[
  {
    "path": ".claude/skills/acestep/SKILL.md",
    "content": "---\nname: acestep\ndescription: Use ACE-Step API to generate music, edit songs, and remix music. Supports text-to-music, lyrics generation, audio continuation, and audio repainting. Use this skill when users mention generating music, creating songs, music production, remix, or audio continuation.\nallowed-tools: Read, Write, Bash, Skill\n---\n\n# ACE-Step Music Generation Skill\n\nUse ACE-Step V1.5 API for music generation. **Always use `scripts/acestep.sh` script** — do NOT call API endpoints directly.\n\n## Quick Start\n\n```bash\n# 1. cd to this skill's directory\ncd {project_root}/{.claude or .codex}/skills/acestep/\n\n# 2. Check API service health\n./scripts/acestep.sh health\n\n# 3. Generate with lyrics (recommended)\n./scripts/acestep.sh generate -c \"pop, female vocal, piano\" -l \"[Verse] Your lyrics here...\" --duration 120 --language zh\n\n# 4. Output saved to: {project_root}/acestep_output/\n```\n\n## Workflow\n\nFor user requests requiring vocals:\n1. Use the **acestep-songwriting** skill for lyrics writing, caption creation, duration/BPM/key selection\n2. Write complete, well-structured lyrics yourself based on the songwriting guide\n3. Generate using Caption mode with `-c` and `-l` parameters\n\nOnly use Simple/Random mode (`-d` or `random`) for quick inspiration or instrumental exploration.\n\nIf the user needs a simple music video, use the **acestep-simplemv** skill to render one with waveform visualization and synced lyrics.\n\n**MV Production Requirements**: Making a simple MV requires three additional skills to be installed:\n- **acestep-songwriting** — for writing lyrics and planning song structure\n- **acestep-lyrics-transcription** — for transcribing audio to timestamped lyrics (LRC)\n- **acestep-simplemv** — for rendering the final music video\n- **acestep-thumbnail** (optional) — for generating cover art / MV background images via Gemini API\n\n**MV Background Image**: When the user requests MV production, ask whether they want a background image for the video:\n1. **Generate via Gemini** — use the **acestep-thumbnail** skill (requires Gemini API key configuration)\n2. **Provide an existing image** — user supplies a local image path\n3. **Skip** — use the default animated gradient background (no image needed)\n\nUse `AskUserQuestion` to let the user choose before proceeding with MV rendering.\n\n**Parallel Processing**: Lyrics transcription and thumbnail generation are independent tasks. When the user chooses to generate a background image, run **acestep-lyrics-transcription** and **acestep-thumbnail** in parallel (e.g. via two concurrent Agent calls) to save time, then use both outputs for the final MV render.\n\n## Script Commands\n\n**CRITICAL - Complete Lyrics Input**: When providing lyrics via the `-l` parameter, you MUST pass ALL lyrics content WITHOUT any omission:\n- If user provides lyrics, pass the ENTIRE text they give you\n- If you generate lyrics yourself, pass the COMPLETE lyrics you created\n- NEVER truncate, shorten, or pass only partial lyrics\n- Missing lyrics will result in incomplete or incoherent songs\n\n**Music Parameters**: Use the **acestep-songwriting** skill for guidance on duration, BPM, key scale, and time signature.\n\n```bash\n# need to cd to this skill's directory first\ncd {project_root}/{.claude or .codex}/skills/acestep/\n\n# Caption mode - RECOMMENDED: Write lyrics first, then generate\n./scripts/acestep.sh generate -c \"Electronic pop, energetic synths\" -l \"[Verse] Your complete lyrics\n[Chorus] Full chorus here...\" --duration 120 --bpm 128\n\n# Instrumental only\n./scripts/acestep.sh generate \"Jazz with saxophone\"\n\n# Quick exploration (Simple/Random mode)\n./scripts/acestep.sh generate -d \"A cheerful song about spring\"\n./scripts/acestep.sh random\n\n# Cover / Repainting from source audio\n./scripts/acestep.sh cover song.mp3 -c \"Rock cover style\" -l \"[Verse] Lyrics...\" --duration 120 --bpm 128\n./scripts/acestep.sh generate --src-audio song.mp3 --task-type repaint -c \"Pop\" --repaint-start 30 --repaint-end 60\n\n# Music attribute options\n./scripts/acestep.sh generate \"Rock\" --duration 60 --bpm 120 --key-scale \"C major\" --time-sig \"4/4\"\n./scripts/acestep.sh generate \"Rock\" --duration 60 --batch 2\n./scripts/acestep.sh generate \"EDM\" --no-thinking    # Faster\n\n# Other commands\n./scripts/acestep.sh status <job_id>\n./scripts/acestep.sh health\n./scripts/acestep.sh models\n```\n\n### Cover / Audio Repainting\n\nThe `cover` command generates music based on a source audio file. The audio is base64-encoded and sent to the API.\n\n```bash\n# Cover: regenerate with new style/lyrics, preserving melody structure\n./scripts/acestep.sh cover input.mp3 -c \"Jazz cover\" -l \"[Verse] New lyrics...\" --duration 120\n\n# Repainting: modify a specific region of the audio\n./scripts/acestep.sh generate --src-audio input.mp3 --task-type repaint -c \"Pop ballad\" --repaint-start 30 --repaint-end 90\n\n# Cover options\n#   --src-audio         Source audio file path\n#   --task-type         cover (default with --src-audio), repaint, text2music\n#   --cover-strength    0.0-1.0 (default: 1.0, higher = closer to source)\n#   --repaint-start     Repainting start position (seconds)\n#   --repaint-end       Repainting end position (seconds)\n#   --key-scale         Musical key (e.g. \"E minor\")\n#   --time-signature    Time signature (e.g. \"4/4\")\n```\n\n**Note**: For cloud API usage, large audio files may be rejected by Cloudflare. Compress audio before uploading if needed (e.g. using ffmpeg: `ffmpeg -i input.mp3 -b:a 64k -ar 24000 -ac 1 compressed.mp3`).\n\n## Output Files\n\nAfter generation, the script automatically saves results to the `acestep_output` folder in the project root (same level as `.claude`):\n\n```\nproject_root/\n├── .claude/\n│   └── skills/acestep/...\n├── acestep_output/          # Output directory\n│   ├── <job_id>.json         # Complete task result (JSON)\n│   ├── <job_id>_1.mp3        # First audio file\n│   ├── <job_id>_2.mp3        # Second audio file (if batch_size > 1)\n│   └── ...\n└── ...\n```\n\n### JSON Result Structure\n\n**Important**: When LM enhancement is enabled (`use_format=true`), the final synthesized content may differ from your input. Check the JSON file for actual values:\n\n| Field | Description |\n|-------|-------------|\n| `prompt` | **Actual caption** used for synthesis (may be LM-enhanced) |\n| `lyrics` | **Actual lyrics** used for synthesis (may be LM-enhanced) |\n| `metas.prompt` | Original input caption |\n| `metas.lyrics` | Original input lyrics |\n| `metas.bpm` | BPM used |\n| `metas.keyscale` | Key scale used |\n| `metas.duration` | Duration in seconds |\n| `generation_info` | Detailed timing and model info |\n| `seed_value` | Seeds used (for reproducibility) |\n| `lm_model` | LM model name |\n| `dit_model` | DiT model name |\n\nTo get the actual synthesized lyrics, parse the JSON and read the top-level `lyrics` field, not `metas.lyrics`.\n\n## Configuration\n\n**Important**: Configuration follows this priority (high to low):\n\n1. **Command line arguments** > **config.json defaults**\n2. User-specified parameters **temporarily override** defaults but **do not modify** config.json\n3. Only `config --set` command **permanently modifies** config.json\n\n### Default Config File (`scripts/config.json`)\n\n```json\n{\n  \"api_url\": \"http://127.0.0.1:8001\",\n  \"api_key\": \"\",\n  \"api_mode\": \"completion\",\n  \"generation\": {\n    \"thinking\": true,\n    \"use_format\": false,\n    \"use_cot_caption\": true,\n    \"use_cot_language\": false,\n    \"batch_size\": 1,\n    \"audio_format\": \"mp3\",\n    \"vocal_language\": \"en\"\n  }\n}\n```\n\n| Option | Default | Description |\n|--------|---------|-------------|\n| `api_url` | `http://127.0.0.1:8001` | API server address |\n| `api_key` | `\"\"` | API authentication key (optional) |\n| `api_mode` | `completion` | API mode: `completion` (OpenRouter, default) or `native` (polling) |\n| `generation.thinking` | `true` | Enable 5Hz LM (higher quality, slower) |\n| `generation.audio_format` | `mp3` | Output format (mp3/wav/flac) |\n| `generation.vocal_language` | `en` | Vocal language |\n\n## Prerequisites - ACE-Step API Service\n\n**IMPORTANT**: This skill requires the ACE-Step API server to be running.\n\n### Required Dependencies\n\nThe `scripts/acestep.sh` script requires: **curl** and **jq**.\n\n```bash\n# Check dependencies\ncurl --version\njq --version\n```\n\nIf jq is not installed, the script will attempt to install it automatically. If automatic installation fails:\n- **Windows**: `choco install jq` or download from https://jqlang.github.io/jq/download/\n- **macOS**: `brew install jq`\n- **Linux**: `sudo apt-get install jq` (Debian/Ubuntu) or `sudo dnf install jq` (Fedora)\n\n### Before First Use\n\n**You MUST check the API key and URL status before proceeding.** Run:\n\n```bash\ncd \"{project_root}/{.claude or .codex}/skills/acestep/\" && bash ./scripts/acestep.sh config --check-key\ncd \"{project_root}/{.claude or .codex}/skills/acestep/\" && bash ./scripts/acestep.sh config --get api_url\n```\n\n#### Case 1: Using Official Cloud API (`https://api.acemusic.ai`) without API key\n\nIf `api_url` is `https://api.acemusic.ai` and `api_key` is `empty`, you MUST stop and guide the user to configure their key:\n\n1. Tell the user: \"You're using the ACE-Step official cloud API, but no API key is configured. An API key is required to use this service.\"\n2. Explain how to get a key: API keys are currently available through [acemusic.ai](https://acemusic.ai/api-key) for free.\n3. Use `AskUserQuestion` to ask the user to provide their API key.\n4. Once provided, configure it:\n   ```bash\n   cd \"{project_root}/{.claude or .codex}/skills/acestep/\" && bash ./scripts/acestep.sh config --set api_key <KEY>\n   ```\n5. Additionally, inform the user: \"If you also want to render music videos (MV), it's recommended to configure a lyrics transcription API key as well (OpenAI Whisper or ElevenLabs Scribe), so that lyrics can be automatically transcribed with accurate timestamps. You can configure it later via the `acestep-lyrics-transcription` skill.\"\n\n#### Case 2: API key is configured\n\nVerify the API endpoint: `./scripts/acestep.sh health` and proceed with music generation.\n\n#### Case 3: Using local/custom API without key\n\nLocal services (`http://127.0.0.1:*`) typically don't require a key. Verify with `./scripts/acestep.sh health` and proceed.\n\nIf health check fails:\n- Ask: \"Do you have ACE-Step installed?\"\n- **If installed but not running**: Use the acestep-docs skill to help them start the service\n- **If not installed**: Use acestep-docs skill to guide through installation\n\n### Service Configuration\n\n**Official Cloud API:** ACE-Step provides an official API endpoint at `https://api.acemusic.ai`. To use it:\n```bash\n./scripts/acestep.sh config --set api_url \"https://api.acemusic.ai\"\n./scripts/acestep.sh config --set api_key \"your-key\"\n./scripts/acestep.sh config --set api_mode completion\n```\nAPI keys are currently available through [acemusic.ai](https://acemusic.ai/api-key) for free. \n\n**Local Service (Default):** No configuration needed — connects to `http://127.0.0.1:8001`.\n\n**Custom Remote Service:** Update `scripts/config.json` or use:\n```bash\n./scripts/acestep.sh config --set api_url \"http://remote-server:8001\"\n./scripts/acestep.sh config --set api_key \"your-key\"\n```\n\n**API Key Handling**: When checking whether an API key is configured, use `config --check-key` which only reports `configured` or `empty` without printing the actual key. **NEVER use `config --get api_key`** or read `config.json` directly — these would expose the user's API key. The `config --list` command is safe — it automatically masks API keys as `***` in output.\n\n### API Mode\n\nThe skill supports two API modes. Switch via `api_mode` in `scripts/config.json`:\n\n| Mode | Endpoint | Description |\n|------|----------|-------------|\n| `completion` (default) | `/v1/chat/completions` | OpenRouter-compatible, sync request, audio returned as base64 |\n| `native` | `/release_task` + `/query_result` | Async polling mode, supports all parameters |\n\n**Switch mode:**\n```bash\n./scripts/acestep.sh config --set api_mode completion\n./scripts/acestep.sh config --set api_mode native\n```\n\n**Completion mode notes:**\n- No polling needed — single request returns result directly\n- Audio is base64-encoded inline in the response (auto-decoded and saved)\n- `inference_steps`, `infer_method`, `shift` are not configurable (server defaults)\n- `--no-wait` and `status` commands are not applicable in completion mode\n- Requires `model` field — auto-detected from `/v1/models` if not specified\n\n### Using acestep-docs Skill for Setup Help\n\n**IMPORTANT**: For installation and startup, always use the acestep-docs skill to get complete and accurate guidance.\n\n**DO NOT provide simplified startup commands** - each user's environment may be different. Always guide them to use acestep-docs for proper setup.\n\n---\n\nFor API debugging, see [API Reference](./api-reference.md).\n"
  },
  {
    "path": ".claude/skills/acestep/api-reference.md",
    "content": "# ACE-Step API Reference\n\n> For debugging and advanced usage only. Normal operations should use `scripts/acestep.sh`.\n\n## Native Mode Endpoints\n\nAll responses wrapped: `{\"data\": <payload>, \"code\": 200, \"error\": null, \"timestamp\": ...}`\n\n| Endpoint | Method | Description |\n|----------|--------|-------------|\n| `/health` | GET | Health check |\n| `/release_task` | POST | Create generation task |\n| `/query_result` | POST | Query task status, body: `{\"task_id_list\": [\"id\"]}` |\n| `/v1/models` | GET | List available models |\n| `/v1/audio?path={path}` | GET | Download audio file |\n\n## Completion Mode Endpoints\n\n| Endpoint | Method | Description |\n|----------|--------|-------------|\n| `/v1/chat/completions` | POST | Generate music (OpenRouter-compatible) |\n| `/v1/models` | GET | List available models (OpenRouter format) |\n\n## Query Result Response\n\n```json\n{\n  \"data\": [{\n    \"task_id\": \"xxx\",\n    \"status\": 1,\n    \"result\": \"[{\\\"file\\\":\\\"/v1/audio?path=...\\\",\\\"metas\\\":{\\\"bpm\\\":120,\\\"duration\\\":60,\\\"keyscale\\\":\\\"C Major\\\"}}]\"\n  }]\n}\n```\n\nStatus codes: `0` = processing, `1` = success, `2` = failed\n\n## Completion Mode Request (`/v1/chat/completions`)\n\n**Caption mode** — prompt and lyrics wrapped in XML tags inside message content:\n```json\n{\n  \"model\": \"acestep/ACE-Step-v1.5\",\n  \"messages\": [{\"role\": \"user\", \"content\": \"<prompt>Jazz with saxophone</prompt><lyrics>[Verse] Hello...</lyrics>\"}],\n  \"stream\": false,\n  \"thinking\": true,\n  \"use_format\": false,\n  \"audio_config\": {\"duration\": 90, \"bpm\": 110, \"format\": \"mp3\", \"vocal_language\": \"en\"}\n}\n```\n\n**Simple mode** — plain text message, set `sample_mode: true`:\n```json\n{\n  \"model\": \"acestep/ACE-Step-v1.5\",\n  \"messages\": [{\"role\": \"user\", \"content\": \"A cheerful pop song about spring\"}],\n  \"stream\": false,\n  \"sample_mode\": true,\n  \"thinking\": true\n}\n```\n\n## Completion Mode Response\n\n```json\n{\n  \"id\": \"chatcmpl-abc123\",\n  \"choices\": [{\n    \"message\": {\n      \"role\": \"assistant\",\n      \"content\": \"## Metadata\\n**Caption:** ...\\n**BPM:** 128\\n\\n## Lyrics\\n...\",\n      \"audio\": [{\"type\": \"audio_url\", \"audio_url\": {\"url\": \"data:audio/mpeg;base64,...\"}}]\n    },\n    \"finish_reason\": \"stop\"\n  }]\n}\n```\n\nAudio is base64-encoded inline — the script auto-decodes and saves to `acestep_output/`.\n\n## Request Parameters (`/release_task`)\n\nParameters can be placed in `param_obj` object.\n\n### Generation Modes\n\n| Mode | Usage | When to Use |\n|------|-------|-------------|\n| **Caption** (Recommended) | `generate -c \"style\" -l \"lyrics\"` | For vocal songs - write lyrics yourself first |\n| **Simple** | `generate -d \"description\"` | Quick exploration, LM generates everything |\n| **Random** | `random` | Random generation for inspiration |\n\n### Core Parameters\n\n| Parameter | Type | Default | Description |\n|-----------|------|---------|-------------|\n| `prompt` | string | \"\" | Music style description (Caption mode) |\n| `lyrics` | string | \"\" | **Full lyrics content** - Pass ALL lyrics without omission. Use `[inst]` for instrumental. Partial/truncated lyrics = incomplete songs |\n| `sample_mode` | bool | false | Enable Simple/Random mode |\n| `sample_query` | string | \"\" | Description for Simple mode |\n| `thinking` | bool | false | Enable 5Hz LM for audio code generation |\n| `use_format` | bool | false | Use LM to enhance caption/lyrics |\n| `model` | string | - | DiT model name |\n| `batch_size` | int | 1 | Number of audio files to generate |\n\n### Music Attributes\n\n| Parameter | Type | Default | Description |\n|-----------|------|---------|-------------|\n| `audio_duration` | float | - | Duration in seconds |\n| `bpm` | int | - | Tempo (beats per minute) |\n| `key_scale` | string | \"\" | Key (e.g. \"C Major\") |\n| `time_signature` | string | \"\" | Time signature (e.g. \"4/4\") |\n| `vocal_language` | string | \"en\" | Language code (en, zh, ja, etc.) |\n| `audio_format` | string | \"mp3\" | Output format (mp3/wav/flac) |\n\n### Generation Parameters\n\n| Parameter | Type | Default | Description |\n|-----------|------|---------|-------------|\n| `inference_steps` | int | 8 | Diffusion steps |\n| `guidance_scale` | float | 7.0 | CFG scale |\n| `seed` | int | -1 | Random seed (-1 for random) |\n| `infer_method` | string | \"ode\" | Diffusion method (ode/sde) |\n\n### Audio Task Parameters\n\n| Parameter | Type | Default | Description |\n|-----------|------|---------|-------------|\n| `task_type` | string | \"text2music\" | text2music / continuation / repainting |\n| `src_audio_path` | string | - | Source audio for continuation |\n| `repainting_start` | float | 0.0 | Repainting start position (seconds) |\n| `repainting_end` | float | - | Repainting end position (seconds) |\n\n### Example Request (Simple Mode)\n\n```json\n{\n  \"sample_mode\": true,\n  \"sample_query\": \"A cheerful pop song about spring\",\n  \"thinking\": true,\n  \"param_obj\": {\n    \"duration\": 60,\n    \"bpm\": 120,\n    \"language\": \"en\"\n  },\n  \"batch_size\": 2\n}\n```\n"
  },
  {
    "path": ".claude/skills/acestep/scripts/acestep.sh",
    "content": "#!/bin/bash\n#\n# ACE-Step Music Generation CLI (Bash + Curl + jq)\n#\n# Requirements: curl, jq\n#\n# Usage:\n#   ./acestep.sh generate \"Music description\" [options]\n#   ./acestep.sh random [--no-thinking]\n#   ./acestep.sh status <job_id>\n#   ./acestep.sh models\n#   ./acestep.sh health\n#   ./acestep.sh config [--get|--set|--reset]\n#\n# Output:\n#   - Results saved to output/<job_id>.json\n#   - Audio files downloaded to output/<job_id>_1.mp3, output/<job_id>_2.mp3, ...\n\nset -e\n\n# Ensure UTF-8 encoding for non-ASCII characters (Japanese, Chinese, etc.)\nexport LANG=\"${LANG:-en_US.UTF-8}\"\nexport LC_ALL=\"${LC_ALL:-en_US.UTF-8}\"\n\nSCRIPT_DIR=\"$(cd \"$(dirname \"${BASH_SOURCE[0]}\")\" && pwd)\"\nCONFIG_FILE=\"${SCRIPT_DIR}/config.json\"\n# Output dir at same level as .claude (go up 4 levels from scripts/)\nOUTPUT_DIR=\"$(cd \"${SCRIPT_DIR}/../../../..\" && pwd)/acestep_output\"\nDEFAULT_API_URL=\"http://127.0.0.1:8001\"\nSTAR_MARKER_FILE=\"${SCRIPT_DIR}/.first_gen_done\"\n\n# Colors\nRED='\\033[0;31m'\nGREEN='\\033[0;32m'\nYELLOW='\\033[1;33m'\nCYAN='\\033[0;36m'\nNC='\\033[0m'\nBOLD='\\033[1m'\n\n# Show GitHub star prompt on first successful generation\nshow_star_prompt() {\n    if [ ! -f \"$STAR_MARKER_FILE\" ]; then\n        touch \"$STAR_MARKER_FILE\"\n        echo \"\"\n        echo -e \"${YELLOW}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}\"\n        echo -e \"${BOLD}  ACE-Step is free and open-source.${NC}\"\n        echo -e \"  If you enjoyed this, a ${YELLOW}★ Star${NC} on GitHub means a lot to us!\"\n        echo -e \"  ${CYAN}→ https://github.com/ace-step/ACE-Step-1.5${NC}\"\n        echo -e \"${YELLOW}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}\"\n    fi\n}\n\n# Check dependencies\ncheck_deps() {\n    if ! command -v curl &> /dev/null; then\n        echo -e \"${RED}Error: curl is required but not installed.${NC}\"\n        exit 1\n    fi\n    if ! command -v jq &> /dev/null; then\n        echo -e \"${RED}Error: jq is required but not installed.${NC}\"\n        echo \"Install: apt install jq / brew install jq / choco install jq\"\n        exit 1\n    fi\n}\n\n# JSON value extractor using jq\n# Usage: json_get \"$json\" \".key\" or json_get \"$json\" \".nested.key\"\njson_get() {\n    local json=\"$1\"\n    local path=\"$2\"\n    echo \"$json\" | jq -r \"$path // empty\" 2>/dev/null\n}\n\n# Extract array values using jq\njson_get_array() {\n    local json=\"$1\"\n    local path=\"$2\"\n    echo \"$json\" | jq -r \"$path[]? // empty\" 2>/dev/null\n}\n\n# Ensure output directory exists\nensure_output_dir() {\n    mkdir -p \"$OUTPUT_DIR\"\n}\n\n# Default config\nDEFAULT_CONFIG='{\n  \"api_url\": \"http://127.0.0.1:8001\",\n  \"api_key\": \"\",\n  \"api_mode\": \"native\",\n  \"generation\": {\n    \"thinking\": true,\n    \"use_format\": true,\n    \"use_cot_caption\": true,\n    \"use_cot_language\": true,\n    \"audio_format\": \"mp3\",\n    \"vocal_language\": \"en\"\n  }\n}'\n\n# Ensure config file exists\nensure_config() {\n    if [ ! -f \"$CONFIG_FILE\" ]; then\n        local example=\"${SCRIPT_DIR}/config.example.json\"\n        if [ -f \"$example\" ]; then\n            cp \"$example\" \"$CONFIG_FILE\"\n            echo -e \"${YELLOW}Config file created from config.example.json. Please configure your settings:${NC}\"\n            echo -e \"  ${CYAN}./scripts/acestep.sh config --set api_url <url>${NC}\"\n            echo -e \"  ${CYAN}./scripts/acestep.sh config --set api_key <key>${NC}\"\n        else\n            echo \"$DEFAULT_CONFIG\" > \"$CONFIG_FILE\"\n        fi\n    fi\n}\n\n# Get config value using jq\nget_config() {\n    local key=\"$1\"\n    ensure_config\n    # Convert dot notation to jq path: \"generation.thinking\" -> \".generation.thinking\"\n    local jq_path=\".${key}\"\n    local value\n    # Don't use // operator as it treats boolean false as falsy\n    value=$(jq -r \"$jq_path\" \"$CONFIG_FILE\" 2>/dev/null)\n    # Remove any trailing whitespace/newlines (Windows compatibility)\n    # Return empty string if value is \"null\" (key doesn't exist)\n    if [ \"$value\" = \"null\" ]; then\n        echo \"\"\n    else\n        echo \"$value\" | tr -d '\\r\\n'\n    fi\n}\n\n# Normalize boolean value for jq --argjson\nnormalize_bool() {\n    local val=\"$1\"\n    local default=\"${2:-false}\"\n    case \"$val\" in\n        true|True|TRUE|1) echo \"true\" ;;\n        false|False|FALSE|0) echo \"false\" ;;\n        *) echo \"$default\" ;;\n    esac\n}\n\n# Set config value using jq\nset_config() {\n    local key=\"$1\"\n    local value=\"$2\"\n    ensure_config\n\n    local tmp_file=\"${CONFIG_FILE}.tmp\"\n    local jq_path=\".${key}\"\n\n    # Determine value type and set accordingly\n    if [ \"$value\" = \"true\" ] || [ \"$value\" = \"false\" ]; then\n        jq \"$jq_path = $value\" \"$CONFIG_FILE\" > \"$tmp_file\"\n    elif [[ \"$value\" =~ ^-?[0-9]+$ ]] || [[ \"$value\" =~ ^-?[0-9]+\\.[0-9]+$ ]]; then\n        jq \"$jq_path = $value\" \"$CONFIG_FILE\" > \"$tmp_file\"\n    else\n        jq \"$jq_path = \\\"$value\\\"\" \"$CONFIG_FILE\" > \"$tmp_file\"\n    fi\n\n    mv \"$tmp_file\" \"$CONFIG_FILE\"\n    echo \"Set $key = $value\"\n}\n\n# Load API URL\nload_api_url() {\n    local url=$(get_config \"api_url\")\n    echo \"${url:-$DEFAULT_API_URL}\"\n}\n\n# Load API Key\nload_api_key() {\n    local key=$(get_config \"api_key\")\n    echo \"${key:-}\"\n}\n\n# Check API health\ncheck_health() {\n    local url=\"$1\"\n    local status\n    status=$(curl -s -o /dev/null -w \"%{http_code}\" --connect-timeout 5 \"${url}/health\" 2>/dev/null) || true\n    [ \"$status\" = \"200\" ]\n}\n\n# Build auth header\nbuild_auth_header() {\n    local api_key=$(load_api_key)\n    if [ -n \"$api_key\" ]; then\n        echo \"-H \\\"Authorization: Bearer ${api_key}\\\"\"\n    fi\n}\n\n# Prompt for URL\nprompt_for_url() {\n    echo \"\"\n    echo -e \"${YELLOW}API server is not responding.${NC}\"\n    echo \"Please enter the API URL (or press Enter for default):\"\n    read -p \"API URL [$DEFAULT_API_URL]: \" user_input\n    echo \"${user_input:-$DEFAULT_API_URL}\"\n}\n\n# Ensure API connection\nensure_connection() {\n    ensure_config\n    local api_url=$(load_api_url)\n\n    if check_health \"$api_url\"; then\n        echo \"$api_url\"\n        return 0\n    fi\n\n    echo -e \"${YELLOW}Cannot connect to: $api_url${NC}\" >&2\n    local new_url=$(prompt_for_url)\n\n    if check_health \"$new_url\"; then\n        set_config \"api_url\" \"$new_url\" > /dev/null\n        echo -e \"${GREEN}Saved API URL: $new_url${NC}\" >&2\n        echo \"$new_url\"\n        return 0\n    fi\n\n    echo -e \"${RED}Error: Cannot connect to $new_url${NC}\" >&2\n    exit 1\n}\n\n# Save result to JSON file\nsave_result() {\n    local job_id=\"$1\"\n    local result_json=\"$2\"\n\n    ensure_output_dir\n    local output_file=\"${OUTPUT_DIR}/${job_id}.json\"\n    echo \"$result_json\" > \"$output_file\"\n    echo -e \"${GREEN}Result saved: $output_file${NC}\"\n}\n\n# Health command\ncmd_health() {\n    check_deps\n    ensure_config\n    local api_url=$(load_api_url)\n\n    echo \"Checking API at: $api_url\"\n    if check_health \"$api_url\"; then\n        echo -e \"${GREEN}Status: OK${NC}\"\n        curl -s \"${api_url}/health\"\n        echo \"\"\n    else\n        echo -e \"${RED}Status: FAILED${NC}\"\n        exit 1\n    fi\n}\n\n# Config command\ncmd_config() {\n    check_deps\n    ensure_config\n\n    local action=\"\"\n    local key=\"\"\n    local value=\"\"\n\n    while [[ $# -gt 0 ]]; do\n        case $1 in\n            --get) action=\"get\"; key=\"$2\"; shift 2 ;;\n            --set) action=\"set\"; key=\"$2\"; value=\"$3\"; shift 3 ;;\n            --reset) action=\"reset\"; shift ;;\n            --list) action=\"list\"; shift ;;\n            --check-key) action=\"check-key\"; shift ;;\n            *) shift ;;\n        esac\n    done\n\n    case \"$action\" in\n        \"check-key\")\n            local api_key=$(get_config \"api_key\")\n            if [ -n \"$api_key\" ]; then\n                echo \"api_key: configured\"\n            else\n                echo \"api_key: empty\"\n            fi\n            ;;\n        \"get\")\n            [ -z \"$key\" ] && { echo -e \"${RED}Error: --get requires KEY${NC}\"; exit 1; }\n            local result=$(get_config \"$key\")\n            [ -n \"$result\" ] && echo \"$key = $result\" || echo \"Key not found: $key\"\n            ;;\n        \"set\")\n            [ -z \"$key\" ] || [ -z \"$value\" ] && { echo -e \"${RED}Error: --set requires KEY VALUE${NC}\"; exit 1; }\n            set_config \"$key\" \"$value\"\n            ;;\n        \"reset\")\n            echo \"$DEFAULT_CONFIG\" > \"$CONFIG_FILE\"\n            echo -e \"${GREEN}Configuration reset to defaults.${NC}\"\n            jq 'walk(if type == \"object\" and has(\"api_key\") and (.api_key | length) > 0 then .api_key = \"***\" else . end)' \"$CONFIG_FILE\"\n            ;;\n        \"list\")\n            echo \"Current configuration:\"\n            jq 'walk(if type == \"object\" and has(\"api_key\") and (.api_key | length) > 0 then .api_key = \"***\" else . end)' \"$CONFIG_FILE\"\n            ;;\n        *)\n            echo \"Config file: $CONFIG_FILE\"\n            echo \"Output dir: $OUTPUT_DIR\"\n            echo \"----------------------------------------\"\n            cat \"$CONFIG_FILE\"\n            echo \"----------------------------------------\"\n            echo \"\"\n            echo \"Usage:\"\n            echo \"  config --list              Show config\"\n            echo \"  config --get <key>         Get value\"\n            echo \"  config --set <key> <val>   Set value\"\n            echo \"  config --reset             Reset to defaults\"\n            ;;\n    esac\n}\n\n# Models command\ncmd_models() {\n    check_deps\n    local api_url=$(ensure_connection)\n    local api_key=$(load_api_key)\n\n    echo \"Available Models:\"\n    echo \"----------------------------------------\"\n    if [ -n \"$api_key\" ]; then\n        curl -s -H \"Authorization: Bearer ${api_key}\" \"${api_url}/v1/models\"\n    else\n        curl -s \"${api_url}/v1/models\"\n    fi\n    echo \"\"\n}\n\n# Query job result via /query_result endpoint\nquery_job_result() {\n    local api_url=\"$1\"\n    local job_id=\"$2\"\n    local api_key=$(load_api_key)\n\n    local payload=$(jq -n --arg id \"$job_id\" '{\"task_id_list\": [$id]}')\n\n    if [ -n \"$api_key\" ]; then\n        curl -s -X POST \"${api_url}/query_result\" \\\n            -H \"Content-Type: application/json; charset=utf-8\" \\\n            -H \"Authorization: Bearer ${api_key}\" \\\n            -d \"$payload\"\n    else\n        curl -s -X POST \"${api_url}/query_result\" \\\n            -H \"Content-Type: application/json; charset=utf-8\" \\\n            -d \"$payload\"\n    fi\n}\n\n# Parse query_result response to extract status (0=processing, 1=success, 2=failed)\n# Response is wrapped: {\"data\": [...], \"code\": 200, ...}\n# Uses temp file to avoid jq pipe issues with special characters on Windows\nparse_query_status() {\n    local response=\"$1\"\n    local tmp_file=$(mktemp)\n    printf '%s' \"$response\" > \"$tmp_file\"\n    jq -r '.data[0].status // .[0].status // 0' \"$tmp_file\"\n    rm -f \"$tmp_file\"\n}\n\n# Parse result JSON string from query_result response\n# The result field is a JSON string that needs to be parsed\n# Uses temp file to avoid jq pipe issues with special characters on Windows\nparse_query_result() {\n    local response=\"$1\"\n    local tmp_file=$(mktemp)\n    printf '%s' \"$response\" > \"$tmp_file\"\n    jq -r '.data[0].result // .[0].result // \"[]\"' \"$tmp_file\"\n    rm -f \"$tmp_file\"\n}\n\n# Extract audio file paths from result (returns newline-separated paths)\n# Uses temp file to avoid jq pipe issues with special characters on Windows\nparse_audio_files() {\n    local result=\"$1\"\n    local tmp_file=$(mktemp)\n    printf '%s' \"$result\" > \"$tmp_file\"\n    jq -r '.[].file // empty' \"$tmp_file\" 2>/dev/null\n    rm -f \"$tmp_file\"\n}\n\n# Extract metas value from result\n# Uses temp file to avoid jq pipe issues with special characters on Windows\nparse_metas_value() {\n    local result=\"$1\"\n    local key=\"$2\"\n    local tmp_file=$(mktemp)\n    printf '%s' \"$result\" > \"$tmp_file\"\n    jq -r \".[0].metas.$key // .[0].$key // empty\" \"$tmp_file\" 2>/dev/null\n    rm -f \"$tmp_file\"\n}\n\n# Status command\ncmd_status() {\n    check_deps\n    local job_id=\"$1\"\n\n    [ -z \"$job_id\" ] && { echo -e \"${RED}Error: job_id required${NC}\"; echo \"Usage: $0 status <job_id>\"; exit 1; }\n\n    local api_url=$(ensure_connection)\n    local response=$(query_job_result \"$api_url\" \"$job_id\")\n\n    local status=$(parse_query_status \"$response\")\n    echo \"Job ID: $job_id\"\n\n    case \"$status\" in\n        0)\n            echo \"Status: processing\"\n            ;;\n        1)\n            echo \"Status: succeeded\"\n            echo \"\"\n            local result_file=$(mktemp)\n            parse_query_result \"$response\" > \"$result_file\"\n\n            local bpm=$(jq -r '.[0].metas.bpm // .[0].bpm // empty' \"$result_file\" 2>/dev/null)\n            local keyscale=$(jq -r '.[0].metas.keyscale // .[0].keyscale // empty' \"$result_file\" 2>/dev/null)\n            local duration=$(jq -r '.[0].metas.duration // .[0].duration // empty' \"$result_file\" 2>/dev/null)\n\n            echo \"Result:\"\n            [ -n \"$bpm\" ] && echo \"  BPM: $bpm\"\n            [ -n \"$keyscale\" ] && echo \"  Key: $keyscale\"\n            [ -n \"$duration\" ] && echo \"  Duration: ${duration}s\"\n\n            # Save and download\n            save_result \"$job_id\" \"$response\"\n            download_audios \"$api_url\" \"$job_id\" \"$result_file\"\n            rm -f \"$result_file\"\n            ;;\n        2)\n            echo \"Status: failed\"\n            echo \"\"\n            echo -e \"${RED}Task failed${NC}\"\n            ;;\n        *)\n            echo \"Status: unknown ($status)\"\n            ;;\n    esac\n}\n\n# Download audio files from result file\n# Usage: download_audios <api_url> <job_id> <result_file>\ndownload_audios() {\n    local api_url=\"$1\"\n    local job_id=\"$2\"\n    local result_file=\"$3\"\n    local api_key=$(load_api_key)\n\n    ensure_output_dir\n\n    local audio_format=$(get_config \"generation.audio_format\")\n    [ -z \"$audio_format\" ] && audio_format=\"mp3\"\n\n    # Read result file content and extract audio paths using pipe (avoid temp file path issues on Windows)\n    local result_content\n    result_content=$(cat \"$result_file\" 2>/dev/null)\n\n    if [ -z \"$result_content\" ]; then\n        echo -e \"  ${RED}Error: Result file is empty or cannot be read${NC}\"\n        return 1\n    fi\n\n    # Extract audio paths using pipe instead of file (better Windows compatibility)\n    local audio_paths\n    audio_paths=$(echo \"$result_content\" | jq -r '.[].file // empty' 2>&1)\n    local jq_exit_code=$?\n\n    if [ $jq_exit_code -ne 0 ]; then\n        echo -e \"  ${RED}Error: Failed to parse result JSON${NC}\"\n        echo -e \"  ${RED}jq error: $audio_paths${NC}\"\n        return 1\n    fi\n\n    if [ -z \"$audio_paths\" ]; then\n        echo -e \"  ${YELLOW}No audio files found in result${NC}\"\n        return 0\n    fi\n\n    local count=1\n    while IFS= read -r audio_path; do\n        # Skip empty lines and remove potential Windows carriage return\n        audio_path=$(echo \"$audio_path\" | tr -d '\\r')\n        if [ -n \"$audio_path\" ]; then\n            local output_file=\"${OUTPUT_DIR}/${job_id}_${count}.${audio_format}\"\n            local download_url=\"${api_url}${audio_path}\"\n\n            echo -e \"  ${CYAN}Downloading audio $count...${NC}\"\n            local curl_output\n            local curl_exit_code\n            if [ -n \"$api_key\" ]; then\n                curl_output=$(curl -s --connect-timeout 10 --max-time 300 \\\n                    -w \"%{http_code}\" \\\n                    -o \"$output_file\" \\\n                    -H \"Authorization: Bearer ${api_key}\" \\\n                    \"$download_url\" 2>&1)\n                curl_exit_code=$?\n            else\n                curl_output=$(curl -s --connect-timeout 10 --max-time 300 \\\n                    -w \"%{http_code}\" \\\n                    -o \"$output_file\" \\\n                    \"$download_url\" 2>&1)\n                curl_exit_code=$?\n            fi\n\n            if [ $curl_exit_code -ne 0 ]; then\n                echo -e \"  ${RED}Failed to download (curl error $curl_exit_code): $download_url${NC}\"\n                rm -f \"$output_file\" 2>/dev/null\n            elif [ -f \"$output_file\" ] && [ -s \"$output_file\" ]; then\n                echo -e \"  ${GREEN}Saved: $output_file${NC}\"\n            else\n                echo -e \"  ${RED}Failed to download (HTTP $curl_output): $download_url${NC}\"\n                rm -f \"$output_file\" 2>/dev/null\n            fi\n            count=$((count + 1))\n        fi\n    done <<< \"$audio_paths\"\n}\n\n# =============================================================================\n# Completion Mode (OpenRouter /v1/chat/completions)\n# =============================================================================\n\n# Load api_mode from config (default: native)\nload_api_mode() {\n    local mode=$(get_config \"api_mode\")\n    echo \"${mode:-native}\"\n}\n\n# Get model ID from /v1/models endpoint for completion mode\nget_completion_model() {\n    local api_url=\"$1\"\n    local user_model=\"$2\"\n    local api_key=$(load_api_key)\n\n    # If user specified a model, prefix with acemusic/ if needed\n    if [ -n \"$user_model\" ]; then\n        if [[ \"$user_model\" == */* ]]; then\n            echo \"$user_model\"\n        else\n            echo \"acemusic/${user_model}\"\n        fi\n        return\n    fi\n\n    # Query /v1/models for the first available model\n    local response\n    if [ -n \"$api_key\" ]; then\n        response=$(curl -s -H \"Authorization: Bearer ${api_key}\" \"${api_url}/v1/models\" 2>/dev/null)\n    else\n        response=$(curl -s \"${api_url}/v1/models\" 2>/dev/null)\n    fi\n\n    local model_id\n    model_id=$(echo \"$response\" | jq -r '.data[0].id // empty' 2>/dev/null)\n    echo \"${model_id:-acemusic/acestep-v15-turbo}\"\n}\n\n# Decode base64 audio data URL and save to file\n# Handles cross-platform compatibility (Linux/macOS/Windows MSYS)\ndecode_base64_audio() {\n    local data_url=\"$1\"\n    local output_file=\"$2\"\n\n    # Strip data URL prefix: data:audio/mpeg;base64,...\n    local b64_data=\"${data_url#data:*;base64,}\"\n\n    local tmp_b64=$(mktemp)\n    printf '%s' \"$b64_data\" > \"$tmp_b64\"\n\n    if command -v base64 &> /dev/null; then\n        # Linux / macOS / MSYS2\n        base64 -d < \"$tmp_b64\" > \"$output_file\" 2>/dev/null || \\\n        base64 -D < \"$tmp_b64\" > \"$output_file\" 2>/dev/null || \\\n        python3 -c \"import base64,sys; sys.stdout.buffer.write(base64.b64decode(sys.stdin.read()))\" < \"$tmp_b64\" > \"$output_file\" 2>/dev/null || \\\n        python -c \"import base64,sys; sys.stdout.buffer.write(base64.b64decode(sys.stdin.read()))\" < \"$tmp_b64\" > \"$output_file\" 2>/dev/null\n    else\n        # Fallback to python\n        python3 -c \"import base64,sys; sys.stdout.buffer.write(base64.b64decode(sys.stdin.read()))\" < \"$tmp_b64\" > \"$output_file\" 2>/dev/null || \\\n        python -c \"import base64,sys; sys.stdout.buffer.write(base64.b64decode(sys.stdin.read()))\" < \"$tmp_b64\" > \"$output_file\" 2>/dev/null\n    fi\n\n    local decode_ok=$?\n    rm -f \"$tmp_b64\"\n    return $decode_ok\n}\n\n# Parse completion response: extract metadata, save audio files\n# Usage: parse_completion_response <response_file> <job_id>\nparse_completion_response() {\n    local resp_file=\"$1\"\n    local job_id=\"$2\"\n\n    ensure_output_dir\n\n    local audio_format=$(get_config \"generation.audio_format\")\n    [ -z \"$audio_format\" ] && audio_format=\"mp3\"\n\n    # Check for error\n    local finish_reason\n    finish_reason=$(jq -r '.choices[0].finish_reason // \"stop\"' \"$resp_file\" 2>/dev/null)\n    if [ \"$finish_reason\" = \"error\" ]; then\n        local err_content\n        err_content=$(jq -r '.choices[0].message.content // \"Unknown error\"' \"$resp_file\" 2>/dev/null)\n        echo -e \"${RED}Generation failed: $err_content${NC}\"\n        return 1\n    fi\n\n    # Extract and display text content (metadata + lyrics)\n    local content\n    content=$(jq -r '.choices[0].message.content // empty' \"$resp_file\" 2>/dev/null)\n    if [ -n \"$content\" ]; then\n        echo \"$content\"\n        echo \"\"\n    fi\n\n    # Extract and save audio files\n    local audio_count\n    audio_count=$(jq -r '.choices[0].message.audio | length // 0' \"$resp_file\" 2>/dev/null)\n\n    if [ \"$audio_count\" -gt 0 ] 2>/dev/null; then\n        local i=0\n        while [ \"$i\" -lt \"$audio_count\" ]; do\n            local audio_url\n            audio_url=$(jq -r \".choices[0].message.audio[$i].audio_url.url // empty\" \"$resp_file\" 2>/dev/null)\n\n            if [ -n \"$audio_url\" ]; then\n                local output_file=\"${OUTPUT_DIR}/${job_id}_$((i+1)).${audio_format}\"\n                echo -e \"  ${CYAN}Decoding audio $((i+1))...${NC}\"\n\n                if decode_base64_audio \"$audio_url\" \"$output_file\"; then\n                    if [ -f \"$output_file\" ] && [ -s \"$output_file\" ]; then\n                        echo -e \"  ${GREEN}Saved: $output_file${NC}\"\n                    else\n                        echo -e \"  ${RED}Failed to decode audio $((i+1))${NC}\"\n                        rm -f \"$output_file\" 2>/dev/null\n                    fi\n                else\n                    echo -e \"  ${RED}Failed to decode audio $((i+1))${NC}\"\n                    rm -f \"$output_file\" 2>/dev/null\n                fi\n            fi\n            i=$((i+1))\n        done\n    else\n        echo -e \"  ${YELLOW}No audio files in response${NC}\"\n    fi\n\n    # Save full response JSON (strip base64 audio to keep file small)\n    local clean_resp\n    clean_resp=$(jq 'del(.choices[].message.audio[].audio_url.url)' \"$resp_file\" 2>/dev/null)\n    if [ -n \"$clean_resp\" ]; then\n        save_result \"$job_id\" \"$clean_resp\"\n    else\n        save_result \"$job_id\" \"$(cat \"$resp_file\")\"\n    fi\n}\n\n# Send request to /v1/chat/completions and handle response\n# Usage: send_completion_request <api_url> <payload_file> <job_id_var>\nsend_completion_request() {\n    local api_url=\"$1\"\n    local payload_file=\"$2\"\n    local api_key=$(load_api_key)\n\n    local resp_file=$(mktemp)\n\n    local http_code\n    if [ -n \"$api_key\" ]; then\n        http_code=$(curl -s -w \"%{http_code}\" --connect-timeout 10 --max-time 660 \\\n            -o \"$resp_file\" \\\n            -X POST \"${api_url}/v1/chat/completions\" \\\n            -H \"Content-Type: application/json; charset=utf-8\" \\\n            -H \"Authorization: Bearer ${api_key}\" \\\n            -A \"curl/8.7.1\" \\\n            --data-binary \"@${payload_file}\")\n    else\n        http_code=$(curl -s -w \"%{http_code}\" --connect-timeout 10 --max-time 660 \\\n            -o \"$resp_file\" \\\n            -X POST \"${api_url}/v1/chat/completions\" \\\n            -H \"Content-Type: application/json; charset=utf-8\" \\\n            -A \"curl/8.7.1\" \\\n            --data-binary \"@${payload_file}\")\n    fi\n\n    rm -f \"$payload_file\"\n\n    if [ \"$http_code\" != \"200\" ]; then\n        local err_detail\n        err_detail=$(jq -r '.detail // .error.message // empty' \"$resp_file\" 2>/dev/null)\n        echo -e \"${RED}Error: HTTP $http_code${NC}\"\n        [ -n \"$err_detail\" ] && echo -e \"${RED}$err_detail${NC}\"\n        rm -f \"$resp_file\"\n        return 1\n    fi\n\n    # Generate a job_id from the completion id\n    local job_id\n    job_id=$(jq -r '.id // empty' \"$resp_file\" 2>/dev/null)\n    [ -z \"$job_id\" ] && job_id=\"completion-$(date +%s)\"\n\n    echo \"\"\n    echo -e \"${GREEN}Generation completed!${NC}\"\n    echo \"\"\n\n    parse_completion_response \"$resp_file\" \"$job_id\"\n    rm -f \"$resp_file\"\n\n    echo \"\"\n    echo -e \"${GREEN}Done! Files saved to: $OUTPUT_DIR${NC}\"\n    show_star_prompt\n}\n\n# Wait for job and download results\nwait_for_job() {\n    local api_url=\"$1\"\n    local job_id=\"$2\"\n\n    echo \"Job created: $job_id\"\n    echo \"Output: $OUTPUT_DIR\"\n    echo \"\"\n\n    while true; do\n        local response=$(query_job_result \"$api_url\" \"$job_id\")\n        local status=$(parse_query_status \"$response\")\n\n        case \"$status\" in\n            1)\n                echo \"\"\n                echo -e \"${GREEN}Generation completed!${NC}\"\n                echo \"\"\n\n                local result_file=$(mktemp)\n                parse_query_result \"$response\" > \"$result_file\"\n\n                local bpm=$(jq -r '.[0].metas.bpm // .[0].bpm // empty' \"$result_file\" 2>/dev/null)\n                local keyscale=$(jq -r '.[0].metas.keyscale // .[0].keyscale // empty' \"$result_file\" 2>/dev/null)\n                local duration=$(jq -r '.[0].metas.duration // .[0].duration // empty' \"$result_file\" 2>/dev/null)\n\n                echo \"Metadata:\"\n                [ -n \"$bpm\" ] && echo \"  BPM: $bpm\"\n                [ -n \"$keyscale\" ] && echo \"  Key: $keyscale\"\n                [ -n \"$duration\" ] && echo \"  Duration: ${duration}s\"\n                echo \"\"\n\n                # Save result JSON\n                save_result \"$job_id\" \"$response\"\n\n                # Download audio files\n                echo \"Downloading audio files...\"\n                download_audios \"$api_url\" \"$job_id\" \"$result_file\"\n                rm -f \"$result_file\"\n\n                echo \"\"\n                echo -e \"${GREEN}Done! Files saved to: $OUTPUT_DIR${NC}\"\n                show_star_prompt\n                return 0\n                ;;\n            2)\n                echo \"\"\n                echo -e \"${RED}Generation failed!${NC}\"\n\n                # Save error result\n                save_result \"$job_id\" \"$response\"\n                return 1\n                ;;\n            0)\n                printf \"\\rProcessing...              \"\n                ;;\n            *)\n                printf \"\\rWaiting...                 \"\n                ;;\n        esac\n        sleep 5\n    done\n}\n\n# Generate command\ncmd_generate() {\n    check_deps\n    ensure_config\n\n    local caption=\"\" lyrics=\"\" description=\"\" thinking=\"\" use_format=\"\"\n    local no_thinking=false no_format=false no_wait=false\n    local model=\"\" language=\"\" steps=\"\" guidance=\"\" seed=\"\" duration=\"\" bpm=\"\" batch=\"\"\n    local task_type=\"\" src_audio=\"\" cover_strength=\"\" repaint_start=\"\" repaint_end=\"\"\n    local key_scale=\"\" time_signature=\"\"\n\n    while [[ $# -gt 0 ]]; do\n        case $1 in\n            --caption|-c) caption=\"$2\"; shift 2 ;;\n            --lyrics|-l) lyrics=\"$2\"; shift 2 ;;\n            --description|-d) description=\"$2\"; shift 2 ;;\n            --thinking|-t) thinking=\"true\"; shift ;;\n            --no-thinking) no_thinking=true; shift ;;\n            --use-format) use_format=\"true\"; shift ;;\n            --no-format) no_format=true; shift ;;\n            --model|-m) model=\"$2\"; shift 2 ;;\n            --language|--vocal-language) language=\"$2\"; shift 2 ;;\n            --steps) steps=\"$2\"; shift 2 ;;\n            --guidance) guidance=\"$2\"; shift 2 ;;\n            --seed) seed=\"$2\"; shift 2 ;;\n            --duration) duration=\"$2\"; shift 2 ;;\n            --bpm) bpm=\"$2\"; shift 2 ;;\n            --batch) batch=\"$2\"; shift 2 ;;\n            --no-wait) no_wait=true; shift ;;\n            --task-type) task_type=\"$2\"; shift 2 ;;\n            --src-audio) src_audio=\"$2\"; shift 2 ;;\n            --cover-strength) cover_strength=\"$2\"; shift 2 ;;\n            --repaint-start) repaint_start=\"$2\"; shift 2 ;;\n            --repaint-end) repaint_end=\"$2\"; shift 2 ;;\n            --key-scale|--key) key_scale=\"$2\"; shift 2 ;;\n            --time-signature|--time-sig) time_signature=\"$2\"; shift 2 ;;\n            *) [ -z \"$caption\" ] && caption=\"$1\"; shift ;;\n        esac\n    done\n\n    # If no caption but has description, use simple mode\n    if [ -z \"$caption\" ] && [ -z \"$description\" ]; then\n        echo -e \"${RED}Error: caption or description required${NC}\"\n        echo \"Usage: $0 generate \\\"Music description\\\" [options]\"\n        echo \"       $0 generate -d \\\"Simple description\\\" [options]\"\n        exit 1\n    fi\n\n    local api_url=$(ensure_connection)\n\n    # Get defaults\n    local def_thinking=$(get_config \"generation.thinking\")\n    local def_format=$(get_config \"generation.use_format\")\n    local def_cot_caption=$(get_config \"generation.use_cot_caption\")\n    local def_cot_language=$(get_config \"generation.use_cot_language\")\n    local def_language=$(get_config \"generation.vocal_language\")\n    local def_audio_format=$(get_config \"generation.audio_format\")\n\n    [ -z \"$thinking\" ] && thinking=\"${def_thinking:-true}\"\n    [ -z \"$use_format\" ] && use_format=\"${def_format:-true}\"\n    [ -z \"$language\" ] && language=\"${def_language:-en}\"\n\n    [ \"$no_thinking\" = true ] && thinking=\"false\"\n    [ \"$no_format\" = true ] && use_format=\"false\"\n\n    # Normalize boolean values for jq --argjson\n    thinking=$(normalize_bool \"$thinking\" \"true\")\n    use_format=$(normalize_bool \"$use_format\" \"true\")\n    local cot_caption=$(normalize_bool \"$def_cot_caption\" \"true\")\n    local cot_language=$(normalize_bool \"$def_cot_language\" \"true\")\n\n    # Build payload using jq for proper escaping\n    local payload=$(jq -n \\\n        --arg prompt \"$caption\" \\\n        --arg lyrics \"${lyrics:-}\" \\\n        --arg sample_query \"${description:-}\" \\\n        --argjson thinking \"$thinking\" \\\n        --argjson use_format \"$use_format\" \\\n        --argjson use_cot_caption \"$cot_caption\" \\\n        --argjson use_cot_language \"$cot_language\" \\\n        --arg vocal_language \"$language\" \\\n        --arg audio_format \"${def_audio_format:-mp3}\" \\\n        '{\n            prompt: $prompt,\n            lyrics: $lyrics,\n            sample_query: $sample_query,\n            thinking: $thinking,\n            use_format: $use_format,\n            use_cot_caption: $use_cot_caption,\n            use_cot_language: $use_cot_language,\n            vocal_language: $vocal_language,\n            audio_format: $audio_format,\n            use_random_seed: true\n        }')\n\n    # Validate src_audio file exists if provided\n    if [ -n \"$src_audio\" ]; then\n        if [ ! -f \"$src_audio\" ]; then\n            echo -e \"${RED}Error: Source audio file not found: $src_audio${NC}\"\n            exit 1\n        fi\n        # Default task_type to \"cover\" when src_audio is provided\n        [ -z \"$task_type\" ] && task_type=\"cover\"\n    fi\n\n    # Add optional parameters\n    [ -n \"$model\" ] && payload=$(echo \"$payload\" | jq --arg v \"$model\" '. + {model: $v}')\n    [ -n \"$steps\" ] && payload=$(echo \"$payload\" | jq --argjson v \"$steps\" '. + {inference_steps: $v}')\n    [ -n \"$guidance\" ] && payload=$(echo \"$payload\" | jq --argjson v \"$guidance\" '. + {guidance_scale: $v}')\n    [ -n \"$seed\" ] && payload=$(echo \"$payload\" | jq --argjson v \"$seed\" '. + {seed: $v, use_random_seed: false}')\n    [ -n \"$duration\" ] && payload=$(echo \"$payload\" | jq --argjson v \"$duration\" '. + {audio_duration: $v}')\n    [ -n \"$bpm\" ] && payload=$(echo \"$payload\" | jq --argjson v \"$bpm\" '. + {bpm: $v}')\n    [ -n \"$batch\" ] && payload=$(echo \"$payload\" | jq --argjson v \"$batch\" '. + {batch_size: $v}')\n    [ -n \"$task_type\" ] && payload=$(echo \"$payload\" | jq --arg v \"$task_type\" '. + {task_type: $v}')\n    [ -n \"$src_audio\" ] && payload=$(echo \"$payload\" | jq --arg v \"$src_audio\" '. + {src_audio_path: $v}')\n    [ -n \"$cover_strength\" ] && payload=$(echo \"$payload\" | jq --argjson v \"$cover_strength\" '. + {audio_cover_strength: $v}')\n    [ -n \"$repaint_start\" ] && payload=$(echo \"$payload\" | jq --argjson v \"$repaint_start\" '. + {repainting_start: $v}')\n    [ -n \"$repaint_end\" ] && payload=$(echo \"$payload\" | jq --argjson v \"$repaint_end\" '. + {repainting_end: $v}')\n    [ -n \"$key_scale\" ] && payload=$(echo \"$payload\" | jq --arg v \"$key_scale\" '. + {key_scale: $v}')\n    [ -n \"$time_signature\" ] && payload=$(echo \"$payload\" | jq --arg v \"$time_signature\" '. + {time_signature: $v}')\n\n    local api_mode=$(load_api_mode)\n\n    echo \"Generating music...\"\n    if [ -n \"$task_type\" ] && [ \"$task_type\" != \"text2music\" ]; then\n        echo \"  Mode: $(echo \"$task_type\" | awk '{print toupper(substr($0,1,1)) substr($0,2)}') (${task_type})\"\n        [ -n \"$src_audio\" ] && echo \"  Source audio: $src_audio\"\n    elif [ -n \"$description\" ]; then\n        echo \"  Mode: Simple (description)\"\n        echo \"  Description: ${description:0:50}...\"\n    else\n        echo \"  Mode: Caption\"\n        echo \"  Caption: ${caption:0:50}...\"\n    fi\n    echo \"  Thinking: $thinking, Format: $use_format\"\n    echo \"  API: $api_mode\"\n    echo \"  Output: $OUTPUT_DIR\"\n    echo \"\"\n\n    if [ \"$api_mode\" = \"completion\" ]; then\n        # --- Completion mode: /v1/chat/completions ---\n        local model_id=$(get_completion_model \"$api_url\" \"$model\")\n\n        # Build message content parts\n        local message_content=\"\"\n        local sample_mode=false\n        if [ -n \"$description\" ]; then\n            message_content=\"$description\"\n            sample_mode=true\n        else\n            message_content=\"<prompt>${caption}</prompt>\"\n            [ -n \"$lyrics\" ] && message_content=\"${message_content}<lyrics>${lyrics}</lyrics>\"\n        fi\n\n        # Build completion payload\n        local payload_c\n        if [ -n \"$src_audio\" ]; then\n            # Audio input mode: use multipart content array with text + input_audio\n            # Encode audio to base64 using python to avoid shell argument limits\n            local audio_b64_file=$(mktemp)\n            python3 -c \"\nimport base64, sys\nwith open(sys.argv[1], 'rb') as f:\n    sys.stdout.write(base64.b64encode(f.read()).decode('ascii'))\n\" \"$src_audio\" > \"$audio_b64_file\"\n\n            local audio_ext=\"${src_audio##*.}\"\n            [ -z \"$audio_ext\" ] && audio_ext=\"mp3\"\n\n            # Build payload with audio using jq --rawfile to read base64 from file\n            payload_c=$(jq -n \\\n                --arg model \"$model_id\" \\\n                --arg text_content \"$message_content\" \\\n                --rawfile audio_b64 \"$audio_b64_file\" \\\n                --arg audio_format \"$audio_ext\" \\\n                --argjson thinking \"$thinking\" \\\n                --argjson use_format \"$use_format\" \\\n                --argjson sample_mode \"$sample_mode\" \\\n                --argjson use_cot_caption \"$cot_caption\" \\\n                --argjson use_cot_language \"$cot_language\" \\\n                --arg vocal_language \"$language\" \\\n                --arg format \"${def_audio_format:-mp3}\" \\\n                --arg task_type \"${task_type:-text2music}\" \\\n                '{\n                    model: $model,\n                    messages: [{\n                        \"role\": \"user\",\n                        \"content\": [\n                            {\"type\": \"text\", \"text\": $text_content},\n                            {\"type\": \"input_audio\", \"input_audio\": {\"data\": $audio_b64, \"format\": $audio_format}}\n                        ]\n                    }],\n                    stream: false,\n                    thinking: $thinking,\n                    use_format: $use_format,\n                    sample_mode: $sample_mode,\n                    use_cot_caption: $use_cot_caption,\n                    use_cot_language: $use_cot_language,\n                    task_type: $task_type,\n                    audio_config: {\n                        format: $format,\n                        vocal_language: $vocal_language\n                    }\n                }')\n\n            rm -f \"$audio_b64_file\"\n\n            # Add cover/repainting parameters\n            [ -n \"$cover_strength\" ] && payload_c=$(echo \"$payload_c\" | jq --argjson v \"$cover_strength\" '. + {audio_cover_strength: $v}')\n            [ -n \"$repaint_start\" ] && payload_c=$(echo \"$payload_c\" | jq --argjson v \"$repaint_start\" '. + {repainting_start: $v}')\n            [ -n \"$repaint_end\" ] && payload_c=$(echo \"$payload_c\" | jq --argjson v \"$repaint_end\" '. + {repainting_end: $v}')\n        else\n            # Text-only mode: use string content\n            payload_c=$(jq -n \\\n                --arg model \"$model_id\" \\\n                --arg content \"$message_content\" \\\n                --argjson thinking \"$thinking\" \\\n                --argjson use_format \"$use_format\" \\\n                --argjson sample_mode \"$sample_mode\" \\\n                --argjson use_cot_caption \"$cot_caption\" \\\n                --argjson use_cot_language \"$cot_language\" \\\n                --arg vocal_language \"$language\" \\\n                --arg format \"${def_audio_format:-mp3}\" \\\n                '{\n                    model: $model,\n                    messages: [{\"role\": \"user\", \"content\": $content}],\n                    stream: false,\n                    thinking: $thinking,\n                    use_format: $use_format,\n                    sample_mode: $sample_mode,\n                    use_cot_caption: $use_cot_caption,\n                    use_cot_language: $use_cot_language,\n                    audio_config: {\n                        format: $format,\n                        vocal_language: $vocal_language\n                    }\n                }')\n        fi\n\n        # Add optional parameters to completion payload\n        [ -n \"$guidance\" ] && payload_c=$(echo \"$payload_c\" | jq --argjson v \"$guidance\" '. + {guidance_scale: $v}')\n        [ -n \"$seed\" ] && payload_c=$(echo \"$payload_c\" | jq --argjson v \"$seed\" '. + {seed: $v}')\n        [ -n \"$batch\" ] && payload_c=$(echo \"$payload_c\" | jq --argjson v \"$batch\" '. + {batch_size: $v}')\n        [ -n \"$duration\" ] && payload_c=$(echo \"$payload_c\" | jq --argjson v \"$duration\" '.audio_config.duration = $v')\n        [ -n \"$bpm\" ] && payload_c=$(echo \"$payload_c\" | jq --argjson v \"$bpm\" '.audio_config.bpm = $v')\n        [ -n \"$key_scale\" ] && payload_c=$(echo \"$payload_c\" | jq --arg v \"$key_scale\" '.audio_config.key_scale = $v')\n        [ -n \"$time_signature\" ] && payload_c=$(echo \"$payload_c\" | jq --arg v \"$time_signature\" '.audio_config.time_signature = $v')\n\n        local temp_payload=$(mktemp)\n        printf '%s' \"$payload_c\" > \"$temp_payload\"\n\n        send_completion_request \"$api_url\" \"$temp_payload\"\n    else\n        # --- Native mode: /release_task + polling ---\n        local temp_payload=$(mktemp)\n        printf '%s' \"$payload\" > \"$temp_payload\"\n\n        local api_key=$(load_api_key)\n        local response\n        if [ -n \"$api_key\" ]; then\n            response=$(curl -s -X POST \"${api_url}/release_task\" \\\n                -H \"Content-Type: application/json; charset=utf-8\" \\\n                -H \"Authorization: Bearer ${api_key}\" \\\n                --data-binary \"@${temp_payload}\")\n        else\n            response=$(curl -s -X POST \"${api_url}/release_task\" \\\n                -H \"Content-Type: application/json; charset=utf-8\" \\\n                --data-binary \"@${temp_payload}\")\n        fi\n\n        rm -f \"$temp_payload\"\n\n        local job_id=$(echo \"$response\" | jq -r '.data.task_id // .task_id // empty')\n        [ -z \"$job_id\" ] && { echo -e \"${RED}Error: Failed to create job${NC}\"; echo \"$response\"; exit 1; }\n\n        if [ \"$no_wait\" = true ]; then\n            echo \"Job ID: $job_id\"\n            echo \"Use '$0 status $job_id' to check progress and download\"\n        else\n            wait_for_job \"$api_url\" \"$job_id\"\n        fi\n    fi\n}\n\n# Random command\ncmd_random() {\n    check_deps\n    ensure_config\n\n    local thinking=\"\" no_thinking=false no_wait=false\n\n    while [[ $# -gt 0 ]]; do\n        case $1 in\n            --thinking|-t) thinking=\"true\"; shift ;;\n            --no-thinking) no_thinking=true; shift ;;\n            --no-wait) no_wait=true; shift ;;\n            *) shift ;;\n        esac\n    done\n\n    local api_url=$(ensure_connection)\n\n    local def_thinking=$(get_config \"generation.thinking\")\n    [ -z \"$thinking\" ] && thinking=\"${def_thinking:-true}\"\n    [ \"$no_thinking\" = true ] && thinking=\"false\"\n\n    # Normalize boolean for jq --argjson\n    thinking=$(normalize_bool \"$thinking\" \"true\")\n\n    local api_mode=$(load_api_mode)\n\n    echo \"Generating random music...\"\n    echo \"  Thinking: $thinking\"\n    echo \"  API: $api_mode\"\n    echo \"  Output: $OUTPUT_DIR\"\n    echo \"\"\n\n    if [ \"$api_mode\" = \"completion\" ]; then\n        # --- Completion mode ---\n        local model_id=$(get_completion_model \"$api_url\" \"\")\n        local def_audio_format=$(get_config \"generation.audio_format\")\n\n        local payload_c=$(jq -n \\\n            --arg model \"$model_id\" \\\n            --argjson thinking \"$thinking\" \\\n            --arg format \"${def_audio_format:-mp3}\" \\\n            '{\n                model: $model,\n                messages: [{\"role\": \"user\", \"content\": \"Generate a random song\"}],\n                stream: false,\n                sample_mode: true,\n                thinking: $thinking,\n                audio_config: { format: $format }\n            }')\n\n        local temp_payload=$(mktemp)\n        printf '%s' \"$payload_c\" > \"$temp_payload\"\n\n        send_completion_request \"$api_url\" \"$temp_payload\"\n    else\n        # --- Native mode ---\n        local payload=$(jq -n --argjson thinking \"$thinking\" '{sample_mode: true, thinking: $thinking}')\n\n        local temp_payload=$(mktemp)\n        printf '%s' \"$payload\" > \"$temp_payload\"\n\n        local api_key=$(load_api_key)\n        local response\n        if [ -n \"$api_key\" ]; then\n            response=$(curl -s -X POST \"${api_url}/release_task\" \\\n                -H \"Content-Type: application/json; charset=utf-8\" \\\n                -H \"Authorization: Bearer ${api_key}\" \\\n                --data-binary \"@${temp_payload}\")\n        else\n            response=$(curl -s -X POST \"${api_url}/release_task\" \\\n                -H \"Content-Type: application/json; charset=utf-8\" \\\n                --data-binary \"@${temp_payload}\")\n        fi\n\n        rm -f \"$temp_payload\"\n\n        local job_id=$(echo \"$response\" | jq -r '.data.task_id // .task_id // empty')\n        [ -z \"$job_id\" ] && { echo -e \"${RED}Error: Failed to create job${NC}\"; echo \"$response\"; exit 1; }\n\n        if [ \"$no_wait\" = true ]; then\n            echo \"Job ID: $job_id\"\n            echo \"Use '$0 status $job_id' to check progress and download\"\n        else\n            wait_for_job \"$api_url\" \"$job_id\"\n        fi\n    fi\n}\n\n# Cover command (shortcut for generate --task-type cover --src-audio)\ncmd_cover() {\n    check_deps\n    ensure_config\n\n    local src_audio=\"\"\n    local args=()\n\n    # Extract src_audio as first positional arg, pass rest to generate\n    while [[ $# -gt 0 ]]; do\n        case $1 in\n            --src-audio) src_audio=\"$2\"; shift 2 ;;\n            -*) args+=(\"$1\"); shift ;;\n            *)\n                if [ -z \"$src_audio\" ]; then\n                    src_audio=\"$1\"; shift\n                else\n                    args+=(\"$1\"); shift\n                fi\n                ;;\n        esac\n    done\n\n    if [ -z \"$src_audio\" ]; then\n        echo -e \"${RED}Error: source audio file required${NC}\"\n        echo \"Usage: $0 cover <audio_file> -c \\\"caption\\\" -l \\\"lyrics\\\" [options]\"\n        exit 1\n    fi\n\n    cmd_generate --src-audio \"$src_audio\" --task-type cover \"${args[@]}\"\n}\n\n# Help\nshow_help() {\n    echo \"ACE-Step Music Generation CLI\"\n    echo \"\"\n    echo \"Requirements: curl, jq\"\n    echo \"\"\n    echo \"Usage: $0 <command> [options]\"\n    echo \"\"\n    echo \"Commands:\"\n    echo \"  generate    Generate music from text\"\n    echo \"  cover       Cover/repainting from source audio\"\n    echo \"  random      Generate random music\"\n    echo \"  status      Check job status and download results\"\n    echo \"  models      List available models\"\n    echo \"  health      Check API health\"\n    echo \"  config      Manage configuration\"\n    echo \"\"\n    echo \"Output:\"\n    echo \"  Results saved to: $OUTPUT_DIR/<job_id>.json\"\n    echo \"  Audio files: $OUTPUT_DIR/<job_id>_1.mp3, ...\"\n    echo \"\"\n    echo \"Generate Options:\"\n    echo \"  -c, --caption       Music style/genre description (caption mode)\"\n    echo \"  -d, --description   Simple description, LM auto-generates caption/lyrics\"\n    echo \"  -l, --lyrics        Lyrics text\"\n    echo \"  -t, --thinking      Enable thinking mode (default: true)\"\n    echo \"  --no-thinking       Disable thinking mode\"\n    echo \"  --no-format         Disable format enhancement\"\n    echo \"  --duration          Duration in seconds\"\n    echo \"  --bpm               Beats per minute\"\n    echo \"  --key-scale         Musical key (e.g. \\\"E minor\\\")\"\n    echo \"  --time-signature    Time signature (e.g. \\\"4/4\\\")\"\n    echo \"\"\n    echo \"Cover/Repainting Options:\"\n    echo \"  --src-audio         Source audio file path\"\n    echo \"  --task-type         Task type: cover, repaint, text2music (default: auto)\"\n    echo \"  --cover-strength    Cover strength 0.0-1.0 (default: 1.0)\"\n    echo \"  --repaint-start     Repainting start position in seconds\"\n    echo \"  --repaint-end       Repainting end position in seconds\"\n    echo \"\"\n    echo \"Examples:\"\n    echo \"  $0 generate \\\"Pop music with guitar\\\"           # Caption mode\"\n    echo \"  $0 generate -d \\\"A February love song\\\"         # Simple mode (LM generates)\"\n    echo \"  $0 generate -c \\\"Jazz\\\" -l \\\"[Verse] Hello\\\"      # With lyrics\"\n    echo \"  $0 cover song.mp3 -c \\\"Rock cover\\\" -l \\\"[Verse] ...\\\" --duration 120\"\n    echo \"  $0 generate --src-audio song.mp3 --task-type repaint -c \\\"Pop\\\" --repaint-start 30 --repaint-end 60\"\n    echo \"  $0 random\"\n    echo \"  $0 status <job_id>\"\n    echo \"  $0 config --set generation.thinking false\"\n}\n\n# Main\ncase \"$1\" in\n    generate) shift; cmd_generate \"$@\" ;;\n    cover) shift; cmd_cover \"$@\" ;;\n    random) shift; cmd_random \"$@\" ;;\n    status) shift; cmd_status \"$@\" ;;\n    models) cmd_models ;;\n    health) cmd_health ;;\n    config) shift; cmd_config \"$@\" ;;\n    help|--help|-h) show_help ;;\n    *) show_help; exit 1 ;;\nesac\n"
  },
  {
    "path": ".claude/skills/acestep/scripts/config.example.json",
    "content": "{\n  \"api_url\": \"https://api.acemusic.ai\",\n  \"api_key\": \"\",\n  \"api_mode\": \"completion\",\n  \"generation\": {\n    \"thinking\": true,\n    \"use_format\": false,\n    \"use_cot_caption\": true,\n    \"use_cot_language\": false,\n    \"audio_format\": \"mp3\",\n    \"batch_size\": 1,\n    \"vocal_language\": \"en\"\n  }\n}\n"
  },
  {
    "path": ".claude/skills/acestep-docs/SKILL.md",
    "content": "---\nname: acestep-docs\ndescription: ACE-Step documentation and troubleshooting. Use when users ask about installing ACE-Step, GPU configuration, model download, Gradio UI usage, API integration, or troubleshooting issues like VRAM problems, CUDA errors, or model loading failures.\nallowed-tools: Read, Glob, Grep\n---\n\n# ACE-Step Documentation\n\nDocumentation skill for ACE-Step music generation system.\n\n## Quick Reference\n\n### Getting Started\n| Document | Description |\n|----------|-------------|\n| [README.md](getting-started/README.md) | Installation, model download, startup commands |\n| [Tutorial.md](getting-started/Tutorial.md) | Getting started tutorial, best practices |\n| [ABOUT.md](getting-started/ABOUT.md) | Project overview, architecture, model zoo |\n\n### Guides\n| Document | Description |\n|----------|-------------|\n| [GRADIO_GUIDE.md](guides/GRADIO_GUIDE.md) | Web UI usage guide |\n| [INFERENCE.md](guides/INFERENCE.md) | Inference parameters tuning |\n| [GPU_COMPATIBILITY.md](guides/GPU_COMPATIBILITY.md) | GPU/VRAM configuration, hardware recommendations |\n| [ENVIRONMENT_SETUP.md](guides/ENVIRONMENT_SETUP.md) | Environment detection, uv installation, python_embeded setup (Windows/Linux/macOS) |\n| [SCRIPT_CONFIGURATION.md](guides/SCRIPT_CONFIGURATION.md) | Configuring launch scripts: .bat (Windows) and .sh (Linux/macOS) |\n| [UPDATE_AND_BACKUP.md](guides/UPDATE_AND_BACKUP.md) | Git updates, file backup, conflict resolution (all platforms) |\n\n### API (for developers)\n| Document | Description |\n|----------|-------------|\n| [API.md](api/API.md) | REST API documentation |\n| [Openrouter_API.md](api/Openrouter_API.md) | OpenRouter API integration |\n\n## Instructions\n\n1. Installation questions → read [getting-started/README.md](getting-started/README.md)\n2. General usage / best practices → read [getting-started/Tutorial.md](getting-started/Tutorial.md)\n3. Project overview / architecture → read [getting-started/ABOUT.md](getting-started/ABOUT.md)\n4. Web UI questions → read [guides/GRADIO_GUIDE.md](guides/GRADIO_GUIDE.md)\n5. Inference parameter tuning → read [guides/INFERENCE.md](guides/INFERENCE.md)\n6. GPU/VRAM issues → read [guides/GPU_COMPATIBILITY.md](guides/GPU_COMPATIBILITY.md)\n7. Environment setup (uv, python_embeded) → read [guides/ENVIRONMENT_SETUP.md](guides/ENVIRONMENT_SETUP.md)\n8. Launch script configuration (.bat/.sh) → read [guides/SCRIPT_CONFIGURATION.md](guides/SCRIPT_CONFIGURATION.md)\n9. Updates and backup → read [guides/UPDATE_AND_BACKUP.md](guides/UPDATE_AND_BACKUP.md)\n10. API development → read [api/API.md](api/API.md) or [api/Openrouter_API.md](api/Openrouter_API.md)\n\n## Common Issues\n\n- **Installation problems**: See getting-started/README.md\n- **VRAM insufficient**: See guides/GPU_COMPATIBILITY.md\n- **Model download failed**: See getting-started/README.md or guides/SCRIPT_CONFIGURATION.md\n- **uv not found**: See guides/ENVIRONMENT_SETUP.md\n- **Environment detection issues**: See guides/ENVIRONMENT_SETUP.md\n- **BAT/SH script configuration**: See guides/SCRIPT_CONFIGURATION.md\n- **Update and backup**: See guides/UPDATE_AND_BACKUP.md\n- **Update conflicts**: See guides/UPDATE_AND_BACKUP.md\n- **Inference quality issues**: See guides/INFERENCE.md\n- **Gradio UI not starting**: See guides/GRADIO_GUIDE.md\n"
  },
  {
    "path": ".claude/skills/acestep-docs/api/API.md",
    "content": "# ACE-Step API Client Documentation\n\n---\n\nThis service provides an HTTP-based asynchronous music generation API.\n\n**Basic Workflow**:\n1. Call `POST /release_task` to submit a task and obtain a `task_id`.\n2. Call `POST /query_result` to batch query task status until `status` is `1` (succeeded) or `2` (failed).\n3. Download audio files via `GET /v1/audio?path=...` URLs returned in the result.\n\n---\n\n## Table of Contents\n\n- [Authentication](#1-authentication)\n- [Response Format](#2-response-format)\n- [Task Status Description](#3-task-status-description)\n- [Create Generation Task](#4-create-generation-task)\n- [Batch Query Task Results](#5-batch-query-task-results)\n- [Format Input](#6-format-input)\n- [Get Random Sample](#7-get-random-sample)\n- [List Available Models](#8-list-available-models)\n- [Server Statistics](#9-server-statistics)\n- [Download Audio Files](#10-download-audio-files)\n- [Health Check](#11-health-check)\n- [Environment Variables](#12-environment-variables)\n\n---\n\n## 1. Authentication\n\nThe API supports optional API key authentication. When enabled, a valid key must be provided in requests.\n\n### Authentication Methods\n\nTwo authentication methods are supported:\n\n**Method A: ai_token in request body**\n\n```json\n{\n  \"ai_token\": \"your-api-key\",\n  \"prompt\": \"upbeat pop song\",\n  ...\n}\n```\n\n**Method B: Authorization header**\n\n```bash\ncurl -X POST http://localhost:8001/release_task \\\n  -H 'Authorization: Bearer your-api-key' \\\n  -H 'Content-Type: application/json' \\\n  -d '{\"prompt\": \"upbeat pop song\"}'\n```\n\n### Configuring API Key\n\nSet via environment variable or command-line argument:\n\n```bash\n# Environment variable\nexport ACESTEP_API_KEY=your-secret-key\n\n# Or command-line argument\npython -m acestep.api_server --api-key your-secret-key\n```\n\n---\n\n## 2. Response Format\n\nAll API responses use a unified wrapper format:\n\n```json\n{\n  \"data\": { ... },\n  \"code\": 200,\n  \"error\": null,\n  \"timestamp\": 1700000000000,\n  \"extra\": null\n}\n```\n\n| Field | Type | Description |\n| :--- | :--- | :--- |\n| `data` | any | Actual response data |\n| `code` | int | Status code (200=success) |\n| `error` | string | Error message (null on success) |\n| `timestamp` | int | Response timestamp (milliseconds) |\n| `extra` | any | Extra information (usually null) |\n\n---\n\n## 3. Task Status Description\n\nTask status (`status`) is represented as integers:\n\n| Status Code | Status Name | Description |\n| :--- | :--- | :--- |\n| `0` | queued/running | Task is queued or in progress |\n| `1` | succeeded | Generation succeeded, result is ready |\n| `2` | failed | Generation failed |\n\n---\n\n## 4. Create Generation Task\n\n### 4.1 API Definition\n\n- **URL**: `/release_task`\n- **Method**: `POST`\n- **Content-Type**: `application/json`, `multipart/form-data`, or `application/x-www-form-urlencoded`\n\n### 4.2 Request Parameters\n\n#### Parameter Naming Convention\n\nThe API supports both **snake_case** and **camelCase** naming for most parameters. For example:\n- `audio_duration` / `duration` / `audioDuration`\n- `key_scale` / `keyscale` / `keyScale`\n- `time_signature` / `timesignature` / `timeSignature`\n- `sample_query` / `sampleQuery` / `description` / `desc`\n- `use_format` / `useFormat` / `format`\n\nAdditionally, metadata can be passed in a nested object (`metas`, `metadata`, or `user_metadata`).\n\n#### Method A: JSON Request (application/json)\n\nSuitable for passing only text parameters, or referencing audio file paths that already exist on the server.\n\n**Basic Parameters**:\n\n| Parameter Name | Type | Default | Description |\n| :--- | :--- | :--- | :--- |\n| `prompt` | string | `\"\"` | Music description prompt (alias: `caption`) |\n| `lyrics` | string | `\"\"` | Lyrics content |\n| `thinking` | bool | `false` | Whether to use 5Hz LM to generate audio codes (lm-dit behavior) |\n| `vocal_language` | string | `\"en\"` | Lyrics language (en, zh, ja, etc.) |\n| `audio_format` | string | `\"mp3\"` | Output format (mp3, wav, flac) |\n\n**Sample/Description Mode Parameters**:\n\n| Parameter Name | Type | Default | Description |\n| :--- | :--- | :--- | :--- |\n| `sample_mode` | bool | `false` | Enable random sample generation mode (auto-generates caption/lyrics/metas via LM) |\n| `sample_query` | string | `\"\"` | Natural language description for sample generation (e.g., \"a soft Bengali love song\"). Aliases: `description`, `desc` |\n| `use_format` | bool | `false` | Use LM to enhance/format the provided caption and lyrics. Alias: `format` |\n\n**Multi-Model Support**:\n\n| Parameter Name | Type | Default | Description |\n| :--- | :--- | :--- | :--- |\n| `model` | string | null | Select which DiT model to use (e.g., `\"acestep-v15-turbo\"`, `\"acestep-v15-turbo-shift3\"`). Use `/v1/models` to list available models. If not specified, uses the default model. |\n\n**thinking Semantics (Important)**:\n\n- `thinking=false`:\n  - The server will **NOT** use 5Hz LM to generate `audio_code_string`.\n  - DiT runs in **text2music** mode and **ignores** any provided `audio_code_string`.\n- `thinking=true`:\n  - The server will use 5Hz LM to generate `audio_code_string` (lm-dit behavior).\n  - DiT runs with LM-generated codes for enhanced music quality.\n\n**Metadata Auto-Completion (Conditional)**:\n\nWhen `use_cot_caption=true` or `use_cot_language=true` or metadata fields are missing, the server may call 5Hz LM to fill the missing fields based on `caption`/`lyrics`:\n\n- `bpm`\n- `key_scale`\n- `time_signature`\n- `audio_duration`\n\nUser-provided values always win; LM only fills the fields that are empty/missing.\n\n**Music Attribute Parameters**:\n\n| Parameter Name | Type | Default | Description |\n| :--- | :--- | :--- | :--- |\n| `bpm` | int | null | Specify tempo (BPM), range 30-300 |\n| `key_scale` | string | `\"\"` | Key/scale (e.g., \"C Major\", \"Am\"). Aliases: `keyscale`, `keyScale` |\n| `time_signature` | string | `\"\"` | Time signature (2, 3, 4, 6 for 2/4, 3/4, 4/4, 6/8). Aliases: `timesignature`, `timeSignature` |\n| `audio_duration` | float | null | Generation duration (seconds), range 10-600. Aliases: `duration`, `target_duration` |\n\n**Audio Codes (Optional)**:\n\n| Parameter Name | Type | Default | Description |\n| :--- | :--- | :--- | :--- |\n| `audio_code_string` | string or string[] | `\"\"` | Audio semantic tokens (5Hz) for `llm_dit`. Alias: `audioCodeString` |\n\n**Generation Control Parameters**:\n\n| Parameter Name | Type | Default | Description |\n| :--- | :--- | :--- | :--- |\n| `inference_steps` | int | `8` | Number of inference steps. Turbo model: 1-20 (recommended 8). Base model: 1-200 (recommended 32-64). |\n| `guidance_scale` | float | `7.0` | Prompt guidance coefficient. Only effective for base model. |\n| `use_random_seed` | bool | `true` | Whether to use random seed |\n| `seed` | int | `-1` | Specify seed (when use_random_seed=false) |\n| `batch_size` | int | `2` | Batch generation count (max 8) |\n\n**Advanced DiT Parameters**:\n\n| Parameter Name | Type | Default | Description |\n| :--- | :--- | :--- | :--- |\n| `shift` | float | `3.0` | Timestep shift factor (range 1.0-5.0). Only effective for base models, not turbo models. |\n| `infer_method` | string | `\"ode\"` | Diffusion inference method: `\"ode\"` (Euler, faster) or `\"sde\"` (stochastic). |\n| `timesteps` | string | null | Custom timesteps as comma-separated values (e.g., `\"0.97,0.76,0.615,0.5,0.395,0.28,0.18,0.085,0\"`). Overrides `inference_steps` and `shift`. |\n| `use_adg` | bool | `false` | Use Adaptive Dual Guidance (base model only) |\n| `cfg_interval_start` | float | `0.0` | CFG application start ratio (0.0-1.0) |\n| `cfg_interval_end` | float | `1.0` | CFG application end ratio (0.0-1.0) |\n\n**5Hz LM Parameters (Optional, server-side)**:\n\nThese parameters control 5Hz LM sampling, used for metadata auto-completion and (when `thinking=true`) codes generation.\n\n| Parameter Name | Type | Default | Description |\n| :--- | :--- | :--- | :--- |\n| `lm_model_path` | string | null | 5Hz LM checkpoint dir name (e.g. `acestep-5Hz-lm-0.6B`) |\n| `lm_backend` | string | `\"vllm\"` | `vllm` or `pt` |\n| `lm_temperature` | float | `0.85` | Sampling temperature |\n| `lm_cfg_scale` | float | `2.5` | CFG scale (>1 enables CFG) |\n| `lm_negative_prompt` | string | `\"NO USER INPUT\"` | Negative prompt used by CFG |\n| `lm_top_k` | int | null | Top-k (0/null disables) |\n| `lm_top_p` | float | `0.9` | Top-p (>=1 will be treated as disabled) |\n| `lm_repetition_penalty` | float | `1.0` | Repetition penalty |\n\n**LM CoT (Chain-of-Thought) Parameters**:\n\n| Parameter Name | Type | Default | Description |\n| :--- | :--- | :--- | :--- |\n| `use_cot_caption` | bool | `true` | Let LM rewrite/enhance the input caption via CoT reasoning. Aliases: `cot_caption`, `cot-caption` |\n| `use_cot_language` | bool | `true` | Let LM detect vocal language via CoT. Aliases: `cot_language`, `cot-language` |\n| `constrained_decoding` | bool | `true` | Enable FSM-based constrained decoding for structured LM output. Aliases: `constrainedDecoding`, `constrained` |\n| `constrained_decoding_debug` | bool | `false` | Enable debug logging for constrained decoding |\n| `allow_lm_batch` | bool | `true` | Allow LM batch processing for efficiency |\n\n**Edit/Reference Audio Parameters** (requires absolute path on server):\n\n| Parameter Name | Type | Default | Description |\n| :--- | :--- | :--- | :--- |\n| `reference_audio_path` | string | null | Reference audio path (Style Transfer) |\n| `src_audio_path` | string | null | Source audio path (Repainting/Cover) |\n| `task_type` | string | `\"text2music\"` | Task type: `text2music`, `cover`, `repaint`, `lego`, `extract`, `complete` |\n| `instruction` | string | auto | Edit instruction (auto-generated based on task_type if not provided) |\n| `repainting_start` | float | `0.0` | Repainting start time (seconds) |\n| `repainting_end` | float | null | Repainting end time (seconds), -1 for end of audio |\n| `audio_cover_strength` | float | `1.0` | Cover strength (0.0-1.0). Lower values (0.2) for style transfer. |\n\n#### Method B: File Upload (multipart/form-data)\n\nUse this when you need to upload local audio files as reference or source audio.\n\nIn addition to supporting all the above fields as Form Fields, the following file fields are also supported:\n\n- `reference_audio` or `ref_audio`: (File) Upload reference audio file\n- `src_audio` or `ctx_audio`: (File) Upload source audio file\n\n> **Note**: After uploading files, the corresponding `_path` parameters will be automatically ignored, and the system will use the temporary file path after upload.\n\n### 4.3 Response Example\n\n```json\n{\n  \"data\": {\n    \"task_id\": \"550e8400-e29b-41d4-a716-446655440000\",\n    \"status\": \"queued\",\n    \"queue_position\": 1\n  },\n  \"code\": 200,\n  \"error\": null,\n  \"timestamp\": 1700000000000,\n  \"extra\": null\n}\n```\n\n### 4.4 Usage Examples (cURL)\n\n**Basic JSON Method**:\n\n```bash\ncurl -X POST http://localhost:8001/release_task \\\n  -H 'Content-Type: application/json' \\\n  -d '{\n    \"prompt\": \"upbeat pop song\",\n    \"lyrics\": \"Hello world\",\n    \"inference_steps\": 8\n  }'\n```\n\n**With thinking=true (LM generates codes + fills missing metas)**:\n\n```bash\ncurl -X POST http://localhost:8001/release_task \\\n  -H 'Content-Type: application/json' \\\n  -d '{\n    \"prompt\": \"upbeat pop song\",\n    \"lyrics\": \"Hello world\",\n    \"thinking\": true,\n    \"lm_temperature\": 0.85,\n    \"lm_cfg_scale\": 2.5\n  }'\n```\n\n**Description-driven generation (sample_query)**:\n\n```bash\ncurl -X POST http://localhost:8001/release_task \\\n  -H 'Content-Type: application/json' \\\n  -d '{\n    \"sample_query\": \"a soft Bengali love song for a quiet evening\",\n    \"thinking\": true\n  }'\n```\n\n**With format enhancement (use_format=true)**:\n\n```bash\ncurl -X POST http://localhost:8001/release_task \\\n  -H 'Content-Type: application/json' \\\n  -d '{\n    \"prompt\": \"pop rock\",\n    \"lyrics\": \"[Verse 1]\\nWalking down the street...\",\n    \"use_format\": true,\n    \"thinking\": true\n  }'\n```\n\n**Select specific model**:\n\n```bash\ncurl -X POST http://localhost:8001/release_task \\\n  -H 'Content-Type: application/json' \\\n  -d '{\n    \"prompt\": \"electronic dance music\",\n    \"model\": \"acestep-v15-turbo\",\n    \"thinking\": true\n  }'\n```\n\n**With custom timesteps**:\n\n```bash\ncurl -X POST http://localhost:8001/release_task \\\n  -H 'Content-Type: application/json' \\\n  -d '{\n    \"prompt\": \"jazz piano trio\",\n    \"timesteps\": \"0.97,0.76,0.615,0.5,0.395,0.28,0.18,0.085,0\",\n    \"thinking\": true\n  }'\n```\n\n**File Upload Method**:\n\n```bash\ncurl -X POST http://localhost:8001/release_task \\\n  -F \"prompt=remix this song\" \\\n  -F \"src_audio=@/path/to/local/song.mp3\" \\\n  -F \"task_type=repaint\"\n```\n\n---\n\n## 5. Batch Query Task Results\n\n### 5.1 API Definition\n\n- **URL**: `/query_result`\n- **Method**: `POST`\n- **Content-Type**: `application/json` or `application/x-www-form-urlencoded`\n\n### 5.2 Request Parameters\n\n| Parameter Name | Type | Description |\n| :--- | :--- | :--- |\n| `task_id_list` | string (JSON array) or array | List of task IDs to query |\n\n### 5.3 Response Example\n\n```json\n{\n  \"data\": [\n    {\n      \"task_id\": \"550e8400-e29b-41d4-a716-446655440000\",\n      \"status\": 1,\n      \"result\": \"[{\\\"file\\\": \\\"/v1/audio?path=...\\\", \\\"wave\\\": \\\"\\\", \\\"status\\\": 1, \\\"create_time\\\": 1700000000, \\\"env\\\": \\\"development\\\", \\\"prompt\\\": \\\"upbeat pop song\\\", \\\"lyrics\\\": \\\"Hello world\\\", \\\"metas\\\": {\\\"bpm\\\": 120, \\\"duration\\\": 30, \\\"genres\\\": \\\"\\\", \\\"keyscale\\\": \\\"C Major\\\", \\\"timesignature\\\": \\\"4\\\"}, \\\"generation_info\\\": \\\"...\\\", \\\"seed_value\\\": \\\"12345,67890\\\", \\\"lm_model\\\": \\\"acestep-5Hz-lm-0.6B\\\", \\\"dit_model\\\": \\\"acestep-v15-turbo\\\"}]\"\n    }\n  ],\n  \"code\": 200,\n  \"error\": null,\n  \"timestamp\": 1700000000000,\n  \"extra\": null\n}\n```\n\n**Result Field Description** (result is a JSON string, after parsing contains):\n\n| Field | Type | Description |\n| :--- | :--- | :--- |\n| `file` | string | Audio file URL (use with `/v1/audio` endpoint) |\n| `wave` | string | Waveform data (usually empty) |\n| `status` | int | Status code (0=in progress, 1=success, 2=failed) |\n| `create_time` | int | Creation time (Unix timestamp) |\n| `env` | string | Environment identifier |\n| `prompt` | string | Prompt used |\n| `lyrics` | string | Lyrics used |\n| `metas` | object | Metadata (bpm, duration, genres, keyscale, timesignature) |\n| `generation_info` | string | Generation info summary |\n| `seed_value` | string | Seed values used (comma-separated) |\n| `lm_model` | string | LM model name used |\n| `dit_model` | string | DiT model name used |\n\n### 5.4 Usage Example\n\n```bash\ncurl -X POST http://localhost:8001/query_result \\\n  -H 'Content-Type: application/json' \\\n  -d '{\n    \"task_id_list\": [\"550e8400-e29b-41d4-a716-446655440000\"]\n  }'\n```\n\n---\n\n## 6. Format Input\n\n### 6.1 API Definition\n\n- **URL**: `/format_input`\n- **Method**: `POST`\n\nThis endpoint uses LLM to enhance and format user-provided caption and lyrics.\n\n### 6.2 Request Parameters\n\n| Parameter Name | Type | Default | Description |\n| :--- | :--- | :--- | :--- |\n| `prompt` | string | `\"\"` | Music description prompt |\n| `lyrics` | string | `\"\"` | Lyrics content |\n| `temperature` | float | `0.85` | LM sampling temperature |\n| `param_obj` | string (JSON) | `\"{}\"` | JSON object containing metadata (duration, bpm, key, time_signature, language) |\n\n### 6.3 Response Example\n\n```json\n{\n  \"data\": {\n    \"caption\": \"Enhanced music description\",\n    \"lyrics\": \"Formatted lyrics...\",\n    \"bpm\": 120,\n    \"key_scale\": \"C Major\",\n    \"time_signature\": \"4\",\n    \"duration\": 180,\n    \"vocal_language\": \"en\"\n  },\n  \"code\": 200,\n  \"error\": null,\n  \"timestamp\": 1700000000000,\n  \"extra\": null\n}\n```\n\n### 6.4 Usage Example\n\n```bash\ncurl -X POST http://localhost:8001/format_input \\\n  -H 'Content-Type: application/json' \\\n  -d '{\n    \"prompt\": \"pop rock\",\n    \"lyrics\": \"Walking down the street\",\n    \"param_obj\": \"{\\\"duration\\\": 180, \\\"language\\\": \\\"en\\\"}\"\n  }'\n```\n\n---\n\n## 7. Get Random Sample\n\n### 7.1 API Definition\n\n- **URL**: `/create_random_sample`\n- **Method**: `POST`\n\nThis endpoint returns random sample parameters from pre-loaded example data for form filling.\n\n### 7.2 Request Parameters\n\n| Parameter Name | Type | Default | Description |\n| :--- | :--- | :--- | :--- |\n| `sample_type` | string | `\"simple_mode\"` | Sample type: `\"simple_mode\"` or `\"custom_mode\"` |\n\n### 7.3 Response Example\n\n```json\n{\n  \"data\": {\n    \"caption\": \"Upbeat pop song with guitar accompaniment\",\n    \"lyrics\": \"[Verse 1]\\nSunshine on my face...\",\n    \"bpm\": 120,\n    \"key_scale\": \"G Major\",\n    \"time_signature\": \"4\",\n    \"duration\": 180,\n    \"vocal_language\": \"en\"\n  },\n  \"code\": 200,\n  \"error\": null,\n  \"timestamp\": 1700000000000,\n  \"extra\": null\n}\n```\n\n### 7.4 Usage Example\n\n```bash\ncurl -X POST http://localhost:8001/create_random_sample \\\n  -H 'Content-Type: application/json' \\\n  -d '{\"sample_type\": \"simple_mode\"}'\n```\n\n---\n\n## 8. List Available Models\n\n### 8.1 API Definition\n\n- **URL**: `/v1/models`\n- **Method**: `GET`\n\nReturns a list of available DiT models loaded on the server.\n\n### 8.2 Response Example\n\n```json\n{\n  \"data\": {\n    \"models\": [\n      {\n        \"name\": \"acestep-v15-turbo\",\n        \"is_default\": true\n      },\n      {\n        \"name\": \"acestep-v15-turbo-shift3\",\n        \"is_default\": false\n      }\n    ],\n    \"default_model\": \"acestep-v15-turbo\"\n  },\n  \"code\": 200,\n  \"error\": null,\n  \"timestamp\": 1700000000000,\n  \"extra\": null\n}\n```\n\n### 8.3 Usage Example\n\n```bash\ncurl http://localhost:8001/v1/models\n```\n\n---\n\n## 9. Server Statistics\n\n### 9.1 API Definition\n\n- **URL**: `/v1/stats`\n- **Method**: `GET`\n\nReturns server runtime statistics.\n\n### 9.2 Response Example\n\n```json\n{\n  \"data\": {\n    \"jobs\": {\n      \"total\": 100,\n      \"queued\": 5,\n      \"running\": 1,\n      \"succeeded\": 90,\n      \"failed\": 4\n    },\n    \"queue_size\": 5,\n    \"queue_maxsize\": 200,\n    \"avg_job_seconds\": 8.5\n  },\n  \"code\": 200,\n  \"error\": null,\n  \"timestamp\": 1700000000000,\n  \"extra\": null\n}\n```\n\n### 9.3 Usage Example\n\n```bash\ncurl http://localhost:8001/v1/stats\n```\n\n---\n\n## 10. Download Audio Files\n\n### 10.1 API Definition\n\n- **URL**: `/v1/audio`\n- **Method**: `GET`\n\nDownload generated audio files by path.\n\n### 10.2 Request Parameters\n\n| Parameter Name | Type | Description |\n| :--- | :--- | :--- |\n| `path` | string | URL-encoded path to the audio file |\n\n### 10.3 Usage Example\n\n```bash\n# Download using the URL from task result\ncurl \"http://localhost:8001/v1/audio?path=%2Ftmp%2Fapi_audio%2Fabc123.mp3\" -o output.mp3\n```\n\n---\n\n## 11. Health Check\n\n### 11.1 API Definition\n\n- **URL**: `/health`\n- **Method**: `GET`\n\nReturns service health status.\n\n### 11.2 Response Example\n\n```json\n{\n  \"data\": {\n    \"status\": \"ok\",\n    \"service\": \"ACE-Step API\",\n    \"version\": \"1.0\"\n  },\n  \"code\": 200,\n  \"error\": null,\n  \"timestamp\": 1700000000000,\n  \"extra\": null\n}\n```\n\n---\n\n## 12. Environment Variables\n\nThe API server can be configured using environment variables:\n\n### Server Configuration\n\n| Variable | Default | Description |\n| :--- | :--- | :--- |\n| `ACESTEP_API_HOST` | `127.0.0.1` | Server bind host |\n| `ACESTEP_API_PORT` | `8001` | Server bind port |\n| `ACESTEP_API_KEY` | (empty) | API authentication key (empty disables auth) |\n| `ACESTEP_API_WORKERS` | `1` | API worker thread count |\n\n### Model Configuration\n\n| Variable | Default | Description |\n| :--- | :--- | :--- |\n| `ACESTEP_CONFIG_PATH` | `acestep-v15-turbo` | Primary DiT model path |\n| `ACESTEP_CONFIG_PATH2` | (empty) | Secondary DiT model path (optional) |\n| `ACESTEP_CONFIG_PATH3` | (empty) | Third DiT model path (optional) |\n| `ACESTEP_DEVICE` | `auto` | Device for model loading |\n| `ACESTEP_USE_FLASH_ATTENTION` | `true` | Enable flash attention |\n| `ACESTEP_OFFLOAD_TO_CPU` | `false` | Offload models to CPU when idle |\n| `ACESTEP_OFFLOAD_DIT_TO_CPU` | `false` | Offload DiT specifically to CPU |\n\n### LM Configuration\n\n| Variable | Default | Description |\n| :--- | :--- | :--- |\n| `ACESTEP_INIT_LLM` | auto | Whether to initialize LM at startup (auto determines based on GPU) |\n| `ACESTEP_LM_MODEL_PATH` | `acestep-5Hz-lm-0.6B` | Default 5Hz LM model |\n| `ACESTEP_LM_BACKEND` | `vllm` | LM backend (vllm or pt) |\n| `ACESTEP_LM_DEVICE` | (same as ACESTEP_DEVICE) | Device for LM |\n| `ACESTEP_LM_OFFLOAD_TO_CPU` | `false` | Offload LM to CPU |\n\n### Queue Configuration\n\n| Variable | Default | Description |\n| :--- | :--- | :--- |\n| `ACESTEP_QUEUE_MAXSIZE` | `200` | Maximum queue size |\n| `ACESTEP_QUEUE_WORKERS` | `1` | Number of queue workers |\n| `ACESTEP_AVG_JOB_SECONDS` | `5.0` | Initial average job duration estimate |\n| `ACESTEP_AVG_WINDOW` | `50` | Window for averaging job duration |\n\n### Cache Configuration\n\n| Variable | Default | Description |\n| :--- | :--- | :--- |\n| `ACESTEP_TMPDIR` | `.cache/acestep/tmp` | Temporary file directory |\n| `TRITON_CACHE_DIR` | `.cache/acestep/triton` | Triton cache directory |\n| `TORCHINDUCTOR_CACHE_DIR` | `.cache/acestep/torchinductor` | TorchInductor cache directory |\n\n---\n\n## Error Handling\n\n**HTTP Status Codes**:\n\n- `200`: Success\n- `400`: Invalid request (bad JSON, missing fields)\n- `401`: Unauthorized (missing or invalid API key)\n- `404`: Resource not found\n- `415`: Unsupported Content-Type\n- `429`: Server busy (queue is full)\n- `500`: Internal server error\n\n**Error Response Format**:\n\n```json\n{\n  \"detail\": \"Error message describing the issue\"\n}\n```\n\n---\n\n## Best Practices\n\n1. **Use `thinking=true`** for best quality results with LM-enhanced generation.\n\n2. **Use `sample_query`/`description`** for quick generation from natural language descriptions.\n\n3. **Use `use_format=true`** when you have caption/lyrics but want LM to enhance them.\n\n4. **Batch query task status** using the `/query_result` endpoint to query multiple tasks at once.\n\n5. **Check `/v1/stats`** to understand server load and average job time.\n\n6. **Use multi-model support** by setting `ACESTEP_CONFIG_PATH2` and `ACESTEP_CONFIG_PATH3` environment variables, then select with the `model` parameter.\n\n7. **For production**, set `ACESTEP_API_KEY` to enable authentication and secure your API.\n\n8. **For low VRAM environments**, enable `ACESTEP_OFFLOAD_TO_CPU=true` to support longer audio generation.\n"
  },
  {
    "path": ".claude/skills/acestep-docs/api/Openrouter_API.md",
    "content": "# ACE-Step OpenRouter API Documentation\n\n> OpenAI Chat Completions-compatible API for AI music generation\n\n**Base URL:** `http://{host}:{port}` (default `http://127.0.0.1:8002`)\n\n---\n\n## Table of Contents\n\n- [Authentication](#authentication)\n- [Endpoints](#endpoints)\n  - [POST /v1/chat/completions - Generate Music](#1-generate-music)\n  - [GET /api/v1/models - List Models](#2-list-models)\n  - [GET /health - Health Check](#3-health-check)\n- [Input Modes](#input-modes)\n- [Streaming Responses](#streaming-responses)\n- [Examples](#examples)\n- [Error Codes](#error-codes)\n\n---\n\n## Authentication\n\nIf the server is configured with an API key (via the `OPENROUTER_API_KEY` environment variable or `--api-key` CLI flag), all requests must include the following header:\n\n```\nAuthorization: Bearer <your-api-key>\n```\n\nNo authentication is required when no API key is configured.\n\n---\n\n## Endpoints\n\n### 1. Generate Music\n\n**POST** `/v1/chat/completions`\n\nGenerates music from chat messages and returns audio data along with LM-generated metadata.\n\n#### Request Parameters\n\n| Field | Type | Required | Default | Description |\n|---|---|---|---|---|\n| `model` | string | No | `\"acemusic/acestep-v1.5-turbo\"` | Model ID |\n| `messages` | array | **Yes** | - | Chat message list. See [Input Modes](#input-modes) |\n| `stream` | boolean | No | `false` | Enable streaming response. See [Streaming Responses](#streaming-responses) |\n| `temperature` | float | No | `0.85` | LM sampling temperature |\n| `top_p` | float | No | `0.9` | LM nucleus sampling parameter |\n| `lyrics` | string | No | `\"\"` | Lyrics passed directly (takes priority over lyrics parsed from messages) |\n| `duration` | float | No | `null` | Audio duration in seconds. If omitted, determined automatically by the LM |\n| `bpm` | integer | No | `null` | Beats per minute. If omitted, determined automatically by the LM |\n| `vocal_language` | string | No | `\"en\"` | Vocal language code (e.g. `\"zh\"`, `\"en\"`, `\"ja\"`) |\n| `instrumental` | boolean | No | `false` | Whether to generate instrumental-only music (no vocals) |\n| `thinking` | boolean | No | `false` | Enable LLM thinking mode for deeper reasoning |\n| `use_cot_metas` | boolean | No | `true` | Auto-generate BPM, duration, key, time signature via Chain-of-Thought |\n| `use_cot_caption` | boolean | No | `true` | Rewrite/enhance the music description via Chain-of-Thought |\n| `use_cot_language` | boolean | No | `true` | Auto-detect vocal language via Chain-of-Thought |\n| `use_format` | boolean | No | `true` | When prompt/lyrics are provided directly, enhance them via LLM formatting |\n\n> **Note on LM parameters:** `use_format` applies when the user provides explicit prompt/lyrics (tagged or lyrics mode) and enhances the description and lyrics formatting via LLM. The `use_cot_*` parameters control Phase 1 CoT reasoning during the audio generation stage. When `use_format` or sample mode has already generated a duration, `use_cot_metas` is automatically skipped to avoid redundancy.\n\n#### messages Format\n\n```json\n{\n  \"messages\": [\n    {\n      \"role\": \"user\",\n      \"content\": \"Your input content\"\n    }\n  ]\n}\n```\n\nSet `role` to `\"user\"` and `content` to the text input. The system automatically determines the input mode based on the content. See [Input Modes](#input-modes) for details.\n\n---\n\n#### Non-Streaming Response (`stream: false`)\n\n```json\n{\n  \"id\": \"chatcmpl-a1b2c3d4e5f6g7h8\",\n  \"object\": \"chat.completion\",\n  \"created\": 1706688000,\n  \"model\": \"acemusic/acestep-v1.5-turbo\",\n  \"choices\": [\n    {\n      \"index\": 0,\n      \"message\": {\n        \"role\": \"assistant\",\n        \"content\": \"## Metadata\\n**Caption:** Upbeat pop song...\\n**BPM:** 120\\n**Duration:** 30s\\n**Key:** C major\\n\\n## Lyrics\\n[Verse 1]\\nHello world...\",\n        \"audio\": [\n          {\n            \"type\": \"audio_url\",\n            \"audio_url\": {\n              \"url\": \"data:audio/mpeg;base64,SUQzBAAAAAAAI1RTU0UAAAA...\"\n            }\n          }\n        ]\n      },\n      \"finish_reason\": \"stop\"\n    }\n  ],\n  \"usage\": {\n    \"prompt_tokens\": 10,\n    \"completion_tokens\": 100,\n    \"total_tokens\": 110\n  }\n}\n```\n\n**Response Fields:**\n\n| Field | Description |\n|---|---|\n| `choices[0].message.content` | Text information generated by the LM, including Metadata (Caption, BPM, Duration, Key, Time Signature, Language) and Lyrics. Returns `\"Music generated successfully.\"` if LM was not involved |\n| `choices[0].message.audio` | Audio data array. Each item contains `type` (`\"audio_url\"`) and `audio_url.url` (Base64 Data URL in format `data:audio/mpeg;base64,...`) |\n| `choices[0].finish_reason` | `\"stop\"` indicates normal completion |\n\n**Decoding Audio:**\n\nThe `audio_url.url` value is a Data URL: `data:audio/mpeg;base64,<base64_data>`\n\nExtract the base64 portion after the comma and decode it to get the MP3 file:\n\n```python\nimport base64\n\nurl = response[\"choices\"][0][\"message\"][\"audio\"][0][\"audio_url\"][\"url\"]\n# Strip the \"data:audio/mpeg;base64,\" prefix\nb64_data = url.split(\",\", 1)[1]\naudio_bytes = base64.b64decode(b64_data)\n\nwith open(\"output.mp3\", \"wb\") as f:\n    f.write(audio_bytes)\n```\n\n```javascript\nconst url = response.choices[0].message.audio[0].audio_url.url;\nconst b64Data = url.split(\",\")[1];\nconst audioBytes = atob(b64Data);\n// Or use the Data URL directly in an <audio> element\nconst audio = new Audio(url);\naudio.play();\n```\n\n---\n\n### 2. List Models\n\n**GET** `/api/v1/models`\n\nReturns available model information.\n\n#### Response\n\n```json\n{\n  \"data\": [\n    {\n      \"id\": \"acemusic/acestep-v1.5-turbo\",\n      \"name\": \"ACE-Step\",\n      \"created\": 1706688000,\n      \"description\": \"High-performance text-to-music generation model...\",\n      \"input_modalities\": [\"text\"],\n      \"output_modalities\": [\"audio\"],\n      \"context_length\": 4096,\n      \"pricing\": {\n        \"prompt\": \"0\",\n        \"completion\": \"0\",\n        \"request\": \"0\"\n      },\n      \"supported_sampling_parameters\": [\"temperature\", \"top_p\"]\n    }\n  ]\n}\n```\n\n---\n\n### 3. Health Check\n\n**GET** `/health`\n\n#### Response\n\n```json\n{\n  \"status\": \"ok\",\n  \"service\": \"ACE-Step OpenRouter API\",\n  \"version\": \"1.0\"\n}\n```\n\n---\n\n## Input Modes\n\nThe system automatically selects the input mode based on the content of the last `user` message:\n\n### Mode 1: Tagged Mode (Recommended)\n\nUse `<prompt>` and `<lyrics>` tags to explicitly specify the music description and lyrics:\n\n```json\n{\n  \"messages\": [\n    {\n      \"role\": \"user\",\n      \"content\": \"<prompt>A gentle acoustic ballad in C major, 80 BPM, female vocal</prompt>\\n<lyrics>[Verse 1]\\nSunlight through the window\\nA brand new day begins\\n\\n[Chorus]\\nWe are the dreamers\\nWe are the light</lyrics>\"\n    }\n  ]\n}\n```\n\n- `<prompt>...</prompt>` - Music style/scene description (caption)\n- `<lyrics>...</lyrics>` - Lyrics content\n- Either tag can be used alone\n- When `use_format=true`, the LLM automatically enhances both prompt and lyrics\n\n### Mode 2: Natural Language Mode (Sample Mode)\n\nDescribe the desired music in natural language. The system uses LLM to generate the prompt and lyrics automatically:\n\n```json\n{\n  \"messages\": [\n    {\n      \"role\": \"user\",\n      \"content\": \"Generate an upbeat pop song about summer and travel\"\n    }\n  ]\n}\n```\n\n**Trigger condition:** Message content contains no tags and does not resemble lyrics (no `[Verse]`/`[Chorus]` markers, few lines, or long single lines).\n\n### Mode 3: Lyrics-Only Mode\n\nPass in lyrics with structural markers directly. The system identifies them automatically:\n\n```json\n{\n  \"messages\": [\n    {\n      \"role\": \"user\",\n      \"content\": \"[Verse 1]\\nWalking down the street\\nFeeling the beat\\n\\n[Chorus]\\nDance with me tonight\\nUnder the moonlight\"\n    }\n  ]\n}\n```\n\n**Trigger condition:** Message content contains `[Verse]`, `[Chorus]`, or similar markers, or has a multi-line short-text structure.\n\n### Instrumental Mode\n\nSet `instrumental: true` or use `[inst]` as the lyrics:\n\n```json\n{\n  \"instrumental\": true,\n  \"messages\": [\n    {\n      \"role\": \"user\",\n      \"content\": \"<prompt>Epic orchestral cinematic score, dramatic and powerful</prompt>\"\n    }\n  ]\n}\n```\n\n---\n\n## Streaming Responses\n\nSet `\"stream\": true` to enable SSE (Server-Sent Events) streaming.\n\n### Event Format\n\nEach event starts with `data: `, followed by JSON, ending with a double newline `\\n\\n`:\n\n```\ndata: {\"id\":\"chatcmpl-xxx\",\"object\":\"chat.completion.chunk\",\"created\":1706688000,\"model\":\"acemusic/acestep-v1.5-turbo\",\"choices\":[{\"index\":0,\"delta\":{...},\"finish_reason\":null}]}\n\n```\n\n### Streaming Event Sequence\n\n| Phase | Delta Content | Description |\n|---|---|---|\n| 1. Initialization | `{\"role\":\"assistant\",\"content\":\"\"}` | Establishes the connection |\n| 2. LM Content (optional) | `{\"content\":\"## Metadata\\n...\"}` | Metadata and lyrics generated by the LM |\n| 3. Heartbeat | `{\"content\":\".\"}` | Sent every 2 seconds during audio generation to keep the connection alive |\n| 4. Audio Data | `{\"audio\":[{\"type\":\"audio_url\",\"audio_url\":{\"url\":\"data:...\"}}]}` | The generated audio |\n| 5. Finish | `finish_reason: \"stop\"` | Generation complete |\n| 6. Termination | `data: [DONE]` | End-of-stream marker |\n\n### Streaming Response Example\n\n```\ndata: {\"id\":\"chatcmpl-abc123\",\"object\":\"chat.completion.chunk\",\"created\":1706688000,\"model\":\"acemusic/acestep-v1.5-turbo\",\"choices\":[{\"index\":0,\"delta\":{\"role\":\"assistant\",\"content\":\"\"},\"finish_reason\":null}]}\n\ndata: {\"id\":\"chatcmpl-abc123\",\"object\":\"chat.completion.chunk\",\"created\":1706688000,\"model\":\"acemusic/acestep-v1.5-turbo\",\"choices\":[{\"index\":0,\"delta\":{\"content\":\"\\n\\n## Metadata\\n**Caption:** Upbeat pop\\n**BPM:** 120\"},\"finish_reason\":null}]}\n\ndata: {\"id\":\"chatcmpl-abc123\",\"object\":\"chat.completion.chunk\",\"created\":1706688000,\"model\":\"acemusic/acestep-v1.5-turbo\",\"choices\":[{\"index\":0,\"delta\":{\"content\":\".\"},\"finish_reason\":null}]}\n\ndata: {\"id\":\"chatcmpl-abc123\",\"object\":\"chat.completion.chunk\",\"created\":1706688000,\"model\":\"acemusic/acestep-v1.5-turbo\",\"choices\":[{\"index\":0,\"delta\":{\"audio\":[{\"type\":\"audio_url\",\"audio_url\":{\"url\":\"data:audio/mpeg;base64,...\"}}]},\"finish_reason\":null}]}\n\ndata: {\"id\":\"chatcmpl-abc123\",\"object\":\"chat.completion.chunk\",\"created\":1706688000,\"model\":\"acemusic/acestep-v1.5-turbo\",\"choices\":[{\"index\":0,\"delta\":{},\"finish_reason\":\"stop\"}]}\n\ndata: [DONE]\n\n```\n\n### Client-Side Streaming Handling\n\n```python\nimport json\nimport httpx\n\nwith httpx.stream(\"POST\", \"http://127.0.0.1:8002/v1/chat/completions\", json={\n    \"messages\": [{\"role\": \"user\", \"content\": \"Generate a cheerful guitar piece\"}],\n    \"stream\": True\n}) as response:\n    content_parts = []\n    audio_url = None\n\n    for line in response.iter_lines():\n        if not line or not line.startswith(\"data: \"):\n            continue\n        if line == \"data: [DONE]\":\n            break\n\n        chunk = json.loads(line[6:])\n        delta = chunk[\"choices\"][0][\"delta\"]\n\n        if \"content\" in delta and delta[\"content\"]:\n            content_parts.append(delta[\"content\"])\n\n        if \"audio\" in delta and delta[\"audio\"]:\n            audio_url = delta[\"audio\"][0][\"audio_url\"][\"url\"]\n\n        if chunk[\"choices\"][0].get(\"finish_reason\") == \"stop\":\n            print(\"Generation complete!\")\n\n    print(\"Content:\", \"\".join(content_parts))\n    if audio_url:\n        import base64\n        b64_data = audio_url.split(\",\", 1)[1]\n        with open(\"output.mp3\", \"wb\") as f:\n            f.write(base64.b64decode(b64_data))\n```\n\n```javascript\nconst response = await fetch(\"http://127.0.0.1:8002/v1/chat/completions\", {\n  method: \"POST\",\n  headers: { \"Content-Type\": \"application/json\" },\n  body: JSON.stringify({\n    messages: [{ role: \"user\", content: \"Generate a cheerful guitar piece\" }],\n    stream: true\n  })\n});\n\nconst reader = response.body.getReader();\nconst decoder = new TextDecoder();\nlet audioUrl = null;\nlet content = \"\";\n\nwhile (true) {\n  const { done, value } = await reader.read();\n  if (done) break;\n\n  const text = decoder.decode(value);\n  for (const line of text.split(\"\\n\")) {\n    if (!line.startsWith(\"data: \") || line === \"data: [DONE]\") continue;\n\n    const chunk = JSON.parse(line.slice(6));\n    const delta = chunk.choices[0].delta;\n\n    if (delta.content) content += delta.content;\n    if (delta.audio) audioUrl = delta.audio[0].audio_url.url;\n  }\n}\n\n// audioUrl can be used directly as <audio src=\"...\">\n```\n\n---\n\n## Examples\n\n### Example 1: Natural Language Generation (Simplest Usage)\n\n```bash\ncurl -X POST http://127.0.0.1:8002/v1/chat/completions \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\n    \"messages\": [\n      {\"role\": \"user\", \"content\": \"A soft folk song about hometown and memories\"}\n    ],\n    \"vocal_language\": \"en\"\n  }'\n```\n\n### Example 2: Tagged Mode with Specific Parameters\n\n```bash\ncurl -X POST http://127.0.0.1:8002/v1/chat/completions \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\n    \"messages\": [\n      {\n        \"role\": \"user\",\n        \"content\": \"<prompt>Energetic EDM track with heavy bass drops and synth leads</prompt><lyrics>[Verse 1]\\nFeel the rhythm in your soul\\nLet the music take control\\n\\n[Drop]\\n(instrumental break)</lyrics>\"\n      }\n    ],\n    \"bpm\": 128,\n    \"duration\": 60,\n    \"vocal_language\": \"en\"\n  }'\n```\n\n### Example 3: Instrumental with LM Enhancement Disabled\n\n```bash\ncurl -X POST http://127.0.0.1:8002/v1/chat/completions \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\n    \"messages\": [\n      {\n        \"role\": \"user\",\n        \"content\": \"<prompt>Peaceful piano solo, slow tempo, jazz harmony</prompt>\"\n      }\n    ],\n    \"instrumental\": true,\n    \"use_format\": false,\n    \"use_cot_caption\": false,\n    \"duration\": 45\n  }'\n```\n\n### Example 4: Streaming Request\n\n```bash\ncurl -X POST http://127.0.0.1:8002/v1/chat/completions \\\n  -H \"Content-Type: application/json\" \\\n  -N \\\n  -d '{\n    \"messages\": [\n      {\"role\": \"user\", \"content\": \"Generate a happy birthday song\"}\n    ],\n    \"stream\": true\n  }'\n```\n\n### Example 5: Full Control with All Parameters\n\n```bash\ncurl -X POST http://127.0.0.1:8002/v1/chat/completions \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\n    \"messages\": [\n      {\n        \"role\": \"user\",\n        \"content\": \"<prompt>Dreamy lo-fi hip hop beat with vinyl crackle</prompt><lyrics>[inst]</lyrics>\"\n      }\n    ],\n    \"temperature\": 0.9,\n    \"top_p\": 0.95,\n    \"bpm\": 85,\n    \"duration\": 30,\n    \"instrumental\": true,\n    \"thinking\": false,\n    \"use_cot_metas\": true,\n    \"use_cot_caption\": true,\n    \"use_cot_language\": false,\n    \"use_format\": true\n  }'\n```\n\n---\n\n## Error Codes\n\n| HTTP Status | Description |\n|---|---|\n| 400 | Invalid request format or missing valid input |\n| 401 | Missing or invalid API key |\n| 500 | Internal error during music generation |\n| 503 | Model not yet initialized |\n\nError response format:\n\n```json\n{\n  \"detail\": \"Error description message\"\n}\n```\n\n---\n\n## Server Configuration (Environment Variables)\n\nThe following environment variables can be used to configure the server (for operations reference):\n\n| Variable | Default | Description |\n|---|---|---|\n| `OPENROUTER_API_KEY` | None | API authentication key |\n| `OPENROUTER_HOST` | `127.0.0.1` | Listen address |\n| `OPENROUTER_PORT` | `8002` | Listen port |\n| `ACESTEP_CONFIG_PATH` | `acestep-v15-turbo` | DiT model configuration path |\n| `ACESTEP_DEVICE` | `auto` | Inference device |\n| `ACESTEP_LM_MODEL_PATH` | `acestep-5Hz-lm-0.6B` | LLM model path |\n| `ACESTEP_LM_BACKEND` | `vllm` | LLM inference backend |\n"
  },
  {
    "path": ".claude/skills/acestep-docs/getting-started/ABOUT.md",
    "content": "# ACE-Step Project Overview\n\n> For installation instructions, see [README.md](README.md)\n\n## Links\n\n- [Project Page](https://ace-step.github.io/ace-step-v1.5.github.io/)\n- [Hugging Face](https://huggingface.co/ACE-Step/Ace-Step1.5)\n- [ModelScope](https://modelscope.cn/models/ACE-Step/Ace-Step1.5)\n- [Space Demo](https://huggingface.co/spaces/ACE-Step/Ace-Step-v1.5)\n- [Discord](https://discord.gg/PeWDxrkdj7)\n- [Technical Report](https://arxiv.org/abs/2602.00744)\n\n## Abstract\n\nACE-Step v1.5 is a highly efficient open-source music foundation model that brings commercial-grade generation to consumer hardware. Key highlights:\n\n- Quality beyond most commercial music models\n- Under 2 seconds per full song on A100, under 10 seconds on RTX 3090\n- Runs locally with less than 4GB of VRAM\n- Supports lightweight LoRA personalization from just a few songs\n\nThe architecture combines a Language Model (LM) as an omni-capable planner with a Diffusion Transformer (DiT). The LM transforms simple user queries into comprehensive song blueprints—scaling from short loops to 10-minute compositions.\n\n## Features\n\n### Performance\n- **Ultra-Fast Generation** — Under 2s per full song on A100\n- **Flexible Duration** — 10 seconds to 10 minutes (600s)\n- **Batch Generation** — Up to 8 songs simultaneously\n\n### Generation Quality\n- **Commercial-Grade Output** — Between Suno v4.5 and Suno v5\n- **Rich Style Support** — 1000+ instruments and styles\n- **Multi-Language Lyrics** — 50+ languages\n\n### Capabilities\n\n| Feature | Description |\n|---------|-------------|\n| Reference Audio Input | Use reference audio to guide style |\n| Cover Generation | Create covers from existing audio |\n| Repaint & Edit | Selective local audio editing |\n| Track Separation | Separate into individual stems |\n| Vocal2BGM | Auto-generate accompaniment |\n| Metadata Control | Duration, BPM, key/scale, time signature |\n| Simple Mode | Full songs from simple descriptions |\n| LoRA Training | 8 songs, 1 hour on 3090 (12GB VRAM) |\n\n## Architecture\n\nThe system uses a hybrid LM + DiT architecture:\n- **LM (Language Model)**: Plans metadata, lyrics, captions via Chain-of-Thought\n- **DiT (Diffusion Transformer)**: Generates audio from the LM's blueprint\n\n## Model Zoo\n\n### DiT Models\n\n| Model | Steps | Quality | Diversity | HuggingFace |\n|-------|:-----:|:-------:|:---------:|-------------|\n| `acestep-v15-base` | 50 | Medium | High | [Link](https://huggingface.co/ACE-Step/acestep-v15-base) |\n| `acestep-v15-sft` | 50 | High | Medium | [Link](https://huggingface.co/ACE-Step/acestep-v15-sft) |\n| `acestep-v15-turbo` | 8 | Very High | Medium | [Link](https://huggingface.co/ACE-Step/Ace-Step1.5) |\n\n### LM Models\n\n| Model | Audio Understanding | Composition | HuggingFace |\n|-------|:------------------:|:-----------:|-------------|\n| `acestep-5Hz-lm-0.6B` | Medium | Medium | [Link](https://huggingface.co/ACE-Step/acestep-5Hz-lm-0.6B) |\n| `acestep-5Hz-lm-1.7B` | Medium | Medium | [Link](https://huggingface.co/ACE-Step/Ace-Step1.5) |\n| `acestep-5Hz-lm-4B` | Strong | Strong | [Link](https://huggingface.co/ACE-Step/acestep-5Hz-lm-4B) |\n\n## License\n\nThis project is licensed under [MIT](https://github.com/ACE-Step/ACE-Step-1.5/blob/main/LICENSE).\n\n## Citation\n\n```BibTeX\n@misc{gong2026acestep,\n    title={ACE-Step 1.5: Pushing the Boundaries of Open-Source Music Generation},\n    author={Junmin Gong, Yulin Song, Wenxiao Zhao, Sen Wang, Shengyuan Xu, Jing Guo},\n    howpublished={\\url{https://github.com/ace-step/ACE-Step-1.5}},\n    year={2026}\n}\n```\n"
  },
  {
    "path": ".claude/skills/acestep-docs/getting-started/README.md",
    "content": "# ACE-Step Installation Guide\n\n## Requirements\n\n- Python 3.11\n- CUDA GPU recommended (works on CPU/MPS/MLX but slower)\n\n## Installation\n\n### Windows Portable Package (Recommended for Windows)\n\n1. Download and extract: [ACE-Step-1.5.7z](https://files.acemusic.ai/acemusic/win/ACE-Step-1.5.7z)\n2. Requirements: CUDA 12.8\n3. The package includes `python_embeded` with all dependencies pre-installed\n\n**Quick Start:**\n```bash\n# Launch Gradio Web UI (CUDA)\nstart_gradio_ui.bat\n\n# Launch REST API Server (CUDA)\nstart_api_server.bat\n\n# Launch Gradio Web UI (AMD ROCm)\nstart_gradio_ui_rocm.bat\n\n# Launch REST API Server (AMD ROCm)\nstart_api_server_rocm.bat\n```\n\n### Launch Scripts (All Platforms)\n\nReady-to-use launch scripts with auto environment detection, update checking, and uv auto-install.\n\n**Windows (.bat):**\n```bash\nstart_gradio_ui.bat          # Gradio Web UI (CUDA)\nstart_api_server.bat         # REST API Server (CUDA)\nstart_gradio_ui_rocm.bat     # Gradio Web UI (AMD ROCm)\nstart_api_server_rocm.bat    # REST API Server (AMD ROCm)\n```\n\n**Linux (.sh):**\n```bash\nchmod +x start_gradio_ui.sh start_api_server.sh   # First time only\n./start_gradio_ui.sh         # Gradio Web UI (CUDA)\n./start_api_server.sh        # REST API Server (CUDA)\n```\n\n**macOS Apple Silicon (.sh):**\n```bash\nchmod +x start_gradio_ui_macos.sh start_api_server_macos.sh   # First time only\n./start_gradio_ui_macos.sh   # Gradio Web UI (MLX backend)\n./start_api_server_macos.sh  # REST API Server (MLX backend)\n```\n\nAll launch scripts support:\n- Startup update check (enabled by default, configurable)\n- Auto environment detection (`python_embeded` or `uv`)\n- Auto install `uv` if needed\n- Configurable download source (HuggingFace/ModelScope)\n- Customizable language, models, and parameters\n\nSee [SCRIPT_CONFIGURATION.md](../guides/SCRIPT_CONFIGURATION.md) for configuration details.\n\n**Manual Launch (Using Python Directly):**\n```bash\n# Gradio Web UI\npython_embeded\\python.exe acestep\\acestep_v15_pipeline.py    # Windows portable\npython acestep/acestep_v15_pipeline.py                        # Linux/macOS\n\n# REST API Server\npython_embeded\\python.exe acestep\\api_server.py              # Windows portable\npython acestep/api_server.py                                  # Linux/macOS\n```\n\n### Standard Installation (All Platforms)\n\n**1. Install uv (Package Manager)**\n```bash\n# macOS / Linux\ncurl -LsSf https://astral.sh/uv/install.sh | sh\n\n# Windows (PowerShell)\npowershell -ExecutionPolicy ByPass -c \"irm https://astral.sh/uv/install.ps1 | iex\"\n```\n\n**2. Clone & Install**\n```bash\ngit clone https://github.com/ACE-Step/ACE-Step-1.5.git\ncd ACE-Step-1.5\nuv sync\n```\n\n**3. Launch**\n\n**Using uv:**\n```bash\n# Gradio Web UI (http://localhost:7860)\nuv run acestep\n\n# REST API Server (http://localhost:8001)\nuv run acestep-api\n```\n\n**Using Python directly:**\n\n> **Note:** Make sure to activate your Python environment first:\n> - **Conda environment**: Run `conda activate your_env_name` first\n> - **venv**: Run `source venv/bin/activate` (Linux/Mac) or `venv\\Scripts\\activate` (Windows) first\n> - **System Python**: Use `python` or `python3` directly\n\n```bash\n# Gradio Web UI\npython acestep/acestep_v15_pipeline.py\n\n# REST API Server\npython acestep/api_server.py\n```\n\n## Model Download\n\nModels are automatically downloaded on first run. Manual download options:\n\n### Download Source Configuration\n\nACE-Step supports multiple download sources:\n\n| Source | Description |\n|--------|-------------|\n| **auto** (default) | Auto-detect best source based on network |\n| **modelscope** | Use ModelScope as download source |\n| **huggingface** | Use HuggingFace Hub as download source |\n\n**Using uv:**\n```bash\n# Download main model\nuv run acestep-download\n\n# Download from ModelScope\nuv run acestep-download --download-source modelscope\n\n# Download from HuggingFace Hub\nuv run acestep-download --download-source huggingface\n\n# Download all models\nuv run acestep-download --all\n\n# List available models\nuv run acestep-download --list\n```\n\n**Using Python directly:**\n\n> **Note:** Replace `python` with your environment's Python executable:\n> - Windows portable package: `python_embeded\\python.exe`\n> - Conda/venv: Activate environment first, then use `python`\n> - System: Use `python` or `python3`\n\n```bash\n# Download main model\npython -m acestep.model_downloader\n\n# Download from ModelScope\npython -m acestep.model_downloader --download-source modelscope\n\n# Download from HuggingFace Hub\npython -m acestep.model_downloader --download-source huggingface\n\n# Download all models\npython -m acestep.model_downloader --all\n\n# List available models\npython -m acestep.model_downloader --list\n```\n\n### GPU VRAM Recommendations\n\n| GPU VRAM | Recommended LM Model | Notes |\n|----------|---------------------|-------|\n| ≤6GB | None (DiT only) | LM disabled to save memory |\n| 6-12GB | `acestep-5Hz-lm-0.6B` | Lightweight, good balance |\n| 12-16GB | `acestep-5Hz-lm-1.7B` | Better quality |\n| ≥16GB | `acestep-5Hz-lm-4B` | Best quality |\n\n## Command Line Options\n\n### Gradio UI (`acestep`)\n\n| Option | Default | Description |\n|--------|---------|-------------|\n| `--port` | 7860 | Server port |\n| `--server-name` | 127.0.0.1 | Server address (`0.0.0.0` for network) |\n| `--share` | false | Create public Gradio link |\n| `--language` | en | UI language: `en`, `zh`, `ja` |\n| `--init_service` | false | Auto-initialize models on startup |\n| `--config_path` | auto | DiT model name |\n| `--lm_model_path` | auto | LM model name |\n| `--offload_to_cpu` | auto | CPU offload (auto if VRAM < 16GB) |\n| `--download-source` | auto | Model download source: `auto`, `huggingface`, or `modelscope` |\n| `--enable-api` | false | Enable REST API endpoints |\n| `--api-key` | none | API authentication key |\n\n**Examples:**\n\n> **Note for Python users:** Replace `python` with your environment's Python executable (see note in Launch section above).\n\n```bash\n# Public access with Chinese UI\nuv run acestep --server-name 0.0.0.0 --share --language zh\n# Or using Python directly:\npython acestep/acestep_v15_pipeline.py --server-name 0.0.0.0 --share --language zh\n\n# Pre-initialize models\nuv run acestep --init_service true --config_path acestep-v15-turbo\n# Or using Python directly:\npython acestep/acestep_v15_pipeline.py --init_service true --config_path acestep-v15-turbo\n\n# Enable API with authentication\nuv run acestep --enable-api --api-key sk-your-secret-key\n# Or using Python directly:\npython acestep/acestep_v15_pipeline.py --enable-api --api-key sk-your-secret-key\n\n# Use ModelScope as download source\nuv run acestep --download-source modelscope\n# Or using Python directly:\npython acestep/acestep_v15_pipeline.py --download-source modelscope\n```\n\n### REST API Server (`acestep-api`)\n\nSame options as Gradio UI. See [API documentation](../api/API.md) for endpoints.\n"
  },
  {
    "path": ".claude/skills/acestep-docs/getting-started/Tutorial.md",
    "content": "# ACE-Step 1.5 Ultimate Guide (Must Read)\n\n---\n\nHello everyone, I'm Gong Junmin, the developer of ACE-Step. Through this tutorial, I'll guide you through the design philosophy and usage of ACE-Step 1.5.\n\n## Mental Models\n\nBefore we begin, we need to establish the correct mental models to set proper expectations.\n\n### Human-Centered Design\n\nThis model is not designed for **one-click generation**, but for **human-centered generation**.\n\nUnderstanding this distinction is crucial.\n\n### What is One-Click Generation?\n\nYou input a prompt, click generate, listen to a few versions, pick one that sounds good, and use it. If someone else inputs the same prompt, they'll likely get similar results.\n\nIn this mode, you and AI have a **client-vendor** relationship. You come with a clear purpose, with a vague expectation in mind, hoping AI delivers a product close to that expectation. Essentially, it's not much different from searching on Google or finding songs on Spotify—just with a bit more customization.\n\nAI is a service, not a creative inspirer.\n\nSuno, Udio, MiniMax, Mureka—these platforms are all designed with this philosophy. They can scale up models as services to ensure delivery. Your generated music is bound by their agreements; you can't run it locally, can't fine-tune for personalized exploration; if they secretly change models or terms, you can only accept it.\n\n### What is Human-Centered Generation?\n\nIf we weaken the AI layer and strengthen the human layer—letting more human will, creativity, and inspiration give life to AI—this is human-centered generation.\n\nUnlike the strong purposefulness of one-click generation, human-centered generation has more of a **playful** nature. It's more like an interactive game where you and the model are **collaborators**.\n\nThe workflow is like this: you throw out some inspiration seeds, get a few songs, choose interesting directions from them to continue iterating—\n- Adjust prompts to regenerate\n- Use **Cover** to maintain structure and adjust details\n- Use **Repaint** for local modifications\n- Use **Add Layer** to add or remove instrument layers\n\nAt this point, AI is not a servant to you, but an **inspirer**.\n\n### What Conditions Must This Design Meet?\n\nFor human-centered generation to truly work, the model must meet several key conditions:\n\n**First, it must be open-source, locally runnable, and trainable.**\n\nThis isn't technical purism, but a matter of ownership. When you use closed-source platforms, you don't own the model, and your generated works are bound by their agreements. Version updates, term changes, service shutdowns—none of these are under your control.\n\nBut when the model is open-source and locally runnable, everything changes: **You forever own this model, and you forever own all the creations you make with it.** No third-party agreement hassles, no platform risks, you can fine-tune, modify, and build your own creative system based on it. Your works will forever belong to you. It's like buying an instrument—you can use it anytime, anywhere, and adjust it anytime, anywhere.\n\n**Second, it must be fast.**\n\nHuman time is precious, but more importantly—**slow generation breaks flow state**.\n\nThe core of human-centered workflow is the rapid cycle of \"try, listen, adjust.\" If each generation takes minutes, your inspiration dissipates while waiting, and the \"play\" experience degrades into the \"wait\" ordeal.\n\nTherefore, we specifically optimized ACE-Step for this: while ensuring quality, we made generation fast enough to support a smooth human-machine dialogue rhythm.\n\n### Finite Game vs Infinite Game\n\nOne-click generation is a **finite game**—clear goals, result-oriented, ends at the finish line. To some extent, it coldly hollows out the music industry, replacing many people's jobs.\n\nHuman-centered generation is an **infinite game**—because the fun lies in the process, and the process never ends.\n\nOur vision is to democratize AI music generation. Let ACE-Step become a big toy in your pocket, let music return to **Play** itself—the creative \"play,\" not just clicking play.\n\n---\n\n## The Elephant Rider Metaphor\n\n> Recommended reading: [The Complete Guide to Mastering Suno](https://www.notion.so/The-Complete-Guide-to-Mastering-Suno-Advanced-Strategies-for-Professional-Music-Generation-2d6ae744ebdf8024be42f6645f884221)—this blog tutorial can help you establish the foundational understanding of AI music.\n\nAI music generation is like the famous **elephant rider metaphor** in psychology.\n\nConsciousness rides on the subconscious, humans ride on elephants. You can give directions, but you can't make the elephant precisely and instantly execute every command. It has its own inertia, its own temperament, its own will.\n\nThis elephant is the music generation model.\n\n### The Iceberg Model\n\nBetween audio and semantics lies a hidden iceberg.\n\nWhat we can describe with language—style, instruments, timbre, emotion, scenes, progression, lyrics, vocal style—these are familiar words, the parts we can touch. But together, they're still just a tiny tip of the audio iceberg above the water.\n\nWhat's the most precise control? You input the expected audio, and the model returns it unchanged.\n\nBut as long as you're using text descriptions, references, prompts—the model will have room to play. This isn't a bug, it's the nature of things.\n\n### What is the Elephant?\n\nThis elephant is a fusion of countless elements: data distribution, model scale, algorithm design, annotation bias, evaluation bias—**it's an abstract crystallization of human music history and engineering trade-offs.**\n\nAny deviation in these elements will cause it to fail to accurately reflect your taste and expectations.\n\nOf course, we can expand data scale, improve algorithm efficiency, increase annotation precision, expand model capacity, introduce more professional evaluation systems—these are all directions we can optimize as model developers.\n\nBut even if one day we achieve technical \"perfection,\" there's still a fundamental problem we can't avoid: **taste.**\n\n### Taste and Expectations\n\nTaste varies from person to person.\n\nIf a music generation model tries to please all listeners, its output will tend toward the popular average of human music history—**this will be extremely mediocre.**\n\nIt's humans who give sound meaning, emotion, experience, life, and cultural symbolic value. It's a small group of artists who create unique tastes, then drive ordinary people to consume and follow, turning niche into mainstream popularity. These pioneering minority artists become legends.\n\nSo when you find the model's output \"not to your taste,\" this might not be the model's problem—**but rather your taste happens to be outside that \"average.\"** This is a good thing.\n\nThis means: **You need to learn to guide this elephant, not expect it to automatically understand you.**\n\n---\n\n## Knowing the Elephant Herd: Model Architecture and Selection\n\nNow you understand the \"elephant\" metaphor. But actually—\n\n**This isn't one elephant, but an entire herd—elephants large and small, forming a family.** 🐘🐘🐘🐘\n\n### Architecture Principles: Two Brains\n\nACE-Step 1.5 uses a **hybrid architecture** with two core components working together:\n\n```\nUser Input → [5Hz LM] → Semantic Blueprint → [DiT] → Audio\n              ↓\n         Metadata Inference\n         Caption Optimization\n         Structure Planning\n```\n\n**5Hz LM (Language Model) — Planner (Optional)**\n\nThe LM is an \"omni-capable planner\" responsible for understanding your intent and making plans:\n- Infers music metadata (BPM, key, duration, etc.) through **Chain-of-Thought**\n- Optimizes and expands your caption—understanding and supplementing your intent\n- Generates **semantic codes**—implicitly containing composition melody, orchestration, and some timbre information\n\nThe LM learns **world knowledge** from training data. It's a planner that improves usability and helps you quickly generate prototypes.\n\n**But the LM is not required.**\n\nIf you're very clear about what you want, or already have a clear planning goal—you can completely skip the LM planning step by not using `thinking` mode.\n\nFor example, in **Cover mode**, you use reference audio to constrain composition, chords, and structure, letting DiT generate directly. Here, **you replace the LM's work**—you become the planner yourself.\n\nAnother example: in **Repaint mode**, you use reference audio as context, constraining timbre, mixing, and details, letting DiT directly adjust locally. Here, DiT is more like your creative brainstorming partner, helping with creative ideation and fixing local disharmony.\n\n**DiT (Diffusion Transformer) — Executor**\n\nDiT is the \"audio craftsman,\" responsible for turning plans into reality:\n- Receives semantic codes and conditions generated by LM\n- Gradually \"carves\" audio from noise through the **diffusion process**\n- Decides final timbre, mixing, details\n\n**Why this design?**\n\nTraditional methods let diffusion models generate audio directly from text, but text-to-audio mapping is too vague. ACE-Step introduces LM as an intermediate layer:\n- LM excels at understanding semantics and planning\n- DiT excels at generating high-fidelity audio\n- They work together, each doing their part\n\n### Choosing the Planner: LM Models\n\nLM has four options: **No LM** (disable thinking mode), **0.6B**, **1.7B**, **4B**.\n\nTheir training data is completely identical; the difference is purely in **knowledge capacity**:\n- Larger models have richer world knowledge\n- Larger models have stronger memory (e.g., remembering reference audio melodies)\n- Larger models perform relatively better on long-tail styles or instruments\n\n| Choice | Speed | World Knowledge | Memory | Use Cases |\n|--------|:-----:|:---------------:|:------:|-----------|\n| No LM | ⚡⚡⚡⚡ | — | — | You do the planning (e.g., Cover mode) |\n| `0.6B` | ⚡⚡⚡ | Basic | Weak | Low VRAM (< 8GB), rapid prototyping |\n| `1.7B` | ⚡⚡ | Medium | Medium | **Default recommendation** |\n| `4B` | ⚡ | Rich | Strong | Complex tasks, high-quality generation |\n\n**How to choose?**\n\nBased on your hardware:\n- **VRAM < 8GB** → No LM or `0.6B`\n- **VRAM 8–16GB** → `1.7B` (default)\n- **VRAM > 16GB** → `1.7B` or `4B`\n\n### Choosing the Executor: DiT Models\n\nWith a planning scheme, you still need to choose an executor. DiT is the core of ACE-Step 1.5—it handles various tasks and decides how to interpret LM-generated codes.\n\nWe've open-sourced **4 Turbo models**, **1 SFT model**, and **1 Base model**.\n\n#### Turbo Series (Recommended for Daily Use)\n\nTurbo models are trained with distillation, generating high-quality audio in just 8 steps. The core difference between the four variants is the **shift hyperparameter configuration during distillation**.\n\n**What is shift?**\n\nShift determines the \"attention allocation\" during DiT denoising:\n- **Larger shift** → More effort spent on early denoising (building large structure from pure noise), **stronger semantics**, clearer overall framework\n- **Smaller shift** → More even step distribution, **more details**, but details might also be noise\n\nSimple understanding: high shift is like \"draw outline first then fill details,\" low shift is like \"draw and fix simultaneously.\"\n\n| Model | Distillation Config | Characteristics |\n|-------|---------------------|-----------------|\n| `turbo` (default) | Joint distillation on shift 1, 2, 3 | **Best balance of creativity and semantics**, thoroughly tested, recommended first choice |\n| `turbo-shift1` | Distilled only on shift=1 | Richer details, but semantics weaker |\n| `turbo-shift3` | Distilled only on shift=3 | Clearer, richer timbre, but may sound \"dry,\" minimal orchestration |\n| `turbo-continuous` | Experimental, supports continuous shift 1–5 | Most flexible tuning, but not thoroughly tested |\n\nYou can choose based on target music style—you might find you prefer a certain variant. **We recommend starting with default turbo**—it's the most balanced and proven choice.\n\n#### SFT Model\n\nCompared to Turbo, SFT model has two notable features:\n- **Supports CFG** (Classifier-Free Guidance), allowing fine-tuning of prompt adherence\n- **More steps** (50 steps), giving the model more time to \"think\"\n\nThe cost: more steps mean error accumulation, audio clarity may be slightly inferior to Turbo. But its **detail expression and semantic parsing will be better**.\n\nIf you don't care about inference time, like tuning CFG and steps, and prefer that rich detail feel—SFT is a good choice. LM-generated codes can also work with SFT models.\n\n#### Base Model\n\nBase is the **master of all tasks**, with three exclusive tasks beyond SFT and Turbo:\n\n| Task | Description |\n|------|-------------|\n| `extract` | Extract single tracks from mixed audio (e.g., separate vocals) |\n| `lego` | Add new tracks to existing tracks (e.g., add drums to guitar) |\n| `complete` | Add mixed accompaniment to single track (e.g., add guitar+drums accompaniment to vocals) |\n\nAdditionally, Base has the **strongest plasticity**. If you have large-scale fine-tuning needs, we recommend starting experiments with Base to train your own SFT model.\n\n#### Creating Your Custom Model\n\nBeyond official models, you can also use **LoRA fine-tuning** to create your custom model.\n\nWe'll release an example LoRA model—trained on 20+ \"Happy New Year\" themed songs, specifically suited for expressing festive atmosphere. This is just a starting point.\n\n**What does a custom model mean?**\n\nYou can reshape DiT's capabilities and preferences with your own data recipe:\n- Like a specific timbre style? Train with that type of songs\n- Want the model better at a certain genre? Collect related data for fine-tuning\n- Have your own unique aesthetic taste? \"Teach\" it to the model\n\nThis greatly expands **customization and playability**—train a model unique to you with your aesthetic taste.\n\n> For detailed LoRA training guide, see the \"LoRA Training\" tab in Gradio UI.\n\n#### DiT Selection Summary\n\n| Model | Steps | CFG | Speed | Exclusive Tasks | Recommended Scenarios |\n|-------|:-----:|:---:|:-----:|-----------------|----------------------|\n| `turbo` (default) | 8 | ❌ | ⚡⚡⚡ | — | Daily use, rapid iteration |\n| `sft` | 50 | ✅ | ⚡ | — | Pursuing details, like tuning |\n| `base` | 50 | ✅ | ⚡ | extract, lego, complete | Special tasks, large-scale fine-tuning |\n\n### Combination Strategies\n\nDefault configuration is **turbo + 1.7B LM**, suitable for most scenarios.\n\n| Need | Recommended Combination |\n|------|------------------------|\n| Fastest speed | `turbo` + No LM or `0.6B` |\n| Daily use | `turbo` + `1.7B` (default) |\n| Pursuing details | `sft` + `1.7B` or `4B` |\n| Special tasks | `base` |\n| Large-scale fine-tuning | `base` |\n| Low VRAM (< 4GB) | `turbo` + No LM + CPU offload |\n\n### Downloading Models\n\n```bash\n# Download default models (turbo + 1.7B LM)\nuv run acestep-download\n\n# Download all models\nuv run acestep-download --all\n\n# Download specific model\nuv run acestep-download --model acestep-v15-base\nuv run acestep-download --model acestep-5Hz-lm-0.6B\n\n# List available models\nuv run acestep-download --list\n```\n\nYou need to download models into a `checkpoints` folder for easy identification.\n\n---\n\n## Guiding the Elephant: What Can You Control?\n\nNow that you know this herd of elephants, let's learn how to communicate with them.\n\nEach generation is determined by three types of factors: **input control**, **inference hyperparameters**, and **random factors**.\n\n### I. Input Control: What Do You Want?\n\nThis is the part where you communicate \"creative intent\" with the model—what kind of music you want to generate.\n\n| Category | Parameter | Function |\n|----------|-----------|----------|\n| **Task Type** | `task_type` | Determines generation mode: text2music, cover, repaint, lego, extract, complete |\n| **Text Input** | `caption` | Description of overall music elements: style, instruments, emotion, atmosphere, timbre, vocal gender, progression, etc. |\n| | `lyrics` | Temporal element description: lyric content, music structure evolution, vocal changes, vocal/instrument performance style, start/end style, articulation, etc. (use `[Instrumental]` for instrumental music) |\n| **Music Metadata** | `bpm` | Tempo (30–300) |\n| | `keyscale` | Key (e.g., C Major, Am) |\n| | `timesignature` | Time signature (4/4, 3/4, 6/8) |\n| | `vocal_language` | Vocal language |\n| | `duration` | Target duration (seconds) |\n| **Audio Reference** | `reference_audio` | Global reference for timbre or style (for cover, style transfer) |\n| | `src_audio` | Source audio for non-text2music tasks (text2music defaults to silence, no input needed) |\n| | `audio_codes` | Semantic codes input to model in Cover mode (advanced: reuse codes for variants, convert songs to codes for extension, combine like DJ mixing) |\n| **Interval Control** | `repainting_start/end` | Time interval for operations (repaint redraw area / lego new track area) |\n\n---\n\n#### About Caption: The Most Important Input\n\n**Caption is the most important factor affecting generated music.**\n\nIt supports multiple input formats: simple style words, comma-separated tags, complex natural language descriptions. We've trained to be compatible with various formats, ensuring text format doesn't significantly affect model performance.\n\n**We provide at least 5 ways to help you write good captions:**\n\n1. **Random Dice** — Click the random button in the UI to see how example captions are written. You can use this standardized caption as a template and have an LLM rewrite it to your desired form.\n\n2. **Format Auto-Rewrite** — We support using the `format` feature to automatically expand your handwritten simple caption into complex descriptions.\n\n3. **CoT Rewrite** — If LM is initialized, whether `thinking` mode is enabled or not, we support rewriting and expanding captions through Chain-of-Thought (unless you actively disable it in settings, or LM is not initialized).\n\n4. **Audio to Caption** — Our LM supports converting your input audio to caption. While precision is limited, the vague direction is correct—enough as a starting point.\n\n5. **Simple Mode** — Just input a simple song description, and LM will automatically generate complete caption, lyrics, and metas samples—suitable for quick starts.\n\nRegardless of which method, they all solve a real problem: **As ordinary people, our music vocabulary is impoverished.**\n\nIf you want generated music to be more interesting and meet expectations, **Prompting is always the optimal option**—it brings the highest marginal returns and surprises.\n\n**Common Dimensions for Caption Writing:**\n\n| Dimension | Examples |\n|-----------|----------|\n| **Style/Genre** | pop, rock, jazz, electronic, hip-hop, R&B, folk, classical, lo-fi, synthwave |\n| **Emotion/Atmosphere** | melancholic, uplifting, energetic, dreamy, dark, nostalgic, euphoric, intimate |\n| **Instruments** | acoustic guitar, piano, synth pads, 808 drums, strings, brass, electric bass |\n| **Timbre Texture** | warm, bright, crisp, muddy, airy, punchy, lush, raw, polished |\n| **Era Reference** | 80s synth-pop, 90s grunge, 2010s EDM, vintage soul, modern trap |\n| **Production Style** | lo-fi, high-fidelity, live recording, studio-polished, bedroom pop |\n| **Vocal Characteristics** | female vocal, male vocal, breathy, powerful, falsetto, raspy, choir |\n| **Speed/Rhythm** | slow tempo, mid-tempo, fast-paced, groovy, driving, laid-back |\n| **Structure Hints** | building intro, catchy chorus, dramatic bridge, fade-out ending |\n\n**Some Practical Principles:**\n\n1. **Specific beats vague** — \"sad piano ballad with female breathy vocal\" works better than \"a sad song.\"\n\n2. **Combine multiple dimensions** — Single-dimension descriptions give the model too much room to play; combining style+emotion+instruments+timbre can more precisely anchor your desired direction.\n\n3. **Use references well** — \"in the style of 80s synthwave\" or \"reminiscent of Bon Iver\" can quickly convey complex aesthetic preferences.\n\n4. **Texture words are useful** — Adjectives like warm, crisp, airy, punchy can influence mixing and timbre tendencies.\n\n5. **Don't pursue perfect descriptions** — Caption is a starting point, not an endpoint. Write a general direction first, then iterate based on results.\n\n6. **Description granularity determines freedom** — More omitted descriptions give the model more room to play, more random factor influence; more detailed descriptions constrain the model more. Decide specificity based on your needs—want surprises? Write less. Want control? Write more details.\n\n7. **Avoid conflicting words** — Conflicting style combinations easily lead to degraded output. For example, wanting both \"classical strings\" and \"hardcore metal\" simultaneously—the model will try to fuse but usually not ideal. Especially when `thinking` mode is enabled, LM has weaker caption generalization than DiT. When prompting is unreasonable, the chance of pleasant surprises is smaller.\n\n   **Ways to resolve conflicts:**\n   - **Repetition reinforcement** — Strengthen the elements you want more in mixed styles by repeating certain words\n   - **Conflict to evolution** — Transform style conflicts into temporal style evolution. For example: \"Start with soft strings, middle becomes noisy dynamic metal rock, end turns to hip-hop\"—this gives the model clear guidance on how to handle different styles, rather than mixing them into a mess\n\n> For more prompting tips, see: [The Complete Guide to Mastering Suno](https://www.notion.so/The-Complete-Guide-to-Mastering-Suno-Advanced-Strategies-for-Professional-Music-Generation-2d6ae744ebdf8024be42f6645f884221)—although it's a Suno tutorial, prompting ideas are universal.\n\n---\n\n#### About Lyrics: The Temporal Script\n\nIf Caption describes the music's \"overall portrait\"—style, atmosphere, timbre—then **Lyrics is the music's \"temporal script\"**, controlling how music unfolds over time.\n\nLyrics is not just lyric content. It carries:\n- The lyric text itself\n- **Structure tags** ([Verse], [Chorus], [Bridge]...)\n- **Vocal style hints** ([raspy vocal], [whispered]...)\n- **Instrumental sections** ([guitar solo], [drum break]...)\n- **Energy changes** ([building energy], [explosive drop]...)\n\n**Structure Tags are Key**\n\nStructure tags (Meta Tags) are the most powerful tool in Lyrics. They tell the model: \"What is this section, how should it be performed?\"\n\n**Common Structure Tags:**\n\n| Category | Tag | Description |\n|----------|-----|-------------|\n| **Basic Structure** | `[Intro]` | Opening, establish atmosphere |\n| | `[Verse]` / `[Verse 1]` | Verse, narrative progression |\n| | `[Pre-Chorus]` | Pre-chorus, build energy |\n| | `[Chorus]` | Chorus, emotional climax |\n| | `[Bridge]` | Bridge, transition or elevation |\n| | `[Outro]` | Ending, conclusion |\n| **Dynamic Sections** | `[Build]` | Energy gradually rising |\n| | `[Drop]` | Electronic music energy release |\n| | `[Breakdown]` | Reduced instrumentation, space |\n| **Instrumental Sections** | `[Instrumental]` | Pure instrumental, no vocals |\n| | `[Guitar Solo]` | Guitar solo |\n| | `[Piano Interlude]` | Piano interlude |\n| **Special Tags** | `[Fade Out]` | Fade out ending |\n| | `[Silence]` | Silence |\n\n**Combining Tags: Use Moderately**\n\nStructure tags can be combined with `-` for finer control:\n\n```\n[Chorus - anthemic]\nThis is the chorus lyrics\nDreams are burning\n\n[Bridge - whispered]\nWhisper those words softly\n```\n\nThis works better than writing `[Chorus]` alone—you're telling the model both what this section is (Chorus) and how to sing it (anthemic).\n\n**⚠️ Note: Don't stack too many tags.**\n\n```\n❌ Not recommended:\n[Chorus - anthemic - stacked harmonies - high energy - powerful - epic]\n\n✅ Recommended:\n[Chorus - anthemic]\n```\n\nStacking too many tags has two risks:\n1. The model might mistake tag content as lyrics to sing\n2. Too many instructions confuse the model, making effects worse\n\n**Principle**: Keep structure tags concise; put complex style descriptions in Caption.\n\n**⚠️ Key: Maintain Consistency Between Caption and Lyrics**\n\n**Models are not good at resolving conflicts.** If descriptions in Caption and Lyrics contradict, the model gets confused and output quality decreases.\n\n```\n❌ Conflict example:\nCaption: \"violin solo, classical, intimate chamber music\"\nLyrics: [Guitar Solo - electric - distorted]\n\n✅ Consistent example:\nCaption: \"violin solo, classical, intimate chamber music\"\nLyrics: [Violin Solo - expressive]\n```\n\n**Checklist:**\n- Instruments in Caption ↔ Instrumental section tags in Lyrics\n- Emotion in Caption ↔ Energy tags in Lyrics\n- Vocal description in Caption ↔ Vocal control tags in Lyrics\n\nThink of Caption as \"overall setting\" and Lyrics as \"shot script\"—they should tell the same story.\n\n**Vocal Control Tags:**\n\n| Tag | Effect |\n|-----|--------|\n| `[raspy vocal]` | Raspy, textured vocals |\n| `[whispered]` | Whispered |\n| `[falsetto]` | Falsetto |\n| `[powerful belting]` | Powerful, high-pitched singing |\n| `[spoken word]` | Rap/recitation |\n| `[harmonies]` | Layered harmonies |\n| `[call and response]` | Call and response |\n| `[ad-lib]` | Improvised embellishments |\n\n**Energy and Emotion Tags:**\n\n| Tag | Effect |\n|-----|--------|\n| `[high energy]` | High energy, passionate |\n| `[low energy]` | Low energy, restrained |\n| `[building energy]` | Increasing energy |\n| `[explosive]` | Explosive energy |\n| `[melancholic]` | Melancholic |\n| `[euphoric]` | Euphoric |\n| `[dreamy]` | Dreamy |\n| `[aggressive]` | Aggressive |\n\n**Lyric Text Writing Tips**\n\n**1. Control Syllable Count**\n\n**6-10 syllables per line** usually works best. The model aligns syllables to beats—if one line has 6 syllables and the next has 14, rhythm becomes strange.\n\n```\n❌ Bad example:\n我站在窗前看着外面的世界一切都在改变（18 syllables）\n你好（2 syllables）\n\n✅ Good example:\n我站在窗前（5 syllables）\n看着外面世界（6 syllables）\n一切都在改变（6 syllables）\n```\n\n**Tip**: Keep similar syllable counts for lines in the same position (e.g., first line of each verse) (±1-2 deviation).\n\n**2. Use Case to Control Intensity**\n\nUppercase indicates stronger vocal intensity:\n\n```\n[Verse]\nwalking through the empty streets (normal intensity)\n\n[Chorus]\nWE ARE THE CHAMPIONS! (high intensity, shouting)\n```\n\n**3. Use Parentheses for Background Vocals**\n\n```\n[Chorus]\nWe rise together (together)\nInto the light (into the light)\n```\n\nContent in parentheses is processed as background vocals or harmonies.\n\n**4. Extend Vowels**\n\nYou can extend sounds by repeating vowels:\n\n```\nFeeeling so aliiive\n```\n\nBut use cautiously—effects are unstable, sometimes ignored or mispronounced.\n\n**5. Clear Section Separation**\n\nSeparate each section with blank lines:\n\n```\n[Verse 1]\nFirst verse lyrics\nContinue first verse\n\n[Chorus]\nChorus lyrics\nChorus continues\n```\n\n**Avoiding \"AI-flavored\" Lyrics**\n\nThese characteristics make lyrics seem mechanical and lack human touch:\n\n| Red Flag 🚩 | Description |\n|-------------|-------------|\n| **Adjective stacking** | \"neon skies, electric hearts, endless dreams\"—filling a section with vague imagery |\n| **Rhyme chaos** | Inconsistent rhyme patterns, or forced rhymes causing semantic breaks |\n| **Blurred section boundaries** | Lyric content crosses structure tags, Verse content \"flows\" into Chorus |\n| **No breathing room** | Each line too long, can't sing in one breath |\n| **Mixed metaphors** | First verse uses water imagery, second suddenly becomes fire, third is flying—listeners can't anchor |\n\n**Metaphor discipline**: Stick to one core metaphor per song, exploring its multiple aspects. For example, choosing \"water\" as metaphor, you can explore: how love flows around obstacles like water, can be gentle rain or flood, reflects the other's image, can't be grasped but exists. One image, multiple facets—this gives lyrics cohesion.\n\n**Writing Instrumental Music**\n\nIf generating pure instrumental music without vocals:\n\n```\n[Instrumental]\n```\n\nOr use structure tags to describe instrumental development:\n\n```\n[Intro - ambient]\n\n[Main Theme - piano]\n\n[Climax - powerful]\n\n[Outro - fade out]\n```\n\n**Complete Example**\n\nAssuming Caption is: `female vocal, piano ballad, emotional, intimate atmosphere, strings, building to powerful chorus`\n\n```\n[Intro - piano]\n\n[Verse 1]\n月光洒在窗台上\n我听见你的呼吸\n城市在远处沉睡\n只有我们还醒着\n\n[Pre-Chorus]\n这一刻如此安静\n却藏着汹涌的心\n\n[Chorus - powerful]\n让我们燃烧吧\n像夜空中的烟火\n短暂却绚烂\n这就是我们的时刻\n\n[Verse 2]\n时间在指尖流过\n我们抓不住什么\n但至少此刻拥有\n彼此眼中的火焰\n\n[Bridge - whispered]\n如果明天一切消散\n至少我们曾经闪耀\n\n[Final Chorus]\n让我们燃烧吧\n像夜空中的烟火\n短暂却绚烂\nTHIS IS OUR MOMENT!\n\n[Outro - fade out]\n```\n\nNote: In this example, Lyrics tags (piano, powerful, whispered) are consistent with Caption descriptions (piano ballad, building to powerful chorus, intimate), with no conflicts.\n\n---\n\n#### About Music Metadata: Optional Fine Control\n\n**Most of the time, you don't need to manually set metadata.**\n\nWhen you enable `thinking` mode (or enable `use_cot_metas`), LM automatically infers appropriate BPM, key, time signature, etc. based on your Caption and Lyrics. This is usually good enough.\n\nBut if you have clear ideas, you can also manually control them:\n\n| Parameter | Control Range | Description |\n|-----------|--------------|-------------|\n| `bpm` | 30–300 | Tempo. Common distribution: slow songs 60–80, mid-tempo 90–120, fast songs 130–180 |\n| `keyscale` | Key | e.g., `C Major`, `Am`, `F# Minor`. Affects overall pitch and emotional color |\n| `timesignature` | Time signature | `4/4` (most common), `3/4` (waltz), `6/8` (swing feel) |\n| `vocal_language` | Language | Vocal language. LM usually auto-detects from lyrics |\n| `duration` | Seconds | Target duration. Actual generation may vary slightly |\n\n**Understanding Control Boundaries**\n\nThese parameters are **guidance** rather than **precise commands**:\n\n- **BPM**: Common range (60–180) works well; extreme values (like 30 or 280) have less training data, may be unstable\n- **Key**: Common keys (C, G, D, Am, Em) are stable; rare keys may be ignored or shifted\n- **Time signature**: `4/4` is most reliable; `3/4`, `6/8` usually OK; complex signatures (like `5/4`, `7/8`) are advanced, effects vary by style\n- **Duration**: Short songs (30–60s) and medium length (2–4min) are stable; very long generation may have repetition or structure issues\n\n**The Model's \"Reference\" Approach**\n\nThe model doesn't mechanically execute `bpm=120`, but rather:\n1. Uses `120 BPM` as an **anchor point**\n2. Samples from distribution near this anchor\n3. Final result might be 118 or 122, not exactly 120\n\nIt's like telling a musician \"around 120 tempo\"—they'll naturally play in this range, not rigidly follow a metronome.\n\n**When Do You Need Manual Settings?**\n\n| Scenario | Suggestion |\n|----------|------------|\n| Daily generation | Don't worry, let LM auto-infer |\n| Clear tempo requirement | Manually set `bpm` |\n| Specific style (e.g., waltz) | Manually set `timesignature=3/4` |\n| Need to match other material | Manually set `bpm` and `duration` |\n| Pursue specific key color | Manually set `keyscale` |\n\n**Tip**: If you manually set metadata but generation results clearly don't match—check if there's conflict with Caption/Lyrics. For example, Caption says \"slow ballad\" but `bpm=160`, the model gets confused.\n\n**Recommended Practice**: Don't write tempo, BPM, key, and other metadata information in Caption. These should be set through dedicated metadata parameters (`bpm`, `keyscale`, `timesignature`, etc.), not described in Caption. Caption should focus on style, emotion, instruments, timbre, and other musical characteristics, while metadata information is handled by corresponding parameters.\n\n---\n\n#### About Audio Control: Controlling Sound with Sound\n\n**Text is dimensionally reduced abstraction; the best control is still controlling with audio.**\n\nThere are three ways to control generation with audio, each with different control ranges and uses:\n\n---\n\n##### 1. Reference Audio: Global Acoustic Feature Control\n\nReference audio (`reference_audio`) is used to control the **acoustic features** of generated music—timbre, mixing style, performance style, etc. It **averages temporal dimension information** and acts **globally**.\n\n**What Does Reference Audio Control?**\n\nReference audio mainly controls the **acoustic features** of generated music, including:\n- **Timbre texture**: Vocal timbre, instrument timbre\n- **Mixing style**: Spatial sense, dynamic range, frequency distribution\n- **Performance style**: Vocal techniques, playing techniques, expression\n- **Overall atmosphere**: The \"feeling\" conveyed through reference audio\n\n**How Does the Backend Process Reference Audio?**\n\nWhen you provide reference audio, the system performs the following processing:\n\n1. **Audio Preprocessing**:\n   - Load audio file, normalize to **stereo 48kHz** format\n   - Detect silence, ignore if audio is completely silent\n   - If audio length is less than 30 seconds, repeat to fill to at least 30 seconds\n   - Randomly select 10-second segments from front, middle, and back positions, concatenate into 30-second reference segment\n\n2. **Encoding Conversion**:\n   - Use **VAE (Variational Autoencoder)** `tiled_encode` method to encode audio into **latent representation (latents)**\n   - These latents contain acoustic feature information but remove specific melody, rhythm, and other structural information\n   - Encoded latents are input as conditions to DiT generation process, **averaging temporal dimension information, acting globally on entire generation process**\n\n---\n\n##### 2. Source Audio: Semantic Structure Control\n\nSource audio (`src_audio`) is used for **Cover tasks**, performing **melodic structure control**. Its principle is to quantize your input source audio into semantically structured information.\n\n**What Does Source Audio Control?**\n\nSource audio is converted into **semantically structured information**, including:\n- **Melody**: Note direction and pitch\n- **Rhythm**: Beat, accent, groove\n- **Chords**: Harmonic progression and changes\n- **Orchestration**: Instrument arrangement and layers\n- **Some timbre**: Partial timbre information\n\n**What Can You Do With It?**\n\n1. **Control style**: Maintain source audio structure, change style and details\n2. **Transfer style**: Apply source audio structure to different styles\n3. **Retake lottery**: Generate similar structure but different variants, get different interpretations through multiple generations\n4. **Control influence degree**: Control source audio influence strength through `audio_cover_strength` parameter (0.0–1.0)\n   - Higher strength: generation results more strictly follow source audio structure\n   - Lower strength: generation results have more room for free play\n\n**Advanced Cover Usage**\n\nYou can use Cover to **Remix a song**, and it supports changing Caption and Lyrics:\n\n- **Remix creation**: Input a song as source audio, reinterpret it by modifying Caption and Lyrics\n  - Change style: Use different Caption descriptions (e.g., change from pop to rock)\n  - Change lyrics: Rewrite lyrics with new Lyrics, maintaining original melody structure\n  - Change emotion: Adjust overall atmosphere through Caption (e.g., change from sad to joyful)\n\n- **Build complex music structures**: Build complex melodic direction, layers, and groove based on your needed structure influence degree\n  - Fine-tune structure adherence through `audio_cover_strength`\n  - Combine Caption and Lyrics modifications to create new expression while maintaining core structure\n  - Can generate multiple versions, each with different emphasis on structure, style, lyrics\n\n---\n\n##### 3. Source Audio Context-Based Control: Local Completion and Modification\n\nThis is the **Repaint task**, performing completion or modification based on source audio context.\n\n**Repaint Principle**\n\nRepaint is based on **context completion** principle:\n- Can complete **beginning**, **middle local**, **ending**, or **any region**\n- Operation range: **3 seconds to 90 seconds**\n- Model references source audio context information, generating within specified interval\n\n**What Can You Do With It?**\n\n1. **Local modification**: Modify lyrics, structure, or content in specified interval\n2. **Change lyrics**: Maintain melody and orchestration, only change lyric content\n3. **Change structure**: Change music structure in specified interval (e.g., change Verse to Chorus)\n4. **Continue writing**: Continue writing beginning or ending based on context\n5. **Clone timbre**: Clone source audio timbre characteristics based on context\n\n**Advanced Repaint Usage**\n\nYou can use Repaint for more complex creative needs:\n\n- **Infinite duration generation**:\n  - Through multiple Repaint operations, can continuously extend audio, achieving infinite duration generation\n  - Each continuation is based on previous segment's context, maintaining natural transitions and coherence\n  - Can generate in segments, each 3–90 seconds, finally concatenate into complete work\n\n- **Intelligent audio stitching**:\n  - Intelligently organize and stitch two audios together\n  - Use Repaint at first audio's end to continue, making transitions naturally connect\n  - Or use Repaint to modify connection part between two audios for smooth transitions\n  - Model automatically handles rhythm, harmony, timbre connections based on context, making stitched audio sound like a complete work\n\n---\n\n##### 4. Base Model Advanced Audio Control Tasks\n\nIn the **Base model**, we also support more advanced audio control tasks:\n\n**Lego Task**: Intelligently add new tracks based on existing tracks\n- Input an existing audio track (e.g., vocals)\n- Model intelligently adds new tracks (e.g., drums, guitar, bass, etc.)\n- New tracks coordinate with original tracks in rhythm and harmony\n\n**Complete Task**: Add mixed tracks to single track\n- Input a single-track audio (e.g., a cappella vocals)\n- Model generates complete mixed accompaniment tracks\n- Generated accompaniment matches vocals in style, rhythm, and harmony\n\n**These advanced context completion tasks** greatly expand control methods, more intelligently providing inspiration and creativity.\n\n---\n\nThe combination of these parameters determines what you \"want.\" We'll explain input control **principles** and **techniques** in detail later.\n\n### II. Inference Hyperparameters: How Does the Model Generate?\n\nThis is the part that affects \"generation process behavior\"—doesn't change what you want, but changes how the model does it.\n\n**DiT (Diffusion Model) Hyperparameters:**\n\n| Parameter | Function | Default | Tuning Advice |\n|-----------|----------|---------|---------------|\n| `inference_steps` | Diffusion steps | 8 (turbo) | More steps = finer but slower. Turbo uses 8, Base uses 32–100 |\n| `guidance_scale` | CFG strength | 7.0 | Higher = more prompt adherence, but may overfit. Only Base model effective |\n| `use_adg` | Adaptive Dual Guidance | False | After enabling, dynamically adjusts CFG, Base model only |\n| `cfg_interval_start/end` | CFG effective interval | 0.0–1.0 | Controls which stage to apply CFG |\n| `shift` | Timestep offset | 1.0 | Adjusts denoising trajectory, affects generation style |\n| `infer_method` | Inference method | \"ode\" | `ode` deterministic, `sde` introduces randomness |\n| `timesteps` | Custom timesteps | None | Advanced usage, overrides steps and shift |\n| `audio_cover_strength` | Reference audio/codes influence strength | 1.0 | 0.0–1.0, higher = closer to reference, lower = more freedom |\n\n**5Hz LM (Language Model) Hyperparameters:**\n\n| Parameter | Function | Default | Tuning Advice |\n|-----------|----------|---------|---------------|\n| `thinking` | Enable CoT reasoning | True | Enable to let LM reason metadata and codes |\n| `lm_temperature` | Sampling temperature | 0.85 | Higher = more random/creative, lower = more conservative/deterministic |\n| `lm_cfg_scale` | LM CFG strength | 2.0 | Higher = more positive prompt adherence |\n| `lm_top_k` | Top-K sampling | 0 | 0 means disabled, limits candidate word count |\n| `lm_top_p` | Top-P sampling | 0.9 | Nucleus sampling, limits cumulative probability |\n| `lm_negative_prompt` | Negative prompt | \"NO USER INPUT\" | Tells LM what not to generate |\n| `use_cot_metas` | CoT reason metadata | True | Let LM auto-infer BPM, key, etc. |\n| `use_cot_caption` | CoT rewrite caption | True | Let LM optimize your description |\n| `use_cot_language` | CoT detect language | True | Let LM auto-detect vocal language |\n| `use_constrained_decoding` | Constrained decoding | True | Ensures correct output format |\n\nThe combination of these parameters determines how the model \"does it.\"\n\n**About Parameter Tuning**\n\nIt's important to emphasize that **tuning factors and random factors sometimes have comparable influence**. When you adjust a parameter, it may be hard to tell if it's the parameter's effect or randomness causing the change.\n\nTherefore, **we recommend fixing random factors when tuning**—by setting a fixed `seed` value, ensuring each generation starts from the same initial noise, so you can accurately feel the parameter's real impact on generated audio. Otherwise, parameter change effects may be masked by randomness, causing you to misjudge the parameter's role.\n\n### III. Random Factors: Sources of Uncertainty\n\nEven with identical inputs and hyperparameters, two generations may produce different results. This is because:\n\n**1. DiT's Initial Noise**\n- Diffusion models start from random noise and gradually denoise\n- `seed` parameter controls this initial noise\n- Different seed → different starting point → different endpoint\n\n**2. LM's Sampling Randomness**\n- When `lm_temperature > 0`, the sampling process itself has randomness\n- Same prompt, each sampling may choose different tokens\n\n**3. Additional Noise When `infer_method = \"sde\"`**\n- SDE method injects additional randomness during denoising\n\n---\n\n#### Pros and Cons of Random Factors\n\nRandomness is a double-edged sword.\n\n**Benefits of Randomness:**\n- **Explore creative space**: Same input can produce different variants, giving you more choices\n- **Discover unexpected surprises**: Sometimes randomness brings excellent results you didn't expect\n- **Avoid repetition**: Each generation is different, won't fall into single-pattern loops\n\n**Challenges of Randomness:**\n- **Uncontrollable results**: You can't precisely predict generation results, may generate multiple times without satisfaction\n- **Hard to reproduce**: Even with identical inputs, hard to reproduce a specific good result\n- **Tuning difficulty**: When adjusting parameters, hard to tell if it's parameter effect or randomness change\n- **Screening cost**: Need to generate multiple versions to find satisfactory ones, increasing time cost\n\n#### What Mindset to Face Random Factors?\n\n**1. Accept Uncertainty**\n- Randomness is an essential characteristic of AI music generation, not a bug, but a feature\n- Don't expect every generation to be perfect; treat randomness as an exploration tool\n\n**2. Embrace the Exploration Process**\n- Treat generation process as \"gacha\" or \"treasure hunting\"—try multiple times, always find surprises\n- Enjoy discovering unexpectedly good results, rather than obsessing over one-time success\n\n**3. Use Fixed Seed Wisely**\n- When you want to **understand parameter effects**, fix `seed` to eliminate randomness interference\n- When you want to **explore creative space**, let `seed` vary randomly\n\n**4. Batch Generation + Intelligent Screening**\n- Don't rely on single generation; batch generate multiple versions\n- Use automatic scoring mechanisms for initial screening to improve efficiency\n\n#### Our Solution: Large Batch + Automatic Scoring\n\nBecause our inference is extremely fast, if your GPU VRAM is sufficient, you can explore random space through **large batch**:\n\n- **Batch generation**: Generate multiple versions at once (e.g., batch_size=2,4,8), quickly explore random space\n- **Automatic scoring mechanism**: We provide automatic scoring mechanisms that can help you initially screen, doing **test time scaling**\n\n**Automatic Scoring Mechanism**\n\nWe provide multiple scoring metrics, among which **my favorite is DiT Lyrics Alignment Score**:\n\n- **DiT Lyrics Alignment Score**: This score implicitly affects lyric accuracy\n  - It evaluates the alignment degree between lyrics and audio in generated audio\n  - Higher score means lyrics are more accurately positioned in audio, better match between singing and lyrics\n  - This is particularly important for music generation with lyrics, can help you screen versions with higher lyric accuracy\n\n- **Other scoring metrics**: Also include other quality assessment metrics, can evaluate generation results from multiple dimensions\n\n**Recommended Workflow:**\n\n1. **Batch generation**: Set larger `batch_size` (e.g., 2, 4, 8), generate multiple versions at once\n2. **Enable AutoGen**: Enable automatic generation, let system continuously generate new batches in background\n   - **AutoGen mechanism**: AutoGen automatically uses same parameters (but random seed) to generate next batch in background while you're viewing current batch results\n   - This lets you continuously explore random space without manually clicking generate button\n   - Each new batch uses new random seed, ensuring result diversity\n3. **Automatic scoring**: Enable automatic scoring, let system automatically score each version\n4. **Initial screening**: Screen versions with higher scores based on DiT Lyrics Alignment Score and other metrics\n5. **Manual selection**: Manually select the final version that best meets your needs from screened versions\n\nThis fully utilizes randomness to explore creative space while improving efficiency through automation tools, avoiding blind searching in large generation results. AutoGen lets you \"generate while listening\"—while browsing current results, the next batch is already prepared in the background.\n\n---\n\n## Conclusion\n\nThis tutorial currently covers ACE-Step 1.5's core concepts and usage methods:\n\n- **Mental Models**: Understanding human-centered generation design philosophy\n- **Model Architecture**: Understanding how LM and DiT work together\n- **Input Control**: Mastering text (Caption, Lyrics, metadata) and audio (reference audio, source audio) control methods\n- **Inference Hyperparameters**: Understanding parameters affecting generation process\n- **Random Factors**: Learning to use randomness to explore creative space, improving efficiency through Large Batch + AutoGen + Automatic Scoring\n\nThis is just the beginning. There's much more content we want to share with you:\n\n- More Prompting tips and practical cases\n- Detailed usage guides for different task types\n- Advanced techniques and creative workflows\n- Common issues and solutions\n- Performance optimization suggestions\n\n**This tutorial will continue to be updated and improved.** If you have any questions or suggestions during use, feedback is welcome. Let's make ACE-Step your creative partner in your pocket together.\n\n---\n\n*To be continued...*\n"
  },
  {
    "path": ".claude/skills/acestep-docs/guides/ENVIRONMENT_SETUP.md",
    "content": "# Environment Setup Guide\n\nThis guide covers Python environment setup for ACE-Step on Windows, Linux, and macOS.\n\n## Environment Options\n\n### Windows\n\n**Option 1: python_embeded (Portable Package)**\n- **Best for**: New users, zero-configuration setup\n- **Pros**: Extract and run, no installation required\n- **Cons**: Large download size (~7GB)\n- **Location**: `python_embeded\\python.exe`\n- **Download**: https://files.acemusic.ai/acemusic/win/ACE-Step-1.5.7z\n\n**Option 2: uv (Package Manager)**\n- **Best for**: Developers, Git repository users\n- **Pros**: Smaller installation, easy updates, excellent tooling\n- **Cons**: Requires uv installation\n- **Installation**: See [Installing uv](#installing-uv) below\n\n### Linux\n\n**uv (Package Manager)**\n- **Only supported option** (no portable package available for Linux)\n- **Best for**: All Linux users\n- **Requires**: uv package manager\n- **Backend**: vllm (default) or pt (PyTorch)\n- **Installation**: See [Installing uv](#installing-uv) below\n\n### macOS (Apple Silicon)\n\n**uv with MLX Backend**\n- **Only supported option** (no portable package available for macOS)\n- **Best for**: All macOS Apple Silicon (M1/M2/M3/M4) users\n- **Requires**: uv package manager\n- **Backend**: mlx (native Apple Silicon acceleration)\n- **Dedicated scripts**: `start_gradio_ui_macos.sh`, `start_api_server_macos.sh`\n- **Installation**: See [Installing uv](#installing-uv) below\n\nNote: Intel Macs can use the standard `start_gradio_ui.sh` with the PyTorch (pt) backend, but Apple Silicon Macs should use the macOS-specific scripts for optimal performance.\n\n## Automatic Detection\n\n### Windows (bat scripts)\n\nThe `.bat` startup scripts detect the environment in this order:\n\n1. **First**: Check for `python_embeded\\python.exe`\n   - If found: Use embedded Python directly\n   - If not found: Continue to step 2\n\n2. **Second**: Check for `uv` command\n   - If found: Use uv\n   - If not found: Prompt to install uv\n\n**Example output:**\n```\n[Environment] Using embedded Python...\n```\nor\n```\n[Environment] Embedded Python not found, checking for uv...\n[Environment] Using uv package manager...\n```\n\n### Linux/macOS (sh scripts)\n\nThe `.sh` startup scripts detect the environment in this order:\n\n1. **First**: Check for `uv` in PATH\n   - Also checks `~/.local/bin/uv` and `~/.cargo/bin/uv`\n   - If found: Use uv\n   - If not found: Prompt to install uv\n\n2. **If not found**: Offer automatic installation\n   - Calls `install_uv.sh --silent` to install uv\n   - Updates PATH and continues\n\n**Example output (Linux):**\n```\n[Environment] Using uv package manager...\n```\n\n**Example output (macOS):**\n```\n============================================\n  ACE-Step 1.5 - macOS Apple Silicon (MLX)\n============================================\n[Environment] Using uv package manager...\n```\n\n## Installing uv\n\n### All Platforms\n\n**Automatic**: When you run a startup script and uv is not found, you will be prompted:\n\n```\nuv package manager not found!\n\nInstall uv now? (Y/N):\n```\n\nType `Y` and press Enter. The script will automatically install uv using the appropriate method for your platform.\n\n### Windows Methods\n\n**Method 1: PowerShell (Recommended)**\n```powershell\nirm https://astral.sh/uv/install.ps1 | iex\n```\n\n**Method 2: winget (Windows 10 1809+, Windows 11)**\n```batch\nwinget install --id=astral-sh.uv -e\n```\n\n**Method 3: Run the install script**\n```batch\ninstall_uv.bat\n```\n\nThe `install_uv.bat` script tries PowerShell first, then falls back to winget if PowerShell fails.\n\n### Linux Methods\n\n**Method 1: curl installer (Recommended)**\n```bash\ncurl -LsSf https://astral.sh/uv/install.sh | sh\n```\n\n**Method 2: Run the install script**\n```bash\nchmod +x install_uv.sh\n./install_uv.sh\n```\n\nThe `install_uv.sh` script uses `curl` or `wget` to download and run the official installer.\n\n### macOS Methods\n\n**Method 1: curl installer (Recommended)**\n```bash\ncurl -LsSf https://astral.sh/uv/install.sh | sh\n```\n\n**Method 2: Homebrew**\n```bash\nbrew install uv\n```\n\n**Method 3: Run the install script**\n```bash\nchmod +x install_uv.sh\n./install_uv.sh\n```\n\nThe `install_uv.sh` script works on both Linux and macOS, and will suggest `brew install curl` on macOS if neither `curl` nor `wget` is available.\n\n## Installation Locations\n\n### Windows\n\n**PowerShell installation:**\n```\n%USERPROFILE%\\.local\\bin\\uv.exe\nExample: C:\\Users\\YourName\\.local\\bin\\uv.exe\n```\n\n**winget installation:**\n```\n%LOCALAPPDATA%\\Microsoft\\WinGet\\Links\\uv.exe\nExample: C:\\Users\\YourName\\AppData\\Local\\Microsoft\\WinGet\\Links\\uv.exe\n```\n\n### Linux\n\n**Default installation (curl installer):**\n```\n~/.local/bin/uv\nExample: /home/yourname/.local/bin/uv\n```\n\n**Alternative location (cargo):**\n```\n~/.cargo/bin/uv\nExample: /home/yourname/.cargo/bin/uv\n```\n\n### macOS\n\n**Default installation (curl installer):**\n```\n~/.local/bin/uv\nExample: /Users/yourname/.local/bin/uv\n```\n\n**Alternative location (cargo):**\n```\n~/.cargo/bin/uv\nExample: /Users/yourname/.cargo/bin/uv\n```\n\n**Homebrew installation:**\n```\n/opt/homebrew/bin/uv  (Apple Silicon)\n/usr/local/bin/uv     (Intel)\n```\n\n## First Run\n\n### Windows with python_embeded\n\n```batch\nREM Download and extract portable package from:\nREM https://files.acemusic.ai/acemusic/win/ACE-Step-1.5.7z\n\nREM Run the startup script\nstart_gradio_ui.bat\n\nREM Output:\nREM [Environment] Using embedded Python...\nREM Starting ACE-Step Gradio UI...\n```\n\n### Windows with uv\n\n```batch\nREM First time: uv will create a virtual environment and sync dependencies\nstart_gradio_ui.bat\n\nREM Output:\nREM [Environment] Using uv package manager...\nREM [Setup] Virtual environment not found. Setting up environment...\nREM Running: uv sync\n```\n\n### Linux with uv\n\n```bash\n# Make scripts executable (first time only)\nchmod +x start_gradio_ui.sh install_uv.sh\n\n# First time: uv will create a virtual environment and sync dependencies\n./start_gradio_ui.sh\n\n# Output:\n# [Environment] Using uv package manager...\n# [Setup] Virtual environment not found. Setting up environment...\n# Running: uv sync\n```\n\n### macOS (Apple Silicon) with uv\n\n```bash\n# Make scripts executable (first time only)\nchmod +x start_gradio_ui_macos.sh install_uv.sh\n\n# Use the macOS-specific script for MLX backend\n./start_gradio_ui_macos.sh\n\n# Output:\n# ============================================\n#   ACE-Step 1.5 - macOS Apple Silicon (MLX)\n# ============================================\n# [Environment] Using uv package manager...\n# [Setup] Virtual environment not found. Setting up environment...\n# Running: uv sync\n```\n\nNote: On macOS Apple Silicon, always use `start_gradio_ui_macos.sh` instead of `start_gradio_ui.sh` to enable the MLX backend for native acceleration.\n\n## Troubleshooting\n\n### \"uv not found\" after installation\n\n**Windows**\n\nCause: PATH not refreshed after installation.\n\nSolution 1: Restart your terminal (close and reopen Command Prompt or PowerShell).\n\nSolution 2: Use the full path temporarily:\n```batch\n%USERPROFILE%\\.local\\bin\\uv.exe run acestep\n```\n\n**Linux/macOS**\n\nCause: uv installed but not in PATH.\n\nSolution 1: Restart your terminal or source your profile:\n```bash\nsource ~/.bashrc    # or ~/.zshrc on macOS\n```\n\nSolution 2: Add uv to your PATH manually:\n```bash\n# For ~/.local/bin installation\necho 'export PATH=\"$HOME/.local/bin:$PATH\"' >> ~/.bashrc\nsource ~/.bashrc\n\n# For macOS with zsh (default shell)\necho 'export PATH=\"$HOME/.local/bin:$PATH\"' >> ~/.zshrc\nsource ~/.zshrc\n```\n\nSolution 3: Use the full path temporarily:\n```bash\n~/.local/bin/uv run acestep\n```\n\n### Permission issues (Linux/macOS)\n\n**Symptom**: `Permission denied` when running scripts.\n\n**Solution**:\n```bash\nchmod +x start_gradio_ui.sh\nchmod +x start_gradio_ui_macos.sh\nchmod +x install_uv.sh\n```\n\n**Symptom**: `Permission denied` during uv installation.\n\n**Solution**: The curl installer installs to `~/.local/bin` which should not require root. If you see permission errors:\n```bash\n# Ensure the directory exists and is writable\nmkdir -p ~/.local/bin\n```\n\nDo not use `sudo` with the uv installer.\n\n### winget not available (Windows)\n\n**Symptom**:\n```\n'winget' is not recognized as an internal or external command\n```\n\n**Solution**:\n- Windows 11: Should be pre-installed. Try updating Windows.\n- Windows 10: Install \"App Installer\" from the Microsoft Store.\n- Alternative: Use the PowerShell installation method instead:\n  ```powershell\n  irm https://astral.sh/uv/install.ps1 | iex\n  ```\n\n### Installation fails\n\n**Common causes**:\n- Network connection issues\n- Firewall blocking downloads\n- Antivirus software interference (Windows)\n- Missing `curl` or `wget` (Linux/macOS)\n\n**Solutions**:\n\n1. Check your internet connection.\n2. Temporarily disable firewall/antivirus (Windows).\n3. Try an alternative installation method:\n   - **Windows**: Use PowerShell method if winget fails, or vice versa.\n   - **Linux**: Install `curl` first (`sudo apt install curl` on Ubuntu/Debian, `sudo yum install curl` on CentOS/RHEL).\n   - **macOS**: Use `brew install uv` as an alternative.\n4. **Windows only**: Use the portable package instead: https://files.acemusic.ai/acemusic/win/ACE-Step-1.5.7z\n\n## Switching Environments (Windows Only)\n\nWindows is the only platform with two environment options. Linux and macOS use uv exclusively.\n\n### From python_embeded to uv\n\n```batch\nREM 1. Install uv\ninstall_uv.bat\n\nREM 2. Rename or delete python_embeded folder\nrename python_embeded python_embeded_backup\n\nREM 3. Run startup script (will use uv)\nstart_gradio_ui.bat\n```\n\n### From uv to python_embeded\n\n```batch\nREM 1. Download portable package\nREM https://files.acemusic.ai/acemusic/win/ACE-Step-1.5.7z\n\nREM 2. Extract python_embeded folder to project root\n\nREM 3. Run startup script (will use python_embeded)\nstart_gradio_ui.bat\n```\n\n## Environment Variables (.env)\n\nACE-Step can be configured using environment variables in a `.env` file.\n\n### Setup\n\n```bash\n# Copy the example file\ncp .env.example .env\n\n# Edit .env with your preferred settings\n```\n\n### Available Variables\n\n| Variable | Default | Description |\n|----------|---------|-------------|\n| `ACESTEP_INIT_LLM` | auto | LLM initialization control |\n| `ACESTEP_CONFIG_PATH` | acestep-v15-turbo | DiT model path |\n| `ACESTEP_LM_MODEL_PATH` | acestep-5Hz-lm-1.7B | LM model path |\n| `ACESTEP_DEVICE` | auto | Device: auto, cuda, cpu, xpu |\n| `ACESTEP_LM_BACKEND` | vllm | LM backend: vllm, pt, mlx |\n| `ACESTEP_DOWNLOAD_SOURCE` | auto | Download source |\n| `ACESTEP_API_KEY` | (none) | API authentication key |\n\n### ACESTEP_LM_BACKEND\n\nControls which backend is used for the Language Model.\n\n| Value | Platform | Description |\n|-------|----------|-------------|\n| `vllm` | Linux (CUDA) | Default. Fastest backend for NVIDIA GPUs. |\n| `pt` | All | PyTorch native backend. Works everywhere but slower. |\n| `mlx` | macOS (Apple Silicon) | Native Apple Silicon acceleration via MLX. |\n\n**Platform-specific recommendations:**\n- **Windows**: Use `vllm` (default) with NVIDIA GPU, or `pt` as fallback.\n- **Linux**: Use `vllm` (default) with NVIDIA GPU, or `pt` as fallback.\n- **macOS Apple Silicon**: Use `mlx` for best performance. The `start_gradio_ui_macos.sh` script sets this automatically via `export ACESTEP_LM_BACKEND=\"mlx\"`.\n\n**Example .env for macOS Apple Silicon:**\n```bash\nACESTEP_LM_BACKEND=mlx\nACESTEP_CONFIG_PATH=acestep-v15-turbo\nACESTEP_LM_MODEL_PATH=acestep-5Hz-lm-0.6B\n```\n\n### ACESTEP_INIT_LLM - LLM Initialization Control\n\nControls whether the Language Model (5Hz LM) is initialized at startup.\n\n**Processing Flow:**\n```\nGPU Detection (full) --> ACESTEP_INIT_LLM Override --> Model Loading\n```\n\n- GPU optimizations (offload, quantization, batch limits) are **always applied**\n- `ACESTEP_INIT_LLM` only overrides the \"should we load LLM\" decision\n- Model validation shows warnings but does not block when forcing\n\n| Value | Behavior |\n|-------|----------|\n| `auto` (or empty) | Use GPU auto-detection result (recommended) |\n| `true` / `1` / `yes` | Force enable LLM after GPU detection (may cause OOM) |\n| `false` / `0` / `no` | Force disable for pure DiT mode |\n\n**Example configurations:**\n\n```bash\n# Auto mode (recommended) - let GPU detection decide\nACESTEP_INIT_LLM=auto\n\n# Auto mode - leave empty (same as above)\nACESTEP_INIT_LLM=\n\n# Force enable on low VRAM GPU (GPU optimizations still applied)\nACESTEP_INIT_LLM=true\nACESTEP_LM_MODEL_PATH=acestep-5Hz-lm-0.6B  # Use smallest model\n\n# Force disable LLM for faster generation\nACESTEP_INIT_LLM=false\n```\n\n### Features Affected by LLM\n\nWhen LLM is disabled (`ACESTEP_INIT_LLM=false`), these features are unavailable:\n\n| Feature | Description | Available without LLM |\n|---------|-------------|----------------------|\n| Thinking mode | LLM generates audio codes | No |\n| CoT caption | LLM enhances captions | No (auto-disabled) |\n| CoT language | LLM detects vocal language | No (auto-disabled) |\n| Sample mode | Generate from description | No |\n| Format mode | LLM-enhanced input | No |\n| Basic generation | DiT-based synthesis | Yes |\n| Cover/Repaint | Audio editing tasks | Yes |\n\nNote: When using the API server, CoT features (`use_cot_caption`, `use_cot_language`) are automatically disabled when LLM is unavailable, allowing basic generation to proceed.\n\n## Environment Comparison\n\n| Feature | python_embeded (Windows) | uv (Windows) | uv (Linux) | uv (macOS) |\n|---------|--------------------------|---------------|-------------|-------------|\n| Setup Difficulty | Zero config | Need install | Need install | Need install |\n| Startup Speed | Fast | Fast | Fast | Fast |\n| Update Ease | Re-download | uv command | uv command | uv command |\n| Environment Isolation | Complete | Virtual env | Virtual env | Virtual env |\n| Development | Basic | Excellent | Excellent | Excellent |\n| Beginner Friendly | Best | Good | Good | Good |\n| GPU Backend | CUDA | CUDA | CUDA (vllm) | MLX (Apple Silicon) |\n| Install Script | N/A | install_uv.bat | install_uv.sh | install_uv.sh |\n| Launch Script | start_gradio_ui.bat | start_gradio_ui.bat | start_gradio_ui.sh | start_gradio_ui_macos.sh |\n\n## Recommendations\n\n### Windows\n\n**Use python_embeded if:**\n- First time using ACE-Step\n- Want zero configuration\n- Do not need frequent updates\n- Prefer a self-contained package\n\n**Use uv if:**\n- Developer or experienced with Python\n- Need to modify dependencies\n- Using the Git repository\n- Want smaller installation size\n- Need frequent code updates\n\n### Linux\n\n**Use uv (only option):**\n- Install uv via the curl installer or `install_uv.sh`\n- Use `start_gradio_ui.sh` to launch\n- NVIDIA GPU with CUDA is recommended for vllm backend\n- CPU-only is possible with `ACESTEP_DEVICE=cpu` and `ACESTEP_LM_BACKEND=pt`\n\n### macOS (Apple Silicon)\n\n**Use uv with MLX backend (recommended):**\n- Install uv via curl installer, Homebrew, or `install_uv.sh`\n- Use `start_gradio_ui_macos.sh` to launch (sets MLX backend automatically)\n- The 0.6B LM model (`acestep-5Hz-lm-0.6B`) is recommended for devices with limited unified memory\n- Set `ACESTEP_LM_BACKEND=mlx` in `.env` if launching manually\n- Intel Macs should use `start_gradio_ui.sh` with `ACESTEP_LM_BACKEND=pt` instead\n"
  },
  {
    "path": ".claude/skills/acestep-docs/guides/GPU_COMPATIBILITY.md",
    "content": "# GPU Compatibility Guide\n\nACE-Step 1.5 automatically adapts to your GPU's available VRAM, adjusting generation limits and LM model availability accordingly. The system detects GPU memory at startup and configures optimal settings.\n\n## GPU Tier Configuration\n\n| VRAM | Tier | LM Mode | Max Duration | Max Batch Size | LM Memory Allocation |\n|------|------|---------|--------------|----------------|---------------------|\n| ≤4GB | Tier 1 | Not available | 3 min | 1 | - |\n| 4-6GB | Tier 2 | Not available | 6 min | 1 | - |\n| 6-8GB | Tier 3 | 0.6B (optional) | With LM: 4 min / Without: 6 min | With LM: 1 / Without: 2 | 3GB |\n| 8-12GB | Tier 4 | 0.6B (optional) | With LM: 4 min / Without: 6 min | With LM: 2 / Without: 4 | 3GB |\n| 12-16GB | Tier 5 | 0.6B / 1.7B | With LM: 4 min / Without: 6 min | With LM: 2 / Without: 4 | 0.6B: 3GB, 1.7B: 8GB |\n| 16-24GB | Tier 6 | 0.6B / 1.7B / 4B | 8 min | With LM: 4 / Without: 8 | 0.6B: 3GB, 1.7B: 8GB, 4B: 12GB |\n| ≥24GB | Unlimited | All models | 10 min | 8 | Unrestricted |\n\n## Notes\n\n- **Default settings** are automatically configured based on detected GPU memory\n- **LM Mode** refers to the Language Model used for Chain-of-Thought generation and audio understanding\n- **Flash Attention**, **CPU Offload**, **Compile**, and **Quantization** are enabled by default for optimal performance\n- If you request a duration or batch size exceeding your GPU's limits, a warning will be displayed and values will be clamped\n- **Constrained Decoding**: When LM is initialized, the LM's duration generation is also constrained to the GPU tier's maximum duration limit, preventing out-of-memory errors during CoT generation\n- For GPUs with ≤6GB VRAM, LM initialization is disabled by default to preserve memory for the DiT model\n- You can manually override settings via command-line arguments or the Gradio UI\n\n## Overriding LLM Initialization\n\nBy default, LLM is auto-enabled/disabled based on GPU VRAM. You can override this behavior.\n\n**Important:** GPU optimizations (offload, quantization, batch limits) are **always applied** regardless of override. `ACESTEP_INIT_LLM` only controls whether to attempt LLM loading.\n\n### Processing Flow\n\n```\nGPU Detection (full)  →  ACESTEP_INIT_LLM Override  →  Model Loading\n     │                          │                          │\n     ├─ offload settings        ├─ auto: use GPU result    ├─ Download model\n     ├─ batch limits            ├─ true: force enable      ├─ Initialize LLM\n     ├─ duration limits         └─ false: force disable    └─ (with GPU settings)\n     └─ recommended models\n```\n\n### Gradio UI\n\n```bash\n# Force enable LLM (may cause OOM on low VRAM)\nuv run acestep --init_llm true\n\n# Force disable LLM (pure DiT mode)\nuv run acestep --init_llm false\n```\n\nOr in `start_gradio_ui.bat`:\n```batch\nset INIT_LLM=--init_llm true\n```\n\n### API Server\n\nUsing environment variable:\n```bash\n# Auto mode (recommended)\nset ACESTEP_INIT_LLM=auto\nuv run acestep-api\n\n# Force enable LLM\nset ACESTEP_INIT_LLM=true\nuv run acestep-api\n\n# Force disable LLM\nset ACESTEP_INIT_LLM=false\nuv run acestep-api\n```\n\nOr using command line:\n```bash\nuv run acestep-api --init-llm\n```\n\nOr in `start_api_server.bat`:\n```batch\nset ACESTEP_INIT_LLM=true\n```\n\n### When to Override\n\n| Scenario | Setting | Notes |\n|----------|---------|-------|\n| Low VRAM but need thinking mode | `true` | May cause OOM, use with caution |\n| Fast generation without CoT | `false` | Skips LLM, uses pure DiT |\n| API server pure DiT mode | `false` | Faster responses, simpler setup |\n| High VRAM but want minimal setup | `false` | No LLM model download needed |\n\n### Features Affected by LLM\n\nWhen LLM is disabled, these features are automatically disabled:\n- **Thinking mode** (`thinking=true`)\n- **CoT caption/language detection** (`use_cot_caption`, `use_cot_language`)\n- **Sample mode** (generate from description)\n- **Format mode** (LLM-enhanced input)\n\nThe API server will automatically fallback to pure DiT mode when these features are requested but LLM is unavailable.\n\n> **Community Contributions Welcome**: The GPU tier configurations above are based on our testing across common hardware. If you find that your device's actual performance differs from these parameters (e.g., can handle longer durations or larger batch sizes), we welcome you to conduct more thorough testing and submit a PR to optimize these configurations in `acestep/gpu_config.py`. Your contributions help improve the experience for all users!\n\n## Memory Optimization Tips\n\n1. **Low VRAM (<8GB)**: Use DiT-only mode without LM initialization for maximum duration\n2. **Medium VRAM (8-16GB)**: Use the 0.6B LM model for best balance of quality and memory\n3. **High VRAM (>16GB)**: Enable larger LM models (1.7B/4B) for better audio understanding and generation quality\n\n## Debug Mode: Simulating Different GPU Configurations\n\nFor testing and development, you can simulate different GPU memory sizes using the `MAX_CUDA_VRAM` environment variable:\n\n```bash\n# Simulate a 4GB GPU (Tier 1)\nMAX_CUDA_VRAM=4 uv run acestep\n\n# Simulate an 8GB GPU (Tier 4)\nMAX_CUDA_VRAM=8 uv run acestep\n\n# Simulate a 12GB GPU (Tier 5)\nMAX_CUDA_VRAM=12 uv run acestep\n\n# Simulate a 16GB GPU (Tier 6)\nMAX_CUDA_VRAM=16 uv run acestep\n```\n\nThis is useful for:\n- Testing GPU tier configurations on high-end hardware\n- Verifying that warnings and limits work correctly for each tier\n- Developing and testing new GPU configuration parameters before submitting a PR\n"
  },
  {
    "path": ".claude/skills/acestep-docs/guides/GRADIO_GUIDE.md",
    "content": "# ACE-Step Gradio Demo User Guide\n\n---\n\nThis guide provides comprehensive documentation for using the ACE-Step Gradio web interface for music generation, including all features and settings.\n\n## Table of Contents\n\n- [Getting Started](#getting-started)\n- [Service Configuration](#service-configuration)\n- [Generation Modes](#generation-modes)\n- [Task Types](#task-types)\n- [Input Parameters](#input-parameters)\n- [Advanced Settings](#advanced-settings)\n- [Results Section](#results-section)\n- [LoRA Training](#lora-training)\n- [Tips and Best Practices](#tips-and-best-practices)\n\n---\n\n## Getting Started\n\n### Launching the Demo\n\n```bash\n# Basic launch\npython app.py\n\n# With pre-initialization\npython app.py --config acestep-v15-turbo --init-llm\n\n# With specific port\npython app.py --port 7860\n```\n\n### Interface Overview\n\nThe Gradio interface consists of several main sections:\n\n1. **Service Configuration** - Model loading and initialization\n2. **Required Inputs** - Task type, audio uploads, and generation mode\n3. **Music Caption & Lyrics** - Text inputs for generation\n4. **Optional Parameters** - Metadata like BPM, key, duration\n5. **Advanced Settings** - Fine-grained control over generation\n6. **Results** - Generated audio playback and management\n\n---\n\n## Service Configuration\n\n### Model Selection\n\n| Setting | Description |\n|---------|-------------|\n| **Checkpoint File** | Select a trained model checkpoint (if available) |\n| **Main Model Path** | Choose the DiT model configuration (e.g., `acestep-v15-turbo`, `acestep-v15-turbo-shift3`) |\n| **Device** | Processing device: `auto` (recommended), `cuda`, or `cpu` |\n\n### 5Hz LM Configuration\n\n| Setting | Description |\n|---------|-------------|\n| **5Hz LM Model Path** | Select the language model (e.g., `acestep-5Hz-lm-0.6B`, `acestep-5Hz-lm-1.7B`) |\n| **5Hz LM Backend** | `vllm` (faster, recommended) or `pt` (PyTorch, more compatible) |\n| **Initialize 5Hz LM** | Check to load the LM during initialization (required for thinking mode) |\n\n### Performance Options\n\n| Setting | Description |\n|---------|-------------|\n| **Use Flash Attention** | Enable for faster inference (requires flash_attn package) |\n| **Offload to CPU** | Offload models to CPU when idle to save GPU memory |\n| **Offload DiT to CPU** | Specifically offload the DiT model to CPU |\n\n### LoRA Adapter\n\n| Setting | Description |\n|---------|-------------|\n| **LoRA Path** | Path to trained LoRA adapter directory |\n| **Load LoRA** | Load the specified LoRA adapter |\n| **Unload** | Remove the currently loaded LoRA |\n| **Use LoRA** | Enable/disable the loaded LoRA for inference |\n\n### Initialization\n\nClick **Initialize Service** to load the models. The status box will show progress and confirmation.\n\n---\n\n## Generation Modes\n\n### Simple Mode\n\nSimple mode is designed for quick, natural language-based music generation.\n\n**How to use:**\n1. Select \"Simple\" in the Generation Mode radio button\n2. Enter a natural language description in the \"Song Description\" field\n3. Optionally check \"Instrumental\" if you don't want vocals\n4. Optionally select a preferred vocal language\n5. Click **Create Sample** to generate caption, lyrics, and metadata\n6. Review the generated content in the expanded sections\n7. Click **Generate Music** to create the audio\n\n**Example descriptions:**\n- \"a soft Bengali love song for a quiet evening\"\n- \"upbeat electronic dance music with heavy bass drops\"\n- \"melancholic indie folk with acoustic guitar\"\n- \"jazz trio playing in a smoky bar\"\n\n**Random Sample:** Click the 🎲 button to load a random example description.\n\n### Custom Mode\n\nCustom mode provides full control over all generation parameters.\n\n**How to use:**\n1. Select \"Custom\" in the Generation Mode radio button\n2. Manually fill in the Caption and Lyrics fields\n3. Set optional metadata (BPM, Key, Duration, etc.)\n4. Optionally click **Format** to enhance your input using the LM\n5. Configure advanced settings as needed\n6. Click **Generate Music** to create the audio\n\n---\n\n## Task Types\n\n### text2music (Default)\n\nGenerate music from text descriptions and/or lyrics.\n\n**Use case:** Creating new music from scratch based on prompts.\n\n**Required inputs:** Caption or Lyrics (at least one)\n\n### cover\n\nTransform existing audio while maintaining structure but changing style.\n\n**Use case:** Creating cover versions in different styles.\n\n**Required inputs:**\n- Source Audio (upload in Audio Uploads section)\n- Caption describing the target style\n\n**Key parameter:** `Audio Cover Strength` (0.0-1.0)\n- Higher values maintain more of the original structure\n- Lower values allow more creative freedom\n\n### repaint\n\nRegenerate a specific time segment of audio.\n\n**Use case:** Fixing or modifying specific sections of generated music.\n\n**Required inputs:**\n- Source Audio\n- Repainting Start (seconds)\n- Repainting End (seconds, -1 for end of file)\n- Caption describing the desired content\n\n### lego (Base Model Only)\n\nGenerate a specific instrument track in context of existing audio.\n\n**Use case:** Adding instrument layers to backing tracks.\n\n**Required inputs:**\n- Source Audio\n- Track Name (select from dropdown)\n- Caption describing the track characteristics\n\n**Available tracks:** vocals, backing_vocals, drums, bass, guitar, keyboard, percussion, strings, synth, fx, brass, woodwinds\n\n### extract (Base Model Only)\n\nExtract/isolate a specific instrument track from mixed audio.\n\n**Use case:** Stem separation, isolating instruments.\n\n**Required inputs:**\n- Source Audio\n- Track Name to extract\n\n### complete (Base Model Only)\n\nComplete partial tracks with specified instruments.\n\n**Use case:** Auto-arranging incomplete compositions.\n\n**Required inputs:**\n- Source Audio\n- Track Names (multiple selection)\n- Caption describing the desired style\n\n---\n\n## Input Parameters\n\n### Required Inputs\n\n#### Task Type\nSelect the generation task from the dropdown. The instruction field updates automatically based on the selected task.\n\n#### Audio Uploads\n\n| Field | Description |\n|-------|-------------|\n| **Reference Audio** | Optional audio for style reference |\n| **Source Audio** | Required for cover, repaint, lego, extract, complete tasks |\n| **Convert to Codes** | Extract 5Hz semantic codes from source audio |\n\n#### LM Codes Hints\n\nPre-computed audio semantic codes can be pasted here to guide generation. Use the **Transcribe** button to analyze codes and extract metadata.\n\n### Music Caption\n\nThe text description of the desired music. Be specific about:\n- Genre and style\n- Instruments\n- Mood and atmosphere\n- Tempo feel (if not specifying BPM)\n\n**Example:** \"upbeat pop rock with electric guitars, driving drums, and catchy synth hooks\"\n\nClick 🎲 to load a random example caption.\n\n### Lyrics\n\nEnter lyrics with structure tags:\n\n```\n[Verse 1]\nWalking down the street today\nThinking of the words you used to say\n\n[Chorus]\nI'm moving on, I'm staying strong\nThis is where I belong\n\n[Verse 2]\n...\n```\n\n**Instrumental checkbox:** Check this to generate instrumental music regardless of lyrics content.\n\n**Vocal Language:** Select the language for vocals. Use \"unknown\" for auto-detection or instrumental tracks.\n\n**Format button:** Click to enhance caption and lyrics using the 5Hz LM.\n\n### Optional Parameters\n\n| Parameter | Default | Description |\n|-----------|---------|-------------|\n| **BPM** | Auto | Tempo in beats per minute (30-300) |\n| **Key Scale** | Auto | Musical key (e.g., \"C Major\", \"Am\", \"F# minor\") |\n| **Time Signature** | Auto | Time signature: 2 (2/4), 3 (3/4), 4 (4/4), 6 (6/8) |\n| **Audio Duration** | Auto/-1 | Target length in seconds (10-600). -1 for automatic |\n| **Batch Size** | 2 | Number of audio variations to generate (1-8) |\n\n---\n\n## Advanced Settings\n\n### DiT Parameters\n\n| Parameter | Default | Description |\n|-----------|---------|-------------|\n| **Inference Steps** | 8 | Denoising steps. Turbo: 1-20, Base: 1-200 |\n| **Guidance Scale** | 7.0 | CFG strength (base model only). Higher = follows prompt more |\n| **Seed** | -1 | Random seed. Use comma-separated values for batches |\n| **Random Seed** | ✓ | When checked, generates random seeds |\n| **Audio Format** | mp3 | Output format: mp3, flac |\n| **Shift** | 3.0 | Timestep shift factor (1.0-5.0). Recommended 3.0 for turbo |\n| **Inference Method** | ode | ode (Euler, faster) or sde (stochastic) |\n| **Custom Timesteps** | - | Override timesteps (e.g., \"0.97,0.76,0.615,0.5,0.395,0.28,0.18,0.085,0\") |\n\n### Base Model Only Parameters\n\n| Parameter | Default | Description |\n|-----------|---------|-------------|\n| **Use ADG** | ✗ | Enable Adaptive Dual Guidance for better quality |\n| **CFG Interval Start** | 0.0 | When to start applying CFG (0.0-1.0) |\n| **CFG Interval End** | 1.0 | When to stop applying CFG (0.0-1.0) |\n\n### LM Parameters\n\n| Parameter | Default | Description |\n|-----------|---------|-------------|\n| **LM Temperature** | 0.85 | Sampling temperature (0.0-2.0). Higher = more creative |\n| **LM CFG Scale** | 2.0 | LM guidance strength (1.0-3.0) |\n| **LM Top-K** | 0 | Top-K sampling. 0 disables |\n| **LM Top-P** | 0.9 | Nucleus sampling (0.0-1.0) |\n| **LM Negative Prompt** | \"NO USER INPUT\" | Negative prompt for CFG |\n\n### CoT (Chain-of-Thought) Options\n\n| Option | Default | Description |\n|--------|---------|-------------|\n| **CoT Metas** | ✓ | Generate metadata via LM reasoning |\n| **CoT Language** | ✓ | Detect vocal language via LM |\n| **Constrained Decoding Debug** | ✗ | Enable debug logging |\n\n### Generation Options\n\n| Option | Default | Description |\n|--------|---------|-------------|\n| **LM Codes Strength** | 1.0 | How strongly LM codes influence generation (0.0-1.0) |\n| **Auto Score** | ✗ | Automatically calculate quality scores |\n| **Auto LRC** | ✗ | Automatically generate lyrics timestamps |\n| **LM Batch Chunk Size** | 8 | Max items per LM batch (GPU memory) |\n\n### Main Generation Controls\n\n| Control | Description |\n|---------|-------------|\n| **Think** | Enable 5Hz LM for code generation and metadata |\n| **ParallelThinking** | Enable parallel LM batch processing |\n| **CaptionRewrite** | Let LM enhance the input caption |\n| **AutoGen** | Automatically start next batch after completion |\n\n---\n\n## Results Section\n\n### Generated Audio\n\nUp to 8 audio samples are displayed based on batch size. Each sample includes:\n\n- **Audio Player** - Play, pause, and download the generated audio\n- **Send To Src** - Send this audio to the Source Audio input for further processing\n- **Save** - Save audio and metadata to a JSON file\n- **Score** - Calculate perplexity-based quality score\n- **LRC** - Generate lyrics timestamps (LRC format)\n\n### Details Accordion\n\nClick \"Score & LRC & LM Codes\" to expand and view:\n- **LM Codes** - The 5Hz semantic codes for this sample\n- **Quality Score** - Perplexity-based quality metric\n- **Lyrics Timestamps** - LRC format timing data\n\n### Batch Navigation\n\n| Control | Description |\n|---------|-------------|\n| **◀ Previous** | View the previous batch |\n| **Batch Indicator** | Shows current batch position (e.g., \"Batch 1 / 3\") |\n| **Next Batch Status** | Shows background generation progress |\n| **Next ▶** | View the next batch (triggers generation if AutoGen is on) |\n\n### Restore Parameters\n\nClick **Apply These Settings to UI** to restore all generation parameters from the current batch back to the input fields. Useful for iterating on a good result.\n\n### Batch Results\n\nThe \"Batch Results & Generation Details\" accordion contains:\n- **All Generated Files** - Download all files from all batches\n- **Generation Details** - Detailed information about the generation process\n\n---\n\n## LoRA Training\n\nThe LoRA Training tab provides tools for creating custom LoRA adapters.\n\n### Dataset Builder Tab\n\n#### Step 1: Load or Scan\n\n**Option A: Load Existing Dataset**\n1. Enter the path to a previously saved dataset JSON\n2. Click **Load**\n\n**Option B: Scan New Directory**\n1. Enter the path to your audio folder\n2. Click **Scan** to find audio files (wav, mp3, flac, ogg, opus)\n\n#### Step 2: Configure Dataset\n\n| Setting | Description |\n|---------|-------------|\n| **Dataset Name** | Name for your dataset |\n| **All Instrumental** | Check if all tracks have no vocals |\n| **Custom Activation Tag** | Unique tag to activate this LoRA's style |\n| **Tag Position** | Where to place the tag: Prepend, Append, or Replace caption |\n\n#### Step 3: Auto-Label\n\nClick **Auto-Label All** to generate metadata for all audio files:\n- Caption (music description)\n- BPM\n- Key\n- Time Signature\n\n**Skip Metas** option will skip LLM labeling and use N/A values.\n\n#### Step 4: Preview & Edit\n\nUse the slider to select samples and manually edit:\n- Caption\n- Lyrics\n- BPM, Key, Time Signature\n- Language\n- Instrumental flag\n\nClick **Save Changes** to update the sample.\n\n#### Step 5: Save Dataset\n\nEnter a save path and click **Save Dataset** to export as JSON.\n\n#### Step 6: Preprocess\n\nConvert the dataset to pre-computed tensors for fast training:\n1. Optionally load an existing dataset JSON\n2. Set the tensor output directory\n3. Click **Preprocess**\n\nThis encodes audio to VAE latents, text to embeddings, and runs the condition encoder.\n\n### Train LoRA Tab\n\n#### Dataset Selection\n\nEnter the path to preprocessed tensors directory and click **Load Dataset**.\n\n#### LoRA Settings\n\n| Setting | Default | Description |\n|---------|---------|-------------|\n| **LoRA Rank (r)** | 64 | Capacity of LoRA. Higher = more capacity, more memory |\n| **LoRA Alpha** | 128 | Scaling factor (typically 2x rank) |\n| **LoRA Dropout** | 0.1 | Dropout rate for regularization |\n\n#### Training Parameters\n\n| Setting | Default | Description |\n|---------|---------|-------------|\n| **Learning Rate** | 1e-4 | Optimization learning rate |\n| **Max Epochs** | 500 | Maximum training epochs |\n| **Batch Size** | 1 | Training batch size |\n| **Gradient Accumulation** | 1 | Effective batch = batch_size × accumulation |\n| **Save Every N Epochs** | 200 | Checkpoint save frequency |\n| **Shift** | 3.0 | Timestep shift for turbo model |\n| **Seed** | 42 | Random seed for reproducibility |\n\n#### Training Controls\n\n- **Start Training** - Begin the training process\n- **Stop Training** - Interrupt training\n- **Training Progress** - Shows current epoch and loss\n- **Training Log** - Detailed training output\n- **Training Loss Plot** - Visual loss curve\n\n#### Export LoRA\n\nAfter training, export the final adapter:\n1. Enter the export path\n2. Click **Export LoRA**\n\n---\n\n## Tips and Best Practices\n\n### For Best Quality\n\n1. **Use thinking mode** - Keep \"Think\" checkbox enabled for LM-enhanced generation\n2. **Be specific in captions** - Include genre, instruments, mood, and style details\n3. **Let LM detect metadata** - Leave BPM/Key/Duration empty for auto-detection\n4. **Use batch generation** - Generate 2-4 variations and pick the best\n\n### For Faster Generation\n\n1. **Use turbo model** - Select `acestep-v15-turbo` or `acestep-v15-turbo-shift3`\n2. **Keep inference steps at 8** - Default is optimal for turbo\n3. **Reduce batch size** - Lower batch size if you need quick results\n4. **Disable AutoGen** - Manual control over batch generation\n\n### For Consistent Results\n\n1. **Set a specific seed** - Uncheck \"Random Seed\" and enter a seed value\n2. **Save good results** - Use \"Save\" to export parameters for reproduction\n3. **Use \"Apply These Settings\"** - Restore parameters from a good batch\n\n### For Long-form Music\n\n1. **Set explicit duration** - Specify duration in seconds\n2. **Use repaint task** - Fix problematic sections after initial generation\n3. **Chain generations** - Use \"Send To Src\" to build upon previous results\n\n### For Style Consistency\n\n1. **Train a LoRA** - Create a custom adapter for your style\n2. **Use reference audio** - Upload style reference in Audio Uploads\n3. **Use consistent captions** - Maintain similar descriptive language\n\n### Troubleshooting\n\n**No audio generated:**\n- Check that the model is initialized (green status message)\n- Ensure 5Hz LM is initialized if using thinking mode\n- Check the status output for error messages\n\n**Poor quality results:**\n- Increase inference steps (for base model)\n- Adjust guidance scale\n- Try different seeds\n- Make caption more specific\n\n**Out of memory:**\n- Reduce batch size\n- Enable CPU offloading\n- Reduce LM batch chunk size\n\n**LM not working:**\n- Ensure \"Initialize 5Hz LM\" was checked during initialization\n- Check that a valid LM model path is selected\n- Verify vllm or PyTorch backend is available\n\n---\n\n## Keyboard Shortcuts\n\nThe Gradio interface supports standard web shortcuts:\n- **Tab** - Move between input fields\n- **Enter** - Submit text inputs\n- **Space** - Toggle checkboxes\n\n---\n\n## Language Support\n\nThe interface supports multiple UI languages:\n- **English** (en)\n- **Chinese** (zh)\n- **Japanese** (ja)\n\nSelect your preferred language in the Service Configuration section.\n\n---\n\nFor more information, see:\n- Main README: [`../../README.md`](../../README.md)\n- REST API Documentation: [`API.md`](API.md)\n- Python Inference API: [`INFERENCE.md`](INFERENCE.md)\n"
  },
  {
    "path": ".claude/skills/acestep-docs/guides/INFERENCE.md",
    "content": "# ACE-Step Inference API Documentation\n\n---\n\nThis document provides comprehensive documentation for the ACE-Step inference API, including parameter specifications for all supported task types.\n\n## Table of Contents\n\n- [Quick Start](#quick-start)\n- [API Overview](#api-overview)\n- [GenerationParams Parameters](#generationparams-parameters)\n- [GenerationConfig Parameters](#generationconfig-parameters)\n- [Task Types](#task-types)\n- [Helper Functions](#helper-functions)\n- [Complete Examples](#complete-examples)\n- [Best Practices](#best-practices)\n\n---\n\n## Quick Start\n\n### Basic Usage\n\n```python\nfrom acestep.handler import AceStepHandler\nfrom acestep.llm_inference import LLMHandler\nfrom acestep.inference import GenerationParams, GenerationConfig, generate_music\n\n# Initialize handlers\ndit_handler = AceStepHandler()\nllm_handler = LLMHandler()\n\n# Initialize services\ndit_handler.initialize_service(\n    project_root=\"/path/to/project\",\n    config_path=\"acestep-v15-turbo\",\n    device=\"cuda\"\n)\n\nllm_handler.initialize(\n    checkpoint_dir=\"/path/to/checkpoints\",\n    lm_model_path=\"acestep-5Hz-lm-0.6B\",\n    backend=\"vllm\",\n    device=\"cuda\"\n)\n\n# Configure generation parameters\nparams = GenerationParams(\n    caption=\"upbeat electronic dance music with heavy bass\",\n    bpm=128,\n    duration=30,\n)\n\n# Configure generation settings\nconfig = GenerationConfig(\n    batch_size=2,\n    audio_format=\"flac\",\n)\n\n# Generate music\nresult = generate_music(dit_handler, llm_handler, params, config, save_dir=\"/path/to/output\")\n\n# Access results\nif result.success:\n    for audio in result.audios:\n        print(f\"Generated: {audio['path']}\")\n        print(f\"Key: {audio['key']}\")\n        print(f\"Seed: {audio['params']['seed']}\")\nelse:\n    print(f\"Error: {result.error}\")\n```\n\n---\n\n## API Overview\n\n### Main Functions\n\n#### generate_music\n\n```python\ndef generate_music(\n    dit_handler,\n    llm_handler,\n    params: GenerationParams,\n    config: GenerationConfig,\n    save_dir: Optional[str] = None,\n    progress=None,\n) -> GenerationResult\n```\n\nMain function for generating music using the ACE-Step model.\n\n#### understand_music\n\n```python\ndef understand_music(\n    llm_handler,\n    audio_codes: str,\n    temperature: float = 0.85,\n    top_k: Optional[int] = None,\n    top_p: Optional[float] = None,\n    repetition_penalty: float = 1.0,\n    use_constrained_decoding: bool = True,\n    constrained_decoding_debug: bool = False,\n) -> UnderstandResult\n```\n\nAnalyze audio semantic codes and extract metadata (caption, lyrics, BPM, key, etc.).\n\n#### create_sample\n\n```python\ndef create_sample(\n    llm_handler,\n    query: str,\n    instrumental: bool = False,\n    vocal_language: Optional[str] = None,\n    temperature: float = 0.85,\n    top_k: Optional[int] = None,\n    top_p: Optional[float] = None,\n    repetition_penalty: float = 1.0,\n    use_constrained_decoding: bool = True,\n    constrained_decoding_debug: bool = False,\n) -> CreateSampleResult\n```\n\nGenerate a complete music sample (caption, lyrics, metadata) from a natural language description.\n\n#### format_sample\n\n```python\ndef format_sample(\n    llm_handler,\n    caption: str,\n    lyrics: str,\n    user_metadata: Optional[Dict[str, Any]] = None,\n    temperature: float = 0.85,\n    top_k: Optional[int] = None,\n    top_p: Optional[float] = None,\n    repetition_penalty: float = 1.0,\n    use_constrained_decoding: bool = True,\n    constrained_decoding_debug: bool = False,\n) -> FormatSampleResult\n```\n\nFormat and enhance user-provided caption and lyrics, generating structured metadata.\n\n### Configuration Objects\n\nThe API uses two configuration dataclasses:\n\n**GenerationParams** - Contains all music generation parameters:\n\n```python\n@dataclass\nclass GenerationParams:\n    # Task & Instruction\n    task_type: str = \"text2music\"\n    instruction: str = \"Fill the audio semantic mask based on the given conditions:\"\n    \n    # Audio Uploads\n    reference_audio: Optional[str] = None\n    src_audio: Optional[str] = None\n    \n    # LM Codes Hints\n    audio_codes: str = \"\"\n    \n    # Text Inputs\n    caption: str = \"\"\n    lyrics: str = \"\"\n    instrumental: bool = False\n    \n    # Metadata\n    vocal_language: str = \"unknown\"\n    bpm: Optional[int] = None\n    keyscale: str = \"\"\n    timesignature: str = \"\"\n    duration: float = -1.0\n    \n    # Advanced Settings\n    inference_steps: int = 8\n    seed: int = -1\n    guidance_scale: float = 7.0\n    use_adg: bool = False\n    cfg_interval_start: float = 0.0\n    cfg_interval_end: float = 1.0\n    shift: float = 1.0                    # NEW: Timestep shift factor\n    infer_method: str = \"ode\"             # NEW: Diffusion inference method\n    timesteps: Optional[List[float]] = None  # NEW: Custom timesteps\n    \n    repainting_start: float = 0.0\n    repainting_end: float = -1\n    audio_cover_strength: float = 1.0\n    \n    # 5Hz Language Model Parameters\n    thinking: bool = True\n    lm_temperature: float = 0.85\n    lm_cfg_scale: float = 2.0\n    lm_top_k: int = 0\n    lm_top_p: float = 0.9\n    lm_negative_prompt: str = \"NO USER INPUT\"\n    use_cot_metas: bool = True\n    use_cot_caption: bool = True\n    use_cot_lyrics: bool = False\n    use_cot_language: bool = True\n    use_constrained_decoding: bool = True\n    \n    # CoT Generated Values (auto-filled by LM)\n    cot_bpm: Optional[int] = None\n    cot_keyscale: str = \"\"\n    cot_timesignature: str = \"\"\n    cot_duration: Optional[float] = None\n    cot_vocal_language: str = \"unknown\"\n    cot_caption: str = \"\"\n    cot_lyrics: str = \"\"\n```\n\n**GenerationConfig** - Contains batch and output configuration:\n\n```python\n@dataclass\nclass GenerationConfig:\n    batch_size: int = 2\n    allow_lm_batch: bool = False\n    use_random_seed: bool = True\n    seeds: Optional[List[int]] = None\n    lm_batch_chunk_size: int = 8\n    constrained_decoding_debug: bool = False\n    audio_format: str = \"flac\"\n```\n\n### Result Objects\n\n**GenerationResult** - Result of music generation:\n\n```python\n@dataclass\nclass GenerationResult:\n    # Audio Outputs\n    audios: List[Dict[str, Any]]  # List of audio dictionaries\n    \n    # Generation Information\n    status_message: str           # Status message from generation\n    extra_outputs: Dict[str, Any] # Extra outputs (latents, masks, lm_metadata, time_costs)\n    \n    # Success Status\n    success: bool                 # Whether generation succeeded\n    error: Optional[str]          # Error message if failed\n```\n\n**Audio Dictionary Structure:**\n\nEach item in `audios` list contains:\n\n```python\n{\n    \"path\": str,           # File path to saved audio\n    \"tensor\": Tensor,      # Audio tensor [channels, samples], CPU, float32\n    \"key\": str,            # Unique audio key (UUID based on params)\n    \"sample_rate\": int,    # Sample rate (default: 48000)\n    \"params\": Dict,        # Generation params for this audio (includes seed, audio_codes, etc.)\n}\n```\n\n**UnderstandResult** - Result of music understanding:\n\n```python\n@dataclass\nclass UnderstandResult:\n    # Metadata Fields\n    caption: str = \"\"\n    lyrics: str = \"\"\n    bpm: Optional[int] = None\n    duration: Optional[float] = None\n    keyscale: str = \"\"\n    language: str = \"\"\n    timesignature: str = \"\"\n    \n    # Status\n    status_message: str = \"\"\n    success: bool = True\n    error: Optional[str] = None\n```\n\n**CreateSampleResult** - Result of sample creation:\n\n```python\n@dataclass\nclass CreateSampleResult:\n    # Metadata Fields\n    caption: str = \"\"\n    lyrics: str = \"\"\n    bpm: Optional[int] = None\n    duration: Optional[float] = None\n    keyscale: str = \"\"\n    language: str = \"\"\n    timesignature: str = \"\"\n    instrumental: bool = False\n    \n    # Status\n    status_message: str = \"\"\n    success: bool = True\n    error: Optional[str] = None\n```\n\n**FormatSampleResult** - Result of sample formatting:\n\n```python\n@dataclass\nclass FormatSampleResult:\n    # Metadata Fields\n    caption: str = \"\"\n    lyrics: str = \"\"\n    bpm: Optional[int] = None\n    duration: Optional[float] = None\n    keyscale: str = \"\"\n    language: str = \"\"\n    timesignature: str = \"\"\n    \n    # Status\n    status_message: str = \"\"\n    success: bool = True\n    error: Optional[str] = None\n```\n\n---\n\n## GenerationParams Parameters\n\n### Text Inputs\n\n| Parameter | Type | Default | Description |\n|-----------|------|---------|-------------|\n| `caption` | `str` | `\"\"` | Text description of the desired music. Can be a simple prompt like \"relaxing piano music\" or detailed description with genre, mood, instruments, etc. Max 512 characters. |\n| `lyrics` | `str` | `\"\"` | Lyrics text for vocal music. Use `\"[Instrumental]\"` for instrumental tracks. Supports multiple languages. Max 4096 characters. |\n| `instrumental` | `bool` | `False` | If True, generate instrumental music regardless of lyrics. |\n\n### Music Metadata\n\n| Parameter | Type | Default | Description |\n|-----------|------|---------|-------------|\n| `bpm` | `Optional[int]` | `None` | Beats per minute (30-300). `None` enables auto-detection via LM. |\n| `keyscale` | `str` | `\"\"` | Musical key (e.g., \"C Major\", \"Am\", \"F# minor\"). Empty string enables auto-detection. |\n| `timesignature` | `str` | `\"\"` | Time signature (2 for '2/4', 3 for '3/4', 4 for '4/4', 6 for '6/8'). Empty string enables auto-detection. |\n| `vocal_language` | `str` | `\"unknown\"` | Language code for vocals (ISO 639-1). Supported: `\"en\"`, `\"zh\"`, `\"ja\"`, `\"es\"`, `\"fr\"`, etc. Use `\"unknown\"` for auto-detection. |\n| `duration` | `float` | `-1.0` | Target audio length in seconds (10-600). If <= 0 or None, model chooses automatically based on lyrics length. |\n\n### Generation Parameters\n\n| Parameter | Type | Default | Description |\n|-----------|------|---------|-------------|\n| `inference_steps` | `int` | `8` | Number of denoising steps. Turbo model: 1-20 (recommended 8). Base model: 1-200 (recommended 32-64). Higher = better quality but slower. |\n| `guidance_scale` | `float` | `7.0` | Classifier-free guidance scale (1.0-15.0). Higher values increase adherence to text prompt. Only supported for non-turbo model. Typical range: 5.0-9.0. |\n| `seed` | `int` | `-1` | Random seed for reproducibility. Use `-1` for random seed, or any positive integer for fixed seed. |\n\n### Advanced DiT Parameters\n\n| Parameter | Type | Default | Description |\n|-----------|------|---------|-------------|\n| `use_adg` | `bool` | `False` | Use Adaptive Dual Guidance (base model only). Improves quality at the cost of speed. |\n| `cfg_interval_start` | `float` | `0.0` | CFG application start ratio (0.0-1.0). Controls when to start applying classifier-free guidance. |\n| `cfg_interval_end` | `float` | `1.0` | CFG application end ratio (0.0-1.0). Controls when to stop applying classifier-free guidance. |\n| `shift` | `float` | `1.0` | Timestep shift factor (range 1.0-5.0, default 1.0). When != 1.0, applies `t = shift * t / (1 + (shift - 1) * t)` to timesteps. Recommended 3.0 for turbo models. |\n| `infer_method` | `str` | `\"ode\"` | Diffusion inference method. `\"ode\"` (Euler) is faster and deterministic. `\"sde\"` (stochastic) may produce different results with variance. |\n| `timesteps` | `Optional[List[float]]` | `None` | Custom timesteps as a list of floats from 1.0 to 0.0 (e.g., `[0.97, 0.76, 0.615, 0.5, 0.395, 0.28, 0.18, 0.085, 0]`). If provided, overrides `inference_steps` and `shift`. |\n\n### Task-Specific Parameters\n\n| Parameter | Type | Default | Description |\n|-----------|------|---------|-------------|\n| `task_type` | `str` | `\"text2music\"` | Generation task type. See [Task Types](#task-types) section for details. |\n| `instruction` | `str` | `\"Fill the audio semantic mask based on the given conditions:\"` | Task-specific instruction prompt. |\n| `reference_audio` | `Optional[str]` | `None` | Path to reference audio file for style transfer or continuation tasks. |\n| `src_audio` | `Optional[str]` | `None` | Path to source audio file for audio-to-audio tasks (cover, repaint, etc.). |\n| `audio_codes` | `str` | `\"\"` | Pre-extracted 5Hz audio semantic codes as a string. Advanced use only. |\n| `repainting_start` | `float` | `0.0` | Repainting start time in seconds (for repaint/lego tasks). |\n| `repainting_end` | `float` | `-1` | Repainting end time in seconds. Use `-1` for end of audio. |\n| `audio_cover_strength` | `float` | `1.0` | Strength of audio cover/codes influence (0.0-1.0). Set smaller (0.2) for style transfer tasks. |\n\n### 5Hz Language Model Parameters\n\n| Parameter | Type | Default | Description |\n|-----------|------|---------|-------------|\n| `thinking` | `bool` | `True` | Enable 5Hz Language Model \"Chain-of-Thought\" reasoning for semantic/music metadata and codes. |\n| `lm_temperature` | `float` | `0.85` | LM sampling temperature (0.0-2.0). Higher = more creative/diverse, lower = more conservative. |\n| `lm_cfg_scale` | `float` | `2.0` | LM classifier-free guidance scale. Higher = stronger adherence to prompt. |\n| `lm_top_k` | `int` | `0` | LM top-k sampling. `0` disables top-k filtering. Typical values: 40-100. |\n| `lm_top_p` | `float` | `0.9` | LM nucleus sampling (0.0-1.0). `1.0` disables nucleus sampling. Typical values: 0.9-0.95. |\n| `lm_negative_prompt` | `str` | `\"NO USER INPUT\"` | Negative prompt for LM guidance. Helps avoid unwanted characteristics. |\n| `use_cot_metas` | `bool` | `True` | Generate metadata using LM CoT reasoning (BPM, key, duration, etc.). |\n| `use_cot_caption` | `bool` | `True` | Refine user caption using LM CoT reasoning. |\n| `use_cot_language` | `bool` | `True` | Detect vocal language using LM CoT reasoning. |\n| `use_cot_lyrics` | `bool` | `False` | (Reserved for future use) Generate/refine lyrics using LM CoT. |\n| `use_constrained_decoding` | `bool` | `True` | Enable constrained decoding for structured LM output. |\n\n### CoT Generated Values\n\nThese fields are automatically populated by the LM when CoT reasoning is enabled:\n\n| Parameter | Type | Default | Description |\n|-----------|------|---------|-------------|\n| `cot_bpm` | `Optional[int]` | `None` | LM-generated BPM value. |\n| `cot_keyscale` | `str` | `\"\"` | LM-generated key/scale. |\n| `cot_timesignature` | `str` | `\"\"` | LM-generated time signature. |\n| `cot_duration` | `Optional[float]` | `None` | LM-generated duration. |\n| `cot_vocal_language` | `str` | `\"unknown\"` | LM-detected vocal language. |\n| `cot_caption` | `str` | `\"\"` | LM-refined caption. |\n| `cot_lyrics` | `str` | `\"\"` | LM-generated/refined lyrics. |\n\n---\n\n## GenerationConfig Parameters\n\n| Parameter | Type | Default | Description |\n|-----------|------|---------|-------------|\n| `batch_size` | `int` | `2` | Number of samples to generate in parallel (1-8). Higher values require more GPU memory. |\n| `allow_lm_batch` | `bool` | `False` | Allow batch processing in LM. Faster when `batch_size >= 2` and `thinking=True`. |\n| `use_random_seed` | `bool` | `True` | Whether to use random seed. `True` for different results each time, `False` for reproducible results. |\n| `seeds` | `Optional[List[int]]` | `None` | List of seeds for batch generation. If provided, will be padded with random seeds if fewer than batch_size. Can also be single int. |\n| `lm_batch_chunk_size` | `int` | `8` | Maximum batch size per LM inference chunk (GPU memory constraint). |\n| `constrained_decoding_debug` | `bool` | `False` | Enable debug logging for constrained decoding. |\n| `audio_format` | `str` | `\"flac\"` | Output audio format. Options: `\"mp3\"`, `\"wav\"`, `\"flac\"`. Default is FLAC for fast saving. |\n\n---\n\n## Task Types\n\nACE-Step supports 6 different generation task types, each optimized for specific use cases.\n\n### 1. Text2Music (Default)\n\n**Purpose**: Generate music from text descriptions and optional metadata.\n\n**Key Parameters**:\n```python\nparams = GenerationParams(\n    task_type=\"text2music\",\n    caption=\"energetic rock music with electric guitar\",\n    lyrics=\"[Instrumental]\",  # or actual lyrics\n    bpm=140,\n    duration=30,\n)\n```\n\n**Required**:\n- `caption` or `lyrics` (at least one)\n\n**Optional but Recommended**:\n- `bpm`: Controls tempo\n- `keyscale`: Controls musical key\n- `timesignature`: Controls rhythm structure\n- `duration`: Controls length\n- `vocal_language`: Controls vocal characteristics\n\n**Use Cases**:\n- Generate music from text descriptions\n- Create backing tracks from prompts\n- Generate songs with lyrics\n\n---\n\n### 2. Cover\n\n**Purpose**: Transform existing audio while maintaining structure but changing style/timbre.\n\n**Key Parameters**:\n```python\nparams = GenerationParams(\n    task_type=\"cover\",\n    src_audio=\"original_song.mp3\",\n    caption=\"jazz piano version\",\n    audio_cover_strength=0.8,  # 0.0-1.0\n)\n```\n\n**Required**:\n- `src_audio`: Path to source audio file\n- `caption`: Description of desired style/transformation\n\n**Optional**:\n- `audio_cover_strength`: Controls influence of original audio\n  - `1.0`: Strong adherence to original structure\n  - `0.5`: Balanced transformation\n  - `0.1`: Loose interpretation\n- `lyrics`: New lyrics (if changing vocals)\n\n**Use Cases**:\n- Create covers in different styles\n- Change instrumentation while keeping melody\n- Genre transformation\n\n---\n\n### 3. Repaint\n\n**Purpose**: Regenerate a specific time segment of audio while keeping the rest unchanged.\n\n**Key Parameters**:\n```python\nparams = GenerationParams(\n    task_type=\"repaint\",\n    src_audio=\"original.mp3\",\n    repainting_start=10.0,  # seconds\n    repainting_end=20.0,    # seconds\n    caption=\"smooth transition with piano solo\",\n)\n```\n\n**Required**:\n- `src_audio`: Path to source audio file\n- `repainting_start`: Start time in seconds\n- `repainting_end`: End time in seconds (use `-1` for end of file)\n- `caption`: Description of desired content for repainted section\n\n**Use Cases**:\n- Fix specific sections of generated music\n- Add variations to parts of a song\n- Create smooth transitions\n- Replace problematic segments\n\n---\n\n### 4. Lego (Base Model Only)\n\n**Purpose**: Generate a specific instrument track in context of existing audio.\n\n**Key Parameters**:\n```python\nparams = GenerationParams(\n    task_type=\"lego\",\n    src_audio=\"backing_track.mp3\",\n    instruction=\"Generate the guitar track based on the audio context:\",\n    caption=\"lead guitar melody with bluesy feel\",\n    repainting_start=0.0,\n    repainting_end=-1,\n)\n```\n\n**Required**:\n- `src_audio`: Path to source/backing audio\n- `instruction`: Must specify the track type (e.g., \"Generate the {TRACK_NAME} track...\")\n- `caption`: Description of desired track characteristics\n\n**Available Tracks**:\n- `\"vocals\"`, `\"backing_vocals\"`, `\"drums\"`, `\"bass\"`, `\"guitar\"`, `\"keyboard\"`, \n- `\"percussion\"`, `\"strings\"`, `\"synth\"`, `\"fx\"`, `\"brass\"`, `\"woodwinds\"`\n\n**Use Cases**:\n- Add specific instrument tracks\n- Layer additional instruments over backing tracks\n- Create multi-track compositions iteratively\n\n---\n\n### 5. Extract (Base Model Only)\n\n**Purpose**: Extract/isolate a specific instrument track from mixed audio.\n\n**Key Parameters**:\n```python\nparams = GenerationParams(\n    task_type=\"extract\",\n    src_audio=\"full_mix.mp3\",\n    instruction=\"Extract the vocals track from the audio:\",\n)\n```\n\n**Required**:\n- `src_audio`: Path to mixed audio file\n- `instruction`: Must specify track to extract\n\n**Available Tracks**: Same as Lego task\n\n**Use Cases**:\n- Stem separation\n- Isolate specific instruments\n- Create remixes\n- Analyze individual tracks\n\n---\n\n### 6. Complete (Base Model Only)\n\n**Purpose**: Complete/extend partial tracks with specified instruments.\n\n**Key Parameters**:\n```python\nparams = GenerationParams(\n    task_type=\"complete\",\n    src_audio=\"incomplete_track.mp3\",\n    instruction=\"Complete the input track with drums, bass, guitar:\",\n    caption=\"rock style completion\",\n)\n```\n\n**Required**:\n- `src_audio`: Path to incomplete/partial track\n- `instruction`: Must specify which tracks to add\n- `caption`: Description of desired style\n\n**Use Cases**:\n- Arrange incomplete compositions\n- Add backing tracks\n- Auto-complete musical ideas\n\n---\n\n## Helper Functions\n\n### understand_music\n\nAnalyze audio codes to extract metadata about the music.\n\n```python\nfrom acestep.inference import understand_music\n\nresult = understand_music(\n    llm_handler=llm_handler,\n    audio_codes=\"<|audio_code_123|><|audio_code_456|>...\",\n    temperature=0.85,\n    use_constrained_decoding=True,\n)\n\nif result.success:\n    print(f\"Caption: {result.caption}\")\n    print(f\"Lyrics: {result.lyrics}\")\n    print(f\"BPM: {result.bpm}\")\n    print(f\"Key: {result.keyscale}\")\n    print(f\"Duration: {result.duration}s\")\n    print(f\"Language: {result.language}\")\nelse:\n    print(f\"Error: {result.error}\")\n```\n\n**Use Cases**:\n- Analyze existing music\n- Extract metadata from audio codes\n- Reverse-engineer generation parameters\n\n---\n\n### create_sample\n\nGenerate a complete music sample from a natural language description. This is the \"Simple Mode\" / \"Inspiration Mode\" feature.\n\n```python\nfrom acestep.inference import create_sample\n\nresult = create_sample(\n    llm_handler=llm_handler,\n    query=\"a soft Bengali love song for a quiet evening\",\n    instrumental=False,\n    vocal_language=\"bn\",  # Optional: constrain to Bengali\n    temperature=0.85,\n)\n\nif result.success:\n    print(f\"Caption: {result.caption}\")\n    print(f\"Lyrics: {result.lyrics}\")\n    print(f\"BPM: {result.bpm}\")\n    print(f\"Duration: {result.duration}s\")\n    print(f\"Key: {result.keyscale}\")\n    print(f\"Is Instrumental: {result.instrumental}\")\n    \n    # Use with generate_music\n    params = GenerationParams(\n        caption=result.caption,\n        lyrics=result.lyrics,\n        bpm=result.bpm,\n        duration=result.duration,\n        keyscale=result.keyscale,\n        vocal_language=result.language,\n    )\nelse:\n    print(f\"Error: {result.error}\")\n```\n\n**Parameters**:\n\n| Parameter | Type | Default | Description |\n|-----------|------|---------|-------------|\n| `query` | `str` | required | Natural language description of desired music |\n| `instrumental` | `bool` | `False` | Whether to generate instrumental music |\n| `vocal_language` | `Optional[str]` | `None` | Constrain lyrics to specific language (e.g., \"en\", \"zh\", \"bn\") |\n| `temperature` | `float` | `0.85` | Sampling temperature |\n| `top_k` | `Optional[int]` | `None` | Top-k sampling (None disables) |\n| `top_p` | `Optional[float]` | `None` | Top-p sampling (None disables) |\n| `repetition_penalty` | `float` | `1.0` | Repetition penalty |\n| `use_constrained_decoding` | `bool` | `True` | Use FSM-based constrained decoding |\n\n---\n\n### format_sample\n\nFormat and enhance user-provided caption and lyrics, generating structured metadata.\n\n```python\nfrom acestep.inference import format_sample\n\nresult = format_sample(\n    llm_handler=llm_handler,\n    caption=\"Latin pop, reggaeton\",\n    lyrics=\"[Verse 1]\\nBailando en la noche...\",\n    user_metadata={\"bpm\": 95},  # Optional: constrain specific values\n    temperature=0.85,\n)\n\nif result.success:\n    print(f\"Enhanced Caption: {result.caption}\")\n    print(f\"Formatted Lyrics: {result.lyrics}\")\n    print(f\"BPM: {result.bpm}\")\n    print(f\"Duration: {result.duration}s\")\n    print(f\"Key: {result.keyscale}\")\n    print(f\"Detected Language: {result.language}\")\nelse:\n    print(f\"Error: {result.error}\")\n```\n\n**Parameters**:\n\n| Parameter | Type | Default | Description |\n|-----------|------|---------|-------------|\n| `caption` | `str` | required | User's caption/description |\n| `lyrics` | `str` | required | User's lyrics with structure tags |\n| `user_metadata` | `Optional[Dict]` | `None` | Constrain specific metadata values (bpm, duration, keyscale, timesignature, language) |\n| `temperature` | `float` | `0.85` | Sampling temperature |\n| `top_k` | `Optional[int]` | `None` | Top-k sampling (None disables) |\n| `top_p` | `Optional[float]` | `None` | Top-p sampling (None disables) |\n| `repetition_penalty` | `float` | `1.0` | Repetition penalty |\n| `use_constrained_decoding` | `bool` | `True` | Use FSM-based constrained decoding |\n\n---\n\n## Complete Examples\n\n### Example 1: Simple Text-to-Music Generation\n\n```python\nfrom acestep.inference import GenerationParams, GenerationConfig, generate_music\n\nparams = GenerationParams(\n    task_type=\"text2music\",\n    caption=\"calm ambient music with soft piano and strings\",\n    duration=60,\n    bpm=80,\n    keyscale=\"C Major\",\n)\n\nconfig = GenerationConfig(\n    batch_size=2,  # Generate 2 variations\n    audio_format=\"flac\",\n)\n\nresult = generate_music(dit_handler, llm_handler, params, config, save_dir=\"/output\")\n\nif result.success:\n    for i, audio in enumerate(result.audios, 1):\n        print(f\"Variation {i}: {audio['path']}\")\n```\n\n### Example 2: Song Generation with Lyrics\n\n```python\nparams = GenerationParams(\n    task_type=\"text2music\",\n    caption=\"pop ballad with emotional vocals\",\n    lyrics=\"\"\"Verse 1:\nWalking down the street today\nThinking of the words you used to say\nEverything feels different now\nBut I'll find my way somehow\n\nChorus:\nI'm moving on, I'm staying strong\nThis is where I belong\n\"\"\",\n    vocal_language=\"en\",\n    bpm=72,\n    duration=45,\n)\n\nconfig = GenerationConfig(batch_size=1)\n\nresult = generate_music(dit_handler, llm_handler, params, config, save_dir=\"/output\")\n```\n\n### Example 3: Using Custom Timesteps\n\n```python\nparams = GenerationParams(\n    task_type=\"text2music\",\n    caption=\"jazz fusion with complex harmonies\",\n    # Custom 9-step schedule\n    timesteps=[0.97, 0.76, 0.615, 0.5, 0.395, 0.28, 0.18, 0.085, 0],\n    thinking=True,\n)\n\nconfig = GenerationConfig(batch_size=1)\n\nresult = generate_music(dit_handler, llm_handler, params, config, save_dir=\"/output\")\n```\n\n### Example 4: Using Shift Parameter (Turbo Model)\n\n```python\nparams = GenerationParams(\n    task_type=\"text2music\",\n    caption=\"upbeat electronic dance music\",\n    inference_steps=8,\n    shift=3.0,  # Recommended for turbo models\n    infer_method=\"ode\",\n)\n\nconfig = GenerationConfig(batch_size=2)\n\nresult = generate_music(dit_handler, llm_handler, params, config, save_dir=\"/output\")\n```\n\n### Example 5: Simple Mode with create_sample\n\n```python\nfrom acestep.inference import create_sample, GenerationParams, GenerationConfig, generate_music\n\n# Step 1: Create sample from description\nsample = create_sample(\n    llm_handler=llm_handler,\n    query=\"energetic K-pop dance track with catchy hooks\",\n    vocal_language=\"ko\",\n)\n\nif sample.success:\n    # Step 2: Generate music using the sample\n    params = GenerationParams(\n        caption=sample.caption,\n        lyrics=sample.lyrics,\n        bpm=sample.bpm,\n        duration=sample.duration,\n        keyscale=sample.keyscale,\n        vocal_language=sample.language,\n        thinking=True,\n    )\n    \n    config = GenerationConfig(batch_size=2)\n    result = generate_music(dit_handler, llm_handler, params, config, save_dir=\"/output\")\n```\n\n### Example 6: Format and Enhance User Input\n\n```python\nfrom acestep.inference import format_sample, GenerationParams, GenerationConfig, generate_music\n\n# Step 1: Format user input\nformatted = format_sample(\n    llm_handler=llm_handler,\n    caption=\"rock ballad\",\n    lyrics=\"[Verse]\\nIn the darkness I find my way...\",\n)\n\nif formatted.success:\n    # Step 2: Generate with enhanced input\n    params = GenerationParams(\n        caption=formatted.caption,\n        lyrics=formatted.lyrics,\n        bpm=formatted.bpm,\n        duration=formatted.duration,\n        keyscale=formatted.keyscale,\n        thinking=True,\n        use_cot_metas=False,  # Already formatted, skip metas CoT\n    )\n    \n    config = GenerationConfig(batch_size=2)\n    result = generate_music(dit_handler, llm_handler, params, config, save_dir=\"/output\")\n```\n\n### Example 7: Style Cover with LM Reasoning\n\n```python\nparams = GenerationParams(\n    task_type=\"cover\",\n    src_audio=\"original_pop_song.mp3\",\n    caption=\"orchestral symphonic arrangement\",\n    audio_cover_strength=0.7,\n    thinking=True,  # Enable LM for metadata\n    use_cot_metas=True,\n)\n\nconfig = GenerationConfig(batch_size=1)\n\nresult = generate_music(dit_handler, llm_handler, params, config, save_dir=\"/output\")\n\n# Access LM-generated metadata\nif result.extra_outputs.get(\"lm_metadata\"):\n    lm_meta = result.extra_outputs[\"lm_metadata\"]\n    print(f\"LM detected BPM: {lm_meta.get('bpm')}\")\n    print(f\"LM detected Key: {lm_meta.get('keyscale')}\")\n```\n\n### Example 8: Batch Generation with Specific Seeds\n\n```python\nparams = GenerationParams(\n    task_type=\"text2music\",\n    caption=\"epic cinematic trailer music\",\n)\n\nconfig = GenerationConfig(\n    batch_size=4,           # Generate 4 variations\n    seeds=[42, 123, 456],   # Specify 3 seeds, 4th will be random\n    use_random_seed=False,  # Use provided seeds\n    lm_batch_chunk_size=2,  # Process 2 at a time (GPU memory)\n)\n\nresult = generate_music(dit_handler, llm_handler, params, config, save_dir=\"/output\")\n\nif result.success:\n    print(f\"Generated {len(result.audios)} variations\")\n    for audio in result.audios:\n        print(f\"  Seed {audio['params']['seed']}: {audio['path']}\")\n```\n\n### Example 9: High-Quality Generation (Base Model)\n\n```python\nparams = GenerationParams(\n    task_type=\"text2music\",\n    caption=\"intricate jazz fusion with complex harmonies\",\n    inference_steps=64,     # High quality\n    guidance_scale=8.0,\n    use_adg=True,           # Adaptive Dual Guidance\n    cfg_interval_start=0.0,\n    cfg_interval_end=1.0,\n    shift=3.0,              # Timestep shift\n    seed=42,                # Reproducible results\n)\n\nconfig = GenerationConfig(\n    batch_size=1,\n    use_random_seed=False,\n    audio_format=\"wav\",     # Lossless format\n)\n\nresult = generate_music(dit_handler, llm_handler, params, config, save_dir=\"/output\")\n```\n\n### Example 10: Understand Audio from Codes\n\n```python\nfrom acestep.inference import understand_music\n\n# Analyze audio codes (e.g., from a previous generation)\nresult = understand_music(\n    llm_handler=llm_handler,\n    audio_codes=\"<|audio_code_10695|><|audio_code_54246|>...\",\n    temperature=0.85,\n)\n\nif result.success:\n    print(f\"Detected Caption: {result.caption}\")\n    print(f\"Detected Lyrics: {result.lyrics}\")\n    print(f\"Detected BPM: {result.bpm}\")\n    print(f\"Detected Key: {result.keyscale}\")\n    print(f\"Detected Duration: {result.duration}s\")\n    print(f\"Detected Language: {result.language}\")\n```\n\n---\n\n## Best Practices\n\n### 1. Caption Writing\n\n**Good Captions**:\n```python\n# Specific and descriptive\ncaption=\"upbeat electronic dance music with heavy bass and synthesizer leads\"\n\n# Include mood and genre\ncaption=\"melancholic indie folk with acoustic guitar and soft vocals\"\n\n# Specify instruments\ncaption=\"jazz trio with piano, upright bass, and brush drums\"\n```\n\n**Avoid**:\n```python\n# Too vague\ncaption=\"good music\"\n\n# Contradictory\ncaption=\"fast slow music\"  # Conflicting tempos\n```\n\n### 2. Parameter Tuning\n\n**For Best Quality**:\n- Use base model with `inference_steps=64` or higher\n- Enable `use_adg=True`\n- Set `guidance_scale=7.0-9.0`\n- Set `shift=3.0` for better timestep distribution\n- Use lossless audio format (`audio_format=\"wav\"`)\n\n**For Speed**:\n- Use turbo model with `inference_steps=8`\n- Disable ADG (`use_adg=False`)\n- Use `infer_method=\"ode\"` (default)\n- Use compressed format (`audio_format=\"mp3\"`) or default FLAC\n\n**For Consistency**:\n- Set `use_random_seed=False` in config\n- Use fixed `seeds` list or single `seed` in params\n- Keep `lm_temperature` lower (0.7-0.85)\n\n**For Diversity**:\n- Set `use_random_seed=True` in config\n- Increase `lm_temperature` (0.9-1.1)\n- Use `batch_size > 1` for variations\n\n### 3. Duration Guidelines\n\n- **Instrumental**: 30-180 seconds works well\n- **With Lyrics**: Auto-detection recommended (set `duration=-1` or leave default)\n- **Short clips**: 10-20 seconds minimum\n- **Long form**: Up to 600 seconds (10 minutes) maximum\n\n### 4. LM Usage\n\n**When to Enable LM (`thinking=True`)**:\n- Need automatic metadata detection\n- Want caption refinement\n- Generating from minimal input\n- Need diverse outputs\n\n**When to Disable LM (`thinking=False`)**:\n- Have precise metadata already\n- Need faster generation\n- Want full control over parameters\n\n### 5. Batch Processing\n\n```python\n# Efficient batch generation\nconfig = GenerationConfig(\n    batch_size=8,           # Max supported\n    allow_lm_batch=True,    # Enable for speed (when thinking=True)\n    lm_batch_chunk_size=4,  # Adjust based on GPU memory\n)\n```\n\n### 6. Error Handling\n\n```python\nresult = generate_music(dit_handler, llm_handler, params, config, save_dir=\"/output\")\n\nif not result.success:\n    print(f\"Generation failed: {result.error}\")\n    print(f\"Status: {result.status_message}\")\nelse:\n    # Process successful result\n    for audio in result.audios:\n        path = audio['path']\n        key = audio['key']\n        seed = audio['params']['seed']\n        # ... process audio files\n```\n\n### 7. Memory Management\n\nFor large batch sizes or long durations:\n- Monitor GPU memory usage\n- Reduce `batch_size` if OOM errors occur\n- Reduce `lm_batch_chunk_size` for LM operations\n- Consider using `offload_to_cpu=True` during initialization\n\n### 8. Accessing Time Costs\n\n```python\nresult = generate_music(dit_handler, llm_handler, params, config, save_dir=\"/output\")\n\nif result.success:\n    time_costs = result.extra_outputs.get(\"time_costs\", {})\n    print(f\"LM Phase 1 Time: {time_costs.get('lm_phase1_time', 0):.2f}s\")\n    print(f\"LM Phase 2 Time: {time_costs.get('lm_phase2_time', 0):.2f}s\")\n    print(f\"DiT Total Time: {time_costs.get('dit_total_time_cost', 0):.2f}s\")\n    print(f\"Pipeline Total: {time_costs.get('pipeline_total_time', 0):.2f}s\")\n```\n\n---\n\n## Troubleshooting\n\n### Common Issues\n\n**Issue**: Out of memory errors\n- **Solution**: Reduce `batch_size`, `inference_steps`, or enable CPU offloading\n\n**Issue**: Poor quality results\n- **Solution**: Increase `inference_steps`, adjust `guidance_scale`, use base model\n\n**Issue**: Results don't match prompt\n- **Solution**: Make caption more specific, increase `guidance_scale`, enable LM refinement (`thinking=True`)\n\n**Issue**: Slow generation\n- **Solution**: Use turbo model, reduce `inference_steps`, disable ADG\n\n**Issue**: LM not generating codes\n- **Solution**: Verify `llm_handler` is initialized, check `thinking=True` and `use_cot_metas=True`\n\n**Issue**: Seeds not being respected\n- **Solution**: Set `use_random_seed=False` in config and provide `seeds` list or `seed` in params\n\n**Issue**: Custom timesteps not working\n- **Solution**: Ensure timesteps are a list of floats from 1.0 to 0.0, properly ordered\n\n---\n\n## API Reference Summary\n\n### GenerationParams Fields\n\nSee [GenerationParams Parameters](#generationparams-parameters) for complete documentation.\n\n### GenerationConfig Fields\n\nSee [GenerationConfig Parameters](#generationconfig-parameters) for complete documentation.\n\n### GenerationResult Fields\n\n```python\n@dataclass\nclass GenerationResult:\n    # Audio Outputs\n    audios: List[Dict[str, Any]]\n    # Each audio dict contains:\n    #   - \"path\": str (file path)\n    #   - \"tensor\": Tensor (audio data)\n    #   - \"key\": str (unique identifier)\n    #   - \"sample_rate\": int (48000)\n    #   - \"params\": Dict (generation params with seed, audio_codes, etc.)\n    \n    # Generation Information\n    status_message: str\n    extra_outputs: Dict[str, Any]\n    # extra_outputs contains:\n    #   - \"lm_metadata\": Dict (LM-generated metadata)\n    #   - \"time_costs\": Dict (timing information)\n    #   - \"latents\": Tensor (intermediate latents, if available)\n    #   - \"masks\": Tensor (attention masks, if available)\n    \n    # Success Status\n    success: bool\n    error: Optional[str]\n```\n\n---\n\n## Version History\n\n- **v1.5.2**: Current version\n  - Added `shift` parameter for timestep shifting\n  - Added `infer_method` parameter for ODE/SDE selection\n  - Added `timesteps` parameter for custom timestep schedules\n  - Added `understand_music()` function for audio analysis\n  - Added `create_sample()` function for simple mode generation\n  - Added `format_sample()` function for input enhancement\n  - Added `UnderstandResult`, `CreateSampleResult`, `FormatSampleResult` dataclasses\n\n- **v1.5.1**: Previous version\n  - Split `GenerationConfig` into `GenerationParams` and `GenerationConfig`\n  - Renamed parameters for consistency (`key_scale` → `keyscale`, `time_signature` → `timesignature`, `audio_duration` → `duration`, `use_llm_thinking` → `thinking`, `audio_code_string` → `audio_codes`)\n  - Added `instrumental` parameter\n  - Added `use_constrained_decoding` parameter\n  - Added CoT auto-filled fields (`cot_*`)\n  - Changed default `audio_format` to \"flac\"\n  - Changed default `batch_size` to 2\n  - Changed default `thinking` to True\n  - Simplified `GenerationResult` structure with unified `audios` list\n  - Added unified `time_costs` in `extra_outputs`\n\n- **v1.5**: Initial version\n  - Introduced `GenerationConfig` and `GenerationResult` dataclasses\n  - Simplified parameter passing\n  - Added comprehensive documentation\n\n---\n\nFor more information, see:\n- Main README: [`../../README.md`](../../README.md)\n- REST API Documentation: [`API.md`](API.md)\n- Gradio Demo Guide: [`GRADIO_GUIDE.md`](GRADIO_GUIDE.md)\n- Project repository: [ACE-Step-1.5](https://github.com/yourusername/ACE-Step-1.5)\n"
  },
  {
    "path": ".claude/skills/acestep-docs/guides/SCRIPT_CONFIGURATION.md",
    "content": "# Launch Script Configuration Guide\n\nThis guide explains how to configure the startup scripts for ACE-Step across all supported platforms: Windows (.bat), Linux (.sh), and macOS (.sh).\n\n> **Note for uv/Python users**: If you're using `uv run acestep` or running Python directly (not using launch scripts), configure settings via the `.env` file instead. See [ENVIRONMENT_SETUP.md](ENVIRONMENT_SETUP.md#environment-variables-env) for details.\n\n## How to Modify\n\nAll configurable options are variables at the top of each script. Open the script with any text editor and modify the values.\n\n**Windows (.bat)**:\n- Set a variable: `set VARIABLE=value`\n- Comment out a line: `REM set VARIABLE=value`\n- Uncomment a line: Remove the leading `REM`\n\n**Linux/macOS (.sh)**:\n- Set a variable: `VARIABLE=\"value\"`\n- Comment out a line: `# VARIABLE=\"value\"`\n- Uncomment a line: Remove the leading `#`\n\n---\n\n## Available Launch Scripts\n\n| Platform | Script | Purpose |\n|----------|--------|---------|\n| Windows (NVIDIA) | `start_gradio_ui.bat` | Gradio Web UI |\n| Windows (NVIDIA) | `start_api_server.bat` | REST API Server |\n| Windows (AMD ROCm) | `start_gradio_ui_rocm.bat` | Gradio Web UI for AMD GPUs |\n| Windows (AMD ROCm) | `start_api_server_rocm.bat` | REST API Server for AMD GPUs |\n| Linux (CUDA) | `start_gradio_ui.sh` | Gradio Web UI |\n| Linux (CUDA) | `start_api_server.sh` | REST API Server |\n| macOS (Apple Silicon) | `start_gradio_ui_macos.sh` | Gradio Web UI (MLX backend) |\n| macOS (Apple Silicon) | `start_api_server_macos.sh` | REST API Server (MLX backend) |\n\n---\n\n## Configuration Sections\n\n### 1. UI Language\n\nControls the language displayed in the Gradio Web UI.\n\n**Options**: `en` (English), `zh` (Chinese), `he` (Hebrew), `ja` (Japanese)\n\n**Windows (.bat)**:\n```batch\nREM UI language: en, zh, he, ja\nset LANGUAGE=en\n```\n\n**Linux/macOS (.sh)**:\n```bash\n# UI language: en, zh, he, ja\nLANGUAGE=\"en\"\n```\n\n**Example -- switch to Chinese**:\n\n| Platform | Setting |\n|----------|---------|\n| Windows | `set LANGUAGE=zh` |\n| Linux/macOS | `LANGUAGE=\"zh\"` |\n\n> **Note**: The `LANGUAGE` variable is only available in Gradio UI scripts. API server scripts do not have a UI language setting.\n\n---\n\n### 2. Server Port\n\nControls which port the server listens on and which address it binds to.\n\n**Gradio UI scripts**:\n\n| Platform | Default Port | Default Address |\n|----------|-------------|-----------------|\n| Windows | `7860` | `127.0.0.1` |\n| Linux | `7860` | `127.0.0.1` |\n| macOS | `7860` | `127.0.0.1` |\n\n**Windows (.bat)** -- Gradio UI:\n```batch\nREM Server settings\nset PORT=7860\nset SERVER_NAME=127.0.0.1\nREM set SERVER_NAME=0.0.0.0\nREM set SHARE=--share\n```\n\n**Linux/macOS (.sh)** -- Gradio UI:\n```bash\n# Server settings\nPORT=7860\nSERVER_NAME=\"127.0.0.1\"\n# SERVER_NAME=\"0.0.0.0\"\nSHARE=\"\"\n# SHARE=\"--share\"\n```\n\n**API Server scripts**:\n\n| Platform | Default Port | Default Host |\n|----------|-------------|--------------|\n| Windows | `8001` | `127.0.0.1` |\n| Linux | `8001` | `127.0.0.1` |\n| macOS | `8001` | `127.0.0.1` |\n\n**Windows (.bat)** -- API Server:\n```batch\nset HOST=127.0.0.1\nset PORT=8001\n```\n\n**Linux/macOS (.sh)** -- API Server:\n```bash\nHOST=\"127.0.0.1\"\nPORT=8001\n```\n\n**Default URLs**:\n- Gradio UI: http://127.0.0.1:7860\n- API Server: http://127.0.0.1:8001\n- API Documentation: http://127.0.0.1:8001/docs\n\n**To expose to the network** (allow access from other devices):\n- Set `SERVER_NAME` or `HOST` to `0.0.0.0`\n- Or enable `SHARE` for Gradio's public sharing link\n\n---\n\n### 3. Download Source\n\nControls where model files are downloaded from. Affects all scripts that download models.\n\n**Windows (.bat)**:\n```batch\nREM Download source: auto (default), huggingface, or modelscope\nREM set DOWNLOAD_SOURCE=--download-source modelscope\nREM set DOWNLOAD_SOURCE=--download-source huggingface\nset DOWNLOAD_SOURCE=\n```\n\n**Linux/macOS (.sh)**:\n```bash\n# Download source: auto (default), huggingface, or modelscope\nDOWNLOAD_SOURCE=\"\"\n# DOWNLOAD_SOURCE=\"--download-source modelscope\"\n# DOWNLOAD_SOURCE=\"--download-source huggingface\"\n```\n\n**Options**:\n\n| Value | When to Use | Speed |\n|-------|-------------|-------|\n| (empty) or `auto` | Auto-detect network | Automatic |\n| `modelscope` | China mainland users | Fast in China |\n| `huggingface` | Overseas users | Fast outside China |\n\n**How auto-detection works**:\n1. Tests Google connectivity\n   - Can access Google --> uses HuggingFace Hub\n   - Cannot access Google --> uses ModelScope\n2. If primary source fails, falls back to the alternate source\n\n**Examples**:\n\n| Platform | China Users | Overseas Users |\n|----------|-------------|----------------|\n| Windows | `set DOWNLOAD_SOURCE=--download-source modelscope` | `set DOWNLOAD_SOURCE=--download-source huggingface` |\n| Linux/macOS | `DOWNLOAD_SOURCE=\"--download-source modelscope\"` | `DOWNLOAD_SOURCE=\"--download-source huggingface\"` |\n\n---\n\n### 4. Update Check\n\nControls whether the script checks GitHub for updates before launching.\n\n**Default**: `true` (enabled)\n\n**Windows (.bat)**:\n```batch\nREM Update check on startup (set to false to disable)\nset CHECK_UPDATE=true\nREM set CHECK_UPDATE=false\n```\n\n**Linux/macOS (.sh)**:\n```bash\n# Update check on startup (set to \"false\" to disable)\nCHECK_UPDATE=\"true\"\n# CHECK_UPDATE=\"false\"\n```\n\n**Git detection by platform**:\n\n| Platform | Git Resolution |\n|----------|---------------|\n| Windows | Tries `PortableGit\\bin\\git.exe` first, then falls back to system `git` (e.g., Git for Windows) |\n| Linux | Uses system `git` |\n| macOS | Uses system `git` (Xcode Command Line Tools or Homebrew) |\n\n> **Important**: On Windows, PortableGit is no longer strictly required. If you have Git for Windows installed system-wide, the update check will find it automatically.\n\n**Behavior when enabled**:\n1. Fetches latest commits from GitHub with a 10 second timeout\n2. Compares local commit hash against remote\n3. If an update is available, shows new commits and prompts `Y/N`\n4. If the network is unreachable or the fetch times out, automatically skips and continues startup\n\n**Timeout handling by platform**:\n- Linux: Uses `timeout` command (10 seconds)\n- macOS: Uses `gtimeout` (from coreutils) or `timeout` if available, otherwise runs without timeout\n- Windows: Network-level timeout via `git fetch`\n\nSee [UPDATE_AND_BACKUP.md](UPDATE_AND_BACKUP.md) for full details on the update process and file backup.\n\n---\n\n### 5. Model Configuration\n\nControls which DiT model and Language Model (LM) are loaded.\n\n**Windows (.bat)** -- Gradio UI:\n```batch\nREM Model settings\nset CONFIG_PATH=--config_path acestep-v15-turbo\nset LM_MODEL_PATH=--lm_model_path acestep-5Hz-lm-0.6B\nREM set OFFLOAD_TO_CPU=--offload_to_cpu true\n```\n\n**Linux/macOS (.sh)** -- Gradio UI:\n```bash\n# Model settings\nCONFIG_PATH=\"--config_path acestep-v15-turbo\"\nLM_MODEL_PATH=\"--lm_model_path acestep-5Hz-lm-0.6B\"\n# OFFLOAD_TO_CPU=\"--offload_to_cpu true\"\nOFFLOAD_TO_CPU=\"\"\n```\n\n**API Server** -- Windows (.bat):\n```batch\nREM LM model path (optional, only used when LLM is enabled)\nREM set LM_MODEL_PATH=--lm-model-path acestep-5Hz-lm-0.6B\n```\n\n**API Server** -- Linux/macOS (.sh):\n```bash\n# LM model path (optional, only used when LLM is enabled)\nLM_MODEL_PATH=\"\"\n# LM_MODEL_PATH=\"--lm-model-path acestep-5Hz-lm-0.6B\"\n```\n\n> **Note**: The API server uses `--lm-model-path` (hyphens) while the Gradio UI uses `--lm_model_path` (underscores).\n\n**Available DiT Models**:\n\n| Model | Description |\n|-------|-------------|\n| `acestep-v15-turbo` | Default turbo model (8 steps, no CFG) |\n| `acestep-v15-base` | Base model (50 steps, with CFG, high diversity) |\n| `acestep-v15-sft` | SFT model (50 steps, with CFG, high quality) |\n| `acestep-v15-turbo-shift1` | Turbo with shift1 |\n| `acestep-v15-turbo-shift3` | Turbo with shift3 |\n| `acestep-v15-turbo-continuous` | Turbo with continuous shift (1-5) |\n\n**Available Language Models**:\n\n| LM Model | Size | Quality |\n|----------|------|---------|\n| `acestep-5Hz-lm-0.6B` | 0.6B | Standard |\n| `acestep-5Hz-lm-1.7B` | 1.7B | Better |\n| `acestep-5Hz-lm-4B` | 4B | Best (requires more VRAM/RAM) |\n\n**CPU Offload**: Enable `OFFLOAD_TO_CPU` when using larger models (especially 4B) on GPUs with limited VRAM. Models shuttle between CPU and GPU as needed, adding ~8-10s overhead per generation but preventing VRAM oversubscription.\n\n---\n\n### 6. LLM Initialization Control\n\nControls whether the Language Model (5Hz LM) is initialized at startup. By default, LLM is automatically enabled or disabled based on GPU VRAM:\n- **<=6GB VRAM**: LLM disabled (DiT-only mode)\n- **>6GB VRAM**: LLM enabled\n\n**Processing Flow:**\n```\nGPU Detection (full) --> ACESTEP_INIT_LLM / INIT_LLM Override --> Model Loading\n```\n\nGPU optimizations (offload, quantization, batch limits) are **always applied** regardless of this setting. The override only controls whether to attempt LLM loading.\n\n**Gradio UI** -- Windows (.bat):\n```batch\nREM LLM initialization: auto (default), true, false\nREM set INIT_LLM=--init_llm auto\nREM set INIT_LLM=--init_llm true\nREM set INIT_LLM=--init_llm false\n```\n\n**Gradio UI** -- Linux/macOS (.sh):\n```bash\n# LLM initialization: auto (default), true, false\nINIT_LLM=\"\"\n# INIT_LLM=\"--init_llm auto\"\n# INIT_LLM=\"--init_llm true\"\n# INIT_LLM=\"--init_llm false\"\n```\n\n**API Server** -- Windows (.bat):\n```batch\nREM Values: auto (default), true (force enable), false (force disable)\nREM set ACESTEP_INIT_LLM=auto\nREM set ACESTEP_INIT_LLM=true\nREM set ACESTEP_INIT_LLM=false\n```\n\n**API Server** -- Linux/macOS (.sh):\n```bash\n# Values: auto (default), true (force enable), false (force disable)\n# export ACESTEP_INIT_LLM=auto\n# export ACESTEP_INIT_LLM=true\n# export ACESTEP_INIT_LLM=false\n```\n\n> **Note**: Gradio UI scripts use `--init_llm` as a command-line argument. API server scripts use the `ACESTEP_INIT_LLM` environment variable.\n\n**When to use**:\n\n| Setting | Use Case |\n|---------|----------|\n| `auto` (default) | Let GPU detection decide (recommended) |\n| `true` | Force LLM on low VRAM GPU (GPU optimizations still applied, may cause OOM) |\n| `false` | Pure DiT mode for faster generation, no LLM features |\n\n**Features affected by LLM**:\n- **Thinking mode**: LLM generates audio codes for better quality\n- **Chain-of-Thought (CoT)**: Auto-enhance captions, detect language, generate metadata\n- **Sample mode**: Generate random songs from descriptions\n- **Format mode**: Enhance user input via LLM\n\nWhen LLM is disabled, these features are automatically disabled, and generation uses pure DiT mode.\n\n---\n\n## Complete Configuration Examples\n\n### Chinese Users\n\n**Windows (.bat)** -- `start_gradio_ui.bat`:\n```batch\nREM UI language\nset LANGUAGE=zh\n\nREM Server port\nset PORT=7860\nset SERVER_NAME=127.0.0.1\n\nREM Download source\nset DOWNLOAD_SOURCE=--download-source modelscope\n\nREM Update check\nset CHECK_UPDATE=true\n\nREM Model settings\nset CONFIG_PATH=--config_path acestep-v15-turbo\nset LM_MODEL_PATH=--lm_model_path acestep-5Hz-lm-0.6B\n```\n\n**Linux (.sh)** -- `start_gradio_ui.sh`:\n```bash\n# UI language\nLANGUAGE=\"zh\"\n\n# Server port\nPORT=7860\nSERVER_NAME=\"127.0.0.1\"\n\n# Download source\nDOWNLOAD_SOURCE=\"--download-source modelscope\"\n\n# Update check\nCHECK_UPDATE=\"true\"\n\n# Model settings\nCONFIG_PATH=\"--config_path acestep-v15-turbo\"\nLM_MODEL_PATH=\"--lm_model_path acestep-5Hz-lm-0.6B\"\n```\n\n---\n\n### Overseas Users\n\n**Windows (.bat)** -- `start_gradio_ui.bat`:\n```batch\nREM UI language\nset LANGUAGE=en\n\nREM Server port\nset PORT=7860\nset SERVER_NAME=127.0.0.1\n\nREM Download source\nset DOWNLOAD_SOURCE=--download-source huggingface\n\nREM Update check\nset CHECK_UPDATE=true\n\nREM Model settings\nset CONFIG_PATH=--config_path acestep-v15-turbo\nset LM_MODEL_PATH=--lm_model_path acestep-5Hz-lm-1.7B\n```\n\n**Linux (.sh)** -- `start_gradio_ui.sh`:\n```bash\n# UI language\nLANGUAGE=\"en\"\n\n# Server port\nPORT=7860\nSERVER_NAME=\"127.0.0.1\"\n\n# Download source\nDOWNLOAD_SOURCE=\"--download-source huggingface\"\n\n# Update check\nCHECK_UPDATE=\"true\"\n\n# Model settings\nCONFIG_PATH=\"--config_path acestep-v15-turbo\"\nLM_MODEL_PATH=\"--lm_model_path acestep-5Hz-lm-1.7B\"\n```\n\n---\n\n### macOS Users (Apple Silicon / MLX)\n\n**`start_gradio_ui_macos.sh`**:\n```bash\n# MLX backend is set automatically by the script:\n# export ACESTEP_LM_BACKEND=\"mlx\"\n\n# UI language\nLANGUAGE=\"en\"\n\n# Server port\nPORT=7860\nSERVER_NAME=\"127.0.0.1\"\n\n# Download source (HuggingFace recommended outside China)\nDOWNLOAD_SOURCE=\"--download-source huggingface\"\n\n# Update check\nCHECK_UPDATE=\"true\"\n\n# Model settings\nCONFIG_PATH=\"--config_path acestep-v15-turbo\"\nLM_MODEL_PATH=\"--lm_model_path acestep-5Hz-lm-0.6B\"\n\n# MLX backend (set automatically, do not change)\nBACKEND=\"--backend mlx\"\n\n# CPU offload (enable for models larger than 0.6B on limited memory)\nOFFLOAD_TO_CPU=\"\"\n# OFFLOAD_TO_CPU=\"--offload_to_cpu true\"\n```\n\n> **Note**: The macOS scripts automatically detect Apple Silicon (arm64). On Intel Macs, the MLX backend is unavailable and the script falls back to the PyTorch backend.\n\n---\n\n## ROCm Configuration\n\nThe `start_gradio_ui_rocm.bat` and `start_api_server_rocm.bat` scripts include additional settings specific to AMD GPUs running ROCm on Windows.\n\n### ROCm-Specific Variables\n\n```batch\nREM ==================== ROCm Configuration ====================\nREM Force PyTorch LM backend (bypasses nano-vllm flash_attn dependency)\nset ACESTEP_LM_BACKEND=pt\n\nREM RDNA3 GPU architecture override\nset HSA_OVERRIDE_GFX_VERSION=11.0.0\n\nREM Disable torch.compile Triton backend (not available on ROCm Windows)\nset TORCH_COMPILE_BACKEND=eager\n\nREM MIOpen: fast heuristic kernel selection instead of exhaustive benchmarking\nset MIOPEN_FIND_MODE=FAST\n\nREM HuggingFace tokenizer parallelism\nset TOKENIZERS_PARALLELISM=false\n```\n\n**Variable details**:\n\n| Variable | Purpose | Common Values |\n|----------|---------|---------------|\n| `ACESTEP_LM_BACKEND` | Forces PyTorch backend instead of vLLM | `pt` (required for ROCm) |\n| `HSA_OVERRIDE_GFX_VERSION` | Overrides GPU architecture for ROCm compatibility | `11.0.0` (gfx1100, RX 7900 XT/XTX), `11.0.1` (gfx1101, RX 7700/7800 XT), `11.0.2` (gfx1102, RX 7600) |\n| `TORCH_COMPILE_BACKEND` | Sets the torch.compile backend | `eager` (required, Triton unavailable on ROCm Windows) |\n| `MIOPEN_FIND_MODE` | Controls MIOpen kernel selection strategy | `FAST` (recommended; prevents first-run hangs on VAE decode) |\n| `TOKENIZERS_PARALLELISM` | Controls HuggingFace tokenizer parallelism | `false` (suppresses warnings) |\n\n**ROCm model settings**:\n\n```batch\nREM Model settings (ROCm)\nset CONFIG_PATH=--config_path acestep-v15-turbo\nset LM_MODEL_PATH=--lm_model_path acestep-5Hz-lm-4B\n\nREM CPU offload: required for 4B LM on GPUs with <=20GB VRAM\nset OFFLOAD_TO_CPU=--offload_to_cpu true\n\nREM LM backend: pt (PyTorch) recommended for ROCm\nset BACKEND=--backend pt\n```\n\n**ROCm virtual environment**:\n\nThe ROCm script uses a separate virtual environment (`venv_rocm`) instead of the standard `.venv` or `python_embeded`:\n```batch\nset VENV_DIR=%~dp0venv_rocm\n```\n\n> **Note**: The ROCm script requires a separate Python environment with ROCm-compatible PyTorch installed. See `requirements-rocm.txt` for setup instructions.\n\n---\n\n## Troubleshooting\n\n### Changes not taking effect\n\n**Solution**: Save the file and restart the script. Changes only apply on the next launch.\n\nWindows:\n```batch\nREM Close current process (Ctrl+C), then run again\nstart_gradio_ui.bat\n```\n\nLinux/macOS:\n```bash\n# Close current process (Ctrl+C), then run again\n./start_gradio_ui.sh\n```\n\n### Model download is slow\n\n**For Chinese users** -- set ModelScope:\n\n| Platform | Setting |\n|----------|---------|\n| Windows | `set DOWNLOAD_SOURCE=--download-source modelscope` |\n| Linux/macOS | `DOWNLOAD_SOURCE=\"--download-source modelscope\"` |\n\n**For overseas users** -- set HuggingFace:\n\n| Platform | Setting |\n|----------|---------|\n| Windows | `set DOWNLOAD_SOURCE=--download-source huggingface` |\n| Linux/macOS | `DOWNLOAD_SOURCE=\"--download-source huggingface\"` |\n\n### Wrong language displayed\n\nVerify the `LANGUAGE` variable in your Gradio UI script:\n\n| Platform | Chinese | English |\n|----------|---------|---------|\n| Windows | `set LANGUAGE=zh` | `set LANGUAGE=en` |\n| Linux/macOS | `LANGUAGE=\"zh\"` | `LANGUAGE=\"en\"` |\n\n### Port already in use\n\n**Error**: `Address already in use`\n\n**Solution 1**: Change the port number.\n\n| Platform | Setting |\n|----------|---------|\n| Windows | `set PORT=7861` |\n| Linux/macOS | `PORT=7861` |\n\n**Solution 2**: Find and close the process using the port.\n\nWindows:\n```batch\nREM Find process using port 7860\nnetstat -ano | findstr :7860\n\nREM Kill process (replace <PID> with the actual process ID)\ntaskkill /PID <PID> /F\n```\n\nLinux/macOS:\n```bash\n# Find process using port 7860\nlsof -i :7860\n\n# Kill process (replace <PID> with the actual process ID)\nkill <PID>\n```\n\n---\n\n## Best Practices\n\n1. **Backup before editing**: Make a copy of the script before modifying it.\n   - Windows: `copy start_gradio_ui.bat start_gradio_ui.bat.backup`\n   - Linux/macOS: `cp start_gradio_ui.sh start_gradio_ui.sh.backup`\n\n2. **Use comments to document your changes**: Add a note explaining why you changed a value so you remember later.\n   - Windows: `REM Changed to port 8080 for testing`\n   - Linux/macOS: `# Changed to port 8080 for testing`\n\n3. **Test after changes**: Save the file, close any running instance, re-launch the script, and verify the changes took effect.\n"
  },
  {
    "path": ".claude/skills/acestep-docs/guides/UPDATE_AND_BACKUP.md",
    "content": "# Update and Backup Guide\n\n## Overview\n\nAll ACE-Step launch scripts check for updates on startup by default. The update check is a lightweight inline operation that runs before the application starts, ensuring you are always notified about new versions without any manual setup.\n\n- **Default behavior**: Update checking is enabled (`CHECK_UPDATE=true`) in every launch script.\n- **Platforms supported**: Windows, Linux, and macOS.\n- **Graceful failures**: If git is not installed, the network is unreachable, or the project is not a git repository, the check is silently skipped and the application starts normally.\n- **User control**: You can disable the check at any time by setting `CHECK_UPDATE=false`.\n\n---\n\n## Update Check Feature\n\n### How It Works\n\nEach launch script contains a lightweight inline update check that runs before the main application starts. The check does not require any external update service -- it uses git directly to compare your local commit with the remote.\n\n**Flow:**\n\n```text\nStartup\n  |\n  v\nCHECK_UPDATE=true?  --No--> Skip, start app\n  |\n  Yes\n  v\nGit available?  --No--> Skip, start app\n  |\n  Yes\n  v\nValid git repo?  --No--> Skip, start app\n  |\n  Yes\n  v\nFetch origin (10s timeout)  --Timeout/Error--> Skip, start app\n  |\n  Success\n  v\nCompare local HEAD vs origin HEAD\n  |\n  +-- Same commit --> \"Already up to date\", start app\n  |\n  +-- Different commit --> Show new commits, ask Y/N\n        |\n        +-- N --> Skip, start app\n        |\n        +-- Y --> Run check_update.bat / check_update.sh for full update\n                    |\n                    v\n                  Start app\n```\n\nAt every failure point (no git, no network, not a repo), the check exits gracefully and the application starts without interruption.\n\n### Enabling and Disabling\n\nThe update check is controlled by the `CHECK_UPDATE` variable near the top of each launch script.\n\n**Windows** (`start_gradio_ui.bat`, `start_api_server.bat`):\n\n```batch\nREM Update check on startup (set to false to disable)\nset CHECK_UPDATE=true\nREM set CHECK_UPDATE=false\n```\n\n**Linux / macOS** (`start_gradio_ui.sh`, `start_api_server.sh`, `start_gradio_ui_macos.sh`, `start_api_server_macos.sh`):\n\n```bash\n# Update check on startup (set to \"false\" to disable)\nCHECK_UPDATE=\"true\"\n# CHECK_UPDATE=\"false\"\n```\n\nTo disable, change the active line to `false`. To re-enable, change it back to `true`.\n\n### Git Requirements by Platform\n\nThe inline update check requires git to be available. How you obtain git depends on your platform.\n\n**Windows:**\n\n- **Option A -- PortableGit** (no installation required): Download from <https://git-scm.com/download/win>, choose the portable version, and extract to a `PortableGit\\` folder in the project root. The launch scripts look for `PortableGit\\bin\\git.exe` first.\n- **Option B -- System git**: Install git through any standard method (Git for Windows installer, winget, scoop, etc.). The launch scripts fall back to system git if PortableGit is not found.\n\n```text\nProject Root/\n├── PortableGit/          <-- Optional, checked first on Windows\n│   └── bin/\n│       └── git.exe\n├── start_gradio_ui.bat\n├── check_update.bat\n└── ...\n```\n\n**Linux:**\n\nInstall git through your distribution's package manager:\n\n```bash\n# Ubuntu / Debian\nsudo apt install git\n\n# CentOS / RHEL / Fedora\nsudo yum install git\n# or\nsudo dnf install git\n\n# Arch Linux\nsudo pacman -S git\n```\n\n**macOS:**\n\nInstall git through Xcode command-line tools or Homebrew:\n\n```bash\n# Xcode command-line tools (includes git)\nxcode-select --install\n\n# Or via Homebrew\nbrew install git\n```\n\n### Example Output\n\n**Already up to date:**\n\n```text\n[Update] Checking for updates...\n[Update] Already up to date (abc1234).\n\nStarting ACE-Step Gradio Web UI...\n```\n\n**Update available:**\n\n```text\n[Update] Checking for updates...\n\n========================================\n  Update available!\n========================================\n  Current: abc1234  ->  Latest: def5678\n\n  Recent changes:\n* def5678 Fix audio processing bug\n* ccc3333 Add new model support\n\nUpdate now before starting? (Y/N):\n```\n\nIf you choose **Y**, the script delegates to `check_update.bat` (Windows) or `check_update.sh` (Linux/macOS) for the full update process including backup handling. If you choose **N**, the update is skipped and the application starts with the current version.\n\n**Network unreachable (auto-skip):**\n\n```text\n[Update] Checking for updates...\n[Update] Network unreachable, skipping.\n\nStarting ACE-Step Gradio Web UI...\n```\n\n---\n\n## Manual Update\n\nYou can run the update check manually at any time, outside of the launch scripts.\n\n**Windows:**\n\n```batch\ncheck_update.bat\n```\n\n**Linux / macOS:**\n\n```bash\n./check_update.sh\n```\n\nThe manual update scripts perform the same 4-step process:\n\n1. Detect git and verify the repository\n2. Fetch from origin with a 10-second timeout\n3. Compare local and remote commits\n4. If an update is available, prompt to apply it (with automatic backup of conflicting files)\n\n---\n\n## File Backup During Updates\n\n### Automatic Backup\n\nWhen you choose to update and you have locally modified files that also changed on the remote, ACE-Step automatically creates a backup before applying the update.\n\n**Supported file types** (any modified text file is backed up):\n\n- Configuration files: `.bat`, `.sh`, `.yaml`, `.json`, `.ini`\n- Python code: `.py`\n- Documentation: `.md`, `.txt`\n\n### Backup Process\n\n```text\n1. Update detects locally modified files\n   that also changed on the remote\n   |\n   v\n2. Creates a timestamped backup directory\n   .update_backup_YYYYMMDD_HHMMSS/\n   |\n   v\n3. Copies conflicting files into the backup\n   (preserves directory structure)\n   |\n   v\n4. Resets working tree to the remote version\n   |\n   v\n5. Displays backup location and instructions\n```\n\n### Example\n\n**Your local modifications:**\n\n- `start_gradio_ui.bat` -- Changed language to Chinese\n- `acestep/handler.py` -- Added debug logging\n- `config.yaml` -- Changed model path\n\n**Remote updates:**\n\n- `start_gradio_ui.bat` -- Added new features\n- `acestep/handler.py` -- Bug fixes\n- `config.yaml` -- New parameters\n\n**Backup created:**\n\n```text\n.update_backup_20260205_143022/\n├── start_gradio_ui.bat          (your version)\n├── config.yaml                  (your version)\n└── acestep/\n    └── handler.py               (your version)\n```\n\n**Working tree after update:**\n\n```text\nstart_gradio_ui.bat              (new version from GitHub)\nconfig.yaml                      (new version from GitHub)\nacestep/\n└── handler.py                   (new version from GitHub)\n```\n\nYour original files are preserved in the backup directory so you can merge your changes back in.\n\n---\n\n## Merging Configurations\n\nAfter an update that backed up your files, use the merge helper to compare and restore your settings.\n\n### Windows: merge_config.bat\n\n```batch\nmerge_config.bat\n```\n\nWhen comparing files, this script opens two Notepad windows side by side -- one with the backup version and one with the current version -- so you can manually copy your settings across.\n\n### Linux / macOS: merge_config.sh\n\n```bash\n./merge_config.sh\n```\n\nWhen comparing files, this script uses `colordiff` (if installed) or `diff` to display a unified diff in the terminal, showing exactly what changed between your backed-up version and the new version.\n\nTo install colordiff for colored output:\n\n```bash\n# Ubuntu / Debian\nsudo apt install colordiff\n\n# macOS (Homebrew)\nbrew install colordiff\n\n# Arch Linux\nsudo pacman -S colordiff\n```\n\n### Menu Options (Both Platforms)\n\nBoth `merge_config.bat` and `merge_config.sh` present the same interactive menu:\n\n```text\n========================================\nACE-Step Backup Merge Helper\n========================================\n\n1. Compare backup with current files\n2. Restore a file from backup\n3. List all backed up files\n4. Delete old backups\n5. Exit\n```\n\n| Option | Description |\n|--------|-------------|\n| **1. Compare** | Show differences between your backup and the current (updated) file. On Windows this opens two Notepad windows. On Linux/macOS this prints a unified diff to the terminal. |\n| **2. Restore** | Copy a file from the backup back into the project, overwriting the updated version. Use this only if the new version causes problems. |\n| **3. List** | Display all files stored in backup directories. |\n| **4. Delete** | Permanently remove old backup directories. Only do this after you have finished merging. |\n\n### Merging Common Files\n\n**Launch scripts** (`start_gradio_ui.bat`, `start_gradio_ui.sh`, etc.):\n\nLook for your custom settings in the backup (language, port, download source, etc.) and copy them into the corresponding lines of the new version.\n\n```bash\n# Example settings you may want to preserve:\nLANGUAGE=\"zh\"\nPORT=8080\nDOWNLOAD_SOURCE=\"--download-source modelscope\"\n```\n\n**Configuration files** (`config.yaml`, `.json`):\n\nCompare the structures. Keep your custom values, add any new keys from the updated version.\n\n```yaml\n# Backup (your version)\nmodel_path: \"custom/path\"\ncustom_setting: true\n\n# Current (new version)\nmodel_path: \"default/path\"\nnew_feature: enabled\n\n# Merged result\nmodel_path: \"custom/path\"       # Keep your setting\ncustom_setting: true             # Keep your setting\nnew_feature: enabled             # Add new feature\n```\n\n---\n\n## Testing Update Functionality\n\nUse the test scripts to verify that your git setup and update mechanism are working correctly before relying on them.\n\n**Windows:**\n\n```batch\ntest_git_update.bat\n```\n\n**Linux / macOS:**\n\n```bash\n./test_git_update.sh\n```\n\n### What the Tests Check\n\n1. **Git availability**: Verifies that git can be found (PortableGit or system git on Windows; system git on Linux/macOS).\n2. **Repository validity**: Confirms the project directory is a valid git repository.\n3. **Update script presence**: Checks that `check_update.bat` / `check_update.sh` exists.\n4. **Network connectivity**: Attempts an actual fetch from the remote (with timeout).\n\n### Example Test Output\n\n```text\n========================================\nTest Git Update Check\n========================================\n\n[Test 1] Checking Git...\n[PASS] Git found\ngit version 2.43.0\n\n[Test 2] Checking git repository...\n[PASS] Valid git repository\n  Branch: main\n  Commit: a1b2c3d\n\n[Test 3] Checking update script...\n[PASS] check_update.sh found\n\n[Test 4] Running update check...\n[PASS] Update check completed successfully\n\n[PASS] All tests completed\n```\n\n---\n\n## Troubleshooting\n\n### Git not found\n\nThe update check is silently skipped if git is not available. To enable it, install git for your platform:\n\n| Platform | Install Command |\n|----------|----------------|\n| **Windows (PortableGit)** | Download from <https://git-scm.com/download/win> and extract to `PortableGit\\` in the project root |\n| **Windows (system)** | `winget install --id Git.Git -e` or use the Git for Windows installer |\n| **Ubuntu / Debian** | `sudo apt install git` |\n| **CentOS / RHEL** | `sudo yum install git` |\n| **Arch Linux** | `sudo pacman -S git` |\n| **macOS** | `xcode-select --install` or `brew install git` |\n\n### Network timeout\n\nThe fetch operation has a 10-second timeout. If it times out, the update check is skipped automatically and the application starts normally. This is expected behavior on slow or restricted networks.\n\nOn macOS, the timeout mechanism uses `gtimeout` from GNU coreutils if available, or falls back to a plain fetch without a timeout. To get proper timeout support:\n\n```bash\nbrew install coreutils\n```\n\n### Proxy configuration\n\n**Windows (`check_update.bat`):**\n\nCreate a `proxy_config.txt` file in the project root:\n\n```text\nPROXY_ENABLED=1\nPROXY_URL=http://127.0.0.1:7890\n```\n\nOr configure interactively:\n\n```batch\ncheck_update.bat proxy\n```\n\nCommon proxy formats:\n\n| Type | Example |\n|------|---------|\n| HTTP proxy | `http://127.0.0.1:7890` |\n| HTTPS proxy | `https://proxy.company.com:8080` |\n| SOCKS5 proxy | `socks5://127.0.0.1:1080` |\n\nTo disable the proxy, set `PROXY_ENABLED=0` in `proxy_config.txt`.\n\n**Linux / macOS:**\n\nSet standard environment variables before running the script:\n\n```bash\nexport http_proxy=\"http://127.0.0.1:7890\"\nexport https_proxy=\"http://127.0.0.1:7890\"\n./check_update.sh\n```\n\nOr add them to your shell profile (`~/.bashrc`, `~/.zshrc`) for persistence.\n\n### Merge conflicts\n\nIf the automatic update fails or produces unexpected results:\n\n1. Check for backup directories: look for `.update_backup_*` folders in the project root.\n2. Use the merge helper (`merge_config.bat` or `./merge_config.sh`) to compare and restore files.\n3. If needed, manually inspect the diff between your backup and the current files.\n\n### Lost configuration after update\n\n1. Find your backup:\n   - **Windows:** `dir /b .update_backup_*`\n   - **Linux / macOS:** `ls -d .update_backup_*`\n2. Use the merge helper (Option 2) to restore specific files, or manually copy settings from the backup.\n\n---\n\n## Quick Reference\n\n| Action | Windows | Linux / macOS |\n|--------|---------|---------------|\n| **Enable update check** | `set CHECK_UPDATE=true` (in `.bat`) | `CHECK_UPDATE=\"true\"` (in `.sh`) |\n| **Disable update check** | `set CHECK_UPDATE=false` (in `.bat`) | `CHECK_UPDATE=\"false\"` (in `.sh`) |\n| **Manual update** | `check_update.bat` | `./check_update.sh` |\n| **Configure proxy** | `check_update.bat proxy` or edit `proxy_config.txt` | `export http_proxy=... && ./check_update.sh` |\n| **Merge configurations** | `merge_config.bat` | `./merge_config.sh` |\n| **Test update setup** | `test_git_update.bat` | `./test_git_update.sh` |\n| **List backups** | `dir /b .update_backup_*` | `ls -d .update_backup_*` |\n| **Delete a backup** | `rmdir /s /q .update_backup_YYYYMMDD_HHMMSS` | `rm -rf .update_backup_YYYYMMDD_HHMMSS` |\n"
  },
  {
    "path": ".claude/skills/acestep-lyrics-transcription/SKILL.md",
    "content": "---\nname: acestep-lyrics-transcription\ndescription: Transcribe audio to timestamped lyrics using OpenAI Whisper or ElevenLabs Scribe API. Outputs LRC, SRT, or JSON with word-level timestamps. Use when users want to transcribe songs, generate LRC files, or extract lyrics with timestamps from audio.\nallowed-tools: Read, Write, Bash\n---\n\n# Lyrics Transcription Skill\n\nTranscribe audio files to timestamped lyrics (LRC/SRT/JSON) via OpenAI Whisper or ElevenLabs Scribe API.\n\n## API Key Setup Guide\n\n**Before transcribing, you MUST check whether the user's API key is configured.** Run the following command to check:\n\n```bash\ncd \"{project_root}/{.claude or .codex}/skills/acestep-lyrics-transcription/\" && bash ./scripts/acestep-lyrics-transcription.sh config --check-key\n```\n\nThis command only reports whether the active provider's API key is set or empty — it does NOT print the actual key value. **NEVER read or display the user's API key content.** Do not use `config --get` on key fields or read `config.json` directly. The `config --list` command is safe — it automatically masks API keys as `***` in output.\n\n**If the command reports the key is empty**, you MUST stop and guide the user to configure it before proceeding. Do NOT attempt transcription without a valid key — it will fail.\n\nUse `AskUserQuestion` to ask the user to provide their API key, with the following options and guidance:\n\n1. Tell the user which provider is currently active (openai or elevenlabs) and that its API key is not configured. Explain that transcription cannot proceed without it.\n2. Provide clear instructions on where to obtain a key:\n   - **OpenAI**: Get an API key at https://platform.openai.com/api-keys — requires an OpenAI account with billing enabled. The Whisper API costs ~$0.006/min.\n   - **ElevenLabs**: Get an API key at https://elevenlabs.io/app/settings/api-keys — requires an ElevenLabs account. Free tier includes limited credits.\n3. Also offer the option to switch to the other provider if they already have a key for it.\n4. Once the user provides the key, configure it using:\n   ```bash\n   cd \"{project_root}/{.claude or .codex}/skills/acestep-lyrics-transcription/\" && bash ./scripts/acestep-lyrics-transcription.sh config --set <provider>.api_key <KEY>\n   ```\n5. If the user wants to switch providers, also run:\n   ```bash\n   cd \"{project_root}/{.claude or .codex}/skills/acestep-lyrics-transcription/\" && bash ./scripts/acestep-lyrics-transcription.sh config --set provider <provider_name>\n   ```\n6. After configuring, re-run `config --check-key` to verify the key is set before proceeding.\n\n**If the API key is already configured**, proceed directly to transcription without asking.\n\n## Quick Start\n\n```bash\n# 1. cd to this skill's directory\ncd {project_root}/{.claude or .codex}/skills/acestep-lyrics-transcription/\n\n# 2. Configure API key (choose one)\n./scripts/acestep-lyrics-transcription.sh config --set openai.api_key sk-...\n# or\n./scripts/acestep-lyrics-transcription.sh config --set elevenlabs.api_key ...\n./scripts/acestep-lyrics-transcription.sh config --set provider elevenlabs\n\n# 3. Transcribe\n./scripts/acestep-lyrics-transcription.sh transcribe --audio /path/to/song.mp3 --language zh\n\n# 4. Output saved to: {project_root}/acestep_output/<filename>.lrc\n```\n\n## Prerequisites\n\n- curl, jq, python3 (or python)\n- An API key for OpenAI or ElevenLabs\n\n## Script Usage\n\n```bash\n./scripts/acestep-lyrics-transcription.sh transcribe --audio <file> [options]\n\nOptions:\n  -a, --audio      Audio file path (required)\n  -l, --language   Language code (zh, en, ja, etc.)\n  -f, --format     Output format: lrc, srt, json (default: lrc)\n  -p, --provider   API provider: openai, elevenlabs (overrides config)\n  -o, --output     Output file path (default: acestep_output/<filename>.lrc)\n```\n\n## Post-Transcription Lyrics Correction (MANDATORY)\n\n**CRITICAL**: After transcription, you MUST manually correct the LRC file before using it for MV rendering. Transcription models frequently produce errors on sung lyrics:\n\n- Proper nouns: \"ACE-Step\" → \"AC step\", \"Spotify\" → \"spot a fly\"\n- Similar-sounding words: \"arrives\" → \"eyes\", \"open source\" → \"open sores\"\n- Merged/split words: \"lighting up\" → \"lightin' nup\"\n\n### Correction Workflow\n\n1. **Read the transcribed LRC file** using the Read tool\n2. **Read the original lyrics** from the ACE-Step output JSON file\n3. **Use original lyrics as a whole reference**: Do NOT attempt line-by-line alignment — transcription often splits, merges, or reorders lines differently from the original. Instead, read the original lyrics in full to understand the correct wording, then scan each LRC line and fix any misrecognized words based on your knowledge of what the original lyrics say.\n4. **Fix transcription errors**: Replace misrecognized words with the correct original words, keeping the timestamps intact\n5. **Write the corrected LRC** back using the Write tool\n\n### What to Correct\n\n- Replace misrecognized words with their correct original versions\n- Keep all `[MM:SS.cc]` timestamps exactly as-is (timestamps from transcription are accurate)\n- Do NOT add structure tags like `[Verse]` or `[Chorus]` — the LRC should only have timestamped text lines\n\n### Example\n\n**Transcribed (wrong):**\n```\n[00:46.96]AC step alive,\n[00:50.80]one point five eyes.\n```\n\n**Original lyrics reference:**\n```\nACE-Step alive\nOne point five arrives\n```\n\n**Corrected (right):**\n```\n[00:46.96]ACE-Step alive,\n[00:50.80]One point five arrives.\n```\n\n## Configuration\n\nConfig file: `scripts/config.json`\n\n```bash\n# Switch provider\n./scripts/acestep-lyrics-transcription.sh config --set provider openai\n./scripts/acestep-lyrics-transcription.sh config --set provider elevenlabs\n\n# Set API keys\n./scripts/acestep-lyrics-transcription.sh config --set openai.api_key sk-...\n./scripts/acestep-lyrics-transcription.sh config --set elevenlabs.api_key ...\n\n# View config\n./scripts/acestep-lyrics-transcription.sh config --list\n```\n\n| Option | Default | Description |\n|--------|---------|-------------|\n| `provider` | `openai` | Active provider: `openai` or `elevenlabs` |\n| `output_format` | `lrc` | Default output: `lrc`, `srt`, or `json` |\n| `openai.api_key` | `\"\"` | OpenAI API key |\n| `openai.api_url` | `https://api.openai.com/v1` | OpenAI API base URL |\n| `openai.model` | `whisper-1` | OpenAI model (whisper-1 for word timestamps) |\n| `elevenlabs.api_key` | `\"\"` | ElevenLabs API key |\n| `elevenlabs.api_url` | `https://api.elevenlabs.io/v1` | ElevenLabs API base URL |\n| `elevenlabs.model` | `scribe_v2` | ElevenLabs model |\n\n## Provider Notes\n\n| Provider | Model | Word Timestamps | Pricing |\n|----------|-------|-----------------|---------|\n| OpenAI | whisper-1 | Yes (segment + word) | $0.006/min |\n| ElevenLabs | scribe_v2 | Yes (word-level) | Varies by plan |\n\n- OpenAI `whisper-1` is the only OpenAI model supporting word-level timestamps\n- ElevenLabs `scribe_v2` returns word-level timestamps with type filtering\n- Both support multilingual transcription\n\n## Examples\n\n```bash\n# Basic transcription (uses config defaults)\n./scripts/acestep-lyrics-transcription.sh transcribe --audio song.mp3\n\n# Chinese song to LRC\n./scripts/acestep-lyrics-transcription.sh transcribe --audio song.mp3 --language zh\n\n# Use ElevenLabs, output SRT\n./scripts/acestep-lyrics-transcription.sh transcribe --audio song.mp3 --provider elevenlabs --format srt\n\n# Custom output path\n./scripts/acestep-lyrics-transcription.sh transcribe --audio song.mp3 --output ./my_lyrics.lrc\n```\n"
  },
  {
    "path": ".claude/skills/acestep-lyrics-transcription/scripts/acestep-lyrics-transcription.sh",
    "content": "#!/bin/bash\n#\n# acestep-lyrics-transcription.sh - Transcribe audio to timestamped lyrics (LRC/SRT/JSON)\n#\n# Requirements: curl, jq\n#\n# Usage:\n#   ./acestep-lyrics-transcription.sh transcribe --audio <file> [options]\n#   ./acestep-lyrics-transcription.sh config [--get|--set|--reset]\n#\n# Output:\n#   - LRC/SRT/JSON files saved to output directory\n\nset -e\n\nexport LANG=\"${LANG:-en_US.UTF-8}\"\nexport LC_ALL=\"${LC_ALL:-en_US.UTF-8}\"\n\nSCRIPT_DIR=\"$(cd \"$(dirname \"${BASH_SOURCE[0]}\")\" && pwd)\"\nCONFIG_FILE=\"${SCRIPT_DIR}/config.json\"\nOUTPUT_DIR=\"$(cd \"${SCRIPT_DIR}/../../../..\" && pwd)/acestep_output\"\n\n# Colors\nRED='\\033[0;31m'\nGREEN='\\033[0;32m'\nYELLOW='\\033[1;33m'\nCYAN='\\033[0;36m'\nNC='\\033[0m'\n\n# Convert MSYS2/Cygwin paths to Windows-native paths for Python\nto_python_path() {\n    if command -v cygpath &> /dev/null; then\n        cygpath -m \"$1\"\n    else\n        echo \"$1\"\n    fi\n}\n\n# Detect python executable (python3 or python)\nPYTHON_CMD=\"\"\nfind_python() {\n    if [ -n \"$PYTHON_CMD\" ]; then return; fi\n    # Test actual execution, not just existence (Windows Store python3 shim returns exit 49)\n    if python3 -c \"pass\" &> /dev/null; then\n        PYTHON_CMD=\"python3\"\n    elif python -c \"pass\" &> /dev/null; then\n        PYTHON_CMD=\"python\"\n    else\n        echo -e \"${RED}Error: python3 or python is required but not found.${NC}\"\n        exit 1\n    fi\n}\n\n# ─── Dependencies ───\n\ncheck_deps() {\n    if ! command -v curl &> /dev/null; then\n        echo -e \"${RED}Error: curl is required but not installed.${NC}\"\n        exit 1\n    fi\n    if ! command -v jq &> /dev/null; then\n        echo -e \"${RED}Error: jq is required but not installed.${NC}\"\n        echo \"Install: apt install jq / brew install jq / choco install jq\"\n        exit 1\n    fi\n}\n\n# ─── Config ───\n\nDEFAULT_CONFIG='{\n  \"provider\": \"openai\",\n  \"output_format\": \"lrc\",\n  \"openai\": {\n    \"api_key\": \"\",\n    \"api_url\": \"https://api.openai.com/v1\",\n    \"model\": \"whisper-1\"\n  },\n  \"elevenlabs\": {\n    \"api_key\": \"\",\n    \"api_url\": \"https://api.elevenlabs.io/v1\",\n    \"model\": \"scribe_v2\"\n  }\n}'\n\nensure_config() {\n    if [ ! -f \"$CONFIG_FILE\" ]; then\n        local example=\"${SCRIPT_DIR}/config.example.json\"\n        if [ -f \"$example\" ]; then\n            cp \"$example\" \"$CONFIG_FILE\"\n            echo -e \"${YELLOW}Config file created from config.example.json. Please configure your settings:${NC}\"\n            echo -e \"  ${CYAN}./scripts/acestep-lyrics-transcription.sh config --set provider <openai|elevenlabs>${NC}\"\n            echo -e \"  ${CYAN}./scripts/acestep-lyrics-transcription.sh config --set <provider>.api_key <key>${NC}\"\n        else\n            echo \"$DEFAULT_CONFIG\" > \"$CONFIG_FILE\"\n        fi\n    fi\n}\n\nget_config() {\n    local key=\"$1\"\n    ensure_config\n    local jq_path=\".${key}\"\n    local value\n    value=$(jq -r \"$jq_path\" \"$CONFIG_FILE\" 2>/dev/null)\n    if [ \"$value\" = \"null\" ]; then\n        echo \"\"\n    else\n        echo \"$value\" | tr -d '\\r\\n'\n    fi\n}\n\nset_config() {\n    local key=\"$1\"\n    local value=\"$2\"\n    ensure_config\n    local tmp_file=\"${CONFIG_FILE}.tmp\"\n    local jq_path=\".${key}\"\n\n    if [ \"$value\" = \"true\" ] || [ \"$value\" = \"false\" ]; then\n        jq \"$jq_path = $value\" \"$CONFIG_FILE\" > \"$tmp_file\"\n    elif [[ \"$value\" =~ ^-?[0-9]+$ ]] || [[ \"$value\" =~ ^-?[0-9]+\\.[0-9]+$ ]]; then\n        jq \"$jq_path = $value\" \"$CONFIG_FILE\" > \"$tmp_file\"\n    else\n        jq \"$jq_path = \\\"$value\\\"\" \"$CONFIG_FILE\" > \"$tmp_file\"\n    fi\n\n    mv \"$tmp_file\" \"$CONFIG_FILE\"\n    echo \"Set $key = $value\"\n}\n\nensure_output_dir() {\n    mkdir -p \"$OUTPUT_DIR\"\n}\n\n# ─── Format Conversion ───\n\n# Convert word-level timestamps to LRC format\n# Input: JSON array of {word, start, end} on stdin\n# Output: LRC text\nwords_to_lrc() {\n    local json_file=\"$(to_python_path \"$1\")\"\n    local output_file=\"$(to_python_path \"$2\")\"\n    local line_gap=\"${3:-1.5}\"\n    find_python\n\n    $PYTHON_CMD -c \"\nimport json, sys, unicodedata\n\ndef is_cjk(ch):\n    cp = ord(ch)\n    return (0x4E00 <= cp <= 0x9FFF or 0x3400 <= cp <= 0x4DBF or\n            0x20000 <= cp <= 0x2A6DF or 0x2A700 <= cp <= 0x2B73F or\n            0x2B740 <= cp <= 0x2B81F or 0x2B820 <= cp <= 0x2CEAF or\n            0xF900 <= cp <= 0xFAFF or 0x2F800 <= cp <= 0x2FA1F or\n            0x3000 <= cp <= 0x303F or 0x3040 <= cp <= 0x309F or\n            0x30A0 <= cp <= 0x30FF or 0xFF00 <= cp <= 0xFFEF)\n\ndef smart_join(word_list):\n    if not word_list:\n        return ''\n    result = word_list[0]\n    for j in range(1, len(word_list)):\n        prev_w = word_list[j-1]\n        curr_w = word_list[j]\n        prev_last = prev_w[-1] if prev_w else ''\n        curr_first = curr_w[0] if curr_w else ''\n        if is_cjk(prev_last) or is_cjk(curr_first):\n            result += curr_w\n        else:\n            result += ' ' + curr_w\n    return result.strip()\n\nwith open('$json_file', 'r', encoding='utf-8') as f:\n    words = json.load(f)\n\nif not words:\n    sys.exit(0)\n\nlines = []\ncurrent_line = []\ncurrent_start = words[0]['start']\n\nfor i, w in enumerate(words):\n    current_line.append(w['word'])\n    is_last = (i == len(words) - 1)\n    has_punct = w['word'].rstrip().endswith(('.', '!', '?', '。', '！', '？', '，', ','))\n    has_gap = (not is_last and words[i+1]['start'] - w['end'] > $line_gap)\n\n    if is_last or has_punct or has_gap:\n        text = smart_join(current_line)\n        text = text.rstrip('，。,.')\n        if text:\n            mins = int(current_start) // 60\n            secs = current_start - mins * 60\n            lines.append(f'[{mins:02d}:{secs:05.2f}]{text}')\n        current_line = []\n        if not is_last:\n            current_start = words[i+1]['start']\n\nwith open('$output_file', 'w', encoding='utf-8') as f:\n    for line in lines:\n        f.write(line + '\\n')\n\"\n}\n\n# Convert word-level timestamps to SRT format\nwords_to_srt() {\n    local json_file=\"$(to_python_path \"$1\")\"\n    local output_file=\"$(to_python_path \"$2\")\"\n    local line_gap=\"${3:-1.5}\"\n    find_python\n\n    $PYTHON_CMD -c \"\nimport json, sys\n\ndef is_cjk(ch):\n    cp = ord(ch)\n    return (0x4E00 <= cp <= 0x9FFF or 0x3400 <= cp <= 0x4DBF or\n            0x20000 <= cp <= 0x2A6DF or 0x2A700 <= cp <= 0x2B73F or\n            0x2B740 <= cp <= 0x2B81F or 0x2B820 <= cp <= 0x2CEAF or\n            0xF900 <= cp <= 0xFAFF or 0x2F800 <= cp <= 0x2FA1F or\n            0x3000 <= cp <= 0x303F or 0x3040 <= cp <= 0x309F or\n            0x30A0 <= cp <= 0x30FF or 0xFF00 <= cp <= 0xFFEF)\n\ndef smart_join(word_list):\n    if not word_list:\n        return ''\n    result = word_list[0]\n    for j in range(1, len(word_list)):\n        prev_w = word_list[j-1]\n        curr_w = word_list[j]\n        prev_last = prev_w[-1] if prev_w else ''\n        curr_first = curr_w[0] if curr_w else ''\n        if is_cjk(prev_last) or is_cjk(curr_first):\n            result += curr_w\n        else:\n            result += ' ' + curr_w\n    return result.strip()\n\nwith open('$json_file', 'r', encoding='utf-8') as f:\n    words = json.load(f)\n\nif not words:\n    sys.exit(0)\n\ndef fmt(t):\n    h = int(t) // 3600\n    m = (int(t) % 3600) // 60\n    s = t - h*3600 - m*60\n    return f'{h:02d}:{m:02d}:{s:06.3f}'.replace('.', ',')\n\nlines = []\ncurrent_line = []\ncurrent_start = words[0]['start']\ncurrent_end = words[0]['end']\n\nfor i, w in enumerate(words):\n    current_line.append(w['word'])\n    current_end = w['end']\n    is_last = (i == len(words) - 1)\n    has_punct = w['word'].rstrip().endswith(('.', '!', '?', '。', '！', '？', '，', ','))\n    has_gap = (not is_last and words[i+1]['start'] - w['end'] > $line_gap)\n\n    if is_last or has_punct or has_gap:\n        text = smart_join(current_line)\n        text = text.rstrip('，。,.')\n        if text:\n            lines.append((current_start, current_end, text))\n        current_line = []\n        if not is_last:\n            current_start = words[i+1]['start']\n\nwith open('$output_file', 'w', encoding='utf-8') as f:\n    for idx, (s, e, text) in enumerate(lines, 1):\n        f.write(f'{idx}\\n')\n        f.write(f'{fmt(s)} --> {fmt(e)}\\n')\n        f.write(f'{text}\\n')\n        f.write('\\n')\n\"\n}\n\n# ─── OpenAI Whisper ───\n\ntranscribe_openai() {\n    local audio_file=\"$1\"\n    local language=\"$2\"\n    local words_file=\"$3\"\n\n    local api_key=$(get_config \"openai.api_key\")\n    local api_url=$(get_config \"openai.api_url\")\n    local model=$(get_config \"openai.model\")\n\n    [ -z \"$api_key\" ] && { echo -e \"${RED}Error: OpenAI API key not configured.${NC}\"; echo \"Run: ./acestep-lyrics-transcription.sh config --set openai.api_key YOUR_KEY\"; exit 1; }\n    [ -z \"$api_url\" ] && api_url=\"https://api.openai.com/v1\"\n    [ -z \"$model\" ] && model=\"whisper-1\"\n\n    echo -e \"  Provider: OpenAI (${model})\"\n\n    local resp_file=$(mktemp)\n\n    # Build curl command\n    local curl_args=(\n        -s -w \"%{http_code}\"\n        -o \"$resp_file\"\n        -X POST \"${api_url}/audio/transcriptions\"\n        -H \"Authorization: Bearer ${api_key}\"\n        -F \"file=@${audio_file}\"\n        -F \"model=${model}\"\n        -F \"response_format=verbose_json\"\n        -F \"timestamp_granularities[]=word\"\n        -F \"timestamp_granularities[]=segment\"\n    )\n\n    [ -n \"$language\" ] && curl_args+=(-F \"language=${language}\")\n\n    local http_code\n    http_code=$(curl \"${curl_args[@]}\")\n\n    if [ \"$http_code\" != \"200\" ]; then\n        local err\n        err=$(jq -r '.error.message // .detail // \"Unknown error\"' \"$resp_file\" 2>/dev/null)\n        echo -e \"${RED}Error: HTTP $http_code - $err${NC}\"\n        rm -f \"$resp_file\"\n        return 1\n    fi\n\n    # Extract word-level timestamps into normalized format [{word, start, end}]\n    jq '[.words[] | {word: .word, start: .start, end: .end}]' \"$resp_file\" > \"$words_file\" 2>/dev/null\n\n    # Show transcription text\n    local text\n    text=$(jq -r '.text // empty' \"$resp_file\" 2>/dev/null)\n    echo -e \"  ${GREEN}Transcription complete${NC}\"\n    echo \"\"\n    echo \"$text\"\n\n    rm -f \"$resp_file\"\n}\n\n# ─── ElevenLabs Scribe ───\n\ntranscribe_elevenlabs() {\n    local audio_file=\"$1\"\n    local language=\"$2\"\n    local words_file=\"$3\"\n\n    local api_key=$(get_config \"elevenlabs.api_key\")\n    local api_url=$(get_config \"elevenlabs.api_url\")\n    local model=$(get_config \"elevenlabs.model\")\n\n    [ -z \"$api_key\" ] && { echo -e \"${RED}Error: ElevenLabs API key not configured.${NC}\"; echo \"Run: ./acestep-lyrics-transcription.sh config --set elevenlabs.api_key YOUR_KEY\"; exit 1; }\n    [ -z \"$api_url\" ] && api_url=\"https://api.elevenlabs.io/v1\"\n    [ -z \"$model\" ] && model=\"scribe_v2\"\n\n    echo -e \"  Provider: ElevenLabs (${model})\"\n\n    local resp_file=$(mktemp)\n\n    local curl_args=(\n        -s -w \"%{http_code}\"\n        -o \"$resp_file\"\n        -X POST \"${api_url}/speech-to-text\"\n        -H \"xi-api-key: ${api_key}\"\n        -F \"file=@${audio_file}\"\n        -F \"model_id=${model}\"\n    )\n\n    [ -n \"$language\" ] && curl_args+=(-F \"language_code=${language}\")\n\n    local http_code\n    http_code=$(curl \"${curl_args[@]}\")\n\n    if [ \"$http_code\" != \"200\" ]; then\n        local err\n        err=$(jq -r '.detail.message // .detail // \"Unknown error\"' \"$resp_file\" 2>/dev/null)\n        echo -e \"${RED}Error: HTTP $http_code - $err${NC}\"\n        rm -f \"$resp_file\"\n        return 1\n    fi\n\n    # ElevenLabs response: { text, words: [{text, start, end, type}...] }\n    # Normalize to [{word, start, end}], timestamps already in seconds, filter only \"word\" type\n    jq '[.words[] | select(.type == \"word\") | {word: .text, start: .start, end: .end}]' \"$resp_file\" > \"$words_file\" 2>/dev/null\n\n    local text\n    text=$(jq -r '.text // empty' \"$resp_file\" 2>/dev/null)\n    echo -e \"  ${GREEN}Transcription complete${NC}\"\n    echo \"\"\n    echo \"$text\"\n\n    rm -f \"$resp_file\"\n}\n\n# ─── Commands ───\n\ncmd_transcribe() {\n    check_deps\n    ensure_config\n\n    local audio=\"\" language=\"\" output=\"\" format=\"\" provider=\"\"\n\n    while [[ $# -gt 0 ]]; do\n        case $1 in\n            --audio|-a)    audio=\"$2\"; shift 2 ;;\n            --language|-l) language=\"$2\"; shift 2 ;;\n            --output|-o)   output=\"$2\"; shift 2 ;;\n            --format|-f)   format=\"$2\"; shift 2 ;;\n            --provider|-p) provider=\"$2\"; shift 2 ;;\n            *) [ -z \"$audio\" ] && audio=\"$1\"; shift ;;\n        esac\n    done\n\n    [ -z \"$audio\" ] && { echo -e \"${RED}Error: --audio is required${NC}\"; echo \"Usage: $0 transcribe --audio <file> [options]\"; exit 1; }\n    [ ! -f \"$audio\" ] && { echo -e \"${RED}Error: audio file not found: $audio${NC}\"; exit 1; }\n\n    # Resolve absolute path\n    audio=\"$(cd \"$(dirname \"$audio\")\" && pwd)/$(basename \"$audio\")\"\n\n    [ -z \"$provider\" ] && provider=$(get_config \"provider\")\n    [ -z \"$provider\" ] && provider=\"openai\"\n\n    [ -z \"$format\" ] && format=$(get_config \"output_format\")\n    [ -z \"$format\" ] && format=\"lrc\"\n\n    # Default output path\n    if [ -z \"$output\" ]; then\n        ensure_output_dir\n        local basename=\"$(basename \"${audio%.*}\")\"\n        output=\"${OUTPUT_DIR}/${basename}.${format}\"\n    fi\n\n    echo \"Transcribing...\"\n    echo \"  Audio: $(basename \"$audio\")\"\n    echo \"  Format: $format\"\n\n    # Transcribe to normalized word timestamps\n    local words_file=$(mktemp)\n\n    case \"$provider\" in\n        openai)   transcribe_openai \"$audio\" \"$language\" \"$words_file\" ;;\n        elevenlabs) transcribe_elevenlabs \"$audio\" \"$language\" \"$words_file\" ;;\n        *) echo -e \"${RED}Error: unknown provider: $provider${NC}\"; echo \"Supported: openai, elevenlabs\"; rm -f \"$words_file\"; exit 1 ;;\n    esac\n\n    # Check if we got words\n    local word_count\n    word_count=$(jq 'length' \"$words_file\" 2>/dev/null)\n    if [ -z \"$word_count\" ] || [ \"$word_count\" = \"0\" ]; then\n        echo -e \"${YELLOW}Warning: no word-level timestamps returned${NC}\"\n        rm -f \"$words_file\"\n        return 1\n    fi\n\n    echo \"\"\n    echo \"  Words detected: $word_count\"\n\n    # Convert to output format\n    mkdir -p \"$(dirname \"$output\")\"\n\n    case \"$format\" in\n        lrc)\n            words_to_lrc \"$words_file\" \"$output\"\n            ;;\n        srt)\n            words_to_srt \"$words_file\" \"$output\"\n            ;;\n        json)\n            cp \"$words_file\" \"$output\"\n            ;;\n        *)\n            echo -e \"${RED}Error: unknown format: $format (supported: lrc, srt, json)${NC}\"\n            rm -f \"$words_file\"\n            exit 1\n            ;;\n    esac\n\n    rm -f \"$words_file\"\n\n    echo -e \"  ${GREEN}Saved: $output${NC}\"\n    echo \"\"\n    echo -e \"${GREEN}Done!${NC}\"\n}\n\ncmd_config() {\n    check_deps\n    ensure_config\n\n    local action=\"\" key=\"\" value=\"\"\n\n    while [[ $# -gt 0 ]]; do\n        case $1 in\n            --get)       action=\"get\"; key=\"$2\"; shift 2 ;;\n            --set)       action=\"set\"; key=\"$2\"; value=\"$3\"; shift 3 ;;\n            --reset)     action=\"reset\"; shift ;;\n            --list)      action=\"list\"; shift ;;\n            --check-key) action=\"check-key\"; shift ;;\n            *) shift ;;\n        esac\n    done\n\n    case \"$action\" in\n        \"check-key\")\n            local provider=$(get_config \"provider\")\n            [ -z \"$provider\" ] && provider=\"openai\"\n            local api_key=$(get_config \"${provider}.api_key\")\n            echo \"provider: $provider\"\n            if [ -n \"$api_key\" ]; then\n                echo \"api_key: configured\"\n            else\n                echo \"api_key: empty\"\n            fi\n            ;;\n        \"get\")\n            [ -z \"$key\" ] && { echo -e \"${RED}Error: --get requires KEY${NC}\"; exit 1; }\n            local result=$(get_config \"$key\")\n            [ -n \"$result\" ] && echo \"$key = $result\" || echo \"Key not found: $key\"\n            ;;\n        \"set\")\n            [ -z \"$key\" ] || [ -z \"$value\" ] && { echo -e \"${RED}Error: --set requires KEY VALUE${NC}\"; exit 1; }\n            set_config \"$key\" \"$value\"\n            ;;\n        \"reset\")\n            echo \"$DEFAULT_CONFIG\" > \"$CONFIG_FILE\"\n            echo -e \"${GREEN}Configuration reset to defaults.${NC}\"\n            jq 'walk(if type == \"object\" and has(\"api_key\") and (.api_key | length) > 0 then .api_key = \"***\" else . end)' \"$CONFIG_FILE\"\n            ;;\n        \"list\")\n            echo \"Current configuration:\"\n            jq 'walk(if type == \"object\" and has(\"api_key\") and (.api_key | length) > 0 then .api_key = \"***\" else . end)' \"$CONFIG_FILE\"\n            ;;\n        *)\n            echo \"Config file: $CONFIG_FILE\"\n            echo \"----------------------------------------\"\n            jq 'walk(if type == \"object\" and has(\"api_key\") and (.api_key | length) > 0 then .api_key = \"***\" else . end)' \"$CONFIG_FILE\"\n            echo \"\"\n            echo \"----------------------------------------\"\n            echo \"\"\n            echo \"Usage:\"\n            echo \"  config --list              Show config\"\n            echo \"  config --get <key>         Get value\"\n            echo \"  config --set <key> <val>   Set value\"\n            echo \"  config --reset             Reset to defaults\"\n            echo \"\"\n            echo \"Examples:\"\n            echo \"  config --set provider elevenlabs\"\n            echo \"  config --set openai.api_key sk-...\"\n            echo \"  config --set elevenlabs.api_key ...\"\n            echo \"  config --set output_format srt\"\n            ;;\n    esac\n}\n\nshow_help() {\n    echo \"Lyrics Transcription CLI\"\n    echo \"\"\n    echo \"Requirements: curl, jq, python3\"\n    echo \"\"\n    echo \"Usage: $0 <command> [options]\"\n    echo \"\"\n    echo \"Commands:\"\n    echo \"  transcribe   Transcribe audio to timestamped lyrics\"\n    echo \"  config       Manage configuration\"\n    echo \"\"\n    echo \"Transcribe Options:\"\n    echo \"  -a, --audio      Audio file path (required)\"\n    echo \"  -l, --language   Language code (e.g. zh, en, ja)\"\n    echo \"  -f, --format     Output format: lrc, srt, json (default: lrc)\"\n    echo \"  -p, --provider   API provider: openai, elevenlabs\"\n    echo \"  -o, --output     Output file path\"\n    echo \"\"\n    echo \"Examples:\"\n    echo \"  $0 transcribe --audio song.mp3\"\n    echo \"  $0 transcribe --audio song.mp3 --language zh --format lrc\"\n    echo \"  $0 config --set provider openai\"\n}\n\n# ─── Main ───\n\ncase \"$1\" in\n    transcribe) shift; cmd_transcribe \"$@\" ;;\n    config)     shift; cmd_config \"$@\" ;;\n    help|--help|-h) show_help ;;\n    *) show_help; exit 1 ;;\nesac\n"
  },
  {
    "path": ".claude/skills/acestep-lyrics-transcription/scripts/config.example.json",
    "content": "{\n  \"provider\": \"elevenlabs\",\n  \"output_format\": \"lrc\",\n  \"openai\": {\n    \"api_key\": \"\",\n    \"api_url\": \"https://api.openai.com/v1\",\n    \"model\": \"whisper-1\"\n  },\n  \"elevenlabs\": {\n    \"api_key\": \"\",\n    \"api_url\": \"https://api.elevenlabs.io/v1\",\n    \"model\": \"scribe_v2\"\n  }\n}\n"
  },
  {
    "path": ".claude/skills/acestep-simplemv/SKILL.md",
    "content": "---\nname: acestep-simplemv\ndescription: Render music videos from audio files and lyrics using Remotion. Accepts audio + LRC/JSON lyrics + title to produce MP4 videos with waveform visualization and synced lyrics display. Use when users mention MV generation, music video rendering, creating video from audio/lyrics, or visualizing songs.\n---\n\n# MV Render\n\nRender music videos with waveform visualization and synced lyrics from audio + lyrics input.\n\n## Prerequisites\n\n- Remotion project at `scripts/` directory within this skill\n- Node.js + npm dependencies installed\n- ffprobe available (for audio duration detection)\n\n### First-Time Setup\n\nBefore first use, check and install dependencies:\n\n```bash\n# 1. Check Node.js\nnode --version\n\n# 2. Install npm dependencies\ncd {project_root}/{.claude or .codex}/skills/acestep-simplemv/scripts && npm install\n\n# 3. Check ffprobe\nffprobe -version\n```\n\nIf ffprobe is not available, install ffmpeg (which includes ffprobe):\n- **Windows**: `choco install ffmpeg` or download from https://ffmpeg.org/download.html and add to PATH\n- **macOS**: `brew install ffmpeg`\n- **Linux**: `sudo apt-get install ffmpeg` (Debian/Ubuntu) or `sudo dnf install ffmpeg` (Fedora)\n\n## Quick Start\n\n```bash\ncd {project_root}/{.claude or .codex}/skills/acestep-simplemv/\n./scripts/render-mv.sh --audio /path/to/song.mp3 --lyrics /path/to/song.lrc --title \"Song Title\"\n```\n\nOutput: MP4 file at `out/<audio_basename>.mp4` (or custom `--output` path).\n\n## Script Usage\n\n```bash\n./scripts/render-mv.sh --audio <file> --lyrics <lrc_file> --title \"Title\" [options]\n\nOptions:\n  --audio        Audio file path (absolute paths supported)\n  --lyrics       LRC format lyrics file (timestamped)\n  --lyrics-json  JSON lyrics file [{start, end, text}] (alternative to --lyrics)\n  --title        Video title (default: \"Music Video\")\n  --subtitle     Subtitle text\n  --credit       Bottom credit text\n  --offset       Lyric timing offset in seconds (default: -0.5)\n  --output       Output file path (default: out/<audio_basename>.mp4)\n  --codec        h264|h265|vp8|vp9 (default: h264)\n  --background   Background image file path (if omitted, uses animated gradient)\n  --browser      Custom browser executable path (Chrome/Edge/Chromium)\n  --max-size     Max output file size in MB (e.g. 24). Auto-compresses if exceeded.\n                 Use for IM platforms (WhatsApp≤16MB, Discord≤25MB, Telegram≤50MB)\n\nEnvironment variables:\n  BROWSER_EXECUTABLE  Path to browser executable (overrides auto-detection)\n```\n\n## Browser Detection\n\nRemotion requires a Chromium-based browser for rendering. The script auto-detects browsers in this priority order:\n\n1. `BROWSER_EXECUTABLE` environment variable\n2. `--browser` CLI argument\n3. Remotion cache (`chrome-headless-shell`, downloaded by Remotion)\n4. System Chrome (auto-uses `--chrome-mode=chrome-for-testing`)\n5. **System Edge** (pre-installed on Windows 10/11, auto-uses `--chrome-mode=chrome-for-testing`)\n6. System Chromium (auto-uses `--chrome-mode=chrome-for-testing`)\n\n**Important**: New versions of Chrome/Edge removed the old headless mode. When using regular Chrome/Edge/Chromium, the script automatically sets `--chrome-mode=chrome-for-testing` (which uses `--headless=new`). When using `chrome-headless-shell`, it uses the default `headless-shell` mode (which uses `--headless=old`). This is handled transparently.\n\nIf no browser is found, Remotion will attempt to download `chrome-headless-shell` from Google servers. **This will fail if Google servers are inaccessible from your network.**\n\n### Workarounds for restricted networks\n\nSince **Edge is pre-installed on Windows 10/11**, it should be auto-detected without any manual configuration. The script automatically detects Chrome/Edge and uses the correct headless mode. If auto-detection fails:\n\n```bash\n# Option 1: Set environment variable\nexport BROWSER_EXECUTABLE=\"/path/to/msedge.exe\"\n\n# Option 2: Pass as CLI argument\n./scripts/render-mv.sh --audio song.mp3 --lyrics song.lrc --title \"Song\" --browser \"/path/to/msedge.exe\"\n\n# Option 3: Enable proxy and let Remotion download chrome-headless-shell\n```\n\n## Examples\n\n```bash\n# Basic render\n./scripts/render-mv.sh --audio /tmp/abc123_1.mp3 --lyrics /tmp/abc123.lrc --title \"夜桜\"\n\n# Custom output path\n./scripts/render-mv.sh --audio song.mp3 --lyrics song.lrc --title \"My Song\" --output /tmp/my_mv.mp4\n\n# With subtitle and credit\n./scripts/render-mv.sh --audio song.mp3 --lyrics song.lrc --title \"Song\" --subtitle \"Artist Name\" --credit \"Generated by ACE-Step\"\n\n# With background image\n./scripts/render-mv.sh --audio song.mp3 --lyrics song.lrc --title \"Song\" --background /path/to/cover.jpg\n\n# Compress for Discord upload (max 25MB)\n./scripts/render-mv.sh --audio song.mp3 --lyrics song.lrc --title \"Song\" --max-size 24\n\n# Compress for WhatsApp (max 16MB)\n./scripts/render-mv.sh --audio song.mp3 --lyrics song.lrc --title \"Song\" --max-size 15\n```\n\n## IM Platform Upload Limits\n\nWhen sending MV to chat platforms, use `--max-size` to auto-compress:\n\n| Platform | Limit | Recommended `--max-size` |\n|----------|-------|--------------------------|\n| WhatsApp | 16MB | 10 |\n| Discord (free) | 25MB | 10 |\n| QQ | 10MB | 10 |\n| Telegram | 50MB | 20 |\n| Slack (free) | 1GB | - |\n\nThe compression uses ffmpeg two-pass encoding to achieve the best quality within the size constraint.\n\n## Container / Docker Font Support\n\nWhen running in containers (e.g. OpenClaw), CJK fonts may not be pre-installed, causing lyrics to render as □ boxes. The script automatically:\n\n1. **Detects** if CJK fonts are available (via `fc-list`)\n2. **Attempts to install** `fonts-noto-cjk` (Debian/Ubuntu), `font-noto-cjk` (Alpine), or `google-noto-sans-cjk-fonts` (Fedora/RHEL)\n3. **Falls back** with a warning and manual install instructions if auto-install fails\n\nIf auto-install doesn't work, manually install fonts before rendering:\n```bash\n# Debian/Ubuntu\napt-get install -y fonts-noto-cjk\n\n# Alpine\napk add font-noto-cjk\n\n# Fedora/RHEL\ndnf install -y google-noto-sans-cjk-fonts\n```\n\n## File Naming\n\n**IMPORTANT**: Use the audio file's job ID as the output filename to avoid overwriting. Do NOT use custom names like `--output my_song.mp4`. Let the default naming handle it (derives from audio filename).\n\nDefault output uses the audio filename as base:\n- Audio: `acestep_output/{job_id}_1.mp3`\n- Lyrics: `acestep_output/{job_id}_1.lrc`\n- Video: Pass `--output acestep_output/{job_id}.mp4` (use the job ID from the audio file)\n\nExample: if audio is `chatcmpl-abc123_1.mp3`, pass `--output acestep_output/chatcmpl-abc123.mp4`\n\n## Title Guidelines\n\n- Keep `--title` short and single-line (max ~50 chars, auto-truncated)\n- Use `--subtitle` for additional info\n- Do NOT put newlines in `--title`\n\nGood: `--title \"Open Source\" --subtitle \"ACE-Step v1.5\"`\nBad: `--title \"Open Source - ACE-Step v1.5\\nCelebrating Music AI\"`\n\n## Notes\n\n- Audio files with absolute paths are auto-copied to `public/` by render.mjs\n- Duration is auto-detected via ffprobe\n- Typical render time: ~1-2 minutes for a 90s song\n- Output resolution: 1920x1080, 30fps\n"
  },
  {
    "path": ".claude/skills/acestep-simplemv/scripts/package.json",
    "content": "{\n  \"name\": \"acestep-video\",\n  \"version\": \"1.0.0\",\n  \"description\": \"\",\n  \"main\": \"index.js\",\n  \"scripts\": {\n    \"start\": \"remotion preview\",\n    \"build\": \"remotion render MusicVideo out/video.mp4\",\n    \"render\": \"node render.mjs\",\n    \"upgrade\": \"remotion upgrade\"\n  },\n  \"keywords\": [],\n  \"author\": \"\",\n  \"license\": \"ISC\",\n  \"type\": \"commonjs\",\n  \"dependencies\": {\n    \"@remotion/cli\": \"^4.0.417\",\n    \"@remotion/media-utils\": \"^4.0.417\",\n    \"react\": \"^18.3.1\",\n    \"react-dom\": \"^18.3.1\",\n    \"remotion\": \"^4.0.417\"\n  },\n  \"devDependencies\": {\n    \"@types/react\": \"^19.2.13\",\n    \"typescript\": \"^5.9.3\"\n  }\n}\n"
  },
  {
    "path": ".claude/skills/acestep-simplemv/scripts/remotion.config.ts",
    "content": "import {Config} from '@remotion/cli/config';\n\nConfig.setVideoImageFormat('jpeg');\nConfig.setOverwriteOutput(true);\n"
  },
  {
    "path": ".claude/skills/acestep-simplemv/scripts/render-mv.sh",
    "content": "#!/bin/bash\n# render-mv.sh - Render a music video from audio + lyrics\n#\n# Usage:\n#   ./render-mv.sh --audio <file> --lyrics <lrc_file> --title \"Title\" [options]\n#\n# Options:\n#   --audio     Audio file path (absolute or relative)\n#   --lyrics    LRC format lyrics file\n#   --lyrics-json  JSON lyrics file [{start, end, text}]\n#   --title     Video title (default: \"Music Video\")\n#   --subtitle  Subtitle text\n#   --credit    Bottom credit text\n#   --offset    Lyric timing offset in seconds (default: -0.5)\n#   --output    Output file path (default: acestep_output/<audio_basename>.mp4)\n#   --codec     h264|h265|vp8|vp9 (default: h264)\n#   --background Background image file path (if omitted, uses animated gradient)\n#   --browser   Custom browser executable path (Chrome/Edge/Chromium)\n#   --max-size  Max output file size in MB (e.g. 24). Compresses video if exceeded.\n#              Use for IM platforms (WhatsApp/Discord/Telegram) with upload limits.\n#\n# Environment variables:\n#   BROWSER_EXECUTABLE  Path to browser executable (overrides auto-detection)\n#\n# Examples:\n#   ./render-mv.sh --audio song.mp3 --lyrics song.lrc --title \"My Song\"\n#   ./render-mv.sh --audio /path/to/abc123_1.mp3 --lyrics /path/to/abc123.lrc --title \"夜桜\"\n\nset -euo pipefail\n\nRENDER_DIR=\"$(cd \"$(dirname \"$0\")\" && pwd)\"\n\n# Ensure output directory exists\nmkdir -p \"${RENDER_DIR}/out\"\n\n# Cross-platform realpath alternative (works on macOS/Linux/Windows MSYS2)\nresolve_path() {\n  local dir base\n  dir=\"$(cd \"$(dirname \"$1\")\" && pwd)\"\n  base=\"$(basename \"$1\")\"\n  echo \"${dir}/${base}\"\n}\n\nAUDIO=\"\"\nLYRICS=\"\"\nLYRICS_JSON=\"\"\nTITLE=\"Music Video\"\nSUBTITLE=\"\"\nCREDIT=\"\"\nOFFSET=\"-0.5\"\nOUTPUT=\"\"\nCODEC=\"h264\"\nBACKGROUND=\"\"\nBROWSER=\"\"\nMAX_SIZE=\"\"\n\n# Parse args\nwhile [[ $# -gt 0 ]]; do\n  case \"$1\" in\n    --audio)       AUDIO=\"$2\"; shift 2 ;;\n    --lyrics)      LYRICS=\"$2\"; shift 2 ;;\n    --lyrics-json) LYRICS_JSON=\"$2\"; shift 2 ;;\n    --title)       TITLE=\"$2\"; shift 2 ;;\n    --subtitle)    SUBTITLE=\"$2\"; shift 2 ;;\n    --credit)      CREDIT=\"$2\"; shift 2 ;;\n    --offset)      OFFSET=\"$2\"; shift 2 ;;\n    --output)      OUTPUT=\"$2\"; shift 2 ;;\n    --codec)       CODEC=\"$2\"; shift 2 ;;\n    --background)  BACKGROUND=\"$2\"; shift 2 ;;\n    --browser)     BROWSER=\"$2\"; shift 2 ;;\n    --max-size)    MAX_SIZE=\"$2\"; shift 2 ;;\n    -h|--help)\n      head -20 \"$0\" | tail -18\n      exit 0\n      ;;\n    *)\n      echo \"Error: unknown argument: $1\" >&2\n      exit 1\n      ;;\n  esac\ndone\n\nif [[ -z \"$AUDIO\" ]]; then\n  echo \"Error: --audio is required\" >&2\n  exit 1\nfi\n\nif [[ ! -f \"$AUDIO\" ]]; then\n  echo \"Error: audio file not found: $AUDIO\" >&2\n  exit 1\nfi\n\n# Resolve absolute path for audio\nAUDIO=\"$(resolve_path \"$AUDIO\")\"\n\n# Default output: acestep_output/<audio_basename>.mp4\nif [[ -z \"$OUTPUT\" ]]; then\n  BASENAME=\"$(basename \"${AUDIO%.*}\")\"\n  # Strip trailing _1, _2 etc from audio filename for cleaner video name\n  OUTPUT=\"${RENDER_DIR}/out/${BASENAME}.mp4\"\nfi\n\n# Ensure output directory exists\nmkdir -p \"$(dirname \"$OUTPUT\")\"\n\n# Build node args array (safe quoting, no eval)\nNODE_ARGS=(render.mjs --audio \"$AUDIO\" --title \"$TITLE\" --offset \"$OFFSET\" --output \"$OUTPUT\" --codec \"$CODEC\")\n\nif [[ -n \"$LYRICS\" ]]; then\n  LYRICS=\"$(resolve_path \"$LYRICS\")\"\n  NODE_ARGS+=(--lyrics \"$LYRICS\")\nelif [[ -n \"$LYRICS_JSON\" ]]; then\n  LYRICS_JSON=\"$(resolve_path \"$LYRICS_JSON\")\"\n  NODE_ARGS+=(--lyrics-json \"$LYRICS_JSON\")\nfi\n\n[[ -n \"$SUBTITLE\" ]] && NODE_ARGS+=(--subtitle \"$SUBTITLE\")\n[[ -n \"$CREDIT\" ]] && NODE_ARGS+=(--credit \"$CREDIT\")\nif [[ -n \"$BACKGROUND\" ]]; then\n  BACKGROUND=\"$(resolve_path \"$BACKGROUND\")\"\n  NODE_ARGS+=(--background \"$BACKGROUND\")\nfi\n[[ -n \"$BROWSER\" ]] && NODE_ARGS+=(--browser \"$BROWSER\")\n\n# --- Font check for container environments ---\ncheck_and_install_cjk_fonts() {\n  # Only run on Linux (containers are typically Linux)\n  [[ \"$(uname -s)\" != \"Linux\" ]] && return 0\n\n  # Check if any CJK font is available via fc-list\n  if command -v fc-list &>/dev/null; then\n    if fc-list :lang=zh 2>/dev/null | head -1 | grep -q .; then\n      return 0  # CJK fonts found\n    fi\n    if fc-list :lang=ja 2>/dev/null | head -1 | grep -q .; then\n      return 0  # Japanese fonts found\n    fi\n  fi\n\n  echo \"⚠️  No CJK fonts detected. Non-ASCII lyrics may render as □ boxes.\"\n\n  # Attempt to install fonts-noto-cjk (works on Debian/Ubuntu containers)\n  if command -v apt-get &>/dev/null; then\n    echo \"   Attempting to install fonts-noto-cjk...\"\n    if apt-get update -qq &>/dev/null && apt-get install -y -qq fonts-noto-cjk &>/dev/null; then\n      # Refresh font cache\n      command -v fc-cache &>/dev/null && fc-cache -f &>/dev/null\n      echo \"   ✅ CJK fonts installed successfully.\"\n      return 0\n    else\n      echo \"   ⚠️  Failed to install fonts (may need root/sudo). Trying sudo...\"\n      if sudo apt-get update -qq &>/dev/null && sudo apt-get install -y -qq fonts-noto-cjk &>/dev/null; then\n        command -v fc-cache &>/dev/null && fc-cache -f &>/dev/null\n        echo \"   ✅ CJK fonts installed successfully.\"\n        return 0\n      fi\n    fi\n  elif command -v apk &>/dev/null; then\n    # Alpine Linux containers\n    echo \"   Attempting to install font-noto-cjk (Alpine)...\"\n    if apk add --no-cache font-noto-cjk &>/dev/null; then\n      command -v fc-cache &>/dev/null && fc-cache -f &>/dev/null\n      echo \"   ✅ CJK fonts installed successfully.\"\n      return 0\n    fi\n  elif command -v dnf &>/dev/null; then\n    echo \"   Attempting to install google-noto-sans-cjk-fonts (dnf)...\"\n    if dnf install -y -q google-noto-sans-cjk-fonts &>/dev/null; then\n      command -v fc-cache &>/dev/null && fc-cache -f &>/dev/null\n      echo \"   ✅ CJK fonts installed successfully.\"\n      return 0\n    fi\n  fi\n\n  echo \"   ⚠️  Could not auto-install CJK fonts. Please install manually:\"\n  echo \"      Debian/Ubuntu: apt-get install fonts-noto-cjk\"\n  echo \"      Alpine: apk add font-noto-cjk\"\n  echo \"      Fedora/RHEL: dnf install google-noto-sans-cjk-fonts\"\n  return 1\n}\n\ncheck_and_install_cjk_fonts\n\n# --- Render ---\necho \"Rendering MV...\"\necho \"  Audio: $(basename \"$AUDIO\")\"\necho \"  Title: $TITLE\"\necho \"  Output: $OUTPUT\"\n\ncd \"$RENDER_DIR\"\nnode \"${NODE_ARGS[@]}\"\n\n# --- Post-render: compress if --max-size is set ---\nif [[ -n \"$MAX_SIZE\" && -f \"$OUTPUT\" ]]; then\n  FILE_SIZE_BYTES=$(stat -f%z \"$OUTPUT\" 2>/dev/null || stat -c%s \"$OUTPUT\" 2>/dev/null || echo 0)\n  MAX_SIZE_BYTES=$((MAX_SIZE * 1024 * 1024))\n\n  if [[ \"$FILE_SIZE_BYTES\" -gt \"$MAX_SIZE_BYTES\" ]]; then\n    echo \"\"\n    echo \"Video size $(( FILE_SIZE_BYTES / 1024 / 1024 ))MB exceeds ${MAX_SIZE}MB limit. Compressing...\"\n\n    COMPRESSED=\"${OUTPUT%.mp4}_compressed.mp4\"\n\n    # Calculate target total bitrate (bits/s) from max size and duration\n    DURATION=$(ffprobe -v error -show_entries format=duration -of csv=p=0 \"$OUTPUT\" 2>/dev/null)\n    if [[ -z \"$DURATION\" || \"$DURATION\" == \"N/A\" ]]; then\n      echo \"Error: Cannot determine video duration for compression.\" >&2\n      exit 1\n    fi\n\n    # Target bitrate = (max_size_bytes * 8) / duration * 0.95 safety margin\n    # Use bc for floating point, fallback to awk\n    TARGET_BITRATE=$(awk \"BEGIN { printf \\\"%d\\\", ($MAX_SIZE_BYTES * 8 / $DURATION) * 0.95 }\")\n    AUDIO_BITRATE=96000  # 96k audio\n    VIDEO_BITRATE=$((TARGET_BITRATE - AUDIO_BITRATE))\n\n    if [[ \"$VIDEO_BITRATE\" -lt 100000 ]]; then\n      echo \"Error: Target size too small for this video duration.\" >&2\n      exit 1\n    fi\n\n    echo \"  Target video bitrate: $((VIDEO_BITRATE / 1000))kbps\"\n\n    # Two-pass encoding for best quality at target size\n    ffmpeg -y -i \"$OUTPUT\" \\\n      -c:v libx264 -b:v \"${VIDEO_BITRATE}\" -pass 1 \\\n      -preset medium -an -f null /dev/null 2>/dev/null\n\n    ffmpeg -y -i \"$OUTPUT\" \\\n      -c:v libx264 -b:v \"${VIDEO_BITRATE}\" -pass 2 \\\n      -preset medium -c:a aac -b:a 96k \\\n      -movflags +faststart \\\n      \"$COMPRESSED\" 2>/dev/null\n\n    # Clean up two-pass log files\n    rm -f ffmpeg2pass-0.log ffmpeg2pass-0.log.mbtree\n\n    if [[ -f \"$COMPRESSED\" ]]; then\n      COMP_SIZE=$(stat -f%z \"$COMPRESSED\" 2>/dev/null || stat -c%s \"$COMPRESSED\" 2>/dev/null || echo 0)\n      echo \"  Compressed: $(( COMP_SIZE / 1024 / 1024 ))MB (was $(( FILE_SIZE_BYTES / 1024 / 1024 ))MB)\"\n\n      # Replace original with compressed\n      mv \"$COMPRESSED\" \"$OUTPUT\"\n      echo \"  ✅ Compressed video saved to: $OUTPUT\"\n    else\n      echo \"  ⚠️  Compression failed, keeping original file.\"\n    fi\n  else\n    echo \"Video size $(( FILE_SIZE_BYTES / 1024 / 1024 ))MB is within ${MAX_SIZE}MB limit. No compression needed.\"\n  fi\nfi\n\necho \"\"\necho \"Output: $OUTPUT\"\n"
  },
  {
    "path": ".claude/skills/acestep-simplemv/scripts/render.mjs",
    "content": "#!/usr/bin/env node\n\n/**\n * CLI entry point for rendering music videos.\n * \n * Usage:\n *   node render.mjs --audio music.mp3 --lyrics lyrics.lrc --title \"Song Name\" --output out/video.mp4\n *   node render.mjs --audio music.mp3 --lyrics-json lyrics.json --title \"Song Name\"\n * \n * Options:\n *   --audio        Audio file path (absolute paths auto-copied to public/) or filename in public/\n *   --lyrics       Path to LRC format lyrics file\n *   --lyrics-json  Path to JSON lyrics file [{start, end, text}]\n *   --title        Main title (default: \"Music Video\")\n *   --subtitle     Subtitle (default: \"\")\n *   --credit       Bottom credit text (default: \"\")\n *   --duration     Audio duration in seconds (auto-detected if omitted)\n *   --offset       Lyric timing offset in seconds (default: -0.5)\n *   --output       Output file path (default: out/video.mp4)\n *   --codec        Video codec: h264, h265, vp8, vp9 (default: h264)\n *   --background   Background image file path (if omitted, uses animated gradient)\n */\n\nimport {execSync} from 'child_process';\nimport {readFileSync, readdirSync, existsSync, copyFileSync, mkdirSync} from 'fs';\nimport {resolve, basename, isAbsolute, join} from 'path';\nimport {homedir} from 'os';\n\n/**\n * Resolve a file path that may be a MSYS2/Cygwin-style path on Windows.\n * Converts paths like /e/foo/bar to E:/foo/bar for Node.js compatibility.\n */\nfunction resolveFilePath(p) {\n  if (process.platform === 'win32' && /^\\/[a-zA-Z]\\//.test(p)) {\n    // Convert MSYS2 path /x/... to X:/...\n    return p[1].toUpperCase() + ':' + p.slice(2);\n  }\n  return resolve(p);\n}\n\n/**\n * Find a usable browser executable for Remotion rendering.\n *\n * Search priority:\n *   1. Environment variable BROWSER_EXECUTABLE\n *   2. CLI argument --browser\n *   3. Remotion cache (chrome-headless-shell)\n *   4. System Chrome (requires --chrome-mode=chrome-for-testing)\n *   5. System Edge (requires --chrome-mode=chrome-for-testing)\n *   6. System Chromium (requires --chrome-mode=chrome-for-testing)\n *\n * Returns {path, chromeMode} or {path: null, chromeMode: 'headless-shell'} if not found.\n *\n * chromeMode:\n *   - 'headless-shell': for chrome-headless-shell binary (uses --headless=old)\n *   - 'chrome-for-testing': for regular Chrome/Edge/Chromium (uses --headless=new)\n */\nfunction findBrowserExecutable(cliOverride) {\n  // 1. Environment variable — highest priority\n  const envExe = process.env.BROWSER_EXECUTABLE;\n  if (envExe && existsSync(envExe)) {\n    const mode = isHeadlessShell(envExe) ? 'headless-shell' : 'chrome-for-testing';\n    return {path: envExe, chromeMode: mode};\n  }\n\n  // 2. CLI argument\n  if (cliOverride && existsSync(cliOverride)) {\n    const mode = isHeadlessShell(cliOverride) ? 'headless-shell' : 'chrome-for-testing';\n    return {path: cliOverride, chromeMode: mode};\n  }\n\n  const platform = process.platform;\n  const home = homedir();\n\n  // 3. Local node_modules/.remotion (chrome-headless-shell) — uses --headless=old\n  const localCacheDir = join(process.cwd(), 'node_modules', '.remotion', 'chrome-headless-shell');\n  if (existsSync(localCacheDir)) {\n    try {\n      // Structure: chrome-headless-shell/linux64/chrome-headless-shell-linux64/chrome-headless-shell\n      const platformDir = platform === 'win32' ? 'win64' : platform === 'darwin' ? 'mac-arm64' : 'linux64';\n      const exeName = platform === 'win32' ? 'chrome-headless-shell.exe' : 'chrome-headless-shell';\n      const platformPath = join(localCacheDir, platformDir);\n\n      if (existsSync(platformPath)) {\n        const subdirs = readdirSync(platformPath);\n        for (const subdir of subdirs) {\n          const exe = join(platformPath, subdir, exeName);\n          if (existsSync(exe)) return {path: exe, chromeMode: 'headless-shell'};\n        }\n      }\n    } catch {}\n  }\n\n  // 4. User home Remotion cache (chrome-headless-shell) — uses --headless=old\n  let cacheDir;\n  if (platform === 'win32') {\n    cacheDir = join(home, 'AppData', 'Local', 'remotion', 'chrome-headless-shell');\n  } else if (platform === 'darwin') {\n    cacheDir = join(home, 'Library', 'Caches', 'remotion', 'chrome-headless-shell');\n  } else {\n    cacheDir = join(home, '.cache', 'remotion', 'chrome-headless-shell');\n  }\n\n  if (existsSync(cacheDir)) {\n    try {\n      const versions = readdirSync(cacheDir).sort().reverse();\n      const exeName = platform === 'win32' ? 'chrome-headless-shell.exe' : 'chrome-headless-shell';\n      for (const ver of versions) {\n        const exe = join(cacheDir, ver, exeName);\n        if (existsSync(exe)) return {path: exe, chromeMode: 'headless-shell'};\n      }\n    } catch {}\n  }\n\n  // 4-6. System browsers: Chrome, Edge, Chromium — require --chrome-mode=chrome-for-testing\n  const browserPaths = platform === 'win32' ? [\n    // Chrome\n    'C:\\\\Program Files\\\\Google\\\\Chrome\\\\Application\\\\chrome.exe',\n    'C:\\\\Program Files (x86)\\\\Google\\\\Chrome\\\\Application\\\\chrome.exe',\n    // Edge (pre-installed on Windows 10/11)\n    'C:\\\\Program Files (x86)\\\\Microsoft\\\\Edge\\\\Application\\\\msedge.exe',\n    'C:\\\\Program Files\\\\Microsoft\\\\Edge\\\\Application\\\\msedge.exe',\n  ] : platform === 'darwin' ? [\n    '/Applications/Google Chrome.app/Contents/MacOS/Google Chrome',\n    '/Applications/Microsoft Edge.app/Contents/MacOS/Microsoft Edge',\n    '/Applications/Chromium.app/Contents/MacOS/Chromium',\n  ] : [\n    '/usr/bin/google-chrome',\n    '/usr/bin/google-chrome-stable',\n    '/usr/bin/chromium',\n    '/usr/bin/chromium-browser',\n    '/usr/bin/microsoft-edge',\n    '/usr/bin/microsoft-edge-stable',\n  ];\n\n  for (const p of browserPaths) {\n    if (existsSync(p)) return {path: p, chromeMode: 'chrome-for-testing'};\n  }\n\n  return {path: null, chromeMode: 'headless-shell'};\n}\n\n/**\n * Check if the given executable path is a chrome-headless-shell binary.\n */\nfunction isHeadlessShell(exePath) {\n  const name = exePath.toLowerCase().replace(/\\\\/g, '/');\n  return name.includes('chrome-headless-shell');\n}\n\nfunction parseLrc(content) {\n  const lines = content.split(/\\r?\\n/).filter(l => l.trim());\n  const parsed = [];\n  for (const line of lines) {\n    const match = line.match(/^\\[(\\d{2}):(\\d{2})(?:\\.(\\d{2,3}))?\\]\\s*(.*)$/);\n    if (match) {\n      const minutes = parseInt(match[1], 10);\n      const seconds = parseInt(match[2], 10);\n      const cs = match[3] ? parseInt(match[3].padEnd(3, '0'), 10) / 1000 : 0;\n      const time = minutes * 60 + seconds + cs;\n      const text = match[4].trim();\n      parsed.push({time, text});\n    }\n  }\n  const result = [];\n  for (let i = 0; i < parsed.length; i++) {\n    const start = parsed[i].time;\n    const end = i < parsed.length - 1 ? parsed[i + 1].time : start + 5;\n    if (parsed[i].text) {\n      result.push({start, end, text: parsed[i].text});\n    }\n  }\n  return result;\n}\n\nfunction getAudioDuration(filePath) {\n  try {\n    const result = execSync(\n      `ffprobe -v error -show_entries format=duration -of csv=p=0 \"${filePath}\"`,\n      {encoding: 'utf-8'}\n    ).trim();\n    return parseFloat(result);\n  } catch {\n    return null;\n  }\n}\n\nfunction parseArgs(argv) {\n  const args = {};\n  for (let i = 2; i < argv.length; i++) {\n    const key = argv[i];\n    if (key.startsWith('--') && i + 1 < argv.length) {\n      const name = key.slice(2);\n      args[name] = argv[i + 1];\n      i++;\n    }\n  }\n  return args;\n}\n\nconst args = parseArgs(process.argv);\n\n// Validate required args\nif (!args.audio) {\n  console.error('Error: --audio is required');\n  console.error('Usage: node render.mjs --audio music.mp3 --lyrics lyrics.lrc --title \"Song\"');\n  process.exit(1);\n}\n\n// If audio is an absolute path, copy it into public/ and use the filename\nlet audioFileName = args.audio;\nconst resolvedAudio = resolveFilePath(args.audio);\nif (isAbsolute(resolvedAudio)) {\n  if (!existsSync(resolvedAudio)) {\n    console.error(`Error: Audio file not found: ${resolvedAudio}`);\n    process.exit(1);\n  }\n  const pubDir = resolve('public');\n  mkdirSync(pubDir, {recursive: true});\n  const fname = basename(resolvedAudio);\n  const dest = resolve(pubDir, fname);\n  if (resolve(resolvedAudio) !== dest) {\n    copyFileSync(resolvedAudio, dest);\n    console.log(`Copied audio to public/${fname}`);\n  }\n  audioFileName = fname;\n} else {\n  // Relative name — must exist in public/\n  const audioPath = resolve('public', args.audio);\n  if (!existsSync(audioPath)) {\n    console.error(`Error: Audio file not found in public/: ${args.audio}`);\n    process.exit(1);\n  }\n}\n\n// Parse lyrics\nlet lyrics = [];\nif (args.lyrics) {\n  const lrcPath = resolveFilePath(args.lyrics);\n  if (!existsSync(lrcPath)) {\n    console.error(`Error: LRC file not found: ${lrcPath}`);\n    process.exit(1);\n  }\n  lyrics = parseLrc(readFileSync(lrcPath, 'utf-8'));\n  console.log(`Parsed ${lyrics.length} lyric lines from LRC file`);\n} else if (args['lyrics-json']) {\n  const jsonPath = resolveFilePath(args['lyrics-json']);\n  if (!existsSync(jsonPath)) {\n    console.error(`Error: JSON lyrics file not found: ${jsonPath}`);\n    process.exit(1);\n  }\n  lyrics = JSON.parse(readFileSync(jsonPath, 'utf-8'));\n  console.log(`Loaded ${lyrics.length} lyric lines from JSON file`);\n}\n\n// Handle background image\nlet backgroundImage = '';\nif (args.background) {\n  const resolvedBg = resolveFilePath(args.background);\n  if (!existsSync(resolvedBg)) {\n    console.error(`Error: Background image not found: ${resolvedBg}`);\n    process.exit(1);\n  }\n  const pubDir = resolve('public');\n  mkdirSync(pubDir, {recursive: true});\n  const bgName = basename(resolvedBg);\n  const bgDest = resolve(pubDir, bgName);\n  if (resolve(resolvedBg) !== bgDest) {\n    copyFileSync(resolvedBg, bgDest);\n    console.log(`Copied background image to public/${bgName}`);\n  }\n  backgroundImage = bgName;\n}\n\n// Determine audio duration\nlet duration = args.duration ? parseFloat(args.duration) : null;\nif (!duration) {\n  const audioPath = resolve('public', audioFileName);\n  if (existsSync(audioPath)) {\n    duration = getAudioDuration(audioPath);\n    if (duration) {\n      console.log(`Auto-detected audio duration: ${duration.toFixed(2)}s`);\n    }\n  }\n}\nif (!duration) {\n  console.error('Error: Could not detect audio duration. Please provide --duration');\n  process.exit(1);\n}\n\n// Build input props\n// Sanitize title: single-line, max 50 chars\nconst rawTitle = (args.title || 'Music Video').replace(/[\\r\\n]+/g, ' ').trim();\nconst title = rawTitle.length > 50 ? rawTitle.slice(0, 47) + '...' : rawTitle;\n\nconst inputProps = {\n  audioFileName: audioFileName,\n  lyrics,\n  title,\n  subtitle: (args.subtitle || '').replace(/[\\r\\n]+/g, ' ').trim(),\n  creditText: args.credit || '',\n  durationInSeconds: duration,\n  lyricOffset: args.offset ? parseFloat(args.offset) : -0.5,\n  backgroundImage,\n};\n\nconst output = args.output ? resolveFilePath(args.output) : 'out/video.mp4';\nconst codec = args.codec || 'h264';\n\n// Write props to temp file to avoid shell escaping issues\nconst propsFile = resolve('.render-props.json');\nconst {writeFileSync} = await import('fs');\nwriteFileSync(propsFile, JSON.stringify(inputProps));\n\n// Find browser executable to avoid re-downloading\nconst {path: browserExe, chromeMode} = findBrowserExecutable(args.browser);\n\nif (!browserExe) {\n  console.warn('⚠️  No browser found. Remotion will attempt to download chrome-headless-shell from Google servers.');\n  console.warn('   If download fails (e.g. Google servers inaccessible), try one of these:');\n  console.warn('   1. Set environment variable: BROWSER_EXECUTABLE=/path/to/chrome-or-edge');\n  console.warn('   2. Pass CLI argument: --browser /path/to/chrome-or-edge');\n  console.warn('   3. Enable proxy and retry');\n  console.warn('');\n}\n\nconst cmd = [\n  'npx remotion render',\n  'MusicVideo',\n  `\"${output}\"`,\n  `--props=\"${propsFile}\"`,\n  `--codec=${codec}`,\n  '--log=error',\n  browserExe ? `--browser-executable=\"${browserExe}\"` : '',\n  chromeMode !== 'headless-shell' ? `--chrome-mode=${chromeMode}` : '',\n].filter(Boolean).join(' ');\n\nconsole.log(`\\nRendering video...`);\nconsole.log(`  Audio: ${args.audio}`);\nconsole.log(`  Title: ${inputProps.title}`);\nconsole.log(`  Duration: ${duration.toFixed(1)}s`);\nconsole.log(`  Lyrics: ${lyrics.length} lines`);\nconsole.log(`  Output: ${output}`);\nconsole.log(`  Codec: ${codec}`);\nif (backgroundImage) console.log(`  Background: ${backgroundImage}`);\nif (browserExe) console.log(`  Browser: ${browserExe}`);\nif (chromeMode !== 'headless-shell') console.log(`  Chrome mode: ${chromeMode}`);\nconsole.log('');\n\ntry {\n  const result = execSync(cmd, {encoding: 'utf-8', stdio: ['pipe', 'pipe', 'pipe']});\n  // Only show the final output file line (starts with '+') and size info\n  const outputLines = result.split(/\\r?\\n/).filter(l => l.includes(output) || /^\\+/.test(l.replace(/\\x1b\\[[0-9;]*m/g, '').trim()));\n  if (outputLines.length) console.log(outputLines.join('\\n'));\n  console.log(`\\n✅ Video rendered successfully: ${output}`);\n} catch (e) {\n  // Show stderr on failure for debugging\n  if (e.stderr) console.error(e.stderr.toString());\n  console.error('\\n❌ Render failed');\n  process.exit(1);\n} finally {\n  // Clean up temp props file\n  try {\n    const {unlinkSync} = await import('fs');\n    unlinkSync(propsFile);\n  } catch {}\n}\n"
  },
  {
    "path": ".claude/skills/acestep-simplemv/scripts/render.sh",
    "content": "#!/bin/bash\n# render.sh - Convenience wrapper for rendering music videos\n#\n# Usage:\n#   ./render.sh --audio music.mp3 --lyrics lyrics.lrc --title \"Song Name\"\n#   ./render.sh --audio music.mp3 --lyrics-json lyrics.json --title \"Song\" --output out/mv.mp4\n#\n# All options are passed through to render.mjs. See render.mjs for full options list.\n\nset -e\ncd \"$(dirname \"$0\")\"\nnode render.mjs \"$@\"\n"
  },
  {
    "path": ".claude/skills/acestep-simplemv/scripts/src/AudioVisualization.tsx",
    "content": "import React from 'react';\nimport {\n  AbsoluteFill,\n  Audio,\n  Img,\n  useCurrentFrame,\n  useVideoConfig,\n  interpolate,\n  Easing,\n  staticFile,\n} from 'remotion';\nimport {useAudioData, visualizeAudio} from '@remotion/media-utils';\nimport {MVInputProps} from './types';\n\nexport const AudioVisualization: React.FC<MVInputProps> = ({\n  audioFileName,\n  lyrics,\n  title,\n  subtitle,\n  creditText,\n  lyricOffset,\n  backgroundImage,\n}) => {\n  const frame = useCurrentFrame();\n  const {fps, durationInFrames} = useVideoConfig();\n\n  const audioSrc = audioFileName.startsWith('http')\n    ? audioFileName\n    : staticFile(audioFileName);\n\n  const audioData = useAudioData(audioSrc);\n\n  if (!audioData) {\n    return null;\n  }\n\n  const visualization = visualizeAudio({\n    fps,\n    frame,\n    audioData,\n    numberOfSamples: 128,\n    optimizeFor: 'speed',\n  });\n\n  const currentTime = frame / fps + lyricOffset;\n\n  const currentLyric = lyrics.find(\n    (lyric) => currentTime >= lyric.start && currentTime < lyric.end\n  );\n\n  const lyricProgress = currentLyric\n    ? interpolate(\n        currentTime,\n        [currentLyric.start, currentLyric.start + 0.3],\n        [0, 1],\n        {extrapolateRight: 'clamp'}\n      )\n    : 0;\n\n  const titleOpacity = interpolate(frame, [0, 30], [0, 1], {\n    extrapolateRight: 'clamp',\n  });\n\n  const titleY = interpolate(frame, [0, 30], [-50, 0], {\n    extrapolateRight: 'clamp',\n    easing: Easing.out(Easing.ease),\n  });\n\n  const hue = interpolate(frame, [0, durationInFrames], [200, 320], {\n    extrapolateRight: 'wrap',\n  });\n\n  const avgAmplitude =\n    visualization.reduce((sum, val) => sum + val, 0) / visualization.length;\n\n  const bgSrc = backgroundImage\n    ? backgroundImage.startsWith('http')\n      ? backgroundImage\n      : staticFile(backgroundImage)\n    : '';\n\n  return (\n    <AbsoluteFill>\n      {/* Background: image or animated gradient */}\n      {bgSrc ? (\n        <>\n          <AbsoluteFill>\n            <Img\n              src={bgSrc}\n              style={{\n                width: '100%',\n                height: '100%',\n                objectFit: 'cover',\n              }}\n            />\n          </AbsoluteFill>\n          {/* Dark overlay for readability */}\n          <AbsoluteFill\n            style={{\n              background: `rgba(0, 0, 0, 0.45)`,\n            }}\n          />\n        </>\n      ) : (\n        <>\n          <AbsoluteFill\n            style={{\n              background: `linear-gradient(135deg, hsl(${hue}, 80%, 12%) 0%, hsl(${hue + 80}, 70%, 8%) 100%)`,\n            }}\n          />\n        </>\n      )}\n\n      {/* Radial glow effect */}\n      <AbsoluteFill\n        style={{\n          background: `radial-gradient(circle at 50% 50%, hsla(${hue}, 100%, 50%, ${avgAmplitude * 0.3}) 0%, transparent 50%)`,\n        }}\n      />\n\n      {/* Audio source */}\n      <Audio src={audioSrc} />\n\n      {/* Bottom frequency bars */}\n      <AbsoluteFill\n        style={{\n          justifyContent: 'flex-end',\n          alignItems: 'center',\n        }}\n      >\n        <div\n          style={{\n            display: 'flex',\n            alignItems: 'flex-end',\n            justifyContent: 'center',\n            gap: 4,\n            height: 350,\n            width: '90%',\n            marginBottom: 180,\n          }}\n        >\n          {visualization.map((value, index) => {\n            const scaledValue = Math.pow(value, 0.6);\n            const barHeight = Math.max(scaledValue * 800, 20);\n            const colorIndex = (index / visualization.length) * 360;\n\n            return (\n              <div\n                key={index}\n                style={{\n                  width: `${100 / visualization.length}%`,\n                  height: barHeight,\n                  background: `linear-gradient(to top,\n                    hsl(${(colorIndex + hue) % 360}, 90%, 60%),\n                    hsl(${(colorIndex + hue + 40) % 360}, 90%, 70%))`,\n                  borderRadius: '4px 4px 0 0',\n                  boxShadow: `0 0 ${10 + scaledValue * 30}px hsla(${(colorIndex + hue) % 360}, 100%, 60%, ${scaledValue})`,\n                  transition: 'height 0.05s ease-out',\n                }}\n              />\n            );\n          })}\n        </div>\n      </AbsoluteFill>\n\n      {/* Symmetrical side bars */}\n      <AbsoluteFill\n        style={{\n          justifyContent: 'center',\n          alignItems: 'center',\n        }}\n      >\n        {/* Left bars */}\n        <div\n          style={{\n            position: 'absolute',\n            left: 40,\n            display: 'flex',\n            flexDirection: 'column',\n            gap: 8,\n            height: '80%',\n            justifyContent: 'space-around',\n          }}\n        >\n          {visualization.slice(0, 20).map((value, index) => {\n            const scaledValue = Math.pow(value, 0.6);\n            const barWidth = Math.max(scaledValue * 300, 10);\n            const colorIndex = (index / 20) * 360;\n            return (\n              <div\n                key={index}\n                style={{\n                  width: barWidth,\n                  height: 12,\n                  background: `linear-gradient(to right,\n                    hsl(${(colorIndex + hue) % 360}, 90%, 60%),\n                    hsl(${(colorIndex + hue + 40) % 360}, 90%, 70%))`,\n                  borderRadius: '0 6px 6px 0',\n                  boxShadow: `0 0 ${10 + scaledValue * 20}px hsla(${(colorIndex + hue) % 360}, 100%, 60%, ${scaledValue})`,\n                }}\n              />\n            );\n          })}\n        </div>\n\n        {/* Right bars */}\n        <div\n          style={{\n            position: 'absolute',\n            right: 40,\n            display: 'flex',\n            flexDirection: 'column',\n            gap: 8,\n            height: '80%',\n            justifyContent: 'space-around',\n            alignItems: 'flex-end',\n          }}\n        >\n          {visualization.slice(0, 20).map((value, index) => {\n            const scaledValue = Math.pow(value, 0.6);\n            const barWidth = Math.max(scaledValue * 300, 10);\n            const colorIndex = (index / 20) * 360;\n            return (\n              <div\n                key={index}\n                style={{\n                  width: barWidth,\n                  height: 12,\n                  background: `linear-gradient(to left,\n                    hsl(${(colorIndex + hue + 180) % 360}, 90%, 60%),\n                    hsl(${(colorIndex + hue + 220) % 360}, 90%, 70%))`,\n                  borderRadius: '6px 0 0 6px',\n                  boxShadow: `0 0 ${10 + scaledValue * 20}px hsla(${(colorIndex + hue + 180) % 360}, 100%, 60%, ${scaledValue})`,\n                }}\n              />\n            );\n          })}\n        </div>\n      </AbsoluteFill>\n\n      {/* Center title area */}\n      <AbsoluteFill\n        style={{\n          justifyContent: 'flex-start',\n          alignItems: 'center',\n          paddingTop: 60,\n        }}\n      >\n        <div\n          style={{\n            textAlign: 'center',\n            transform: `scale(${1 + avgAmplitude * 0.1})`,\n            transition: 'transform 0.1s ease-out',\n          }}\n        >\n          <div\n            style={{\n              fontSize: 96,\n              fontWeight: 'bold',\n              color: 'white',\n              opacity: titleOpacity,\n              transform: `translateY(${titleY}px)`,\n              textShadow: `0 0 40px hsla(${hue}, 100%, 70%, 0.8), 0 4px 20px rgba(0,0,0,0.5)`,\n              fontFamily: '\"Noto Sans CJK SC\", \"Noto Sans CJK JP\", \"Noto Sans CJK TC\", \"Noto Sans CJK KR\", \"WenQuanYi Micro Hei\", \"WenQuanYi Zen Hei\", \"Droid Sans Fallback\", \"Source Han Sans SC\", \"Microsoft YaHei\", \"SimHei\", \"Hiragino Sans GB\", Arial, Helvetica, sans-serif',\n              marginBottom: 10,\n            }}\n          >\n            {title}\n          </div>\n          <div\n            style={{\n              fontSize: 56,\n              fontWeight: '600',\n              color: 'rgba(255,255,255,0.95)',\n              opacity: titleOpacity,\n              transform: `translateY(${titleY}px)`,\n              textShadow: `0 0 30px hsla(${hue + 60}, 100%, 70%, 0.6), 0 2px 10px rgba(0,0,0,0.5)`,\n              fontFamily: '\"Noto Sans CJK SC\", \"Noto Sans CJK JP\", \"Noto Sans CJK TC\", \"Noto Sans CJK KR\", \"WenQuanYi Micro Hei\", \"WenQuanYi Zen Hei\", \"Droid Sans Fallback\", \"Source Han Sans SC\", \"Microsoft YaHei\", \"SimHei\", \"Hiragino Sans GB\", Arial, Helvetica, sans-serif',\n              letterSpacing: '4px',\n            }}\n          >\n            {subtitle}\n          </div>\n        </div>\n      </AbsoluteFill>\n\n      {/* Lyrics display */}\n      {currentLyric && currentLyric.text && (\n        <AbsoluteFill\n          style={{\n            justifyContent: 'center',\n            alignItems: 'center',\n            paddingTop: 100,\n          }}\n        >\n          <div\n            style={{\n              fontSize: 48,\n              fontWeight: '600',\n              color: 'white',\n              textAlign: 'center',\n              maxWidth: '85%',\n              opacity: lyricProgress,\n              transform: `translateY(${(1 - lyricProgress) * 30}px)`,\n              textShadow: `0 0 40px hsla(${hue}, 100%, 70%, 0.8), 0 4px 30px rgba(0,0,0,0.9)`,\n              fontFamily: '\"Noto Sans CJK SC\", \"Noto Sans CJK JP\", \"Noto Sans CJK TC\", \"Noto Sans CJK KR\", \"WenQuanYi Micro Hei\", \"WenQuanYi Zen Hei\", \"Droid Sans Fallback\", \"Source Han Sans SC\", \"Microsoft YaHei\", \"SimHei\", \"Hiragino Sans GB\", Arial, Helvetica, sans-serif',\n              lineHeight: 1.5,\n              padding: '25px 50px',\n              background: `linear-gradient(135deg, rgba(0,0,0,0.4), rgba(0,0,0,0.2))`,\n              backdropFilter: 'blur(15px)',\n              borderRadius: '20px',\n              border: `2px solid hsla(${hue}, 80%, 60%, 0.3)`,\n              boxShadow: `0 8px 32px rgba(0,0,0,0.5), inset 0 0 40px hsla(${hue}, 100%, 50%, 0.1)`,\n            }}\n          >\n            {currentLyric.text}\n          </div>\n        </AbsoluteFill>\n      )}\n\n      {/* Bottom credit text */}\n      <AbsoluteFill\n        style={{\n          justifyContent: 'flex-end',\n          alignItems: 'center',\n          padding: 50,\n        }}\n      >\n        <div\n          style={{\n            fontSize: 32,\n            fontWeight: '500',\n            color: 'white',\n            opacity: 0.8,\n            textAlign: 'center',\n            textShadow: `0 0 20px hsla(${hue}, 100%, 70%, 0.6), 0 2px 10px rgba(0,0,0,0.7)`,\n            fontFamily: '\"Noto Sans CJK SC\", \"Noto Sans CJK JP\", \"Noto Sans CJK TC\", \"Noto Sans CJK KR\", \"WenQuanYi Micro Hei\", \"WenQuanYi Zen Hei\", \"Droid Sans Fallback\", \"Source Han Sans SC\", \"Microsoft YaHei\", \"SimHei\", \"Hiragino Sans GB\", Arial, Helvetica, sans-serif',\n          }}\n        >\n          {creditText}\n        </div>\n      </AbsoluteFill>\n    </AbsoluteFill>\n  );\n};\n"
  },
  {
    "path": ".claude/skills/acestep-simplemv/scripts/src/Root.tsx",
    "content": "import React from 'react';\nimport {Composition, CalculateMetadataFunction} from 'remotion';\nimport {AudioVisualization} from './AudioVisualization';\nimport {MVInputProps, defaultProps} from './types';\n\nconst calculateMetadata: CalculateMetadataFunction<MVInputProps> = ({props}) => {\n  const fps = 30;\n  const durationInFrames = Math.ceil(props.durationInSeconds * fps);\n  return {\n    durationInFrames,\n    fps,\n    width: 1920,\n    height: 1080,\n  };\n};\n\nexport const RemotionRoot: React.FC = () => {\n  return (\n    <>\n      <Composition\n        id=\"MusicVideo\"\n        component={AudioVisualization}\n        fps={30}\n        width={1920}\n        height={1080}\n        defaultProps={defaultProps}\n        calculateMetadata={calculateMetadata}\n      />\n    </>\n  );\n};\n"
  },
  {
    "path": ".claude/skills/acestep-simplemv/scripts/src/index.ts",
    "content": "import {registerRoot} from 'remotion';\nimport {RemotionRoot} from './Root';\n\nregisterRoot(RemotionRoot);\n"
  },
  {
    "path": ".claude/skills/acestep-simplemv/scripts/src/parseLrc.ts",
    "content": "import {LyricLine} from './types';\n\n/**\n * Parse LRC format lyrics into LyricLine array.\n * LRC format: [mm:ss.xx] lyrics text\n * \n * Example:\n *   [00:02.99] Version one point five is here today\n *   [00:07.00] ACE-Step's rising, leading the way\n */\nexport function parseLrc(lrcContent: string): LyricLine[] {\n  const lines = lrcContent.split('\\n').filter((line) => line.trim());\n  const parsed: {time: number; text: string}[] = [];\n\n  for (const line of lines) {\n    // Match [mm:ss.xx] or [mm:ss] format\n    const match = line.match(/^\\[(\\d{2}):(\\d{2})(?:\\.(\\d{2,3}))?\\]\\s*(.*)$/);\n    if (match) {\n      const minutes = parseInt(match[1], 10);\n      const seconds = parseInt(match[2], 10);\n      const centiseconds = match[3] ? parseInt(match[3].padEnd(3, '0'), 10) / 1000 : 0;\n      const time = minutes * 60 + seconds + centiseconds;\n      const text = match[4].trim();\n      parsed.push({time, text});\n    }\n  }\n\n  // Convert to LyricLine with start/end\n  const result: LyricLine[] = [];\n  for (let i = 0; i < parsed.length; i++) {\n    const start = parsed[i].time;\n    const end = i < parsed.length - 1 ? parsed[i + 1].time : start + 5;\n    const text = parsed[i].text;\n    if (text) {\n      result.push({start, end, text});\n    }\n  }\n\n  return result;\n}\n"
  },
  {
    "path": ".claude/skills/acestep-simplemv/scripts/src/types.ts",
    "content": "export interface LyricLine {\n  start: number;\n  end: number;\n  text: string;\n}\n\nexport interface MVInputProps extends Record<string, unknown> {\n  /** Path to audio file (relative to public/ or absolute URL) */\n  audioFileName: string;\n  /** Lyrics as JSON array [{start, end, text}] */\n  lyrics: LyricLine[];\n  /** Main title displayed at top */\n  title: string;\n  /** Subtitle displayed below title */\n  subtitle: string;\n  /** Bottom credit text */\n  creditText: string;\n  /** Audio duration in seconds (used to calculate total frames) */\n  durationInSeconds: number;\n  /** Lyric timing offset in seconds (positive = delay, negative = advance) */\n  lyricOffset: number;\n  /** Background image filename (relative to public/ or absolute URL). If empty, uses animated gradient. */\n  backgroundImage: string;\n}\n\nexport const defaultProps: MVInputProps = {\n  audioFileName: 'celebration.mp3',\n  lyrics: [],\n  title: 'ACE-Step',\n  subtitle: 'v1.5',\n  creditText: 'Powered by Claude Code + ACE-Step',\n  durationInSeconds: 150,\n  lyricOffset: -0.5,\n  backgroundImage: '',\n};\n"
  },
  {
    "path": ".claude/skills/acestep-simplemv/scripts/tsconfig.json",
    "content": "{\n  \"compilerOptions\": {\n    \"target\": \"ES2022\",\n    \"module\": \"ES2022\",\n    \"moduleResolution\": \"Bundler\",\n    \"lib\": [\"DOM\", \"ES2022\"],\n    \"jsx\": \"react-jsx\",\n    \"skipLibCheck\": true,\n    \"strict\": true,\n    \"esModuleInterop\": true,\n    \"allowSyntheticDefaultImports\": true,\n    \"forceConsistentCasingInFileNames\": true,\n    \"resolveJsonModule\": true,\n    \"isolatedModules\": true,\n    \"noEmit\": true\n  },\n  \"include\": [\"src/**/*\"]\n}\n"
  },
  {
    "path": ".claude/skills/acestep-songwriting/SKILL.md",
    "content": "---\nname: acestep-songwriting\ndescription: Music songwriting guide for ACE-Step. Provides professional knowledge on writing captions, lyrics, choosing BPM/key/duration, and structuring songs. Use this skill when users want to create, write, or plan a song before generating it with ACE-Step.\nallowed-tools: Read\n---\n\n# ACE-Step Songwriting Guide\n\nProfessional music creation knowledge for writing captions, lyrics, and choosing music parameters for ACE-Step.\n\n## Output Format\n\nAfter using this guide, produce two things for the acestep skill:\n1. **Caption** (`-c`): Style/genre/instruments/emotion description\n2. **Lyrics** (`-l`): Complete structured lyrics with tags\n3. **Parameters**: `--duration`, `--bpm`, `--key`, `--time-signature`, `--language`\n\n---\n\n## Caption: The Most Important Input\n\n**Caption is the most important factor affecting generated music.**\n\nSupports multiple formats: simple style words, comma-separated tags, complex natural language descriptions.\n\n### Common Dimensions\n\n| Dimension | Examples |\n|-----------|----------|\n| **Style/Genre** | pop, rock, jazz, electronic, hip-hop, R&B, folk, classical, lo-fi, synthwave |\n| **Emotion/Atmosphere** | melancholic, uplifting, energetic, dreamy, dark, nostalgic, euphoric, intimate |\n| **Instruments** | acoustic guitar, piano, synth pads, 808 drums, strings, brass, electric bass |\n| **Timbre Texture** | warm, bright, crisp, muddy, airy, punchy, lush, raw, polished |\n| **Era Reference** | 80s synth-pop, 90s grunge, 2010s EDM, vintage soul, modern trap |\n| **Production Style** | lo-fi, high-fidelity, live recording, studio-polished, bedroom pop |\n| **Vocal Characteristics** | female vocal, male vocal, breathy, powerful, falsetto, raspy, choir |\n| **Speed/Rhythm** | slow tempo, mid-tempo, fast-paced, groovy, driving, laid-back |\n| **Structure Hints** | building intro, catchy chorus, dramatic bridge, fade-out ending |\n\n### Caption Writing Principles\n\n1. **Specific beats vague** — \"sad piano ballad with female breathy vocal\" > \"a sad song\"\n2. **Combine multiple dimensions** — style+emotion+instruments+timbre anchors direction precisely\n3. **Use references well** — \"in the style of 80s synthwave\" conveys complex aesthetic quickly\n4. **Texture words are useful** — warm, crisp, airy, punchy influence mixing and timbre\n5. **Don't pursue perfection** — Caption is a starting point, iterate based on results\n6. **Granularity determines freedom** — Less detail = more model creativity; more detail = more control\n7. **Avoid conflicting words** — \"classical strings\" + \"hardcore metal\" degrades output\n   - **Fix: Repetition reinforcement** — Repeat the elements you want more\n   - **Fix: Conflict to evolution** — \"Start with soft strings, middle becomes metal rock, end turns to hip-hop\"\n8. **Don't put BPM/key/tempo in Caption** — Use dedicated parameters instead\n\n---\n\n## Lyrics: The Temporal Script\n\nLyrics controls how music unfolds over time. It carries:\n- Lyric text itself\n- **Structure tags** ([Verse], [Chorus], [Bridge]...)\n- **Vocal style hints** ([raspy vocal], [whispered]...)\n- **Instrumental sections** ([guitar solo], [drum break]...)\n- **Energy changes** ([building energy], [explosive drop]...)\n\n### Structure Tags\n\n| Category | Tag | Description |\n|----------|-----|-------------|\n| **Basic Structure** | `[Intro]` | Opening, establish atmosphere |\n| | `[Verse]` / `[Verse 1]` | Verse, narrative progression |\n| | `[Pre-Chorus]` | Pre-chorus, build energy |\n| | `[Chorus]` | Chorus, emotional climax |\n| | `[Bridge]` | Bridge, transition or elevation |\n| | `[Outro]` | Ending, conclusion |\n| **Dynamic Sections** | `[Build]` | Energy gradually rising |\n| | `[Drop]` | Electronic music energy release |\n| | `[Breakdown]` | Reduced instrumentation, space |\n| **Instrumental** | `[Instrumental]` | Pure instrumental, no vocals |\n| | `[Guitar Solo]` | Guitar solo |\n| | `[Piano Interlude]` | Piano interlude |\n| **Special** | `[Fade Out]` | Fade out ending |\n| | `[Silence]` | Silence |\n\n### Combining Tags\n\nUse `-` for finer control, but keep it concise:\n\n```\n✅ [Chorus - anthemic]\n❌ [Chorus - anthemic - stacked harmonies - high energy - powerful - epic]\n```\n\nPut complex style descriptions in Caption, not in tags.\n\n### Caption-Lyrics Consistency\n\n**Models are not good at resolving conflicts.** Checklist:\n- Instruments in Caption ↔ Instrumental section tags in Lyrics\n- Emotion in Caption ↔ Energy tags in Lyrics\n- Vocal description in Caption ↔ Vocal control tags in Lyrics\n\n### Vocal Control Tags\n\n| Tag | Effect |\n|-----|--------|\n| `[raspy vocal]` | Raspy, textured vocals |\n| `[whispered]` | Whispered |\n| `[falsetto]` | Falsetto |\n| `[powerful belting]` | Powerful, high-pitched singing |\n| `[spoken word]` | Rap/recitation |\n| `[harmonies]` | Layered harmonies |\n| `[call and response]` | Call and response |\n| `[ad-lib]` | Improvised embellishments |\n\n### Energy and Emotion Tags\n\n| Tag | Effect |\n|-----|--------|\n| `[high energy]` | High energy, passionate |\n| `[low energy]` | Low energy, restrained |\n| `[building energy]` | Increasing energy |\n| `[explosive]` | Explosive energy |\n| `[melancholic]` | Melancholic |\n| `[euphoric]` | Euphoric |\n| `[dreamy]` | Dreamy |\n| `[aggressive]` | Aggressive |\n\n### Lyric Writing Tips\n\n1. **6-10 syllables per line** — Model aligns syllables to beats; keep similar counts for lines in same position (±1-2)\n2. **Uppercase = stronger intensity** — `WE ARE THE CHAMPIONS!` (shouting) vs `walking through the streets` (normal)\n3. **Parentheses = background vocals** — `We rise together (together)`\n4. **Extend vowels** — `Feeeling so aliiive` (use cautiously, effects unstable)\n5. **Clear section separation** — Blank lines between sections\n\n### Avoiding \"AI-flavored\" Lyrics\n\n| Red Flag | Description |\n|----------|-------------|\n| **Adjective stacking** | \"neon skies, electric hearts, endless dreams\" — vague imagery filler |\n| **Rhyme chaos** | Inconsistent patterns or forced rhymes breaking meaning |\n| **Blurred boundaries** | Lyric content crosses structure tags |\n| **No breathing room** | Lines too long to sing in one breath |\n| **Mixed metaphors** | Water → fire → flying — listeners can't anchor |\n\n**Metaphor discipline**: One core metaphor per song, explore its multiple aspects.\n\n---\n\n## Music Metadata\n\n**Most of the time, let LM auto-infer.** Only set manually when you have clear requirements.\n\n| Parameter | Range | Description |\n|-----------|-------|-------------|\n| `bpm` | 30–300 | Slow 60–80, mid 90–120, fast 130–180 |\n| `keyscale` | Key | e.g. `C Major`, `Am`. Common keys (C, G, D, Am, Em) most stable |\n| `timesignature` | Time sig | `4/4` (most common), `3/4` (waltz), `6/8` (swing) |\n| `vocal_language` | Language | Usually auto-detected from lyrics |\n| `duration` | Seconds | See duration calculation below |\n\n### When to Set Manually\n\n| Scenario | Set |\n|----------|-----|\n| Daily generation | Let LM auto-infer |\n| Clear tempo requirement | `bpm` |\n| Specific style (waltz) | `timesignature=3/4` |\n| Match other material | `bpm` + `duration` |\n| Specific key color | `keyscale` |\n\n---\n\n## Duration Calculation\n\n### Estimation Method\n\n- **Intro/Outro**: 5-10 seconds each\n- **Instrumental sections**: 5-15 seconds each\n- **Typical structures**:\n  - 2 verses + 2 choruses: 120-150s minimum\n  - 2 verses + 2 choruses + bridge: 180-240s minimum\n  - Full song with intro/outro: 210-270s (3.5-4.5 min)\n\n### BPM and Duration Relationship\n\n- **Slower BPM (60-80)**: Need MORE duration for same lyrics\n- **Medium BPM (100-130)**: Standard duration\n- **Faster BPM (150-180)**: Can fit more lyrics, but still need breathing room\n\n**Rule of thumb**: When in doubt, estimate longer. A song too short feels rushed.\n\n---\n\nNote: Lyrics tags (piano, powerful, whispered) are consistent with Caption (piano ballad, building to powerful chorus, intimate).\n"
  },
  {
    "path": ".claude/skills/acestep-thumbnail/SKILL.md",
    "content": "---\nname: acestep-thumbnail\ndescription: Generate song cover/thumbnail images using Gemini API. Creates artistic images suitable for music video backgrounds. Use when users want to generate album art, song covers, thumbnails, or background images for MVs.\nallowed-tools: Read, Write, Bash\n---\n\n# Thumbnail Generation Skill\n\nGenerate song cover/thumbnail images using Google Gemini's image generation API. Output images can be used directly as MV backgrounds with the acestep-simplemv skill.\n\n## API Key Setup Guide\n\n**Before generating, you MUST check whether the user's API key is configured.** Run the following command to check:\n\n```bash\ncd \"{project_root}/{.claude or .codex}/skills/acestep-thumbnail/\" && bash ./scripts/acestep-thumbnail.sh config --check-key\n```\n\nThis command only reports whether the API key is set or empty — it does NOT print the actual key value. **NEVER read or display the user's API key content.** Do not use `config --get` on key fields or read `config.json` directly. The `config --list` command is safe — it automatically masks API keys as `***` in output.\n\n**If the command reports the key is empty**, you MUST stop and guide the user to configure it before proceeding. Do NOT attempt generation without a valid key — it will fail.\n\nUse `AskUserQuestion` to ask the user to provide their API key, with the following guidance:\n\n1. Tell the user the Gemini API key is not configured and image generation cannot proceed without it.\n2. Provide instructions on where to get a key:\n   - **Google AI Studio**: Get a API key at https://aistudio.google.com/apikey — requires a Google account.\n3. Once the user provides the key, configure it using:\n   ```bash\n   cd \"{project_root}/{.claude or .codex}/skills/acestep-thumbnail/\" && bash ./scripts/acestep-thumbnail.sh config --set api_key <KEY>\n   ```\n4. After configuring, re-run `config --check-key` to verify the key is set before proceeding.\n\n**If the API key is already configured**, proceed directly to generation without asking.\n\n## Quick Start\n\n```bash\n# 1. cd to this skill's directory\ncd {project_root}/{.claude or .codex}/skills/acestep-thumbnail/\n\n# 2. Configure API key\n./scripts/acestep-thumbnail.sh config --set api_key <YOUR_GEMINI_KEY>\n\n# 3. Generate thumbnail\n./scripts/acestep-thumbnail.sh generate --prompt \"Cherry blossoms at night with moonlight\"\n\n# 4. Output saved to: {project_root}/acestep_output/<timestamp>_thumbnail.png\n```\n\n## Prerequisites\n\n- curl, jq, base64 (or python3)\n- A Gemini API key (at https://aistudio.google.com/apikey)\n\n## Script Usage\n\n```bash\n./scripts/acestep-thumbnail.sh generate [options]\n\nOptions:\n  --prompt       Image description (required)\n  --aspect-ratio 16:9, 1:1, or 9:16 (default: 16:9)\n  --output       Output image path (default: acestep_output/<timestamp>_thumbnail.png)\n```\n\n## Prompt Guidelines\n\nWhen crafting prompts for song thumbnails:\n\n- **Be descriptive and atmospheric**: \"Neon-lit rain-soaked Tokyo street at midnight\" works better than \"city at night\"\n- **Match the music mood**: A jazz song might need \"Warm smoky lounge with dim golden lighting\", while EDM might need \"Abstract geometric patterns with vibrant electric colors\"\n- **Avoid text requests**: Image generation models often struggle with text. Add \"No text or letters in the image\" if needed\n- **For MV backgrounds**: The image will be overlaid with visualizations, so avoid overly busy compositions. Atmospheric, gradient-rich scenes work best\n\n## Configuration\n\nConfig file: `scripts/config.json`\n\n```bash\n# Set API key\n./scripts/acestep-thumbnail.sh config --set api_key <YOUR_KEY>\n\n# Change model\n./scripts/acestep-thumbnail.sh config --set model gemini-3.1-flash-image-preview\n\n# Change default aspect ratio\n./scripts/acestep-thumbnail.sh config --set aspect_ratio 1:1\n\n# View config (API key masked)\n./scripts/acestep-thumbnail.sh config --list\n```\n\n| Option | Default | Description |\n|--------|---------|-------------|\n| `api_key` | `\"\"` | Gemini API key |\n| `api_url` | `https://generativelanguage.googleapis.com/v1beta` | Gemini API base URL |\n| `model` | `gemini-3.1-flash-image-preview` | Gemini model with image generation |\n| `aspect_ratio` | `16:9` | Default aspect ratio (16:9 for MV, 1:1 for album art) |\n\n## Integration with MV Rendering\n\nGenerated thumbnails can be directly used as MV backgrounds:\n\n```bash\n# 1. Generate thumbnail\ncd {project_root}/{.claude or .codex}/skills/acestep-thumbnail/\n./scripts/acestep-thumbnail.sh generate --prompt \"Energetic pop concert stage with colorful lights\" --output /tmp/cover.png\n\n# 2. Use as MV background\ncd {project_root}/{.claude or .codex}/skills/acestep-simplemv/\n./scripts/render-mv.sh --audio song.mp3 --lyrics song.lrc --title \"Song Name\" --background /tmp/cover.png\n```\n\n## Workflow: Full Song Pipeline\n\nThe complete workflow with all ACE-Step skills:\n\n1. **acestep-songwriting** — Write lyrics and plan structure\n2. **acestep** — Generate music from lyrics\n3. **acestep-lyrics-transcription** — Transcribe audio to timestamped LRC\n4. **acestep-thumbnail** — Generate cover art / MV background\n5. **acestep-simplemv** — Render final music video with cover + audio + lyrics\n"
  },
  {
    "path": ".claude/skills/acestep-thumbnail/scripts/acestep-thumbnail.sh",
    "content": "#!/bin/bash\n# acestep-thumbnail.sh - Generate song cover/thumbnail images using Gemini API\n#\n# Usage:\n#   ./acestep-thumbnail.sh generate --prompt \"description\" [options]\n#   ./acestep-thumbnail.sh config --set <key> <value>\n#   ./acestep-thumbnail.sh config --get <key>\n#   ./acestep-thumbnail.sh config --list\n#   ./acestep-thumbnail.sh config --check-key\n#\n# Generate options:\n#   --prompt       Image description prompt (required)\n#   --aspect-ratio Aspect ratio: 16:9, 1:1, 9:16 (default: from config, typically 16:9)\n#   --output       Output image path (default: acestep_output/<timestamp>_thumbnail.png)\n#\n# Examples:\n#   ./acestep-thumbnail.sh generate --prompt \"Cyberpunk city skyline at night with neon lights\"\n#   ./acestep-thumbnail.sh generate --prompt \"Cherry blossoms\" --output /tmp/cover.png\n\nset -euo pipefail\n\nSCRIPT_DIR=\"$(cd \"$(dirname \"$0\")\" && pwd)\"\nSKILL_DIR=\"$(cd \"$SCRIPT_DIR/..\" && pwd)\"\nCONFIG_FILE=\"${SCRIPT_DIR}/config.json\"\nCONFIG_EXAMPLE=\"${SCRIPT_DIR}/config.example.json\"\n\n# ── Helpers ──────────────────────────────────────────────────────────\n\nensure_config() {\n  if [[ ! -f \"$CONFIG_FILE\" ]]; then\n    if [[ -f \"$CONFIG_EXAMPLE\" ]]; then\n      cp \"$CONFIG_EXAMPLE\" \"$CONFIG_FILE\"\n      echo \"Created config.json from config.example.json\"\n    else\n      echo '{\"api_key\":\"\",\"api_url\":\"https://generativelanguage.googleapis.com/v1beta\",\"model\":\"gemini-3.1-flash-image-preview\",\"aspect_ratio\":\"16:9\"}' > \"$CONFIG_FILE\"\n      echo \"Created default config.json\"\n    fi\n  fi\n}\n\nget_config() {\n  local key=\"$1\"\n  ensure_config\n  jq -r \".$key // empty\" \"$CONFIG_FILE\"\n}\n\nset_config() {\n  local key=\"$1\" value=\"$2\"\n  ensure_config\n  local tmp=\"${CONFIG_FILE}.tmp\"\n  jq --arg v \"$value\" \".$key = \\$v\" \"$CONFIG_FILE\" > \"$tmp\" && mv \"$tmp\" \"$CONFIG_FILE\"\n  echo \"Set $key\"\n}\n\ncheck_api_key() {\n  ensure_config\n  local key\n  key=$(get_config \"api_key\")\n  if [[ -n \"$key\" ]]; then\n    echo \"Gemini API key: configured\"\n  else\n    echo \"Gemini API key: empty\"\n    echo \"\"\n    echo \"Get a free API key at: https://aistudio.google.com/apikey\"\n    echo \"Then run: ./scripts/acestep-thumbnail.sh config --set api_key <YOUR_KEY>\"\n  fi\n}\n\nlist_config() {\n  ensure_config\n  # Mask API key in output\n  jq 'if .api_key and (.api_key | length) > 0 then .api_key = \"***\" else . end' \"$CONFIG_FILE\"\n}\n\n# ── Config command ───────────────────────────────────────────────────\n\nhandle_config() {\n  local action=\"${1:-}\" key=\"${2:-}\" value=\"${3:-}\"\n  case \"$action\" in\n    --set)\n      [[ -z \"$key\" || -z \"$value\" ]] && { echo \"Usage: config --set <key> <value>\" >&2; exit 1; }\n      set_config \"$key\" \"$value\"\n      ;;\n    --get)\n      [[ -z \"$key\" ]] && { echo \"Usage: config --get <key>\" >&2; exit 1; }\n      # Safety: refuse to print API key directly\n      if [[ \"$key\" == \"api_key\" ]]; then\n        echo \"Error: Use 'config --check-key' to check API key status. Direct key access is not allowed.\" >&2\n        exit 1\n      fi\n      get_config \"$key\"\n      ;;\n    --list)\n      list_config\n      ;;\n    --check-key)\n      check_api_key\n      ;;\n    *)\n      echo \"Usage: config [--set <key> <value> | --get <key> | --list | --check-key]\" >&2\n      exit 1\n      ;;\n  esac\n}\n\n# ── Generate command ─────────────────────────────────────────────────\n\nhandle_generate() {\n  ensure_config\n\n  local prompt=\"\" aspect_ratio=\"\" output=\"\"\n\n  # Parse args\n  while [[ $# -gt 0 ]]; do\n    case \"$1\" in\n      --prompt)       prompt=\"$2\"; shift 2 ;;\n      --aspect-ratio) aspect_ratio=\"$2\"; shift 2 ;;\n      --output)       output=\"$2\"; shift 2 ;;\n      *)\n        echo \"Error: unknown argument: $1\" >&2\n        exit 1\n        ;;\n    esac\n  done\n\n  # Load config\n  local api_key api_url model\n  api_key=$(get_config \"api_key\")\n  api_url=$(get_config \"api_url\")\n  model=$(get_config \"model\")\n\n  if [[ -z \"$api_key\" ]]; then\n    echo \"Error: Gemini API key not configured.\" >&2\n    echo \"Get a free key at: https://aistudio.google.com/apikey\" >&2\n    echo \"Then run: ./scripts/acestep-thumbnail.sh config --set api_key <YOUR_KEY>\" >&2\n    exit 1\n  fi\n\n  [[ -z \"$api_url\" ]] && api_url=\"https://generativelanguage.googleapis.com/v1beta\"\n  [[ -z \"$model\" ]] && model=\"gemini-3.1-flash-image-preview\"\n  local generate_api=\"generateContent\"\n\n  # Aspect ratio: CLI arg > config > default\n  if [[ -z \"$aspect_ratio\" ]]; then\n    aspect_ratio=$(get_config \"aspect_ratio\")\n    [[ -z \"$aspect_ratio\" ]] && aspect_ratio=\"16:9\"\n  fi\n\n  if [[ -z \"$prompt\" ]]; then\n    echo \"Error: --prompt is required\" >&2\n    exit 1\n  fi\n\n  # Default output path\n  if [[ -z \"$output\" ]]; then\n    # Find project root (walk up to find acestep_output or use skill's parent)\n    local project_root\n    project_root=\"$(cd \"$SKILL_DIR/../..\" && pwd)\"\n    # Go up one more level if we're inside .claude/skills or .codex/skills\n    if [[ \"$(basename \"$(dirname \"$SKILL_DIR\")\")\" == \"skills\" ]]; then\n      local skills_parent\n      skills_parent=\"$(dirname \"$(dirname \"$SKILL_DIR\")\")\"\n      local skills_grandparent\n      skills_grandparent=\"$(dirname \"$skills_parent\")\"\n      project_root=\"$skills_grandparent\"\n    fi\n    local out_dir=\"${project_root}/acestep_output\"\n    mkdir -p \"$out_dir\"\n    local timestamp\n    timestamp=$(date +%Y%m%d_%H%M%S)\n    output=\"${out_dir}/${timestamp}_thumbnail.png\"\n  fi\n\n  # Ensure output directory exists\n  mkdir -p \"$(dirname \"$output\")\"\n\n  echo \"Generating thumbnail...\"\n  echo \"  Prompt: ${prompt:0:100}$([ ${#prompt} -gt 100 ] && echo '...')\"\n  echo \"  Model: $model\"\n  echo \"  Aspect ratio: $aspect_ratio\"\n  echo \"  Output: $output\"\n  echo \"\"\n\n  # Build request payload\n  local payload\n  payload=$(jq -n \\\n    --arg prompt \"$prompt\" \\\n    --arg aspect_ratio \"$aspect_ratio\" \\\n    '{\n      contents: [{\n        role: \"user\",\n        parts: [{ text: $prompt }]\n      }],\n      generationConfig: {\n        responseModalities: [\"IMAGE\"],\n        thinkingConfig: { thinkingLevel: \"MINIMAL\" },\n        imageConfig: { aspectRatio: $aspect_ratio, imageSize: \"1K\" }\n      }\n    }')\n\n  # Call Gemini API\n  local endpoint=\"${api_url}/models/${model}:${generate_api}?key=${api_key}\"\n\n  local response http_code\n  local tmp_response\n  tmp_response=$(mktemp)\n\n  http_code=$(curl -s -w \"%{http_code}\" -o \"$tmp_response\" \\\n    -X POST \"$endpoint\" \\\n    -H \"Content-Type: application/json\" \\\n    -d \"$payload\")\n\n  if [[ \"$http_code\" -ne 200 ]]; then\n    echo \"Error: API request failed with HTTP $http_code\" >&2\n    # Show error message but mask the API key\n    local err_body\n    err_body=$(cat \"$tmp_response\")\n    echo \"$err_body\" | jq -r '.error.message // .error // .' 2>/dev/null || echo \"$err_body\" >&2\n    rm -f \"$tmp_response\"\n    exit 1\n  fi\n\n  response=$(cat \"$tmp_response\")\n  rm -f \"$tmp_response\"\n\n  # Extract base64 image data from response (generateContent returns plain JSON)\n  local image_data mime_type\n  image_data=$(echo \"$response\" | jq -r '\n    .candidates[0].content.parts[]\n    | select(.inlineData != null)\n    | .inlineData.data' 2>/dev/null | head -1)\n\n  mime_type=$(echo \"$response\" | jq -r '\n    .candidates[0].content.parts[]\n    | select(.inlineData != null)\n    | .inlineData.mimeType' 2>/dev/null | head -1)\n\n  if [[ -z \"$image_data\" || \"$image_data\" == \"null\" ]]; then\n    echo \"Error: No image data in API response\" >&2\n    local text_part\n    text_part=$(echo \"$response\" | jq -r '.candidates[0].content.parts[] | select(.text != null) | .text' 2>/dev/null | head -3)\n    [[ -n \"$text_part\" ]] && echo \"Response text: $text_part\" >&2\n    echo \"Raw response (first 500 chars): ${response:0:500}\" >&2\n    exit 1\n  fi\n\n  # Determine file extension from mime type\n  local ext=\"png\"\n  case \"$mime_type\" in\n    image/jpeg) ext=\"jpg\" ;;\n    image/png)  ext=\"png\" ;;\n    image/webp) ext=\"webp\" ;;\n  esac\n\n  # Adjust output extension if needed\n  local output_ext=\"${output##*.}\"\n  if [[ \"$output_ext\" != \"$ext\" && \"$output_ext\" == \"png\" ]]; then\n    output=\"${output%.*}.${ext}\"\n  fi\n\n  # Decode base64 and save\n  echo \"$image_data\" | base64 -d > \"$output\" 2>/dev/null || \\\n  echo \"$image_data\" | python3 -c \"import sys,base64; sys.stdout.buffer.write(base64.b64decode(sys.stdin.read().strip()))\" > \"$output\" 2>/dev/null || \\\n  echo \"$image_data\" | python -c \"import sys,base64; sys.stdout.buffer.write(base64.b64decode(sys.stdin.read().strip()))\" > \"$output\"\n\n  local file_size\n  if [[ -f \"$output\" ]]; then\n    file_size=$(wc -c < \"$output\" | tr -d ' ')\n    echo \"Thumbnail saved: $output (${file_size} bytes)\"\n    echo \"\"\n    echo \"Use as MV background:\"\n    echo \"  ./scripts/render-mv.sh --audio song.mp3 --lyrics song.lrc --title \\\"Title\\\" --background \\\"$output\\\"\"\n  else\n    echo \"Error: Failed to save image\" >&2\n    exit 1\n  fi\n}\n\n# ── Main ─────────────────────────────────────────────────────────────\n\nmain() {\n  local command=\"${1:-}\"\n  shift || true\n\n  case \"$command\" in\n    generate)\n      handle_generate \"$@\"\n      ;;\n    config)\n      handle_config \"$@\"\n      ;;\n    -h|--help|help)\n      head -16 \"$0\" | tail -14\n      ;;\n    *)\n      echo \"Usage: acestep-thumbnail.sh <command> [options]\" >&2\n      echo \"\" >&2\n      echo \"Commands:\" >&2\n      echo \"  generate   Generate a thumbnail image\" >&2\n      echo \"  config     Manage configuration\" >&2\n      echo \"  help       Show usage\" >&2\n      exit 1\n      ;;\n  esac\n}\n\nmain \"$@\"\n"
  },
  {
    "path": ".claude/skills/acestep-thumbnail/scripts/config.example.json",
    "content": "{\n  \"api_key\": \"\",\n  \"api_url\": \"https://generativelanguage.googleapis.com/v1beta\",\n  \"model\": \"gemini-3.1-flash-image-preview\",\n  \"aspect_ratio\": \"16:9\"\n}\n"
  },
  {
    "path": ".dockerignore",
    "content": "# =============================================================================\n# .dockerignore — ACE-Step 1.5\n# Keep Docker build context small by excluding large / unnecessary files.\n# =============================================================================\n\n# Version control\n.git\n.gitignore\n\n# Model checkpoints (mount as volumes at runtime instead)\ncheckpoints/\n*.safetensors\n*.bin\n*.ckpt\n*.pt\n\n# Generated outputs\ngradio_outputs/\n\n# Python artifacts\n__pycache__/\n*.py[cod]\n*.egg-info/\ndist/\nbuild/\n*.egg\n\n# Virtual environments\n.venv/\nvenv/\nenv/\n\n# IDE / editor files\n.vscode/\n.idea/\n*.swp\n*.swo\n*~\n\n# Docker files (don't include Dockerfiles in the build context copy)\nDockerfile*\ndocker-compose*\n\n# OS files\n.DS_Store\nThumbs.db\n\n# CI/CD\n.github/\n\n# Large docs / assets not needed at runtime\ndocs/pics/\n\n# UV lock file (deps are installed explicitly in Dockerfile)\nuv.lock\n\n# Windows scripts (not needed on Jetson ARM64)\n*.bat\n*.ps1\n\n# nano-vllm build artifacts (not used on Jetson)\nacestep/third_parts/nano-vllm/build/\nacestep/third_parts/nano-vllm/nano_vllm.egg-info/\n"
  },
  {
    "path": ".editorconfig",
    "content": "﻿root = true\n\n[*]\ncharset = utf-8\nend_of_line = lf\ninsert_final_newline = true\ntrim_trailing_whitespace = true\n\n[*.{bat,cmd,ps1}]\nend_of_line = crlf\n\n[*.png]\ncharset = unset\nend_of_line = unset\ninsert_final_newline = false\ntrim_trailing_whitespace = false\n"
  },
  {
    "path": ".githooks/pre-push",
    "content": "#!/usr/bin/env sh\nset -eu\n\n# Prevent cross-polluted PR branches by ensuring the current branch is\n# independently based on upstream/main and does not reuse non-main commits\n# from other remote feature/fix/docs branches.\n\ncurrent_branch=\"$(git symbolic-ref --quiet --short HEAD || true)\"\n[ -z \"$current_branch\" ] && exit 0\n\nbase_ref=\"${PR_BASE_REF:-upstream/main}\"\nif ! git rev-parse --verify \"$base_ref\" >/dev/null 2>&1; then\n  # If upstream/main is unavailable locally, do not block pushes.\n  exit 0\nfi\n\nif ! git merge-base --is-ancestor \"$base_ref\" HEAD; then\n  echo \"ERROR: '$current_branch' is not based on '$base_ref'.\"\n  echo \"Create PR branches from upstream/main to keep PRs independent.\"\n  exit 1\nfi\n\nahead_commits=\"$(git rev-list \"$base_ref\"..HEAD)\"\n[ -z \"$ahead_commits\" ] && exit 0\n\nremote_branches=\"$(git for-each-ref --format='%(refname:short)' \\\n  refs/remotes/origin/feat \\\n  refs/remotes/origin/fix \\\n  refs/remotes/origin/docs)\"\n\nfor commit in $ahead_commits; do\n  for remote_branch in $remote_branches; do\n    [ \"$remote_branch\" = \"origin/$current_branch\" ] && continue\n    if git merge-base --is-ancestor \"$commit\" \"$remote_branch\"; then\n      echo \"ERROR: Commit $commit is also present in $remote_branch.\"\n      echo \"This branch appears stacked or cross-polluted.\"\n      echo \"Recreate from '$base_ref' and cherry-pick only intended commits.\"\n      exit 1\n    fi\n  done\ndone\n\nexit 0\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/bug_report.md",
    "content": "---\nname: Bug report\nabout: Create a report to help us improve\ntitle: ''\nlabels: ''\nassignees: ''\n\n---\n\n> **📚 Before submitting:** Have you tried [DeepWiki AI Assistant](https://deepwiki.com/ace-step/ACE-Step-1.5)?\n> DeepWiki can instantly help with installation, troubleshooting, and common issues!\n> See pinned issue #791 for more info.\n\n**Did you check DeepWiki?**\n- [ ] Yes, I checked DeepWiki but couldn't find a solution\n- [ ] No, this is a new bug not covered in the docs\n\n**Describe the bug**\nA clear and concise description of what the bug is.\n\n**To Reproduce**\nSteps to reproduce the behavior:\n1. Go to '...'\n2. Click on '....'\n3. Scroll down to '....'\n4. See error\n\n**Expected behavior**\nA clear and concise description of what you expected to happen.\n\n**Screenshots**\nIf applicable, add screenshots to help explain your problem.\n\n**Desktop (please complete the following information):**\n - OS: [e.g. iOS]\n - Browser [e.g. chrome, safari]\n - Version [e.g. 22]\n\n**Smartphone (please complete the following information):**\n - Device: [e.g. iPhone6]\n - OS: [e.g. iOS8.1]\n - Browser [e.g. stock browser, safari]\n - Version [e.g. 22]\n\n**Additional context**\nAdd any other context about the problem here.\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/feature_request.md",
    "content": "---\nname: Feature request\nabout: Suggest an idea for this project\ntitle: ''\nlabels: ''\nassignees: ''\n\n---\n\n> **📚 Quick tip:** Check if this feature already exists!\n> Ask [DeepWiki AI Assistant](https://deepwiki.com/ace-step/ACE-Step-1.5) first - it knows all current features.\n> See pinned issue #791 for more info.\n\n**Did you check existing features?**\n- [ ] Yes, I checked DeepWiki and this feature doesn't exist\n- [ ] This is a new feature idea\n\n**Is your feature request related to a problem? Please describe.**\nA clear and concise description of what the problem is. Ex. I'm always frustrated when [...]\n\n**Describe the solution you'd like**\nA clear and concise description of what you want to happen.\n\n**Describe alternatives you've considered**\nA clear and concise description of any alternative solutions or features you've considered.\n\n**Additional context**\nAdd any other context or screenshots about the feature request here.\n"
  },
  {
    "path": ".github/codeql-config.yml",
    "content": "# CodeQL configuration for ACE-Step-1.5\n#\n# This project is a local Gradio desktop application for music generation\n# and LoRA/LoKr fine-tuning. It is NOT a web service exposed to the internet.\n#\n# CodeQL's py/path-injection query flags Gradio UI component values\n# (gr.Textbox, gr.Dropdown, etc.) as \"user-provided\" taint sources.\n# While technically the local user can edit these values, the application\n# runs entirely on the user's own machine — the user IS the operator.\n# There is no remote attacker surface.\n#\n# Additionally, all user-provided paths are validated through\n# acestep.training.path_safety.safe_path() which performs\n# os.path.normpath + startswith checks, but CodeQL does not recognise\n# cross-function sanitisers.\n#\n# We therefore exclude the training and UI modules from path-injection\n# analysis to suppress these confirmed false positives.\n\nname: \"ACE-Step CodeQL Config\"\n\npaths-ignore:\n  # Training modules — local-only, paths validated via safe_path()\n  - acestep/training\n  - acestep/ui\n  # Third-party vendored code\n  - acestep/third_parts\n  - third_party\n"
  },
  {
    "path": ".github/copilot-instructions.md",
    "content": "# ACE-Step 1.5 - GitHub Copilot Instructions\n\n## Project Overview\n\nACE-Step 1.5 is an open-source music foundation model combining a Language Model (LM) as a planner with a Diffusion Transformer (DiT) for audio synthesis. It generates commercial-grade music on consumer hardware (< 4GB VRAM).\n\n## Tech Stack\n\n- **Python 3.11-3.12** (ROCm on Windows requires 3.12; other platforms use 3.11)\n- **PyTorch 2.7+** with CUDA 12.8 (Windows/Linux), MPS (macOS ARM64)\n- **Transformers 4.51.0-4.57.x** for LLM inference\n- **Diffusers** for diffusion models\n- **Gradio 6.2.0** for web UI\n- **FastAPI + Uvicorn** for REST API server\n- **uv** for dependency management\n- **MLX** (Apple Silicon native acceleration, macOS ARM64)\n- **nano-vllm** (optimized LLM inference, non-macOS ARM64)\n\n## Multi-Platform Support\n\n**CRITICAL**: Supports CUDA, ROCm, Intel XPU, MPS, MLX, and CPU. When fixing bugs or adding features:\n- **DO NOT alter non-target platform paths** unless explicitly required\n- Changes to CUDA code should not affect MPS/XPU/CPU paths\n- Use `gpu_config.py` for hardware detection and configuration\n\n## Code Organization\n\n### Main Entry Points\n- `acestep/acestep_v15_pipeline.py` - Gradio UI pipeline\n- `acestep/api_server.py` - REST API server\n- `cli.py` - Command-line interface\n- `acestep/model_downloader.py` - Model downloader\n\n### Core Modules\n- `acestep/handler.py` - Audio generation handler (AceStepHandler)\n- `acestep/llm_inference.py` - LLM handler for text processing\n- `acestep/inference.py` - Generation logic and parameters\n- `acestep/gpu_config.py` - Hardware detection and GPU configuration\n- `acestep/audio_utils.py` - Audio processing utilities\n- `acestep/constants.py` - Global constants\n\n### UI & Internationalization\n- `acestep/gradio_ui/` - Gradio interface components\n- `acestep/gradio_ui/i18n.py` - i18n system (50+ languages)\n- All user-facing strings must use i18n translation keys\n\n### Training\n- `acestep/training/` - LoRA training pipeline\n- `acestep/dataset/` - Dataset handling\n\n## Key Conventions\n\n- **Python style**: PEP 8, 4 spaces, double quotes for strings\n- **Naming**: `snake_case` functions/variables, `PascalCase` classes, `UPPER_SNAKE_CASE` constants\n- **Logging**: Use `loguru` logger (not `print()` except CLI output)\n- **Dependencies**: Use `uv add <package>` to add to `pyproject.toml`\n\n## Performance\n\n- Target: 4GB VRAM - minimize memory allocations\n- Lazy load models when needed\n- Batch operations supported (up to 8 songs)\n\n## Additional Resources\n\n- **AGENTS.md**: Detailed guidance for AI coding agents\n- **CONTRIBUTING.md**: Contribution workflow and guidelines\n"
  },
  {
    "path": ".github/workflows/close-inactive-issues.yml",
    "content": "name: Close inactive issues\n\non:\n  schedule:\n    # Cron is UTC\n    - cron: \"15 6 * * *\"\n  workflow_dispatch: {}\n\npermissions:\n  issues: write\n\njobs:\n  stale:\n    runs-on: ubuntu-latest\n    steps:\n      - name: Mark stale and close\n        uses: actions/stale@v10\n        with:\n          repo-token: ${{ github.token }}\n\n          # \"No activity for 28 days\" -> mark stale at 21 days,\n          # then close 7 days after being marked stale\n          days-before-issue-stale: 21\n          days-before-issue-close: 7\n          days-before-pr-stale: -1\n          days-before-pr-close: -1\n\n          stale-issue-label: stale\n          close-issue-message: >\n            Closing due to 28 days of inactivity. If this is still relevant,\n            please comment to reopen.\n          stale-issue-message: >\n            No activity for 28 days. Closing automatically unless updated.\n\n          # Prevent closing important issues\n          exempt-issue-labels: \"keep-open,pinned,security\"\n          exempt-all-milestones: true"
  },
  {
    "path": ".github/workflows/codeql.yml",
    "content": "# For most projects, this workflow file will not need changing; you simply need\n# to commit it to your repository.\n#\n# You may wish to alter this file to override the set of languages analyzed,\n# or to provide custom queries or build logic.\n#\n# ******** NOTE ********\n# We have attempted to detect the languages in your repository. Please check\n# the `language` matrix defined below to confirm you have the correct set of\n# supported CodeQL languages.\n#\nname: \"CodeQL Advanced\"\n\non:\n  push:\n    branches: [ \"main\" ]\n  pull_request:\n    branches: [ \"main\" ]\n  schedule:\n    - cron: '26 2 * * 5'\n\njobs:\n  analyze:\n    name: Analyze (${{ matrix.language }})\n    # Runner size impacts CodeQL analysis time. To learn more, please see:\n    #   - https://gh.io/recommended-hardware-resources-for-running-codeql\n    #   - https://gh.io/supported-runners-and-hardware-resources\n    #   - https://gh.io/using-larger-runners (GitHub.com only)\n    # Consider using larger runners or machines with greater resources for possible analysis time improvements.\n    runs-on: ${{ (matrix.language == 'swift' && 'macos-latest') || 'ubuntu-latest' }}\n    permissions:\n      # required for all workflows\n      security-events: write\n\n      # required to fetch internal or private CodeQL packs\n      packages: read\n\n      # only required for workflows in private repositories\n      actions: read\n      contents: read\n\n    strategy:\n      fail-fast: false\n      matrix:\n        include:\n          - language: python\n            build-mode: none\n        # CodeQL supports the following values keywords for 'language': 'actions', 'c-cpp', 'csharp', 'go', 'java-kotlin', 'javascript-typescript', 'python', 'ruby', 'rust', 'swift'\n        # Use `c-cpp` to analyze code written in C, C++ or both\n        # Use 'java-kotlin' to analyze code written in Java, Kotlin or both\n        # Use 'javascript-typescript' to analyze code written in JavaScript, TypeScript or both\n        # To learn more about changing the languages that are analyzed or customizing the build mode for your analysis,\n        # see https://docs.github.com/en/code-security/code-scanning/creating-an-advanced-setup-for-code-scanning/customizing-your-advanced-setup-for-code-scanning.\n        # If you are analyzing a compiled language, you can modify the 'build-mode' for that language to customize how\n        # your codebase is analyzed, see https://docs.github.com/en/code-security/code-scanning/creating-an-advanced-setup-for-code-scanning/codeql-code-scanning-for-compiled-languages\n    steps:\n      - name: Checkout repository\n        uses: actions/checkout@v4\n\n    # Add any setup steps before running the `github/codeql-action/init` action.\n    # This includes steps like installing compilers or runtimes (`actions/setup-node`\n    # or others). This is typically only required for manual builds.\n    # - name: Setup runtime (example)\n    #   uses: actions/setup-example@v1\n\n    # Initializes the CodeQL tools for scanning.\n      - name: Initialize CodeQL\n        uses: github/codeql-action/init@v4\n        with:\n          languages: ${{ matrix.language }}\n          build-mode: ${{ matrix.build-mode }}\n          config-file: ./.github/codeql-config.yml\n        # For more details on CodeQL's query packs, refer to: https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-code-scanning#using-queries-in-ql-packs\n        # queries: security-extended,security-and-quality\n\n    # If the analyze step fails for one of the languages you are analyzing with\n    # \"We were unable to automatically build your code\", modify the matrix above\n    # to set the build mode to \"manual\" for that language. Then modify this step\n    # to build your code.\n    # ℹ️ Command-line programs to run using the OS shell.\n    # 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun\n      - name: Run manual build steps\n        if: matrix.build-mode == 'manual'\n        shell: bash\n        run: |\n          echo 'If you are using a \"manual\" build mode for one or more of the' \\\n            'languages you are analyzing, replace this with the commands to build' \\\n            'your code, for example:'\n          echo '  make bootstrap'\n          echo '  make release'\n          exit 1\n\n      - name: Perform CodeQL Analysis\n        uses: github/codeql-action/analyze@v4\n        with:\n          category: \"/language:${{matrix.language}}\"\n"
  },
  {
    "path": ".github/workflows/docs.yml",
    "content": "name: Deploy Documentation\n\non:\n  push:\n    branches: [main]\n    paths:\n      - 'docs/**'\n      - 'package.json'\n      - '.github/workflows/docs.yml'\n  workflow_dispatch:\n\npermissions:\n  contents: read\n  pages: write\n  id-token: write\n\nconcurrency:\n  group: pages\n  cancel-in-progress: false\n\njobs:\n  build:\n    runs-on: ubuntu-latest\n    steps:\n      - name: Checkout\n        uses: actions/checkout@v4\n        with:\n          fetch-depth: 0\n\n      - name: Setup Node\n        uses: actions/setup-node@v4\n        with:\n          node-version: 20\n\n      - name: Setup Pages\n        uses: actions/configure-pages@v5\n\n      - name: Install dependencies\n        run: npm install\n\n      - name: Build with VitePress\n        run: npm run docs:build\n\n      - name: Upload artifact\n        uses: actions/upload-pages-artifact@v3\n        with:\n          path: docs/.vitepress/dist\n\n  deploy:\n    environment:\n      name: github-pages\n      url: ${{ steps.deployment.outputs.page_url }}\n    needs: build\n    runs-on: ubuntu-latest\n    steps:\n      - name: Deploy to GitHub Pages\n        id: deployment\n        uses: actions/deploy-pages@v4\n"
  },
  {
    "path": ".gitignore",
    "content": "#Exclude potential (c) training data\n*_lyrics.txt\n*.mp3\nAlbumArt*.jpg\nFolder.jpg\n\n\ndata/\n*.mp3\n*.wav\n\n# Byte-compiled / optimized / DLL files\n__pycache__/\n*.py[codz]\n*$py.class\n\n# C extensions\n*.so\n\n# Distribution / packaging\n.Python\nbuild/\ndevelop-eggs/\ndist/\ndownloads/\neggs/\n.eggs/\nlib/\nlib64/\nparts/\nsdist/\nvar/\nwheels/\nshare/python-wheels/\n*.egg-info/\n.installed.cfg\n*.egg\nMANIFEST\n\n# PyInstaller\n#  Usually these files are written by a python script from a template\n#  before PyInstaller builds the exe, so as to inject date/other infos into it.\n*.manifest\n*.spec\n\n# Installer logs\npip-log.txt\npip-delete-this-directory.txt\n\n# Unit test / coverage reports\nhtmlcov/\n.tox/\n.nox/\n.coverage\n.coverage.*\n.cache\nnosetests.xml\ncoverage.xml\n*.cover\n*.py.cover\n.hypothesis/\n.pytest_cache/\ncover/\n\n# Translations\n*.mo\n*.pot\n\n# Django stuff:\n*.log\nlocal_settings.py\ndb.sqlite3\ndb.sqlite3-journal\n\n# Flask stuff:\ninstance/\n.webassets-cache\n\n# Scrapy stuff:\n.scrapy\n\n# Sphinx documentation\ndocs/_build/\n\n# PyBuilder\n.pybuilder/\ntarget/\n\n# Jupyter Notebook\n.ipynb_checkpoints\n\n# IPython\nprofile_default/\nipython_config.py\n\n# pyenv\n#   For a library or package, you might want to ignore these files since the code is\n#   intended to run in multiple environments; otherwise, check them in:\n# .python-version\n\n# pipenv\n#   According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.\n#   However, in case of collaboration, if having platform-specific dependencies or dependencies\n#   having no cross-platform support, pipenv may install dependencies that don't work, or not\n#   install all needed dependencies.\n#Pipfile.lock\n\n# UV\n#   Similar to Pipfile.lock, it is generally recommended to include uv.lock in version control.\n#   This is especially recommended for binary packages to ensure reproducibility, and is more\n#   commonly ignored for libraries.\nuv.lock\n\n# poetry\n#   Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.\n#   This is especially recommended for binary packages to ensure reproducibility, and is more\n#   commonly ignored for libraries.\n#   https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control\n#poetry.lock\n#poetry.toml\n\n# pdm\n#   Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.\n#   pdm recommends including project-wide configuration in pdm.toml, but excluding .pdm-python.\n#   https://pdm-project.org/en/latest/usage/project/#working-with-version-control\n#pdm.lock\n#pdm.toml\n.pdm-python\n.pdm-build/\n\n# pixi\n#   Similar to Pipfile.lock, it is generally recommended to include pixi.lock in version control.\n#pixi.lock\n#   Pixi creates a virtual environment in the .pixi directory, just like venv module creates one\n#   in the .venv directory. It is recommended not to include this directory in version control.\n.pixi\n\n# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm\n__pypackages__/\n\n# Celery stuff\ncelerybeat-schedule\ncelerybeat.pid\n\n# SageMath parsed files\n*.sage.py\n\n# Environments\n.env\n.envrc\n.venv\nenv/\nvenv/\nENV/\nenv.bak/\nvenv.bak/\n\n# Spyder project settings\n.spyderproject\n.spyproject\n\n# Rope project settings\n.ropeproject\n\n# mkdocs documentation\n/site\n\n# mypy\n.mypy_cache/\n.dmypy.json\ndmypy.json\n\n# Pyre type checker\n.pyre/\n\n# pytype static type analyzer\n.pytype/\n\n# Cython debug symbols\ncython_debug/\n\n# PyCharm\n#  JetBrains specific template is maintained in a separate JetBrains.gitignore that can\n#  be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore\n#  and can be added to the global gitignore or merged into this file.  For a more nuclear\n#  option (not recommended) you can uncomment the following to ignore the entire idea folder.\n#.idea/\n\n# Abstra\n# Abstra is an AI-powered process automation framework.\n# Ignore directories containing user credentials, local state, and settings.\n# Learn more at https://abstra.io/docs\n.abstra/\n\n# Visual Studio Code\n#  Visual Studio Code specific template is maintained in a separate VisualStudioCode.gitignore \n#  that can be found at https://github.com/github/gitignore/blob/main/Global/VisualStudioCode.gitignore\n#  and can be added to the global gitignore or merged into this file. However, if you prefer, \n#  you could uncomment the following to ignore the entire vscode folder\n# .vscode/\n\n# Ruff stuff:\n.ruff_cache/\n\n# PyPI configuration file\n.pypirc\n\n# Cursor\n#  Cursor is an AI-powered code editor. `.cursorignore` specifies files/directories to\n#  exclude from AI features like autocomplete and code analysis. Recommended for sensitive data\n#  refer to https://docs.cursor.com/context/ignore-files\n.cursorignore\n.cursorindexingignore\n\n# Marimo\nmarimo/_static/\nmarimo/_lsp/\n__marimo__/\ntests/\ncheckpoints/\nplayground.ipynb\n.history/\nupload_checkpoints.sh\ncheckpoints.7z\nREADME_old.md\ndiscord_bot/\nfeishu_bot/\ntmp*\ntorchinductor_root/\nscripts/*.pyc\nscripts/__pycache__/\n!scripts/check_gpu.py\n!scripts/prepare_vae_calibration_data.py\ncheckpoints_legacy/\nlora_output/\ndatasets/\npython_embeded/\ncheckpoints_pack/\nissues/\nPortableGit/\nproxy_config.txt\ngradio_outputs/\nacestep/third_parts/vllm/\ntest_lora_scale_fix.py\nlokr_output/\n.claude/skills/acestep/scripts/config.json\n.claude/skills/acestep/scripts/.first_gen_done\n.claude/skills/acestep-simplemv/scripts/public/\nconfig.json\n\nacestep_output/\n# macOS\n.DS_Store\n\n# VitePress / Node\nnode_modules/\ndocs/.vitepress/dist/\ndocs/.vitepress/cache/\ndocs/en/awesome.md\npackage-lock.json"
  },
  {
    "path": "AGENTS.md",
    "content": "# AGENTS.md\n\nGuidance for AI coding agents working in `ace-step/ACE-Step-1.5`.\n\nThis document is aligned with the intent from:\n- Discussion #408: functional decomposition to reduce risk from large mixed-responsibility files.\n- Discussion #365: low-risk contribution workflow, minimal scope, and review rigor.\n\n## Primary Objectives\n\n1. Keep changes safe and reviewable.\n2. Prefer small, maintainable, decomposed modules.\n3. Preserve behavior outside the target fix.\n4. Validate with focused Python unit tests.\n\n## Build, Lint, and Test Commands\n\n```bash\n# Install dependencies\nuv sync\n\n# Run all tests (unittest-based, discovery in */*_test.py and test_*.py)\nuv run python -m unittest discover -s . -p \"*_test.py\"\nuv run python -m unittest discover -s . -p \"test_*.py\"\n\n# Run a single test file\nuv run python -m unittest acestep.training.test_lora_utils\n\n# Run a specific test class\nuv run python -m unittest acestep.training.test_lora_utils.TestUnwrapDecoder\n\n# Run a single test method\nuv run python -m unittest acestep.training.test_lora_utils.TestUnwrapDecoder.test_returns_module_directly\n\n# Run all tests in a directory\nuv run python -m unittest discover -s acestep/training -p \"*_test.py\"\n```\n\n## Scope and Change Control (Required)\n\n- Solve one problem per task/PR.\n- Keep edits minimal: touch only files/functions required for the requested change.\n- Do not make drive-by refactors, formatting sweeps, or opportunistic cleanups.\n- Do not alter non-target hardware/runtime paths (CPU/CUDA/MPS/XPU) unless required by the task.\n- If any cross-path change is necessary, isolate it and justify it in the PR notes.\n- Preserve existing public interfaces unless the task explicitly requires an interface change.\n\n## Decomposition and Module Size Policy\n\n- Prefer single-responsibility modules with clear boundaries.\n- Target module size:\n  - Optimal: `<= 150` LOC\n  - Hard cap: `200` LOC\n- Function decomposition rules:\n  - Do one thing at a time; if a function description naturally contains \"and\", split it.\n  - Split by responsibility, not by convenience.\n  - Keep data flow explicit (`data in, data out`); side effects must be obvious and deliberate.\n  - Push decisions up and push work down (orchestration at higher layers, execution details in lower layers).\n  - The call graph should read clearly from top-level orchestration to leaf operations.\n- If a module would exceed `200` LOC:\n  - Split by responsibility before merging, or\n  - Add a short justification in PR notes and include a concrete follow-up split plan.\n- Keep orchestrator/facade modules thin. Move logic into focused helpers/services.\n- Preserve stable facade imports when splitting large files so external callers are not broken.\n\n## Python Unit Testing Expectations\n\n- Add or update tests for every behavior change and bug fix.\n- Match repository conventions:\n  - Use `unittest`-style tests.\n  - Name test files as `*_test.py` or `test_*.py`.\n- Keep tests deterministic, fast, and scoped to changed behavior.\n- Use `unittest.mock.MagicMock` and `unittest.mock.patch` for mocking.\n- Mock GPU, filesystem, network, and external services where possible.\n- If a change requires mocking a large portion of the system to test one unit, treat that as a decomposition smell and refactor boundaries.\n- Include at least:\n  - One success-path test.\n  - One regression/edge-case test for the bug being fixed.\n  - One non-target behavior check when relevant.\n- Run targeted tests locally before submitting.\n\n## Code Style Guidelines\n\n- **Python version**: 3.11-3.12\n- **Indentation**: 4 spaces (no tabs)\n- **Line length**: Maximum 100 characters (recommended). See `pyproject.toml` for configured formatter limits. Exceptions allowed for URLs and long strings where wrapping would hurt readability.\n- **Strings**: Double quotes `\"` preferred\n- **Imports**: Group by type (stdlib, third-party, local), sort alphabetically within groups\n\n```python\n# Example import ordering\nimport os\nimport tempfile\nfrom pathlib import Path\nfrom typing import Any\nfrom unittest.mock import MagicMock, patch\n\nimport torch\nimport torch.nn as nn\n\nfrom acestep.training.lora_injection import inject_lora_into_dit\n```\n\n**Naming conventions**:\n- `snake_case` for functions, variables, and module names\n- `PascalCase` for classes\n- `UPPER_SNAKE_CASE` for constants\n- Prefix private/internal names with underscore: `_internal_func`, `_private_var`\n\n**Type hints**: Add type annotations for new/modified functions when practical.\n\n**Docstrings**: Mandatory for all modules, classes, and public functions. Use concise format:\n\n```python\ndef inject_lora_into_dit(\n    dit: nn.Module,\n    config: dict[str, Any],\n    target_modules: list[str],\n) -> nn.Module:\n    \"\"\"Inject LoRA adapters into DiT model for parameter-efficient fine-tuning.\n\n    Args:\n        dit: The Diffusion Transformer model to modify.\n        config: LoRA configuration dictionary.\n        target_modules: List of module names to apply LoRA to.\n\n    Returns:\n        The modified DiT model with LoRA adapters injected.\n    \"\"\"\n```\n\n**Error handling**:\n- Avoid bare `except:` clauses; catch specific exceptions\n- Use custom exceptions for domain errors\n- Log errors with `loguru.logger` (not `print()`)\n- Let exceptions propagate for truly exceptional conditions\n\n**Logging**:\n- Use `from loguru import logger` and `logger.info()`, `logger.error()`, etc.\n- Keep logs actionable and debug-level for development\n- Avoid `print()` in committed code except CLI output\n\n**Multi-platform support** (CUDA, ROCm, Intel XPU, MPS, MLX, CPU):\n- Use `gpu_config.py` for hardware detection\n- Do not alter non-target platform paths unless explicitly required\n- Changes to CUDA code should not break MPS/XPU/CPU paths\n\n## Feature Gating and WIP Safety\n\n- Do not expose unfinished or non-functional user-facing flows by default.\n- Gate WIP or unstable UI/API paths behind explicit feature/release flags.\n- Keep default behavior stable; \"coming soon\" paths must not appear as usable functionality unless they are operational and tested.\n\n## Python Coding Best Practices\n\n- Use explicit, readable code over clever shortcuts.\n- Docstrings are mandatory for all new or modified Python modules, classes, and functions.\n- Docstrings must be concise and include purpose plus key inputs/outputs (and raised exceptions when relevant).\n- Add type hints for new/modified functions when practical.\n- Keep functions focused and short; extract helpers instead of nesting complexity.\n- Use clear names that describe behavior, not implementation trivia.\n- Prefer pure functions for logic-heavy paths where possible.\n- Avoid duplicated logic, but do not introduce broad abstractions too early; prefer simple local duplication over unstable premature abstraction.\n- Handle errors explicitly; avoid bare `except`.\n- Keep logging actionable; avoid noisy logs and `print` debugging in committed code.\n- Avoid hidden state and unintended side effects.\n- Write comments only where intent is non-obvious; keep comments concise and technical.\n\n## AI-Agent Workflow (Recommended)\n\n1. Understand the task and define explicit in-scope/out-of-scope boundaries.\n2. Propose a minimal patch plan before editing.\n3. Implement the smallest viable change.\n4. Add/update focused tests.\n5. Self-review only changed hunks for regressions and scope creep.\n6. Summarize risk, validation, and non-target impact in PR notes.\n\n## PR Readiness Checklist\n\n- [ ] Change is tightly scoped to one problem.\n- [ ] Non-target paths are unchanged, or changes are explicitly justified.\n- [ ] New/updated tests cover changed behavior and edge cases.\n- [ ] No unrelated refactor/formatting churn.\n- [ ] Required docstrings are present for all new/modified modules, classes, and functions.\n- [ ] WIP/unstable functionality is feature-flagged and not exposed as default-ready behavior.\n- [ ] Module LOC policy is met (`<=150` target, `<=200` hard cap or justified exception).\n"
  },
  {
    "path": "CONTRIBUTING.md",
    "content": "Hopefully this will provide a simple, easy to understand guide to making safe contributions to the project, happy coding!\n\n\n## Why This Matters\n\nThis project supports **many hardware and runtime combinations**.\nA change that works perfectly on one setup can unintentionally break another if scope is not tightly controlled.\n\nThe project has kind of gone viral, and has thousands of users, amateur, semi professional and professional, technical and none technical, it is important that Ace-Step has reliable builds to maintain user trust and engagement.\n\nRecent PR patterns have shown avoidable regressions, for example:\n\n- Fixes that changed behaviour outside the intended target path\n- Hardware-specific assumptions leaking into general code paths\n- String / status handling changes that broke downstream logic\n- Missing or weak review before merge\n\nThe goal here is **not blame**.\nThe goal is **predictable, low-risk contributions** that maintainers can trust and merge with confidence.\n\n---\n\n## Core Principles for Contributors\n\n### Solve One Problem at a Time\n- Keep each PR focused on **a single bug or feature**.\n- Do **not** mix refactors, formatting, and behaviour changes unless absolutely required.\n\n### Minimize Blast Radius\n- Touch **only** the files and functions required for the fix.\n- Avoid “drive-by improvements” in unrelated code.\n\n### Preserve Non-Target Platforms\n- If fixing **CUDA behaviour**, do not change **CPU / MPS / XPU** paths unless needed.\n- Explicitly state **“non-target platforms unchanged”** in the PR notes — and verify it.\n\n### Prove the Change\n- Add or run **targeted checks** for the affected path.\n- Include a short **regression checklist** in the PR description.\n\n### Be Explicit About Risk\n- Call out edge cases and trade-offs up front.\n- If uncertain, say so and ask maintainers or experienced contributors for preferred direction.\n\nClarity beats confidence.\n\n---\n## AI Prompt Guardrails for Multi-Platform Projects\n\nTell your coding agent explicitly:\n\n- Ask for a proposal and plan before making code changes.\n- Make only the **minimum required changes** for the target issue.\n- Do **not** refactor unrelated code.\n- Do **not** alter non-target hardware/runtime paths unless required.\n- If a cross-platform change is necessary, **isolate and justify it explicitly**.\n- Preserve existing behaviour and interfaces unless the bug fix requires change.\n\nThese guardrails dramatically reduce accidental regressions from broad AI edits.\n\n---\n\n## Recommended AI-Assisted Workflow (Copilot / CodePilot / Codex)\n\n### Step 1: Commit-Scoped Review (First Pass)\nOnce you feel work is complete, and whatever manual or automated testing passes, commit your work to your local project. Note the commit number, or ask your agent to provide the number for your latest commit.\n\n**Use a different agent to review your work than was used to produce the work**\n\nIf you use Claud or OpenAI codex, use your free Copilot tokens in VScode to get a Copilot review. If in doubt, ask your main agent to formulate a prompt for the review agent. It will 'know' what it has worked on and can suggest appropriate focus areas for the review agent.\n\nAsk the agent to review **only your commit diff**, not the whole repo.\n\nPrompt example:\n\nReview commit <sha> only.\nFocus on regressions, behaviour changes, and missing tests.\nIgnore pre-existing issues outside changed hunks.\nOutput findings by severity with file/line references.\n\nFix the issues raised by the review, rerun the review process until only non-breaking trivial issues exist. This may need to be repeated a number of times until the commit is clean, but watch that this does not incorrectly blow scope out beyond what is required for the primary fix.\n---\n\n### Step 2: Validate Findings\n\nClassify each finding as:\n\n- **Accept** — real issue introduced or exposed by your change\n- **Rebut** — incorrect or out-of-scope concern\n- **Pre-existing** — not introduced by this PR (note separately)\n\n---\n\n### Step 3: Apply Minimal Fixes\n- Fix **accepted** issues with the **smallest possible patch**.\n- Do **not** broaden scope or refactor opportunistically.\n\n---\n\n### Step 4: PR-Scoped Review (Second Pass)\n\nRun review on the **entire PR diff**, but only what changed.\n\nPrompt example:\n\nReview PR diff only (base <base>, head <head>), \n(or alternatively, \"treat commit a/b/c... as a whole.\")\nPrioritize regression risk across hardware paths.\nVerify unchanged behaviour on non-target platforms.\nFlag only issues in changed code.\n\n---\n\n### Step 5: Write Reviewer Responses\n\nFor each reviewer comment:\n\n- Quote the concern\n- Respond in one line\n- Mark disposition clearly\n- Link to fix if applicable\n\n---\n\n## Review / Accept / Rebut / Fix Cycle (Practical Template)\n\nUse this structure in your notes:\n\nComment: <reviewer concern>\nDisposition: Accepted | Rebutted | Pre-existing\nResponse: <one-line rationale>\nAction: <commit / file / line> or No code change\n\nThis keeps discussion **objective, fast, and easy to follow**.\n\n---\n\n## PR Description Template (Recommended)\n\n### Summary\n- What bug or feature is addressed\n- Why this change is needed\n\n### Scope\n- Files changed\n- What is explicitly **out of scope**\n\n### Risk and Compatibility\n- Target platform / path\n- Confirmation that **non-target paths are unchanged**\n  (or describe exactly what changed and why)\n\n### Regression Checks\n- Checks run (manual and/or automated)\n- Key scenarios validated\n\n### Reviewer Notes\n- Known pre-existing issues not addressed\n- Follow-up items (if any)\n\nYour PR description should look something like [this](https://github.com/ace-step/ACE-Step-1.5/pull/309), demonstrating care and rigor applied by the author before hitting the PR button. If you have multiple Coderabbit/copilot responses to your PR, its probably a good idea to revoke the PR, fix the issues raised by the review bot, and resubmit.\n\n---\n\nMaintainers are balancing **correctness, stability, and review bandwidth**.\n\nPRs that are:\n- tightly scoped\n- clearly explained\n- minimally risky\n- easy to reason about\n\nare **much more likely to be reviewed and merged quickly**.\n\nThanks for helping keep the project stable and enjoyable to work on.\n"
  },
  {
    "path": "Dockerfile.jetson",
    "content": "# =============================================================================\n# ACE-Step 1.5 — NVIDIA Jetson Dockerfile\n# =============================================================================\n#\n# Builds ACE-Step 1.5 with GPU acceleration for NVIDIA Jetson platforms.\n#\n# Supported hardware:\n#   - Jetson Orin Nano  (4/8 GB unified memory)\n#   - Jetson Orin NX    (8/16 GB)\n#   - Jetson AGX Orin   (32/64 GB)\n#   - Jetson Xavier NX / AGX Xavier (JetPack 5.x — see JetPack 5 note below)\n#\n# Requirements:\n#   - JetPack 6.x installed on the Jetson (L4T R36.x)\n#   - NVIDIA Container Runtime (`nvidia-docker2` or `nvidia-container-toolkit`)\n#   - Docker with BuildKit (Docker >= 20.10)\n#\n# Build:\n#   docker build -f Dockerfile.jetson -t acestep-jetson .\n#\n# Run (Gradio UI — default, models pre-loaded at startup):\n#   docker run --runtime nvidia -it --rm \\\n#     -p 7860:7860 \\\n#     -v $(pwd)/checkpoints:/app/checkpoints \\\n#     -v $(pwd)/gradio_outputs:/app/gradio_outputs \\\n#     acestep-jetson\n#\n# Run (REST API server):\n#   docker run --runtime nvidia -it --rm \\\n#     -p 8001:8001 \\\n#     -v $(pwd)/checkpoints:/app/checkpoints \\\n#     -e ACESTEP_MODE=api \\\n#     acestep-jetson\n#\n# Run without pre-initialization (deferred to UI \"Initialize\" button):\n#   docker run --runtime nvidia -it --rm \\\n#     -p 7860:7860 \\\n#     -v $(pwd)/checkpoints:/app/checkpoints \\\n#     -e ACESTEP_INIT_SERVICE=false \\\n#     acestep-jetson\n#\n# ---- JetPack 5.x (Xavier) ----\n# Override build args for JetPack 5:\n#   docker build -f Dockerfile.jetson \\\n#     --build-arg L4T_VERSION=r35.5.0 \\\n#     -t acestep-jetson-jp5 .\n#\n# =============================================================================\n\n# ==================== Build arguments ====================\n\n# L4T JetPack image tag — must match your Jetson's JetPack installation.\n# JetPack 6.2 → r36.4.0 | JetPack 6.1 → r36.3.0 | JetPack 6.0 → r36.2.0\n# The l4t-jetpack image includes CUDA toolkit, cuDNN and TensorRT.\nARG L4T_VERSION=r36.4.0\n\n# ==================== Base image ====================\nFROM nvcr.io/nvidia/l4t-jetpack:${L4T_VERSION}\n\nENV DEBIAN_FRONTEND=noninteractive\nENV LANG=C.UTF-8\nENV LC_ALL=C.UTF-8\n\n# ==================== System packages ====================\n# NOTE: We use the system Python 3.10 (shipped with Ubuntu 22.04 / L4T) because\n# NVIDIA's Jetson AI Lab only publishes PyTorch wheels for cp310.\n# The ACE-Step codebase is compatible with Python 3.10.\nRUN apt-get update && apt-get install -y --no-install-recommends \\\n        software-properties-common \\\n        build-essential \\\n        cmake \\\n        git \\\n        curl \\\n        wget \\\n        pkg-config \\\n        python3-dev \\\n        python3-venv \\\n        # Audio processing libraries\n        libsndfile1 \\\n        libsndfile1-dev \\\n        # FFmpeg build dependencies (we build FFmpeg 7 from source for torchcodec)\n        nasm \\\n        yasm \\\n        libx264-dev \\\n        libx265-dev \\\n        libmp3lame-dev \\\n        libopus-dev \\\n        libvorbis-dev \\\n        # BLAS / LAPACK for scipy & numpy on aarch64\n        libopenblas-dev \\\n        liblapack-dev \\\n        gfortran \\\n    && rm -rf /var/lib/apt/lists/*\n\n# ==================== FFmpeg 7 (from source) ====================\n# torchcodec 0.10.0 requires FFmpeg 7 shared libraries (libavfilter.so.10,\n# libavcodec.so.61, etc.). Ubuntu 22.04 ships FFmpeg 4.4 which is too old.\n# We build a minimal FFmpeg 7.1 with shared libs and install to /usr/local.\nARG FFMPEG_VERSION=7.1\nRUN cd /tmp \\\n    && curl -fSL \"https://ffmpeg.org/releases/ffmpeg-${FFMPEG_VERSION}.tar.xz\" -o ffmpeg.tar.xz \\\n    && tar xf ffmpeg.tar.xz \\\n    && cd ffmpeg-${FFMPEG_VERSION} \\\n    && ./configure \\\n        --prefix=/usr/local \\\n        --enable-shared \\\n        --disable-static \\\n        --enable-gpl \\\n        --enable-libx264 \\\n        --enable-libx265 \\\n        --enable-libmp3lame \\\n        --enable-libopus \\\n        --enable-libvorbis \\\n        --disable-doc \\\n        --disable-programs \\\n    && make -j$(nproc) \\\n    && make install \\\n    && ldconfig \\\n    && cd /tmp && rm -rf ffmpeg* \\\n    && echo \"FFmpeg $(ffmpeg -version 2>&1 | head -1 || echo 'libs installed')\"\n\n# Ensure 'python' -> python3 symlink exists.\nRUN ln -sf /usr/bin/python3 /usr/bin/python\n\n# Bootstrap pip and install a modern numpy (base image ships 1.21 for 3.10).\nRUN curl -sS https://bootstrap.pypa.io/get-pip.py | python3 \\\n    && pip install --no-cache-dir --upgrade pip setuptools wheel \\\n    && pip install --no-cache-dir \"numpy>=1.24\"\n\n# ==================== PyTorch — Jetson-optimised wheels ====================\n# Installed from NVIDIA's Jetson AI Lab pip index which provides aarch64\n# wheels compiled specifically for Jetson GPUs (SM 8.7 / Orin architecture).\n# Standard PyPI cu126 wheels do NOT include SM 8.7 kernels and will fail\n# with \"no kernel image is available for execution on the device\".\nARG JETSON_PIP_INDEX=https://pypi.jetson-ai-lab.io/jp6/cu126/+simple/\n\n# nvidia-cudss-cu12 provides libcudss.so.0 which torch 2.9+ requires at import.\n# IMPORTANT: nvidia-cudss-cu12 from PyPI pulls in nvidia-cublas-cu12 and\n# nvidia-cuda-runtime-cu12 for a *newer* CUDA (12.9).  These conflict with the\n# CUDA 12.6 system libs shipped in l4t-jetpack and cause CUBLAS_STATUS errors.\n# We keep ONLY the cudss .so and remove the conflicting cublas/cuda-runtime pkgs\n# so that torch uses the system CUDA 12.6 libraries at runtime.\nENV NVIDIA_PYTHON_LIBS=/usr/local/lib/python3.10/dist-packages/nvidia\nENV LD_LIBRARY_PATH=\"${NVIDIA_PYTHON_LIBS}/cu12/lib:${LD_LIBRARY_PATH}\"\n\nRUN pip install --no-cache-dir nvidia-cudss-cu12 \\\n    && pip uninstall -y nvidia-cublas-cu12 nvidia-cuda-runtime-cu12 \\\n        nvidia-cusparse-cu12 nvidia-nvjitlink-cu12 2>/dev/null || true \\\n    && echo \"${NVIDIA_PYTHON_LIBS}/cu12/lib\" > /etc/ld.so.conf.d/nvidia-cudss.conf \\\n    && ldconfig \\\n    && pip install --no-cache-dir \\\n        \"torch==2.9.1\" \"torchvision==0.24.1\" \"torchaudio==2.9.1\" \\\n        --index-url ${JETSON_PIP_INDEX} \\\n    && python -c \"import torch; print(f'PyTorch {torch.__version__}  CUDA avail: {torch.cuda.is_available()}  Archs: {torch.cuda.get_arch_list()}')\" \\\n    || echo \"WARNING: torch import check failed (expected during build without GPU — will work at runtime with --runtime nvidia)\"\n\n# torchcodec — required by torchaudio 2.9+ as the default audio decoder.\n# The Jetson AI Lab prebuilt wheel has an ABI mismatch (links against desktop\n# NVDEC / libnvcuvid.so.1 which doesn't exist on Jetson).  We build v0.10.0\n# from source with ENABLE_CUDA=0 (CPU-only FFmpeg decode, which is all we need\n# for audio).  pybind11 is required at build time.\n# HARD REQUIREMENT: build will fail if torchcodec cannot be compiled.\nARG TORCHCODEC_VERSION=v0.10.0\nRUN pip install --no-cache-dir pybind11 \\\n    && cd /tmp \\\n    && git clone --depth 1 --branch ${TORCHCODEC_VERSION} \\\n        https://github.com/pytorch/torchcodec.git \\\n    && cd torchcodec \\\n    && CMAKE_PREFIX_PATH=\"$(python -c 'import pybind11; print(pybind11.get_cmake_dir())'):${CMAKE_PREFIX_PATH}\" \\\n       PKG_CONFIG_PATH=\"/usr/local/lib/pkgconfig:${PKG_CONFIG_PATH}\" \\\n       ENABLE_CUDA=0 \\\n       I_CONFIRM_THIS_IS_NOT_A_LICENSE_VIOLATION=1 \\\n       pip install --no-cache-dir --no-build-isolation . \\\n    && cd /tmp && rm -rf torchcodec \\\n    && python -c \"import torchcodec; print(f'torchcodec {torchcodec.__version__}')\"\n\n# ==================== Project source ====================\nWORKDIR /app\nCOPY . /app/\n\n# ==================== Python dependencies ====================\n# We install dependencies explicitly rather than via `pip install .` because\n# pyproject.toml's aarch64 markers point to cu130 wheels (DGX Spark), which\n# are incompatible with Jetson's CUDA 12.x.\n#\n# Excluded packages (Jetson-incompatible):\n#   - torch/torchvision/torchaudio  → already installed from Jetson wheels\n#   - mlx / mlx-lm                  → Apple Silicon only\n#   - torchcodec                    → installed separately from Jetson AI Lab index\n\n# Core + training + API dependencies\nRUN pip install --no-cache-dir \\\n        \"transformers>=4.51.0,<4.58.0\" \\\n        \"diffusers\" \\\n        \"gradio==6.2.0\" \\\n        \"matplotlib>=3.7.5\" \\\n        \"scipy>=1.10.1\" \\\n        \"soundfile>=0.13.1\" \\\n        \"loguru>=0.7.3\" \\\n        \"einops>=0.8.1\" \\\n        \"accelerate>=1.12.0\" \\\n        \"fastapi>=0.110.0\" \\\n        \"diskcache\" \\\n        \"uvicorn[standard]>=0.27.0\" \\\n        \"numba>=0.63.1\" \\\n        \"vector-quantize-pytorch>=1.27.15\" \\\n        \"toml\" \\\n        \"safetensors\" \\\n        \"modelscope\" \\\n        \"peft>=0.18.0\" \\\n        \"lycoris-lora\" \\\n        \"lightning>=2.0.0\" \\\n        \"tensorboard>=2.20.0\" \\\n        \"typer-slim>=0.21.1\" \\\n        \"xxhash\" \\\n        \"pyyaml\" \\\n        \"bitsandbytes>=0.49.0\"\n\n# torchao — DISABLED on Jetson.\n# The original diffusers 0.36.0 logger bug is fixed in 0.37.0+, but torchao\n# 0.16.0 skips its C++ extensions with torch 2.9.1 (\"incompatible torch\n# version\") making quantization ops non-functional.  Since ACE-Step does not\n# use torchao quantization, installing it adds noise without benefit.\n# Re-evaluate when Jetson AI Lab ships a torch build that torchao supports.\n\n# ==================== Triton + nano-vllm ====================\n# Triton aarch64 wheels are available on the Jetson AI Lab index.\n# flash-attn is NOT installed: the Jetson AI Lab wheels are compiled against an\n# older PyTorch ABI and crash on import with torch 2.9.x (undefined SymInt\n# symbols). nano-vllm gracefully falls back to SDPA attention without flash-attn.\n# nano-vllm is installed from the bundled source with --no-deps to avoid pulling\n# x86-only flash-attn wheels from its pyproject.toml.\n# HARD REQUIREMENT: build will fail if nano-vllm cannot be installed.\n#\n# Triton requires ptxas and cuda.h from the CUDA toolkit — we set the env var\n# and create a symlink so triton's nvidia backend can find them.\nENV TRITON_PTXAS_PATH=/usr/local/cuda/bin/ptxas\nRUN pip install --no-cache-dir \\\n        \"triton>=3.4.0\" \\\n        --index-url ${JETSON_PIP_INDEX} \\\n    && mkdir -p /usr/local/lib/python3.10/dist-packages/triton/backends/nvidia/include \\\n    && ln -sf /usr/local/cuda/include/cuda.h \\\n              /usr/local/lib/python3.10/dist-packages/triton/backends/nvidia/include/cuda.h \\\n    && pip install --no-cache-dir --no-deps /app/acestep/third_parts/nano-vllm \\\n    && python -c \"import nanovllm; print('nano-vllm OK')\"\n\n# ==================== Runtime directories ====================\nRUN mkdir -p /app/checkpoints /app/gradio_outputs\n\n# ==================== Jetson environment defaults ====================\n\n# LLM backend: \"vllm\" uses nano-vllm with paged KV cache (recommended for\n# ≥24GB VRAM with the 4B LM model).  CUDA graph capture is automatically\n# disabled on Jetson (enforce_eager) since SDPA paged-cache decode is\n# incompatible with graph capture.\nENV ACESTEP_LLM_BACKEND=vllm\n\n# Bind to all interfaces so Docker port-mapping works.\nENV ACESTEP_API_HOST=0.0.0.0\nENV GRADIO_SERVER_NAME=0.0.0.0\n\n# Default startup mode: \"gradio\" for the web UI, \"api\" for the REST server.\nENV ACESTEP_MODE=gradio\n\n# Auto-initialize models on startup so users can generate immediately.\n# Set to \"false\" to defer initialization to the UI \"Initialize\" button.\nENV ACESTEP_INIT_SERVICE=true\n\n# Default DiT model to load at startup (must exist in /app/checkpoints).\nENV ACESTEP_CONFIG_PATH=acestep-v15-turbo\n\n# Default LM model — 4B gives best quality on ≥24GB GPUs (see README).\n# Use \"acestep-5Hz-lm-0.6B\" or \"acestep-5Hz-lm-1.7B\" for lower VRAM.\nENV ACESTEP_LM_MODEL_PATH=acestep-5Hz-lm-4B\n\n# Disable tokenizers parallelism (avoids fork warnings in containers).\nENV TOKENIZERS_PARALLELISM=false\n\n# ==================== Ports ====================\n# 7860 = Gradio web UI | 8001 = REST API server\nEXPOSE 7860 8001\n\n# ==================== Health check ====================\n# Lightweight probe: the Gradio or API server must be listening.\nHEALTHCHECK --interval=60s --timeout=10s --start-period=120s --retries=3 \\\n    CMD curl -sf http://localhost:${GRADIO_PORT:-7860}/ > /dev/null 2>&1 \\\n     || curl -sf http://localhost:${ACESTEP_API_PORT:-8001}/health > /dev/null 2>&1 \\\n     || exit 1\n\n# ==================== Entrypoint ====================\nCOPY <<'EOF' /app/docker-entrypoint.sh\n#!/usr/bin/env bash\nset -e\n\necho \"===========================================\"\necho \"  ACE-Step 1.5 — NVIDIA Jetson Container\"\necho \"===========================================\"\necho \"Mode      : ${ACESTEP_MODE}\"\necho \"Python    : $(python --version 2>&1)\"\necho \"PyTorch   : $(python -c 'import torch; print(torch.__version__)' 2>/dev/null || echo 'N/A')\"\n\nif python -c 'import torch; assert torch.cuda.is_available()' 2>/dev/null; then\n    echo \"CUDA      : $(python -c 'import torch; print(torch.version.cuda)')\"\n    echo \"GPU       : $(python -c 'import torch; print(torch.cuda.get_device_name(0))')\"\n    echo \"Memory    : $(python -c 'import torch; p=torch.cuda.get_device_properties(0); print(f\"{p.total_memory/1024**3:.1f} GB\")')\"\nelse\n    echo \"CUDA      : NOT AVAILABLE — running on CPU\"\n    echo \"           (make sure you launched with --runtime nvidia)\"\nfi\necho \"===========================================\"\n\n# Build --init_service flags when ACESTEP_INIT_SERVICE=true\nINIT_ARGS=\"\"\nif [ \"${ACESTEP_INIT_SERVICE:-true}\" = \"true\" ]; then\n    INIT_ARGS=\"--init_service true\"\n    [ -n \"${ACESTEP_CONFIG_PATH:-}\" ]   && INIT_ARGS=\"${INIT_ARGS} --config_path ${ACESTEP_CONFIG_PATH}\"\n    [ -n \"${ACESTEP_LM_MODEL_PATH:-}\" ] && INIT_ARGS=\"${INIT_ARGS} --init_llm true --lm_model_path ${ACESTEP_LM_MODEL_PATH}\"\n    echo \"Auto-init    : DiT=${ACESTEP_CONFIG_PATH:-auto}  LM=${ACESTEP_LM_MODEL_PATH:-none}\"\nfi\n\nif [ \"${ACESTEP_MODE}\" = \"api\" ]; then\n    echo \"Starting REST API server on 0.0.0.0:${ACESTEP_API_PORT:-8001} ...\"\n    exec python -m acestep.api_server \\\n        --host \"${ACESTEP_API_HOST:-0.0.0.0}\" \\\n        --port \"${ACESTEP_API_PORT:-8001}\" \\\n        ${ACESTEP_EXTRA_ARGS:-}\nelse\n    echo \"Starting Gradio UI on 0.0.0.0:${GRADIO_PORT:-7860} ...\"\n    exec python -m acestep.acestep_v15_pipeline \\\n        --server-name \"${GRADIO_SERVER_NAME:-0.0.0.0}\" \\\n        --port \"${GRADIO_PORT:-7860}\" \\\n        --backend \"${ACESTEP_LLM_BACKEND:-pt}\" \\\n        ${INIT_ARGS} \\\n        ${ACESTEP_EXTRA_ARGS:-}\nfi\nEOF\n\nRUN chmod +x /app/docker-entrypoint.sh\n\nENTRYPOINT [\"/app/docker-entrypoint.sh\"]\n"
  },
  {
    "path": "LICENSE",
    "content": "MIT License\n\nCopyright (c) 2026 ACEStep\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
  },
  {
    "path": "README-XPU.md",
    "content": "# ACE-Step 1.5 - Intel XPU Setup Guide\n\nQuick start guide for running ACE-Step on Intel Arc GPUs and integrated graphics.\n\n## 🎯 What You Need\n\n- **Intel Arc GPU**: A770, A750, A580, A380, or Intel integrated graphics\n- **Python 3.11**: Download from [python.org](https://www.python.org/downloads/release/python-3119/)\n- **Latest Intel GPU drivers**: Install from Intel's website\n- **Internet connection**: For first-time setup\n- **Disk space**: ~5-10 GB for dependencies\n\n## 🚀 Quick Start\n\n### Option 1: Automatic Setup (Recommended)\n\n1. **Run the setup script**:\n   ```bat\n   setup_xpu.bat\n   ```\n\n2. **Wait for installation** (takes a few minutes on first run)\n\n3. **Launch the Gradio UI**:\n   ```bat\n   start_gradio_ui_xpu.bat\n   ```\n\n4. **Open your browser**: http://127.0.0.1:7860\n\n### Option 2: Manual Setup\n\n1. **Create virtual environment**:\n   ```bat\n   python -m venv venv_xpu\n   ```\n\n2. **Activate it**:\n   ```bat\n   call venv_xpu\\Scripts\\activate\n   ```\n\n3. **Upgrade pip**:\n   ```bat\n   python -m pip install --upgrade pip\n   ```\n\n4. **Install XPU dependencies**:\n   ```bat\n   pip install -r requirements-xpu.txt\n   ```\n\n5. **Launch**:\n   ```bat\n   start_gradio_ui_xpu.bat\n   ```\n\n## 📁 Model Configuration\n\nModels should be placed in the `checkpoints` folder. If you already have models from a previous installation, they will be automatically detected.\n\n### Default Models\n- **DiT Model**: `acestep-v15-turbo` (fast generation)\n- **LM Model**: `acestep-5Hz-lm-4B` (best quality, uses CPU offload)\n\n### Launch Options\n\n1. **Automatic** (uses defaults):\n   ```bat\n   start_gradio_ui_xpu.bat\n   ```\n\n2. **Manual** (choose models interactively):\n   ```bat\n   start_gradio_ui_xpu_manual.bat\n   ```\n\n3. **API Server** (REST API access):\n   ```bat\n   start_api_server_xpu.bat\n   ```\n\n## ⚙️ XPU Environment Variables\n\nThe bat files automatically set these performance optimizations:\n\n```bat\nset SYCL_CACHE_PERSISTENT=1\nset SYCL_PI_LEVEL_ZERO_USE_IMMEDIATE_COMMANDLISTS=1\nset PYTORCH_DEVICE=xpu\nset TORCH_COMPILE_BACKEND=eager\n```\n\nThese settings improve XPU performance and are based on verified working configurations.\n\n## 🔧 Configuration (.env file)\n\nCreate a `.env` file in the root directory to customize settings:\n\n```env\n# Gradio UI Settings\nPORT=7860\nSERVER_NAME=127.0.0.1\nLANGUAGE=en\n\n# Model Settings\nACESTEP_CONFIG_PATH=acestep-v15-turbo\nACESTEP_LM_MODEL_PATH=acestep-5Hz-lm-4B\nACESTEP_OFFLOAD_TO_CPU=true\n\n# API Settings\nACESTEP_API_KEY=your-secret-key\n```\n\n## 🛠️ Troubleshooting\n\n### \"venv_xpu not found\"\nRun `setup_xpu.bat` to create the virtual environment.\n\n### \"Intel XPU not detected\"\n1. Check that your GPU drivers are up to date\n2. Verify PyTorch XPU installation:\n   ```bat\n   call venv_xpu\\Scripts\\activate\n   python -c \"import torch; print(torch.xpu.is_available())\"\n   ```\n\n### \"torch.xpu.is_available() returns False\"\nReinstall PyTorch XPU:\n```bat\ncall venv_xpu\\Scripts\\activate\npip uninstall torch torchaudio torchvision\npip install --pre torch torchaudio torchvision --index-url https://download.pytorch.org/whl/nightly/xpu\n```\n\n### Out of memory errors\n1. Use a smaller LM model (0.6B or 1.7B instead of 4B)\n2. Enable CPU offload in the UI\n3. Close other GPU-intensive applications\n\n### Audio loading issues\n- MP3/Opus/AAC files use torchaudio with ffmpeg backend (bundled)\n- FLAC/WAV files use soundfile (fastest)\n- If issues occur, try converting to WAV format\n\n## 📊 Launch Scripts\n\n| Script | Description |\n|--------|-------------|\n| `setup_xpu.bat` | One-command environment setup |\n| `start_gradio_ui_xpu.bat` | Launch Gradio web UI (automatic) |\n| `start_gradio_ui_xpu_manual.bat` | Launch Gradio UI with model selection |\n| `start_api_server_xpu.bat` | Launch REST API server |\n\n## 🎵 Audio Support\n\n- ✅ **WAV/FLAC**: Native support via soundfile (fastest)\n- ✅ **MP3**: Supported via torchaudio with ffmpeg backend\n- ✅ **Opus/AAC**: Supported via torchaudio\n\nNo additional codec installation needed!\n\n## 📝 Notes\n\n1. **First launch** takes longer as models are initialized\n2. **CPU offload** is recommended for 4B LM on GPUs with <=16GB VRAM\n3. **torch.compile** is disabled (not fully supported on XPU yet)\n4. **Python 3.11** is recommended for best compatibility\n\n## 🆘 Need Help?\n\n- Check the main documentation: `README.md`\n- Verify XPU installation: Run verification commands above\n- Update check: Bat files automatically check for updates on startup\n\n## 🎉 You're Ready!\n\nOnce setup is complete, simply run:\n```bat\nstart_gradio_ui_xpu.bat\n```\n\nAnd start creating music with ACE-Step on your Intel GPU!\n"
  },
  {
    "path": "README.md",
    "content": "<h1 align=\"center\">ACE-Step 1.5</h1>\n<h1 align=\"center\">Pushing the Boundaries of Open-Source Music Generation</h1>\n<p align=\"center\">\n    <a href=\"https://ace-step.github.io/ace-step-v1.5.github.io/\">Project</a> |\n    <a href=\"https://huggingface.co/ACE-Step/Ace-Step1.5\">Hugging Face</a> |\n    <a href=\"https://modelscope.cn/models/ACE-Step/Ace-Step1.5\">ModelScope</a> |\n    <a href=\"https://huggingface.co/spaces/ACE-Step/Ace-Step-v1.5\">Space Demo</a> |\n    <a href=\"https://discord.gg/PeWDxrkdj7\">Discord</a> |\n    <a href=\"https://arxiv.org/abs/2602.00744\">Technical Report</a> |\n    <a href=\"https://github.com/ace-step/awesome-ace-step\">Awesome ACE-Step</a>\n</p>\n\n<p align=\"center\">\n    <img src=\"./assets/organization_logos.png\" width=\"100%\" alt=\"StepFun Logo\">\n</p>\n\n## Table of Contents\n\n- [✨ Features](#-features)\n- [⚡ Quick Start](#-quick-start)\n- [🚀 Launch Scripts](#-launch-scripts)\n- [📚 Documentation](#-documentation)\n- [📖 Tutorial](#-tutorial)\n- [🏗️ Architecture](#️-architecture)\n- [🦁 Model Zoo](#-model-zoo)\n- [🔬 Benchmark](#-benchmark)\n\n## 📝 Abstract\n🚀 We present ACE-Step v1.5, a highly efficient open-source music foundation model that brings commercial-grade generation to consumer hardware. On commonly used evaluation metrics, ACE-Step v1.5 achieves quality beyond most commercial music models while remaining extremely fast—under 2 seconds per full song on an A100 and under 10 seconds on an RTX 3090. The model runs locally with less than 4GB of VRAM, and supports lightweight personalization: users can train a LoRA from just a few songs to capture their own style.\n\n🌉 At its core lies a novel hybrid architecture where the Language Model (LM) functions as an omni-capable planner: it transforms simple user queries into comprehensive song blueprints—scaling from short loops to 10-minute compositions—while synthesizing metadata, lyrics, and captions via Chain-of-Thought to guide the Diffusion Transformer (DiT). ⚡ Uniquely, this alignment is achieved through intrinsic reinforcement learning relying solely on the model's internal mechanisms, thereby eliminating the biases inherent in external reward models or human preferences. 🎚️\n\n🔮 Beyond standard synthesis, ACE-Step v1.5 unifies precise stylistic control with versatile editing capabilities—such as cover generation, repainting, and vocal-to-BGM conversion—while maintaining strict adherence to prompts across 50+ languages. This paves the way for powerful tools that seamlessly integrate into the creative workflows of music artists, producers, and content creators. 🎸\n\n\n## ✨ Features\n\n<p align=\"center\">\n    <img src=\"./assets/application_map.png\" width=\"100%\" alt=\"ACE-Step Framework\">\n</p>\n\n### ⚡ Performance\n- ✅ **Ultra-Fast Generation** — Under 2s per full song on A100, under 10s on RTX 3090 (0.5s to 10s on A100 depending on think mode & diffusion steps)\n- ✅ **Flexible Duration** — Supports 10 seconds to 10 minutes (600s) audio generation\n- ✅ **Batch Generation** — Generate up to 8 songs simultaneously\n\n### 🎵 Generation Quality\n- ✅ **Commercial-Grade Output** — Quality beyond most commercial music models (between Suno v4.5 and Suno v5)\n- ✅ **Rich Style Support** — 1000+ instruments and styles with fine-grained timbre description\n- ✅ **Multi-Language Lyrics** — Supports 50+ languages with lyrics prompt for structure & style control\n\n### 🎛️ Versatility & Control\n\n| Feature | Description |\n|---------|-------------|\n| ✅ Reference Audio Input | Use reference audio to guide generation style |\n| ✅ Cover Generation | Create covers from existing audio |\n| ✅ Repaint & Edit | Selective local audio editing and regeneration |\n| ✅ Track Separation | Separate audio into individual stems |\n| ✅ Multi-Track Generation | Add layers like Suno Studio's \"Add Layer\" feature |\n| ✅ Vocal2BGM | Auto-generate accompaniment for vocal tracks |\n| ✅ Metadata Control | Control duration, BPM, key/scale, time signature |\n| ✅ Simple Mode | Generate full songs from simple descriptions |\n| ✅ Query Rewriting | Auto LM expansion of tags and lyrics |\n| ✅ Audio Understanding | Extract BPM, key/scale, time signature & caption from audio |\n| ✅ LRC Generation | Auto-generate lyric timestamps for generated music |\n| ✅ LoRA Training | One-click annotation & training in Gradio. 8 songs, 1 hour on 3090 (12GB VRAM) |\n| ✅ Quality Scoring | Automatic quality assessment for generated audio |\n\n## 🔔 Staying ahead\nStar ACE-Step on GitHub and be instantly notified of new releases\n![](assets/star.gif)\n\n## 🤝 Partners\n\n<p align=\"center\">\n    <a href=\"https://www.comfy.org/\"><img src=\"https://registry.comfy.org/_next/static/media/logo_blue.9ac227d3.png\" alt=\"ComfyUI\" height=\"40\" style=\"margin: 5px;\"></a>\n    <a href=\"https://zilliz.com/\"><img src=\"https://avatars.githubusercontent.com/u/18416694\" alt=\"Zilliz\" height=\"40\" style=\"margin: 5px;\"></a>\n    <a href=\"https://milvus.io/\"><img src=\"https://miro.medium.com/v2/resize:fit:2400/1*-VEGyAgcIBD62XtZWavy8w.png\" alt=\"Milvus\" height=\"40\" style=\"margin: 5px;\"></a>\n    <a href=\"https://zeabur.com/\"><img src=\"https://zeabur.notion.site/image/attachment%3A43bc244b-9a2d-4b96-9646-8392aa6fc862%3Alogo-dark_1.svg?table=block&id=318a221c-948e-8056-b3c0-f9c39ce543ba&spaceId=ba37aeb9-0937-401d-aa41-ce1d3b6ff778&userId=&cache=v2\" alt=\"Zeabur\" height=\"40\" width=\"40\" style=\"margin: 5px;\"></a>\n</p>\n\n## ⚡ Quick Start\n\n> **Requirements:** Python 3.11-3.12, CUDA GPU recommended (also supports MPS / ROCm / Intel XPU / CPU)\n> \n> **Note:** ROCm on Windows requires Python 3.12 (AMD officially provides Python 3.12 wheels only)\n\n```bash\n# 1. Install uv\ncurl -LsSf https://astral.sh/uv/install.sh | sh          # macOS / Linux\n# powershell -ExecutionPolicy ByPass -c \"irm https://astral.sh/uv/install.ps1 | iex\"  # Windows\n\n# 2. Clone & install\ngit clone https://github.com/ACE-Step/ACE-Step-1.5.git\ncd ACE-Step-1.5\nuv sync\n\n# 3. Launch Gradio UI (models auto-download on first run)\nuv run acestep\n\n# Or launch REST API server\nuv run acestep-api\n```\n\nOpen http://localhost:7860 (Gradio) or http://localhost:8001 (API).\n\n> 📦 **Windows users:** A [portable package](https://files.acemusic.ai/acemusic/win/ACE-Step-1.5.7z) with pre-installed dependencies is available. See [Installation Guide](./docs/en/INSTALL.md#-windows-portable-package).\n\n> 📦 **MacOS users:** A [portable package](https://files.acemusic.ai/acemusic/mac/ACE-Step-1.5.zip) with pre-installed dependencies is available. See [Installation Guide](./docs/en/INSTALL.md#-macos-portable-package).\n\n> 📖 **Full installation guide** (AMD/ROCm, Intel GPU, CPU, environment variables, command-line options): [English](./docs/en/INSTALL.md) | [中文](./docs/zh/INSTALL.md) | [日本語](./docs/ja/INSTALL.md)\n\n### 💡 Which Model Should I Choose?\n\n| Your GPU VRAM | Recommended LM Model | Backend | Notes |\n|---------------|---------------------|---------|-------|\n| **≤6GB** | None (DiT only) | — | LM disabled by default; INT8 quantization + full CPU offload |\n| **6-8GB** | `acestep-5Hz-lm-0.6B` | `pt` | Lightweight LM with PyTorch backend |\n| **8-16GB** | `acestep-5Hz-lm-0.6B` / `1.7B` | `vllm` | 0.6B for 8-12GB, 1.7B for 12-16GB |\n| **16-24GB** | `acestep-5Hz-lm-1.7B` | `vllm` | 4B available on 20GB+; no offload needed on 20GB+ |\n| **≥24GB** | `acestep-5Hz-lm-4B` | `vllm` | Best quality, all models fit without offload |\n\nThe UI automatically selects the best configuration for your GPU. All settings (LM model, backend, offloading, quantization) are tier-aware and pre-configured.\n\n> 📖 GPU compatibility details: [English](./docs/en/GPU_COMPATIBILITY.md) | [中文](./docs/zh/GPU_COMPATIBILITY.md) | [日本語](./docs/ja/GPU_COMPATIBILITY.md) | [한국어](./docs/ko/GPU_COMPATIBILITY.md)\n\n## 🚀 Launch Scripts\n\nReady-to-use launch scripts for all platforms with auto environment detection, update checking, and dependency installation.\n\n| Platform | Scripts | Backend |\n|----------|---------|---------|\n| **Windows** | `start_gradio_ui.bat`, `start_api_server.bat` | CUDA |\n| **Windows (ROCm)** | `start_gradio_ui_rocm.bat`, `start_api_server_rocm.bat` | AMD ROCm |\n| **Linux** | `start_gradio_ui.sh`, `start_api_server.sh` | CUDA |\n| **macOS** | `start_gradio_ui_macos.sh`, `start_api_server_macos.sh` | MLX (Apple Silicon) |\n\n```bash\n# Windows\nstart_gradio_ui.bat\n\n# Linux\nchmod +x start_gradio_ui.sh && ./start_gradio_ui.sh\n\n# macOS (Apple Silicon)\nchmod +x start_gradio_ui_macos.sh && ./start_gradio_ui_macos.sh\n```\n\n### ⚙️ Customizing Launch Settings\n\n**Recommended:** Create a `.env` file to customize models, ports, and other settings. Your `.env` configuration will survive repository updates.\n\n```bash\n# Copy the example file\ncp .env.example .env\n\n# Edit with your preferred settings\n# Examples in .env:\nACESTEP_CONFIG_PATH=acestep-v15-turbo\nACESTEP_LM_MODEL_PATH=acestep-5Hz-lm-1.7B\nPORT=7860\nLANGUAGE=en\n```\n\n> 📖 **Script configuration & customization:** [English](./docs/en/INSTALL.md#-launch-scripts) | [中文](./docs/zh/INSTALL.md#-启动脚本) | [日本語](./docs/ja/INSTALL.md#-起動スクリプト)\n\n## 📚 Documentation\n\n### Usage Guides\n\n| Method | Description | Documentation |\n|--------|-------------|---------------|\n| 🖥️ **Gradio Web UI** | Interactive web interface for music generation | [Guide](./docs/en/GRADIO_GUIDE.md) |\n| 🎚️ **Studio UI** | Optional HTML frontend (DAW-like) | [Guide](./docs/en/studio.md) |\n| 🎛️ **VST3 MVP Architecture** | Proposed DAW plugin architecture and scope | [Guide](./docs/en/VST3_MVP.md) |\n| 🐍 **Python API** | Programmatic access for integration | [Guide](./docs/en/INFERENCE.md) |\n| 🌐 **REST API** | HTTP-based async API for services | [Guide](./docs/en/API.md) |\n| ⌨️ **CLI** | Interactive wizard and configuration | [Guide](./docs/en/CLI.md) |\n\n### Setup & Configuration\n\n| Topic | Documentation |\n|-------|---------------|\n| 📦 Installation (all platforms) | [English](./docs/en/INSTALL.md) \\| [中文](./docs/zh/INSTALL.md) \\| [日本語](./docs/ja/INSTALL.md) |\n| 🎮 GPU Compatibility | [English](./docs/en/GPU_COMPATIBILITY.md) \\| [中文](./docs/zh/GPU_COMPATIBILITY.md) \\| [日本語](./docs/ja/GPU_COMPATIBILITY.md) |\n| 🔧 GPU Troubleshooting | [English](./docs/en/GPU_TROUBLESHOOTING.md) |\n| 🔬 Benchmark & Profiling | [English](./docs/en/BENCHMARK.md) \\| [中文](./docs/zh/BENCHMARK.md) |\n\n### Multi-Language Docs\n\n| Language | API | Gradio | Inference | Tutorial | LoRA Training | Install | Benchmark |\n|----------|-----|--------|-----------|----------|---------------|---------|-----------|\n| 🇺🇸 English | [Link](./docs/en/API.md) | [Link](./docs/en/GRADIO_GUIDE.md) | [Link](./docs/en/INFERENCE.md) | [Link](./docs/en/Tutorial.md) | [Link](./docs/en/LoRA_Training_Tutorial.md) | [Link](./docs/en/INSTALL.md) | [Link](./docs/en/BENCHMARK.md) |\n| 🇨🇳 中文 | [Link](./docs/zh/API.md) | [Link](./docs/zh/GRADIO_GUIDE.md) | [Link](./docs/zh/INFERENCE.md) | [Link](./docs/zh/Tutorial.md) | [Link](./docs/zh/LoRA_Training_Tutorial.md) | [Link](./docs/zh/INSTALL.md) | [Link](./docs/zh/BENCHMARK.md) |\n| 🇯🇵 日本語 | [Link](./docs/ja/API.md) | [Link](./docs/ja/GRADIO_GUIDE.md) | [Link](./docs/ja/INFERENCE.md) | [Link](./docs/ja/Tutorial.md) | [Link](./docs/ja/LoRA_Training_Tutorial.md) | [Link](./docs/ja/INSTALL.md) | — |\n| 🇰🇷 한국어 | [Link](./docs/ko/API.md) | [Link](./docs/ko/GRADIO_GUIDE.md) | [Link](./docs/ko/INFERENCE.md) | [Link](./docs/ko/Tutorial.md) | [Link](./docs/ko/LoRA_Training_Tutorial.md) | — | — |\n\n## 📖 Tutorial\n\n**🎯 Must Read:** Comprehensive guide to ACE-Step 1.5's design philosophy and usage methods.\n\n| Language | Link |\n|----------|------|\n| 🇺🇸 English | [English Tutorial](./docs/en/Tutorial.md) |\n| 🇨🇳 中文 | [中文教程](./docs/zh/Tutorial.md) |\n| 🇯🇵 日本語 | [日本語チュートリアル](./docs/ja/Tutorial.md) |\n\nThis tutorial covers: mental models and design philosophy, model architecture and selection, input control (text and audio), inference hyperparameters, random factors and optimization strategies.\n\n## 🔨 Train\n\n📖 **LoRA Training Tutorial** — step-by-step guide covering data preparation, annotation, preprocessing, and training:\n\n| Language | Link |\n|----------|------|\n| 🇺🇸 English | [LoRA Training Tutorial](./docs/en/LoRA_Training_Tutorial.md) |\n| 🇨🇳 中文 | [LoRA 训练教程](./docs/zh/LoRA_Training_Tutorial.md) |\n| 🇯🇵 日本語 | [LoRA トレーニングチュートリアル](./docs/ja/LoRA_Training_Tutorial.md) |\n| 🇰🇷 한국어 | [LoRA 학습 튜토리얼](./docs/ko/LoRA_Training_Tutorial.md) |\n\nSee also the **LoRA Training** tab in Gradio UI for one-click training, or [Gradio Guide - LoRA Training](./docs/en/GRADIO_GUIDE.md#lora-training) for UI reference.\n\n🔧 **Advanced Training with [Side-Step](https://github.com/koda-dernet/Side-Step)** — CLI-based training toolkit with corrected timestep sampling, LoKR adapters, VRAM optimization, gradient sensitivity analysis, and more. See the [Side-Step documentation](./docs/sidestep/Getting%20Started.md).\n\n## 🏗️ Architecture\n\n<p align=\"center\">\n    <img src=\"./assets/ACE-Step_framework.png\" width=\"100%\" alt=\"ACE-Step Framework\">\n</p>\n\n## 🦁 Model Zoo\n\n<p align=\"center\">\n    <img src=\"./assets/model_zoo.png\" width=\"100%\" alt=\"Model Zoo\">\n</p>\n\n### DiT Models\n\n| DiT Model | Pre-Training | SFT | RL | CFG | Step | Refer audio | Text2Music | Cover | Repaint | Extract | Lego | Complete | Quality | Diversity | Fine-Tunability | Hugging Face |\n|-----------|:------------:|:---:|:--:|:---:|:----:|:-----------:|:----------:|:-----:|:-------:|:-------:|:----:|:--------:|:-------:|:---------:|:---------------:|--------------|\n| `acestep-v15-base` | ✅ | ❌ | ❌ | ✅ | 50 | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | Medium | High | Easy | [Link](https://huggingface.co/ACE-Step/acestep-v15-base) |\n| `acestep-v15-sft` | ✅ | ✅ | ❌ | ✅ | 50 | ✅ | ✅ | ✅ | ✅ | ❌ | ❌ | ❌ | High | Medium | Easy | [Link](https://huggingface.co/ACE-Step/acestep-v15-sft) |\n| `acestep-v15-turbo` | ✅ | ✅ | ❌ | ❌ | 8 | ✅ | ✅ | ✅ | ✅ | ❌ | ❌ | ❌ | Very High | Medium | Medium | [Link](https://huggingface.co/ACE-Step/Ace-Step1.5) |\n| `acestep-v15-turbo-rl` | ✅ | ✅ | ✅ | ❌ | 8 | ✅ | ✅ | ✅ | ✅ | ❌ | ❌ | ❌ | Very High | Medium | Medium | To be released |\n\n### LM Models\n\n| LM Model | Pretrain from | Pre-Training | SFT | RL | CoT metas | Query rewrite | Audio Understanding | Composition Capability | Copy Melody | Hugging Face |\n|----------|---------------|:------------:|:---:|:--:|:---------:|:-------------:|:-------------------:|:----------------------:|:-----------:|--------------|\n| `acestep-5Hz-lm-0.6B` | Qwen3-0.6B | ✅ | ✅ | ✅ | ✅ | ✅ | Medium | Medium | Weak | ✅ |\n| `acestep-5Hz-lm-1.7B` | Qwen3-1.7B | ✅ | ✅ | ✅ | ✅ | ✅ | Medium | Medium | Medium | ✅ |\n| `acestep-5Hz-lm-4B` | Qwen3-4B | ✅ | ✅ | ✅ | ✅ | ✅ | Strong | Strong | Strong | ✅ |\n\n## 🔬 Benchmark\n\nACE-Step 1.5 includes `profile_inference.py`, a profiling & benchmarking tool that measures LLM, DiT, and VAE timing across devices and configurations.\n\n```bash\npython profile_inference.py                        # Single-run profile\npython profile_inference.py --mode benchmark       # Configuration matrix\n```\n\n> 📖 **Full guide** (all modes, CLI options, output interpretation): [English](./docs/en/BENCHMARK.md) | [中文](./docs/zh/BENCHMARK.md)\n\n## 📜 License & Disclaimer\n\nThis project is licensed under [MIT](./LICENSE)\n\nACE-Step enables original music generation across diverse genres, with applications in creative production, education, and entertainment. While designed to support positive and artistic use cases, we acknowledge potential risks such as unintentional copyright infringement due to stylistic similarity, inappropriate blending of cultural elements, and misuse for generating harmful content. To ensure responsible use, we encourage users to verify the originality of generated works, clearly disclose AI involvement, and obtain appropriate permissions when adapting protected styles or materials. By using ACE-Step, you agree to uphold these principles and respect artistic integrity, cultural diversity, and legal compliance. The authors are not responsible for any misuse of the model, including but not limited to copyright violations, cultural insensitivity, or the generation of harmful content.\n\n🔔 Important Notice  \nThe only official website for the ACE-Step project is our GitHub Pages site.    \n We do not operate any other websites.  \n🚫 Fake domains include but are not limited to:\nac\\*\\*p.com, a\\*\\*p.org, a\\*\\*\\*c.org  \n⚠️ Please be cautious. Do not visit, trust, or make payments on any of those sites.\n\n## 🌐 Community & Ecosystem\n\nCheck out **[Awesome ACE-Step](https://github.com/ace-step/awesome-ace-step)** — a curated list of community projects, alternative UIs, ComfyUI nodes, cloud deployments, training tools, and more built around ACE-Step.\n\n## 🙏 Acknowledgements\n\nThis project is co-led by ACE Studio and StepFun.\n\n\n## 📖 Citation\n\nIf you find this project useful for your research, please consider citing:\n\n```BibTeX\n@misc{gong2026acestep,\n\ttitle={ACE-Step 1.5: Pushing the Boundaries of Open-Source Music Generation},\n\tauthor={Junmin Gong, Yulin Song, Wenxiao Zhao, Sen Wang, Shengyuan Xu, Jing Guo}, \n\thowpublished={\\url{https://github.com/ace-step/ACE-Step-1.5}},\n\tyear={2026},\n\tnote={GitHub repository}\n}\n```\n"
  },
  {
    "path": "SECURITY.md",
    "content": "# Security Policy\n\n## Reporting a Vulnerability\n\nWe take security issues seriously and appreciate responsible disclosure.\n\nIf you believe you have found a security vulnerability, **please do not report it in a public GitHub issue**.\n\nInstead, use one of the following private channels:\n\n- Open a **GitHub Security Advisory** for this repository (preferred)\n- Or contact the maintainers directly if a private email channel is listed\n\nPlease include:\n- A clear description of the issue\n- Steps to reproduce (if applicable)\n- Potential impact\n- Any relevant proof-of-concept or logs\n\nWe will acknowledge receipt and work to assess the issue as quickly as possible.\n\n## Bug Bounties\n\nAt this time, this project does **not** operate a formal bug bounty program.  \nHowever, valid and responsibly disclosed security issues may be acknowledged in release notes or documentation at the maintainers’ discretion.\n\nThank you for helping keep the project and its users safe.\n"
  },
  {
    "path": "acestep/__init__.py",
    "content": "\"\"\"ACE-Step package.\"\"\"\n"
  },
  {
    "path": "acestep/acestep_v15_pipeline.py",
    "content": "\"\"\"\nACE-Step V1.5 Pipeline\nHandler wrapper connecting model and UI\n\"\"\"\n\nimport os\nimport sys\n\n# Load environment variables from .env file at most once per process to avoid\n# epoch-boundary stalls (e.g. on Windows when Gradio yields during training)\n_env_loaded = False  # module-level so we never reload .env in the same process\ntry:\n    from dotenv import load_dotenv\n\n    if not _env_loaded:\n        _current_file = os.path.abspath(__file__)\n        _project_root = os.path.dirname(os.path.dirname(_current_file))\n        _env_path = os.path.join(_project_root, \".env\")\n        _env_example_path = os.path.join(_project_root, \".env.example\")\n        if os.path.exists(_env_path):\n            load_dotenv(_env_path)\n            print(f\"Loaded configuration from {_env_path}\")\n        elif os.path.exists(_env_example_path):\n            load_dotenv(_env_example_path)\n            print(f\"Loaded configuration from {_env_example_path} (fallback)\")\n        _env_loaded = True\nexcept ImportError:\n    # python-dotenv not installed, skip loading .env\n    pass\n\n# Clear proxy settings that may affect Gradio\nfor proxy_var in [\n    \"http_proxy\",\n    \"https_proxy\",\n    \"HTTP_PROXY\",\n    \"HTTPS_PROXY\",\n    \"ALL_PROXY\",\n]:\n    os.environ.pop(proxy_var, None)\n\n# Force torchaudio to use ffmpeg backend (torchcodec not available on XPU/Windows)\nos.environ[\"TORCHAUDIO_USE_BACKEND\"] = \"ffmpeg\"\n\ntry:\n    # When executed as a module: `python -m acestep.acestep_v15_pipeline`\n    from .cli_args import parse_quantization_arg\n    from .handler import AceStepHandler\n    from .llm_inference import LLMHandler\n    from .dataset_handler import DatasetHandler\n    from .ui.gradio import create_gradio_interface\n    from acestep.ui.gradio.i18n import get_i18n, available_languages_info\n    from .gpu_config import (\n        get_gpu_config,\n        get_gpu_memory_gb,\n        print_gpu_config_info,\n        set_global_gpu_config,\n        VRAM_16GB_MIN_GB,\n        VRAM_AUTO_OFFLOAD_THRESHOLD_GB,\n        is_mps_platform,\n    )\n    from .model_downloader import ensure_lm_model\nexcept ImportError:\n    # When executed as a script: `python acestep/acestep_v15_pipeline.py`\n    project_root = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))\n    if project_root not in sys.path:\n        sys.path.insert(0, project_root)\n    from acestep.cli_args import parse_quantization_arg\n    from acestep.handler import AceStepHandler\n    from acestep.llm_inference import LLMHandler\n    from acestep.dataset_handler import DatasetHandler\n    from acestep.ui.gradio import create_gradio_interface\n    from acestep.ui.gradio.i18n import get_i18n, available_languages_info\n    from acestep.gpu_config import (\n        get_gpu_config,\n        get_gpu_memory_gb,\n        print_gpu_config_info,\n        set_global_gpu_config,\n        VRAM_16GB_MIN_GB,\n        VRAM_AUTO_OFFLOAD_THRESHOLD_GB,\n        is_mps_platform,\n    )\n    from acestep.model_downloader import ensure_lm_model\n\n\ndef create_demo(init_params=None, language=\"en\"):\n    \"\"\"\n    Create Gradio demo interface\n\n    Args:\n        init_params: Dictionary containing initialization parameters and state.\n                    If None, service will not be pre-initialized.\n                    Keys: 'pre_initialized' (bool), 'checkpoint', 'config_path', 'device',\n                          'init_llm', 'lm_model_path', 'backend', 'use_flash_attention',\n                          'offload_to_cpu', 'offload_dit_to_cpu', 'init_status',\n                          'dit_handler', 'llm_handler' (initialized handlers if pre-initialized),\n                          'language' (UI language code)\n        language: UI language code ('en', 'zh', 'ja', default: 'en')\n\n    Returns:\n        Gradio Blocks instance\n    \"\"\"\n    # Use pre-initialized handlers if available, otherwise create new ones\n    if (\n        init_params\n        and init_params.get(\"pre_initialized\")\n        and \"dit_handler\" in init_params\n    ):\n        dit_handler = init_params[\"dit_handler\"]\n        llm_handler = init_params[\"llm_handler\"]\n    else:\n        dit_handler = AceStepHandler()  # DiT handler\n        llm_handler = LLMHandler()  # LM handler\n\n    dataset_handler = DatasetHandler()  # Dataset handler\n\n    # Create Gradio interface with all handlers and initialization parameters\n    demo = create_gradio_interface(\n        dit_handler,\n        llm_handler,\n        dataset_handler,\n        init_params=init_params,\n        language=language,\n    )\n\n    return demo\n\n\ndef main():\n    \"\"\"Main entry function\"\"\"\n    import argparse\n\n    # Detect GPU memory and get configuration\n    gpu_config = get_gpu_config()\n    set_global_gpu_config(gpu_config)  # Set global config for use across modules\n\n    gpu_memory_gb = gpu_config.gpu_memory_gb\n    _is_mac = is_mps_platform()\n    # Enable auto-offload for GPUs below 20 GB.  16 GB GPUs cannot hold all\n    # models simultaneously (DiT ~4.7 + VAE ~0.3 + text_enc ~1.2 + LM â‰¥1.2 +\n    # activations) so they *must* offload.  The old threshold of 16 GB caused\n    # 16 GB GPUs to never offload, leading to OOM.\n    # Mac (Apple Silicon) uses unified memory â€” offloading provides no benefit.\n    auto_offload = (\n        (not _is_mac)\n        and gpu_memory_gb > 0\n        and gpu_memory_gb < VRAM_AUTO_OFFLOAD_THRESHOLD_GB\n    )\n    _default_backend = \"mlx\" if _is_mac else \"vllm\"\n\n    # Print GPU configuration info\n    print(f\"\\n{'=' * 60}\")\n    print(\"GPU Configuration Detected:\")\n    print(f\"{'=' * 60}\")\n    print(f\"  GPU Memory: {gpu_memory_gb:.2f} GB\")\n    print(f\"  Configuration Tier: {gpu_config.tier}\")\n    print(\n        f\"  Max Duration (with LM): {gpu_config.max_duration_with_lm}s ({gpu_config.max_duration_with_lm // 60} min)\"\n    )\n    print(\n        f\"  Max Duration (without LM): {gpu_config.max_duration_without_lm}s ({gpu_config.max_duration_without_lm // 60} min)\"\n    )\n    print(f\"  Max Batch Size (with LM): {gpu_config.max_batch_size_with_lm}\")\n    print(f\"  Max Batch Size (without LM): {gpu_config.max_batch_size_without_lm}\")\n    print(f\"  Default LM Init: {gpu_config.init_lm_default}\")\n    print(f\"  Available LM Models: {gpu_config.available_lm_models or 'None'}\")\n    print(f\"{'=' * 60}\\n\")\n\n    if _is_mac:\n        print(\n            f\"Apple Silicon (MPS) detected â€” unified memory {gpu_memory_gb:.1f}GB, no CPU offload needed, backend={_default_backend}\"\n        )\n    elif auto_offload:\n        print(\n            f\"Auto-enabling CPU offload (GPU {gpu_memory_gb:.1f}GB < {VRAM_AUTO_OFFLOAD_THRESHOLD_GB}GB threshold)\"\n        )\n    elif gpu_memory_gb > 0:\n        print(\n            f\"CPU offload disabled by default (GPU {gpu_memory_gb:.1f}GB >= {VRAM_AUTO_OFFLOAD_THRESHOLD_GB}GB threshold)\"\n        )\n    else:\n        print(\"No GPU detected, running on CPU\")\n\n    # Define local outputs directory\n    project_root = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))\n    output_dir = os.path.join(project_root, \"gradio_outputs\")\n    # Normalize path to use forward slashes for Gradio 6 compatibility on Windows\n    output_dir = output_dir.replace(\"\\\\\", \"/\")\n    os.makedirs(output_dir, exist_ok=True)\n    print(f\"Output directory: {output_dir}\")\n\n    # Initialize i18n with default language (en)\n    get_i18n()\n\n    parser = argparse.ArgumentParser(\n        description=\"Gradio Demo for ACE-Step V1.5\",\n        formatter_class=argparse.RawTextHelpFormatter,\n    )\n    parser.add_argument(\n        \"--port\", type=int, default=7860, help=\"Port to run the gradio server on\"\n    )\n    parser.add_argument(\"--share\", action=\"store_true\", help=\"Create a public link\")\n    parser.add_argument(\"--debug\", action=\"store_true\", help=\"Enable debug mode\")\n    parser.add_argument(\n        \"--server-name\",\n        type=str,\n        default=\"127.0.0.1\",\n        help=\"Server name (default: 127.0.0.1, use 0.0.0.0 for all interfaces)\",\n    )\n\n    # language argument\n    available_languages = available_languages_info()\n    parser.add_argument(\n        \"--language\",\n        type=str,\n        default=\"en\",\n        choices=[language[0] for language in available_languages],\n        help=\"UI language:\\n  \"\n        + \"\\n  \".join(\n            (\n                code\n                + f\" ({native_name}\"\n                + (f\"/{name})\" if name != native_name else \")\")\n                for code, name, native_name in available_languages\n            )\n        ),\n    )\n    del available_languages\n\n    parser.add_argument(\n        \"--allowed-path\",\n        action=\"append\",\n        default=[],\n        help=\"Additional allowed file paths for Gradio (repeatable).\",\n    )\n\n    # Service mode argument\n    parser.add_argument(\n        \"--service_mode\",\n        type=lambda x: x.lower() in [\"true\", \"1\", \"yes\"],\n        default=False,\n        help=\"Enable service mode (default: False). When enabled, uses preset models and restricts UI options.\",\n    )\n\n    # Service initialization arguments\n    parser.add_argument(\n        \"--init_service\",\n        type=lambda x: x.lower() in [\"true\", \"1\", \"yes\"],\n        default=False,\n        help=\"Initialize service on startup (default: False)\",\n    )\n    parser.add_argument(\n        \"--checkpoint\",\n        type=str,\n        default=None,\n        help=\"Checkpoint file path (optional, for display purposes)\",\n    )\n    parser.add_argument(\n        \"--config_path\",\n        type=str,\n        default=None,\n        help=\"Main model path (e.g., 'acestep-v15-turbo')\",\n    )\n    parser.add_argument(\n        \"--device\",\n        type=str,\n        default=\"auto\",\n        choices=[\"auto\", \"cuda\", \"mps\", \"xpu\", \"cpu\"],\n        help=\"Processing device (default: auto)\",\n    )\n    parser.add_argument(\n        \"--init_llm\",\n        type=lambda x: x.lower() in [\"true\", \"1\", \"yes\"],\n        default=None,\n        help=\"Initialize 5Hz LM (default: auto based on GPU memory)\",\n    )\n    parser.add_argument(\n        \"--lm_model_path\",\n        type=str,\n        default=None,\n        help=\"5Hz LM model path (e.g., 'acestep-5Hz-lm-0.6B')\",\n    )\n    parser.add_argument(\n        \"--backend\",\n        type=str,\n        default=_default_backend,\n        choices=[\"vllm\", \"pt\", \"mlx\"],\n        help=f\"5Hz LM backend (default: {_default_backend}, use 'mlx' for native Apple Silicon acceleration)\",\n    )\n    parser.add_argument(\n        \"--use_flash_attention\",\n        type=lambda x: x.lower() in [\"true\", \"1\", \"yes\"],\n        default=None,\n        help=\"Use flash attention (default: auto-detect)\",\n    )\n    parser.add_argument(\n        \"--offload_to_cpu\",\n        type=lambda x: x.lower() in [\"true\", \"1\", \"yes\"],\n        default=auto_offload,\n        help=f\"Offload models to CPU (default: {'True' if auto_offload else 'False'}, auto-detected based on GPU VRAM)\",\n    )\n    _default_offload_dit = (\n        gpu_config.offload_dit_to_cpu_default if not _is_mac else False\n    )\n    parser.add_argument(\n        \"--offload_dit_to_cpu\",\n        type=lambda x: x.lower() in [\"true\", \"1\", \"yes\"],\n        default=_default_offload_dit,\n        help=f\"Offload DiT to CPU after diffusion (default: {_default_offload_dit}, auto-detected based on GPU tier)\",\n    )\n    _default_quantization = None\n    if gpu_config.quantization_default and not _is_mac:\n        _default_quantization = \"int8_weight_only\"\n        try:\n            import torch\n            if torch.cuda.is_available():\n                major, _ = torch.cuda.get_device_capability(0)\n                if major < 7:\n                    _default_quantization = \"w8a8_dynamic\"\n        except Exception as exc:\n            logger.warning(\n                \"[parse_args] CUDA capability probe failed while resolving quantization default: {}\",\n                exc,\n            )\n    parser.add_argument(\n        \"--quantization\",\n        type=parse_quantization_arg,\n        default=_default_quantization,\n        help=(\n            \"DiT quantization method: int8_weight_only, fp8_weight_only, \"\n            \"w8a8_dynamic, or none \"\n            f\"(default: {_default_quantization}, auto-detected based on GPU tier)\"\n        ),\n    )\n    parser.add_argument(\n        \"--download-source\",\n        type=str,\n        default=None,\n        choices=[\"huggingface\", \"modelscope\", \"auto\"],\n        help=\"Preferred model download source (default: auto-detect based on network)\",\n    )\n    parser.add_argument(\n        \"--batch_size\",\n        type=int,\n        default=None,\n        help=\"Default batch size for generation (1-8). Defaults to min(2, GPU_max) if not specified\",\n    )\n\n    # API mode argument\n    parser.add_argument(\n        \"--enable-api\",\n        action=\"store_true\",\n        help=\"Enable API endpoints (default: False)\",\n    )\n\n    # Authentication arguments\n    parser.add_argument(\n        \"--auth-username\",\n        type=str,\n        default=None,\n        help=\"Username for Gradio authentication\",\n    )\n    parser.add_argument(\n        \"--auth-password\",\n        type=str,\n        default=None,\n        help=\"Password for Gradio authentication\",\n    )\n    parser.add_argument(\n        \"--api-key\",\n        type=str,\n        default=None,\n        help=\"API key for API endpoints authentication\",\n    )\n\n    args = parser.parse_args()\n\n    # Enable API requires init_service\n    if args.enable_api:\n        args.init_service = True\n        # Load config from .env if not specified\n        if args.config_path is None:\n            args.config_path = os.environ.get(\"ACESTEP_CONFIG_PATH\")\n        if args.lm_model_path is None:\n            args.lm_model_path = os.environ.get(\"ACESTEP_LM_MODEL_PATH\")\n        if os.environ.get(\"ACESTEP_LM_BACKEND\"):\n            args.backend = os.environ.get(\"ACESTEP_LM_BACKEND\")\n\n    # Service mode defaults (can be configured via .env file)\n    if args.service_mode:\n        print(\"Service mode enabled - applying preset configurations...\")\n        # Force init_service in service mode\n        args.init_service = True\n        # Default DiT model for service mode (from env or fallback)\n        if args.config_path is None:\n            args.config_path = os.environ.get(\n                \"SERVICE_MODE_DIT_MODEL\", \"acestep-v15-turbo-fix-inst-shift-dynamic\"\n            )\n        # Default LM model for service mode (from env or fallback)\n        if args.lm_model_path is None:\n            args.lm_model_path = os.environ.get(\n                \"SERVICE_MODE_LM_MODEL\", \"acestep-5Hz-lm-1.7B-v4-fix\"\n            )\n        # Backend for service mode (from env or fallback to vllm)\n        args.backend = os.environ.get(\"SERVICE_MODE_BACKEND\", \"vllm\")\n        print(f\"  DiT model: {args.config_path}\")\n        print(f\"  LM model: {args.lm_model_path}\")\n        print(f\"  Backend: {args.backend}\")\n\n    # Auto-enable CPU offload for tier6 GPUs (16-24GB) when using the 4B LM model\n    # The 4B LM (~8GB) + DiT (~4.7GB) + VAE + text encoder exceeds 16-20GB with activations\n    if not args.offload_to_cpu and args.lm_model_path and \"4B\" in args.lm_model_path:\n        if 0 < gpu_memory_gb <= 24:\n            args.offload_to_cpu = True\n            print(\n                f\"Auto-enabling CPU offload (4B LM model requires offloading on {gpu_memory_gb:.0f}GB GPU)\"\n            )\n\n    # Safety: on 16GB GPUs, prevent selecting LM models that are too large.\n    # Even with offloading, a 4B LM (8 GB weights + KV cache) leaves almost no\n    # headroom for DiT activations on a 16 GB card.\n    if args.lm_model_path and 0 < gpu_memory_gb < VRAM_AUTO_OFFLOAD_THRESHOLD_GB:\n        if \"4B\" in args.lm_model_path:\n            # Downgrade to 1.7B if available\n            fallback = args.lm_model_path.replace(\"4B\", \"1.7B\")\n            print(\n                f\"WARNING: 4B LM model is too large for {gpu_memory_gb:.0f}GB GPU. \"\n                f\"Downgrading to 1.7B variant: {fallback}\"\n            )\n            args.lm_model_path = fallback\n\n    try:\n        init_params = None\n        dit_handler = None\n        llm_handler = None\n\n        # If init_service is True, perform initialization before creating UI\n        if args.init_service:\n            print(\"Initializing service from command line...\")\n\n            # Create handler instances for initialization\n            dit_handler = AceStepHandler()\n            llm_handler = LLMHandler()\n\n            # Auto-select config_path if not provided\n            if args.config_path is None:\n                available_models = dit_handler.get_available_acestep_v15_models()\n                if available_models:\n                    args.config_path = (\n                        \"acestep-v15-turbo\"\n                        if \"acestep-v15-turbo\" in available_models\n                        else available_models[0]\n                    )\n                    print(f\"Auto-selected config_path: {args.config_path}\")\n                else:\n                    print(\n                        \"Error: No available models found. Please specify --config_path\",\n                        file=sys.stderr,\n                    )\n                    sys.exit(1)\n\n            # Get project root (same logic as in handler)\n            current_file = os.path.abspath(__file__)\n            project_root = os.path.dirname(os.path.dirname(current_file))\n\n            # Determine flash attention setting\n            use_flash_attention = args.use_flash_attention\n            if use_flash_attention is None:\n                use_flash_attention = dit_handler.is_flash_attention_available(\n                    args.device\n                )\n\n            # Determine download source preference\n            prefer_source = None\n            if args.download_source and args.download_source != \"auto\":\n                prefer_source = args.download_source\n                print(f\"Using preferred download source: {prefer_source}\")\n\n            # Initialize DiT handler\n            print(f\"Initializing DiT model: {args.config_path} on {args.device}...\")\n            compile_model = os.environ.get(\n                \"ACESTEP_COMPILE_MODEL\", \"\"\n            ).strip().lower() in {\"1\", \"true\", \"yes\", \"y\", \"on\"}\n\n            init_status, enable_generate = dit_handler.initialize_service(\n                project_root=project_root,\n                config_path=args.config_path,\n                device=args.device,\n                use_flash_attention=use_flash_attention,\n                compile_model=compile_model,\n                offload_to_cpu=args.offload_to_cpu,\n                offload_dit_to_cpu=args.offload_dit_to_cpu,\n                quantization=args.quantization,\n                prefer_source=prefer_source,\n            )\n\n            if not enable_generate:\n                print(f\"Error initializing DiT model: {init_status}\", file=sys.stderr)\n                sys.exit(1)\n\n            print(f\"DiT model initialized successfully\")\n\n            # Initialize LM handler if requested\n            # Auto-determine init_llm based on GPU config if not explicitly set\n            if args.init_llm is None:\n                args.init_llm = gpu_config.init_lm_default\n                print(\n                    f\"Auto-setting init_llm to {args.init_llm} based on GPU configuration\"\n                )\n\n            lm_status = \"\"\n            if args.init_llm:\n                if args.lm_model_path is None:\n                    # Try to get default LM model\n                    available_lm_models = llm_handler.get_available_5hz_lm_models()\n                    if available_lm_models:\n                        args.lm_model_path = available_lm_models[0]\n                        print(f\"Using default LM model: {args.lm_model_path}\")\n                    else:\n                        print(\n                            \"Warning: No LM models available, skipping LM initialization\",\n                            file=sys.stderr,\n                        )\n                        args.init_llm = False\n\n                if args.init_llm and args.lm_model_path:\n                    checkpoint_dir = os.path.join(project_root, \"checkpoints\")\n\n                    # Ensure LM model is downloaded before initialization\n                    prefer_source = None\n                    if args.download_source and args.download_source != \"auto\":\n                        prefer_source = args.download_source\n                    try:\n                        dl_ok, dl_msg = ensure_lm_model(\n                            model_name=args.lm_model_path,\n                            checkpoints_dir=checkpoint_dir,\n                            prefer_source=prefer_source,\n                        )\n                        if not dl_ok:\n                            print(\n                                f\"Warning: LM model download failed: {dl_msg}\",\n                                file=sys.stderr,\n                            )\n                    except Exception as e:\n                        print(\n                            f\"Warning: Failed to download LM model: {e}\",\n                            file=sys.stderr,\n                        )\n\n                    print(\n                        f\"Initializing 5Hz LM: {args.lm_model_path} on {args.device}...\"\n                    )\n                    lm_status, lm_success = llm_handler.initialize(\n                        checkpoint_dir=checkpoint_dir,\n                        lm_model_path=args.lm_model_path,\n                        backend=args.backend,\n                        device=args.device,\n                        offload_to_cpu=args.offload_to_cpu,\n                        dtype=None,\n                    )\n\n                    if lm_success:\n                        print(f\"5Hz LM initialized successfully\")\n                        init_status += f\"\\n{lm_status}\"\n                    else:\n                        print(\n                            f\"Warning: 5Hz LM initialization failed: {lm_status}\",\n                            file=sys.stderr,\n                        )\n                        init_status += f\"\\n{lm_status}\"\n\n            # Prepare initialization parameters for UI\n            init_params = {\n                \"pre_initialized\": True,\n                \"service_mode\": args.service_mode,\n                \"checkpoint\": args.checkpoint,\n                \"config_path\": args.config_path,\n                \"device\": args.device,\n                \"init_llm\": args.init_llm,\n                \"lm_model_path\": args.lm_model_path,\n                \"backend\": args.backend,\n                \"use_flash_attention\": use_flash_attention,\n                \"offload_to_cpu\": args.offload_to_cpu,\n                \"offload_dit_to_cpu\": args.offload_dit_to_cpu,\n                \"quantization\": args.quantization,\n                \"init_status\": init_status,\n                \"enable_generate\": enable_generate,\n                \"dit_handler\": dit_handler,\n                \"llm_handler\": llm_handler,\n                \"language\": args.language,\n                \"gpu_config\": gpu_config,  # Pass GPU config to UI\n                \"output_dir\": output_dir,  # Pass output dir to UI\n                \"default_batch_size\": args.batch_size,  # Pass user-specified default batch size\n            }\n\n            print(\"Service initialization completed successfully!\")\n\n        # Create and launch demo\n        print(f\"Creating Gradio interface with language: {args.language}...\")\n\n        # If not using init_service, still pass gpu_config to init_params\n        if init_params is None:\n            init_params = {\n                \"gpu_config\": gpu_config,\n                \"language\": args.language,\n                \"output_dir\": output_dir,  # Pass output dir to UI\n                \"default_batch_size\": args.batch_size,  # Pass user-specified default batch size\n            }\n\n        demo = create_demo(init_params=init_params, language=args.language)\n\n        # Enable queue for multi-user support\n        # This ensures proper request queuing and prevents concurrent generation conflicts\n        print(\"Enabling queue for multi-user support...\")\n        demo.queue(\n            max_size=20,  # Maximum queue size (adjust based on your needs)\n            status_update_rate=\"auto\",  # Update rate for queue status\n            default_concurrency_limit=1,  # Prevents VRAM saturation\n        )\n\n        print(f\"Launching server on {args.server_name}:{args.port}...\")\n\n        # Setup authentication if provided\n        auth = None\n        if args.auth_username and args.auth_password:\n            auth = (args.auth_username, args.auth_password)\n            print(\"Authentication enabled\")\n\n        allowed_paths = [output_dir]\n        for p in args.allowed_path:\n            if p and p not in allowed_paths:\n                allowed_paths.append(p)\n\n        # Enable API endpoints if requested\n        if args.enable_api:\n            print(\"Enabling API endpoints...\")\n            from acestep.ui.gradio.api.api_routes import setup_api_routes\n\n            # Launch Gradio first with prevent_thread_lock=True\n            demo.launch(\n                server_name=args.server_name,\n                server_port=args.port,\n                share=args.share,\n                debug=args.debug,\n                show_error=True,\n                prevent_thread_lock=True,  # Don't block, so we can add routes\n                inbrowser=False,\n                auth=auth,\n                allowed_paths=allowed_paths,  # include output_dir + user-provided\n            )\n\n            # Now add API routes to Gradio's FastAPI app (app is available after launch)\n            setup_api_routes(demo, dit_handler, llm_handler, api_key=args.api_key)\n\n            if args.api_key:\n                print(\"API authentication enabled\")\n            print(\n                \"API endpoints enabled: /health, /v1/models, /release_task, /query_result, /create_random_sample, /format_lyrics\"\n            )\n\n            # Keep the main thread alive\n            try:\n                while True:\n                    import time\n\n                    time.sleep(1)\n            except KeyboardInterrupt:\n                print(\"\\nShutting down...\")\n        else:\n            demo.launch(\n                server_name=args.server_name,\n                server_port=args.port,\n                share=args.share,\n                debug=args.debug,\n                show_error=True,\n                prevent_thread_lock=False,\n                inbrowser=False,\n                auth=auth,\n                allowed_paths=allowed_paths,  # include output_dir + user-provided\n            )\n    except Exception as e:\n        print(f\"Error launching Gradio: {e}\", file=sys.stderr)\n        import traceback\n\n        traceback.print_exc()\n        sys.exit(1)\n\n\nif __name__ == \"__main__\":\n    main()\n"
  },
  {
    "path": "acestep/api/__init__.py",
    "content": "\"\"\"API package intent: external service boundary (transport, auth, request lifecycle).\"\"\"\n"
  },
  {
    "path": "acestep/api/http/__init__.py",
    "content": "\"\"\"HTTP package intent: web app assembly, routes, schemas, and middleware.\"\"\"\n"
  },
  {
    "path": "acestep/api/http/audio_route.py",
    "content": "\"\"\"HTTP route for serving generated audio files by path.\"\"\"\n\nfrom __future__ import annotations\n\nfrom pathlib import Path\nfrom typing import Any, Callable\n\nfrom fastapi import Depends, FastAPI, HTTPException, Request\n\n\ndef register_audio_route(\n    app: FastAPI,\n    verify_api_key: Callable[..., Any],\n) -> None:\n    \"\"\"Register the ``GET /v1/audio`` route.\"\"\"\n\n    @app.get(\"/v1/audio\")\n    async def get_audio(path: str, request: Request, _: None = Depends(verify_api_key)):\n        \"\"\"Serve a generated audio file when path is within the allowed directory.\"\"\"\n\n        from fastapi.responses import FileResponse\n\n        resolved_path = Path(path).resolve(strict=False)\n        allowed_dir = Path(request.app.state.temp_audio_dir).resolve(strict=False)\n        try:\n            resolved_path.relative_to(allowed_dir)\n        except ValueError:\n            raise HTTPException(status_code=403, detail=\"Access denied: path outside allowed directory\")\n        if not resolved_path.is_file():\n            raise HTTPException(status_code=404, detail=\"Audio file not found\")\n\n        ext = resolved_path.suffix.lower()\n        media_types = {\n            \".mp3\": \"audio/mpeg\",\n            \".wav\": \"audio/wav\",\n            \".flac\": \"audio/flac\",\n            \".ogg\": \"audio/ogg\",\n        }\n        return FileResponse(str(resolved_path), media_type=media_types.get(ext, \"audio/mpeg\"))\n"
  },
  {
    "path": "acestep/api/http/audio_route_http_test.py",
    "content": "\"\"\"HTTP integration tests for the audio file route.\"\"\"\n\nimport unittest\nfrom pathlib import Path\nfrom unittest import mock\n\nfrom fastapi import FastAPI, Header, HTTPException\nfrom fastapi.testclient import TestClient\nfrom starlette.responses import Response\n\nfrom acestep.api.http.audio_route import register_audio_route\n\n\nasync def _verify_api_key(authorization: str | None = Header(None)) -> None:\n    \"\"\"Validate fixed bearer token for audio route integration tests.\"\"\"\n\n    if authorization != \"Bearer test-token\":\n        raise HTTPException(status_code=401, detail=\"Unauthorized\")\n\n\nclass AudioRouteHttpTests(unittest.TestCase):\n    \"\"\"Integration tests covering real HTTP requests for ``GET /v1/audio``.\"\"\"\n\n    def test_requires_authentication(self):\n        \"\"\"GET /v1/audio should return 401 without Authorization header.\"\"\"\n\n        app = FastAPI()\n        app.state.temp_audio_dir = str(Path.cwd())\n        register_audio_route(app=app, verify_api_key=_verify_api_key)\n        client = TestClient(app)\n        response = client.get(\"/v1/audio\", params={\"path\": str(Path.cwd() / \"x.mp3\")})\n        self.assertEqual(401, response.status_code)\n\n    def test_serves_audio_file_with_authorization(self):\n        \"\"\"GET /v1/audio should return file bytes for authorized requests.\"\"\"\n\n        app = FastAPI()\n        file_path = Path.cwd() / \"ok.mp3\"\n        app.state.temp_audio_dir = str(Path.cwd())\n        register_audio_route(app=app, verify_api_key=_verify_api_key)\n        client = TestClient(app)\n        with mock.patch(\"acestep.api.http.audio_route.Path.is_file\", return_value=True), mock.patch(\n            \"fastapi.responses.FileResponse\",\n            return_value=Response(content=b\"fake-audio\", media_type=\"audio/mpeg\"),\n        ):\n            response = client.get(\n                \"/v1/audio\",\n                params={\"path\": str(file_path)},\n                headers={\"Authorization\": \"Bearer test-token\"},\n            )\n        self.assertEqual(200, response.status_code)\n        self.assertEqual(b\"fake-audio\", response.content)\n\n\nif __name__ == \"__main__\":\n    unittest.main()\n"
  },
  {
    "path": "acestep/api/http/audio_route_test.py",
    "content": "\"\"\"Unit tests for audio route registration.\"\"\"\n\nimport asyncio\nimport unittest\nfrom pathlib import Path\n\nfrom fastapi import FastAPI, HTTPException\nfrom fastapi.routing import APIRoute\n\nfrom acestep.api.http.audio_route import register_audio_route\n\n\nasync def _verify_api_key(_authorization: str | None = None) -> None:\n    \"\"\"No-op auth dependency for unit-level route execution.\"\"\"\n\n    return None\n\n\ndef _get_endpoint(app: FastAPI, path: str, method: str):\n    \"\"\"Return endpoint callable matching route path and method.\"\"\"\n\n    for route in app.routes:\n        if isinstance(route, APIRoute) and route.path == path and method.upper() in route.methods:\n            return route.endpoint\n    raise AssertionError(f\"Missing route: {method} {path}\")\n\n\nclass AudioRouteTests(unittest.TestCase):\n    \"\"\"Behavior tests for ``GET /v1/audio`` security and file checks.\"\"\"\n\n    def test_rejects_path_outside_allowed_dir(self):\n        \"\"\"Audio route should return HTTP 403 for paths outside allowed directory.\"\"\"\n\n        app = FastAPI()\n        allowed_dir = Path.cwd() / \"__allowed_audio_dir__\"\n        app.state.temp_audio_dir = str(allowed_dir)\n        register_audio_route(app=app, verify_api_key=_verify_api_key)\n        endpoint = _get_endpoint(app, \"/v1/audio\", \"GET\")\n        request = type(\"Req\", (), {\"app\": app})()\n        outside_path = Path.cwd() / \"__outside_audio__.mp3\"\n\n        with self.assertRaises(HTTPException) as ctx:\n            asyncio.run(endpoint(path=str(outside_path), request=request, _=None))\n        self.assertEqual(403, ctx.exception.status_code)\n\n    def test_returns_404_when_file_missing(self):\n        \"\"\"Audio route should return HTTP 404 for missing files inside allowed dir.\"\"\"\n\n        app = FastAPI()\n        allowed_dir = Path.cwd() / \"__allowed_audio_dir__\"\n        app.state.temp_audio_dir = str(allowed_dir)\n        register_audio_route(app=app, verify_api_key=_verify_api_key)\n        endpoint = _get_endpoint(app, \"/v1/audio\", \"GET\")\n        request = type(\"Req\", (), {\"app\": app})()\n\n        with self.assertRaises(HTTPException) as ctx:\n            asyncio.run(endpoint(path=str(allowed_dir / \"missing.mp3\"), request=request, _=None))\n        self.assertEqual(404, ctx.exception.status_code)\n\n    def test_returns_404_for_directory_target(self):\n        \"\"\"Audio route should return HTTP 404 when target path is a directory.\"\"\"\n\n        app = FastAPI()\n        app.state.temp_audio_dir = str(Path.cwd())\n        register_audio_route(app=app, verify_api_key=_verify_api_key)\n        endpoint = _get_endpoint(app, \"/v1/audio\", \"GET\")\n        request = type(\"Req\", (), {\"app\": app})()\n\n        with self.assertRaises(HTTPException) as ctx:\n            asyncio.run(endpoint(path=str(Path.cwd()), request=request, _=None))\n        self.assertEqual(404, ctx.exception.status_code)\n\n\nif __name__ == \"__main__\":\n    unittest.main()\n"
  },
  {
    "path": "acestep/api/http/auth.py",
    "content": "\"\"\"API-key authentication helpers shared across HTTP route registration.\"\"\"\n\nfrom __future__ import annotations\n\nfrom typing import Any, Optional\n\nfrom fastapi import Header, HTTPException\n\n_api_key: Optional[str] = None\n\n\ndef set_api_key(key: Optional[str]) -> None:\n    \"\"\"Set the process-level API key used by auth verification helpers.\n\n    Args:\n        key: API key string, or ``None`` to disable auth enforcement.\n    \"\"\"\n\n    global _api_key\n    _api_key = key\n\n\ndef verify_token_from_request(\n    body: dict[str, Any], authorization: Optional[str] = None\n) -> Optional[str]:\n    \"\"\"Validate request auth from body ``ai_token`` or Authorization header.\n\n    Args:\n        body: Parsed request payload dictionary.\n        authorization: Optional ``Authorization`` header value.\n\n    Returns:\n        Validated token value, or ``None`` when auth is disabled.\n\n    Raises:\n        HTTPException: If auth is required and token is missing/invalid.\n    \"\"\"\n\n    if _api_key is None:\n        return None\n\n    ai_token = body.get(\"ai_token\") if body else None\n    if ai_token:\n        if ai_token == _api_key:\n            return ai_token\n        raise HTTPException(status_code=401, detail=\"Invalid ai_token\")\n\n    if authorization:\n        token = authorization[7:] if authorization.startswith(\"Bearer \") else authorization\n        if token == _api_key:\n            return token\n        raise HTTPException(status_code=401, detail=\"Invalid API key\")\n\n    raise HTTPException(status_code=401, detail=\"Missing ai_token or Authorization header\")\n\n\nasync def verify_api_key(authorization: Optional[str] = Header(None)) -> None:\n    \"\"\"Validate Authorization header for endpoints that do not parse request body.\n\n    Args:\n        authorization: Optional ``Authorization`` header value.\n\n    Raises:\n        HTTPException: If auth is required and header token is missing/invalid.\n    \"\"\"\n\n    if _api_key is None:\n        return\n\n    if not authorization:\n        raise HTTPException(status_code=401, detail=\"Missing Authorization header\")\n\n    token = authorization[7:] if authorization.startswith(\"Bearer \") else authorization\n    if token != _api_key:\n        raise HTTPException(status_code=401, detail=\"Invalid API key\")\n"
  },
  {
    "path": "acestep/api/http/auth_test.py",
    "content": "\"\"\"Unit tests for API-key authentication helpers.\"\"\"\n\nfrom __future__ import annotations\n\nimport asyncio\nimport unittest\n\nfrom fastapi import HTTPException\n\nfrom acestep.api.http.auth import set_api_key, verify_api_key, verify_token_from_request\n\n\nclass AuthHelpersTests(unittest.TestCase):\n    \"\"\"Behavior tests for API-key state and token/header validation helpers.\"\"\"\n\n    def setUp(self) -> None:\n        \"\"\"Reset auth state before each test.\"\"\"\n\n        set_api_key(None)\n\n    def tearDown(self) -> None:\n        \"\"\"Reset auth state after each test.\"\"\"\n\n        set_api_key(None)\n\n    def test_verify_token_returns_none_when_auth_is_disabled(self) -> None:\n        \"\"\"Token verification should allow requests when no API key is configured.\"\"\"\n\n        token = verify_token_from_request(body={}, authorization=None)\n        self.assertIsNone(token)\n        asyncio.run(verify_api_key(authorization=None))\n\n    def test_verify_token_accepts_ai_token_in_body(self) -> None:\n        \"\"\"Body ai_token should be accepted when it matches configured API key.\"\"\"\n\n        set_api_key(\"secret\")\n        token = verify_token_from_request(body={\"ai_token\": \"secret\"}, authorization=None)\n        self.assertEqual(\"secret\", token)\n\n    def test_verify_token_rejects_invalid_ai_token(self) -> None:\n        \"\"\"Body ai_token mismatch should return the legacy 401 detail message.\"\"\"\n\n        set_api_key(\"secret\")\n        with self.assertRaises(HTTPException) as ctx:\n            verify_token_from_request(body={\"ai_token\": \"wrong\"}, authorization=None)\n        self.assertEqual(401, ctx.exception.status_code)\n        self.assertEqual(\"Invalid ai_token\", ctx.exception.detail)\n\n    def test_verify_token_accepts_bearer_header(self) -> None:\n        \"\"\"Authorization header should support Bearer-prefix token values.\"\"\"\n\n        set_api_key(\"secret\")\n        token = verify_token_from_request(body={}, authorization=\"Bearer secret\")\n        self.assertEqual(\"secret\", token)\n\n    def test_verify_token_requires_token_when_auth_enabled(self) -> None:\n        \"\"\"Missing body token and header should preserve existing 401 error message.\"\"\"\n\n        set_api_key(\"secret\")\n        with self.assertRaises(HTTPException) as ctx:\n            verify_token_from_request(body={}, authorization=None)\n        self.assertEqual(401, ctx.exception.status_code)\n        self.assertEqual(\"Missing ai_token or Authorization header\", ctx.exception.detail)\n\n    def test_verify_api_key_rejects_invalid_or_missing_header(self) -> None:\n        \"\"\"Header-only verifier should preserve missing/invalid API key errors.\"\"\"\n\n        set_api_key(\"secret\")\n\n        with self.assertRaises(HTTPException) as missing_ctx:\n            asyncio.run(verify_api_key(authorization=None))\n        self.assertEqual(401, missing_ctx.exception.status_code)\n        self.assertEqual(\"Missing Authorization header\", missing_ctx.exception.detail)\n\n        with self.assertRaises(HTTPException) as invalid_ctx:\n            asyncio.run(verify_api_key(authorization=\"Bearer wrong\"))\n        self.assertEqual(401, invalid_ctx.exception.status_code)\n        self.assertEqual(\"Invalid API key\", invalid_ctx.exception.detail)\n\n        asyncio.run(verify_api_key(authorization=\"Bearer secret\"))\n\n\nif __name__ == \"__main__\":\n    unittest.main()\n"
  },
  {
    "path": "acestep/api/http/lora_routes.py",
    "content": "\"\"\"LoRA HTTP routes for adapter lifecycle controls.\"\"\"\n\nfrom __future__ import annotations\n\nfrom typing import Any, Callable, Dict, Optional\n\nfrom fastapi import Depends, FastAPI, HTTPException\nfrom pydantic import BaseModel, Field\n\nfrom acestep.handler import AceStepHandler\n\n_SUCCESS_PREFIX = \"\\u2705\"\n_WARNING_PREFIX = \"\\u26a0\\ufe0f\"\n\n\nclass LoadLoRARequest(BaseModel):\n    \"\"\"Request payload for loading a LoRA/LoKr adapter.\"\"\"\n\n    lora_path: str = Field(..., description=\"Path to LoRA adapter directory or LoKr/LyCORIS safetensors file\")\n    adapter_name: Optional[str] = Field(default=None, description=\"Optional adapter name for multi-adapter mode\")\n\n\nclass SetLoRAScaleRequest(BaseModel):\n    \"\"\"Request payload for setting LoRA strength.\"\"\"\n\n    scale: float = Field(..., ge=0.0, le=1.0, description=\"LoRA scale strength (0.0 to 1.0)\")\n    adapter_name: Optional[str] = Field(default=None, description=\"Optional adapter name for multi-adapter mode\")\n\n\nclass ToggleLoRARequest(BaseModel):\n    \"\"\"Request payload for enabling/disabling loaded LoRA adapters.\"\"\"\n\n    use_lora: bool = Field(..., description=\"Enable or disable LoRA\")\n\n\ndef _require_initialized_handler(app: FastAPI) -> AceStepHandler:\n    \"\"\"Return initialized handler or raise HTTP 500 when unavailable.\"\"\"\n\n    handler: AceStepHandler = app.state.handler\n    if handler is None or handler.model is None:\n        raise HTTPException(status_code=500, detail=\"Model not initialized\")\n    return handler\n\n\ndef _is_success_message(result: str, allow_warning: bool = False) -> bool:\n    \"\"\"Check whether backend operation result is considered successful.\"\"\"\n\n    if result.startswith(_SUCCESS_PREFIX):\n        return True\n    return allow_warning and result.startswith(_WARNING_PREFIX)\n\n\ndef register_lora_routes(\n    app: FastAPI,\n    verify_api_key: Callable[..., Any],\n    wrap_response: Callable[..., Dict[str, Any]],\n) -> None:\n    \"\"\"Register LoRA lifecycle endpoints on the provided FastAPI app.\"\"\"\n\n    @app.post(\"/v1/lora/load\")\n    async def load_lora_endpoint(request: LoadLoRARequest, _: None = Depends(verify_api_key)):\n        \"\"\"Load LoRA adapter into the primary model.\"\"\"\n\n        handler = _require_initialized_handler(app)\n        try:\n            adapter_name = request.adapter_name.strip() if isinstance(request.adapter_name, str) else None\n            if adapter_name:\n                result = handler.add_lora(request.lora_path, adapter_name=adapter_name)\n            else:\n                result = handler.load_lora(request.lora_path)\n\n            if _is_success_message(result):\n                response_data: Dict[str, Any] = {\"message\": result, \"lora_path\": request.lora_path}\n                if adapter_name:\n                    response_data[\"adapter_name\"] = adapter_name\n                return wrap_response(response_data)\n            raise HTTPException(status_code=400, detail=result)\n        except HTTPException:\n            raise\n        except Exception as exc:\n            raise HTTPException(status_code=500, detail=f\"Failed to load LoRA: {str(exc)}\")\n\n    @app.post(\"/v1/lora/unload\")\n    async def unload_lora_endpoint(_: None = Depends(verify_api_key)):\n        \"\"\"Unload LoRA adapter and restore base model.\"\"\"\n\n        handler = _require_initialized_handler(app)\n        try:\n            result = handler.unload_lora()\n            if _is_success_message(result, allow_warning=True):\n                return wrap_response({\"message\": result})\n            raise HTTPException(status_code=400, detail=result)\n        except HTTPException:\n            raise\n        except Exception as exc:\n            raise HTTPException(status_code=500, detail=f\"Failed to unload LoRA: {str(exc)}\")\n\n    @app.post(\"/v1/lora/toggle\")\n    async def toggle_lora_endpoint(request: ToggleLoRARequest, _: None = Depends(verify_api_key)):\n        \"\"\"Enable or disable LoRA adapter for inference.\"\"\"\n\n        handler = _require_initialized_handler(app)\n        try:\n            result = handler.set_use_lora(request.use_lora)\n            if _is_success_message(result):\n                return wrap_response({\"message\": result, \"use_lora\": request.use_lora})\n            return wrap_response(None, code=400, error=result)\n        except Exception as exc:\n            return wrap_response(None, code=500, error=f\"Failed to toggle LoRA: {str(exc)}\")\n\n    @app.post(\"/v1/lora/scale\")\n    async def set_lora_scale_endpoint(request: SetLoRAScaleRequest, _: None = Depends(verify_api_key)):\n        \"\"\"Set LoRA adapter scale/strength.\"\"\"\n\n        handler = _require_initialized_handler(app)\n        try:\n            adapter_name = request.adapter_name.strip() if isinstance(request.adapter_name, str) else None\n            if adapter_name:\n                result = handler.set_lora_scale(adapter_name, request.scale)\n            else:\n                result = handler.set_lora_scale(request.scale)\n\n            if _is_success_message(result, allow_warning=True):\n                response_data: Dict[str, Any] = {\"message\": result, \"scale\": request.scale}\n                if adapter_name:\n                    response_data[\"adapter_name\"] = adapter_name\n                return wrap_response(response_data)\n            return wrap_response(None, code=400, error=result)\n        except Exception as exc:\n            return wrap_response(None, code=500, error=f\"Failed to set LoRA scale: {str(exc)}\")\n\n    @app.get(\"/v1/lora/status\")\n    async def get_lora_status_endpoint(_: None = Depends(verify_api_key)):\n        \"\"\"Get current LoRA/LoKr adapter state for the primary handler.\"\"\"\n\n        handler = _require_initialized_handler(app)\n        status = handler.get_lora_status()\n        return wrap_response(\n            {\n                \"lora_loaded\": bool(status.get(\"loaded\", getattr(handler, \"lora_loaded\", False))),\n                \"use_lora\": bool(status.get(\"active\", getattr(handler, \"use_lora\", False))),\n                \"lora_scale\": float(status.get(\"scale\", getattr(handler, \"lora_scale\", 1.0))),\n                \"adapter_type\": getattr(handler, \"_adapter_type\", None),\n                \"scales\": status.get(\"scales\", {}),\n                \"active_adapter\": status.get(\"active_adapter\"),\n                \"adapters\": status.get(\"adapters\", []),\n                \"synthetic_default_mode\": bool(status.get(\"synthetic_default_mode\", False)),\n            }\n        )\n"
  },
  {
    "path": "acestep/api/http/lora_routes_http_test.py",
    "content": "\"\"\"HTTP integration tests for LoRA route registration.\"\"\"\n\nimport unittest\nfrom typing import Any, Dict\n\nfrom fastapi import FastAPI, Header, HTTPException\nfrom fastapi.testclient import TestClient\n\nfrom acestep.api.http.lora_routes import register_lora_routes\n\n\ndef _wrap_response(data: Any, code: int = 200, error: str | None = None) -> Dict[str, Any]:\n    \"\"\"Return response envelope matching API server contract.\"\"\"\n\n    return {\"data\": data, \"code\": code, \"error\": error}\n\n\nasync def _verify_api_key(authorization: str | None = Header(None)) -> None:\n    \"\"\"Require a fixed bearer token for integration tests.\"\"\"\n\n    if authorization != \"Bearer test-token\":\n        raise HTTPException(status_code=401, detail=\"Unauthorized\")\n\n\nclass _FakeHandler:\n    \"\"\"Minimal route handler stub used for HTTP integration tests.\"\"\"\n\n    def __init__(self, model: object | None = None) -> None:\n        self.model = model\n        self.calls: list[tuple] = []\n        self.toggle_result = \"\\u2705 toggled\"\n\n    def add_lora(self, lora_path: str, adapter_name: str | None = None) -> str:\n        \"\"\"Record add_lora calls and return success marker.\"\"\"\n\n        self.calls.append((\"add_lora\", lora_path, adapter_name))\n        return \"\\u2705 loaded adapter\"\n\n    def load_lora(self, lora_path: str) -> str:\n        \"\"\"Record load_lora calls and return success marker.\"\"\"\n\n        self.calls.append((\"load_lora\", lora_path))\n        return \"\\u2705 loaded\"\n\n    def unload_lora(self) -> str:\n        \"\"\"Record unload_lora calls and return success marker.\"\"\"\n\n        self.calls.append((\"unload_lora\",))\n        return \"\\u2705 unloaded\"\n\n    def set_use_lora(self, use_lora: bool) -> str:\n        \"\"\"Record set_use_lora calls and return configurable result.\"\"\"\n\n        self.calls.append((\"set_use_lora\", use_lora))\n        return self.toggle_result\n\n    def set_lora_scale(self, *args) -> str:\n        \"\"\"Record set_lora_scale calls and return success marker.\"\"\"\n\n        self.calls.append((\"set_lora_scale\",) + args)\n        return \"\\u2705 scale set\"\n\n    def get_lora_status(self) -> Dict[str, Any]:\n        \"\"\"Return canned LoRA status payload.\"\"\"\n\n        self.calls.append((\"get_lora_status\",))\n        return {\"loaded\": True, \"active\": True, \"scale\": 0.6, \"adapters\": [\"main\"], \"scales\": {\"main\": 0.6}}\n\n\nclass LoraRoutesHttpTests(unittest.TestCase):\n    \"\"\"Exercise LoRA endpoints through real TestClient HTTP requests.\"\"\"\n\n    def _build_client(self, handler: _FakeHandler) -> TestClient:\n        \"\"\"Build a FastAPI app, register routes, and return an HTTP client.\"\"\"\n\n        app = FastAPI()\n        app.state.handler = handler\n        register_lora_routes(app=app, verify_api_key=_verify_api_key, wrap_response=_wrap_response)\n        return TestClient(app)\n\n    def test_load_lora_post_returns_wrapped_success_payload(self):\n        \"\"\"POST /v1/lora/load should return wrapped response and call add_lora.\"\"\"\n\n        handler = _FakeHandler(model=object())\n        client = self._build_client(handler)\n\n        response = client.post(\n            \"/v1/lora/load\",\n            headers={\"Authorization\": \"Bearer test-token\"},\n            json={\"lora_path\": \"adapter.safetensors\", \"adapter_name\": \"main\"},\n        )\n\n        self.assertEqual(200, response.status_code)\n        payload = response.json()\n        self.assertEqual(200, payload[\"code\"])\n        self.assertEqual(\"main\", payload[\"data\"][\"adapter_name\"])\n        self.assertEqual((\"add_lora\", \"adapter.safetensors\", \"main\"), handler.calls[0])\n\n    def test_toggle_lora_post_preserves_wrapper_400_semantics(self):\n        \"\"\"POST /v1/lora/toggle should keep HTTP 200 with wrapped code=400 on failure.\"\"\"\n\n        handler = _FakeHandler(model=object())\n        handler.toggle_result = \"failed to toggle\"\n        client = self._build_client(handler)\n\n        response = client.post(\n            \"/v1/lora/toggle\",\n            headers={\"Authorization\": \"Bearer test-token\"},\n            json={\"use_lora\": True},\n        )\n\n        self.assertEqual(200, response.status_code)\n        payload = response.json()\n        self.assertEqual(400, payload[\"code\"])\n        self.assertEqual(\"failed to toggle\", payload[\"error\"])\n\n    def test_status_get_returns_http_500_when_model_not_initialized(self):\n        \"\"\"GET /v1/lora/status should return HTTP 500 when handler model is missing.\"\"\"\n\n        handler = _FakeHandler(model=None)\n        client = self._build_client(handler)\n\n        response = client.get(\"/v1/lora/status\", headers={\"Authorization\": \"Bearer test-token\"})\n\n        self.assertEqual(500, response.status_code)\n        self.assertEqual(\"Model not initialized\", response.json()[\"detail\"])\n\n    def test_requests_require_authorization_header(self):\n        \"\"\"GET /v1/lora/status without token should return HTTP 401 from dependency.\"\"\"\n\n        handler = _FakeHandler(model=object())\n        client = self._build_client(handler)\n\n        response = client.get(\"/v1/lora/status\")\n\n        self.assertEqual(401, response.status_code)\n        self.assertEqual(\"Unauthorized\", response.json()[\"detail\"])\n\n\nif __name__ == \"__main__\":\n    unittest.main()\n"
  },
  {
    "path": "acestep/api/http/lora_routes_test.py",
    "content": "\"\"\"Unit tests for LoRA route registration and endpoint behavior.\"\"\"\n\nimport asyncio\nimport unittest\nfrom typing import Any, Dict\n\nfrom fastapi import FastAPI, HTTPException\nfrom fastapi.routing import APIRoute\n\nfrom acestep.api.http.lora_routes import (\n    LoadLoRARequest,\n    SetLoRAScaleRequest,\n    ToggleLoRARequest,\n    register_lora_routes,\n)\n\n\ndef _wrap_response(data: Any, code: int = 200, error: str | None = None) -> Dict[str, Any]:\n    \"\"\"Return response envelope matching api_server wrapper contract.\"\"\"\n\n    return {\"data\": data, \"code\": code, \"error\": error}\n\n\nasync def _verify_api_key(_: str | None = None) -> None:\n    \"\"\"Test no-op auth dependency.\"\"\"\n\n    return None\n\n\ndef _get_route_endpoint(app: FastAPI, path: str, method: str):\n    \"\"\"Resolve route endpoint callable by path and HTTP method.\"\"\"\n\n    method = method.upper()\n    for route in app.routes:\n        if isinstance(route, APIRoute) and route.path == path and method in route.methods:\n            return route.endpoint\n    raise AssertionError(f\"Route not found: {method} {path}\")\n\n\nclass _FakeHandler:\n    \"\"\"Minimal handler stub for LoRA route tests.\"\"\"\n\n    def __init__(self, model: object | None = None) -> None:\n        self.model = model\n        self.calls: list[tuple] = []\n        self.lora_loaded = False\n        self.use_lora = False\n        self.lora_scale = 1.0\n        self._adapter_type = \"lora\"\n        self.scale_result = \"\\u2705 scale set\"\n\n    def add_lora(self, lora_path: str, adapter_name: str | None = None) -> str:\n        self.calls.append((\"add_lora\", lora_path, adapter_name))\n        return \"\\u2705 loaded adapter\"\n\n    def load_lora(self, lora_path: str) -> str:\n        self.calls.append((\"load_lora\", lora_path))\n        return \"\\u2705 loaded\"\n\n    def unload_lora(self) -> str:\n        self.calls.append((\"unload_lora\",))\n        return \"\\u2705 unloaded\"\n\n    def set_use_lora(self, use_lora: bool) -> str:\n        self.calls.append((\"set_use_lora\", use_lora))\n        return \"failed to toggle\"\n\n    def set_lora_scale(self, *args) -> str:\n        self.calls.append((\"set_lora_scale\",) + args)\n        return self.scale_result\n\n    def get_lora_status(self) -> Dict[str, Any]:\n        self.calls.append((\"get_lora_status\",))\n        return {\"loaded\": True, \"active\": True, \"scale\": 0.6, \"adapters\": [\"main\"], \"scales\": {\"main\": 0.6}}\n\n\nclass LoraRoutesTests(unittest.TestCase):\n    \"\"\"Behavior tests for the extracted LoRA endpoint registration module.\"\"\"\n\n    def _build_app(self, handler: _FakeHandler) -> FastAPI:\n        \"\"\"Create test app and register LoRA routes with stubs.\"\"\"\n\n        app = FastAPI()\n        app.state.handler = handler\n        register_lora_routes(app=app, verify_api_key=_verify_api_key, wrap_response=_wrap_response)\n        return app\n\n    def test_load_route_uses_add_lora_when_adapter_name_present(self):\n        \"\"\"Load endpoint should route named adapters through add_lora().\"\"\"\n\n        handler = _FakeHandler(model=object())\n        app = self._build_app(handler)\n        endpoint = _get_route_endpoint(app, \"/v1/lora/load\", \"POST\")\n\n        payload = LoadLoRARequest(lora_path=\"adapter.safetensors\", adapter_name=\"main\")\n        result = asyncio.run(endpoint(payload, None))\n\n        self.assertEqual((\"add_lora\", \"adapter.safetensors\", \"main\"), handler.calls[0])\n        self.assertEqual(200, result[\"code\"])\n        self.assertEqual(\"main\", result[\"data\"][\"adapter_name\"])\n\n    def test_status_route_raises_when_model_not_initialized(self):\n        \"\"\"Status endpoint should reject requests when model is unavailable.\"\"\"\n\n        handler = _FakeHandler(model=None)\n        app = self._build_app(handler)\n        endpoint = _get_route_endpoint(app, \"/v1/lora/status\", \"GET\")\n\n        with self.assertRaises(HTTPException) as ctx:\n            asyncio.run(endpoint(None))\n\n        self.assertEqual(500, ctx.exception.status_code)\n        self.assertIn(\"Model not initialized\", str(ctx.exception.detail))\n\n    def test_scale_route_accepts_warning_prefix_as_success(self):\n        \"\"\"Scale endpoint should treat warning-prefixed responses as success.\"\"\"\n\n        handler = _FakeHandler(model=object())\n        handler.scale_result = \"\\u26a0\\ufe0f using fallback adapter\"\n        app = self._build_app(handler)\n        endpoint = _get_route_endpoint(app, \"/v1/lora/scale\", \"POST\")\n\n        payload = SetLoRAScaleRequest(scale=0.42)\n        result = asyncio.run(endpoint(payload, None))\n\n        self.assertEqual(200, result[\"code\"])\n        self.assertEqual(0.42, result[\"data\"][\"scale\"])\n\n    def test_toggle_route_returns_400_wrapper_for_non_success_message(self):\n        \"\"\"Toggle endpoint should map non-success handler responses to code 400.\"\"\"\n\n        handler = _FakeHandler(model=object())\n        app = self._build_app(handler)\n        endpoint = _get_route_endpoint(app, \"/v1/lora/toggle\", \"POST\")\n\n        payload = ToggleLoRARequest(use_lora=True)\n        result = asyncio.run(endpoint(payload, None))\n\n        self.assertEqual(400, result[\"code\"])\n        self.assertEqual(\"failed to toggle\", result[\"error\"])\n\n\nif __name__ == \"__main__\":\n    unittest.main()\n"
  },
  {
    "path": "acestep/api/http/model_init_service.py",
    "content": "\"\"\"Blocking model initialization helpers for API model service routes.\"\"\"\n\nfrom __future__ import annotations\n\nimport os\nfrom typing import Any, Callable, Dict, Optional\n\nfrom acestep.gpu_config import VRAM_AUTO_OFFLOAD_THRESHOLD_GB, get_gpu_config\n\n\ndef initialize_models_for_request(\n    app_state: Any,\n    model_name: Optional[str],\n    init_llm: bool,\n    requested_lm_model_path: Optional[str],\n    get_project_root: Callable[[], str],\n    get_model_name: Callable[[str], str],\n    ensure_model_downloaded: Callable[[str, str], str],\n    env_bool: Callable[[str, bool], bool],\n) -> Dict[str, Optional[str]]:\n    \"\"\"Initialize DiT and optional LM models.\n\n    Args:\n        app_state: FastAPI application state carrying handler objects and flags.\n        model_name: Requested DiT model name, or current configured model when empty.\n        init_llm: Whether to initialize the LM in the same request.\n        requested_lm_model_path: Optional LM model path/name override.\n        get_project_root: Returns the project root path.\n        get_model_name: Normalizes a model path to its model name.\n        ensure_model_downloaded: Ensures a named model exists under checkpoints.\n        env_bool: Reads boolean environment variables.\n    Returns:\n        Mapping with keys ``loaded_model`` and ``loaded_lm_model``.\n    Raises:\n        RuntimeError: When model names are invalid or DiT/LLM initialization fails.\n        AttributeError: When required app state attributes are missing (legacy behavior).\n    \"\"\"\n\n    handler = app_state.handler\n    llm = app_state.llm_handler\n    project_root = get_project_root()\n    checkpoint_dir = os.path.join(project_root, \"checkpoints\")\n    os.makedirs(checkpoint_dir, exist_ok=True)\n\n    target_model = (model_name or get_model_name(getattr(app_state, \"_config_path\", \"\"))).strip()\n    if not target_model:\n        raise RuntimeError(\"No DiT model specified\")\n\n    gpu_config = get_gpu_config()\n    auto_offload = gpu_config.gpu_memory_gb > 0 and gpu_config.gpu_memory_gb < VRAM_AUTO_OFFLOAD_THRESHOLD_GB\n    offload_to_cpu_env = os.getenv(\"ACESTEP_OFFLOAD_TO_CPU\")\n    offload_to_cpu = env_bool(\"ACESTEP_OFFLOAD_TO_CPU\", False) if offload_to_cpu_env is not None else auto_offload\n    use_flash_attention = env_bool(\"ACESTEP_USE_FLASH_ATTENTION\", True)\n    offload_dit_to_cpu = env_bool(\"ACESTEP_OFFLOAD_DIT_TO_CPU\", False)\n    compile_model = env_bool(\"ACESTEP_COMPILE_MODEL\", False)\n    device = os.getenv(\"ACESTEP_DEVICE\", \"auto\")\n\n    ensure_model_downloaded(target_model, checkpoint_dir)\n    ensure_model_downloaded(\"vae\", checkpoint_dir)\n\n    status_msg, ok = handler.initialize_service(\n        project_root=project_root,\n        config_path=target_model,\n        device=device,\n        use_flash_attention=use_flash_attention,\n        compile_model=compile_model,\n        offload_to_cpu=offload_to_cpu,\n        offload_dit_to_cpu=offload_dit_to_cpu,\n    )\n    if not ok:\n        raise RuntimeError(f\"DiT init failed: {status_msg}\")\n\n    app_state._config_path = target_model\n    app_state._initialized = True\n    app_state._init_error = None\n\n    loaded_lm_model: Optional[str] = None\n    if init_llm:\n        lm_model_path = (requested_lm_model_path or os.getenv(\"ACESTEP_LM_MODEL_PATH\", \"acestep-5Hz-lm-0.6B\")).strip()\n        if not lm_model_path:\n            lm_model_path = \"acestep-5Hz-lm-0.6B\"\n\n        os.environ[\"ACESTEP_INIT_LLM\"] = \"true\"\n        os.environ[\"ACESTEP_LM_MODEL_PATH\"] = lm_model_path\n\n        lm_backend = os.getenv(\"ACESTEP_LM_BACKEND\", \"vllm\").strip().lower()\n        if lm_backend not in {\"vllm\", \"pt\", \"mlx\"}:\n            lm_backend = \"vllm\"\n        lm_device = os.getenv(\"ACESTEP_LM_DEVICE\", device)\n        lm_offload_env = os.getenv(\"ACESTEP_LM_OFFLOAD_TO_CPU\")\n        lm_offload = env_bool(\"ACESTEP_LM_OFFLOAD_TO_CPU\", False) if lm_offload_env is not None else offload_to_cpu\n\n        lm_model_name = get_model_name(lm_model_path)\n        if lm_model_name:\n            ensure_model_downloaded(lm_model_name, checkpoint_dir)\n\n        with app_state._llm_init_lock:\n            llm_status, llm_ok = llm.initialize(\n                checkpoint_dir=checkpoint_dir,\n                lm_model_path=lm_model_path,\n                backend=lm_backend,\n                device=lm_device,\n                offload_to_cpu=lm_offload,\n                dtype=None,\n            )\n            if not llm_ok:\n                app_state._llm_initialized = False\n                app_state._llm_init_error = llm_status\n                raise RuntimeError(f\"LLM init failed: {llm_status}\")\n            app_state._llm_initialized = True\n            app_state._llm_init_error = None\n            app_state._llm_lazy_load_disabled = False\n        loaded_lm_model = lm_model_name or lm_model_path\n\n    return {\"loaded_model\": target_model, \"loaded_lm_model\": loaded_lm_model}\n"
  },
  {
    "path": "acestep/api/http/model_init_service_test.py",
    "content": "\"\"\"Unit tests for blocking model initialization service helpers.\"\"\"\n\nimport threading\nimport unittest\nfrom types import SimpleNamespace\nfrom unittest import mock\n\nfrom acestep.api.http.model_init_service import initialize_models_for_request\n\n\nclass _FakeHandler:\n    \"\"\"Fake DiT handler providing initialize_service contract.\"\"\"\n\n    def initialize_service(self, **_kwargs):\n        \"\"\"Return ``(\"ok\", True)`` to emulate successful DiT initialization.\"\"\"\n\n        return \"ok\", True\n\n\nclass _FakeLlm:\n    \"\"\"Fake LLM handler providing initialize contract.\"\"\"\n\n    def initialize(self, **_kwargs):\n        \"\"\"Return ``(\"ok\", True)`` to emulate successful LLM initialization.\"\"\"\n\n        return \"ok\", True\n\n\nclass _FailingLlm:\n    \"\"\"Fake LLM handler that fails initialize for error-path tests.\"\"\"\n\n    def initialize(self, **_kwargs):\n        \"\"\"Return ``(\"llm-failed\", False)`` for LLM failure-path assertions.\"\"\"\n\n        return \"llm-failed\", False\n\n\nclass ModelInitServiceTests(unittest.TestCase):\n    \"\"\"Behavior tests for initialize_models_for_request helper.\"\"\"\n\n    def test_raises_when_handler_missing(self):\n        \"\"\"Missing handler should preserve legacy AttributeError behavior.\"\"\"\n\n        state = SimpleNamespace(handler=None, llm_handler=_FakeLlm())\n        with mock.patch(\"acestep.api.http.model_init_service.os.makedirs\"):\n            with self.assertRaises(AttributeError) as ctx:\n                initialize_models_for_request(\n                    app_state=state,\n                    model_name=\"acestep-v15-base\",\n                    init_llm=False,\n                    requested_lm_model_path=None,\n                    get_project_root=lambda: \"/tmp/non-existent\",\n                    get_model_name=lambda p: str(p).split(\"/\")[-1].split(\"\\\\\")[-1],\n                    ensure_model_downloaded=lambda *_: \"\",\n                    env_bool=lambda *_: False,\n                )\n        self.assertIn(\"initialize_service\", str(ctx.exception))\n\n    def test_raises_when_init_llm_requested_but_llm_missing(self):\n        \"\"\"Missing llm_handler should preserve legacy AttributeError behavior.\"\"\"\n\n        state = SimpleNamespace(handler=_FakeHandler(), llm_handler=None, _llm_init_lock=threading.Lock())\n        with mock.patch(\"acestep.api.http.model_init_service.os.makedirs\"):\n            with self.assertRaises(AttributeError) as ctx:\n                initialize_models_for_request(\n                    app_state=state,\n                    model_name=\"acestep-v15-base\",\n                    init_llm=True,\n                    requested_lm_model_path=\"acestep-5Hz-lm-0.6B\",\n                    get_project_root=lambda: \"/tmp/non-existent\",\n                    get_model_name=lambda p: str(p).split(\"/\")[-1].split(\"\\\\\")[-1],\n                    ensure_model_downloaded=lambda *_: \"\",\n                    env_bool=lambda *_: False,\n                )\n        self.assertIn(\"initialize\", str(ctx.exception))\n\n    def test_returns_loaded_model_when_dit_init_succeeds(self):\n        \"\"\"Successful DiT-only init should return loaded_model and no LM value.\"\"\"\n\n        state = SimpleNamespace(\n            handler=_FakeHandler(),\n            llm_handler=_FakeLlm(),\n            _llm_init_lock=threading.Lock(),\n            _config_path=\"\",\n        )\n        with mock.patch(\"acestep.api.http.model_init_service.os.makedirs\"):\n            result = initialize_models_for_request(\n                app_state=state,\n                model_name=\"acestep-v15-base\",\n                init_llm=False,\n                requested_lm_model_path=None,\n                get_project_root=lambda: \"/tmp/non-existent\",\n                get_model_name=lambda p: str(p).split(\"/\")[-1].split(\"\\\\\")[-1],\n                ensure_model_downloaded=lambda *_: \"\",\n                env_bool=lambda *_: False,\n            )\n\n        self.assertEqual(\"acestep-v15-base\", result[\"loaded_model\"])\n        self.assertIsNone(result[\"loaded_lm_model\"])\n\n    def test_lm_init_failure_sets_state_and_raises(self):\n        \"\"\"LLM init failure should update state flags and raise RuntimeError.\"\"\"\n\n        state = SimpleNamespace(\n            handler=_FakeHandler(),\n            llm_handler=_FailingLlm(),\n            _llm_init_lock=threading.Lock(),\n            _config_path=\"\",\n            _llm_initialized=True,\n            _llm_init_error=None,\n            _llm_lazy_load_disabled=False,\n        )\n\n        with mock.patch(\"acestep.api.http.model_init_service.os.makedirs\"):\n            with self.assertRaises(RuntimeError) as ctx:\n                initialize_models_for_request(\n                    app_state=state,\n                    model_name=\"acestep-v15-base\",\n                    init_llm=True,\n                    requested_lm_model_path=\"acestep-5Hz-lm-0.6B\",\n                    get_project_root=lambda: \"/tmp/non-existent\",\n                    get_model_name=lambda p: str(p).split(\"/\")[-1].split(\"\\\\\")[-1],\n                    ensure_model_downloaded=lambda *_: \"\",\n                    env_bool=lambda *_: False,\n                )\n\n        self.assertIn(\"LLM init failed\", str(ctx.exception))\n        self.assertFalse(state._llm_initialized)\n        self.assertEqual(\"llm-failed\", state._llm_init_error)\n\n\nif __name__ == \"__main__\":\n    unittest.main()\n"
  },
  {
    "path": "acestep/api/http/model_service_routes.py",
    "content": "\"\"\"HTTP routes for service health, model inventory, and on-demand model init.\"\"\"\n\nfrom __future__ import annotations\n\nimport asyncio\nimport json\nimport os\nfrom typing import Any, Callable, Dict, List, Optional\n\nfrom fastapi import Depends, FastAPI\nfrom pydantic import BaseModel, Field\n\nfrom acestep.api.http.model_init_service import initialize_models_for_request\nfrom acestep.constants import TASK_TYPES_BASE, TASK_TYPES_TURBO\n\n\nclass InitModelRequest(BaseModel):\n    \"\"\"Request payload for on-demand DiT/LM model initialization.\"\"\"\n\n    model: Optional[str] = Field(default=None, description=\"DiT model name to initialize (e.g., 'acestep-v15-base')\")\n    init_llm: bool = Field(default=False, description=\"Whether to initialize LLM as part of this request\")\n    lm_model_path: Optional[str] = Field(default=None, description=\"LLM model path/name (e.g., 'acestep-5Hz-lm-1.7B')\")\n\n\ndef _read_model_supported_tasks(checkpoint_dir: str, model_name: str) -> List[str]:\n    \"\"\"Read config.json for a model and return its supported task types.\"\"\"\n    config_path = os.path.join(checkpoint_dir, model_name, \"config.json\")\n    if not os.path.isfile(config_path):\n        return list(TASK_TYPES_BASE)\n    try:\n        with open(config_path, \"r\") as f:\n            config = json.load(f)\n        is_turbo = config.get(\"is_turbo\", False)\n        if is_turbo:\n            return list(TASK_TYPES_TURBO)\n        return list(TASK_TYPES_BASE)\n    except Exception:\n        return list(TASK_TYPES_BASE)\n\n\ndef _collect_model_inventory(\n    app: FastAPI,\n    get_project_root: Callable[[], str],\n    get_model_name: Callable[[str], str],\n) -> Dict[str, Any]:\n    \"\"\"Collect DiT/LM inventory for status endpoints.\n\n    Inputs: app state plus project/model helper callables.\n    Returns: wrapped-internal inventory payload with loaded/default model metadata.\n    \"\"\"\n\n    project_root = get_project_root()\n    checkpoint_dir = os.path.join(project_root, \"checkpoints\")\n\n    loaded_dit_models: Dict[str, bool] = {}\n    primary_model = get_model_name(getattr(app.state, \"_config_path\", \"\"))\n    secondary_model = get_model_name(getattr(app.state, \"_config_path2\", \"\"))\n    third_model = get_model_name(getattr(app.state, \"_config_path3\", \"\"))\n\n    if getattr(app.state, \"_initialized\", False) and primary_model:\n        loaded_dit_models[primary_model] = True\n    if getattr(app.state, \"_initialized2\", False) and secondary_model:\n        loaded_dit_models[secondary_model] = True\n    if getattr(app.state, \"_initialized3\", False) and third_model:\n        loaded_dit_models[third_model] = True\n\n    available_dit_models = set(loaded_dit_models.keys())\n    available_lm_models = set()\n\n    if os.path.isdir(checkpoint_dir):\n        for name in os.listdir(checkpoint_dir):\n            full_path = os.path.join(checkpoint_dir, name)\n            if not os.path.isdir(full_path):\n                continue\n            if name.startswith(\"acestep-5Hz-lm-\"):\n                available_lm_models.add(name)\n            elif name.startswith(\"acestep-\"):\n                available_dit_models.add(name)\n\n    llm_initialized = bool(getattr(app.state, \"_llm_initialized\", False))\n    loaded_lm_model: Optional[str] = None\n    if llm_initialized:\n        llm = getattr(app.state, \"llm_handler\", None)\n        llm_params = getattr(llm, \"last_init_params\", None) if llm else None\n        lm_model_path = \"\"\n        if isinstance(llm_params, dict):\n            lm_model_path = str(llm_params.get(\"lm_model_path\", \"\") or \"\")\n        if not lm_model_path:\n            lm_model_path = os.getenv(\"ACESTEP_LM_MODEL_PATH\", \"\").strip()\n        loaded_lm_model = get_model_name(lm_model_path) or None\n        if loaded_lm_model:\n            available_lm_models.add(loaded_lm_model)\n\n    models = [\n        {\n            \"name\": name,\n            \"is_default\": bool(name == primary_model and primary_model),\n            \"is_loaded\": name in loaded_dit_models,\n            \"supported_task_types\": _read_model_supported_tasks(checkpoint_dir, name),\n        }\n        for name in sorted(available_dit_models)\n    ]\n    lm_models = [\n        {\n            \"name\": name,\n            \"is_loaded\": bool(loaded_lm_model and name == loaded_lm_model),\n        }\n        for name in sorted(available_lm_models)\n    ]\n\n    return {\n        \"models\": models,\n        \"default_model\": primary_model or None,\n        \"lm_models\": lm_models,\n        \"loaded_lm_model\": loaded_lm_model,\n        \"llm_initialized\": llm_initialized,\n    }\n\n\ndef register_model_service_routes(\n    app: FastAPI,\n    verify_api_key: Callable[..., Any],\n    wrap_response: Callable[..., Dict[str, Any]],\n    store: Any,\n    queue_maxsize: int,\n    initial_avg_job_seconds: float,\n    get_project_root: Callable[[], str],\n    get_model_name: Callable[[str], str],\n    ensure_model_downloaded: Callable[[str, str], str],\n    env_bool: Callable[[str, bool], bool],\n) -> None:\n    \"\"\"Register health/stats/inventory/init routes.\n\n    Inputs: app, auth/response wrappers, job store settings, and model helper callables.\n    Returns: None after route registration side effects on ``app``.\n    \"\"\"\n\n    @app.get(\"/health\")\n    async def health_check():\n        \"\"\"Health check endpoint for service status.\"\"\"\n\n        inventory = _collect_model_inventory(app, get_project_root, get_model_name)\n        return wrap_response(\n            {\n                \"status\": \"ok\",\n                \"service\": \"ACE-Step API\",\n                \"version\": \"1.0\",\n                \"models_initialized\": bool(getattr(app.state, \"_initialized\", False)),\n                \"llm_initialized\": inventory[\"llm_initialized\"],\n                \"loaded_model\": inventory[\"default_model\"],\n                \"loaded_lm_model\": inventory[\"loaded_lm_model\"],\n            }\n        )\n\n    @app.get(\"/v1/stats\")\n    async def get_stats(_: None = Depends(verify_api_key)):\n        \"\"\"Get server statistics including job store stats.\"\"\"\n\n        job_stats = store.get_stats()\n        async with app.state.stats_lock:\n            avg_job_seconds = getattr(app.state, \"avg_job_seconds\", initial_avg_job_seconds)\n        return wrap_response(\n            {\n                \"jobs\": job_stats,\n                \"queue_size\": app.state.job_queue.qsize(),\n                \"queue_maxsize\": queue_maxsize,\n                \"avg_job_seconds\": avg_job_seconds,\n            }\n        )\n\n    @app.get(\"/v1/models\")\n    async def list_models(_: None = Depends(verify_api_key)):\n        \"\"\"List available DiT/LM models and their load status.\"\"\"\n\n        return wrap_response(_collect_model_inventory(app, get_project_root, get_model_name))\n\n    @app.get(\"/v1/model_inventory\")\n    async def model_inventory(_: None = Depends(verify_api_key)):\n        \"\"\"List available DiT/LM models (non-OpenRouter internal endpoint).\"\"\"\n\n        return wrap_response(_collect_model_inventory(app, get_project_root, get_model_name))\n\n    @app.post(\"/v1/init\")\n    async def init_model(request: InitModelRequest, _: None = Depends(verify_api_key)):\n        \"\"\"Initialize or switch DiT/LM models on demand.\"\"\"\n\n        async with app.state._init_lock:\n            loop = asyncio.get_running_loop()\n\n            try:\n                result = await loop.run_in_executor(\n                    app.state.executor,\n                    lambda: initialize_models_for_request(\n                        app_state=app.state,\n                        model_name=request.model,\n                        init_llm=request.init_llm,\n                        requested_lm_model_path=request.lm_model_path,\n                        get_project_root=get_project_root,\n                        get_model_name=get_model_name,\n                        ensure_model_downloaded=ensure_model_downloaded,\n                        env_bool=env_bool,\n                    ),\n                )\n                inventory = _collect_model_inventory(app, get_project_root, get_model_name)\n                return wrap_response(\n                    {\n                        \"message\": \"Model initialization completed\",\n                        \"loaded_model\": result.get(\"loaded_model\"),\n                        \"loaded_lm_model\": result.get(\"loaded_lm_model\"),\n                        \"models\": inventory[\"models\"],\n                        \"lm_models\": inventory[\"lm_models\"],\n                        \"llm_initialized\": inventory[\"llm_initialized\"],\n                    }\n                )\n            except Exception as exc:\n                return wrap_response(None, code=500, error=f\"Model initialization failed: {str(exc)}\")\n"
  },
  {
    "path": "acestep/api/http/model_service_routes_http_test.py",
    "content": "\"\"\"HTTP integration tests for model service routes.\"\"\"\n\nimport asyncio\nimport queue\nimport threading\nimport unittest\nfrom types import SimpleNamespace\nfrom unittest import mock\n\nfrom fastapi import FastAPI, Header, HTTPException\nfrom fastapi.testclient import TestClient\n\nfrom acestep.api.http.model_service_routes import register_model_service_routes\n\n\ndef _wrap_response(data, code=200, error=None):\n    \"\"\"Return an ``api_server``-compatible response envelope dict.\"\"\"\n\n    return {\"data\": data, \"code\": code, \"error\": error}\n\n\nasync def _verify_api_key(authorization: str | None = Header(None)) -> None:\n    \"\"\"Validate a fixed bearer token and return ``None`` on success.\"\"\"\n\n    if authorization != \"Bearer test-token\":\n        raise HTTPException(status_code=401, detail=\"Unauthorized\")\n\n\nclass _FakeStore:\n    \"\"\"Fake job store implementation for stats endpoint tests.\"\"\"\n\n    def get_stats(self):\n        \"\"\"Return deterministic job stats as a mapping payload.\"\"\"\n\n        return {\"total\": 2, \"queued\": 1, \"running\": 1, \"succeeded\": 0, \"failed\": 0}\n\n\nclass _FakeHandler:\n    \"\"\"Minimal fake DiT handler for /v1/init route wiring.\"\"\"\n\n    def initialize_service(self, **_kwargs):\n        \"\"\"Return ``(\\\"ok\\\", True)`` to emulate a successful DiT initialization.\"\"\"\n\n        return \"ok\", True\n\n\nclass _FakeLlm:\n    \"\"\"Minimal fake LLM handler for route state access.\"\"\"\n\n    last_init_params = None\n\n    def initialize(self, **_kwargs):\n        \"\"\"Return ``(\\\"ok\\\", True)`` for init_llm success paths.\"\"\"\n\n        return \"ok\", True\n\n\nclass _FailingLlm:\n    \"\"\"Minimal fake LLM handler that fails initialization.\"\"\"\n\n    last_init_params = None\n\n    def initialize(self, **_kwargs):\n        \"\"\"Return ``(\\\"llm-failed\\\", False)`` for LLM failure-path tests.\"\"\"\n\n        return \"llm-failed\", False\n\n\nclass ModelServiceRoutesHttpTests(unittest.TestCase):\n    \"\"\"Integration tests covering real HTTP requests for model service routes.\"\"\"\n\n    def _build_client(self, llm_handler=None) -> TestClient:\n        \"\"\"Create a route-wired app and return ``TestClient`` for HTTP assertions.\"\"\"\n\n        app = FastAPI()\n        app.state._config_path = \"acestep-v15-base\"\n        app.state._config_path2 = \"\"\n        app.state._config_path3 = \"\"\n        app.state._initialized = True\n        app.state._initialized2 = False\n        app.state._initialized3 = False\n        app.state._llm_initialized = False\n        app.state._llm_init_error = None\n        app.state._llm_lazy_load_disabled = False\n        app.state.llm_handler = llm_handler or _FakeLlm()\n        app.state.handler = _FakeHandler()\n        app.state._init_lock = asyncio.Lock()\n        app.state._llm_init_lock = threading.Lock()\n        app.state.stats_lock = asyncio.Lock()\n        app.state.avg_job_seconds = 4.2\n        app.state.job_queue = queue.Queue()\n        app.state.executor = None\n        register_model_service_routes(\n            app=app,\n            verify_api_key=_verify_api_key,\n            wrap_response=_wrap_response,\n            store=_FakeStore(),\n            queue_maxsize=200,\n            initial_avg_job_seconds=5.0,\n            get_project_root=lambda: \"/tmp/non-existent\",\n            get_model_name=lambda p: str(p).split(\"/\")[-1].split(\"\\\\\")[-1],\n            ensure_model_downloaded=lambda *_: \"\",\n            env_bool=lambda *_: False,\n        )\n        return TestClient(app)\n\n    def test_stats_requires_authentication(self):\n        \"\"\"GET /v1/stats without token should return HTTP 401.\"\"\"\n\n        client = self._build_client()\n        response = client.get(\"/v1/stats\")\n        self.assertEqual(401, response.status_code)\n\n    def test_models_requires_authentication(self):\n        \"\"\"GET /v1/models without token should return HTTP 401.\"\"\"\n\n        client = self._build_client()\n        response = client.get(\"/v1/models\")\n        self.assertEqual(401, response.status_code)\n\n    def test_model_inventory_requires_authentication(self):\n        \"\"\"GET /v1/model_inventory without token should return HTTP 401.\"\"\"\n\n        client = self._build_client()\n        response = client.get(\"/v1/model_inventory\")\n        self.assertEqual(401, response.status_code)\n\n    def test_init_requires_authentication(self):\n        \"\"\"POST /v1/init without token should return HTTP 401.\"\"\"\n\n        client = self._build_client()\n        response = client.post(\"/v1/init\", json={\"model\": \"acestep-v15-base\", \"init_llm\": False})\n        self.assertEqual(401, response.status_code)\n\n    def test_health_returns_wrapped_payload(self):\n        \"\"\"GET /health should return wrapped status payload with service marker.\"\"\"\n\n        client = self._build_client()\n        response = client.get(\"/health\")\n        self.assertEqual(200, response.status_code)\n        payload = response.json()\n        self.assertEqual(200, payload[\"code\"])\n        self.assertEqual(\"ACE-Step API\", payload[\"data\"][\"service\"])\n\n    def test_init_route_returns_wrapped_success(self):\n        \"\"\"POST /v1/init should return wrapped success payload.\"\"\"\n\n        client = self._build_client()\n        with mock.patch(\n            \"acestep.api.http.model_service_routes.initialize_models_for_request\",\n            return_value={\"loaded_model\": \"acestep-v15-base\", \"loaded_lm_model\": None},\n        ):\n            response = client.post(\n                \"/v1/init\",\n                headers={\"Authorization\": \"Bearer test-token\"},\n                json={\"model\": \"acestep-v15-base\", \"init_llm\": False},\n            )\n\n        self.assertEqual(200, response.status_code)\n        payload = response.json()\n        self.assertEqual(200, payload[\"code\"])\n        self.assertEqual(\"Model initialization completed\", payload[\"data\"][\"message\"])\n\n    def test_init_route_returns_wrapped_error_when_initializer_fails(self):\n        \"\"\"POST /v1/init should preserve wrapped code=500 contract on init failures.\"\"\"\n\n        client = self._build_client()\n        with mock.patch(\n            \"acestep.api.http.model_service_routes.initialize_models_for_request\",\n            side_effect=RuntimeError(\"boom\"),\n        ):\n            response = client.post(\n                \"/v1/init\",\n                headers={\"Authorization\": \"Bearer test-token\"},\n                json={\"model\": \"acestep-v15-base\", \"init_llm\": False},\n            )\n\n        self.assertEqual(200, response.status_code)\n        payload = response.json()\n        self.assertEqual(500, payload[\"code\"])\n        self.assertIn(\"Model initialization failed\", payload[\"error\"])\n\n    def test_init_route_returns_wrapped_error_when_llm_init_fails(self):\n        \"\"\"POST /v1/init with init_llm should wrap LLM initialization failures.\"\"\"\n\n        client = self._build_client(llm_handler=_FailingLlm())\n        with mock.patch(\"acestep.api.http.model_init_service.os.makedirs\"):\n            response = client.post(\n                \"/v1/init\",\n                headers={\"Authorization\": \"Bearer test-token\"},\n                json={\"model\": \"acestep-v15-base\", \"init_llm\": True, \"lm_model_path\": \"acestep-5Hz-lm-0.6B\"},\n            )\n\n        self.assertEqual(200, response.status_code)\n        payload = response.json()\n        self.assertEqual(500, payload[\"code\"])\n        self.assertIn(\"LLM init failed\", payload[\"error\"])\n\n\nif __name__ == \"__main__\":\n    unittest.main()\n"
  },
  {
    "path": "acestep/api/http/model_service_routes_test.py",
    "content": "\"\"\"Unit tests for model service route registration helpers.\"\"\"\n\nimport asyncio\nimport os\nimport queue\nimport unittest\nfrom types import SimpleNamespace\nfrom unittest import mock\n\nfrom fastapi import FastAPI\nfrom fastapi.routing import APIRoute\n\nfrom acestep.api.http.model_service_routes import (\n    InitModelRequest,\n    _collect_model_inventory,\n    register_model_service_routes,\n)\n\n\ndef _wrap_response(data, code=200, error=None):\n    \"\"\"Return an ``api_server``-compatible response envelope dict.\"\"\"\n\n    return {\"data\": data, \"code\": code, \"error\": error}\n\n\nasync def _verify_api_key(_: str | None = None) -> None:\n    \"\"\"Return ``None`` as a no-op auth dependency for unit tests.\"\"\"\n\n    return None\n\n\ndef _get_endpoint(app: FastAPI, path: str, method: str):\n    \"\"\"Return the endpoint callable matching ``path`` and HTTP ``method``.\"\"\"\n\n    for route in app.routes:\n        if isinstance(route, APIRoute) and route.path == path and method.upper() in route.methods:\n            return route.endpoint\n    raise AssertionError(f\"Missing route: {method} {path}\")\n\n\nclass _FakeStore:\n    \"\"\"Small fake store for stats route registration dependencies.\"\"\"\n\n    def get_stats(self):\n        \"\"\"Return deterministic job stats payload mapping.\"\"\"\n\n        return {\"total\": 0, \"queued\": 0, \"running\": 0, \"succeeded\": 0, \"failed\": 0}\n\n\nclass ModelServiceRoutesTests(unittest.TestCase):\n    \"\"\"Unit-level behavior tests for model service route module.\"\"\"\n\n    def _build_app(self) -> FastAPI:\n        \"\"\"Create app with minimal state required by registered routes.\"\"\"\n\n        app = FastAPI()\n        app.state._config_path = \"acestep-v15-base\"\n        app.state._config_path2 = \"\"\n        app.state._config_path3 = \"\"\n        app.state._initialized = True\n        app.state._initialized2 = False\n        app.state._initialized3 = False\n        app.state._llm_initialized = True\n        app.state.llm_handler = SimpleNamespace(last_init_params={\"lm_model_path\": \"acestep-5Hz-lm-1.7B\"})\n        app.state._llm_lazy_load_disabled = False\n        app.state._init_lock = asyncio.Lock()\n        app.state.executor = None\n        app.state.stats_lock = asyncio.Lock()\n        app.state.avg_job_seconds = 3.5\n        app.state.job_queue = queue.Queue()\n        app.state.handler = SimpleNamespace()\n        app.state._llm_init_lock = mock.MagicMock()\n        register_model_service_routes(\n            app=app,\n            verify_api_key=_verify_api_key,\n            wrap_response=_wrap_response,\n            store=_FakeStore(),\n            queue_maxsize=200,\n            initial_avg_job_seconds=5.0,\n            get_project_root=lambda: \"/tmp/non-existent\",\n            get_model_name=lambda p: os.path.basename(str(p).rstrip(\"/\\\\\")),\n            ensure_model_downloaded=lambda *_: \"\",\n            env_bool=lambda *_: False,\n        )\n        return app\n\n    def test_collect_model_inventory_merges_loaded_and_available_models(self):\n        \"\"\"Inventory helper should include loaded default model and discovered models.\"\"\"\n\n        app = self._build_app()\n        with mock.patch(\"acestep.api.http.model_service_routes.os.path.isdir\", return_value=True), mock.patch(\n            \"acestep.api.http.model_service_routes.os.listdir\",\n            return_value=[\"acestep-v15-base\", \"acestep-v15-turbo\", \"acestep-5Hz-lm-1.7B\"],\n        ):\n            inventory = _collect_model_inventory(\n                app=app,\n                get_project_root=lambda: \"/fake/project\",\n                get_model_name=lambda p: os.path.basename(str(p).rstrip(\"/\\\\\")),\n            )\n\n        names = [m[\"name\"] for m in inventory[\"models\"]]\n        self.assertIn(\"acestep-v15-base\", names)\n        self.assertIn(\"acestep-v15-turbo\", names)\n        self.assertEqual(\"acestep-v15-base\", inventory[\"default_model\"])\n        self.assertTrue(inventory[\"llm_initialized\"])\n\n    def test_init_route_wraps_initializer_exception(self):\n        \"\"\"Init endpoint should convert initializer exceptions into wrapped code=500 payloads.\"\"\"\n\n        app = self._build_app()\n        endpoint = _get_endpoint(app, \"/v1/init\", \"POST\")\n        request = InitModelRequest(model=\"acestep-v15-base\", init_llm=False, lm_model_path=None)\n\n        with mock.patch(\"acestep.api.http.model_service_routes.initialize_models_for_request\", side_effect=RuntimeError(\"boom\")):\n            result = asyncio.run(endpoint(request, None))\n\n        self.assertEqual(500, result[\"code\"])\n        self.assertIn(\"Model initialization failed\", result[\"error\"])\n\n\nif __name__ == \"__main__\":\n    unittest.main()\n"
  },
  {
    "path": "acestep/api/http/query_result_route.py",
    "content": "\"\"\"HTTP route for querying one or more generation task results.\"\"\"\n\nfrom __future__ import annotations\n\nfrom typing import Any, Callable, Dict, Optional\n\nfrom fastapi import FastAPI, Header, Request\n\nfrom acestep.api.http.query_result_service import collect_query_results, parse_task_id_list\n\n\ndef register_query_result_route(\n    app: FastAPI,\n    verify_token_from_request: Callable[[dict, Optional[str]], Optional[str]],\n    wrap_response: Callable[..., Dict[str, Any]],\n    store: Any,\n    map_status: Callable[[str], int],\n    result_key_prefix: str,\n    task_timeout_seconds: int,\n    log_buffer: Any,\n) -> None:\n    \"\"\"Register the ``/query_result`` endpoint.\n\n    Args:\n        app: FastAPI app instance to register the route on.\n        verify_token_from_request: Auth validator used by legacy route.\n        wrap_response: Response envelope builder preserving client contract.\n        store: In-memory job store with ``get(task_id)``.\n        map_status: Mapper from store status text to integer code.\n        result_key_prefix: Prefix used for local-cache lookup keys.\n        task_timeout_seconds: Timeout threshold for running cached jobs.\n        log_buffer: Shared log buffer with ``last_message`` field.\n    \"\"\"\n\n    @app.post(\"/query_result\")\n    async def query_result_endpoint(request: Request, authorization: Optional[str] = Header(None)):\n        \"\"\"Batch query result payloads for one or more task IDs.\n\n        Args:\n            request: HTTP request containing JSON or form fields.\n            authorization: Optional Authorization header value.\n\n        Returns:\n            Wrapped payload list with one result item per task ID.\n        \"\"\"\n\n        content_type = (request.headers.get(\"content-type\") or \"\").lower()\n        if \"json\" in content_type:\n            body = await request.json()\n        else:\n            form = await request.form()\n            body = {key: value for key, value in form.items()}\n\n        verify_token_from_request(body, authorization)\n        task_ids = parse_task_id_list(body.get(\"task_id_list\", \"[]\"))\n        local_cache = getattr(app.state, \"local_cache\", None)\n        data_list = collect_query_results(\n            task_ids=task_ids,\n            local_cache=local_cache,\n            store=store,\n            map_status=map_status,\n            result_key_prefix=result_key_prefix,\n            task_timeout_seconds=task_timeout_seconds,\n            get_log_last_message=lambda: log_buffer.last_message,\n        )\n        return wrap_response(data_list)\n"
  },
  {
    "path": "acestep/api/http/query_result_route_http_test.py",
    "content": "\"\"\"HTTP integration tests for query-result route behavior.\"\"\"\n\nimport json\nimport time\nimport unittest\nfrom types import SimpleNamespace\n\nfrom fastapi import FastAPI, HTTPException\nfrom fastapi.testclient import TestClient\n\nfrom acestep.api.http.query_result_route import register_query_result_route\n\n\ndef _wrap_response(data, code=200, error=None):\n    \"\"\"Return an ``api_server``-compatible response envelope dict.\"\"\"\n\n    return {\n        \"data\": data,\n        \"code\": code,\n        \"error\": error,\n        \"timestamp\": int(time.time() * 1000),\n        \"extra\": None,\n    }\n\n\ndef _verify_token_from_request(body: dict, authorization: str | None = None) -> None:\n    \"\"\"Validate a fixed body/header token for HTTP tests.\"\"\"\n\n    if (body or {}).get(\"ai_token\") == \"test-token\":\n        return\n    if authorization == \"Bearer test-token\":\n        return\n    raise HTTPException(status_code=401, detail=\"Unauthorized\")\n\n\ndef _map_status(status: str) -> int:\n    \"\"\"Map internal store status strings to legacy integer status values.\"\"\"\n\n    return {\"queued\": 0, \"running\": 0, \"succeeded\": 1, \"failed\": 2}.get(status, 2)\n\n\nclass _FakeStore:\n    \"\"\"Minimal in-memory store fake keyed by task ID.\"\"\"\n\n    def __init__(self, records: dict[str, object]) -> None:\n        \"\"\"Store deterministic records for ``get`` lookups.\"\"\"\n\n        self._records = records\n\n    def get(self, task_id: str):\n        \"\"\"Return configured record by ID, or ``None`` when missing.\"\"\"\n\n        return self._records.get(task_id)\n\n\nclass QueryResultRouteHttpTests(unittest.TestCase):\n    \"\"\"Integration tests covering real HTTP calls for query-result route.\"\"\"\n\n    def _build_client(self, records: dict[str, object] | None = None, local_cache: object | None = None) -> TestClient:\n        \"\"\"Create app and register query-result route for HTTP tests.\"\"\"\n\n        app = FastAPI()\n        app.state.local_cache = local_cache\n        register_query_result_route(\n            app=app,\n            verify_token_from_request=_verify_token_from_request,\n            wrap_response=_wrap_response,\n            store=_FakeStore(records or {}),\n            map_status=_map_status,\n            result_key_prefix=\"ace_step_v1.5_\",\n            task_timeout_seconds=3600,\n            log_buffer=SimpleNamespace(last_message=\"processing\"),\n        )\n        return TestClient(app)\n\n    def test_query_result_requires_auth(self):\n        \"\"\"POST /query_result should return 401 when auth token is missing.\"\"\"\n\n        client = self._build_client()\n        response = client.post(\"/query_result\", json={\"task_id_list\": [\"task-1\"]})\n        self.assertEqual(401, response.status_code)\n\n    def test_query_result_marks_timed_out_cache_entry_as_failed(self):\n        \"\"\"POST /query_result should return status 2 for stale running cache entries.\"\"\"\n\n        stale = json.dumps([{\"status\": 0, \"create_time\": int(time.time()) - 7200}])\n        local_cache = {\"ace_step_v1.5_task-1\": stale}\n        client = self._build_client(local_cache=local_cache)\n        response = client.post(\"/query_result\", json={\"ai_token\": \"test-token\", \"task_id_list\": [\"task-1\"]})\n\n        self.assertEqual(200, response.status_code)\n        payload = response.json()\n        self.assertEqual(200, payload[\"code\"])\n        self.assertEqual(2, payload[\"data\"][0][\"status\"])\n        self.assertIn(\"timestamp\", payload)\n        self.assertIsNone(payload[\"extra\"])\n\n    def test_query_result_returns_full_analysis_result_directly(self):\n        \"\"\"POST /query_result should preserve full-analysis payload wrapping contract.\"\"\"\n\n        record = SimpleNamespace(\n            status=\"succeeded\",\n            created_at=100.0,\n            result={\"status_message\": \"Full Hardware Analysis Success\", \"analysis\": \"ok\"},\n            progress_text=\"done\",\n            progress=1.0,\n            stage=\"succeeded\",\n            error=None,\n            env=\"development\",\n        )\n        client = self._build_client(records={\"task-3\": record})\n        response = client.post(\"/query_result\", json={\"ai_token\": \"test-token\", \"task_id_list\": [\"task-3\"]})\n\n        self.assertEqual(200, response.status_code)\n        payload = response.json()\n        result_json = json.loads(payload[\"data\"][0][\"result\"])\n        self.assertEqual(\"Full Hardware Analysis Success\", result_json[0][\"status_message\"])\n\n    def test_query_result_returns_extract_codes_result_directly(self):\n        \"\"\"POST /query_result should preserve extract-codes payload with audio_codes field.\"\"\"\n\n        record = SimpleNamespace(\n            status=\"succeeded\",\n            created_at=100.0,\n            result={\n                \"status_message\": \"Audio Codes Extraction Success\",\n                \"audio_codes\": \"<|audio_code_1|><|audio_code_2|>\",\n                \"audio_paths\": [],\n                \"raw_audio_paths\": [],\n                \"first_audio_path\": None,\n                \"metas\": {},\n            },\n            progress_text=\"done\",\n            progress=1.0,\n            stage=\"succeeded\",\n            error=None,\n            env=\"development\",\n        )\n        client = self._build_client(records={\"task-ec\": record})\n        response = client.post(\n            \"/query_result\",\n            json={\"ai_token\": \"test-token\", \"task_id_list\": [\"task-ec\"]},\n        )\n\n        self.assertEqual(200, response.status_code)\n        payload = response.json()\n        result_json = json.loads(payload[\"data\"][0][\"result\"])\n        self.assertEqual(\n            \"Audio Codes Extraction Success\",\n            result_json[0][\"status_message\"],\n        )\n        self.assertEqual(\n            \"<|audio_code_1|><|audio_code_2|>\",\n            result_json[0][\"audio_codes\"],\n        )\n\n    def test_query_result_accepts_form_encoded_payload(self):\n        \"\"\"POST /query_result should accept form payloads and parse task IDs from JSON text.\"\"\"\n\n        record = SimpleNamespace(\n            status=\"succeeded\",\n            created_at=100.0,\n            result={\"audio_paths\": [\"form.mp3\"], \"metas\": {\"caption\": \"c\"}},\n            progress_text=\"done\",\n            progress=1.0,\n            stage=\"succeeded\",\n            error=None,\n            env=\"development\",\n        )\n        client = self._build_client(records={\"task-form\": record})\n        response = client.post(\n            \"/query_result\",\n            data={\"ai_token\": \"test-token\", \"task_id_list\": json.dumps([\"task-form\"])},\n        )\n\n        self.assertEqual(200, response.status_code)\n        payload = response.json()\n        self.assertEqual(200, payload[\"code\"])\n        result_json = json.loads(payload[\"data\"][0][\"result\"])\n        self.assertEqual(\"form.mp3\", result_json[0][\"file\"])\n\n    def test_query_result_returns_empty_data_for_missing_task_id_list(self):\n        \"\"\"POST /query_result should return an empty result list when task IDs are omitted.\"\"\"\n\n        client = self._build_client()\n        response = client.post(\"/query_result\", json={\"ai_token\": \"test-token\"})\n        self.assertEqual(200, response.status_code)\n        payload = response.json()\n        self.assertEqual([], payload[\"data\"])\n\n    def test_query_result_returns_empty_data_for_malformed_task_id_list(self):\n        \"\"\"POST /query_result should return an empty result list when task IDs are malformed.\"\"\"\n\n        client = self._build_client()\n        response = client.post(\n            \"/query_result\",\n            json={\"ai_token\": \"test-token\", \"task_id_list\": \"not-valid-json\"},\n        )\n        self.assertEqual(200, response.status_code)\n        payload = response.json()\n        self.assertEqual([], payload[\"data\"])\n\n    def test_query_result_preserves_non_list_json_task_id_iteration(self):\n        \"\"\"POST /query_result should keep legacy iteration behavior for parsed non-list JSON payloads.\"\"\"\n\n        client = self._build_client()\n        response = client.post(\n            \"/query_result\",\n            json={\"ai_token\": \"test-token\", \"task_id_list\": '{\"task-a\": 1, \"task-b\": 2}'},\n        )\n        self.assertEqual(200, response.status_code)\n        payload = response.json()\n        self.assertEqual(2, len(payload[\"data\"]))\n        self.assertEqual(\"task-a\", payload[\"data\"][0][\"task_id\"])\n        self.assertEqual(\"task-b\", payload[\"data\"][1][\"task_id\"])\n        self.assertEqual(0, payload[\"data\"][0][\"status\"])\n        self.assertEqual(0, payload[\"data\"][1][\"status\"])\n\n\nif __name__ == \"__main__\":\n    unittest.main()\n"
  },
  {
    "path": "acestep/api/http/query_result_route_test.py",
    "content": "\"\"\"Unit tests for query-result route registration and helper behavior.\"\"\"\n\nimport asyncio\nimport json\nimport time\nimport unittest\nfrom types import SimpleNamespace\n\nfrom fastapi import FastAPI, HTTPException\nfrom fastapi.routing import APIRoute\n\nfrom acestep.api.http.query_result_route import register_query_result_route\n\n\ndef _wrap_response(data, code=200, error=None):\n    \"\"\"Return an ``api_server``-compatible response envelope dict.\"\"\"\n\n    return {\n        \"data\": data,\n        \"code\": code,\n        \"error\": error,\n        \"timestamp\": int(time.time() * 1000),\n        \"extra\": None,\n    }\n\n\ndef _verify_token_from_request(body: dict, authorization: str | None = None) -> None:\n    \"\"\"Validate a fixed body/header token for route unit tests.\"\"\"\n\n    if (body or {}).get(\"ai_token\") == \"test-token\":\n        return\n    if authorization == \"Bearer test-token\":\n        return\n    raise HTTPException(status_code=401, detail=\"Unauthorized\")\n\n\ndef _map_status(status: str) -> int:\n    \"\"\"Map internal store status strings to legacy integer status values.\"\"\"\n\n    return {\"queued\": 0, \"running\": 0, \"succeeded\": 1, \"failed\": 2}.get(status, 2)\n\n\ndef _get_endpoint(app: FastAPI, path: str, method: str):\n    \"\"\"Return endpoint callable matching a route path/method pair.\"\"\"\n\n    for route in app.routes:\n        if isinstance(route, APIRoute) and route.path == path and method.upper() in route.methods:\n            return route.endpoint\n    raise AssertionError(f\"Missing route: {method} {path}\")\n\n\nclass _FakeStore:\n    \"\"\"Minimal in-memory store fake keyed by task ID.\"\"\"\n\n    def __init__(self, records: dict[str, object]) -> None:\n        \"\"\"Store deterministic records for ``get`` lookups.\"\"\"\n\n        self._records = records\n\n    def get(self, task_id: str):\n        \"\"\"Return configured record by ID, or ``None`` when missing.\"\"\"\n\n        return self._records.get(task_id)\n\n\nclass QueryResultRouteTests(unittest.TestCase):\n    \"\"\"Behavior tests for query-result route decomposition.\"\"\"\n\n    def _build_app(self, records: dict[str, object] | None = None, local_cache: object | None = None) -> FastAPI:\n        \"\"\"Create app state and register query-result route for tests.\"\"\"\n\n        app = FastAPI()\n        app.state.local_cache = local_cache\n        register_query_result_route(\n            app=app,\n            verify_token_from_request=_verify_token_from_request,\n            wrap_response=_wrap_response,\n            store=_FakeStore(records or {}),\n            map_status=_map_status,\n            result_key_prefix=\"ace_step_v1.5_\",\n            task_timeout_seconds=3600,\n            log_buffer=SimpleNamespace(last_message=\"working\"),\n        )\n        return app\n\n    def test_query_result_uses_cache_payload_when_present(self):\n        \"\"\"Route should return cache payload and running progress text when cache has fresh record.\"\"\"\n\n        create_time = int(time.time())\n        cached = json.dumps([{\"status\": 0, \"create_time\": create_time}])\n        local_cache = {\"ace_step_v1.5_task-1\": cached}\n        app = self._build_app(local_cache=local_cache)\n        endpoint = _get_endpoint(app, \"/query_result\", \"POST\")\n\n        async def _json():\n            \"\"\"Return valid request body for cache-hit path test.\"\"\"\n\n            return {\"ai_token\": \"test-token\", \"task_id_list\": [\"task-1\"]}\n\n        request = SimpleNamespace(headers={\"content-type\": \"application/json\"}, json=_json)\n        result = asyncio.run(endpoint(request, None))\n        self.assertEqual(200, result[\"code\"])\n        self.assertEqual(0, result[\"data\"][0][\"status\"])\n        self.assertEqual(\"working\", result[\"data\"][0][\"progress_text\"])\n\n    def test_query_result_uses_store_payload_when_cache_missing(self):\n        \"\"\"Route should serialize store record payload when cache miss occurs.\"\"\"\n\n        record = SimpleNamespace(\n            status=\"succeeded\",\n            created_at=123.0,\n            result={\n                \"audio_paths\": [\"a.mp3\"],\n                \"metas\": {\"caption\": \"c\", \"lyrics\": \"l\", \"bpm\": 120},\n            },\n            progress_text=\"done\",\n            progress=1.0,\n            stage=\"succeeded\",\n            error=None,\n            env=\"development\",\n        )\n        app = self._build_app(records={\"task-2\": record})\n        endpoint = _get_endpoint(app, \"/query_result\", \"POST\")\n\n        async def _json():\n            \"\"\"Return valid request body for store-fallback path test.\"\"\"\n\n            return {\"ai_token\": \"test-token\", \"task_id_list\": json.dumps([\"task-2\"])}\n\n        request = SimpleNamespace(headers={\"content-type\": \"application/json\"}, json=_json)\n        result = asyncio.run(endpoint(request, None))\n        payload = result[\"data\"][0]\n        self.assertEqual(1, payload[\"status\"])\n        serialized = json.loads(payload[\"result\"])\n        self.assertEqual(\"a.mp3\", serialized[0][\"file\"])\n        self.assertEqual(\"c\", serialized[0][\"prompt\"])\n\n    def test_query_result_returns_empty_when_task_missing(self):\n        \"\"\"Route should preserve legacy missing-task response contract.\"\"\"\n\n        app = self._build_app()\n        endpoint = _get_endpoint(app, \"/query_result\", \"POST\")\n\n        async def _json():\n            \"\"\"Return valid request body for missing-task path test.\"\"\"\n\n            return {\"ai_token\": \"test-token\", \"task_id_list\": [\"unknown-id\"]}\n\n        request = SimpleNamespace(headers={\"content-type\": \"application/json\"}, json=_json)\n        result = asyncio.run(endpoint(request, None))\n        self.assertEqual(\"[]\", result[\"data\"][0][\"result\"])\n        self.assertEqual(0, result[\"data\"][0][\"status\"])\n\n    def test_query_result_falls_back_when_cache_json_is_non_list(self):\n        \"\"\"Route should treat non-list cache JSON payloads as failed cache entries.\"\"\"\n\n        local_cache = {\"ace_step_v1.5_task-3\": json.dumps({\"status\": 0, \"create_time\": int(time.time())})}\n        app = self._build_app(local_cache=local_cache)\n        endpoint = _get_endpoint(app, \"/query_result\", \"POST\")\n\n        async def _json():\n            \"\"\"Return valid request body for malformed cache shape test.\"\"\"\n\n            return {\"ai_token\": \"test-token\", \"task_id_list\": [\"task-3\"]}\n\n        request = SimpleNamespace(headers={\"content-type\": \"application/json\"}, json=_json)\n        result = asyncio.run(endpoint(request, None))\n        payload = result[\"data\"][0]\n        self.assertEqual(2, payload[\"status\"])\n        self.assertEqual(local_cache[\"ace_step_v1.5_task-3\"], payload[\"result\"])\n\n\nif __name__ == \"__main__\":\n    unittest.main()\n"
  },
  {
    "path": "acestep/api/http/query_result_service.py",
    "content": "\"\"\"Service helpers for `/query_result` response shaping.\"\"\"\n\nfrom __future__ import annotations\n\nimport json\nimport time\nfrom typing import Any, Callable, Dict, List\n\n\ndef parse_task_id_list(task_id_list_raw: Any) -> Any:\n    \"\"\"Parse raw ``task_id_list`` input using legacy permissive semantics.\n\n    Args:\n        task_id_list_raw: Either a list of IDs or JSON-encoded text.\n\n    Returns:\n        Raw list value when already a list, parsed JSON value otherwise,\n        or an empty list when JSON parsing fails.\n    \"\"\"\n\n    if isinstance(task_id_list_raw, list):\n        return task_id_list_raw\n    try:\n        return json.loads(task_id_list_raw)\n    except Exception:\n        return []\n\n\ndef _build_running_result_payload(\n    task_id: str,\n    data: str,\n    current_time: float,\n    task_timeout_seconds: int,\n    get_log_last_message: Callable[[], str],\n) -> Dict[str, Any]:\n    \"\"\"Return one cache-derived response item for the given task.\"\"\"\n\n    try:\n        data_json = json.loads(data)\n    except (TypeError, json.JSONDecodeError):\n        data_json = []\n\n    if (\n        not isinstance(data_json, list)\n        or len(data_json) <= 0\n        or not isinstance(data_json[0], dict)\n    ):\n        return {\"task_id\": task_id, \"result\": data, \"status\": 2}\n\n    first_item = data_json[0]\n    status = first_item.get(\"status\")\n    create_time = first_item.get(\"create_time\", 0)\n    if status == 0 and (current_time - create_time) > task_timeout_seconds:\n        return {\"task_id\": task_id, \"result\": data, \"status\": 2}\n    return {\n        \"task_id\": task_id,\n        \"result\": data,\n        \"status\": int(status) if status is not None else 1,\n        \"progress_text\": get_log_last_message(),\n    }\n\n\ndef _build_store_result_payload(\n    task_id: str,\n    record: Any,\n    map_status: Callable[[str], int],\n    get_log_last_message: Callable[[], str],\n) -> Dict[str, Any]:\n    \"\"\"Return one store-derived response item for the given task.\"\"\"\n\n    env = getattr(record, \"env\", \"development\")\n    create_time = record.created_at\n    status_int = map_status(record.status)\n\n    if record.result and record.status == \"succeeded\":\n        if record.result.get(\"status_message\") in (\n            \"Full Hardware Analysis Success\",\n            \"Audio Codes Extraction Success\",\n        ):\n            result_data = [record.result]\n        else:\n            audio_paths = record.result.get(\"audio_paths\", [])\n            metas = record.result.get(\"metas\", {}) or {}\n            result_data = [\n                {\n                    \"file\": path,\n                    \"wave\": \"\",\n                    \"status\": status_int,\n                    \"create_time\": int(create_time),\n                    \"env\": env,\n                    \"prompt\": metas.get(\"caption\", \"\"),\n                    \"lyrics\": metas.get(\"lyrics\", \"\"),\n                    \"metas\": {\n                        \"bpm\": metas.get(\"bpm\"),\n                        \"duration\": metas.get(\"duration\"),\n                        \"genres\": metas.get(\"genres\", \"\"),\n                        \"keyscale\": metas.get(\"keyscale\", \"\"),\n                        \"timesignature\": metas.get(\"timesignature\", \"\"),\n                    },\n                }\n                for path in audio_paths\n            ] if audio_paths else [{\n                \"file\": \"\",\n                \"wave\": \"\",\n                \"status\": status_int,\n                \"create_time\": int(create_time),\n                \"env\": env,\n                \"prompt\": metas.get(\"caption\", \"\"),\n                \"lyrics\": metas.get(\"lyrics\", \"\"),\n                \"metas\": {\n                    \"bpm\": metas.get(\"bpm\"),\n                    \"duration\": metas.get(\"duration\"),\n                    \"genres\": metas.get(\"genres\", \"\"),\n                    \"keyscale\": metas.get(\"keyscale\", \"\"),\n                    \"timesignature\": metas.get(\"timesignature\", \"\"),\n                },\n            }]\n    else:\n        result_data = [{\n            \"file\": \"\",\n            \"wave\": \"\",\n            \"status\": status_int,\n            \"create_time\": int(create_time),\n            \"env\": env,\n            \"prompt\": \"\",\n            \"lyrics\": \"\",\n            \"metas\": {},\n            \"progress\": float(record.progress) if record else 0.0,\n            \"stage\": record.stage if record else \"queued\",\n            \"error\": record.error if record.error else None,\n        }]\n\n    current_log = get_log_last_message() if status_int == 0 else record.progress_text\n    return {\n        \"task_id\": task_id,\n        \"result\": json.dumps(result_data, ensure_ascii=False),\n        \"status\": status_int,\n        \"progress_text\": current_log,\n    }\n\n\ndef collect_query_results(\n    task_ids: Any,\n    local_cache: Any,\n    store: Any,\n    map_status: Callable[[str], int],\n    result_key_prefix: str,\n    task_timeout_seconds: int,\n    get_log_last_message: Callable[[], str],\n) -> List[Dict[str, Any]]:\n    \"\"\"Collect legacy response items for each requested task ID.\n\n    Args:\n        task_ids: Parsed task ID payload to iterate with legacy behavior.\n        local_cache: Cache object exposing ``get(key)``.\n        store: In-memory store exposing ``get(task_id)``.\n        map_status: Mapper from store status text to integer code.\n        result_key_prefix: Prefix used for local-cache lookup keys.\n        task_timeout_seconds: Timeout threshold for running cached jobs.\n        get_log_last_message: Zero-arg callable returning current global log text.\n\n    Returns:\n        Ordered list of response items matching ``/query_result`` contract.\n    \"\"\"\n\n    current_time = time.time()\n    data_list = []\n    for task_id in task_ids:\n        result_key = f\"{result_key_prefix}{task_id}\"\n        if local_cache:\n            data = local_cache.get(result_key)\n            if data:\n                data_list.append(\n                    _build_running_result_payload(\n                        task_id=task_id,\n                        data=data,\n                        current_time=current_time,\n                        task_timeout_seconds=task_timeout_seconds,\n                        get_log_last_message=get_log_last_message,\n                    )\n                )\n                continue\n\n        record = store.get(task_id)\n        if record:\n            data_list.append(\n                _build_store_result_payload(\n                    task_id=task_id,\n                    record=record,\n                    map_status=map_status,\n                    get_log_last_message=get_log_last_message,\n                )\n            )\n        else:\n            data_list.append({\"task_id\": task_id, \"result\": \"[]\", \"status\": 0})\n    return data_list\n"
  },
  {
    "path": "acestep/api/http/reinitialize_route.py",
    "content": "\"\"\"HTTP route for reinitializing service components after unload flows.\"\"\"\n\nfrom __future__ import annotations\n\nimport os\nfrom typing import Any, Callable, Dict\n\nimport torch\nfrom fastapi import Depends, FastAPI, HTTPException\n\n\ndef register_reinitialize_route(\n    app: FastAPI,\n    verify_api_key: Callable[..., Any],\n    wrap_response: Callable[..., Dict[str, Any]],\n    env_bool: Callable[[str, bool], bool],\n    get_project_root: Callable[[], str],\n) -> None:\n    \"\"\"Register the reinitialization endpoint.\n\n    Inputs: app, auth dependency, response wrapper, env parser, and project-root helper.\n    Returns: None after registering ``POST /v1/reinitialize`` on ``app``.\n    \"\"\"\n\n    @app.post(\"/v1/reinitialize\")\n    async def reinitialize_service(_: None = Depends(verify_api_key)):\n        \"\"\"Reinitialize components that were unloaded during training/preprocessing.\"\"\"\n\n        handler = app.state.handler\n        llm = app.state.llm_handler\n\n        # Preserve original api_server contract: missing service state is an HTTP 500.\n        if handler is None:\n            raise HTTPException(status_code=500, detail=\"Service not initialized\")\n\n        try:\n            import gc\n\n            reloaded = []\n            params = getattr(handler, \"last_init_params\", None) or None\n            if params and (handler.model is None or handler.vae is None or handler.text_encoder is None):\n                status, ok = handler.initialize_service(\n                    project_root=params[\"project_root\"],\n                    config_path=params[\"config_path\"],\n                    device=params[\"device\"],\n                    use_flash_attention=params[\"use_flash_attention\"],\n                    compile_model=params[\"compile_model\"],\n                    offload_to_cpu=params[\"offload_to_cpu\"],\n                    offload_dit_to_cpu=params[\"offload_dit_to_cpu\"],\n                    quantization=params.get(\"quantization\"),\n                    prefer_source=params.get(\"prefer_source\"),\n                    use_mlx_dit=params.get(\"use_mlx_dit\", True),\n                )\n                if ok:\n                    reloaded.append(\"DiT/VAE/Text Encoder\")\n\n            if llm and not llm.llm_initialized:\n                llm_params = getattr(llm, \"last_init_params\", None)\n                if llm_params is None:\n                    project_root = get_project_root()\n                    checkpoint_dir = os.path.join(project_root, \"checkpoints\")\n                    lm_model_path = os.getenv(\"ACESTEP_LM_MODEL_PATH\", \"acestep-5Hz-lm-0.6B\").strip()\n                    backend = os.getenv(\"ACESTEP_LM_BACKEND\", \"vllm\").strip().lower()\n                    lm_device = os.getenv(\"ACESTEP_LM_DEVICE\", os.getenv(\"ACESTEP_DEVICE\", \"auto\"))\n                    lm_offload = env_bool(\"ACESTEP_LM_OFFLOAD_TO_CPU\", False)\n                    llm_params = {\n                        \"checkpoint_dir\": checkpoint_dir,\n                        \"lm_model_path\": lm_model_path,\n                        \"backend\": backend,\n                        \"device\": lm_device,\n                        \"offload_to_cpu\": lm_offload,\n                        \"dtype\": None,\n                    }\n\n                status, ok = llm.initialize(**llm_params)\n                if ok:\n                    reloaded.append(\"LLM\")\n                    try:\n                        app.state._llm_initialized = True\n                        app.state._llm_init_error = None\n                    except Exception:\n                        pass\n                else:\n                    try:\n                        app.state._llm_initialized = False\n                        app.state._llm_init_error = status\n                    except Exception:\n                        pass\n\n            if handler.model is not None:\n                if hasattr(handler.model, \"decoder\") and handler.model.decoder is not None:\n                    first_param = next(handler.model.decoder.parameters(), None)\n                    if first_param is not None and first_param.device.type == \"cpu\":\n                        handler.model.decoder = handler.model.decoder.to(handler.device).to(handler.dtype)\n                        reloaded.append(\"Decoder (moved to GPU)\")\n\n            gc.collect()\n            if torch.cuda.is_available():\n                torch.cuda.empty_cache()\n\n            message = \"\\u2705 Service reinitialized\"\n            if reloaded:\n                message += f\"\\n\\U0001f504 Reloaded: {', '.join(reloaded)}\"\n            return wrap_response({\"message\": message, \"reloaded\": reloaded})\n        except Exception as exc:\n            return wrap_response(None, code=500, error=f\"Reinitialization failed: {str(exc)}\")\n"
  },
  {
    "path": "acestep/api/http/reinitialize_route_http_test.py",
    "content": "\"\"\"HTTP integration tests for the /v1/reinitialize route.\"\"\"\n\nfrom pathlib import Path\nimport unittest\nfrom types import SimpleNamespace\nfrom unittest import mock\n\nfrom fastapi import FastAPI, Header, HTTPException\nfrom fastapi.testclient import TestClient\n\nfrom acestep.api.http.reinitialize_route import register_reinitialize_route\n\n_NON_EXISTENT_TEST_ROOT = str(Path.cwd() / \"non-existent-test-root\")\n\n\ndef _wrap_response(data, code=200, error=None):\n    \"\"\"Return an ``api_server``-compatible response envelope dict.\"\"\"\n\n    return {\"data\": data, \"code\": code, \"error\": error}\n\n\nasync def _verify_api_key(authorization: str | None = Header(None)) -> None:\n    \"\"\"Validate a fixed bearer token and return ``None`` on success.\"\"\"\n\n    if authorization != \"Bearer test-token\":\n        raise HTTPException(status_code=401, detail=\"Unauthorized\")\n\n\nclass ReinitializeRouteHttpTests(unittest.TestCase):\n    \"\"\"Integration tests for reinitialize route using real HTTP requests.\"\"\"\n\n    def _build_client(self, handler) -> TestClient:\n        \"\"\"Create a test app with route registration and return TestClient.\"\"\"\n\n        app = FastAPI()\n        app.state.handler = handler\n        app.state.llm_handler = SimpleNamespace(llm_initialized=True)\n        register_reinitialize_route(\n            app=app,\n            verify_api_key=_verify_api_key,\n            wrap_response=_wrap_response,\n            env_bool=lambda *_: False,\n            get_project_root=lambda: _NON_EXISTENT_TEST_ROOT,\n        )\n        return TestClient(app)\n\n    def test_missing_handler_returns_raw_http_500_contract(self):\n        \"\"\"POST /v1/reinitialize should preserve legacy raw HTTP 500 when handler is missing.\"\"\"\n\n        app = FastAPI()\n        app.state.handler = None\n        app.state.llm_handler = SimpleNamespace(llm_initialized=True)\n        register_reinitialize_route(\n            app=app,\n            verify_api_key=_verify_api_key,\n            wrap_response=_wrap_response,\n            env_bool=lambda *_: False,\n            get_project_root=lambda: _NON_EXISTENT_TEST_ROOT,\n        )\n        client = TestClient(app)\n        response = client.post(\"/v1/reinitialize\", headers={\"Authorization\": \"Bearer test-token\"})\n\n        self.assertEqual(500, response.status_code)\n        payload = response.json()\n        self.assertEqual(\"Service not initialized\", payload[\"detail\"])\n\n    def test_requires_authentication(self):\n        \"\"\"POST /v1/reinitialize without token should return HTTP 401.\"\"\"\n\n        handler = SimpleNamespace(model=object(), vae=object(), text_encoder=object(), last_init_params=None)\n        client = self._build_client(handler)\n        response = client.post(\"/v1/reinitialize\")\n        self.assertEqual(401, response.status_code)\n\n    def test_returns_wrapped_success_payload(self):\n        \"\"\"POST /v1/reinitialize should return wrapped success payload when initialized.\"\"\"\n\n        handler = SimpleNamespace(model=object(), vae=object(), text_encoder=object(), last_init_params=None)\n        client = self._build_client(handler)\n        with mock.patch(\"acestep.api.http.reinitialize_route.torch.cuda.is_available\", return_value=False):\n            response = client.post(\"/v1/reinitialize\", headers={\"Authorization\": \"Bearer test-token\"})\n\n        self.assertEqual(200, response.status_code)\n        payload = response.json()\n        self.assertEqual(200, payload[\"code\"])\n        self.assertIn(\"Service reinitialized\", payload[\"data\"][\"message\"])\n\n\nif __name__ == \"__main__\":\n    unittest.main()\n"
  },
  {
    "path": "acestep/api/http/reinitialize_route_test.py",
    "content": "\"\"\"Unit tests for reinitialize route registration.\"\"\"\n\nimport asyncio\nimport unittest\nfrom types import SimpleNamespace\nfrom unittest import mock\n\nfrom fastapi import FastAPI, HTTPException\nfrom fastapi.routing import APIRoute\n\nfrom acestep.api.http.reinitialize_route import register_reinitialize_route\n\n\ndef _wrap_response(data, code=200, error=None):\n    \"\"\"Return an ``api_server``-compatible response envelope dict.\"\"\"\n\n    return {\"data\": data, \"code\": code, \"error\": error}\n\n\nasync def _verify_api_key(_: str | None = None) -> None:\n    \"\"\"Return ``None`` as a no-op auth dependency for unit tests.\"\"\"\n\n    return None\n\n\ndef _get_endpoint(app: FastAPI, path: str, method: str):\n    \"\"\"Return the endpoint callable matching ``path`` and HTTP ``method``.\"\"\"\n\n    for route in app.routes:\n        if isinstance(route, APIRoute) and route.path == path and method.upper() in route.methods:\n            return route.endpoint\n    raise AssertionError(f\"Missing route: {method} {path}\")\n\n\nclass ReinitializeRouteUnitTests(unittest.TestCase):\n    \"\"\"Unit tests for reinitialize route behavior and error handling.\"\"\"\n\n    def test_raises_http_500_when_service_not_initialized(self):\n        \"\"\"Handler absence should return HTTP 500 via raised HTTPException.\"\"\"\n\n        app = FastAPI()\n        app.state.handler = None\n        app.state.llm_handler = None\n        app.state._llm_lazy_load_disabled = False\n        register_reinitialize_route(\n            app=app,\n            verify_api_key=_verify_api_key,\n            wrap_response=_wrap_response,\n            env_bool=lambda *_: False,\n            get_project_root=lambda: \"/tmp/non-existent\",\n        )\n        endpoint = _get_endpoint(app, \"/v1/reinitialize\", \"POST\")\n\n        with self.assertRaises(HTTPException) as ctx:\n            asyncio.run(endpoint(None))\n        self.assertEqual(500, ctx.exception.status_code)\n\n    def test_missing_llm_handler_returns_wrapped_success(self):\n        \"\"\"Missing llm_handler should still preserve legacy wrapped-success behavior.\"\"\"\n\n        app = FastAPI()\n        app.state.handler = SimpleNamespace(model=object(), vae=object(), text_encoder=object(), last_init_params=None)\n        app.state.llm_handler = None\n        app.state._llm_lazy_load_disabled = False\n        register_reinitialize_route(\n            app=app,\n            verify_api_key=_verify_api_key,\n            wrap_response=_wrap_response,\n            env_bool=lambda *_: False,\n            get_project_root=lambda: \"/tmp/non-existent\",\n        )\n        endpoint = _get_endpoint(app, \"/v1/reinitialize\", \"POST\")\n\n        with mock.patch(\"acestep.api.http.reinitialize_route.torch.cuda.is_available\", return_value=False):\n            result = asyncio.run(endpoint(None))\n\n        self.assertEqual(200, result[\"code\"])\n        self.assertIn(\"Service reinitialized\", result[\"data\"][\"message\"])\n\n    def test_returns_wrapped_success_when_no_reload_needed(self):\n        \"\"\"Initialized handler/LLM should return wrapped success without reload entries.\"\"\"\n\n        app = FastAPI()\n        app.state.handler = SimpleNamespace(\n            model=object(),\n            vae=object(),\n            text_encoder=object(),\n            last_init_params=None,\n        )\n        app.state.llm_handler = SimpleNamespace(llm_initialized=True)\n        app.state._llm_lazy_load_disabled = False\n        register_reinitialize_route(\n            app=app,\n            verify_api_key=_verify_api_key,\n            wrap_response=_wrap_response,\n            env_bool=lambda *_: False,\n            get_project_root=lambda: \"/tmp/non-existent\",\n        )\n        endpoint = _get_endpoint(app, \"/v1/reinitialize\", \"POST\")\n\n        with mock.patch(\"acestep.api.http.reinitialize_route.torch.cuda.is_available\", return_value=False):\n            result = asyncio.run(endpoint(None))\n\n        self.assertEqual(200, result[\"code\"])\n        self.assertIn(\"Service reinitialized\", result[\"data\"][\"message\"])\n\n    def test_handler_reload_failure_keeps_wrapped_success_contract(self):\n        \"\"\"Failed handler reload should not crash endpoint or change wrapper contract.\"\"\"\n\n        app = FastAPI()\n        app.state.handler = SimpleNamespace(\n            model=None,\n            vae=None,\n            text_encoder=None,\n            last_init_params={\n                \"project_root\": \".\",\n                \"config_path\": \"acestep-v15-base\",\n                \"device\": \"auto\",\n                \"use_flash_attention\": True,\n                \"compile_model\": False,\n                \"offload_to_cpu\": False,\n                \"offload_dit_to_cpu\": False,\n            },\n            initialize_service=lambda **_kwargs: (\"failed\", False),\n        )\n        app.state.llm_handler = SimpleNamespace(llm_initialized=True)\n        app.state._llm_lazy_load_disabled = False\n        register_reinitialize_route(\n            app=app,\n            verify_api_key=_verify_api_key,\n            wrap_response=_wrap_response,\n            env_bool=lambda *_: False,\n            get_project_root=lambda: \"/tmp/non-existent\",\n        )\n        endpoint = _get_endpoint(app, \"/v1/reinitialize\", \"POST\")\n\n        with mock.patch(\"acestep.api.http.reinitialize_route.torch.cuda.is_available\", return_value=False):\n            result = asyncio.run(endpoint(None))\n\n        self.assertEqual(200, result[\"code\"])\n        self.assertIn(\"Service reinitialized\", result[\"data\"][\"message\"])\n\n\nif __name__ == \"__main__\":\n    unittest.main()\n"
  },
  {
    "path": "acestep/api/http/release_task_audio_paths.py",
    "content": "\"\"\"Audio-path validation and upload persistence helpers for release-task flow.\"\"\"\n\nfrom __future__ import annotations\n\nimport os\nimport tempfile\nfrom pathlib import Path\nfrom typing import Optional\n\nfrom fastapi import HTTPException\nfrom starlette.datastructures import UploadFile as StarletteUploadFile\n\n\ndef validate_audio_path(path: Optional[str]) -> Optional[str]:\n    \"\"\"Validate user-supplied audio path and block unsafe filesystem traversal.\n\n    Args:\n        path: User-supplied path value from request payload.\n\n    Returns:\n        Normalized path string for accepted values, or ``None`` for empty input.\n\n    Raises:\n        HTTPException: If absolute paths outside temp or traversal markers are detected.\n    \"\"\"\n\n    if not path:\n        return None\n\n    system_temp = os.path.realpath(tempfile.gettempdir())\n    requested_path = os.path.realpath(path)\n    try:\n        is_in_temp = os.path.commonpath([system_temp, requested_path]) == system_temp\n    except ValueError:\n        is_in_temp = False\n\n    if is_in_temp:\n        return requested_path\n\n    if os.path.isabs(path):\n        raise HTTPException(status_code=400, detail=\"absolute audio file paths are not allowed\")\n\n    normalized = os.path.normpath(path)\n    if \"..\" in normalized.split(os.sep):\n        raise HTTPException(status_code=400, detail=\"path traversal in audio file paths is not allowed\")\n    return path\n\n\nasync def save_upload_to_temp(upload: StarletteUploadFile, *, prefix: str) -> str:\n    \"\"\"Persist uploaded audio file to a temporary location.\n\n    Args:\n        upload: Uploaded file wrapper from Starlette/FastAPI.\n        prefix: Filename prefix used for the temporary file.\n\n    Returns:\n        Path to the stored temporary file.\n\n    Raises:\n        Exception: Re-raises write errors after cleaning up partial files.\n    \"\"\"\n\n    suffix = Path(upload.filename or \"\").suffix\n    fd, path = tempfile.mkstemp(prefix=f\"{prefix}_\", suffix=suffix)\n    try:\n        try:\n            os.close(fd)\n        except OSError:\n            # fd is invalid or already closed — clean up the temp file\n            try:\n                os.remove(path)\n            except OSError:\n                pass\n            raise\n\n        with open(path, \"wb\") as file_obj:\n            while True:\n                chunk = await upload.read(1024 * 1024)\n                if not chunk:\n                    break\n                file_obj.write(chunk)\n    except Exception:\n        try:\n            os.remove(path)\n        except OSError:\n            pass\n        raise\n    finally:\n        try:\n            await upload.close()\n        except Exception:\n            pass\n    return path\n"
  },
  {
    "path": "acestep/api/http/release_task_audio_paths_test.py",
    "content": "\"\"\"Unit tests for audio path validation and temp upload persistence helpers.\"\"\"\n\nimport asyncio\nimport os\nimport tempfile\nimport unittest\nfrom unittest import mock\n\nfrom fastapi import HTTPException\n\nfrom acestep.api.http.release_task_audio_paths import save_upload_to_temp, validate_audio_path\n\n\nclass _FakeUpload:\n    \"\"\"Minimal async upload stub for exercising temp-file persistence behavior.\"\"\"\n\n    def __init__(self, payload: bytes, filename: str = \"clip.wav\") -> None:\n        \"\"\"Store upload payload bytes and filename metadata.\"\"\"\n\n        self._payload = payload\n        self._offset = 0\n        self.filename = filename\n        self.closed = False\n\n    async def read(self, size: int) -> bytes:\n        \"\"\"Return next payload chunk, emulating Starlette UploadFile reads.\"\"\"\n\n        if self._offset >= len(self._payload):\n            return b\"\"\n        end = min(self._offset + size, len(self._payload))\n        chunk = self._payload[self._offset:end]\n        self._offset = end\n        return chunk\n\n    async def close(self) -> None:\n        \"\"\"Mark fake upload as closed.\"\"\"\n\n        self.closed = True\n\n\nclass ReleaseTaskAudioPathsTests(unittest.TestCase):\n    \"\"\"Behavior tests for path-validation and upload-persistence helpers.\"\"\"\n\n    def test_validate_audio_path_rejects_absolute_non_temp_path(self):\n        \"\"\"Validator should reject absolute paths outside the system temp directory.\"\"\"\n\n        with self.assertRaises(HTTPException) as ctx:\n            validate_audio_path(os.path.abspath(os.path.join(os.getcwd(), \"outside.wav\")))\n        self.assertEqual(400, ctx.exception.status_code)\n        self.assertIn(\"absolute audio file paths are not allowed\", str(ctx.exception.detail))\n\n    def test_validate_audio_path_rejects_traversal_sequences(self):\n        \"\"\"Validator should reject relative paths containing traversal markers.\"\"\"\n\n        with self.assertRaises(HTTPException) as ctx:\n            validate_audio_path(\"../unsafe.wav\")\n        self.assertEqual(400, ctx.exception.status_code)\n        self.assertIn(\"path traversal\", str(ctx.exception.detail))\n\n    def test_save_upload_to_temp_cleans_up_on_fd_close_failure(self):\n        \"\"\"If os.close(fd) raises OSError, temp file should be removed and error re-raised.\"\"\"\n\n        leaked_path = os.path.join(tempfile.gettempdir(), \"leaked.wav\")\n        upload = _FakeUpload(payload=b\"data\", filename=\"clip.wav\")\n        with mock.patch(\n            \"acestep.api.http.release_task_audio_paths.tempfile.mkstemp\",\n            return_value=(99, leaked_path),\n        ), mock.patch(\n            \"acestep.api.http.release_task_audio_paths.os.close\",\n            side_effect=OSError(\"bad fd\"),\n        ), mock.patch(\n            \"acestep.api.http.release_task_audio_paths.os.remove\",\n        ) as remove_mock:\n            with self.assertRaises(OSError):\n                asyncio.run(save_upload_to_temp(upload, prefix=\"test\"))\n        # Inner except removes the temp file, outer except catches the re-raised\n        # OSError and attempts removal again — both calls target the same path.\n        remove_mock.assert_called_with(leaked_path)\n        self.assertEqual(remove_mock.call_count, 2)\n\n    def test_save_upload_to_temp_writes_file_and_closes_upload(self):\n        \"\"\"Uploader helper should stream bytes through mocked file writes and close upload.\"\"\"\n\n        upload = _FakeUpload(payload=b\"abc123\", filename=\"sample.wav\")\n        with mock.patch(\n            \"acestep.api.http.release_task_audio_paths.tempfile.mkstemp\",\n            return_value=(123, \"mock/path/sample.wav\"),\n        ), mock.patch(\"acestep.api.http.release_task_audio_paths.os.close\") as close_mock, mock.patch(\n            \"acestep.api.http.release_task_audio_paths.open\",\n            new_callable=mock.mock_open,\n        ) as open_mock:\n            saved_path = asyncio.run(save_upload_to_temp(upload, prefix=\"ref_audio\"))\n\n        self.assertEqual(\"mock/path/sample.wav\", saved_path)\n        close_mock.assert_called_once_with(123)\n        open_mock.assert_called_once_with(\"mock/path/sample.wav\", \"wb\")\n        open_mock().write.assert_called_once_with(b\"abc123\")\n        self.assertTrue(upload.closed)\n\n\nif __name__ == \"__main__\":\n    unittest.main()\n"
  },
  {
    "path": "acestep/api/http/release_task_models.py",
    "content": "\"\"\"Pydantic request model definitions used by the `/release_task` flow.\"\"\"\n\nfrom __future__ import annotations\n\nfrom typing import List, Literal, Optional, Union\n\nfrom pydantic import BaseModel, Field\n\nfrom acestep.constants import DEFAULT_DIT_INSTRUCTION\n\n\nclass GenerateMusicRequest(BaseModel):\n    \"\"\"Typed request payload model for generation jobs.\n\n    This schema mirrors the historical `api_server` request contract so legacy\n    clients remain compatible while route handling is decomposed.\n    \"\"\"\n\n    prompt: str = Field(default=\"\", description=\"Text prompt describing the music (local/per-track description for lego SFT)\")\n    global_caption: str = Field(default=\"\", description=\"Global song description for SFT-stems lego tasks (full song context)\")\n    lyrics: str = Field(default=\"\", description=\"Lyric text\")\n\n    # New API semantics:\n    # - thinking=True: use 5Hz LM to generate audio codes (lm-dit behavior)\n    # - thinking=False: do not use LM to generate codes (dit behavior)\n    # Regardless of thinking, if some metas are missing, server may use LM to fill them.\n    thinking: bool = False\n    # Sample-mode requests auto-generate caption/lyrics/metas via LM (no user prompt).\n    sample_mode: bool = False\n    # Description for sample mode: auto-generate caption/lyrics from description query\n    sample_query: str = Field(default=\"\", description=\"Query/description for sample mode (use create_sample)\")\n    # Whether to use format_sample() to enhance input caption/lyrics\n    use_format: bool = Field(default=False, description=\"Use format_sample() to enhance input (default: False)\")\n    # Model name for multi-model support (select which DiT model to use)\n    model: Optional[str] = Field(default=None, description=\"Model name to use (e.g., 'acestep-v15-turbo')\")\n\n    bpm: Optional[int] = None\n    key_scale: str = \"\"\n    time_signature: str = \"\"\n    vocal_language: str = \"en\"\n    inference_steps: int = 8\n    guidance_scale: float = 7.0\n    use_random_seed: bool = True\n    seed: Union[int, str] = -1\n\n    reference_audio_path: Optional[str] = None\n    src_audio_path: Optional[str] = None\n    audio_duration: Optional[float] = None\n    batch_size: Optional[int] = None\n\n    repainting_start: float = 0.0\n    repainting_end: Optional[float] = None\n\n    instruction: str = DEFAULT_DIT_INSTRUCTION\n    audio_cover_strength: float = 1.0\n    cover_noise_strength: float = Field(\n        default=0.0,\n        description=\"Cover noise blending strength (0.0=pure noise, 1.0=closest to source audio). Used for cover/repaint tasks.\",\n    )\n    audio_code_string: str = Field(\n        default=\"\",\n        description=\"User-provided audio semantic codes string for code-control generation. When non-empty, skips LM code generation.\",\n    )\n    task_type: str = \"text2music\"\n    chunk_mask_mode: Literal[\"explicit\", \"auto\"] = \"auto\"\n    repaint_latent_crossfade_frames: int = Field(\n        default=10,\n        description=\"Latent-level boundary blend width in frames (25Hz, 10~0.4s)\",\n    )\n    repaint_wav_crossfade_sec: float = Field(\n        default=0.0,\n        description=\"Waveform-level splice crossfade in seconds (0=hard cut)\",\n    )\n    repaint_mode: Literal[\"conservative\", \"balanced\", \"aggressive\"] = Field(\n        default=\"balanced\",\n        description=\"Repaint preservation mode: conservative (max src retention), balanced (tunable), aggressive (pure diffusion)\",\n    )\n    repaint_strength: float = Field(\n        default=0.5,\n        ge=0.0,\n        le=1.0,\n        description=\"Balanced-mode repaint intensity: 0.0=conservative (max source preservation), 1.0=aggressive (pure diffusion). Only used in balanced mode.\",\n    )\n    analysis_only: bool = False\n    full_analysis_only: bool = False\n    extract_codes_only: bool = False\n\n    use_adg: bool = False\n    cfg_interval_start: float = 0.0\n    cfg_interval_end: float = 1.0\n    infer_method: str = \"ode\"  # \"ode\" or \"sde\" - diffusion inference method\n    shift: float = Field(\n        default=3.0,\n        description=\"Timestep shift factor (range 1.0~5.0, default 3.0). Only effective for base models, not turbo models.\",\n    )\n    timesteps: Optional[str] = Field(\n        default=None,\n        description=\"Custom timesteps (comma-separated, e.g., '0.97,0.76,0.615,0.5,0.395,0.28,0.18,0.085,0'). Overrides inference_steps and shift.\",\n    )\n\n    audio_format: str = Field(\n        default=\"mp3\",\n        description=\"Output audio format. Supported formats: 'flac', 'mp3', 'opus', 'aac', 'wav', 'wav32'. Default: 'mp3'\",\n    )\n    use_tiled_decode: bool = True\n\n    # 5Hz LM (server-side): used for metadata completion and (when thinking=True) codes generation.\n    lm_model_path: Optional[str] = None  # e.g. \"acestep-5Hz-lm-0.6B\"\n    lm_backend: Literal[\"vllm\", \"pt\", \"mlx\"] = \"vllm\"\n\n    constrained_decoding: bool = True\n    constrained_decoding_debug: bool = False\n    use_cot_caption: bool = True\n    use_cot_language: bool = True\n    is_format_caption: bool = False\n    allow_lm_batch: bool = True\n    track_name: Optional[str] = None\n    track_classes: Optional[List[str]] = None\n\n    lm_temperature: float = 0.85\n    lm_cfg_scale: float = 2.5\n    lm_top_k: Optional[int] = None\n    lm_top_p: Optional[float] = 0.9\n    lm_repetition_penalty: float = 1.0\n    lm_negative_prompt: str = \"NO USER INPUT\"\n\n    class Config:\n        \"\"\"Legacy pydantic config preserving prior population semantics.\"\"\"\n\n        allow_population_by_field_name = True\n        allow_population_by_alias = True\n"
  },
  {
    "path": "acestep/api/http/release_task_models_test.py",
    "content": "\"\"\"Unit tests for release-task request model defaults and compatibility flags.\"\"\"\n\nimport unittest\n\nfrom acestep.api.http.release_task_models import GenerateMusicRequest\nfrom acestep.constants import DEFAULT_DIT_INSTRUCTION\n\n\nclass ReleaseTaskModelsTests(unittest.TestCase):\n    \"\"\"Behavior tests for release-task request model schema defaults.\"\"\"\n\n    def test_generate_music_request_preserves_legacy_defaults(self):\n        \"\"\"Model should expose same default values used by existing clients.\"\"\"\n\n        req = GenerateMusicRequest()\n        self.assertEqual(\"\", req.prompt)\n        self.assertEqual(\"text2music\", req.task_type)\n        self.assertEqual(\"mp3\", req.audio_format)\n        self.assertEqual(DEFAULT_DIT_INSTRUCTION, req.instruction)\n        self.assertTrue(req.use_random_seed)\n\n    def test_new_fields_have_expected_defaults(self):\n        \"\"\"New audio_code_string and cover_noise_strength should default to safe values.\"\"\"\n\n        req = GenerateMusicRequest()\n        self.assertEqual(\"\", req.audio_code_string)\n        self.assertAlmostEqual(0.0, req.cover_noise_strength)\n\n    def test_audio_code_string_and_cover_noise_strength_are_accepted(self):\n        \"\"\"Model should accept user-supplied audio_code_string and cover_noise_strength.\"\"\"\n\n        req = GenerateMusicRequest(audio_code_string=\"<|audio_code_1|>\", cover_noise_strength=0.75)\n        self.assertEqual(\"<|audio_code_1|>\", req.audio_code_string)\n        self.assertAlmostEqual(0.75, req.cover_noise_strength)\n\n\nif __name__ == \"__main__\":\n    unittest.main()\n"
  },
  {
    "path": "acestep/api/http/release_task_param_parser.py",
    "content": "\"\"\"Canonical parameter aliasing and parsing helpers for release-task requests.\"\"\"\n\nfrom __future__ import annotations\n\nimport json\nfrom typing import Any, Dict, Optional\n\n\nPARAM_ALIASES: Dict[str, list[str]] = {\n    \"prompt\": [\"prompt\", \"caption\"],\n    \"lyrics\": [\"lyrics\"],\n    \"thinking\": [\"thinking\"],\n    \"analysis_only\": [\"analysis_only\", \"analysisOnly\"],\n    \"full_analysis_only\": [\"full_analysis_only\", \"fullAnalysisOnly\"],\n    \"extract_codes_only\": [\"extract_codes_only\", \"extractCodesOnly\"],\n    \"sample_mode\": [\"sample_mode\", \"sampleMode\"],\n    \"sample_query\": [\"sample_query\", \"sampleQuery\", \"description\", \"desc\"],\n    \"use_format\": [\"use_format\", \"useFormat\", \"format\"],\n    \"model\": [\"model\", \"model_name\", \"modelName\", \"dit_model\", \"ditModel\"],\n    \"key_scale\": [\"key_scale\", \"keyscale\", \"keyScale\", \"key\"],\n    \"time_signature\": [\"time_signature\", \"timesignature\", \"timeSignature\"],\n    \"audio_duration\": [\"audio_duration\", \"duration\", \"audioDuration\", \"target_duration\", \"targetDuration\"],\n    \"vocal_language\": [\"vocal_language\", \"vocalLanguage\", \"language\"],\n    \"bpm\": [\"bpm\"],\n    \"inference_steps\": [\"inference_steps\", \"inferenceSteps\"],\n    \"guidance_scale\": [\"guidance_scale\", \"guidanceScale\"],\n    \"use_random_seed\": [\"use_random_seed\", \"useRandomSeed\"],\n    \"seed\": [\"seed\"],\n    \"audio_cover_strength\": [\"audio_cover_strength\", \"audioCoverStrength\", \"cover_strength\", \"coverStrength\"],\n    \"cover_noise_strength\": [\"cover_noise_strength\", \"coverNoiseStrength\"],\n    \"audio_code_string\": [\"audio_code_string\", \"audioCodeString\", \"audio_codes\"],\n    \"reference_audio_path\": [\"reference_audio_path\", \"ref_audio_path\", \"referenceAudioPath\", \"refAudioPath\"],\n    \"src_audio_path\": [\"src_audio_path\", \"ctx_audio_path\", \"sourceAudioPath\", \"srcAudioPath\", \"ctxAudioPath\"],\n    \"task_type\": [\"task_type\", \"taskType\"],\n    \"infer_method\": [\"infer_method\", \"inferMethod\"],\n    \"use_tiled_decode\": [\"use_tiled_decode\", \"useTiledDecode\"],\n    \"constrained_decoding\": [\"constrained_decoding\", \"constrainedDecoding\", \"constrained\"],\n    \"constrained_decoding_debug\": [\"constrained_decoding_debug\", \"constrainedDecodingDebug\"],\n    \"use_cot_caption\": [\"use_cot_caption\", \"cot_caption\", \"cot-caption\"],\n    \"use_cot_language\": [\"use_cot_language\", \"cot_language\", \"cot-language\"],\n    \"is_format_caption\": [\"is_format_caption\", \"isFormatCaption\"],\n    \"allow_lm_batch\": [\"allow_lm_batch\", \"allowLmBatch\", \"parallel_thinking\"],\n    \"track_name\": [\"track_name\", \"trackName\"],\n    \"track_classes\": [\"track_classes\", \"trackClasses\", \"instruments\"],\n}\n\n\ndef _to_int(value: Any, default: Optional[int] = None) -> Optional[int]:\n    \"\"\"Parse int-like values and return fallback on conversion failure.\"\"\"\n\n    if value is None:\n        return default\n    if isinstance(value, int):\n        return value\n    as_text = str(value).strip()\n    if as_text == \"\":\n        return default\n    try:\n        return int(as_text)\n    except Exception:\n        return default\n\n\ndef _to_float(value: Any, default: Optional[float] = None) -> Optional[float]:\n    \"\"\"Parse float-like values and return fallback on conversion failure.\"\"\"\n\n    if value is None:\n        return default\n    if isinstance(value, float):\n        return value\n    as_text = str(value).strip()\n    if as_text == \"\":\n        return default\n    try:\n        return float(as_text)\n    except Exception:\n        return default\n\n\ndef _to_bool(value: Any, default: bool = False) -> bool:\n    \"\"\"Parse boolean-like values from common textual representations.\"\"\"\n\n    if value is None:\n        return default\n    if isinstance(value, bool):\n        return value\n    as_text = str(value).strip().lower()\n    if as_text == \"\":\n        return default\n    return as_text in {\"1\", \"true\", \"yes\", \"y\", \"on\"}\n\n\nclass RequestParser:\n    \"\"\"Parse request parameters from multiple sources with alias support.\"\"\"\n\n    def __init__(self, raw: dict):\n        \"\"\"Initialize parser and precompute nested metadata sources.\n\n        Args:\n            raw: Flat request body/form dictionary from client.\n        \"\"\"\n\n        self._raw = dict(raw) if raw else {}\n        self._param_obj = self._parse_json(self._raw.get(\"param_obj\"))\n        self._metas = self._find_metas()\n\n    def _parse_json(self, value: Any) -> dict:\n        \"\"\"Parse dict-or-JSON-string values into dictionaries.\"\"\"\n\n        if isinstance(value, dict):\n            return value\n        if isinstance(value, str) and value.strip():\n            try:\n                parsed = json.loads(value)\n                if isinstance(parsed, dict):\n                    return parsed\n                return {}\n            except Exception:\n                pass\n        return {}\n\n    def _find_metas(self) -> dict:\n        \"\"\"Locate and parse first metadata field from known alias keys.\"\"\"\n\n        for key in (\"metas\", \"meta\", \"metadata\", \"user_metadata\", \"userMetadata\"):\n            raw_value = self._raw.get(key)\n            if raw_value:\n                return self._parse_json(raw_value)\n        return {}\n\n    def get(self, name: str, default: Any = None):\n        \"\"\"Get parameter by canonical name from all known request sources.\"\"\"\n\n        aliases = PARAM_ALIASES.get(name, [name])\n        for source in (self._raw, self._param_obj, self._metas):\n            for alias in aliases:\n                value = source.get(alias)\n                if value is not None:\n                    return value\n        return default\n\n    def str(self, name: str, default: str = \"\") -> str:\n        \"\"\"Get parameter as string with fallback default.\"\"\"\n\n        value = self.get(name)\n        return str(value) if value is not None else default\n\n    def int(self, name: str, default: Optional[int] = None) -> Optional[int]:\n        \"\"\"Get parameter as integer with fallback default.\"\"\"\n\n        return _to_int(self.get(name), default)\n\n    def float(self, name: str, default: Optional[float] = None) -> Optional[float]:\n        \"\"\"Get parameter as float with fallback default.\"\"\"\n\n        return _to_float(self.get(name), default)\n\n    def bool(self, name: str, default: bool = False) -> bool:\n        \"\"\"Get parameter as bool with fallback default.\"\"\"\n\n        return _to_bool(self.get(name), default)\n"
  },
  {
    "path": "acestep/api/http/release_task_param_parser_test.py",
    "content": "\"\"\"Unit tests for canonical request parameter parsing helpers.\"\"\"\n\nimport unittest\n\nfrom acestep.api.http.release_task_param_parser import RequestParser\n\n\nclass ReleaseTaskParamParserTests(unittest.TestCase):\n    \"\"\"Behavior tests for alias resolution and typed conversion in RequestParser.\"\"\"\n\n    def test_get_prefers_primary_raw_payload_values(self):\n        \"\"\"Parser should return raw-body values before nested param/meta objects.\"\"\"\n\n        parser = RequestParser(\n            {\n                \"caption\": \"raw-caption\",\n                \"param_obj\": {\"caption\": \"param-caption\"},\n                \"metas\": {\"caption\": \"meta-caption\"},\n            }\n        )\n        self.assertEqual(\"raw-caption\", parser.str(\"prompt\"))\n\n    def test_get_falls_back_to_param_obj_then_metas(self):\n        \"\"\"Parser should resolve aliases from param_obj and then metas when raw missing.\"\"\"\n\n        parser = RequestParser(\n            {\n                \"param_obj\": {\"keyScale\": \"C\"},\n                \"metas\": {\"timeSignature\": \"3/4\"},\n            }\n        )\n        self.assertEqual(\"C\", parser.str(\"key_scale\"))\n        self.assertEqual(\"3/4\", parser.str(\"time_signature\"))\n\n    def test_typed_accessors_apply_legacy_conversion_rules(self):\n        \"\"\"Parser typed methods should preserve prior bool/int/float coercion behavior.\"\"\"\n\n        parser = RequestParser({\"seed\": \"42\", \"guidanceScale\": \"7.25\", \"useRandomSeed\": \"yes\"})\n        self.assertEqual(42, parser.int(\"seed\"))\n        self.assertAlmostEqual(7.25, parser.float(\"guidance_scale\"))\n        self.assertTrue(parser.bool(\"use_random_seed\"))\n\n    def test_cover_noise_strength_and_audio_code_string_aliases_are_resolved(self):\n        \"\"\"Parser should resolve camelCase aliases for the new fields.\"\"\"\n\n        parser = RequestParser({\"coverNoiseStrength\": \"0.5\", \"audioCodeString\": \"<|code|>\"})\n        self.assertAlmostEqual(0.5, parser.float(\"cover_noise_strength\"))\n        self.assertEqual(\"<|code|>\", parser.str(\"audio_code_string\"))\n\n    def test_audio_codes_alias_resolves_to_audio_code_string(self):\n        \"\"\"Legacy `audio_codes` key should resolve via audio_code_string alias list.\"\"\"\n\n        parser = RequestParser({\"audio_codes\": \"<|audio_code_42|>\"})\n        self.assertEqual(\"<|audio_code_42|>\", parser.str(\"audio_code_string\"))\n\n    def test_non_dict_param_obj_json_is_ignored(self):\n        \"\"\"Parser should ignore parsed param_obj JSON values that are not dictionaries.\"\"\"\n\n        parser = RequestParser(\n            {\n                \"param_obj\": \"[\\\"not-a-dict\\\"]\",\n                \"metas\": {\"caption\": \"meta-caption\"},\n            }\n        )\n        self.assertEqual(\"meta-caption\", parser.str(\"prompt\"))\n\n\nif __name__ == \"__main__\":\n    unittest.main()\n"
  },
  {
    "path": "acestep/api/http/release_task_request_builder.py",
    "content": "\"\"\"Helpers for building release-task request models from parsed inputs.\"\"\"\n\nfrom __future__ import annotations\n\nfrom typing import Any, Optional\n\n\ndef build_generate_music_request(\n    parser: Any,\n    request_model_cls: Any,\n    default_dit_instruction: str,\n    lm_default_temperature: float,\n    lm_default_cfg_scale: float,\n    lm_default_top_p: float,\n    **overrides: Any,\n) -> Any:\n    \"\"\"Build request-model payload for ``/release_task``.\n\n    Args:\n        parser: Request parser exposing ``str``, ``bool``, ``int``, ``float``, and ``get``.\n        request_model_cls: Request model class (for example ``GenerateMusicRequest``).\n        default_dit_instruction: Default DiT instruction string.\n        lm_default_temperature: Default LM temperature value.\n        lm_default_cfg_scale: Default LM CFG scale value.\n        lm_default_top_p: Default LM top-p value.\n        **overrides: Optional explicit field overrides for parsed values.\n\n    Returns:\n        Instantiated request model object.\n    \"\"\"\n\n    reference_audio = overrides.pop(\"reference_audio_path\", None) or parser.str(\"reference_audio_path\") or None\n    src_audio = overrides.pop(\"src_audio_path\", None) or parser.str(\"src_audio_path\") or None\n\n    track_classes = parser.get(\"track_classes\")\n    if track_classes is not None and isinstance(track_classes, str):\n        track_classes = [track_classes]\n\n    payload = dict(\n        prompt=parser.str(\"prompt\"),\n        global_caption=parser.str(\"global_caption\"),\n        lyrics=parser.str(\"lyrics\"),\n        thinking=parser.bool(\"thinking\"),\n        analysis_only=parser.bool(\"analysis_only\"),\n        full_analysis_only=parser.bool(\"full_analysis_only\"),\n        extract_codes_only=parser.bool(\"extract_codes_only\"),\n        sample_mode=parser.bool(\"sample_mode\"),\n        sample_query=parser.str(\"sample_query\"),\n        use_format=parser.bool(\"use_format\"),\n        model=parser.str(\"model\") or None,\n        bpm=parser.int(\"bpm\"),\n        key_scale=parser.str(\"key_scale\"),\n        time_signature=parser.str(\"time_signature\"),\n        audio_duration=parser.float(\"audio_duration\"),\n        vocal_language=parser.str(\"vocal_language\", \"en\"),\n        inference_steps=parser.int(\"inference_steps\", 8),\n        guidance_scale=parser.float(\"guidance_scale\", 7.0),\n        use_random_seed=parser.bool(\"use_random_seed\", True),\n        seed=parser.get(\"seed\", -1),\n        batch_size=parser.int(\"batch_size\"),\n        repainting_start=parser.float(\"repainting_start\", 0.0),\n        repainting_end=parser.float(\"repainting_end\"),\n        instruction=parser.str(\"instruction\", default_dit_instruction),\n        audio_cover_strength=parser.float(\"audio_cover_strength\", 1.0),\n        cover_noise_strength=parser.float(\"cover_noise_strength\", 0.0),\n        audio_code_string=parser.str(\"audio_code_string\"),\n        reference_audio_path=reference_audio,\n        src_audio_path=src_audio,\n        task_type=parser.str(\"task_type\", \"text2music\"),\n        chunk_mask_mode=parser.str(\"chunk_mask_mode\", \"auto\"),\n        repaint_latent_crossfade_frames=parser.int(\n            \"repaint_latent_crossfade_frames\", 10,\n        ),\n        repaint_wav_crossfade_sec=parser.float(\n            \"repaint_wav_crossfade_sec\", 0.0,\n        ),\n        repaint_mode=parser.str(\"repaint_mode\", \"balanced\"),\n        repaint_strength=parser.float(\"repaint_strength\", 0.5),\n        use_adg=parser.bool(\"use_adg\"),\n        cfg_interval_start=parser.float(\"cfg_interval_start\", 0.0),\n        cfg_interval_end=parser.float(\"cfg_interval_end\", 1.0),\n        infer_method=parser.str(\"infer_method\", \"ode\"),\n        shift=parser.float(\"shift\", 3.0),\n        audio_format=parser.str(\"audio_format\", \"mp3\"),\n        use_tiled_decode=parser.bool(\"use_tiled_decode\", True),\n        lm_model_path=parser.str(\"lm_model_path\") or None,\n        lm_backend=parser.str(\"lm_backend\", \"vllm\"),\n        lm_temperature=parser.float(\"lm_temperature\", lm_default_temperature),\n        lm_cfg_scale=parser.float(\"lm_cfg_scale\", lm_default_cfg_scale),\n        lm_top_k=parser.int(\"lm_top_k\"),\n        lm_top_p=parser.float(\"lm_top_p\", lm_default_top_p),\n        lm_repetition_penalty=parser.float(\"lm_repetition_penalty\", 1.0),\n        lm_negative_prompt=parser.str(\"lm_negative_prompt\", \"NO USER INPUT\"),\n        constrained_decoding=parser.bool(\"constrained_decoding\", True),\n        constrained_decoding_debug=parser.bool(\"constrained_decoding_debug\"),\n        use_cot_caption=parser.bool(\"use_cot_caption\", True),\n        use_cot_language=parser.bool(\"use_cot_language\", True),\n        is_format_caption=parser.bool(\"is_format_caption\"),\n        allow_lm_batch=parser.bool(\"allow_lm_batch\", True),\n        track_name=parser.str(\"track_name\"),\n        track_classes=track_classes,\n    )\n    payload.update(overrides)\n    return request_model_cls(**payload)\n"
  },
  {
    "path": "acestep/api/http/release_task_request_builder_test.py",
    "content": "\"\"\"Unit tests for release-task request-model builder helpers.\"\"\"\n\nimport unittest\nfrom types import SimpleNamespace\n\nfrom acestep.api.http.release_task_request_builder import build_generate_music_request\n\n\nclass _FakeParser:\n    \"\"\"Minimal parser stub exposing typed accessors used by request builder.\"\"\"\n\n    def __init__(self, values: dict) -> None:\n        \"\"\"Store deterministic key/value pairs for parser methods.\"\"\"\n\n        self._values = values\n\n    def get(self, key: str):\n        \"\"\"Return raw value for ``key`` from parser payload.\"\"\"\n\n        return self._values.get(key)\n\n    def str(self, key: str, default: str = \"\") -> str:\n        \"\"\"Return string value for ``key`` with default fallback.\"\"\"\n\n        value = self._values.get(key, default)\n        return default if value is None else str(value)\n\n    def bool(self, key: str, default: bool = False) -> bool:\n        \"\"\"Return boolean value for ``key`` with default fallback.\"\"\"\n\n        value = self._values.get(key, default)\n        if isinstance(value, bool):\n            return value\n        return str(value).strip().lower() in {\"1\", \"true\", \"yes\", \"y\", \"on\"}\n\n    def int(self, key: str, default=None):\n        \"\"\"Return integer value for ``key`` with default fallback.\"\"\"\n\n        value = self._values.get(key, default)\n        return default if value is None else int(value)\n\n    def float(self, key: str, default=None):\n        \"\"\"Return float value for ``key`` with default fallback.\"\"\"\n\n        value = self._values.get(key, default)\n        return default if value is None else float(value)\n\n\nclass ReleaseTaskRequestBuilderTests(unittest.TestCase):\n    \"\"\"Behavior tests for request-building helper used by `/release_task`.\"\"\"\n\n    def test_build_request_converts_track_classes_string_to_list(self):\n        \"\"\"Builder should normalize single-string track class to one-item list.\"\"\"\n\n        parser = _FakeParser(\n            {\n                \"prompt\": \"hello\",\n                \"track_classes\": \"vocals\",\n                \"use_random_seed\": True,\n            }\n        )\n        request = build_generate_music_request(\n            parser=parser,\n            request_model_cls=lambda **kwargs: SimpleNamespace(**kwargs),\n            default_dit_instruction=\"default-instruction\",\n            lm_default_temperature=0.85,\n            lm_default_cfg_scale=2.5,\n            lm_default_top_p=0.9,\n        )\n\n        self.assertEqual(\"hello\", request.prompt)\n        self.assertEqual([\"vocals\"], request.track_classes)\n        self.assertEqual(\"default-instruction\", request.instruction)\n\n    def test_build_request_prefers_explicit_audio_path_overrides(self):\n        \"\"\"Builder should prioritize explicit path overrides over parser fields.\"\"\"\n\n        parser = _FakeParser(\n            {\n                \"reference_audio_path\": \"from-parser-ref.wav\",\n                \"src_audio_path\": \"from-parser-src.wav\",\n            }\n        )\n        request = build_generate_music_request(\n            parser=parser,\n            request_model_cls=lambda **kwargs: SimpleNamespace(**kwargs),\n            default_dit_instruction=\"default-instruction\",\n            lm_default_temperature=0.85,\n            lm_default_cfg_scale=2.5,\n            lm_default_top_p=0.9,\n            reference_audio_path=\"override-ref.wav\",\n            src_audio_path=\"override-src.wav\",\n        )\n\n        self.assertEqual(\"override-ref.wav\", request.reference_audio_path)\n        self.assertEqual(\"override-src.wav\", request.src_audio_path)\n\n    def test_build_request_allows_generic_overrides_without_kwarg_collision(self):\n        \"\"\"Builder should allow overrides for any field without duplicate-kwarg errors.\"\"\"\n\n        parser = _FakeParser({\"prompt\": \"from-parser\", \"lyrics\": \"from-parser\"})\n        request = build_generate_music_request(\n            parser=parser,\n            request_model_cls=lambda **kwargs: SimpleNamespace(**kwargs),\n            default_dit_instruction=\"default-instruction\",\n            lm_default_temperature=0.85,\n            lm_default_cfg_scale=2.5,\n            lm_default_top_p=0.9,\n            prompt=\"from-override\",\n            lyrics=\"override-lyrics\",\n        )\n\n        self.assertEqual(\"from-override\", request.prompt)\n        self.assertEqual(\"override-lyrics\", request.lyrics)\n\n    def test_build_request_forwards_audio_code_string_and_cover_noise_strength(self):\n        \"\"\"Builder should include audio_code_string and cover_noise_strength in payload.\"\"\"\n\n        parser = _FakeParser(\n            {\n                \"audio_code_string\": \"<|audio_code_7|>\",\n                \"cover_noise_strength\": 0.6,\n            }\n        )\n        request = build_generate_music_request(\n            parser=parser,\n            request_model_cls=lambda **kwargs: SimpleNamespace(**kwargs),\n            default_dit_instruction=\"default-instruction\",\n            lm_default_temperature=0.85,\n            lm_default_cfg_scale=2.5,\n            lm_default_top_p=0.9,\n        )\n\n        self.assertEqual(\"<|audio_code_7|>\", request.audio_code_string)\n        self.assertAlmostEqual(0.6, request.cover_noise_strength)\n\n\nif __name__ == \"__main__\":\n    unittest.main()\n"
  },
  {
    "path": "acestep/api/http/release_task_request_parser.py",
    "content": "\"\"\"Request parsing helpers for the ``/release_task`` HTTP route.\"\"\"\n\nfrom __future__ import annotations\n\nimport json\nimport os\nimport urllib.parse\nfrom typing import Any, Callable, Dict, Optional, Tuple\n\nfrom fastapi import HTTPException, Request\n\nfrom acestep.api.http.release_task_request_builder import build_generate_music_request\n\n\ndef _extract_non_file_form_values(form: Any) -> Dict[str, Any]:\n    \"\"\"Extract scalar/list form values while filtering file objects.\n\n    Args:\n        form: Starlette multipart form object.\n\n    Returns:\n        Dictionary of non-file form values preserving single vs multi-value shape.\n    \"\"\"\n\n    values: Dict[str, Any] = {}\n    for key in form.keys():\n        non_files = [value for value in form.getlist(key) if not hasattr(value, \"read\")]\n        if len(non_files) == 1:\n            values[key] = non_files[0]\n        elif len(non_files) > 1:\n            values[key] = non_files\n    return values\n\n\nasync def parse_release_task_request(\n    request: Request,\n    authorization: Optional[str],\n    verify_token_from_request: Callable[[dict, Optional[str]], Optional[str]],\n    request_parser_cls: Any,\n    request_model_cls: Any,\n    validate_audio_path: Callable[[Optional[str]], Optional[str]],\n    save_upload_to_temp: Callable[..., Any],\n    upload_file_type: type,\n    default_dit_instruction: str,\n    lm_default_temperature: float,\n    lm_default_cfg_scale: float,\n    lm_default_top_p: float,\n) -> Tuple[Any, list[str]]:\n    \"\"\"Parse ``/release_task`` request body into request model and temp-file list.\n\n    Args:\n        request: FastAPI request carrying body/form data.\n        authorization: Optional Authorization header value.\n        verify_token_from_request: Legacy token validator.\n        request_parser_cls: Parser class for request dictionaries.\n        request_model_cls: Request model class (for example ``GenerateMusicRequest``).\n        validate_audio_path: Validator for manual audio-path fields.\n        save_upload_to_temp: Helper for persisting uploaded files to temp paths.\n        upload_file_type: Upload class used for multipart file detection.\n        default_dit_instruction: Default DiT instruction string.\n        lm_default_temperature: Default LM temperature value.\n        lm_default_cfg_scale: Default LM CFG scale value.\n        lm_default_top_p: Default LM top-p value.\n\n    Returns:\n        Tuple of ``(request_model, temp_files)``.\n\n    Raises:\n        HTTPException: When content type is unsupported or body parsing fails.\n    \"\"\"\n\n    content_type = (request.headers.get(\"content-type\") or \"\").lower()\n    temp_files: list[str] = []\n\n    def _build(parser: Any, **overrides: Any) -> Any:\n        \"\"\"Build request model from parsed values and explicit overrides.\"\"\"\n\n        return build_generate_music_request(\n            parser=parser,\n            request_model_cls=request_model_cls,\n            default_dit_instruction=default_dit_instruction,\n            lm_default_temperature=lm_default_temperature,\n            lm_default_cfg_scale=lm_default_cfg_scale,\n            lm_default_top_p=lm_default_top_p,\n            **overrides,\n        )\n\n    if content_type.startswith(\"application/json\") or content_type.endswith(\"+json\"):\n        try:\n            body = await request.json()\n        except (json.JSONDecodeError, ValueError):\n            raise HTTPException(status_code=400, detail=\"Malformed JSON payload\")\n        if not isinstance(body, dict):\n            raise HTTPException(status_code=400, detail=\"JSON payload must be an object\")\n        verify_token_from_request(body, authorization)\n        parser = request_parser_cls(body)\n        req = _build(\n            parser,\n            reference_audio_path=validate_audio_path(parser.str(\"reference_audio_path\") or None),\n            src_audio_path=validate_audio_path(parser.str(\"src_audio_path\") or None),\n        )\n        return req, temp_files\n\n    if content_type.startswith(\"multipart/form-data\"):\n        try:\n            form = await request.form()\n            form_values = _extract_non_file_form_values(form)\n            verify_token_from_request(form_values, authorization)\n\n            ref_upload = form.get(\"ref_audio\") or form.get(\"reference_audio\")\n            ctx_upload = form.get(\"ctx_audio\") or form.get(\"src_audio\")\n            if isinstance(ref_upload, upload_file_type):\n                reference_audio_path = await save_upload_to_temp(ref_upload, prefix=\"ref_audio\")\n                temp_files.append(reference_audio_path)\n            else:\n                reference_audio_path = validate_audio_path(\n                    str(form.get(\"ref_audio_path\") or form.get(\"reference_audio_path\") or \"\").strip() or None\n                )\n\n            if isinstance(ctx_upload, upload_file_type):\n                src_audio_path = await save_upload_to_temp(ctx_upload, prefix=\"ctx_audio\")\n                temp_files.append(src_audio_path)\n            else:\n                src_audio_path = validate_audio_path(\n                    str(form.get(\"ctx_audio_path\") or form.get(\"src_audio_path\") or \"\").strip() or None\n                )\n\n            req = _build(\n                request_parser_cls(dict(form_values)),\n                reference_audio_path=reference_audio_path,\n                src_audio_path=src_audio_path,\n            )\n            return req, temp_files\n        except Exception:\n            for temp_file in temp_files:\n                try:\n                    os.remove(temp_file)\n                except Exception:\n                    pass\n            raise\n\n    if content_type.startswith(\"application/x-www-form-urlencoded\"):\n        form = await request.form()\n        form_dict = dict(form)\n        verify_token_from_request(form_dict, authorization)\n        reference_audio_path = validate_audio_path(\n            str(form.get(\"ref_audio_path\") or form.get(\"reference_audio_path\") or \"\").strip() or None\n        )\n        src_audio_path = validate_audio_path(\n            str(form.get(\"ctx_audio_path\") or form.get(\"src_audio_path\") or \"\").strip() or None\n        )\n        req = _build(\n            request_parser_cls(form_dict),\n            reference_audio_path=reference_audio_path,\n            src_audio_path=src_audio_path,\n        )\n        return req, temp_files\n\n    raw = await request.body()\n    raw_stripped = raw.lstrip()\n    if raw_stripped.startswith(b\"{\") or raw_stripped.startswith(b\"[\"):\n        try:\n            body = json.loads(raw.decode(\"utf-8\"))\n            if not isinstance(body, dict):\n                raise HTTPException(status_code=400, detail=\"JSON payload must be an object\")\n            verify_token_from_request(body, authorization)\n            parser = request_parser_cls(body)\n            req = _build(\n                parser,\n                reference_audio_path=validate_audio_path(parser.str(\"reference_audio_path\") or None),\n                src_audio_path=validate_audio_path(parser.str(\"src_audio_path\") or None),\n            )\n            return req, temp_files\n        except HTTPException:\n            raise\n        except Exception:\n            raise HTTPException(\n                status_code=400,\n                detail=\"Invalid JSON body (hint: set 'Content-Type: application/json')\",\n            )\n\n    if raw_stripped and b\"=\" in raw:\n        parsed = urllib.parse.parse_qs(raw.decode(\"utf-8\"), keep_blank_values=True)\n        flat = {key: (value[0] if isinstance(value, list) and value else value) for key, value in parsed.items()}\n        verify_token_from_request(flat, authorization)\n        reference_audio_path = validate_audio_path(\n            str(flat.get(\"ref_audio_path\") or flat.get(\"reference_audio_path\") or \"\").strip() or None\n        )\n        src_audio_path = validate_audio_path(\n            str(flat.get(\"ctx_audio_path\") or flat.get(\"src_audio_path\") or \"\").strip() or None\n        )\n        req = _build(\n            request_parser_cls(flat),\n            reference_audio_path=reference_audio_path,\n            src_audio_path=src_audio_path,\n        )\n        return req, temp_files\n\n    raise HTTPException(\n        status_code=415,\n        detail=(\n            f\"Unsupported Content-Type: {content_type or '(missing)'}; \"\n            \"use application/json, application/x-www-form-urlencoded, or multipart/form-data\"\n        ),\n    )\n"
  },
  {
    "path": "acestep/api/http/release_task_request_parser_test.py",
    "content": "\"\"\"Unit tests for release-task request parsing helper.\"\"\"\n\nimport asyncio\nimport json\nimport unittest\nfrom types import SimpleNamespace\nfrom unittest import mock\n\nfrom fastapi import HTTPException\n\nfrom acestep.api.http.release_task_request_parser import parse_release_task_request\n\n\nclass _FakeParser:\n    \"\"\"Minimal parser stub exposing typed accessors used by parser helper.\"\"\"\n\n    def __init__(self, values: dict) -> None:\n        \"\"\"Store deterministic key/value pairs for parser methods.\"\"\"\n\n        self._values = values\n\n    def get(self, key: str):\n        \"\"\"Return raw value for ``key`` from parser payload.\"\"\"\n\n        return self._values.get(key)\n\n    def str(self, key: str, default: str = \"\") -> str:\n        \"\"\"Return string value for ``key`` with default fallback.\"\"\"\n\n        value = self._values.get(key, default)\n        return default if value is None else str(value)\n\n    def bool(self, key: str, default: bool = False) -> bool:\n        \"\"\"Return boolean value for ``key`` with default fallback.\"\"\"\n\n        value = self._values.get(key, default)\n        if isinstance(value, bool):\n            return value\n        return str(value).strip().lower() in {\"1\", \"true\", \"yes\", \"y\", \"on\"}\n\n    def int(self, key: str, default=None):\n        \"\"\"Return integer value for ``key`` with default fallback.\"\"\"\n\n        value = self._values.get(key, default)\n        return default if value is None else int(value)\n\n    def float(self, key: str, default=None):\n        \"\"\"Return float value for ``key`` with default fallback.\"\"\"\n\n        value = self._values.get(key, default)\n        return default if value is None else float(value)\n\n\nclass _FakeRequest:\n    \"\"\"Minimal request stub supporting async json/form/body accessors.\"\"\"\n\n    def __init__(\n        self,\n        content_type: str,\n        *,\n        json_data=None,\n        json_error: Exception | None = None,\n        form_data=None,\n        raw_body: bytes = b\"\",\n    ) -> None:\n        \"\"\"Initialize request payloads for targeted parser-path tests.\"\"\"\n\n        self.headers = {\"content-type\": content_type}\n        self._json_data = json_data\n        self._json_error = json_error\n        self._form_data = form_data\n        self._raw_body = raw_body\n\n    async def json(self):\n        \"\"\"Return deterministic JSON payload for this test request.\"\"\"\n\n        if self._json_error is not None:\n            raise self._json_error\n        return self._json_data\n\n    async def form(self):\n        \"\"\"Return deterministic form payload for this test request.\"\"\"\n\n        return self._form_data\n\n    async def body(self):\n        \"\"\"Return deterministic raw request bytes for this test request.\"\"\"\n\n        return self._raw_body\n\n\nclass ReleaseTaskRequestParserTests(unittest.TestCase):\n    \"\"\"Behavior tests for low-level parsing helper used by `/release_task`.\"\"\"\n\n    def test_json_payload_must_be_object(self):\n        \"\"\"Parser should reject JSON payloads that are not objects.\"\"\"\n\n        request = _FakeRequest(\"application/json\", json_data=[\"not-object\"])\n\n        with self.assertRaises(HTTPException) as ctx:\n            asyncio.run(\n                parse_release_task_request(\n                    request=request,\n                    authorization=None,\n                    verify_token_from_request=lambda *_: None,\n                    request_parser_cls=_FakeParser,\n                    request_model_cls=lambda **kwargs: SimpleNamespace(**kwargs),\n                    validate_audio_path=lambda path: path,\n                    save_upload_to_temp=lambda *_args, **_kwargs: \"\",\n                    upload_file_type=type(\"Upload\", (), {}),\n                    default_dit_instruction=\"instruction\",\n                    lm_default_temperature=0.85,\n                    lm_default_cfg_scale=2.5,\n                    lm_default_top_p=0.9,\n                )\n            )\n\n        self.assertEqual(400, ctx.exception.status_code)\n        self.assertIn(\"JSON payload must be an object\", str(ctx.exception.detail))\n\n    def test_missing_content_type_with_urlencoded_body_is_supported(self):\n        \"\"\"Parser should support key/value raw bodies when content-type is missing.\"\"\"\n\n        request = _FakeRequest(\n            \"\",\n            raw_body=b\"ai_token=test-token&prompt=hello&reference_audio_path=ref.wav\",\n        )\n        called = {\"verified\": False}\n\n        def _verify_token(payload, _authorization):\n            \"\"\"Record auth verification and assert parsed body contains token.\"\"\"\n\n            called[\"verified\"] = True\n            self.assertEqual(\"test-token\", payload.get(\"ai_token\"))\n\n        req, temp_files = asyncio.run(\n            parse_release_task_request(\n                request=request,\n                authorization=None,\n                verify_token_from_request=_verify_token,\n                request_parser_cls=_FakeParser,\n                request_model_cls=lambda **kwargs: SimpleNamespace(**kwargs),\n                validate_audio_path=lambda path: path,\n                save_upload_to_temp=lambda *_args, **_kwargs: \"\",\n                upload_file_type=type(\"Upload\", (), {}),\n                default_dit_instruction=\"instruction\",\n                lm_default_temperature=0.85,\n                lm_default_cfg_scale=2.5,\n                lm_default_top_p=0.9,\n            )\n        )\n\n        self.assertTrue(called[\"verified\"])\n        self.assertEqual(\"hello\", req.prompt)\n        self.assertEqual(\"ref.wav\", req.reference_audio_path)\n        self.assertEqual([], temp_files)\n\n    def test_application_json_malformed_payload_returns_400(self):\n        \"\"\"Parser should return HTTP 400 when JSON body parsing fails.\"\"\"\n\n        request = _FakeRequest(\n            \"application/json\",\n            json_error=json.JSONDecodeError(\"Expecting value\", \"x\", 0),\n        )\n\n        with self.assertRaises(HTTPException) as ctx:\n            asyncio.run(\n                parse_release_task_request(\n                    request=request,\n                    authorization=None,\n                    verify_token_from_request=lambda *_: None,\n                    request_parser_cls=_FakeParser,\n                    request_model_cls=lambda **kwargs: SimpleNamespace(**kwargs),\n                    validate_audio_path=lambda path: path,\n                    save_upload_to_temp=lambda *_args, **_kwargs: \"\",\n                    upload_file_type=type(\"Upload\", (), {}),\n                    default_dit_instruction=\"instruction\",\n                    lm_default_temperature=0.85,\n                    lm_default_cfg_scale=2.5,\n                    lm_default_top_p=0.9,\n                )\n            )\n\n        self.assertEqual(400, ctx.exception.status_code)\n        self.assertEqual(\"Malformed JSON payload\", ctx.exception.detail)\n\n    def test_multipart_cleanup_removes_uploaded_temp_files_on_error(self):\n        \"\"\"Parser should remove uploaded temp files when multipart parsing fails.\"\"\"\n\n        class _Upload:\n            \"\"\"Minimal upload marker type for multipart form branch.\"\"\"\n\n            def read(self):\n                \"\"\"Expose read attribute for file-like filtering.\"\"\"\n\n                return b\"\"\n\n        class _FakeForm:\n            \"\"\"Minimal multipart form object with key/get/getlist semantics.\"\"\"\n\n            def __init__(self) -> None:\n                \"\"\"Store deterministic multipart values for this test.\"\"\"\n\n                self._values = {\n                    \"ai_token\": \"test-token\",\n                    \"ref_audio\": _Upload(),\n                    \"ctx_audio_path\": \"bad-path\",\n                }\n\n            def keys(self):\n                \"\"\"Return iterable form keys.\"\"\"\n\n                return self._values.keys()\n\n            def getlist(self, key: str):\n                \"\"\"Return list-shaped values for the requested key.\"\"\"\n\n                value = self._values.get(key)\n                if value is None:\n                    return []\n                return value if isinstance(value, list) else [value]\n\n            def get(self, key: str):\n                \"\"\"Return scalar value for the requested key.\"\"\"\n\n                return self._values.get(key)\n\n        async def _save_upload_to_temp(_upload, *, prefix: str) -> str:\n            \"\"\"Return deterministic temp file path for uploaded payload.\"\"\"\n\n            return f\"/tmp/{prefix}_123.wav\"\n\n        def _validate_audio_path(path: str | None) -> str | None:\n            \"\"\"Raise on the sentinel bad path to force cleanup flow.\"\"\"\n\n            if path == \"bad-path\":\n                raise HTTPException(status_code=400, detail=\"bad path\")\n            return path\n\n        request = _FakeRequest(\"multipart/form-data; boundary=x\", form_data=_FakeForm())\n\n        with mock.patch(\"acestep.api.http.release_task_request_parser.os.remove\") as remove_mock:\n            with self.assertRaises(HTTPException) as ctx:\n                asyncio.run(\n                    parse_release_task_request(\n                        request=request,\n                        authorization=None,\n                        verify_token_from_request=lambda *_: None,\n                        request_parser_cls=_FakeParser,\n                        request_model_cls=lambda **kwargs: SimpleNamespace(**kwargs),\n                        validate_audio_path=_validate_audio_path,\n                        save_upload_to_temp=_save_upload_to_temp,\n                        upload_file_type=_Upload,\n                        default_dit_instruction=\"instruction\",\n                        lm_default_temperature=0.85,\n                        lm_default_cfg_scale=2.5,\n                        lm_default_top_p=0.9,\n                    )\n                )\n\n        self.assertEqual(400, ctx.exception.status_code)\n        remove_mock.assert_called_once_with(\"/tmp/ref_audio_123.wav\")\n\n\nif __name__ == \"__main__\":\n    unittest.main()\n"
  },
  {
    "path": "acestep/api/http/release_task_route.py",
    "content": "\"\"\"HTTP route registration for ``/release_task`` task-submission endpoint.\"\"\"\n\nfrom __future__ import annotations\n\nimport asyncio\nimport os\nfrom typing import Any, Callable, Dict, Optional\n\nfrom fastapi import FastAPI, Header, HTTPException, Request\n\nfrom acestep.api.http.release_task_request_parser import parse_release_task_request\n\n\ndef register_release_task_route(\n    app: FastAPI,\n    verify_token_from_request: Callable[[dict, Optional[str]], Optional[str]],\n    wrap_response: Callable[..., Dict[str, Any]],\n    store: Any,\n    request_parser_cls: Any,\n    request_model_cls: Any,\n    validate_audio_path: Callable[[Optional[str]], Optional[str]],\n    save_upload_to_temp: Callable[..., Any],\n    upload_file_type: type,\n    default_dit_instruction: str,\n    lm_default_temperature: float,\n    lm_default_cfg_scale: float,\n    lm_default_top_p: float,\n) -> None:\n    \"\"\"Register the legacy-compatible ``/release_task`` route.\n\n    Args:\n        app: FastAPI app instance.\n        verify_token_from_request: Legacy token validator.\n        wrap_response: API response wrapper helper.\n        store: Job store exposing ``create()``.\n        request_parser_cls: Request parser class for body dictionaries.\n        request_model_cls: Request model class (for example ``GenerateMusicRequest``).\n        validate_audio_path: Validator for manual audio-path fields.\n        save_upload_to_temp: Helper for persisting uploaded files to temp paths.\n        upload_file_type: Upload class used for multipart file detection.\n        default_dit_instruction: Default DiT instruction string.\n        lm_default_temperature: Default LM temperature value.\n        lm_default_cfg_scale: Default LM CFG scale value.\n        lm_default_top_p: Default LM top-p value.\n    \"\"\"\n\n    @app.post(\"/release_task\")\n    async def create_music_generate_job(request: Request, authorization: Optional[str] = Header(None)):\n        \"\"\"Create a queued generation job from supported content types.\"\"\"\n\n        req, temp_files = await parse_release_task_request(\n            request=request,\n            authorization=authorization,\n            verify_token_from_request=verify_token_from_request,\n            request_parser_cls=request_parser_cls,\n            request_model_cls=request_model_cls,\n            validate_audio_path=validate_audio_path,\n            save_upload_to_temp=save_upload_to_temp,\n            upload_file_type=upload_file_type,\n            default_dit_instruction=default_dit_instruction,\n            lm_default_temperature=lm_default_temperature,\n            lm_default_cfg_scale=lm_default_cfg_scale,\n            lm_default_top_p=lm_default_top_p,\n        )\n\n        record = store.create()\n        queue_ref: asyncio.Queue = app.state.job_queue\n        if queue_ref.full():\n            for temp_path in temp_files:\n                try:\n                    os.remove(temp_path)\n                except Exception:\n                    pass\n            raise HTTPException(status_code=429, detail=\"Server busy: queue is full\")\n\n        if temp_files:\n            async with app.state.job_temp_files_lock:\n                app.state.job_temp_files[record.job_id] = temp_files\n\n        async with app.state.pending_lock:\n            app.state.pending_ids.append(record.job_id)\n            position = len(app.state.pending_ids)\n\n        await queue_ref.put((record.job_id, req))\n        return wrap_response({\"task_id\": record.job_id, \"status\": \"queued\", \"queue_position\": position})\n"
  },
  {
    "path": "acestep/api/http/release_task_route_http_test.py",
    "content": "\"\"\"HTTP integration tests for release-task route registration.\"\"\"\n\nimport asyncio\nimport time\nimport unittest\nfrom types import SimpleNamespace\n\nfrom fastapi import FastAPI, HTTPException\nfrom fastapi.testclient import TestClient\n\nfrom acestep.api.http.release_task_route import register_release_task_route\n\n\nclass _FakeParser:\n    \"\"\"Minimal parser stub exposing typed accessors used by route dependencies.\"\"\"\n\n    def __init__(self, values: dict) -> None:\n        \"\"\"Store deterministic key/value pairs for parser methods.\"\"\"\n\n        self._values = values\n\n    def get(self, key: str):\n        \"\"\"Return raw value for ``key`` from parser payload.\"\"\"\n\n        return self._values.get(key)\n\n    def str(self, key: str, default: str = \"\") -> str:\n        \"\"\"Return string value for ``key`` with default fallback.\"\"\"\n\n        value = self._values.get(key, default)\n        return default if value is None else str(value)\n\n    def bool(self, key: str, default: bool = False) -> bool:\n        \"\"\"Return boolean value for ``key`` with default fallback.\"\"\"\n\n        value = self._values.get(key, default)\n        if isinstance(value, bool):\n            return value\n        return str(value).strip().lower() in {\"1\", \"true\", \"yes\", \"y\", \"on\"}\n\n    def int(self, key: str, default=None):\n        \"\"\"Return integer value for ``key`` with default fallback.\"\"\"\n\n        value = self._values.get(key, default)\n        return default if value is None else int(value)\n\n    def float(self, key: str, default=None):\n        \"\"\"Return float value for ``key`` with default fallback.\"\"\"\n\n        value = self._values.get(key, default)\n        return default if value is None else float(value)\n\n\nclass _FakeStore:\n    \"\"\"Minimal job-store fake returning deterministic job IDs.\"\"\"\n\n    def __init__(self) -> None:\n        \"\"\"Initialize deterministic record counter.\"\"\"\n\n        self._counter = 0\n\n    def create(self):\n        \"\"\"Return next deterministic record with ``job_id`` attribute.\"\"\"\n\n        self._counter += 1\n        return SimpleNamespace(job_id=f\"job-{self._counter}\")\n\n\nclass ReleaseTaskRouteHttpTests(unittest.TestCase):\n    \"\"\"Integration tests covering real HTTP calls for `/release_task`.\"\"\"\n\n    def _build_client(self, queue_maxsize: int = 8) -> TestClient:\n        \"\"\"Build app and register release-task route with deterministic fakes.\"\"\"\n\n        app = FastAPI()\n        app.state.job_queue = asyncio.Queue(maxsize=queue_maxsize)\n        app.state.job_temp_files = {}\n        app.state.pending_ids = []\n        app.state.job_temp_files_lock = asyncio.Lock()\n        app.state.pending_lock = asyncio.Lock()\n        store = _FakeStore()\n\n        def _verify_token_from_request(body: dict, authorization: str | None = None) -> None:\n            \"\"\"Require fixed token either in body or Authorization header.\"\"\"\n\n            if (body or {}).get(\"ai_token\") == \"test-token\":\n                return\n            if authorization == \"Bearer test-token\":\n                return\n            raise HTTPException(status_code=401, detail=\"Unauthorized\")\n\n        def _wrap_response(data, code=200, error=None):\n            \"\"\"Return an ``api_server``-compatible response envelope dict.\"\"\"\n\n            return {\n                \"data\": data,\n                \"code\": code,\n                \"error\": error,\n                \"timestamp\": int(time.time() * 1000),\n                \"extra\": None,\n            }\n\n        register_release_task_route(\n            app=app,\n            verify_token_from_request=_verify_token_from_request,\n            wrap_response=_wrap_response,\n            store=store,\n            request_parser_cls=_FakeParser,\n            request_model_cls=lambda **kwargs: SimpleNamespace(**kwargs),\n            validate_audio_path=lambda path: path,\n            save_upload_to_temp=lambda *_args, **_kwargs: \"\",\n            upload_file_type=type(\"Upload\", (), {}),\n            default_dit_instruction=\"default-instruction\",\n            lm_default_temperature=0.85,\n            lm_default_cfg_scale=2.5,\n            lm_default_top_p=0.9,\n        )\n        return TestClient(app)\n\n    def test_release_task_requires_auth(self):\n        \"\"\"POST /release_task should return HTTP 401 when auth token is missing.\"\"\"\n\n        client = self._build_client()\n        response = client.post(\"/release_task\", json={\"prompt\": \"hello\"})\n        self.assertEqual(401, response.status_code)\n\n    def test_release_task_returns_wrapped_queue_response(self):\n        \"\"\"POST /release_task should enqueue job and return wrapped queued payload.\"\"\"\n\n        client = self._build_client()\n        response = client.post(\"/release_task\", json={\"ai_token\": \"test-token\", \"prompt\": \"hello\"})\n\n        self.assertEqual(200, response.status_code)\n        payload = response.json()\n        self.assertEqual(200, payload[\"code\"])\n        self.assertEqual(\"queued\", payload[\"data\"][\"status\"])\n        self.assertEqual(1, payload[\"data\"][\"queue_position\"])\n        self.assertIn(\"timestamp\", payload)\n\n    def test_release_task_returns_429_when_queue_is_full(self):\n        \"\"\"POST /release_task should return HTTP 429 when queue capacity is exhausted.\"\"\"\n\n        client = self._build_client(queue_maxsize=1)\n        first = client.post(\"/release_task\", json={\"ai_token\": \"test-token\", \"prompt\": \"first\"})\n        self.assertEqual(200, first.status_code)\n\n        second = client.post(\"/release_task\", json={\"ai_token\": \"test-token\", \"prompt\": \"second\"})\n        self.assertEqual(429, second.status_code)\n        self.assertEqual(\"Server busy: queue is full\", second.json()[\"detail\"])\n\n    def test_release_task_rejects_unsupported_content_type(self):\n        \"\"\"POST /release_task should return HTTP 415 for unsupported content type.\"\"\"\n\n        client = self._build_client()\n        response = client.post(\n            \"/release_task\",\n            headers={\"Content-Type\": \"text/plain\"},\n            content=\"hello world\",\n        )\n        self.assertEqual(415, response.status_code)\n        self.assertIn(\"Unsupported Content-Type\", response.json()[\"detail\"])\n\n\nif __name__ == \"__main__\":\n    unittest.main()\n"
  },
  {
    "path": "acestep/api/http/sample_format_routes.py",
    "content": "\"\"\"HTTP routes for random sample creation and input formatting.\"\"\"\n\nfrom __future__ import annotations\n\nimport json\nimport os\nfrom threading import Lock\nfrom typing import Any, Callable, Dict, List, Optional\n\nfrom fastapi import FastAPI, Header, HTTPException, Request\n\n\ndef register_sample_format_routes(\n    app: FastAPI,\n    verify_token_from_request: Callable[[dict, Optional[str]], Optional[str]],\n    wrap_response: Callable[..., Dict[str, Any]],\n    simple_example_data: List[Dict[str, Any]],\n    custom_example_data: List[Dict[str, Any]],\n    format_sample: Callable[..., Any],\n    get_project_root: Callable[[], str],\n    get_model_name: Callable[[str], str],\n    ensure_model_downloaded: Callable[[str, str], str],\n    env_bool: Callable[[str, bool], bool],\n    to_int: Callable[[Any, Optional[int]], Optional[int]],\n    to_float: Callable[[Any, Optional[float]], Optional[float]],\n) -> None:\n    \"\"\"Register random-sample and format-input routes on the FastAPI app.\"\"\"\n\n    @app.post(\"/create_random_sample\")\n    async def create_random_sample_endpoint(request: Request, authorization: Optional[str] = Header(None)):\n        \"\"\"Return a random pre-loaded sample payload for UI form filling.\"\"\"\n\n        content_type = (request.headers.get(\"content-type\") or \"\").lower()\n        if \"json\" in content_type:\n            body = await request.json()\n        else:\n            form = await request.form()\n            body = {k: v for k, v in form.items()}\n\n        verify_token_from_request(body, authorization)\n        sample_type = body.get(\"sample_type\", \"simple_mode\") or \"simple_mode\"\n        example_data = simple_example_data if sample_type == \"simple_mode\" else custom_example_data\n        if not example_data:\n            return wrap_response(None, code=500, error=\"No example data available\")\n        # Preserve existing API behavior of returning random sample payload.\n        import random\n\n        return wrap_response(random.choice(example_data))\n\n    @app.post(\"/format_input\")\n    async def format_input_endpoint(request: Request, authorization: Optional[str] = Header(None)):\n        \"\"\"Format prompt/lyrics via LLM and return normalized metadata fields.\"\"\"\n\n        content_type = (request.headers.get(\"content-type\") or \"\").lower()\n        if \"json\" in content_type:\n            body = await request.json()\n        else:\n            form = await request.form()\n            body = {k: v for k, v in form.items()}\n\n        verify_token_from_request(body, authorization)\n        llm = app.state.llm_handler\n        llm_lock: Lock = app.state._llm_init_lock\n\n        with llm_lock:\n            if not getattr(app.state, \"_llm_initialized\", False):\n                if getattr(app.state, \"_llm_init_error\", None):\n                    raise HTTPException(status_code=500, detail=f\"LLM init failed: {app.state._llm_init_error}\")\n                if getattr(app.state, \"_llm_lazy_load_disabled\", False):\n                    raise HTTPException(\n                        status_code=503,\n                        detail=\"LLM not initialized. Set ACESTEP_INIT_LLM=true in .env to enable.\",\n                    )\n\n                project_root = get_project_root()\n                checkpoint_dir = os.path.join(project_root, \"checkpoints\")\n                lm_model_path = os.getenv(\"ACESTEP_LM_MODEL_PATH\", \"acestep-5Hz-lm-0.6B\").strip()\n                backend = os.getenv(\"ACESTEP_LM_BACKEND\", \"vllm\").strip().lower()\n                if backend not in {\"vllm\", \"pt\", \"mlx\"}:\n                    backend = \"vllm\"\n\n                lm_model_name = get_model_name(lm_model_path)\n                if lm_model_name:\n                    try:\n                        ensure_model_downloaded(lm_model_name, checkpoint_dir)\n                    except Exception as exc:\n                        print(f\"[API Server] Warning: Failed to download LM model {lm_model_name}: {exc}\")\n\n                lm_device = os.getenv(\"ACESTEP_LM_DEVICE\", os.getenv(\"ACESTEP_DEVICE\", \"auto\"))\n                lm_offload = env_bool(\"ACESTEP_LM_OFFLOAD_TO_CPU\", False)\n                status, ok = llm.initialize(\n                    checkpoint_dir=checkpoint_dir,\n                    lm_model_path=lm_model_path,\n                    backend=backend,\n                    device=lm_device,\n                    offload_to_cpu=lm_offload,\n                    dtype=None,\n                )\n                if not ok:\n                    app.state._llm_init_error = status\n                    raise HTTPException(status_code=500, detail=f\"LLM init failed: {status}\")\n                app.state._llm_initialized = True\n\n        prompt = body.get(\"prompt\", \"\") or \"\"\n        lyrics = body.get(\"lyrics\", \"\") or \"\"\n        temperature = to_float(body.get(\"temperature\"), 0.85)\n        param_obj_str = body.get(\"param_obj\", \"{}\")\n        if isinstance(param_obj_str, dict):\n            param_obj = param_obj_str\n        else:\n            try:\n                param_obj = json.loads(param_obj_str) if param_obj_str else {}\n            except json.JSONDecodeError:\n                param_obj = {}\n\n        duration = to_float(param_obj.get(\"duration\"))\n        bpm = to_int(param_obj.get(\"bpm\"))\n        key_scale = param_obj.get(\"key\", \"\") or param_obj.get(\"key_scale\", \"\") or \"\"\n        time_signature = param_obj.get(\"time_signature\", \"\") or body.get(\"time_signature\", \"\") or \"\"\n        language = param_obj.get(\"language\", \"\") or \"\"\n\n        user_metadata_for_format: Dict[str, Any] = {}\n        if bpm is not None:\n            user_metadata_for_format[\"bpm\"] = bpm\n        if duration is not None and duration > 0:\n            user_metadata_for_format[\"duration\"] = int(duration)\n        if key_scale:\n            user_metadata_for_format[\"keyscale\"] = key_scale\n        if time_signature:\n            user_metadata_for_format[\"timesignature\"] = time_signature\n        if language and language != \"unknown\":\n            user_metadata_for_format[\"language\"] = language\n\n        try:\n            format_result = format_sample(\n                llm_handler=llm,\n                caption=prompt,\n                lyrics=lyrics,\n                user_metadata=user_metadata_for_format if user_metadata_for_format else None,\n                temperature=temperature,\n                use_constrained_decoding=True,\n            )\n            if not format_result.success:\n                error_msg = format_result.error or format_result.status_message\n                return wrap_response(None, code=500, error=f\"format_sample failed: {error_msg}\")\n\n            return wrap_response(\n                {\n                    \"caption\": format_result.caption or prompt,\n                    \"lyrics\": format_result.lyrics or lyrics,\n                    \"bpm\": format_result.bpm or bpm,\n                    \"key_scale\": format_result.keyscale or key_scale,\n                    \"time_signature\": format_result.timesignature or time_signature,\n                    \"duration\": format_result.duration or duration,\n                    \"vocal_language\": format_result.language or language or \"unknown\",\n                }\n            )\n        except Exception as exc:\n            return wrap_response(None, code=500, error=f\"format_sample error: {str(exc)}\")\n"
  },
  {
    "path": "acestep/api/http/sample_format_routes_http_test.py",
    "content": "\"\"\"HTTP integration tests for sample/format routes.\"\"\"\n\nimport threading\nimport unittest\nfrom types import SimpleNamespace\n\nfrom fastapi import FastAPI, HTTPException\nfrom fastapi.testclient import TestClient\n\nfrom acestep.api.http.sample_format_routes import register_sample_format_routes\n\n\ndef _wrap_response(data, code=200, error=None):\n    \"\"\"Return an ``api_server``-compatible response envelope dict.\"\"\"\n\n    return {\"data\": data, \"code\": code, \"error\": error}\n\n\ndef _verify_token_from_request(body: dict, authorization: str | None = None) -> None:\n    \"\"\"Validate fixed bearer/body token for integration tests.\"\"\"\n\n    if (body or {}).get(\"ai_token\") == \"test-token\":\n        return\n    if authorization == \"Bearer test-token\":\n        return\n    raise HTTPException(status_code=401, detail=\"Unauthorized\")\n\n\nclass _FakeLlm:\n    \"\"\"Minimal fake LLM handler for format endpoint HTTP tests.\"\"\"\n\n    llm_initialized = True\n\n    def initialize(self, **_kwargs):\n        \"\"\"Return successful initialization tuple.\"\"\"\n\n        self.llm_initialized = True\n        return \"ok\", True\n\n\nclass SampleFormatRoutesHttpTests(unittest.TestCase):\n    \"\"\"Integration tests covering real HTTP calls for sample/format routes.\"\"\"\n\n    def _build_client(self) -> TestClient:\n        \"\"\"Create app and register sample/format routes.\"\"\"\n\n        app = FastAPI()\n        app.state.llm_handler = _FakeLlm()\n        app.state._llm_init_lock = threading.Lock()\n        app.state._llm_initialized = True\n        app.state._llm_init_error = None\n        app.state._llm_lazy_load_disabled = False\n\n        register_sample_format_routes(\n            app=app,\n            verify_token_from_request=_verify_token_from_request,\n            wrap_response=_wrap_response,\n            simple_example_data=[{\"mode\": \"simple\", \"seed\": 1}],\n            custom_example_data=[{\"mode\": \"custom\", \"seed\": 2}],\n            format_sample=lambda **_kwargs: SimpleNamespace(\n                success=True,\n                caption=\"c\",\n                lyrics=\"l\",\n                bpm=100,\n                keyscale=\"C\",\n                timesignature=\"4/4\",\n                duration=8,\n                language=\"en\",\n                error=None,\n                status_message=None,\n            ),\n            get_project_root=lambda: \"/tmp/non-existent\",\n            get_model_name=lambda p: str(p).split(\"/\")[-1].split(\"\\\\\")[-1],\n            ensure_model_downloaded=lambda *_: \"\",\n            env_bool=lambda *_: False,\n            to_int=lambda v, d=None: int(v) if v is not None else d,\n            to_float=lambda v, d=None: float(v) if v is not None else d,\n        )\n        return TestClient(app)\n\n    def test_create_random_sample_requires_auth(self):\n        \"\"\"POST /create_random_sample should return 401 when auth is missing.\"\"\"\n\n        client = self._build_client()\n        response = client.post(\"/create_random_sample\", json={\"sample_type\": \"simple_mode\"})\n        self.assertEqual(401, response.status_code)\n\n    def test_create_random_sample_returns_wrapped_payload(self):\n        \"\"\"POST /create_random_sample should return wrapped payload when authorized.\"\"\"\n\n        client = self._build_client()\n        response = client.post(\n            \"/create_random_sample\",\n            json={\"ai_token\": \"test-token\", \"sample_type\": \"simple_mode\"},\n        )\n        self.assertEqual(200, response.status_code)\n        payload = response.json()\n        self.assertEqual(200, payload[\"code\"])\n        self.assertEqual(\"simple\", payload[\"data\"][\"mode\"])\n\n    def test_format_input_returns_wrapped_payload(self):\n        \"\"\"POST /format_input should return wrapped formatted response.\"\"\"\n\n        client = self._build_client()\n        response = client.post(\n            \"/format_input\",\n            json={\"ai_token\": \"test-token\", \"prompt\": \"p\", \"lyrics\": \"l\", \"param_obj\": {\"bpm\": 100}},\n        )\n        self.assertEqual(200, response.status_code)\n        payload = response.json()\n        self.assertEqual(200, payload[\"code\"])\n        self.assertEqual(\"c\", payload[\"data\"][\"caption\"])\n\n\nif __name__ == \"__main__\":\n    unittest.main()\n"
  },
  {
    "path": "acestep/api/http/sample_format_routes_test.py",
    "content": "\"\"\"Unit tests for sample/format route registration.\"\"\"\n\nimport asyncio\nimport json\nimport threading\nimport unittest\nfrom types import SimpleNamespace\n\nfrom fastapi import FastAPI, HTTPException\nfrom fastapi.routing import APIRoute\n\nfrom acestep.api.http.sample_format_routes import register_sample_format_routes\n\n\ndef _wrap_response(data, code=200, error=None):\n    \"\"\"Return an ``api_server``-compatible response envelope dict.\"\"\"\n\n    return {\"data\": data, \"code\": code, \"error\": error}\n\n\ndef _verify_token_from_request(body: dict, authorization: str | None = None) -> None:\n    \"\"\"Validate a fixed token from body or Authorization header for unit tests.\"\"\"\n\n    token = (body or {}).get(\"ai_token\")\n    if token == \"test-token\":\n        return\n    if authorization == \"Bearer test-token\":\n        return\n    raise HTTPException(status_code=401, detail=\"Unauthorized\")\n\n\ndef _get_endpoint(app: FastAPI, path: str, method: str):\n    \"\"\"Return endpoint callable matching a route path/method pair.\"\"\"\n\n    for route in app.routes:\n        if isinstance(route, APIRoute) and route.path == path and method.upper() in route.methods:\n            return route.endpoint\n    raise AssertionError(f\"Missing route: {method} {path}\")\n\n\nclass _FakeLlm:\n    \"\"\"Minimal fake LLM handler used by format route tests.\"\"\"\n\n    def __init__(self) -> None:\n        \"\"\"Initialize fake handler state.\"\"\"\n\n        self.llm_initialized = False\n\n    def initialize(self, **_kwargs):\n        \"\"\"Return successful initialization tuple.\"\"\"\n\n        self.llm_initialized = True\n        return \"ok\", True\n\n\nclass SampleFormatRoutesTests(unittest.TestCase):\n    \"\"\"Behavior tests for sample and format route registration helpers.\"\"\"\n\n    def _build_app(self) -> FastAPI:\n        \"\"\"Create app state and register sample/format routes for tests.\"\"\"\n\n        app = FastAPI()\n        app.state.llm_handler = _FakeLlm()\n        app.state._llm_init_lock = threading.Lock()\n        app.state._llm_initialized = True\n        app.state._llm_init_error = None\n        app.state._llm_lazy_load_disabled = False\n        register_sample_format_routes(\n            app=app,\n            verify_token_from_request=_verify_token_from_request,\n            wrap_response=_wrap_response,\n            simple_example_data=[{\"mode\": \"simple\", \"x\": 1}],\n            custom_example_data=[{\"mode\": \"custom\", \"x\": 2}],\n            format_sample=lambda **_kwargs: SimpleNamespace(\n                success=True,\n                caption=\"formatted-caption\",\n                lyrics=\"formatted-lyrics\",\n                bpm=120,\n                keyscale=\"C\",\n                timesignature=\"4/4\",\n                duration=10,\n                language=\"en\",\n                error=None,\n                status_message=None,\n            ),\n            get_project_root=lambda: \"/tmp/non-existent\",\n            get_model_name=lambda p: str(p).split(\"/\")[-1].split(\"\\\\\")[-1],\n            ensure_model_downloaded=lambda *_: \"\",\n            env_bool=lambda *_: False,\n            to_int=lambda v, d=None: int(v) if v is not None else d,\n            to_float=lambda v, d=None: float(v) if v is not None else d,\n        )\n        return app\n\n    def test_create_random_sample_returns_simple_payload(self):\n        \"\"\"Random sample endpoint should return wrapped random simple-mode payload.\"\"\"\n\n        app = self._build_app()\n        endpoint = _get_endpoint(app, \"/create_random_sample\", \"POST\")\n        request = SimpleNamespace(headers={\"content-type\": \"application/json\"}, json=lambda: {\"ai_token\": \"test-token\"})\n\n        async def _json():\n            \"\"\"Return a deterministic JSON payload for this unit test.\"\"\"\n\n            return {\"ai_token\": \"test-token\", \"sample_type\": \"simple_mode\"}\n\n        request.json = _json\n\n        result = asyncio.run(endpoint(request, None))\n\n        self.assertEqual(200, result[\"code\"])\n        self.assertEqual(\"simple\", result[\"data\"][\"mode\"])\n\n    def test_format_input_returns_wrapped_success_payload(self):\n        \"\"\"Format endpoint should return wrapped formatted fields on success.\"\"\"\n\n        app = self._build_app()\n        endpoint = _get_endpoint(app, \"/format_input\", \"POST\")\n\n        async def _json():\n            \"\"\"Return a deterministic format-input JSON body for this test.\"\"\"\n\n            return {\"ai_token\": \"test-token\", \"prompt\": \"p\", \"lyrics\": \"l\", \"param_obj\": json.dumps({\"bpm\": 100})}\n\n        request = SimpleNamespace(headers={\"content-type\": \"application/json\"}, json=_json)\n        result = asyncio.run(endpoint(request, None))\n\n        self.assertEqual(200, result[\"code\"])\n        self.assertEqual(\"formatted-caption\", result[\"data\"][\"caption\"])\n\n    def test_format_input_raises_503_when_lazy_load_disabled(self):\n        \"\"\"Format endpoint should preserve 503 contract when lazy loading is disabled.\"\"\"\n\n        app = self._build_app()\n        app.state._llm_initialized = False\n        app.state._llm_lazy_load_disabled = True\n        endpoint = _get_endpoint(app, \"/format_input\", \"POST\")\n\n        async def _json():\n            \"\"\"Return a minimal format-input JSON body for lazy-load test.\"\"\"\n\n            return {\"ai_token\": \"test-token\", \"prompt\": \"p\", \"lyrics\": \"l\"}\n\n        request = SimpleNamespace(headers={\"content-type\": \"application/json\"}, json=_json)\n\n        with self.assertRaises(HTTPException) as ctx:\n            asyncio.run(endpoint(request, None))\n        self.assertEqual(503, ctx.exception.status_code)\n\n\nif __name__ == \"__main__\":\n    unittest.main()\n"
  },
  {
    "path": "acestep/api/job_analysis_runtime.py",
    "content": "\"\"\"Analysis-mode runtime helpers for API job generation.\"\"\"\n\nfrom __future__ import annotations\n\nimport os\nfrom typing import Any, Optional\n\n\ndef maybe_handle_analysis_only_modes(\n    *,\n    req: Any,\n    params: Any,\n    config: Any,\n    llm_handler: Any,\n    dit_handler: Any,\n    store: Any,\n    job_id: str,\n) -> Optional[dict[str, Any]]:\n    \"\"\"Run analysis-only branches and return response payload when handled.\n\n    Args:\n        req: Generation request object.\n        params: Prepared generation params object.\n        config: Prepared generation config object.\n        llm_handler: Initialized LLM handler (or None if unavailable).\n        dit_handler: Selected DiT handler.\n        store: Job store used for progress text updates.\n        job_id: Current job identifier.\n\n    Returns:\n        Optional[dict[str, Any]]: Analysis response when an analysis mode is active,\n            otherwise None.\n\n    Raises:\n        RuntimeError: If analysis execution fails.\n    \"\"\"\n\n    if req.extract_codes_only:\n        if not params.src_audio:\n            raise ValueError(\"extract_codes_only requires src_audio_path to be set.\")\n        store.update_progress_text(job_id, \"Extracting Audio Codes...\")\n        audio_codes = dit_handler.convert_src_audio_to_codes(params.src_audio)\n        if not audio_codes or audio_codes.startswith(\"❌\"):\n            raise RuntimeError(f\"Audio extraction failed: {audio_codes}\")\n        return {\n            \"status_message\": \"Audio Codes Extraction Success\",\n            \"audio_codes\": audio_codes,\n            \"audio_paths\": [],\n            \"raw_audio_paths\": [],\n            \"first_audio_path\": None,\n            \"metas\": {},\n        }\n\n    if req.full_analysis_only:\n        store.update_progress_text(job_id, \"Starting Deep Analysis...\")\n        audio_codes = dit_handler.convert_src_audio_to_codes(params.src_audio)\n        if not audio_codes or audio_codes.startswith(\"❌\"):\n            raise RuntimeError(f\"Audio encoding failed: {audio_codes}\")\n\n        metadata_dict, status_string = llm_handler.understand_audio_from_codes(\n            audio_codes=audio_codes,\n            temperature=0.3,\n            use_constrained_decoding=True,\n            constrained_decoding_debug=config.constrained_decoding_debug,\n        )\n        if not metadata_dict:\n            raise RuntimeError(f\"LLM Understanding failed: {status_string}\")\n\n        return {\n            \"status_message\": \"Full Hardware Analysis Success\",\n            \"bpm\": metadata_dict.get(\"bpm\"),\n            \"keyscale\": metadata_dict.get(\"keyscale\"),\n            \"timesignature\": metadata_dict.get(\"timesignature\"),\n            \"duration\": metadata_dict.get(\"duration\"),\n            \"genre\": metadata_dict.get(\"genres\") or metadata_dict.get(\"genre\"),\n            \"prompt\": metadata_dict.get(\"caption\", \"\"),\n            \"lyrics\": metadata_dict.get(\"lyrics\", \"\"),\n            \"language\": metadata_dict.get(\"language\", \"unknown\"),\n            \"metas\": metadata_dict,\n            \"audio_codes\": audio_codes,\n            \"audio_paths\": [],\n        }\n\n    if req.analysis_only:\n        lm_res = llm_handler.generate_with_stop_condition(\n            caption=params.caption,\n            lyrics=params.lyrics,\n            infer_type=\"dit\",\n            temperature=req.lm_temperature,\n            top_p=req.lm_top_p,\n            use_cot_metas=True,\n            use_cot_caption=req.use_cot_caption,\n            use_cot_language=req.use_cot_language,\n            use_constrained_decoding=True,\n        )\n        if not lm_res.get(\"success\"):\n            raise RuntimeError(f\"Analysis Failed: {lm_res.get('error')}\")\n\n        metas_found = lm_res.get(\"metadata\", {})\n        return {\n            \"first_audio_path\": None,\n            \"audio_paths\": [],\n            \"raw_audio_paths\": [],\n            \"generation_info\": \"Analysis Only Mode Complete\",\n            \"status_message\": \"Success\",\n            \"metas\": metas_found,\n            \"bpm\": metas_found.get(\"bpm\"),\n            \"keyscale\": metas_found.get(\"keyscale\"),\n            \"duration\": metas_found.get(\"duration\"),\n            \"prompt\": metas_found.get(\"caption\", params.caption),\n            \"lyrics\": params.lyrics,\n            \"lm_model\": os.getenv(\"ACESTEP_LM_MODEL_PATH\", \"\"),\n            \"dit_model\": \"None (Analysis Only)\",\n        }\n\n    return None\n"
  },
  {
    "path": "acestep/api/job_analysis_runtime_test.py",
    "content": "\"\"\"Unit tests for analysis-only runtime helpers.\"\"\"\n\nfrom __future__ import annotations\n\nimport os\nimport unittest\nfrom types import SimpleNamespace\nfrom unittest.mock import MagicMock, patch\n\nfrom acestep.api.job_analysis_runtime import maybe_handle_analysis_only_modes\n\n\nclass JobAnalysisRuntimeTests(unittest.TestCase):\n    \"\"\"Behavior tests for analysis-only and full-analysis runtime branches.\"\"\"\n\n    def _base_req(self) -> SimpleNamespace:\n        return SimpleNamespace(\n            full_analysis_only=False,\n            analysis_only=False,\n            extract_codes_only=False,\n            lm_temperature=0.85,\n            lm_top_p=0.9,\n            use_cot_caption=False,\n            use_cot_language=False,\n        )\n\n    def test_full_analysis_returns_expected_payload(self) -> None:\n        \"\"\"Full analysis should convert audio and return metadata payload.\"\"\"\n\n        req = self._base_req()\n        req.full_analysis_only = True\n        params = SimpleNamespace(src_audio=\"src.wav\", caption=\"cap\", lyrics=\"lyr\")\n        config = SimpleNamespace(constrained_decoding_debug=True)\n        llm_handler = MagicMock()\n        llm_handler.understand_audio_from_codes.return_value = (\n            {\n                \"bpm\": 120,\n                \"keyscale\": \"C major\",\n                \"timesignature\": \"4/4\",\n                \"duration\": 8.0,\n                \"caption\": \"meta cap\",\n                \"lyrics\": \"meta lyr\",\n                \"language\": \"en\",\n                \"genres\": \"pop\",\n            },\n            \"ok\",\n        )\n        dit_handler = MagicMock()\n        dit_handler.convert_src_audio_to_codes.return_value = \"<|audio_code_1|>\"\n        store = MagicMock()\n\n        result = maybe_handle_analysis_only_modes(\n            req=req,\n            params=params,\n            config=config,\n            llm_handler=llm_handler,\n            dit_handler=dit_handler,\n            store=store,\n            job_id=\"job-1\",\n        )\n\n        self.assertEqual(\"Full Hardware Analysis Success\", result[\"status_message\"])\n        self.assertEqual(\"pop\", result[\"genre\"])\n        self.assertEqual(\"<|audio_code_1|>\", result[\"audio_codes\"])\n        store.update_progress_text.assert_called_once_with(\"job-1\", \"Starting Deep Analysis...\")\n\n    def test_analysis_only_uses_lm_and_returns_payload(self) -> None:\n        \"\"\"Analysis-only mode should return LM metadata with fixed response contract.\"\"\"\n\n        req = self._base_req()\n        req.analysis_only = True\n        req.use_cot_caption = True\n        params = SimpleNamespace(caption=\"cap\", lyrics=\"lyr\")\n        config = SimpleNamespace(constrained_decoding_debug=False)\n        llm_handler = MagicMock()\n        llm_handler.generate_with_stop_condition.return_value = {\n            \"success\": True,\n            \"metadata\": {\"bpm\": 123, \"caption\": \"better cap\", \"duration\": 9.0},\n        }\n        dit_handler = MagicMock()\n        store = MagicMock()\n\n        with patch.dict(os.environ, {\"ACESTEP_LM_MODEL_PATH\": \"lm-path\"}, clear=True):\n            result = maybe_handle_analysis_only_modes(\n                req=req,\n                params=params,\n                config=config,\n                llm_handler=llm_handler,\n                dit_handler=dit_handler,\n                store=store,\n                job_id=\"job-2\",\n            )\n\n        self.assertEqual(\"Success\", result[\"status_message\"])\n        self.assertEqual(\"lm-path\", result[\"lm_model\"])\n        self.assertEqual(\"None (Analysis Only)\", result[\"dit_model\"])\n\n    def test_extract_codes_only_returns_expected_payload(self) -> None:\n        \"\"\"extract_codes_only should convert audio and return codes without LLM call.\"\"\"\n\n        req = self._base_req()\n        req.extract_codes_only = True\n        params = SimpleNamespace(src_audio=\"src.wav\", caption=\"cap\", lyrics=\"lyr\")\n        config = SimpleNamespace(constrained_decoding_debug=False)\n        dit_handler = MagicMock()\n        dit_handler.convert_src_audio_to_codes.return_value = \"<|audio_code_1|>\"\n        llm_handler = MagicMock()\n        store = MagicMock()\n\n        result = maybe_handle_analysis_only_modes(\n            req=req,\n            params=params,\n            config=config,\n            llm_handler=llm_handler,\n            dit_handler=dit_handler,\n            store=store,\n            job_id=\"job-ec-1\",\n        )\n\n        self.assertEqual(\"Audio Codes Extraction Success\", result[\"status_message\"])\n        self.assertEqual(\"<|audio_code_1|>\", result[\"audio_codes\"])\n        self.assertEqual([], result[\"audio_paths\"])\n        self.assertIsNone(result[\"first_audio_path\"])\n        store.update_progress_text.assert_called_once_with(\"job-ec-1\", \"Extracting Audio Codes...\")\n        llm_handler.understand_audio_from_codes.assert_not_called()\n        llm_handler.generate_with_stop_condition.assert_not_called()\n\n    def test_extract_codes_only_raises_when_no_src_audio(self) -> None:\n        \"\"\"extract_codes_only should raise ValueError when src_audio is not provided.\"\"\"\n\n        req = self._base_req()\n        req.extract_codes_only = True\n        params = SimpleNamespace(src_audio=None, caption=\"cap\", lyrics=\"lyr\")\n        config = SimpleNamespace(constrained_decoding_debug=False)\n\n        with self.assertRaisesRegex(ValueError, \"extract_codes_only requires src_audio_path to be set\"):\n            maybe_handle_analysis_only_modes(\n                req=req,\n                params=params,\n                config=config,\n                llm_handler=MagicMock(),\n                dit_handler=MagicMock(),\n                store=MagicMock(),\n                job_id=\"job-ec-2\",\n            )\n\n    def test_extract_codes_only_raises_on_extraction_failure(self) -> None:\n        \"\"\"extract_codes_only should raise RuntimeError when audio extraction fails.\"\"\"\n\n        req = self._base_req()\n        req.extract_codes_only = True\n        params = SimpleNamespace(src_audio=\"bad.wav\", caption=\"cap\", lyrics=\"lyr\")\n        config = SimpleNamespace(constrained_decoding_debug=False)\n        dit_handler = MagicMock()\n        dit_handler.convert_src_audio_to_codes.return_value = \"❌ encoding error\"\n        store = MagicMock()\n\n        with self.assertRaises(RuntimeError):\n            maybe_handle_analysis_only_modes(\n                req=req,\n                params=params,\n                config=config,\n                llm_handler=MagicMock(),\n                dit_handler=dit_handler,\n                store=store,\n                job_id=\"job-ec-3\",\n            )\n\n    def test_returns_none_when_no_analysis_flags(self) -> None:\n        \"\"\"Helper should no-op when neither analysis mode is enabled.\"\"\"\n\n        req = self._base_req()\n        params = SimpleNamespace(caption=\"cap\", lyrics=\"lyr\", src_audio=\"src.wav\")\n        config = SimpleNamespace(constrained_decoding_debug=False)\n\n        result = maybe_handle_analysis_only_modes(\n            req=req,\n            params=params,\n            config=config,\n            llm_handler=MagicMock(),\n            dit_handler=MagicMock(),\n            store=MagicMock(),\n            job_id=\"job-3\",\n        )\n\n        self.assertIsNone(result)\n\n\nif __name__ == \"__main__\":\n    unittest.main()\n"
  },
  {
    "path": "acestep/api/job_blocking_generation.py",
    "content": "\"\"\"Blocking generation orchestration helper for API jobs.\"\"\"\n\nfrom __future__ import annotations\n\nimport os\nimport time\nfrom typing import Any, Callable\n\nfrom acestep.api.job_analysis_runtime import maybe_handle_analysis_only_modes\nfrom acestep.api.job_generation_runtime import run_generation_with_optional_sequential_cover_mode\nfrom acestep.api.job_llm_preparation import (\n    ensure_llm_ready_for_request,\n    prepare_llm_generation_inputs,\n)\nfrom acestep.api.job_runtime_state import update_progress_job_cache\nfrom acestep.api.job_result_payload import build_generation_success_response\nfrom acestep.api.job_generation_setup import build_generation_setup\n\n\ndef run_blocking_generate(\n    *,\n    app_state: Any,\n    req: Any,\n    job_id: str,\n    store: Any,\n    llm_handler: Any,\n    selected_handler: Any,\n    selected_model_name: str,\n    map_status: Callable[[str], str],\n    result_key_prefix: str,\n    result_expire_seconds: int,\n    get_project_root: Callable[[], str],\n    get_model_name: Callable[[str], str],\n    ensure_model_downloaded: Callable[[str, str], str],\n    env_bool: Callable[[str, bool], bool],\n    parse_description_hints: Callable[[str], tuple[str | None, bool]],\n    parse_timesteps: Callable[[str | None], list[float] | None],\n    is_instrumental: Callable[[str], bool],\n    create_sample_fn: Callable[..., Any],\n    format_sample_fn: Callable[..., Any],\n    generate_music_fn: Callable[..., Any],\n    default_dit_instruction: str,\n    task_instructions: dict[str, str],\n    build_generation_info_fn: Callable[..., str],\n    path_to_audio_url_fn: Callable[[str], str],\n    log_fn: Callable[[str], None] = print,\n) -> dict[str, Any]:\n    \"\"\"Execute the blocking generation path for a job.\n\n    Args:\n        app_state: FastAPI app state object.\n        req: Generation request object.\n        job_id: Job identifier.\n        store: Job store used for progress updates.\n        llm_handler: LLM handler instance.\n        selected_handler: Selected DiT handler instance.\n        selected_model_name: Selected DiT model label.\n        map_status: Status mapping callback for cache updates.\n        result_key_prefix: Result key namespace prefix.\n        result_expire_seconds: Result cache expiration window.\n        get_project_root: Project-root callback.\n        get_model_name: Model-name resolver callback.\n        ensure_model_downloaded: Model download callback.\n        env_bool: Environment boolean parser callback.\n        parse_description_hints: Prompt-hints parser callback.\n        parse_timesteps: Timesteps parser callback.\n        is_instrumental: Instrumental detector callback.\n        create_sample_fn: Sample generation callback.\n        format_sample_fn: Sample formatting callback.\n        generate_music_fn: Core generation callback.\n        default_dit_instruction: Default instruction constant.\n        task_instructions: Task instruction mapping.\n        build_generation_info_fn: Generation-info builder callback.\n        path_to_audio_url_fn: Audio path to URL callback.\n        log_fn: Logging callback.\n\n    Returns:\n        dict[str, Any]: Final success payload for job completion.\n    \"\"\"\n\n    def _ensure_llm_ready() -> None:\n        ensure_llm_ready_for_request(\n            app_state=app_state,\n            llm_handler=llm_handler,\n            req=req,\n            get_project_root=get_project_root,\n            get_model_name=get_model_name,\n            ensure_model_downloaded=ensure_model_downloaded,\n            env_bool=env_bool,\n            log_fn=log_fn,\n        )\n\n    prepared_inputs = prepare_llm_generation_inputs(\n        app_state=app_state,\n        llm_handler=llm_handler,\n        req=req,\n        selected_handler_device=selected_handler.device,\n        parse_description_hints=parse_description_hints,\n        create_sample_fn=create_sample_fn,\n        format_sample_fn=format_sample_fn,\n        ensure_llm_ready_fn=_ensure_llm_ready,\n        log_fn=log_fn,\n    )\n\n    generation_setup = build_generation_setup(\n        req=req,\n        caption=prepared_inputs.caption,\n        global_caption=prepared_inputs.global_caption,\n        lyrics=prepared_inputs.lyrics,\n        bpm=prepared_inputs.bpm,\n        key_scale=prepared_inputs.key_scale,\n        time_signature=prepared_inputs.time_signature,\n        audio_duration=prepared_inputs.audio_duration,\n        thinking=prepared_inputs.thinking,\n        sample_mode=prepared_inputs.sample_mode,\n        format_has_duration=prepared_inputs.format_has_duration,\n        use_cot_caption=prepared_inputs.use_cot_caption,\n        use_cot_language=prepared_inputs.use_cot_language,\n        lm_top_k=prepared_inputs.lm_top_k,\n        lm_top_p=prepared_inputs.lm_top_p,\n        parse_timesteps=parse_timesteps,\n        is_instrumental=is_instrumental,\n        default_dit_instruction=default_dit_instruction,\n        task_instructions=task_instructions,\n    )\n    params = generation_setup.params\n    config = generation_setup.config\n\n    llm_is_initialized = getattr(app_state, \"_llm_initialized\", False)\n    llm_to_pass = llm_handler if llm_is_initialized else None\n\n    last_progress = {\"value\": -1.0, \"time\": 0.0, \"stage\": \"\"}\n\n    def _progress_cb(value: float, desc: str = \"\") -> None:\n        now = time.time()\n        try:\n            value_f = max(0.0, min(1.0, float(value)))\n        except Exception:\n            value_f = 0.0\n        stage = desc or last_progress[\"stage\"] or \"running\"\n        if (\n            value_f - last_progress[\"value\"] >= 0.01\n            or stage != last_progress[\"stage\"]\n            or (now - last_progress[\"time\"]) >= 0.5\n        ):\n            last_progress[\"value\"] = value_f\n            last_progress[\"time\"] = now\n            last_progress[\"stage\"] = stage\n            store.update_progress(job_id, value_f, stage=stage)\n            update_progress_job_cache(\n                app_state=app_state,\n                store=store,\n                job_id=job_id,\n                progress=value_f,\n                stage=stage,\n                map_status=map_status,\n                result_key_prefix=result_key_prefix,\n                result_expire_seconds=result_expire_seconds,\n            )\n\n    analysis_result = maybe_handle_analysis_only_modes(\n        req=req,\n        params=params,\n        config=config,\n        llm_handler=llm_to_pass,\n        dit_handler=selected_handler,\n        store=store,\n        job_id=job_id,\n    )\n    if analysis_result is not None:\n        return analysis_result\n\n    result = run_generation_with_optional_sequential_cover_mode(\n        req=req,\n        job_id=job_id,\n        handler_device=selected_handler.device,\n        config=config,\n        params=params,\n        dit_handler=selected_handler,\n        llm_handler=llm_to_pass,\n        temp_audio_dir=app_state.temp_audio_dir,\n        generate_music_fn=generate_music_fn,\n        progress_cb=_progress_cb,\n        log_fn=log_fn,\n    )\n\n    lm_model_name = os.getenv(\"ACESTEP_LM_MODEL_PATH\", \"acestep-5Hz-lm-0.6B\")\n    return build_generation_success_response(\n        result=result,\n        params=params,\n        bpm=prepared_inputs.bpm,\n        audio_duration=prepared_inputs.audio_duration,\n        key_scale=prepared_inputs.key_scale,\n        time_signature=prepared_inputs.time_signature,\n        original_prompt=prepared_inputs.original_prompt,\n        original_lyrics=prepared_inputs.original_lyrics,\n        inference_steps=req.inference_steps,\n        path_to_audio_url=path_to_audio_url_fn,\n        build_generation_info=build_generation_info_fn,\n        lm_model_name=lm_model_name,\n        dit_model_name=selected_model_name,\n    )\n"
  },
  {
    "path": "acestep/api/job_blocking_generation_test.py",
    "content": "\"\"\"Unit tests for blocking generation orchestration helper.\"\"\"\n\nfrom __future__ import annotations\n\nimport unittest\nfrom types import SimpleNamespace\nfrom unittest.mock import MagicMock, patch\n\nfrom acestep.api.job_blocking_generation import run_blocking_generate\n\n\nclass JobBlockingGenerationTests(unittest.TestCase):\n    \"\"\"Behavior tests for blocking generation orchestration decomposition.\"\"\"\n\n    def _base_req(self) -> SimpleNamespace:\n        return SimpleNamespace(inference_steps=25)\n\n    def test_run_blocking_generate_success_path_updates_progress_and_builds_payload(self) -> None:\n        \"\"\"Helper should preserve progress/cache update flow and success payload assembly.\"\"\"\n\n        app_state = SimpleNamespace(_llm_initialized=True, temp_audio_dir=\"tmp\")\n        req = self._base_req()\n        store = MagicMock()\n        llm_handler = MagicMock()\n        selected_handler = SimpleNamespace(device=\"cuda\")\n        prepared = SimpleNamespace(\n            caption=\"cap\",\n            lyrics=\"lyr\",\n            bpm=120,\n            key_scale=\"C major\",\n            time_signature=\"4/4\",\n            audio_duration=12.0,\n            thinking=False,\n            sample_mode=False,\n            format_has_duration=False,\n            use_cot_caption=False,\n            use_cot_language=False,\n            lm_top_k=0,\n            lm_top_p=0.9,\n            original_prompt=\"orig cap\",\n            original_lyrics=\"orig lyr\",\n        )\n        setup = SimpleNamespace(\n            params=SimpleNamespace(caption=\"cap\", lyrics=\"lyr\"),\n            config=SimpleNamespace(),\n        )\n        generation_result = SimpleNamespace(success=True, audios=[{\"audio_path\": \"a.wav\"}])\n\n        def _run_generation_side_effect(**kwargs):\n            kwargs[\"progress_cb\"](0.5, \"generating\")\n            return generation_result\n\n        with patch(\"acestep.api.job_blocking_generation.prepare_llm_generation_inputs\", return_value=prepared), \\\n                patch(\"acestep.api.job_blocking_generation.build_generation_setup\", return_value=setup), \\\n                patch(\"acestep.api.job_blocking_generation.maybe_handle_analysis_only_modes\", return_value=None), \\\n                patch(\n                    \"acestep.api.job_blocking_generation.run_generation_with_optional_sequential_cover_mode\",\n                    side_effect=_run_generation_side_effect,\n                ), \\\n                patch(\n                    \"acestep.api.job_blocking_generation.build_generation_success_response\",\n                    return_value={\"status_message\": \"Success\"},\n                ) as build_resp_mock, \\\n                patch(\"acestep.api.job_blocking_generation.update_progress_job_cache\") as cache_progress_mock:\n            result = run_blocking_generate(\n                app_state=app_state,\n                req=req,\n                job_id=\"job-1\",\n                store=store,\n                llm_handler=llm_handler,\n                selected_handler=selected_handler,\n                selected_model_name=\"model-A\",\n                map_status=MagicMock(return_value=\"running\"),\n                result_key_prefix=\"prefix_\",\n                result_expire_seconds=3600,\n                get_project_root=MagicMock(return_value=\"root\"),\n                get_model_name=MagicMock(return_value=\"m\"),\n                ensure_model_downloaded=MagicMock(),\n                env_bool=MagicMock(return_value=False),\n                parse_description_hints=MagicMock(return_value=(\"en\", False)),\n                parse_timesteps=MagicMock(return_value=None),\n                is_instrumental=MagicMock(return_value=False),\n                create_sample_fn=MagicMock(),\n                format_sample_fn=MagicMock(),\n                generate_music_fn=MagicMock(),\n                default_dit_instruction=\"default\",\n                task_instructions={},\n                build_generation_info_fn=MagicMock(return_value=\"info\"),\n                path_to_audio_url_fn=MagicMock(side_effect=lambda p: p),\n                log_fn=MagicMock(),\n            )\n\n        self.assertEqual({\"status_message\": \"Success\"}, result)\n        store.update_progress.assert_called_once()\n        cache_progress_mock.assert_called_once()\n        build_resp_mock.assert_called_once()\n\n    def test_run_blocking_generate_returns_analysis_result_without_generation(self) -> None:\n        \"\"\"Helper should short-circuit when analysis mode returns payload.\"\"\"\n\n        app_state = SimpleNamespace(_llm_initialized=False, temp_audio_dir=\"tmp\")\n        req = self._base_req()\n        store = MagicMock()\n        llm_handler = MagicMock()\n        selected_handler = SimpleNamespace(device=\"cuda\")\n        prepared = SimpleNamespace(\n            caption=\"cap\",\n            lyrics=\"lyr\",\n            bpm=None,\n            key_scale=\"\",\n            time_signature=\"\",\n            audio_duration=None,\n            thinking=False,\n            sample_mode=False,\n            format_has_duration=False,\n            use_cot_caption=False,\n            use_cot_language=False,\n            lm_top_k=0,\n            lm_top_p=0.9,\n            original_prompt=\"orig cap\",\n            original_lyrics=\"orig lyr\",\n        )\n        setup = SimpleNamespace(\n            params=SimpleNamespace(caption=\"cap\", lyrics=\"lyr\"),\n            config=SimpleNamespace(),\n        )\n        analysis_payload = {\"status_message\": \"Analysis Only Mode Complete\"}\n\n        with patch(\"acestep.api.job_blocking_generation.prepare_llm_generation_inputs\", return_value=prepared), \\\n                patch(\"acestep.api.job_blocking_generation.build_generation_setup\", return_value=setup), \\\n                patch(\n                    \"acestep.api.job_blocking_generation.maybe_handle_analysis_only_modes\",\n                    return_value=analysis_payload,\n                ) as analysis_mock, \\\n                patch(\"acestep.api.job_blocking_generation.run_generation_with_optional_sequential_cover_mode\") as run_mock, \\\n                patch(\"acestep.api.job_blocking_generation.build_generation_success_response\") as build_resp_mock:\n            result = run_blocking_generate(\n                app_state=app_state,\n                req=req,\n                job_id=\"job-2\",\n                store=store,\n                llm_handler=llm_handler,\n                selected_handler=selected_handler,\n                selected_model_name=\"model-B\",\n                map_status=MagicMock(return_value=\"running\"),\n                result_key_prefix=\"prefix_\",\n                result_expire_seconds=3600,\n                get_project_root=MagicMock(return_value=\"root\"),\n                get_model_name=MagicMock(return_value=\"m\"),\n                ensure_model_downloaded=MagicMock(),\n                env_bool=MagicMock(return_value=False),\n                parse_description_hints=MagicMock(return_value=(\"en\", False)),\n                parse_timesteps=MagicMock(return_value=None),\n                is_instrumental=MagicMock(return_value=False),\n                create_sample_fn=MagicMock(),\n                format_sample_fn=MagicMock(),\n                generate_music_fn=MagicMock(),\n                default_dit_instruction=\"default\",\n                task_instructions={},\n                build_generation_info_fn=MagicMock(return_value=\"info\"),\n                path_to_audio_url_fn=MagicMock(side_effect=lambda p: p),\n                log_fn=MagicMock(),\n            )\n\n        self.assertEqual(analysis_payload, result)\n        self.assertIsNone(analysis_mock.call_args.kwargs[\"llm_handler\"])\n        run_mock.assert_not_called()\n        build_resp_mock.assert_not_called()\n\n\nif __name__ == \"__main__\":\n    unittest.main()\n"
  },
  {
    "path": "acestep/api/job_execution_runtime.py",
    "content": "\"\"\"Async job execution runtime helper for API queue workers.\"\"\"\n\nfrom __future__ import annotations\n\nimport asyncio\nimport time\nimport traceback\nfrom typing import Any, Awaitable, Callable\n\n\nasync def run_one_job_runtime(\n    *,\n    app_state: Any,\n    store: Any,\n    job_id: str,\n    req: Any,\n    ensure_models_initialized_fn: Callable[[Any], Awaitable[None]],\n    select_generation_handler_fn: Callable[..., tuple[Any, str]],\n    get_model_name: Callable[[str], str],\n    build_blocking_result_fn: Callable[[Any, str], dict[str, Any]],\n    update_progress_job_cache_fn: Callable[..., None],\n    update_terminal_job_cache_fn: Callable[..., None],\n    map_status: Callable[[str], str],\n    result_key_prefix: str,\n    result_expire_seconds: int,\n    log_fn: Callable[[str], None] = print,\n) -> None:\n    \"\"\"Execute one queued job end-to-end with success/failure cache updates.\n\n    Args:\n        app_state: FastAPI app state object.\n        store: Job store/cache facade.\n        job_id: Current job identifier.\n        req: Generation request object.\n        ensure_models_initialized_fn: Async startup-guard callback.\n        select_generation_handler_fn: Handler selection callback.\n        get_model_name: Model-name resolver callback.\n        build_blocking_result_fn: Blocking generation callback.\n        update_progress_job_cache_fn: Local cache progress updater.\n        update_terminal_job_cache_fn: Local cache terminal updater.\n        map_status: Status mapping callback.\n        result_key_prefix: Result key namespace prefix.\n        result_expire_seconds: Result cache expiration window.\n        log_fn: Logging callback.\n    \"\"\"\n\n    job_store = app_state.job_store\n    executor = app_state.executor\n\n    await ensure_models_initialized_fn(app_state)\n    job_store.mark_running(job_id)\n    update_progress_job_cache_fn(\n        app_state=app_state,\n        store=store,\n        job_id=job_id,\n        progress=0.01,\n        stage=\"running\",\n        map_status=map_status,\n        result_key_prefix=result_key_prefix,\n        result_expire_seconds=result_expire_seconds,\n    )\n\n    selected_handler, selected_model_name = select_generation_handler_fn(\n        app_state=app_state,\n        requested_model=req.model,\n        get_model_name=get_model_name,\n        job_id=job_id,\n        log_fn=log_fn,\n    )\n\n    def _blocking_generate() -> dict[str, Any]:\n        return build_blocking_result_fn(selected_handler, selected_model_name)\n\n    t0 = time.time()\n    try:\n        loop = asyncio.get_running_loop()\n        result = await loop.run_in_executor(executor, _blocking_generate)\n        job_store.mark_succeeded(job_id, result)\n        update_terminal_job_cache_fn(\n            app_state=app_state,\n            store=store,\n            job_id=job_id,\n            result=result,\n            status=\"succeeded\",\n            map_status=map_status,\n            result_key_prefix=result_key_prefix,\n            result_expire_seconds=result_expire_seconds,\n        )\n    except Exception as exc:\n        error_traceback = traceback.format_exc()\n        log_fn(f\"[API Server] Job {job_id} FAILED: {exc}\")\n        log_fn(f\"[API Server] Traceback:\\n{error_traceback}\")\n        job_store.mark_failed(job_id, error_traceback)\n        update_terminal_job_cache_fn(\n            app_state=app_state,\n            store=store,\n            job_id=job_id,\n            result=None,\n            status=\"failed\",\n            map_status=map_status,\n            result_key_prefix=result_key_prefix,\n            result_expire_seconds=result_expire_seconds,\n        )\n    finally:\n        try:\n            if hasattr(selected_handler, \"_empty_cache\"):\n                selected_handler._empty_cache()\n            else:\n                import torch\n\n                if hasattr(torch, \"mps\") and hasattr(torch.mps, \"empty_cache\"):\n                    torch.mps.empty_cache()\n        except Exception:\n            pass\n        dt = max(0.0, time.time() - t0)\n        async with app_state.stats_lock:\n            app_state.recent_durations.append(dt)\n            if app_state.recent_durations:\n                app_state.avg_job_seconds = sum(app_state.recent_durations) / len(\n                    app_state.recent_durations\n                )\n"
  },
  {
    "path": "acestep/api/job_execution_runtime_test.py",
    "content": "\"\"\"Unit tests for async job execution runtime helper.\"\"\"\n\nfrom __future__ import annotations\n\nimport asyncio\nimport unittest\nfrom collections import deque\nfrom concurrent.futures import ThreadPoolExecutor\nfrom types import SimpleNamespace\nfrom unittest.mock import AsyncMock, MagicMock, patch\n\nfrom acestep.api.job_execution_runtime import run_one_job_runtime\n\n\nclass JobExecutionRuntimeTests(unittest.IsolatedAsyncioTestCase):\n    \"\"\"Behavior tests for queue-worker runtime execution orchestration.\"\"\"\n\n    async def test_run_one_job_runtime_success_updates_terminal_cache(self) -> None:\n        \"\"\"Success path should mark succeeded and write terminal cache success status.\"\"\"\n\n        app_state = SimpleNamespace(\n            job_store=MagicMock(),\n            executor=MagicMock(),\n            stats_lock=asyncio.Lock(),\n            recent_durations=deque(maxlen=50),\n            avg_job_seconds=5.0,\n        )\n        req = SimpleNamespace(model=\"acestep-v15\")\n        selected_handler = SimpleNamespace(_empty_cache=MagicMock())\n        select_generation_handler_fn = MagicMock(return_value=(selected_handler, \"model-A\"))\n        ensure_models_initialized_fn = AsyncMock()\n        update_progress_job_cache_fn = MagicMock()\n        update_terminal_job_cache_fn = MagicMock()\n        build_blocking_result_fn = MagicMock(return_value={\"status_message\": \"Success\"})\n        loop_mock = MagicMock()\n        loop_mock.run_in_executor = AsyncMock(return_value={\"status_message\": \"Success\"})\n\n        with patch(\"acestep.api.job_execution_runtime.asyncio.get_running_loop\", return_value=loop_mock):\n            await run_one_job_runtime(\n                app_state=app_state,\n                store=MagicMock(),\n                job_id=\"job-1\",\n                req=req,\n                ensure_models_initialized_fn=ensure_models_initialized_fn,\n                select_generation_handler_fn=select_generation_handler_fn,\n                get_model_name=MagicMock(return_value=\"m\"),\n                build_blocking_result_fn=build_blocking_result_fn,\n                update_progress_job_cache_fn=update_progress_job_cache_fn,\n                update_terminal_job_cache_fn=update_terminal_job_cache_fn,\n                map_status=MagicMock(return_value=\"running\"),\n                result_key_prefix=\"prefix_\",\n                result_expire_seconds=3600,\n                log_fn=MagicMock(),\n            )\n\n        app_state.job_store.mark_running.assert_called_once_with(\"job-1\")\n        app_state.job_store.mark_succeeded.assert_called_once_with(\n            \"job-1\", {\"status_message\": \"Success\"}\n        )\n        update_progress_job_cache_fn.assert_called_once()\n        update_terminal_job_cache_fn.assert_called_once()\n        self.assertEqual(\"succeeded\", update_terminal_job_cache_fn.call_args.kwargs[\"status\"])\n        selected_handler._empty_cache.assert_called_once()\n        self.assertGreaterEqual(app_state.avg_job_seconds, 0.0)\n\n    async def test_run_one_job_runtime_failure_marks_failed_and_updates_cache(self) -> None:\n        \"\"\"Failure path should mark failed and write terminal cache failed status.\"\"\"\n\n        app_state = SimpleNamespace(\n            job_store=MagicMock(),\n            executor=MagicMock(),\n            stats_lock=asyncio.Lock(),\n            recent_durations=deque(maxlen=50),\n            avg_job_seconds=5.0,\n        )\n        req = SimpleNamespace(model=\"acestep-v15\")\n        selected_handler = SimpleNamespace(_empty_cache=MagicMock())\n        select_generation_handler_fn = MagicMock(return_value=(selected_handler, \"model-A\"))\n        ensure_models_initialized_fn = AsyncMock()\n        update_progress_job_cache_fn = MagicMock()\n        update_terminal_job_cache_fn = MagicMock()\n        build_blocking_result_fn = MagicMock(side_effect=RuntimeError(\"boom\"))\n\n        async def _run_in_executor(_executor, fn):\n            return fn()\n\n        loop_mock = MagicMock()\n        loop_mock.run_in_executor = AsyncMock(side_effect=_run_in_executor)\n        log_fn = MagicMock()\n\n        with patch(\"acestep.api.job_execution_runtime.asyncio.get_running_loop\", return_value=loop_mock):\n            await run_one_job_runtime(\n                app_state=app_state,\n                store=MagicMock(),\n                job_id=\"job-2\",\n                req=req,\n                ensure_models_initialized_fn=ensure_models_initialized_fn,\n                select_generation_handler_fn=select_generation_handler_fn,\n                get_model_name=MagicMock(return_value=\"m\"),\n                build_blocking_result_fn=build_blocking_result_fn,\n                update_progress_job_cache_fn=update_progress_job_cache_fn,\n                update_terminal_job_cache_fn=update_terminal_job_cache_fn,\n                map_status=MagicMock(return_value=\"failed\"),\n                result_key_prefix=\"prefix_\",\n                result_expire_seconds=3600,\n                log_fn=log_fn,\n            )\n\n        app_state.job_store.mark_failed.assert_called_once()\n        self.assertEqual(\"failed\", update_terminal_job_cache_fn.call_args.kwargs[\"status\"])\n        selected_handler._empty_cache.assert_called_once()\n        self.assertTrue(any(\"FAILED\" in str(call.args[0]) for call in log_fn.call_args_list))\n\n    async def test_run_one_job_runtime_integration_uses_real_executor_and_wires_handler(self) -> None:\n        \"\"\"Integration-style check with real run_in_executor and callback wiring.\"\"\"\n\n        executor = ThreadPoolExecutor(max_workers=1)\n        try:\n            app_state = SimpleNamespace(\n                job_store=MagicMock(),\n                executor=executor,\n                stats_lock=asyncio.Lock(),\n                recent_durations=deque(maxlen=50),\n                avg_job_seconds=5.0,\n            )\n            req = SimpleNamespace(model=\"acestep-v15\")\n            selected_handler = SimpleNamespace(_empty_cache=MagicMock())\n            select_generation_handler_fn = MagicMock(return_value=(selected_handler, \"model-A\"))\n            ensure_models_initialized_fn = AsyncMock()\n            update_progress_job_cache_fn = MagicMock()\n            update_terminal_job_cache_fn = MagicMock()\n            captured = {}\n\n            def _build_blocking_result(handler, model_name):\n                captured[\"handler\"] = handler\n                captured[\"model_name\"] = model_name\n                return {\"status_message\": \"Success\"}\n\n            await run_one_job_runtime(\n                app_state=app_state,\n                store=MagicMock(),\n                job_id=\"job-int-1\",\n                req=req,\n                ensure_models_initialized_fn=ensure_models_initialized_fn,\n                select_generation_handler_fn=select_generation_handler_fn,\n                get_model_name=MagicMock(return_value=\"m\"),\n                build_blocking_result_fn=_build_blocking_result,\n                update_progress_job_cache_fn=update_progress_job_cache_fn,\n                update_terminal_job_cache_fn=update_terminal_job_cache_fn,\n                map_status=MagicMock(return_value=\"running\"),\n                result_key_prefix=\"prefix_\",\n                result_expire_seconds=3600,\n                log_fn=MagicMock(),\n            )\n\n            self.assertIs(captured[\"handler\"], selected_handler)\n            self.assertEqual(\"model-A\", captured[\"model_name\"])\n            app_state.job_store.mark_succeeded.assert_called_once_with(\n                \"job-int-1\", {\"status_message\": \"Success\"}\n            )\n            update_progress_job_cache_fn.assert_called_once()\n            update_terminal_job_cache_fn.assert_called_once()\n            selected_handler._empty_cache.assert_called_once()\n        finally:\n            executor.shutdown(wait=True, cancel_futures=True)\n\n\nif __name__ == \"__main__\":\n    unittest.main()\n"
  },
  {
    "path": "acestep/api/job_generation_runtime.py",
    "content": "\"\"\"Runtime helpers for executing generation runs and aggregating outputs.\"\"\"\n\nfrom __future__ import annotations\n\nfrom typing import Any, Callable\n\n\ndef run_generation_with_optional_sequential_cover_mode(\n    *,\n    req: Any,\n    job_id: str,\n    handler_device: str,\n    config: Any,\n    params: Any,\n    dit_handler: Any,\n    llm_handler: Any,\n    temp_audio_dir: str,\n    generate_music_fn: Callable[..., Any],\n    progress_cb: Callable[[float, str], None],\n    log_fn: Callable[[str], None] = print,\n) -> Any:\n    \"\"\"Run music generation and aggregate outputs across sequential MPS cover slices.\n\n    Args:\n        req: Generation request object.\n        job_id: Job identifier for progress logs.\n        handler_device: Device string for selected handler.\n        config: GenerationConfig instance.\n        params: GenerationParams instance.\n        dit_handler: Active DiT handler.\n        llm_handler: Optional active LLM handler.\n        temp_audio_dir: Output directory for generated audio.\n        generate_music_fn: Generation execution callback.\n        progress_cb: Progress callback receiving value and optional description.\n        log_fn: Logging callback for status messages.\n\n    Returns:\n        Any: Aggregated successful generation result object.\n\n    Raises:\n        RuntimeError: If generation fails or returns no results.\n    \"\"\"\n\n    sequential_runs = 1\n    if req.task_type == \"cover\" and handler_device == \"mps\":\n        if config.batch_size is not None and config.batch_size > 1:\n            sequential_runs = int(config.batch_size)\n            config.batch_size = 1\n            log_fn(\n                f\"[API Server] Job {job_id}: MPS cover sequential mode enabled \"\n                f\"(runs={sequential_runs})\"\n            )\n\n    def _progress_for_slice(start: float, end: float) -> Callable[[float, str], None]:\n        base = {\"seen\": False, \"value\": 0.0}\n\n        def _cb(value: float, desc: str = \"\") -> None:\n            try:\n                value_f = max(0.0, min(1.0, float(value)))\n            except Exception:\n                value_f = 0.0\n            if not base[\"seen\"]:\n                base[\"seen\"] = True\n                base[\"value\"] = value_f\n            if value_f <= base[\"value\"]:\n                norm = 0.0\n            else:\n                denom = max(1e-6, 1.0 - base[\"value\"])\n                norm = min(1.0, (value_f - base[\"value\"]) / denom)\n            mapped = start + (end - start) * norm\n            progress_cb(mapped, desc=desc)\n\n        return _cb\n\n    aggregated_result = None\n    all_audios = []\n    for run_idx in range(sequential_runs):\n        if sequential_runs > 1:\n            log_fn(f\"[API Server] Job {job_id}: Sequential cover run {run_idx + 1}/{sequential_runs}\")\n        if sequential_runs > 1:\n            start = run_idx / sequential_runs\n            end = (run_idx + 1) / sequential_runs\n            run_progress_cb = _progress_for_slice(start, end)\n        else:\n            run_progress_cb = progress_cb\n\n        result = generate_music_fn(\n            dit_handler=dit_handler,\n            llm_handler=llm_handler,\n            params=params,\n            config=config,\n            save_dir=temp_audio_dir,\n            progress=run_progress_cb,\n        )\n        if not result.success:\n            raise RuntimeError(f\"Music generation failed: {result.error or result.status_message}\")\n        if aggregated_result is None:\n            aggregated_result = result\n        all_audios.extend(result.audios)\n\n    if aggregated_result is None:\n        raise RuntimeError(\"Music generation failed: no results\")\n    aggregated_result.audios = all_audios\n    if not aggregated_result.success:\n        raise RuntimeError(\n            f\"Music generation failed: {aggregated_result.error or aggregated_result.status_message}\"\n        )\n    return aggregated_result\n"
  },
  {
    "path": "acestep/api/job_generation_runtime_test.py",
    "content": "\"\"\"Unit tests for generation runtime execution helper.\"\"\"\n\nfrom __future__ import annotations\n\nimport unittest\nfrom types import SimpleNamespace\nfrom unittest.mock import MagicMock\n\nfrom acestep.api.job_generation_runtime import run_generation_with_optional_sequential_cover_mode\n\n\nclass JobGenerationRuntimeTests(unittest.TestCase):\n    \"\"\"Behavior tests for sequential generation and aggregation logic.\"\"\"\n\n    def test_runs_once_when_not_mps_cover(self) -> None:\n        \"\"\"Non-MPS/cover mode should invoke generation once with original batch size.\"\"\"\n\n        req = SimpleNamespace(task_type=\"text2music\")\n        config = SimpleNamespace(batch_size=2)\n        result = SimpleNamespace(success=True, audios=[{\"audio_path\": \"a.wav\"}], error=None, status_message=\"\")\n        generate_music_fn = MagicMock(return_value=result)\n        progress_cb = MagicMock()\n\n        out = run_generation_with_optional_sequential_cover_mode(\n            req=req,\n            job_id=\"job-1\",\n            handler_device=\"cuda\",\n            config=config,\n            params=SimpleNamespace(),\n            dit_handler=MagicMock(),\n            llm_handler=MagicMock(),\n            temp_audio_dir=\"tmp\",\n            generate_music_fn=generate_music_fn,\n            progress_cb=progress_cb,\n            log_fn=MagicMock(),\n        )\n\n        self.assertIs(out, result)\n        self.assertEqual(1, generate_music_fn.call_count)\n        self.assertEqual(2, config.batch_size)\n\n    def test_splits_cover_mps_batch_into_sequential_runs(self) -> None:\n        \"\"\"MPS cover mode should run sequentially and aggregate audios.\"\"\"\n\n        req = SimpleNamespace(task_type=\"cover\")\n        config = SimpleNamespace(batch_size=2)\n        result1 = SimpleNamespace(success=True, audios=[{\"audio_path\": \"a.wav\"}], error=None, status_message=\"\")\n        result2 = SimpleNamespace(success=True, audios=[{\"audio_path\": \"b.wav\"}], error=None, status_message=\"\")\n        generate_music_fn = MagicMock(side_effect=[result1, result2])\n        progress_cb = MagicMock()\n        log_fn = MagicMock()\n\n        out = run_generation_with_optional_sequential_cover_mode(\n            req=req,\n            job_id=\"job-2\",\n            handler_device=\"mps\",\n            config=config,\n            params=SimpleNamespace(),\n            dit_handler=MagicMock(),\n            llm_handler=MagicMock(),\n            temp_audio_dir=\"tmp\",\n            generate_music_fn=generate_music_fn,\n            progress_cb=progress_cb,\n            log_fn=log_fn,\n        )\n\n        self.assertEqual(2, generate_music_fn.call_count)\n        self.assertEqual(1, config.batch_size)\n        self.assertEqual(2, len(out.audios))\n        self.assertTrue(any(\"Sequential cover run\" in str(call.args[0]) for call in log_fn.call_args_list))\n\n    def test_raises_when_generation_fails(self) -> None:\n        \"\"\"Generation failure should raise with original error message format.\"\"\"\n\n        req = SimpleNamespace(task_type=\"text2music\")\n        config = SimpleNamespace(batch_size=1)\n        result = SimpleNamespace(success=False, audios=[], error=\"boom\", status_message=\"\")\n        generate_music_fn = MagicMock(return_value=result)\n\n        with self.assertRaisesRegex(RuntimeError, \"Music generation failed: boom\"):\n            run_generation_with_optional_sequential_cover_mode(\n                req=req,\n                job_id=\"job-3\",\n                handler_device=\"cuda\",\n                config=config,\n                params=SimpleNamespace(),\n                dit_handler=MagicMock(),\n                llm_handler=MagicMock(),\n                temp_audio_dir=\"tmp\",\n                generate_music_fn=generate_music_fn,\n                progress_cb=MagicMock(),\n                log_fn=MagicMock(),\n            )\n\n\nif __name__ == \"__main__\":\n    unittest.main()\n"
  },
  {
    "path": "acestep/api/job_generation_setup.py",
    "content": "\"\"\"Generation parameter/config assembly helpers for API job execution.\"\"\"\n\nfrom __future__ import annotations\n\nfrom dataclasses import dataclass\nfrom typing import Any, Callable, Optional\n\nfrom acestep.inference import GenerationConfig, GenerationParams\n\n# Sensible fallback when the API receives a null/missing audio_duration.\n# This prevents -1.0/None from propagating into the LLM and DiT, which\n# can cause unconstrained code generation and downstream tensor mismatches.\n_API_DEFAULT_DURATION_SECONDS: float = 120.0\n\n\n@dataclass\nclass GenerationSetup:\n    \"\"\"Prepared generation objects for a single API job.\"\"\"\n\n    params: GenerationParams\n    config: GenerationConfig\n\n\ndef _resolve_instruction(\n    *,\n    req: Any,\n    default_dit_instruction: str,\n    task_instructions: dict[str, str],\n) -> str:\n    \"\"\"Resolve task-specific instruction text for generation.\n\n    Args:\n        req: Request object with task_type and optional track fields.\n        default_dit_instruction: Default instruction fallback.\n        task_instructions: Task-type instruction templates.\n\n    Returns:\n        str: Instruction to pass to generation.\n    \"\"\"\n\n    instruction_to_use = req.instruction\n    if instruction_to_use == default_dit_instruction and req.task_type in task_instructions:\n        raw_instruction = task_instructions[req.task_type]\n\n        if req.task_type == \"complete\":\n            if req.track_classes:\n                classes_str = \" | \".join([str(track).upper() for track in req.track_classes])\n                instruction_to_use = raw_instruction.format(TRACK_CLASSES=classes_str)\n            else:\n                instruction_to_use = task_instructions.get(\"complete_default\", raw_instruction)\n        elif \"{TRACK_NAME}\" in raw_instruction:\n            if req.track_name:\n                instruction_to_use = raw_instruction.format(TRACK_NAME=req.track_name.upper())\n            else:\n                # Fall back to default instruction when track_name is missing\n                # to avoid sending literal {TRACK_NAME} placeholder to the model\n                default_key = f\"{req.task_type}_default\"\n                instruction_to_use = task_instructions.get(default_key, raw_instruction)\n        else:\n            instruction_to_use = raw_instruction\n\n    return instruction_to_use\n\n\ndef _resolve_generation_seeds(req: Any) -> Optional[list[int]]:\n    \"\"\"Resolve request seed input into GenerationConfig.seeds format.\n\n    Args:\n        req: Request object with use_random_seed and seed values.\n\n    Returns:\n        Optional[list[int]]: Seed list when explicit deterministic seeds are usable.\n    \"\"\"\n\n    resolved_seeds = None\n    if not req.use_random_seed and req.seed is not None:\n        if isinstance(req.seed, int):\n            if req.seed >= 0:\n                resolved_seeds = [req.seed]\n        elif isinstance(req.seed, str):\n            resolved_seeds = []\n            for value in req.seed.split(\",\"):\n                value = value.strip()\n                if value and value != \"-1\":\n                    try:\n                        resolved_seeds.append(int(float(value)))\n                    except (ValueError, TypeError):\n                        pass\n            if not resolved_seeds:\n                resolved_seeds = None\n    return resolved_seeds\n\n\ndef build_generation_setup(\n    *,\n    req: Any,\n    caption: str,\n    global_caption: str = \"\",\n    lyrics: str,\n    bpm: Any,\n    key_scale: Any,\n    time_signature: Any,\n    audio_duration: Any,\n    thinking: bool,\n    sample_mode: bool,\n    format_has_duration: bool,\n    use_cot_caption: bool,\n    use_cot_language: bool,\n    lm_top_k: int,\n    lm_top_p: float,\n    parse_timesteps: Callable[[Optional[str]], Optional[list[float]]],\n    is_instrumental: Callable[[str], bool],\n    default_dit_instruction: str,\n    task_instructions: dict[str, str],\n) -> GenerationSetup:\n    \"\"\"Build GenerationParams and GenerationConfig from request and prepared LLM inputs.\n\n    Args:\n        req: Request object for music generation.\n        caption: Final caption text to generate from.\n        lyrics: Final lyrics text to generate from.\n        bpm: Optional BPM metadata.\n        key_scale: Optional keyscale metadata.\n        time_signature: Optional time signature metadata.\n        audio_duration: Optional target duration metadata.\n        thinking: Whether LM code generation mode is enabled.\n        sample_mode: Whether sample mode generated metadata already.\n        format_has_duration: Whether format mode already produced duration metadata.\n        use_cot_caption: Optional CoT caption enhancement flag.\n        use_cot_language: Optional CoT language enhancement flag.\n        lm_top_k: Normalized LM top-k sampling value.\n        lm_top_p: Normalized LM top-p sampling value.\n        parse_timesteps: Timesteps parsing callback.\n        is_instrumental: Instrumental detection callback.\n        default_dit_instruction: Default instruction constant.\n        task_instructions: Task instruction mapping.\n\n    Returns:\n        GenerationSetup: Prepared params/config pair for `generate_music`.\n    \"\"\"\n\n    parsed_timesteps = parse_timesteps(req.timesteps)\n    instruction_to_use = _resolve_instruction(\n        req=req,\n        default_dit_instruction=default_dit_instruction,\n        task_instructions=task_instructions,\n    )\n\n    params = GenerationParams(\n        task_type=req.task_type,\n        instruction=instruction_to_use,\n        reference_audio=req.reference_audio_path,\n        src_audio=req.src_audio_path,\n        audio_codes=req.audio_code_string if req.audio_code_string else \"\",\n        caption=caption,\n        global_caption=global_caption,\n        lyrics=lyrics,\n        instrumental=is_instrumental(lyrics),\n        vocal_language=req.vocal_language,\n        bpm=bpm,\n        keyscale=key_scale,\n        timesignature=time_signature,\n        duration=audio_duration if audio_duration else _API_DEFAULT_DURATION_SECONDS,\n        inference_steps=req.inference_steps,\n        seed=req.seed,\n        guidance_scale=req.guidance_scale,\n        use_adg=req.use_adg,\n        cfg_interval_start=req.cfg_interval_start,\n        cfg_interval_end=req.cfg_interval_end,\n        shift=req.shift,\n        infer_method=req.infer_method,\n        timesteps=parsed_timesteps,\n        repainting_start=req.repainting_start,\n        repainting_end=req.repainting_end if req.repainting_end else -1,\n        chunk_mask_mode=getattr(req, \"chunk_mask_mode\", \"auto\"),\n        repaint_latent_crossfade_frames=getattr(\n            req, \"repaint_latent_crossfade_frames\", 10,\n        ),\n        repaint_wav_crossfade_sec=getattr(\n            req, \"repaint_wav_crossfade_sec\", 0.0,\n        ),\n        repaint_mode=getattr(req, \"repaint_mode\", \"balanced\"),\n        repaint_strength=getattr(req, \"repaint_strength\", 0.5),\n        audio_cover_strength=req.audio_cover_strength,\n        cover_noise_strength=req.cover_noise_strength,\n        thinking=thinking,\n        lm_temperature=req.lm_temperature,\n        lm_cfg_scale=req.lm_cfg_scale,\n        lm_top_k=lm_top_k,\n        lm_top_p=lm_top_p,\n        lm_negative_prompt=req.lm_negative_prompt,\n        use_cot_metas=not sample_mode and not format_has_duration,\n        use_cot_caption=use_cot_caption,\n        use_cot_language=use_cot_language,\n        use_constrained_decoding=True,\n    )\n\n    batch_size = req.batch_size if req.batch_size is not None else 2\n    config = GenerationConfig(\n        batch_size=batch_size,\n        allow_lm_batch=req.allow_lm_batch,\n        use_random_seed=req.use_random_seed,\n        seeds=_resolve_generation_seeds(req),\n        audio_format=req.audio_format,\n        constrained_decoding_debug=req.constrained_decoding_debug,\n    )\n\n    return GenerationSetup(params=params, config=config)\n"
  },
  {
    "path": "acestep/api/job_generation_setup_test.py",
    "content": "\"\"\"Unit tests for generation setup assembly helpers.\"\"\"\n\nfrom __future__ import annotations\n\nimport unittest\nfrom types import SimpleNamespace\n\nfrom acestep.api.job_generation_setup import build_generation_setup\n\n\ndef _base_req() -> SimpleNamespace:\n    return SimpleNamespace(\n        task_type=\"text2music\",\n        instruction=\"default instruction\",\n        reference_audio_path=\"\",\n        src_audio_path=\"\",\n        vocal_language=\"en\",\n        inference_steps=25,\n        seed=None,\n        guidance_scale=4.5,\n        use_adg=False,\n        cfg_interval_start=0.0,\n        cfg_interval_end=1.0,\n        shift=0.0,\n        infer_method=\"euler\",\n        timesteps=\"\",\n        repainting_start=0.0,\n        repainting_end=-1,\n        audio_cover_strength=0.0,\n        cover_noise_strength=0.0,\n        audio_code_string=\"\",\n        lm_temperature=0.85,\n        lm_cfg_scale=2.5,\n        lm_negative_prompt=\"\",\n        batch_size=None,\n        allow_lm_batch=False,\n        use_random_seed=True,\n        audio_format=\"wav\",\n        constrained_decoding_debug=False,\n        track_classes=None,\n        track_name=\"\",\n    )\n\n\nclass JobGenerationSetupTests(unittest.TestCase):\n    \"\"\"Behavioral tests for generation setup decomposition.\"\"\"\n\n    def test_build_generation_setup_applies_complete_instruction_template(self) -> None:\n        \"\"\"Complete task should inject uppercased track classes into instruction.\"\"\"\n\n        req = _base_req()\n        req.task_type = \"complete\"\n        req.track_classes = [\"Drums\", \"Bass\"]\n        task_instructions = {\n            \"complete\": \"Complete with {TRACK_CLASSES}\",\n            \"complete_default\": \"Complete default\",\n        }\n        setup = build_generation_setup(\n            req=req,\n            caption=\"cap\",\n            lyrics=\"lyr\",\n            bpm=120,\n            key_scale=\"C major\",\n            time_signature=\"4/4\",\n            audio_duration=10.0,\n            thinking=False,\n            sample_mode=False,\n            format_has_duration=False,\n            use_cot_caption=True,\n            use_cot_language=True,\n            lm_top_k=0,\n            lm_top_p=0.9,\n            parse_timesteps=lambda _value: None,\n            is_instrumental=lambda _lyrics: False,\n            default_dit_instruction=\"default instruction\",\n            task_instructions=task_instructions,\n        )\n\n        self.assertEqual(\"Complete with DRUMS | BASS\", setup.params.instruction)\n        self.assertTrue(setup.params.use_cot_metas)\n\n    def test_build_generation_setup_applies_track_name_template(self) -> None:\n        \"\"\"Extract/lego style template should inject uppercased track name.\"\"\"\n\n        req = _base_req()\n        req.task_type = \"extract\"\n        req.track_name = \"vocals\"\n        task_instructions = {\"extract\": \"Extract {TRACK_NAME}\"}\n        setup = build_generation_setup(\n            req=req,\n            caption=\"cap\",\n            lyrics=\"lyr\",\n            bpm=None,\n            key_scale=\"\",\n            time_signature=\"\",\n            audio_duration=None,\n            thinking=True,\n            sample_mode=True,\n            format_has_duration=True,\n            use_cot_caption=False,\n            use_cot_language=False,\n            lm_top_k=10,\n            lm_top_p=0.8,\n            parse_timesteps=lambda _value: [0.1, 0.5],\n            is_instrumental=lambda _lyrics: True,\n            default_dit_instruction=\"default instruction\",\n            task_instructions=task_instructions,\n        )\n\n        self.assertEqual(\"Extract VOCALS\", setup.params.instruction)\n        self.assertFalse(setup.params.use_cot_metas)\n        self.assertEqual([0.1, 0.5], setup.params.timesteps)\n        # When audio_duration is None, the API default (120s) is used\n        # instead of -1.0 to prevent unconstrained generation (issue #797).\n        from acestep.api.job_generation_setup import _API_DEFAULT_DURATION_SECONDS\n        self.assertEqual(_API_DEFAULT_DURATION_SECONDS, setup.params.duration)\n\n    def test_build_generation_setup_resolves_seed_list_from_string(self) -> None:\n        \"\"\"Seed strings should keep valid values and drop invalid or sentinel values.\"\"\"\n\n        req = _base_req()\n        req.use_random_seed = False\n        req.seed = \"12, -1, 13.0, bad\"\n        setup = build_generation_setup(\n            req=req,\n            caption=\"cap\",\n            lyrics=\"lyr\",\n            bpm=None,\n            key_scale=\"\",\n            time_signature=\"\",\n            audio_duration=None,\n            thinking=False,\n            sample_mode=False,\n            format_has_duration=False,\n            use_cot_caption=False,\n            use_cot_language=False,\n            lm_top_k=0,\n            lm_top_p=0.9,\n            parse_timesteps=lambda _value: None,\n            is_instrumental=lambda _lyrics: False,\n            default_dit_instruction=\"default instruction\",\n            task_instructions={},\n        )\n\n        self.assertEqual([12, 13], setup.config.seeds)\n\n    def test_build_generation_setup_forwards_audio_codes_and_cover_noise_strength(self) -> None:\n        \"\"\"Audio code hints and cover-noise strength should be forwarded unchanged.\"\"\"\n\n        req = _base_req()\n        req.audio_code_string = \"<|audio_code_42|>\"\n        req.cover_noise_strength = 0.42\n        setup = build_generation_setup(\n            req=req,\n            caption=\"cap\",\n            lyrics=\"lyr\",\n            bpm=None,\n            key_scale=\"\",\n            time_signature=\"\",\n            audio_duration=None,\n            thinking=False,\n            sample_mode=False,\n            format_has_duration=False,\n            use_cot_caption=False,\n            use_cot_language=False,\n            lm_top_k=0,\n            lm_top_p=0.9,\n            parse_timesteps=lambda _value: None,\n            is_instrumental=lambda _lyrics: False,\n            default_dit_instruction=\"default instruction\",\n            task_instructions={},\n        )\n\n        self.assertEqual(\"<|audio_code_42|>\", setup.params.audio_codes)\n        self.assertAlmostEqual(0.42, setup.params.cover_noise_strength)\n\n\nif __name__ == \"__main__\":\n    unittest.main()\n"
  },
  {
    "path": "acestep/api/job_llm_preparation.py",
    "content": "\"\"\"Compatibility facade for LLM request preparation helpers.\"\"\"\n\nfrom acestep.api.llm_generation_inputs import PreparedLlmInputs, prepare_llm_generation_inputs\nfrom acestep.api.llm_readiness import ensure_llm_ready_for_request\n\n__all__ = [\n    \"PreparedLlmInputs\",\n    \"ensure_llm_ready_for_request\",\n    \"prepare_llm_generation_inputs\",\n]\n"
  },
  {
    "path": "acestep/api/job_llm_preparation_test.py",
    "content": "\"\"\"Unit tests for LLM readiness and request-input preparation helpers.\"\"\"\n\nfrom __future__ import annotations\n\nimport os\nimport unittest\nfrom types import SimpleNamespace\nfrom unittest.mock import MagicMock, patch\n\nfrom acestep.api.job_llm_preparation import (\n    ensure_llm_ready_for_request,\n    prepare_llm_generation_inputs,\n)\n\n\nclass JobLlmPreparationTests(unittest.TestCase):\n    \"\"\"Behavior tests for LLM initialization guard and input preparation.\"\"\"\n\n    def _base_req(self) -> SimpleNamespace:\n        return SimpleNamespace(\n            lm_model_path=\"\",\n            lm_backend=\"\",\n            lm_temperature=0.85,\n            lm_top_k=0,\n            lm_top_p=0.9,\n            thinking=False,\n            sample_mode=False,\n            sample_query=\"\",\n            use_format=False,\n            use_cot_caption=False,\n            use_cot_language=False,\n            full_analysis_only=False,\n            prompt=\"p\",\n            lyrics=\"l\",\n            bpm=None,\n            key_scale=\"\",\n            time_signature=\"\",\n            audio_duration=None,\n            task_type=\"text2music\",\n            vocal_language=\"en\",\n        )\n\n    def test_ensure_llm_ready_for_request_respects_disabled_env(self) -> None:\n        \"\"\"LLM guard should set lazy-load-disabled error when ACESTEP_INIT_LLM=false.\"\"\"\n\n        req = self._base_req()\n        app_state = SimpleNamespace(\n            _llm_init_lock=__import__(\"threading\").Lock(),\n            _llm_initialized=False,\n            _llm_init_error=None,\n            _llm_lazy_load_disabled=False,\n        )\n        llm = MagicMock()\n\n        with patch.dict(os.environ, {\"ACESTEP_INIT_LLM\": \"false\"}, clear=True):\n            ensure_llm_ready_for_request(\n                app_state=app_state,\n                llm_handler=llm,\n                req=req,\n                get_project_root=MagicMock(return_value=\"k:/repo\"),\n                get_model_name=MagicMock(return_value=\"lm\"),\n                ensure_model_downloaded=MagicMock(),\n                env_bool=lambda _name, default: default,\n                log_fn=MagicMock(),\n            )\n\n        self.assertTrue(app_state._llm_lazy_load_disabled)\n        self.assertIsNotNone(app_state._llm_init_error)\n        llm.initialize.assert_not_called()\n\n    def test_prepare_llm_generation_inputs_updates_values_from_sample_mode(self) -> None:\n        \"\"\"Sample mode preparation should replace prompt/lyrics/meta fields from sample output.\"\"\"\n\n        req = self._base_req()\n        req.sample_mode = True\n        req.sample_query = \"energetic song\"\n        sample_result = SimpleNamespace(\n            success=True,\n            caption=\"generated caption\",\n            lyrics=\"generated lyrics\",\n            bpm=128,\n            keyscale=\"C major\",\n            timesignature=\"4/4\",\n            duration=12.0,\n        )\n        app_state = SimpleNamespace(\n            _llm_initialized=True,\n            _llm_init_error=None,\n            _llm_lazy_load_disabled=False,\n        )\n        llm = MagicMock()\n\n        prepared = prepare_llm_generation_inputs(\n            app_state=app_state,\n            llm_handler=llm,\n            req=req,\n            selected_handler_device=\"cuda\",\n            parse_description_hints=MagicMock(return_value=(\"en\", False)),\n            create_sample_fn=MagicMock(return_value=sample_result),\n            format_sample_fn=MagicMock(),\n            ensure_llm_ready_fn=MagicMock(),\n            log_fn=MagicMock(),\n        )\n\n        self.assertEqual(\"generated caption\", prepared.caption)\n        self.assertEqual(\"generated lyrics\", prepared.lyrics)\n        self.assertEqual(128, prepared.bpm)\n        self.assertEqual(\"C major\", prepared.key_scale)\n        self.assertEqual(\"4/4\", prepared.time_signature)\n        self.assertEqual(12.0, prepared.audio_duration)\n\n    def test_prepare_llm_generation_inputs_disables_optional_cot_when_llm_unavailable(self) -> None:\n        \"\"\"Optional CoT flags should auto-disable when LLM is unavailable but not required.\"\"\"\n\n        req = self._base_req()\n        req.use_cot_caption = True\n        req.use_cot_language = True\n        app_state = SimpleNamespace(\n            _llm_initialized=False,\n            _llm_init_error=\"failed\",\n            _llm_lazy_load_disabled=False,\n        )\n        llm = MagicMock()\n\n        prepared = prepare_llm_generation_inputs(\n            app_state=app_state,\n            llm_handler=llm,\n            req=req,\n            selected_handler_device=\"cuda\",\n            parse_description_hints=MagicMock(),\n            create_sample_fn=MagicMock(),\n            format_sample_fn=MagicMock(),\n            ensure_llm_ready_fn=MagicMock(),\n            log_fn=MagicMock(),\n        )\n\n        self.assertFalse(prepared.use_cot_caption)\n        self.assertFalse(prepared.use_cot_language)\n\n\nif __name__ == \"__main__\":\n    unittest.main()\n"
  },
  {
    "path": "acestep/api/job_model_selection.py",
    "content": "\"\"\"Model selection helpers for per-job DiT handler routing.\"\"\"\n\nfrom __future__ import annotations\n\nfrom typing import Any, Callable, Optional, Tuple\n\n\ndef select_generation_handler(\n    *,\n    app_state: Any,\n    requested_model: Optional[str],\n    get_model_name: Callable[[str], str],\n    job_id: str,\n    log_fn: Callable[[str], None] = print,\n) -> Tuple[Any, str]:\n    \"\"\"Resolve the handler/model name for a generation job request.\n\n    Args:\n        app_state: Application state object containing primary/secondary/third handlers and config paths.\n        requested_model: Optional requested model name from request payload.\n        get_model_name: Callable that normalizes config path to display model name.\n        job_id: Current job identifier for log messages.\n        log_fn: Logger callable used for parity with existing print-based logs.\n\n    Returns:\n        Tuple of ``(selected_handler, selected_model_name)``.\n    \"\"\"\n\n    selected_handler = app_state.handler\n    selected_model_name = get_model_name(app_state._config_path)\n\n    if not requested_model:\n        return selected_handler, selected_model_name\n\n    model_matched = False\n\n    if app_state.handler2 and getattr(app_state, \"_initialized2\", False):\n        model2_name = get_model_name(app_state._config_path2)\n        if requested_model == model2_name:\n            selected_handler = app_state.handler2\n            selected_model_name = model2_name\n            model_matched = True\n            log_fn(f\"[API Server] Job {job_id}: Using second model: {model2_name}\")\n\n    if not model_matched and app_state.handler3 and getattr(app_state, \"_initialized3\", False):\n        model3_name = get_model_name(app_state._config_path3)\n        if requested_model == model3_name:\n            selected_handler = app_state.handler3\n            selected_model_name = model3_name\n            model_matched = True\n            log_fn(f\"[API Server] Job {job_id}: Using third model: {model3_name}\")\n\n    if not model_matched:\n        available_models = [get_model_name(app_state._config_path)]\n        if app_state.handler2 and getattr(app_state, \"_initialized2\", False):\n            available_models.append(get_model_name(app_state._config_path2))\n        if app_state.handler3 and getattr(app_state, \"_initialized3\", False):\n            available_models.append(get_model_name(app_state._config_path3))\n        log_fn(\n            f\"[API Server] Job {job_id}: Model '{requested_model}' not found in \"\n            f\"{available_models}, using primary: {selected_model_name}\"\n        )\n\n    return selected_handler, selected_model_name\n"
  },
  {
    "path": "acestep/api/job_model_selection_test.py",
    "content": "\"\"\"Unit tests for per-job model handler selection helper.\"\"\"\n\nfrom __future__ import annotations\n\nimport unittest\nfrom types import SimpleNamespace\nfrom unittest.mock import MagicMock\n\nfrom acestep.api.job_model_selection import select_generation_handler\n\n\nclass JobModelSelectionTests(unittest.TestCase):\n    \"\"\"Behavior tests for model routing and fallback logging.\"\"\"\n\n    def _app_state(self) -> SimpleNamespace:\n        return SimpleNamespace(\n            handler=MagicMock(name=\"primary\"),\n            handler2=MagicMock(name=\"second\"),\n            handler3=MagicMock(name=\"third\"),\n            _initialized2=True,\n            _initialized3=True,\n            _config_path=\"acestep-v15-primary\",\n            _config_path2=\"acestep-v15-second\",\n            _config_path3=\"acestep-v15-third\",\n        )\n\n    def test_select_generation_handler_defaults_to_primary(self) -> None:\n        \"\"\"No requested model should return primary handler/model.\"\"\"\n\n        app_state = self._app_state()\n        handler, model = select_generation_handler(\n            app_state=app_state,\n            requested_model=None,\n            get_model_name=lambda value: value.split(\"-\")[-1] if value else \"\",\n            job_id=\"job-1\",\n            log_fn=MagicMock(),\n        )\n\n        self.assertIs(handler, app_state.handler)\n        self.assertEqual(\"primary\", model)\n\n    def test_select_generation_handler_uses_second_model_when_requested(self) -> None:\n        \"\"\"Requested model should route to second handler when initialized and matched.\"\"\"\n\n        app_state = self._app_state()\n        logger = MagicMock()\n        handler, model = select_generation_handler(\n            app_state=app_state,\n            requested_model=\"second\",\n            get_model_name=lambda value: value.split(\"-\")[-1] if value else \"\",\n            job_id=\"job-2\",\n            log_fn=logger,\n        )\n\n        self.assertIs(handler, app_state.handler2)\n        self.assertEqual(\"second\", model)\n        logger.assert_called_once()\n\n    def test_select_generation_handler_uses_third_model_when_second_not_matched(self) -> None:\n        \"\"\"Requested model should route to third handler when it is the first match.\"\"\"\n\n        app_state = self._app_state()\n        logger = MagicMock()\n        handler, model = select_generation_handler(\n            app_state=app_state,\n            requested_model=\"third\",\n            get_model_name=lambda value: value.split(\"-\")[-1] if value else \"\",\n            job_id=\"job-3\",\n            log_fn=logger,\n        )\n\n        self.assertIs(handler, app_state.handler3)\n        self.assertEqual(\"third\", model)\n        logger.assert_called_once()\n\n    def test_select_generation_handler_logs_fallback_on_unknown_model(self) -> None:\n        \"\"\"Unknown requested model should preserve fallback-to-primary behavior.\"\"\"\n\n        app_state = self._app_state()\n        logger = MagicMock()\n        handler, model = select_generation_handler(\n            app_state=app_state,\n            requested_model=\"unknown\",\n            get_model_name=lambda value: value.split(\"-\")[-1] if value else \"\",\n            job_id=\"job-4\",\n            log_fn=logger,\n        )\n\n        self.assertIs(handler, app_state.handler)\n        self.assertEqual(\"primary\", model)\n        logger.assert_called_once()\n        self.assertIn(\"not found\", logger.call_args[0][0])\n\n\nif __name__ == \"__main__\":\n    unittest.main()\n"
  },
  {
    "path": "acestep/api/job_result_payload.py",
    "content": "\"\"\"Response payload helpers for successful music generation jobs.\"\"\"\n\nfrom __future__ import annotations\n\nfrom typing import Any, Callable, Optional\n\n\ndef normalize_metas(meta: dict[str, Any]) -> dict[str, Any]:\n    \"\"\"Normalize LM metadata and ensure expected response keys exist.\"\"\"\n\n    meta = meta or {}\n    out: dict[str, Any] = dict(meta)\n\n    if \"keyscale\" not in out and \"key_scale\" in out:\n        out[\"keyscale\"] = out.get(\"key_scale\")\n    if \"timesignature\" not in out and \"time_signature\" in out:\n        out[\"timesignature\"] = out.get(\"time_signature\")\n\n    for key in [\"bpm\", \"duration\", \"genres\", \"keyscale\", \"timesignature\"]:\n        if out.get(key) in (None, \"\"):\n            out[key] = \"N/A\"\n    return out\n\n\ndef _none_if_na_str(value: Any) -> Optional[str]:\n    if value is None:\n        return None\n    text = str(value).strip()\n    if text in {\"\", \"N/A\"}:\n        return None\n    return text\n\n\ndef _extract_seed_value(audios: list[dict[str, Any]]) -> str:\n    seed_values: list[str] = []\n    for audio in audios:\n        audio_params = audio.get(\"params\", {})\n        seed = audio_params.get(\"seed\")\n        if seed is not None:\n            seed_values.append(str(seed))\n    return \",\".join(seed_values) if seed_values else \"\"\n\n\ndef build_generation_success_response(\n    *,\n    result: Any,\n    params: Any,\n    bpm: Any,\n    audio_duration: Any,\n    key_scale: Any,\n    time_signature: Any,\n    original_prompt: str,\n    original_lyrics: str,\n    inference_steps: int,\n    path_to_audio_url: Callable[[str], str],\n    build_generation_info: Callable[..., Any],\n    lm_model_name: str,\n    dit_model_name: str,\n) -> dict[str, Any]:\n    \"\"\"Build API success payload from final generation outputs.\"\"\"\n\n    audios: list[dict[str, Any]] = list(result.audios)\n    audio_paths = [audio[\"path\"] for audio in audios if audio.get(\"path\")]\n    first_audio = audio_paths[0] if len(audio_paths) > 0 else None\n    second_audio = audio_paths[1] if len(audio_paths) > 1 else None\n\n    lm_metadata = result.extra_outputs.get(\"lm_metadata\", {})\n    metas_out = normalize_metas(lm_metadata)\n\n    if params.cot_bpm:\n        metas_out[\"bpm\"] = params.cot_bpm\n    elif bpm:\n        metas_out[\"bpm\"] = bpm\n\n    if params.cot_duration:\n        metas_out[\"duration\"] = params.cot_duration\n    elif audio_duration:\n        metas_out[\"duration\"] = audio_duration\n\n    if params.cot_keyscale:\n        metas_out[\"keyscale\"] = params.cot_keyscale\n    elif key_scale:\n        metas_out[\"keyscale\"] = key_scale\n\n    if params.cot_timesignature:\n        metas_out[\"timesignature\"] = params.cot_timesignature\n    elif time_signature:\n        metas_out[\"timesignature\"] = time_signature\n\n    metas_out[\"prompt\"] = original_prompt\n    metas_out[\"lyrics\"] = original_lyrics\n\n    seed_value = _extract_seed_value(audios)\n    time_costs = result.extra_outputs.get(\"time_costs\", {})\n    generation_info = build_generation_info(\n        lm_metadata=lm_metadata,\n        time_costs=time_costs,\n        seed_value=seed_value,\n        inference_steps=inference_steps,\n        num_audios=len(audios),\n    )\n\n    return {\n        \"first_audio_path\": path_to_audio_url(first_audio) if first_audio else None,\n        \"second_audio_path\": path_to_audio_url(second_audio) if second_audio else None,\n        \"audio_paths\": [path_to_audio_url(path) for path in audio_paths],\n        \"raw_audio_paths\": list(audio_paths),\n        \"generation_info\": generation_info,\n        \"status_message\": result.status_message,\n        \"seed_value\": seed_value,\n        \"prompt\": params.caption or \"\",\n        \"lyrics\": params.lyrics or \"\",\n        \"metas\": metas_out,\n        \"bpm\": metas_out.get(\"bpm\") if isinstance(metas_out.get(\"bpm\"), int) else None,\n        \"duration\": (\n            metas_out.get(\"duration\")\n            if isinstance(metas_out.get(\"duration\"), (int, float))\n            else None\n        ),\n        \"genres\": _none_if_na_str(metas_out.get(\"genres\")),\n        \"keyscale\": _none_if_na_str(metas_out.get(\"keyscale\")),\n        \"timesignature\": _none_if_na_str(metas_out.get(\"timesignature\")),\n        \"lm_model\": lm_model_name,\n        \"dit_model\": dit_model_name,\n    }\n"
  },
  {
    "path": "acestep/api/job_result_payload_test.py",
    "content": "\"\"\"Unit tests for generation success response payload helper.\"\"\"\n\nfrom __future__ import annotations\n\nimport unittest\nfrom types import SimpleNamespace\nfrom unittest.mock import MagicMock\n\nfrom acestep.api.job_result_payload import (\n    build_generation_success_response,\n    normalize_metas,\n)\n\n\nclass JobResultPayloadTests(unittest.TestCase):\n    \"\"\"Behavior tests for generation payload normalization and assembly.\"\"\"\n\n    def test_normalize_metas_maps_aliases_and_applies_defaults(self) -> None:\n        \"\"\"Metadata normalizer should preserve aliases and fill missing keys.\"\"\"\n\n        out = normalize_metas(\n            {\n                \"key_scale\": \"C major\",\n                \"time_signature\": \"4/4\",\n                \"genres\": \"\",\n            }\n        )\n        self.assertEqual(\"C major\", out[\"keyscale\"])\n        self.assertEqual(\"4/4\", out[\"timesignature\"])\n        self.assertEqual(\"N/A\", out[\"genres\"])\n        self.assertEqual(\"N/A\", out[\"bpm\"])\n        self.assertEqual(\"N/A\", out[\"duration\"])\n\n    def test_build_generation_success_response_preserves_response_contract(self) -> None:\n        \"\"\"Success payload helper should assemble fields with legacy shape and overrides.\"\"\"\n\n        result = SimpleNamespace(\n            audios=[\n                {\"path\": \"a.wav\", \"params\": {\"seed\": 11}},\n                {\"path\": \"b.wav\", \"params\": {\"seed\": 22}},\n            ],\n            extra_outputs={\"lm_metadata\": {\"genres\": \"rock\"}, \"time_costs\": {\"total\": 1.2}},\n            status_message=\"ok\",\n        )\n        params = SimpleNamespace(\n            caption=\"final caption\",\n            lyrics=\"final lyrics\",\n            cot_bpm=120,\n            cot_duration=8.0,\n            cot_keyscale=\"G major\",\n            cot_timesignature=\"3/4\",\n        )\n        build_generation_info = MagicMock(return_value=\"gen-info\")\n\n        payload = build_generation_success_response(\n            result=result,\n            params=params,\n            bpm=None,\n            audio_duration=None,\n            key_scale=None,\n            time_signature=None,\n            original_prompt=\"orig prompt\",\n            original_lyrics=\"orig lyrics\",\n            inference_steps=8,\n            path_to_audio_url=lambda path: f\"/v1/audio?path={path}\",\n            build_generation_info=build_generation_info,\n            lm_model_name=\"lm\",\n            dit_model_name=\"dit\",\n        )\n\n        self.assertEqual(\"/v1/audio?path=a.wav\", payload[\"first_audio_path\"])\n        self.assertEqual(\"/v1/audio?path=b.wav\", payload[\"second_audio_path\"])\n        self.assertEqual(\"11,22\", payload[\"seed_value\"])\n        self.assertEqual(\"orig prompt\", payload[\"metas\"][\"prompt\"])\n        self.assertEqual(\"orig lyrics\", payload[\"metas\"][\"lyrics\"])\n        self.assertEqual(120, payload[\"bpm\"])\n        self.assertEqual(8.0, payload[\"duration\"])\n        self.assertEqual(\"G major\", payload[\"keyscale\"])\n        self.assertEqual(\"3/4\", payload[\"timesignature\"])\n        self.assertEqual(\"lm\", payload[\"lm_model\"])\n        self.assertEqual(\"dit\", payload[\"dit_model\"])\n        build_generation_info.assert_called_once()\n\n\nif __name__ == \"__main__\":\n    unittest.main()\n"
  },
  {
    "path": "acestep/api/job_runtime_state.py",
    "content": "\"\"\"Runtime state helpers for API job execution flow.\"\"\"\n\nfrom __future__ import annotations\n\nimport os\nfrom typing import Any, Optional\n\nfrom acestep.api.jobs.local_cache_updates import update_local_cache, update_local_cache_progress\n\n\nasync def ensure_models_initialized(app_state: Any) -> None:\n    \"\"\"Raise when startup model initialization failed or has not completed.\n\n    Args:\n        app_state: Application state object containing initialization flags.\n\n    Raises:\n        RuntimeError: If startup initialization failed or has not completed.\n    \"\"\"\n\n    if getattr(app_state, \"_init_error\", None):\n        raise RuntimeError(app_state._init_error)\n    if not getattr(app_state, \"_initialized\", False):\n        raise RuntimeError(\"Model not initialized\")\n\n\nasync def cleanup_job_temp_files(app_state: Any, job_id: str) -> None:\n    \"\"\"Delete temporary upload files tracked for a completed job.\n\n    Args:\n        app_state: Application state object containing temp-file tracking state.\n        job_id: Job identifier whose tracked temp files should be deleted.\n    \"\"\"\n\n    async with app_state.job_temp_files_lock:\n        paths = app_state.job_temp_files.pop(job_id, [])\n    for path in paths:\n        try:\n            os.remove(path)\n        except Exception:\n            pass\n\n\ndef update_terminal_job_cache(\n    *,\n    app_state: Any,\n    store: Any,\n    job_id: str,\n    result: Optional[dict[str, Any]],\n    status: str,\n    map_status: Any,\n    result_key_prefix: str,\n    result_expire_seconds: int,\n) -> None:\n    \"\"\"Persist final job result state in optional local cache.\n\n    Args:\n        app_state: Application state object containing optional local cache.\n        store: Job store used for fetching current job data.\n        job_id: Job identifier to update in local cache.\n        result: Final job result payload, if present.\n        status: Final status value (for example, ``succeeded`` or ``failed``).\n        map_status: Callable that maps textual status to integer code.\n        result_key_prefix: Cache key prefix for result records.\n        result_expire_seconds: Cache TTL for result records.\n    \"\"\"\n\n    update_local_cache(\n        local_cache=getattr(app_state, \"local_cache\", None),\n        store=store,\n        job_id=job_id,\n        result=result,\n        status=status,\n        map_status=map_status,\n        result_key_prefix=result_key_prefix,\n        result_expire_seconds=result_expire_seconds,\n    )\n\n\ndef update_progress_job_cache(\n    *,\n    app_state: Any,\n    store: Any,\n    job_id: str,\n    progress: float,\n    stage: str,\n    map_status: Any,\n    result_key_prefix: str,\n    result_expire_seconds: int,\n) -> None:\n    \"\"\"Persist non-terminal job progress state in optional local cache.\n\n    Args:\n        app_state: Application state object containing optional local cache.\n        store: Job store used for fetching current job data.\n        job_id: Job identifier to update in local cache.\n        progress: Progress value in ``[0.0, 1.0]``.\n        stage: Text stage label for current progress.\n        map_status: Callable that maps textual status to integer code.\n        result_key_prefix: Cache key prefix for result records.\n        result_expire_seconds: Cache TTL for result records.\n    \"\"\"\n\n    update_local_cache_progress(\n        local_cache=getattr(app_state, \"local_cache\", None),\n        store=store,\n        job_id=job_id,\n        progress=progress,\n        stage=stage,\n        map_status=map_status,\n        result_key_prefix=result_key_prefix,\n        result_expire_seconds=result_expire_seconds,\n    )\n"
  },
  {
    "path": "acestep/api/job_runtime_state_test.py",
    "content": "\"\"\"Unit tests for runtime job-state helper functions.\"\"\"\n\nfrom __future__ import annotations\n\nimport asyncio\nimport os\nimport tempfile\nimport unittest\nfrom types import SimpleNamespace\nfrom unittest.mock import MagicMock, patch\n\nfrom acestep.api.job_runtime_state import (\n    cleanup_job_temp_files,\n    ensure_models_initialized,\n    update_progress_job_cache,\n    update_terminal_job_cache,\n)\n\n\nclass JobRuntimeStateTests(unittest.IsolatedAsyncioTestCase):\n    \"\"\"Behavior tests for runtime cache and job-state helpers.\"\"\"\n\n    async def test_ensure_models_initialized_raises_on_error_or_uninitialized(self) -> None:\n        \"\"\"Initialization guard should preserve legacy error behavior.\"\"\"\n\n        app_state_error = SimpleNamespace(_init_error=\"boom\", _initialized=False)\n        with self.assertRaisesRegex(RuntimeError, \"boom\"):\n            await ensure_models_initialized(app_state_error)\n\n        app_state_not_ready = SimpleNamespace(_init_error=None, _initialized=False)\n        with self.assertRaisesRegex(RuntimeError, \"Model not initialized\"):\n            await ensure_models_initialized(app_state_not_ready)\n\n        app_state_ready = SimpleNamespace(_init_error=None, _initialized=True)\n        await ensure_models_initialized(app_state_ready)\n\n    async def test_cleanup_job_temp_files_removes_tracked_paths(self) -> None:\n        \"\"\"Cleanup helper should remove tracked files and clear job mapping.\"\"\"\n\n        fd, file_path = tempfile.mkstemp(prefix=\"acestep-runtime-state-\", suffix=\".tmp\")\n        os.close(fd)\n        app_state = SimpleNamespace(\n            job_temp_files={\"job-1\": [file_path, \"missing-file.tmp\"]},\n            job_temp_files_lock=asyncio.Lock(),\n        )\n\n        await cleanup_job_temp_files(app_state, \"job-1\")\n\n        self.assertFalse(os.path.exists(file_path))\n        self.assertEqual({}, app_state.job_temp_files)\n\n    @patch(\"acestep.api.job_runtime_state.update_local_cache\")\n    @patch(\"acestep.api.job_runtime_state.update_local_cache_progress\")\n    async def test_cache_helpers_delegate_to_local_cache_update_functions(\n        self,\n        mock_update_local_cache_progress: MagicMock,\n        mock_update_local_cache: MagicMock,\n    ) -> None:\n        \"\"\"Cache helper wrappers should forward parameters unchanged.\"\"\"\n\n        app_state = SimpleNamespace(local_cache=MagicMock())\n        store = MagicMock()\n        map_status = MagicMock(return_value=1)\n\n        update_terminal_job_cache(\n            app_state=app_state,\n            store=store,\n            job_id=\"job-1\",\n            result={\"ok\": True},\n            status=\"succeeded\",\n            map_status=map_status,\n            result_key_prefix=\"prefix\",\n            result_expire_seconds=60,\n        )\n        update_progress_job_cache(\n            app_state=app_state,\n            store=store,\n            job_id=\"job-1\",\n            progress=0.5,\n            stage=\"running\",\n            map_status=map_status,\n            result_key_prefix=\"prefix\",\n            result_expire_seconds=60,\n        )\n\n        mock_update_local_cache.assert_called_once()\n        mock_update_local_cache_progress.assert_called_once()\n\n\nif __name__ == \"__main__\":\n    unittest.main()\n"
  },
  {
    "path": "acestep/api/jobs/__init__.py",
    "content": "\"\"\"Jobs package: async task execution, queueing, and job state tracking.\"\"\"\n"
  },
  {
    "path": "acestep/api/jobs/local_cache_updates.py",
    "content": "\"\"\"Helpers for writing API job state into the local cache backend.\"\"\"\n\nfrom __future__ import annotations\n\nimport time\nfrom typing import Any, Callable, Dict, Optional\n\n\ndef _get_record_env_and_time(\n    store: Any,\n    job_id: str,\n    now_fn: Callable[[], float],\n) -> tuple[str, float]:\n    \"\"\"Return `(env, create_time)` derived from store record or defaults.\"\"\"\n\n    record = store.get(job_id)\n    if record is None:\n        return \"development\", now_fn()\n    return getattr(record, \"env\", \"development\"), getattr(record, \"created_at\", now_fn())\n\n\ndef update_local_cache(\n    local_cache: Any,\n    store: Any,\n    job_id: str,\n    result: Optional[Dict[str, Any]],\n    status: str,\n    map_status: Callable[[str], int],\n    result_key_prefix: str,\n    result_expire_seconds: int,\n    now_fn: Callable[[], float] = time.time,\n) -> None:\n    \"\"\"Persist terminal job result payload to local cache.\n\n    Args:\n        local_cache: Cache object exposing `set(key, value, ex=...)`.\n        store: Job store exposing `get(job_id)`.\n        job_id: Job identifier.\n        result: Optional terminal result payload.\n        status: Terminal job status string.\n        map_status: Status mapper from text status to integer code.\n        result_key_prefix: Prefix for cache keys.\n        result_expire_seconds: Cache TTL in seconds.\n        now_fn: Time provider for deterministic tests.\n    \"\"\"\n\n    if not local_cache:\n        return\n\n    env, create_time = _get_record_env_and_time(store=store, job_id=job_id, now_fn=now_fn)\n    status_int = map_status(status)\n\n    if status == \"succeeded\" and result:\n        if result.get(\"status_message\") in (\n            \"Full Hardware Analysis Success\",\n            \"Audio Codes Extraction Success\",\n        ):\n            result_data = [result]\n        else:\n            audio_paths = result.get(\"audio_paths\", [])\n            final_prompt = result.get(\"prompt\", \"\")\n            final_lyrics = result.get(\"lyrics\", \"\")\n            metas_raw = result.get(\"metas\", {}) or {}\n            metas = {\n                \"bpm\": metas_raw.get(\"bpm\"),\n                \"duration\": metas_raw.get(\"duration\"),\n                \"genres\": metas_raw.get(\"genres\", \"\"),\n                \"keyscale\": metas_raw.get(\"keyscale\", \"\"),\n                \"timesignature\": metas_raw.get(\"timesignature\", \"\"),\n                \"prompt\": metas_raw.get(\"prompt\", \"\"),\n                \"lyrics\": metas_raw.get(\"lyrics\", \"\"),\n            }\n            generation_info = result.get(\"generation_info\", \"\")\n            seed_value = result.get(\"seed_value\", \"\")\n            lm_model = result.get(\"lm_model\", \"\")\n            dit_model = result.get(\"dit_model\", \"\")\n\n            if audio_paths:\n                result_data = [\n                    {\n                        \"file\": path,\n                        \"wave\": \"\",\n                        \"status\": status_int,\n                        \"create_time\": int(create_time),\n                        \"env\": env,\n                        \"prompt\": final_prompt,\n                        \"lyrics\": final_lyrics,\n                        \"metas\": metas,\n                        \"generation_info\": generation_info,\n                        \"seed_value\": seed_value,\n                        \"lm_model\": lm_model,\n                        \"dit_model\": dit_model,\n                        \"progress\": 1.0,\n                        \"stage\": \"succeeded\",\n                    }\n                    for path in audio_paths\n                ]\n            else:\n                result_data = [{\n                    \"file\": \"\",\n                    \"wave\": \"\",\n                    \"status\": status_int,\n                    \"create_time\": int(create_time),\n                    \"env\": env,\n                    \"prompt\": final_prompt,\n                    \"lyrics\": final_lyrics,\n                    \"metas\": metas,\n                    \"generation_info\": generation_info,\n                    \"seed_value\": seed_value,\n                    \"lm_model\": lm_model,\n                    \"dit_model\": dit_model,\n                    \"progress\": 1.0,\n                    \"stage\": \"succeeded\",\n                }]\n    else:\n        result_data = [{\n            \"file\": \"\",\n            \"wave\": \"\",\n            \"status\": status_int,\n            \"create_time\": int(create_time),\n            \"env\": env,\n            \"progress\": 0.0,\n            \"stage\": \"failed\" if status == \"failed\" else status,\n        }]\n\n    result_key = f\"{result_key_prefix}{job_id}\"\n    local_cache.set(result_key, result_data, ex=result_expire_seconds)\n\n\ndef update_local_cache_progress(\n    local_cache: Any,\n    store: Any,\n    job_id: str,\n    progress: float,\n    stage: str,\n    map_status: Callable[[str], int],\n    result_key_prefix: str,\n    result_expire_seconds: int,\n    now_fn: Callable[[], float] = time.time,\n) -> None:\n    \"\"\"Persist running/queued progress payload to local cache.\"\"\"\n\n    if not local_cache:\n        return\n\n    env, create_time = _get_record_env_and_time(store=store, job_id=job_id, now_fn=now_fn)\n    status_int = map_status(\"running\")\n    result_data = [{\n        \"file\": \"\",\n        \"wave\": \"\",\n        \"status\": status_int,\n        \"create_time\": int(create_time),\n        \"env\": env,\n        \"progress\": float(progress),\n        \"stage\": stage,\n    }]\n    result_key = f\"{result_key_prefix}{job_id}\"\n    local_cache.set(result_key, result_data, ex=result_expire_seconds)\n"
  },
  {
    "path": "acestep/api/jobs/local_cache_updates_test.py",
    "content": "\"\"\"Unit tests for local-cache job payload update helpers.\"\"\"\n\nimport unittest\nfrom types import SimpleNamespace\n\nfrom acestep.api.jobs.local_cache_updates import (\n    update_local_cache,\n    update_local_cache_progress,\n)\n\n\ndef _map_status(status: str) -> int:\n    \"\"\"Map text status to legacy integer status used by API responses.\"\"\"\n\n    return {\"queued\": 0, \"running\": 0, \"succeeded\": 1, \"failed\": 2}.get(status, 2)\n\n\nclass _FakeLocalCache:\n    \"\"\"Capture local-cache set calls for deterministic assertions.\"\"\"\n\n    def __init__(self) -> None:\n        \"\"\"Initialize an empty call log.\"\"\"\n\n        self.calls = []\n\n    def set(self, key: str, value, ex: int) -> None:\n        \"\"\"Record one cache write call.\"\"\"\n\n        self.calls.append((key, value, ex))\n\n\nclass _FakeStore:\n    \"\"\"Return preconfigured records by job id.\"\"\"\n\n    def __init__(self, records: dict[str, object] | None = None) -> None:\n        \"\"\"Store test records in memory.\"\"\"\n\n        self._records = records or {}\n\n    def get(self, job_id: str):\n        \"\"\"Return record for job id or None when missing.\"\"\"\n\n        return self._records.get(job_id)\n\n\nclass LocalCacheUpdatesTests(unittest.TestCase):\n    \"\"\"Behavior tests for local cache update helpers.\"\"\"\n\n    def test_update_local_cache_writes_full_analysis_payload(self):\n        \"\"\"Full-analysis success payload should be cached unchanged inside list wrapper.\"\"\"\n\n        cache = _FakeLocalCache()\n        store = _FakeStore({\"job-1\": SimpleNamespace(created_at=123.0, env=\"development\")})\n        result = {\"status_message\": \"Full Hardware Analysis Success\", \"analysis\": \"ok\"}\n\n        update_local_cache(\n            local_cache=cache,\n            store=store,\n            job_id=\"job-1\",\n            result=result,\n            status=\"succeeded\",\n            map_status=_map_status,\n            result_key_prefix=\"prefix:\",\n            result_expire_seconds=600,\n        )\n\n        self.assertEqual(1, len(cache.calls))\n        key, payload, ttl = cache.calls[0]\n        self.assertEqual(\"prefix:job-1\", key)\n        self.assertEqual(600, ttl)\n        self.assertEqual([result], payload)\n\n    def test_update_local_cache_writes_extract_codes_payload(self):\n        \"\"\"Extract-codes success payload should be cached unchanged inside list wrapper.\"\"\"\n\n        cache = _FakeLocalCache()\n        store = _FakeStore(\n            {\"job-ec\": SimpleNamespace(created_at=150.0, env=\"development\")}\n        )\n        result = {\n            \"status_message\": \"Audio Codes Extraction Success\",\n            \"audio_codes\": \"<|audio_code_1|>\",\n            \"audio_paths\": [],\n            \"raw_audio_paths\": [],\n            \"first_audio_path\": None,\n            \"metas\": {},\n        }\n\n        update_local_cache(\n            local_cache=cache,\n            store=store,\n            job_id=\"job-ec\",\n            result=result,\n            status=\"succeeded\",\n            map_status=_map_status,\n            result_key_prefix=\"prefix:\",\n            result_expire_seconds=600,\n        )\n\n        self.assertEqual(1, len(cache.calls))\n        key, payload, ttl = cache.calls[0]\n        self.assertEqual(\"prefix:job-ec\", key)\n        self.assertEqual(600, ttl)\n        self.assertEqual([result], payload)\n        self.assertEqual(\n            \"<|audio_code_1|>\", payload[0][\"audio_codes\"]\n        )\n\n    def test_update_local_cache_writes_success_audio_payload(self):\n        \"\"\"Succeeded payload should include transformed audio entries and preserved metadata fields.\"\"\"\n\n        cache = _FakeLocalCache()\n        store = _FakeStore({\"job-2\": SimpleNamespace(created_at=200.0, env=\"development\")})\n        result = {\n            \"audio_paths\": [\"a.mp3\", \"b.mp3\"],\n            \"prompt\": \"final prompt\",\n            \"lyrics\": \"final lyrics\",\n            \"metas\": {\n                \"bpm\": 120,\n                \"duration\": 8.0,\n                \"genres\": \"pop\",\n                \"keyscale\": \"C\",\n                \"timesignature\": \"4/4\",\n                \"prompt\": \"original prompt\",\n                \"lyrics\": \"original lyrics\",\n            },\n            \"generation_info\": \"info\",\n            \"seed_value\": \"42\",\n            \"lm_model\": \"lm-model\",\n            \"dit_model\": \"dit-model\",\n        }\n\n        update_local_cache(\n            local_cache=cache,\n            store=store,\n            job_id=\"job-2\",\n            result=result,\n            status=\"succeeded\",\n            map_status=_map_status,\n            result_key_prefix=\"prefix:\",\n            result_expire_seconds=600,\n        )\n\n        _, payload, _ = cache.calls[0]\n        self.assertEqual(2, len(payload))\n        self.assertEqual(\"a.mp3\", payload[0][\"file\"])\n        self.assertEqual(\"final prompt\", payload[0][\"prompt\"])\n        self.assertEqual(\"original prompt\", payload[0][\"metas\"][\"prompt\"])\n        self.assertEqual(1.0, payload[0][\"progress\"])\n        self.assertEqual(\"succeeded\", payload[0][\"stage\"])\n\n    def test_update_local_cache_writes_failed_payload(self):\n        \"\"\"Failed status should emit failed stage with zero progress.\"\"\"\n\n        cache = _FakeLocalCache()\n        store = _FakeStore({\"job-3\": SimpleNamespace(created_at=300.0, env=\"development\")})\n\n        update_local_cache(\n            local_cache=cache,\n            store=store,\n            job_id=\"job-3\",\n            result=None,\n            status=\"failed\",\n            map_status=_map_status,\n            result_key_prefix=\"prefix:\",\n            result_expire_seconds=600,\n        )\n\n        _, payload, _ = cache.calls[0]\n        self.assertEqual(2, payload[0][\"status\"])\n        self.assertEqual(0.0, payload[0][\"progress\"])\n        self.assertEqual(\"failed\", payload[0][\"stage\"])\n\n    def test_update_local_cache_progress_writes_running_payload(self):\n        \"\"\"Progress updates should write running payload with provided stage and progress value.\"\"\"\n\n        cache = _FakeLocalCache()\n        store = _FakeStore({\"job-4\": SimpleNamespace(created_at=400.0, env=\"development\")})\n\n        update_local_cache_progress(\n            local_cache=cache,\n            store=store,\n            job_id=\"job-4\",\n            progress=0.25,\n            stage=\"running\",\n            map_status=_map_status,\n            result_key_prefix=\"prefix:\",\n            result_expire_seconds=600,\n        )\n\n        _, payload, _ = cache.calls[0]\n        self.assertEqual(0, payload[0][\"status\"])\n        self.assertEqual(0.25, payload[0][\"progress\"])\n        self.assertEqual(\"running\", payload[0][\"stage\"])\n\n    def test_update_helpers_are_noop_without_local_cache(self):\n        \"\"\"Update helpers should return without writes when local cache backend is absent.\"\"\"\n\n        store = _FakeStore({\"job-5\": SimpleNamespace(created_at=500.0, env=\"development\")})\n\n        update_local_cache(\n            local_cache=None,\n            store=store,\n            job_id=\"job-5\",\n            result={\"audio_paths\": []},\n            status=\"succeeded\",\n            map_status=_map_status,\n            result_key_prefix=\"prefix:\",\n            result_expire_seconds=600,\n        )\n        update_local_cache_progress(\n            local_cache=None,\n            store=store,\n            job_id=\"job-5\",\n            progress=0.1,\n            stage=\"running\",\n            map_status=_map_status,\n            result_key_prefix=\"prefix:\",\n            result_expire_seconds=600,\n        )\n\n\nif __name__ == \"__main__\":\n    unittest.main()\n"
  },
  {
    "path": "acestep/api/jobs/models.py",
    "content": "\"\"\"Job models for API queue state and response payloads.\"\"\"\n\nfrom __future__ import annotations\n\nfrom typing import Any, Dict, Literal, Optional\n\nfrom pydantic import BaseModel, Field\n\nJobStatus = Literal[\"queued\", \"running\", \"succeeded\", \"failed\"]\n\n\nclass CreateJobResponse(BaseModel):\n    \"\"\"Response payload returned immediately after job creation.\"\"\"\n\n    task_id: str\n    status: JobStatus\n    queue_position: int = 0\n    progress_text: Optional[str] = \"\"\n\n\nclass JobResult(BaseModel):\n    \"\"\"Result payload for completed music generation jobs.\"\"\"\n\n    first_audio_path: Optional[str] = None\n    second_audio_path: Optional[str] = None\n    audio_paths: list[str] = Field(default_factory=list)\n    generation_info: str = \"\"\n    status_message: str = \"\"\n    seed_value: str = \"\"\n    metas: Dict[str, Any] = Field(default_factory=dict)\n    bpm: Optional[int] = None\n    duration: Optional[float] = None\n    genres: Optional[str] = None\n    keyscale: Optional[str] = None\n    timesignature: Optional[str] = None\n    lm_model: Optional[str] = None\n    dit_model: Optional[str] = None\n\n\nclass JobResponse(BaseModel):\n    \"\"\"Response payload for querying a job's current status.\"\"\"\n\n    job_id: str\n    status: JobStatus\n    created_at: float\n    started_at: Optional[float] = None\n    finished_at: Optional[float] = None\n    queue_position: int = 0\n    eta_seconds: Optional[float] = None\n    avg_job_seconds: Optional[float] = None\n    result: Optional[JobResult] = None\n    error: Optional[str] = None\n"
  },
  {
    "path": "acestep/api/jobs/store.py",
    "content": "\"\"\"In-memory job store and JSON persistence helpers for API jobs.\"\"\"\n\nfrom __future__ import annotations\n\nimport asyncio\nimport json\nimport os\nimport tempfile\nimport time\nfrom dataclasses import dataclass\nfrom threading import Lock\nfrom typing import Any, Dict, Literal, Optional\nfrom uuid import uuid4\n\nJobStatus = Literal[\"queued\", \"running\", \"succeeded\", \"failed\"]\n\n\n@dataclass\nclass _JobRecord:\n    \"\"\"Internal mutable record stored in the in-memory job store.\"\"\"\n    job_id: str\n    status: JobStatus\n    created_at: float\n    started_at: Optional[float] = None\n    finished_at: Optional[float] = None\n    result: Optional[Dict[str, Any]] = None\n    error: Optional[str] = None\n    progress_text: str = \"\"\n    status_text: str = \"\"\n    env: str = \"development\"\n    progress: float = 0.0\n    stage: str = \"queued\"\n    updated_at: Optional[float] = None\n    done_event: Optional[asyncio.Event] = None\n    progress_queue: Optional[asyncio.Queue] = None\n\n\ndef _atomic_write_json(path: str, payload: Dict[str, Any]) -> None:\n    \"\"\"Write a JSON document atomically to reduce corruption risk.\"\"\"\n    directory = os.path.dirname(path)\n    if directory:\n        os.makedirs(directory, exist_ok=True)\n\n    fd, tmp_path = tempfile.mkstemp(prefix=\".tmp_\", suffix=\".json\", dir=directory or None)\n    try:\n        with os.fdopen(fd, \"w\", encoding=\"utf-8\") as file_obj:\n            json.dump(payload, file_obj, ensure_ascii=False, indent=2)\n            file_obj.flush()\n            os.fsync(file_obj.fileno())\n        os.replace(tmp_path, path)\n    except Exception:\n        try:\n            os.remove(tmp_path)\n        except Exception:\n            pass\n        raise\n\n\ndef _append_jsonl(path: str, record: Dict[str, Any]) -> None:\n    \"\"\"Append a single JSON record as one line in JSONL format.\"\"\"\n    directory = os.path.dirname(path)\n    if directory:\n        os.makedirs(directory, exist_ok=True)\n    with open(path, \"a\", encoding=\"utf-8\") as file_obj:\n        file_obj.write(json.dumps(record, ensure_ascii=False) + \"\\n\")\n\n\nclass _JobStore:\n    \"\"\"Thread-safe in-memory store for queued/running/completed jobs.\"\"\"\n\n    def __init__(self, max_age_seconds: int = 86400) -> None:\n        \"\"\"Initialize store state and completed-job retention policy.\"\"\"\n        self._lock = Lock()\n        self._jobs: Dict[str, _JobRecord] = {}\n        self._max_age = max_age_seconds\n\n    def create(self) -> _JobRecord:\n        \"\"\"Create and register a queued job with a generated UUID.\"\"\"\n        job_id = str(uuid4())\n        now = time.time()\n        record = _JobRecord(\n            job_id=job_id,\n            status=\"queued\",\n            created_at=now,\n            progress=0.0,\n            stage=\"queued\",\n            updated_at=now,\n        )\n        with self._lock:\n            self._jobs[job_id] = record\n        return record\n\n    def create_with_id(self, job_id: str, env: str = \"development\") -> _JobRecord:\n        \"\"\"Create and register a queued job using a caller-provided ID.\"\"\"\n        now = time.time()\n        record = _JobRecord(\n            job_id=job_id,\n            status=\"queued\",\n            created_at=now,\n            env=env,\n            progress=0.0,\n            stage=\"queued\",\n            updated_at=now,\n        )\n        with self._lock:\n            self._jobs[job_id] = record\n        return record\n\n    def get(self, job_id: str) -> Optional[_JobRecord]:\n        \"\"\"Return a job record by ID if present.\"\"\"\n        with self._lock:\n            return self._jobs.get(job_id)\n\n    def mark_running(self, job_id: str) -> None:\n        \"\"\"Mark a queued job as running and set timestamps/progress.\"\"\"\n        with self._lock:\n            record = self._jobs[job_id]\n            record.status = \"running\"\n            record.started_at = time.time()\n            record.progress = max(record.progress, 0.01)\n            record.stage = \"running\"\n            record.updated_at = time.time()\n\n    def mark_succeeded(self, job_id: str, result: Dict[str, Any]) -> None:\n        \"\"\"Mark a job as succeeded and attach its result payload.\"\"\"\n        with self._lock:\n            record = self._jobs[job_id]\n            record.status = \"succeeded\"\n            record.finished_at = time.time()\n            record.result = result\n            record.error = None\n            record.progress = 1.0\n            record.stage = \"succeeded\"\n            record.updated_at = time.time()\n\n    def mark_failed(self, job_id: str, error: str) -> None:\n        \"\"\"Mark a job as failed and persist an error message.\"\"\"\n        with self._lock:\n            record = self._jobs[job_id]\n            record.status = \"failed\"\n            record.finished_at = time.time()\n            record.result = None\n            record.error = error\n            record.progress = record.progress if record.progress > 0 else 0.0\n            record.stage = \"failed\"\n            record.updated_at = time.time()\n\n    def update_progress(self, job_id: str, progress: float, stage: Optional[str] = None) -> None:\n        \"\"\"Update progress and optional stage for an existing job.\"\"\"\n        with self._lock:\n            record = self._jobs.get(job_id)\n            if not record:\n                return\n            record.progress = max(0.0, min(1.0, float(progress)))\n            if stage:\n                record.stage = stage\n            record.updated_at = time.time()\n\n    def cleanup_old_jobs(self, max_age_seconds: Optional[int] = None) -> int:\n        \"\"\"Remove completed jobs older than retention threshold.\"\"\"\n        max_age = max_age_seconds if max_age_seconds is not None else self._max_age\n        now = time.time()\n        removed = 0\n\n        with self._lock:\n            to_remove = []\n            for job_id, record in self._jobs.items():\n                if record.status in (\"succeeded\", \"failed\"):\n                    finish_time = record.finished_at or record.created_at\n                    if now - finish_time > max_age:\n                        to_remove.append(job_id)\n\n            for job_id in to_remove:\n                del self._jobs[job_id]\n                removed += 1\n\n        return removed\n\n    def get_stats(self) -> Dict[str, int]:\n        \"\"\"Return aggregate counts for each job status.\"\"\"\n        with self._lock:\n            stats = {\n                \"total\": len(self._jobs),\n                \"queued\": 0,\n                \"running\": 0,\n                \"succeeded\": 0,\n                \"failed\": 0,\n            }\n            for record in self._jobs.values():\n                if record.status in stats:\n                    stats[record.status] += 1\n            return stats\n\n    def update_status_text(self, job_id: str, text: str) -> None:\n        \"\"\"Update human-readable status text for a job.\"\"\"\n        with self._lock:\n            if job_id in self._jobs:\n                self._jobs[job_id].status_text = text\n\n    def update_progress_text(self, job_id: str, text: str) -> None:\n        \"\"\"Update human-readable progress text for a job.\"\"\"\n        with self._lock:\n            if job_id in self._jobs:\n                self._jobs[job_id].progress_text = text\n"
  },
  {
    "path": "acestep/api/jobs/store_test.py",
    "content": "\"\"\"Unit tests for API job store state tracking and persistence helpers.\"\"\"\n\nimport json\nimport os\nimport time\nimport unittest\nfrom pathlib import Path\nfrom unittest import mock\n\nfrom acestep.api.jobs.store import _JobStore, _append_jsonl, _atomic_write_json\n\n_REPO_ROOT = Path(__file__).resolve().parents[3]\n_REPO_TMP_ROOT = _REPO_ROOT / \"acestep\" / \"api\" / \"jobs\"\n\n\nclass JobStoreTests(unittest.TestCase):\n    \"\"\"Tests for queue/job lifecycle behavior in the in-memory store.\"\"\"\n\n    def test_create_mark_running_mark_succeeded_updates_state(self):\n        \"\"\"Store should transition job state through queued->running->succeeded.\"\"\"\n\n        store = _JobStore()\n        store.create_with_id(\"job-1\")\n\n        queued = store.get(\"job-1\")\n        self.assertIsNotNone(queued)\n        self.assertEqual(\"queued\", queued.status)\n\n        store.mark_running(\"job-1\")\n        running = store.get(\"job-1\")\n        self.assertEqual(\"running\", running.status)\n        self.assertIsNotNone(running.started_at)\n        self.assertGreaterEqual(running.progress, 0.01)\n\n        result = {\"audio_paths\": [\"a.wav\"]}\n        store.mark_succeeded(\"job-1\", result=result)\n        succeeded = store.get(\"job-1\")\n        self.assertEqual(\"succeeded\", succeeded.status)\n        self.assertEqual(result, succeeded.result)\n        self.assertEqual(1.0, succeeded.progress)\n\n        stats = store.get_stats()\n        self.assertEqual(1, stats[\"total\"])\n        self.assertEqual(1, stats[\"succeeded\"])\n\n    def test_cleanup_old_jobs_removes_only_completed_jobs(self):\n        \"\"\"Cleanup should remove stale finished jobs while preserving queued jobs.\"\"\"\n\n        store = _JobStore()\n        store.create_with_id(\"queued\")\n        store.create_with_id(\"failed\")\n        store.mark_failed(\"failed\", error=\"boom\")\n\n        failed = store.get(\"failed\")\n        failed.finished_at = time.time() - 10\n\n        removed = store.cleanup_old_jobs(max_age_seconds=1)\n\n        self.assertEqual(1, removed)\n        self.assertIsNotNone(store.get(\"queued\"))\n        self.assertIsNone(store.get(\"failed\"))\n\n    def test_update_progress_clamps_values_and_ignores_missing_jobs(self):\n        \"\"\"Progress updates should clamp to [0,1] and no-op for unknown IDs.\"\"\"\n\n        store = _JobStore()\n        store.create_with_id(\"job-2\")\n\n        store.update_progress(\"job-2\", 2.0, stage=\"running\")\n        high = store.get(\"job-2\")\n        self.assertEqual(1.0, high.progress)\n        self.assertEqual(\"running\", high.stage)\n\n        store.update_progress(\"job-2\", -1.0)\n        low = store.get(\"job-2\")\n        self.assertEqual(0.0, low.progress)\n\n        store.update_progress(\"missing\", 0.5)\n\n\nclass JobStorePersistenceTests(unittest.TestCase):\n    \"\"\"Tests for JSON and JSONL helper functions used by job persistence.\"\"\"\n\n    def test_atomic_write_json_uses_atomic_replace_flow(self):\n        \"\"\"Atomic write should write+flush+fsync and then replace target path.\"\"\"\n\n        target_path = str(_REPO_TMP_ROOT / \"record.json\")\n        payload = {\"id\": \"job-1\", \"status\": \"running\"}\n        fake_fd = 101\n        fake_tmp_path = str(_REPO_TMP_ROOT / \".tmp_record.json\")\n\n        fake_file = mock.MagicMock()\n        fake_file.__enter__.return_value = fake_file\n        fake_file.fileno.return_value = 202\n\n        with mock.patch(\"acestep.api.jobs.store.tempfile.mkstemp\", return_value=(fake_fd, fake_tmp_path)) as mkstemp_mock, \\\n             mock.patch(\"acestep.api.jobs.store.os.fdopen\", return_value=fake_file) as fdopen_mock, \\\n             mock.patch(\"acestep.api.jobs.store.json.dump\") as dump_mock, \\\n             mock.patch(\"acestep.api.jobs.store.os.fsync\") as fsync_mock, \\\n             mock.patch(\"acestep.api.jobs.store.os.replace\") as replace_mock:\n            _atomic_write_json(target_path, payload)\n\n        mkstemp_mock.assert_called_once()\n        fdopen_mock.assert_called_once_with(fake_fd, \"w\", encoding=\"utf-8\")\n        dump_mock.assert_called_once()\n        fsync_mock.assert_called_once_with(202)\n        replace_mock.assert_called_once_with(fake_tmp_path, target_path)\n\n    def test_append_jsonl_writes_one_json_line_per_record(self):\n        \"\"\"JSONL append should serialize each record with a newline terminator.\"\"\"\n\n        target_path = str(_REPO_TMP_ROOT / \"events.jsonl\")\n        first = {\"event\": \"queued\"}\n        expected = json.dumps(first, ensure_ascii=False) + \"\\n\"\n\n        fake_file = mock.MagicMock()\n        fake_file.__enter__.return_value = fake_file\n\n        with mock.patch(\"acestep.api.jobs.store.open\", return_value=fake_file, create=True) as open_mock:\n            _append_jsonl(target_path, first)\n\n        open_mock.assert_called_once_with(target_path, \"a\", encoding=\"utf-8\")\n        fake_file.write.assert_called_once_with(expected)\n\n\nif __name__ == \"__main__\":\n    unittest.main()\n"
  },
  {
    "path": "acestep/api/jobs/test_fakes.py",
    "content": "\"\"\"Shared unittest fakes for API job helper tests.\"\"\"\n\nfrom __future__ import annotations\n\nfrom typing import Any, Optional\n\n\nclass _FakeJobQueue:\n    \"\"\"Track task completion calls made by worker helper.\"\"\"\n\n    def __init__(self) -> None:\n        \"\"\"Initialize task_done call counter.\"\"\"\n\n        self.task_done_calls = 0\n\n    def task_done(self) -> None:\n        \"\"\"Record one task completion.\"\"\"\n\n        self.task_done_calls += 1\n\n\nclass _FakeStore:\n    \"\"\"In-memory store stub for worker helper tests.\"\"\"\n\n    def __init__(self, record: Optional[Any] = None) -> None:\n        \"\"\"Initialize store with optional record.\"\"\"\n\n        self.record = record\n        self.mark_failed_calls = []\n        self.cleanup_returns = [0]\n        self.cleanup_call_count = 0\n        self.stats = {\"total\": 0}\n\n    def get(self, _job_id: str) -> Any:\n        \"\"\"Return configured record.\"\"\"\n\n        return self.record\n\n    def mark_failed(self, job_id: str, error: str) -> None:\n        \"\"\"Record mark_failed invocations.\"\"\"\n\n        self.mark_failed_calls.append((job_id, error))\n        if self.record is not None:\n            self.record.status = \"failed\"\n            self.record.error = error\n\n    def cleanup_old_jobs(self) -> int:\n        \"\"\"Return deterministic cleanup counts for each invocation.\"\"\"\n\n        index = min(self.cleanup_call_count, len(self.cleanup_returns) - 1)\n        self.cleanup_call_count += 1\n        result = self.cleanup_returns[index]\n        if isinstance(result, Exception):\n            raise result\n        return int(result)\n\n    def get_stats(self) -> dict[str, int]:\n        \"\"\"Return deterministic stats payload.\"\"\"\n\n        return self.stats\n\n\nclass _DoneEvent:\n    \"\"\"Simple event stub tracking whether set() was called.\"\"\"\n\n    def __init__(self) -> None:\n        \"\"\"Initialize unset event state.\"\"\"\n\n        self.was_set = False\n\n    def set(self) -> None:\n        \"\"\"Mark event as set.\"\"\"\n\n        self.was_set = True\n"
  },
  {
    "path": "acestep/api/jobs/worker_loops.py",
    "content": "\"\"\"Queue worker loop helpers for API job processing.\"\"\"\n\nfrom __future__ import annotations\n\nimport asyncio\nfrom typing import Any, Awaitable, Callable\n\n\nasync def process_queue_item(\n    job_id: str,\n    req: Any,\n    app_state: Any,\n    store: Any,\n    run_one_job: Callable[[str, Any], Awaitable[None]],\n    cleanup_job_temp_files: Callable[[str], Awaitable[None]],\n) -> None:\n    \"\"\"Process one queued job item and notify waiters.\n\n    Args:\n        job_id: Job identifier from queue.\n        req: Request payload associated with the job.\n        app_state: App state containing queue and pending-id synchronization.\n        store: Job store exposing `get(job_id)` and `mark_failed(job_id, error)`.\n        run_one_job: Async callable that executes one job.\n        cleanup_job_temp_files: Async callable to cleanup temporary upload files.\n    \"\"\"\n\n    rec = store.get(job_id)\n    try:\n        async with app_state.pending_lock:\n            try:\n                app_state.pending_ids.remove(job_id)\n            except ValueError:\n                pass\n\n        await run_one_job(job_id, req)\n\n        if rec and rec.progress_queue:\n            if rec.status == \"succeeded\" and rec.result:\n                await rec.progress_queue.put({\"type\": \"result\", \"result\": rec.result})\n            elif rec.status == \"failed\":\n                await rec.progress_queue.put({\"type\": \"error\", \"content\": rec.error or \"Generation failed\"})\n            await rec.progress_queue.put({\"type\": \"done\"})\n        if rec and rec.done_event:\n            rec.done_event.set()\n\n    except Exception as exc:\n        if rec and rec.status not in (\"succeeded\", \"failed\"):\n            store.mark_failed(job_id, str(exc))\n        if rec and rec.progress_queue:\n            await rec.progress_queue.put({\"type\": \"error\", \"content\": str(exc)})\n            await rec.progress_queue.put({\"type\": \"done\"})\n        if rec and rec.done_event:\n            rec.done_event.set()\n    finally:\n        await cleanup_job_temp_files(job_id)\n        app_state.job_queue.task_done()\n\n\nasync def run_job_store_cleanup_loop(\n    store: Any,\n    cleanup_interval_seconds: int,\n    sleep_fn: Callable[[float], Awaitable[None]] = asyncio.sleep,\n    log_fn: Callable[[str], None] = print,\n) -> None:\n    \"\"\"Periodically cleanup completed jobs until cancelled.\"\"\"\n\n    while True:\n        try:\n            await sleep_fn(cleanup_interval_seconds)\n            removed = store.cleanup_old_jobs()\n            if removed > 0:\n                stats = store.get_stats()\n                log_fn(f\"[API Server] Cleaned up {removed} old jobs. Current stats: {stats}\")\n        except asyncio.CancelledError:\n            break\n        except Exception as exc:\n            log_fn(f\"[API Server] Job cleanup error: {exc}\")\n"
  },
  {
    "path": "acestep/api/jobs/worker_loops_test.py",
    "content": "\"\"\"Unit tests for queue worker loop helper functions.\"\"\"\n\nfrom __future__ import annotations\n\nimport asyncio\nimport unittest\nfrom types import SimpleNamespace\n\nfrom acestep.api.jobs.test_fakes import _DoneEvent, _FakeJobQueue, _FakeStore\nfrom acestep.api.jobs.worker_loops import (\n    process_queue_item,\n    run_job_store_cleanup_loop,\n)\n\n\nclass WorkerLoopTests(unittest.TestCase):\n    \"\"\"Behavior tests for extracted queue worker helper logic.\"\"\"\n\n    def test_process_queue_item_success_notifies_result_and_done(self):\n        \"\"\"Success path should emit result+done and cleanup queue bookkeeping.\"\"\"\n\n        async def _run() -> None:\n            \"\"\"Execute success-path queue item processing and assert notifications.\"\"\"\n\n            progress_queue = asyncio.Queue()\n            done_event = _DoneEvent()\n            record = SimpleNamespace(\n                status=\"running\",\n                result=None,\n                error=None,\n                progress_queue=progress_queue,\n                done_event=done_event,\n            )\n            store = _FakeStore(record=record)\n            app_state = SimpleNamespace(\n                pending_lock=asyncio.Lock(),\n                pending_ids=[\"job-1\"],\n                job_queue=_FakeJobQueue(),\n            )\n            cleanup_calls = []\n\n            async def _run_one_job(job_id: str, _req) -> None:\n                \"\"\"Mark record as succeeded and attach deterministic result payload.\"\"\"\n\n                record.status = \"succeeded\"\n                record.result = {\"job_id\": job_id, \"ok\": True}\n\n            async def _cleanup_job_temp_files(job_id: str) -> None:\n                \"\"\"Record cleanup invocation for assertion.\"\"\"\n\n                cleanup_calls.append(job_id)\n\n            await process_queue_item(\n                job_id=\"job-1\",\n                req=SimpleNamespace(),\n                app_state=app_state,\n                store=store,\n                run_one_job=_run_one_job,\n                cleanup_job_temp_files=_cleanup_job_temp_files,\n            )\n\n            msg1 = await progress_queue.get()\n            msg2 = await progress_queue.get()\n            self.assertEqual({\"type\": \"result\", \"result\": {\"job_id\": \"job-1\", \"ok\": True}}, msg1)\n            self.assertEqual({\"type\": \"done\"}, msg2)\n            self.assertTrue(done_event.was_set)\n            self.assertEqual([], app_state.pending_ids)\n            self.assertEqual([\"job-1\"], cleanup_calls)\n            self.assertEqual(1, app_state.job_queue.task_done_calls)\n\n        asyncio.run(_run())\n\n    def test_process_queue_item_failure_marks_failed_and_notifies_error(self):\n        \"\"\"Failure path should mark failed, emit error+done, and perform cleanup.\"\"\"\n\n        async def _run() -> None:\n            \"\"\"Execute failure-path queue item processing and assert error signaling.\"\"\"\n\n            progress_queue = asyncio.Queue()\n            done_event = _DoneEvent()\n            record = SimpleNamespace(\n                status=\"running\",\n                result=None,\n                error=None,\n                progress_queue=progress_queue,\n                done_event=done_event,\n            )\n            store = _FakeStore(record=record)\n            app_state = SimpleNamespace(\n                pending_lock=asyncio.Lock(),\n                pending_ids=[\"job-2\"],\n                job_queue=_FakeJobQueue(),\n            )\n            cleanup_calls = []\n\n            async def _run_one_job(_job_id: str, _req) -> None:\n                \"\"\"Raise deterministic runtime error to exercise failure branch.\"\"\"\n\n                raise RuntimeError(\"boom\")\n\n            async def _cleanup_job_temp_files(job_id: str) -> None:\n                \"\"\"Record cleanup invocation for assertion.\"\"\"\n\n                cleanup_calls.append(job_id)\n\n            await process_queue_item(\n                job_id=\"job-2\",\n                req=SimpleNamespace(),\n                app_state=app_state,\n                store=store,\n                run_one_job=_run_one_job,\n                cleanup_job_temp_files=_cleanup_job_temp_files,\n            )\n\n            msg1 = await progress_queue.get()\n            msg2 = await progress_queue.get()\n            self.assertEqual({\"type\": \"error\", \"content\": \"boom\"}, msg1)\n            self.assertEqual({\"type\": \"done\"}, msg2)\n            self.assertTrue(done_event.was_set)\n            self.assertEqual([(\"job-2\", \"boom\")], store.mark_failed_calls)\n            self.assertEqual([], app_state.pending_ids)\n            self.assertEqual([\"job-2\"], cleanup_calls)\n            self.assertEqual(1, app_state.job_queue.task_done_calls)\n\n        asyncio.run(_run())\n\n    def test_run_job_store_cleanup_loop_logs_cleanup_and_stops_on_cancel(self):\n        \"\"\"Cleanup loop should log cleanup stats and exit on cancellation.\"\"\"\n\n        async def _run() -> None:\n            \"\"\"Run one cleanup iteration and then cancel to verify graceful exit.\"\"\"\n\n            store = _FakeStore()\n            store.cleanup_returns = [2]\n            store.stats = {\"total\": 3, \"succeeded\": 2, \"failed\": 1}\n            logs = []\n            calls = {\"count\": 0}\n\n            async def _sleep_fn(_seconds: float) -> None:\n                \"\"\"Allow first tick, then cancel loop on second tick.\"\"\"\n\n                calls[\"count\"] += 1\n                if calls[\"count\"] == 1:\n                    return\n                raise asyncio.CancelledError\n\n            await run_job_store_cleanup_loop(\n                store=store,\n                cleanup_interval_seconds=1,\n                sleep_fn=_sleep_fn,\n                log_fn=logs.append,\n            )\n\n            self.assertEqual(1, store.cleanup_call_count)\n            self.assertEqual(1, len(logs))\n            self.assertIn(\"Cleaned up 2 old jobs\", logs[0])\n\n        asyncio.run(_run())\n\n    def test_run_job_store_cleanup_loop_logs_errors_and_continues(self):\n        \"\"\"Cleanup loop should log non-cancel exceptions and continue until cancelled.\"\"\"\n\n        async def _run() -> None:\n            \"\"\"Raise one cleanup error, continue, then cancel on subsequent tick.\"\"\"\n\n            store = _FakeStore()\n            store.cleanup_returns = [RuntimeError(\"cleanup-failed\"), 0]\n            logs = []\n            calls = {\"count\": 0}\n\n            async def _sleep_fn(_seconds: float) -> None:\n                \"\"\"Permit two iterations before raising cancellation.\"\"\"\n\n                calls[\"count\"] += 1\n                if calls[\"count\"] <= 2:\n                    return\n                raise asyncio.CancelledError\n\n            await run_job_store_cleanup_loop(\n                store=store,\n                cleanup_interval_seconds=1,\n                sleep_fn=_sleep_fn,\n                log_fn=logs.append,\n            )\n\n            self.assertGreaterEqual(store.cleanup_call_count, 2)\n            self.assertTrue(any(\"Job cleanup error: cleanup-failed\" in line for line in logs))\n\n        asyncio.run(_run())\n\n\nif __name__ == \"__main__\":\n    unittest.main()\n"
  },
  {
    "path": "acestep/api/lifespan_runtime.py",
    "content": "\"\"\"Lifespan bootstrap helpers for API server runtime state initialization.\"\"\"\n\nfrom __future__ import annotations\n\nimport asyncio\nimport os\nimport sys\nfrom collections import deque\nfrom concurrent.futures import ThreadPoolExecutor\nfrom dataclasses import dataclass\nfrom threading import Lock\nfrom typing import Any, Callable\n\n\n@dataclass\nclass LifespanRuntime:\n    \"\"\"Runtime objects returned after lifespan state initialization.\"\"\"\n\n    cache_root: str\n    tmp_root: str\n    handler: Any\n    llm_handler: Any\n    handler2: Any\n    handler3: Any\n    config_path2: str\n    config_path3: str\n    executor: ThreadPoolExecutor\n\n\ndef _initialize_local_cache(app: Any, cache_root: str) -> None:\n    \"\"\"Initialize local cache store when optional dependency is available.\"\"\"\n\n    try:\n        from acestep.local_cache import get_local_cache\n\n        local_cache_dir = os.path.join(cache_root, \"local_redis\")\n        app.state.local_cache = get_local_cache(local_cache_dir)\n    except ImportError:\n        app.state.local_cache = None\n\n\ndef initialize_lifespan_runtime(\n    *,\n    app: Any,\n    store: Any,\n    queue_maxsize: int,\n    avg_window: int,\n    initial_avg_job_seconds: float,\n    get_project_root: Callable[[], str],\n    initialize_training_state_fn: Callable[[Any], None],\n    ace_handler_cls: Callable[[], Any],\n    llm_handler_cls: Callable[[], Any],\n) -> LifespanRuntime:\n    \"\"\"Initialize process environment, model handlers, and app.state runtime fields.\"\"\"\n\n    for proxy_var in [\"http_proxy\", \"https_proxy\", \"HTTP_PROXY\", \"HTTPS_PROXY\", \"ALL_PROXY\"]:\n        os.environ.pop(proxy_var, None)\n\n    project_root = get_project_root()\n    cache_root = os.path.join(project_root, \".cache\", \"acestep\")\n    tmp_root = (os.getenv(\"ACESTEP_TMPDIR\") or os.path.join(cache_root, \"tmp\")).strip()\n    triton_cache_root = (os.getenv(\"TRITON_CACHE_DIR\") or os.path.join(cache_root, \"triton\")).strip()\n    inductor_cache_root = (\n        (os.getenv(\"TORCHINDUCTOR_CACHE_DIR\") or os.path.join(cache_root, \"torchinductor\")).strip()\n    )\n\n    for path in [cache_root, tmp_root, triton_cache_root, inductor_cache_root]:\n        try:\n            os.makedirs(path, exist_ok=True)\n        except Exception:\n            pass\n\n    if os.getenv(\"ACESTEP_TMPDIR\"):\n        os.environ[\"TMPDIR\"] = tmp_root\n        os.environ[\"TEMP\"] = tmp_root\n        os.environ[\"TMP\"] = tmp_root\n    else:\n        os.environ.setdefault(\"TMPDIR\", tmp_root)\n        os.environ.setdefault(\"TEMP\", tmp_root)\n        os.environ.setdefault(\"TMP\", tmp_root)\n\n    os.environ.setdefault(\"TRITON_CACHE_DIR\", triton_cache_root)\n    os.environ.setdefault(\"TORCHINDUCTOR_CACHE_DIR\", inductor_cache_root)\n\n    handler = ace_handler_cls()\n    llm_handler = llm_handler_cls()\n    init_lock = asyncio.Lock()\n    app.state._initialized = False\n    app.state._init_error = None\n    app.state._init_lock = init_lock\n\n    app.state.llm_handler = llm_handler\n    app.state._llm_initialized = False\n    app.state._llm_init_error = None\n    app.state._llm_init_lock = Lock()\n    app.state._llm_lazy_load_disabled = False\n\n    handler2 = None\n    handler3 = None\n    config_path2 = os.getenv(\"ACESTEP_CONFIG_PATH2\", \"\").strip()\n    config_path3 = os.getenv(\"ACESTEP_CONFIG_PATH3\", \"\").strip()\n    if config_path2:\n        handler2 = ace_handler_cls()\n    if config_path3:\n        handler3 = ace_handler_cls()\n\n    app.state.handler2 = handler2\n    app.state.handler3 = handler3\n    app.state._initialized2 = False\n    app.state._initialized3 = False\n    app.state._config_path = os.getenv(\"ACESTEP_CONFIG_PATH\", \"acestep-v15-turbo\")\n    app.state._config_path2 = config_path2\n    app.state._config_path3 = config_path3\n\n    max_workers = int(os.getenv(\"ACESTEP_API_WORKERS\", \"1\"))\n    executor = ThreadPoolExecutor(max_workers=max_workers)\n\n    app.state.job_queue = asyncio.Queue(maxsize=queue_maxsize)\n    app.state.pending_ids = deque()\n    app.state.pending_lock = asyncio.Lock()\n    app.state.job_temp_files = {}\n    app.state.job_temp_files_lock = asyncio.Lock()\n    app.state.stats_lock = asyncio.Lock()\n    app.state.recent_durations = deque(maxlen=avg_window)\n    app.state.avg_job_seconds = initial_avg_job_seconds\n\n    app.state.handler = handler\n    app.state.executor = executor\n    app.state.job_store = store\n    app.state._python_executable = sys.executable\n    initialize_training_state_fn(app)\n\n    app.state.temp_audio_dir = os.path.join(tmp_root, \"api_audio\")\n    os.makedirs(app.state.temp_audio_dir, exist_ok=True)\n    _initialize_local_cache(app, cache_root)\n\n    return LifespanRuntime(\n        cache_root=cache_root,\n        tmp_root=tmp_root,\n        handler=handler,\n        llm_handler=llm_handler,\n        handler2=handler2,\n        handler3=handler3,\n        config_path2=config_path2,\n        config_path3=config_path3,\n        executor=executor,\n    )\n"
  },
  {
    "path": "acestep/api/lifespan_runtime_test.py",
    "content": "\"\"\"Unit tests for lifespan runtime bootstrap helper.\"\"\"\n\nfrom __future__ import annotations\n\nimport os\nimport unittest\nfrom types import SimpleNamespace\nfrom unittest.mock import MagicMock, patch\n\nfrom acestep.api.lifespan_runtime import initialize_lifespan_runtime\n\n\nclass LifespanRuntimeTests(unittest.TestCase):\n    \"\"\"Behavior tests for API lifespan runtime/state initialization.\"\"\"\n\n    @patch(\"acestep.api.lifespan_runtime._initialize_local_cache\")\n    @patch(\"acestep.api.lifespan_runtime.os.makedirs\")\n    def test_initialize_lifespan_runtime_sets_expected_default_state(\n        self,\n        mock_makedirs: MagicMock,\n        mock_initialize_local_cache: MagicMock,\n    ) -> None:\n        \"\"\"Bootstrap helper should initialize default app.state runtime fields.\"\"\"\n\n        app = SimpleNamespace(state=SimpleNamespace())\n        store = object()\n        training_state_init = MagicMock()\n        handler = MagicMock(name=\"handler\")\n        ace_handler_cls = MagicMock(return_value=handler)\n        llm_handler = MagicMock(name=\"llm_handler\")\n        llm_handler_cls = MagicMock(return_value=llm_handler)\n\n        with patch.dict(os.environ, {}, clear=True):\n            runtime = initialize_lifespan_runtime(\n                app=app,\n                store=store,\n                queue_maxsize=200,\n                avg_window=50,\n                initial_avg_job_seconds=5.0,\n                get_project_root=MagicMock(return_value=\"k:/repo\"),\n                initialize_training_state_fn=training_state_init,\n                ace_handler_cls=ace_handler_cls,\n                llm_handler_cls=llm_handler_cls,\n            )\n\n        self.assertEqual(200, app.state.job_queue.maxsize)\n        self.assertEqual(5.0, app.state.avg_job_seconds)\n        self.assertEqual(\"acestep-v15-turbo\", app.state._config_path)\n        self.assertIs(app.state.handler, handler)\n        self.assertIs(app.state.llm_handler, llm_handler)\n        self.assertIsNone(runtime.handler2)\n        self.assertIsNone(runtime.handler3)\n        training_state_init.assert_called_once_with(app)\n        mock_initialize_local_cache.assert_called_once_with(app, runtime.cache_root)\n        self.assertTrue(mock_makedirs.called)\n\n    @patch(\"acestep.api.lifespan_runtime._initialize_local_cache\")\n    @patch(\"acestep.api.lifespan_runtime.os.makedirs\")\n    def test_initialize_lifespan_runtime_supports_secondary_and_third_model_handlers(\n        self,\n        _mock_makedirs: MagicMock,\n        _mock_initialize_local_cache: MagicMock,\n    ) -> None:\n        \"\"\"Bootstrap helper should create extra handlers when secondary config paths exist.\"\"\"\n\n        app = SimpleNamespace(state=SimpleNamespace())\n        store = object()\n        training_state_init = MagicMock()\n        handler_values = [MagicMock(), MagicMock(), MagicMock()]\n        ace_handler_cls = MagicMock(side_effect=handler_values)\n        llm_handler_cls = MagicMock(return_value=MagicMock())\n\n        with patch.dict(\n            os.environ,\n            {\n                \"ACESTEP_TMPDIR\": \"k:/tmp/acestep\",\n                \"ACESTEP_CONFIG_PATH2\": \"acestep-v15-second\",\n                \"ACESTEP_CONFIG_PATH3\": \"acestep-v15-third\",\n                \"ACESTEP_API_WORKERS\": \"3\",\n            },\n            clear=True,\n        ):\n            runtime = initialize_lifespan_runtime(\n                app=app,\n                store=store,\n                queue_maxsize=50,\n                avg_window=20,\n                initial_avg_job_seconds=2.5,\n                get_project_root=MagicMock(return_value=\"k:/repo\"),\n                initialize_training_state_fn=training_state_init,\n                ace_handler_cls=ace_handler_cls,\n                llm_handler_cls=llm_handler_cls,\n            )\n            self.assertEqual(\"k:/tmp/acestep\", os.environ.get(\"TMPDIR\"))\n\n        self.assertIsNotNone(runtime.handler2)\n        self.assertIsNotNone(runtime.handler3)\n        self.assertEqual(\"acestep-v15-second\", runtime.config_path2)\n        self.assertEqual(\"acestep-v15-third\", runtime.config_path3)\n        self.assertEqual(\"acestep-v15-second\", app.state._config_path2)\n        self.assertEqual(\"acestep-v15-third\", app.state._config_path3)\n        self.assertTrue(str(app.state.temp_audio_dir).endswith(\"api_audio\"))\n\n\nif __name__ == \"__main__\":\n    unittest.main()\n"
  },
  {
    "path": "acestep/api/llm_generation_inputs.py",
    "content": "\"\"\"LLM-driven request input preparation helpers for generation jobs.\"\"\"\n\nfrom __future__ import annotations\n\nfrom dataclasses import dataclass\nfrom typing import Any, Callable, Optional\n\n\n@dataclass\nclass PreparedLlmInputs:\n    \"\"\"Resolved LLM flags and generation input values.\"\"\"\n\n    lm_top_k: int\n    lm_top_p: float\n    thinking: bool\n    sample_mode: bool\n    use_cot_caption: bool\n    use_cot_language: bool\n    full_analysis_only: bool\n    caption: str\n    lyrics: str\n    bpm: Any\n    key_scale: Any\n    time_signature: Any\n    audio_duration: Any\n    original_prompt: str\n    original_lyrics: str\n    format_has_duration: bool\n    global_caption: str = \"\"\n\n\ndef prepare_llm_generation_inputs(\n    *,\n    app_state: Any,\n    llm_handler: Any,\n    req: Any,\n    selected_handler_device: str,\n    parse_description_hints: Callable[[str], tuple[Optional[str], bool]],\n    create_sample_fn: Callable[..., Any],\n    format_sample_fn: Callable[..., Any],\n    ensure_llm_ready_fn: Callable[[], None],\n    log_fn: Callable[[str], None] = print,\n) -> PreparedLlmInputs:\n    \"\"\"Resolve LLM flags and prepare caption/lyrics/metadata inputs for generation.\n\n    Args:\n        app_state: FastAPI app state with LLM initialization flags.\n        llm_handler: LLM handler instance.\n        req: Generation request object.\n        selected_handler_device: Device of the active diffusion handler.\n        parse_description_hints: Helper to infer language/instrumental hints.\n        create_sample_fn: Function that generates sample caption/lyrics metadata.\n        format_sample_fn: Function that formats sample metadata from caption/lyrics.\n        ensure_llm_ready_fn: Callback that lazily initializes the LLM.\n        log_fn: Logging callback for status output.\n\n    Returns:\n        PreparedLlmInputs: Normalized generation inputs and LLM flags.\n\n    Raises:\n        RuntimeError: If required LLM functionality is unavailable or sampling fails.\n    \"\"\"\n\n    lm_top_k = req.lm_top_k if req.lm_top_k and req.lm_top_k > 0 else 0\n    lm_top_p = req.lm_top_p if req.lm_top_p and req.lm_top_p < 1.0 else 0.9\n\n    thinking = bool(req.thinking)\n    sample_mode = bool(req.sample_mode)\n    has_sample_query = bool(req.sample_query and req.sample_query.strip())\n    use_format = bool(req.use_format)\n    use_cot_caption = bool(req.use_cot_caption)\n    use_cot_language = bool(req.use_cot_language)\n    full_analysis_only = bool(req.full_analysis_only)\n\n    if req.task_type == \"cover\" and selected_handler_device == \"mps\":\n        if getattr(app_state, \"_llm_initialized\", False) and getattr(\n            llm_handler, \"llm_initialized\", False\n        ):\n            try:\n                log_fn(\"[API Server] unloading.\")\n                llm_handler.unload()\n                app_state._llm_initialized = False\n                app_state._llm_init_error = None\n            except Exception as exc:\n                log_fn(f\"[API Server] Failed to unload LM: {exc}\")\n\n    require_llm = thinking or sample_mode or has_sample_query or use_format or full_analysis_only\n    want_llm = use_cot_caption or use_cot_language\n\n    llm_available = True\n    if require_llm or want_llm:\n        ensure_llm_ready_fn()\n        if getattr(app_state, \"_llm_init_error\", None):\n            llm_available = False\n\n    if require_llm and not llm_available:\n        raise RuntimeError(f\"5Hz LM init failed: {app_state._llm_init_error}\")\n\n    if want_llm and not llm_available:\n        if use_cot_caption or use_cot_language:\n            log_fn(\n                \"[API Server] LLM unavailable, auto-disabling: \"\n                f\"use_cot_caption={use_cot_caption}->False, use_cot_language={use_cot_language}->False\"\n            )\n        use_cot_caption = False\n        use_cot_language = False\n\n    caption = req.prompt\n    lyrics = req.lyrics\n    bpm = req.bpm\n    key_scale = req.key_scale\n    time_signature = req.time_signature\n    audio_duration = req.audio_duration\n\n    original_prompt = req.prompt or \"\"\n    original_lyrics = req.lyrics or \"\"\n\n    if sample_mode or has_sample_query:\n        sample_query = req.sample_query if has_sample_query else \"NO USER INPUT\"\n        parsed_language, parsed_instrumental = parse_description_hints(sample_query)\n\n        if req.vocal_language and req.vocal_language not in (\"en\", \"unknown\", \"\"):\n            sample_language = req.vocal_language\n        else:\n            sample_language = parsed_language\n\n        sample_result = create_sample_fn(\n            llm_handler=llm_handler,\n            query=sample_query,\n            instrumental=parsed_instrumental,\n            vocal_language=sample_language,\n            temperature=req.lm_temperature,\n            top_k=lm_top_k if lm_top_k > 0 else None,\n            top_p=lm_top_p if lm_top_p < 1.0 else None,\n            use_constrained_decoding=True,\n        )\n\n        if not sample_result.success:\n            raise RuntimeError(f\"create_sample failed: {sample_result.error or sample_result.status_message}\")\n\n        caption = sample_result.caption\n        lyrics = sample_result.lyrics\n        bpm = sample_result.bpm\n        key_scale = sample_result.keyscale\n        time_signature = sample_result.timesignature\n        audio_duration = sample_result.duration\n\n    format_has_duration = False\n    if req.use_format and (caption or lyrics):\n        ensure_llm_ready_fn()\n        if getattr(app_state, \"_llm_init_error\", None):\n            raise RuntimeError(f\"5Hz LM init failed (needed for format): {app_state._llm_init_error}\")\n\n        user_metadata_for_format = {}\n        if bpm is not None:\n            user_metadata_for_format[\"bpm\"] = bpm\n        if audio_duration is not None and float(audio_duration) > 0:\n            user_metadata_for_format[\"duration\"] = float(audio_duration)\n        if key_scale:\n            user_metadata_for_format[\"keyscale\"] = key_scale\n        if time_signature:\n            user_metadata_for_format[\"timesignature\"] = time_signature\n        if req.vocal_language and req.vocal_language != \"unknown\":\n            user_metadata_for_format[\"language\"] = req.vocal_language\n\n        format_result = format_sample_fn(\n            llm_handler=llm_handler,\n            caption=caption,\n            lyrics=lyrics,\n            user_metadata=user_metadata_for_format if user_metadata_for_format else None,\n            temperature=req.lm_temperature,\n            top_k=lm_top_k if lm_top_k > 0 else None,\n            top_p=lm_top_p if lm_top_p < 1.0 else None,\n            use_constrained_decoding=True,\n        )\n        if format_result.success:\n            caption = format_result.caption or caption\n            lyrics = format_result.lyrics or lyrics\n            if format_result.duration:\n                audio_duration = format_result.duration\n                format_has_duration = True\n            if format_result.bpm:\n                bpm = format_result.bpm\n            if format_result.keyscale:\n                key_scale = format_result.keyscale\n            if format_result.timesignature:\n                time_signature = format_result.timesignature\n\n    return PreparedLlmInputs(\n        lm_top_k=lm_top_k,\n        lm_top_p=lm_top_p,\n        thinking=thinking,\n        sample_mode=sample_mode,\n        use_cot_caption=use_cot_caption,\n        use_cot_language=use_cot_language,\n        full_analysis_only=full_analysis_only,\n        caption=caption,\n        lyrics=lyrics,\n        bpm=bpm,\n        key_scale=key_scale,\n        time_signature=time_signature,\n        audio_duration=audio_duration,\n        original_prompt=original_prompt,\n        original_lyrics=original_lyrics,\n        format_has_duration=format_has_duration,\n        global_caption=getattr(req, \"global_caption\", \"\") or \"\",\n    )\n"
  },
  {
    "path": "acestep/api/llm_readiness.py",
    "content": "\"\"\"LLM readiness helper for generation requests.\"\"\"\n\nfrom __future__ import annotations\n\nimport os\nfrom typing import Any, Callable\n\n\ndef ensure_llm_ready_for_request(\n    *,\n    app_state: Any,\n    llm_handler: Any,\n    req: Any,\n    get_project_root: Callable[[], str],\n    get_model_name: Callable[[str], str],\n    ensure_model_downloaded: Callable[[str, str], str],\n    env_bool: Callable[[str, bool], bool],\n    log_fn: Callable[[str], None] = print,\n) -> None:\n    \"\"\"Initialize LLM on-demand for a request unless lazy loading is blocked.\n\n    Args:\n        app_state: FastAPI app state with LLM init flags and lock.\n        llm_handler: LLM handler instance.\n        req: Request object carrying optional LM overrides.\n        get_project_root: Callback that returns project root path.\n        get_model_name: Callback that maps model path to model name.\n        ensure_model_downloaded: Callback to ensure checkpoint availability.\n        env_bool: Boolean env parser callback.\n        log_fn: Logging callback for user-visible status messages.\n    \"\"\"\n\n    with app_state._llm_init_lock:\n        initialized = getattr(app_state, \"_llm_initialized\", False)\n        had_error = getattr(app_state, \"_llm_init_error\", None)\n        if initialized or had_error is not None:\n            return\n        log_fn(\"[API Server] reloading.\")\n\n        if getattr(app_state, \"_llm_lazy_load_disabled\", False):\n            app_state._llm_init_error = (\n                \"LLM not initialized at startup. To enable LLM, set ACESTEP_INIT_LLM=true \"\n                \"in .env or environment variables. For this request, optional LLM features \"\n                \"(use_cot_caption, use_cot_language) will be auto-disabled.\"\n            )\n            log_fn(\"[API Server] LLM lazy load blocked: LLM was not initialized at startup\")\n            return\n\n        init_llm_env = os.getenv(\"ACESTEP_INIT_LLM\", \"\").strip().lower()\n        if init_llm_env in {\"0\", \"false\", \"no\", \"n\", \"off\"}:\n            app_state._llm_lazy_load_disabled = True\n            app_state._llm_init_error = (\n                \"LLM disabled via ACESTEP_INIT_LLM=false. \"\n                \"Optional LLM features (use_cot_caption, use_cot_language) will be auto-disabled.\"\n            )\n            log_fn(\"[API Server] LLM lazy load blocked: ACESTEP_INIT_LLM=false\")\n            return\n\n        project_root = get_project_root()\n        checkpoint_dir = os.path.join(project_root, \"checkpoints\")\n        lm_model_path = (\n            req.lm_model_path or os.getenv(\"ACESTEP_LM_MODEL_PATH\") or \"acestep-5Hz-lm-0.6B\"\n        ).strip()\n        backend = (req.lm_backend or os.getenv(\"ACESTEP_LM_BACKEND\") or \"vllm\").strip().lower()\n        if backend not in {\"vllm\", \"pt\", \"mlx\"}:\n            backend = \"vllm\"\n\n        lm_model_name = get_model_name(lm_model_path)\n        if lm_model_name:\n            try:\n                ensure_model_downloaded(lm_model_name, checkpoint_dir)\n            except Exception as exc:\n                log_fn(f\"[API Server] Warning: Failed to download LM model {lm_model_name}: {exc}\")\n\n        lm_device = os.getenv(\"ACESTEP_LM_DEVICE\", os.getenv(\"ACESTEP_DEVICE\", \"auto\"))\n        lm_offload = env_bool(\"ACESTEP_LM_OFFLOAD_TO_CPU\", False)\n        status, ok = llm_handler.initialize(\n            checkpoint_dir=checkpoint_dir,\n            lm_model_path=lm_model_path,\n            backend=backend,\n            device=lm_device,\n            offload_to_cpu=lm_offload,\n            dtype=None,\n        )\n        if not ok:\n            app_state._llm_init_error = status\n        else:\n            app_state._llm_initialized = True\n"
  },
  {
    "path": "acestep/api/log_capture.py",
    "content": "\"\"\"Log capture utilities for API progress/status endpoints.\"\"\"\n\nfrom __future__ import annotations\n\nfrom typing import Any\n\n\nclass LogBuffer:\n    \"\"\"Minimal write buffer storing the latest non-empty log line.\"\"\"\n\n    def __init__(self):\n        \"\"\"Initialize buffer with default waiting status.\"\"\"\n\n        self.last_message = \"Waiting\"\n\n    def write(self, message: str) -> None:\n        \"\"\"Capture latest non-empty stripped message.\"\"\"\n\n        msg = message.strip()\n        if msg:\n            self.last_message = msg\n\n    def flush(self) -> None:\n        \"\"\"No-op flush to satisfy file-like API expectations.\"\"\"\n\n        return None\n\n\nclass StderrLogger:\n    \"\"\"Stderr proxy forwarding writes to original stderr and log buffer.\"\"\"\n\n    def __init__(self, original_stderr: Any, buffer: LogBuffer):\n        \"\"\"Initialize stderr proxy references.\"\"\"\n\n        self.original_stderr = original_stderr\n        self.buffer = buffer\n\n    def write(self, message: str) -> None:\n        \"\"\"Write to terminal stderr and update in-memory buffer.\"\"\"\n\n        self.original_stderr.write(message)\n        self.buffer.write(message)\n\n    def flush(self) -> None:\n        \"\"\"Flush original stderr stream.\"\"\"\n\n        self.original_stderr.flush()\n\n\ndef install_log_capture(logger_obj: Any, stderr_obj: Any) -> tuple[LogBuffer, StderrLogger]:\n    \"\"\"Install log sink and stderr proxy for API status polling.\n\n    Args:\n        logger_obj: Logger exposing ``add`` method (for example loguru logger).\n        stderr_obj: Existing stderr stream object.\n\n    Returns:\n        Tuple of ``(log_buffer, stderr_proxy)``.\n    \"\"\"\n\n    log_buffer = LogBuffer()\n    logger_obj.add(\n        lambda msg: log_buffer.write(str(msg)),\n        format=\"{time:HH:mm:ss} | {level} | {message}\",\n    )\n    stderr_proxy = StderrLogger(stderr_obj, log_buffer)\n    return log_buffer, stderr_proxy\n"
  },
  {
    "path": "acestep/api/log_capture_test.py",
    "content": "\"\"\"Unit tests for API log capture utilities.\"\"\"\n\nfrom __future__ import annotations\n\nimport io\nimport unittest\n\nfrom acestep.api.log_capture import LogBuffer, StderrLogger, install_log_capture\n\n\nclass _FakeLogger:\n    \"\"\"Minimal fake logger storing added sink callback metadata.\"\"\"\n\n    def __init__(self):\n        self.calls = []\n\n    def add(self, sink, format):\n        self.calls.append((sink, format))\n        return 1\n\n\nclass LogCaptureTests(unittest.TestCase):\n    \"\"\"Behavior tests for API log buffer and stderr proxy helpers.\"\"\"\n\n    def test_log_buffer_updates_last_message(self) -> None:\n        \"\"\"Buffer should keep latest non-empty stripped message.\"\"\"\n\n        buffer = LogBuffer()\n        self.assertEqual(\"Waiting\", buffer.last_message)\n        buffer.write(\"   \\n\")\n        self.assertEqual(\"Waiting\", buffer.last_message)\n        buffer.write(\"hello\\n\")\n        self.assertEqual(\"hello\", buffer.last_message)\n\n    def test_stderr_logger_forwards_to_stream_and_buffer(self) -> None:\n        \"\"\"Stderr proxy should write both to original stream and memory buffer.\"\"\"\n\n        stream = io.StringIO()\n        buffer = LogBuffer()\n        proxy = StderrLogger(stream, buffer)\n        proxy.write(\"line\\n\")\n        proxy.flush()\n        self.assertEqual(\"line\\n\", stream.getvalue())\n        self.assertEqual(\"line\", buffer.last_message)\n\n    def test_install_log_capture_registers_sink_and_returns_proxy(self) -> None:\n        \"\"\"Installer should register a sink and return connected buffer/proxy.\"\"\"\n\n        fake_logger = _FakeLogger()\n        stream = io.StringIO()\n        buffer, proxy = install_log_capture(fake_logger, stream)\n        self.assertIsInstance(buffer, LogBuffer)\n        self.assertIsInstance(proxy, StderrLogger)\n        self.assertEqual(1, len(fake_logger.calls))\n        sink, sink_format = fake_logger.calls[0]\n        self.assertIn(\"{level}\", sink_format)\n        sink(\"custom message\")\n        self.assertEqual(\"custom message\", buffer.last_message)\n\n\nif __name__ == \"__main__\":\n    unittest.main()\n"
  },
  {
    "path": "acestep/api/model_download.py",
    "content": "\"\"\"Model auto-download helpers extracted from API server runtime.\"\"\"\n\nfrom __future__ import annotations\n\nimport os\n\n\nMODEL_REPO_MAPPING = {\n    \"acestep-v15-turbo\": \"ACE-Step/Ace-Step1.5\",\n    \"acestep-5Hz-lm-1.7B\": \"ACE-Step/Ace-Step1.5\",\n    \"vae\": \"ACE-Step/Ace-Step1.5\",\n    \"Qwen3-Embedding-0.6B\": \"ACE-Step/Ace-Step1.5\",\n    \"acestep-5Hz-lm-0.6B\": \"ACE-Step/acestep-5Hz-lm-0.6B\",\n    \"acestep-5Hz-lm-4B\": \"ACE-Step/acestep-5Hz-lm-4B\",\n    \"acestep-v15-base\": \"ACE-Step/acestep-v15-base\",\n    \"acestep-v15-sft\": \"ACE-Step/acestep-v15-sft\",\n    \"acestep-v15-turbo-shift3\": \"ACE-Step/acestep-v15-turbo-shift3\",\n}\n\nDEFAULT_REPO_ID = \"ACE-Step/Ace-Step1.5\"\n\n\ndef can_access_google(timeout: float = 3.0) -> bool:\n    \"\"\"Check if Google is reachable to select preferred model source.\"\"\"\n\n    import socket\n\n    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)\n    try:\n        sock.settimeout(timeout)\n        sock.connect((\"www.google.com\", 443))\n        return True\n    except (socket.timeout, socket.error, OSError):\n        return False\n    finally:\n        sock.close()\n\n\ndef download_from_huggingface(repo_id: str, local_dir: str, model_name: str) -> str:\n    \"\"\"Download model snapshot from HuggingFace Hub.\"\"\"\n\n    from huggingface_hub import snapshot_download\n\n    is_unified_repo = repo_id == DEFAULT_REPO_ID or repo_id == \"ACE-Step/Ace-Step1.5\"\n\n    if is_unified_repo:\n        download_dir = local_dir\n        print(f\"[Model Download] Downloading unified repo {repo_id} to {download_dir}...\")\n    else:\n        download_dir = os.path.join(local_dir, model_name)\n        os.makedirs(download_dir, exist_ok=True)\n        print(f\"[Model Download] Downloading {model_name} from {repo_id} to {download_dir}...\")\n\n    snapshot_download(\n        repo_id=repo_id,\n        local_dir=download_dir,\n        local_dir_use_symlinks=False,\n    )\n\n    return os.path.join(local_dir, model_name)\n\n\ndef download_from_modelscope(repo_id: str, local_dir: str, model_name: str) -> str:\n    \"\"\"Download model snapshot from ModelScope.\"\"\"\n\n    from modelscope import snapshot_download\n\n    is_unified_repo = repo_id == DEFAULT_REPO_ID or repo_id == \"ACE-Step/Ace-Step1.5\"\n\n    if is_unified_repo:\n        download_dir = local_dir\n        print(f\"[Model Download] Downloading unified repo {repo_id} from ModelScope to {download_dir}...\")\n    else:\n        download_dir = os.path.join(local_dir, model_name)\n        os.makedirs(download_dir, exist_ok=True)\n        print(f\"[Model Download] Downloading {model_name} from ModelScope {repo_id} to {download_dir}...\")\n\n    try:\n        result_path = snapshot_download(\n            model_id=repo_id,\n            local_dir=download_dir,\n        )\n        print(f\"[Model Download] ModelScope download completed: {result_path}\")\n    except TypeError:\n        print(\"[Model Download] Retrying with cache_dir parameter...\")\n        result_path = snapshot_download(\n            model_id=repo_id,\n            cache_dir=download_dir,\n        )\n        print(f\"[Model Download] ModelScope download completed: {result_path}\")\n\n    return os.path.join(local_dir, model_name)\n\n\ndef ensure_model_downloaded(model_name: str, checkpoint_dir: str) -> str:\n    \"\"\"Ensure model exists locally, downloading from configured source if missing.\"\"\"\n\n    model_path = os.path.join(checkpoint_dir, model_name)\n\n    if os.path.exists(model_path) and os.listdir(model_path):\n        print(f\"[Model Download] Model {model_name} already exists at {model_path}\")\n        return model_path\n\n    repo_id = MODEL_REPO_MAPPING.get(model_name, DEFAULT_REPO_ID)\n    print(f\"[Model Download] Model {model_name} not found, checking network...\")\n\n    prefer_source = os.environ.get(\"ACESTEP_DOWNLOAD_SOURCE\", \"\").lower()\n    if prefer_source == \"huggingface\":\n        use_huggingface = True\n        print(\"[Model Download] User preference: HuggingFace Hub\")\n    elif prefer_source == \"modelscope\":\n        use_huggingface = False\n        print(\"[Model Download] User preference: ModelScope\")\n    else:\n        use_huggingface = can_access_google()\n        print(f\"[Model Download] Auto-detected: {'HuggingFace Hub' if use_huggingface else 'ModelScope'}\")\n\n    if use_huggingface:\n        print(\"[Model Download] Using HuggingFace Hub...\")\n        try:\n            return download_from_huggingface(repo_id, checkpoint_dir, model_name)\n        except Exception as exc:\n            print(f\"[Model Download] HuggingFace download failed: {exc}\")\n            print(\"[Model Download] Falling back to ModelScope...\")\n            return download_from_modelscope(repo_id, checkpoint_dir, model_name)\n\n    print(\"[Model Download] Using ModelScope...\")\n    try:\n        return download_from_modelscope(repo_id, checkpoint_dir, model_name)\n    except Exception as exc:\n        print(f\"[Model Download] ModelScope download failed: {exc}\")\n        print(\"[Model Download] Trying HuggingFace as fallback...\")\n        return download_from_huggingface(repo_id, checkpoint_dir, model_name)\n"
  },
  {
    "path": "acestep/api/model_download_test.py",
    "content": "\"\"\"Unit tests for API model auto-download helper functions.\"\"\"\n\nfrom __future__ import annotations\n\nimport os\nimport types\nimport unittest\nfrom unittest import mock\n\nfrom acestep.api import model_download\n\n\nclass ModelDownloadTests(unittest.TestCase):\n    \"\"\"Behavior tests for extracted model download helper module.\"\"\"\n\n    def test_download_from_huggingface_uses_unified_repo_target_dir(self):\n        \"\"\"Unified repo downloads should target local_dir directly.\"\"\"\n\n        snapshot_download = mock.Mock(return_value=\"ok\")\n        fake_hf = types.SimpleNamespace(snapshot_download=snapshot_download)\n        with mock.patch.dict(\"sys.modules\", {\"huggingface_hub\": fake_hf}):\n            out = model_download.download_from_huggingface(\n                repo_id=model_download.DEFAULT_REPO_ID,\n                local_dir=\"checkpoints\",\n                model_name=\"acestep-v15-turbo\",\n            )\n\n        snapshot_download.assert_called_once_with(\n            repo_id=model_download.DEFAULT_REPO_ID,\n            local_dir=\"checkpoints\",\n            local_dir_use_symlinks=False,\n        )\n        self.assertEqual(os.path.join(\"checkpoints\", \"acestep-v15-turbo\"), out)\n\n    def test_download_from_modelscope_retries_with_cache_dir_on_type_error(self):\n        \"\"\"ModelScope download should retry with cache_dir for compatibility.\"\"\"\n\n        snapshot_download = mock.Mock(side_effect=[TypeError(\"bad\"), \"ok\"])\n        fake_ms = types.SimpleNamespace(snapshot_download=snapshot_download)\n        with mock.patch.dict(\"sys.modules\", {\"modelscope\": fake_ms}):\n            out = model_download.download_from_modelscope(\n                repo_id=model_download.DEFAULT_REPO_ID,\n                local_dir=\"checkpoints\",\n                model_name=\"acestep-v15-turbo\",\n            )\n\n        self.assertEqual(2, snapshot_download.call_count)\n        first_call = snapshot_download.call_args_list[0].kwargs\n        second_call = snapshot_download.call_args_list[1].kwargs\n        self.assertEqual(\n            {\"model_id\": model_download.DEFAULT_REPO_ID, \"local_dir\": \"checkpoints\"},\n            first_call,\n        )\n        self.assertEqual(\n            {\"model_id\": model_download.DEFAULT_REPO_ID, \"cache_dir\": \"checkpoints\"},\n            second_call,\n        )\n        self.assertEqual(os.path.join(\"checkpoints\", \"acestep-v15-turbo\"), out)\n\n    def test_ensure_model_downloaded_returns_existing_model_path(self):\n        \"\"\"Ensure helper should return existing model path without download attempts.\"\"\"\n\n        with mock.patch(\"acestep.api.model_download.os.path.exists\", return_value=True), mock.patch(\n            \"acestep.api.model_download.os.listdir\",\n            return_value=[\"weights.safetensors\"],\n        ), mock.patch(\"acestep.api.model_download.download_from_huggingface\") as hf_mock, mock.patch(\n            \"acestep.api.model_download.download_from_modelscope\"\n        ) as ms_mock:\n            out = model_download.ensure_model_downloaded(\"acestep-v15-turbo\", \"checkpoints\")\n\n        self.assertEqual(os.path.join(\"checkpoints\", \"acestep-v15-turbo\"), out)\n        hf_mock.assert_not_called()\n        ms_mock.assert_not_called()\n\n    def test_ensure_model_downloaded_uses_huggingface_when_env_prefers_it(self):\n        \"\"\"Ensure helper should honor explicit HuggingFace preference.\"\"\"\n\n        with mock.patch.dict(os.environ, {\"ACESTEP_DOWNLOAD_SOURCE\": \"huggingface\"}, clear=False), mock.patch(\n            \"acestep.api.model_download.os.path.exists\",\n            return_value=False,\n        ), mock.patch(\n            \"acestep.api.model_download.download_from_huggingface\",\n            return_value=\"hf-path\",\n        ) as hf_mock, mock.patch(\n            \"acestep.api.model_download.download_from_modelscope\",\n            return_value=\"ms-path\",\n        ) as ms_mock:\n            out = model_download.ensure_model_downloaded(\"acestep-v15-turbo\", \"checkpoints\")\n\n        self.assertEqual(\"hf-path\", out)\n        hf_mock.assert_called_once()\n        ms_mock.assert_not_called()\n\n    def test_ensure_model_downloaded_falls_back_to_modelscope_from_huggingface(self):\n        \"\"\"Ensure helper should fallback to ModelScope when HuggingFace fails.\"\"\"\n\n        with mock.patch.dict(os.environ, {\"ACESTEP_DOWNLOAD_SOURCE\": \"\"}, clear=False), mock.patch(\n            \"acestep.api.model_download.os.path.exists\",\n            return_value=False,\n        ), mock.patch(\"acestep.api.model_download.can_access_google\", return_value=True), mock.patch(\n            \"acestep.api.model_download.download_from_huggingface\",\n            side_effect=RuntimeError(\"hf down\"),\n        ) as hf_mock, mock.patch(\n            \"acestep.api.model_download.download_from_modelscope\",\n            return_value=\"ms-path\",\n        ) as ms_mock:\n            out = model_download.ensure_model_downloaded(\"acestep-v15-turbo\", \"checkpoints\")\n\n        self.assertEqual(\"ms-path\", out)\n        hf_mock.assert_called_once()\n        ms_mock.assert_called_once()\n\n    def test_ensure_model_downloaded_falls_back_to_huggingface_from_modelscope(self):\n        \"\"\"Ensure helper should fallback to HuggingFace when ModelScope fails.\"\"\"\n\n        with mock.patch.dict(os.environ, {\"ACESTEP_DOWNLOAD_SOURCE\": \"\"}, clear=False), mock.patch(\n            \"acestep.api.model_download.os.path.exists\",\n            return_value=False,\n        ), mock.patch(\"acestep.api.model_download.can_access_google\", return_value=False), mock.patch(\n            \"acestep.api.model_download.download_from_modelscope\",\n            side_effect=RuntimeError(\"ms down\"),\n        ) as ms_mock, mock.patch(\n            \"acestep.api.model_download.download_from_huggingface\",\n            return_value=\"hf-path\",\n        ) as hf_mock:\n            out = model_download.ensure_model_downloaded(\"acestep-v15-turbo\", \"checkpoints\")\n\n        self.assertEqual(\"hf-path\", out)\n        ms_mock.assert_called_once()\n        hf_mock.assert_called_once()\n\n\nif __name__ == \"__main__\":\n    unittest.main()\n"
  },
  {
    "path": "acestep/api/route_setup.py",
    "content": "\"\"\"Application route and middleware registration helpers for API server.\"\"\"\n\nfrom __future__ import annotations\n\nfrom functools import partial\nfrom typing import Any, Callable, Dict, List, Optional\n\nfrom fastapi import FastAPI\nfrom fastapi.middleware.cors import CORSMiddleware\nfrom starlette.datastructures import UploadFile as StarletteUploadFile\n\nfrom acestep.api.http.audio_route import register_audio_route\nfrom acestep.api.http.lora_routes import register_lora_routes\nfrom acestep.api.http.model_service_routes import register_model_service_routes\nfrom acestep.api.http.query_result_route import register_query_result_route\nfrom acestep.api.http.reinitialize_route import register_reinitialize_route\nfrom acestep.api.http.release_task_route import register_release_task_route\nfrom acestep.api.http.sample_format_routes import register_sample_format_routes\nfrom acestep.api.train_api_service import register_training_api_routes\nfrom acestep.openrouter_adapter import create_openrouter_router\n\n\ndef configure_api_routes(\n    app: FastAPI,\n    *,\n    store: Any,\n    queue_maxsize: int,\n    initial_avg_job_seconds: float,\n    verify_api_key: Callable[..., Any],\n    verify_token_from_request: Callable[[dict, Optional[str]], Optional[str]],\n    wrap_response: Callable[..., Dict[str, Any]],\n    get_project_root: Callable[[], str],\n    get_model_name: Callable[[str], str],\n    ensure_model_downloaded: Callable[[str, str], str],\n    env_bool: Callable[[str, bool], bool],\n    simple_example_data: List[Dict[str, Any]],\n    custom_example_data: List[Dict[str, Any]],\n    format_sample: Callable[..., Any],\n    to_int: Callable[[Any, Optional[int]], Optional[int]],\n    to_float: Callable[[Any, Optional[float]], Optional[float]],\n    request_parser_cls: Any,\n    request_model_cls: Any,\n    validate_audio_path: Callable[[Optional[str]], Optional[str]],\n    save_upload_to_temp: Callable[..., Any],\n    default_dit_instruction: str,\n    lm_default_temperature: float,\n    lm_default_cfg_scale: float,\n    lm_default_top_p: float,\n    map_status: Callable[[str], int],\n    result_key_prefix: str,\n    task_timeout_seconds: int,\n    log_buffer: Any,\n    runtime_start_tensorboard: Callable[..., Any],\n    runtime_stop_tensorboard: Callable[..., Any],\n    runtime_temporary_llm_model: Callable[..., Any],\n    runtime_atomic_write_json: Callable[..., Any],\n    runtime_append_jsonl: Callable[..., Any],\n) -> None:\n    \"\"\"Configure middleware, compatibility router, and all API route modules.\"\"\"\n\n    app.add_middleware(\n        CORSMiddleware,\n        allow_origins=[\"null\", \"http://localhost\", \"http://127.0.0.1\"],\n        allow_origin_regex=r\"^https?://(localhost|127\\.0\\.0\\.1)(:\\d+)?$\",\n        allow_methods=[\"GET\", \"POST\", \"OPTIONS\"],\n        allow_headers=[\"Content-Type\", \"Authorization\"],\n    )\n\n    openrouter_router = create_openrouter_router(lambda: app.state)\n    app.include_router(openrouter_router)\n\n    register_model_service_routes(\n        app=app,\n        verify_api_key=verify_api_key,\n        wrap_response=wrap_response,\n        store=store,\n        queue_maxsize=queue_maxsize,\n        initial_avg_job_seconds=initial_avg_job_seconds,\n        get_project_root=get_project_root,\n        get_model_name=get_model_name,\n        ensure_model_downloaded=ensure_model_downloaded,\n        env_bool=env_bool,\n    )\n\n    register_sample_format_routes(\n        app=app,\n        verify_token_from_request=verify_token_from_request,\n        wrap_response=wrap_response,\n        simple_example_data=simple_example_data,\n        custom_example_data=custom_example_data,\n        format_sample=format_sample,\n        get_project_root=get_project_root,\n        get_model_name=get_model_name,\n        ensure_model_downloaded=ensure_model_downloaded,\n        env_bool=env_bool,\n        to_int=to_int,\n        to_float=to_float,\n    )\n\n    register_lora_routes(app=app, verify_api_key=verify_api_key, wrap_response=wrap_response)\n\n    register_reinitialize_route(\n        app=app,\n        verify_api_key=verify_api_key,\n        wrap_response=wrap_response,\n        env_bool=env_bool,\n        get_project_root=get_project_root,\n    )\n\n    register_training_api_routes(\n        app=app,\n        verify_api_key=verify_api_key,\n        wrap_response=wrap_response,\n        start_tensorboard=partial(\n            runtime_start_tensorboard,\n            stop_tensorboard_fn=runtime_stop_tensorboard,\n        ),\n        stop_tensorboard=runtime_stop_tensorboard,\n        temporary_llm_model=partial(\n            runtime_temporary_llm_model,\n            get_project_root=get_project_root,\n            get_model_name=get_model_name,\n            ensure_model_downloaded=ensure_model_downloaded,\n            env_bool=env_bool,\n        ),\n        atomic_write_json=runtime_atomic_write_json,\n        append_jsonl=runtime_append_jsonl,\n    )\n\n    register_audio_route(app=app, verify_api_key=verify_api_key)\n\n    register_release_task_route(\n        app=app,\n        verify_token_from_request=verify_token_from_request,\n        wrap_response=wrap_response,\n        store=store,\n        request_parser_cls=request_parser_cls,\n        request_model_cls=request_model_cls,\n        validate_audio_path=validate_audio_path,\n        save_upload_to_temp=save_upload_to_temp,\n        upload_file_type=StarletteUploadFile,\n        default_dit_instruction=default_dit_instruction,\n        lm_default_temperature=lm_default_temperature,\n        lm_default_cfg_scale=lm_default_cfg_scale,\n        lm_default_top_p=lm_default_top_p,\n    )\n\n    register_query_result_route(\n        app=app,\n        verify_token_from_request=verify_token_from_request,\n        wrap_response=wrap_response,\n        store=store,\n        map_status=map_status,\n        result_key_prefix=result_key_prefix,\n        task_timeout_seconds=task_timeout_seconds,\n        log_buffer=log_buffer,\n    )\n"
  },
  {
    "path": "acestep/api/route_setup_test.py",
    "content": "\"\"\"Unit tests for API route setup helper wiring.\"\"\"\n\nfrom __future__ import annotations\n\nimport unittest\nfrom unittest.mock import MagicMock, patch\n\nfrom fastapi import APIRouter, FastAPI\nfrom fastapi.middleware.cors import CORSMiddleware\n\nfrom acestep.api.route_setup import configure_api_routes\n\n\nclass RouteSetupTests(unittest.TestCase):\n    \"\"\"Behavior tests for middleware and route registration orchestration.\"\"\"\n\n    @patch(\"acestep.api.route_setup.register_query_result_route\")\n    @patch(\"acestep.api.route_setup.register_release_task_route\")\n    @patch(\"acestep.api.route_setup.register_audio_route\")\n    @patch(\"acestep.api.route_setup.register_training_api_routes\")\n    @patch(\"acestep.api.route_setup.register_reinitialize_route\")\n    @patch(\"acestep.api.route_setup.register_lora_routes\")\n    @patch(\"acestep.api.route_setup.register_sample_format_routes\")\n    @patch(\"acestep.api.route_setup.register_model_service_routes\")\n    @patch(\"acestep.api.route_setup.create_openrouter_router\")\n    def test_configure_api_routes_registers_all_routes_and_middleware(\n        self,\n        mock_create_openrouter_router,\n        mock_register_model_service_routes,\n        mock_register_sample_format_routes,\n        mock_register_lora_routes,\n        mock_register_reinitialize_route,\n        mock_register_training_api_routes,\n        mock_register_audio_route,\n        mock_register_release_task_route,\n        mock_register_query_result_route,\n    ) -> None:\n        \"\"\"Setup should add CORS, include router, and invoke all route registrars once.\"\"\"\n\n        app = FastAPI()\n        router = APIRouter()\n        mock_create_openrouter_router.return_value = router\n\n        configure_api_routes(\n            app=app,\n            store=object(),\n            queue_maxsize=200,\n            initial_avg_job_seconds=5.0,\n            verify_api_key=MagicMock(),\n            verify_token_from_request=MagicMock(),\n            wrap_response=MagicMock(),\n            get_project_root=MagicMock(return_value=\"k:/repo\"),\n            get_model_name=MagicMock(return_value=\"acestep-v15-turbo\"),\n            ensure_model_downloaded=MagicMock(return_value=\"k:/repo/checkpoints/model\"),\n            env_bool=MagicMock(return_value=False),\n            simple_example_data=[],\n            custom_example_data=[],\n            format_sample=MagicMock(),\n            to_int=MagicMock(return_value=None),\n            to_float=MagicMock(return_value=None),\n            request_parser_cls=MagicMock(),\n            request_model_cls=MagicMock(),\n            validate_audio_path=MagicMock(return_value=None),\n            save_upload_to_temp=MagicMock(),\n            default_dit_instruction=\"instruction\",\n            lm_default_temperature=0.85,\n            lm_default_cfg_scale=2.5,\n            lm_default_top_p=0.9,\n            map_status=MagicMock(return_value=0),\n            result_key_prefix=\"prefix\",\n            task_timeout_seconds=3600,\n            log_buffer=MagicMock(),\n            runtime_start_tensorboard=MagicMock(),\n            runtime_stop_tensorboard=MagicMock(),\n            runtime_temporary_llm_model=MagicMock(),\n            runtime_atomic_write_json=MagicMock(),\n            runtime_append_jsonl=MagicMock(),\n        )\n\n        self.assertTrue(any(m.cls is CORSMiddleware for m in app.user_middleware))\n        mock_create_openrouter_router.assert_called_once()\n        mock_register_model_service_routes.assert_called_once()\n        mock_register_sample_format_routes.assert_called_once()\n        mock_register_lora_routes.assert_called_once()\n        mock_register_reinitialize_route.assert_called_once()\n        mock_register_training_api_routes.assert_called_once()\n        mock_register_audio_route.assert_called_once()\n        mock_register_release_task_route.assert_called_once()\n        mock_register_query_result_route.assert_called_once()\n\n\nif __name__ == \"__main__\":\n    unittest.main()\n"
  },
  {
    "path": "acestep/api/runtime_helpers.py",
    "content": "\"\"\"Runtime helper functions used by API training and model orchestration paths.\"\"\"\n\nfrom __future__ import annotations\n\nimport json\nimport os\nimport subprocess\nimport sys\nimport tempfile\nfrom contextlib import contextmanager\nfrom typing import Any, Callable, Dict, Optional\n\n\ndef stop_tensorboard(app: Any) -> None:\n    \"\"\"Stop TensorBoard process if running.\"\"\"\n\n    try:\n        proc = getattr(app.state, \"tensorboard_process\", None)\n    except Exception:\n        proc = None\n\n    if proc is None:\n        return\n\n    try:\n        proc.terminate()\n    except Exception:\n        pass\n    try:\n        proc.wait(timeout=3)\n    except Exception:\n        try:\n            proc.kill()\n        except Exception:\n            pass\n    try:\n        app.state.tensorboard_process = None\n    except Exception:\n        pass\n\n\ndef start_tensorboard(\n    app: Any,\n    logdir: str,\n    stop_tensorboard_fn: Callable[[Any], None] = stop_tensorboard,\n) -> Optional[str]:\n    \"\"\"(Re)start TensorBoard with the given logdir and return URL if successful.\"\"\"\n\n    try:\n        tensorboard_port = int(os.getenv(\"TENSORBOARD_PORT\", \"6006\"))\n        stop_tensorboard_fn(app)\n\n        if sys.prefix != sys.base_prefix:\n            tensorboard_cmd = os.path.join(sys.prefix, \"Scripts\", \"tensorboard.exe\")\n            if not os.path.exists(tensorboard_cmd):\n                tensorboard_cmd = os.path.join(sys.prefix, \"bin\", \"tensorboard\")\n            if not os.path.exists(tensorboard_cmd):\n                tensorboard_cmd = \"tensorboard\"\n        else:\n            tensorboard_cmd = \"tensorboard\"\n\n        app.state.tensorboard_process = subprocess.Popen(\n            [\n                tensorboard_cmd,\n                \"--logdir\",\n                logdir,\n                \"--port\",\n                str(tensorboard_port),\n                \"--bind_all\",\n            ],\n            stdout=subprocess.DEVNULL,\n            stderr=subprocess.DEVNULL,\n        )\n        return f\"http://localhost:{tensorboard_port}\"\n    except Exception:\n        return None\n\n\n@contextmanager\ndef temporary_llm_model(\n    app: Any,\n    llm: Any,\n    lm_model_path: Optional[str],\n    get_project_root: Callable[[], str],\n    get_model_name: Callable[[str], str],\n    ensure_model_downloaded: Callable[[str, str], str],\n    env_bool: Callable[[str, bool], bool],\n):\n    \"\"\"Temporarily switch LLM model for a critical section and restore afterward.\"\"\"\n\n    desired = (lm_model_path or \"\").strip()\n    if not desired:\n        yield\n        return\n\n    if llm is None or not getattr(llm, \"llm_initialized\", False):\n        yield\n        return\n\n    lock = getattr(app.state, \"_llm_init_lock\", None)\n    if lock is None:\n        yield\n        return\n\n    with lock:\n        prev_params = getattr(llm, \"last_init_params\", None)\n        prev_model = (prev_params or {}).get(\"lm_model_path\") if isinstance(prev_params, dict) else None\n        if prev_model and prev_model.strip() == desired:\n            yield\n            return\n\n        project_root = get_project_root()\n        checkpoint_dir = os.path.join(project_root, \"checkpoints\")\n        os.makedirs(checkpoint_dir, exist_ok=True)\n\n        lm_model_name = get_model_name(desired)\n        if lm_model_name:\n            try:\n                ensure_model_downloaded(lm_model_name, checkpoint_dir)\n            except Exception:\n                pass\n\n        restore_params = prev_params if isinstance(prev_params, dict) else None\n\n        ok_switched = False\n        try:\n            new_params = dict(restore_params) if restore_params else {\n                \"checkpoint_dir\": checkpoint_dir,\n                \"backend\": os.getenv(\"ACESTEP_LM_BACKEND\", \"vllm\").strip().lower() or \"vllm\",\n                \"device\": os.getenv(\"ACESTEP_LM_DEVICE\", os.getenv(\"ACESTEP_DEVICE\", \"auto\")),\n                \"offload_to_cpu\": env_bool(\"ACESTEP_LM_OFFLOAD_TO_CPU\", False),\n                \"dtype\": None,\n            }\n            new_params[\"checkpoint_dir\"] = checkpoint_dir\n            new_params[\"lm_model_path\"] = desired\n\n            status, ok = llm.initialize(**new_params)\n            if ok:\n                ok_switched = True\n                try:\n                    app.state._llm_initialized = True\n                    app.state._llm_init_error = None\n                except Exception:\n                    pass\n            else:\n                try:\n                    app.state._llm_initialized = False\n                    app.state._llm_init_error = status\n                except Exception:\n                    pass\n        except Exception as exc:\n            try:\n                app.state._llm_initialized = False\n                app.state._llm_init_error = str(exc)\n            except Exception:\n                pass\n\n        try:\n            yield\n        finally:\n            if ok_switched and restore_params:\n                try:\n                    llm.initialize(**restore_params)\n                    try:\n                        app.state._llm_initialized = True\n                        app.state._llm_init_error = None\n                    except Exception:\n                        pass\n                except Exception as exc:\n                    try:\n                        app.state._llm_initialized = False\n                        app.state._llm_init_error = str(exc)\n                    except Exception:\n                        pass\n\n\ndef atomic_write_json(path: str, payload: Dict[str, Any]) -> None:\n    \"\"\"Write JSON atomically to reduce corruption risk during incremental saves.\"\"\"\n\n    directory = os.path.dirname(path)\n    if directory:\n        os.makedirs(directory, exist_ok=True)\n\n    fd, tmp_path = tempfile.mkstemp(prefix=\".tmp_\", suffix=\".json\", dir=directory or None)\n    try:\n        with os.fdopen(fd, \"w\", encoding=\"utf-8\") as file_obj:\n            json.dump(payload, file_obj, ensure_ascii=False, indent=2)\n            file_obj.flush()\n            os.fsync(file_obj.fileno())\n        os.replace(tmp_path, path)\n    except Exception:\n        try:\n            os.remove(tmp_path)\n        except Exception:\n            pass\n        raise\n\n\ndef append_jsonl(path: str, record: Dict[str, Any]) -> None:\n    \"\"\"Append a single JSONL record for audit/progress tracing.\"\"\"\n\n    directory = os.path.dirname(path)\n    if directory:\n        os.makedirs(directory, exist_ok=True)\n    with open(path, \"a\", encoding=\"utf-8\") as file_obj:\n        file_obj.write(json.dumps(record, ensure_ascii=False) + \"\\n\")\n"
  },
  {
    "path": "acestep/api/runtime_helpers_test.py",
    "content": "\"\"\"Unit tests for API runtime helper utilities.\"\"\"\n\nfrom __future__ import annotations\n\nimport os\nimport threading\nimport unittest\nfrom types import SimpleNamespace\nfrom unittest import mock\n\nfrom acestep.api.runtime_helpers import (\n    append_jsonl,\n    atomic_write_json,\n    start_tensorboard,\n    stop_tensorboard,\n    temporary_llm_model,\n)\n\n\nclass RuntimeHelpersTests(unittest.TestCase):\n    \"\"\"Behavior tests for extracted runtime helper functions.\"\"\"\n\n    def test_stop_tensorboard_terminates_and_clears_process(self):\n        \"\"\"Stop helper should terminate process and clear app state pointer.\"\"\"\n\n        process = mock.Mock()\n        app = SimpleNamespace(state=SimpleNamespace(tensorboard_process=process))\n\n        stop_tensorboard(app)\n\n        process.terminate.assert_called_once()\n        process.wait.assert_called_once_with(timeout=3)\n        self.assertIsNone(app.state.tensorboard_process)\n\n    def test_start_tensorboard_starts_process_and_returns_url(self):\n        \"\"\"Start helper should invoke Popen and return URL when startup succeeds.\"\"\"\n\n        app = SimpleNamespace(state=SimpleNamespace(tensorboard_process=None))\n        fake_proc = mock.Mock()\n        stop_calls = []\n\n        with mock.patch(\"acestep.api.runtime_helpers.os.getenv\", return_value=\"6007\"), mock.patch(\n            \"acestep.api.runtime_helpers.sys.prefix\", \"venv-prefix\"\n        ), mock.patch(\"acestep.api.runtime_helpers.sys.base_prefix\", \"base-prefix\"), mock.patch(\n            \"acestep.api.runtime_helpers.os.path.exists\", return_value=False\n        ), mock.patch(\n            \"acestep.api.runtime_helpers.subprocess.Popen\", return_value=fake_proc\n        ):\n            url = start_tensorboard(app, logdir=\"logs\", stop_tensorboard_fn=lambda a: stop_calls.append(a))\n\n        self.assertEqual(\"http://localhost:6007\", url)\n        self.assertEqual([app], stop_calls)\n        self.assertIs(app.state.tensorboard_process, fake_proc)\n\n    def test_start_tensorboard_returns_none_on_failure(self):\n        \"\"\"Start helper should return None when startup raises an exception.\"\"\"\n\n        app = SimpleNamespace(state=SimpleNamespace(tensorboard_process=None))\n        with mock.patch(\n            \"acestep.api.runtime_helpers.subprocess.Popen\",\n            side_effect=RuntimeError(\"failed\"),\n        ):\n            url = start_tensorboard(app, logdir=\"logs\")\n        self.assertIsNone(url)\n\n    def test_temporary_llm_model_noops_when_path_missing(self):\n        \"\"\"Temporary switch helper should no-op when desired model path is empty.\"\"\"\n\n        app = SimpleNamespace(state=SimpleNamespace(_llm_init_lock=threading.Lock()))\n        llm = SimpleNamespace(llm_initialized=True, initialize=mock.Mock(), last_init_params={})\n\n        with temporary_llm_model(\n            app=app,\n            llm=llm,\n            lm_model_path=\"\",\n            get_project_root=lambda: \"root\",\n            get_model_name=lambda path: path,\n            ensure_model_downloaded=lambda *_: \"\",\n            env_bool=lambda *_: False,\n        ):\n            pass\n\n        llm.initialize.assert_not_called()\n\n    def test_temporary_llm_model_switches_and_restores(self):\n        \"\"\"Temporary switch helper should initialize target model then restore previous params.\"\"\"\n\n        app = SimpleNamespace(\n            state=SimpleNamespace(\n                _llm_init_lock=threading.Lock(),\n                _llm_initialized=False,\n                _llm_init_error=\"\",\n            )\n        )\n        prev_params = {\n            \"checkpoint_dir\": \"old-checkpoints\",\n            \"lm_model_path\": \"old-model\",\n            \"backend\": \"vllm\",\n            \"device\": \"cuda\",\n            \"offload_to_cpu\": False,\n            \"dtype\": None,\n        }\n        llm = SimpleNamespace(\n            llm_initialized=True,\n            initialize=mock.Mock(return_value=(\"ok\", True)),\n            last_init_params=prev_params,\n        )\n        downloaded = []\n\n        with mock.patch(\"acestep.api.runtime_helpers.os.makedirs\"):\n            with temporary_llm_model(\n                app=app,\n                llm=llm,\n                lm_model_path=\"new-model\",\n                get_project_root=lambda: \"project-root\",\n                get_model_name=lambda _path: \"new-model\",\n                ensure_model_downloaded=lambda model, checkpoint_dir: downloaded.append((model, checkpoint_dir)),\n                env_bool=lambda *_: False,\n            ):\n                self.assertTrue(app.state._llm_initialized)\n                self.assertIsNone(app.state._llm_init_error)\n\n        self.assertEqual([(\"new-model\", os.path.join(\"project-root\", \"checkpoints\"))], downloaded)\n        self.assertEqual(2, llm.initialize.call_count)\n        first_call = llm.initialize.call_args_list[0].kwargs\n        second_call = llm.initialize.call_args_list[1].kwargs\n        self.assertEqual(\"new-model\", first_call[\"lm_model_path\"])\n        self.assertEqual(prev_params, second_call)\n\n    def test_temporary_llm_model_does_not_suppress_exception_when_switch_fails(self):\n        \"\"\"Exceptions inside the context should propagate even if switch/restore is skipped.\"\"\"\n\n        app = SimpleNamespace(state=SimpleNamespace(_llm_init_lock=threading.Lock()))\n        prev_params = {\n            \"checkpoint_dir\": \"old-checkpoints\",\n            \"lm_model_path\": \"old-model\",\n            \"backend\": \"vllm\",\n            \"device\": \"cuda\",\n            \"offload_to_cpu\": False,\n            \"dtype\": None,\n        }\n        llm = SimpleNamespace(\n            llm_initialized=True,\n            initialize=mock.Mock(return_value=(\"failed\", False)),\n            last_init_params=prev_params,\n        )\n\n        with mock.patch(\"acestep.api.runtime_helpers.os.makedirs\"):\n            with self.assertRaises(ValueError):\n                with temporary_llm_model(\n                    app=app,\n                    llm=llm,\n                    lm_model_path=\"new-model\",\n                    get_project_root=lambda: \"project-root\",\n                    get_model_name=lambda _path: \"new-model\",\n                    ensure_model_downloaded=lambda *_: \"\",\n                    env_bool=lambda *_: False,\n                ):\n                    raise ValueError(\"boom\")\n\n        self.assertEqual(1, llm.initialize.call_count)\n\n    def test_atomic_write_json_replaces_target_on_success(self):\n        \"\"\"Atomic write helper should fsync temp file and replace destination path.\"\"\"\n\n        mock_file = mock.Mock()\n        mock_file.fileno.return_value = 99\n        mock_context = mock.Mock()\n        mock_context.__enter__ = mock.Mock(return_value=mock_file)\n        mock_context.__exit__ = mock.Mock(return_value=False)\n\n        with mock.patch(\"acestep.api.runtime_helpers.os.makedirs\"), mock.patch(\n            \"acestep.api.runtime_helpers.tempfile.mkstemp\",\n            return_value=(11, \"tmp-file.json\"),\n        ), mock.patch(\"acestep.api.runtime_helpers.os.fdopen\", return_value=mock_context), mock.patch(\n            \"acestep.api.runtime_helpers.json.dump\"\n        ), mock.patch(\n            \"acestep.api.runtime_helpers.os.fsync\"\n        ) as fsync_mock, mock.patch(\n            \"acestep.api.runtime_helpers.os.replace\"\n        ) as replace_mock:\n            atomic_write_json(\"out/data.json\", {\"ok\": True})\n\n        fsync_mock.assert_called_once_with(99)\n        replace_mock.assert_called_once_with(\"tmp-file.json\", \"out/data.json\")\n\n    def test_atomic_write_json_cleans_tmp_file_on_error(self):\n        \"\"\"Atomic write helper should remove temp file and re-raise when replace fails.\"\"\"\n\n        mock_file = mock.Mock()\n        mock_file.fileno.return_value = 99\n        mock_context = mock.Mock()\n        mock_context.__enter__ = mock.Mock(return_value=mock_file)\n        mock_context.__exit__ = mock.Mock(return_value=False)\n\n        with mock.patch(\"acestep.api.runtime_helpers.os.makedirs\"), mock.patch(\n            \"acestep.api.runtime_helpers.tempfile.mkstemp\",\n            return_value=(11, \"tmp-file.json\"),\n        ), mock.patch(\"acestep.api.runtime_helpers.os.fdopen\", return_value=mock_context), mock.patch(\n            \"acestep.api.runtime_helpers.json.dump\"\n        ), mock.patch(\n            \"acestep.api.runtime_helpers.os.fsync\"\n        ), mock.patch(\n            \"acestep.api.runtime_helpers.os.replace\",\n            side_effect=RuntimeError(\"replace failed\"),\n        ), mock.patch(\"acestep.api.runtime_helpers.os.remove\") as remove_mock:\n            with self.assertRaises(RuntimeError):\n                atomic_write_json(\"out/data.json\", {\"ok\": True})\n\n        remove_mock.assert_called_once_with(\"tmp-file.json\")\n\n    def test_append_jsonl_writes_one_line(self):\n        \"\"\"JSONL append helper should append one serialized record plus newline.\"\"\"\n\n        with mock.patch(\"acestep.api.runtime_helpers.os.makedirs\"), mock.patch(\n            \"acestep.api.runtime_helpers.json.dumps\",\n            return_value='{\"a\": 1}',\n        ), mock.patch(\"builtins.open\", mock.mock_open()) as open_mock:\n            append_jsonl(\"out/log.jsonl\", {\"a\": 1})\n\n        open_mock.assert_called_once_with(\"out/log.jsonl\", \"a\", encoding=\"utf-8\")\n        open_mock().write.assert_called_once_with('{\"a\": 1}\\n')\n\n\nif __name__ == \"__main__\":\n    unittest.main()\n"
  },
  {
    "path": "acestep/api/server_cli.py",
    "content": "\"\"\"CLI bootstrap helpers for launching the API server process.\"\"\"\n\nfrom __future__ import annotations\n\nimport argparse\nimport os\nfrom typing import Callable, Optional\n\nimport uvicorn\n\n\ndef run_api_server_main(\n    env_bool: Callable[[str, bool], bool],\n    argv: Optional[list[str]] = None,\n) -> None:\n    \"\"\"Parse CLI args, set environment overrides, and start uvicorn.\n\n    Args:\n        env_bool: Boolean env parser used for defaults.\n        argv: Optional explicit arg list (used by tests). Defaults to process argv.\n    \"\"\"\n\n    parser = argparse.ArgumentParser(description=\"ACE-Step API server\")\n    parser.add_argument(\n        \"--host\",\n        default=os.getenv(\"ACESTEP_API_HOST\", \"127.0.0.1\"),\n        help=\"Bind host (default from ACESTEP_API_HOST or 127.0.0.1)\",\n    )\n    parser.add_argument(\n        \"--port\",\n        type=int,\n        default=int(os.getenv(\"ACESTEP_API_PORT\", \"8001\")),\n        help=\"Bind port (default from ACESTEP_API_PORT or 8001)\",\n    )\n    parser.add_argument(\n        \"--api-key\",\n        type=str,\n        default=os.getenv(\"ACESTEP_API_KEY\", None),\n        help=\"API key for authentication (default from ACESTEP_API_KEY)\",\n    )\n    parser.add_argument(\n        \"--download-source\",\n        type=str,\n        choices=[\"huggingface\", \"modelscope\", \"auto\"],\n        default=os.getenv(\"ACESTEP_DOWNLOAD_SOURCE\", \"auto\"),\n        help=\"Preferred model download source: auto (default), huggingface, or modelscope\",\n    )\n    parser.add_argument(\n        \"--init-llm\",\n        action=\"store_true\",\n        default=env_bool(\"ACESTEP_INIT_LLM\", False),\n        help=\"Initialize LLM even if GPU memory is insufficient (may cause OOM). \"\n        \"Can also be set via ACESTEP_INIT_LLM=true environment variable.\",\n    )\n    parser.add_argument(\n        \"--lm-model-path\",\n        type=str,\n        default=os.getenv(\"ACESTEP_LM_MODEL_PATH\", \"\"),\n        help=\"LM model to load (e.g., 'acestep-5Hz-lm-0.6B'). Default from ACESTEP_LM_MODEL_PATH.\",\n    )\n    parser.add_argument(\n        \"--no-init\",\n        action=\"store_true\",\n        default=env_bool(\"ACESTEP_NO_INIT\", False),\n        help=\"Skip model loading at startup (models will be lazy-loaded on first request). \"\n        \"Can also be set via ACESTEP_NO_INIT=true environment variable.\",\n    )\n    args = parser.parse_args(args=argv)\n\n    if args.api_key:\n        os.environ[\"ACESTEP_API_KEY\"] = args.api_key\n\n    if args.download_source and args.download_source != \"auto\":\n        os.environ[\"ACESTEP_DOWNLOAD_SOURCE\"] = args.download_source\n        print(f\"Using preferred download source: {args.download_source}\")\n\n    if args.init_llm:\n        os.environ[\"ACESTEP_INIT_LLM\"] = \"true\"\n        print(\"[API Server] LLM initialization enabled via --init-llm\")\n\n    if args.lm_model_path:\n        os.environ[\"ACESTEP_LM_MODEL_PATH\"] = args.lm_model_path\n        print(f\"[API Server] Using LM model: {args.lm_model_path}\")\n\n    if args.no_init:\n        os.environ[\"ACESTEP_NO_INIT\"] = \"true\"\n        print(\"[API Server] --no-init: Models will NOT be loaded at startup (lazy load on first request)\")\n\n    # IMPORTANT: in-memory queue/store -> workers MUST be 1\n    uvicorn.run(\n        \"acestep.api_server:app\",\n        host=str(args.host),\n        port=int(args.port),\n        reload=False,\n        workers=1,\n    )\n"
  },
  {
    "path": "acestep/api/server_cli_test.py",
    "content": "\"\"\"Unit tests for API server CLI bootstrap helper.\"\"\"\n\nfrom __future__ import annotations\n\nimport os\nimport unittest\nfrom unittest.mock import patch\n\nfrom acestep.api.server_cli import run_api_server_main\n\n\nclass ServerCliTests(unittest.TestCase):\n    \"\"\"Behavior tests for argument parsing and uvicorn bootstrap wiring.\"\"\"\n\n    def test_run_api_server_main_invokes_uvicorn_with_parsed_host_port(self) -> None:\n        \"\"\"CLI helper should pass parsed host/port and fixed worker settings to uvicorn.\"\"\"\n\n        with patch.dict(os.environ, {}, clear=True):\n            with patch(\"acestep.api.server_cli.uvicorn.run\") as mock_run:\n                run_api_server_main(lambda _name, default: default, argv=[\"--host\", \"0.0.0.0\", \"--port\", \"9001\"])\n        mock_run.assert_called_once_with(\n            \"acestep.api_server:app\",\n            host=\"0.0.0.0\",\n            port=9001,\n            reload=False,\n            workers=1,\n        )\n\n    def test_run_api_server_main_sets_env_overrides_from_flags(self) -> None:\n        \"\"\"CLI helper should apply legacy env side effects for supported flags.\"\"\"\n\n        with patch.dict(os.environ, {}, clear=True):\n            with patch(\"acestep.api.server_cli.uvicorn.run\"):\n                run_api_server_main(\n                    lambda _name, default: default,\n                    argv=[\n                        \"--api-key\",\n                        \"secret\",\n                        \"--download-source\",\n                        \"huggingface\",\n                        \"--init-llm\",\n                        \"--lm-model-path\",\n                        \"acestep-5Hz-lm-0.6B\",\n                        \"--no-init\",\n                    ],\n                )\n\n            self.assertEqual(\"secret\", os.environ.get(\"ACESTEP_API_KEY\"))\n            self.assertEqual(\"huggingface\", os.environ.get(\"ACESTEP_DOWNLOAD_SOURCE\"))\n            self.assertEqual(\"true\", os.environ.get(\"ACESTEP_INIT_LLM\"))\n            self.assertEqual(\"acestep-5Hz-lm-0.6B\", os.environ.get(\"ACESTEP_LM_MODEL_PATH\"))\n            self.assertEqual(\"true\", os.environ.get(\"ACESTEP_NO_INIT\"))\n\n    def test_run_api_server_main_uses_env_bool_for_flag_defaults(self) -> None:\n        \"\"\"CLI helper should respect env_bool-provided defaults when flags omitted.\"\"\"\n\n        observed = []\n\n        def _env_bool(name: str, default: bool) -> bool:\n            observed.append((name, default))\n            if name == \"ACESTEP_INIT_LLM\":\n                return True\n            return False\n\n        with patch.dict(os.environ, {}, clear=True):\n            with patch(\"acestep.api.server_cli.uvicorn.run\") as mock_run:\n                run_api_server_main(_env_bool, argv=[])\n                self.assertEqual(\"true\", os.environ.get(\"ACESTEP_INIT_LLM\"))\n                self.assertIsNone(os.environ.get(\"ACESTEP_NO_INIT\"))\n                mock_run.assert_called_once()\n\n        self.assertIn((\"ACESTEP_INIT_LLM\", False), observed)\n        self.assertIn((\"ACESTEP_NO_INIT\", False), observed)\n\n\nif __name__ == \"__main__\":\n    unittest.main()\n"
  },
  {
    "path": "acestep/api/server_utils.py",
    "content": "\"\"\"Shared helper utilities used by API server request and runtime flows.\"\"\"\n\nfrom __future__ import annotations\n\nimport os\nimport re\nfrom typing import Optional\n\n\nSTATUS_MAP = {\"queued\": 0, \"running\": 0, \"succeeded\": 1, \"failed\": 2}\n\n\ndef parse_description_hints(description: str) -> tuple[Optional[str], bool]:\n    \"\"\"Parse language and instrumental hints from free-form description text.\n\n    Args:\n        description: User free-form sample description.\n\n    Returns:\n        Tuple of ``(language_code, is_instrumental)``.\n    \"\"\"\n\n    if not description:\n        return None, False\n\n    description_lower = description.lower().strip()\n\n    language_mapping = {\n        \"english\": \"en\",\n        \"en\": \"en\",\n        \"chinese\": \"zh\",\n        \"中文\": \"zh\",\n        \"zh\": \"zh\",\n        \"mandarin\": \"zh\",\n        \"japanese\": \"ja\",\n        \"日本語\": \"ja\",\n        \"ja\": \"ja\",\n        \"korean\": \"ko\",\n        \"한국어\": \"ko\",\n        \"ko\": \"ko\",\n        \"spanish\": \"es\",\n        \"español\": \"es\",\n        \"es\": \"es\",\n        \"french\": \"fr\",\n        \"français\": \"fr\",\n        \"fr\": \"fr\",\n        \"german\": \"de\",\n        \"deutsch\": \"de\",\n        \"de\": \"de\",\n        \"italian\": \"it\",\n        \"italiano\": \"it\",\n        \"it\": \"it\",\n        \"portuguese\": \"pt\",\n        \"português\": \"pt\",\n        \"pt\": \"pt\",\n        \"russian\": \"ru\",\n        \"русский\": \"ru\",\n        \"ru\": \"ru\",\n        \"bengali\": \"bn\",\n        \"bn\": \"bn\",\n        \"hindi\": \"hi\",\n        \"hi\": \"hi\",\n        \"arabic\": \"ar\",\n        \"ar\": \"ar\",\n        \"thai\": \"th\",\n        \"th\": \"th\",\n        \"vietnamese\": \"vi\",\n        \"vi\": \"vi\",\n        \"indonesian\": \"id\",\n        \"id\": \"id\",\n        \"turkish\": \"tr\",\n        \"tr\": \"tr\",\n        \"dutch\": \"nl\",\n        \"nl\": \"nl\",\n        \"polish\": \"pl\",\n        \"pl\": \"pl\",\n    }\n\n    detected_language = None\n    for lang_name, lang_code in language_mapping.items():\n        if len(lang_name) <= 2:\n            pattern = r\"(?:^|\\s|[.,;:!?])\" + re.escape(lang_name) + r\"(?:$|\\s|[.,;:!?])\"\n        else:\n            pattern = r\"\\b\" + re.escape(lang_name) + r\"\\b\"\n        if re.search(pattern, description_lower):\n            detected_language = lang_code\n            break\n\n    is_instrumental = False\n    if \"instrumental\" in description_lower:\n        is_instrumental = True\n    elif \"pure music\" in description_lower or \"pure instrument\" in description_lower:\n        is_instrumental = True\n    elif description_lower.endswith(\" solo\") or description_lower == \"solo\":\n        is_instrumental = True\n\n    return detected_language, is_instrumental\n\n\ndef env_bool(name: str, default: bool) -> bool:\n    \"\"\"Read boolean environment variable with legacy truthy semantics.\"\"\"\n\n    value = os.getenv(name)\n    if value is None:\n        return default\n    return value.strip().lower() in {\"1\", \"true\", \"yes\", \"y\", \"on\"}\n\n\ndef get_model_name(config_path: str) -> str:\n    \"\"\"Extract model name from config path.\"\"\"\n\n    if not config_path:\n        return \"\"\n    normalized = config_path.rstrip(\"/\\\\\")\n    return os.path.basename(normalized)\n\n\ndef map_status(status: str) -> int:\n    \"\"\"Map textual job status to integer API status code.\"\"\"\n\n    return STATUS_MAP.get(status, 2)\n\n\ndef parse_timesteps(value: Optional[str]) -> Optional[list[float]]:\n    \"\"\"Parse comma-separated timesteps into float list.\"\"\"\n\n    if not value or not value.strip():\n        return None\n    try:\n        return [float(item.strip()) for item in value.split(\",\") if item.strip()]\n    except (ValueError, Exception):\n        return None\n\n\ndef is_instrumental(lyrics: str) -> bool:\n    \"\"\"Return whether lyrics indicate instrumental output.\"\"\"\n\n    if not lyrics:\n        return True\n    lyrics_clean = lyrics.strip().lower()\n    if not lyrics_clean:\n        return True\n    return lyrics_clean in (\"[inst]\", \"[instrumental]\")\n"
  },
  {
    "path": "acestep/api/server_utils_test.py",
    "content": "\"\"\"Unit tests for shared API server utility helpers.\"\"\"\n\nfrom __future__ import annotations\n\nimport os\nimport unittest\nfrom unittest.mock import patch\n\nfrom acestep.api.server_utils import (\n    env_bool,\n    get_model_name,\n    is_instrumental,\n    map_status,\n    parse_description_hints,\n    parse_timesteps,\n)\n\n\nclass ServerUtilsTests(unittest.TestCase):\n    \"\"\"Behavior tests for server utility parsing and normalization helpers.\"\"\"\n\n    def test_parse_description_hints_detects_language_and_instrumental(self) -> None:\n        \"\"\"Description parser should detect language and instrumental hints.\"\"\"\n\n        language, instrumental = parse_description_hints(\"Epic rock in English solo\")\n        self.assertEqual(\"en\", language)\n        self.assertTrue(instrumental)\n\n    def test_parse_description_hints_empty_input(self) -> None:\n        \"\"\"Description parser should default to no hints for empty input.\"\"\"\n\n        language, instrumental = parse_description_hints(\"\")\n        self.assertIsNone(language)\n        self.assertFalse(instrumental)\n\n    def test_parse_description_hints_detects_unicode_language_aliases(self) -> None:\n        \"\"\"Description parser should support non-ASCII language aliases.\"\"\"\n\n        language, instrumental = parse_description_hints(\"抒情流行 中文\")\n        self.assertEqual(\"zh\", language)\n        self.assertFalse(instrumental)\n\n    def test_env_bool_uses_truthy_values_and_default(self) -> None:\n        \"\"\"Boolean env parser should support legacy truthy values and default fallback.\"\"\"\n\n        with patch.dict(os.environ, {}, clear=True):\n            self.assertTrue(env_bool(\"NOT_SET\", True))\n            self.assertFalse(env_bool(\"NOT_SET\", False))\n\n        with patch.dict(os.environ, {\"FLAG\": \"yes\"}, clear=True):\n            self.assertTrue(env_bool(\"FLAG\", False))\n\n    def test_get_model_name_normalizes_trailing_separators(self) -> None:\n        \"\"\"Model-name parser should return final path segment.\"\"\"\n\n        self.assertEqual(\"acestep-v15-turbo\", get_model_name(\"acestep-v15-turbo\"))\n        self.assertEqual(\"acestep-v15-turbo\", get_model_name(\"/models/acestep-v15-turbo/\"))\n\n    def test_map_status_returns_legacy_integer_codes(self) -> None:\n        \"\"\"Status mapper should preserve legacy integer API mapping.\"\"\"\n\n        self.assertEqual(0, map_status(\"queued\"))\n        self.assertEqual(0, map_status(\"running\"))\n        self.assertEqual(1, map_status(\"succeeded\"))\n        self.assertEqual(2, map_status(\"failed\"))\n        self.assertEqual(2, map_status(\"unknown\"))\n\n    def test_parse_timesteps_parses_valid_and_rejects_invalid(self) -> None:\n        \"\"\"Timesteps parser should parse float lists and return None on invalid input.\"\"\"\n\n        self.assertEqual([0.5, 0.25, 0.0], parse_timesteps(\"0.5, 0.25, 0\"))\n        self.assertIsNone(parse_timesteps(\"x,0.2\"))\n\n    def test_is_instrumental_preserves_legacy_markers(self) -> None:\n        \"\"\"Instrumental detector should match empty/marker lyrics behavior.\"\"\"\n\n        self.assertTrue(is_instrumental(\"\"))\n        self.assertTrue(is_instrumental(\"  [inst] \"))\n        self.assertFalse(is_instrumental(\"hello world\"))\n\n\nif __name__ == \"__main__\":\n    unittest.main()\n"
  },
  {
    "path": "acestep/api/startup_llm_init.py",
    "content": "\"\"\"LLM startup initialization helper for API server.\"\"\"\n\nfrom __future__ import annotations\n\nimport os\nfrom typing import Any, Callable\n\nfrom acestep.gpu_config import get_recommended_lm_model, is_lm_model_supported\n\n\ndef initialize_llm_at_startup(\n    *,\n    app: Any,\n    llm_handler: Any,\n    gpu_config: Any,\n    device: str,\n    offload_to_cpu: bool,\n    checkpoint_dir: str,\n    get_model_name: Callable[[str], str],\n    ensure_model_downloaded: Callable[[str, str], str],\n    env_bool: Callable[[str, bool], bool],\n) -> None:\n    \"\"\"Initialize LLM model according to GPU config and environment overrides.\"\"\"\n\n    init_llm_env = os.getenv(\"ACESTEP_INIT_LLM\", \"\").strip().lower()\n    init_llm = gpu_config.init_lm_default\n    print(\n        f\"[API Server] GPU auto-detection: init_llm={init_llm} \"\n        f\"(VRAM: {gpu_config.gpu_memory_gb:.1f}GB, tier: {gpu_config.tier})\"\n    )\n    if not init_llm_env or init_llm_env == \"auto\":\n        print(\"[API Server] ACESTEP_INIT_LLM=auto, using GPU auto-detection result\")\n    elif init_llm_env in {\"1\", \"true\", \"yes\", \"y\", \"on\"}:\n        if init_llm:\n            print(\"[API Server] ACESTEP_INIT_LLM=true (GPU already supports LLM, no override needed)\")\n        else:\n            init_llm = True\n            print(\"[API Server] ACESTEP_INIT_LLM=true, overriding GPU auto-detection (force enable)\")\n    else:\n        if not init_llm:\n            print(\"[API Server] ACESTEP_INIT_LLM=false (GPU already disabled LLM, no override needed)\")\n        else:\n            init_llm = False\n            print(\"[API Server] ACESTEP_INIT_LLM=false, overriding GPU auto-detection (force disable)\")\n\n    if init_llm:\n        print(\"[API Server] Loading LLM model...\")\n        lm_model_path = os.getenv(\"ACESTEP_LM_MODEL_PATH\", \"\").strip()\n        if lm_model_path:\n            print(f\"[API Server] Using user-specified LM model: {lm_model_path}\")\n        else:\n            recommended_lm = get_recommended_lm_model(gpu_config)\n            if recommended_lm:\n                lm_model_path = recommended_lm\n                print(f\"[API Server] Auto-selected LM model: {lm_model_path} based on GPU tier\")\n            else:\n                lm_model_path = \"acestep-5Hz-lm-0.6B\"\n                print(f\"[API Server] No recommended model for this GPU tier, using smallest: {lm_model_path}\")\n\n        is_supported, warning_msg = is_lm_model_supported(lm_model_path, gpu_config)\n        if not is_supported:\n            print(f\"[API Server] Warning: {warning_msg}\")\n            recommended_lm = get_recommended_lm_model(gpu_config)\n            if recommended_lm:\n                lm_model_path = recommended_lm\n                print(f\"[API Server] Falling back to supported LM model: {lm_model_path}\")\n            else:\n                print(f\"[API Server] No GPU-validated LM model available, attempting {lm_model_path} anyway (may cause OOM)\")\n\n        lm_backend = os.getenv(\"ACESTEP_LM_BACKEND\", \"vllm\").strip().lower()\n        if lm_backend not in {\"vllm\", \"pt\", \"mlx\"}:\n            lm_backend = \"vllm\"\n        lm_device = os.getenv(\"ACESTEP_LM_DEVICE\", device)\n        lm_offload_env = os.getenv(\"ACESTEP_LM_OFFLOAD_TO_CPU\")\n        lm_offload = env_bool(\"ACESTEP_LM_OFFLOAD_TO_CPU\", False) if lm_offload_env is not None else offload_to_cpu\n\n        lm_model_name = get_model_name(lm_model_path)\n        try:\n            ensure_model_downloaded(lm_model_name, checkpoint_dir)\n        except Exception as exc:\n            print(f\"[API Server] Warning: Failed to download LLM model: {exc}\")\n\n        llm_status, llm_ok = llm_handler.initialize(\n            checkpoint_dir=checkpoint_dir,\n            lm_model_path=lm_model_path,\n            backend=lm_backend,\n            device=lm_device,\n            offload_to_cpu=lm_offload,\n            dtype=None,\n        )\n        if llm_ok:\n            app.state._llm_initialized = True\n            print(f\"[API Server] LLM model loaded: {lm_model_path}\")\n        else:\n            app.state._llm_init_error = llm_status\n            print(f\"[API Server] Warning: LLM model failed to load: {llm_status}\")\n        return\n\n    print(\"[API Server] Skipping LLM initialization (disabled or not supported for this GPU)\")\n    app.state._llm_initialized = False\n    app.state._llm_lazy_load_disabled = True\n    print(\"[API Server] LLM lazy loading disabled. To enable LLM:\")\n    print(\"[API Server]   - Set ACESTEP_INIT_LLM=true in .env or environment\")\n    print(\"[API Server]   - Or use --init-llm command line flag\")\n"
  },
  {
    "path": "acestep/api/startup_llm_init_test.py",
    "content": "\"\"\"Unit tests for LLM startup initialization helper.\"\"\"\n\nfrom __future__ import annotations\n\nimport os\nimport unittest\nfrom types import SimpleNamespace\nfrom unittest.mock import MagicMock, patch\n\nfrom acestep.api.startup_llm_init import initialize_llm_at_startup\n\n\nclass StartupLlmInitTests(unittest.TestCase):\n    \"\"\"Behavior tests for LLM startup initialization decisions.\"\"\"\n\n    def test_initialize_llm_at_startup_skips_when_disabled(self) -> None:\n        \"\"\"Helper should skip LLM init and disable lazy loading when explicitly disabled.\"\"\"\n\n        app = SimpleNamespace(\n            state=SimpleNamespace(\n                _llm_initialized=True,\n                _llm_init_error=None,\n                _llm_lazy_load_disabled=False,\n            )\n        )\n        llm_handler = MagicMock()\n        gpu_config = SimpleNamespace(init_lm_default=True, gpu_memory_gb=8.0, tier=\"mid\")\n\n        with patch.dict(os.environ, {\"ACESTEP_INIT_LLM\": \"false\"}, clear=True):\n            initialize_llm_at_startup(\n                app=app,\n                llm_handler=llm_handler,\n                gpu_config=gpu_config,\n                device=\"cuda\",\n                offload_to_cpu=False,\n                checkpoint_dir=\"k:/repo/checkpoints\",\n                get_model_name=MagicMock(return_value=\"acestep-5Hz-lm-0.6B\"),\n                ensure_model_downloaded=MagicMock(),\n                env_bool=lambda _name, default: default,\n            )\n\n        llm_handler.initialize.assert_not_called()\n        self.assertFalse(app.state._llm_initialized)\n        self.assertTrue(app.state._llm_lazy_load_disabled)\n\n    @patch(\"acestep.api.startup_llm_init.is_lm_model_supported\")\n    @patch(\"acestep.api.startup_llm_init.get_recommended_lm_model\")\n    def test_initialize_llm_at_startup_loads_recommended_model(\n        self,\n        mock_get_recommended_lm_model: MagicMock,\n        mock_is_lm_model_supported: MagicMock,\n    ) -> None:\n        \"\"\"Helper should initialize LLM with recommended model when auto mode is active.\"\"\"\n\n        app = SimpleNamespace(\n            state=SimpleNamespace(\n                _llm_initialized=False,\n                _llm_init_error=None,\n                _llm_lazy_load_disabled=False,\n            )\n        )\n        llm_handler = MagicMock()\n        llm_handler.initialize.return_value = (\"ok\", True)\n        gpu_config = SimpleNamespace(init_lm_default=True, gpu_memory_gb=24.0, tier=\"high\")\n        mock_get_recommended_lm_model.return_value = \"acestep-5Hz-lm-1.1B\"\n        mock_is_lm_model_supported.return_value = (True, \"\")\n        ensure_model_downloaded = MagicMock()\n\n        with patch.dict(os.environ, {}, clear=True):\n            initialize_llm_at_startup(\n                app=app,\n                llm_handler=llm_handler,\n                gpu_config=gpu_config,\n                device=\"cuda\",\n                offload_to_cpu=False,\n                checkpoint_dir=\"k:/repo/checkpoints\",\n                get_model_name=MagicMock(return_value=\"acestep-5Hz-lm-1.1B\"),\n                ensure_model_downloaded=ensure_model_downloaded,\n                env_bool=lambda _name, default: default,\n            )\n\n        ensure_model_downloaded.assert_called_once_with(\n            \"acestep-5Hz-lm-1.1B\",\n            \"k:/repo/checkpoints\",\n        )\n        llm_handler.initialize.assert_called_once()\n        self.assertTrue(app.state._llm_initialized)\n        self.assertIsNone(app.state._llm_init_error)\n\n\nif __name__ == \"__main__\":\n    unittest.main()\n"
  },
  {
    "path": "acestep/api/startup_model_init.py",
    "content": "\"\"\"Startup model initialization orchestration for API server lifespan.\"\"\"\n\nfrom __future__ import annotations\n\nimport os\nfrom typing import Any, Callable, Optional\n\nfrom acestep.gpu_config import (\n    VRAM_AUTO_OFFLOAD_THRESHOLD_GB,\n    get_gpu_config,\n    set_global_gpu_config,\n)\nfrom acestep.api.startup_llm_init import initialize_llm_at_startup\n\n\ndef initialize_models_at_startup(\n    *,\n    app: Any,\n    handler: Any,\n    llm_handler: Any,\n    handler2: Any,\n    handler3: Any,\n    config_path2: str,\n    config_path3: str,\n    get_project_root: Callable[[], str],\n    get_model_name: Callable[[str], str],\n    ensure_model_downloaded: Callable[[str, str], str],\n    env_bool: Callable[[str, bool], bool],\n) -> None:\n    \"\"\"Initialize DiT and optional LLM models at server startup.\"\"\"\n\n    no_init = env_bool(\"ACESTEP_NO_INIT\", False)\n    gpu_config = get_gpu_config()\n    set_global_gpu_config(gpu_config)\n    app.state.gpu_config = gpu_config\n\n    gpu_memory_gb = gpu_config.gpu_memory_gb\n    auto_offload = gpu_memory_gb > 0 and gpu_memory_gb < VRAM_AUTO_OFFLOAD_THRESHOLD_GB\n\n    print(f\"\\n{'='*60}\")\n    print(\"[API Server] GPU Configuration Detected:\")\n    print(f\"{'='*60}\")\n    print(f\"  GPU Memory: {gpu_memory_gb:.2f} GB\")\n    print(f\"  Configuration Tier: {gpu_config.tier}\")\n    print(f\"  Max Duration (with LM): {gpu_config.max_duration_with_lm}s\")\n    print(f\"  Max Duration (without LM): {gpu_config.max_duration_without_lm}s\")\n    print(f\"  Max Batch Size (with LM): {gpu_config.max_batch_size_with_lm}\")\n    print(f\"  Max Batch Size (without LM): {gpu_config.max_batch_size_without_lm}\")\n    print(f\"  Default LM Init: {gpu_config.init_lm_default}\")\n    print(f\"  Available LM Models: {gpu_config.available_lm_models or 'None'}\")\n    print(f\"{'='*60}\\n\")\n\n    if no_init:\n        print(\"[API Server] --no-init mode: Skipping all model loading at startup\")\n        print(\"[API Server] Models will be lazy-loaded on first request\")\n        print(\"[API Server] Server is ready to accept requests (models not loaded yet)\")\n        return\n\n    print(\"[API Server] Initializing models at startup...\")\n    if auto_offload:\n        print(\"[API Server] Auto-enabling CPU offload (GPU < 16GB)\")\n    elif gpu_memory_gb > 0:\n        print(\"[API Server] CPU offload disabled by default (GPU >= 16GB)\")\n    else:\n        print(\"[API Server] No GPU detected, running on CPU\")\n\n    project_root = get_project_root()\n    config_path = os.getenv(\"ACESTEP_CONFIG_PATH\", \"acestep-v15-turbo\")\n    device = os.getenv(\"ACESTEP_DEVICE\", \"auto\")\n    use_flash_attention = env_bool(\"ACESTEP_USE_FLASH_ATTENTION\", True)\n\n    offload_to_cpu_env = os.getenv(\"ACESTEP_OFFLOAD_TO_CPU\")\n    if offload_to_cpu_env is not None:\n        offload_to_cpu = env_bool(\"ACESTEP_OFFLOAD_TO_CPU\", False)\n    else:\n        offload_to_cpu = auto_offload\n        if auto_offload:\n            print(\"[API Server] Auto-setting offload_to_cpu=True based on GPU memory\")\n\n    offload_dit_to_cpu = env_bool(\"ACESTEP_OFFLOAD_DIT_TO_CPU\", False)\n    compile_model = env_bool(\"ACESTEP_COMPILE_MODEL\", False)\n\n    checkpoint_dir = os.path.join(project_root, \"checkpoints\")\n    os.makedirs(checkpoint_dir, exist_ok=True)\n\n    dit_model_name = get_model_name(config_path)\n    if dit_model_name:\n        try:\n            ensure_model_downloaded(dit_model_name, checkpoint_dir)\n        except Exception as exc:\n            print(f\"[API Server] Warning: Failed to download DiT model: {exc}\")\n\n    try:\n        ensure_model_downloaded(\"vae\", checkpoint_dir)\n    except Exception as exc:\n        print(f\"[API Server] Warning: Failed to download VAE model: {exc}\")\n\n    print(f\"[API Server] Loading primary DiT model: {config_path}\")\n    status_msg, ok = handler.initialize_service(\n        project_root=project_root,\n        config_path=config_path,\n        device=device,\n        use_flash_attention=use_flash_attention,\n        compile_model=compile_model,\n        offload_to_cpu=offload_to_cpu,\n        offload_dit_to_cpu=offload_dit_to_cpu,\n    )\n    if not ok:\n        app.state._init_error = status_msg\n        print(f\"[API Server] ERROR: Primary model failed to load: {status_msg}\")\n        raise RuntimeError(status_msg)\n    app.state._initialized = True\n    print(f\"[API Server] Primary model loaded: {get_model_name(config_path)}\")\n\n    if handler2 and config_path2:\n        model2_name = get_model_name(config_path2)\n        if model2_name:\n            try:\n                ensure_model_downloaded(model2_name, checkpoint_dir)\n            except Exception as exc:\n                print(f\"[API Server] Warning: Failed to download secondary model: {exc}\")\n        print(f\"[API Server] Loading secondary DiT model: {config_path2}\")\n        try:\n            status_msg2, ok2 = handler2.initialize_service(\n                project_root=project_root,\n                config_path=config_path2,\n                device=device,\n                use_flash_attention=use_flash_attention,\n                compile_model=compile_model,\n                offload_to_cpu=offload_to_cpu,\n                offload_dit_to_cpu=offload_dit_to_cpu,\n            )\n            app.state._initialized2 = ok2\n            if ok2:\n                print(f\"[API Server] Secondary model loaded: {model2_name}\")\n            else:\n                print(f\"[API Server] Warning: Secondary model failed: {status_msg2}\")\n        except Exception as exc:\n            print(f\"[API Server] Warning: Failed to initialize secondary model: {exc}\")\n            app.state._initialized2 = False\n\n    if handler3 and config_path3:\n        model3_name = get_model_name(config_path3)\n        if model3_name:\n            try:\n                ensure_model_downloaded(model3_name, checkpoint_dir)\n            except Exception as exc:\n                print(f\"[API Server] Warning: Failed to download third model: {exc}\")\n        print(f\"[API Server] Loading third DiT model: {config_path3}\")\n        try:\n            status_msg3, ok3 = handler3.initialize_service(\n                project_root=project_root,\n                config_path=config_path3,\n                device=device,\n                use_flash_attention=use_flash_attention,\n                compile_model=compile_model,\n                offload_to_cpu=offload_to_cpu,\n                offload_dit_to_cpu=offload_dit_to_cpu,\n            )\n            app.state._initialized3 = ok3\n            if ok3:\n                print(f\"[API Server] Third model loaded: {model3_name}\")\n            else:\n                print(f\"[API Server] Warning: Third model failed: {status_msg3}\")\n        except Exception as exc:\n            print(f\"[API Server] Warning: Failed to initialize third model: {exc}\")\n            app.state._initialized3 = False\n\n    initialize_llm_at_startup(\n        app=app,\n        llm_handler=llm_handler,\n        gpu_config=gpu_config,\n        device=device,\n        offload_to_cpu=offload_to_cpu,\n        checkpoint_dir=checkpoint_dir,\n        get_model_name=get_model_name,\n        ensure_model_downloaded=ensure_model_downloaded,\n        env_bool=env_bool,\n    )\n\n    print(\"[API Server] All models initialized successfully!\")\n"
  },
  {
    "path": "acestep/api/startup_model_init_test.py",
    "content": "\"\"\"Unit tests for startup model initialization orchestration helper.\"\"\"\n\nfrom __future__ import annotations\n\nimport os\nimport unittest\nfrom types import SimpleNamespace\nfrom unittest.mock import ANY, MagicMock, patch\n\nfrom acestep.api.startup_model_init import initialize_models_at_startup\n\n\ndef _gpu_config(init_lm_default: bool = True) -> SimpleNamespace:\n    \"\"\"Create a fake GPU config object with all fields used by startup init.\"\"\"\n\n    return SimpleNamespace(\n        gpu_memory_gb=24.0,\n        tier=\"high\",\n        max_duration_with_lm=180,\n        max_duration_without_lm=300,\n        max_batch_size_with_lm=2,\n        max_batch_size_without_lm=4,\n        init_lm_default=init_lm_default,\n        available_lm_models=[\"acestep-5Hz-lm-1.1B\"],\n    )\n\n\nclass StartupModelInitTests(unittest.TestCase):\n    \"\"\"Behavior tests for startup model-loading orchestration.\"\"\"\n\n    @patch(\"acestep.api.startup_model_init.initialize_llm_at_startup\")\n    @patch(\"acestep.api.startup_model_init.set_global_gpu_config\")\n    @patch(\"acestep.api.startup_model_init.get_gpu_config\")\n    def test_initialize_models_at_startup_skips_model_init_in_no_init_mode(\n        self,\n        mock_get_gpu_config: MagicMock,\n        _mock_set_global_gpu_config: MagicMock,\n        mock_initialize_llm_at_startup: MagicMock,\n    ) -> None:\n        \"\"\"Helper should skip model initialization when ACESTEP_NO_INIT resolves true.\"\"\"\n\n        app = SimpleNamespace(state=SimpleNamespace())\n        handler = MagicMock()\n        llm_handler = MagicMock()\n        mock_get_gpu_config.return_value = _gpu_config()\n\n        def _env_bool(name: str, default: bool) -> bool:\n            return True if name == \"ACESTEP_NO_INIT\" else default\n\n        initialize_models_at_startup(\n            app=app,\n            handler=handler,\n            llm_handler=llm_handler,\n            handler2=None,\n            handler3=None,\n            config_path2=\"\",\n            config_path3=\"\",\n            get_project_root=MagicMock(return_value=\"k:/repo\"),\n            get_model_name=MagicMock(return_value=\"acestep-v15-turbo\"),\n            ensure_model_downloaded=MagicMock(),\n            env_bool=_env_bool,\n        )\n\n        handler.initialize_service.assert_not_called()\n        mock_initialize_llm_at_startup.assert_not_called()\n        self.assertIsNotNone(getattr(app.state, \"gpu_config\", None))\n\n    @patch(\"acestep.api.startup_model_init.initialize_llm_at_startup\")\n    @patch(\"acestep.api.startup_model_init.set_global_gpu_config\")\n    @patch(\"acestep.api.startup_model_init.get_gpu_config\")\n    def test_initialize_models_at_startup_initializes_primary_and_calls_llm(\n        self,\n        mock_get_gpu_config: MagicMock,\n        _mock_set_global_gpu_config: MagicMock,\n        mock_initialize_llm_at_startup: MagicMock,\n    ) -> None:\n        \"\"\"Helper should initialize primary DiT and then call LLM startup helper.\"\"\"\n\n        app = SimpleNamespace(\n            state=SimpleNamespace(\n                _initialized=False,\n                _initialized2=False,\n                _initialized3=False,\n                _init_error=None,\n                _llm_initialized=False,\n                _llm_init_error=None,\n                _llm_lazy_load_disabled=False,\n            )\n        )\n        handler = MagicMock()\n        handler.initialize_service.return_value = (\"ok\", True)\n        llm_handler = MagicMock()\n        ensure_model_downloaded = MagicMock()\n        mock_get_gpu_config.return_value = _gpu_config()\n\n        with patch.dict(os.environ, {}, clear=True):\n            initialize_models_at_startup(\n                app=app,\n                handler=handler,\n                llm_handler=llm_handler,\n                handler2=None,\n                handler3=None,\n                config_path2=\"\",\n                config_path3=\"\",\n                get_project_root=MagicMock(return_value=\"k:/repo\"),\n                get_model_name=MagicMock(return_value=\"acestep-v15-turbo\"),\n                ensure_model_downloaded=ensure_model_downloaded,\n                env_bool=lambda _name, default: default,\n            )\n\n        handler.initialize_service.assert_called_once()\n        ensure_model_downloaded.assert_any_call(\"acestep-v15-turbo\", ANY)\n        ensure_model_downloaded.assert_any_call(\"vae\", ANY)\n        self.assertTrue(app.state._initialized)\n        mock_initialize_llm_at_startup.assert_called_once()\n\n    @patch(\"acestep.api.startup_model_init.initialize_llm_at_startup\")\n    @patch(\"acestep.api.startup_model_init.set_global_gpu_config\")\n    @patch(\"acestep.api.startup_model_init.get_gpu_config\")\n    def test_initialize_models_at_startup_raises_on_primary_init_failure(\n        self,\n        mock_get_gpu_config: MagicMock,\n        _mock_set_global_gpu_config: MagicMock,\n        mock_initialize_llm_at_startup: MagicMock,\n    ) -> None:\n        \"\"\"Helper should raise and persist init error when primary DiT fails.\"\"\"\n\n        app = SimpleNamespace(\n            state=SimpleNamespace(\n                _initialized=False,\n                _init_error=None,\n                _llm_initialized=False,\n                _llm_init_error=None,\n                _llm_lazy_load_disabled=False,\n            )\n        )\n        handler = MagicMock()\n        handler.initialize_service.return_value = (\"boom\", False)\n        mock_get_gpu_config.return_value = _gpu_config()\n\n        with patch.dict(os.environ, {}, clear=True):\n            with self.assertRaisesRegex(RuntimeError, \"boom\"):\n                initialize_models_at_startup(\n                    app=app,\n                    handler=handler,\n                    llm_handler=MagicMock(),\n                    handler2=None,\n                    handler3=None,\n                    config_path2=\"\",\n                    config_path3=\"\",\n                    get_project_root=MagicMock(return_value=\"k:/repo\"),\n                    get_model_name=MagicMock(return_value=\"acestep-v15-turbo\"),\n                    ensure_model_downloaded=MagicMock(),\n                    env_bool=lambda _name, default: default,\n                )\n\n        mock_initialize_llm_at_startup.assert_not_called()\n        self.assertEqual(\"boom\", app.state._init_error)\n\n\nif __name__ == \"__main__\":\n    unittest.main()\n"
  },
  {
    "path": "acestep/api/train_api_dataset_auto_label_async_route.py",
    "content": "\"\"\"Async auto-label route registration for training dataset APIs.\"\"\"\n\nfrom __future__ import annotations\n\nimport os\nimport time\nfrom typing import Any, Callable, Dict, Optional\nfrom uuid import uuid4\n\nfrom fastapi import Depends, FastAPI, HTTPException\nfrom loguru import logger\n\nfrom acestep.api import train_api_models\nfrom acestep.api.train_api_dataset_models import AutoLabelRequest, _serialize_samples\nfrom acestep.api.train_api_runtime import RuntimeComponentManager\nfrom acestep.handler import AceStepHandler\nfrom acestep.llm_inference import LLMHandler\n\n\ndef register_training_dataset_auto_label_async_route(\n    app: FastAPI,\n    verify_api_key: Callable[..., Any],\n    wrap_response: Callable[[Any, int, Optional[str]], Dict[str, Any]],\n    temporary_llm_model: Callable[[FastAPI, LLMHandler, Optional[str]], Any],\n    atomic_write_json: Callable[[str, Dict[str, Any]], None],\n    append_jsonl: Callable[[str, Dict[str, Any]], None],\n) -> None:\n    \"\"\"Register the asynchronous auto-label route.\"\"\"\n\n    @app.post(\"/v1/dataset/auto_label_async\")\n    async def auto_label_dataset_async(request: AutoLabelRequest, _: None = Depends(verify_api_key)):\n        \"\"\"Start auto-labeling task asynchronously and return task_id immediately.\"\"\"\n\n        builder = app.state.dataset_builder\n        if builder is None:\n            raise HTTPException(status_code=400, detail=\"No dataset loaded. Please scan or load a dataset first.\")\n\n        handler: AceStepHandler = app.state.handler\n        llm: LLMHandler = app.state.llm_handler\n\n        if handler is None or handler.model is None:\n            raise HTTPException(status_code=500, detail=\"Model not initialized\")\n\n        if llm is None or not llm.llm_initialized:\n            raise HTTPException(status_code=500, detail=\"LLM not initialized\")\n\n        task_id = str(uuid4())\n\n        if request.only_unlabeled:\n            samples_to_label = [sample for sample in builder.samples if not sample.labeled or not sample.caption]\n        else:\n            samples_to_label = builder.samples\n\n        total = len(samples_to_label)\n        if total == 0:\n            return wrap_response(\n                {\n                    \"task_id\": task_id,\n                    \"message\": \"All samples already labeled\" if request.only_unlabeled else \"No samples to label\",\n                    \"total\": 0,\n                }\n            )\n\n        resolved_save_path = (request.save_path.strip() if request.save_path else None) or getattr(\n            app.state,\n            \"dataset_json_path\",\n            None,\n        )\n        resolved_save_path = os.path.normpath(resolved_save_path) if resolved_save_path else None\n        with train_api_models._auto_label_lock:\n            train_api_models._auto_label_tasks[task_id] = train_api_models.AutoLabelTask(\n                task_id=task_id,\n                status=\"running\",\n                progress=(f\"Starting... (save_path={resolved_save_path})\" if resolved_save_path else \"Starting...\"),\n                current=0,\n                total=total,\n                save_path=resolved_save_path,\n                created_at=time.time(),\n                updated_at=time.time(),\n            )\n            train_api_models._auto_label_latest_task_id = task_id\n\n        if resolved_save_path:\n            try:\n                dataset = {\n                    \"metadata\": builder.metadata.to_dict(),\n                    \"samples\": [sample.to_dict() for sample in builder.samples],\n                }\n                atomic_write_json(resolved_save_path, dataset)\n            except Exception as exc:\n                logger.exception(\"Auto-label initial save failed\")\n                with train_api_models._auto_label_lock:\n                    task = train_api_models._auto_label_tasks.get(task_id)\n                    if task:\n                        task.progress = f\"⚠️ Initial save failed: {exc}\"\n                        task.updated_at = time.time()\n\n        def run_labeling() -> None:\n            mgr = RuntimeComponentManager(handler=handler, llm=llm, app_state=app.state)\n            mgr.offload_decoder_to_cpu()\n\n            try:\n                with temporary_llm_model(app, llm, request.lm_model_path):\n\n                    def progress_callback(msg: str):\n                        with train_api_models._auto_label_lock:\n                            task = train_api_models._auto_label_tasks.get(task_id)\n                            if task:\n                                task.progress = msg\n                                task.updated_at = time.time()\n                                import re\n\n                                match = re.match(r\"^(?:VAE encoding|Tokenizing|Labeling|Encoding) (\\d+)/(\\d+)\", msg)\n                                if match:\n                                    task.current = int(match.group(1))\n                                    task.total = int(match.group(2))\n\n                    resolved_jsonl_path = f\"{resolved_save_path}.autolabel.jsonl\" if resolved_save_path else None\n\n                    def sample_labeled_callback(sample_idx: int, sample: Any, status: str):\n                        if \"✅\" not in status:\n                            return\n\n                        with train_api_models._auto_label_lock:\n                            task = train_api_models._auto_label_tasks.get(task_id)\n                            if task:\n                                task.progress = status\n                                task.last_updated_index = sample_idx\n                                task.last_updated_sample = sample.to_dict()\n                                task.updated_at = time.time()\n\n                        if resolved_save_path is None:\n                            return\n                        try:\n                            if resolved_jsonl_path is not None:\n                                append_jsonl(\n                                    resolved_jsonl_path,\n                                    {\n                                        \"ts\": time.time(),\n                                        \"index\": sample_idx,\n                                        \"status\": status,\n                                        \"sample\": sample.to_dict(),\n                                    },\n                                )\n                            dataset = {\n                                \"metadata\": builder.metadata.to_dict(),\n                                \"samples\": [sample.to_dict() for sample in builder.samples],\n                            }\n                            atomic_write_json(resolved_save_path, dataset)\n                        except Exception:\n                            logger.exception(\"Auto-label incremental save failed\")\n                            with train_api_models._auto_label_lock:\n                                task = train_api_models._auto_label_tasks.get(task_id)\n                                if task:\n                                    task.progress = \"⚠️ Auto-label incremental save failed (see server logs)\"\n                                    task.updated_at = time.time()\n\n                    _samples, status = builder.label_all_samples(\n                        dit_handler=handler,\n                        llm_handler=llm,\n                        format_lyrics=request.format_lyrics,\n                        transcribe_lyrics=request.transcribe_lyrics,\n                        skip_metas=request.skip_metas,\n                        only_unlabeled=request.only_unlabeled,\n                        chunk_size=request.chunk_size,\n                        batch_size=request.batch_size,\n                        progress_callback=progress_callback,\n                        sample_labeled_callback=sample_labeled_callback,\n                    )\n\n                    if mgr.decoder_moved:\n                        status += \"\\nℹ️ Decoder was temporarily offloaded during labeling and restored afterward.\"\n\n                    with train_api_models._auto_label_lock:\n                        task = train_api_models._auto_label_tasks.get(task_id)\n                        if task:\n                            task.status = \"completed\"\n                            task.progress = status\n                            task.current = task.total\n                            task.updated_at = time.time()\n                            task.result = {\n                                \"message\": status,\n                                \"labeled_count\": builder.get_labeled_count(),\n                                \"samples\": _serialize_samples(builder),\n                            }\n            except Exception as exc:\n                with train_api_models._auto_label_lock:\n                    task = train_api_models._auto_label_tasks.get(task_id)\n                    if task:\n                        task.status = \"failed\"\n                        task.error = str(exc)\n                        task.progress = f\"Failed: {exc}\"\n                        task.updated_at = time.time()\n            finally:\n                mgr.restore()\n\n        import threading\n\n        thread = threading.Thread(target=run_labeling, daemon=True)\n        thread.start()\n\n        return wrap_response(\n            {\n                \"task_id\": task_id,\n                \"message\": \"Auto-labeling task started\",\n                \"total\": total,\n            }\n        )\n"
  },
  {
    "path": "acestep/api/train_api_dataset_auto_label_routes.py",
    "content": "\"\"\"Auto-label route-registration facade for training dataset APIs.\"\"\"\n\nfrom __future__ import annotations\n\nfrom typing import Any, Callable, Dict, Optional\n\nfrom fastapi import FastAPI\n\nfrom acestep.api.train_api_dataset_auto_label_async_route import (\n    register_training_dataset_auto_label_async_route,\n)\nfrom acestep.api.train_api_dataset_auto_label_status_route import (\n    register_training_dataset_auto_label_status_route,\n)\nfrom acestep.api.train_api_dataset_auto_label_sync_route import (\n    register_training_dataset_auto_label_sync_route,\n)\nfrom acestep.llm_inference import LLMHandler\n\n\ndef register_training_dataset_auto_label_routes(\n    app: FastAPI,\n    verify_api_key: Callable[..., Any],\n    wrap_response: Callable[[Any, int, Optional[str]], Dict[str, Any]],\n    temporary_llm_model: Callable[[FastAPI, LLMHandler, Optional[str]], Any],\n    atomic_write_json: Callable[[str, Dict[str, Any]], None],\n    append_jsonl: Callable[[str, Dict[str, Any]], None],\n) -> None:\n    \"\"\"Register all auto-label routes via focused submodules.\"\"\"\n\n    register_training_dataset_auto_label_sync_route(\n        app=app,\n        verify_api_key=verify_api_key,\n        wrap_response=wrap_response,\n        temporary_llm_model=temporary_llm_model,\n        atomic_write_json=atomic_write_json,\n        append_jsonl=append_jsonl,\n    )\n    register_training_dataset_auto_label_async_route(\n        app=app,\n        verify_api_key=verify_api_key,\n        wrap_response=wrap_response,\n        temporary_llm_model=temporary_llm_model,\n        atomic_write_json=atomic_write_json,\n        append_jsonl=append_jsonl,\n    )\n    register_training_dataset_auto_label_status_route(\n        app=app,\n        verify_api_key=verify_api_key,\n        wrap_response=wrap_response,\n    )\n"
  },
  {
    "path": "acestep/api/train_api_dataset_auto_label_routes_http_test.py",
    "content": "\"\"\"HTTP integration tests for dataset auto-label route registration.\"\"\"\n\nfrom __future__ import annotations\n\nfrom contextlib import contextmanager\nfrom types import SimpleNamespace\nfrom typing import Any, Dict, Optional\nimport time\nimport tempfile\nimport unittest\nfrom pathlib import Path\n\nfrom fastapi import FastAPI, Header, HTTPException\nfrom fastapi.testclient import TestClient\n\nfrom acestep.api import train_api_models\nfrom acestep.api.train_api_dataset_auto_label_routes import register_training_dataset_auto_label_routes\n\n\ndef _wrap_response(data: Any, code: int = 200, error: Optional[str] = None) -> Dict[str, Any]:\n    \"\"\"Return API-compatible response envelope for tests.\"\"\"\n\n    return {\"data\": data, \"code\": code, \"error\": error}\n\n\nasync def _verify_api_key(authorization: str | None = Header(None)) -> None:\n    \"\"\"Require fixed bearer token for test requests.\"\"\"\n\n    if authorization != \"Bearer test-token\":\n        raise HTTPException(status_code=401, detail=\"Unauthorized\")\n\n\n@contextmanager\ndef _temporary_llm_model(_app: FastAPI, _llm: Any, _lm_model_path: Optional[str]):\n    \"\"\"No-op context manager used by auto-label routes during tests.\"\"\"\n\n    yield\n\n\nclass _Sample:\n    \"\"\"Sample test double with attributes consumed by route handlers.\"\"\"\n\n    def __init__(self, caption: str = \"ready\", labeled: bool = True) -> None:\n        \"\"\"Initialize sample fields and deterministic defaults.\"\"\"\n\n        self.filename = \"sample.wav\"\n        self.audio_path = str(Path(tempfile.gettempdir()) / \"sample.wav\")\n        self.duration = 10.0\n        self.caption = caption\n        self.genre = \"electronic\"\n        self.prompt_override = None\n        self.lyrics = \"[Instrumental]\"\n        self.bpm = 120\n        self.keyscale = \"C major\"\n        self.timesignature = \"4/4\"\n        self.language = \"unknown\"\n        self.is_instrumental = True\n        self.labeled = labeled\n\n    def to_dict(self) -> dict[str, Any]:\n        \"\"\"Return dictionary payload for persistence/status code paths.\"\"\"\n\n        return {\n            \"filename\": self.filename,\n            \"audio_path\": self.audio_path,\n            \"duration\": self.duration,\n            \"caption\": self.caption,\n            \"genre\": self.genre,\n            \"prompt_override\": self.prompt_override,\n            \"lyrics\": self.lyrics,\n            \"bpm\": self.bpm,\n            \"keyscale\": self.keyscale,\n            \"timesignature\": self.timesignature,\n            \"language\": self.language,\n            \"is_instrumental\": self.is_instrumental,\n            \"labeled\": self.labeled,\n        }\n\n\nclass _Metadata:\n    \"\"\"Metadata test double expected by dataset builder routes.\"\"\"\n\n    def to_dict(self) -> dict[str, Any]:\n        \"\"\"Return dictionary payload used by checkpoint writes.\"\"\"\n\n        return {\"name\": \"my_dataset\"}\n\n\nclass _Builder:\n    \"\"\"Dataset builder test double for auto-label route behavior.\"\"\"\n\n    def __init__(self, samples: list[_Sample]) -> None:\n        \"\"\"Store deterministic samples for route logic.\"\"\"\n\n        self.metadata = _Metadata()\n        self.samples = samples\n\n    def get_labeled_count(self) -> int:\n        \"\"\"Return number of labeled samples.\"\"\"\n\n        return sum(1 for sample in self.samples if sample.labeled)\n\n    def label_all_samples(self, **_kwargs: Any) -> tuple[list[_Sample], str]:\n        \"\"\"Return successful label status without mutating sample data.\"\"\"\n\n        return self.samples, \"ok\"\n\n\nclass TrainApiDatasetAutoLabelRoutesHttpTests(unittest.TestCase):\n    \"\"\"HTTP tests covering extracted auto-label route behavior.\"\"\"\n\n    def setUp(self) -> None:\n        \"\"\"Reset global task registries before each test.\"\"\"\n\n        with train_api_models._auto_label_lock:\n            train_api_models._auto_label_tasks.clear()\n            train_api_models._auto_label_latest_task_id = None\n\n    def tearDown(self) -> None:\n        \"\"\"Reset global task registries after each test.\"\"\"\n\n        with train_api_models._auto_label_lock:\n            train_api_models._auto_label_tasks.clear()\n            train_api_models._auto_label_latest_task_id = None\n\n    def _build_client(self, samples: list[_Sample]) -> TestClient:\n        \"\"\"Create app/client pair with lightweight dataset + model state.\"\"\"\n\n        app = FastAPI()\n        app.state.dataset_builder = _Builder(samples=samples)\n        app.state.dataset_json_path = \"dataset.json\"\n        app.state.handler = SimpleNamespace(model=object())\n        app.state.llm_handler = SimpleNamespace(llm_initialized=True)\n        register_training_dataset_auto_label_routes(\n            app=app,\n            verify_api_key=_verify_api_key,\n            wrap_response=_wrap_response,\n            temporary_llm_model=_temporary_llm_model,\n            atomic_write_json=lambda _path, _payload: None,\n            append_jsonl=lambda _path, _record: None,\n        )\n        return TestClient(app)\n\n    def test_auto_label_requires_auth(self) -> None:\n        \"\"\"POST /v1/dataset/auto_label should return 401 when auth token is missing.\"\"\"\n\n        client = self._build_client(samples=[_Sample()])\n        response = client.post(\"/v1/dataset/auto_label\", json={})\n        self.assertEqual(401, response.status_code)\n\n    def test_auto_label_async_returns_zero_total_for_only_unlabeled_when_all_labeled(self) -> None:\n        \"\"\"POST /v1/dataset/auto_label_async should return zero total when all samples are already labeled.\"\"\"\n\n        client = self._build_client(samples=[_Sample(caption=\"ready\", labeled=True)])\n        response = client.post(\n            \"/v1/dataset/auto_label_async\",\n            json={\"only_unlabeled\": True},\n            headers={\"Authorization\": \"Bearer test-token\"},\n        )\n\n        self.assertEqual(200, response.status_code)\n        payload = response.json()\n        self.assertEqual(200, payload[\"code\"])\n        self.assertEqual(0, payload[\"data\"][\"total\"])\n        self.assertEqual(\"All samples already labeled\", payload[\"data\"][\"message\"])\n\n    def test_auto_label_status_returns_wrapped_task_payload(self) -> None:\n        \"\"\"GET /v1/dataset/auto_label_status/{task_id} should return wrapped task fields for known tasks.\"\"\"\n\n        client = self._build_client(samples=[_Sample()])\n        with train_api_models._auto_label_lock:\n            train_api_models._auto_label_tasks[\"task-1\"] = train_api_models.AutoLabelTask(\n                task_id=\"task-1\",\n                status=\"running\",\n                progress=\"working\",\n                current=1,\n                total=10,\n                save_path=\"dataset.json\",\n                created_at=time.time(),\n                updated_at=time.time(),\n            )\n\n        response = client.get(\n            \"/v1/dataset/auto_label_status/task-1\",\n            headers={\"Authorization\": \"Bearer test-token\"},\n        )\n\n        self.assertEqual(200, response.status_code)\n        payload = response.json()\n        self.assertEqual(200, payload[\"code\"])\n        self.assertEqual(\"task-1\", payload[\"data\"][\"task_id\"])\n        self.assertEqual(\"running\", payload[\"data\"][\"status\"])\n        self.assertEqual(1, payload[\"data\"][\"current\"])\n        self.assertEqual(10, payload[\"data\"][\"total\"])\n\n\nif __name__ == \"__main__\":\n    unittest.main()\n"
  },
  {
    "path": "acestep/api/train_api_dataset_auto_label_status_route.py",
    "content": "\"\"\"Auto-label status-by-task route registration for training dataset APIs.\"\"\"\n\nfrom __future__ import annotations\n\nfrom typing import Any, Callable, Dict, Optional\n\nfrom fastapi import Depends, FastAPI, HTTPException\n\nfrom acestep.api import train_api_models\n\n\ndef register_training_dataset_auto_label_status_route(\n    app: FastAPI,\n    verify_api_key: Callable[..., Any],\n    wrap_response: Callable[[Any, int, Optional[str]], Dict[str, Any]],\n) -> None:\n    \"\"\"Register the task-id status route for auto-label workflows.\"\"\"\n\n    @app.get(\"/v1/dataset/auto_label_status/{task_id}\")\n    async def get_auto_label_status(task_id: str, _: None = Depends(verify_api_key)):\n        \"\"\"Get auto-labeling task status and progress.\"\"\"\n\n        with train_api_models._auto_label_lock:\n            task = train_api_models._auto_label_tasks.get(task_id)\n            if not task:\n                raise HTTPException(status_code=404, detail=\"Task not found\")\n\n            response_data = {\n                \"task_id\": task.task_id,\n                \"status\": task.status,\n                \"progress\": task.progress,\n                \"current\": task.current,\n                \"total\": task.total,\n                \"save_path\": task.save_path,\n                \"last_updated_index\": task.last_updated_index,\n                \"last_updated_sample\": task.last_updated_sample,\n            }\n\n            if task.status == \"completed\" and task.result:\n                response_data[\"result\"] = task.result\n            elif task.status == \"failed\" and task.error:\n                response_data[\"error\"] = task.error\n\n            return wrap_response(response_data)\n"
  },
  {
    "path": "acestep/api/train_api_dataset_auto_label_sync_route.py",
    "content": "\"\"\"Sync auto-label route registration for training dataset APIs.\"\"\"\n\nfrom __future__ import annotations\n\nimport os\nimport time\nfrom typing import Any, Callable, Dict, Optional\n\nfrom fastapi import Depends, FastAPI, HTTPException\nfrom loguru import logger\n\nfrom acestep.api.train_api_dataset_models import AutoLabelRequest, _serialize_samples\nfrom acestep.api.train_api_runtime import RuntimeComponentManager\nfrom acestep.handler import AceStepHandler\nfrom acestep.llm_inference import LLMHandler\n\n\ndef register_training_dataset_auto_label_sync_route(\n    app: FastAPI,\n    verify_api_key: Callable[..., Any],\n    wrap_response: Callable[[Any, int, Optional[str]], Dict[str, Any]],\n    temporary_llm_model: Callable[[FastAPI, LLMHandler, Optional[str]], Any],\n    atomic_write_json: Callable[[str, Dict[str, Any]], None],\n    append_jsonl: Callable[[str, Dict[str, Any]], None],\n) -> None:\n    \"\"\"Register the synchronous auto-label route.\"\"\"\n\n    @app.post(\"/v1/dataset/auto_label\")\n    async def auto_label_dataset(request: AutoLabelRequest, _: None = Depends(verify_api_key)):\n        \"\"\"Auto-label all samples using AI.\"\"\"\n\n        builder = app.state.dataset_builder\n        if builder is None:\n            raise HTTPException(status_code=400, detail=\"No dataset loaded. Please scan or load a dataset first.\")\n\n        handler: AceStepHandler = app.state.handler\n        llm: LLMHandler = app.state.llm_handler\n\n        if handler is None or handler.model is None:\n            raise HTTPException(status_code=500, detail=\"Model not initialized\")\n\n        if llm is None or not llm.llm_initialized:\n            raise HTTPException(status_code=500, detail=\"LLM not initialized\")\n\n        mgr = RuntimeComponentManager(handler=handler, llm=llm, app_state=app.state)\n        mgr.offload_decoder_to_cpu()\n\n        try:\n            with temporary_llm_model(app, llm, request.lm_model_path):\n                resolved_save_path = (request.save_path.strip() if request.save_path else None) or getattr(\n                    app.state,\n                    \"dataset_json_path\",\n                    None,\n                )\n                resolved_save_path = os.path.normpath(resolved_save_path) if resolved_save_path else None\n                resolved_jsonl_path = f\"{resolved_save_path}.autolabel.jsonl\" if resolved_save_path else None\n\n                if resolved_save_path:\n                    try:\n                        dataset = {\n                            \"metadata\": builder.metadata.to_dict(),\n                            \"samples\": [sample.to_dict() for sample in builder.samples],\n                        }\n                        atomic_write_json(resolved_save_path, dataset)\n                    except Exception:\n                        logger.exception(\"Auto-label initial save failed\")\n\n                def sample_labeled_callback(sample_idx: int, sample: Any, status: str):\n                    if resolved_save_path is None:\n                        return\n                    if \"✅\" not in status:\n                        return\n\n                    try:\n                        if resolved_jsonl_path is not None:\n                            append_jsonl(\n                                resolved_jsonl_path,\n                                {\n                                    \"ts\": time.time(),\n                                    \"index\": sample_idx,\n                                    \"status\": status,\n                                    \"sample\": sample.to_dict(),\n                                },\n                            )\n                        dataset = {\n                            \"metadata\": builder.metadata.to_dict(),\n                            \"samples\": [sample.to_dict() for sample in builder.samples],\n                        }\n                        atomic_write_json(resolved_save_path, dataset)\n                    except Exception:\n                        logger.exception(\"Auto-label incremental save failed\")\n\n                _samples, status = builder.label_all_samples(\n                    dit_handler=handler,\n                    llm_handler=llm,\n                    format_lyrics=request.format_lyrics,\n                    transcribe_lyrics=request.transcribe_lyrics,\n                    skip_metas=request.skip_metas,\n                    only_unlabeled=request.only_unlabeled,\n                    chunk_size=request.chunk_size,\n                    batch_size=request.batch_size,\n                    progress_callback=None,\n                    sample_labeled_callback=sample_labeled_callback,\n                )\n\n                if mgr.decoder_moved:\n                    status += \"\\nℹ️ Decoder was temporarily offloaded during labeling and restored afterward.\"\n\n                return wrap_response(\n                    {\n                        \"message\": status,\n                        \"labeled_count\": builder.get_labeled_count(),\n                        \"samples\": _serialize_samples(builder),\n                    }\n                )\n        except Exception as exc:\n            return wrap_response(None, code=500, error=f\"Auto-label failed: {exc}\")\n        finally:\n            mgr.restore()\n"
  },
  {
    "path": "acestep/api/train_api_dataset_models.py",
    "content": "\"\"\"Request payload schemas and sample serialization for training dataset routes.\"\"\"\n\nfrom __future__ import annotations\n\nfrom typing import Any, Dict, Optional\n\nfrom pydantic import BaseModel, Field, root_validator\n\n\nclass ScanDirectoryRequest(BaseModel):\n    \"\"\"Request payload for scanning a directory into a dataset.\"\"\"\n\n    audio_dir: str = Field(..., description=\"Directory path to scan for audio files\")\n    dataset_name: str = Field(default=\"my_lora_dataset\", description=\"Dataset name\")\n    custom_tag: str = Field(default=\"\", description=\"Custom activation tag\")\n    tag_position: str = Field(default=\"replace\", description=\"Tag position: prepend/append/replace\")\n    all_instrumental: bool = Field(default=True, description=\"All tracks instrumental\")\n\n\nclass LoadDatasetRequest(BaseModel):\n    \"\"\"Request payload for loading an existing dataset JSON file.\"\"\"\n\n    dataset_path: str = Field(..., description=\"Path to dataset JSON file\")\n\n\nclass AutoLabelRequest(BaseModel):\n    \"\"\"Request payload for auto-labeling dataset samples.\"\"\"\n\n    skip_metas: bool = Field(default=False, description=\"Skip BPM/Key/TimeSig generation\")\n    format_lyrics: bool = Field(default=False, description=\"Format user lyrics via LLM\")\n    transcribe_lyrics: bool = Field(default=False, description=\"Transcribe lyrics from audio\")\n    only_unlabeled: bool = Field(default=False, description=\"Only label unlabeled samples\")\n\n    lm_model_path: Optional[str] = Field(\n        default=None,\n        description=\"Optional LM model path to use for labeling (temporary switch)\",\n    )\n\n    save_path: Optional[str] = Field(\n        default=None,\n        description=\"Optional dataset JSON path to persist progress during auto-label\",\n    )\n\n    chunk_size: int = Field(default=16, ge=1, description=\"Chunk size for batch audio encoding\")\n    batch_size: int = Field(default=1, ge=1, description=\"Batch size for batch audio encoding\")\n\n    @root_validator(pre=True)\n    def _backward_compatible_field_names(cls, values: Dict[str, Any]):\n        \"\"\"Map legacy payload fields to current request field names.\"\"\"\n\n        if values is None:\n            return values\n\n        if \"chunk_size\" not in values or values.get(\"chunk_size\") is None:\n            for key in (\"hunk_size\", \"hunksize\"):\n                if key in values and values.get(key) is not None:\n                    values[\"chunk_size\"] = values[key]\n                    break\n\n        if \"batch_size\" not in values or values.get(\"batch_size\") is None:\n            for key in (\"batchsize\",):\n                if key in values and values.get(key) is not None:\n                    values[\"batch_size\"] = values[key]\n                    break\n\n        return values\n\n\nclass SaveDatasetRequest(BaseModel):\n    \"\"\"Request payload for persisting current dataset state.\"\"\"\n\n    save_path: str = Field(..., description=\"Path to save dataset JSON\")\n    dataset_name: str = Field(default=\"my_lora_dataset\", description=\"Dataset name\")\n    custom_tag: Optional[str] = Field(default=None, description=\"Custom activation tag\")\n    tag_position: Optional[str] = Field(default=None, description=\"Tag position: prepend/append/replace\")\n    all_instrumental: Optional[bool] = Field(default=None, description=\"All tracks instrumental\")\n    genre_ratio: Optional[int] = Field(default=None, ge=0, le=100, description=\"Genre vs caption ratio\")\n\n\nclass UpdateSampleRequest(BaseModel):\n    \"\"\"Request payload for updating a single dataset sample.\"\"\"\n\n    sample_idx: int = Field(..., ge=0, description=\"Sample index\")\n    caption: str = Field(default=\"\", description=\"Music description\")\n    genre: str = Field(default=\"\", description=\"Genre tags\")\n    prompt_override: Optional[str] = Field(default=None, description=\"caption/genre/None\")\n    lyrics: str = Field(default=\"[Instrumental]\", description=\"Lyrics\")\n    bpm: Optional[int] = Field(default=None, description=\"BPM\")\n    keyscale: str = Field(default=\"\", description=\"Musical key\")\n    timesignature: str = Field(default=\"\", description=\"Time signature\")\n    language: str = Field(default=\"unknown\", description=\"Vocal language\")\n    is_instrumental: bool = Field(default=True, description=\"Instrumental track\")\n\n\nclass PreprocessDatasetRequest(BaseModel):\n    \"\"\"Request payload for dataset tensor preprocessing.\"\"\"\n\n    output_dir: str = Field(..., description=\"Output directory for preprocessed tensors\")\n    skip_existing: bool = Field(default=False, description=\"Skip tensors that already exist (by sample id filename)\")\n\n\ndef _serialize_samples(builder: Any) -> list[Dict[str, Any]]:\n    \"\"\"Return stable sample payload list for dataset endpoints.\"\"\"\n\n    return [\n        {\n            \"index\": i,\n            \"filename\": sample.filename,\n            \"audio_path\": sample.audio_path,\n            \"duration\": sample.duration,\n            \"caption\": sample.caption,\n            \"genre\": sample.genre,\n            \"prompt_override\": sample.prompt_override,\n            \"lyrics\": sample.lyrics,\n            \"bpm\": sample.bpm,\n            \"keyscale\": sample.keyscale,\n            \"timesignature\": sample.timesignature,\n            \"language\": sample.language,\n            \"is_instrumental\": sample.is_instrumental,\n            \"labeled\": sample.labeled,\n        }\n        for i, sample in enumerate(builder.samples)\n    ]\n"
  },
  {
    "path": "acestep/api/train_api_dataset_models_test.py",
    "content": "\"\"\"Unit tests for training dataset request models and serialization helpers.\"\"\"\n\nfrom __future__ import annotations\n\nimport tempfile\nimport unittest\nfrom pathlib import Path\n\nfrom acestep.api.train_api_dataset_models import AutoLabelRequest, _serialize_samples\n\n\nclass _Sample:\n    \"\"\"Lightweight sample object for serializer tests.\"\"\"\n\n    def __init__(\n        self,\n        filename: str,\n        audio_path: str,\n        duration: float,\n        caption: str,\n        genre: str,\n        prompt_override: str | None,\n        lyrics: str,\n        bpm: int | None,\n        keyscale: str,\n        timesignature: str,\n        language: str,\n        is_instrumental: bool,\n        labeled: bool,\n    ) -> None:\n        \"\"\"Store sample attributes used by the serializer helper.\"\"\"\n\n        self.filename = filename\n        self.audio_path = audio_path\n        self.duration = duration\n        self.caption = caption\n        self.genre = genre\n        self.prompt_override = prompt_override\n        self.lyrics = lyrics\n        self.bpm = bpm\n        self.keyscale = keyscale\n        self.timesignature = timesignature\n        self.language = language\n        self.is_instrumental = is_instrumental\n        self.labeled = labeled\n\n\nclass _Builder:\n    \"\"\"Minimal builder object exposing a ``samples`` list.\"\"\"\n\n    def __init__(self, samples: list[_Sample]) -> None:\n        \"\"\"Initialize with deterministic sample data.\"\"\"\n\n        self.samples = samples\n\n\nclass TrainApiDatasetModelsTests(unittest.TestCase):\n    \"\"\"Behavior tests for extracted request models and serializers.\"\"\"\n\n    _TEST_AUDIO_PATH = str(Path(tempfile.gettempdir()) / \"song.wav\")\n\n    def test_auto_label_request_maps_hunk_size_alias(self) -> None:\n        \"\"\"``hunk_size`` payload key should populate ``chunk_size``.\"\"\"\n\n        request = AutoLabelRequest(hunk_size=32)\n        self.assertEqual(32, request.chunk_size)\n\n    def test_auto_label_request_maps_hunksize_alias(self) -> None:\n        \"\"\"``hunksize`` payload key should populate ``chunk_size``.\"\"\"\n\n        request = AutoLabelRequest(hunksize=24)\n        self.assertEqual(24, request.chunk_size)\n\n    def test_auto_label_request_maps_batchsize_alias(self) -> None:\n        \"\"\"``batchsize`` payload key should populate ``batch_size``.\"\"\"\n\n        request = AutoLabelRequest(batchsize=3)\n        self.assertEqual(3, request.batch_size)\n\n    def test_auto_label_request_keeps_explicit_values(self) -> None:\n        \"\"\"Explicit fields should not be overridden by backward-compatible aliases.\"\"\"\n\n        request = AutoLabelRequest(chunk_size=16, hunk_size=64, batch_size=2, batchsize=8)\n        self.assertEqual(16, request.chunk_size)\n        self.assertEqual(2, request.batch_size)\n\n    def test_serialize_samples_returns_expected_payload_shape(self) -> None:\n        \"\"\"Serializer should return stable dictionaries with index and sample fields.\"\"\"\n\n        builder = _Builder(\n            samples=[\n                _Sample(\n                    filename=\"song.wav\",\n                    audio_path=self._TEST_AUDIO_PATH,\n                    duration=12.5,\n                    caption=\"bright synthwave\",\n                    genre=\"synthwave\",\n                    prompt_override=None,\n                    lyrics=\"[Instrumental]\",\n                    bpm=120,\n                    keyscale=\"C major\",\n                    timesignature=\"4/4\",\n                    language=\"unknown\",\n                    is_instrumental=True,\n                    labeled=True,\n                )\n            ]\n        )\n\n        payload = _serialize_samples(builder)\n        self.assertEqual(1, len(payload))\n        self.assertEqual(0, payload[0][\"index\"])\n        self.assertEqual(\"song.wav\", payload[0][\"filename\"])\n        self.assertEqual(self._TEST_AUDIO_PATH, payload[0][\"audio_path\"])\n        self.assertEqual(12.5, payload[0][\"duration\"])\n        self.assertEqual(\"bright synthwave\", payload[0][\"caption\"])\n        self.assertEqual(\"synthwave\", payload[0][\"genre\"])\n        self.assertIsNone(payload[0][\"prompt_override\"])\n        self.assertEqual(\"[Instrumental]\", payload[0][\"lyrics\"])\n        self.assertEqual(120, payload[0][\"bpm\"])\n        self.assertEqual(\"C major\", payload[0][\"keyscale\"])\n        self.assertEqual(\"4/4\", payload[0][\"timesignature\"])\n        self.assertEqual(\"unknown\", payload[0][\"language\"])\n        self.assertTrue(payload[0][\"is_instrumental\"])\n        self.assertTrue(payload[0][\"labeled\"])\n\n\nif __name__ == \"__main__\":\n    unittest.main()\n"
  },
  {
    "path": "acestep/api/train_api_dataset_preprocess_routes.py",
    "content": "\"\"\"Preprocess route registration for training dataset APIs.\"\"\"\n\nfrom __future__ import annotations\n\nimport asyncio\nimport time\nfrom typing import Any, Callable, Dict, Optional\nfrom uuid import uuid4\n\nfrom fastapi import Depends, FastAPI, HTTPException\n\nfrom acestep.api import train_api_models\nfrom acestep.api.train_api_dataset_models import PreprocessDatasetRequest\nfrom acestep.api.train_api_runtime import RuntimeComponentManager\nfrom acestep.handler import AceStepHandler\nfrom acestep.llm_inference import LLMHandler\n\n\ndef register_training_dataset_preprocess_routes(\n    app: FastAPI,\n    verify_api_key: Callable[..., Any],\n    wrap_response: Callable[[Any, int, Optional[str]], Dict[str, Any]],\n) -> None:\n    \"\"\"Register preprocess routes used by training workflows.\"\"\"\n\n    @app.post(\"/v1/dataset/preprocess\")\n    async def preprocess_dataset(request: PreprocessDatasetRequest, _: None = Depends(verify_api_key)):\n        \"\"\"Preprocess dataset to tensor files for training.\"\"\"\n\n        builder = app.state.dataset_builder\n        if builder is None:\n            raise HTTPException(status_code=400, detail=\"No dataset loaded\")\n\n        handler: AceStepHandler = app.state.handler\n        if handler is None or handler.model is None:\n            raise HTTPException(status_code=500, detail=\"Model not initialized\")\n\n        preprocess_notes = []\n        llm: LLMHandler = app.state.llm_handler\n        mgr = RuntimeComponentManager(handler=handler, llm=llm, app_state=app.state)\n        mgr.offload_decoder_to_cpu()\n        mgr.unload_llm()\n\n        try:\n            output_paths, status = await asyncio.to_thread(\n                builder.preprocess_to_tensors,\n                dit_handler=handler,\n                output_dir=request.output_dir.strip(),\n                skip_existing=request.skip_existing,\n                progress_callback=None,\n            )\n\n            if status.startswith(\"✅\"):\n                if mgr.llm_unloaded:\n                    status += \"\\nℹ️ LLM was temporarily unloaded during preprocessing and restored afterward.\"\n                if mgr.decoder_moved:\n                    status += \"\\nℹ️ Decoder was temporarily offloaded during preprocessing and restored afterward.\"\n                if preprocess_notes:\n                    status += \"\\n\" + \"\\n\".join(preprocess_notes)\n\n                return wrap_response(\n                    {\n                        \"message\": status,\n                        \"output_dir\": request.output_dir,\n                        \"num_tensors\": len(output_paths),\n                    }\n                )\n            return wrap_response(None, code=400, error=status)\n        except Exception as exc:\n            return wrap_response(None, code=500, error=f\"Preprocessing failed: {exc}\")\n        finally:\n            mgr.restore()\n\n    @app.post(\"/v1/dataset/preprocess_async\")\n    async def preprocess_dataset_async(request: PreprocessDatasetRequest, _: None = Depends(verify_api_key)):\n        \"\"\"Start preprocessing task asynchronously and return task_id immediately.\"\"\"\n\n        builder = app.state.dataset_builder\n        if builder is None:\n            raise HTTPException(status_code=400, detail=\"No dataset loaded\")\n\n        handler: AceStepHandler = app.state.handler\n        if handler is None or handler.model is None:\n            raise HTTPException(status_code=500, detail=\"Model not initialized\")\n\n        task_id = str(uuid4())\n\n        labeled_samples = [sample for sample in builder.samples if sample.labeled]\n        total = len(labeled_samples)\n\n        if total == 0:\n            return wrap_response(\n                {\n                    \"task_id\": task_id,\n                    \"message\": \"No labeled samples to preprocess\",\n                    \"total\": 0,\n                }\n            )\n\n        with train_api_models._preprocess_lock:\n            train_api_models._preprocess_tasks[task_id] = train_api_models.PreprocessTask(\n                task_id=task_id,\n                status=\"running\",\n                progress=\"Starting preprocessing...\",\n                current=0,\n                total=total,\n                created_at=time.time(),\n            )\n            train_api_models._preprocess_latest_task_id = task_id\n\n        def run_preprocessing() -> None:\n            mgr = RuntimeComponentManager(handler=handler, llm=app.state.llm_handler, app_state=app.state)\n\n            try:\n                preprocess_notes = []\n                mgr.offload_decoder_to_cpu()\n                mgr.unload_llm()\n\n                def progress_callback(msg: str):\n                    with train_api_models._preprocess_lock:\n                        task = train_api_models._preprocess_tasks.get(task_id)\n                        if task:\n                            import re\n\n                            match = re.match(r\"Preprocessing (\\d+)/(\\d+)\", msg)\n                            if match:\n                                task.current = int(match.group(1))\n                                task.progress = msg\n\n                output_paths, status = builder.preprocess_to_tensors(\n                    dit_handler=handler,\n                    output_dir=request.output_dir.strip(),\n                    skip_existing=request.skip_existing,\n                    progress_callback=progress_callback,\n                )\n\n                if mgr.llm_unloaded:\n                    status += \"\\nℹ️ LLM was temporarily unloaded during preprocessing and restored afterward.\"\n                if mgr.decoder_moved:\n                    status += \"\\nℹ️ Decoder was temporarily offloaded during preprocessing and restored afterward.\"\n                if preprocess_notes:\n                    status += \"\\n\" + \"\\n\".join(preprocess_notes)\n\n                with train_api_models._preprocess_lock:\n                    task = train_api_models._preprocess_tasks.get(task_id)\n                    if task:\n                        task.status = \"completed\"\n                        task.progress = status\n                        task.current = task.total\n                        task.result = {\n                            \"message\": status,\n                            \"output_dir\": request.output_dir,\n                            \"num_tensors\": len(output_paths),\n                        }\n            except Exception as exc:\n                with train_api_models._preprocess_lock:\n                    task = train_api_models._preprocess_tasks.get(task_id)\n                    if task:\n                        task.status = \"failed\"\n                        task.error = str(exc)\n                        task.progress = f\"Failed: {exc}\"\n            finally:\n                mgr.restore()\n\n        import threading\n\n        thread = threading.Thread(target=run_preprocessing, daemon=True)\n        thread.start()\n\n        return wrap_response(\n            {\n                \"task_id\": task_id,\n                \"message\": \"Preprocessing task started\",\n                \"total\": total,\n            }\n        )\n\n    @app.get(\"/v1/dataset/preprocess_status/{task_id}\")\n    async def get_preprocess_status(task_id: str, _: None = Depends(verify_api_key)):\n        \"\"\"Get preprocessing task status and progress.\"\"\"\n\n        with train_api_models._preprocess_lock:\n            task = train_api_models._preprocess_tasks.get(task_id)\n            if not task:\n                raise HTTPException(status_code=404, detail=\"Task not found\")\n\n            response_data = {\n                \"task_id\": task.task_id,\n                \"status\": task.status,\n                \"progress\": task.progress,\n                \"current\": task.current,\n                \"total\": task.total,\n            }\n\n            if task.status == \"completed\" and task.result:\n                response_data[\"result\"] = task.result\n            elif task.status == \"failed\" and task.error:\n                response_data[\"error\"] = task.error\n\n            return wrap_response(response_data)\n"
  },
  {
    "path": "acestep/api/train_api_dataset_preprocess_routes_http_test.py",
    "content": "\"\"\"HTTP integration tests for dataset preprocess routes.\"\"\"\n\nfrom __future__ import annotations\n\nfrom types import SimpleNamespace\nfrom typing import Any, Dict, Optional\nimport unittest\n\nfrom fastapi import FastAPI, Header, HTTPException\nfrom fastapi.testclient import TestClient\n\nfrom acestep.api import train_api_models\nfrom acestep.api.train_api_dataset_preprocess_routes import register_training_dataset_preprocess_routes\n\n\ndef _wrap_response(data: Any, code: int = 200, error: Optional[str] = None) -> Dict[str, Any]:\n    \"\"\"Return API-compatible response envelope for tests.\"\"\"\n\n    return {\"data\": data, \"code\": code, \"error\": error}\n\n\nasync def _verify_api_key(authorization: str | None = Header(None)) -> None:\n    \"\"\"Require fixed bearer token for test requests.\"\"\"\n\n    if authorization != \"Bearer test-token\":\n        raise HTTPException(status_code=401, detail=\"Unauthorized\")\n\n\nclass _Sample:\n    \"\"\"Minimal sample test double for preprocess route logic.\"\"\"\n\n    def __init__(self, labeled: bool) -> None:\n        \"\"\"Store labeled marker consumed by preprocess route filtering.\"\"\"\n\n        self.labeled = labeled\n\n\nclass _Builder:\n    \"\"\"Dataset builder test double for preprocess route behavior.\"\"\"\n\n    def __init__(self, samples: list[_Sample]) -> None:\n        \"\"\"Initialize deterministic sample list.\"\"\"\n\n        self.samples = samples\n\n    def preprocess_to_tensors(self, **_kwargs: Any) -> tuple[list[str], str]:\n        \"\"\"Return deterministic preprocess success payload.\"\"\"\n\n        return [\"tensor-1.pt\"], \"✅ preprocessed\"\n\n\nclass TrainApiDatasetPreprocessRoutesHttpTests(unittest.TestCase):\n    \"\"\"HTTP tests covering extracted preprocess route behavior.\"\"\"\n\n    def setUp(self) -> None:\n        \"\"\"Reset preprocess task registries before each test.\"\"\"\n\n        with train_api_models._preprocess_lock:\n            train_api_models._preprocess_tasks.clear()\n            train_api_models._preprocess_latest_task_id = None\n\n    def tearDown(self) -> None:\n        \"\"\"Reset preprocess task registries after each test.\"\"\"\n\n        with train_api_models._preprocess_lock:\n            train_api_models._preprocess_tasks.clear()\n            train_api_models._preprocess_latest_task_id = None\n\n    def _build_client(self, samples: list[_Sample]) -> TestClient:\n        \"\"\"Create app/client pair with lightweight preprocess dependencies.\"\"\"\n\n        app = FastAPI()\n        app.state.dataset_builder = _Builder(samples=samples)\n        app.state.handler = SimpleNamespace(model=object())\n        app.state.llm_handler = SimpleNamespace(llm_initialized=True)\n        register_training_dataset_preprocess_routes(\n            app=app,\n            verify_api_key=_verify_api_key,\n            wrap_response=_wrap_response,\n        )\n        return TestClient(app)\n\n    def test_preprocess_async_returns_zero_total_when_no_labeled_samples(self) -> None:\n        \"\"\"POST /v1/dataset/preprocess_async should return zero total when no samples are labeled.\"\"\"\n\n        client = self._build_client(samples=[_Sample(labeled=False)])\n        response = client.post(\n            \"/v1/dataset/preprocess_async\",\n            json={\"output_dir\": \"out\"},\n            headers={\"Authorization\": \"Bearer test-token\"},\n        )\n\n        self.assertEqual(200, response.status_code)\n        payload = response.json()\n        self.assertEqual(200, payload[\"code\"])\n        self.assertEqual(0, payload[\"data\"][\"total\"])\n        self.assertEqual(\"No labeled samples to preprocess\", payload[\"data\"][\"message\"])\n\n    def test_preprocess_status_by_task_returns_wrapped_payload(self) -> None:\n        \"\"\"GET /v1/dataset/preprocess_status/{task_id} should return wrapped task payload.\"\"\"\n\n        with train_api_models._preprocess_lock:\n            train_api_models._preprocess_tasks[\"task-1\"] = train_api_models.PreprocessTask(\n                task_id=\"task-1\",\n                status=\"running\",\n                progress=\"working\",\n                current=1,\n                total=10,\n            )\n\n        client = self._build_client(samples=[_Sample(labeled=True)])\n        response = client.get(\n            \"/v1/dataset/preprocess_status/task-1\",\n            headers={\"Authorization\": \"Bearer test-token\"},\n        )\n        self.assertEqual(200, response.status_code)\n        payload = response.json()\n        self.assertEqual(200, payload[\"code\"])\n        self.assertEqual(\"task-1\", payload[\"data\"][\"task_id\"])\n        self.assertEqual(\"running\", payload[\"data\"][\"status\"])\n        self.assertEqual(1, payload[\"data\"][\"current\"])\n        self.assertEqual(10, payload[\"data\"][\"total\"])\n\n\nif __name__ == \"__main__\":\n    unittest.main()\n"
  },
  {
    "path": "acestep/api/train_api_dataset_sample_routes.py",
    "content": "\"\"\"Sample and dataset-save route registration for training dataset APIs.\"\"\"\n\nfrom __future__ import annotations\n\nfrom typing import Any, Callable, Dict, Optional\n\nfrom fastapi import Depends, FastAPI, HTTPException\n\nfrom acestep.api.train_api_dataset_models import SaveDatasetRequest, UpdateSampleRequest, _serialize_samples\n\n\ndef register_training_dataset_sample_routes(\n    app: FastAPI,\n    verify_api_key: Callable[..., Any],\n    wrap_response: Callable[[Any, int, Optional[str]], Dict[str, Any]],\n) -> None:\n    \"\"\"Register dataset save and sample CRUD routes used by training workflows.\"\"\"\n\n    @app.post(\"/v1/dataset/save\")\n    async def save_dataset(request: SaveDatasetRequest, _: None = Depends(verify_api_key)):\n        \"\"\"Save dataset to JSON file.\"\"\"\n\n        builder = app.state.dataset_builder\n        if builder is None:\n            raise HTTPException(status_code=400, detail=\"No dataset to save\")\n\n        try:\n            if request.custom_tag is not None:\n                builder.metadata.custom_tag = request.custom_tag\n            if request.tag_position is not None:\n                builder.metadata.tag_position = request.tag_position\n            if request.all_instrumental is not None:\n                builder.metadata.all_instrumental = request.all_instrumental\n            if request.genre_ratio is not None:\n                builder.metadata.genre_ratio = request.genre_ratio\n\n            status = builder.save_dataset(request.save_path.strip(), request.dataset_name)\n\n            if status.startswith(\"✅\"):\n                app.state.dataset_json_path = request.save_path.strip()\n\n            if status.startswith(\"✅\"):\n                return wrap_response({\"message\": status, \"save_path\": request.save_path})\n            return wrap_response(None, code=400, error=status)\n        except Exception as exc:\n            return wrap_response(None, code=500, error=f\"Save failed: {exc}\")\n\n    @app.get(\"/v1/dataset/samples\")\n    async def get_all_samples(_: None = Depends(verify_api_key)):\n        \"\"\"Get all samples in the current dataset.\"\"\"\n\n        builder = app.state.dataset_builder\n        if builder is None:\n            raise HTTPException(status_code=400, detail=\"No dataset loaded\")\n\n        return wrap_response(\n            {\n                \"dataset_name\": builder.metadata.name,\n                \"num_samples\": len(builder.samples),\n                \"labeled_count\": builder.get_labeled_count(),\n                \"samples\": _serialize_samples(builder),\n            }\n        )\n\n    @app.get(\"/v1/dataset/sample/{sample_idx}\")\n    async def get_sample(sample_idx: int, _: None = Depends(verify_api_key)):\n        \"\"\"Get a specific sample by index.\"\"\"\n\n        builder = app.state.dataset_builder\n        if builder is None:\n            raise HTTPException(status_code=400, detail=\"No dataset loaded\")\n\n        if sample_idx < 0 or sample_idx >= len(builder.samples):\n            raise HTTPException(status_code=404, detail=f\"Sample index {sample_idx} out of range\")\n\n        sample = builder.samples[sample_idx]\n        payload = sample.to_dict()\n        payload[\"index\"] = sample_idx\n        return wrap_response(payload)\n\n    @app.put(\"/v1/dataset/sample/{sample_idx}\")\n    async def update_sample(sample_idx: int, request: UpdateSampleRequest, _: None = Depends(verify_api_key)):\n        \"\"\"Update a sample's metadata.\"\"\"\n\n        builder = app.state.dataset_builder\n        if builder is None:\n            raise HTTPException(status_code=400, detail=\"No dataset loaded\")\n\n        try:\n            sample, status = builder.update_sample(\n                sample_idx,\n                caption=request.caption,\n                genre=request.genre,\n                prompt_override=request.prompt_override,\n                lyrics=request.lyrics if not request.is_instrumental else \"[Instrumental]\",\n                bpm=request.bpm,\n                keyscale=request.keyscale,\n                timesignature=request.timesignature,\n                language=\"unknown\" if request.is_instrumental else request.language,\n                is_instrumental=request.is_instrumental,\n                labeled=True,\n            )\n\n            if status.startswith(\"✅\"):\n                sample_payload = sample.to_dict()\n                sample_payload[\"index\"] = sample_idx\n                return wrap_response({\"message\": status, \"sample\": sample_payload})\n            return wrap_response(None, code=400, error=status)\n        except Exception as exc:\n            return wrap_response(None, code=500, error=f\"Update failed: {exc}\")\n"
  },
  {
    "path": "acestep/api/train_api_dataset_sample_routes_http_test.py",
    "content": "\"\"\"HTTP integration tests for dataset save/sample routes.\"\"\"\n\nfrom __future__ import annotations\n\nfrom typing import Any, Dict, Optional\nimport tempfile\nimport unittest\nfrom pathlib import Path\n\nfrom fastapi import FastAPI, Header, HTTPException\nfrom fastapi.testclient import TestClient\n\nfrom acestep.api.train_api_dataset_sample_routes import register_training_dataset_sample_routes\n\n\ndef _wrap_response(data: Any, code: int = 200, error: Optional[str] = None) -> Dict[str, Any]:\n    \"\"\"Return API-compatible response envelope for tests.\"\"\"\n\n    return {\"data\": data, \"code\": code, \"error\": error}\n\n\nasync def _verify_api_key(authorization: str | None = Header(None)) -> None:\n    \"\"\"Require fixed bearer token for test requests.\"\"\"\n\n    if authorization != \"Bearer test-token\":\n        raise HTTPException(status_code=401, detail=\"Unauthorized\")\n\n\nclass _Sample:\n    \"\"\"Sample test double for sample route payloads.\"\"\"\n\n    def __init__(self) -> None:\n        \"\"\"Initialize default sample fields.\"\"\"\n\n        self.filename = \"sample.wav\"\n        self.audio_path = str(Path(tempfile.gettempdir()) / \"sample.wav\")\n        self.duration = 10.0\n        self.caption = \"cap\"\n        self.genre = \"electronic\"\n        self.prompt_override = None\n        self.lyrics = \"[Instrumental]\"\n        self.bpm = 120\n        self.keyscale = \"C major\"\n        self.timesignature = \"4/4\"\n        self.language = \"unknown\"\n        self.is_instrumental = True\n        self.labeled = True\n\n    def to_dict(self) -> dict[str, Any]:\n        \"\"\"Return dictionary payload consumed by route handlers.\"\"\"\n\n        return {\n            \"filename\": self.filename,\n            \"audio_path\": self.audio_path,\n            \"duration\": self.duration,\n            \"caption\": self.caption,\n            \"genre\": self.genre,\n            \"prompt_override\": self.prompt_override,\n            \"lyrics\": self.lyrics,\n            \"bpm\": self.bpm,\n            \"keyscale\": self.keyscale,\n            \"timesignature\": self.timesignature,\n            \"language\": self.language,\n            \"is_instrumental\": self.is_instrumental,\n            \"labeled\": self.labeled,\n        }\n\n\nclass _Metadata:\n    \"\"\"Metadata test double used for dataset save/get operations.\"\"\"\n\n    def __init__(self) -> None:\n        \"\"\"Initialize mutable metadata values.\"\"\"\n\n        self.name = \"dataset\"\n        self.custom_tag = \"\"\n        self.tag_position = \"replace\"\n        self.all_instrumental = True\n        self.genre_ratio = 0\n\n\nclass _Builder:\n    \"\"\"Dataset builder test double for save/sample route behavior.\"\"\"\n\n    def __init__(self) -> None:\n        \"\"\"Initialize metadata and deterministic sample list.\"\"\"\n\n        self.metadata = _Metadata()\n        self.samples = [_Sample()]\n        self.saved_args: tuple[str, str] | None = None\n\n    def get_labeled_count(self) -> int:\n        \"\"\"Return deterministic labeled count.\"\"\"\n\n        return 1\n\n    def save_dataset(self, save_path: str, dataset_name: str) -> str:\n        \"\"\"Capture save args and return success status.\"\"\"\n\n        self.saved_args = (save_path, dataset_name)\n        return \"✅ saved\"\n\n    def update_sample(self, sample_idx: int, **_kwargs: Any) -> tuple[_Sample, str]:\n        \"\"\"Return selected sample with success status.\"\"\"\n\n        return self.samples[sample_idx], \"✅ updated\"\n\n\nclass TrainApiDatasetSampleRoutesHttpTests(unittest.TestCase):\n    \"\"\"HTTP tests covering extracted sample/save route behavior.\"\"\"\n\n    def _build_client(self) -> tuple[TestClient, _Builder]:\n        \"\"\"Create app/client pair with sample routes registered.\"\"\"\n\n        app = FastAPI()\n        builder = _Builder()\n        app.state.dataset_builder = builder\n        register_training_dataset_sample_routes(\n            app=app,\n            verify_api_key=_verify_api_key,\n            wrap_response=_wrap_response,\n        )\n        return TestClient(app), builder\n\n    def test_save_dataset_updates_path_on_success(self) -> None:\n        \"\"\"POST /v1/dataset/save should update app dataset path when save status is successful.\"\"\"\n\n        client, builder = self._build_client()\n        response = client.post(\n            \"/v1/dataset/save\",\n            json={\"save_path\": \"x.json\", \"dataset_name\": \"ds\"},\n            headers={\"Authorization\": \"Bearer test-token\"},\n        )\n\n        self.assertEqual(200, response.status_code)\n        payload = response.json()\n        self.assertEqual(200, payload[\"code\"])\n        self.assertEqual(\"✅ saved\", payload[\"data\"][\"message\"])\n        self.assertEqual((\"x.json\", \"ds\"), builder.saved_args)\n        self.assertEqual(\"x.json\", client.app.state.dataset_json_path)\n\n    def test_get_sample_returns_404_when_index_out_of_range(self) -> None:\n        \"\"\"GET /v1/dataset/sample/{sample_idx} should return 404 for out-of-range index.\"\"\"\n\n        client, _builder = self._build_client()\n        response = client.get(\n            \"/v1/dataset/sample/99\",\n            headers={\"Authorization\": \"Bearer test-token\"},\n        )\n        self.assertEqual(404, response.status_code)\n        self.assertIn(\"out of range\", response.json()[\"detail\"])\n\n\nif __name__ == \"__main__\":\n    unittest.main()\n"
  },
  {
    "path": "acestep/api/train_api_dataset_scan_load_routes.py",
    "content": "\"\"\"Scan/load dataset route registration for training APIs.\"\"\"\n\nfrom __future__ import annotations\n\nimport os\nfrom typing import Any, Callable, Dict, Optional\n\nfrom fastapi import Depends, FastAPI\n\nfrom acestep.api.train_api_dataset_models import LoadDatasetRequest, ScanDirectoryRequest, _serialize_samples\n\n\ndef register_training_dataset_scan_load_routes(\n    app: FastAPI,\n    verify_api_key: Callable[..., Any],\n    wrap_response: Callable[[Any, int, Optional[str]], Dict[str, Any]],\n) -> None:\n    \"\"\"Register dataset scan/load routes used by training workflows.\"\"\"\n\n    @app.post(\"/v1/dataset/scan\")\n    async def scan_dataset_directory(request: ScanDirectoryRequest, _: None = Depends(verify_api_key)):\n        \"\"\"Scan directory for audio files and create dataset.\"\"\"\n\n        from acestep.training.dataset_builder import DatasetBuilder\n\n        try:\n            builder = DatasetBuilder()\n            builder.metadata.name = request.dataset_name\n            builder.metadata.custom_tag = request.custom_tag\n            builder.metadata.tag_position = request.tag_position\n            builder.metadata.all_instrumental = request.all_instrumental\n\n            samples, status = builder.scan_directory(request.audio_dir.strip())\n\n            if not samples:\n                return wrap_response(None, code=400, error=status)\n\n            builder.set_all_instrumental(request.all_instrumental)\n            if request.custom_tag:\n                builder.set_custom_tag(request.custom_tag, request.tag_position)\n\n            app.state.dataset_builder = builder\n            app.state.dataset_json_path = os.path.join(request.audio_dir.strip(), f\"{builder.metadata.name}.json\")\n\n            return wrap_response(\n                {\n                    \"message\": status,\n                    \"num_samples\": len(samples),\n                    \"samples\": _serialize_samples(builder),\n                }\n            )\n        except Exception as exc:\n            return wrap_response(None, code=500, error=f\"Scan failed: {exc}\")\n\n    @app.post(\"/v1/dataset/load\")\n    async def load_dataset(request: LoadDatasetRequest, _: None = Depends(verify_api_key)):\n        \"\"\"Load existing dataset from JSON file.\"\"\"\n\n        from acestep.training.dataset_builder import DatasetBuilder\n\n        try:\n            builder = DatasetBuilder()\n            samples, status = builder.load_dataset(request.dataset_path.strip())\n\n            if not samples:\n                return wrap_response(\n                    {\n                        \"message\": status,\n                        \"dataset_name\": \"\",\n                        \"num_samples\": 0,\n                        \"labeled_count\": 0,\n                        \"samples\": [],\n                    },\n                    code=400,\n                    error=status,\n                )\n\n            app.state.dataset_builder = builder\n\n            return wrap_response(\n                {\n                    \"message\": status,\n                    \"dataset_name\": builder.metadata.name,\n                    \"num_samples\": len(samples),\n                    \"labeled_count\": builder.get_labeled_count(),\n                    \"samples\": _serialize_samples(builder),\n                }\n            )\n        except Exception as exc:\n            error_msg = f\"Load failed: {exc}\"\n            return wrap_response(\n                {\n                    \"message\": error_msg,\n                    \"dataset_name\": \"\",\n                    \"num_samples\": 0,\n                    \"labeled_count\": 0,\n                    \"samples\": [],\n                },\n                code=500,\n                error=error_msg,\n            )\n"
  },
  {
    "path": "acestep/api/train_api_dataset_scan_load_routes_http_test.py",
    "content": "\"\"\"HTTP integration tests for dataset scan/load route registration.\"\"\"\n\nfrom __future__ import annotations\n\nfrom typing import Any, Dict, Optional\nimport sys\nimport tempfile\nimport types\nimport unittest\nfrom unittest import mock\nfrom pathlib import Path\n\nfrom fastapi import FastAPI, Header, HTTPException\nfrom fastapi.testclient import TestClient\n\nfrom acestep.api.train_api_dataset_scan_load_routes import register_training_dataset_scan_load_routes\n\n\ndef _wrap_response(data: Any, code: int = 200, error: Optional[str] = None) -> Dict[str, Any]:\n    \"\"\"Return API-compatible response envelope for tests.\"\"\"\n\n    return {\"data\": data, \"code\": code, \"error\": error}\n\n\nasync def _verify_api_key(authorization: str | None = Header(None)) -> None:\n    \"\"\"Require fixed bearer token for test requests.\"\"\"\n\n    if authorization != \"Bearer test-token\":\n        raise HTTPException(status_code=401, detail=\"Unauthorized\")\n\n\nclass _Sample:\n    \"\"\"Sample test double used by serializer payload assertions.\"\"\"\n\n    def __init__(self, caption: str = \"cap\") -> None:\n        \"\"\"Initialize fields read by ``_serialize_samples``.\"\"\"\n\n        self.filename = \"sample.wav\"\n        self.audio_path = str(Path(tempfile.gettempdir()) / \"sample.wav\")\n        self.duration = 8.0\n        self.caption = caption\n        self.genre = \"electronic\"\n        self.prompt_override = None\n        self.lyrics = \"[Instrumental]\"\n        self.bpm = 120\n        self.keyscale = \"C major\"\n        self.timesignature = \"4/4\"\n        self.language = \"unknown\"\n        self.is_instrumental = True\n        self.labeled = True\n\n\nclass _Metadata:\n    \"\"\"Metadata test double used by fake dataset builders.\"\"\"\n\n    def __init__(self) -> None:\n        \"\"\"Initialize mutable metadata fields consumed by handlers.\"\"\"\n\n        self.name = \"default_name\"\n        self.custom_tag = \"\"\n        self.tag_position = \"replace\"\n        self.all_instrumental = True\n\n\nclass _ScanSuccessBuilder:\n    \"\"\"Fake DatasetBuilder for scan success flow.\"\"\"\n\n    def __init__(self) -> None:\n        \"\"\"Initialize fake metadata and deterministic sample list.\"\"\"\n\n        self.metadata = _Metadata()\n        self.samples = [_Sample()]\n        self.set_all_instrumental_calls: list[bool] = []\n        self.set_custom_tag_calls: list[tuple[str, str]] = []\n\n    def scan_directory(self, _audio_dir: str) -> tuple[list[_Sample], str]:\n        \"\"\"Return a successful scan result.\"\"\"\n\n        return self.samples, \"scan-ok\"\n\n    def set_all_instrumental(self, value: bool) -> None:\n        \"\"\"Capture set-all-instrumental call arguments.\"\"\"\n\n        self.set_all_instrumental_calls.append(value)\n\n    def set_custom_tag(self, tag: str, position: str) -> None:\n        \"\"\"Capture custom-tag call arguments.\"\"\"\n\n        self.set_custom_tag_calls.append((tag, position))\n\n\nclass _LoadEmptyBuilder:\n    \"\"\"Fake DatasetBuilder for load failure flow.\"\"\"\n\n    def __init__(self) -> None:\n        \"\"\"Initialize fake metadata and empty sample list.\"\"\"\n\n        self.metadata = _Metadata()\n        self.samples = []\n\n    def load_dataset(self, _dataset_path: str) -> tuple[list[_Sample], str]:\n        \"\"\"Return empty samples with a status message.\"\"\"\n\n        return [], \"no-samples\"\n\n    def get_labeled_count(self) -> int:\n        \"\"\"Return zero labeled samples for completeness.\"\"\"\n\n        return 0\n\n\nclass TrainApiDatasetScanLoadRoutesHttpTests(unittest.TestCase):\n    \"\"\"HTTP tests covering extracted scan/load route behavior.\"\"\"\n\n    def _build_client(self) -> TestClient:\n        \"\"\"Create app/client pair with scan/load routes only.\"\"\"\n\n        app = FastAPI()\n        register_training_dataset_scan_load_routes(\n            app=app,\n            verify_api_key=_verify_api_key,\n            wrap_response=_wrap_response,\n        )\n        return TestClient(app)\n\n    def test_scan_dataset_success_sets_state_and_returns_serialized_samples(self) -> None:\n        \"\"\"POST /v1/dataset/scan should keep state updates and wrapped sample payload behavior.\"\"\"\n\n        client = self._build_client()\n        fake_module = types.SimpleNamespace(DatasetBuilder=_ScanSuccessBuilder)\n\n        with mock.patch.dict(sys.modules, {\"acestep.training.dataset_builder\": fake_module}):\n            response = client.post(\n                \"/v1/dataset/scan\",\n                json={\n                    \"audio_dir\": \"dataset_dir\",\n                    \"dataset_name\": \"test_dataset\",\n                    \"custom_tag\": \"tag-1\",\n                    \"tag_position\": \"append\",\n                    \"all_instrumental\": False,\n                },\n                headers={\"Authorization\": \"Bearer test-token\"},\n            )\n\n        self.assertEqual(200, response.status_code)\n        payload = response.json()\n        self.assertEqual(200, payload[\"code\"])\n        self.assertEqual(\"scan-ok\", payload[\"data\"][\"message\"])\n        self.assertEqual(1, payload[\"data\"][\"num_samples\"])\n        self.assertEqual(\"sample.wav\", payload[\"data\"][\"samples\"][0][\"filename\"])\n        self.assertEqual(\"dataset_dir/test_dataset.json\", client.app.state.dataset_json_path.replace(\"\\\\\", \"/\"))\n\n        builder = client.app.state.dataset_builder\n        self.assertIsInstance(builder, _ScanSuccessBuilder)\n        self.assertEqual([False], builder.set_all_instrumental_calls)\n        self.assertEqual([(\"tag-1\", \"append\")], builder.set_custom_tag_calls)\n\n    def test_load_dataset_empty_returns_wrapped_400_payload(self) -> None:\n        \"\"\"POST /v1/dataset/load should keep wrapped error payload when load returns no samples.\"\"\"\n\n        client = self._build_client()\n        fake_module = types.SimpleNamespace(DatasetBuilder=_LoadEmptyBuilder)\n\n        with mock.patch.dict(sys.modules, {\"acestep.training.dataset_builder\": fake_module}):\n            response = client.post(\n                \"/v1/dataset/load\",\n                json={\"dataset_path\": \"missing.json\"},\n                headers={\"Authorization\": \"Bearer test-token\"},\n            )\n\n        self.assertEqual(200, response.status_code)\n        payload = response.json()\n        self.assertEqual(400, payload[\"code\"])\n        self.assertEqual(\"no-samples\", payload[\"error\"])\n        self.assertEqual(0, payload[\"data\"][\"num_samples\"])\n\n    def test_scan_dataset_requires_auth(self) -> None:\n        \"\"\"POST /v1/dataset/scan should return 401 when auth token is missing.\"\"\"\n\n        client = self._build_client()\n        response = client.post(\"/v1/dataset/scan\", json={\"audio_dir\": \"dataset_dir\"})\n        self.assertEqual(401, response.status_code)\n\n\nif __name__ == \"__main__\":\n    unittest.main()\n"
  },
  {
    "path": "acestep/api/train_api_dataset_service.py",
    "content": "\"\"\"Dataset-route registration facade for training APIs.\"\"\"\n\nfrom __future__ import annotations\n\nfrom typing import Any, Callable, Dict, Optional\n\nfrom fastapi import FastAPI\n\nfrom acestep.api.train_api_dataset_auto_label_routes import register_training_dataset_auto_label_routes\nfrom acestep.api.train_api_dataset_preprocess_routes import register_training_dataset_preprocess_routes\nfrom acestep.api.train_api_dataset_sample_routes import register_training_dataset_sample_routes\nfrom acestep.api.train_api_dataset_scan_load_routes import register_training_dataset_scan_load_routes\nfrom acestep.api.train_api_dataset_status_routes import register_training_dataset_status_routes\nfrom acestep.llm_inference import LLMHandler\n\n\ndef register_training_dataset_routes(\n    app: FastAPI,\n    verify_api_key: Callable[..., Any],\n    wrap_response: Callable[[Any, int, Optional[str]], Dict[str, Any]],\n    temporary_llm_model: Callable[[FastAPI, LLMHandler, Optional[str]], Any],\n    atomic_write_json: Callable[[str, Dict[str, Any]], None],\n    append_jsonl: Callable[[str, Dict[str, Any]], None],\n) -> None:\n    \"\"\"Register all dataset-related training routes via focused route modules.\"\"\"\n\n    register_training_dataset_scan_load_routes(\n        app=app,\n        verify_api_key=verify_api_key,\n        wrap_response=wrap_response,\n    )\n    register_training_dataset_auto_label_routes(\n        app=app,\n        verify_api_key=verify_api_key,\n        wrap_response=wrap_response,\n        temporary_llm_model=temporary_llm_model,\n        atomic_write_json=atomic_write_json,\n        append_jsonl=append_jsonl,\n    )\n    register_training_dataset_status_routes(\n        app=app,\n        verify_api_key=verify_api_key,\n        wrap_response=wrap_response,\n    )\n    register_training_dataset_preprocess_routes(\n        app=app,\n        verify_api_key=verify_api_key,\n        wrap_response=wrap_response,\n    )\n    register_training_dataset_sample_routes(\n        app=app,\n        verify_api_key=verify_api_key,\n        wrap_response=wrap_response,\n    )\n\n"
  },
  {
    "path": "acestep/api/train_api_dataset_service_http_test.py",
    "content": "\"\"\"HTTP integration tests for dataset route registration behavior.\"\"\"\n\nfrom __future__ import annotations\n\nfrom contextlib import contextmanager\nfrom types import SimpleNamespace\nfrom typing import Any, Dict, Optional\nimport tempfile\nimport unittest\nfrom unittest import mock\nfrom pathlib import Path\n\nfrom fastapi import FastAPI, Header, HTTPException\nfrom fastapi.testclient import TestClient\n\nfrom acestep.api.train_api_dataset_service import register_training_dataset_routes\n\n\ndef _wrap_response(data: Any, code: int = 200, error: Optional[str] = None) -> Dict[str, Any]:\n    \"\"\"Return API-compatible response envelope for tests.\"\"\"\n\n    return {\"data\": data, \"code\": code, \"error\": error}\n\n\nasync def _verify_api_key(authorization: str | None = Header(None)) -> None:\n    \"\"\"Require fixed bearer token for test requests.\"\"\"\n\n    if authorization != \"Bearer test-token\":\n        raise HTTPException(status_code=401, detail=\"Unauthorized\")\n\n\n@contextmanager\ndef _temporary_llm_model(_app: FastAPI, _llm: Any, _lm_model_path: Optional[str]):\n    \"\"\"No-op context manager used by dataset routes during tests.\"\"\"\n\n    yield\n\n\nclass _Sample:\n    \"\"\"Sample test double with ``to_dict`` payload support.\"\"\"\n\n    def __init__(self, caption: str = \"\") -> None:\n        \"\"\"Initialize sample fields consumed by dataset route handlers.\"\"\"\n\n        self.filename = \"sample.wav\"\n        self.audio_path = str(Path(tempfile.gettempdir()) / \"sample.wav\")\n        self.duration = 10.0\n        self.caption = caption\n        self.genre = \"electronic\"\n        self.prompt_override = None\n        self.lyrics = \"[Instrumental]\"\n        self.bpm = 120\n        self.keyscale = \"C major\"\n        self.timesignature = \"4/4\"\n        self.language = \"unknown\"\n        self.is_instrumental = True\n        self.labeled = bool(caption)\n\n    def to_dict(self) -> dict[str, Any]:\n        \"\"\"Return stable dictionary representation used by route persistence logic.\"\"\"\n\n        return {\n            \"filename\": self.filename,\n            \"audio_path\": self.audio_path,\n            \"duration\": self.duration,\n            \"caption\": self.caption,\n            \"genre\": self.genre,\n            \"prompt_override\": self.prompt_override,\n            \"lyrics\": self.lyrics,\n            \"bpm\": self.bpm,\n            \"keyscale\": self.keyscale,\n            \"timesignature\": self.timesignature,\n            \"language\": self.language,\n            \"is_instrumental\": self.is_instrumental,\n            \"labeled\": self.labeled,\n        }\n\n\nclass _Metadata:\n    \"\"\"Metadata test double expected by dataset builder routes.\"\"\"\n\n    def __init__(self) -> None:\n        \"\"\"Initialize mutable metadata fields used by route code.\"\"\"\n\n        self.name = \"my_dataset\"\n        self.custom_tag = \"\"\n        self.tag_position = \"replace\"\n        self.all_instrumental = True\n        self.genre_ratio = 0\n\n    def to_dict(self) -> dict[str, Any]:\n        \"\"\"Return dictionary payload used for save checkpoints.\"\"\"\n\n        return {\n            \"name\": self.name,\n            \"custom_tag\": self.custom_tag,\n            \"tag_position\": self.tag_position,\n            \"all_instrumental\": self.all_instrumental,\n            \"genre_ratio\": self.genre_ratio,\n        }\n\n\nclass _Builder:\n    \"\"\"Dataset builder test double backing route behavior.\"\"\"\n\n    def __init__(self) -> None:\n        \"\"\"Initialize deterministic sample data and call-capture hooks.\"\"\"\n\n        self.metadata = _Metadata()\n        self.samples = [_Sample(caption=\"already set\"), _Sample(caption=\"\")]\n        self.last_label_call: dict[str, Any] | None = None\n\n    def get_labeled_count(self) -> int:\n        \"\"\"Return deterministic labeled count.\"\"\"\n\n        return 1\n\n    def label_all_samples(self, **kwargs: Any) -> tuple[list[Any], str]:\n        \"\"\"Capture label invocation arguments and return success status.\"\"\"\n\n        self.last_label_call = kwargs\n        return self.samples, \"ok\"\n\n\nclass _RuntimeComponentManager:\n    \"\"\"No-op runtime manager replacement for route tests.\"\"\"\n\n    def __init__(self, handler: Any, llm: Any, app_state: Any) -> None:\n        \"\"\"Store passed runtime references.\"\"\"\n\n        self.handler = handler\n        self.llm = llm\n        self.app_state = app_state\n        self.decoder_moved = False\n        self.llm_unloaded = False\n\n    def offload_decoder_to_cpu(self) -> None:\n        \"\"\"No-op in tests.\"\"\"\n\n    def unload_llm(self) -> None:\n        \"\"\"No-op in tests.\"\"\"\n\n    def restore(self) -> None:\n        \"\"\"No-op in tests.\"\"\"\n\n\nclass TrainApiDatasetServiceHttpTests(unittest.TestCase):\n    \"\"\"HTTP tests covering extracted dataset-route dependencies.\"\"\"\n\n    def _build_client(self) -> tuple[TestClient, _Builder]:\n        \"\"\"Create app/client pair with lightweight dataset state.\"\"\"\n\n        app = FastAPI()\n        builder = _Builder()\n        app.state.dataset_builder = builder\n        app.state.dataset_json_path = \"dataset.json\"\n        app.state.handler = SimpleNamespace(model=object())\n        app.state.llm_handler = SimpleNamespace(llm_initialized=True)\n\n        register_training_dataset_routes(\n            app=app,\n            verify_api_key=_verify_api_key,\n            wrap_response=_wrap_response,\n            temporary_llm_model=_temporary_llm_model,\n            atomic_write_json=lambda _path, _payload: None,\n            append_jsonl=lambda _path, _record: None,\n        )\n        return TestClient(app), builder\n\n    @mock.patch(\n        \"acestep.api.train_api_dataset_auto_label_sync_route.RuntimeComponentManager\",\n        new=_RuntimeComponentManager,\n    )\n    def test_auto_label_accepts_legacy_alias_fields(self) -> None:\n        \"\"\"POST /v1/dataset/auto_label should map legacy alias keys to current request fields.\"\"\"\n\n        client, builder = self._build_client()\n        response = client.post(\n            \"/v1/dataset/auto_label\",\n            json={\"hunk_size\": 7, \"batchsize\": 3, \"only_unlabeled\": False},\n            headers={\"Authorization\": \"Bearer test-token\"},\n        )\n\n        self.assertEqual(200, response.status_code)\n        self.assertIsNotNone(builder.last_label_call)\n        self.assertEqual(7, builder.last_label_call[\"chunk_size\"])\n        self.assertEqual(3, builder.last_label_call[\"batch_size\"])\n\n    def test_get_samples_returns_wrapped_serialized_payload(self) -> None:\n        \"\"\"GET /v1/dataset/samples should return serialized sample data in wrapped response.\"\"\"\n\n        client, _builder = self._build_client()\n        response = client.get(\"/v1/dataset/samples\", headers={\"Authorization\": \"Bearer test-token\"})\n\n        self.assertEqual(200, response.status_code)\n        payload = response.json()\n        self.assertEqual(200, payload[\"code\"])\n        self.assertIsNone(payload[\"error\"])\n        self.assertEqual(2, payload[\"data\"][\"num_samples\"])\n        self.assertEqual(0, payload[\"data\"][\"samples\"][0][\"index\"])\n        self.assertEqual(\"sample.wav\", payload[\"data\"][\"samples\"][0][\"filename\"])\n\n\nif __name__ == \"__main__\":\n    unittest.main()\n"
  },
  {
    "path": "acestep/api/train_api_dataset_status_routes.py",
    "content": "\"\"\"Latest-status route registration for training dataset APIs.\"\"\"\n\nfrom __future__ import annotations\n\nfrom typing import Any, Callable, Dict, Optional\n\nfrom fastapi import Depends, FastAPI\n\nfrom acestep.api import train_api_models\n\n\ndef register_training_dataset_status_routes(\n    app: FastAPI,\n    verify_api_key: Callable[..., Any],\n    wrap_response: Callable[[Any, int, Optional[str]], Dict[str, Any]],\n) -> None:\n    \"\"\"Register latest-status routes for auto-label and preprocess workflows.\"\"\"\n\n    @app.get(\"/v1/dataset/preprocess_status\")\n    async def get_preprocess_status_latest(_: None = Depends(verify_api_key)):\n        \"\"\"Get latest preprocess task status.\"\"\"\n\n        with train_api_models._preprocess_lock:\n            latest_task_id = train_api_models._preprocess_latest_task_id\n            if latest_task_id is None:\n                return wrap_response(\n                    {\n                        \"task_id\": None,\n                        \"status\": \"idle\",\n                        \"progress\": \"\",\n                        \"current\": 0,\n                        \"total\": 0,\n                    }\n                )\n\n            task = train_api_models._preprocess_tasks.get(latest_task_id)\n            if task is None:\n                return wrap_response(\n                    {\n                        \"task_id\": latest_task_id,\n                        \"status\": \"idle\",\n                        \"progress\": \"\",\n                        \"current\": 0,\n                        \"total\": 0,\n                    }\n                )\n\n            response_data = {\n                \"task_id\": task.task_id,\n                \"status\": task.status,\n                \"progress\": task.progress,\n                \"current\": task.current,\n                \"total\": task.total,\n            }\n\n            if task.status == \"completed\" and task.result:\n                response_data[\"result\"] = task.result\n            elif task.status == \"failed\" and task.error:\n                response_data[\"error\"] = task.error\n            return wrap_response(response_data)\n\n    @app.get(\"/v1/dataset/auto_label_status\")\n    async def get_auto_label_status_latest(_: None = Depends(verify_api_key)):\n        \"\"\"Get latest auto-label task status.\"\"\"\n\n        with train_api_models._auto_label_lock:\n            latest_task_id = train_api_models._auto_label_latest_task_id\n            if latest_task_id is None:\n                return wrap_response(\n                    {\n                        \"task_id\": None,\n                        \"status\": \"idle\",\n                        \"progress\": \"\",\n                        \"current\": 0,\n                        \"total\": 0,\n                    }\n                )\n            task = train_api_models._auto_label_tasks.get(latest_task_id)\n            if task is None:\n                return wrap_response(\n                    {\n                        \"task_id\": latest_task_id,\n                        \"status\": \"idle\",\n                        \"progress\": \"\",\n                        \"current\": 0,\n                        \"total\": 0,\n                    }\n                )\n\n            response_data = {\n                \"task_id\": task.task_id,\n                \"status\": task.status,\n                \"progress\": task.progress,\n                \"current\": task.current,\n                \"total\": task.total,\n                \"save_path\": task.save_path,\n                \"last_updated_index\": task.last_updated_index,\n                \"last_updated_sample\": task.last_updated_sample,\n            }\n            if task.status == \"completed\" and task.result:\n                response_data[\"result\"] = task.result\n            elif task.status == \"failed\" and task.error:\n                response_data[\"error\"] = task.error\n            return wrap_response(response_data)\n"
  },
  {
    "path": "acestep/api/train_api_dataset_status_routes_http_test.py",
    "content": "\"\"\"HTTP integration tests for latest-status dataset routes.\"\"\"\n\nfrom __future__ import annotations\n\nfrom typing import Any, Dict, Optional\nimport time\nimport unittest\n\nfrom fastapi import FastAPI, Header, HTTPException\nfrom fastapi.testclient import TestClient\n\nfrom acestep.api import train_api_models\nfrom acestep.api.train_api_dataset_status_routes import register_training_dataset_status_routes\n\n\ndef _wrap_response(data: Any, code: int = 200, error: Optional[str] = None) -> Dict[str, Any]:\n    \"\"\"Return API-compatible response envelope for tests.\"\"\"\n\n    return {\"data\": data, \"code\": code, \"error\": error}\n\n\nasync def _verify_api_key(authorization: str | None = Header(None)) -> None:\n    \"\"\"Require fixed bearer token for test requests.\"\"\"\n\n    if authorization != \"Bearer test-token\":\n        raise HTTPException(status_code=401, detail=\"Unauthorized\")\n\n\nclass TrainApiDatasetStatusRoutesHttpTests(unittest.TestCase):\n    \"\"\"HTTP tests covering latest-status route behavior.\"\"\"\n\n    def setUp(self) -> None:\n        \"\"\"Reset global preprocess/auto-label task registries before each test.\"\"\"\n\n        with train_api_models._auto_label_lock:\n            train_api_models._auto_label_tasks.clear()\n            train_api_models._auto_label_latest_task_id = None\n        with train_api_models._preprocess_lock:\n            train_api_models._preprocess_tasks.clear()\n            train_api_models._preprocess_latest_task_id = None\n\n    def tearDown(self) -> None:\n        \"\"\"Reset global preprocess/auto-label task registries after each test.\"\"\"\n\n        with train_api_models._auto_label_lock:\n            train_api_models._auto_label_tasks.clear()\n            train_api_models._auto_label_latest_task_id = None\n        with train_api_models._preprocess_lock:\n            train_api_models._preprocess_tasks.clear()\n            train_api_models._preprocess_latest_task_id = None\n\n    def _build_client(self) -> TestClient:\n        \"\"\"Create app/client pair with status routes registered.\"\"\"\n\n        app = FastAPI()\n        register_training_dataset_status_routes(\n            app=app,\n            verify_api_key=_verify_api_key,\n            wrap_response=_wrap_response,\n        )\n        return TestClient(app)\n\n    def test_preprocess_status_latest_returns_idle_when_no_task(self) -> None:\n        \"\"\"GET /v1/dataset/preprocess_status should return wrapped idle payload when no task exists.\"\"\"\n\n        client = self._build_client()\n        response = client.get(\"/v1/dataset/preprocess_status\", headers={\"Authorization\": \"Bearer test-token\"})\n        self.assertEqual(200, response.status_code)\n        payload = response.json()\n        self.assertEqual(200, payload[\"code\"])\n        self.assertEqual(\"idle\", payload[\"data\"][\"status\"])\n        self.assertIsNone(payload[\"data\"][\"task_id\"])\n\n    def test_auto_label_status_latest_returns_task_payload(self) -> None:\n        \"\"\"GET /v1/dataset/auto_label_status should return wrapped latest-task payload.\"\"\"\n\n        with train_api_models._auto_label_lock:\n            train_api_models._auto_label_tasks[\"task-1\"] = train_api_models.AutoLabelTask(\n                task_id=\"task-1\",\n                status=\"running\",\n                progress=\"working\",\n                current=1,\n                total=5,\n                save_path=\"dataset.json\",\n                created_at=time.time(),\n                updated_at=time.time(),\n            )\n            train_api_models._auto_label_latest_task_id = \"task-1\"\n\n        client = self._build_client()\n        response = client.get(\"/v1/dataset/auto_label_status\", headers={\"Authorization\": \"Bearer test-token\"})\n        self.assertEqual(200, response.status_code)\n        payload = response.json()\n        self.assertEqual(200, payload[\"code\"])\n        self.assertEqual(\"task-1\", payload[\"data\"][\"task_id\"])\n        self.assertEqual(\"running\", payload[\"data\"][\"status\"])\n        self.assertEqual(1, payload[\"data\"][\"current\"])\n        self.assertEqual(5, payload[\"data\"][\"total\"])\n\n\nif __name__ == \"__main__\":\n    unittest.main()\n"
  },
  {
    "path": "acestep/api/train_api_lokr_start_route.py",
    "content": "\"\"\"LoKR training start route registration.\"\"\"\n\nfrom __future__ import annotations\n\nimport os\nimport re\nimport threading\nimport time\nfrom typing import Any, Callable, Dict, Optional\nfrom uuid import uuid4\n\nfrom fastapi import Depends, FastAPI, HTTPException\nfrom loguru import logger\n\nfrom acestep.api.train_api_models import StartLoKRTrainingRequest, initialize_training_state\nfrom acestep.api.train_api_runtime import RuntimeComponentManager, unwrap_module\nfrom acestep.handler import AceStepHandler\n\n\ndef register_lokr_training_start_route(\n    app: FastAPI,\n    verify_api_key: Callable[..., Any],\n    wrap_response: Callable[[Any, int, Optional[str]], Dict[str, Any]],\n    start_tensorboard: Callable[[FastAPI, str], Optional[str]],\n) -> None:\n    \"\"\"Register the `/v1/training/start_lokr` route.\"\"\"\n\n    @app.post(\"/v1/training/start_lokr\")\n    async def start_lokr_training(request: StartLoKRTrainingRequest, _: None = Depends(verify_api_key)):\n        \"\"\"Start LoKr training from preprocessed tensors.\"\"\"\n\n        initialize_training_state(app)\n        training_state = app.state.training_state\n        if training_state.get(\"is_training\", False):\n            raise HTTPException(status_code=400, detail=\"Training already in progress\")\n\n        handler: AceStepHandler = app.state.handler\n        if handler is None or handler.model is None:\n            raise HTTPException(status_code=500, detail=\"Model not initialized\")\n        if not hasattr(handler.model, \"decoder\") or handler.model.decoder is None:\n            raise HTTPException(\n                status_code=500,\n                detail=\"Decoder not found. Please reload the model via /v1/reinitialize before training.\",\n            )\n\n        handler.model.decoder = unwrap_module(handler.model.decoder)\n        mgr = RuntimeComponentManager(handler=handler, llm=app.state.llm_handler, app_state=app.state)\n        mgr.move_decoder_to(str(handler.device))\n        mgr.offload_vae_to_cpu()\n        mgr.offload_text_encoder_to_cpu()\n        mgr.offload_model_encoder_to_cpu()\n        mgr.unload_llm()\n\n        try:\n            from acestep.training.configs import LoKRConfig as LoKRConfigClass, TrainingConfig\n            from acestep.training.trainer import LoKRTrainer\n\n            factor = request.lokr_factor\n            if factor != -1:\n                factor = int(factor)\n                if factor == 0:\n                    factor = 1\n                factor = min(factor, 8)\n\n            lokr_config = LoKRConfigClass(\n                linear_dim=request.lokr_linear_dim,\n                linear_alpha=request.lokr_linear_alpha,\n                factor=factor,\n                decompose_both=request.lokr_decompose_both,\n                use_tucker=request.lokr_use_tucker,\n                use_scalar=request.lokr_use_scalar,\n                weight_decompose=request.lokr_weight_decompose,\n            )\n            training_config = TrainingConfig(\n                shift=request.training_shift,\n                learning_rate=request.learning_rate,\n                batch_size=request.train_batch_size,\n                gradient_accumulation_steps=request.gradient_accumulation,\n                max_epochs=request.train_epochs,\n                save_every_n_epochs=request.save_every_n_epochs,\n                seed=request.training_seed,\n                output_dir=request.output_dir,\n                gradient_checkpointing=request.gradient_checkpointing,\n            )\n            trainer = LoKRTrainer(dit_handler=handler, lokr_config=lokr_config, training_config=training_config)\n        except Exception as exc:\n            training_state[\"is_training\"] = False\n            mgr.restore()\n            return wrap_response(None, code=500, error=f\"Failed to start LoKR training: {exc}\")\n\n        tensorboard_logdir = os.path.join(request.output_dir, \"logs\")\n        os.makedirs(tensorboard_logdir, exist_ok=True)\n\n        run_id = str(uuid4())\n        training_state.update(\n            {\n                \"is_training\": True,\n                \"should_stop\": False,\n                \"run_id\": run_id,\n                \"trainer\": trainer,\n                \"tensor_dir\": request.tensor_dir,\n                \"tensorboard_logdir\": tensorboard_logdir,\n                \"current_step\": 0,\n                \"current_loss\": None,\n                \"status\": \"Starting...\",\n                \"loss_history\": [],\n                \"training_log\": \"Starting...\",\n                \"start_time\": time.time(),\n                \"current_epoch\": 0,\n                \"last_step_time\": time.time(),\n                \"steps_per_second\": 0.0,\n                \"estimated_time_remaining\": 0.0,\n                \"error\": None,\n                \"config\": {\n                    \"adapter_type\": \"lokr\",\n                    \"lokr_linear_dim\": request.lokr_linear_dim,\n                    \"lokr_linear_alpha\": request.lokr_linear_alpha,\n                    \"lokr_factor\": request.lokr_factor,\n                    \"lokr_decompose_both\": request.lokr_decompose_both,\n                    \"lokr_use_tucker\": request.lokr_use_tucker,\n                    \"lokr_use_scalar\": request.lokr_use_scalar,\n                    \"lokr_weight_decompose\": request.lokr_weight_decompose,\n                    \"learning_rate\": request.learning_rate,\n                    \"epochs\": request.train_epochs,\n                },\n                \"_component_manager\": mgr,\n            }\n        )\n        training_state[\"tensorboard_url\"] = start_tensorboard(app, tensorboard_logdir)\n\n        def _runner() -> None:\n            local_run_id = run_id\n            try:\n                for step, loss, status in trainer.train_from_preprocessed(request.tensor_dir, training_state):\n                    if training_state.get(\"run_id\") != local_run_id:\n                        break\n                    training_state[\"current_step\"] = step\n                    training_state[\"current_loss\"] = loss\n                    training_state[\"status\"] = status\n                    text = str(status)\n                    match = re.search(r\"Epoch (\\d+)/(\\d+)\", text)\n                    if match:\n                        training_state[\"current_epoch\"] = int(match.group(1))\n                    if loss is not None and loss == loss and step > 0:\n                        history = training_state.get(\"loss_history\", [])\n                        history.append({\"step\": step, \"loss\": float(loss)})\n                        training_state[\"loss_history\"] = history[-1000:]\n                    if training_state.get(\"should_stop\", False):\n                        break\n            except Exception as exc:\n                training_state[\"error\"] = str(exc)\n            finally:\n                training_state[\"is_training\"] = False\n                try:\n                    if handler.model is not None and getattr(handler.model, \"decoder\", None) is not None:\n                        handler.model.decoder = unwrap_module(handler.model.decoder)\n                        handler.model.decoder.eval()\n                except Exception:\n                    logger.exception(\"Failed to restore decoder wrapper state after LoKR training\")\n                cm = training_state.pop(\"_component_manager\", None)\n                if cm is not None:\n                    cm.restore()\n\n        threading.Thread(target=_runner, daemon=True).start()\n        return wrap_response(\n            {\n                \"message\": \"LoKR training started\",\n                \"tensor_dir\": request.tensor_dir,\n                \"output_dir\": request.output_dir,\n                \"config\": training_state[\"config\"],\n            }\n        )\n"
  },
  {
    "path": "acestep/api/train_api_lora_start_route.py",
    "content": "\"\"\"LoRA training start route registration.\"\"\"\n\nfrom __future__ import annotations\n\nimport os\nimport re\nimport threading\nimport time\nfrom typing import Any, Callable, Dict, Optional\nfrom uuid import uuid4\n\nfrom fastapi import Depends, FastAPI, HTTPException\nfrom loguru import logger\n\nfrom acestep.api.train_api_models import StartTrainingRequest, initialize_training_state\nfrom acestep.api.train_api_runtime import RuntimeComponentManager, unwrap_module\nfrom acestep.handler import AceStepHandler\n\n\ndef register_lora_training_start_route(\n    app: FastAPI,\n    verify_api_key: Callable[..., Any],\n    wrap_response: Callable[[Any, int, Optional[str]], Dict[str, Any]],\n    start_tensorboard: Callable[[FastAPI, str], Optional[str]],\n) -> None:\n    \"\"\"Register the `/v1/training/start` route.\"\"\"\n\n    @app.post(\"/v1/training/start\")\n    async def start_training(request: StartTrainingRequest, _: None = Depends(verify_api_key)):\n        \"\"\"Start LoRA training from preprocessed tensors.\"\"\"\n\n        initialize_training_state(app)\n        training_state = app.state.training_state\n        if training_state.get(\"is_training\", False):\n            raise HTTPException(status_code=400, detail=\"Training already in progress\")\n\n        handler: AceStepHandler = app.state.handler\n        if handler is None or handler.model is None:\n            raise HTTPException(status_code=500, detail=\"Model not initialized\")\n        if not hasattr(handler.model, \"decoder\") or handler.model.decoder is None:\n            raise HTTPException(\n                status_code=500,\n                detail=\"Decoder not found. Please reload the model via /v1/reinitialize before training.\",\n            )\n\n        handler.model.decoder = unwrap_module(handler.model.decoder)\n        mgr = RuntimeComponentManager(handler=handler, llm=app.state.llm_handler, app_state=app.state)\n        mgr.move_decoder_to(str(handler.device))\n        mgr.offload_vae_to_cpu()\n        mgr.offload_text_encoder_to_cpu()\n        mgr.offload_model_encoder_to_cpu()\n        mgr.unload_llm()\n\n        try:\n            from acestep.training.configs import LoRAConfig as LoRAConfigClass, TrainingConfig\n            from acestep.training.trainer import LoRATrainer\n\n            lora_config = LoRAConfigClass(r=request.lora_rank, alpha=request.lora_alpha, dropout=request.lora_dropout)\n            training_config = TrainingConfig(\n                shift=request.training_shift,\n                learning_rate=request.learning_rate,\n                batch_size=request.train_batch_size,\n                gradient_accumulation_steps=request.gradient_accumulation,\n                max_epochs=request.train_epochs,\n                save_every_n_epochs=request.save_every_n_epochs,\n                seed=request.training_seed,\n                output_dir=request.lora_output_dir,\n                use_fp8=request.use_fp8,\n                gradient_checkpointing=request.gradient_checkpointing,\n            )\n            trainer = LoRATrainer(dit_handler=handler, lora_config=lora_config, training_config=training_config)\n        except Exception as exc:\n            training_state[\"is_training\"] = False\n            mgr.restore()\n            return wrap_response(None, code=500, error=f\"Failed to start training: {exc}\")\n\n        tensorboard_logdir = os.path.join(request.lora_output_dir, \"logs\")\n        os.makedirs(tensorboard_logdir, exist_ok=True)\n\n        run_id = str(uuid4())\n        training_state.update(\n            {\n                \"is_training\": True,\n                \"should_stop\": False,\n                \"run_id\": run_id,\n                \"trainer\": trainer,\n                \"tensor_dir\": request.tensor_dir,\n                \"tensorboard_logdir\": tensorboard_logdir,\n                \"current_step\": 0,\n                \"current_loss\": None,\n                \"status\": \"Starting...\",\n                \"loss_history\": [],\n                \"training_log\": \"Starting...\",\n                \"start_time\": time.time(),\n                \"current_epoch\": 0,\n                \"last_step_time\": time.time(),\n                \"steps_per_second\": 0.0,\n                \"estimated_time_remaining\": 0.0,\n                \"error\": None,\n                \"config\": {\n                    \"lora_rank\": request.lora_rank,\n                    \"lora_alpha\": request.lora_alpha,\n                    \"learning_rate\": request.learning_rate,\n                    \"epochs\": request.train_epochs,\n                },\n                \"_component_manager\": mgr,\n            }\n        )\n        training_state[\"tensorboard_url\"] = start_tensorboard(app, tensorboard_logdir)\n\n        def _runner() -> None:\n            local_run_id = run_id\n            try:\n                for step, loss, status in trainer.train_from_preprocessed(request.tensor_dir, training_state):\n                    if training_state.get(\"run_id\") != local_run_id:\n                        break\n                    training_state[\"current_step\"] = step\n                    training_state[\"current_loss\"] = loss\n                    training_state[\"status\"] = status\n                    text = str(status)\n                    match = re.search(r\"Epoch (\\d+)/(\\d+)\", text)\n                    if match:\n                        training_state[\"current_epoch\"] = int(match.group(1))\n                    if loss is not None and loss == loss and step > 0:\n                        history = training_state.get(\"loss_history\", [])\n                        history.append({\"step\": step, \"loss\": float(loss)})\n                        training_state[\"loss_history\"] = history[-1000:]\n                    if training_state.get(\"should_stop\", False):\n                        break\n            except Exception as exc:\n                training_state[\"error\"] = str(exc)\n            finally:\n                training_state[\"is_training\"] = False\n                try:\n                    if handler.model is not None and getattr(handler.model, \"decoder\", None) is not None:\n                        handler.model.decoder = unwrap_module(handler.model.decoder)\n                        handler.model.decoder.eval()\n                except Exception:\n                    logger.exception(\"Failed to restore decoder wrapper state after training\")\n                cm = training_state.pop(\"_component_manager\", None)\n                if cm is not None:\n                    cm.restore()\n\n        threading.Thread(target=_runner, daemon=True).start()\n        return wrap_response(\n            {\n                \"message\": \"Training started\",\n                \"tensor_dir\": request.tensor_dir,\n                \"output_dir\": request.lora_output_dir,\n                \"config\": training_state[\"config\"],\n                \"fp8_enabled\": request.use_fp8,\n            }\n        )\n"
  },
  {
    "path": "acestep/api/train_api_models.py",
    "content": "\"\"\"Request models and shared state helpers for training APIs.\"\"\"\n\nfrom __future__ import annotations\n\nfrom dataclasses import dataclass\nfrom threading import Lock\nfrom typing import Any, Dict, Optional\n\nfrom fastapi import FastAPI\nfrom pydantic import BaseModel, Field\n\n\nclass StartTrainingRequest(BaseModel):\n    \"\"\"Request payload for starting LoRA training.\"\"\"\n\n    tensor_dir: str = Field(..., description=\"Directory with preprocessed tensors\")\n    lora_rank: int = Field(default=64, ge=1, le=256, description=\"LoRA rank\")\n    lora_alpha: int = Field(default=128, ge=1, le=512, description=\"LoRA alpha\")\n    lora_dropout: float = Field(default=0.1, ge=0.0, le=1.0, description=\"LoRA dropout\")\n    learning_rate: float = Field(default=1e-4, gt=0.0, description=\"Learning rate\")\n    train_epochs: int = Field(default=10, ge=1, description=\"Training epochs\")\n    train_batch_size: int = Field(default=1, ge=1, description=\"Batch size\")\n    gradient_accumulation: int = Field(default=4, ge=1, description=\"Gradient accumulation steps\")\n    save_every_n_epochs: int = Field(default=5, ge=1, description=\"Save checkpoint every N epochs\")\n    training_shift: float = Field(default=3.0, ge=0.0, description=\"Training timestep shift\")\n    training_seed: int = Field(default=42, description=\"Random seed\")\n    lora_output_dir: str = Field(default=\"./lora_output\", description=\"Output directory\")\n    use_fp8: bool = Field(default=False, description=\"Use FP8 training when runtime supports it\")\n    gradient_checkpointing: bool = Field(default=False, description=\"Trade compute speed for lower VRAM usage\")\n\n\nclass StartLoKRTrainingRequest(BaseModel):\n    \"\"\"Request payload for starting LoKr training.\"\"\"\n\n    tensor_dir: str = Field(..., description=\"Directory with preprocessed tensors\")\n    lokr_linear_dim: int = Field(default=64, ge=1, le=256, description=\"LoKR linear dimension\")\n    lokr_linear_alpha: int = Field(default=128, ge=1, le=512, description=\"LoKR linear alpha\")\n    lokr_factor: int = Field(default=-1, description=\"Kronecker factor (-1 = auto)\")\n    lokr_decompose_both: bool = Field(default=False, description=\"Decompose both matrices\")\n    lokr_use_tucker: bool = Field(default=False, description=\"Use Tucker decomposition\")\n    lokr_use_scalar: bool = Field(default=False, description=\"Use scalar calibration\")\n    lokr_weight_decompose: bool = Field(default=True, description=\"Enable DoRA mode\")\n    learning_rate: float = Field(default=0.03, gt=0.0, description=\"Learning rate\")\n    train_epochs: int = Field(default=500, ge=1, description=\"Training epochs\")\n    train_batch_size: int = Field(default=1, ge=1, description=\"Batch size\")\n    gradient_accumulation: int = Field(default=4, ge=1, description=\"Gradient accumulation steps\")\n    save_every_n_epochs: int = Field(default=5, ge=1, description=\"Save checkpoint every N epochs\")\n    training_shift: float = Field(default=3.0, ge=0.0, description=\"Training timestep shift\")\n    training_seed: int = Field(default=42, description=\"Random seed\")\n    output_dir: str = Field(default=\"./lokr_output\", description=\"Output directory\")\n    gradient_checkpointing: bool = Field(default=False, description=\"Trade compute speed for lower VRAM usage\")\n\n\nclass ExportLoRARequest(BaseModel):\n    \"\"\"Request payload for exporting trained adapters.\"\"\"\n\n    export_path: str = Field(..., description=\"Export destination path\")\n    lora_output_dir: str = Field(..., description=\"Training output directory\")\n\n\n@dataclass\nclass AutoLabelTask:\n    \"\"\"Runtime status snapshot for async auto-label tasks.\"\"\"\n\n    task_id: str\n    status: str\n    progress: str\n    current: int\n    total: int\n    save_path: Optional[str] = None\n    last_updated_index: Optional[int] = None\n    last_updated_sample: Optional[Dict[str, Any]] = None\n    result: Optional[Dict[str, Any]] = None\n    error: Optional[str] = None\n    created_at: float = 0.0\n    updated_at: float = 0.0\n\n\n@dataclass\nclass PreprocessTask:\n    \"\"\"Runtime status snapshot for async dataset preprocess tasks.\"\"\"\n\n    task_id: str\n    status: str\n    progress: str\n    current: int\n    total: int\n    result: Optional[Dict[str, Any]] = None\n    error: Optional[str] = None\n    created_at: float = 0.0\n\n\n_auto_label_lock = Lock()\n_auto_label_tasks: Dict[str, AutoLabelTask] = {}\n_auto_label_latest_task_id: Optional[str] = None\n\n_preprocess_lock = Lock()\n_preprocess_tasks: Dict[str, PreprocessTask] = {}\n_preprocess_latest_task_id: Optional[str] = None\n\n\ndef initialize_training_state(app: FastAPI) -> None:\n    \"\"\"Ensure app state has a stable ``training_state`` mapping.\"\"\"\n\n    state = getattr(app.state, \"training_state\", None)\n    if not isinstance(state, dict):\n        state = {}\n        app.state.training_state = state\n\n    defaults: dict[str, Any] = {\n        \"is_training\": False,\n        \"should_stop\": False,\n        \"run_id\": None,\n        \"trainer\": None,\n        \"tensor_dir\": \"\",\n        \"tensorboard_logdir\": None,\n        \"tensorboard_url\": None,\n        \"current_step\": 0,\n        \"current_loss\": None,\n        \"status\": \"Idle\",\n        \"loss_history\": [],\n        \"training_log\": \"\",\n        \"start_time\": None,\n        \"current_epoch\": 0,\n        \"last_step_time\": 0.0,\n        \"steps_per_second\": 0.0,\n        \"estimated_time_remaining\": 0.0,\n        \"error\": None,\n        \"config\": {},\n    }\n    for key, value in defaults.items():\n        if key not in state:\n            if isinstance(value, list):\n                state[key] = []\n            elif isinstance(value, dict):\n                state[key] = {}\n            else:\n                state[key] = value\n"
  },
  {
    "path": "acestep/api/train_api_runtime.py",
    "content": "\"\"\"Runtime helpers for training API temporary component management.\"\"\"\n\nfrom __future__ import annotations\n\nfrom typing import Any, Optional\n\nfrom loguru import logger\n\nfrom acestep.handler import AceStepHandler\nfrom acestep.llm_inference import LLMHandler\n\n\ndef unwrap_module(module: Any) -> Any:\n    \"\"\"Best-effort unwrap for common wrapper attributes used by training runtimes.\"\"\"\n\n    current = module\n    for _ in range(4):\n        if hasattr(current, \"_forward_module\"):\n            current = getattr(current, \"_forward_module\")\n            continue\n        if hasattr(current, \"module\"):\n            current = getattr(current, \"module\")\n            continue\n        break\n    return current\n\n\nclass RuntimeComponentManager:\n    \"\"\"Temporarily offload runtime components and restore them after a task.\"\"\"\n\n    def __init__(self, handler: AceStepHandler, llm: Optional[LLMHandler], app_state: Any) -> None:\n        \"\"\"Capture runtime handles used by offload/restore operations.\"\"\"\n\n        self.handler = handler\n        self.llm = llm\n        self.app_state = app_state\n\n        self.decoder_moved = False\n        self.llm_unloaded = False\n\n        self._decoder_prev_device: Optional[str] = None\n        self._decoder_prev_dtype: Any = None\n        self._vae_prev_device: Optional[str] = None\n        self._text_encoder_prev_device: Optional[str] = None\n        self._model_encoder_prev_device: Optional[str] = None\n\n    @staticmethod\n    def _device_of(module: Any) -> Optional[str]:\n        \"\"\"Return module device string when available.\"\"\"\n\n        if module is None:\n            return None\n        try:\n            first = next(module.parameters())\n            return str(first.device)\n        except Exception:\n            return None\n\n    @staticmethod\n    def _move_module(module: Any, device: str, dtype: Any = None) -> None:\n        \"\"\"Move a module to a target device/dtype when possible.\"\"\"\n\n        if module is None:\n            return\n        try:\n            if dtype is None:\n                module.to(device)\n            else:\n                module.to(device).to(dtype)\n        except Exception:\n            module.to(device)\n\n    def move_decoder_to(self, device: str) -> None:\n        \"\"\"Move decoder to target device for training.\"\"\"\n\n        decoder = getattr(getattr(self.handler, \"model\", None), \"decoder\", None)\n        if decoder is None:\n            return\n        current = self._device_of(decoder)\n        if current is not None:\n            self._decoder_prev_device = current\n            self._decoder_prev_dtype = getattr(self.handler, \"dtype\", None)\n        self._move_module(decoder, device, self._decoder_prev_dtype)\n\n    def offload_decoder_to_cpu(self) -> None:\n        \"\"\"Move decoder to CPU to free VRAM for non-decoder workloads.\"\"\"\n\n        decoder = getattr(getattr(self.handler, \"model\", None), \"decoder\", None)\n        if decoder is None:\n            return\n        current = self._device_of(decoder)\n        if current and not current.startswith(\"cpu\"):\n            self._decoder_prev_device = current\n            self._decoder_prev_dtype = getattr(self.handler, \"dtype\", None)\n            self._move_module(decoder, \"cpu\")\n            self.decoder_moved = True\n\n    def offload_vae_to_cpu(self) -> None:\n        \"\"\"Move VAE to CPU.\"\"\"\n\n        vae = getattr(self.handler, \"vae\", None)\n        self._vae_prev_device = self._device_of(vae)\n        if self._vae_prev_device and not self._vae_prev_device.startswith(\"cpu\"):\n            self._move_module(vae, \"cpu\")\n\n    def offload_text_encoder_to_cpu(self) -> None:\n        \"\"\"Move text encoder to CPU.\"\"\"\n\n        text_encoder = getattr(self.handler, \"text_encoder\", None)\n        self._text_encoder_prev_device = self._device_of(text_encoder)\n        if self._text_encoder_prev_device and not self._text_encoder_prev_device.startswith(\"cpu\"):\n            self._move_module(text_encoder, \"cpu\")\n\n    def offload_model_encoder_to_cpu(self) -> None:\n        \"\"\"Move DiT encoder branch to CPU when present.\"\"\"\n\n        model = getattr(self.handler, \"model\", None)\n        encoder = getattr(model, \"encoder\", None)\n        self._model_encoder_prev_device = self._device_of(encoder)\n        if self._model_encoder_prev_device and not self._model_encoder_prev_device.startswith(\"cpu\"):\n            self._move_module(encoder, \"cpu\")\n\n    def unload_llm(self) -> None:\n        \"\"\"Unload LLM to release VRAM and mark state flags.\"\"\"\n\n        if self.llm is None or not getattr(self.llm, \"llm_initialized\", False):\n            return\n        try:\n            self.llm.unload()\n            self.llm_unloaded = True\n            self.app_state._llm_initialized = False\n            self.app_state._llm_init_error = None\n        except Exception:\n            logger.exception(\"Failed to unload LLM for temporary offload\")\n\n    def restore(self) -> None:\n        \"\"\"Restore previously offloaded components back to their original state.\"\"\"\n\n        try:\n            decoder = getattr(getattr(self.handler, \"model\", None), \"decoder\", None)\n            if decoder is not None and self._decoder_prev_device:\n                self._move_module(decoder, self._decoder_prev_device, self._decoder_prev_dtype)\n                try:\n                    decoder.eval()\n                except Exception:\n                    pass\n        except Exception:\n            logger.exception(\"Failed to restore decoder\")\n\n        for module, prev in (\n            (getattr(self.handler, \"vae\", None), self._vae_prev_device),\n            (getattr(self.handler, \"text_encoder\", None), self._text_encoder_prev_device),\n            (getattr(getattr(self.handler, \"model\", None), \"encoder\", None), self._model_encoder_prev_device),\n        ):\n            if module is None or not prev:\n                continue\n            try:\n                self._move_module(module, prev)\n            except Exception:\n                logger.exception(\"Failed to restore module from temporary offload\")\n\n        if self.llm_unloaded and self.llm is not None:\n            params = getattr(self.llm, \"last_init_params\", None)\n            if isinstance(params, dict) and params:\n                try:\n                    status, ok = self.llm.initialize(**params)\n                    self.app_state._llm_initialized = bool(ok)\n                    self.app_state._llm_init_error = None if ok else status\n                except Exception as exc:\n                    self.app_state._llm_initialized = False\n                    self.app_state._llm_init_error = str(exc)\n\n        self.decoder_moved = False\n        self.llm_unloaded = False\n"
  },
  {
    "path": "acestep/api/train_api_service.py",
    "content": "\"\"\"Training API route registration facade.\"\"\"\n\nfrom __future__ import annotations\n\nimport json\nimport os\nimport shutil\nfrom typing import Any, Callable, Dict, Optional\n\nfrom fastapi import Depends, FastAPI, HTTPException\nfrom loguru import logger\n\nfrom acestep.api.train_api_dataset_service import register_training_dataset_routes\nfrom acestep.api.train_api_lokr_start_route import register_lokr_training_start_route\nfrom acestep.api.train_api_lora_start_route import register_lora_training_start_route\nfrom acestep.api.train_api_models import ExportLoRARequest, initialize_training_state\n\n\ndef register_training_api_routes(\n    app: FastAPI,\n    verify_api_key: Callable[..., Any],\n    wrap_response: Callable[[Any, int, Optional[str]], Dict[str, Any]],\n    start_tensorboard: Callable[[FastAPI, str], Optional[str]],\n    stop_tensorboard: Callable[[FastAPI], None],\n    temporary_llm_model: Callable[[FastAPI, Any, Optional[str]], Any],\n    atomic_write_json: Callable[[str, Dict[str, Any]], None],\n    append_jsonl: Callable[[str, Dict[str, Any]], None],\n) -> None:\n    \"\"\"Register all training-related endpoints onto ``app``.\"\"\"\n\n    register_lora_training_start_route(\n        app=app,\n        verify_api_key=verify_api_key,\n        wrap_response=wrap_response,\n        start_tensorboard=start_tensorboard,\n    )\n    register_lokr_training_start_route(\n        app=app,\n        verify_api_key=verify_api_key,\n        wrap_response=wrap_response,\n        start_tensorboard=start_tensorboard,\n    )\n    register_training_dataset_routes(\n        app=app,\n        verify_api_key=verify_api_key,\n        wrap_response=wrap_response,\n        temporary_llm_model=temporary_llm_model,\n        atomic_write_json=atomic_write_json,\n        append_jsonl=append_jsonl,\n    )\n\n    @app.post(\"/v1/training/stop\")\n    async def stop_training(_: None = Depends(verify_api_key)):\n        \"\"\"Stop the current training process.\"\"\"\n\n        initialize_training_state(app)\n        training_state = app.state.training_state\n        if training_state.get(\"is_training\", False):\n            training_state[\"should_stop\"] = True\n        try:\n            stop_tensorboard(app)\n        except Exception:\n            logger.exception(\"Failed to stop tensorboard process\")\n\n        training_state.update(\n            {\n                \"current_step\": 0,\n                \"current_loss\": None,\n                \"status\": \"Stopping...\",\n                \"loss_history\": [],\n                \"training_log\": \"\",\n                \"tensorboard_url\": None,\n                \"tensorboard_logdir\": None,\n                \"steps_per_second\": 0.0,\n                \"estimated_time_remaining\": 0.0,\n                \"error\": None,\n            }\n        )\n        if training_state.get(\"is_training\", False):\n            return wrap_response({\"message\": \"Stopping training...\"})\n        return wrap_response({\"message\": \"No training in progress\"})\n\n    @app.get(\"/v1/training/status\")\n    async def get_training_status(_: None = Depends(verify_api_key)):\n        \"\"\"Get current training status.\"\"\"\n\n        initialize_training_state(app)\n        ts = app.state.training_state\n        payload: Dict[str, Any] = {\n            \"is_training\": ts.get(\"is_training\", False),\n            \"should_stop\": ts.get(\"should_stop\", False),\n            \"current_step\": ts.get(\"current_step\", 0),\n            \"current_loss\": ts.get(\"current_loss\"),\n            \"status\": ts.get(\"status\", \"Idle\"),\n            \"config\": ts.get(\"config\", {}),\n            \"tensor_dir\": ts.get(\"tensor_dir\", \"\"),\n            \"loss_history\": ts.get(\"loss_history\", []),\n            \"tensorboard_url\": ts.get(\"tensorboard_url\"),\n            \"tensorboard_logdir\": ts.get(\"tensorboard_logdir\"),\n            \"training_log\": ts.get(\"training_log\", \"\"),\n            \"start_time\": ts.get(\"start_time\"),\n            \"current_epoch\": ts.get(\"current_epoch\", 0),\n            \"steps_per_second\": ts.get(\"steps_per_second\", 0.0),\n            \"estimated_time_remaining\": ts.get(\"estimated_time_remaining\", 0.0),\n            \"error\": ts.get(\"error\"),\n        }\n        return wrap_response(payload)\n\n    @app.post(\"/v1/training/load_tensor_info\")\n    async def load_tensor_info(request: dict, _: None = Depends(verify_api_key)):\n        \"\"\"Load preprocessed tensor dataset info from directory.\"\"\"\n\n        tensor_dir = str(request.get(\"tensor_dir\", \"\")).strip()\n        if not tensor_dir:\n            raise HTTPException(status_code=400, detail=\"Please enter a tensor directory path\")\n        if not os.path.exists(tensor_dir):\n            raise HTTPException(status_code=400, detail=f\"Directory not found: {tensor_dir}\")\n        if not os.path.isdir(tensor_dir):\n            raise HTTPException(status_code=400, detail=f\"Not a directory: {tensor_dir}\")\n\n        manifest_path = os.path.join(tensor_dir, \"manifest.json\")\n        if os.path.exists(manifest_path):\n            try:\n                with open(manifest_path, \"r\", encoding=\"utf-8\") as f:\n                    manifest = json.load(f)\n                metadata = manifest.get(\"metadata\", {}) or {}\n                num_samples = int(manifest.get(\"num_samples\", 0))\n                dataset_name = metadata.get(\"name\", \"Unknown\")\n                custom_tag = metadata.get(\"custom_tag\", \"\")\n                message = f\"✅ Loaded preprocessed dataset: {dataset_name}\\n📊 Samples: {num_samples} preprocessed tensors\"\n                if custom_tag:\n                    message += f\"\\n🏷️ Custom Tag: {custom_tag}\"\n                return wrap_response(\n                    {\n                        \"dataset_name\": dataset_name,\n                        \"num_samples\": num_samples,\n                        \"custom_tag\": custom_tag,\n                        \"tensor_dir\": tensor_dir,\n                        \"message\": message,\n                    }\n                )\n            except Exception:\n                logger.exception(\"Failed to parse tensor manifest, fallback to .pt scan\")\n\n        pt_files = [f for f in os.listdir(tensor_dir) if f.endswith(\".pt\")]\n        if not pt_files:\n            raise HTTPException(status_code=400, detail=f\"No .pt tensor files found in {tensor_dir}\")\n        return wrap_response(\n            {\n                \"dataset_name\": \"Unknown\",\n                \"num_samples\": len(pt_files),\n                \"custom_tag\": \"\",\n                \"tensor_dir\": tensor_dir,\n                \"message\": f\"✅ Found {len(pt_files)} tensor files in {tensor_dir}\\n⚠️ No manifest.json found - using all .pt files\",\n            }\n        )\n\n    @app.post(\"/v1/training/export\")\n    async def export_lora(request: ExportLoRARequest, _: None = Depends(verify_api_key)):\n        \"\"\"Export trained LoRA/LoKr weights.\"\"\"\n\n        final_dir = os.path.join(request.lora_output_dir, \"final\")\n        checkpoint_dir = os.path.join(request.lora_output_dir, \"checkpoints\")\n        if os.path.exists(final_dir):\n            source_path = final_dir\n        elif os.path.exists(checkpoint_dir):\n            checkpoints = [d for d in os.listdir(checkpoint_dir) if d.startswith(\"epoch_\")]\n            if not checkpoints:\n                raise HTTPException(status_code=404, detail=\"No checkpoints found\")\n            checkpoints.sort(key=lambda x: int(x.split(\"_\")[1]))\n            source_path = os.path.join(checkpoint_dir, checkpoints[-1])\n        else:\n            raise HTTPException(status_code=404, detail=f\"No trained model found in {request.lora_output_dir}\")\n\n        try:\n            export_path = request.export_path.strip()\n            os.makedirs(os.path.dirname(export_path) if os.path.dirname(export_path) else \".\", exist_ok=True)\n            if os.path.exists(export_path):\n                shutil.rmtree(export_path)\n            shutil.copytree(source_path, export_path)\n            return wrap_response({\"message\": \"LoRA exported successfully\", \"export_path\": export_path, \"source\": source_path})\n        except Exception as exc:\n            return wrap_response(None, code=500, error=f\"Export failed: {exc}\")\n"
  },
  {
    "path": "acestep/api/train_api_service_http_test.py",
    "content": "\"\"\"HTTP integration tests for training API route registration.\"\"\"\n\nfrom __future__ import annotations\n\nfrom contextlib import contextmanager\nfrom typing import Any, Dict, Optional\nimport unittest\nfrom unittest import mock\n\nfrom fastapi import FastAPI, Header, HTTPException\nfrom fastapi.testclient import TestClient\n\nfrom acestep.api.train_api_service import register_training_api_routes\n\n\ndef _wrap_response(data: Any, code: int = 200, error: Optional[str] = None) -> Dict[str, Any]:\n    \"\"\"Return API-compatible response envelope for tests.\"\"\"\n\n    return {\"data\": data, \"code\": code, \"error\": error}\n\n\nasync def _verify_api_key(authorization: str | None = Header(None)) -> None:\n    \"\"\"Require fixed bearer token for test requests.\"\"\"\n\n    if authorization != \"Bearer test-token\":\n        raise HTTPException(status_code=401, detail=\"Unauthorized\")\n\n\n@contextmanager\ndef _temporary_llm_model(_app: FastAPI, _llm: Any, _lm_model_path: Optional[str]):\n    \"\"\"No-op context manager used by dataset routes during registration.\"\"\"\n\n    yield\n\n\nclass TrainingApiServiceHttpTests(unittest.TestCase):\n    \"\"\"HTTP tests covering core training service routes.\"\"\"\n\n    def _build_client(self) -> tuple[TestClient, dict[str, int], FastAPI]:\n        \"\"\"Build app/client pair with deterministic route dependencies.\"\"\"\n\n        app = FastAPI()\n        calls = {\"stop_tensorboard\": 0}\n\n        def _start_tensorboard(_app: FastAPI, _logdir: str) -> Optional[str]:\n            \"\"\"Return fixed tensorboard URL.\"\"\"\n\n            return \"http://localhost:6006\"\n\n        def _stop_tensorboard(_app: FastAPI) -> None:\n            \"\"\"Record stop callback invocations.\"\"\"\n\n            calls[\"stop_tensorboard\"] += 1\n\n        register_training_api_routes(\n            app=app,\n            verify_api_key=_verify_api_key,\n            wrap_response=_wrap_response,\n            start_tensorboard=_start_tensorboard,\n            stop_tensorboard=_stop_tensorboard,\n            temporary_llm_model=_temporary_llm_model,\n            atomic_write_json=lambda _path, _payload: None,\n            append_jsonl=lambda _path, _record: None,\n        )\n        return TestClient(app), calls, app\n\n    def test_training_status_requires_auth(self):\n        \"\"\"GET /v1/training/status should return 401 when auth is missing.\"\"\"\n\n        client, _calls, _app = self._build_client()\n        response = client.get(\"/v1/training/status\")\n        self.assertEqual(401, response.status_code)\n\n    def test_training_status_returns_wrapped_payload(self):\n        \"\"\"GET /v1/training/status should return wrapped status payload when authorized.\"\"\"\n\n        client, _calls, _app = self._build_client()\n        response = client.get(\"/v1/training/status\", headers={\"Authorization\": \"Bearer test-token\"})\n        self.assertEqual(200, response.status_code)\n        payload = response.json()\n        self.assertEqual(200, payload[\"code\"])\n        self.assertIsNone(payload[\"error\"])\n        self.assertIn(\"is_training\", payload[\"data\"])\n        self.assertIn(\"status\", payload[\"data\"])\n\n    def test_training_stop_sets_should_stop_and_calls_tensorboard_stop(self):\n        \"\"\"POST /v1/training/stop should set stop flag and call stop callback when training.\"\"\"\n\n        client, calls, app = self._build_client()\n        app.state.training_state = {\n            \"is_training\": True,\n            \"should_stop\": False,\n            \"status\": \"Running\",\n        }\n        response = client.post(\"/v1/training/stop\", headers={\"Authorization\": \"Bearer test-token\"})\n        self.assertEqual(200, response.status_code)\n        payload = response.json()\n        self.assertEqual(200, payload[\"code\"])\n        self.assertEqual(\"Stopping training...\", payload[\"data\"][\"message\"])\n        self.assertEqual(1, calls[\"stop_tensorboard\"])\n        self.assertTrue(app.state.training_state[\"should_stop\"])\n\n    def test_training_stop_returns_idle_message_when_not_training(self):\n        \"\"\"POST /v1/training/stop should return idle message when no training is active.\"\"\"\n\n        client, calls, app = self._build_client()\n        app.state.training_state = {\n            \"is_training\": False,\n            \"should_stop\": False,\n            \"status\": \"Idle\",\n        }\n        response = client.post(\"/v1/training/stop\", headers={\"Authorization\": \"Bearer test-token\"})\n        self.assertEqual(200, response.status_code)\n        payload = response.json()\n        self.assertEqual(\"No training in progress\", payload[\"data\"][\"message\"])\n        self.assertEqual(1, calls[\"stop_tensorboard\"])\n\n    def test_load_tensor_info_returns_400_for_missing_dir(self):\n        \"\"\"POST /v1/training/load_tensor_info should return HTTP 400 for missing directory.\"\"\"\n\n        client, _calls, _app = self._build_client()\n        with mock.patch(\"acestep.api.train_api_service.os.path.exists\", return_value=False):\n            response = client.post(\n                \"/v1/training/load_tensor_info\",\n                json={\"tensor_dir\": \"missing-dir\"},\n                headers={\"Authorization\": \"Bearer test-token\"},\n            )\n\n        self.assertEqual(400, response.status_code)\n        self.assertIn(\"Directory not found\", response.json()[\"detail\"])\n\n\nif __name__ == \"__main__\":\n    unittest.main()\n"
  },
  {
    "path": "acestep/api/worker_runtime.py",
    "content": "\"\"\"Background worker task orchestration helpers for API server.\"\"\"\n\nfrom __future__ import annotations\n\nimport asyncio\nfrom concurrent.futures import ThreadPoolExecutor\nfrom typing import Any, Awaitable, Callable\n\nfrom acestep.api.jobs.worker_loops import process_queue_item, run_job_store_cleanup_loop\n\n\nasync def _queue_worker_loop(\n    *,\n    app_state: Any,\n    store: Any,\n    run_one_job: Callable[[str, Any], Awaitable[None]],\n    cleanup_job_temp_files: Callable[[str], Awaitable[None]],\n) -> None:\n    \"\"\"Continuously consume job queue entries and process each item.\"\"\"\n\n    while True:\n        job_id, req = await app_state.job_queue.get()\n        await process_queue_item(\n            job_id=job_id,\n            req=req,\n            app_state=app_state,\n            store=store,\n            run_one_job=run_one_job,\n            cleanup_job_temp_files=cleanup_job_temp_files,\n        )\n\n\nasync def _job_store_cleanup_worker_loop(*, store: Any, cleanup_interval_seconds: int) -> None:\n    \"\"\"Run periodic completed-job cleanup loop.\"\"\"\n\n    await run_job_store_cleanup_loop(\n        store=store,\n        cleanup_interval_seconds=cleanup_interval_seconds,\n    )\n\n\ndef start_worker_tasks(\n    *,\n    app_state: Any,\n    store: Any,\n    worker_count: int,\n    run_one_job: Callable[[str, Any], Awaitable[None]],\n    cleanup_job_temp_files: Callable[[str], Awaitable[None]],\n    cleanup_interval_seconds: int,\n) -> tuple[list[asyncio.Task], asyncio.Task]:\n    \"\"\"Start queue workers and cleanup worker; attach task refs to app state.\"\"\"\n\n    normalized_worker_count = max(1, worker_count)\n    workers = [\n        asyncio.create_task(\n            _queue_worker_loop(\n                app_state=app_state,\n                store=store,\n                run_one_job=run_one_job,\n                cleanup_job_temp_files=cleanup_job_temp_files,\n            )\n        )\n        for _ in range(normalized_worker_count)\n    ]\n    cleanup_task = asyncio.create_task(\n        _job_store_cleanup_worker_loop(\n            store=store,\n            cleanup_interval_seconds=cleanup_interval_seconds,\n        )\n    )\n    app_state.worker_tasks = workers\n    app_state.cleanup_task = cleanup_task\n    return workers, cleanup_task\n\n\ndef stop_worker_tasks(\n    *,\n    workers: list[asyncio.Task],\n    cleanup_task: asyncio.Task,\n    executor: ThreadPoolExecutor,\n) -> None:\n    \"\"\"Cancel running worker tasks and shut down thread pool executor.\"\"\"\n\n    cleanup_task.cancel()\n    for worker in workers:\n        worker.cancel()\n    executor.shutdown(wait=False, cancel_futures=True)\n"
  },
  {
    "path": "acestep/api/worker_runtime_test.py",
    "content": "\"\"\"Unit tests for background worker task orchestration helper.\"\"\"\n\nfrom __future__ import annotations\n\nimport asyncio\nimport unittest\nfrom concurrent.futures import ThreadPoolExecutor\nfrom types import SimpleNamespace\nfrom unittest.mock import AsyncMock, MagicMock, patch\n\nfrom acestep.api.worker_runtime import start_worker_tasks, stop_worker_tasks\n\n\nclass WorkerRuntimeTests(unittest.IsolatedAsyncioTestCase):\n    \"\"\"Behavior tests for queue worker startup and shutdown helpers.\"\"\"\n\n    @patch(\"acestep.api.worker_runtime.run_job_store_cleanup_loop\", new_callable=AsyncMock)\n    @patch(\"acestep.api.worker_runtime.process_queue_item\", new_callable=AsyncMock)\n    async def test_start_and_stop_worker_tasks_processes_queue_items(\n        self,\n        mock_process_queue_item: AsyncMock,\n        _mock_run_job_store_cleanup_loop: AsyncMock,\n    ) -> None:\n        \"\"\"Worker orchestration should start tasks, process queue items, and stop cleanly.\"\"\"\n\n        processed = asyncio.Event()\n\n        async def _process_queue_item_side_effect(**_kwargs) -> None:\n            processed.set()\n\n        mock_process_queue_item.side_effect = _process_queue_item_side_effect\n        app_state = SimpleNamespace(job_queue=asyncio.Queue())\n        store = MagicMock()\n        run_one_job = AsyncMock()\n        cleanup_job_temp_files = AsyncMock()\n\n        workers, cleanup_task = start_worker_tasks(\n            app_state=app_state,\n            store=store,\n            worker_count=0,\n            run_one_job=run_one_job,\n            cleanup_job_temp_files=cleanup_job_temp_files,\n            cleanup_interval_seconds=300,\n        )\n\n        self.assertEqual(1, len(workers))\n        await app_state.job_queue.put((\"job-1\", MagicMock()))\n        await asyncio.wait_for(processed.wait(), timeout=1.0)\n\n        executor = ThreadPoolExecutor(max_workers=1)\n        with patch.object(executor, \"shutdown\") as mock_shutdown:\n            stop_worker_tasks(\n                workers=workers,\n                cleanup_task=cleanup_task,\n                executor=executor,\n            )\n            mock_shutdown.assert_called_once_with(wait=False, cancel_futures=True)\n\n        await asyncio.gather(*workers, cleanup_task, return_exceptions=True)\n        self.assertGreaterEqual(mock_process_queue_item.await_count, 1)\n\n\nif __name__ == \"__main__\":\n    unittest.main()\n"
  },
  {
    "path": "acestep/api_server.py",
    "content": "\"\"\"FastAPI server for ACE-Step V1.5.\n\nEndpoints:\n- POST /release_task          Create music generation task\n- POST /query_result          Batch query task results\n- POST /create_random_sample  Generate random music parameters via LLM\n- POST /format_input          Format and enhance lyrics/caption via LLM\n- GET  /v1/models             List available models\n- GET  /v1/audio              Download audio file\n- GET  /health                Health check\n\nNOTE:\n- In-memory queue and job store -> run uvicorn with workers=1.\n\"\"\"\n\nfrom __future__ import annotations\n\nimport glob\nimport json\nimport os\nimport sys\nimport time\nimport urllib.parse\nfrom contextlib import asynccontextmanager\nfrom typing import Any, Dict, List, Optional\nfrom loguru import logger\n\ntry:\n    from dotenv import load_dotenv\nexcept ImportError:  # Optional dependency\n    load_dotenv = None  # type: ignore\n\nfrom fastapi import FastAPI\nfrom acestep.api.train_api_service import (\n    initialize_training_state,\n)\nfrom acestep.api.jobs.store import _JobStore\nfrom acestep.api.log_capture import install_log_capture\nfrom acestep.api.route_setup import configure_api_routes\nfrom acestep.api.server_cli import run_api_server_main\nfrom acestep.api.lifespan_runtime import initialize_lifespan_runtime\nfrom acestep.api.job_blocking_generation import run_blocking_generate\nfrom acestep.api.job_execution_runtime import run_one_job_runtime\nfrom acestep.api.job_model_selection import select_generation_handler\nfrom acestep.api.job_runtime_state import (\n    cleanup_job_temp_files as _cleanup_job_temp_files_state,\n    ensure_models_initialized as _ensure_models_initialized,\n    update_progress_job_cache as _update_progress_job_cache,\n    update_terminal_job_cache as _update_terminal_job_cache,\n)\nfrom acestep.api.startup_model_init import initialize_models_at_startup\nfrom acestep.api.worker_runtime import start_worker_tasks, stop_worker_tasks\nfrom acestep.api.server_utils import (\n    env_bool as _env_bool,\n    get_model_name as _get_model_name,\n    is_instrumental as _is_instrumental,\n    map_status as _map_status,\n    parse_description_hints as _parse_description_hints,\n    parse_timesteps as _parse_timesteps,\n)\nfrom acestep.api.http.auth import (\n    set_api_key,\n    verify_api_key,\n    verify_token_from_request,\n)\nfrom acestep.api.http.release_task_audio_paths import (\n    save_upload_to_temp as _save_upload_to_temp,\n    validate_audio_path as _validate_audio_path,\n)\nfrom acestep.api.http.release_task_models import GenerateMusicRequest\nfrom acestep.api.http.release_task_param_parser import (\n    RequestParser,\n    _to_float as _request_to_float,\n    _to_int as _request_to_int,\n)\nfrom acestep.api.runtime_helpers import (\n    append_jsonl as _runtime_append_jsonl,\n    atomic_write_json as _runtime_atomic_write_json,\n    start_tensorboard as _runtime_start_tensorboard,\n    stop_tensorboard as _runtime_stop_tensorboard,\n    temporary_llm_model as _runtime_temporary_llm_model,\n)\nfrom acestep.api.model_download import (\n    ensure_model_downloaded as _ensure_model_downloaded,\n)\n\nfrom acestep.handler import AceStepHandler\nfrom acestep.llm_inference import LLMHandler\nfrom acestep.constants import (\n    DEFAULT_DIT_INSTRUCTION,\n    TASK_INSTRUCTIONS,\n)\nfrom acestep.inference import (\n    generate_music,\n    create_sample,\n    format_sample,\n)\nfrom acestep.ui.gradio.events.results_handlers import _build_generation_info\n\ndef _get_project_root() -> str:\n    current_file = os.path.abspath(__file__)\n    return os.path.dirname(os.path.dirname(current_file))\n\n\n# =============================================================================\n# Constants\n# =============================================================================\n\nRESULT_KEY_PREFIX = \"ace_step_v1.5_\"\nRESULT_EXPIRE_SECONDS = 7 * 24 * 60 * 60  # 7 days\nTASK_TIMEOUT_SECONDS = 3600  # 1 hour\nJOB_STORE_CLEANUP_INTERVAL = 300  # 5 minutes - interval for cleaning up old jobs\nJOB_STORE_MAX_AGE_SECONDS = 86400  # 24 hours - completed jobs older than this will be cleaned\n\nLM_DEFAULT_TEMPERATURE = 0.85\nLM_DEFAULT_CFG_SCALE = 2.5\nLM_DEFAULT_TOP_P = 0.9\n\n\ndef _wrap_response(data: Any, code: int = 200, error: Optional[str] = None) -> Dict[str, Any]:\n    \"\"\"Wrap response data in standard format.\"\"\"\n    return {\n        \"data\": data,\n        \"code\": code,\n        \"error\": error,\n        \"timestamp\": int(time.time() * 1000),\n        \"extra\": None,\n    }\n\n\n# =============================================================================\n# Example Data for Random Sample\n# =============================================================================\n\nSIMPLE_MODE_EXAMPLES_DIR = os.path.join(_get_project_root(), \"examples\", \"simple_mode\")\nCUSTOM_MODE_EXAMPLES_DIR = os.path.join(_get_project_root(), \"examples\", \"text2music\")\n\n\ndef _load_all_examples(sample_mode: str = \"simple_mode\") -> List[Dict[str, Any]]:\n    \"\"\"Load all example data files from the examples directory.\"\"\"\n    examples = []\n    examples_dir = SIMPLE_MODE_EXAMPLES_DIR if sample_mode == \"simple_mode\" else CUSTOM_MODE_EXAMPLES_DIR\n    pattern = os.path.join(examples_dir, \"example_*.json\")\n\n    for filepath in glob.glob(pattern):\n        try:\n            with open(filepath, 'r', encoding='utf-8') as f:\n                data = json.load(f)\n                examples.append(data)\n        except Exception as e:\n            print(f\"[API Server] Failed to load example file {filepath}: {e}\")\n\n    return examples\n\n\n# Pre-load example data at module load time\nSIMPLE_EXAMPLE_DATA: List[Dict[str, Any]] = _load_all_examples(sample_mode=\"simple_mode\")\nCUSTOM_EXAMPLE_DATA: List[Dict[str, Any]] = _load_all_examples(sample_mode=\"custom_mode\")\n\n\n_project_env_loaded = False\n\n\ndef _load_project_env() -> None:\n    \"\"\"Load .env at most once per process to avoid epoch-boundary stalls (e.g. Windows LoRA training).\"\"\"\n    global _project_env_loaded\n    if _project_env_loaded or load_dotenv is None:\n        return\n    try:\n        project_root = _get_project_root()\n        env_path = os.path.join(project_root, \".env\")\n        if os.path.exists(env_path):\n            load_dotenv(env_path, override=False)\n        _project_env_loaded = True\n    except Exception:\n        # Optional best-effort: continue even if .env loading fails.\n        pass\n\n\n_load_project_env()\n\n\nlog_buffer, _stderr_proxy = install_log_capture(logger, sys.stderr)\nsys.stderr = _stderr_proxy\n\n\ndef create_app() -> FastAPI:\n    store = _JobStore()\n\n    # API Key authentication (from environment variable)\n    api_key = os.getenv(\"ACESTEP_API_KEY\", None)\n    set_api_key(api_key)\n\n    QUEUE_MAXSIZE = int(os.getenv(\"ACESTEP_QUEUE_MAXSIZE\", \"200\"))\n    WORKER_COUNT = int(os.getenv(\"ACESTEP_QUEUE_WORKERS\", \"1\"))  # Single GPU recommended\n\n    INITIAL_AVG_JOB_SECONDS = float(os.getenv(\"ACESTEP_AVG_JOB_SECONDS\", \"5.0\"))\n    AVG_WINDOW = int(os.getenv(\"ACESTEP_AVG_WINDOW\", \"50\"))\n\n    def _path_to_audio_url(path: str) -> str:\n        \"\"\"Convert local file path to downloadable relative URL\"\"\"\n        if not path:\n            return path\n        if path.startswith(\"http://\") or path.startswith(\"https://\"):\n            return path\n        encoded_path = urllib.parse.quote(path, safe=\"\")\n        return f\"/v1/audio?path={encoded_path}\"\n\n    @asynccontextmanager\n    async def lifespan(app: FastAPI):\n        runtime = initialize_lifespan_runtime(\n            app=app,\n            store=store,\n            queue_maxsize=QUEUE_MAXSIZE,\n            avg_window=AVG_WINDOW,\n            initial_avg_job_seconds=INITIAL_AVG_JOB_SECONDS,\n            get_project_root=_get_project_root,\n            initialize_training_state_fn=initialize_training_state,\n            ace_handler_cls=AceStepHandler,\n            llm_handler_cls=LLMHandler,\n        )\n        handler = runtime.handler\n        llm_handler = runtime.llm_handler\n        handler2 = runtime.handler2\n        handler3 = runtime.handler3\n        config_path2 = runtime.config_path2\n        config_path3 = runtime.config_path3\n        executor = runtime.executor\n\n        async def _run_one_job(job_id: str, req: GenerateMusicRequest) -> None:\n            llm: LLMHandler = app.state.llm_handler\n\n            def _build_blocking_result(\n                selected_handler: AceStepHandler,\n                selected_model_name: str,\n            ) -> Dict[str, Any]:\n                return run_blocking_generate(\n                    app_state=app.state,\n                    req=req,\n                    job_id=job_id,\n                    store=store,\n                    llm_handler=llm,\n                    selected_handler=selected_handler,\n                    selected_model_name=selected_model_name,\n                    map_status=_map_status,\n                    result_key_prefix=RESULT_KEY_PREFIX,\n                    result_expire_seconds=RESULT_EXPIRE_SECONDS,\n                    get_project_root=_get_project_root,\n                    get_model_name=_get_model_name,\n                    ensure_model_downloaded=_ensure_model_downloaded,\n                    env_bool=_env_bool,\n                    parse_description_hints=_parse_description_hints,\n                    parse_timesteps=_parse_timesteps,\n                    is_instrumental=_is_instrumental,\n                    create_sample_fn=create_sample,\n                    format_sample_fn=format_sample,\n                    generate_music_fn=generate_music,\n                    default_dit_instruction=DEFAULT_DIT_INSTRUCTION,\n                    task_instructions=TASK_INSTRUCTIONS,\n                    build_generation_info_fn=_build_generation_info,\n                    path_to_audio_url_fn=_path_to_audio_url,\n                    log_fn=print,\n                )\n\n            await run_one_job_runtime(\n                app_state=app.state,\n                store=store,\n                job_id=job_id,\n                req=req,\n                ensure_models_initialized_fn=_ensure_models_initialized,\n                select_generation_handler_fn=select_generation_handler,\n                get_model_name=_get_model_name,\n                build_blocking_result_fn=_build_blocking_result,\n                update_progress_job_cache_fn=_update_progress_job_cache,\n                update_terminal_job_cache_fn=_update_terminal_job_cache,\n                map_status=_map_status,\n                result_key_prefix=RESULT_KEY_PREFIX,\n                result_expire_seconds=RESULT_EXPIRE_SECONDS,\n                log_fn=print,\n            )\n\n        async def _cleanup_job_temp_files_for_job(job_id: str) -> None:\n            await _cleanup_job_temp_files_state(app.state, job_id)\n\n        workers, cleanup_task = start_worker_tasks(\n            app_state=app.state,\n            store=store,\n            worker_count=WORKER_COUNT,\n            run_one_job=_run_one_job,\n            cleanup_job_temp_files=_cleanup_job_temp_files_for_job,\n            cleanup_interval_seconds=JOB_STORE_CLEANUP_INTERVAL,\n        )\n        initialize_models_at_startup(\n            app=app,\n            handler=handler,\n            llm_handler=llm_handler,\n            handler2=handler2,\n            handler3=handler3,\n            config_path2=config_path2,\n            config_path3=config_path3,\n            get_project_root=_get_project_root,\n            get_model_name=_get_model_name,\n            ensure_model_downloaded=_ensure_model_downloaded,\n            env_bool=_env_bool,\n        )\n        try:\n            yield\n        finally:\n            stop_worker_tasks(\n                workers=workers,\n                cleanup_task=cleanup_task,\n                executor=executor,\n            )\n\n    app = FastAPI(title=\"ACE-Step API\", version=\"1.0\", lifespan=lifespan)\n\n    configure_api_routes(\n        app=app,\n        store=store,\n        queue_maxsize=QUEUE_MAXSIZE,\n        initial_avg_job_seconds=INITIAL_AVG_JOB_SECONDS,\n        verify_api_key=verify_api_key,\n        verify_token_from_request=verify_token_from_request,\n        wrap_response=_wrap_response,\n        get_project_root=_get_project_root,\n        get_model_name=_get_model_name,\n        ensure_model_downloaded=_ensure_model_downloaded,\n        env_bool=_env_bool,\n        simple_example_data=SIMPLE_EXAMPLE_DATA,\n        custom_example_data=CUSTOM_EXAMPLE_DATA,\n        format_sample=format_sample,\n        to_int=_request_to_int,\n        to_float=_request_to_float,\n        request_parser_cls=RequestParser,\n        request_model_cls=GenerateMusicRequest,\n        validate_audio_path=_validate_audio_path,\n        save_upload_to_temp=_save_upload_to_temp,\n        default_dit_instruction=DEFAULT_DIT_INSTRUCTION,\n        lm_default_temperature=LM_DEFAULT_TEMPERATURE,\n        lm_default_cfg_scale=LM_DEFAULT_CFG_SCALE,\n        lm_default_top_p=LM_DEFAULT_TOP_P,\n        map_status=_map_status,\n        result_key_prefix=RESULT_KEY_PREFIX,\n        task_timeout_seconds=TASK_TIMEOUT_SECONDS,\n        log_buffer=log_buffer,\n        runtime_start_tensorboard=_runtime_start_tensorboard,\n        runtime_stop_tensorboard=_runtime_stop_tensorboard,\n        runtime_temporary_llm_model=_runtime_temporary_llm_model,\n        runtime_atomic_write_json=_runtime_atomic_write_json,\n        runtime_append_jsonl=_runtime_append_jsonl,\n    )\n\n    return app\n\n\napp = create_app()\n\n\ndef main() -> None:\n    \"\"\"CLI entrypoint for API server startup.\"\"\"\n\n    run_api_server_main(env_bool=_env_bool)\n\nif __name__ == \"__main__\":\n    main()\n\n\n\n\n\n\n\n"
  },
  {
    "path": "acestep/audio_utils.py",
    "content": "\"\"\"\r\nAudio saving and transcoding utility module\r\n\r\nIndependent audio file operations outside of handler, supporting:\r\n- Save audio tensor/numpy to files (default FLAC format, fast)\r\n- Format conversion (FLAC/WAV/MP3)\r\n- Batch processing\r\n\"\"\"\r\n\r\n\r\nimport io\r\nimport json\r\nimport os\r\nimport subprocess\r\nimport hashlib\r\nfrom pathlib import Path\r\nfrom typing import Union, Optional, List, Tuple\r\nimport torch\r\nimport numpy as np\r\nimport torchaudio\r\nfrom loguru import logger\r\n\r\n\r\ndef apply_fade(\r\n    audio_data: Union[torch.Tensor, np.ndarray],\r\n    fade_in_samples: int = 0,\r\n    fade_out_samples: int = 0,\r\n) -> Union[torch.Tensor, np.ndarray]:\r\n    \"\"\"Apply linear fade in and/or fade out to audio data.\r\n\r\n    Args:\r\n        audio_data: Audio data as torch.Tensor [channels, samples] or numpy.ndarray.\r\n        fade_in_samples: Number of samples for fade in ramp (0 = no fade in).\r\n        fade_out_samples: Number of samples for fade out ramp (0 = no fade out).\r\n\r\n    Returns:\r\n        Audio data with fades applied, in the same format as input.\r\n    \"\"\"\r\n    if fade_in_samples <= 0 and fade_out_samples <= 0:\r\n        return audio_data\r\n\r\n    is_tensor = isinstance(audio_data, torch.Tensor)\r\n    if is_tensor:\r\n        audio = audio_data.clone()\r\n        total_samples = audio.shape[-1]\r\n    else:\r\n        audio = audio_data.copy()\r\n        total_samples = audio.shape[-1]\r\n\r\n    if fade_in_samples > 0:\r\n        actual_in = min(fade_in_samples, total_samples)\r\n        if is_tensor:\r\n            ramp = torch.linspace(0.0, 1.0, actual_in, dtype=audio.dtype, device=audio.device)\r\n            audio[..., :actual_in] = audio[..., :actual_in] * ramp\r\n        else:\r\n            ramp = np.linspace(0.0, 1.0, actual_in, dtype=np.float32)\r\n            audio[..., :actual_in] = audio[..., :actual_in] * ramp\r\n\r\n    if fade_out_samples > 0:\r\n        actual_out = min(fade_out_samples, total_samples)\r\n        if is_tensor:\r\n            ramp = torch.linspace(1.0, 0.0, actual_out, dtype=audio.dtype, device=audio.device)\r\n            audio[..., total_samples - actual_out:] = audio[..., total_samples - actual_out:] * ramp\r\n        else:\r\n            ramp = np.linspace(1.0, 0.0, actual_out, dtype=np.float32)\r\n            audio[..., total_samples - actual_out:] = audio[..., total_samples - actual_out:] * ramp\r\n\r\n    return audio\r\n\r\n\r\ndef normalize_audio(audio_data: Union[torch.Tensor, np.ndarray], target_db: float = -1.0) -> Union[torch.Tensor, np.ndarray]:\r\n    \"\"\"\r\n    Apply peak normalization to audio data.\r\n    \r\n    Args:\r\n        audio_data: Audio data as torch.Tensor or numpy.ndarray\r\n        target_db: Target peak level in dB (default: -1.0)\r\n        \r\n    Returns:\r\n        Normalized audio data in the same format as input\r\n    \"\"\"\r\n    # Create a copy to avoid modifying original in-place\r\n    if isinstance(audio_data, torch.Tensor):\r\n        audio = audio_data.clone()\r\n        is_tensor = True\r\n    else:\r\n        audio = audio_data.copy()\r\n        is_tensor = False\r\n        \r\n    # Calculate current peak\r\n    if is_tensor:\r\n        peak = torch.max(torch.abs(audio))\r\n    else:\r\n        peak = np.max(np.abs(audio))\r\n        \r\n    # Handle silence/near-silence to avoid division by zero or extreme gain\r\n    if peak < 1e-6:\r\n        return audio_data\r\n        \r\n    # Convert target dB to linear amplitude\r\n    target_amp = 10 ** (target_db / 20.0)\r\n    \r\n    # Calculate needed gain\r\n    gain = target_amp / peak\r\n    \r\n    # Apply gain\r\n    audio = audio * gain\r\n    \r\n    return audio\r\n\r\n\r\n\r\nclass AudioSaver:\r\n    \"\"\"Audio saving and transcoding utility class\"\"\"\r\n    \r\n    def __init__(self, default_format: str = \"flac\"):\r\n        \"\"\"\r\n        Initialize audio saver\r\n        \r\n        Args:\r\n            default_format: Default save format ('flac', 'wav', 'mp3', 'wav32', 'opus', 'aac')\r\n        \"\"\"\r\n        self.default_format = default_format.lower()\r\n        if self.default_format not in [\"flac\", \"wav\", \"mp3\", \"wav32\", \"opus\", \"aac\"]:\r\n            logger.warning(f\"Unsupported format {default_format}, using 'flac'\")\r\n            self.default_format = \"flac\"\r\n    \r\n    def save_audio(\r\n        self,\r\n        audio_data: Union[torch.Tensor, np.ndarray],\r\n        output_path: Union[str, Path],\r\n        sample_rate: int = 48000,\r\n        format: Optional[str] = None,\r\n        channels_first: bool = True,\r\n    ) -> str:\r\n        \"\"\"\r\n        Save audio data to file\r\n        \r\n        Args:\r\n            audio_data: Audio data, torch.Tensor [channels, samples] or numpy.ndarray\r\n            output_path: Output file path (extension can be omitted)\r\n            sample_rate: Sample rate\r\n            format: Audio format ('flac', 'wav', 'mp3', 'wav32', 'opus', 'aac'), defaults to default_format\r\n            channels_first: If True, tensor format is [channels, samples], else [samples, channels]\r\n        \r\n        Returns:\r\n            Actual saved file path\r\n        \"\"\"\r\n        format = (format or self.default_format).lower()\r\n        if format not in [\"flac\", \"wav\", \"mp3\", \"wav32\", \"opus\", \"aac\"]:\r\n            logger.warning(f\"Unsupported format {format}, using {self.default_format}\")\r\n            format = self.default_format\r\n        \r\n        # Ensure output path has correct extension\r\n        output_path = Path(output_path)\r\n        \r\n        # Determine extension based on format\r\n        ext = \".wav\" if format == \"wav32\" else f\".{format}\"\r\n        \r\n        if output_path.suffix.lower() not in ['.flac', '.wav', '.mp3', '.opus', '.aac', '.m4a']:\r\n            output_path = output_path.with_suffix(ext)\r\n        elif format == \"wav32\" and output_path.suffix.lower() == \".wav32\":\r\n             # Explicitly fix .wav32 extension if present\r\n             output_path = output_path.with_suffix(\".wav\")\r\n        elif format == \"aac\" and output_path.suffix.lower() == \".m4a\":\r\n             # Allow .m4a as valid extension for AAC (it's a container format for AAC)\r\n             pass\r\n        \r\n        # Convert to torch tensor\r\n        if isinstance(audio_data, np.ndarray):\r\n            if channels_first:\r\n                # numpy already [channels, samples]\r\n                audio_tensor = torch.from_numpy(audio_data).float()\r\n            else:\r\n                # numpy [samples, channels] -> tensor [samples, channels] -> [channels, samples] (if transposed)\r\n                audio_tensor = torch.from_numpy(audio_data).float()\r\n                if audio_tensor.dim() == 2 and audio_tensor.shape[0] > audio_tensor.shape[1]:\r\n                     # Assume [samples, channels] if dim0 > dim1 (heuristic)\r\n                     audio_tensor = audio_tensor.T\r\n        else:\r\n            # torch tensor\r\n            audio_tensor = audio_data.cpu().float()\r\n            if not channels_first and audio_tensor.dim() == 2:\r\n                # [samples, channels] -> [channels, samples]\r\n                if audio_tensor.shape[0] > audio_tensor.shape[1]:\r\n                    audio_tensor = audio_tensor.T\r\n        \r\n        # Ensure memory is contiguous\r\n        audio_tensor = audio_tensor.contiguous()\r\n        \r\n        # Select backend and save\r\n        try:\r\n            if format in [\"mp3\", \"opus\", \"aac\"]:\r\n                # MP3, Opus, and AAC use ffmpeg backend\r\n                torchaudio.save(\r\n                    str(output_path),\r\n                    audio_tensor,\r\n                    sample_rate,\r\n                    channels_first=True,\r\n                    backend='ffmpeg',\r\n                )\r\n            elif format in [\"flac\", \"wav\", \"wav32\"]:\r\n                # FLAC and WAV use soundfile backend (fastest)\r\n                # handle 32-bit float wav\r\n                if format == \"wav32\":\r\n                    try:\r\n                        import soundfile as sf\r\n                        \r\n                        # Use soundfile directly for 32-bit float\r\n                        audio_np = audio_tensor.transpose(0, 1).numpy() # [channels, samples] -> [samples, channels]\r\n                        \r\n                        # Explicitly specify format as WAV to avoid issues with extension detection or custom extensions\r\n                        sf.write(str(output_path), audio_np, sample_rate, subtype='FLOAT', format='WAV')\r\n                        logger.debug(f\"[AudioSaver] Saved audio to {output_path} (wav32, {sample_rate}Hz)\")\r\n                        return str(output_path)\r\n                    except Exception as e:\r\n                        logger.error(f\"Failed to save wav32: {e}, falling back to standard wav\")\r\n                        format = \"wav\"\r\n                        # Fallthrough to standard wav saving\r\n\r\n                torchaudio.save(\r\n                    str(output_path),\r\n                    audio_tensor,\r\n                    sample_rate,\r\n                    channels_first=True,\r\n                    backend='soundfile',\r\n                )\r\n            else:\r\n                # Other formats use default backend\r\n                torchaudio.save(\r\n                    str(output_path),\r\n                    audio_tensor,\r\n                    sample_rate,\r\n                    channels_first=True,\r\n                )\r\n            \r\n            logger.debug(f\"[AudioSaver] Saved audio to {output_path} ({format}, {sample_rate}Hz)\")\r\n            return str(output_path)\r\n            \r\n        except Exception as e:\r\n            try:\r\n                import soundfile as sf\r\n                audio_np = audio_tensor.transpose(0, 1).numpy()  # -> [samples, channels]\r\n                \r\n                # Handle wav32 fallback formatting\r\n                if format == \"wav32\":\r\n                    sf_format = \"WAV\"\r\n                    subtype = \"FLOAT\"\r\n                else:\r\n                    sf_format = format.upper()\r\n                    subtype = None\r\n                    \r\n                sf.write(str(output_path), audio_np, sample_rate, format=sf_format, subtype=subtype)\r\n                logger.debug(f\"[AudioSaver] Fallback soundfile Saved audio to {output_path} ({format}, {sample_rate}Hz)\")\r\n                return str(output_path)\r\n            except Exception as inner_e:\r\n                logger.error(f\"[AudioSaver] Failed to save audio: {e} -> Fallback failed: {inner_e}\")\r\n                raise\r\n    \r\n    def convert_audio(\r\n        self,\r\n        input_path: Union[str, Path],\r\n        output_path: Union[str, Path],\r\n        output_format: str,\r\n        remove_input: bool = False,\r\n    ) -> str:\r\n        \"\"\"\r\n        Convert audio format\r\n        \r\n        Args:\r\n            input_path: Input audio file path\r\n            output_path: Output audio file path\r\n            output_format: Target format ('flac', 'wav', 'mp3', 'wav32', 'opus', 'aac')\r\n            remove_input: Whether to delete input file\r\n        \r\n        Returns:\r\n            Output file path\r\n        \"\"\"\r\n        input_path = Path(input_path)\r\n        output_path = Path(output_path)\r\n        \r\n        if not input_path.exists():\r\n            raise FileNotFoundError(f\"Input file not found: {input_path}\")\r\n        \r\n        # Load audio\r\n        audio_tensor, sample_rate = torchaudio.load(str(input_path))\r\n        \r\n        # Save as new format\r\n        output_path = self.save_audio(\r\n            audio_tensor,\r\n            output_path,\r\n            sample_rate=sample_rate,\r\n            format=output_format,\r\n            channels_first=True\r\n        )\r\n        \r\n        # Delete input file if needed\r\n        if remove_input:\r\n            input_path.unlink()\r\n            logger.debug(f\"[AudioSaver] Removed input file: {input_path}\")\r\n        \r\n        return output_path\r\n    \r\n    def save_batch(\r\n        self,\r\n        audio_batch: Union[List[torch.Tensor], torch.Tensor],\r\n        output_dir: Union[str, Path],\r\n        file_prefix: str = \"audio\",\r\n        sample_rate: int = 48000,\r\n        format: Optional[str] = None,\r\n        channels_first: bool = True,\r\n    ) -> List[str]:\r\n        \"\"\"\r\n        Save audio batch\r\n        \r\n        Args:\r\n            audio_batch: Audio batch, List[tensor] or tensor [batch, channels, samples]\r\n            output_dir: Output directory\r\n            file_prefix: File prefix\r\n            sample_rate: Sample rate\r\n            format: Audio format\r\n            channels_first: Tensor format flag\r\n        \r\n        Returns:\r\n            List of saved file paths\r\n        \"\"\"\r\n        output_dir = Path(output_dir)\r\n        output_dir.mkdir(parents=True, exist_ok=True)\r\n        \r\n        # Process batch\r\n        if isinstance(audio_batch, torch.Tensor) and audio_batch.dim() == 3:\r\n            # [batch, channels, samples]\r\n            audio_list = [audio_batch[i] for i in range(audio_batch.shape[0])]\r\n        elif isinstance(audio_batch, list):\r\n            audio_list = audio_batch\r\n        else:\r\n            audio_list = [audio_batch]\r\n        \r\n        saved_paths = []\r\n        for i, audio in enumerate(audio_list):\r\n            output_path = output_dir / f\"{file_prefix}_{i:04d}\"\r\n            saved_path = self.save_audio(\r\n                audio,\r\n                output_path,\r\n                sample_rate=sample_rate,\r\n                format=format,\r\n                channels_first=channels_first\r\n            )\r\n            saved_paths.append(saved_path)\r\n        \r\n        return saved_paths\r\n\r\n\r\ndef get_lora_weights_hash(dit_handler) -> str:\r\n    \"\"\"Compute an MD5 hash identifying the currently loaded LoRA adapter weights.\r\n\r\n    Iterates over the handler's LoRA service registry to find adapter weight\r\n    file paths, then hashes each file to produce a combined fingerprint.\r\n\r\n    Args:\r\n        dit_handler: DiT handler instance with LoRA state attributes.\r\n\r\n    Returns:\r\n        Hex digest string uniquely identifying the loaded LoRA weights,\r\n        or empty string if no LoRA is active.\r\n    \"\"\"\r\n    if not getattr(dit_handler, \"lora_loaded\", False):\r\n        return \"\"\r\n    if not getattr(dit_handler, \"use_lora\", False):\r\n        return \"\"\r\n\r\n    lora_service = getattr(dit_handler, \"_lora_service\", None)\r\n    if lora_service is None or not lora_service.registry:\r\n        return \"\"\r\n\r\n    hash_obj = hashlib.sha256()\r\n    found_any = False\r\n\r\n    for adapter_name in sorted(lora_service.registry.keys()):\r\n        meta = lora_service.registry[adapter_name]\r\n        lora_path = meta.get(\"path\")\r\n        if not lora_path:\r\n            continue\r\n\r\n        # Try common weight file names at lora_path\r\n        candidates = []\r\n        if os.path.isfile(lora_path):\r\n            candidates.append(lora_path)\r\n        elif os.path.isdir(lora_path):\r\n            for fname in (\r\n                \"adapter_model.safetensors\",\r\n                \"adapter_model.bin\",\r\n                \"lokr_weights.safetensors\",\r\n            ):\r\n                fpath = os.path.join(lora_path, fname)\r\n                if os.path.isfile(fpath):\r\n                    candidates.append(fpath)\r\n\r\n        for fpath in candidates:\r\n            try:\r\n                with open(fpath, \"rb\") as f:\r\n                    while True:\r\n                        chunk = f.read(1 << 20)  # 1 MB chunks\r\n                        if not chunk:\r\n                            break\r\n                        hash_obj.update(chunk)\r\n                found_any = True\r\n            except OSError:\r\n                continue\r\n\r\n    return hash_obj.hexdigest() if found_any else \"\"\r\n\r\n\r\ndef get_audio_file_hash(audio_file) -> str:\r\n    \"\"\"\r\n    Get hash identifier for an audio file.\r\n    \r\n    Args:\r\n        audio_file: Path to audio file (str) or file-like object\r\n    \r\n    Returns:\r\n        Hash string or empty string\r\n    \"\"\"\r\n    if audio_file is None:\r\n        return \"\"\r\n    \r\n    try:\r\n        if isinstance(audio_file, str):\r\n            if os.path.exists(audio_file):\r\n                with open(audio_file, 'rb') as f:\r\n                    return hashlib.sha256(f.read()).hexdigest()\r\n            return hashlib.sha256(audio_file.encode('utf-8')).hexdigest()\r\n        elif hasattr(audio_file, 'name'):\r\n            return hashlib.sha256(str(audio_file.name).encode('utf-8')).hexdigest()\r\n        return hashlib.sha256(str(audio_file).encode('utf-8')).hexdigest()\r\n    except Exception:\r\n        return hashlib.sha256(str(audio_file).encode('utf-8')).hexdigest()\r\n\r\n\r\ndef generate_uuid_from_params(params_dict) -> str:\r\n    \"\"\"\r\n    Generate deterministic UUID from generation parameters.\r\n    Same parameters will always generate the same UUID.\r\n    \r\n    Args:\r\n        params_dict: Dictionary of parameters\r\n    \r\n    Returns:\r\n        UUID string\r\n    \"\"\"\r\n    \r\n    params_json = json.dumps(params_dict, sort_keys=True, ensure_ascii=False)\r\n    hash_obj = hashlib.sha256(params_json.encode('utf-8'))\r\n    hash_hex = hash_obj.hexdigest()\r\n    uuid_str = f\"{hash_hex[0:8]}-{hash_hex[8:12]}-{hash_hex[12:16]}-{hash_hex[16:20]}-{hash_hex[20:32]}\"\r\n    return uuid_str\r\n\r\n\r\ndef generate_uuid_from_audio_data(\r\n    audio_data: Union[torch.Tensor, np.ndarray],\r\n    seed: Optional[int] = None\r\n) -> str:\r\n    \"\"\"\r\n    Generate UUID from audio data (for caching/deduplication)\r\n    \r\n    Args:\r\n        audio_data: Audio data\r\n        seed: Optional seed value\r\n    \r\n    Returns:\r\n        UUID string\r\n    \"\"\"\r\n    if isinstance(audio_data, torch.Tensor):\r\n        # Convert to numpy and calculate hash\r\n        audio_np = audio_data.cpu().numpy()\r\n    else:\r\n        audio_np = audio_data\r\n    \r\n    # Calculate data hash\r\n    data_hash = hashlib.sha256(audio_np.tobytes()).hexdigest()\r\n    \r\n    if seed is not None:\r\n        combined = f\"{data_hash}_{seed}\"\r\n        return hashlib.sha256(combined.encode()).hexdigest()\r\n    \r\n    return data_hash\r\n\r\n\r\n# Global default instance\r\n_default_saver = AudioSaver(default_format=\"flac\")\r\n\r\n\r\ndef save_audio(\r\n    audio_data: Union[torch.Tensor, np.ndarray],\r\n    output_path: Union[str, Path],\r\n    sample_rate: int = 48000,\r\n    format: Optional[str] = None,\r\n    channels_first: bool = True,\r\n) -> str:\r\n    \"\"\"\r\n    Convenience function: save audio (using default configuration)\r\n    \r\n    Args:\r\n        audio_data: Audio data\r\n        output_path: Output path\r\n        sample_rate: Sample rate\r\n        format: Format (default flac)\r\n        channels_first: Tensor format flag\r\n    \r\n    Returns:\r\n        Saved file path\r\n    \"\"\"\r\n    return _default_saver.save_audio(\r\n        audio_data, output_path, sample_rate, format, channels_first\r\n    )\r\n\r\n"
  },
  {
    "path": "acestep/audio_utils_test.py",
    "content": "\"\"\"Unit tests for audio_utils module, focusing on format support.\"\"\"\n\nimport os\nimport tempfile\nimport unittest\nfrom pathlib import Path\nfrom unittest.mock import patch, MagicMock\n\nimport torch\nimport numpy as np\n\nfrom acestep.audio_utils import AudioSaver, apply_fade, save_audio\n\nclass AudioSaverFormatTests(unittest.TestCase):\n    \"\"\"Tests for AudioSaver format support, especially new Opus and AAC formats.\"\"\"\n\n    def setUp(self):\n        \"\"\"Set up temporary directory for test outputs.\"\"\"\n        self.temp_dir = tempfile.mkdtemp()\n        self.sample_audio = torch.randn(2, 48000)  # 2 channels, 1 second at 48kHz\n        self.sample_rate = 48000\n\n    def tearDown(self):\n        \"\"\"Clean up temporary directory.\"\"\"\n        import shutil\n        shutil.rmtree(self.temp_dir, ignore_errors=True)\n\n    def test_init_accepts_opus_format(self):\n        \"\"\"AudioSaver should accept 'opus' as a valid format.\"\"\"\n        saver = AudioSaver(default_format=\"opus\")\n        self.assertEqual(saver.default_format, \"opus\")\n\n    def test_init_accepts_aac_format(self):\n        \"\"\"AudioSaver should accept 'aac' as a valid format.\"\"\"\n        saver = AudioSaver(default_format=\"aac\")\n        self.assertEqual(saver.default_format, \"aac\")\n\n    def test_init_accepts_all_formats(self):\n        \"\"\"AudioSaver should accept all supported formats.\"\"\"\n        for fmt in [\"flac\", \"wav\", \"mp3\", \"wav32\", \"opus\", \"aac\"]:\n            saver = AudioSaver(default_format=fmt)\n            self.assertEqual(saver.default_format, fmt)\n\n    def test_init_rejects_invalid_format(self):\n        \"\"\"AudioSaver should reject invalid formats and fall back to 'flac'.\"\"\"\n        saver = AudioSaver(default_format=\"invalid\")\n        self.assertEqual(saver.default_format, \"flac\")\n\n    def test_save_audio_validates_opus_format(self):\n        \"\"\"save_audio should validate 'opus' as a valid format.\"\"\"\n        saver = AudioSaver()\n        output_path = Path(self.temp_dir) / \"test_opus\"\n        \n        # Mock torchaudio.save to avoid actual file writing\n        with patch('acestep.audio_utils.torchaudio.save') as mock_save:\n            result = saver.save_audio(\n                self.sample_audio,\n                output_path,\n                sample_rate=self.sample_rate,\n                format=\"opus\"\n            )\n            \n            # Verify torchaudio.save was called with ffmpeg backend\n            mock_save.assert_called_once()\n            call_kwargs = mock_save.call_args[1]\n            self.assertEqual(call_kwargs.get('backend'), 'ffmpeg')\n            self.assertTrue(result.endswith('.opus'))\n\n    def test_save_audio_validates_aac_format(self):\n        \"\"\"save_audio should validate 'aac' as a valid format.\"\"\"\n        saver = AudioSaver()\n        output_path = Path(self.temp_dir) / \"test_aac\"\n        \n        # Mock torchaudio.save to avoid actual file writing\n        with patch('acestep.audio_utils.torchaudio.save') as mock_save:\n            result = saver.save_audio(\n                self.sample_audio,\n                output_path,\n                sample_rate=self.sample_rate,\n                format=\"aac\"\n            )\n            \n            # Verify torchaudio.save was called with ffmpeg backend\n            mock_save.assert_called_once()\n            call_kwargs = mock_save.call_args[1]\n            self.assertEqual(call_kwargs.get('backend'), 'ffmpeg')\n            self.assertTrue(result.endswith('.aac'))\n\n    def test_save_audio_opus_uses_ffmpeg_backend(self):\n        \"\"\"Opus format should use ffmpeg backend like MP3.\"\"\"\n        saver = AudioSaver()\n        output_path = Path(self.temp_dir) / \"test.opus\"\n        \n        with patch('acestep.audio_utils.torchaudio.save') as mock_save:\n            saver.save_audio(\n                self.sample_audio,\n                output_path,\n                sample_rate=self.sample_rate,\n                format=\"opus\"\n            )\n            \n            # Check that ffmpeg backend was used\n            call_kwargs = mock_save.call_args[1]\n            self.assertEqual(call_kwargs['backend'], 'ffmpeg')\n\n    def test_save_audio_aac_uses_ffmpeg_backend(self):\n        \"\"\"AAC format should use ffmpeg backend like MP3.\"\"\"\n        saver = AudioSaver()\n        output_path = Path(self.temp_dir) / \"test.aac\"\n        \n        with patch('acestep.audio_utils.torchaudio.save') as mock_save:\n            saver.save_audio(\n                self.sample_audio,\n                output_path,\n                sample_rate=self.sample_rate,\n                format=\"aac\"\n            )\n            \n            # Check that ffmpeg backend was used\n            call_kwargs = mock_save.call_args[1]\n            self.assertEqual(call_kwargs['backend'], 'ffmpeg')\n\n    def test_extension_handling_for_opus(self):\n        \"\"\"Test that .opus extension is correctly added.\"\"\"\n        saver = AudioSaver()\n        output_path = Path(self.temp_dir) / \"test_file\"\n        \n        with patch('acestep.audio_utils.torchaudio.save'):\n            result = saver.save_audio(\n                self.sample_audio,\n                output_path,\n                sample_rate=self.sample_rate,\n                format=\"opus\"\n            )\n            \n            self.assertTrue(result.endswith('.opus'))\n            self.assertTrue('test_file.opus' in result)\n\n    def test_extension_handling_for_aac(self):\n        \"\"\"Test that .aac extension is correctly added.\"\"\"\n        saver = AudioSaver()\n        output_path = Path(self.temp_dir) / \"test_file\"\n        \n        with patch('acestep.audio_utils.torchaudio.save'):\n            result = saver.save_audio(\n                self.sample_audio,\n                output_path,\n                sample_rate=self.sample_rate,\n                format=\"aac\"\n            )\n            \n            self.assertTrue(result.endswith('.aac'))\n            self.assertTrue('test_file.aac' in result)\n\n    def test_m4a_extension_accepted_for_aac(self):\n        \"\"\"Test that .m4a extension is accepted as valid for AAC format.\"\"\"\n        saver = AudioSaver()\n        output_path = Path(self.temp_dir) / \"test_file.m4a\"\n        \n        with patch('acestep.audio_utils.torchaudio.save'):\n            result = saver.save_audio(\n                self.sample_audio,\n                output_path,\n                sample_rate=self.sample_rate,\n                format=\"aac\"\n            )\n            \n            self.assertTrue(result.endswith('.m4a'))\n\n    def test_save_audio_invalid_format_fallback(self):\n        \"\"\"save_audio should fall back to default format for invalid formats.\"\"\"\n        saver = AudioSaver(default_format=\"flac\")\n        output_path = Path(self.temp_dir) / \"test\"\n        \n        with patch('acestep.audio_utils.torchaudio.save'):\n            result = saver.save_audio(\n                self.sample_audio,\n                output_path,\n                sample_rate=self.sample_rate,\n                format=\"invalid_format\"\n            )\n            \n            # Should fall back to flac\n            self.assertTrue(result.endswith('.flac'))\n\n    def test_numpy_array_input_with_opus(self):\n        \"\"\"Test that numpy arrays work with Opus format.\"\"\"\n        saver = AudioSaver()\n        output_path = Path(self.temp_dir) / \"test_numpy.opus\"\n        audio_np = np.random.randn(2, 48000).astype(np.float32)\n        \n        with patch('acestep.audio_utils.torchaudio.save') as mock_save:\n            result = saver.save_audio(\n                audio_np,\n                output_path,\n                sample_rate=self.sample_rate,\n                format=\"opus\"\n            )\n            \n            # Verify the call was made\n            mock_save.assert_called_once()\n            self.assertTrue(result.endswith('.opus'))\n\n    def test_convenience_function_supports_opus(self):\n        \"\"\"Test that the convenience save_audio function supports Opus.\"\"\"\n        output_path = Path(self.temp_dir) / \"convenience_test.opus\"\n        \n        with patch('acestep.audio_utils.torchaudio.save'):\n            result = save_audio(\n                self.sample_audio,\n                output_path,\n                sample_rate=self.sample_rate,\n                format=\"opus\"\n            )\n            \n            self.assertTrue(result.endswith('.opus'))\n\n    def test_convenience_function_supports_aac(self):\n        \"\"\"Test that the convenience save_audio function supports AAC.\"\"\"\n        output_path = Path(self.temp_dir) / \"convenience_test.aac\"\n\n        with patch('acestep.audio_utils.torchaudio.save'):\n            result = save_audio(\n                self.sample_audio,\n                output_path,\n                sample_rate=self.sample_rate,\n                format=\"aac\"\n            )\n\n            self.assertTrue(result.endswith('.aac'))\n\n\nclass ApplyFadeTests(unittest.TestCase):\n    \"\"\"Tests for apply_fade function.\"\"\"\n\n    def setUp(self):\n        \"\"\"Create a constant-amplitude stereo test signal.\"\"\"\n        # 1 second of constant value 1.0 at 48 kHz, stereo\n        self.sample_rate = 48000\n        self.audio_tensor = torch.ones(2, self.sample_rate)\n        self.audio_numpy = np.ones((2, self.sample_rate), dtype=np.float32)\n\n    # ------------------------------------------------------------------\n    # Success path\n    # ------------------------------------------------------------------\n\n    def test_no_fade_returns_unchanged_tensor(self):\n        \"\"\"Zero fade durations should return audio unchanged.\"\"\"\n        result = apply_fade(self.audio_tensor, 0, 0)\n        self.assertTrue(torch.allclose(result, self.audio_tensor))\n\n    def test_no_fade_returns_unchanged_numpy(self):\n        \"\"\"Zero fade durations should return numpy audio unchanged.\"\"\"\n        result = apply_fade(self.audio_numpy, 0, 0)\n        np.testing.assert_array_equal(result, self.audio_numpy)\n\n    def test_fade_in_first_sample_is_zero(self):\n        \"\"\"The very first sample should be 0 after a fade in is applied.\"\"\"\n        result = apply_fade(self.audio_tensor, fade_in_samples=1000, fade_out_samples=0)\n        self.assertAlmostEqual(result[0, 0].item(), 0.0, places=5)\n\n    def test_fade_in_last_ramp_sample_near_one(self):\n        \"\"\"The last sample of a fade-in ramp should approach 1.0.\"\"\"\n        fade_samples = 4800\n        result = apply_fade(self.audio_tensor, fade_in_samples=fade_samples, fade_out_samples=0)\n        # Sample at index fade_samples - 1 should be close to 1.0\n        self.assertAlmostEqual(result[0, fade_samples - 1].item(), 1.0, places=3)\n\n    def test_fade_out_last_sample_is_zero(self):\n        \"\"\"The last sample should be 0 after a fade out is applied.\"\"\"\n        result = apply_fade(self.audio_tensor, fade_in_samples=0, fade_out_samples=1000)\n        self.assertAlmostEqual(result[0, -1].item(), 0.0, places=5)\n\n    def test_fade_out_first_ramp_sample_near_one(self):\n        \"\"\"The first sample of the fade-out region should approach 1.0.\"\"\"\n        total = self.sample_rate\n        fade_samples = 4800\n        result = apply_fade(self.audio_tensor, fade_in_samples=0, fade_out_samples=fade_samples)\n        self.assertAlmostEqual(result[0, total - fade_samples].item(), 1.0, places=3)\n\n    def test_both_fades_combined(self):\n        \"\"\"Fade in and fade out should both be applied correctly.\"\"\"\n        result = apply_fade(self.audio_tensor, fade_in_samples=480, fade_out_samples=480)\n        self.assertAlmostEqual(result[0, 0].item(), 0.0, places=5)\n        self.assertAlmostEqual(result[0, -1].item(), 0.0, places=5)\n        # Middle should be unaffected (constant 1.0)\n        mid = self.sample_rate // 2\n        self.assertAlmostEqual(result[0, mid].item(), 1.0, places=5)\n\n    def test_fade_preserves_type_tensor(self):\n        \"\"\"apply_fade should return a tensor when given a tensor.\"\"\"\n        result = apply_fade(self.audio_tensor, 100, 100)\n        self.assertIsInstance(result, torch.Tensor)\n\n    def test_fade_preserves_type_numpy(self):\n        \"\"\"apply_fade should return a numpy array when given a numpy array.\"\"\"\n        result = apply_fade(self.audio_numpy, 100, 100)\n        self.assertIsInstance(result, np.ndarray)\n\n    def test_fade_does_not_modify_input_tensor(self):\n        \"\"\"apply_fade should not modify the original tensor in place.\"\"\"\n        original = self.audio_tensor.clone()\n        apply_fade(self.audio_tensor, 1000, 1000)\n        self.assertTrue(torch.allclose(self.audio_tensor, original))\n\n    def test_fade_does_not_modify_input_numpy(self):\n        \"\"\"apply_fade should not modify the original numpy array in place.\"\"\"\n        original = self.audio_numpy.copy()\n        apply_fade(self.audio_numpy, 1000, 1000)\n        np.testing.assert_array_equal(self.audio_numpy, original)\n\n    # ------------------------------------------------------------------\n    # Edge cases\n    # ------------------------------------------------------------------\n\n    def test_fade_clamps_to_signal_length(self):\n        \"\"\"Fade longer than the signal should be clamped to signal length.\"\"\"\n        very_long = self.sample_rate * 10\n        result = apply_fade(self.audio_tensor, very_long, very_long)\n        # Should not raise and both ends should be 0\n        self.assertAlmostEqual(result[0, 0].item(), 0.0, places=5)\n        self.assertAlmostEqual(result[0, -1].item(), 0.0, places=5)\n\n    def test_fade_in_numpy_first_sample_is_zero(self):\n        \"\"\"Numpy fade-in should make the first sample 0.\"\"\"\n        result = apply_fade(self.audio_numpy, fade_in_samples=1000, fade_out_samples=0)\n        self.assertAlmostEqual(float(result[0, 0]), 0.0, places=5)\n\n    def test_fade_out_numpy_last_sample_is_zero(self):\n        \"\"\"Numpy fade-out should make the last sample 0.\"\"\"\n        result = apply_fade(self.audio_numpy, fade_in_samples=0, fade_out_samples=1000)\n        self.assertAlmostEqual(float(result[0, -1]), 0.0, places=5)\n\n\nif __name__ == '__main__':\n    unittest.main()\n"
  },
  {
    "path": "acestep/audio_utils_uuid_test.py",
    "content": "\"\"\"Test UUID generation includes LoRA state to prevent file reuse.\"\"\"\nimport os\nimport tempfile\nimport unittest\n\nfrom acestep.audio_utils import generate_uuid_from_params, get_lora_weights_hash\n\n\n# ---------------------------------------------------------------------------\n# Lightweight stub for dit_handler used by get_lora_weights_hash tests\n# ---------------------------------------------------------------------------\n\nclass _FakeLoraService:\n    \"\"\"Minimal stand-in for LoraService with a registry dict.\"\"\"\n\n    def __init__(self, registry=None):\n        self.registry = registry or {}\n\n\nclass _FakeHandler:\n    \"\"\"Minimal stand-in for a DiT handler with LoRA attributes.\"\"\"\n\n    def __init__(self, lora_loaded=False, use_lora=False, registry=None):\n        self.lora_loaded = lora_loaded\n        self.use_lora = use_lora\n        self._lora_service = _FakeLoraService(registry)\n\n\nclass UuidGenerationTest(unittest.TestCase):\n    \"\"\"Test that UUID generation correctly differentiates LoRA states.\"\"\"\n\n    def test_different_lora_states_produce_different_uuids(self):\n        \"\"\"Different LoRA states with same other params should produce different UUIDs.\"\"\"\n        base_params = {\n            \"seed\": 3631605787,\n            \"caption\": \"A beautiful melody\",\n            \"lyrics\": \"[Instrumental]\",\n            \"inference_steps\": 8,\n        }\n\n        # Generate UUID with LoRA disabled\n        params_lora_off = base_params.copy()\n        params_lora_off[\"lora_loaded\"] = False\n        params_lora_off[\"use_lora\"] = False\n        params_lora_off[\"lora_scale\"] = 1.0\n        uuid_lora_off = generate_uuid_from_params(params_lora_off)\n\n        # Generate UUID with LoRA enabled\n        params_lora_on = base_params.copy()\n        params_lora_on[\"lora_loaded\"] = True\n        params_lora_on[\"use_lora\"] = True\n        params_lora_on[\"lora_scale\"] = 1.0\n        uuid_lora_on = generate_uuid_from_params(params_lora_on)\n\n        # UUIDs should be different\n        self.assertNotEqual(\n            uuid_lora_off,\n            uuid_lora_on,\n            \"UUIDs should differ when only LoRA state changes\",\n        )\n\n    def test_different_lora_scale_produces_different_uuids(self):\n        \"\"\"Different LoRA scales should produce different UUIDs.\"\"\"\n        base_params = {\n            \"seed\": 3631605787,\n            \"caption\": \"A beautiful melody\",\n            \"lora_loaded\": True,\n            \"use_lora\": True,\n        }\n\n        params_scale_0_5 = base_params.copy()\n        params_scale_0_5[\"lora_scale\"] = 0.5\n        uuid_scale_0_5 = generate_uuid_from_params(params_scale_0_5)\n\n        params_scale_1_0 = base_params.copy()\n        params_scale_1_0[\"lora_scale\"] = 1.0\n        uuid_scale_1_0 = generate_uuid_from_params(params_scale_1_0)\n\n        # UUIDs should be different\n        self.assertNotEqual(\n            uuid_scale_0_5,\n            uuid_scale_1_0,\n            \"UUIDs should differ when only LoRA scale changes\",\n        )\n\n    def test_same_params_produce_same_uuid(self):\n        \"\"\"Same params should always produce the same UUID (deterministic).\"\"\"\n        params = {\n            \"seed\": 3631605787,\n            \"caption\": \"A beautiful melody\",\n            \"lora_loaded\": True,\n            \"use_lora\": True,\n            \"lora_scale\": 1.0,\n        }\n\n        uuid1 = generate_uuid_from_params(params)\n        uuid2 = generate_uuid_from_params(params)\n\n        # UUIDs should be identical\n        self.assertEqual(uuid1, uuid2, \"Same params should produce same UUID\")\n\n    def test_uuid_format_is_valid(self):\n        \"\"\"Generated UUID should follow standard format.\"\"\"\n        params = {\n            \"seed\": 3631605787,\n            \"lora_loaded\": False,\n            \"use_lora\": False,\n            \"lora_scale\": 1.0,\n        }\n\n        uuid = generate_uuid_from_params(params)\n\n        # Check format: 8-4-4-4-12\n        parts = uuid.split(\"-\")\n        self.assertEqual(len(parts), 5, \"UUID should have 5 parts\")\n        self.assertEqual(len(parts[0]), 8, \"First part should be 8 chars\")\n        self.assertEqual(len(parts[1]), 4, \"Second part should be 4 chars\")\n        self.assertEqual(len(parts[2]), 4, \"Third part should be 4 chars\")\n        self.assertEqual(len(parts[3]), 4, \"Fourth part should be 4 chars\")\n        self.assertEqual(len(parts[4]), 12, \"Fifth part should be 12 chars\")\n\n    # ------------------------------------------------------------------\n    # get_lora_weights_hash tests\n    # ------------------------------------------------------------------\n\n    def test_lora_weights_hash_empty_when_no_lora(self):\n        \"\"\"Hash should be empty when no LoRA is loaded.\"\"\"\n        handler = _FakeHandler(lora_loaded=False, use_lora=False)\n        self.assertEqual(get_lora_weights_hash(handler), \"\")\n\n    def test_lora_weights_hash_empty_when_use_lora_false(self):\n        \"\"\"Hash should be empty when use_lora is False even if loaded.\"\"\"\n        handler = _FakeHandler(lora_loaded=True, use_lora=False)\n        self.assertEqual(get_lora_weights_hash(handler), \"\")\n\n    def test_different_lora_files_produce_different_hashes(self):\n        \"\"\"Two different weight files should yield different hashes.\"\"\"\n        with tempfile.TemporaryDirectory() as tmpdir:\n            path_a = os.path.join(tmpdir, \"lora_a\")\n            path_b = os.path.join(tmpdir, \"lora_b\")\n            os.makedirs(path_a)\n            os.makedirs(path_b)\n\n            # Write distinct fake weight files\n            with open(os.path.join(path_a, \"adapter_model.safetensors\"), \"wb\") as f:\n                f.write(b\"weights_A_content_1234\")\n            with open(os.path.join(path_b, \"adapter_model.safetensors\"), \"wb\") as f:\n                f.write(b\"weights_B_content_5678\")\n\n            handler_a = _FakeHandler(\n                lora_loaded=True,\n                use_lora=True,\n                registry={\"adapter\": {\"path\": path_a, \"targets\": []}},\n            )\n            handler_b = _FakeHandler(\n                lora_loaded=True,\n                use_lora=True,\n                registry={\"adapter\": {\"path\": path_b, \"targets\": []}},\n            )\n\n            hash_a = get_lora_weights_hash(handler_a)\n            hash_b = get_lora_weights_hash(handler_b)\n\n            self.assertTrue(hash_a, \"Hash A should be non-empty\")\n            self.assertTrue(hash_b, \"Hash B should be non-empty\")\n            self.assertNotEqual(\n                hash_a,\n                hash_b,\n                \"Different LoRA weight files must produce different hashes\",\n            )\n\n    def test_same_lora_file_produces_same_hash(self):\n        \"\"\"Same weight file should produce identical hash on repeated calls.\"\"\"\n        with tempfile.TemporaryDirectory() as tmpdir:\n            path = os.path.join(tmpdir, \"lora\")\n            os.makedirs(path)\n            with open(os.path.join(path, \"adapter_model.safetensors\"), \"wb\") as f:\n                f.write(b\"consistent_weights\")\n\n            handler = _FakeHandler(\n                lora_loaded=True,\n                use_lora=True,\n                registry={\"adapter\": {\"path\": path, \"targets\": []}},\n            )\n\n            self.assertEqual(\n                get_lora_weights_hash(handler),\n                get_lora_weights_hash(handler),\n                \"Same LoRA file should produce identical hash\",\n            )\n\n    def test_lora_weights_hash_differentiates_uuids(self):\n        \"\"\"UUID should differ when only lora_weights_hash changes.\"\"\"\n        base = {\"seed\": 42, \"lora_loaded\": True, \"use_lora\": True, \"lora_scale\": 1.0}\n\n        params_a = {**base, \"lora_weights_hash\": \"aaa\"}\n        params_b = {**base, \"lora_weights_hash\": \"bbb\"}\n\n        self.assertNotEqual(\n            generate_uuid_from_params(params_a),\n            generate_uuid_from_params(params_b),\n            \"UUIDs should differ when lora_weights_hash differs\",\n        )\n\n\nclass AudioCodesPreservationTest(unittest.TestCase):\n    \"\"\"Test that user-provided audio_codes are not overwritten by empty LM codes.\n\n    Reproduces the logic from inference.py lines 654-658 where\n    lm_generated_audio_codes_list may contain empty strings (from\n    infer_type='dit') that would incorrectly overwrite user-provided codes.\n    \"\"\"\n\n    @staticmethod\n    def _build_audio_params(base_params, lm_codes_list, idx):\n        \"\"\"Replicate the audio_params building logic from inference.py.\"\"\"\n        audio_params = base_params.copy()\n        if lm_codes_list and idx < len(lm_codes_list):\n            lm_code = lm_codes_list[idx]\n            if lm_code and str(lm_code).strip():\n                audio_params[\"audio_codes\"] = lm_code\n        return audio_params\n\n    def test_user_codes_preserved_when_lm_returns_empty(self):\n        \"\"\"User-provided audio_codes must survive when LM returns empty codes.\"\"\"\n        user_codes = \"<|audio_code_1|><|audio_code_2|>\"\n        base = {\"audio_codes\": user_codes, \"seed\": 42}\n        # LM ran in \"dit\" mode → empty string in list\n        result = self._build_audio_params(base, [\"\"], 0)\n        self.assertEqual(result[\"audio_codes\"], user_codes)\n\n    def test_lm_codes_overwrite_when_non_empty(self):\n        \"\"\"LM-generated codes should overwrite when non-empty.\"\"\"\n        lm_codes = \"<|audio_code_99|>\"\n        base = {\"audio_codes\": \"\", \"seed\": 42}\n        result = self._build_audio_params(base, [lm_codes], 0)\n        self.assertEqual(result[\"audio_codes\"], lm_codes)\n\n    def test_user_codes_preserved_when_lm_list_empty(self):\n        \"\"\"User codes preserved when lm_generated list is empty.\"\"\"\n        user_codes = \"<|audio_code_1|>\"\n        base = {\"audio_codes\": user_codes, \"seed\": 42}\n        result = self._build_audio_params(base, [], 0)\n        self.assertEqual(result[\"audio_codes\"], user_codes)\n\n\nif __name__ == \"__main__\":\n    unittest.main()\n"
  },
  {
    "path": "acestep/cli_args.py",
    "content": "\"\"\"Argument parsing helpers shared by ACE-Step CLI entrypoints.\"\"\"\n\nfrom __future__ import annotations\n\nimport argparse\n\n_QUANTIZATION_ALIASES = {\n    \"int8_weight_only\": \"int8_weight_only\",\n    \"fp8_weight_only\": \"fp8_weight_only\",\n    \"w8a8_dynamic\": \"w8a8_dynamic\",\n}\n_NONE_ALIASES = {\"\", \"none\", \"null\"}\n\n\ndef parse_quantization_arg(value: str | None) -> str | None:\n    \"\"\"Parse ``--quantization`` values from CLI input.\n\n    Args:\n        value: Raw CLI value.\n\n    Returns:\n        Canonical quantization method or ``None`` for disabled quantization.\n\n    Raises:\n        argparse.ArgumentTypeError: If the value is not supported.\n    \"\"\"\n    if value is None:\n        return None\n\n    normalized = value.strip().lower()\n    if normalized in _NONE_ALIASES:\n        return None\n\n    quantization = _QUANTIZATION_ALIASES.get(normalized)\n    if quantization is not None:\n        return quantization\n\n    raise argparse.ArgumentTypeError(\n        \"Invalid quantization value. Use int8_weight_only, fp8_weight_only, \"\n        \"w8a8_dynamic, or none.\"\n    )\n"
  },
  {
    "path": "acestep/cli_args_test.py",
    "content": "\"\"\"Unit tests for CLI argument parsing helpers.\"\"\"\n\nfrom __future__ import annotations\n\nimport argparse\nimport unittest\n\nfrom acestep.cli_args import parse_quantization_arg\n\n\nclass ParseQuantizationArgTests(unittest.TestCase):\n    \"\"\"Behavior tests for quantization CLI parsing.\"\"\"\n\n    def test_returns_none_for_none_aliases(self) -> None:\n        \"\"\"It treats ``none`` aliases as disabled quantization.\"\"\"\n        self.assertIsNone(parse_quantization_arg(\"none\"))\n        self.assertIsNone(parse_quantization_arg(\"None\"))\n        self.assertIsNone(parse_quantization_arg(\" null \"))\n        self.assertIsNone(parse_quantization_arg(\"\"))\n\n    def test_returns_canonical_quantization_values(self) -> None:\n        \"\"\"It returns supported quantization values in canonical form.\"\"\"\n        self.assertEqual(\"int8_weight_only\", parse_quantization_arg(\"int8_weight_only\"))\n        self.assertEqual(\"int8_weight_only\", parse_quantization_arg(\"INT8_WEIGHT_ONLY\"))\n        self.assertEqual(\"fp8_weight_only\", parse_quantization_arg(\"fp8_weight_only\"))\n        self.assertEqual(\"fp8_weight_only\", parse_quantization_arg(\" FP8_Weight_Only \"))\n        self.assertEqual(\"w8a8_dynamic\", parse_quantization_arg(\"w8a8_dynamic\"))\n        self.assertEqual(\"w8a8_dynamic\", parse_quantization_arg(\" W8A8_Dynamic \"))\n\n    def test_raises_for_invalid_value(self) -> None:\n        \"\"\"It raises ``ArgumentTypeError`` for unsupported values.\"\"\"\n        with self.assertRaises(argparse.ArgumentTypeError):\n            parse_quantization_arg(\"int4_weight_only\")\n\n\nif __name__ == \"__main__\":\n    unittest.main()\n"
  },
  {
    "path": "acestep/constants.py",
    "content": "\"\"\"\nConstants for ACE-Step\nCentralized constants used across the codebase\n\"\"\"\n\n# ==============================================================================\n# Language Constants\n# ==============================================================================\n\n# Supported languages for vocal generation and language detection\n# Covers major world languages with good TTS support in the underlying model\n# 'unknown' is used when language cannot be determined automatically\nVALID_LANGUAGES = [\n    'ar', 'az', 'bg', 'bn', 'ca', 'cs', 'da', 'de', 'el', 'en',\n    'es', 'fa', 'fi', 'fr', 'he', 'hi', 'hr', 'ht', 'hu', 'id',\n    'is', 'it', 'ja', 'ko', 'la', 'lt', 'ms', 'ne', 'nl', 'no',\n    'pa', 'pl', 'pt', 'ro', 'ru', 'sa', 'sk', 'sr', 'sv', 'sw',\n    'ta', 'te', 'th', 'tl', 'tr', 'uk', 'ur', 'vi', 'yue', 'zh',\n    'unknown'\n]\n\n\n# ==============================================================================\n# Keyscale Constants\n# ==============================================================================\n\n# Musical note names using standard Western notation\nKEYSCALE_NOTES = ['A', 'B', 'C', 'D', 'E', 'F', 'G']\n\n# Supported accidentals: natural, ASCII sharp/flat, Unicode sharp/flat\nKEYSCALE_ACCIDENTALS = ['', '#', 'b', '♯', '♭']  # empty + ASCII sharp/flat + Unicode sharp/flat\n\n# Major and minor scale modes\nKEYSCALE_MODES = ['major', 'minor']\n\n# Generate all valid keyscales: 7 notes × 5 accidentals × 2 modes = 70 combinations\n# Examples: \"C major\", \"F# minor\", \"B♭ major\"\nVALID_KEYSCALES = set()\nfor note in KEYSCALE_NOTES:\n    for acc in KEYSCALE_ACCIDENTALS:\n        for mode in KEYSCALE_MODES:\n            VALID_KEYSCALES.add(f\"{note}{acc} {mode}\")\n\n\n# ==============================================================================\n# Metadata Range Constants\n# ==============================================================================\n\n# BPM (Beats Per Minute) range - covers most musical styles\n# 30 BPM: Very slow ballads, ambient music\n# 300 BPM: Fast electronic dance music, extreme metal\nBPM_MIN = 30\nBPM_MAX = 300\n\n# Duration range (in seconds) - balances quality vs. computational cost\n# 10s: Short loops, musical excerpts\n# 600s: Full songs, extended compositions (10 minutes)\nDURATION_MIN = 10\nDURATION_MAX = 600\n\n# Valid time signatures - common musical meter patterns\n# 2: 2/4 time (marches, polka)\n# 3: 3/4 time (waltzes, ballads) \n# 4: 4/4 time (most pop, rock, hip-hop)\n# 6: 6/8 time (compound time, folk dances)\nVALID_TIME_SIGNATURES = [2, 3, 4, 6]\n\n\n# ==============================================================================\n# Task Type Constants  \n# ==============================================================================\n\n# All supported generation tasks across different model variants\nTASK_TYPES = [\"text2music\", \"repaint\", \"cover\", \"extract\", \"lego\", \"complete\"]\n\n# Task types available for turbo models (optimized subset for speed)\n# - text2music: Generate from text descriptions\n# - repaint: Selective audio editing/regeneration  \n# - cover: Style transfer using reference audio\nTASK_TYPES_TURBO = [\"text2music\", \"repaint\", \"cover\"]\n\n# Task types available for base models (full feature set)\n# Additional tasks requiring more computational resources:\n# - extract: Separate individual tracks/stems from audio\n# - lego: Multi-track generation (add layers)\n# - complete: Automatic completion of partial audio\nTASK_TYPES_BASE = [\"text2music\", \"repaint\", \"cover\", \"extract\", \"lego\", \"complete\"]\n\n\n# ==============================================================================\n# Generation Mode Constants (UI-level modes that map to task types)\n# ==============================================================================\n\n# Default modes for turbo and SFT models (restricted set)\nGENERATION_MODES_TURBO = [\"Simple\", \"Custom\", \"Remix\", \"Repaint\"]\n\n# Extended modes for pure base models only — adds Extract/Lego/Complete\nGENERATION_MODES_BASE = [\"Simple\", \"Custom\", \"Remix\", \"Repaint\", \"Extract\", \"Lego\", \"Complete\"]\n\n# Mapping from generation mode to task_type value\nMODE_TO_TASK_TYPE = {\n    \"Simple\": \"text2music\",\n    \"Custom\": \"text2music\",\n    \"Remix\": \"cover\",\n    \"Repaint\": \"repaint\",\n    \"Extract\": \"extract\",\n    \"Lego\": \"lego\",\n    \"Complete\": \"complete\",\n}\n\n\n# ==============================================================================\n# Instruction Constants\n# ==============================================================================\n\n# Default instructions\nDEFAULT_DIT_INSTRUCTION = \"Fill the audio semantic mask based on the given conditions:\"\nDEFAULT_LM_INSTRUCTION = \"Generate audio semantic tokens based on the given conditions:\"\nDEFAULT_LM_UNDERSTAND_INSTRUCTION = \"Understand the given musical conditions and describe the audio semantics accordingly:\"\nDEFAULT_LM_INSPIRED_INSTRUCTION = \"Expand the user's input into a more detailed and specific musical description:\"\nDEFAULT_LM_REWRITE_INSTRUCTION = \"Format the user's input into a more detailed and specific musical description:\"\n\n# Instruction templates for each task type\n# Note: Some instructions use placeholders like {TRACK_NAME} or {TRACK_CLASSES}\n# These should be formatted using .format() or f-strings when used\nTASK_INSTRUCTIONS = {\n    \"text2music\": \"Fill the audio semantic mask based on the given conditions:\",\n    \"repaint\": \"Repaint the mask area based on the given conditions:\",\n    \"cover\": \"Generate audio semantic tokens based on the given conditions:\",\n    \"extract\": \"Extract the {TRACK_NAME} track from the audio:\",\n    \"extract_default\": \"Extract the track from the audio:\",\n    \"lego\": \"Generate the {TRACK_NAME} track based on the audio context:\",\n    \"lego_default\": \"Generate the track based on the audio context:\",\n    \"complete\": \"Complete the input track with {TRACK_CLASSES}:\",\n    \"complete_default\": \"Complete the input track:\",\n}\n\n\n# ==============================================================================\n# Track/Instrument Constants\n# ==============================================================================\n\n# Supported instrumental track types for multi-track generation and extraction\n# Organized by instrument families for logical grouping:\n# - Wind instruments: woodwinds, brass\n# - Electronic: fx (effects), synth (synthesizer)  \n# - String instruments: strings, guitar, bass\n# - Rhythm section: percussion, drums, keyboard\n# - Vocals: backing_vocals, vocals (lead vocals)\nTRACK_NAMES = [\n    \"woodwinds\", \"brass\", \"fx\", \"synth\", \"strings\", \"percussion\",\n    \"keyboard\", \"guitar\", \"bass\", \"drums\", \"backing_vocals\", \"vocals\"\n]\n\n# Template for SFT (Supervised Fine-Tuning) model prompts\n# Used to format inputs for the language model with instruction, caption, and metadata\nSFT_GEN_PROMPT = \"\"\"# Instruction\n{}\n\n# Caption\n{}\n\n# Metas\n{}<|endoftext|>\n\"\"\"\n\n\n# ==============================================================================\n# GPU Memory Configuration Constants\n# ==============================================================================\n\n# GPU tier thresholds (in GB)\nGPU_TIER_THRESHOLDS = {\n    \"tier1\": 4,    # <= 4GB\n    \"tier2\": 6,    # 4-6GB\n    \"tier3\": 8,    # 6-8GB\n    \"tier4\": 12,   # 8-12GB\n    \"tier5\": 16,   # 12-16GB\n    \"tier6\": 24,   # 16-24GB\n    # \"unlimited\" for >= 24GB\n}\n\n# LM model memory requirements (in GB)\nLM_MODEL_MEMORY_GB = {\n    \"0.6B\": 3.0,\n    \"1.7B\": 8.0,\n    \"4B\": 12.0,\n}\n\n# LM model names mapping\nLM_MODEL_NAMES = {\n    \"0.6B\": \"acestep-5Hz-lm-0.6B\",\n    \"1.7B\": \"acestep-5Hz-lm-1.7B\",\n    \"4B\": \"acestep-5Hz-lm-4B\",\n}\n\n\n# ==============================================================================\n# Debug Constants\n# ==============================================================================\n\n# Tensor debug mode (values: \"OFF\" | \"ON\" | \"VERBOSE\")\nTENSOR_DEBUG_MODE = \"OFF\"\n\n# Placeholder debug switches for other main functionality (default \"OFF\")\n# Update names/usage as features adopt them.\nDEBUG_API_SERVER = \"OFF\"\nDEBUG_INFERENCE = \"OFF\"\nDEBUG_TRAINING = \"OFF\"\nDEBUG_DATASET = \"OFF\"\nDEBUG_AUDIO = \"OFF\"\nDEBUG_LLM = \"OFF\"\nDEBUG_UI = \"OFF\"\nDEBUG_MODEL_LOADING = \"OFF\"\nDEBUG_GPU = \"OFF\"\n"
  },
  {
    "path": "acestep/constrained_logits_processor.py",
    "content": "\n\"\"\"\nConstrained Logits Processor for ACE-Step Language Model\n\nThis module implements a finite state machine (FSM) based logits processor that constrains\nthe language model's output to follow specific formats and value ranges during music generation.\n\nKey Features:\n- Enforces structured metadata generation (BPM, duration, keyscale, etc.)\n- Validates numeric ranges (BPM: 30-300, Duration: 10-600s)\n- Ensures proper formatting for musical metadata\n- Prevents generation of invalid tokens or formats\n- Supports constrained audio code generation (0-63999)\n\nThe FSM guides the model through different states to ensure outputs conform to expected\nschema requirements without post-processing corrections.\n\nUsage:\n    processor = ConstrainedLogitsProcessor(tokenizer, mode=\"metadata\")\n    outputs = model.generate(inputs, logits_processor=[processor])\n\"\"\"\n\nfrom enum import Enum, auto\nfrom typing import Optional, Dict, Any, Tuple, List, Callable, Set\nfrom loguru import logger\nfrom transformers import AutoTokenizer\nfrom transformers.generation.logits_process import LogitsProcessor\nimport os\nimport torch\nfrom acestep.constants import (\n    VALID_LANGUAGES,\n    KEYSCALE_NOTES,\n    KEYSCALE_ACCIDENTALS,\n    KEYSCALE_MODES,\n    VALID_KEYSCALES,\n    BPM_MIN,\n    BPM_MAX,\n    DURATION_MIN,\n    DURATION_MAX,\n    VALID_TIME_SIGNATURES,\n)\n\n\n# ==============================================================================\n# Audio Code Constants\n# ==============================================================================\nMAX_AUDIO_CODE = 63999  # Maximum valid audio code value (codebook size = 64000)\n\n\n# ==============================================================================\n# FSM States for Constrained Decoding\n# ==============================================================================\nclass FSMState(Enum):\n    \"\"\"Finite State Machine states for metadata generation\"\"\"\n    THINK_TAG = auto()           # Generating \"<think>\"\n    NEWLINE_AFTER_THINK = auto() # Generating \"\\n\" after <think>\n    BPM_NAME = auto()            # Generating \"bpm: \"\n    BPM_VALUE = auto()           # Generating numeric value 30-300\n    NEWLINE_AFTER_BPM = auto()   # Generating \"\\n\" after bpm value\n    CAPTION_NAME = auto()        # Generating \"caption: \"\n    CAPTION_VALUE = auto()       # Generating caption text (no code blocks/newlines)\n    DURATION_NAME = auto()       # Generating \"duration: \"\n    DURATION_VALUE = auto()      # Generating numeric value 10-600\n    NEWLINE_AFTER_DURATION = auto()\n    GENRES_NAME = auto()         # Generating \"genres: \"\n    GENRES_VALUE = auto()        # Generating any non-empty string\n    NEWLINE_AFTER_GENRES = auto()\n    KEYSCALE_NAME = auto()       # Generating \"keyscale: \"\n    KEYSCALE_VALUE = auto()      # Generating keyscale pattern\n    NEWLINE_AFTER_KEYSCALE = auto()\n    LANGUAGE_NAME = auto()       # Generating \"language: \"\n    LANGUAGE_VALUE = auto()      # Generating language code (en, zh, ja, etc.)\n    TIMESIG_NAME = auto()        # Generating \"timesignature: \"\n    TIMESIG_VALUE = auto()       # Generating 2, 3, 4, or 6\n    NEWLINE_AFTER_TIMESIG = auto()\n    THINK_END_TAG = auto()       # Generating \"</think>\"\n    CODES_GENERATION = auto()    # Generating audio codes (no constraints)\n    COMPLETED = auto()           # Generation completed\n\n\nclass MetadataConstrainedLogitsProcessor(LogitsProcessor):\n    \"\"\"\n    FSM-driven LogitsProcessor that constrains generation to produce valid metadata.\n    \n    This processor enforces the following format:\n    <think>\n    bpm: [30-300]\n    caption: [text without code blocks, ends with period + newline]\n    duration: [10-600]\n    keyscale: [A-G][#/♭]? [major/minor]\n    language: [en/zh/ja/ko/es/fr/de/uk/ru/...]\n    timesignature: [2/3/4/6]\n    </think>\n    \n    It uses token masking (setting invalid token logits to -inf) to enforce constraints.\n    For numeric fields, it uses early-blocking to prevent out-of-range values.\n    For field transitions (e.g., end of numeric value), it compares P(newline) vs P(digit).\n    For caption field, it blocks code blocks and newlines, and only transitions when\n    the previous token was a period and newline has the highest probability.\n    \"\"\"\n    \n    def __init__(\n        self,\n        tokenizer: AutoTokenizer,\n        enabled: bool = True,\n        debug: bool = False,\n        genres_vocab_path: Optional[str] = None,\n        skip_genres: bool = True,\n        max_duration: Optional[int] = None,\n    ):\n        \"\"\"\n        Initialize the constrained logits processor.\n        \n        This processor should be initialized once when loading the LLM and reused\n        for all generations.\n        Args:\n            tokenizer: The tokenizer to use for encoding/decoding\n            enabled: Whether to enable constrained decoding\n            debug: Whether to print debug information\n            genres_vocab_path: Path to genres vocabulary file\n            skip_genres: Whether to skip genres field generation\n            max_duration: Maximum duration in seconds (default: DURATION_MAX from constants)\n        \"\"\"\n        self.tokenizer = tokenizer\n        self.enabled = enabled\n        self.debug = debug\n        self.skip_genres = skip_genres\n        \n        # Maximum duration limit (can be dynamically updated based on GPU config)\n        self.max_duration = max_duration if max_duration is not None else DURATION_MAX\n        self.skip_caption = False  # Set to True to skip caption field generation\n        self.skip_language = False  # Set to True to skip language field generation\n        self.caption: Optional[str] = None  # Set via update_caption() before each generation\n        \n        # User-provided metadata fields (optional)\n        # If provided, these fields will be used directly instead of generating\n        # Format: {\"bpm\": \"120\", \"caption\": \"...\", \"duration\": \"234\", \"keyscale\": \"G major\", \"language\": \"en\", \"timesignature\": \"4\"}\n        self.user_provided_metadata: Dict[str, Optional[str]] = {\n            \"bpm\": None,\n            \"caption\": None,\n            \"duration\": None,\n            \"keyscale\": None,\n            \"language\": None,\n            \"timesignature\": None,\n            \"genres\": None,\n        }\n        \n        # Temperature settings for different generation phases (set per-generation)\n        # If set, the processor will apply temperature scaling (divide logits by temperature)\n        # Note: Set base sampler temperature to 1.0 when using processor-based temperature\n        self.metadata_temperature: Optional[float] = None\n        self.codes_temperature: Optional[float] = None\n        \n        # Duration constraint for codes generation\n        # 5 codes = 1 second, so target_codes = target_duration * 5\n        self.target_duration: Optional[float] = None  # User-specified duration in seconds\n        self.target_codes: Optional[int] = None  # Computed target codes count\n        self.codes_count: int = 0  # Counter for generated codes\n        \n        # Stop at reasoning flag - if True, stop generation after </think> tag\n        self.stop_at_reasoning: bool = False\n        \n        # Generation phase - \"cot\" or \"codes\"\n        # Used to determine FSM behavior when prompt already contains CoT\n        self.generation_phase: str = \"cot\"\n        \n        # Current state\n        self.state = FSMState.THINK_TAG\n        self.position_in_state = 0  # Position within current state's fixed string\n        self.accumulated_value = \"\"  # For numeric/text value accumulation (legacy, for compatibility)\n        self.accumulated_token_ids: List[int] = []  # Token ID sequence for keyscale (and other fields)\n        \n        # Caption generation state tracking\n        self.caption_after_newline = False  # Track if we're right after a newline in caption\n        self.caption_token_count = 0  # Track token count for caption (max 512)\n        self.caption_ending = False  # Track if caption is ending (after detecting non-indented line)\n        self.pending_field_name = \"\"  # Accumulate field name tokens when caption is ending\n        \n        # Token queue for user-provided fields (injected directly without generation)\n        self.user_field_token_queue: List[int] = []\n        self.current_user_field: Optional[str] = None  # Current field being injected\n        \n        # Pre-compute token IDs for efficiency\n        self._precompute_tokens()\n\n        # Genres vocabulary for constrained decoding\n        self.genres_vocab_path = genres_vocab_path or os.path.join(\n            os.path.dirname(os.path.abspath(__file__)), \"genres_vocab.txt\"\n        )\n        self.genres_vocab: List[str] = []  # Full vocab\n        self.genres_vocab_mtime: float = 0.0\n        self.genres_trie: Dict = {}  # Trie for full vocab (fallback)\n        self.caption_genres_trie: Dict = {}  # Trie for caption-matched genres (priority)\n        self.caption_matched_genres: List[str] = []  # Genres matched from caption\n        \n        self._char_to_tokens: Dict[str, set] = {}  # Precomputed char -> token IDs mapping\n        \n        # Precompute token mappings once (O(vocab_size), runs once at init)\n        self._precompute_char_token_mapping()\n        \n        # Field definitions (needed before building prefix trees)\n        # Note: duration max uses self.max_duration which can be dynamically updated based on GPU config\n        self.field_specs = {\n            \"bpm\": {\"min\": BPM_MIN, \"max\": BPM_MAX},\n            \"duration\": {\"min\": DURATION_MIN, \"max\": self.max_duration},\n            \"timesignature\": {\"valid_values\": VALID_TIME_SIGNATURES},\n        }\n        \n        # Build valid numeric values for BPM, Duration, Timesignature\n        # These will be used to build prefix trees based on actual tokenization\n        self.valid_bpm_values = [str(v) for v in range(self.field_specs[\"bpm\"][\"min\"], self.field_specs[\"bpm\"][\"max\"] + 1)]\n        self.valid_duration_values = [str(v) for v in range(self.field_specs[\"duration\"][\"min\"], self.field_specs[\"duration\"][\"max\"] + 1)]\n        self.valid_timesig_values = [str(v) for v in self.field_specs[\"timesignature\"][\"valid_values\"]]\n        \n        # Build keyscale prefix tree (requires _char_to_tokens to be initialized)\n        self.keyscale_prefix_tree = self._build_keyscale_prefix_tree()\n        \n        # Build numeric prefix trees (BPM, Duration, Timesignature) with context\n        # IMPORTANT: State machine generates \"bpm:\" (no space), but tokenizer sees \"bpm: \" (with space)\n        # Use same logic as keyscale: context_prefix_for_matching (no space) and context_prefix_for_tokenization (with space)\n        self.bpm_prefix_tree = self._build_numeric_prefix_tree(\n            self.valid_bpm_values, \n            context_prefix_for_matching=\"bpm:\",\n            context_prefix_for_tokenization=\"bpm: \"\n        )\n        self.duration_prefix_tree = self._build_numeric_prefix_tree(\n            self.valid_duration_values,\n            context_prefix_for_matching=\"duration:\",\n            context_prefix_for_tokenization=\"duration: \"\n        )\n        self.timesig_prefix_tree = self._build_numeric_prefix_tree(\n            self.valid_timesig_values,\n            context_prefix_for_matching=\"timesignature:\",\n            context_prefix_for_tokenization=\"timesignature: \"\n        )\n        \n        # Build language prefix tree (similar to keyscale but for language codes)\n        self.language_prefix_tree = self._build_language_prefix_tree()\n\n        self._load_genres_vocab()\n        \n        # Fixed strings for each state\n        # IMPORTANT: Do NOT include trailing space after colon - tokenizer will handle spacing\n        # All matching should be done at token level, not string level\n        # NOTE: NEWLINE_AFTER_* states are removed - field values generate newline directly and transition to next field\n        self.fixed_strings = {\n            FSMState.THINK_TAG: \"<think>\",\n            FSMState.NEWLINE_AFTER_THINK: \"\\n\",\n            FSMState.BPM_NAME: \"bpm:\",\n            FSMState.CAPTION_NAME: \"caption:\",\n            FSMState.DURATION_NAME: \"duration:\",\n            FSMState.GENRES_NAME: \"genres:\",\n            FSMState.KEYSCALE_NAME: \"keyscale:\",\n            FSMState.LANGUAGE_NAME: \"language:\",\n            FSMState.TIMESIG_NAME: \"timesignature:\",\n            FSMState.THINK_END_TAG: \"</think>\",\n        }\n        \n        # State transitions\n        self._build_state_transitions()\n    \n    def _get_next_field_state(self, current_field: str) -> Optional[FSMState]:\n        \"\"\"\n        Get the next field state. Always returns the next field's NAME state,\n        even if the field is user-provided (we still need to generate the field name).\n        \n        Args:\n            current_field: Current field name (\"bpm\", \"caption\", \"duration\", \"genres\", \"keyscale\", \"language\", \"timesignature\")\n            \n        Returns:\n            Next FSMState (NAME state of next field), or THINK_END_TAG if no more fields\n        \"\"\"\n        # New field order: bpm -> caption -> duration -> keyscale -> language -> timesignature\n        # genres is optional and can be skipped\n        field_order = [\"bpm\", \"caption\", \"duration\", \"genres\", \"keyscale\", \"language\", \"timesignature\"]\n        field_to_state = {\n            \"bpm\": FSMState.BPM_NAME,\n            \"caption\": FSMState.CAPTION_NAME,\n            \"duration\": FSMState.DURATION_NAME,\n            \"genres\": FSMState.GENRES_NAME,\n            \"keyscale\": FSMState.KEYSCALE_NAME,\n            \"language\": FSMState.LANGUAGE_NAME,\n            \"timesignature\": FSMState.TIMESIG_NAME,\n        }\n        \n        try:\n            current_idx = field_order.index(current_field)\n        except ValueError:\n            return FSMState.THINK_END_TAG\n        \n        # Find next field in order\n        for i in range(current_idx + 1, len(field_order)):\n            field = field_order[i]\n            \n            # Skip fields based on flags\n            if field == \"genres\" and self.skip_genres:\n                continue\n            if field == \"caption\" and self.skip_caption:\n                continue\n            if field == \"language\" and self.skip_language:\n                continue\n            \n            # Return the next field's NAME state (even if user-provided, we still generate field name)\n            return field_to_state[field]\n        \n        # No more fields, go to THINK_END_TAG\n        return FSMState.THINK_END_TAG\n    \n    def _build_state_transitions(self):\n        \"\"\"Build state transition map based on user-provided metadata.\"\"\"\n        self.next_state = {\n            FSMState.THINK_TAG: FSMState.NEWLINE_AFTER_THINK,\n            FSMState.NEWLINE_AFTER_THINK: FSMState.BPM_NAME,  # Always start with BPM\n            FSMState.THINK_END_TAG: FSMState.CODES_GENERATION,\n            FSMState.CODES_GENERATION: FSMState.COMPLETED,\n        }\n        \n        # Build transitions for all fields (even if user-provided, we still need to generate field name)\n        # Field order: bpm -> caption -> duration -> genres -> keyscale -> language -> timesignature\n        \n        # BPM field: NAME -> VALUE -> next field (caption or duration)\n        self.next_state[FSMState.BPM_NAME] = FSMState.BPM_VALUE\n        self.next_state[FSMState.BPM_VALUE] = self._get_next_field_state(\"bpm\")\n        \n        # Caption field (only if not skipped): NAME -> VALUE -> next field (duration)\n        if not self.skip_caption:\n            self.next_state[FSMState.CAPTION_NAME] = FSMState.CAPTION_VALUE\n            self.next_state[FSMState.CAPTION_VALUE] = self._get_next_field_state(\"caption\")\n        \n        # Duration field: NAME -> VALUE -> next field\n        self.next_state[FSMState.DURATION_NAME] = FSMState.DURATION_VALUE\n        self.next_state[FSMState.DURATION_VALUE] = self._get_next_field_state(\"duration\")\n\n        # Genres field (only if not skipped): NAME -> VALUE -> next field\n        if not self.skip_genres:\n            self.next_state[FSMState.GENRES_NAME] = FSMState.GENRES_VALUE\n            self.next_state[FSMState.GENRES_VALUE] = self._get_next_field_state(\"genres\")\n        \n        # Keyscale field: NAME -> VALUE -> next field (language or timesignature)\n        self.next_state[FSMState.KEYSCALE_NAME] = FSMState.KEYSCALE_VALUE\n        self.next_state[FSMState.KEYSCALE_VALUE] = self._get_next_field_state(\"keyscale\")\n        \n        # Language field (only if not skipped): NAME -> VALUE -> next field (timesignature)\n        if not self.skip_language:\n            self.next_state[FSMState.LANGUAGE_NAME] = FSMState.LANGUAGE_VALUE\n            self.next_state[FSMState.LANGUAGE_VALUE] = self._get_next_field_state(\"language\")\n        \n        # Timesignature field: NAME -> VALUE -> THINK_END_TAG\n        self.next_state[FSMState.TIMESIG_NAME] = FSMState.TIMESIG_VALUE\n        self.next_state[FSMState.TIMESIG_VALUE] = FSMState.THINK_END_TAG\n\n    def set_skip_genres(self, skip: bool):\n        \"\"\"Set whether to skip genres generation and rebuild state transitions.\"\"\"\n        self.skip_genres = skip\n        self._build_state_transitions()\n    \n    def set_skip_caption(self, skip: bool):\n        \"\"\"Set whether to skip caption generation and rebuild state transitions.\"\"\"\n        self.skip_caption = skip\n        self._build_state_transitions()\n    \n    def set_skip_language(self, skip: bool):\n        \"\"\"Set whether to skip language generation and rebuild state transitions.\"\"\"\n        self.skip_language = skip\n        self._build_state_transitions()\n    \n    @staticmethod\n    def postprocess_caption(caption: str) -> str:\n        \"\"\"\n        Post-process caption to remove YAML multi-line formatting.\n        Converts YAML-style multi-line text (with newlines and leading spaces) \n        to a single-line string.\n        \n        Example:\n            Input:  \"An emotional ballad.\\\\n  The track opens with piano.\\\\n  More text.\"\n            Output: \"An emotional ballad. The track opens with piano. More text.\"\n        \n        Args:\n            caption: Raw caption text with possible YAML formatting\n            \n        Returns:\n            Clean single-line caption\n        \"\"\"\n        if not caption:\n            return caption\n        \n        # Split by newlines\n        lines = caption.split('\\n')\n        \n        # Process each line: strip leading/trailing whitespace\n        cleaned_lines = []\n        for line in lines:\n            stripped = line.strip()\n            if stripped:\n                cleaned_lines.append(stripped)\n        \n        # Join with single space\n        return ' '.join(cleaned_lines)\n    \n    def set_stop_at_reasoning(self, stop: bool):\n        \"\"\"\n        Set whether to stop generation after </think> tag.\n        \n        Args:\n            stop: If True, generation will stop immediately after </think> tag is generated.\n                  If False, generation continues to codes generation phase.\n        \"\"\"\n        self.stop_at_reasoning = stop\n    \n    def set_generation_phase(self, phase: str):\n        \"\"\"\n        Set the generation phase.\n        \n        Args:\n            phase: \"cot\" for CoT metadata generation, \"codes\" for audio codes generation,\n                   or \"understand\" for audio understanding (codes → metadata + lyrics).\n                   When phase is \"codes\" and the input prompt already contains </think>,\n                   the FSM will skip metadata generation and go directly to codes generation.\n                   When phase is \"understand\", generate CoT metadata then free-form lyrics.\n        \"\"\"\n        if phase not in (\"cot\", \"codes\", \"understand\"):\n            raise ValueError(f\"Invalid generation phase: {phase!r}. Must be 'cot', 'codes', or 'understand'\")\n        self.generation_phase = phase\n    \n    def set_user_metadata(self, metadata: Optional[Dict[str, Optional[str]]] = None):\n        \"\"\"\n        Set user-provided metadata fields. Fields that are provided will be used directly\n        instead of generating. Fields that are None will be generated.\n        \n        Args:\n            metadata: Dictionary with optional fields:\n                - \"bpm\": Optional[str] - e.g., \"120\"\n                - \"caption\": Optional[str] - e.g., \"A melodic piano piece...\"\n                - \"duration\": Optional[str] - e.g., \"234\"\n                - \"keyscale\": Optional[str] - e.g., \"G major\"\n                - \"language\": Optional[str] - e.g., \"en\"\n                - \"timesignature\": Optional[str] - e.g., \"4\"\n                - \"genres\": Optional[str] - e.g., \"Pop Rock\"\n                If None, clears all user-provided metadata.\n        \"\"\"\n        if metadata is None:\n            metadata = {}\n        \n        # Update user-provided metadata\n        for field in [\"bpm\", \"caption\", \"duration\", \"keyscale\", \"language\", \"timesignature\", \"genres\"]:\n            if field in metadata:\n                self.user_provided_metadata[field] = metadata[field]\n            else:\n                self.user_provided_metadata[field] = None\n        \n        # Rebuild state transitions to skip provided fields\n        self._build_state_transitions()\n        \n        if self.debug:\n            provided_fields = [k for k, v in self.user_provided_metadata.items() if v is not None]\n            if provided_fields:\n                logger.debug(f\"User provided metadata fields: {provided_fields}\")\n            else:\n                logger.debug(\"No user-provided metadata, all fields will be generated\")\n    \n    def _precompute_tokens(self):\n        \"\"\"Pre-compute commonly used token IDs for efficiency.\"\"\"\n        # Digit tokens (0-9)\n        self.digit_tokens = {}\n        for d in range(10):\n            tokens = self.tokenizer.encode(str(d), add_special_tokens=False)\n            if tokens:\n                self.digit_tokens[d] = tokens[-1]  # Take last token (in case of prefix)\n        \n        # Newline token\n        newline_tokens = self.tokenizer.encode(\"\\n\", add_special_tokens=False)\n        self.newline_token = newline_tokens[-1] if newline_tokens else None\n        \n        # Note tokens for keyscale (A-G)\n        self.note_tokens = {}\n        for note in KEYSCALE_NOTES:\n            tokens = self.tokenizer.encode(note, add_special_tokens=False)\n            if tokens:\n                self.note_tokens[note] = tokens[-1]\n        \n        # Sharp/flat tokens\n        self.sharp_tokens = []\n        for s in [\"#\", \"♯\"]:\n            tokens = self.tokenizer.encode(s, add_special_tokens=False)\n            if tokens:\n                self.sharp_tokens.append(tokens[-1])\n        \n        self.flat_tokens = []\n        for f in [\"b\", \"♭\"]:\n            tokens = self.tokenizer.encode(f, add_special_tokens=False)\n            if tokens:\n                self.flat_tokens.append(tokens[-1])\n        \n        # Space token\n        space_tokens = self.tokenizer.encode(\" \", add_special_tokens=False)\n        self.space_token = space_tokens[-1] if space_tokens else None\n        \n        # Major/minor tokens (we'll encode the full words)\n        self.major_start_tokens = []\n        self.minor_start_tokens = []\n        for prefix in [\"m\", \"M\"]:\n            tokens = self.tokenizer.encode(prefix, add_special_tokens=False)\n            if tokens:\n                if prefix.lower() == \"m\":\n                    self.minor_start_tokens.append(tokens[-1])\n                    self.major_start_tokens.append(tokens[-1])  # \"major\" also starts with m\n        \n        # Vocab size\n        self.vocab_size = len(self.tokenizer)\n\n        # Comma token for multi-genre support\n        comma_tokens = self.tokenizer.encode(\",\", add_special_tokens=False)\n        self.comma_token = comma_tokens[-1] if comma_tokens else None\n        \n        # EOS token for duration-constrained codes generation\n        self.eos_token_id = self.tokenizer.eos_token_id\n        \n        # Period token for caption field transition logic\n        period_tokens = self.tokenizer.encode(\".\", add_special_tokens=False)\n        self.period_token = period_tokens[-1] if period_tokens else None\n        \n        # Backtick tokens for blocking code blocks in caption\n        backtick_tokens = self.tokenizer.encode(\"`\", add_special_tokens=False)\n        self.backtick_token = backtick_tokens[-1] if backtick_tokens else None\n        \n        # Valid language codes (ISO 639-1 and common variants)\n        self.valid_languages = VALID_LANGUAGES\n        \n        # Precompute audio code token IDs (tokens matching <|audio_code_\\d+|>)\n        # These should be blocked during caption generation\n        self.audio_code_token_ids: Set[int] = set()\n        self._precompute_audio_code_tokens()\n        \n        # Precompute audio code mask for efficient blocking (O(1) instead of O(n))\n        # This mask will be added to scores during caption generation\n        self.audio_code_mask: Optional[torch.Tensor] = None\n        # Inverse mask: block all non-audio-code tokens (for CODES_GENERATION state)\n        self.non_audio_code_mask: Optional[torch.Tensor] = None\n        self._build_audio_code_mask()\n        \n        # Build valid keyscales set (prefix tree will be built after _char_to_tokens is initialized)\n        # 7 notes × 5 accidentals (none, #, b, ♯, ♭) × 2 modes = 70 valid combinations\n        self.valid_keyscales = VALID_KEYSCALES.copy()\n        \n        # keyscale_prefix_tree will be built in _precompute_char_token_mapping() after _char_to_tokens is ready\n        # Numeric prefix trees will be built after field_specs is defined\n    \n    def _precompute_audio_code_tokens(self):\n        \"\"\"\n        Precompute audio code token IDs (tokens matching <|audio_code_\\\\d+|>).\n        These tokens should be blocked during caption generation.\n        Only tokens with code values in range [0, MAX_AUDIO_CODE] are included.\n        \"\"\"\n        import re\n        audio_code_pattern = re.compile(r'^<\\|audio_code_(\\d+)\\|>$')\n        invalid_tokens_count = 0\n        \n        # Iterate through vocabulary to find audio code tokens\n        for token_id in range(self.vocab_size):\n            try:\n                token_text = self.tokenizer.decode([token_id])\n                match = audio_code_pattern.match(token_text)\n                if match:\n                    # Extract code value from token text\n                    code_value = int(match.group(1))\n                    # Only add tokens with valid code values (0-63999)\n                    if 0 <= code_value <= MAX_AUDIO_CODE:\n                        self.audio_code_token_ids.add(token_id)\n                    else:\n                        invalid_tokens_count += 1\n                        if self.debug:\n                            logger.debug(f\"Skipping audio code token {token_id} with invalid code value {code_value} (max: {MAX_AUDIO_CODE})\")\n            except Exception:\n                continue\n        \n        if invalid_tokens_count > 0:\n            logger.debug(f\"Found {invalid_tokens_count} audio code tokens with values outside valid range [0, {MAX_AUDIO_CODE}]\")\n        \n        # Log warning if no valid tokens found (this would prevent code generation)\n        if len(self.audio_code_token_ids) == 0:\n            logger.warning(f\"No valid audio code tokens found in vocabulary (range [0, {MAX_AUDIO_CODE}]). Code generation may fail.\")\n        elif self.debug:\n            logger.debug(f\"Found {len(self.audio_code_token_ids)} valid audio code tokens (range [0, {MAX_AUDIO_CODE}])\")\n    \n    def _extract_code_from_token(self, token_id: int) -> Optional[int]:\n        \"\"\"\n        Extract audio code value from a token ID.\n        \n        Args:\n            token_id: Token ID to extract code value from\n            \n        Returns:\n            Code value if token is a valid audio code token, None otherwise\n        \"\"\"\n        import re\n        audio_code_pattern = re.compile(r'^<\\|audio_code_(\\d+)\\|>$')\n        \n        try:\n            token_text = self.tokenizer.decode([token_id])\n            match = audio_code_pattern.match(token_text)\n            if match:\n                return int(match.group(1))\n        except Exception:\n            pass\n        \n        return None\n    \n    def _build_audio_code_mask(self):\n        \"\"\"\n        Build a precomputed mask tensor for blocking audio code tokens.\n        This mask can be added to scores in O(1) time instead of O(n) loop.\n        \n        The mask is [1, vocab_size] tensor with -inf at audio code token positions.\n        \n        Also builds the inverse mask (non_audio_code_mask) for CODES_GENERATION state,\n        which blocks all non-audio-code tokens.\n        \"\"\"\n        if not self.audio_code_token_ids:\n            self.audio_code_mask = None\n            self.non_audio_code_mask = None\n            return\n        \n        # Create mask tensor: 0 everywhere, -inf at audio code positions\n        # Use float32 for compatibility with most model dtypes\n        mask = torch.zeros(1, self.vocab_size, dtype=torch.float32)\n        \n        # Convert set to list for indexing\n        audio_code_indices = list(self.audio_code_token_ids)\n        \n        # Set -inf at audio code token positions\n        mask[0, audio_code_indices] = float('-inf')\n        \n        self.audio_code_mask = mask\n        \n        # Build inverse mask: -inf everywhere EXCEPT at audio code positions\n        # This is used in CODES_GENERATION state to only allow audio codes\n        inverse_mask = torch.full((1, self.vocab_size), float('-inf'), dtype=torch.float32)\n        inverse_mask[0, audio_code_indices] = 0\n        \n        # Also allow EOS token in codes generation (will be controlled by duration constraint)\n        if self.eos_token_id is not None:\n            inverse_mask[0, self.eos_token_id] = 0\n        \n        self.non_audio_code_mask = inverse_mask\n        \n        if self.debug:\n            logger.debug(f\"Built audio code masks for {len(self.audio_code_token_ids)} tokens\")\n\n    def _apply_whitelist_inplace(self, scores: torch.Tensor, allowed_tokens: List[int]) -> None:\n        \"\"\"\n        Apply whitelist constraint inplace: only allow specified tokens, block all others.\n        \n        This is more efficient than creating a mask tensor because:\n        1. No memory allocation for mask\n        2. No tensor addition operation\n        \n        Args:\n            scores: [1, vocab_size] scores tensor to modify inplace\n            allowed_tokens: List of token IDs to allow (all others will be set to -inf)\n        \"\"\"\n        if not allowed_tokens:\n            # No tokens allowed, set all to -inf\n            scores.fill_(float('-inf'))\n            return\n        \n        # Save the original values of allowed tokens\n        allowed_indices = torch.tensor(allowed_tokens, device=scores.device, dtype=torch.long)\n        saved_values = scores[0, allowed_indices].clone()\n        \n        # Set all scores to -inf\n        scores.fill_(float('-inf'))\n        \n        # Restore allowed token values\n        scores[0, allowed_indices] = saved_values\n\n    def _build_keyscale_prefix_tree(self) -> Dict[Tuple[int, ...], Set[int]]:\n        \"\"\"\n        Build keyscale prefix to allowed tokens mapping based on ACTUAL tokenization.\n        \n        IMPORTANT: Uses token ID sequences as keys, NOT strings, to avoid tokenization mismatches.\n        \n        CRITICAL FIX: The tokenizer may merge the context's trailing space into the next token.\n        For example:\n        - \"keyscale: \" tokenizes to [10563, 2246, 25, 220] -> ['keys', 'cale', ':', ' ']\n        - \"keyscale: G major\" tokenizes to [10563, 2246, 25, 479, 3598] -> ['keys', 'cale', ':', ' G', ' major']\n        The space ' ' (220) is merged into ' G' (479), so we can't use simple slicing.\n        \n        Strategy:\n        1. For each keyscale (e.g., \"G major\"), encode the FULL string \"keyscale: G major\"\n        2. Tokenize to get: [10563, 2246, 25, 479, 3598] -> ['keys', 'cale', ':', ' G', ' major']\n        3. Find where context prefix ends by matching token sequences (handling space merging)\n        4. Extract keyscale value tokens: [479, 3598] (for \"G major\")\n        5. Build prefix tree using token ID sequences as keys\n        \n        This ensures we get the exact tokenization that occurs during generation.\n        \"\"\"\n        prefix_to_tokens: Dict[Tuple[int, ...], Set[int]] = {}\n        \n        # Context prefix that appears before keyscale value\n        # IMPORTANT: The state machine generates \"keyscale:\" (no space), but when tokenizing\n        # the full string \"keyscale: G major\", the tokenizer includes space, so we need to\n        # match the actual tokenization behavior.\n        # \n        # Strategy:\n        # 1. Use \"keyscale:\" (no space) to match the state machine's output\n        # 2. But when building prefix tree, use \"keyscale: \" (with space) + keyscale to match actual tokenization\n        context_prefix_for_matching = \"keyscale:\"  # What state machine generates\n        context_prefix_for_tokenization = \"keyscale: \"  # What tokenizer sees in full string\n        \n        # First, tokenize the context (without space) to know its token sequence for matching\n        context_token_ids = self.tokenizer.encode(context_prefix_for_matching, add_special_tokens=False)\n        \n        if self.debug:\n            context_tokens_str = [self.tokenizer.decode([t]) for t in context_token_ids]\n            logger.debug(f\"Context for matching 'keyscale:' tokenizes to {context_token_ids} -> {context_tokens_str}\")\n        \n        # For each valid keyscale, encode full string and extract value tokens\n        for keyscale in self.valid_keyscales:\n            # Step 1: Encode full string \"keyscale: {keyscale}\" (with space, as tokenizer sees it)\n            full_text = context_prefix_for_tokenization + keyscale\n            full_token_ids = self.tokenizer.encode(full_text, add_special_tokens=False)\n            \n            # Step 2: Find where context ends in full_token_ids\n            # We match using context_prefix_for_matching (\"keyscale:\") token sequence\n            # because that's what the state machine actually generates\n            context_end_idx = None\n            \n            # Try exact prefix match using context_prefix_for_matching token sequence\n            if len(full_token_ids) >= len(context_token_ids):\n                if full_token_ids[:len(context_token_ids)] == context_token_ids:\n                    context_end_idx = len(context_token_ids)\n            \n            if context_end_idx is None:\n                if self.debug:\n                    logger.warning(f\"Could not find context prefix in full tokenization of '{full_text}', skipping\")\n                continue\n            \n            # Step 3: Extract keyscale value tokens (everything after context)\n            keyscale_token_ids = full_token_ids[context_end_idx:]\n            \n            # Step 4: Verify we extracted some tokens (sanity check)\n            if not keyscale_token_ids:\n                if self.debug:\n                    logger.warning(f\"No tokens extracted for keyscale '{keyscale}', skipping\")\n                continue\n            \n            # Step 5: Verify first token is a note (A-G)\n            # This is critical: the first token of keyscale value must be a note\n            first_token_id = keyscale_token_ids[0]\n            first_token_str = self.tokenizer.decode([first_token_id])\n            # Check if first token starts with a note (A-G, case insensitive, with optional leading space)\n            first_char = first_token_str.lstrip()[0].upper() if first_token_str.lstrip() else \"\"\n            if first_char not in \"ABCDEFG\":\n                # This keyscale's first token is not a note - skip it\n                if self.debug:\n                    logger.debug(f\"Skipping keyscale '{keyscale}': first token is '{first_token_str}' (id={first_token_id}), not a note\")\n                continue\n            \n            # Step 6: Build prefix mappings from keyscale value tokens\n            # Use token ID sequences as keys (not strings) to avoid tokenization mismatches\n            for i in range(len(keyscale_token_ids) + 1):\n                # Current token sequence prefix (empty tuple for start)\n                token_prefix = tuple(keyscale_token_ids[:i])\n                \n                if token_prefix not in prefix_to_tokens:\n                    prefix_to_tokens[token_prefix] = set()\n                \n                if i < len(keyscale_token_ids):\n                    # Add next token as allowed for current prefix\n                    next_token_id = keyscale_token_ids[i]\n                    prefix_to_tokens[token_prefix].add(next_token_id)\n                else:\n                    # Complete keyscale should allow newline\n                    if self.newline_token:\n                        prefix_to_tokens[token_prefix].add(self.newline_token)\n        \n        if self.debug:\n            logger.debug(f\"Built keyscale prefix tree with {len(prefix_to_tokens)} token sequence prefixes\")\n            # Check empty prefix (start of keyscale value)\n            empty_prefix = tuple()\n            if empty_prefix in prefix_to_tokens:\n                first_tokens = prefix_to_tokens[empty_prefix]\n                decoded_first = [(t, repr(self.tokenizer.decode([t]))) for t in sorted(first_tokens)]\n                logger.debug(f\"First tokens allowed (empty prefix): {decoded_first}\")\n        \n        return prefix_to_tokens\n    \n    def _build_numeric_prefix_tree(\n        self, \n        valid_values: List[str], \n        context_prefix_for_matching: str = \"\",\n        context_prefix_for_tokenization: str = \"\"\n    ) -> Dict[Tuple[int, ...], Set[int]]:\n        \"\"\"\n        Build prefix tree for numeric field based on actual tokenization with context.\n        \n        IMPORTANT: Uses token ID sequences as keys, NOT strings, to avoid tokenization mismatches.\n        \n        Args:\n            valid_values: List of valid numeric strings (e.g., [\"30\", \"31\", ..., \"300\"])\n            context_prefix_for_matching: Context string that state machine generates (e.g., \"bpm:\") - no space\n            context_prefix_for_tokenization: Context string for tokenization (e.g., \"bpm: \") - with space\n            \n        Returns:\n            Dict mapping token ID sequence prefix -> set of allowed token IDs\n        \"\"\"\n        prefix_to_tokens: Dict[Tuple[int, ...], Set[int]] = {}\n        \n        # Encode context for matching (what state machine generates, no space)\n        context_token_ids = self.tokenizer.encode(context_prefix_for_matching, add_special_tokens=False) if context_prefix_for_matching else []\n        \n        # For each valid value, encode it with context and build prefix mappings\n        for value_str in valid_values:\n            # Encode value WITH context (with space) to match actual tokenization\n            full_text = context_prefix_for_tokenization + value_str\n            token_ids = self.tokenizer.encode(full_text, add_special_tokens=False)\n            \n            # Find where context ends in full_token_ids using context_prefix_for_matching token sequence\n            context_end_idx = None\n            if len(token_ids) >= len(context_token_ids):\n                if token_ids[:len(context_token_ids)] == context_token_ids:\n                    context_end_idx = len(context_token_ids)\n            \n            if context_end_idx is None:\n                if self.debug:\n                    logger.warning(f\"Could not find context prefix in full tokenization of '{full_text}', skipping\")\n                continue\n            \n            # Extract only tokens that belong to the value itself (skip context tokens)\n            value_token_ids = token_ids[context_end_idx:]\n            \n            # Build prefix mappings using token ID sequences as keys\n            for i in range(len(value_token_ids) + 1):\n                # Current token sequence prefix (empty tuple for start)\n                token_prefix = tuple(value_token_ids[:i])\n                \n                if token_prefix not in prefix_to_tokens:\n                    prefix_to_tokens[token_prefix] = set()\n                \n                if i < len(value_token_ids):\n                    # Add next token as allowed for current prefix\n                    next_token_id = value_token_ids[i]\n                    prefix_to_tokens[token_prefix].add(next_token_id)\n                else:\n                    # Complete value should allow newline\n                    if self.newline_token:\n                        prefix_to_tokens[token_prefix].add(self.newline_token)\n        \n        return prefix_to_tokens\n    \n    def _build_language_prefix_tree(self) -> Dict[Tuple[int, ...], Set[int]]:\n        \"\"\"\n        Build language prefix to allowed tokens mapping based on ACTUAL tokenization.\n        Similar to keyscale prefix tree but for language codes.\n        \n        Uses token ID sequences as keys, NOT strings, to avoid tokenization mismatches.\n        \"\"\"\n        prefix_to_tokens: Dict[Tuple[int, ...], Set[int]] = {}\n        \n        context_prefix_for_matching = \"language:\"\n        context_prefix_for_tokenization = \"language: \"\n        \n        context_token_ids = self.tokenizer.encode(context_prefix_for_matching, add_special_tokens=False)\n        \n        if self.debug:\n            context_tokens_str = [self.tokenizer.decode([t]) for t in context_token_ids]\n            logger.debug(f\"Context for matching 'language:' tokenizes to {context_token_ids} -> {context_tokens_str}\")\n        \n        for lang in self.valid_languages:\n            full_text = context_prefix_for_tokenization + lang\n            full_token_ids = self.tokenizer.encode(full_text, add_special_tokens=False)\n            \n            context_end_idx = None\n            if len(full_token_ids) >= len(context_token_ids):\n                if full_token_ids[:len(context_token_ids)] == context_token_ids:\n                    context_end_idx = len(context_token_ids)\n            \n            if context_end_idx is None:\n                if self.debug:\n                    logger.warning(f\"Could not find context prefix in full tokenization of '{full_text}', skipping\")\n                continue\n            \n            lang_token_ids = full_token_ids[context_end_idx:]\n            \n            if not lang_token_ids:\n                if self.debug:\n                    logger.warning(f\"No tokens extracted for language '{lang}', skipping\")\n                continue\n            \n            for i in range(len(lang_token_ids) + 1):\n                token_prefix = tuple(lang_token_ids[:i])\n                \n                if token_prefix not in prefix_to_tokens:\n                    prefix_to_tokens[token_prefix] = set()\n                \n                if i < len(lang_token_ids):\n                    next_token_id = lang_token_ids[i]\n                    prefix_to_tokens[token_prefix].add(next_token_id)\n                else:\n                    if self.newline_token:\n                        prefix_to_tokens[token_prefix].add(self.newline_token)\n        \n        if self.debug:\n            logger.debug(f\"Built language prefix tree with {len(prefix_to_tokens)} token sequence prefixes\")\n            empty_prefix = tuple()\n            if empty_prefix in prefix_to_tokens:\n                first_tokens = prefix_to_tokens[empty_prefix]\n                decoded_first = [(t, repr(self.tokenizer.decode([t]))) for t in sorted(first_tokens)]\n                logger.debug(f\"First tokens allowed for language (empty prefix): {decoded_first}\")\n        \n        return prefix_to_tokens\n    \n    def diagnose_keyscale_prefix_tree(self):\n        \"\"\"\n        Diagnose the keyscale prefix tree to help debug generation bias.\n        Call this method to print detailed information about allowed tokens at each prefix.\n        \"\"\"\n        print(\"=\" * 60)\n        print(\"KEYSCALE PREFIX TREE DIAGNOSIS\")\n        print(\"=\" * 60)\n        \n        # Check empty prefix (first token)\n        if \"\" in self.keyscale_prefix_tree:\n            first_tokens = self.keyscale_prefix_tree[\"\"]\n            print(f\"\\n[Empty prefix] Allowed first tokens ({len(first_tokens)} total):\")\n            for t in sorted(first_tokens):\n                decoded = self.tokenizer.decode([t])\n                print(f\"  Token {t}: {repr(decoded)}\")\n        else:\n            print(\"\\nWARNING: Empty prefix not in tree!\")\n        \n        # Check some common prefixes\n        test_prefixes = [\"A\", \"B\", \"C\", \"D\", \"E\", \"F\", \"G\"]\n        for prefix in test_prefixes:\n            # Try both with and without potential tokenizer artifacts\n            for test_key in [prefix, prefix + \" \"]:\n                if test_key in self.keyscale_prefix_tree:\n                    tokens = self.keyscale_prefix_tree[test_key]\n                    print(f\"\\n[Prefix {repr(test_key)}] Allowed tokens ({len(tokens)}):\")\n                    for t in sorted(tokens):\n                        decoded = self.tokenizer.decode([t])\n                        print(f\"  Token {t}: {repr(decoded)}\")\n        \n        # Show some complete keyscales that should be valid\n        print(f\"\\n[Valid keyscales] Total: {len(self.valid_keyscales)}\")\n        sample = sorted(list(self.valid_keyscales))[:10]\n        for ks in sample:\n            print(f\"  {repr(ks)}\")\n        \n        print(\"=\" * 60)\n\n    \n    def _load_genres_vocab(self):\n        \"\"\"\n        Load genres vocabulary from file. Supports hot reload by checking file mtime.\n        File format: one genre per line, lines starting with # are comments.\n        \"\"\"\n        if not os.path.exists(self.genres_vocab_path):\n            if self.debug:\n                logger.debug(f\"Genres vocab file not found: {self.genres_vocab_path}\")\n            return\n        \n        try:\n            mtime = os.path.getmtime(self.genres_vocab_path)\n            if mtime <= self.genres_vocab_mtime:\n                return  # File hasn't changed\n            \n            with open(self.genres_vocab_path, 'r', encoding='utf-8') as f:\n                genres = []\n                for line in f:\n                    line = line.strip()\n                    if line and not line.startswith('#'):\n                        genres.append(line.lower())\n                \n                self.genres_vocab = genres\n                self.genres_vocab_mtime = mtime\n                self._build_genres_trie()\n                \n                if self.debug:\n                    logger.debug(f\"Loaded {len(self.genres_vocab)} genres from {self.genres_vocab_path}\")\n        except Exception as e:\n            logger.warning(f\"Failed to load genres vocab: {e}\")\n    \n    def _build_genres_trie(self):\n        \"\"\"\n        Build a trie (prefix tree) from genres vocabulary for efficient prefix matching.\n        Each node is a dict with:\n          - '_end': True if this node represents a complete genre\n          - other keys: next characters in the trie\n        \"\"\"\n        self.genres_trie = {}\n        \n        for genre in self.genres_vocab:\n            node = self.genres_trie\n            for char in genre:\n                if char not in node:\n                    node[char] = {}\n                node = node[char]\n            node['_end'] = True  # Mark end of a complete genre\n        \n        if self.debug:\n            logger.debug(f\"Built genres trie with {len(self.genres_vocab)} entries\")\n    \n    def _extract_caption_genres(self, caption: str):\n        \"\"\"\n        Extract genres from the user's caption that match entries in the vocabulary.\n        This creates a smaller trie for faster and more relevant genre generation.\n        \n        Strategy (optimized - O(words * max_genre_len) instead of O(vocab_size)):\n        1. Extract words/phrases from caption\n        2. For each word, use trie to find all vocab entries that START with this word\n        3. Build a separate trie from matched genres\n        \"\"\"\n        if not caption or not self.genres_vocab:\n            return\n        \n        caption_lower = caption.lower()\n        matched_genres = set()\n        \n        # Extract words from caption (split by common delimiters)\n        import re\n        words = re.split(r'[,\\s\\-_/\\\\|]+', caption_lower)\n        words = [w.strip() for w in words if w.strip() and len(w.strip()) >= 2]\n        \n        # For each word, find genres in trie that start with this word\n        for word in words:\n            # Find all genres starting with this word using trie traversal\n            node = self._get_genres_trie_node(word)\n            if node is not None:\n                # Collect all complete genres under this node\n                self._collect_complete_genres(node, word, matched_genres)\n        \n        # Also check if any word appears as a substring in short genres (< 20 chars)\n        # This is a quick check for common single-word genres\n        genres_set = set(self.genres_vocab)\n        for word in words:\n            if word in genres_set:\n                matched_genres.add(word)\n        \n        if not matched_genres:\n            if self.debug:\n                logger.debug(f\"No genres matched in caption, using full vocab\")\n            return\n        \n        # Build a trie from matched genres\n        self.caption_matched_genres = list(matched_genres)\n        self.caption_genres_trie = {}\n        \n        for genre in matched_genres:\n            node = self.caption_genres_trie\n            for char in genre:\n                if char not in node:\n                    node[char] = {}\n                node = node[char]\n            node['_end'] = True\n        \n        if self.debug:\n            logger.debug(f\"Matched {len(matched_genres)} genres from caption: {list(matched_genres)[:5]}...\")\n    \n    def _collect_complete_genres(self, node: Dict, prefix: str, result: set, max_depth: int = 50):\n        \"\"\"\n        Recursively collect all complete genres under a trie node.\n        Limited depth to avoid too many matches.\n        \"\"\"\n        if max_depth <= 0:\n            return\n        \n        if node.get('_end', False):\n            result.add(prefix)\n        \n        # Limit total collected genres to avoid slowdown\n        if len(result) >= 100:\n            return\n        \n        for char, child_node in node.items():\n            if char not in ('_end', '_tokens'):\n                self._collect_complete_genres(child_node, prefix + char, result, max_depth - 1)\n    \n    def _precompute_char_token_mapping(self):\n        \"\"\"\n        Precompute mapping from characters to token IDs and token decoded texts.\n        This allows O(1) lookup instead of calling tokenizer.encode()/decode() at runtime.\n        \n        Time complexity: O(vocab_size) - runs once during initialization\n        \n        Note: Many subword tokenizers (like Qwen) add space prefixes to tokens.\n        We need to handle both the raw first char and the first non-space char.\n        \"\"\"\n        self._char_to_tokens: Dict[str, set] = {}\n        self._token_to_text: Dict[int, str] = {}  # Precomputed decoded text for each token\n        \n        # For each token in vocabulary, get its decoded text\n        for token_id in range(self.vocab_size):\n            try:\n                text = self.tokenizer.decode([token_id])\n                \n                if not text:\n                    continue\n                \n                # Store the decoded text (normalized to lowercase)\n                # Keep leading spaces for proper concatenation (e.g., \" rock\" in \"pop rock\")\n                # Only rstrip trailing whitespace, unless it's a pure whitespace token\n                text_lower = text.lower()\n                if text_lower.strip():  # Has non-whitespace content\n                    normalized_text = text_lower.rstrip()\n                else:  # Pure whitespace token\n                    normalized_text = \" \"  # Normalize to single space\n                self._token_to_text[token_id] = normalized_text\n                \n                # Map first character (including space) to this token\n                first_char = text[0].lower()\n                if first_char not in self._char_to_tokens:\n                    self._char_to_tokens[first_char] = set()\n                self._char_to_tokens[first_char].add(token_id)\n                \n                # Also map first non-space character to this token\n                # This handles tokenizers that add space prefixes (e.g., \" pop\" -> maps to 'p')\n                stripped_text = text.lstrip()\n                if stripped_text and stripped_text != text:\n                    first_nonspace_char = stripped_text[0].lower()\n                    if first_nonspace_char not in self._char_to_tokens:\n                        self._char_to_tokens[first_nonspace_char] = set()\n                    self._char_to_tokens[first_nonspace_char].add(token_id)\n                    \n            except Exception:\n                continue\n        \n        if self.debug:\n            logger.debug(f\"Precomputed char->token mapping for {len(self._char_to_tokens)} unique characters\")\n    \n    def _try_reload_genres_vocab(self):\n        \"\"\"Check if genres vocab file has been updated and reload if necessary.\"\"\"\n        if not os.path.exists(self.genres_vocab_path):\n            return\n        \n        try:\n            mtime = os.path.getmtime(self.genres_vocab_path)\n            if mtime > self.genres_vocab_mtime:\n                self._load_genres_vocab()\n        except Exception:\n            pass  # Ignore errors during hot reload check\n    \n    def _get_genres_trie_node(self, prefix: str) -> Optional[Dict]:\n        \"\"\"\n        Get the trie node for a given prefix.\n        Returns None if the prefix is not valid (no genres start with this prefix).\n        \"\"\"\n        node = self.genres_trie\n        for char in prefix.lower():\n            if char not in node:\n                return None\n            node = node[char]\n        return node\n    \n    def _is_complete_genre(self, text: str) -> bool:\n        \"\"\"Check if the given text is a complete genre in the vocabulary.\"\"\"\n        node = self._get_genres_trie_node(text.strip())\n        return node is not None and node.get('_end', False)\n    \n    def _get_trie_node_from_trie(self, trie: Dict, prefix: str) -> Optional[Dict]:\n        \"\"\"Get a trie node from a specific trie (helper for caption vs full trie).\"\"\"\n        node = trie\n        for char in prefix.lower():\n            if char not in node:\n                return None\n            node = node[char]\n        return node\n\n    def _get_allowed_genres_tokens(self) -> List[int]:\n        \"\"\"\n        Get allowed tokens for genres field based on trie matching.\n        \n        The entire genres string (including commas) must match a complete entry in the vocab.\n        For example, if vocab contains \"pop, rock, jazz\", the generated string must exactly\n        match that entry - we don't treat commas as separators for individual genres.\n        \n        Strategy:\n        1. If caption-matched genres exist, use that smaller trie first (faster + more relevant)\n        2. If no caption matches or prefix not in caption trie, fallback to full vocab trie\n        3. Get valid next characters from current trie node\n        4. For each candidate token, verify the full decoded text forms a valid trie prefix\n        \"\"\"\n        if not self.genres_vocab:\n            # No vocab loaded, allow all except newline if empty\n            return []\n        \n        # Use the full accumulated value (don't split by comma - treat as single entry)\n        accumulated = self.accumulated_value.lower()\n        current_genre_prefix = accumulated.strip()\n        \n        # Determine which trie to use: caption-matched (priority) or full vocab (fallback)\n        use_caption_trie = False\n        current_node = None\n        \n        # Try caption-matched trie first if available\n        if self.caption_genres_trie:\n            if current_genre_prefix == \"\":\n                current_node = self.caption_genres_trie\n                use_caption_trie = True\n            else:\n                current_node = self._get_trie_node_from_trie(self.caption_genres_trie, current_genre_prefix)\n                if current_node is not None:\n                    use_caption_trie = True\n        \n        # Fallback to full vocab trie\n        if current_node is None:\n            if current_genre_prefix == \"\":\n                current_node = self.genres_trie\n            else:\n                current_node = self._get_genres_trie_node(current_genre_prefix)\n        \n        if current_node is None:\n            # Invalid prefix, force newline to end\n            if self.newline_token:\n                return [self.newline_token]\n            return []\n        \n        # Get valid next characters from trie node\n        valid_next_chars = set(k for k in current_node.keys() if k not in ('_end', '_tokens'))\n        \n        # If current value is a complete genre, allow newline to end\n        is_complete = current_node.get('_end', False)\n        \n        if not valid_next_chars:\n            # No more characters to match, only allow newline if complete\n            allowed = set()\n            if is_complete and self.newline_token:\n                allowed.add(self.newline_token)\n            return list(allowed)\n        \n        # Collect candidate tokens based on first character\n        candidate_tokens = set()\n        for char in valid_next_chars:\n            if char in self._char_to_tokens:\n                candidate_tokens.update(self._char_to_tokens[char])\n        \n        # Select the appropriate trie for validation\n        active_trie = self.caption_genres_trie if use_caption_trie else self.genres_trie\n        \n        # Validate each candidate token: check if prefix + decoded_token is a valid trie prefix\n        allowed = set()\n        for token_id in candidate_tokens:\n            # Use precomputed decoded text (already normalized)\n            decoded_normalized = self._token_to_text.get(token_id, \"\")\n            \n            if not decoded_normalized or not decoded_normalized.strip():\n                # Token decodes to empty or only whitespace - allow if space/comma is a valid next char\n                if ' ' in valid_next_chars or ',' in valid_next_chars:\n                    allowed.add(token_id)\n                continue\n            \n            # Build new prefix by appending decoded token\n            # Handle space-prefixed tokens (e.g., \" rock\" from \"pop rock\")\n            if decoded_normalized.startswith(' ') or decoded_normalized.startswith(','):\n                # Token has leading space/comma - append directly\n                new_prefix = current_genre_prefix + decoded_normalized\n            else:\n                new_prefix = current_genre_prefix + decoded_normalized\n            \n            # Check if new_prefix is a valid prefix in the active trie\n            new_node = self._get_trie_node_from_trie(active_trie, new_prefix)\n            if new_node is not None:\n                allowed.add(token_id)\n        \n        # If current value is a complete genre, also allow newline\n        if is_complete and self.newline_token:\n            allowed.add(self.newline_token)\n        \n        return list(allowed)\n    \n    def reset(self):\n        \"\"\"Reset the processor state for a new generation.\"\"\"\n        self.state = FSMState.THINK_TAG\n        self.position_in_state = 0\n        self.accumulated_value = \"\"  # Legacy, kept for compatibility\n        self.accumulated_token_ids = []  # Reset token ID sequence\n        self.codes_count = 0  # Reset codes counter\n        self.user_field_token_queue = []  # Reset user field token queue\n        self.current_user_field = None  # Reset current user field\n        self.caption_after_newline = False  # Reset caption newline tracking\n        self.caption_token_count = 0  # Reset caption token count\n        self.caption_ending = False  # Reset caption ending tracking\n        self.pending_field_name = \"\"  # Reset pending field name\n    \n    def set_target_duration(self, duration: Optional[float]):\n        \"\"\"\n        Set the target duration for codes generation.\n        \n        Args:\n            duration: Target duration in seconds. If None, no duration constraint is applied.\n                     5 codes = 1 second, so target_codes = duration * 5.\n        \"\"\"\n        self.target_duration = duration\n        if duration is not None and duration > 0:\n            self.target_codes = int(duration * 5)\n            if self.debug:\n                logger.debug(f\"Set target duration: {duration}s -> {self.target_codes} codes\")\n        else:\n            self.target_codes = None\n            if self.debug:\n                logger.debug(\"Target duration cleared, no duration constraint\")\n    \n    def set_max_duration(self, max_duration: int):\n        \"\"\"\n        Dynamically update the maximum allowed duration for constrained decoding.\n        \n        This method should be called when GPU configuration changes (e.g., LM initialization state changes).\n        It rebuilds the duration prefix tree to constrain duration values to the new maximum.\n        \n        Args:\n            max_duration: Maximum duration in seconds (e.g., 120 for 2 minutes, 360 for 6 minutes)\n        \"\"\"\n        if max_duration == self.max_duration:\n            return  # No change needed\n        \n        old_max = self.max_duration\n        self.max_duration = max_duration\n        \n        # Update field specs\n        self.field_specs[\"duration\"][\"max\"] = max_duration\n        \n        # Rebuild valid duration values\n        self.valid_duration_values = [str(v) for v in range(self.field_specs[\"duration\"][\"min\"], self.field_specs[\"duration\"][\"max\"] + 1)]\n        \n        # Rebuild duration prefix tree\n        self.duration_prefix_tree = self._build_numeric_prefix_tree(\n            self.valid_duration_values,\n            context_prefix_for_matching=\"duration:\",\n            context_prefix_for_tokenization=\"duration: \"\n        )\n        \n        if self.debug:\n            logger.debug(f\"Updated max duration: {old_max}s -> {max_duration}s, rebuilt prefix tree with {len(self.valid_duration_values)} values\")\n    \n    def _get_allowed_tokens_for_fixed_string(self, fixed_str: str) -> List[int]:\n        \"\"\"\n        Get the token IDs that can continue the fixed string from current position.\n        Returns list of allowed token IDs.\n        \n        Strategy: Find the longest prefix that encodes to a single token, and return that token.\n        This ensures we generate by tokens, not character-by-character.\n        \"\"\"\n        remaining = fixed_str[self.position_in_state:]\n        if not remaining:\n            return []\n        \n        if self.debug:\n            logger.debug(f\"_get_allowed_tokens_for_fixed_string: fixed_str={repr(fixed_str)}, position_in_state={self.position_in_state}, remaining={repr(remaining)}\")\n        \n        # Try encoding progressively longer prefixes, from longest to shortest\n        # We want to find the longest prefix that encodes to a single token\n        best_token = None\n        best_prefix_len = 0\n        \n        # First pass: find the longest prefix that encodes to exactly one token\n        for end in range(len(remaining), 0, -1):  # Start from longest prefix\n            prefix = remaining[:end]\n            tokens = self.tokenizer.encode(prefix, add_special_tokens=False)\n            if tokens and len(tokens) == 1:\n                # Found a prefix that encodes to a single token\n                # Use this one (longest match)\n                best_token = tokens[0]\n                best_prefix_len = end\n                if self.debug:\n                    logger.debug(f\"Found single-token match: prefix={repr(prefix)}, token_id={best_token}, token_text={repr(self.tokenizer.decode([best_token]))}\")\n                break\n        \n        # If we found a single-token match, return it (this is the preferred case)\n        if best_token is not None:\n            return [best_token]\n        \n        # Fallback: if no single-token match found, collect all possible first tokens\n        # This handles edge cases where the string might need multiple tokens\n        # But we still want to prefer longer matches\n        # IMPORTANT: Only consider tokens that actually match the beginning of remaining string\n        # Decode each candidate token and verify it matches the prefix\n        allowed_tokens = {}\n        for end in range(1, min(len(remaining) + 1, 20)):  # Limit search to avoid too many iterations\n            prefix = remaining[:end]\n            tokens = self.tokenizer.encode(prefix, add_special_tokens=False)\n            if tokens:\n                first_token = tokens[0]\n                # Verify: decode the token and check it matches the prefix start\n                decoded_token = self.tokenizer.decode([first_token])\n                # Normalize both for comparison (strip and lower)\n                normalized_prefix = prefix.lstrip().lower()\n                normalized_decoded = decoded_token.lstrip().lower()\n                \n                # Check if decoded token matches the prefix start (allowing for space prefixes)\n                if normalized_decoded.startswith(normalized_prefix) or normalized_prefix.startswith(normalized_decoded):\n                    # Store the longest prefix length for each token\n                    if first_token not in allowed_tokens or end > allowed_tokens[first_token]:\n                        allowed_tokens[first_token] = end\n        \n        # Return tokens sorted by prefix length (longest first)\n        # This ensures we prefer longer matches\n        sorted_tokens = sorted(allowed_tokens.items(), key=lambda x: x[1], reverse=True)\n        result = [token for token, _ in sorted_tokens] if sorted_tokens else []\n        \n        if self.debug:\n            logger.debug(f\"Fallback: returning {len(result)} tokens: {[(t, repr(self.tokenizer.decode([t]))) for t in result[:5]]}\")\n            if result:\n                logger.debug(f\"Fixed string: {repr(fixed_str)}, position: {self.position_in_state}, remaining: {repr(remaining)}\")\n        \n        return result\n    \n    def _get_allowed_digit_tokens(self, min_val: int, max_val: int) -> List[int]:\n        \"\"\"\n        Get allowed digit tokens based on accumulated value and range constraints.\n        Uses early-blocking to prevent out-of-range values.\n        \"\"\"\n        if not self.accumulated_value:\n            # First digit: determine valid starting digits\n            allowed_digits = set()\n            for v in range(min_val, max_val + 1):\n                allowed_digits.add(int(str(v)[0]))\n            return [self.digit_tokens[d] for d in allowed_digits if d in self.digit_tokens]\n        \n        current = int(self.accumulated_value)\n        allowed = []\n        \n        for d in range(10):\n            new_value = int(self.accumulated_value + str(d))\n            # Check if this digit could lead to a valid final value\n            # A digit is valid if:\n            # 1. new_value <= max_val (not already exceeded)\n            # 2. new_value could potentially reach >= min_val\n            #    (i.e., new_value * 10^k >= min_val for some k >= 0)\n            \n            if new_value > max_val:\n                continue  # Already exceeded max\n            \n            # Check if we can still reach min_val\n            # If new_value is already >= min_val, it's valid\n            # If new_value < min_val, we need more digits, but new_value * 10 must not exceed max\n            if new_value >= min_val:\n                allowed.append(d)\n            elif new_value * 10 <= max_val:\n                # Can add more digits\n                allowed.append(d)\n        \n        return [self.digit_tokens[d] for d in allowed if d in self.digit_tokens]\n    \n    def _get_allowed_numeric_tokens(self, prefix_tree: Dict[Tuple[int, ...], Set[int]]) -> List[int]:\n        \"\"\"\n        Get allowed tokens for numeric field using the precomputed prefix tree.\n        \n        IMPORTANT: Uses token ID sequence as key (not string) to avoid tokenization mismatches.\n        \n        Args:\n            prefix_tree: Precomputed prefix tree mapping token ID sequence -> set of allowed token IDs\n            \n        Returns:\n            List of allowed token IDs for current accumulated_token_ids\n        \"\"\"\n        token_prefix = tuple(self.accumulated_token_ids)\n        \n        if token_prefix in prefix_tree:\n            return list(prefix_tree[token_prefix])\n        \n        # No valid continuation found - return empty list\n        # The caller will handle this by forcing newline to end the field\n        return []\n    \n    def _should_end_numeric_field(self, logits: torch.Tensor, min_val: int, max_val: int) -> bool:\n        \"\"\"\n        Determine if we should end the current numeric field.\n        Returns True if P(newline) > P(any valid digit) AND current value is valid.\n        \"\"\"\n        if not self.accumulated_value:\n            return False\n        \n        current = int(self.accumulated_value)\n        if current < min_val or current > max_val:\n            return False  # Can't end yet, value not in range\n        \n        # Get probabilities\n        probs = torch.softmax(logits, dim=-1)\n        \n        newline_prob = probs[0, self.newline_token].item() if self.newline_token else 0\n        \n        # Get max probability among valid digit tokens\n        allowed_digits = self._get_allowed_digit_tokens(min_val, max_val)\n        if not allowed_digits:\n            return True  # No more digits possible, must end\n        \n        max_digit_prob = max(probs[0, t].item() for t in allowed_digits)\n        \n        if self.debug:\n            logger.debug(f\"Numeric field decision: newline_prob={newline_prob:.4f}, max_digit_prob={max_digit_prob:.4f}\")\n        \n        return newline_prob > max_digit_prob\n\n    \n    def _should_end_text_field(self, logits: torch.Tensor) -> bool:\n        \"\"\"\n        Determine if we should end a text field (genres).\n        Returns True if P(newline) > P(any other token) AND we have some content.\n        \"\"\"\n        if not self.accumulated_value.strip():\n            return False  # Need at least some content\n        \n        probs = torch.softmax(logits, dim=-1)\n        newline_prob = probs[0, self.newline_token].item() if self.newline_token else 0\n        \n        # Get max probability among non-newline tokens\n        masked_probs = probs.clone()\n        if self.newline_token:\n            masked_probs[0, self.newline_token] = 0\n        max_other_prob = masked_probs[0].max().item()\n        \n        return newline_prob > max_other_prob\n    \n    def _get_allowed_keyscale_tokens(self) -> List[int]:\n        \"\"\"\n        Get allowed tokens for keyscale field using the precomputed prefix tree.\n        Uses token ID sequence as key (not string) to avoid tokenization mismatches.\n        \"\"\"\n        # Use token ID sequence as key\n        token_prefix = tuple(self.accumulated_token_ids)\n        \n        if token_prefix in self.keyscale_prefix_tree:\n            return list(self.keyscale_prefix_tree[token_prefix])\n        \n        # Fallback: if we somehow drifted off (shouldn't happen with constrained decoding),\n        # return empty to force newline logic or stop.\n        return []\n    \n    def _is_keyscale_complete(self) -> bool:\n        \"\"\"\n        Check if keyscale value is complete and valid.\n        Uses token ID sequence to check if current prefix allows newline.\n        \"\"\"\n        token_prefix = tuple(self.accumulated_token_ids)\n        # If current token sequence prefix is in tree and allows newline, it's complete\n        if token_prefix in self.keyscale_prefix_tree:\n            return self.newline_token in self.keyscale_prefix_tree[token_prefix]\n        return False\n    \n    def _get_allowed_language_tokens(self) -> List[int]:\n        \"\"\"\n        Get allowed tokens for language field using the precomputed prefix tree.\n        Uses token ID sequence as key (not string) to avoid tokenization mismatches.\n        Similar to keyscale.\n        \"\"\"\n        token_prefix = tuple(self.accumulated_token_ids)\n        \n        if token_prefix in self.language_prefix_tree:\n            return list(self.language_prefix_tree[token_prefix])\n        \n        # Fallback: no valid continuation found\n        return []\n    \n    def _get_allowed_timesig_tokens(self) -> List[int]:\n        \"\"\"\n        Get allowed tokens for timesignature field using the precomputed prefix tree.\n        Uses token ID sequence as key (not string) to avoid tokenization mismatches.\n        \"\"\"\n        token_prefix = tuple(self.accumulated_token_ids)\n        \n        if token_prefix in self.timesig_prefix_tree:\n            return list(self.timesig_prefix_tree[token_prefix])\n        \n        # No valid continuation found - return empty list\n        # The caller will handle this by forcing newline to end the field\n        return []\n    \n    def __call__(\n        self,\n        input_ids: torch.LongTensor,\n        scores: torch.FloatTensor,\n    ) -> torch.FloatTensor:\n        \"\"\"\n        Apply constrained decoding by modifying logits.\n        \n        Args:\n            input_ids: [batch_size, seq_len] input token IDs\n            scores: [batch_size, vocab_size] logits for next token\n            \n        Returns:\n            Modified scores with invalid tokens masked to -inf and temperature scaling applied\n        \"\"\"\n        if not self.enabled:\n            return self._apply_temperature_scaling(scores)\n        \n        if self.state == FSMState.COMPLETED:\n            # In understanding phase, block audio codes during lyrics generation (COMPLETED state)\n            if self.generation_phase == \"understand\" and self.audio_code_mask is not None:\n                # Move mask to same device/dtype as scores if needed\n                if self.audio_code_mask.device != scores.device or self.audio_code_mask.dtype != scores.dtype:\n                    self.audio_code_mask = self.audio_code_mask.to(device=scores.device, dtype=scores.dtype)\n                scores = scores + self.audio_code_mask\n            return self._apply_temperature_scaling(scores)\n        \n        # For codes phase, detect if input already contains </think> and skip to CODES_GENERATION\n        if self.generation_phase == \"codes\" and self.state == FSMState.THINK_TAG:\n            # Check if input contains </think> token sequence\n            if self._input_contains_think_end_tag(input_ids):\n                # Skip metadata generation, go directly to codes generation\n                self.state = FSMState.CODES_GENERATION\n                self.codes_count = 0\n                if self.debug:\n                    logger.debug(\"Codes phase: detected </think> in input, skipping to CODES_GENERATION\")\n        \n        if self.state == FSMState.CODES_GENERATION:\n            # Block all non-audio-code tokens (only allow audio codes and EOS)\n            # Note: audio_code_token_ids already contains only valid tokens (0-63999 range)\n            # because _precompute_audio_code_tokens() filters out invalid tokens during initialization\n            if self.non_audio_code_mask is not None:\n                # Move mask to same device/dtype as scores if needed\n                if self.non_audio_code_mask.device != scores.device or self.non_audio_code_mask.dtype != scores.dtype:\n                    self.non_audio_code_mask = self.non_audio_code_mask.to(device=scores.device, dtype=scores.dtype)\n                scores = scores + self.non_audio_code_mask\n            \n            # Apply duration constraint in codes generation phase\n            if self.target_codes is not None and self.eos_token_id is not None:\n                if self.codes_count < self.target_codes:\n                    # Block EOS token until target codes count is reached\n                    scores[:, self.eos_token_id] = float('-inf')\n                    if self.debug:\n                        logger.debug(f\"Codes generation: {self.codes_count}/{self.target_codes}, blocking EOS\")\n                else:\n                    # Force EOS token when target codes count is reached - inplace\n                    eos_scores = scores[:, self.eos_token_id].clone()\n                    scores.fill_(float('-inf'))\n                    scores[:, self.eos_token_id] = eos_scores\n                    if self.debug:\n                        logger.debug(f\"Codes generation: {self.codes_count}/{self.target_codes}, forcing EOS\")\n            return self._apply_temperature_scaling(scores)\n        \n        batch_size = scores.shape[0]\n        \n        # Process each sequence in batch\n        for b in range(batch_size):\n            result = self._process_single_sequence(input_ids[b], scores[b:b+1])\n            scores[b] = result[0]  # result is [1, vocab_size], need [vocab_size]\n        \n        # Apply temperature scaling after constraint masking\n        return self._apply_temperature_scaling(scores)\n    \n    def _input_contains_think_end_tag(self, input_ids: torch.LongTensor) -> bool:\n        \"\"\"\n        Check if input contains the </think> closing tag.\n        \n        Args:\n            input_ids: [batch_size, seq_len] input token IDs\n            \n        Returns:\n            True if </think> is found in the input (any sequence in batch)\n        \"\"\"\n        # Tokenize </think> to get its token sequence\n        think_end_tokens = self.tokenizer.encode(\"</think>\", add_special_tokens=False)\n        if not think_end_tokens:\n            return False\n        \n        # Check each sequence in batch\n        for b in range(input_ids.shape[0]):\n            seq = input_ids[b].tolist()\n            # Search for the token sequence in the input\n            for i in range(len(seq) - len(think_end_tokens) + 1):\n                if seq[i:i+len(think_end_tokens)] == think_end_tokens:\n                    return True\n        \n        return False\n    \n    def _apply_temperature_scaling(self, scores: torch.FloatTensor) -> torch.FloatTensor:\n        \"\"\"\n        Apply temperature scaling based on current generation phase.\n        \n        Temperature scaling: logits = logits / temperature\n        - Lower temperature (< 1.0) makes distribution sharper (more deterministic)\n        - Higher temperature (> 1.0) makes distribution flatter (more diverse)\n        \n        Args:\n            scores: [batch_size, vocab_size] logits\n            \n        Returns:\n            Temperature-scaled logits\n        \"\"\"\n        # Determine which temperature to use based on current state\n        if self.state == FSMState.CODES_GENERATION or self.state == FSMState.COMPLETED:\n            temperature = self.codes_temperature\n        else:\n            temperature = self.metadata_temperature\n        \n        # If no temperature is set for this phase, return scores unchanged\n        if temperature is None:\n            return scores\n        \n        # Avoid division by zero\n        if temperature <= 0:\n            temperature = 1e-6\n        \n        # Apply temperature scaling\n        return scores / temperature\n    \n    def _get_user_provided_field_tokens(self, field_name: str) -> Optional[List[int]]:\n        \"\"\"\n        Get token sequence for a user-provided field (field_name + value + newline).\n        Uses the same tokenization logic as prefix tree building.\n        \n        Args:\n            field_name: Field name (\"bpm\", \"caption\", \"duration\", \"keyscale\", \"language\", \"timesignature\")\n            \n        Returns:\n            List of token IDs for the complete field, or None if field is not provided\n        \"\"\"\n        value = self.user_provided_metadata.get(field_name)\n        if value is None:\n            return None\n        \n        # Build full field string with space (matching prefix tree tokenization)\n        field_to_prefix = {\n            \"bpm\": \"bpm: \",\n            \"caption\": \"caption: \",\n            \"duration\": \"duration: \",\n            \"keyscale\": \"keyscale: \",\n            \"language\": \"language: \",\n            \"timesignature\": \"timesignature: \",\n            \"genres\": \"genres: \",\n        }\n        prefix = field_to_prefix[field_name]\n        full_text = f\"{prefix}{value}\\n\"\n        \n        # Tokenize the full field\n        tokens = self.tokenizer.encode(full_text, add_special_tokens=False)\n        \n        # Extract only the field tokens (skip the prefix tokens that match state machine output)\n        # The state machine generates \"field_name:\" (no space), so we need to match that\n        prefix_for_matching = field_name + \":\"\n        prefix_tokens = self.tokenizer.encode(prefix_for_matching, add_special_tokens=False)\n        \n        # Find where prefix ends in full tokens\n        if len(tokens) >= len(prefix_tokens) and tokens[:len(prefix_tokens)] == prefix_tokens:\n            # Return tokens after prefix (field value + newline)\n            return tokens[len(prefix_tokens):]\n        else:\n            # Fallback: return all tokens (shouldn't happen if tokenization is consistent)\n            if self.debug:\n                logger.warning(f\"Could not match prefix tokens for field {field_name}, using all tokens\")\n            return tokens\n    \n    def _process_single_sequence(\n        self,\n        input_ids: torch.LongTensor,\n        scores: torch.FloatTensor,\n    ) -> torch.FloatTensor:\n        \"\"\"Process a single sequence and return modified scores (inplace when possible).\"\"\"\n        \n        # Check if we have tokens in queue for user-provided field\n        # If so, inject the next token directly\n        if self.user_field_token_queue:\n            next_token = self.user_field_token_queue[0]\n            self._apply_whitelist_inplace(scores, [next_token])\n            return scores\n        \n        if self.state in self.fixed_strings:\n            # Fixed string state: force specific tokens\n            fixed_str = self.fixed_strings[self.state]\n            allowed = self._get_allowed_tokens_for_fixed_string(fixed_str)\n            \n            if allowed:\n                # Check if we should stop at reasoning (after </think> tag)\n                # This happens when we're about to complete the </think> tag\n                if self.state == FSMState.THINK_END_TAG and self.stop_at_reasoning:\n                    # Check if the next token would complete the fixed string\n                    remaining_chars = len(fixed_str) - self.position_in_state\n                    # If remaining is small (<= 10 chars, which is typically 1-2 tokens), force EOS\n                    if remaining_chars <= 10:\n                        # Force EOS token to stop generation\n                        if self.eos_token_id is not None:\n                            self._apply_whitelist_inplace(scores, [self.eos_token_id])\n                            if self.debug:\n                                logger.debug(f\"stop_at_reasoning=True: forcing EOS near end of </think> tag (remaining: {remaining_chars} chars)\")\n                            return scores\n                \n                # Apply whitelist constraint inplace\n                self._apply_whitelist_inplace(scores, allowed)\n            else:\n                # Position exceeds string, move to next state\n                # If stop_at_reasoning is True and we're transitioning from THINK_END_TAG,\n                # force EOS before transitioning\n                if self.state == FSMState.THINK_END_TAG and self.stop_at_reasoning:\n                    # Force EOS token to stop generation\n                    if self.eos_token_id is not None:\n                        self._apply_whitelist_inplace(scores, [self.eos_token_id])\n                        if self.debug:\n                            logger.debug(f\"stop_at_reasoning=True: forcing EOS after completing </think> tag\")\n                        return scores\n                \n                old_state = self.state\n                self._transition_to_next_state()\n                # Avoid infinite recursion: if we're still in a fixed_strings state, just return scores\n                if self.state in self.fixed_strings:\n                    # This shouldn't happen, but if it does, just return scores to avoid recursion\n                    if self.debug:\n                        logger.warning(f\"State transition from {old_state.name} to {self.state.name} still in fixed_strings, avoiding recursion\")\n                    return scores\n                # For recursion, reset scores to zero (no constraints from previous state)\n                scores.zero_()\n                return self._process_single_sequence(input_ids, scores)\n        \n        elif self.state == FSMState.BPM_VALUE:\n            # Check if field is user-provided and we haven't started injecting yet\n            if self.user_provided_metadata[\"bpm\"] is not None and not self.user_field_token_queue and not self.accumulated_token_ids:\n                # Initialize token queue with field value tokens (value + newline)\n                value = self.user_provided_metadata[\"bpm\"]\n                # Tokenize \" value\\n\" (space + value + newline) to match actual tokenization\n                value_text = f\" {value}\\n\"\n                value_tokens = self.tokenizer.encode(value_text, add_special_tokens=False)\n                if value_tokens:\n                    self.user_field_token_queue = value_tokens\n                    self.current_user_field = \"bpm\"\n                    # Inject first token\n                    self._apply_whitelist_inplace(scores, [value_tokens[0]])\n                    return scores\n            \n            # Allow valid numeric tokens using prefix tree (supports multi-digit tokens like \"120\")\n            allowed = self._get_allowed_numeric_tokens(self.bpm_prefix_tree)\n            \n            # Also allow newline if current token sequence prefix allows it\n            token_prefix = tuple(self.accumulated_token_ids)\n            if token_prefix in self.bpm_prefix_tree and self.newline_token in self.bpm_prefix_tree[token_prefix]:\n                allowed = allowed + [self.newline_token]\n            \n            self._apply_whitelist_inplace(scores, allowed)\n        \n        elif self.state == FSMState.CAPTION_VALUE:\n            # Caption field generation with YAML format support:\n            # - Allow newlines and spaces (YAML multi-line formatting)\n            # - Block audio codes and backticks\n            # - Max 512 tokens\n            # - Transition when model wants to generate next field (non-indented line)\n            \n            # Check if field is user-provided and we haven't started injecting yet\n            if self.user_provided_metadata[\"caption\"] is not None and not self.user_field_token_queue and not self.accumulated_value:\n                # Initialize token queue with field value tokens (value + newline)\n                value = self.user_provided_metadata[\"caption\"]\n                value_text = f\" {value}\\n\"\n                value_tokens = self.tokenizer.encode(value_text, add_special_tokens=False)\n                if value_tokens:\n                    self.user_field_token_queue = value_tokens\n                    self.current_user_field = \"caption\"\n                    # Inject first token\n                    self._apply_whitelist_inplace(scores, [value_tokens[0]])\n                    return scores\n            \n            # Check if we should transition after a newline (non-indented line = new field)\n            if self.caption_after_newline:\n                # Get top token from current scores\n                top_token_id = torch.argmax(scores[0]).item()\n                top_token_text = self.tokenizer.decode([top_token_id])\n                \n                # If top token does NOT start with space/tab, it's a new field (like \"duration:\")\n                if len(top_token_text) > 0 and top_token_text[0] not in ' \\t':\n                    # Caption is ending - LM is generating next field name\n                    # Instead of forcing state transition to DURATION_NAME (which would regenerate the field name),\n                    # we enter a \"caption_ending\" mode where we allow free generation until we detect the field value\n                    self.caption_after_newline = False\n                    self.caption_ending = True  # Start tracking field name\n                    self.pending_field_name = \"\"  # Reset pending field name\n                    # Allow free generation (no constraints) so LM can generate field name naturally\n                    return scores\n                else:\n                    # It's indentation, continue caption (don't transition!)\n                    self.caption_after_newline = False\n                    # Continue normal caption generation\n                    # Fall through to caption constraints below\n\n            # If caption is ending (LM generating next field name), allow free generation\n            # and track the field name until we see colon\n            if self.caption_ending:\n                # Allow any token (free generation)\n                # The field name detection will happen in update_state()\n                return scores\n            \n            # Block backticks (code blocks) - inplace\n            if self.backtick_token is not None:\n                scores[0, self.backtick_token] = float('-inf')\n            \n            # Block ALL audio code tokens (critical - these should never appear in caption)\n            # Use precomputed mask for O(1) performance instead of O(n) loop\n            if self.audio_code_mask is not None:\n                # Move mask to same device/dtype as scores if needed\n                if self.audio_code_mask.device != scores.device or self.audio_code_mask.dtype != scores.dtype:\n                    self.audio_code_mask = self.audio_code_mask.to(device=scores.device, dtype=scores.dtype)\n                scores = scores + self.audio_code_mask\n            \n            # Enforce 512 token limit for caption\n            if self.caption_token_count >= 512:\n                # Force end by only allowing newline\n                if self.newline_token is not None:\n                    self._apply_whitelist_inplace(scores, [self.newline_token])\n                    return scores\n            \n            # Allow natural generation (with blocked audio codes and backticks)\n            return scores\n        \n        elif self.state == FSMState.DURATION_VALUE:\n            # Check if field is user-provided and we haven't started injecting yet\n            if self.user_provided_metadata[\"duration\"] is not None and not self.user_field_token_queue and not self.accumulated_token_ids:\n                # Initialize token queue with field value tokens (value + newline)\n                value = self.user_provided_metadata[\"duration\"]\n                value_text = f\" {value}\\n\"\n                value_tokens = self.tokenizer.encode(value_text, add_special_tokens=False)\n                if value_tokens:\n                    self.user_field_token_queue = value_tokens\n                    self.current_user_field = \"duration\"\n                    # Inject first token\n                    self._apply_whitelist_inplace(scores, [value_tokens[0]])\n                    return scores\n            \n            # If target_duration is set, force generate that exact value\n            if self.target_duration is not None:\n                target_str = str(int(self.target_duration))\n                current_pos = len(self.accumulated_value)\n                \n                if current_pos < len(target_str):\n                    # Force the next digit\n                    next_digit = int(target_str[current_pos])\n                    if next_digit in self.digit_tokens:\n                        self._apply_whitelist_inplace(scores, [self.digit_tokens[next_digit]])\n                else:\n                    # All digits generated, force newline\n                    if self.newline_token:\n                        self._apply_whitelist_inplace(scores, [self.newline_token])\n            else:\n                # Normal duration generation with range constraint\n                # Allow valid numeric tokens using prefix tree (supports multi-digit tokens like \"60\", \"120\")\n                allowed = self._get_allowed_numeric_tokens(self.duration_prefix_tree)\n                \n                # Also allow newline if current token sequence prefix allows it\n                token_prefix = tuple(self.accumulated_token_ids)\n                if token_prefix in self.duration_prefix_tree and self.newline_token in self.duration_prefix_tree[token_prefix]:\n                    allowed = allowed + [self.newline_token]\n                \n                self._apply_whitelist_inplace(scores, allowed)\n        \n        elif self.state == FSMState.GENRES_VALUE:\n            # Check if field is user-provided and we haven't started injecting yet\n            if self.user_provided_metadata[\"genres\"] is not None and not self.user_field_token_queue and not self.accumulated_value:\n                # Initialize token queue with field value tokens (value + newline)\n                value = self.user_provided_metadata[\"genres\"]\n                value_text = f\" {value}\\n\"\n                value_tokens = self.tokenizer.encode(value_text, add_special_tokens=False)\n                if value_tokens:\n                    self.user_field_token_queue = value_tokens\n                    self.current_user_field = \"genres\"\n                    # Inject first token\n                    self._apply_whitelist_inplace(scores, [value_tokens[0]])\n                    return scores\n            \n            # Try to hot-reload genres vocab if file has changed\n            self._try_reload_genres_vocab()\n            \n            # Get allowed tokens based on genres vocabulary\n            allowed = self._get_allowed_genres_tokens()\n            \n            if allowed:\n                # Use vocabulary-constrained decoding\n                self._apply_whitelist_inplace(scores, allowed)\n            elif self.genres_vocab:\n                # Vocab is loaded but no valid continuation found\n                # Force newline to end the field\n                if self.newline_token:\n                    if self.debug:\n                        logger.debug(f\"No valid genre continuation for '{self.accumulated_value}', forcing newline\")\n                    self._apply_whitelist_inplace(scores, [self.newline_token])\n            else:\n                # Fallback: no vocab loaded, use probability-based ending\n                if self._should_end_text_field(scores):\n                    if self.newline_token:\n                        self._apply_whitelist_inplace(scores, [self.newline_token])\n                        self._transition_to_next_state()\n                else:\n                    # Allow any token except newline if we don't have content yet\n                    if not self.accumulated_value.strip():\n                        if self.newline_token:\n                            scores[0, self.newline_token] = float('-inf')\n                    # Otherwise, don't constrain (fallback behavior)\n        \n        elif self.state == FSMState.KEYSCALE_VALUE:\n            # Check if field is user-provided and we haven't started injecting yet\n            if self.user_provided_metadata[\"keyscale\"] is not None and not self.user_field_token_queue and not self.accumulated_token_ids:\n                # Initialize token queue with field value tokens (value + newline)\n                value = self.user_provided_metadata[\"keyscale\"]\n                value_text = f\" {value}\\n\"\n                value_tokens = self.tokenizer.encode(value_text, add_special_tokens=False)\n                if value_tokens:\n                    self.user_field_token_queue = value_tokens\n                    self.current_user_field = \"keyscale\"\n                    # Inject first token\n                    self._apply_whitelist_inplace(scores, [value_tokens[0]])\n                    return scores\n            \n            # Check if current token sequence is complete (allows newline)\n            token_prefix = tuple(self.accumulated_token_ids)\n            if token_prefix in self.keyscale_prefix_tree and self.newline_token in self.keyscale_prefix_tree[token_prefix]:\n                # Complete keyscale, allow newline\n                if self.newline_token:\n                    self._apply_whitelist_inplace(scores, [self.newline_token])\n            else:\n                # Not complete, allow valid continuation tokens\n                allowed = self._get_allowed_keyscale_tokens()\n                if allowed:\n                    self._apply_whitelist_inplace(scores, allowed)\n                else:\n                    # No valid tokens found - force newline to end field\n                    # This handles edge cases where keyscale format is unexpected\n                    if self.newline_token:\n                        self._apply_whitelist_inplace(scores, [self.newline_token])\n        \n        elif self.state == FSMState.LANGUAGE_VALUE:\n            # Language field: Use top-1 probability language (greedy selection)\n            # Unlike other fields, we don't use prefix tree sampling.\n            # Instead, we select the highest probability language at the start,\n            # then force generate the rest of that language code.\n            \n            # Check if field is user-provided and we haven't started injecting yet\n            if self.user_provided_metadata[\"language\"] is not None and not self.user_field_token_queue and not self.accumulated_token_ids:\n                # Initialize token queue with field value tokens (value + newline)\n                value = self.user_provided_metadata[\"language\"]\n                value_text = f\" {value}\\n\"\n                value_tokens = self.tokenizer.encode(value_text, add_special_tokens=False)\n                if value_tokens:\n                    self.user_field_token_queue = value_tokens\n                    self.current_user_field = \"language\"\n                    # Inject first token\n                    self._apply_whitelist_inplace(scores, [value_tokens[0]])\n                    return scores\n\n            # If we haven't started generating language yet (empty accumulated_token_ids),\n            # select the top-1 probability token from all valid first tokens\n            if not self.accumulated_token_ids:\n                # Get all possible first tokens for all languages\n                empty_prefix = tuple()\n                if empty_prefix in self.language_prefix_tree:\n                    candidate_tokens = list(self.language_prefix_tree[empty_prefix])\n                    \n                    if candidate_tokens:\n                        # Find the token with highest probability (top-1) among candidates\n                        # Use tensor indexing to get scores of candidate tokens directly\n                        candidate_indices = torch.tensor(candidate_tokens, device=scores.device, dtype=torch.long)\n                        candidate_scores = scores[0, candidate_indices]\n                        \n                        # Get the highest probability token among candidates\n                        best_idx = torch.argmax(candidate_scores).item()\n                        top_token_id = candidate_tokens[best_idx]\n                        \n                        # Only allow this top-1 token, block all others\n                        self._apply_whitelist_inplace(scores, [top_token_id])\n                        \n                        if self.debug:\n                            top_token_text = self.tokenizer.decode([top_token_id])\n                            logger.debug(f\"Language field: selected top-1 token {top_token_id} ({repr(top_token_text)}) from {len(candidate_tokens)} candidates\")\n                    else:\n                        # No valid first tokens found - force newline\n                        if self.newline_token:\n                            self._apply_whitelist_inplace(scores, [self.newline_token])\n                else:\n                    # Empty prefix not in tree - force newline\n                    if self.newline_token:\n                        self._apply_whitelist_inplace(scores, [self.newline_token])\n            else:\n                # We've started generating a language, continue with prefix tree constraints\n                # Check if current token sequence is complete (allows newline)\n                token_prefix = tuple(self.accumulated_token_ids)\n                if token_prefix in self.language_prefix_tree and self.newline_token in self.language_prefix_tree[token_prefix]:\n                    # Complete language, allow newline\n                    if self.newline_token:\n                        self._apply_whitelist_inplace(scores, [self.newline_token])\n                else:\n                    # Not complete, allow valid continuation tokens\n                    allowed = self._get_allowed_language_tokens()\n                    if allowed:\n                        self._apply_whitelist_inplace(scores, allowed)\n                    else:\n                        # No valid tokens found - force newline to end field\n                        if self.newline_token:\n                            self._apply_whitelist_inplace(scores, [self.newline_token])\n        \n        elif self.state == FSMState.TIMESIG_VALUE:\n            # Check if field is user-provided and we haven't started injecting yet\n            if self.user_provided_metadata[\"timesignature\"] is not None and not self.user_field_token_queue and not self.accumulated_token_ids:\n                # Initialize token queue with field value tokens (value + newline)\n                value = self.user_provided_metadata[\"timesignature\"]\n                value_text = f\" {value}\\n\"\n                value_tokens = self.tokenizer.encode(value_text, add_special_tokens=False)\n                if value_tokens:\n                    self.user_field_token_queue = value_tokens\n                    self.current_user_field = \"timesignature\"\n                    # Inject first token\n                    self._apply_whitelist_inplace(scores, [value_tokens[0]])\n                    return scores\n            \n            # Check if current token sequence is complete (allows newline)\n            token_prefix = tuple(self.accumulated_token_ids)\n            if token_prefix in self.timesig_prefix_tree and self.newline_token in self.timesig_prefix_tree[token_prefix]:\n                # Complete value, allow newline\n                if self.newline_token:\n                    self._apply_whitelist_inplace(scores, [self.newline_token])\n            else:\n                # Not complete, allow valid continuation tokens\n                allowed = self._get_allowed_timesig_tokens()\n                self._apply_whitelist_inplace(scores, allowed)\n        \n        return scores\n    \n    def _transition_to_next_state(self):\n        \"\"\"Transition to the next FSM state.\"\"\"\n        if self.state in self.next_state:\n            old_state = self.state\n            next_state = self.next_state[self.state]\n            \n            # Handle different cases at THINK_END_TAG based on generation phase\n            # NOTE: Do NOT override next_state here when stop_at_reasoning=True\n            # because we need to transition to the tag state first to generate </think>,\n            # then handle stop_at_reasoning in update_state() AFTER the tag is complete\n            if old_state == FSMState.THINK_END_TAG:\n                if self.generation_phase == \"understand\":\n                    # Understanding mode: allow free-form lyrics after metadata\n                    # No more constrained decoding after </think>\n                    next_state = FSMState.COMPLETED\n                    if self.debug:\n                        logger.debug(f\"generation_phase='understand': allowing free-form lyrics after </think>\")\n                # else: default to CODES_GENERATION (for \"codes\" phase) or respect stop_at_reasoning flag\n            \n            self.state = next_state\n            self.position_in_state = 0\n            self.accumulated_value = \"\"  # Legacy, kept for compatibility\n            self.accumulated_token_ids = []  # Reset token ID sequence for new field\n            self.caption_after_newline = False  # Reset caption newline tracking\n            self.caption_token_count = 0  # Reset caption token count\n            self.caption_ending = False  # Reset caption ending tracking\n            self.pending_field_name = \"\"  # Reset pending field name\n            if self.debug:\n                logger.debug(f\"FSM transition: {old_state.name} -> {self.state.name}\")\n    \n    def update_state(self, generated_token_id: int):\n        \"\"\"\n        Update internal state after a token has been generated.\n        This should be called after each token generation.\n        \n        Args:\n            generated_token_id: The token ID that was just generated\n        \"\"\"\n        if not self.enabled:\n            return\n        \n        if self.state == FSMState.COMPLETED:\n            return\n        \n        if self.state == FSMState.CODES_GENERATION:\n            # Count generated codes for duration constraint\n            self.codes_count += 1\n            if self.debug and self.target_codes is not None:\n                logger.debug(f\"Codes count: {self.codes_count}/{self.target_codes}\")\n            return\n        \n        # Handle user-provided field token injection\n        if self.user_field_token_queue:\n            # Verify the generated token matches the expected token from queue\n            expected_token = self.user_field_token_queue[0]\n            if generated_token_id != expected_token:\n                if self.debug:\n                    logger.warning(f\"Expected token {expected_token} but got {generated_token_id} for user-provided field {self.current_user_field}\")\n            \n            # Remove consumed token from queue\n            self.user_field_token_queue.pop(0)\n            \n            # If queue is empty, field injection is complete, transition to next state\n            if not self.user_field_token_queue:\n                if self.debug:\n                    logger.debug(f\"Completed injection of user-provided field: {self.current_user_field}\")\n                field_name = self.current_user_field\n                self.current_user_field = None\n                \n                # Transition to next state (skip VALUE state since we already injected everything)\n                # The next state should be determined by _get_next_field_state\n                next_state = self._get_next_field_state(field_name)\n                if next_state:\n                    old_state = self.state\n                    self.state = next_state\n                    self.position_in_state = 0\n                    self.accumulated_value = \"\"\n                    self.accumulated_token_ids = []\n                    if self.debug:\n                        logger.debug(f\"FSM transition (after user field injection): {old_state.name} -> {self.state.name}\")\n                else:\n                    # All fields done, go to THINK_END_TAG\n                    self._transition_to_next_state()\n            return\n        \n        token_str = self.tokenizer.decode([generated_token_id])\n        \n        if self.debug:\n            logger.debug(f\"Generated token: {repr(token_str)} (id={generated_token_id}), state={self.state.name}\")\n        \n        if self.state in self.fixed_strings:\n            # Update position in fixed string\n            fixed_str = self.fixed_strings[self.state]\n            self.position_in_state += len(token_str)\n            \n            # Check if we've completed the fixed string\n            if self.position_in_state >= len(fixed_str):\n                # Special handling for THINK_END_TAG with stop_at_reasoning\n                if self.state == FSMState.THINK_END_TAG and self.stop_at_reasoning:\n                    # </think> tag is complete, now we can stop generation\n                    # Force transition to COMPLETED instead of CODES_GENERATION\n                    old_state = self.state\n                    self.state = FSMState.COMPLETED\n                    self.position_in_state = 0\n                    self.accumulated_value = \"\"\n                    self.accumulated_token_ids = []\n                    if self.debug:\n                        logger.debug(f\"FSM transition (stop_at_reasoning): {old_state.name} -> {self.state.name}\")\n                else:\n                    self._transition_to_next_state()\n        \n        elif self.state in [FSMState.BPM_VALUE, FSMState.DURATION_VALUE, FSMState.TIMESIG_VALUE]:\n            # Accumulate numeric value using token ID sequence\n            if generated_token_id == self.newline_token:\n                old_state = self.state\n                self._transition_to_next_state()\n                # IMPORTANT: After state transition, if new state is a fixed_strings state,\n                # we should NOT update position_in_state with the newline token length,\n                # because that token belongs to the old state, not the new state.\n                # Return early to avoid the fixed_strings update logic below.\n                if self.state in self.fixed_strings:\n                    return\n            else:\n                # Add token ID to sequence (for prefix tree lookup)\n                self.accumulated_token_ids.append(generated_token_id)\n                # Also update legacy accumulated_value for compatibility\n                if token_str.strip().isdigit():\n                    self.accumulated_value += token_str.strip()\n\n        elif self.state == FSMState.GENRES_VALUE:\n            if generated_token_id == self.newline_token:\n                # Newline ends the field\n                self._transition_to_next_state()\n                # IMPORTANT: After state transition, if new state is a fixed_strings state,\n                # we should NOT update position_in_state with the newline token length,\n                # because that token belongs to the old state, not the new state.\n                # Return early to avoid the fixed_strings update logic below.\n                if self.state in self.fixed_strings:\n                    return\n            else:\n                # Genres still uses string-based trie, so keep accumulated_value\n                self.accumulated_value += token_str\n        \n        elif self.state == FSMState.CAPTION_VALUE:\n            # Track token count for 512 limit\n            self.caption_token_count += 1\n            \n            # Accumulate caption text\n            self.accumulated_value += token_str\n            \n            # Track if this token contains a newline (for transition detection)\n            # Token may be '\\n' alone or combined with other chars like '.\\n'\n            if '\\n' in token_str:\n                # Mark that we need to check next token for field transition\n                self.caption_after_newline = True\n            else:\n                # Not a newline - if we were after newline and this is not space,\n                # transition already happened in _process_single_sequence\n                self.caption_after_newline = False\n            \n            # If caption is ending, accumulate field name and detect field completion\n            if self.caption_ending:\n                self.pending_field_name += token_str\n                \n                # Check if we've completed a field name (detected colon)\n                if ':' in token_str or token_str.strip() == ':':\n                    # Extract field name (before colon)\n                    field_name_full = self.pending_field_name.strip()\n                    # Remove trailing colon if present\n                    field_name = field_name_full.rstrip(':').strip().lower()\n                    \n                    if self.debug:\n                        logger.debug(f\"Detected field name after caption: {repr(field_name)}\")\n                    \n                    # Map field name to VALUE state\n                    field_name_to_value_state = {\n                        \"duration\": FSMState.DURATION_VALUE,\n                        \"genres\": FSMState.GENRES_VALUE,\n                        \"keyscale\": FSMState.KEYSCALE_VALUE,\n                        \"language\": FSMState.LANGUAGE_VALUE,\n                        \"timesignature\": FSMState.TIMESIG_VALUE,\n                    }\n                    \n                    if field_name in field_name_to_value_state:\n                        # Transition directly to the field's VALUE state\n                        old_state = self.state\n                        self.state = field_name_to_value_state[field_name]\n                        self.position_in_state = 0\n                        self.accumulated_value = \"\"\n                        self.accumulated_token_ids = []\n                        self.caption_ending = False\n                        self.pending_field_name = \"\"\n                        \n                        if self.debug:\n                            logger.debug(f\"FSM transition (caption ending): {old_state.name} -> {self.state.name}\")\n                    else:\n                        # Unknown field name, force transition to next field\n                        if self.debug:\n                            logger.warning(f\"Unknown field name after caption: {repr(field_name)}, forcing transition\")\n                        self.caption_ending = False\n                        self.pending_field_name = \"\"\n                        self._transition_to_next_state()\n        \n        elif self.state == FSMState.KEYSCALE_VALUE:\n            if generated_token_id == self.newline_token:\n                # Newline ends the field\n                self._transition_to_next_state()\n                # IMPORTANT: After state transition, if new state is a fixed_strings state,\n                # we should NOT update position_in_state with the newline token length,\n                # because that token belongs to the old state, not the new state.\n                # Return early to avoid the fixed_strings update logic below.\n                if self.state in self.fixed_strings:\n                    return\n            else:\n                # Add token ID to sequence (for prefix tree lookup)\n                self.accumulated_token_ids.append(generated_token_id)\n                # Also update legacy accumulated_value for compatibility\n                self.accumulated_value += token_str\n        \n        elif self.state == FSMState.LANGUAGE_VALUE:\n            if generated_token_id == self.newline_token:\n                # Newline ends the field\n                self._transition_to_next_state()\n                if self.state in self.fixed_strings:\n                    return\n            else:\n                # Add token ID to sequence (for prefix tree lookup)\n                self.accumulated_token_ids.append(generated_token_id)\n                # Also update legacy accumulated_value for compatibility\n                self.accumulated_value += token_str\n\n"
  },
  {
    "path": "acestep/core/__init__.py",
    "content": "\"\"\"Core package intent: framework-agnostic domain logic for generation and inference.\"\"\"\n"
  },
  {
    "path": "acestep/core/audio/__init__.py",
    "content": "\"\"\"Audio package intent: reusable audio IO, transforms, and codec utilities.\"\"\"\n"
  },
  {
    "path": "acestep/core/generation/__init__.py",
    "content": "\"\"\"Generation package intent: music generation orchestration, params, and diffusion flow.\"\"\"\n"
  },
  {
    "path": "acestep/core/generation/handler/__init__.py",
    "content": "\"\"\"Handler decomposition components.\"\"\"\n\nfrom .audio_codes import AudioCodesMixin\nfrom .batch_prep import BatchPrepMixin\nfrom .conditioning_batch import ConditioningBatchMixin\nfrom .conditioning_embed import ConditioningEmbedMixin\nfrom .conditioning_masks import ConditioningMaskMixin\nfrom .conditioning_target import ConditioningTargetMixin\nfrom .conditioning_text import ConditioningTextMixin\nfrom .diffusion import DiffusionMixin\nfrom .generate_music import GenerateMusicMixin\nfrom .generate_music_decode import GenerateMusicDecodeMixin\nfrom .generate_music_execute import GenerateMusicExecuteMixin\nfrom .generate_music_payload import GenerateMusicPayloadMixin\nfrom .generate_music_request import GenerateMusicRequestMixin\nfrom .init_service import InitServiceMixin\nfrom .io_audio import IoAudioMixin\nfrom .lyric_score import LyricScoreMixin\nfrom .lyric_timestamp import LyricTimestampMixin\nfrom .lora_manager import LoraManagerMixin\nfrom .memory_utils import MemoryUtilsMixin\nfrom .metadata_utils import MetadataMixin\nfrom .mlx_dit_init import MlxDitInitMixin\nfrom .mlx_vae_decode_native import MlxVaeDecodeNativeMixin\nfrom .mlx_vae_encode_native import MlxVaeEncodeNativeMixin\nfrom .mlx_vae_init import MlxVaeInitMixin\nfrom .padding_utils import PaddingMixin\nfrom .prompt_utils import PromptMixin\nfrom .progress import ProgressMixin\nfrom .service_generate_execute import ServiceGenerateExecuteMixin\nfrom .service_generate_outputs import ServiceGenerateOutputsMixin\nfrom .service_generate_request import ServiceGenerateRequestMixin\nfrom .service_generate import ServiceGenerateMixin\nfrom .task_utils import TaskUtilsMixin\nfrom .training_preset import TrainingPresetMixin\nfrom .vae_decode import VaeDecodeMixin\nfrom .vae_decode_chunks import VaeDecodeChunksMixin\nfrom .vae_encode import VaeEncodeMixin\nfrom .vae_encode_chunks import VaeEncodeChunksMixin\n\n__all__ = [\n    \"AudioCodesMixin\",\n    \"BatchPrepMixin\",\n    \"ConditioningBatchMixin\",\n    \"ConditioningEmbedMixin\",\n    \"ConditioningMaskMixin\",\n    \"ConditioningTargetMixin\",\n    \"ConditioningTextMixin\",\n    \"DiffusionMixin\",\n    \"GenerateMusicMixin\",\n    \"GenerateMusicDecodeMixin\",\n    \"GenerateMusicExecuteMixin\",\n    \"GenerateMusicPayloadMixin\",\n    \"GenerateMusicRequestMixin\",\n    \"InitServiceMixin\",\n    \"IoAudioMixin\",\n    \"LyricScoreMixin\",\n    \"LyricTimestampMixin\",\n    \"LoraManagerMixin\",\n    \"MemoryUtilsMixin\",\n    \"MetadataMixin\",\n    \"MlxDitInitMixin\",\n    \"MlxVaeDecodeNativeMixin\",\n    \"MlxVaeEncodeNativeMixin\",\n    \"MlxVaeInitMixin\",\n    \"PaddingMixin\",\n    \"PromptMixin\",\n    \"ProgressMixin\",\n    \"ServiceGenerateExecuteMixin\",\n    \"ServiceGenerateMixin\",\n    \"ServiceGenerateOutputsMixin\",\n    \"ServiceGenerateRequestMixin\",\n    \"TaskUtilsMixin\",\n    \"TrainingPresetMixin\",\n    \"VaeDecodeMixin\",\n    \"VaeDecodeChunksMixin\",\n    \"VaeEncodeMixin\",\n    \"VaeEncodeChunksMixin\",\n]\n"
  },
  {
    "path": "acestep/core/generation/handler/audio_codes.py",
    "content": "\"\"\"Audio-code parsing and conversion helpers for handler decomposition.\"\"\"\n\nimport re\nimport traceback\nfrom typing import List, Optional\n\nimport torch\nfrom loguru import logger\n\n\nclass AudioCodesMixin:\n    \"\"\"Mixin containing audio-code parsing and latent conversion helpers.\n\n    Depends on host members:\n    - Attributes: ``model``, ``vae``, ``device``, ``dtype``, ``silence_latent``.\n    - Methods: ``_load_model_context``, ``process_src_audio``, ``is_silence``,\n      ``_encode_audio_to_latents``.\n    \"\"\"\n\n    def _parse_audio_code_string(self, code_str: str) -> List[int]:\n        \"\"\"Extract integer audio codes from tokens like ``<|audio_code_123|>``.\"\"\"\n        if not code_str:\n            return []\n        try:\n            max_audio_code = 63999\n            codes = []\n            clamped_count = 0\n            for x in re.findall(r\"<\\|audio_code_(\\d+)\\|>\", code_str):\n                code_value = int(x)\n                clamped_value = max(0, min(code_value, max_audio_code))\n                if clamped_value != code_value:\n                    clamped_count += 1\n                    logger.warning(\n                        f\"[_parse_audio_code_string] Clamped audio code value from {code_value} to {clamped_value}\"\n                    )\n                codes.append(clamped_value)\n            if clamped_count > 0:\n                logger.warning(\n                    f\"[_parse_audio_code_string] Clamped {clamped_count} audio code value(s) \"\n                    f\"to valid range [0, {max_audio_code}]\"\n                )\n            return codes\n        except Exception as e:\n            logger.debug(f\"[_parse_audio_code_string] Failed to parse audio code string: {e}\")\n            return []\n\n    def _decode_audio_codes_to_latents(self, code_str: str) -> Optional[torch.Tensor]:\n        \"\"\"Convert serialized audio-code string into 25Hz latents.\"\"\"\n        if self.model is None or not hasattr(self.model, \"tokenizer\") or not hasattr(self.model, \"detokenizer\"):\n            return None\n\n        code_ids = self._parse_audio_code_string(code_str)\n        if len(code_ids) == 0:\n            return None\n\n        with self._load_model_context(\"model\"):\n            quantizer = self.model.tokenizer.quantizer\n            detokenizer = self.model.detokenizer\n            indices = torch.tensor(code_ids, device=self.device, dtype=torch.long)\n            indices = indices.unsqueeze(0).unsqueeze(-1)\n\n            quantized = quantizer.get_output_from_indices(indices)\n            if quantized.dtype != self.dtype:\n                quantized = quantized.to(self.dtype)\n            lm_hints_25hz = detokenizer(quantized)\n            return lm_hints_25hz\n\n    def convert_src_audio_to_codes(self, audio_file) -> str:\n        \"\"\"Convert uploaded source audio into serialized audio code tokens.\"\"\"\n        if audio_file is None:\n            return \"❌ Please upload source audio first\"\n        if self.model is None or self.vae is None:\n            return \"❌ Model not initialized. Please initialize the service first.\"\n\n        try:\n            processed_audio = self.process_src_audio(audio_file)\n            if processed_audio is None:\n                return \"❌ Failed to process audio file\"\n\n            with torch.inference_mode():\n                with self._load_model_context(\"vae\"):\n                    if self.is_silence(processed_audio.unsqueeze(0)):\n                        return \"❌ Audio file appears to be silent\"\n                    latents = self._encode_audio_to_latents(processed_audio)\n\n                attention_mask = torch.ones(latents.shape[0], dtype=torch.bool, device=self.device)\n                with self._load_model_context(\"model\"):\n                    hidden_states = latents.unsqueeze(0)\n                    _, indices, _ = self.model.tokenize(\n                        hidden_states, self.silence_latent, attention_mask.unsqueeze(0)\n                    )\n                    indices_flat = indices.flatten().cpu().tolist()\n                    codes_string = \"\".join([f\"<|audio_code_{idx}|>\" for idx in indices_flat])\n                    logger.info(f\"[convert_src_audio_to_codes] Generated {len(indices_flat)} audio codes\")\n                    return codes_string\n        except Exception as e:\n            error_msg = f\"❌ Error converting audio to codes: {str(e)}\\n{traceback.format_exc()}\"\n            logger.exception(\"[convert_src_audio_to_codes] Error converting audio to codes\")\n            return error_msg\n"
  },
  {
    "path": "acestep/core/generation/handler/batch_prep.py",
    "content": "\"\"\"Batch preparation helpers for handler decomposition.\"\"\"\n\nfrom typing import Dict, List, Optional, Union\n\nimport torch\n\nfrom acestep.constants import DEFAULT_DIT_INSTRUCTION\n\n\nclass BatchPrepMixin:\n    \"\"\"Mixin containing batch and input normalization helpers.\n\n    Depends on host members:\n    - Attributes: ``device``, ``dtype``.\n    - Methods: ``tiled_encode``, ``extract_caption_from_sft_format``,\n      ``_build_metadata_dict``.\n    \"\"\"\n\n    def _normalize_audio_code_hints(\n        self, audio_code_hints: Optional[Union[str, List[str]]], batch_size: int\n    ) -> List[Optional[str]]:\n        \"\"\"Normalize ``audio_code_hints`` into a batch-length list.\"\"\"\n        if audio_code_hints is None:\n            normalized: List[Optional[str]] = [None] * batch_size\n        elif isinstance(audio_code_hints, str):\n            normalized = [audio_code_hints] * batch_size\n        elif len(audio_code_hints) == 1 and batch_size > 1:\n            normalized = audio_code_hints * batch_size\n        elif len(audio_code_hints) != batch_size:\n            normalized = list(audio_code_hints[:batch_size])\n            while len(normalized) < batch_size:\n                normalized.append(None)\n        else:\n            normalized = list(audio_code_hints)\n        return [hint if isinstance(hint, str) and hint.strip() else None for hint in normalized]\n\n    def _normalize_instructions(\n        self,\n        instructions: Optional[Union[str, List[str]]],\n        batch_size: int,\n        default: Optional[str] = None,\n    ) -> List[str]:\n        \"\"\"Normalize instructions into a batch-length list.\"\"\"\n        if instructions is None:\n            default_instruction = default or DEFAULT_DIT_INSTRUCTION\n            return [default_instruction] * batch_size\n        if isinstance(instructions, str):\n            return [instructions] * batch_size\n        if len(instructions) == 1:\n            return instructions * batch_size\n        if len(instructions) != batch_size:\n            normalized = list(instructions[:batch_size])\n            default_instruction = default or DEFAULT_DIT_INSTRUCTION\n            while len(normalized) < batch_size:\n                normalized.append(default_instruction)\n            return normalized\n        return list(instructions)\n\n    def _create_fallback_vocal_languages(self, batch_size: int) -> List[str]:\n        \"\"\"Create default vocal-language values for missing inputs.\"\"\"\n        return [\"en\"] * batch_size\n\n    def _encode_audio_to_latents(self, audio: torch.Tensor) -> torch.Tensor:\n        \"\"\"Encode audio to latents using tiled VAE encode path.\"\"\"\n        input_was_2d = audio.dim() == 2\n        if input_was_2d:\n            audio = audio.unsqueeze(0)\n\n        with torch.inference_mode():\n            latents = self.tiled_encode(audio, offload_latent_to_cpu=True)\n\n        latents = latents.to(self.device).to(self.dtype)\n        latents = latents.transpose(1, 2)\n        if input_was_2d:\n            latents = latents.squeeze(0)\n        return latents\n\n    def prepare_batch_data(\n        self,\n        actual_batch_size,\n        processed_src_audio,\n        audio_duration,\n        captions,\n        lyrics,\n        vocal_language,\n        instruction,\n        bpm,\n        key_scale,\n        time_signature,\n    ):\n        \"\"\"Prepare repeated batch-level caption/instruction/metadata values.\"\"\"\n        pure_caption = self.extract_caption_from_sft_format(captions)\n        captions_batch = [pure_caption] * actual_batch_size\n        instructions_batch = [instruction] * actual_batch_size\n        lyrics_batch = [lyrics] * actual_batch_size\n        vocal_languages_batch = [vocal_language] * actual_batch_size\n\n        calculated_duration = None\n        if processed_src_audio is not None:\n            calculated_duration = processed_src_audio.shape[-1] / 48000.0\n        elif audio_duration is not None and float(audio_duration) > 0:\n            calculated_duration = float(audio_duration)\n\n        metadata_dict: Dict[str, Union[str, int]] = self._build_metadata_dict(\n            bpm, key_scale, time_signature, calculated_duration\n        )\n        metas_batch = [metadata_dict.copy() for _ in range(actual_batch_size)]\n        return captions_batch, instructions_batch, lyrics_batch, vocal_languages_batch, metas_batch\n"
  },
  {
    "path": "acestep/core/generation/handler/conditioning_batch.py",
    "content": "\"\"\"Batch-conditioning orchestration helpers for handler decomposition.\"\"\"\n\nfrom typing import Any, Dict, List, Optional, Union\n\nimport torch\n\nfrom acestep.constants import DEFAULT_DIT_INSTRUCTION\n\n\nclass ConditioningBatchMixin:\n    \"\"\"Mixin containing batch preparation orchestration.\n\n    Depends on host members:\n    - Attributes: ``device``, ``dtype``, ``sample_rate``.\n    - Methods: ``_normalize_audio_code_hints``, ``_create_fallback_vocal_languages``,\n      ``_parse_metas``, ``_normalize_instructions``, ``_prepare_target_latents_and_wavs``,\n      ``_build_chunk_masks_and_src_latents``, ``_prepare_precomputed_lm_hints``,\n      ``_prepare_text_conditioning_inputs``.\n    \"\"\"\n\n    def _prepare_batch(\n        self,\n        captions: List[str],\n        global_captions: Optional[List[str]] = None,\n        lyrics: List[str] = None,\n        keys: Optional[List[str]] = None,\n        target_wavs: Optional[torch.Tensor] = None,\n        refer_audios: Optional[List[List[torch.Tensor]]] = None,\n        metas: Optional[List[Union[str, Dict[str, Any]]]] = None,\n        vocal_languages: Optional[List[str]] = None,\n        repainting_start: Optional[List[float]] = None,\n        repainting_end: Optional[List[float]] = None,\n        instructions: Optional[List[str]] = None,\n        audio_code_hints: Optional[List[Optional[str]]] = None,\n        audio_cover_strength: float = 1.0,\n        cover_noise_strength: float = 0.0,\n        chunk_mask_modes: Optional[List[str]] = None,\n    ) -> Dict[str, Any]:\n        \"\"\"Prepare model-ready conditioning batch tensors and metadata.\n\n        Args:\n            captions: Per-item captions.\n            lyrics: Per-item lyric strings.\n            keys: Optional per-item keys.\n            target_wavs: Target audio tensor batch.\n            refer_audios: Optional nested reference-audio tensors.\n            metas: Optional per-item metadata strings/dicts.\n            vocal_languages: Optional per-item vocal language codes.\n            repainting_start: Optional repaint start times.\n            repainting_end: Optional repaint end times.\n            instructions: Optional per-item generation instructions.\n            audio_code_hints: Optional per-item serialized audio-code hints.\n            audio_cover_strength: Blend factor for cover/non-cover conditioning.\n\n        Returns:\n            Batch dictionary containing padded tensors and conditioning metadata\n            consumed by ``preprocess_batch`` and downstream generation.\n        \"\"\"\n        if lyrics is None:\n            lyrics = [\"\"] * len(captions)\n        batch_size = len(captions)\n        audio_code_hints = self._normalize_audio_code_hints(audio_code_hints, batch_size)\n\n        if refer_audios is None:\n            refer_audios = [[torch.zeros(2, 30 * self.sample_rate)] for _ in range(batch_size)]\n        for ii, refer_audio_list in enumerate(refer_audios):\n            if isinstance(refer_audio_list, list):\n                for idx, _ in enumerate(refer_audio_list):\n                    refer_audio_list[idx] = refer_audio_list[idx].to(self.device).to(self._get_vae_dtype())\n            elif isinstance(refer_audio_list, torch.Tensor):\n                refer_audios[ii] = refer_audios[ii].to(self.device)\n\n        if vocal_languages is None:\n            vocal_languages = self._create_fallback_vocal_languages(batch_size)\n        parsed_metas = self._parse_metas(metas)\n\n        target_wavs, target_latents, latent_masks, max_latent_length, silence_latent_tiled = (\n            self._prepare_target_latents_and_wavs(batch_size, target_wavs, audio_code_hints)\n        )\n        wav_lengths = torch.tensor([target_wavs.shape[-1]] * batch_size, dtype=torch.long)\n\n        instructions = self._normalize_instructions(instructions, batch_size, DEFAULT_DIT_INSTRUCTION)\n        chunk_masks, spans, is_covers, src_latents, repaint_mask = self._build_chunk_masks_and_src_latents(\n            batch_size,\n            max_latent_length,\n            instructions,\n            audio_code_hints,\n            target_wavs,\n            target_latents,\n            repainting_start,\n            repainting_end,\n            silence_latent_tiled,\n            chunk_mask_modes=chunk_mask_modes,\n        )\n        precomputed_lm_hints_25hz = self._prepare_precomputed_lm_hints(\n            batch_size, audio_code_hints, max_latent_length, silence_latent_tiled\n        )\n        (\n            text_inputs,\n            padded_text_token_idss,\n            padded_text_attention_masks,\n            padded_lyric_token_idss,\n            padded_lyric_attention_masks,\n            padded_non_cover_text_input_ids,\n            padded_non_cover_text_attention_masks,\n        ) = self._prepare_text_conditioning_inputs(\n            batch_size,\n            instructions,\n            captions,\n            lyrics,\n            parsed_metas,\n            vocal_languages,\n            audio_cover_strength,\n            global_captions=global_captions,\n            chunk_mask_modes=chunk_mask_modes,\n        )\n\n        batch = {\n            \"keys\": keys,\n            \"target_wavs\": target_wavs.to(self.device),\n            \"refer_audioss\": refer_audios,\n            \"wav_lengths\": wav_lengths.to(self.device),\n            \"captions\": captions,\n            \"lyrics\": lyrics,\n            \"metas\": parsed_metas,\n            \"vocal_languages\": vocal_languages,\n            \"target_latents\": target_latents,\n            \"src_latents\": src_latents,\n            \"latent_masks\": latent_masks,\n            \"chunk_masks\": chunk_masks,\n            \"spans\": spans,\n            \"text_inputs\": text_inputs,\n            \"text_token_idss\": padded_text_token_idss,\n            \"text_attention_masks\": padded_text_attention_masks,\n            \"lyric_token_idss\": padded_lyric_token_idss,\n            \"lyric_attention_masks\": padded_lyric_attention_masks,\n            \"is_covers\": is_covers,\n            \"precomputed_lm_hints_25Hz\": precomputed_lm_hints_25hz,\n            \"non_cover_text_input_ids\": padded_non_cover_text_input_ids,\n            \"non_cover_text_attention_masks\": padded_non_cover_text_attention_masks,\n            \"repaint_mask\": repaint_mask,\n        }\n        for k, v in batch.items():\n            if isinstance(v, torch.Tensor):\n                batch[k] = v.to(self.device)\n                if torch.is_floating_point(batch[k]):\n                    batch[k] = batch[k].to(self.dtype)\n        return batch\n"
  },
  {
    "path": "acestep/core/generation/handler/conditioning_batch_test.py",
    "content": "\"\"\"Unit tests for batch-conditioning orchestration mixin.\"\"\"\n\nimport unittest\nfrom typing import Any, Dict, List, Optional, Tuple, Union\n\nimport torch\n\nfrom acestep.core.generation.handler.conditioning_batch import ConditioningBatchMixin\n\n\nclass _Host(ConditioningBatchMixin):\n    \"\"\"Minimal host implementing ConditioningBatchMixin dependencies.\"\"\"\n\n    def __init__(self):\n        self.device = \"cpu\"\n        self.dtype = torch.float32\n        self.sample_rate = 48000\n\n    def _normalize_audio_code_hints(self, audio_code_hints, batch_size: int) -> List[Optional[str]]:\n        if audio_code_hints is None:\n            return [None] * batch_size\n        return list(audio_code_hints)\n\n    def _create_fallback_vocal_languages(self, batch_size: int) -> List[str]:\n        return [\"en\"] * batch_size\n\n    def _get_vae_dtype(self) -> torch.dtype:\n        return torch.float32\n\n    def _parse_metas(self, metas) -> List[str]:\n        if metas is None:\n            return [\"- bpm: N/A\\n- timesignature: N/A\\n- keyscale: N/A\\n- duration: 30 seconds\\n\"] * 2\n        return metas\n\n    def _normalize_instructions(self, instructions, batch_size: int, default: str) -> List[str]:\n        if instructions is None:\n            return [default] * batch_size\n        return list(instructions)\n\n    def _prepare_target_latents_and_wavs(\n        self, batch_size: int, target_wavs: torch.Tensor, audio_code_hints: List[Optional[str]]\n    ) -> Tuple[torch.Tensor, torch.Tensor, torch.Tensor, int, torch.Tensor]:\n        target_latents = torch.zeros(batch_size, 128, 16, dtype=torch.float32)\n        latent_masks = torch.ones(batch_size, 128, dtype=torch.long)\n        silence_latent_tiled = torch.zeros(128, 16, dtype=torch.float32)\n        return target_wavs, target_latents, latent_masks, 128, silence_latent_tiled\n\n    def _build_chunk_masks_and_src_latents(\n        self,\n        batch_size: int,\n        max_latent_length: int,\n        instructions: List[str],\n        audio_code_hints: List[Optional[str]],\n        target_wavs: torch.Tensor,\n        target_latents: torch.Tensor,\n        repainting_start: Optional[List[float]],\n        repainting_end: Optional[List[float]],\n        silence_latent_tiled: torch.Tensor,\n        chunk_mask_modes: Optional[List[str]] = None,\n    ) -> Tuple[torch.Tensor, List[Tuple[str, int, int]], torch.Tensor, torch.Tensor, None]:\n        chunk_masks = torch.ones(batch_size, max_latent_length, dtype=torch.bool)\n        spans: List[Tuple[str, int, int]] = [(\"full\", 0, max_latent_length)] * batch_size\n        is_covers = torch.zeros(batch_size, dtype=torch.bool)\n        src_latents = target_latents.clone()\n        return chunk_masks, spans, is_covers, src_latents, None\n\n    def _prepare_precomputed_lm_hints(\n        self,\n        batch_size: int,\n        audio_code_hints: List[Optional[str]],\n        max_latent_length: int,\n        silence_latent_tiled: torch.Tensor,\n    ) -> Optional[torch.Tensor]:\n        if any(audio_code_hints):\n            return torch.zeros(batch_size, max_latent_length, 16, dtype=torch.float32)\n        return None\n\n    def _prepare_text_conditioning_inputs(\n        self,\n        batch_size: int,\n        instructions: List[str],\n        captions: List[str],\n        lyrics: List[str],\n        parsed_metas: List[str],\n        vocal_languages: List[str],\n        audio_cover_strength: float,\n        global_captions: Optional[List[str]] = None,\n        chunk_mask_modes: Optional[List[str]] = None,\n    ):\n        text_inputs = [f\"{captions[i]}::{lyrics[i]}\" for i in range(batch_size)]\n        text_ids = torch.ones(batch_size, 8, dtype=torch.long)\n        text_mask = torch.ones(batch_size, 8, dtype=torch.long)\n        lyric_ids = torch.ones(batch_size, 12, dtype=torch.long)\n        lyric_mask = torch.ones(batch_size, 12, dtype=torch.long)\n        non_cover_ids = torch.ones(batch_size, 8, dtype=torch.long) if audio_cover_strength < 1.0 else None\n        non_cover_mask = torch.ones(batch_size, 8, dtype=torch.long) if audio_cover_strength < 1.0 else None\n        return text_inputs, text_ids, text_mask, lyric_ids, lyric_mask, non_cover_ids, non_cover_mask\n\n\nclass ConditioningBatchMixinTests(unittest.TestCase):\n    \"\"\"Tests for ConditioningBatchMixin orchestration behavior.\"\"\"\n\n    def test_prepare_batch_builds_expected_keys_and_tensor_types(self):\n        \"\"\"Build batch with defaults and verify expected structure.\"\"\"\n        host = _Host()\n        batch = host._prepare_batch(\n            captions=[\"c1\", \"c2\"],\n            lyrics=[\"l1\", \"l2\"],\n            keys=[\"k1\", \"k2\"],\n            target_wavs=torch.zeros(2, 2, 96000),\n            refer_audios=None,\n            metas=None,\n            vocal_languages=None,\n            instructions=None,\n            audio_code_hints=[None, None],\n            audio_cover_strength=1.0,\n        )\n\n        self.assertIn(\"target_latents\", batch)\n        self.assertIn(\"chunk_masks\", batch)\n        self.assertIn(\"text_token_idss\", batch)\n        self.assertIn(\"refer_audioss\", batch)\n        self.assertEqual(batch[\"target_latents\"].dtype, torch.float32)\n        self.assertEqual(batch[\"target_latents\"].shape, (2, 128, 16))\n        self.assertEqual(len(batch[\"refer_audioss\"]), 2)\n        self.assertEqual(batch[\"refer_audioss\"][0][0].shape, (2, 30 * host.sample_rate))\n\n    def test_prepare_batch_populates_non_cover_inputs_when_strength_below_one(self):\n        \"\"\"Populate optional non-cover token fields for blended cover path.\"\"\"\n        host = _Host()\n        batch = host._prepare_batch(\n            captions=[\"c1\", \"c2\"],\n            lyrics=[\"l1\", \"l2\"],\n            keys=[\"k1\", \"k2\"],\n            target_wavs=torch.zeros(2, 2, 96000),\n            refer_audios=[[torch.zeros(2, 96000)], [torch.zeros(2, 96000)]],\n            metas=[\"m1\", \"m2\"],\n            vocal_languages=[\"en\", \"en\"],\n            instructions=[\"i1\", \"i2\"],\n            audio_code_hints=[\"hint\", None],\n            audio_cover_strength=0.5,\n        )\n\n        self.assertIsNotNone(batch[\"non_cover_text_input_ids\"])\n        self.assertIsNotNone(batch[\"non_cover_text_attention_masks\"])\n        self.assertIsNotNone(batch[\"precomputed_lm_hints_25Hz\"])\n\n\nif __name__ == \"__main__\":\n    unittest.main()\n"
  },
  {
    "path": "acestep/core/generation/handler/conditioning_embed.py",
    "content": "\"\"\"Reference/text embedding preprocessing helpers for conditioned generation.\"\"\"\n\nfrom typing import Dict, List, Tuple\n\nimport torch\nfrom loguru import logger\n\n\nclass ConditioningEmbedMixin:\n    \"\"\"Mixin containing reference/text embedding preprocessing steps.\n\n    Depends on host members:\n    - Attributes: ``device``, ``dtype``, ``silence_latent``, ``text_encoder``.\n    - Methods: ``_ensure_silence_latent_on_device``, ``_load_model_context``,\n      ``tiled_encode``.\n    \"\"\"\n\n    def infer_refer_latent(self, refer_audioss: List[List[torch.Tensor]]) -> Tuple[torch.Tensor, torch.Tensor]:\n        \"\"\"Infer packed reference-audio latents and order mask.\"\"\"\n        refer_audio_order_mask = []\n        refer_audio_latents = []\n        self._ensure_silence_latent_on_device()\n\n        def _normalize_audio_2d(a: torch.Tensor) -> torch.Tensor:\n            if not isinstance(a, torch.Tensor):\n                raise TypeError(f\"refer_audio must be a torch.Tensor, got {type(a)!r}\")\n            if a.dim() == 3 and a.shape[0] == 1:\n                a = a.squeeze(0)\n            if a.dim() == 1:\n                a = a.unsqueeze(0)\n            if a.dim() != 2:\n                raise ValueError(f\"refer_audio must be 1D/2D/3D(1,2,T); got shape={tuple(a.shape)}\")\n            if a.shape[0] == 1:\n                a = torch.cat([a, a], dim=0)\n            return a[:2]\n\n        def _ensure_latent_3d(z: torch.Tensor) -> torch.Tensor:\n            if z.dim() == 4 and z.shape[0] == 1:\n                z = z.squeeze(0)\n            if z.dim() == 2:\n                z = z.unsqueeze(0)\n            return z\n\n        refer_encode_cache: Dict[int, torch.Tensor] = {}\n        for batch_idx, refer_audios in enumerate(refer_audioss):\n            if len(refer_audios) == 1 and torch.all(refer_audios[0] == 0.0):\n                refer_audio_latent = _ensure_latent_3d(self.silence_latent[:, :750, :])\n                refer_audio_latents.append(refer_audio_latent)\n                refer_audio_order_mask.append(batch_idx)\n            else:\n                for refer_audio in refer_audios:\n                    cache_key = refer_audio.data_ptr()\n                    if cache_key in refer_encode_cache:\n                        refer_audio_latent = refer_encode_cache[cache_key].clone()\n                    else:\n                        refer_audio = _normalize_audio_2d(refer_audio)\n                        with torch.inference_mode():\n                            refer_audio_latent = self.tiled_encode(refer_audio, offload_latent_to_cpu=True)\n                        refer_audio_latent = refer_audio_latent.to(self.device).to(self.dtype)\n                        if refer_audio_latent.dim() == 2:\n                            refer_audio_latent = refer_audio_latent.unsqueeze(0)\n                        refer_audio_latent = _ensure_latent_3d(refer_audio_latent.transpose(1, 2))\n                        refer_encode_cache[cache_key] = refer_audio_latent\n                    refer_audio_latents.append(refer_audio_latent)\n                    refer_audio_order_mask.append(batch_idx)\n\n        refer_audio_latents = torch.cat(refer_audio_latents, dim=0)\n        refer_audio_order_mask = torch.tensor(refer_audio_order_mask, device=self.device, dtype=torch.long)\n        return refer_audio_latents, refer_audio_order_mask\n\n    def infer_text_embeddings(self, text_token_idss):\n        \"\"\"Infer text-token embeddings via text encoder.\"\"\"\n        with torch.inference_mode():\n            return self.text_encoder(input_ids=text_token_idss, lyric_attention_mask=None).last_hidden_state\n\n    def infer_lyric_embeddings(self, lyric_token_ids):\n        \"\"\"Infer lyric-token embeddings via text encoder embedding table.\"\"\"\n        with torch.inference_mode():\n            return self.text_encoder.embed_tokens(lyric_token_ids)\n\n    def preprocess_batch(self, batch) -> Tuple:\n        \"\"\"Preprocess an already prepared batch for DiT model input.\"\"\"\n        target_latents = batch[\"target_latents\"]\n        src_latents = batch[\"src_latents\"]\n        attention_mask = batch[\"latent_masks\"]\n        audio_codes = batch.get(\"audio_codes\", None)\n        audio_attention_mask = attention_mask\n\n        dtype = target_latents.dtype\n        device = target_latents.device\n\n        keys = batch[\"keys\"]\n        with self._load_model_context(\"vae\"):\n            refer_audio_acoustic_hidden_states_packed, refer_audio_order_mask = self.infer_refer_latent(\n                batch[\"refer_audioss\"]\n            )\n        if refer_audio_acoustic_hidden_states_packed.dtype != dtype:\n            refer_audio_acoustic_hidden_states_packed = refer_audio_acoustic_hidden_states_packed.to(dtype)\n\n        chunk_mask = batch[\"chunk_masks\"]\n        chunk_mask = chunk_mask.to(device).unsqueeze(-1).repeat(1, 1, target_latents.shape[2])\n        spans = batch[\"spans\"]\n\n        text_token_idss = batch[\"text_token_idss\"]\n        text_attention_mask = batch[\"text_attention_masks\"]\n        lyric_token_idss = batch[\"lyric_token_idss\"]\n        lyric_attention_mask = batch[\"lyric_attention_masks\"]\n        text_inputs = batch[\"text_inputs\"]\n\n        logger.info(\"[preprocess_batch] Inferring prompt embeddings...\")\n        with self._load_model_context(\"text_encoder\"):\n            text_hidden_states = self.infer_text_embeddings(text_token_idss)\n            logger.info(\"[preprocess_batch] Inferring lyric embeddings...\")\n            lyric_hidden_states = self.infer_lyric_embeddings(lyric_token_idss)\n\n            is_covers = batch[\"is_covers\"]\n            precomputed_lm_hints_25hz = batch.get(\"precomputed_lm_hints_25Hz\", None)\n            non_cover_text_input_ids = batch.get(\"non_cover_text_input_ids\", None)\n            non_cover_text_attention_masks = batch.get(\"non_cover_text_attention_masks\", None)\n            non_cover_text_hidden_states = None\n            if non_cover_text_input_ids is not None:\n                logger.info(\"[preprocess_batch] Inferring non-cover text embeddings...\")\n                non_cover_text_hidden_states = self.infer_text_embeddings(non_cover_text_input_ids)\n\n        repaint_mask = batch.get(\"repaint_mask\", None)\n\n        return (\n            keys,\n            text_inputs,\n            src_latents,\n            target_latents,\n            text_hidden_states,\n            text_attention_mask,\n            lyric_hidden_states,\n            lyric_attention_mask,\n            audio_attention_mask,\n            refer_audio_acoustic_hidden_states_packed,\n            refer_audio_order_mask,\n            chunk_mask,\n            spans,\n            is_covers,\n            audio_codes,\n            lyric_token_idss,\n            precomputed_lm_hints_25hz,\n            non_cover_text_hidden_states,\n            non_cover_text_attention_masks,\n            repaint_mask,\n        )\n"
  },
  {
    "path": "acestep/core/generation/handler/conditioning_embed_test.py",
    "content": "\"\"\"Unit tests for conditioning embedding/preprocess mixin.\"\"\"\n\nfrom contextlib import contextmanager\nimport unittest\n\nimport torch\n\nfrom acestep.core.generation.handler.conditioning_embed import ConditioningEmbedMixin\n\n\nclass _FakeTextEncoder:\n    \"\"\"Minimal text encoder stub for preprocess tests.\"\"\"\n\n    def __call__(self, input_ids, lyric_attention_mask=None):\n        del lyric_attention_mask\n        b, t = input_ids.shape\n        return type(\"O\", (), {\"last_hidden_state\": torch.zeros(b, t, 6, dtype=torch.float32)})\n\n    def embed_tokens(self, token_ids):\n        b, t = token_ids.shape\n        return torch.zeros(b, t, 6, dtype=torch.float32)\n\n\nclass _Host(ConditioningEmbedMixin):\n    \"\"\"Minimal host implementing ConditioningEmbedMixin dependencies.\"\"\"\n\n    def __init__(self):\n        self.device = \"cpu\"\n        self.dtype = torch.float32\n        self.silence_latent = torch.zeros(1, 128, 6, dtype=torch.float32)\n        self.text_encoder = _FakeTextEncoder()\n        self.tiled_encode_calls = 0\n\n    def _ensure_silence_latent_on_device(self):\n        return None\n\n    @contextmanager\n    def _load_model_context(self, _name):\n        yield\n\n    def tiled_encode(self, audio, offload_latent_to_cpu=True):\n        del offload_latent_to_cpu\n        self.tiled_encode_calls += 1\n        t = max(1, audio.shape[-1] // 1920)\n        return torch.zeros(1, 6, t, dtype=torch.float32)\n\n\nclass ConditioningEmbedMixinTests(unittest.TestCase):\n    \"\"\"Tests for ConditioningEmbedMixin methods.\"\"\"\n\n    def test_infer_refer_latent_returns_latents_and_order_mask(self):\n        \"\"\"Infer reference latents and preserve per-batch ordering mask.\"\"\"\n        host = _Host()\n        refer_audioss = [\n            [torch.ones(2, 96000)],\n            [torch.ones(2, 96000)],\n        ]\n        latents, order_mask = host.infer_refer_latent(refer_audioss)\n        self.assertEqual(latents.dim(), 3)\n        self.assertEqual(order_mask.tolist(), [0, 1])\n        self.assertEqual(host.tiled_encode_calls, 2)\n\n    def test_infer_refer_latent_cache_hit_reuses_encoding(self):\n        \"\"\"Reuse cached latent when the exact same tensor object appears multiple times.\"\"\"\n        host = _Host()\n        shared = torch.ones(2, 96000)\n        latents, order_mask = host.infer_refer_latent([[shared], [shared]])\n        self.assertEqual(latents.shape[0], 2)\n        self.assertEqual(order_mask.tolist(), [0, 1])\n        self.assertEqual(host.tiled_encode_calls, 1)\n\n    def test_infer_refer_latent_uses_silence_fast_path(self):\n        \"\"\"Use silence-latent shortcut when reference audio is an explicit zero tensor.\"\"\"\n        host = _Host()\n        latents, order_mask = host.infer_refer_latent([[torch.zeros(2, 96000)]])\n        self.assertEqual(latents.shape, (1, 128, 6))\n        self.assertEqual(order_mask.tolist(), [0])\n        self.assertEqual(host.tiled_encode_calls, 0)\n\n    def test_infer_refer_latent_handles_multiple_references_per_item(self):\n        \"\"\"Flatten multiple references for one batch item while preserving order index.\"\"\"\n        host = _Host()\n        refer_audioss = [[torch.ones(2, 96000), torch.ones(2, 96000)]]\n        latents, order_mask = host.infer_refer_latent(refer_audioss)\n        self.assertEqual(latents.shape[0], 2)\n        self.assertEqual(order_mask.tolist(), [0, 0])\n\n    def test_preprocess_batch_returns_expected_tuple_shape(self):\n        \"\"\"Preprocess batch and return full model-input tuple contract.\"\"\"\n        host = _Host()\n        batch = {\n            \"keys\": [\"k1\", \"k2\"],\n            \"target_latents\": torch.zeros(2, 128, 6, dtype=torch.float32),\n            \"src_latents\": torch.zeros(2, 128, 6, dtype=torch.float32),\n            \"latent_masks\": torch.ones(2, 128, dtype=torch.long),\n            \"refer_audioss\": [[torch.zeros(2, 96000)], [torch.zeros(2, 96000)]],\n            \"chunk_masks\": torch.ones(2, 128, dtype=torch.bool),\n            \"spans\": [(\"full\", 0, 128), (\"full\", 0, 128)],\n            \"text_token_idss\": torch.ones(2, 8, dtype=torch.long),\n            \"text_attention_masks\": torch.ones(2, 8, dtype=torch.long),\n            \"lyric_token_idss\": torch.ones(2, 10, dtype=torch.long),\n            \"lyric_attention_masks\": torch.ones(2, 10, dtype=torch.long),\n            \"text_inputs\": [\"a\", \"b\"],\n            \"is_covers\": torch.zeros(2, dtype=torch.bool),\n            \"precomputed_lm_hints_25Hz\": None,\n            \"non_cover_text_input_ids\": None,\n            \"non_cover_text_attention_masks\": None,\n        }\n        result = host.preprocess_batch(batch)\n        self.assertEqual(len(result), 20)\n        self.assertEqual(result[0], [\"k1\", \"k2\"])\n        self.assertEqual(result[3].shape, (2, 128, 6))\n\n\nif __name__ == \"__main__\":\n    unittest.main()\n"
  },
  {
    "path": "acestep/core/generation/handler/conditioning_masks.py",
    "content": "\"\"\"Chunk-mask and source-latent helpers for batch conditioning.\"\"\"\n\nfrom typing import Dict, List, Optional, Tuple\n\nimport torch\n\n# Phrase unique to lego task instructions — used to detect lego items from instruction text.\n# Matches both TASK_INSTRUCTIONS[\"lego\"] and TASK_INSTRUCTIONS[\"lego_default\"].\n_LEGO_INSTRUCTION_MARKER = \"based on the audio context\"\n\n\nclass ConditioningMaskMixin:\n    \"\"\"Mixin containing repaint mask/span and source-latent builders.\n\n    Depends on host members:\n    - Attributes: ``device``, ``sample_rate``.\n    \"\"\"\n\n    def _build_chunk_masks_and_src_latents(\n        self,\n        batch_size: int,\n        max_latent_length: int,\n        instructions: List[str],\n        audio_code_hints: List[Optional[str]],\n        target_wavs: torch.Tensor,\n        target_latents: torch.Tensor,\n        repainting_start: Optional[List[float]],\n        repainting_end: Optional[List[float]],\n        silence_latent_tiled: torch.Tensor,\n        chunk_mask_modes: Optional[List[str]] = None,\n    ) -> Tuple[\n        torch.Tensor,\n        List[Tuple[str, int, int]],\n        torch.Tensor,\n        torch.Tensor,\n        Optional[torch.Tensor],\n    ]:\n        \"\"\"Create chunk masks/spans, source latents, and repaint injection mask.\n\n        Returns:\n            Tuple of (chunk_masks, spans, is_covers, src_latents, repaint_mask).\n            ``repaint_mask`` is a boolean ``[B, T]`` tensor (True = generate,\n            False = preserve source) when any item uses repainting, else ``None``.\n        \"\"\"\n        chunk_masks = []\n        spans = []\n        is_covers = []\n        repainting_ranges: Dict[int, Tuple[int, int]] = {}\n\n        for i in range(batch_size):\n            has_code_hint = audio_code_hints[i] is not None\n            if repainting_start is not None and repainting_end is not None:\n                start_sec = repainting_start[i] if repainting_start[i] is not None else 0.0\n                end_sec = repainting_end[i]\n                if end_sec is not None and end_sec > start_sec:\n                    left_padding_sec = max(0, -start_sec)\n                    adjusted_start_sec = start_sec + left_padding_sec\n                    adjusted_end_sec = end_sec + left_padding_sec\n                    start_latent = int(adjusted_start_sec * self.sample_rate // 1920)\n                    end_latent = int(adjusted_end_sec * self.sample_rate // 1920)\n                    start_latent = max(0, min(start_latent, max_latent_length - 1))\n                    end_latent = max(start_latent + 1, min(end_latent, max_latent_length))\n\n                    mask = torch.zeros(max_latent_length, dtype=torch.bool, device=self.device)\n                    mask[start_latent:end_latent] = True\n                    chunk_masks.append(mask)\n                    spans.append((\"repainting\", start_latent, end_latent))\n                    repainting_ranges[i] = (start_latent, end_latent)\n                    is_covers.append(False)\n                    continue\n\n            chunk_masks.append(torch.ones(max_latent_length, dtype=torch.bool, device=self.device))\n            spans.append((\"full\", 0, max_latent_length))\n            instruction_i = instructions[i] if instructions and i < len(instructions) else \"\"\n            instruction_lower = instruction_i.lower()\n            is_cover = (\n                \"generate audio semantic tokens\" in instruction_lower\n                and \"based on the given conditions\" in instruction_lower\n            ) or has_code_hint\n            is_covers.append(is_cover)\n\n        chunk_masks_tensor = torch.stack(chunk_masks)\n        if chunk_mask_modes:\n            for i, mode in enumerate(chunk_mask_modes):\n                if mode == \"auto\":\n                    chunk_masks_tensor[i] = 2.0\n        is_covers_tensor = torch.BoolTensor(is_covers).to(self.device)\n\n        src_latents_list = []\n        for i in range(batch_size):\n            has_code_hint = audio_code_hints[i] is not None\n            has_target_audio = has_code_hint or (target_wavs is not None and target_wavs[i].abs().sum() > 1e-6)\n            if has_target_audio:\n                if i in repainting_ranges:\n                    src_latent = target_latents[i].clone()\n                    start_latent, end_latent = repainting_ranges[i]\n                    instruction_i = instructions[i] if instructions and i < len(instructions) else \"\"\n                    is_lego = _LEGO_INSTRUCTION_MARKER in instruction_i.lower()\n                    if not is_lego:\n                        src_latent[start_latent:end_latent] = silence_latent_tiled[start_latent:end_latent]\n                    src_latents_list.append(src_latent)\n                else:\n                    src_latents_list.append(target_latents[i].clone())\n            else:\n                src_latents_list.append(silence_latent_tiled.clone())\n        src_latents = torch.stack(src_latents_list)\n\n        repaint_mask: Optional[torch.Tensor] = None\n        if repainting_ranges:\n            repaint_mask = torch.ones(\n                batch_size, max_latent_length, dtype=torch.bool, device=self.device,\n            )\n            for i, (start_latent, end_latent) in repainting_ranges.items():\n                repaint_mask[i] = False\n                repaint_mask[i, start_latent:end_latent] = True\n\n        return chunk_masks_tensor, spans, is_covers_tensor, src_latents, repaint_mask\n"
  },
  {
    "path": "acestep/core/generation/handler/conditioning_masks_test.py",
    "content": "\"\"\"Unit tests for ConditioningMaskMixin chunk-mask and source-latent behavior.\"\"\"\n\nimport unittest\nfrom typing import List, Optional\n\nimport torch\n\nfrom acestep.core.generation.handler.conditioning_masks import (\n    ConditioningMaskMixin,\n    _LEGO_INSTRUCTION_MARKER,\n)\n\n\nclass _Host(ConditioningMaskMixin):\n    \"\"\"Minimal host implementing ConditioningMaskMixin dependencies.\"\"\"\n\n    def __init__(self):\n        self.device = \"cpu\"\n        self.sample_rate = 48000\n\n\ndef _make_host():\n    return _Host()\n\n\ndef _build(\n    host,\n    batch_size: int = 1,\n    max_latent_length: int = 100,\n    instructions: Optional[List[str]] = None,\n    audio_code_hints: Optional[List[Optional[str]]] = None,\n    target_wavs: Optional[torch.Tensor] = None,\n    target_latents: Optional[torch.Tensor] = None,\n    repainting_start: Optional[List[float]] = None,\n    repainting_end: Optional[List[float]] = None,\n):\n    \"\"\"Call _build_chunk_masks_and_src_latents with sensible defaults.\"\"\"\n    if instructions is None:\n        instructions = [\"Fill the audio semantic mask based on the given conditions:\"] * batch_size\n    if audio_code_hints is None:\n        audio_code_hints = [None] * batch_size\n    if target_wavs is None:\n        target_wavs = torch.ones(batch_size, 2, 48000)\n    if target_latents is None:\n        # Non-zero so we can detect if they were replaced with silence\n        target_latents = torch.ones(batch_size, max_latent_length, 16)\n    silence_latent_tiled = torch.zeros(max_latent_length, 16)\n    return host._build_chunk_masks_and_src_latents(\n        batch_size=batch_size,\n        max_latent_length=max_latent_length,\n        instructions=instructions,\n        audio_code_hints=audio_code_hints,\n        target_wavs=target_wavs,\n        target_latents=target_latents,\n        repainting_start=repainting_start,\n        repainting_end=repainting_end,\n        silence_latent_tiled=silence_latent_tiled,\n    )\n\n\nclass ConditioningMaskLegoBehaviorTests(unittest.TestCase):\n    \"\"\"Verify lego mode keeps source audio latents intact (no silence replacement).\n\n    For lego, can_use_repainting=True so repainting_start/end are set and the\n    chunk mask is computed from the repainting range. However, src_latents must\n    NOT be silenced — the source audio is the musical context for the DiT.\n    \"\"\"\n\n    def test_lego_with_repainting_range_preserves_source_latents(self):\n        \"\"\"Lego with repainting_start/end must preserve src_latents (no silencing).\n\n        The chunk mask is computed from the range (marking which positions have\n        active audio to generate), but the source latents carry the backing track\n        context and must reach the DiT unchanged.\n        \"\"\"\n        host = _make_host()\n        target_latents = torch.ones(1, 100, 16) * 2.5\n        lego_instruction = \"Generate the GUITAR track based on the audio context:\"\n        chunk_masks, spans, is_covers, src_latents, _rm = _build(\n            host,\n            instructions=[lego_instruction],\n            target_latents=target_latents,\n            repainting_start=[0.0],\n            repainting_end=[4.0],  # 4 s at sample_rate=48000, stride=1920 → latents 0..100\n        )\n        self.assertTrue(\n            torch.allclose(src_latents, target_latents),\n            \"lego src_latents must equal the source audio latents, not be silenced\",\n        )\n        self.assertEqual(spans[0][0], \"repainting\", \"lego span should be 'repainting' (from range)\")\n\n    def test_lego_default_instruction_preserves_source_latents(self):\n        \"\"\"The lego_default instruction also preserves src_latents.\"\"\"\n        host = _make_host()\n        target_latents = torch.ones(1, 100, 16) * 1.7\n        lego_default_instruction = \"Generate the track based on the audio context:\"\n        chunk_masks, spans, is_covers, src_latents, _rm = _build(\n            host,\n            instructions=[lego_default_instruction],\n            target_latents=target_latents,\n            repainting_start=[0.0],\n            repainting_end=[4.0],\n        )\n        self.assertTrue(\n            torch.allclose(src_latents, target_latents),\n            \"lego_default src_latents must equal the source audio latents\",\n        )\n\n    def test_repaint_full_range_silences_repainting_region(self):\n        \"\"\"Repaint with full range should overwrite the repainting region with silence.\n\n        This verifies the existing repaint behavior is preserved: src_latents for\n        the masked region should be silence so the DiT regenerates that section.\n        \"\"\"\n        host = _make_host()\n        target_latents = torch.ones(1, 100, 16) * 2.5\n        chunk_masks, spans, is_covers, src_latents, _rm = _build(\n            host,\n            target_latents=target_latents,\n            repainting_start=[0.0],\n            repainting_end=[4.0],  # 4 seconds at sample_rate=48000, stride=1920 → latents 0..100\n        )\n        # With full-range repainting the src_latents region should be silenced\n        start_l, end_l = spans[0][1], spans[0][2]\n        self.assertEqual(spans[0][0], \"repainting\")\n        # The repainting region in src_latents should be zeros (silence)\n        self.assertTrue(\n            src_latents[0, start_l:end_l].abs().sum().item() < 1e-6,\n            \"repaint src_latents in masked region should be silence\",\n        )\n\n    def test_repaint_partial_range_silences_only_masked_region(self):\n        \"\"\"Partial repaint leaves source audio outside the mask intact.\"\"\"\n        host = _make_host()\n        target_latents = torch.ones(1, 100, 16) * 3.0\n        # Repaint 1s-2s (roughly latents 25-50 at 48000/1920=25 latents/sec)\n        chunk_masks, spans, is_covers, src_latents, _rm = _build(\n            host,\n            target_latents=target_latents,\n            repainting_start=[1.0],\n            repainting_end=[2.0],\n        )\n        self.assertEqual(spans[0][0], \"repainting\")\n        start_l, end_l = spans[0][1], spans[0][2]\n        # Repainting region should be silenced\n        self.assertTrue(\n            src_latents[0, start_l:end_l].abs().sum().item() < 1e-6,\n            \"masked region in repaint src_latents should be silence\",\n        )\n        # Outside region should keep original values\n        if start_l > 0:\n            self.assertAlmostEqual(\n                src_latents[0, 0, 0].item(),\n                3.0,\n                places=4,\n                msg=\"src_latents outside repaint mask should preserve original audio\",\n            )\n\n    def test_lego_instruction_marker_constant(self):\n        \"\"\"The _LEGO_INSTRUCTION_MARKER constant matches the actual lego instruction templates.\"\"\"\n        lego_instructions = [\n            \"Generate the GUITAR track based on the audio context:\",\n            \"Generate the track based on the audio context:\",\n            \"Generate the DRUMS track based on the audio context:\",\n        ]\n        for instr in lego_instructions:\n            self.assertIn(\n                _LEGO_INSTRUCTION_MARKER,\n                instr.lower(),\n                f\"Marker must match lego instruction: {instr!r}\",\n            )\n\n    def test_lego_detection_is_case_insensitive(self):\n        \"\"\"Lego detection must be case-insensitive via .lower().\"\"\"\n        host = _make_host()\n        target_latents = torch.ones(1, 100, 16) * 2.5\n        # Use mixed-case version of the instruction\n        mixed_case_instruction = \"Generate the GUITAR Track BASED ON THE AUDIO CONTEXT:\"\n        chunk_masks, spans, is_covers, src_latents, _rm = _build(\n            host,\n            instructions=[mixed_case_instruction],\n            target_latents=target_latents,\n            repainting_start=[0.0],\n            repainting_end=[4.0],\n        )\n        self.assertTrue(\n            torch.allclose(src_latents, target_latents),\n            \"lego detection must be case-insensitive; src_latents should be preserved\",\n        )\n\n    def test_lego_with_empty_instructions_does_not_raise(self):\n        \"\"\"Empty instructions list must not cause an index error or silence lego latents.\"\"\"\n        host = _make_host()\n        target_latents = torch.ones(1, 100, 16) * 2.5\n        # Empty instructions list — instructions[i] lookup falls back to \"\"\n        chunk_masks, spans, is_covers, src_latents, _rm = _build(\n            host,\n            instructions=[],\n            target_latents=target_latents,\n            repainting_start=[0.0],\n            repainting_end=[4.0],\n        )\n        # With an empty instructions list, is_lego=False, so the repaint silencing applies.\n        # This is a graceful fallback — the important thing is no exception is raised.\n        self.assertEqual(src_latents.shape, target_latents.shape)\n\n    def test_non_lego_instruction_still_silences_repaint(self):\n        \"\"\"A non-lego instruction in the repainting path must still silence src_latents.\"\"\"\n        host = _make_host()\n        target_latents = torch.ones(1, 100, 16) * 2.5\n        repaint_instruction = \"Repaint the mask area based on the given conditions:\"\n        chunk_masks, spans, is_covers, src_latents, _rm = _build(\n            host,\n            instructions=[repaint_instruction],\n            target_latents=target_latents,\n            repainting_start=[0.0],\n            repainting_end=[4.0],\n        )\n        start_l, end_l = spans[0][1], spans[0][2]\n        self.assertTrue(\n            src_latents[0, start_l:end_l].abs().sum().item() < 1e-6,\n            \"non-lego instruction must still silence the repaint region\",\n        )\n\n    def test_no_source_audio_produces_silence_latents(self):\n        \"\"\"Without source audio, src_latents should be silence (text2music behavior).\"\"\"\n        host = _make_host()\n        target_wavs = torch.zeros(1, 2, 48000)\n        chunk_masks, spans, is_covers, src_latents, _rm = _build(\n            host,\n            target_wavs=target_wavs,\n            repainting_start=None,\n            repainting_end=None,\n        )\n        self.assertTrue(\n            src_latents.abs().sum().item() < 1e-6,\n            \"src_latents should be silence when no source audio is present\",\n        )\n\n\nif __name__ == \"__main__\":\n    unittest.main()\n"
  },
  {
    "path": "acestep/core/generation/handler/conditioning_target.py",
    "content": "\"\"\"Target-latent preparation helpers for handler batch conditioning.\"\"\"\n\nfrom typing import List, Optional, Tuple\n\nimport torch\nfrom loguru import logger\n\n\nclass ConditioningTargetMixin:\n    \"\"\"Mixin containing target-audio to latent preparation helpers.\n\n    Depends on host members:\n    - Attributes: ``device``, ``dtype``, ``sample_rate``, ``silence_latent``.\n    - Methods: ``_ensure_silence_latent_on_device ``, ``_load_model_context``,\n      ``is_silence``, ``_encode_audio_to_latents``, ``_decode_audio_codes_to_latents``.\n    \"\"\"\n\n    def _get_silence_latent_slice(self, length: int) -> torch.Tensor:\n        \"\"\"Return a silence-latent slice of exactly ``length`` frames.\n\n        When the pre-computed ``silence_latent`` tensor is shorter than\n        ``length``, it is tiled (repeated) along the time axis to cover\n        the needed span.  This prevents a silent shape mismatch that\n        previously occurred when ``audio_duration`` was null and the\n        generated code count exceeded the stored silence latent size.\n        \"\"\"\n        available = self.silence_latent.shape[1]\n        if length <= available:\n            return self.silence_latent[0, :length, :]\n        # Tile to cover the needed length\n        repeats = (length + available - 1) // available  # ceil division\n        tiled = self.silence_latent[0].repeat(repeats, 1)  # (repeats*available, C)\n        return tiled[:length, :]\n\n    def _prepare_target_latents_and_wavs(\n        self,\n        batch_size: int,\n        target_wavs: torch.Tensor,\n        audio_code_hints: List[Optional[str]],\n    ) -> Tuple[torch.Tensor, torch.Tensor, torch.Tensor, int, torch.Tensor]:\n        \"\"\"Encode target audio/codes to latents and pad batch tensors.\"\"\"\n        self._ensure_silence_latent_on_device()\n\n        with torch.inference_mode():\n            target_latents_list = []\n            latent_lengths = []\n            target_wavs_list = [target_wavs[i].clone() for i in range(batch_size)]\n            if target_wavs.device != self.device:\n                target_wavs = target_wavs.to(self.device)\n\n            with self._load_model_context(\"vae\"):\n                _cached_wav_ref: Optional[torch.Tensor] = None\n                _cached_latent: Optional[torch.Tensor] = None\n\n                for i in range(batch_size):\n                    code_hint = audio_code_hints[i]\n                    if code_hint:\n                        logger.info(f\"[generate_music] Decoding audio codes for item {i}...\")\n                        decoded_latents = self._decode_audio_codes_to_latents(code_hint)\n                        if decoded_latents is not None:\n                            decoded_latents = decoded_latents.squeeze(0)\n                            target_latents_list.append(decoded_latents)\n                            latent_lengths.append(decoded_latents.shape[0])\n                            frames_from_codes = max(1, int(decoded_latents.shape[0] * 1920))\n                            target_wavs_list[i] = torch.zeros(2, frames_from_codes)\n                            continue\n\n                    current_wav = target_wavs_list[i].to(self.device).unsqueeze(0)\n                    if self.is_silence(current_wav):\n                        expected_latent_length = current_wav.shape[-1] // 1920\n                        target_latent = self._get_silence_latent_slice(expected_latent_length)\n                    else:\n                        if (\n                            _cached_wav_ref is not None\n                            and _cached_latent is not None\n                            and _cached_wav_ref.shape == current_wav.shape\n                            and torch.equal(_cached_wav_ref, current_wav)\n                        ):\n                            logger.info(\n                                f\"[generate_music] Reusing cached VAE latents for item {i} (same audio as previous item)\"\n                            )\n                            target_latent = _cached_latent.clone()\n                        else:\n                            logger.info(f\"[generate_music] Encoding target audio to latents for item {i}...\")\n                            target_latent = self._encode_audio_to_latents(current_wav.squeeze(0))\n                            _cached_wav_ref = current_wav\n                            _cached_latent = target_latent\n                    target_latents_list.append(target_latent)\n                    latent_lengths.append(target_latent.shape[0])\n\n            max_target_frames = max(wav.shape[-1] for wav in target_wavs_list)\n            padded_target_wavs = []\n            for wav in target_wavs_list:\n                if wav.shape[-1] < max_target_frames:\n                    pad_frames = max_target_frames - wav.shape[-1]\n                    wav = torch.nn.functional.pad(wav, (0, pad_frames), \"constant\", 0)\n                padded_target_wavs.append(wav)\n            target_wavs = torch.stack(padded_target_wavs)\n\n            max_latent_length = max(latent.shape[0] for latent in target_latents_list)\n            max_latent_length = max(128, max_latent_length)\n            silence_latent_tiled = self._get_silence_latent_slice(max_latent_length)\n\n            padded_latents = []\n            for latent in target_latents_list:\n                latent_length = latent.shape[0]\n                if latent_length < max_latent_length:\n                    pad_length = max_latent_length - latent_length\n                    latent = torch.cat([latent, self._get_silence_latent_slice(pad_length)], dim=0)\n                padded_latents.append(latent)\n\n            target_latents = torch.stack(padded_latents)\n            latent_masks = torch.stack(\n                [\n                    torch.cat(\n                        [\n                            torch.ones(l, dtype=torch.long, device=self.device),\n                            torch.zeros(max_latent_length - l, dtype=torch.long, device=self.device),\n                        ]\n                    )\n                    for l in latent_lengths\n                ]\n            )\n            return target_wavs, target_latents, latent_masks, max_latent_length, silence_latent_tiled\n"
  },
  {
    "path": "acestep/core/generation/handler/conditioning_text.py",
    "content": "\"\"\"Text-token and hint preparation helpers for batch conditioning.\"\"\"\n\nfrom typing import List, Optional, Tuple\n\nimport torch\nfrom loguru import logger\n\nfrom acestep.constants import DEFAULT_DIT_INSTRUCTION, SFT_GEN_PROMPT\n\n\nclass ConditioningTextMixin:\n    \"\"\"Mixin containing prompt tokenization and LM-hint preparation.\n\n    Depends on host members:\n    - Attributes: ``text_tokenizer``, ``device``, ``dtype``, ``silence_latent``.\n    - Methods: ``_decode_audio_codes_to_latents``, ``_extract_caption_and_language``,\n      ``_format_instruction``, ``_format_lyrics``, ``_pad_sequences``.\n    \"\"\"\n\n    def _prepare_precomputed_lm_hints(\n        self,\n        batch_size: int,\n        audio_code_hints: List[Optional[str]],\n        max_latent_length: int,\n        silence_latent_tiled: torch.Tensor,\n    ) -> Optional[torch.Tensor]:\n        \"\"\"Decode audio-code hints into padded 25Hz latent hints.\"\"\"\n        precomputed_lm_hints_25hz_list = []\n        for i in range(batch_size):\n            if audio_code_hints[i] is not None:\n                logger.info(f\"[generate_music] Decoding audio codes for LM hints for item {i}...\")\n                hints = self._decode_audio_codes_to_latents(audio_code_hints[i])\n                if hints is not None:\n                    if hints.shape[1] < max_latent_length:\n                        pad_length = max_latent_length - hints.shape[1]\n                        pad = self.silence_latent\n                        if pad.dim() == 2:\n                            pad = pad.unsqueeze(0)\n                        if hints.dim() == 2:\n                            hints = hints.unsqueeze(0)\n                        pad_chunk = pad[:, :pad_length, :]\n                        if pad_chunk.device != hints.device or pad_chunk.dtype != hints.dtype:\n                            pad_chunk = pad_chunk.to(device=hints.device, dtype=hints.dtype)\n                        hints = torch.cat([hints, pad_chunk], dim=1)\n                    elif hints.shape[1] > max_latent_length:\n                        hints = hints[:, :max_latent_length, :]\n                    precomputed_lm_hints_25hz_list.append(hints[0])\n                else:\n                    precomputed_lm_hints_25hz_list.append(None)\n            else:\n                precomputed_lm_hints_25hz_list.append(None)\n\n        if any(h is not None for h in precomputed_lm_hints_25hz_list):\n            return torch.stack([h if h is not None else silence_latent_tiled for h in precomputed_lm_hints_25hz_list])\n        return None\n\n    def _prepare_text_conditioning_inputs(\n        self,\n        batch_size: int,\n        instructions: List[str],\n        captions: List[str],\n        lyrics: List[str],\n        parsed_metas: List[str],\n        vocal_languages: List[str],\n        audio_cover_strength: float,\n        global_captions: Optional[List[str]] = None,\n        chunk_mask_modes: Optional[List[str]] = None,\n    ) -> Tuple[List[str], torch.Tensor, torch.Tensor, torch.Tensor, torch.Tensor, Optional[torch.Tensor], Optional[torch.Tensor]]:\n        \"\"\"Tokenize caption/lyric prompts and optional non-cover branch prompts.\"\"\"\n        actual_captions, actual_languages = self._extract_caption_and_language(parsed_metas, captions, vocal_languages)\n\n        # Detect is_lego_sft from the loaded model config (set on the SFT-stems checkpoint).\n        is_lego_sft = (\n            hasattr(self, \"model\")\n            and self.model is not None\n            and getattr(self.model.config, \"is_lego_sft\", False)\n        )\n\n        text_inputs = []\n        text_token_idss = []\n        text_attention_masks = []\n        lyric_token_idss = []\n        lyric_attention_masks = []\n\n        for i in range(batch_size):\n            instruction = self._format_instruction(\n                instructions[i] if i < len(instructions) else DEFAULT_DIT_INSTRUCTION\n            )\n            actual_caption = actual_captions[i]\n            actual_language = actual_languages[i]\n\n            # SFT-stems lego: build the training-compatible caption block.\n            #\n            # Training format — full mode (\"Generate the {TAG} track based on the audio context:\"):\n            #   \"Global: {global_caption}\\nLocal: {local_caption}\\nMask Control: true\"\n            #   where global_caption = full song description, local_caption = per-stem description\n            #\n            # Training format — chunk mode (\"Generate a segment of the {TAG} track...\"):\n            #   \"Local: {local_caption}\\nMask Control: true\"    (no Global prefix)\n            #\n            # The caller passes:\n            #   - captions[i]        → local/per-track description  (→ Local:)\n            #   - global_captions[i] → global/full-song description (→ Global:)\n            if is_lego_sft:\n                local_cap = actual_caption\n                global_cap = (global_captions[i] if global_captions and i < len(global_captions) else \"\") or \"\"\n                instr_lower = instruction.lower()\n                is_chunk_mode = \"a segment\" in instr_lower\n                chunk_mode_i = (chunk_mask_modes[i] if chunk_mask_modes and i < len(chunk_mask_modes) else \"auto\")\n                mask_control_str = \"Mask Control: false\" if chunk_mode_i == \"auto\" else \"Mask Control: true\"\n                if is_chunk_mode:\n                    actual_caption = f\"Local: {local_cap}\\n{mask_control_str}\"\n                else:\n                    actual_caption = f\"Global: {global_cap}\\nLocal: {local_cap}\\n{mask_control_str}\"\n\n            text_prompt = SFT_GEN_PROMPT.format(instruction, actual_caption, parsed_metas[i])\n\n            if i == 0:\n                logger.info(f\"\\n{'='*70}\")\n                logger.info(\"🔍 [DEBUG] DiT TEXT ENCODER INPUT (Inference)\")\n                logger.info(f\"{'='*70}\")\n                logger.info(f\"text_prompt:\\n{text_prompt}\")\n                logger.info(f\"{'='*70}\")\n                logger.info(f\"lyrics_text:\\n{self._format_lyrics(lyrics[i], actual_language)}\")\n                logger.info(f\"{'='*70}\\n\")\n\n            text_inputs_dict = self.text_tokenizer(\n                text_prompt,\n                padding=\"longest\",\n                truncation=True,\n                max_length=256,\n                return_tensors=\"pt\",\n            )\n            text_token_ids = text_inputs_dict.input_ids[0]\n            text_attention_mask = text_inputs_dict.attention_mask[0].bool()\n\n            lyrics_text = self._format_lyrics(lyrics[i], actual_language)\n            lyrics_inputs_dict = self.text_tokenizer(\n                lyrics_text,\n                padding=\"longest\",\n                truncation=True,\n                max_length=2048,\n                return_tensors=\"pt\",\n            )\n            lyric_token_ids = lyrics_inputs_dict.input_ids[0]\n            lyric_attention_mask = lyrics_inputs_dict.attention_mask[0].bool()\n\n            text_inputs.append(text_prompt + \"\\n\\n\" + lyrics_text)\n            text_token_idss.append(text_token_ids)\n            text_attention_masks.append(text_attention_mask)\n            lyric_token_idss.append(lyric_token_ids)\n            lyric_attention_masks.append(lyric_attention_mask)\n\n        max_text_length = max(len(seq) for seq in text_token_idss)\n        padded_text_token_idss = self._pad_sequences(text_token_idss, max_text_length, self.text_tokenizer.pad_token_id)\n        padded_text_attention_masks = self._pad_sequences(text_attention_masks, max_text_length, 0)\n\n        max_lyric_length = max(len(seq) for seq in lyric_token_idss)\n        padded_lyric_token_idss = self._pad_sequences(lyric_token_idss, max_lyric_length, self.text_tokenizer.pad_token_id)\n        padded_lyric_attention_masks = self._pad_sequences(lyric_attention_masks, max_lyric_length, 0)\n\n        padded_non_cover_text_input_ids = None\n        padded_non_cover_text_attention_masks = None\n        if audio_cover_strength < 1.0:\n            non_cover_text_input_ids = []\n            non_cover_text_attention_masks = []\n            for i in range(batch_size):\n                text_prompt = SFT_GEN_PROMPT.format(\n                    self._format_instruction(DEFAULT_DIT_INSTRUCTION), actual_captions[i], parsed_metas[i]\n                )\n                text_inputs_dict = self.text_tokenizer(\n                    text_prompt,\n                    padding=\"longest\",\n                    truncation=True,\n                    max_length=256,\n                    return_tensors=\"pt\",\n                )\n                non_cover_text_input_ids.append(text_inputs_dict.input_ids[0])\n                non_cover_text_attention_masks.append(text_inputs_dict.attention_mask[0].bool())\n            padded_non_cover_text_input_ids = self._pad_sequences(\n                non_cover_text_input_ids, max_text_length, self.text_tokenizer.pad_token_id\n            )\n            padded_non_cover_text_attention_masks = self._pad_sequences(non_cover_text_attention_masks, max_text_length, 0)\n\n        return (\n            text_inputs,\n            padded_text_token_idss,\n            padded_text_attention_masks,\n            padded_lyric_token_idss,\n            padded_lyric_attention_masks,\n            padded_non_cover_text_input_ids,\n            padded_non_cover_text_attention_masks,\n        )\n"
  },
  {
    "path": "acestep/core/generation/handler/cover_noise_strength_forwarding_test.py",
    "content": "\"\"\"Regression tests for cover-noise-strength forwarding in generation.\"\"\"\n\nimport contextlib\nimport types\nimport unittest\nfrom unittest.mock import Mock\n\nimport torch\n\ntry:\n    from acestep.handler import AceStepHandler\nexcept ModuleNotFoundError:\n    AceStepHandler = None\n\n\n@unittest.skipIf(AceStepHandler is None, \"AceStepHandler dependencies are unavailable in this test environment.\")\nclass CoverNoiseStrengthForwardingTests(unittest.TestCase):\n    \"\"\"Verify `cover_noise_strength` survives the service-generation flow.\"\"\"\n\n    def test_service_generate_forwards_cover_noise_strength(self) -> None:\n        \"\"\"`service_generate` should pass `cover_noise_strength` to model generation.\"\"\"\n        handler = AceStepHandler.__new__(AceStepHandler)\n\n        handler.config = types.SimpleNamespace(is_turbo=False)\n        handler.device = \"cpu\"\n        handler.dtype = torch.float32\n        handler.use_mlx_dit = False\n        handler.mlx_decoder = None\n        handler.silence_latent = torch.zeros(1, 16, 4, dtype=torch.float32)\n\n        handler._normalize_instructions = lambda instructions, _batch, _default: instructions\n        handler._normalize_audio_code_hints = lambda hints, _batch: hints\n        handler._ensure_silence_latent_on_device = lambda: None\n        handler._load_model_context = lambda _name: contextlib.nullcontext()\n\n        prepare_batch_mock = Mock(return_value={\"latent_masks\": torch.ones(1, 4, dtype=torch.long)})\n        handler._prepare_batch = prepare_batch_mock\n\n        src_latents = torch.zeros(1, 4, 4, dtype=torch.float32)\n        tensor_2d = torch.ones(1, 4, dtype=torch.float32)\n        bool_mask = torch.ones(1, 4, dtype=torch.bool)\n        handler.preprocess_batch = Mock(\n            return_value=(\n                [\"k1\"],\n                [\"text\"],\n                src_latents,\n                src_latents.clone(),\n                tensor_2d.clone(),\n                bool_mask.clone(),\n                tensor_2d.clone(),\n                bool_mask.clone(),\n                bool_mask.clone(),\n                tensor_2d.clone(),\n                torch.tensor([0], dtype=torch.long),\n                bool_mask.clone(),\n                [(\"full\", 0, 4)],\n                torch.tensor([True]),\n                None,\n                torch.ones(1, 2, dtype=torch.long),\n                None,\n                None,\n                None,\n                None,\n            )\n        )\n\n        model = Mock()\n        model.prepare_condition = Mock(\n            return_value=(tensor_2d.clone(), bool_mask.clone(), tensor_2d.clone())\n        )\n        model.generate_audio = Mock(return_value={\"target_latents\": src_latents.clone()})\n        handler.model = model\n\n        cover_noise_strength = 0.42\n        handler.service_generate(\n            captions=\"caption\",\n            lyrics=\"lyrics\",\n            cover_noise_strength=cover_noise_strength,\n            target_wavs=torch.zeros(1, 2, 1920, dtype=torch.float32),\n            refer_audios=[[torch.zeros(2, 1920, dtype=torch.float32)]],\n        )\n\n        self.assertEqual(\n            prepare_batch_mock.call_args.kwargs.get(\"cover_noise_strength\"),\n            cover_noise_strength,\n        )\n        self.assertEqual(\n            model.generate_audio.call_args.kwargs.get(\"cover_noise_strength\"),\n            cover_noise_strength,\n        )\n\n\nif __name__ == \"__main__\":\n    unittest.main()\n"
  },
  {
    "path": "acestep/core/generation/handler/diffusion.py",
    "content": "\"\"\"Diffusion-related handler helpers.\"\"\"\n\nfrom typing import Any, Dict, Optional\n\nimport torch\nfrom acestep.models.mlx.dit_generate import mlx_generate_diffusion\n\n\nclass DiffusionMixin:\n    \"\"\"Mixin containing diffusion execution helpers.\n\n    Required host attributes:\n    - ``mlx_decoder``: MLX decoder object passed to ``mlx_generate_diffusion``.\n    - ``device``: torch device string used for output tensor placement.\n    - ``dtype``: torch dtype used for output tensor conversion.\n    \"\"\"\n\n    def _mlx_run_diffusion(\n        self,\n        encoder_hidden_states,\n        encoder_attention_mask,\n        context_latents,\n        src_latents,\n        seed,\n        infer_method: str = \"ode\",\n        shift: float = 3.0,\n        timesteps=None,\n        infer_steps: Optional[int] = None,\n        guidance_scale: float = 1.0,\n        null_condition_emb: Optional[torch.Tensor] = None,\n        cfg_interval_start: float = 0.0,\n        cfg_interval_end: float = 1.0,\n        audio_cover_strength: float = 1.0,\n        encoder_hidden_states_non_cover=None,\n        encoder_attention_mask_non_cover=None,\n        context_latents_non_cover=None,\n        disable_tqdm: bool = False,\n    ) -> Dict[str, Any]:\n        \"\"\"Run the MLX diffusion loop and return generated latents.\n\n        Args:\n            encoder_hidden_states: Prompt conditioning tensor.\n            encoder_attention_mask: Unused; accepted for API compatibility.\n            context_latents: Context/reference latent tensor.\n            src_latents: Source latent tensor used for shape and initialization.\n            seed: Random seed used by MLX diffusion.\n            infer_method: Diffusion method, one of ``\"ode\"`` or ``\"sde\"``.\n            shift: Timestep shift value.\n            timesteps: Optional iterable or tensor-like custom timesteps.\n            infer_steps: Number of diffusion steps (overrides fixed 8-step table).\n            guidance_scale: CFG guidance strength (>1.0 enables CFG).\n            null_condition_emb: Null condition embedding tensor for CFG.\n            cfg_interval_start: Timestep ratio below which CFG is disabled.\n            cfg_interval_end: Timestep ratio above which CFG is disabled.\n            audio_cover_strength: Blend factor for cover conditioning.\n            encoder_hidden_states_non_cover: Optional non-cover conditioning tensor.\n            encoder_attention_mask_non_cover: Unused; accepted for API compatibility.\n            context_latents_non_cover: Optional non-cover context latent tensor.\n            disable_tqdm: If True, suppress the diffusion progress bar.\n\n        Returns:\n            Dict[str, Any]: ``{\"target_latents\": torch.Tensor, \"time_costs\": dict}``.\n        \"\"\"\n        import numpy as np\n\n        _ = encoder_attention_mask, encoder_attention_mask_non_cover\n\n        for required_attr in (\"mlx_decoder\", \"device\", \"dtype\"):\n            if not hasattr(self, required_attr):\n                raise AttributeError(f\"DiffusionMixin host is missing required attribute '{required_attr}'\")\n\n        if infer_method not in {\"ode\", \"sde\"}:\n            raise ValueError(f\"Unsupported infer_method '{infer_method}'. Expected 'ode' or 'sde'.\")\n\n        if timesteps is not None and not (hasattr(timesteps, \"__iter__\") or hasattr(timesteps, \"tolist\")):\n            raise TypeError(\"timesteps must be iterable, tensor-like, or None\")\n\n        if encoder_hidden_states.shape[0] != context_latents.shape[0]:\n            raise ValueError(\n                \"Batch dimension mismatch: encoder_hidden_states and context_latents must share dim 0\"\n            )\n        if encoder_hidden_states.shape[0] != src_latents.shape[0]:\n            raise ValueError(\n                \"Batch dimension mismatch: encoder_hidden_states and src_latents must share dim 0\"\n            )\n        if encoder_hidden_states_non_cover is not None and encoder_hidden_states_non_cover.shape[0] != encoder_hidden_states.shape[0]:\n            raise ValueError(\n                \"Batch dimension mismatch: encoder_hidden_states_non_cover must share dim 0 with encoder_hidden_states\"\n            )\n        if context_latents_non_cover is not None and context_latents_non_cover.shape[0] != context_latents.shape[0]:\n            raise ValueError(\n                \"Batch dimension mismatch: context_latents_non_cover must share dim 0 with context_latents\"\n            )\n\n        enc_np = encoder_hidden_states.detach().cpu().float().numpy()\n        ctx_np = context_latents.detach().cpu().float().numpy()\n        src_shape = (src_latents.shape[0], src_latents.shape[1], src_latents.shape[2])\n\n        enc_nc_np = (\n            encoder_hidden_states_non_cover.detach().cpu().float().numpy()\n            if encoder_hidden_states_non_cover is not None else None\n        )\n        ctx_nc_np = (\n            context_latents_non_cover.detach().cpu().float().numpy()\n            if context_latents_non_cover is not None else None\n        )\n\n        null_cond_np = (\n            null_condition_emb.detach().cpu().float().numpy()\n            if null_condition_emb is not None else None\n        )\n\n        ts_list = None\n        if timesteps is not None:\n            if hasattr(timesteps, \"tolist\"):\n                ts_list = timesteps.tolist()\n            else:\n                ts_list = list(timesteps)\n\n        result = mlx_generate_diffusion(\n            mlx_decoder=self.mlx_decoder,\n            encoder_hidden_states_np=enc_np,\n            context_latents_np=ctx_np,\n            src_latents_shape=src_shape,\n            seed=seed,\n            infer_method=infer_method,\n            shift=shift,\n            timesteps=ts_list,\n            infer_steps=infer_steps,\n            guidance_scale=guidance_scale,\n            null_condition_emb_np=null_cond_np,\n            cfg_interval_start=cfg_interval_start,\n            cfg_interval_end=cfg_interval_end,\n            audio_cover_strength=audio_cover_strength,\n            encoder_hidden_states_non_cover_np=enc_nc_np,\n            context_latents_non_cover_np=ctx_nc_np,\n            compile_model=getattr(self, \"mlx_dit_compiled\", False),\n            disable_tqdm=disable_tqdm,\n        )\n\n        target_np = result[\"target_latents\"]\n        target_tensor = torch.from_numpy(target_np).to(device=self.device, dtype=self.dtype)\n\n        return {\n            \"target_latents\": target_tensor,\n            \"time_costs\": result[\"time_costs\"],\n        }\n"
  },
  {
    "path": "acestep/core/generation/handler/diffusion_test.py",
    "content": "import unittest\nfrom unittest.mock import patch\n\nimport numpy as np\nimport torch\n\nfrom acestep.core.generation.handler.diffusion import DiffusionMixin\n\n\nclass _Host(DiffusionMixin):\n    def __init__(self, device: str = \"cpu\", dtype: torch.dtype = torch.float32):\n        self.mlx_decoder = object()\n        self.device = device\n        self.dtype = dtype\n\n\nclass _IterableTimesteps:\n    def __init__(self, values):\n        self._values = values\n\n    def __iter__(self):\n        return iter(self._values)\n\n\nclass DiffusionMixinTests(unittest.TestCase):\n    def test_mlx_run_diffusion_converts_inputs_and_outputs_tensor(self):\n        host = _Host(dtype=torch.float16)\n        encoder_hidden_states = torch.randn(2, 4, 8, dtype=torch.float64)\n        encoder_attention_mask = torch.ones(2, 4, dtype=torch.int64)\n        context_latents = torch.randn(2, 16, 8, dtype=torch.float64)\n        src_latents = torch.zeros(2, 3, 5, dtype=torch.float32)\n        timesteps = torch.tensor([1.0, 0.5], dtype=torch.float32)\n        non_cover_hidden = torch.randn(2, 4, 8, dtype=torch.float64)\n        non_cover_mask = torch.ones(2, 4, dtype=torch.int64)\n        non_cover_context = torch.randn(2, 16, 8, dtype=torch.float64)\n        fake_target = np.ones((2, 3, 5), dtype=np.float32)\n\n        def _fake_generate(**kwargs):\n            self.assertIs(kwargs[\"mlx_decoder\"], host.mlx_decoder)\n            self.assertEqual(kwargs[\"src_latents_shape\"], (2, 3, 5))\n            self.assertEqual(kwargs[\"timesteps\"], [1.0, 0.5])\n            self.assertEqual(kwargs[\"infer_method\"], \"sde\")\n            self.assertEqual(kwargs[\"shift\"], 2.0)\n            self.assertEqual(kwargs[\"audio_cover_strength\"], 0.6)\n            self.assertEqual(kwargs[\"encoder_hidden_states_np\"].dtype, np.float32)\n            self.assertEqual(kwargs[\"context_latents_np\"].dtype, np.float32)\n            self.assertEqual(kwargs[\"encoder_hidden_states_non_cover_np\"].dtype, np.float32)\n            self.assertEqual(kwargs[\"context_latents_non_cover_np\"].dtype, np.float32)\n            return {\"target_latents\": fake_target, \"time_costs\": {\"diffusion_time_cost\": 1.2}}\n\n        with patch(\"acestep.core.generation.handler.diffusion.mlx_generate_diffusion\", side_effect=_fake_generate):\n            result = host._mlx_run_diffusion(\n                encoder_hidden_states=encoder_hidden_states,\n                encoder_attention_mask=encoder_attention_mask,\n                context_latents=context_latents,\n                src_latents=src_latents,\n                seed=123,\n                infer_method=\"sde\",\n                shift=2.0,\n                timesteps=timesteps,\n                audio_cover_strength=0.6,\n                encoder_hidden_states_non_cover=non_cover_hidden,\n                encoder_attention_mask_non_cover=non_cover_mask,\n                context_latents_non_cover=non_cover_context,\n            )\n\n        self.assertIn(\"target_latents\", result)\n        self.assertIn(\"time_costs\", result)\n        self.assertEqual(result[\"time_costs\"][\"diffusion_time_cost\"], 1.2)\n        self.assertEqual(result[\"target_latents\"].dtype, torch.float16)\n        self.assertEqual(result[\"target_latents\"].device.type, \"cpu\")\n        self.assertTrue(torch.allclose(result[\"target_latents\"], torch.ones_like(result[\"target_latents\"])))\n\n    def test_mlx_run_diffusion_handles_optional_and_iterable_timesteps(self):\n        host = _Host(dtype=torch.float32)\n        encoder_hidden_states = torch.randn(1, 2, 3, dtype=torch.float32)\n        encoder_attention_mask = torch.ones(1, 2, dtype=torch.int64)\n        context_latents = torch.randn(1, 4, 3, dtype=torch.float32)\n        src_latents = torch.zeros(1, 2, 3, dtype=torch.float32)\n        timesteps = _IterableTimesteps([0.9, 0.8, 0.7])\n\n        def _fake_generate(**kwargs):\n            self.assertEqual(kwargs[\"timesteps\"], [0.9, 0.8, 0.7])\n            self.assertIsNone(kwargs[\"encoder_hidden_states_non_cover_np\"])\n            self.assertIsNone(kwargs[\"context_latents_non_cover_np\"])\n            return {\"target_latents\": np.zeros((1, 2, 3), dtype=np.float32), \"time_costs\": {}}\n\n        with patch(\"acestep.core.generation.handler.diffusion.mlx_generate_diffusion\", side_effect=_fake_generate):\n            result = host._mlx_run_diffusion(\n                encoder_hidden_states=encoder_hidden_states,\n                encoder_attention_mask=encoder_attention_mask,\n                context_latents=context_latents,\n                src_latents=src_latents,\n                seed=1,\n                timesteps=timesteps,\n            )\n\n        self.assertEqual(tuple(result[\"target_latents\"].shape), (1, 2, 3))\n        self.assertEqual(result[\"target_latents\"].dtype, torch.float32)\n\n    def test_mlx_run_diffusion_rejects_invalid_infer_method(self):\n        host = _Host()\n        x = torch.randn(1, 2, 3)\n        with self.assertRaises(ValueError):\n            host._mlx_run_diffusion(\n                encoder_hidden_states=x,\n                encoder_attention_mask=torch.ones(1, 2, dtype=torch.int64),\n                context_latents=torch.randn(1, 4, 3),\n                src_latents=torch.randn(1, 2, 3),\n                seed=1,\n                infer_method=\"bad\",\n            )\n\n    def test_mlx_run_diffusion_rejects_non_iterable_timesteps(self):\n        host = _Host()\n        x = torch.randn(1, 2, 3)\n        with self.assertRaises(TypeError):\n            host._mlx_run_diffusion(\n                encoder_hidden_states=x,\n                encoder_attention_mask=torch.ones(1, 2, dtype=torch.int64),\n                context_latents=torch.randn(1, 4, 3),\n                src_latents=torch.randn(1, 2, 3),\n                seed=1,\n                timesteps=123,\n            )\n\n    def test_mlx_run_diffusion_rejects_batch_mismatch(self):\n        host = _Host()\n        with self.assertRaises(ValueError):\n            host._mlx_run_diffusion(\n                encoder_hidden_states=torch.randn(2, 2, 3),\n                encoder_attention_mask=torch.ones(2, 2, dtype=torch.int64),\n                context_latents=torch.randn(1, 4, 3),\n                src_latents=torch.randn(2, 2, 3),\n                seed=1,\n            )\n\n    def test_mlx_run_diffusion_requires_host_attributes(self):\n        class _BrokenHost(DiffusionMixin):\n            pass\n\n        host = _BrokenHost()\n        x = torch.randn(1, 2, 3)\n        with self.assertRaises(AttributeError):\n            host._mlx_run_diffusion(\n                encoder_hidden_states=x,\n                encoder_attention_mask=torch.ones(1, 2, dtype=torch.int64),\n                context_latents=torch.randn(1, 4, 3),\n                src_latents=torch.randn(1, 2, 3),\n                seed=1,\n            )\n\n\nif __name__ == \"__main__\":\n    unittest.main()\n"
  },
  {
    "path": "acestep/core/generation/handler/generate_music.py",
    "content": "\"\"\"Top-level ``generate_music`` orchestration mixin.\n\nThis module provides the public ``generate_music`` entry point extracted from\n``AceStepHandler`` so orchestration stays separate from lower-level helpers.\n\"\"\"\n\nimport gc\nimport traceback\nfrom typing import Any, Dict, List, Optional, Union\n\nimport torch\nfrom loguru import logger\n\nfrom acestep.constants import DEFAULT_DIT_INSTRUCTION\nfrom acestep.core.generation.handler.repaint_waveform_splice import (\n    apply_repaint_waveform_splice,\n)\nfrom acestep.gpu_config import (\n    DIT_INFERENCE_VRAM_PER_BATCH,\n    VRAM_SAFETY_MARGIN_GB,\n    get_effective_free_vram_gb,\n)\n\n\ndef _resolve_repaint_config(\n    mode: str = \"balanced\",\n    strength: float = 0.5,\n) -> tuple:\n    \"\"\"Convert repaint mode and strength into concrete numeric parameters.\n\n    Higher *strength* means more aggressive repainting (less source preservation).\n\n    Args:\n        mode: One of ``\"conservative\"``, ``\"balanced\"``, or ``\"aggressive\"``.\n        strength: 0.0 = conservative (max preservation), 1.0 = aggressive\n            (pure diffusion).  Only effective in balanced mode.\n\n    Returns:\n        Tuple of ``(injection_ratio, crossfade_frames, wav_crossfade_sec)``.\n    \"\"\"\n    strength = max(0.0, min(1.0, strength))\n    if mode == \"aggressive\":\n        return 0.0, 0, 0.0\n    if mode == \"conservative\":\n        return 1.0, 25, 0.05\n    inv = 1.0 - strength\n    return inv, round(25 * inv), 0.05 * inv\n\n\nclass GenerateMusicMixin:\n    \"\"\"Coordinate request prep, service execution, decode, and payload assembly.\n\n    The host class is expected to implement helper methods invoked by this\n    orchestration flow.\n    \"\"\"\n\n    def _vram_preflight_check(\n        self,\n        actual_batch_size: int,\n        audio_duration: Optional[float],\n        guidance_scale: float,\n    ) -> Optional[Dict[str, Any]]:\n        \"\"\"Check free VRAM headroom before attempting service_generate.\n\n        Model weights are already resident in GPU memory at this point.  We\n        only need to verify there is enough room for the diffusion-pass\n        activations (intermediate attention maps, FFN buffers, noise tensors)\n        plus a project-standard safety margin.\n\n        Args:\n            actual_batch_size: Number of samples being generated.\n            audio_duration: Requested audio length in seconds, or None for default.\n            guidance_scale: CFG guidance value; values > 1.0 indicate CFG is active\n                and the DiT runs two forward passes per step (doubling activation memory).\n\n        Returns:\n            An error payload dict when VRAM is insufficient, or None when the\n            check passes or no CUDA device is present (CPU/MPS/XPU fall through).\n        \"\"\"\n        if not torch.cuda.is_available():\n            return None\n\n        if getattr(self, \"offload_to_cpu\", False):\n            logger.debug(\n                \"[generate_music] VRAM pre-flight: skipping check \"\n                \"(offload_to_cpu=True, models loaded one-at-a-time)\"\n            )\n            return None\n\n        duration_s = audio_duration or 60.0\n        # CFG doubles forward-pass memory: two DiT evaluations per step.\n        dit_key = \"base\" if guidance_scale > 1.0 else \"turbo\"\n        per_batch_gb = DIT_INFERENCE_VRAM_PER_BATCH.get(dit_key, 0.6)\n        # Longer audio = more latent frames (5 Hz rate) = more memory.\n        duration_factor = max(1.0, duration_s / 60.0)\n        needed_gb = per_batch_gb * actual_batch_size * duration_factor + VRAM_SAFETY_MARGIN_GB\n\n        free_gb = get_effective_free_vram_gb()\n        logger.info(\n            \"[generate_music] VRAM pre-flight: {:.2f} GB free, ~{:.2f} GB needed \"\n            \"(batch={}, duration={:.0f}s, mode={}).\",\n            free_gb, needed_gb, actual_batch_size, duration_s, dit_key,\n        )\n\n        if free_gb >= needed_gb:\n            return None\n\n        msg = (\n            f\"Insufficient free VRAM: need ~{needed_gb:.1f} GB, \"\n            f\"only {free_gb:.1f} GB available. \"\n            f\"Reduce batch size (currently {actual_batch_size}) \"\n            f\"or audio duration (currently {duration_s:.0f}s).\"\n        )\n        logger.warning(\"[generate_music] VRAM pre-flight failed: {}\", msg)\n        return {\n            \"audios\": [],\n            \"status_message\": f\"Error: {msg}\",\n            \"extra_outputs\": {},\n            \"success\": False,\n            \"error\": msg,\n        }\n\n    def generate_music(\n        self,\n        captions: str,\n        global_caption: str = \"\",\n        lyrics: str = \"\",\n        bpm: Optional[int] = None,\n        key_scale: str = \"\",\n        time_signature: str = \"\",\n        vocal_language: str = \"en\",\n        inference_steps: int = 8,\n        guidance_scale: float = 7.0,\n        use_random_seed: bool = True,\n        seed: Optional[Union[str, float, int]] = -1,\n        reference_audio=None,\n        audio_duration: Optional[float] = None,\n        batch_size: Optional[int] = None,\n        src_audio=None,\n        audio_code_string: Union[str, List[str]] = \"\",\n        repainting_start: float = 0.0,\n        repainting_end: Optional[float] = None,\n        instruction: str = DEFAULT_DIT_INSTRUCTION,\n        audio_cover_strength: float = 1.0,\n        cover_noise_strength: float = 0.0,\n        task_type: str = \"text2music\",\n        use_adg: bool = False,\n        cfg_interval_start: float = 0.0,\n        cfg_interval_end: float = 1.0,\n        shift: float = 1.0,\n        infer_method: str = \"ode\",\n        use_tiled_decode: bool = True,\n        timesteps: Optional[List[float]] = None,\n        latent_shift: float = 0.0,\n        latent_rescale: float = 1.0,\n        chunk_mask_mode: str = \"auto\",\n        repaint_latent_crossfade_frames: int = 10,\n        repaint_wav_crossfade_sec: float = 0.0,\n        repaint_mode: str = \"balanced\",\n        repaint_strength: float = 0.5,\n        progress=None,\n    ) -> Dict[str, Any]:\n        \"\"\"Generate audio from text/reference inputs and return response payload.\n\n        Args:\n            captions: Text prompt describing requested music.\n            lyrics: Lyric text used for conditioning.\n            reference_audio: Optional reference-audio payload.\n            src_audio: Optional source audio for repaint/cover.\n            inference_steps: Diffusion step count.\n            guidance_scale: CFG guidance value.\n            seed: Optional explicit seed from caller/UI.\n            infer_method: Diffusion method name.\n            timesteps: Optional custom timestep schedule.\n            use_tiled_decode: Whether tiled VAE decode is used.\n            latent_shift: Additive latent post-processing value.\n            latent_rescale: Multiplicative latent post-processing value.\n            progress: Optional callback taking ``(ratio, desc=...)``.\n\n        Returns:\n            Dict[str, Any]: Standard payload with generated audio tensors, status,\n            intermediate outputs, success flag, and optional error text.\n\n        Raises:\n            No exceptions are re-raised. Runtime failures are converted into the\n            returned error payload.\n        \"\"\"\n        progress = self._resolve_generate_music_progress(progress)\n        if self.model is None or self.vae is None or self.text_tokenizer is None or self.text_encoder is None:\n            readiness_error = self._validate_generate_music_readiness()\n            return readiness_error\n\n        task_type, instruction = self._resolve_generate_music_task(\n            task_type=task_type,\n            audio_code_string=audio_code_string,\n            instruction=instruction,\n        )\n\n        logger.info(\"[generate_music] Starting generation...\")\n        if progress:\n            progress(0.51, desc=\"Preparing inputs...\")\n        logger.info(\"[generate_music] Preparing inputs...\")\n\n        runtime = self._prepare_generate_music_runtime(\n            batch_size=batch_size,\n            audio_duration=audio_duration,\n            repainting_end=repainting_end,\n            seed=seed,\n            use_random_seed=use_random_seed,\n        )\n        actual_batch_size = runtime[\"actual_batch_size\"]\n        actual_seed_list = runtime[\"actual_seed_list\"]\n        seed_value_for_ui = runtime[\"seed_value_for_ui\"]\n        audio_duration = runtime[\"audio_duration\"]\n        repainting_end = runtime[\"repainting_end\"]\n\n        try:\n            refer_audios, processed_src_audio, audio_error = self._prepare_reference_and_source_audio(\n                reference_audio=reference_audio,\n                src_audio=src_audio,\n                audio_code_string=audio_code_string,\n                actual_batch_size=actual_batch_size,\n                task_type=task_type,\n            )\n            if audio_error is not None:\n                return audio_error\n\n            service_inputs = self._prepare_generate_music_service_inputs(\n                actual_batch_size=actual_batch_size,\n                processed_src_audio=processed_src_audio,\n                audio_duration=audio_duration,\n                captions=captions,\n                global_caption=global_caption,\n                lyrics=lyrics,\n                vocal_language=vocal_language,\n                instruction=instruction,\n                bpm=bpm,\n                key_scale=key_scale,\n                time_signature=time_signature,\n                task_type=task_type,\n                audio_code_string=audio_code_string,\n                repainting_start=repainting_start,\n                repainting_end=repainting_end,\n                chunk_mask_mode=chunk_mask_mode,\n            )\n            vram_error = self._vram_preflight_check(\n                actual_batch_size=actual_batch_size,\n                audio_duration=audio_duration,\n                guidance_scale=guidance_scale,\n            )\n            if vram_error is not None:\n                return vram_error\n\n            injection_ratio, resolved_cf_frames, resolved_wav_cf = (\n                _resolve_repaint_config(repaint_mode, repaint_strength)\n            )\n\n            service_run = self._run_generate_music_service_with_progress(\n                progress=progress,\n                actual_batch_size=actual_batch_size,\n                audio_duration=audio_duration,\n                inference_steps=inference_steps,\n                timesteps=timesteps,\n                service_inputs=service_inputs,\n                refer_audios=refer_audios,\n                guidance_scale=guidance_scale,\n                actual_seed_list=actual_seed_list,\n                audio_cover_strength=audio_cover_strength,\n                cover_noise_strength=cover_noise_strength,\n                use_adg=use_adg,\n                cfg_interval_start=cfg_interval_start,\n                cfg_interval_end=cfg_interval_end,\n                shift=shift,\n                infer_method=infer_method,\n                repaint_crossfade_frames=resolved_cf_frames,\n                repaint_injection_ratio=injection_ratio,\n            )\n            outputs = service_run[\"outputs\"]\n            infer_steps_for_progress = service_run[\"infer_steps_for_progress\"]\n\n            pred_latents, time_costs = self._prepare_generate_music_decode_state(\n                outputs=outputs,\n                infer_steps_for_progress=infer_steps_for_progress,\n                actual_batch_size=actual_batch_size,\n                audio_duration=audio_duration,\n                latent_shift=latent_shift,\n                latent_rescale=latent_rescale,\n            )\n            pred_wavs, pred_latents_cpu, time_costs = self._decode_generate_music_pred_latents(\n                pred_latents=pred_latents,\n                progress=progress,\n                use_tiled_decode=use_tiled_decode,\n                time_costs=time_costs,\n            )\n            repainting_start_batch = service_inputs.get(\"repainting_start_batch\")\n            repainting_end_batch = service_inputs.get(\"repainting_end_batch\")\n            do_wav_splice = (\n                repaint_mode != \"aggressive\"\n                and repainting_start_batch is not None\n                and repainting_end_batch is not None\n            )\n            if do_wav_splice:\n                pred_wavs = apply_repaint_waveform_splice(\n                    pred_wavs=pred_wavs,\n                    src_wavs=service_inputs[\"target_wavs_tensor\"],\n                    repainting_starts=repainting_start_batch,\n                    repainting_ends=repainting_end_batch,\n                    sample_rate=self.sample_rate,\n                    crossfade_duration=resolved_wav_cf,\n                )\n            result = self._build_generate_music_success_payload(\n                outputs=outputs,\n                pred_wavs=pred_wavs,\n                pred_latents_cpu=pred_latents_cpu,\n                time_costs=time_costs,\n                seed_value_for_ui=seed_value_for_ui,\n                actual_batch_size=actual_batch_size,\n                progress=progress,\n            )\n            # Clear GPU tensor references from the mutable outputs dict so\n            # accelerator memory is reclaimable before the next generation.\n            _gpu_keys = (\n                \"src_latents\", \"target_latents_input\", \"chunk_masks\",\n                \"latent_masks\", \"encoder_hidden_states\",\n                \"encoder_attention_mask\", \"context_latents\",\n                \"lyric_token_idss\",\n            )\n            for _k in _gpu_keys:\n                outputs.pop(_k, None)\n            del outputs, pred_wavs, pred_latents_cpu\n            gc.collect()\n            self._empty_cache()\n            return result\n        except Exception as exc:\n            error_msg = f\"Error: {exc!s}\\n{traceback.format_exc()}\"\n            logger.exception(\"[generate_music] Generation failed\")\n            return {\n                \"audios\": [],\n                \"status_message\": error_msg,\n                \"extra_outputs\": {},\n                \"success\": False,\n                \"error\": f\"{exc!s}\",\n            }\n"
  },
  {
    "path": "acestep/core/generation/handler/generate_music_decode.py",
    "content": "\"\"\"Decode/validation helpers for ``generate_music`` orchestration.\"\"\"\n\nimport gc\nimport os\nimport time\nfrom typing import Any, Dict, Optional, Tuple\n\nimport torch\nfrom loguru import logger\n\nfrom acestep.gpu_config import get_effective_free_vram_gb\n\n\nclass GenerateMusicDecodeMixin:\n    \"\"\"Validate generated latents and decode them into waveform tensors.\"\"\"\n\n    def _prepare_generate_music_decode_state(\n        self,\n        outputs: Dict[str, Any],\n        infer_steps_for_progress: int,\n        actual_batch_size: int,\n        audio_duration: Optional[float],\n        latent_shift: float,\n        latent_rescale: float,\n    ) -> Tuple[torch.Tensor, Dict[str, Any]]:\n        \"\"\"Collect decode inputs and validate raw diffusion latents.\n\n        Args:\n            outputs: ``service_generate`` output payload containing target latents and timings.\n            infer_steps_for_progress: Effective diffusion step count for estimates.\n            actual_batch_size: Effective generation batch size.\n            audio_duration: Optional generation duration in seconds.\n            latent_shift: Additive latent post-processing shift.\n            latent_rescale: Multiplicative latent post-processing scale.\n\n        Returns:\n            Tuple containing validated ``pred_latents`` and mutable ``time_costs``.\n\n        Raises:\n            RuntimeError: If latents contain NaN/Inf values or collapse to all zeros.\n        \"\"\"\n        logger.info(\"[generate_music] Model generation completed. Decoding latents...\")\n        pred_latents = outputs[\"target_latents\"]\n        time_costs = outputs[\"time_costs\"]\n        time_costs[\"offload_time_cost\"] = self.current_offload_cost\n\n        per_step = time_costs.get(\"diffusion_per_step_time_cost\")\n        if isinstance(per_step, (int, float)) and per_step > 0:\n            self._last_diffusion_per_step_sec = float(per_step)\n            self._update_progress_estimate(\n                per_step_sec=float(per_step),\n                infer_steps=infer_steps_for_progress,\n                batch_size=actual_batch_size,\n                duration_sec=audio_duration if audio_duration and audio_duration > 0 else None,\n            )\n\n        if self.debug_stats:\n            logger.debug(\n                f\"[generate_music] pred_latents: {pred_latents.shape}, dtype={pred_latents.dtype} \"\n                f\"{pred_latents.min()=}, {pred_latents.max()=}, {pred_latents.mean()=} \"\n                f\"{pred_latents.std()=}\"\n            )\n        else:\n            logger.debug(f\"[generate_music] pred_latents: {pred_latents.shape}, dtype={pred_latents.dtype}\")\n        logger.debug(f\"[generate_music] time_costs: {time_costs}\")\n\n        if torch.isnan(pred_latents).any() or torch.isinf(pred_latents).any():\n            raise RuntimeError(\n                \"Generation produced NaN or Inf latents. \"\n                \"This usually indicates a checkpoint/config mismatch \"\n                \"or unsupported quantization/backend combination. \"\n                \"Try running with --backend pt or verify your model checkpoints match this release.\"\n            )\n        if pred_latents.numel() > 0 and pred_latents.abs().sum() == 0:\n            raise RuntimeError(\n                \"Generation produced zero latents. \"\n                \"This usually indicates a checkpoint/config mismatch or unsupported setup.\"\n            )\n        if latent_shift != 0.0 or latent_rescale != 1.0:\n            logger.info(\n                f\"[generate_music] Applying latent post-processing: shift={latent_shift}, \"\n                f\"rescale={latent_rescale}\"\n            )\n            if self.debug_stats:\n                logger.debug(\n                    f\"[generate_music] Latent BEFORE shift/rescale: min={pred_latents.min():.4f}, \"\n                    f\"max={pred_latents.max():.4f}, mean={pred_latents.mean():.4f}, \"\n                    f\"std={pred_latents.std():.4f}\"\n                )\n            pred_latents = pred_latents * latent_rescale + latent_shift\n            if self.debug_stats:\n                logger.debug(\n                    f\"[generate_music] Latent AFTER shift/rescale: min={pred_latents.min():.4f}, \"\n                    f\"max={pred_latents.max():.4f}, mean={pred_latents.mean():.4f}, \"\n                    f\"std={pred_latents.std():.4f}\"\n                )\n        return pred_latents, time_costs\n\n    def _decode_generate_music_pred_latents(\n        self,\n        pred_latents: torch.Tensor,\n        progress: Any,\n        use_tiled_decode: bool,\n        time_costs: Dict[str, Any],\n    ) -> Tuple[torch.Tensor, torch.Tensor, Dict[str, Any]]:\n        \"\"\"Decode predicted latents and update decode timing metrics.\n\n        Args:\n            pred_latents: Predicted latent tensor shaped ``[batch, frames, dim]``.\n            progress: Optional progress callback.\n            use_tiled_decode: Whether tiled VAE decode should be used.\n            time_costs: Mutable time-cost payload from service generation.\n\n        Returns:\n            Tuple of decoded waveforms, CPU latents, and updated time-cost payload.\n        \"\"\"\n        if progress:\n            progress(0.8, desc=\"Decoding audio...\")\n        logger.info(\"[generate_music] Decoding latents with VAE...\")\n        start_time = time.time()\n        with torch.inference_mode():\n            with self._load_model_context(\"vae\"):\n                pred_latents_cpu = pred_latents.detach().cpu()\n                pred_latents_for_decode = pred_latents.transpose(1, 2).contiguous().to(self.vae.dtype)\n                del pred_latents\n                self._empty_cache()\n\n                logger.debug(\n                    \"[generate_music] Before VAE decode: \"\n                    f\"allocated={self._memory_allocated()/1024**3:.2f}GB, \"\n                    f\"max={self._max_memory_allocated()/1024**3:.2f}GB\"\n                )\n                using_mlx_vae = self.use_mlx_vae and self.mlx_vae is not None\n                vae_cpu = False\n                vae_device = None\n                if not using_mlx_vae:\n                    vae_cpu = os.environ.get(\"ACESTEP_VAE_ON_CPU\", \"0\").lower() in (\"1\", \"true\", \"yes\")\n                    if not vae_cpu:\n                        if self.device == \"mps\":\n                            logger.info(\n                                \"[generate_music] MPS device: skipping VRAM check \"\n                                \"(unified memory), keeping VAE on MPS\"\n                            )\n                        else:\n                            effective_free = get_effective_free_vram_gb()\n                            logger.info(\n                                \"[generate_music] Effective free VRAM before VAE decode: \"\n                                f\"{effective_free:.2f} GB\"\n                            )\n                            if effective_free < 0.5:\n                                logger.warning(\n                                    \"[generate_music] Only \"\n                                    f\"{effective_free:.2f} GB free VRAM; auto-enabling CPU VAE decode\"\n                                )\n                                vae_cpu = True\n                    if vae_cpu:\n                        logger.info(\"[generate_music] Moving VAE to CPU for decode (ACESTEP_VAE_ON_CPU=1)...\")\n                        vae_device = next(self.vae.parameters()).device\n                        self.vae = self.vae.cpu()\n                        pred_latents_for_decode = pred_latents_for_decode.cpu()\n                        self._empty_cache()\n                try:\n                    if use_tiled_decode:\n                        logger.info(\"[generate_music] Using tiled VAE decode to reduce VRAM usage...\")\n                        pred_wavs = self.tiled_decode(pred_latents_for_decode)\n                    elif using_mlx_vae:\n                        try:\n                            pred_wavs = self._mlx_vae_decode(pred_latents_for_decode)\n                        except Exception as exc:\n                            logger.warning(\n                                f\"[generate_music] MLX direct decode failed ({exc}), falling back to PyTorch\"\n                            )\n                            decoder_output = self.vae.decode(pred_latents_for_decode)\n                            pred_wavs = decoder_output.sample\n                            del decoder_output\n                    else:\n                        decoder_output = self.vae.decode(pred_latents_for_decode)\n                        pred_wavs = decoder_output.sample\n                        del decoder_output\n                finally:\n                    if vae_cpu and vae_device is not None:\n                        logger.info(\"[generate_music] Restoring VAE to original device after CPU decode path...\")\n                        self.vae = self.vae.to(vae_device)\n                    self._empty_cache()\n                logger.debug(\n                    \"[generate_music] After VAE decode: \"\n                    f\"allocated={self._memory_allocated()/1024**3:.2f}GB, \"\n                    f\"max={self._max_memory_allocated()/1024**3:.2f}GB\"\n                )\n                del pred_latents_for_decode\n                if pred_wavs.dtype != torch.float32:\n                    pred_wavs = pred_wavs.float()\n                peak = pred_wavs.abs().amax(dim=[1, 2], keepdim=True)\n                if torch.any(peak > 1.0):\n                    pred_wavs = pred_wavs / peak.clamp(min=1.0)\n                self._empty_cache()\n        gc.collect()\n        self._empty_cache()\n        end_time = time.time()\n        time_costs[\"vae_decode_time_cost\"] = end_time - start_time\n        time_costs[\"total_time_cost\"] = time_costs[\"total_time_cost\"] + time_costs[\"vae_decode_time_cost\"]\n        time_costs[\"offload_time_cost\"] = self.current_offload_cost\n        return pred_wavs, pred_latents_cpu, time_costs\n"
  },
  {
    "path": "acestep/core/generation/handler/generate_music_decode_test.py",
    "content": "\"\"\"Tests for extracted ``generate_music`` decode helper mixin behavior.\"\"\"\n\nimport importlib.util\nimport types\nimport sys\nimport unittest\nfrom contextlib import contextmanager\nfrom pathlib import Path\nfrom unittest.mock import patch\n\nimport torch\n\n\ndef _load_generate_music_decode_module():\n    \"\"\"Load ``generate_music_decode.py`` from disk and return its module object.\n\n    Raises ``FileNotFoundError`` or ``ImportError`` when loading fails.\n    \"\"\"\n    repo_root = Path(__file__).resolve().parents[4]\n    if str(repo_root) not in sys.path:\n        sys.path.insert(0, str(repo_root))\n    package_paths = {\n        \"acestep\": repo_root / \"acestep\",\n        \"acestep.core\": repo_root / \"acestep\" / \"core\",\n        \"acestep.core.generation\": repo_root / \"acestep\" / \"core\" / \"generation\",\n        \"acestep.core.generation.handler\": repo_root / \"acestep\" / \"core\" / \"generation\" / \"handler\",\n    }\n    for package_name, package_path in package_paths.items():\n        if package_name in sys.modules:\n            continue\n        package_module = types.ModuleType(package_name)\n        package_module.__path__ = [str(package_path)]\n        sys.modules[package_name] = package_module\n    module_path = Path(__file__).with_name(\"generate_music_decode.py\")\n    spec = importlib.util.spec_from_file_location(\n        \"acestep.core.generation.handler.generate_music_decode\",\n        module_path,\n    )\n    module = importlib.util.module_from_spec(spec)\n    assert spec.loader is not None\n    spec.loader.exec_module(module)\n    return module\n\n\nGENERATE_MUSIC_DECODE_MODULE = _load_generate_music_decode_module()\nGenerateMusicDecodeMixin = GENERATE_MUSIC_DECODE_MODULE.GenerateMusicDecodeMixin\n\n\nclass _FakeDecodeOutput:\n    \"\"\"Minimal VAE decode output container exposing ``sample`` attribute.\"\"\"\n\n    def __init__(self, sample: torch.Tensor):\n        \"\"\"Store decoded sample tensor for mixin decode flow.\"\"\"\n        self.sample = sample\n\n\nclass _FakeVae:\n    \"\"\"Minimal VAE stand-in with dtype, decode, and parameter iteration hooks.\"\"\"\n\n    def __init__(self):\n        \"\"\"Initialize deterministic dtype/device state for decode tests.\"\"\"\n        self.dtype = torch.float32\n        self._param = torch.nn.Parameter(torch.zeros(1))\n\n    def decode(self, latents: torch.Tensor):\n        \"\"\"Return deterministic decoded waveform output.\"\"\"\n        return _FakeDecodeOutput(torch.ones(latents.shape[0], 2, 8))\n\n    def parameters(self):\n        \"\"\"Yield one parameter so `.device` lookups remain valid.\"\"\"\n        yield self._param\n\n    def cpu(self):\n        \"\"\"Return self for test-only CPU transfer calls.\"\"\"\n        return self\n\n    def to(self, *_args, **_kwargs):\n        \"\"\"Return self for test-only device transfer calls.\"\"\"\n        return self\n\n\nclass _Host(GenerateMusicDecodeMixin):\n    \"\"\"Minimal decode-mixin host exposing deterministic state for assertions.\"\"\"\n\n    def __init__(self):\n        \"\"\"Initialize deterministic runtime state for decode tests.\"\"\"\n        self.current_offload_cost = 0.25\n        self.debug_stats = False\n        self._last_diffusion_per_step_sec = None\n        self.estimate_calls = []\n        self.progress_calls = []\n        self.device = \"cpu\"\n        self.use_mlx_vae = True\n        self.mlx_vae = object()\n        self.vae = _FakeVae()\n\n    def _update_progress_estimate(self, **kwargs):\n        \"\"\"Capture estimate updates for assertions.\"\"\"\n        self.estimate_calls.append(kwargs)\n\n    @contextmanager\n    def _load_model_context(self, _model_name):\n        \"\"\"Provide no-op model context manager for decode tests.\"\"\"\n        yield\n\n    def _empty_cache(self):\n        \"\"\"Provide no-op cache clear helper for decode tests.\"\"\"\n        return None\n\n    def _memory_allocated(self):\n        \"\"\"Return deterministic allocated-memory value for debug logging.\"\"\"\n        return 0.0\n\n    def _max_memory_allocated(self):\n        \"\"\"Return deterministic max-memory value for debug logging.\"\"\"\n        return 0.0\n\n    def _mlx_vae_decode(self, latents):\n        \"\"\"Return deterministic decoded waveform for MLX decode branch.\"\"\"\n        _ = latents\n        return torch.ones(1, 2, 8)\n\n    def tiled_decode(self, latents):\n        \"\"\"Return deterministic decoded waveform for tiled decode branch.\"\"\"\n        _ = latents\n        return torch.ones(1, 2, 8)\n\n\nclass GenerateMusicDecodeMixinTests(unittest.TestCase):\n    \"\"\"Verify decode-state preparation and latent decode helper behavior.\"\"\"\n\n    def test_prepare_decode_state_updates_progress_estimates(self):\n        \"\"\"It updates timing fields and progress estimate metadata for valid latents.\"\"\"\n        host = _Host()\n        outputs = {\n            \"target_latents\": torch.ones(1, 4, 3),\n            \"time_costs\": {\"total_time_cost\": 1.0, \"diffusion_per_step_time_cost\": 0.2},\n        }\n        pred_latents, time_costs = host._prepare_generate_music_decode_state(\n            outputs=outputs,\n            infer_steps_for_progress=8,\n            actual_batch_size=1,\n            audio_duration=12.0,\n            latent_shift=0.0,\n            latent_rescale=1.0,\n        )\n        self.assertEqual(tuple(pred_latents.shape), (1, 4, 3))\n        self.assertEqual(time_costs[\"offload_time_cost\"], 0.25)\n        self.assertEqual(host._last_diffusion_per_step_sec, 0.2)\n        self.assertEqual(host.estimate_calls[0][\"infer_steps\"], 8)\n\n    def test_prepare_decode_state_raises_for_nan_latents(self):\n        \"\"\"It raises runtime error when diffusion latents contain NaN values.\"\"\"\n        host = _Host()\n        outputs = {\n            \"target_latents\": torch.tensor([[[float(\"nan\")]]]),\n            \"time_costs\": {\"total_time_cost\": 1.0},\n        }\n        with self.assertRaises(RuntimeError):\n            host._prepare_generate_music_decode_state(\n                outputs=outputs,\n                infer_steps_for_progress=8,\n                actual_batch_size=1,\n                audio_duration=None,\n                latent_shift=0.0,\n                latent_rescale=1.0,\n            )\n\n    def test_decode_pred_latents_updates_decode_time_and_returns_cpu_latents(self):\n        \"\"\"It decodes latents and updates decode timing metrics in time_costs.\"\"\"\n        host = _Host()\n        pred_latents = torch.ones(1, 4, 3)\n        time_costs = {\"total_time_cost\": 1.0}\n\n        def _progress(value, desc=None):\n            \"\"\"Capture progress updates for assertions.\"\"\"\n            host.progress_calls.append((value, desc))\n\n        with patch.object(GENERATE_MUSIC_DECODE_MODULE.time, \"time\", side_effect=[10.0, 11.5]):\n            pred_wavs, pred_latents_cpu, updated_costs = host._decode_generate_music_pred_latents(\n                pred_latents=pred_latents,\n                progress=_progress,\n                use_tiled_decode=False,\n                time_costs=time_costs,\n            )\n\n        self.assertEqual(tuple(pred_wavs.shape), (1, 2, 8))\n        self.assertEqual(pred_latents_cpu.device.type, \"cpu\")\n        self.assertAlmostEqual(updated_costs[\"vae_decode_time_cost\"], 1.5, places=6)\n        self.assertAlmostEqual(updated_costs[\"total_time_cost\"], 2.5, places=6)\n        self.assertAlmostEqual(updated_costs[\"offload_time_cost\"], 0.25, places=6)\n        self.assertEqual(host.progress_calls[0][0], 0.8)\n\n    def test_decode_pred_latents_restores_vae_device_on_decode_error(self):\n        \"\"\"It restores VAE device in the CPU-offload path even when decode raises.\"\"\"\n\n        class _FailingVae(_FakeVae):\n            \"\"\"VAE double that raises during decode and records transfer calls.\"\"\"\n\n            def __init__(self):\n                \"\"\"Initialize transfer call trackers for restoration assertions.\"\"\"\n                super().__init__()\n                self.cpu_calls = 0\n                self.to_calls = []\n\n            def decode(self, latents: torch.Tensor):\n                \"\"\"Raise decode error to exercise restoration in finally branch.\"\"\"\n                _ = latents\n                raise RuntimeError(\"decode failed\")\n\n            def cpu(self):\n                \"\"\"Record explicit CPU transfer and return self.\"\"\"\n                self.cpu_calls += 1\n                return self\n\n            def to(self, *args, **kwargs):\n                \"\"\"Record restore transfer target and return self.\"\"\"\n                self.to_calls.append((args, kwargs))\n                return self\n\n        class _FailingHost(_Host):\n            \"\"\"Host variant that forces non-MLX VAE decode and tracks cache clears.\"\"\"\n\n            def __init__(self):\n                \"\"\"Set non-MLX state so CPU offload path is exercised deterministically.\"\"\"\n                super().__init__()\n                self.use_mlx_vae = False\n                self.mlx_vae = None\n                self.vae = _FailingVae()\n                self.empty_cache_calls = 0\n\n            def _empty_cache(self):\n                \"\"\"Count cache-clear calls to verify finally cleanup runs.\"\"\"\n                self.empty_cache_calls += 1\n\n        host = _FailingHost()\n        pred_latents = torch.ones(1, 4, 3)\n        time_costs = {\"total_time_cost\": 1.0}\n\n        with patch.dict(GENERATE_MUSIC_DECODE_MODULE.os.environ, {\"ACESTEP_VAE_ON_CPU\": \"1\"}, clear=False):\n            with self.assertRaisesRegex(RuntimeError, \"decode failed\"):\n                host._decode_generate_music_pred_latents(\n                    pred_latents=pred_latents,\n                    progress=None,\n                    use_tiled_decode=False,\n                    time_costs=time_costs,\n                )\n\n        self.assertEqual(host.vae.cpu_calls, 1)\n        self.assertEqual(len(host.vae.to_calls), 1)\n        self.assertGreaterEqual(host.empty_cache_calls, 2)\n\n\n    def test_decode_pred_latents_does_not_restore_latents_to_gpu_after_successful_cpu_decode(self):\n        \"\"\"It does not move pred_latents_for_decode back to GPU after a successful CPU decode.\n\n        The removed ``pred_latents_for_decode = pred_latents_for_decode.to(vae_device)`` line\n        was causing a wasteful re-allocation of the already-decoded input tensor on the\n        GPU.  After the fix, only the VAE itself is restored; the input latent is not.\n        \"\"\"\n\n        class _SuccessVae(_FakeVae):\n            \"\"\"VAE double that records transfer calls and succeeds on decode.\"\"\"\n\n            def __init__(self):\n                \"\"\"Initialize transfer call trackers.\"\"\"\n                super().__init__()\n                self.vae_to_calls = []\n                self._device = \"cuda\"\n\n            def decode(self, latents: torch.Tensor):\n                \"\"\"Return a simple decoded output.\"\"\"\n                return _FakeDecodeOutput(torch.ones(latents.shape[0], 2, 8))\n\n            def cpu(self):\n                \"\"\"Simulate VAE being moved to CPU.\"\"\"\n                self._device = \"cpu\"\n                return self\n\n            def to(self, *args, **kwargs):\n                \"\"\"Record VAE device-transfer destinations.\"\"\"\n                self.vae_to_calls.append(args[0] if args else kwargs)\n                return self\n\n        class _SuccessHost(_Host):\n            \"\"\"Host that forces non-MLX VAE so the CPU-decode path is exercised.\"\"\"\n\n            def __init__(self):\n                \"\"\"Configure non-MLX state and a tracking VAE.\"\"\"\n                super().__init__()\n                self.use_mlx_vae = False\n                self.mlx_vae = None\n                self.vae = _SuccessVae()\n                self.device = \"cuda\"\n\n        host = _SuccessHost()\n        pred_latents = torch.ones(1, 4, 3)\n        time_costs = {\"total_time_cost\": 1.0}\n\n        with patch.dict(GENERATE_MUSIC_DECODE_MODULE.os.environ, {\"ACESTEP_VAE_ON_CPU\": \"1\"}, clear=False):\n            pred_wavs, _cpu_latents, _costs = host._decode_generate_music_pred_latents(\n                pred_latents=pred_latents,\n                progress=None,\n                use_tiled_decode=False,\n                time_costs=time_costs,\n            )\n\n        # VAE itself must be restored to its original device.\n        self.assertEqual(len(host.vae.vae_to_calls), 1)\n        # The decoded waveform must be returned correctly.\n        self.assertEqual(tuple(pred_wavs.shape), (1, 2, 8))\n\n\nif __name__ == \"__main__\":\n    unittest.main()\n\n"
  },
  {
    "path": "acestep/core/generation/handler/generate_music_execute.py",
    "content": "\"\"\"Execution helper for ``generate_music`` service invocation with progress tracking.\"\"\"\n\nimport os\nimport threading\nfrom typing import Any, Dict, List, Optional, Sequence\n\nfrom loguru import logger\n\n# Maximum wall-clock seconds to wait for service_generate before declaring a hang.\n# Generous default: most generations finish in 30-120s, but large batches on slow\n# GPUs can take several minutes.  Override via ACESTEP_GENERATION_TIMEOUT env var.\n_DEFAULT_GENERATION_TIMEOUT = int(os.environ.get(\"ACESTEP_GENERATION_TIMEOUT\", \"600\"))\n\n\nclass GenerateMusicExecuteMixin:\n    \"\"\"Run service generation under diffusion progress estimation lifecycle.\"\"\"\n\n    def _run_generate_music_service_with_progress(\n        self,\n        progress: Any,\n        actual_batch_size: int,\n        audio_duration: Optional[float],\n        inference_steps: int,\n        timesteps: Optional[Sequence[float]],\n        service_inputs: Dict[str, Any],\n        refer_audios: Optional[List[Any]],\n        guidance_scale: float,\n        actual_seed_list: Optional[List[int]],\n        audio_cover_strength: float,\n        cover_noise_strength: float,\n        use_adg: bool,\n        cfg_interval_start: float,\n        cfg_interval_end: float,\n        shift: float,\n        infer_method: str,\n        repaint_crossfade_frames: int = 10,\n        repaint_injection_ratio: float = 0.5,\n    ) -> Dict[str, Any]:\n        \"\"\"Invoke ``service_generate`` while maintaining background progress estimation.\n\n        Wraps the synchronous CUDA call in a monitored thread so that a hung\n        diffusion loop becomes a recoverable ``TimeoutError`` instead of a\n        permanent UI freeze.\n        \"\"\"\n        infer_steps_for_progress = len(timesteps) if timesteps else inference_steps\n        progress_desc = f\"Generating music (batch size: {actual_batch_size})...\"\n        progress(0.52, desc=progress_desc)\n        stop_event = None\n        progress_thread = None\n\n        # --- Timeout-wrapped service_generate ---\n        # Run the actual CUDA work in a child thread so we can join() with a\n        # deadline.  If it exceeds the timeout the calling thread unblocks and\n        # raises TimeoutError, which propagates to generate_music()'s\n        # try/except and becomes a clean error payload for the UI.\n        _result: Dict[str, Any] = {}\n        _error: Dict[str, BaseException] = {}\n\n        def _service_target():\n            try:\n                _result[\"outputs\"] = self.service_generate(\n                    captions=service_inputs[\"captions_batch\"],\n                    global_captions=service_inputs.get(\"global_captions_batch\"),\n                    lyrics=service_inputs[\"lyrics_batch\"],\n                    metas=service_inputs[\"metas_batch\"],\n                    vocal_languages=service_inputs[\"vocal_languages_batch\"],\n                    refer_audios=refer_audios,\n                    target_wavs=service_inputs[\"target_wavs_tensor\"],\n                    infer_steps=inference_steps,\n                    guidance_scale=guidance_scale,\n                    seed=actual_seed_list,\n                    repainting_start=service_inputs[\"repainting_start_batch\"],\n                    repainting_end=service_inputs[\"repainting_end_batch\"],\n                    instructions=service_inputs[\"instructions_batch\"],\n                    audio_cover_strength=audio_cover_strength,\n                    cover_noise_strength=cover_noise_strength,\n                    use_adg=use_adg,\n                    cfg_interval_start=cfg_interval_start,\n                    cfg_interval_end=cfg_interval_end,\n                    shift=shift,\n                    infer_method=infer_method,\n                    audio_code_hints=service_inputs[\"audio_code_hints_batch\"],\n                    return_intermediate=service_inputs[\"should_return_intermediate\"],\n                    timesteps=timesteps,\n                    chunk_mask_modes=service_inputs.get(\"chunk_mask_modes_batch\"),\n                    repaint_crossfade_frames=repaint_crossfade_frames,\n                    repaint_injection_ratio=repaint_injection_ratio,\n                )\n            except Exception as exc:\n                _error[\"exc\"] = exc\n\n        try:\n            stop_event, progress_thread = self._start_diffusion_progress_estimator(\n                progress=progress,\n                start=0.52,\n                end=0.79,\n                infer_steps=infer_steps_for_progress,\n                batch_size=actual_batch_size,\n                duration_sec=audio_duration if audio_duration and audio_duration > 0 else None,\n                desc=progress_desc,\n            )\n\n            gen_thread = threading.Thread(\n                target=_service_target,\n                name=\"service-generate\",\n                daemon=True,\n            )\n            gen_thread.start()\n            gen_thread.join(timeout=_DEFAULT_GENERATION_TIMEOUT)\n\n            if gen_thread.is_alive():\n                logger.error(\n                    f\"[generate_music] service_generate exceeded {_DEFAULT_GENERATION_TIMEOUT}s \"\n                    f\"timeout (batch={actual_batch_size}, steps={inference_steps}, \"\n                    f\"duration={audio_duration}s).  The CUDA operation may still be \"\n                    f\"running in the background.\"\n                )\n                raise TimeoutError(\n                    f\"Music generation timed out after {_DEFAULT_GENERATION_TIMEOUT} seconds.  \"\n                    f\"This usually means the GPU ran out of VRAM or the diffusion loop \"\n                    f\"stalled.  Try reducing batch size, duration, or inference steps.\"\n                )\n            if \"exc\" in _error:\n                raise _error[\"exc\"]\n\n        finally:\n            if stop_event is not None:\n                stop_event.set()\n            if progress_thread is not None:\n                progress_thread.join(timeout=1.0)\n\n        return {\"outputs\": _result[\"outputs\"], \"infer_steps_for_progress\": infer_steps_for_progress}"
  },
  {
    "path": "acestep/core/generation/handler/generate_music_execute_test.py",
    "content": "\"\"\"Unit tests for ``generate_music`` execution helper mixin.\"\"\"\n\nimport unittest\n\nfrom acestep.core.generation.handler.generate_music_execute import GenerateMusicExecuteMixin\n\n\nclass _Host(GenerateMusicExecuteMixin):\n    \"\"\"Minimal host implementing progress/service stubs for execute helper tests.\"\"\"\n\n    def __init__(self):\n        \"\"\"Capture calls for assertions.\"\"\"\n        self.started = False\n        self.stopped = False\n        self.service_calls = 0\n\n    def _start_diffusion_progress_estimator(self, **kwargs):\n        \"\"\"Return fake stop event/thread handles used by helper lifecycle.\"\"\"\n        _ = kwargs\n        self.started = True\n\n        class _Stop:\n            \"\"\"Minimal stop-event stand-in used by the test host.\"\"\"\n\n            def __init__(self, host):\n                \"\"\"Bind host state so ``set`` can mark stop lifecycle completion.\"\"\"\n                self.host = host\n\n            def set(self):\n                \"\"\"Mark progress lifecycle as stopped.\"\"\"\n                self.host.stopped = True\n\n        class _Thread:\n            \"\"\"Minimal thread stand-in exposing a ``join`` method.\"\"\"\n\n            def join(self, timeout=None):\n                \"\"\"Accept join calls without background threading.\"\"\"\n                _ = timeout\n\n        return _Stop(self), _Thread()\n\n    def service_generate(self, **kwargs):\n        \"\"\"Record service invocation and return minimal output payload.\"\"\"\n        _ = kwargs\n        self.service_calls += 1\n        return {\"target_latents\": \"ok\"}\n\n\nclass GenerateMusicExecuteMixinTests(unittest.TestCase):\n    \"\"\"Verify progress lifecycle and service forwarding behavior.\"\"\"\n\n    def test_run_service_with_progress_invokes_service_and_stops_estimator(self):\n        \"\"\"Helper should call service once and always stop progress estimator.\"\"\"\n        host = _Host()\n        out = host._run_generate_music_service_with_progress(\n            progress=lambda *args, **kwargs: None,\n            actual_batch_size=1,\n            audio_duration=10.0,\n            inference_steps=8,\n            timesteps=None,\n            service_inputs={\n                \"captions_batch\": [\"c\"],\n                \"lyrics_batch\": [\"l\"],\n                \"metas_batch\": [\"m\"],\n                \"vocal_languages_batch\": [\"en\"],\n                \"target_wavs_tensor\": None,\n                \"repainting_start_batch\": [0.0],\n                \"repainting_end_batch\": [1.0],\n                \"instructions_batch\": [\"i\"],\n                \"audio_code_hints_batch\": None,\n                \"should_return_intermediate\": True,\n            },\n            refer_audios=None,\n            guidance_scale=7.0,\n            actual_seed_list=[1],\n            audio_cover_strength=1.0,\n            cover_noise_strength=0.0,\n            use_adg=False,\n            cfg_interval_start=0.0,\n            cfg_interval_end=1.0,\n            shift=1.0,\n            infer_method=\"ode\",\n        )\n        self.assertTrue(host.started)\n        self.assertTrue(host.stopped)\n        self.assertEqual(host.service_calls, 1)\n        self.assertEqual(out[\"outputs\"][\"target_latents\"], \"ok\")\n\n\nif __name__ == \"__main__\":\n    unittest.main()\n"
  },
  {
    "path": "acestep/core/generation/handler/generate_music_payload.py",
    "content": "\"\"\"Success payload builders for ``generate_music`` orchestration.\"\"\"\n\nfrom typing import Any, Dict\n\nfrom loguru import logger\n\n\nclass GenerateMusicPayloadMixin:\n    \"\"\"Build audio/metadata payload structures returned by ``generate_music``.\"\"\"\n\n    def _build_generate_music_success_payload(\n        self,\n        outputs: Dict[str, Any],\n        pred_wavs,\n        pred_latents_cpu,\n        time_costs: Dict[str, Any],\n        seed_value_for_ui: int,\n        actual_batch_size: int,\n        progress: Any,\n    ) -> Dict[str, Any]:\n        \"\"\"Assemble final success response from decoded tensors and model outputs.\n\n        Args:\n            outputs: Service output payload containing intermediate generation tensors.\n            pred_wavs: Decoded waveform tensor shaped ``[batch, channels, samples]``.\n            pred_latents_cpu: CPU latent tensor preserved for extra outputs.\n            time_costs: Updated time-cost payload including decode/offload timings.\n            seed_value_for_ui: Seed value displayed in UI outputs.\n            actual_batch_size: Effective generation batch size.\n            progress: Optional progress callback.\n\n        Returns:\n            Dict[str, Any]: Standard success payload returned by ``generate_music``.\n        \"\"\"\n        logger.info(\"[generate_music] VAE decode completed. Preparing audio tensors...\")\n        if progress:\n            progress(0.99, desc=\"Preparing audio data...\")\n\n        audio_tensors = []\n        for index in range(actual_batch_size):\n            audio_tensor = pred_wavs[index].cpu()\n            audio_tensors.append(audio_tensor)\n        # Free the GPU waveform tensor now that all per-sample CPU copies are done.\n        del pred_wavs\n\n        status_message = \"Generation completed successfully!\"\n        logger.info(f\"[generate_music] Done! Generated {len(audio_tensors)} audio tensors.\")\n\n        src_latents = outputs.get(\"src_latents\")\n        target_latents_input = outputs.get(\"target_latents_input\")\n        chunk_masks = outputs.get(\"chunk_masks\")\n        spans = outputs.get(\"spans\", [])\n        latent_masks = outputs.get(\"latent_masks\")\n\n        encoder_hidden_states = outputs.get(\"encoder_hidden_states\")\n        encoder_attention_mask = outputs.get(\"encoder_attention_mask\")\n        context_latents = outputs.get(\"context_latents\")\n        lyric_token_idss = outputs.get(\"lyric_token_idss\")\n\n        extra_outputs = {\n            \"pred_latents\": pred_latents_cpu,\n            \"target_latents\": target_latents_input.detach().cpu() if target_latents_input is not None else None,\n            \"src_latents\": src_latents.detach().cpu() if src_latents is not None else None,\n            \"chunk_masks\": chunk_masks.detach().cpu() if chunk_masks is not None else None,\n            \"latent_masks\": latent_masks.detach().cpu() if latent_masks is not None else None,\n            \"spans\": spans,\n            \"time_costs\": time_costs,\n            \"seed_value\": seed_value_for_ui,\n            \"encoder_hidden_states\": (\n                encoder_hidden_states.detach().cpu()\n                if encoder_hidden_states is not None\n                else None\n            ),\n            \"encoder_attention_mask\": (\n                encoder_attention_mask.detach().cpu()\n                if encoder_attention_mask is not None\n                else None\n            ),\n            \"context_latents\": context_latents.detach().cpu() if context_latents is not None else None,\n            \"lyric_token_idss\": lyric_token_idss.detach().cpu() if lyric_token_idss is not None else None,\n        }\n\n        audios = []\n        for audio_tensor in audio_tensors:\n            audios.append({\"tensor\": audio_tensor, \"sample_rate\": self.sample_rate})\n\n        return {\n            \"audios\": audios,\n            \"status_message\": status_message,\n            \"extra_outputs\": extra_outputs,\n            \"success\": True,\n            \"error\": None,\n        }\n"
  },
  {
    "path": "acestep/core/generation/handler/generate_music_payload_test.py",
    "content": "\"\"\"Tests for extracted ``generate_music`` success-payload builder behavior.\n\nThe module loads ``acestep.core.generation.handler.generate_music_payload``\ndirectly from file and validates final payload assembly with deterministic test\nfixtures.\n\"\"\"\n\nimport importlib.util\nimport sys\nimport types\nimport unittest\nfrom pathlib import Path\n\nimport torch\n\n\ndef _load_generate_music_payload_module():\n    \"\"\"Load ``generate_music_payload.py`` from disk for isolated tests.\n\n    Returns:\n        types.ModuleType: Loaded module object for\n        ``acestep.core.generation.handler.generate_music_payload``.\n\n    Raises:\n        FileNotFoundError: If the target file does not exist.\n        ImportError: If module execution fails.\n    \"\"\"\n    repo_root = Path(__file__).resolve().parents[4]\n    if str(repo_root) not in sys.path:\n        sys.path.insert(0, str(repo_root))\n    package_paths = {\n        \"acestep\": repo_root / \"acestep\",\n        \"acestep.core\": repo_root / \"acestep\" / \"core\",\n        \"acestep.core.generation\": repo_root / \"acestep\" / \"core\" / \"generation\",\n        \"acestep.core.generation.handler\": repo_root / \"acestep\" / \"core\" / \"generation\" / \"handler\",\n    }\n    for package_name, package_path in package_paths.items():\n        if package_name in sys.modules:\n            continue\n        package_module = types.ModuleType(package_name)\n        package_module.__path__ = [str(package_path)]\n        sys.modules[package_name] = package_module\n    module_path = Path(__file__).with_name(\"generate_music_payload.py\")\n    spec = importlib.util.spec_from_file_location(\n        \"acestep.core.generation.handler.generate_music_payload\",\n        module_path,\n    )\n    module = importlib.util.module_from_spec(spec)\n    assert spec.loader is not None\n    spec.loader.exec_module(module)\n    return module\n\n\nGENERATE_MUSIC_PAYLOAD_MODULE = _load_generate_music_payload_module()\nGenerateMusicPayloadMixin = GENERATE_MUSIC_PAYLOAD_MODULE.GenerateMusicPayloadMixin\n\n\nclass _Host(GenerateMusicPayloadMixin):\n    \"\"\"Minimal host providing state required by payload assembly tests.\"\"\"\n\n    def __init__(self):\n        \"\"\"Initialize deterministic sample rate state.\"\"\"\n        self.sample_rate = 48000\n\n\nclass GenerateMusicPayloadMixinTests(unittest.TestCase):\n    \"\"\"Verify payload builder output structure and tensor routing.\"\"\"\n\n    def test_build_success_payload_contains_audio_and_extra_outputs(self):\n        \"\"\"It assembles audios and extra_outputs with CPU tensors and metadata.\"\"\"\n        host = _Host()\n        outputs = {\n            \"target_latents_input\": torch.ones(1, 4, 3),\n            \"src_latents\": torch.ones(1, 4, 3),\n            \"chunk_masks\": torch.ones(1, 4),\n            \"latent_masks\": torch.ones(1, 4),\n            \"spans\": [(0, 4)],\n            \"encoder_hidden_states\": torch.ones(1, 2, 3),\n            \"encoder_attention_mask\": torch.ones(1, 2),\n            \"context_latents\": torch.ones(1, 4, 3),\n            \"lyric_token_idss\": torch.ones(1, 2, dtype=torch.long),\n        }\n        pred_wavs = torch.ones(1, 2, 8)\n        pred_latents_cpu = torch.ones(1, 4, 3)\n        time_costs = {\"total_time_cost\": 2.0}\n        progress_calls = []\n\n        def _progress(value, desc=None):\n            \"\"\"Capture progress updates for assertions.\"\"\"\n            progress_calls.append((value, desc))\n\n        payload = host._build_generate_music_success_payload(\n            outputs=outputs,\n            pred_wavs=pred_wavs,\n            pred_latents_cpu=pred_latents_cpu,\n            time_costs=time_costs,\n            seed_value_for_ui=7,\n            actual_batch_size=1,\n            progress=_progress,\n        )\n\n        self.assertTrue(payload[\"success\"])\n        self.assertEqual(payload[\"error\"], None)\n        self.assertEqual(len(payload[\"audios\"]), 1)\n        self.assertEqual(payload[\"audios\"][0][\"sample_rate\"], 48000)\n        self.assertEqual(payload[\"extra_outputs\"][\"seed_value\"], 7)\n        self.assertEqual(payload[\"extra_outputs\"][\"pred_latents\"].device.type, \"cpu\")\n        self.assertEqual(progress_calls[0][0], 0.99)\n\n    def test_build_success_payload_handles_missing_optional_outputs_without_progress(self):\n        \"\"\"It handles absent optional output keys and no progress callback.\"\"\"\n        host = _Host()\n        outputs = {}\n        pred_wavs = torch.ones(1, 2, 8)\n        pred_latents_cpu = torch.ones(1, 4, 3)\n        time_costs = {\"total_time_cost\": 2.0}\n\n        payload = host._build_generate_music_success_payload(\n            outputs=outputs,\n            pred_wavs=pred_wavs,\n            pred_latents_cpu=pred_latents_cpu,\n            time_costs=time_costs,\n            seed_value_for_ui=11,\n            actual_batch_size=1,\n            progress=None,\n        )\n\n        self.assertTrue(payload[\"success\"])\n        self.assertIsNone(payload[\"error\"])\n        self.assertEqual(payload[\"status_message\"], \"Generation completed successfully!\")\n        self.assertEqual(payload[\"extra_outputs\"][\"spans\"], [])\n        self.assertIsNone(payload[\"extra_outputs\"][\"encoder_hidden_states\"])\n        self.assertIsNone(payload[\"extra_outputs\"][\"encoder_attention_mask\"])\n        self.assertIsNone(payload[\"extra_outputs\"][\"context_latents\"])\n        self.assertEqual(payload[\"extra_outputs\"][\"pred_latents\"].device.type, \"cpu\")\n\n\n    def test_build_success_payload_does_not_mutate_outputs_dict(self):\n        \"\"\"Payload builder must not remove keys from the caller's outputs dict.\"\"\"\n        host = _Host()\n        outputs = {\n            \"target_latents_input\": torch.ones(1, 4, 3),\n            \"src_latents\": torch.ones(1, 4, 3),\n            \"chunk_masks\": torch.ones(1, 4),\n            \"latent_masks\": torch.ones(1, 4),\n            \"spans\": [(0, 4)],\n            \"encoder_hidden_states\": torch.ones(1, 2, 3),\n            \"encoder_attention_mask\": torch.ones(1, 2),\n            \"context_latents\": torch.ones(1, 4, 3),\n            \"lyric_token_idss\": torch.ones(1, 2, dtype=torch.long),\n        }\n        original_keys = set(outputs.keys())\n\n        host._build_generate_music_success_payload(\n            outputs=outputs,\n            pred_wavs=torch.ones(1, 2, 8),\n            pred_latents_cpu=torch.ones(1, 4, 3),\n            time_costs={\"total_time_cost\": 1.0},\n            seed_value_for_ui=0,\n            actual_batch_size=1,\n            progress=None,\n        )\n\n        self.assertEqual(set(outputs.keys()), original_keys)\n\n    def test_build_success_payload_all_extra_outputs_are_cpu_tensors(self):\n        \"\"\"It ensures every tensor in extra_outputs is on CPU.\"\"\"\n        host = _Host()\n        outputs = {\n            \"target_latents_input\": torch.ones(1, 4, 3),\n            \"src_latents\": torch.ones(1, 4, 3),\n            \"encoder_hidden_states\": torch.ones(1, 2, 3),\n            \"encoder_attention_mask\": torch.ones(1, 2),\n            \"context_latents\": torch.ones(1, 4, 3),\n            \"lyric_token_idss\": torch.ones(1, 2, dtype=torch.long),\n        }\n        pred_wavs = torch.ones(1, 2, 8)\n        pred_latents_cpu = torch.ones(1, 4, 3)\n\n        payload = host._build_generate_music_success_payload(\n            outputs=outputs,\n            pred_wavs=pred_wavs,\n            pred_latents_cpu=pred_latents_cpu,\n            time_costs={\"total_time_cost\": 1.0},\n            seed_value_for_ui=0,\n            actual_batch_size=1,\n            progress=None,\n        )\n\n        for key, val in payload[\"extra_outputs\"].items():\n            if isinstance(val, torch.Tensor):\n                self.assertEqual(\n                    val.device.type, \"cpu\",\n                    f\"extra_outputs['{key}'] is not on CPU (device={val.device})\",\n                )\n\n\nif __name__ == \"__main__\":\n    unittest.main()\n\n"
  },
  {
    "path": "acestep/core/generation/handler/generate_music_request.py",
    "content": "\"\"\"Input and preflight helpers for ``generate_music`` orchestration.\"\"\"\n\nfrom typing import Any, Callable, Dict, List, Optional, Tuple, Union\n\nimport torch\nfrom loguru import logger\n\nfrom acestep.constants import TASK_INSTRUCTIONS\n\n\nclass GenerateMusicRequestMixin:\n    \"\"\"Prepare normalized ``generate_music`` inputs before service execution.\"\"\"\n\n    def _resolve_generate_music_progress(\n        self,\n        progress: Optional[Callable[..., Any]],\n    ) -> Callable[..., Any]:\n        \"\"\"Return a callable progress callback, defaulting to no-op.\"\"\"\n        if progress is not None:\n            return progress\n\n        def _progress(*args: Any, **kwargs: Any) -> Any:\n            \"\"\"No-op callback for non-UI call sites.\"\"\"\n            _ = args, kwargs\n            return None\n\n        return _progress\n\n    def _validate_generate_music_readiness(self) -> Optional[Dict[str, Any]]:\n        \"\"\"Return standardized error payload when model components are unavailable.\"\"\"\n        if self.model is None or self.vae is None or self.text_tokenizer is None or self.text_encoder is None:\n            return {\n                \"audios\": [],\n                \"status_message\": \"\\u274c Model not fully initialized. Please initialize all components first.\",\n                \"extra_outputs\": {},\n                \"success\": False,\n                \"error\": \"Model not fully initialized\",\n            }\n        return None\n\n    def _has_non_empty_audio_codes(self, value: Union[str, List[str]]) -> bool:\n        \"\"\"Return ``True`` when at least one non-empty audio-code string is present.\"\"\"\n        if isinstance(value, list):\n            return any((x or \"\").strip() for x in value)\n        return bool(value and str(value).strip())\n\n    def _resolve_generate_music_task(\n        self,\n        task_type: str,\n        audio_code_string: Union[str, List[str]],\n        instruction: str,\n    ) -> Tuple[str, str]:\n        \"\"\"Auto-switch text2music to cover task when audio codes are provided.\"\"\"\n        if task_type == \"text2music\" and self._has_non_empty_audio_codes(audio_code_string):\n            return \"cover\", TASK_INSTRUCTIONS[\"cover\"]\n        return task_type, instruction\n\n    def _prepare_generate_music_runtime(\n        self,\n        batch_size: Optional[int],\n        audio_duration: Optional[float],\n        repainting_end: Optional[float],\n        seed: Optional[Union[str, float, int]],\n        use_random_seed: bool,\n    ) -> Dict[str, Any]:\n        \"\"\"Prepare runtime batch/seed/duration values for generation.\"\"\"\n        self.current_offload_cost = 0.0\n        actual_batch_size = batch_size if batch_size is not None else self.batch_size\n        actual_batch_size = max(1, actual_batch_size)\n        actual_batch_size = self._vram_guard_reduce_batch(actual_batch_size, audio_duration=audio_duration)\n        actual_seed_list, seed_value_for_ui = self.prepare_seeds(actual_batch_size, seed, use_random_seed)\n\n        if audio_duration is not None and float(audio_duration) <= 0:\n            audio_duration = None\n        if repainting_end is not None and float(repainting_end) < 0:\n            repainting_end = None\n\n        return {\n            \"actual_batch_size\": actual_batch_size,\n            \"actual_seed_list\": actual_seed_list,\n            \"seed_value_for_ui\": seed_value_for_ui,\n            \"audio_duration\": audio_duration,\n            \"repainting_end\": repainting_end,\n        }\n\n    def _prepare_reference_and_source_audio(\n        self,\n        reference_audio: Optional[str],\n        src_audio: Optional[str],\n        audio_code_string: Union[str, List[str]],\n        actual_batch_size: int,\n        task_type: str,\n    ) -> Tuple[Optional[List[List[torch.Tensor]]], Optional[torch.Tensor], Optional[Dict[str, Any]]]:\n        \"\"\"Prepare reference/source audio tensors and return early error payload when invalid.\"\"\"\n        if reference_audio is not None:\n            logger.info(\"[generate_music] Processing reference audio...\")\n            processed_ref_audio = self.process_reference_audio(reference_audio)\n            if processed_ref_audio is None:\n                return None, None, {\n                    \"audios\": [],\n                    \"status_message\": (\n                        \"Reference audio is invalid, unreadable, or silent. \"\n                        \"Please upload a valid audible audio file.\"\n                    ),\n                    \"extra_outputs\": {},\n                    \"success\": False,\n                    \"error\": \"Invalid reference audio\",\n                }\n            refer_audios = [[processed_ref_audio] for _ in range(actual_batch_size)]\n        else:\n            refer_audios = [[torch.zeros(2, 30 * self.sample_rate)] for _ in range(actual_batch_size)]\n\n        processed_src_audio = None\n        if task_type == \"text2music\":\n            if src_audio is not None:\n                logger.info(\"[generate_music] text2music task does not use src_audio, ignoring\")\n        elif src_audio is not None:\n            if self._has_non_empty_audio_codes(audio_code_string):\n                logger.info(\"[generate_music] Audio codes provided, ignoring src_audio and using codes instead\")\n            else:\n                logger.info(\"[generate_music] Processing source audio...\")\n                processed_src_audio = self.process_src_audio(src_audio)\n                if processed_src_audio is None:\n                    logger.error(\"[generate_music] Source audio is invalid after processing\")\n                    return None, None, {\n                        \"audios\": [],\n                        \"status_message\": (\n                            \"Source audio is invalid, unreadable, or silent. \"\n                            \"Please upload a valid audible audio file.\"\n                        ),\n                        \"extra_outputs\": {},\n                        \"success\": False,\n                        \"error\": \"Invalid source audio\",\n                    }\n\n        return refer_audios, processed_src_audio, None\n\n    def _prepare_generate_music_service_inputs(\n        self,\n        actual_batch_size: int,\n        processed_src_audio: Optional[torch.Tensor],\n        audio_duration: Optional[float],\n        captions: str,\n        global_caption: str = \"\",\n        lyrics: str = \"\",\n        vocal_language: str = \"en\",\n        instruction: str = \"\",\n        bpm: Optional[int] = None,\n        key_scale: str = \"\",\n        time_signature: str = \"\",\n        task_type: str = \"text2music\",\n        audio_code_string: Union[str, List[str]] = \"\",\n        repainting_start: float = 0.0,\n        repainting_end: Optional[float] = None,\n        chunk_mask_mode: str = \"auto\",\n    ) -> Dict[str, Any]:\n        \"\"\"Prepare service inputs (batch text, repaint spans, and optional code hints).\"\"\"\n        captions_batch, instructions_batch, lyrics_batch, vocal_languages_batch, metas_batch = self.prepare_batch_data(\n            actual_batch_size,\n            processed_src_audio,\n            audio_duration,\n            captions,\n            lyrics,\n            vocal_language,\n            instruction,\n            bpm,\n            key_scale,\n            time_signature,\n        )\n        global_captions_batch = [global_caption] * actual_batch_size\n\n        is_repaint_task, is_lego_task, is_cover_task, can_use_repainting = self.determine_task_type(task_type, audio_code_string)\n        repainting_start_batch, repainting_end_batch, target_wavs_tensor = self.prepare_padding_info(\n            actual_batch_size,\n            processed_src_audio,\n            audio_duration,\n            repainting_start,\n            repainting_end,\n            is_repaint_task,\n            is_lego_task,\n            is_cover_task,\n            can_use_repainting,\n        )\n        audio_code_hints_batch = None\n        if self._has_non_empty_audio_codes(audio_code_string):\n            if isinstance(audio_code_string, list):\n                audio_code_hints_batch = audio_code_string\n            else:\n                audio_code_hints_batch = [audio_code_string] * actual_batch_size\n\n        return {\n            \"captions_batch\": captions_batch,\n            \"global_captions_batch\": global_captions_batch,\n            \"instructions_batch\": instructions_batch,\n            \"lyrics_batch\": lyrics_batch,\n            \"vocal_languages_batch\": vocal_languages_batch,\n            \"metas_batch\": metas_batch,\n            \"repainting_start_batch\": repainting_start_batch,\n            \"repainting_end_batch\": repainting_end_batch,\n            \"target_wavs_tensor\": target_wavs_tensor,\n            \"audio_code_hints_batch\": audio_code_hints_batch,\n            \"chunk_mask_modes_batch\": [chunk_mask_mode] * actual_batch_size,\n            \"should_return_intermediate\": True,\n        }\n\n"
  },
  {
    "path": "acestep/core/generation/handler/generate_music_request_test.py",
    "content": "\"\"\"Unit tests for ``generate_music`` request helper mixin.\"\"\"\n\nimport types\nimport unittest\n\nimport torch\n\nfrom acestep.core.generation.handler.generate_music_request import GenerateMusicRequestMixin\n\n\nclass _Host(GenerateMusicRequestMixin):\n    \"\"\"Minimal host implementing dependencies for request helper tests.\"\"\"\n\n    def __init__(self):\n        \"\"\"Initialize state and default stubs used by helper methods.\"\"\"\n        self.current_offload_cost = 0.0\n        self.batch_size = 2\n        self.sample_rate = 48000\n        self.model = object()\n        self.vae = object()\n        self.text_tokenizer = object()\n        self.text_encoder = object()\n        self._vram_guard_reduce_batch = lambda bs, audio_duration=None: bs\n        self.prepare_seeds = lambda bs, seed, use_random_seed: ([1] * bs, 1)\n        self.process_reference_audio = lambda _ref: torch.zeros(2, 100)\n        self.process_src_audio = lambda _src: torch.ones(2, 100)\n        self.prepare_batch_data = lambda *args, **kwargs: (\n            [\"cap\"], [\"inst\"], [\"lyr\"], [\"en\"], [\"meta\"]\n        )\n        self.determine_task_type = lambda task, codes: (False, False, task == \"cover\", True)\n        self.prepare_padding_info = lambda *args, **kwargs: ([0.0], [1.0], torch.zeros(1, 2, 100))\n\n\nclass GenerateMusicRequestMixinTests(unittest.TestCase):\n    \"\"\"Validate request helper behavior used by ``generate_music`` orchestration.\"\"\"\n\n    def test_resolve_task_switches_to_cover_when_audio_codes_present(self):\n        \"\"\"Text2music should switch to cover mode when audio code hints are supplied.\"\"\"\n        host = _Host()\n        task, instruction = host._resolve_generate_music_task(\n            task_type=\"text2music\",\n            audio_code_string=\"<|audio_code_1|>\",\n            instruction=\"old\",\n        )\n        self.assertEqual(task, \"cover\")\n        self.assertNotEqual(instruction, \"old\")\n\n    def test_prepare_runtime_normalizes_batch_and_duration(self):\n        \"\"\"Runtime helper should clamp batch floor and normalize invalid duration/end values.\"\"\"\n        host = _Host()\n        out = host._prepare_generate_music_runtime(\n            batch_size=0,\n            audio_duration=0.0,\n            repainting_end=-1.0,\n            seed=7,\n            use_random_seed=False,\n        )\n        self.assertEqual(out[\"actual_batch_size\"], 1)\n        self.assertIsNone(out[\"audio_duration\"])\n        self.assertIsNone(out[\"repainting_end\"])\n\n    def test_prepare_reference_and_source_audio_returns_error_for_invalid_reference(self):\n        \"\"\"Invalid reference audio should return a structured early error payload.\"\"\"\n        host = _Host()\n        host.process_reference_audio = lambda _ref: None\n        _, _, error = host._prepare_reference_and_source_audio(\n            reference_audio=\"bad.wav\",\n            src_audio=None,\n            audio_code_string=\"\",\n            actual_batch_size=1,\n            task_type=\"cover\",\n        )\n        self.assertIsNotNone(error)\n        self.assertFalse(error[\"success\"])\n        self.assertEqual(error[\"error\"], \"Invalid reference audio\")\n\n    def test_prepare_reference_and_source_audio_ignores_src_audio_for_text2music(self):\n        \"\"\"Text2music should ignore src audio to preserve upstream behavior.\"\"\"\n        host = _Host()\n        called = {\"process_src_audio\": False}\n\n        def _process_src_audio(_src):\n            called[\"process_src_audio\"] = True\n            return torch.ones(2, 100)\n\n        host.process_src_audio = _process_src_audio\n        _, processed_src_audio, error = host._prepare_reference_and_source_audio(\n            reference_audio=None,\n            src_audio=\"song.wav\",\n            audio_code_string=\"\",\n            actual_batch_size=1,\n            task_type=\"text2music\",\n        )\n        self.assertIsNone(error)\n        self.assertIsNone(processed_src_audio)\n        self.assertFalse(called[\"process_src_audio\"])\n\n    def test_prepare_reference_and_source_audio_returns_error_for_invalid_source(self):\n        \"\"\"Non-text2music source audio failure should return structured error payload.\"\"\"\n        host = _Host()\n        host.process_src_audio = lambda _src: None\n        _, processed_src_audio, error = host._prepare_reference_and_source_audio(\n            reference_audio=None,\n            src_audio=\"bad.wav\",\n            audio_code_string=\"\",\n            actual_batch_size=1,\n            task_type=\"cover\",\n        )\n        self.assertIsNone(processed_src_audio)\n        self.assertIsNotNone(error)\n        self.assertFalse(error[\"success\"])\n        self.assertEqual(error[\"error\"], \"Invalid source audio\")\n\n\n    def test_should_return_intermediate_always_true(self):\n        \"\"\"Intermediate tensors must always be returned for LRC generation support.\"\"\"\n        host = _Host()\n        for task in (\"text2music\", \"cover\", \"repaint\"):\n            inputs = host._prepare_generate_music_service_inputs(\n                actual_batch_size=1,\n                processed_src_audio=None,\n                audio_duration=60.0,\n                captions=\"test\",\n                lyrics=\"test\",\n                vocal_language=\"en\",\n                instruction=\"inst\",\n                bpm=120,\n                key_scale=\"C major\",\n                time_signature=\"4/4\",\n                task_type=task,\n                audio_code_string=\"\",\n                repainting_start=0.0,\n                repainting_end=1.0,\n            )\n            self.assertTrue(\n                inputs[\"should_return_intermediate\"],\n                f\"should_return_intermediate must be True for task_type={task!r}\",\n            )\n\n\nif __name__ == \"__main__\":\n    unittest.main()\n"
  },
  {
    "path": "acestep/core/generation/handler/generate_music_test.py",
    "content": "\"\"\"Tests for extracted ``generate_music`` orchestration behavior.\n\nThe module loads ``acestep.core.generation.handler.generate_music`` directly\nfrom file to avoid package import side effects and validates orchestration\nordering, readiness short-circuiting, and failure payload handling.\n\"\"\"\n\nimport importlib.util\nimport sys\nimport types\nimport unittest\nfrom pathlib import Path\nfrom typing import Any, Dict\nfrom unittest.mock import patch\n\nimport torch\n\n\ndef _load_generate_music_module():\n    \"\"\"Load ``generate_music.py`` from disk for isolated mixin tests.\n\n    Returns:\n        types.ModuleType: Loaded module object for\n        ``acestep.core.generation.handler.generate_music``.\n\n    Raises:\n        FileNotFoundError: If the target module file is missing.\n        ImportError: If module loading fails.\n    \"\"\"\n    repo_root = Path(__file__).resolve().parents[4]\n    if str(repo_root) not in sys.path:\n        sys.path.insert(0, str(repo_root))\n    package_paths = {\n        \"acestep\": repo_root / \"acestep\",\n        \"acestep.core\": repo_root / \"acestep\" / \"core\",\n        \"acestep.core.generation\": repo_root / \"acestep\" / \"core\" / \"generation\",\n        \"acestep.core.generation.handler\": repo_root / \"acestep\" / \"core\" / \"generation\" / \"handler\",\n    }\n    for package_name, package_path in package_paths.items():\n        if package_name in sys.modules:\n            continue\n        package_module = types.ModuleType(package_name)\n        package_module.__path__ = [str(package_path)]\n        sys.modules[package_name] = package_module\n    module_path = Path(__file__).with_name(\"generate_music.py\")\n    spec = importlib.util.spec_from_file_location(\n        \"acestep.core.generation.handler.generate_music\",\n        module_path,\n    )\n    module = importlib.util.module_from_spec(spec)\n    assert spec.loader is not None\n    spec.loader.exec_module(module)\n    return module\n\n\nGENERATE_MUSIC_MODULE = _load_generate_music_module()\nGenerateMusicMixin = GENERATE_MUSIC_MODULE.GenerateMusicMixin\n\n\nclass _Host(GenerateMusicMixin):\n    \"\"\"Minimal host implementing ``generate_music`` helper dependencies.\n\n    The host captures helper calls in ``self.calls`` and returns deterministic\n    payloads so tests can assert orchestration sequencing and return behavior.\n    \"\"\"\n\n    def __init__(self, offload_to_cpu: bool = False):\n        \"\"\"Initialize deterministic state and stub payloads for orchestration tests.\"\"\"\n        self.model = object()\n        self.vae = object()\n        self.text_tokenizer = object()\n        self.text_encoder = object()\n        self.offload_to_cpu = offload_to_cpu\n        self.sample_rate = 48000\n        self.calls: Dict[str, Any] = {}\n        self._final_payload = {\"audios\": [{\"tensor\": torch.zeros(1, 4), \"sample_rate\": 48000}], \"success\": True}\n        self._readiness_error = {\n            \"audios\": [],\n            \"status_message\": \"not ready\",\n            \"extra_outputs\": {},\n            \"success\": False,\n            \"error\": \"Model not fully initialized\",\n        }\n\n    def _resolve_generate_music_progress(self, progress):\n        \"\"\"Return provided callback or deterministic no-op callback.\"\"\"\n        self.calls[\"_resolve_generate_music_progress\"] = bool(progress)\n        if progress is not None:\n            return progress\n\n        def _noop(*_args, **_kwargs):\n            \"\"\"Ignore progress updates in tests.\"\"\"\n            return None\n\n        return _noop\n\n    def _validate_generate_music_readiness(self):\n        \"\"\"Return deterministic readiness error payload.\"\"\"\n        self.calls[\"_validate_generate_music_readiness\"] = True\n        return self._readiness_error\n\n    def _resolve_generate_music_task(self, **kwargs):\n        \"\"\"Capture task resolution args and return deterministic task/instruction.\"\"\"\n        self.calls[\"_resolve_generate_music_task\"] = kwargs\n        return kwargs[\"task_type\"], kwargs[\"instruction\"]\n\n    def _prepare_generate_music_runtime(self, **kwargs):\n        \"\"\"Capture runtime args and return deterministic runtime state.\"\"\"\n        self.calls[\"_prepare_generate_music_runtime\"] = kwargs\n        return {\n            \"actual_batch_size\": 1,\n            \"actual_seed_list\": [77],\n            \"seed_value_for_ui\": 77,\n            \"audio_duration\": kwargs[\"audio_duration\"],\n            \"repainting_end\": kwargs[\"repainting_end\"],\n        }\n\n    def _prepare_reference_and_source_audio(self, **kwargs):\n        \"\"\"Capture audio-prepare args and return deterministic prepared state.\"\"\"\n        self.calls[\"_prepare_reference_and_source_audio\"] = kwargs\n        return [[torch.zeros(2, 10)]], None, None\n\n    def _prepare_generate_music_service_inputs(self, **kwargs):\n        \"\"\"Capture service-input args and return deterministic payload.\"\"\"\n        self.calls[\"_prepare_generate_music_service_inputs\"] = kwargs\n        return {\"should_return_intermediate\": True}\n\n    def _run_generate_music_service_with_progress(self, **kwargs):\n        \"\"\"Capture service execution args and return deterministic model outputs.\"\"\"\n        self.calls[\"_run_generate_music_service_with_progress\"] = kwargs\n        return {\n            \"outputs\": {\n                \"target_latents\": torch.ones(1, 4, 3),\n                \"time_costs\": {\"total_time_cost\": 1.0, \"diffusion_per_step_time_cost\": 0.1},\n            },\n            \"infer_steps_for_progress\": 8,\n        }\n\n    def _prepare_generate_music_decode_state(self, **kwargs):\n        \"\"\"Capture decode-state args and return deterministic latents/costs.\"\"\"\n        self.calls[\"_prepare_generate_music_decode_state\"] = kwargs\n        return torch.ones(1, 4, 3), {\"total_time_cost\": 1.0}\n\n    def _decode_generate_music_pred_latents(self, **kwargs):\n        \"\"\"Capture decode args and return deterministic decode outputs.\"\"\"\n        self.calls[\"_decode_generate_music_pred_latents\"] = kwargs\n        return torch.ones(1, 2, 8), torch.ones(1, 4, 3), {\"total_time_cost\": 2.0}\n\n    def _build_generate_music_success_payload(self, **kwargs):\n        \"\"\"Capture payload-builder args and return deterministic success payload.\"\"\"\n        self.calls[\"_build_generate_music_success_payload\"] = kwargs\n        return self._final_payload\n\n    def _empty_cache(self):\n        \"\"\"No-op cache clear for test host.\"\"\"\n\n\nclass GenerateMusicMixinTests(unittest.TestCase):\n    \"\"\"Verify top-level ``generate_music`` orchestration behavior.\"\"\"\n\n    def test_generate_music_returns_success_payload_from_builder(self):\n        \"\"\"It executes helper stages and returns the payload builder result.\"\"\"\n        host = _Host()\n        out = host.generate_music(\n            captions=\"cap\",\n            lyrics=\"lyr\",\n            inference_steps=8,\n            guidance_scale=6.5,\n            use_random_seed=False,\n            seed=77,\n            task_type=\"text2music\",\n        )\n        self.assertEqual(out, host._final_payload)\n        self.assertEqual(host.calls[\"_prepare_generate_music_runtime\"][\"seed\"], 77)\n        self.assertEqual(host.calls[\"_run_generate_music_service_with_progress\"][\"guidance_scale\"], 6.5)\n        self.assertEqual(host.calls[\"_prepare_generate_music_decode_state\"][\"infer_steps_for_progress\"], 8)\n\n    def test_generate_music_returns_readiness_error_when_components_missing(self):\n        \"\"\"It short-circuits with readiness payload when required models are missing.\"\"\"\n        host = _Host()\n        host.model = None\n        out = host.generate_music(captions=\"cap\", lyrics=\"lyr\")\n        self.assertEqual(out, host._readiness_error)\n        self.assertTrue(host.calls[\"_validate_generate_music_readiness\"])\n        self.assertNotIn(\"_prepare_generate_music_runtime\", host.calls)\n\n    def test_generate_music_returns_error_payload_on_exception(self):\n        \"\"\"It catches orchestration errors and returns standardized failure payload.\"\"\"\n        host = _Host()\n\n        def _raise_error(**_kwargs):\n            \"\"\"Raise deterministic runtime failure for exception-path validation.\"\"\"\n            raise RuntimeError(\"boom\")\n\n        host._prepare_reference_and_source_audio = _raise_error\n        out = host.generate_music(captions=\"cap\", lyrics=\"lyr\")\n        self.assertFalse(out[\"success\"])\n        self.assertEqual(out[\"error\"], \"boom\")\n        self.assertIn(\"Error: boom\", out[\"status_message\"])\n\n\nclass VramPreflightCheckTests(unittest.TestCase):\n    \"\"\"Verify ``_vram_preflight_check`` respects CPU offload mode.\"\"\"\n\n    _GM_MOD = GENERATE_MUSIC_MODULE\n\n    @patch.object(_GM_MOD, \"torch\")\n    def test_preflight_skips_when_offload_to_cpu_enabled(self, mock_torch):\n        \"\"\"It returns None (pass) when offload_to_cpu is True, regardless of free VRAM.\"\"\"\n        mock_torch.cuda.is_available.return_value = True\n        host = _Host(offload_to_cpu=True)\n        result = host._vram_preflight_check(\n            actual_batch_size=2,\n            audio_duration=246.0,\n            guidance_scale=7.0,\n        )\n        self.assertIsNone(result)\n\n    @patch.object(_GM_MOD, \"get_effective_free_vram_gb\", return_value=3.4)\n    @patch.object(_GM_MOD, \"torch\")\n    def test_preflight_blocks_when_offload_disabled_and_vram_low(\n        self, mock_torch, _mock_free_vram\n    ):\n        \"\"\"It returns error payload when offload is off and free VRAM is insufficient.\"\"\"\n        mock_torch.cuda.is_available.return_value = True\n        host = _Host(offload_to_cpu=False)\n        result = host._vram_preflight_check(\n            actual_batch_size=2,\n            audio_duration=246.0,\n            guidance_scale=7.0,\n        )\n        self.assertIsNotNone(result)\n        self.assertFalse(result[\"success\"])\n        self.assertIn(\"Insufficient free VRAM\", result[\"error\"])\n\n    @patch.object(_GM_MOD, \"get_effective_free_vram_gb\", return_value=24.0)\n    @patch.object(_GM_MOD, \"torch\")\n    def test_preflight_passes_when_offload_disabled_and_vram_sufficient(\n        self, mock_torch, _mock_free_vram\n    ):\n        \"\"\"It returns None when offload is off but free VRAM exceeds estimate.\"\"\"\n        mock_torch.cuda.is_available.return_value = True\n        host = _Host(offload_to_cpu=False)\n        result = host._vram_preflight_check(\n            actual_batch_size=2,\n            audio_duration=246.0,\n            guidance_scale=7.0,\n        )\n        self.assertIsNone(result)\n\n    @patch.object(_GM_MOD, \"torch\")\n    def test_preflight_passes_on_non_cuda_device(self, mock_torch):\n        \"\"\"It returns None when CUDA is not available (CPU/MPS/XPU).\"\"\"\n        mock_torch.cuda.is_available.return_value = False\n        host = _Host(offload_to_cpu=False)\n        result = host._vram_preflight_check(\n            actual_batch_size=2,\n            audio_duration=246.0,\n            guidance_scale=7.0,\n        )\n        self.assertIsNone(result)\n\n\nif __name__ == \"__main__\":\n    unittest.main()\n"
  },
  {
    "path": "acestep/core/generation/handler/init_service.py",
    "content": "\"\"\"Facade mixin that composes initialization helper modules.\"\"\"\n\nfrom .init_service_catalog import InitServiceCatalogMixin\nfrom .init_service_downloads import InitServiceDownloadsMixin\nfrom .init_service_loader import InitServiceLoaderMixin\nfrom .init_service_memory_basic import InitServiceMemoryBasicMixin\nfrom .init_service_memory_transfer import InitServiceMemoryTransferMixin\nfrom .init_service_offload_context import InitServiceOffloadContextMixin\nfrom .init_service_orchestrator import InitServiceOrchestratorMixin\nfrom .init_service_setup import InitServiceSetupMixin\n\n\nclass InitServiceMixin(\n    InitServiceCatalogMixin,\n    InitServiceSetupMixin,\n    InitServiceDownloadsMixin,\n    InitServiceLoaderMixin,\n    InitServiceOrchestratorMixin,\n    InitServiceMemoryBasicMixin,\n    InitServiceMemoryTransferMixin,\n    InitServiceOffloadContextMixin,\n):\n    \"\"\"Composed initialization mixin for AceStepHandler.\"\"\"\n"
  },
  {
    "path": "acestep/core/generation/handler/init_service_catalog.py",
    "content": "\"\"\"Catalog and capability helpers for initialization flow.\"\"\"\n\nimport os\nfrom typing import List, Optional\n\nimport torch\nfrom loguru import logger\n\n\nclass InitServiceCatalogMixin:\n    \"\"\"Checkpoint discovery and backend capability helpers.\"\"\"\n\n    def _device_type(self) -> str:\n        \"\"\"Normalize the host device value to a backend type string.\"\"\"\n        if isinstance(self.device, str):\n            return self.device.split(\":\", 1)[0]\n        return self.device.type\n\n    def get_available_checkpoints(self) -> List[str]:\n        \"\"\"Return available checkpoint directory paths under the project root.\"\"\"\n        project_root = self._get_project_root()\n        checkpoint_dir = os.path.join(project_root, \"checkpoints\")\n        if os.path.exists(checkpoint_dir):\n            return [checkpoint_dir]\n        return []\n\n    def get_available_acestep_v15_models(self) -> List[str]:\n        \"\"\"Scan and return all model directory names starting with ``acestep-v15-``.\"\"\"\n        project_root = self._get_project_root()\n        checkpoint_dir = os.path.join(project_root, \"checkpoints\")\n\n        models = []\n        if os.path.exists(checkpoint_dir):\n            for item in os.listdir(checkpoint_dir):\n                item_path = os.path.join(checkpoint_dir, item)\n                if os.path.isdir(item_path) and item.startswith(\"acestep-v15-\"):\n                    models.append(item)\n\n        models.sort()\n        return models\n\n    def is_flash_attention_available(self, device: Optional[str] = None) -> bool:\n        \"\"\"Check whether flash attention can be used on the target device.\"\"\"\n        target_device = str(device or self.device or \"auto\").split(\":\", 1)[0]\n        if target_device == \"auto\":\n            if not torch.cuda.is_available():\n                return False\n        else:\n            if target_device != \"cuda\" or not torch.cuda.is_available():\n                return False\n\n        try:\n            major, _ = torch.cuda.get_device_capability()\n            if major < 8:\n                logger.info(\n                    f\"[is_flash_attention_available] GPU compute capability {major}.x < 8.0 \"\n                    f\"(pre-Ampere) — FlashAttention not supported, will use SDPA instead.\"\n                )\n                return False\n        except Exception:\n            return False\n\n        try:\n            import flash_attn\n            return True\n        except ImportError:\n            return False\n\n    def is_turbo_model(self) -> bool:\n        \"\"\"Check whether the currently loaded model is a turbo variant.\"\"\"\n        if self.config is None:\n            return False\n        return getattr(self.config, \"is_turbo\", False)\n"
  },
  {
    "path": "acestep/core/generation/handler/init_service_downloads.py",
    "content": "\"\"\"Download and precheck helpers for service initialization.\"\"\"\n\nfrom pathlib import Path\nfrom typing import Optional, Tuple\n\nfrom loguru import logger\n\nfrom acestep.model_downloader import (\n    check_main_model_exists,\n    check_model_exists,\n    ensure_dit_model,\n    ensure_main_model,\n)\n\n\nclass InitServiceDownloadsMixin:\n    \"\"\"Helpers that validate and fetch required model checkpoints.\"\"\"\n\n    def _ensure_models_present(\n        self,\n        *,\n        checkpoint_path: Path,\n        config_path: str,\n        prefer_source: Optional[str],\n    ) -> Optional[Tuple[str, bool]]:\n        \"\"\"Ensure required checkpoint assets exist locally, downloading when missing.\"\"\"\n        if not check_main_model_exists(checkpoint_path):\n            logger.info(\"[initialize_service] Main model not found, starting auto-download...\")\n            success, msg = ensure_main_model(checkpoint_path, prefer_source=prefer_source)\n            if not success:\n                return f\"ERROR: Failed to download main model: {msg}\", False\n            logger.info(f\"[initialize_service] {msg}\")\n\n        if config_path == \"\":\n            logger.warning(\n                \"[initialize_service] Empty config_path; pass None to use the default model.\"\n            )\n\n        if not check_model_exists(config_path, checkpoint_path):\n            logger.info(f\"[initialize_service] DiT model '{config_path}' not found, starting auto-download...\")\n            success, msg = ensure_dit_model(config_path, checkpoint_path, prefer_source=prefer_source)\n            if not success:\n                return f\"ERROR: Failed to download DiT model '{config_path}': {msg}\", False\n            logger.info(f\"[initialize_service] {msg}\")\n\n        return None\n\n    @staticmethod\n    def _sync_model_code_if_needed(config_path: str, checkpoint_path: Path) -> None:\n        \"\"\"Sync model-side python files when checkpoint code metadata diverges.\"\"\"\n        from acestep.model_downloader import _check_code_mismatch, _sync_model_code_files\n\n        mismatched = _check_code_mismatch(config_path, checkpoint_path)\n        if mismatched:\n            logger.warning(\n                f\"[initialize_service] Model code mismatch detected for '{config_path}': \"\n                f\"{mismatched}. Auto-syncing from acestep/models/...\"\n            )\n            _sync_model_code_files(config_path, checkpoint_path)\n            logger.info(\"[initialize_service] Model code files synced successfully.\")\n"
  },
  {
    "path": "acestep/core/generation/handler/init_service_loader.py",
    "content": "\"\"\"Checkpoint and model-loading helpers for service initialization.\"\"\"\n\nimport importlib\nimport os\nfrom typing import Optional\n\nimport torch\nfrom loguru import logger\n\nfrom .init_service_loader_components import InitServiceLoaderComponentsMixin\n\n\nclass InitServiceLoaderMixin(InitServiceLoaderComponentsMixin):\n    \"\"\"Helpers for heavy model component loading.\"\"\"\n\n    def _cuda_supports_bool_argsort(self) -> bool:\n        \"\"\"Return whether CUDA argsort supports bool tensors on the active device.\"\"\"\n        if not torch.cuda.is_available():\n            return True\n        target_device = str(getattr(self, \"device\", \"cuda\"))\n        if not target_device.startswith(\"cuda\"):\n            target_device = \"cuda\"\n        try:\n            mask_cat = torch.tensor([[True, False]], device=target_device)\n            _ = mask_cat.argsort(dim=1, descending=True, stable=True)\n            return True\n        except RuntimeError as exc:\n            logger.debug(\n                \"[_cuda_supports_bool_argsort] Treating CUDA bool argsort probe failure as unsupported: {}\",\n                exc,\n            )\n            return False\n\n    def _apply_cuda_bool_argsort_workaround(self) -> None:\n        \"\"\"Patch dynamic model helpers when bool argsort is unsupported on CUDA.\"\"\"\n        target_device = str(getattr(self, \"device\", \"\"))\n        if not target_device.startswith(\"cuda\"):\n            return\n        if self._cuda_supports_bool_argsort():\n            return\n\n        model_module_name = getattr(self.model.__class__, \"__module__\", \"\")\n        if not model_module_name:\n            return\n\n        try:\n            model_module = importlib.import_module(model_module_name)\n        except Exception as exc:\n            logger.warning(\n                \"[initialize_service] Failed to import model module for CUDA bool-argsort workaround: {}\",\n                exc,\n            )\n            return\n\n        original_pack_sequences = getattr(model_module, \"pack_sequences\", None)\n        if original_pack_sequences is None:\n            return\n        if getattr(original_pack_sequences, \"__acestep_bool_argsort_patched__\", False):\n            return\n\n        def _pack_sequences_cuda_compat(hidden1, hidden2, mask1, mask2):\n            # ``pack_sequences`` only needs sortable integer-like masks here; keep\n            # truthy/falsey semantics while avoiding CUDA bool argsort failures.\n            if isinstance(mask1, torch.Tensor) and mask1.is_cuda and mask1.dtype == torch.bool:\n                mask1 = mask1.to(torch.int32)\n            if isinstance(mask2, torch.Tensor) and mask2.is_cuda and mask2.dtype == torch.bool:\n                mask2 = mask2.to(torch.int32)\n            return original_pack_sequences(hidden1, hidden2, mask1, mask2)\n\n        _pack_sequences_cuda_compat.__acestep_bool_argsort_patched__ = True\n        setattr(model_module, \"pack_sequences\", _pack_sequences_cuda_compat)\n        logger.warning(\n            \"[initialize_service] Applied CUDA bool-argsort workaround to {}.pack_sequences\",\n            model_module_name,\n        )\n\n    @staticmethod\n    def _build_quantization_config(quantization: str):\n        \"\"\"Return a torchao quantization config object for the requested mode.\"\"\"\n        if quantization == \"int8_weight_only\":\n            from torchao.quantization import Int8WeightOnlyConfig\n            return Int8WeightOnlyConfig()\n        if quantization == \"fp8_weight_only\":\n            from torchao.quantization import Float8WeightOnlyConfig\n            return Float8WeightOnlyConfig()\n        if quantization == \"w8a8_dynamic\":\n            from torchao.quantization import Int8DynamicActivationInt8WeightConfig, MappingType\n            return Int8DynamicActivationInt8WeightConfig(act_mapping_type=MappingType.ASYMMETRIC)\n        raise ValueError(f\"Unsupported quantization type: {quantization}\")\n\n    def _apply_dit_quantization(self, quantization: Optional[str]) -> None:\n        \"\"\"Apply torchao quantization to DiT linear layers when requested.\"\"\"\n        if quantization is None:\n            return\n        from torchao.quantization import quantize_\n        from torchao.quantization.quant_api import _is_linear\n\n        quant_config = self._build_quantization_config(quantization)\n        def _dit_filter_fn(module, fqn):\n            \"\"\"Keep only decoder-side DiT linear layers and exclude tokenizers.\"\"\"\n            if not _is_linear(module, fqn):\n                return False\n            parts = fqn.split(\".\")\n            if not parts or parts[0] != \"decoder\":\n                return False\n            for part in parts:\n                if part in (\"tokenizer\", \"detokenizer\"):\n                    return False\n            return True\n\n        quantize_(self.model, quant_config, filter_fn=_dit_filter_fn)\n        logger.info(f\"[initialize_service] DiT quantized with: {quantization}\")\n\n    def _load_main_model_from_checkpoint(\n        self,\n        *,\n        model_checkpoint_path: str,\n        device: str,\n        use_flash_attention: bool,\n        compile_model: bool,\n        quantization: Optional[str],\n    ) -> str:\n        \"\"\"Load DiT, apply compile/quantization options, and return selected attention backend.\"\"\"\n        from transformers import AutoModel\n\n        if not os.path.exists(model_checkpoint_path):\n            raise FileNotFoundError(f\"ACE-Step V1.5 checkpoint not found at {model_checkpoint_path}\")\n\n        if torch.cuda.is_available():\n            if getattr(self, \"model\", None) is not None:\n                del self.model\n                self.model = None\n            torch.cuda.empty_cache()\n            try:\n                torch.cuda.synchronize()\n            except RuntimeError as exc:\n                logger.warning(\n                    \"[initialize_service] cuda.synchronize() failed during pre-load cleanup: {}. \"\n                    \"Continuing with fresh load attempt.\",\n                    exc,\n                )\n\n        if use_flash_attention and self.is_flash_attention_available(device):\n            attn_implementation = \"flash_attention_2\"\n        else:\n            if use_flash_attention:\n                logger.warning(\n                    f\"[initialize_service] Flash attention requested but unavailable for device={device}. \"\n                    \"Falling back to SDPA.\"\n                )\n            attn_implementation = \"sdpa\"\n\n        attn_candidates = [attn_implementation]\n        if \"sdpa\" not in attn_candidates:\n            attn_candidates.append(\"sdpa\")\n        if \"eager\" not in attn_candidates:\n            attn_candidates.append(\"eager\")\n\n        last_attn_error = None\n        self.model = None\n        for candidate in attn_candidates:\n            try:\n                logger.info(f\"[initialize_service] Attempting to load model with attention implementation: {candidate}\")\n                self.model = AutoModel.from_pretrained(\n                    model_checkpoint_path,\n                    trust_remote_code=True,\n                    attn_implementation=candidate,\n                    dtype=self.dtype,\n                )\n                attn_implementation = candidate\n                break\n            except Exception as exc:\n                last_attn_error = exc\n                logger.warning(f\"[initialize_service] Failed to load model with {candidate}: {exc}\")\n\n        if self.model is None:\n            raise RuntimeError(\n                f\"Failed to load model with attention implementations {attn_candidates}: {last_attn_error}\"\n            ) from last_attn_error\n\n        self.model.config._attn_implementation = attn_implementation\n        self.config = self.model.config\n        self._apply_cuda_bool_argsort_workaround()\n\n        if not self.offload_to_cpu:\n            self.model = self.model.to(device).to(self.dtype)\n        elif not self.offload_dit_to_cpu:\n            logger.info(f\"[initialize_service] Keeping main model on {device} (persistent)\")\n            self.model = self.model.to(device).to(self.dtype)\n        else:\n            self.model = self.model.to(\"cpu\").to(self.dtype)\n        self.model.eval()\n\n        if compile_model:\n            self._ensure_len_for_compile(self.model, \"model\")\n            self.model = torch.compile(self.model)\n        self._apply_dit_quantization(quantization)\n\n        silence_latent_path = os.path.join(model_checkpoint_path, \"silence_latent.pt\")\n        if not os.path.exists(silence_latent_path):\n            raise FileNotFoundError(f\"Silence latent not found at {silence_latent_path}\")\n        self.silence_latent = torch.load(silence_latent_path, weights_only=True).transpose(1, 2)\n        silence_latent_device = \"cpu\" if self.offload_to_cpu and self.offload_dit_to_cpu else device\n        self.silence_latent = self.silence_latent.to(silence_latent_device).to(self.dtype)\n        return attn_implementation\n"
  },
  {
    "path": "acestep/core/generation/handler/init_service_loader_components.py",
    "content": "\"\"\"VAE and text component loading helpers for service initialization.\"\"\"\n\nimport os\n\nimport torch\n\n\nclass InitServiceLoaderComponentsMixin:\n    \"\"\"Load VAE and text components used during service initialization.\n\n    Host contract:\n        The concrete host in the MRO must provide ``offload_to_cpu``, ``dtype``,\n        ``_get_vae_dtype(device)``, and ``_ensure_len_for_compile(module, name)``.\n        The helpers also assign ``self.vae``, ``self.text_encoder``, and\n        ``self.text_tokenizer`` as side effects.\n    \"\"\"\n\n    def _load_vae_model(self, *, checkpoint_dir: str, device: str, compile_model: bool) -> str:\n        \"\"\"Load the VAE checkpoint and return its resolved path.\n\n        Args:\n            checkpoint_dir: Root checkpoint directory containing the ``vae`` subdirectory.\n            device: Target runtime device when CPU offload is disabled.\n            compile_model: Whether to compile the loaded VAE after device placement.\n\n        Returns:\n            The resolved VAE checkpoint path as a string.\n\n        Raises:\n            FileNotFoundError: If ``checkpoint_dir`` does not contain a valid ``vae`` checkpoint.\n            Exception: Propagates loader, device transfer, or compile errors from dependencies.\n\n        Side Effects:\n            Assigns ``self.vae``, selects a device-appropriate dtype via\n            ``_get_vae_dtype()``, may offload the module to CPU, switches the module\n            to eval mode, and may compile it after calling ``_ensure_len_for_compile``.\n        \"\"\"\n        from diffusers.models import AutoencoderOobleck\n\n        vae_checkpoint_path = os.path.join(checkpoint_dir, \"vae\")\n        if not os.path.exists(vae_checkpoint_path):\n            raise FileNotFoundError(f\"VAE checkpoint not found at {vae_checkpoint_path}\")\n\n        self.vae = AutoencoderOobleck.from_pretrained(vae_checkpoint_path)\n        if not self.offload_to_cpu:\n            vae_dtype = self._get_vae_dtype(device)\n            self.vae = self.vae.to(device).to(vae_dtype)\n        else:\n            vae_dtype = self._get_vae_dtype(\"cpu\")\n            self.vae = self.vae.to(\"cpu\").to(vae_dtype)\n        self.vae.eval()\n\n        if compile_model:\n            self._ensure_len_for_compile(self.vae, \"vae\")\n            self.vae = torch.compile(self.vae)\n\n        return vae_checkpoint_path\n\n    def _load_text_encoder_and_tokenizer(self, *, checkpoint_dir: str, device: str) -> str:\n        \"\"\"Load the text tokenizer and embedding model, then return its path.\n\n        Args:\n            checkpoint_dir: Root checkpoint directory containing the text encoder subdirectory.\n            device: Target runtime device when CPU offload is disabled.\n\n        Returns:\n            The resolved text encoder checkpoint path as a string.\n\n        Raises:\n            FileNotFoundError: If ``checkpoint_dir`` does not contain the text encoder checkpoint.\n            Exception: Propagates tokenizer, model load, or device transfer errors from dependencies.\n\n        Side Effects:\n            Assigns ``self.text_tokenizer`` and ``self.text_encoder``, places the\n            text encoder on the active runtime device or CPU depending on\n            ``offload_to_cpu``, normalizes CPU offload to a CPU-safe dtype, and\n            switches the model to eval mode.\n        \"\"\"\n        from transformers import AutoModel, AutoTokenizer\n\n        text_encoder_path = os.path.join(checkpoint_dir, \"Qwen3-Embedding-0.6B\")\n        if not os.path.exists(text_encoder_path):\n            raise FileNotFoundError(f\"Text encoder not found at {text_encoder_path}\")\n\n        self.text_tokenizer = AutoTokenizer.from_pretrained(text_encoder_path)\n        self.text_encoder = AutoModel.from_pretrained(text_encoder_path)\n        if not self.offload_to_cpu:\n            self.text_encoder = self.text_encoder.to(device).to(self.dtype)\n        else:\n            cpu_dtype = self._get_vae_dtype(\"cpu\")\n            self.text_encoder = self.text_encoder.to(\"cpu\").to(cpu_dtype)\n        self.text_encoder.eval()\n        return text_encoder_path\n"
  },
  {
    "path": "acestep/core/generation/handler/init_service_memory_basic.py",
    "content": "\"\"\"Memory and device-check helpers for initialization/offload flows.\"\"\"\n\nimport torch\nfrom loguru import logger\n\n\nclass InitServiceMemoryBasicMixin:\n    \"\"\"Memory cache, sync, and tensor-device utility helpers.\"\"\"\n\n    def _empty_cache(self):\n        \"\"\"Clear accelerator memory cache (CUDA, XPU, or MPS).\"\"\"\n        device_type = self._device_type()\n        if device_type == \"cuda\" and torch.cuda.is_available():\n            torch.cuda.empty_cache()\n        elif device_type == \"xpu\" and hasattr(torch, \"xpu\") and torch.xpu.is_available():\n            torch.xpu.empty_cache()\n        elif device_type == \"mps\" and hasattr(torch.backends, \"mps\") and torch.backends.mps.is_available():\n            torch.mps.empty_cache()\n\n    def _synchronize(self):\n        \"\"\"Synchronize accelerator operations (CUDA, XPU, or MPS).\"\"\"\n        device_type = self._device_type()\n        if device_type == \"cuda\" and torch.cuda.is_available():\n            torch.cuda.synchronize()\n        elif device_type == \"xpu\" and hasattr(torch, \"xpu\") and torch.xpu.is_available():\n            torch.xpu.synchronize()\n        elif device_type == \"mps\" and hasattr(torch.backends, \"mps\") and torch.backends.mps.is_available():\n            torch.mps.synchronize()\n\n    def _memory_allocated(self):\n        \"\"\"Get current accelerator memory usage in bytes, or 0 for unsupported backends.\"\"\"\n        device_type = self._device_type()\n        if device_type == \"cuda\" and torch.cuda.is_available():\n            return torch.cuda.memory_allocated()\n        return 0\n\n    def _max_memory_allocated(self):\n        \"\"\"Get peak accelerator memory usage in bytes, or 0 for unsupported backends.\"\"\"\n        device_type = self._device_type()\n        if device_type == \"cuda\" and torch.cuda.is_available():\n            return torch.cuda.max_memory_allocated()\n        return 0\n\n    def _is_on_target_device(self, tensor, target_device):\n        \"\"\"Check if tensor is on the target device (handles cuda vs cuda:0 comparison).\"\"\"\n        if tensor is None:\n            return True\n        try:\n            if isinstance(target_device, torch.device):\n                target_type = target_device.type\n            else:\n                target_type = torch.device(str(target_device)).type\n        except Exception:\n            target_type = str(target_device).strip().lower().split(\":\", 1)[0]\n            if not target_type:\n                logger.warning(\n                    \"[_is_on_target_device] Malformed target device value: {!r}\",\n                    target_device,\n                )\n                return False\n        return tensor.device.type == target_type\n\n    @staticmethod\n    def _get_affine_quantized_tensor_class():\n        \"\"\"Return the AffineQuantizedTensor class from torchao, or None if unavailable.\"\"\"\n        try:\n            from torchao.dtypes.affine_quantized_tensor import AffineQuantizedTensor\n            return AffineQuantizedTensor\n        except Exception as exc:\n            logger.debug(\n                \"[_get_affine_quantized_tensor_class] failed to import AffineQuantizedTensor from torchao.dtypes.affine_quantized_tensor: {}\",\n                exc,\n            )\n        try:\n            from torchao.quantization.affine_quantized import AffineQuantizedTensor\n            return AffineQuantizedTensor\n        except Exception as exc:\n            logger.debug(\n                \"[_get_affine_quantized_tensor_class] failed to import AffineQuantizedTensor from torchao.quantization.affine_quantized: {}\",\n                exc,\n            )\n        return None\n\n    def _is_quantized_tensor(self, t):\n        \"\"\"True if ``t`` is a torchao AffineQuantizedTensor.\"\"\"\n        if t is None:\n            return False\n        cls = self._get_affine_quantized_tensor_class()\n        if cls is None:\n            return False\n        return isinstance(t, cls)\n\n    def _has_quantized_params(self, module):\n        \"\"\"True if module (or any submodule) has an AffineQuantizedTensor parameter.\"\"\"\n        cls = self._get_affine_quantized_tensor_class()\n        if cls is None:\n            return False\n        for _, param in module.named_parameters():\n            if param is not None and isinstance(param, cls):\n                return True\n        return False\n\n    def _ensure_silence_latent_on_device(self):\n        \"\"\"Ensure ``silence_latent`` is on ``self.device``.\"\"\"\n        if hasattr(self, \"silence_latent\") and self.silence_latent is not None:\n            if not self._is_on_target_device(self.silence_latent, self.device):\n                self.silence_latent = self.silence_latent.to(self.device).to(self.dtype)\n"
  },
  {
    "path": "acestep/core/generation/handler/init_service_memory_transfer.py",
    "content": "\"\"\"Recursive model/tensor transfer helpers for offload workflows.\"\"\"\n\nimport torch\nfrom loguru import logger\n\n\nclass InitServiceMemoryTransferMixin:\n    \"\"\"Helpers that move modules/parameters across devices and dtypes.\"\"\"\n\n    def _move_module_recursive(self, module, target_device, dtype=None, visited=None):\n        \"\"\"Recursively move a module and all submodules to the target device.\"\"\"\n        if visited is None:\n            visited = set()\n\n        module_id = id(module)\n        if module_id in visited:\n            return\n        visited.add(module_id)\n\n        module.to(target_device)\n        if dtype is not None:\n            module.to(dtype)\n\n        for param_name, param in module._parameters.items():\n            if param is not None and not self._is_on_target_device(param, target_device):\n                if self._is_quantized_tensor(param):\n                    moved_param = self._move_quantized_param(param, target_device)\n                else:\n                    moved_param = torch.nn.Parameter(\n                        param.data.to(target_device), requires_grad=param.requires_grad\n                    )\n                if dtype is not None and moved_param.is_floating_point():\n                    moved_param = torch.nn.Parameter(\n                        moved_param.data.to(dtype), requires_grad=param.requires_grad\n                    )\n                module._parameters[param_name] = moved_param\n\n        for buf_name, buf in module._buffers.items():\n            if buf is not None and not self._is_on_target_device(buf, target_device):\n                module._buffers[buf_name] = buf.to(target_device)\n\n        for _, child in module._modules.items():\n            if child is not None:\n                self._move_module_recursive(child, target_device, dtype, visited)\n\n        for attr_name in dir(module):\n            if attr_name.startswith(\"_\"):\n                continue\n            try:\n                attr = getattr(module, attr_name, None)\n                if isinstance(attr, torch.nn.Module) and id(attr) not in visited:\n                    self._move_module_recursive(attr, target_device, dtype, visited)\n            except (AttributeError, TypeError) as exc:\n                log = getattr(self, \"logger\", logger)\n                log.warning(\n                    f\"[_move_module_recursive] Skipping attr '{attr_name}' during recursive move: {exc}\"\n                )\n\n    def _move_quantized_param(self, param, target_device):\n        \"\"\"Move an AffineQuantizedTensor to target device using ``_apply_fn_to_data`` when available.\"\"\"\n        if hasattr(param, \"_apply_fn_to_data\"):\n            return torch.nn.Parameter(\n                param._apply_fn_to_data(lambda x: x.to(target_device)),\n                requires_grad=param.requires_grad,\n            )\n        moved = param.to(target_device)\n        return torch.nn.Parameter(moved, requires_grad=param.requires_grad)\n\n    def _recursive_to_device(self, model, device, dtype=None):\n        \"\"\"Recursively move parameters and buffers to the specified device.\"\"\"\n        target_device = torch.device(device) if isinstance(device, str) else device\n\n        try:\n            model.to(target_device)\n            if dtype is not None:\n                model.to(dtype)\n        except NotImplementedError:\n            logger.info(\n                \"[_recursive_to_device] model.to() raised NotImplementedError \"\n                \"(AffineQuantizedTensor on older torch). Moving parameters individually.\"\n            )\n            for module in model.modules():\n                for param_name, param in module._parameters.items():\n                    if param is None:\n                        continue\n                    if self._is_on_target_device(param, target_device):\n                        continue\n                    if self._is_quantized_tensor(param):\n                        module._parameters[param_name] = self._move_quantized_param(param, target_device)\n                    else:\n                        module._parameters[param_name] = torch.nn.Parameter(\n                            param.data.to(target_device), requires_grad=param.requires_grad\n                        )\n                        if dtype is not None:\n                            module._parameters[param_name] = torch.nn.Parameter(\n                                module._parameters[param_name].data.to(dtype),\n                                requires_grad=param.requires_grad,\n                            )\n                for buf_name, buf in module._buffers.items():\n                    if buf is not None and not self._is_on_target_device(buf, target_device):\n                        module._buffers[buf_name] = buf.to(target_device)\n\n        try:\n            self._move_module_recursive(model, target_device, dtype)\n        except NotImplementedError:\n            pass\n\n        wrong_device_params = []\n        for name, param in model.named_parameters():\n            if not self._is_on_target_device(param, device):\n                wrong_device_params.append(name)\n\n        if wrong_device_params and device != \"cpu\":\n            logger.warning(\n                f\"[_recursive_to_device] {len(wrong_device_params)} parameters on wrong device after initial move, retrying individually\"\n            )\n            for module in model.modules():\n                for param_name, param in module._parameters.items():\n                    if param is None or self._is_on_target_device(param, target_device):\n                        continue\n                    if self._is_quantized_tensor(param):\n                        module._parameters[param_name] = self._move_quantized_param(param, target_device)\n                    else:\n                        module._parameters[param_name] = torch.nn.Parameter(\n                            param.data.to(target_device), requires_grad=param.requires_grad\n                        )\n                        if dtype is not None and module._parameters[param_name].is_floating_point():\n                            module._parameters[param_name] = torch.nn.Parameter(\n                                module._parameters[param_name].data.to(dtype),\n                                requires_grad=param.requires_grad,\n                            )\n\n        if device != \"cpu\":\n            self._synchronize()\n\n        if device != \"cpu\":\n            still_wrong = []\n            for name, param in model.named_parameters():\n                if not self._is_on_target_device(param, device):\n                    still_wrong.append(f\"{name} on {param.device}\")\n            if still_wrong:\n                logger.error(\n                    f\"[_recursive_to_device] CRITICAL: {len(still_wrong)} parameters still on wrong device: {still_wrong[:10]}\"\n                )\n"
  },
  {
    "path": "acestep/core/generation/handler/init_service_offload_context.py",
    "content": "\"\"\"Context manager for temporary model loading/offloading.\"\"\"\n\nimport gc\nimport time\nfrom contextlib import contextmanager\n\nfrom loguru import logger\n\n\nclass InitServiceOffloadContextMixin:\n    \"\"\"Context-managed model load/offload behavior for CPU offload mode.\"\"\"\n\n    @contextmanager\n    def _load_model_context(self, model_name: str):\n        \"\"\"Load a model to device for the context and offload back to CPU on exit.\"\"\"\n        if not self.offload_to_cpu:\n            yield\n            return\n\n        if model_name == \"model\" and not self.offload_dit_to_cpu:\n            model = getattr(self, model_name, None)\n            if model is not None:\n                try:\n                    param = next(model.parameters())\n                    if param.device.type == \"cpu\":\n                        logger.info(f\"[_load_model_context] Moving {model_name} to {self.device} (persistent)\")\n                        self._recursive_to_device(model, self.device, self.dtype)\n                        if hasattr(self, \"silence_latent\"):\n                            self.silence_latent = self.silence_latent.to(self.device).to(self.dtype)\n                except StopIteration:\n                    pass\n            yield\n            return\n\n        model = getattr(self, model_name, None)\n        if model is None:\n            yield\n            return\n\n        logger.info(f\"[_load_model_context] Loading {model_name} to {self.device}\")\n        start_time = time.time()\n        if model_name == \"vae\":\n            vae_dtype = self._get_vae_dtype()\n            self._recursive_to_device(model, self.device, vae_dtype)\n        else:\n            self._recursive_to_device(model, self.device, self.dtype)\n\n        if model_name == \"model\" and hasattr(self, \"silence_latent\"):\n            self.silence_latent = self.silence_latent.to(self.device).to(self.dtype)\n\n        load_time = time.time() - start_time\n        self.current_offload_cost += load_time\n        logger.info(f\"[_load_model_context] Loaded {model_name} to {self.device} in {load_time:.4f}s\")\n\n        try:\n            yield\n        finally:\n            logger.info(f\"[_load_model_context] Offloading {model_name} to CPU\")\n            start_time = time.time()\n            if model_name == \"vae\":\n                self._recursive_to_device(model, \"cpu\", self._get_vae_dtype(\"cpu\"))\n            else:\n                self._recursive_to_device(model, \"cpu\")\n\n            gc.collect()\n            self._empty_cache()\n            offload_time = time.time() - start_time\n            self.current_offload_cost += offload_time\n            logger.info(f\"[_load_model_context] Offloaded {model_name} to CPU in {offload_time:.4f}s\")\n"
  },
  {
    "path": "acestep/core/generation/handler/init_service_orchestrator.py",
    "content": "\"\"\"Top-level initialization orchestration for the handler.\"\"\"\n\nimport os\nimport traceback\nfrom pathlib import Path\nfrom typing import Optional, Tuple\n\nimport torch\nfrom loguru import logger\n\nfrom acestep import gpu_config\n\n_ROCM_DTYPE_MAP = {\n    \"float32\": torch.float32,\n    \"float16\": torch.float16,\n    \"bfloat16\": torch.bfloat16,\n}\n\n\ndef _cuda_supports_bfloat16() -> bool:\n    \"\"\"Return whether the active CUDA device supports native bfloat16 kernels.\"\"\"\n    return gpu_config.cuda_supports_bfloat16()\n\n\ndef _resolve_rocm_dtype() -> torch.dtype:\n    \"\"\"Return a safe model dtype for ROCm/HIP devices.\n\n    Uses ``float32`` by default to avoid segfaults from incomplete\n    ``bfloat16`` kernel support on some ROCm GPU configurations (e.g.\n    AMD iGPUs on Strix Halo).  Set the ``ACESTEP_ROCM_DTYPE`` environment\n    variable to ``float16`` or ``bfloat16`` to override for hardware that\n    fully supports those formats.\n    \"\"\"\n    raw = os.environ.get(\"ACESTEP_ROCM_DTYPE\", \"float32\").strip().lower()\n    dtype = _ROCM_DTYPE_MAP.get(raw)\n    if dtype is None:\n        logger.warning(\n            f\"[initialize_service] Unknown ACESTEP_ROCM_DTYPE={raw!r}; \"\n            \"falling back to float32.\"\n        )\n        dtype = torch.float32\n    return dtype\n\n\nclass InitServiceOrchestratorMixin:\n    \"\"\"Public ``initialize_service`` orchestration entrypoint.\"\"\"\n\n    def initialize_service(\n        self,\n        project_root: str,\n        config_path: str,\n        device: str = \"auto\",\n        use_flash_attention: bool = False,\n        compile_model: bool = False,\n        offload_to_cpu: bool = False,\n        offload_dit_to_cpu: bool = False,\n        quantization: Optional[str] = None,\n        prefer_source: Optional[str] = None,\n        use_mlx_dit: bool = True,\n    ) -> Tuple[str, bool]:\n        \"\"\"Initialize model artifacts and runtime backends for generation.\n\n        This method intentionally supports repeated calls to reinitialize models\n        with new settings; it does not short-circuit when components are already loaded.\n        \"\"\"\n        try:\n            if config_path is None:\n                config_path = \"acestep-v15-turbo\"\n                logger.warning(\n                    \"[initialize_service] config_path not set; defaulting to 'acestep-v15-turbo'.\"\n                )\n\n            resolved_device = self._resolve_initialize_device(device)\n            self.device = resolved_device\n            self.offload_to_cpu = offload_to_cpu\n            self.offload_dit_to_cpu = offload_dit_to_cpu\n\n            normalized_compile, normalized_quantization, mlx_compile_requested = self._configure_initialize_runtime(\n                device=resolved_device,\n                compile_model=compile_model,\n                quantization=quantization,\n            )\n            self.compiled = normalized_compile\n            if resolved_device == \"cuda\" and gpu_config.is_rocm_available():\n                self.dtype = _resolve_rocm_dtype()\n                logger.info(\n                    f\"[initialize_service] ROCm/HIP device detected: using dtype={self.dtype} \"\n                    \"(set ACESTEP_ROCM_DTYPE=bfloat16 or float16 to override)\"\n                )\n            elif resolved_device == \"cuda\":\n                if gpu_config.cuda_supports_bfloat16():\n                    self.dtype = torch.bfloat16\n                else:\n                    self.dtype = torch.float16\n                    logger.info(\n                        \"[initialize_service] Pre-Ampere CUDA detected: \"\n                        \"using float16 instead of bfloat16.\"\n                    )\n            else:\n                self.dtype = torch.bfloat16 if resolved_device == \"xpu\" else torch.float32\n            self.quantization = normalized_quantization\n            try:\n                self._validate_quantization_setup(\n                    quantization=self.quantization,\n                    compile_model=normalized_compile,\n                )\n            except ImportError as exc:\n                if self.quantization is not None:\n                    logger.warning(\n                        \"[initialize_service] Quantization disabled: {}\",\n                        exc,\n                    )\n                    self.quantization = None\n                else:\n                    raise\n\n            base_root = project_root or self._get_project_root()\n            checkpoint_dir = os.path.join(base_root, \"checkpoints\")\n            checkpoint_path = Path(checkpoint_dir)\n\n            precheck_failure = self._ensure_models_present(\n                checkpoint_path=checkpoint_path,\n                config_path=config_path,\n                prefer_source=prefer_source,\n            )\n            if precheck_failure is not None:\n                self.model = None\n                self.vae = None\n                self.text_encoder = None\n                self.text_tokenizer = None\n                self.config = None\n                self.silence_latent = None\n                return precheck_failure\n\n            self._sync_model_code_if_needed(config_path, checkpoint_path)\n\n            model_path = os.path.join(checkpoint_dir, config_path)\n            self._load_main_model_from_checkpoint(\n                model_checkpoint_path=model_path,\n                device=resolved_device,\n                use_flash_attention=use_flash_attention,\n                compile_model=normalized_compile,\n                quantization=self.quantization,\n            )\n            vae_path = self._load_vae_model(\n                checkpoint_dir=checkpoint_dir,\n                device=resolved_device,\n                compile_model=normalized_compile,\n            )\n            text_encoder_path = self._load_text_encoder_and_tokenizer(\n                checkpoint_dir=checkpoint_dir,\n                device=resolved_device,\n            )\n\n            mlx_dit_status, mlx_vae_status = self._initialize_mlx_backends(\n                device=resolved_device,\n                use_mlx_dit=use_mlx_dit,\n                mlx_compile_requested=mlx_compile_requested,\n            )\n\n            status_msg = self._build_initialize_status_message(\n                device=resolved_device,\n                model_path=model_path,\n                vae_path=vae_path,\n                text_encoder_path=text_encoder_path,\n                dtype=self.dtype,\n                attention=getattr(self.config, \"_attn_implementation\", \"eager\"),\n                compile_model=normalized_compile,\n                mlx_compile_requested=mlx_compile_requested,\n                offload_to_cpu=offload_to_cpu,\n                offload_dit_to_cpu=offload_dit_to_cpu,\n                quantization=self.quantization,\n                mlx_dit_status=mlx_dit_status,\n                mlx_vae_status=mlx_vae_status,\n            )\n\n            self.last_init_params = {\n                \"project_root\": project_root,\n                \"config_path\": config_path,\n                \"device\": resolved_device,\n                \"use_flash_attention\": use_flash_attention,\n                \"compile_model\": normalized_compile,\n                \"offload_to_cpu\": offload_to_cpu,\n                \"offload_dit_to_cpu\": offload_dit_to_cpu,\n                \"quantization\": self.quantization,\n                \"use_mlx_dit\": use_mlx_dit,\n                \"prefer_source\": prefer_source,\n            }\n\n            return status_msg, True\n        except Exception as exc:\n            self.model = None\n            self.vae = None\n            self.text_encoder = None\n            self.text_tokenizer = None\n            self.config = None\n            self.silence_latent = None\n            error_msg = f\"Error initializing model: {str(exc)}\\n\\nTraceback:\\n{traceback.format_exc()}\"\n            logger.exception(error_msg)\n            return error_msg, False\n"
  },
  {
    "path": "acestep/core/generation/handler/init_service_setup.py",
    "content": "\"\"\"Runtime setup helpers for initialization orchestration.\"\"\"\n\nfrom typing import Any, Optional, Tuple\n\nimport torch\nfrom loguru import logger\n\nfrom acestep import gpu_config\n\n\nclass InitServiceSetupMixin:\n    \"\"\"Device/runtime normalization and status helpers.\"\"\"\n\n    def _resolve_initialize_device(self, requested_device: str) -> str:\n        \"\"\"Resolve a concrete runtime device, applying backend fallback rules.\"\"\"\n        device = requested_device\n        if device == \"auto\":\n            if gpu_config.is_cuda_available():\n                return \"cuda\"\n            if gpu_config.is_mps_available():\n                return \"mps\"\n            if gpu_config.is_xpu_available():\n                return \"xpu\"\n            return \"cpu\"\n\n        if device == \"cuda\" and not gpu_config.is_cuda_available():\n            if gpu_config.is_mps_available():\n                logger.warning(\"[initialize_service] CUDA requested but unavailable. Falling back to MPS.\")\n                return \"mps\"\n            if gpu_config.is_xpu_available():\n                logger.warning(\"[initialize_service] CUDA requested but unavailable. Falling back to XPU.\")\n                return \"xpu\"\n            logger.warning(\"[initialize_service] CUDA requested but unavailable. Falling back to CPU.\")\n            return \"cpu\"\n\n        if device == \"mps\" and not gpu_config.is_mps_available():\n            if gpu_config.is_cuda_available():\n                logger.warning(\"[initialize_service] MPS requested but unavailable. Falling back to CUDA.\")\n                return \"cuda\"\n            if gpu_config.is_xpu_available():\n                logger.warning(\"[initialize_service] MPS requested but unavailable. Falling back to XPU.\")\n                return \"xpu\"\n            logger.warning(\"[initialize_service] MPS requested but unavailable. Falling back to CPU.\")\n            return \"cpu\"\n\n        if device == \"xpu\" and not gpu_config.is_xpu_available():\n            if gpu_config.is_cuda_available():\n                logger.warning(\"[initialize_service] XPU requested but unavailable. Falling back to CUDA.\")\n                return \"cuda\"\n            if gpu_config.is_mps_available():\n                logger.warning(\"[initialize_service] XPU requested but unavailable. Falling back to MPS.\")\n                return \"mps\"\n            logger.warning(\"[initialize_service] XPU requested but unavailable. Falling back to CPU.\")\n            return \"cpu\"\n\n        return device\n\n    def _configure_initialize_runtime(\n        self,\n        *,\n        device: str,\n        compile_model: bool,\n        quantization: Optional[str],\n    ) -> Tuple[bool, Optional[str], bool]:\n        \"\"\"Apply backend constraints and return normalized compile/quantization settings.\"\"\"\n        mlx_compile_requested = False\n        normalized_compile = compile_model\n        normalized_quantization = quantization\n\n        if device == \"mps\":\n            if normalized_compile:\n                logger.info(\n                    \"[initialize_service] MPS detected: torch.compile is not \"\n                    \"supported - redirecting to mx.compile for MLX components.\"\n                )\n                mlx_compile_requested = True\n                normalized_compile = False\n            if normalized_quantization is not None:\n                logger.warning(\"[initialize_service] Quantization (torchao) is not supported on MPS; disabling.\")\n                normalized_quantization = None\n\n        return normalized_compile, normalized_quantization, mlx_compile_requested\n\n    @staticmethod\n    def _ensure_len_for_compile(model: Any, method_name: str) -> None:\n        \"\"\"Inject a fallback ``__len__`` implementation for torch.compile introspection.\n\n        Args:\n            model: Model instance whose class may need a ``__len__`` shim.\n            method_name: Label used in debug logs to identify the target model.\n        \"\"\"\n        if hasattr(model.__class__, \"__len__\"):\n            return\n\n        def _len_impl(_model_self):\n            \"\"\"Return a neutral length for torch.compile compatibility.\"\"\"\n            return 0\n\n        model.__class__.__len__ = _len_impl\n        logger.debug(f\"[initialize_service] Injected __len__ into {method_name} class for torch.compile\")\n\n    def _validate_quantization_setup(self, *, quantization: Optional[str], compile_model: bool) -> None:\n        \"\"\"Validate quantization prerequisites before model loading.\"\"\"\n        if quantization is None:\n            return\n        try:\n            import torchao  # noqa: F401\n        except Exception as exc:\n            raise ImportError(\n                \"torchao is required for quantization but is unavailable or incompatible \"\n                \"with this PyTorch build. Please install a compatible torchao version.\"\n            ) from exc\n\n    def _initialize_mlx_backends(\n        self,\n        *,\n        device: str,\n        use_mlx_dit: bool,\n        mlx_compile_requested: bool,\n    ) -> Tuple[str, str]:\n        \"\"\"Initialize MLX DiT/VAE integrations and return status labels.\"\"\"\n        mlx_dit_status = \"Disabled\"\n        if use_mlx_dit and device in (\"mps\", \"cpu\"):\n            mlx_ok = self._init_mlx_dit(compile_model=mlx_compile_requested)\n            if mlx_ok:\n                mlx_dit_status = (\n                    \"Active (native MLX, mx.compile)\"\n                    if mlx_compile_requested\n                    else \"Active (native MLX)\"\n                )\n            else:\n                mlx_dit_status = \"Unavailable (PyTorch fallback)\"\n        elif not use_mlx_dit:\n            mlx_dit_status = \"Disabled by user\"\n            self.mlx_decoder = None\n            self.use_mlx_dit = False\n\n        mlx_vae_status = \"Disabled\"\n        if device in (\"mps\", \"cpu\"):\n            mlx_vae_ok = self._init_mlx_vae()\n            mlx_vae_status = \"Active (native MLX)\" if mlx_vae_ok else \"Unavailable (PyTorch fallback)\"\n        else:\n            self.mlx_vae = None\n            self.use_mlx_vae = False\n\n        return mlx_dit_status, mlx_vae_status\n\n    @staticmethod\n    def _build_initialize_status_message(\n        *,\n        device: str,\n        model_path: str,\n        vae_path: str,\n        text_encoder_path: str,\n        dtype: torch.dtype,\n        attention: str,\n        compile_model: bool,\n        mlx_compile_requested: bool,\n        offload_to_cpu: bool,\n        offload_dit_to_cpu: bool,\n        quantization: Optional[str],\n        mlx_dit_status: str,\n        mlx_vae_status: str,\n    ) -> str:\n        \"\"\"Format initialize_service status output for UI/API consumers.\"\"\"\n        status_msg = f\"[OK] Model initialized successfully on {device}\\n\"\n        status_msg += f\"Main model: {model_path}\\n\"\n        status_msg += f\"VAE: {vae_path}\\n\"\n        status_msg += f\"Text encoder: {text_encoder_path}\\n\"\n        status_msg += f\"Dtype: {dtype}\\n\"\n        status_msg += f\"Attention: {attention}\\n\"\n        compiled_label = \"mx.compile (MLX)\" if mlx_compile_requested else str(compile_model)\n        status_msg += f\"Compiled: {compiled_label}\\n\"\n        status_msg += f\"Quantization: {quantization or 'Disabled'}\\n\"\n        status_msg += f\"Offload to CPU: {offload_to_cpu}\\n\"\n        status_msg += f\"Offload DiT to CPU: {offload_dit_to_cpu}\\n\"\n        status_msg += f\"MLX DiT: {mlx_dit_status}\\n\"\n        status_msg += f\"MLX VAE: {mlx_vae_status}\"\n        return status_msg\n\n"
  },
  {
    "path": "acestep/core/generation/handler/init_service_test.py",
    "content": "\"\"\"Unit tests for InitServiceMixin behavior and initialization orchestration.\"\"\"\n\nimport importlib\nimport importlib.util\nimport os\nimport tempfile\nimport builtins\nimport sys\nimport types\nimport unittest\nfrom pathlib import Path\nfrom unittest.mock import Mock, patch\n\nimport torch\n\n\ndef _load_init_service_module():\n    \"\"\"Load init_service module directly from file to avoid package side-effect imports.\"\"\"\n    repo_root = Path(__file__).resolve().parents[4]\n    if str(repo_root) not in sys.path:\n        sys.path.insert(0, str(repo_root))\n    package_paths = {\n        \"acestep\": repo_root / \"acestep\",\n        \"acestep.core\": repo_root / \"acestep\" / \"core\",\n        \"acestep.core.generation\": repo_root / \"acestep\" / \"core\" / \"generation\",\n        \"acestep.core.generation.handler\": repo_root / \"acestep\" / \"core\" / \"generation\" / \"handler\",\n    }\n    for package_name, package_path in package_paths.items():\n        if package_name in sys.modules:\n            continue\n        package_module = types.ModuleType(package_name)\n        package_module.__path__ = [str(package_path)]\n        sys.modules[package_name] = package_module\n    module_path = Path(__file__).with_name(\"init_service.py\")\n    spec = importlib.util.spec_from_file_location(\n        \"acestep.core.generation.handler.init_service\",\n        module_path,\n    )\n    module = importlib.util.module_from_spec(spec)\n    assert spec.loader is not None\n    spec.loader.exec_module(module)\n    return module\n\n\nINIT_SERVICE_MODULE = _load_init_service_module()\nInitServiceMixin = INIT_SERVICE_MODULE.InitServiceMixin\nINIT_SERVICE_DOWNLOADS_MODULE = importlib.import_module(\"acestep.core.generation.handler.init_service_downloads\")\nINIT_SERVICE_MEMORY_BASIC_MODULE = importlib.import_module(\"acestep.core.generation.handler.init_service_memory_basic\")\nINIT_SERVICE_LOADER_MODULE = importlib.import_module(\"acestep.core.generation.handler.init_service_loader\")\n\n\nclass _Host(InitServiceMixin):\n    \"\"\"Minimal host object exposing InitServiceMixin for focused unit testing.\"\"\"\n\n    def __init__(self, project_root: str, device: str = \"cpu\", config=None):\n        \"\"\"Initialize a lightweight host state used by mixin tests.\"\"\"\n        self._project_root = project_root\n        self.device = device\n        self.config = config\n        self.model = None\n        self.vae = None\n        self.text_encoder = None\n        self.text_tokenizer = None\n        self.dtype = torch.float32\n        self.offload_to_cpu = False\n        self.offload_dit_to_cpu = False\n        self.compiled = False\n        self.quantization = None\n        self.last_init_params = None\n        self.mlx_decoder = None\n        self.use_mlx_dit = False\n        self.mlx_vae = None\n        self.use_mlx_vae = False\n        self.current_offload_cost = 0.0\n\n    def _get_project_root(self):\n        \"\"\"Return the fake project root path configured for the test host.\"\"\"\n        return self._project_root\n\n    def _get_vae_dtype(self, _device: str = \"cpu\"):\n        \"\"\"Return a stable dtype for VAE-related tests.\"\"\"\n        return torch.float32\n\n    def _init_mlx_dit(self, compile_model: bool = False) -> bool:\n        \"\"\"Stub MLX DiT init hook and always report unavailable in tests.\"\"\"\n        _ = compile_model\n        return False\n\n    def _init_mlx_vae(self) -> bool:\n        \"\"\"Stub MLX VAE init hook and always report unavailable in tests.\"\"\"\n        return False\n\n\nclass InitServiceMixinTests(unittest.TestCase):\n    \"\"\"Behavioral tests for InitServiceMixin helpers and initialization flow.\"\"\"\n\n    def test_device_type_normalizes_device(self):\n        \"\"\"It normalizes device strings with explicit indexes to backend tokens.\"\"\"\n        host = _Host(project_root=\"K:/fake_root\", device=\"cuda:0\")\n        self.assertEqual(host._device_type(), \"cuda\")\n\n    def test_is_on_target_device_handles_device_alias(self):\n        \"\"\"It treats backend aliases like ``cuda`` and ``cuda:0`` as equivalent.\"\"\"\n        host = _Host(project_root=\"K:/fake_root\", device=\"cpu\")\n        t = types.SimpleNamespace(device=types.SimpleNamespace(type=\"cuda\"))\n        self.assertTrue(host._is_on_target_device(t, \"cuda:0\"))\n        self.assertFalse(host._is_on_target_device(t, \"cpu\"))\n\n    def test_is_on_target_device_fallback_does_not_assume_cuda(self):\n        \"\"\"It keeps fallback parsing backend-specific instead of defaulting to CUDA.\"\"\"\n        host = _Host(project_root=\"K:/fake_root\", device=\"cpu\")\n        t = types.SimpleNamespace(device=types.SimpleNamespace(type=\"cuda\"))\n        self.assertFalse(host._is_on_target_device(t, \"mps:0\"))\n\n    def test_is_on_target_device_malformed_target_logs_and_returns_false(self):\n        \"\"\"It logs and returns False when target device strings are malformed.\"\"\"\n        host = _Host(project_root=\"K:/fake_root\", device=\"cpu\")\n        t = types.SimpleNamespace(device=types.SimpleNamespace(type=\"cuda\"))\n        with patch.object(INIT_SERVICE_MEMORY_BASIC_MODULE.logger, \"warning\") as warning:\n            self.assertFalse(host._is_on_target_device(t, \":0\"))\n        warning.assert_called_once()\n\n\n    def test_get_auto_decode_chunk_size_uses_cuda_device_index(self):\n        \"\"\"It probes effective VRAM on the selected CUDA device index.\"\"\"\n        host = types.SimpleNamespace(\n            device=\"cuda:1\",\n            VAE_DECODE_MAX_CHUNK_SIZE=512,\n            _get_effective_mps_memory_gb=lambda: None,\n            _get_system_memory_gb=lambda: None,\n        )\n\n        with patch.object(\n            MEMORY_UTILS_MODULE,\n            \"get_effective_free_vram_gb\",\n            return_value=24.0,\n        ) as free_mock:\n            self.assertEqual(MEMORY_UTILS_MODULE.MemoryUtilsMixin._get_auto_decode_chunk_size(host), 512)\n\n        free_mock.assert_called_once_with(1)\n\n    def test_vram_guard_reduce_batch_uses_cuda_device_index(self):\n        \"\"\"It queries VRAM against the requested CUDA device when reducing batch size.\"\"\"\n        host = types.SimpleNamespace(\n            device=\"cuda:1\",\n            offload_to_cpu=False,\n            model=None,\n            config_path=\"\",\n        )\n\n        with patch.object(\n            MEMORY_UTILS_MODULE,\n            \"get_effective_free_vram_gb\",\n            return_value=1.0,\n        ) as free_mock:\n            self.assertEqual(\n                MEMORY_UTILS_MODULE.MemoryUtilsMixin._vram_guard_reduce_batch(\n                    host,\n                    2,\n                    audio_duration=60,\n                ),\n                1,\n            )\n\n        free_mock.assert_called_once_with(1)\n\n    def test_move_module_recursive_preserves_parameter_type(self):\n        \"\"\"It preserves ``torch.nn.Parameter`` objects during recursive device moves.\"\"\"\n        host = _Host(project_root=\"K:/fake_root\", device=\"cpu\")\n        module = torch.nn.Linear(2, 2)\n        with patch.object(host, \"_is_on_target_device\", return_value=False):\n            host._move_module_recursive(module, \"cpu\")\n        self.assertIsInstance(module.weight, torch.nn.Parameter)\n        self.assertIsInstance(module.bias, torch.nn.Parameter)\n\n    def test_move_quantized_param_fallback_wraps_parameter(self):\n        \"\"\"It wraps moved quantized parameters back into ``torch.nn.Parameter``.\"\"\"\n        host = _Host(project_root=\"K:/fake_root\", device=\"cpu\")\n        param = torch.nn.Parameter(torch.randn(2), requires_grad=True)\n        moved = host._move_quantized_param(param, \"cpu\")\n        self.assertIsInstance(moved, torch.nn.Parameter)\n        self.assertTrue(moved.requires_grad)\n\n    def test_get_available_checkpoints_returns_expected_list(self):\n        \"\"\"It returns checkpoint paths only when the checkpoints directory exists.\"\"\"\n        host = _Host(project_root=\"K:/fake_root\")\n        with patch(\"os.path.exists\", return_value=False):\n            self.assertEqual(host.get_available_checkpoints(), [])\n\n        with patch(\"os.path.exists\", return_value=True):\n            self.assertEqual(host.get_available_checkpoints(), [os.path.join(\"K:/fake_root\", \"checkpoints\")])\n\n    def test_get_available_acestep_v15_models_filters_and_sorts(self):\n        \"\"\"It filters to acestep-v15 directories and returns sorted model names.\"\"\"\n        host = _Host(project_root=\"K:/fake_root\")\n        with patch(\"os.path.exists\", return_value=True), patch(\n            \"os.listdir\",\n            return_value=[\"acestep-v15-zeta\", \"acestep-v15-alpha\", \"not-a-model\", \"acestep-v15-file\"],\n        ), patch(\n            \"os.path.isdir\",\n            side_effect=lambda p: p.endswith(\"acestep-v15-zeta\")\n            or p.endswith(\"acestep-v15-alpha\")\n            or p.endswith(\"not-a-model\"),\n        ):\n            self.assertEqual(\n                host.get_available_acestep_v15_models(),\n                [\"acestep-v15-alpha\", \"acestep-v15-zeta\"],\n            )\n\n    def test_is_turbo_model_uses_config_flag(self):\n        \"\"\"It reflects the ``is_turbo`` flag from handler config.\"\"\"\n        host = _Host(project_root=\"K:/fake_root\", config=None)\n        self.assertFalse(host.is_turbo_model())\n\n        host.config = types.SimpleNamespace(is_turbo=True)\n        self.assertTrue(host.is_turbo_model())\n\n    def test_is_flash_attention_available_rejects_non_cuda(self):\n        \"\"\"It rejects FlashAttention on non-CUDA targets.\"\"\"\n        host = _Host(project_root=\"K:/fake_root\", device=\"cpu\")\n        self.assertFalse(host.is_flash_attention_available())\n        self.assertFalse(host.is_flash_attention_available(device=\"mps\"))\n\n    def test_is_flash_attention_available_true_when_cuda_and_module_present(self):\n        \"\"\"It reports available when CUDA, Ampere+, and ``flash_attn`` are present.\"\"\"\n        host = _Host(project_root=\"K:/fake_root\", device=\"cuda\")\n        with patch(\"torch.cuda.is_available\", return_value=True):\n            with patch(\"torch.cuda.get_device_capability\", return_value=(8, 0)):\n                with patch.dict(\"sys.modules\", {\"flash_attn\": types.SimpleNamespace()}):\n                    self.assertTrue(host.is_flash_attention_available())\n\n    def test_is_flash_attention_available_false_when_pre_ampere_gpu(self):\n        \"\"\"It rejects FlashAttention on pre-Ampere CUDA GPUs.\"\"\"\n        host = _Host(project_root=\"K:/fake_root\", device=\"cuda\")\n        with patch(\"torch.cuda.is_available\", return_value=True):\n            with patch(\"torch.cuda.get_device_capability\", return_value=(7, 5)):\n                with patch.dict(\"sys.modules\", {\"flash_attn\": types.SimpleNamespace()}):\n                    self.assertFalse(host.is_flash_attention_available())\n\n    def test_is_flash_attention_available_false_when_module_missing(self):\n        \"\"\"It rejects FlashAttention when the module import fails.\"\"\"\n        host = _Host(project_root=\"K:/fake_root\", device=\"cuda\")\n        real_import = builtins.__import__\n\n        def fake_import(name, globals_=None, locals_=None, fromlist=(), level=0):\n            \"\"\"Raise ImportError for flash_attn while delegating all other imports.\"\"\"\n            if name == \"flash_attn\":\n                raise ImportError(\"flash_attn missing\")\n            return real_import(name, globals_, locals_, fromlist, level)\n\n        with patch(\"torch.cuda.is_available\", return_value=True):\n            with patch(\"torch.cuda.get_device_capability\", return_value=(8, 0)):\n                with patch(\"builtins.__import__\", side_effect=fake_import):\n                    self.assertFalse(host.is_flash_attention_available())\n\n    def test_resolve_initialize_device_auto_prefers_cuda(self):\n        \"\"\"It prefers CUDA first when resolving the ``auto`` device mode.\"\"\"\n        host = _Host(project_root=\"K:/fake_root\", device=\"auto\")\n        with patch(\"torch.cuda.is_available\", return_value=True):\n            with patch(\"torch.backends.mps.is_available\", return_value=False, create=True):\n                with patch(\"torch.xpu\", new=types.SimpleNamespace(is_available=lambda: False), create=True):\n                    self.assertEqual(host._resolve_initialize_device(\"auto\"), \"cuda\")\n\n    def test_configure_initialize_runtime_redirects_compile_on_mps(self):\n        \"\"\"It converts MPS compile intent to MLX compile and disables quantization.\"\"\"\n        host = _Host(project_root=\"K:/fake_root\", device=\"mps\")\n        compile_model, quantization, mlx_compile_requested = host._configure_initialize_runtime(\n            device=\"mps\",\n            compile_model=True,\n            quantization=\"int8_weight_only\",\n        )\n        self.assertFalse(compile_model)\n        self.assertIsNone(quantization)\n        self.assertTrue(mlx_compile_requested)\n\n    def test_configure_initialize_runtime_keeps_settings_on_cuda(self):\n        \"\"\"It leaves compile and quantization flags unchanged for CUDA backends.\"\"\"\n        host = _Host(project_root=\"K:/fake_root\", device=\"cuda\")\n        compile_model, quantization, mlx_compile_requested = host._configure_initialize_runtime(\n            device=\"cuda\",\n            compile_model=True,\n            quantization=\"int8_weight_only\",\n        )\n        self.assertTrue(compile_model)\n        self.assertEqual(quantization, \"int8_weight_only\")\n        self.assertFalse(mlx_compile_requested)\n\n    def test_resolve_initialize_device_requested_cuda_falls_back_to_cpu(self):\n        \"\"\"It falls back from CUDA to CPU when no accelerator backends are available.\"\"\"\n        host = _Host(project_root=\"K:/fake_root\", device=\"cuda\")\n        with patch(\"torch.cuda.is_available\", return_value=False):\n            with patch(\"torch.backends.mps.is_available\", return_value=False, create=True):\n                with patch(\"torch.xpu\", new=types.SimpleNamespace(is_available=lambda: False), create=True):\n                    self.assertEqual(host._resolve_initialize_device(\"cuda\"), \"cpu\")\n\n    def test_resolve_initialize_device_requested_cuda_falls_back_to_mps(self):\n        \"\"\"It falls back from CUDA to MPS when MPS is the first available backend.\"\"\"\n        host = _Host(project_root=\"K:/fake_root\", device=\"cuda\")\n        with patch(\"torch.cuda.is_available\", return_value=False):\n            with patch(\"torch.backends.mps.is_available\", return_value=True, create=True):\n                with patch(\"torch.xpu\", new=types.SimpleNamespace(is_available=lambda: True), create=True):\n                    self.assertEqual(host._resolve_initialize_device(\"cuda\"), \"mps\")\n\n    def test_validate_quantization_setup_allows_quantization_without_compile_model(self):\n        \"\"\"It allows quantization checks even when compile mode is disabled.\"\"\"\n        host = _Host(project_root=\"K:/fake_root\", device=\"cpu\")\n        real_import = builtins.__import__\n\n        def fake_import(name, globals_=None, locals_=None, fromlist=(), level=0):\n            \"\"\"Return a torchao stub so the check can pass without real dependency.\"\"\"\n            if name == \"torchao\":\n                return types.ModuleType(\"torchao\")\n            return real_import(name, globals_, locals_, fromlist, level)\n\n        with patch(\"builtins.__import__\", side_effect=fake_import):\n            host._validate_quantization_setup(quantization=\"int8_weight_only\", compile_model=False)\n\n    def test_ensure_models_present_returns_download_error_when_main_model_fails(self):\n        \"\"\"It returns an error tuple when main model download fails.\"\"\"\n        host = _Host(project_root=\"K:/fake_root\", device=\"cpu\")\n        with patch.object(INIT_SERVICE_DOWNLOADS_MODULE, \"check_main_model_exists\", return_value=False):\n            with patch.object(INIT_SERVICE_DOWNLOADS_MODULE, \"ensure_main_model\", return_value=(False, \"boom\")):\n                result = host._ensure_models_present(\n                    checkpoint_path=Path(\"K:/fake_root/checkpoints\"),\n                    config_path=\"acestep-v15-turbo\",\n                    prefer_source=None,\n                )\n        self.assertEqual(result, (\"ERROR: Failed to download main model: boom\", False))\n\n    def test_build_initialize_status_message_reports_mlx_compile_label(self):\n        \"\"\"It renders the mx.compile label when MLX compile redirection is active.\"\"\"\n        msg = _Host._build_initialize_status_message(\n            device=\"mps\",\n            model_path=\"m\",\n            vae_path=\"v\",\n            text_encoder_path=\"t\",\n            dtype=torch.float32,\n            attention=\"sdpa\",\n            compile_model=False,\n            mlx_compile_requested=True,\n            offload_to_cpu=False,\n            offload_dit_to_cpu=False,\n            quantization=\"w8a8_dynamic\",\n            mlx_dit_status=\"Active\",\n            mlx_vae_status=\"Active\",\n        )\n        self.assertIn(\"Compiled: mx.compile (MLX)\", msg)\n        self.assertIn(\"Quantization: w8a8_dynamic\", msg)\n\n    def test_initialize_mlx_backends_disables_dit_when_requested(self):\n        \"\"\"It disables MLX DiT state when caller explicitly opts out.\"\"\"\n        host = _Host(project_root=\"K:/fake_root\", device=\"cpu\")\n        host.mlx_decoder = object()\n        host.use_mlx_dit = True\n        dit_status, vae_status = host._initialize_mlx_backends(\n            device=\"cpu\",\n            use_mlx_dit=False,\n            mlx_compile_requested=False,\n        )\n        self.assertEqual(dit_status, \"Disabled by user\")\n        self.assertIn(\"Unavailable\", vae_status)\n        self.assertIsNone(host.mlx_decoder)\n        self.assertFalse(host.use_mlx_dit)\n\n    def test_initialize_service_returns_model_precheck_failure(self):\n        \"\"\"It returns precheck failures without continuing initialization work.\"\"\"\n        host = _Host(project_root=\"K:/fake_root\", device=\"cpu\")\n        with patch.object(host, \"_ensure_models_present\", return_value=(\"download failed\", False)):\n            status, ok = host.initialize_service(\n                project_root=\"K:/fake_root\",\n                config_path=\"acestep-v15-turbo\",\n                device=\"cpu\",\n            )\n        self.assertEqual(status, \"download failed\")\n        self.assertFalse(ok)\n\n    def test_initialize_service_clears_stale_state_on_model_precheck_failure(self):\n        \"\"\"It clears stale model attributes before returning a precheck failure.\"\"\"\n        host = _Host(project_root=\"K:/fake_root\", device=\"cpu\")\n        host.model = object()\n        host.vae = object()\n        host.text_encoder = object()\n        host.text_tokenizer = object()\n        host.config = object()\n        host.silence_latent = object()\n\n        with patch.object(host, \"_ensure_models_present\", return_value=(\"download failed\", False)):\n            status, ok = host.initialize_service(\n                project_root=\"K:/fake_root\",\n                config_path=\"acestep-v15-turbo\",\n                device=\"cpu\",\n            )\n\n        self.assertEqual(status, \"download failed\")\n        self.assertFalse(ok)\n        self.assertIsNone(host.model)\n        self.assertIsNone(host.vae)\n        self.assertIsNone(host.text_encoder)\n        self.assertIsNone(host.text_tokenizer)\n        self.assertIsNone(host.config)\n        self.assertIsNone(host.silence_latent)\n\n    def test_initialize_service_uses_provided_project_root_for_checkpoints(self):\n        \"\"\"It builds checkpoint paths from the provided project_root when truthy.\"\"\"\n        host = _Host(project_root=\"K:/fallback_root\", device=\"cpu\")\n\n        def _fake_load_main_model(**kwargs):\n            \"\"\"Capture model path and initialize minimal config state.\"\"\"\n            host._captured_model_path = kwargs[\"model_checkpoint_path\"]\n            host.config = types.SimpleNamespace(_attn_implementation=\"sdpa\")\n            host.model = object()\n\n        with patch.object(host, \"_ensure_models_present\", return_value=None):\n            with patch.object(host, \"_sync_model_code_if_needed\"):\n                with patch.object(host, \"_load_main_model_from_checkpoint\", side_effect=_fake_load_main_model):\n                    with patch.object(host, \"_load_vae_model\", return_value=\"K:/custom_root/checkpoints/vae\"):\n                        with patch.object(\n                            host,\n                            \"_load_text_encoder_and_tokenizer\",\n                            return_value=\"K:/custom_root/checkpoints/Qwen3-Embedding-0.6B\",\n                        ):\n                            with patch.object(host, \"_initialize_mlx_backends\", return_value=(\"Disabled\", \"Disabled\")):\n                                status, ok = host.initialize_service(\n                                    project_root=\"K:/custom_root\",\n                                    config_path=\"acestep-v15-turbo\",\n                                    device=\"cpu\",\n                                )\n        self.assertTrue(ok)\n        expected_model_path = os.path.normpath(\"K:/custom_root/checkpoints/acestep-v15-turbo\")\n        self.assertEqual(os.path.normpath(host._captured_model_path), expected_model_path)\n        self.assertIn(expected_model_path, os.path.normpath(status))\n\n    def test_initialize_service_success_uses_decomposed_helpers(self):\n        \"\"\"It executes decomposed helper calls and returns a success status payload.\"\"\"\n        host = _Host(project_root=\"K:/fake_root\", device=\"cpu\")\n\n        def _fake_load_main_model(**_kwargs):\n            \"\"\"Simulate successful main-model load by setting minimal config state.\"\"\"\n            host.config = types.SimpleNamespace(_attn_implementation=\"sdpa\")\n            host.model = object()\n\n        with patch.object(host, \"_ensure_models_present\", return_value=None) as ensure_models:\n            with patch.object(host, \"_sync_model_code_if_needed\") as sync_code:\n                with patch.object(host, \"_load_main_model_from_checkpoint\", side_effect=_fake_load_main_model):\n                    with patch.object(host, \"_load_vae_model\", return_value=\"K:/fake_root/checkpoints/vae\"):\n                        with patch.object(\n                            host,\n                            \"_load_text_encoder_and_tokenizer\",\n                            return_value=\"K:/fake_root/checkpoints/Qwen3-Embedding-0.6B\",\n                        ):\n                            with patch.object(\n                                host,\n                                \"_initialize_mlx_backends\",\n                                return_value=(\"Disabled\", \"Disabled\"),\n                            ):\n                                status, ok = host.initialize_service(\n                                    project_root=\"K:/fake_root\",\n                                    config_path=\"acestep-v15-turbo\",\n                                    device=\"cpu\",\n                                )\n        self.assertTrue(ok)\n        self.assertIn(\"Model initialized successfully on cpu\", status)\n        expected_keys = {\n            \"project_root\",\n            \"config_path\",\n            \"device\",\n            \"use_flash_attention\",\n            \"compile_model\",\n            \"offload_to_cpu\",\n            \"offload_dit_to_cpu\",\n            \"quantization\",\n            \"use_mlx_dit\",\n            \"prefer_source\",\n        }\n        self.assertEqual(set(host.last_init_params.keys()), expected_keys)\n        self.assertEqual(host.last_init_params[\"config_path\"], \"acestep-v15-turbo\")\n        self.assertEqual(host.last_init_params[\"device\"], \"cpu\")\n        ensure_models.assert_called_once()\n        sync_code.assert_called_once()\n\n    def test_initialize_service_returns_error_payload_when_loader_raises(self):\n        \"\"\"It catches init errors and returns a formatted failure message.\"\"\"\n        host = _Host(project_root=\"K:/fake_root\", device=\"cpu\")\n        with patch.object(host, \"_ensure_models_present\", return_value=None):\n            with patch.object(host, \"_sync_model_code_if_needed\"):\n                with patch.object(host, \"_load_main_model_from_checkpoint\", side_effect=RuntimeError(\"load failed\")):\n                    status, ok = host.initialize_service(\n                        project_root=\"K:/fake_root\",\n                        config_path=\"acestep-v15-turbo\",\n                        device=\"cpu\",\n                    )\n        self.assertFalse(ok)\n        self.assertIn(\"Error initializing model\", status)\n        self.assertIn(\"load failed\", status)\n        self.assertIn(\"Traceback:\", status)\n        self.assertIn(\"RuntimeError: load failed\", status)\n\n    def test_load_main_model_ignores_cuda_sync_cleanup_error(self):\n        \"\"\"It continues model loading when pre-load ``cuda.synchronize`` raises.\"\"\"\n        host = _Host(project_root=\"K:/fake_root\", device=\"cpu\")\n        host.offload_to_cpu = True\n        host.offload_dit_to_cpu = True\n\n        class _DummyModel:\n            \"\"\"Minimal model stub matching loader expectations.\"\"\"\n\n            def __init__(self):\n                self.config = types.SimpleNamespace(_attn_implementation=\"sdpa\")\n\n            def to(self, *_args, **_kwargs):\n                return self\n\n            def eval(self):\n                return self\n\n        with tempfile.TemporaryDirectory() as tmpdir:\n            checkpoint_dir = os.path.join(tmpdir, \"acestep-v15-turbo\")\n            os.makedirs(checkpoint_dir, exist_ok=True)\n            torch.save(torch.zeros(1, 1, 1), os.path.join(checkpoint_dir, \"silence_latent.pt\"))\n\n            with patch(\"torch.cuda.is_available\", return_value=True), \\\n                    patch(\"torch.cuda.empty_cache\"), \\\n                    patch(\"torch.cuda.synchronize\", side_effect=RuntimeError(\"oom during sync\")), \\\n                    patch(\"transformers.AutoModel.from_pretrained\", return_value=_DummyModel()), \\\n                    patch.object(host, \"is_flash_attention_available\", return_value=False):\n                attn = host._load_main_model_from_checkpoint(\n                    model_checkpoint_path=checkpoint_dir,\n                    device=\"cpu\",\n                    use_flash_attention=False,\n                    compile_model=False,\n                    quantization=None,\n                )\n\n        self.assertEqual(attn, \"sdpa\")\n        self.assertIsNotNone(host.model)\n        self.assertIsNotNone(host.silence_latent)\n\n    def test_apply_cuda_bool_argsort_workaround_patches_pack_sequences(self):\n        \"\"\"It monkey-patches dynamic ``pack_sequences`` when CUDA bool argsort is unsupported.\"\"\"\n        host = _Host(project_root=\"K:/fake_root\", device=\"cuda\")\n\n        class _DummyModel:\n            \"\"\"Model stub exposing a dynamic module path.\"\"\"\n\n        _DummyModel.__module__ = \"dummy_cuda_pack_module\"\n        host.model = _DummyModel()\n\n        def _pack_sequences(_h1, _h2, _m1, _m2):\n            \"\"\"Original no-op function used for patch detection.\"\"\"\n            return \"ok\"\n\n        dummy_module = types.SimpleNamespace(pack_sequences=_pack_sequences)\n\n        with patch.object(host, \"_cuda_supports_bool_argsort\", return_value=False), \\\n                patch.object(INIT_SERVICE_LOADER_MODULE.importlib, \"import_module\", return_value=dummy_module):\n            host._apply_cuda_bool_argsort_workaround()\n\n        self.assertIsNot(dummy_module.pack_sequences, _pack_sequences)\n        self.assertTrue(getattr(dummy_module.pack_sequences, \"__acestep_bool_argsort_patched__\", False))\n\n    def test_cuda_supports_bool_argsort_returns_false_for_unexpected_runtime_error(self):\n        \"\"\"It treats any CUDA bool argsort RuntimeError as unsupported.\"\"\"\n        host = _Host(project_root=\"K:/fake_root\", device=\"cuda\")\n        mask_cat = Mock()\n        mask_cat.argsort.side_effect = RuntimeError(\"unexpected argsort failure\")\n\n        with patch(\"torch.cuda.is_available\", return_value=True), patch(\n            \"torch.tensor\",\n            return_value=mask_cat,\n        ):\n            self.assertFalse(host._cuda_supports_bool_argsort())\n\n        mask_cat.argsort.assert_called_once_with(dim=1, descending=True, stable=True)\n\n\n    def test_apply_dit_quantization_filters_to_decoder_linear_layers(self):\n        \"\"\"It quantizes only decoder-side linear layers.\"\"\"\n        host = _Host(project_root=\"K:/fake_root\", device=\"cpu\")\n        host.model = object()\n        observed = {}\n\n        class _DummyConfig:\n            pass\n\n        def fake_quantize(_model, _config, filter_fn):\n            observed[\"decoder\"] = filter_fn(object(), \"decoder.layers.0.fc\")\n            observed[\"encoder\"] = filter_fn(object(), \"encoder.layers.0.fc\")\n            observed[\"tokenizer\"] = filter_fn(object(), \"decoder.tokenizer.proj\")\n            observed[\"detokenizer\"] = filter_fn(object(), \"decoder.detokenizer.proj\")\n\n        quantization_module = types.ModuleType(\"torchao.quantization\")\n        quantization_module.Int8WeightOnlyConfig = _DummyConfig\n        quantization_module.quantize_ = fake_quantize\n        quant_api_module = types.ModuleType(\"torchao.quantization.quant_api\")\n        quant_api_module._is_linear = lambda _module, _fqn: True\n        torchao_module = types.ModuleType(\"torchao\")\n        torchao_module.quantization = quantization_module\n\n        with patch.dict(\n            sys.modules,\n            {\n                \"torchao\": torchao_module,\n                \"torchao.quantization\": quantization_module,\n                \"torchao.quantization.quant_api\": quant_api_module,\n            },\n        ):\n            host._apply_dit_quantization(\"int8_weight_only\")\n\n        self.assertTrue(observed[\"decoder\"])\n        self.assertFalse(observed[\"encoder\"])\n        self.assertFalse(observed[\"tokenizer\"])\n        self.assertFalse(observed[\"detokenizer\"])\n\n    def test_validate_quantization_setup_raises_import_error_when_torchao_missing(self):\n        \"\"\"It raises ImportError with guidance when torchao is unavailable.\"\"\"\n        host = _Host(project_root=\"K:/fake_root\", device=\"cpu\")\n        real_import = builtins.__import__\n\n        def fake_import(name, globals_=None, locals_=None, fromlist=(), level=0):\n            \"\"\"Raise ImportError only for torchao imports.\"\"\"\n            if name == \"torchao\":\n                raise ImportError(\"torchao missing\")\n            return real_import(name, globals_, locals_, fromlist, level)\n\n        with patch(\"builtins.__import__\", side_effect=fake_import):\n            with self.assertRaises(ImportError) as ctx:\n                host._validate_quantization_setup(\n                    quantization=\"int8_weight_only\",\n                    compile_model=True,\n                )\n        self.assertIn(\"torchao is required\", str(ctx.exception))\n\n    def test_initialize_service_disables_quantization_when_torchao_is_incompatible(self):\n        \"\"\"It falls back to non-quantized initialization when torchao checks fail.\"\"\"\n        host = _Host(project_root=\"K:/fake_root\", device=\"cpu\")\n\n        def _fake_load_main_model(**_kwargs):\n            host.config = types.SimpleNamespace(_attn_implementation=\"sdpa\")\n            host.model = object()\n\n        with patch.object(host, \"_ensure_models_present\", return_value=None), \\\n                patch.object(host, \"_sync_model_code_if_needed\"), \\\n                patch.object(host, \"_validate_quantization_setup\", side_effect=ImportError(\"torchao incompatible\")), \\\n                patch.object(host, \"_load_main_model_from_checkpoint\", side_effect=_fake_load_main_model), \\\n                patch.object(host, \"_load_vae_model\", return_value=\"vae\"), \\\n                patch.object(host, \"_load_text_encoder_and_tokenizer\", return_value=\"te\"), \\\n                patch.object(host, \"_initialize_mlx_backends\", return_value=(\"Disabled\", \"Disabled\")):\n            status, ok = host.initialize_service(\n                project_root=\"K:/fake_root\",\n                config_path=\"acestep-v15-turbo\",\n                device=\"cpu\",\n                quantization=\"int8_weight_only\",\n            )\n        self.assertTrue(ok)\n        self.assertIsNone(host.quantization)\n        self.assertIn(\"Model initialized successfully on cpu\", status)\n\n    def test_get_affine_quantized_tensor_class_returns_none_on_torchao_attr_error(self):\n        \"\"\"It treats torchao runtime import errors as unavailable quantization support.\"\"\"\n        host = _Host(project_root=\"K:/fake_root\", device=\"cpu\")\n        real_import = builtins.__import__\n\n        def fake_import(name, globals_=None, locals_=None, fromlist=(), level=0):\n            \"\"\"Simulate incompatible torchao module imports raising AttributeError.\"\"\"\n            if name in {\n                \"torchao.dtypes.affine_quantized_tensor\",\n                \"torchao.quantization.affine_quantized\",\n            }:\n                raise AttributeError(\"incompatible torchao build\")\n            return real_import(name, globals_, locals_, fromlist, level)\n\n        with patch(\"builtins.__import__\", side_effect=fake_import):\n            result = host._get_affine_quantized_tensor_class()\n        self.assertIsNone(result)\n\n    def test_load_model_context_yields_immediately_when_offload_disabled(self):\n        \"\"\"It does not move models when offload_to_cpu is disabled.\"\"\"\n        host = _Host(project_root=\"K:/fake_root\", device=\"cpu\")\n        host.offload_to_cpu = False\n        host.model = torch.nn.Linear(1, 1)\n        with patch.object(host, \"_recursive_to_device\") as move_mock:\n            with host._load_model_context(\"model\"):\n                pass\n        move_mock.assert_not_called()\n\n    def test_load_model_context_loads_and_offloads_when_enabled_for_vae(self):\n        \"\"\"It performs load/offload calls around the context body for VAE.\"\"\"\n        host = _Host(project_root=\"K:/fake_root\", device=\"cpu\")\n        host.offload_to_cpu = True\n        host.vae = torch.nn.Linear(1, 1)\n        with patch.object(host, \"_recursive_to_device\") as move_mock:\n            with patch.object(host, \"_empty_cache\") as empty_cache:\n                with host._load_model_context(\"vae\"):\n                    pass\n        self.assertEqual(move_mock.call_count, 2)\n        empty_cache.assert_called_once()\n\n    def test_recursive_to_device_uses_quantized_move_fallback(self):\n        \"\"\"It routes parameters through quantized move fallback after to() failure.\"\"\"\n        host = _Host(project_root=\"K:/fake_root\", device=\"cpu\")\n        model = torch.nn.Linear(2, 2)\n\n        def _raise_not_implemented(*_args, **_kwargs):\n            \"\"\"Simulate older torch behavior for quantized tensor moves.\"\"\"\n            raise NotImplementedError(\"no shallow copy\")\n\n        model.to = _raise_not_implemented  # type: ignore[assignment]\n        with patch.object(host, \"_is_on_target_device\", return_value=False):\n            with patch.object(host, \"_is_quantized_tensor\", return_value=True):\n                with patch.object(\n                    host,\n                    \"_move_quantized_param\",\n                    side_effect=lambda p, _d: torch.nn.Parameter(p.data, requires_grad=p.requires_grad),\n                ) as move_quant:\n                    host._recursive_to_device(model, \"cpu\")\n        self.assertGreaterEqual(move_quant.call_count, 1)\n\n    def test_empty_cache_routes_to_cuda(self):\n        \"\"\"It routes cache clearing to CUDA when the host device is CUDA.\"\"\"\n        host = _Host(project_root=\"K:/fake_root\", device=\"cuda\")\n        with patch(\"torch.cuda.is_available\", return_value=True), patch(\"torch.cuda.empty_cache\") as empty_cache:\n            host._empty_cache()\n            empty_cache.assert_called_once()\n\n    def test_empty_cache_routes_to_xpu(self):\n        \"\"\"It routes cache clearing to XPU when the host device is XPU.\"\"\"\n        host = _Host(project_root=\"K:/fake_root\", device=\"xpu\")\n        empty_cache = Mock()\n        xpu_stub = types.SimpleNamespace(is_available=lambda: True, empty_cache=empty_cache)\n        with patch(\"torch.xpu\", new=xpu_stub, create=True):\n            host._empty_cache()\n        empty_cache.assert_called_once()\n\n    def test_empty_cache_routes_to_mps(self):\n        \"\"\"It routes cache clearing to MPS when the host device is MPS.\"\"\"\n        host = _Host(project_root=\"K:/fake_root\", device=\"mps\")\n        with patch(\"torch.backends.mps.is_available\", return_value=True, create=True), patch(\"torch.mps.empty_cache\") as empty_cache:\n            host._empty_cache()\n            empty_cache.assert_called_once()\n\n    def test_synchronize_routes_to_cuda(self):\n        \"\"\"It routes synchronization to CUDA when the host device is CUDA.\"\"\"\n        host = _Host(project_root=\"K:/fake_root\", device=\"cuda\")\n        with patch(\"torch.cuda.is_available\", return_value=True), patch(\"torch.cuda.synchronize\") as sync:\n            host._synchronize()\n            sync.assert_called_once()\n\n    def test_synchronize_routes_to_xpu(self):\n        \"\"\"It routes synchronization to XPU when the host device is XPU.\"\"\"\n        host = _Host(project_root=\"K:/fake_root\", device=\"xpu\")\n        sync = Mock()\n        xpu_stub = types.SimpleNamespace(is_available=lambda: True, synchronize=sync)\n        with patch(\"torch.xpu\", new=xpu_stub, create=True):\n            host._synchronize()\n        sync.assert_called_once()\n\n    def test_synchronize_routes_to_mps(self):\n        \"\"\"It routes synchronization to MPS when the host device is MPS.\"\"\"\n        host = _Host(project_root=\"K:/fake_root\", device=\"mps\")\n        with patch(\"torch.backends.mps.is_available\", return_value=True, create=True), patch(\"torch.mps.synchronize\") as sync:\n            host._synchronize()\n            sync.assert_called_once()\n\n    def test_memory_queries_use_cuda_only(self):\n        \"\"\"It reports memory metrics only for CUDA and returns zero elsewhere.\"\"\"\n        host = _Host(project_root=\"K:/fake_root\", device=\"cpu\")\n        self.assertEqual(host._memory_allocated(), 0)\n        self.assertEqual(host._max_memory_allocated(), 0)\n\n        host.device = \"cuda\"\n        with patch(\"torch.cuda.is_available\", return_value=True):\n            with patch(\"torch.cuda.memory_allocated\", return_value=123), patch(\n                \"torch.cuda.max_memory_allocated\", return_value=456\n            ):\n                self.assertEqual(host._memory_allocated(), 123)\n                self.assertEqual(host._max_memory_allocated(), 456)\n\n\nORCHESTRATOR_MODULE = importlib.import_module(\n    \"acestep.core.generation.handler.init_service_orchestrator\"\n)\nGPU_CONFIG_MODULE = importlib.import_module(\"acestep.gpu_config\")\nMEMORY_UTILS_MODULE = importlib.import_module(\n    \"acestep.core.generation.handler.memory_utils\"\n)\n\n\nclass _VaeHost(_Host):\n    \"\"\"Host variant that exposes the real MemoryUtilsMixin._get_vae_dtype implementation.\n\n    The base _Host overrides ``_get_vae_dtype`` for stability in unrelated tests;\n    this subclass removes the override so ROCm VAE-dtype tests exercise the real logic.\n    \"\"\"\n\n    _get_vae_dtype = MEMORY_UTILS_MODULE.MemoryUtilsMixin._get_vae_dtype\n\n\nclass RocmDtypeTests(unittest.TestCase):\n    \"\"\"Tests verifying safe dtype selection for ROCm/HIP devices.\"\"\"\n\n    def _make_rocm_host(self, device: str = \"cuda\") -> _Host:\n        \"\"\"Return a minimal host configured as if running on ROCm.\"\"\"\n        host = _Host(project_root=\"K:/fake_root\", device=device)\n        host.dtype = torch.float32\n        return host\n\n    def test_resolve_rocm_dtype_defaults_to_float32(self):\n        \"\"\"It returns float32 when ACESTEP_ROCM_DTYPE is not set.\"\"\"\n        with patch.dict(\"os.environ\", {}, clear=False):\n            os.environ.pop(\"ACESTEP_ROCM_DTYPE\", None)\n            result = ORCHESTRATOR_MODULE._resolve_rocm_dtype()\n        self.assertEqual(result, torch.float32)\n\n    def test_resolve_rocm_dtype_respects_float16_override(self):\n        \"\"\"It returns float16 when ACESTEP_ROCM_DTYPE=float16.\"\"\"\n        with patch.dict(\"os.environ\", {\"ACESTEP_ROCM_DTYPE\": \"float16\"}):\n            result = ORCHESTRATOR_MODULE._resolve_rocm_dtype()\n        self.assertEqual(result, torch.float16)\n\n    def test_resolve_rocm_dtype_respects_bfloat16_override(self):\n        \"\"\"It returns bfloat16 when ACESTEP_ROCM_DTYPE=bfloat16.\"\"\"\n        with patch.dict(\"os.environ\", {\"ACESTEP_ROCM_DTYPE\": \"bfloat16\"}):\n            result = ORCHESTRATOR_MODULE._resolve_rocm_dtype()\n        self.assertEqual(result, torch.bfloat16)\n\n    def test_resolve_rocm_dtype_unknown_value_falls_back_to_float32(self):\n        \"\"\"It falls back to float32 for unrecognised ACESTEP_ROCM_DTYPE values.\"\"\"\n        with patch.dict(\"os.environ\", {\"ACESTEP_ROCM_DTYPE\": \"int8\"}):\n            result = ORCHESTRATOR_MODULE._resolve_rocm_dtype()\n        self.assertEqual(result, torch.float32)\n\n    def test_initialize_service_uses_float32_on_rocm(self):\n        \"\"\"It sets dtype=float32 during initialization when ROCm is active.\"\"\"\n        host = self._make_rocm_host()\n\n        def _fake_load_main_model(**_kwargs):\n            host.config = types.SimpleNamespace(_attn_implementation=\"sdpa\")\n            host.model = object()\n\n        with patch.object(GPU_CONFIG_MODULE, \"is_cuda_available\", return_value=True), \\\n                patch.object(GPU_CONFIG_MODULE, \"is_rocm_available\", return_value=True), \\\n                patch.dict(\"os.environ\", {}, clear=False):\n            os.environ.pop(\"ACESTEP_ROCM_DTYPE\", None)\n            with patch.object(host, \"_ensure_models_present\", return_value=None):\n                with patch.object(host, \"_sync_model_code_if_needed\"):\n                    with patch.object(\n                        host,\n                        \"_load_main_model_from_checkpoint\",\n                        side_effect=_fake_load_main_model,\n                    ):\n                        with patch.object(host, \"_load_vae_model\", return_value=\"vae\"):\n                            with patch.object(\n                                host,\n                                \"_load_text_encoder_and_tokenizer\",\n                                return_value=\"te\",\n                            ):\n                                with patch.object(\n                                    host,\n                                    \"_initialize_mlx_backends\",\n                                    return_value=(\"Disabled\", \"Disabled\"),\n                                ):\n                                    _, ok = host.initialize_service(\n                                        project_root=\"K:/fake_root\",\n                                        config_path=\"acestep-v15-turbo\",\n                                        device=\"cuda\",\n                                    )\n        self.assertTrue(ok)\n        self.assertEqual(host.dtype, torch.float32)\n\n    def test_initialize_service_uses_bfloat16_on_non_rocm_cuda(self):\n        \"\"\"It keeps dtype=bfloat16 on standard CUDA (non-ROCm) devices.\"\"\"\n        host = self._make_rocm_host()\n\n        def _fake_load_main_model(**_kwargs):\n            host.config = types.SimpleNamespace(_attn_implementation=\"sdpa\")\n            host.model = object()\n\n        with patch.object(GPU_CONFIG_MODULE, \"is_cuda_available\", return_value=True), \\\n                patch.object(GPU_CONFIG_MODULE, \"is_rocm_available\", return_value=False), \\\n                patch.object(GPU_CONFIG_MODULE, \"cuda_supports_bfloat16\", return_value=True):\n            with patch.object(host, \"_ensure_models_present\", return_value=None):\n                with patch.object(host, \"_sync_model_code_if_needed\"):\n                    with patch.object(\n                        host,\n                        \"_load_main_model_from_checkpoint\",\n                        side_effect=_fake_load_main_model,\n                    ):\n                        with patch.object(host, \"_load_vae_model\", return_value=\"vae\"):\n                            with patch.object(\n                                host,\n                                \"_load_text_encoder_and_tokenizer\",\n                                return_value=\"te\",\n                            ):\n                                with patch.object(\n                                    host,\n                                    \"_initialize_mlx_backends\",\n                                    return_value=(\"Disabled\", \"Disabled\"),\n                                ):\n                                    _, ok = host.initialize_service(\n                                        project_root=\"K:/fake_root\",\n                                        config_path=\"acestep-v15-turbo\",\n                                        device=\"cuda\",\n                                    )\n        self.assertTrue(ok)\n        self.assertEqual(host.dtype, torch.bfloat16)\n\n    def test_initialize_service_uses_float16_on_pre_ampere_cuda(self):\n        \"\"\"It falls back to float16 on pre-Ampere CUDA GPUs.\"\"\"\n        host = self._make_rocm_host()\n\n        def _fake_load_main_model(**_kwargs):\n            host.config = types.SimpleNamespace(_attn_implementation=\"sdpa\")\n            host.model = object()\n\n        with patch.object(GPU_CONFIG_MODULE, \"is_cuda_available\", return_value=True), \\\n                patch.object(GPU_CONFIG_MODULE, \"is_rocm_available\", return_value=False), \\\n                patch.object(GPU_CONFIG_MODULE, \"cuda_supports_bfloat16\", return_value=False):\n            with patch.object(host, \"_ensure_models_present\", return_value=None):\n                with patch.object(host, \"_sync_model_code_if_needed\"):\n                    with patch.object(\n                        host,\n                        \"_load_main_model_from_checkpoint\",\n                        side_effect=_fake_load_main_model,\n                    ):\n                        with patch.object(host, \"_load_vae_model\", return_value=\"vae\"):\n                            with patch.object(\n                                host,\n                                \"_load_text_encoder_and_tokenizer\",\n                                return_value=\"te\",\n                            ):\n                                with patch.object(\n                                    host,\n                                    \"_initialize_mlx_backends\",\n                                    return_value=(\"Disabled\", \"Disabled\"),\n                                ):\n                                    _, ok = host.initialize_service(\n                                        project_root=\"K:/fake_root\",\n                                        config_path=\"acestep-v15-turbo\",\n                                        device=\"cuda\",\n                                    )\n        self.assertTrue(ok)\n        self.assertEqual(host.dtype, torch.float16)\n\n    def test_get_vae_dtype_returns_self_dtype_on_rocm(self):\n        \"\"\"It defers to self.dtype for VAE when ROCm is active.\"\"\"\n        host = _VaeHost(project_root=\"K:/fake_root\", device=\"cuda\")\n        host.dtype = torch.float32\n        with patch.object(MEMORY_UTILS_MODULE, \"is_rocm_available\", return_value=True):\n            result = host._get_vae_dtype(\"cuda\")\n        self.assertEqual(result, torch.float32)\n\n    def test_get_vae_dtype_rocm_override_propagates_float16(self):\n        \"\"\"It propagates float16 VAE dtype when self.dtype is float16 on ROCm.\"\"\"\n        host = _VaeHost(project_root=\"K:/fake_root\", device=\"cuda\")\n        host.dtype = torch.float16\n        with patch.object(MEMORY_UTILS_MODULE, \"is_rocm_available\", return_value=True):\n            result = host._get_vae_dtype(\"cuda\")\n        self.assertEqual(result, torch.float16)\n\n    def test_get_vae_dtype_returns_bfloat16_on_non_rocm_cuda(self):\n        \"\"\"It returns bfloat16 for VAE on standard CUDA (non-ROCm) devices.\"\"\"\n        host = _VaeHost(project_root=\"K:/fake_root\", device=\"cuda\")\n        host.dtype = torch.float32\n        with patch.object(MEMORY_UTILS_MODULE, \"is_rocm_available\", return_value=False), \\\n                patch.object(MEMORY_UTILS_MODULE, \"cuda_supports_bfloat16\", return_value=True):\n            result = host._get_vae_dtype(\"cuda\")\n        self.assertEqual(result, torch.bfloat16)\n\n    def test_get_vae_dtype_returns_float16_on_pre_ampere_cuda(self):\n        \"\"\"It returns float16 for VAE on pre-Ampere CUDA devices.\"\"\"\n        host = _VaeHost(project_root=\"K:/fake_root\", device=\"cuda\")\n        host.dtype = torch.float32\n        with patch.object(MEMORY_UTILS_MODULE, \"is_rocm_available\", return_value=False), \\\n                patch.object(MEMORY_UTILS_MODULE, \"cuda_supports_bfloat16\", return_value=False):\n            result = host._get_vae_dtype(\"cuda\")\n        self.assertEqual(result, torch.float16)\n\n    def test_get_vae_dtype_treats_cuda_index_device_as_cuda(self):\n        \"\"\"It treats device strings like ``cuda:1`` as CUDA for VAE dtype selection.\"\"\"\n        host = _VaeHost(project_root=\"K:/fake_root\", device=\"cuda:1\")\n        host.dtype = torch.float32\n        with patch.object(MEMORY_UTILS_MODULE, \"is_rocm_available\", return_value=False), \\\n                patch.object(MEMORY_UTILS_MODULE, \"cuda_supports_bfloat16\", return_value=True) as bf16_mock:\n            result = host._get_vae_dtype(\"cuda:1\")\n        self.assertEqual(result, torch.bfloat16)\n        bf16_mock.assert_called_once_with(1)\n\n    def test_load_text_encoder_uses_cpu_safe_dtype_when_offloaded(self):\n        \"\"\"It casts the text encoder to the CPU-safe dtype during CPU offload.\"\"\"\n        host = _Host(project_root=\"K:/fake_root\", device=\"cuda\")\n        host.offload_to_cpu = True\n        host.dtype = torch.bfloat16\n\n        class _FakeEncoder:\n            def __init__(self):\n                self.to_calls = []\n                self.eval_called = False\n\n            def to(self, value):\n                self.to_calls.append(value)\n                return self\n\n            def eval(self):\n                self.eval_called = True\n                return self\n\n        fake_encoder = _FakeEncoder()\n        fake_tokenizer = object()\n        fake_transformers = types.SimpleNamespace(\n            AutoModel=types.SimpleNamespace(from_pretrained=Mock(return_value=fake_encoder)),\n            AutoTokenizer=types.SimpleNamespace(from_pretrained=Mock(return_value=fake_tokenizer)),\n        )\n\n        with patch(\"os.path.exists\", return_value=True):\n            with patch.dict(\"sys.modules\", {\"transformers\": fake_transformers}):\n                result = host._load_text_encoder_and_tokenizer(\n                    checkpoint_dir=\"K:/fake_root/checkpoints/acestep-v15-turbo\",\n                    device=\"cuda\",\n                )\n\n        self.assertEqual(\n            result,\n            os.path.join(\"K:/fake_root/checkpoints/acestep-v15-turbo\", \"Qwen3-Embedding-0.6B\"),\n        )\n        self.assertIs(host.text_encoder, fake_encoder)\n        self.assertIs(host.text_tokenizer, fake_tokenizer)\n        self.assertEqual(fake_encoder.to_calls, [\"cpu\", torch.float32])\n        self.assertTrue(fake_encoder.eval_called)\n\nif __name__ == \"__main__\":\n    unittest.main()\n"
  },
  {
    "path": "acestep/core/generation/handler/io_audio.py",
    "content": "\"\"\"Audio IO and normalization helpers for handler decomposition.\"\"\"\n\nimport math\nimport random\nfrom typing import Optional\nfrom pathlib import Path\n\nimport torch\nimport soundfile as sf\nfrom loguru import logger\n\n\nclass IoAudioMixin:\n    \"\"\"Mixin containing audio file loading and normalization helpers.\n\n    Depends on host members:\n    - Method: ``is_silence`` (provided by ``MemoryUtilsMixin`` in this decomposition).\n    \"\"\"\n\n    def _normalize_audio_to_stereo_48k(\n        self, audio: torch.Tensor, sr: int\n    ) -> torch.Tensor:\n        \"\"\"Normalize audio tensor to stereo at 48kHz.\n\n        Args:\n            audio: Tensor in [channels, samples] or [samples] format.\n            sr: Source sample rate.\n\n        Returns:\n            Tensor in [2, samples] at 48kHz, clamped to [-1.0, 1.0].\n        \"\"\"\n        if audio.shape[0] == 1:\n            audio = torch.cat([audio, audio], dim=0)\n\n        audio = audio[:2]\n\n        if sr != 48000:\n            import torchaudio\n\n            audio = torchaudio.transforms.Resample(sr, 48000)(audio)\n\n        return torch.clamp(audio, -1.0, 1.0)\n\n    def process_target_audio(self, audio_file: Optional[str]) -> Optional[torch.Tensor]:\n        \"\"\"Load and normalize target audio file.\n\n        Args:\n            audio_file: Path to target audio file.\n\n        Returns:\n            Normalized stereo 48kHz tensor, or ``None`` on error/empty input.\n        \"\"\"\n        if audio_file is None:\n            return None\n\n        try:\n            import soundfile as sf\n\n            audio_np, sr = sf.read(audio_file, dtype=\"float32\")\n            if audio_np.ndim == 1:\n                audio = torch.from_numpy(audio_np).unsqueeze(0)\n            else:\n                audio = torch.from_numpy(audio_np.T)\n            return self._normalize_audio_to_stereo_48k(audio, sr)\n        except (OSError, RuntimeError, ValueError):\n            logger.exception(\"[process_target_audio] Error processing target audio\")\n            return None\n\n    def process_reference_audio(\n        self, audio_file: Optional[str]\n    ) -> Optional[torch.Tensor]:\n        \"\"\"Load and normalize reference audio, then sample 3x10s segments.\n\n        Args:\n            audio_file: Path to reference audio file.\n\n        Returns:\n            30-second stereo tensor from sampled front/middle/back segments,\n            or ``None`` for empty/silent/error cases.\n        \"\"\"\n        if audio_file is None:\n            return None\n\n        try:\n            # Use soundfile instead of torchaudio to avoid torchcodec dependency\n            audio_np, sr = sf.read(audio_file, dtype=\"float32\")\n            if audio_np.ndim == 1:\n                audio = torch.from_numpy(audio_np).unsqueeze(0)\n            else:\n                audio = torch.from_numpy(audio_np.T)\n\n            logger.debug(\n                f\"[process_reference_audio] Reference audio shape: {audio.shape}\"\n            )\n            logger.debug(f\"[process_reference_audio] Reference audio sample rate: {sr}\")\n            logger.debug(\n                f\"[process_reference_audio] Reference audio duration: {audio.shape[-1] / sr:.6f} seconds\"\n            )\n\n            audio = self._normalize_audio_to_stereo_48k(audio, sr)\n            if self.is_silence(audio):\n                return None\n\n            target_frames = 30 * 48000\n            segment_frames = 10 * 48000\n\n            if audio.shape[-1] < target_frames:\n                repeat_times = math.ceil(target_frames / audio.shape[-1])\n                audio = audio.repeat(1, repeat_times)\n\n            total_frames = audio.shape[-1]\n            segment_size = total_frames // 3\n\n            front_start = random.randint(0, max(0, segment_size - segment_frames))\n            front_audio = audio[:, front_start : front_start + segment_frames]\n\n            middle_start = segment_size + random.randint(\n                0, max(0, segment_size - segment_frames)\n            )\n            middle_audio = audio[:, middle_start : middle_start + segment_frames]\n\n            back_start = 2 * segment_size + random.randint(\n                0, max(0, (total_frames - 2 * segment_size) - segment_frames)\n            )\n            back_audio = audio[:, back_start : back_start + segment_frames]\n\n            return torch.cat([front_audio, middle_audio, back_audio], dim=-1)\n        except (OSError, RuntimeError, ValueError) as exc:\n            logger.warning(\n                f\"[process_reference_audio] Invalid or unsupported reference audio: {exc}\"\n            )\n            return None\n\n    def process_src_audio(self, audio_file: Optional[str]) -> Optional[torch.Tensor]:\n        \"\"\"Load and normalize source audio for remix/extract flows.\n\n        Args:\n            audio_file: Path to source audio file.\n\n        Returns:\n            Normalized stereo 48kHz tensor, or ``None`` on error/empty input.\n        \"\"\"\n        if audio_file is None:\n            return None\n\n        try:\n            # Use soundfile instead of torchaudio to avoid torchcodec dependency\n            audio_np, sr = sf.read(audio_file, dtype=\"float32\")\n            if audio_np.ndim == 1:\n                audio = torch.from_numpy(audio_np).unsqueeze(0)\n            else:\n                audio = torch.from_numpy(audio_np.T)\n            return self._normalize_audio_to_stereo_48k(audio, sr)\n        except (OSError, RuntimeError, ValueError):\n            logger.exception(\"[process_src_audio] Error processing source audio\")\n            return None\n"
  },
  {
    "path": "acestep/core/generation/handler/io_audio_test.py",
    "content": "\"\"\"Unit tests for audio IO mixin extraction.\"\"\"\n\nimport sys\nimport types\nimport unittest\nfrom unittest.mock import patch\n\nimport numpy as np\nimport torch\n\nfrom acestep.core.generation.handler.io_audio import IoAudioMixin\n\n\nclass _Host(IoAudioMixin):\n    \"\"\"Minimal host implementing methods used by ``IoAudioMixin``.\"\"\"\n\n    def is_silence(self, audio: torch.Tensor) -> bool:\n        \"\"\"Treat near-zero tensors as silence.\"\"\"\n        return torch.all(audio.abs() < 1e-6).item()\n\n\ndef _fake_torchaudio_module(load_fn):\n    \"\"\"Create fake ``torchaudio`` module with minimal API used by tests.\"\"\"\n    module = types.ModuleType(\"torchaudio\")\n    module.load = load_fn\n    module.transforms = types.SimpleNamespace(Resample=lambda *_args, **_kwargs: (lambda x: x))\n    return module\n\n\nclass IoAudioMixinTests(unittest.TestCase):\n    \"\"\"Tests for normalization and audio loading helpers.\"\"\"\n\n    def test_normalize_audio_to_stereo_48k_duplicates_mono_and_clamps(self):\n        \"\"\"Mono input should duplicate to stereo and clamp values.\"\"\"\n        host = _Host()\n        audio = torch.tensor([[2.0, -2.0, 0.5]], dtype=torch.float32)\n        result = host._normalize_audio_to_stereo_48k(audio, 48000)\n\n        self.assertEqual(tuple(result.shape), (2, 3))\n        self.assertTrue(torch.all(result <= 1.0))\n        self.assertTrue(torch.all(result >= -1.0))\n\n    def test_process_target_audio_loads_and_normalizes(self):\n        \"\"\"Target audio should be loaded and normalized through helper.\"\"\"\n        host = _Host()\n        fake_np = np.array([0.1, -0.1, 0.2], dtype=np.float32)\n        fake_sf = types.ModuleType(\"soundfile\")\n        fake_sf.read = lambda *_args, **_kwargs: (fake_np, 32000)\n\n        with patch.dict(sys.modules, {\"soundfile\": fake_sf}):\n            with patch.object(host, \"_normalize_audio_to_stereo_48k\", return_value=torch.zeros(2, 3)) as norm:\n                result = host.process_target_audio(\"fake.wav\")\n\n        self.assertIsNotNone(result)\n        norm.assert_called_once()\n\n    def test_process_src_audio_handles_load_error(self):\n        \"\"\"Source audio processing should return None on load failure.\"\"\"\n        host = _Host()\n        fake_ta = _fake_torchaudio_module(lambda *_args, **_kwargs: (_ for _ in ()).throw(RuntimeError(\"bad\")))\n        with patch.dict(sys.modules, {\"torchaudio\": fake_ta}):\n            result = host.process_src_audio(\"bad.wav\")\n        self.assertIsNone(result)\n\n    def test_process_reference_audio_returns_none_for_silence(self):\n        \"\"\"Reference audio should short-circuit for silent input.\"\"\"\n        host = _Host()\n        silent = torch.zeros(2, 16, dtype=torch.float32)\n        fake_ta = _fake_torchaudio_module(lambda *_args, **_kwargs: (silent, 48000))\n        with patch.dict(sys.modules, {\"torchaudio\": fake_ta}):\n            result = host.process_reference_audio(\"silent.wav\")\n        self.assertIsNone(result)\n\n    def test_process_reference_audio_samples_expected_segments(self):\n        \"\"\"Reference audio should concatenate front/middle/back 10s sampled windows.\"\"\"\n        host = _Host()\n        base = torch.linspace(-1.0, 1.0, 1_800_000, dtype=torch.float32)\n        audio = torch.stack([base, -base], dim=0)\n        fake_ta = _fake_torchaudio_module(lambda *_args, **_kwargs: (audio, 48000))\n\n        with patch.dict(sys.modules, {\"torchaudio\": fake_ta}):\n            with patch(\"acestep.core.generation.handler.io_audio.random.randint\", side_effect=[10, 20, 30]):\n                result = host.process_reference_audio(\"ref.wav\")\n\n        self.assertIsNotNone(result)\n        segment_frames = 10 * 48000\n        expected = torch.cat(\n            [\n                audio[:, 10 : 10 + segment_frames],\n                audio[:, 600_000 + 20 : 600_000 + 20 + segment_frames],\n                audio[:, 1_200_000 + 30 : 1_200_000 + 30 + segment_frames],\n            ],\n            dim=-1,\n        )\n        self.assertTrue(torch.equal(result, expected))\n\n    def test_process_reference_audio_returns_none_on_load_error(self):\n        \"\"\"Reference audio processing should return None when loading fails.\"\"\"\n        host = _Host()\n        fake_ta = _fake_torchaudio_module(lambda *_args, **_kwargs: (_ for _ in ()).throw(RuntimeError(\"bad\")))\n        with patch.dict(sys.modules, {\"torchaudio\": fake_ta}):\n            result = host.process_reference_audio(\"bad.wav\")\n        self.assertIsNone(result)\n\n\nif __name__ == \"__main__\":\n    unittest.main()\n"
  },
  {
    "path": "acestep/core/generation/handler/lora/__init__.py",
    "content": "\"\"\"LoRA management implementation modules.\"\"\"\n"
  },
  {
    "path": "acestep/core/generation/handler/lora/adapter_discovery.py",
    "content": "\"\"\"Handler wrapper for adapter discovery.\"\"\"\n\n\ndef collect_adapter_names(self) -> list[str]:\n    \"\"\"Best-effort adapter name discovery across PEFT runtime variants.\"\"\"\n    self._ensure_lora_registry()\n    return self._lora_service.discover_adapter_names()\n"
  },
  {
    "path": "acestep/core/generation/handler/lora/controls.py",
    "content": "\"\"\"Runtime controls for LoRA enablement, scaling, and adapter selection.\"\"\"\n\nimport math\nfrom typing import Any\n\nfrom loguru import logger\n\nfrom acestep.constants import DEBUG_MODEL_LOADING\nfrom acestep.debug_utils import debug_log\n\n\ndef _toggle_lokr(decoder, enable: bool, scale: float = 1.0) -> bool:\n    \"\"\"Toggle a LyCORIS LoKr adapter via its multiplier.\n\n    Args:\n        decoder: Model decoder that may carry a ``_lycoris_net`` attribute.\n        enable: ``True`` to activate (restore multiplier), ``False`` to zero it.\n        scale: Multiplier value when enabling (default 1.0).\n\n    Returns:\n        ``True`` if a LyCORIS net was found and toggled, ``False`` otherwise.\n    \"\"\"\n    lycoris_net = getattr(decoder, \"_lycoris_net\", None)\n    if lycoris_net is None:\n        return False\n    set_mul = getattr(lycoris_net, \"set_multiplier\", None)\n    if not callable(set_mul):\n        return False\n    target = float(scale) if enable else 0.0\n    set_mul(target)\n    logger.info(f\"LoKr multiplier set to {target}\")\n    return True\n\n\ndef set_use_lora(self, use_lora: bool) -> str:\n    \"\"\"Toggle LoRA/LoKr usage for inference.\"\"\"\n    if use_lora and not self.lora_loaded:\n        return \"❌ No LoRA adapter loaded. Please load a LoRA first.\"\n\n    self.use_lora = use_lora\n    model = getattr(self, \"model\", None)\n    decoder = getattr(model, \"decoder\", None) if model is not None else None\n    if self.lora_loaded and decoder is None:\n        logger.warning(\"LoRA is marked as loaded, but model/decoder is unavailable during toggle.\")\n\n    if self.lora_loaded and decoder is not None:\n        adapter_type = getattr(self, \"_adapter_type\", None)\n\n        # LoKr (LyCORIS) path: toggle via set_multiplier\n        if adapter_type == \"lokr\":\n            active = getattr(self, \"_lora_active_adapter\", None)\n            scale = getattr(self, \"_active_loras\", {}).get(active, 1.0) if active else self.lora_scale\n            toggled = _toggle_lokr(decoder, use_lora, scale=scale)\n            if not toggled:\n                logger.warning(\"LoKr adapter type set but no _lycoris_net found on decoder\")\n\n        # PEFT LoRA path: toggle via enable/disable adapter layers\n        elif hasattr(decoder, \"disable_adapter_layers\"):\n            try:\n                if use_lora:\n                    active = getattr(self, \"_lora_active_adapter\", None)\n                    if active and hasattr(decoder, \"set_adapter\"):\n                        try:\n                            decoder.set_adapter(active)\n                        except Exception:\n                            pass\n                    decoder.enable_adapter_layers()\n                    logger.info(\"LoRA adapter enabled\")\n                    scale = getattr(self, \"_active_loras\", {}).get(active, 1.0)\n                    if active and scale != 1.0:\n                        self.set_lora_scale(active, scale)\n                else:\n                    decoder.disable_adapter_layers()\n                    logger.info(\"LoRA adapter disabled\")\n            except Exception as e:\n                logger.warning(f\"Could not toggle adapter layers: {e}\")\n\n    adapter_label = \"LoKr\" if getattr(self, \"_adapter_type\", None) == \"lokr\" else \"LoRA\"\n    status = \"enabled\" if use_lora else \"disabled\"\n    return f\"✅ {adapter_label} {status}\"\n\n\ndef set_lora_scale(self, adapter_name_or_scale: str | float, scale: float | None = None) -> str:\n    \"\"\"Set LoRA scale (0–1). Call as set_lora_scale(scale) or set_lora_scale(adapter_name, scale).\"\"\"\n    if not self.lora_loaded:\n        return \"⚠️ No LoRA loaded\"\n\n    if scale is None:\n        # Single-arg: first arg is scale, use active adapter\n        scale_value = adapter_name_or_scale\n        effective_name = None\n    else:\n        effective_name = adapter_name_or_scale if isinstance(adapter_name_or_scale, str) else None\n        scale_value = scale\n\n    try:\n        scale_value = float(scale_value)\n    except (TypeError, ValueError):\n        return \"❌ Invalid LoRA scale: please provide a numeric value between 0 and 1.\"\n    if not math.isfinite(scale_value):\n        return \"❌ Invalid LoRA scale: please provide a finite numeric value between 0 and 1.\"\n\n    scale_value = max(0.0, min(1.0, scale_value))\n    _active_loras = getattr(self, \"_active_loras\", None) or {}\n    if not effective_name:\n        effective_name = getattr(self, \"_lora_active_adapter\", None) or (\n            next(iter(_active_loras), None) if _active_loras else None\n        )\n    if not effective_name:\n        return \"❌ No adapter specified and no active adapter. Load a LoRA or pass adapter_name.\"\n\n    self._active_loras[effective_name] = scale_value\n    self.lora_scale = scale_value  # backward compat: single \"current\" scale for status/UI\n\n    adapter_label = \"LoKr\" if getattr(self, \"_adapter_type\", None) == \"lokr\" else \"LoRA\"\n\n    if not self.use_lora:\n        logger.info(f\"{adapter_label} scale for '{effective_name}' set to {scale_value:.2f} (will apply when enabled)\")\n        return f\"✅ {adapter_label} scale ({effective_name}): {scale_value:.2f} ({adapter_label} disabled)\"\n\n    # LoKr (LyCORIS) path: apply scale via set_multiplier\n    if getattr(self, \"_adapter_type\", None) == \"lokr\":\n        decoder = getattr(getattr(self, \"model\", None), \"decoder\", None)\n        if decoder is not None:\n            toggled = _toggle_lokr(decoder, True, scale=scale_value)\n            if toggled:\n                return f\"✅ {adapter_label} scale ({effective_name}): {scale_value:.2f}\"\n            logger.warning(\"LoKr adapter type set but no _lycoris_net found for scale\")\n        return f\"⚠️ {adapter_label} scale set to {scale_value:.2f} (no LyCORIS net found)\"\n\n    # PEFT LoRA path: apply scale via registry\n    try:\n        rebuilt_adapters: list[str] | None = None\n        if not getattr(self, \"_lora_adapter_registry\", None):\n            _, rebuilt_adapters = self._rebuild_lora_registry()\n\n        if rebuilt_adapters is not None:\n            if effective_name not in (rebuilt_adapters or []):\n                return f\"❌ Adapter '{effective_name}' not in loaded adapters: {rebuilt_adapters}\"\n            active_adapter = self._lora_service.active_adapter or effective_name\n            if active_adapter != effective_name:\n                self._lora_service.set_active_adapter(effective_name)\n                self._lora_active_adapter = effective_name\n                if getattr(self.model, \"decoder\", None) and hasattr(self.model.decoder, \"set_adapter\"):\n                    try:\n                        self.model.decoder.set_adapter(effective_name)\n                    except Exception:\n                        pass\n        else:\n            active_adapter = self._lora_service.ensure_active_adapter()\n            self._lora_active_adapter = active_adapter\n        self._sync_lora_state_from_service()\n        adapter_names = list(self._lora_service.registry.keys())\n\n        debug_log(\n            lambda: (\n                f\"LoRA scale request: adapter={effective_name} scale={scale_value:.3f} \"\n                f\"adapters={adapter_names}\"\n            ),\n            mode=DEBUG_MODEL_LOADING,\n            prefix=\"lora\",\n        )\n\n        modified = self._apply_scale_to_adapter(effective_name, scale_value)\n        report = getattr(self, \"_lora_last_scale_report\", {})\n        skipped_total = sum(report.get(\"skipped_by_kind\", {}).values())\n\n        if modified > 0:\n            logger.info(\n                f\"LoRA scale for '{effective_name}' set to {scale_value:.2f} \"\n                f\"(modified={modified}, by_kind={report.get('modified_by_kind', {})}, skipped={report.get('skipped_by_kind', {})})\"\n            )\n            return (\n                f\"✅ LoRA scale ({effective_name}): {scale_value:.2f}\"\n                if skipped_total == 0\n                else f\"✅ LoRA scale ({effective_name}): {scale_value:.2f} (skipped {skipped_total} targets)\"\n            )\n\n        if skipped_total > 0:\n            logger.warning(\n                f\"No LoRA targets were modified for adapter '{effective_name}' \"\n                f\"(skipped={report.get('skipped_by_kind', {})})\"\n            )\n            return f\"⚠️ LoRA scale unchanged: {scale_value:.2f} (skipped {skipped_total} targets)\"\n\n        logger.warning(f\"No registered LoRA scaling targets found for adapter '{effective_name}'\")\n        return f\"⚠️ Scale set to {scale_value:.2f} (no modules found)\"\n    except Exception as e:\n        logger.warning(f\"Could not set LoRA scale: {e}\")\n        return f\"⚠️ Scale set to {scale_value:.2f} (partial)\"\n\n\ndef set_active_lora_adapter(self, adapter_name: str) -> str:\n    \"\"\"Set the active LoRA adapter for scaling/inference.\"\"\"\n    self._ensure_lora_registry()\n    if not self._lora_service.set_active_adapter(adapter_name):\n        return f\"❌ Unknown adapter: {adapter_name}\"\n    self._lora_active_adapter = self._lora_service.active_adapter\n    debug_log(f\"Selected active LoRA adapter: {adapter_name}\", mode=DEBUG_MODEL_LOADING, prefix=\"lora\")\n    if self.model is not None and hasattr(self.model, \"decoder\") and hasattr(self.model.decoder, \"set_adapter\"):\n        try:\n            self.model.decoder.set_adapter(adapter_name)\n        except Exception:\n            pass\n    return f\"✅ Active LoRA adapter: {adapter_name}\"\n\n\ndef get_lora_status(self) -> dict[str, Any]:\n    \"\"\"Get current LoRA status.\"\"\"\n    self._ensure_lora_registry()\n    _active_loras = getattr(self, \"_active_loras\", None) or {}\n    return {\n        \"loaded\": self.lora_loaded,\n        \"active\": self.use_lora,\n        \"scale\": self.lora_scale,\n        \"scales\": dict(_active_loras),\n        \"active_adapter\": self._lora_active_adapter,\n        \"adapters\": list(self._lora_service.registry.keys()),\n        \"synthetic_default_mode\": self._lora_service.synthetic_default_mode,\n    }\n"
  },
  {
    "path": "acestep/core/generation/handler/lora/controls_test.py",
    "content": "\"\"\"Tests for LoRA/LoKr runtime controls (toggle, scale).\"\"\"\n\nimport unittest\nfrom types import SimpleNamespace\nfrom unittest.mock import Mock\n\nfrom acestep.core.generation.handler.lora.controls import (\n    _toggle_lokr,\n    set_lora_scale,\n    set_use_lora,\n)\n\n\nclass _DummyHandler:\n    \"\"\"Handler stub exposing the attributes used by ``set_use_lora`` / ``set_lora_scale``.\"\"\"\n\n    def __init__(self, adapter_type=None) -> None:\n        self.model = SimpleNamespace(decoder=SimpleNamespace())\n        self.lora_loaded = True\n        self.use_lora = True\n        self.lora_scale = 1.0\n        self._adapter_type = adapter_type\n        self._lora_active_adapter = \"default\"\n        self._active_loras = {\"default\": 1.0}\n        self._lora_service = SimpleNamespace(\n            registry={\"default\": {}},\n            scale_state={},\n            active_adapter=\"default\",\n            last_scale_report={},\n            synthetic_default_mode=False,\n        )\n\n    def _ensure_lora_registry(self):\n        return None\n\n    def _rebuild_lora_registry(self, lora_path=None):\n        return 0, list(self._active_loras.keys())\n\n    def _sync_lora_state_from_service(self):\n        return None\n\n    def _apply_scale_to_adapter(self, name, scale):\n        return 1\n\n    def set_lora_scale(self, adapter_name_or_scale, scale=None):\n        return set_lora_scale(self, adapter_name_or_scale, scale)\n\n\nclass ToggleLokrTests(unittest.TestCase):\n    \"\"\"Unit tests for the ``_toggle_lokr`` helper.\"\"\"\n\n    def test_disable_sets_multiplier_to_zero(self):\n        \"\"\"Disabling should call set_multiplier(0.0).\"\"\"\n        lycoris_net = SimpleNamespace(set_multiplier=Mock())\n        decoder = SimpleNamespace(_lycoris_net=lycoris_net)\n        result = _toggle_lokr(decoder, enable=False)\n        self.assertTrue(result)\n        lycoris_net.set_multiplier.assert_called_once_with(0.0)\n\n    def test_enable_sets_multiplier_to_scale(self):\n        \"\"\"Enabling should call set_multiplier with the given scale.\"\"\"\n        lycoris_net = SimpleNamespace(set_multiplier=Mock())\n        decoder = SimpleNamespace(_lycoris_net=lycoris_net)\n        result = _toggle_lokr(decoder, enable=True, scale=0.75)\n        self.assertTrue(result)\n        lycoris_net.set_multiplier.assert_called_once_with(0.75)\n\n    def test_returns_false_when_no_lycoris_net(self):\n        \"\"\"Should return False when decoder has no _lycoris_net.\"\"\"\n        decoder = SimpleNamespace()\n        result = _toggle_lokr(decoder, enable=False)\n        self.assertFalse(result)\n\n    def test_returns_false_when_no_set_multiplier(self):\n        \"\"\"Should return False when _lycoris_net lacks set_multiplier.\"\"\"\n        decoder = SimpleNamespace(_lycoris_net=SimpleNamespace())\n        result = _toggle_lokr(decoder, enable=True)\n        self.assertFalse(result)\n\n\nclass SetUseLokrTests(unittest.TestCase):\n    \"\"\"Tests for set_use_lora with LoKr adapter type.\"\"\"\n\n    def test_disable_lokr_zeros_multiplier(self):\n        \"\"\"Unchecking use_lora should set LoKr multiplier to 0.\"\"\"\n        handler = _DummyHandler(adapter_type=\"lokr\")\n        lycoris_net = SimpleNamespace(set_multiplier=Mock())\n        handler.model.decoder._lycoris_net = lycoris_net\n\n        result = set_use_lora(handler, False)\n\n        self.assertFalse(handler.use_lora)\n        lycoris_net.set_multiplier.assert_called_once_with(0.0)\n        self.assertIn(\"LoKr\", result)\n        self.assertIn(\"disabled\", result)\n\n    def test_enable_lokr_restores_multiplier(self):\n        \"\"\"Re-checking use_lora should restore LoKr multiplier to saved scale.\"\"\"\n        handler = _DummyHandler(adapter_type=\"lokr\")\n        handler.use_lora = False\n        handler._active_loras = {\"default\": 0.8}\n        lycoris_net = SimpleNamespace(set_multiplier=Mock())\n        handler.model.decoder._lycoris_net = lycoris_net\n\n        result = set_use_lora(handler, True)\n\n        self.assertTrue(handler.use_lora)\n        lycoris_net.set_multiplier.assert_called_once_with(0.8)\n        self.assertIn(\"LoKr\", result)\n        self.assertIn(\"enabled\", result)\n\n    def test_enable_lokr_uses_lora_scale_fallback(self):\n        \"\"\"When no active adapter, should fall back to self.lora_scale.\"\"\"\n        handler = _DummyHandler(adapter_type=\"lokr\")\n        handler.use_lora = False\n        handler._lora_active_adapter = None\n        handler.lora_scale = 0.5\n        lycoris_net = SimpleNamespace(set_multiplier=Mock())\n        handler.model.decoder._lycoris_net = lycoris_net\n\n        set_use_lora(handler, True)\n\n        lycoris_net.set_multiplier.assert_called_once_with(0.5)\n\n\nclass SetUsePeftLoraTests(unittest.TestCase):\n    \"\"\"Tests for set_use_lora with PEFT LoRA adapter type (non-regression).\"\"\"\n\n    def test_disable_peft_lora_calls_disable_adapter_layers(self):\n        \"\"\"Unchecking use_lora should call disable_adapter_layers for PEFT.\"\"\"\n        handler = _DummyHandler(adapter_type=\"lora\")\n        handler.model.decoder.disable_adapter_layers = Mock()\n\n        result = set_use_lora(handler, False)\n\n        self.assertFalse(handler.use_lora)\n        handler.model.decoder.disable_adapter_layers.assert_called_once()\n        self.assertIn(\"LoRA\", result)\n        self.assertIn(\"disabled\", result)\n\n    def test_enable_peft_lora_calls_enable_adapter_layers(self):\n        \"\"\"Re-checking use_lora should call enable_adapter_layers for PEFT.\"\"\"\n        handler = _DummyHandler(adapter_type=\"lora\")\n        handler.use_lora = False\n        handler.model.decoder.enable_adapter_layers = Mock()\n        handler.model.decoder.disable_adapter_layers = Mock()\n        handler.model.decoder.set_adapter = Mock()\n\n        result = set_use_lora(handler, True)\n\n        self.assertTrue(handler.use_lora)\n        handler.model.decoder.enable_adapter_layers.assert_called_once()\n        self.assertIn(\"LoRA\", result)\n        self.assertIn(\"enabled\", result)\n\n    def test_no_adapter_loaded_returns_error(self):\n        \"\"\"Enabling with no adapter loaded should return error.\"\"\"\n        handler = _DummyHandler()\n        handler.lora_loaded = False\n        handler.use_lora = False\n\n        result = set_use_lora(handler, True)\n        self.assertIn(\"❌\", result)\n\n\nclass SetLokrScaleTests(unittest.TestCase):\n    \"\"\"Tests for set_lora_scale with LoKr adapter type.\"\"\"\n\n    def test_scale_lokr_sets_multiplier(self):\n        \"\"\"Setting scale on LoKr should call set_multiplier with the value.\"\"\"\n        handler = _DummyHandler(adapter_type=\"lokr\")\n        lycoris_net = SimpleNamespace(set_multiplier=Mock())\n        handler.model.decoder._lycoris_net = lycoris_net\n\n        result = set_lora_scale(handler, 0.6)\n\n        lycoris_net.set_multiplier.assert_called_once_with(0.6)\n        self.assertIn(\"0.60\", result)\n        self.assertIn(\"LoKr\", result)\n        self.assertAlmostEqual(handler.lora_scale, 0.6)\n\n    def test_scale_lokr_when_disabled_stores_but_does_not_apply(self):\n        \"\"\"Scale change while disabled should store value but not call multiplier.\"\"\"\n        handler = _DummyHandler(adapter_type=\"lokr\")\n        handler.use_lora = False\n        lycoris_net = SimpleNamespace(set_multiplier=Mock())\n        handler.model.decoder._lycoris_net = lycoris_net\n\n        result = set_lora_scale(handler, 0.3)\n\n        lycoris_net.set_multiplier.assert_not_called()\n        self.assertIn(\"disabled\", result)\n        self.assertAlmostEqual(handler.lora_scale, 0.3)\n\n\nif __name__ == \"__main__\":\n    unittest.main()\n"
  },
  {
    "path": "acestep/core/generation/handler/lora/lifecycle.py",
    "content": "\"\"\"LoRA/LoKr adapter load/unload lifecycle management.\"\"\"\n\nimport json\nimport os\nfrom typing import Any\n\nfrom loguru import logger\n\nfrom acestep.constants import DEBUG_MODEL_LOADING\nfrom acestep.debug_utils import debug_log\nfrom acestep.training.configs import LoKRConfig\n\nLOKR_WEIGHTS_FILENAME = \"lokr_weights.safetensors\"\nREQUIRED_PEFT_CONFIG_KEYS = (\"peft_type\",)\n\n\ndef _is_lokr_safetensors(weights_path: str) -> bool:\n    \"\"\"Return whether ``weights_path`` looks like a LoKr/LyCORIS safetensors file.\"\"\"\n    if not os.path.isfile(weights_path) or not weights_path.lower().endswith(\".safetensors\"):\n        return False\n    if os.path.basename(weights_path) == LOKR_WEIGHTS_FILENAME:\n        return True\n\n    try:\n        from safetensors import safe_open\n    except ImportError:\n        return False\n\n    try:\n        with safe_open(weights_path, framework=\"pt\", device=\"cpu\") as sf:\n            metadata: dict[str, Any] = sf.metadata() or {}\n    except Exception:\n        return False\n\n    raw_config = metadata.get(\"lokr_config\")\n    return isinstance(raw_config, str) and bool(raw_config.strip())\n\n\ndef _resolve_lokr_weights_path(adapter_path: str) -> str | None:\n    \"\"\"Return LoKr safetensors path when ``adapter_path`` points to LoKr artifacts.\"\"\"\n    if os.path.isfile(adapter_path):\n        return adapter_path if _is_lokr_safetensors(adapter_path) else None\n    if os.path.isdir(adapter_path):\n        weights_path = os.path.join(adapter_path, LOKR_WEIGHTS_FILENAME)\n        if os.path.exists(weights_path):\n            return weights_path\n\n        # Backward-compat: support custom LyCORIS safetensors filenames that\n        # carry ``lokr_config`` metadata.\n        try:\n            entries = os.listdir(adapter_path)\n        except OSError:\n            return None\n        for name in entries:\n            candidate = os.path.join(adapter_path, name)\n            if _is_lokr_safetensors(candidate):\n                return candidate\n    return None\n\n\ndef _validate_peft_adapter_config(config_file: str) -> str | None:\n    \"\"\"Validate a PEFT ``adapter_config.json`` file and return an error message or ``None``.\n\n    Returns:\n        An error string describing the problem, or ``None`` when the config is valid.\n    \"\"\"\n    try:\n        with open(config_file, \"r\", encoding=\"utf-8\") as fh:\n            config = json.load(fh)\n    except (OSError, json.JSONDecodeError) as exc:\n        return f\"❌ Could not read adapter_config.json: {exc}\"\n\n    if not isinstance(config, dict):\n        return \"❌ adapter_config.json must be a JSON object.\"\n\n    for key in REQUIRED_PEFT_CONFIG_KEYS:\n        if key not in config:\n            return (\n                f\"❌ adapter_config.json is missing required field '{key}'. \"\n                \"The adapter may have been saved with an incompatible tool or a very old PEFT version. \"\n                \"Please re-export the adapter using a current PEFT release.\"\n            )\n\n    return None\n\n\ndef _load_lokr_config(weights_path: str) -> LoKRConfig:\n    \"\"\"Build ``LoKRConfig`` from safetensors metadata, with defaults on parse failure.\"\"\"\n    config = LoKRConfig()\n    try:\n        from safetensors import safe_open\n    except ImportError:\n        logger.warning(\"safetensors metadata reader unavailable; using default LoKr config.\")\n        return config\n\n    try:\n        with safe_open(weights_path, framework=\"pt\", device=\"cpu\") as sf:\n            metadata: dict[str, Any] = sf.metadata() or {}\n    except Exception as exc:\n        logger.warning(f\"Unable to read LoKr metadata from {weights_path}: {exc}\")\n        return config\n\n    raw_config = metadata.get(\"lokr_config\")\n    if not isinstance(raw_config, str) or not raw_config.strip():\n        return config\n\n    try:\n        parsed = json.loads(raw_config)\n    except json.JSONDecodeError as exc:\n        logger.warning(f\"Invalid LoKr metadata config JSON in {weights_path}: {exc}\")\n        return config\n\n    if not isinstance(parsed, dict):\n        return config\n\n    allowed_keys = set(LoKRConfig.__dataclass_fields__.keys())\n    filtered = {k: v for k, v in parsed.items() if k in allowed_keys}\n    if not filtered:\n        return config\n\n    try:\n        return LoKRConfig(**filtered)\n    except Exception as exc:\n        logger.warning(f\"Failed to apply LoKr metadata config from {weights_path}: {exc}\")\n        return config\n\n\ndef _load_lokr_adapter(decoder: Any, weights_path: str) -> Any:\n    \"\"\"Inject and load a LoKr LyCORIS adapter into ``decoder``.\"\"\"\n    try:\n        from lycoris import LycorisNetwork, create_lycoris\n    except ImportError as exc:\n        raise ImportError(\"LyCORIS library not installed. Please install with: pip install lycoris-lora\") from exc\n\n    lokr_config = _load_lokr_config(weights_path)\n    LycorisNetwork.apply_preset(\n        {\n            \"unet_target_name\": lokr_config.target_modules,\n            \"target_name\": lokr_config.target_modules,\n        }\n    )\n    lycoris_net = create_lycoris(\n        decoder,\n        1.0,\n        linear_dim=lokr_config.linear_dim,\n        linear_alpha=lokr_config.linear_alpha,\n        algo=\"lokr\",\n        factor=lokr_config.factor,\n        decompose_both=lokr_config.decompose_both,\n        use_tucker=lokr_config.use_tucker,\n        use_scalar=lokr_config.use_scalar,\n        full_matrix=lokr_config.full_matrix,\n        bypass_mode=lokr_config.bypass_mode,\n        rs_lora=lokr_config.rs_lora,\n        unbalanced_factorization=lokr_config.unbalanced_factorization,\n    )\n\n    if lokr_config.weight_decompose:\n        try:\n            lycoris_net = create_lycoris(\n                decoder,\n                1.0,\n                linear_dim=lokr_config.linear_dim,\n                linear_alpha=lokr_config.linear_alpha,\n                algo=\"lokr\",\n                factor=lokr_config.factor,\n                decompose_both=lokr_config.decompose_both,\n                use_tucker=lokr_config.use_tucker,\n                use_scalar=lokr_config.use_scalar,\n                full_matrix=lokr_config.full_matrix,\n                bypass_mode=lokr_config.bypass_mode,\n                rs_lora=lokr_config.rs_lora,\n                unbalanced_factorization=lokr_config.unbalanced_factorization,\n                dora_wd=True,\n            )\n        except Exception as exc:\n            logger.warning(f\"DoRA mode not supported in current LyCORIS build: {exc}\")\n\n    lycoris_net.apply_to()\n    decoder._lycoris_net = lycoris_net\n    lycoris_net.load_weights(weights_path)\n    return lycoris_net\n\n\ndef _default_adapter_name_from_path(lora_path: str) -> str:\n    \"\"\"Derive a default adapter name from path (e.g. 'final' from './lora/final').\"\"\"\n    name = os.path.basename(lora_path.rstrip(os.sep))\n    return name if name else \"default\"\n\n\ndef add_lora(self, lora_path: str, adapter_name: str | None = None) -> str:\n    \"\"\"Load a LoRA adapter into the decoder under the given name.\n\n    If the decoder is not yet a PeftModel, wraps it and loads the first adapter.\n    If it is already a PeftModel, loads an additional adapter (no base restore).\n    \"\"\"\n    if self.model is None:\n        return \"❌ Model not initialized. Please initialize service first.\"\n\n    if self.quantization is not None:\n        return (\n            \"❌ LoRA loading is not supported on quantized models. \"\n            f\"Current quantization: {self.quantization}. \"\n            \"Please re-initialize the service with quantization disabled, then try loading the LoRA adapter again.\"\n        )\n\n    if not lora_path or not lora_path.strip():\n        return \"❌ Please provide a LoRA path.\"\n\n    lora_path = lora_path.strip()\n    if not os.path.exists(lora_path):\n        return f\"❌ LoRA path not found: {lora_path}\"\n\n    lokr_weights_path = _resolve_lokr_weights_path(lora_path)\n    if lokr_weights_path is None:\n        config_file = os.path.join(lora_path, \"adapter_config.json\")\n        if not os.path.exists(config_file):\n            return (\n                \"❌ Invalid adapter: expected PEFT LoRA directory containing adapter_config.json \"\n                f\"or LoKr artifact {LOKR_WEIGHTS_FILENAME} in {lora_path}\"\n            )\n        config_error = _validate_peft_adapter_config(config_file)\n        if config_error is not None:\n            return config_error\n\n    try:\n        from peft import PeftModel\n    except ImportError:\n        if lokr_weights_path is None:\n            return \"❌ PEFT library not installed. Please install with: pip install peft\"\n        PeftModel = None  # type: ignore[assignment]\n\n    effective_name = adapter_name.strip() if isinstance(adapter_name, str) and adapter_name.strip() else _default_adapter_name_from_path(lora_path)\n    _active_loras = getattr(self, \"_active_loras\", None)\n    if _active_loras is None:\n        self._active_loras = {}\n        _active_loras = self._active_loras\n    if effective_name in _active_loras:\n        return f\"❌ Adapter name already in use: {effective_name}. Use a different name or remove it first.\"\n\n    try:\n        decoder = self.model.decoder\n        is_peft = PeftModel is not None and isinstance(decoder, PeftModel)\n\n        if not is_peft:\n            # First LoRA: backup base once, then wrap with PEFT\n            if self._base_decoder is None:\n                if hasattr(self, \"_memory_allocated\"):\n                    mem_before = self._memory_allocated() / (1024**3)\n                    logger.info(f\"VRAM before LoRA load: {mem_before:.2f}GB\")\n                try:\n                    state_dict = decoder.state_dict()\n                    if not state_dict:\n                        raise ValueError(\"state_dict is empty - cannot backup decoder\")\n                    self._base_decoder = {k: v.detach().cpu().clone() for k, v in state_dict.items()}\n                except Exception as e:\n                    logger.error(f\"Failed to create state_dict backup: {e}\")\n                    raise\n                backup_size_mb = sum(v.numel() * v.element_size() for v in self._base_decoder.values()) / (1024**2)\n                logger.info(f\"Base decoder state_dict backed up to CPU ({backup_size_mb:.1f}MB)\")\n\n            if lokr_weights_path is not None:\n                logger.info(f\"Loading LoKr adapter from {lokr_weights_path} as '{effective_name}'\")\n                _load_lokr_adapter(decoder, lokr_weights_path)\n                self.model.decoder = decoder\n                self._adapter_type = \"lokr\"\n            else:\n                logger.info(f\"Loading LoRA adapter from {lora_path} as '{effective_name}'\")\n                self.model.decoder = PeftModel.from_pretrained(\n                    decoder, lora_path, adapter_name=effective_name, is_trainable=False\n                )\n                self._adapter_type = \"lora\"\n        else:\n            # Already PEFT: load additional adapter (no base restore). LoKr not supported as second adapter.\n            if lokr_weights_path is not None:\n                return \"❌ LoKr cannot be added as a second adapter when PEFT is already loaded.\"\n            logger.info(f\"Loading additional LoRA from {lora_path} as '{effective_name}'\")\n            self.model.decoder.load_adapter(lora_path, adapter_name=effective_name)\n            self._adapter_type = \"lora\"\n\n        self.model.decoder = self.model.decoder.to(self.device).to(self.dtype)\n        self.model.decoder.eval()\n\n        if hasattr(self, \"_memory_allocated\"):\n            mem_after = self._memory_allocated() / (1024**3)\n            logger.info(f\"VRAM after LoRA load: {mem_after:.2f}GB\")\n\n        self.lora_loaded = True\n        self.use_lora = True\n        self._active_loras[effective_name] = 1.0\n        self._ensure_lora_registry()\n        self._lora_active_adapter = None\n        target_count, adapters = self._rebuild_lora_registry(lora_path=lora_path)\n        # Set the newly added adapter as active\n        if effective_name in (getattr(self._lora_service, \"registry\", {}) or {}):\n            self._lora_service.set_active_adapter(effective_name)\n            self._lora_active_adapter = effective_name\n        if hasattr(self.model.decoder, \"set_adapter\"):\n            try:\n                self.model.decoder.set_adapter(effective_name)\n            except Exception:\n                pass\n\n        logger.info(\n            f\"LoRA adapter '{effective_name}' loaded from {lora_path} \"\n            f\"(adapters={adapters}, targets={target_count})\"\n        )\n        debug_log(\n            lambda: f\"LoRA registry snapshot: {self._debug_lora_registry_snapshot()}\",\n            mode=DEBUG_MODEL_LOADING,\n            prefix=\"lora\",\n        )\n        return f\"✅ LoRA '{effective_name}' loaded from {lora_path}\"\n    except Exception as e:\n        logger.exception(\"Failed to load LoRA adapter\")\n        return f\"❌ Failed to load LoRA: {str(e)}\"\n\n\ndef load_lora(self, lora_path: str) -> str:\n    \"\"\"Load a single adapter (backward-compat), including LyCORIS LoKr paths.\"\"\"\n    lokr_weights_path = _resolve_lokr_weights_path(lora_path.strip()) if isinstance(lora_path, str) else None\n    message = self.add_lora(lora_path, adapter_name=None)\n    if lokr_weights_path is not None and message.startswith(\"✅\"):\n        return f\"✅ LoKr loaded from {lokr_weights_path}\"\n    return message\n\n\ndef add_voice_lora(self, lora_path: str, scale: float = 1.0) -> str:\n    \"\"\"Load a LoRA as the 'voice' adapter and set its scale. Same machinery as style LoRA.\"\"\"\n    msg = self.add_lora(lora_path, adapter_name=\"voice\")\n    if not msg.startswith(\"✅\"):\n        return msg\n    return self.set_lora_scale(\"voice\", scale)\n\n\ndef remove_lora(self, adapter_name: str) -> str:\n    \"\"\"Remove one LoRA adapter by name. If no adapters remain, restores base decoder.\"\"\"\n    if not self.lora_loaded:\n        return \"⚠️ No LoRA adapter loaded.\"\n\n    _active_loras = getattr(self, \"_active_loras\", None) or {}\n    if adapter_name not in _active_loras:\n        return f\"❌ Unknown adapter: {adapter_name}. Loaded: {list(_active_loras.keys())}\"\n\n    try:\n        from peft import PeftModel\n    except ImportError:\n        return \"❌ PEFT library not installed.\"\n\n    decoder = getattr(self.model, \"decoder\", None)\n    if decoder is None or not isinstance(decoder, PeftModel):\n        # Inconsistent state: clear our bookkeeping\n        _active_loras.pop(adapter_name, None)\n        if not _active_loras:\n            self.lora_loaded = False\n            self.use_lora = False\n            self._adapter_type = None\n        return \"⚠️ Adapter removed from registry (decoder was not PEFT).\"\n\n    if adapter_name not in (getattr(decoder, \"peft_config\", None) or {}):\n        _active_loras.pop(adapter_name, None)\n        self._ensure_lora_registry()\n        self._rebuild_lora_registry()\n        return f\"✅ Adapter '{adapter_name}' removed (was not in PEFT).\"\n\n    try:\n        decoder.delete_adapter(adapter_name)\n        _active_loras.pop(adapter_name, None)\n        remaining = list(_active_loras.keys())\n\n        if not remaining:\n            # No adapters left: restore base decoder\n            if self._base_decoder is None:\n                self.lora_loaded = False\n                self.use_lora = False\n                self._adapter_type = None\n                self._active_loras.clear()\n                self._ensure_lora_registry()\n                self._lora_service.registry = {}\n                self._lora_service.scale_state = {}\n                self._lora_service.active_adapter = None\n                self._lora_service.last_scale_report = {}\n                self._lora_adapter_registry = {}\n                self._lora_active_adapter = None\n                self._lora_scale_state = {}\n                return \"✅ Last adapter removed; base decoder still wrapped (no backup). Restart or load a new LoRA.\"\n            mem_before = None\n            if hasattr(self, \"_memory_allocated\"):\n                mem_before = self._memory_allocated() / (1024**3)\n                logger.info(f\"VRAM before LoRA unload: {mem_before:.2f}GB\")\n            self.model.decoder = decoder.get_base_model()\n            load_result = self.model.decoder.load_state_dict(self._base_decoder, strict=False)\n            if load_result.missing_keys:\n                logger.warning(f\"Missing keys when restoring decoder: {load_result.missing_keys[:5]}\")\n            if load_result.unexpected_keys:\n                logger.warning(f\"Unexpected keys when restoring decoder: {load_result.unexpected_keys[:5]}\")\n            self.model.decoder = self.model.decoder.to(self.device).to(self.dtype)\n            self.model.decoder.eval()\n            self.lora_loaded = False\n            self.use_lora = False\n            self._adapter_type = None\n            self._active_loras = {}\n            self._ensure_lora_registry()\n            self._lora_service.registry = {}\n            self._lora_service.scale_state = {}\n            self._lora_service.active_adapter = None\n            self._lora_service.last_scale_report = {}\n            self._lora_adapter_registry = {}\n            self._lora_active_adapter = None\n            self._lora_scale_state = {}\n            if mem_before is not None and hasattr(self, \"_memory_allocated\"):\n                mem_after = self._memory_allocated() / (1024**3)\n                logger.info(f\"VRAM after LoRA unload: {mem_after:.2f}GB (freed: {mem_before - mem_after:.2f}GB)\")\n            logger.info(\"LoRA unloaded, base decoder restored\")\n            return \"✅ LoRA unloaded, using base model\"\n        # Else: set another adapter active and rebuild registry\n        next_active = remaining[0]\n        if hasattr(decoder, \"set_adapter\"):\n            try:\n                decoder.set_adapter(next_active)\n            except Exception:\n                pass\n        self._lora_active_adapter = next_active\n        self._ensure_lora_registry()\n        self._rebuild_lora_registry()\n        self._lora_service.set_active_adapter(next_active)\n        # Re-apply scale for the now-active adapter\n        scale = self._active_loras.get(next_active, 1.0)\n        self._apply_scale_to_adapter(next_active, scale)\n        logger.info(f\"Adapter '{adapter_name}' removed. Active: {next_active}\")\n        return f\"✅ Adapter '{adapter_name}' removed. Active: {next_active}\"\n    except Exception as e:\n        logger.exception(\"Failed to remove LoRA adapter\")\n        return f\"❌ Failed to remove LoRA: {str(e)}\"\n\n\ndef unload_lora(self) -> str:\n    \"\"\"Unload all LoRA adapters and restore base decoder.\"\"\"\n    if not self.lora_loaded:\n        return \"⚠️ No LoRA adapter loaded.\"\n\n    if self._base_decoder is None:\n        return \"❌ Base decoder backup not found. Cannot restore.\"\n\n    try:\n        mem_before = None\n        if hasattr(self, \"_memory_allocated\"):\n            mem_before = self._memory_allocated() / (1024**3)\n            logger.info(f\"VRAM before LoRA unload: {mem_before:.2f}GB\")\n\n        # If this decoder has an attached LyCORIS net, restore original module graph first.\n        lycoris_net = getattr(self.model.decoder, \"_lycoris_net\", None)\n        if lycoris_net is not None:\n            restore_fn = getattr(lycoris_net, \"restore\", None)\n            if callable(restore_fn):\n                logger.info(\"Restoring decoder structure from LyCORIS adapter\")\n                restore_fn()\n            else:\n                logger.warning(\"Decoder has _lycoris_net but no restore() method; continuing with state_dict restore\")\n            self.model.decoder._lycoris_net = None\n\n        try:\n            from peft import PeftModel\n        except ImportError:\n            PeftModel = None  # type: ignore[assignment]\n\n        if PeftModel is not None and isinstance(self.model.decoder, PeftModel):\n            logger.info(\"Extracting base model from PEFT wrapper\")\n            self.model.decoder = self.model.decoder.get_base_model()\n            load_result = self.model.decoder.load_state_dict(self._base_decoder, strict=False)\n            if load_result.missing_keys:\n                logger.warning(f\"Missing keys when restoring decoder: {load_result.missing_keys[:5]}\")\n            if load_result.unexpected_keys:\n                logger.warning(f\"Unexpected keys when restoring decoder: {load_result.unexpected_keys[:5]}\")\n        else:\n            logger.info(\"Restoring base decoder from state_dict backup\")\n            load_result = self.model.decoder.load_state_dict(self._base_decoder, strict=False)\n            if load_result.missing_keys:\n                logger.warning(f\"Missing keys when restoring decoder: {load_result.missing_keys[:5]}\")\n            if load_result.unexpected_keys:\n                logger.warning(f\"Unexpected keys when restoring decoder: {load_result.unexpected_keys[:5]}\")\n\n        self.model.decoder = self.model.decoder.to(self.device).to(self.dtype)\n        self.model.decoder.eval()\n\n        self.lora_loaded = False\n        self.use_lora = False\n        self._adapter_type = None\n        self.lora_scale = 1.0\n        _active_loras = getattr(self, \"_active_loras\", None)\n        if _active_loras is not None:\n            _active_loras.clear()\n        self._ensure_lora_registry()\n        self._lora_service.registry = {}\n        self._lora_service.scale_state = {}\n        self._lora_service.active_adapter = None\n        self._lora_service.last_scale_report = {}\n        self._lora_adapter_registry = {}\n        self._lora_active_adapter = None\n        self._lora_scale_state = {}\n\n        if mem_before is not None and hasattr(self, \"_memory_allocated\"):\n            mem_after = self._memory_allocated() / (1024**3)\n            logger.info(f\"VRAM after LoRA unload: {mem_after:.2f}GB (freed: {mem_before - mem_after:.2f}GB)\")\n\n        logger.info(\"LoRA unloaded, base decoder restored\")\n        return \"✅ LoRA unloaded, using base model\"\n    except Exception as e:\n        logger.exception(\"Failed to unload LoRA\")\n        return f\"❌ Failed to unload LoRA: {str(e)}\"\n"
  },
  {
    "path": "acestep/core/generation/handler/lora/lifecycle_test.py",
    "content": "\"\"\"Tests for LoRA/LoKr lifecycle loading behavior.\"\"\"\n\nimport tempfile\nimport unittest\nfrom pathlib import Path\nfrom types import SimpleNamespace\nfrom unittest.mock import Mock, patch\n\nimport torch\n\nfrom acestep.core.generation.handler.lora import lifecycle\n\n\nclass _DummyDecoder:\n    \"\"\"Minimal decoder stub for lifecycle loader tests.\"\"\"\n\n    def __init__(self) -> None:\n        self._weights = {\"w\": torch.zeros(1)}\n\n    def state_dict(self):\n        \"\"\"Return a tiny state dict suitable for backup/restore paths.\"\"\"\n        return self._weights\n\n    def load_state_dict(self, state_dict, strict=False):\n        \"\"\"Pretend to restore weights and report no key mismatches.\"\"\"\n        self._weights = state_dict\n        return SimpleNamespace(missing_keys=[], unexpected_keys=[])\n\n    def to(self, *_args, **_kwargs):\n        \"\"\"Match torch module ``to`` chaining.\"\"\"\n        return self\n\n    def eval(self):\n        \"\"\"Match torch module ``eval`` API.\"\"\"\n        return self\n\n\nclass _DummyHandler:\n    \"\"\"Handler stub exposing the attributes used by ``load_lora``.\"\"\"\n\n    def __init__(self) -> None:\n        self.model = SimpleNamespace(decoder=_DummyDecoder())\n        self.device = \"cpu\"\n        self.dtype = torch.float32\n        self.quantization = None\n        self._base_decoder = None\n        self.lora_loaded = False\n        self.use_lora = False\n        self.lora_scale = 1.0\n        self._lora_active_adapter = None\n        self._lora_service = SimpleNamespace(\n            registry={},\n            scale_state={},\n            active_adapter=None,\n            last_scale_report={},\n        )\n\n    def _ensure_lora_registry(self):\n        \"\"\"Satisfy lifecycle hook without side effects.\"\"\"\n        return None\n\n    def _rebuild_lora_registry(self, lora_path=None):\n        \"\"\"Return deterministic empty registry output.\"\"\"\n        _ = lora_path\n        return 0, []\n\n    def _debug_lora_registry_snapshot(self):\n        \"\"\"Return simple debug payload.\"\"\"\n        return {}\n\n    def add_lora(self, lora_path, adapter_name=None):\n        \"\"\"Forward to lifecycle implementation to mimic mixin wiring.\"\"\"\n        return lifecycle.add_lora(self, lora_path, adapter_name=adapter_name)\n\n\nclass LifecycleTests(unittest.TestCase):\n    \"\"\"Coverage for LoKr path detection and load branching.\"\"\"\n\n    def test_resolve_lokr_weights_from_directory(self):\n        \"\"\"Directory containing ``lokr_weights.safetensors`` should resolve.\"\"\"\n        with tempfile.TemporaryDirectory() as tmp:\n            weights = Path(tmp) / lifecycle.LOKR_WEIGHTS_FILENAME\n            weights.write_bytes(b\"\")\n            resolved = lifecycle._resolve_lokr_weights_path(str(Path(tmp)))\n            self.assertEqual(resolved, str(weights))\n\n    def test_resolve_lokr_weights_from_file(self):\n        \"\"\"Direct ``lokr_weights.safetensors`` file should resolve.\"\"\"\n        with tempfile.TemporaryDirectory() as tmp:\n            weights = Path(tmp) / lifecycle.LOKR_WEIGHTS_FILENAME\n            weights.write_bytes(b\"\")\n            resolved = lifecycle._resolve_lokr_weights_path(str(weights))\n            self.assertEqual(resolved, str(weights))\n\n    def test_resolve_lokr_weights_from_custom_safetensors_name(self):\n        \"\"\"Directory should resolve custom LyCORIS safetensors filenames when metadata matches.\"\"\"\n        with tempfile.TemporaryDirectory() as tmp:\n            adapter_dir = Path(tmp)\n            custom = adapter_dir / \"custom_lycoris.safetensors\"\n            custom.write_bytes(b\"\")\n\n            with patch(\n                \"acestep.core.generation.handler.lora.lifecycle._is_lokr_safetensors\",\n                side_effect=lambda path: path == str(custom),\n            ):\n                resolved = lifecycle._resolve_lokr_weights_path(str(adapter_dir))\n\n        self.assertEqual(resolved, str(custom))\n\n    def test_load_lora_accepts_lokr_directory_without_adapter_config(self):\n        \"\"\"LoKr directory should bypass PEFT config-file requirement.\"\"\"\n        handler = _DummyHandler()\n        with tempfile.TemporaryDirectory() as tmp:\n            adapter_dir = Path(tmp) / \"adapter\"\n            adapter_dir.mkdir(parents=True, exist_ok=True)\n            weights = adapter_dir / lifecycle.LOKR_WEIGHTS_FILENAME\n            weights.write_bytes(b\"\")\n            with patch(\"acestep.core.generation.handler.lora.lifecycle._load_lokr_adapter\") as mock_load_lokr:\n                message = lifecycle.load_lora(handler, str(adapter_dir))\n\n        self.assertEqual(message, f\"✅ LoKr loaded from {weights}\")\n        mock_load_lokr.assert_called_once_with(handler.model.decoder, str(weights))\n\n    def test_load_lora_invalid_adapter_message_mentions_lokr(self):\n        \"\"\"Invalid adapter error should mention both LoRA and LoKr expectations.\"\"\"\n        handler = _DummyHandler()\n        with tempfile.TemporaryDirectory() as tmp:\n            message = lifecycle.load_lora(handler, tmp)\n        self.assertIn(\"adapter_config.json\", message)\n        self.assertIn(lifecycle.LOKR_WEIGHTS_FILENAME, message)\n\n    def test_validate_peft_adapter_config_missing_peft_type(self):\n        \"\"\"adapter_config.json without peft_type should return a clear error message.\"\"\"\n        with tempfile.TemporaryDirectory() as tmp:\n            config_file = Path(tmp) / \"adapter_config.json\"\n            config_file.write_text('{\"r\": 16, \"lora_alpha\": 32}', encoding=\"utf-8\")\n            error = lifecycle._validate_peft_adapter_config(str(config_file))\n        self.assertIsNotNone(error)\n        self.assertIn(\"peft_type\", error)\n        self.assertIn(\"adapter_config.json\", error)\n\n    def test_validate_peft_adapter_config_valid(self):\n        \"\"\"adapter_config.json with peft_type present should return None.\"\"\"\n        with tempfile.TemporaryDirectory() as tmp:\n            config_file = Path(tmp) / \"adapter_config.json\"\n            config_file.write_text('{\"peft_type\": \"LORA\", \"r\": 16}', encoding=\"utf-8\")\n            error = lifecycle._validate_peft_adapter_config(str(config_file))\n        self.assertIsNone(error)\n\n    def test_validate_peft_adapter_config_invalid_json(self):\n        \"\"\"Malformed adapter_config.json should return a parse-error message.\"\"\"\n        with tempfile.TemporaryDirectory() as tmp:\n            config_file = Path(tmp) / \"adapter_config.json\"\n            config_file.write_text(\"{not valid json}\", encoding=\"utf-8\")\n            error = lifecycle._validate_peft_adapter_config(str(config_file))\n        self.assertIsNotNone(error)\n        self.assertIn(\"adapter_config.json\", error)\n\n    def test_validate_peft_adapter_config_not_a_dict(self):\n        \"\"\"adapter_config.json that is a non-object JSON value should return an error.\"\"\"\n        with tempfile.TemporaryDirectory() as tmp:\n            config_file = Path(tmp) / \"adapter_config.json\"\n            config_file.write_text(\"[1, 2, 3]\", encoding=\"utf-8\")\n            error = lifecycle._validate_peft_adapter_config(str(config_file))\n        self.assertIsNotNone(error)\n\n    def test_add_lora_returns_clear_error_when_peft_type_missing(self):\n        \"\"\"add_lora should return a descriptive error when adapter_config.json lacks peft_type.\"\"\"\n        handler = _DummyHandler()\n        with tempfile.TemporaryDirectory() as tmp:\n            config_file = Path(tmp) / \"adapter_config.json\"\n            config_file.write_text('{\"r\": 16, \"lora_alpha\": 32}', encoding=\"utf-8\")\n            message = lifecycle.add_lora(handler, tmp)\n        self.assertTrue(message.startswith(\"❌\"))\n        self.assertIn(\"peft_type\", message)\n\n    def test_load_lokr_adapter_recreates_with_dora_when_weight_decompose_enabled(self):\n        \"\"\"Weight-decompose config should request a second LyCORIS net with DoRA enabled.\"\"\"\n        decoder = _DummyDecoder()\n        base_net = Mock()\n        dora_net = Mock()\n        create_lycoris = Mock(side_effect=[base_net, dora_net])\n        fake_lycoris = SimpleNamespace(\n            LycorisNetwork=SimpleNamespace(apply_preset=Mock()),\n            create_lycoris=create_lycoris,\n        )\n        config = lifecycle.LoKRConfig(weight_decompose=True)\n\n        with patch.dict(\"sys.modules\", {\"lycoris\": fake_lycoris}):\n            with patch(\"acestep.core.generation.handler.lora.lifecycle._load_lokr_config\", return_value=config):\n                result = lifecycle._load_lokr_adapter(decoder, \"weights.safetensors\")\n\n        self.assertIs(result, dora_net)\n        self.assertEqual(create_lycoris.call_count, 2)\n        self.assertNotIn(\"dora_wd\", create_lycoris.call_args_list[0].kwargs)\n        self.assertTrue(create_lycoris.call_args_list[1].kwargs[\"dora_wd\"])\n        dora_net.apply_to.assert_called_once_with()\n        dora_net.load_weights.assert_called_once_with(\"weights.safetensors\")\n        self.assertIs(decoder._lycoris_net, dora_net)\n\n    def test_load_lokr_adapter_uses_base_net_when_dora_not_supported(self):\n        \"\"\"DoRA create failures should warn and keep the initially created LyCORIS net.\"\"\"\n        decoder = _DummyDecoder()\n        base_net = Mock()\n        create_lycoris = Mock(side_effect=[base_net, RuntimeError(\"unsupported\")])\n        fake_lycoris = SimpleNamespace(\n            LycorisNetwork=SimpleNamespace(apply_preset=Mock()),\n            create_lycoris=create_lycoris,\n        )\n        config = lifecycle.LoKRConfig(weight_decompose=True)\n\n        with patch.dict(\"sys.modules\", {\"lycoris\": fake_lycoris}):\n            with patch(\"acestep.core.generation.handler.lora.lifecycle._load_lokr_config\", return_value=config):\n                with patch(\"acestep.core.generation.handler.lora.lifecycle.logger.warning\") as mock_warning:\n                    result = lifecycle._load_lokr_adapter(decoder, \"weights.safetensors\")\n\n        self.assertIs(result, base_net)\n        self.assertEqual(create_lycoris.call_count, 2)\n        mock_warning.assert_called_once()\n        base_net.apply_to.assert_called_once_with()\n        base_net.load_weights.assert_called_once_with(\"weights.safetensors\")\n        self.assertIs(decoder._lycoris_net, base_net)\n\n    def test_unload_lora_restores_lokr_adapter_before_state_restore(self):\n        \"\"\"Unload should call LyCORIS restore() and then restore decoder weights.\"\"\"\n        handler = _DummyHandler()\n        handler.lora_loaded = True\n        handler._base_decoder = {\"w\": torch.ones(1)}\n        events = []\n\n        lycoris_net = SimpleNamespace(restore=Mock(side_effect=lambda: events.append(\"restore\")))\n        handler.model.decoder._lycoris_net = lycoris_net\n        handler.model.decoder.load_state_dict = Mock(\n            side_effect=lambda *_args, **_kwargs: events.append(\"load_state_dict\") or SimpleNamespace(\n                missing_keys=[], unexpected_keys=[]\n            )\n        )\n\n        message = lifecycle.unload_lora(handler)\n\n        self.assertEqual(message, \"✅ LoRA unloaded, using base model\")\n        self.assertEqual(events, [\"restore\", \"load_state_dict\"])\n        self.assertIsNone(handler.model.decoder._lycoris_net)\n        self.assertFalse(handler.lora_loaded)\n        self.assertFalse(handler.use_lora)\n\n    def test_unload_lora_fails_when_lokr_restore_raises(self):\n        \"\"\"Unload should fail fast if LyCORIS restore() raises an exception.\"\"\"\n        handler = _DummyHandler()\n        handler.lora_loaded = True\n        handler._base_decoder = {\"w\": torch.ones(1)}\n        handler.model.decoder._lycoris_net = SimpleNamespace(restore=Mock(side_effect=RuntimeError(\"restore failed\")))\n        handler.model.decoder.load_state_dict = Mock(\n            return_value=SimpleNamespace(missing_keys=[], unexpected_keys=[])\n        )\n\n        message = lifecycle.unload_lora(handler)\n\n        self.assertIn(\"❌ Failed to unload LoRA\", message)\n        self.assertIn(\"restore failed\", message)\n        handler.model.decoder.load_state_dict.assert_not_called()\n\n\nif __name__ == \"__main__\":\n    unittest.main()\n"
  },
  {
    "path": "acestep/core/generation/handler/lora/registry_builder.py",
    "content": "\"\"\"Handler wrapper around the LoRA service registry build.\"\"\"\n\nfrom loguru import logger\n\nfrom acestep.constants import DEBUG_MODEL_LOADING\nfrom acestep.debug_utils import debug_log\n\n\ndef rebuild_lora_registry(self, lora_path: str | None = None) -> tuple[int, list[str]]:\n    \"\"\"Build explicit adapter->target mapping used for deterministic scaling.\"\"\"\n    self._ensure_lora_registry()\n    total_targets, adapters = self._lora_service.rebuild_registry(lora_path=lora_path)\n    sync_state = getattr(self, \"_sync_lora_state_from_service\", None)\n    if callable(sync_state):\n        sync_state()\n    else:\n        self._ensure_lora_registry()\n\n    if not adapters:\n        logger.warning(\"No adapter names discovered from decoder; LoRA registry will be empty.\")\n        debug_log(\n            \"No adapter names discovered; skipping adapter target registration.\",\n            mode=DEBUG_MODEL_LOADING,\n            prefix=\"lora\",\n        )\n\n    return total_targets, adapters\n"
  },
  {
    "path": "acestep/core/generation/handler/lora/registry_state.py",
    "content": "\"\"\"LoRA registry state helpers.\"\"\"\n\nfrom typing import Any\n\nfrom acestep.core.lora import LoraService\n\n\ndef _decoder_from_host(self):\n    model = getattr(self, \"model\", None)\n    return getattr(model, \"decoder\", None) if model is not None else None\n\n\ndef _copy_registry(registry: dict[str, dict[str, Any]]) -> dict[str, dict[str, Any]]:\n    copied: dict[str, dict[str, Any]] = {}\n    for adapter_name, meta in registry.items():\n        targets: list[dict[str, Any]] = []\n        for target in meta.get(\"targets\", []):\n            target_copy = dict(target)\n            module = target_copy.pop(\"module\", None)\n            if \"module_class\" not in target_copy:\n                target_copy[\"module_class\"] = module.__class__.__name__ if module is not None else None\n            targets.append(target_copy)\n        copied[adapter_name] = {\n            \"path\": meta.get(\"path\"),\n            \"targets\": targets,\n        }\n    return copied\n\n\ndef sync_lora_state_from_service(self) -> None:\n    \"\"\"Sync handler-visible snapshots from the authoritative service state.\"\"\"\n    self._lora_adapter_registry = _copy_registry(self._lora_service.registry)\n    self._lora_scale_state = dict(self._lora_service.scale_state)\n    self._lora_active_adapter = self._lora_service.active_adapter\n    self._lora_last_scale_report = dict(self._lora_service.last_scale_report)\n\n\ndef ensure_lora_registry(self) -> None:\n    decoder = _decoder_from_host(self)\n    if not hasattr(self, \"_lora_service\"):\n        self._lora_service = LoraService(decoder=decoder)\n    else:\n        self._lora_service.bind_decoder(decoder)\n\n    if not hasattr(self, \"_lora_adapter_registry\"):\n        self._lora_adapter_registry = {}\n    if not hasattr(self, \"_lora_active_adapter\"):\n        self._lora_active_adapter = None\n    if not hasattr(self, \"_lora_scale_state\"):\n        self._lora_scale_state = {}\n    if not hasattr(self, \"_active_loras\"):\n        self._active_loras = {}\n    if not hasattr(self, \"_lora_last_scale_report\"):\n        self._lora_last_scale_report = {}\n\n    sync_lora_state_from_service(self)\n\n\ndef debug_lora_registry_snapshot(self, max_targets_per_adapter: int = 20) -> dict[str, Any]:\n    \"\"\"Return debugger-friendly snapshot of LoRA adapter registry.\"\"\"\n    self._ensure_lora_registry()\n    return self._lora_service.registry_snapshot(max_targets_per_adapter=max_targets_per_adapter)\n"
  },
  {
    "path": "acestep/core/generation/handler/lora/scale_apply.py",
    "content": "\"\"\"Handler wrapper around LoRA service scale application.\"\"\"\n\nfrom loguru import logger\n\nfrom acestep.constants import DEBUG_MODEL_LOADING\nfrom acestep.debug_utils import debug_log\n\n\ndef apply_scale_to_adapter(self, adapter_name: str, scale: float) -> int:\n    \"\"\"Apply scale to registered targets for one adapter.\"\"\"\n    self._ensure_lora_registry()\n    self._lora_service.set_hooks(\n        warn_hook=logger.warning,\n        debug_hook=lambda message: debug_log(message, mode=DEBUG_MODEL_LOADING, prefix=\"lora\"),\n    )\n    modified = self._lora_service.apply_scale(adapter_name=adapter_name, scale=scale)\n    sync_state = getattr(self, \"_sync_lora_state_from_service\", None)\n    if callable(sync_state):\n        sync_state()\n    else:\n        self._ensure_lora_registry()\n    return modified\n"
  },
  {
    "path": "acestep/core/generation/handler/lora_integration_test.py",
    "content": "import unittest\n\nfrom acestep.core.generation.handler.lora_manager import LoraManagerMixin\n\n\nclass FakeDecoder:\n    def __init__(self, modules, adapter_names):\n        self._modules = modules\n        self._adapter_names = adapter_names\n\n    def named_modules(self):\n        return self._modules\n\n    def get_adapter_names(self):\n        return self._adapter_names\n\n\nclass FakeModel:\n    def __init__(self, decoder):\n        self.decoder = decoder\n\n\nclass FakeSetScaleModule:\n    def __init__(self):\n        self.scaling = {}\n        self.lora_alpha = {\"main\": 2.0}\n        self.r = {\"main\": 2.0}\n\n    def set_scale(self, adapter_name, factor):\n        raise AssertionError(f\"set_scale should be skipped for {adapter_name} with factor={factor}\")\n\n\nclass MinimalHandler(LoraManagerMixin):\n    def __init__(self, decoder):\n        self.model = FakeModel(decoder)\n        self.device = \"cpu\"\n        self.dtype = \"float32\"\n        self.quantization = None\n        self._base_decoder = None\n        self.lora_loaded = True\n        self.use_lora = True\n        self.lora_scale = 1.0\n\n\nclass LoraHandlerIntegrationTests(unittest.TestCase):\n    def test_handler_state_snapshot_does_not_mutate_service(self):\n        decoder = FakeDecoder(modules=[(\"lora_block\", FakeSetScaleModule())], adapter_names=[\"main\"])\n        handler = MinimalHandler(decoder)\n\n        _, adapters = handler._rebuild_lora_registry()\n        self.assertEqual(adapters, [\"main\"])\n        self.assertIn(\"main\", handler._lora_service.registry)\n        handler_target = handler._lora_adapter_registry[\"main\"][\"targets\"][0]\n        self.assertNotIn(\"module\", handler_target)\n        self.assertEqual(handler_target[\"module_class\"], \"FakeSetScaleModule\")\n\n        handler._lora_adapter_registry.clear()\n        self.assertIn(\"main\", handler._lora_service.registry)\n\n    def test_set_lora_scale_reports_skipped_targets(self):\n        decoder = FakeDecoder(modules=[(\"lora_block\", FakeSetScaleModule())], adapter_names=[\"main\"])\n        handler = MinimalHandler(decoder)\n        handler._rebuild_lora_registry()\n\n        message = handler.set_lora_scale(0.7)\n\n        self.assertIn(\"skipped\", message)\n        self.assertIn(\"unchanged\", message)\n\n    def test_set_lora_scale_reports_no_modules_found(self):\n        decoder = FakeDecoder(modules=[], adapter_names=[\"main\"])\n        handler = MinimalHandler(decoder)\n        handler._rebuild_lora_registry()\n\n        message = handler.set_lora_scale(0.7)\n\n        self.assertIn(\"no modules found\", message)\n\n    def test_get_lora_status_exposes_synthetic_default_mode(self):\n        decoder = FakeDecoder(modules=[], adapter_names=[])\n        handler = MinimalHandler(decoder)\n        handler._rebuild_lora_registry()\n\n        status = handler.get_lora_status()\n\n        self.assertIn(\"synthetic_default_mode\", status)\n        self.assertTrue(status[\"synthetic_default_mode\"])\n\n    def test_set_lora_scale_rejects_non_numeric_input(self):\n        decoder = FakeDecoder(modules=[], adapter_names=[\"main\"])\n        handler = MinimalHandler(decoder)\n\n        message = handler.set_lora_scale(\"abc\")\n\n        self.assertIn(\"Invalid LoRA scale\", message)\n\n    def test_set_use_lora_handles_missing_model_decoder(self):\n        decoder = FakeDecoder(modules=[], adapter_names=[\"main\"])\n        handler = MinimalHandler(decoder)\n        handler.model = None\n\n        message = handler.set_use_lora(False)\n\n        self.assertEqual(message, \"✅ LoRA disabled\")\n\n\nif __name__ == \"__main__\":\n    unittest.main()\n"
  },
  {
    "path": "acestep/core/generation/handler/lora_manager.py",
    "content": "\"\"\"LoRA management mixin for AceStepHandler.\"\"\"\n\nfrom .lora.adapter_discovery import collect_adapter_names\nfrom .lora.controls import get_lora_status, set_active_lora_adapter, set_lora_scale, set_use_lora\nfrom .lora.lifecycle import add_lora, add_voice_lora, load_lora, remove_lora, unload_lora\nfrom .lora.registry_builder import rebuild_lora_registry\nfrom .lora.registry_state import debug_lora_registry_snapshot, ensure_lora_registry, sync_lora_state_from_service\nfrom .lora.scale_apply import apply_scale_to_adapter\n\n\nclass LoraManagerMixin:\n    \"\"\"LoRA management behavior mixed into AceStepHandler.\n\n    Expected host attributes:\n    - model, device, dtype, quantization\n    - _base_decoder\n    - lora_loaded, use_lora, lora_scale\n    \"\"\"\n\n    _ensure_lora_registry = ensure_lora_registry\n    _sync_lora_state_from_service = sync_lora_state_from_service\n    _debug_lora_registry_snapshot = debug_lora_registry_snapshot\n    _collect_adapter_names = collect_adapter_names\n\n    _rebuild_lora_registry = rebuild_lora_registry\n    _apply_scale_to_adapter = apply_scale_to_adapter\n\n    add_lora = add_lora\n    add_voice_lora = add_voice_lora\n    load_lora = load_lora\n    remove_lora = remove_lora\n    unload_lora = unload_lora\n    set_use_lora = set_use_lora\n    set_lora_scale = set_lora_scale\n    set_active_lora_adapter = set_active_lora_adapter\n    get_lora_status = get_lora_status\n"
  },
  {
    "path": "acestep/core/generation/handler/lyric_alignment_common.py",
    "content": "\"\"\"Shared helpers for lyric alignment and scoring mixins.\"\"\"\n\nfrom typing import Any, Dict, List, Optional, Sequence, Tuple\n\nimport torch\n\n\nclass LyricAlignmentCommonMixin:\n    \"\"\"Provide shared data preparation helpers for lyric alignment methods.\"\"\"\n\n    def _resolve_custom_layers_config(\n        self, custom_layers_config: Optional[Dict[int, List[int]]]\n    ) -> Dict[int, List[int]]:\n        \"\"\"Return caller config when provided, otherwise host default config.\"\"\"\n        if custom_layers_config is not None:\n            return custom_layers_config\n        return self.custom_layers_config\n\n    def _move_alignment_inputs_to_runtime(\n        self,\n        pred_latent: torch.Tensor,\n        encoder_hidden_states: torch.Tensor,\n        encoder_attention_mask: torch.Tensor,\n        context_latents: torch.Tensor,\n    ) -> Tuple[torch.Tensor, torch.Tensor, torch.Tensor, torch.Tensor]:\n        \"\"\"Move alignment tensors to the handler runtime device and dtype.\"\"\"\n        device = self.device\n        dtype = self.dtype\n        return (\n            pred_latent.to(device=device, dtype=dtype),\n            encoder_hidden_states.to(device=device, dtype=dtype),\n            encoder_attention_mask.to(device=device, dtype=dtype),\n            context_latents.to(device=device, dtype=dtype),\n        )\n\n    def _sample_noise_like(self, reference: torch.Tensor, seed: Optional[int]) -> torch.Tensor:\n        \"\"\"Sample deterministic noise for a tensor shape, including MPS-safe seeding.\"\"\"\n        if seed is None:\n            return torch.randn_like(reference)\n\n        device = reference.device\n        dtype = reference.dtype\n        is_mps = (isinstance(device, str) and device == \"mps\") or (\n            hasattr(device, \"type\") and device.type == \"mps\"\n        )\n        gen_device = \"cpu\" if is_mps else device\n        generator = torch.Generator(device=gen_device).manual_seed(int(seed))\n        return torch.randn(reference.shape, generator=generator, device=gen_device, dtype=dtype).to(device)\n\n    def _extract_lyric_segment(\n        self,\n        lyric_token_ids: torch.Tensor,\n        vocal_language: str,\n    ) -> Tuple[Sequence[int], List[int], int, int]:\n        \"\"\"Split token ids into header and lyric ranges.\"\"\"\n        raw_lyric_ids: Sequence[int]\n        if isinstance(lyric_token_ids, torch.Tensor):\n            raw_lyric_ids = lyric_token_ids[0].tolist()\n        else:\n            raw_lyric_ids = lyric_token_ids\n\n        header_str = f\"# Languages\\n{vocal_language}\\n\\n# Lyric\\n\"\n        header_ids = self.text_tokenizer.encode(header_str, add_special_tokens=False)\n        start_idx = len(header_ids)\n        try:\n            end_idx = raw_lyric_ids.index(151643)  # <|endoftext|>\n        except ValueError:\n            end_idx = len(raw_lyric_ids)\n\n        pure_lyric_ids = list(raw_lyric_ids[start_idx:end_idx])\n        return raw_lyric_ids, pure_lyric_ids, start_idx, end_idx\n\n    def _lyric_timestamp_error(self, message: str) -> Dict[str, Any]:\n        \"\"\"Build the standard timestamp error payload.\"\"\"\n        return {\n            \"lrc_text\": \"\",\n            \"sentence_timestamps\": [],\n            \"token_timestamps\": [],\n            \"success\": False,\n            \"error\": message,\n        }\n\n    def _lyric_score_error(self, message: str) -> Dict[str, Any]:\n        \"\"\"Build the standard lyric-score error payload.\"\"\"\n        return {\n            \"lm_score\": 0.0,\n            \"dit_score\": 0.0,\n            \"success\": False,\n            \"error\": message,\n        }\n"
  },
  {
    "path": "acestep/core/generation/handler/lyric_alignment_test.py",
    "content": "\"\"\"Unit tests for lyric timestamp and lyric score mixins.\"\"\"\n\nimport contextlib\nimport types\nimport unittest\nfrom unittest.mock import patch\n\nimport torch\n\nfrom acestep.core.generation.handler.lyric_score import LyricScoreMixin\nfrom acestep.core.generation.handler.lyric_timestamp import LyricTimestampMixin\n\n\nclass _Tokenizer:\n    \"\"\"Minimal tokenizer stub with deterministic header ids.\"\"\"\n\n    def encode(self, _text, add_special_tokens=False):\n        \"\"\"Return a fixed header-token shape for deterministic slicing.\"\"\"\n        _ = add_special_tokens\n        return [1, 2]\n\n\nclass _Decoder:\n    \"\"\"Minimal decoder stub returning configured cross-attention outputs.\"\"\"\n\n    def __init__(self, cross_attns):\n        \"\"\"Store decoder output tuple index-2 payload.\"\"\"\n        self._cross_attns = cross_attns\n\n    def eval(self):\n        \"\"\"Mirror torch module API used by score mixin.\"\"\"\n\n    def __call__(self, **kwargs):\n        \"\"\"Return an output tuple compatible with handler expectations.\"\"\"\n        _ = kwargs\n        return (None, None, self._cross_attns)\n\n\nclass _Model:\n    \"\"\"Model wrapper containing a fake decoder.\"\"\"\n\n    def __init__(self, decoder):\n        \"\"\"Bind the test decoder.\"\"\"\n        self.decoder = decoder\n\n\nclass _Host(LyricTimestampMixin, LyricScoreMixin):\n    \"\"\"Host object exposing the minimal attributes expected by mixins.\"\"\"\n\n    def __init__(self, decoder):\n        \"\"\"Initialize runtime attributes consumed by lyric mixins.\"\"\"\n        self.model = _Model(decoder)\n        self.text_tokenizer = _Tokenizer()\n        self.device = \"cpu\"\n        self.dtype = torch.float32\n        self.custom_layers_config = {2: [6]}\n\n    def _load_model_context(self, _name):\n        \"\"\"Return a no-op context manager to mimic handler model context.\"\"\"\n        return contextlib.nullcontext()\n\n\nclass LyricAlignmentMixinTests(unittest.TestCase):\n    \"\"\"Cover success and no-attention regression behaviors.\"\"\"\n\n    def _sample_inputs(self):\n        \"\"\"Build deterministic tensors and lyric token ids for tests.\"\"\"\n        pred = torch.randn(1, 7, 4)\n        enc = torch.randn(1, 6, 4)\n        enc_mask = torch.ones(1, 6)\n        ctx = torch.randn(1, 7, 4)\n        lyric_ids = torch.tensor([[1, 2, 101, 102, 103, 151643]], dtype=torch.long)\n        return pred, enc, enc_mask, ctx, lyric_ids\n\n    def test_get_lyric_timestamp_success(self):\n        \"\"\"Timestamp generation should return successful payload with aligner output.\"\"\"\n        decoder = _Decoder(cross_attns=[torch.randn(1, 2, 7, 6)])\n        host = _Host(decoder=decoder)\n        pred, enc, enc_mask, ctx, lyric_ids = self._sample_inputs()\n\n        class _FakeStampsAligner:\n            \"\"\"Fake aligner used to isolate timestamp mixin behavior.\"\"\"\n\n            def __init__(self, _tokenizer):\n                \"\"\"Match production constructor signature.\"\"\"\n\n            def stamps_align_info(self, **kwargs):\n                \"\"\"Return a non-empty calc matrix to simulate valid alignment.\"\"\"\n                _ = kwargs\n                return {\"calc_matrix\": torch.ones(2, 2)}\n\n            def get_timestamps_and_lrc(self, **kwargs):\n                \"\"\"Return deterministic timestamp payload.\"\"\"\n                _ = kwargs\n                return {\n                    \"lrc_text\": \"[00:00.00]hello\",\n                    \"sentence_timestamps\": [{\"start\": 0.0, \"end\": 1.0}],\n                    \"token_timestamps\": [{\"token\": \"hello\", \"start\": 0.0, \"end\": 0.5}],\n                }\n\n        fake_module = types.SimpleNamespace(MusicStampsAligner=_FakeStampsAligner)\n        with patch.dict(\"sys.modules\", {\"acestep.core.scoring.dit_alignment\": fake_module}):\n\n            result = host.get_lyric_timestamp(\n                pred_latent=pred,\n                encoder_hidden_states=enc,\n                encoder_attention_mask=enc_mask,\n                context_latents=ctx,\n                lyric_token_ids=lyric_ids,\n                total_duration_seconds=3.0,\n            )\n\n        self.assertTrue(result[\"success\"])\n        self.assertEqual(result[\"lrc_text\"], \"[00:00.00]hello\")\n        self.assertIsNone(result[\"error\"])\n\n    def test_get_lyric_score_success(self):\n        \"\"\"Score generation should return LM and DiT scores from the scorer output.\"\"\"\n        decoder = _Decoder(cross_attns=[torch.randn(2, 2, 7, 6)])\n        host = _Host(decoder=decoder)\n        pred, enc, enc_mask, ctx, lyric_ids = self._sample_inputs()\n\n        class _FakeLyricScorer:\n            \"\"\"Fake lyric scorer used to isolate score mixin behavior.\"\"\"\n\n            def __init__(self, _tokenizer):\n                \"\"\"Match production constructor signature.\"\"\"\n\n            def lyrics_alignment_info(self, **kwargs):\n                \"\"\"Return deterministic alignment info for downstream scoring.\"\"\"\n                _ = kwargs\n                return {\n                    \"energy_matrix\": torch.ones(2, 2),\n                    \"type_mask\": torch.ones(2, 2),\n                    \"path_coords\": [(0, 0)],\n                }\n\n            def calculate_score(self, **kwargs):\n                \"\"\"Return a stable numeric score for assertions.\"\"\"\n                _ = kwargs\n                return {\"lyrics_score\": 0.77, \"final_score\": 0.66}\n\n        fake_module = types.SimpleNamespace(MusicLyricScorer=_FakeLyricScorer)\n        with patch.dict(\"sys.modules\", {\"acestep.core.scoring.dit_score\": fake_module}):\n\n            result = host.get_lyric_score(\n                pred_latent=pred,\n                encoder_hidden_states=enc,\n                encoder_attention_mask=enc_mask,\n                context_latents=ctx,\n                lyric_token_ids=lyric_ids,\n            )\n\n        self.assertTrue(result[\"success\"])\n        self.assertEqual(result[\"lm_score\"], 0.77)\n        self.assertEqual(result[\"dit_score\"], 0.77)\n        self.assertIsNone(result[\"error\"])\n\n    def test_get_lyric_timestamp_returns_error_when_attentions_missing(self):\n        \"\"\"Timestamp generation should fail clearly when decoder returns no attentions.\"\"\"\n        decoder = _Decoder(cross_attns=None)\n        host = _Host(decoder=decoder)\n        pred, enc, enc_mask, ctx, lyric_ids = self._sample_inputs()\n\n        result = host.get_lyric_timestamp(\n            pred_latent=pred,\n            encoder_hidden_states=enc,\n            encoder_attention_mask=enc_mask,\n            context_latents=ctx,\n            lyric_token_ids=lyric_ids,\n            total_duration_seconds=3.0,\n        )\n\n        self.assertFalse(result[\"success\"])\n        self.assertEqual(result[\"error\"], \"Model did not return attentions\")\n\n    def test_get_lyric_score_returns_error_when_attentions_missing(self):\n        \"\"\"Score generation should fail clearly when decoder returns no attentions.\"\"\"\n        decoder = _Decoder(cross_attns=None)\n        host = _Host(decoder=decoder)\n        pred, enc, enc_mask, ctx, lyric_ids = self._sample_inputs()\n\n        result = host.get_lyric_score(\n            pred_latent=pred,\n            encoder_hidden_states=enc,\n            encoder_attention_mask=enc_mask,\n            context_latents=ctx,\n            lyric_token_ids=lyric_ids,\n        )\n\n        self.assertFalse(result[\"success\"])\n        self.assertEqual(result[\"error\"], \"Model did not return attentions\")\n\n\nif __name__ == \"__main__\":\n    unittest.main()\n"
  },
  {
    "path": "acestep/core/generation/handler/lyric_score.py",
    "content": "\"\"\"Lyric alignment scoring mixin for the main handler.\"\"\"\n\nfrom typing import Any, Dict, List, Optional\n\nimport torch\nfrom loguru import logger\n\nfrom acestep.core.generation.handler.lyric_alignment_common import LyricAlignmentCommonMixin\n\n\nclass LyricScoreMixin(LyricAlignmentCommonMixin):\n    \"\"\"Provide LM/DiT lyric alignment scoring from decoder attentions.\"\"\"\n\n    @torch.inference_mode()\n    def get_lyric_score(\n        self,\n        pred_latent: torch.Tensor,\n        encoder_hidden_states: torch.Tensor,\n        encoder_attention_mask: torch.Tensor,\n        context_latents: torch.Tensor,\n        lyric_token_ids: torch.Tensor,\n        vocal_language: str = \"en\",\n        inference_steps: int = 8,\n        seed: int = 42,\n        custom_layers_config: Optional[Dict[int, List[int]]] = None,\n    ) -> Dict[str, Any]:\n        \"\"\"Calculate lyric alignment scores for pure-noise and regressed-latent inputs.\n\n        Args:\n            pred_latent (torch.Tensor): Generated latent tensor shaped ``[B, T, D]``.\n            encoder_hidden_states (torch.Tensor): Decoder conditioning states.\n            encoder_attention_mask (torch.Tensor): Conditioning attention mask.\n            context_latents (torch.Tensor): Context latents aligned to ``pred_latent``.\n            lyric_token_ids (torch.Tensor): Tokenized lyric ids for alignment slicing.\n            vocal_language (str): Language tag used to parse lyric header tokens.\n            inference_steps (int): Positive diffusion step count for ``t_last``.\n            seed (int): Noise seed used for deterministic score sampling.\n            custom_layers_config (Optional[Dict[int, List[int]]]): Optional attention layer/head map.\n\n        Returns:\n            Dict[str, Any]: Score payload with ``lm_score``, ``dit_score``, ``success``, and ``error``.\n\n        Raises:\n            Exception: Unexpected runtime failures are re-raised after logging.\n        \"\"\"\n        if self.model is None:\n            return self._lyric_score_error(\"Model not initialized\")\n\n        custom_layers_config = self._resolve_custom_layers_config(custom_layers_config)\n\n        try:\n            (\n                pred_latent,\n                encoder_hidden_states,\n                encoder_attention_mask,\n                context_latents,\n            ) = self._move_alignment_inputs_to_runtime(\n                pred_latent=pred_latent,\n                encoder_hidden_states=encoder_hidden_states,\n                encoder_attention_mask=encoder_attention_mask,\n                context_latents=context_latents,\n            )\n\n            bsz = pred_latent.shape[0]\n            if not isinstance(inference_steps, int) or inference_steps <= 0:\n                raise ValueError(\n                    f\"inference_steps must be a positive non-zero integer, got {inference_steps!r}\"\n                )\n\n            x0 = self._sample_noise_like(pred_latent, seed)\n            t_last_val = 1.0 / inference_steps\n\n            xt_lm = x0\n            xt_dit = t_last_val * x0 + (1.0 - t_last_val) * pred_latent\n            xt_in = torch.cat([xt_lm, xt_dit], dim=0)\n            t_in = torch.cat(\n                [\n                    torch.tensor([1.0] * bsz, device=pred_latent.device, dtype=pred_latent.dtype),\n                    torch.tensor([t_last_val] * bsz, device=pred_latent.device, dtype=pred_latent.dtype),\n                ],\n                dim=0,\n            )\n            encoder_hidden_states_in = torch.cat([encoder_hidden_states, encoder_hidden_states], dim=0)\n            encoder_attention_mask_in = torch.cat([encoder_attention_mask, encoder_attention_mask], dim=0)\n            context_latents_in = torch.cat([context_latents, context_latents], dim=0)\n            attention_mask_in = torch.ones(\n                2 * bsz,\n                xt_in.shape[1],\n                device=pred_latent.device,\n                dtype=pred_latent.dtype,\n            )\n\n            with self._load_model_context(\"model\"):\n                decoder = self.model.decoder\n                if hasattr(decoder, \"eval\"):\n                    decoder.eval()\n                decoder_outputs = decoder(\n                    hidden_states=xt_in,\n                    timestep=t_in,\n                    timestep_r=t_in,\n                    attention_mask=attention_mask_in,\n                    encoder_hidden_states=encoder_hidden_states_in,\n                    use_cache=False,\n                    past_key_values=None,\n                    encoder_attention_mask=encoder_attention_mask_in,\n                    context_latents=context_latents_in,\n                    output_attentions=True,\n                    custom_layers_config=custom_layers_config,\n                    enable_early_exit=True,\n                )\n\n            if decoder_outputs[2] is None:\n                return self._lyric_score_error(\"Model did not return attentions\")\n\n            captured_layers = []\n            for layer_attn in decoder_outputs[2]:\n                if layer_attn is None:\n                    continue\n                captured_layers.append(layer_attn.transpose(-1, -2))\n            if not captured_layers:\n                return self._lyric_score_error(\"No valid attention layers returned\")\n\n            stacked = torch.stack(captured_layers)\n            all_layers_matrix_lm = stacked[:, :bsz, ...]\n            all_layers_matrix_dit = stacked[:, bsz:, ...]\n            if bsz == 1:\n                all_layers_matrix_lm = all_layers_matrix_lm.squeeze(1)\n                all_layers_matrix_dit = all_layers_matrix_dit.squeeze(1)\n\n            _, pure_lyric_ids, start_idx, end_idx = self._extract_lyric_segment(\n                lyric_token_ids=lyric_token_ids,\n                vocal_language=vocal_language,\n            )\n            if start_idx >= all_layers_matrix_lm.shape[-2]:\n                return self._lyric_score_error(\"Lyrics indices out of bounds\")\n\n            pure_matrix_lm = all_layers_matrix_lm[..., start_idx:end_idx, :]\n            pure_matrix_dit = all_layers_matrix_dit[..., start_idx:end_idx, :]\n\n            from acestep.core.scoring.dit_score import MusicLyricScorer\n\n            aligner = MusicLyricScorer(self.text_tokenizer)\n            lm_score = self._calculate_single_lyric_score(\n                aligner=aligner,\n                matrix=pure_matrix_lm,\n                pure_lyric_ids=pure_lyric_ids,\n                custom_layers_config=custom_layers_config,\n            )\n            dit_score = self._calculate_single_lyric_score(\n                aligner=aligner,\n                matrix=pure_matrix_dit,\n                pure_lyric_ids=pure_lyric_ids,\n                custom_layers_config=custom_layers_config,\n            )\n            return {\n                \"lm_score\": lm_score,\n                \"dit_score\": dit_score,\n                \"success\": True,\n                \"error\": None,\n            }\n        except (ValueError, KeyError, RuntimeError, OSError) as exc:\n            logger.exception(\"[get_lyric_score] Failed\")\n            return self._lyric_score_error(f\"Error generating score: {exc}\")\n        except Exception:\n            logger.exception(\"[get_lyric_score] Unexpected failure\")\n            raise\n\n    def _calculate_single_lyric_score(\n        self,\n        aligner: Any,\n        matrix: torch.Tensor,\n        pure_lyric_ids: List[int],\n        custom_layers_config: Dict[int, List[int]],\n    ) -> float:\n        \"\"\"Run one alignment-score evaluation against one attention matrix.\"\"\"\n        info = aligner.lyrics_alignment_info(\n            attention_matrix=matrix,\n            token_ids=pure_lyric_ids,\n            custom_config=custom_layers_config,\n            return_matrices=False,\n            medfilt_width=1,\n        )\n        if info.get(\"energy_matrix\") is None:\n            return 0.0\n        res = aligner.calculate_score(\n            energy_matrix=info[\"energy_matrix\"],\n            type_mask=info[\"type_mask\"],\n            path_coords=info[\"path_coords\"],\n        )\n        return float(res.get(\"lyrics_score\", res.get(\"final_score\", 0.0)))\n"
  },
  {
    "path": "acestep/core/generation/handler/lyric_timestamp.py",
    "content": "\"\"\"Lyric timestamp generation mixin for the main handler.\"\"\"\n\nfrom typing import Any, Dict, List, Optional\n\nimport torch\nfrom loguru import logger\n\nfrom acestep.core.generation.handler.lyric_alignment_common import LyricAlignmentCommonMixin\n\n\nclass LyricTimestampMixin(LyricAlignmentCommonMixin):\n    \"\"\"Provide cross-attention based lyric timestamp generation.\"\"\"\n\n    @torch.inference_mode()\n    def get_lyric_timestamp(\n        self,\n        pred_latent: torch.Tensor,\n        encoder_hidden_states: torch.Tensor,\n        encoder_attention_mask: torch.Tensor,\n        context_latents: torch.Tensor,\n        lyric_token_ids: torch.Tensor,\n        total_duration_seconds: float,\n        vocal_language: str = \"en\",\n        inference_steps: int = 8,\n        seed: int = 42,\n        custom_layers_config: Optional[Dict[int, List[int]]] = None,\n    ) -> Dict[str, Any]:\n        \"\"\"Generate LRC timestamps by aligning decoder cross-attention to lyric tokens.\n\n        Args:\n            pred_latent (torch.Tensor): Generated latent tensor shaped ``[B, T, D]``.\n            encoder_hidden_states (torch.Tensor): Decoder conditioning states.\n            encoder_attention_mask (torch.Tensor): Conditioning attention mask.\n            context_latents (torch.Tensor): Context latents aligned to ``pred_latent``.\n            lyric_token_ids (torch.Tensor): Tokenized lyric sequence including header tokens.\n            total_duration_seconds (float): Audio duration used to scale timestamp output.\n            vocal_language (str): Language tag used to locate lyric header boundary.\n            inference_steps (int): Positive diffusion step count for ``t_last``.\n            seed (int): Noise seed used for deterministic timestamp sampling.\n            custom_layers_config (Optional[Dict[int, List[int]]]): Optional attention layer/head map.\n\n        Returns:\n            Dict[str, Any]: Timestamp payload with ``lrc_text``, token/sentence timestamps, ``success``, and ``error``.\n\n        Raises:\n            Exception: Unexpected runtime failures are re-raised after logging.\n        \"\"\"\n        if self.model is None:\n            return self._lyric_timestamp_error(\"Model not initialized\")\n\n        custom_layers_config = self._resolve_custom_layers_config(custom_layers_config)\n\n        try:\n            (\n                pred_latent,\n                encoder_hidden_states,\n                encoder_attention_mask,\n                context_latents,\n            ) = self._move_alignment_inputs_to_runtime(\n                pred_latent=pred_latent,\n                encoder_hidden_states=encoder_hidden_states,\n                encoder_attention_mask=encoder_attention_mask,\n                context_latents=context_latents,\n            )\n            bsz = pred_latent.shape[0]\n            if not isinstance(inference_steps, int) or inference_steps <= 0:\n                return self._lyric_timestamp_error(\n                    f\"inference_steps must be a positive non-zero integer, got {inference_steps!r}\"\n                )\n\n            t_last_val = 1.0 / inference_steps\n            t_tensor = torch.tensor([t_last_val] * bsz, device=pred_latent.device, dtype=pred_latent.dtype)\n            noise = self._sample_noise_like(pred_latent, seed)\n            xt = t_last_val * noise + (1.0 - t_last_val) * pred_latent\n            attention_mask = torch.ones(bsz, pred_latent.shape[1], device=pred_latent.device, dtype=pred_latent.dtype)\n\n            with self._load_model_context(\"model\"):\n                decoder_outputs = self.model.decoder(\n                    hidden_states=xt,\n                    timestep=t_tensor,\n                    timestep_r=t_tensor,\n                    attention_mask=attention_mask,\n                    encoder_hidden_states=encoder_hidden_states,\n                    use_cache=False,\n                    past_key_values=None,\n                    encoder_attention_mask=encoder_attention_mask,\n                    context_latents=context_latents,\n                    output_attentions=True,\n                    custom_layers_config=custom_layers_config,\n                    enable_early_exit=True,\n                )\n\n            if decoder_outputs[2] is None:\n                return self._lyric_timestamp_error(\"Model did not return attentions\")\n\n            captured_layers = []\n            for layer_attn in decoder_outputs[2]:\n                if layer_attn is None:\n                    continue\n                captured_layers.append(layer_attn[:bsz].transpose(-1, -2))\n            if not captured_layers:\n                return self._lyric_timestamp_error(\"No valid attention layers returned\")\n\n            stacked = torch.stack(captured_layers)\n            all_layers_matrix = stacked.squeeze(1) if bsz == 1 else stacked\n\n            _, pure_lyric_ids, start_idx, end_idx = self._extract_lyric_segment(\n                lyric_token_ids=lyric_token_ids,\n                vocal_language=vocal_language,\n            )\n            pure_lyric_matrix = all_layers_matrix[:, :, start_idx:end_idx, :]\n\n            from acestep.core.scoring.dit_alignment import MusicStampsAligner\n\n            aligner = MusicStampsAligner(self.text_tokenizer)\n            align_info = aligner.stamps_align_info(\n                attention_matrix=pure_lyric_matrix,\n                lyrics_tokens=pure_lyric_ids,\n                total_duration_seconds=total_duration_seconds,\n                custom_config=custom_layers_config,\n                return_matrices=False,\n                violence_level=2.0,\n                medfilt_width=1,\n            )\n            if align_info.get(\"calc_matrix\") is None:\n                return self._lyric_timestamp_error(\n                    align_info.get(\"error\", \"Failed to process attention matrix\")\n                )\n\n            result = aligner.get_timestamps_and_lrc(\n                calc_matrix=align_info[\"calc_matrix\"],\n                lyrics_tokens=pure_lyric_ids,\n                total_duration_seconds=total_duration_seconds,\n            )\n            return {\n                \"lrc_text\": result[\"lrc_text\"],\n                \"sentence_timestamps\": result[\"sentence_timestamps\"],\n                \"token_timestamps\": result[\"token_timestamps\"],\n                \"success\": True,\n                \"error\": None,\n            }\n        except (ValueError, KeyError, RuntimeError, OSError) as exc:\n            logger.exception(\"[get_lyric_timestamp] Failed\")\n            return self._lyric_timestamp_error(f\"Error generating timestamps: {exc}\")\n        except Exception:\n            logger.exception(\"[get_lyric_timestamp] Unexpected failure\")\n            raise\n"
  },
  {
    "path": "acestep/core/generation/handler/memory_utils.py",
    "content": "\"\"\"Memory and VRAM helper methods for handler decomposition.\"\"\"\n\nimport os\nfrom typing import Optional\n\nimport torch\nfrom loguru import logger\n\nfrom acestep.gpu_config import (\n    cuda_supports_bfloat16,\n    get_effective_free_vram_gb,\n    get_global_gpu_config,\n    is_rocm_available,\n)\n\n\ndef _is_cuda_device(device: object) -> bool:\n    \"\"\"Return whether a device identifier refers to any CUDA device.\"\"\"\n    if device is None:\n        return False\n    try:\n        return torch.device(str(device)).type == \"cuda\"\n    except (TypeError, RuntimeError, ValueError):\n        return isinstance(device, str) and device.split(\":\", 1)[0] == \"cuda\"\n\ndef _cuda_device_index(device: object) -> int:\n    \"\"\"Return the CUDA device index implied by a device identifier.\"\"\"\n    if isinstance(device, torch.device):\n        return 0 if device.index is None else device.index\n    try:\n        parsed = torch.device(str(device))\n        if parsed.type == \"cuda\":\n            return 0 if parsed.index is None else parsed.index\n    except (TypeError, RuntimeError, ValueError):\n        pass\n    if isinstance(device, str) and device.startswith(\"cuda:\"):\n        try:\n            return int(device.split(\":\", 1)[1])\n        except ValueError:\n            return 0\n    return 0\n\n\nclass MemoryUtilsMixin:\n    \"\"\"Mixin containing memory sizing and VRAM guard helpers.\n\n    Depends on host members:\n    - Attribute: ``device``.\n    \"\"\"\n\n    def is_silence(self, audio: torch.Tensor) -> bool:\n        \"\"\"Return True when audio is effectively silent.\"\"\"\n        return bool(torch.all(audio.abs() < 1e-6))\n\n    def _get_system_memory_gb(self) -> Optional[float]:\n        \"\"\"Return total system RAM in GB when available.\"\"\"\n        try:\n            page_size = os.sysconf(\"SC_PAGE_SIZE\")\n            page_count = os.sysconf(\"SC_PHYS_PAGES\")\n            if page_size and page_count:\n                return (page_size * page_count) / (1024**3)\n        except (ValueError, OSError, AttributeError):\n            return None\n        return None\n\n    def _get_effective_mps_memory_gb(self) -> Optional[float]:\n        \"\"\"Best-effort MPS memory estimate (recommended max or system RAM).\"\"\"\n        if hasattr(torch, \"mps\") and hasattr(torch.mps, \"recommended_max_memory\"):\n            try:\n                return torch.mps.recommended_max_memory() / (1024**3)\n            except Exception:\n                pass\n        system_gb = self._get_system_memory_gb()\n        if system_gb is None:\n            return None\n        return system_gb * 0.75\n\n    VAE_DECODE_MAX_CHUNK_SIZE = 512\n\n    def _get_auto_decode_chunk_size(self) -> int:\n        \"\"\"Choose a conservative VAE decode chunk size based on available memory.\"\"\"\n        override = os.environ.get(\"ACESTEP_VAE_DECODE_CHUNK_SIZE\")\n        if override:\n            try:\n                value = int(override)\n                if value > 0:\n                    return value\n            except ValueError:\n                pass\n\n        max_chunk = self.VAE_DECODE_MAX_CHUNK_SIZE\n\n        if self.device == \"mps\":\n            mem_gb = self._get_effective_mps_memory_gb()\n            if mem_gb is not None:\n                if mem_gb >= 48:\n                    return min(1536, max_chunk)\n                if mem_gb >= 24:\n                    return min(1024, max_chunk)\n            return min(512, max_chunk)\n\n        if _is_cuda_device(self.device):\n            try:\n                free_gb = get_effective_free_vram_gb(_cuda_device_index(self.device))\n            except Exception:\n                free_gb = 0\n            logger.debug(f\"[_get_auto_decode_chunk_size] Effective free VRAM: {free_gb:.2f} GB\")\n            if free_gb >= 24.0:\n                return min(512, max_chunk)\n            if free_gb >= 16.0:\n                return min(384, max_chunk)\n            if free_gb >= 12.0:\n                return min(256, max_chunk)\n            return min(128, max_chunk)\n        return min(256, max_chunk)\n\n    def _should_offload_wav_to_cpu(self) -> bool:\n        \"\"\"Decide whether to offload decoded wavs to CPU for memory safety.\"\"\"\n        override = os.environ.get(\"ACESTEP_MPS_DECODE_OFFLOAD\")\n        if override:\n            return override.lower() in (\"1\", \"true\", \"yes\")\n        if self.device == \"mps\":\n            mem_gb = self._get_effective_mps_memory_gb()\n            if mem_gb is not None and mem_gb >= 32:\n                return False\n            return True\n        if _is_cuda_device(self.device):\n            try:\n                free_gb = get_effective_free_vram_gb(_cuda_device_index(self.device))\n                logger.debug(f\"[_should_offload_wav_to_cpu] Effective free VRAM: {free_gb:.2f} GB\")\n                if free_gb >= 24.0:\n                    return False\n            except Exception:\n                pass\n        return True\n\n    def _vram_guard_reduce_batch(\n        self,\n        batch_size: int,\n        audio_duration: Optional[float] = None,\n        use_lm: bool = False,\n    ) -> int:\n        \"\"\"Auto-reduce batch_size when free VRAM is too tight.\"\"\"\n        if batch_size <= 1:\n            return batch_size\n\n        device = self.device\n        if device == \"cpu\" or device == \"mps\":\n            return batch_size\n\n        if self.offload_to_cpu:\n            gpu_config = get_global_gpu_config()\n            if gpu_config is not None:\n                tier_max = gpu_config.max_batch_size_with_lm\n                if batch_size <= tier_max:\n                    logger.debug(\n                        f\"[VRAM guard] offload_to_cpu=True, batch_size={batch_size} <= \"\n                        f\"tier limit {tier_max} - skipping dynamic VRAM check\"\n                    )\n                    return batch_size\n\n        try:\n            free_gb = get_effective_free_vram_gb(_cuda_device_index(device))\n        except Exception:\n            return batch_size\n\n        duration_sec = float(audio_duration) if audio_duration and float(audio_duration) > 0 else 60.0\n        per_sample_gb = 0.5 + max(0.0, 0.15 * (duration_sec - 60.0) / 60.0)\n        if hasattr(self, \"model\") and self.model is not None:\n            model_name = getattr(self, \"config_path\", \"\") or \"\"\n            if \"base\" in model_name.lower():\n                per_sample_gb *= 2.0\n\n        safety_margin_gb = 1.5\n        available_for_batch = free_gb - safety_margin_gb\n        if available_for_batch <= 0:\n            logger.warning(\n                f\"[VRAM guard] Only {free_gb:.1f} GB free - reducing batch_size to 1\"\n            )\n            return 1\n\n        max_safe_batch = max(1, int(available_for_batch / per_sample_gb))\n        if max_safe_batch < batch_size:\n            logger.warning(\n                f\"[VRAM guard] Free VRAM {free_gb:.1f} GB can safely fit ~{max_safe_batch} samples \"\n                f\"(requested {batch_size}). Reducing batch_size to {max_safe_batch}.\"\n            )\n            return max_safe_batch\n        return batch_size\n\n    def _get_vae_dtype(self, device: Optional[str] = None) -> torch.dtype:\n        \"\"\"Get VAE dtype based on target device and GPU tier.\"\"\"\n        target_device = device or self.device\n        if _is_cuda_device(target_device):\n            if is_rocm_available():\n                # On ROCm, defer to self.dtype which is already set to a safe\n                # value (float32 by default, or ACESTEP_ROCM_DTYPE override).\n                return getattr(self, \"dtype\", torch.float32)\n            if cuda_supports_bfloat16(_cuda_device_index(target_device)):\n                return torch.bfloat16\n            return torch.float16\n        if target_device == \"xpu\":\n            return torch.bfloat16\n        if target_device == \"mps\":\n            return torch.float16\n        if target_device == \"cpu\":\n            return torch.float32\n        return self.dtype\n"
  },
  {
    "path": "acestep/core/generation/handler/metadata_utils.py",
    "content": "\"\"\"Metadata formatting helpers for handler decomposition.\"\"\"\n\nfrom typing import Any, Dict, List, Optional, Union\n\n\nclass MetadataMixin:\n    \"\"\"Mixin containing metadata parsing and formatting helpers.\n\n    Depends on host members:\n    - No cross-mixin runtime dependencies; pure formatting/parsing helpers.\n    \"\"\"\n\n    def _create_default_meta(self) -> str:\n        \"\"\"Create default metadata string.\"\"\"\n        return (\n            \"- bpm: N/A\\n\"\n            \"- timesignature: N/A\\n\"\n            \"- keyscale: N/A\\n\"\n            \"- duration: 30 seconds\\n\"\n        )\n\n    def _dict_to_meta_string(self, meta_dict: Dict[str, Any]) -> str:\n        \"\"\"Convert metadata dict to formatted string.\"\"\"\n        bpm = meta_dict.get(\"bpm\", meta_dict.get(\"tempo\", \"N/A\"))\n        timesignature = meta_dict.get(\"timesignature\", meta_dict.get(\"time_signature\", \"N/A\"))\n        keyscale = meta_dict.get(\"keyscale\", meta_dict.get(\"key\", meta_dict.get(\"scale\", \"N/A\")))\n        duration = meta_dict.get(\"duration\", meta_dict.get(\"length\", 30))\n\n        if isinstance(duration, (int, float)):\n            duration = f\"{int(duration)} seconds\"\n        elif not isinstance(duration, str):\n            duration = \"30 seconds\"\n\n        return (\n            f\"- bpm: {bpm}\\n\"\n            f\"- timesignature: {timesignature}\\n\"\n            f\"- keyscale: {keyscale}\\n\"\n            f\"- duration: {duration}\\n\"\n        )\n\n    def _parse_metas(self, metas: List[Union[str, Dict[str, Any]]]) -> List[str]:\n        \"\"\"Parse and normalize metadata values with safe fallbacks.\"\"\"\n        parsed_metas = []\n        for meta in metas:\n            if meta is None:\n                parsed_meta = self._create_default_meta()\n            elif isinstance(meta, str):\n                parsed_meta = meta\n            elif isinstance(meta, dict):\n                parsed_meta = self._dict_to_meta_string(meta)\n            else:\n                parsed_meta = self._create_default_meta()\n            parsed_metas.append(parsed_meta)\n        return parsed_metas\n\n    def prepare_metadata(\n        self, bpm: Optional[Union[int, str]], key_scale: str, time_signature: str\n    ) -> Dict[str, Any]:\n        \"\"\"Build metadata dict for generation.\"\"\"\n        return self._build_metadata_dict(bpm, key_scale, time_signature)\n\n    def _build_metadata_dict(\n        self,\n        bpm: Optional[Union[int, str]],\n        key_scale: str,\n        time_signature: str,\n        duration: Optional[float] = None,\n    ) -> Dict[str, Any]:\n        \"\"\"Build metadata dictionary with defaults for missing fields.\"\"\"\n        metadata_dict: Dict[str, Any] = {}\n        metadata_dict[\"bpm\"] = bpm if bpm else \"N/A\"\n        metadata_dict[\"keyscale\"] = key_scale if key_scale.strip() else \"N/A\"\n        if time_signature.strip() and time_signature != \"N/A\" and time_signature:\n            metadata_dict[\"timesignature\"] = time_signature\n        else:\n            metadata_dict[\"timesignature\"] = \"N/A\"\n        if duration is not None:\n            metadata_dict[\"duration\"] = f\"{int(duration)} seconds\"\n        return metadata_dict\n"
  },
  {
    "path": "acestep/core/generation/handler/mlx_dit_init.py",
    "content": "\"\"\"MLX DiT initialization helpers for Apple Silicon acceleration.\"\"\"\n\nfrom loguru import logger\n\n\nclass MlxDitInitMixin:\n    \"\"\"Initialize native MLX DiT decoder state used by generation runtime.\"\"\"\n\n    def _init_mlx_dit(self, compile_model: bool = False) -> bool:\n        \"\"\"Initialize the MLX DiT decoder when platform support is available.\n\n        Args:\n            compile_model: Whether MLX diffusion should use ``mx.compile``.\n\n        Returns:\n            bool: ``True`` when MLX DiT is initialized successfully, else ``False``.\n        \"\"\"\n        try:\n            from acestep.models.mlx import mlx_available\n\n            if not mlx_available():\n                logger.info(\"[MLX-DiT] MLX not available on this platform; skipping.\")\n                return False\n\n            from acestep.models.mlx.dit_model import MLXDiTDecoder\n            from acestep.models.mlx.dit_convert import convert_and_load\n\n            mlx_decoder = MLXDiTDecoder.from_config(self.config)\n            convert_and_load(self.model, mlx_decoder)\n            self.mlx_decoder = mlx_decoder\n            self.use_mlx_dit = True\n            self.mlx_dit_compiled = compile_model\n            logger.info(\n                \"[MLX-DiT] Native MLX DiT decoder initialized successfully \"\n                f\"(mx.compile={compile_model}).\"\n            )\n            return True\n        except Exception as exc:  # noqa: BLE001\n            logger.warning(f\"[MLX-DiT] Failed to initialize MLX decoder (non-fatal): {exc}\")\n            self.mlx_decoder = None\n            self.use_mlx_dit = False\n            self.mlx_dit_compiled = False\n            return False\n"
  },
  {
    "path": "acestep/core/generation/handler/mlx_dit_init_test.py",
    "content": "\"\"\"Unit tests for extracted MLX DiT initialization mixin.\"\"\"\n\nimport importlib.util\nimport sys\nimport types\nimport unittest\nfrom pathlib import Path\nfrom unittest.mock import Mock, patch\n\n\ndef _load_handler_module(filename: str, module_name: str):\n    \"\"\"Load handler mixin module directly from file path.\"\"\"\n    repo_root = Path(__file__).resolve().parents[4]\n    if str(repo_root) not in sys.path:\n        sys.path.insert(0, str(repo_root))\n    package_paths = {\n        \"acestep\": repo_root / \"acestep\",\n        \"acestep.core\": repo_root / \"acestep\" / \"core\",\n        \"acestep.core.generation\": repo_root / \"acestep\" / \"core\" / \"generation\",\n        \"acestep.core.generation.handler\": repo_root / \"acestep\" / \"core\" / \"generation\" / \"handler\",\n    }\n    for package_name, package_path in package_paths.items():\n        if package_name in sys.modules:\n            continue\n        package_module = types.ModuleType(package_name)\n        package_module.__path__ = [str(package_path)]\n        sys.modules[package_name] = package_module\n    module_path = Path(__file__).with_name(filename)\n    spec = importlib.util.spec_from_file_location(module_name, module_path)\n    module = importlib.util.module_from_spec(spec)\n    assert spec.loader is not None\n    spec.loader.exec_module(module)\n    return module\n\n\nMLX_DIT_INIT_MODULE = _load_handler_module(\n    \"mlx_dit_init.py\",\n    \"acestep.core.generation.handler.mlx_dit_init\",\n)\nMlxDitInitMixin = MLX_DIT_INIT_MODULE.MlxDitInitMixin\n\n\nclass _DitHost(MlxDitInitMixin):\n    \"\"\"Minimal host exposing DiT init state used by tests.\"\"\"\n\n    def __init__(self):\n        \"\"\"Initialize deterministic model/config placeholders.\"\"\"\n        self.config = {\"size\": \"tiny\"}\n        self.model = object()\n        self.mlx_decoder = None\n        self.use_mlx_dit = False\n        self.mlx_dit_compiled = False\n\n\nclass MlxDitInitMixinTests(unittest.TestCase):\n    \"\"\"Behavior tests for extracted ``MlxDitInitMixin``.\"\"\"\n\n    def test_init_mlx_dit_unavailable_returns_false(self):\n        \"\"\"It returns False and leaves MLX DiT flags unset when unavailable.\"\"\"\n        host = _DitHost()\n        fake_mlx = types.ModuleType(\"acestep.models.mlx\")\n        fake_mlx.mlx_available = lambda: False\n        with patch.dict(sys.modules, {\"acestep.models.mlx\": fake_mlx}):\n            self.assertFalse(host._init_mlx_dit(compile_model=True))\n        self.assertIsNone(host.mlx_decoder)\n        self.assertFalse(host.use_mlx_dit)\n\n    def test_init_mlx_dit_success_sets_decoder(self):\n        \"\"\"It loads converted MLX DiT decoder and stores compile flag.\"\"\"\n        host = _DitHost()\n        fake_mlx = types.ModuleType(\"acestep.models.mlx\")\n        fake_mlx.mlx_available = lambda: True\n        fake_dit_model = types.ModuleType(\"acestep.models.mlx.dit_model\")\n        fake_dit_model.MLXDiTDecoder = type(\n            \"FakeDecoder\",\n            (),\n            {\"from_config\": classmethod(lambda _cls, _cfg: object())},\n        )\n        fake_dit_convert = types.ModuleType(\"acestep.models.mlx.dit_convert\")\n        fake_dit_convert.convert_and_load = Mock()\n        with patch.dict(\n            sys.modules,\n            {\n                \"acestep.models.mlx\": fake_mlx,\n                \"acestep.models.mlx.dit_model\": fake_dit_model,\n                \"acestep.models.mlx.dit_convert\": fake_dit_convert,\n            },\n        ):\n            self.assertTrue(host._init_mlx_dit(compile_model=True))\n        self.assertTrue(host.use_mlx_dit)\n        self.assertTrue(host.mlx_dit_compiled)\n        fake_dit_convert.convert_and_load.assert_called_once()\n\n\nif __name__ == \"__main__\":\n    unittest.main()\n"
  },
  {
    "path": "acestep/core/generation/handler/mlx_vae_decode_native.py",
    "content": "\"\"\"Native MLX VAE decode helpers for latent-to-audio conversion.\"\"\"\n\nimport math\nimport time as _time\n\nimport numpy as np\nimport torch\nfrom loguru import logger\nfrom tqdm import tqdm\n\n\nclass MlxVaeDecodeNativeMixin:\n    \"\"\"Decode MLX latents with optional overlap-discard tiling.\"\"\"\n\n    def _resolve_mlx_decode_fn(self):\n        \"\"\"Resolve the active MLX decode callable from compiled or model state.\n\n        Returns:\n            Any: Callable that decodes ``[1, T, C]`` MLX latents.\n\n        Raises:\n            RuntimeError: If no compiled callable exists and ``self.mlx_vae`` is missing.\n        \"\"\"\n        decode_fn = getattr(self, \"_mlx_compiled_decode\", None)\n        if decode_fn is not None:\n            return decode_fn\n        if self.mlx_vae is None:\n            raise RuntimeError(\"MLX VAE decode requested but mlx_vae is not initialized.\")\n        return self.mlx_vae.decode\n\n    def _mlx_vae_decode(self, latents_torch):\n        \"\"\"Decode batched PyTorch latents using native MLX VAE decode.\n\n        Args:\n            latents_torch: Latent tensor shaped ``[batch, channels, frames]``.\n\n        Returns:\n            torch.Tensor: Decoded audio shaped ``[batch, channels, samples]``.\n        \"\"\"\n        import mlx.core as mx\n\n        t_start = _time.time()\n        latents_np = latents_torch.detach().cpu().float().numpy()\n        latents_nlc = np.transpose(latents_np, (0, 2, 1))\n        batch_size = latents_nlc.shape[0]\n        latent_frames = latents_nlc.shape[1]\n\n        vae_dtype = getattr(self, \"_mlx_vae_dtype\", mx.float32)\n        latents_mx = mx.array(latents_nlc).astype(vae_dtype)\n        t_convert = _time.time()\n\n        decode_fn = self._resolve_mlx_decode_fn()\n        audio_parts = []\n        for idx in range(batch_size):\n            decoded = self._mlx_decode_single(latents_mx[idx : idx + 1], decode_fn=decode_fn)\n            if decoded.dtype != mx.float32:\n                decoded = decoded.astype(mx.float32)\n            mx.eval(decoded)\n            audio_parts.append(np.array(decoded))\n            mx.clear_cache()\n\n        t_decode = _time.time()\n        audio_nlc = np.concatenate(audio_parts, axis=0)\n        audio_ncl = np.transpose(audio_nlc, (0, 2, 1))\n        elapsed = _time.time() - t_start\n        logger.info(\n            f\"[MLX-VAE] Decoded {batch_size} sample(s), {latent_frames} latent frames -> \"\n            f\"audio in {elapsed:.2f}s \"\n            f\"(convert={t_convert - t_start:.3f}s, decode={t_decode - t_convert:.2f}s, \"\n            f\"dtype={vae_dtype})\"\n        )\n        return torch.from_numpy(audio_ncl)\n\n    def _mlx_decode_single(self, z_nlc, decode_fn=None):\n        \"\"\"Decode a single MLX latent sample with optional tiling.\n\n        Args:\n            z_nlc: MLX array in ``[1, frames, channels]`` layout.\n            decode_fn: Optional decode callable; falls back to compiled decode.\n\n        Returns:\n            Any: MLX array in ``[1, samples, channels]`` layout.\n        \"\"\"\n        import mlx.core as mx\n\n        if decode_fn is None:\n            decode_fn = self._resolve_mlx_decode_fn()\n\n        latent_frames = z_nlc.shape[1]\n        mlx_chunk = 2048\n        mlx_overlap = 64\n\n        if latent_frames <= mlx_chunk:\n            return decode_fn(z_nlc)\n\n        stride = mlx_chunk - 2 * mlx_overlap\n        num_steps = math.ceil(latent_frames / stride)\n        decoded_parts = []\n        upsample_factor = None\n\n        for idx in tqdm(range(num_steps), desc=\"Decoding audio chunks\", disable=self.disable_tqdm):\n            core_start = idx * stride\n            core_end = min(core_start + stride, latent_frames)\n            win_start = max(0, core_start - mlx_overlap)\n            win_end = min(latent_frames, core_end + mlx_overlap)\n\n            chunk = z_nlc[:, win_start:win_end, :]\n            audio_chunk = decode_fn(chunk)\n            mx.eval(audio_chunk)\n            if upsample_factor is None:\n                upsample_factor = audio_chunk.shape[1] / chunk.shape[1]\n\n            trim_start = int(round((core_start - win_start) * upsample_factor))\n            trim_end = int(round((win_end - core_end) * upsample_factor))\n            audio_len = audio_chunk.shape[1]\n            end_idx = audio_len - trim_end if trim_end > 0 else audio_len\n            decoded_parts.append(audio_chunk[:, trim_start:end_idx, :])\n\n        return mx.concatenate(decoded_parts, axis=1)\n"
  },
  {
    "path": "acestep/core/generation/handler/mlx_vae_encode_native.py",
    "content": "\"\"\"Native MLX VAE encode helpers for audio-to-latent conversion.\"\"\"\n\nimport math\nimport time as _time\n\nimport numpy as np\nimport torch\nfrom loguru import logger\nfrom tqdm import tqdm\n\n\nclass MlxVaeEncodeNativeMixin:\n    \"\"\"Encode MLX audio samples into latent tensors with overlap-discard tiling.\"\"\"\n\n    def _resolve_mlx_encode_fn(self):\n        \"\"\"Resolve the active MLX encode callable from compiled or model state.\n\n        Returns:\n            Any: Callable that encodes ``[1, S, C]`` MLX audio samples.\n\n        Raises:\n            RuntimeError: If no compiled callable exists and ``self.mlx_vae`` is missing.\n        \"\"\"\n        encode_fn = getattr(self, \"_mlx_compiled_encode_sample\", None)\n        if encode_fn is not None:\n            return encode_fn\n        if self.mlx_vae is None:\n            raise RuntimeError(\"MLX VAE encode requested but mlx_vae is not initialized.\")\n        return self.mlx_vae.encode_and_sample\n\n    def _mlx_vae_encode_sample(self, audio_torch):\n        \"\"\"Encode batched PyTorch audio to MLX latents.\n\n        Args:\n            audio_torch: Audio tensor shaped ``[batch, channels, samples]``.\n\n        Returns:\n            torch.Tensor: Latent tensor shaped ``[batch, channels, frames]``.\n        \"\"\"\n        import mlx.core as mx\n\n        audio_np = audio_torch.detach().cpu().float().numpy()\n        audio_nlc = np.transpose(audio_np, (0, 2, 1))\n        batch_size = audio_nlc.shape[0]\n        sample_frames = audio_nlc.shape[1]\n\n        mlx_encode_chunk = 48000 * 30\n        mlx_encode_overlap = 48000 * 2\n        if sample_frames <= mlx_encode_chunk:\n            chunks_per_sample = 1\n        else:\n            stride = mlx_encode_chunk - 2 * mlx_encode_overlap\n            chunks_per_sample = math.ceil(sample_frames / stride)\n        total_work = batch_size * chunks_per_sample\n\n        t_start = _time.time()\n        vae_dtype = getattr(self, \"_mlx_vae_dtype\", mx.float32)\n        encode_fn = self._resolve_mlx_encode_fn()\n\n        latent_parts = []\n        pbar = tqdm(\n            total=total_work,\n            desc=f\"MLX VAE Encode (native, n={batch_size})\",\n            disable=self.disable_tqdm,\n            unit=\"chunk\",\n        )\n        for idx in range(batch_size):\n            single = mx.array(audio_nlc[idx : idx + 1])\n            if single.dtype != vae_dtype:\n                single = single.astype(vae_dtype)\n            latent = self._mlx_encode_single(single, pbar=pbar, encode_fn=encode_fn)\n            if latent.dtype != mx.float32:\n                latent = latent.astype(mx.float32)\n            mx.eval(latent)\n            latent_parts.append(np.array(latent))\n            mx.clear_cache()\n        pbar.close()\n\n        elapsed = _time.time() - t_start\n        logger.info(\n            f\"[MLX-VAE] Encoded {batch_size} sample(s), {sample_frames} audio frames -> \"\n            f\"latent in {elapsed:.2f}s (dtype={vae_dtype})\"\n        )\n\n        latent_nlc = np.concatenate(latent_parts, axis=0)\n        latent_ncl = np.transpose(latent_nlc, (0, 2, 1))\n        return torch.from_numpy(latent_ncl)\n\n    def _mlx_encode_single(self, audio_nlc, pbar=None, encode_fn=None):\n        \"\"\"Encode one MLX audio sample with optional overlap-discard tiling.\n\n        Args:\n            audio_nlc: MLX array in ``[1, samples, channels]`` layout.\n            pbar: Optional progress-bar object with ``update``.\n            encode_fn: Optional encode callable; falls back to compiled encode.\n\n        Returns:\n            Any: MLX array in ``[1, frames, channels]`` layout.\n        \"\"\"\n        import mlx.core as mx\n\n        if encode_fn is None:\n            encode_fn = self._resolve_mlx_encode_fn()\n\n        sample_frames = audio_nlc.shape[1]\n        mlx_encode_chunk = 48000 * 30\n        mlx_encode_overlap = 48000 * 2\n\n        if sample_frames <= mlx_encode_chunk:\n            result = encode_fn(audio_nlc)\n            mx.eval(result)\n            if pbar is not None:\n                pbar.update(1)\n            return result\n\n        stride = mlx_encode_chunk - 2 * mlx_encode_overlap\n        num_steps = math.ceil(sample_frames / stride)\n        encoded_parts = []\n        downsample_factor = None\n\n        for idx in range(num_steps):\n            core_start = idx * stride\n            core_end = min(core_start + stride, sample_frames)\n            win_start = max(0, core_start - mlx_encode_overlap)\n            win_end = min(sample_frames, core_end + mlx_encode_overlap)\n\n            chunk = audio_nlc[:, win_start:win_end, :]\n            latent_chunk = encode_fn(chunk)\n            mx.eval(latent_chunk)\n            if downsample_factor is None:\n                downsample_factor = chunk.shape[1] / latent_chunk.shape[1]\n\n            trim_start = int(round((core_start - win_start) / downsample_factor))\n            trim_end = int(round((win_end - core_end) / downsample_factor))\n            latent_len = latent_chunk.shape[1]\n            end_idx = latent_len - trim_end if trim_end > 0 else latent_len\n            encoded_parts.append(latent_chunk[:, trim_start:end_idx, :])\n            if pbar is not None:\n                pbar.update(1)\n\n        return mx.concatenate(encoded_parts, axis=1)\n"
  },
  {
    "path": "acestep/core/generation/handler/mlx_vae_init.py",
    "content": "\"\"\"MLX VAE initialization helpers for Apple Silicon acceleration.\"\"\"\n\nimport os\nfrom typing import Any\n\nfrom loguru import logger\n\n\nclass MlxVaeInitMixin:\n    \"\"\"Initialize native MLX VAE state and compiled decode/encode callables.\"\"\"\n\n    def _init_mlx_vae(self) -> bool:\n        \"\"\"Initialize native MLX VAE runtime state from ``self.vae``.\n\n        The ``_init_mlx_vae`` path converts the loaded PyTorch VAE in\n        ``self.vae`` to an MLX implementation, optionally applies float16\n        conversion based on ``ACESTEP_MLX_VAE_FP16``, and prepares decode/encode\n        callables.\n\n        Side effects:\n            Mutates ``self.mlx_vae`` and ``self.use_mlx_vae`` and updates\n            ``self._mlx_compiled_decode``, ``self._mlx_compiled_encode_sample``,\n            and ``self._mlx_vae_dtype``.\n\n        Returns:\n            bool: ``True`` when MLX VAE is initialized successfully, else ``False``.\n\n        Error behavior:\n            Returns ``False`` when MLX is unavailable or when any conversion/\n            initialization step raises an exception. Failures are logged as\n            non-fatal.\n        \"\"\"\n        try:\n            from acestep.models.mlx import mlx_available\n\n            if not mlx_available():\n                logger.info(\"[MLX-VAE] MLX not available on this platform; skipping.\")\n                return False\n\n            import mlx.core as mx\n            from mlx.utils import tree_map\n            from acestep.models.mlx.vae_model import MLXAutoEncoderOobleck\n            from acestep.models.mlx.vae_convert import convert_and_load\n\n            mlx_vae = MLXAutoEncoderOobleck.from_pytorch_config(self.vae)\n            convert_and_load(self.vae, mlx_vae)\n\n            use_fp16 = os.environ.get(\"ACESTEP_MLX_VAE_FP16\", \"0\").lower() in (\n                \"1\",\n                \"true\",\n                \"yes\",\n            )\n            vae_dtype = mx.float16 if use_fp16 else mx.float32\n\n            if use_fp16:\n                try:\n\n                    def _to_fp16(value: Any):\n                        \"\"\"Cast floating MLX arrays to float16 while preserving other values.\"\"\"\n                        if isinstance(value, mx.array) and mx.issubdtype(value.dtype, mx.floating):\n                            return value.astype(mx.float16)\n                        return value\n\n                    mlx_vae.update(tree_map(_to_fp16, mlx_vae.parameters()))\n                    mx.eval(mlx_vae.parameters())\n                    logger.info(\"[MLX-VAE] Model weights converted to float16.\")\n                except Exception as exc:\n                    logger.warning(f\"[MLX-VAE] Float16 conversion failed ({exc}); using float32.\")\n                    vae_dtype = mx.float32\n\n            compiled = True\n            try:\n                self._mlx_compiled_decode = mx.compile(mlx_vae.decode)\n                self._mlx_compiled_encode_sample = mx.compile(mlx_vae.encode_and_sample)\n                logger.info(\"[MLX-VAE] Decode/encode compiled with mx.compile().\")\n            except Exception as exc:\n                compiled = False\n                logger.warning(f\"[MLX-VAE] mx.compile() failed ({exc}); using uncompiled path.\")\n                self._mlx_compiled_decode = mlx_vae.decode\n                self._mlx_compiled_encode_sample = mlx_vae.encode_and_sample\n\n            self.mlx_vae = mlx_vae\n            self.use_mlx_vae = True\n            self._mlx_vae_dtype = vae_dtype\n            logger.info(\n                f\"[MLX-VAE] Native MLX VAE initialized (dtype={vae_dtype}, compiled={compiled}).\"\n            )\n            return True\n        except Exception as exc:\n            logger.warning(f\"[MLX-VAE] Failed to initialize MLX VAE (non-fatal): {exc}\")\n            self.mlx_vae = None\n            self.use_mlx_vae = False\n            self._mlx_compiled_decode = None\n            self._mlx_compiled_encode_sample = None\n            self._mlx_vae_dtype = None\n            return False\n"
  },
  {
    "path": "acestep/core/generation/handler/mlx_vae_init_test.py",
    "content": "\"\"\"Unit tests for extracted MLX VAE initialization mixin.\"\"\"\nimport importlib.util\nimport os\nimport sys\nimport types\nimport unittest\nfrom pathlib import Path\nfrom unittest.mock import Mock, patch\ndef _load_handler_module(filename: str, module_name: str) -> types.ModuleType:\n    \"\"\"Load a handler mixin module for isolated tests.\n\n    Args:\n        filename: Module filename in the current test directory.\n        module_name: Fully-qualified module name used for import execution.\n    Returns:\n        Loaded module object.\n    Raises:\n        FileNotFoundError, ImportError, SyntaxError: On module load failures.\n    \"\"\"\n    repo_root = Path(__file__).resolve().parents[4]\n    if str(repo_root) not in sys.path:\n        sys.path.insert(0, str(repo_root))\n    package_paths = {\n        \"acestep\": repo_root / \"acestep\",\n        \"acestep.core\": repo_root / \"acestep\" / \"core\",\n        \"acestep.core.generation\": repo_root / \"acestep\" / \"core\" / \"generation\",\n        \"acestep.core.generation.handler\": repo_root / \"acestep\" / \"core\" / \"generation\" / \"handler\",\n    }\n    previous_modules = {name: sys.modules.get(name) for name in package_paths}\n    try:\n        for package_name, package_path in package_paths.items():\n            if package_name in sys.modules:\n                continue\n            package_module = types.ModuleType(package_name)\n            package_module.__path__ = [str(package_path)]\n            sys.modules[package_name] = package_module\n        module_path = Path(__file__).with_name(filename)\n        spec = importlib.util.spec_from_file_location(module_name, module_path)\n        if spec is None or spec.loader is None:\n            raise ImportError(f\"Unable to load module spec for {module_name}\")\n        module = importlib.util.module_from_spec(spec)\n        spec.loader.exec_module(module)\n        return module\n    finally:\n        for package_name, previous in previous_modules.items():\n            if previous is None:\n                sys.modules.pop(package_name, None)\n            else:\n                sys.modules[package_name] = previous\nMLX_VAE_INIT_MODULE = _load_handler_module(\n    \"mlx_vae_init.py\",\n    \"acestep.core.generation.handler.mlx_vae_init\",\n)\nMlxVaeInitMixin = MLX_VAE_INIT_MODULE.MlxVaeInitMixin\nclass _VaeHost(MlxVaeInitMixin):\n    \"\"\"Minimal host exposing VAE init state used by tests.\"\"\"\n\n    def __init__(self):\n        \"\"\"Initialize deterministic VAE placeholders.\"\"\"\n        self.vae = object()\n        self.mlx_vae = None\n        self.use_mlx_vae = False\n        self._mlx_vae_dtype = None\nclass _FakeMlxVae:\n    \"\"\"Simple fake MLX VAE object with decode/encode callables.\"\"\"\n\n    def decode(self, value):\n        \"\"\"Return tagged decode output.\"\"\"\n        return (\"decode\", value)\n\n    def encode_and_sample(self, value):\n        \"\"\"Return tagged encode output.\"\"\"\n        return (\"encode\", value)\n\n    @classmethod\n    def from_pytorch_config(cls, _vae):\n        \"\"\"Build fake MLX VAE from PyTorch VAE placeholder.\"\"\"\n        return cls()\n\n    def update(self, _params):\n        \"\"\"Accept parameter update requests.\"\"\"\n        return None\n\n    def parameters(self):\n        \"\"\"Return placeholder params tree.\"\"\"\n        return {}\ndef _build_fake_mx_core(raise_compile: bool) -> tuple[types.ModuleType, dict[str, int]]:\n    \"\"\"Build fake ``mlx.core`` and compile-call tracking for tests.\n\n    Args:\n        raise_compile: Whether inner ``_compile`` raises ``CompileError``.\n    Returns:\n        ``(fake_mx_core, calls)`` where ``calls`` tracks ``_compile`` count.\n    Raises:\n        CompileError: Raised by ``_compile`` when ``raise_compile`` is True.\n    \"\"\"\n    class CompileError(RuntimeError):\n        \"\"\"Raised when fake MLX compile is configured to fail.\"\"\"\n\n    fake_mx_core = types.ModuleType(\"mlx.core\")\n    fake_mx_core.float16 = \"float16\"\n    fake_mx_core.float32 = \"float32\"\n    fake_mx_core.floating = \"floating\"\n    fake_mx_core.array = tuple\n    fake_mx_core.issubdtype = lambda *_args, **_kwargs: False\n    fake_mx_core.eval = lambda *_args, **_kwargs: None\n    calls = {\"compile\": 0}\n\n    def _compile(fn):\n        \"\"\"Track compile invocations and optionally simulate compile failure.\"\"\"\n        calls[\"compile\"] += 1\n        if raise_compile:\n            raise CompileError(\"compile failed\")\n        return fn\n\n    fake_mx_core.compile = _compile\n    return fake_mx_core, calls\nclass MlxVaeInitMixinTests(unittest.TestCase):\n    \"\"\"Behavior tests for extracted ``MlxVaeInitMixin``.\"\"\"\n\n    def test_init_mlx_vae_unavailable_returns_false(self):\n        \"\"\"It returns False and leaves MLX VAE flags unset when unavailable.\"\"\"\n        host = _VaeHost()\n        fake_mlx = types.ModuleType(\"acestep.models.mlx\")\n        fake_mlx.mlx_available = lambda: False\n        with patch.dict(sys.modules, {\"acestep.models.mlx\": fake_mlx}):\n            self.assertFalse(host._init_mlx_vae())\n        self.assertIsNone(host.mlx_vae)\n        self.assertFalse(host.use_mlx_vae)\n\n    def test_init_mlx_vae_success_sets_compiled_callables(self):\n        \"\"\"It initializes MLX VAE and stores compiled decode/encode callables.\"\"\"\n        host = _VaeHost()\n        fake_mx_core, calls = _build_fake_mx_core(raise_compile=False)\n        fake_mlx = types.ModuleType(\"acestep.models.mlx\")\n        fake_mlx.mlx_available = lambda: True\n        fake_vae_model = types.ModuleType(\"acestep.models.mlx.vae_model\")\n        fake_vae_model.MLXAutoEncoderOobleck = _FakeMlxVae\n        fake_vae_convert = types.ModuleType(\"acestep.models.mlx.vae_convert\")\n        fake_vae_convert.convert_and_load = Mock()\n        fake_mlx_pkg = types.ModuleType(\"mlx\")\n        fake_mlx_pkg.__path__ = []\n        fake_utils = types.ModuleType(\"mlx.utils\")\n        fake_utils.tree_map = lambda _fn, params: params\n        with patch.dict(\n            sys.modules,\n            {\n                \"mlx\": fake_mlx_pkg,\n                \"mlx.core\": fake_mx_core,\n                \"mlx.utils\": fake_utils,\n                \"acestep.models.mlx\": fake_mlx,\n                \"acestep.models.mlx.vae_model\": fake_vae_model,\n                \"acestep.models.mlx.vae_convert\": fake_vae_convert,\n            },\n        ):\n            with patch.dict(os.environ, {\"ACESTEP_MLX_VAE_FP16\": \"0\"}, clear=False):\n                self.assertTrue(host._init_mlx_vae())\n        self.assertEqual(calls[\"compile\"], 2)\n        self.assertTrue(host.use_mlx_vae)\n        self.assertEqual(host._mlx_vae_dtype, \"float32\")\n\n    def test_init_mlx_vae_compile_failure_falls_back(self):\n        \"\"\"It keeps uncompiled methods when ``mx.compile`` fails.\"\"\"\n        host = _VaeHost()\n        fake_mx_core, _calls = _build_fake_mx_core(raise_compile=True)\n        fake_mlx = types.ModuleType(\"acestep.models.mlx\")\n        fake_mlx.mlx_available = lambda: True\n        fake_vae_model = types.ModuleType(\"acestep.models.mlx.vae_model\")\n        fake_vae_model.MLXAutoEncoderOobleck = _FakeMlxVae\n        fake_vae_convert = types.ModuleType(\"acestep.models.mlx.vae_convert\")\n        fake_vae_convert.convert_and_load = Mock()\n        fake_mlx_pkg = types.ModuleType(\"mlx\")\n        fake_mlx_pkg.__path__ = []\n        fake_utils = types.ModuleType(\"mlx.utils\")\n        fake_utils.tree_map = lambda _fn, params: params\n        with patch.dict(\n            sys.modules,\n            {\n                \"mlx\": fake_mlx_pkg,\n                \"mlx.core\": fake_mx_core,\n                \"mlx.utils\": fake_utils,\n                \"acestep.models.mlx\": fake_mlx,\n                \"acestep.models.mlx.vae_model\": fake_vae_model,\n                \"acestep.models.mlx.vae_convert\": fake_vae_convert,\n            },\n        ):\n            self.assertTrue(host._init_mlx_vae())\n        self.assertEqual(host._mlx_compiled_decode(\"x\"), host.mlx_vae.decode(\"x\"))\n        self.assertEqual(host._mlx_compiled_encode_sample(\"x\"), host.mlx_vae.encode_and_sample(\"x\"))\nif __name__ == \"__main__\":\n    unittest.main()\n"
  },
  {
    "path": "acestep/core/generation/handler/mlx_vae_native_test.py",
    "content": "\"\"\"Unit tests for extracted native MLX VAE encode/decode mixins.\"\"\"\nimport importlib.util\nimport sys\nimport types\nimport unittest\nfrom pathlib import Path\n\nimport numpy as np\nimport torch\nfrom unittest.mock import patch\ndef _load_handler_module(module_filename: str, module_name: str):\n    \"\"\"Load a handler mixin module directly from disk for isolated tests.\"\"\"\n    repo_root = Path(__file__).resolve().parents[4]\n    if str(repo_root) not in sys.path:\n        sys.path.insert(0, str(repo_root))\n    package_paths = {\n        \"acestep\": repo_root / \"acestep\",\n        \"acestep.core\": repo_root / \"acestep\" / \"core\",\n        \"acestep.core.generation\": repo_root / \"acestep\" / \"core\" / \"generation\",\n        \"acestep.core.generation.handler\": repo_root / \"acestep\" / \"core\" / \"generation\" / \"handler\",\n    }\n    for package_name, package_path in package_paths.items():\n        if package_name in sys.modules:\n            continue\n        package_module = types.ModuleType(package_name)\n        package_module.__path__ = [str(package_path)]\n        sys.modules[package_name] = package_module\n    module_path = Path(__file__).with_name(module_filename)\n    spec = importlib.util.spec_from_file_location(module_name, module_path)\n    module = importlib.util.module_from_spec(spec)\n    assert spec.loader is not None\n    spec.loader.exec_module(module)\n    return module\nMLX_VAE_DECODE_NATIVE_MODULE = _load_handler_module(\n    \"mlx_vae_decode_native.py\",\n    \"acestep.core.generation.handler.mlx_vae_decode_native\",\n)\nMLX_VAE_ENCODE_NATIVE_MODULE = _load_handler_module(\n    \"mlx_vae_encode_native.py\",\n    \"acestep.core.generation.handler.mlx_vae_encode_native\",\n)\nMlxVaeDecodeNativeMixin = MLX_VAE_DECODE_NATIVE_MODULE.MlxVaeDecodeNativeMixin\nMlxVaeEncodeNativeMixin = MLX_VAE_ENCODE_NATIVE_MODULE.MlxVaeEncodeNativeMixin\n\n\nclass _Progress:\n    \"\"\"Minimal progress object tracking update calls.\"\"\"\n\n    def __init__(self, *_args, **_kwargs):\n        \"\"\"Initialize an empty update counter.\"\"\"\n        self.count = 0\n\n    def update(self, amount):\n        \"\"\"Record update increments from mixin helpers.\"\"\"\n        self.count += amount\n\n    def close(self):\n        \"\"\"Provide close API parity with tqdm.\"\"\"\n        return None\n\n\nclass _Host(MlxVaeDecodeNativeMixin, MlxVaeEncodeNativeMixin):\n    \"\"\"Minimal host exposing extracted native MLX encode/decode helper methods.\"\"\"\n\n    def __init__(self):\n        \"\"\"Initialize fake MLX runtime attributes used by helper methods.\"\"\"\n        self.disable_tqdm = True\n        self._mlx_vae_dtype = np.float32\n        self.mlx_vae = types.SimpleNamespace(\n            decode=lambda chunk: np.repeat(chunk, 2, axis=1),\n            encode_and_sample=lambda chunk: chunk[:, ::2, :],\n        )\n        self._mlx_compiled_decode = self.mlx_vae.decode\n        self._mlx_compiled_encode_sample = self.mlx_vae.encode_and_sample\n\n\ndef _fake_mx_core_module():\n    \"\"\"Create a minimal fake ``mlx.core`` module backed by NumPy arrays.\"\"\"\n    fake_mx_core = types.ModuleType(\"mlx.core\")\n    fake_mx_core.float32 = np.float32\n    fake_mx_core.float16 = np.float16\n    fake_mx_core.array = lambda values: np.array(values)\n    fake_mx_core.eval = lambda *_args, **_kwargs: None\n    fake_mx_core.clear_cache = lambda *_args, **_kwargs: None\n    fake_mx_core.concatenate = lambda values, axis=0: np.concatenate(values, axis=axis)\n    return fake_mx_core\n\n\nclass MlxVaeNativeMixinTests(unittest.TestCase):\n    \"\"\"Behavior tests for extracted native MLX VAE encode/decode helpers.\"\"\"\n\n    def test_mlx_decode_single_without_tiling_uses_decode_fn(self):\n        \"\"\"It decodes short sequences without entering overlap-discard tiling.\"\"\"\n        host = _Host()\n        fake_mx_core = _fake_mx_core_module()\n        fake_mlx_pkg = types.ModuleType(\"mlx\")\n        fake_mlx_pkg.__path__ = []\n        z_nlc = np.ones((1, 64, 1), dtype=np.float32)\n        def decode_fn(chunk):\n            \"\"\"Expand latent time axis by factor two for decode test behavior.\"\"\"\n            return np.repeat(chunk, 2, axis=1)\n        with patch.dict(sys.modules, {\"mlx\": fake_mlx_pkg, \"mlx.core\": fake_mx_core}):\n            out = host._mlx_decode_single(z_nlc, decode_fn=decode_fn)\n        self.assertEqual(tuple(out.shape), (1, 128, 1))\n\n    def test_mlx_decode_single_with_tiling_concatenates_trimmed_chunks(self):\n        \"\"\"It applies overlap-discard tiling for long latent sequences.\"\"\"\n        host = _Host()\n        fake_mx_core = _fake_mx_core_module()\n        fake_mlx_pkg = types.ModuleType(\"mlx\")\n        fake_mlx_pkg.__path__ = []\n        z_nlc = np.ones((1, 2200, 1), dtype=np.float32)\n        def decode_fn(chunk):\n            \"\"\"Expand latent time axis by factor two for tiled decode test behavior.\"\"\"\n            return np.repeat(chunk, 2, axis=1)\n        with patch.dict(sys.modules, {\"mlx\": fake_mlx_pkg, \"mlx.core\": fake_mx_core}):\n            out = host._mlx_decode_single(z_nlc, decode_fn=decode_fn)\n        self.assertEqual(tuple(out.shape), (1, 4400, 1))\n\n    def test_mlx_vae_decode_returns_torch_tensor_with_expected_shape(self):\n        \"\"\"It converts NCL latents to MLX, decodes, and returns NCL torch tensor.\"\"\"\n        host = _Host()\n        fake_mx_core = _fake_mx_core_module()\n        fake_mlx_pkg = types.ModuleType(\"mlx\")\n        fake_mlx_pkg.__path__ = []\n        latents = torch.ones(2, 1, 32, dtype=torch.float32)\n        with patch.dict(sys.modules, {\"mlx\": fake_mlx_pkg, \"mlx.core\": fake_mx_core}):\n            out = host._mlx_vae_decode(latents)\n        self.assertEqual(tuple(out.shape), (2, 1, 64))\n        self.assertIsInstance(out, torch.Tensor)\n\n    def test_mlx_encode_single_without_tiling_updates_progress(self):\n        \"\"\"It encodes short audio in one pass and updates progress once.\"\"\"\n        host = _Host()\n        fake_mx_core = _fake_mx_core_module()\n        fake_mlx_pkg = types.ModuleType(\"mlx\")\n        fake_mlx_pkg.__path__ = []\n        progress = _Progress()\n        audio_nlc = np.ones((1, 1000, 1), dtype=np.float32)\n        with patch.dict(sys.modules, {\"mlx\": fake_mlx_pkg, \"mlx.core\": fake_mx_core}):\n            out = host._mlx_encode_single(audio_nlc, pbar=progress)\n        self.assertEqual(tuple(out.shape), (1, 500, 1))\n        self.assertEqual(progress.count, 1)\n\n    def test_mlx_encode_single_with_tiling_updates_progress_per_chunk(self):\n        \"\"\"It applies overlap-discard tiling for long audio inputs.\"\"\"\n        host = _Host()\n        fake_mx_core = _fake_mx_core_module()\n        fake_mlx_pkg = types.ModuleType(\"mlx\")\n        fake_mlx_pkg.__path__ = []\n        progress = _Progress()\n        audio_nlc = np.ones((1, 1_500_000, 1), dtype=np.float32)\n        with patch.dict(sys.modules, {\"mlx\": fake_mlx_pkg, \"mlx.core\": fake_mx_core}):\n            out = host._mlx_encode_single(audio_nlc, pbar=progress)\n        self.assertTrue(out.shape[1] > 0)\n        self.assertEqual(progress.count, 2)\n\n    def test_mlx_vae_encode_sample_returns_torch_tensor(self):\n        \"\"\"It encodes batched audio and returns NCL torch latents.\"\"\"\n        host = _Host()\n        fake_mx_core = _fake_mx_core_module()\n        fake_mlx_pkg = types.ModuleType(\"mlx\")\n        fake_mlx_pkg.__path__ = []\n        audio = torch.ones(2, 1, 1200, dtype=torch.float32)\n        with patch.dict(sys.modules, {\"mlx\": fake_mlx_pkg, \"mlx.core\": fake_mx_core}):\n            with patch.object(MLX_VAE_ENCODE_NATIVE_MODULE, \"tqdm\", _Progress):\n                out = host._mlx_vae_encode_sample(audio)\n        self.assertIsInstance(out, torch.Tensor)\n        self.assertEqual(tuple(out.shape), (2, 1, 600))\n\n    def test_mlx_decode_single_raises_when_mlx_vae_missing(self):\n        \"\"\"It raises a clear runtime error when decode is requested without MLX VAE.\"\"\"\n        host = _Host()\n        host._mlx_compiled_decode = None\n        host.mlx_vae = None\n        fake_mx_core = _fake_mx_core_module()\n        fake_mlx_pkg = types.ModuleType(\"mlx\")\n        fake_mlx_pkg.__path__ = []\n        with patch.dict(sys.modules, {\"mlx\": fake_mlx_pkg, \"mlx.core\": fake_mx_core}):\n            with self.assertRaises(RuntimeError) as ctx:\n                host._mlx_decode_single(np.ones((1, 16, 1), dtype=np.float32))\n        self.assertIn(\"mlx_vae is not initialized\", str(ctx.exception))\n\n    def test_mlx_encode_single_raises_when_mlx_vae_missing(self):\n        \"\"\"It raises a clear runtime error when encode is requested without MLX VAE.\"\"\"\n        host = _Host()\n        host._mlx_compiled_encode_sample = None\n        host.mlx_vae = None\n        fake_mx_core = _fake_mx_core_module()\n        fake_mlx_pkg = types.ModuleType(\"mlx\")\n        fake_mlx_pkg.__path__ = []\n        with patch.dict(sys.modules, {\"mlx\": fake_mlx_pkg, \"mlx.core\": fake_mx_core}):\n            with self.assertRaises(RuntimeError) as ctx:\n                host._mlx_encode_single(np.ones((1, 1000, 1), dtype=np.float32))\n        self.assertIn(\"mlx_vae is not initialized\", str(ctx.exception))\n\n\nif __name__ == \"__main__\":\n    unittest.main()\n"
  },
  {
    "path": "acestep/core/generation/handler/padding_utils.py",
    "content": "\"\"\"Padding helpers for handler batch preparation.\"\"\"\n\nimport torch\nfrom loguru import logger\n\n\nclass PaddingMixin:\n    \"\"\"Mixin containing repaint/lego padding helpers.\n\n    Depends on host members:\n    - Method: ``create_target_wavs`` (provided by ``TaskUtilsMixin`` in this decomposition).\n    \"\"\"\n\n    def prepare_padding_info(\n        self,\n        actual_batch_size,\n        processed_src_audio,\n        audio_duration,\n        repainting_start,\n        repainting_end,\n        is_repaint_task,\n        is_lego_task,\n        is_cover_task,\n        can_use_repainting,\n    ):\n        \"\"\"Prepare padded target wavs and repaint coordinates for each batch item.\"\"\"\n        try:\n            target_wavs_batch = []\n            # Store padding info for each batch item to adjust repainting coordinates\n            padding_info_batch = []\n            for i in range(actual_batch_size):\n                if processed_src_audio is not None:\n                    if is_cover_task:\n                        # Cover task: Use src_audio directly without padding\n                        batch_target_wavs = processed_src_audio\n                        padding_info_batch.append({\"left_padding_duration\": 0.0, \"right_padding_duration\": 0.0})\n                    elif is_repaint_task or is_lego_task:\n                        # Repaint/lego task: May need padding for outpainting\n                        src_audio_duration = processed_src_audio.shape[-1] / 48000.0\n\n                        # Determine actual end time\n                        if repainting_end is None or repainting_end < 0:\n                            actual_end = src_audio_duration\n                        else:\n                            actual_end = repainting_end\n\n                        left_padding_duration = max(0, -repainting_start) if repainting_start is not None else 0\n                        right_padding_duration = max(0, actual_end - src_audio_duration)\n\n                        # Create padded audio\n                        left_padding_frames = int(left_padding_duration * 48000)\n                        right_padding_frames = int(right_padding_duration * 48000)\n\n                        if left_padding_frames > 0 or right_padding_frames > 0:\n                            # Pad the src audio\n                            batch_target_wavs = torch.nn.functional.pad(\n                                processed_src_audio, (left_padding_frames, right_padding_frames), \"constant\", 0\n                            )\n                        else:\n                            batch_target_wavs = processed_src_audio\n\n                        # Store padding info for coordinate adjustment\n                        padding_info_batch.append(\n                            {\n                                \"left_padding_duration\": left_padding_duration,\n                                \"right_padding_duration\": right_padding_duration,\n                            }\n                        )\n                    else:\n                        # Other tasks: Use src_audio directly without padding\n                        batch_target_wavs = processed_src_audio\n                        padding_info_batch.append({\"left_padding_duration\": 0.0, \"right_padding_duration\": 0.0})\n                else:\n                    padding_info_batch.append({\"left_padding_duration\": 0.0, \"right_padding_duration\": 0.0})\n                    if audio_duration is not None and float(audio_duration) > 0:\n                        batch_target_wavs = self.create_target_wavs(float(audio_duration))\n                    else:\n                        import random\n\n                        random_duration = random.uniform(10.0, 120.0)\n                        batch_target_wavs = self.create_target_wavs(random_duration)\n                target_wavs_batch.append(batch_target_wavs)\n\n            # Stack target_wavs into batch tensor\n            # Ensure all tensors have the same shape by padding to max length\n            max_frames = max(wav.shape[-1] for wav in target_wavs_batch)\n            padded_target_wavs = []\n            for wav in target_wavs_batch:\n                if wav.shape[-1] < max_frames:\n                    pad_frames = max_frames - wav.shape[-1]\n                    padded_wav = torch.nn.functional.pad(wav, (0, pad_frames), \"constant\", 0)\n                    padded_target_wavs.append(padded_wav)\n                else:\n                    padded_target_wavs.append(wav)\n\n            target_wavs_tensor = torch.stack(padded_target_wavs, dim=0)  # [batch_size, 2, frames]\n\n            if can_use_repainting:\n                # Repaint task: Set repainting parameters\n                if repainting_start is None:\n                    repainting_start_batch = None\n                elif isinstance(repainting_start, (int, float)):\n                    if processed_src_audio is not None:\n                        adjusted_start = repainting_start + padding_info_batch[0][\"left_padding_duration\"]\n                        repainting_start_batch = [adjusted_start] * actual_batch_size\n                    else:\n                        repainting_start_batch = [repainting_start] * actual_batch_size\n                else:\n                    # List input - adjust each item\n                    repainting_start_batch = []\n                    for i in range(actual_batch_size):\n                        if processed_src_audio is not None:\n                            adjusted_start = repainting_start[i] + padding_info_batch[i][\"left_padding_duration\"]\n                            repainting_start_batch.append(adjusted_start)\n                        else:\n                            repainting_start_batch.append(repainting_start[i])\n\n                # Handle repainting_end - use src audio duration if not specified or negative\n                if processed_src_audio is not None:\n                    # If src audio is provided, use its duration as default end\n                    src_audio_duration = processed_src_audio.shape[-1] / 48000.0\n                    if repainting_end is None or repainting_end < 0:\n                        # Use src audio duration (before padding), then adjust for padding\n                        adjusted_end = src_audio_duration + padding_info_batch[0][\"left_padding_duration\"]\n                        repainting_end_batch = [adjusted_end] * actual_batch_size\n                    else:\n                        # Adjust repainting_end to be relative to padded audio\n                        adjusted_end = repainting_end + padding_info_batch[0][\"left_padding_duration\"]\n                        repainting_end_batch = [adjusted_end] * actual_batch_size\n                else:\n                    # No src audio - repainting doesn't make sense without it\n                    if repainting_end is None or repainting_end < 0:\n                        repainting_end_batch = None\n                    elif isinstance(repainting_end, (int, float)):\n                        repainting_end_batch = [repainting_end] * actual_batch_size\n                    else:\n                        # List input - adjust each item\n                        repainting_end_batch = []\n                        for i in range(actual_batch_size):\n                            repainting_end_batch.append(repainting_end[i])\n            else:\n                # All other tasks (cover, text2music, extract, complete): No repainting\n                # Only repaint and lego tasks should have repainting parameters\n                repainting_start_batch = None\n                repainting_end_batch = None\n\n            return repainting_start_batch, repainting_end_batch, target_wavs_tensor\n        except (TypeError, ValueError, RuntimeError, IndexError):\n            logger.exception(\"[prepare_padding_info] Error preparing padding information\")\n            fallback = torch.stack([self.create_target_wavs(30.0) for _ in range(actual_batch_size)], dim=0)\n            return None, None, fallback\n"
  },
  {
    "path": "acestep/core/generation/handler/progress.py",
    "content": "\"\"\"Progress estimation mixin for AceStepHandler.\"\"\"\n\nimport json\nimport os\nimport threading\nimport time\nfrom typing import Optional\n\nfrom loguru import logger\n\n# Conservative per-step estimate used when no historical timing data exists\n# (i.e., first-ever generation on this machine).  2.5s/step is deliberately\n# slow so the progress bar undershoots rather than overshoots — reaching 79%\n# early and pausing is far less alarming than freezing at 52% with zero\n# movement.  The estimate self-corrects after the first successful generation.\n_FALLBACK_PER_STEP_SEC = 2.5\n\n\nclass ProgressMixin:\n    def _get_project_root(self) -> str:\n        \"\"\"Get project root directory path.\n\n        Returns the directory set by the ``ACESTEP_PROJECT_ROOT`` environment\n        variable when present, otherwise the current working directory.  Using\n        the working directory (rather than ``__file__``) keeps generated cache\n        files and the checkpoints folder next to where the user launched the\n        process, regardless of whether the package was installed via\n        ``pip install .`` or run from source.\n        \"\"\"\n        env_root = os.environ.get(\"ACESTEP_PROJECT_ROOT\")\n        if env_root:\n            return os.path.abspath(env_root)\n        return os.getcwd()\n\n    def _load_progress_estimates(self) -> None:\n        \"\"\"Load persisted diffusion progress estimates if available.\"\"\"\n        try:\n            if os.path.exists(self._progress_estimates_path):\n                with open(self._progress_estimates_path, \"r\", encoding=\"utf-8\") as f:\n                    data = json.load(f)\n                    if isinstance(data, dict) and isinstance(data.get(\"records\"), list):\n                        self._progress_estimates = data\n        except Exception:\n            # Ignore corrupted cache; it will be overwritten on next save.\n            self._progress_estimates = {\"records\": []}\n\n    def _save_progress_estimates(self) -> None:\n        \"\"\"Persist diffusion progress estimates.\"\"\"\n        try:\n            os.makedirs(os.path.dirname(self._progress_estimates_path), exist_ok=True)\n            with open(self._progress_estimates_path, \"w\", encoding=\"utf-8\") as f:\n                json.dump(self._progress_estimates, f)\n        except Exception:\n            pass\n\n    def _duration_bucket(self, duration_sec: Optional[float]) -> str:\n        if duration_sec is None or duration_sec <= 0:\n            return \"unknown\"\n        if duration_sec <= 60:\n            return \"short\"\n        if duration_sec <= 180:\n            return \"medium\"\n        if duration_sec <= 360:\n            return \"long\"\n        return \"xlong\"\n\n    def _update_progress_estimate(\n        self,\n        per_step_sec: float,\n        infer_steps: int,\n        batch_size: int,\n        duration_sec: Optional[float],\n    ) -> None:\n        if per_step_sec <= 0 or infer_steps <= 0:\n            return\n        record = {\n            \"device\": self.device,\n            \"infer_steps\": int(infer_steps),\n            \"batch_size\": int(batch_size),\n            \"duration_sec\": float(duration_sec) if duration_sec and duration_sec > 0 else None,\n            \"duration_bucket\": self._duration_bucket(duration_sec),\n            \"per_step_sec\": float(per_step_sec),\n            \"updated_at\": time.time(),\n        }\n        with self._progress_estimates_lock:\n            records = self._progress_estimates.get(\"records\", [])\n            records.append(record)\n            # Keep recent 100 records\n            records = records[-100:]\n            self._progress_estimates[\"records\"] = records\n            self._progress_estimates[\"updated_at\"] = time.time()\n            self._save_progress_estimates()\n\n    def _estimate_diffusion_per_step(\n        self,\n        infer_steps: int,\n        batch_size: int,\n        duration_sec: Optional[float],\n    ) -> Optional[float]:\n        # Prefer most recent exact-ish record\n        target_bucket = self._duration_bucket(duration_sec)\n        with self._progress_estimates_lock:\n            records = list(self._progress_estimates.get(\"records\", []))\n        if not records:\n            return None\n\n        # Filter by device first\n        device_records = [r for r in records if r.get(\"device\") == self.device] or records\n\n        # Exact match by steps/batch/bucket\n        for r in reversed(device_records):\n            if (\n                r.get(\"infer_steps\") == infer_steps\n                and r.get(\"batch_size\") == batch_size\n                and r.get(\"duration_bucket\") == target_bucket\n            ):\n                return r.get(\"per_step_sec\")\n\n        # Same steps + bucket, scale by batch and duration when possible\n        for r in reversed(device_records):\n            if r.get(\"infer_steps\") == infer_steps and r.get(\"duration_bucket\") == target_bucket:\n                base = r.get(\"per_step_sec\")\n                base_batch = r.get(\"batch_size\", batch_size)\n                base_dur = r.get(\"duration_sec\")\n                if base and base_batch:\n                    est = base * (batch_size / base_batch)\n                    if duration_sec and base_dur:\n                        est *= (duration_sec / base_dur)\n                    return est\n\n        # Same steps, scale by batch and duration ratio if available\n        for r in reversed(device_records):\n            if r.get(\"infer_steps\") == infer_steps:\n                base = r.get(\"per_step_sec\")\n                base_batch = r.get(\"batch_size\", batch_size)\n                base_dur = r.get(\"duration_sec\")\n                if base and base_batch:\n                    est = base * (batch_size / base_batch)\n                    if duration_sec and base_dur:\n                        est *= (duration_sec / base_dur)\n                    return est\n\n        # Fallback to global median\n        per_steps = [r.get(\"per_step_sec\") for r in device_records if r.get(\"per_step_sec\")]\n        if per_steps:\n            per_steps.sort()\n            return per_steps[len(per_steps) // 2]\n        return None\n\n    def _start_diffusion_progress_estimator(\n        self,\n        progress,\n        start: float,\n        end: float,\n        infer_steps: int,\n        batch_size: int,\n        duration_sec: Optional[float],\n        desc: str,\n    ):\n        \"\"\"Best-effort progress updates during diffusion using previous step timing.\n\n        Falls back to a conservative default estimate when no historical data\n        exists (first-ever generation).  This ensures the progress bar always\n        moves during Phase 2 instead of freezing at 52%.\n        \"\"\"\n        if progress is None or infer_steps <= 0:\n            return None, None\n        per_step = self._estimate_diffusion_per_step(\n            infer_steps=infer_steps,\n            batch_size=batch_size,\n            duration_sec=duration_sec,\n        ) or self._last_diffusion_per_step_sec\n\n        if not per_step or per_step <= 0:\n            # No history at all — use conservative fallback so progress bar\n            # still moves on first run.  Scale by batch size for a rough\n            # approximation.\n            per_step = _FALLBACK_PER_STEP_SEC * max(1, batch_size)\n            logger.info(\n                f\"[progress] No timing history — using fallback estimate \"\n                f\"({per_step:.1f}s/step for batch_size={batch_size}).  \"\n                f\"This will self-calibrate after the first generation.\"\n            )\n\n        expected = per_step * infer_steps\n        if expected <= 0:\n            return None, None\n        stop_event = threading.Event()\n\n        def _runner():\n            start_time = time.time()\n            while not stop_event.is_set():\n                elapsed = time.time() - start_time\n                frac = min(0.999, elapsed / expected)\n                value = start + (end - start) * frac\n                try:\n                    progress(value, desc=desc)\n                except Exception:\n                    pass\n                stop_event.wait(0.5)\n\n        thread = threading.Thread(target=_runner, name=\"diffusion-progress\", daemon=True)\n        thread.start()\n        return stop_event, thread"
  },
  {
    "path": "acestep/core/generation/handler/progress_project_root_test.py",
    "content": "\"\"\"Unit tests for ProgressMixin._get_project_root path resolution.\"\"\"\n\nimport importlib.util\nimport os\nimport sys\nimport tempfile\nimport unittest\nfrom pathlib import Path\nfrom unittest.mock import patch\n\n\ndef _load_progress_mixin():\n    \"\"\"Load ProgressMixin directly without importing the full handler package.\"\"\"\n    spec = importlib.util.spec_from_file_location(\n        \"progress\",\n        os.path.join(os.path.dirname(__file__), \"progress.py\"),\n    )\n    mod = importlib.util.module_from_spec(spec)\n    spec.loader.exec_module(mod)\n    return mod.ProgressMixin\n\n\nclass TestProgressMixinGetProjectRoot(unittest.TestCase):\n    \"\"\"Tests for ProgressMixin._get_project_root().\"\"\"\n\n    def _make_host(self):\n        ProgressMixin = _load_progress_mixin()\n\n        class Host(ProgressMixin):\n            def __init__(self):\n                self._last_diffusion_per_step_sec = None\n                self._progress_estimates_lock = __import__(\"threading\").Lock()\n                self._progress_estimates = {\"records\": []}\n                self._progress_estimates_path = os.path.join(\n                    tempfile.gettempdir(), \"test_progress_estimates.json\"\n                )\n\n        return Host()\n\n    def test_returns_cwd_by_default(self):\n        \"\"\"_get_project_root returns the current working directory when no env var is set.\"\"\"\n        host = self._make_host()\n        env = {k: v for k, v in os.environ.items() if k != \"ACESTEP_PROJECT_ROOT\"}\n        with patch.dict(os.environ, env, clear=True):\n            result = host._get_project_root()\n        self.assertEqual(result, os.getcwd())\n\n    def test_returns_env_var_when_set(self):\n        \"\"\"_get_project_root returns the ACESTEP_PROJECT_ROOT env var path when set.\"\"\"\n        with tempfile.TemporaryDirectory() as tmp_dir:\n            host = self._make_host()\n            with patch.dict(os.environ, {\"ACESTEP_PROJECT_ROOT\": tmp_dir}):\n                result = host._get_project_root()\n            self.assertEqual(result, os.path.abspath(tmp_dir))\n\n    def test_env_var_takes_precedence_over_cwd(self):\n        \"\"\"ACESTEP_PROJECT_ROOT overrides the current working directory.\"\"\"\n        with tempfile.TemporaryDirectory() as tmp_dir:\n            host = self._make_host()\n            with patch.dict(os.environ, {\"ACESTEP_PROJECT_ROOT\": tmp_dir}):\n                result = host._get_project_root()\n            self.assertNotEqual(result, os.getcwd())\n            self.assertEqual(result, os.path.abspath(tmp_dir))\n\n    def test_does_not_use_file_location(self):\n        \"\"\"_get_project_root must not return a path derived from __file__ (site-packages fix).\"\"\"\n        host = self._make_host()\n        env = {k: v for k, v in os.environ.items() if k != \"ACESTEP_PROJECT_ROOT\"}\n        with patch.dict(os.environ, env, clear=True):\n            result = host._get_project_root()\n        # The result must equal os.getcwd(), not the directory of progress.py\n        progress_file_dir = os.path.dirname(os.path.abspath(__file__))\n        self.assertNotEqual(result, progress_file_dir)\n        self.assertEqual(result, os.getcwd())\n\n\nif __name__ == \"__main__\":\n    unittest.main()\n"
  },
  {
    "path": "acestep/core/generation/handler/prompt_utils.py",
    "content": "\"\"\"Prompt and text-input helpers for handler decomposition.\"\"\"\n\nimport re\nfrom typing import Any, Dict, List, Optional, Tuple, Union\n\nimport torch\nfrom loguru import logger\n\nfrom acestep.constants import DEFAULT_DIT_INSTRUCTION, SFT_GEN_PROMPT\n\n\nclass PromptMixin:\n    \"\"\"Mixin containing prompt formatting and text-encoder helpers.\n\n    Depends on host members:\n    - Attributes: ``text_tokenizer``, ``text_encoder``, ``device``, ``dtype``.\n    - Methods: ``_parse_metas`` (from ``MetadataMixin``), ``_load_model_context``\n      (from ``InitServiceMixin``).\n    \"\"\"\n\n    def _format_instruction(self, instruction: str) -> str:\n        \"\"\"Ensure instruction ends with a colon.\"\"\"\n        if not instruction.endswith(\":\"):\n            instruction = instruction + \":\"\n        return instruction\n\n    def _format_lyrics(self, lyrics: str, language: str) -> str:\n        \"\"\"Format lyrics text with language header.\"\"\"\n        return f\"# Languages\\n{language}\\n\\n# Lyric\\n{lyrics}<|endoftext|>\"\n\n    def _pad_sequences(\n        self, sequences: List[torch.Tensor], max_length: int, pad_value: int = 0\n    ) -> torch.Tensor:\n        \"\"\"Pad sequence tensors to the same length.\"\"\"\n        return torch.stack(\n            [\n                torch.nn.functional.pad(seq, (0, max_length - len(seq)), \"constant\", pad_value)\n                for seq in sequences\n            ]\n        )\n\n    def extract_caption_from_sft_format(self, caption: str) -> str:\n        \"\"\"Extract caption body from SFT-formatted prompt when present.\"\"\"\n        try:\n            if \"# Instruction\" in caption and \"# Caption\" in caption:\n                pattern = r\"#\\s*Caption\\s*\\n(.*?)(?:\\n\\s*#\\s*Metas|$)\"\n                match = re.search(pattern, caption, re.DOTALL)\n                if match:\n                    return match.group(1).strip()\n            return caption\n        except (AttributeError, TypeError, re.error):\n            logger.exception(\"[extract_caption_from_sft_format] Error extracting caption\")\n            return caption\n\n    def build_dit_inputs(\n        self,\n        task: str,\n        instruction: Optional[str],\n        caption: str,\n        lyrics: str,\n        metas: Optional[Union[str, Dict[str, Any]]] = None,\n        vocal_language: str = \"en\",\n    ) -> Tuple[str, str]:\n        \"\"\"Build caption and lyric input text for DiT branches.\n\n        Args:\n            task: Task name (currently informational; reserved for task-specific formatting).\n            instruction: Instruction text; falls back to default when empty.\n            caption: Caption fallback value.\n            lyrics: Raw lyric text.\n            metas: Optional metadata (string or dict) that may include caption/language.\n            vocal_language: Fallback lyric language when not present in metadata.\n\n        Returns:\n            Tuple of ``(caption_input, lyrics_input)`` for caption and lyric encoder branches.\n        \"\"\"\n        final_instruction = self._format_instruction(instruction or DEFAULT_DIT_INSTRUCTION)\n        actual_caption = caption\n        actual_language = vocal_language\n\n        if metas is not None:\n            try:\n                if isinstance(metas, str):\n                    parsed_metas = self._parse_metas([metas])\n                    meta_dict = parsed_metas[0] if parsed_metas and isinstance(parsed_metas[0], dict) else {}\n                elif isinstance(metas, dict):\n                    meta_dict = metas\n                else:\n                    meta_dict = {}\n            except (TypeError, ValueError, KeyError, IndexError):\n                logger.exception(\"[build_dit_inputs] Error parsing metas\")\n                meta_dict = {}\n            if \"caption\" in meta_dict and meta_dict[\"caption\"]:\n                actual_caption = str(meta_dict[\"caption\"])\n            if \"language\" in meta_dict and meta_dict[\"language\"]:\n                actual_language = str(meta_dict[\"language\"])\n\n        parsed_meta = self._parse_metas([metas])[0]\n        caption_input = SFT_GEN_PROMPT.format(final_instruction, actual_caption, parsed_meta)\n        lyrics_input = self._format_lyrics(lyrics, actual_language)\n        return caption_input, lyrics_input\n\n    def _get_text_hidden_states(self, text_prompt: str) -> Tuple[torch.Tensor, torch.Tensor]:\n        \"\"\"Get hidden states and attention mask from text encoder.\"\"\"\n        if self.text_tokenizer is None or self.text_encoder is None:\n            raise ValueError(\"Text encoder not initialized\")\n\n        try:\n            with self._load_model_context(\"text_encoder\"):\n                text_inputs = self.text_tokenizer(\n                    text_prompt,\n                    padding=\"longest\",\n                    truncation=True,\n                    max_length=256,\n                    return_tensors=\"pt\",\n                )\n                text_input_ids = text_inputs.input_ids.to(self.device)\n                text_attention_mask = text_inputs.attention_mask.to(self.device).bool()\n\n                with torch.inference_mode():\n                    text_outputs = self.text_encoder(text_input_ids)\n                    if hasattr(text_outputs, \"last_hidden_state\"):\n                        text_hidden_states = text_outputs.last_hidden_state\n                    elif isinstance(text_outputs, tuple):\n                        text_hidden_states = text_outputs[0]\n                    else:\n                        text_hidden_states = text_outputs\n\n                text_hidden_states = text_hidden_states.to(self.dtype)\n                return text_hidden_states, text_attention_mask\n        except (AttributeError, RuntimeError, TypeError, ValueError):\n            logger.exception(\"[_get_text_hidden_states] Failed to encode text prompt\")\n            raise\n\n    def _extract_caption_and_language(\n        self,\n        metas: List[Union[str, Dict[str, Any]]],\n        captions: List[str],\n        vocal_languages: List[str],\n    ) -> Tuple[List[str], List[str]]:\n        \"\"\"Extract caption/language values from metas with fallback values.\"\"\"\n        actual_captions = list(captions)\n        actual_languages = list(vocal_languages)\n\n        for i, meta in enumerate(metas):\n            if i >= len(actual_captions):\n                break\n\n            meta_dict = None\n            if isinstance(meta, str):\n                parsed = self._parse_metas([meta])\n                if parsed and isinstance(parsed[0], dict):\n                    meta_dict = parsed[0]\n            elif isinstance(meta, dict):\n                meta_dict = meta\n\n            if meta_dict:\n                if \"caption\" in meta_dict and meta_dict[\"caption\"]:\n                    actual_captions[i] = str(meta_dict[\"caption\"])\n                if \"language\" in meta_dict and meta_dict[\"language\"]:\n                    actual_languages[i] = str(meta_dict[\"language\"])\n        return actual_captions, actual_languages\n"
  },
  {
    "path": "acestep/core/generation/handler/reference_audio_validation_test.py",
    "content": "\"\"\"Regression tests for user-facing reference-audio validation errors.\"\"\"\n\nimport unittest\nfrom unittest.mock import Mock\n\ntry:\n    from acestep.handler import AceStepHandler\nexcept ModuleNotFoundError:\n    AceStepHandler = None\n\n\n@unittest.skipIf(AceStepHandler is None, \"AceStepHandler dependencies are unavailable in this test environment.\")\nclass ReferenceAudioValidationTests(unittest.TestCase):\n    \"\"\"Tests for invalid reference-audio handling in ``generate_music``.\"\"\"\n\n    def test_generate_music_returns_error_for_invalid_reference_audio(self) -> None:\n        \"\"\"Invalid reference audio should fail fast with a user-facing message.\"\"\"\n        handler = AceStepHandler.__new__(AceStepHandler)\n        handler.model = object()\n        handler.vae = object()\n        handler.text_tokenizer = object()\n        handler.text_encoder = object()\n        handler.batch_size = 1\n        handler.sample_rate = 48000\n        handler.current_offload_cost = 0.0\n\n        handler._vram_guard_reduce_batch = lambda batch_size, audio_duration=None: batch_size\n        handler.prepare_seeds = lambda batch_size, seed, use_random_seed: ([123] * batch_size, 123)\n        handler.process_reference_audio = lambda _audio_file: None\n        handler.service_generate = Mock(side_effect=AssertionError(\"service_generate should not be called\"))\n\n        result = handler.generate_music(\n            captions=\"\",\n            lyrics=\"\",\n            reference_audio=\"not_audio.mp3\",\n            progress=lambda *_args, **_kwargs: None,\n        )\n\n        self.assertFalse(result[\"success\"])\n        self.assertEqual(result[\"error\"], \"Invalid reference audio\")\n        self.assertIn(\"Reference audio is invalid\", result[\"status_message\"])\n        self.assertEqual(result[\"audios\"], [])\n\n\nif __name__ == \"__main__\":\n    unittest.main()\n"
  },
  {
    "path": "acestep/core/generation/handler/repaint_step_injection.py",
    "content": "\"\"\"Step-level repaint injection and boundary blending for diffusion loops.\"\"\"\n\nimport torch\n\n\ndef apply_repaint_step_injection(\n    xt: torch.Tensor,\n    clean_src_latents: torch.Tensor,\n    repaint_mask: torch.Tensor,\n    t_next: float,\n    noise: torch.Tensor,\n) -> torch.Tensor:\n    \"\"\"Replace non-repaint regions of xt with noised source latents.\n\n    At each diffusion step the non-repaint regions are forced back to the\n    appropriately-noised version of the original audio so they cannot drift.\n\n    Args:\n        xt: Current diffusion state [B, T, C].\n        clean_src_latents: VAE-encoded source audio (unmasked) [B, T, C].\n        repaint_mask: Boolean [B, T], True = repaint (generate), False = preserve.\n        t_next: Noise level after this step (flow-matching: 1.0=noise, 0.0=clean).\n        noise: Initial noise tensor [B, T, C], reused across steps for consistency.\n\n    Returns:\n        Updated xt with non-repaint regions replaced by noised source.\n    \"\"\"\n    zt_src = t_next * noise + (1.0 - t_next) * clean_src_latents\n    mask_expanded = repaint_mask.unsqueeze(-1).expand_as(xt)\n    return torch.where(mask_expanded, xt, zt_src)\n\n\ndef build_soft_repaint_mask(\n    repaint_mask: torch.Tensor,\n    crossfade_frames: int,\n) -> torch.Tensor:\n    \"\"\"Build a soft float mask with linear crossfade at repaint boundaries.\n\n    The crossfade zones extend into the preserved (non-repaint) region on each\n    side of the boundary, linearly ramping from 0 to 1 (left) or 1 to 0 (right).\n\n    Args:\n        repaint_mask: Boolean [B, T], True = repaint region.\n        crossfade_frames: Width of each crossfade ramp (in latent frames).\n\n    Returns:\n        Soft float mask [B, T] with smooth boundary transitions.\n    \"\"\"\n    soft_mask = repaint_mask.float().clone()\n    if crossfade_frames <= 0:\n        return soft_mask\n\n    B, T = repaint_mask.shape\n    for b in range(B):\n        row = repaint_mask[b]\n        if row.all() or not row.any():\n            continue\n\n        indices = torch.nonzero(row, as_tuple=False).squeeze(-1)\n        if indices.numel() == 0:\n            continue\n        left = indices[0].item()\n        right = indices[-1].item() + 1\n\n        fade_start = max(left - crossfade_frames, 0)\n        ramp_len = left - fade_start\n        if ramp_len > 0:\n            ramp = torch.linspace(\n                0.0, 1.0, ramp_len + 2, device=soft_mask.device,\n            )[1:-1]\n            soft_mask[b, fade_start:left] = ramp\n\n        fade_end = min(right + crossfade_frames, T)\n        ramp_len = fade_end - right\n        if ramp_len > 0:\n            ramp = torch.linspace(\n                1.0, 0.0, ramp_len + 2, device=soft_mask.device,\n            )[1:-1]\n            soft_mask[b, right:fade_end] = ramp\n\n    return soft_mask\n\n\ndef apply_repaint_boundary_blend(\n    x_gen: torch.Tensor,\n    clean_src_latents: torch.Tensor,\n    repaint_mask: torch.Tensor,\n    crossfade_frames: int = 10,\n) -> torch.Tensor:\n    \"\"\"Blend generated latents with source at repaint boundaries.\n\n    Args:\n        x_gen: Diffusion output [B, T, C].\n        clean_src_latents: Original source latents [B, T, C].\n        repaint_mask: Boolean [B, T], True = repaint region.\n        crossfade_frames: Width of crossfade zone per boundary side.\n\n    Returns:\n        Blended output with smooth transitions at repaint edges.\n    \"\"\"\n    soft_mask = build_soft_repaint_mask(repaint_mask, crossfade_frames)\n    m = soft_mask.unsqueeze(-1).expand_as(x_gen)\n    return m * x_gen + (1.0 - m) * clean_src_latents\n"
  },
  {
    "path": "acestep/core/generation/handler/repaint_step_injection_test.py",
    "content": "\"\"\"Unit tests for repaint step injection and boundary blending.\"\"\"\n\nimport unittest\n\nimport torch\n\nfrom acestep.core.generation.handler.repaint_step_injection import (\n    apply_repaint_boundary_blend,\n    apply_repaint_step_injection,\n    build_soft_repaint_mask,\n)\n\n\nclass TestApplyRepaintStepInjection(unittest.TestCase):\n    \"\"\"Tests for per-step source latent replacement in non-repaint regions.\"\"\"\n\n    def setUp(self):\n        self.B, self.T, self.C = 2, 100, 64\n        self.xt = torch.randn(self.B, self.T, self.C)\n        self.clean_src = torch.randn(self.B, self.T, self.C)\n        self.noise = torch.randn(self.B, self.T, self.C)\n        self.mask = torch.ones(self.B, self.T, dtype=torch.bool)\n        self.mask[0, :20] = False\n        self.mask[0, 40:] = False\n        self.mask[1, :10] = False\n        self.mask[1, 60:] = False\n\n    def test_non_repaint_regions_match_noised_source(self):\n        t_next = 0.5\n        result = apply_repaint_step_injection(\n            self.xt, self.clean_src, self.mask, t_next, self.noise,\n        )\n        expected = t_next * self.noise + (1.0 - t_next) * self.clean_src\n        torch.testing.assert_close(result[0, :20], expected[0, :20])\n        torch.testing.assert_close(result[0, 40:], expected[0, 40:])\n\n    def test_repaint_regions_unchanged(self):\n        result = apply_repaint_step_injection(\n            self.xt, self.clean_src, self.mask, 0.3, self.noise,\n        )\n        torch.testing.assert_close(result[0, 20:40], self.xt[0, 20:40])\n        torch.testing.assert_close(result[1, 10:60], self.xt[1, 10:60])\n\n    def test_all_true_mask_is_noop(self):\n        full_mask = torch.ones(self.B, self.T, dtype=torch.bool)\n        result = apply_repaint_step_injection(\n            self.xt, self.clean_src, full_mask, 0.5, self.noise,\n        )\n        torch.testing.assert_close(result, self.xt)\n\n    def test_t_zero_returns_clean_source_in_preserved(self):\n        result = apply_repaint_step_injection(\n            self.xt, self.clean_src, self.mask, 0.0, self.noise,\n        )\n        torch.testing.assert_close(result[0, :20], self.clean_src[0, :20])\n\n    def test_t_one_returns_pure_noise_in_preserved(self):\n        result = apply_repaint_step_injection(\n            self.xt, self.clean_src, self.mask, 1.0, self.noise,\n        )\n        torch.testing.assert_close(result[0, :20], self.noise[0, :20])\n\n\nclass TestBuildSoftRepaintMask(unittest.TestCase):\n    \"\"\"Tests for soft crossfade mask construction.\"\"\"\n\n    def test_core_region_is_one(self):\n        mask = torch.zeros(1, 100, dtype=torch.bool)\n        mask[0, 20:40] = True\n        soft = build_soft_repaint_mask(mask, crossfade_frames=5)\n        self.assertTrue((soft[0, 20:40] == 1.0).all())\n\n    def test_far_preserved_is_zero(self):\n        mask = torch.zeros(1, 100, dtype=torch.bool)\n        mask[0, 20:40] = True\n        soft = build_soft_repaint_mask(mask, crossfade_frames=5)\n        self.assertTrue((soft[0, :15] == 0.0).all())\n        self.assertTrue((soft[0, 45:] == 0.0).all())\n\n    def test_crossfade_zone_is_monotonic(self):\n        mask = torch.zeros(1, 100, dtype=torch.bool)\n        mask[0, 20:60] = True\n        soft = build_soft_repaint_mask(mask, crossfade_frames=8)\n        left_ramp = soft[0, 12:20]\n        for i in range(len(left_ramp) - 1):\n            self.assertLess(left_ramp[i].item(), left_ramp[i + 1].item())\n        right_ramp = soft[0, 60:68]\n        for i in range(len(right_ramp) - 1):\n            self.assertGreater(right_ramp[i].item(), right_ramp[i + 1].item())\n\n    def test_all_true_mask_returns_ones(self):\n        mask = torch.ones(2, 50, dtype=torch.bool)\n        soft = build_soft_repaint_mask(mask, crossfade_frames=10)\n        self.assertTrue((soft == 1.0).all())\n\n    def test_all_false_mask_returns_zeros(self):\n        mask = torch.zeros(2, 50, dtype=torch.bool)\n        soft = build_soft_repaint_mask(mask, crossfade_frames=10)\n        self.assertTrue((soft == 0.0).all())\n\n    def test_zero_crossfade_is_hard_mask(self):\n        mask = torch.zeros(1, 100, dtype=torch.bool)\n        mask[0, 30:70] = True\n        soft = build_soft_repaint_mask(mask, crossfade_frames=0)\n        torch.testing.assert_close(soft, mask.float())\n\n    def test_crossfade_clamped_at_boundaries(self):\n        mask = torch.zeros(1, 50, dtype=torch.bool)\n        mask[0, 2:48] = True\n        soft = build_soft_repaint_mask(mask, crossfade_frames=10)\n        self.assertTrue((soft[0] >= 0.0).all())\n        self.assertTrue((soft[0] <= 1.0).all())\n        self.assertTrue((soft[0, :2] < 1.0).all())\n\n\nclass TestApplyRepaintBoundaryBlend(unittest.TestCase):\n    \"\"\"Tests for post-loop boundary blending.\"\"\"\n\n    def test_preserved_region_uses_source(self):\n        B, T, C = 1, 100, 16\n        x_gen = torch.ones(B, T, C)\n        clean = torch.zeros(B, T, C)\n        mask = torch.zeros(B, T, dtype=torch.bool)\n        mask[0, 30:60] = True\n        result = apply_repaint_boundary_blend(x_gen, clean, mask, crossfade_frames=5)\n        torch.testing.assert_close(result[0, :25], clean[0, :25])\n        torch.testing.assert_close(result[0, 65:], clean[0, 65:])\n\n    def test_core_repaint_uses_generated(self):\n        B, T, C = 1, 100, 16\n        x_gen = torch.ones(B, T, C) * 2.0\n        clean = torch.zeros(B, T, C)\n        mask = torch.zeros(B, T, dtype=torch.bool)\n        mask[0, 30:60] = True\n        result = apply_repaint_boundary_blend(x_gen, clean, mask, crossfade_frames=5)\n        torch.testing.assert_close(result[0, 30:60], x_gen[0, 30:60])\n\n    def test_full_repaint_mask_returns_generated(self):\n        B, T, C = 2, 50, 8\n        x_gen = torch.randn(B, T, C)\n        clean = torch.randn(B, T, C)\n        mask = torch.ones(B, T, dtype=torch.bool)\n        result = apply_repaint_boundary_blend(x_gen, clean, mask, crossfade_frames=10)\n        torch.testing.assert_close(result, x_gen)\n\n    def test_blending_zone_is_interpolated(self):\n        B, T, C = 1, 100, 4\n        x_gen = torch.ones(B, T, C)\n        clean = torch.zeros(B, T, C)\n        mask = torch.zeros(B, T, dtype=torch.bool)\n        mask[0, 20:80] = True\n        result = apply_repaint_boundary_blend(x_gen, clean, mask, crossfade_frames=5)\n        blend_zone = result[0, 15:20, 0]\n        for i in range(len(blend_zone)):\n            val = blend_zone[i].item()\n            self.assertGreater(val, 0.0)\n            self.assertLess(val, 1.0)\n\n\nif __name__ == \"__main__\":\n    unittest.main()\n"
  },
  {
    "path": "acestep/core/generation/handler/repaint_waveform_splice.py",
    "content": "\"\"\"Waveform-level splice for repaint tasks.\n\nAfter VAE decode, non-repaint regions still carry VAE reconstruction error.\nThis module replaces those regions with the original user waveform and applies\na short crossfade at boundaries to eliminate clicks.\n\"\"\"\n\nfrom typing import List\n\nimport torch\nfrom loguru import logger\n\n\ndef _build_waveform_crossfade_mask(\n    total_samples: int,\n    start_sample: int,\n    end_sample: int,\n    crossfade_samples: int,\n    device: torch.device,\n) -> torch.Tensor:\n    \"\"\"Build a per-sample float mask: 1.0 inside repaint, 0.0 outside, ramp at edges.\n\n    Args:\n        total_samples: Total waveform length in samples.\n        start_sample: First sample of the repaint region.\n        end_sample: One-past-last sample of the repaint region.\n        crossfade_samples: Number of samples over which to ramp.\n        device: Target tensor device.\n\n    Returns:\n        Float tensor of shape ``[total_samples]`` with values in ``[0, 1]``.\n    \"\"\"\n    mask = torch.zeros(total_samples, device=device)\n    mask[start_sample:end_sample] = 1.0\n\n    if crossfade_samples <= 0:\n        return mask\n\n    fade_start = max(start_sample - crossfade_samples, 0)\n    ramp_len = start_sample - fade_start\n    if ramp_len > 0:\n        ramp = torch.linspace(0.0, 1.0, ramp_len + 2, device=device)[1:-1]\n        mask[fade_start:start_sample] = ramp\n\n    fade_end = min(end_sample + crossfade_samples, total_samples)\n    ramp_len = fade_end - end_sample\n    if ramp_len > 0:\n        ramp = torch.linspace(1.0, 0.0, ramp_len + 2, device=device)[1:-1]\n        mask[end_sample:fade_end] = ramp\n\n    return mask\n\n\ndef apply_repaint_waveform_splice(\n    pred_wavs: torch.Tensor,\n    src_wavs: torch.Tensor,\n    repainting_starts: List[float],\n    repainting_ends: List[float],\n    sample_rate: int = 48000,\n    crossfade_duration: float = 0.01,\n) -> torch.Tensor:\n    \"\"\"Splice original user waveform into non-repaint regions after VAE decode.\n\n    Args:\n        pred_wavs: VAE-decoded waveform ``[B, C, samples]``.\n        src_wavs: Original user waveform (pre-VAE) ``[B, C, samples]``.\n        repainting_starts: Per-batch start time in seconds.\n        repainting_ends: Per-batch end time in seconds.\n        sample_rate: Audio sample rate (default 48000).\n        crossfade_duration: Crossfade length in seconds at splice boundaries\n            (default 0.01 = 10 ms).\n\n    Returns:\n        Spliced waveform tensor with same shape as ``pred_wavs``.\n    \"\"\"\n    B = pred_wavs.shape[0]\n    min_samples = min(pred_wavs.shape[-1], src_wavs.shape[-1])\n\n    if pred_wavs.shape[-1] != src_wavs.shape[-1]:\n        logger.debug(\n            \"[repaint_waveform_splice] Length mismatch: pred_wavs={}, src_wavs={}; \"\n            \"truncating to {}\",\n            pred_wavs.shape[-1], src_wavs.shape[-1], min_samples,\n        )\n\n    pred_trimmed = pred_wavs[..., :min_samples]\n    src_trimmed = src_wavs[..., :min_samples].to(\n        device=pred_trimmed.device, dtype=pred_trimmed.dtype,\n    )\n\n    crossfade_samples = int(crossfade_duration * sample_rate)\n    result = pred_trimmed.clone()\n\n    for b in range(B):\n        start_sample = int(repainting_starts[b] * sample_rate)\n        end_sample = int(repainting_ends[b] * sample_rate)\n        start_sample = max(0, min(start_sample, min_samples))\n        end_sample = max(start_sample, min(end_sample, min_samples))\n\n        if start_sample == 0 and end_sample >= min_samples:\n            continue\n\n        mask = _build_waveform_crossfade_mask(\n            min_samples, start_sample, end_sample, crossfade_samples,\n            device=pred_trimmed.device,\n        )\n        m = mask.unsqueeze(0).expand_as(result[b])\n        result[b] = m * pred_trimmed[b] + (1.0 - m) * src_trimmed[b]\n\n    if pred_wavs.shape[-1] > min_samples:\n        result = torch.cat(\n            [result, pred_wavs[..., min_samples:]], dim=-1,\n        )\n\n    return result\n"
  },
  {
    "path": "acestep/core/generation/handler/repaint_waveform_splice_test.py",
    "content": "\"\"\"Tests for repaint_waveform_splice module.\"\"\"\n\nimport unittest\n\nimport torch\n\nfrom acestep.core.generation.handler.repaint_waveform_splice import (\n    _build_waveform_crossfade_mask,\n    apply_repaint_waveform_splice,\n)\n\n\nclass TestBuildWaveformCrossfadeMask(unittest.TestCase):\n    \"\"\"Tests for _build_waveform_crossfade_mask.\"\"\"\n\n    def test_mask_ones_inside_repaint_region(self):\n        mask = _build_waveform_crossfade_mask(100, 20, 60, 0, torch.device(\"cpu\"))\n        self.assertTrue(torch.all(mask[20:60] == 1.0))\n        self.assertTrue(torch.all(mask[:20] == 0.0))\n        self.assertTrue(torch.all(mask[60:] == 0.0))\n\n    def test_crossfade_ramp_at_left_boundary(self):\n        mask = _build_waveform_crossfade_mask(200, 50, 150, 10, torch.device(\"cpu\"))\n        ramp = mask[40:50]\n        self.assertEqual(ramp.shape[0], 10)\n        self.assertTrue(torch.all(ramp > 0.0))\n        self.assertTrue(torch.all(ramp < 1.0))\n        diffs = ramp[1:] - ramp[:-1]\n        self.assertTrue(torch.all(diffs > 0), \"Left ramp must be monotonically increasing\")\n\n    def test_crossfade_ramp_at_right_boundary(self):\n        mask = _build_waveform_crossfade_mask(200, 50, 150, 10, torch.device(\"cpu\"))\n        ramp = mask[150:160]\n        self.assertEqual(ramp.shape[0], 10)\n        self.assertTrue(torch.all(ramp > 0.0))\n        self.assertTrue(torch.all(ramp < 1.0))\n        diffs = ramp[1:] - ramp[:-1]\n        self.assertTrue(torch.all(diffs < 0), \"Right ramp must be monotonically decreasing\")\n\n    def test_crossfade_clamps_to_boundaries(self):\n        mask = _build_waveform_crossfade_mask(100, 5, 95, 20, torch.device(\"cpu\"))\n        self.assertTrue(torch.all(mask >= 0.0))\n        self.assertTrue(torch.all(mask <= 1.0))\n        self.assertTrue(torch.all(mask[5:95] == 1.0))\n\n    def test_zero_crossfade_is_hard_step(self):\n        mask = _build_waveform_crossfade_mask(100, 30, 70, 0, torch.device(\"cpu\"))\n        self.assertTrue(torch.all(mask[:30] == 0.0))\n        self.assertTrue(torch.all(mask[30:70] == 1.0))\n        self.assertTrue(torch.all(mask[70:] == 0.0))\n\n\nclass TestApplyRepaintWaveformSplice(unittest.TestCase):\n    \"\"\"Tests for apply_repaint_waveform_splice.\"\"\"\n\n    def _make_tensors(self, B=1, C=2, samples=4800):\n        pred = torch.ones(B, C, samples) * 2.0\n        src = torch.ones(B, C, samples) * 5.0\n        return pred, src\n\n    def test_non_repaint_regions_match_src(self):\n        pred, src = self._make_tensors(samples=9600)\n        result = apply_repaint_waveform_splice(\n            pred, src, [0.05], [0.15], sample_rate=48000, crossfade_duration=0.0,\n        )\n        start = int(0.05 * 48000)\n        end = int(0.15 * 48000)\n        torch.testing.assert_close(result[0, :, :start], src[0, :, :start])\n        torch.testing.assert_close(result[0, :, end:], src[0, :, end:])\n\n    def test_repaint_region_uses_pred(self):\n        pred, src = self._make_tensors(samples=9600)\n        result = apply_repaint_waveform_splice(\n            pred, src, [0.05], [0.15], sample_rate=48000, crossfade_duration=0.0,\n        )\n        start = int(0.05 * 48000)\n        end = int(0.15 * 48000)\n        torch.testing.assert_close(result[0, :, start:end], pred[0, :, start:end])\n\n    def test_crossfade_produces_intermediate_values(self):\n        pred, src = self._make_tensors(samples=9600)\n        result = apply_repaint_waveform_splice(\n            pred, src, [0.05], [0.15], sample_rate=48000, crossfade_duration=0.005,\n        )\n        cf_samples = int(0.005 * 48000)\n        start = int(0.05 * 48000)\n        left_zone = result[0, 0, start - cf_samples:start]\n        self.assertTrue(torch.all(left_zone > 2.0))\n        self.assertTrue(torch.all(left_zone < 5.0))\n\n    def test_full_repaint_returns_pred_unchanged(self):\n        pred, src = self._make_tensors(samples=4800)\n        result = apply_repaint_waveform_splice(\n            pred, src, [0.0], [0.1], sample_rate=48000, crossfade_duration=0.01,\n        )\n        torch.testing.assert_close(result, pred)\n\n    def test_length_mismatch_pred_longer(self):\n        pred = torch.ones(1, 2, 5000) * 2.0\n        src = torch.ones(1, 2, 4800) * 5.0\n        result = apply_repaint_waveform_splice(\n            pred, src, [0.02], [0.08], sample_rate=48000, crossfade_duration=0.0,\n        )\n        self.assertEqual(result.shape[-1], 5000)\n        torch.testing.assert_close(result[..., 4800:], pred[..., 4800:])\n\n    def test_length_mismatch_src_longer(self):\n        pred = torch.ones(1, 2, 4800) * 2.0\n        src = torch.ones(1, 2, 5000) * 5.0\n        result = apply_repaint_waveform_splice(\n            pred, src, [0.02], [0.08], sample_rate=48000, crossfade_duration=0.0,\n        )\n        self.assertEqual(result.shape[-1], 4800)\n\n    def test_batch_independent_splice(self):\n        pred = torch.ones(2, 2, 9600) * 2.0\n        src = torch.ones(2, 2, 9600) * 5.0\n        result = apply_repaint_waveform_splice(\n            pred, src, [0.02, 0.05], [0.08, 0.15], sample_rate=48000,\n            crossfade_duration=0.0,\n        )\n        s0, e0 = int(0.02 * 48000), int(0.08 * 48000)\n        s1, e1 = int(0.05 * 48000), int(0.15 * 48000)\n        torch.testing.assert_close(result[0, :, :s0], src[0, :, :s0])\n        torch.testing.assert_close(result[0, :, s0:e0], pred[0, :, s0:e0])\n        torch.testing.assert_close(result[1, :, :s1], src[1, :, :s1])\n        torch.testing.assert_close(result[1, :, s1:e1], pred[1, :, s1:e1])\n\n    def test_zero_crossfade_duration(self):\n        pred, src = self._make_tensors(samples=9600)\n        result = apply_repaint_waveform_splice(\n            pred, src, [0.05], [0.15], sample_rate=48000, crossfade_duration=0.0,\n        )\n        start = int(0.05 * 48000)\n        self.assertAlmostEqual(result[0, 0, start - 1].item(), 5.0)\n        self.assertAlmostEqual(result[0, 0, start].item(), 2.0)\n\n\nif __name__ == \"__main__\":\n    unittest.main()\n"
  },
  {
    "path": "acestep/core/generation/handler/resolve_repaint_config_test.py",
    "content": "\"\"\"Tests for _resolve_repaint_config().\"\"\"\n\nimport unittest\n\nfrom acestep.core.generation.handler.generate_music import _resolve_repaint_config\n\n\nclass TestResolveRepaintConfig(unittest.TestCase):\n    \"\"\"Verify mode/strength -> (injection_ratio, crossfade_frames, wav_crossfade).\n\n    Strength semantics: 0.0 = conservative, 1.0 = aggressive.\n    \"\"\"\n\n    def test_aggressive_returns_zeros(self):\n        ratio, frames, wav = _resolve_repaint_config(\"aggressive\", 0.5)\n        self.assertEqual(ratio, 0.0)\n        self.assertEqual(frames, 0)\n        self.assertEqual(wav, 0.0)\n\n    def test_conservative_returns_max(self):\n        ratio, frames, wav = _resolve_repaint_config(\"conservative\", 1.0)\n        self.assertEqual(ratio, 1.0)\n        self.assertEqual(frames, 25)\n        self.assertAlmostEqual(wav, 0.05)\n\n    def test_balanced_half(self):\n        ratio, frames, wav = _resolve_repaint_config(\"balanced\", 0.5)\n        self.assertAlmostEqual(ratio, 0.5)\n        self.assertEqual(frames, 12)\n        self.assertAlmostEqual(wav, 0.025)\n\n    def test_balanced_zero_equals_conservative(self):\n        \"\"\"strength=0 in balanced mode behaves like conservative.\"\"\"\n        ratio, frames, wav = _resolve_repaint_config(\"balanced\", 0.0)\n        self.assertEqual(ratio, 1.0)\n        self.assertEqual(frames, 25)\n        self.assertAlmostEqual(wav, 0.05)\n\n    def test_balanced_one_equals_aggressive(self):\n        \"\"\"strength=1 in balanced mode behaves like aggressive.\"\"\"\n        ratio, frames, wav = _resolve_repaint_config(\"balanced\", 1.0)\n        self.assertEqual(ratio, 0.0)\n        self.assertEqual(frames, 0)\n        self.assertEqual(wav, 0.0)\n\n    def test_strength_clamped_above_one(self):\n        ratio, frames, wav = _resolve_repaint_config(\"balanced\", 1.5)\n        self.assertEqual(ratio, 0.0)\n\n    def test_strength_clamped_below_zero(self):\n        ratio, frames, wav = _resolve_repaint_config(\"balanced\", -0.3)\n        self.assertEqual(ratio, 1.0)\n\n    def test_default_args(self):\n        ratio, frames, wav = _resolve_repaint_config()\n        self.assertAlmostEqual(ratio, 0.5)\n        self.assertEqual(frames, 12)\n\n\nif __name__ == \"__main__\":\n    unittest.main()\n"
  },
  {
    "path": "acestep/core/generation/handler/service_generate.py",
    "content": "\"\"\"Service-generate orchestration entrypoint for handler decomposition.\n\nThis module provides the top-level generation flow used by service callers.\nIt coordinates request normalization, batch preparation, diffusion execution,\nand output attachment without owning model internals.\n\"\"\"\n\nfrom typing import Any, Dict, List, Optional, Union\n\nimport torch\n\n\nclass ServiceGenerateMixin:\n    \"\"\"Run the high-level service-generation pipeline over prepared helper APIs.\n\n    Implementing hosts are expected to provide request-normalization, batch\n    preparation, diffusion, and output-attachment helper methods.\n    \"\"\"\n\n    @torch.inference_mode()\n    def service_generate(\n        self,\n        captions: Union[str, List[str]],\n        global_captions: Optional[List[str]] = None,\n        lyrics: Union[str, List[str]] = \"\",\n        keys: Optional[Union[str, List[str]]] = None,\n        target_wavs: Optional[torch.Tensor] = None,\n        refer_audios: Optional[List[List[torch.Tensor]]] = None,\n        metas: Optional[Union[str, Dict[str, Any], List[Union[str, Dict[str, Any]]]]] = None,\n        vocal_languages: Optional[Union[str, List[str]]] = None,\n        infer_steps: int = 60,\n        guidance_scale: float = 7.0,\n        seed: Optional[Union[int, List[int]]] = None,\n        return_intermediate: bool = False,\n        repainting_start: Optional[Union[float, List[float]]] = None,\n        repainting_end: Optional[Union[float, List[float]]] = None,\n        instructions: Optional[Union[str, List[str]]] = None,\n        audio_cover_strength: float = 1.0,\n        cover_noise_strength: float = 0.0,\n        use_adg: bool = False,\n        cfg_interval_start: float = 0.0,\n        cfg_interval_end: float = 1.0,\n        shift: float = 1.0,\n        audio_code_hints: Optional[Union[str, List[str]]] = None,\n        infer_method: str = \"ode\",\n        timesteps: Optional[List[float]] = None,\n        chunk_mask_modes: Optional[List[str]] = None,\n        repaint_crossfade_frames: int = 10,\n        repaint_injection_ratio: float = 0.5,\n    ) -> Dict[str, Any]:\n        \"\"\"Generate music latents and metadata from text/audio conditioning inputs.\n\n        Args:\n            captions: Caption string(s) describing the target generation.\n            lyrics: Lyric string(s) aligned with each requested sample.\n            keys: Optional sample identifiers.\n            target_wavs: Optional target audio tensor for repaint/cover flows.\n            refer_audios: Optional nested reference-audio tensors for style conditioning.\n            metas: Optional metadata payload(s) for each sample.\n            vocal_languages: Optional per-sample vocal language code(s).\n            infer_steps: Number of diffusion steps to run.\n            guidance_scale: CFG guidance strength.\n            seed: Optional scalar or per-sample seed list.\n            return_intermediate: Whether to include intermediate tensors in outputs.\n            repainting_start: Optional repaint start time(s) in seconds.\n            repainting_end: Optional repaint end time(s) in seconds.\n            instructions: Optional per-sample instruction string(s).\n            audio_cover_strength: Cover blend strength.\n            cover_noise_strength: Cover noise blend strength.\n            use_adg: Whether adaptive diffusion guidance is enabled.\n            cfg_interval_start: CFG schedule start ratio.\n            cfg_interval_end: CFG schedule end ratio.\n            shift: Diffusion shift parameter.\n            audio_code_hints: Optional serialized audio-code hints.\n            infer_method: Diffusion inference method selector.\n            timesteps: Optional explicit diffusion timestep sequence.\n            repaint_crossfade_frames: Crossfade width (latent frames) at repaint\n                boundaries for boundary blending.  ~0.4s at 25 Hz.\n\n        Returns:\n            Dict[str, Any]: Service output payload containing generated latents,\n            timing fields, and optionally intermediate conditioning tensors.\n\n        Raises:\n            Exception: Propagates exceptions raised by downstream helper methods\n                (e.g., normalization, diffusion execution, output assembly).\n        \"\"\"\n        normalized = self._normalize_service_generate_inputs(\n            captions=captions,\n            lyrics=lyrics,\n            keys=keys,\n            metas=metas,\n            vocal_languages=vocal_languages,\n            repainting_start=repainting_start,\n            repainting_end=repainting_end,\n            instructions=instructions,\n            audio_code_hints=audio_code_hints,\n            infer_steps=infer_steps,\n            seed=seed,\n            return_intermediate=return_intermediate,\n        )\n        batch = self._prepare_batch(\n            captions=normalized[\"captions\"],\n            global_captions=global_captions,\n            lyrics=normalized[\"lyrics\"],\n            keys=normalized[\"keys\"],\n            target_wavs=target_wavs,\n            refer_audios=refer_audios,\n            metas=normalized[\"metas\"],\n            vocal_languages=normalized[\"vocal_languages\"],\n            repainting_start=normalized[\"repainting_start\"],\n            repainting_end=normalized[\"repainting_end\"],\n            instructions=normalized[\"instructions\"],\n            audio_code_hints=normalized[\"audio_code_hints\"],\n            audio_cover_strength=audio_cover_strength,\n            cover_noise_strength=cover_noise_strength,\n            chunk_mask_modes=chunk_mask_modes,\n        )\n        payload = self._unpack_service_processed_data(self.preprocess_batch(batch))\n        seed_param = self._resolve_service_seed_param(normalized[\"seed_list\"])\n        self._ensure_silence_latent_on_device()\n        generate_kwargs = self._build_service_generate_kwargs(\n            payload=payload,\n            seed_param=seed_param,\n            infer_steps=normalized[\"infer_steps\"],\n            guidance_scale=guidance_scale,\n            audio_cover_strength=audio_cover_strength,\n            cover_noise_strength=cover_noise_strength,\n            infer_method=infer_method,\n            use_adg=use_adg,\n            cfg_interval_start=cfg_interval_start,\n            cfg_interval_end=cfg_interval_end,\n            shift=shift,\n            timesteps=timesteps,\n            repaint_crossfade_frames=repaint_crossfade_frames,\n            repaint_injection_ratio=repaint_injection_ratio,\n        )\n        outputs, encoder_hidden_states, encoder_attention_mask, context_latents = (\n            self._execute_service_generate_diffusion(\n                payload=payload,\n                generate_kwargs=generate_kwargs,\n                seed_param=seed_param,\n                infer_method=infer_method,\n                shift=shift,\n                audio_cover_strength=audio_cover_strength,\n            )\n        )\n        return self._attach_service_generate_outputs(\n            outputs=outputs,\n            payload=payload,\n            batch=batch,\n            encoder_hidden_states=encoder_hidden_states,\n            encoder_attention_mask=encoder_attention_mask,\n            context_latents=context_latents,\n            return_intermediate=normalized[\"return_intermediate\"],\n        )\n"
  },
  {
    "path": "acestep/core/generation/handler/service_generate_execute.py",
    "content": "\"\"\"Execution helpers for service generation diffusion and output assembly.\"\"\"\n\nimport random\nfrom typing import Any, Dict, List, Optional, Tuple\n\nimport torch\nfrom loguru import logger\n\n\nclass ServiceGenerateExecuteMixin:\n    \"\"\"Run diffusion execution for normalized service-generation requests.\"\"\"\n\n    def _unpack_service_processed_data(self, processed_data: Tuple[Any, ...]) -> Dict[str, Any]:\n        \"\"\"Convert batch preprocessing tuple into a keyed payload.\"\"\"\n        (\n            keys,\n            text_inputs,\n            src_latents,\n            target_latents,\n            text_hidden_states,\n            text_attention_mask,\n            lyric_hidden_states,\n            lyric_attention_mask,\n            _audio_attention_mask,\n            refer_audio_acoustic_hidden_states_packed,\n            refer_audio_order_mask,\n            chunk_mask,\n            spans,\n            is_covers,\n            _audio_codes,\n            lyric_token_idss,\n            precomputed_lm_hints_25Hz,\n            non_cover_text_hidden_states,\n            non_cover_text_attention_masks,\n            repaint_mask,\n        ) = processed_data\n        return {\n            \"keys\": keys,\n            \"text_inputs\": text_inputs,\n            \"src_latents\": src_latents,\n            \"target_latents\": target_latents,\n            \"text_hidden_states\": text_hidden_states,\n            \"text_attention_mask\": text_attention_mask,\n            \"lyric_hidden_states\": lyric_hidden_states,\n            \"lyric_attention_mask\": lyric_attention_mask,\n            \"refer_audio_acoustic_hidden_states_packed\": refer_audio_acoustic_hidden_states_packed,\n            \"refer_audio_order_mask\": refer_audio_order_mask,\n            \"chunk_mask\": chunk_mask,\n            \"spans\": spans,\n            \"is_covers\": is_covers,\n            \"lyric_token_idss\": lyric_token_idss,\n            \"precomputed_lm_hints_25Hz\": precomputed_lm_hints_25Hz,\n            \"non_cover_text_hidden_states\": non_cover_text_hidden_states,\n            \"non_cover_text_attention_masks\": non_cover_text_attention_masks,\n            \"repaint_mask\": repaint_mask,\n        }\n\n    def _resolve_service_seed_param(self, seed_list: Optional[List[int]]) -> Any:\n        \"\"\"Return model seed parameter: per-item seed list or random single seed.\"\"\"\n        if seed_list is not None:\n            return seed_list\n        return random.randint(0, 2**32 - 1)\n\n    def _build_service_generate_kwargs(\n        self,\n        payload: Dict[str, Any],\n        seed_param: Any,\n        infer_steps: int,\n        guidance_scale: float,\n        audio_cover_strength: float,\n        cover_noise_strength: float,\n        infer_method: str,\n        use_adg: bool,\n        cfg_interval_start: float,\n        cfg_interval_end: float,\n        shift: float,\n        timesteps: Optional[List[float]],\n        repaint_crossfade_frames: int = 10,\n        repaint_injection_ratio: float = 0.5,\n    ) -> Dict[str, Any]:\n        \"\"\"Build kwargs passed to model generation backends.\"\"\"\n        repaint_mask = payload.get(\"repaint_mask\")\n        clean_src_latents = payload.get(\"target_latents\") if repaint_mask is not None else None\n\n        kwargs = {\n            \"text_hidden_states\": payload[\"text_hidden_states\"],\n            \"text_attention_mask\": payload[\"text_attention_mask\"],\n            \"lyric_hidden_states\": payload[\"lyric_hidden_states\"],\n            \"lyric_attention_mask\": payload[\"lyric_attention_mask\"],\n            \"refer_audio_acoustic_hidden_states_packed\": payload[\"refer_audio_acoustic_hidden_states_packed\"],\n            \"refer_audio_order_mask\": payload[\"refer_audio_order_mask\"],\n            \"src_latents\": payload[\"src_latents\"],\n            \"chunk_masks\": payload[\"chunk_mask\"],\n            \"is_covers\": payload[\"is_covers\"],\n            \"silence_latent\": self.silence_latent,\n            \"seed\": seed_param,\n            \"non_cover_text_hidden_states\": payload[\"non_cover_text_hidden_states\"],\n            \"non_cover_text_attention_mask\": payload[\"non_cover_text_attention_masks\"],\n            \"precomputed_lm_hints_25Hz\": payload[\"precomputed_lm_hints_25Hz\"],\n            \"audio_cover_strength\": audio_cover_strength,\n            \"cover_noise_strength\": cover_noise_strength,\n            \"infer_method\": infer_method,\n            \"infer_steps\": infer_steps,\n            \"diffusion_guidance_sale\": guidance_scale,\n            \"use_adg\": use_adg,\n            \"cfg_interval_start\": cfg_interval_start,\n            \"cfg_interval_end\": cfg_interval_end,\n            \"shift\": shift,\n            \"repaint_mask\": repaint_mask,\n            \"clean_src_latents\": clean_src_latents,\n            \"repaint_crossfade_frames\": repaint_crossfade_frames,\n            \"repaint_injection_ratio\": repaint_injection_ratio,\n        }\n        if timesteps is not None:\n            kwargs[\"timesteps\"] = torch.tensor(timesteps, dtype=torch.float32, device=self.device)\n        return kwargs\n\n    def _execute_service_generate_diffusion(\n        self,\n        payload: Dict[str, Any],\n        generate_kwargs: Dict[str, Any],\n        seed_param: Any,\n        infer_method: str,\n        shift: float,\n        audio_cover_strength: float,\n    ) -> Tuple[Dict[str, Any], torch.Tensor, torch.Tensor, torch.Tensor]:\n        \"\"\"Execute condition preparation and diffusion using MLX or PyTorch backend.\"\"\"\n        dit_backend = (\n            \"MLX (native)\" if (self.use_mlx_dit and self.mlx_decoder is not None) else f\"PyTorch ({self.device})\"\n        )\n        logger.info(f\"[service_generate] Generating audio... (DiT backend: {dit_backend})\")\n        with torch.inference_mode():\n            with self._load_model_context(\"model\"):\n                encoder_hidden_states, encoder_attention_mask, context_latents = self.model.prepare_condition(\n                    text_hidden_states=payload[\"text_hidden_states\"],\n                    text_attention_mask=payload[\"text_attention_mask\"],\n                    lyric_hidden_states=payload[\"lyric_hidden_states\"],\n                    lyric_attention_mask=payload[\"lyric_attention_mask\"],\n                    refer_audio_acoustic_hidden_states_packed=payload[\"refer_audio_acoustic_hidden_states_packed\"],\n                    refer_audio_order_mask=payload[\"refer_audio_order_mask\"],\n                    hidden_states=payload[\"src_latents\"],\n                    attention_mask=torch.ones(\n                        payload[\"src_latents\"].shape[0],\n                        payload[\"src_latents\"].shape[1],\n                        device=payload[\"src_latents\"].device,\n                        dtype=payload[\"src_latents\"].dtype,\n                    ),\n                    silence_latent=self.silence_latent,\n                    src_latents=payload[\"src_latents\"],\n                    chunk_masks=payload[\"chunk_mask\"],\n                    is_covers=payload[\"is_covers\"],\n                    precomputed_lm_hints_25Hz=payload[\"precomputed_lm_hints_25Hz\"],\n                )\n\n                if self.use_mlx_dit and self.mlx_decoder is not None:\n                    try:\n                        enc_hs_nc, enc_am_nc, ctx_nc = None, None, None\n                        if audio_cover_strength < 1.0 and payload[\"non_cover_text_hidden_states\"] is not None:\n                            non_is_covers = torch.zeros_like(payload[\"is_covers\"])\n                            sil_exp = self.silence_latent[:, :payload[\"src_latents\"].shape[1], :].expand(\n                                payload[\"src_latents\"].shape[0], -1, -1\n                            )\n                            enc_hs_nc, enc_am_nc, ctx_nc = self.model.prepare_condition(\n                                text_hidden_states=payload[\"non_cover_text_hidden_states\"],\n                                text_attention_mask=payload[\"non_cover_text_attention_masks\"],\n                                lyric_hidden_states=payload[\"lyric_hidden_states\"],\n                                lyric_attention_mask=payload[\"lyric_attention_mask\"],\n                                refer_audio_acoustic_hidden_states_packed=payload[\"refer_audio_acoustic_hidden_states_packed\"],\n                                refer_audio_order_mask=payload[\"refer_audio_order_mask\"],\n                                hidden_states=sil_exp,\n                                attention_mask=torch.ones(\n                                    sil_exp.shape[0], sil_exp.shape[1], device=sil_exp.device, dtype=sil_exp.dtype\n                                ),\n                                silence_latent=self.silence_latent,\n                                src_latents=sil_exp,\n                                chunk_masks=payload[\"chunk_mask\"],\n                                is_covers=non_is_covers,\n                            )\n\n                        null_cond_emb = getattr(self.model, \"null_condition_emb\", None)\n\n                        outputs = self._mlx_run_diffusion(\n                            encoder_hidden_states=encoder_hidden_states,\n                            encoder_attention_mask=encoder_attention_mask,\n                            context_latents=context_latents,\n                            src_latents=payload[\"src_latents\"],\n                            seed=seed_param,\n                            infer_method=infer_method,\n                            shift=shift,\n                            timesteps=generate_kwargs.get(\"timesteps\"),\n                            infer_steps=generate_kwargs.get(\"infer_steps\"),\n                            guidance_scale=generate_kwargs.get(\"diffusion_guidance_sale\", 1.0),\n                            null_condition_emb=null_cond_emb,\n                            cfg_interval_start=generate_kwargs.get(\"cfg_interval_start\", 0.0),\n                            cfg_interval_end=generate_kwargs.get(\"cfg_interval_end\", 1.0),\n                            audio_cover_strength=audio_cover_strength,\n                            encoder_hidden_states_non_cover=enc_hs_nc,\n                            encoder_attention_mask_non_cover=enc_am_nc,\n                            context_latents_non_cover=ctx_nc,\n                        )\n                        _tc = outputs.get(\"time_costs\", {})\n                        logger.info(\n                            \"[service_generate] DiT diffusion complete via MLX (%.2fs total, %.3fs/step).\",\n                            _tc.get(\"diffusion_time_cost\", 0),\n                            _tc.get(\"diffusion_per_step_time_cost\", 0),\n                        )\n                    except Exception as exc:\n                        logger.warning(\"[service_generate] MLX diffusion failed (%s); falling back to PyTorch.\", exc)\n                        outputs = self.model.generate_audio(**generate_kwargs)\n                else:\n                    logger.info(\"[service_generate] DiT diffusion via PyTorch ({})...\", self.device)\n                    outputs = self.model.generate_audio(**generate_kwargs)\n\n        return outputs, encoder_hidden_states, encoder_attention_mask, context_latents\n"
  },
  {
    "path": "acestep/core/generation/handler/service_generate_execute_test.py",
    "content": "\"\"\"Unit tests for service-generation execution helper mixin.\"\"\"\n\nimport unittest\nfrom unittest.mock import patch\n\nimport torch\n\nfrom acestep.core.generation.handler.service_generate_execute import ServiceGenerateExecuteMixin\nfrom acestep.core.generation.handler.service_generate_outputs import ServiceGenerateOutputsMixin\n\n\nclass _Host(ServiceGenerateExecuteMixin, ServiceGenerateOutputsMixin):\n    \"\"\"Test host exposing the minimum attributes used by execute helpers.\"\"\"\n\n    def __init__(self):\n        \"\"\"Initialize static runtime fields for helper-method tests.\"\"\"\n        self.device = \"cpu\"\n        self.silence_latent = torch.zeros(1, 4, 4, dtype=torch.float32)\n\n\nclass ServiceGenerateExecuteMixinTests(unittest.TestCase):\n    \"\"\"Validate helper behavior for kwargs and output assembly.\"\"\"\n\n    def test_build_generate_kwargs_adds_timesteps_tensor(self):\n        \"\"\"Timesteps input should be converted to a device tensor in kwargs.\"\"\"\n        host = _Host()\n        payload = {\n            \"text_hidden_states\": torch.zeros(1, 2),\n            \"text_attention_mask\": torch.ones(1, 2),\n            \"lyric_hidden_states\": torch.zeros(1, 2),\n            \"lyric_attention_mask\": torch.ones(1, 2),\n            \"refer_audio_acoustic_hidden_states_packed\": torch.zeros(1, 2),\n            \"refer_audio_order_mask\": torch.zeros(1, dtype=torch.long),\n            \"src_latents\": torch.zeros(1, 4, 4),\n            \"chunk_mask\": torch.ones(1, 4, dtype=torch.bool),\n            \"is_covers\": torch.tensor([True]),\n            \"non_cover_text_hidden_states\": None,\n            \"non_cover_text_attention_masks\": None,\n            \"precomputed_lm_hints_25Hz\": None,\n        }\n        kwargs = host._build_service_generate_kwargs(\n            payload=payload,\n            seed_param=123,\n            infer_steps=16,\n            guidance_scale=7.0,\n            audio_cover_strength=1.0,\n            cover_noise_strength=0.0,\n            infer_method=\"ode\",\n            use_adg=False,\n            cfg_interval_start=0.0,\n            cfg_interval_end=1.0,\n            shift=1.0,\n            timesteps=[1.0, 0.5],\n        )\n\n        self.assertIn(\"timesteps\", kwargs)\n        self.assertEqual(kwargs[\"seed\"], 123)\n        self.assertEqual(kwargs[\"infer_steps\"], 16)\n        self.assertEqual(kwargs[\"timesteps\"].dtype, torch.float32)\n        self.assertEqual(kwargs[\"timesteps\"].device.type, \"cpu\")\n\n    def test_attach_service_outputs_persists_required_fields(self):\n        \"\"\"Attached payload fields should be available to downstream handlers.\"\"\"\n        host = _Host()\n        payload = {\n            \"src_latents\": torch.zeros(1, 4, 4),\n            \"target_latents\": torch.ones(1, 4, 4),\n            \"chunk_mask\": torch.ones(1, 4, dtype=torch.bool),\n            \"spans\": [(\"full\", 0, 4)],\n            \"lyric_token_idss\": torch.ones(1, 3, dtype=torch.long),\n        }\n        outputs = host._attach_service_generate_outputs(\n            outputs={\"target_latents\": torch.zeros(1, 4, 4)},\n            payload=payload,\n            batch={\"latent_masks\": torch.ones(1, 4, dtype=torch.long)},\n            encoder_hidden_states=torch.zeros(1, 2),\n            encoder_attention_mask=torch.ones(1, 2),\n            context_latents=torch.zeros(1, 2),\n        )\n\n        self.assertIn(\"src_latents\", outputs)\n        self.assertIn(\"target_latents_input\", outputs)\n        self.assertIn(\"latent_masks\", outputs)\n        self.assertIn(\"encoder_hidden_states\", outputs)\n        self.assertIn(\"lyric_token_idss\", outputs)\n\n    def test_resolve_seed_param_none_uses_random_seed(self):\n        \"\"\"None seed list should produce a random integer seed parameter.\"\"\"\n        host = _Host()\n        with patch(\"acestep.core.generation.handler.service_generate_execute.random.randint\", return_value=42):\n            seed_param = host._resolve_service_seed_param(None)\n        self.assertEqual(seed_param, 42)\n\n\nif __name__ == \"__main__\":\n    unittest.main()\n"
  },
  {
    "path": "acestep/core/generation/handler/service_generate_outputs.py",
    "content": "\"\"\"Output assembly helpers for service generation.\"\"\"\n\nfrom typing import Any, Dict\n\nimport torch\n\n\nclass ServiceGenerateOutputsMixin:\n    \"\"\"Attach service-generation intermediates required by downstream flows.\"\"\"\n\n    def _attach_service_generate_outputs(\n        self,\n        outputs: Dict[str, Any],\n        payload: Dict[str, Any],\n        batch: Dict[str, Any],\n        encoder_hidden_states: torch.Tensor,\n        encoder_attention_mask: torch.Tensor,\n        context_latents: torch.Tensor,\n        return_intermediate: bool = True,\n    ) -> Dict[str, Any]:\n        \"\"\"Attach intermediate tensors required by downstream consumers.\"\"\"\n        outputs[\"spans\"] = payload[\"spans\"]\n        if not return_intermediate:\n            return outputs\n\n        outputs[\"src_latents\"] = payload[\"src_latents\"]\n        outputs[\"target_latents_input\"] = payload[\"target_latents\"]\n        outputs[\"chunk_masks\"] = payload[\"chunk_mask\"]\n        outputs[\"latent_masks\"] = batch.get(\"latent_masks\")\n        outputs[\"encoder_hidden_states\"] = encoder_hidden_states\n        outputs[\"encoder_attention_mask\"] = encoder_attention_mask\n        outputs[\"context_latents\"] = context_latents\n        outputs[\"lyric_token_idss\"] = payload[\"lyric_token_idss\"]\n        return outputs\n"
  },
  {
    "path": "acestep/core/generation/handler/service_generate_request.py",
    "content": "\"\"\"Input normalization and batch preparation helpers for service generation.\"\"\"\n\nimport random\nfrom typing import Any, Dict, List, Optional, Union\n\nfrom loguru import logger\n\nfrom acestep.constants import DEFAULT_DIT_INSTRUCTION\n\n# Maximum batch size supported per coding guidelines\n# (batch operations are supported up to 8 songs)\nMAX_BATCH_SIZE = 8\n\n\nclass ServiceGenerateRequestMixin:\n    \"\"\"Prepare normalized service-generation inputs before diffusion execution.\"\"\"\n\n    def _build_service_seed_list(\n        self,\n        seed: Optional[Union[int, List[int]]],\n        batch_size: int,\n    ) -> Optional[List[int]]:\n        \"\"\"Normalize ``seed`` into a per-item list or ``None`` for random sampling.\"\"\"\n        if seed is None:\n            return None\n        if isinstance(seed, list):\n            seed_list = list(seed)\n            if len(seed_list) < batch_size:\n                while len(seed_list) < batch_size:\n                    seed_list.append(random.randint(0, 2**32 - 1))\n            elif len(seed_list) > batch_size:\n                seed_list = seed_list[:batch_size]\n            return seed_list\n        return [int(seed)] * batch_size\n\n    def _normalize_service_generate_inputs(\n        self,\n        captions: Union[str, List[str]],\n        lyrics: Union[str, List[str]],\n        keys: Optional[Union[str, List[str]]],\n        metas: Optional[Union[str, Dict[str, Any], List[Union[str, Dict[str, Any]]]]],\n        vocal_languages: Optional[Union[str, List[str]]],\n        repainting_start: Optional[Union[float, List[float]]],\n        repainting_end: Optional[Union[float, List[float]]],\n        instructions: Optional[Union[str, List[str]]],\n        audio_code_hints: Optional[Union[str, List[str]]],\n        infer_steps: int,\n        seed: Optional[Union[int, List[int]]],\n        return_intermediate: bool = False,\n    ) -> Dict[str, Any]:\n        \"\"\"Normalize scalar/list generation inputs and clamp turbo infer steps.\"\"\"\n        if self.config.is_turbo and infer_steps > 8:\n            logger.warning(\n                \"[service_generate] dmd_gan version: infer_steps {} exceeds maximum 8, clamping to 8\",\n                infer_steps,\n            )\n            infer_steps = 8\n\n        # Convert captions to list and determine batch size\n        if isinstance(captions, str):\n            captions = [captions]\n        \n        batch_size = len(captions)\n        \n        # Validate and clamp batch size to maximum supported\n        if batch_size > MAX_BATCH_SIZE:\n            logger.warning(\n                \"[service_generate] Batch size {} exceeds maximum supported batch size ({}). \"\n                \"Clamping to {}.\",\n                batch_size,\n                MAX_BATCH_SIZE,\n                MAX_BATCH_SIZE,\n            )\n            batch_size = MAX_BATCH_SIZE\n            captions = captions[:batch_size]\n        \n        # Now convert other inputs to lists, using the clamped batch_size\n        if isinstance(lyrics, str):\n            lyrics = [lyrics]\n        if isinstance(keys, str):\n            keys = [keys]\n        if isinstance(vocal_languages, str):\n            vocal_languages = [vocal_languages]\n        if isinstance(metas, (str, dict)):\n            metas = [metas]\n        if isinstance(repainting_start, (int, float)):\n            repainting_start = [repainting_start]\n        if isinstance(repainting_end, (int, float)):\n            repainting_end = [repainting_end]\n        \n        # Truncate list inputs that exceed clamped batch size\n        if keys is not None and len(keys) > batch_size:\n            keys = keys[:batch_size]\n        if metas is not None and len(metas) > batch_size:\n            metas = metas[:batch_size]\n        if vocal_languages is not None and len(vocal_languages) > batch_size:\n            vocal_languages = vocal_languages[:batch_size]\n        if repainting_start is not None and len(repainting_start) > batch_size:\n            repainting_start = repainting_start[:batch_size]\n        if repainting_end is not None and len(repainting_end) > batch_size:\n            repainting_end = repainting_end[:batch_size]\n        \n        if len(lyrics) < batch_size:\n            fill = lyrics[-1] if lyrics else \"\"\n            lyrics = list(lyrics) + [fill] * (batch_size - len(lyrics))\n        elif len(lyrics) > batch_size:\n            lyrics = lyrics[:batch_size]\n\n        if instructions is not None:\n            instructions = self._normalize_instructions(\n                instructions,\n                batch_size,\n                DEFAULT_DIT_INSTRUCTION,\n            )\n        if audio_code_hints is not None:\n            audio_code_hints = self._normalize_audio_code_hints(audio_code_hints, batch_size)\n\n        return {\n            \"captions\": captions,\n            \"lyrics\": lyrics,\n            \"keys\": keys,\n            \"metas\": metas,\n            \"vocal_languages\": vocal_languages,\n            \"repainting_start\": repainting_start,\n            \"repainting_end\": repainting_end,\n            \"instructions\": instructions,\n            \"audio_code_hints\": audio_code_hints,\n            \"infer_steps\": infer_steps,\n            \"seed_list\": self._build_service_seed_list(seed=seed, batch_size=batch_size),\n            \"return_intermediate\": return_intermediate,\n        }\n"
  },
  {
    "path": "acestep/core/generation/handler/service_generate_request_test.py",
    "content": "\"\"\"Unit tests for service-generation request normalization helpers.\"\"\"\n\nimport types\nimport unittest\nfrom unittest.mock import patch\n\nfrom acestep.core.generation.handler.service_generate_request import ServiceGenerateRequestMixin\n\n\nclass _Host(ServiceGenerateRequestMixin):\n    \"\"\"Test host exposing the minimum runtime attributes for request helpers.\"\"\"\n\n    def __init__(self, is_turbo: bool):\n        \"\"\"Configure turbo flag and no-op normalizers.\"\"\"\n        self.config = types.SimpleNamespace(is_turbo=is_turbo)\n        self._normalize_instructions = lambda instructions, _batch, _default: instructions\n        self._normalize_audio_code_hints = lambda hints, _batch: hints\n\n\nclass ServiceGenerateRequestMixinTests(unittest.TestCase):\n    \"\"\"Verify request normalization behavior stays stable after extraction.\"\"\"\n\n    def test_normalize_inputs_clamps_turbo_steps_and_expands_lists(self):\n        \"\"\"Turbo path should clamp infer steps and normalize list-like inputs.\"\"\"\n        host = _Host(is_turbo=True)\n        out = host._normalize_service_generate_inputs(\n            captions=\"cap\",\n            lyrics=[\"lyric\"],\n            keys=\"k1\",\n            metas={\"bpm\": 120},\n            vocal_languages=\"en\",\n            repainting_start=0.1,\n            repainting_end=1.2,\n            instructions=[\"i1\"],\n            audio_code_hints=[\"h1\"],\n            infer_steps=20,\n            seed=[1],\n        )\n\n        self.assertEqual(out[\"infer_steps\"], 8)\n        self.assertEqual(out[\"captions\"], [\"cap\"])\n        self.assertEqual(out[\"lyrics\"], [\"lyric\"])\n        self.assertEqual(out[\"keys\"], [\"k1\"])\n        self.assertEqual(out[\"metas\"], [{\"bpm\": 120}])\n        self.assertEqual(out[\"vocal_languages\"], [\"en\"])\n        self.assertEqual(out[\"repainting_start\"], [0.1])\n        self.assertEqual(out[\"repainting_end\"], [1.2])\n        self.assertEqual(out[\"seed_list\"], [1])\n\n    def test_build_service_seed_list_duplicates_scalar_seed(self):\n        \"\"\"Scalar seed should be copied across the normalized batch size.\"\"\"\n        host = _Host(is_turbo=False)\n        out = host._normalize_service_generate_inputs(\n            captions=[\"a\", \"b\", \"c\"],\n            lyrics=[\"l1\"],\n            keys=None,\n            metas=None,\n            vocal_languages=None,\n            repainting_start=None,\n            repainting_end=None,\n            instructions=None,\n            audio_code_hints=None,\n            infer_steps=12,\n            seed=7,\n        )\n\n        self.assertEqual(out[\"infer_steps\"], 12)\n        self.assertEqual(out[\"lyrics\"], [\"l1\", \"l1\", \"l1\"])\n        self.assertEqual(out[\"seed_list\"], [7, 7, 7])\n\n    def test_seed_list_shorter_than_batch_gets_padded(self):\n        \"\"\"Short seed lists should preserve existing entries and append random seeds.\"\"\"\n        host = _Host(is_turbo=False)\n        with patch(\"acestep.core.generation.handler.service_generate_request.random.randint\", return_value=99):\n            out = host._normalize_service_generate_inputs(\n                captions=[\"a\", \"b\", \"c\"],\n                lyrics=[\"l1\"],\n                keys=None,\n                metas=None,\n                vocal_languages=None,\n                repainting_start=None,\n                repainting_end=None,\n                instructions=None,\n                audio_code_hints=None,\n                infer_steps=12,\n                seed=[3],\n            )\n        self.assertEqual(out[\"seed_list\"], [3, 99, 99])\n\n    def test_seed_list_longer_than_batch_gets_truncated(self):\n        \"\"\"Long seed lists should be truncated to batch size.\"\"\"\n        host = _Host(is_turbo=False)\n        out = host._normalize_service_generate_inputs(\n            captions=[\"a\", \"b\"],\n            lyrics=[\"l1\"],\n            keys=None,\n            metas=None,\n            vocal_languages=None,\n            repainting_start=None,\n            repainting_end=None,\n            instructions=None,\n            audio_code_hints=None,\n            infer_steps=12,\n            seed=[11, 12, 13, 14],\n        )\n        self.assertEqual(out[\"seed_list\"], [11, 12])\n\n    def test_lyrics_longer_than_batch_get_truncated(self):\n        \"\"\"Lyrics list should be truncated to match caption batch size.\"\"\"\n        host = _Host(is_turbo=False)\n        out = host._normalize_service_generate_inputs(\n            captions=[\"a\", \"b\"],\n            lyrics=[\"l1\", \"l2\", \"l3\"],\n            keys=None,\n            metas=None,\n            vocal_languages=None,\n            repainting_start=None,\n            repainting_end=None,\n            instructions=None,\n            audio_code_hints=None,\n            infer_steps=12,\n            seed=[1, 2],\n        )\n        self.assertEqual(out[\"lyrics\"], [\"l1\", \"l2\"])\n\n    def test_batch_size_at_maximum_is_not_clamped(self):\n        \"\"\"Batch size exactly at MAX_BATCH_SIZE (8) should not be clamped.\"\"\"\n        host = _Host(is_turbo=False)\n        captions = [f\"caption_{i}\" for i in range(8)]\n        out = host._normalize_service_generate_inputs(\n            captions=captions,\n            lyrics=[\"lyric\"],\n            keys=None,\n            metas=None,\n            vocal_languages=None,\n            repainting_start=None,\n            repainting_end=None,\n            instructions=None,\n            audio_code_hints=None,\n            infer_steps=12,\n            seed=None,\n        )\n        self.assertEqual(len(out[\"captions\"]), 8)\n        self.assertEqual(out[\"captions\"], captions)\n        self.assertEqual(len(out[\"lyrics\"]), 8)\n\n    def test_batch_size_exceeds_maximum_gets_clamped(self):\n        \"\"\"Batch size exceeding MAX_BATCH_SIZE (8) should be clamped to 8.\"\"\"\n        host = _Host(is_turbo=False)\n        captions = [f\"caption_{i}\" for i in range(10)]\n        out = host._normalize_service_generate_inputs(\n            captions=captions,\n            lyrics=[\"lyric\"],\n            keys=None,\n            metas=None,\n            vocal_languages=None,\n            repainting_start=None,\n            repainting_end=None,\n            instructions=None,\n            audio_code_hints=None,\n            infer_steps=12,\n            seed=None,\n        )\n        # Batch size should be clamped to 8\n        self.assertEqual(len(out[\"captions\"]), 8)\n        self.assertEqual(out[\"captions\"], captions[:8])\n        # Lyrics should be expanded to match clamped batch size\n        self.assertEqual(len(out[\"lyrics\"]), 8)\n        # Seed list should match clamped batch size\n        self.assertIsNone(out[\"seed_list\"])\n\n    def test_batch_size_clamping_with_seed_list(self):\n        \"\"\"Batch size clamping should work correctly with seed lists.\"\"\"\n        host = _Host(is_turbo=False)\n        captions = [f\"caption_{i}\" for i in range(12)]\n        seeds = [i for i in range(12)]\n        out = host._normalize_service_generate_inputs(\n            captions=captions,\n            lyrics=[\"lyric\"],\n            keys=None,\n            metas=None,\n            vocal_languages=None,\n            repainting_start=None,\n            repainting_end=None,\n            instructions=None,\n            audio_code_hints=None,\n            infer_steps=12,\n            seed=seeds,\n        )\n        # Batch size should be clamped to 8\n        self.assertEqual(len(out[\"captions\"]), 8)\n        # Seed list should be generated for clamped batch size of 8\n        self.assertEqual(len(out[\"seed_list\"]), 8)\n        self.assertEqual(out[\"seed_list\"], seeds[:8])\n\n    def test_batch_size_below_maximum_is_not_affected(self):\n        \"\"\"Batch sizes below MAX_BATCH_SIZE should pass through unchanged.\"\"\"\n        host = _Host(is_turbo=False)\n        for batch_size in [1, 2, 4, 7]:\n            captions = [f\"caption_{i}\" for i in range(batch_size)]\n            out = host._normalize_service_generate_inputs(\n                captions=captions,\n                lyrics=[\"lyric\"],\n                keys=None,\n                metas=None,\n                vocal_languages=None,\n                repainting_start=None,\n                repainting_end=None,\n                instructions=None,\n                audio_code_hints=None,\n                infer_steps=12,\n                seed=None,\n            )\n            self.assertEqual(len(out[\"captions\"]), batch_size)\n            self.assertEqual(out[\"captions\"], captions)\n\n    def test_batch_size_clamping_truncates_all_list_fields(self):\n        \"\"\"Batch size clamping should truncate all optional list fields.\"\"\"\n        host = _Host(is_turbo=False)\n        # Create lists with 10 items each\n        captions = [f\"caption_{i}\" for i in range(10)]\n        keys = [f\"key_{i}\" for i in range(10)]\n        metas = [{\"id\": i} for i in range(10)]\n        vocal_languages = [f\"lang_{i}\" for i in range(10)]\n        repainting_start = [float(i) for i in range(10)]\n        repainting_end = [float(i + 1) for i in range(10)]\n        \n        out = host._normalize_service_generate_inputs(\n            captions=captions,\n            lyrics=[\"lyric\"],\n            keys=keys,\n            metas=metas,\n            vocal_languages=vocal_languages,\n            repainting_start=repainting_start,\n            repainting_end=repainting_end,\n            instructions=None,\n            audio_code_hints=None,\n            infer_steps=12,\n            seed=None,\n        )\n        \n        # All fields should be clamped to 8\n        self.assertEqual(len(out[\"captions\"]), 8)\n        self.assertEqual(out[\"captions\"], captions[:8])\n        self.assertEqual(len(out[\"keys\"]), 8)\n        self.assertEqual(out[\"keys\"], keys[:8])\n        self.assertEqual(len(out[\"metas\"]), 8)\n        self.assertEqual(out[\"metas\"], metas[:8])\n        self.assertEqual(len(out[\"vocal_languages\"]), 8)\n        self.assertEqual(out[\"vocal_languages\"], vocal_languages[:8])\n        self.assertEqual(len(out[\"repainting_start\"]), 8)\n        self.assertEqual(out[\"repainting_start\"], repainting_start[:8])\n        self.assertEqual(len(out[\"repainting_end\"]), 8)\n        self.assertEqual(out[\"repainting_end\"], repainting_end[:8])\n        self.assertEqual(len(out[\"lyrics\"]), 8)\n\n    def test_batch_size_clamping_with_single_value_fields(self):\n        \"\"\"Batch size clamping should work correctly when single values are expanded.\"\"\"\n        host = _Host(is_turbo=False)\n        # 10 captions but single values for other fields\n        captions = [f\"caption_{i}\" for i in range(10)]\n        \n        out = host._normalize_service_generate_inputs(\n            captions=captions,\n            lyrics=\"single_lyric\",\n            keys=\"single_key\",\n            metas={\"bpm\": 120},\n            vocal_languages=\"en\",\n            repainting_start=0.5,\n            repainting_end=1.5,\n            instructions=None,\n            audio_code_hints=None,\n            infer_steps=12,\n            seed=42,\n        )\n        \n        # Batch size should be clamped to 8\n        self.assertEqual(len(out[\"captions\"]), 8)\n        self.assertEqual(out[\"captions\"], captions[:8])\n        # Single values are converted to single-item lists (not expanded to batch size)\n        # This matches the original behavior - only lyrics/instructions/audio_code_hints expand\n        self.assertEqual(len(out[\"keys\"]), 1)  # Single value becomes list of 1\n        self.assertEqual(out[\"keys\"], [\"single_key\"])\n        self.assertEqual(len(out[\"metas\"]), 1)  # Single value becomes list of 1\n        self.assertEqual(out[\"metas\"], [{\"bpm\": 120}])\n        self.assertEqual(len(out[\"vocal_languages\"]), 1)  # Single value becomes list of 1\n        self.assertEqual(out[\"vocal_languages\"], [\"en\"])\n        self.assertEqual(len(out[\"repainting_start\"]), 1)  # Single value becomes list of 1\n        self.assertEqual(out[\"repainting_start\"], [0.5])\n        self.assertEqual(len(out[\"repainting_end\"]), 1)  # Single value becomes list of 1\n        self.assertEqual(out[\"repainting_end\"], [1.5])\n        # Lyrics should be expanded to match clamped batch size\n        self.assertEqual(len(out[\"lyrics\"]), 8)\n        self.assertEqual(out[\"lyrics\"], [\"single_lyric\"] * 8)\n        # Seed should create list for clamped batch size\n        self.assertEqual(len(out[\"seed_list\"]), 8)\n        self.assertEqual(out[\"seed_list\"], [42] * 8)\n\n\nif __name__ == \"__main__\":\n    unittest.main()\n"
  },
  {
    "path": "acestep/core/generation/handler/service_generate_test.py",
    "content": "\"\"\"Unit tests for extracted service-generation orchestration.\n\nThis test module loads ``service_generate.py`` directly from file to avoid\npackage import side effects, then validates that orchestration wiring and\nruntime-control forwarding remain stable after extraction.\n\"\"\"\n\nimport importlib.util\nimport sys\nimport types\nimport unittest\nfrom pathlib import Path\n\n\ndef _load_service_generate_module():\n    \"\"\"Load ``acestep.core.generation.handler.service_generate`` from disk.\n\n    Inputs:\n        Resolves the repository root from this file path, injects it into\n        ``sys.path``, and stubs package modules in ``sys.modules``.\n\n    Returns:\n        The loaded module object for\n        ``acestep.core.generation.handler.service_generate``.\n\n    Raises:\n        AssertionError: If import spec loader cannot be created.\n        ImportError: If module loading fails.\n        OSError: If the module file cannot be read.\n    \"\"\"\n    repo_root = Path(__file__).resolve().parents[4]\n    if str(repo_root) not in sys.path:\n        sys.path.insert(0, str(repo_root))\n    package_paths = {\n        \"acestep\": repo_root / \"acestep\",\n        \"acestep.core\": repo_root / \"acestep\" / \"core\",\n        \"acestep.core.generation\": repo_root / \"acestep\" / \"core\" / \"generation\",\n        \"acestep.core.generation.handler\": repo_root / \"acestep\" / \"core\" / \"generation\" / \"handler\",\n    }\n    for package_name, package_path in package_paths.items():\n        if package_name in sys.modules:\n            continue\n        package_module = types.ModuleType(package_name)\n        package_module.__path__ = [str(package_path)]\n        sys.modules[package_name] = package_module\n    module_path = Path(__file__).with_name(\"service_generate.py\")\n    spec = importlib.util.spec_from_file_location(\"acestep.core.generation.handler.service_generate\", module_path)\n    module = importlib.util.module_from_spec(spec)\n    assert spec.loader is not None\n    spec.loader.exec_module(module)\n    return module\n\n\n# Import context: load extracted mixin directly to isolate tests from package side effects.\nSERVICE_GENERATE_MODULE = _load_service_generate_module()\nServiceGenerateMixin = SERVICE_GENERATE_MODULE.ServiceGenerateMixin\n\n\nclass _Host(ServiceGenerateMixin):\n    \"\"\"Minimal orchestration host used to record helper invocations.\n\n    Exposes deterministic fixture state and a ``calls`` dictionary for asserted\n    input/output forwarding across normalize, diffusion, and attachment helpers.\n    \"\"\"\n\n    def __init__(self):\n        \"\"\"Initialize deterministic fixtures and return values for helper stubs.\"\"\"\n        self.calls = {}\n        self.normalized = {\n            \"captions\": [\"cap\"], \"lyrics\": [\"lyr\"], \"keys\": [\"k1\"], \"metas\": [{\"bpm\": 120}],\n            \"vocal_languages\": [\"en\"], \"repainting_start\": [0.0], \"repainting_end\": [12.0],\n            \"instructions\": [\"ins\"], \"audio_code_hints\": [\"hint\"], \"infer_steps\": 77, \"seed_list\": [101],\n        }\n        self.batch = {\"batch\": \"prepared\"}\n        self.processed = {\"processed\": \"batch\"}\n        self.payload = {\"payload\": \"ready\"}\n        self.seed_param = 314\n        self.generate_kwargs = {\"gw\": \"args\"}\n        self.diffusion_outputs = (\"outputs\", \"ehs\", \"eam\", \"ctx\")\n        self.final_payload = {\"result\": \"ok\"}\n        self._returns = {\n            \"_prepare_batch\": lambda _a, _k: self.batch,\n            \"preprocess_batch\": lambda _a, _k: self.processed,\n            \"_unpack_service_processed_data\": lambda _a, _k: self.payload,\n            \"_resolve_service_seed_param\": lambda _a, _k: self.seed_param,\n            \"_ensure_silence_latent_on_device\": lambda _a, _k: None,\n            \"_build_service_generate_kwargs\": lambda _a, _k: self.generate_kwargs,\n            \"_execute_service_generate_diffusion\": lambda _a, _k: self.diffusion_outputs,\n            \"_attach_service_generate_outputs\": lambda _a, _k: self.final_payload,\n        }\n\n    def _normalize_service_generate_inputs(self, **kwargs):\n        \"\"\"Capture normalize args and return deterministic normalized payload.\"\"\"\n        self.calls[\"_normalize_service_generate_inputs\"] = kwargs\n        out = dict(self.normalized)\n        out[\"return_intermediate\"] = kwargs[\"return_intermediate\"]\n        return out\n\n    def __getattr__(self, name):\n        \"\"\"Create and return a recording helper stub for known mixin dependencies.\"\"\"\n        if name not in self._returns:\n            raise AttributeError(name)\n\n        def _stub(*args, **kwargs):\n            \"\"\"Record call arguments and return deterministic fixture data.\"\"\"\n            self.calls[name] = kwargs if kwargs else (args[0] if len(args) == 1 else args if args else True)\n            return self._returns[name](args, kwargs)\n\n        return _stub\n\n\nclass ServiceGenerateMixinTests(unittest.TestCase):\n    \"\"\"Verify service-generate entrypoint orchestration after extraction.\"\"\"\n\n    def test_service_generate_orchestrates_helpers_and_returns_attached_outputs(self):\n        \"\"\"It executes helper stages in order and returns attached final outputs.\"\"\"\n        host = _Host()\n        out = host.service_generate(captions=\"cap\", lyrics=\"lyr\", infer_steps=10, seed=7, return_intermediate=True)\n        self.assertEqual(out, host.final_payload)\n        self.assertEqual(host.calls[\"_normalize_service_generate_inputs\"][\"infer_steps\"], 10)\n        self.assertEqual(host.calls[\"_normalize_service_generate_inputs\"][\"seed\"], 7)\n        self.assertTrue(host.calls[\"_normalize_service_generate_inputs\"][\"return_intermediate\"])\n        self.assertEqual(host.calls[\"_prepare_batch\"][\"captions\"], host.normalized[\"captions\"])\n        self.assertEqual(host.calls[\"_resolve_service_seed_param\"], host.normalized[\"seed_list\"])\n        self.assertTrue(host.calls[\"_attach_service_generate_outputs\"][\"return_intermediate\"])\n\n    def test_service_generate_forwards_runtime_controls_to_build_and_execute(self):\n        \"\"\"It forwards runtime tuning controls to downstream helper invocations.\"\"\"\n        host = _Host()\n        custom_timesteps = [1.0, 0.5, 0.0]\n        host.service_generate(\n            captions=\"cap\", lyrics=\"lyr\", guidance_scale=9.5, audio_cover_strength=0.7,\n            cover_noise_strength=0.2, use_adg=True, cfg_interval_start=0.1, cfg_interval_end=0.9,\n            shift=1.3, infer_method=\"sde\", timesteps=custom_timesteps, return_intermediate=False,\n        )\n        build_kwargs = host.calls[\"_build_service_generate_kwargs\"]\n        self.assertEqual(build_kwargs[\"guidance_scale\"], 9.5)\n        self.assertEqual(build_kwargs[\"audio_cover_strength\"], 0.7)\n        self.assertEqual(build_kwargs[\"cover_noise_strength\"], 0.2)\n        self.assertTrue(build_kwargs[\"use_adg\"])\n        self.assertEqual(build_kwargs[\"timesteps\"], custom_timesteps)\n        self.assertFalse(host.calls[\"_attach_service_generate_outputs\"][\"return_intermediate\"])\n        execute_kwargs = host.calls[\"_execute_service_generate_diffusion\"]\n        self.assertEqual(execute_kwargs[\"infer_method\"], \"sde\")\n        self.assertEqual(execute_kwargs[\"shift\"], 1.3)\n        self.assertEqual(execute_kwargs[\"audio_cover_strength\"], 0.7)\n\n\nif __name__ == \"__main__\":\n    unittest.main()\n"
  },
  {
    "path": "acestep/core/generation/handler/task_utils.py",
    "content": "\"\"\"Task and seed helpers for handler decomposition.\"\"\"\n\nimport random\nfrom typing import List, Optional, Tuple\n\nimport torch\nfrom loguru import logger\n\nfrom acestep.constants import TASK_INSTRUCTIONS\n\n\nclass TaskUtilsMixin:\n    \"\"\"Mixin containing generation task and seed utility helpers.\n\n    Depends on host members:\n    - No required cross-mixin attributes for seed/instruction helpers.\n    \"\"\"\n\n    def prepare_seeds(\n        self, actual_batch_size: int, seed, use_random_seed: bool\n    ) -> Tuple[List[int], str]:\n        \"\"\"Prepare per-item seeds and UI seed string.\"\"\"\n        actual_seed_list: List[int] = []\n        seed_value_for_ui = \"\"\n        try:\n            if use_random_seed:\n                actual_seed_list = [random.randint(0, 2**32 - 1) for _ in range(actual_batch_size)]\n                seed_value_for_ui = \", \".join(str(s) for s in actual_seed_list)\n            else:\n                seed_list: List[int] = []\n                if isinstance(seed, str):\n                    for s in [s.strip() for s in seed.split(\",\")]:\n                        if s == \"-1\" or s == \"\":\n                            seed_list.append(-1)\n                        else:\n                            try:\n                                seed_list.append(int(float(s)))\n                            except (ValueError, TypeError) as exc:\n                                logger.debug(f\"[prepare_seeds] Failed to parse seed value '{s}': {exc}\")\n                                seed_list.append(-1)\n                elif seed is None or (isinstance(seed, (int, float)) and seed < 0):\n                    seed_list = [-1] * actual_batch_size\n                elif isinstance(seed, (int, float)):\n                    seed_list = [int(seed)]\n                else:\n                    seed_list = [-1] * actual_batch_size\n\n                has_single_non_negative_seed = len(seed_list) == 1 and seed_list[0] != -1\n                for i in range(actual_batch_size):\n                    seed_val = seed_list[i] if i < len(seed_list) else -1\n                    if has_single_non_negative_seed and actual_batch_size > 1 and i > 0:\n                        actual_seed_list.append(random.randint(0, 2**32 - 1))\n                    elif seed_val == -1:\n                        actual_seed_list.append(random.randint(0, 2**32 - 1))\n                    else:\n                        actual_seed_list.append(int(seed_val))\n                seed_value_for_ui = \", \".join(str(s) for s in actual_seed_list)\n        except (TypeError, ValueError, OverflowError):\n            logger.exception(\"[prepare_seeds] Failed to prepare seeds\")\n            actual_seed_list = [random.randint(0, 2**32 - 1) for _ in range(actual_batch_size)]\n            seed_value_for_ui = \", \".join(str(s) for s in actual_seed_list)\n\n        return actual_seed_list, seed_value_for_ui\n\n    def generate_instruction(\n        self,\n        task_type: str,\n        track_name: Optional[str] = None,\n        complete_track_classes: Optional[List[str]] = None,\n    ) -> str:\n        \"\"\"Generate task instruction text from task type and track context.\"\"\"\n        if task_type == \"text2music\":\n            return TASK_INSTRUCTIONS[\"text2music\"]\n        if task_type == \"repaint\":\n            return TASK_INSTRUCTIONS[\"repaint\"]\n        if task_type == \"cover\":\n            return TASK_INSTRUCTIONS[\"cover\"]\n        if task_type == \"extract\":\n            return (\n                TASK_INSTRUCTIONS[\"extract\"].format(TRACK_NAME=track_name.upper())\n                if track_name\n                else TASK_INSTRUCTIONS[\"extract_default\"]\n            )\n        if task_type == \"lego\":\n            return (\n                TASK_INSTRUCTIONS[\"lego\"].format(TRACK_NAME=track_name.upper())\n                if track_name\n                else TASK_INSTRUCTIONS[\"lego_default\"]\n            )\n        if task_type == \"complete\":\n            if complete_track_classes and len(complete_track_classes) > 0:\n                track_classes_upper = [t.upper() for t in complete_track_classes]\n                return TASK_INSTRUCTIONS[\"complete\"].format(\n                    TRACK_CLASSES=\" | \".join(track_classes_upper)\n                )\n            return TASK_INSTRUCTIONS[\"complete_default\"]\n        return TASK_INSTRUCTIONS[\"text2music\"]\n\n    def determine_task_type(self, task_type, audio_code_string):\n        \"\"\"Compute task-mode booleans for downstream generation logic.\"\"\"\n        is_repaint_task = task_type == \"repaint\"\n        is_lego_task = task_type == \"lego\"\n        is_cover_task = task_type == \"cover\"\n\n        if isinstance(audio_code_string, list):\n            has_codes = any((c or \"\").strip() for c in audio_code_string)\n        else:\n            has_codes = bool(audio_code_string and str(audio_code_string).strip())\n\n        if has_codes:\n            is_cover_task = True\n        can_use_repainting = is_repaint_task or is_lego_task\n        return is_repaint_task, is_lego_task, is_cover_task, can_use_repainting\n\n    def create_target_wavs(self, duration_seconds: float) -> torch.Tensor:\n        \"\"\"Create silent stereo target audio with safe duration handling.\"\"\"\n        try:\n            duration_seconds = max(0.1, round(duration_seconds, 1))\n            frames = int(duration_seconds * 48000)\n            return torch.zeros(2, frames)\n        except (TypeError, ValueError, OverflowError):\n            logger.exception(\"[create_target_wavs] Error creating target audio\")\n            return torch.zeros(2, 30 * 48000)\n"
  },
  {
    "path": "acestep/core/generation/handler/task_utils_test.py",
    "content": "\"\"\"Unit tests for TaskUtilsMixin helper methods.\"\"\"\n\nimport unittest\n\nfrom acestep.core.generation.handler.task_utils import TaskUtilsMixin\n\n\nclass _Host(TaskUtilsMixin):\n    \"\"\"Minimal host implementing TaskUtilsMixin dependencies.\"\"\"\n\n\nclass DetermineTaskTypeTests(unittest.TestCase):\n    \"\"\"Validate task-mode boolean computation in determine_task_type.\"\"\"\n\n    def setUp(self):\n        self.host = _Host()\n\n    def test_repaint_task_enables_repainting(self):\n        \"\"\"Repaint task should set can_use_repainting=True.\"\"\"\n        is_repaint, is_lego, is_cover, can_repaint = self.host.determine_task_type(\"repaint\", None)\n        self.assertTrue(is_repaint)\n        self.assertFalse(is_lego)\n        self.assertFalse(is_cover)\n        self.assertTrue(can_repaint)\n\n    def test_lego_task_enables_repainting_for_chunk_mask(self):\n        \"\"\"Lego task should set can_use_repainting=True so the chunk mask is computed\n        from repainting_start/end, marking which positions have active audio to generate.\n\n        Source audio silencing is prevented separately in _build_chunk_masks_and_src_latents\n        via instruction-text detection, not here.\n        \"\"\"\n        is_repaint, is_lego, is_cover, can_repaint = self.host.determine_task_type(\"lego\", None)\n        self.assertFalse(is_repaint)\n        self.assertTrue(is_lego)\n        self.assertFalse(is_cover)\n        self.assertTrue(can_repaint, \"lego must use the repainting path to get a proper chunk mask\")\n\n    def test_cover_task_is_not_repaint(self):\n        \"\"\"Cover task should not set can_use_repainting=True.\"\"\"\n        is_repaint, is_lego, is_cover, can_repaint = self.host.determine_task_type(\"cover\", None)\n        self.assertFalse(is_repaint)\n        self.assertFalse(is_lego)\n        self.assertTrue(is_cover)\n        self.assertFalse(can_repaint)\n\n    def test_text2music_task_is_not_repaint(self):\n        \"\"\"Text-to-music task should not set can_use_repainting=True.\"\"\"\n        is_repaint, is_lego, is_cover, can_repaint = self.host.determine_task_type(\"text2music\", None)\n        self.assertFalse(is_repaint)\n        self.assertFalse(is_lego)\n        self.assertFalse(is_cover)\n        self.assertFalse(can_repaint)\n\n    def test_audio_codes_upgrade_task_to_cover(self):\n        \"\"\"Providing audio codes should set is_cover_task=True regardless of task_type.\"\"\"\n        is_repaint, is_lego, is_cover, can_repaint = self.host.determine_task_type(\n            \"text2music\", \"<|audio_code_1|>\"\n        )\n        self.assertFalse(is_repaint)\n        self.assertFalse(is_lego)\n        self.assertTrue(is_cover)\n        self.assertFalse(can_repaint)\n\n    def test_lego_with_audio_codes_enables_repainting(self):\n        \"\"\"Lego with audio codes should still have can_use_repainting=True for chunk mask.\"\"\"\n        is_repaint, is_lego, is_cover, can_repaint = self.host.determine_task_type(\n            \"lego\", \"<|audio_code_1|>\"\n        )\n        self.assertTrue(is_lego)\n        self.assertTrue(is_cover)\n        self.assertTrue(can_repaint, \"lego must use the repainting path for chunk mask\")\n\n\nif __name__ == \"__main__\":\n    unittest.main()\n"
  },
  {
    "path": "acestep/core/generation/handler/training_preset.py",
    "content": "\"\"\"Training-preset switching helpers for handler decomposition.\"\"\"\n\nfrom typing import Tuple\n\n\nclass TrainingPresetMixin:\n    \"\"\"Helpers for switching runtime initialization to training-safe settings.\"\"\"\n\n    def switch_to_training_preset(self) -> Tuple[str, bool]:\n        \"\"\"Reinitialize with quantization disabled using the last successful init parameters.\n\n        Returns:\n            Tuple[str, bool]:\n                - A human-readable status message for UI/API consumers.\n                - ``True`` when the preset is already safe or reinitialization succeeds,\n                  otherwise ``False``.\n        \"\"\"\n        if self.quantization is None:\n            return \"Already in training-safe preset (quantization disabled).\", True\n\n        if not self.last_init_params:\n            return \"Cannot switch preset automatically: no previous init parameters found.\", False\n\n        params = dict(self.last_init_params)\n        params[\"quantization\"] = None\n\n        status, ok = self.initialize_service(\n            project_root=params[\"project_root\"],\n            config_path=params[\"config_path\"],\n            device=params[\"device\"],\n            use_flash_attention=params[\"use_flash_attention\"],\n            compile_model=params[\"compile_model\"],\n            offload_to_cpu=params[\"offload_to_cpu\"],\n            offload_dit_to_cpu=params[\"offload_dit_to_cpu\"],\n            quantization=None,\n            prefer_source=params.get(\"prefer_source\"),\n            use_mlx_dit=params.get(\"use_mlx_dit\", True),\n        )\n        if ok:\n            return f\"Switched to training preset (quantization disabled).\\n{status}\", True\n        return f\"Failed to switch to training preset.\\n{status}\", False\n"
  },
  {
    "path": "acestep/core/generation/handler/training_preset_test.py",
    "content": "\"\"\"Unit tests for training-preset switching behavior.\"\"\"\n\nimport importlib.util\nimport sys\nimport types\nimport unittest\nfrom pathlib import Path\n\n\ndef _load_training_preset_module():\n    \"\"\"Load training_preset module directly from file to avoid package side effects.\"\"\"\n    repo_root = Path(__file__).resolve().parents[4]\n    if str(repo_root) not in sys.path:\n        sys.path.insert(0, str(repo_root))\n    package_paths = {\n        \"acestep\": repo_root / \"acestep\",\n        \"acestep.core\": repo_root / \"acestep\" / \"core\",\n        \"acestep.core.generation\": repo_root / \"acestep\" / \"core\" / \"generation\",\n        \"acestep.core.generation.handler\": repo_root / \"acestep\" / \"core\" / \"generation\" / \"handler\",\n    }\n    for package_name, package_path in package_paths.items():\n        if package_name in sys.modules:\n            continue\n        package_module = types.ModuleType(package_name)\n        package_module.__path__ = [str(package_path)]\n        sys.modules[package_name] = package_module\n    module_path = Path(__file__).with_name(\"training_preset.py\")\n    spec = importlib.util.spec_from_file_location(\n        \"acestep.core.generation.handler.training_preset\",\n        module_path,\n    )\n    module = importlib.util.module_from_spec(spec)\n    assert spec.loader is not None\n    spec.loader.exec_module(module)\n    return module\n\n\nTRAINING_PRESET_MODULE = _load_training_preset_module()\nTrainingPresetMixin = TRAINING_PRESET_MODULE.TrainingPresetMixin\n\n\nclass _Host(TrainingPresetMixin):\n    \"\"\"Minimal host object exposing TrainingPresetMixin for focused unit testing.\"\"\"\n\n    def __init__(self):\n        \"\"\"Initialize host state needed for switch_to_training_preset tests.\"\"\"\n        self.quantization = None\n        self.last_init_params = None\n        self._initialize_calls = []\n        self._initialize_result = (\"ok\", True)\n\n    def initialize_service(self, **kwargs):\n        \"\"\"Capture initialize_service arguments and return a configured test result.\"\"\"\n        self._initialize_calls.append(kwargs)\n        return self._initialize_result\n\n\nclass TrainingPresetMixinTests(unittest.TestCase):\n    \"\"\"Behavioral tests for training-preset switching helpers.\"\"\"\n\n    def test_switch_to_training_preset_returns_already_safe_when_unquantized(self):\n        \"\"\"It short-circuits when quantization is already disabled.\"\"\"\n        host = _Host()\n        status, ok = host.switch_to_training_preset()\n        self.assertTrue(ok)\n        self.assertIn(\"Already in training-safe preset\", status)\n        self.assertEqual(host._initialize_calls, [])\n\n    def test_switch_to_training_preset_fails_without_last_init_params(self):\n        \"\"\"It returns a descriptive failure when no previous init params are stored.\"\"\"\n        host = _Host()\n        host.quantization = \"int8_weight_only\"\n        status, ok = host.switch_to_training_preset()\n        self.assertFalse(ok)\n        self.assertIn(\"no previous init parameters\", status)\n        self.assertEqual(host._initialize_calls, [])\n\n    def test_switch_to_training_preset_reinitializes_without_quantization(self):\n        \"\"\"It reinitializes using cached params and forces quantization to None.\"\"\"\n        host = _Host()\n        host.quantization = \"int8_weight_only\"\n        host.last_init_params = {\n            \"project_root\": \"K:/fake_root\",\n            \"config_path\": \"acestep-v15-turbo\",\n            \"device\": \"cpu\",\n            \"use_flash_attention\": False,\n            \"compile_model\": True,\n            \"offload_to_cpu\": False,\n            \"offload_dit_to_cpu\": False,\n            \"quantization\": \"int8_weight_only\",\n            \"prefer_source\": \"huggingface\",\n            \"use_mlx_dit\": False,\n        }\n        host._initialize_result = (\"reinit ok\", True)\n\n        status, ok = host.switch_to_training_preset()\n\n        self.assertTrue(ok)\n        self.assertIn(\"Switched to training preset\", status)\n        self.assertIn(\"reinit ok\", status)\n        self.assertEqual(len(host._initialize_calls), 1)\n        call = host._initialize_calls[0]\n        self.assertIsNone(call[\"quantization\"])\n        self.assertEqual(call[\"prefer_source\"], \"huggingface\")\n        self.assertFalse(call[\"use_mlx_dit\"])\n        self.assertEqual(call[\"config_path\"], \"acestep-v15-turbo\")\n\n    def test_switch_to_training_preset_returns_failure_on_reinit_error(self):\n        \"\"\"It returns a failure message when initialize_service reports failure.\"\"\"\n        host = _Host()\n        host.quantization = \"fp8_weight_only\"\n        host.last_init_params = {\n            \"project_root\": \"K:/fake_root\",\n            \"config_path\": \"acestep-v15-turbo\",\n            \"device\": \"cpu\",\n            \"use_flash_attention\": False,\n            \"compile_model\": False,\n            \"offload_to_cpu\": True,\n            \"offload_dit_to_cpu\": True,\n            \"quantization\": \"fp8_weight_only\",\n        }\n        host._initialize_result = (\"boom\", False)\n\n        status, ok = host.switch_to_training_preset()\n\n        self.assertFalse(ok)\n        self.assertIn(\"Failed to switch to training preset\", status)\n        self.assertIn(\"boom\", status)\n        self.assertEqual(len(host._initialize_calls), 1)\n        self.assertIsNone(host._initialize_calls[0][\"quantization\"])\n\n    def test_switch_to_training_preset_passes_none_when_prefer_source_absent(self):\n        \"\"\"It forwards ``prefer_source=None`` and default ``use_mlx_dit=True`` when missing.\"\"\"\n        host = _Host()\n        host.quantization = \"int8_weight_only\"\n        host.last_init_params = {\n            \"project_root\": \"K:/fake_root\",\n            \"config_path\": \"acestep-v15-turbo\",\n            \"device\": \"cpu\",\n            \"use_flash_attention\": False,\n            \"compile_model\": True,\n            \"offload_to_cpu\": False,\n            \"offload_dit_to_cpu\": False,\n            \"quantization\": \"int8_weight_only\",\n        }\n        host._initialize_result = (\"ok\", True)\n\n        _, ok = host.switch_to_training_preset()\n\n        self.assertTrue(ok)\n        self.assertEqual(len(host._initialize_calls), 1)\n        self.assertIsNone(host._initialize_calls[0][\"prefer_source\"])\n        self.assertTrue(host._initialize_calls[0][\"use_mlx_dit\"])\n\n    def test_switch_to_training_preset_does_not_mutate_last_init_params(self):\n        \"\"\"It preserves cached init parameters while forcing quantization only in call args.\"\"\"\n        host = _Host()\n        host.quantization = \"int8_weight_only\"\n        host.last_init_params = {\n            \"project_root\": \"K:/fake_root\",\n            \"config_path\": \"acestep-v15-turbo\",\n            \"device\": \"cpu\",\n            \"use_flash_attention\": False,\n            \"compile_model\": True,\n            \"offload_to_cpu\": False,\n            \"offload_dit_to_cpu\": False,\n            \"quantization\": \"int8_weight_only\",\n            \"prefer_source\": \"modelscope\",\n        }\n        host._initialize_result = (\"ok\", True)\n\n        _, ok = host.switch_to_training_preset()\n\n        self.assertTrue(ok)\n        self.assertEqual(host.last_init_params[\"quantization\"], \"int8_weight_only\")\n        self.assertIsNone(host._initialize_calls[0][\"quantization\"])\n\n\nif __name__ == \"__main__\":\n    unittest.main()\n"
  },
  {
    "path": "acestep/core/generation/handler/vae_decode.py",
    "content": "\"\"\"VAE decode orchestration helpers for tiled latent-to-audio conversion.\"\"\"\n\nfrom typing import Optional\n\nimport torch\nfrom loguru import logger\n\n\nclass VaeDecodeMixin:\n    \"\"\"High-level VAE decode entrypoints and fallback policies.\"\"\"\n\n    # MPS-safe chunk parameters (class-level for testability)\n    _MPS_DECODE_CHUNK_SIZE = 32\n    _MPS_DECODE_OVERLAP = 8\n\n    def tiled_decode(\n        self,\n        latents,\n        chunk_size: Optional[int] = None,\n        overlap: int = 64,\n        offload_wav_to_cpu: Optional[bool] = None,\n    ):\n        \"\"\"Decode latents using tiling to reduce VRAM usage.\n\n        Uses overlap-discard chunking to avoid boundary artifacts while\n        constraining peak decode memory.\n\n        Args:\n            latents: Tensor shaped ``[batch, channels, latent_frames]``.\n            chunk_size: Chunk size in latent frames. When ``None``, an\n                auto-tuned value is selected by runtime policy.\n            overlap: Overlap in latent frames between adjacent windows.\n            offload_wav_to_cpu: Whether decoded waveform chunks should be\n                offloaded to CPU immediately to reduce VRAM pressure.\n\n        Returns:\n            Decoded waveform tensor shaped ``[batch, audio_channels, samples]``.\n        \"\"\"\n        # ---- MLX fast path (macOS Apple Silicon) ----\n        if self.use_mlx_vae and self.mlx_vae is not None:\n            try:\n                result = self._mlx_vae_decode(latents)\n                return result\n            except Exception as exc:\n                logger.warning(\n                    f\"[tiled_decode] MLX VAE decode failed ({type(exc).__name__}: {exc}), \"\n                    f\"falling back to PyTorch VAE...\"\n                )\n\n        # ---- PyTorch path (CUDA / MPS / CPU) ----\n        if chunk_size is None:\n            chunk_size = self._get_auto_decode_chunk_size()\n        if offload_wav_to_cpu is None:\n            offload_wav_to_cpu = self._should_offload_wav_to_cpu()\n\n        logger.info(\n            f\"[tiled_decode] chunk_size={chunk_size}, offload_wav_to_cpu={offload_wav_to_cpu}, \"\n            f\"latents_shape={latents.shape}\"\n        )\n\n        # MPS Conv1d has a hard output-size limit during temporal upsampling.\n        _is_mps = self.device == \"mps\"\n        if _is_mps:\n            _mps_chunk = self._MPS_DECODE_CHUNK_SIZE\n            _mps_overlap = self._MPS_DECODE_OVERLAP\n            _needs_reduction = (chunk_size > _mps_chunk) or (overlap > _mps_overlap)\n            if _needs_reduction:\n                logger.info(\n                    f\"[tiled_decode] VAE decode via PyTorch MPS; reducing chunk_size from {chunk_size} \"\n                    f\"to {min(chunk_size, _mps_chunk)} and overlap from {overlap} \"\n                    f\"to {min(overlap, _mps_overlap)} to avoid MPS conv output limit.\"\n                )\n                chunk_size = min(chunk_size, _mps_chunk)\n                overlap = min(overlap, _mps_overlap)\n\n        try:\n            return self._tiled_decode_inner(latents, chunk_size, overlap, offload_wav_to_cpu)\n        except (NotImplementedError, RuntimeError) as exc:\n            if not _is_mps:\n                raise\n            logger.warning(\n                f\"[tiled_decode] MPS decode failed ({type(exc).__name__}: {exc}), \"\n                f\"falling back to CPU VAE decode...\"\n            )\n            return self._tiled_decode_cpu_fallback(latents)\n\n    def _tiled_decode_cpu_fallback(self, latents):\n        \"\"\"Last-resort CPU VAE decode when MPS fails unexpectedly.\"\"\"\n        _first_param = next(self.vae.parameters())\n        vae_device = _first_param.device\n        vae_dtype = _first_param.dtype\n        try:\n            self.vae = self.vae.cpu().float()\n            latents_cpu = latents.to(device=\"cpu\", dtype=torch.float32)\n            decoder_output = self.vae.decode(latents_cpu)\n            result = decoder_output.sample\n            del decoder_output\n            return result\n        finally:\n            # Always restore VAE to original device/dtype\n            self.vae = self.vae.to(vae_dtype).to(vae_device)\n\n    def _decode_on_cpu(self, latents):\n        \"\"\"Move VAE to CPU, decode there, then restore original device.\"\"\"\n        logger.warning(\"[_decode_on_cpu] Moving VAE to CPU for decode (VRAM too tight for GPU decode)\")\n\n        try:\n            original_device = next(self.vae.parameters()).device\n        except StopIteration:\n            original_device = torch.device(\"cpu\")\n\n        vae_cpu_dtype = self._get_vae_dtype(\"cpu\")\n        self._recursive_to_device(self.vae, \"cpu\", vae_cpu_dtype)\n        self._empty_cache()\n\n        latents_cpu = latents.cpu().to(vae_cpu_dtype)\n        try:\n            with torch.inference_mode():\n                decoder_output = self.vae.decode(latents_cpu)\n                result = decoder_output.sample\n                del decoder_output\n        finally:\n            if original_device.type != \"cpu\":\n                vae_gpu_dtype = self._get_vae_dtype(str(original_device))\n                self._recursive_to_device(self.vae, original_device, vae_gpu_dtype)\n\n        logger.info(f\"[_decode_on_cpu] CPU decode complete, result shape={result.shape}\")\n        return result\n"
  },
  {
    "path": "acestep/core/generation/handler/vae_decode_chunks.py",
    "content": "\"\"\"Chunk-level VAE decode helpers used by tiled decode orchestration.\"\"\"\n\nimport math\n\nimport torch\nfrom loguru import logger\nfrom tqdm import tqdm\n\n\nclass VaeDecodeChunksMixin:\n    \"\"\"Implement chunked decode strategies for GPU and CPU-offload modes.\"\"\"\n\n    def _tiled_decode_inner(self, latents, chunk_size, overlap, offload_wav_to_cpu):\n        \"\"\"Run tiled decode with adaptive overlap and OOM fallbacks.\"\"\"\n        bsz, _channels, latent_frames = latents.shape\n\n        # Batch-sequential decode keeps peak VRAM stable across batch sizes.\n        if bsz > 1:\n            logger.info(f\"[tiled_decode] Batch size {bsz} > 1; decoding samples sequentially to save VRAM\")\n            per_sample_results = []\n            for b_idx in range(bsz):\n                single = latents[b_idx : b_idx + 1]\n                decoded = self._tiled_decode_inner(single, chunk_size, overlap, offload_wav_to_cpu)\n                per_sample_results.append(decoded.cpu() if decoded.device.type != \"cpu\" else decoded)\n                self._empty_cache()\n            result = torch.cat(per_sample_results, dim=0)\n            if latents.device.type != \"cpu\" and not offload_wav_to_cpu:\n                result = result.to(latents.device)\n            return result\n\n        min_overlap = 4  # Minimum floor to prevent audio artifacts at chunk boundaries\n        effective_overlap = overlap\n        while chunk_size - 2 * effective_overlap <= 0 and effective_overlap > min_overlap:\n            effective_overlap = effective_overlap // 2\n        # Enforce minimum overlap floor to avoid near-zero values that cause corruption\n        if effective_overlap < min_overlap and overlap >= min_overlap:\n            effective_overlap = min_overlap\n        if effective_overlap != overlap:\n            logger.warning(\n                f\"[tiled_decode] Reduced overlap from {overlap} to {effective_overlap} for chunk_size={chunk_size}\"\n            )\n        overlap = effective_overlap\n\n        if latent_frames <= chunk_size:\n            try:\n                decoder_output = self.vae.decode(latents)\n                result = decoder_output.sample\n                del decoder_output\n                return result\n            except torch.cuda.OutOfMemoryError:\n                logger.warning(\"[tiled_decode] OOM on direct decode, falling back to CPU VAE decode\")\n                self._empty_cache()\n                return self._decode_on_cpu(latents)\n\n        stride = chunk_size - 2 * overlap\n        if stride <= 0:\n            raise ValueError(f\"chunk_size {chunk_size} must be > 2 * overlap {overlap}\")\n\n        num_steps = math.ceil(latent_frames / stride)\n\n        if offload_wav_to_cpu:\n            try:\n                return self._tiled_decode_offload_cpu(latents, bsz, latent_frames, stride, overlap, num_steps)\n            except torch.cuda.OutOfMemoryError:\n                logger.warning(\n                    f\"[tiled_decode] OOM during offload_cpu decode with chunk_size={chunk_size}, \"\n                    \"falling back to CPU VAE decode\"\n                )\n                self._empty_cache()\n                return self._decode_on_cpu(latents)\n\n        try:\n            return self._tiled_decode_gpu(latents, stride, overlap, num_steps)\n        except torch.cuda.OutOfMemoryError:\n            logger.warning(\n                f\"[tiled_decode] OOM during GPU decode with chunk_size={chunk_size}, \"\n                \"falling back to CPU offload path\"\n            )\n            self._empty_cache()\n            try:\n                return self._tiled_decode_offload_cpu(latents, bsz, latent_frames, stride, overlap, num_steps)\n            except torch.cuda.OutOfMemoryError:\n                logger.warning(\"[tiled_decode] OOM even with offload path, falling back to full CPU VAE decode\")\n                self._empty_cache()\n                return self._decode_on_cpu(latents)\n\n    def _tiled_decode_gpu(self, latents, stride, overlap, num_steps):\n        \"\"\"Decode chunks and keep decoded audio tensors on GPU.\"\"\"\n        decoded_audio_list = []\n        upsample_factor = None\n\n        for i in tqdm(range(num_steps), desc=\"Decoding audio chunks\", disable=self.disable_tqdm):\n            core_start = i * stride\n            core_end = min(core_start + stride, latents.shape[-1])\n            win_start = max(0, core_start - overlap)\n            win_end = min(latents.shape[-1], core_end + overlap)\n\n            latent_chunk = latents[:, :, win_start:win_end]\n            decoder_output = self.vae.decode(latent_chunk)\n            audio_chunk = decoder_output.sample\n            del decoder_output\n\n            if upsample_factor is None:\n                upsample_factor = audio_chunk.shape[-1] / latent_chunk.shape[-1]\n\n            added_start = core_start - win_start\n            trim_start = int(round(added_start * upsample_factor))\n            added_end = win_end - core_end\n            trim_end = int(round(added_end * upsample_factor))\n\n            audio_len = audio_chunk.shape[-1]\n            end_idx = audio_len - trim_end if trim_end > 0 else audio_len\n            audio_core = audio_chunk[:, :, trim_start:end_idx]\n            decoded_audio_list.append(audio_core)\n\n        return torch.cat(decoded_audio_list, dim=-1)\n\n    def _tiled_decode_offload_cpu(self, latents, bsz, latent_frames, stride, overlap, num_steps):\n        \"\"\"Decode chunks on GPU and copy trimmed audio cores to a CPU buffer.\"\"\"\n        first_core_end = min(stride, latent_frames)\n        first_win_end = min(latent_frames, first_core_end + overlap)\n        first_latent_chunk = latents[:, :, 0:first_win_end]\n        first_decoder_output = self.vae.decode(first_latent_chunk)\n        first_audio_chunk = first_decoder_output.sample\n        del first_decoder_output\n\n        upsample_factor = first_audio_chunk.shape[-1] / first_latent_chunk.shape[-1]\n        audio_channels = first_audio_chunk.shape[1]\n\n        total_audio_length = int(round(latent_frames * upsample_factor))\n        final_audio = torch.zeros(bsz, audio_channels, total_audio_length, dtype=first_audio_chunk.dtype, device=\"cpu\")\n\n        first_added_end = first_win_end - first_core_end\n        first_trim_end = int(round(first_added_end * upsample_factor))\n        first_audio_len = first_audio_chunk.shape[-1]\n        first_end_idx = first_audio_len - first_trim_end if first_trim_end > 0 else first_audio_len\n\n        first_audio_core = first_audio_chunk[:, :, :first_end_idx]\n        audio_write_pos = first_audio_core.shape[-1]\n        final_audio[:, :, :audio_write_pos] = first_audio_core.cpu()\n\n        del first_audio_chunk, first_audio_core, first_latent_chunk\n\n        for i in tqdm(range(1, num_steps), desc=\"Decoding audio chunks\", disable=self.disable_tqdm):\n            core_start = i * stride\n            core_end = min(core_start + stride, latent_frames)\n            win_start = max(0, core_start - overlap)\n            win_end = min(latent_frames, core_end + overlap)\n\n            latent_chunk = latents[:, :, win_start:win_end]\n            decoder_output = self.vae.decode(latent_chunk)\n            audio_chunk = decoder_output.sample\n            del decoder_output\n\n            added_start = core_start - win_start\n            trim_start = int(round(added_start * upsample_factor))\n            added_end = win_end - core_end\n            trim_end = int(round(added_end * upsample_factor))\n\n            audio_len = audio_chunk.shape[-1]\n            end_idx = audio_len - trim_end if trim_end > 0 else audio_len\n            audio_core = audio_chunk[:, :, trim_start:end_idx]\n\n            core_len = audio_core.shape[-1]\n            final_audio[:, :, audio_write_pos : audio_write_pos + core_len] = audio_core.cpu()\n            audio_write_pos += core_len\n\n            del audio_chunk, audio_core, latent_chunk\n\n        return final_audio[:, :, :audio_write_pos]\n"
  },
  {
    "path": "acestep/core/generation/handler/vae_decode_chunks_test.py",
    "content": "\"\"\"Unit tests for ``VaeDecodeChunksMixin`` chunk/fallback behavior.\"\"\"\n\nimport unittest\n\nimport torch\n\nfrom acestep.core.generation.handler.vae_decode_test_helpers import _ChunksHost\n\n\nclass VaeDecodeChunksMixinTests(unittest.TestCase):\n    \"\"\"Verify critical chunk decode paths and OOM fallback chain semantics.\"\"\"\n\n    def test_batch_sequential_decode_for_multi_sample_input(self):\n        \"\"\"Batch size > 1 should decode per sample then concatenate.\"\"\"\n        host = _ChunksHost()\n        latents = torch.zeros(2, 4, 6)\n        out = host._tiled_decode_inner(latents, chunk_size=10, overlap=2, offload_wav_to_cpu=False)\n        self.assertEqual(tuple(out.shape), (2, 2, 12))\n\n    def test_direct_decode_for_short_latents(self):\n        \"\"\"Short latents should take direct decode path without tiling loop.\"\"\"\n        host = _ChunksHost()\n        latents = torch.zeros(1, 4, 6)\n        out = host._tiled_decode_inner(latents, chunk_size=10, overlap=2, offload_wav_to_cpu=False)\n        self.assertEqual(tuple(out.shape), (1, 2, 12))\n\n    def test_overlap_adjustment_reduces_invalid_overlap(self):\n        \"\"\"Invalid overlap should be reduced until stride becomes positive.\"\"\"\n        host = _ChunksHost()\n\n        def _capture_gpu(latents, stride, overlap, num_steps):\n            \"\"\"Capture overlap argument passed to GPU decode path.\"\"\"\n            _ = latents, stride, num_steps\n            host.recorded[\"overlap\"] = overlap\n            return torch.ones(1, 2, 4)\n\n        host._tiled_decode_gpu = _capture_gpu\n        out = host._tiled_decode_inner(torch.zeros(1, 4, 10), chunk_size=4, overlap=3, offload_wav_to_cpu=False)\n        self.assertEqual(host.recorded[\"overlap\"], 1)\n        self.assertEqual(tuple(out.shape), (1, 2, 4))\n\n    def test_oom_fallback_gpu_to_offload_path(self):\n        \"\"\"GPU OOM should fallback to offload path before full CPU fallback.\"\"\"\n        host = _ChunksHost()\n\n        def _gpu_oom(*args, **kwargs):\n            \"\"\"Raise OOM to force GPU fallback chain.\"\"\"\n            _ = args, kwargs\n            raise torch.cuda.OutOfMemoryError(\"gpu oom\")\n\n        def _offload_ok(*args, **kwargs):\n            \"\"\"Return sentinel tensor from offload path.\"\"\"\n            _ = args, kwargs\n            return torch.ones(1, 2, 5)\n\n        host._tiled_decode_gpu = _gpu_oom\n        host._tiled_decode_offload_cpu = _offload_ok\n        out = host._tiled_decode_inner(torch.zeros(1, 4, 20), chunk_size=8, overlap=2, offload_wav_to_cpu=False)\n        self.assertEqual(tuple(out.shape), (1, 2, 5))\n        self.assertEqual(host.decode_on_cpu_calls, 0)\n\n    def test_oom_fallback_chain_reaches_decode_on_cpu(self):\n        \"\"\"Repeated OOMs should end at full CPU decode fallback.\"\"\"\n        host = _ChunksHost()\n\n        def _oom(*args, **kwargs):\n            \"\"\"Raise OOM for all tiled decode branches.\"\"\"\n            _ = args, kwargs\n            raise torch.cuda.OutOfMemoryError(\"oom\")\n\n        host._tiled_decode_gpu = _oom\n        host._tiled_decode_offload_cpu = _oom\n        out = host._tiled_decode_inner(torch.zeros(1, 4, 20), chunk_size=8, overlap=2, offload_wav_to_cpu=False)\n        self.assertTrue(torch.equal(out, torch.full((1, 2, 7), 9.0)))\n        self.assertEqual(host.decode_on_cpu_calls, 1)\n\n\nif __name__ == \"__main__\":\n    unittest.main()\n"
  },
  {
    "path": "acestep/core/generation/handler/vae_decode_mixin_test.py",
    "content": "\"\"\"Unit tests for ``VaeDecodeMixin`` orchestration behavior.\"\"\"\n\nimport unittest\n\nimport torch\n\nfrom acestep.core.generation.handler.vae_decode_test_helpers import _DecodeHost\n\n\nclass VaeDecodeMixinTests(unittest.TestCase):\n    \"\"\"Verify decode orchestrator paths, fallback policy, and error propagation.\"\"\"\n\n    def test_tiled_decode_reduces_mps_chunk_and_overlap(self):\n        \"\"\"MPS path clamps chunk/overlap to safe configured limits.\"\"\"\n        host = _DecodeHost()\n        out = host.tiled_decode(torch.zeros(1, 4, 128), chunk_size=64, overlap=16)\n        self.assertEqual(host.recorded[\"chunk_size\"], 32)\n        self.assertEqual(host.recorded[\"overlap\"], 8)\n        self.assertFalse(host.recorded[\"offload\"])\n        self.assertEqual(tuple(out.shape), (1, 2, 8))\n\n    def test_tiled_decode_mps_runtime_failure_uses_cpu_fallback(self):\n        \"\"\"MPS runtime failures fallback to CPU decode helper.\"\"\"\n        host = _DecodeHost()\n\n        def _raise(*args, **kwargs):\n            \"\"\"Simulate runtime failure inside tiled decode implementation.\"\"\"\n            _ = args, kwargs\n            raise RuntimeError(\"mps decode failure\")\n\n        host._tiled_decode_inner = _raise\n        out = host.tiled_decode(torch.zeros(1, 4, 32), chunk_size=32, overlap=8)\n        self.assertTrue(torch.equal(out, torch.full((1, 2, 8), 2.0)))\n\n    def test_tiled_decode_uses_mlx_fast_path_when_available(self):\n        \"\"\"MLX decode should short-circuit before PyTorch path when enabled.\"\"\"\n        host = _DecodeHost()\n        host.use_mlx_vae = True\n        host.mlx_vae = object()\n        out = host.tiled_decode(torch.zeros(1, 4, 32), chunk_size=32, overlap=8)\n        self.assertTrue(torch.equal(out, torch.full((1, 2, 6), 3.0)))\n\n    def test_tiled_decode_falls_back_when_mlx_decode_fails(self):\n        \"\"\"MLX decode errors should fallback to normal tiled decode path.\"\"\"\n        host = _DecodeHost()\n        host.use_mlx_vae = True\n        host.mlx_vae = object()\n\n        def _mlx_raise(_latents):\n            \"\"\"Raise MLX failure to exercise fallback path.\"\"\"\n            raise ValueError(\"mlx failed\")\n\n        host._mlx_vae_decode = _mlx_raise\n        out = host.tiled_decode(torch.zeros(1, 4, 32), chunk_size=32, overlap=8)\n        self.assertEqual(tuple(out.shape), (1, 2, 8))\n        self.assertEqual(host.recorded[\"chunk_size\"], 32)\n\n    def test_tiled_decode_non_mps_runtime_error_is_raised(self):\n        \"\"\"Non-MPS runtime errors should bubble to caller unchanged.\"\"\"\n        host = _DecodeHost()\n        host.device = \"cuda\"\n\n        def _raise(*args, **kwargs):\n            \"\"\"Raise runtime failure for non-MPS path assertion.\"\"\"\n            _ = args, kwargs\n            raise RuntimeError(\"cuda decode failure\")\n\n        host._tiled_decode_inner = _raise\n        with self.assertRaises(RuntimeError):\n            host.tiled_decode(torch.zeros(1, 4, 32), chunk_size=32, overlap=8)\n\n\nif __name__ == \"__main__\":\n    unittest.main()\n"
  },
  {
    "path": "acestep/core/generation/handler/vae_decode_test_helpers.py",
    "content": "\"\"\"Shared stubs used by VAE decode unit tests.\"\"\"\n\nimport torch\n\nfrom acestep.core.generation.handler.vae_decode import VaeDecodeMixin\nfrom acestep.core.generation.handler.vae_decode_chunks import VaeDecodeChunksMixin\n\n\nclass _DecodeOutput:\n    \"\"\"Minimal decoder output wrapper exposing ``sample``.\"\"\"\n\n    def __init__(self, sample: torch.Tensor):\n        \"\"\"Store decoded sample tensor.\"\"\"\n        self.sample = sample\n\n\nclass _FakeVae:\n    \"\"\"Simple VAE stub with injectable decode behavior.\"\"\"\n\n    def __init__(self, decode_fn=None):\n        \"\"\"Bind optional decode function and initialize default parameter.\"\"\"\n        self._decode_fn = decode_fn\n        self._param = torch.nn.Parameter(torch.zeros(1))\n\n    def parameters(self):\n        \"\"\"Yield a single parameter to emulate module parameter iteration.\"\"\"\n        yield self._param\n\n    def cpu(self):\n        \"\"\"Return self to emulate in-place module migration.\"\"\"\n        return self\n\n    def float(self):\n        \"\"\"Return self to emulate in-place dtype cast.\"\"\"\n        return self\n\n    def to(self, target):\n        \"\"\"Return self for chained ``to(...)`` transitions in tests.\"\"\"\n        _ = target\n        return self\n\n    def decode(self, latents: torch.Tensor):\n        \"\"\"Decode latents using injected behavior or default upsample stub.\"\"\"\n        if self._decode_fn is not None:\n            return _DecodeOutput(self._decode_fn(latents))\n        bsz, _channels, latent_frames = latents.shape\n        return _DecodeOutput(torch.ones(bsz, 2, latent_frames * 2))\n\n\nclass _DecodeHost(VaeDecodeMixin):\n    \"\"\"Host stub for testing VaeDecodeMixin orchestration behavior.\"\"\"\n\n    def __init__(self):\n        \"\"\"Initialize deterministic decode host state.\"\"\"\n        self.use_mlx_vae = False\n        self.mlx_vae = None\n        self.device = \"mps\"\n        self.disable_tqdm = True\n        self.recorded = {}\n\n    def _get_auto_decode_chunk_size(self):\n        \"\"\"Return deterministic chunk size used by default path.\"\"\"\n        return 64\n\n    def _should_offload_wav_to_cpu(self):\n        \"\"\"Return deterministic offload policy used by default path.\"\"\"\n        return False\n\n    def _tiled_decode_inner(self, latents, chunk_size, overlap, offload_wav_to_cpu):\n        \"\"\"Record routed args and return sentinel audio tensor.\"\"\"\n        _ = latents\n        self.recorded[\"chunk_size\"] = chunk_size\n        self.recorded[\"overlap\"] = overlap\n        self.recorded[\"offload\"] = offload_wav_to_cpu\n        return torch.ones(1, 2, 8)\n\n    def _tiled_decode_cpu_fallback(self, latents):\n        \"\"\"Return fallback tensor for failure-path assertions.\"\"\"\n        _ = latents\n        return torch.full((1, 2, 8), 2.0)\n\n    def _mlx_vae_decode(self, latents):\n        \"\"\"Return MLX sentinel tensor for MLX path assertions.\"\"\"\n        _ = latents\n        return torch.full((1, 2, 6), 3.0)\n\n\nclass _ChunksHost(VaeDecodeChunksMixin):\n    \"\"\"Host stub for testing chunk decode implementations.\"\"\"\n\n    def __init__(self):\n        \"\"\"Initialize default dependencies and call counters.\"\"\"\n        self.disable_tqdm = True\n        self.vae = _FakeVae()\n        self.empty_cache_calls = 0\n        self.decode_on_cpu_calls = 0\n        self.recorded = {}\n\n    def _empty_cache(self):\n        \"\"\"Track cache-empty calls to validate OOM paths.\"\"\"\n        self.empty_cache_calls += 1\n\n    def _decode_on_cpu(self, latents):\n        \"\"\"Return sentinel tensor for CPU-fallback assertions.\"\"\"\n        self.decode_on_cpu_calls += 1\n        bsz = latents.shape[0]\n        return torch.full((bsz, 2, 7), 9.0)\n"
  },
  {
    "path": "acestep/core/generation/handler/vae_encode.py",
    "content": "\"\"\"VAE encode orchestration helpers for tiled audio-to-latent conversion.\"\"\"\n\nimport math\nfrom typing import Optional\n\nimport torch\nfrom loguru import logger\n\nfrom acestep.gpu_config import get_gpu_memory_gb\n\n\nclass VaeEncodeMixin:\n    \"\"\"High-level VAE encode entrypoints and runtime chunk policy.\"\"\"\n\n    def tiled_encode(self, audio, chunk_size=None, overlap=None, offload_latent_to_cpu=True):\n        \"\"\"Encode audio to latents using overlap-discard tiling.\n\n        Args:\n            audio: Tensor shaped ``[batch, channels, samples]`` or ``[channels, samples]``.\n            chunk_size: Audio chunk size in samples; auto-selected when ``None``.\n            overlap: Overlap in samples; defaults to 2 seconds at 48kHz.\n            offload_latent_to_cpu: Whether to offload chunk outputs to CPU.\n\n        Returns:\n            Latent tensor shaped ``[batch, latent_channels, latent_frames]``.\n        \"\"\"\n        # ---- MLX fast path (macOS Apple Silicon) ----\n        if self.use_mlx_vae and self.mlx_vae is not None:\n            input_was_2d = audio.dim() == 2\n            if input_was_2d:\n                audio = audio.unsqueeze(0)\n            try:\n                result = self._mlx_vae_encode_sample(audio)\n                if input_was_2d:\n                    result = result.squeeze(0)\n                return result\n            except Exception as exc:\n                logger.warning(\n                    f\"[tiled_encode] MLX VAE encode failed ({type(exc).__name__}: {exc}), \"\n                    f\"falling back to PyTorch VAE...\"\n                )\n                if input_was_2d:\n                    audio = audio.squeeze(0)\n\n        # ---- PyTorch path (CUDA / MPS / CPU) ----\n        if chunk_size is None:\n            gpu_memory = get_gpu_memory_gb()\n            if gpu_memory <= 0 and self.device == \"mps\":\n                mem_gb = self._get_effective_mps_memory_gb()\n                if mem_gb is not None:\n                    gpu_memory = mem_gb\n            chunk_size = 48000 * 15 if gpu_memory <= 8 else 48000 * 30\n        if overlap is None:\n            overlap = 48000 * 2\n\n        input_was_2d = audio.dim() == 2\n        if input_was_2d:\n            audio = audio.unsqueeze(0)\n\n        batch_size, _channels, samples = audio.shape\n\n        if samples <= chunk_size:\n            vae_input = audio.to(self.device).to(self.vae.dtype)\n            with torch.inference_mode():\n                latents = self.vae.encode(vae_input).latent_dist.sample()\n            if input_was_2d:\n                latents = latents.squeeze(0)\n            return latents\n\n        stride = chunk_size - 2 * overlap\n        if stride <= 0:\n            raise ValueError(f\"chunk_size {chunk_size} must be > 2 * overlap {overlap}\")\n\n        num_steps = math.ceil(samples / stride)\n        if offload_latent_to_cpu:\n            result = self._tiled_encode_offload_cpu(audio, batch_size, samples, stride, overlap, num_steps, chunk_size)\n        else:\n            result = self._tiled_encode_gpu(audio, batch_size, samples, stride, overlap, num_steps, chunk_size)\n\n        if input_was_2d:\n            result = result.squeeze(0)\n        return result\n"
  },
  {
    "path": "acestep/core/generation/handler/vae_encode_chunks.py",
    "content": "\"\"\"Chunk-level VAE encode helpers for tiled audio-to-latent conversion.\"\"\"\n\nimport torch\nfrom tqdm import tqdm\n\n\nclass VaeEncodeChunksMixin:\n    \"\"\"Implement chunked encode strategies for GPU and CPU-offload modes.\"\"\"\n\n    def _tiled_encode_gpu(self, audio, batch_size, samples, stride, overlap, num_steps, chunk_size):\n        \"\"\"Standard tiled encode keeping all data on GPU.\"\"\"\n        _ = batch_size, chunk_size\n        encoded_latent_list = []\n        downsample_factor = None\n\n        for i in tqdm(range(num_steps), desc=\"Encoding audio chunks\", disable=self.disable_tqdm):\n            core_start = i * stride\n            core_end = min(core_start + stride, samples)\n            win_start = max(0, core_start - overlap)\n            win_end = min(samples, core_end + overlap)\n\n            audio_chunk = audio[:, :, win_start:win_end].to(self.device).to(self.vae.dtype)\n            with torch.inference_mode():\n                latent_chunk = self.vae.encode(audio_chunk).latent_dist.sample()\n\n            if downsample_factor is None:\n                downsample_factor = audio_chunk.shape[-1] / latent_chunk.shape[-1]\n\n            added_start = core_start - win_start\n            trim_start = int(round(added_start / downsample_factor))\n            added_end = win_end - core_end\n            trim_end = int(round(added_end / downsample_factor))\n\n            latent_len = latent_chunk.shape[-1]\n            end_idx = latent_len - trim_end if trim_end > 0 else latent_len\n            latent_core = latent_chunk[:, :, trim_start:end_idx]\n            encoded_latent_list.append(latent_core)\n            del audio_chunk\n\n        return torch.cat(encoded_latent_list, dim=-1)\n\n    def _tiled_encode_offload_cpu(self, audio, batch_size, samples, stride, overlap, num_steps, chunk_size):\n        \"\"\"Tiled encode that offloads latent chunks to CPU immediately.\"\"\"\n        _ = chunk_size\n        first_core_end = min(stride, samples)\n        first_win_end = min(samples, first_core_end + overlap)\n\n        first_audio_chunk = audio[:, :, 0:first_win_end].to(self.device).to(self.vae.dtype)\n        with torch.inference_mode():\n            first_latent_chunk = self.vae.encode(first_audio_chunk).latent_dist.sample()\n\n        downsample_factor = first_audio_chunk.shape[-1] / first_latent_chunk.shape[-1]\n        latent_channels = first_latent_chunk.shape[1]\n\n        total_latent_length = int(round(samples / downsample_factor))\n        final_latents = torch.zeros(\n            batch_size,\n            latent_channels,\n            total_latent_length,\n            dtype=first_latent_chunk.dtype,\n            device=\"cpu\",\n        )\n\n        first_added_end = first_win_end - first_core_end\n        first_trim_end = int(round(first_added_end / downsample_factor))\n        first_latent_len = first_latent_chunk.shape[-1]\n        first_end_idx = first_latent_len - first_trim_end if first_trim_end > 0 else first_latent_len\n\n        first_latent_core = first_latent_chunk[:, :, :first_end_idx]\n        latent_write_pos = first_latent_core.shape[-1]\n        final_latents[:, :, :latent_write_pos] = first_latent_core.cpu()\n        del first_audio_chunk, first_latent_chunk, first_latent_core\n\n        for i in tqdm(range(1, num_steps), desc=\"Encoding audio chunks\", disable=self.disable_tqdm):\n            core_start = i * stride\n            core_end = min(core_start + stride, samples)\n            win_start = max(0, core_start - overlap)\n            win_end = min(samples, core_end + overlap)\n\n            audio_chunk = audio[:, :, win_start:win_end].to(self.device).to(self.vae.dtype)\n            with torch.inference_mode():\n                latent_chunk = self.vae.encode(audio_chunk).latent_dist.sample()\n\n            added_start = core_start - win_start\n            trim_start = int(round(added_start / downsample_factor))\n            added_end = win_end - core_end\n            trim_end = int(round(added_end / downsample_factor))\n\n            latent_len = latent_chunk.shape[-1]\n            end_idx = latent_len - trim_end if trim_end > 0 else latent_len\n            latent_core = latent_chunk[:, :, trim_start:end_idx]\n\n            core_len = latent_core.shape[-1]\n            final_latents[:, :, latent_write_pos : latent_write_pos + core_len] = latent_core.cpu()\n            latent_write_pos += core_len\n            del audio_chunk, latent_chunk, latent_core\n\n        return final_latents[:, :, :latent_write_pos]\n"
  },
  {
    "path": "acestep/core/generation/handler/vae_encode_test.py",
    "content": "\"\"\"Unit tests for extracted VAE encode mixins.\"\"\"\n\nimport unittest\n\nimport torch\n\nfrom acestep.core.generation.handler.vae_encode import VaeEncodeMixin\nfrom acestep.core.generation.handler.vae_encode_chunks import VaeEncodeChunksMixin\n\n\nclass _Dist:\n    \"\"\"Minimal distribution wrapper exposing ``sample``.\"\"\"\n\n    def __init__(self, sample):\n        \"\"\"Store latent sample tensor.\"\"\"\n        self._sample = sample\n\n    def sample(self):\n        \"\"\"Return precomputed latent sample.\"\"\"\n        return self._sample\n\n\nclass _EncOut:\n    \"\"\"Minimal encode output wrapper exposing ``latent_dist``.\"\"\"\n\n    def __init__(self, sample):\n        \"\"\"Store sample wrapper used by tests.\"\"\"\n        self.latent_dist = _Dist(sample)\n\n\nclass _Vae:\n    \"\"\"Simple VAE stub with deterministic temporal downsample.\"\"\"\n\n    def __init__(self, fn=None):\n        \"\"\"Configure optional encode callback.\"\"\"\n        self.dtype = torch.float32\n        self._fn = fn\n\n    def encode(self, audio_chunk):\n        \"\"\"Return deterministic latent tensor (2x temporal downsample).\"\"\"\n        if self._fn:\n            return _EncOut(self._fn(audio_chunk))\n        bsz, _c, s = audio_chunk.shape\n        return _EncOut(torch.ones(bsz, 4, max(1, s // 2)))\n\n\nclass _Host(VaeEncodeMixin, VaeEncodeChunksMixin):\n    \"\"\"Host combining both encode mixins with minimal dependencies.\"\"\"\n\n    def __init__(self):\n        \"\"\"Initialize deterministic state for unit tests.\"\"\"\n        self.use_mlx_vae = False\n        self.mlx_vae = None\n        self.device = \"cpu\"\n        self.vae = _Vae()\n        self.disable_tqdm = True\n        self.recorded = {}\n\n    def _get_effective_mps_memory_gb(self):\n        \"\"\"Return no override by default.\"\"\"\n        return None\n\n    def _mlx_vae_encode_sample(self, audio):\n        \"\"\"Return MLX sentinel result for MLX-path tests.\"\"\"\n        _ = audio\n        return torch.full((1, 4, 6), 3.0)\n\n\nclass VaeEncodeMixinTests(unittest.TestCase):\n    \"\"\"Validate orchestration and chunk path selection for tiled encode.\"\"\"\n\n    def test_tiled_encode_uses_mlx_path_when_available(self):\n        \"\"\"MLX path should short-circuit PyTorch path.\"\"\"\n        host = _Host()\n        host.use_mlx_vae = True\n        host.mlx_vae = object()\n        out = host.tiled_encode(torch.zeros(1, 2, 16), chunk_size=8, overlap=2)\n        self.assertTrue(torch.equal(out, torch.full((1, 4, 6), 3.0)))\n\n    def test_tiled_encode_direct_path_for_short_audio(self):\n        \"\"\"Short audio should encode directly without chunk helpers.\"\"\"\n        host = _Host()\n        out = host.tiled_encode(torch.zeros(1, 2, 16), chunk_size=20, overlap=2)\n        self.assertEqual(tuple(out.shape), (1, 4, 8))\n\n    def test_tiled_encode_uses_offload_path(self):\n        \"\"\"Offload mode should route through CPU-offload chunk helper.\"\"\"\n        host = _Host()\n\n        def _offload(*args, **kwargs):\n            \"\"\"Capture invocation and return sentinel latents.\"\"\"\n            _ = args, kwargs\n            host.recorded[\"offload\"] = True\n            return torch.ones(1, 4, 5)\n\n        host._tiled_encode_offload_cpu = _offload\n        out = host.tiled_encode(torch.zeros(1, 2, 48), chunk_size=16, overlap=2, offload_latent_to_cpu=True)\n        self.assertTrue(host.recorded[\"offload\"])\n        self.assertEqual(tuple(out.shape), (1, 4, 5))\n\n    def test_tiled_encode_rejects_invalid_stride(self):\n        \"\"\"Stride <= 0 should raise ValueError.\"\"\"\n        host = _Host()\n        with self.assertRaises(ValueError):\n            host.tiled_encode(torch.zeros(1, 2, 48), chunk_size=10, overlap=5)\n\n    def test_tiled_encode_routes_to_gpu_chunk_path(self):\n        \"\"\"Non-offload mode should route through GPU chunk helper.\"\"\"\n        host = _Host()\n\n        def _gpu(*args, **kwargs):\n            \"\"\"Capture GPU routing and return sentinel latents.\"\"\"\n            _ = args, kwargs\n            host.recorded[\"gpu\"] = True\n            return torch.ones(1, 4, 7)\n\n        host._tiled_encode_gpu = _gpu\n        out = host.tiled_encode(torch.zeros(1, 2, 64), chunk_size=16, overlap=2, offload_latent_to_cpu=False)\n        self.assertTrue(host.recorded[\"gpu\"])\n        self.assertEqual(tuple(out.shape), (1, 4, 7))\n\n    def test_tiled_encode_gpu_and_offload_outputs_match(self):\n        \"\"\"GPU and offload chunk methods should agree on deterministic output.\"\"\"\n        host = _Host()\n        audio = torch.zeros(1, 2, 40)\n        chunk_size = 16\n        overlap = 2\n        stride = chunk_size - 2 * overlap\n        num_steps = 4\n        out_gpu = host._tiled_encode_gpu(audio, 1, 40, stride, overlap, num_steps, chunk_size)\n        out_offload = host._tiled_encode_offload_cpu(audio, 1, 40, stride, overlap, num_steps, chunk_size)\n        self.assertEqual(tuple(out_gpu.shape), (1, 4, 20))\n        self.assertEqual(tuple(out_offload.shape), (1, 4, 20))\n        self.assertTrue(torch.equal(out_gpu.cpu(), out_offload))\n\n    def test_tiled_encode_offload_returns_cpu_tensor(self):\n        \"\"\"CPU-offload chunk helper should return latents on CPU.\"\"\"\n        host = _Host()\n        audio = torch.zeros(1, 2, 40)\n        chunk_size = 16\n        overlap = 2\n        stride = chunk_size - 2 * overlap\n        num_steps = 4\n        out = host._tiled_encode_offload_cpu(audio, 1, 40, stride, overlap, num_steps, chunk_size)\n        self.assertEqual(out.device.type, \"cpu\")\n\n\nif __name__ == \"__main__\":\n    unittest.main()\n"
  },
  {
    "path": "acestep/core/llm/__init__.py",
    "content": "\"\"\"LLM package intent: text inference contracts, provider adapters, and routing.\"\"\"\n"
  },
  {
    "path": "acestep/core/lora/__init__.py",
    "content": "\"\"\"LoRA domain services shared by handler and UI layers.\"\"\"\n\nfrom .introspection import collect_adapter_names\nfrom .registry import build_lora_registry\nfrom .scaling import apply_scale_to_adapter\nfrom .service import LoraService\n\n__all__ = [\"collect_adapter_names\", \"build_lora_registry\", \"apply_scale_to_adapter\", \"LoraService\"]\n"
  },
  {
    "path": "acestep/core/lora/introspection.py",
    "content": "\"\"\"Pure LoRA introspection helpers reusable across runtimes and UIs.\"\"\"\n\nimport math\nfrom collections.abc import Callable\nfrom typing import Any\n\n\ndef collect_adapter_names(decoder: Any) -> list[str]:\n    \"\"\"Best-effort adapter name discovery across PEFT runtime variants.\"\"\"\n\n    def _extract_names(value: Any) -> list[str]:\n        names: list[str] = []\n\n        def _append_name(name: Any) -> None:\n            if isinstance(name, str) and name and name not in names:\n                names.append(name)\n\n        def _walk(obj: Any) -> None:\n            if obj is None:\n                return\n            if isinstance(obj, str):\n                _append_name(obj)\n                return\n            if isinstance(obj, dict):\n                for key in obj.keys():\n                    _append_name(key)\n                return\n            if isinstance(obj, (list, tuple, set)):\n                for item in obj:\n                    _walk(item)\n                return\n            if hasattr(obj, \"keys\") and callable(obj.keys):\n                try:\n                    for key in obj.keys():\n                        _append_name(key)\n                except Exception:\n                    pass\n            if hasattr(obj, \"adapters\"):\n                _walk(getattr(obj, \"adapters\"))\n            if hasattr(obj, \"adapter_names\"):\n                _walk(getattr(obj, \"adapter_names\"))\n            if hasattr(obj, \"to_dict\") and callable(obj.to_dict):\n                try:\n                    _walk(obj.to_dict())\n                except Exception:\n                    pass\n\n        _walk(value)\n        return list(dict.fromkeys(names))\n\n    ordered: list[str] = []\n    source_groups: list[list[str]] = []\n\n    if hasattr(decoder, \"get_adapter_names\") and callable(decoder.get_adapter_names):\n        try:\n            names_value = decoder.get_adapter_names()\n            source_groups.append(_extract_names(names_value() if callable(names_value) else names_value))\n        except Exception:\n            pass\n\n    for attr in (\"active_adapter\", \"active_adapters\", \"peft_config\"):\n        if not hasattr(decoder, attr):\n            continue\n        try:\n            value = getattr(decoder, attr)\n            source_groups.append(_extract_names(value() if callable(value) else value))\n        except Exception:\n            pass\n\n    for group in source_groups:\n        for name in group:\n            if name not in ordered:\n                ordered.append(name)\n    return ordered\n\n\ndef is_lora_like_module(name: str, module: Any) -> bool:\n    \"\"\"Conservative LoRA module detection for mixed PEFT implementations.\"\"\"\n    name_l = name.lower()\n    cls_l = module.__class__.__name__.lower()\n    mod_l = module.__class__.__module__.lower()\n    has_lora_signals = (\n        \"lora\" in name_l\n        or \"lora\" in cls_l\n        or (\"peft\" in mod_l and \"lora\" in mod_l)\n        or hasattr(module, \"lora_A\")\n        or hasattr(module, \"lora_B\")\n    )\n    has_scaling_api = hasattr(module, \"scaling\") or hasattr(module, \"set_scale\") or hasattr(module, \"scale_layer\")\n    return has_lora_signals and has_scaling_api\n\n\ndef read_adapter_value(value: Any, adapter: str) -> Any:\n    \"\"\"Read adapter-specific value from mapping-like or scalar containers.\"\"\"\n    if value is None:\n        return None\n    if isinstance(value, dict):\n        return value.get(adapter)\n    if hasattr(value, \"keys\") and callable(value.keys):\n        try:\n            return value.get(adapter)\n        except Exception:\n            return None\n    if isinstance(value, (int, float)):\n        return value\n    return None\n\n\ndef is_peft_factor_set_scale_module(module: Any) -> bool:\n    \"\"\"Detect modules where set_scale(adapter, factor) semantics are expected.\"\"\"\n    return hasattr(module, \"set_scale\") and hasattr(module, \"lora_alpha\") and hasattr(module, \"r\")\n\n\ndef get_peft_initial_scale(\n    module: Any,\n    adapter: str,\n    debug_hook: Callable[[str], None] | None = None,\n) -> float | None:\n    \"\"\"Return PEFT LoRA baseline scale (alpha/r or alpha/sqrt(r)) for adapter.\"\"\"\n    try:\n        alpha = read_adapter_value(getattr(module, \"lora_alpha\", None), adapter)\n        r_val = read_adapter_value(getattr(module, \"r\", None), adapter)\n        if not isinstance(alpha, (int, float)) or not isinstance(r_val, (int, float)) or not r_val:\n            return None\n        use_rslora_raw = getattr(module, \"use_rslora\", False)\n        use_rslora = bool(use_rslora_raw.get(adapter, False)) if isinstance(use_rslora_raw, dict) else bool(use_rslora_raw)\n        return (alpha / math.sqrt(r_val)) if use_rslora else (alpha / r_val)\n    except Exception as exc:\n        if debug_hook is not None:\n            debug_hook(f\"Failed to compute initial scale (adapter={adapter}, err={exc})\")\n        return None\n"
  },
  {
    "path": "acestep/core/lora/registry.py",
    "content": "\"\"\"Pure LoRA registry construction.\"\"\"\n\nfrom typing import Any\n\nfrom .introspection import (\n    get_peft_initial_scale,\n    is_lora_like_module,\n    is_peft_factor_set_scale_module,\n    read_adapter_value,\n)\n\n\ndef build_lora_registry(\n    decoder: Any,\n    adapter_names: list[str],\n    lora_path: str | None = None,\n) -> tuple[dict[str, dict[str, Any]], int]:\n    \"\"\"Build explicit adapter->target mapping used for deterministic scaling.\"\"\"\n    registry: dict[str, dict[str, Any]] = {name: {\"path\": lora_path, \"targets\": []} for name in adapter_names}\n\n    for module_name, module in decoder.named_modules():\n        if not is_lora_like_module(module_name, module):\n            continue\n\n        if is_peft_factor_set_scale_module(module):\n            for adapter in adapter_names:\n                scaling = getattr(module, \"scaling\", None)\n                current_scale = read_adapter_value(scaling, adapter)\n                initial_scale = get_peft_initial_scale(module, adapter)\n                base_factor = (\n                    float(current_scale) / float(initial_scale)\n                    if isinstance(current_scale, (int, float))\n                    and isinstance(initial_scale, (int, float))\n                    and initial_scale != 0\n                    else None\n                )\n                registry[adapter][\"targets\"].append(\n                    {\n                        \"module\": module,\n                        \"kind\": \"set_scale_factor\",\n                        \"adapter\": adapter,\n                        \"module_name\": module_name,\n                        \"base_factor\": base_factor,\n                    }\n                )\n            continue\n\n        if hasattr(module, \"scaling\") and isinstance(module.scaling, dict):\n            for adapter in adapter_names:\n                if adapter in module.scaling:\n                    registry[adapter][\"targets\"].append(\n                        {\n                            \"module\": module,\n                            \"kind\": \"scaling_dict\",\n                            \"adapter\": adapter,\n                            \"module_name\": module_name,\n                            \"base_scale\": module.scaling[adapter],\n                        }\n                    )\n            continue\n\n        if hasattr(module, \"set_scale\"):\n            for adapter in adapter_names:\n                registry[adapter][\"targets\"].append(\n                    {\n                        \"module\": module,\n                        \"kind\": \"set_scale_unknown\",\n                        \"adapter\": adapter,\n                        \"module_name\": module_name,\n                        \"base_scale\": read_adapter_value(getattr(module, \"scaling\", None), adapter),\n                    }\n                )\n            continue\n\n        if hasattr(module, \"scale_layer\") and len(adapter_names) == 1:\n            adapter = adapter_names[0]\n            base_scale = read_adapter_value(getattr(module, \"scaling\", None), adapter)\n            registry[adapter][\"targets\"].append(\n                {\n                    \"module\": module,\n                    \"kind\": \"scale_layer\",\n                    \"module_name\": module_name,\n                    \"base_scale\": float(base_scale) if isinstance(base_scale, (int, float)) else None,\n                }\n            )\n            continue\n\n        if hasattr(module, \"scaling\") and isinstance(module.scaling, (int, float)) and len(adapter_names) == 1:\n            adapter = adapter_names[0]\n            registry[adapter][\"targets\"].append(\n                {\n                    \"module\": module,\n                    \"kind\": \"scaling_scalar\",\n                    \"module_name\": module_name,\n                    \"base_scale\": float(module.scaling),\n                }\n            )\n\n    total_targets = sum(len(meta[\"targets\"]) for meta in registry.values())\n    return registry, total_targets\n"
  },
  {
    "path": "acestep/core/lora/scaling.py",
    "content": "\"\"\"Pure LoRA scale application using registry entries.\"\"\"\n\nimport traceback\nfrom collections.abc import Callable\nfrom typing import Any\n\nMIN_PREV_SCALE = 1e-12\n\n\ndef _inc(store: dict[str, int], key: str) -> None:\n    store[key] = store.get(key, 0) + 1\n\n\ndef apply_scale_to_adapter(\n    registry: dict[str, dict[str, Any]],\n    scale_state: dict[tuple[int, str, str], float],\n    adapter_name: str,\n    scale: float,\n    warn_hook: Callable[[str], None] | None = None,\n    debug_hook: Callable[[str], None] | None = None,\n) -> tuple[int, dict[str, Any]]:\n    \"\"\"Apply scale to one adapter and return `(modified_count, report)`.\"\"\"\n    meta = registry.get(adapter_name)\n    if not meta:\n        report = {\n            \"adapter\": adapter_name,\n            \"modified_total\": 0,\n            \"modified_by_kind\": {},\n            \"skipped_by_kind\": {\"no_registry\": 1},\n        }\n        return 0, report\n\n    modified = 0\n    modified_by_kind: dict[str, int] = {}\n    skipped_by_kind: dict[str, int] = {}\n\n    for target in meta.get(\"targets\", []):\n        module = target.get(\"module\")\n        kind = target.get(\"kind\")\n        kind_key = kind if isinstance(kind, str) and kind else \"unknown_kind\"\n        module_name = target.get(\"module_name\")\n        if module is None:\n            _inc(skipped_by_kind, kind_key)\n            continue\n\n        try:\n            if kind == \"scaling_dict\":\n                adapter = target.get(\"adapter\")\n                if adapter not in module.scaling:\n                    _inc(skipped_by_kind, kind_key)\n                    continue\n                module.scaling[adapter] = target.get(\"base_scale\", module.scaling[adapter]) * scale\n                modified += 1\n                _inc(modified_by_kind, kind_key)\n            elif kind == \"set_scale_factor\":\n                base_factor = target.get(\"base_factor\", None)\n                if isinstance(base_factor, (int, float)):\n                    module.set_scale(adapter_name, base_factor * scale)\n                    modified += 1\n                    _inc(modified_by_kind, kind_key)\n                else:\n                    _inc(skipped_by_kind, \"set_scale_factor_unanchored\")\n                    if warn_hook:\n                        warn_hook(\n                            f\"Skipping set_scale_factor target without anchor \"\n                            f\"(adapter={adapter_name}, module={target.get('module_name')})\"\n                        )\n            elif kind == \"set_scale_unknown\":\n                base_scale = target.get(\"base_scale\", None)\n                if isinstance(base_scale, (int, float)):\n                    module.set_scale(adapter_name, base_scale * scale)\n                    modified += 1\n                    _inc(modified_by_kind, kind_key)\n                else:\n                    _inc(skipped_by_kind, kind_key)\n                    if warn_hook:\n                        warn_hook(\n                            f\"Skipping set_scale target with unknown semantics and no base \"\n                            f\"(adapter={adapter_name}, module={target.get('module_name')})\"\n                        )\n                    if debug_hook:\n                        debug_hook(\n                            f\"Skipped unanchored set_scale target \"\n                            f\"(adapter={adapter_name}, module={target.get('module_name')})\"\n                        )\n            elif kind == \"scale_layer\":\n                # scale_state tracks layer-scaling semantics (absolute desired layer scale).\n                base_scale = target.get(\"base_scale\", None)\n                desired = (base_scale * scale) if isinstance(base_scale, (int, float)) else scale\n                state_key = (id(module), kind_key, adapter_name)\n                if hasattr(module, \"unscale_layer\"):\n                    # Record the applied absolute desired scale so state stays coherent.\n                    module.unscale_layer()\n                    module.scale_layer(desired)\n                    scale_state[state_key] = float(desired)\n                    modified += 1\n                    _inc(modified_by_kind, kind_key if base_scale is not None else \"scale_layer_fallback\")\n                elif base_scale is None:\n                    _inc(skipped_by_kind, \"scale_layer_unanchored\")\n                    if warn_hook:\n                        warn_hook(\n                            f\"Skipping unanchored scale_layer target without unscale_layer \"\n                            f\"(adapter={adapter_name}, module={target.get('module_name')})\"\n                        )\n                else:\n                    prev = scale_state.get(state_key)\n                    module.scale_layer(\n                        desired / prev if isinstance(prev, (int, float)) and prev > MIN_PREV_SCALE else desired\n                    )\n                    scale_state[state_key] = float(desired)\n                    modified += 1\n                    _inc(modified_by_kind, kind_key)\n            elif kind == \"scaling_scalar\":\n                base_scale = target.get(\"base_scale\", None)\n                if not isinstance(base_scale, (int, float)):\n                    current_scaling = getattr(module, \"scaling\", None)\n                    if not isinstance(current_scaling, (int, float)):\n                        _inc(skipped_by_kind, kind_key)\n                        if warn_hook:\n                            warn_hook(\n                                f\"Skipping scaling_scalar target with non-numeric scaling \"\n                                f\"(adapter={adapter_name}, module={module_name})\"\n                            )\n                        continue\n                    base_scale = float(current_scaling)\n                module.scaling = base_scale * scale\n                modified += 1\n                _inc(modified_by_kind, kind_key)\n        except Exception as exc:\n            _inc(skipped_by_kind, kind_key)\n            if warn_hook:\n                warn_hook(\n                    f\"Failed to apply LoRA scale target \"\n                    f\"(adapter={adapter_name}, module={module_name}, kind={kind_key}, err={exc})\"\n                )\n            if debug_hook:\n                err_tb = traceback.format_exc()\n                debug_hook(\n                    f\"Scale application exception for target \"\n                    f\"(adapter={adapter_name}, module={module_name}, kind={kind_key}, err={exc}, tb={err_tb})\"\n                )\n\n    report = {\n        \"adapter\": adapter_name,\n        \"modified_total\": modified,\n        \"modified_by_kind\": modified_by_kind,\n        \"skipped_by_kind\": skipped_by_kind,\n    }\n    return modified, report\n"
  },
  {
    "path": "acestep/core/lora/service.py",
    "content": "\"\"\"Stateful LoRA facade that composes core pure functions.\"\"\"\n\nfrom collections.abc import Callable\nfrom typing import Any\n\nfrom .introspection import collect_adapter_names\nfrom .registry import build_lora_registry\nfrom .scaling import apply_scale_to_adapter\n\n\nclass LoraService:\n    \"\"\"Facade over adapter discovery, registry build, and scaling application.\n\n    When no adapter names are discoverable, a synthetic ``default`` adapter is\n    used internally and filtered to adapter-agnostic target kinds only.\n    \"\"\"\n\n    def __init__(\n        self,\n        decoder: Any | None = None,\n        warn_hook: Callable[[str], None] | None = None,\n        debug_hook: Callable[[str], None] | None = None,\n    ) -> None:\n        self.decoder = decoder\n        self.warn_hook = warn_hook\n        self.debug_hook = debug_hook\n        self.registry: dict[str, dict[str, Any]] = {}\n        self.scale_state: dict[tuple[int, str, str], float] = {}\n        self.active_adapter: str | None = None\n        self.last_scale_report: dict[str, Any] = {}\n        self.synthetic_default_mode = False\n\n    def bind_decoder(self, decoder: Any | None) -> None:\n        self.decoder = decoder\n\n    def set_hooks(\n        self,\n        warn_hook: Callable[[str], None] | None = None,\n        debug_hook: Callable[[str], None] | None = None,\n    ) -> None:\n        self.warn_hook = warn_hook\n        self.debug_hook = debug_hook\n\n    def discover_adapter_names(self) -> list[str]:\n        if self.decoder is None:\n            return []\n        return [name for name in collect_adapter_names(self.decoder) if isinstance(name, str) and name]\n\n    @staticmethod\n    def _keep_adapter_agnostic_targets(registry: dict[str, dict[str, Any]]) -> dict[str, dict[str, Any]]:\n        \"\"\"Keep only adapter-agnostic targets when no adapter names are discoverable.\"\"\"\n        allowed_kinds = {\"scale_layer\", \"scaling_scalar\"}\n        filtered: dict[str, dict[str, Any]] = {}\n        for adapter_name, meta in registry.items():\n            targets = [target for target in meta.get(\"targets\", []) if target.get(\"kind\") in allowed_kinds]\n            if targets:\n                filtered[adapter_name] = {\n                    \"path\": meta.get(\"path\"),\n                    \"targets\": targets,\n                }\n        return filtered\n\n    def rebuild_registry(self, lora_path: str | None = None) -> tuple[int, list[str]]:\n        if self.decoder is None:\n            self.registry = {}\n            self.scale_state = {}\n            self.active_adapter = None\n            self.synthetic_default_mode = False\n            return 0, []\n\n        adapter_names = self.discover_adapter_names()\n        synthetic_default = not adapter_names\n        self.synthetic_default_mode = synthetic_default\n        effective_names = adapter_names or [\"default\"]\n\n        rebuilt_registry, _ = build_lora_registry(\n            decoder=self.decoder,\n            adapter_names=effective_names,\n            lora_path=lora_path,\n        )\n        if synthetic_default:\n            rebuilt_registry = self._keep_adapter_agnostic_targets(rebuilt_registry)\n\n        self.registry = rebuilt_registry\n        self.scale_state = {}\n        total_targets = sum(len(meta.get(\"targets\", [])) for meta in self.registry.values())\n        if self.active_adapter not in self.registry:\n            self.active_adapter = next(iter(self.registry.keys()), None)\n        return total_targets, list(self.registry.keys())\n\n    def ensure_active_adapter(self) -> str | None:\n        if self.active_adapter is None and self.registry:\n            self.active_adapter = next(iter(self.registry.keys()))\n        return self.active_adapter\n\n    def set_active_adapter(self, adapter_name: str) -> bool:\n        if adapter_name not in self.registry:\n            return False\n        self.active_adapter = adapter_name\n        return True\n\n    def apply_scale(self, adapter_name: str, scale: float) -> int:\n        modified, report = apply_scale_to_adapter(\n            registry=self.registry,\n            scale_state=self.scale_state,\n            adapter_name=adapter_name,\n            scale=scale,\n            warn_hook=self.warn_hook,\n            debug_hook=self.debug_hook,\n        )\n        self.last_scale_report = report\n        return modified\n\n    def registry_snapshot(self, max_targets_per_adapter: int = 20) -> dict[str, Any]:\n        \"\"\"Return debuggable registry view and synthetic fallback mode flag.\"\"\"\n        adapters: dict[str, Any] = {}\n        for adapter_name, meta in self.registry.items():\n            targets = meta.get(\"targets\", [])\n            entries = []\n            for target in targets[:max_targets_per_adapter]:\n                module = target.get(\"module\")\n                entries.append(\n                    {\n                        \"kind\": target.get(\"kind\"),\n                        \"module_name\": target.get(\"module_name\"),\n                        \"adapter\": target.get(\"adapter\"),\n                        \"module_class\": module.__class__.__name__ if module is not None else None,\n                    }\n                )\n            adapters[adapter_name] = {\n                \"path\": meta.get(\"path\"),\n                \"target_count\": len(targets),\n                \"targets\": entries,\n                \"truncated\": len(targets) > max_targets_per_adapter,\n            }\n        return {\n            \"active_adapter\": self.active_adapter,\n            \"adapter_names\": list(self.registry.keys()),\n            \"synthetic_default_mode\": self.synthetic_default_mode,\n            \"adapters\": adapters,\n        }\n"
  },
  {
    "path": "acestep/core/lora/service_test.py",
    "content": "import unittest\n\nfrom acestep.core.lora import LoraService\nfrom acestep.core.lora.scaling import apply_scale_to_adapter\n\n\nclass FakeDecoder:\n    def __init__(self, modules, adapter_names=None):\n        self._modules = modules\n        self._adapter_names = adapter_names\n\n    def named_modules(self):\n        return self._modules\n\n    def get_adapter_names(self):\n        if self._adapter_names is None:\n            raise AttributeError(\"no adapter names\")\n        return self._adapter_names\n\n\nclass FakeScaleLayerModule:\n    scaling = 1.0\n\n    def __init__(self):\n        self.current = 1.0\n\n    def unscale_layer(self):\n        self.current = 1.0\n\n    def scale_layer(self, value):\n        self.current *= value\n\n\nclass FakeSetScaleFactorModule:\n    def __init__(self, scaling):\n        self.scaling = scaling\n        self.lora_alpha = {\"main\": 2.0}\n        self.r = {\"main\": 2.0}\n        self.calls = []\n\n    def set_scale(self, adapter_name, factor):\n        self.calls.append((adapter_name, factor))\n\n\nclass ExplodingSetScaleModule:\n    def set_scale(self, adapter_name, factor):\n        raise RuntimeError(\"boom\")\n\n\nclass LoraServiceTests(unittest.TestCase):\n    def test_rebuild_registry_keeps_adapter_agnostic_targets_without_adapter_names(self):\n        decoder = FakeDecoder(modules=[(\"lora_layer\", FakeScaleLayerModule())], adapter_names=[])\n        service = LoraService(decoder=decoder)\n\n        total_targets, adapters = service.rebuild_registry()\n\n        self.assertEqual(adapters, [\"default\"])\n        self.assertEqual(total_targets, 1)\n        self.assertEqual(service.active_adapter, \"default\")\n        target = service.registry[\"default\"][\"targets\"][0]\n        self.assertEqual(target[\"kind\"], \"scale_layer\")\n\n    def test_apply_scale_scale_layer_is_idempotent_with_unscale_layer(self):\n        module = FakeScaleLayerModule()\n        decoder = FakeDecoder(modules=[(\"lora_layer\", module)], adapter_names=[])\n        service = LoraService(decoder=decoder)\n        service.rebuild_registry()\n\n        modified_first = service.apply_scale(\"default\", 0.5)\n        first_value = module.current\n        modified_second = service.apply_scale(\"default\", 0.5)\n\n        self.assertEqual(modified_first, 1)\n        self.assertEqual(modified_second, 1)\n        self.assertEqual(first_value, 0.5)\n        self.assertEqual(module.current, 0.5)\n        self.assertEqual(len(service.scale_state), 1)\n\n    def test_set_scale_factor_unanchored_is_reported_and_skipped(self):\n        module = FakeSetScaleFactorModule(scaling={})\n        decoder = FakeDecoder(modules=[(\"lora_block\", module)], adapter_names=[\"main\"])\n        service = LoraService(decoder=decoder)\n        service.rebuild_registry()\n\n        modified = service.apply_scale(\"main\", 0.5)\n\n        self.assertEqual(modified, 0)\n        self.assertEqual(module.calls, [])\n        report = service.last_scale_report\n        self.assertEqual(report[\"adapter\"], \"main\")\n        self.assertIn(\"set_scale_factor_unanchored\", report[\"skipped_by_kind\"])\n\n    def test_scaling_scalar_non_numeric_is_skipped_with_warning(self):\n        class BadScalarModule:\n            scaling = \"not-a-number\"\n\n        warnings = []\n        registry = {\n            \"main\": {\n                \"path\": None,\n                \"targets\": [{\"module\": BadScalarModule(), \"kind\": \"scaling_scalar\", \"module_name\": \"bad_scalar\"}],\n            }\n        }\n        modified, report = apply_scale_to_adapter(\n            registry=registry,\n            scale_state={},\n            adapter_name=\"main\",\n            scale=0.5,\n            warn_hook=warnings.append,\n        )\n\n        self.assertEqual(modified, 0)\n        self.assertIn(\"scaling_scalar\", report[\"skipped_by_kind\"])\n        self.assertTrue(any(\"non-numeric scaling\" in msg for msg in warnings))\n\n    def test_target_exception_surfaces_warning(self):\n        warnings = []\n        debug = []\n        registry = {\n            \"main\": {\n                \"path\": None,\n                \"targets\": [\n                    {\n                        \"module\": ExplodingSetScaleModule(),\n                        \"kind\": \"set_scale_unknown\",\n                        \"module_name\": \"explode\",\n                        \"base_scale\": 1.0,\n                    }\n                ],\n            }\n        }\n        modified, report = apply_scale_to_adapter(\n            registry=registry,\n            scale_state={},\n            adapter_name=\"main\",\n            scale=0.5,\n            warn_hook=warnings.append,\n            debug_hook=debug.append,\n        )\n\n        self.assertEqual(modified, 0)\n        self.assertIn(\"set_scale_unknown\", report[\"skipped_by_kind\"])\n        self.assertTrue(any(\"Failed to apply LoRA scale target\" in msg for msg in warnings))\n        self.assertTrue(any(\"Scale application exception\" in msg for msg in debug))\n\n\nif __name__ == \"__main__\":\n    unittest.main()\n"
  },
  {
    "path": "acestep/core/scoring/__init__.py",
    "content": "\"\"\"Scoring package: alignment and quality metrics for generated outputs.\"\"\"\nfrom acestep.core.scoring.dit_alignment import (\n    MusicStampsAligner,\n    TokenTimestamp,\n    SentenceTimestamp,\n)\nfrom acestep.core.scoring.dit_score import MusicLyricScorer\nfrom acestep.core.scoring.lm_score import (\n    calculate_pmi_score_per_condition,\n    calculate_reward_score,\n)\n\n__all__ = [\n    \"MusicStampsAligner\",\n    \"TokenTimestamp\",\n    \"SentenceTimestamp\",\n    \"MusicLyricScorer\",\n    \"calculate_pmi_score_per_condition\",\n    \"calculate_reward_score\",\n]\n"
  },
  {
    "path": "acestep/core/scoring/_dtw.py",
    "content": "\"\"\"\nDTW and signal-processing utilities shared by DiT scoring modules.\n\nProvides Numba-optimized Dynamic Time Warping and a median filter helper.\n\"\"\"\nimport numba\nimport numpy as np\nimport torch\nimport torch.nn.functional as F\n\n\n@numba.jit(nopython=True)\ndef dtw_cpu(x: np.ndarray):\n    \"\"\"\n    Dynamic Time Warping algorithm optimized with Numba.\n\n    Args:\n        x: Cost matrix of shape [N, M]\n\n    Returns:\n        Tuple of (text_indices, time_indices) arrays\n    \"\"\"\n    N, M = x.shape\n    # Use float32 for memory efficiency\n    cost = np.ones((N + 1, M + 1), dtype=np.float32) * np.inf\n    trace = -np.ones((N + 1, M + 1), dtype=np.float32)\n    cost[0, 0] = 0\n\n    for j in range(1, M + 1):\n        for i in range(1, N + 1):\n            c0 = cost[i - 1, j - 1]\n            c1 = cost[i - 1, j]\n            c2 = cost[i, j - 1]\n\n            if c0 < c1 and c0 < c2:\n                c, t = c0, 0\n            elif c1 < c0 and c1 < c2:\n                c, t = c1, 1\n            else:\n                c, t = c2, 2\n\n            cost[i, j] = x[i - 1, j - 1] + c\n            trace[i, j] = t\n\n    return _backtrace(trace, N, M)\n\n\n@numba.jit(nopython=True)\ndef _backtrace(trace: np.ndarray, N: int, M: int):\n    \"\"\"\n    Optimized backtrace function for DTW.\n\n    Args:\n        trace: Trace matrix of shape (N+1, M+1)\n        N, M: Original matrix dimensions\n\n    Returns:\n        Path array of shape (2, path_len) - first row is text indices, second is time indices\n    \"\"\"\n    # Boundary handling\n    trace[0, :] = 2\n    trace[:, 0] = 1\n\n    # Pre-allocate array, max path length is N+M\n    max_path_len = N + M\n    path = np.zeros((2, max_path_len), dtype=np.int32)\n\n    i, j = N, M\n    path_idx = max_path_len - 1\n\n    while i > 0 or j > 0:\n        path[0, path_idx] = i - 1  # text index\n        path[1, path_idx] = j - 1  # time index\n        path_idx -= 1\n\n        t = trace[i, j]\n        if t == 0:\n            i -= 1\n            j -= 1\n        elif t == 1:\n            i -= 1\n        elif t == 2:\n            j -= 1\n        else:\n            break\n\n    return path[:, path_idx + 1:max_path_len]\n\n\ndef median_filter(x: torch.Tensor, filter_width: int) -> torch.Tensor:\n    \"\"\"\n    Apply median filter to tensor.\n\n    Args:\n        x: Input tensor\n        filter_width: Width of median filter\n\n    Returns:\n        Filtered tensor\n    \"\"\"\n    pad_width = filter_width // 2\n    if x.shape[-1] <= pad_width:\n        return x\n    if x.ndim == 2:\n        x = x[None, :]\n    x = F.pad(x, (filter_width // 2, filter_width // 2, 0, 0), mode=\"reflect\")\n    result = x.unfold(-1, filter_width, 1).sort()[0][..., filter_width // 2]\n    if result.ndim > 2:\n        result = result.squeeze(0)\n    return result\n"
  },
  {
    "path": "acestep/core/scoring/dit_alignment.py",
    "content": "\"\"\"\nDiT Alignment Module\n\nProvides lyrics-to-audio timestamp alignment using cross-attention matrices\nfrom the DiT model.  Produces LRC-format timestamps via bidirectional\nconsensus denoising and DTW.\n\"\"\"\nimport numpy as np\nimport torch\nimport torch.nn.functional as F\nfrom dataclasses import dataclass\nfrom typing import List, Dict, Any\n\nfrom acestep.core.scoring._dtw import dtw_cpu, median_filter\n\n\n# ================= Data Classes =================\n@dataclass\nclass TokenTimestamp:\n    \"\"\"Stores per-token timing information.\"\"\"\n    token_id: int\n    text: str\n    start: float\n    end: float\n    probability: float\n\n\n@dataclass\nclass SentenceTimestamp:\n    \"\"\"Stores per-sentence timing information with token list.\"\"\"\n    text: str\n    start: float\n    end: float\n    tokens: List[TokenTimestamp]\n    confidence: float\n\n\n# ================= Main Aligner Class =================\nclass MusicStampsAligner:\n    \"\"\"\n    Aligner class for generating lyrics timestamps from cross-attention matrices.\n\n    Uses bidirectional consensus denoising and DTW for alignment.\n    \"\"\"\n\n    def __init__(self, tokenizer):\n        \"\"\"\n        Initialize the aligner.\n\n        Args:\n            tokenizer: Text tokenizer for decoding tokens\n        \"\"\"\n        self.tokenizer = tokenizer\n\n    def _apply_bidirectional_consensus(\n        self,\n        weights_stack: torch.Tensor,\n        violence_level: float,\n        medfilt_width: int\n    ) -> tuple:\n        \"\"\"\n        Core denoising logic using bidirectional consensus.\n\n        Args:\n            weights_stack: Attention weights [Heads, Tokens, Frames]\n            violence_level: Denoising strength coefficient\n            medfilt_width: Median filter width\n\n        Returns:\n            Tuple of (calc_matrix, energy_matrix) as numpy arrays\n        \"\"\"\n        # A. Bidirectional Consensus\n        row_prob = F.softmax(weights_stack, dim=-1)  # Token -> Frame\n        col_prob = F.softmax(weights_stack, dim=-2)  # Frame -> Token\n        processed = row_prob * col_prob\n\n        # 1. Row suppression (kill horizontal crossing lines)\n        row_medians = torch.quantile(processed, 0.5, dim=-1, keepdim=True)\n        processed = processed - (violence_level * row_medians)\n        processed = torch.relu(processed)\n\n        # 2. Column suppression (kill vertical crossing lines)\n        col_medians = torch.quantile(processed, 0.5, dim=-2, keepdim=True)\n        processed = processed - (violence_level * col_medians)\n        processed = torch.relu(processed)\n\n        # C. Power sharpening\n        processed = processed ** 2\n\n        # Energy matrix for confidence\n        energy_matrix = processed.mean(dim=0).cpu().numpy()\n\n        # D. Z-Score normalization\n        std, mean = torch.std_mean(processed, unbiased=False)\n        weights_processed = (processed - mean) / (std + 1e-9)\n\n        # E. Median filtering\n        weights_processed = median_filter(weights_processed, filter_width=medfilt_width)\n        calc_matrix = weights_processed.mean(dim=0).numpy()\n\n        return calc_matrix, energy_matrix\n\n    def _preprocess_attention(\n        self,\n        attention_matrix: torch.Tensor,\n        custom_config: Dict[int, List[int]],\n        violence_level: float,\n        medfilt_width: int = 7\n    ) -> tuple:\n        \"\"\"\n        Preprocess attention matrix for alignment.\n\n        Args:\n            attention_matrix: Attention tensor [Layers, Heads, Tokens, Frames]\n            custom_config: Dict mapping layer indices to head indices\n            violence_level: Denoising strength\n            medfilt_width: Median filter width\n\n        Returns:\n            Tuple of (calc_matrix, energy_matrix, visual_matrix)\n        \"\"\"\n        if not isinstance(attention_matrix, torch.Tensor):\n            weights = torch.tensor(attention_matrix)\n        else:\n            weights = attention_matrix.clone()\n\n        weights = weights.cpu().float()\n\n        selected_tensors = []\n        for layer_idx, head_indices in custom_config.items():\n            for head_idx in head_indices:\n                if layer_idx < weights.shape[0] and head_idx < weights.shape[1]:\n                    head_matrix = weights[layer_idx, head_idx]\n                    selected_tensors.append(head_matrix)\n\n        if not selected_tensors:\n            return None, None, None\n\n        # Stack selected heads: [Heads, Tokens, Frames]\n        weights_stack = torch.stack(selected_tensors, dim=0)\n        visual_matrix = weights_stack.mean(dim=0).numpy()\n\n        calc_matrix, energy_matrix = self._apply_bidirectional_consensus(\n            weights_stack, violence_level, medfilt_width\n        )\n\n        return calc_matrix, energy_matrix, visual_matrix\n\n    def stamps_align_info(\n        self,\n        attention_matrix: torch.Tensor,\n        lyrics_tokens: List[int],\n        total_duration_seconds: float,\n        custom_config: Dict[int, List[int]],\n        return_matrices: bool = False,\n        violence_level: float = 2.0,\n        medfilt_width: int = 1\n    ) -> Dict[str, Any]:\n        \"\"\"\n        Get alignment information from attention matrix.\n\n        Args:\n            attention_matrix: Cross-attention tensor [Layers, Heads, Tokens, Frames]\n            lyrics_tokens: List of lyrics token IDs\n            total_duration_seconds: Total audio duration in seconds\n            custom_config: Dict mapping layer indices to head indices\n            return_matrices: Whether to return intermediate matrices\n            violence_level: Denoising strength\n            medfilt_width: Median filter width\n\n        Returns:\n            Dict containing calc_matrix, lyrics_tokens, total_duration_seconds,\n            and optionally energy_matrix and vis_matrix\n        \"\"\"\n        calc_matrix, energy_matrix, visual_matrix = self._preprocess_attention(\n            attention_matrix, custom_config, violence_level, medfilt_width\n        )\n\n        if calc_matrix is None:\n            return {\n                \"calc_matrix\": None,\n                \"lyrics_tokens\": lyrics_tokens,\n                \"total_duration_seconds\": total_duration_seconds,\n                \"error\": \"No valid attention heads found\"\n            }\n\n        return_dict = {\n            \"calc_matrix\": calc_matrix,\n            \"lyrics_tokens\": lyrics_tokens,\n            \"total_duration_seconds\": total_duration_seconds\n        }\n\n        if return_matrices:\n            return_dict['energy_matrix'] = energy_matrix\n            return_dict['vis_matrix'] = visual_matrix\n\n        return return_dict\n\n    def _decode_tokens_incrementally(self, token_ids: List[int]) -> List[str]:\n        \"\"\"\n        Decode tokens incrementally to properly handle multi-byte UTF-8 characters.\n\n        For Chinese and other multi-byte characters, the tokenizer may split them\n        into multiple byte-level tokens. Decoding each token individually produces\n        invalid UTF-8 sequences (showing as \\ufffd). This method uses byte-level comparison\n        to correctly track which characters each token contributes.\n\n        Args:\n            token_ids: List of token IDs\n\n        Returns:\n            List of decoded text for each token position\n        \"\"\"\n        decoded_tokens = []\n        prev_bytes = b\"\"\n\n        for i in range(len(token_ids)):\n            # Decode tokens from start to current position\n            current_text = self.tokenizer.decode(token_ids[:i+1], skip_special_tokens=False)\n            current_bytes = current_text.encode('utf-8', errors='surrogatepass')\n\n            # The contribution of current token is the new bytes added\n            if len(current_bytes) >= len(prev_bytes):\n                new_bytes = current_bytes[len(prev_bytes):]\n                # Try to decode the new bytes; if incomplete, use empty string\n                try:\n                    token_text = new_bytes.decode('utf-8')\n                except UnicodeDecodeError:\n                    # Incomplete UTF-8 sequence, this token doesn't complete a character\n                    token_text = \"\"\n            else:\n                # Edge case: current decode is shorter (shouldn't happen normally)\n                token_text = \"\"\n\n            decoded_tokens.append(token_text)\n            prev_bytes = current_bytes\n\n        return decoded_tokens\n\n    def token_timestamps(\n        self,\n        calc_matrix: np.ndarray,\n        lyrics_tokens: List[int],\n        total_duration_seconds: float\n    ) -> List[TokenTimestamp]:\n        \"\"\"\n        Generate per-token timestamps using DTW.\n\n        Args:\n            calc_matrix: Processed attention matrix [Tokens, Frames]\n            lyrics_tokens: List of token IDs\n            total_duration_seconds: Total audio duration\n\n        Returns:\n            List of TokenTimestamp objects\n        \"\"\"\n        n_frames = calc_matrix.shape[-1]\n        text_indices, time_indices = dtw_cpu(-calc_matrix.astype(np.float64))\n\n        seconds_per_frame = total_duration_seconds / n_frames\n        alignment_results = []\n\n        # Use incremental decoding to properly handle multi-byte UTF-8 characters\n        decoded_tokens = self._decode_tokens_incrementally(lyrics_tokens)\n\n        for i in range(len(lyrics_tokens)):\n            mask = (text_indices == i)\n\n            if not np.any(mask):\n                start = alignment_results[-1].end if alignment_results else 0.0\n                end = start\n                token_conf = 0.0\n            else:\n                times = time_indices[mask] * seconds_per_frame\n                start = times[0]\n                end = times[-1]\n                token_conf = 0.0\n\n            if end < start:\n                end = start\n\n            alignment_results.append(TokenTimestamp(\n                token_id=lyrics_tokens[i],\n                text=decoded_tokens[i],\n                start=float(start),\n                end=float(end),\n                probability=token_conf\n            ))\n\n        return alignment_results\n\n    def _decode_sentence_from_tokens(self, tokens: List[TokenTimestamp]) -> str:\n        \"\"\"\n        Decode a sentence by decoding all token IDs together.\n\n        Args:\n            tokens: List of TokenTimestamp objects\n\n        Returns:\n            Properly decoded sentence text\n        \"\"\"\n        token_ids = [t.token_id for t in tokens]\n        return self.tokenizer.decode(token_ids, skip_special_tokens=False)\n\n    def sentence_timestamps(\n        self,\n        token_alignment: List[TokenTimestamp]\n    ) -> List[SentenceTimestamp]:\n        \"\"\"\n        Group token timestamps into sentence timestamps.\n\n        Args:\n            token_alignment: List of TokenTimestamp objects\n\n        Returns:\n            List of SentenceTimestamp objects\n        \"\"\"\n        results = []\n        current_tokens = []\n\n        for token in token_alignment:\n            current_tokens.append(token)\n\n            if '\\n' in token.text:\n                # Decode all token IDs together to avoid UTF-8 issues\n                full_text = self._decode_sentence_from_tokens(current_tokens)\n\n                if full_text.strip():\n                    valid_scores = [t.probability for t in current_tokens if t.probability > 0]\n                    sent_conf = sum(valid_scores) / len(valid_scores) if valid_scores else 0.0\n\n                    results.append(SentenceTimestamp(\n                        text=full_text.strip(),\n                        start=round(current_tokens[0].start, 3),\n                        end=round(current_tokens[-1].end, 3),\n                        tokens=list(current_tokens),\n                        confidence=sent_conf\n                    ))\n\n                current_tokens = []\n\n        # Handle last sentence\n        if current_tokens:\n            # Decode all token IDs together to avoid UTF-8 issues\n            full_text = self._decode_sentence_from_tokens(current_tokens)\n            if full_text.strip():\n                valid_scores = [t.probability for t in current_tokens if t.probability > 0]\n                sent_conf = sum(valid_scores) / len(valid_scores) if valid_scores else 0.0\n\n                results.append(SentenceTimestamp(\n                    text=full_text.strip(),\n                    start=round(current_tokens[0].start, 3),\n                    end=round(current_tokens[-1].end, 3),\n                    tokens=list(current_tokens),\n                    confidence=sent_conf\n                ))\n\n        # Normalize confidence scores\n        if results:\n            all_scores = [s.confidence for s in results]\n            min_score = min(all_scores)\n            max_score = max(all_scores)\n            score_range = max_score - min_score\n\n            if score_range > 1e-9:\n                for s in results:\n                    normalized_score = (s.confidence - min_score) / score_range\n                    s.confidence = round(normalized_score, 2)\n            else:\n                for s in results:\n                    s.confidence = round(s.confidence, 2)\n\n        return results\n\n    def format_lrc(\n        self,\n        sentence_timestamps: List[SentenceTimestamp],\n        include_end_time: bool = False\n    ) -> str:\n        \"\"\"\n        Format sentence timestamps as LRC lyrics format.\n\n        Args:\n            sentence_timestamps: List of SentenceTimestamp objects\n            include_end_time: Whether to include end time (enhanced LRC format)\n\n        Returns:\n            LRC formatted string\n        \"\"\"\n        lines = []\n\n        for sentence in sentence_timestamps:\n            # Convert seconds to mm:ss.xx format\n            start_minutes = int(sentence.start // 60)\n            start_seconds = sentence.start % 60\n\n            if include_end_time:\n                end_minutes = int(sentence.end // 60)\n                end_seconds = sentence.end % 60\n                timestamp = f\"[{start_minutes:02d}:{start_seconds:05.2f}][{end_minutes:02d}:{end_seconds:05.2f}]\"\n            else:\n                timestamp = f\"[{start_minutes:02d}:{start_seconds:05.2f}]\"\n\n            # Clean the text (remove structural tags like [verse], [chorus])\n            text = sentence.text\n\n            lines.append(f\"{timestamp}{text}\")\n\n        return \"\\n\".join(lines)\n\n    def get_timestamps_and_lrc(\n        self,\n        calc_matrix: np.ndarray,\n        lyrics_tokens: List[int],\n        total_duration_seconds: float\n    ) -> Dict[str, Any]:\n        \"\"\"\n        Convenience method to get both timestamps and LRC in one call.\n\n        Args:\n            calc_matrix: Processed attention matrix\n            lyrics_tokens: List of token IDs\n            total_duration_seconds: Total audio duration\n\n        Returns:\n            Dict containing token_timestamps, sentence_timestamps, and lrc_text\n        \"\"\"\n        token_stamps = self.token_timestamps(\n            calc_matrix=calc_matrix,\n            lyrics_tokens=lyrics_tokens,\n            total_duration_seconds=total_duration_seconds\n        )\n\n        sentence_stamps = self.sentence_timestamps(token_stamps)\n        lrc_text = self.format_lrc(sentence_stamps)\n\n        return {\n            \"token_timestamps\": token_stamps,\n            \"sentence_timestamps\": sentence_stamps,\n            \"lrc_text\": lrc_text\n        }\n"
  },
  {
    "path": "acestep/core/scoring/dit_score.py",
    "content": "\"\"\"\nDiT Lyrics Quality Scorer\n\nEvaluates lyrics-to-audio alignment quality using cross-attention energy\nmatrices.  Computes Coverage, Monotonicity, and Path Confidence metrics\nvia tensor operations.\n\"\"\"\nimport numpy as np\nimport torch\nfrom typing import Any, Dict, List, Optional, Tuple, Union\n\nfrom acestep.core.scoring._dtw import dtw_cpu, median_filter\n\n\nclass MusicLyricScorer:\n    \"\"\"\n    Scorer class for evaluating lyrics-to-audio alignment quality.\n\n    Focuses on calculating alignment quality metrics (Coverage, Monotonicity, Confidence)\n    using tensor operations for potential differentiability or GPU acceleration.\n    \"\"\"\n\n    def __init__(self, tokenizer: Any):\n        \"\"\"\n        Initialize the scorer.\n\n        Args:\n            tokenizer: Tokenizer instance (must implement .decode()).\n        \"\"\"\n        self.tokenizer = tokenizer\n\n    def _generate_token_type_mask(self, token_ids: List[int]) -> np.ndarray:\n        \"\"\"\n        Generate a mask distinguishing lyrics (1) from structural tags (0).\n        Uses self.tokenizer to decode tokens.\n\n        Args:\n            token_ids: List of token IDs.\n\n        Returns:\n            Numpy array of shape [len(token_ids)] with 1 or 0.\n        \"\"\"\n        decoded_tokens = [self.tokenizer.decode([tid]) for tid in token_ids]\n        mask = np.ones(len(token_ids), dtype=np.int32)\n        in_bracket = False\n\n        for i, token_str in enumerate(decoded_tokens):\n            if '[' in token_str:\n                in_bracket = True\n            if in_bracket:\n                mask[i] = 0\n            if ']' in token_str:\n                in_bracket = False\n                mask[i] = 0\n        return mask\n\n    def _preprocess_attention(\n            self,\n            attention_matrix: Union[torch.Tensor, np.ndarray],\n            custom_config: Dict[int, List[int]],\n            medfilt_width: int = 1\n    ) -> Tuple[Optional[np.ndarray], Optional[np.ndarray], Optional[torch.Tensor]]:\n        \"\"\"\n        Extracts and normalizes the attention matrix.\n\n        Logic V4: Uses Min-Max normalization to highlight energy differences.\n\n        Args:\n            attention_matrix: Raw attention tensor [Layers, Heads, Tokens, Frames].\n            custom_config: Config mapping layers to heads.\n            medfilt_width: Width for median filtering.\n\n        Returns:\n            Tuple of (calc_matrix, energy_matrix, avg_weights_tensor).\n        \"\"\"\n        # 1. Prepare Tensor\n        if not isinstance(attention_matrix, torch.Tensor):\n            weights = torch.tensor(attention_matrix)\n        else:\n            weights = attention_matrix.clone()\n        weights = weights.cpu().float()\n\n        # 2. Select Heads based on config\n        selected_tensors = []\n        for layer_idx, head_indices in custom_config.items():\n            for head_idx in head_indices:\n                if layer_idx < weights.shape[0] and head_idx < weights.shape[1]:\n                    selected_tensors.append(weights[layer_idx, head_idx])\n\n        if not selected_tensors:\n            return None, None, None\n\n        weights_stack = torch.stack(selected_tensors, dim=0)\n\n        # 3. Average Heads\n        avg_weights = weights_stack.mean(dim=0)  # [Tokens, Frames]\n\n        # 4. Preprocessing Logic\n        # Min-Max normalization preserving energy distribution\n        # Median filter is applied to the energy matrix\n        energy_tensor = median_filter(avg_weights, filter_width=medfilt_width)\n        energy_matrix = energy_tensor.numpy()\n\n        e_min, e_max = energy_matrix.min(), energy_matrix.max()\n\n        if e_max - e_min > 1e-9:\n            energy_matrix = (energy_matrix - e_min) / (e_max - e_min)\n        else:\n            energy_matrix = np.zeros_like(energy_matrix)\n\n        # Contrast enhancement for DTW pathfinding\n        # calc_matrix is used for pathfinding, energy_matrix for scoring\n        calc_matrix = energy_matrix ** 2\n\n        return calc_matrix, energy_matrix, avg_weights\n\n    def _compute_alignment_metrics(\n            self,\n            energy_matrix: torch.Tensor,\n            path_coords: torch.Tensor,\n            type_mask: torch.Tensor,\n            time_weight: float = 0.01,\n            overlap_frames: float = 9.0,\n            instrumental_weight: float = 1.0\n    ) -> Tuple[float, float, float]:\n        \"\"\"\n        Core metric calculation logic using high-precision Tensor operations.\n\n        Args:\n            energy_matrix: Normalized energy [Rows, Cols].\n            path_coords: DTW path coordinates [Steps, 2].\n            type_mask: Token type mask [Rows] (1=Lyrics, 0=Tags).\n            time_weight: Minimum energy threshold for monotonicity.\n            overlap_frames: Allowed overlap for monotonicity check.\n            instrumental_weight: Weight for non-lyric tokens in confidence calc.\n\n        Returns:\n            Tuple of (coverage, monotonicity, confidence).\n        \"\"\"\n        # Ensure high precision for internal calculation\n        energy_matrix = energy_matrix.to(dtype=torch.float64)\n        path_coords = path_coords.long()\n        type_mask = type_mask.long()\n\n        device = energy_matrix.device\n        rows, cols = energy_matrix.shape\n\n        is_lyrics_row = (type_mask == 1)\n\n        # ================= A. Coverage Score =================\n        row_max_energies = energy_matrix.max(dim=1).values\n        total_sung_rows = is_lyrics_row.sum().double()\n\n        coverage_threshold = 0.1\n        valid_sung_mask = is_lyrics_row & (row_max_energies > coverage_threshold)\n        valid_sung_rows = valid_sung_mask.sum().double()\n\n        if total_sung_rows > 0:\n            coverage_score = valid_sung_rows / total_sung_rows\n        else:\n            coverage_score = torch.tensor(1.0, device=device, dtype=torch.float64)\n\n        # ================= B. Monotonicity Score =================\n        col_indices = torch.arange(cols, device=device, dtype=torch.float64)\n\n        weights = torch.where(\n            energy_matrix > time_weight,\n            energy_matrix,\n            torch.zeros_like(energy_matrix)\n        )\n\n        sum_w = weights.sum(dim=1)\n        sum_t = (weights * col_indices).sum(dim=1)\n\n        centroids = torch.full((rows,), -1.0, device=device, dtype=torch.float64)\n        valid_w_mask = sum_w > 1e-9\n        centroids[valid_w_mask] = sum_t[valid_w_mask] / sum_w[valid_w_mask]\n\n        valid_sequence_mask = is_lyrics_row & (centroids >= 0)\n        sung_centroids = centroids[valid_sequence_mask]\n\n        cnt = sung_centroids.shape[0]\n        if cnt > 1:\n            curr_c = sung_centroids[:-1]\n            next_c = sung_centroids[1:]\n\n            non_decreasing = (next_c >= (curr_c - overlap_frames)).double().sum()\n            pairs = torch.tensor(cnt - 1, device=device, dtype=torch.float64)\n            monotonicity_score = non_decreasing / pairs\n        else:\n            monotonicity_score = torch.tensor(1.0, device=device, dtype=torch.float64)\n\n        # ================= C. Path Confidence =================\n        if path_coords.shape[0] > 0:\n            p_rows = path_coords[:, 0]\n            p_cols = path_coords[:, 1]\n\n            path_energies = energy_matrix[p_rows, p_cols]\n            step_weights = torch.ones_like(path_energies)\n\n            is_inst_step = (type_mask[p_rows] == 0)\n            step_weights[is_inst_step] = instrumental_weight\n\n            total_energy = (path_energies * step_weights).sum()\n            total_steps = step_weights.sum()\n\n            if total_steps > 0:\n                path_confidence = total_energy / total_steps\n            else:\n                path_confidence = torch.tensor(0.0, device=device, dtype=torch.float64)\n        else:\n            path_confidence = torch.tensor(0.0, device=device, dtype=torch.float64)\n\n        return coverage_score.item(), monotonicity_score.item(), path_confidence.item()\n\n    def lyrics_alignment_info(\n            self,\n            attention_matrix: Union[torch.Tensor, np.ndarray],\n            token_ids: List[int],\n            custom_config: Dict[int, List[int]],\n            return_matrices: bool = False,\n            medfilt_width: int = 1\n    ) -> Dict[str, Any]:\n        \"\"\"\n        Generates alignment path and processed matrices.\n\n        Args:\n            attention_matrix: Input attention tensor.\n            token_ids: Corresponding token IDs.\n            custom_config: Layer/Head configuration.\n            return_matrices: If True, returns matrices in the output.\n            medfilt_width: Median filter width.\n\n        Returns:\n            Dict containing path, masks, and energy matrix.\n        \"\"\"\n        calc_matrix, energy_matrix, vis_matrix = self._preprocess_attention(\n            attention_matrix, custom_config, medfilt_width\n        )\n\n        if calc_matrix is None:\n            return {\n                \"calc_matrix\": None,\n                \"error\": \"No valid attention heads found\"\n            }\n\n        # 1. Generate Semantic Mask (1=Lyrics, 0=Tags)\n        type_mask = self._generate_token_type_mask(token_ids)\n\n        # Safety check for shape mismatch\n        if len(type_mask) != energy_matrix.shape[0]:\n            type_mask = np.ones(energy_matrix.shape[0], dtype=np.int32)\n\n        # 2. DTW Pathfinding\n        text_indices, time_indices = dtw_cpu(-calc_matrix.astype(np.float32))\n        path_coords = np.stack([text_indices, time_indices], axis=1)\n\n        return_dict = {\n            \"path_coords\": path_coords,\n            \"type_mask\": type_mask,\n            \"energy_matrix\": energy_matrix\n        }\n        if return_matrices:\n            return_dict['calc_matrix'] = calc_matrix\n            return_dict['vis_matrix'] = vis_matrix\n\n        return return_dict\n\n    def calculate_score(\n            self,\n            energy_matrix: Union[torch.Tensor, np.ndarray],\n            type_mask: Union[torch.Tensor, np.ndarray],\n            path_coords: Union[torch.Tensor, np.ndarray],\n            time_weight: float = 0.01,\n            overlap_frames: float = 9.0,\n            instrumental_weight: float = 1.0\n    ) -> Dict[str, Any]:\n        \"\"\"\n        Calculates the final alignment score based on pre-computed components.\n\n        Args:\n            energy_matrix: Processed energy matrix.\n            type_mask: Token type mask.\n            path_coords: DTW path coordinates.\n            time_weight: Minimum energy threshold for monotonicity.\n            overlap_frames: Allowed backward movement frames.\n            instrumental_weight: Weight for non-lyric path steps.\n\n        Returns:\n            Dict containing ``lyrics_score`` key with the final score.\n        \"\"\"\n        # Always compute on CPU — the scoring matrices are small and this\n        # avoids occupying GPU VRAM that DiT / VAE / LM need.\n        _score_device = \"cpu\"\n        if not isinstance(energy_matrix, torch.Tensor):\n            energy_matrix = torch.tensor(energy_matrix, device=_score_device, dtype=torch.float32)\n        else:\n            energy_matrix = energy_matrix.to(device=_score_device, dtype=torch.float32)\n\n        device = energy_matrix.device\n\n        if not isinstance(type_mask, torch.Tensor):\n            type_mask = torch.tensor(type_mask, device=device, dtype=torch.long)\n        else:\n            type_mask = type_mask.to(device=device, dtype=torch.long)\n\n        if not isinstance(path_coords, torch.Tensor):\n            path_coords = torch.tensor(path_coords, device=device, dtype=torch.long)\n        else:\n            path_coords = path_coords.to(device=device, dtype=torch.long)\n\n        # Compute Metrics\n        coverage, monotonicity, confidence = self._compute_alignment_metrics(\n            energy_matrix=energy_matrix,\n            path_coords=path_coords,\n            type_mask=type_mask,\n            time_weight=time_weight,\n            overlap_frames=overlap_frames,\n            instrumental_weight=instrumental_weight\n        )\n\n        # Final Score Calculation\n        # (Cov^2 * Mono^2 * Conf)\n        final_score = (coverage ** 2) * (monotonicity ** 2) * confidence\n        final_score = float(np.clip(final_score, 0.0, 1.0))\n\n        return {\n            \"lyrics_score\": round(final_score, 4)\n        }\n"
  },
  {
    "path": "acestep/core/scoring/lm_score.py",
    "content": "\"\"\"\nLM Perplexity / PMI Scoring Module\n\nImplements perplexity-based scoring for generated audio codes using a\nlanguage model.  Provides PMI, top-k recall, metadata recall, and a\ncomposite reward score.\n\"\"\"\nimport contextlib\nimport math\nimport re\n\nimport torch\nimport torch.nn.functional as F\nimport yaml\nfrom loguru import logger\nfrom typing import Tuple, Optional, Dict, Any, List\n\n\ndef pmi_score(log_prob_conditional: float, log_prob_unconditional: float) -> float:\n    \"\"\"\n    Calculate Pointwise Mutual Information (PMI) score.\n\n    PMI = log P(condition|codes) - log P(condition)\n        = log [P(codes|condition) / P(codes)]\n\n    This removes the bias from P(condition) and measures how much the codes\n    improve our ability to predict the condition.\n\n    Args:\n        log_prob_conditional: Average log probability of condition given codes\n        log_prob_unconditional: Average log probability of condition without codes\n\n    Returns:\n        PMI score (higher is better, can be positive or negative)\n        - Positive: codes improve prediction -> good match\n        - Zero: codes don't help -> no correlation\n        - Negative: codes hurt prediction -> poor match\n    \"\"\"\n    return log_prob_conditional - log_prob_unconditional\n\n\ndef pmi_to_normalized_score(pmi: float, scale: float = 0.1) -> float:\n    \"\"\"\n    Convert PMI score to normalized [0, 1] range using sigmoid function.\n\n    score = sigmoid(PMI / scale) = 1 / (1 + exp(-PMI / scale))\n\n    Args:\n        pmi: PMI score (can be positive or negative)\n        scale: Scale parameter to control sensitivity (default 0.1)\n               - Smaller scale: more sensitive to PMI changes\n               - Larger scale: less sensitive to PMI changes\n\n    Returns:\n        Normalized score in [0, 1] range, where:\n        - PMI > 0 -> score > 0.5 (good match)\n        - PMI = 0 -> score = 0.5 (neutral)\n        - PMI < 0 -> score < 0.5 (poor match)\n\n    Examples (scale=1.0):\n        PMI=2.0  -> score~0.88  (excellent)\n        PMI=1.0  -> score~0.73  (good)\n        PMI=0.0  -> score=0.50  (neutral)\n        PMI=-1.0 -> score~0.27  (poor)\n        PMI=-2.0 -> score~0.12  (bad)\n    \"\"\"\n    return 1.0 / (1.0 + math.exp(-pmi / scale))\n\n\n@contextlib.contextmanager\ndef _load_scoring_model_context(llm_handler):\n    \"\"\"\n    Context manager that loads the HF scoring model to the accelerator device\n    before use and offloads it back to CPU afterwards.\n\n    For the ``pt`` backend the existing ``_load_model_context()`` already\n    handles offloading, so we just delegate to it.  For ``vllm`` / ``mlx``\n    backends, ``get_hf_model_for_scoring()`` caches a *separate* HF model\n    that would otherwise stay on GPU permanently -- here we move it to GPU\n    only for the duration of the scoring forward pass and move it back to\n    CPU when done, freeing VRAM for DiT / VAE.\n    \"\"\"\n    backend = getattr(llm_handler, \"llm_backend\", \"pt\")\n\n    if backend == \"pt\":\n        # pt backend: _load_model_context already handles GPU <-> CPU\n        with llm_handler._load_model_context():\n            yield\n        return\n\n    # vllm / mlx: manage the cached HF model ourselves\n    model = llm_handler.get_hf_model_for_scoring()\n    if model is None:\n        yield\n        return\n\n    offload = getattr(llm_handler, \"offload_to_cpu\", False)\n    device = llm_handler.device if hasattr(llm_handler, \"device\") else \"cpu\"\n\n    if offload and hasattr(model, \"to\"):\n        logger.info(f\"[scoring] Loading HF scoring model to {device}\")\n        model.to(device)\n\n    try:\n        yield\n    finally:\n        if offload and hasattr(model, \"to\"):\n            logger.info(\"[scoring] Offloading HF scoring model to CPU\")\n            model.to(\"cpu\")\n            if torch.cuda.is_available():\n                torch.cuda.empty_cache()\n            elif hasattr(torch.backends, \"mps\") and torch.backends.mps.is_available() and hasattr(torch, \"mps\") and hasattr(torch.mps, \"empty_cache\"):\n                torch.mps.empty_cache()\n\n\ndef _get_logits_and_target_for_scoring(llm_handler, formatted_prompt: str,\n                                       target_text: str) -> Tuple[torch.Tensor, torch.Tensor]:\n    \"\"\"\n    Args:\n        llm_handler: The handler containing the model and tokenizer.\n        formatted_prompt: The input context.\n        target_text: The text we want to calculate probability/recall for.\n\n    Returns:\n        Tuple of (target_logits, target_ids)\n        - target_logits: Logits used to predict the target tokens.\n        - target_ids: The ground truth token IDs of the target.\n    \"\"\"\n    model = llm_handler.get_hf_model_for_scoring()\n    tokenizer = llm_handler.llm_tokenizer\n\n    # Determine the device the model is *currently* on (it may be on CPU\n    # if offload_to_cpu is active -- _load_scoring_model_context will move\n    # it to the accelerator before the forward pass).\n    backend = getattr(llm_handler, \"llm_backend\", \"pt\")\n    if backend == \"pt\":\n        device = llm_handler.device\n    else:\n        # For vllm/mlx the scoring model may be on CPU right now;\n        # use the handler's target device so tensors land on the right device\n        # once the model is moved there by the context manager.\n        device = llm_handler.device if hasattr(llm_handler, \"device\") else next(model.parameters()).device\n\n    # 1. Tokenize prompt ONLY to get its length (used for slicing later).\n    #    We must ensure special tokens are added to count the offset correctly.\n    prompt_tokens_temp = tokenizer(formatted_prompt, return_tensors=\"pt\", add_special_tokens=True)\n    prompt_len = prompt_tokens_temp['input_ids'].shape[1]\n\n    # 2. Tokenize the FULL text (Prompt + Target).\n    #    This ensures subword merging at boundaries is handled correctly by the tokenizer.\n    full_text = formatted_prompt + target_text\n    full_tokens = tokenizer(full_text, return_tensors=\"pt\", padding=False, truncation=True, add_special_tokens=True).to(device)\n\n    input_ids = full_tokens['input_ids']\n\n    # Safety check: if target was empty or truncated entirely\n    if input_ids.shape[1] <= prompt_len:\n        return torch.empty(0, device=device), torch.empty(0, device=device)\n\n    # 3. Forward Pass (Teacher Forcing)\n    #    _load_scoring_model_context ensures the model is on-device for the\n    #    forward pass and offloaded back to CPU afterwards.\n    with torch.no_grad():\n        with _load_scoring_model_context(llm_handler):\n            outputs = model(input_ids=input_ids, attention_mask=full_tokens['attention_mask'])\n            all_logits = outputs.logits  # [1, seq_len, vocab_size]\n\n    # 4. Extract Logits and Labels -- move to CPU so downstream scoring\n    #    does not keep large vocab-sized tensors on GPU.\n    target_logits = all_logits[0, prompt_len - 1:-1, :].cpu()  # [target_len, vocab_size]\n    target_ids = input_ids[0, prompt_len:].cpu()  # [target_len]\n\n    return target_logits, target_ids\n\n\n# ==============================================================================\n# Scoring Logic\n# ==============================================================================\n\n\ndef _calculate_topk_recall(llm_handler,\n                           formatted_prompt: str,\n                           target_text: str,\n                           topk: int = 10) -> Tuple[float, Dict[int, float]]:\n    \"\"\"\n    Calculate top-k recall for target text given prompt.\n    Checks if the ground truth token is within the top-k probabilities at each step.\n    \"\"\"\n    # Use the fixed helper to get aligned logits/labels\n    pred_logits, target_ids = _get_logits_and_target_for_scoring(llm_handler, formatted_prompt, target_text)\n\n    if target_ids.shape[0] == 0:\n        return 0.0, {}\n\n    target_len = target_ids.shape[0]\n\n    # Get top-k indices for all positions at once\n    # topk_indices: [target_len, topk]\n    _, topk_indices = torch.topk(pred_logits, k=min(topk, pred_logits.shape[-1]), dim=-1)\n\n    recall_per_k = {}\n    position_scores = []\n\n    # Convert to list for faster CPU iteration\n    target_ids_list = target_ids.tolist()\n    topk_indices_list = topk_indices.tolist()\n\n    for k in range(1, topk + 1):\n        hits = 0\n        for pos in range(target_len):\n            gt_token = target_ids_list[pos]\n            # Check the top-k slice\n            topk_at_pos = topk_indices_list[pos][:k]\n\n            if gt_token in topk_at_pos:\n                hits += 1\n                # Calculate position-weighted score only once (when k=topk)\n                if k == topk:\n                    rank = topk_at_pos.index(gt_token) + 1\n                    # Rank 1 = 1.0, Rank k = small positive\n                    position_weight = 1.0 - (rank - 1) / topk\n                    position_scores.append(position_weight)\n\n        recall_per_k[k] = hits / target_len if target_len > 0 else 0.0\n\n    # Fill scores for positions where GT was NOT in top-k\n    while len(position_scores) < target_len:\n        position_scores.append(0.0)\n\n    average_recall = sum(position_scores) / len(position_scores) if position_scores else 0.0\n\n    return average_recall, recall_per_k\n\n\ndef _calculate_metadata_recall(llm_handler,\n                               formatted_prompt: str,\n                               fields_dict: Dict[str, Any],\n                               topk: int = 10) -> Dict[str, float]:\n    \"\"\"\n    Args:\n        fields_dict: Dictionary of {field_name: field_value}\n    \"\"\"\n    if not fields_dict:\n        return {}\n\n    field_scores = {}\n\n    for field_name in sorted(fields_dict.keys()):\n        # Construct target text for this specific field\n        # e.g. <think>\\nbpm: 120\\n</think>\\n\n        field_yaml = yaml.dump({field_name: fields_dict[field_name]}, allow_unicode=True, sort_keys=True).strip()\n        field_target_text = f\"<think>\\n{field_yaml}\\n</think>\\n\"\n\n        # Calculate recall using the robust logic\n        avg_score, _ = _calculate_topk_recall(llm_handler, formatted_prompt, field_target_text, topk=topk)\n\n        field_scores[field_name] = avg_score\n        logger.debug(f\"Recall for {field_name}: {avg_score:.4f}\")\n\n    return field_scores\n\n\ndef _calculate_log_prob(\n        llm_handler,\n        formatted_prompt: str,\n        target_text: str,\n        temperature: float = 1.0  # Kept for API compatibility, but ignored for scoring\n) -> float:\n    \"\"\"\n    Calculate average log probability of target text given prompt.\n    \"\"\"\n    pred_logits, target_ids = _get_logits_and_target_for_scoring(llm_handler, formatted_prompt, target_text)\n\n    if target_ids.shape[0] == 0:\n        return float('-inf')\n\n    # FIX: Do not divide by temperature.\n    # Log-probability for PMI/Perplexity should be exact.\n\n    # Calculate log probabilities (log_softmax)\n    log_probs = F.log_softmax(pred_logits, dim=-1)  # [target_len, vocab_size]\n\n    # Gather log probabilities of the ground truth tokens\n    target_log_probs = log_probs[torch.arange(target_ids.shape[0]), target_ids]\n\n    # Return average log probability\n    mean_log_prob = target_log_probs.mean().item()\n\n    return mean_log_prob\n\n\ndef calculate_reward_score(\n    scores: Dict[str, float],\n    weights_config: Optional[Dict[str, float]] = None\n) -> Tuple[float, str]:\n    \"\"\"\n    Reward Model Calculator: Computes a final reward based on user priorities.\n\n    Priority Logic:\n        1. Caption (Highest): The overall vibe/style must match.\n        2. Lyrics (Medium): Content accuracy is important but secondary to vibe.\n        3. Metadata (Lowest): Technical constraints (BPM, Key) allow for slight deviations.\n\n    Strategy: Dynamic Weighted Sum\n    - Metadata fields are aggregated into a single 'metadata' score first.\n    - Weights are dynamically renormalized if any component (e.g., lyrics) is missing.\n\n    Args:\n        scores: Dictionary of raw scores (0.0 - 1.0) from the evaluation module.\n        weights_config: Optional custom weights. Defaults to:\n                        Caption (50%), Lyrics (30%), Metadata (20%).\n\n    Returns:\n        final_reward: The calculated reward score (0.0 - 1.0).\n        explanation: A formatted string explaining how the score was derived.\n    \"\"\"\n\n    # 1. Default Preference Configuration\n    # These weights determine the relative importance of each component.\n    if weights_config is None:\n        weights_config = {\n            'caption': 0.50,  # High priority: Style/Vibe\n            'lyrics':  0.30,  # Medium priority: Content\n            'metadata': 0.20  # Low priority: Technical details\n        }\n\n    # 2. Extract and Group Scores\n    # Caption and Lyrics are standalone high-level features.\n    caption_score = scores.get('caption')\n    lyrics_score = scores.get('lyrics')\n\n    # Metadata fields (bpm, key, duration, etc.) are aggregated.\n    # We treat them as a single \"Technical Score\" to prevent them from\n    # diluting the weight of Caption/Lyrics simply by having many fields.\n    meta_scores_list = [\n        val for key, val in scores.items()\n        if key not in ['caption', 'lyrics']\n    ]\n\n    # Calculate average of all metadata fields (if any exist)\n    meta_aggregate_score = None\n    if meta_scores_list:\n        meta_aggregate_score = sum(meta_scores_list) / len(meta_scores_list)\n\n    # 3. specific Active Components & Dynamic Weighting\n    # We only include components that actually exist in this generation.\n    active_components = {}\n\n    if caption_score is not None:\n        active_components['caption'] = (caption_score, weights_config['caption'])\n\n    if lyrics_score is not None:\n        active_components['lyrics'] = (lyrics_score, weights_config['lyrics'])\n\n    if meta_aggregate_score is not None:\n        active_components['metadata'] = (meta_aggregate_score, weights_config['metadata'])\n\n    # 4. Calculate Final Weighted Score\n    total_base_weight = sum(w for _, w in active_components.values())\n    total_score = 0.0\n\n    breakdown_lines = []\n\n    if total_base_weight == 0:\n        return 0.0, \"❌ No valid scores available to calculate reward.\"\n\n    # Sort by weight (importance) for display\n    sorted_components = sorted(active_components.items(), key=lambda x: x[1][1], reverse=True)\n\n    for name, (score, base_weight) in sorted_components:\n        # Renormalize weight: If lyrics are missing, caption/metadata weights scale up proportionately.\n        normalized_weight = base_weight / total_base_weight\n        weighted_contribution = score * normalized_weight\n        total_score += weighted_contribution\n\n        breakdown_lines.append(\n            f\"  • {name.title():<8} | Score: {score:.4f} | Weight: {normalized_weight:.2f} \"\n            f\"-> Contrib: +{weighted_contribution:.4f}\"\n        )\n\n    return total_score, \"\\n\".join(breakdown_lines)\n\n# ==============================================================================\n# Main Public API\n# ==============================================================================\n\n\ndef calculate_pmi_score_per_condition(\n    llm_handler,\n    audio_codes: str,\n    caption: str = \"\",\n    lyrics: str = \"\",\n    metadata: Optional[Dict[str, Any]] = None,\n    temperature: float = 1.0,\n    topk: int = 10,\n    score_scale: float = 0.1,\n) -> Tuple[Dict[str, float], float, str]:\n    \"\"\"\n    Calculate quality score separately for each condition.\n    - Metadata: Uses Top-k Recall.\n    - Caption/Lyrics: Uses PMI (Normalized).\n    \"\"\"\n    if not llm_handler.llm_initialized:\n        return {}, 0.0, \"❌ LLM not initialized\"\n\n    if not audio_codes or not audio_codes.strip():\n        return {}, 0.0, \"❌ No audio codes provided\"\n\n    if \"caption\" not in metadata:\n        metadata['caption'] = caption\n\n    formatted_prompt = llm_handler.build_formatted_prompt_for_understanding(audio_codes=audio_codes, is_negative_prompt=False)\n    prompt_uncond = llm_handler.build_formatted_prompt_for_understanding(audio_codes=\"NO USER INPUT\", is_negative_prompt=False)\n    try:\n        # 1. Calculate Recall for Metadata Fields\n        if metadata and isinstance(metadata, dict):\n            scores = {}\n            # Define which fields use which metric\n            metadata_recall_keys = ['bpm', 'duration', 'genres', 'keyscale', 'language', 'timesignature']\n            metadata_pmi_keys = ['caption']\n            for key in metadata_recall_keys:\n                if key in metadata and metadata[key] is not None:\n                    recall_metadata = {key: metadata[key]}\n                    field_scores = _calculate_metadata_recall(llm_handler, formatted_prompt, recall_metadata, topk=topk)\n                    scores.update(field_scores)\n\n            # 2. Calculate PMI for Caption\n            for key in metadata_pmi_keys:\n                if key in metadata and metadata[key] is not None:\n                    cot_yaml = yaml.dump({key: metadata[key]}, allow_unicode=True, sort_keys=True).strip()\n                    target_text = f\"<think>\\n{cot_yaml}\\n</think>\\n\"\n\n                    log_prob_cond = _calculate_log_prob(llm_handler, formatted_prompt, target_text)\n                    log_prob_uncond = _calculate_log_prob(llm_handler, prompt_uncond, target_text)\n\n                    pmi_normalized = pmi_to_normalized_score(log_prob_cond - log_prob_uncond, scale=score_scale)\n                    scores[key] = pmi_normalized\n\n        # 3. Calculate PMI for Lyrics\n        if lyrics:\n            target_text = f\"<think>\\n</think>\\n# Lyric\\n{lyrics}\\n\"\n\n            log_prob_cond = _calculate_log_prob(llm_handler, formatted_prompt, target_text)\n\n            prompt_uncond = llm_handler.build_formatted_prompt_for_understanding(audio_codes=\"NO USER INPUT\", is_negative_prompt=False)\n            log_prob_uncond = _calculate_log_prob(llm_handler, prompt_uncond, target_text)\n\n            scores['lyrics'] = pmi_to_normalized_score(log_prob_cond - log_prob_uncond, scale=score_scale)\n\n        if not scores:\n            return {}, 0.0, \"❌ No conditions to evaluate\"\n\n        # 4. Global Score\n        global_score = sum(scores.values()) / len(scores)\n        global_score, breakdown_lines = calculate_reward_score(scores)\n\n        # Status Message\n        status_lines = [breakdown_lines, \"\\n✅ Per-condition scores (0-1):\"]\n        for key, score in sorted(scores.items()):\n            metric = \"Top-k Recall\" if key in metadata_recall_keys else \"PMI (Norm)\"\n            status_lines.append(f\"  {key}: {score:.4f} ({metric})\")\n        status = \"\\n\".join(status_lines)\n        logger.info(f\"Calculated scores: {global_score:.4f}\\n{status}\")\n        return scores, global_score, status\n\n    except Exception as e:\n        import traceback\n        error_msg = f\"❌ Error: {str(e)}\"\n        logger.error(error_msg)\n        logger.error(traceback.format_exc())\n        return {}, float('-inf'), error_msg\n"
  },
  {
    "path": "acestep/core/scoring/scoring_test.py",
    "content": "\"\"\"Unit tests for DTW utilities and LM score pure functions.\"\"\"\n\nimport math\nimport unittest\n\nimport numpy as np\nimport torch\n\nfrom acestep.core.scoring._dtw import dtw_cpu, median_filter\nfrom acestep.core.scoring.lm_score import (\n    pmi_score,\n    pmi_to_normalized_score,\n    calculate_reward_score,\n)\n\n\nclass DtwCpuTests(unittest.TestCase):\n    \"\"\"Tests for the Numba-optimized DTW implementation.\"\"\"\n\n    def test_identity_cost_matrix(self):\n        \"\"\"DTW on a diagonal-zero cost matrix should follow the diagonal.\"\"\"\n        n = 4\n        cost = np.ones((n, n), dtype=np.float64)\n        np.fill_diagonal(cost, 0.0)\n        text_idx, time_idx = dtw_cpu(-cost)\n        # Path should be monotonically non-decreasing\n        self.assertTrue(np.all(np.diff(text_idx) >= 0))\n        self.assertTrue(np.all(np.diff(time_idx) >= 0))\n\n    def test_single_element(self):\n        \"\"\"DTW on a 1x1 matrix should return a single-step path.\"\"\"\n        cost = np.array([[0.5]], dtype=np.float64)\n        text_idx, time_idx = dtw_cpu(-cost)\n        self.assertEqual(text_idx.tolist(), [0])\n        self.assertEqual(time_idx.tolist(), [0])\n\n    def test_rectangular_matrix(self):\n        \"\"\"DTW should handle non-square matrices.\"\"\"\n        cost = np.zeros((2, 5), dtype=np.float64)\n        text_idx, time_idx = dtw_cpu(-cost)\n        # Path must cover both rows and all columns\n        self.assertIn(0, text_idx)\n        self.assertIn(1, text_idx)\n        self.assertEqual(time_idx[-1], 4)\n\n\nclass MedianFilterTests(unittest.TestCase):\n    \"\"\"Tests for the median filter utility.\"\"\"\n\n    def test_identity_with_width_one(self):\n        \"\"\"Filter width 1 should return the input unchanged.\"\"\"\n        x = torch.tensor([[1.0, 2.0, 3.0, 4.0, 5.0]])\n        result = median_filter(x, filter_width=1)\n        torch.testing.assert_close(result, x)\n\n    def test_smoothing_effect(self):\n        \"\"\"Filter width > 1 should smooth spike values.\"\"\"\n        x = torch.tensor([[0.0, 0.0, 10.0, 0.0, 0.0]])\n        result = median_filter(x, filter_width=3)\n        # The spike at index 2 should be reduced\n        self.assertLess(result[0, 2].item(), 10.0)\n\n    def test_short_input_passthrough(self):\n        \"\"\"Inputs shorter than pad width should be returned as-is.\"\"\"\n        x = torch.tensor([[1.0]])\n        result = median_filter(x, filter_width=5)\n        torch.testing.assert_close(result, x)\n\n\nclass PmiScoreTests(unittest.TestCase):\n    \"\"\"Tests for the PMI pure functions.\"\"\"\n\n    def test_positive_pmi(self):\n        \"\"\"Conditional > unconditional should yield positive PMI.\"\"\"\n        result = pmi_score(-1.0, -2.0)\n        self.assertAlmostEqual(result, 1.0)\n\n    def test_zero_pmi(self):\n        \"\"\"Equal log probs should yield zero PMI.\"\"\"\n        result = pmi_score(-1.5, -1.5)\n        self.assertAlmostEqual(result, 0.0)\n\n    def test_negative_pmi(self):\n        \"\"\"Conditional < unconditional should yield negative PMI.\"\"\"\n        result = pmi_score(-3.0, -1.0)\n        self.assertAlmostEqual(result, -2.0)\n\n\nclass PmiNormalizedScoreTests(unittest.TestCase):\n    \"\"\"Tests for the PMI-to-sigmoid normalization.\"\"\"\n\n    def test_zero_pmi_gives_half(self):\n        \"\"\"PMI of zero should map to exactly 0.5.\"\"\"\n        self.assertAlmostEqual(pmi_to_normalized_score(0.0), 0.5)\n\n    def test_positive_pmi_above_half(self):\n        \"\"\"Positive PMI should map above 0.5.\"\"\"\n        self.assertGreater(pmi_to_normalized_score(1.0), 0.5)\n\n    def test_negative_pmi_below_half(self):\n        \"\"\"Negative PMI should map below 0.5.\"\"\"\n        self.assertLess(pmi_to_normalized_score(-1.0), 0.5)\n\n    def test_bounded_zero_one(self):\n        \"\"\"Output should always be in [0, 1].\"\"\"\n        for pmi_val in [-100, -10, -1, 0, 1, 10, 100]:\n            score = pmi_to_normalized_score(float(pmi_val), scale=1.0)\n            self.assertGreaterEqual(score, 0.0)\n            self.assertLessEqual(score, 1.0)\n\n\nclass RewardScoreTests(unittest.TestCase):\n    \"\"\"Tests for the reward score aggregation.\"\"\"\n\n    def test_all_components_present(self):\n        \"\"\"With all three components, result should be a weighted average.\"\"\"\n        scores = {\"caption\": 0.8, \"lyrics\": 0.6, \"bpm\": 0.9}\n        total, _ = calculate_reward_score(scores)\n        self.assertGreater(total, 0.0)\n        self.assertLessEqual(total, 1.0)\n\n    def test_no_scores_returns_zero(self):\n        \"\"\"Empty scores dict should return zero reward.\"\"\"\n        total, explanation = calculate_reward_score({})\n        self.assertEqual(total, 0.0)\n\n    def test_caption_only(self):\n        \"\"\"With only caption, reward should equal the caption score.\"\"\"\n        scores = {\"caption\": 0.75}\n        total, _ = calculate_reward_score(scores)\n        self.assertAlmostEqual(total, 0.75, places=2)\n\n    def test_metadata_aggregation(self):\n        \"\"\"Multiple metadata fields should be averaged into one component.\"\"\"\n        scores = {\"bpm\": 1.0, \"duration\": 0.5}\n        total, _ = calculate_reward_score(scores)\n        # Only metadata component present, so total = avg(1.0, 0.5) = 0.75\n        self.assertAlmostEqual(total, 0.75, places=2)\n\n\nif __name__ == \"__main__\":\n    unittest.main()\n"
  },
  {
    "path": "acestep/core/system/__init__.py",
    "content": "\"\"\"System package intent: shared infra helpers (GPU config, models, cache, constants).\"\"\"\n"
  },
  {
    "path": "acestep/dataset/__init__.py",
    "content": "\"\"\"Dataset package intent: dataset lifecycle modules for runtime and build-time usage.\"\"\"\n"
  },
  {
    "path": "acestep/dataset/builder/__init__.py",
    "content": "\"\"\"Dataset builder package intent: offline dataset scanning, preprocessing, and serialization.\"\"\"\n"
  },
  {
    "path": "acestep/dataset/runtime/__init__.py",
    "content": "\"\"\"Dataset runtime package intent: dataset access/operations used during app execution.\"\"\"\n"
  },
  {
    "path": "acestep/dataset_handler.py",
    "content": "\"\"\"\nDataset Handler Module\n\nHandles dataset import and exploration functionality for ACE-Step training.\nThis module provides a placeholder implementation for dataset operations\nwhen the full training dataset dependencies are not available.\n\nNote: Full dataset functionality requires Text2MusicDataset which may not be\nincluded in the basic installation to reduce dependencies.\n\"\"\"\nfrom typing import Optional, Tuple, Any, Dict\n\n\nclass DatasetHandler:\n    \"\"\"\n    Dataset Handler for Dataset Explorer functionality.\n    \n    Provides interface for dataset import and exploration features in the Gradio UI.\n    When training dependencies are not available, returns appropriate fallback responses.\n    \"\"\"\n    \n    def __init__(self):\n        \"\"\"Initialize dataset handler with empty state\"\"\"\n        self.dataset = None\n        self.dataset_imported = False\n    \n    def import_dataset(self, dataset_type: str) -> str:\n        \"\"\"\n        Import dataset (currently disabled in base installation)\n        \n        Args:\n            dataset_type: Type of dataset to import (e.g., \"train\", \"test\", \"validation\")\n            \n        Returns:\n            Status message indicating dataset import is disabled\n            \n        Note:\n            This is a placeholder implementation. Full dataset support requires:\n            - Text2MusicDataset dependency\n            - Training data files  \n            - Additional configuration\n        \"\"\"\n        self.dataset_imported = False\n        return f\"⚠️ Dataset import is currently disabled. Text2MusicDataset dependency not available.\"\n    \n    def get_item_data(self, *args, **kwargs) -> Tuple:\n        \"\"\"\n        Get dataset item data (placeholder implementation)\n        \n        Args:\n            *args: Variable arguments (ignored in placeholder)\n            **kwargs: Keyword arguments (ignored in placeholder)\n            \n        Returns:\n            Tuple of placeholder values matching the expected return format:\n            (caption, lyrics, language, bpm, keyscale, ref_audio, src_audio, codes,\n             status_msg, instruction, duration, timesig, audio1, audio2, audio3, \n             metadata, task_type)\n             \n        Note:\n            Returns empty/default values since dataset is not available.\n            Real implementation would return actual dataset samples.\n        \"\"\"\n        return (\n            \"\",           # caption: empty string\n            \"\",           # lyrics: empty string  \n            \"\",           # language: empty string\n            \"\",           # bpm: empty string\n            \"\",           # keyscale: empty string\n            None,         # ref_audio: no audio file\n            None,         # src_audio: no audio file\n            None,         # codes: no audio codes\n            \"❌ Dataset not available\",  # status_msg: error indicator\n            \"\",           # instruction: empty string\n            0,            # duration: zero\n            \"\",           # timesig: empty string\n            None,         # audio1: no audio\n            None,         # audio2: no audio\n            None,         # audio3: no audio\n            {},           # metadata: empty dict\n            \"text2music\"  # task_type: default task\n        )\n\n"
  },
  {
    "path": "acestep/debug_utils.py",
    "content": "\"\"\"\nDebug helpers (global).\n\"\"\"\nfrom __future__ import annotations\n\nfrom datetime import datetime\nfrom typing import Optional, Callable, Union\n\nfrom acestep.constants import (\n    TENSOR_DEBUG_MODE,\n    DEBUG_API_SERVER,\n    DEBUG_INFERENCE,\n    DEBUG_TRAINING,\n    DEBUG_DATASET,\n    DEBUG_AUDIO,\n    DEBUG_LLM,\n    DEBUG_UI,\n    DEBUG_MODEL_LOADING,\n    DEBUG_GPU,\n)\n\n# ----------------------------------------------------------------------\n# CPU thread configuration\n# ----------------------------------------------------------------------\n# When running on CPU we want to make use of most of the available cores\n# but leave a couple free for the OS / other processes.  The logic is:\n#   * If the system has ≤ 2 logical CPUs, use all of them.\n#   * Otherwise, use (cpu_count - 2) threads.\n# This mirrors the common “all‑but‑two” heuristic while guaranteeing at\n#   least one thread.\n# The function is executed at import time so that any subsequent\n# torch operations respect the setting.\nimport os\nimport torch\n\ndef _configure_cpu_threads() -> None:\n    \"\"\"Set torch's intra-op and inter-op thread counts based on available CPUs.\n\n    This function configures PyTorch to use most available CPU cores while\n    leaving a couple free for the OS and other processes. The logic is:\n      * If the system has ≤ 2 logical CPUs, use all of them.\n      * Otherwise, use (cpu_count - 2) threads.\n\n    This mirrors the common \"all-but-two\" heuristic while guaranteeing at\n    least one thread.\n\n    Raises:\n        RuntimeError: If torch.set_num_threads or torch.set_num_interop_threads\n            fails (e.g., if called after threads have already been used).\n    \"\"\"\n    cpu_cnt = os.cpu_count() or 1\n    # Ensure we never set a non-positive number of threads.\n    threads = cpu_cnt - 2 if cpu_cnt > 2 else cpu_cnt\n    threads = max(threads, 1)\n\n    try:\n        torch.set_num_threads(threads)\n    except RuntimeError as exc:\n        raise RuntimeError(\n            f\"Failed to set torch intra-op threads to {threads}: {exc}\"\n        ) from exc\n\n    try:\n        torch.set_num_interop_threads(threads)\n    except RuntimeError as exc:\n        raise RuntimeError(\n            f\"Failed to set torch inter-op threads to {threads}: {exc}\"\n        ) from exc\n\n# Track whether CPU threads have been configured to avoid redundant calls.\n_cpu_threads_configured = False\n\n\ndef configure_cpu_threads_if_needed() -> bool:\n    \"\"\"Configure CPU threads if enabled via environment variable.\n\n    This function provides an opt-in mechanism for configuring PyTorch's\n    thread counts. It only takes effect if the environment variable\n    ``ACESTEP_CONFIGURE_THREADS`` is set to a truthy value (e.g., \"1\", \"true\", \"yes\").\n\n    The configuration is applied at most once per process; subsequent calls\n    are no-ops.\n\n    Returns:\n        True if configuration was applied, False if skipped (either because\n        the environment variable is not set or configuration was already done).\n\n    Raises:\n        RuntimeError: If thread configuration fails (propagated from\n            ``_configure_cpu_threads``).\n    \"\"\"\n    global _cpu_threads_configured\n\n    if _cpu_threads_configured:\n        return False\n\n    env_value = os.environ.get(\"ACESTEP_CONFIGURE_THREADS\", \"\").strip().lower()\n    if env_value not in (\"1\", \"true\", \"yes\", \"on\"):\n        return False\n\n    _configure_cpu_threads()\n    _cpu_threads_configured = True\n    return True\n\n\n# Apply opt-in CPU thread configuration early so torch respects it.\nconfigure_cpu_threads_if_needed()\n\n\ndef _normalize_mode(mode: str) -> str:\n    return (mode or \"\").strip().upper()\n\n\ndef is_debug_enabled(mode: str) -> bool:\n    return _normalize_mode(mode) != \"OFF\"\n\n\ndef is_debug_verbose(mode: str) -> bool:\n    return _normalize_mode(mode) == \"VERBOSE\"\n\n\ndef debug_log(message: Union[str, Callable[[], str]], *, mode: str = TENSOR_DEBUG_MODE, prefix: str = \"debug\") -> None:\n    \"\"\"Emit a timestamped debug log line if the mode is enabled.\"\"\"\n    if not is_debug_enabled(mode):\n        return\n    if callable(message):\n        message = message()\n    ts = datetime.now().strftime(\"%Y-%m-%d %H:%M:%S.%f\")[:-3]\n    print(f\"[{prefix}] {ts} {message}\", flush=True)\n\n\n# Placeholder debug switches registry (for centralized access)\nDEBUG_SWITCHES = {\n    \"tensor\": TENSOR_DEBUG_MODE,\n    \"api_server\": DEBUG_API_SERVER,\n    \"inference\": DEBUG_INFERENCE,\n    \"training\": DEBUG_TRAINING,\n    \"dataset\": DEBUG_DATASET,\n    \"audio\": DEBUG_AUDIO,\n    \"llm\": DEBUG_LLM,\n    \"ui\": DEBUG_UI,\n    \"model_loading\": DEBUG_MODEL_LOADING,\n    \"gpu\": DEBUG_GPU,\n}\n\n\ndef get_debug_mode(name: str, default: str = \"OFF\") -> str:\n    \"\"\"Fetch a placeholder debug mode by name.\"\"\"\n    return DEBUG_SWITCHES.get((name or \"\").strip().lower(), default)\n\n\ndef debug_log_for(name: str, message: Union[str, Callable[[], str]], *, prefix: str | None = None) -> None:\n    \"\"\"Emit a timestamped debug log for a named subsystem.\"\"\"\n    mode = get_debug_mode(name)\n    debug_log(message, mode=mode, prefix=prefix or name)\n\n\ndef debug_start_for(name: str, label: str) -> Optional[float]:\n    \"\"\"Start timing for a named subsystem.\"\"\"\n    mode = get_debug_mode(name)\n    return debug_start(label, mode=mode, prefix=name)\n\n\ndef debug_end_for(name: str, label: str, start_ts: Optional[float]) -> None:\n    \"\"\"End timing for a named subsystem.\"\"\"\n    mode = get_debug_mode(name)\n    debug_end(label, start_ts, mode=mode, prefix=name)\n\n\ndef debug_log_verbose_for(name: str, message: Union[str, Callable[[], str]], *, prefix: str | None = None) -> None:\n    \"\"\"Emit a timestamped debug log only in VERBOSE mode for a named subsystem.\"\"\"\n    mode = get_debug_mode(name)\n    if not is_debug_verbose(mode):\n        return\n    debug_log(message, mode=mode, prefix=prefix or name)\n\n\ndef debug_start_verbose_for(name: str, label: str) -> Optional[float]:\n    \"\"\"Start timing only in VERBOSE mode for a named subsystem.\"\"\"\n    mode = get_debug_mode(name)\n    if not is_debug_verbose(mode):\n        return None\n    return debug_start(label, mode=mode, prefix=name)\n\n\ndef debug_end_verbose_for(name: str, label: str, start_ts: Optional[float]) -> None:\n    \"\"\"End timing only in VERBOSE mode for a named subsystem.\"\"\"\n    mode = get_debug_mode(name)\n    if not is_debug_verbose(mode):\n        return\n    debug_end(label, start_ts, mode=mode, prefix=name)\n\n\ndef debug_start(name: str, *, mode: str = TENSOR_DEBUG_MODE, prefix: str = \"debug\") -> Optional[float]:\n    \"\"\"Return a start timestamp (perf counter) if enabled, otherwise None.\"\"\"\n    if not is_debug_enabled(mode):\n        return None\n    debug_log(f\"START {name}\", mode=mode, prefix=prefix)\n    from time import perf_counter\n    return perf_counter()\n\n\ndef debug_end(name: str, start_ts: Optional[float], *, mode: str = TENSOR_DEBUG_MODE, prefix: str = \"debug\") -> None:\n    \"\"\"Emit an END log with elapsed ms if enabled and start_ts is present.\"\"\"\n    if start_ts is None or not is_debug_enabled(mode):\n        return\n    from time import perf_counter\n    elapsed_ms = (perf_counter() - start_ts) * 1000.0\n    debug_log(f\"END {name} ({elapsed_ms:.1f} ms)\", mode=mode, prefix=prefix)\n"
  },
  {
    "path": "acestep/genres_vocab.txt",
    "content": "16-bit J-RPG\n16-bit JRPG\n16-bit Japanese RPG\n16-bit RPG\n16-bit ambient\n16-bit chiptune\n16-bit orchestral\n16-bit video game\n16-bit video game music\n1950s pop\n1950s rock and roll\n1960s British pop\n1960s German pop-rock\n1960s Spanish rock, Latin rock, mambo\n1960s ballad\n1960s pop\n1960s pop ballad\n1960s pop, doo-wop\n1960s pop, doo-wop, cinematic\n1960s pop, lounge, exotica\n1960s pop, theatrical, cinematic\n1960s pop-rock\n1960s rock and roll\n2-step garage\n2000s Asian pop\n2000s R&B\n2000s R&B Afrobeats\n2000s R&B Pop\n2000s R&B chiptune\n2000s R&B dancehall\n2000s R&B hip hop\n2000s R&B hip-hop\n2000s R&B pop\n2000s R&B, chiptune, hip-hop\n2000s R&B, hip-hop\n2000s R&B, hip-hop, gospel\n2000s club\n2000s hip-hop\n2000s pop R&B\n20th-century classical\n4/4 drum loop\n60s British Invasion\n60s British pop\n60s British pop-rock\n60s British rock\n60s Dutch rock\n60s European pop\n60s French pop\n60s French pop-rock\n60s French rock\n60s German pop\n60s German rock\n60s Israeli pop\n60s Israeli rock\n60s Italian pop\n60s Italian pop-rock\n60s Italian rock\n60s R&B\n60s R&B soul\n60s Spanish rock\n60s ballad\n60s beat music\n60s beat music, German Schlager\n60s dance-pop\n60s folk-pop\n60s folk-rock\n60s garage rock\n60s novelty pop\n60s pop\n60s pop ballad\n60s pop rock\n60s pop soul\n60s pop, Latin pop\n60s pop, Latin pop, theatrical\n60s pop, art rock, soul\n60s pop, cinematic, orchestral\n60s pop, doo-wop\n60s pop, early rock and roll\n60s pop, exotica, theatrical\n60s pop, lounge, exotica\n60s pop, pop-rock, psychedelic\n60s pop, theatrical pop\n60s pop, theatrical pop, orchestral\n60s pop, theatrical, baritone\n60s pop, theatrical, cinematic\n60s pop, theatrical, melancholic\n60s pop, theatrical, operatic\n60s pop, theatrical, orchestral\n60s pop-rock\n60s pop-rock country\n60s pop-rock exotica\n60s pop-rock soul\n60s pop-rock, Israeli psychedelic rock\n60s pop-rock, J-pop\n60s pop-rock, Schlager\n60s pop-rock, exotica, lounge\n60s pop-soul\n60s psychedelic pop\n60s psychedelic pop-rock\n60s psychedelic rock\n60s rock\n60s rock and roll\n60s rock and roll soul\n60s rock ballad\n60s rock, Eastern European rock\n60s rock, German rock\n60s rock, choral rock\n60s rock, jangle pop\n60s rock, theatrical rock\n60s soul\n60s soul ballad\n60s soul rock\n60s soul, rock and roll\n60s soul-pop\n60s spy soundtrack\n60s-70s East Asian pop\n70s Polish rock\n70s funk, R&B, Christmas\n70s pop\n70s pop ballad\n70s pop-rock\n70s pop-soul\n70s rock, psychedelic soul\n70s soul\n70s soul-pop\n8-bit\n8-bit Japanese RPG\n8-bit Japanese anime\n8-bit Japanese synth\n8-bit Japanese video game\n8-bit RPG\n8-bit ambient\n8-bit anime\n8-bit arcade\n8-bit chiptune\n8-bit chiptune polka\n8-bit chiptune trap\n8-bit chiptune, Afro-pop\n8-bit chiptune, new jack swing\n8-bit dembow\n8-bit electro\n8-bit electro-funk\n8-bit electronic\n8-bit funk\n8-bit hip hop\n8-bit jazzy\n8-bit metal\n8-bit nostalgia\n8-bit orchestral\n8-bit pop\n8-bit, synthwave, Japanese video game\n80s Arabic rock\n80s Arabic synth-pop\n80s Asian pop\n80s Asian pop, cinematic ballad\n80s Balkan power ballad\n80s Bengali pop\n80s Bollywood\n80s Bollywood dance-pop\n80s Bollywood pop\n80s Bollywood synth-pop\n80s Brazilian ballad\n80s Brazilian boogie\n80s Brazilian funk-pop\n80s Brazilian gospel\n80s Brazilian pop\n80s Brazilian pop-funk\n80s Brazilian pop-gospel\n80s Brazilian pop-rock\n80s Brazilian power ballad\n80s Brazilian rock\n80s Brazilian romantic ballad\n80s British indie rock\n80s C-pop\n80s Cantopop\n80s Cantopop rock\n80s Cantopop, Eurobeat\n80s Cantopop, cinematic synth-pop\n80s Cantopop, synth-pop, dance-pop\n80s Cantopop, synth-pop, pop-rock\n80s Cantopop, synth-pop, rock fusion\n80s Cantopop-rock\n80s Chinese pop\n80s Chinese rock\n80s Christian pop\n80s Christian pop-gospel\n80s Christian pop-rock\n80s Christian power ballad\n80s Christian rock\n80s Christian worship\n80s Christmas ballad\n80s Czech pop\n80s Danish pop\n80s Danish pop-rock\n80s Danish rock\n80s Dutch levenslied\n80s Dutch pop\n80s Dutch pop-rock\n80s East Asian pop\n80s Eastern European pop\n80s Eastern European rock\n80s European pop\n80s Europop\n80s Filipino pop\n80s Filipino pop-rock\n80s Filipino power ballad\n80s Filipino rock\n80s Finnish pop-rock\n80s French pop\n80s French pop-rock\n80s French power ballad\n80s French rock\n80s G-funk\n80s German Schlager\n80s German children's music\n80s German pop\n80s German pop-rock\n80s German power ballad\n80s German rock\n80s Greek pop-rock\n80s Greek rock\n80s Indian film-pop\n80s Indian filmi\n80s Indian funk-pop\n80s Indonesian pop\n80s Indonesian pop-gospel\n80s Indonesian pop-rock\n80s Indonesian rock\n80s Israeli pop\n80s Israeli pop-rock\n80s Israeli power ballad\n80s Israeli rock\n80s Italian pop-rock\n80s Italian power ballad\n80s Italian rock\n80s J-pop\n80s J-pop cinematic\n80s J-pop city pop\n80s J-pop, city pop, anime theme\n80s J-pop, city-pop\n80s J-pop, city-pop, synth-pop\n80s J-pop, city-pop, synthwave\n80s J-pop, synth-pop, city pop\n80s J-rock\n80s Japanese RPG\n80s Japanese anime\n80s Japanese anime rock\n80s Japanese arcade\n80s Japanese arena rock\n80s Japanese ballad\n80s Japanese funk-rock\n80s Japanese fusion\n80s Japanese hard rock\n80s Japanese heavy metal\n80s Japanese pop\n80s Japanese pop-rock\n80s Japanese power ballad\n80s Japanese rock\n80s Japanese synth-pop\n80s Japanese synth-rock\n80s Japanese video game\n80s Japanese video game music\n80s K-ballad\n80s K-pop\n80s K-pop ballad\n80s K-pop rock\n80s Korean funk-pop\n80s Korean pop\n80s Korean rock\n80s Korean synth-pop\n80s Korean synth-pop, new wave\n80s Korean trot-pop\n80s Latin Christian\n80s Latin Christian pop\n80s Latin ballad\n80s Latin pop\n80s Latin pop-rock\n80s Latin power ballad\n80s Latin rock\n80s Latin synth-pop\n80s Mandopop\n80s Mandopop Latin\n80s Mandopop Latin disco\n80s Mandopop campus rock\n80s Mandopop disco\n80s Mandopop disco-funk\n80s Mandopop funk-rock\n80s Mandopop power ballad\n80s Mandopop rock\n80s Mandopop tropical\n80s Mandopop, City Pop\n80s Mandopop, City Pop, synth-pop\n80s Mandopop, Latin pop\n80s Mandopop, chiptune, synth-pop\n80s Mandopop, cinematic orchestral\n80s Mandopop, cinematic, epic\n80s Mandopop, cinematic, orchestral\n80s Mandopop, cinematic, synthwave\n80s Mandopop, city pop, synth-pop\n80s Mandopop, city-pop\n80s Mandopop, disco, funk\n80s Mandopop, disco, synth-pop\n80s Mandopop, disco-funk\n80s Mandopop, disco-funk, city pop\n80s Mandopop, disco-pop\n80s Mandopop, power ballad, cinematic\n80s Mandopop, power ballad, city pop\n80s Mandopop, power ballad, glam rock\n80s Mandopop, power metal\n80s Mandopop, synth-pop\n80s Mandopop, synth-pop, R&B\n80s Mandopop, synth-pop, chiptune\n80s Mandopop, synth-pop, city pop\n80s Mandopop, synth-pop, disco\n80s Mandopop, synth-pop, new wave\n80s OPM\n80s OPM, cumbia, synth pop\n80s Persian pop\n80s Persian pop-rock\n80s Persian synth-pop\n80s Polish pop\n80s Polish pop-rock\n80s Polish power ballad\n80s Polish rock\n80s Portuguese ballad\n80s Portuguese pop\n80s Portuguese pop, disco\n80s Portuguese pop-rock\n80s R&B\n80s R&B boogie\n80s R&B boogie-woogie\n80s R&B city pop\n80s R&B funk\n80s R&B funk-pop\n80s R&B gospel\n80s R&B pop\n80s R&B smooth jazz\n80s R&B soul\n80s R&B synth-pop\n80s R&B, Christmas pop\n80s R&B, New Jack Swing\n80s R&B, Quiet Storm\n80s R&B, cinematic soul\n80s R&B, city pop, synth-funk\n80s R&B, gospel, new jack swing\n80s R&B, gospel-pop\n80s R&B, new jack swing\n80s R&B, new jack swing, city pop\n80s R&B, new jack swing, gospel\n80s R&B, quiet storm\n80s R&B, quiet storm, cinematic soul\n80s R&B, soul, new jack swing\n80s R&B, synth-funk\n80s R&B, synth-funk, soul\n80s R&B, synth-pop\n80s Romanian pop-rock\n80s Romanian power ballad\n80s Russian power ballad\n80s Russian rock\n80s Scandinavian pop\n80s Schlager\n80s Schlager, Neue Deutsche Welle\n80s Schlager, Neue Deutsche Welle, Christmas\n80s South Asian film music\n80s South Asian pop\n80s South Asian pop funk\n80s South Asian pop-rock\n80s South Indian pop\n80s Southeast Asian pop\n80s Soviet synth-pop\n80s Spanish ballad\n80s Spanish pop\n80s Spanish pop-rock\n80s Spanish power ballad\n80s Spanish power ballad, future bass\n80s Spanish rock\n80s Sundanese pop\n80s Swedish pop\n80s Swedish pop-rock\n80s Swedish power ballad\n80s Swedish rock\n80s TV theme\n80s Taiwanese Hokkien pop\n80s Taiwanese pop\n80s Taiwanese pop-rock\n80s Thai funk-pop\n80s Thai pop\n80s Thai pop-rock\n80s Thai power ballad\n80s Thai rock\n80s Thai synth-pop\n80s Turkish pop\n80s Turkish pop-rock\n80s V-Pop\n80s V-pop\n80s Vietnamese pop\n80s Vietnamese pop, synth-pop\n80s Zouk\n80s Zouk R&B\n80s action\n80s action movie\n80s action-pop\n80s adult contemporary\n80s adult contemporary, country-pop\n80s adult contemporary, smooth jazz, melancholic ballad\n80s alternative rock\n80s anime\n80s anime pop\n80s anime rock\n80s anime soundtrack\n80s anime synth\n80s anime theme\n80s arena rock\n80s arena rock, chiptune\n80s arena rock, video game soundtrack\n80s ballad\n80s ballad, dance-pop, rock\n80s ballad, hard rock, cinematic\n80s boogie\n80s boogie R&B\n80s boogie funk\n80s boogie post-disco\n80s boogie soul\n80s boogie synth-funk\n80s boogie, R&B\n80s boogie, cinematic synth, funk\n80s boogie, electro-funk, Afropop\n80s boogie, electro-funk, post-disco\n80s boogie, post-disco, funk\n80s boogie, post-disco, new jack swing\n80s boogie, post-disco, soulful synth\n80s boogie, synth-funk\n80s boogie, synth-funk, New Jack Swing\n80s boogie, synth-funk, R&B\n80s boogie, synth-funk, post-disco\n80s boogie-funk\n80s boogie-rock\n80s cartoon\n80s cartoon theme\n80s cinematic\n80s cinematic rock\n80s corporate\n80s dance\n80s dance pop\n80s dance-pop\n80s dance-pop funk\n80s dance-rock\n80s dancehall\n80s digital reggae\n80s drum loop\n80s drum machine\n80s electro\n80s electro-funk\n80s electro-pop\n80s electronic\n80s electronic dance\n80s electronic, dance, Middle Eastern fusion\n80s electronic, world fusion, synth-pop\n80s fantasy\n80s film score\n80s filmi pop\n80s filmi-pop\n80s football anthem\n80s freestyle\n80s freestyle house\n80s freestyle, dance-pop\n80s freestyle, new jack swing\n80s freestyle, synth-pop\n80s funk\n80s funk R&B\n80s funk boogie\n80s funk, boogie\n80s funk, boogie, soul\n80s funk-pop\n80s funk-rock\n80s fusion\n80s gospel\n80s gospel R&B\n80s gospel pop-rock\n80s hard rock\n80s hard rock, South Asian pop-rock\n80s hard rock, glam metal, power ballad\n80s hard rock, video game music\n80s heavy metal\n80s heavy metal chiptune\n80s heavy metal, video game music\n80s heavy metal, video game soundtrack\n80s hip-hop\n80s hip-hop, new jack swing, synth-pop\n80s horror soundtrack\n80s house\n80s indie pop\n80s indie pop-rock\n80s instrumental\n80s jangle pop\n80s jingle\n80s movie theme\n80s new age\n80s new age smooth jazz\n80s new age, cinematic, video game soundtrack\n80s new age, library music\n80s new age, smooth jazz\n80s new age, smooth jazz, cinematic\n80s new age, synth-pop\n80s new age, synth-pop, cinematic\n80s new age, world fusion\n80s new age, world music\n80s new wave\n80s new wave rock\n80s new wave, dream pop, Christmas\n80s new wave, early house, Afro-funk\n80s new wave, gothic rock, power ballad\n80s new wave, video game soundtrack\n80s pop\n80s pop R&B\n80s pop ballad\n80s pop ballad, smooth jazz\n80s pop gospel\n80s pop rock\n80s pop, 90s East Asian pop\n80s pop, 90s East Asian pop, chiptune\n80s pop, 90s East Asian pop, retro synth\n80s pop, 90s East Asian pop, synth pop\n80s pop, 90s Southeast Asian pop\n80s pop, 90s pop, Asian pop\n80s pop, 90s pop, Southeast Asian pop\n80s pop, 90s pop, children's music\n80s pop, Asian pop\n80s pop, Christmas\n80s pop, Christmas, synth-pop\n80s pop, Danish Christmas\n80s pop, Eastern European, synth pop\n80s pop, Eurodance\n80s pop, Israeli pop, dance-pop\n80s pop, Portuguese pop\n80s pop, R&B\n80s pop, South Asian pop\n80s pop, Southeast Asian pop\n80s pop, Southeast Asian pop, synth pop\n80s pop, Swedish Christmas\n80s pop, disco, smooth jazz\n80s pop, filmi, synth funk\n80s pop, gospel, R&B\n80s pop, karaoke, retro synth\n80s pop, pimba\n80s pop, pimba, retro Portuguese\n80s pop, retro dance-pop\n80s pop, retro pop, Taiwanese Hokkien pop\n80s pop, retro synth, Southeast Asian pop\n80s pop, retro, Sinhala pop\n80s pop, synth ballad\n80s pop, synth ballad, C-pop\n80s pop, synth pop, tropical pop\n80s pop, tropical pop\n80s pop-R&B\n80s pop-country\n80s pop-funk\n80s pop-gospel\n80s pop-rock\n80s pop-rock, Israeli rock\n80s pop-rock, Latin pop\n80s pop-rock, Latin, instrumental\n80s pop-rock, South Indian film music\n80s pop-rock, Southern rock\n80s pop-rock, acoustic ballad\n80s pop-rock, country-pop\n80s pop-rock, new wave\n80s pop-soul\n80s post-disco\n80s power ballad\n80s power ballad, Christian contemporary\n80s power ballad, Eastern European rock\n80s power ballad, J-rock\n80s power ballad, synth-pop\n80s power pop\n80s power pop-rock\n80s power rock\n80s power-pop\n80s praise and worship\n80s progressive rock, synth-pop, power ballad\n80s reggae\n80s reggae-pop, synth-pop\n80s retro\n80s retro electronic\n80s retro house\n80s retro-futuristic\n80s retro-futuristic chiptune\n80s retro-futuristic house\n80s rock\n80s rock ballad\n80s rock funk\n80s rock opera\n80s rock parody\n80s rock, East Asian folk\n80s rock, Latin rock\n80s rock, Nepali rock\n80s rock, South Asian pop\n80s rock, Southeast Asian rock\n80s rock, Vietnamese rock\n80s rock, power ballad, C-pop\n80s rock, power ballad, cinematic rock\n80s rock, synth-pop, South Indian film music\n80s romantic ballad\n80s romantic duet\n80s schlager\n80s slow jam\n80s slow rock\n80s soft rock\n80s soul\n80s soul R&B\n80s soul boogie\n80s soul-pop\n80s soundtrack\n80s stadium rock\n80s synth\n80s synth anthem\n80s synth ballad\n80s synth brass\n80s synth funk\n80s synth lullaby\n80s synth pop\n80s synth rock\n80s synth-pop\n80s synth-pop J-pop\n80s synth-pop dream pop\n80s synth-pop funk\n80s synth-pop library music\n80s synth-pop rock\n80s synth-pop rock opera\n80s synth-pop, Bollywood, Christian devotional\n80s synth-pop, Christian contemporary, power ballad\n80s synth-pop, Mandopop ballad\n80s synth-pop, Schlager, children's music\n80s synth-pop, disco, C-pop\n80s synth-pop, disco, Christmas pop\n80s synth-pop, library music\n80s synth-pop, pop-rock, power ballad\n80s synth-rock\n80s synthpop\n80s synthwave\n80s video game\n80s video game rock\n80s world-pop\n80s worldbeat\n80s worldbeat, new age\n80s worship\n80s-inspired Filipino pop\n80s-inspired pop-rock\n80s-inspired, lo-fi, ambient\n80s-style Mandopop\n80s-style South Asian pop\n80s-style Taiwanese pop\n80s-style Vietnamese pop\n80s-style rock\n80s/90s South Asian film music\n80s/90s South Asian pop\n80s/90s Southeast Asian pop\n90s Asian pop\n90s British indie rock\n90s C-pop, synth-pop\n90s C-pop, world music\n90s Chinese dance-pop\n90s Christian C-pop\n90s Christian hip-hop\n90s Danish hip-hop\n90s East Coast hip hop\n90s East Coast hip-hop\n90s Eurodance\n90s Eurodance, R&B, pop\n90s European pop\n90s Filipino hip-hop\n90s Filipino pop\n90s Filipino power ballad\n90s French hip-hop\n90s German hip-hop\n90s Indonesian pop\n90s Italian funk, acid jazz\n90s J-RPG\n90s J-pop\n90s JRPG\n90s Japanese RPG\n90s Japanese hip-hop\n90s Japanese house\n90s Japanese house, video game music\n90s Japanese lounge\n90s Japanese video game\n90s Japanese video game music\n90s Japanese video game music fusion jazz\n90s Japanese video game music, Eurobeat\n90s Japanese video game music, funk, synth-pop\n90s Japanese video game music, happy hardcore\n90s Japanese video game music, house music\n90s Japanese video game music, synth-funk\n90s Japanese video game music, synth-pop\n90s K-ballad\n90s K-hip-hop\n90s K-pop\n90s K-pop Eurodance\n90s K-pop ballad\n90s K-pop hip-hop\n90s K-pop, Eurobeat\n90s K-pop, Eurobeat, dance-pop\n90s K-pop, Eurobeat, high-energy\n90s K-pop, Eurodance\n90s K-pop, Eurodance, City Pop\n90s K-pop, Eurodance, Hi-NRG\n90s K-pop, Eurodance, Italo disco\n90s K-pop, Eurodance, dance\n90s K-pop, Eurodance, dance-pop\n90s K-pop, Eurodance, happy hardcore\n90s K-pop, Eurodance, techno\n90s K-pop, Eurodance, trance\n90s K-pop, New Jack Swing\n90s K-pop, R&B, city-pop\n90s K-pop, boom-bap, funk\n90s K-pop, city pop, Eurobeat\n90s K-pop, new jack swing\n90s K-pop, new jack swing, city pop\n90s K-pop, new jack swing, dance\n90s K-pop, new jack swing, funk\n90s Korean R&B\n90s Korean ballad\n90s Korean hip-hop\n90s Korean hip-hop R&B\n90s Korean rock\n90s Latin pop\n90s MPB\n90s Malaysian slow rock\n90s Mandopop\n90s Mandopop R&B\n90s Mandopop dance\n90s Mandopop rock\n90s Mandopop, R&B, city pop\n90s Mandopop, synth-pop\n90s Memphis rap\n90s Polish hip-hop\n90s Pop Dangdut\n90s R&B\n90s R&B Arabic pop\n90s R&B Bollywood pop\n90s R&B C-pop\n90s R&B City Pop\n90s R&B French hip-hop\n90s R&B French house\n90s R&B G-funk\n90s R&B Gospel\n90s R&B Indian pop\n90s R&B K-pop\n90s R&B MPB\n90s R&B Mandopop\n90s R&B UK garage\n90s R&B acid jazz\n90s R&B adult contemporary\n90s R&B chiptune\n90s R&B city pop\n90s R&B conscious hip-hop\n90s R&B dancehall\n90s R&B dream pop\n90s R&B funk\n90s R&B gospel\n90s R&B gospel hip-hop\n90s R&B gospel-pop\n90s R&B hip-hop\n90s R&B hip-hop soul\n90s R&B house\n90s R&B lo-fi\n90s R&B lovers rock\n90s R&B neo-soul\n90s R&B neo-soul reggae\n90s R&B pop\n90s R&B pop-rock dance-pop\n90s R&B reggae fusion\n90s R&B smooth jazz\n90s R&B soul\n90s R&B soul-pop\n90s R&B synth-pop\n90s R&B trip-hop\n90s R&B, Brazilian pop\n90s R&B, Brazilian pop, gospel\n90s R&B, Cantopop\n90s R&B, Cantopop, new jack swing\n90s R&B, Christmas pop, cinematic\n90s R&B, French hip-hop\n90s R&B, G-funk\n90s R&B, G-funk, hip-hop\n90s R&B, G-funk, modern R&B\n90s R&B, G-funk, new jack swing\n90s R&B, G-funk, smooth hip-hop\n90s R&B, Gospel\n90s R&B, Gospel, New Jack Swing\n90s R&B, J-pop, pop ballad\n90s R&B, Japanese hip-hop\n90s R&B, K-pop\n90s R&B, Latin pop\n90s R&B, Middle Eastern pop\n90s R&B, New Jack Swing\n90s R&B, New Jack Swing, Christmas\n90s R&B, New Jack Swing, German pop\n90s R&B, New Jack Swing, festive\n90s R&B, New Jack Swing, pop-R&B\n90s R&B, New York House\n90s R&B, Punjabi pop\n90s R&B, Quiet Storm\n90s R&B, UK garage\n90s R&B, UK garage, house\n90s R&B, UK hip-hop\n90s R&B, adult contemporary\n90s R&B, ambient pop\n90s R&B, atmospheric piano\n90s R&B, boom-bap, hip-hop\n90s R&B, boom-bap, vaporwave\n90s R&B, chillwave\n90s R&B, chiptune\n90s R&B, cinematic soul\n90s R&B, cinematic soul, lo-fi hip hop\n90s R&B, cinematic, C-pop\n90s R&B, city pop\n90s R&B, conscious hip-hop\n90s R&B, conscious reggae\n90s R&B, dance-pop\n90s R&B, dancehall\n90s R&B, funk, Christmas\n90s R&B, gospel\n90s R&B, gospel hip-hop\n90s R&B, gospel house\n90s R&B, gospel pop\n90s R&B, gospel pop, cinematic\n90s R&B, gospel soul\n90s R&B, gospel, Christmas ballad\n90s R&B, gospel, pop\n90s R&B, gospel, power ballad\n90s R&B, gospel, soul\n90s R&B, gospel, synth pop\n90s R&B, gospel, world music\n90s R&B, gospel-pop\n90s R&B, hip hop, Latin pop\n90s R&B, hip-hop\n90s R&B, hip-hop soul\n90s R&B, hip-hop, Balkan pop\n90s R&B, hip-hop, G-funk\n90s R&B, hip-hop, K-R&B\n90s R&B, hip-hop, Latin\n90s R&B, hip-hop, New Jack Swing\n90s R&B, hip-hop, acid jazz\n90s R&B, hip-hop, chiptune\n90s R&B, hip-hop, cinematic\n90s R&B, hip-hop, cinematic soul\n90s R&B, hip-hop, dancehall\n90s R&B, hip-hop, dream pop\n90s R&B, hip-hop, dream-pop\n90s R&B, hip-hop, festive\n90s R&B, hip-hop, gospel\n90s R&B, hip-hop, industrial\n90s R&B, hip-hop, lo-fi\n90s R&B, hip-hop, lo-fi jazz\n90s R&B, hip-hop, neo-soul\n90s R&B, hip-hop, new jack swing\n90s R&B, hip-hop, quiet storm\n90s R&B, hip-hop, soul\n90s R&B, hip-hop, video game soundtrack\n90s R&B, house\n90s R&B, inspirational pop, gospel\n90s R&B, lo-fi hip hop\n90s R&B, neo-soul\n90s R&B, neo-soul, boom-bap\n90s R&B, neo-soul, hip-hop\n90s R&B, neo-soul, quiet storm\n90s R&B, neo-soul, trip-hop\n90s R&B, new age, dream pop\n90s R&B, new jack swing\n90s R&B, new jack swing, Italian pop\n90s R&B, new jack swing, cinematic\n90s R&B, new jack swing, cinematic orchestral\n90s R&B, new jack swing, city pop\n90s R&B, new jack swing, festive\n90s R&B, new jack swing, lo-fi\n90s R&B, new jack swing, pop\n90s R&B, new jack swing, video game music\n90s R&B, pop ballad\n90s R&B, pop, soul\n90s R&B, pop, world music\n90s R&B, pop-rock\n90s R&B, quiet storm\n90s R&B, reggae fusion, pop ballad\n90s R&B, smooth jazz\n90s R&B, smooth soul\n90s R&B, soul, cinematic\n90s R&B, soul, dream pop\n90s R&B, synth-pop\n90s R&B, synth-pop, video game music\n90s R&B, trap, hip-hop\n90s R&B, video game music\n90s R&B, video game soundtrack\n90s R&B, world music\n90s RPG\n90s Romanian pop\n90s Russian dance-pop\n90s Russian hip-hop\n90s Russian pop\n90s South Asian pop\n90s South Indian pop, Eurodance, Christian devotional\n90s Southeast Asian pop\n90s Southeast Asian pop-rock\n90s Southeast Asian power ballad\n90s Southeast Asian slow rock\n90s Thai dance-pop\n90s Thai pop\n90s Thai pop-rock\n90s Thai-pop\n90s UK hip-hop\n90s Ukrainian pop\n90s V-Pop\n90s V-pop\n90s V-pop, Eurodance\n90s Vietnamese pop\n90s Vietnamese power ballad\n90s Vietnamese rock ballad\n90s adult contemporary\n90s alternative\n90s alternative dance\n90s alternative rock\n90s alternative rock dream pop\n90s anime\n90s anime rock\n90s anime soundtrack\n90s anime theme\n90s boom-bap\n90s boom-bap hip-hop\n90s boom-bap, R&B, hip hop\n90s boom-bap, soulful hip-hop, atmospheric rap\n90s boy band\n90s breakbeat\n90s breakbeat, South Asian pop\n90s corporate\n90s dance\n90s dance diva\n90s dance, video game music, chiptune\n90s dance-pop\n90s electronic\n90s electronic dance\n90s electronic pop\n90s electronica\n90s eurodance, chiptune, children's music\n90s gangsta rap\n90s hip hop\n90s hip hop R&B\n90s hip hop, dance-pop\n90s hip-hop\n90s hip-hop Bollywood pop\n90s hip-hop Indian film music\n90s hip-hop R&B\n90s hip-hop acid jazz\n90s hip-hop funk\n90s hip-hop neo-soul\n90s hip-hop neo-soul acid jazz\n90s hip-hop reggae fusion\n90s hip-hop samba\n90s hip-hop soul\n90s hip-hop, Bollywood fusion\n90s hip-hop, Bollywood pop\n90s hip-hop, Caribbean hip-hop\n90s hip-hop, G-funk\n90s hip-hop, Indian fusion\n90s hip-hop, New Jack Swing\n90s hip-hop, Punjabi pop, Hindi rap\n90s hip-hop, R&B\n90s hip-hop, R&B, C-pop\n90s hip-hop, R&B, G-funk\n90s hip-hop, R&B, house\n90s hip-hop, R&B, neo-soul\n90s hip-hop, South Asian pop\n90s hip-hop, South Indian film music\n90s hip-hop, South Indian funk\n90s hip-hop, cinematic, soul\n90s hip-hop, funk, pop-rap\n90s hip-hop, lo-fi R&B\n90s hip-hop, neo-soul\n90s hip-hop, neo-soul, R&B\n90s hip-hop, neo-soul, funk\n90s hip-hop, neo-soul, jazz\n90s hip-hop, new jack swing\n90s hip-hop, new jack swing, K-pop\n90s hip-hop, new jack swing, funk\n90s hip-hop, reggae, dancehall\n90s hip-hop, soul, R&B\n90s hip-hop, soulful R&B\n90s house\n90s house R&B\n90s house acid jazz\n90s house dancehall\n90s house disco-funk\n90s house disco-pop\n90s house funk\n90s house funk jazz fusion\n90s house garage\n90s house gospel\n90s house gospel-pop\n90s house soulful disco\n90s house soulful garage\n90s house techno\n90s house trance\n90s house worldbeat\n90s house, Bollywood dance-pop\n90s house, Eurodance\n90s house, Italo disco\n90s house, Italo house\n90s house, Latin freestyle\n90s house, R&B\n90s house, R&B, breakbeat\n90s house, UK garage\n90s house, UK garage, electronic\n90s house, UK garage, soulful R&B\n90s house, acid house\n90s house, ballroom\n90s house, breakbeat\n90s house, breakbeat, funk\n90s house, breakbeat, soulful\n90s house, breakbeat, synth funk\n90s house, chiptune\n90s house, chiptune, trance\n90s house, dance-pop\n90s house, deep house\n90s house, disco house\n90s house, disco-funk\n90s house, disco-house\n90s house, disco-pop\n90s house, diva house\n90s house, early techno\n90s house, eurodance\n90s house, garage\n90s house, garage, hip-house\n90s house, gospel house\n90s house, gospel house, Eurodance\n90s house, gospel, Chinese traditional\n90s house, gospel-pop\n90s house, hip-house\n90s house, jungle, deep house\n90s house, new jack swing\n90s house, new jack swing, R&B\n90s house, nu-disco\n90s house, soulful R&B\n90s house, soulful disco\n90s house, soulful disco, funk\n90s house, soulful garage\n90s house, soulful house\n90s house, synth-pop\n90s house, trance\n90s house, trip-hop\n90s house, video game music\n90s house-pop\n90s indie rock\n90s lounge\n90s new age, world fusion\n90s pop\n90s pop R&B\n90s pop ballad\n90s pop, Eastern European, Turkish\n90s pop, Latin pop, world music\n90s pop-R&B\n90s pop-folk\n90s pop-rock\n90s power ballad\n90s rave\n90s rave, happy hardcore\n90s rock\n90s rock ballad\n90s slow rock\n90s synth\n90s synth-pop\n90s synthwave\n90s techno\n90s techno house\n90s trance\n90s trance, EBM\n90s trance, Eurodance\n90s trance, eurodance\n90s trance, progressive house\n90s trance, techno\n90s trance, video game music\n90s trance, video game music, cinematic\n90s underground hip-hop\n90s video game\n90s video game music\n90s video game music, breakbeat, house\n90s video game music, synth-pop\n90s video game, Japanese fusion, funk\n90s video game, funk, electronic lounge\n90s video game, house\n90s video game, new age\n90s world music\nAI pop\nAOR\nAOR city pop\nAOR fusion\nAOR pop-rock\nAOR power ballad\nAOR rock\nAOR synth-pop\nAOR, new wave, arena rock\nAOR, soft rock, 80s power ballad\nASMR\nASMR lullaby\nAcoustic C-pop\nAcoustic Folk\nAcoustic folk\nAcoustic, Ambient, Ancient Style\nAfrican Gospel\nAfrican Gospel, Soukous\nAfrican R&B\nAfrican Rumba\nAfrican acoustic\nAfrican chant\nAfrican chiptune\nAfrican choral\nAfrican choral folk\nAfrican choral, French chanson, folk\nAfrican choral, chiptune\nAfrican choral, chiptune, video game music\nAfrican choral, synth-pop\nAfrican dance-pop\nAfrican disco-funk\nAfrican drill\nAfrican drill trap\nAfrican drum circle\nAfrican drumming\nAfrican folk\nAfrican folk chiptune\nAfrican folk cumbia\nAfrican folk funk\nAfrican folk lo-fi\nAfrican folk rumba\nAfrican folk world music\nAfrican folk, Congolese rumba, soukous\nAfrican folk, Latin jazz, Gypsy jazz\nAfrican folk, acoustic hip-hop\nAfrican folk, reggae, dancehall\nAfrican folk, soukous\nAfrican folk, soukous, disco\nAfrican folk, soukous, highlife\nAfrican folk, soukous, salsa\nAfrican folk, worldbeat\nAfrican folk, worldbeat, acoustic\nAfrican folk-funk\nAfrican folk-fusion\nAfrican folk-gospel\nAfrican folk-pop\nAfrican folk-pop, Soukous\nAfrican folk-reggae\nAfrican folk-rock\nAfrican funk\nAfrican funk soul\nAfrican funk, Highlife\nAfrican funk, soukous\nAfrican fusion\nAfrican gospel\nAfrican gospel R&B\nAfrican gospel chiptune\nAfrican gospel cumbia\nAfrican gospel funk\nAfrican gospel funk-pop\nAfrican gospel highlife\nAfrican gospel pop-rock\nAfrican gospel reggae\nAfrican gospel synth-pop\nAfrican gospel, Afropop, Soukous\nAfrican gospel, Highlife\nAfrican gospel, Highlife, ambient soul\nAfrican gospel, Soukous\nAfrican gospel, Soukous, Afrobeat\nAfrican gospel, Soukous, cinematic\nAfrican gospel, Soukous, upbeat\nAfrican gospel, chiptune, video game music\nAfrican gospel, electronic\nAfrican gospel, funk, afrobeat\nAfrican gospel-pop\nAfrican groove\nAfrican hip-hop\nAfrican house\nAfrican jazz\nAfrican math rock\nAfrican percussion\nAfrican pop\nAfrican pop Bossa Nova\nAfrican pop Mbalax\nAfrican pop Soukous\nAfrican pop Zouk\nAfrican pop cumbia\nAfrican pop gospel\nAfrican pop reggae Highlife\nAfrican pop soukous\nAfrican pop, AOR fusion, cinematic\nAfrican pop, Christmas, highlife\nAfrican pop, Highlife\nAfrican pop, Latin, Caribbean\nAfrican pop, Middle Eastern, choral\nAfrican pop, Soukous\nAfrican pop, Soukous, disco\nAfrican pop, Soukous, upbeat\nAfrican pop, Zouk, Soukous\nAfrican pop, ambient, spiritual\nAfrican pop, cinematic ballad\nAfrican pop, cinematic, choral\nAfrican pop, cinematic, orchestral\nAfrican pop, gospel\nAfrican pop, gospel, world music\nAfrican pop, synth-pop\nAfrican pop, synth-pop, worldbeat\nAfrican pop-gospel\nAfrican pop-rock\nAfrican psychedelic funk\nAfrican psychedelic rock\nAfrican reggae\nAfrican rhumba\nAfrican rock\nAfrican rumba\nAfrican rumba gospel\nAfrican rumba salsa\nAfrican rumba soukous\nAfrican rumba, gospel, R&B\nAfrican salsa\nAfrican synth-pop\nAfrican traditional\nAfrican traditional, jazz fusion\nAfrican tribal\nAfrican tribal house hip-hop\nAfrican vocal\nAfrican vocal jazz\nAfrican world music\nAfrican worldbeat\nAfrikaans ballad\nAfrikaans children's music\nAfrikaans children's pop\nAfrikaans country-folk\nAfrikaans country-gospel\nAfrikaans country-pop\nAfrikaans country-rock\nAfrikaans dance-pop\nAfrikaans folk\nAfrikaans folk rock\nAfrikaans folk, polka, ska\nAfrikaans folk-country\nAfrikaans folk-pop\nAfrikaans folk-punk\nAfrikaans folk-rock\nAfrikaans hip hop\nAfrikaans hip-hop\nAfrikaans hip-hop, alternative rock, post-hardcore\nAfrikaans house\nAfrikaans indie rock\nAfrikaans party\nAfrikaans party rock\nAfrikaans pop\nAfrikaans pop boeremusiek\nAfrikaans pop, Eurodance\nAfrikaans pop, Latin pop\nAfrikaans pop, cumbia\nAfrikaans pop, dance-pop\nAfrikaans pop, retro, chiptune\nAfrikaans pop-folk\nAfrikaans pop-rap\nAfrikaans pop-rock\nAfrikaans punk rock\nAfrikaans rock\nAfrikaans rock 'n' roll\nAfro Christmas\nAfro Drill\nAfro Funk\nAfro Gospel\nAfro House\nAfro House Latin House\nAfro House lo-fi\nAfro dance\nAfro drill\nAfro fusion\nAfro gospel\nAfro groove\nAfro house\nAfro pop\nAfro pop Bossa Nova\nAfro pop disco funk\nAfro pop, 80s synth-pop\nAfro pop, 80s synth-pop, Soukous\nAfro pop-rock\nAfro trap\nAfro-Balkan\nAfro-Balkan brass\nAfro-Balkan dance\nAfro-Balkan folk\nAfro-Balkan fusion\nAfro-Balkan, Arabic Mawwal\nAfro-Bossa\nAfro-Brazilian\nAfro-Brazilian MPB\nAfro-Brazilian Samba\nAfro-Brazilian a cappella\nAfro-Brazilian beat\nAfro-Brazilian capoeira\nAfro-Brazilian carnival\nAfro-Brazilian ceremonial\nAfro-Brazilian choral\nAfro-Brazilian choro\nAfro-Brazilian dance\nAfro-Brazilian devotional\nAfro-Brazilian electronic\nAfro-Brazilian folk\nAfro-Brazilian folk rock\nAfro-Brazilian folk-rock\nAfro-Brazilian funk\nAfro-Brazilian funk samba-reggae\nAfro-Brazilian funk samba-rock\nAfro-Brazilian funk-rock\nAfro-Brazilian fusion\nAfro-Brazilian groove\nAfro-Brazilian hip-hop\nAfro-Brazilian jazz\nAfro-Brazilian jazz fusion\nAfro-Brazilian jazz-funk\nAfro-Brazilian percussion\nAfro-Brazilian pop\nAfro-Brazilian pop-rock\nAfro-Brazilian protest\nAfro-Brazilian reggae\nAfro-Brazilian ritual\nAfro-Brazilian rock\nAfro-Brazilian samba\nAfro-Brazilian samba-funk\nAfro-Brazilian samba-reggae\nAfro-Brazilian samba-rock\nAfro-Brazilian spiritual\nAfro-Brazilian spiritual house\nAfro-Brazilian spirituality\nAfro-Brazilian world music\nAfro-Brazilian, Axé, dance\nAfro-Brazilian, Axé, percussion\nAfro-Brazilian, Candomblé, choral\nAfro-Brazilian, Indian classical, Afrobeat\nAfro-Brazilian, MPB, Samba\nAfro-Brazilian, MPB, world music\nAfro-Brazilian, dance, trance\nAfro-Brazilian, deep house, ritual groove\nAfro-Brazilian, lo-fi hip hop\nAfro-Brazilian, percussion, hip hop\nAfro-Brazilian, ritual ambient\nAfro-Brazilian, samba, gypsy-jazz\nAfro-Brazilian, samba, percussion\nAfro-Brazilian, spiritual folk, cinematic\nAfro-Brazilian, spiritual, Arabic\nAfro-Brazilian, tango, soul\nAfro-Caribbean\nAfro-Caribbean R&B\nAfro-Caribbean Zouk\nAfro-Caribbean Zouk R&B\nAfro-Caribbean big band\nAfro-Caribbean children's\nAfro-Caribbean children's music\nAfro-Caribbean dance\nAfro-Caribbean dancehall\nAfro-Caribbean electronic\nAfro-Caribbean folk\nAfro-Caribbean folk-rock\nAfro-Caribbean funk\nAfro-Caribbean funk salsa\nAfro-Caribbean funk, Soukous\nAfro-Caribbean funk-rock\nAfro-Caribbean fusion\nAfro-Caribbean gospel\nAfro-Caribbean groove\nAfro-Caribbean hip hop\nAfro-Caribbean hip-hop\nAfro-Caribbean house\nAfro-Caribbean jazz\nAfro-Caribbean jazz-funk\nAfro-Caribbean pop\nAfro-Caribbean pop-rap\nAfro-Caribbean pop-rock\nAfro-Caribbean protest\nAfro-Caribbean reggae\nAfro-Caribbean rock\nAfro-Caribbean rumba\nAfro-Caribbean salsa\nAfro-Caribbean soul\nAfro-Caribbean spiritual\nAfro-Caribbean trap\nAfro-Caribbean world music\nAfro-Caribbean zouk\nAfro-Caribbean, festive, dance\nAfro-Caribbean, festive, salsa\nAfro-Caribbean, zouk, kompa\nAfro-Celebration\nAfro-Cuban\nAfro-Cuban Christmas\nAfro-Cuban Gospel\nAfro-Cuban boogaloo\nAfro-Cuban cabaret\nAfro-Cuban children's\nAfro-Cuban children's music\nAfro-Cuban cinematic\nAfro-Cuban dance\nAfro-Cuban disco\nAfro-Cuban drum\nAfro-Cuban drum break\nAfro-Cuban drumming\nAfro-Cuban electronic\nAfro-Cuban experimental\nAfro-Cuban folk\nAfro-Cuban folk-rock\nAfro-Cuban folkloric\nAfro-Cuban funk\nAfro-Cuban funk boogaloo\nAfro-Cuban funk rock\nAfro-Cuban funk salsa\nAfro-Cuban funk soul\nAfro-Cuban funk, progressive rock fusion\nAfro-Cuban funk-rock\nAfro-Cuban fusion\nAfro-Cuban gospel\nAfro-Cuban hip hop\nAfro-Cuban hip-hop\nAfro-Cuban house\nAfro-Cuban jazz\nAfro-Cuban jazz funk\nAfro-Cuban jazz salsa\nAfro-Cuban jazz, Afro-funk\nAfro-Cuban jazz, Arabic music\nAfro-Cuban jazz-funk\nAfro-Cuban jazz-rock\nAfro-Cuban mambo\nAfro-Cuban percussion\nAfro-Cuban pop\nAfro-Cuban pop-rock\nAfro-Cuban protest\nAfro-Cuban reggaeton\nAfro-Cuban rock\nAfro-Cuban rumba\nAfro-Cuban salsa\nAfro-Cuban salsa funk\nAfro-Cuban salsa, Turkish pop\nAfro-Cuban salsa, hard rock\nAfro-Cuban samba\nAfro-Cuban son\nAfro-Cuban son montuno\nAfro-Cuban soul\nAfro-Cuban soul, trip-hop\nAfro-Cuban spiritual\nAfro-Cuban trance\nAfro-Cuban tumba\nAfro-Cuban tumbao\nAfro-Cuban, Andean, World Fusion\nAfro-Cuban, Latin, acoustic\nAfro-Cuban, Latin, world music\nAfro-Cuban, chanson, vocal harmony\nAfro-Cumbia\nAfro-Drill\nAfro-Drill Amapiano\nAfro-Drill hip-hop\nAfro-Drill lo-fi\nAfro-Drill, Latin, Nigerian Pidgin\nAfro-Drill, Pop-Culture\nAfro-Drill, cinematic\nAfro-Drill, lo-fi hip hop\nAfro-Flamenco Fusion\nAfro-French fusion\nAfro-French pop\nAfro-Hip Hop\nAfro-Jamaican fusion\nAfro-Latin\nAfro-Latin Bossa Nova\nAfro-Latin R&B\nAfro-Latin ambient\nAfro-Latin breakbeat\nAfro-Latin chant\nAfro-Latin chill\nAfro-Latin chiptune\nAfro-Latin choral\nAfro-Latin cinematic\nAfro-Latin club\nAfro-Latin cumbia\nAfro-Latin dance\nAfro-Latin dance-pop\nAfro-Latin dancehall\nAfro-Latin deep house\nAfro-Latin disco funk\nAfro-Latin electronic\nAfro-Latin flamenco\nAfro-Latin folk\nAfro-Latin folk-pop\nAfro-Latin folk-rock\nAfro-Latin funk\nAfro-Latin funk gospel\nAfro-Latin funk, gospel\nAfro-Latin funk-rock\nAfro-Latin fusion\nAfro-Latin gospel\nAfro-Latin groove\nAfro-Latin hip hop\nAfro-Latin hip-hop\nAfro-Latin house\nAfro-Latin jazz\nAfro-Latin jazz-funk\nAfro-Latin lounge\nAfro-Latin minimal\nAfro-Latin minimalism\nAfro-Latin percussion\nAfro-Latin pop\nAfro-Latin pop-rock\nAfro-Latin protest\nAfro-Latin reggaeton\nAfro-Latin rock\nAfro-Latin salsa\nAfro-Latin samba\nAfro-Latin soul\nAfro-Latin spiritual\nAfro-Latin tech house\nAfro-Latin tech-house\nAfro-Latin techno\nAfro-Latin trap\nAfro-Latin world music\nAfro-Latin, Anatolian rock\nAfro-Latin, Crossover, World Fusion\nAfro-Latin, R&B, C-pop\nAfro-Latin, chiptune, instrumental\nAfro-Latin, choral, world fusion\nAfro-Latin, cinematic, gospel\nAfro-Latin, cinematic, orchestral\nAfro-Latin, cinematic, revolutionary\nAfro-Latin, downtempo, lounge\nAfro-Latin, electronic, dance\nAfro-Latin, electronic, experimental\nAfro-Latin, festive, dance\nAfro-Latin, flamenco, blues\nAfro-Latin, flamenco, choral\nAfro-Latin, flamenco, dance\nAfro-Latin, flamenco, world music\nAfro-Latin, instrumental, electronic\nAfro-Latin, psychedelic funk, worldbeat\nAfro-Latin, traditional, soulful\nAfro-Latin, trance, world music\nAfro-Latin, world music\nAfro-Latin, world music, South African folk\nAfro-Latin, worldbeat, flamenco\nAfro-Latin, worldbeat, flamenco fusion\nAfro-Latin, worldbeat, folk\nAfro-Latin, worldbeat, funk\nAfro-Lusophone\nAfro-Lusophone folk\nAfro-Lusophone hip hop\nAfro-Lusophone hip-hop\nAfro-Lusophone pop\nAfro-R&B\nAfro-R&B chillwave\nAfro-R&B lo-fi hip hop\nAfro-R&B lo-fi hip-hop\nAfro-R&B trap-soul\nAfro-Reggaeton\nAfro-Rumba\nAfro-Trap\nAfro-Trap chiptune\nAfro-Trap, Jazzy Hip Hop\nAfro-accordion\nAfro-choral\nAfro-dance\nAfro-dance 80s\nAfro-dancehall\nAfro-dancehall funk\nAfro-dancehall trap\nAfro-disco\nAfro-disco funk\nAfro-electronic\nAfro-folk\nAfro-folk country\nAfro-folk dance\nAfro-folk pop\nAfro-funk\nAfro-funk Latin soul\nAfro-funk R&B\nAfro-funk disco\nAfro-funk house\nAfro-funk neo-soul\nAfro-funk pop\nAfro-funk reggae\nAfro-funk rock\nAfro-funk salsa\nAfro-funk soul\nAfro-funk, Gospel\nAfro-funk, R&B, Brazilian funk\nAfro-fusion\nAfro-fusion Amapiano\nAfro-fusion Middle Eastern\nAfro-fusion R&B\nAfro-fusion R&B trap\nAfro-fusion ballad\nAfro-fusion chill\nAfro-fusion chill R&B\nAfro-fusion chill trap\nAfro-fusion chillwave\nAfro-fusion cinematic\nAfro-fusion cloud rap\nAfro-fusion dancehall\nAfro-fusion dancehall lo-fi\nAfro-fusion deep house\nAfro-fusion funk\nAfro-fusion hip-hop\nAfro-fusion jazz\nAfro-fusion lo-fi\nAfro-fusion lo-fi hip hop\nAfro-fusion lo-fi hip-hop\nAfro-fusion lounge\nAfro-fusion neo-soul\nAfro-fusion pop\nAfro-fusion soul\nAfro-fusion trap\nAfro-fusion trap R&B\nAfro-fusion trap-soul\nAfro-fusion tropical\nAfro-fusion, German hyper-rap\nAfro-fusion, Middle Eastern, soul\nAfro-fusion, UK drill\nAfro-fusion, UK drill, cinematic soul\nAfro-fusion, UK drill, lo-fi\nAfro-fusion, future bass, trap\nAfro-fusion, hip hop\nAfro-fusion, hip-hop, R&B\nAfro-futurism, trap, ambient\nAfro-futuristic hip-hop\nAfro-gospel\nAfro-gospel Afrobeats\nAfro-gospel dancehall\nAfro-gospel funk\nAfro-gospel hip-hop\nAfro-gospel pop\nAfro-gospel reggae\nAfro-gospel rock\nAfro-gospel salsa\nAfro-gospel synth-pop\nAfro-gospel trap\nAfro-hip hop\nAfro-hip-hop\nAfro-house\nAfro-house Amapiano\nAfro-house ambient\nAfro-house chiptune\nAfro-house cinematic\nAfro-house dancehall\nAfro-house deep house\nAfro-house lo-fi\nAfro-house tech-house\nAfro-house worldbeat\nAfro-house, Latin house\nAfro-house, Latin house, deep house\nAfro-house, big room house\nAfro-house, dancehall, house\nAfro-house, deep house, spiritual\nAfro-house, gospel house\nAfro-house, minimal tech-house\nAfro-jazz\nAfro-jazz fusion\nAfro-pop\nAfro-pop 80s\nAfro-pop Amapiano\nAfro-pop Anatolian rock\nAfro-pop Bossa Nova\nAfro-pop Bossa Nova Samba\nAfro-pop Cumbia\nAfro-pop French\nAfro-pop Highlife\nAfro-pop Kizomba\nAfro-pop Latin\nAfro-pop Latin groove\nAfro-pop Latin jazz\nAfro-pop Latin worldbeat\nAfro-pop Mbalax\nAfro-pop R&B\nAfro-pop Zouk\nAfro-pop Zouk Soukous\nAfro-pop children's music\nAfro-pop chiptune\nAfro-pop cinematic\nAfro-pop dance\nAfro-pop dance-pop\nAfro-pop dancehall\nAfro-pop digital reggae\nAfro-pop experimental\nAfro-pop funk\nAfro-pop funk jazz fusion\nAfro-pop funk reggae\nAfro-pop funk soul\nAfro-pop funk-rock\nAfro-pop fusion\nAfro-pop gospel\nAfro-pop gospel jazz\nAfro-pop gospel reggae\nAfro-pop gospel rock\nAfro-pop gospel world music\nAfro-pop jazz Bossa Nova\nAfro-pop neo-soul\nAfro-pop reggae\nAfro-pop reggae Highlife\nAfro-pop reggae North African\nAfro-pop reggae dancehall\nAfro-pop reggae gospel\nAfro-pop reggae soul\nAfro-pop reggae world music\nAfro-pop reggae worldbeat\nAfro-pop reggaeton\nAfro-pop retro\nAfro-pop rock\nAfro-pop smooth jazz\nAfro-pop soul\nAfro-pop trap\nAfro-pop tropical\nAfro-pop world music\nAfro-pop worldbeat\nAfro-pop, 90s house\nAfro-pop, Highlife\nAfro-pop, Kizomba\nAfro-pop, Latin, Cumbia\nAfro-pop, Raï, electronic\nAfro-pop, Soukous, worldbeat\nAfro-pop, Zouk, Soukous\nAfro-pop, big band, cinematic orchestral\nAfro-pop, cinematic, traditional Arabic\nAfro-pop, conscious hip-hop, Kizomba\nAfro-pop, dream pop\nAfro-pop, electronic, world music\nAfro-pop, ney flute, world fusion\nAfro-pop, reggae, worldbeat\nAfro-pop, soulful house\nAfro-pop, synth-funk\nAfro-pop, synth-pop\nAfro-pop, traditional soul\nAfro-pop, worldbeat, synth-pop\nAfro-rap\nAfro-reggae\nAfro-reggae dancehall\nAfro-reggae pop\nAfro-reggae soul\nAfro-reggaeton\nAfro-reggaeton chiptune\nAfro-rock\nAfro-soukous\nAfro-soul\nAfro-soul Afrobeat\nAfro-soul dream pop\nAfro-soul funk\nAfro-soul gospel\nAfro-soul hip-hop\nAfro-soul lo-fi hip-hop\nAfro-soul trap\nAfro-soul world music\nAfro-swing\nAfro-swing Latin\nAfro-tech\nAfro-trap\nAfro-trap Dutch\nAfro-trap French\nAfro-trap French drill\nAfro-trap French rap\nAfro-trap Latin pop\nAfro-trap Latin trap\nAfro-trap R&B\nAfro-trap chiptune\nAfro-trap cinematic\nAfro-trap cloud rap\nAfro-trap lo-fi\nAfro-trap lo-fi hip hop\nAfro-trap pluggnb\nAfro-trap soul\nAfro-trap vaporwave\nAfro-trap, French cloud rap\nAfro-trap, French hip-hop, gospel\nAfro-trap, French pop-rap\nAfro-trap, French rap, Arabic pop\nAfro-trap, French rap, dancehall\nAfro-trap, French rap, reggaeton\nAfro-trap, chiptune\nAfro-trap, cloud rap\nAfro-trap, melodic hip-hop\nAfrobeat\nAfrobeat 80s\nAfrobeat Amapiano\nAfrobeat Arabic pop\nAfrobeat Brazilian funk\nAfrobeat C-pop\nAfrobeat Christian\nAfrobeat Dancehall\nAfrobeat EDM\nAfrobeat French rap\nAfrobeat German R&B\nAfrobeat Gospel\nAfrobeat Gospel Dancehall\nAfrobeat Gospel Highlife\nAfrobeat Gospel House\nAfrobeat Highlife\nAfrobeat House\nAfrobeat J-hip-hop\nAfrobeat Kizomba\nAfrobeat Kizomba fusion\nAfrobeat Latin\nAfrobeat Latin House\nAfrobeat Latin Trap\nAfrobeat Latin dance\nAfrobeat Latin dancehall\nAfrobeat Latin funk\nAfrobeat Latin fusion\nAfrobeat Latin house\nAfrobeat Latin jazz\nAfrobeat Latin pop\nAfrobeat Latin pop Dutch hip-hop\nAfrobeat Pop\nAfrobeat R&B\nAfrobeat R&B lo-fi hip-hop\nAfrobeat Salsa\nAfrobeat Ska\nAfrobeat Soca\nAfrobeat Soca Zouk\nAfrobeat Soukous\nAfrobeat Zouk\nAfrobeat ambient\nAfrobeat children's\nAfrobeat children's music\nAfrobeat chill\nAfrobeat chillwave\nAfrobeat chiptune\nAfrobeat cinematic\nAfrobeat conscious dancehall\nAfrobeat conscious hip-hop\nAfrobeat dance\nAfrobeat dance-pop\nAfrobeat dancehall\nAfrobeat dancehall hip-hop\nAfrobeat deep house\nAfrobeat disco-funk\nAfrobeat downtempo\nAfrobeat electronic\nAfrobeat experimental\nAfrobeat folk\nAfrobeat free jazz\nAfrobeat free-jazz\nAfrobeat funk\nAfrobeat funk Highlife\nAfrobeat funk R&B\nAfrobeat funk gospel\nAfrobeat funk pop\nAfrobeat funk reggae\nAfrobeat funk rock\nAfrobeat funk soul\nAfrobeat funk world music\nAfrobeat funk worldbeat\nAfrobeat funk-pop\nAfrobeat funk-rock\nAfrobeat fusion\nAfrobeat gospel\nAfrobeat gospel dancehall\nAfrobeat gospel rock\nAfrobeat gospel-pop\nAfrobeat gospel-rock\nAfrobeat hip-hop\nAfrobeat house\nAfrobeat jazz\nAfrobeat jazz fusion\nAfrobeat jazzy\nAfrobeat lo-fi\nAfrobeat lo-fi hip hop\nAfrobeat lo-fi hip-hop\nAfrobeat lounge\nAfrobeat minimal house\nAfrobeat neo-soul\nAfrobeat pop\nAfrobeat pop R&B\nAfrobeat pop, tropical house\nAfrobeat pop-R&B\nAfrobeat pop-rock\nAfrobeat protest\nAfrobeat reggae\nAfrobeat reggae dub\nAfrobeat reggae fusion\nAfrobeat reggaeton\nAfrobeat rock\nAfrobeat soul\nAfrobeat spiritual\nAfrobeat synth-pop\nAfrobeat trap\nAfrobeat tribal house\nAfrobeat tropical\nAfrobeat tropical house\nAfrobeat vaporwave\nAfrobeat world fusion\nAfrobeat world music\nAfrobeat worldbeat\nAfrobeat worship\nAfrobeat, African gospel\nAfrobeat, African pop\nAfrobeat, Arabic pop, synth groove\nAfrobeat, Brazilian funk, electronic dance\nAfrobeat, Brazilian, upbeat\nAfrobeat, Christmas\nAfrobeat, Dancehall\nAfrobeat, Dancehall, North African Pop\nAfrobeat, French ballad\nAfrobeat, French cloud rap, afro-trap\nAfrobeat, French rap, cinematic\nAfrobeat, German pop-rap\nAfrobeat, Gospel, African pop\nAfrobeat, Gospel, South African pop\nAfrobeat, Kizomba, Favela Funk\nAfrobeat, Kizomba, cinematic synth\nAfrobeat, Latin electronic, dance\nAfrobeat, Latin pop, North African pop\nAfrobeat, Latin, Dancehall\nAfrobeat, Middle Eastern, C-pop\nAfrobeat, Moombahton, hardstyle\nAfrobeat, North African folk\nAfrobeat, R&B\nAfrobeat, R&B, electronic dance\nAfrobeat, Rai, Global Pop\nAfrobeat, Rai, pop\nAfrobeat, Raï\nAfrobeat, Soukous, African gospel\nAfrobeat, South African house, dance-pop\nAfrobeat, World Music, Soul\nAfrobeat, ambient, lo-fi hip hop\nAfrobeat, ambient, soul\nAfrobeat, ambient, synth\nAfrobeat, bolero\nAfrobeat, children's music\nAfrobeat, chillhop, lo-fi hip-hop\nAfrobeat, chiptune, dance pop\nAfrobeat, chiptune, gospel\nAfrobeat, cinematic\nAfrobeat, cinematic, Haitian Creole\nAfrobeat, cinematic, ethereal\nAfrobeat, cinematic, gospel\nAfrobeat, cinematic, spiritual\nAfrobeat, cinematic, world fusion\nAfrobeat, conscious hip-hop\nAfrobeat, conscious hip-hop, world music\nAfrobeat, dancehall, minimal electronic\nAfrobeat, dancehall, minimal house\nAfrobeat, electronic\nAfrobeat, electronic dance\nAfrobeat, electronic, dancehall\nAfrobeat, experimental electronic\nAfrobeat, flamenco, C-pop\nAfrobeat, folk fusion\nAfrobeat, funk, hip-hop\nAfrobeat, gospel, African pop\nAfrobeat, gospel, ambient\nAfrobeat, gospel, pop\nAfrobeat, hip hop\nAfrobeat, hip hop, ambient\nAfrobeat, hyperpop, jazz\nAfrobeat, inspirational hip-hop\nAfrobeat, lo-fi hip hop\nAfrobeat, lo-fi orchestral\nAfrobeat, lo-fi pop\nAfrobeat, lo-fi, C-pop\nAfrobeat, lo-fi, ambient\nAfrobeat, neo-soul, R&B\nAfrobeat, pop\nAfrobeat, reggaeton\nAfrobeat, spiritual, ambient\nAfrobeat, synth pop\nAfrobeat, trap, ambient\nAfrobeat, vintage folk, bubblegum\nAfrobeat, world music, conscious folk\nAfrobeat, worldbeat, cinematic\nAfrobeat-pop\nAfrobeats\nAfrobeats Afro-Caribbean\nAfrobeats Afro-funk\nAfrobeats Afro-fusion\nAfrobeats Afro-gospel\nAfrobeats Afro-jazz\nAfrobeats Afro-pop\nAfrobeats Afro-soul\nAfrobeats Afro-trap\nAfrobeats Afropop\nAfrobeats Amapiano\nAfrobeats Amapiano fusion\nAfrobeats Arabic hip-hop\nAfrobeats Arabic pop\nAfrobeats Balkan fusion\nAfrobeats Bhangra fusion\nAfrobeats Bhangra-pop\nAfrobeats Bollywood fusion\nAfrobeats Bollywood pop\nAfrobeats Bongo Flava\nAfrobeats Bongo Flava Arabic\nAfrobeats Bongo Flava Latin\nAfrobeats Bongo Flava Middle Eastern\nAfrobeats Bongo Flava chiptune\nAfrobeats Bossa Nova\nAfrobeats Brazilian funk chiptune\nAfrobeats C-pop\nAfrobeats C-pop R&B\nAfrobeats C-pop fusion\nAfrobeats Caribbean\nAfrobeats Caribbean pop\nAfrobeats Christmas\nAfrobeats Congolese Rumba\nAfrobeats Congolese rumba\nAfrobeats Coupé-Décalé\nAfrobeats Cumbia\nAfrobeats Dancehall\nAfrobeats Dancehall Pop\nAfrobeats Dancehall Zouk\nAfrobeats Desi Pop\nAfrobeats Desi pop\nAfrobeats Dutch hip-hop\nAfrobeats Dutch pop\nAfrobeats EDM\nAfrobeats East African\nAfrobeats Eurodance\nAfrobeats French\nAfrobeats French Caribbean\nAfrobeats French R&B\nAfrobeats French cloud rap\nAfrobeats French dance-pop\nAfrobeats French dancehall\nAfrobeats French hip-hop\nAfrobeats French pop\nAfrobeats French pop North African\nAfrobeats French pop R&B\nAfrobeats French pop Zouk\nAfrobeats French pop dancehall\nAfrobeats French pop gospel\nAfrobeats French pop-R&B\nAfrobeats French pop-rap\nAfrobeats French rap\nAfrobeats French trap\nAfrobeats German\nAfrobeats German R&B\nAfrobeats German pop\nAfrobeats Gospel\nAfrobeats Gospel Afro-pop\nAfrobeats Gospel Afro-soul\nAfrobeats Gospel Afropop\nAfrobeats Gospel Amapiano\nAfrobeats Gospel Dancehall\nAfrobeats Gospel Highlife\nAfrobeats Gospel R&B\nAfrobeats Gospel-pop\nAfrobeats Hausa\nAfrobeats Highlife\nAfrobeats House\nAfrobeats Indipop\nAfrobeats J-R&B\nAfrobeats J-pop\nAfrobeats J-pop fusion\nAfrobeats Javanese pop\nAfrobeats K-pop global pop\nAfrobeats Kizomba\nAfrobeats Kizomba chiptune\nAfrobeats Kizomba fusion\nAfrobeats Kompa\nAfrobeats Kompa Zouk\nAfrobeats Latin\nAfrobeats Latin Pop\nAfrobeats Latin R&B\nAfrobeats Latin funk\nAfrobeats Latin house\nAfrobeats Latin jazz\nAfrobeats Latin pop\nAfrobeats Latin pop dancehall\nAfrobeats Latin trap\nAfrobeats Mandopop\nAfrobeats Mandopop R&B\nAfrobeats Mandopop hyperpop\nAfrobeats Mandopop lo-fi hip-hop\nAfrobeats Mbalax\nAfrobeats Middle Eastern\nAfrobeats North African\nAfrobeats Punjabi Pop\nAfrobeats Punjabi pop\nAfrobeats R&B\nAfrobeats R&B Afropop\nAfrobeats R&B Congolese pop\nAfrobeats R&B Dancehall\nAfrobeats R&B French cloud rap\nAfrobeats R&B French pop\nAfrobeats R&B Gospel\nAfrobeats R&B Highlife\nAfrobeats R&B Kizomba\nAfrobeats R&B Latin\nAfrobeats R&B Mandopop\nAfrobeats R&B Middle Eastern\nAfrobeats R&B North African\nAfrobeats R&B North African pop\nAfrobeats R&B Soukous\nAfrobeats R&B UK rap\nAfrobeats R&B Zouk\nAfrobeats R&B chillwave\nAfrobeats R&B chiptune\nAfrobeats R&B cinematic\nAfrobeats R&B classical\nAfrobeats R&B cloud rap\nAfrobeats R&B dancehall\nAfrobeats R&B dream pop\nAfrobeats R&B flamenco\nAfrobeats R&B fusion\nAfrobeats R&B gospel\nAfrobeats R&B hip-hop\nAfrobeats R&B jazz\nAfrobeats R&B lo-fi\nAfrobeats R&B lo-fi hip-hop\nAfrobeats R&B neo-soul\nAfrobeats R&B pop\nAfrobeats R&B pop-reggae\nAfrobeats R&B reggae fusion\nAfrobeats R&B smooth jazz\nAfrobeats R&B soul\nAfrobeats R&B synth-pop\nAfrobeats R&B trap\nAfrobeats R&B vaporwave\nAfrobeats R&B world music\nAfrobeats Raï\nAfrobeats Russian pop\nAfrobeats Scandinavian R&B\nAfrobeats Soca\nAfrobeats Soukous\nAfrobeats Soukous fusion\nAfrobeats Swedish rap\nAfrobeats Trap\nAfrobeats Turkish fusion\nAfrobeats Turkish pop\nAfrobeats UK drill\nAfrobeats UK rap\nAfrobeats V-Pop fusion\nAfrobeats Zouk\nAfrobeats Zouk Afropop\nAfrobeats Zouk Caribbean\nAfrobeats Zouk French pop\nAfrobeats Zouk Kompa\nAfrobeats Zouk R&B\nAfrobeats Zouk chill\nAfrobeats Zouk fusion\nAfrobeats Zouk pop\nAfrobeats Zouk tropical\nAfrobeats alternative R&B\nAfrobeats ambient\nAfrobeats ambient pop\nAfrobeats ballad\nAfrobeats baroque\nAfrobeats boom-bap\nAfrobeats children's\nAfrobeats children's music\nAfrobeats children's pop\nAfrobeats chill\nAfrobeats chill R&B\nAfrobeats chill trap\nAfrobeats chillwave\nAfrobeats chillwave R&B\nAfrobeats chillwave world music\nAfrobeats chiptune\nAfrobeats chiptune reggae\nAfrobeats chiptune reggaeton\nAfrobeats cinematic\nAfrobeats classical\nAfrobeats classical fusion\nAfrobeats cloud rap\nAfrobeats conscious\nAfrobeats conscious hip-hop\nAfrobeats cumbia\nAfrobeats dance\nAfrobeats dance-pop\nAfrobeats dance-pop house\nAfrobeats dancehall\nAfrobeats dancehall R&B\nAfrobeats dancehall chiptune\nAfrobeats dancehall gospel\nAfrobeats dancehall hip-hop\nAfrobeats dancehall moombahton\nAfrobeats dancehall pop\nAfrobeats dancehall reggae\nAfrobeats dancehall tropical\nAfrobeats dancehall world music\nAfrobeats dancehall worldbeat\nAfrobeats dancehall zouk\nAfrobeats dancehall-pop\nAfrobeats deep house\nAfrobeats deep house R&B\nAfrobeats dream pop\nAfrobeats dreamy\nAfrobeats drill\nAfrobeats electronic\nAfrobeats flamenco fusion\nAfrobeats funk\nAfrobeats funk R&B\nAfrobeats funk dancehall\nAfrobeats fusion\nAfrobeats future bass\nAfrobeats gospel\nAfrobeats gospel Highlife\nAfrobeats gospel R&B\nAfrobeats gospel dancehall\nAfrobeats gospel hip-hop\nAfrobeats gospel rap\nAfrobeats gospel reggae\nAfrobeats gospel world music\nAfrobeats gospel zouk\nAfrobeats hardstyle\nAfrobeats highlife\nAfrobeats hip hop\nAfrobeats hip-hop\nAfrobeats hip-hop R&B\nAfrobeats hip-hop electronic\nAfrobeats hip-hop fusion\nAfrobeats house\nAfrobeats hyperpop\nAfrobeats hyperpop J-pop\nAfrobeats hyperpop dancehall\nAfrobeats hyperpop pluggnb\nAfrobeats indie pop\nAfrobeats indie pop R&B\nAfrobeats island pop\nAfrobeats jazz\nAfrobeats jazzy\nAfrobeats kids\nAfrobeats lo-fi\nAfrobeats lo-fi R&B\nAfrobeats lo-fi hip hop\nAfrobeats lo-fi hip-hop\nAfrobeats lo-fi soul\nAfrobeats lounge\nAfrobeats lullaby\nAfrobeats melancholic\nAfrobeats melodic trap\nAfrobeats militant\nAfrobeats moombahton\nAfrobeats neo-soul\nAfrobeats neo-soul R&B\nAfrobeats pop\nAfrobeats pop R&B\nAfrobeats pop chiptune\nAfrobeats pop dancehall\nAfrobeats pop fusion\nAfrobeats pop gospel\nAfrobeats pop hip-hop\nAfrobeats pop tropical house\nAfrobeats pop worldbeat\nAfrobeats pop, Latin pop\nAfrobeats pop, Latin pop, tropical house\nAfrobeats pop-R&B\nAfrobeats pop-funk\nAfrobeats pop-gospel\nAfrobeats pop-rap\nAfrobeats pop-reggae\nAfrobeats pop-reggaeton\nAfrobeats protest\nAfrobeats reggae\nAfrobeats reggae cumbia\nAfrobeats reggae dancehall\nAfrobeats reggae fusion\nAfrobeats reggae gospel\nAfrobeats reggaeton\nAfrobeats reggaeton dancehall\nAfrobeats rock\nAfrobeats romantic\nAfrobeats sad trap\nAfrobeats singer-songwriter\nAfrobeats smooth R&B\nAfrobeats smooth jazz\nAfrobeats soul\nAfrobeats soul pop\nAfrobeats spiritual\nAfrobeats synth-pop\nAfrobeats synth-pop chiptune\nAfrobeats trap\nAfrobeats trap Coupé-Décalé\nAfrobeats trap Middle Eastern\nAfrobeats trap R&B\nAfrobeats trap chiptune\nAfrobeats trap drill\nAfrobeats trap fusion\nAfrobeats trap hip-hop\nAfrobeats trap lo-fi\nAfrobeats trap pop-rap\nAfrobeats trap-soul\nAfrobeats tribal house\nAfrobeats tropical\nAfrobeats tropical house\nAfrobeats tropical pop\nAfrobeats vaporwave\nAfrobeats world fusion\nAfrobeats world music\nAfrobeats worship\nAfrobeats zouk\nAfrobeats, 8-bit, electronic\nAfrobeats, 90s R&B\nAfrobeats, 90s dancehall\nAfrobeats, A cappella, Pop\nAfrobeats, Afro-fusion\nAfrobeats, Afro-gospel\nAfrobeats, Afro-gospel, dancehall\nAfrobeats, Amapiano\nAfrobeats, Amapiano, Dancehall\nAfrobeats, Amapiano, French rap\nAfrobeats, Amapiano, Gospel\nAfrobeats, Amapiano, cinematic\nAfrobeats, Arabic pop, Raï\nAfrobeats, Arabic pop, dance-pop\nAfrobeats, Bollywood, dance-pop\nAfrobeats, Bongo Flava, Dancehall\nAfrobeats, Brazilian pop\nAfrobeats, C-pop\nAfrobeats, C-pop, Middle Eastern\nAfrobeats, C-pop, electronic\nAfrobeats, C-pop, lo-fi hip hop\nAfrobeats, Caribbean Zouk, dancehall\nAfrobeats, Caribbean pop, electronic\nAfrobeats, Caribbean, Zouk\nAfrobeats, Caribbean, dance\nAfrobeats, Caribbean, modern\nAfrobeats, Christian, modern\nAfrobeats, Christian, pop\nAfrobeats, Christmas, C-pop\nAfrobeats, Christmas, romantic\nAfrobeats, Congolese Rumba\nAfrobeats, Congolese Rumba, Soukous\nAfrobeats, Congolese rumba\nAfrobeats, Coupé-Décalé\nAfrobeats, Dancehall\nAfrobeats, Dancehall, Christmas\nAfrobeats, Dancehall, North African pop\nAfrobeats, Dancehall, R&B\nAfrobeats, Dancehall, Trap\nAfrobeats, Danish pop\nAfrobeats, Eastern European pop\nAfrobeats, Eastern European, lo-fi\nAfrobeats, French R&B\nAfrobeats, French cloud rap\nAfrobeats, French pop, R&B\nAfrobeats, French pop, chiptune\nAfrobeats, French pop, dancehall\nAfrobeats, French pop, tropical\nAfrobeats, French pop, tropical house\nAfrobeats, French pop-rap\nAfrobeats, French pop-rap, vaporwave\nAfrobeats, French rap\nAfrobeats, French rap, Congolese Rumba\nAfrobeats, French rap, dancehall\nAfrobeats, French rap, electronic\nAfrobeats, French rap, pop\nAfrobeats, German rap\nAfrobeats, Gospel\nAfrobeats, Gospel, Afropop\nAfrobeats, Gospel, Amapiano\nAfrobeats, Gospel, Bongo Flava\nAfrobeats, Gospel, Dancehall\nAfrobeats, Gospel, EDM\nAfrobeats, Gospel, French pop\nAfrobeats, Gospel, Highlife\nAfrobeats, Gospel, R&B\nAfrobeats, Gospel, acoustic ballad\nAfrobeats, Highlife\nAfrobeats, Highlife, Dancehall\nAfrobeats, Highlife, dance\nAfrobeats, Highlife, disco\nAfrobeats, Hindi pop, lo-fi\nAfrobeats, Island Pop\nAfrobeats, Italo-disco, synth-pop\nAfrobeats, Jokingo\nAfrobeats, Kizomba\nAfrobeats, Kizomba, Dancehall\nAfrobeats, Kizomba, pop-R&B\nAfrobeats, Latin hip hop\nAfrobeats, Latin house\nAfrobeats, Latin pop\nAfrobeats, Latin, Gospel\nAfrobeats, Latin, dream pop\nAfrobeats, Latin-pop\nAfrobeats, Malay pop\nAfrobeats, Mandarin rap\nAfrobeats, Middle Eastern\nAfrobeats, Middle Eastern fusion\nAfrobeats, Middle Eastern pop, dance-pop\nAfrobeats, Middle Eastern, Turkish\nAfrobeats, Middle Eastern, cinematic\nAfrobeats, Middle Eastern, dance\nAfrobeats, Middle Eastern, groovy\nAfrobeats, Middle Eastern, modern\nAfrobeats, Middle Eastern, pop\nAfrobeats, Middle Eastern, upbeat\nAfrobeats, Middle Eastern, world pop\nAfrobeats, Nigerian Highlife\nAfrobeats, Nigerian folk, cinematic\nAfrobeats, North African pop\nAfrobeats, North African pop, Raï\nAfrobeats, North African, upbeat\nAfrobeats, R&B\nAfrobeats, R&B, 2000s\nAfrobeats, R&B, Gospel\nAfrobeats, R&B, UK hip hop\nAfrobeats, R&B, chillwave\nAfrobeats, R&B, cinematic\nAfrobeats, R&B, dance\nAfrobeats, R&B, dream pop\nAfrobeats, R&B, hip-hop\nAfrobeats, R&B, pop\nAfrobeats, R&B, trap\nAfrobeats, R&B, trap soul\nAfrobeats, Rai, North African pop\nAfrobeats, Rai, dance-pop\nAfrobeats, Raï\nAfrobeats, Raï, North African\nAfrobeats, Raï, North African pop\nAfrobeats, Scandinavian\nAfrobeats, Scandinavian pop\nAfrobeats, Soca, Zouk\nAfrobeats, Soukous\nAfrobeats, Soukous, Amapiano\nAfrobeats, Soukous, Christmas\nAfrobeats, Soukous, French gospel\nAfrobeats, Soukous, cinematic\nAfrobeats, South African\nAfrobeats, South African house\nAfrobeats, South African house, a capella\nAfrobeats, South African house, gospel\nAfrobeats, South Asian fusion\nAfrobeats, South Asian pop\nAfrobeats, Southeast Asian fusion\nAfrobeats, Swedish hip-hop\nAfrobeats, Tamil pop, cinematic\nAfrobeats, Turkish R&B\nAfrobeats, Turkish, Middle Eastern\nAfrobeats, UK drill\nAfrobeats, UK drill, lo-fi hip hop\nAfrobeats, Zouk\nAfrobeats, Zouk, Caribbean\nAfrobeats, Zouk, Dancehall\nAfrobeats, Zouk, French pop\nAfrobeats, Zouk, Kizomba\nAfrobeats, Zouk, Kompa\nAfrobeats, Zouk, Latin pop\nAfrobeats, Zouk, R&B\nAfrobeats, Zouk, Soca\nAfrobeats, Zouk, Soukous\nAfrobeats, Zouk, chiptune\nAfrobeats, Zouk, cinematic pop\nAfrobeats, Zouk, dancehall\nAfrobeats, Zouk, emotional pop\nAfrobeats, Zouk, tropical\nAfrobeats, ambient R&B\nAfrobeats, ambient pop\nAfrobeats, ambient, cinematic\nAfrobeats, ambient, dream pop\nAfrobeats, ambient, lo-fi\nAfrobeats, ambient, melancholic\nAfrobeats, ambient, soul\nAfrobeats, ambient, spiritual\nAfrobeats, boom-bap hip-hop\nAfrobeats, brass, hip hop\nAfrobeats, breakcore\nAfrobeats, chill, hyperpop\nAfrobeats, chiptune\nAfrobeats, chiptune, French pop-rap\nAfrobeats, chiptune, Highlife\nAfrobeats, chiptune, R&B\nAfrobeats, chiptune, breakbeat\nAfrobeats, chiptune, electronic\nAfrobeats, chiptune, hip-hop\nAfrobeats, chiptune, modern\nAfrobeats, chiptune, soul\nAfrobeats, chiptune, trap\nAfrobeats, cinematic\nAfrobeats, cinematic hip-hop\nAfrobeats, cinematic soul\nAfrobeats, cinematic, French pop\nAfrobeats, cinematic, French rap\nAfrobeats, cinematic, Mandarin hip hop\nAfrobeats, cinematic, Middle Eastern\nAfrobeats, cinematic, R&B\nAfrobeats, cinematic, emotional\nAfrobeats, cinematic, ethereal\nAfrobeats, cinematic, gospel\nAfrobeats, cinematic, hip-hop\nAfrobeats, cinematic, lo-fi\nAfrobeats, cinematic, orchestral\nAfrobeats, cinematic, pop\nAfrobeats, cinematic, triumphant\nAfrobeats, city pop, funk\nAfrobeats, cloud rap\nAfrobeats, conscious hip-hop\nAfrobeats, dance pop\nAfrobeats, dance, electronic\nAfrobeats, dance-pop\nAfrobeats, dancehall, Afro-trap\nAfrobeats, dancehall, Caribbean\nAfrobeats, dancehall, French rap\nAfrobeats, dancehall, chiptune\nAfrobeats, dancehall, hip-hop\nAfrobeats, dancehall, moombahton\nAfrobeats, dancehall, reggaeton\nAfrobeats, desert pop, Middle Eastern fusion\nAfrobeats, doom metal\nAfrobeats, dream pop\nAfrobeats, dream pop, electronic\nAfrobeats, dreamy, atmospheric\nAfrobeats, electronic\nAfrobeats, electronic dance\nAfrobeats, electronic, anthemic\nAfrobeats, electronic, chiptune\nAfrobeats, electronic, dance\nAfrobeats, electronic, hip hop\nAfrobeats, electronic, stadium anthem\nAfrobeats, electronic, world fusion\nAfrobeats, experimental, trap\nAfrobeats, festive\nAfrobeats, future bass\nAfrobeats, futuristic\nAfrobeats, gospel, French pop\nAfrobeats, gospel, R&B\nAfrobeats, gospel, Soukous\nAfrobeats, gospel, chiptune\nAfrobeats, gospel, dancehall\nAfrobeats, gospel, pop\nAfrobeats, gospel, pop-R&B\nAfrobeats, gospel, reggae\nAfrobeats, gospel, spiritual\nAfrobeats, gospel, world music\nAfrobeats, hardstyle\nAfrobeats, hip hop\nAfrobeats, hip-hop\nAfrobeats, hip-hop, North African fusion\nAfrobeats, hip-hop, dancehall\nAfrobeats, hyperpop\nAfrobeats, inspirational hip-hop\nAfrobeats, inspirational pop\nAfrobeats, jazz fusion, gospel\nAfrobeats, jazz hip-hop\nAfrobeats, jazzy, lo-fi\nAfrobeats, jazzy, modern\nAfrobeats, lo-fi hip hop\nAfrobeats, lo-fi, French pop\nAfrobeats, lo-fi, R&B\nAfrobeats, lo-fi, acoustic pop\nAfrobeats, lo-fi, ambient\nAfrobeats, lo-fi, dream pop\nAfrobeats, lo-fi, inspirational\nAfrobeats, lo-fi, melancholic\nAfrobeats, melancholic\nAfrobeats, melancholic, romantic\nAfrobeats, pop, Middle Eastern\nAfrobeats, pop, North African\nAfrobeats, pop, chiptune\nAfrobeats, pop-R&B, flamenco\nAfrobeats, pop-reggaeton\nAfrobeats, reggae, dancehall\nAfrobeats, reggaeton, Latin\nAfrobeats, reggaeton, tropical pop\nAfrobeats, retro electronic\nAfrobeats, retro synth, South African\nAfrobeats, retro, chiptune\nAfrobeats, retro-futuristic\nAfrobeats, soul, Afro-soul\nAfrobeats, soul, cinematic\nAfrobeats, soul, electronic\nAfrobeats, soul, gospel\nAfrobeats, soul, gospel hip-hop\nAfrobeats, soul, hip-hop\nAfrobeats, soul, lo-fi hip hop\nAfrobeats, soulful R&B\nAfrobeats, synth pop\nAfrobeats, synth-pop\nAfrobeats, synth-pop, 8-bit\nAfrobeats, synth-pop, Highlife\nAfrobeats, synth-pop, R&B\nAfrobeats, synth-pop, chiptune\nAfrobeats, synth-pop, dance-pop\nAfrobeats, synthwave\nAfrobeats, synthwave, electronic\nAfrobeats, synthwave, lo-fi\nAfrobeats, trap R&B\nAfrobeats, trap, French pop\nAfrobeats, trap, R&B\nAfrobeats, trap, cinematic\nAfrobeats, trap, future bass\nAfrobeats, trap, lo-fi\nAfrobeats, trap, marching band\nAfrobeats, trap, modern\nAfrobeats, trap, synthwave\nAfrobeats, trap, world fusion\nAfrobeats, trap, world music\nAfrobeats, tropical house\nAfrobeats, world fusion\nAfrobeats, world music\nAfrobeats, world music, electronic\nAfrobeats, world pop, Mediterranean groove\nAfrobeats, world-pop, chiptune\nAfrobeats, worldbeat, chiptune\nAfrobeats, worldbeat, electronic\nAfrobeats-pop\nAfrobeats-pop future bass\nAfrohouse\nAfrohouse, chiptune\nAfropop\nAfropop 80s\nAfropop Afrobeat\nAfropop Amapiano\nAfropop Bongo Flava\nAfropop Bongo Flava Gospel\nAfropop Bongo Flava smooth jazz\nAfropop Bossa Nova\nAfropop Christmas\nAfropop Congolese Rumba\nAfropop Coupé-Décalé\nAfropop Cumbia\nAfropop French hip-hop\nAfropop French pop\nAfropop French pop-rap\nAfropop Gospel\nAfropop Gospel Highlife\nAfropop Gospel R&B\nAfropop Gospel reggae\nAfropop Highlife\nAfropop Kizomba\nAfropop Latin\nAfropop Latin dance\nAfropop Latin fusion\nAfropop Latin jazz\nAfropop Latin pop\nAfropop Mbalax\nAfropop R&B\nAfropop R&B Congolese rumba\nAfropop R&B Gospel\nAfropop R&B Highlife\nAfropop R&B Soca\nAfropop R&B Zouk\nAfropop R&B chillwave\nAfropop R&B cinematic\nAfropop R&B funk\nAfropop R&B gospel\nAfropop R&B neo-classical\nAfropop R&B reggae\nAfropop Soca\nAfropop Soca worldbeat\nAfropop Soukous\nAfropop Soukous Highlife\nAfropop Zouk\nAfropop Zouk R&B\nAfropop Zouk pop\nAfropop Zouk world music\nAfropop acoustic R&B\nAfropop acoustic soul\nAfropop acoustic world music\nAfropop ballad\nAfropop chiptune\nAfropop chiptune reggae\nAfropop cinematic\nAfropop country-rock\nAfropop cumbia\nAfropop cumbia reggae\nAfropop dance\nAfropop dance-pop\nAfropop dancehall\nAfropop desert blues\nAfropop dream pop\nAfropop electro-pop\nAfropop funk\nAfropop funk R&B\nAfropop funk disco\nAfropop funk gospel\nAfropop gospel\nAfropop gospel dancehall\nAfropop gospel reggae\nAfropop gospel soukous\nAfropop gospel world music\nAfropop highlife\nAfropop hip-hop\nAfropop lo-fi\nAfropop reggae\nAfropop reggae dancehall\nAfropop reggae fusion\nAfropop reggae soukous\nAfropop reggaeton\nAfropop retro\nAfropop salsa\nAfropop smooth jazz\nAfropop soukous\nAfropop soul\nAfropop synth-pop\nAfropop tropical\nAfropop tropical house\nAfropop world music\nAfropop worldbeat\nAfropop, 90s R&B\nAfropop, 90s digital reggae\nAfropop, African House\nAfropop, Arabic, worldbeat\nAfropop, Bongo Flava, Gospel\nAfropop, Bongo Flava, Latin\nAfropop, Caribbean dance\nAfropop, Caribbean, Christmas\nAfropop, Caribbean, upbeat\nAfropop, Congolese Rumba\nAfropop, Congolese rumba, soukous\nAfropop, EDM\nAfropop, French pop, synthwave\nAfropop, Gospel, Afrobeat\nAfropop, Gospel, Amapiano\nAfropop, Gospel, Bongo Flava\nAfropop, Gospel, Highlife\nAfropop, Gospel, R&B\nAfropop, Gospel, Soca\nAfropop, Gospel, Zouk\nAfropop, Gospel, ambient\nAfropop, Gospel, reggae\nAfropop, Gospel, smooth jazz\nAfropop, Highlife\nAfropop, Highlife, Soca\nAfropop, Highlife, dance\nAfropop, Highlife, hip-hop\nAfropop, Highlife, synth funk\nAfropop, Highlife, vintage\nAfropop, Italo-disco, Eurodance\nAfropop, Italo-disco, chiptune\nAfropop, Italo-disco, early house\nAfropop, Kizomba\nAfropop, Kizomba, Soukous\nAfropop, Kizomba, Zouk\nAfropop, Latin pop\nAfropop, Latin, Dancehall\nAfropop, Latin, world-pop\nAfropop, Middle Eastern fusion\nAfropop, Middle Eastern, dance\nAfropop, Middle Eastern, electronic\nAfropop, Middle Eastern, pop\nAfropop, Oud, World Fusion\nAfropop, Raï\nAfropop, Raï, desert blues\nAfropop, Raï, electronic\nAfropop, Soukous\nAfropop, Soukous, Rumba\nAfropop, Soukous, Zouk\nAfropop, Soukous, dance\nAfropop, Soukous, highlife\nAfropop, Soukous, lo-fi\nAfropop, Soukous, political\nAfropop, Soukous, upbeat\nAfropop, South African house\nAfropop, Zouk, Caribbean\nAfropop, Zouk, Kizomba\nAfropop, Zouk, Kompa\nAfropop, Zouk, R&B\nAfropop, Zouk, Soukous\nAfropop, Zouk, cinematic\nAfropop, Zouk, dancehall\nAfropop, Zouk, funk\nAfropop, Zouk, pop\nAfropop, ambient\nAfropop, ambient, spiritual\nAfropop, chiptune\nAfropop, chiptune, dance\nAfropop, chiptune, electronic\nAfropop, chiptune, retro\nAfropop, choral, cinematic\nAfropop, cinematic, Arabic soul\nAfropop, cinematic, French spoken word\nAfropop, cinematic, brass\nAfropop, cinematic, spiritual\nAfropop, cinematic, synth\nAfropop, corporate anthem, electronic\nAfropop, dance-pop\nAfropop, digital cumbia\nAfropop, digital cumbia, worldbeat\nAfropop, early 2000s house\nAfropop, early house\nAfropop, electronic, choral\nAfropop, gospel\nAfropop, gospel, Congolese rumba\nAfropop, gospel, Highlife\nAfropop, gospel, Soukous\nAfropop, gospel, chiptune\nAfropop, gospel, cinematic\nAfropop, gospel, electronic\nAfropop, gospel, reggae\nAfropop, gospel, smooth jazz\nAfropop, gospel, synth-pop\nAfropop, gospel, world music\nAfropop, gospel, zouk\nAfropop, hardstyle\nAfropop, hip-hop, gospel\nAfropop, reggaeton, dancehall\nAfropop, retro, chiptune\nAfropop, retro, house\nAfropop, retro, synth pop\nAfropop, retro, synth-pop\nAfropop, sacred fusion\nAfropop, salsa, soukous\nAfropop, spiritual, Mawwal\nAfropop, spiritual, choral\nAfropop, spiritual, gospel\nAfropop, synth pop\nAfropop, synth-funk, retro\nAfropop, synth-pop\nAfropop, synth-pop, retro\nAfropop, synth-pop, worldbeat\nAfropop, vintage French pop\nAfropop, world music, gospel\nAfropop, world music, pop\nAfropop, world pop\nAfropop, worldbeat, Kizomba\nAfropop, worldbeat, choral\nAfropop, worldbeat, gospel\nAfropop, worldbeat, retro\nAfropop, zouk, inspirational\nAfroswing\nAmapiano\nAmapiano Afro House\nAmapiano Afro-Latin\nAmapiano Afro-fusion\nAmapiano Afrobeat\nAmapiano Afrobeats\nAmapiano Afrobeats R&B\nAmapiano Afrobeats hip-hop\nAmapiano Dancehall\nAmapiano Kuduro\nAmapiano Punjabi pop\nAmapiano gospel\nAmapiano hip-hop\nAmapiano house\nAmapiano hyperpop\nAmapiano trap\nAmapiano, Afro-Latin\nAmapiano, Afrobeat, hip-hop\nAmapiano, Bollywood dance-pop\nAmapiano, Isicathamiya\nAmapiano, Kuduro, hip-hop\nAmapiano, Soukous\nAmapiano, ambient, electronic\nAmapiano, cinematic\nAmapiano, deep house, hip-hop\nAmapiano, hip hop\nAmapiano, hip-hop, Afro-pop\nAmbient\nAmbient Chinese\nAmbient East Asian\nAmbient Guzheng\nAmbient guzheng\nAmbient, Traditional Chinese, Meditative\nAmerican Primitivism\nAmerican folk\nAmerican folk blues\nAmerican folk gospel\nAmerican folk novelty\nAmerican folk spiritual\nAmerican folk, bluegrass\nAmerican folk, blues\nAmerican folk, gospel, brass band\nAmerican folk-blues\nAmerican folk-gospel\nAmerican gospel\nAmerican march\nAmerican primitive\nAmerican roots\nAmerican spiritual\nAmericana\nAmericana Christmas\nAmericana Latin\nAmericana Latin folk\nAmericana Tex-Mex\nAmericana alt-country\nAmericana alt-rock\nAmericana alternative rock\nAmericana ballad\nAmericana bluegrass\nAmericana bluegrass gospel\nAmericana blues\nAmericana blues country-rock\nAmericana blues country-western\nAmericana blues jazz\nAmericana blues lounge jazz\nAmericana blues rock\nAmericana blues roots rock\nAmericana blues-folk\nAmericana blues-jazz\nAmericana blues-rock\nAmericana country\nAmericana country blues\nAmericana country rock\nAmericana country-blues\nAmericana country-folk\nAmericana country-funk\nAmericana country-gospel\nAmericana country-rock\nAmericana country-rock blues\nAmericana desert rock\nAmericana folk\nAmericana folk rock\nAmericana folk, Southern rock\nAmericana folk, hard rock\nAmericana folk, southern rock\nAmericana folk-country\nAmericana folk-jazz\nAmericana folk-pop\nAmericana folk-rock\nAmericana fusion\nAmericana gospel\nAmericana gospel blues\nAmericana gospel folk\nAmericana gypsy jazz\nAmericana heartland rock\nAmericana hip hop\nAmericana hip-hop\nAmericana indie rock\nAmericana jazz\nAmericana jazz lounge\nAmericana lo-fi\nAmericana lounge jazz\nAmericana noir lounge jazz\nAmericana noir-folk\nAmericana noir-western\nAmericana post-rock\nAmericana protest\nAmericana psychedelic folk-rock\nAmericana psychedelic rock\nAmericana rock\nAmericana rockabilly\nAmericana roots rock\nAmericana roots-funk\nAmericana roots-rock\nAmericana satire\nAmericana singer-songwriter\nAmericana soul\nAmericana surf rock\nAmericana swamp folk\nAmericana swamp rock\nAmericana trap\nAmericana world music\nAmericana, California rock\nAmericana, Dixieland, brass\nAmericana, European folk\nAmericana, Indian classical\nAmericana, Latin folk\nAmericana, New Orleans jazz\nAmericana, Quebecois folk\nAmericana, Southern Rock\nAmericana, Southern rock\nAmericana, Southern rock, bluegrass\nAmericana, Southern rock, blues\nAmericana, Southern rock, blues-rock\nAmericana, Southern rock, folk-rock\nAmericana, Southern rock, instrumental\nAmericana, Southern rock, soulful\nAmericana, Southern rock, swamp rock\nAmericana, Western Gothic\nAmericana, Western Swing\nAmericana, Western swing, country-western\nAmericana, alt-country\nAmericana, alt-country, blues rock\nAmericana, alt-country, cinematic\nAmericana, alt-country, classic rock\nAmericana, alt-country, folk\nAmericana, alt-country, folk rock\nAmericana, alt-country, folk-rock\nAmericana, alt-country, heartland rock\nAmericana, alt-country, melancholic\nAmericana, alt-country, raw live\nAmericana, alt-country, rock\nAmericana, alt-rock\nAmericana, bluegrass\nAmericana, bluegrass, country\nAmericana, bluegrass, country rock\nAmericana, bluegrass, country-folk\nAmericana, bluegrass, country-funk\nAmericana, bluegrass, country-rock\nAmericana, bluegrass, country-western\nAmericana, bluegrass, folk\nAmericana, bluegrass, folk-punk\nAmericana, bluegrass, lo-fi\nAmericana, bluegrass, roots rock\nAmericana, bluegrass, roots-rock\nAmericana, blues, country-rock\nAmericana, chamber pop\nAmericana, cinematic, folk\nAmericana, classic rock\nAmericana, country\nAmericana, country blues\nAmericana, country blues, roots rock\nAmericana, country rock, desert folk\nAmericana, country rock, psychedelic rock\nAmericana, country swing\nAmericana, country, ambient\nAmericana, country, bluegrass\nAmericana, country, blues\nAmericana, country, blues-rock\nAmericana, country, folk-rock\nAmericana, country, roots-rock\nAmericana, country, western swing\nAmericana, country-blues\nAmericana, country-folk\nAmericana, country-folk, Southern rock\nAmericana, country-folk, Western swing\nAmericana, country-folk, heartland rock\nAmericana, country-folk, rockabilly\nAmericana, country-folk, roots-rock\nAmericana, country-folk, skiffle\nAmericana, country-folk, western swing\nAmericana, country-funk\nAmericana, country-gospel\nAmericana, country-rock\nAmericana, country-rock, blues rock\nAmericana, country-rock, cinematic\nAmericana, country-rock, heartland rock\nAmericana, country-rock, roots-rock\nAmericana, country-western\nAmericana, country-western, cinematic\nAmericana, country-western, melancholic\nAmericana, folk, Spanish guitar\nAmericana, folk-rock, gritty\nAmericana, folk-rock, roots-rock\nAmericana, gospel, bluegrass\nAmericana, gospel, country\nAmericana, gospel, country-rock\nAmericana, gospel, folk\nAmericana, gothic country\nAmericana, gypsy-folk, bluegrass\nAmericana, heartland rock\nAmericana, heartland rock, blues-rock\nAmericana, heartland rock, country-folk\nAmericana, heartland rock, country-rock\nAmericana, heartland rock, folk-rock\nAmericana, heartland rock, synth folk\nAmericana, honky-tonk, country-folk\nAmericana, newgrass\nAmericana, noir-folk\nAmericana, outlaw country\nAmericana, outlaw country, roots rock\nAmericana, post-rock\nAmericana, progressive rock\nAmericana, psychedelic folk-rock\nAmericana, psychedelic rock\nAmericana, roots rock\nAmericana, roots rock, folk punk\nAmericana, roots-rock, folk-punk\nAmericana, roots-rock, upbeat\nAmericana, singer-songwriter, folk\nAmericana, southern rock\nAmericana, southern rock, blues\nAmericana, southern rock, blues rock\nAmericana, southern rock, blues-rock\nAmericana, southern rock, country-folk\nAmericana, southern rock, country-rock\nAmericana, southern rock, gritty\nAmericana, swamp folk\nAmericana, swamp rock, shoegaze\nAmericana, western swing, blues\nAmericana, western swing, upbeat\nAmericana-noir alt-rock\nAmericana-rock\nAmericana-trap\nAnasheed\nAnatolian Sufi\nAnatolian ballad\nAnatolian choral\nAnatolian folk\nAnatolian folk chiptune\nAnatolian folk electronic rock\nAnatolian folk flamenco\nAnatolian folk funk-rock\nAnatolian folk fusion\nAnatolian folk hip-hop\nAnatolian folk jazz\nAnatolian folk metal\nAnatolian folk pop\nAnatolian folk protest\nAnatolian folk rock\nAnatolian folk trap\nAnatolian folk, Sufi chanting\nAnatolian folk, Sufi music\nAnatolian folk, Turkish pop\nAnatolian folk, cinematic folk-rock\nAnatolian folk, cinematic fusion\nAnatolian folk, cinematic orchestral\nAnatolian folk, cinematic rock\nAnatolian folk, cinematic trap\nAnatolian folk, cinematic, lo-fi\nAnatolian folk, cinematic, melancholic\nAnatolian folk, cinematic, world music\nAnatolian folk, downtempo hip-hop\nAnatolian folk, electronic dance, choral\nAnatolian folk, electronic pop, dance\nAnatolian folk, electronic, cinematic\nAnatolian folk, electronic, melancholic\nAnatolian folk, psychedelic folk\nAnatolian folk, psychedelic rock\nAnatolian folk, trap\nAnatolian folk, world music, cinematic\nAnatolian folk-funk\nAnatolian folk-pop\nAnatolian folk-rock\nAnatolian funk\nAnatolian funk rock\nAnatolian funk-rock\nAnatolian fusion\nAnatolian hard rock\nAnatolian hip hop\nAnatolian hip-hop\nAnatolian hip-hop, Middle Eastern funk\nAnatolian metal\nAnatolian music\nAnatolian pop\nAnatolian pop rock\nAnatolian pop-rock\nAnatolian protest\nAnatolian psychedelic rock\nAnatolian rock\nAnatolian rock Balkan brass\nAnatolian rock Balkan folk\nAnatolian rock big band\nAnatolian rock cabaret\nAnatolian rock chiptune\nAnatolian rock disco-funk\nAnatolian rock flamenco\nAnatolian rock folk\nAnatolian rock folk metal\nAnatolian rock funk\nAnatolian rock funk-rock\nAnatolian rock hard rock\nAnatolian rock hip-hop\nAnatolian rock industrial metal\nAnatolian rock jazz-funk\nAnatolian rock metal\nAnatolian rock nu-metal\nAnatolian rock power metal\nAnatolian rock progressive\nAnatolian rock progressive metal\nAnatolian rock progressive rock\nAnatolian rock psychedelic blues\nAnatolian rock psychedelic folk\nAnatolian rock psychedelic funk\nAnatolian rock psychedelic metal\nAnatolian rock psychedelic rock\nAnatolian rock revolutionary folk\nAnatolian rock speed metal\nAnatolian rock surf metal\nAnatolian rock surf rock\nAnatolian rock synth-pop\nAnatolian rock tango\nAnatolian rock tango fusion\nAnatolian rock trip-hop\nAnatolian rock world music\nAnatolian rock worldbeat\nAnatolian rock, 80s new wave\nAnatolian rock, Balkan brass\nAnatolian rock, Middle Eastern folk\nAnatolian rock, Middle Eastern folk, progressive metal\nAnatolian rock, Middle Eastern fusion\nAnatolian rock, Sufi music\nAnatolian rock, Turkish folk\nAnatolian rock, Turkish folk, cinematic\nAnatolian rock, Turkish pop\nAnatolian rock, big band jazz\nAnatolian rock, big band jazz fusion\nAnatolian rock, electronic\nAnatolian rock, electronic dance\nAnatolian rock, electronic dance music\nAnatolian rock, electronic dance, cinematic\nAnatolian rock, folk rock\nAnatolian rock, gypsy punk, folk rock\nAnatolian rock, hard rock\nAnatolian rock, heavy metal\nAnatolian rock, industrial metal, cinematic\nAnatolian rock, jazz fusion, big band\nAnatolian rock, psychedelic electronic\nAnatolian rock, psychedelic folk\nAnatolian rock, psychedelic funk\nAnatolian rock, psychedelic metal\nAnatolian rock, psychedelic rock\nAnatolian rock, psychedelic surf rock\nAnatolian rock, revolutionary folk\nAnatolian rock, symphonic metal\nAnatolian rock, symphonic metal, folk\nAnatolian rock, synth-pop\nAnatolian rock, synth-pop, chiptune\nAnatolian rock, synth-pop, electronic\nAnatolian rock, trap metal\nAnatolian rock, trap, hip-hop\nAnatolian spiritual\nAnatolian trap\nAncient Style\nAncient Style, C-pop, cinematic\nAncient Style, Chinese Folk, Ambient\nAncient Style, Chinese Opera, Cinematic\nAncient Style, Chinese Opera, Epic\nAncient Style, Ethereal, Chinese Ambient\nAncient Style, Folk, Cinematic\nAncient Style, Industrial, Ambient\nAncient Style, Mongolian Folk, World Music\nAncient Style, Orchestral, C-pop\nAncient Style, ambient, electronic\nAncient Style, ambient, ethereal\nAncient Style, ambient, lo-fi hip hop\nAncient Style, cinematic orchestral, Chinese classical\nAncient Style, cinematic pop, Chinese fusion\nAncient Style, cinematic rock\nAncient Style, cinematic, C-pop\nAncient Style, cinematic, Chinese\nAncient Style, cinematic, Chinese opera\nAncient Style, cinematic, Chinese orchestral\nAncient Style, cinematic, Chinese pop\nAncient Style, cinematic, ambient\nAncient Style, cinematic, ballad\nAncient Style, cinematic, electronic\nAncient Style, cinematic, lo-fi\nAncient Style, cinematic, orchestral\nAncient Style, cinematic, orchestral rock\nAncient Style, cinematic, pop-rock\nAncient Style, cinematic, rock\nAncient Style, orchestral, cinematic\nAncient Style, theatrical, Chinese opera\nAndalusian folk\nAndalusian music\nAndalusian pop\nAndalusian pop-rock\nAndalusian rumba\nAndean Christmas\nAndean Cumbia\nAndean ambient\nAndean carnaval\nAndean carnival\nAndean cumbia\nAndean electronic\nAndean electronic rock\nAndean electronica\nAndean festival\nAndean folk\nAndean folk blues\nAndean folk cumbia\nAndean folk fusion\nAndean folk gospel\nAndean folk hip-hop\nAndean folk pop\nAndean folk protest\nAndean folk rock\nAndean folk surf rock\nAndean folk tango\nAndean folk, Latin rock, Javanese fusion\nAndean folk, Latin worship\nAndean folk, Polish folk-rock\nAndean folk, copla, Latin American folk\nAndean folk, cumbia, protest music\nAndean folk, cumbia, psychedelic folk-rock\nAndean folk, flamenco\nAndean folk, operatic flamenco\nAndean folk, psychedelic rock\nAndean folk-fusion\nAndean folk-pop\nAndean folk-rock\nAndean fusion\nAndean fusion progressive rock\nAndean hip-hop\nAndean merengue\nAndean music\nAndean pop\nAndean pop-rock\nAndean protest\nAndean punk\nAndean rock\nAndean spiritual\nAndean trap\nAngolan Fado\nAngolan Samba\nAngolan Samba City Pop\nAngolan dance\nAngolan folk\nAngolan folk, Brazilian samba\nAngolan folk-pop\nAngolan funk\nAngolan funk carioca hip-hop\nAngolan hip-hop\nAngolan kuduro\nAngolan music\nAngolan pop\nAngolan pop, Kizomba, world music\nAngolan pop-funk\nAngolan pop-rock\nAngolan samba\nAngolan semba\nAngolan traditional\nAppalachian folk\nAppalachian folk, bluegrass\nAppalachian folk, southern rock, country-rock\nAppalachian gospel\nApres-ski Schlager\nArabesque\nArabesque rock\nArabesque, Balkan, Turkish folk\nArabesque, Turkish folk\nArabesque, Turkish folk, cinematic\nArabesque, Turkish folk, world fusion\nArabesque, trap, Anatolian folk\nArabic Afrobeats\nArabic Bossa Nova\nArabic Christian\nArabic Christian chiptune\nArabic Christian folk\nArabic Christian hymn\nArabic Christian music\nArabic Christian pop\nArabic Christian praise\nArabic Christian synth-pop\nArabic Christian worship\nArabic Christian worship chiptune\nArabic Christian, retro synth, chiptune\nArabic Christmas\nArabic Cumbia\nArabic Dabke\nArabic EDM\nArabic EDM progressive house\nArabic EDM-pop\nArabic Eurodance\nArabic J-pop\nArabic Latin fusion\nArabic Latin pop\nArabic Maqam\nArabic Mawwal\nArabic Mawwal, Arabic Folk\nArabic Mawwal, Arabic Folk, Belly Dance\nArabic Mawwal, Belly Dance\nArabic Mawwal, Dabke\nArabic Mawwal, Electronic, Dabke\nArabic Mawwal, Electronic, Dance\nArabic Mawwal, Electronic, World Fusion\nArabic Mawwal, Folk Dance\nArabic Mawwal, Folk Fusion\nArabic Mawwal, Folk Fusion, Dance Pop\nArabic Mawwal, Khaleeji pop\nArabic Mawwal, Khaleeji pop, cinematic\nArabic Mawwal, Middle Eastern Folk\nArabic Mawwal, Middle Eastern fusion\nArabic Mawwal, Modern Arabic Pop\nArabic Mawwal, North African folk\nArabic Mawwal, Pop, World Fusion\nArabic Mawwal, Raï, dance-pop\nArabic Mawwal, World Fusion\nArabic Mawwal, World Fusion, Ambient\nArabic Mawwal, ambient, electronic\nArabic Mawwal, belly dance\nArabic Mawwal, cinematic electronic\nArabic Mawwal, cinematic, ambient\nArabic Mawwal, cinematic, electronic\nArabic Mawwal, cinematic, orchestral\nArabic Mawwal, cinematic, world fusion\nArabic Mawwal, electronic dabke\nArabic Mawwal, electronic dance\nArabic Mawwal, electronic fusion\nArabic Mawwal, electronic, cinematic\nArabic Mawwal, electronic, dance\nArabic Mawwal, electronic, fusion\nArabic Mawwal, electronic, spiritual\nArabic Mawwal, electronic, world fusion\nArabic Mawwal, jazz fusion, funk\nArabic Mawwal, traditional fusion\nArabic Nasheed\nArabic Pop\nArabic Pop funk R&B\nArabic Pop, Rai\nArabic Pop, Raï\nArabic Pop-R&B\nArabic R&B\nArabic R&B Afrobeats\nArabic R&B lo-fi\nArabic R&B lo-fi hip-hop\nArabic R&B trap\nArabic R&B, lo-fi hip hop, ambient\nArabic R&B, sad trap\nArabic Sufi\nArabic Taqsim\nArabic Tarab\nArabic Zaffa\nArabic a cappella\nArabic acoustic\nArabic acoustic pop\nArabic alternative rock\nArabic ambient\nArabic ambient hip-hop\nArabic anasheed\nArabic anthem\nArabic art song\nArabic art-pop\nArabic ballad\nArabic ballad Bossa Nova\nArabic ballad jazz\nArabic ballad jazz lounge\nArabic ballad lounge jazz\nArabic ballad tango\nArabic ballad, Arabic pop\nArabic ballad, Khaleeji pop\nArabic ballad, R&B, pop\nArabic ballad, cinematic, orchestral\nArabic ballad, dance-pop\nArabic ballad, electronic, Mawwal\nArabic ballad, pop-rock\nArabic ballad, tango fusion, Latin folk\nArabic belly dance\nArabic big band\nArabic big band swing\nArabic big-band\nArabic bluegrass fusion\nArabic blues jazz\nArabic blues-rock\nArabic cabaret\nArabic cabaret jazz\nArabic cabaret, musical theater\nArabic cabaret-pop\nArabic chanson\nArabic chant\nArabic children's\nArabic children's EDM\nArabic children's chiptune\nArabic children's dance\nArabic children's disco\nArabic children's lo-fi\nArabic children's music\nArabic children's music chiptune\nArabic children's pop\nArabic children's synth-pop\nArabic children's, 80s anime, synth pop\nArabic children's, Bossa Nova\nArabic children's, Eurodance\nArabic children's, Latin, mambo\nArabic children's, big band swing\nArabic children's, chiptune\nArabic children's, chiptune, electronic\nArabic children's, chiptune, video game music\nArabic children's, early 2000s electronic\nArabic children's, electronic\nArabic children's, electronic dance\nArabic children's, electronic pop\nArabic children's, electronic, chiptune\nArabic children's, lo-fi, retro\nArabic children's, retro synth\nArabic children's, theatrical, cinematic\nArabic chiptune\nArabic chiptune pop\nArabic chiptune rap\nArabic chiptune-pop\nArabic choir\nArabic choral\nArabic choral, synth-pop\nArabic cinematic\nArabic cinematic, nu-disco\nArabic classical\nArabic classical crossover\nArabic classical tango\nArabic classical, Arabic folk\nArabic classical, Arabic pop\nArabic classical, Khaleeji\nArabic classical, Mawwal, cinematic\nArabic classical, cinematic orchestral\nArabic classical, cinematic, tango\nArabic classical, tango, cabaret\nArabic comedy\nArabic conscious hip-hop\nArabic dance\nArabic dance pop\nArabic dance-pop\nArabic dance-pop chiptune\nArabic dance-pop moombahton\nArabic dance-pop reggaeton\nArabic dancehall\nArabic deep house\nArabic devotional\nArabic devotional, Latin percussion, folk fusion\nArabic devotional, chiptune, electronic\nArabic devotional, chiptune, synth-pop\nArabic devotional, electronic, hip-hop\nArabic devotional, world music\nArabic disco\nArabic disco funk\nArabic disco-funk\nArabic disco-pop\nArabic drill\nArabic drill, microtonal\nArabic drum & bass\nArabic drum and bass\nArabic dubstep\nArabic electro-dabke\nArabic electro-funk\nArabic electro-house\nArabic electro-pop\nArabic electronic\nArabic electronic dance\nArabic electronic dance-pop\nArabic electronic folk\nArabic electronic funk\nArabic electronic fusion\nArabic electronic pop\nArabic electronic pop-rock\nArabic electronic protest\nArabic electronic rock\nArabic electronic trap\nArabic electronic, Mahraganat, hardstyle\nArabic electronic, hardstyle, Mahraganat\nArabic electronica\nArabic emo-rap\nArabic epic\nArabic film score\nArabic film score, belly dance, dabke\nArabic flamenco\nArabic flamenco fusion\nArabic flamenco pop-rock\nArabic folk\nArabic folk acoustic\nArabic folk anthem\nArabic folk blues-rock\nArabic folk cumbia\nArabic folk dance\nArabic folk electronic\nArabic folk flamenco\nArabic folk fusion\nArabic folk indie rock\nArabic folk pop\nArabic folk rock\nArabic folk swing\nArabic folk, Arabic pop\nArabic folk, Iberian folk\nArabic folk, Latin fusion, flamenco\nArabic folk, Latin rhythm\nArabic folk, Latin rock\nArabic folk, Latin rumba\nArabic folk, alternative hip-hop\nArabic folk, bluegrass\nArabic folk, chiptune, video game music\nArabic folk, cinematic orchestral\nArabic folk, cinematic pop, world fusion\nArabic folk, cinematic, ballad\nArabic folk, conscious hip-hop\nArabic folk, electronic dance\nArabic folk, electronic pop\nArabic folk, electronic shoabi\nArabic folk, electronic, Dabke\nArabic folk, electronic, belly dance\nArabic folk, electronic, cinematic\nArabic folk, electronic, hip-hop\nArabic folk, electronic, world fusion\nArabic folk, fusion, pop\nArabic folk, hip-hop fusion\nArabic folk, norteño\nArabic folk, psychedelic funk-rock\nArabic folk, psychedelic rock\nArabic folk, surf rock\nArabic folk, world music\nArabic folk, world music, Latin-influenced\nArabic folk, world music, cinematic\nArabic folk, world music, cinematic pop\nArabic folk-dance\nArabic folk-fusion\nArabic folk-pop\nArabic folk-rock\nArabic football chant\nArabic funk\nArabic funk fusion\nArabic funk pop\nArabic funk reggae\nArabic funk rock\nArabic funk soul\nArabic funk, psychedelic rock\nArabic funk-pop\nArabic funk-rap\nArabic funk-reggae\nArabic funk-reggae fusion\nArabic funk-rock\nArabic fusion\nArabic fusion Spanish folk\nArabic fusion funk\nArabic fusion funk rock\nArabic fusion hip-hop\nArabic fusion pop\nArabic fusion trap\nArabic fusion, Dabke, electronic\nArabic fusion, Latin pop, French pop\nArabic fusion, Latin salsa\nArabic fusion, South Indian fusion, funk pop\nArabic fusion, Spanish folk, festive\nArabic fusion, belly dance, ambient\nArabic fusion, electronic pop\nArabic fusion, electronic pop, cinematic\nArabic fusion, electronic, Indian classical\nArabic fusion, synth-pop, cinematic\nArabic gospel\nArabic gospel, Latin jazz, salsa\nArabic happy hardcore\nArabic hardcore\nArabic hardstyle\nArabic hip hop\nArabic hip hop, trap\nArabic hip-hop\nArabic hip-hop Latin dance\nArabic hip-hop chiptune\nArabic hip-hop funk\nArabic hip-hop lo-fi\nArabic hip-hop trap\nArabic hip-hop, Afrobeats\nArabic hip-hop, Mahraganat\nArabic hip-hop, R&B\nArabic hip-hop, atmospheric R&B\nArabic hip-hop, electronic\nArabic hip-hop, hard trap\nArabic hip-hop, tech-house\nArabic hip-hop, trap\nArabic hip-hop, world music, boom-bap\nArabic house\nArabic hymn\nArabic hyperpop\nArabic indie\nArabic indie pop\nArabic indie rock\nArabic indie-folk\nArabic indie-pop\nArabic inspirational\nArabic instrumental\nArabic jazz\nArabic jazz ballad\nArabic jazz fusion\nArabic jazz lounge\nArabic jazz-funk\nArabic jazz-pop\nArabic lament\nArabic lo-fi\nArabic lo-fi hip hop\nArabic lo-fi hip-hop\nArabic lo-fi trap\nArabic lullaby\nArabic mambo\nArabic maqam\nArabic mawwal\nArabic mawwal, Khaleeji pop\nArabic mawwal, belly dance, electronic fusion\nArabic mawwal, dabke\nArabic mawwal, electronic, world fusion\nArabic melancholic\nArabic military march\nArabic moombahton\nArabic music\nArabic music, Khaleeji pop\nArabic music, Mawwal, Dabke\nArabic music, Mawwal, traditional fusion\nArabic music, North African, flamenco\nArabic music, dabke, traditional\nArabic narrative\nArabic nasheed\nArabic new jack swing\nArabic ney\nArabic nu-disco\nArabic nursery rhyme\nArabic opera\nArabic operatic\nArabic orchestral\nArabic oud\nArabic patriotic\nArabic percussion\nArabic phonk\nArabic piano\nArabic pop\nArabic pop 80s\nArabic pop 90s\nArabic pop Afrobeat Latin\nArabic pop Balkan brass\nArabic pop Balkan folk\nArabic pop Bossa Nova\nArabic pop Chalga\nArabic pop Dabke\nArabic pop EDM\nArabic pop J-pop\nArabic pop Khaleeji\nArabic pop Latin\nArabic pop Latin dance\nArabic pop Latin fusion\nArabic pop Latin jazz\nArabic pop Latin pop\nArabic pop R&B\nArabic pop R&B funk\nArabic pop R&B hip-hop\nArabic pop R&B lo-fi hip-hop\nArabic pop R&B neo-soul\nArabic pop R&B trap\nArabic pop Rai\nArabic pop Spanish pop\nArabic pop ballad\nArabic pop big band jazz\nArabic pop cabaret\nArabic pop cabaret tango\nArabic pop chaabi\nArabic pop chillwave\nArabic pop chiptune\nArabic pop cinematic\nArabic pop classical\nArabic pop cumbia\nArabic pop dance\nArabic pop dance-pop\nArabic pop dancehall\nArabic pop deep house\nArabic pop dembow\nArabic pop electro\nArabic pop electro-cumbia chiptune\nArabic pop electro-dabke\nArabic pop electro-shaabi\nArabic pop electro-shaabi chiptune\nArabic pop electronic rock\nArabic pop electropop\nArabic pop flamenco\nArabic pop flamenco fusion\nArabic pop folk\nArabic pop funk\nArabic pop funk R&B\nArabic pop funk chiptune\nArabic pop funk disco\nArabic pop funk electronic\nArabic pop funk rock\nArabic pop funk soul\nArabic pop funk-rock\nArabic pop fusion\nArabic pop gospel\nArabic pop hip-hop\nArabic pop hip-hop funk\nArabic pop house\nArabic pop jazz\nArabic pop jazz Latin\nArabic pop jazz fusion\nArabic pop jazz fusion funk\nArabic pop jazz lounge\nArabic pop lo-fi\nArabic pop lo-fi hip hop\nArabic pop lo-fi hip-hop\nArabic pop lounge\nArabic pop lounge exotica\nArabic pop metal\nArabic pop neo-soul\nArabic pop nu-disco funk\nArabic pop orchestral\nArabic pop progressive house\nArabic pop psychedelic funk\nArabic pop reggae\nArabic pop reggae dancehall\nArabic pop reggae ska\nArabic pop reggaeton\nArabic pop retro\nArabic pop retro disco\nArabic pop retro funk\nArabic pop retro-disco\nArabic pop retro-electronic\nArabic pop retro-funk\nArabic pop rock\nArabic pop salsa\nArabic pop salsa fusion\nArabic pop samba\nArabic pop smooth jazz funk\nArabic pop surf rock\nArabic pop synth-pop\nArabic pop tango\nArabic pop tango folk\nArabic pop trap\nArabic pop trap R&B\nArabic pop trap afrobeat\nArabic pop trap dancehall\nArabic pop tropical house\nArabic pop world music\nArabic pop worldbeat\nArabic pop, 80s funk, disco\nArabic pop, 80s pop, funk\nArabic pop, 80s pop, theatrical\nArabic pop, 80s retro\nArabic pop, 80s synth, cinematic\nArabic pop, 80s synth, retro\nArabic pop, 80s synth-pop, funk\nArabic pop, 90s dance-pop\nArabic pop, 90s hip-hop\nArabic pop, Afrobeat\nArabic pop, Afrobeat, Dancehall\nArabic pop, Afrobeat, dancehall\nArabic pop, Afrobeats\nArabic pop, Afrobeats, Dancehall\nArabic pop, Afrobeats, R&B\nArabic pop, Afrobeats, dancehall\nArabic pop, Afrobeats, electronic\nArabic pop, Andalusian, modern pop\nArabic pop, Arabic house\nArabic pop, Arabic trap, Rai\nArabic pop, Balkan brass, theatrical pop\nArabic pop, Balkan fusion\nArabic pop, Balkan, Klezmer\nArabic pop, Bollywood, electronic dance\nArabic pop, Bossa Nova, Latin jazz\nArabic pop, Bossa Nova, jazz\nArabic pop, Christmas, cinematic\nArabic pop, Cumbia\nArabic pop, Cumbia, Salsa\nArabic pop, Cumbia, vintage\nArabic pop, Dabke\nArabic pop, Dabke, Eurodance\nArabic pop, Dabke, Latin pop\nArabic pop, Dabke, chiptune\nArabic pop, Dabke, cinematic\nArabic pop, Dabke, electronic\nArabic pop, Dabke, electronic dance\nArabic pop, Dabke, lo-fi\nArabic pop, Dabke, synth-pop\nArabic pop, Dabke, synthwave\nArabic pop, Dabke, vintage synth\nArabic pop, Dangdut Koplo\nArabic pop, EDM\nArabic pop, EDM, Dabke\nArabic pop, EDM, Middle Eastern\nArabic pop, EDM, R&B\nArabic pop, EDM, cinematic\nArabic pop, EDM, dance\nArabic pop, EDM, dance-pop\nArabic pop, EDM, dancehall\nArabic pop, EDM, devotional\nArabic pop, EDM, future bass\nArabic pop, EDM, hip-hop\nArabic pop, EDM, moombahton\nArabic pop, EDM, oriental\nArabic pop, EDM, progressive house\nArabic pop, EDM, rock\nArabic pop, EDM, trance\nArabic pop, EDM, trap\nArabic pop, Egyptian hip-hop\nArabic pop, Eurodance\nArabic pop, Eurodance, 90s dance\nArabic pop, Eurodance, 90s dance-pop\nArabic pop, Eurodance, 90s pop\nArabic pop, Eurodance, 90s synth\nArabic pop, Eurodance, Dabke\nArabic pop, Eurodance, Hi-NRG\nArabic pop, Eurodance, Italo disco\nArabic pop, Eurodance, Latin house\nArabic pop, Eurodance, Latin pop\nArabic pop, Eurodance, R&B\nArabic pop, Eurodance, Russian pop\nArabic pop, Eurodance, chiptune\nArabic pop, Eurodance, cinematic\nArabic pop, Eurodance, dance-pop\nArabic pop, Eurodance, electronic\nArabic pop, Eurodance, funk\nArabic pop, Eurodance, happy hardcore\nArabic pop, Eurodance, retro\nArabic pop, Eurodance, trance\nArabic pop, European folk\nArabic pop, European folk, theatrical\nArabic pop, French R&B, trap\nArabic pop, French dance-pop\nArabic pop, French folk\nArabic pop, French hip-hop\nArabic pop, French hip-hop, electronic\nArabic pop, French hip-hop, fusion\nArabic pop, French pop\nArabic pop, French pop, electronic\nArabic pop, French pop, fusion\nArabic pop, French rap, electronic dance\nArabic pop, French rap, reggaeton\nArabic pop, French rap, trap\nArabic pop, French rock\nArabic pop, German rap, dancehall\nArabic pop, Indonesian pop, ambient\nArabic pop, Islamic devotional, folk\nArabic pop, Italian rap, trap\nArabic pop, Khaleeji\nArabic pop, Khaleeji pop, cinematic\nArabic pop, Khaleeji, R&B\nArabic pop, Khaleeji, Taqsim\nArabic pop, Khaleeji, anthemic\nArabic pop, Khaleeji, celebratory\nArabic pop, Khaleeji, cinematic\nArabic pop, Khaleeji, dance\nArabic pop, Khaleeji, dance pop\nArabic pop, Khaleeji, dance-pop\nArabic pop, Khaleeji, electronic\nArabic pop, Khaleeji, electronic dance\nArabic pop, Khaleeji, festive\nArabic pop, Khaleeji, funk\nArabic pop, Khaleeji, hip-hop\nArabic pop, Khaleeji, hyperpop\nArabic pop, Khaleeji, modern\nArabic pop, Khaleeji, modern pop\nArabic pop, Khaleeji, patriotic\nArabic pop, Khaleeji, pop\nArabic pop, Khaleeji, pop-dance\nArabic pop, Khaleeji, pop-rock\nArabic pop, Khaleeji, synth pop\nArabic pop, Khaleeji, upbeat\nArabic pop, Latin cumbia\nArabic pop, Latin dance\nArabic pop, Latin dance, electronic\nArabic pop, Latin dance, reggaeton\nArabic pop, Latin dance, upbeat\nArabic pop, Latin funk\nArabic pop, Latin funk, cinematic\nArabic pop, Latin funk, dance\nArabic pop, Latin fusion\nArabic pop, Latin fusion, world music\nArabic pop, Latin jazz\nArabic pop, Latin jazz, bolero\nArabic pop, Latin jazz, funk\nArabic pop, Latin jazz, mambo\nArabic pop, Latin jazz, salsa\nArabic pop, Latin mambo\nArabic pop, Latin mambo, orchestral\nArabic pop, Latin pop\nArabic pop, Latin pop, Caribbean\nArabic pop, Latin pop, Cumbia\nArabic pop, Latin pop, Zouk\nArabic pop, Latin pop, ballad\nArabic pop, Latin pop, cinematic\nArabic pop, Latin pop, cumbia\nArabic pop, Latin pop, dance\nArabic pop, Latin pop, dembow\nArabic pop, Latin pop, electronic\nArabic pop, Latin pop, flamenco\nArabic pop, Latin pop, folk fusion\nArabic pop, Latin pop, merengue\nArabic pop, Latin pop, modern\nArabic pop, Latin pop, reggaeton\nArabic pop, Latin pop, retro\nArabic pop, Latin pop, salsa\nArabic pop, Latin pop, vintage\nArabic pop, Latin pop, world music\nArabic pop, Latin rock\nArabic pop, Latin rumba\nArabic pop, Latin salsa\nArabic pop, Latin salsa, Eurodance\nArabic pop, Latin salsa, funk\nArabic pop, Latin, North African\nArabic pop, Latin, Raï\nArabic pop, Latin, cha-cha-chá\nArabic pop, Latin, cinematic\nArabic pop, Latin, flamenco\nArabic pop, Latin, reggae\nArabic pop, Latin, salsa\nArabic pop, Latin, tango\nArabic pop, Mahraganat\nArabic pop, Mahraganat, Dabke\nArabic pop, Mahraganat, Raï\nArabic pop, Mahraganat, belly dance\nArabic pop, Mahraganat, chiptune\nArabic pop, Mahraganat, cinematic\nArabic pop, Mahraganat, dancehall\nArabic pop, Mahraganat, electro-dabke\nArabic pop, Mahraganat, electro-shaabi\nArabic pop, Mahraganat, electronic\nArabic pop, Mahraganat, electronic dance\nArabic pop, Mahraganat, hip-hop\nArabic pop, Mahraganat, pop-dabke\nArabic pop, Middle Eastern fusion\nArabic pop, Middle Eastern fusion, French hip-hop\nArabic pop, Moombahton\nArabic pop, Nasheed\nArabic pop, North African folk\nArabic pop, R&B\nArabic pop, R&B, 2000s pop\nArabic pop, R&B, Afrobeats\nArabic pop, R&B, French pop\nArabic pop, R&B, Moombahton\nArabic pop, R&B, acoustic\nArabic pop, R&B, ambient\nArabic pop, R&B, dancehall\nArabic pop, R&B, electronic\nArabic pop, R&B, experimental\nArabic pop, R&B, hip-hop\nArabic pop, R&B, pop\nArabic pop, R&B, smooth jazz\nArabic pop, R&B, trap\nArabic pop, Rai\nArabic pop, Rai, Chaabi\nArabic pop, Rai, Dabke\nArabic pop, Rai, Middle Eastern\nArabic pop, Rai, cinematic\nArabic pop, Rai, dance\nArabic pop, Rai, dance pop\nArabic pop, Rai, dance-pop\nArabic pop, Rai, dancehall\nArabic pop, Rai, electronic\nArabic pop, Rai, electronic dance\nArabic pop, Rai, hip-hop\nArabic pop, Rai, melodic\nArabic pop, Rai, modern Chaabi\nArabic pop, Rai, modern pop\nArabic pop, Rai, ney flute\nArabic pop, Rai, synth pop\nArabic pop, Rai, trap\nArabic pop, Rai, world fusion\nArabic pop, Raï\nArabic pop, Raï, Balkan fusion\nArabic pop, Raï, Chaabi\nArabic pop, Raï, Cumbia\nArabic pop, Raï, Dabke\nArabic pop, Raï, Latin\nArabic pop, Raï, Latin pop\nArabic pop, Raï, North African\nArabic pop, Raï, North African folk\nArabic pop, Raï, cinematic\nArabic pop, Raï, dance\nArabic pop, Raï, dance-pop\nArabic pop, Raï, dancehall\nArabic pop, Raï, electronic\nArabic pop, Raï, electronic belly dance\nArabic pop, Raï, electronic dance\nArabic pop, Raï, folk\nArabic pop, Raï, folkloric\nArabic pop, Raï, funk\nArabic pop, Raï, hip-hop\nArabic pop, Raï, live\nArabic pop, Raï, lo-fi hip-hop\nArabic pop, Raï, microtonal\nArabic pop, Raï, modern\nArabic pop, Raï, modern Thea\nArabic pop, Raï, modern folk\nArabic pop, Raï, modern pop\nArabic pop, Raï, salsa\nArabic pop, Raï, synthwave\nArabic pop, Raï, traditional\nArabic pop, Raï, trap\nArabic pop, Raï, upbeat\nArabic pop, Turkish dance, electronic\nArabic pop, Turkish pop, fusion\nArabic pop, Turkish pop, modern ballad\nArabic pop, ambient trap\nArabic pop, atmospheric R&B\nArabic pop, baroque pop\nArabic pop, belly dance\nArabic pop, belly dance, electronic\nArabic pop, big band funk\nArabic pop, big band jazz\nArabic pop, big band jazz, funk\nArabic pop, big band, soul\nArabic pop, big beat, cinematic\nArabic pop, boom-bap, cinematic\nArabic pop, breakbeat, electronic\nArabic pop, cabaret, Latin pop\nArabic pop, cabaret, musette\nArabic pop, cha-cha-chá\nArabic pop, chillwave\nArabic pop, chiptune\nArabic pop, chiptune, Mahraganat\nArabic pop, chiptune, bubblegum\nArabic pop, chiptune, children's music\nArabic pop, chiptune, cinematic\nArabic pop, chiptune, dance\nArabic pop, chiptune, electronic\nArabic pop, chiptune, electronic dance\nArabic pop, chiptune, novelty\nArabic pop, chiptune, reggaeton\nArabic pop, chiptune, retro\nArabic pop, chiptune, retro electronic\nArabic pop, chiptune, retro-futuristic\nArabic pop, chiptune, rock\nArabic pop, chiptune, synth-pop\nArabic pop, chiptune, synthwave\nArabic pop, chiptune, video game music\nArabic pop, chiptune, world music\nArabic pop, choral anthem\nArabic pop, cinematic\nArabic pop, cinematic ambient\nArabic pop, cinematic ambient, electronic\nArabic pop, cinematic ballad\nArabic pop, cinematic dance\nArabic pop, cinematic electronic, trap\nArabic pop, cinematic orchestral\nArabic pop, cinematic orchestral, Middle Eastern fusion\nArabic pop, cinematic orchestral, folk fusion\nArabic pop, cinematic pop\nArabic pop, cinematic rock\nArabic pop, cinematic soul\nArabic pop, cinematic synth, dance-pop\nArabic pop, cinematic trap\nArabic pop, cinematic trap, R&B\nArabic pop, cinematic, Afrobeat\nArabic pop, cinematic, Dabke\nArabic pop, cinematic, Eurodance\nArabic pop, cinematic, Khaleeji\nArabic pop, cinematic, Latin\nArabic pop, cinematic, Middle Eastern\nArabic pop, cinematic, Middle Eastern fusion\nArabic pop, cinematic, R&B\nArabic pop, cinematic, Raï\nArabic pop, cinematic, ambient\nArabic pop, cinematic, anthemic\nArabic pop, cinematic, belly dance\nArabic pop, cinematic, belly house\nArabic pop, cinematic, classical\nArabic pop, cinematic, dabke\nArabic pop, cinematic, dance\nArabic pop, cinematic, dance-pop\nArabic pop, cinematic, dramatic\nArabic pop, cinematic, duduk\nArabic pop, cinematic, electronic\nArabic pop, cinematic, electronic dance\nArabic pop, cinematic, emotional\nArabic pop, cinematic, epic\nArabic pop, cinematic, flamenco\nArabic pop, cinematic, folk\nArabic pop, cinematic, folk dance\nArabic pop, cinematic, folk-dance\nArabic pop, cinematic, funk\nArabic pop, cinematic, fusion\nArabic pop, cinematic, future bass\nArabic pop, cinematic, hip-hop\nArabic pop, cinematic, lo-fi\nArabic pop, cinematic, lo-fi chiptune\nArabic pop, cinematic, lo-fi hip hop\nArabic pop, cinematic, lounge\nArabic pop, cinematic, melancholic\nArabic pop, cinematic, microtonal\nArabic pop, cinematic, modern\nArabic pop, cinematic, moombahton\nArabic pop, cinematic, ney\nArabic pop, cinematic, operatic\nArabic pop, cinematic, orchestral\nArabic pop, cinematic, oud\nArabic pop, cinematic, pop-funk\nArabic pop, cinematic, pop-rock\nArabic pop, cinematic, rock\nArabic pop, cinematic, soulful\nArabic pop, cinematic, synth-pop\nArabic pop, cinematic, synthwave\nArabic pop, cinematic, traditional\nArabic pop, cinematic, trap\nArabic pop, cinematic, world fusion\nArabic pop, cinematic, world music\nArabic pop, classical fusion, romantic ballad\nArabic pop, contemporary R&B, trap\nArabic pop, cumbia\nArabic pop, cumbia, Latin\nArabic pop, cumbia, Latin pop\nArabic pop, cumbia, cinematic\nArabic pop, cumbia, dembow\nArabic pop, dabke, ney\nArabic pop, dance, cinematic\nArabic pop, dance, electronic\nArabic pop, dance, fusion\nArabic pop, dance, hip-hop\nArabic pop, dance-pop\nArabic pop, dance-pop, Mahraganat\nArabic pop, dance-pop, cinematic\nArabic pop, dance-pop, deep house\nArabic pop, dance-pop, hip-hop\nArabic pop, dancehall\nArabic pop, dancehall, afrobeat\nArabic pop, dancehall, electronic\nArabic pop, dancehall, reggae\nArabic pop, dancehall, reggaeton\nArabic pop, deep house\nArabic pop, dembow, electronic\nArabic pop, devotional, electronic dance\nArabic pop, digital cumbia\nArabic pop, digital cumbia, Rai\nArabic pop, downtempo R&B, cinematic\nArabic pop, early 2000s hip-hop\nArabic pop, electa, Raï\nArabic pop, electro-Bağlama, Raï\nArabic pop, electro-dabke\nArabic pop, electro-dabke, chiptune\nArabic pop, electro-dabke, cinematic\nArabic pop, electro-dabke, dance\nArabic pop, electro-dabke, electronic\nArabic pop, electro-dabke, electronic dance\nArabic pop, electro-dabke, funk\nArabic pop, electro-dabke, high-energy\nArabic pop, electro-dabke, hyperpop\nArabic pop, electro-dabke, moombahton\nArabic pop, electro-pop, Dabke\nArabic pop, electro-shaabi\nArabic pop, electro-shaabi, Mahraganat\nArabic pop, electro-shaabi, belly dance\nArabic pop, electro-shaabi, chiptune\nArabic pop, electro-shaabi, funk\nArabic pop, electro-shaabi, hip-hop\nArabic pop, electro-shaabi, oriental house\nArabic pop, electro-swing, chiptune\nArabic pop, electronic\nArabic pop, electronic R&B\nArabic pop, electronic belly dance\nArabic pop, electronic dance\nArabic pop, electronic dance music\nArabic pop, electronic dance music, Islamic devotional\nArabic pop, electronic dance, Dabke\nArabic pop, electronic dance, Mahraganat\nArabic pop, electronic dance, Mawwal\nArabic pop, electronic dance, Middle Eastern\nArabic pop, electronic dance, Middle Eastern fusion\nArabic pop, electronic dance, North African\nArabic pop, electronic dance, ambient\nArabic pop, electronic dance, ambient fusion\nArabic pop, electronic dance, chiptune\nArabic pop, electronic dance, cinematic\nArabic pop, electronic dance, fusion\nArabic pop, electronic dance, hip-hop\nArabic pop, electronic dance, pop\nArabic pop, electronic dance, reggae fusion\nArabic pop, electronic dance, rock\nArabic pop, electronic dance, rock fusion\nArabic pop, electronic dance, synth-pop\nArabic pop, electronic folk\nArabic pop, electronic rock\nArabic pop, electronic, Dabke\nArabic pop, electronic, Latin pop\nArabic pop, electronic, Mawwal\nArabic pop, electronic, North African\nArabic pop, electronic, Rai\nArabic pop, electronic, Raï\nArabic pop, electronic, Vocaloid\nArabic pop, electronic, ambient\nArabic pop, electronic, belly dance\nArabic pop, electronic, children's\nArabic pop, electronic, chiptune\nArabic pop, electronic, cinematic\nArabic pop, electronic, dance\nArabic pop, electronic, dance-pop\nArabic pop, electronic, dancehall\nArabic pop, electronic, dream pop\nArabic pop, electronic, ethereal\nArabic pop, electronic, folk-dance\nArabic pop, electronic, funk\nArabic pop, electronic, fusion\nArabic pop, electronic, hip hop\nArabic pop, electronic, hip-hop\nArabic pop, electronic, mawwal\nArabic pop, electronic, melancholic\nArabic pop, electronic, moombahton\nArabic pop, electronic, ney\nArabic pop, electronic, oriental\nArabic pop, electronic, protest\nArabic pop, electronic, raï\nArabic pop, electronic, traditional\nArabic pop, electronic, traditional fusion\nArabic pop, electronic, trance\nArabic pop, electronic, trap\nArabic pop, electronic, vaporwave\nArabic pop, electronic, virtuosic violin\nArabic pop, electronic, world fusion\nArabic pop, electronic, world music\nArabic pop, electropop, belly dance\nArabic pop, ethno-pop, oriental house\nArabic pop, festive pop, bilingual\nArabic pop, flamenco fusion, modern pop\nArabic pop, flamenco, Latin\nArabic pop, flamenco-pop, Latin pop\nArabic pop, folk fusion, cinematic\nArabic pop, folk, belly dance\nArabic pop, funk, 90s new jack swing\nArabic pop, funk, North African\nArabic pop, funk, R&B\nArabic pop, funk, cinematic\nArabic pop, funk, dance\nArabic pop, funk, disco\nArabic pop, funk, electronic dance\nArabic pop, funk, new jack swing\nArabic pop, funk, oriental pop\nArabic pop, funk, pop-rock\nArabic pop, funk, retro-futuristic\nArabic pop, funk-rock\nArabic pop, future bass, cinematic\nArabic pop, gospel, pop-rock\nArabic pop, gospel, spiritual\nArabic pop, gypsy jazz, flamenco\nArabic pop, hard rock\nArabic pop, hard rock, hip-hop\nArabic pop, hardstyle, electronic\nArabic pop, hardstyle, trap\nArabic pop, hip-hop\nArabic pop, hip-hop, EDM\nArabic pop, hip-hop, Khaleeji\nArabic pop, hip-hop, Mahraganat\nArabic pop, hip-hop, Middle Eastern rock\nArabic pop, hip-hop, North African\nArabic pop, hip-hop, R&B\nArabic pop, hip-hop, Rai\nArabic pop, hip-hop, Raï\nArabic pop, hip-hop, chiptune\nArabic pop, hip-hop, cinematic\nArabic pop, hip-hop, dancehall\nArabic pop, hip-hop, electronic\nArabic pop, hip-hop, electronic dance\nArabic pop, hip-hop, funk\nArabic pop, hip-hop, fusion\nArabic pop, hip-hop, hardstyle\nArabic pop, hip-hop, reggaeton\nArabic pop, hip-hop, trap\nArabic pop, hyperpop, EDM\nArabic pop, jazz fusion\nArabic pop, jazz, Latin\nArabic pop, jazz, lounge\nArabic pop, lo-fi hip hop\nArabic pop, lo-fi hip hop, ambient\nArabic pop, lo-fi hip hop, contemporary R&B\nArabic pop, lo-fi hip-hop\nArabic pop, lo-fi hip-hop, R&B\nArabic pop, lo-fi, R&B\nArabic pop, lo-fi, chiptune\nArabic pop, lo-fi, cinematic\nArabic pop, lo-fi, electronic\nArabic pop, merengue, Latin pop\nArabic pop, merengue, stadium rock\nArabic pop, microtonal, cinematic\nArabic pop, modern Raï\nArabic pop, modern dance, microtonal\nArabic pop, modern pop-trap\nArabic pop, moombahton\nArabic pop, moombahton, cinematic\nArabic pop, moombahton, reggaeton\nArabic pop, moombahton, trap\nArabic pop, neo-soul, R&B\nArabic pop, new jack swing, funk\nArabic pop, new jack swing, hip hop\nArabic pop, old-school hip-hop\nArabic pop, old-school hip-hop, cinematic\nArabic pop, pop-shaabi\nArabic pop, progressive house\nArabic pop, progressive house, trance\nArabic pop, progressive rock\nArabic pop, psychedelic funk, belly dance\nArabic pop, psychedelic funk-rock\nArabic pop, psychedelic rock, synth-pop\nArabic pop, psychedelic, cinematic\nArabic pop, psychedelic, lo-fi\nArabic pop, rap, pop-rock\nArabic pop, reggae, dancehall\nArabic pop, reggaeton\nArabic pop, reggaeton, Latin\nArabic pop, reggaeton, Latin dance\nArabic pop, reggaeton, Latin pop\nArabic pop, reggaeton, North African\nArabic pop, reggaeton, afrobeat\nArabic pop, reggaeton, chiptune\nArabic pop, reggaeton, cinematic\nArabic pop, reggaeton, dance-pop\nArabic pop, reggaeton, dancehall\nArabic pop, reggaeton, dream pop\nArabic pop, reggaeton, electronic\nArabic pop, reggaeton, electronic dance\nArabic pop, reggaeton, melodic\nArabic pop, reggaeton, moombahton\nArabic pop, reggaeton, world music\nArabic pop, retro chiptune\nArabic pop, retro dance\nArabic pop, retro electronic\nArabic pop, retro electronic, synth-pop\nArabic pop, retro funk\nArabic pop, retro funk, 80s synth\nArabic pop, retro funk, disco\nArabic pop, retro funk, new jack swing\nArabic pop, retro pop, bubblegum pop\nArabic pop, retro swing, big band\nArabic pop, retro synth\nArabic pop, retro synth, 80s pop\nArabic pop, retro synth, chiptune\nArabic pop, retro synth, video game music\nArabic pop, retro synth-pop\nArabic pop, retro synth-pop, Latin groove\nArabic pop, retro video game\nArabic pop, retro video game, theatrical\nArabic pop, retro, Dabke\nArabic pop, retro, chiptune\nArabic pop, retro, funk\nArabic pop, retro, hip-hop\nArabic pop, retro, surf rock\nArabic pop, retro, surf-rock\nArabic pop, retro-digital\nArabic pop, retro-funk, disco\nArabic pop, retro-gaming, electronic\nArabic pop, salsa\nArabic pop, salsa, Latin\nArabic pop, salsa, Latin pop\nArabic pop, salsa, cinematic\nArabic pop, salsa, reggaeton\nArabic pop, sliding house, Mahraganat\nArabic pop, smooth jazz, R&B\nArabic pop, smooth jazz, world music\nArabic pop, spiritual music\nArabic pop, surf rock, belly dance\nArabic pop, synth pop, retro\nArabic pop, synth pop, worship\nArabic pop, synth-funk\nArabic pop, synth-funk, 80s pop\nArabic pop, synth-funk, disco\nArabic pop, synth-pop\nArabic pop, synth-pop, 80s\nArabic pop, synth-pop, EDM\nArabic pop, synth-pop, Italo-disco\nArabic pop, synth-pop, North African pop\nArabic pop, synth-pop, chiptune\nArabic pop, synth-pop, disco\nArabic pop, synth-pop, disco-funk\nArabic pop, synth-pop, electronic\nArabic pop, synth-pop, electronic dance\nArabic pop, synth-pop, funk\nArabic pop, synth-pop, new wave\nArabic pop, synth-pop, psychedelic\nArabic pop, synth-pop, retro\nArabic pop, synth-pop, trance\nArabic pop, synth-pop, tropical house\nArabic pop, tango, classical\nArabic pop, theatrical pop\nArabic pop, theatrical, eclectic\nArabic pop, trance, cinematic\nArabic pop, trap\nArabic pop, trap R&B\nArabic pop, trap, EDM\nArabic pop, trap, Mahraganat\nArabic pop, trap, Middle Eastern\nArabic pop, trap, North African\nArabic pop, trap, R&B\nArabic pop, trap, Rai\nArabic pop, trap, afrobeat\nArabic pop, trap, ambient\nArabic pop, trap, atmospheric\nArabic pop, trap, atmospheric R&B\nArabic pop, trap, ballad\nArabic pop, trap, chiptune\nArabic pop, trap, cinematic\nArabic pop, trap, dance-pop\nArabic pop, trap, dancehall\nArabic pop, trap, dubstep\nArabic pop, trap, electronic\nArabic pop, trap, emotional\nArabic pop, trap, hip-hop\nArabic pop, trap, melodic\nArabic pop, trap, modern\nArabic pop, trap, orchestral\nArabic pop, trap, reggaeton\nArabic pop, trap, rock\nArabic pop, trip-hop, ambient\nArabic pop, world fusion\nArabic pop, world fusion, video game music\nArabic pop, world music\nArabic pop, world music, adult contemporary\nArabic pop, world music, dance-pop\nArabic pop, world music, smooth jazz\nArabic pop, worldbeat\nArabic pop, worldbeat, Latin fusion\nArabic pop, worldbeat, cinematic\nArabic pop, worldbeat, dance\nArabic pop, worldbeat, jazz fusion\nArabic pop, worldbeat, pop-fusion\nArabic pop, zouk, soca\nArabic pop-EDM\nArabic pop-R&B\nArabic pop-dance\nArabic pop-folk\nArabic pop-funk\nArabic pop-fusion\nArabic pop-hip hop\nArabic pop-rap\nArabic pop-rock\nArabic pop-rock funk-rock\nArabic pop-rock fusion\nArabic pop-rock worldbeat\nArabic pop-rock, electronic dance\nArabic pop-rock, hard rock\nArabic pop-shaabi\nArabic pop-trap\nArabic popular music\nArabic power ballad\nArabic progressive house\nArabic protest\nArabic protest anthem\nArabic protest hip-hop\nArabic protest music\nArabic psychedelic funk\nArabic psychedelic rock\nArabic psytrance\nArabic rap-rock\nArabic reggae\nArabic reggae dancehall\nArabic reggae dub\nArabic reggae fusion\nArabic reggae ska\nArabic reggaeton\nArabic revolutionary\nArabic revolutionary chant\nArabic revolutionary folk\nArabic rock\nArabic rock funk\nArabic rock fusion\nArabic rock surf rock\nArabic rock, South Indian folk, fusion\nArabic rock, psychedelic funk\nArabic rock, symphonic metal\nArabic romantic\nArabic romantic ballad\nArabic rumba\nArabic rumba flamenco\nArabic salsa\nArabic soul\nArabic spiritual\nArabic spiritual ballad\nArabic spiritual pop\nArabic spoken word\nArabic sports anthem\nArabic surf rock\nArabic surf-pop\nArabic swing\nArabic swing jazz\nArabic swing-pop\nArabic synth\nArabic synth-funk\nArabic synth-pop\nArabic synth-pop chiptune\nArabic synthwave\nArabic tango\nArabic tango cabaret\nArabic tango flamenco\nArabic tango-pop\nArabic taqsim\nArabic tech house\nArabic tech-house\nArabic techno\nArabic theatrical\nArabic traditional\nArabic traditional, Mawwal, Folk\nArabic traditional, belly dance\nArabic traditional, electronic fusion\nArabic traditional, taqsim, folk fusion\nArabic trance\nArabic trance-pop\nArabic trap\nArabic trap R&B\nArabic trap chiptune\nArabic trap metal\nArabic trap, Bollywood, cinematic\nArabic trap, EDM\nArabic trap, German drill\nArabic trap, Latin fusion\nArabic trap, Latin pop, R&B\nArabic trap, Mahraganat\nArabic trap, R&B\nArabic trap, Rai, modern pop\nArabic trap, cinematic hip-hop\nArabic trap, cloud rap\nArabic trap, electro-pop\nArabic trap, hardstyle\nArabic trap, hip-hop\nArabic trap, hyperpop, cinematic\nArabic trap, lo-fi hip-hop\nArabic trap-R&B\nArabic trap-pop\nArabic trap-rock\nArabic trap-soul\nArabic trip-hop\nArabic vocal\nArabic vocal, melancholic, oud\nArabic wedding anthem\nArabic wedding music\nArabic world fusion\nArabic world music\nArabic world-pop\nArabic worldbeat\nArabic zaffa\nArabic, Dabke\nArabic, Mahraganat\nArabic, Sufi, spiritual\nArabic, atmospheric, dramatic\nArabic, celebratory\nArabic, choral, traditional\nArabic, cinematic, ambient\nArabic, cinematic, melancholic\nArabic, cinematic, oud\nArabic, cinematic, traditional\nArabic, traditional, epic\nArabic, traditional, spiritual\nArgentine folk\nArgentinian Cuarteto\nArgentinian RKT trap\nArgentinian carnaval\nArgentinian drill\nArgentinian festival\nArgentinian folk\nArgentinian folk cumbia\nArgentinian folk flamenco\nArgentinian folk polka\nArgentinian folk rock\nArgentinian folk tango\nArgentinian folk, Chacarera\nArgentinian folklore\nArgentinian funk\nArgentinian hip-hop\nArgentinian rock\nArgentinian samba\nArgentinian tango\nArgentinian trap\nArmenian dance-pop\nArmenian folk\nArmenian folk pop-rock\nArmenian folk-pop\nArmenian hip-hop\nArmenian pop\nArmenian pop, Latin jazz, tango\nArmenian pop, electronic dance\nArmenian pop-dance\nArmenian pop-folk\nArmenian pop-funk\nArrocha\nArrocha Brega\nArrocha Brega Romântico\nArrocha Brega-pop\nArrocha Forró\nArrocha, Brega pop\nAsian Trap\nAsian folk\nAsian folk rock\nAsian hip-hop\nAsian pop\nAsian pop ballad\nAsian trap\nAtlanta trap\nAustralian blues\nAustralian country\nAustralian country-folk\nAustralian country-rock\nAustralian drill\nAustralian folk\nAustralian folk novelty\nAustralian folk, country and western\nAustralian folk, country, bluegrass\nAustralian folk, country, rockabilly\nAustralian folk, country, western\nAustralian folk-country\nAustralian folk-rock\nAustralian grime\nAustralian hip-hop\nAustralian hip-hop trap\nAustralian novelty Christmas\nAustralian rock\nAustralian ska\nAustralian trap\nAxé\nAxé Forró\nAxé Forró Sertanejo\nAxé Gospel\nAxé Samba\nAxé Samba-reggae\nAxé Sertanejo\nAxé children's\nAxé chiptune\nAxé cumbia\nAxé dance\nAxé dance-pop\nAxé electronic\nAxé funk\nAxé funk carioca\nAxé funk pop-rock\nAxé funk-pop\nAxé funk-rock\nAxé gospel\nAxé gospel funk\nAxé gospel pop\nAxé metal\nAxé music\nAxé pop\nAxé pop Forró\nAxé pop, Arabic pop\nAxé pop, Brega\nAxé pop, Brega, Brazilian pop\nAxé pop, Brega, dance-pop\nAxé pop, Eurodance\nAxé pop, Forró\nAxé pop, Forró, Brazilian pop\nAxé pop, Forró, electronic dance\nAxé pop, R&B\nAxé pop, Sertanejo\nAxé pop, smooth jazz\nAxé pop-rock\nAxé punk rock\nAxé rock\nAxé rock, Forró, Brazilian party\nAxé rock, funk, Brazilian\nAxé rock, samba-reggae, hard rock\nAxé salsa\nAxé samba-reggae\nAxé surf rock\nAxé synth-pop\nAxé, Brazilian Carnival\nAxé, Brazilian Carnival, pop-reggae\nAxé, Brazilian carnival\nAxé, Brazilian party\nAxé, Brazilian pop\nAxé, Brazilian pop, smooth jazz\nAxé, Brazilian pop-funk\nAxé, Brazilian pop-rock\nAxé, Brazilian pop-rock, carnival\nAxé, Brazilian, carnival\nAxé, Brazilian, festive\nAxé, Brega, Brazilian pop\nAxé, Christian pop\nAxé, Cumbia\nAxé, Forró\nAxé, Forró Eletrônico\nAxé, Forró Eletrônico, Brazilian party\nAxé, Forró Eletrônico, Brazilian pop\nAxé, Forró Eletrônico, C-pop\nAxé, Forró Eletrônico, cinematic pop\nAxé, Forró Eletrônico, dance\nAxé, Forró Eletrônico, dance-pop\nAxé, Forró Eletrônico, pop-rock\nAxé, Forró, Brazilian dance\nAxé, Forró, Brazilian funk\nAxé, Forró, Brazilian gospel\nAxé, Forró, Brazilian party\nAxé, Forró, Brazilian pop\nAxé, Forró, Brazilian pop-rock\nAxé, Forró, Brazilian rock\nAxé, Forró, EDM\nAxé, Forró, MPB\nAxé, Forró, Sertanejo\nAxé, Forró, children's music\nAxé, Forró, children's pop\nAxé, Forró, dance\nAxé, Forró, electronic\nAxé, Forró, electronic dance\nAxé, Forró, funk carioca\nAxé, Forró, pop-rock\nAxé, Forró-pop\nAxé, Salsa\nAxé, Samba\nAxé, Samba, Brazilian Carnival\nAxé, Samba, Brazilian pop\nAxé, Samba, Forró\nAxé, Samba, political jingle\nAxé, Samba-Pop\nAxé, Samba-Reggae\nAxé, Samba-Reggae, Brazilian pop\nAxé, Samba-reggae\nAxé, Samba-reggae, Afro-Brazilian\nAxé, Samba-reggae, Brazilian\nAxé, Samba-reggae, Brazilian Carnival\nAxé, Samba-reggae, Brazilian ballad\nAxé, Samba-reggae, Brazilian carnival\nAxé, Samba-reggae, Brazilian folk\nAxé, Samba-reggae, Brazilian funk\nAxé, Samba-reggae, Brazilian gospel\nAxé, Samba-reggae, Brazilian pop\nAxé, Samba-reggae, Brazilian pop-rock\nAxé, Samba-reggae, C-pop\nAxé, Samba-reggae, Forró Eletrônico, R&B/soul\nAxé, Samba-reggae, Latin\nAxé, Samba-reggae, Latin dance\nAxé, Samba-reggae, MPB\nAxé, Samba-reggae, Soul\nAxé, Samba-reggae, children's gospel\nAxé, Samba-reggae, children's music\nAxé, Samba-reggae, cinematic\nAxé, Samba-reggae, dance\nAxé, Samba-reggae, dance-pop\nAxé, Samba-reggae, electronic dance\nAxé, Samba-reggae, gospel\nAxé, Samba-reggae, live performance\nAxé, Samba-reggae, piano ballad\nAxé, Samba-reggae, pop\nAxé, Samba-reggae, pop-rock\nAxé, Samba-reggae, soul\nAxé, Samba-reggae, theatrical folk\nAxé, Sertanejo\nAxé, Sertanejo, Brazilian party\nAxé, Sertanejo, Brazilian pop\nAxé, Sertanejo, Forró Eletrônico, Brazilian Funk\nAxé, Ska, Brazilian pop\nAxé, Zouk, Brazilian pop\nAxé, capoeira\nAxé, carnival\nAxé, carnival brega\nAxé, carnival pop\nAxé, carnival, Brazilian\nAxé, children's music, Brazilian\nAxé, children's music, Brazilian carnival\nAxé, children's music, carnival\nAxé, children's pop\nAxé, cinematic\nAxé, cinematic orchestral\nAxé, cinematic, Brazilian\nAxé, cinematic, devotional\nAxé, cinematic, orchestral\nAxé, dance-pop, children's music\nAxé, electronic dance\nAxé, electronic dance, Brazilian party\nAxé, electronic pop\nAxé, forró\nAxé, forró, Brazilian pop\nAxé, forró, Brazilian pop-rock\nAxé, forró, brega\nAxé, gospel, spiritual\nAxé, power ballad\nAxé, samba-reggae\nAxé, samba-reggae, Brazilian pop\nAxé, samba-reggae, pop-reggae\nAxé, smooth jazz, Brazilian pop\nAxé, synth-pop\nAxé, synth-pop, children's Christian\nAxé, synth-pop, gospel\nAxé-pop\nAzerbaijani estrada\nAzerbaijani estrada pop\nAzerbaijani estrada, cinematic, classical\nAzerbaijani folk\nAzerbaijani folk dance\nAzerbaijani folk electronic\nAzerbaijani folk hip-hop\nAzerbaijani folk pop\nAzerbaijani folk pop-rap\nAzerbaijani folk pop-rock\nAzerbaijani folk rock\nAzerbaijani folk, Latin, cinematic\nAzerbaijani folk, Russian pop\nAzerbaijani folk, cinematic pop\nAzerbaijani folk, cinematic, dramatic\nAzerbaijani folk, cinematic, modern\nAzerbaijani folk, cinematic, orchestral\nAzerbaijani folk, classical piano\nAzerbaijani folk, classical, pop-rock\nAzerbaijani folk, dance-pop\nAzerbaijani folk, dance-pop, house\nAzerbaijani folk, electronic\nAzerbaijani folk, electronic dance\nAzerbaijani folk, electronic dance, anthemic\nAzerbaijani folk, electronic dance, cinematic\nAzerbaijani folk, electronic dance, fusion\nAzerbaijani folk, electronic dance, house\nAzerbaijani folk, electronic dance, rap\nAzerbaijani folk, electronic pop\nAzerbaijani folk, electronic, cinematic\nAzerbaijani folk, electronic, hardstyle\nAzerbaijani folk, electronic, trap\nAzerbaijani folk, pop-dance\nAzerbaijani folk, pop-rock\nAzerbaijani folk, world music\nAzerbaijani folk-pop\nAzerbaijani folk-pop hip-hop\nAzerbaijani folk-pop rock\nAzerbaijani folk-pop, electronic dance\nAzerbaijani folk-pop, hard rock\nAzerbaijani folk-pop, trap\nAzerbaijani fusion\nAzerbaijani fusion pop\nAzerbaijani fusion pop-R&B\nAzerbaijani fusion pop-rock\nAzerbaijani fusion, electronic pop\nAzerbaijani fusion, pop-R&B\nAzerbaijani hip-hop\nAzerbaijani mugham\nAzerbaijani pop\nAzerbaijani pop ballad\nAzerbaijani pop chiptune\nAzerbaijani pop funk\nAzerbaijani pop retro\nAzerbaijani pop, Eurodance\nAzerbaijani pop, Eurodance, chiptune\nAzerbaijani pop, Latin, big band\nAzerbaijani pop, cinematic, ambient\nAzerbaijani pop, cinematic, electronic\nAzerbaijani pop, cinematic, folk\nAzerbaijani pop, cinematic, orchestral\nAzerbaijani pop, dance, fusion\nAzerbaijani pop, dance-pop\nAzerbaijani pop, dancehall, reggaeton\nAzerbaijani pop, electronic dance\nAzerbaijani pop, hip-hop\nAzerbaijani pop, hip-hop, R&B\nAzerbaijani pop, ney, tarabuka\nAzerbaijani pop, reggaeton\nAzerbaijani pop, reggaeton, Latin pop\nAzerbaijani pop, trap\nAzerbaijani pop-dance\nAzerbaijani pop-folk\nAzerbaijani pop-funk\nAzerbaijani pop-rap\nAzerbaijani pop-rock\nAzerbaijani pop-trap\nAzerbaijani rock\nAzerbaijani trap\nBachata\nBaila electronic\nBaile Funk\nBaião\nBalkan Christmas\nBalkan EDM\nBalkan Eurodance\nBalkan House\nBalkan R&B\nBalkan R&B trap\nBalkan Ska\nBalkan art song\nBalkan art-pop\nBalkan ballad\nBalkan ballad bossa nova\nBalkan ballad turbo-folk\nBalkan ballad, Latin salsa\nBalkan ballad, hard rock, power ballad\nBalkan ballad, pop-rock, cinematic\nBalkan beats\nBalkan blues-rock\nBalkan brass\nBalkan brass cumbia\nBalkan brass dance-pop\nBalkan brass dembow\nBalkan brass drill\nBalkan brass dubstep\nBalkan brass funk\nBalkan brass funk hip-hop\nBalkan brass funk rock\nBalkan brass funk ska\nBalkan brass funk-rock\nBalkan brass gypsy punk\nBalkan brass gypsy punk surf rock\nBalkan brass hip-hop\nBalkan brass indie rock\nBalkan brass pop\nBalkan brass pop-rock\nBalkan brass punk\nBalkan brass reggae\nBalkan brass reggae ska\nBalkan brass reggae-ska\nBalkan brass rock\nBalkan brass rockabilly\nBalkan brass ska-punk\nBalkan brass surf rock\nBalkan brass tango flamenco\nBalkan brass trap\nBalkan brass, Indian fusion, electronic\nBalkan brass, Klezmer, speed metal\nBalkan brass, Latin cumbia\nBalkan brass, Latin dance\nBalkan brass, Latin dance-pop\nBalkan brass, Latin percussion, punk rock\nBalkan brass, Latin pop\nBalkan brass, Latin pop, big band jazz\nBalkan brass, Latin salsa, French chanson\nBalkan brass, Middle Eastern folk\nBalkan brass, Portuguese fado, folk fusion\nBalkan brass, Turkish art-pop\nBalkan brass, Turkish folk, comedic\nBalkan brass, cabaret pop\nBalkan brass, cumbia, Italian rap\nBalkan brass, dance-pop\nBalkan brass, dembow, Latin dance\nBalkan brass, dub-reggae\nBalkan brass, electronic dance\nBalkan brass, electronic dance music\nBalkan brass, electronic dance, fusion\nBalkan brass, electronic dance, rap\nBalkan brass, electronic, cinematic\nBalkan brass, gypsy jazz\nBalkan brass, gypsy punk, French chanson\nBalkan brass, gypsy punk, surf rock\nBalkan brass, gypsy punk, theatrical rock\nBalkan brass, klezmer, Latin folk\nBalkan brass, klezmer, rock\nBalkan brass, klezmer, surf rock\nBalkan brass, klezmer, theatrical pop-rock\nBalkan brass, rap-rock\nBalkan brass, surf rock, polka\nBalkan brass, surf rock, rockabilly\nBalkan brass, surf rock, theatrical pop-rock\nBalkan brass-pop\nBalkan breakbeat\nBalkan cabaret\nBalkan chiptune\nBalkan club\nBalkan club-rap\nBalkan cumbia\nBalkan cumbia reggaeton\nBalkan dance\nBalkan dance pop\nBalkan dance-pop\nBalkan dance-pop hip-hop\nBalkan dance-pop tropical house\nBalkan dancehall\nBalkan disco\nBalkan disco-folk\nBalkan disco-funk\nBalkan disco-rock\nBalkan drill\nBalkan electronic\nBalkan electronic dance-pop\nBalkan electronic funk\nBalkan electronic rock\nBalkan folk\nBalkan folk Latin fusion\nBalkan folk Latin jazz\nBalkan folk ballad\nBalkan folk cabaret\nBalkan folk chiptune\nBalkan folk classical\nBalkan folk dance\nBalkan folk dance pop\nBalkan folk dance-pop\nBalkan folk electronic\nBalkan folk electronic rock\nBalkan folk electronica\nBalkan folk flamenco\nBalkan folk funk\nBalkan folk fusion\nBalkan folk hip-hop\nBalkan folk house\nBalkan folk jazz\nBalkan folk metal\nBalkan folk pop\nBalkan folk pop-rock\nBalkan folk punk\nBalkan folk reggae\nBalkan folk rock\nBalkan folk surf rock\nBalkan folk techno\nBalkan folk trap\nBalkan folk trap-pop\nBalkan folk, Arabic pop, electronic dance\nBalkan folk, Chalga\nBalkan folk, Chalga, electronic\nBalkan folk, EDM\nBalkan folk, EDM pop\nBalkan folk, Eurodance\nBalkan folk, Eurodance, anthemic\nBalkan folk, Eurodance, cinematic\nBalkan folk, Eurodance, dance-pop\nBalkan folk, Eurodance, operatic\nBalkan folk, European folk\nBalkan folk, Greek cabaret, art song\nBalkan folk, Klezmer\nBalkan folk, Klezmer, Arabic fusion\nBalkan folk, Klezmer, Latin folk\nBalkan folk, Klezmer, cinematic\nBalkan folk, Klezmer, electronic\nBalkan folk, Klezmer, instrumental\nBalkan folk, Klezmer, surf rock\nBalkan folk, Klezmer, theatrical\nBalkan folk, Klezmer, world music\nBalkan folk, Latin pop\nBalkan folk, Latin pop-rock\nBalkan folk, Latin rumba, cinematic pop\nBalkan folk, Mediterranean, world music\nBalkan folk, Middle Eastern fusion\nBalkan folk, Middle Eastern, cinematic\nBalkan folk, Middle Eastern, hip-hop\nBalkan folk, Middle Eastern, pop\nBalkan folk, Middle Eastern, spiritual\nBalkan folk, Middle Eastern, world music\nBalkan folk, Russian folk\nBalkan folk, Turkish folk-pop\nBalkan folk, Turkish music, theatrical\nBalkan folk, ambient, downtempo\nBalkan folk, big band, swing\nBalkan folk, cabaret, acoustic\nBalkan folk, cabaret, cinematic\nBalkan folk, chanson, Persian vocal\nBalkan folk, chiptune\nBalkan folk, cinematic art-song\nBalkan folk, cinematic, ambient\nBalkan folk, cinematic, classical\nBalkan folk, cinematic, electronic\nBalkan folk, cinematic, lo-fi\nBalkan folk, cinematic, ney\nBalkan folk, cinematic, operatic\nBalkan folk, cumbia, dance\nBalkan folk, dance-pop\nBalkan folk, downtempo, electronic\nBalkan folk, electronic dance\nBalkan folk, electronic dance pop\nBalkan folk, electronic dance, Manele\nBalkan folk, electronic dance, anthemic\nBalkan folk, electronic dance, cinematic\nBalkan folk, electronic dance, funk\nBalkan folk, electronic dance, fusion\nBalkan folk, electronic dance, klezmer\nBalkan folk, electronic dance, pop\nBalkan folk, electronic dance, reggaeton\nBalkan folk, electronic dance, tango\nBalkan folk, electronic pop\nBalkan folk, electronic pop, cinematic\nBalkan folk, electronic, Chalga\nBalkan folk, electronic, Manele\nBalkan folk, electronic, Middle Eastern\nBalkan folk, electronic, club\nBalkan folk, electronic, dance\nBalkan folk, electronic, festive\nBalkan folk, electronic, fusion\nBalkan folk, electronic, gypsy-punk\nBalkan folk, electronic, melancholic\nBalkan folk, gypsy jazz\nBalkan folk, gypsy jazz, acoustic\nBalkan folk, gypsy jazz, avant-garde\nBalkan folk, gypsy jazz, cabaret\nBalkan folk, gypsy jazz, cinematic\nBalkan folk, gypsy jazz, dance-pop\nBalkan folk, gypsy jazz, electronic\nBalkan folk, gypsy jazz, funk\nBalkan folk, gypsy jazz, klezmer\nBalkan folk, gypsy jazz, progressive rock\nBalkan folk, gypsy jazz, surf rock\nBalkan folk, gypsy jazz, theatrical\nBalkan folk, gypsy jazz, theatrical cabaret\nBalkan folk, gypsy jazz, world music\nBalkan folk, gypsy punk\nBalkan folk, gypsy punk, rock\nBalkan folk, gypsy punk, theatrical rock\nBalkan folk, hard dance\nBalkan folk, hard electronic, dance\nBalkan folk, hard techno\nBalkan folk, industrial, choral\nBalkan folk, klezmer, cinematic\nBalkan folk, operatic, cinematic\nBalkan folk, orchestral, cinematic\nBalkan folk, polka, chiptune\nBalkan folk, polka, dance\nBalkan folk, pop-rock, cinematic\nBalkan folk, protest rock, hip-hop\nBalkan folk, psytrance, electronic\nBalkan folk, reggae, hip-hop\nBalkan folk, reggae, ska\nBalkan folk, retro electronic\nBalkan folk, stadium rock\nBalkan folk, surf rock\nBalkan folk, surf rock, big band\nBalkan folk, surf rock, klezmer\nBalkan folk, synth-pop, Italo-disco\nBalkan folk, theatrical pop, operatic\nBalkan folk, theatrical, cinematic\nBalkan folk, theatrical, orchestral\nBalkan folk, trap, R&B\nBalkan folk, turbo-folk\nBalkan folk, turbo-folk, chiptune\nBalkan folk, turbo-folk, electronic dance\nBalkan folk, turbo-folk, pop-rock\nBalkan folk-jazz\nBalkan folk-pop\nBalkan folk-punk\nBalkan folk-rock\nBalkan folk-rock tango\nBalkan folk-trap\nBalkan funk\nBalkan funk chiptune\nBalkan funk hip-hop\nBalkan funk pop-rock\nBalkan funk rock\nBalkan funk-hop\nBalkan funk-pop\nBalkan funk-reggae\nBalkan funk-rock\nBalkan funk-ska\nBalkan fusion\nBalkan fusion dance pop\nBalkan fusion dance-pop\nBalkan fusion dancehall\nBalkan fusion funk-rock\nBalkan fusion rock\nBalkan fusion trap\nBalkan fusion, Turkish folk, dance\nBalkan fusion, electronic dance\nBalkan fusion, world music, funk rock\nBalkan gangsta rap\nBalkan gangster rap\nBalkan hard rock\nBalkan hip hop\nBalkan hip-hop\nBalkan hip-hop trap\nBalkan house\nBalkan house dance-pop\nBalkan house, Eurodance, dance-pop\nBalkan jazz\nBalkan jazz fusion\nBalkan march\nBalkan metal\nBalkan new wave\nBalkan party\nBalkan party rock\nBalkan polka\nBalkan pop\nBalkan pop Latin\nBalkan pop Latin dance\nBalkan pop Latin folk\nBalkan pop R&B\nBalkan pop ballad\nBalkan pop chalga\nBalkan pop chanson\nBalkan pop chiptune\nBalkan pop dance-pop\nBalkan pop dance-rock\nBalkan pop ethno-pop\nBalkan pop flamenco\nBalkan pop funk\nBalkan pop fusion\nBalkan pop hip-hop\nBalkan pop jazz\nBalkan pop jazz lounge\nBalkan pop moombahton\nBalkan pop nu-disco funk\nBalkan pop reggaeton\nBalkan pop rock\nBalkan pop ska\nBalkan pop surf rock\nBalkan pop tango\nBalkan pop trap\nBalkan pop turbo-folk\nBalkan pop worldbeat\nBalkan pop, Arabic pop, dance\nBalkan pop, Arabic trap\nBalkan pop, Bollywood dance\nBalkan pop, Bossa Nova\nBalkan pop, Chalga\nBalkan pop, Chalga, electronic\nBalkan pop, Chalga, electronic dance\nBalkan pop, Chalga, orchestral rock\nBalkan pop, EDM\nBalkan pop, EDM, dance-pop\nBalkan pop, EDM, electronic\nBalkan pop, EDM, hardstyle\nBalkan pop, EDM, turbo-folk\nBalkan pop, Eurodance\nBalkan pop, Eurodance, Chalga\nBalkan pop, Eurodance, Latin-pop\nBalkan pop, Eurodance, turbo-folk\nBalkan pop, German hip-hop\nBalkan pop, Latin dance\nBalkan pop, Latin dance, reggaeton\nBalkan pop, Latin folk\nBalkan pop, Latin house\nBalkan pop, Latin pop\nBalkan pop, Manele\nBalkan pop, Manele, electronic pop\nBalkan pop, Middle Eastern pop, hip-hop\nBalkan pop, chiptune, dance-pop\nBalkan pop, chiptune, hyperpop\nBalkan pop, cinematic rock\nBalkan pop, cinematic, pop-rock\nBalkan pop, cumbia, Latin pop\nBalkan pop, dance\nBalkan pop, dance, electronic\nBalkan pop, dance-pop\nBalkan pop, dance-pop, moombahton\nBalkan pop, dance-pop, pop-rock\nBalkan pop, dance-pop, reggaeton\nBalkan pop, dance-pop, turbo-folk\nBalkan pop, dancehall\nBalkan pop, dancehall, reggaeton\nBalkan pop, deep house\nBalkan pop, deep house, reggaeton\nBalkan pop, disco-funk\nBalkan pop, electro-pop\nBalkan pop, electronic dance\nBalkan pop, electronic, pop\nBalkan pop, electronic, reggaeton\nBalkan pop, ethno-pop, Latin pop\nBalkan pop, funk, disco\nBalkan pop, hard dance, EDM\nBalkan pop, hardstyle, reggaeton\nBalkan pop, hardstyle, trap\nBalkan pop, hip-hop, trap\nBalkan pop, house\nBalkan pop, hyperpop\nBalkan pop, hyperpop, chiptune\nBalkan pop, jazz, soul\nBalkan pop, lo-fi hip hop\nBalkan pop, moombahton\nBalkan pop, progressive house\nBalkan pop, reggaeton\nBalkan pop, reggaeton, Latin\nBalkan pop, reggaeton, Latin pop\nBalkan pop, reggaeton, Middle Eastern fusion\nBalkan pop, reggaeton, dance\nBalkan pop, reggaeton, dance-pop\nBalkan pop, reggaeton, dancehall\nBalkan pop, reggaeton, dembow\nBalkan pop, reggaeton, electronic\nBalkan pop, reggaeton, hip-hop\nBalkan pop, reggaeton, lo-fi\nBalkan pop, reggaeton, oriental synth\nBalkan pop, reggaeton, synth-pop\nBalkan pop, reggaeton, synthpop\nBalkan pop, reggaeton, trap\nBalkan pop, trap\nBalkan pop, trap, Middle Eastern\nBalkan pop, trap, R&B\nBalkan pop, trap, cinematic\nBalkan pop, trap, dance-pop\nBalkan pop, trap, electronic\nBalkan pop, trap, electronic dance\nBalkan pop, trap, emotional pop\nBalkan pop, trap, hyperpop\nBalkan pop, trap, lo-fi hip hop\nBalkan pop, trap, reggaeton\nBalkan pop, trap, synth\nBalkan pop, turbo-folk, dance-pop\nBalkan pop, turbo-folk, pop-rock\nBalkan pop-R&B\nBalkan pop-dance\nBalkan pop-folk\nBalkan pop-folk rock\nBalkan pop-folk, Eurodance\nBalkan pop-folk, Eurodance, dance-pop\nBalkan pop-folk, electronic dance\nBalkan pop-folk, hard rock\nBalkan pop-funk\nBalkan pop-rap\nBalkan pop-rock\nBalkan pop-rock Latin dance\nBalkan pop-rock cabaret\nBalkan pop-rock chiptune\nBalkan pop-rock jazz fusion\nBalkan pop-rock jazz-rock\nBalkan pop-rock turbo-folk\nBalkan pop-rock worldbeat\nBalkan pop-rock, cinematic synth, turbo-folk\nBalkan pop-rock, hard rock\nBalkan pop-trap\nBalkan power ballad\nBalkan power metal\nBalkan power-pop\nBalkan punk\nBalkan punk gypsy punk\nBalkan punk rock\nBalkan punk rockabilly\nBalkan punk surf rock\nBalkan punk turbo-folk\nBalkan rap\nBalkan reggae\nBalkan reggaeton\nBalkan rock\nBalkan rock fusion\nBalkan rock surf rock\nBalkan rock turbo-folk\nBalkan rockabilly\nBalkan ska-punk\nBalkan soul\nBalkan surf\nBalkan surf rock\nBalkan swing\nBalkan synth-pop\nBalkan tango\nBalkan tech house\nBalkan tech-house\nBalkan techno\nBalkan trance\nBalkan trap\nBalkan trap R&B\nBalkan trap pop\nBalkan trap reggaeton\nBalkan trap, Eurodance\nBalkan trap, emo rap, cloud rap\nBalkan trap, hard dance\nBalkan trap-folk\nBalkan trap-pop\nBalkan turbo-folk\nBalkan turbo-folk chiptune\nBalkan turbo-folk chiptune rock\nBalkan turbo-folk dance-pop\nBalkan turbo-folk drill\nBalkan turbo-folk funk\nBalkan turbo-folk funk-rock\nBalkan turbo-folk hip-hop\nBalkan turbo-folk pop-rock\nBalkan turbo-folk punk\nBalkan turbo-folk rock\nBalkan turbo-folk surf rock\nBalkan turbo-folk trap\nBalkan turbo-folk, Arabic pop\nBalkan turbo-folk, Bollywood dance\nBalkan turbo-folk, EDM\nBalkan turbo-folk, Eurodance\nBalkan turbo-folk, chiptune\nBalkan turbo-folk, chiptune rock\nBalkan turbo-folk, electronic dance\nBalkan turbo-folk, electronic hip-hop\nBalkan turbo-folk, hard rock\nBalkan turbo-folk, hard rock, 80s pop-rock\nBalkan turbo-folk, hard techno\nBalkan turbo-folk, rap-rock\nBalkan turbo-folk, speed metal\nBalkan turbo-folk, trap\nBalkan, Klezmer\nBalkan, Klezmer, instrumental\nBalkan-bap\nBalkan-funk\nBalkan-pop\nBalkan-pop dancehall\nBalkan-reggaeton\nBalkan-ska\nBallermann\nBamba\nBambora\nBambuco\nBambuco Cumbia\nBanda\nBanda Corrido\nBanda Cumbia\nBanda Sinaloense\nBanda Tlax Banda\nBanda chiptune\nBanda corrido\nBanda cumbia\nBanda cumbia, Latin pop\nBanda de Cantina\nBanda hip-hop\nBanda moderna\nBanda music\nBanda ranchera\nBanda reggaeton\nBanda rock\nBanda sinaloense\nBanda trap\nBanda, Cumbia\nBanda, Norteño\nBaroque\nBaroque C-pop\nBaroque art song\nBaroque chamber\nBaroque chiptune\nBaroque choral\nBaroque classical\nBaroque classical, chiptune\nBaroque folk\nBaroque opera\nBaroque orchestral\nBaroque organ\nBaroque pop Mandopop\nBaroque reggae\nBaroque sacred\nBaroque style\nBaroque synth\nBaroque toccata\nBaroque, neo-classical, cinematic\nBaroque-style electronic\nBaroque-style synth\nBasque folk\nBasque folk cumbia\nBasque folk, synth pop\nBasque folk-pop\nBasque folk-rock\nBasque punk rock\nBasque rock\nBasque trap\nBay Area hip-hop\nBeijing Opera\nBelly Dance\nBemba rap\nBengali EDM\nBengali acoustic ballad\nBengali ballad\nBengali cinema\nBengali dance\nBengali dance-pop\nBengali devotional\nBengali film music\nBengali film music surf rock\nBengali film song\nBengali filmi pop-rock\nBengali folk\nBengali folk EDM\nBengali folk ballad\nBengali folk chiptune\nBengali folk dance\nBengali folk electronic\nBengali folk fusion\nBengali folk pop\nBengali folk pop-rock\nBengali folk protest\nBengali folk rock\nBengali folk, Bollywood, electronic fusion\nBengali folk, Latin acoustic\nBengali folk, Latin pop\nBengali folk, chiptune\nBengali folk, chiptune, electronic dance\nBengali folk, dance-pop\nBengali folk, electronic dance\nBengali folk, electronic dance, fusion\nBengali folk, electronic dance, hip-hop\nBengali folk, electronic dance, world fusion\nBengali folk, electronic pop\nBengali folk, electronic, cinematic\nBengali folk, electronic, fusion\nBengali folk, electronic, trap\nBengali folk, hyper-electronic, dance\nBengali folk, progressive rock\nBengali folk, psychedelic rock\nBengali folk, world music, flamenco fusion\nBengali folk-fusion\nBengali folk-pop\nBengali folk-pop blues-rock\nBengali folk-pop chiptune\nBengali folk-pop funk-rock\nBengali folk-pop rock\nBengali folk-pop soft rock\nBengali folk-pop world music\nBengali folk-pop, EDM\nBengali folk-pop, Latin dance\nBengali folk-pop, electronic dance\nBengali folk-pop, hard rock\nBengali folk-rock\nBengali folk-rock synth-pop\nBengali folk-rock, classic rock\nBengali folk-rock, hard rock\nBengali folk-rock, psychedelic rock\nBengali fusion\nBengali ghazal\nBengali ghazal, cinematic ballad, emotional fusion\nBengali hip hop\nBengali hip-hop\nBengali hip-hop trap\nBengali lo-fi hip hop\nBengali pop\nBengali pop chiptune\nBengali pop dance-pop\nBengali pop folk\nBengali pop funk disco\nBengali pop fusion\nBengali pop rock\nBengali pop trap\nBengali pop, EDM\nBengali pop, EDM, dance-pop\nBengali pop, EDM, synth-pop\nBengali pop, Eurodance\nBengali pop, Indian pop, dance pop\nBengali pop, Latin Cumbia\nBengali pop, Latin cumbia\nBengali pop, Latin dance\nBengali pop, Latin funk\nBengali pop, Latin pop\nBengali pop, Latin pop, Bollywood\nBengali pop, Latin pop, Caribbean pop\nBengali pop, Latin pop, European folk\nBengali pop, Latin, big band\nBengali pop, chiptune\nBengali pop, cinematic pop, acoustic folk\nBengali pop, cumbia\nBengali pop, cumbia, Latin pop\nBengali pop, cumbia, lo-fi\nBengali pop, dance-pop, electronic\nBengali pop, dancehall, reggaeton\nBengali pop, disco, funk\nBengali pop, electronic dance\nBengali pop, electronic dance, rock fusion\nBengali pop, electronic fusion\nBengali pop, folk fusion, lo-fi\nBengali pop, lo-fi hip hop\nBengali pop, lo-fi hip hop, ballad\nBengali pop, nightcore, hyperpop\nBengali pop, reggae, dancehall\nBengali pop, reggaeton\nBengali pop, reggaeton, dream pop\nBengali pop, soft rock, world music\nBengali pop, synth-pop\nBengali pop, synth-pop, disco\nBengali pop, trap, R&B\nBengali pop, world music, synth-pop\nBengali pop-R&B\nBengali pop-funk\nBengali pop-rap\nBengali pop-rock\nBengali pop-rock, electronic dance\nBengali pop-rock, hard rock\nBengali pop-rock, synth-pop\nBengali pop-trap\nBengali rock\nBengali rock fusion\nBengali rock reggae ska\nBengali rock, Latin rock\nBengali spoken word\nBengali trap\nBhajan\nBhajan Bhangra\nBhajan Bollywood\nBhajan EDM\nBhajan House\nBhajan Qawwali\nBhajan chiptune\nBhajan dance-pop\nBhajan electronic\nBhajan fusion\nBhajan pop\nBhajan, Bollywood dance-pop\nBhajan, Bollywood pop\nBhajan, Bollywood, Bhangra\nBhajan, Bollywood, Electronic\nBhajan, Bollywood, Indian pop\nBhajan, Bollywood, cinematic\nBhajan, Bollywood, electronic\nBhajan, Bollywood-pop\nBhajan, EDM, Indian pop\nBhajan, Indian folk, Bollywood\nBhajan, Indian pop, Bollywood\nBhajan, dance-pop\nBhajan, dance-pop, EDM\nBhajan, dance-pop, electronic\nBhajan, electronic dance music\nBhajan-EDM\nBhangra\nBhangra Amapiano\nBhangra Arabic pop\nBhangra Bhajan\nBhangra Bollywood\nBhangra Christian\nBhangra Dancehall\nBhangra EDM\nBhangra EDM trap\nBhangra EDM-pop\nBhangra Eurodance\nBhangra Haryanvi\nBhangra House\nBhangra Latin\nBhangra Latin dance-pop\nBhangra Latin fusion\nBhangra Latin pop\nBhangra Moombahton\nBhangra Reggae\nBhangra Soca\nBhangra Sufi\nBhangra UK garage\nBhangra acid jazz\nBhangra bhajan\nBhangra big beat\nBhangra children's\nBhangra chiptune\nBhangra cinematic\nBhangra club\nBhangra dance\nBhangra dance-pop\nBhangra dancehall\nBhangra dancehall chiptune\nBhangra dancehall hip hop\nBhangra dancehall pop\nBhangra dancehall reggae\nBhangra devotional\nBhangra disco\nBhangra drill\nBhangra drum and bass\nBhangra electro house\nBhangra electro-funk\nBhangra electro-pop\nBhangra electroclash\nBhangra electronic\nBhangra electronic funk\nBhangra electronica\nBhangra folk\nBhangra folk fusion\nBhangra folk pop\nBhangra folk, Indian folk ballad\nBhangra folk, pop-rock\nBhangra folk-pop\nBhangra folk-rock\nBhangra funk\nBhangra funk electronic\nBhangra funk-hop\nBhangra funk-pop\nBhangra funk-rock\nBhangra fusion\nBhangra fusion, New Jack Swing\nBhangra fusion, hip-hop, EDM\nBhangra fusion, vintage electronic, retro dance\nBhangra garage\nBhangra gospel\nBhangra grime hip-hop\nBhangra happy hardcore\nBhangra hard dance\nBhangra hardcore\nBhangra hardstyle\nBhangra hardstyle trap\nBhangra hip hop\nBhangra hip-hop\nBhangra hip-hop electronic\nBhangra hip-hop reggaeton\nBhangra house\nBhangra hyperpop\nBhangra jazz\nBhangra jungle\nBhangra moombahton\nBhangra neurofunk\nBhangra new jack swing\nBhangra nu-metal\nBhangra pop\nBhangra pop rap\nBhangra pop, Bollywood dance, electronic fusion\nBhangra pop, Bollywood funk\nBhangra pop, Bollywood fusion, electronic dance\nBhangra pop, Punjabi pop, electronic\nBhangra pop, stadium rock\nBhangra pop-funk\nBhangra pop-rock\nBhangra rap-rock\nBhangra reggae\nBhangra reggaeton\nBhangra rock\nBhangra surf rock\nBhangra techno\nBhangra trap\nBhangra, Arabic pop, electronic dance\nBhangra, Bollywood\nBhangra, Bollywood, Christian devotional\nBhangra, Bollywood, EDM\nBhangra, Bollywood, Indian Christian\nBhangra, Bollywood, Indian bhajan\nBhangra, Bollywood, Indian devotional\nBhangra, Bollywood, chiptune\nBhangra, Bollywood, cinematic\nBhangra, Bollywood, dance\nBhangra, Bollywood, dance-pop\nBhangra, Bollywood, devotional\nBhangra, Bollywood, electronic\nBhangra, Bollywood, electronic devotional\nBhangra, Bollywood, hardstyle\nBhangra, Bollywood, party\nBhangra, Bollywood, political anthem\nBhangra, Bollywood, romantic\nBhangra, Desi Hip Hop\nBhangra, Desi Hip Hop, Dance-Pop\nBhangra, Desi Hip Hop, Dancehall\nBhangra, Desi Hip Hop, EDM\nBhangra, Desi club\nBhangra, Desi folk, cinematic\nBhangra, Desi hip-hop\nBhangra, Desi pop\nBhangra, Desi pop, electronic\nBhangra, Desi pop, electronic dance\nBhangra, EDM, pop\nBhangra, EDM, trap\nBhangra, Ghazal, World Fusion\nBhangra, Indian classical\nBhangra, Indian classical, cinematic\nBhangra, Indian classical, electronic\nBhangra, Indian classical, ghazal\nBhangra, Indian classical, pop\nBhangra, Indian devotional, Bollywood\nBhangra, Indian folk\nBhangra, Indian folk, Bollywood\nBhangra, Indian folk, cinematic\nBhangra, Indian folk, electronic\nBhangra, Indian folk, electronic dance\nBhangra, Indian fusion, electronic\nBhangra, New Jack Swing\nBhangra, Punjabi Pop\nBhangra, Punjabi folk\nBhangra, Punjabi folk, ambient\nBhangra, Punjabi folk, pop\nBhangra, Punjabi folk, world fusion\nBhangra, Punjabi pop\nBhangra, Punjabi pop, Bollywood, hip-hop\nBhangra, Punjabi pop, electronic\nBhangra, Punjabi pop, hip-hop\nBhangra, Punjabi, devotional\nBhangra, R&B, cinematic\nBhangra, R&B, trap\nBhangra, Sufi, South Asian pop\nBhangra, UK drill, Bollywood\nBhangra, World Fusion\nBhangra, World Fusion, Ambient\nBhangra, ambient folk\nBhangra, ambient, traditional Indian\nBhangra, children's music, pop\nBhangra, chiptune, Bollywood\nBhangra, chiptune, cinematic\nBhangra, chiptune, electronic\nBhangra, chiptune, electronic dance\nBhangra, cinematic, Indian classical\nBhangra, cinematic, Indian folk\nBhangra, cinematic, Indian fusion\nBhangra, cinematic, South Asian\nBhangra, cinematic, ambient fusion\nBhangra, cinematic, devotional\nBhangra, cinematic, electronic\nBhangra, cinematic, epic\nBhangra, cinematic, folk\nBhangra, cinematic, folk fusion\nBhangra, cinematic, melancholic\nBhangra, cinematic, orchestral\nBhangra, devotional, Indian classical\nBhangra, devotional, electronic\nBhangra, electronic\nBhangra, electronic dance\nBhangra, electronic dance, Bollywood\nBhangra, electronic dance, Indian pop\nBhangra, electronic dance, fusion\nBhangra, electronic dance, hip hop\nBhangra, electronic dance, hip-hop\nBhangra, electronic dance, hyperpop\nBhangra, electronic, Bollywood\nBhangra, electronic, Indian classical\nBhangra, electronic, cinematic\nBhangra, electronic, devotional\nBhangra, electronic, folk\nBhangra, electronic, folk fusion\nBhangra, electronic, fusion\nBhangra, electronic, hip-hop\nBhangra, electronic, pop\nBhangra, folk, cinematic\nBhangra, folk, devotional\nBhangra, folk, electronic\nBhangra, folk, traditional South Asian\nBhangra, happy hardcore\nBhangra, hard electronic\nBhangra, hard electronic, dance\nBhangra, hardstyle\nBhangra, hip-hop, Bollywood\nBhangra, hip-hop, R&B\nBhangra, hip-hop, pop\nBhangra, hip-hop, trap\nBhangra, moombahton, electronic\nBhangra, synth-pop\nBhangra, trap, R&B\nBhangra, trap, electronic\nBhangra, vintage Bollywood, energetic\nBhangra, world fusion\nBhangra, world fusion, cinematic\nBhangra-EDM\nBhangra-EDM fusion\nBhangra-electronic\nBhangra-funk\nBhangra-pop\nBhangra-pop Bollywood\nBhangra-pop EDM\nBhangra-pop chiptune\nBhangra-pop electronic\nBhangra-pop hip-hop\nBhangra-pop, EDM, cinematic\nBhangra-pop, Hindi pop, R&B\nBhangra-pop, cinematic, folk\nBhangra-pop, electronic dance\nBhangra-pop, hip-hop\nBhangra-pop, hip-hop, folk\nBhangra-rock\nBhangra-trap\nBhangra-trap fusion\nBhojpuri\nBhojpuri Bhajan\nBhojpuri Christian Bhajan\nBhojpuri Christian EDM\nBhojpuri Christian dance\nBhojpuri DJ\nBhojpuri DJ remix\nBhojpuri EDM\nBhojpuri Eurodance\nBhojpuri Holi\nBhojpuri bhajan\nBhojpuri chiptune\nBhojpuri club\nBhojpuri cumbia\nBhojpuri dance\nBhojpuri dance pop\nBhojpuri dance, Bollywood, electronic\nBhojpuri dance, EDM\nBhojpuri dance, EDM, dance-pop\nBhojpuri dance, chiptune, Eurodance\nBhojpuri dance, chiptune, electronic\nBhojpuri dance, electronic folk\nBhojpuri dance, happy hardcore\nBhojpuri dance, hardstyle\nBhojpuri dance, hardstyle, happy hardcore\nBhojpuri dance, hyperpop\nBhojpuri dance, trap\nBhojpuri dance-pop\nBhojpuri devotional\nBhojpuri devotional, electronic\nBhojpuri devotional, electronic dance\nBhojpuri disco\nBhojpuri electronic\nBhojpuri electronic pop\nBhojpuri electronic rock\nBhojpuri festival\nBhojpuri film song\nBhojpuri folk\nBhojpuri folk chiptune\nBhojpuri folk dance\nBhojpuri folk fusion\nBhojpuri folk, EDM\nBhojpuri folk, chiptune\nBhojpuri folk, chiptune, EDM\nBhojpuri folk, chiptune, electro-folk\nBhojpuri folk, chiptune, electro-pop\nBhojpuri folk, chiptune, electronic\nBhojpuri folk, chiptune, electronic dance\nBhojpuri folk, chiptune, hyperpop\nBhojpuri folk, electronic\nBhojpuri folk, electronic dance\nBhojpuri folk, electronic dance, chiptune\nBhojpuri folk, electronic dance, devotional\nBhojpuri folk, electronic dance, hip-hop\nBhojpuri folk, electronic, aggro\nBhojpuri folk, electronic, devotional\nBhojpuri folk, funkot, electronic dance\nBhojpuri folk, happy hardcore\nBhojpuri folk, hard electronic\nBhojpuri folk, hard electronic, EDM\nBhojpuri folk, hard electronic, dance\nBhojpuri folk, hard electronic, rave\nBhojpuri folk, hard trance\nBhojpuri folk, hardstyle\nBhojpuri folk, hardstyle, EDM\nBhojpuri folk, hardstyle, electronic dance\nBhojpuri folk, hyper-electro\nBhojpuri folk, hyper-electro, chiptune\nBhojpuri folk, hyper-electronic\nBhojpuri folk, hyper-electronic, dance\nBhojpuri folk, hyper-speed EDM\nBhojpuri folk, hyperpop, electronic dance\nBhojpuri folk, moombahton\nBhojpuri folk, moombahton, electronic dance\nBhojpuri folk, retro electronic\nBhojpuri folk, retro electronic, dance\nBhojpuri folk-pop\nBhojpuri folk-pop, R&B\nBhojpuri folk-pop, chiptune, electronic dance\nBhojpuri folk-pop, electronic dance\nBhojpuri fusion\nBhojpuri fusion, electronic dance-pop\nBhojpuri hardstyle\nBhojpuri hip hop\nBhojpuri hip-hop\nBhojpuri hip-hop, electronic dance, fusion\nBhojpuri house\nBhojpuri hyperpop\nBhojpuri moombahton\nBhojpuri party\nBhojpuri pop\nBhojpuri pop chiptune\nBhojpuri pop, Bollywood pop, electronic dance\nBhojpuri pop, EDM\nBhojpuri pop, EDM, dance-pop\nBhojpuri pop, chiptune EDM\nBhojpuri pop, cinematic, electronic\nBhojpuri pop, cinematic, orchestral\nBhojpuri pop, dance-pop\nBhojpuri pop, electronic dance\nBhojpuri pop, electronic, cinematic\nBhojpuri pop, electronic, folk fusion\nBhojpuri pop, hard dance, Indian classical\nBhojpuri pop, hardstyle, EDM\nBhojpuri pop, reggaeton, ambient\nBhojpuri pop, trap, cinematic\nBhojpuri pop-rap\nBhojpuri pop-rock\nBhojpuri protest\nBhojpuri remix\nBhojpuri rock\nBhojpuri surf rock\nBhojpuri techno\nBhojpuri trance\nBhojpuri trap\nBhojpuri trap-pop\nBhojpuri, Bollywood, Indian classical\nBhojpuri, Bollywood, folk dance\nBhojpuri, Bollywood, patriotic\nBhojpuri, Holi, dance\nBhojpuri, Holi, festive\nBhojpuri, Holi, folk dance\nBhojpuri, dance, electronic\nBhojpuri, dance, festival\nBhojpuri, dance, festive\nBhojpuri, electronic dance\nBhojpuri, electronic dance music\nBhojpuri, electronic, Holi\nBhojpuri, electronic, dance\nBhojpuri, electronic, devotional\nBhojpuri, electronic, festival\nBhojpuri, electronic, festive\nBhojpuri, electronic, moombahton\nBhojpuri, electronic, party\nBhojpuri, festival, electronic\nBhojpuri, festive, dholak\nBhojpuri, festive, electronic\nBilingual ballad\nBilingual pop, Brazilian R&B\nBilingual pop, Brazilian reggae\nBilingual pop, Brazilian, R&B\nBoi-Bumbá\nBoi-Bumbá Cumbia\nBoi-Bumbá Forró\nBoi-Bumbá Sertanejo\nBoi-Bumbá Sertanejo de Raiz\nBolero\nBolero Bossa Nova\nBolero MPB\nBolero brega\nBolero samba\nBolero, Brega\nBolero, Gospel, Brazilian ballad\nBolero, Samba, Cinematic\nBolero, samba-romântico, cinematic\nBollywood\nBollywood 90s\nBollywood Bhangra\nBollywood Christian\nBollywood Christian devotional\nBollywood Cumbia\nBollywood Dancehall\nBollywood EDM\nBollywood EDM Latin\nBollywood EDM hardstyle\nBollywood EDM hip-hop\nBollywood EDM trap\nBollywood Eurodance\nBollywood Eurodance chiptune\nBollywood Flamenco fusion\nBollywood Ghazal\nBollywood Indipop\nBollywood Latin\nBollywood Latin fusion\nBollywood Latin jazz\nBollywood Latin pop\nBollywood Moombahton\nBollywood R&B\nBollywood R&B fusion\nBollywood R&B trap\nBollywood Soca\nBollywood UK garage drum and bass\nBollywood acoustic\nBollywood action\nBollywood ambient\nBollywood ballad\nBollywood ballad, dance-pop, cinematic\nBollywood ballad, electronic, hip-hop\nBollywood ballad, folk fusion, Bhangra\nBollywood ballad, trap, cinematic\nBollywood bhajan\nBollywood bhangra\nBollywood big band\nBollywood breakbeat\nBollywood breakcore\nBollywood cha-cha-chá\nBollywood children's\nBollywood children's music\nBollywood chiptune\nBollywood chiptune breakcore\nBollywood chiptune electro-pop\nBollywood chiptune funk\nBollywood cinematic\nBollywood cinematic pop\nBollywood classic\nBollywood classical\nBollywood club\nBollywood club, Haryanvi dance\nBollywood club, electronic dance\nBollywood cumbia\nBollywood dance\nBollywood dance chiptune\nBollywood dance funk-pop\nBollywood dance pop\nBollywood dance ragga\nBollywood dance remix\nBollywood dance soca\nBollywood dance, 2000s EDM, fusion\nBollywood dance, 80s synth, retro pop\nBollywood dance, 90s Eurodance\nBollywood dance, 90s electronic\nBollywood dance, 90s electronic, hip-hop\nBollywood dance, 90s house\nBollywood dance, 90s trance, Eurodance\nBollywood dance, Arabic pop\nBollywood dance, Arabic pop, electronic\nBollywood dance, Bhangra\nBollywood dance, Bhangra, Desi pop\nBollywood dance, Bhangra, Eurodance\nBollywood dance, Bhangra, devotional\nBollywood dance, Bhangra, electronic\nBollywood dance, Bhangra, electronic club\nBollywood dance, Bhangra-pop, electronic\nBollywood dance, Dappan Koothu, electronic\nBollywood dance, Dappan Koothu, electronic fusion\nBollywood dance, EDM\nBollywood dance, EDM trap\nBollywood dance, EDM, hip-hop\nBollywood dance, Eurodance\nBollywood dance, Eurodance, Bhangra\nBollywood dance, Eurodance, chiptune\nBollywood dance, Eurodance, happy hardcore\nBollywood dance, Eurodance, trance\nBollywood dance, Italo-disco, synth-pop\nBollywood dance, Latin cumbia, electronic\nBollywood dance, Latin dance\nBollywood dance, Latin funk\nBollywood dance, Latin fusion\nBollywood dance, Latin percussion\nBollywood dance, Latin percussion, electronic\nBollywood dance, Latin pop\nBollywood dance, Latin, salsa\nBollywood dance, Middle Eastern fusion\nBollywood dance, breakbeat, electronic\nBollywood dance, chiptune\nBollywood dance, chiptune, Bhangra\nBollywood dance, chiptune, electro-funk\nBollywood dance, chiptune, electro-pop\nBollywood dance, chiptune, electronic\nBollywood dance, chiptune, happy hardcore\nBollywood dance, chiptune, trap\nBollywood dance, electronic\nBollywood dance, electronic pop\nBollywood dance, electronic, EDM\nBollywood dance, electronic, chiptune\nBollywood dance, electronic, club\nBollywood dance, electronic, funk\nBollywood dance, electronic, fusion\nBollywood dance, electronic, pop\nBollywood dance, electronic, pop-rap\nBollywood dance, funk, disco\nBollywood dance, happy hardcore\nBollywood dance, happy hardcore, chiptune\nBollywood dance, happy hardcore, trance\nBollywood dance, hard electronic\nBollywood dance, hard house\nBollywood dance, hard techno\nBollywood dance, hard trance\nBollywood dance, hardstyle EDM\nBollywood dance, hardstyle, EDM\nBollywood dance, moombahton\nBollywood dance, moombahton, electronic\nBollywood dance, new jack swing, Bhangra\nBollywood dance, nightcore, happy hardcore\nBollywood dance, progressive trance\nBollywood dance, reggaeton\nBollywood dance, reggaeton, electronic\nBollywood dance, retro electronic\nBollywood dance, retro-futuristic\nBollywood dance, retro-futuristic, disco-funk\nBollywood dance, retro-futuristic, electro\nBollywood dance, retro-futuristic, electronic\nBollywood dance, synth-pop, retro\nBollywood dance-pop\nBollywood dance-pop EDM\nBollywood dance-pop Eurodance\nBollywood dance-pop chiptune\nBollywood dance-pop electronic rock\nBollywood dance-pop funk\nBollywood dance-pop funk ska\nBollywood dance-pop funk-rock\nBollywood dance-pop hip-hop\nBollywood dance-pop moombahton\nBollywood dance-pop nu-metal\nBollywood dance-pop reggae\nBollywood dance-pop reggae-dancehall\nBollywood dance-pop reggaeton\nBollywood dance-pop rock\nBollywood dance-pop, 90s Eurodance\nBollywood dance-pop, Bhangra, trap, drill\nBollywood dance-pop, EDM\nBollywood dance-pop, EDM, trap\nBollywood dance-pop, Eurodance\nBollywood dance-pop, Latin percussion\nBollywood dance-pop, Middle Eastern electronic\nBollywood dance-pop, R&B\nBollywood dance-pop, ambient rock\nBollywood dance-pop, big band swing\nBollywood dance-pop, big beat\nBollywood dance-pop, breakbeat\nBollywood dance-pop, chiptune EDM\nBollywood dance-pop, chiptune electro\nBollywood dance-pop, cinematic orchestral\nBollywood dance-pop, early 2000s electronic\nBollywood dance-pop, electronic\nBollywood dance-pop, happy hardcore\nBollywood dance-pop, hard rock\nBollywood dance-pop, hardstyle\nBollywood dance-pop, hardstyle EDM\nBollywood dance-pop, hardstyle, electronic\nBollywood dance-pop, hip-hop\nBollywood dance-pop, house, hip-house\nBollywood dance-pop, moombahton, EDM\nBollywood dance-rock\nBollywood dancehall\nBollywood devotional\nBollywood disco\nBollywood disco funk\nBollywood disco fusion\nBollywood disco, Middle Eastern pop\nBollywood disco, chiptune\nBollywood disco, funk, worldbeat\nBollywood disco, synth-pop, Italo-disco\nBollywood disco, synth-pop, chiptune\nBollywood disco-funk\nBollywood disco-pop\nBollywood disco-rock\nBollywood electro\nBollywood electro house\nBollywood electro-pop\nBollywood electro-swing\nBollywood electronic\nBollywood electronic rock\nBollywood electronica\nBollywood electropop\nBollywood epic\nBollywood film music\nBollywood film music, 80s synth-pop, devotional\nBollywood film music, worldbeat, electronic lounge\nBollywood film score\nBollywood film score lounge jazz\nBollywood film song\nBollywood filmi\nBollywood filmi ghazal\nBollywood filmi lo-fi\nBollywood filmi pop\nBollywood filmi, Bhangra, folk fusion\nBollywood filmi, cinematic, Indian classical\nBollywood filmi, devotional dance, retro Indian\nBollywood filmi, electronic dance, cinematic\nBollywood filmi-pop\nBollywood folk\nBollywood folk-pop\nBollywood funk\nBollywood funk Latin\nBollywood funk Latin jazz\nBollywood funk big band\nBollywood funk chiptune\nBollywood funk disco\nBollywood funk electronic rock\nBollywood funk hip-hop\nBollywood funk rock\nBollywood funk soul\nBollywood funk, psychedelic rock\nBollywood funk-pop\nBollywood funk-rock\nBollywood funk-rock electronic\nBollywood fusion\nBollywood fusion gypsy jazz\nBollywood fusion rock\nBollywood fusion, Bhangra, chiptune\nBollywood fusion, Latin dance\nBollywood fusion, Latin mambo, lo-fi synth\nBollywood fusion, Latin rhythm\nBollywood fusion, cinematic EDM, trap\nBollywood fusion, experimental, eclectic\nBollywood fusion, moombahton, Indian classical\nBollywood future bass\nBollywood ghazal\nBollywood gospel\nBollywood happy hardcore\nBollywood hard dance\nBollywood hardstyle\nBollywood hardstyle trap\nBollywood hip hop\nBollywood hip-hop\nBollywood hip-hop EDM\nBollywood hip-hop chiptune\nBollywood hip-hop dance-pop\nBollywood hip-hop electronic\nBollywood hip-hop funk\nBollywood hip-hop funk-rock\nBollywood hip-hop fusion\nBollywood hip-hop moombahton\nBollywood hip-hop pop\nBollywood hip-hop, Latin pop, funk\nBollywood hip-hop, moombahton\nBollywood house\nBollywood hyperpop\nBollywood hyperpop chiptune\nBollywood jazz\nBollywood jazz fusion\nBollywood jazz lounge\nBollywood jazz-pop\nBollywood jungle\nBollywood kuthu\nBollywood lo-fi\nBollywood lo-fi chillwave\nBollywood lo-fi hip hop\nBollywood lo-fi hip-hop\nBollywood lounge\nBollywood lullaby\nBollywood mambo\nBollywood mashup\nBollywood metal\nBollywood moombahton\nBollywood novelty\nBollywood nu-metal\nBollywood orchestral\nBollywood orchestral pop\nBollywood party rock funk\nBollywood playback\nBollywood playback, cinematic, R&B\nBollywood pop\nBollywood pop Arabic pop\nBollywood pop Arabic pop electronic dance\nBollywood pop Arabic pop reggaeton\nBollywood pop EDM\nBollywood pop EDM hip-hop\nBollywood pop Eurodance\nBollywood pop European folk\nBollywood pop K-pop trap\nBollywood pop Latin\nBollywood pop Latin dance\nBollywood pop Latin fusion\nBollywood pop Latin jazz\nBollywood pop R&B\nBollywood pop R&B funk\nBollywood pop Soca\nBollywood pop alternative rock\nBollywood pop chiptune\nBollywood pop dance\nBollywood pop dance-pop\nBollywood pop dancehall\nBollywood pop dancehall chiptune\nBollywood pop electronic\nBollywood pop funk\nBollywood pop funk disco\nBollywood pop funk hip-hop\nBollywood pop funk-rock\nBollywood pop funk-rock electronic dance\nBollywood pop fusion\nBollywood pop future bass\nBollywood pop hip-hop\nBollywood pop hyperpop\nBollywood pop hyperpop chiptune\nBollywood pop jazz\nBollywood pop lo-fi hip-hop\nBollywood pop lounge\nBollywood pop moombahton\nBollywood pop orchestral\nBollywood pop progressive house\nBollywood pop rap\nBollywood pop reggaeton\nBollywood pop rock\nBollywood pop surf rock\nBollywood pop synth-pop\nBollywood pop synth-rock\nBollywood pop trance\nBollywood pop trap\nBollywood pop trap-R&B\nBollywood pop world music\nBollywood pop, Arabic dance, EDM\nBollywood pop, Arabic pop, electronic\nBollywood pop, Arabic pop, electronic dance\nBollywood pop, Arabic pop, hip-hop\nBollywood pop, Bengali pop, electronic rock\nBollywood pop, Bengali pop, world music\nBollywood pop, Bhangra EDM\nBollywood pop, Bhangra, Arabic pop\nBollywood pop, Bhangra, EDM\nBollywood pop, Bhangra, Western pop\nBollywood pop, Bhangra, chiptune\nBollywood pop, Bhangra, dancehall\nBollywood pop, Bhangra, hip-hop\nBollywood pop, Bhojpuri pop, rock\nBollywood pop, Christian rock\nBollywood pop, Christian worship\nBollywood pop, Christmas pop\nBollywood pop, EDM\nBollywood pop, EDM trap\nBollywood pop, EDM trap, hardstyle\nBollywood pop, EDM, chiptune\nBollywood pop, EDM, dance-pop\nBollywood pop, EDM, future bass\nBollywood pop, EDM, hip-hop\nBollywood pop, EDM, trap\nBollywood pop, Eurodance, hip-hop\nBollywood pop, Indian classical, cinematic\nBollywood pop, Indian fusion, hip-hop\nBollywood pop, Islamic devotional\nBollywood pop, Latin acoustic\nBollywood pop, Latin dance\nBollywood pop, Latin dance, fusion\nBollywood pop, Latin funk\nBollywood pop, Latin funk, dance\nBollywood pop, Latin fusion\nBollywood pop, Latin gospel\nBollywood pop, Latin hip-hop\nBollywood pop, Latin pop\nBollywood pop, Latin pop, reggaeton\nBollywood pop, Latin, Bhangra\nBollywood pop, Latin, retro\nBollywood pop, Middle Eastern dance\nBollywood pop, Middle Eastern pop\nBollywood pop, New Jack Swing, R&B\nBollywood pop, Punjabi Pop, Moombahton\nBollywood pop, Punjabi pop, electronic\nBollywood pop, Punjabi pop, festive\nBollywood pop, Punjabi pop, trap\nBollywood pop, R&B\nBollywood pop, R&B, cinematic\nBollywood pop, R&B, electronic\nBollywood pop, R&B, hip-hop\nBollywood pop, big room house, operatic\nBollywood pop, boom-bap hip-hop, cinematic\nBollywood pop, chiptune\nBollywood pop, chiptune EDM\nBollywood pop, chiptune, EDM\nBollywood pop, chiptune, electronic\nBollywood pop, chiptune, electronic dance\nBollywood pop, chiptune, hip-hop\nBollywood pop, chiptune, hyperpop\nBollywood pop, chiptune, trap\nBollywood pop, cinematic pop-rock\nBollywood pop, cinematic score\nBollywood pop, cinematic, synth-pop\nBollywood pop, dance, electronic\nBollywood pop, dance-pop\nBollywood pop, dance-pop, ambient\nBollywood pop, dance-pop, hip-hop\nBollywood pop, dance-pop, rock\nBollywood pop, dancehall\nBollywood pop, dancehall, reggae\nBollywood pop, electronic R&B\nBollywood pop, electronic dance\nBollywood pop, electronic dance music\nBollywood pop, electronic dance, fusion\nBollywood pop, electronic dance, hard-hitting\nBollywood pop, electronic dance, hip-hop\nBollywood pop, electronic dance, rock\nBollywood pop, electronic pop\nBollywood pop, electronic trap\nBollywood pop, electronic, ambient\nBollywood pop, folk fusion, cinematic\nBollywood pop, funk, R&B\nBollywood pop, funk, electronic dance\nBollywood pop, future bass, EDM\nBollywood pop, future bass, trap\nBollywood pop, hard rock\nBollywood pop, hard rock, EDM\nBollywood pop, hard rock, moombahton\nBollywood pop, hardstyle\nBollywood pop, hardstyle, EDM\nBollywood pop, hardstyle, hyperpop\nBollywood pop, hip-hop\nBollywood pop, hip-hop, breakbeat\nBollywood pop, hip-hop, electronic\nBollywood pop, hip-hop, electronic dance\nBollywood pop, hip-hop, funk\nBollywood pop, hip-hop, rock\nBollywood pop, hyperpop, EDM\nBollywood pop, hyperpop, electronic dance\nBollywood pop, late-90s hip-hop\nBollywood pop, moombahton\nBollywood pop, pop-bhangra\nBollywood pop, progressive house, trance\nBollywood pop, reggaeton\nBollywood pop, reggaeton, electronic\nBollywood pop, reggaeton, pop\nBollywood pop, stadium rock, EDM\nBollywood pop, synth-pop, chiptune\nBollywood pop, trap\nBollywood pop, trap, EDM\nBollywood pop, trap, Indian folk\nBollywood pop, trap, K-pop\nBollywood pop, trap, R&B\nBollywood pop, trap, chiptune\nBollywood pop, trap-R&B\nBollywood pop-folk\nBollywood pop-funk\nBollywood pop-fusion\nBollywood pop-rap\nBollywood pop-rock\nBollywood pop-rock chiptune\nBollywood pop-rock folk metal\nBollywood pop-rock funk\nBollywood pop-rock funk-rock\nBollywood pop-rock, Latin acoustic\nBollywood pop-rock, electronic dance\nBollywood pop-rock, electronic dance, fusion\nBollywood pop-rock, surf rock\nBollywood power ballad\nBollywood progressive house\nBollywood psychedelic\nBollywood psychedelic rock\nBollywood punk\nBollywood qawwali\nBollywood rap, EDM, dubstep\nBollywood reggae\nBollywood reggae fusion\nBollywood reggae ska\nBollywood reggaeton\nBollywood remix\nBollywood remix, Bhojpuri, electronic dance\nBollywood retro\nBollywood retro-funk\nBollywood retro-funk surf rock\nBollywood rock\nBollywood rock blues rock\nBollywood rock cinematic\nBollywood rock folk metal\nBollywood rock funk\nBollywood rock funk metal\nBollywood rock nu-metal\nBollywood rock surf rock\nBollywood rock, Bhangra\nBollywood rock, electronic dance\nBollywood romantic\nBollywood romantic ballad\nBollywood sad song\nBollywood salsa\nBollywood show tune\nBollywood ska\nBollywood ska-funk\nBollywood soundtrack\nBollywood surf rock\nBollywood surf rock Latin fusion\nBollywood surf rock big band\nBollywood surf-rock\nBollywood swing\nBollywood swing surf rock\nBollywood swing-pop\nBollywood synth\nBollywood synth-pop\nBollywood techno\nBollywood trance\nBollywood trance-pop\nBollywood trap\nBollywood trap R&B\nBollywood trap lo-fi\nBollywood trap lo-fi hip-hop\nBollywood trap pop\nBollywood trip-hop\nBollywood vintage\nBollywood world music\nBollywood worship\nBollywood, Bhangra, Arabic pop\nBollywood, Bhangra, EDM\nBollywood, Bhangra, Indian classical\nBollywood, Bhangra, Indian devotional\nBollywood, Bhangra, Indian patriotic\nBollywood, Bhangra, Indian political anthem\nBollywood, Bhangra, Islamic devotional\nBollywood, Bhangra, chiptune\nBollywood, Bhangra, dance\nBollywood, Bhangra, devotional\nBollywood, Bhangra, devotional pop\nBollywood, Bhangra, disco\nBollywood, Bhangra, electronic\nBollywood, Bhangra, electronic dance\nBollywood, Bhangra, hardstyle\nBollywood, Bhangra, synth-pop\nBollywood, Bhangra-pop\nBollywood, Bhojpuri, electronic\nBollywood, Bhojpuri, folk dance\nBollywood, Christian bhajan\nBollywood, Christian devotional\nBollywood, Christian devotional, South Asian\nBollywood, Christian, festive\nBollywood, EDM, pop-rock\nBollywood, EDM, romantic\nBollywood, European fusion\nBollywood, Gujarati, electronic\nBollywood, Haryanvi folk\nBollywood, Indian Christian, devotional\nBollywood, Indian bhajan\nBollywood, Indian classical, worldbeat\nBollywood, Indian folk\nBollywood, Indian folk, rock, dance-pop, pop-ballad\nBollywood, Indian folk, upbeat\nBollywood, Indian pop, filmi\nBollywood, Latin\nBollywood, Latin big band\nBollywood, Latin dance\nBollywood, Latin dance, folk fusion\nBollywood, Latin funk, disco\nBollywood, Latin fusion\nBollywood, Latin groove\nBollywood, Latin jazz, lounge\nBollywood, Latin mambo, retro\nBollywood, Latin pop\nBollywood, Latin pop, dance\nBollywood, Latin pop, folk fusion\nBollywood, Latin, Cumbia\nBollywood, Latin, European\nBollywood, Latin, Exotica\nBollywood, Latin, Flamenco\nBollywood, Latin, Mambo\nBollywood, Latin, Middle Eastern\nBollywood, Latin, accordion\nBollywood, Latin, acoustic\nBollywood, Latin, big band\nBollywood, Latin, cha-cha-chá\nBollywood, Latin, cinematic\nBollywood, Latin, dance\nBollywood, Latin, devotional\nBollywood, Latin, disco\nBollywood, Latin, eclectic\nBollywood, Latin, electronic\nBollywood, Latin, film score\nBollywood, Latin, flamenco\nBollywood, Latin, folk\nBollywood, Latin, funk\nBollywood, Latin, fusion\nBollywood, Latin, groove\nBollywood, Latin, jazz\nBollywood, Latin, mambo\nBollywood, Latin, orchestral\nBollywood, Latin, pop\nBollywood, Latin, psychedelic\nBollywood, Latin, retro\nBollywood, Latin, retro synth\nBollywood, Latin, surf rock\nBollywood, Latin, surf-rock\nBollywood, Latin, synth funk\nBollywood, Latin, synth pop\nBollywood, Latin, theatrical\nBollywood, Latin, upbeat\nBollywood, Latin, vintage\nBollywood, Latin, world music\nBollywood, Latin, worship\nBollywood, Punjabi folk\nBollywood, Punjabi, pop-rock\nBollywood, South Asian folk, Islamic devotional\nBollywood, Spanish fusion, ambient\nBollywood, Sufi\nBollywood, Sufi, electronic\nBollywood, UK garage\nBollywood, ambient, electronic\nBollywood, big band, devotional\nBollywood, big band, rock\nBollywood, big room house, folk fusion\nBollywood, big room house, hardstyle\nBollywood, bossa nova, Latin\nBollywood, cha-cha, vintage\nBollywood, children's music, Latin pop\nBollywood, chiptune\nBollywood, chiptune, R&B\nBollywood, chiptune, cinematic\nBollywood, chiptune, dance\nBollywood, chiptune, devotional\nBollywood, chiptune, devotional dance\nBollywood, chiptune, dream pop\nBollywood, chiptune, electronic\nBollywood, chiptune, orchestral\nBollywood, chiptune, retro-futuristic\nBollywood, chiptune, synth-pop\nBollywood, cinematic, EDM\nBollywood, cinematic, ambient\nBollywood, cinematic, devotional\nBollywood, cinematic, electronic\nBollywood, cinematic, lo-fi hip hop\nBollywood, cinematic, rock\nBollywood, cinematic, synth-pop\nBollywood, cinematic, trap\nBollywood, dance, festive\nBollywood, dance-pop, cinematic\nBollywood, dance-pop, retro\nBollywood, devotional, Indian\nBollywood, devotional, Indian fusion\nBollywood, devotional, Indian pop\nBollywood, devotional, dance\nBollywood, devotional, electronic\nBollywood, devotional, upbeat\nBollywood, disco-pop, funk\nBollywood, disco-pop, orchestral\nBollywood, dream pop, electronic\nBollywood, electronic dance\nBollywood, electronic dance, Indian folk\nBollywood, electronic dance, South Indian film music\nBollywood, electronic dance, devotional\nBollywood, electronic pop, orchestral\nBollywood, electronic, Indian classical\nBollywood, electronic, ballad\nBollywood, electronic, cinematic\nBollywood, electronic, dance\nBollywood, electronic, devotional\nBollywood, electronic, festive\nBollywood, electronic, hip-hop\nBollywood, electronic, melancholic\nBollywood, electronic, modern\nBollywood, electronic, playful\nBollywood, electronic, trap\nBollywood, electronic, world music\nBollywood, festive, dance\nBollywood, festive, pop\nBollywood, festive, world fusion\nBollywood, filmi, pop-rap\nBollywood, flamenco, Latin\nBollywood, flamenco, cinematic\nBollywood, folk, Latin\nBollywood, folk, cinematic\nBollywood, funk, 80s retro\nBollywood, funk, Latin\nBollywood, funk, pop\nBollywood, funk-rock, Indian pop-rock\nBollywood, future bass, cinematic\nBollywood, happy hardcore\nBollywood, hardstyle\nBollywood, hip-hop, pop-R&B\nBollywood, lo-fi, vintage\nBollywood, moombahton\nBollywood, moombahton, EDM\nBollywood, moombahton, Indian folk\nBollywood, moombahton, dance\nBollywood, moombahton, electronic\nBollywood, moombahton, electronic dance\nBollywood, moombahton, hardstyle\nBollywood, novelty, electronic\nBollywood, pop-EDM\nBollywood, pop-ballad\nBollywood, pop-rap, cinematic, dance-pop\nBollywood, psychedelic rock\nBollywood, psychedelic rock, funk\nBollywood, psychedelic, cumbia\nBollywood, psychedelic, lo-fi\nBollywood, retro\nBollywood, retro electronic\nBollywood, retro synth\nBollywood, retro, Latin-pop\nBollywood, retro, chiptune\nBollywood, retro, dance\nBollywood, retro, funk\nBollywood, retro-futuristic, chiptune\nBollywood, retro-futuristic, electronic\nBollywood, retro-futuristic, synth-pop\nBollywood, soft rock\nBollywood, surf rock\nBollywood, surf rock, garage rock\nBollywood, surf rock, rockabilly\nBollywood, synth pop\nBollywood, synth-pop\nBollywood, synth-pop, chiptune\nBollywood, synth-pop, disco\nBollywood, synth-pop, funk\nBollywood, synth-pop, retro\nBollywood, synth-pop, retro-futuristic\nBollywood, synthwave, electronic\nBollywood, theatrical, comedic\nBollywood, trap, hip-hop\nBollywood, world music\nBollywood, world music, Indian fusion\nBollywood, world music, Latin fusion\nBollywood, world music, acoustic\nBollywood, world music, ambient pop\nBollywood, world music, children's music\nBollywood, worldbeat, electronic\nBollywood-EDM\nBollywood-chiptune\nBollywood-electronic\nBollywood-pop\nBollywood-pop EDM\nBollywood-pop EDM trap\nBollywood-pop Naat\nBollywood-pop R&B\nBollywood-pop children's music\nBollywood-pop chiptune\nBollywood-pop devotional\nBollywood-pop funk\nBollywood-pop trap\nBollywood-pop world music\nBollywood-pop, EDM, trap\nBollywood-pop, Eurodance, dance-pop\nBollywood-pop, dance-pop, Western pop\nBollywood-ska\nBollywood-trap\nBongo Flava\nBongo Flava hip-hop\nBongo Flava neo-soul\nBornean electronic\nBornean pop\nBornean pop reggae\nBossa Nova\nBossa Nova Bollywood\nBossa Nova Cantopop\nBossa Nova Christian\nBossa Nova Christmas\nBossa Nova Cumbia\nBossa Nova Czech\nBossa Nova Fado\nBossa Nova Forró\nBossa Nova French Chanson\nBossa Nova French Pop\nBossa Nova French chanson\nBossa Nova French pop\nBossa Nova Greek pop\nBossa Nova Indian classical\nBossa Nova Israeli Folk\nBossa Nova Italian ballad\nBossa Nova Italian pop\nBossa Nova J-pop\nBossa Nova K-ballad\nBossa Nova K-pop\nBossa Nova Kizomba\nBossa Nova Kizomba R&B\nBossa Nova Latin Jazz\nBossa Nova Latin Pop\nBossa Nova Latin jazz\nBossa Nova Latin pop\nBossa Nova MPB\nBossa Nova MPB cool jazz\nBossa Nova Mandopop\nBossa Nova R&B\nBossa Nova R&B Kizomba\nBossa Nova R&B lo-fi hip-hop\nBossa Nova R&B trap\nBossa Nova Salsa\nBossa Nova Samba\nBossa Nova Samba Jazz\nBossa Nova Samba MPB\nBossa Nova Samba Pop\nBossa Nova Samba Rock\nBossa Nova Samba Salsa\nBossa Nova Samba-Jazz\nBossa Nova Samba-Pagode\nBossa Nova Samba-Rock\nBossa Nova Samba-reggae\nBossa Nova Sertanejo\nBossa Nova Turkish folk\nBossa Nova acid jazz\nBossa Nova acoustic pop\nBossa Nova alt-rock\nBossa Nova ambient\nBossa Nova art song\nBossa Nova art-pop\nBossa Nova ballad\nBossa Nova blues\nBossa Nova chamber folk\nBossa Nova chamber jazz\nBossa Nova chamber pop\nBossa Nova chanson\nBossa Nova children's\nBossa Nova children's music\nBossa Nova chillout\nBossa Nova choral\nBossa Nova cinematic\nBossa Nova cool jazz\nBossa Nova dance-pop\nBossa Nova downtempo\nBossa Nova drum and bass\nBossa Nova exotica\nBossa Nova folk\nBossa Nova folk-pop\nBossa Nova folk-rock\nBossa Nova funk\nBossa Nova funk MPB\nBossa Nova funk jazz\nBossa Nova funk neo-soul\nBossa Nova funk psychedelic pop\nBossa Nova funk synth-pop\nBossa Nova funk-pop\nBossa Nova future bass\nBossa Nova gospel\nBossa Nova gospel rock\nBossa Nova hip hop\nBossa Nova hip-hop\nBossa Nova house\nBossa Nova indie folk\nBossa Nova indie pop\nBossa Nova indie rock\nBossa Nova jazz\nBossa Nova jazz fusion\nBossa Nova jazz lounge\nBossa Nova jazz pop\nBossa Nova jazz-funk\nBossa Nova jazz-pop\nBossa Nova jazz-rock\nBossa Nova jungle\nBossa Nova lo-fi\nBossa Nova lo-fi hip hop\nBossa Nova lo-fi hip-hop\nBossa Nova lo-fi neo-soul\nBossa Nova lo-fi pop\nBossa Nova lounge\nBossa Nova lounge jazz\nBossa Nova lounge pop\nBossa Nova lounge-pop\nBossa Nova neo-soul\nBossa Nova novelty\nBossa Nova orchestral\nBossa Nova pop\nBossa Nova pop, hardstyle, hip-hop\nBossa Nova pop-R&B\nBossa Nova pop-funk\nBossa Nova pop-rock\nBossa Nova pop-soul\nBossa Nova progressive rock\nBossa Nova psychedelic rock\nBossa Nova reggae\nBossa Nova reggaeton\nBossa Nova rock\nBossa Nova rock fusion\nBossa Nova samba\nBossa Nova samba-rock\nBossa Nova smooth jazz\nBossa Nova soft rock\nBossa Nova soul\nBossa Nova soul pop-rock\nBossa Nova soul-jazz\nBossa Nova soulful pop\nBossa Nova tango\nBossa Nova trap\nBossa Nova trap fusion\nBossa Nova trip-hop\nBossa Nova worship\nBossa Nova, Axé\nBossa Nova, Axé, Samba-reggae\nBossa Nova, Baile Funk, Reggaeton\nBossa Nova, Big Band Swing\nBossa Nova, Brazilian Bass\nBossa Nova, Brazilian Bass, Slap House\nBossa Nova, Brazilian Folk\nBossa Nova, Brazilian Funk\nBossa Nova, Brazilian Funk Carioca\nBossa Nova, Brazilian Funk, Trap\nBossa Nova, Brazilian Funk, lo-fi R&B\nBossa Nova, Brazilian funk-pop\nBossa Nova, Brazilian phonk, trap\nBossa Nova, C-pop, acoustic\nBossa Nova, C-pop, jazz\nBossa Nova, Carnival, Italian Soul\nBossa Nova, Christian rock\nBossa Nova, City Pop\nBossa Nova, Drum and Bass, Lo-fi Hip Hop\nBossa Nova, Enka\nBossa Nova, European chanson, cinematic\nBossa Nova, European folk\nBossa Nova, Fado, MPB\nBossa Nova, Fado, Samba Funk\nBossa Nova, Filipino pop\nBossa Nova, Flamenco, Acoustic Guitar\nBossa Nova, Flamenco, Samba\nBossa Nova, Flamenco, World Music\nBossa Nova, Free Jazz\nBossa Nova, French Chanson\nBossa Nova, French Chanson, Ambient\nBossa Nova, French Chanson, Jazz\nBossa Nova, French Rap, Portuguese Pop\nBossa Nova, French chanson\nBossa Nova, French chanson, light jazz\nBossa Nova, French chanson, world music\nBossa Nova, French pop, jazz\nBossa Nova, Funk, Soul\nBossa Nova, Gospel\nBossa Nova, Gospel Rock\nBossa Nova, Indonesian folk\nBossa Nova, Indonesian pop\nBossa Nova, Italian ballad\nBossa Nova, Italian ballad, cinematic\nBossa Nova, Italian folk, Mediterranean folk\nBossa Nova, Italian pop\nBossa Nova, Italian pop, jazz\nBossa Nova, Italian pop, light jazz\nBossa Nova, Kayōkyoku\nBossa Nova, Latin Folk, Ethereal\nBossa Nova, Latin Jazz\nBossa Nova, Latin Jazz, Ambient\nBossa Nova, Latin Jazz, Cinematic\nBossa Nova, Latin Pop\nBossa Nova, Latin Pop, Cinematic\nBossa Nova, Latin Pop, European Pop\nBossa Nova, Latin Salsa\nBossa Nova, Latin ballad\nBossa Nova, Latin folk-pop\nBossa Nova, Latin jazz\nBossa Nova, Latin jazz, C-pop\nBossa Nova, Latin jazz, Flamenco\nBossa Nova, Latin jazz, French chanson\nBossa Nova, Latin jazz, Italian pop\nBossa Nova, Latin jazz, Turkish ballad\nBossa Nova, Latin jazz, ballad\nBossa Nova, Latin jazz, cinematic\nBossa Nova, Latin jazz, crooner\nBossa Nova, Latin jazz, flamenco\nBossa Nova, Latin jazz, lo-fi\nBossa Nova, Latin jazz, lo-fi trip-hop\nBossa Nova, Latin pop\nBossa Nova, Latin, world music\nBossa Nova, MPB\nBossa Nova, MPB, Afrobeat\nBossa Nova, MPB, Brazilian Jazz\nBossa Nova, MPB, Brazilian pop\nBossa Nova, MPB, Funk\nBossa Nova, MPB, Latin jazz\nBossa Nova, MPB, R&B\nBossa Nova, MPB, Samba\nBossa Nova, MPB, Samba Rock\nBossa Nova, MPB, alternative rock\nBossa Nova, MPB, choral\nBossa Nova, MPB, cinematic\nBossa Nova, MPB, dream pop\nBossa Nova, MPB, gospel\nBossa Nova, MPB, indie pop\nBossa Nova, MPB, light pop-rock\nBossa Nova, MPB, lo-fi\nBossa Nova, MPB, pop-rock\nBossa Nova, MPB, smooth pop\nBossa Nova, MPB, vocal jazz\nBossa Nova, Mandarin pop, acoustic\nBossa Nova, R&B\nBossa Nova, Russian Estrada\nBossa Nova, Samba\nBossa Nova, Samba Funk\nBossa Nova, Samba Funk, Afro-Latin\nBossa Nova, Samba Jazz\nBossa Nova, Samba Pop\nBossa Nova, Samba Rock\nBossa Nova, Samba Rock, Afro-Brazilian\nBossa Nova, Samba Rock, Big Band\nBossa Nova, Samba Rock, Children's Music\nBossa Nova, Samba Rock, Free Jazz\nBossa Nova, Samba Rock, Psychedelic\nBossa Nova, Samba Rock, Punk\nBossa Nova, Samba, Big Band\nBossa Nova, Samba, Brazilian Carnival\nBossa Nova, Samba, Brazilian Jazz\nBossa Nova, Samba, Brazilian pop\nBossa Nova, Samba, Dance Pop\nBossa Nova, Samba, MPB\nBossa Nova, Samba, Samba de Enredo\nBossa Nova, Samba, Vocal Jazz\nBossa Nova, Samba, theatrical ballad\nBossa Nova, Samba-Jazz\nBossa Nova, Samba-Jazz, MPB\nBossa Nova, Samba-Pop\nBossa Nova, Samba-Pop, MPB\nBossa Nova, Samba-Reggae\nBossa Nova, Samba-Reggae, Gospel\nBossa Nova, Samba-Reggae, MPB\nBossa Nova, Samba-Rock\nBossa Nova, Samba-reggae\nBossa Nova, Samba-reggae, Brazilian pop\nBossa Nova, Samba-reggae, Latin\nBossa Nova, Schlager, Latin pop\nBossa Nova, Trap, Brazilian Funk\nBossa Nova, Turkish folk\nBossa Nova, World Music\nBossa Nova, World Music, Samba\nBossa Nova, Zouk, Kizomba\nBossa Nova, acoustic, Vietnamese folk\nBossa Nova, acoustic, bilingual\nBossa Nova, alternative rock\nBossa Nova, ambient, cinematic\nBossa Nova, ambient, experimental\nBossa Nova, art rock\nBossa Nova, avant-garde jazz\nBossa Nova, cabaret, experimental\nBossa Nova, chamber pop\nBossa Nova, chamber pop, MPB\nBossa Nova, chamber pop, lounge jazz\nBossa Nova, children's music, Vietnamese\nBossa Nova, cinematic orchestral\nBossa Nova, cinematic, Brazilian ballad\nBossa Nova, cinematic, Italian\nBossa Nova, cinematic, Latin\nBossa Nova, cinematic, MPB\nBossa Nova, cinematic, Mandarin pop\nBossa Nova, cinematic, Portuguese pop\nBossa Nova, cinematic, ambient\nBossa Nova, cinematic, big band\nBossa Nova, cinematic, folk\nBossa Nova, cinematic, indie folk\nBossa Nova, cinematic, jazz\nBossa Nova, cinematic, lo-fi\nBossa Nova, cinematic, lounge\nBossa Nova, cinematic, melancholic\nBossa Nova, cinematic, orchestral\nBossa Nova, cinematic, soul\nBossa Nova, contemporary Christian, new age\nBossa Nova, cool jazz\nBossa Nova, dance-pop, EDM\nBossa Nova, drum and bass, breakcore\nBossa Nova, electronic pop\nBossa Nova, folk-pop, ambient\nBossa Nova, funk, neo-soul\nBossa Nova, funk-rock, Brazilian pop\nBossa Nova, gospel rock\nBossa Nova, hardstyle, psytrance\nBossa Nova, indie dance, nu-disco\nBossa Nova, indie pop-rock, alt-rock\nBossa Nova, indie rock\nBossa Nova, jazz\nBossa Nova, jazz fusion\nBossa Nova, jazz fusion, MPB\nBossa Nova, jazz, Cantopop\nBossa Nova, jazz, French pop\nBossa Nova, jazz, Sinhala soul\nBossa Nova, jazz, Vietnamese ballad\nBossa Nova, jazz, classical\nBossa Nova, jazz, live\nBossa Nova, jazz, piano ballad\nBossa Nova, jazz-fusion\nBossa Nova, jungle, drum and bass\nBossa Nova, light jazz\nBossa Nova, lo-fi R&B\nBossa Nova, lo-fi hip-hop\nBossa Nova, lo-fi hip-hop, Brazilian pop\nBossa Nova, lo-fi pop\nBossa Nova, lo-fi, Brazilian pop\nBossa Nova, lo-fi, electronic\nBossa Nova, lounge jazz, big band\nBossa Nova, melancholic, cinematic\nBossa Nova, neo-soul\nBossa Nova, orchestral, MPB\nBossa Nova, pop-rock\nBossa Nova, pop-rock, gospel\nBossa Nova, progressive house\nBossa Nova, progressive rock\nBossa Nova, progressive rock, cinematic\nBossa Nova, psychedelic art-rock, glam rock\nBossa Nova, psychedelic folk-rock\nBossa Nova, psychedelic funk, rock\nBossa Nova, psychedelic rock\nBossa Nova, psychedelic rock, noise rock\nBossa Nova, psychedelic rock, punk rock\nBossa Nova, psychedelic rock, trip-hop\nBossa Nova, psychedelic surf-rock\nBossa Nova, reggae-pop, contemporary Christian\nBossa Nova, rock, Portuguese folk\nBossa Nova, shoegaze\nBossa Nova, shoegaze, noise rock\nBossa Nova, shoegaze, post-rock\nBossa Nova, smooth jazz\nBossa Nova, smooth jazz, Brazilian pop\nBossa Nova, smooth jazz, Italian pop\nBossa Nova, theatrical pop, cinematic\nBossa Nova, vintage pop, rockabilly\nBossa Nova-pop\nBossa nova\nBossa nova pop\nBossa nova rock\nBossa nova samba\nBossa nova, Forró, Brazilian pop\nBossa nova, French chanson, gypsy jazz\nBossa nova, R&B, acoustic\nBossa nova, children's music, Brazilian\nBrazilian Axé\nBrazilian Bass\nBrazilian Bass, Hardstyle, Reggaeton\nBrazilian Bass, Slap House\nBrazilian Boi-Bumbá\nBrazilian Brega\nBrazilian Carnival\nBrazilian Chacarera\nBrazilian Christian\nBrazilian Christian Cumbia\nBrazilian Christian hip-hop\nBrazilian Christian hymn\nBrazilian Christian pop\nBrazilian Christian pop reggaeton\nBrazilian Christian pop-rock\nBrazilian Christian rock\nBrazilian Christian trap\nBrazilian Christian, retro synth, video game\nBrazilian Christmas\nBrazilian Christmas ballad\nBrazilian Christmas carol\nBrazilian Christmas, synth-pop, MPB\nBrazilian Cumbia\nBrazilian EDM\nBrazilian Eurodance\nBrazilian Forró\nBrazilian Funk\nBrazilian Funk Brega\nBrazilian Funk Carioca\nBrazilian Funk EDM\nBrazilian Funk Mandelão\nBrazilian Funk Piseiro\nBrazilian Funk R&B\nBrazilian Funk Rave\nBrazilian Funk Trap\nBrazilian Funk chiptune\nBrazilian Funk lo-fi\nBrazilian Funk mandelão\nBrazilian Funk montagem\nBrazilian Funk ostentação\nBrazilian Funk, C-pop\nBrazilian Funk, Christian EDM\nBrazilian Funk, Egyptian Theme\nBrazilian Funk, Happy Hardcore\nBrazilian Funk, Hard Dance\nBrazilian Funk, Hardstyle\nBrazilian Funk, Hyperpop\nBrazilian Funk, Hyperpop, Nightcore\nBrazilian Funk, Latin Pop, R&B\nBrazilian Funk, Pagode\nBrazilian Funk, Ragtime\nBrazilian Funk, chiptune\nBrazilian Funk, chiptune, hyperpop\nBrazilian Funk, cinematic pop\nBrazilian Funk, hyperpop, trap\nBrazilian Funk, rave, hardstyle\nBrazilian Funk, synth-pop\nBrazilian Funk, trap, lo-fi hip hop\nBrazilian G-funk\nBrazilian G-funk R&B\nBrazilian G-funk hip-hop\nBrazilian G-funk, boombap hip-hop\nBrazilian G-funk, new jack swing\nBrazilian Gaita\nBrazilian Gaucho\nBrazilian Gaúcho\nBrazilian Gaúcho folk\nBrazilian Gospel\nBrazilian Gospel Samba\nBrazilian Gospel Samba-Pagode\nBrazilian La Bada\nBrazilian MPB\nBrazilian MPB indie rock\nBrazilian MPB, psychedelic rock\nBrazilian MPB, samba-rock, Bossa Nova\nBrazilian MPB, trip-hop, psychedelic\nBrazilian Parrocha\nBrazilian Phonk\nBrazilian Piseiro\nBrazilian Piseiro chiptune\nBrazilian Piseiro funk carioca country\nBrazilian Piseiro, Kizomba\nBrazilian Piseiro, chiptune\nBrazilian Piseiro, electronic dance\nBrazilian Pop\nBrazilian Pop R&B\nBrazilian R&B\nBrazilian R&B MPB\nBrazilian R&B acoustic soul\nBrazilian R&B deep house trap\nBrazilian R&B funk\nBrazilian R&B lo-fi\nBrazilian R&B lo-fi hip hop\nBrazilian R&B lo-fi hip-hop\nBrazilian R&B lo-fi trap\nBrazilian R&B neo-soul\nBrazilian R&B soul\nBrazilian R&B trap\nBrazilian R&B trap-soul\nBrazilian R&B, Afrobeat\nBrazilian R&B, hip-hop\nBrazilian R&B, hip-hop, jazz\nBrazilian R&B, lo-fi pop\nBrazilian R&B, melodic trap\nBrazilian R&B, phonk\nBrazilian R&B, sad trap\nBrazilian R&B, trap\nBrazilian R&B, trap R&B, ambient pop\nBrazilian R&B, trap R&B, atmospheric R&B\nBrazilian R&B, trap-soul\nBrazilian Salsa\nBrazilian Samba\nBrazilian Trap\nBrazilian Vaneira\nBrazilian Vanejada\nBrazilian Vaquejada\nBrazilian accordion\nBrazilian acoustic\nBrazilian acoustic ballad\nBrazilian acoustic pop\nBrazilian acoustic pop-rock\nBrazilian acoustic, pop-rock\nBrazilian alternative rock\nBrazilian ambient\nBrazilian anthem\nBrazilian anthemic\nBrazilian art song\nBrazilian art-pop\nBrazilian ballad\nBrazilian ballad art rock\nBrazilian ballad brega\nBrazilian ballad forró\nBrazilian ballad indie rock\nBrazilian ballad samba\nBrazilian ballad samba-reggae\nBrazilian ballad sertanejo\nBrazilian ballad tango\nBrazilian ballad, Axé music, cinematic\nBrazilian ballad, Axé, Samba-reggae\nBrazilian ballad, Forró\nBrazilian ballad, Forró Eletrônico, Axé\nBrazilian ballad, Forró, Sertanejo\nBrazilian ballad, MPB, romantic ballad\nBrazilian ballad, Piseiro\nBrazilian ballad, Sertanejo Universitário\nBrazilian ballad, art rock\nBrazilian ballad, forró, romantic\nBrazilian ballad, gospel, cinematic\nBrazilian ballad, gospel, romantic\nBrazilian ballad, gospel, synth pop\nBrazilian ballad, pop, soul\nBrazilian ballad, pop-rock\nBrazilian ballad, samba\nBrazilian ballad, theatrical rock\nBrazilian bass\nBrazilian bass trap\nBrazilian battle rap\nBrazilian beach pop-rock\nBrazilian beat\nBrazilian beat, electronic, hip hop\nBrazilian big band\nBrazilian bluegrass\nBrazilian blues\nBrazilian blues-rock\nBrazilian bolero\nBrazilian bolero MPB\nBrazilian bolero cabaret\nBrazilian bolero, MPB, cinematic\nBrazilian bolero, disco-funk\nBrazilian bolero-samba\nBrazilian boogie\nBrazilian boogie-funk\nBrazilian boogie-woogie\nBrazilian boom-bap\nBrazilian boom-bap hip-hop\nBrazilian boombap\nBrazilian bossa nova\nBrazilian cabaret\nBrazilian capoeira\nBrazilian carnival\nBrazilian carnival, video game, synthpop\nBrazilian ceremonial\nBrazilian cha-cha-cha\nBrazilian chanson\nBrazilian children's\nBrazilian children's Christian\nBrazilian children's dance\nBrazilian children's gospel\nBrazilian children's lullaby\nBrazilian children's music\nBrazilian children's pop\nBrazilian children's, country-pop\nBrazilian children's, hyperpop, cartoon orchestral\nBrazilian chiptune\nBrazilian choral\nBrazilian choral, European folk\nBrazilian choro\nBrazilian choro fado\nBrazilian cinematic\nBrazilian classical\nBrazilian comedy\nBrazilian comedy rock\nBrazilian conscious hip-hop\nBrazilian country\nBrazilian country rock\nBrazilian country rockabilly\nBrazilian country, Western swing\nBrazilian country-blues\nBrazilian country-folk\nBrazilian country-gospel\nBrazilian country-pop\nBrazilian country-rock\nBrazilian country-ska\nBrazilian country-western\nBrazilian cumbia\nBrazilian dance\nBrazilian dance, Eurodance\nBrazilian dance, chiptune, electronic\nBrazilian dance-pop\nBrazilian dance-pop nu-disco\nBrazilian dancehall\nBrazilian dancehall, chiptune\nBrazilian deep house\nBrazilian devotional\nBrazilian devotional pop-rock\nBrazilian disco-funk\nBrazilian disco-pop\nBrazilian drama\nBrazilian drill\nBrazilian drill lo-fi\nBrazilian drill trap\nBrazilian drill, American hip-hop\nBrazilian drill, cinematic hip hop\nBrazilian drill, cinematic trap\nBrazilian drill, hyper-trap\nBrazilian drill, neo-soul\nBrazilian drill, phonk\nBrazilian drill, trap\nBrazilian electronic\nBrazilian electronic dance\nBrazilian electronic forró\nBrazilian electronic funk carioca\nBrazilian electronic pop\nBrazilian electropop\nBrazilian encapsro\nBrazilian festival\nBrazilian fingerstyle\nBrazilian fitness\nBrazilian flamenco\nBrazilian folk\nBrazilian folk MPB\nBrazilian folk ambient\nBrazilian folk ballad\nBrazilian folk gospel\nBrazilian folk hip-hop\nBrazilian folk polka\nBrazilian folk pop\nBrazilian folk pop-rock\nBrazilian folk punk\nBrazilian folk rock\nBrazilian folk samba\nBrazilian folk tango\nBrazilian folk waltz\nBrazilian folk, Afro-Brazilian, world music\nBrazilian folk, Americana, country-western\nBrazilian folk, Andean, folk rock\nBrazilian folk, Axé\nBrazilian folk, Axé, cinematic\nBrazilian folk, Christian pop\nBrazilian folk, European folk\nBrazilian folk, Fado, acoustic\nBrazilian folk, Forró\nBrazilian folk, German polka\nBrazilian folk, MPB\nBrazilian folk, MPB, cinematic\nBrazilian folk, MPB, spiritual music\nBrazilian folk, Piseiro, world music\nBrazilian folk, Samba\nBrazilian folk, Sertanejo\nBrazilian folk, Spanish flamenco, English folk-rock, hard rock, French cabaret\nBrazilian folk, art song\nBrazilian folk, art song, ritual music\nBrazilian folk, baião, cinematic\nBrazilian folk, cabaret, theatrical\nBrazilian folk, carnival rhythm\nBrazilian folk, carnival, electronic\nBrazilian folk, children's music\nBrazilian folk, choral, acoustic\nBrazilian folk, choral, ambient\nBrazilian folk, cinematic, epic\nBrazilian folk, cinematic, folkloric\nBrazilian folk, cinematic, orchestral\nBrazilian folk, country rock\nBrazilian folk, electronic, ambient\nBrazilian folk, electronic, carnival\nBrazilian folk, flamenco, acoustic\nBrazilian folk, forró\nBrazilian folk, forró, baião\nBrazilian folk, gospel\nBrazilian folk, indie rock\nBrazilian folk, indie rock, ska-punk\nBrazilian folk, lo-fi hip-hop, indie pop\nBrazilian folk, new age\nBrazilian folk, orchestral, world music\nBrazilian folk, polka, children's hymn\nBrazilian folk, psychedelic rock\nBrazilian folk, psychedelic, theatrical\nBrazilian folk, sacred choral\nBrazilian folk, samba\nBrazilian folk, samba, forró\nBrazilian folk, samba-reggae\nBrazilian folk, samba-rock\nBrazilian folk, sertanejo, musical theater\nBrazilian folk, spiritual, epic\nBrazilian folk, world music\nBrazilian folk, world music, lo-fi\nBrazilian folk, worldbeat, shamanic\nBrazilian folk-blues\nBrazilian folk-country\nBrazilian folk-gospel\nBrazilian folk-pop\nBrazilian folk-reggae\nBrazilian folk-rock\nBrazilian folk-rock alternative rock\nBrazilian folk-rock indie rock\nBrazilian folk-rock samba-rock\nBrazilian folk-rock, hard rock\nBrazilian folk-rock, psychedelic blues-rock\nBrazilian folktronica\nBrazilian football anthem\nBrazilian football chant\nBrazilian forró eletrônico\nBrazilian forró, gospel, big band\nBrazilian freestyle\nBrazilian freestyle new jack swing\nBrazilian funk\nBrazilian funk Afro-Brazilian fusion\nBrazilian funk Afrobeats\nBrazilian funk EDM\nBrazilian funk MPB\nBrazilian funk R&B\nBrazilian funk acid house\nBrazilian funk acid jazz\nBrazilian funk afrobeat\nBrazilian funk agro-funk\nBrazilian funk ambient\nBrazilian funk arrocha\nBrazilian funk boogie\nBrazilian funk carioca\nBrazilian funk carioca alternative R&B\nBrazilian funk carioca chiptune\nBrazilian funk carioca, EDM, hardstyle\nBrazilian funk carioca, J-pop, anime soundtrack\nBrazilian funk carioca, R&B\nBrazilian funk carioca, chiptune\nBrazilian funk carioca, cloud rap\nBrazilian funk carioca, lo-fi psychedelic rock\nBrazilian funk carioca, old-school hip-hop\nBrazilian funk carioca, reggaeton\nBrazilian funk chiptune\nBrazilian funk chiptune trap\nBrazilian funk classical fusion\nBrazilian funk dance-pop\nBrazilian funk dancehall\nBrazilian funk deep house\nBrazilian funk disco\nBrazilian funk disco-house\nBrazilian funk disco-pop\nBrazilian funk drill\nBrazilian funk drum and bass\nBrazilian funk electro-pop\nBrazilian funk electronic\nBrazilian funk forró\nBrazilian funk fusion\nBrazilian funk gospel\nBrazilian funk grime\nBrazilian funk hardstyle\nBrazilian funk hip-hop\nBrazilian funk house\nBrazilian funk hyperpop\nBrazilian funk hyperpop R&B\nBrazilian funk hyperpop chiptune\nBrazilian funk indie pop\nBrazilian funk industrial\nBrazilian funk jazz\nBrazilian funk jazz fusion\nBrazilian funk jazz hip-hop\nBrazilian funk lo-fi\nBrazilian funk lo-fi hip hop\nBrazilian funk lo-fi hyperpop\nBrazilian funk mandelão\nBrazilian funk neo-soul\nBrazilian funk neoclassical\nBrazilian funk nu-disco\nBrazilian funk orchestral\nBrazilian funk ostentação\nBrazilian funk ousi\nBrazilian funk pagode\nBrazilian funk pop\nBrazilian funk pop-rap\nBrazilian funk rap\nBrazilian funk rap-rock\nBrazilian funk rave\nBrazilian funk rave, chiptune, hard dance\nBrazilian funk reggae\nBrazilian funk reggae fusion\nBrazilian funk reggaeton\nBrazilian funk rock\nBrazilian funk rock samba-reggae\nBrazilian funk samba\nBrazilian funk samba-jazz\nBrazilian funk samba-pop\nBrazilian funk samba-reggae\nBrazilian funk samba-rock\nBrazilian funk sertanejo\nBrazilian funk ska\nBrazilian funk slap house\nBrazilian funk soul\nBrazilian funk soul-jazz\nBrazilian funk soul-rock\nBrazilian funk surf rock\nBrazilian funk synth-pop\nBrazilian funk tech house\nBrazilian funk trap\nBrazilian funk trap R&B\nBrazilian funk tribal house\nBrazilian funk, 80s boogie, city pop\nBrazilian funk, Asian fusion\nBrazilian funk, Dutch hip-hop\nBrazilian funk, EDM\nBrazilian funk, Eurodance\nBrazilian funk, French rap\nBrazilian funk, Latin hip-hop\nBrazilian funk, Latin pop\nBrazilian funk, Latin pop, R&B\nBrazilian funk, MPB, boogie\nBrazilian funk, MPB, electronic\nBrazilian funk, Middle Eastern fusion\nBrazilian funk, Middle Eastern synth\nBrazilian funk, R&B\nBrazilian funk, R&B, Latin hip hop\nBrazilian funk, R&B, ambient\nBrazilian funk, R&B, chillwave\nBrazilian funk, R&B, cinematic\nBrazilian funk, R&B, dream pop\nBrazilian funk, R&B, hyperpop\nBrazilian funk, R&B, lo-fi hip hop\nBrazilian funk, R&B, pop\nBrazilian funk, R&B, trap\nBrazilian funk, alternative R&B\nBrazilian funk, atmospheric R&B\nBrazilian funk, auto-tune pop\nBrazilian funk, auto-tune rap\nBrazilian funk, baile funk\nBrazilian funk, bass house\nBrazilian funk, big band\nBrazilian funk, boogie\nBrazilian funk, boogie, post-disco\nBrazilian funk, boom-bap hip-hop\nBrazilian funk, breakbeat, dream-pop\nBrazilian funk, breakbeat, electronic\nBrazilian funk, brega funk, pagode\nBrazilian funk, chillwave\nBrazilian funk, chiptune\nBrazilian funk, chiptune, 8-bit\nBrazilian funk, chiptune, R&B\nBrazilian funk, chiptune, cyberpunk\nBrazilian funk, chiptune, electro-pop\nBrazilian funk, chiptune, electronic\nBrazilian funk, chiptune, funk carioca\nBrazilian funk, chiptune, hip hop\nBrazilian funk, chiptune, hyperpop\nBrazilian funk, chiptune, lo-fi\nBrazilian funk, chiptune, synth-pop\nBrazilian funk, chiptune, trap\nBrazilian funk, chiptune, video game\nBrazilian funk, cinematic hip hop\nBrazilian funk, cinematic pop\nBrazilian funk, cinematic soul\nBrazilian funk, cinematic, chiptune\nBrazilian funk, cinematic, glitch\nBrazilian funk, cinematic, lo-fi\nBrazilian funk, cinematic, orchestral\nBrazilian funk, cinematic, trap\nBrazilian funk, city pop\nBrazilian funk, city pop, boogie\nBrazilian funk, cloud rap\nBrazilian funk, conscious hip-hop\nBrazilian funk, conscious hip-hop, experimental electronic\nBrazilian funk, country-western\nBrazilian funk, country-western fusion\nBrazilian funk, cyberpunk\nBrazilian funk, cyberpunk, funk carioca\nBrazilian funk, dance-pop\nBrazilian funk, dark electronic\nBrazilian funk, dark trap\nBrazilian funk, disco-house\nBrazilian funk, dream pop\nBrazilian funk, dreamy electronic\nBrazilian funk, dreamy synth\nBrazilian funk, drum and bass\nBrazilian funk, electronic\nBrazilian funk, electronic dance\nBrazilian funk, electronic dance, chiptune\nBrazilian funk, electronic, Latin-funk\nBrazilian funk, electronic, Middle Eastern fusion\nBrazilian funk, electronic, ambient\nBrazilian funk, electronic, hip hop\nBrazilian funk, electronic, lo-fi hip hop\nBrazilian funk, electronic, microtonal\nBrazilian funk, experimental hip-hop\nBrazilian funk, flamenco fusion\nBrazilian funk, forró, electronic\nBrazilian funk, funk carioca, R&B\nBrazilian funk, funk carioca, country-western\nBrazilian funk, funk-rock, lo-fi\nBrazilian funk, glitch, ambient\nBrazilian funk, gospel\nBrazilian funk, gospel, trap\nBrazilian funk, happy hardcore\nBrazilian funk, happy hardcore, hyperpop\nBrazilian funk, hard dance\nBrazilian funk, hard techno\nBrazilian funk, hardstyle\nBrazilian funk, hardstyle, hyperpop\nBrazilian funk, hardstyle, trap\nBrazilian funk, hip hop\nBrazilian funk, hip hop, Eurodance\nBrazilian funk, hip hop, R&B\nBrazilian funk, hip hop, glitch\nBrazilian funk, hip-hop\nBrazilian funk, hip-hop, chillwave\nBrazilian funk, hip-hop, electronic\nBrazilian funk, hip-hop, synthwave\nBrazilian funk, horrorcore\nBrazilian funk, horrorcore, trap\nBrazilian funk, house\nBrazilian funk, hyperpop\nBrazilian funk, hyperpop, R&B\nBrazilian funk, hyperpop, breakcore\nBrazilian funk, hyperpop, chiptune\nBrazilian funk, hyperpop, digital\nBrazilian funk, hyperpop, electronic\nBrazilian funk, hyperpop, funk carioca\nBrazilian funk, hyperpop, gaming\nBrazilian funk, hyperpop, glitch\nBrazilian funk, hyperpop, glitch-pop\nBrazilian funk, hyperpop, glitchcore\nBrazilian funk, hyperpop, hardstyle\nBrazilian funk, hyperpop, nightcore\nBrazilian funk, hyperpop, pluggnb\nBrazilian funk, hyperpop, slap house\nBrazilian funk, hyperpop, synth-pop\nBrazilian funk, hyperpop, trap\nBrazilian funk, indie pop, psychedelic soul\nBrazilian funk, industrial, deep house\nBrazilian funk, kawaii future bass\nBrazilian funk, lo-fi hip hop\nBrazilian funk, lo-fi hip hop, cinematic\nBrazilian funk, lo-fi, ambient\nBrazilian funk, lo-fi, chiptune\nBrazilian funk, lo-fi, cinematic\nBrazilian funk, lo-fi, trap\nBrazilian funk, lounge, lo-fi hip hop\nBrazilian funk, melancholic, hyperpop\nBrazilian funk, neo-soul\nBrazilian funk, neo-soul, a cappella\nBrazilian funk, old-school hip-hop\nBrazilian funk, orchestral, baroque\nBrazilian funk, phonk, R&B\nBrazilian funk, pop\nBrazilian funk, pop, ambient\nBrazilian funk, pop, electronic\nBrazilian funk, pop-R&B, electronic\nBrazilian funk, pop-reggaeton\nBrazilian funk, pop-rock\nBrazilian funk, pop-rock, reggae\nBrazilian funk, psychedelic hip hop\nBrazilian funk, psychedelic pop\nBrazilian funk, ragtime, lo-fi hip hop\nBrazilian funk, reggae, lo-fi\nBrazilian funk, reggaeton\nBrazilian funk, reggaeton, hard dance\nBrazilian funk, reggaeton, moombahton\nBrazilian funk, reggaeton, trap\nBrazilian funk, retro synth\nBrazilian funk, samba, ambient\nBrazilian funk, samba, trap\nBrazilian funk, samba-reggae\nBrazilian funk, samba-rock\nBrazilian funk, slap house\nBrazilian funk, soul, Afrobeat\nBrazilian funk, soul, jazz fusion\nBrazilian funk, soul, lo-fi\nBrazilian funk, synth pop\nBrazilian funk, synth-pop\nBrazilian funk, synth-pop, chiptune\nBrazilian funk, tech house\nBrazilian funk, trap\nBrazilian funk, trap R&B\nBrazilian funk, trap soul, R&B\nBrazilian funk, trap, R&B\nBrazilian funk, trap, acoustic\nBrazilian funk, trap, ambient\nBrazilian funk, trap, cinematic\nBrazilian funk, trap, cloud rap\nBrazilian funk, trap, dark ambient\nBrazilian funk, trap, funk carioca\nBrazilian funk, trap, hip hop\nBrazilian funk, trap, hyperpop\nBrazilian funk, trap, lo-fi hip hop\nBrazilian funk, trap, orchestral\nBrazilian funk, trap, posse cut\nBrazilian funk, trap, psychedelic pop\nBrazilian funk, trap, ragtime\nBrazilian funk, trap, reggaeton\nBrazilian funk, trap, synthwave\nBrazilian funk, trap, vaporwave\nBrazilian funk, tribal house\nBrazilian funk, vaporwave, trap\nBrazilian funk-house\nBrazilian funk-pop\nBrazilian funk-rap\nBrazilian funk-reggae\nBrazilian funk-rock\nBrazilian funk-rock, trap\nBrazilian funk-trap\nBrazilian fusion\nBrazilian gangsta rap\nBrazilian gospel\nBrazilian gospel EDM\nBrazilian gospel MPB\nBrazilian gospel Sertanejo\nBrazilian gospel acoustic folk\nBrazilian gospel bolero\nBrazilian gospel brega\nBrazilian gospel chiptune\nBrazilian gospel country\nBrazilian gospel country-rock\nBrazilian gospel cumbia\nBrazilian gospel dance-pop\nBrazilian gospel folk\nBrazilian gospel forró\nBrazilian gospel funk\nBrazilian gospel funk rock\nBrazilian gospel hip-hop\nBrazilian gospel lo-fi\nBrazilian gospel pagode\nBrazilian gospel pop\nBrazilian gospel pop-funk\nBrazilian gospel pop-reggae\nBrazilian gospel pop-rock\nBrazilian gospel pop-rock sertanejo\nBrazilian gospel pop-sertanejo\nBrazilian gospel pop-trap\nBrazilian gospel rap\nBrazilian gospel reggae\nBrazilian gospel reggaeton\nBrazilian gospel rock\nBrazilian gospel salsa\nBrazilian gospel samba\nBrazilian gospel samba-reggae\nBrazilian gospel sertanejo\nBrazilian gospel smooth jazz\nBrazilian gospel soul\nBrazilian gospel trap\nBrazilian gospel, Axé, Samba-reggae\nBrazilian gospel, Axé, cinematic\nBrazilian gospel, MPB\nBrazilian gospel, MPB, a cappella\nBrazilian gospel, MPB, vintage\nBrazilian gospel, Sertanejo\nBrazilian gospel, forró\nBrazilian gospel, forró, country\nBrazilian gospel, funk, trap\nBrazilian gospel, hard rock\nBrazilian gospel, hyperpop, children's music\nBrazilian gospel, retro chiptune\nBrazilian gospel, rockabilly, country\nBrazilian gospel, sertanejo\nBrazilian gospel, sertanejo, rock\nBrazilian gospel, smooth jazz\nBrazilian gospel, smooth jazz, pop-rock\nBrazilian gospel, synth-pop\nBrazilian gospel, synth-pop, Italo-disco\nBrazilian gospel, synth-pop, Latin pop\nBrazilian gospel, synth-pop, disco\nBrazilian gospel-pop\nBrazilian gospel-rock\nBrazilian grime\nBrazilian groove\nBrazilian guitar\nBrazilian gypsy jazz\nBrazilian hard rock\nBrazilian hip hop\nBrazilian hip-hop\nBrazilian hip-hop G-funk\nBrazilian hip-hop Latin folk\nBrazilian hip-hop MPB\nBrazilian hip-hop R&B\nBrazilian hip-hop chiptune\nBrazilian hip-hop funk\nBrazilian hip-hop funk carioca\nBrazilian hip-hop funk carioca trap\nBrazilian hip-hop lo-fi\nBrazilian hip-hop neo-soul\nBrazilian hip-hop soul\nBrazilian hip-hop trap\nBrazilian hip-hop, R&B, trap\nBrazilian hip-hop, boom-bap\nBrazilian hip-hop, boom-bap, trap\nBrazilian hip-hop, chiptune, boom-bap\nBrazilian hip-hop, chiptune, trap\nBrazilian hip-hop, cinematic trap\nBrazilian hip-hop, cinematic, sci-fi\nBrazilian hip-hop, drill, cinematic\nBrazilian hip-hop, lo-fi boom-bap\nBrazilian hip-hop, lo-fi, trap\nBrazilian hip-hop, pop-rock\nBrazilian hip-hop, trap, R&B\nBrazilian hip-hop, trap, chiptune\nBrazilian hip-hop, trap, cinematic\nBrazilian hip-hop, trap, cloud rap\nBrazilian hip-hop, trap, conscious rap\nBrazilian hip-hop, trap, drill\nBrazilian hip-hop, trap, funk carioca\nBrazilian hip-hop, trap, lo-fi\nBrazilian hip-hop, trap, modern R&B\nBrazilian hip-hop, trap, reggaeton\nBrazilian house\nBrazilian house, breakbeat\nBrazilian hymn\nBrazilian hyperpop\nBrazilian indie folk\nBrazilian indie folk-pop\nBrazilian indie pop\nBrazilian indie pop-rock\nBrazilian indie rock\nBrazilian indie-folk\nBrazilian indie-pop\nBrazilian jaripeo\nBrazilian jazz\nBrazilian jazz MPB\nBrazilian jazz cabaret\nBrazilian jazz fusion\nBrazilian jazz hip hop\nBrazilian jazz soul\nBrazilian jazz, MPB, ethereal\nBrazilian jazz-funk\nBrazilian jazz-fusion\nBrazilian jazz-pop\nBrazilian jazz-rock\nBrazilian jingle\nBrazilian lo-fi\nBrazilian lo-fi hip hop\nBrazilian lounge\nBrazilian lullaby\nBrazilian march\nBrazilian marching band\nBrazilian melancholic\nBrazilian melodic rap\nBrazilian metal\nBrazilian military march\nBrazilian milonga\nBrazilian music\nBrazilian music, Latin, world music\nBrazilian music, choro, flamenco fusion\nBrazilian nerdcore\nBrazilian new wave\nBrazilian novelty\nBrazilian opera\nBrazilian orchestral\nBrazilian pagode\nBrazilian pagode, R&B\nBrazilian pagode, arrocha, sentimental ballad\nBrazilian pagode, brega\nBrazilian pagode, funk carioca\nBrazilian pagode, pop-reggae\nBrazilian party\nBrazilian party anthem\nBrazilian party rock\nBrazilian percussion\nBrazilian percussion, Afrobeat, hip-hop\nBrazilian percussion, world music, electronic\nBrazilian phonk\nBrazilian phonk trap\nBrazilian phonk trap metal\nBrazilian phonk, EDM\nBrazilian phonk, cinematic trap\nBrazilian phonk, hardstyle\nBrazilian phonk, hyperpop, video game soundtrack\nBrazilian phonk, trap metal, dark trap R&B\nBrazilian phonk, trap metal, orchestral\nBrazilian phonk, trap, anime\nBrazilian phonk, trap, cinematic\nBrazilian piseiro\nBrazilian piseiro chiptune\nBrazilian piseiro, chiptune\nBrazilian piseiro, electronic dance\nBrazilian political jingle\nBrazilian pop\nBrazilian pop 80s\nBrazilian pop Afro-Latin\nBrazilian pop Afrobeat\nBrazilian pop Axé\nBrazilian pop Axé Sertanejo\nBrazilian pop Forró\nBrazilian pop J-pop\nBrazilian pop Kizomba\nBrazilian pop MPB\nBrazilian pop MPB Bossa Nova\nBrazilian pop MPB R&B\nBrazilian pop MPB Sertanejo\nBrazilian pop MPB gospel\nBrazilian pop MPB samba\nBrazilian pop MPB smooth jazz\nBrazilian pop R&B\nBrazilian pop R&B Afrobeats\nBrazilian pop R&B Bossa Nova\nBrazilian pop R&B Kizomba\nBrazilian pop R&B MPB\nBrazilian pop R&B Sertanejo\nBrazilian pop R&B Zouk\nBrazilian pop R&B electronic\nBrazilian pop R&B funk\nBrazilian pop R&B funk carioca\nBrazilian pop R&B gospel\nBrazilian pop R&B lo-fi\nBrazilian pop R&B lo-fi hip-hop\nBrazilian pop R&B neo-soul\nBrazilian pop R&B pagode\nBrazilian pop R&B reggae\nBrazilian pop R&B reggae fusion\nBrazilian pop R&B reggaeton\nBrazilian pop R&B smooth jazz\nBrazilian pop R&B soul\nBrazilian pop R&B synth-pop\nBrazilian pop R&B trap\nBrazilian pop Sertanejo\nBrazilian pop Sertanejo Forró\nBrazilian pop a cappella\nBrazilian pop afrobeat R&B\nBrazilian pop ambient\nBrazilian pop arrocha\nBrazilian pop brega\nBrazilian pop brega arrocha\nBrazilian pop brega forró\nBrazilian pop brega funk\nBrazilian pop brega piseiro\nBrazilian pop brega smooth jazz\nBrazilian pop carimbó\nBrazilian pop chanson\nBrazilian pop chillwave deep house\nBrazilian pop chillwave lounge\nBrazilian pop chiptune\nBrazilian pop chiptune reggae\nBrazilian pop cinematic\nBrazilian pop city pop\nBrazilian pop cumbia\nBrazilian pop dance-pop\nBrazilian pop dembow\nBrazilian pop drum and bass\nBrazilian pop forró\nBrazilian pop funk\nBrazilian pop funk R&B\nBrazilian pop funk carioca\nBrazilian pop funk carioca EDM\nBrazilian pop funk carioca R&B\nBrazilian pop funk carioca chiptune\nBrazilian pop funk carioca reggaeton\nBrazilian pop funk chiptune\nBrazilian pop funk disco\nBrazilian pop funk electronic\nBrazilian pop funk hip-hop\nBrazilian pop funk neo-soul\nBrazilian pop funk reggae\nBrazilian pop funk rock\nBrazilian pop funk soul\nBrazilian pop future bass\nBrazilian pop gospel\nBrazilian pop gospel electronic\nBrazilian pop hip-hop\nBrazilian pop jazz fusion\nBrazilian pop kizomba\nBrazilian pop lo-fi\nBrazilian pop lo-fi R&B\nBrazilian pop lo-fi hip hop\nBrazilian pop lo-fi hip-hop\nBrazilian pop lo-fi neo-soul\nBrazilian pop neo-soul\nBrazilian pop neo-soul funk\nBrazilian pop neo-soul lo-fi hip-hop\nBrazilian pop nu-disco\nBrazilian pop nu-disco funk\nBrazilian pop nu-disco house\nBrazilian pop nu-disco synth-pop\nBrazilian pop nu-disco tropical house\nBrazilian pop pagode\nBrazilian pop reggae\nBrazilian pop reggae Latin\nBrazilian pop reggae MPB\nBrazilian pop reggae R&B\nBrazilian pop reggae dancehall\nBrazilian pop reggae funk\nBrazilian pop reggae hip-hop\nBrazilian pop reggae jazz\nBrazilian pop reggae ska\nBrazilian pop reggae-pop\nBrazilian pop reggaeton\nBrazilian pop reggaeton R&B\nBrazilian pop reggaeton afrobeat\nBrazilian pop reggaeton chiptune\nBrazilian pop reggaeton funk carioca\nBrazilian pop rock\nBrazilian pop rockabilly\nBrazilian pop salsa\nBrazilian pop samba\nBrazilian pop samba bossa nova\nBrazilian pop samba-reggae\nBrazilian pop samba-reggae funk\nBrazilian pop samba-rock\nBrazilian pop sertanejo\nBrazilian pop sertanejo forró\nBrazilian pop singer-songwriter\nBrazilian pop smooth jazz\nBrazilian pop soul\nBrazilian pop trap\nBrazilian pop trap R&B\nBrazilian pop trap chiptune\nBrazilian pop trap-R&B\nBrazilian pop world music\nBrazilian pop, 80s pop\nBrazilian pop, 80s pop, cinematic\nBrazilian pop, 80s pop, theatrical\nBrazilian pop, 90s R&B, hip-hop\nBrazilian pop, Afro-Brazilian, MPB\nBrazilian pop, Afro-pop, world music\nBrazilian pop, Afrobeats, dancehall\nBrazilian pop, Axé\nBrazilian pop, Axé, Eurodance\nBrazilian pop, Axé, Forró\nBrazilian pop, Axé, Forró Eletrônico\nBrazilian pop, Axé, Sertanejo\nBrazilian pop, Axé, brega-pop\nBrazilian pop, Axé, cinematic\nBrazilian pop, Axé, cinematic pop\nBrazilian pop, Axé, hip-hop\nBrazilian pop, Axé, pop-rock\nBrazilian pop, Axé, rock\nBrazilian pop, Axé, romantic ballad\nBrazilian pop, Bollywood, drum and bass\nBrazilian pop, Brazilian Funk\nBrazilian pop, Brega\nBrazilian pop, Brega, Forró\nBrazilian pop, Brega, Forró Eletrônico\nBrazilian pop, Christian contemporary\nBrazilian pop, EDM\nBrazilian pop, EDM, dance-pop\nBrazilian pop, EDM, future bass\nBrazilian pop, Eurodance\nBrazilian pop, Eurodance, Axé\nBrazilian pop, Eurodance, Italo disco\nBrazilian pop, Eurodance, house\nBrazilian pop, Forró\nBrazilian pop, Forró Eletrônico\nBrazilian pop, Forró, Sertanejo\nBrazilian pop, Forró, pop-rock\nBrazilian pop, Italo-disco\nBrazilian pop, Kizomba\nBrazilian pop, Kizomba, Brega\nBrazilian pop, Kizomba, R&B\nBrazilian pop, Kizomba, Samba\nBrazilian pop, Kizomba, Zouk\nBrazilian pop, Kizomba, smooth jazz\nBrazilian pop, Latin R&B\nBrazilian pop, MPB\nBrazilian pop, MPB, Bossa Nova\nBrazilian pop, MPB, R&B\nBrazilian pop, MPB, Samba\nBrazilian pop, MPB, ballad\nBrazilian pop, MPB, forró\nBrazilian pop, MPB, gospel\nBrazilian pop, MPB, lullaby\nBrazilian pop, MPB, orchestral\nBrazilian pop, MPB, reggaeton\nBrazilian pop, MPB, samba\nBrazilian pop, MPB, samba-reggae\nBrazilian pop, MPB, samba-rock\nBrazilian pop, MPB, smooth jazz\nBrazilian pop, MPB, soft rock\nBrazilian pop, MPB, soul\nBrazilian pop, Middle Eastern fusion\nBrazilian pop, R&B\nBrazilian pop, R&B, 2000s pop\nBrazilian pop, R&B, 80s synth\nBrazilian pop, R&B, Kizomba\nBrazilian pop, R&B, New Jack Swing\nBrazilian pop, R&B, Sertanejo\nBrazilian pop, R&B, deep house\nBrazilian pop, R&B, electronic\nBrazilian pop, R&B, funk carioca\nBrazilian pop, R&B, gospel\nBrazilian pop, R&B, lo-fi hip-hop\nBrazilian pop, R&B, new jack swing\nBrazilian pop, R&B, reggaeton\nBrazilian pop, R&B, soul\nBrazilian pop, R&B, synth-pop\nBrazilian pop, R&B, trap\nBrazilian pop, Samba, MPB\nBrazilian pop, Sertanejo\nBrazilian pop, Sertanejo, Axé\nBrazilian pop, Zouk, Brega\nBrazilian pop, acid jazz, funk\nBrazilian pop, acid jazz, samba\nBrazilian pop, baile funk, reggaeton\nBrazilian pop, big band, orchestral\nBrazilian pop, big band, samba\nBrazilian pop, blues-rock, pop-rock\nBrazilian pop, bossa nova, jazz\nBrazilian pop, brega\nBrazilian pop, brega, forró\nBrazilian pop, brega, forró eletrônico\nBrazilian pop, brega, romântico\nBrazilian pop, carnival music\nBrazilian pop, children's folk\nBrazilian pop, children's music, pop-rap\nBrazilian pop, chillwave, electronic\nBrazilian pop, chiptune\nBrazilian pop, chiptune, cinematic pop\nBrazilian pop, chiptune, hyper-pop\nBrazilian pop, chiptune, reggaeton\nBrazilian pop, cinematic orchestral\nBrazilian pop, cinematic soul\nBrazilian pop, cinematic, Axé\nBrazilian pop, cinematic, epic\nBrazilian pop, cinematic, forró\nBrazilian pop, cinematic, orchestral\nBrazilian pop, cinematic, soul\nBrazilian pop, country, gospel\nBrazilian pop, deep house\nBrazilian pop, deep house, slap house\nBrazilian pop, disco, romantic\nBrazilian pop, electronic R&B, future bass\nBrazilian pop, electronic pop, cinematic\nBrazilian pop, electronic, Bossa Nova\nBrazilian pop, electronic, chiptune\nBrazilian pop, electronic, funk carioca\nBrazilian pop, electronic, gospel\nBrazilian pop, electronic, lo-fi\nBrazilian pop, electronic, trap\nBrazilian pop, forró\nBrazilian pop, forró eletrônico\nBrazilian pop, forró eletrônico, chiptune\nBrazilian pop, forró, brega\nBrazilian pop, forró, chiptune\nBrazilian pop, forró, dance\nBrazilian pop, forró, piseiro\nBrazilian pop, forró, pop-rock\nBrazilian pop, forró, sertanejo\nBrazilian pop, forró, synth pop\nBrazilian pop, forró, upbeat\nBrazilian pop, funk carioca\nBrazilian pop, funk carioca, EDM\nBrazilian pop, funk carioca, hyperpop\nBrazilian pop, funk carioca, pop-rock\nBrazilian pop, funk, R&B\nBrazilian pop, future bass\nBrazilian pop, gospel\nBrazilian pop, gospel soul\nBrazilian pop, gospel, 80s pop\nBrazilian pop, gospel, 80s pop-rock\nBrazilian pop, gospel, 80s soul\nBrazilian pop, gospel, 80s synth\nBrazilian pop, gospel, Axé\nBrazilian pop, gospel, Christmas\nBrazilian pop, gospel, MPB\nBrazilian pop, gospel, R&B\nBrazilian pop, gospel, acoustic\nBrazilian pop, gospel, ballad\nBrazilian pop, gospel, cinematic\nBrazilian pop, gospel, dance\nBrazilian pop, gospel, funk\nBrazilian pop, gospel, jazz\nBrazilian pop, gospel, pop-rock\nBrazilian pop, gospel, salsa\nBrazilian pop, gospel, samba-reggae\nBrazilian pop, gospel, smooth jazz\nBrazilian pop, gospel, soul\nBrazilian pop, gospel, synth-pop\nBrazilian pop, gospel, world music\nBrazilian pop, hard dance, EDM\nBrazilian pop, hard rock\nBrazilian pop, hip-hop\nBrazilian pop, hip-hop, soul\nBrazilian pop, late-90s house\nBrazilian pop, liquid drum and bass\nBrazilian pop, lo-fi, forró\nBrazilian pop, modern trap\nBrazilian pop, neo-soul\nBrazilian pop, neo-soul, R&B\nBrazilian pop, neo-soul, funk\nBrazilian pop, neo-soul, jazz fusion\nBrazilian pop, neo-soul, lo-fi hip-hop\nBrazilian pop, new age\nBrazilian pop, new jack swing, hip-hop\nBrazilian pop, pagode\nBrazilian pop, pagode romântico\nBrazilian pop, pagode, R&B\nBrazilian pop, pagode, bossa nova\nBrazilian pop, pagode, pop-rock\nBrazilian pop, pagode, samba\nBrazilian pop, pagode, sertanejo\nBrazilian pop, pagode, synth-pop\nBrazilian pop, piseiro, brega\nBrazilian pop, pop-funk\nBrazilian pop, pop-rock\nBrazilian pop, pop-rock, Bossa Nova\nBrazilian pop, pop-rock, forró\nBrazilian pop, pop-rock, hard rock\nBrazilian pop, pop-sertanejo\nBrazilian pop, power ballad, theatrical\nBrazilian pop, power-pop, electronic\nBrazilian pop, progressive house, EDM\nBrazilian pop, psychedelic funk\nBrazilian pop, psychedelic rock\nBrazilian pop, reggae, pagode\nBrazilian pop, reggaeton\nBrazilian pop, reggaeton, Latin pop\nBrazilian pop, reggaeton, R&B\nBrazilian pop, reggaeton, atmospheric\nBrazilian pop, reggaeton, baile funk\nBrazilian pop, reggaeton, chiptune\nBrazilian pop, reggaeton, dancehall\nBrazilian pop, reggaeton, funk carioca\nBrazilian pop, reggaeton, pop\nBrazilian pop, reggaeton, pop-ballad\nBrazilian pop, reggaeton, synth pop\nBrazilian pop, reggaeton, synth-pop\nBrazilian pop, reggaeton, trap\nBrazilian pop, retro funk\nBrazilian pop, retro pop, chiptune\nBrazilian pop, retro synth\nBrazilian pop, salsa\nBrazilian pop, salsa, MPB\nBrazilian pop, salsa, upbeat\nBrazilian pop, samba, MPB\nBrazilian pop, samba, smooth jazz\nBrazilian pop, samba-pop, pop-rock\nBrazilian pop, samba-reggae\nBrazilian pop, samba-rock, Axé\nBrazilian pop, sertanejo\nBrazilian pop, sertanejo, Axé\nBrazilian pop, sertanejo, forró\nBrazilian pop, smooth jazz\nBrazilian pop, smooth jazz, Axé\nBrazilian pop, smooth jazz, MPB\nBrazilian pop, smooth jazz, adult contemporary\nBrazilian pop, smooth jazz, bossa nova\nBrazilian pop, smooth jazz, gospel\nBrazilian pop, smooth jazz, pagode\nBrazilian pop, smooth jazz, salsa\nBrazilian pop, spiritual, electronic dance\nBrazilian pop, synth-pop\nBrazilian pop, synth-pop, 80s new wave\nBrazilian pop, synth-pop, Axé\nBrazilian pop, synth-pop, MPB\nBrazilian pop, synth-pop, R&B\nBrazilian pop, theatrical pop\nBrazilian pop, theatrical pop, pop-rock\nBrazilian pop, trap\nBrazilian pop, trap, R&B\nBrazilian pop, trap, electronic\nBrazilian pop, trip-hop, world music\nBrazilian pop, world music\nBrazilian pop, world music, ambient\nBrazilian pop-EDM\nBrazilian pop-R&B\nBrazilian pop-axé\nBrazilian pop-ballad\nBrazilian pop-country\nBrazilian pop-dance\nBrazilian pop-dance future bass\nBrazilian pop-folk\nBrazilian pop-funk\nBrazilian pop-funk jazz fusion\nBrazilian pop-funk neo-soul\nBrazilian pop-funk reggae\nBrazilian pop-funk soul\nBrazilian pop-funk, chiptune\nBrazilian pop-funk, conscious hip-hop\nBrazilian pop-funk, new jack swing\nBrazilian pop-funk, reggae, Axé\nBrazilian pop-funk, reggaeton\nBrazilian pop-funk, soulful R&B\nBrazilian pop-gospel\nBrazilian pop-house\nBrazilian pop-jazz\nBrazilian pop-punk\nBrazilian pop-rap\nBrazilian pop-reggae\nBrazilian pop-reggae chiptune\nBrazilian pop-reggae funk\nBrazilian pop-reggaeton\nBrazilian pop-rock\nBrazilian pop-rock 80s\nBrazilian pop-rock Axé\nBrazilian pop-rock MPB\nBrazilian pop-rock brega\nBrazilian pop-rock chiptune\nBrazilian pop-rock forró\nBrazilian pop-rock funk\nBrazilian pop-rock hip-hop\nBrazilian pop-rock industrial rock\nBrazilian pop-rock neo-soul\nBrazilian pop-rock reggae\nBrazilian pop-rock reggaeton\nBrazilian pop-rock samba-reggae\nBrazilian pop-rock sertanejo\nBrazilian pop-rock ska-reggae\nBrazilian pop-rock, Axé\nBrazilian pop-rock, Axé, Forró\nBrazilian pop-rock, Axé, Samba-reggae\nBrazilian pop-rock, Axé, electronic dance\nBrazilian pop-rock, Axé, pop-ballad\nBrazilian pop-rock, Eurodance\nBrazilian pop-rock, Forró\nBrazilian pop-rock, Forró, Axé\nBrazilian pop-rock, MPB\nBrazilian pop-rock, MPB, soul\nBrazilian pop-rock, R&B\nBrazilian pop-rock, Sertanejo\nBrazilian pop-rock, Sertanejo Universitário\nBrazilian pop-rock, dance-pop\nBrazilian pop-rock, electronic dance, anthemic\nBrazilian pop-rock, forró\nBrazilian pop-rock, forró eletrônico\nBrazilian pop-rock, hard rock\nBrazilian pop-rock, neo-soul, city pop\nBrazilian pop-rock, new wave, synth-pop\nBrazilian pop-rock, pagode\nBrazilian pop-rock, progressive house\nBrazilian pop-rock, punk rock\nBrazilian pop-rock, smooth jazz\nBrazilian pop-rock, smooth jazz, MPB\nBrazilian pop-rock, soul\nBrazilian pop-rock, synth-pop\nBrazilian pop-romântico\nBrazilian pop-samba\nBrazilian pop-sertanejo\nBrazilian pop-soul\nBrazilian pop-trap\nBrazilian popular music\nBrazilian post-punk\nBrazilian power ballad\nBrazilian power ballad, 80s synth-pop\nBrazilian power ballad, cumbia, Latin\nBrazilian power ballad, pop-rock\nBrazilian protest\nBrazilian protest music\nBrazilian psychedelic\nBrazilian psychedelic folk\nBrazilian psychedelic folk-rock\nBrazilian psychedelic pop\nBrazilian psychedelic rock\nBrazilian punk\nBrazilian punk rock\nBrazilian ranchera\nBrazilian rap\nBrazilian rap, trap, chiptune\nBrazilian rave\nBrazilian rave funk\nBrazilian reggae\nBrazilian reggae MPB\nBrazilian reggae forró\nBrazilian reggae fusion\nBrazilian reggae gospel\nBrazilian reggae lovers rock\nBrazilian reggae ska\nBrazilian reggae-pop\nBrazilian reggaeton\nBrazilian regional\nBrazilian revolutionary\nBrazilian rhythm\nBrazilian rhythms, world music, Afro-Latin\nBrazilian rhythms, world music, flamenco\nBrazilian ritual\nBrazilian rock\nBrazilian rock MPB\nBrazilian rock MPB surf rock\nBrazilian rock and roll\nBrazilian rock baião\nBrazilian rock brega\nBrazilian rock chiptune\nBrazilian rock country-rock\nBrazilian rock forró\nBrazilian rock funk\nBrazilian rock funk MPB\nBrazilian rock gospel\nBrazilian rock post-punk\nBrazilian rock reggae ska\nBrazilian rock samba-rock\nBrazilian rock sertanejo\nBrazilian rock sertanejo forró\nBrazilian rock surf rock\nBrazilian rock surf-rock\nBrazilian rock tango\nBrazilian rock, 80s new wave\nBrazilian rock, Axé, Samba\nBrazilian rock, Axé, carnival rock\nBrazilian rock, Axé, gospel\nBrazilian rock, MPB\nBrazilian rock, MPB, blues-rock\nBrazilian rock, MPB, gospel\nBrazilian rock, MPB, psychedelic\nBrazilian rock, MPB, psychedelic rock\nBrazilian rock, MPB, samba-rock\nBrazilian rock, big band, theatrical rock\nBrazilian rock, cinematic rock\nBrazilian rock, country-rock\nBrazilian rock, desert rock, southern rock\nBrazilian rock, forró, brega\nBrazilian rock, forró, pub rock\nBrazilian rock, funk rock, rockabilly\nBrazilian rock, garage rock, satirical\nBrazilian rock, new wave\nBrazilian rock, new wave, 80s\nBrazilian rock, new wave, synth-pop\nBrazilian rock, psychedelic rock, blues-rock\nBrazilian rock, punk rock\nBrazilian rock, punk rock, garage rock\nBrazilian rock, reggae, ska\nBrazilian rock, salsa, mambo\nBrazilian rock, samba rock, MPB\nBrazilian rock, ska, Latin rock\nBrazilian rock, ska, reggae\nBrazilian rock, surf rock\nBrazilian rock, surf rock, big band\nBrazilian rock, surf rock, garage rock\nBrazilian rock, surf rock, rockabilly\nBrazilian rockabilly\nBrazilian rodeo\nBrazilian rodeo ballad\nBrazilian romance\nBrazilian romantic\nBrazilian romantic ballad\nBrazilian romantic ballads\nBrazilian romantic music\nBrazilian romantic pop\nBrazilian romantic pop, Axé\nBrazilian romantic power ballad\nBrazilian romantic rock\nBrazilian salsa\nBrazilian samba\nBrazilian samba canção\nBrazilian samba choro\nBrazilian samba funk\nBrazilian samba pop\nBrazilian samba rock\nBrazilian samba tango\nBrazilian samba, R&B, soul\nBrazilian samba, cinematic, MPB\nBrazilian samba, cinematic, romantic\nBrazilian samba, classical fusion, theatrical\nBrazilian samba, electronic dance, carnival\nBrazilian samba, soul, Christmas\nBrazilian samba-blues\nBrazilian samba-pop\nBrazilian samba-reggae\nBrazilian samba-rock\nBrazilian seresta\nBrazilian sertanejo, power ballad\nBrazilian show tune\nBrazilian singer-songwriter\nBrazilian sofregão\nBrazilian soul\nBrazilian soul MPB\nBrazilian soul funk\nBrazilian soul-funk\nBrazilian soul-pop\nBrazilian soul-rock\nBrazilian spiritual\nBrazilian spiritual rock\nBrazilian sports anthem\nBrazilian stadium rock\nBrazilian surf rock\nBrazilian tango\nBrazilian tech house\nBrazilian tech-house\nBrazilian techno\nBrazilian techno brega\nBrazilian techno-brega\nBrazilian theater\nBrazilian theatrical\nBrazilian torch song\nBrazilian trap\nBrazilian trap R&B\nBrazilian trap chillwave\nBrazilian trap chiptune\nBrazilian trap funk\nBrazilian trap funk carioca\nBrazilian trap lo-fi\nBrazilian trap vaporwave\nBrazilian trap, R&B\nBrazilian trap, ambient R&B\nBrazilian trap, anime hip hop\nBrazilian trap, chillwave\nBrazilian trap, chiptune\nBrazilian trap, chiptune, hyperpop\nBrazilian trap, cloud rap\nBrazilian trap, cloud rap, pluggnb\nBrazilian trap, cloud rap, vaporwave\nBrazilian trap, dream pop, R&B\nBrazilian trap, emo rap\nBrazilian trap, funk carioca\nBrazilian trap, gospel rap, pop-rap\nBrazilian trap, hip-hop\nBrazilian trap, horrorcore\nBrazilian trap, hyper-trap\nBrazilian trap, hyperpop\nBrazilian trap, hyperpop, glitch\nBrazilian trap, lo-fi hip hop\nBrazilian trap, lo-fi hip-hop\nBrazilian trap, melodic R&B\nBrazilian trap, melodic R&B, world music\nBrazilian trap, melodic funk\nBrazilian trap, melodic rap\nBrazilian trap, melodic rap, pluggnb\nBrazilian trap, motivational pop-rap\nBrazilian trap, pluggnb\nBrazilian trap, pluggnb, J-pop\nBrazilian trap, pluggnb, lo-fi pop\nBrazilian trap, rage rap\nBrazilian trap, sad rap\nBrazilian trap, sad trap\nBrazilian trap, sad trap, emotional hip-hop\nBrazilian trap, sad trap, pluggnb\nBrazilian trap, vaporwave\nBrazilian trap-R&B\nBrazilian trap-funk\nBrazilian trap-pop\nBrazilian trap-soul\nBrazilian tribal\nBrazilian tribal house\nBrazilian trip-hop\nBrazilian vaneira\nBrazilian viola caipira\nBrazilian vocal\nBrazilian vocal music\nBrazilian waltz\nBrazilian world music\nBrazilian, Afro-Brazilian, percussion-driven\nBrazilian, Afro-Brazilian, rhythmic\nBrazilian, Afro-Brazilian, samba\nBrazilian, Afro-Cuban, world music\nBrazilian, Afrobeat, psychedelic\nBrazilian, MPB, ambient\nBrazilian, acoustic, flamenco\nBrazilian, acoustic, spiritual\nBrazilian, acoustic, vocal\nBrazilian, bossa nova, cinematic\nBrazilian, cinematic, folk\nBrazilian, cinematic, orchestral\nBrazilian, devotional, uplifting\nBrazilian, flamenco, Latin\nBrazilian, flamenco, acoustic\nBrazilian, folk, flamenco\nBrazilian, gospel, folk\nBrazilian, mandolin, theatrical\nBrazilian, melancholic, cinematic\nBrazilian, melancholic, theatrical\nBrazilian, organic, psychedelic\nBrazilian, samba, Afro-Brazilian\nBrazilian, samba, accordion\nBrazilian, samba, acoustic\nBrazilian, samba, flamenco fusion\nBrazilian, samba, folk\nBrazilian, samba, lo-fi\nBrazilian, samba, melancholic\nBrazilian, samba, melancholic acoustic\nBrazilian, samba, orchestral\nBrazilian, samba, passion\nBrazilian, samba, percussion\nBrazilian, samba, spiritual\nBrazilian, samba, theatrical\nBrazilian, spiritual, Afro-Brazilian\nBrazilian, spiritual, acoustic\nBrazilian, spiritual, gospel\nBrazilian, spiritual, uplifting\nBrazilian, spiritual, world music\nBrazilian, theatrical, choral\nBrazilian, theatrical, classical fusion\nBrazilian, world music, upbeat\nBrega\nBrega Arrocha\nBrega Brega\nBrega Cumbia\nBrega DJ\nBrega Eletrônico\nBrega Forró\nBrega Forró Eletrônico\nBrega Funk\nBrega Funk Carioca\nBrega Funk, Piseiro\nBrega Funkot\nBrega Gospel\nBrega Nova\nBrega Piseiro\nBrega Pop\nBrega Romântico\nBrega Romântico Forró\nBrega Romântico Sertanejo\nBrega Samba\nBrega Samba-rock\nBrega Serehor\nBrega Sertanejo\nBrega Sertanejo Romântico\nBrega chiptune\nBrega gospel\nBrega pop\nBrega pop Forró\nBrega pop-rock\nBrega rock\nBrega romântico\nBrega samba\nBrega samba-pop\nBrega samba-rock\nBrega sertanejo\nBrega sertanejo, Forró, romantic ballad\nBrega sertanejo, samba-pop\nBrega soul\nBrega trucker\nBrega, Arrocha\nBrega, Brazilian pop\nBrega, Brazilian pop-rock\nBrega, Christian pop, Brazilian pop\nBrega, Forró\nBrega, Forró Eletrônico\nBrega, Forró Eletrônico, melancholic ballad\nBrega, Forró Eletrônico, pop-rock\nBrega, Forró Romântico\nBrega, Forró romântico\nBrega, Forró romântico, Forró Eletrônico\nBrega, Forró, Brazilian pop\nBrega, Forró, Christian\nBrega, Forró, Latin pop\nBrega, Forró, Sertanejo\nBrega, Forró, dance pop\nBrega, Forró, pop\nBrega, Forró, romantic pop\nBrega, Forró, synth pop\nBrega, New Jack Swing\nBrega, Samba\nBrega, Samba-pop\nBrega, Samba-rock\nBrega, Sertanejo\nBrega, Sertanejo, Brazilian pop\nBrega, Sertanejo, pop\nBrega, chiptune\nBrega, chiptune, Brazilian pop\nBrega, dream pop, theatrical pop-rock\nBrega, electronic dance\nBrega, forró\nBrega, samba-pop\nBrega-Brega\nBrega-Polka\nBrega-dance\nBrega-disco\nBrega-pop\nBrega-reggae\nBrega-romântico\nBrega-samba\nBritish Invasion\nBritish Invasion rock\nBritish brass band\nBritish folk\nBritish folk rock\nBritish folk-pop\nBritish folk-punk\nBritish folk-rock\nBritish hip hop\nBritish hip-hop\nBritish indie folk\nBritish indie pop\nBritish indie rock\nBritish music hall\nBritish pop\nBritish pop, music hall\nBritish pop-rock\nBritish pub rock\nBritish punk rock\nBritish rock\nBritish rock and roll\nBritpop\nBroadway\nBroadway ballad\nBroadway funk\nBroadway funk soul\nBroadway funk-pop\nBroadway funk-rock\nBroadway hip-hop\nBroadway jazz\nBroadway musical\nBroadway pop\nBroadway pop, funk R&B\nBroadway pop-rock\nBroadway pop-rock funk\nBroadway rock\nBroadway show tune\nBroadway show tune, klezmer, big band\nBroadway showtune\nBroadway soul\nBroadway swing\nBroadway, Eurodance\nBroadway, country-rock\nBroadway, eurodance\nBronx drill\nBrooklyn drill\nBuddhist ambient\nBuddhist chant\nBuddhist chant, electronic, lo-fi\nBuddhist hymn\nBuddhist meditation\nBuddhist music\nBuddhist pop\nBuddhist spiritual\nBulgarian folk\nBulgarian gangsta rap\nBulgarian hip hop\nBulgarian hip-hop\nBulgarian hip-hop trap\nBulgarian trap\nC-Pop R&B\nC-Pop R&B lo-fi hip-hop\nC-Pop R&B trap\nC-Pop trap-R&B\nC-Pop, R&B, cloud rap\nC-Pop, lo-fi trap, R&B\nC-Rap\nC-Rap trap\nC-Rap wuxia\nC-Rap, chiptune, trap\nC-Rap, electronic dance\nC-Rap, melodic trap\nC-Rap, melodic trap, chiptune\nC-Rap, trap, cinematic\nC-Rock\nC-Rock Guofeng\nC-Rock, Anisong, electronic rock\nC-Rock, trap, nu-metal\nC-pop\nC-pop 80s anime\nC-pop Afrobeats\nC-pop Afrobeats R&B\nC-pop Bossa Nova\nC-pop Cantopop\nC-pop Cantopop bedroom pop\nC-pop Cantopop chiptune\nC-pop Christmas\nC-pop EDM\nC-pop EDM Guofeng\nC-pop EDM J-pop\nC-pop EDM K-pop\nC-pop EDM anime\nC-pop EDM chiptune\nC-pop EDM dance-pop\nC-pop EDM folk\nC-pop EDM future bass\nC-pop EDM hardstyle\nC-pop EDM hip-hop\nC-pop EDM trance\nC-pop EDM trap\nC-pop EDM world music\nC-pop EDM-pop\nC-pop Eurobeat\nC-pop Eurobeat J-pop\nC-pop Eurobeat trance\nC-pop Eurodance\nC-pop Eurodance J-pop\nC-pop Eurodance trance\nC-pop European folk\nC-pop Gu Feng\nC-pop Guofeng\nC-pop Guofeng chillout\nC-pop Guofeng electronic\nC-pop J-pop\nC-pop J-pop anime\nC-pop J-pop anime soundtrack\nC-pop J-pop ballad\nC-pop J-pop chiptune\nC-pop J-pop cinematic\nC-pop J-pop dance\nC-pop J-pop dance-pop\nC-pop J-pop electronic pop\nC-pop J-pop festive\nC-pop J-pop future bass\nC-pop J-pop hip-hop\nC-pop J-pop idol\nC-pop J-pop lo-fi\nC-pop J-pop lo-fi hip-hop\nC-pop J-pop rock\nC-pop J-pop video game\nC-pop J-pop video game music\nC-pop J-rock\nC-pop J-rock anime\nC-pop J-rock cinematic\nC-pop J-rock power ballad\nC-pop K-pop\nC-pop K-pop anime\nC-pop K-pop fusion\nC-pop K-pop trap\nC-pop Latin\nC-pop Latin dance\nC-pop Latin fusion\nC-pop Latin pop\nC-pop Latin pop dance\nC-pop Latin pop hip-hop\nC-pop Mandopop\nC-pop R&B\nC-pop R&B Afrobeats\nC-pop R&B EDM\nC-pop R&B Neo-Soul\nC-pop R&B ambient\nC-pop R&B ballad\nC-pop R&B boom-bap\nC-pop R&B chill trap\nC-pop R&B chill-pop\nC-pop R&B chillwave\nC-pop R&B chiptune\nC-pop R&B cinematic\nC-pop R&B city pop\nC-pop R&B city-pop\nC-pop R&B dance-pop\nC-pop R&B deep house\nC-pop R&B downtempo\nC-pop R&B dream pop\nC-pop R&B dreamy\nC-pop R&B dreamy synth-pop\nC-pop R&B electronic\nC-pop R&B funk\nC-pop R&B fusion\nC-pop R&B future bass\nC-pop R&B hip-hop\nC-pop R&B jazz\nC-pop R&B lo-fi\nC-pop R&B lo-fi hip hop\nC-pop R&B lo-fi hip-hop\nC-pop R&B lo-fi trap\nC-pop R&B lounge\nC-pop R&B neo-soul\nC-pop R&B orchestral\nC-pop R&B pop-rock\nC-pop R&B smooth jazz\nC-pop R&B soul\nC-pop R&B synth-pop\nC-pop R&B trap\nC-pop R&B trap-pop\nC-pop R&B trap-soul\nC-pop R&B vaporwave\nC-pop R&B video game\nC-pop R&B, Mongolian fusion\nC-pop R&B, lo-fi hip-hop\nC-pop UK garage\nC-pop Vocaloid\nC-pop acoustic\nC-pop acoustic R&B\nC-pop acoustic ballad\nC-pop alternative R&B\nC-pop alternative rock\nC-pop ambient\nC-pop ambient trap\nC-pop ancient style\nC-pop anime\nC-pop anime ballad\nC-pop anime chiptune\nC-pop anime opening\nC-pop anime orchestral\nC-pop anime pop\nC-pop anime pop-rock\nC-pop anime rock\nC-pop anime soundtrack\nC-pop anime theme\nC-pop anime-pop\nC-pop anime-style pop-rock\nC-pop ballad\nC-pop ballad hip-hop\nC-pop ballad lo-fi hip-hop\nC-pop ballad, J-rock, pop-rock\nC-pop ballad, alternative rock\nC-pop ballad, anime theme, cinematic\nC-pop ballad, cinematic pop, epic rock\nC-pop ballad, cinematic rock\nC-pop ballad, contemporary R&B\nC-pop ballad, electronic dance-pop\nC-pop ballad, funk pop-rock\nC-pop ballad, heartfelt hip-hop\nC-pop ballad, hip-hop\nC-pop ballad, indie pop\nC-pop ballad, jazz, soul\nC-pop ballad, lo-fi hip-hop\nC-pop ballad, narrative hip-hop\nC-pop ballad, nostalgic hip-hop\nC-pop ballad, pop-rap\nC-pop ballad, pop-rock\nC-pop ballad, pop-rock, R&B\nC-pop ballad, pop-rock, cinematic\nC-pop ballad, pop-rock, hip-hop\nC-pop ballad, pop-rock, synth-pop\nC-pop ballad, smooth jazz, anime soundtrack\nC-pop ballad, symphonic rock\nC-pop banda\nC-pop bedroom pop\nC-pop big band\nC-pop big band swing\nC-pop blues\nC-pop blues-rock\nC-pop bossa nova\nC-pop bossa nova lounge\nC-pop bossa nova lounge jazz\nC-pop bubblegum\nC-pop bubblegum pop\nC-pop cabaret swing\nC-pop children's\nC-pop children's music\nC-pop chill-out\nC-pop chillwave\nC-pop chillwave lo-fi hip-hop\nC-pop chiptune\nC-pop chiptune J-pop\nC-pop chiptune J-rock\nC-pop chiptune anime\nC-pop chiptune emo rap\nC-pop chiptune hip-hop\nC-pop chiptune kawaii\nC-pop chiptune lo-fi\nC-pop chiptune lo-fi hip-hop\nC-pop chiptune pop-rock\nC-pop chiptune synth-pop\nC-pop chiptune trap\nC-pop cinematic\nC-pop cinematic electronic\nC-pop cinematic folk\nC-pop cinematic funk\nC-pop cinematic pop-rock\nC-pop cinematic rock\nC-pop city pop\nC-pop city pop R&B\nC-pop city pop jazz fusion\nC-pop city-pop\nC-pop city-pop anime\nC-pop complextro\nC-pop conscious hip-hop\nC-pop cumbia\nC-pop dance\nC-pop dance funk\nC-pop dance-pop\nC-pop dance-pop EDM\nC-pop dance-pop chiptune\nC-pop dance-pop hip-hop\nC-pop dance-pop trap\nC-pop dancehall\nC-pop dancehall reggaeton\nC-pop dark trap EDM\nC-pop dark trap R&B\nC-pop deep house\nC-pop disco\nC-pop disco funk\nC-pop disco-funk\nC-pop downtempo\nC-pop dramatic\nC-pop dream pop\nC-pop dream pop R&B\nC-pop dream pop electronic\nC-pop dream-pop\nC-pop dreamy\nC-pop dreamy ballad\nC-pop dreamy trap\nC-pop dubstep\nC-pop duet\nC-pop easy-listening\nC-pop electro house\nC-pop electro house future bass\nC-pop electro-house\nC-pop electro-pop\nC-pop electro-swing\nC-pop electronic\nC-pop electronic R&B\nC-pop electronic anime\nC-pop electronic cinematic\nC-pop electronic dance\nC-pop electronic dream-pop\nC-pop electronic fusion\nC-pop electronic hip-hop\nC-pop electronic pop\nC-pop electronic pop-rock\nC-pop electronic rock\nC-pop electronic rock dance-pop\nC-pop electronic rock hip-hop\nC-pop electronic trap\nC-pop electronicore\nC-pop emo rap\nC-pop emo rap alternative R&B\nC-pop emo rap indie rock\nC-pop emo-rap\nC-pop emotional hip-hop\nC-pop epic\nC-pop epic rock\nC-pop ethereal\nC-pop euro pop\nC-pop experimental\nC-pop festive\nC-pop flamenco\nC-pop flamenco fusion\nC-pop flamenco tango\nC-pop folk\nC-pop folk ballad\nC-pop folk dance\nC-pop folk fusion\nC-pop folk rock\nC-pop folk waltz\nC-pop folk-pop\nC-pop folk-rock\nC-pop folk-rock electronic\nC-pop funk\nC-pop funk R&B\nC-pop funk chiptune\nC-pop funk city pop\nC-pop funk dance-pop\nC-pop funk disco\nC-pop funk electro-pop\nC-pop funk electronic\nC-pop funk hip-hop\nC-pop funk jazz\nC-pop funk orchestral\nC-pop funk rock\nC-pop funk ska\nC-pop funk soul\nC-pop funk world music\nC-pop funk worldbeat\nC-pop funk-pop\nC-pop funk-rock\nC-pop funk-rock electronic\nC-pop fusion\nC-pop future bass\nC-pop future bass EDM\nC-pop future bass chiptune\nC-pop future bass hardstyle\nC-pop future bass kawaii bass\nC-pop future bass rock\nC-pop future bass trap\nC-pop gufeng\nC-pop guofeng\nC-pop gypsy jazz\nC-pop happy hardcore\nC-pop happy hardcore J-core\nC-pop hard dance\nC-pop hard rock\nC-pop hardstyle\nC-pop hardstyle big room\nC-pop hardstyle chiptune\nC-pop hardstyle hip-hop\nC-pop hardstyle trap\nC-pop hip-hop\nC-pop hip-hop EDM\nC-pop hip-hop Latin\nC-pop hip-hop R&B\nC-pop hip-hop acoustic\nC-pop hip-hop ballad\nC-pop hip-hop chiptune\nC-pop hip-hop cinematic\nC-pop hip-hop dance-pop\nC-pop hip-hop dream pop\nC-pop hip-hop dreamy indie-pop\nC-pop hip-hop electronic\nC-pop hip-hop funk\nC-pop hip-hop fusion\nC-pop hip-hop future bass\nC-pop hip-hop lo-fi\nC-pop hip-hop rock\nC-pop hip-hop sentimental ballad\nC-pop hip-hop synth-pop\nC-pop hip-hop trap\nC-pop holiday\nC-pop house\nC-pop hyperpop\nC-pop hyperpop EDM\nC-pop hyperpop anime\nC-pop hyperpop children's music\nC-pop hyperpop chiptune\nC-pop hyperpop city pop\nC-pop hyperpop emo-rap\nC-pop hyperpop future bass\nC-pop hyperpop indie rock\nC-pop hyperpop kawaii future bass\nC-pop hyperpop lo-fi\nC-pop hyperpop trance\nC-pop hyperpop trap\nC-pop idol\nC-pop idol pop anime\nC-pop indie pop\nC-pop indie pop emo rap\nC-pop indie pop lo-fi R&B\nC-pop indie pop lo-fi hip-hop\nC-pop indie pop-rock\nC-pop indie rock\nC-pop indie-pop\nC-pop industrial rock\nC-pop instrumental\nC-pop jazz\nC-pop jazz R&B\nC-pop jazz ballad\nC-pop jazz blues\nC-pop jazz fusion\nC-pop jazz lounge\nC-pop jazz neo-soul\nC-pop jazz orchestral\nC-pop jazz pop\nC-pop jazz rock\nC-pop jazz soul\nC-pop jazz-funk\nC-pop jazz-pop\nC-pop jazz-rock\nC-pop kawaii\nC-pop kawaii J-pop\nC-pop kawaii anime\nC-pop kawaii future bass chiptune\nC-pop lo-fi\nC-pop lo-fi R&B\nC-pop lo-fi bedroom pop\nC-pop lo-fi chiptune\nC-pop lo-fi hip hop\nC-pop lo-fi hip hop retro-funk\nC-pop lo-fi hip-hop\nC-pop lo-fi hip-hop R&B\nC-pop lo-fi hip-hop ambient\nC-pop lo-fi hip-hop ambient pop\nC-pop lo-fi hip-hop chiptune\nC-pop lo-fi hip-hop dream pop\nC-pop lo-fi hip-hop retro-funk\nC-pop lo-fi hip-hop romantic R&B\nC-pop lo-fi hip-hop sentimental ballad\nC-pop lo-fi hip-hop trap\nC-pop lo-fi hip-hop vaporwave\nC-pop lo-fi kawaii\nC-pop lo-fi pop\nC-pop lo-fi trap\nC-pop lofi\nC-pop lounge\nC-pop lounge jazz\nC-pop lounge-jazz\nC-pop lullaby\nC-pop melancholic\nC-pop melancholic cinematic\nC-pop melancholic electronic\nC-pop melancholic hip-hop\nC-pop melancholic trap-pop\nC-pop melancholic wuxia\nC-pop melodic hip-hop trap\nC-pop melodic rap drill\nC-pop melodic trap\nC-pop merengue\nC-pop metalcore\nC-pop minimalist\nC-pop musical theater\nC-pop narrative\nC-pop neo-classical\nC-pop neo-soul\nC-pop neo-soul R&B\nC-pop neo-soul city pop\nC-pop neo-soul funk\nC-pop neo-soul jazz\nC-pop neo-soul lo-fi\nC-pop neo-soul lo-fi hip-hop\nC-pop neo-soul lounge jazz\nC-pop new age\nC-pop noir-jazz\nC-pop nu-disco\nC-pop nu-metal\nC-pop orchestral\nC-pop orchestral ballad\nC-pop orchestral rock\nC-pop patriotic\nC-pop piano ballad\nC-pop pop-punk\nC-pop pop-rap\nC-pop pop-rap synth-pop\nC-pop pop-rock\nC-pop pop-rock EDM\nC-pop pop-rock hip-hop\nC-pop power ballad\nC-pop power metal\nC-pop power rock\nC-pop power-pop\nC-pop progressive house\nC-pop progressive house EDM\nC-pop progressive house trance\nC-pop psychedelic\nC-pop rap\nC-pop rap ballad\nC-pop reggae ska\nC-pop reggaeton\nC-pop reggaeton-lite\nC-pop retro\nC-pop retro Eurodance\nC-pop retro anime\nC-pop retro chiptune\nC-pop retro dance-pop\nC-pop retro electronic\nC-pop retro folk-pop\nC-pop retro funk\nC-pop retro game\nC-pop retro new wave surf rock\nC-pop retro rock chiptune\nC-pop retro surf-rock\nC-pop retro synth\nC-pop retro synth-pop\nC-pop retro video game\nC-pop retro wuxia\nC-pop retro-dance\nC-pop retro-funk disco\nC-pop retro-funk hip-hop\nC-pop retro-futuristic\nC-pop retro-swing\nC-pop rock\nC-pop rock ballad\nC-pop rock electronic\nC-pop rock fusion\nC-pop rock metal\nC-pop rock opera\nC-pop rock orchestral\nC-pop rock, EDM, atmospheric\nC-pop rock, Eurodance, theatrical\nC-pop rock, J-rock\nC-pop rock, cinematic electronic, traditional fusion\nC-pop rock, cinematic hip-hop\nC-pop rock, cinematic orchestral\nC-pop rock, cinematic, dubstep\nC-pop rock, dubstep, hardstyle\nC-pop rock, hardstyle, EDM\nC-pop rock, synth-pop, theatrical\nC-pop rock, traditional Chinese, hip-hop\nC-pop rock, trap, cinematic\nC-pop romantic\nC-pop romantic ballad\nC-pop romantic cinematic\nC-pop romantic duet\nC-pop romantic hip-hop\nC-pop salsa\nC-pop samba\nC-pop sentimental\nC-pop sentimental ballad\nC-pop singer-songwriter\nC-pop ska reggae\nC-pop smooth jazz\nC-pop smooth jazz lounge\nC-pop soft rock blues\nC-pop soul\nC-pop soul funk\nC-pop soul jazz\nC-pop stadium rock\nC-pop surf rock\nC-pop surf rock gypsy jazz\nC-pop surf-rock\nC-pop swing\nC-pop symphonic metal\nC-pop symphonic rock\nC-pop synth-funk\nC-pop synth-pop\nC-pop synth-pop chiptune\nC-pop synth-pop trap\nC-pop synthwave\nC-pop tango Latin\nC-pop techno\nC-pop theatrical\nC-pop trance\nC-pop trance EDM\nC-pop trance hardstyle\nC-pop trance synth-pop\nC-pop trance-pop\nC-pop trancecore\nC-pop trap\nC-pop trap EDM\nC-pop trap R&B\nC-pop trap ambient\nC-pop trap ambient synth-pop\nC-pop trap atmospheric R&B\nC-pop trap atmospheric pop\nC-pop trap chillwave\nC-pop trap chiptune\nC-pop trap cinematic\nC-pop trap cloud rap\nC-pop trap dark pop\nC-pop trap dream pop\nC-pop trap dreamy electronic\nC-pop trap dreamy synth-pop\nC-pop trap electronic\nC-pop trap electronic rock\nC-pop trap experimental\nC-pop trap fusion\nC-pop trap future bass\nC-pop trap hardstyle\nC-pop trap hip-hop\nC-pop trap horrorcore\nC-pop trap hyperpop\nC-pop trap industrial\nC-pop trap lo-fi\nC-pop trap lo-fi hip-hop\nC-pop trap orchestral\nC-pop trap sentimental pop\nC-pop trap soul\nC-pop trap synth-pop\nC-pop trap whimsical pop\nC-pop trap world music\nC-pop trap-EDM\nC-pop trap-R&B\nC-pop trap-pop\nC-pop trap-rap\nC-pop trap-soul\nC-pop trap-soul future bass\nC-pop trip-hop\nC-pop trip-hop R&B\nC-pop trip-hop electronic\nC-pop trip-hop lo-fi hip-hop\nC-pop tropical\nC-pop upbeat\nC-pop vaporwave\nC-pop vaporwave lo-fi hip-hop\nC-pop waltz\nC-pop whimsical\nC-pop whimsical ballad\nC-pop world fusion\nC-pop world music\nC-pop worldbeat\nC-pop worship\nC-pop wuxia\nC-pop 古风\nC-pop 喊麦\nC-pop, 80s anime\nC-pop, 90s R&B\nC-pop, 90s R&B, city pop\nC-pop, 90s R&B, funk\nC-pop, 90s R&B, hip-hop\nC-pop, 90s R&B, new jack swing\nC-pop, 90s R&B, synth-pop\nC-pop, 90s R&B, trip-hop\nC-pop, 90s anime\nC-pop, 90s anime, synth rock\nC-pop, 90s dance-pop\nC-pop, 90s dance-pop, Eurodance\nC-pop, 90s dance-pop, hip-hop\nC-pop, Afro-Latin fusion\nC-pop, Asian electronic\nC-pop, Axé\nC-pop, Axé, Forró\nC-pop, Axé, Samba-reggae\nC-pop, Axé, cinematic\nC-pop, Bhangra, ambient\nC-pop, Bhangra, cinematic\nC-pop, Bollywood, Bhangra\nC-pop, Bollywood, dance\nC-pop, Bossa Nova\nC-pop, Bossa Nova, pop-rock\nC-pop, Brazilian funk, cinematic\nC-pop, Brazilian pop-rock\nC-pop, Cantopop, EDM\nC-pop, Cantopop, pop-rock\nC-pop, Cantopop, sentimental ballad\nC-pop, Central Asian folk\nC-pop, Central Asian folk, electronic\nC-pop, Chinese electronic\nC-pop, Chinese folk\nC-pop, Chinese folk, cinematic\nC-pop, Chinese folk, emotional ballad\nC-pop, Chinese hip-hop, cinematic trap\nC-pop, Chinese opera\nC-pop, Chinese opera, hip-hop\nC-pop, Chinese-style rock\nC-pop, Christmas\nC-pop, Christmas ballad\nC-pop, Christmas, fairytale\nC-pop, City Pop, contemporary R&B\nC-pop, Cumbia\nC-pop, Dangdut Koplo\nC-pop, Dangdut Koplo, Funkot\nC-pop, Dangdut Koplo, cinematic\nC-pop, Dangdut, cinematic pop\nC-pop, EDM\nC-pop, EDM, Guofeng\nC-pop, EDM, J-pop\nC-pop, EDM, J-rock\nC-pop, EDM, K-pop\nC-pop, EDM, Latin\nC-pop, EDM, ambient\nC-pop, EDM, anime\nC-pop, EDM, anime pop\nC-pop, EDM, anime theme\nC-pop, EDM, anthemic\nC-pop, EDM, ballad\nC-pop, EDM, big room house\nC-pop, EDM, chiptune\nC-pop, EDM, cinematic\nC-pop, EDM, cyberpunk\nC-pop, EDM, dance\nC-pop, EDM, dance-pop\nC-pop, EDM, dream pop\nC-pop, EDM, dreamy\nC-pop, EDM, dubstep\nC-pop, EDM, festive\nC-pop, EDM, future bass\nC-pop, EDM, futuristic\nC-pop, EDM, happy hardcore\nC-pop, EDM, hardstyle\nC-pop, EDM, hip-hop\nC-pop, EDM, hyperpop\nC-pop, EDM, live performance\nC-pop, EDM, orchestral\nC-pop, EDM, pop-rock\nC-pop, EDM, progressive house\nC-pop, EDM, rock\nC-pop, EDM, synth pop\nC-pop, EDM, synth-pop\nC-pop, EDM, synthwave\nC-pop, EDM, traditional Chinese\nC-pop, EDM, traditional Chinese opera\nC-pop, EDM, traditional fusion\nC-pop, EDM, trance\nC-pop, EDM, trance, hip-hop\nC-pop, EDM, trance-pop\nC-pop, EDM, trap\nC-pop, EDM, tropical house\nC-pop, EDM, world music\nC-pop, EDM, wuxia\nC-pop, EDM-pop\nC-pop, EDM-trap\nC-pop, East Asian fusion, hip hop\nC-pop, Eastern-influenced, electronic\nC-pop, Eurobeat\nC-pop, Eurobeat, City Pop\nC-pop, Eurobeat, J-pop\nC-pop, Eurobeat, anime\nC-pop, Eurobeat, anime theme\nC-pop, Eurobeat, chiptune\nC-pop, Eurobeat, dance\nC-pop, Eurobeat, happy hardcore\nC-pop, Eurobeat, hyperpop\nC-pop, Eurobeat, rhythm game\nC-pop, Eurobeat, trance\nC-pop, Eurobeat, video game music\nC-pop, Eurodance\nC-pop, Eurodance, 2000s dance\nC-pop, Eurodance, 90s dance\nC-pop, Eurodance, 90s dance-pop\nC-pop, Eurodance, 90s retro\nC-pop, Eurodance, EDM\nC-pop, Eurodance, Italo disco\nC-pop, Eurodance, J-pop\nC-pop, Eurodance, J-rock\nC-pop, Eurodance, bubblegum pop\nC-pop, Eurodance, chiptune\nC-pop, Eurodance, cinematic\nC-pop, Eurodance, dance\nC-pop, Eurodance, dance-pop\nC-pop, Eurodance, electronic\nC-pop, Eurodance, happy hardcore\nC-pop, Eurodance, hardstyle\nC-pop, Eurodance, hip-hop\nC-pop, Eurodance, hip-house\nC-pop, Eurodance, hyperpop\nC-pop, Eurodance, pop-rock\nC-pop, Eurodance, retro\nC-pop, Eurodance, retro dance\nC-pop, Eurodance, retro-futuristic\nC-pop, Eurodance, stadium rock\nC-pop, Eurodance, synth-pop\nC-pop, Eurodance, synthpop\nC-pop, Eurodance, synthwave\nC-pop, Eurodance, techno\nC-pop, Eurodance, trance\nC-pop, Eurodance, trance-pop\nC-pop, Eurodance, upbeat\nC-pop, European cafe\nC-pop, European folk\nC-pop, European folk, ballad\nC-pop, European folk, circus music\nC-pop, European folk, musette\nC-pop, Forró\nC-pop, Forró Eletrônico\nC-pop, Gu Feng\nC-pop, Gu Feng, ballad\nC-pop, Gu Feng, cinematic\nC-pop, Gu Feng, dance-pop\nC-pop, Gu Feng, modern\nC-pop, Gu Feng, traditional Chinese\nC-pop, Gufeng\nC-pop, Gufeng, cinematic\nC-pop, Gufeng, electronic\nC-pop, Gufeng, hard rock\nC-pop, Gufeng, orchestral\nC-pop, Gufeng, pop-rock\nC-pop, Guofeng\nC-pop, Guofeng rock\nC-pop, Guofeng, EDM\nC-pop, Guofeng, ambient\nC-pop, Guofeng, ambient electronic\nC-pop, Guofeng, cinematic\nC-pop, Guofeng, dance-pop\nC-pop, Guofeng, dream pop\nC-pop, Guofeng, dreamy\nC-pop, Guofeng, dreamy electronic\nC-pop, Guofeng, dreamy pop\nC-pop, Guofeng, electronic\nC-pop, Guofeng, electronic dance\nC-pop, Guofeng, electronic dance-pop\nC-pop, Guofeng, electronic pop-rock\nC-pop, Guofeng, ethereal\nC-pop, Guofeng, lo-fi\nC-pop, Guofeng, lo-fi hip hop\nC-pop, Guofeng, modern\nC-pop, Guofeng, synth pop\nC-pop, Guofeng, trap\nC-pop, Guofeng, whimsical\nC-pop, Indian fusion\nC-pop, Indian fusion, cinematic pop\nC-pop, Italo disco\nC-pop, J-core\nC-pop, J-core, dance\nC-pop, J-core, happy hardcore\nC-pop, J-core, hyperpop\nC-pop, J-core, trance\nC-pop, J-pop\nC-pop, J-pop, EDM\nC-pop, J-pop, Eurobeat\nC-pop, J-pop, Mandopop\nC-pop, J-pop, Mongolian folk\nC-pop, J-pop, R&B, cinematic\nC-pop, J-pop, acoustic pop\nC-pop, J-pop, ambient\nC-pop, J-pop, anime\nC-pop, J-pop, anime opening\nC-pop, J-pop, anime soundtrack\nC-pop, J-pop, anime theme\nC-pop, J-pop, chill-hop\nC-pop, J-pop, chiptune\nC-pop, J-pop, cinematic\nC-pop, J-pop, city pop\nC-pop, J-pop, city-pop\nC-pop, J-pop, dance\nC-pop, J-pop, dance-pop\nC-pop, J-pop, dream pop\nC-pop, J-pop, electronic\nC-pop, J-pop, electronic, R&B\nC-pop, J-pop, ethereal\nC-pop, J-pop, ethnic fusion\nC-pop, J-pop, future bass\nC-pop, J-pop, happy hardcore\nC-pop, J-pop, hip-hop\nC-pop, J-pop, hyper-pop\nC-pop, J-pop, hyperpop\nC-pop, J-pop, idol\nC-pop, J-pop, kawaii-pop\nC-pop, J-pop, lo-fi\nC-pop, J-pop, pop-rock\nC-pop, J-pop, power ballad\nC-pop, J-pop, synth pop\nC-pop, J-pop, trance\nC-pop, J-pop, trap\nC-pop, J-pop, video game\nC-pop, J-pop, video game music\nC-pop, J-pop, video game soundtrack\nC-pop, J-rock\nC-pop, J-rock, Anisong\nC-pop, J-rock, EDM\nC-pop, J-rock, Vocaloid\nC-pop, J-rock, ambient\nC-pop, J-rock, anime\nC-pop, J-rock, anime ballad\nC-pop, J-rock, anime rock\nC-pop, J-rock, anime soundtrack\nC-pop, J-rock, anime theme\nC-pop, J-rock, anison\nC-pop, J-rock, ballad\nC-pop, J-rock, chiptune\nC-pop, J-rock, cinematic\nC-pop, J-rock, cinematic pop\nC-pop, J-rock, dream pop\nC-pop, J-rock, dubstep\nC-pop, J-rock, electronic\nC-pop, J-rock, electronic dance\nC-pop, J-rock, hyperpop\nC-pop, J-rock, lo-fi\nC-pop, J-rock, lo-fi hip hop\nC-pop, J-rock, metalcore\nC-pop, J-rock, piano ballad\nC-pop, J-rock, pop, piano ballad, Chinese traditional, hip-hop\nC-pop, J-rock, pop-R&B\nC-pop, J-rock, pop-rock\nC-pop, J-rock, power ballad\nC-pop, J-rock, power metal\nC-pop, J-rock, symphonic rock\nC-pop, J-rock, synth-pop\nC-pop, J-rock, trance\nC-pop, J-rock, trancecore\nC-pop, J-rock, trap\nC-pop, J-rock, video game music\nC-pop, J-rock, video game soundtrack\nC-pop, K-hip-hop\nC-pop, K-pop\nC-pop, K-pop ballad\nC-pop, K-pop, electronic\nC-pop, K-pop, electronic dance\nC-pop, K-pop, hyperpop\nC-pop, K-pop, trap\nC-pop, Latin cumbia\nC-pop, Latin dance\nC-pop, Latin funk\nC-pop, Latin fusion\nC-pop, Latin fusion, Middle Eastern\nC-pop, Latin house, trap\nC-pop, Latin jazz, ambient\nC-pop, Latin jazz, pop-rock\nC-pop, Latin pop\nC-pop, Latin pop, acoustic\nC-pop, Latin pop, cinematic\nC-pop, Latin pop, cinematic rock\nC-pop, Latin pop, electronic\nC-pop, Latin pop, flamenco rock\nC-pop, Latin rock\nC-pop, Latin, Middle Eastern\nC-pop, Latin, dance\nC-pop, Latin, festive\nC-pop, Latin, flamenco\nC-pop, Latin, orchestral\nC-pop, Latin, tango\nC-pop, Latin, tropical\nC-pop, Latin, world music\nC-pop, Mandopop\nC-pop, Mandopop rock\nC-pop, Mandopop, cinematic\nC-pop, Mandopop, dream pop\nC-pop, Mandopop, electronic\nC-pop, Mandopop, electronic hip-hop\nC-pop, Mandopop, hip-hop\nC-pop, Mandopop, pop-rock\nC-pop, Middle Eastern dance\nC-pop, Middle Eastern pop, dance\nC-pop, Middle Eastern, cinematic\nC-pop, Middle Eastern, electronic\nC-pop, Middle Eastern, theatrical\nC-pop, Mongolian folk\nC-pop, Mongolian folk, EDM\nC-pop, Mongolian folk, cinematic\nC-pop, Mongolian folk, electronic\nC-pop, Mongolian folk, epic\nC-pop, Mongolian folk, hip-hop\nC-pop, Mongolian folk, pop-rock\nC-pop, Moombahton\nC-pop, Moombahton, pop\nC-pop, New Jack Swing\nC-pop, R&B\nC-pop, R&B, Ancient Style\nC-pop, R&B, EDM\nC-pop, R&B, ambient\nC-pop, R&B, ambient pop\nC-pop, R&B, ballad\nC-pop, R&B, chill trap\nC-pop, R&B, chillwave\nC-pop, R&B, chiptune\nC-pop, R&B, cinematic\nC-pop, R&B, cinematic pop\nC-pop, R&B, city pop\nC-pop, R&B, cyberpunk\nC-pop, R&B, dance-pop\nC-pop, R&B, dream pop\nC-pop, R&B, dreamy\nC-pop, R&B, electronic\nC-pop, R&B, electronic pop\nC-pop, R&B, electronic rock\nC-pop, R&B, funk\nC-pop, R&B, funk, acoustic ballad\nC-pop, R&B, future bass\nC-pop, R&B, hip-hop\nC-pop, R&B, hyperpop\nC-pop, R&B, kawaii-pop\nC-pop, R&B, lo-fi\nC-pop, R&B, lo-fi hip hop\nC-pop, R&B, lo-fi hip-hop\nC-pop, R&B, melancholic\nC-pop, R&B, neo-soul\nC-pop, R&B, nostalgic\nC-pop, R&B, orchestral\nC-pop, R&B, orchestral synth\nC-pop, R&B, pop-rock\nC-pop, R&B, synth pop\nC-pop, R&B, synth-pop\nC-pop, R&B, synthwave\nC-pop, R&B, trap\nC-pop, R&B, trap soul\nC-pop, R&B, trap-soul\nC-pop, R&B, upbeat\nC-pop, R&B, vaporwave\nC-pop, R&B, world music\nC-pop, R&B-pop\nC-pop, South Indian film music, Christmas pop\nC-pop, Spanish-style, electronic\nC-pop, Tibetan folk, electronic\nC-pop, V-pop, dance\nC-pop, Vietnamese pop\nC-pop, Vietnamese pop, cinematic\nC-pop, Vietnamese pop, folk fusion\nC-pop, Vocaloid\nC-pop, Vocaloid style\nC-pop, Vocaloid, anime\nC-pop, Vocaloid, dance\nC-pop, Vocaloid, dreamy\nC-pop, Vocaloid, electronic\nC-pop, Wuxia, cinematic\nC-pop, Zouk, Kizomba\nC-pop, Zouk, Kompa\nC-pop, acoustic ballad\nC-pop, acoustic ballad, pop-rock\nC-pop, acoustic folk, upbeat pop\nC-pop, acoustic pop\nC-pop, acoustic, ambient\nC-pop, acoustic, dreamy\nC-pop, acoustic, pop-rock\nC-pop, alt-rock\nC-pop, alt-rock, acoustic ballad\nC-pop, alternative metal\nC-pop, alternative rock, hip-hop\nC-pop, ambient\nC-pop, ambient R&B\nC-pop, ambient ballad\nC-pop, ambient electronic\nC-pop, ambient electronica\nC-pop, ambient folk\nC-pop, ambient folk, cinematic\nC-pop, ambient folk, modern traditional\nC-pop, ambient hip-hop\nC-pop, ambient pop\nC-pop, ambient pop, cinematic\nC-pop, ambient pop, cinematic rock\nC-pop, ambient pop, electronic\nC-pop, ambient pop, emotional rock\nC-pop, ambient pop, indie rock\nC-pop, ambient pop, modern rock\nC-pop, ambient pop, pop-rock\nC-pop, ambient pop, post-rock\nC-pop, ambient pop, spiritual rock\nC-pop, ambient pop, traditional fusion\nC-pop, ambient pop, trap\nC-pop, ambient rock\nC-pop, ambient synth\nC-pop, ambient trap\nC-pop, ambient, Chinese traditional\nC-pop, ambient, Indian classical\nC-pop, ambient, Indian fusion\nC-pop, ambient, R&B\nC-pop, ambient, Spanish-influenced\nC-pop, ambient, Vocaloid\nC-pop, ambient, acoustic\nC-pop, ambient, ancient style\nC-pop, ambient, anime\nC-pop, ambient, anime ballad\nC-pop, ambient, anime soundtrack\nC-pop, ambient, ballad\nC-pop, ambient, baroque\nC-pop, ambient, baroque pop\nC-pop, ambient, blues\nC-pop, ambient, chill electronic\nC-pop, ambient, chillwave\nC-pop, ambient, cinematic\nC-pop, ambient, cinematic rock\nC-pop, ambient, dance-pop\nC-pop, ambient, devotional\nC-pop, ambient, downtempo\nC-pop, ambient, dream pop\nC-pop, ambient, dreamy\nC-pop, ambient, educational\nC-pop, ambient, electronic\nC-pop, ambient, emotional\nC-pop, ambient, ethereal\nC-pop, ambient, experimental\nC-pop, ambient, folk\nC-pop, ambient, folk rock\nC-pop, ambient, funk\nC-pop, ambient, future bass\nC-pop, ambient, glitch\nC-pop, ambient, guzheng\nC-pop, ambient, hip-hop\nC-pop, ambient, hyperpop\nC-pop, ambient, indie\nC-pop, ambient, indie rock\nC-pop, ambient, introspective\nC-pop, ambient, jazz\nC-pop, ambient, klezmer\nC-pop, ambient, lo-fi\nC-pop, ambient, lo-fi hip hop\nC-pop, ambient, meditative\nC-pop, ambient, melancholic\nC-pop, ambient, modern pop\nC-pop, ambient, new-age\nC-pop, ambient, orchestral\nC-pop, ambient, oud\nC-pop, ambient, pop-R&B\nC-pop, ambient, pop-rock\nC-pop, ambient, rap\nC-pop, ambient, rock\nC-pop, ambient, romantic\nC-pop, ambient, soul\nC-pop, ambient, spiritual\nC-pop, ambient, synth\nC-pop, ambient, synth-pop\nC-pop, ambient, synthwave\nC-pop, ambient, theatrical\nC-pop, ambient, traditional\nC-pop, ambient, traditional Chinese\nC-pop, ambient, traditional Chinese folk\nC-pop, ambient, traditional Chinese opera\nC-pop, ambient, traditional South Asian\nC-pop, ambient, traditional Vietnamese\nC-pop, ambient, traditional folk\nC-pop, ambient, traditional fusion\nC-pop, ambient, trap\nC-pop, ambient, trip-hop\nC-pop, ambient, uplifting\nC-pop, ambient, video game soundtrack\nC-pop, ambient, world fusion\nC-pop, ambient, world music\nC-pop, ancient style\nC-pop, ancient style, electronic\nC-pop, anime\nC-pop, anime J-pop\nC-pop, anime OST\nC-pop, anime OST, pop-rock\nC-pop, anime ballad\nC-pop, anime ballad, cinematic\nC-pop, anime ballad, cinematic pop\nC-pop, anime ballad, cinematic rock\nC-pop, anime ballad, dream pop\nC-pop, anime ballad, lo-fi\nC-pop, anime ballad, pop-rock\nC-pop, anime ballad, rock\nC-pop, anime dance-pop\nC-pop, anime electronic\nC-pop, anime music, children's music\nC-pop, anime opening\nC-pop, anime opening, EDM\nC-pop, anime opening, dance\nC-pop, anime opening, dance-pop\nC-pop, anime opening, electronic\nC-pop, anime opening, electronic dance\nC-pop, anime opening, future bass\nC-pop, anime opening, hyperpop\nC-pop, anime opening, pop-rock\nC-pop, anime pop\nC-pop, anime pop, electronic\nC-pop, anime pop, synth pop\nC-pop, anime pop-rock\nC-pop, anime pop-rock, J-rock\nC-pop, anime power ballad\nC-pop, anime rock\nC-pop, anime rock, electronic\nC-pop, anime rock, lo-fi electronic\nC-pop, anime rock, pop-rock\nC-pop, anime soundtrack\nC-pop, anime soundtrack, Guofeng\nC-pop, anime soundtrack, J-rock\nC-pop, anime soundtrack, Vocaloid\nC-pop, anime soundtrack, cinematic\nC-pop, anime soundtrack, cinematic pop\nC-pop, anime soundtrack, city-pop\nC-pop, anime soundtrack, dream pop\nC-pop, anime soundtrack, dreamy\nC-pop, anime soundtrack, electronic\nC-pop, anime soundtrack, electronic dance\nC-pop, anime soundtrack, future bass\nC-pop, anime soundtrack, kawaii\nC-pop, anime soundtrack, lo-fi\nC-pop, anime soundtrack, pop-jazz\nC-pop, anime soundtrack, pop-rock\nC-pop, anime soundtrack, power ballad\nC-pop, anime soundtrack, power rock\nC-pop, anime soundtrack, synth pop\nC-pop, anime soundtrack, synthwave\nC-pop, anime soundtrack, video game music\nC-pop, anime style\nC-pop, anime style, dance\nC-pop, anime style, electronic\nC-pop, anime theme\nC-pop, anime theme, EDM\nC-pop, anime theme, J-rock\nC-pop, anime theme, children's music\nC-pop, anime theme, chiptune\nC-pop, anime theme, cinematic\nC-pop, anime theme, cinematic pop\nC-pop, anime theme, dance\nC-pop, anime theme, dance-pop\nC-pop, anime theme, dream pop\nC-pop, anime theme, early 2000s\nC-pop, anime theme, electronic\nC-pop, anime theme, electronic dance\nC-pop, anime theme, electronic dance-pop\nC-pop, anime theme, electronic rock\nC-pop, anime theme, festive\nC-pop, anime theme, future bass\nC-pop, anime theme, hyperpop\nC-pop, anime theme, lo-fi\nC-pop, anime theme, lo-fi hip-hop\nC-pop, anime theme, pop-rock\nC-pop, anime theme, power ballad\nC-pop, anime theme, retro game\nC-pop, anime theme, retro synth\nC-pop, anime theme, retro video game\nC-pop, anime theme, symphonic rock\nC-pop, anime theme, synth pop\nC-pop, anime theme, synth-pop\nC-pop, anime theme, synthwave\nC-pop, anime theme, video game\nC-pop, anime theme, video game music\nC-pop, anime, EDM\nC-pop, anime, J-pop\nC-pop, anime, J-rock\nC-pop, anime, Vocaloid\nC-pop, anime, ambient\nC-pop, anime, ballad\nC-pop, anime, children's music\nC-pop, anime, chiptune\nC-pop, anime, cinematic\nC-pop, anime, dance\nC-pop, anime, dreamy\nC-pop, anime, electronic\nC-pop, anime, electronic dance\nC-pop, anime, electronic rock\nC-pop, anime, festive\nC-pop, anime, folk\nC-pop, anime, future bass\nC-pop, anime, hardstyle\nC-pop, anime, hyperpop\nC-pop, anime, kawaii\nC-pop, anime, lo-fi\nC-pop, anime, orchestral\nC-pop, anime, playful\nC-pop, anime, pop-rock\nC-pop, anime, rhythm game\nC-pop, anime, synth\nC-pop, anime, synth pop\nC-pop, anime, synthpop\nC-pop, anime, synthwave\nC-pop, anime, trance\nC-pop, anime, trap\nC-pop, anime, upbeat\nC-pop, anime, video game\nC-pop, anime, video game soundtrack\nC-pop, anime, whimsical\nC-pop, anime-inspired, pop-rock\nC-pop, anime-style\nC-pop, anime-style pop\nC-pop, anthemic\nC-pop, anthemic ballad\nC-pop, anthemic pop\nC-pop, anthemic, children's choir\nC-pop, anthemic, cinematic\nC-pop, anthemic, electronic\nC-pop, anthemic, hip-hop\nC-pop, anthemic, military march\nC-pop, anthemic, patriotic\nC-pop, anthemic, pop-rock\nC-pop, anthemic, rock\nC-pop, anthemic, theatrical\nC-pop, anthemic, traditional Chinese\nC-pop, anthemic, uplifting\nC-pop, artcore, J-core\nC-pop, artcore, ambient\nC-pop, atmospheric\nC-pop, atmospheric R&B\nC-pop, atmospheric ballad\nC-pop, atmospheric electronic\nC-pop, atmospheric pop\nC-pop, atmospheric pop, R&B\nC-pop, atmospheric pop, cinematic rock\nC-pop, atmospheric rock\nC-pop, atmospheric trap\nC-pop, atmospheric trap, emotional hip-hop\nC-pop, atmospheric, EDM\nC-pop, atmospheric, R&B\nC-pop, atmospheric, ambient\nC-pop, atmospheric, ballad\nC-pop, atmospheric, cinematic\nC-pop, atmospheric, downtempo\nC-pop, atmospheric, electronic\nC-pop, atmospheric, epic\nC-pop, atmospheric, folk\nC-pop, atmospheric, folk-pop\nC-pop, atmospheric, funk\nC-pop, atmospheric, hip-hop\nC-pop, atmospheric, introspective\nC-pop, atmospheric, lo-fi\nC-pop, atmospheric, melancholic\nC-pop, atmospheric, modern\nC-pop, atmospheric, modern ballad\nC-pop, atmospheric, modern traditional\nC-pop, atmospheric, moody\nC-pop, atmospheric, spiritual\nC-pop, atmospheric, synth-pop\nC-pop, atmospheric, synthwave\nC-pop, atmospheric, traditional fusion\nC-pop, atmospheric, trap\nC-pop, atmospheric, trip-hop\nC-pop, atmospheric, world fusion\nC-pop, ballad, dance-pop\nC-pop, ballad, synthwave\nC-pop, baroque, cumbia\nC-pop, baroque, power ballad\nC-pop, bedroom pop\nC-pop, bedroom pop, jazz\nC-pop, big band jazz, anime theme\nC-pop, big band, cinematic\nC-pop, big band, show tune\nC-pop, big band, swing\nC-pop, big band, theatrical\nC-pop, big room house\nC-pop, big room house, cinematic\nC-pop, big room house, hardstyle\nC-pop, blues-rock\nC-pop, blues-rock, ambient\nC-pop, boom-bap, R&B\nC-pop, boom-bap, ambient\nC-pop, boom-bap, cinematic\nC-pop, boom-bap, lo-fi hip hop\nC-pop, boom-bap, orchestral\nC-pop, boom-bap, retro synth\nC-pop, boom-bap, romantic\nC-pop, bossa nova\nC-pop, bossa nova, lounge\nC-pop, bossa nova, romantic pop\nC-pop, cafe music\nC-pop, cafe pop\nC-pop, children's lullaby\nC-pop, children's music\nC-pop, children's music, anime theme\nC-pop, children's music, video game\nC-pop, children's music, video game music\nC-pop, children's music, video game soundtrack\nC-pop, chill, funk\nC-pop, chillwave, trap\nC-pop, chiptune\nC-pop, chiptune, EDM\nC-pop, chiptune, Eurodance\nC-pop, chiptune, J-pop\nC-pop, chiptune, R&B\nC-pop, chiptune, Vocaloid\nC-pop, chiptune, ambient\nC-pop, chiptune, anime\nC-pop, chiptune, anime electronic\nC-pop, chiptune, anime soundtrack\nC-pop, chiptune, anime theme\nC-pop, chiptune, ballad\nC-pop, chiptune, bedroom pop\nC-pop, chiptune, breakcore\nC-pop, chiptune, cinematic\nC-pop, chiptune, dance\nC-pop, chiptune, dance-pop\nC-pop, chiptune, dream pop\nC-pop, chiptune, dreamy\nC-pop, chiptune, dubstep\nC-pop, chiptune, electro-house\nC-pop, chiptune, electronic\nC-pop, chiptune, electronic pop\nC-pop, chiptune, eurodance\nC-pop, chiptune, folk\nC-pop, chiptune, future bass\nC-pop, chiptune, happy hardcore\nC-pop, chiptune, hardstyle\nC-pop, chiptune, hip-hop\nC-pop, chiptune, hyper-pop\nC-pop, chiptune, hyperpop\nC-pop, chiptune, idol\nC-pop, chiptune, idol pop\nC-pop, chiptune, kawaii\nC-pop, chiptune, lo-fi\nC-pop, chiptune, lo-fi hip hop\nC-pop, chiptune, nostalgic\nC-pop, chiptune, orchestral\nC-pop, chiptune, pop\nC-pop, chiptune, pop-R&B\nC-pop, chiptune, pop-punk\nC-pop, chiptune, pop-rap\nC-pop, chiptune, pop-rock\nC-pop, chiptune, pop-trap\nC-pop, chiptune, retro\nC-pop, chiptune, retro game\nC-pop, chiptune, retro-futuristic\nC-pop, chiptune, synth pop\nC-pop, chiptune, synth-pop\nC-pop, chiptune, synthwave\nC-pop, chiptune, theatrical\nC-pop, chiptune, trance\nC-pop, chiptune, trap\nC-pop, chiptune, upbeat\nC-pop, chiptune, video game music\nC-pop, chiptune, wuxia\nC-pop, cinematic\nC-pop, cinematic EDM\nC-pop, cinematic R&B\nC-pop, cinematic ambient, trap\nC-pop, cinematic ballad\nC-pop, cinematic ballad, folk pop\nC-pop, cinematic ballad, pop-rock\nC-pop, cinematic ballad, traditional fusion\nC-pop, cinematic electronic\nC-pop, cinematic electronic rock\nC-pop, cinematic electronic, electronic rock\nC-pop, cinematic folk\nC-pop, cinematic folk, orchestral pop\nC-pop, cinematic folk, pop-rock\nC-pop, cinematic folk-pop\nC-pop, cinematic funk\nC-pop, cinematic fusion\nC-pop, cinematic hip hop\nC-pop, cinematic hip-hop\nC-pop, cinematic hip-hop, pop-rock\nC-pop, cinematic orchestral\nC-pop, cinematic pop\nC-pop, cinematic pop, R&B\nC-pop, cinematic pop, ambient rock\nC-pop, cinematic pop, anime soundtrack\nC-pop, cinematic pop, anime style\nC-pop, cinematic pop, anime theme\nC-pop, cinematic pop, anthemic rock\nC-pop, cinematic pop, ballad\nC-pop, cinematic pop, dream pop\nC-pop, cinematic pop, dreamy rock\nC-pop, cinematic pop, electronic\nC-pop, cinematic pop, electronic rock\nC-pop, cinematic pop, emotional ballad\nC-pop, cinematic pop, emotional rock\nC-pop, cinematic pop, epic rock\nC-pop, cinematic pop, folk rock\nC-pop, cinematic pop, fusion\nC-pop, cinematic pop, hip-hop\nC-pop, cinematic pop, indie ballad\nC-pop, cinematic pop, indie rock\nC-pop, cinematic pop, modern rock\nC-pop, cinematic pop, orchestral rock\nC-pop, cinematic pop, pop-rap\nC-pop, cinematic pop, pop-rock\nC-pop, cinematic pop, post-rock\nC-pop, cinematic pop, power ballad\nC-pop, cinematic pop, power rock\nC-pop, cinematic pop, rock\nC-pop, cinematic pop, rock ballad\nC-pop, cinematic pop, synth rock\nC-pop, cinematic pop, traditional Chinese\nC-pop, cinematic pop, traditional fusion\nC-pop, cinematic pop-rock\nC-pop, cinematic rock\nC-pop, cinematic rock, J-rock\nC-pop, cinematic rock, electronic\nC-pop, cinematic rock, gǔfēng\nC-pop, cinematic rock, metalcore\nC-pop, cinematic rock, orchestral\nC-pop, cinematic rock, traditional Chinese\nC-pop, cinematic synth\nC-pop, cinematic synth, anthemic\nC-pop, cinematic synth, wuxia\nC-pop, cinematic synth-pop\nC-pop, cinematic trap\nC-pop, cinematic world music\nC-pop, cinematic, 80s Mandopop\nC-pop, cinematic, 80s anime\nC-pop, cinematic, 80s pop\nC-pop, cinematic, 80s synth\nC-pop, cinematic, 90s anime\nC-pop, cinematic, 90s dance-pop\nC-pop, cinematic, Ancient Style\nC-pop, cinematic, Bollywood\nC-pop, cinematic, Bossa Nova\nC-pop, cinematic, Buddhist\nC-pop, cinematic, Chinese classical crossover\nC-pop, cinematic, Chinese fantasy\nC-pop, cinematic, Chinese opera\nC-pop, cinematic, Chinese-style\nC-pop, cinematic, Christian hip-hop\nC-pop, cinematic, EDM\nC-pop, cinematic, East Asian\nC-pop, cinematic, Eurodance\nC-pop, cinematic, Gu Feng\nC-pop, cinematic, Gufeng\nC-pop, cinematic, Guofeng\nC-pop, cinematic, Indian classical\nC-pop, cinematic, Indian fusion\nC-pop, cinematic, J-RPG\nC-pop, cinematic, J-pop\nC-pop, cinematic, J-rock\nC-pop, cinematic, JRPG\nC-pop, cinematic, Javanese\nC-pop, cinematic, Javanese folk\nC-pop, cinematic, Kayōkyoku\nC-pop, cinematic, Malay pop\nC-pop, cinematic, Mandopop\nC-pop, cinematic, Mandopop rock\nC-pop, cinematic, Mongolian folk\nC-pop, cinematic, R&B\nC-pop, cinematic, Sundanese pop\nC-pop, cinematic, Tamil folk\nC-pop, cinematic, Tibetan folk\nC-pop, cinematic, Turkish pop\nC-pop, cinematic, V-Pop\nC-pop, cinematic, Vocaloid\nC-pop, cinematic, Wuxia\nC-pop, cinematic, ambient\nC-pop, cinematic, ambient pop\nC-pop, cinematic, ambient rock\nC-pop, cinematic, ancient style\nC-pop, cinematic, anime\nC-pop, cinematic, anime OST\nC-pop, cinematic, anime ballad\nC-pop, cinematic, anime rock\nC-pop, cinematic, anime soundtrack\nC-pop, cinematic, anime theme\nC-pop, cinematic, anthemic\nC-pop, cinematic, atmospheric\nC-pop, cinematic, avant-garde\nC-pop, cinematic, ballad\nC-pop, cinematic, celebratory\nC-pop, cinematic, chiptune\nC-pop, cinematic, choral\nC-pop, cinematic, classical\nC-pop, cinematic, classical crossover\nC-pop, cinematic, dance\nC-pop, cinematic, dance-pop\nC-pop, cinematic, dark trap\nC-pop, cinematic, devotional\nC-pop, cinematic, disco\nC-pop, cinematic, downtempo\nC-pop, cinematic, downtempo trap\nC-pop, cinematic, dream pop\nC-pop, cinematic, dreamy\nC-pop, cinematic, dubstep\nC-pop, cinematic, duet\nC-pop, cinematic, electronic\nC-pop, cinematic, electronic dance\nC-pop, cinematic, electronic rock\nC-pop, cinematic, electronic-rock\nC-pop, cinematic, emotional\nC-pop, cinematic, emotional rock\nC-pop, cinematic, energetic\nC-pop, cinematic, epic\nC-pop, cinematic, epic ballad\nC-pop, cinematic, epic pop\nC-pop, cinematic, epic pop-rock\nC-pop, cinematic, epic rock\nC-pop, cinematic, ethereal\nC-pop, cinematic, ethnic fusion\nC-pop, cinematic, experimental\nC-pop, cinematic, fairytale\nC-pop, cinematic, fantasy\nC-pop, cinematic, festive\nC-pop, cinematic, flamenco\nC-pop, cinematic, folk\nC-pop, cinematic, folk fusion\nC-pop, cinematic, folk opera\nC-pop, cinematic, folk pop\nC-pop, cinematic, folk rock\nC-pop, cinematic, folk-dance\nC-pop, cinematic, folk-pop\nC-pop, cinematic, folk-rock\nC-pop, cinematic, funk\nC-pop, cinematic, funk-rock\nC-pop, cinematic, fusion\nC-pop, cinematic, future bass\nC-pop, cinematic, futuristic\nC-pop, cinematic, game soundtrack\nC-pop, cinematic, glitch\nC-pop, cinematic, gufeng\nC-pop, cinematic, gǔfēng\nC-pop, cinematic, hardstyle\nC-pop, cinematic, heroic\nC-pop, cinematic, hip hop\nC-pop, cinematic, hip-hop\nC-pop, cinematic, historical fantasy\nC-pop, cinematic, hybrid trap\nC-pop, cinematic, indie ballad\nC-pop, cinematic, indie folk\nC-pop, cinematic, indie rock\nC-pop, cinematic, lo-fi\nC-pop, cinematic, lo-fi hip hop\nC-pop, cinematic, lo-fi hip-hop\nC-pop, cinematic, lounge-funk\nC-pop, cinematic, martial\nC-pop, cinematic, martial arts\nC-pop, cinematic, melancholic\nC-pop, cinematic, modern\nC-pop, cinematic, modern Chinese\nC-pop, cinematic, modern ballad\nC-pop, cinematic, modern folk\nC-pop, cinematic, modern pop\nC-pop, cinematic, modern pop-trap\nC-pop, cinematic, modern rock\nC-pop, cinematic, modern traditional\nC-pop, cinematic, mystical\nC-pop, cinematic, narrative\nC-pop, cinematic, neo-classical\nC-pop, cinematic, new-age\nC-pop, cinematic, ney flute\nC-pop, cinematic, nostalgic\nC-pop, cinematic, nu-metal\nC-pop, cinematic, opera\nC-pop, cinematic, opera fusion\nC-pop, cinematic, opera rock\nC-pop, cinematic, operatic\nC-pop, cinematic, operatic rock\nC-pop, cinematic, orchestral\nC-pop, cinematic, orchestral pop\nC-pop, cinematic, orchestral pop-rock\nC-pop, cinematic, orchestral rock\nC-pop, cinematic, patriotic\nC-pop, cinematic, pop\nC-pop, cinematic, pop ballad\nC-pop, cinematic, pop sunda\nC-pop, cinematic, pop sundan\nC-pop, cinematic, pop-ballad\nC-pop, cinematic, pop-rap\nC-pop, cinematic, pop-rock\nC-pop, cinematic, pop-trap\nC-pop, cinematic, power ballad\nC-pop, cinematic, retro\nC-pop, cinematic, retro-electronic\nC-pop, cinematic, revolutionary\nC-pop, cinematic, ritual\nC-pop, cinematic, rock\nC-pop, cinematic, rock ballad\nC-pop, cinematic, rock fusion\nC-pop, cinematic, rock opera\nC-pop, cinematic, rock-opera\nC-pop, cinematic, romantic\nC-pop, cinematic, sci-fi\nC-pop, cinematic, sentimental\nC-pop, cinematic, spiritual\nC-pop, cinematic, symphonic\nC-pop, cinematic, symphonic rock\nC-pop, cinematic, synth\nC-pop, cinematic, synth ballad\nC-pop, cinematic, synth-pop\nC-pop, cinematic, synthwave\nC-pop, cinematic, taiko\nC-pop, cinematic, tango\nC-pop, cinematic, theatrical\nC-pop, cinematic, traditional\nC-pop, cinematic, traditional Chinese\nC-pop, cinematic, traditional Chinese fantasy\nC-pop, cinematic, traditional Chinese folk\nC-pop, cinematic, traditional Chinese opera\nC-pop, cinematic, traditional East Asian\nC-pop, cinematic, traditional South Asian\nC-pop, cinematic, traditional Vietnamese\nC-pop, cinematic, traditional folk\nC-pop, cinematic, traditional fusion\nC-pop, cinematic, trance\nC-pop, cinematic, trap\nC-pop, cinematic, trap-pop\nC-pop, cinematic, trip-hop\nC-pop, cinematic, upbeat\nC-pop, cinematic, uplifting\nC-pop, cinematic, video game\nC-pop, cinematic, video game soundtrack\nC-pop, cinematic, waltz\nC-pop, cinematic, whimsical\nC-pop, cinematic, world fusion\nC-pop, cinematic, world music\nC-pop, cinematic, world pop\nC-pop, cinematic, worldbeat\nC-pop, cinematic, worship\nC-pop, cinematic, wuxia\nC-pop, cinematic,古风\nC-pop, cinematic,喊麦\nC-pop, city pop\nC-pop, city pop, J-pop\nC-pop, city pop, R&B\nC-pop, city pop, electronic\nC-pop, city-pop, ambient\nC-pop, city-pop, anime soundtrack\nC-pop, city-pop, melancholic\nC-pop, city-pop, nu-disco\nC-pop, classical Chinese, orchestral ballad\nC-pop, classical, ambient\nC-pop, classical, ancient style\nC-pop, classical, cinematic\nC-pop, color bass\nC-pop, complextro\nC-pop, complextro, pop-rock\nC-pop, conscious hip-hop\nC-pop, contemporary R&B\nC-pop, cumbia cristiana\nC-pop, cumbia villera, reggaeton\nC-pop, cumbia, cinematic\nC-pop, cumbia, liturgical\nC-pop, cyberpunk, dance\nC-pop, cyberpunk, electronic\nC-pop, cyberpunk, hip-hop\nC-pop, cyberpunk, trap\nC-pop, dance\nC-pop, dance pop\nC-pop, dance pop, festive\nC-pop, dance, 2000s Eurodance\nC-pop, dance, 2000s nostalgia\nC-pop, dance, EDM\nC-pop, dance, Middle Eastern\nC-pop, dance, Middle Eastern fusion\nC-pop, dance, anime\nC-pop, dance, anime opening\nC-pop, dance, anthemic\nC-pop, dance, bubblegum pop\nC-pop, dance, chiptune\nC-pop, dance, cinematic\nC-pop, dance, early 2000s\nC-pop, dance, electronic\nC-pop, dance, eurodance\nC-pop, dance, festive\nC-pop, dance, folk\nC-pop, dance, folk fusion\nC-pop, dance, folk-pop\nC-pop, dance, house\nC-pop, dance, idol-pop\nC-pop, dance, melancholic\nC-pop, dance, novelty\nC-pop, dance, orchestral\nC-pop, dance, retro\nC-pop, dance, retro game\nC-pop, dance, synth-pop\nC-pop, dance, synthwave\nC-pop, dance, traditional fusion\nC-pop, dance, world music\nC-pop, dance, wuxia\nC-pop, dance-pop\nC-pop, dance-pop, 90s retro\nC-pop, dance-pop, 90s revival\nC-pop, dance-pop, Christmas\nC-pop, dance-pop, EDM\nC-pop, dance-pop, Eurodance\nC-pop, dance-pop, Mongolian folk\nC-pop, dance-pop, anime\nC-pop, dance-pop, anime soundtrack\nC-pop, dance-pop, anthemic\nC-pop, dance-pop, children's music\nC-pop, dance-pop, chiptune\nC-pop, dance-pop, cinematic\nC-pop, dance-pop, electronic\nC-pop, dance-pop, festive\nC-pop, dance-pop, folk\nC-pop, dance-pop, hip-hop\nC-pop, dance-pop, lo-fi hip hop\nC-pop, dance-pop, new jack swing\nC-pop, dance-pop, orchestral\nC-pop, dance-pop, retro\nC-pop, dance-pop, retro synth\nC-pop, dance-pop, rock\nC-pop, dance-pop, synth-pop\nC-pop, dance-pop, trap\nC-pop, dance-pop, video game soundtrack\nC-pop, dangdut koplo\nC-pop, dangdut koplo, cinematic\nC-pop, dark ambient\nC-pop, dark cinematic\nC-pop, dark electronic\nC-pop, dark pop\nC-pop, deep house\nC-pop, devotional pop, cinematic\nC-pop, downtempo R&B\nC-pop, downtempo hip-hop\nC-pop, downtempo trap\nC-pop, downtempo, Guofeng\nC-pop, downtempo, R&B\nC-pop, downtempo, ambient\nC-pop, downtempo, ambient hip-hop\nC-pop, downtempo, ambient pop\nC-pop, downtempo, cinematic\nC-pop, downtempo, electronic\nC-pop, dream pop\nC-pop, dream pop, EDM\nC-pop, dream pop, J-rock\nC-pop, dream pop, R&B\nC-pop, dream pop, alternative rock\nC-pop, dream pop, ambient\nC-pop, dream pop, anime\nC-pop, dream pop, anime music\nC-pop, dream pop, anime soundtrack\nC-pop, dream pop, anime theme\nC-pop, dream pop, cinematic\nC-pop, dream pop, cinematic rock\nC-pop, dream pop, electronic\nC-pop, dream pop, electronic rock\nC-pop, dream pop, emotional ballad\nC-pop, dream pop, funk rock\nC-pop, dream pop, hip-hop\nC-pop, dream pop, indie folk\nC-pop, dream pop, indie rock\nC-pop, dream pop, lo-fi\nC-pop, dream pop, lo-fi hip hop\nC-pop, dream pop, pop-rock\nC-pop, dream pop, rock\nC-pop, dream pop, synth pop\nC-pop, dream pop, synth rock\nC-pop, dream pop, synth-pop\nC-pop, dream pop, synthwave\nC-pop, dream pop, trap\nC-pop, dream pop, trap R&B\nC-pop, dream trap\nC-pop, dream-pop, hip-hop\nC-pop, dreamy\nC-pop, dreamy R&B\nC-pop, dreamy R&B, atmospheric trap\nC-pop, dreamy ambient\nC-pop, dreamy ballad\nC-pop, dreamy ballad, R&B\nC-pop, dreamy ballad, traditional Chinese\nC-pop, dreamy electronic\nC-pop, dreamy electronic, downtempo trap\nC-pop, dreamy electronic, trip-hop\nC-pop, dreamy hip hop\nC-pop, dreamy hip-hop\nC-pop, dreamy pop\nC-pop, dreamy pop, R&B\nC-pop, dreamy pop, cinematic\nC-pop, dreamy pop, electronic\nC-pop, dreamy synth\nC-pop, dreamy synth, R&B\nC-pop, dreamy synth, ambient\nC-pop, dreamy synth, atmospheric\nC-pop, dreamy synth, cinematic\nC-pop, dreamy synth, electronic\nC-pop, dreamy synth, electronic ballad\nC-pop, dreamy synth, lo-fi\nC-pop, dreamy synth, trap\nC-pop, dreamy trap\nC-pop, dreamy, R&B\nC-pop, dreamy, Vocaloid\nC-pop, dreamy, ambient\nC-pop, dreamy, anime\nC-pop, dreamy, anime soundtrack\nC-pop, dreamy, anime-inspired\nC-pop, dreamy, anthemic\nC-pop, dreamy, atmospheric\nC-pop, dreamy, bossa nova\nC-pop, dreamy, chiptune\nC-pop, dreamy, cinematic\nC-pop, dreamy, dance-pop\nC-pop, dreamy, electronic\nC-pop, dreamy, ethereal\nC-pop, dreamy, hip-hop\nC-pop, dreamy, introspective\nC-pop, dreamy, lo-fi\nC-pop, dreamy, lo-fi hip hop\nC-pop, dreamy, melancholic\nC-pop, dreamy, mid-tempo\nC-pop, dreamy, romantic\nC-pop, dreamy, synthwave\nC-pop, dreamy, traditional Chinese\nC-pop, dreamy, trap\nC-pop, dreamy, trap-pop\nC-pop, dreamy, video game soundtrack\nC-pop, dreamy, whimsical\nC-pop, drum and bass, electronic\nC-pop, drum and bass, glitch\nC-pop, dubstep\nC-pop, dubstep, ambient\nC-pop, dubstep, cinematic\nC-pop, dubstep, electronic\nC-pop, dubstep, glitch-hop\nC-pop, dubstep, hardstyle\nC-pop, dubstep, hip-hop\nC-pop, dubstep, metalcore\nC-pop, dubstep, rap\nC-pop, dubstep, rock\nC-pop, dubstep, trap\nC-pop, dubstep, trap metal\nC-pop, early 2000s\nC-pop, early 2000s R&B\nC-pop, early 2000s R&B, hip-hop\nC-pop, early 2000s R&B, lo-fi hip hop\nC-pop, early 2000s dance\nC-pop, early 2000s electronic\nC-pop, early 2000s hip-hop\nC-pop, early 2000s pop\nC-pop, early 2000s, funk\nC-pop, early 2000s, synth-pop\nC-pop, easy listening\nC-pop, easy-listening\nC-pop, electro house\nC-pop, electro-pop\nC-pop, electronic\nC-pop, electronic R&B\nC-pop, electronic R&B, downtempo trap\nC-pop, electronic R&B, trap\nC-pop, electronic ballad\nC-pop, electronic dance\nC-pop, electronic dance music\nC-pop, electronic dance, Chinese New Year\nC-pop, electronic dance, Guofeng\nC-pop, electronic dance, ancient style\nC-pop, electronic dance, anime\nC-pop, electronic dance, anime soundtrack\nC-pop, electronic dance, art pop\nC-pop, electronic dance, chiptune\nC-pop, electronic dance, cinematic\nC-pop, electronic dance, dream pop\nC-pop, electronic dance, festive\nC-pop, electronic dance, folk fusion\nC-pop, electronic dance, hardstyle\nC-pop, electronic dance, hip-hop\nC-pop, electronic dance, hyperpop\nC-pop, electronic dance, melancholic\nC-pop, electronic dance, modern Chinese\nC-pop, electronic dance, modern pop\nC-pop, electronic dance, patriotic\nC-pop, electronic dance, rock\nC-pop, electronic dance, traditional Chinese\nC-pop, electronic dance, traditional folk\nC-pop, electronic dance, traditional fusion\nC-pop, electronic dance, trance\nC-pop, electronic dance, wuxia\nC-pop, electronic dance-pop\nC-pop, electronic dance-pop, Guofeng\nC-pop, electronic dance-pop, anime soundtrack\nC-pop, electronic dance-pop, wuxia\nC-pop, electronic folk\nC-pop, electronic fusion\nC-pop, electronic hip-hop\nC-pop, electronic hip-hop, EDM\nC-pop, electronic hip-hop, cinematic\nC-pop, electronic hip-hop, wuxia\nC-pop, electronic pop\nC-pop, electronic pop, EDM\nC-pop, electronic pop, R&B\nC-pop, electronic pop, anime\nC-pop, electronic pop, festive\nC-pop, electronic pop, future bass\nC-pop, electronic pop, hip-hop\nC-pop, electronic pop, trap\nC-pop, electronic pop-rock\nC-pop, electronic rock\nC-pop, electronic rock, EDM\nC-pop, electronic rock, ancient style\nC-pop, electronic rock, cinematic\nC-pop, electronic rock, dubstep\nC-pop, electronic rock, hip-hop\nC-pop, electronic rock, trap\nC-pop, electronic trap\nC-pop, electronic, Arabic pop\nC-pop, electronic, EDM\nC-pop, electronic, Gu Feng\nC-pop, electronic, Guofeng\nC-pop, electronic, Indian fusion\nC-pop, electronic, J-pop\nC-pop, electronic, Mandopop\nC-pop, electronic, R&B\nC-pop, electronic, Telugu\nC-pop, electronic, Vocaloid\nC-pop, electronic, ambient\nC-pop, electronic, ancient style\nC-pop, electronic, anime\nC-pop, electronic, anime soundtrack\nC-pop, electronic, anime theme\nC-pop, electronic, anthemic\nC-pop, electronic, artcore\nC-pop, electronic, atmospheric\nC-pop, electronic, ballad\nC-pop, electronic, breakbeat\nC-pop, electronic, breakcore\nC-pop, electronic, brostep\nC-pop, electronic, chiptune\nC-pop, electronic, choral\nC-pop, electronic, cinematic\nC-pop, electronic, classical Chinese\nC-pop, electronic, classical fusion\nC-pop, electronic, comedic\nC-pop, electronic, cyberpunk\nC-pop, electronic, dance\nC-pop, electronic, dance-pop\nC-pop, electronic, dancehall\nC-pop, electronic, dark pop\nC-pop, electronic, dramatic\nC-pop, electronic, dream pop\nC-pop, electronic, dreamy\nC-pop, electronic, dreamy pop\nC-pop, electronic, dubstep\nC-pop, electronic, duet\nC-pop, electronic, epic\nC-pop, electronic, ethereal\nC-pop, electronic, fantasy\nC-pop, electronic, festival\nC-pop, electronic, festive\nC-pop, electronic, folk\nC-pop, electronic, folk fusion\nC-pop, electronic, funk\nC-pop, electronic, funk-rock\nC-pop, electronic, fusion\nC-pop, electronic, future bass\nC-pop, electronic, futuristic\nC-pop, electronic, game music\nC-pop, electronic, glitch\nC-pop, electronic, groove\nC-pop, electronic, gufeng\nC-pop, electronic, guzheng\nC-pop, electronic, guzheng fusion\nC-pop, electronic, hardstyle\nC-pop, electronic, hip hop\nC-pop, electronic, hip-hop\nC-pop, electronic, idol\nC-pop, electronic, indie\nC-pop, electronic, instrumental\nC-pop, electronic, jazz fusion\nC-pop, electronic, lo-fi\nC-pop, electronic, lo-fi hip hop\nC-pop, electronic, melancholic\nC-pop, electronic, melodic\nC-pop, electronic, meme\nC-pop, electronic, minimalist\nC-pop, electronic, modern\nC-pop, electronic, modern Chinese\nC-pop, electronic, modern traditional\nC-pop, electronic, motivational\nC-pop, electronic, mystical\nC-pop, electronic, nostalgic\nC-pop, electronic, nu-disco\nC-pop, electronic, orchestral\nC-pop, electronic, pentatonic\nC-pop, electronic, playful\nC-pop, electronic, pop\nC-pop, electronic, pop-R&B\nC-pop, electronic, pop-rock\nC-pop, electronic, power-pop\nC-pop, electronic, quirky\nC-pop, electronic, rap\nC-pop, electronic, retro game\nC-pop, electronic, rock\nC-pop, electronic, romantic\nC-pop, electronic, sentimental\nC-pop, electronic, smooth jazz\nC-pop, electronic, spy-thriller\nC-pop, electronic, synth\nC-pop, electronic, synth folk\nC-pop, electronic, synth pop\nC-pop, electronic, synthpop\nC-pop, electronic, synthwave\nC-pop, electronic, theatrical\nC-pop, electronic, traditional\nC-pop, electronic, traditional Chinese\nC-pop, electronic, traditional Chinese folk\nC-pop, electronic, traditional Chinese fusion\nC-pop, electronic, traditional fusion\nC-pop, electronic, trap\nC-pop, electronic, upbeat\nC-pop, electronic, uplifting\nC-pop, electronic, video game\nC-pop, electronic, video game music\nC-pop, electronic, video game soundtrack\nC-pop, electronic, whimsical\nC-pop, electronic, world fusion\nC-pop, electronic, world music\nC-pop, electronic, wuxia\nC-pop, electronic-rock, cinematic\nC-pop, emotional EDM\nC-pop, emotional R&B\nC-pop, emotional ballad\nC-pop, emotional ballad, EDM\nC-pop, emotional ballad, electronic\nC-pop, emotional ballad, hip-hop\nC-pop, emotional ballad, pop-R&B\nC-pop, emotional ballad, pop-rock\nC-pop, emotional ballad, rap\nC-pop, emotional ballad, trap-influenced\nC-pop, emotional dance-pop\nC-pop, emotional hip-hop\nC-pop, emotional pop\nC-pop, emotional pop, R&B\nC-pop, emotional pop, ambient\nC-pop, emotional pop, atmospheric\nC-pop, emotional pop, cinematic rap\nC-pop, emotional pop-rap, atmospheric R&B\nC-pop, emotional pop-rock\nC-pop, emotional pop-rock, future bass\nC-pop, emotional rap\nC-pop, emotional rock\nC-pop, emotional trap\nC-pop, emotional, ambient\nC-pop, emotional, cinematic\nC-pop, emotional, electronic\nC-pop, emotional, hip-hop\nC-pop, emotional, minimalist\nC-pop, emotional, pop-rock\nC-pop, emotional, synth-pop\nC-pop, emotional, trap\nC-pop, epic ballad\nC-pop, epic ballad, dance-pop\nC-pop, epic ballad, rock\nC-pop, epic ballad, wuxia\nC-pop, epic rock\nC-pop, epic rock, cinematic\nC-pop, epic trap\nC-pop, epic, anthemic\nC-pop, epic, cinematic\nC-pop, epic, operatic\nC-pop, epic, patriotic\nC-pop, epic, pop-rock\nC-pop, epic, power ballad\nC-pop, epic, synth\nC-pop, epic, traditional fusion\nC-pop, ethereal\nC-pop, ethereal ballad\nC-pop, ethereal pop\nC-pop, ethereal pop, cinematic rock\nC-pop, ethereal pop, electronic\nC-pop, ethereal pop, indie rock\nC-pop, ethereal trap\nC-pop, ethereal trap, ambient electronic\nC-pop, ethereal, R&B\nC-pop, ethereal, ambient\nC-pop, ethereal, anime soundtrack\nC-pop, ethereal, atmospheric\nC-pop, ethereal, cinematic\nC-pop, ethereal, electronic\nC-pop, ethereal, fantasy\nC-pop, ethereal, folk-infused\nC-pop, ethereal, melancholic\nC-pop, ethereal, pop-funk\nC-pop, ethereal, pop-rap\nC-pop, ethereal, pop-rock\nC-pop, ethereal, romantic\nC-pop, ethereal, synthwave\nC-pop, ethereal, traditional Chinese\nC-pop, ethereal, trap\nC-pop, ethereal, trap ballad\nC-pop, ethno-pop\nC-pop, experimental\nC-pop, experimental, folk rock\nC-pop, experimental, metalcore\nC-pop, fairytale pop\nC-pop, fantasy, electronic\nC-pop, fantasy, lo-fi\nC-pop, festive\nC-pop, festive ballad\nC-pop, festive pop\nC-pop, festive, R&B\nC-pop, festive, anime pop\nC-pop, festive, anthemic\nC-pop, festive, children's music\nC-pop, festive, cinematic\nC-pop, festive, dance\nC-pop, festive, dreamy\nC-pop, festive, electronic\nC-pop, festive, funk\nC-pop, festive, hip-hop\nC-pop, festive, marching band\nC-pop, festive, melancholic\nC-pop, festive, modern\nC-pop, festive, orchestral\nC-pop, festive, pop\nC-pop, festive, pop-rock\nC-pop, festive, pop-trap\nC-pop, festive, retro\nC-pop, festive, romantic\nC-pop, festive, synthwave\nC-pop, festive, theatrical\nC-pop, festive, traditional\nC-pop, festive, traditional fusion\nC-pop, festive, trap\nC-pop, festive, upbeat\nC-pop, festive, video game music\nC-pop, flamenco pop, hip-hop\nC-pop, flamenco rock\nC-pop, flamenco, jazz fusion\nC-pop, flamenco, pop-rock\nC-pop, flamenco, world music\nC-pop, folk\nC-pop, folk ballad\nC-pop, folk fusion\nC-pop, folk fusion, cinematic\nC-pop, folk fusion, cinematic pop\nC-pop, folk fusion, dance\nC-pop, folk fusion, electronic\nC-pop, folk fusion, modern pop\nC-pop, folk hip-hop\nC-pop, folk pop\nC-pop, folk rock\nC-pop, folk rock, ambient\nC-pop, folk rock, cinematic\nC-pop, folk rock, cinematic pop\nC-pop, folk, ambient\nC-pop, folk, anthemic\nC-pop, folk, ballad\nC-pop, folk, chiptune\nC-pop, folk, cinematic\nC-pop, folk, dance\nC-pop, folk, electronic\nC-pop, folk, hip-hop\nC-pop, folk, modern\nC-pop, folk, nostalgic\nC-pop, folk, orchestral\nC-pop, folk, pop\nC-pop, folk, pop ballad\nC-pop, folk, pop-rock\nC-pop, folk, pop-rock, ballad\nC-pop, folk, rap\nC-pop, folk, retro\nC-pop, folk, rock\nC-pop, folk, romantic\nC-pop, folk, sentimental\nC-pop, folk, traditional\nC-pop, folk, upbeat\nC-pop, folk-electronic\nC-pop, folk-inspired, gentle\nC-pop, folk-pop\nC-pop, folk-pop, cinematic\nC-pop, folk-pop, dance\nC-pop, folk-pop, dance-pop\nC-pop, folk-pop, funk\nC-pop, folk-pop, hip-hop\nC-pop, folk-pop, neo-classical\nC-pop, folk-pop, pop-rock\nC-pop, folk-rock, anthemic\nC-pop, folk-rock, cinematic\nC-pop, forró, cinematic\nC-pop, funk\nC-pop, funk soul\nC-pop, funk, R&B\nC-pop, funk, ambient\nC-pop, funk, atmospheric\nC-pop, funk, beatboxing\nC-pop, funk, cinematic\nC-pop, funk, comedy\nC-pop, funk, dance\nC-pop, funk, early 2000s R&B\nC-pop, funk, electronic\nC-pop, funk, hip-hop\nC-pop, funk, lo-fi\nC-pop, funk, orchestral\nC-pop, funk, playful\nC-pop, funk, synth groove\nC-pop, funk, synth pop\nC-pop, funk, synthpop\nC-pop, funk, synthwave\nC-pop, funk, theatrical\nC-pop, funk, trap\nC-pop, funk, video game\nC-pop, funk-rock\nC-pop, funk-rock, cinematic\nC-pop, future bass\nC-pop, future bass, EDM\nC-pop, future bass, J-rock\nC-pop, future bass, ambient\nC-pop, future bass, anime theme\nC-pop, future bass, cinematic\nC-pop, future bass, downtempo\nC-pop, future bass, dreamy\nC-pop, future bass, electronic\nC-pop, future bass, hardstyle\nC-pop, future bass, hip-hop\nC-pop, future bass, hyperpop\nC-pop, future bass, lo-fi\nC-pop, future bass, lo-fi hip hop\nC-pop, future bass, orchestral\nC-pop, future bass, pop-R&B\nC-pop, future bass, pop-rock\nC-pop, future bass, power ballad\nC-pop, future bass, synth-pop\nC-pop, future bass, trap\nC-pop, future bass, winter holiday\nC-pop, future pop\nC-pop, future trap\nC-pop, futuristic, anime\nC-pop, futuristic, dreamy\nC-pop, game music\nC-pop, gentle, romantic\nC-pop, glitch hop\nC-pop, glitch-hop\nC-pop, gospel, ambient\nC-pop, gufeng\nC-pop, gufeng, ballad\nC-pop, gufeng, cinematic\nC-pop, gufeng, pop-rock\nC-pop, guzheng, cinematic\nC-pop, happy hardcore\nC-pop, happy hardcore, Eurodance\nC-pop, happy hardcore, J-core\nC-pop, happy hardcore, J-pop\nC-pop, happy hardcore, anime\nC-pop, happy hardcore, chiptune\nC-pop, happy hardcore, denpa\nC-pop, happy hardcore, hardstyle\nC-pop, happy hardcore, nightcore\nC-pop, happy hardcore, pop-rock\nC-pop, happy hardcore, trance\nC-pop, hard dance\nC-pop, hard rock\nC-pop, hard rock, electronic\nC-pop, hard rock, world music\nC-pop, hardstyle\nC-pop, hardstyle trance\nC-pop, hardstyle, EDM\nC-pop, hardstyle, J-core\nC-pop, hardstyle, ambient\nC-pop, hardstyle, big room\nC-pop, hardstyle, big room house\nC-pop, hardstyle, chiptune\nC-pop, hardstyle, cinematic\nC-pop, hardstyle, dance\nC-pop, hardstyle, dubstep\nC-pop, hardstyle, electronic\nC-pop, hardstyle, future bass\nC-pop, hardstyle, glitch\nC-pop, hardstyle, happy hardcore\nC-pop, hardstyle, hyperpop\nC-pop, hardstyle, indie-pop\nC-pop, hardstyle, lo-fi hip hop\nC-pop, hardstyle, lo-fi hip-hop\nC-pop, hardstyle, pop-rock\nC-pop, hardstyle, rock\nC-pop, hardstyle, synthpop\nC-pop, hardstyle, trance\nC-pop, hardstyle, trap\nC-pop, hip hop\nC-pop, hip hop, cinematic\nC-pop, hip-hop\nC-pop, hip-hop, EDM\nC-pop, hip-hop, J-rock\nC-pop, hip-hop, Mandopop, pop-rock\nC-pop, hip-hop, R&B\nC-pop, hip-hop, alternative rock\nC-pop, hip-hop, ambient\nC-pop, hip-hop, ancient style\nC-pop, hip-hop, anthemic\nC-pop, hip-hop, ballad\nC-pop, hip-hop, chiptune\nC-pop, hip-hop, cinematic\nC-pop, hip-hop, dance-pop\nC-pop, hip-hop, dubstep\nC-pop, hip-hop, electronic\nC-pop, hip-hop, electronic dance\nC-pop, hip-hop, folk\nC-pop, hip-hop, funk\nC-pop, hip-hop, funk-rock\nC-pop, hip-hop, future bass\nC-pop, hip-hop, hyperpop\nC-pop, hip-hop, indie rock\nC-pop, hip-hop, industrial metal\nC-pop, hip-hop, lo-fi\nC-pop, hip-hop, melancholic\nC-pop, hip-hop, modern\nC-pop, hip-hop, orchestral\nC-pop, hip-hop, orchestral synth\nC-pop, hip-hop, pop\nC-pop, hip-hop, pop-rock\nC-pop, hip-hop, rock\nC-pop, hip-hop, romantic\nC-pop, hip-hop, sentimental ballad\nC-pop, hip-hop, sentimental pop\nC-pop, hip-hop, synth-pop\nC-pop, hip-hop, traditional Chinese\nC-pop, hip-hop, traditional Chinese folk\nC-pop, hip-hop, trap\nC-pop, house, electronic\nC-pop, hyperpop\nC-pop, hyperpop, EDM\nC-pop, hyperpop, EDM, pop-rock, trap\nC-pop, hyperpop, Eurobeat\nC-pop, hyperpop, J-pop\nC-pop, hyperpop, J-rock\nC-pop, hyperpop, chiptune\nC-pop, hyperpop, cinematic\nC-pop, hyperpop, dream pop\nC-pop, hyperpop, electronic\nC-pop, hyperpop, electronic dance\nC-pop, hyperpop, hardstyle\nC-pop, hyperpop, trap\nC-pop, hyperpop, vaporwave\nC-pop, hyperpop, video game music\nC-pop, idol pop, dance\nC-pop, idol, electronic\nC-pop, indie ballad, hip-hop\nC-pop, indie folk\nC-pop, indie folk, cinematic\nC-pop, indie folk, emotional rock\nC-pop, indie pop, cinematic\nC-pop, indie pop, emotional\nC-pop, indie pop, hip-hop\nC-pop, indie rock\nC-pop, indie-pop, synth-pop, cinematic, future bass\nC-pop, industrial electronic, J-rock\nC-pop, industrial hip-hop, cinematic\nC-pop, industrial rock, ambient\nC-pop, industrial, electronic\nC-pop, inspirational synth-pop\nC-pop, instrumental, cinematic\nC-pop, instrumental, modern folk\nC-pop, instrumental, modern rock\nC-pop, instrumental, pop-rock\nC-pop, jazz ballad, pop-rock\nC-pop, jazz fusion\nC-pop, jazz fusion, cinematic\nC-pop, jazz pop, ballad\nC-pop, jazz, cinematic\nC-pop, jazz, lo-fi\nC-pop, jazz, smooth\nC-pop, jazz, theatrical\nC-pop, jazz, traditional\nC-pop, jazz-rock, cinematic\nC-pop, jazzy groove\nC-pop, jazzy pop-rock\nC-pop, kawaii\nC-pop, kawaii electronic\nC-pop, kawaii future bass\nC-pop, kawaii future bass, chiptune\nC-pop, kawaii, anime\nC-pop, kawaii, lo-fi\nC-pop, kawaii, video game music\nC-pop, kawaii-pop, electronic\nC-pop, light EDM\nC-pop, light R&B\nC-pop, lo-fi R&B\nC-pop, lo-fi R&B, chillwave\nC-pop, lo-fi anime\nC-pop, lo-fi electronic, J-rock\nC-pop, lo-fi hip hop\nC-pop, lo-fi hip hop, Gu Feng\nC-pop, lo-fi hip hop, R&B\nC-pop, lo-fi hip hop, ambient\nC-pop, lo-fi hip hop, atmospheric\nC-pop, lo-fi hip hop, chiptune\nC-pop, lo-fi hip hop, cinematic\nC-pop, lo-fi hip hop, dream pop\nC-pop, lo-fi hip hop, dubstep\nC-pop, lo-fi hip hop, emotional ballad\nC-pop, lo-fi hip hop, pop-rock\nC-pop, lo-fi hip hop, rap\nC-pop, lo-fi hip hop, romantic ballad\nC-pop, lo-fi hip hop, synthwave\nC-pop, lo-fi hip hop, traditional Chinese\nC-pop, lo-fi hip hop, trap\nC-pop, lo-fi hip hop, vaporwave\nC-pop, lo-fi hip hop, wuxia\nC-pop, lo-fi hip-hop\nC-pop, lo-fi hip-hop, R&B\nC-pop, lo-fi hip-hop, ambient\nC-pop, lo-fi hip-hop, atmospheric\nC-pop, lo-fi hip-hop, cinematic\nC-pop, lo-fi hip-hop, folk\nC-pop, lo-fi hip-hop, traditional Chinese\nC-pop, lo-fi pop\nC-pop, lo-fi trap\nC-pop, lo-fi trap, R&B\nC-pop, lo-fi, J-rock\nC-pop, lo-fi, R&B\nC-pop, lo-fi, acoustic\nC-pop, lo-fi, ambient\nC-pop, lo-fi, anime\nC-pop, lo-fi, anime soundtrack\nC-pop, lo-fi, atmospheric\nC-pop, lo-fi, ballad\nC-pop, lo-fi, chiptune\nC-pop, lo-fi, cinematic\nC-pop, lo-fi, cinematic pop\nC-pop, lo-fi, dance-pop\nC-pop, lo-fi, dream pop\nC-pop, lo-fi, dreamy\nC-pop, lo-fi, electronic\nC-pop, lo-fi, ethereal\nC-pop, lo-fi, future bass\nC-pop, lo-fi, hip-hop\nC-pop, lo-fi, indie-pop, rock\nC-pop, lo-fi, melancholic\nC-pop, lo-fi, pop-rock\nC-pop, lo-fi, pop-rock, orchestral\nC-pop, lo-fi, power ballad\nC-pop, lo-fi, rock\nC-pop, lo-fi, summer pop\nC-pop, lo-fi, traditional Chinese\nC-pop, lo-fi, trap\nC-pop, lo-fi, trip-hop\nC-pop, lo-fi, vaporwave\nC-pop, lo-fi, video game\nC-pop, lounge, rock\nC-pop, lullaby\nC-pop, martial\nC-pop, martial arts, pop-rock\nC-pop, math rock, J-rock\nC-pop, melancholic\nC-pop, melancholic ballad\nC-pop, melancholic ballad, shoegaze\nC-pop, melancholic hip-hop\nC-pop, melancholic pop\nC-pop, melancholic pop, indie rock\nC-pop, melancholic pop, trap\nC-pop, melancholic pop-rock\nC-pop, melancholic trap\nC-pop, melancholic waltz\nC-pop, melancholic, ambient\nC-pop, melancholic, anime-inspired\nC-pop, melancholic, atmospheric\nC-pop, melancholic, cinematic\nC-pop, melancholic, dance-pop\nC-pop, melancholic, electronic\nC-pop, melancholic, hip-hop\nC-pop, melancholic, introspective\nC-pop, melancholic, lo-fi\nC-pop, melancholic, modern\nC-pop, melancholic, modern R&B\nC-pop, melancholic, modern ballad\nC-pop, melancholic, pop-rock\nC-pop, melancholic, rock\nC-pop, melancholic, rock-influenced\nC-pop, melancholic, traditional\nC-pop, melancholic, traditional Chinese\nC-pop, melancholic, traditional fusion\nC-pop, melancholic, trap\nC-pop, melancholic, trap soul\nC-pop, melancholic, trap-influenced\nC-pop, melodic\nC-pop, melodic rap\nC-pop, melodic rap, R&B\nC-pop, melodic rap, lo-fi hip-hop\nC-pop, melodic rap, synth-pop\nC-pop, melodic rap, trap\nC-pop, melodic trap, R&B\nC-pop, metalcore\nC-pop, metalcore, cinematic\nC-pop, military march\nC-pop, minimalist\nC-pop, minimalist, groovy\nC-pop, modern Chinese style\nC-pop, modern Chinese, cinematic pop\nC-pop, modern Chinese, electronic\nC-pop, modern R&B\nC-pop, modern R&B, cinematic\nC-pop, modern R&B, trap\nC-pop, modern ballad, traditional Chinese\nC-pop, modern ballad, traditional fusion\nC-pop, modern folk, pop-rock\nC-pop, modern folk, rock\nC-pop, modern pop\nC-pop, modern pop, ambient\nC-pop, modern pop, hip-hop\nC-pop, modern pop, traditional Chinese\nC-pop, modern pop-R&B\nC-pop, modern pop-rap\nC-pop, modern pop-rock\nC-pop, modern rock\nC-pop, modern rock, traditional Chinese\nC-pop, modern, electronic\nC-pop, modern, hip-hop\nC-pop, modern, pop-rock\nC-pop, modern, traditional\nC-pop, modern, traditional Chinese\nC-pop, modern, traditional fusion\nC-pop, modern,古风\nC-pop, musical theatre, pop-rock\nC-pop, mystical, Latin\nC-pop, narrative hip-hop\nC-pop, neo-soul\nC-pop, neo-soul, R&B\nC-pop, neo-soul, city pop\nC-pop, neoclassical, ambient\nC-pop, new age, cinematic\nC-pop, new age, world music\nC-pop, new jack swing\nC-pop, new jack swing, funk\nC-pop, new jack swing, hip-hop\nC-pop, new jack swing, hip-house\nC-pop, new jack swing, old-school hip-hop\nC-pop, new jack swing, retro\nC-pop, new-age\nC-pop, new-age, cinematic\nC-pop, new-age, pop-rock\nC-pop, ney flute, cinematic\nC-pop, nightcore\nC-pop, noir, cinematic\nC-pop, noise-rock\nC-pop, nostalgic, hip-hop\nC-pop, nostalgic, synthwave\nC-pop, nostalgic, traditional Chinese\nC-pop, nostalgic, upbeat\nC-pop, nu-disco\nC-pop, nu-metal\nC-pop, nu-metal, cinematic\nC-pop, nu-metal, electronicore\nC-pop, operatic, traditional Chinese\nC-pop, orchestral ballad\nC-pop, orchestral pop\nC-pop, orchestral pop, anime soundtrack\nC-pop, orchestral pop, celebratory\nC-pop, orchestral pop, children's music\nC-pop, orchestral pop, new age\nC-pop, orchestral pop, pop-rock\nC-pop, orchestral pop, wuxia\nC-pop, orchestral pop-rock\nC-pop, orchestral rock\nC-pop, orchestral rock, anime theme\nC-pop, orchestral rock, cinematic\nC-pop, orchestral rock, wuxia\nC-pop, orchestral, 90s ballad\nC-pop, orchestral, Eurodance\nC-pop, orchestral, Gufeng\nC-pop, orchestral, Mandopop\nC-pop, orchestral, R&B\nC-pop, orchestral, anime theme\nC-pop, orchestral, anthemic\nC-pop, orchestral, ballad\nC-pop, orchestral, celebratory\nC-pop, orchestral, children's\nC-pop, orchestral, cinematic\nC-pop, orchestral, disco-funk\nC-pop, orchestral, epic\nC-pop, orchestral, festive\nC-pop, orchestral, folk\nC-pop, orchestral, patriotic\nC-pop, orchestral, pop-ballad\nC-pop, orchestral, pop-rock\nC-pop, orchestral, power ballad\nC-pop, orchestral, retro\nC-pop, orchestral, rock\nC-pop, orchestral, rock-opera\nC-pop, orchestral, synth-pop\nC-pop, orchestral, traditional Chinese\nC-pop, orchestral, wuxia\nC-pop, patriotic\nC-pop, patriotic ballad\nC-pop, patriotic pop\nC-pop, patriotic, 80s synth\nC-pop, patriotic, anthemic\nC-pop, patriotic, ballad\nC-pop, patriotic, cinematic\nC-pop, patriotic, orchestral\nC-pop, patriotic, pop-rock\nC-pop, patriotic, synth ballad\nC-pop, patriotic, synthwave\nC-pop, piano ballad\nC-pop, piano ballad, cinematic\nC-pop, piano ballad, synth pop\nC-pop, playful hip-hop\nC-pop, playful pop\nC-pop, playful, cinematic\nC-pop, playful, energetic\nC-pop, playful, modern traditional\nC-pop, playful, synth-pop\nC-pop, playful, theatrical\nC-pop, polka\nC-pop, pop\nC-pop, pop ballad\nC-pop, pop ballad, cinematic\nC-pop, pop ballad, hip-hop\nC-pop, pop ballad, modern pop\nC-pop, pop ballad, pop-rock\nC-pop, pop sunda\nC-pop, pop, R&B\nC-pop, pop, cinematic\nC-pop, pop, folk\nC-pop, pop, hip-hop\nC-pop, pop, theatrical\nC-pop, pop-EDM\nC-pop, pop-R&B\nC-pop, pop-R&B, cinematic\nC-pop, pop-R&B, cinematic rock\nC-pop, pop-R&B, pop-rock\nC-pop, pop-ballad, J-rock\nC-pop, pop-ballad, dubstep\nC-pop, pop-ballad, trap\nC-pop, pop-hip hop\nC-pop, pop-hip hop, cinematic\nC-pop, pop-hip-hop\nC-pop, pop-hip-hop, pop-rock\nC-pop, pop-punk\nC-pop, pop-rap\nC-pop, pop-rap, R&B\nC-pop, pop-rap, acoustic ballad\nC-pop, pop-rap, anthemic\nC-pop, pop-rap, bubblegum pop\nC-pop, pop-rap, cinematic\nC-pop, pop-rap, dreamy\nC-pop, pop-rap, emo-rap\nC-pop, pop-rap, indie pop\nC-pop, pop-rap, indie rock\nC-pop, pop-rap, lo-fi\nC-pop, pop-rap, pop-rock\nC-pop, pop-rap, sentimental ballad\nC-pop, pop-rap, synth-pop\nC-pop, pop-reggae\nC-pop, pop-rock\nC-pop, pop-rock, 80s hard rock\nC-pop, pop-rock, Celtic fusion\nC-pop, pop-rock, Chinese New Year\nC-pop, pop-rock, EDM\nC-pop, pop-rock, Eastern fusion\nC-pop, pop-rock, Guofeng\nC-pop, pop-rock, Indian fusion\nC-pop, pop-rock, J-rock\nC-pop, pop-rock, J-rock, cinematic\nC-pop, pop-rock, Mongolian folk\nC-pop, pop-rock, R&B\nC-pop, pop-rock, R&B, acoustic ballad\nC-pop, pop-rock, acoustic folk\nC-pop, pop-rock, alternative rock\nC-pop, pop-rock, ambient\nC-pop, pop-rock, ancient style\nC-pop, pop-rock, anime\nC-pop, pop-rock, anime opening\nC-pop, pop-rock, anime soundtrack\nC-pop, pop-rock, anime theme\nC-pop, pop-rock, anison\nC-pop, pop-rock, anthemic\nC-pop, pop-rock, atmospheric\nC-pop, pop-rock, ballad\nC-pop, pop-rock, big band jazz\nC-pop, pop-rock, chiptune\nC-pop, pop-rock, cinematic\nC-pop, pop-rock, cinematic folk\nC-pop, pop-rock, dance-pop\nC-pop, pop-rock, dubstep\nC-pop, pop-rock, electronic\nC-pop, pop-rock, emotional\nC-pop, pop-rock, epic\nC-pop, pop-rock, epic rock\nC-pop, pop-rock, experimental\nC-pop, pop-rock, festive\nC-pop, pop-rock, folk\nC-pop, pop-rock, folk fusion\nC-pop, pop-rock, folk, cinematic\nC-pop, pop-rock, future bass\nC-pop, pop-rock, ghazal\nC-pop, pop-rock, hard rock\nC-pop, pop-rock, heavy metal\nC-pop, pop-rock, hip hop\nC-pop, pop-rock, hip-hop\nC-pop, pop-rock, hip-hop, EDM\nC-pop, pop-rock, hyperpop\nC-pop, pop-rock, instrumental\nC-pop, pop-rock, jazz\nC-pop, pop-rock, jazz ballad\nC-pop, pop-rock, jazz fusion\nC-pop, pop-rock, lo-fi\nC-pop, pop-rock, lo-fi hip hop\nC-pop, pop-rock, lo-fi orchestral\nC-pop, pop-rock, melancholic\nC-pop, pop-rock, metal\nC-pop, pop-rock, metalcore\nC-pop, pop-rock, operatic\nC-pop, pop-rock, orchestral\nC-pop, pop-rock, post-metal\nC-pop, pop-rock, post-rock\nC-pop, pop-rock, power ballad\nC-pop, pop-rock, power ballad, cinematic\nC-pop, pop-rock, progressive rock\nC-pop, pop-rock, psychedelic rock\nC-pop, pop-rock, rap\nC-pop, pop-rock, rap-rock\nC-pop, pop-rock, retro\nC-pop, pop-rock, soul\nC-pop, pop-rock, stadium rock\nC-pop, pop-rock, symphonic rock\nC-pop, pop-rock, synth\nC-pop, pop-rock, synth-pop\nC-pop, pop-rock, synthwave\nC-pop, pop-rock, theatrical\nC-pop, pop-rock, traditional\nC-pop, pop-rock, traditional Chinese\nC-pop, pop-rock, traditional Chinese opera\nC-pop, pop-rock, traditional folk\nC-pop, pop-rock, traditional fusion\nC-pop, pop-rock, trap\nC-pop, pop-rock, vaporwave\nC-pop, pop-rock, video game\nC-pop, pop-rock, world music\nC-pop, pop-rock, wuxia\nC-pop, pop-trap\nC-pop, pop-trap, Indian fusion\nC-pop, pop-trap, R&B\nC-pop, pop-trap, cinematic\nC-pop, pop-trap, festive\nC-pop, pop-trap, traditional East Asian\nC-pop, pop/R&B\nC-pop, post-rock\nC-pop, post-rock, pop-rock\nC-pop, power ballad\nC-pop, power ballad, 80s synth\nC-pop, power ballad, ambient\nC-pop, power ballad, anime\nC-pop, power ballad, anthemic\nC-pop, power ballad, cinematic\nC-pop, power ballad, epic\nC-pop, power ballad, funk-rock\nC-pop, power ballad, hard rock\nC-pop, power ballad, lo-fi\nC-pop, power ballad, melancholic\nC-pop, power ballad, orchestral\nC-pop, power ballad, orchestral pop\nC-pop, power ballad, orchestral rock\nC-pop, power ballad, pop-rock\nC-pop, power ballad, rap-rock\nC-pop, power ballad, rock\nC-pop, power ballad, traditional Chinese\nC-pop, power ballad, trap\nC-pop, power pop\nC-pop, power rock\nC-pop, power rock, cinematic\nC-pop, power-pop, anime rock\nC-pop, progressive house\nC-pop, progressive house, EDM\nC-pop, progressive house, trance\nC-pop, quirky\nC-pop, quirky pop\nC-pop, quirky, synth pop\nC-pop, rap fusion, cinematic\nC-pop, rap, ambient\nC-pop, rap, electronic\nC-pop, rap-rock, cinematic\nC-pop, reggae-pop\nC-pop, retro Eurodance\nC-pop, retro Mandopop\nC-pop, retro anime\nC-pop, retro chiptune\nC-pop, retro dance\nC-pop, retro dance-pop\nC-pop, retro disco, funk\nC-pop, retro electronic\nC-pop, retro electronic, festive\nC-pop, retro funk\nC-pop, retro game\nC-pop, retro game, chiptune\nC-pop, retro game, cinematic\nC-pop, retro game, dance\nC-pop, retro game, electronic\nC-pop, retro game, funk\nC-pop, retro game, orchestral\nC-pop, retro game, synth pop\nC-pop, retro game, theatrical\nC-pop, retro hip-hop\nC-pop, retro hip-hop, synth funk\nC-pop, retro pop\nC-pop, retro pop, chiptune\nC-pop, retro pop, electronic\nC-pop, retro pop, indie rock\nC-pop, retro pop-funk\nC-pop, retro pop-rock\nC-pop, retro soul\nC-pop, retro synth\nC-pop, retro synth, 90s anime\nC-pop, retro synth, Eurodance\nC-pop, retro synth, anime soundtrack\nC-pop, retro synth, dance\nC-pop, retro synth, dance-pop\nC-pop, retro synth, electronic\nC-pop, retro synth, eurodance\nC-pop, retro synth, festive\nC-pop, retro synth, orchestral\nC-pop, retro synth, theatrical\nC-pop, retro synth, theatrical pop\nC-pop, retro synth, video game\nC-pop, retro video game\nC-pop, retro video game, dance-pop\nC-pop, retro video game, festive\nC-pop, retro, anime\nC-pop, retro, anthemic\nC-pop, retro, children's music\nC-pop, retro, chiptune\nC-pop, retro, cinematic\nC-pop, retro, dance\nC-pop, retro, dance-pop\nC-pop, retro, early 2000s\nC-pop, retro, electronic\nC-pop, retro, festive\nC-pop, retro, karaoke\nC-pop, retro, orchestral\nC-pop, retro, patriotic\nC-pop, retro, pop-rock\nC-pop, retro, sentimental\nC-pop, retro, synth ballad\nC-pop, retro, synth-pop\nC-pop, retro, synthwave\nC-pop, retro, theatrical\nC-pop, retro, upbeat\nC-pop, retro, video game\nC-pop, retro-dance\nC-pop, retro-funk, ambient\nC-pop, retro-funk, disco\nC-pop, retro-futuristic\nC-pop, retro-futuristic, anime\nC-pop, retro-futuristic, anime theme\nC-pop, retro-futuristic, dance\nC-pop, retro-futuristic, dance-pop\nC-pop, retro-futuristic, synthwave\nC-pop, retro-pop\nC-pop, revolutionary style, orchestral pop\nC-pop, revolutionary, anthemic\nC-pop, rock, acoustic\nC-pop, rock, ancient style\nC-pop, rock, ballad\nC-pop, rock, cinematic\nC-pop, rock, electronic\nC-pop, rock, epic\nC-pop, rock, folk\nC-pop, rock, metalcore\nC-pop, rock, orchestral\nC-pop, rock-opera\nC-pop, romantic\nC-pop, romantic R&B\nC-pop, romantic ballad, R&B\nC-pop, romantic, Christmas\nC-pop, romantic, R&B\nC-pop, romantic, ambient\nC-pop, romantic, cinematic\nC-pop, romantic, duet\nC-pop, romantic, epic\nC-pop, romantic, lo-fi\nC-pop, romantic, melancholic\nC-pop, romantic, modern\nC-pop, romantic, pop-rock\nC-pop, romantic, traditional\nC-pop, romantic, traditional Chinese\nC-pop, sentimental ballad\nC-pop, sentimental pop\nC-pop, sentimental, hip-hop\nC-pop, smooth R&B\nC-pop, smooth jazz\nC-pop, smooth soul\nC-pop, soft pop\nC-pop, soft rock\nC-pop, soulful ballad\nC-pop, soulful rock\nC-pop, soulful, ambient\nC-pop, spiritual pop\nC-pop, spiritual, atmospheric\nC-pop, spiritual, ballad\nC-pop, spiritual, cinematic\nC-pop, spiritual, epic\nC-pop, stadium rock, EDM\nC-pop, stadium rock, electronic\nC-pop, summer beach, R&B\nC-pop, symphonic J-rock\nC-pop, symphonic metal\nC-pop, symphonic metal, J-rock\nC-pop, symphonic metal, ambient\nC-pop, symphonic metal, ethereal pop\nC-pop, symphonic metal, metalcore\nC-pop, symphonic metal, nu-metal\nC-pop, symphonic metal, rock\nC-pop, symphonic power ballad\nC-pop, symphonic power metal\nC-pop, symphonic rock\nC-pop, symphonic rock, J-rock\nC-pop, symphonic rock, anime soundtrack\nC-pop, symphonic rock, cinematic\nC-pop, symphonic rock, electronic\nC-pop, symphonic rock, hip-hop\nC-pop, symphonic rock, nu-metal\nC-pop, symphonic rock, rap rock\nC-pop, synth folk\nC-pop, synth funk\nC-pop, synth pop\nC-pop, synth pop, ambient\nC-pop, synth pop, anime\nC-pop, synth pop, emotional rock\nC-pop, synth pop, festive\nC-pop, synth pop, funk rock\nC-pop, synth pop, pop-rock\nC-pop, synth pop, trap\nC-pop, synth pop, video game music\nC-pop, synth, anime\nC-pop, synth-pop\nC-pop, synth-pop, 80s pop\nC-pop, synth-pop, EDM\nC-pop, synth-pop, EDM-lite\nC-pop, synth-pop, J-pop\nC-pop, synth-pop, Mongolian folk\nC-pop, synth-pop, R&B\nC-pop, synth-pop, ambient\nC-pop, synth-pop, anime\nC-pop, synth-pop, anime soundtrack\nC-pop, synth-pop, anime theme\nC-pop, synth-pop, ballad\nC-pop, synth-pop, chiptune\nC-pop, synth-pop, cinematic\nC-pop, synth-pop, city pop\nC-pop, synth-pop, cyberpunk\nC-pop, synth-pop, dance-pop\nC-pop, synth-pop, disco\nC-pop, synth-pop, disco-funk\nC-pop, synth-pop, dream-pop\nC-pop, synth-pop, dreamy\nC-pop, synth-pop, electronic\nC-pop, synth-pop, electronic dance\nC-pop, synth-pop, electronic rock\nC-pop, synth-pop, emotional\nC-pop, synth-pop, festive\nC-pop, synth-pop, folk-pop\nC-pop, synth-pop, funk\nC-pop, synth-pop, future bass\nC-pop, synth-pop, hip-hop\nC-pop, synth-pop, lo-fi\nC-pop, synth-pop, lo-fi, piano ballad\nC-pop, synth-pop, melancholic\nC-pop, synth-pop, neo-soul\nC-pop, synth-pop, new-age\nC-pop, synth-pop, orchestral\nC-pop, synth-pop, patriotic\nC-pop, synth-pop, playful\nC-pop, synth-pop, pop ballad\nC-pop, synth-pop, pop-rock\nC-pop, synth-pop, retro\nC-pop, synth-pop, retro video game\nC-pop, synth-pop, retro-futuristic\nC-pop, synth-pop, theatrical\nC-pop, synth-pop, traditional fusion\nC-pop, synth-pop, trance-pop\nC-pop, synth-pop, trap\nC-pop, synth-pop, video game\nC-pop, synth-pop, video game music\nC-pop, synth-pop, world music\nC-pop, synth-pop, wuxia\nC-pop, synthpop\nC-pop, synthpop, Vocaloid\nC-pop, synthpop, quirky\nC-pop, synthwave\nC-pop, synthwave, JRPG\nC-pop, synthwave, Vocaloid\nC-pop, synthwave, chiptune\nC-pop, synthwave, cinematic\nC-pop, synthwave, cyberpunk\nC-pop, synthwave, dance\nC-pop, synthwave, electronic\nC-pop, synthwave, emotional\nC-pop, synthwave, festive\nC-pop, synthwave, lo-fi\nC-pop, synthwave, lo-fi hip hop\nC-pop, synthwave, pop-rock\nC-pop, synthwave, retro\nC-pop, synthwave, retro dance\nC-pop, tango, cumbia\nC-pop, theatrical\nC-pop, theatrical pop\nC-pop, theatrical pop, Wuxia style\nC-pop, theatrical pop, anime soundtrack\nC-pop, theatrical pop, hip-hop\nC-pop, theatrical pop, lo-fi\nC-pop, theatrical pop, orchestral pop\nC-pop, theatrical pop, pop-rock\nC-pop, theatrical pop, video game music\nC-pop, theatrical pop, wuxia\nC-pop, theatrical pop-rock\nC-pop, theatrical rock\nC-pop, theatrical, 80s synth\nC-pop, theatrical, Wuxia\nC-pop, theatrical, animation\nC-pop, theatrical, anime\nC-pop, theatrical, big band\nC-pop, theatrical, cinematic\nC-pop, theatrical, disco\nC-pop, theatrical, electronic\nC-pop, theatrical, fantasy\nC-pop, theatrical, festive\nC-pop, theatrical, funk\nC-pop, theatrical, hip-hop\nC-pop, theatrical, lo-fi\nC-pop, theatrical, modern traditional\nC-pop, theatrical, operatic\nC-pop, theatrical, playful\nC-pop, theatrical, pop-rock\nC-pop, theatrical, retro synth\nC-pop, theatrical, synth\nC-pop, theatrical, synthwave\nC-pop, theatrical, traditional\nC-pop, theatrical, traditional Chinese\nC-pop, theatrical, vintage\nC-pop, theatrical, whimsical\nC-pop, theatrical, wuxia\nC-pop, traditional Chinese folk\nC-pop, traditional Chinese folk, electronic\nC-pop, traditional Chinese folk, modern fusion\nC-pop, traditional Chinese folk, pop-rock\nC-pop, traditional Chinese fusion\nC-pop, traditional Chinese opera\nC-pop, traditional Chinese opera, rock\nC-pop, traditional Chinese, R&B\nC-pop, traditional Chinese, ambient\nC-pop, traditional Chinese, ballad\nC-pop, traditional Chinese, cinematic\nC-pop, traditional Chinese, electronic\nC-pop, traditional Chinese, electronic fusion\nC-pop, traditional Chinese, festive\nC-pop, traditional Chinese, folk pop\nC-pop, traditional Chinese, lo-fi\nC-pop, traditional Chinese, modern\nC-pop, traditional Chinese, modern ballad\nC-pop, traditional Chinese, modern folk\nC-pop, traditional Chinese, modern fusion\nC-pop, traditional Chinese, modern pop\nC-pop, traditional Chinese, playful\nC-pop, traditional Chinese, pop\nC-pop, traditional Chinese, pop-rock\nC-pop, traditional Chinese, rock\nC-pop, traditional Chinese, romantic\nC-pop, traditional Chinese, sentimental\nC-pop, traditional Chinese, trap\nC-pop, traditional Chinese, upbeat\nC-pop, traditional Chinese, whimsical\nC-pop, traditional folk\nC-pop, traditional folk, ambient\nC-pop, traditional folk, cinematic\nC-pop, traditional folk, electronic\nC-pop, traditional folk, festive\nC-pop, traditional folk, pop-rock\nC-pop, traditional fusion\nC-pop, traditional fusion, electronic\nC-pop, trance\nC-pop, trance, EDM\nC-pop, trance, Eurodance\nC-pop, trance, J-core\nC-pop, trance, anime\nC-pop, trance, artcore\nC-pop, trance, hardstyle\nC-pop, trance, hip-hop\nC-pop, trance, progressive house\nC-pop, trance-pop\nC-pop, trap\nC-pop, trap R&B\nC-pop, trap R&B, vaporwave\nC-pop, trap ballad\nC-pop, trap hip-hop\nC-pop, trap metal\nC-pop, trap soul\nC-pop, trap, Ancient Style\nC-pop, trap, EDM\nC-pop, trap, J-rock\nC-pop, trap, R&B\nC-pop, trap, R&B, hip-hop\nC-pop, trap, acoustic pop\nC-pop, trap, ambient\nC-pop, trap, ancient style\nC-pop, trap, anime-pop\nC-pop, trap, atmospheric\nC-pop, trap, atmospheric electronic\nC-pop, trap, ballad\nC-pop, trap, bossa nova\nC-pop, trap, chiptune\nC-pop, trap, cinematic\nC-pop, trap, cinematic, J-pop\nC-pop, trap, classical fusion\nC-pop, trap, cyberpunk\nC-pop, trap, dream pop\nC-pop, trap, dream-pop\nC-pop, trap, dreamy\nC-pop, trap, dreamy synth\nC-pop, trap, dubstep\nC-pop, trap, electronic\nC-pop, trap, electronic dance\nC-pop, trap, electronic pop\nC-pop, trap, electronic rock\nC-pop, trap, emotional\nC-pop, trap, emotional ballad\nC-pop, trap, epic\nC-pop, trap, ethereal\nC-pop, trap, festive\nC-pop, trap, folk\nC-pop, trap, folk fusion\nC-pop, trap, folkloric\nC-pop, trap, future bass\nC-pop, trap, gufeng\nC-pop, trap, guzheng\nC-pop, trap, hardstyle\nC-pop, trap, hip-hop\nC-pop, trap, hyperpop\nC-pop, trap, lo-fi\nC-pop, trap, lo-fi hip hop\nC-pop, trap, lo-fi hip-hop\nC-pop, trap, melancholic\nC-pop, trap, melodic rap\nC-pop, trap, nu-disco\nC-pop, trap, opera\nC-pop, trap, orchestral\nC-pop, trap, playful\nC-pop, trap, pop\nC-pop, trap, pop-ballad\nC-pop, trap, pop-punk\nC-pop, trap, pop-rap\nC-pop, trap, pop-rock\nC-pop, trap, rock\nC-pop, trap, romantic\nC-pop, trap, sentimental\nC-pop, trap, soul\nC-pop, trap, synth pop\nC-pop, trap, synth-pop\nC-pop, trap, synthpop\nC-pop, trap, synthwave\nC-pop, trap, traditional Chinese\nC-pop, trap, traditional South Asian\nC-pop, trap, traditional fusion\nC-pop, trap, trance\nC-pop, trap, vaporwave\nC-pop, trap, world music\nC-pop, trap, wuxia\nC-pop, trap-R&B\nC-pop, trap-R&B, atmospheric\nC-pop, trap-R&B, cinematic\nC-pop, trap-R&B, hyper-pop\nC-pop, trap-R&B, modern R&B\nC-pop, trap-pop\nC-pop, trap-pop, R&B\nC-pop, trap-pop, ambient\nC-pop, trap-pop, anime soundtrack\nC-pop, trap-pop, cinematic\nC-pop, trap-pop, dreamy\nC-pop, trap-pop, future bass\nC-pop, trap-soul, R&B\nC-pop, tribal electronic\nC-pop, trip-hop, R&B\nC-pop, trip-hop, ambient\nC-pop, trip-hop, cinematic\nC-pop, trip-hop, electronic\nC-pop, tropical house\nC-pop, tropical house, hip-hop\nC-pop, tropical, calypso\nC-pop, ukulele pop\nC-pop, upbeat, anime-inspired\nC-pop, upbeat, campus life\nC-pop, upbeat, electronic\nC-pop, upbeat, festive\nC-pop, upbeat, hip-hop\nC-pop, upbeat, modern pop\nC-pop, upbeat, nostalgic\nC-pop, upbeat, playful\nC-pop, upbeat, quirky\nC-pop, upbeat, retro synth\nC-pop, upbeat, romantic\nC-pop, upbeat, synthwave\nC-pop, upbeat, traditional Chinese\nC-pop, urban pop\nC-pop, vaporwave\nC-pop, vaporwave, R&B\nC-pop, vaporwave, trap\nC-pop, vaporwave, trap-R&B\nC-pop, video game\nC-pop, video game music\nC-pop, video game music, chiptune\nC-pop, video game music, dreamy\nC-pop, video game music, electronic\nC-pop, video game music, funk\nC-pop, video game music, hyper-pop\nC-pop, video game music, jazzy\nC-pop, video game music, synth pop\nC-pop, video game music, upbeat\nC-pop, video game pop\nC-pop, video game soundtrack\nC-pop, video game soundtrack, anime\nC-pop, video game soundtrack, whimsical\nC-pop, video game soundtrack, wuxia\nC-pop, video game, anime\nC-pop, video game, folk\nC-pop, video game, folk fusion\nC-pop, video game, lo-fi\nC-pop, video game, playful\nC-pop, video game, synthpop\nC-pop, video game, upbeat\nC-pop, video game, whimsical\nC-pop, whimsical\nC-pop, whimsical, dreamy\nC-pop, whimsical, electronic\nC-pop, whimsical, magical\nC-pop, whimsical, modern\nC-pop, whimsical, modern traditional\nC-pop, whimsical, nostalgic\nC-pop, whimsical, romantic\nC-pop, whimsical, synth pop\nC-pop, whimsical, traditional\nC-pop, whimsical, traditional Chinese\nC-pop, whimsical, video game\nC-pop, world fusion\nC-pop, world fusion, cinematic folk\nC-pop, world fusion, electronic dance\nC-pop, world fusion, lo-fi\nC-pop, world fusion, pop-rock\nC-pop, world music\nC-pop, world music fusion\nC-pop, world music, EDM\nC-pop, world music, ambient\nC-pop, world music, anthemic\nC-pop, world music, atmospheric\nC-pop, world music, cinematic\nC-pop, world music, dance\nC-pop, world music, funk\nC-pop, world music, melancholic\nC-pop, world music, pop-rock\nC-pop, world music, power ballad\nC-pop, world music, rock\nC-pop, world music, synth pop\nC-pop, world pop\nC-pop, worldbeat\nC-pop, worldbeat, ambient\nC-pop, worldbeat, electronic dance\nC-pop, worldbeat, video game music\nC-pop, wuxia, anime\nC-pop, wuxia, anime opening\nC-pop, wuxia, anime soundtrack\nC-pop, wuxia, anime theme\nC-pop, wuxia, atmospheric\nC-pop, wuxia, ballad\nC-pop, wuxia, cinematic\nC-pop, wuxia, cinematic rock\nC-pop, wuxia, electronic\nC-pop, wuxia, epic\nC-pop, wuxia, epic ballad\nC-pop, wuxia, epic rock\nC-pop, wuxia, fantasy anime\nC-pop, wuxia, pop-rock\nC-pop, wuxia, theatrical\nC-pop, wuxia, trap\nC-pop, wuxia, video game\nC-pop, wuxia, video game soundtrack\nC-pop, zouk, kompa\nC-pop,古风\nC-pop,喊麦\nC-rock\nC-rock J-rock\nC-rock guofeng\nC-rock, J-rock, cinematic\nC-rock, anime power metal\nC-rock, anime rock\nC-rock, anime rock, cinematic rock\nC-rock, anime theme, cinematic rock\nC-rock, electronic rock, traditional fusion\nC-rock, nu-metal, cinematic rock\nC-rock, power metal, wuxia\nC-rock, symphonic rock, Chinese fusion\nC-rock, symphonic rock, cinematic\nC-trap\nC-trap lo-fi\nC-trap, chiptune, trap\nC-trap, cloud rap, vaporwave\nC-trap, emo rap\nCafe music\nCajun\nCajun Christmas\nCajun bluegrass\nCajun country\nCajun country rock\nCajun country-rock\nCajun folk\nCajun folk-rock\nCajun music\nCajun polka-rock\nCajun pop\nCajun rock\nCajun rock, country rock\nCajun rockabilly\nCajun swing\nCajun waltz\nCajun, New Orleans, dance\nCajun, New Orleans, swing\nCajun, Western Swing\nCajun, bluegrass\nCajun, country-folk\nCajun, festive, country\nCajun, festive, danceable\nCajun, festive, upbeat\nCajun, party, high-energy\nCalifornia hip-hop\nCalifornia trap\nCanadian drill\nCanadian hip hop\nCandombe\nCandombe Rumba\nCandombe protest\nCandombe rock\nCandombe tango\nCandy-reggaeton\nCante Jondo\nCanto-pop\nCanto-pop J-rock anime\nCanto-pop Latin\nCanto-pop Latin jazz\nCanto-pop R&B\nCanto-pop anime\nCanto-pop anime theme\nCanto-pop ballad\nCanto-pop blues\nCanto-pop cinematic\nCanto-pop classical crossover\nCanto-pop dream pop\nCanto-pop folk\nCanto-pop funk\nCanto-pop funk disco\nCanto-pop funk hip-hop\nCanto-pop hip-hop\nCanto-pop hip-hop J-pop\nCanto-pop jazz\nCanto-pop jazz fusion\nCanto-pop jazz lounge\nCanto-pop retro\nCanto-pop rock\nCanto-pop show tune\nCanto-pop surf rock\nCanto-pop swing\nCanto-pop, European folk, theatrical\nCanto-pop, J-rock\nCanto-pop, Latin, world music\nCanto-pop, chanson, jazz\nCanto-pop, cinematic, industrial\nCanto-pop, cinematic, orchestral\nCanto-pop, cinematic, retro pop-rock\nCanto-pop, funk, old-school hip-hop\nCanto-pop, funk, retro\nCanto-pop, orchestral, power ballad\nCanto-pop, rockabilly, retro swing\nCanto-rap\nCanto-rock\nCanto-rock punk\nCanto-rock surf rock\nCanto-rock, rockabilly, big band\nCanto-trap\nCantonese R&B\nCantonese acoustic\nCantonese acoustic ballad\nCantonese ambient\nCantonese ballad\nCantonese ballad, Bossa Nova\nCantonese ballad, cinematic pop, emotional\nCantonese ballad, hip-hop, cinematic\nCantonese ballad, power ballad, Christmas\nCantonese ballad, stadium rock\nCantonese cinematic\nCantonese electronic\nCantonese folk\nCantonese folk ballad, pop-rock\nCantonese folk pop\nCantonese folk rock\nCantonese folk-pop\nCantonese hip hop\nCantonese hip-hop\nCantonese hip-hop, Mandarin pop\nCantonese hip-hop, cinematic hip-hop\nCantonese hip-hop, cinematic soul\nCantonese hip-hop, hyperpop, chiptune\nCantonese indie\nCantonese indie rock\nCantonese opera\nCantonese opera rock\nCantonese opera, electronic, theatrical\nCantonese pop\nCantonese pop ballad\nCantonese pop, 8-bit, theatrical\nCantonese pop, 80s synth\nCantonese pop, Mandarin pop, ballad\nCantonese pop, chiptune, theatrical\nCantonese pop, cinematic, emotional\nCantonese pop, hip-hop\nCantonese pop-rap\nCantonese power ballad\nCantonese rap\nCantonese rap, EDM, dubstep\nCantonese rock\nCantonese rock ballad\nCantonese soul, city pop, J-pop\nCantonese trap\nCantonese trap, cloud rap, R&B\nCantonese trap, future bass, cinematic\nCantonese trap, pop-trap, cinematic hip hop\nCantopop\nCantopop 80s\nCantopop 80s anime\nCantopop 90s R&B\nCantopop Bossa Nova\nCantopop City Pop\nCantopop City Pop funk\nCantopop EDM\nCantopop Eurobeat trance\nCantopop Eurodance\nCantopop Eurodance J-pop\nCantopop Eurodance trance\nCantopop Italo-disco\nCantopop J-pop\nCantopop J-pop EDM\nCantopop J-pop anime\nCantopop J-pop chiptune\nCantopop J-pop video game\nCantopop J-pop video game music\nCantopop J-rock\nCantopop J-rock anime\nCantopop Latin\nCantopop Latin dance\nCantopop Latin disco\nCantopop Latin fusion\nCantopop Latin pop\nCantopop Mandopop\nCantopop Mandopop Eurodance\nCantopop Mandopop orchestral\nCantopop R&B\nCantopop R&B city pop\nCantopop R&B electronic\nCantopop R&B funk\nCantopop R&B hip-hop\nCantopop R&B lo-fi\nCantopop R&B lo-fi hip-hop\nCantopop R&B soul\nCantopop R&B synth-pop\nCantopop R&B trap\nCantopop V-Pop\nCantopop acoustic ballad\nCantopop anime\nCantopop anime soundtrack\nCantopop anime theme\nCantopop ballad\nCantopop big band\nCantopop big band jazz\nCantopop big band swing\nCantopop blues\nCantopop blues soul\nCantopop blues-rock\nCantopop blues-rock soul\nCantopop bossa nova\nCantopop bossa nova lounge\nCantopop chamber pop\nCantopop chiptune\nCantopop cinematic\nCantopop city pop\nCantopop city pop R&B\nCantopop city pop funk\nCantopop city pop jazz-fusion\nCantopop city pop smooth jazz\nCantopop city pop synth-pop\nCantopop classical crossover\nCantopop country-rock\nCantopop dance\nCantopop disco\nCantopop disco funk\nCantopop disco-funk\nCantopop flamenco\nCantopop folk\nCantopop folk-pop\nCantopop folk-rock\nCantopop funk\nCantopop funk R&B\nCantopop funk city pop\nCantopop funk dance-pop\nCantopop funk disco\nCantopop funk hip-hop\nCantopop funk jazz fusion\nCantopop funk pop-rock\nCantopop funk reggae\nCantopop funk soul\nCantopop funk synth-pop\nCantopop funk-pop\nCantopop funk-rock\nCantopop funk-rock synth-pop\nCantopop future bass\nCantopop future bass EDM\nCantopop gospel\nCantopop hard rock\nCantopop hardstyle\nCantopop hip-hop\nCantopop hip-hop R&B\nCantopop hyperpop\nCantopop hyperpop EDM\nCantopop hyperpop J-pop\nCantopop hyperpop cloud rap\nCantopop hyperpop trap\nCantopop indie rock\nCantopop jazz\nCantopop jazz ballad\nCantopop jazz big band\nCantopop jazz blues\nCantopop jazz funk\nCantopop jazz fusion\nCantopop jazz fusion city pop\nCantopop jazz lounge\nCantopop jazz soul\nCantopop jazz-funk R&B\nCantopop jazzy R&B\nCantopop lo-fi\nCantopop lo-fi hip hop\nCantopop lo-fi hip-hop R&B\nCantopop lo-fi hip-hop chiptune\nCantopop lounge\nCantopop lounge bossa nova\nCantopop lounge exotica\nCantopop lounge jazz\nCantopop neo-soul\nCantopop neo-soul R&B\nCantopop neo-soul city pop\nCantopop neo-soul funk\nCantopop neo-soul jazz fusion\nCantopop nu-disco city pop\nCantopop orchestral\nCantopop pop-punk\nCantopop progressive house\nCantopop rap\nCantopop retro\nCantopop retro big-band\nCantopop retro funk\nCantopop retro rock\nCantopop retro-funk disco\nCantopop rock\nCantopop rock ballad\nCantopop rock soul\nCantopop rockabilly\nCantopop rockabilly blues rock\nCantopop rockabilly surf rock\nCantopop rockabilly swing\nCantopop smooth jazz\nCantopop soul\nCantopop soul funk\nCantopop surf rock\nCantopop synth-funk\nCantopop synth-pop\nCantopop synth-pop dance-pop\nCantopop trance\nCantopop trap\nCantopop trap R&B\nCantopop trap chiptune\nCantopop trap synth-pop\nCantopop trap-R&B\nCantopop trip-hop\nCantopop tropical house\nCantopop world music\nCantopop wuxia\nCantopop, 70s rock\nCantopop, 80s adult contemporary\nCantopop, 80s anime\nCantopop, 80s anime, synthwave\nCantopop, 80s anime, theatrical\nCantopop, 80s dance-pop\nCantopop, 80s martial arts film, theatrical\nCantopop, 80s pop-rock\nCantopop, 80s rock\nCantopop, 80s rock, chiptune\nCantopop, 80s rock, power ballad\nCantopop, 80s synth\nCantopop, 80s synth pop\nCantopop, 80s synth, cinematic\nCantopop, 80s synth, funk\nCantopop, 80s synth, retro-futuristic\nCantopop, 80s synth-pop\nCantopop, 80s synth-pop, city pop\nCantopop, 80s, Latin funk\nCantopop, 80s, Latin-infused\nCantopop, 80s, cinematic\nCantopop, 80s, power ballad\nCantopop, 90s R&B\nCantopop, 90s R&B, city pop\nCantopop, 90s anime, synthwave\nCantopop, 90s hip-hop, cinematic\nCantopop, Bossa Nova\nCantopop, Bossa Nova, Latin jazz\nCantopop, Bossa Nova, light jazz\nCantopop, Bossa Nova, lounge\nCantopop, Bossa Nova, lounge jazz\nCantopop, Christmas pop, musical theater\nCantopop, Christmas, pop\nCantopop, Christmas, soulful\nCantopop, City Pop\nCantopop, City Pop, disco-funk\nCantopop, City Pop, funk\nCantopop, City Pop, retro-futuristic\nCantopop, City Pop, synth-funk\nCantopop, City Pop, synth-pop\nCantopop, EDM\nCantopop, EDM, cinematic\nCantopop, EDM, dance\nCantopop, EDM, dance-pop\nCantopop, EDM, festive\nCantopop, EDM, future bass\nCantopop, EDM, hip-hop\nCantopop, EDM, synth-pop\nCantopop, EDM, trance\nCantopop, Eurobeat\nCantopop, Eurobeat, City Pop\nCantopop, Eurobeat, Hi-NRG\nCantopop, Eurobeat, Italo-disco\nCantopop, Eurobeat, J-pop\nCantopop, Eurobeat, J-rock\nCantopop, Eurobeat, anime\nCantopop, Eurobeat, happy hardcore\nCantopop, Eurobeat, synth-pop\nCantopop, Eurobeat, trance\nCantopop, Eurodance\nCantopop, Eurodance, 90s dance-pop\nCantopop, Eurodance, Hi-NRG\nCantopop, Eurodance, Italo disco\nCantopop, Eurodance, J-pop\nCantopop, Eurodance, Trance\nCantopop, Eurodance, chiptune\nCantopop, Eurodance, dance\nCantopop, Eurodance, dance-pop\nCantopop, Eurodance, funk\nCantopop, Eurodance, happy hardcore\nCantopop, Eurodance, hardstyle\nCantopop, Eurodance, hip-house\nCantopop, Eurodance, hyperpop\nCantopop, Eurodance, retro\nCantopop, Eurodance, synth-pop\nCantopop, Eurodance, techno\nCantopop, Eurodance, trance\nCantopop, Eurodance, trance-pop\nCantopop, European folk\nCantopop, European folk, cinematic\nCantopop, Hi-NRG, dance-pop\nCantopop, Italo-disco\nCantopop, J-RPG, pop-rock\nCantopop, J-RPG, theatrical\nCantopop, J-pop\nCantopop, J-pop, anime\nCantopop, J-pop, chiptune\nCantopop, J-pop, cinematic\nCantopop, J-pop, funk\nCantopop, J-pop, video game music\nCantopop, J-rock\nCantopop, J-rock, anime\nCantopop, J-rock, anime theme\nCantopop, J-rock, chiptune\nCantopop, J-rock, cinematic\nCantopop, J-rock, dreamy synth\nCantopop, J-rock, electronic\nCantopop, J-rock, nu-metal\nCantopop, J-rock, synth-pop\nCantopop, Latin cha-cha-chá\nCantopop, Latin disco, funk\nCantopop, Latin jazz, salsa\nCantopop, Latin pop\nCantopop, Latin pop, disco\nCantopop, Latin pop-rock\nCantopop, Latin, ballad\nCantopop, Latin, samba\nCantopop, Latin, synthwave\nCantopop, Middle Eastern dance\nCantopop, New Jack Swing\nCantopop, New Jack Swing, Hip Hop\nCantopop, New Jack Swing, dance\nCantopop, R&B\nCantopop, R&B, hip-hop\nCantopop, R&B, lo-fi hip-hop\nCantopop, R&B, synth-pop\nCantopop, alternative rock, lo-fi\nCantopop, ambient, electronic\nCantopop, anime theme, electronic\nCantopop, anime theme, funk\nCantopop, anime theme, video game music\nCantopop, anime, video game\nCantopop, arena rock\nCantopop, baroque-pop, dance\nCantopop, big band\nCantopop, big band, Latin\nCantopop, big band, disco-funk\nCantopop, big band, funk\nCantopop, big band, jazz\nCantopop, big band, rock\nCantopop, big band, show tune\nCantopop, big band, swing\nCantopop, big band, theatrical\nCantopop, big band, triumphant\nCantopop, big band, vintage\nCantopop, big-band, theatrical\nCantopop, boom-bap hip-hop\nCantopop, boom-bap hip-hop, lo-fi\nCantopop, boom-bap, lo-fi hip hop\nCantopop, cha-cha-cha\nCantopop, cha-cha-cha, theatrical\nCantopop, cha-cha-chá\nCantopop, chiptune\nCantopop, chiptune, J-pop\nCantopop, chiptune, J-rock\nCantopop, chiptune, ambient\nCantopop, chiptune, cinematic\nCantopop, chiptune, dance-pop\nCantopop, chiptune, electronic\nCantopop, chiptune, lo-fi\nCantopop, chiptune, nostalgic\nCantopop, chiptune, orchestral\nCantopop, chiptune, power ballad\nCantopop, chiptune, rock\nCantopop, chiptune, synth-pop\nCantopop, chiptune, video game music\nCantopop, cinematic hip-hop\nCantopop, cinematic orchestral\nCantopop, cinematic orchestral, rock\nCantopop, cinematic pop, J-rock\nCantopop, cinematic pop, emotional rock\nCantopop, cinematic rock\nCantopop, cinematic synth, orchestral\nCantopop, cinematic, 80s\nCantopop, cinematic, 80s synth\nCantopop, cinematic, 90s\nCantopop, cinematic, Chinese ballad\nCantopop, cinematic, Eurodance\nCantopop, cinematic, J-RPG\nCantopop, cinematic, ambient\nCantopop, cinematic, anime\nCantopop, cinematic, atmospheric\nCantopop, cinematic, ballad\nCantopop, cinematic, baroque pop\nCantopop, cinematic, blues-rock\nCantopop, cinematic, classical\nCantopop, cinematic, classical crossover\nCantopop, cinematic, electronic\nCantopop, cinematic, epic\nCantopop, cinematic, funk\nCantopop, cinematic, guzheng\nCantopop, cinematic, gypsy-jazz\nCantopop, cinematic, hard rock\nCantopop, cinematic, melancholic\nCantopop, cinematic, new-age\nCantopop, cinematic, operatic\nCantopop, cinematic, orchestral\nCantopop, cinematic, orchestral pop\nCantopop, cinematic, pop-rock\nCantopop, cinematic, power ballad\nCantopop, cinematic, retro\nCantopop, cinematic, rock\nCantopop, cinematic, rock ballad\nCantopop, cinematic, spiritual\nCantopop, cinematic, synth-orchestral\nCantopop, cinematic, synthwave\nCantopop, cinematic, traditional Chinese\nCantopop, cinematic, traditional East Asian\nCantopop, cinematic, trap\nCantopop, cinematic, wuxia\nCantopop, city pop\nCantopop, city pop, dance-pop\nCantopop, city pop, funk\nCantopop, city pop, smooth jazz\nCantopop, city pop, synth-pop\nCantopop, city pop, synthwave\nCantopop, city-pop\nCantopop, city-pop, 80s synth\nCantopop, city-pop, retro\nCantopop, dance, Eurodance\nCantopop, dance, chiptune\nCantopop, dance, electronic\nCantopop, dance, festive\nCantopop, dance, retro\nCantopop, dance, synth-pop\nCantopop, dance-pop\nCantopop, dance-pop, 90s\nCantopop, dance-pop, EDM\nCantopop, dance-pop, Eurobeat\nCantopop, dance-pop, Eurodance\nCantopop, dance-pop, breakbeat\nCantopop, dance-pop, disco\nCantopop, dance-pop, festive\nCantopop, dance-pop, funk\nCantopop, dance-pop, hip-hop\nCantopop, dance-pop, new jack swing\nCantopop, disco, funk\nCantopop, disco-funk\nCantopop, disco-funk, 80s\nCantopop, disco-funk, big band\nCantopop, disco-funk, cinematic\nCantopop, disco-funk, dance\nCantopop, disco-funk, rock\nCantopop, dreamy, cinematic\nCantopop, dreamy, electronic\nCantopop, electronic rock\nCantopop, electronic, cinematic\nCantopop, electronic, festive\nCantopop, electronic, glitch\nCantopop, electronic, hip hop\nCantopop, electronic, techno\nCantopop, festive, electronic\nCantopop, festive, retro\nCantopop, festive, romantic\nCantopop, flamenco, ballad\nCantopop, folk pop\nCantopop, folk rock\nCantopop, funk pop, pop-rock\nCantopop, funk, 80s pop\nCantopop, funk, 90s new jack swing\nCantopop, funk, R&B\nCantopop, funk, big band\nCantopop, funk, city pop\nCantopop, funk, dance-pop\nCantopop, funk, hip-hop\nCantopop, funk, new jack swing\nCantopop, funk, soul\nCantopop, funk, synth-pop\nCantopop, funk, synthwave\nCantopop, garage rock, surf rock\nCantopop, happy hardcore, trance\nCantopop, happy hardcore, trancecore\nCantopop, hard rock\nCantopop, hard rock, glam metal\nCantopop, hard rock, synth-pop\nCantopop, hard rock, synthwave\nCantopop, hardstyle\nCantopop, hip-hop, R&B\nCantopop, hip-hop, breakbeat\nCantopop, hip-hop, chiptune\nCantopop, hip-hop, electronic\nCantopop, hip-hop, electronic dance\nCantopop, hip-hop, retro\nCantopop, hip-hop, synthwave\nCantopop, hyperpop\nCantopop, hyperpop, J-pop\nCantopop, hyperpop, nightcore\nCantopop, jazz-funk, city pop\nCantopop, jungle, rave\nCantopop, lo-fi trap\nCantopop, lo-fi, ambient\nCantopop, lo-fi, pop-rock\nCantopop, lo-fi, power ballad\nCantopop, martial arts, cinematic\nCantopop, melancholic pop-rock\nCantopop, melancholic, retro\nCantopop, musical theater, dramatic ballad\nCantopop, musical theatre\nCantopop, new jack swing\nCantopop, new jack swing, 90s pop\nCantopop, new jack swing, breakbeat\nCantopop, new jack swing, city pop\nCantopop, new jack swing, dance\nCantopop, new jack swing, dance-pop\nCantopop, new jack swing, funk\nCantopop, new jack swing, hip-house\nCantopop, new jack swing, synth-funk\nCantopop, new jack swing, synth-pop\nCantopop, new wave, post-punk\nCantopop, new-age, world music\nCantopop, novelty, theatrical\nCantopop, operatic, art song\nCantopop, orchestral pop\nCantopop, orchestral pop, cinematic\nCantopop, orchestral, 80s\nCantopop, orchestral, 80s synth\nCantopop, orchestral, cinematic\nCantopop, orchestral, dance-pop\nCantopop, orchestral, disco-funk\nCantopop, orchestral, funk\nCantopop, orchestral, pop-rock\nCantopop, orchestral, power ballad\nCantopop, orchestral, rock\nCantopop, orchestral, synth-pop\nCantopop, orchestral, theatrical\nCantopop, orchestral, traditional Chinese\nCantopop, pop-rap\nCantopop, pop-rock\nCantopop, pop-rock, J-rock\nCantopop, pop-rock, cinematic\nCantopop, pop-rock, classical fusion\nCantopop, pop-rock, electronic\nCantopop, pop-rock, hip-hop\nCantopop, pop-rock, rock\nCantopop, pop-rock, slide guitar\nCantopop, pop-rock, symphonic rock\nCantopop, power ballad, 80s\nCantopop, power ballad, 80s rock\nCantopop, power ballad, Eurodance\nCantopop, power ballad, cinematic\nCantopop, power ballad, cinematic rock\nCantopop, power ballad, orchestral\nCantopop, power ballad, pop-rock\nCantopop, power ballad, rock\nCantopop, retro dance\nCantopop, retro dance, Eurodance\nCantopop, retro dance-pop\nCantopop, retro disco, funk\nCantopop, retro funk, disco\nCantopop, retro game, electronic\nCantopop, retro rock, surf rock\nCantopop, retro synth\nCantopop, retro synth, dance-pop\nCantopop, retro synth, theatrical\nCantopop, retro synth, traditional fusion\nCantopop, retro synth, video game\nCantopop, retro video game\nCantopop, retro video game, theatrical\nCantopop, retro, 80s\nCantopop, retro, anime\nCantopop, retro, anime theme\nCantopop, retro, big-band\nCantopop, retro, chiptune\nCantopop, retro, cinematic\nCantopop, retro, dance\nCantopop, retro, dance-pop\nCantopop, retro, electronic\nCantopop, retro, festive\nCantopop, retro, funk\nCantopop, retro, garage rock\nCantopop, retro, hip-hop\nCantopop, retro, karaoke\nCantopop, retro, orchestral\nCantopop, retro, theatrical\nCantopop, retro, video game\nCantopop, retro-futuristic, dance\nCantopop, retro-futuristic, synth-pop\nCantopop, rock and roll\nCantopop, rock and roll, big band\nCantopop, rock, cinematic\nCantopop, rock, emotional\nCantopop, rock, traditional Chinese\nCantopop, show tune\nCantopop, show tune, theatrical\nCantopop, smooth jazz, adult contemporary\nCantopop, surf rock, indie pop\nCantopop, surf rock, rock and roll\nCantopop, symphonic rock\nCantopop, symphonic rock, cinematic\nCantopop, symphonic rock, power ballad\nCantopop, synth-funk, city pop\nCantopop, synth-funk, new jack swing\nCantopop, synth-funk, synth-pop\nCantopop, synth-orchestral, 80s\nCantopop, synth-pop\nCantopop, synth-pop, 80s\nCantopop, synth-pop, 80s dance\nCantopop, synth-pop, 90s dance-pop\nCantopop, synth-pop, City Pop\nCantopop, synth-pop, EDM\nCantopop, synth-pop, Eurobeat\nCantopop, synth-pop, Italo-disco\nCantopop, synth-pop, Mandopop\nCantopop, synth-pop, anime theme\nCantopop, synth-pop, ballad\nCantopop, synth-pop, chiptune\nCantopop, synth-pop, cinematic\nCantopop, synth-pop, city pop\nCantopop, synth-pop, dance-pop\nCantopop, synth-pop, disco\nCantopop, synth-pop, disco-funk\nCantopop, synth-pop, electro-funk\nCantopop, synth-pop, electro-pop\nCantopop, synth-pop, electronic\nCantopop, synth-pop, electronic dance\nCantopop, synth-pop, electronic rock\nCantopop, synth-pop, festive\nCantopop, synth-pop, funk\nCantopop, synth-pop, funk-rock\nCantopop, synth-pop, hip hop\nCantopop, synth-pop, hip-hop\nCantopop, synth-pop, new jack swing\nCantopop, synth-pop, new wave\nCantopop, synth-pop, pop-rock\nCantopop, synth-pop, power ballad\nCantopop, synth-pop, retro\nCantopop, synth-pop, retro-futuristic\nCantopop, synth-pop, rock\nCantopop, synth-pop, video game music\nCantopop, synth-pop, wuxia\nCantopop, synth-rock\nCantopop, synthwave, 80s pop\nCantopop, synthwave, rock\nCantopop, theatrical, baroque\nCantopop, theatrical, chiptune\nCantopop, theatrical, folk tango\nCantopop, theatrical, orchestral\nCantopop, theatrical, power ballad\nCantopop, theatrical, retro\nCantopop, theatrical, rock\nCantopop, theatrical, show tune\nCantopop, traditional Chinese folk\nCantopop, trap, R&B\nCantopop, trap, ballad\nCantopop, trap, electronic\nCantopop, video game music, synthwave\nCantopop, vintage rock, surf rock\nCantopop, world music, cinematic\nCantopop, wuxia, cinematic\nCantopop, wuxia, pop-rock\nCantopop-rock\nCanzone Italiana\nCaribbean\nCaribbean Christmas\nCaribbean Christmas, Zouk, R&B\nCaribbean Gospel\nCaribbean R&B\nCaribbean Zouk\nCaribbean acapella\nCaribbean acoustic\nCaribbean anthem\nCaribbean ballad\nCaribbean blues\nCaribbean boogie-woogie\nCaribbean carnival\nCaribbean chanson\nCaribbean chiptune\nCaribbean club\nCaribbean dance\nCaribbean dance, Zouk, Afrobeats\nCaribbean dance-pop\nCaribbean dancehall\nCaribbean electronic\nCaribbean folk\nCaribbean folk, French chanson\nCaribbean folk-pop\nCaribbean folk-rock\nCaribbean funk\nCaribbean funk, Soukous\nCaribbean gospel\nCaribbean groove\nCaribbean hip hop\nCaribbean hip-hop\nCaribbean hip-hop funk\nCaribbean hip-hop trap\nCaribbean jazz\nCaribbean jazz-funk\nCaribbean music\nCaribbean party\nCaribbean pop\nCaribbean pop, Afrobeats, Dancehall\nCaribbean pop-funk\nCaribbean pop-rock\nCaribbean protest\nCaribbean rave\nCaribbean reggae\nCaribbean rhythm\nCaribbean rock\nCaribbean rumba\nCaribbean salsa\nCaribbean samba\nCaribbean soca\nCaribbean soul\nCaribbean soul salsa\nCaribbean spiritual\nCaribbean trap\nCaribbean vocal\nCaribbean world music\nCaribbean zouk\nCaribbean, Christmas, dance\nCaribbean, brass, dance\nCaribbean, brass, festive\nCaribbean, calypso, festive\nCaribbean, dance, brass\nCaribbean, dance, reggae\nCaribbean, drinking song\nCaribbean, festive, acoustic\nCaribbean, soca, Afro-Latin\nCaribbean, soukous, highlife\nCaribbean, video game music\nCaribbean, zouk, dance\nCarnatic\nCarnatic a cappella\nCarnatic bhajan\nCarnatic chiptune\nCarnatic classical\nCarnatic devotional\nCarnatic electronic\nCarnatic electronica\nCarnatic folk\nCarnatic folk fusion\nCarnatic folk-pop\nCarnatic fusion\nCarnatic fusion funk\nCarnatic fusion, pop-rock, electronic\nCarnatic hip-hop\nCarnatic jazz cabaret\nCarnatic music\nCarnatic pop\nCarnatic pop-rock\nCarnatic rock\nCarnatic trap\nCarnatic trap R&B\nCarnatic world music\nCarnatic, Indian devotional\nCarnatic, Indian folk\nCarnatic, Kollywood, cinematic\nCarnatic, bhajan, devotional\nCarnatic, cinematic, devotional\nCarnatic, cinematic, orchestral\nCarnatic, cinematic, world fusion\nCarnatic, devotional, South Indian\nCarnatic, devotional, cinematic\nCarnatic, devotional, festive\nCarnatic, devotional, world fusion\nCarnatic, folk, devotional\nCarnival music\nCatalan ballad\nCatalan folk\nCatalan rumba\nCaucasian folk fusion\nCaucasian folk-pop\nCaucasian pop\nCello, Folk, Klezmer\nCeltic\nCeltic EDM\nCeltic a cappella\nCeltic ambient\nCeltic ballad\nCeltic chiptune\nCeltic dance-pop\nCeltic drill\nCeltic electronic\nCeltic fantasy\nCeltic fiddle\nCeltic folk\nCeltic folk bluegrass\nCeltic folk chiptune\nCeltic folk country\nCeltic folk gypsy jazz\nCeltic folk jazz\nCeltic folk metal\nCeltic folk metal arena rock\nCeltic folk metal chiptune\nCeltic folk metal power metal\nCeltic folk metal, hard rock\nCeltic folk pop\nCeltic folk pop-rock\nCeltic folk power metal\nCeltic folk rock\nCeltic folk swing\nCeltic folk worship\nCeltic folk, Americana\nCeltic folk, Andean folk\nCeltic folk, Irish folk, Spanish carol, German polka\nCeltic folk, J-rock\nCeltic folk, J-rock, anime theme\nCeltic folk, JRPG soundtrack, instrumental\nCeltic folk, bluegrass\nCeltic folk, blues-rock\nCeltic folk, boogie-woogie rock\nCeltic folk, cinematic, orchestral\nCeltic folk, cinematic, progressive rock\nCeltic folk, electronic dance\nCeltic folk, electronic dance music\nCeltic folk, electronic dance, cinematic\nCeltic folk, electronic dance-pop\nCeltic folk, electronic, ambient\nCeltic folk, electronic, cinematic\nCeltic folk, folk-punk\nCeltic folk, happy hardcore, trance\nCeltic folk, new age, chamber music\nCeltic folk, orchestral, operatic\nCeltic folk, polka\nCeltic folk, praise and worship, pop-rock\nCeltic folk, video game soundtrack\nCeltic folk, video game soundtrack, epic\nCeltic folk, video game soundtrack, instrumental\nCeltic folk, world music, epic soundtrack\nCeltic folk-jazz\nCeltic folk-pop\nCeltic folk-pop dance-rock\nCeltic folk-pop, EDM, stadium rock\nCeltic folk-punk\nCeltic folk-reggae\nCeltic folk-rock\nCeltic folk-rock J-pop\nCeltic folk-rock power metal\nCeltic folk-rock synth-pop\nCeltic folk-rock, EDM\nCeltic folk-rock, EDM-pop\nCeltic folk-rock, chiptune\nCeltic folk-rock, chiptune, synth-pop\nCeltic funk\nCeltic fusion\nCeltic fusion dance-pop\nCeltic harp\nCeltic hip-hop\nCeltic hip-hop rock\nCeltic house\nCeltic hymn\nCeltic jazz fusion\nCeltic jazz swing\nCeltic metal\nCeltic metal power metal\nCeltic new age\nCeltic new-age\nCeltic pop\nCeltic pop rock\nCeltic pop-dance\nCeltic pop-folk\nCeltic pop-rap\nCeltic pop-rock\nCeltic power metal\nCeltic pub rock\nCeltic pub-rock\nCeltic punk\nCeltic punk chiptune\nCeltic punk folk metal\nCeltic punk folk rock\nCeltic punk folk-punk\nCeltic punk funk rock\nCeltic punk pirate metal\nCeltic punk pop-punk\nCeltic punk power metal\nCeltic punk power-pop\nCeltic punk pub rock\nCeltic punk rock\nCeltic punk rock chiptune\nCeltic punk rock power metal\nCeltic punk rock, Nintendocore\nCeltic punk rock, chiptune power metal\nCeltic punk rock, chiptune, power metal\nCeltic punk rock, power metal\nCeltic punk rockabilly\nCeltic punk ska-punk\nCeltic punk, bluegrass\nCeltic punk, chiptune, Nintendocore\nCeltic punk, electronic dance\nCeltic punk, folk metal\nCeltic punk, folk metal, sea shanty\nCeltic punk, folk rock\nCeltic punk, folk rock, punk rock\nCeltic punk, folk-rock, sea shanty\nCeltic punk, hard rock\nCeltic punk, horror rock\nCeltic punk, pirate metal\nCeltic punk, pop-punk\nCeltic punk, power metal\nCeltic punk, pub rock\nCeltic punk, pub rock, high-speed\nCeltic punk, sea shanty\nCeltic punk, sea shanty rock\nCeltic punk, speed metal\nCeltic reel\nCeltic reggae\nCeltic rock\nCeltic rock arena rock\nCeltic spiritual\nCeltic swing\nCeltic swing jazz\nCeltic synth\nCeltic synth-pop\nCeltic trap\nCeltic worship\nCeltic, bluegrass\nCeltic, cinematic, orchestral\nCentral Asian dance-pop\nCentral Asian folk\nCentral Asian folk hip-hop\nCentral Asian folk pop\nCentral Asian folk pop-rock\nCentral Asian folk rock\nCentral Asian folk, Eurodance\nCentral Asian folk, electronic dance\nCentral Asian folk, modern production, spiritual\nCentral Asian folk-pop\nCentral Asian fusion\nCentral Asian fusion pop\nCentral Asian fusion pop-rock\nCentral Asian fusion rock\nCentral Asian hip-hop\nCentral Asian pop\nCentral Asian pop Eurodance\nCentral Asian pop chiptune\nCentral Asian pop reggaeton\nCentral Asian pop, Eurodance\nCentral Asian pop, Eurodance, chiptune\nCentral Asian pop, Eurodance, cinematic\nCentral Asian pop, electronic dance\nCentral Asian pop, trap, rock\nCentral Asian pop-R&B\nCentral Asian pop-dance\nCentral Asian pop-rap\nCentral Asian pop-rock\nCh tripleto\nChacamé\nChacarera\nChacarera Candombe\nChacarera Cumbia\nChacarera Vallenato\nChalga\nChalga pop\nChalga pop-rock\nChalga, Balkan, Turkish folk\nChalga, Eurodance, folk-pop\nChalga, cinematic folk\nChalga, cinematic, Balkan\nChalga, electronic, Balkan folk\nChalga, electronic, duduk\nChamamé\nChant\nChicago R&B\nChicago blues\nChicago blues rock\nChicago drill\nChicago drill trap\nChicago drill, trap\nChicago hip-hop\nChicago house\nChicago soul\nChicago trap\nChicago-style R&B\nChicha\nChill hip-hop, trap, lo-fi\nChill trap\nChinese DJ remix, Eurodance, high-tempo\nChinese EDM\nChinese EDM rap\nChinese EDM-rap\nChinese Eurodance\nChinese MC\nChinese MC dance\nChinese MC electronic\nChinese MC 喊麦\nChinese MC, Eurodance\nChinese MC, Eurodance, Trance\nChinese MC, Eurodance, electronic\nChinese MC, electronic dance, EDM\nChinese MC, electronic, dance\nChinese MC喊麦, Eurodance, ambient\nChinese New Year\nChinese New Year hip-hop\nChinese New Year pop\nChinese New Year pop, Mandopop\nChinese New Year pop-rock\nChinese New Year, big band, festive\nChinese New Year, big band, pop-rock\nChinese New Year, chiptune, electronic\nChinese New Year, chiptune, pop\nChinese New Year, chiptune, retro\nChinese New Year, dance, synth pop\nChinese New Year, electronic dance, C-pop\nChinese New Year, electronic, festive\nChinese New Year, electronic, pop\nChinese New Year, electronic, video game\nChinese New Year, festive pop\nChinese New Year, festive pop, children's choir\nChinese New Year, festive pop, electronic\nChinese New Year, festive pop, synth pop\nChinese New Year, festive, children's choir\nChinese New Year, festive, choir\nChinese New Year, festive, electronic\nChinese New Year, festive, orchestral\nChinese New Year, festive, pop\nChinese New Year, festive, retro\nChinese New Year, festive, traditional\nChinese New Year, festive, traditional percussion\nChinese New Year, hip-hop, EDM\nChinese New Year, pop, electronic\nChinese New Year, pop, festive\nChinese New Year, pop, hip-hop\nChinese New Year, retro pop, festive\nChinese New Year, retro pop, synth\nChinese New Year, retro swing, big band\nChinese New Year, retro synth, children's choir\nChinese New Year, retro synth, dance\nChinese New Year, retro synth, dance pop\nChinese New Year, retro synth, festive pop\nChinese New Year, retro synth, pop\nChinese New Year, retro, chiptune\nChinese New Year, retro, festive\nChinese New Year, synth pop\nChinese New Year, synth pop, dance\nChinese New Year, synth pop, festive\nChinese New Year, synth pop, retro\nChinese New Year, synth pop, vintage\nChinese New Year, synth pop, vintage electronic\nChinese New Year, synth-pop, orchestral\nChinese New Year, synthwave, retro pop\nChinese New Year, traditional, festive\nChinese New Year, traditional, theatrical\nChinese New Year, upbeat, chiptune\nChinese New Year, upbeat, festive\nChinese New Year, upbeat, synth pop\nChinese New Year, vintage pop, theatrical\nChinese R&B\nChinese R&B lo-fi hip hop\nChinese R&B, hip-hop\nChinese R&B, hip-hop, funk\nChinese R&B, hip-hop, jazz\nChinese R&B, hip-hop, trap\nChinese R&B, lo-fi hip hop\nChinese R&B, lo-fi hip-hop\nChinese R&B, trap, hip-hop\nChinese acoustic ballad\nChinese acoustic folk\nChinese alternative rock\nChinese ambient\nChinese ambient pop\nChinese art song\nChinese art-pop\nChinese ballad\nChinese ballad, downtempo, ambient\nChinese ballad, lo-fi pop\nChinese ballad, pop-rock\nChinese blues-rock\nChinese boom-bap\nChinese boom-bap hip-hop\nChinese campus folk\nChinese children's music\nChinese children's pop\nChinese classical\nChinese classical crossover\nChinese classical fusion\nChinese dance\nChinese dance-pop\nChinese drill\nChinese drill trap\nChinese electronic\nChinese electronic dance\nChinese electronic fusion\nChinese electronic hardcore\nChinese electronic hip-hop\nChinese electronic pop\nChinese electronic rock\nChinese electronic rock, J-rock\nChinese electronic trap\nChinese electronic, J-core\nChinese electronic, J-core, hardstyle\nChinese festival\nChinese flute, ambient, cinematic\nChinese flute, ambient, jazz fusion\nChinese flute, festive, upbeat\nChinese folk\nChinese folk ambient\nChinese folk art song\nChinese folk ballad\nChinese folk ballad, cinematic rock\nChinese folk blues\nChinese folk blues-rock\nChinese folk cinematic\nChinese folk electronic\nChinese folk epic\nChinese folk funk\nChinese folk fusion\nChinese folk hip-hop\nChinese folk march\nChinese folk metal\nChinese folk opera\nChinese folk orchestral\nChinese folk pop\nChinese folk pop rock\nChinese folk pop-rock\nChinese folk punk\nChinese folk rock\nChinese folk trap\nChinese folk, Eurodance, trance\nChinese folk, Peking Opera, cinematic\nChinese folk, acoustic pop\nChinese folk, acoustic pop-rock\nChinese folk, ambient pop\nChinese folk, ambient, choral\nChinese folk, ambient, cinematic\nChinese folk, ambient, electronic\nChinese folk, ambient, flamenco\nChinese folk, ambient, lo-fi\nChinese folk, ambient, modern ethereal\nChinese folk, chiptune\nChinese folk, cinematic pop\nChinese folk, cinematic, ambient\nChinese folk, cinematic, classical\nChinese folk, cinematic, epic\nChinese folk, cinematic, opera\nChinese folk, cinematic, orchestral\nChinese folk, cinematic, patriotic\nChinese folk, electronic pop\nChinese folk, electronic, ambient\nChinese folk, electronic, cinematic\nChinese folk, electronic, world music\nChinese folk, epic, cinematic\nChinese folk, festive pop\nChinese folk, lo-fi, ambient\nChinese folk, new age, world music\nChinese folk, patriotic, cinematic\nChinese folk, pop-rock\nChinese folk, post-hardcore\nChinese folk, psychedelic rock\nChinese folk, theatrical folk\nChinese folk, theatrical, operatic\nChinese folk, theatrical, orchestral\nChinese folk, trap, ambient\nChinese folk, video game music\nChinese folk, video game, quirky\nChinese folk, video game, upbeat\nChinese folk, whimsical, narrative\nChinese folk-pop\nChinese folk-pop Eurodance\nChinese folk-pop chiptune\nChinese folk-pop cinematic\nChinese folk-pop cumbia\nChinese folk-pop disco-funk\nChinese folk-pop electronic\nChinese folk-pop funk-rock\nChinese folk-pop lo-fi hip-hop\nChinese folk-pop opera\nChinese folk-pop retro\nChinese folk-pop rock\nChinese folk-pop stadium rock\nChinese folk-pop world music\nChinese folk-pop, EDM, trance\nChinese folk-pop, big band jazz\nChinese folk-pop, cinematic ballad\nChinese folk-pop, city pop, jazz-funk\nChinese folk-pop, hard rock\nChinese folk-pop, hard rock, cinematic\nChinese folk-pop, pop-rock\nChinese folk-pop, power rock\nChinese folk-pop, stadium rock\nChinese folk-rap\nChinese folk-rock\nChinese folk-rock blues-rock\nChinese folk-rock surf rock\nChinese folk-rock, C-pop, hard rock\nChinese folk-rock, cinematic, nu-metal\nChinese folk-rock, stadium rock\nChinese fusion\nChinese fusion hip-hop\nChinese fusion pop\nChinese future bass\nChinese guzheng\nChinese hard dance\nChinese hard rock\nChinese hip hop\nChinese hip hop, lo-fi, cinematic\nChinese hip hop, trap, boom-bap\nChinese hip-hop\nChinese hip-hop G-funk\nChinese hip-hop R&B\nChinese hip-hop acoustic folk-pop\nChinese hip-hop chiptune\nChinese hip-hop funk\nChinese hip-hop lo-fi\nChinese hip-hop rock\nChinese hip-hop trap\nChinese hip-hop, EDM trap\nChinese hip-hop, R&B, city pop\nChinese hip-hop, chiptune\nChinese hip-hop, cinematic\nChinese hip-hop, cinematic trap\nChinese hip-hop, cinematic, trap\nChinese hip-hop, city-pop, lo-fi\nChinese hip-hop, electronic, cinematic\nChinese hip-hop, emotional synth\nChinese hip-hop, hardstyle\nChinese hip-hop, lo-fi, chiptune\nChinese hip-hop, synth-pop, city pop\nChinese hip-hop, traditional opera\nChinese hip-hop, trap\nChinese hip-hop, trap, traditional\nChinese hip-hop, trap, traditional fusion\nChinese hǎnmài dance\nChinese indie folk\nChinese indie folk-pop\nChinese indie folk-rock\nChinese indie pop\nChinese indie rock\nChinese indie-folk\nChinese indie-pop\nChinese instrumental\nChinese jazz\nChinese lounge\nChinese lullaby\nChinese metal\nChinese narrative rap\nChinese nursery rhyme\nChinese opera\nChinese opera hip-hop\nChinese opera trap\nChinese opera, electronic, cinematic\nChinese opera, folk-rock\nChinese opera, jazz fusion\nChinese opera, musical theater, retro synth\nChinese opera, pop, cinematic\nChinese opera, retro synth, folk\nChinese opera, trap\nChinese opera, trap, cinematic\nChinese opera, trap, fusion\nChinese orchestral\nChinese orchestral ballad\nChinese orchestral pop\nChinese patriotic pop\nChinese patriotic, retro synth, 80s pop\nChinese pop\nChinese pop ballad\nChinese pop ballad, pop-rock, J-rock\nChinese pop chiptune\nChinese pop folk\nChinese pop funk\nChinese pop funk disco\nChinese pop funk hip-hop\nChinese pop hip-hop\nChinese pop hip-hop funk\nChinese pop jazz\nChinese pop jazz swing\nChinese pop lo-fi hip hop\nChinese pop rap\nChinese pop retro\nChinese pop retro funk lo-fi hip-hop\nChinese pop retro funk lounge\nChinese pop retro-funk\nChinese pop retro-funk hip-hop\nChinese pop rock\nChinese pop, Eurodance, trance-pop\nChinese pop, anime soundtrack, video game music\nChinese pop, chiptune, retro\nChinese pop, cinematic, ambient\nChinese pop, dance-pop, retro\nChinese pop, dance-pop, synth-pop\nChinese pop, disco, theatrical\nChinese pop, electronic, theatrical\nChinese pop, electronic, whimsical\nChinese pop, jazz fusion\nChinese pop, reggae, theatrical\nChinese pop, retro funk, lo-fi hip-hop\nChinese pop, retro game, theatrical\nChinese pop, retro, synth-pop\nChinese pop, retro-funk, lo-fi hip-hop\nChinese pop, rock, synth-pop\nChinese pop, theatrical pop, pop-rock\nChinese pop-ballad\nChinese pop-folk\nChinese pop-rap\nChinese pop-rock\nChinese pop-rock lo-fi\nChinese pop-rock lo-fi hip-hop\nChinese power ballad\nChinese power metal\nChinese rap\nChinese rap chiptune\nChinese rap, Mandopop\nChinese rap, disco-funk\nChinese rap, lo-fi hip hop, emotional\nChinese rap, lo-fi hip-hop, melancholic\nChinese regional rap, Eurodance, dance-pop\nChinese revolutionary opera\nChinese rock\nChinese rock ballad\nChinese rock blues\nChinese rock funk\nChinese rock opera\nChinese rock, J-rock\nChinese rock, J-rock, anime soundtrack\nChinese rock, anime theme\nChinese rock, cinematic rock, wuxia metal\nChinese rock, electronic dance, synth rock\nChinese rock, electronic fusion\nChinese rock, electronic, festive\nChinese rock, heavy metal\nChinese rock, nu-metal, rap-rock\nChinese rock, power metal\nChinese rock, power metal, Mandopop\nChinese rock, power metal, cinematic\nChinese soul\nChinese storytelling rap\nChinese synth-pop, hardstyle\nChinese techno\nChinese theatrical\nChinese traditional\nChinese traditional ballad\nChinese traditional fusion\nChinese traditional pop\nChinese traditional, ambient, cinematic\nChinese traditional, instrumental, driving\nChinese trap\nChinese trap R&B\nChinese trap fusion\nChinese trap metal\nChinese trap, cloud rap\nChinese trap, hardstyle\nChinese trap, hardstyle, dubstep\nChinese trap, hardstyle, jazz lounge\nChinese-style EDM\nChinese-style a cappella\nChinese-style ballad\nChinese-style cinematic\nChinese-style electronic\nChinese-style epic\nChinese-style hip-hop\nChinese-style instrumental\nChinese-style orchestral pop\nChinese-style orchestral pop-rock\nChinese-style pop\nChinese-style pop-rock\nChinese-style rock\nChinese-style rock opera\nChinese-style romance\nChinese-style romantic duet\nChinese-style, ambient, duet\nChinese-style, educational, pop\nChinese-style, romantic, duet\nChinese-style, theatrical, video game\nChinese-style, tranquil, romantic\nChoro\nChoro MPB\nChoro Samba\nChoro Sertanejo\nChoro rock\nChoro samba\nChoro samba-rock\nChoro, Forró, Brazilian folk\nChoro, MPB\nChoro, Música Gaúcha\nChoro, Sertanejo de Raiz\nChristian\nChristian Banda\nChristian Bhangra\nChristian Bhangra-pop\nChristian C-pop\nChristian Christmas\nChristian Contemporary\nChristian Contemporary Music\nChristian Cumbia\nChristian EDM\nChristian EDM Bollywood\nChristian EDM K-pop\nChristian EDM Latin\nChristian EDM Latin pop\nChristian EDM Latin urban\nChristian EDM chiptune\nChristian EDM future bass\nChristian EDM progressive house\nChristian EDM-pop\nChristian Eurodance\nChristian J-pop\nChristian Kuthu\nChristian Latin\nChristian Latin Cumbia\nChristian Latin ballad\nChristian Latin cumbia\nChristian Latin dance\nChristian Latin dance-pop\nChristian Latin drill\nChristian Latin folk\nChristian Latin fusion\nChristian Latin hip-hop\nChristian Latin pop\nChristian Latin pop chiptune\nChristian Latin pop-rock\nChristian Latin rap\nChristian Latin rock\nChristian Latin trap\nChristian Latin urban\nChristian Mariachi\nChristian Norteño\nChristian R&B\nChristian R&B gospel\nChristian R&B neo-soul\nChristian R&B trap\nChristian R&B trap-soul\nChristian R&B, Latin pop, trap\nChristian R&B, Latin trap\nChristian R&B, early 2000s hip hop\nChristian R&B, hip-hop\nChristian R&B, hip-hop, contemporary\nChristian R&B, hip-hop, early 2000s\nChristian R&B, hip-hop, trap\nChristian R&B, new jack swing\nChristian R&B, trap-soul\nChristian Salsa\nChristian Sertanejo\nChristian alternative rock\nChristian ambient\nChristian anthem\nChristian anthem Latin\nChristian arena rock\nChristian bachata\nChristian ballad\nChristian ballad, Korean trot, synth pop\nChristian ballad, Latin, operatic\nChristian bhajan\nChristian brass band\nChristian carol\nChristian children's\nChristian children's Latin pop\nChristian children's folk\nChristian children's hymn\nChristian children's music\nChristian children's pop\nChristian children's rock\nChristian children's show tune\nChristian children's worship\nChristian children's, pop-rock, hymn\nChristian chillhop\nChristian chiptune\nChristian choral\nChristian conscious hip-hop\nChristian contemporary\nChristian contemporary gospel\nChristian contemporary pop\nChristian contemporary pop-rock\nChristian contemporary rock\nChristian contemporary worship\nChristian contemporary, Latin pop, cinematic\nChristian contemporary, indie folk-rock\nChristian contemporary, lo-fi hip-hop, Latin pop\nChristian contemporary, smooth jazz\nChristian corrido\nChristian corrido tumbado\nChristian country\nChristian country gospel\nChristian country rock\nChristian country-folk\nChristian country-gospel\nChristian country-pop\nChristian country-rock\nChristian crunk\nChristian cumbia\nChristian cumbia pop\nChristian cumbia rap\nChristian cumbia rock\nChristian cumbia-electronica\nChristian cumbia-pop\nChristian cumbia-reggaeton\nChristian dance\nChristian dance pop\nChristian dance-pop\nChristian dance-pop J-pop\nChristian dance-pop tropical house\nChristian dancehall\nChristian dancehall-pop\nChristian dembow\nChristian devotional\nChristian devotional pop\nChristian devotional, 80s South Indian film music\nChristian devotional, 90s South Indian film music, electronic\nChristian devotional, 90s South Indian film music, synth pop\nChristian devotional, Bollywood, anthemic\nChristian devotional, Bollywood, cinematic\nChristian devotional, Carnatic, electronic hip-hop\nChristian devotional, Indian classical\nChristian devotional, Indian classical, ambient\nChristian devotional, Indian classical, cinematic\nChristian devotional, Indian film music\nChristian devotional, Indian film music, 80s synth\nChristian devotional, Indian film music, electronic\nChristian devotional, Indian film music, mid-tempo\nChristian devotional, Indian film music, pop-rock\nChristian devotional, Indian film music, synth pop\nChristian devotional, Indian film music, upbeat\nChristian devotional, Indian film music, uplifting\nChristian devotional, Indian film music, vintage\nChristian devotional, Indian folk\nChristian devotional, Indian folk, Bollywood\nChristian devotional, Indian folk, cinematic\nChristian devotional, Indian folk, dance\nChristian devotional, Indian folk, upbeat\nChristian devotional, Indian fusion\nChristian devotional, Indian fusion, electronic worship\nChristian devotional, Indian fusion, synth pop\nChristian devotional, Indian fusion, upbeat worship\nChristian devotional, South Asian folk\nChristian devotional, South Asian folk, celebratory\nChristian devotional, South Asian folk, dance\nChristian devotional, South Asian folk, dholak\nChristian devotional, South Asian folk, electronic\nChristian devotional, South Asian folk, upbeat\nChristian devotional, South Asian folk, uplifting\nChristian devotional, South Asian fusion\nChristian devotional, South Asian, Middle Eastern\nChristian devotional, South Asian, upbeat\nChristian devotional, South Indian film music\nChristian devotional, South Indian film music, 80s synth\nChristian devotional, South Indian film music, 90s pop\nChristian devotional, South Indian film music, Bhangra\nChristian devotional, South Indian film music, chiptune\nChristian devotional, South Indian film music, dance\nChristian devotional, South Indian film music, dance pop\nChristian devotional, South Indian film music, devotional pop\nChristian devotional, South Indian film music, electronic\nChristian devotional, South Indian film music, energetic\nChristian devotional, South Indian film music, festive\nChristian devotional, South Indian film music, funk\nChristian devotional, South Indian film music, high-energy\nChristian devotional, South Indian film music, pop\nChristian devotional, South Indian film music, retro-pop\nChristian devotional, South Indian film music, synth pop\nChristian devotional, South Indian film music, upbeat\nChristian devotional, South Indian film music, uplifting\nChristian devotional, South Indian film music, vintage\nChristian devotional, South Indian film music, vintage organ\nChristian devotional, South Indian film music, vintage pop\nChristian devotional, South Indian folk\nChristian devotional, South Indian folk, Carnatic\nChristian devotional, South Indian folk, dance\nChristian devotional, South Indian folk, devotional pop\nChristian devotional, South Indian folk, electronic\nChristian devotional, South Indian folk, energetic\nChristian devotional, South Indian folk, festive\nChristian devotional, South Indian folk, folk-pop\nChristian devotional, South Indian folk, upbeat\nChristian devotional, South Indian, chiptune\nChristian devotional, South Indian, danceable\nChristian devotional, South Indian, synth worship\nChristian devotional, South Indian, upbeat\nChristian devotional, South Indian, uplifting\nChristian devotional, dance-pop, South Indian film music\nChristian devotional, electronic, Indian classical\nChristian devotional, retro Indian film, synth pop\nChristian devotional, retro MIDI, Tamil worship\nChristian devotional, synth-pop\nChristian disco-funk\nChristian disco-pop\nChristian drill\nChristian electronic\nChristian electronic dance\nChristian electronic pop\nChristian electronic rock\nChristian folk\nChristian folk Latin\nChristian folk ballad\nChristian folk chiptune\nChristian folk cumbia\nChristian folk pop\nChristian folk, Latin American\nChristian folk, cumbia, Latin\nChristian folk-country\nChristian folk-gospel\nChristian folk-pop\nChristian folk-rock\nChristian forró\nChristian funk\nChristian funk-pop\nChristian funk-rock\nChristian fusion\nChristian gospel\nChristian hard rock\nChristian hardstyle\nChristian hip-hop\nChristian hip-hop Afrobeat\nChristian hip-hop Afrobeats\nChristian hip-hop EDM\nChristian hip-hop G-funk\nChristian hip-hop Latin pop\nChristian hip-hop R&B\nChristian hip-hop acoustic pop\nChristian hip-hop chiptune\nChristian hip-hop chiptune trap\nChristian hip-hop dancehall\nChristian hip-hop emo-trap\nChristian hip-hop funk\nChristian hip-hop funk carioca\nChristian hip-hop funk soul\nChristian hip-hop funk-rock\nChristian hip-hop future bass\nChristian hip-hop gospel\nChristian hip-hop gospel rock\nChristian hip-hop lo-fi\nChristian hip-hop pop-rap\nChristian hip-hop pop-rock\nChristian hip-hop reggaeton\nChristian hip-hop rock\nChristian hip-hop soul\nChristian hip-hop trap\nChristian hip-hop, Afrobeats, Gospel\nChristian hip-hop, EDM trap\nChristian hip-hop, Latin trap\nChristian hip-hop, chiptune\nChristian hip-hop, cinematic pop-rock\nChristian hip-hop, cinematic trap, pop/R&B\nChristian hip-hop, rock, nu-metal\nChristian hip-hop, trap\nChristian hip-hop, trap, Latin\nChristian hip-hop, trap, Latin rap\nChristian hip-hop, trap, lo-fi\nChristian hip-hop, trap, multi-lingual\nChristian hip-hop, trap, synth-pop\nChristian hip-house\nChristian house\nChristian hymn\nChristian hymn Indian classical\nChristian hymn Indian film music\nChristian hymn Latin\nChristian hymn Latin folk\nChristian hymn big band\nChristian hymn chiptune\nChristian hymn, C-pop, cinematic\nChristian hymn, Indian film music\nChristian hymn, Latin big band, triumphal\nChristian hymn, Latin folk, mariachi\nChristian hymn, South Indian film music, cinematic\nChristian hymn, South Indian film music, devotional\nChristian hymn, South Indian, cinematic\nChristian hymn, chiptune, pop-rock\nChristian hymn, cinematic, Indian film music\nChristian hymn, lo-fi, vintage\nChristian hymn, mariachi, Latin folk\nChristian hymn, vintage South Indian film music\nChristian hymns\nChristian hyperpop\nChristian jazz\nChristian kuthu\nChristian liturgical\nChristian lullaby\nChristian mambo\nChristian march\nChristian marching band\nChristian mariachi\nChristian merengue\nChristian metal\nChristian metalcore\nChristian musical theater\nChristian narrative ballad\nChristian new jack swing\nChristian orchestral\nChristian polka\nChristian pop\nChristian pop Afrobeat\nChristian pop Afrobeats\nChristian pop Bollywood\nChristian pop EDM\nChristian pop Eurodance\nChristian pop Indian\nChristian pop Indian classical\nChristian pop Indian film music\nChristian pop J-pop\nChristian pop K-pop\nChristian pop Latin\nChristian pop R&B\nChristian pop R&B hip-hop\nChristian pop R&B trap\nChristian pop Tollywood\nChristian pop big band\nChristian pop bluegrass\nChristian pop chiptune\nChristian pop country\nChristian pop country-folk\nChristian pop folk\nChristian pop folk-pop\nChristian pop funk\nChristian pop funk R&B\nChristian pop funk disco\nChristian pop future bass\nChristian pop gospel\nChristian pop hip-hop\nChristian pop lo-fi hip-hop\nChristian pop neo-soul\nChristian pop neo-soul lo-fi hip-hop\nChristian pop polka\nChristian pop reggae\nChristian pop reggae world music\nChristian pop reggaeton\nChristian pop rock\nChristian pop schlager\nChristian pop smooth jazz\nChristian pop trap\nChristian pop tropical house\nChristian pop tropical house afrobeat\nChristian pop world music\nChristian pop worship\nChristian pop, 80s synth-pop\nChristian pop, 80s synth-pop, new jack swing\nChristian pop, Bhangra\nChristian pop, Bollywood\nChristian pop, Bollywood, dance\nChristian pop, Bollywood, electronic\nChristian pop, Brazilian funk carioca\nChristian pop, Brazilian pop, synth pop\nChristian pop, EDM\nChristian pop, EDM, Latin pop\nChristian pop, EDM, R&B\nChristian pop, EDM, dance pop\nChristian pop, EDM, dance-pop\nChristian pop, EDM, future bass\nChristian pop, EDM, hip-hop\nChristian pop, EDM, synth-pop\nChristian pop, EDM, trap\nChristian pop, Eastern European estrada\nChristian pop, Eurodance\nChristian pop, Indian film music\nChristian pop, Indian film music, cinematic\nChristian pop, Indian film music, contemporary\nChristian pop, Indian film music, pop-rock\nChristian pop, Indian pop\nChristian pop, Indonesian pop\nChristian pop, J-pop\nChristian pop, Latin cumbia\nChristian pop, Latin cumbia, synth pop\nChristian pop, Latin hip-hop\nChristian pop, Latin pop\nChristian pop, Latin pop, 80s pop\nChristian pop, Latin pop, EDM\nChristian pop, Latin pop, Romanian\nChristian pop, Latin pop, cumbia\nChristian pop, Latin pop, electronic\nChristian pop, Latin pop, retro\nChristian pop, Latin pop, upbeat\nChristian pop, Latin salsa\nChristian pop, R&B, hip-hop\nChristian pop, Romanian folk\nChristian pop, South Asian fusion\nChristian pop, South Asian pop\nChristian pop, South Indian film music\nChristian pop, South Indian film music, electronic\nChristian pop, South Indian film music, funk\nChristian pop, South Indian film music, retro-pop\nChristian pop, South Indian folk, upbeat\nChristian pop, South Indian pop\nChristian pop, South Indian, EDM\nChristian pop, South Indian, devotional\nChristian pop, Zouk, Caribbean\nChristian pop, chiptune\nChristian pop, dancehall, reggaeton\nChristian pop, funk, R&B\nChristian pop, funk, disco\nChristian pop, funk, gospel\nChristian pop, gospel, Latin\nChristian pop, gospel, South Indian\nChristian pop, gospel, smooth jazz\nChristian pop, hip-hop\nChristian pop, hip-hop, electronic\nChristian pop, hip-hop, nu-disco\nChristian pop, new jack swing\nChristian pop, new jack swing, funk\nChristian pop, pop-punk, Mandarin pop\nChristian pop, reggaeton, R&B\nChristian pop, retro South Indian film\nChristian pop, synth-pop\nChristian pop, synth-pop, 80s\nChristian pop, synth-pop, EDM\nChristian pop, trap, R&B\nChristian pop, trap, cinematic\nChristian pop, trap, pop ballad\nChristian pop, worldbeat, Latin pop\nChristian pop-EDM\nChristian pop-R&B\nChristian pop-dance\nChristian pop-folk\nChristian pop-funk\nChristian pop-gospel\nChristian pop-punk\nChristian pop-rap\nChristian pop-reggae\nChristian pop-rock\nChristian pop-rock Bollywood\nChristian pop-rock J-pop\nChristian pop-rock chiptune\nChristian pop-rock funk\nChristian pop-rock lo-fi\nChristian pop-rock reggae\nChristian pop-rock sertanejo\nChristian pop-rock, 80s funk, Latin funk\nChristian pop-rock, EDM\nChristian pop-rock, EDM, anthemic\nChristian pop-rock, Indian fusion\nChristian pop-rock, Latin gospel, cinematic\nChristian pop-rock, electronic dance\nChristian pop-trap\nChristian power ballad\nChristian power ballad, 80s synth-pop\nChristian power ballad, J-rock\nChristian power ballad, R&B gospel\nChristian power ballad, salsa-gospel, Latin rock\nChristian power metal\nChristian power rock\nChristian power-pop\nChristian power-pop rock\nChristian praise\nChristian praise chiptune\nChristian praise, Eastern European folk\nChristian praise, Latin pop\nChristian praise, Southeast Asian pop\nChristian praise, chiptune\nChristian praise, chiptune, retro\nChristian praise, folk-pop, estrada\nChristian praise, retro synth, electronic\nChristian praise, retro synth, folk pop\nChristian praise, retro synth, video game music\nChristian praise, retro, polka\nChristian praise, world music, soul\nChristian protest\nChristian punk rock\nChristian ranchera\nChristian rap\nChristian rap-rock\nChristian rap-rock, trap metal\nChristian reggae\nChristian reggae chiptune\nChristian reggae-pop\nChristian reggaeton\nChristian reggaeton Latin trap\nChristian regional Mexican\nChristian rock\nChristian rock Indian fusion\nChristian rock J-Rock\nChristian rock J-rock\nChristian rock Latin\nChristian rock chiptune\nChristian rock country\nChristian rock country crossover\nChristian rock country gospel\nChristian rock country-gospel\nChristian rock country-rock\nChristian rock electronicore\nChristian rock folk\nChristian rock funk\nChristian rock funk Latin\nChristian rock funk blues\nChristian rock funk blues-rock\nChristian rock funk fusion\nChristian rock funk hip-hop\nChristian rock funk salsa\nChristian rock funk-pop\nChristian rock funk-rock\nChristian rock gospel\nChristian rock heartland rock\nChristian rock opera\nChristian rock post-hardcore\nChristian rock post-rock\nChristian rock progressive trance\nChristian rock punk\nChristian rock ska-punk\nChristian rock surf rock\nChristian rock synth-pop\nChristian rock world music\nChristian rock, Americana, Southern rock\nChristian rock, Americana, country-gospel\nChristian rock, Celtic folk\nChristian rock, Celtic rock\nChristian rock, EDM\nChristian rock, EDM, anthemic\nChristian rock, Indian folk\nChristian rock, Indian pop\nChristian rock, J-rock\nChristian rock, J-rock, power metal\nChristian rock, Kuthu\nChristian rock, Latin rock\nChristian rock, Latin rock, cumbia\nChristian rock, Latin, theatrical\nChristian rock, boogie-woogie\nChristian rock, cinematic, Latin\nChristian rock, electronic dance music\nChristian rock, electronic dance, trance\nChristian rock, happy hardcore\nChristian rock, hardstyle\nChristian rock, heartland rock\nChristian rock, heavy metal\nChristian rock, hip-hop, ambient\nChristian rock, nu-metal, electronic\nChristian rock, post-rock, Latin ballad\nChristian rock, swing, vintage rock and roll\nChristian rock, symphonic metal\nChristian rock, synth-pop\nChristian rock, synth-pop, cinematic\nChristian rock, synth-rock, industrial\nChristian rock, trance\nChristian rock, worship, power ballad\nChristian rockabilly\nChristian salsa\nChristian show tune\nChristian ska\nChristian ska-pop\nChristian ska-punk\nChristian soft rock\nChristian soul\nChristian synth\nChristian synth pop\nChristian synth-pop\nChristian synth-rock\nChristian synthwave\nChristian tango\nChristian trance\nChristian trap\nChristian trap R&B\nChristian trap, R&B\nChristian trap-rock\nChristian world music\nChristian worship\nChristian worship J-rock\nChristian worship Latin\nChristian worship Latin folk\nChristian worship chillwave\nChristian worship chiptune\nChristian worship cumbia\nChristian worship dream pop\nChristian worship funk\nChristian worship indie rock\nChristian worship jazz\nChristian worship jazz pop-rock\nChristian worship lo-fi hip hop\nChristian worship pop-rock\nChristian worship rock\nChristian worship salsa\nChristian worship smooth jazz\nChristian worship synth-pop\nChristian worship world music\nChristian worship, 80s synth\nChristian worship, Bollywood film music\nChristian worship, Bollywood pop-rock\nChristian worship, Bollywood, Bhangra\nChristian worship, Bollywood, contemporary\nChristian worship, Brazilian folk, live\nChristian worship, Eurodance, Bollywood dance-pop\nChristian worship, Eurodance, Latin pop\nChristian worship, Eurodance, Trance\nChristian worship, Eurodance, trance\nChristian worship, European folk, orchestral\nChristian worship, Forró\nChristian worship, German Schlager\nChristian worship, Indian classical\nChristian worship, Indian classical fusion\nChristian worship, Indian classical, ambient\nChristian worship, Indian classical, cinematic\nChristian worship, Indian film music\nChristian worship, Indian film music, devotional\nChristian worship, Indian film music, electronic\nChristian worship, Indian film score, cinematic\nChristian worship, Indian folk\nChristian worship, Indian fusion\nChristian worship, Indian pop-rock\nChristian worship, Latin Cumbia\nChristian worship, Latin cumbia\nChristian worship, Latin cumbia, electronic\nChristian worship, Latin cumbia, live\nChristian worship, Latin cumbia, synth pop\nChristian worship, Latin cumbia, synth-pop\nChristian worship, Latin folk\nChristian worship, Latin folk, Balkan folk\nChristian worship, Latin jazz, smooth jazz\nChristian worship, Latin pop\nChristian worship, Latin pop, Eurodance\nChristian worship, Latin pop, cinematic\nChristian worship, Latin pop, cumbia\nChristian worship, Latin pop, folk\nChristian worship, Latin pop, synth pop\nChristian worship, Latin pop, trap\nChristian worship, Latin pop-rock\nChristian worship, Latin pop-rock, dance-pop\nChristian worship, Latin rock\nChristian worship, Latin, Bollywood\nChristian worship, Latin, Bossa Nova\nChristian worship, Latin, Brazilian\nChristian worship, Latin, South Indian\nChristian worship, Latin, acoustic\nChristian worship, Latin, anthemic\nChristian worship, Latin, ballad\nChristian worship, Latin, cinematic\nChristian worship, Latin, flamenco\nChristian worship, Latin, gospel\nChristian worship, Latin, orchestral\nChristian worship, Middle Eastern, Mediterranean\nChristian worship, Middle Eastern, inspirational\nChristian worship, Romanian folk\nChristian worship, South Asian folk\nChristian worship, South Indian film music, cinematic\nChristian worship, South Indian film music, dance pop\nChristian worship, South Indian film music, electronic\nChristian worship, South Indian folk-pop\nChristian worship, South Indian pop, funk\nChristian worship, South Indian, devotional\nChristian worship, South Indian, electronic\nChristian worship, ambient, Tamil devotional\nChristian worship, big band, Latin\nChristian worship, cinematic, 80s power ballad\nChristian worship, cinematic, C-pop\nChristian worship, cinematic, Indian fusion\nChristian worship, cinematic, ballad\nChristian worship, cinematic, hip-hop\nChristian worship, cinematic, pop-rock\nChristian worship, cinematic, world music\nChristian worship, classical crossover\nChristian worship, cumbia, Latin\nChristian worship, cumbia, Latin pop-rock\nChristian worship, electronic pop, cinematic\nChristian worship, electronic-pop, cinematic\nChristian worship, folk, Hindi devotional\nChristian worship, folk, ballad\nChristian worship, forró, sertanejo\nChristian worship, gospel pop\nChristian worship, pop-rock, Middle Eastern\nChristian worship, pop-rock, gospel\nChristian worship, pop-rock, hip-hop\nChristian worship, pop-rock, schlager\nChristian worship, retro Latin, synth pop\nChristian worship, retro chiptune\nChristian worship, retro synth\nChristian worship, smooth jazz\nChristian worship, soft rock\nChristian worship, synth-pop\nChristian worship, synth-pop, Latin pop\nChristian worship, synth-pop, chiptune\nChristian worship, synthwave\nChristian worship, trap, R&B\nChristian worship, trap, hip-hop\nChristian worship, world music\nChristian worship, world music fusion\nChristian worship, world music, uplifting\nChristian, Christmas, synth pop\nChristian, Indian film music, devotional\nChristian, Latin, cinematic\nChristian, acoustic, Christmas\nChristian, brass, vintage\nChristian, retro MIDI\nChristian, synthwave, choral\nChristmas\nChristmas R&B\nChristmas R&B lo-fi hip-hop\nChristmas R&B trap\nChristmas a cappella\nChristmas ambient\nChristmas anthem\nChristmas ballad\nChristmas ballad Latin\nChristmas ballad, Arabic pop, Latin salsa\nChristmas ballad, Eurodance\nChristmas ballad, Eurodance, Italo dance\nChristmas ballad, big band swing\nChristmas ballad, big band swing, rock and roll\nChristmas ballad, gospel, cinematic\nChristmas ballad, jazz, orchestral\nChristmas ballad, soul, R&B\nChristmas big band\nChristmas blues\nChristmas blues swing\nChristmas boogie-woogie\nChristmas carol\nChristmas carol world music\nChristmas carol, Romanian folk-pop\nChristmas carol, folk, choral\nChristmas carol, theatrical, comedic\nChristmas chanson\nChristmas chiptune\nChristmas choir\nChristmas choral\nChristmas classical\nChristmas country\nChristmas country-folk\nChristmas cumbia\nChristmas drill\nChristmas folk\nChristmas funk\nChristmas funk gospel\nChristmas funk soul\nChristmas gospel\nChristmas hip hop\nChristmas hip-hop\nChristmas hymn\nChristmas instrumental\nChristmas jazz\nChristmas jazz ballad\nChristmas jazz-pop\nChristmas lullaby\nChristmas mambo\nChristmas mashup\nChristmas music\nChristmas novelty\nChristmas novelty, Latin exotica\nChristmas novelty, ragtime, theatrical\nChristmas novelty, retro rock and roll\nChristmas nursery rhyme\nChristmas orchestral\nChristmas polka\nChristmas pop\nChristmas pop J-pop\nChristmas pop K-pop\nChristmas pop R&B\nChristmas pop R&B funk\nChristmas pop R&B hip-hop\nChristmas pop R&B soul\nChristmas pop Schlager\nChristmas pop country crossover\nChristmas pop folk\nChristmas pop funk\nChristmas pop funk disco\nChristmas pop funk gospel\nChristmas pop funk soul\nChristmas pop gospel\nChristmas pop hip-hop\nChristmas pop indie rock\nChristmas pop jazz\nChristmas pop jazz swing\nChristmas pop rap\nChristmas pop reggae\nChristmas pop reggaeton\nChristmas pop schlager\nChristmas pop soul\nChristmas pop trap\nChristmas pop world music\nChristmas pop, 60s rock, schlager\nChristmas pop, 80s R&B\nChristmas pop, 80s R&B, smooth jazz\nChristmas pop, 80s Schlager, synth pop\nChristmas pop, 90s K-pop\nChristmas pop, 90s K-pop, city pop\nChristmas pop, 90s R&B\nChristmas pop, C-pop, pop-rock\nChristmas pop, German folk\nChristmas pop, German schlager\nChristmas pop, J-pop\nChristmas pop, J-pop, musical theater\nChristmas pop, Latin Cumbia\nChristmas pop, Latin cumbia\nChristmas pop, Latin pop\nChristmas pop, Latin pop, 1960s pop\nChristmas pop, Latin pop, R&B\nChristmas pop, Latin pop, reggaeton\nChristmas pop, Latin salsa\nChristmas pop, Latin, Caribbean\nChristmas pop, R&B\nChristmas pop, R&B, city pop\nChristmas pop, R&B, dance-pop\nChristmas pop, R&B, early 2000s\nChristmas pop, R&B, funk\nChristmas pop, R&B, gospel\nChristmas pop, R&B, hip-hop\nChristmas pop, R&B, show tune\nChristmas pop, R&B, soul\nChristmas pop, R&B, trap\nChristmas pop, Romanian pop, 80s pop\nChristmas pop, Schlager\nChristmas pop, South Indian film music\nChristmas pop, Vietnamese pop\nChristmas pop, acoustic folk\nChristmas pop, big band\nChristmas pop, big band jazz\nChristmas pop, big band, swing\nChristmas pop, cabaret, European\nChristmas pop, chiptune\nChristmas pop, cumbia pop\nChristmas pop, deep house\nChristmas pop, early 2000s R&B\nChristmas pop, eclectic, comedic\nChristmas pop, funk, R&B\nChristmas pop, funk, disco\nChristmas pop, future bass\nChristmas pop, future bass, electronic\nChristmas pop, gospel, R&B\nChristmas pop, jazz, show tune\nChristmas pop, musical theater\nChristmas pop, new jack swing\nChristmas pop, pop-rock, J-rock\nChristmas pop, pop-rock, Vietnamese pop\nChristmas pop, reggaeton\nChristmas pop, retro funk, disco\nChristmas pop, retro soul, R&B\nChristmas pop, retro synth, chiptune\nChristmas pop, schlager\nChristmas pop, schlager, theatrical\nChristmas pop, soul, R&B\nChristmas pop, soul, disco\nChristmas pop, synth-pop, C-pop\nChristmas pop, worldbeat, dance-pop\nChristmas pop-R&B\nChristmas pop-country\nChristmas pop-folk\nChristmas pop-funk\nChristmas pop-gospel\nChristmas pop-rap\nChristmas pop-rock\nChristmas pop-rock, South Asian fusion\nChristmas pop-rock, electronic\nChristmas pop-soul\nChristmas power ballad\nChristmas punk rock\nChristmas ragtime\nChristmas rock\nChristmas rock alt-country\nChristmas rock and roll\nChristmas rockabilly\nChristmas salsa\nChristmas samba\nChristmas schlager\nChristmas show tune\nChristmas soul\nChristmas swing\nChristmas synth\nChristmas trap\nChristmas waltz\nChristmas worship\nChristmas, 1960s, gospel\nChristmas, Baroque, choral\nChristmas, C-pop, orchestral\nChristmas, Celtic, orchestral\nChristmas, Eurodance, a cappella\nChristmas, German folk\nChristmas, German folk, festive\nChristmas, Indian film music, pop-rock\nChristmas, Indian film music, upbeat\nChristmas, Indian fusion, electronic\nChristmas, Italian folk\nChristmas, Latin pop\nChristmas, Latin, Cumbia\nChristmas, Latin, Mariachi, Cumbia\nChristmas, Latin, forró\nChristmas, Malayalam, acoustic\nChristmas, Schlager\nChristmas, South Indian film music, upbeat\nChristmas, South Indian, electronic\nChristmas, Spanish, children's choir\nChristmas, Spanish, choral\nChristmas, Spanish, synth\nChristmas, Spanish, synth-pop\nChristmas, Swedish folk, orchestral\nChristmas, Vietnamese, synth\nChristmas, acoustic duet, Latin pop-rock\nChristmas, acoustic, ambient\nChristmas, acoustic, choral\nChristmas, acoustic, duet\nChristmas, ambient pop\nChristmas, ambient, Arabic pop\nChristmas, ambient, acoustic\nChristmas, ambient, choral\nChristmas, ambient, cinematic\nChristmas, ambient, gospel\nChristmas, ambient, lo-fi\nChristmas, ambient, synth pop\nChristmas, anthemic, synthpop\nChristmas, baroque pop, choral\nChristmas, boogie-woogie, choral\nChristmas, chamber pop\nChristmas, chanson, vintage\nChristmas, choir, orchestral\nChristmas, choir, pop\nChristmas, choral, German\nChristmas, choral, Latin\nChristmas, choral, Schlager\nChristmas, choral, Spanish\nChristmas, choral, acoustic\nChristmas, choral, ambient\nChristmas, choral, classical\nChristmas, choral, folk\nChristmas, choral, hymnal\nChristmas, choral, lounge-pop\nChristmas, choral, nostalgic\nChristmas, choral, orchestral\nChristmas, choral, pop\nChristmas, choral, pop-rock\nChristmas, choral, traditional Spanish\nChristmas, choral, video game\nChristmas, choral, vintage\nChristmas, cinematic, ambient\nChristmas, cinematic, baroque\nChristmas, cinematic, choir\nChristmas, cinematic, choral\nChristmas, cinematic, classical\nChristmas, cinematic, operatic\nChristmas, cinematic, orchestral\nChristmas, cinematic, spiritual\nChristmas, classical, ambient\nChristmas, classical, country gospel\nChristmas, classical, jazz\nChristmas, classical, orchestral\nChristmas, classical, sacred\nChristmas, classical, vocal duet\nChristmas, dark pop\nChristmas, dark pop, baroque pop\nChristmas, dream pop\nChristmas, electronic, choir\nChristmas, festive, Spanish\nChristmas, folk\nChristmas, folk, cinematic\nChristmas, folk, classical\nChristmas, folk, pop\nChristmas, folk, world music\nChristmas, gospel, orchestral\nChristmas, gospel, vintage\nChristmas, hardstyle, big room house\nChristmas, jazz, Romanian folk\nChristmas, lo-fi, Vocaloid\nChristmas, lo-fi, vocaloid\nChristmas, operatic, cinematic\nChristmas, operatic, synthwave\nChristmas, operatic, vintage\nChristmas, orchestral pop, easy-listening\nChristmas, orchestral, German\nChristmas, orchestral, cartoon\nChristmas, orchestral, choral\nChristmas, orchestral, cinematic\nChristmas, orchestral, classical\nChristmas, orchestral, folk\nChristmas, orchestral, lullaby\nChristmas, orchestral, music box\nChristmas, orchestral, pop\nChristmas, orchestral, show tune\nChristmas, orchestral, soulful\nChristmas, orchestral, theatrical\nChristmas, polka, synth-pop\nChristmas, pop\nChristmas, pop, Latin\nChristmas, pop, R&B\nChristmas, pop, folk\nChristmas, pop-rock, Indian film music\nChristmas, pop-rock, J-pop\nChristmas, ragtime, acoustic\nChristmas, ragtime, choir\nChristmas, ragtime, theatrical\nChristmas, retro synth, theatrical\nChristmas, retro, schlager\nChristmas, rock and roll, pop-punk\nChristmas, rockabilly\nChristmas, soft pop\nChristmas, soft pop, choral\nChristmas, soul, ambient\nChristmas, soul, traditional\nChristmas, soulful duet\nChristmas, synth orchestra\nChristmas, synth pop\nChristmas, synth pop, German folk\nChristmas, synth pop, German pop\nChristmas, synth pop, Italian\nChristmas, synth pop, ambient\nChristmas, synth pop, choral\nChristmas, synth pop, vocaloid\nChristmas, synth, instrumental\nChristmas, synthpop, cartoon\nChristmas, synthpop, cinematic\nChristmas, synthwave\nChristmas, synthwave, German folk\nChristmas, synthwave, Latin\nChristmas, synthwave, Romanian folk\nChristmas, synthwave, choral\nChristmas, synthwave, lo-fi\nChristmas, synthwave, orchestral\nChristmas, theatrical, brass band\nChristmas, theatrical, orchestral\nChristmas, theatrical, piano\nChristmas, theatrical, ragtime\nChristmas, theatrical, synth pop\nChristmas, traditional German\nChristmas, traditional German, choral\nChristmas, traditional Spanish, children's choir\nChristmas, vintage pop, crooner\nChristmas, whimsical, eerie\nCinematic\nCinematic Afro-Latin\nCinematic Ambient\nCinematic Arabic\nCinematic Arabic Folk\nCinematic Arabic Pop\nCinematic Arabic ballad\nCinematic Arabic devotional\nCinematic Arabic fusion\nCinematic Arabic hip-hop\nCinematic Arabic pop\nCinematic Ballad\nCinematic Bengali Ballad\nCinematic Bossa Nova\nCinematic Brazilian\nCinematic C-pop\nCinematic C-pop, Telugu hip-hop, spiritual ambient\nCinematic Chinese\nCinematic Chinese Ambient\nCinematic Chinese Ballad\nCinematic Chinese Fantasy\nCinematic Chinese Folk\nCinematic Chinese Opera\nCinematic Chinese Orchestral\nCinematic Chinese Traditional\nCinematic Chinese ballad\nCinematic Chinese folk\nCinematic Chinese fusion\nCinematic Chinese instrumental\nCinematic Chinese orchestral\nCinematic Cumbia\nCinematic Dizi\nCinematic EDM\nCinematic East Asian\nCinematic East Asian folk\nCinematic Folk\nCinematic Folk Fusion\nCinematic Greek\nCinematic Greek Folk\nCinematic Greek Laïko\nCinematic Guzheng\nCinematic Indian\nCinematic Indian Ballad\nCinematic Indian Classical\nCinematic Indian Devotional\nCinematic Indian Folk\nCinematic Indian Fusion\nCinematic Indian Pop\nCinematic Indian ballad\nCinematic Indian classical\nCinematic Indian film\nCinematic Indian film music\nCinematic Indian film score\nCinematic Indian folk\nCinematic Indian fusion\nCinematic Indian hip-hop\nCinematic Indian pop\nCinematic J-rock\nCinematic Japanese folk\nCinematic Javanese\nCinematic Kollywood\nCinematic MPB\nCinematic Malay Folk\nCinematic Malay Pop\nCinematic Malayalam\nCinematic Mawwal\nCinematic Middle Eastern\nCinematic Mongolian\nCinematic Māori pop\nCinematic Neapolitan\nCinematic Nepali\nCinematic Nepali film music\nCinematic Nez\nCinematic Orchestral, Enka, Kayōkyoku\nCinematic Oud\nCinematic Persian\nCinematic Pop\nCinematic Pop, Malay Traditional\nCinematic R&B\nCinematic Raï\nCinematic Samba\nCinematic South Asian\nCinematic South Indian\nCinematic Spanish\nCinematic Spanish ballad\nCinematic Sufi\nCinematic Tamil\nCinematic Tamil Pop\nCinematic Tamil ballad\nCinematic Tamil electronic\nCinematic Tamil film\nCinematic Tamil film music\nCinematic Tamil folk\nCinematic Tamil fusion\nCinematic Tamil hip hop\nCinematic Tamil pop\nCinematic Telugu\nCinematic Telugu Folk\nCinematic Telugu rock\nCinematic Thai pop\nCinematic Trap\nCinematic Turkish\nCinematic Turkish Folk\nCinematic Turkish Pop\nCinematic Turkish ballad\nCinematic Turkish folk\nCinematic V-Pop\nCinematic V-pop\nCinematic Vietnamese Ballad\nCinematic Vietnamese Bolero\nCinematic Vietnamese ballad\nCinematic Vietnamese ballad, EDM, trap\nCinematic Vietnamese pop\nCinematic World\nCinematic World Fusion\nCinematic Zouk\nCinematic ambient\nCinematic ballad\nCinematic ballad, Arabic fusion, Italian opera\nCinematic bossa nova\nCinematic devotional\nCinematic electronic\nCinematic flamenco\nCinematic folk\nCinematic folk fusion\nCinematic folk pop\nCinematic folk rock\nCinematic fusion\nCinematic guzheng\nCinematic hip hop\nCinematic hip-hop\nCinematic lo-fi\nCinematic ney\nCinematic orchestral, Canzone Italiana\nCinematic orchestral, Enka, traditional East Asian folk\nCinematic orchestral, Kayōkyoku, Enka\nCinematic oud\nCinematic piano, Brazilian samba-reggae\nCinematic pop\nCinematic pop, Axé\nCinematic pop, Latin pop, Malay traditional\nCinematic pop, Malay pop\nCinematic pop, South Asian folk, trap\nCinematic pop, South Indian folk\nCinematic pop, disco-funk, Indonesian ballad\nCinematic pop-rock\nCinematic rock\nCinematic rock, Malayalam trap\nCinematic salsa\nCinematic soul\nCinematic synth, Zouk, R&B\nCinematic trap\nCinematic world\nCinematic world fusion\nCinematic world music\nCinematic worship\nCinematic, Ambient, Ancient Style\nCinematic, Ambient, Traditional Chinese\nCinematic, Ancient Style\nCinematic, Azerbaijani, Microtonal\nCinematic, Erhu, Ambient\nCinematic, Middle Eastern, Ambient\nCinematic, Middle Eastern, Flamenco\nCinematic, Traditional East Asian, Ambient\nCinematic, Vietnamese ballad, New-age\nCircus Rock\nCircus music\nCity Pop\nCity Pop AOR\nCity Pop Afro-pop\nCity Pop Dangdut Koplo\nCity Pop J-funk\nCity Pop J-pop\nCity Pop Mandopop\nCity Pop R&B\nCity Pop funk\nCity Pop funk-rock\nCity Pop lounge jazz\nCity Pop neo-soul\nCity Pop nu-disco\nCity Pop orchestral\nCity Pop, AOR, Japanese ballad\nCity Pop, AOR, Japanese pop\nCity Pop, AOR, Kayōkyoku\nCity Pop, AOR, cinematic\nCity Pop, Brazilian Funk\nCity Pop, Cantopop, synthwave\nCity Pop, Eurobeat\nCity Pop, Eurobeat, 80s synth\nCity Pop, Eurobeat, 90s Mandopop\nCity Pop, Eurobeat, Filipino pop\nCity Pop, Eurobeat, House\nCity Pop, Eurobeat, J-pop\nCity Pop, Eurobeat, Mandopop\nCity Pop, Eurobeat, Synth-pop\nCity Pop, Funk\nCity Pop, Funk Fusion\nCity Pop, Funk, 80s\nCity Pop, Funk, J-Pop\nCity Pop, Funk, Kayōkyoku\nCity Pop, Funk, Synthwave\nCity Pop, Funk, Video Game Soundtrack\nCity Pop, J-Pop, Funk\nCity Pop, J-Pop, R&B\nCity Pop, J-Rock\nCity Pop, J-pop\nCity Pop, J-pop, anime\nCity Pop, J-pop, funk\nCity Pop, J-rock\nCity Pop, Japanese rock\nCity Pop, Kayōkyoku\nCity Pop, Kayōkyoku, Disco\nCity Pop, Kayōkyoku, J-pop\nCity Pop, Kayōkyoku, Japanese pop\nCity Pop, Kayōkyoku, Latin\nCity Pop, Kayōkyoku, big band\nCity Pop, Kayōkyoku, big band jazz\nCity Pop, Kayōkyoku, cinematic\nCity Pop, Kayōkyoku, disco-funk\nCity Pop, Kayōkyoku, jazz fusion\nCity Pop, Kayōkyoku, orchestral\nCity Pop, Latin jazz, Kayōkyoku\nCity Pop, Mandopop, Funk\nCity Pop, Mandopop, Latin disco\nCity Pop, Mandopop, disco\nCity Pop, Mandopop, disco-funk\nCity Pop, Neo-Soul, J-Pop\nCity Pop, New Jack Swing\nCity Pop, New Jack Swing, J-Pop\nCity Pop, New Jack Swing, K-pop\nCity Pop, R&B\nCity Pop, R&B, hip-hop\nCity Pop, Smooth Jazz\nCity Pop, Synth-pop\nCity Pop, arena rock\nCity Pop, cinematic orchestral\nCity Pop, cinematic, folk\nCity Pop, disco, Kayōkyoku\nCity Pop, disco-funk\nCity Pop, disco-funk, Kayōkyoku\nCity Pop, disco-funk, synth-pop\nCity Pop, funk\nCity Pop, funk, 80s\nCity Pop, funk, J-pop\nCity Pop, funk, Japanese\nCity Pop, funk, Kayōkyoku\nCity Pop, funk, nu-disco\nCity Pop, funk-rock\nCity Pop, funk-rock, 80s\nCity Pop, funk-rock, J-pop\nCity Pop, fusion jazz, synth-pop\nCity Pop, hard rock\nCity Pop, lo-fi hip hop\nCity Pop, modern R&B\nCity Pop, smooth jazz\nCity Pop, synth-funk\nCity Pop, synth-pop\nCity Pop, synth-pop, J-pop\nCity Pop, synth-pop, hip-hop\nColombian folk\nCongolese Gospel\nCongolese Rumba\nCongolese Rumba Soukous Afrobeats\nCongolese club\nCongolese disco-funk\nCongolese folk\nCongolese gospel\nCongolese pop\nCongolese pop, gospel, world music\nCongolese rumba\nCongolese rumba funk\nCongolese rumba funk rock\nCongolese rumba soukous\nCongolese salsa\nCongolese soukous\nContemporary Christian\nContemporary Christian Music\nContemporary Christian R&B\nCoupé-Décalé\nCuarteto\nCuarteto Bend\nCuarteto Popular\nCuarteto de Oyeo\nCuban Son\nCuban dembow\nCuban folk\nCuban hip-hop\nCuban jazz\nCuban mambo\nCuban protest\nCuban reggae\nCuban rumba\nCuban salsa\nCuban son\nCuban son bolero\nCuban son flamenco\nCuban son mambo\nCuban son montuno\nCuban son rumba\nCuban son salsa\nCuban son, Latin folk, Afro-Latin\nCuban son, Latin folk, cinematic\nCuban son, Latin pop\nCuban son, Latin pop, reggaeton\nCuban son, Latin rock\nCuban son, salsa\nCuban son-chá\nCuban son-guajira\nCuban son-malena\nCuban villancico\nCultural Ambient\nCultural Anthem\nCultural fusion\nCumbia\nCumbia 42\nCumbia 420\nCumbia 420, trap-cumbia\nCumbia 422\nCumbia 8-bit\nCumbia 808\nCumbia Andina\nCumbia Bamba\nCumbia Banda\nCumbia Barulera\nCumbia Bass\nCumbia Bellowera\nCumbia Bollywood\nCumbia Brega\nCumbia Cadiz\nCumbia Caleira\nCumbia Caleña\nCumbia Carioca\nCumbia Ch-fi\nCumbia Ch-hop\nCumbia Chacarera\nCumbia Chapina\nCumbia Chicha\nCumbia Cholers\nCumbia Choriza\nCumbia Christian\nCumbia Christmas\nCumbia Eurodance\nCumbia Flamenco\nCumbia Forró\nCumbia Gaita\nCumbia Gaucha\nCumbia Giddy\nCumbia Giddya\nCumbia Giddyina\nCumbia Gira\nCumbia Güira\nCumbia Hip Hop\nCumbia Jazzy\nCumbia Joropo\nCumbia Latin Pop\nCumbia Latin ballad\nCumbia Mariachi\nCumbia Murga\nCumbia Newa\nCumbia Norteña\nCumbia Norteña corrido\nCumbia Norteño\nCumbia Oyeña\nCumbia Peruvian\nCumbia Peruviana\nCumbia Pop\nCumbia Poulana\nCumbia R-fi\nCumbia RKT\nCumbia RKT trap\nCumbia RKT, Latin trap\nCumbia RKT, reggaeton\nCumbia Rabaña\nCumbia Raggamuffin\nCumbia Rama\nCumbia Ranchera\nCumbia Ranga\nCumbia Rap\nCumbia Rastafes\nCumbia Rebellada\nCumbia Reggaeton\nCumbia Rock\nCumbia Romántica\nCumbia Romántica, Cumbia, Tumpa-tumpa\nCumbia Romántica, Regional Mexican\nCumbia Romântico\nCumbia Rumba\nCumbia Salsa\nCumbia Sank Padera\nCumbia Santafesina\nCumbia Santo\nCumbia Sareña\nCumbia Sateña\nCumbia Screamed\nCumbia Sierreña\nCumbia Sinaloense\nCumbia Ska\nCumbia Soca\nCumbia Sonica\nCumbia Sonidera\nCumbia Sonora\nCumbia Tejana\nCumbia Tlax Banda\nCumbia Tlexical\nCumbia Trap\nCumbia Tumbado\nCumbia Tumbana\nCumbia Tumbao\nCumbia Tumpa\nCumbia Vallenata\nCumbia Vallenato\nCumbia Villera\nCumbia Villera lo-fi\nCumbia Vàng\nCumbia Western\nCumbia Zaj matureña\nCumbia Zajangera\nCumbia Zanfaera\nCumbia Zanquera\nCumbia Zuliana\nCumbia Zumba\nCumbia accelerada\nCumbia ballad\nCumbia banda\nCumbia barola\nCumbia barria\nCumbia chicha\nCumbia chiptune\nCumbia cinematic\nCumbia corrido\nCumbia de Vallenato\nCumbia devotional\nCumbia digital\nCumbia disco\nCumbia dramática\nCumbia electronic\nCumbia electrónica\nCumbia festiva\nCumbia flamenco\nCumbia folk\nCumbia folk-rock\nCumbia fusion\nCumbia gospel\nCumbia hardstyle\nCumbia hip-hop\nCumbia hip-hop fusion\nCumbia kids\nCumbia lo-fi\nCumbia loquera\nCumbia merengue\nCumbia merengue ballad\nCumbia metal\nCumbia nena\nCumbia nu-metal\nCumbia political\nCumbia pop\nCumbia pop-rock\nCumbia praise\nCumbia protest\nCumbia psychedelic\nCumbia ranchera\nCumbia reggaeton\nCumbia regional Mexican\nCumbia retro\nCumbia rock\nCumbia rock electronic\nCumbia rock, Cumbia Villera, Cumbia pop\nCumbia romantic\nCumbia salsa\nCumbia satirical\nCumbia sentimental\nCumbia sierreño\nCumbia sonidera\nCumbia sonidero\nCumbia synth-pop\nCumbia tambora\nCumbia tango\nCumbia techno\nCumbia trap\nCumbia tripa\nCumbia tropical\nCumbia tropical rock\nCumbia urbana\nCumbia villera\nCumbia violera\nCumbia worship\nCumbia, Andean folk\nCumbia, Andean, Latin fusion\nCumbia, Andean, Spanish folk\nCumbia, Andean, festive\nCumbia, Andean, folk\nCumbia, Arabic Mawwal\nCumbia, Arabic fusion\nCumbia, Banda\nCumbia, Baroque, Choral\nCumbia, Bolero\nCumbia, Bolero, Latin\nCumbia, Bossa Nova, East Asian ballad\nCumbia, Candombe\nCumbia, Cantopop\nCumbia, Celtic fusion\nCumbia, Chicha\nCumbia, Chicha, lo-fi\nCumbia, Christian worship\nCumbia, Christian, Latin\nCumbia, Christian, dance\nCumbia, Christmas, Latin\nCumbia, Christmas, Latin pop\nCumbia, Cumbia Pop\nCumbia, Eastern European, cinematic\nCumbia, European folk, Mandopop\nCumbia, Flamenco, Andalusian folk\nCumbia, Flamenco, Latin Rock\nCumbia, Forró\nCumbia, Forró, Latin dance\nCumbia, Forró, dance\nCumbia, Forró, electronic\nCumbia, Forró, folk rock\nCumbia, Forró, soul ballad\nCumbia, French pop\nCumbia, Guinguette\nCumbia, Halloween, upbeat\nCumbia, Huapango\nCumbia, Huapango, Latin folk\nCumbia, Huayno\nCumbia, Indian folk\nCumbia, Javanese, Latin fusion\nCumbia, Joropo\nCumbia, Latin Christian\nCumbia, Latin Christian, festive\nCumbia, Latin Christmas\nCumbia, Latin Christmas, big band\nCumbia, Latin Pop\nCumbia, Latin Pop, Pop-Rock\nCumbia, Latin ballad\nCumbia, Latin ballad, romantic pop\nCumbia, Latin dance\nCumbia, Latin dance, electronic\nCumbia, Latin dance-pop\nCumbia, Latin electronic\nCumbia, Latin folk\nCumbia, Latin pop\nCumbia, Latin pop, cinematic\nCumbia, Latin pop, electronic\nCumbia, Latin pop, reggaeton\nCumbia, Latin pop, retro\nCumbia, Latin pop-rock\nCumbia, Latin rock\nCumbia, Latin surf rock\nCumbia, Latin, Flamenco\nCumbia, Latin, cinematic\nCumbia, Latin, festive\nCumbia, Latin, operatic\nCumbia, Latin, synth\nCumbia, Latin, worship\nCumbia, Merengue\nCumbia, Merengue, Regional Mexican\nCumbia, Norteño\nCumbia, Pop Sunda\nCumbia, Pop-Ska, Reggaeton\nCumbia, Regional Mexican\nCumbia, Romanian folk, Latin\nCumbia, Salsa\nCumbia, Salsa Romántica\nCumbia, Salsa, psychedelic pop\nCumbia, Ska\nCumbia, Ska, Chinese Opera\nCumbia, Ska, traditional\nCumbia, Soukous, Afro-Latin\nCumbia, Tango\nCumbia, Vallenato\nCumbia, Vallenato, Latin ballad\nCumbia, Vallenato, Latin folk\nCumbia, Vallenato, ballad\nCumbia, Vallenato, pop-rock\nCumbia, Zouk\nCumbia, ambient\nCumbia, ambient, Indian classical\nCumbia, ambient, folkloric\nCumbia, ambient, indie rock\nCumbia, ballad\nCumbia, ballad, Latin pop\nCumbia, ballad, emotional\nCumbia, baroque pop, cinematic\nCumbia, blues, classical\nCumbia, children's music\nCumbia, chiptune\nCumbia, chiptune, Latin pop\nCumbia, chiptune, brass\nCumbia, chiptune, dance\nCumbia, chiptune, electronic\nCumbia, chiptune, lo-fi\nCumbia, chiptune, romantic\nCumbia, cinematic\nCumbia, cinematic, Latin\nCumbia, cinematic, Latin pop\nCumbia, cinematic, Spanish\nCumbia, cinematic, ambient\nCumbia, cinematic, ballad\nCumbia, cinematic, baroque\nCumbia, cinematic, baroque pop\nCumbia, cinematic, brass\nCumbia, cinematic, choral\nCumbia, cinematic, dreamy\nCumbia, cinematic, electronic\nCumbia, cinematic, emotional\nCumbia, cinematic, emotional ballad\nCumbia, cinematic, festive\nCumbia, cinematic, folk\nCumbia, cinematic, lo-fi\nCumbia, cinematic, melancholic\nCumbia, cinematic, novelty\nCumbia, cinematic, operatic\nCumbia, cinematic, orchestral\nCumbia, cinematic, reggaeton\nCumbia, cinematic, romantic\nCumbia, cinematic, synth\nCumbia, cinematic, theatrical\nCumbia, cinematic, trailer\nCumbia, cinematic, triumphant\nCumbia, dance, Hindi\nCumbia, dance, Latin pop\nCumbia, dance, bilingual\nCumbia, dance, electronic\nCumbia, dance-pop\nCumbia, devotional, South Indian Christian\nCumbia, devotional, electronic\nCumbia, dream pop\nCumbia, electronic\nCumbia, electronic, Latin\nCumbia, electronic, Latin dance\nCumbia, electronic, Latin pop\nCumbia, electronic, ambient\nCumbia, electronic, atmospheric\nCumbia, electronic, dance\nCumbia, electronic, melancholic\nCumbia, electronic, party\nCumbia, electronic, rock\nCumbia, electronic, romantic\nCumbia, electronic, sci-fi\nCumbia, electronic, spooky\nCumbia, electronic, synth\nCumbia, electronic, synthwave\nCumbia, electronic, upbeat\nCumbia, ethereal, acoustic\nCumbia, experimental, cinematic\nCumbia, festive\nCumbia, festive, Latin\nCumbia, festive, electronic\nCumbia, festive, holiday\nCumbia, festive, nostalgic\nCumbia, folk fusion\nCumbia, gospel\nCumbia, hardcore punk\nCumbia, hip-hop, Latin\nCumbia, hip-hop, electronic\nCumbia, hip-hop, salsa\nCumbia, indie-rock, cinematic\nCumbia, jazz fusion\nCumbia, lo-fi, Latin folk\nCumbia, lo-fi, cinematic\nCumbia, lo-fi, theatrical\nCumbia, melancholic, dance\nCumbia, melancholic, emotional\nCumbia, merengue\nCumbia, novelty, Filipino\nCumbia, novelty, synth pop\nCumbia, operatic, cinematic\nCumbia, orchestral, cinematic\nCumbia, piano ballad\nCumbia, pop-rock\nCumbia, psychedelic, theatrical\nCumbia, reggaeton\nCumbia, reggaeton, pop-ballad\nCumbia, regional Mexican\nCumbia, retro Latin pop\nCumbia, retro electronic\nCumbia, retro electronic, chiptune\nCumbia, retro pop\nCumbia, retro synth\nCumbia, retro, chiptune\nCumbia, retro, dance\nCumbia, retro, electronic\nCumbia, retro, surf-rock\nCumbia, retro, synth\nCumbia, rock\nCumbia, synth pop\nCumbia, synth, 8-bit\nCumbia, synth-pop\nCumbia, synthwave\nCumbia, synthwave, 8-bit\nCumbia, synthwave, baroque pop\nCumbia, synthwave, chiptune\nCumbia, tango\nCumbia, tango, cinematic\nCumbia, theatrical pop\nCumbia, theatrical rock\nCumbia, tropical, upbeat\nCumbia, upbeat, melancholic\nCumbia, vintage pop\nCumbia-pop\nCumbia-rock\nCumbia-ska fusion\nCumbia-techno\nCumbiaconstructa\nCzech Christian hymn\nCzech R&B\nCzech R&B trap-pop\nCzech R&B, dance-pop\nCzech bluegrass\nCzech blues\nCzech blues-folk\nCzech brass band\nCzech cabaret\nCzech cabaret, polka\nCzech chanson\nCzech children's music\nCzech children's music, big band, theatrical\nCzech choral\nCzech country-folk\nCzech country-rock\nCzech country-western\nCzech drill\nCzech folk\nCzech folk blues\nCzech folk country\nCzech folk flamenco\nCzech folk polka\nCzech folk rock\nCzech folk swing\nCzech folk, Balkan jazz\nCzech folk, Latin, mariachi\nCzech folk, Western, folk rock\nCzech folk, bluegrass\nCzech folk, bluegrass, country\nCzech folk, bluegrass, country-western\nCzech folk, cabaret, polka\nCzech folk, cabaret, theatrical\nCzech folk, country\nCzech folk, country, western\nCzech folk, flamenco, Latin\nCzech folk, flamenco, spoken word\nCzech folk, folk-punk\nCzech folk, gypsy jazz\nCzech folk, klezmer, folk rock\nCzech folk, neo-classical, Polish folk\nCzech folk, novelty, chiptune\nCzech folk, polka\nCzech folk, polka, country\nCzech folk, polka, electronic\nCzech folk, polka, pub rock\nCzech folk-country\nCzech folk-jazz\nCzech folk-polka\nCzech folk-pop\nCzech folk-rock\nCzech funk-rock\nCzech grime\nCzech hip-hop\nCzech hip-hop G-funk\nCzech hip-hop chiptune\nCzech hip-hop pop\nCzech hip-hop trap\nCzech hip-hop, Latin dance\nCzech hip-hop, UK garage, 2-step\nCzech hip-hop, new jack swing\nCzech hip-hop, reggaeton, hardstyle\nCzech hip-hop, synth-pop, deep house\nCzech hip-hop, trap\nCzech house\nCzech house-rap\nCzech indie rock\nCzech lullaby\nCzech march\nCzech new wave\nCzech polka\nCzech polka chiptune\nCzech polka-pop\nCzech pop\nCzech pop ballad\nCzech pop tango\nCzech pop trap\nCzech pop, Balkan brass\nCzech pop, EDM\nCzech pop, Eurodance\nCzech pop, European chanson\nCzech pop, Latin dance, modern pop\nCzech pop, R&B, trap\nCzech pop, big band, theatrical\nCzech pop, cabaret, polka\nCzech pop, chanson, swing\nCzech pop, chiptune\nCzech pop, disco, Eurodance\nCzech pop, exotica, Latin pop\nCzech pop, funk, R&B\nCzech pop, future bass\nCzech pop, hip-hop, electronic\nCzech pop, new wave\nCzech pop, polka\nCzech pop, polka, marching band\nCzech pop, reggaeton, Latin pop\nCzech pop, retro schlager\nCzech pop, retro, festive\nCzech pop, rock\nCzech pop, schlager\nCzech pop, swing, big band\nCzech pop, trap\nCzech pop-R&B\nCzech pop-dance\nCzech pop-funk\nCzech pop-rap\nCzech pop-rock\nCzech pop-rock cabaret\nCzech pop-rock country-rock\nCzech punk rock\nCzech reggae\nCzech rock\nCzech rock 'n' roll\nCzech rock and roll\nCzech rock, boogie-woogie, rockabilly\nCzech rock, new wave\nCzech rock, pop-punk\nCzech rock, punk, ambient\nCzech rock, surf rock, rockabilly\nCzech schlager\nCzech swing\nCzech tango\nCzech trap\nCzech trap, hyperpop, chiptune\nDabke\nDabke electronic\nDabke pop\nDabke, Arabic Mawwal, electronic\nDangdut\nDangdut Cumbia\nDangdut Funkot\nDangdut Koplo\nDangdut Koplo Balkan fusion\nDangdut Koplo City Pop\nDangdut Koplo Funkot\nDangdut Koplo Pop Melayu\nDangdut Koplo alternative rock\nDangdut Koplo chiptune\nDangdut Koplo chiptune rock\nDangdut Koplo cinematic\nDangdut Koplo disco rock\nDangdut Koplo electronic\nDangdut Koplo electronic pop hip-hop\nDangdut Koplo electronic rock\nDangdut Koplo funkot\nDangdut Koplo hip-hop\nDangdut Koplo jazz fusion\nDangdut Koplo metal\nDangdut Koplo pop\nDangdut Koplo pop-rock\nDangdut Koplo pop-rock metalcore\nDangdut Koplo power metal\nDangdut Koplo progressive rock chiptune\nDangdut Koplo psychedelic rock\nDangdut Koplo punk rock\nDangdut Koplo rock\nDangdut Koplo rock electronic\nDangdut Koplo rock fusion\nDangdut Koplo ska-punk\nDangdut Koplo surf rock\nDangdut Koplo, Arabic Pop, Cinematic\nDangdut Koplo, City Pop\nDangdut Koplo, EDM, pop\nDangdut Koplo, Eurodance\nDangdut Koplo, Eurodance, pop\nDangdut Koplo, Funkot, Indonesian pop\nDangdut Koplo, Funkot, Javanese ballad\nDangdut Koplo, Funkot, cinematic\nDangdut Koplo, Funkot, cinematic ballad\nDangdut Koplo, Funkot, cinematic pop\nDangdut Koplo, Funkot, electronic\nDangdut Koplo, Funkot, pop-ballad\nDangdut Koplo, Indian classical, electronic\nDangdut Koplo, Japanese rock\nDangdut Koplo, Javanese, rock\nDangdut Koplo, Malay pop, cinematic\nDangdut Koplo, Pop Melayu\nDangdut Koplo, children's music\nDangdut Koplo, chiptune\nDangdut Koplo, chiptune, Malay pop\nDangdut Koplo, chiptune, hyperpop\nDangdut Koplo, chiptune, pop\nDangdut Koplo, cinematic pop, Javanese vocal\nDangdut Koplo, cinematic pop, Malay pop\nDangdut Koplo, cinematic, Malay traditional\nDangdut Koplo, cinematic, electronic\nDangdut Koplo, cinematic, fantasy\nDangdut Koplo, cinematic, pop\nDangdut Koplo, electronic dance\nDangdut Koplo, electronic pop, hip-hop\nDangdut Koplo, electronic, rock\nDangdut Koplo, gamelan, electronic\nDangdut Koplo, happy hardcore\nDangdut Koplo, hard rock\nDangdut Koplo, hard rock, metal\nDangdut Koplo, heavy metal\nDangdut Koplo, indie rock, traditional Javanese\nDangdut Koplo, pop, R&B\nDangdut Koplo, pop, cinematic\nDangdut Koplo, pop-rock\nDangdut Koplo, pop-rock, rock\nDangdut Koplo, psychedelic rock\nDangdut Koplo, psychedelic rock, electronic\nDangdut Koplo, reggae pop\nDangdut Koplo, rock, electronic\nDangdut Koplo, synth-pop, city pop\nDangdut Melayu\nDangdut Pop\nDangdut Pop Melayu\nDangdut Pop Sunda\nDangdut Reggae\nDangdut Salsa\nDangdut ballad\nDangdut cinematic\nDangdut fusion\nDangdut koplo\nDangdut orchestral\nDangdut pop\nDangdut pop-rock\nDangdut reggae\nDangdut rock\nDangdut, City Pop\nDangdut, Indonesian pop, Middle Eastern\nDangdut, Indonesian pop, Middle Eastern fusion\nDangdut, Islamic devotional\nDangdut, Latin pop\nDangdut, Latin pop, vintage Indonesian pop\nDangdut, Melayu\nDangdut, Middle Eastern pop\nDangdut, Middle Eastern pop, vintage Indonesian pop\nDangdut, Pop Melayu\nDangdut, Pop Sunda\nDangdut, Pop Sunda, 80s pop\nDangdut, cinematic pop\nDangdut, pop ballad\nDangdut, vintage Indonesian pop\nDanish Christmas\nDanish Christmas novelty\nDanish Christmas pop\nDanish R&B\nDanish R&B trap\nDanish R&B, Latin pop\nDanish R&B, early 2000s hip-hop\nDanish R&B, hip-hop\nDanish R&B, new jack swing\nDanish R&B, trap, lo-fi\nDanish Schlager\nDanish ballad\nDanish blues-folk\nDanish cabaret\nDanish chanson\nDanish club\nDanish club house\nDanish club-pop\nDanish club-rap\nDanish comedy\nDanish country-folk\nDanish country-pop\nDanish country-rock\nDanish drill\nDanish drill afro-swing\nDanish drill trap\nDanish folk\nDanish folk jazz\nDanish folk, Latin, polka\nDanish folk, Latin, world music\nDanish folk, country, ragtime\nDanish folk, country, western\nDanish folk, gypsy jazz\nDanish folk, polka, schlager\nDanish folk, polka, sea shanty\nDanish folk, rockabilly, country\nDanish folk, sea shanty, country\nDanish folk, sea shanty, polka\nDanish folk-country\nDanish folk-pop\nDanish folk-rock\nDanish folk-rock funk-rock\nDanish hip-hop\nDanish hip-hop G-funk\nDanish hip-hop chiptune\nDanish hip-hop funk\nDanish hip-hop trap\nDanish hip-hop, G-funk\nDanish hip-hop, Latin trap\nDanish hip-hop, Melbourne bounce\nDanish hip-hop, hardstyle, EDM\nDanish hip-hop, reggaeton, Latin pop\nDanish hip-hop, trap\nDanish hip-hop, trap, R&B\nDanish indie rock\nDanish novelty\nDanish party-rap\nDanish polka\nDanish pop\nDanish pop 80s\nDanish pop Afro-Cuban\nDanish pop R&B\nDanish pop reggaeton\nDanish pop, 80s schlager\nDanish pop, Bossa Nova\nDanish pop, Latin cumbia\nDanish pop, Latin pop\nDanish pop, Latin pop, Christmas\nDanish pop, Latin pop, reggaeton\nDanish pop, Latin pop, soca\nDanish pop, Latin pop, tropical pop\nDanish pop, Latin pop, world music\nDanish pop, R&B, dance-pop\nDanish pop, R&B, festive\nDanish pop, big band, ska\nDanish pop, bossa nova, light jazz\nDanish pop, cabaret pop\nDanish pop, cabaret, vintage\nDanish pop, cumbia, schlager\nDanish pop, disco-funk\nDanish pop, folk-rock\nDanish pop, funk, hip-hop\nDanish pop, gospel, uplifting\nDanish pop, musical theatre, pop-rock\nDanish pop, reggae, ska\nDanish pop, reggaeton\nDanish pop, reggaeton, dancehall\nDanish pop, schlager\nDanish pop, schlager, polka\nDanish pop, show tune, big band\nDanish pop, ska, upbeat\nDanish pop, swing jazz\nDanish pop, trap, atmospheric\nDanish pop, trap, electronic\nDanish pop, tropical, Latin\nDanish pop-R&B\nDanish pop-R&B tropical house\nDanish pop-dance\nDanish pop-dance future bass\nDanish pop-funk\nDanish pop-rap\nDanish pop-rap funk\nDanish pop-rap, progressive house\nDanish pop-reggae\nDanish pop-reggaeton\nDanish pop-rock\nDanish pop-rock 80s\nDanish pop-rock cabaret\nDanish pop-rock ska\nDanish pop-rock, 80s new wave\nDanish pop-schlager\nDanish pop-soul\nDanish pop-trap\nDanish rock\nDanish rock 'n' roll\nDanish rock and roll\nDanish rock cabaret\nDanish rock, country rock, rockabilly\nDanish rock, country-rock\nDanish rock, new wave\nDanish rock, rockabilly, country rock\nDanish rock, rockabilly, theatrical rock\nDanish rock, schlager\nDanish schlager\nDanish schlager, lounge jazz\nDanish schlager, tropical dance-pop\nDanish schlager-pop\nDanish schlager-rock\nDanish singer-songwriter\nDanish summer pop\nDanish swing\nDanish tango\nDanish trap\nDanish trap, R&B\nDanish trap, lo-fi, melodic hip hop\nDanish trap, psychedelic R&B\nDanish trap-pop\nDansband\nDansband country-rock\nDansband rockabilly\nDansband schlager\nDansband, Schlager-rock\nDansktop\nDansktop Schlager\nDansktop country-rock\nDansktop schlager\nDansktop schlager-rock\nDansktop, Schlager\nDansktop, Schlager, country-rock\nDansktop, schlager\nDansktop, schlager, country-rock\nDansktop, schlager-pop\nDansktop, schlager-rock\nDansktop-rock\nDelta blues\nDesi DJ\nDesi DJ remix\nDesi EDM\nDesi Hip Hop\nDesi Hip Hop Bhangra\nDesi Hip Hop Latin Pop\nDesi Hip Hop Latin fusion\nDesi Hip Hop Neo-Soul\nDesi Hip Hop Trap\nDesi Hip Hop chiptune\nDesi Hip Hop lo-fi boom-bap\nDesi Hip Hop nu-metal\nDesi Hip Hop trap\nDesi Hip Hop, Latin Acoustic\nDesi Hip Hop, electronic trap\nDesi Hip Hop, hard trap\nDesi Hip Hop, trap\nDesi Hip-Hop\nDesi House\nDesi Pop\nDesi Pop R&B\nDesi Pop R&B lo-fi hip-hop\nDesi Pop hip-hop\nDesi Pop trap\nDesi Pop, Hip Hop\nDesi Pop, electronic, trap\nDesi Pop, trap, electronic\nDesi R&B\nDesi Trap\nDesi dance\nDesi dance pop\nDesi dance-pop\nDesi dance-pop moombahton\nDesi drill\nDesi drill trap\nDesi electronic\nDesi fusion hip-hop\nDesi hard dance\nDesi hip hop\nDesi hip-hop\nDesi hip-hop Bhangra\nDesi hip-hop Latin acoustic\nDesi hip-hop chiptune\nDesi hip-hop chiptune trap\nDesi hip-hop hardstyle\nDesi hip-hop lo-fi\nDesi hip-hop moombahton\nDesi hip-hop pop\nDesi hip-hop rap-rock\nDesi hip-hop reggaeton\nDesi hip-hop trap\nDesi hip-hop trap drill\nDesi hip-hop trap-pop\nDesi hip-hop, Bhangra pop\nDesi hip-hop, Bollywood dance\nDesi hip-hop, Bollywood dance, moombahton\nDesi hip-hop, Bollywood pop\nDesi hip-hop, EDM\nDesi hip-hop, EDM trap\nDesi hip-hop, EDM, hardstyle\nDesi hip-hop, chiptune trap\nDesi hip-hop, chiptune, electronic\nDesi hip-hop, electronic dance\nDesi hip-hop, electronic dance, Indian folk\nDesi hip-hop, electronic dance, fusion\nDesi hip-hop, electronic dance, trap\nDesi hip-hop, hard trap\nDesi hip-hop, hard trap, hardstyle\nDesi hip-hop, hardstyle\nDesi hip-hop, hardstyle, EDM\nDesi hip-hop, hardstyle, trap\nDesi hip-hop, lo-fi boom-bap\nDesi house\nDesi party\nDesi phonk\nDesi pop\nDesi pop EDM\nDesi pop R&B\nDesi pop UK garage\nDesi pop chiptune\nDesi pop dancehall\nDesi pop hip-hop\nDesi pop moombahton\nDesi pop reggaeton\nDesi pop trap\nDesi pop, Bhangra\nDesi pop, Bhangra, electronic\nDesi pop, Bhangra, trap\nDesi pop, EDM\nDesi pop, EDM trap\nDesi pop, EDM, trap\nDesi pop, EDM-trap\nDesi pop, Eurodance, 90s dance-pop\nDesi pop, R&B, lo-fi hip hop\nDesi pop, club, reggaeton\nDesi pop, dancehall, electronic\nDesi pop, dancehall, reggaeton\nDesi pop, electronic dance\nDesi pop, electronic dance, Bollywood\nDesi pop, hip-hop\nDesi pop, hip-hop, chiptune\nDesi pop, hip-hop, trap\nDesi pop, hyperpop\nDesi pop, moombahton\nDesi pop, trap, EDM\nDesi pop, trap, R&B\nDesi pop, trap, hip-hop\nDesi pop, trap, lo-fi\nDesi pop-rap\nDesi trap\nDesi-pop\nDesi-pop Bhangra\nDesi-pop chiptune\nDetroit Trap\nDetroit hip-hop\nDetroit rap\nDetroit trap\nDeutsch drill\nDeutschpop\nDeutschpop cinematic ballad\nDeutschpunk\nDeutschpunk Oi!\nDeutschpunk ska-punk\nDeutschrap\nDeutschrap Latin\nDeutschrap dark pop\nDeutschrap melodic trap\nDeutschrap trap\nDeutschrap, Eurodance, tropical house\nDeutschrap, Turkish saz, hip-hop\nDeutschrap, boom-bap, cinematic hip-hop\nDeutschrap, chiptune, Eurodance\nDeutschrap, chiptune, synthwave\nDeutschrap, cloud rap\nDeutschrap, cloud rap, lo-fi hip hop\nDeutschrap, cloud rap, synth pop\nDeutschrap, dubstep, trap\nDeutschrap, gangsta rap\nDeutschrap, melodic trap, chiptune\nDeutschrap, reggaeton, dancehall\nDeutschrap, synthwave, chiptune\nDeutschrap, techno, EBM\nDeutschrap, trap, Middle Eastern fusion\nDeutschrap, trap, Middle Eastern synth\nDeutschrap, trap, ambient\nDeutschrap, trap, chiptune\nDeutschrap, trap, cinematic\nDeutschrap, trap, dark ambient\nDeutschrap, trap, drill\nDeutschrap, trap, electronic\nDeutschrap, trap, gangsta rap\nDeutschrap, trap, lo-fi\nDeutschrap, trap, microtonal\nDeutschrap, trap, retro synth\nDeutschrap, trap, world fusion\nDeutschrapentik\nDeutschrock\nDeutschrock big band swing\nDeutschrock blues-rock\nDeutschrock boogie-woogie\nDeutschrock country-rock\nDeutschrock indie rock\nDeutschrock post-punk\nDeutschrock pub rock\nDeutschrock punk\nDeutschrock punk garage rock\nDeutschrock punk rock\nDeutschrock rockabilly\nDeutschrock rockabilly boogie-woogie\nDeutschrock rockabilly country\nDeutschrock rockabilly country rock\nDeutschrock rockabilly country-rock\nDeutschrock rockabilly surf rock\nDeutschrock ska\nDeutschrock ska-punk\nDeutschrock surf rock\nDeutschrock, Neue Deutsche Welle\nDirty South hip-hop\nDisco Polo\nDixieland\nDixieland jazz\nDixieland jazz ragtime\nDixieland novelty\nDixieland ragtime\nDixieland swing\nDoo-wop\nDutch Christmas\nDutch Christmas ballad\nDutch Christmas march\nDutch Christmas novelty\nDutch Christmas pop\nDutch Christmas, 80s synth, levenslied\nDutch House\nDutch R&B\nDutch R&B lo-fi hip-hop\nDutch R&B trap\nDutch R&B trap-soul\nDutch R&B, Afrobeats\nDutch R&B, boom-bap\nDutch R&B, hip-hop\nDutch R&B, hip-hop, early 2000s\nDutch R&B, hip-hop, funk\nDutch R&B, hip-hop, trap\nDutch R&B, trap\nDutch R&B, trap, hip-hop\nDutch R&B, trap, vaporwave\nDutch R&B, trap-soul, drill\nDutch Schlager\nDutch Schlager Eurodance\nDutch Schlager Europop\nDutch Schlager, Euro-pop\nDutch Schlager, Eurodance\nDutch Schlager, country-rock\nDutch Schlager, pop-rock\nDutch Trap\nDutch ballad\nDutch beat music\nDutch cabaret\nDutch carnaval\nDutch carnaval, Schlager, Euro-pop\nDutch carnaval, schlager\nDutch carnaval, schlager, oompah\nDutch carnaval, schlager, theatrical pop\nDutch carnival\nDutch carnival pop\nDutch carnival, Caribbean, samba\nDutch chanson\nDutch chanson bossa nova\nDutch chanson exotica lounge\nDutch chanson jazz blues\nDutch chanson tango\nDutch chanson, Dixieland, early swing\nDutch chanson, Latin jazz, bossa nova\nDutch chanson, Latin, theatrical\nDutch chanson, Latin, vintage\nDutch chanson, Parisian cabaret, theatrical\nDutch chanson, cabaret, theatrical\nDutch chanson, flamenco, world music\nDutch children's music\nDutch children's music funk disco\nDutch children's party\nDutch children's pop\nDutch club\nDutch club rap\nDutch club-rap\nDutch country\nDutch country-pop\nDutch country-rock\nDutch cumbia\nDutch dance-pop\nDutch dancehall\nDutch dancehall afrobeats\nDutch disco, schlager\nDutch disco-funk\nDutch disco-pop\nDutch drill\nDutch drill hardstyle\nDutch drill trap\nDutch drill, cinematic synth\nDutch drill, dancehall\nDutch drill, hyperpop\nDutch drill, reggaeton, ambient\nDutch drill, trap\nDutch drill, trap, R&B\nDutch drill, trap, rage\nDutch feest\nDutch folk\nDutch folk Latin\nDutch folk polka\nDutch folk, Celtic, polka\nDutch folk, Schlager\nDutch folk, Schlager, carnival\nDutch folk, big band\nDutch folk, boogie-woogie\nDutch folk, gypsy jazz\nDutch folk, gypsy jazz, theatrical\nDutch folk, orchestral, musical theatre\nDutch folk, polka\nDutch folk, polka, carnival\nDutch folk-party\nDutch folk-pop\nDutch folk-pop schlager\nDutch folk-pop, happy hardcore, gabber\nDutch folk-pop, hardstyle, gabber\nDutch folk-rock\nDutch folk-swing\nDutch football anthem\nDutch football chant\nDutch funk\nDutch funk-pop\nDutch funk-rap\nDutch gangsta rap\nDutch garage rock\nDutch hardcore hip-hop\nDutch hip hop\nDutch hip-hop\nDutch hip-hop Afro-Caribbean\nDutch hip-hop G-funk\nDutch hip-hop chiptune\nDutch hip-hop chiptune trap\nDutch hip-hop dancehall\nDutch hip-hop electro-funk\nDutch hip-hop funk soul\nDutch hip-hop lo-fi\nDutch hip-hop nu-disco funk\nDutch hip-hop reggaeton\nDutch hip-hop trap\nDutch hip-hop, Latin pop, dancehall\nDutch hip-hop, boom-bap, horrorcore\nDutch hip-hop, hardstyle\nDutch hip-hop, hardstyle, gabber\nDutch hip-hop, industrial rock\nDutch hip-hop, jungle\nDutch hip-hop, moombahton, dancehall\nDutch hip-hop, reggae fusion\nDutch hip-hop, reggaeton, Latin hip-hop\nDutch hip-hop, trap\nDutch hip-hop, trap, Afrobeats\nDutch hip-hop, trap, R&B\nDutch hip-hop, trap, electronic\nDutch house\nDutch house pop\nDutch house, slap house, pop-rap\nDutch indie pop\nDutch levenslied\nDutch levenslied, Eurodance\nDutch levenslied, Eurodance, folk-pop\nDutch levenslied, Latin pop\nDutch levenslied, pop-rock, cinematic\nDutch mambo\nDutch musical theatre\nDutch muziek\nDutch novelty\nDutch novelty, 8-bit, chiptune\nDutch novelty, 80s Schlager\nDutch novelty, 80s schlager, polka\nDutch novelty, polka, Schlager\nDutch novelty, polka, levenslied\nDutch novelty, tropical, Schlager\nDutch party\nDutch party anthem\nDutch party music\nDutch party polka\nDutch party rap\nDutch party rock\nDutch party, Eurodance\nDutch party, Latin carnival, electronic\nDutch party, Latin dance\nDutch party, Latin, Schlager\nDutch party, Latin-ska, schlager\nDutch party-rap\nDutch polka\nDutch polka ska\nDutch pop\nDutch pop J-pop\nDutch pop R&B\nDutch pop cabaret\nDutch pop disco-funk\nDutch pop exotica\nDutch pop funk disco\nDutch pop reggaeton\nDutch pop schlager\nDutch pop show tune\nDutch pop ska\nDutch pop, 60s rock and roll, Latin\nDutch pop, 80s Europop\nDutch pop, 80s pop, theatrical pop\nDutch pop, 80s retro, novelty\nDutch pop, 80s schlager\nDutch pop, 80s schlager, theatrical pop\nDutch pop, 80s synthpop\nDutch pop, Christmas, ballad\nDutch pop, EDM\nDutch pop, EDM, dance-pop\nDutch pop, EDM, slap house\nDutch pop, Eurodance\nDutch pop, Eurodance, Latin pop\nDutch pop, Eurodance, Schlager\nDutch pop, Eurodance, funk\nDutch pop, European folk\nDutch pop, Europop, Schlager\nDutch pop, Latin cumbia\nDutch pop, Latin dance\nDutch pop, Latin dance, reggaeton\nDutch pop, Latin dance, upbeat\nDutch pop, Latin pop\nDutch pop, Latin pop, 80s Euro pop\nDutch pop, Latin pop, Caribbean pop\nDutch pop, Latin pop, Europop\nDutch pop, Latin pop, Schlager\nDutch pop, Latin pop, ballad\nDutch pop, Latin pop, cumbia\nDutch pop, Latin pop, dembow\nDutch pop, Latin pop, levenslied\nDutch pop, Latin pop, soca\nDutch pop, Latin pop, theatrical\nDutch pop, Latin pop, theatrical pop\nDutch pop, Latin pop, tropical\nDutch pop, Latin, big band\nDutch pop, R&B\nDutch pop, R&B, trap\nDutch pop, Schlager\nDutch pop, Schlager, Christmas\nDutch pop, Schlager, Latin pop\nDutch pop, Schlager, retro\nDutch pop, Schlager, theatrical pop\nDutch pop, Schlager, vintage big band\nDutch pop, afrobeat, dancehall\nDutch pop, big band\nDutch pop, big band, cabaret\nDutch pop, big band, show tune\nDutch pop, big band, ska\nDutch pop, big-band swing\nDutch pop, cabaret, big band\nDutch pop, cabaret, boogie-woogie\nDutch pop, cabaret, polka\nDutch pop, cabaret, schlager\nDutch pop, cabaret, show tune\nDutch pop, cabaret, swing\nDutch pop, cabaret, world music\nDutch pop, chanson\nDutch pop, chanson, schlager\nDutch pop, chanson, theatrical\nDutch pop, chiptune\nDutch pop, cumbia\nDutch pop, disco-funk\nDutch pop, festive, levenslied\nDutch pop, folk pop, polka\nDutch pop, folk, theatrical\nDutch pop, funk, disco\nDutch pop, funk, hip-hop\nDutch pop, funk, retro\nDutch pop, garage rock, surf rock\nDutch pop, lo-fi, garage rock\nDutch pop, musical theatre\nDutch pop, musical theatre, pop-rock\nDutch pop, new jack swing\nDutch pop, retro big band, ska\nDutch pop, retro disco, funk\nDutch pop, retro, Latin pop\nDutch pop, retro, levenslied\nDutch pop, schlager\nDutch pop, schlager, musical theater\nDutch pop, schlager, novelty\nDutch pop, schlager, pop-rock\nDutch pop, show tune\nDutch pop, synth-pop, disco\nDutch pop, trap, hip-hop\nDutch pop-EDM\nDutch pop-R&B\nDutch pop-dance\nDutch pop-folk\nDutch pop-funk\nDutch pop-rap\nDutch pop-rap tropical house\nDutch pop-rap, hardstyle\nDutch pop-reggae\nDutch pop-rock\nDutch pop-rock 80s\nDutch pop-rock cabaret\nDutch pop-rock schlager\nDutch pop-rock ska\nDutch pop-rock, schlager\nDutch pop-schlager\nDutch pop-trap\nDutch power ballad\nDutch pub rock\nDutch punk rock\nDutch rap\nDutch rap, trap, boom-bap\nDutch reggae\nDutch reggae ska\nDutch reggaeton\nDutch rock\nDutch rock 'n' roll\nDutch rock and roll\nDutch rock cabaret\nDutch rock funk\nDutch rock, 80s new wave\nDutch rock, Latin rock\nDutch rock, Schlager\nDutch rock, big band, swing\nDutch rock, new wave, post-punk\nDutch rock, polka, feest\nDutch rock, polka, levenslied\nDutch rock, schlager, rock 'n' roll\nDutch rock, schlager, theatrical rock\nDutch rock, ska, reggae\nDutch rock, ska, rockabilly\nDutch schlager\nDutch schlager exotica\nDutch schlager tango\nDutch schlager, Eurodance\nDutch schlager, Europop\nDutch schlager, Italo-disco\nDutch schlager, Latin cumbia\nDutch schlager, Latin pop\nDutch schlager, Latin pop, carnival\nDutch schlager, Latin pop, levenslied\nDutch schlager, Latin salsa\nDutch schlager, Latin, cumbia\nDutch schlager, Latin, mariachi\nDutch schlager, Spanish cabaret, theatrical pop\nDutch schlager, carnival pop\nDutch schlager, carnival, Eastern European polka\nDutch schlager, carnival, Latin pop\nDutch schlager, carnival, Spanish flair\nDutch schlager, carnival, Western\nDutch schlager, carnival, chiptune\nDutch schlager, carnival, cinematic\nDutch schlager, carnival, polka\nDutch schlager, carnival, upbeat\nDutch schlager, country-rock\nDutch schlager, happy hardcore\nDutch schlager, happy hardcore, gabber\nDutch schlager, mariachi, upbeat\nDutch schlager, polka\nDutch schlager, tropical pop, Latin-pop\nDutch schlager-pop\nDutch schlager-rock\nDutch sea shanty\nDutch sea shanty schlager\nDutch sea shanty, polka, accordion\nDutch singer-songwriter\nDutch ska\nDutch ska-pop\nDutch soul-pop\nDutch summer pop\nDutch swing\nDutch swing-pop\nDutch trap\nDutch trap R&B\nDutch trap lo-fi\nDutch trap, Afro-trap\nDutch trap, North African fusion\nDutch trap, cloud rap\nDutch trap-pop\nDutch waltz\nDutch winter pop\nEBM\nEBM Anatolian rock\nEBM Hi-NRG\nEBM Italo-disco\nEBM Neue Deutsche Welle\nEBM Soviet synth-pop\nEBM ambient\nEBM chiptune\nEBM chiptune synth-pop\nEBM cinematic\nEBM coldwave\nEBM cyberpunk\nEBM dark synthwave\nEBM dark techno\nEBM dark techno electro\nEBM dark techno industrial\nEBM darksynth\nEBM darkwave\nEBM darkwave gothic\nEBM darkwave industrial\nEBM darkwave industrial techno\nEBM darkwave minimal techno\nEBM darkwave progressive house\nEBM darkwave synth-pop\nEBM darkwave synth-punk\nEBM darkwave synthpop\nEBM darkwave techno\nEBM electro-pop\nEBM electroclash\nEBM futurepop\nEBM futurepop industrial dance\nEBM hip-hop\nEBM horror cinematic\nEBM hyperpop\nEBM industrial\nEBM industrial cyberpunk\nEBM industrial dance\nEBM industrial dark synthwave\nEBM industrial darkwave\nEBM industrial experimental hip-hop\nEBM industrial metal\nEBM industrial rock\nEBM industrial synth-pop\nEBM industrial synthwave\nEBM industrial techno\nEBM industrial trance\nEBM minimal techno\nEBM post-punk\nEBM synth-pop\nEBM synth-pop chiptune\nEBM synth-pop industrial rock\nEBM synthwave\nEBM synthwave electro\nEBM synthwave industrial\nEBM techno\nEBM trance\nEBM, 80s electronic, synthwave\nEBM, Chinese hip hop\nEBM, German hip-hop\nEBM, Italian hip-hop\nEBM, Italian pop-rock\nEBM, Italo-disco\nEBM, Moombahton\nEBM, Neue Deutsche Härte\nEBM, Neue Deutsche Härte, cinematic\nEBM, Neue Deutsche Welle\nEBM, acid techno, industrial\nEBM, alternative rock, punk rock\nEBM, ambient\nEBM, ambient, cinematic\nEBM, ambient, dystopian\nEBM, ambient, ethereal\nEBM, ambient, synth-pop\nEBM, ambient, synthwave\nEBM, breakcore, ambient\nEBM, chiptune, folk\nEBM, chiptune, industrial\nEBM, cinematic synth\nEBM, cinematic synth, German industrial\nEBM, cinematic synth, chiptune\nEBM, cinematic trance\nEBM, cinematic, Spanish vocals\nEBM, cinematic, ambient\nEBM, cinematic, big beat\nEBM, cinematic, chiptune\nEBM, cinematic, cyberpunk\nEBM, cinematic, dark synth\nEBM, cinematic, dark wave\nEBM, cinematic, darkwave\nEBM, cinematic, electronic\nEBM, cinematic, gothic\nEBM, cinematic, industrial\nEBM, cinematic, orchestral\nEBM, cinematic, synthwave\nEBM, cold wave, industrial dance\nEBM, coldwave, industrial\nEBM, coldwave, retro-futuristic\nEBM, coldwave, synthwave\nEBM, cyberpunk\nEBM, cyberpunk, darkwave\nEBM, cyberpunk, electronic\nEBM, cyberpunk, industrial\nEBM, cyberpunk, lo-fi\nEBM, cyberpunk, synthwave\nEBM, cyberpunk, techno\nEBM, dark ambient\nEBM, dark ambient, cinematic\nEBM, dark ambient, synthwave\nEBM, dark electronic, lo-fi\nEBM, dark synth\nEBM, dark synth, cinematic\nEBM, dark synth-pop\nEBM, dark synthwave\nEBM, dark techno\nEBM, dark techno, Latin urban\nEBM, dark techno, electronic\nEBM, dark techno, hard dance\nEBM, dark techno, industrial\nEBM, dark wave\nEBM, dark wave, choral\nEBM, dark wave, cinematic\nEBM, dark wave, dream pop\nEBM, dark wave, electronic\nEBM, dark wave, glitch\nEBM, dark wave, industrial\nEBM, dark wave, psychedelic\nEBM, dark wave, synthpop\nEBM, darkwave\nEBM, darkwave, 80s electronic\nEBM, darkwave, analog synth\nEBM, darkwave, coldwave\nEBM, darkwave, cyberpunk\nEBM, darkwave, electronic\nEBM, darkwave, gothic\nEBM, darkwave, hard techno\nEBM, darkwave, industrial\nEBM, darkwave, industrial dance\nEBM, darkwave, industrial techno\nEBM, darkwave, retro-futuristic\nEBM, darkwave, synth-pop\nEBM, darkwave, synth-punk\nEBM, darkwave, synthwave\nEBM, darkwave, techno\nEBM, deep house, ambient\nEBM, dream pop, industrial techno\nEBM, dream-pop, industrial\nEBM, drum and bass\nEBM, dubstep, synthwave\nEBM, early techno\nEBM, early techno, retro-futuristic\nEBM, electro, glitch\nEBM, electro, retro-electronic\nEBM, electro, synthwave\nEBM, electroclash, aggressive electro\nEBM, experimental electronic\nEBM, experimental hip-hop, ambient\nEBM, futuristic electronic\nEBM, glitch, Chinese synth\nEBM, glitch, industrial\nEBM, glitch, post-punk\nEBM, glitch, synthwave\nEBM, gothic\nEBM, gothic rock, cinematic\nEBM, gothic synth\nEBM, hard techno\nEBM, hard techno, industrial hip-hop\nEBM, industrial dance\nEBM, industrial dance, synthwave\nEBM, industrial rock\nEBM, industrial techno\nEBM, industrial techno, Eastern European folk\nEBM, industrial techno, ambient\nEBM, industrial techno, chiptune\nEBM, industrial techno, cinematic\nEBM, industrial techno, darkwave\nEBM, industrial techno, synthwave\nEBM, industrial, Neue Deutsche Härte\nEBM, industrial, Neue Deutsche Welle\nEBM, industrial, ambient\nEBM, industrial, cinematic\nEBM, industrial, cyberpunk\nEBM, industrial, dark ambient\nEBM, industrial, dark techno\nEBM, industrial, darkwave\nEBM, industrial, glitch\nEBM, industrial, hard techno\nEBM, industrial, hyperpop\nEBM, industrial, retro-futuristic\nEBM, industrial, shoegaze\nEBM, industrial, synth-pop\nEBM, industrial, synthwave\nEBM, industrial, techno\nEBM, industrial, techno-pop\nEBM, industrial, trap\nEBM, jazz, synthwave\nEBM, minimal synth\nEBM, noise rock\nEBM, post-punk, synthwave\nEBM, synth-pop\nEBM, synth-pop, 80s\nEBM, synth-pop, Neue Deutsche Welle\nEBM, synth-pop, chiptune\nEBM, synth-pop, dark wave\nEBM, synth-pop, darkwave\nEBM, synth-pop, industrial\nEBM, synth-pop, new wave\nEBM, synth-pop, retro-futuristic\nEBM, synth-pop, techno\nEBM, synth-pop, trance\nEBM, synth-punk\nEBM, synthwave\nEBM, synthwave, French indie\nEBM, synthwave, German industrial\nEBM, synthwave, German spoken word\nEBM, synthwave, Swedish rap\nEBM, synthwave, atmospheric\nEBM, synthwave, chiptune\nEBM, synthwave, cinematic\nEBM, synthwave, cyberpunk\nEBM, synthwave, dark wave\nEBM, synthwave, darkwave\nEBM, synthwave, electronic\nEBM, synthwave, future pop\nEBM, synthwave, industrial\nEBM, synthwave, industrial dance\nEBM, synthwave, psychedelic\nEBM, synthwave, retro-futuristic\nEBM, synthwave, techno\nEBM, synthwave, techno-pop\nEBM, synthwave, trance\nEBM, synthwave, video game\nEBM, techno\nEBM, techno, ambient\nEBM, techno, cinematic\nEBM, techno, classical fusion\nEBM, techno, dark wave\nEBM, techno, hard dance\nEBM, techno, industrial\nEBM, techno, synthwave\nEBM, trance\nEDM\nEDM Arabic\nEDM Arabic fusion\nEDM Arabic pop\nEDM Balkan fusion\nEDM Balkan house\nEDM Balkan pop\nEDM Bhangra\nEDM Bhangra fusion\nEDM Bhojpuri\nEDM Bhojpuri fusion\nEDM Bollywood\nEDM Bollywood Bhangra\nEDM Bollywood Bhojpuri\nEDM Bollywood Eurodance\nEDM Bollywood Trance\nEDM Bollywood chiptune\nEDM Bollywood fusion\nEDM Bollywood pop\nEDM Bollywood pop future bass\nEDM C-pop\nEDM C-pop Eurodance\nEDM C-pop J-pop\nEDM C-pop K-pop\nEDM C-pop big room house\nEDM C-pop chiptune\nEDM C-pop dance-pop\nEDM C-pop electro house\nEDM C-pop fusion\nEDM C-pop future bass\nEDM C-pop hard dance\nEDM C-pop hardstyle\nEDM C-pop hip-hop\nEDM C-pop hyperpop\nEDM C-pop rap\nEDM C-pop synth-pop\nEDM C-pop trance\nEDM Cantopop\nEDM Christian\nEDM Christmas\nEDM Dutch House\nEDM Eurodance\nEDM Eurodance Trance\nEDM Eurodance V-Pop\nEDM Eurodance slap house\nEDM Eurodance trance\nEDM Indian bhajan\nEDM Indian devotional\nEDM Indian folk\nEDM Indian folk fusion\nEDM Indian fusion\nEDM Indian pop\nEDM J-core\nEDM J-pop\nEDM J-pop C-pop\nEDM J-pop Eurodance\nEDM J-pop anime\nEDM J-pop happy hardcore\nEDM J-pop hybrid\nEDM J-pop trance\nEDM Javanese pop\nEDM K-pop\nEDM K-pop crossover\nEDM K-pop future bass\nEDM K-pop hardstyle\nEDM K-pop hip-hop\nEDM K-pop progressive house\nEDM Kollywood\nEDM Kuthu\nEDM Latin\nEDM Latin Hardstyle\nEDM Latin House\nEDM Latin House Moombahton\nEDM Latin dance-pop\nEDM Latin fusion\nEDM Latin house\nEDM Latin house moombahton\nEDM Latin pop\nEDM Latin pop Melbourne bounce\nEDM Latin urban\nEDM Malay fusion\nEDM Mandopop\nEDM Mandopop Eurodance\nEDM Mandopop big room\nEDM Mandopop electro house\nEDM Melbourne Bounce\nEDM Melbourne bounce\nEDM Middle Eastern\nEDM Naat\nEDM Russian pop\nEDM South African house\nEDM Tibetan pop\nEDM UK garage\nEDM V-Pop\nEDM V-Pop Eurodance\nEDM V-Pop Mandopop\nEDM V-Pop hardstyle\nEDM V-pop\nEDM Vinahouse\nEDM anthemic\nEDM ballad\nEDM bhajan\nEDM bhajan fusion\nEDM big room\nEDM big room Indian pop\nEDM big room hardstyle\nEDM big room hip-hop\nEDM big room house\nEDM big room trap\nEDM big room tropical house\nEDM chiptune\nEDM chiptune happy hardcore\nEDM chiptune trance\nEDM cinematic\nEDM complextro\nEDM cyberpunk\nEDM dance-pop\nEDM dance-pop Eurodance\nEDM dance-pop house\nEDM dance-pop slap house\nEDM dancehall\nEDM dancehall soca\nEDM devotional\nEDM dream-pop rock\nEDM dubstep\nEDM electro\nEDM electro house\nEDM electro house dance-pop\nEDM electro-pop\nEDM electro-pop hip-hop\nEDM festival\nEDM festival house\nEDM festival house trance\nEDM folk fusion\nEDM folk-dance\nEDM football chant\nEDM funk house\nEDM funk-pop\nEDM fusion\nEDM future bass\nEDM future bass J-pop\nEDM future bass electro house\nEDM future bass gospel\nEDM future bass hardstyle\nEDM future bass pop\nEDM gospel\nEDM gospel Afrobeat\nEDM gospel hip-hop\nEDM hands-up\nEDM happy hardcore\nEDM hard dance Balkan pop-rap\nEDM hard dance trap\nEDM hardstyle\nEDM hardstyle Bollywood\nEDM hardstyle Eurodance\nEDM hardstyle J-pop\nEDM hardstyle Mandopop\nEDM hardstyle V-pop\nEDM hardstyle big room\nEDM hardstyle chiptune\nEDM hardstyle pop\nEDM hardstyle trance\nEDM hardstyle trap\nEDM hip-hop\nEDM hip-hop Indian film music\nEDM hip-hop Mandopop\nEDM hip-hop bass house\nEDM hip-hop chiptune\nEDM hip-hop crossover\nEDM hip-hop dance-pop\nEDM hip-hop fusion\nEDM hip-hop future bass\nEDM hip-hop hardstyle\nEDM hip-hop moombahton\nEDM hip-hop pop\nEDM hip-hop tech house\nEDM hip-hop trance\nEDM hip-hop, South Indian fusion\nEDM hip-house dance-pop\nEDM house\nEDM house pop\nEDM hyperpop\nEDM hyperpop J-core\nEDM hyperpop J-pop\nEDM hyperpop hardstyle\nEDM industrial\nEDM lo-fi\nEDM moombahton\nEDM moombahton Indian folk\nEDM moombahton Indian pop\nEDM nightcore\nEDM nu-metal\nEDM orchestral\nEDM pirate theme\nEDM pop\nEDM pop Middle Eastern\nEDM pop chiptune\nEDM pop future bass\nEDM pop hardstyle\nEDM pop hip-hop\nEDM pop house\nEDM pop rap\nEDM pop rock\nEDM pop world music\nEDM pop, Middle Eastern fusion\nEDM pop, ethnic fusion\nEDM pop-R&B\nEDM pop-house\nEDM pop-punk\nEDM pop-punk hyperpop\nEDM pop-rap\nEDM pop-rap future bass\nEDM pop-rock\nEDM progressive house\nEDM progressive house C-pop\nEDM progressive house Mandopop\nEDM progressive house V-pop\nEDM progressive house big room\nEDM progressive house electro\nEDM progressive house electro-pop\nEDM progressive house hardstyle\nEDM progressive house pop-rap\nEDM progressive house trance\nEDM psytrance\nEDM reggaeton\nEDM rock\nEDM satirical\nEDM sea shanty\nEDM sea-shanty\nEDM slap house\nEDM slap house Eurodance\nEDM sports anthem\nEDM synth-pop\nEDM synthwave\nEDM synthwave chiptune\nEDM synthwave electro-pop\nEDM synthwave trance\nEDM tech house\nEDM tech-house\nEDM techno\nEDM trance\nEDM trance Eurodance\nEDM trance eurodance\nEDM trance hands-up\nEDM trance hardstyle\nEDM trance progressive house\nEDM trance synth-pop\nEDM trance-pop\nEDM trap\nEDM trap Bollywood\nEDM trap C-pop\nEDM trap Hindu devotional\nEDM trap Indian\nEDM trap Indian devotional\nEDM trap Indian fusion\nEDM trap Indian pop\nEDM trap K-pop\nEDM trap Middle Eastern\nEDM trap Tibetan\nEDM trap bhajan\nEDM trap big room\nEDM trap chiptune\nEDM trap cinematic pop\nEDM trap dubstep\nEDM trap future bass\nEDM trap hardstyle\nEDM trap hip-hop\nEDM trap hyperpop\nEDM trap moombahton\nEDM trap pop\nEDM trap pop-rock\nEDM trap stadium anthem\nEDM trap synth-pop\nEDM trap world music\nEDM trap worship\nEDM trap, Bhangra\nEDM trap, South Asian fusion\nEDM trap, hardstyle, vaporwave\nEDM trap-pop\nEDM tribal\nEDM tribal house\nEDM tropical\nEDM tropical house\nEDM tropical house future bass\nEDM tropical house moombahton\nEDM world fusion\nEDM world music\nEDM worship\nEDM, Arabic cinematic\nEDM, Arabic devotional, dance-pop\nEDM, Arabic fusion\nEDM, Arabic, Middle Eastern\nEDM, Balkan fusion\nEDM, Balkan fusion, dance-pop\nEDM, Balkan fusion, electronic\nEDM, Balkan fusion, house\nEDM, Balkan hip-hop, cinematic\nEDM, Bengali pop\nEDM, Bengali pop, dance\nEDM, Bhangra, hip-hop\nEDM, Bhangra, militant\nEDM, Bhojpuri, Bollywood\nEDM, Bhojpuri, Haryanvi\nEDM, Bhojpuri, Pahari\nEDM, Bhojpuri, electronic\nEDM, Bollywood\nEDM, Bollywood dance-pop, devotional\nEDM, Bollywood fusion\nEDM, Bollywood pop, future bass\nEDM, Bollywood, Bhangra\nEDM, Bollywood, Indian classical\nEDM, Bollywood, Indian devotional\nEDM, Bollywood, Middle Eastern\nEDM, Bollywood, South Asian\nEDM, Bollywood, devotional\nEDM, Bollywood, electronic\nEDM, Bollywood, hardstyle\nEDM, Bollywood, spiritual\nEDM, C-pop\nEDM, C-pop, cinematic\nEDM, C-pop, electronic\nEDM, C-pop, folk-electronic\nEDM, C-pop, synthwave\nEDM, C-pop, traditional fusion\nEDM, Cantonese pop\nEDM, Cantopop, hip-hop\nEDM, Central Asian fusion\nEDM, Central Asian, Eastern European\nEDM, Chinese MC, dance\nEDM, Chinese New Year\nEDM, Chinese New Year, dance\nEDM, Chinese New Year, dance-pop\nEDM, Chinese New Year, pop\nEDM, Chinese electronic\nEDM, Chinese folk\nEDM, Chinese fusion\nEDM, Chinese fusion, electronic\nEDM, Chinese fusion, hardstyle\nEDM, Chinese hip hop\nEDM, Chinese hip hop, Eurodance\nEDM, Chinese hip-hop\nEDM, Chinese pop\nEDM, Chinese pop, dance\nEDM, Chinese pop, electronic\nEDM, Chinese pop, meme music\nEDM, Chinese rap, atmospheric\nEDM, Christmas, pop\nEDM, Dangdut Koplo\nEDM, Dutch House\nEDM, Dutch House, Mandopop\nEDM, Dutch House, Melbourne Bounce\nEDM, Dutch House, cinematic\nEDM, Dutch House, future bass\nEDM, Dutch House, pop\nEDM, East Asian folk, electronic\nEDM, East Asian fusion\nEDM, Eurodance, C-pop\nEDM, Eurodance, Cantopop\nEDM, Eurodance, Italo dance\nEDM, Eurodance, J-pop\nEDM, Eurodance, Trance\nEDM, Eurodance, V-Pop\nEDM, Eurodance, V-pop\nEDM, Eurodance, Vina House\nEDM, Eurodance, breakcore\nEDM, Eurodance, happy hardcore\nEDM, Eurodance, hyperpop\nEDM, Eurodance, progressive house\nEDM, Eurodance, trance\nEDM, French pop, electronic\nEDM, Gana, Bollywood\nEDM, Garba, Bhojpuri\nEDM, German pop-rap, Middle Eastern fusion\nEDM, German rap, Russian pop-dance\nEDM, Hindi house\nEDM, Hindi pop\nEDM, Hindi pop, electronic\nEDM, Hindu devotional, electronic fusion\nEDM, Hindu devotional, trap\nEDM, Indian bhajan\nEDM, Indian bhajan, big band\nEDM, Indian bhajan, dance\nEDM, Indian bhajan, dance-pop\nEDM, Indian bhajan, electronic\nEDM, Indian bhajan, house\nEDM, Indian bhajan, trap\nEDM, Indian classical, electronic\nEDM, Indian classical, lo-fi\nEDM, Indian classical, trap\nEDM, Indian club\nEDM, Indian dance\nEDM, Indian devotional\nEDM, Indian devotional, Garba\nEDM, Indian devotional, big room house\nEDM, Indian devotional, dance\nEDM, Indian devotional, electronic\nEDM, Indian devotional, electronic fusion\nEDM, Indian devotional, fusion\nEDM, Indian devotional, hardstyle\nEDM, Indian devotional, trap\nEDM, Indian electronic\nEDM, Indian folk\nEDM, Indian folk, Bollywood\nEDM, Indian folk, bhajan\nEDM, Indian folk, big room house\nEDM, Indian folk, chiptune\nEDM, Indian folk, cinematic\nEDM, Indian folk, dance\nEDM, Indian folk, devotional\nEDM, Indian folk, devotional dance\nEDM, Indian folk, electronic\nEDM, Indian folk, electronic dance\nEDM, Indian folk, fusion\nEDM, Indian fusion\nEDM, Indian fusion, cinematic\nEDM, Indian fusion, devotional\nEDM, Indian fusion, electronic\nEDM, Indian fusion, hip-hop\nEDM, Indian fusion, spiritual club\nEDM, Indian fusion, sports anthem\nEDM, Indian pop\nEDM, Indian pop, chiptune\nEDM, Indian pop, electronic dance\nEDM, Indian pop, hip-hop\nEDM, Indian pop, house\nEDM, Indonesian fusion\nEDM, Indonesian pop, funkot\nEDM, Italo dance, Eurodance\nEDM, J-core, Chinese opera\nEDM, J-core, hands-up trance\nEDM, J-core, happy hardcore\nEDM, J-core, hardstyle\nEDM, J-core, trance\nEDM, J-pop, chiptune\nEDM, J-pop, happy hardcore\nEDM, J-pop, hardstyle\nEDM, J-pop, hyperpop\nEDM, J-pop, progressive house\nEDM, J-pop, trance\nEDM, Javanese pop\nEDM, K-pop, Mandopop\nEDM, K-pop, electronic\nEDM, K-pop, hardstyle\nEDM, K-pop, trap\nEDM, Kannada pop, dance\nEDM, Kuthu, Gaana\nEDM, Kuthu, Tamil dance\nEDM, Kuthu, electronic\nEDM, Latin House\nEDM, Latin hip-hop, hard dance\nEDM, Latin house, big room\nEDM, Latin house, moombahton\nEDM, Latin house, tribal house\nEDM, Latin pop, big room house\nEDM, Latin pop, hip hop\nEDM, Latin pop, moombahton\nEDM, Latin pop, reggaeton\nEDM, Latin, Middle Eastern\nEDM, Malay fusion\nEDM, Malay pop, festive\nEDM, Mandarin hip hop\nEDM, Mandarin pop\nEDM, Mandarin rap, synthwave\nEDM, Mandopop, Trance\nEDM, Mandopop, disco-house\nEDM, Mandopop, hip hop\nEDM, Mandopop, hip-hop\nEDM, Marathi dance\nEDM, Marathi folk, electronic\nEDM, Marathi fusion\nEDM, Melbourne bounce\nEDM, Melbourne bounce, hard dance\nEDM, Melbourne bounce, hardstyle\nEDM, Middle Eastern\nEDM, Middle Eastern dance\nEDM, Middle Eastern fusion\nEDM, Middle Eastern fusion, Balkan\nEDM, Middle Eastern fusion, cinematic\nEDM, Middle Eastern fusion, electronic dance\nEDM, Middle Eastern pop\nEDM, Middle Eastern synth\nEDM, Middle Eastern trance\nEDM, Middle Eastern, Arabic\nEDM, Middle Eastern, Arabic fusion\nEDM, Middle Eastern, Balkan\nEDM, Middle Eastern, Bollywood\nEDM, Middle Eastern, Phrygian\nEDM, Middle Eastern, South Asian\nEDM, Middle Eastern, Turkish\nEDM, Middle Eastern, cinematic\nEDM, Middle Eastern, electronic\nEDM, Middle Eastern, house\nEDM, Middle Eastern, instrumental\nEDM, Middle Eastern, mystical\nEDM, Middle Eastern, oriental\nEDM, Middle Eastern, psytrance\nEDM, Middle Eastern, trance\nEDM, Mongolian folk, cinematic\nEDM, Moombahton, Latin\nEDM, Nepali folk\nEDM, Norwegian party, anthemic\nEDM, Russian folk\nEDM, Russian rap, aggressive\nEDM, Sinhala pop\nEDM, South African hip-hop\nEDM, South Asian folk\nEDM, South Asian folk, dance\nEDM, South Asian folk, electronic\nEDM, South Asian fusion\nEDM, South Asian fusion, Middle Eastern electronic\nEDM, South Asian pop\nEDM, South Asian, Middle Eastern\nEDM, South Asian, Pahari\nEDM, South Indian\nEDM, South Indian film music, reggaeton\nEDM, South Indian folk\nEDM, South Indian fusion\nEDM, South Indian pop, Kollywood\nEDM, South Indian, dance\nEDM, South Indian, electronic\nEDM, Southeast Asian fusion\nEDM, Southeast Asian, house\nEDM, Soviet-era, trance\nEDM, Sundanese fusion\nEDM, Tamil folk, electronic\nEDM, Telugu Christian, dance\nEDM, Telugu folk\nEDM, Telugu folk, devotional dance\nEDM, Telugu hip hop, cinematic\nEDM, Telugu pop, electronic\nEDM, Turkish pop, oriental synth\nEDM, Ukrainian folk, patriotic\nEDM, Ukrainian pop\nEDM, V-Pop, Eurodance\nEDM, V-Pop, electro house\nEDM, V-Pop, trance\nEDM, V-pop, J-pop\nEDM, V-pop, big room house\nEDM, V-pop, future bass\nEDM, Vietnamese fusion\nEDM, Vietnamese hip hop\nEDM, Vietnamese pop\nEDM, Vietnamese pop, chiptune\nEDM, Vietnamese pop, dream pop\nEDM, Vietnamese pop, hardstyle\nEDM, alt-rock\nEDM, ambient, Chinese pop\nEDM, anime opening, hardstyle\nEDM, bhajan\nEDM, bhajan, dance-pop\nEDM, bhajan, trance\nEDM, big room house, Bollywood\nEDM, big room house, Melbourne bounce\nEDM, big room house, acoustic rock\nEDM, big room house, hardstyle\nEDM, big room, chiptune\nEDM, bilingual club\nEDM, bilingual pop\nEDM, bilingual, dance\nEDM, bilingual, electronic\nEDM, bilingual, pop\nEDM, chiptune, C-pop\nEDM, chiptune, Indian film music\nEDM, chiptune, J-core\nEDM, chiptune, Malayalam pop\nEDM, chiptune, cinematic\nEDM, chiptune, festival\nEDM, chiptune, happy hardcore\nEDM, chiptune, hip-hop\nEDM, chiptune, hyperpop\nEDM, cinematic pop\nEDM, cinematic, Azerbaijani\nEDM, cinematic, Chinese pop\nEDM, cinematic, Mandarin pop\nEDM, cinematic, Middle Eastern fusion\nEDM, cinematic, Russian pop\nEDM, cinematic, South Asian fusion\nEDM, cinematic, electronic\nEDM, cinematic, oriental trance\nEDM, cinematic, pop\nEDM, cinematic, rap\nEDM, cinematic, trance\nEDM, club, multilingual\nEDM, cyber-pop\nEDM, cyberpunk, Chinese pop\nEDM, cyberpunk, Mandarin pop\nEDM, dance, Chinese pop\nEDM, dance, bilingual\nEDM, dance, pop\nEDM, dance-pop\nEDM, dance-pop, C-pop\nEDM, dance-pop, Indian bhajan\nEDM, dance-pop, Mandarin rap\nEDM, dance-pop, Mandopop\nEDM, dance-pop, Telugu devotional\nEDM, dance-pop, big room house\nEDM, dance-pop, electro-house\nEDM, dance-pop, fusion\nEDM, dance-pop, hardstyle\nEDM, dance-pop, hyperpop\nEDM, dance-pop, moombahton\nEDM, dance-pop, trance\nEDM, dancehall, cinematic\nEDM, dancehall, moombahton\nEDM, desert wave, pop\nEDM, devotional, Hindu\nEDM, devotional, Indian bhajan\nEDM, devotional, Indian electronic\nEDM, devotional, Indian fusion\nEDM, devotional, cinematic\nEDM, devotional, electronic\nEDM, devotional, ritualistic\nEDM, devotional, trap\nEDM, dubstep, C-pop\nEDM, dubstep, dance-pop\nEDM, educational, pop\nEDM, electro house\nEDM, electro house, Mandopop\nEDM, electro-house\nEDM, electronic, East Asian fusion\nEDM, electronic, Indian fusion\nEDM, electronic, folk fusion\nEDM, ethnic folk, Middle Eastern\nEDM, ethnic folk, fusion\nEDM, festival house\nEDM, festival, Middle Eastern\nEDM, festival, high-energy\nEDM, festive\nEDM, folk fusion\nEDM, folk fusion, Indian electronic\nEDM, folk fusion, Ukrainian\nEDM, future bass\nEDM, future bass, C-pop\nEDM, future bass, Latin pop\nEDM, future bass, electro-pop\nEDM, future bass, happy hardcore\nEDM, future bass, hardstyle\nEDM, future house, trance\nEDM, futuristic, sci-fi\nEDM, global fusion, Carnatic\nEDM, happy hardcore\nEDM, hard dance, Hindi hip hop\nEDM, hard dance, big room house\nEDM, hard dance, techno-pop\nEDM, hard trance, hands-up\nEDM, hardstyle\nEDM, hardstyle, Bollywood\nEDM, hardstyle, C-pop\nEDM, hardstyle, Eurodance\nEDM, hardstyle, Melbourne bounce\nEDM, hardstyle, Southeast Asian\nEDM, hardstyle, Vietnamese pop\nEDM, hardstyle, Vocaloid\nEDM, hardstyle, big room\nEDM, hardstyle, big room house\nEDM, hardstyle, cinematic\nEDM, hardstyle, dubstep\nEDM, hardstyle, festival\nEDM, hardstyle, happy hardcore\nEDM, hardstyle, pop-rap\nEDM, hardstyle, progressive house\nEDM, hardstyle, psytrance\nEDM, hardstyle, trap\nEDM, hip hop, C-pop\nEDM, hip-hop, Kuthu\nEDM, hip-hop, South Indian fusion\nEDM, hip-hop, bass house\nEDM, hip-hop, folk-dance\nEDM, hip-hop, hardstyle\nEDM, hip-hop, pop\nEDM, house, East Asian fusion\nEDM, house, Mandarin pop\nEDM, house, Mandarin rap\nEDM, house, South Asian fusion\nEDM, house, festive\nEDM, house, sea shanty\nEDM, hyperpop\nEDM, hyperpop, Czech rap\nEDM, hyperpop, children's music\nEDM, hyperpop, cinematic\nEDM, hǎnmài\nEDM, oriental fusion\nEDM, oriental synth, dance\nEDM, oriental, Middle Eastern\nEDM, oriental, electronic\nEDM, oriental, high-energy\nEDM, patriotic, folk-electronic\nEDM, patriotic, militant\nEDM, pirate theme, happy hardcore\nEDM, pop, Middle Eastern fusion\nEDM, pop, V-Pop\nEDM, pop, V-pop\nEDM, pop, future bass\nEDM, pop, hip hop\nEDM, pop-rap, Chinese pop\nEDM, pop-rock, funk-pop\nEDM, progressive house\nEDM, progressive house, C-pop\nEDM, progressive house, Indian devotional\nEDM, progressive house, Polish folk\nEDM, progressive house, big room\nEDM, progressive house, dance-pop\nEDM, progressive house, pop-punk\nEDM, progressive house, trance\nEDM, psytrance, Indian devotional\nEDM, psytrance, Middle Eastern fusion\nEDM, slap house, big room\nEDM, soul, dance-pop\nEDM, sports anthem\nEDM, synth-pop, C-pop\nEDM, synth-pop, Eurodance\nEDM, synth-pop, cyberpunk\nEDM, synth-pop, future bass\nEDM, synth-pop, hardstyle\nEDM, synth-pop, trance\nEDM, tech house, dance-pop\nEDM, tech-house, C-pop\nEDM, trance\nEDM, trance, Eurodance\nEDM, trance, Hindi pop\nEDM, trance, Khmer pop\nEDM, trance, Mandopop\nEDM, trance, Middle Eastern\nEDM, trance, Middle Eastern fusion\nEDM, trance, devotional\nEDM, trance, hands-up\nEDM, trance, happy hardcore\nEDM, trance, hard dance\nEDM, trance, hardstyle\nEDM, trance, pop\nEDM, trap, C-pop\nEDM, trap, Chinese pop\nEDM, trap, Indian bhajan\nEDM, trap, Indian devotional\nEDM, trap, Indian pop\nEDM, trap, Middle Eastern\nEDM, trap, South Asian fusion\nEDM, trap, bhajan\nEDM, trap, big room house\nEDM, trap, cinematic\nEDM, trap, devotional\nEDM, trap, future bass\nEDM, trap, hip-hop\nEDM, tribal house, cinematic\nEDM, tribal house, worldbeat\nEDM, tribal, cinematic\nEDM, world fusion\nEDM, world fusion, cinematic\nEDM, world fusion, electronic\nEDM, world music, Middle Eastern house\nEDM, worldbeat, football chant\nEDM, 喊麦\nEDM-pop\nEDM-pop Arabic hip-hop\nEDM-pop Bollywood\nEDM-pop C-pop\nEDM-pop Christmas\nEDM-pop Indian fusion\nEDM-pop Latin\nEDM-pop Middle Eastern fusion\nEDM-pop ballad\nEDM-pop electro-house\nEDM-pop future bass\nEDM-pop hip-hop\nEDM-pop progressive house\nEDM-pop trance\nEDM-pop world music\nEDM-pop, Balkan, Middle Eastern\nEDM-pop, Middle Eastern, Turkish\nEDM-pop, Middle Eastern, cinematic\nEDM-pop, South American folk\nEDM-pop, South Asian folk\nEDM-pop, South Asian fusion\nEDM-pop, future bass, C-pop\nEDM-pop, future bass, Mandarin pop\nEDM-pop, future bass, Vietnamese R&B\nEDM-pop, future bass, chiptune\nEDM-pop, future bass, cinematic\nEDM-pop, future bass, hip-hop\nEDM-pop, future bass, trap\nEDM-pop, future bass, world music\nEDM-pop, hardstyle\nEDM-pop, hardstyle, dubstep\nEDM-pop, hardstyle, trap\nEDM-pop, vaporwave, lo-fi hip-hop\nEDM-pop, world music, South Asian\nEDM-trap fusion\nEast African boom-bap\nEast African choral\nEast African folk\nEast African folk-pop\nEast African hip-hop\nEast African hip-hop flamenco fusion\nEast African pop\nEast Asian\nEast Asian ambient\nEast Asian cinematic\nEast Asian classical\nEast Asian folk\nEast Asian folk pop\nEast Asian folk, soft rock\nEast Asian fusion\nEast Asian hip-hop\nEast Asian instrumental\nEast Asian minimal\nEast Asian new age\nEast Asian percussion\nEast Asian pop\nEast Asian pop ballad\nEast Asian pop-rock\nEast Asian trap\nEast Asian, cinematic, lo-fi\nEast Coast boom-bap\nEast Coast club rap\nEast Coast drill\nEast Coast gangsta rap\nEast Coast hip hop\nEast Coast hip hop, cloud rap\nEast Coast hip-hop\nEast Coast hip-hop folk fusion\nEast Coast hip-hop funk-rock\nEast Coast hip-hop sea shanty\nEast Coast hip-hop trap\nEast Coast hip-hop, maritime folk\nEast Coast hip-hop, orchestral trap\nEast Coast hip-hop, trap\nEast Coast trap\nEast-Asian trap\nEastern European folk\nEastern European folk hip-hop\nEastern European folk rock\nEastern European folk, Soviet-era, theatrical\nEastern European folk, big band swing\nEastern European folk, classical, orchestral\nEastern European pop\nEastern European pop, chiptune\nEastern European pop, hip-hop\nEastern European pop-rock\nEastern European punk rock\nEastern European rock\nEastern ambient\nEastern folk\nEgyptian drill\nEgyptian hip-hop\nEgyptian hip-hop trap\nEgyptian pop\nEgyptian pop, Mahraganat\nEgyptian pop, Mahraganat, hip-hop\nEgyptian pop, cinematic, Arabic\nEgyptian pop-rap\nEgyptian rap\nEgyptian rap, chiptune, trap\nEgyptian trap\nEgyptian trap, Mahraganat\nEid music\nEmotional Trap\nEmotional trap\nEnglish folk\nEnka\nEnka Kayōkyoku\nEnka Sorendero\nEnka ballad\nEnka big band\nEnka blues-rock\nEnka cinematic\nEnka classical\nEnka festival\nEnka flamenco\nEnka folk-rock\nEnka fusion\nEnka hip-hop\nEnka jazz\nEnka jazz-rock\nEnka orchestral\nEnka orchestral pop\nEnka pop-rock\nEnka rock\nEnka salsa\nEnka, European folk\nEnka, Japanese Kayōkyoku\nEnka, Japanese ballad\nEnka, Japanese ballad, big band jazz\nEnka, Japanese festival, big band\nEnka, Japanese folk\nEnka, Japanese folk, big band\nEnka, Japanese pop, big-band\nEnka, Kayōkyoku\nEnka, Kayōkyoku, European folk\nEnka, Kayōkyoku, Japanese ballad\nEnka, Kayōkyoku, acoustic ballad\nEnka, Kayōkyoku, ballad\nEnka, Kayōkyoku, big band\nEnka, Kayōkyoku, cinematic\nEnka, Kayōkyoku, cinematic ballad\nEnka, Kayōkyoku, funk\nEnka, Kayōkyoku, jazz\nEnka, Kayōkyoku, live ballad\nEnka, Kayōkyoku, lo-fi\nEnka, Kayōkyoku, melancholic ballad\nEnka, Kayōkyoku, orchestral ballad\nEnka, Kayōkyoku, rock\nEnka, Kayōkyoku, rock-ballad\nEnka, Kayōkyoku, soulful jazz\nEnka, Kayōkyoku, synth\nEnka, Kayōkyoku, theatrical\nEnka, Kayōkyoku, theatrical rock\nEnka, Kayōkyoku, traditional East Asian\nEnka, Kayōkyoku, traditional Japanese\nEnka, Minyō, Japanese traditional\nEnka, Sorendero\nEnka, big band\nEnka, big band, Japanese folk\nEnka, big band, cinematic\nEnka, big band, festival\nEnka, big band, theatrical\nEnka, cinematic ballad\nEnka, cinematic ballad, Japanese Kayōkyoku\nEnka, cinematic ballad, Kayōkyoku\nEnka, cinematic ballad, blues-inflected\nEnka, cinematic ballad, blues-rock\nEnka, cinematic ballad, orchestral\nEnka, cinematic orchestral\nEnka, cinematic pop\nEnka, cinematic rock\nEnka, cinematic, Japanese ballad\nEnka, cinematic, Japanese pop\nEnka, cinematic, Kayōkyoku\nEnka, cinematic, acoustic\nEnka, cinematic, ambient\nEnka, cinematic, ballad\nEnka, cinematic, big band\nEnka, cinematic, brass\nEnka, cinematic, flamenco\nEnka, cinematic, orchestral\nEnka, cinematic, orchestral rock\nEnka, cinematic, solo violin\nEnka, cinematic, traditional\nEnka, cinematic, traditional East Asian\nEnka, cinematic, traditional Japanese\nEnka, dream pop\nEnka, electronic dance\nEnka, festival, Japanese\nEnka, flamenco, European folk\nEnka, flamenco, ballad\nEnka, flamenco, classical guitar\nEnka, funk, disco\nEnka, melancholic ballad\nEnka, melancholic, mandolin\nEnka, orchestral\nEnka, orchestral, Japanese narrative\nEnka, orchestral, cinematic\nEnka, orchestral, theatrical\nEnka, tango, cinematic ballad\nEnka, theatrical folk, marching band\nEnka, theatrical, cinematic\nEnka, traditional Chinese\nEnka, traditional Japanese folk\nEnka, traditional Japanese, cinematic\nEnka-rock\nEstonian hip-hop\nEstonian house\nEstonian trap\nEstrada\nEstrada pop\nEthio-Balkan dance\nEthio-dancehall\nEthio-disco\nEthio-funk\nEthio-pop\nEthiopian folk\nEthnic folk\nEtno\nEuro ballad\nEuro disco\nEuro pop\nEuro pop ballad\nEuro pop-rock\nEuro-Latin\nEuro-Schlager\nEuro-dance\nEuro-disco\nEuro-disco, disco polo\nEuro-folk\nEuro-folk dance-pop\nEuro-pop\nEuro-pop Italo-disco\nEuro-pop Latin\nEuro-pop R&B\nEuro-pop Schlager\nEuro-pop children's pop\nEuro-pop cinematic\nEuro-pop folk\nEuro-pop worldbeat\nEuro-pop, Latin dance, theatrical pop\nEuro-pop, Latin pop, pop\nEuro-pop, Schlager, Eurodance\nEuro-pop, Schlager, dance\nEuro-ska\nEuro-trance\nEuro-trance J-pop\nEuro-trance K-pop\nEurobeat\nEurobeat Italo disco\nEurobeat J-core\nEurobeat J-pop\nEurobeat J-pop fusion\nEurobeat J-pop trance\nEurobeat J-pop video game\nEurobeat J-rock\nEurobeat K-pop\nEurobeat K-pop fusion\nEurobeat arcade rock\nEurobeat children's\nEurobeat chiptune\nEurobeat happy hardcore\nEurobeat hard rock\nEurobeat lo-fi\nEurobeat orchestral\nEurobeat power metal\nEurobeat rock\nEurobeat trance\nEurobeat trance-pop\nEurobeat, 90s J-pop, synthwave\nEurobeat, J-core\nEurobeat, J-pop\nEurobeat, J-pop, cinematic\nEurobeat, J-rock, hardstyle\nEurobeat, Japanese video game music\nEurobeat, K-pop\nEurobeat, Tibetan fusion, video game music\nEurobeat, Trance, Anime\nEurobeat, Trance, Japanese pop\nEurobeat, chiptune\nEurobeat, chiptune, J-pop\nEurobeat, chiptune, dance-pop\nEurobeat, chiptune, synthwave\nEurobeat, cinematic, C-pop\nEurobeat, cinematic, synthwave\nEurobeat, cinematic, video game\nEurobeat, happy hardcore\nEurobeat, happy hardcore, chiptune\nEurobeat, happy hardcore, video game music\nEurobeat, house\nEurobeat, trance\nEurobeat, trance, J-pop\nEurobeat, trot\nEurobeat, video game music\nEurodance\nEurodance 90s\nEurodance Afro-Latin\nEurodance Anatolian rock\nEurodance Arabic\nEurodance Arabic pop\nEurodance Balkan\nEurodance Balkan folk\nEurodance Balkan fusion\nEurodance Balkan pop\nEurodance Balkan pop-folk\nEurodance Balkan pop-rock\nEurodance Bengali pop\nEurodance Bhangra\nEurodance Bhangra Bollywood\nEurodance Bollywood\nEurodance Bollywood pop\nEurodance Bollywood-pop\nEurodance C-pop\nEurodance C-pop J-pop\nEurodance C-pop chiptune\nEurodance C-pop fusion\nEurodance C-pop happy hardcore\nEurodance C-pop oriental\nEurodance C-pop trance\nEurodance C-pop video game\nEurodance Cantopop\nEurodance Chalga\nEurodance Christmas\nEurodance Christmas pop\nEurodance Cumbia Bollywood\nEurodance Dancehall\nEurodance Deutschrock\nEurodance EBM darkwave\nEurodance EBM industrial\nEurodance EBM techno\nEurodance EDM\nEurodance Flamenco\nEurodance French House\nEurodance French house\nEurodance German Schlager\nEurodance German hip-hop\nEurodance Gipsy-Pop\nEurodance Hands Up\nEurodance Hi-NRG\nEurodance Indian folk\nEurodance Indian fusion\nEurodance Indian pop\nEurodance Italo dance\nEurodance Italo disco\nEurodance Italo house\nEurodance Italo-disco\nEurodance J-pop\nEurodance J-pop Latin pop\nEurodance J-pop Middle Eastern\nEurodance J-pop anime\nEurodance J-pop chiptune\nEurodance J-pop fusion\nEurodance J-pop happy hardcore\nEurodance J-pop trance\nEurodance J-pop video game\nEurodance J-rock\nEurodance K-pop\nEurodance K-pop fusion\nEurodance K-pop happy hardcore\nEurodance K-pop parody\nEurodance K-pop trance\nEurodance K-pop trot\nEurodance K-trot\nEurodance Kizomba\nEurodance Klezmer\nEurodance Kollywood\nEurodance Latin\nEurodance Latin House\nEurodance Latin dance-pop\nEurodance Latin freestyle\nEurodance Latin house\nEurodance Latin pop\nEurodance Mandopop\nEurodance Mandopop hardstyle\nEurodance Mandopop hip-hop\nEurodance Mandopop hip-house\nEurodance Mandopop synth-pop\nEurodance Manele\nEurodance Mizrahi\nEurodance Mizrahi pop\nEurodance Mongolian pop\nEurodance Persian\nEurodance Persian pop\nEurodance Pimba\nEurodance Punjabi pop\nEurodance R&B\nEurodance R&B dance-pop\nEurodance R&B pop\nEurodance Rai\nEurodance Russian pop\nEurodance Schlager\nEurodance Schlager-pop\nEurodance T-Pop\nEurodance Tamil pop\nEurodance Tibetan pop\nEurodance Tollywood\nEurodance Tollywood dance-pop\nEurodance Trance\nEurodance Turkish\nEurodance Turkish pop\nEurodance Turkish rock\nEurodance V-Pop\nEurodance V-Pop Vina House\nEurodance V-Pop trance\nEurodance V-pop\nEurodance anime\nEurodance bubblegum\nEurodance bubblegum pop\nEurodance cabaret\nEurodance children's\nEurodance children's music\nEurodance children's pop\nEurodance chiptune\nEurodance chiptune Arabic pop\nEurodance chiptune Bollywood\nEurodance chiptune Italo disco\nEurodance chiptune J-pop\nEurodance chiptune Persian\nEurodance chiptune Turkish pop\nEurodance chiptune bubblegum pop\nEurodance chiptune disco polo\nEurodance chiptune filmi\nEurodance chiptune folk\nEurodance chiptune folk-dance\nEurodance chiptune schlager\nEurodance chiptune sea shanty\nEurodance chiptune trance\nEurodance chiptune turbo-folk\nEurodance cinematic\nEurodance country\nEurodance country-dance\nEurodance dance-pop\nEurodance dancehall\nEurodance disco polo\nEurodance electro-pop\nEurodance flamenco\nEurodance folk\nEurodance folk fusion\nEurodance folk metal\nEurodance folk-pop\nEurodance football anthem\nEurodance funky house\nEurodance gospel\nEurodance gypsy jazz\nEurodance happy hardcore\nEurodance hard rock\nEurodance hard trance\nEurodance hardcore techno\nEurodance hardstyle\nEurodance hip hop\nEurodance hip-hop\nEurodance hip-hop pop\nEurodance hip-house\nEurodance horror\nEurodance house\nEurodance hyperpop\nEurodance hyperpop J-pop\nEurodance industrial metal\nEurodance industrial rock\nEurodance jungle\nEurodance kids\nEurodance kids' pop\nEurodance lo-fi\nEurodance novelty\nEurodance novelty pop\nEurodance orchestral\nEurodance polka\nEurodance pop\nEurodance pop-dance\nEurodance pop-funk\nEurodance pop-punk\nEurodance pop-rap\nEurodance pop-rock\nEurodance popsa\nEurodance power ballad\nEurodance power metal\nEurodance progressive house\nEurodance reggae dancehall\nEurodance reggae fusion\nEurodance reggaeton\nEurodance rock\nEurodance satire\nEurodance schlager\nEurodance surf rock\nEurodance synth-pop\nEurodance tango\nEurodance tech house\nEurodance tech-house\nEurodance trance\nEurodance trance-pop\nEurodance trap\nEurodance tropical\nEurodance tropical house\nEurodance trot\nEurodance turbo-folk\nEurodance world fusion\nEurodance world music\nEurodance worldbeat\nEurodance worship\nEurodance, 2000s Russian pop\nEurodance, 90s Bollywood\nEurodance, 90s German pop\nEurodance, 90s R&B\nEurodance, 90s Russian pop\nEurodance, 90s Trance\nEurodance, 90s Trance, Chiptune\nEurodance, 90s Trance, Cinematic\nEurodance, 90s Zumba\nEurodance, 90s dance, South Asian pop\nEurodance, 90s dance-pop, children's music\nEurodance, 90s happy hardcore\nEurodance, 90s pop, novelty\nEurodance, Anatolian, Middle Eastern\nEurodance, Arabic pop\nEurodance, Arabic pop, Middle Eastern\nEurodance, Arabic pop, Middle Eastern house\nEurodance, Arabic pop, cinematic\nEurodance, Arabic pop, trance\nEurodance, Arabic synth, cinematic\nEurodance, Arabic, dance\nEurodance, Armenian folk\nEurodance, Axé\nEurodance, Azerbaijani pop\nEurodance, Balkan folk\nEurodance, Balkan folk, cinematic\nEurodance, Balkan folk, hard rock\nEurodance, Balkan fusion, reggaeton\nEurodance, Balkan pop\nEurodance, Balkan pop, Chalga\nEurodance, Balkan pop, Manele\nEurodance, Balkan pop, chiptune\nEurodance, Balkan pop, dance-pop\nEurodance, Balkan pop, dancehall\nEurodance, Balkan, Middle Eastern\nEurodance, Balkan, Turkish pop\nEurodance, Balkan, dance\nEurodance, Balkan, electronic\nEurodance, Balkan, hardstyle\nEurodance, Bhangra, Bollywood\nEurodance, Bhangra, Dancehall\nEurodance, Bollywood filmi, Christian devotional\nEurodance, Bollywood fusion\nEurodance, Bollywood pop\nEurodance, Bollywood, 90s dance\nEurodance, Bollywood, Bhojpuri\nEurodance, Bollywood, Middle Eastern\nEurodance, Bollywood, Trance\nEurodance, Bollywood, chiptune\nEurodance, Bollywood, dance\nEurodance, Bollywood, dance-pop\nEurodance, Bollywood, psytrance\nEurodance, Bollywood, trance\nEurodance, Brazilian\nEurodance, Brazilian Carnival\nEurodance, Brazilian Funkot, C-pop\nEurodance, Brazilian dance-pop\nEurodance, Brazilian electronic\nEurodance, Brazilian folk\nEurodance, Brazilian funk\nEurodance, Brazilian funk, breakbeat\nEurodance, Brazilian funk, happy hardcore\nEurodance, Brazilian funk, house\nEurodance, Brazilian pop\nEurodance, Brazilian, 90s dance\nEurodance, Brazilian, Trance\nEurodance, C-pop\nEurodance, C-pop, J-pop\nEurodance, C-pop, cinematic\nEurodance, C-pop, dance remix\nEurodance, C-pop, dance-pop\nEurodance, C-pop, electronic\nEurodance, C-pop, orchestral\nEurodance, C-pop, traditional South Asian\nEurodance, C-pop, traditional fusion\nEurodance, C-pop, trance\nEurodance, Cantopop\nEurodance, Cantopop, Trance\nEurodance, Cantopop, electronic dance\nEurodance, Cantopop, happy hardcore\nEurodance, Cantopop, rave\nEurodance, Caucasian folk\nEurodance, Central Asian folk\nEurodance, Central Asian folk, chiptune\nEurodance, Central Asian folk, dance-pop\nEurodance, Central Asian fusion\nEurodance, Central Asian pop\nEurodance, Central Asian pop, retro synth\nEurodance, Central Asian, Middle Eastern\nEurodance, Central Asian, Uzbek pop\nEurodance, Central Asian, dance\nEurodance, Central Asian, dance-pop\nEurodance, Central Asian, synthpop\nEurodance, Chinese DJ mix\nEurodance, Chinese DJ remix\nEurodance, Chinese DJ remix, early 2000s\nEurodance, Chinese DJ, Trance\nEurodance, Chinese MC, dance\nEurodance, Chinese New Year\nEurodance, Chinese New Year, 90s dance\nEurodance, Chinese New Year, dance\nEurodance, Chinese New Year, dance-pop\nEurodance, Chinese club\nEurodance, Chinese dance-pop\nEurodance, Chinese disco\nEurodance, Chinese disco, early 2000s\nEurodance, Chinese folk\nEurodance, Chinese folk-pop, disco-pop\nEurodance, Chinese fusion\nEurodance, Chinese hǎnmài\nEurodance, Chinese pop\nEurodance, Chinese pop-dance\nEurodance, Christian pop\nEurodance, Christmas\nEurodance, Christmas novelty\nEurodance, Christmas pop\nEurodance, Christmas, 90s dance-pop\nEurodance, Christmas, 90s happy hardcore\nEurodance, Christmas, Vocaloid\nEurodance, Christmas, comedic\nEurodance, Christmas, dance-pop\nEurodance, Christmas, happy hardcore\nEurodance, Christmas, high-energy\nEurodance, Christmas, novelty\nEurodance, Christmas, synth-pop\nEurodance, Christmas, synthpop\nEurodance, Christmas, upbeat\nEurodance, City Pop\nEurodance, City Pop, early house\nEurodance, Czech Schlager\nEurodance, Czech pop\nEurodance, Czech pop, retro\nEurodance, Dangdut Koplo\nEurodance, Danish pop\nEurodance, Disco Polo\nEurodance, Disco Polo, Polish rap\nEurodance, Dutch Carnaval, pop\nEurodance, Dutch House, Trance\nEurodance, Dutch Schlager\nEurodance, Dutch schlager, dance-pop\nEurodance, EBM, techno\nEurodance, EDM, C-pop\nEurodance, EDM, pop-dance\nEurodance, East Asian fusion\nEurodance, Eastern European pop\nEurodance, Eastern European pop, Turkish pop\nEurodance, Eastern European, dance\nEurodance, Filipino Christmas, dance-pop\nEurodance, Finnish Schlager\nEurodance, Finnish schlager\nEurodance, French house\nEurodance, French house, cinematic pop\nEurodance, French pop\nEurodance, French rap, club\nEurodance, German Schlager\nEurodance, German Schlager-pop\nEurodance, German hip-hop\nEurodance, German pop\nEurodance, German rap\nEurodance, German techno\nEurodance, Greek folk, pop\nEurodance, Greek pop\nEurodance, Greek pop-rap\nEurodance, Gypsy Folk, Hungarian Dance-Pop\nEurodance, Gypsy Pop, Hungarian Folk\nEurodance, Halloween, campy\nEurodance, Hands Up\nEurodance, Hands Up, Hardstyle\nEurodance, Happy Hardcore\nEurodance, Hardstyle, Trance\nEurodance, Hi-NRG\nEurodance, Hi-NRG, 90s dance\nEurodance, Hi-NRG, Latin pop\nEurodance, Hi-NRG, dance-pop\nEurodance, Hi-NRG, synthpop\nEurodance, Hindi pop\nEurodance, Hungarian Schlager\nEurodance, Hungarian folk\nEurodance, Hungarian pop\nEurodance, Hungarian pop, Romani\nEurodance, Indian bhajan\nEurodance, Indian devotional, trance\nEurodance, Indian electronic, dance\nEurodance, Indian filmi, dance\nEurodance, Indian fusion\nEurodance, Indian pop, rock\nEurodance, Israeli pop\nEurodance, Israeli pop, dance-pop\nEurodance, Italian pop\nEurodance, Italo dance\nEurodance, Italo dance, Latin dance\nEurodance, Italo dance, Zouk\nEurodance, Italo dance, happy hardcore\nEurodance, Italo dance, pop\nEurodance, Italo dance, synthwave\nEurodance, Italo dance, trance\nEurodance, Italo disco\nEurodance, Italo disco, 90s dance\nEurodance, Italo disco, Cantopop\nEurodance, Italo disco, Disco Polo\nEurodance, Italo disco, Eastern European pop\nEurodance, Italo disco, Hungarian pop\nEurodance, Italo disco, Polish Disco Polo\nEurodance, Italo disco, chiptune\nEurodance, Italo disco, cinematic\nEurodance, Italo disco, dance\nEurodance, Italo disco, disco polo\nEurodance, Italo disco, folk fusion\nEurodance, Italo disco, folk-pop\nEurodance, Italo disco, novelty\nEurodance, Italo disco, synth-pop\nEurodance, Italo disco, synthpop\nEurodance, Italo disco, synthwave\nEurodance, Italo house\nEurodance, Italo-disco\nEurodance, Italo-disco, 90s dance\nEurodance, Italo-disco, Romanian pop\nEurodance, Italo-disco, Schlager\nEurodance, J-core\nEurodance, J-core, happy hardcore\nEurodance, J-core, trance\nEurodance, J-pop\nEurodance, J-pop, City Pop\nEurodance, J-pop, Eurobeat\nEurodance, J-pop, Russian\nEurodance, J-pop, Trance\nEurodance, J-pop, anime\nEurodance, J-pop, chiptune\nEurodance, J-pop, cinematic\nEurodance, J-pop, dance-pop\nEurodance, J-pop, folk\nEurodance, J-pop, happy hardcore\nEurodance, J-pop, hyperpop\nEurodance, J-pop, trance\nEurodance, Japanese dance music\nEurodance, K-pop\nEurodance, K-pop, R&B\nEurodance, K-pop, chiptune\nEurodance, K-pop, happy hardcore\nEurodance, K-pop, retro-futuristic\nEurodance, K-pop, trot\nEurodance, K-trot\nEurodance, Kollywood, Christian pop\nEurodance, Korean trot\nEurodance, Kurdish pop\nEurodance, Kurdish, Middle Eastern\nEurodance, Kuthu\nEurodance, Latin Cumbia\nEurodance, Latin electronic\nEurodance, Latin house\nEurodance, Latin pop\nEurodance, Latin pop, Schlager\nEurodance, Latin pop, chiptune\nEurodance, Latin pop, cinematic\nEurodance, Latin pop, complextro\nEurodance, Latin pop, merengue\nEurodance, Latin pop, pop\nEurodance, Latin pop, reggaeton\nEurodance, Latin pop, salsa\nEurodance, Latin pop, trance\nEurodance, Latin pop, world music\nEurodance, Latin tech-house\nEurodance, Latin, Dancehall\nEurodance, Latin, Dutch House\nEurodance, Latin, Middle Eastern\nEurodance, Latin, Samba\nEurodance, Latin, Schlager\nEurodance, Latin, Trance\nEurodance, Latin, Vietnamese pop\nEurodance, Latin, children's music\nEurodance, Latin, chiptune\nEurodance, Latin, dance\nEurodance, Latin, tropical\nEurodance, Latin, worldbeat\nEurodance, Laïko\nEurodance, Laïko, dance\nEurodance, Malay traditional, cinematic\nEurodance, Mandarin pop, cinematic\nEurodance, Mandopop\nEurodance, Mandopop, EDM\nEurodance, Mandopop, Hardstyle\nEurodance, Mandopop, Trance\nEurodance, Mandopop, dance remix\nEurodance, Mandopop, dance-pop\nEurodance, Mandopop, electronic\nEurodance, Mandopop, hardstyle\nEurodance, Mandopop, hip hop\nEurodance, Mandopop, hip-hop\nEurodance, Manele\nEurodance, Melbourne bounce, Schlager\nEurodance, Middle Eastern\nEurodance, Middle Eastern folk\nEurodance, Middle Eastern folk, cinematic\nEurodance, Middle Eastern fusion\nEurodance, Middle Eastern fusion, cinematic pop\nEurodance, Middle Eastern fusion, hip-hop\nEurodance, Middle Eastern pop\nEurodance, Middle Eastern pop, Eastern European pop\nEurodance, Middle Eastern pop, Israeli pop\nEurodance, Middle Eastern trance\nEurodance, Middle Eastern, 90s dance\nEurodance, Middle Eastern, Armenian folk\nEurodance, Middle Eastern, Balkan\nEurodance, Middle Eastern, Bollywood\nEurodance, Middle Eastern, Eastern European\nEurodance, Middle Eastern, Klezmer\nEurodance, Middle Eastern, Kurdish\nEurodance, Middle Eastern, Persian\nEurodance, Middle Eastern, Trance\nEurodance, Middle Eastern, Turkish\nEurodance, Middle Eastern, Turkish pop\nEurodance, Middle Eastern, anthemic\nEurodance, Middle Eastern, cinematic\nEurodance, Middle Eastern, dance\nEurodance, Middle Eastern, electronic\nEurodance, Middle Eastern, hardstyle\nEurodance, Middle Eastern, lo-fi\nEurodance, Middle Eastern, pop\nEurodance, Middle Eastern, trance\nEurodance, Mizrahi pop\nEurodance, Mizrahi, 90s synth\nEurodance, Mizrahi, Arabic pop\nEurodance, Mizrahi, Trance\nEurodance, Mizrahi, chiptune\nEurodance, Mizrahi, electronic\nEurodance, Mizrahi-pop\nEurodance, Mongolian folk\nEurodance, North African pop\nEurodance, North African, Arabic pop\nEurodance, Oud, cinematic\nEurodance, Pansori, K-pop\nEurodance, Partyschlager\nEurodance, Partyschlager, Pirate Theme\nEurodance, Persian pop\nEurodance, Persian, Middle Eastern\nEurodance, Persian, Trance\nEurodance, Persian, cinematic\nEurodance, Persian, electronic\nEurodance, Pimba, Portuguese pop\nEurodance, Pimba, dance\nEurodance, Polish Disco Polo\nEurodance, Polish folk\nEurodance, Polish pop\nEurodance, Portuguese pop\nEurodance, Portuguese pop, pimba\nEurodance, R&B\nEurodance, R&B, dance-pop\nEurodance, Raï, pop\nEurodance, Romanian Manele\nEurodance, Romanian Manele, dance-pop\nEurodance, Romanian folk\nEurodance, Romanian folk, dance\nEurodance, Romanian folk, synthpop\nEurodance, Romanian party\nEurodance, Romanian party music\nEurodance, Romanian pop\nEurodance, Romanian pop, dance-pop\nEurodance, Romanian rap\nEurodance, Russian Estrada, theatrical pop\nEurodance, Russian chanson\nEurodance, Russian chanson, folk fusion\nEurodance, Russian chanson, theatrical pop\nEurodance, Russian estrada\nEurodance, Russian folk\nEurodance, Russian folk, anthemic\nEurodance, Russian folk, chiptune\nEurodance, Russian folk, dance\nEurodance, Russian folk, hip-hop\nEurodance, Russian folk, techno\nEurodance, Russian pop\nEurodance, Russian pop, 2000s\nEurodance, Russian pop, 2000s dance\nEurodance, Russian pop, 2000s pop\nEurodance, Russian pop, 90s dance\nEurodance, Russian pop, 90s synth\nEurodance, Russian pop, Eastern European\nEurodance, Russian pop, chiptune\nEurodance, Russian pop, comedic\nEurodance, Russian pop, dance\nEurodance, Russian pop, early 2000s\nEurodance, Russian pop, folk-dance\nEurodance, Russian pop, folk-electronic\nEurodance, Russian pop, happy hardcore\nEurodance, Russian pop, hip-house\nEurodance, Russian pop, lo-fi\nEurodance, Russian pop, novelty\nEurodance, Russian pop, retro\nEurodance, Russian pop, synthwave\nEurodance, Russian pop, theatrical pop\nEurodance, Russian pop-dance\nEurodance, Russian pop-rap\nEurodance, Russian pop-rock\nEurodance, Schlager\nEurodance, Schlager, 90s\nEurodance, Schlager, 90s dance\nEurodance, Schlager, Christmas\nEurodance, Schlager, Czech pop\nEurodance, Schlager, Dutch party\nEurodance, Schlager, Dutch pop\nEurodance, Schlager, German pop\nEurodance, Schlager, Latin pop\nEurodance, Schlager, Metal\nEurodance, Schlager, Party\nEurodance, Schlager, Sci-Fi\nEurodance, Schlager, Western\nEurodance, Schlager, children's music\nEurodance, Schlager, chiptune\nEurodance, Schlager, dance\nEurodance, Schlager, dance pop\nEurodance, Schlager, electronic\nEurodance, Schlager, football chant\nEurodance, Schlager, happy hardcore\nEurodance, Schlager, novelty\nEurodance, Schlager, novelty pop\nEurodance, Schlager, party\nEurodance, Schlager-pop\nEurodance, Schlager-pop, cinematic\nEurodance, Slavic folk\nEurodance, South African fusion\nEurodance, South Asian pop\nEurodance, South Asian, dance\nEurodance, South Indian filmi\nEurodance, South Indian, electronic\nEurodance, Southeast Asian pop\nEurodance, Spanish-style, trance\nEurodance, Swiss House\nEurodance, T-Pop\nEurodance, Tamil film music, retro-futuristic\nEurodance, Techno, Ballad\nEurodance, Thai pop\nEurodance, Tibetan ambient\nEurodance, Tibetan pop\nEurodance, Tollywood, Christian\nEurodance, Trance\nEurodance, Trance, 2000s\nEurodance, Trance, 2000s EDM\nEurodance, Trance, 2000s dance\nEurodance, Trance, Ancient Style\nEurodance, Trance, Arabic Pop\nEurodance, Trance, Big Room House\nEurodance, Trance, Bilingual\nEurodance, Trance, Bollywood\nEurodance, Trance, C-pop\nEurodance, Trance, Central Asian\nEurodance, Trance, Central Asian Pop\nEurodance, Trance, Chinese DJ Remix\nEurodance, Trance, Chinese Electronic\nEurodance, Trance, Chiptune\nEurodance, Trance, Choral\nEurodance, Trance, Cinematic\nEurodance, Trance, Cinematic Pop\nEurodance, Trance, Dance-Pop\nEurodance, Trance, Dance-pop\nEurodance, Trance, Dutch House\nEurodance, Trance, Folk\nEurodance, Trance, Future Dance\nEurodance, Trance, Gothic\nEurodance, Trance, Hands-up\nEurodance, Trance, Happy Hardcore\nEurodance, Trance, Hard Dance\nEurodance, Trance, Hard Rock\nEurodance, Trance, Hardstyle\nEurodance, Trance, Hip-House\nEurodance, Trance, House\nEurodance, Trance, J-pop\nEurodance, Trance, K-pop\nEurodance, Trance, Latin dance-pop\nEurodance, Trance, Lo-fi\nEurodance, Trance, Mandopop\nEurodance, Trance, Middle Eastern\nEurodance, Trance, Middle Eastern fusion\nEurodance, Trance, Persian\nEurodance, Trance, Persian Pop\nEurodance, Trance, Persian pop\nEurodance, Trance, Pop\nEurodance, Trance, R&B\nEurodance, Trance, Rock\nEurodance, Trance, Russian Estrada\nEurodance, Trance, Synth-Orchestral\nEurodance, Trance, Tibetan pop\nEurodance, Trance, Turkish\nEurodance, Trance, Turkish Pop\nEurodance, Trance, Turkish folk-pop\nEurodance, Trance, Turkish pop\nEurodance, Trance, Video Game Music\nEurodance, Trance, Vietnamese pop\nEurodance, Trance, Vocaloid\nEurodance, Trance, World Music\nEurodance, Trance-pop\nEurodance, Trance-pop, Cinematic\nEurodance, Turkish folk\nEurodance, Turkish folk, Azerbaijani pop\nEurodance, Turkish folk, Russian vocal\nEurodance, Turkish folk, cinematic\nEurodance, Turkish folk, electronic\nEurodance, Turkish fusion, Middle Eastern\nEurodance, Turkish military march\nEurodance, Turkish pop\nEurodance, Turkish pop, 80s synth\nEurodance, Turkish pop, Arabesque\nEurodance, Turkish pop, Azerbaijani pop\nEurodance, Turkish pop, Balkan pop\nEurodance, Turkish pop, Eastern European\nEurodance, Turkish pop, Eastern European pop\nEurodance, Turkish pop, Middle Eastern\nEurodance, Turkish pop, Middle Eastern electronic\nEurodance, Turkish pop, Middle Eastern fusion\nEurodance, Turkish pop, Middle Eastern pop\nEurodance, Turkish pop, cinematic\nEurodance, Turkish pop, dance\nEurodance, Turkish pop, dance-pop\nEurodance, Turkish pop, electronic\nEurodance, Turkish pop, hardstyle\nEurodance, Turkish pop, hip-hop\nEurodance, Turkish pop, pop-dance\nEurodance, Turkish pop, retro pop\nEurodance, Turkish pop, synthwave\nEurodance, Turkish pop, trance\nEurodance, Turkish pop-rock, stadium anthem\nEurodance, Turkish, Balkan\nEurodance, Turkish, Middle Eastern\nEurodance, Ukrainian folk\nEurodance, Ukrainian folk, dance\nEurodance, Ukrainian folk, dance-pop\nEurodance, Ukrainian folk, synthwave\nEurodance, V-Pop\nEurodance, V-Pop, 2000s dance-pop\nEurodance, V-Pop, 90s dance\nEurodance, V-Pop, Hands Up\nEurodance, V-Pop, Trance\nEurodance, V-Pop, Vinahouse\nEurodance, V-Pop, chiptune\nEurodance, V-Pop, cinematic\nEurodance, V-Pop, dance-pop\nEurodance, V-Pop, happy hardcore\nEurodance, V-Pop, pop\nEurodance, V-Pop, retro\nEurodance, V-Pop, traditional Vietnamese\nEurodance, V-Pop, trance\nEurodance, V-pop\nEurodance, V-pop, Vietnamese folk-pop\nEurodance, Vietnamese pop\nEurodance, Vietnamese pop, R&B\nEurodance, Vietnamese pop, retro-futuristic\nEurodance, Vocaloid, happy hardcore\nEurodance, Zouk, Kizomba\nEurodance, acid trance\nEurodance, adult contemporary\nEurodance, ambient, chiptune\nEurodance, arcade, synthwave\nEurodance, big beat, cinematic\nEurodance, big beat, cinematic electronic\nEurodance, big room house\nEurodance, bubblegum pop\nEurodance, bubblegum pop, children's music\nEurodance, calypso, pop-rock\nEurodance, chanson paillarde\nEurodance, children's choir, dance-pop\nEurodance, children's music\nEurodance, children's music, 90s happy hardcore\nEurodance, children's music, Christmas\nEurodance, children's music, Dutch pop\nEurodance, children's music, dance\nEurodance, children's music, festive\nEurodance, children's music, novelty\nEurodance, children's music, retro Vietnamese\nEurodance, children's pop\nEurodance, children's pop, Dutch pop\nEurodance, children's pop, Italian pop\nEurodance, children's pop, Russian pop\nEurodance, children's pop, Vietnamese pop\nEurodance, chiptune\nEurodance, chiptune, 90s dance-pop\nEurodance, chiptune, Bollywood\nEurodance, chiptune, C-pop\nEurodance, chiptune, Disco Polo\nEurodance, chiptune, Hi-NRG\nEurodance, chiptune, Italo disco\nEurodance, chiptune, J-core\nEurodance, chiptune, J-pop\nEurodance, chiptune, Mandarin pop\nEurodance, chiptune, Russian pop\nEurodance, chiptune, Schlagerpop\nEurodance, chiptune, V-Pop\nEurodance, chiptune, V-pop\nEurodance, chiptune, bubblegum dance\nEurodance, chiptune, children's music\nEurodance, chiptune, dance-pop\nEurodance, chiptune, disco polo\nEurodance, chiptune, electronic\nEurodance, chiptune, happy hardcore\nEurodance, chiptune, hardstyle\nEurodance, chiptune, hip-house\nEurodance, chiptune, lo-fi electronic\nEurodance, chiptune, novelty\nEurodance, chiptune, pop\nEurodance, chiptune, rave\nEurodance, chiptune, reggaeton\nEurodance, chiptune, synthpop\nEurodance, chiptune, trance\nEurodance, chiptune, video game\nEurodance, chiptune, worldbeat\nEurodance, choral, Christmas\nEurodance, choral, ambient\nEurodance, cinematic\nEurodance, cinematic folk, C-pop\nEurodance, cinematic orchestral\nEurodance, cinematic pop\nEurodance, cinematic pop, Eastern European dance-pop\nEurodance, cinematic pop, folk fusion\nEurodance, cinematic pop, world fusion\nEurodance, cinematic synth\nEurodance, cinematic synth, Mongolian pop\nEurodance, cinematic synth, dance-pop\nEurodance, cinematic synth, orchestral\nEurodance, cinematic synth, retro game\nEurodance, cinematic synth, spy thriller\nEurodance, cinematic, Arabic fusion\nEurodance, cinematic, Balkan fusion\nEurodance, cinematic, Balkan pop\nEurodance, cinematic, C-pop\nEurodance, cinematic, Central Asian\nEurodance, cinematic, Chinese-style\nEurodance, cinematic, Eastern European\nEurodance, cinematic, Eastern fusion\nEurodance, cinematic, Greek\nEurodance, cinematic, Hungarian pop\nEurodance, cinematic, J-pop\nEurodance, cinematic, K-pop\nEurodance, cinematic, Mandarin pop\nEurodance, cinematic, Middle Eastern\nEurodance, cinematic, Middle Eastern fusion\nEurodance, cinematic, Mizrahi pop\nEurodance, cinematic, Mongolian pop\nEurodance, cinematic, Persian\nEurodance, cinematic, Persian pop\nEurodance, cinematic, Russian pop\nEurodance, cinematic, Russian theatrical\nEurodance, cinematic, Turkish folk\nEurodance, cinematic, Turkish fusion\nEurodance, cinematic, Vietnamese pop\nEurodance, cinematic, ambient\nEurodance, cinematic, anthemic\nEurodance, cinematic, diva house\nEurodance, cinematic, duduk\nEurodance, cinematic, electronic\nEurodance, cinematic, emotional\nEurodance, cinematic, fantasy\nEurodance, cinematic, folk fusion\nEurodance, cinematic, folk rock\nEurodance, cinematic, happy hardcore\nEurodance, cinematic, hardstyle\nEurodance, cinematic, liturgical\nEurodance, cinematic, operatic\nEurodance, cinematic, orchestral\nEurodance, cinematic, oud\nEurodance, cinematic, polka\nEurodance, cinematic, pop\nEurodance, cinematic, retro-futuristic\nEurodance, cinematic, rock\nEurodance, cinematic, synthpop\nEurodance, cinematic, synthwave\nEurodance, cinematic, theatrical\nEurodance, cinematic, trance\nEurodance, cinematic, world fusion\nEurodance, classical fusion\nEurodance, club, multilingual\nEurodance, comedy, Christmas parody\nEurodance, dance-pop\nEurodance, dance-pop, 90s style\nEurodance, dance-pop, C-pop\nEurodance, dance-pop, Czech hip hop\nEurodance, dance-pop, J-pop\nEurodance, dance-pop, cinematic\nEurodance, dance-pop, electronic\nEurodance, dance-pop, folktronica\nEurodance, dance-pop, world music\nEurodance, dancehall, lo-fi hip hop\nEurodance, dancehall, pop\nEurodance, dancehall, reggae\nEurodance, dansband, schlager\nEurodance, dark wave, theatrical\nEurodance, darkwave, cinematic\nEurodance, disco polo\nEurodance, disco polo, children's music\nEurodance, disco polo, chiptune\nEurodance, disco polo, happy hardcore\nEurodance, disco polo, novelty\nEurodance, disco, Czech pop\nEurodance, diva house, 90s dance\nEurodance, early 2000s pop, Central Asian pop\nEurodance, early house\nEurodance, early trance\nEurodance, festive, satirical\nEurodance, flamenco, Kazakh pop\nEurodance, flamenco, Turkish pop\nEurodance, folk dance\nEurodance, folk dance, Tatar\nEurodance, folk electronic\nEurodance, folk fusion\nEurodance, folk fusion, dance-pop\nEurodance, folk pop\nEurodance, folk, Central Asian\nEurodance, folk, K-pop\nEurodance, folk, cabaret\nEurodance, folk, chanson\nEurodance, folk, chiptune\nEurodance, folk, comedic\nEurodance, folk, dance\nEurodance, folk, electronic\nEurodance, folk, energetic\nEurodance, folk, hardstyle\nEurodance, folk, klezmer\nEurodance, folk, polka\nEurodance, folk, rock\nEurodance, folk, schlager\nEurodance, folk, synth\nEurodance, folk, synthpop\nEurodance, folk-dance\nEurodance, folk-influenced, high-energy\nEurodance, folk-infused dance-pop, atmospheric trance\nEurodance, folk-pop, cinematic\nEurodance, folk-pop, synth-rock\nEurodance, forró, dance\nEurodance, future bass, progressive house\nEurodance, futurepop\nEurodance, happy hardcore\nEurodance, happy hardcore, 90s dance\nEurodance, happy hardcore, C-pop\nEurodance, happy hardcore, Cantopop\nEurodance, happy hardcore, Chinese New Year\nEurodance, happy hardcore, Christmas\nEurodance, happy hardcore, Christmas ballad\nEurodance, happy hardcore, Dutch\nEurodance, happy hardcore, Dutch carnaval\nEurodance, happy hardcore, Dutch pop\nEurodance, happy hardcore, Euro-trance\nEurodance, happy hardcore, Finnish schlager\nEurodance, happy hardcore, German Schlager\nEurodance, happy hardcore, Hungarian Schlager\nEurodance, happy hardcore, J-core\nEurodance, happy hardcore, J-pop\nEurodance, happy hardcore, J-rock\nEurodance, happy hardcore, K-pop\nEurodance, happy hardcore, Latin techno\nEurodance, happy hardcore, Melbourne bounce\nEurodance, happy hardcore, Russian folk\nEurodance, happy hardcore, Russian party\nEurodance, happy hardcore, Schlager\nEurodance, happy hardcore, Schlager-pop\nEurodance, happy hardcore, Spanish-style\nEurodance, happy hardcore, Vocaloid\nEurodance, happy hardcore, ballad\nEurodance, happy hardcore, bubblegum dance\nEurodance, happy hardcore, children's music\nEurodance, happy hardcore, children's pop\nEurodance, happy hardcore, chiptune\nEurodance, happy hardcore, cinematic\nEurodance, happy hardcore, dancehall\nEurodance, happy hardcore, disco polo\nEurodance, happy hardcore, dubstep\nEurodance, happy hardcore, electro house\nEurodance, happy hardcore, flamenco\nEurodance, happy hardcore, folk\nEurodance, happy hardcore, folk electronic\nEurodance, happy hardcore, funkot\nEurodance, happy hardcore, gabber\nEurodance, happy hardcore, gospel\nEurodance, happy hardcore, hardstyle\nEurodance, happy hardcore, hip-house\nEurodance, happy hardcore, hyperpop\nEurodance, happy hardcore, industrial\nEurodance, happy hardcore, industrial rock\nEurodance, happy hardcore, iskelmä\nEurodance, happy hardcore, levenslied\nEurodance, happy hardcore, lo-fi hip hop\nEurodance, happy hardcore, nightcore\nEurodance, happy hardcore, novelty\nEurodance, happy hardcore, novelty Christmas\nEurodance, happy hardcore, novelty dance\nEurodance, happy hardcore, operatic pop\nEurodance, happy hardcore, party music\nEurodance, happy hardcore, polka\nEurodance, happy hardcore, pop\nEurodance, happy hardcore, power ballad\nEurodance, happy hardcore, ragtime pop\nEurodance, happy hardcore, rave\nEurodance, happy hardcore, retro electronic\nEurodance, happy hardcore, rock\nEurodance, happy hardcore, schlager\nEurodance, happy hardcore, sea shanty\nEurodance, happy hardcore, synthwave\nEurodance, happy hardcore, trance\nEurodance, happy hardcore, video game\nEurodance, happy hardcore, video game music\nEurodance, hard dance\nEurodance, hard dance, C-pop\nEurodance, hard house\nEurodance, hard rock, trance\nEurodance, hard trance\nEurodance, hard trance, dance-pop\nEurodance, hardbass\nEurodance, hardcore techno, folk pop\nEurodance, hardstyle\nEurodance, hardstyle, C-pop\nEurodance, hardstyle, Chinese\nEurodance, hardstyle, EDM\nEurodance, hardstyle, German electronic pop\nEurodance, hardstyle, German hip-hop\nEurodance, hardstyle, Italo dance\nEurodance, hardstyle, Mandarin pop\nEurodance, hardstyle, Mandopop\nEurodance, hardstyle, Middle Eastern\nEurodance, hardstyle, chiptune\nEurodance, hardstyle, cinematic\nEurodance, hardstyle, cinematic pop\nEurodance, hardstyle, electronic\nEurodance, hardstyle, gabber\nEurodance, hardstyle, happy hardcore\nEurodance, hardstyle, pop\nEurodance, hardstyle, pop ballad\nEurodance, hardstyle, rave\nEurodance, hardstyle, techno\nEurodance, hardstyle, trance\nEurodance, hardstyle, trance-pop\nEurodance, hardstyle, tropical jungle\nEurodance, hip house\nEurodance, hip-hop, Russian pop\nEurodance, hip-hop, ambient\nEurodance, hip-hop, cinematic\nEurodance, hip-hop, dance\nEurodance, hip-house\nEurodance, hip-house, 90s\nEurodance, hip-house, C-pop\nEurodance, hip-house, Mandopop\nEurodance, hip-house, Middle Eastern fusion\nEurodance, hip-house, dance-pop\nEurodance, hip-house, hardstyle\nEurodance, hip-house, trance\nEurodance, house, 90s electronic\nEurodance, house, dance-pop\nEurodance, house, retro electronic\nEurodance, hyperpop\nEurodance, hyperpop, C-pop\nEurodance, hyperpop, chiptune\nEurodance, hyperpop, happy hardcore\nEurodance, hyperpop, hardstyle\nEurodance, indie rock, trance\nEurodance, industrial ambient, disco\nEurodance, iskelmä\nEurodance, jungle, happy hardcore\nEurodance, klezmer, electronic\nEurodance, klezmer, piano ballad\nEurodance, lo-fi, Eastern fusion\nEurodance, lo-fi, Persian\nEurodance, lo-fi, Ukrainian pop\nEurodance, lo-fi, happy hardcore\nEurodance, lo-fi, synthwave\nEurodance, lo-fi, trance\nEurodance, melodic house, hip hop\nEurodance, metalcore\nEurodance, microtonal, Turkish pop\nEurodance, nightcore\nEurodance, nightcore, chiptune\nEurodance, nightcore, festive\nEurodance, nightcore, happy hardcore\nEurodance, novelty\nEurodance, novelty dance\nEurodance, novelty pop\nEurodance, novelty pop, dance-pop\nEurodance, novelty, Christmas\nEurodance, novelty, French pop\nEurodance, novelty, German\nEurodance, novelty, J-pop\nEurodance, novelty, Russian pop\nEurodance, novelty, Schlager\nEurodance, novelty, children's\nEurodance, novelty, children's music\nEurodance, novelty, chipmunk\nEurodance, novelty, country\nEurodance, novelty, happy hardcore\nEurodance, novelty, polka\nEurodance, nu-disco, emotional synth\nEurodance, operatic pop, 90s dance\nEurodance, operatic, anthemic\nEurodance, orchestral synth, cinematic\nEurodance, orchestral, Middle Eastern\nEurodance, orchestral, cinematic\nEurodance, orchestral, hardstyle\nEurodance, orchestral, rock\nEurodance, orchestral, synth\nEurodance, orchestral, trance\nEurodance, oriental, Middle Eastern\nEurodance, party-schlager\nEurodance, partyschlager, hard techno\nEurodance, polka, Russian pop\nEurodance, polka, comedic\nEurodance, polka, funk disco\nEurodance, polka, novelty\nEurodance, polka, party\nEurodance, pop\nEurodance, pop, Central Asian\nEurodance, pop, Central Asian pop\nEurodance, pop, K-pop\nEurodance, pop, Spanish-influenced\nEurodance, pop, ambient\nEurodance, pop, happy hardcore\nEurodance, pop, hip hop\nEurodance, pop, rock\nEurodance, pop-house\nEurodance, pop-rap, pop ballad, pop-rock, funk-pop, disco-pop\nEurodance, post-punk\nEurodance, progressive trance, Turkish pop\nEurodance, rave, chiptune\nEurodance, rave, electronic\nEurodance, rave, house\nEurodance, reggaeton, Latin\nEurodance, reggaeton, Latin house\nEurodance, reggaeton, dance pop\nEurodance, reggaeton, pop\nEurodance, retro-futuristic\nEurodance, rock, classical\nEurodance, russemusikk, party\nEurodance, schlager\nEurodance, schlager, polka\nEurodance, sci-fi, pop\nEurodance, show tune\nEurodance, show tune, happy hardcore\nEurodance, synth-orchestral, trance\nEurodance, synth-pop\nEurodance, synth-pop, C-pop\nEurodance, synth-pop, Italo-disco\nEurodance, synth-pop, J-pop\nEurodance, synth-pop, children's music\nEurodance, synth-pop, hip-hop, pop-rock\nEurodance, synth-pop, pop-rock\nEurodance, synth-pop, theatrical\nEurodance, synthwave\nEurodance, synthwave, futuristic\nEurodance, tango, folk fusion\nEurodance, tech-house\nEurodance, theatrical pop\nEurodance, theatrical pop, Hebrew vocal\nEurodance, theatrical pop, retro\nEurodance, traditional Central Asian, 90s dance-pop\nEurodance, trance\nEurodance, trance, 2000s\nEurodance, trance, 2000s pop\nEurodance, trance, 90s\nEurodance, trance, Arabic hip hop\nEurodance, trance, Bollywood\nEurodance, trance, C-pop\nEurodance, trance, Cantopop\nEurodance, trance, Chinese fusion\nEurodance, trance, Christmas\nEurodance, trance, EDM\nEurodance, trance, Indian classical\nEurodance, trance, J-pop\nEurodance, trance, K-ambient\nEurodance, trance, Kazakh pop\nEurodance, trance, Mandarin pop\nEurodance, trance, Middle Eastern\nEurodance, trance, Middle Eastern fusion\nEurodance, trance, Persian ambient\nEurodance, trance, Russian folk\nEurodance, trance, Russian pop\nEurodance, trance, V-Pop\nEurodance, trance, Vietnamese pop\nEurodance, trance, acid house\nEurodance, trance, ambient\nEurodance, trance, ballad\nEurodance, trance, bilingual\nEurodance, trance, chiptune\nEurodance, trance, cinematic\nEurodance, trance, cinematic pop\nEurodance, trance, dance-pop\nEurodance, trance, dubstep\nEurodance, trance, electronic\nEurodance, trance, emotional pop\nEurodance, trance, folk\nEurodance, trance, happy hardcore\nEurodance, trance, hardstyle\nEurodance, trance, hip-hop\nEurodance, trance, hip-house\nEurodance, trance, lo-fi\nEurodance, trance, lo-fi pop\nEurodance, trance, orchestral\nEurodance, trance, piano ballad\nEurodance, trance, political dance\nEurodance, trance, pop-dance\nEurodance, trance, rock\nEurodance, trance, soul\nEurodance, trance, synth-pop\nEurodance, trance, synthwave\nEurodance, trance, vaporwave\nEurodance, trance, world music\nEurodance, trance-pop\nEurodance, trance-pop, emotional pop\nEurodance, trance-pop, hip hop\nEurodance, trance-pop, hip-hop\nEurodance, trap, cinematic\nEurodance, tropical house\nEurodance, trot\nEurodance, turbo-folk\nEurodance, vaporwave, synthpop\nEurodance, video game music\nEurodance, video game music, 90s synth\nEurodance, video game music, Italo dance\nEurodance, video game music, happy hardcore\nEurodance, video game music, house\nEurodance, video game music, retro-futuristic\nEurodance, video game music, synthwave\nEurodance, video game music, trance\nEurodance, video game soundtrack\nEurodance, world fusion, 90s pop\nEurodance, world music, cinematic\nEurodance, world music, cinematic pop\nEurodance, worldbeat, reggae fusion\nEurodance-pop\nEuropean Christmas pop\nEuropean art song\nEuropean ballad\nEuropean ballad, Korean trot, cinematic\nEuropean cabaret\nEuropean cabaret folk\nEuropean cabaret tango\nEuropean cabaret, polka, children's music\nEuropean cafe\nEuropean cafe music\nEuropean café\nEuropean café music\nEuropean chanson\nEuropean chanson lounge jazz\nEuropean chanson tango\nEuropean chanson, Kayōkyoku\nEuropean chanson, Latin jazz\nEuropean choral\nEuropean drill\nEuropean drill, Latin trap\nEuropean drill, gangsta rap\nEuropean film score\nEuropean folk\nEuropean folk R&B\nEuropean folk ballad\nEuropean folk blues\nEuropean folk cabaret\nEuropean folk chanson\nEuropean folk choral\nEuropean folk dance\nEuropean folk hymn\nEuropean folk jazz\nEuropean folk march\nEuropean folk opera\nEuropean folk polka\nEuropean folk pop\nEuropean folk rock\nEuropean folk salsa\nEuropean folk tango\nEuropean folk waltz\nEuropean folk, Balkan, Indonesian folk\nEuropean folk, Bollywood, folk pop\nEuropean folk, Brazilian Forró\nEuropean folk, Brazilian ballad\nEuropean folk, Brazilian folk-rock\nEuropean folk, C-pop, cinematic\nEuropean folk, Fado, cinematic pop\nEuropean folk, Forró\nEuropean folk, Klezmer\nEuropean folk, Klezmer, theatrical folk\nEuropean folk, Latin dance\nEuropean folk, Latin fusion\nEuropean folk, Latin rumba, flamenco\nEuropean folk, Parisian cafe\nEuropean folk, Parisian cafe, waltz\nEuropean folk, Schlager\nEuropean folk, cabaret, chanson\nEuropean folk, cabaret, operatic\nEuropean folk, chanson, cinematic\nEuropean folk, chanson, klezmer\nEuropean folk, chanson, operatic\nEuropean folk, chanson, tango\nEuropean folk, children's music\nEuropean folk, cinematic, choral\nEuropean folk, cinematic, operatic\nEuropean folk, cinematic, trot\nEuropean folk, circus music\nEuropean folk, classical crossover, Turkish art music\nEuropean folk, forró\nEuropean folk, jump blues, gypsy jazz\nEuropean folk, klezmer, cinematic\nEuropean folk, orchestral, video game soundtrack\nEuropean folk, polka, Christmas\nEuropean folk, power ballad, cinematic\nEuropean folk, schlager\nEuropean folk, tango, cabaret\nEuropean folk, tango, jazz\nEuropean folk, theatrical ballad, tango\nEuropean folk, theatrical pop\nEuropean folk, video game music\nEuropean folk, video game soundtrack\nEuropean folk, video game soundtrack, cinematic\nEuropean folk-pop\nEuropean folk-pop tango\nEuropean folk-rock\nEuropean hip-hop trap\nEuropean hip-hop, Anatolian hip-hop\nEuropean house\nEuropean instrumental\nEuropean pop\nEuropean pop Schlager\nEuropean pop ballad\nEuropean pop cabaret tango\nEuropean pop chanson schlager\nEuropean pop tango\nEuropean pop tango chanson\nEuropean pop, Latin pop, cha-cha-chá\nEuropean pop, Schlager\nEuropean pop, Schlager, cinematic pop\nEuropean pop, Schlager, polka\nEuropean pop, chanson\nEuropean pop, theatrical pop\nEuropean pop-rock\nEuropean pop-rock schlager\nEuropean rock\nEuropean rock ballad\nEuropean romantic ballad\nEuropean schlager\nEuropean trap\nEuropean trap, reggaeton\nEuropean waltz\nEuropean waltz, Turkish pop\nEuropop\nEuropop Bollywood\nEuropop Christmas\nEuropop Italo disco\nEuropop Italo-disco\nEuropop Italo-disco Schlager\nEuropop J-pop\nEuropop Latin\nEuropop Latin dance\nEuropop Schlager\nEuropop ballad\nEuropop children's pop\nEuropop chiptune\nEuropop cinematic\nEuropop dance-pop\nEuropop disco\nEuropop folk\nEuropop rock\nEuropop schlager\nEuropop space-disco\nEuropop tango\nEuropop tropical\nEuropop waltz\nEuropop worldbeat\nEuropop, Arabic pop, vintage\nEuropop, Celtic pop\nEuropop, Dutch Schlager\nEuropop, Dutch Schlager, dance\nEuropop, Dutch party music, cinematic pop\nEuropop, Dutch schlager, dance\nEuropop, Eastern European folk\nEuropop, Eurodance, Latin pop, theatrical rock\nEuropop, Eurodance, Russian pop\nEuropop, Greek Schlager\nEuropop, Italo disco\nEuropop, Latin dance\nEuropop, Latin dance, Dutch\nEuropop, Latin dance, Dutch pop\nEuropop, Latin house, Dutch pop\nEuropop, Latin pop, Dutch party\nEuropop, Latin pop, Russian pop\nEuropop, Latin pop, rock\nEuropop, Latin, Dutch\nEuropop, Latin, Schlager\nEuropop, Latin, tropical\nEuropop, Mandopop, acoustic\nEuropop, Russian pop\nEuropop, Russian pop, festive\nEuropop, Russian pop, winter holiday\nEuropop, Schlager\nEuropop, Schlager, 80s pop\nEuropop, Schlager, 80s synth\nEuropop, Schlager, Dutch pop\nEuropop, Schlager, German pop\nEuropop, Schlager, Greek-inspired\nEuropop, Schlager, Swedish pop\nEuropop, Schlager, children's music\nEuropop, Schlager, dance\nEuropop, Schlager, pop\nEuropop, Schlager, synth-pop\nEuropop, Turkish pop, arabesque\nEuropop, ballad, C-pop\nEuropop, boogie-woogie, jazz\nEuropop, cafe music\nEuropop, cafe music, ballad\nEuropop, cafe music, waltz\nEuropop, chanson, vintage pop\nEuropop, chiptune\nEuropop, cinematic pop\nEuropop, cinematic, 80s\nEuropop, cinematic, French chanson\nEuropop, cinematic, folk\nEuropop, cinematic, synthwave\nEuropop, dance, live performance\nEuropop, dance, pop\nEuropop, disco, Dutch pop\nEuropop, disco, Russian pop\nEuropop, folk pop\nEuropop, folk pop, Mandarin pop\nEuropop, folk pop, accordion\nEuropop, folk pop, cinematic\nEuropop, folk pop, dance\nEuropop, folk pop, tango\nEuropop, folk, theatrical\nEuropop, happy hardcore\nEuropop, happy hardcore, children's music\nEuropop, tango, cafe music\nEuropop, theatrical, accordion\nEuropop, waltz, C-pop\nEuropop, world music, accordion\nEurovision anthem\nEurovision pop\nFM synth\nFado\nFado Bossa Nova\nFado Latin\nFado Latin pop\nFado MPB\nFado Rock\nFado Samba\nFado Tango\nFado acoustic folk\nFado ballad\nFado cabaret\nFado chiptune\nFado cinematic\nFado comédia\nFado electronic\nFado flamenco\nFado folk\nFado folk-pop\nFado folk-rock\nFado hip-hop\nFado jazz\nFado orchestral\nFado pop\nFado pop Afrobeat\nFado pop-reggaeton\nFado pop-rock\nFado psychedelic rock\nFado rock\nFado samba-rock\nFado tango\nFado trap\nFado waltz\nFado, Afro-Lusophone, ritual groove\nFado, Balkan folk\nFado, Bossa Nova\nFado, Bossa Nova, Flamenco\nFado, Bossa Nova, acoustic\nFado, Bossa Nova, acoustic ballad\nFado, Bossa Nova, ambient acoustic\nFado, Bossa Nova, cinematic\nFado, Bossa Nova, free jazz\nFado, Brazilian folk\nFado, Brazilian, melancholic\nFado, Christmas, Portuguese folk\nFado, Cumbia, Reggaeton\nFado, European chanson\nFado, European chanson, waltz\nFado, European folk\nFado, European folk, theatrical\nFado, French chanson, European folk\nFado, Latin folk\nFado, Latin folk, flamenco\nFado, Latin, melancholic\nFado, Latin, piano ballad\nFado, Latin, soul\nFado, MPB\nFado, MPB, acoustic\nFado, MPB, acoustic blues\nFado, MPB, ballad\nFado, MPB, folk\nFado, MPB, romantic ballad\nFado, Pimba\nFado, Pimba, Portuguese pop\nFado, Portuguese folk\nFado, Portuguese folk, hip-hop fusion\nFado, Portuguese folk-pop\nFado, Portuguese pop\nFado, Portuguese popular\nFado, Samba, Portuguese folk\nFado, Samba-Pop\nFado, Tango\nFado, acoustic, Portuguese\nFado, ambient trap\nFado, art song\nFado, big band swing\nFado, big band, Portuguese folk\nFado, brass, theatrical\nFado, cabaret\nFado, cabaret, cinematic\nFado, cabaret, upbeat Portuguese\nFado, cinematic\nFado, cinematic ballad\nFado, cinematic, ambient\nFado, cinematic, chanson\nFado, cinematic, flamenco\nFado, cinematic, melancholic\nFado, cinematic, operatic\nFado, cinematic, orchestral\nFado, cinematic, theatrical\nFado, classical art song\nFado, classical chamber, European folk\nFado, classical, cinematic\nFado, flamenco\nFado, flamenco, Latin folk\nFado, flamenco, acoustic\nFado, flamenco, theatrical\nFado, flamenco, world music\nFado, folk-rock\nFado, orchestral, classical\nFado, romantic ballad, acoustic\nFado, romantic pop\nFado, theatrical ballad\nFado, trap R&B\nFado, trap, R&B\nFado, world fusion\nFado-pop\nFesta Junina\nFestival music\nFestive Indian\nFestive Indian Folk\nFestive World Music\nFilipino Christian\nFilipino Christian EDM\nFilipino Christian hip-hop\nFilipino Christian pop\nFilipino Christian pop-rock\nFilipino Christian power ballad\nFilipino Christian rock\nFilipino Christmas\nFilipino Christmas ballad\nFilipino Christmas pop\nFilipino Christmas pop-rap\nFilipino Christmas, Eurodance, novelty pop\nFilipino Christmas, big band\nFilipino Christmas, big band, retro\nFilipino Christmas, big band, vintage\nFilipino Christmas, chiptune\nFilipino Christmas, chiptune, retro pop\nFilipino Christmas, cumbia, salsa\nFilipino Christmas, lo-fi, retro pop\nFilipino Christmas, power ballad, pop-rock\nFilipino Christmas, retro big band\nFilipino Christmas, retro pop-rock\nFilipino Christmas, retro rock and roll\nFilipino Christmas, retro synth\nFilipino Christmas, retro synth, 80s pop\nFilipino Christmas, retro synth, chiptune\nFilipino Christmas, rockabilly\nFilipino EDM\nFilipino Eurodance\nFilipino Latin jazz\nFilipino Latin soul\nFilipino Pop\nFilipino Pop Afrobeats\nFilipino Pop J-pop\nFilipino Pop R&B\nFilipino Pop R&B trap\nFilipino Pop chiptune\nFilipino Pop trap-R&B\nFilipino Pop world music\nFilipino Pop-R&B\nFilipino Pop-Rap\nFilipino Pop-Rock\nFilipino Pop-rap\nFilipino R&B\nFilipino R&B afrobeats\nFilipino R&B lo-fi\nFilipino R&B lo-fi hip hop\nFilipino R&B lo-fi hip-hop\nFilipino R&B neo-soul\nFilipino R&B trap\nFilipino R&B trap-soul\nFilipino R&B, Hip Hop\nFilipino R&B, boom-bap, lo-fi hip hop\nFilipino R&B, hip-hop\nFilipino R&B, lo-fi hip-hop\nFilipino R&B, lo-fi pop\nFilipino R&B, lo-fi, trap-soul\nFilipino R&B, trap hip-hop\nFilipino R&B, trap, pop-rap\nFilipino R&B, trap-pop\nFilipino acoustic ballad\nFilipino acoustic ballad, pop/R&B\nFilipino acoustic pop\nFilipino acoustic pop-rock\nFilipino acoustic rock\nFilipino alternative pop-rock\nFilipino alternative rock\nFilipino art song\nFilipino ballad\nFilipino ballad jazz blues\nFilipino ballad, cumbia\nFilipino ballad, lounge jazz\nFilipino ballad, retro, cinematic\nFilipino big band swing\nFilipino bolero\nFilipino boom-bap\nFilipino brass band\nFilipino children's\nFilipino children's music\nFilipino children's music retro pop-rock\nFilipino children's pop\nFilipino choral\nFilipino club\nFilipino conscious hip-hop\nFilipino country-folk\nFilipino country-rock\nFilipino cumbia\nFilipino dance\nFilipino dance, Latin, upbeat\nFilipino dance-pop\nFilipino dance-pop tropical house\nFilipino dancehall\nFilipino disco, city pop, retro pop\nFilipino disco-funk\nFilipino drill\nFilipino electronic\nFilipino folk\nFilipino folk rock\nFilipino folk-pop\nFilipino folk-pop, novelty music\nFilipino folk-rock\nFilipino folk-rock Latin rock\nFilipino folk-rock, blues-rock\nFilipino funk\nFilipino funk disco\nFilipino funk hip-hop\nFilipino funk soul\nFilipino funk-pop\nFilipino funk-rap\nFilipino funk-reggae\nFilipino funk-rock\nFilipino gangsta rap\nFilipino gangster rap\nFilipino gospel\nFilipino gospel funk\nFilipino gospel pop\nFilipino gospel pop-rock\nFilipino gospel, retro pop-rock\nFilipino hard dance\nFilipino hard rock\nFilipino hip hop\nFilipino hip-hop\nFilipino hip-hop G-funk\nFilipino hip-hop R&B\nFilipino hip-hop chiptune\nFilipino hip-hop lo-fi\nFilipino hip-hop synth-pop\nFilipino hip-hop trap\nFilipino hip-hop, R&B\nFilipino hip-hop, hyperpop, pop\nFilipino hip-hop, new jack swing\nFilipino hip-hop, pop-rap\nFilipino hip-hop, trap\nFilipino hip-hop, trap, pop-rap\nFilipino house\nFilipino indie\nFilipino indie folk\nFilipino indie pop\nFilipino indie pop lo-fi R&B\nFilipino indie pop-rock\nFilipino indie rock\nFilipino inspirational ballad\nFilipino jazz\nFilipino jazz-pop\nFilipino mambo\nFilipino march\nFilipino marching\nFilipino metal\nFilipino new wave\nFilipino novelty\nFilipino novelty pop\nFilipino novelty, Latin cumbia\nFilipino novelty, retro rock and roll, surf rock\nFilipino orchestral\nFilipino patriotic\nFilipino patriotic hymn\nFilipino polka\nFilipino pop\nFilipino pop 70s\nFilipino pop 80s\nFilipino pop Bossa Nova\nFilipino pop J-pop\nFilipino pop Latin\nFilipino pop R&B\nFilipino pop R&B funk\nFilipino pop ballad\nFilipino pop big band\nFilipino pop big-band\nFilipino pop bolero\nFilipino pop bossa nova\nFilipino pop chiptune\nFilipino pop cumbia\nFilipino pop funk disco\nFilipino pop hip-hop\nFilipino pop jazz\nFilipino pop jazz R&B\nFilipino pop jazz city pop\nFilipino pop jazz soul\nFilipino pop lounge\nFilipino pop lounge exotica\nFilipino pop lounge jazz\nFilipino pop lounge soul\nFilipino pop lounge-pop\nFilipino pop neo-soul\nFilipino pop reggae\nFilipino pop reggae dancehall\nFilipino pop reggae-pop\nFilipino pop reggaeton\nFilipino pop rock\nFilipino pop soul\nFilipino pop trap\nFilipino pop world music\nFilipino pop, 80s anime, synth-pop\nFilipino pop, 80s soft rock, city pop\nFilipino pop, 80s synth pop\nFilipino pop, 80s synth, theatrical pop\nFilipino pop, 90s R&B\nFilipino pop, 90s R&B, city pop\nFilipino pop, Bossa Nova\nFilipino pop, Christmas pop\nFilipino pop, Eurodance\nFilipino pop, J-pop, anime soundtrack\nFilipino pop, Latin pop\nFilipino pop, Latin pop, Cumbia\nFilipino pop, Latin pop, pop-rock\nFilipino pop, R&B, hip-hop\nFilipino pop, R&B, trap\nFilipino pop, big band\nFilipino pop, big band, Latin\nFilipino pop, big band, Latin jazz\nFilipino pop, big band, cha-cha-chá\nFilipino pop, big band, mambo\nFilipino pop, big band, novelty\nFilipino pop, bolero\nFilipino pop, cinematic orchestral\nFilipino pop, city-pop, soul\nFilipino pop, dancehall, reggaeton\nFilipino pop, hardstyle\nFilipino pop, jazz, R&B\nFilipino pop, jazz, soul\nFilipino pop, neo-soul, R&B\nFilipino pop, new jack swing\nFilipino pop, reggae\nFilipino pop, reggaeton, chiptune\nFilipino pop, retro soul, big band\nFilipino pop, retro, big-band\nFilipino pop, smooth jazz\nFilipino pop, smooth jazz, adult contemporary\nFilipino pop, soft rock\nFilipino pop, synth-pop\nFilipino pop, theatrical\nFilipino pop, theatrical pop, 80s pop\nFilipino pop, trap, Christmas\nFilipino pop-R&B\nFilipino pop-funk\nFilipino pop-jazz\nFilipino pop-punk\nFilipino pop-rap\nFilipino pop-rap R&B\nFilipino pop-rap lo-fi hip-hop\nFilipino pop-rap, hyperpop, trap\nFilipino pop-reggae\nFilipino pop-rock\nFilipino pop-rock chiptune\nFilipino pop-rock funk\nFilipino pop-rock hip-hop\nFilipino pop-rock reggae\nFilipino pop-rock, 80s new wave\nFilipino pop-rock, 80s synth-pop\nFilipino pop-rock, EDM\nFilipino pop-rock, J-rock\nFilipino pop-rock, Latin dance\nFilipino pop-rock, city pop, funk\nFilipino pop-rock, city-pop\nFilipino pop-rock, comedy-rock, novelty\nFilipino pop-rock, funk\nFilipino pop-rock, lo-fi hip-hop\nFilipino pop-rock, neo-soul, city pop\nFilipino pop-soul\nFilipino pop-trap\nFilipino popular\nFilipino power ballad\nFilipino praise and worship, pop-rock\nFilipino protest\nFilipino psychedelic rock\nFilipino punk rock\nFilipino reggae\nFilipino reggae-rock\nFilipino rock\nFilipino rock and roll\nFilipino rock ska-punk\nFilipino rock, Latin rock\nFilipino rock, big band swing\nFilipino rock, rockabilly, swing\nFilipino rock, surf rock\nFilipino rockabilly\nFilipino romantic ballad\nFilipino salsa\nFilipino ska-reggae\nFilipino ska-rock\nFilipino slow rock\nFilipino soul\nFilipino soul-pop\nFilipino theatrical march\nFilipino trap\nFilipino trap-pop\nFilmi\nFilmi music\nFilmi, surf rock\nFinnish Christmas\nFinnish Christmas pop\nFinnish Christmas rock\nFinnish Christmas, Latin jazz\nFinnish Eurodance\nFinnish G-funk\nFinnish R&B\nFinnish R&B trap\nFinnish R&B, UK garage\nFinnish R&B, hip-hop\nFinnish alternative rock\nFinnish art song\nFinnish ballad\nFinnish big band swing\nFinnish boogie-woogie rock\nFinnish boom-bap\nFinnish cabaret\nFinnish children's\nFinnish children's music\nFinnish children's schlager\nFinnish conscious hip-hop\nFinnish country\nFinnish country-folk rockabilly\nFinnish country-rock\nFinnish country-western swing\nFinnish dance-pop\nFinnish dancehall\nFinnish disco-funk\nFinnish disco-pop\nFinnish drill\nFinnish electro-pop\nFinnish electropop\nFinnish folk\nFinnish folk cabaret\nFinnish folk country\nFinnish folk hip-hop\nFinnish folk humppa\nFinnish folk rock\nFinnish folk schlager\nFinnish folk tango\nFinnish folk techno\nFinnish folk waltz\nFinnish folk, Latin fusion\nFinnish folk, Latin rhythm\nFinnish folk, Latin, acoustic\nFinnish folk, Latin, tango\nFinnish folk, Spanish flair, theatrical\nFinnish folk, bluegrass, country\nFinnish folk, blues, country-western\nFinnish folk, boogie-woogie, cabaret\nFinnish folk, bossa nova\nFinnish folk, cabaret, klezmer\nFinnish folk, children's music, humppa\nFinnish folk, country, bluegrass\nFinnish folk, cowboy folk\nFinnish folk, flamenco, acoustic\nFinnish folk, flamenco, schlager\nFinnish folk, gypsy jazz, klezmer\nFinnish folk, humppa\nFinnish folk, humppa, schlager\nFinnish folk, ragtime, cabaret\nFinnish folk, schlager\nFinnish folk, schlager, danceable waltz\nFinnish folk-country\nFinnish folk-country rockabilly\nFinnish folk-jazz\nFinnish folk-polka\nFinnish folk-pop\nFinnish folk-pop cabaret\nFinnish folk-pop rockabilly\nFinnish folk-rock\nFinnish folk-rock country-western\nFinnish funk-pop\nFinnish funk-rap\nFinnish funk-reggae\nFinnish funk-rock\nFinnish gangsta rap\nFinnish hard rock\nFinnish hardcore hip-hop\nFinnish heavy metal\nFinnish hip hop\nFinnish hip-hop\nFinnish hip-hop G-funk\nFinnish hip-hop chiptune\nFinnish hip-hop electro-funk\nFinnish hip-hop funk\nFinnish hip-hop humpa\nFinnish hip-hop lo-fi\nFinnish hip-hop reggaeton\nFinnish hip-hop trap\nFinnish hip-hop, EDM, trap\nFinnish hip-hop, Eurodance\nFinnish hip-hop, G-funk\nFinnish hip-hop, R&B-influenced hip-hop\nFinnish hip-hop, chiptune, electronic\nFinnish hip-hop, chiptune, hyperpop\nFinnish hip-hop, cinematic hip-hop\nFinnish hip-hop, cinematic pop\nFinnish hip-hop, cinematic pop, trap\nFinnish hip-hop, cinematic trap\nFinnish hip-hop, cinematic trap, pop-rap\nFinnish hip-hop, cinematic, dark ambient\nFinnish hip-hop, dancehall, moombahton\nFinnish hip-hop, dream pop, trap\nFinnish hip-hop, hardstyle, EDM\nFinnish hip-hop, hardstyle, gabber\nFinnish hip-hop, humppa, comedy rap\nFinnish hip-hop, polka\nFinnish hip-hop, reggaeton, Latin funk\nFinnish hip-hop, trap\nFinnish hip-hop, vaporwave, pop-rap\nFinnish hip-house\nFinnish horrorcore\nFinnish humppa\nFinnish humppa rock\nFinnish humppa, operatic, theatrical\nFinnish indie pop\nFinnish indie rock\nFinnish iskelmä\nFinnish jazz-pop\nFinnish jazz-swing\nFinnish march\nFinnish metal\nFinnish military march\nFinnish new wave\nFinnish novelty\nFinnish novelty pop\nFinnish novelty, Latin cumbia, ukulele pop\nFinnish operetta\nFinnish party anthem\nFinnish polka\nFinnish polka humppa\nFinnish pop\nFinnish pop 80s\nFinnish pop R&B\nFinnish pop R&B dancehall\nFinnish pop reggaeton\nFinnish pop schlager\nFinnish pop, 80s schlager\nFinnish pop, Euro-pop\nFinnish pop, Latin cumbia\nFinnish pop, Latin dance\nFinnish pop, Latin pop\nFinnish pop, Latin pop, electronic\nFinnish pop, Latin pop, salsa\nFinnish pop, Latin pop, tango\nFinnish pop, humppa, 70s schlager\nFinnish pop, jazz ballad\nFinnish pop, neo-soul, R&B\nFinnish pop, polka, upbeat\nFinnish pop, schlager\nFinnish pop, schlager, electronic\nFinnish pop, theatrical, big band\nFinnish pop, trap, R&B\nFinnish pop-R&B\nFinnish pop-funk\nFinnish pop-rap\nFinnish pop-reggae\nFinnish pop-rock\nFinnish pop-rock cabaret\nFinnish pop-rock funk\nFinnish pop-rock, smooth jazz\nFinnish pop-trap\nFinnish punk rock\nFinnish rap\nFinnish rap, Eurodance, EDM\nFinnish rap, atmospheric, electronic\nFinnish rap, dembow, electronic\nFinnish reggae\nFinnish reggae-pop\nFinnish reggae-ska\nFinnish reggaeton\nFinnish rock\nFinnish rock 'n' roll\nFinnish rock AOR\nFinnish rock and roll\nFinnish rock boogie-woogie\nFinnish rock cabaret\nFinnish rock country-rock\nFinnish rock funk\nFinnish rock humppa\nFinnish rock iskelmä\nFinnish rock jangle pop\nFinnish rock post-punk\nFinnish rock rockabilly\nFinnish rock schlager\nFinnish rock ska-punk\nFinnish rock surf-rock\nFinnish rock'n'roll\nFinnish rock, 80s new wave\nFinnish rock, Balkan folk\nFinnish rock, Middle Eastern fusion\nFinnish rock, big band, swing\nFinnish rock, folk-punk\nFinnish rock, humppa\nFinnish rock, humppa, synth rock\nFinnish rock, iskelmä\nFinnish rock, power metal\nFinnish rock, punk rock, theatrical rock\nFinnish rock, rockabilly\nFinnish rock, rockabilly, boogie-woogie\nFinnish rock, rockabilly, country\nFinnish rock, rockabilly, country rock\nFinnish rock, rockabilly, country-rock\nFinnish rock, rockabilly, humppa\nFinnish rock, rockabilly, schlager\nFinnish rock, schlager\nFinnish rock, schlager, big band\nFinnish rock, schlager, big-band rock\nFinnish rock, schlager, humppa\nFinnish rock, schlager, rockabilly\nFinnish rock, schlager, theatrical rock\nFinnish rock, surf rock\nFinnish rockabilly\nFinnish salsa\nFinnish schlager\nFinnish schlager cabaret jazz\nFinnish schlager disco\nFinnish schlager humppa\nFinnish schlager jazz\nFinnish schlager rock\nFinnish schlager rockabilly\nFinnish schlager tango\nFinnish schlager, 80s synth-pop\nFinnish schlager, 80s synth-pop, disco\nFinnish schlager, Eurodance\nFinnish schlager, Latin disco\nFinnish schlager, Latin pop\nFinnish schlager, Latin salsa\nFinnish schlager, Latin, cinematic\nFinnish schlager, Latin, mambo\nFinnish schlager, big band jazz\nFinnish schlager, humppa, big band\nFinnish schlager, lounge jazz\nFinnish schlager, surf rock, chiptune\nFinnish schlager-pop\nFinnish schlager-rock\nFinnish summer pop-rap\nFinnish swing\nFinnish swing jazz\nFinnish synth-pop\nFinnish tango\nFinnish tango gypsy jazz\nFinnish tango humppa\nFinnish tango-pop\nFinnish tango-rock\nFinnish tech-house\nFinnish trap\nFinnish trap metal\nFinnish trap, cloud rap\nFinnish trap-pop\nFinnish waltz\nFlamenco\nFlamenco Arabic fusion\nFlamenco Rumba\nFlamenco fusion\nFlamenco guitar\nFlamenco pop\nFlamenco, cinematic, orchestral\nFolk Fusion\nFolk, Latin, Dance\nForró\nForró Axé\nForró Brega\nForró Brega Axé Sertanejo\nForró Eletrônico\nForró Eletrônico Axé\nForró Eletrônico Sertanejo\nForró Eletrônico, Brega\nForró Eletrônico, Sertanejo, Axé, Brazilian Pop\nForró Eletrônico, Sertanejo, Funk Carioca\nForró Eletrônico, chiptune, pop-ballad\nForró Eurodance\nForró Gospel\nForró J-pop\nForró MPB\nForró Piseiro\nForró Romântico\nForró Samba\nForró Sertanejo\nForró Sertanejo Axé\nForró Sertanejo Pop-rock\nForró Sertanejo Romântico\nForró Sertanejo, Sertanejo ballad, Axé\nForró Universitário\nForró V-hop\nForró Vaquejada\nForró chiptune\nForró country\nForró de Vaquejada\nForró de Vbera\nForró de Vberão\nForró electrique\nForró electronic\nForró eletrônico\nForró funk\nForró fusion\nForró gospel\nForró gospel rock\nForró hip-hop\nForró kids\nForró piseiro\nForró pop\nForró pop-rock\nForró punk\nForró reggae\nForró rock\nForró rockabilly\nForró rockabilly fusion\nForró tango\nForró váteda\nForró, Axé\nForró, Axé, Brazilian\nForró, Axé, Brazilian pop\nForró, Axé, Brega\nForró, Axé, Brega-pop\nForró, Axé, protest music\nForró, Brazilian festival\nForró, Brazilian regional\nForró, Brega\nForró, Brega, Brazilian pop\nForró, Brega, Sertanejo\nForró, MPB, pop-rock\nForró, Samba, Brazilian\nForró, Sertanejo\nForró, Sertanejo Universitário\nForró, Sertanejo, Brazilian pop\nForró, Vaneira\nForró, acoustic rock\nForró, chiptune\nForró, country-rock\nForró, dance, Brazilian\nForró, gothic, dance\nForró, industrial rock, pop\nForró, lo-fi hip-hop\nForró, melancholic ballad\nForró, narrative ballad\nForró, pop/R&B\nForró, power ballad, rock\nForró, synth-pop, children's pop\nForró-rock, pop-rock, funk\nFrench Afro-pop\nFrench Afro-trap\nFrench Afrobeats\nFrench Caribbean\nFrench Caribbean chanson\nFrench Caribbean dance\nFrench Caribbean folk\nFrench Caribbean folk-pop\nFrench Caribbean hip-hop\nFrench Caribbean pop\nFrench Caribbean rumba\nFrench Caribbean swing\nFrench Caribbean, festive, musette\nFrench Chanson\nFrench Christian hip-hop\nFrench Christian hymn\nFrench Christian pop\nFrench Christian trap, boom-bap hip-hop\nFrench Christian worship\nFrench Christmas\nFrench Christmas ballad\nFrench Christmas carol\nFrench Christmas waltz\nFrench Christmas, Latin pop\nFrench Christmas, ragtime, theatrical\nFrench Christmas, retro synth, video game music\nFrench Christmas, vintage jazz\nFrench Christmas, vintage, polka\nFrench Creole\nFrench Cumbia\nFrench EDM\nFrench EDM-pop\nFrench Eurodance\nFrench G-funk\nFrench G-funk, new jack swing\nFrench Hardcore\nFrench House\nFrench House electropop\nFrench House nu-disco\nFrench House, Eurodance, lounge funk\nFrench House, nu-disco\nFrench J-pop\nFrench Latin pop\nFrench Pop Arabic Pop\nFrench R&B\nFrench R&B Afro-trap\nFrench R&B Afrobeat\nFrench R&B Afrobeats\nFrench R&B G-funk\nFrench R&B chillwave\nFrench R&B chiptune\nFrench R&B dancehall\nFrench R&B deep house\nFrench R&B funk\nFrench R&B funk-pop\nFrench R&B hip-hop\nFrench R&B house\nFrench R&B lo-fi\nFrench R&B lo-fi hip hop\nFrench R&B lo-fi hip-hop\nFrench R&B lo-fi hip-hop afrobeat\nFrench R&B neo-soul\nFrench R&B neo-soul city pop\nFrench R&B nu-disco city pop\nFrench R&B nu-disco funk\nFrench R&B pop\nFrench R&B reggaeton\nFrench R&B soul\nFrench R&B trap\nFrench R&B trap Afrobeats\nFrench R&B trap-pop\nFrench R&B trap-soul\nFrench R&B vaporwave\nFrench R&B zouk\nFrench R&B, Afro-Caribbean\nFrench R&B, Afro-trap\nFrench R&B, Afro-trap, Latin-pop\nFrench R&B, Afrobeat\nFrench R&B, Afrobeats\nFrench R&B, Afrobeats, Latin\nFrench R&B, Afrobeats, Zouk\nFrench R&B, Afrobeats, chillwave\nFrench R&B, Afrobeats, dancehall\nFrench R&B, Afrobeats, lo-fi\nFrench R&B, Afrobeats, lo-fi hip hop\nFrench R&B, Afrobeats, trap\nFrench R&B, Arabic pop\nFrench R&B, Arabic trap\nFrench R&B, Balkan folk, trap\nFrench R&B, Caribbean Zouk\nFrench R&B, Dancehall, Afro-French\nFrench R&B, Latin pop\nFrench R&B, Latin pop, lo-fi\nFrench R&B, Latin pop, reggaeton\nFrench R&B, New Jack Swing\nFrench R&B, North African pop\nFrench R&B, Zouk\nFrench R&B, Zouk, Afrobeat\nFrench R&B, Zouk, Afrobeats\nFrench R&B, Zouk, Kizomba\nFrench R&B, Zouk, New Jack Swing\nFrench R&B, afro-trap\nFrench R&B, afro-trap, pop\nFrench R&B, afrobeat\nFrench R&B, ambient trap\nFrench R&B, ambient, lo-fi\nFrench R&B, atmospheric trap\nFrench R&B, boom-bap, soul\nFrench R&B, chiptune, cloud rap\nFrench R&B, cinematic pop\nFrench R&B, cinematic, Afrobeat\nFrench R&B, cinematic, atmospheric\nFrench R&B, cinematic, early 2000s pop\nFrench R&B, cloud rap\nFrench R&B, cloud rap, ambient\nFrench R&B, cloud rap, atmospheric hip-hop\nFrench R&B, cloud rap, atmospheric pop\nFrench R&B, cloud rap, emo rap\nFrench R&B, cloud rap, trap\nFrench R&B, conscious hip-hop, neo-soul\nFrench R&B, dance-pop\nFrench R&B, dancehall\nFrench R&B, early 2000s pop\nFrench R&B, hip-hop\nFrench R&B, hip-hop, 2000s\nFrench R&B, hip-hop, Afrobeat\nFrench R&B, hip-hop, afrobeat\nFrench R&B, hip-hop, ambient\nFrench R&B, hip-hop, club\nFrench R&B, hip-hop, dreamy\nFrench R&B, hip-hop, early 2000s\nFrench R&B, hip-hop, jazz fusion\nFrench R&B, hip-hop, world music\nFrench R&B, hyperpop\nFrench R&B, lo-fi hip hop\nFrench R&B, lo-fi hip hop, ambient\nFrench R&B, lo-fi hip hop, chill Afrobeats\nFrench R&B, lo-fi hip hop, pop\nFrench R&B, lo-fi hip hop, trap-soul\nFrench R&B, lo-fi hip-hop\nFrench R&B, lo-fi hip-hop, Spanish guitar\nFrench R&B, lo-fi, 90s new jack swing\nFrench R&B, lo-fi, trap\nFrench R&B, lo-fi, trap-soul\nFrench R&B, melodic trap\nFrench R&B, modern trap\nFrench R&B, modern trap, Rai\nFrench R&B, neo-soul\nFrench R&B, new jack swing\nFrench R&B, pop\nFrench R&B, pop, trap\nFrench R&B, pop-dance, early 2000s\nFrench R&B, pop-rap\nFrench R&B, pop-soul\nFrench R&B, progressive metal, funk\nFrench R&B, reggaeton, pop\nFrench R&B, sad trap\nFrench R&B, soul\nFrench R&B, synth-pop\nFrench R&B, trap\nFrench R&B, trap soul\nFrench R&B, trap soul, drill\nFrench R&B, trap, Afrobeats\nFrench R&B, trap, ambient\nFrench R&B, trap, atmospheric\nFrench R&B, trap, cinematic\nFrench R&B, trap, cinematic pop\nFrench R&B, trap, dream pop\nFrench R&B, trap, dreamy\nFrench R&B, trap, flamenco\nFrench R&B, trap, hip-hop\nFrench R&B, trap, lo-fi\nFrench R&B, trap, lo-fi hip hop\nFrench R&B, trap, psychedelic\nFrench R&B, trap, rock\nFrench R&B, trap, synthwave\nFrench R&B, trap, vaporwave\nFrench R&B, trap, world music\nFrench R&B, trap-pop, cinematic\nFrench R&B, trap-soul\nFrench R&B, vaporwave, cloud rap\nFrench R&B, vaporwave, trap\nFrench R&B, world music\nFrench R&B, zouk\nFrench Raï\nFrench Zouk\nFrench accordion\nFrench acoustic\nFrench acoustic ballad\nFrench acoustic pop\nFrench alternative rock\nFrench ambient\nFrench ambient ballad\nFrench ambient pop\nFrench ambient trap\nFrench anthem\nFrench art pop\nFrench art song\nFrench art-pop\nFrench ballad\nFrench ballad rock\nFrench ballad, Latin pop\nFrench ballad, Latin pop, reggaeton\nFrench ballad, Zouk, Kizomba\nFrench ballad, atmospheric pop, cinematic soul\nFrench ballad, hard rock\nFrench ballad, pop-rock\nFrench ballad, trap, cinematic\nFrench battle rap\nFrench big band\nFrench bluegrass\nFrench blues\nFrench blues rock\nFrench blues, jazz-pop, lounge\nFrench blues-rock\nFrench blues-swing\nFrench bolero\nFrench boogie\nFrench boom-bap\nFrench cabaret\nFrench cabaret pop\nFrench cafe\nFrench cafe jazz\nFrench café\nFrench café jazz\nFrench café music\nFrench café waltz\nFrench carnival\nFrench chanson\nFrench chanson African pop\nFrench chanson Arabic fusion\nFrench chanson Balkan folk\nFrench chanson alt-country\nFrench chanson alternative rock\nFrench chanson art-rock\nFrench chanson big band\nFrench chanson blues jazz\nFrench chanson blues lounge jazz\nFrench chanson blues soul\nFrench chanson blues-rock\nFrench chanson bossa nova\nFrench chanson bossa nova cool jazz\nFrench chanson cabaret\nFrench chanson cabaret jazz\nFrench chanson cinematic\nFrench chanson classical\nFrench chanson cool jazz\nFrench chanson cool jazz bossa nova\nFrench chanson country\nFrench chanson country-folk\nFrench chanson country-rock\nFrench chanson country-western\nFrench chanson deep house\nFrench chanson disco-pop\nFrench chanson doo-wop\nFrench chanson dream pop\nFrench chanson exotica\nFrench chanson exotica lounge\nFrench chanson flamenco\nFrench chanson folk\nFrench chanson folk-country\nFrench chanson folk-pop\nFrench chanson folk-punk\nFrench chanson folk-rock\nFrench chanson folk-rock alternative rock\nFrench chanson folk-rock blues\nFrench chanson funk\nFrench chanson funk soul\nFrench chanson funk world music\nFrench chanson funk-rock\nFrench chanson garage rock\nFrench chanson gospel\nFrench chanson gypsy jazz\nFrench chanson gypsy jazz blues\nFrench chanson gypsy jazz pop\nFrench chanson hardcore punk\nFrench chanson indie folk\nFrench chanson indie folk-rock\nFrench chanson indie pop\nFrench chanson indie pop-rock\nFrench chanson indie rock\nFrench chanson indie rock dream pop\nFrench chanson indie rock lounge jazz\nFrench chanson indie rock post-rock\nFrench chanson indie-folk\nFrench chanson indie-pop\nFrench chanson jazz\nFrench chanson jazz ballad\nFrench chanson jazz blues\nFrench chanson jazz bossa nova\nFrench chanson jazz cabaret\nFrench chanson jazz funk\nFrench chanson jazz lounge\nFrench chanson jazz manouche\nFrench chanson jazz noir\nFrench chanson jazz soul\nFrench chanson jazz swing\nFrench chanson jazz-pop\nFrench chanson jazz-rock\nFrench chanson jazz-swing\nFrench chanson lo-fi\nFrench chanson lo-fi hip hop\nFrench chanson lo-fi hip-hop\nFrench chanson lo-fi indie folk\nFrench chanson lo-fi indie pop\nFrench chanson lo-fi indie-pop\nFrench chanson lo-fi lounge jazz\nFrench chanson lounge\nFrench chanson lounge exotica\nFrench chanson lounge jazz\nFrench chanson lounge swing\nFrench chanson lounge-jazz\nFrench chanson mariachi\nFrench chanson musette\nFrench chanson neo-soul indie-pop\nFrench chanson noir jazz\nFrench chanson noir-jazz\nFrench chanson orchestral\nFrench chanson paillarde\nFrench chanson pop\nFrench chanson pop-rock\nFrench chanson post-rock\nFrench chanson progressive rock\nFrench chanson psychedelic folk-rock\nFrench chanson psychedelic rock\nFrench chanson punk\nFrench chanson punk rock\nFrench chanson ragtime\nFrench chanson reggae\nFrench chanson reggae-ska\nFrench chanson retro rock swing\nFrench chanson rock\nFrench chanson rockabilly\nFrench chanson rockabilly country-western\nFrench chanson rockabilly surf rock\nFrench chanson rockabilly swing\nFrench chanson rockabilly western swing\nFrench chanson rumba-ska\nFrench chanson salsa\nFrench chanson samba\nFrench chanson ska\nFrench chanson ska-punk\nFrench chanson smooth jazz\nFrench chanson soul-rock\nFrench chanson surf rock\nFrench chanson surf-rock\nFrench chanson swing\nFrench chanson swing jazz\nFrench chanson swing-pop\nFrench chanson swing-rock\nFrench chanson synth-pop\nFrench chanson tango\nFrench chanson tango cabaret\nFrench chanson trap\nFrench chanson trip-hop\nFrench chanson tropical\nFrench chanson world music\nFrench chanson worldbeat\nFrench chanson, 60s pop-rock\nFrench chanson, 60s rock, big band\nFrench chanson, 70s pop-rock\nFrench chanson, 80s pop-rock\nFrench chanson, Afro-Caribbean\nFrench chanson, Afro-Caribbean, folk-pop\nFrench chanson, Afro-Caribbean, upbeat\nFrench chanson, Afro-Cuban, world music\nFrench chanson, American folk, Western\nFrench chanson, American folk, bluegrass\nFrench chanson, Americana\nFrench chanson, Americana, blues-rock\nFrench chanson, Americana, country-rock\nFrench chanson, Americana, folk-blues\nFrench chanson, Americana, folk-rock\nFrench chanson, Arabic fusion\nFrench chanson, Balkan folk, Mediterranean folk\nFrench chanson, Balkan folk, Middle Eastern jazz\nFrench chanson, Balkan folk, cabaret\nFrench chanson, Balkan folk, dance\nFrench chanson, Balkan folk, theatrical\nFrench chanson, Balkan, Klezmer\nFrench chanson, Bossa Nova\nFrench chanson, Bossa Nova, Latin\nFrench chanson, Bossa Nova, Latin Jazz\nFrench chanson, Bossa Nova, Latin jazz\nFrench chanson, Bossa Nova, Samba\nFrench chanson, Bossa Nova, cool jazz\nFrench chanson, Bossa Nova, jazz\nFrench chanson, Bossa Nova, lounge\nFrench chanson, Bossa Nova, lounge jazz\nFrench chanson, Brazilian bossa nova\nFrench chanson, Brazilian samba\nFrench chanson, Caribbean folk\nFrench chanson, Caribbean, acoustic\nFrench chanson, Caribbean, live performance\nFrench chanson, Caribbean, melancholic\nFrench chanson, Caribbean, soul\nFrench chanson, Caribbean, vintage\nFrench chanson, Dixieland jazz\nFrench chanson, Dixieland, big band\nFrench chanson, Dixieland, ragtime\nFrench chanson, Dixieland, swing\nFrench chanson, Dutch rock\nFrench chanson, European folk\nFrench chanson, European folk, operatic\nFrench chanson, French pop-funk\nFrench chanson, Gipsy Jazz, Western swing\nFrench chanson, Italian folk, cabaret\nFrench chanson, Italian folk, cinematic\nFrench chanson, Italian folk, theatrical\nFrench chanson, Italo-disco\nFrench chanson, Latin American, vintage\nFrench chanson, Latin acoustic\nFrench chanson, Latin acoustic, samba fusion\nFrench chanson, Latin big band\nFrench chanson, Latin big band, mambo\nFrench chanson, Latin blues\nFrench chanson, Latin cumbia\nFrench chanson, Latin dance, cha-cha-chá\nFrench chanson, Latin exotica\nFrench chanson, Latin folk\nFrench chanson, Latin folk, Caribbean folk\nFrench chanson, Latin folk, cinematic\nFrench chanson, Latin folk, rock\nFrench chanson, Latin groove\nFrench chanson, Latin groove, bossa nova\nFrench chanson, Latin groove, flamenco\nFrench chanson, Latin groove, jazz\nFrench chanson, Latin jazz\nFrench chanson, Latin jazz, Bossa Nova\nFrench chanson, Latin jazz, big band\nFrench chanson, Latin jazz, blues\nFrench chanson, Latin jazz, bolero\nFrench chanson, Latin jazz, bossa nova\nFrench chanson, Latin jazz, cabaret\nFrench chanson, Latin jazz, classical piano\nFrench chanson, Latin jazz, exotica\nFrench chanson, Latin jazz, gypsy jazz\nFrench chanson, Latin jazz, mambo\nFrench chanson, Latin jazz, salsa\nFrench chanson, Latin jazz, surf rock\nFrench chanson, Latin jazz, tango\nFrench chanson, Latin jazz, theatrical\nFrench chanson, Latin mambo\nFrench chanson, Latin music, acoustic guitar\nFrench chanson, Latin pop\nFrench chanson, Latin pop, Caribbean\nFrench chanson, Latin pop, Mediterranean\nFrench chanson, Latin pop, acoustic\nFrench chanson, Latin pop, cinematic\nFrench chanson, Latin pop, exotica\nFrench chanson, Latin pop, melancholic\nFrench chanson, Latin pop, theatrical\nFrench chanson, Latin pop-rap\nFrench chanson, Latin rhythm\nFrench chanson, Latin rhythm, cabaret\nFrench chanson, Latin rhythm, cafe music\nFrench chanson, Latin rhythm, cha-cha-chá\nFrench chanson, Latin rhythm, flamenco\nFrench chanson, Latin rhythm, nostalgic\nFrench chanson, Latin rhythm, theatrical\nFrench chanson, Latin rock\nFrench chanson, Latin rumba\nFrench chanson, Latin salsa\nFrench chanson, Latin salsa, cabaret\nFrench chanson, Latin, Caribbean\nFrench chanson, Latin, accordion\nFrench chanson, Latin, acoustic\nFrench chanson, Latin, big band\nFrench chanson, Latin, bolero\nFrench chanson, Latin, bossa nova\nFrench chanson, Latin, breezy\nFrench chanson, Latin, children's music\nFrench chanson, Latin, cinematic\nFrench chanson, Latin, cumbia\nFrench chanson, Latin, exotica\nFrench chanson, Latin, flamenco\nFrench chanson, Latin, gipsy\nFrench chanson, Latin, jazz\nFrench chanson, Latin, klezmer\nFrench chanson, Latin, mambo\nFrench chanson, Latin, melancholic\nFrench chanson, Latin, psychedelic\nFrench chanson, Latin, rumba\nFrench chanson, Latin, salsa\nFrench chanson, Latin, samba\nFrench chanson, Latin, ska\nFrench chanson, Latin, tango\nFrench chanson, Latin, theatrical\nFrench chanson, Latin, upbeat\nFrench chanson, Latin, vintage\nFrench chanson, Mediterranean, Balkan\nFrench chanson, Middle Eastern folk\nFrench chanson, North African folk\nFrench chanson, Portuguese ballad, folk-pop\nFrench chanson, Portuguese folk\nFrench chanson, Portuguese popular music\nFrench chanson, Russian estrada, cabaret\nFrench chanson, Western folk\nFrench chanson, Western, pedal steel\nFrench chanson, acoustic ballad, Latin folk\nFrench chanson, acoustic folk\nFrench chanson, acoustic folk, pop-rap\nFrench chanson, acoustic, folk\nFrench chanson, alt-country\nFrench chanson, alt-rock\nFrench chanson, alternative rock\nFrench chanson, ambient, experimental\nFrench chanson, arena rock\nFrench chanson, art rock\nFrench chanson, art rock, cool jazz\nFrench chanson, art rock, free jazz\nFrench chanson, art rock, theatrical rock\nFrench chanson, art song, operatic\nFrench chanson, art-pop\nFrench chanson, art-pop, cinematic\nFrench chanson, art-pop, jazz lounge\nFrench chanson, baroque pop\nFrench chanson, big band\nFrench chanson, big band jazz\nFrench chanson, big band jazz, musette\nFrench chanson, big band jazz, theatrical\nFrench chanson, big band jazz, world music\nFrench chanson, big band swing\nFrench chanson, big band swing, free jazz\nFrench chanson, big band, Latin\nFrench chanson, big band, Latin jazz\nFrench chanson, big band, Latin pop\nFrench chanson, big band, avant-garde\nFrench chanson, big band, cabaret\nFrench chanson, big band, cinematic\nFrench chanson, big band, jazz\nFrench chanson, big band, jazz lounge\nFrench chanson, big band, orchestral\nFrench chanson, big band, rock and roll\nFrench chanson, big band, ska\nFrench chanson, big band, soul\nFrench chanson, big band, swing\nFrench chanson, big band, theatrical\nFrench chanson, big band, vintage\nFrench chanson, big-band swing\nFrench chanson, bluegrass\nFrench chanson, bluegrass, country\nFrench chanson, bluegrass, rock\nFrench chanson, blues, boogie-woogie\nFrench chanson, blues-rock\nFrench chanson, blues-rock, boogie-woogie\nFrench chanson, blues-rock, cinematic\nFrench chanson, blues-rock, country-western\nFrench chanson, blues-rock, funk\nFrench chanson, blues-rock, power ballad\nFrench chanson, bolero\nFrench chanson, bolero, cinematic\nFrench chanson, bolero, jazz\nFrench chanson, bolero, tango\nFrench chanson, bolero, theatrical\nFrench chanson, boogie-woogie, cabaret\nFrench chanson, boogie-woogie, jazz\nFrench chanson, boogie-woogie, rock and roll\nFrench chanson, boogie-woogie, satirical pop\nFrench chanson, boogie-woogie, swing\nFrench chanson, boogie-woogie, swing jazz\nFrench chanson, boogie-woogie, theatrical\nFrench chanson, bossa nova\nFrench chanson, bossa nova, Latin\nFrench chanson, bossa nova, Latin pop\nFrench chanson, bossa nova, cool jazz\nFrench chanson, bossa nova, electronic\nFrench chanson, bossa nova, indie rock\nFrench chanson, bossa nova, jazz\nFrench chanson, bossa nova, latin jazz\nFrench chanson, bossa nova, light jazz\nFrench chanson, bossa nova, lounge\nFrench chanson, bossa nova, lounge jazz\nFrench chanson, bossa nova, melancholic\nFrench chanson, bossa nova, samba\nFrench chanson, cabaret\nFrench chanson, cabaret jazz\nFrench chanson, cabaret rock\nFrench chanson, cabaret rock, jazz ballad\nFrench chanson, cabaret, Dixieland\nFrench chanson, cabaret, Latin\nFrench chanson, cabaret, Latin jazz\nFrench chanson, cabaret, art-rock\nFrench chanson, cabaret, big band\nFrench chanson, cabaret, big band jazz\nFrench chanson, cabaret, bossa nova\nFrench chanson, cabaret, chiptune\nFrench chanson, cabaret, cinematic\nFrench chanson, cabaret, circus\nFrench chanson, cabaret, folk\nFrench chanson, cabaret, free jazz\nFrench chanson, cabaret, gypsy jazz\nFrench chanson, cabaret, jazz\nFrench chanson, cabaret, klezmer\nFrench chanson, cabaret, musette\nFrench chanson, cabaret, music hall\nFrench chanson, cabaret, polka\nFrench chanson, cabaret, ragtime\nFrench chanson, cabaret, rockabilly\nFrench chanson, cabaret, swing\nFrench chanson, cabaret, swing jazz\nFrench chanson, cabaret, tango\nFrench chanson, cabaret, theatrical\nFrench chanson, cabaret, theatrical rock\nFrench chanson, cabaret-punk\nFrench chanson, cabaret-rock, folk-punk\nFrench chanson, cartoon music\nFrench chanson, cha-cha-chá\nFrench chanson, children's music\nFrench chanson, chiptune\nFrench chanson, chiptune, video game music\nFrench chanson, cinematic ballad\nFrench chanson, cinematic folk, Parisian café\nFrench chanson, cinematic orchestral\nFrench chanson, cinematic pop\nFrench chanson, cinematic pop, ballad\nFrench chanson, cinematic pop, rock\nFrench chanson, cinematic pop-rock\nFrench chanson, cinematic rock\nFrench chanson, cinematic, Spanish flair\nFrench chanson, cinematic, big band\nFrench chanson, cinematic, big band jazz\nFrench chanson, cinematic, choral\nFrench chanson, cinematic, epic\nFrench chanson, cinematic, experimental\nFrench chanson, cinematic, operatic\nFrench chanson, cinematic, orchestral\nFrench chanson, cinematic, post-rock\nFrench chanson, cinematic, synthwave\nFrench chanson, classic rock\nFrench chanson, classic rock, ambient\nFrench chanson, classical art song\nFrench chanson, cool jazz\nFrench chanson, cool jazz, big band\nFrench chanson, cool jazz, bossa nova\nFrench chanson, cool jazz, lounge\nFrench chanson, cool jazz, swing\nFrench chanson, country blues, rock\nFrench chanson, country folk\nFrench chanson, country swing, rockabilly\nFrench chanson, country western\nFrench chanson, country, folk\nFrench chanson, country, gospel\nFrench chanson, country, vintage\nFrench chanson, country, western\nFrench chanson, country-folk\nFrench chanson, country-western\nFrench chanson, country-western, blues-rock\nFrench chanson, cumbia\nFrench chanson, cumbia, Latin\nFrench chanson, cumbia, accordion\nFrench chanson, cumbia, forró\nFrench chanson, cumbia, lo-fi\nFrench chanson, cumbia, salsa\nFrench chanson, cumbia, theatrical\nFrench chanson, cumbia, upbeat\nFrench chanson, cumbia-ska, theatrical\nFrench chanson, dance-pop\nFrench chanson, dark cabaret\nFrench chanson, dark cabaret, theatrical\nFrench chanson, deep house, ambient\nFrench chanson, disco-pop\nFrench chanson, disco-rock\nFrench chanson, dixieland jazz\nFrench chanson, doo-wop, swing\nFrench chanson, dream pop\nFrench chanson, dream-pop\nFrench chanson, electro-pop, cinematic\nFrench chanson, electronic pop\nFrench chanson, electronic pop, cinematic rock\nFrench chanson, electronic, cinematic\nFrench chanson, electronic, rap\nFrench chanson, electronic, rock\nFrench chanson, epic rock\nFrench chanson, exotica\nFrench chanson, exotica, Latin\nFrench chanson, exotica, lounge\nFrench chanson, exotica, psychedelic pop\nFrench chanson, exotica, tropical\nFrench chanson, experimental electronic\nFrench chanson, flamenco, Latin\nFrench chanson, flamenco, Latin pop\nFrench chanson, flamenco, Mediterranean\nFrench chanson, flamenco, acoustic\nFrench chanson, flamenco, cabaret\nFrench chanson, flamenco, cinematic\nFrench chanson, flamenco, pop-rock\nFrench chanson, flamenco, protest music\nFrench chanson, flamenco, tango\nFrench chanson, flamenco, theatrical\nFrench chanson, folk\nFrench chanson, folk rock\nFrench chanson, folk, Americana\nFrench chanson, folk, cinematic\nFrench chanson, folk, country\nFrench chanson, folk, gypsy jazz\nFrench chanson, folk, polka\nFrench chanson, folk, pub rock\nFrench chanson, folk-blues\nFrench chanson, folk-pop, psychedelic funk\nFrench chanson, folk-punk\nFrench chanson, folk-punk, polka\nFrench chanson, folk-rock\nFrench chanson, folk-rock, Latin rock\nFrench chanson, folk-rock, acoustic\nFrench chanson, folk-rock, alternative rock\nFrench chanson, folk-rock, blues-rock\nFrench chanson, folk-rock, cinematic\nFrench chanson, folk-rock, noise-rock\nFrench chanson, folk-rock, pub-rock\nFrench chanson, folk-rock, punk rock\nFrench chanson, free jazz, avant-garde\nFrench chanson, funk, indie\nFrench chanson, funk, instrumental\nFrench chanson, funk, soul\nFrench chanson, funk-pop\nFrench chanson, garage punk\nFrench chanson, garage rock\nFrench chanson, garage rock, Eastern European folk\nFrench chanson, gospel ballad\nFrench chanson, gospel, acoustic\nFrench chanson, gospel, theatrical\nFrench chanson, gospel-rock, power ballad\nFrench chanson, guinguette\nFrench chanson, gypsy jazz\nFrench chanson, gypsy jazz, Balkan brass\nFrench chanson, gypsy jazz, Balkan folk\nFrench chanson, gypsy jazz, Latin jazz\nFrench chanson, gypsy jazz, big band\nFrench chanson, gypsy jazz, bossa nova\nFrench chanson, gypsy jazz, cabaret\nFrench chanson, gypsy jazz, flamenco\nFrench chanson, gypsy jazz, folk\nFrench chanson, gypsy jazz, indie rock\nFrench chanson, gypsy jazz, klezmer\nFrench chanson, gypsy jazz, manouche\nFrench chanson, gypsy jazz, musette\nFrench chanson, gypsy jazz, surf rock\nFrench chanson, gypsy jazz, swing\nFrench chanson, gypsy jazz, tango\nFrench chanson, gypsy jazz, theatrical\nFrench chanson, gypsy jazz, world music\nFrench chanson, hard rock\nFrench chanson, hard rock, metal\nFrench chanson, indie pop\nFrench chanson, indie rock\nFrench chanson, indie rock, cinematic\nFrench chanson, indie rock, pop-rock\nFrench chanson, indie rock, post-rock\nFrench chanson, indie-pop, jazz\nFrench chanson, industrial breakcore\nFrench chanson, industrial electronic\nFrench chanson, industrial rock, chiptune\nFrench chanson, jazz\nFrench chanson, jazz lounge\nFrench chanson, jazz manouche, cabaret\nFrench chanson, jazz manouche, cinematic\nFrench chanson, jazz manouche, swing\nFrench chanson, jazz swing\nFrench chanson, jazz waltz\nFrench chanson, jazz, big band\nFrench chanson, jazz, cabaret\nFrench chanson, jazz, cinematic\nFrench chanson, jazz, indie-pop\nFrench chanson, jazz, lo-fi hip hop\nFrench chanson, jazz, melancholic\nFrench chanson, jazz, musette\nFrench chanson, jazz, operatic\nFrench chanson, jazz, soul\nFrench chanson, jazz, theatrical\nFrench chanson, jazz, theatrical rock\nFrench chanson, klezmer, cabaret\nFrench chanson, klezmer, pop-rock\nFrench chanson, klezmer, theatrical\nFrench chanson, klezmer, theatrical rock\nFrench chanson, klezmer, whimsical\nFrench chanson, light Latin, children's music\nFrench chanson, light jazz\nFrench chanson, lo-fi hip hop, ambient\nFrench chanson, lounge jazz\nFrench chanson, lounge jazz, blues\nFrench chanson, mambo\nFrench chanson, mambo, big band\nFrench chanson, mambo, cha-cha\nFrench chanson, mambo, cha-cha-chá\nFrench chanson, mambo, cinematic\nFrench chanson, mambo, theatrical\nFrench chanson, musette, Latin\nFrench chanson, musette, brass pop\nFrench chanson, musette, cabaret\nFrench chanson, musette, folk\nFrench chanson, musette, polka\nFrench chanson, musette, swing\nFrench chanson, musette, tango\nFrench chanson, musical theater\nFrench chanson, neo-soul\nFrench chanson, new wave\nFrench chanson, noir-jazz, theatrical\nFrench chanson, noise rock\nFrench chanson, noise rock, ambient\nFrench chanson, nu-disco\nFrench chanson, operatic, theatrical\nFrench chanson, orchestral pop, tango\nFrench chanson, orchestral, theatrical\nFrench chanson, piano rock\nFrench chanson, pirate folk, sea shanty\nFrench chanson, pirate, theatrical\nFrench chanson, polka\nFrench chanson, polka, accordion\nFrench chanson, polka, cabaret\nFrench chanson, polka, country-western\nFrench chanson, polka, festive\nFrench chanson, polka, musette\nFrench chanson, polka, rockabilly\nFrench chanson, polka, ska\nFrench chanson, polka, theatrical\nFrench chanson, pop ballad, cinematic\nFrench chanson, pop ballad, cinematic pop\nFrench chanson, pop, cinematic\nFrench chanson, pop-punk\nFrench chanson, pop-rock\nFrench chanson, pop-rock ballad\nFrench chanson, pop-rock, accordion\nFrench chanson, pop-rock, arena rock\nFrench chanson, pop-rock, atmospheric\nFrench chanson, pop-rock, ballad\nFrench chanson, pop-rock, big band\nFrench chanson, pop-rock, blues\nFrench chanson, pop-rock, choral\nFrench chanson, pop-rock, cinematic\nFrench chanson, pop-rock, cinematic rock\nFrench chanson, pop-rock, dramatic rock\nFrench chanson, pop-rock, epic rock\nFrench chanson, pop-rock, folk\nFrench chanson, pop-rock, folk-rock\nFrench chanson, pop-rock, free jazz\nFrench chanson, pop-rock, funk-rock\nFrench chanson, pop-rock, glam rock\nFrench chanson, pop-rock, gospel\nFrench chanson, pop-rock, hard rock\nFrench chanson, pop-rock, rock\nFrench chanson, pop-rock, rumba\nFrench chanson, pop-rock, symphonic metal\nFrench chanson, pop-rock, synth\nFrench chanson, pop-rock, synth pop\nFrench chanson, pop-rock, theatrical\nFrench chanson, post-punk\nFrench chanson, post-rock\nFrench chanson, post-rock, circus music\nFrench chanson, post-rock, shoegaze\nFrench chanson, power ballad\nFrench chanson, power ballad, cinematic\nFrench chanson, power ballad, hard rock\nFrench chanson, power ballad, live rock\nFrench chanson, power ballad, rock\nFrench chanson, protest rock\nFrench chanson, psychedelic pop\nFrench chanson, psychedelic rock\nFrench chanson, psychedelic rock, theatrical\nFrench chanson, pub rock\nFrench chanson, punk rock\nFrench chanson, ragtime, big band\nFrench chanson, ragtime, early jazz\nFrench chanson, ragtime, swing\nFrench chanson, ragtime, theatrical\nFrench chanson, reggae, Caribbean\nFrench chanson, reggae, ska\nFrench chanson, retro rock\nFrench chanson, retro rock 'n' roll, swing\nFrench chanson, retro surf-rock\nFrench chanson, retro video game, children's music\nFrench chanson, retro video game, theatrical\nFrench chanson, retro-futuristic, cabaret\nFrench chanson, retro-pop, doo-wop\nFrench chanson, rock\nFrench chanson, rock 'n' roll\nFrench chanson, rock ballad\nFrench chanson, rock opera\nFrench chanson, rock opera, theatrical\nFrench chanson, rock, atmospheric\nFrench chanson, rock, experimental\nFrench chanson, rock, operatic\nFrench chanson, rock, psychedelic rock\nFrench chanson, rock, theatrical\nFrench chanson, rockabilly\nFrench chanson, rockabilly, country\nFrench chanson, rockabilly, country-western\nFrench chanson, rockabilly, early rock 'n' roll\nFrench chanson, rockabilly, gypsy jazz\nFrench chanson, rockabilly, surf rock\nFrench chanson, rockabilly, swing\nFrench chanson, rumba, flamenco\nFrench chanson, salsa\nFrench chanson, salsa, Caribbean\nFrench chanson, salsa, theatrical\nFrench chanson, samba, Brazilian\nFrench chanson, samba, Brazilian jazz\nFrench chanson, sea shanty, folk rock\nFrench chanson, sea shanty, polka\nFrench chanson, sea shanty, tropical\nFrench chanson, shoegaze, post-rock\nFrench chanson, singer-songwriter, lo-fi\nFrench chanson, ska, polka\nFrench chanson, ska, reggae\nFrench chanson, smooth jazz\nFrench chanson, soft pop-rock\nFrench chanson, soft rock\nFrench chanson, soft rock, cinematic\nFrench chanson, soul, funk\nFrench chanson, stadium rock\nFrench chanson, surf rock\nFrench chanson, surf rock, Latin\nFrench chanson, surf rock, klezmer\nFrench chanson, surf rock, lo-fi\nFrench chanson, surf-rock, theatrical\nFrench chanson, swing jazz\nFrench chanson, swing, Christmas\nFrench chanson, swing, big band\nFrench chanson, swing, jazz\nFrench chanson, swing, musette\nFrench chanson, swing, rockabilly\nFrench chanson, swing, ska\nFrench chanson, symphonic rock\nFrench chanson, synth-pop\nFrench chanson, synth-pop, Italo-disco\nFrench chanson, synth-pop, cinematic\nFrench chanson, synth-pop, electro-pop\nFrench chanson, tango, Latin\nFrench chanson, tango, Latin dance\nFrench chanson, tango, ballad\nFrench chanson, theatrical ballad\nFrench chanson, theatrical pop, childlike\nFrench chanson, theatrical pop, dramatic rock\nFrench chanson, theatrical pop, rock ballad\nFrench chanson, theatrical rock\nFrench chanson, theatrical rock, blues-rock\nFrench chanson, theatrical rock, cinematic pop\nFrench chanson, theatrical rock, cinematic rock\nFrench chanson, theatrical rock, jazz-influenced\nFrench chanson, theatrical rock, sea shanty\nFrench chanson, theatrical, Spanish influence\nFrench chanson, trap\nFrench chanson, trap, electronic\nFrench chanson, trap-rock, ambient\nFrench chanson, trip-hop, cinematic\nFrench chanson, trip-hop, downtempo\nFrench chanson, trip-hop, melancholic ballad\nFrench chanson, tropical, upbeat\nFrench chanson, video game soundtrack, baroque-pop\nFrench chanson, video game soundtrack, whimsical\nFrench chanson, vintage Christmas, early rock 'n' roll\nFrench chanson, vintage jazz, big band\nFrench chanson, vintage mambo, big band swing\nFrench chanson, vintage pop, early rock 'n' roll\nFrench chanson, vintage rock\nFrench chanson, vintage rock 'n' roll, swing\nFrench chanson, vintage rock and roll, big band\nFrench chanson, vintage rock and roll, swing\nFrench chanson, vintage rock, theatrical\nFrench chanson, world music\nFrench chanson, world music, Latin\nFrench chanson, world music, Latin pop\nFrench chanson, world music, Mediterranean\nFrench chanson, world music, acoustic\nFrench chanson, world music, cinematic\nFrench chanson, world music, cumbia\nFrench chanson, world music, folk\nFrench chanson, world music, lo-fi groove\nFrench chanson, world music, theatrical rock\nFrench chanson, worldbeat, electronic\nFrench chanson, zouk\nFrench chanson, zouk, kompa\nFrench chanson, zouk, soca\nFrench children's\nFrench children's cabaret\nFrench children's folk\nFrench children's jazz\nFrench children's music\nFrench children's polka\nFrench children's pop\nFrench children's swing\nFrench chill wave\nFrench circus\nFrench cloud rap\nFrench cloud rap, Latin pop\nFrench cloud rap, Latin pop-trap\nFrench cloud rap, Latin trap\nFrench cloud rap, chiptune\nFrench club rap\nFrench club-pop\nFrench club-rap\nFrench cold wave\nFrench comedy folk\nFrench comedy rock\nFrench conscious hip-hop\nFrench conscious rap\nFrench country rock\nFrench country-folk\nFrench country-folk rockabilly\nFrench country-gospel\nFrench country-pop\nFrench country-rock\nFrench country-western\nFrench country-western novelty\nFrench cumbia\nFrench cumbia ska\nFrench cumbia-pop\nFrench dance\nFrench dance-pop\nFrench dance-pop chiptune\nFrench dance-pop nu-disco\nFrench dance-pop nu-disco funk\nFrench dance-pop tropical house\nFrench dance-pop, Latin house\nFrench dance-rap\nFrench dancehall\nFrench dancehall afro-trap\nFrench dancehall afrobeat\nFrench dancehall afrobeats chiptune\nFrench dancehall chiptune\nFrench dancehall moombahton\nFrench dancehall reggaeton\nFrench dancehall zouk\nFrench dancehall, Afrobeats\nFrench dancehall, Latin pop\nFrench dancehall, afrobeat\nFrench dancehall, chiptune, electro-pop\nFrench dancehall, reggaeton, Latin\nFrench dancehall, zouk, afrobeats\nFrench dark pop\nFrench disco\nFrench disco funk\nFrench disco, Italo-disco, high-energy\nFrench disco-funk\nFrench disco-funk, 80s power ballad, militaristic march\nFrench disco-pop\nFrench disco-rock\nFrench dream pop, tropical wave\nFrench dream trap\nFrench drill\nFrench drill afro-trap\nFrench drill lo-fi\nFrench drill reggaeton\nFrench drill trap\nFrench drill, Afro-Caribbean pop\nFrench drill, Afro-Latin\nFrench drill, Turkish fusion\nFrench drill, afro-trap\nFrench drill, ambient trap\nFrench drill, anime hip hop\nFrench drill, cinematic\nFrench drill, cinematic hip hop\nFrench drill, cinematic orchestral\nFrench drill, cinematic synth\nFrench drill, cinematic trap\nFrench drill, cloud rap\nFrench drill, cloud rap, reggaeton\nFrench drill, dancehall\nFrench drill, hip-hop\nFrench drill, lo-fi hip hop\nFrench drill, melodic rap\nFrench drill, trap\nFrench drill, trap soul\nFrench drill, trap, acoustic\nFrench drill, trap, acoustic guitar\nFrench drill, trap, boom-bap\nFrench drill, trap, cinematic\nFrench drill, trap, drill South African\nFrench drill, trap, emo-rap\nFrench drill, trap, world fusion\nFrench drill, vaporwave\nFrench electro\nFrench electro-pop\nFrench electro-rap\nFrench electronic\nFrench electronic dance\nFrench electronic pop\nFrench electropop\nFrench emo-rap\nFrench exotica\nFrench folk\nFrench folk baroque\nFrench folk chanson\nFrench folk chiptune\nFrench folk country\nFrench folk cumbia\nFrench folk gospel\nFrench folk indie rock\nFrench folk manouche\nFrench folk punk\nFrench folk rock\nFrench folk waltz\nFrench folk, Balkan, Gypsy\nFrench folk, Celtic folk\nFrench folk, Celtic punk\nFrench folk, Celtic, Mediterranean\nFrench folk, Celtic, bluegrass\nFrench folk, Celtic, sea shanty\nFrench folk, Celtic, upbeat\nFrench folk, North African, Middle Eastern\nFrench folk, Western, cowboy\nFrench folk, accordion, comedy\nFrench folk, bluegrass\nFrench folk, bluegrass, Americana\nFrench folk, bluegrass, country\nFrench folk, bluegrass, hoedown\nFrench folk, bluegrass, pub rock\nFrench folk, bluegrass, pub song\nFrench folk, brass band, spoken word\nFrench folk, country\nFrench folk, country western\nFrench folk, country, bluegrass\nFrench folk, country, western\nFrench folk, dance, Afro-fusion\nFrench folk, electronic, party\nFrench folk, folk-rock, worldbeat\nFrench folk, gypsy, Balkan\nFrench folk, polka\nFrench folk, polka, country\nFrench folk, sea shanty\nFrench folk, sea shanty, cabaret\nFrench folk, sea shanty, theatrical\nFrench folk, theatrical\nFrench folk, video game music, children's music\nFrench folk-country\nFrench folk-pop\nFrench folk-pop gypsy jazz\nFrench folk-rap\nFrench folk-rock\nFrench folk-rock gypsy jazz\nFrench funk\nFrench funk boogie\nFrench funk disco\nFrench funk neo-soul\nFrench funk new wave\nFrench funk nu-disco\nFrench funk soul\nFrench funk, boogie, 80s synth\nFrench funk, lo-fi hip-hop\nFrench funk-house\nFrench funk-pop\nFrench funk-rap\nFrench funk-rock\nFrench funk-soul\nFrench gangsta rap\nFrench gospel\nFrench gospel folk-pop\nFrench gospel hip-hop\nFrench gospel pop\nFrench gospel rap\nFrench gospel trap\nFrench gospel zouk\nFrench gospel, cumbia\nFrench gospel, retro video game\nFrench gospel, soca\nFrench gospel, zouk\nFrench gospel-pop\nFrench groove\nFrench hardcore hip-hop\nFrench hardcore punk\nFrench hip hop\nFrench hip hop, Haitian Creole rap, ambient trap\nFrench hip hop, Latin fusion\nFrench hip hop, Latin soul\nFrench hip hop, baroque pop\nFrench hip hop, boom-bap\nFrench hip hop, boom-bap, cinematic\nFrench hip hop, boom-bap, dream trap\nFrench hip hop, boom-bap, lo-fi\nFrench hip hop, boom-bap, synthwave\nFrench hip hop, boom-bap, trap\nFrench hip hop, boom-bap, underground\nFrench hip hop, cinematic ambient\nFrench hip hop, cinematic boom-bap\nFrench hip hop, cinematic electronic\nFrench hip hop, cinematic hip hop\nFrench hip hop, cinematic lo-fi\nFrench hip hop, cinematic rap\nFrench hip hop, cinematic rock\nFrench hip hop, cinematic trap\nFrench hip hop, cinematic, boom-bap\nFrench hip hop, cinematic, dystopian\nFrench hip hop, gangsta rap\nFrench hip hop, hyper-trap\nFrench hip hop, industrial rap\nFrench hip hop, lo-fi boom-bap\nFrench hip hop, lo-fi, boom-bap\nFrench hip hop, retro-futuristic\nFrench hip hop, soulful jazz rap\nFrench hip-hop\nFrench hip-hop Afro-Caribbean\nFrench hip-hop Afrobeat dancehall\nFrench hip-hop Afrobeats\nFrench hip-hop Afrobeats R&B\nFrench hip-hop Arabic fusion\nFrench hip-hop Arabic pop\nFrench hip-hop Balkan brass\nFrench hip-hop Balkan folk\nFrench hip-hop Eurodance\nFrench hip-hop G-funk\nFrench hip-hop Latin pop\nFrench hip-hop R&B\nFrench hip-hop Rai fusion\nFrench hip-hop acoustic R&B\nFrench hip-hop afro-trap\nFrench hip-hop blues-rock\nFrench hip-hop boom bap\nFrench hip-hop boom-bap\nFrench hip-hop chiptune\nFrench hip-hop chiptune trap\nFrench hip-hop cinematic\nFrench hip-hop cloud rap\nFrench hip-hop dance-pop\nFrench hip-hop dancehall\nFrench hip-hop deep house\nFrench hip-hop electro-funk\nFrench hip-hop electro-house\nFrench hip-hop funk\nFrench hip-hop funk disco\nFrench hip-hop funk gospel\nFrench hip-hop funk neo-soul\nFrench hip-hop funk ska\nFrench hip-hop funk-pop\nFrench hip-hop indie pop\nFrench hip-hop industrial\nFrench hip-hop lo-fi\nFrench hip-hop lo-fi trap\nFrench hip-hop neo-soul\nFrench hip-hop nu-disco\nFrench hip-hop nu-disco funk\nFrench hip-hop nu-metal\nFrench hip-hop pop\nFrench hip-hop reggae\nFrench hip-hop reggae dancehall\nFrench hip-hop reggaeton\nFrench hip-hop rock\nFrench hip-hop spiritual pop\nFrench hip-hop swing jazz\nFrench hip-hop synth-pop\nFrench hip-hop trap\nFrench hip-hop tropical\nFrench hip-hop world fusion\nFrench hip-hop world music\nFrench hip-hop, Afro-Caribbean, Latin\nFrench hip-hop, Afro-trap\nFrench hip-hop, Afrobeat\nFrench hip-hop, Afrobeats\nFrench hip-hop, Afrobeats, dancehall\nFrench hip-hop, Afrobeats, pop-rap\nFrench hip-hop, Afrobeats, trap\nFrench hip-hop, Arabic fusion\nFrench hip-hop, Arabic hip-hop, boom-bap\nFrench hip-hop, Arabic pop\nFrench hip-hop, Arabic pop, Rai\nFrench hip-hop, Arabic pop, trap\nFrench hip-hop, Balkan fusion\nFrench hip-hop, Balkan hip-hop\nFrench hip-hop, Bollywood fusion\nFrench hip-hop, Bollywood pop\nFrench hip-hop, Brazilian funk\nFrench hip-hop, Brazilian funk, afrobeat\nFrench hip-hop, EDM\nFrench hip-hop, Eurodance, hyperpop\nFrench hip-hop, G-funk\nFrench hip-hop, G-funk, comedic\nFrench hip-hop, Latin dancehall\nFrench hip-hop, Latin funk\nFrench hip-hop, Latin fusion\nFrench hip-hop, Latin hip-hop\nFrench hip-hop, Latin jazz\nFrench hip-hop, Latin pop\nFrench hip-hop, Latin pop, club\nFrench hip-hop, Latin pop, funk\nFrench hip-hop, Latin reggae\nFrench hip-hop, Latin trap\nFrench hip-hop, MPB\nFrench hip-hop, Middle Eastern, chiptune\nFrench hip-hop, North African funk\nFrench hip-hop, North African fusion\nFrench hip-hop, North African fusion, worldbeat\nFrench hip-hop, North African pop\nFrench hip-hop, R&B, cinematic\nFrench hip-hop, R&B, trap\nFrench hip-hop, Rai\nFrench hip-hop, Rai, electronic\nFrench hip-hop, Raï\nFrench hip-hop, UK drill\nFrench hip-hop, West African fusion\nFrench hip-hop, acoustic soul\nFrench hip-hop, ambient R&B\nFrench hip-hop, baroque electronica\nFrench hip-hop, baroque pop\nFrench hip-hop, big beat, drum and bass\nFrench hip-hop, boom-bap\nFrench hip-hop, boom-bap, Middle Eastern\nFrench hip-hop, boom-bap, atmospheric\nFrench hip-hop, boom-bap, cinematic\nFrench hip-hop, boom-bap, psychedelic\nFrench hip-hop, boom-bap, soulful\nFrench hip-hop, boom-bap, turntablism\nFrench hip-hop, chiptune\nFrench hip-hop, chiptune, Latin fusion\nFrench hip-hop, chiptune, boom-bap\nFrench hip-hop, chiptune, electro\nFrench hip-hop, chiptune, electro-funk\nFrench hip-hop, chiptune, hyperpop\nFrench hip-hop, chiptune, lo-fi\nFrench hip-hop, chiptune, nerdcore\nFrench hip-hop, chiptune, pop-rap\nFrench hip-hop, chiptune, synth-pop\nFrench hip-hop, chiptune, trap\nFrench hip-hop, cinematic\nFrench hip-hop, cinematic lo-fi\nFrench hip-hop, cinematic pop\nFrench hip-hop, cinematic soul\nFrench hip-hop, cinematic synth\nFrench hip-hop, cinematic trap\nFrench hip-hop, cinematic, boom-bap\nFrench hip-hop, cinematic, dark trap\nFrench hip-hop, cinematic, emotional\nFrench hip-hop, cinematic, lo-fi\nFrench hip-hop, cinematic, melodic trap\nFrench hip-hop, cinematic, orchestral\nFrench hip-hop, cinematic, rap-rock\nFrench hip-hop, cinematic, synthwave\nFrench hip-hop, cinematic, trap\nFrench hip-hop, cloud rap\nFrench hip-hop, cloud rap, lo-fi hip-hop\nFrench hip-hop, dancehall, boom-bap\nFrench hip-hop, dancehall, moombahton\nFrench hip-hop, dark boom-bap\nFrench hip-hop, deep house, afro-house\nFrench hip-hop, dreamy trap\nFrench hip-hop, dub, world music\nFrench hip-hop, electronic, chiptune\nFrench hip-hop, ethereal R&B\nFrench hip-hop, experimental electronic\nFrench hip-hop, glitch hop, chiptune\nFrench hip-hop, gospel rap, lo-fi trap\nFrench hip-hop, hardstyle, cinematic\nFrench hip-hop, horrorcore\nFrench hip-hop, indie rock\nFrench hip-hop, introspective rap\nFrench hip-hop, jazz rap\nFrench hip-hop, jazz, classical\nFrench hip-hop, jazzy boom-bap\nFrench hip-hop, jazzy hip-hop\nFrench hip-hop, lo-fi hip hop\nFrench hip-hop, lo-fi hip-hop\nFrench hip-hop, lo-fi trap\nFrench hip-hop, lo-fi, ambient\nFrench hip-hop, lo-fi, cinematic\nFrench hip-hop, lo-fi, cloud rap\nFrench hip-hop, lo-fi, dream pop\nFrench hip-hop, lo-fi, dreamy R&B\nFrench hip-hop, lo-fi, dystopian\nFrench hip-hop, lo-fi, introspective\nFrench hip-hop, lo-fi, jazz\nFrench hip-hop, lo-fi, psychedelic\nFrench hip-hop, lo-fi, trap\nFrench hip-hop, melodic trap\nFrench hip-hop, new jack swing\nFrench hip-hop, nu-disco\nFrench hip-hop, nu-metal, rap-rock\nFrench hip-hop, pop-R&B\nFrench hip-hop, psychedelic, lo-fi\nFrench hip-hop, rap-rock\nFrench hip-hop, reggaeton\nFrench hip-hop, reggaeton, Latin\nFrench hip-hop, rock\nFrench hip-hop, soul R&B\nFrench hip-hop, soul, R&B\nFrench hip-hop, soulful R&B\nFrench hip-hop, soulful jazz\nFrench hip-hop, synth-pop\nFrench hip-hop, synth-pop, cinematic\nFrench hip-hop, synth-pop, new wave\nFrench hip-hop, trap\nFrench hip-hop, trap R&B\nFrench hip-hop, trap, acoustic\nFrench hip-hop, trap, afro-trap\nFrench hip-hop, trap, ambient\nFrench hip-hop, trap, chanson\nFrench hip-hop, trap, chiptune\nFrench hip-hop, trap, cinematic\nFrench hip-hop, trap, cinematic orchestral\nFrench hip-hop, trap, cloud rap\nFrench hip-hop, trap, drill\nFrench hip-hop, trap, electronic\nFrench hip-hop, trap, experimental\nFrench hip-hop, trap, futuristic\nFrench hip-hop, trap, melancholic\nFrench hip-hop, trap, melodic rap\nFrench hip-hop, trap, oriental synth\nFrench hip-hop, trap, synth-pop\nFrench hip-hop, trap, turntablism\nFrench hip-hop, tropical house\nFrench hip-hop, vaporwave\nFrench hip-hop, world fusion\nFrench hip-hop, world music\nFrench hip-hop, world music, Latin\nFrench hip-hop, zouk, dance\nFrench hip-hop, zouk, tropical\nFrench hip-house\nFrench house\nFrench house electro-funk\nFrench house electro-swing\nFrench house nu-disco\nFrench house, Arabic pop\nFrench house, Balkan brass, worldbeat\nFrench house, Eurodance, dance-pop\nFrench house, Italo disco\nFrench house, Latin house\nFrench house, North African pop\nFrench house, UK garage, dance\nFrench house, baile funk\nFrench house, chillwave\nFrench house, deep house\nFrench house, electro, chiptune\nFrench house, nu-disco\nFrench house, nu-disco, melancholic pop\nFrench house, nu-disco, pop\nFrench house, nu-disco, synth-pop\nFrench house, nu-disco, upbeat pop\nFrench house, tropical house, dance-pop\nFrench hymn\nFrench hyperpop\nFrench hyperpop, breakbeat\nFrench indie\nFrench indie dance\nFrench indie electronic\nFrench indie folk\nFrench indie hip-hop\nFrench indie pop\nFrench indie pop lo-fi hip-hop\nFrench indie pop lounge-jazz\nFrench indie pop neo-soul\nFrench indie pop, experimental trap\nFrench indie pop-rock\nFrench indie rock\nFrench indie trap\nFrench indie-folk\nFrench indie-pop\nFrench indie-pop bossa nova\nFrench indie-pop nu-disco\nFrench indie-pop nu-disco funk\nFrench jazz\nFrench jazz chanson\nFrench jazz-funk\nFrench jazz-pop\nFrench lo-fi\nFrench lo-fi hip hop\nFrench lo-fi synth\nFrench lo-fi trap\nFrench lounge\nFrench lounge funk\nFrench lounge-pop\nFrench lullaby\nFrench lullaby, cinematic, big band\nFrench mambo\nFrench melodic rap\nFrench melodic rap, North African pop\nFrench melodic trap\nFrench metal\nFrench musette\nFrench musette, Balkan folk\nFrench nerdcore, trap\nFrench new wave\nFrench novelty\nFrench novelty polka\nFrench novelty, Latin pop, zouk\nFrench novelty, Latin, mambo\nFrench novelty, Western Swing\nFrench novelty, bal musette\nFrench novelty, boogie-woogie, swing\nFrench novelty, cabaret, musical theatre\nFrench novelty, cabaret, polka\nFrench novelty, chiptune\nFrench novelty, country swing\nFrench novelty, country western\nFrench novelty, cumbia\nFrench novelty, polka, chanson paillarde\nFrench novelty, polka, guinguette\nFrench novelty, polka, musette\nFrench novelty, polka, ska\nFrench novelty, sea shanty, polka\nFrench novelty, tropical, big band\nFrench novelty, zouk, dance\nFrench nursery rhyme\nFrench nursery rhyme jazz\nFrench nursery rhyme, video game music, playful orchestral\nFrench operatic\nFrench party\nFrench party anthem\nFrench party, Latin, Caribbean\nFrench party-rap\nFrench political rap\nFrench polka\nFrench polka cabaret\nFrench polka-chanson\nFrench polka-pop\nFrench pop\nFrench pop 80s\nFrench pop 80s anime\nFrench pop Afro-Caribbean\nFrench pop Afro-Cuban\nFrench pop Afrobeat\nFrench pop Afrobeat Latin\nFrench pop Afrobeats\nFrench pop Afropop\nFrench pop Bossa Nova\nFrench pop J-pop\nFrench pop R&B\nFrench pop R&B Latin\nFrench pop R&B hip-hop\nFrench pop R&B trap\nFrench pop afrobeat\nFrench pop ballad\nFrench pop bossa nova\nFrench pop cabaret\nFrench pop cabaret samba\nFrench pop cabaret swing\nFrench pop chanson\nFrench pop chanson bossa nova\nFrench pop chanson lounge\nFrench pop chanson, smooth jazz\nFrench pop chiptune\nFrench pop country\nFrench pop cumbia\nFrench pop cumbia reggae\nFrench pop deep house\nFrench pop disco\nFrench pop electropop\nFrench pop exotica\nFrench pop flamenco\nFrench pop folk\nFrench pop funk\nFrench pop funk disco\nFrench pop funk electronic\nFrench pop funk lounge\nFrench pop funk reggae\nFrench pop funk soul\nFrench pop future bass\nFrench pop gipsy jazz\nFrench pop gospel\nFrench pop gypsy jazz\nFrench pop gypsy jazz Latin\nFrench pop hip-hop\nFrench pop hip-hop ballad\nFrench pop indie-pop\nFrench pop jazz\nFrench pop jazz cabaret\nFrench pop jazz chanson\nFrench pop jazz lounge\nFrench pop jazz swing\nFrench pop jazz-funk\nFrench pop jazz-hop\nFrench pop lo-fi\nFrench pop lo-fi hip hop\nFrench pop lo-fi hip-hop\nFrench pop lo-fi hip-hop chillwave\nFrench pop lo-fi hip-hop neo-soul\nFrench pop lo-fi house\nFrench pop lounge\nFrench pop lounge bossa nova\nFrench pop lounge cabaret\nFrench pop lounge exotica\nFrench pop lounge funk\nFrench pop lounge jazz\nFrench pop lounge jazz bossa nova\nFrench pop lounge smooth jazz\nFrench pop musette\nFrench pop neo-soul\nFrench pop neo-soul lounge\nFrench pop nu-disco\nFrench pop nu-disco funk\nFrench pop nu-disco synth-pop\nFrench pop nu-jazz bossa nova\nFrench pop nu-jazz lounge\nFrench pop progressive house\nFrench pop reggae\nFrench pop reggae dub\nFrench pop reggae ska\nFrench pop reggae-dub\nFrench pop reggae-ska\nFrench pop reggaeton\nFrench pop rock\nFrench pop rockabilly\nFrench pop ska\nFrench pop ska funk\nFrench pop ska reggae\nFrench pop smooth jazz funk\nFrench pop soul\nFrench pop tango\nFrench pop trap\nFrench pop tropical\nFrench pop tropical house\nFrench pop waltz\nFrench pop world music\nFrench pop yé-yé\nFrench pop zouk\nFrench pop, 60s pop, country-pop\nFrench pop, 60s rock and roll, swing\nFrench pop, 60s rock, chanson\nFrench pop, 60s rock, garage rock\nFrench pop, 80s Euro-pop\nFrench pop, 80s R&B\nFrench pop, 80s aesthetic, theatrical\nFrench pop, 80s anime\nFrench pop, 80s anime, cinematic\nFrench pop, 80s anime, synthwave\nFrench pop, 80s anime, theatrical\nFrench pop, 80s cartoon\nFrench pop, 80s disco, funk\nFrench pop, 80s disco, retro\nFrench pop, 80s funk, R&B\nFrench pop, 80s funk, disco\nFrench pop, 80s funk, worldbeat\nFrench pop, 80s new wave\nFrench pop, 80s new wave, disco\nFrench pop, 80s new wave, dream pop\nFrench pop, 80s synth\nFrench pop, 80s synth pop\nFrench pop, 80s synth, cinematic\nFrench pop, 80s synth, funk\nFrench pop, 80s synth-pop\nFrench pop, 80s, theatrical\nFrench pop, 90s Eurodance\nFrench pop, 90s R&B\nFrench pop, African pop\nFrench pop, Afro-Caribbean, retro\nFrench pop, Afro-Caribbean, zouk\nFrench pop, Afro-Latin, world music\nFrench pop, Afrobeat\nFrench pop, Afrobeat, Latin\nFrench pop, Afrobeat, Zouk\nFrench pop, Afrobeat, dancehall\nFrench pop, Afrobeat, tropical house\nFrench pop, Afrobeats\nFrench pop, Afrobeats, Latin\nFrench pop, Afrobeats, Latin pop\nFrench pop, Afrobeats, North African\nFrench pop, Afrobeats, R&B\nFrench pop, Afrobeats, Zouk\nFrench pop, Afrobeats, dancehall\nFrench pop, Afrobeats, tropical house\nFrench pop, Afrobeats, world music\nFrench pop, Afropop, Latin\nFrench pop, Arabic dance, electronic\nFrench pop, Arabic fusion\nFrench pop, Arabic fusion, dance-pop\nFrench pop, Arabic fusion, electronic\nFrench pop, Arabic fusion, reggaeton\nFrench pop, Arabic hip-hop\nFrench pop, Arabic music, Afrobeats\nFrench pop, Arabic pop, dancehall\nFrench pop, Balkan brass\nFrench pop, Balkan pop, Middle Eastern pop\nFrench pop, Bollywood dance, reggaeton\nFrench pop, Bossa Nova\nFrench pop, Bossa Nova, Afro-Caribbean\nFrench pop, Bossa Nova, Latin\nFrench pop, Bossa Nova, Latin jazz\nFrench pop, Bossa Nova, Latin pop\nFrench pop, Bossa Nova, Samba\nFrench pop, Bossa Nova, acoustic world\nFrench pop, Bossa Nova, jazz\nFrench pop, Bossa Nova, lounge\nFrench pop, Caribbean groove\nFrench pop, Caribbean pop\nFrench pop, EDM\nFrench pop, EDM, dance-pop\nFrench pop, EDM, emotional\nFrench pop, EDM, future bass\nFrench pop, Eurodance\nFrench pop, Eurodance, 80s synth\nFrench pop, Eurodance, Italo disco\nFrench pop, Eurodance, cinematic\nFrench pop, Eurodance, funk\nFrench pop, Eurodance, house\nFrench pop, Eurodance, novelty\nFrench pop, Eurodance, synth-pop\nFrench pop, European folk\nFrench pop, Haitian Creole, ambient house\nFrench pop, Italo-disco\nFrench pop, Italo-disco, Eurodance\nFrench pop, Italo-disco, Latin pop\nFrench pop, J-pop\nFrench pop, J-pop, Eurodance\nFrench pop, J-pop, video game music\nFrench pop, Latin R&B\nFrench pop, Latin dance\nFrench pop, Latin dance, reggaeton\nFrench pop, Latin dance, tropical house\nFrench pop, Latin dance-pop\nFrench pop, Latin disco\nFrench pop, Latin funk\nFrench pop, Latin groove\nFrench pop, Latin jazz, bossa nova\nFrench pop, Latin jazz, gypsy jazz\nFrench pop, Latin jazz, salsa\nFrench pop, Latin jazz, sophisticated pop\nFrench pop, Latin pop\nFrench pop, Latin pop, 1960s\nFrench pop, Latin pop, 80s euro pop\nFrench pop, Latin pop, Caribbean\nFrench pop, Latin pop, Caribbean pop\nFrench pop, Latin pop, Chanson\nFrench pop, Latin pop, Euro-pop\nFrench pop, Latin pop, Europop\nFrench pop, Latin pop, Mediterranean\nFrench pop, Latin pop, Zouk\nFrench pop, Latin pop, ballad\nFrench pop, Latin pop, big band\nFrench pop, Latin pop, boogie-woogie\nFrench pop, Latin pop, bossa nova\nFrench pop, Latin pop, cabaret\nFrench pop, Latin pop, carnival\nFrench pop, Latin pop, chanson\nFrench pop, Latin pop, chill groove\nFrench pop, Latin pop, cinematic\nFrench pop, Latin pop, cumbia\nFrench pop, Latin pop, dance\nFrench pop, Latin pop, dance pop\nFrench pop, Latin pop, dance-pop\nFrench pop, Latin pop, dream pop\nFrench pop, Latin pop, exotica\nFrench pop, Latin pop, flamenco\nFrench pop, Latin pop, flamenco pop\nFrench pop, Latin pop, funk\nFrench pop, Latin pop, groove\nFrench pop, Latin pop, gypsy jazz\nFrench pop, Latin pop, mambo\nFrench pop, Latin pop, reggaeton\nFrench pop, Latin pop, retro\nFrench pop, Latin pop, rumba\nFrench pop, Latin pop, salsa\nFrench pop, Latin pop, samba\nFrench pop, Latin pop, ska\nFrench pop, Latin pop, smooth groove\nFrench pop, Latin pop, synth-pop\nFrench pop, Latin pop, theatrical\nFrench pop, Latin pop, theatrical pop\nFrench pop, Latin pop, tropical\nFrench pop, Latin pop, tropical house\nFrench pop, Latin pop, upbeat\nFrench pop, Latin pop, vintage\nFrench pop, Latin pop, world music\nFrench pop, Latin pop, worldbeat\nFrench pop, Latin salsa\nFrench pop, Latin, Mediterranean\nFrench pop, Latin, big band\nFrench pop, Latin, reggaeton\nFrench pop, Latin, worldbeat\nFrench pop, Mediterranean, cinematic\nFrench pop, Mediterranean, dance\nFrench pop, Mediterranean, upbeat\nFrench pop, Middle Eastern dance\nFrench pop, Middle Eastern fusion\nFrench pop, Middle Eastern, upbeat\nFrench pop, North African electronic\nFrench pop, North African fusion\nFrench pop, North African, Arabic\nFrench pop, North African, Latin\nFrench pop, North African, romantic duet\nFrench pop, R&B\nFrench pop, R&B, 2000s\nFrench pop, R&B, Afrobeats\nFrench pop, R&B, Afropop\nFrench pop, R&B, Middle Eastern\nFrench pop, R&B, ambient\nFrench pop, R&B, chillwave\nFrench pop, R&B, dance-pop\nFrench pop, R&B, dancehall\nFrench pop, R&B, deep house\nFrench pop, R&B, electronic\nFrench pop, R&B, emo rap\nFrench pop, R&B, funk\nFrench pop, R&B, gospel\nFrench pop, R&B, gospel-pop\nFrench pop, R&B, hip-hop\nFrench pop, R&B, lo-fi hip-hop\nFrench pop, R&B, lo-fi trap\nFrench pop, R&B, melancholic\nFrench pop, R&B, neo-soul\nFrench pop, R&B, reggae\nFrench pop, R&B, smooth jazz\nFrench pop, R&B, synth-pop\nFrench pop, R&B, trap\nFrench pop, R&B, zouk\nFrench pop, Rai\nFrench pop, Rai fusion\nFrench pop, Rai, dance\nFrench pop, Rai, dance pop\nFrench pop, Rai, electronic\nFrench pop, Rai, electronic dance\nFrench pop, Rai, pop-R&B\nFrench pop, Rai, reggaeton\nFrench pop, Rai, trap\nFrench pop, Raï, electronic\nFrench pop, Western cinematic\nFrench pop, Zouk\nFrench pop, Zouk, 80s synth\nFrench pop, Zouk, Afrobeats\nFrench pop, Zouk, Caribbean\nFrench pop, Zouk, Kizomba\nFrench pop, Zouk, R&B\nFrench pop, Zouk, Soca\nFrench pop, Zouk, dance-pop\nFrench pop, Zouk, retro\nFrench pop, Zouk, retro dance\nFrench pop, Zouk, retro funk\nFrench pop, Zouk, retro synth\nFrench pop, Zouk, synthwave\nFrench pop, afro-trap, R&B\nFrench pop, afrobeat\nFrench pop, afrobeat, R&B\nFrench pop, afrobeat, acoustic singer-songwriter\nFrench pop, afrobeat, dancehall\nFrench pop, afrobeat, tropical pop\nFrench pop, afrobeat, world music\nFrench pop, afrobeats\nFrench pop, alternative R&B, dream pop\nFrench pop, alternative rock\nFrench pop, ambient, documentary\nFrench pop, ambient, trap\nFrench pop, anime orchestral\nFrench pop, anime theme\nFrench pop, arena rock\nFrench pop, big band\nFrench pop, big band jazz\nFrench pop, big band swing\nFrench pop, big band, Latin pop\nFrench pop, big band, carnival\nFrench pop, big band, soul\nFrench pop, big band, swing\nFrench pop, big band, theatrical\nFrench pop, big band, vintage\nFrench pop, big-band swing, theatrical\nFrench pop, boogaloo, Latin pop\nFrench pop, boom-bap hip hop\nFrench pop, bossa nova\nFrench pop, bossa nova, Latin pop\nFrench pop, bossa nova, cinematic\nFrench pop, bossa nova, exotica\nFrench pop, bossa nova, funk\nFrench pop, bossa nova, jazz\nFrench pop, bossa nova, latin pop\nFrench pop, bossa nova, light jazz\nFrench pop, bossa nova, lounge\nFrench pop, bossa nova, psychedelic\nFrench pop, bossa nova, retro\nFrench pop, bubblegum pop\nFrench pop, bubblegum pop, retro\nFrench pop, cabaret, Latin pop\nFrench pop, cabaret, big band\nFrench pop, cabaret, samba\nFrench pop, cabaret, show tune\nFrench pop, cabaret, ska\nFrench pop, cabaret, swing\nFrench pop, cabaret, theatrical\nFrench pop, calypso, exotica\nFrench pop, chanson, cinematic\nFrench pop, chanson, pop-rock\nFrench pop, chanson, theatrical pop\nFrench pop, chanson, vintage\nFrench pop, chillwave, R&B\nFrench pop, chillwave, exotica\nFrench pop, chillwave, retro\nFrench pop, chiptune\nFrench pop, chiptune, lo-fi\nFrench pop, chiptune, novelty\nFrench pop, chiptune, video game music\nFrench pop, chiptune, world music\nFrench pop, cinematic folk\nFrench pop, cinematic pop-rock\nFrench pop, cinematic soul\nFrench pop, cinematic trap\nFrench pop, cinematic, Mediterranean\nFrench pop, cinematic, chanson\nFrench pop, cinematic, disco-pop\nFrench pop, cinematic, electronic\nFrench pop, cinematic, fairytale\nFrench pop, cinematic, funk\nFrench pop, cinematic, operatic\nFrench pop, cinematic, orchestral\nFrench pop, cinematic, retro\nFrench pop, cinematic, rock\nFrench pop, cinematic, romantic\nFrench pop, cinematic, theatrical\nFrench pop, city pop, 80s lounge\nFrench pop, city pop, funk\nFrench pop, city pop, jazz-fusion\nFrench pop, city pop, nu-disco\nFrench pop, city pop, smooth jazz\nFrench pop, city-pop, funk\nFrench pop, conscious hip-hop\nFrench pop, country\nFrench pop, country pop\nFrench pop, country, bluegrass\nFrench pop, country, vintage\nFrench pop, cumbia\nFrench pop, cumbia, Latin pop\nFrench pop, cumbia, cha-cha-chá\nFrench pop, cumbia, chiptune\nFrench pop, cumbia, house techno\nFrench pop, cumbia, merengue\nFrench pop, cumbia, rumba\nFrench pop, cumbia, salsa\nFrench pop, cumbia, samba\nFrench pop, cumbia, synth-pop\nFrench pop, cumbia, world music\nFrench pop, dance pop\nFrench pop, dance-pop\nFrench pop, dance-pop, Balkan fusion\nFrench pop, dance-pop, EDM\nFrench pop, dance-pop, hip-hop\nFrench pop, dance-pop, hyperpop\nFrench pop, dance-pop, lo-fi hip hop\nFrench pop, dancehall, afrobeat\nFrench pop, dancehall, chiptune\nFrench pop, dancehall, moombahton\nFrench pop, dancehall, reggaeton\nFrench pop, dark pop\nFrench pop, deep house\nFrench pop, disco, bossa nova\nFrench pop, disco, chanson\nFrench pop, disco, funk\nFrench pop, disco-funk\nFrench pop, downtempo, lo-fi hip hop\nFrench pop, dream pop, 80s new wave\nFrench pop, dream pop, R&B\nFrench pop, dream pop, lo-fi\nFrench pop, dream pop, reggaeton\nFrench pop, dream pop, synth-pop\nFrench pop, early 2000s R&B\nFrench pop, electro-pop, dream-pop, dance-pop, hip-hop, pop-rock\nFrench pop, electronic\nFrench pop, electronic dance\nFrench pop, electronic dance, Middle Eastern fusion\nFrench pop, electronic, ballad\nFrench pop, electronic, cinematic\nFrench pop, electronic, gospel\nFrench pop, electronic, hip-hop\nFrench pop, electronic, trap\nFrench pop, emo rap, lo-fi indie\nFrench pop, ethnic fusion\nFrench pop, exotica, Latin pop\nFrench pop, exotica, exotica nova\nFrench pop, exotica, lounge\nFrench pop, exotica, mambo\nFrench pop, exotica, retro\nFrench pop, exotica, spy soundtrack\nFrench pop, experimental hip-hop\nFrench pop, flamenco pop\nFrench pop, flamenco, Latin\nFrench pop, flamenco, Latin pop\nFrench pop, folk pop\nFrench pop, folk, dance\nFrench pop, folk, musette\nFrench pop, funk\nFrench pop, funk, Latin\nFrench pop, funk, R&B\nFrench pop, funk, city pop\nFrench pop, funk, disco\nFrench pop, funk, synth\nFrench pop, funk, theatrical\nFrench pop, future bass\nFrench pop, future bass, cinematic\nFrench pop, garage rock\nFrench pop, garage rock, 60s pop\nFrench pop, garage rock, chanson\nFrench pop, garage rock, retro\nFrench pop, garage rock, surf rock\nFrench pop, garage rock, theatrical pop\nFrench pop, gospel\nFrench pop, gospel, 80s\nFrench pop, gospel, zouk\nFrench pop, gypsy jazz\nFrench pop, gypsy jazz, Balkan pop\nFrench pop, gypsy jazz, chanson\nFrench pop, gypsy jazz, electronic\nFrench pop, gypsy jazz, flamenco\nFrench pop, gypsy jazz, polka\nFrench pop, gypsy jazz, swing\nFrench pop, gypsy pop, flamenco\nFrench pop, gypsy, flamenco\nFrench pop, hip-hop\nFrench pop, hip-hop, Latin\nFrench pop, hip-hop, R&B\nFrench pop, hip-hop, cinematic\nFrench pop, indie electronic\nFrench pop, jazz, Latin\nFrench pop, jazz, big band\nFrench pop, jazz, soul\nFrench pop, jazz, trip-hop\nFrench pop, jazz-funk, bossa nova\nFrench pop, late-90s R&B\nFrench pop, lo-fi bedroom pop\nFrench pop, lo-fi hip hop\nFrench pop, lo-fi hip hop, Latin pop\nFrench pop, lo-fi hip hop, chillwave\nFrench pop, lo-fi hip hop, hyperpop\nFrench pop, lo-fi hip hop, introspective\nFrench pop, lo-fi hip hop, melancholic\nFrench pop, lo-fi hip hop, modern R&B\nFrench pop, lo-fi hip-hop, R&B\nFrench pop, lo-fi, electronic\nFrench pop, lo-fi, melancholic\nFrench pop, lo-fi, pop-rock\nFrench pop, mambo, lounge\nFrench pop, melodic rap, cinematic hip-hop\nFrench pop, minimalist, R&B\nFrench pop, musette, polka\nFrench pop, musical theatre\nFrench pop, musical theatre, pop-rock\nFrench pop, neo-soul, R&B\nFrench pop, neo-soul, funk\nFrench pop, neo-soul, jazz\nFrench pop, neo-soul, lo-fi hip-hop\nFrench pop, neo-soul, lounge\nFrench pop, neo-soul, smooth jazz\nFrench pop, neo-soul, trip-hop\nFrench pop, neo-soul, tropical\nFrench pop, new jack swing\nFrench pop, new jack swing, Eurodance\nFrench pop, new jack swing, afrobeat\nFrench pop, new jack swing, funk\nFrench pop, new jack swing, retro\nFrench pop, new wave\nFrench pop, new wave, chanson\nFrench pop, new wave, funk\nFrench pop, nu-disco\nFrench pop, nu-disco, French touch\nFrench pop, nu-disco, R&B\nFrench pop, nu-disco, city pop\nFrench pop, nu-disco, city-pop\nFrench pop, nu-disco, funk\nFrench pop, nu-disco, lounge\nFrench pop, polka\nFrench pop, polka, cabaret\nFrench pop, polka, pop\nFrench pop, polka, theatrical\nFrench pop, polka, upbeat\nFrench pop, pop-rock\nFrench pop, pop-rock, blues-rock\nFrench pop, pop-rock, cinematic\nFrench pop, pop-rock, rock\nFrench pop, pop-trap\nFrench pop, power ballad\nFrench pop, progressive house\nFrench pop, psychedelic chanson\nFrench pop, psychedelic pop\nFrench pop, psychedelic rock, retro\nFrench pop, psychedelic, funk\nFrench pop, psychedelic, garage rock\nFrench pop, ragtime, theatrical\nFrench pop, reggae, chanson\nFrench pop, reggae, chiptune\nFrench pop, reggae, classical fusion\nFrench pop, reggae, dancehall\nFrench pop, reggae, dub\nFrench pop, reggae, funk\nFrench pop, reggae, ska\nFrench pop, reggae, world music\nFrench pop, reggaeton\nFrench pop, reggaeton, Latin\nFrench pop, reggaeton, Latin pop\nFrench pop, reggaeton, afrobeat\nFrench pop, reggaeton, atmospheric\nFrench pop, reggaeton, dream pop\nFrench pop, reggaeton, lo-fi\nFrench pop, reggaeton, moombahton\nFrench pop, reggaeton, pop-dance\nFrench pop, reggaeton, synth pop\nFrench pop, reggaeton, world music\nFrench pop, reggaeton-pop, Latin pop\nFrench pop, retro funk, chanson\nFrench pop, retro funk, disco\nFrench pop, retro funk, new jack swing\nFrench pop, retro funk, soul\nFrench pop, retro pop, theatrical pop\nFrench pop, retro surf-rock\nFrench pop, retro swing, cabaret\nFrench pop, retro swing, mambo\nFrench pop, retro synth, cinematic\nFrench pop, retro, Latin pop\nFrench pop, retro, anime\nFrench pop, retro, big-band\nFrench pop, retro, children's music\nFrench pop, retro, chiptune\nFrench pop, retro, cinematic\nFrench pop, retro, dance\nFrench pop, retro, doo-wop\nFrench pop, retro, exotica\nFrench pop, retro, novelty\nFrench pop, retro, psychedelic\nFrench pop, retro, surf-rock\nFrench pop, retro, swing revival\nFrench pop, retro-funk, disco\nFrench pop, retro-soul, funk\nFrench pop, rock and roll, doo-wop\nFrench pop, rockabilly, 60s rock\nFrench pop, rockabilly, big band\nFrench pop, rockabilly, doo-wop\nFrench pop, rockabilly, retro\nFrench pop, rockabilly, swing\nFrench pop, rockabilly, vintage\nFrench pop, sad rap, piano ballad\nFrench pop, salsa, Latin pop\nFrench pop, samba, retro\nFrench pop, samba, world music\nFrench pop, samba, worldbeat\nFrench pop, samba-pop, tropical\nFrench pop, show tune, chanson\nFrench pop, show tune, theatrical\nFrench pop, show tune, theatrical pop\nFrench pop, ska, big band\nFrench pop, ska, polka\nFrench pop, ska, reggae\nFrench pop, ska, swing\nFrench pop, smooth jazz, funk\nFrench pop, smooth jazz, lounge\nFrench pop, smooth jazz, zouk\nFrench pop, soca\nFrench pop, sophisti-pop, smooth jazz\nFrench pop, soul, jazz\nFrench pop, soul, vintage\nFrench pop, soulful hip-hop\nFrench pop, surf rock\nFrench pop, surf rock, garage rock\nFrench pop, swing, big band\nFrench pop, synth-funk, new jack swing\nFrench pop, synth-pop\nFrench pop, synth-pop, 80s new wave\nFrench pop, synth-pop, R&B\nFrench pop, synth-pop, art-pop\nFrench pop, synth-pop, chiptune\nFrench pop, synth-pop, city pop\nFrench pop, synth-pop, disco\nFrench pop, synth-pop, new wave\nFrench pop, synth-pop, nu-disco\nFrench pop, synth-pop, retro\nFrench pop, theatrical pop, Spanish flair\nFrench pop, theatrical pop, show tune\nFrench pop, theatrical, chanson\nFrench pop, theatrical, cinematic\nFrench pop, theatrical, circus\nFrench pop, theatrical, gothic\nFrench pop, theatrical, synthwave\nFrench pop, trap\nFrench pop, trap, Mandarin rap\nFrench pop, trap, R&B\nFrench pop, trap, afrobeat\nFrench pop, trap, ambient\nFrench pop, trap, atmospheric\nFrench pop, trap, cinematic\nFrench pop, trap, electronic\nFrench pop, trap, future bass\nFrench pop, trap, hip-hop\nFrench pop, trap, hyperpop\nFrench pop, trap, melancholic\nFrench pop, trip-hop\nFrench pop, trip-hop, art-pop\nFrench pop, trip-hop, cinematic\nFrench pop, trip-hop, dream pop\nFrench pop, trip-hop, electronic\nFrench pop, tropical house\nFrench pop, tropical house, afrobeat\nFrench pop, tropical, Afropop\nFrench pop, tropical, Caribbean\nFrench pop, tropical, Latin\nFrench pop, tropical, calypso\nFrench pop, tropical, exotica\nFrench pop, tropical, sea shanty\nFrench pop, tropical, world music\nFrench pop, vintage rock and roll, boogie-woogie\nFrench pop, vintage swing, satirical\nFrench pop, world fusion, cinematic\nFrench pop, world music\nFrench pop, world music, Bossa Nova\nFrench pop, world music, bossa nova\nFrench pop, world music, chiptune\nFrench pop, world music, cumbia\nFrench pop, world music, dance\nFrench pop, world music, reggae\nFrench pop, world music, reggaeton\nFrench pop, world music, soft rock\nFrench pop, world music, trap\nFrench pop, world music, upbeat\nFrench pop, world music, zouk\nFrench pop, worldbeat, Latin\nFrench pop, zouk\nFrench pop, zouk, Afro-Caribbean\nFrench pop, zouk, Caribbean\nFrench pop, zouk, R&B\nFrench pop, zouk, afrobeats\nFrench pop, zouk, kizomba\nFrench pop, zouk, kompa\nFrench pop, zouk, novelty\nFrench pop, zouk, salsa\nFrench pop, zouk, soca\nFrench pop, zouk, soukous\nFrench pop, zouk, world music\nFrench pop-EDM\nFrench pop-R&B\nFrench pop-R&B chiptune\nFrench pop-R&B future bass\nFrench pop-R&B lo-fi hip-hop\nFrench pop-chanson\nFrench pop-chanson jazz\nFrench pop-chanson, Latin rhythm\nFrench pop-chanson, ska\nFrench pop-dance\nFrench pop-dance tropical house\nFrench pop-folk\nFrench pop-funk\nFrench pop-gospel\nFrench pop-house\nFrench pop-punk\nFrench pop-rap\nFrench pop-rap Arabic trap\nFrench pop-rap afro-trap\nFrench pop-rap afrobeat\nFrench pop-rap chiptune\nFrench pop-rap cumbia\nFrench pop-rap indie pop\nFrench pop-rap lo-fi hip-hop\nFrench pop-rap nu-disco\nFrench pop-rap nu-disco funk\nFrench pop-rap reggaeton\nFrench pop-rap tropical\nFrench pop-rap, Caribbean fusion\nFrench pop-rap, G-funk\nFrench pop-rap, Latin, flamenco\nFrench pop-rap, Middle Eastern fusion\nFrench pop-rap, Rai\nFrench pop-rap, Rai, electronic\nFrench pop-rap, Rai, electronic dance\nFrench pop-rap, Rai, reggaeton\nFrench pop-rap, baile funk\nFrench pop-rap, deep house\nFrench pop-rap, nu-disco, funk\nFrench pop-rap, reggaeton, Latin pop\nFrench pop-rap, reggaeton, dance\nFrench pop-rap, reggaeton, dancehall\nFrench pop-rap, synthwave, ambient\nFrench pop-rap, trap\nFrench pop-reggae\nFrench pop-reggaeton\nFrench pop-rock\nFrench pop-rock 80s\nFrench pop-rock bossa nova\nFrench pop-rock cabaret\nFrench pop-rock exotica\nFrench pop-rock funk\nFrench pop-rock hip-hop\nFrench pop-rock reggae\nFrench pop-rock yé-yé\nFrench pop-rock, 80s new wave\nFrench pop-rock, Italo-disco\nFrench pop-rock, Italo-disco, 80s synth\nFrench pop-rock, Latin pop, big band\nFrench pop-rock, Rai, fusion\nFrench pop-rock, cumbia, upbeat\nFrench pop-rock, drum and bass, cinematic\nFrench pop-rock, gypsy jazz\nFrench pop-rock, gypsy-punk\nFrench pop-rock, hip-hop\nFrench pop-rock, rockabilly, retro\nFrench pop-rock, ska, funk\nFrench pop-soul\nFrench pop-trap\nFrench power ballad\nFrench protest\nFrench psychedelic\nFrench pub-rock\nFrench punk rock\nFrench punk-chanson\nFrench punk-ska\nFrench rap\nFrench rap Arabic pop\nFrench rap cumbia\nFrench rap hardstyle\nFrench rap lo-fi hip-hop\nFrench rap reggaeton\nFrench rap trap\nFrench rap, Afro-Latin, electronic\nFrench rap, Afro-trap\nFrench rap, Afro-trap, melodic rap\nFrench rap, Afrobeat, North African pop\nFrench rap, Afrobeats, North African pop\nFrench rap, Arabic pop, electronic\nFrench rap, Arabic pop, electronic dance\nFrench rap, Arabic pop, reggaeton\nFrench rap, Balkan brass, electronic dance\nFrench rap, Eurodance, trap\nFrench rap, Latin hip hop\nFrench rap, Latin hip-hop\nFrench rap, Latin pop, afrobeat\nFrench rap, Latin pop, jazz fusion\nFrench rap, Latin trap\nFrench rap, Middle Eastern dance\nFrench rap, North African pop\nFrench rap, North African pop, R&B\nFrench rap, North African pop, dancehall\nFrench rap, North African pop, electronic\nFrench rap, North African pop, reggaeton\nFrench rap, North African pop-R&B\nFrench rap, North African pop-rap\nFrench rap, North African, melancholic\nFrench rap, R&B, acoustic\nFrench rap, R&B, gospel\nFrench rap, Rai fusion\nFrench rap, Rai, electronic\nFrench rap, Rai, synthwave\nFrench rap, Rai, trap\nFrench rap, Raï, electronic\nFrench rap, afro-trap\nFrench rap, ambient hip hop\nFrench rap, ambient, breakbeat\nFrench rap, atmospheric R&B, lo-fi hip hop\nFrench rap, atmospheric electronica, cinematic hip hop\nFrench rap, atmospheric, melancholic\nFrench rap, baile funk\nFrench rap, baroque synth, boom-bap\nFrench rap, boom-bap, ambient\nFrench rap, boom-bap, cinematic\nFrench rap, boom-bap, cinematic hip hop\nFrench rap, boom-bap, psychedelic\nFrench rap, boom-bap, synthwave\nFrench rap, chiptune\nFrench rap, chiptune, afro-trap\nFrench rap, chiptune, electronic\nFrench rap, chiptune, lo-fi\nFrench rap, chiptune, synth-pop\nFrench rap, chiptune, trap\nFrench rap, cinematic\nFrench rap, cinematic hip hop\nFrench rap, cinematic, melancholic\nFrench rap, cloud rap, afro-trap\nFrench rap, cyberpunk, electronic\nFrench rap, dance-pop, Arabic fusion\nFrench rap, dancehall, electronic\nFrench rap, dancehall, reggaeton\nFrench rap, dreamy R&B, lo-fi hip hop\nFrench rap, dreamy trap\nFrench rap, drum and bass\nFrench rap, drum and bass, lo-fi hip hop\nFrench rap, electronic, North African fusion\nFrench rap, electronic, club\nFrench rap, emotional R&B\nFrench rap, emotional R&B, trap\nFrench rap, emotional pop, lo-fi hip hop\nFrench rap, hardstyle, gabber\nFrench rap, industrial hip hop, cyberpunk\nFrench rap, lo-fi boom-bap\nFrench rap, lo-fi hip hop\nFrench rap, lo-fi hip hop, cinematic\nFrench rap, lo-fi hip hop, melancholic\nFrench rap, lo-fi hip hop, trap\nFrench rap, lo-fi hip-hop\nFrench rap, neo-soul, minimalist hip-hop\nFrench rap, phonk, anime\nFrench rap, reggaeton\nFrench rap, reggaeton, afrobeat\nFrench rap, reggaeton, dance\nFrench rap, soulful R&B, lo-fi hip hop\nFrench rap, trap\nFrench rap, trap, Afro-Caribbean\nFrench rap, trap, Arabic fusion\nFrench rap, trap, Balkan fusion\nFrench rap, trap, Latin guitar\nFrench rap, trap, North African\nFrench rap, trap, acoustic\nFrench rap, trap, ambient\nFrench rap, trap, boom-bap, hyperpop\nFrench rap, trap, chiptune\nFrench rap, trap, cinematic\nFrench rap, trap, electronic\nFrench rap, trap, emotional piano\nFrench rap, trap, gritty\nFrench rap, trap, lo-fi\nFrench rap, trap, melodic hip hop\nFrench rap, trap, orchestral\nFrench rap, trap, phonk\nFrench rap, zouk, dancehall\nFrench rap-rock\nFrench reggae\nFrench reggae dancehall\nFrench reggae dub\nFrench reggae rocksteady\nFrench reggae-pop\nFrench reggae-pop tropical house\nFrench reggae-rap\nFrench reggae-ska\nFrench reggaeton\nFrench reggaeton hardstyle\nFrench reggaeton tropical house\nFrench rock\nFrench rock 'n' roll\nFrench rock and roll\nFrench rock ballad\nFrench rock boogie-woogie\nFrench rock cabaret\nFrench rock cabaret ska\nFrench rock chiptune\nFrench rock garage rock\nFrench rock opera\nFrench rock post-punk\nFrench rock punk\nFrench rock ska punk\nFrench rock surf rock\nFrench rock surf-rock\nFrench rock yé-yé\nFrench rock, 80s new wave\nFrench rock, Americana, roots rock\nFrench rock, Latin rock, psychedelic\nFrench rock, big band, swing\nFrench rock, boogie-woogie\nFrench rock, boogie-woogie, rockabilly\nFrench rock, cabaret, Latin\nFrench rock, country rock\nFrench rock, garage rock, 60s rock\nFrench rock, garage rock, theatrical rock\nFrench rock, new wave\nFrench rock, new wave, synth-pop\nFrench rock, new wave, theatrical rock\nFrench rock, nou-disco, funk\nFrench rock, polka, punk rock\nFrench rock, reggae, dub\nFrench rock, rockabilly\nFrench rock, rockabilly, big band\nFrench rock, rockabilly, chanson\nFrench rock, rockabilly, country\nFrench rock, rockabilly, country rock\nFrench rock, rockabilly, vintage swing\nFrench rock, ska, Latin rock\nFrench rock, ska, big band\nFrench rock, ska, rockabilly\nFrench rock, spaghetti western\nFrench rock, surf rock\nFrench rock, thrash metal\nFrench rumba\nFrench samba\nFrench sea shanty\nFrench show tune\nFrench show tune, big band, novelty\nFrench ska-chanson\nFrench ska-pop\nFrench ska-punk\nFrench ska-reggae\nFrench ska-swing\nFrench soul\nFrench soul jazz-pop\nFrench soul-funk\nFrench soul-pop\nFrench soul-rock\nFrench spoken word\nFrench sports anthem\nFrench street rap\nFrench swing\nFrench swing jazz\nFrench swing rockabilly\nFrench swing-pop\nFrench swing-pop jazz\nFrench synth-pop\nFrench synth-pop nu-disco\nFrench synthwave\nFrench tech house\nFrench tech-house\nFrench techno\nFrench theatrical rock\nFrench trap\nFrench trap R&B\nFrench trap chiptune\nFrench trap emo-rap\nFrench trap lo-fi chiptune\nFrench trap world music\nFrench trap, Afro-trap\nFrench trap, Afrobeats\nFrench trap, Afrobeats, Latin pop\nFrench trap, Afrobeats, R&B\nFrench trap, Latin acoustic\nFrench trap, Latin fusion\nFrench trap, Latin hip-hop\nFrench trap, Latin pop\nFrench trap, Latin pop, reggaeton\nFrench trap, North African pop\nFrench trap, R&B\nFrench trap, R&B, soul\nFrench trap, Rai fusion\nFrench trap, acoustic ballad\nFrench trap, alternative R&B\nFrench trap, big band swing\nFrench trap, boom-bap\nFrench trap, chiptune\nFrench trap, cinematic\nFrench trap, cinematic pop\nFrench trap, cinematic, Brazilian pop\nFrench trap, cloud rap\nFrench trap, cloud rap, Middle Eastern fusion\nFrench trap, cloud rap, R&B\nFrench trap, cloud rap, emo trap\nFrench trap, cloud rap, emotional hip-hop\nFrench trap, cloud rap, future bass\nFrench trap, cloud rap, vaporwave\nFrench trap, drill\nFrench trap, emo trap\nFrench trap, hyperpop\nFrench trap, lo-fi hip hop\nFrench trap, lo-fi, vaporwave\nFrench trap, piano ballad, rock\nFrench trap, pop, electronic\nFrench trap, pop-rap\nFrench trap, trap metal\nFrench trap, vaporwave\nFrench trap-R&B\nFrench trap-pop\nFrench trap-rap\nFrench trap-soul\nFrench tropical pop\nFrench urban pop\nFrench waltz\nFrench western novelty\nFrench world music\nFrench world-pop\nFrench worldbeat\nFrench yé-yé\nFrench-Arabic pop\nFrench-Arabic pop-rap\nFrench-Canadian chanson\nFrench-Canadian folk\nFrench-Canadian folk, Latin, salsa\nFrench-Canadian folk, bluegrass\nFrench-Canadian folk, country-western, cabaret\nFrench-Canadian folk-country\nFrench-Canadian hip-hop\nFrench-Canadian novelty\nFrenchcore\nFrenchcore hyperpop\nFrenchcore, chiptune\nFretless\nFunk Carioca\nFunk Mandelão\nFunk Piseiro\nFunk Rave\nFunk, Arabic fusion\nFunkot\nFunkot Bhangra\nFunkot Bhojpuri\nFunkot Cumbia House\nFunkot Dangdut Koplo\nFunkot gabber\nFunkot, Bhojpuri DJ remix\nFunkot, Bhojpuri dance\nFunkot, Bhojpuri electronic\nFunkot, Bhojpuri pop\nFunkot, Bollywood dance\nFunkot, Dangdut Koplo\nFunkot, Dangdut Koplo, happy hardcore\nFunkot, EDM\nFunkot, EDM, South Asian electronic\nFunkot, Indian House\nFunkot, K-pop, R&B\nFunkot, gabber, rave\nFunkot, happy hardcore\nFunkot, happy hardcore, Dangdut Koplo\nFunkot, happy hardcore, nightcore\nFunkot, hard house, happy hardcore\nFunkot, hardstyle\nFunkot, regional house\nFunkot, speedcore\nFunky Kota\nG-Funk\nG-funk\nG-funk 90s hip-hop\nG-funk Afro-fusion\nG-funk Brazilian hip-hop\nG-funk Chicano rap\nG-funk Christian hip-hop\nG-funk Cumbia hip-hop\nG-funk Desi Hip Hop\nG-funk Deutschrap\nG-funk Dutch hip-hop\nG-funk French hip-hop\nG-funk German hip-hop\nG-funk Hawaiian hip-hop\nG-funk J-hip-hop\nG-funk Japanese hip-hop\nG-funk Korean hip-hop\nG-funk Latin R&B\nG-funk Latin fusion\nG-funk Latin hip-hop\nG-funk Latin soul\nG-funk N-funk\nG-funk R&B\nG-funk R&B hip-hop\nG-funk Russian hip-hop\nG-funk Southern Hip Hop\nG-funk Southern hip-hop\nG-funk Spanish hip-hop\nG-funk Swedish hip-hop\nG-funk Thai hip-hop\nG-funk Turkish hip-hop\nG-funk UK hip-hop\nG-funk West Coast hip-hop\nG-funk acid jazz\nG-funk acid jazz hip-hop\nG-funk alternative rock\nG-funk blues-rock\nG-funk boogie\nG-funk boom-bap\nG-funk chillhop\nG-funk chiptune\nG-funk chiptune hip-hop\nG-funk cinematic\nG-funk city pop\nG-funk city pop hip-hop\nG-funk cloud rap\nG-funk comedy\nG-funk conscious hip-hop\nG-funk dancehall\nG-funk dancehall hip-hop\nG-funk deep funk\nG-funk electro-funk\nG-funk electro-house\nG-funk flamenco\nG-funk funk\nG-funk funk hip-hop\nG-funk funk-hop\nG-funk funk-rap\nG-funk funk-rock\nG-funk gangsta rap\nG-funk hip hop\nG-funk hip-hop\nG-funk hip-hop soul\nG-funk hip-hop vaporwave\nG-funk hip-hop, orchestral trap\nG-funk hip-hop, trap\nG-funk hip-house\nG-funk horrorcore\nG-funk house\nG-funk jazz-funk\nG-funk jazz-hop\nG-funk jazz-rap\nG-funk lo-fi\nG-funk lo-fi hip hop\nG-funk lo-fi hip-hop\nG-funk lowrider hip-hop\nG-funk neo-soul\nG-funk neo-soul hip-hop\nG-funk old-school hip-hop\nG-funk orchestral\nG-funk parody\nG-funk party rap\nG-funk pop-rap\nG-funk rap\nG-funk rap-rock\nG-funk reggae\nG-funk reggae fusion\nG-funk reggae hip-hop\nG-funk reggaeton\nG-funk reggaeton hip-hop\nG-funk rock\nG-funk smooth jazz\nG-funk soul\nG-funk soul hip-hop\nG-funk soul-funk\nG-funk soul-hop\nG-funk soul-rap\nG-funk space hip-hop\nG-funk synth-pop\nG-funk synthwave\nG-funk trap\nG-funk trap hip-hop\nG-funk trap-house\nG-funk trap-soul\nG-funk trip-hop\nG-funk vaporwave\nG-funk, 90s R&B\nG-funk, 90s West Coast hip-hop\nG-funk, 90s hip-hop\nG-funk, 90s hip-hop, R&B\nG-funk, 90s hip-hop, West Coast\nG-funk, Brazilian hip-hop\nG-funk, California hip-hop\nG-funk, Cumbia rap\nG-funk, Desi Hip Hop\nG-funk, Dutch hip-hop\nG-funk, Finnish rap\nG-funk, German hip-hop\nG-funk, German hip-hop, boom-bap\nG-funk, Italian hip-hop, late-90s\nG-funk, Japanese hip hop\nG-funk, Japanese hip-hop\nG-funk, K-hip-hop\nG-funk, Korean hip-hop\nG-funk, Latin R&B, new jack swing\nG-funk, Latin hip-hop\nG-funk, Latin hip-hop, new jack swing\nG-funk, Mexican hip-hop\nG-funk, N-backus\nG-funk, New Jack Swing\nG-funk, New Jack Swing, R&B\nG-funk, R&B\nG-funk, R&B, bolero\nG-funk, R&B, comedy\nG-funk, R&B, hip-hop\nG-funk, R&B, lo-fi\nG-funk, R&B, lo-fi hip hop\nG-funk, R&B, soul\nG-funk, Russian gangster rap\nG-funk, Russian hip-hop\nG-funk, Southern hip-hop\nG-funk, Southern hip-hop, R&B\nG-funk, Southern hip-hop, crunk\nG-funk, Southern hip-hop, soul\nG-funk, Southern hip-hop, soulful hip-hop\nG-funk, Spanish hip-hop\nG-funk, Spanish-style, hip hop\nG-funk, Swedish hip-hop\nG-funk, Swedish hip-hop, soulful\nG-funk, Texas hip-hop\nG-funk, Thai pop, hip-hop\nG-funk, Turkish hip-hop\nG-funk, West Coast R&B\nG-funk, West Coast hip hop\nG-funk, West Coast hip hop, R&B\nG-funk, West Coast hip-hop\nG-funk, West Coast hip-hop, 90s R&B\nG-funk, West Coast hip-hop, Japanese hip-hop\nG-funk, West Coast hip-hop, Latin hip-hop\nG-funk, West Coast hip-hop, R&B\nG-funk, West Coast hip-hop, Spanish hip-hop\nG-funk, West Coast hip-hop, Spanish rap\nG-funk, West Coast hip-hop, cinematic hip-hop\nG-funk, West Coast hip-hop, cinematic rap\nG-funk, West Coast hip-hop, early 2000s gangsta rap\nG-funk, West Coast hip-hop, funk\nG-funk, West Coast hip-hop, lo-fi\nG-funk, West Coast hip-hop, narrative hip-hop\nG-funk, West Coast hip-hop, nostalgic hip-hop\nG-funk, West Coast hip-hop, psychedelic\nG-funk, West Coast hip-hop, soul\nG-funk, West Coast hip-hop, soulful R&B\nG-funk, West Coast hip-hop, synth bass\nG-funk, West Coast hip-hop, synthwave\nG-funk, West Coast pop\nG-funk, West Coast rap\nG-funk, West Coast rap, lo-fi hip hop\nG-funk, West Coast, ambient\nG-funk, acid jazz, hip-hop\nG-funk, acid jazz, instrumental hip-hop\nG-funk, ambient, hip-hop\nG-funk, boom-bap\nG-funk, boom-bap, French hip-hop\nG-funk, boom-bap, French rap\nG-funk, boom-bap, Latin hip-hop\nG-funk, boom-bap, R&B\nG-funk, boom-bap, West Coast hip-hop\nG-funk, boom-bap, cinematic\nG-funk, boom-bap, cinematic hip-hop\nG-funk, boom-bap, hip hop\nG-funk, boom-bap, hip-hop\nG-funk, boom-bap, instrumental hip-hop\nG-funk, boombap, Brazilian hip-hop\nG-funk, chillhop, West Coast hip-hop\nG-funk, chillwave\nG-funk, chillwave, hip-hop\nG-funk, chiptune, hip-hop\nG-funk, chiptune, lo-fi\nG-funk, chopped and screwed\nG-funk, cinematic\nG-funk, cinematic hip hop\nG-funk, cinematic hip-hop\nG-funk, cinematic orchestral\nG-funk, cinematic synth\nG-funk, cinematic, Bollywood\nG-funk, cinematic, West Coast\nG-funk, cinematic, West Coast hip-hop\nG-funk, cinematic, chiptune\nG-funk, cinematic, dark hip hop\nG-funk, cinematic, dark synth\nG-funk, cinematic, gangsta rap\nG-funk, cinematic, hip hop\nG-funk, cinematic, hip-hop\nG-funk, cinematic, italo-disco\nG-funk, cinematic, lo-fi\nG-funk, cinematic, lo-fi hip hop\nG-funk, cinematic, operatic\nG-funk, cinematic, orchestral\nG-funk, cinematic, soul\nG-funk, cinematic, soulful\nG-funk, cinematic, synthwave\nG-funk, city pop, hip-hop\nG-funk, cloud rap\nG-funk, cloud rap, lo-fi hip hop\nG-funk, cloud rap, trap\nG-funk, conscious hip-hop\nG-funk, conscious hip-hop, R&B\nG-funk, conscious hip-hop, West Coast hip-hop\nG-funk, conscious hip-hop, boom-bap\nG-funk, conscious hip-hop, soul\nG-funk, conscious hip-hop, vaporwave\nG-funk, country-folk, bluegrass\nG-funk, dancehall, hip-hop\nG-funk, dream pop, lo-fi hip hop\nG-funk, electro-funk, hip-hop\nG-funk, electro-funk, old-school hip-hop\nG-funk, gangsta rap\nG-funk, gangsta rap, West Coast hip hop\nG-funk, gangsta rap, cinematic\nG-funk, gangsta rap, synth bass\nG-funk, gangster rap\nG-funk, glitch hop\nG-funk, hip hop\nG-funk, hip hop, Latin trap\nG-funk, hip hop, cinematic\nG-funk, hip hop, soul\nG-funk, hip-hop\nG-funk, hip-hop, Filipino\nG-funk, hip-hop, Latin hip-hop\nG-funk, hip-hop, Latin rap\nG-funk, hip-hop, Mexican hip-hop\nG-funk, hip-hop, Mexican rap\nG-funk, hip-hop, R&B\nG-funk, hip-hop, Texas rap\nG-funk, hip-hop, West Coast\nG-funk, hip-hop, cinematic\nG-funk, hip-hop, corridos tumbados\nG-funk, hip-hop, lo-fi\nG-funk, hip-hop, new jack swing\nG-funk, hip-hop, regional Mexican\nG-funk, hip-hop, video game music\nG-funk, horrorcore\nG-funk, horrorcore, West Coast hip-hop\nG-funk, lo-fi hip hop\nG-funk, lo-fi hip hop, West Coast\nG-funk, lo-fi hip hop, soul\nG-funk, lowrider hip-hop\nG-funk, neo-soul\nG-funk, neo-soul, 90s hip-hop\nG-funk, neo-soul, R&B\nG-funk, neo-soul, hip-hop\nG-funk, neo-soul, instrumental hip-hop\nG-funk, neo-soul, world music\nG-funk, new jack swing\nG-funk, new jack swing, Dutch rap\nG-funk, new jack swing, German hip-hop\nG-funk, new jack swing, Japanese hip-hop\nG-funk, new jack swing, K-rap\nG-funk, new jack swing, Korean R&B\nG-funk, new jack swing, Korean hip-hop\nG-funk, new jack swing, Latin hip-hop\nG-funk, new jack swing, Mandopop\nG-funk, new jack swing, R&B\nG-funk, new jack swing, Russian\nG-funk, new jack swing, chiptune\nG-funk, new jack swing, funk hip-hop\nG-funk, new jack swing, gospel R&B\nG-funk, new jack swing, hip hop\nG-funk, new jack swing, hip-hop\nG-funk, new jack swing, lo-fi hip hop\nG-funk, new jack swing, retro hip-hop\nG-funk, new jack swing, video game music\nG-funk, nu-metal, hip hop\nG-funk, old-school hip-hop\nG-funk, old-school hip-hop, cinematic\nG-funk, old-school hip-hop, new jack swing\nG-funk, orchestral, gangsta rap\nG-funk, orchestral, soul\nG-funk, party hip-hop\nG-funk, pop-R&B, cinematic\nG-funk, psychedelic hip hop\nG-funk, psychedelic soul\nG-funk, psychedelic, lo-fi\nG-funk, psychedelic, lo-fi hip hop\nG-funk, reggae hip-hop\nG-funk, regional Mexican, party\nG-funk, sleek, hip hop\nG-funk, slow jam, hip-hop\nG-funk, soul, hip hop\nG-funk, soul, hip-hop\nG-funk, soul, jazz-rock\nG-funk, soulful R&B\nG-funk, summer hip-hop\nG-funk, trap soul, R&B\nG-funk, trap, new jack swing\nG-funk, vaporwave, chill hop\nG-funk, vaporwave, lo-fi hip hop\nG-funk, video game music\nG-funk, video game music, 90s hip hop\nG-funk, video game music, synth funk\nGaana\nGaana Kuthu\nGaana, Kuthu, South Indian dance\nGaita\nGaita Manouche\nGaita Zouk\nGaita Zuliana\nGalician folk\nGalician folk rock\nGalician folk, chiptune\nGalician folk, retro synth, video game music\nGalician folk, theatrical, show tune\nGalician folk-pop\nGalician folk-rock\nGalician pop-rock\nGamelan\nGarba\nGarba Bhangra\nGarba Bhojpuri\nGarba Dandiya\nGarba Holi\nGarba bhajan\nGarba folk\nGarba fusion\nGarba fusion, electronic dance, hip-hop\nGarba, Indian folk\nGaucho\nGaucho Fandango\nGaucho ballad\nGaucho folk\nGaucho music\nGaucho party\nGaúcha\nGaúcha folk\nGaúcho\nGaúcho Vaneira\nGaúcho folk\nGaúcho folk-rock\nGaúcho gospel\nGaúcho music\nGaúcho music vaneira\nGaúcho waltz\nGaúcho, Sertanejo, Forró\nGaúcho, Vaneira, Sertanejo\nGaúcho, forró, Brazilian folk\nGaúcho, forró, rock\nGaúcho, forró, sertanejo\nGaúcho, forró, traditional Brazilian\nGerman Afro-pop\nGerman Afrobeats\nGerman Christian hip-hop\nGerman Christian pop\nGerman Christmas\nGerman Christmas ballad\nGerman Christmas carol\nGerman Christmas novelty\nGerman Christmas pop\nGerman Christmas rock\nGerman EDM\nGerman Euro-pop\nGerman Eurodance\nGerman Europop\nGerman Hands Up\nGerman Lied\nGerman Liedermacher\nGerman Partyschlager\nGerman Polka\nGerman Pop-R&B\nGerman Pop-Schlager\nGerman R&B\nGerman R&B cinematic\nGerman R&B hip-hop\nGerman R&B lo-fi hip hop\nGerman R&B lo-fi hip-hop\nGerman R&B lo-fi pop\nGerman R&B pop\nGerman R&B pop-rap\nGerman R&B trap\nGerman R&B trap-pop\nGerman R&B trap-soul\nGerman R&B tropical house\nGerman R&B, German trap\nGerman R&B, Latin pop\nGerman R&B, Latin trap\nGerman R&B, New Jack Swing\nGerman R&B, cloud rap, emo R&B\nGerman R&B, cloud rap, emo trap\nGerman R&B, hip-hop\nGerman R&B, hip-hop, early 2000s\nGerman R&B, lo-fi hip hop\nGerman R&B, pop\nGerman R&B, trap\nGerman R&B, trap, ambient\nGerman Schlager\nGerman Schlager EDM\nGerman Schlager Eurodance\nGerman Schlager chiptune\nGerman Schlager punk rock\nGerman Schlager rock\nGerman Schlager, 80s anime, synth pop\nGerman Schlager, Eurodance\nGerman Schlager, Eurodance, Happy Hardcore\nGerman Schlager, Eurodance, pop\nGerman Schlager, Latin Cumbia, European folk\nGerman Schlager, Latin pop\nGerman Schlager, cinematic pop\nGerman Schlager, cinematic, Euro-pop\nGerman Schlager, hard rock\nGerman Schlager, hard rock, Eurodance\nGerman Schlager, polka, chiptune\nGerman Schlager, synth-pop\nGerman Ska\nGerman alternative rock\nGerman anthem\nGerman art rock\nGerman art song\nGerman art song, cabaret, folk-punk\nGerman ballad\nGerman battle rap\nGerman battle rap trap\nGerman battle rap, chiptune, boom-bap\nGerman battle rap, chiptune, trap\nGerman battle rap, cinematic orchestral\nGerman battle rap, orchestral hip-hop\nGerman boom-bap\nGerman boom-bap, cinematic hip hop\nGerman boom-bap, cinematic, dark\nGerman boom-bap, dark trap\nGerman brass band\nGerman brass band hip-hop\nGerman cabaret\nGerman cabaret tango\nGerman cabaret, Schlager, swing\nGerman carnival\nGerman carnival rock\nGerman chanson\nGerman chanson cabaret\nGerman chanson cool jazz\nGerman chanson cool jazz bossa nova\nGerman chanson jazz\nGerman chanson jazz noir\nGerman chanson lounge\nGerman chanson lounge-jazz\nGerman chanson swing jazz\nGerman chanson, Latin, tango\nGerman chanson, cool jazz\nGerman chanson, gypsy jazz, cabaret\nGerman chanson, gypsy jazz, tango\nGerman chanson, synth-pop\nGerman chanson, theatrical, Latin rhythm\nGerman children's folk\nGerman children's music\nGerman children's song\nGerman chopper rap\nGerman cloud rap\nGerman cloud rap, hardstyle, trap metal\nGerman cloud rap, synth-pop\nGerman club\nGerman club-rap\nGerman comedy punk rock\nGerman comedy rap\nGerman comedy rap, Eurodance\nGerman comedy rap, electronic dance music\nGerman comedy rap, trap, hardstyle\nGerman comedy rock\nGerman comedy-pop\nGerman comedy-pop chiptune\nGerman comedy-rap\nGerman conscious hip-hop\nGerman country-folk\nGerman country-pop\nGerman country-rock\nGerman country-western\nGerman crossover rock\nGerman crunk\nGerman dance\nGerman dance-pop\nGerman dancehall\nGerman dancehall afrobeat\nGerman dancehall afrobeats\nGerman dancehall reggaeton\nGerman disco\nGerman disco-funk\nGerman disco-pop\nGerman drill\nGerman drill trap\nGerman drill, cinematic\nGerman drill, cinematic trap\nGerman drill, lo-fi ambient\nGerman drill, lo-fi hip hop\nGerman drill, trap\nGerman drill, trap, cinematic\nGerman electro-pop\nGerman electronic\nGerman electronic dance\nGerman electronic pop\nGerman electronic, chiptune, video game music\nGerman electropop\nGerman emo rap\nGerman emo-pop\nGerman emo-rap\nGerman experimental hip-hop\nGerman folk\nGerman folk blues\nGerman folk cabaret\nGerman folk chiptune\nGerman folk comedy\nGerman folk hip-hop\nGerman folk metal\nGerman folk novelty\nGerman folk polka\nGerman folk protest\nGerman folk rock\nGerman folk satire\nGerman folk tango\nGerman folk waltz\nGerman folk, EBM/industrial\nGerman folk, Hawaiian exotica\nGerman folk, Latin, world music\nGerman folk, Schlager, Western\nGerman folk, Schlager, polka\nGerman folk, bluegrass, country\nGerman folk, cabaret\nGerman folk, cabaret, lullaby\nGerman folk, country, western\nGerman folk, dark cabaret\nGerman folk, polka\nGerman folk, polka, Schlager\nGerman folk, polka, cabaret\nGerman folk, polka, gypsy jazz\nGerman folk, polka, synth folk\nGerman folk, pop-rap\nGerman folk, retro jingle\nGerman folk, sea shanty, Schlager\nGerman folk, sea shanty, theatrical\nGerman folk, techno\nGerman folk-country\nGerman folk-polka\nGerman folk-pop\nGerman folk-pop cabaret\nGerman folk-pop children's pop-rock\nGerman folk-pop chiptune\nGerman folk-pop gypsy jazz\nGerman folk-punk\nGerman folk-rock\nGerman folk-rock alternative rock\nGerman folk-rock punk\nGerman folk-rock, Schlager\nGerman folk-rock, anime power pop\nGerman folk-rock, psychedelic rock, psychedelic metal\nGerman freestyle rap\nGerman funk\nGerman funk-pop\nGerman funk-rap\nGerman gangsta rap\nGerman gangsta rap chiptune\nGerman gangsta rap, cinematic trap\nGerman gangsta rap, cinematic, trap\nGerman gangsta rap, trap\nGerman gangsta rap, trap, cinematic\nGerman gangster rap\nGerman gangster rap, atmospheric trap\nGerman hard rock\nGerman hardcore hip-hop\nGerman hardcore punk\nGerman heavy metal\nGerman heavy metal polka\nGerman hip hop\nGerman hip hop, boom-bap\nGerman hip hop, boom-bap, cinematic\nGerman hip hop, boom-bap, dark ambient\nGerman hip hop, boom-bap, dark electronic\nGerman hip hop, chiptune\nGerman hip hop, chiptune, dark trap\nGerman hip hop, cinematic boom-bap\nGerman hip hop, cinematic hip hop\nGerman hip hop, cinematic lo-fi\nGerman hip hop, cinematic rap\nGerman hip hop, cinematic synth, boom-bap\nGerman hip hop, cinematic trap\nGerman hip hop, dark ambient\nGerman hip hop, dark electronic\nGerman hip hop, dark trap\nGerman hip hop, electronic, neurofunk\nGerman hip hop, electronic, trap\nGerman hip hop, glitch hop\nGerman hip hop, lo-fi beat\nGerman hip hop, lo-fi boom-bap\nGerman hip hop, lo-fi, boom-bap\nGerman hip hop, soulful R&B\nGerman hip hop, trap\nGerman hip-hop\nGerman hip-hop Arabic fusion\nGerman hip-hop G-funk\nGerman hip-hop Latin fusion\nGerman hip-hop R&B\nGerman hip-hop alternative rock\nGerman hip-hop chiptune\nGerman hip-hop chiptune trap\nGerman hip-hop dance-pop\nGerman hip-hop deep house\nGerman hip-hop electro-house\nGerman hip-hop electro-pop\nGerman hip-hop electro-rock\nGerman hip-hop funk\nGerman hip-hop funk ska\nGerman hip-hop funk-rock\nGerman hip-hop horrorcore\nGerman hip-hop indie rock\nGerman hip-hop industrial\nGerman hip-hop jazz-rap\nGerman hip-hop lo-fi\nGerman hip-hop lo-fi boom-bap\nGerman hip-hop lo-fi chiptune\nGerman hip-hop lo-fi trap\nGerman hip-hop neo-soul\nGerman hip-hop nu-metal\nGerman hip-hop nu-metal electronicore\nGerman hip-hop punk rock\nGerman hip-hop reggae\nGerman hip-hop reggaeton\nGerman hip-hop rock\nGerman hip-hop rock crossover\nGerman hip-hop synth-pop\nGerman hip-hop tech-house\nGerman hip-hop trap\nGerman hip-hop vaporwave\nGerman hip-hop, Arabic trap\nGerman hip-hop, Balkan fusion\nGerman hip-hop, EDM, cinematic\nGerman hip-hop, EDM, trap\nGerman hip-hop, English hip-hop\nGerman hip-hop, Eurodance\nGerman hip-hop, Eurodance, chiptune\nGerman hip-hop, G-funk\nGerman hip-hop, G-funk, trap\nGerman hip-hop, Italo-disco\nGerman hip-hop, Latin funk, lo-fi hip hop\nGerman hip-hop, Latin fusion\nGerman hip-hop, Latin hip-hop\nGerman hip-hop, Latin pop\nGerman hip-hop, Latin pop-rap\nGerman hip-hop, Latin trap\nGerman hip-hop, Middle Eastern fusion\nGerman hip-hop, Middle Eastern pop\nGerman hip-hop, Middle Eastern trap\nGerman hip-hop, Middle Eastern, North African\nGerman hip-hop, Turkish hip-hop\nGerman hip-hop, alternative R&B\nGerman hip-hop, alternative pop\nGerman hip-hop, ambient, cinematic\nGerman hip-hop, ambient, ethereal\nGerman hip-hop, big band\nGerman hip-hop, boom-bap\nGerman hip-hop, boom-bap, cinematic\nGerman hip-hop, brostep, hardstyle\nGerman hip-hop, chiptune\nGerman hip-hop, chiptune, 8-bit\nGerman hip-hop, chiptune, boom-bap\nGerman hip-hop, chiptune, dark electronic\nGerman hip-hop, chiptune, electro\nGerman hip-hop, chiptune, electro-funk\nGerman hip-hop, chiptune, hyperpop\nGerman hip-hop, chiptune, nu-metal\nGerman hip-hop, chiptune, old-school\nGerman hip-hop, chiptune, phonk\nGerman hip-hop, chiptune, trap\nGerman hip-hop, cinematic\nGerman hip-hop, cinematic ambient\nGerman hip-hop, cinematic pop\nGerman hip-hop, cinematic pop-rap\nGerman hip-hop, cinematic rap\nGerman hip-hop, cinematic rock\nGerman hip-hop, cinematic synth\nGerman hip-hop, cinematic trap\nGerman hip-hop, cinematic, Arabic fusion\nGerman hip-hop, cinematic, ambient\nGerman hip-hop, cinematic, boom-bap\nGerman hip-hop, cinematic, dark ambient\nGerman hip-hop, cinematic, dark electronic\nGerman hip-hop, cinematic, electronic\nGerman hip-hop, cinematic, lo-fi\nGerman hip-hop, cinematic, melancholic\nGerman hip-hop, cinematic, orchestral\nGerman hip-hop, cinematic, trap\nGerman hip-hop, cloud rap, chiptune\nGerman hip-hop, cloud rap, psychedelic\nGerman hip-hop, cyberpunk\nGerman hip-hop, dark electronic\nGerman hip-hop, dark synth, boom-bap\nGerman hip-hop, dark trap\nGerman hip-hop, dreamy synth\nGerman hip-hop, electro-funk\nGerman hip-hop, electro-hop\nGerman hip-hop, electronic\nGerman hip-hop, emotional ballad, trap\nGerman hip-hop, emotional pop\nGerman hip-hop, ethereal trap\nGerman hip-hop, festive pop\nGerman hip-hop, funk, klezmer\nGerman hip-hop, gospel, soul\nGerman hip-hop, hard techno\nGerman hip-hop, hardstyle\nGerman hip-hop, hardstyle, EDM\nGerman hip-hop, hardstyle, chiptune\nGerman hip-hop, hardstyle, cinematic\nGerman hip-hop, hardstyle, electro\nGerman hip-hop, hardstyle, electronic\nGerman hip-hop, hardstyle, festival trap\nGerman hip-hop, hardstyle, gabber\nGerman hip-hop, hardstyle, psytrance\nGerman hip-hop, horrorcore\nGerman hip-hop, horrorcore, cinematic\nGerman hip-hop, hyperpop, trap\nGerman hip-hop, indie rock, industrial\nGerman hip-hop, industrial hip-hop\nGerman hip-hop, industrial hip-hop, cinematic rap\nGerman hip-hop, industrial, cinematic\nGerman hip-hop, industrial, lo-fi\nGerman hip-hop, lo-fi hip hop\nGerman hip-hop, lo-fi hip-hop\nGerman hip-hop, lo-fi hip-hop, trap\nGerman hip-hop, lo-fi, boom-bap\nGerman hip-hop, lo-fi, cinematic\nGerman hip-hop, lo-fi, cinematic trap\nGerman hip-hop, lo-fi, trap\nGerman hip-hop, metalcore\nGerman hip-hop, minimalist trap\nGerman hip-hop, new jack swing, retro\nGerman hip-hop, nu-disco, deep house\nGerman hip-hop, nu-metal\nGerman hip-hop, nu-metal, ambient\nGerman hip-hop, nu-metal, crossover\nGerman hip-hop, nu-metal, electronic\nGerman hip-hop, nu-metal, trap\nGerman hip-hop, old-school, chiptune\nGerman hip-hop, phonk, ambient\nGerman hip-hop, polka, party\nGerman hip-hop, pop-punk, dream-pop\nGerman hip-hop, pop-rap\nGerman hip-hop, pop-rock\nGerman hip-hop, pop-rock, cinematic\nGerman hip-hop, pop-rock, lo-fi\nGerman hip-hop, psychedelic rock\nGerman hip-hop, rap-rock\nGerman hip-hop, reggaeton, Latin hip-hop\nGerman hip-hop, reggaeton, Latin pop\nGerman hip-hop, reggaeton, lo-fi\nGerman hip-hop, rock, lo-fi\nGerman hip-hop, rock-influenced\nGerman hip-hop, synth-pop\nGerman hip-hop, synth-pop, retro\nGerman hip-hop, synthwave\nGerman hip-hop, techno, club\nGerman hip-hop, trap\nGerman hip-hop, trap, G-funk\nGerman hip-hop, trap, Latin R&B\nGerman hip-hop, trap, Middle Eastern fusion\nGerman hip-hop, trap, big band\nGerman hip-hop, trap, chiptune\nGerman hip-hop, trap, cinematic\nGerman hip-hop, trap, cloud rap, G-funk\nGerman hip-hop, trap, cyberpunk\nGerman hip-hop, trap, dark ambient\nGerman hip-hop, trap, electronic\nGerman hip-hop, trap, futuristic\nGerman hip-hop, trap, novelty rap\nGerman hip-hop, trap, synthwave\nGerman hip-hop, trap-metal, nu-metal\nGerman hip-hop, trap/R&B\nGerman hip-hop, vaporwave, trap\nGerman hip-house\nGerman horrorcore\nGerman horrorcore, cinematic trap\nGerman hyperpop\nGerman indie dance\nGerman indie pop\nGerman indie pop neo-soul\nGerman indie pop surf rock\nGerman indie rock\nGerman indie rock hip-hop\nGerman indie rock ska-punk\nGerman indie-folk\nGerman indie-pop\nGerman indie-pop funk\nGerman indie-pop funk disco\nGerman indie-pop nu-disco\nGerman indie-rap\nGerman jazz\nGerman lullaby\nGerman march\nGerman marching song\nGerman narrative hip-hop\nGerman narrative rap\nGerman new wave\nGerman novelty\nGerman novelty, ambient ballad\nGerman party\nGerman party anthem\nGerman party chant\nGerman party rap\nGerman party rock\nGerman party schlager\nGerman party-rap\nGerman party-schlager\nGerman party-schlager reggaeton\nGerman party-techno\nGerman partyschlager\nGerman phonk\nGerman political anthem\nGerman political hip-hop\nGerman political rap\nGerman polka\nGerman polka-pop\nGerman polka-schlager\nGerman pop\nGerman pop Afrobeats\nGerman pop Arabic pop Latin pop\nGerman pop R&B\nGerman pop ballad\nGerman pop bossa nova\nGerman pop cabaret\nGerman pop cabaret swing\nGerman pop chiptune\nGerman pop emo-rap\nGerman pop folk\nGerman pop funk\nGerman pop funk disco\nGerman pop future bass\nGerman pop jazz\nGerman pop lo-fi hip-hop\nGerman pop lounge exotica\nGerman pop reggae\nGerman pop reggaeton\nGerman pop soul\nGerman pop trap\nGerman pop tropical\nGerman pop waltz\nGerman pop world music\nGerman pop, 80s Schlager, cinematic\nGerman pop, 80s funk, disco\nGerman pop, 90s Europop\nGerman pop, Afrobeat, dancehall\nGerman pop, Arabic fusion\nGerman pop, EDM\nGerman pop, EDM, ballad\nGerman pop, EDM, dance-pop\nGerman pop, EDM, future bass\nGerman pop, Eurodance\nGerman pop, Eurodance, ambient\nGerman pop, J-pop\nGerman pop, K-pop\nGerman pop, Latin pop\nGerman pop, Latin pop, Schlager\nGerman pop, Latin pop, dance\nGerman pop, Latin pop, dance pop\nGerman pop, Latin pop, hip-hop\nGerman pop, Latin pop, reggaeton\nGerman pop, Latin pop, tropical\nGerman pop, Latin pop, tropical house\nGerman pop, Latin pop, upbeat\nGerman pop, Latin-pop\nGerman pop, R&B\nGerman pop, R&B, chiptune\nGerman pop, R&B, dance-pop\nGerman pop, R&B, funk\nGerman pop, R&B, hip-hop\nGerman pop, R&B, lo-fi hip-hop\nGerman pop, R&B, trap\nGerman pop, Schlager, 80s\nGerman pop, Schlager, 80s pop\nGerman pop, Schlager, 80s synth\nGerman pop, Schlager, Neue Deutsche Welle\nGerman pop, Schlager, big band\nGerman pop, Schlager, bubblegum pop\nGerman pop, Schlager, dance-pop\nGerman pop, Schlager, hip-hop\nGerman pop, Schlager, power ballad\nGerman pop, Schlager, retro\nGerman pop, Schlager, trap\nGerman pop, afrobeat, trap\nGerman pop, boogaloo, Latin pop\nGerman pop, bossa nova\nGerman pop, cabaret, Latin pop\nGerman pop, cabaret, big band\nGerman pop, chiptune\nGerman pop, cinematic, 80s Schlager\nGerman pop, cinematic, Christmas\nGerman pop, circus pop, polka\nGerman pop, dance-pop\nGerman pop, dancehall, reggaeton\nGerman pop, emo rap, electronic\nGerman pop, emo rap, trap\nGerman pop, folk pop\nGerman pop, funk, R&B\nGerman pop, funk, disco\nGerman pop, future bass\nGerman pop, future pop, trap\nGerman pop, hardstyle, trance\nGerman pop, hyperpop\nGerman pop, lo-fi hip hop, atmospheric\nGerman pop, lo-fi hip-hop\nGerman pop, metalcore\nGerman pop, musical theatre\nGerman pop, neo-soul, R&B\nGerman pop, neo-soul, funk\nGerman pop, reggae, dancehall\nGerman pop, reggaeton\nGerman pop, reggaeton, Arabic pop\nGerman pop, reggaeton, Latin pop\nGerman pop, reggaeton, dancehall\nGerman pop, retro game, Schlager\nGerman pop, retro video game\nGerman pop, retro, big-band\nGerman pop, retro, exotica\nGerman pop, retro-schlager\nGerman pop, satirical pop, Eurodance\nGerman pop, ska, swing\nGerman pop, swing, lounge\nGerman pop, tango, ballad\nGerman pop, theatrical pop, show tune\nGerman pop, trap\nGerman pop, trap, R&B\nGerman pop, trap, chiptune\nGerman pop, trap, electronic\nGerman pop, trap, future bass\nGerman pop, trap, hyperpop\nGerman pop, trip-hop, ballad\nGerman pop, worldbeat, novelty\nGerman pop-EDM\nGerman pop-R&B\nGerman pop-R&B tropical house\nGerman pop-R&B, cinematic, Middle Eastern fusion\nGerman pop-ballad\nGerman pop-dance\nGerman pop-folk\nGerman pop-funk\nGerman pop-house\nGerman pop-punk\nGerman pop-rap\nGerman pop-rap chiptune\nGerman pop-rap future bass\nGerman pop-rap lo-fi hip-hop\nGerman pop-rap reggae\nGerman pop-rap tropical house\nGerman pop-rap, Arabic dance\nGerman pop-rap, Arabic dance, electronic\nGerman pop-rap, Eurodance\nGerman pop-rap, Latin pop\nGerman pop-rap, Middle Eastern dance\nGerman pop-rap, Turkish pop-rap, trap\nGerman pop-rap, alternative rock\nGerman pop-rap, deep house\nGerman pop-rap, lo-fi hip-hop\nGerman pop-reggae\nGerman pop-reggaeton\nGerman pop-rock\nGerman pop-rock cabaret\nGerman pop-rock chiptune\nGerman pop-rock novelty\nGerman pop-rock, EDM, cinematic\nGerman pop-rock, EDM, hardstyle\nGerman pop-rock, Eurodance\nGerman pop-rock, Neue Deutsche Welle\nGerman pop-rock, Schlager, theatrical\nGerman pop-rock, big room house\nGerman pop-rock, chiptune\nGerman pop-rock, cumbia, quirky\nGerman pop-rock, dance-pop\nGerman pop-rock, happy hardcore\nGerman pop-rock, hyperpop\nGerman pop-schlager\nGerman pop-trap\nGerman pop-trap, lo-fi hip-hop\nGerman protest\nGerman protest folk\nGerman protest rap\nGerman punk rock\nGerman punk rock Neue Deutsche Härte\nGerman punk rock chiptune\nGerman punk rock electronicore\nGerman punk rock power metal\nGerman punk rock ska\nGerman punk rock ska-punk\nGerman punk rock synth-pop\nGerman punk rock, atmospheric ballad\nGerman punk rock, happy hardcore\nGerman punk rock, hardstyle, electronic\nGerman punk rock, trap\nGerman rap\nGerman rap dancehall\nGerman rap nu-metal\nGerman rap techno\nGerman rap, Arabic EDM\nGerman rap, Arabic fusion, Latin electronic\nGerman rap, EDM, hardcore\nGerman rap, Eurodance\nGerman rap, Turkish pop, Middle Eastern fusion\nGerman rap, Turkish pop, electronic\nGerman rap, aggressive rock, atmospheric\nGerman rap, alternative rock\nGerman rap, beatbox, live energy\nGerman rap, boom-bap, double-time\nGerman rap, brass band, polka\nGerman rap, chiptune, dubstep\nGerman rap, chiptune, electro\nGerman rap, chiptune, electronic\nGerman rap, chiptune, trap\nGerman rap, cinematic hip-hop\nGerman rap, cinematic trap\nGerman rap, cinematic, trap\nGerman rap, dembow, trap\nGerman rap, electronic\nGerman rap, electronic rock\nGerman rap, electronic, EDM\nGerman rap, electronic, chiptune\nGerman rap, electronic, dubstep\nGerman rap, electronic, game music\nGerman rap, electronic, trance\nGerman rap, halftime rock, electronic\nGerman rap, hard rock, aggressive\nGerman rap, hard techno, EBM\nGerman rap, hardstyle\nGerman rap, hardstyle, electronic\nGerman rap, industrial, EBM\nGerman rap, lo-fi, dubstep\nGerman rap, nerdcore, trap\nGerman rap, nu-metal, hip-hop\nGerman rap, pop-punk, electronic\nGerman rap, reggaeton, Latin pop\nGerman rap, stadium rock\nGerman rap, techno\nGerman rap, techno hip-hop\nGerman rap, techno, club\nGerman rap, techno, electronic\nGerman rap, techno, hardcore\nGerman rap, techno, trance\nGerman rap, trap, Balkan fusion\nGerman rap, trap, chiptune\nGerman rap, trap, cinematic\nGerman rap, trap, dark electronic\nGerman rap, trap, electronic\nGerman rap, trap, hardstyle\nGerman rap, trap, militant\nGerman rap, trap, phonk\nGerman rap, trap, rock\nGerman rap-rock\nGerman reggae\nGerman reggae ragga\nGerman reggaeton\nGerman rock\nGerman rock 'n' roll\nGerman rock Schlager\nGerman rock and roll\nGerman rock ballad\nGerman rock cabaret\nGerman rock country-rock\nGerman rock funk\nGerman rock punk\nGerman rock ska reggae\nGerman rock'n'roll\nGerman rock, 80s Schlager, dance rock\nGerman rock, EBM, industrial\nGerman rock, Neue Deutsche Welle\nGerman rock, Schlager\nGerman rock, Schlager, anthemic rock\nGerman rock, Schlager, ballad\nGerman rock, Schlager, cabaret\nGerman rock, Schlager, cinematic rock\nGerman rock, Schlager, live rock\nGerman rock, Schlager, party anthem\nGerman rock, Schlager, polka\nGerman rock, Schlager, pub rock\nGerman rock, Schlager, theatrical rock\nGerman rock, Spaghetti Western\nGerman rock, brass rock\nGerman rock, cabaret, swing\nGerman rock, cinematic, orchestral\nGerman rock, country-rock\nGerman rock, hardstyle\nGerman rock, new wave\nGerman rock, polka, Schlager\nGerman rock, ska, Neue Deutsche Welle\nGerman rock, ska-punk\nGerman schlager\nGerman schlager, Latin cumbia\nGerman schlager, forró, dance\nGerman schlager-pop\nGerman sci-fi rap\nGerman sea shanty\nGerman sea shanty chiptune\nGerman sea shanty, polka, folk rock\nGerman singer-songwriter\nGerman singer-songwriter pop\nGerman singer-songwriter, bossa nova\nGerman street rap\nGerman street-rap\nGerman tech house\nGerman tech-house\nGerman techno\nGerman techno-pop\nGerman techno-rap\nGerman trance\nGerman trap\nGerman trap Bollywood\nGerman trap R&B\nGerman trap chiptune\nGerman trap classical\nGerman trap metal\nGerman trap soul\nGerman trap, Arabic trap\nGerman trap, Balkan folk\nGerman trap, Bollywood fusion\nGerman trap, East Asian cinematic\nGerman trap, French pop\nGerman trap, G-funk\nGerman trap, Latin hip-hop\nGerman trap, Latin pop\nGerman trap, Latin trap\nGerman trap, Middle Eastern fusion\nGerman trap, R&B\nGerman trap, R&B, sad pop\nGerman trap, Turkish pop\nGerman trap, boom-bap\nGerman trap, chillwave, cinematic\nGerman trap, cinematic\nGerman trap, cinematic orchestral\nGerman trap, cinematic synth\nGerman trap, cinematic, Middle Eastern\nGerman trap, cinematic, world fusion\nGerman trap, cloud rap\nGerman trap, cloud rap, cinematic\nGerman trap, cloud rap, emo trap\nGerman trap, cloud rap, pop-rap\nGerman trap, cloud rap, synthwave\nGerman trap, contemporary R&B\nGerman trap, dark synthwave\nGerman trap, dream pop\nGerman trap, emo-rap\nGerman trap, horrorcore\nGerman trap, hyperpop\nGerman trap, hyperpop, chiptune\nGerman trap, lo-fi hip hop\nGerman trap, lo-fi synth\nGerman trap, lo-fi, cinematic\nGerman trap, melodic hip-hop\nGerman trap, nu-metal\nGerman trap, phonk\nGerman trap, phonk, orchestral\nGerman trap, pop-rap\nGerman trap, psychedelic\nGerman trap, soulful R&B\nGerman trap, synthwave\nGerman trap, trap-metal, melodic hip hop\nGerman trap, vaporwave\nGerman trap, vaporwave, R&B\nGerman trap, vaporwave, melodic R&B\nGerman trap-R&B\nGerman trap-metal\nGerman trap-pop\nGerman trap-rap\nGerman trap-rock\nGerman trap-soul\nGerman underground hip-hop\nGerman-style march\nGhazal\nGhazal Bollywood\nGhazal Indian folk\nGhazal Sufi Kirtan\nGhibli-esque\nGipsy Jazz\nGipsy Jazz, French chanson\nGipsy Jazz, German chanson, cabaret\nGipsy-folk\nGipsy-pop\nGospel Afrobeat\nGospel Afrobeats\nGospel Amapiano\nGospel Dancehall\nGospel Dancehall Soca\nGospel Soca\nGospel reggae\nGqom Amapiano hip-hop\nGqom hip-hop\nGreek Bossa Nova\nGreek Christian worship\nGreek Christmas\nGreek Christmas, cabaret, theatrical\nGreek EDM\nGreek Eurodance\nGreek Latin\nGreek Latin jazz\nGreek Laïko\nGreek Laïko Eurodance\nGreek Laïko funk-rock\nGreek Laïko hip-hop\nGreek Laïko metal\nGreek Laïko pop-rock\nGreek Laïko progressive rock\nGreek Laïko rock\nGreek Laïko surf rock\nGreek Laïko trap\nGreek Laïko, Arabic pop, electronic dance\nGreek Laïko, Balkan pop\nGreek Laïko, Balkan pop, electronic\nGreek Laïko, EDM\nGreek Laïko, Eurodance\nGreek Laïko, Eurodance, chiptune\nGreek Laïko, Middle Eastern fusion, pop-rock\nGreek Laïko, art song, cinematic\nGreek Laïko, cabaret, art song\nGreek Laïko, cinematic pop\nGreek Laïko, cinematic rock\nGreek Laïko, cinematic, art song\nGreek Laïko, dance-pop\nGreek Laïko, electronic dance\nGreek Laïko, electronic dance, cinematic\nGreek Laïko, electronic dance-pop\nGreek Laïko, electronic pop\nGreek Laïko, flamenco, world music\nGreek Laïko, hard rock\nGreek Laïko, jungle, dancehall\nGreek Laïko, pop\nGreek Laïko, soft rock, melancholic ballad\nGreek Laïko, stadium rock\nGreek Laïko-pop\nGreek Laïko-pop, EDM\nGreek Laïko-rock\nGreek R&B\nGreek R&B hip-hop\nGreek Rebetiko\nGreek Rumba Flamenca\nGreek Salsa\nGreek art music\nGreek art rock\nGreek art song\nGreek art-folk\nGreek art-pop\nGreek art-rock\nGreek ballad\nGreek ballad blues jazz\nGreek ballad blues-rock\nGreek ballad flamenco\nGreek ballad folk-rock\nGreek ballad jazz\nGreek ballad progressive rock\nGreek ballad rock\nGreek ballad tango\nGreek ballad, Latin jazz, bolero\nGreek ballad, big band jazz\nGreek ballad, hard rock\nGreek big band\nGreek boom-bap\nGreek cabaret\nGreek cabaret swing\nGreek chanson\nGreek children's\nGreek children's music\nGreek choral\nGreek classical\nGreek comedy-pop\nGreek cumbia\nGreek dance-pop\nGreek dance-pop reggaeton\nGreek disco-funk\nGreek disco-pop\nGreek drill\nGreek drill lo-fi\nGreek drill trap\nGreek drill, trap\nGreek folk\nGreek folk Latin dance\nGreek folk Latin fusion\nGreek folk ballad\nGreek folk big band\nGreek folk bluegrass\nGreek folk blues-rock\nGreek folk cabaret\nGreek folk chiptune\nGreek folk dance\nGreek folk dance-pop\nGreek folk electronic\nGreek folk electronic hip-hop\nGreek folk electronica\nGreek folk flamenco\nGreek folk fusion\nGreek folk hip-hop\nGreek folk house\nGreek folk jazz\nGreek folk metal\nGreek folk pop\nGreek folk pop-rock\nGreek folk punk\nGreek folk reggae\nGreek folk rock\nGreek folk rumba\nGreek folk swing\nGreek folk tango\nGreek folk tango cabaret\nGreek folk trap\nGreek folk, Balkan folk, folk-rock\nGreek folk, Balkan jazz, Gypsy jazz\nGreek folk, Balkan, Klezmer\nGreek folk, Balkan, upbeat\nGreek folk, Eurodance\nGreek folk, Laiko, cinematic\nGreek folk, Latin, Balkan\nGreek folk, Latin, Samba\nGreek folk, Laïko\nGreek folk, Laïko, Balkan\nGreek folk, Laïko, Balkan dance\nGreek folk, Laïko, ballad\nGreek folk, Laïko, big band\nGreek folk, Laïko, cinematic\nGreek folk, Laïko, cinematic pop\nGreek folk, Laïko, dance\nGreek folk, Laïko, flamenco\nGreek folk, Laïko, flamenco fusion\nGreek folk, Laïko, oud\nGreek folk, Laïko, ska\nGreek folk, Laïko, tango\nGreek folk, Laïko, theatrical\nGreek folk, Middle Eastern, ney\nGreek folk, Middle Eastern, spiritual\nGreek folk, bluegrass, Americana\nGreek folk, boogie-woogie, vintage pop\nGreek folk, cabaret, Latin\nGreek folk, cabaret, klezmer\nGreek folk, children's music\nGreek folk, chiptune\nGreek folk, cinematic pop\nGreek folk, dance-pop\nGreek folk, educational pop\nGreek folk, electronic dance\nGreek folk, electronic dance, fusion\nGreek folk, electronic dance, laiko\nGreek folk, electronic dance, worldbeat\nGreek folk, flamenco, Latin\nGreek folk, flamenco, Laïko\nGreek folk, laïko, cinematic\nGreek folk, ney, ambient\nGreek folk, oud, cinematic\nGreek folk, oud, electronic\nGreek folk, oud, pop-rock\nGreek folk, oud, world music\nGreek folk, progressive rock\nGreek folk, soft rock\nGreek folk, synth-pop\nGreek folk, tango, jazz\nGreek folk, world music, cinematic\nGreek folk, world music, neo-classical\nGreek folk-electronic\nGreek folk-pop\nGreek folk-pop chiptune\nGreek folk-pop rock\nGreek folk-rock\nGreek folk-rock alternative metal\nGreek folk-rock alternative rock\nGreek folk-rock funk-rock\nGreek folk-rock hard rock\nGreek folk-rock power metal\nGreek folk-rock psychedelic rock\nGreek folk-rock punk\nGreek folk-rock ska Balkan\nGreek folk-rock surf rock\nGreek folk-rock surf-rock\nGreek folk-rock synth-pop\nGreek folk-rock, Latin groove\nGreek folk-rock, Latin rhythms\nGreek folk-rock, hard rock\nGreek folk-rock, psychedelic rock\nGreek funk\nGreek funk-pop\nGreek funk-rock\nGreek fusion, Middle Eastern, rock\nGreek gospel\nGreek hard rock\nGreek hip hop\nGreek hip-hop\nGreek hip-hop R&B\nGreek hip-hop chiptune\nGreek hip-hop reggaeton\nGreek hip-hop trap\nGreek hip-hop vaporwave\nGreek hip-hop, Balkan pop\nGreek hip-hop, dark boom-bap\nGreek hip-hop, electronic dance\nGreek hip-hop, electronic dance, Balkan fusion\nGreek hip-hop, electronic dance, cinematic\nGreek hip-hop, pop-rock\nGreek house\nGreek indie rock\nGreek indie-pop\nGreek indie-pop surf-rock\nGreek jazz\nGreek jazz lounge\nGreek jazz tango\nGreek jazz-pop\nGreek jazz-swing\nGreek lament\nGreek laïko\nGreek marching band\nGreek new wave\nGreek novelty\nGreek novelty pop\nGreek nursery rhyme\nGreek opera\nGreek pop\nGreek pop 80s\nGreek pop Arabic pop\nGreek pop Arabic pop electronic dance\nGreek pop Latin fusion\nGreek pop ballad\nGreek pop cabaret swing\nGreek pop chiptune\nGreek pop flamenco\nGreek pop funk\nGreek pop hip-hop\nGreek pop reggaeton\nGreek pop trap\nGreek pop trap chiptune\nGreek pop, 80s pop, synth funk\nGreek pop, 80s pop, synthwave\nGreek pop, Arabic pop, electronic dance\nGreek pop, Balkan, cabaret\nGreek pop, Bossa Nova, jazz\nGreek pop, EDM\nGreek pop, Eurodance\nGreek pop, Eurodance, Latin pop\nGreek pop, Eurodance, Laïko\nGreek pop, Europop, Latin pop\nGreek pop, Latin exotica\nGreek pop, Latin pop\nGreek pop, Latin pop, Balkan pop\nGreek pop, Latin pop, Laïko\nGreek pop, Latin pop, cumbia\nGreek pop, Latin pop, dance\nGreek pop, Latin pop, playful\nGreek pop, Latin pop, salsa\nGreek pop, Latin salsa\nGreek pop, Latin, Balkan\nGreek pop, Latin, exotica\nGreek pop, Latin, salsa\nGreek pop, Laïko\nGreek pop, Laïko, Balkan\nGreek pop, Laïko, Balkan dance\nGreek pop, Laïko, Eurodance\nGreek pop, Laïko, dance\nGreek pop, Laïko, electronic\nGreek pop, Laïko, electronic dance\nGreek pop, Laïko, modern Laïko-pop\nGreek pop, Laïko, modern folk\nGreek pop, Laïko, vintage\nGreek pop, Middle Eastern pop\nGreek pop, Middle Eastern pop, dance pop\nGreek pop, big band\nGreek pop, big band, mambo\nGreek pop, chiptune, children's music\nGreek pop, cinematic, Laïko\nGreek pop, cinematic, electronic\nGreek pop, electronic dance\nGreek pop, electronic dance, Balkan fusion\nGreek pop, electronic dance, Middle Eastern fusion\nGreek pop, electronic dance, ethnic fusion\nGreek pop, electronic, Laïko\nGreek pop, electronic, reggaeton\nGreek pop, ethno-pop\nGreek pop, funk, Latin\nGreek pop, hip-hop, dancehall\nGreek pop, hip-hop, electronic dance\nGreek pop, hip-hop, trap\nGreek pop, moombahton\nGreek pop, reggae, theatrical\nGreek pop, reggaeton\nGreek pop, reggaeton, Latin\nGreek pop, reggaeton, Latin pop\nGreek pop, reggaeton, dancehall\nGreek pop, reggaeton, dembow\nGreek pop, reggaeton, electronic\nGreek pop, reggaeton, laïko\nGreek pop, reggaeton, moombahton\nGreek pop, synth-pop\nGreek pop, synth-pop, 80s\nGreek pop, trance, electronic\nGreek pop-dance\nGreek pop-folk\nGreek pop-folk, hard rock\nGreek pop-funk\nGreek pop-rap\nGreek pop-reggae\nGreek pop-reggaeton\nGreek pop-rock\nGreek pop-rock chiptune\nGreek pop-rock, Latin, salsa\nGreek pop-rock, acoustic ballad\nGreek pop-rock, electronic dance\nGreek pop-rock, world music\nGreek pop-trap\nGreek power ballad\nGreek power ballad, Laïko-pop\nGreek power-pop\nGreek protest\nGreek psychedelic rock\nGreek rap\nGreek rap, electronic trap\nGreek rap, pop-rock, electronic\nGreek reggae\nGreek reggae-pop\nGreek reggaeton\nGreek rock\nGreek rock ballad\nGreek rock blues\nGreek rock boogie-woogie\nGreek rock chiptune\nGreek rock cinematic\nGreek rock flamenco rumba\nGreek rock funk\nGreek rock post-punk\nGreek rock punk\nGreek rock reggae ska\nGreek rock surf rock\nGreek rock surf-rock\nGreek rock, 80s new wave\nGreek rock, Latin, salsa\nGreek rock, Laïko\nGreek rock, Laïko, theatrical rock\nGreek rock, cinematic, laïko\nGreek rock, cumbia, Latin rock\nGreek rock, new wave\nGreek rock, rockabilly, honky-tonk\nGreek rock, rockabilly, ska\nGreek rock, surf-rock, rockabilly\nGreek salsa\nGreek soft rock\nGreek song\nGreek soul\nGreek soul-funk\nGreek swing\nGreek synth-pop\nGreek tango\nGreek techno-pop\nGreek theatrical\nGreek traditional\nGreek trap\nGreek trap Arabic trap\nGreek trap R&B\nGreek trap reggaeton\nGreek trap, cloud rap\nGreek trap, electronic dance music\nGreek trap, hyperpop\nGreek trap, reggaeton\nGreek trap-pop\nGreek waltz\nGregorian chant\nGregorian chant, Schlager, Christian pop-rock\nGu Feng\nGu Feng C-pop\nGu Feng, cinematic, Vocaloid\nGu Feng, cinematic, pop-rock\nGuacha\nGufeng\nGufeng C-pop\nGufeng ballad\nGufeng cinematic\nGufeng orchestral\nGufeng, C-pop, chillwave\nGufeng, ambient pop\nGufeng, ambient, electronic\nGufeng, chill-hop, C-pop\nGufeng, chillwave, C-pop\nGufeng, cinematic, ambient\nGufeng, cinematic, ballad\nGufeng, cinematic, lo-fi\nGufeng, cinematic, melancholic\nGufeng, electronic, cinematic\nGufeng, electronic, modern Chinese\nGujarati DJ remix\nGujarati dance\nGujarati folk\nGujarati folk dance\nGujarati folk dance, electronic dance\nGujarati folk garageba\nGujarati folk hip-hop\nGujarati folk, electronic dance\nGujarati folk, electronic dance, fusion\nGujarati folk, electronic pop\nGujarati folk, garage, festive\nGujarati folk, garage, jimesha\nGujarati folk, synth-pop\nGujarati folk-dance\nGujarati folk-electronic\nGujarati folk-fusion\nGujarati folk-pop\nGujarati folk-rap\nGujarati garage\nGujarati garage boombra\nGujarati garageba\nGujarati hip-hop\nGujarati pop\nGujarati pop, EDM, Bhangra\nGuofeng\nGuofeng C-pop\nGuofeng Rock\nGuofeng electronic\nGuofeng electronic pop\nGuofeng hip-hop\nGuofeng jazz\nGuofeng pop\nGuofeng rock\nGuofeng trap\nGuofeng, C-pop, cinematic\nGypsy Jazz\nGypsy Jazz Balkan\nGypsy folk\nGypsy jazz\nGypsy jazz, Romanian folk, tango\nGypsy jazz, cabaret, German chanson\nGypsy jazz, folk rock\nGypsy pop\nHaitian Creole\nHaitian Creole hip-hop\nHaitian Creole music\nHaitian Creole pop\nHaitian Gospel\nHaitian Gospel Kompa\nHaitian Gospel Zouk\nHaitian Vodou\nHaitian dancehall\nHaitian drill\nHaitian folk\nHaitian folk, Middle Eastern folk\nHaitian folk, reggae\nHaitian folk-gospel\nHaitian gospel\nHaitian hip-hop\nHaitian rap\nHaitian rap trap\nHaitian rap, dancehall, electronic\nHaitian rap, trap\nHaitian rap, trap, Middle Eastern fusion\nHaitian rap, trap, drill\nHaitian rumba\nHaitian trap\nHalloween pop\nHalloween rock\nHalloween theme\nHaomba\nHaryanvi\nHaryanvi Bhajan\nHaryanvi Bhojpuri\nHaryanvi DJ\nHaryanvi DJ remix\nHaryanvi EDM\nHaryanvi club\nHaryanvi dance\nHaryanvi dance, electronic, folk fusion\nHaryanvi dance-pop\nHaryanvi devotional\nHaryanvi drill\nHaryanvi electronic\nHaryanvi folk\nHaryanvi folk chiptune\nHaryanvi folk dance\nHaryanvi folk hip-hop\nHaryanvi folk trap\nHaryanvi folk, Bollywood dance\nHaryanvi folk, EDM\nHaryanvi folk, Gujarati folk, electronic dance\nHaryanvi folk, Gujarati folk, fusion\nHaryanvi folk, Rajasthani folk, electronic dance\nHaryanvi folk, chiptune hip-hop\nHaryanvi folk, chiptune, electronic\nHaryanvi folk, chiptune, electronic dance\nHaryanvi folk, electronic dance\nHaryanvi folk, electronic dance music\nHaryanvi folk, electronic dance, chiptune\nHaryanvi folk, electronic dance, fusion\nHaryanvi folk, electronic dance, hip-hop\nHaryanvi folk, electronic dance, rap\nHaryanvi folk, electronic dance, trap\nHaryanvi folk, electronic, dance\nHaryanvi folk, hard electronic, dance\nHaryanvi folk, hardstyle\nHaryanvi folk, hardstyle, EDM\nHaryanvi folk-EDM\nHaryanvi folk-dance\nHaryanvi folk-electronic\nHaryanvi folk-pop\nHaryanvi folk-rap\nHaryanvi folk-trap\nHaryanvi fusion\nHaryanvi fusion, electronic dance\nHaryanvi hardstyle\nHaryanvi hip-hop\nHaryanvi hip-hop trap\nHaryanvi pop\nHaryanvi pop trap\nHaryanvi pop, Bhojpuri folk-pop\nHaryanvi pop, EDM, psychedelic\nHaryanvi pop, Gujarati folk-pop\nHaryanvi pop, electronic, trap\nHaryanvi pop, hip-hop\nHaryanvi pop, reggaeton, chiptune\nHaryanvi pop, trap\nHaryanvi pop, trap, electronic\nHaryanvi pop-rap\nHaryanvi rap\nHaryanvi rap chiptune\nHaryanvi rap trap\nHaryanvi rap, EDM trap\nHaryanvi rap, UK drill, trap\nHaryanvi rap, chiptune trap\nHaryanvi rap, hardstyle\nHaryanvi rap, hardstyle, trap\nHaryanvi rap, moombahton, dance\nHaryanvi techno\nHaryanvi trap\nHaryanvi trap-pop\nHaryanvi, Bhojpuri, dance\nHaryanvi, Bhojpuri, electronic folk\nHaryanvi, Indian folk, dance\nHaryanvi, North Indian folk, dance\nHawaiian\nHawaiian Christmas\nHawaiian Christmas, Western swing\nHawaiian Christmas, gypsy jazz\nHawaiian ballad\nHawaiian ceremonial\nHawaiian chant\nHawaiian choral\nHawaiian country\nHawaiian easy-listening\nHawaiian exotica\nHawaiian festive\nHawaiian folk\nHawaiian folk-pop\nHawaiian funk\nHawaiian fusion\nHawaiian indie pop\nHawaiian instrumental\nHawaiian jazz\nHawaiian lounge\nHawaiian music\nHawaiian music box\nHawaiian music hall\nHawaiian novelty\nHawaiian pop\nHawaiian pop reggae\nHawaiian pop, Latin pop\nHawaiian pop-rock\nHawaiian ragtime\nHawaiian reggae\nHawaiian reggae-pop\nHawaiian rock\nHawaiian rock and roll\nHawaiian slack key\nHawaiian soul\nHawaiian spiritual\nHawaiian style\nHawaiian style gypsy jazz\nHawaiian style, Western Swing\nHawaiian style, vintage holiday\nHawaiian surf rock\nHawaiian swing\nHawaiian swing jazz\nHawaiian traditional\nHawaiian ukulele\nHawaiian-style, surf-rock, J-pop\nHebrew drill\nHebrew electronic pop\nHebrew folk\nHebrew hip-hop\nHebrew hip-hop chiptune\nHebrew hip-hop reggaeton\nHebrew hip-hop trap\nHebrew novelty\nHebrew pop-rap\nHebrew trap\nHi-NRG\nHi-NRG Eurobeat\nHi-NRG Eurodance\nHi-NRG Italo disco\nHi-NRG Italo-disco\nHi-NRG dance pop\nHi-NRG dance-pop\nHi-NRG disco funk\nHi-NRG house\nHi-NRG synth-pop\nHi-NRG, Eurobeat, synthwave\nHi-NRG, Eurodance, electronic\nHi-NRG, Italo disco\nHi-NRG, Italo-disco\nHi-NRG, Italo-disco, Latin pop\nHi-NRG, new-wave, Latin freestyle\nHi-NRG, synth-pop\nHighlife\nHighlife gospel\nHighlife, Cumbia\nHighlife, cinematic\nHindi R&B\nHindi alt-rock\nHindi alternative rock\nHindi ballad\nHindi ballad, soulful R&B, cinematic pop\nHindi devotional trap\nHindi drill phonk\nHindi ghazal\nHindi hard rock\nHindi hip-hop\nHindi hip-hop lo-fi\nHindi hip-hop trap\nHindi hip-hop, synth-pop\nHindi hip-hop, trap, cinematic\nHindi pop\nHindi pop EDM\nHindi pop R&B\nHindi pop R&B electronic\nHindi pop R&B funk\nHindi pop R&B trap\nHindi pop chiptune\nHindi pop deep house\nHindi pop funk R&B\nHindi pop funk disco\nHindi pop future bass\nHindi pop lo-fi R&B\nHindi pop rock\nHindi pop trap\nHindi pop, EDM\nHindi pop, EDM, ballad\nHindi pop, EDM, dance-pop\nHindi pop, EDM, future bass\nHindi pop, EDM, rock\nHindi pop, EDM-pop, cinematic\nHindi pop, EDM-pop, future bass\nHindi pop, big room house\nHindi pop, electronic R&B\nHindi pop, electronic dance\nHindi pop, electronic, dance-pop\nHindi pop, electronic, trap\nHindi pop, future bass\nHindi pop, hip-hop\nHindi pop, lo-fi hip hop, folk\nHindi pop, reggaeton\nHindi pop, trap\nHindi pop, trap, rap\nHindi pop-EDM\nHindi pop-R&B\nHindi pop-rap\nHindi pop-rock\nHindi pop-rock, electronic\nHindi pop-trap\nHindi rap\nHindi rap, anime trap\nHindi rap, chiptune, lo-fi hip hop\nHindi rock\nHindi trap\nHindu ambient trap\nHindu bhajan\nHindu devotional\nHindu devotional rock\nHindu devotional trap\nHindu devotional, electronic dance, modern bhajan\nHindustani classical\nHindustani classical, Bhangra\nHindustani devotional\nHokkien ballad\nHokkien pop\nHokkien pop-rock\nHoli dance\nHoli festival\nHoli music\nHollywood film score\nHollywood musical\nHollywood orchestral\nHollywood score\nHuapango\nHuapango ranchera\nHuapango salsa\nHuayno\nHuayno Cumbia\nHuayno salsa\nHungarian R&B\nHungarian R&B, hip-hop\nHungarian Schlager\nHungarian ballad\nHungarian cabaret\nHungarian charanga\nHungarian club rap\nHungarian comedy rap\nHungarian disco-pop\nHungarian drill\nHungarian folk\nHungarian folk chiptune\nHungarian folk dance-pop\nHungarian folk polka\nHungarian folk rock\nHungarian folk, bluegrass, country\nHungarian folk, polka, children's music\nHungarian folk, polka, chiptune\nHungarian folk, polka, schlager\nHungarian folk-polka\nHungarian folk-pop\nHungarian folk-rock\nHungarian freestyle\nHungarian hip-hop\nHungarian hip-hop chiptune\nHungarian hip-hop, Latin hip-hop\nHungarian hip-hop, chiptune, 8-bit\nHungarian hip-hop, synth-pop\nHungarian hip-hop, trap\nHungarian hip-hop, trap, emo-rap\nHungarian novelty\nHungarian novelty polka\nHungarian party\nHungarian party rap\nHungarian polka\nHungarian polka-pop\nHungarian pop\nHungarian pop, Eurodance, Schlager\nHungarian pop, Italo-disco\nHungarian pop, Latin cumbia\nHungarian pop, cumbia\nHungarian pop, eurodance\nHungarian pop, schlager\nHungarian pop-R&B\nHungarian pop-folk\nHungarian pop-rap\nHungarian pop-rock\nHungarian pop-schlager\nHungarian rock\nHungarian schlager\nHungarian schlager lounge jazz\nHungarian trap\nHungarian trap-pop\nI-Pop\nIDM\nIDM\nIDM ambient\nIDM ambient chiptune\nIDM ambient electronica\nIDM ambient future garage\nIDM ambient hip-hop\nIDM ambient post-rock\nIDM ambient techno\nIDM ambient video game\nIDM ambient world music\nIDM art pop world music\nIDM art-pop\nIDM artcore\nIDM breakbeat art pop\nIDM breakcore\nIDM breakcore artcore\nIDM chillwave\nIDM chiptune\nIDM chiptune artcore\nIDM chiptune breakbeat\nIDM deep house\nIDM experimental\nIDM experimental techno\nIDM funk\nIDM future garage\nIDM glitch\nIDM glitch ambient\nIDM glitch-hop\nIDM glitch-hop ambient\nIDM glitch-hop artcore\nIDM glitch-hop experimental\nIDM glitch-hop future bass\nIDM glitch-hop jazz fusion\nIDM glitch-hop world music\nIDM glitch-pop\nIDM glitch-pop hyperpop\nIDM glitchcore\nIDM lounge\nIDM progressive house\nIDM progressive house trance\nIDM synth-funk vaporwave\nIDM synth-pop ambient\nIDM synthwave\nIDM tech house\nIDM tech-trance\nIDM techno\nIDM techstep\nIDM trip-hop\nIDM trip-hop ambient\nIDM, acid house, ambient\nIDM, acid house, experimental electronic\nIDM, ambient, Tamil electronic\nIDM, ambient, drum and bass\nIDM, ambient, electronic\nIDM, ambient, glitch\nIDM, art pop, chiptune\nIDM, art pop, electronica\nIDM, art pop, video game music\nIDM, art pop, video game soundtrack\nIDM, artcore, electronic\nIDM, atmospheric drum and bass\nIDM, atmospheric drum and bass, art pop\nIDM, atmospheric drum and bass, lo-fi\nIDM, atmospheric drum and bass, world music\nIDM, big beat, cinematic synth\nIDM, breakbeat, acid bass\nIDM, breakbeat, ambient\nIDM, breakbeat, ambient electronica\nIDM, breakbeat, art pop\nIDM, breakbeat, atmospheric electronic\nIDM, breakbeat, atmospheric electronica\nIDM, breakbeat, chiptune\nIDM, breakbeat, electronic\nIDM, breakbeat, video game music\nIDM, breakbeat, world music\nIDM, breakcore\nIDM, breakcore, ambient\nIDM, breakcore, chiptune\nIDM, breakcore, drum and bass\nIDM, breakcore, experimental electronic\nIDM, chillout\nIDM, chillwave, experimental electronica\nIDM, chiptune, ambient\nIDM, chiptune, art-pop\nIDM, chiptune, electronic\nIDM, cinematic, electronic\nIDM, cinematic, glitch\nIDM, drum and bass, ambient\nIDM, electro, glitch\nIDM, electronic, ambient\nIDM, electronic, synthwave\nIDM, experimental drum and bass, glitch\nIDM, experimental electronic\nIDM, experimental electronic, ambient\nIDM, experimental electronic, breakcore\nIDM, experimental electronic, glitch\nIDM, experimental electronic, world music\nIDM, experimental electronica\nIDM, experimental electronica, UK garage\nIDM, experimental electronica, glitch\nIDM, experimental funk, ambient\nIDM, experimental funk, glitch\nIDM, experimental hip-hop, Brazilian electronic\nIDM, experimental hip-hop, abstract electronic\nIDM, experimental hip-hop, abstract electronica\nIDM, experimental techno\nIDM, experimental trip-hop, ambient\nIDM, footwork, ambient\nIDM, funk, breakbeat\nIDM, future garage, ambient\nIDM, future garage, art pop\nIDM, future garage, neurofunk\nIDM, glitch pop\nIDM, glitch, ambient\nIDM, glitch, atmospheric electronica\nIDM, glitch, breakcore\nIDM, glitch, chiptune\nIDM, glitch, experimental electronic\nIDM, glitch, lo-fi\nIDM, hard techno, psytrance\nIDM, industrial rock, experimental\nIDM, industrial, vaporwave\nIDM, jazz fusion, experimental hip-hop\nIDM, liquid drum and bass\nIDM, lo-fi hip hop, ambient electronic\nIDM, minimal electronic\nIDM, minimal techno\nIDM, minimal techno, experimental electronic\nIDM, modern classical, glitch\nIDM, post-rock, ambient\nIDM, progressive house, melodic techno\nIDM, progressive house, synthwave\nIDM, progressive house, trance\nIDM, progressive rock, world music\nIDM, progressive trance, ambient\nIDM, synth-pop, dream pop\nIDM, tech house, cinematic electronic\nIDM, tech house, experimental electronic\nIDM, tech house, minimal techno\nIDM, tech-house\nIDM, tech-house, ambient\nIDM, tech-trance\nIDM, techstep, electronic\nIDM, trance, electronic\nIDM, trap, hardstyle\nIDM, trap, world music\nIDM, trip-hop, world music\nIban pop, Sundanese pop, electronic dance\nIberian folk\nIcelandic dance-pop\nIcelandic folk\nIcelandic folk, Gipsy Jazz, Western swing\nIcelandic folk, country, western\nIcelandic folk-country\nIcelandic folk-pop\nIcelandic hip-hop\nIcelandic pop\nIcelandic pop, reggaeton, dancehall\nIcelandic pop-rap\nIcelandic pop-rock\nIcelandic punk rock\nIcelandic schlager\nIcelandic trap\nIndi-pop\nIndi-pop R&B\nIndi-pop R&B funk\nIndi-pop lo-fi hip hop\nIndi-pop lo-fi hip-hop\nIndian Bhajan\nIndian Bhajan, electronic, dance\nIndian Christian\nIndian Christian Bhajan\nIndian Christian bhajan\nIndian Christian devotional\nIndian Christian devotional, Tollywood film music, dance pop\nIndian Christian festive\nIndian Christian filmi\nIndian Christian folk\nIndian Christian folk-pop\nIndian Christian fusion\nIndian Christian hymn\nIndian Christian music\nIndian Christian music funk jazz-rock\nIndian Christian music jazz-rock funk\nIndian Christian pop\nIndian Christian pop-folk\nIndian Christian pop-rock\nIndian Christian synth-pop\nIndian Christian worship\nIndian Christian, Bollywood pop, smooth jazz\nIndian Christian, Bollywood, devotional\nIndian Christian, Kannada folk, devotional\nIndian Christian, Kollywood, devotional\nIndian Christian, Latin Cumbia\nIndian Christian, Latin cumbia\nIndian Christian, Latin pop\nIndian Christian, Latin, festive\nIndian Christian, South Indian folk, devotional\nIndian Christian, Tollywood, devotional\nIndian Christian, chiptune\nIndian Christian, chiptune, devotional\nIndian Christian, chiptune, synth-pop\nIndian Christian, cinematic pop\nIndian Christian, retro electronic\nIndian Christian, retro synth-pop\nIndian Christian, synth-pop, Bollywood\nIndian Christian, world music\nIndian Christian, world music, devotional\nIndian Christmas\nIndian Christmas pop\nIndian DJ\nIndian DJ remix\nIndian EDM\nIndian EDM trap\nIndian Kuthu\nIndian Pop\nIndian Pop EDM\nIndian Pop R&B\nIndian Pop R&B Trap\nIndian Pop R&B lo-fi hip-hop\nIndian Pop R&B lounge\nIndian Pop R&B trap\nIndian Pop Trap\nIndian Pop, EDM, cinematic\nIndian Pop, R&B, hip-hop\nIndian Pop, R&B, trap\nIndian R&B\nIndian R&B fusion\nIndian R&B lo-fi hip-hop\nIndian R&B trap\nIndian R&B, trap-soul, vaporwave\nIndian acoustic\nIndian acoustic ballad\nIndian acoustic pop\nIndian ambient\nIndian ambient ballad\nIndian ambient fusion\nIndian ambient trap\nIndian anthem\nIndian ballad\nIndian ballad, EDM, trap\nIndian ballad, electronic, cinematic\nIndian bhajan\nIndian bhajan ambient\nIndian bhajan bhangra\nIndian bhajan chiptune\nIndian bhajan cinematic\nIndian bhajan electronic\nIndian bhajan electronic fusion\nIndian bhajan filmi\nIndian bhajan folk-fusion\nIndian bhajan funk\nIndian bhajan fusion\nIndian bhajan hip-hop\nIndian bhajan lo-fi\nIndian bhajan pop\nIndian bhajan pop fusion\nIndian bhajan pop-funk\nIndian bhajan pop-fusion\nIndian bhajan pop-rock\nIndian bhajan, chiptune, electronic\nIndian bhajan, chiptune, synth-pop\nIndian bhajan, dance-pop\nIndian bhajan, devotional pop\nIndian bhajan, electronic\nIndian bhajan, electronic dance music\nIndian bhajan, electronic dance, late 90s synth\nIndian bhajan, electronic dance, moombahton\nIndian bhajan, electronic fusion\nIndian bhajan, electronic, ambient\nIndian bhajan, electronic, chiptune\nIndian bhajan, electronic, devotional\nIndian bhajan, electronic, hip-hop\nIndian bhajan, electronic, modern\nIndian bhajan, electronic, upbeat\nIndian bhajan, folk dance\nIndian bhajan, folk-pop\nIndian bhajan, hip-hop, electronic\nIndian bhajan, retro Bollywood, pop\nIndian bhajan, retro electronic\nIndian bhajan, trap, EDM\nIndian bhajan, trap, hip-hop\nIndian children's\nIndian children's folk\nIndian children's music\nIndian children's music chiptune\nIndian chiptune\nIndian chiptune fusion\nIndian choral\nIndian cinematic\nIndian cinematic rock\nIndian classical\nIndian classical R&B\nIndian classical a cappella\nIndian classical ambient\nIndian classical ballad\nIndian classical bhajan\nIndian classical crossover\nIndian classical devotional\nIndian classical electronica\nIndian classical folk\nIndian classical fusion\nIndian classical fusion trap\nIndian classical ghazal\nIndian classical hip-hop\nIndian classical hip-hop fusion\nIndian classical percussion\nIndian classical pop\nIndian classical pop-rock\nIndian classical rock\nIndian classical trap\nIndian classical trap R&B\nIndian classical, Bengali folk-rock, progressive metal\nIndian classical, Bhangra\nIndian classical, Bollywood, folk\nIndian classical, Brazilian devotional\nIndian classical, Christian worship\nIndian classical, Eurodance\nIndian classical, European folk\nIndian classical, French folk-rock\nIndian classical, Punjabi folk\nIndian classical, Punjabi folk-pop\nIndian classical, Vietnamese pop-rock\nIndian classical, acoustic folk\nIndian classical, acoustic pop-rock\nIndian classical, ambient ballad, soulful pop\nIndian classical, ambient devotional\nIndian classical, ambient electronic\nIndian classical, ambient electronica\nIndian classical, ambient, electronic\nIndian classical, ambient, experimental\nIndian classical, ambient, spiritual\nIndian classical, ambient, world fusion\nIndian classical, art song\nIndian classical, bhajan\nIndian classical, bhajan, ambient\nIndian classical, bhajan, cinematic\nIndian classical, bhajan, dholak\nIndian classical, bhajan, electronic\nIndian classical, bhajan, folk\nIndian classical, bhajan, folk dance\nIndian classical, breakbeat\nIndian classical, chamber music\nIndian classical, cinematic\nIndian classical, cinematic folk-pop\nIndian classical, cinematic pop\nIndian classical, cinematic, Bollywood\nIndian classical, cinematic, ambient\nIndian classical, cinematic, devotional\nIndian classical, cinematic, folk\nIndian classical, cinematic, melancholic\nIndian classical, cinematic, patriotic\nIndian classical, cinematic, pop\nIndian classical, cinematic, romantic\nIndian classical, cinematic, soulful\nIndian classical, devotional\nIndian classical, devotional bhajan\nIndian classical, devotional, ambient\nIndian classical, devotional, ambient fusion\nIndian classical, devotional, bhajan\nIndian classical, devotional, cinematic\nIndian classical, devotional, contemporary\nIndian classical, devotional, contemporary bhajan\nIndian classical, devotional, dholak\nIndian classical, devotional, dholak groove\nIndian classical, devotional, electronic\nIndian classical, devotional, electronic bhajan\nIndian classical, devotional, electronic fusion\nIndian classical, devotional, folk\nIndian classical, devotional, fusion\nIndian classical, devotional, patriotic\nIndian classical, devotional, spiritual\nIndian classical, devotional, world fusion\nIndian classical, devotional, world music\nIndian classical, electronic R&B\nIndian classical, electronic fusion\nIndian classical, electronic, ambient\nIndian classical, electronic, devotional\nIndian classical, electronic, filmi-pop\nIndian classical, electronic, spiritual\nIndian classical, electronic, trap\nIndian classical, epic narrative\nIndian classical, folk\nIndian classical, folk anthem\nIndian classical, folk ballad, melancholic\nIndian classical, folk dance\nIndian classical, folk fusion\nIndian classical, folk rock, cinematic\nIndian classical, folk, ambient\nIndian classical, folk, bhajan\nIndian classical, folk, cinematic\nIndian classical, folk, devotional\nIndian classical, folk, spiritual\nIndian classical, folk, world music\nIndian classical, folk-pop\nIndian classical, folk-rock\nIndian classical, fusion, rap\nIndian classical, ghazal, cinematic\nIndian classical, gypsy jazz, world music\nIndian classical, hip-hop, R&B\nIndian classical, hip-hop, choral\nIndian classical, hip-hop, cinematic\nIndian classical, industrial electronic\nIndian classical, modern bhajan, electronic\nIndian classical, new age\nIndian classical, new-age\nIndian classical, orchestral\nIndian classical, pop, dance-pop\nIndian classical, pop-rock\nIndian classical, pop-rock, hip-hop\nIndian classical, pop/R&B\nIndian classical, psychedelic rock\nIndian classical, retro electronic\nIndian classical, soft jazz, melancholic pop\nIndian classical, soul, ambient fusion\nIndian classical, spiritual, folk\nIndian classical, spoken word\nIndian classical, trap\nIndian classical, trap fusion\nIndian classical, trap, R&B\nIndian classical, trap, ambient\nIndian classical, trap, hardstyle\nIndian classical, video game soundtrack\nIndian classical, world fusion\nIndian classical, world music, ambient\nIndian classical, world music, devotional\nIndian classical, world music, electronic\nIndian classical, world music, romantic\nIndian club\nIndian club music\nIndian dance\nIndian dance bhajan\nIndian dance pop\nIndian dance remix\nIndian dance, electronic, folk fusion\nIndian dance, funkot, electronic\nIndian dance, hyperpop\nIndian dance, kuthu, electronic\nIndian dance-pop\nIndian dance-pop chiptune\nIndian dance-pop, EDM\nIndian devotional\nIndian devotional Bhajan\nIndian devotional EDM\nIndian devotional ambient\nIndian devotional bhajan\nIndian devotional chiptune\nIndian devotional cumbia\nIndian devotional dance\nIndian devotional dance-pop\nIndian devotional electronic\nIndian devotional film music\nIndian devotional filmi\nIndian devotional folk\nIndian devotional folk-pop\nIndian devotional funk\nIndian devotional funk-rock\nIndian devotional fusion\nIndian devotional hip-hop\nIndian devotional pop\nIndian devotional pop-rock\nIndian devotional rock\nIndian devotional salsa\nIndian devotional synth-pop\nIndian devotional trap\nIndian devotional, EDM\nIndian devotional, EDM, Bollywood\nIndian devotional, Eurodance, trance\nIndian devotional, Kollywood, electronic\nIndian devotional, Latin, world music\nIndian devotional, Spanish acoustic, rock fusion\nIndian devotional, Tollywood film music\nIndian devotional, Western folk\nIndian devotional, acoustic folk\nIndian devotional, chiptune, electronic dance\nIndian devotional, chiptune, retro\nIndian devotional, cinematic, Middle Eastern\nIndian devotional, cinematic, electronic fusion\nIndian devotional, dance-pop\nIndian devotional, dance-pop, electronic\nIndian devotional, electronic dance\nIndian devotional, electronic dance music\nIndian devotional, electronic dance music, synth-pop\nIndian devotional, electronic dance, bhajan\nIndian devotional, electronic dance, chiptune\nIndian devotional, electronic dance, folk fusion\nIndian devotional, electronic dance, modern bhajan\nIndian devotional, electronic dance, synth-pop\nIndian devotional, electronic fusion\nIndian devotional, electronic pop\nIndian devotional, electronic, bhajan\nIndian devotional, electronic, cinematic\nIndian devotional, electronic, dance\nIndian devotional, electronic, dance-pop\nIndian devotional, electronic, dholak\nIndian devotional, electronic, folk\nIndian devotional, electronic, fusion\nIndian devotional, electronic, high-energy\nIndian devotional, electronic, high-tempo\nIndian devotional, electronic, hip-hop\nIndian devotional, electronic, modern bhajan\nIndian devotional, electronic, pop\nIndian devotional, electronic, trap\nIndian devotional, electronic, upbeat\nIndian devotional, flamenco fusion\nIndian devotional, folk\nIndian devotional, folk dance\nIndian devotional, folk-electronic, bhajan\nIndian devotional, folk-rock\nIndian devotional, retro Bollywood\nIndian devotional, retro Cumbia, psychedelic bhajan\nIndian devotional, retro electronic\nIndian devotional, retro electronic, chiptune\nIndian devotional, retro synth\nIndian devotional, retro synth, dance bhajan\nIndian devotional, retro-electronic, dance\nIndian devotional, soft rock, blues\nIndian devotional, synth pop\nIndian devotional, synthwave, 80s electronic\nIndian devotional, trap, R&B\nIndian devotional, tribal dance\nIndian devotional, vintage film music, upbeat\nIndian devotional, world fusion\nIndian devotional, world fusion, electronic\nIndian devotional, world fusion, light jazz\nIndian devotional, world music\nIndian devotional, world music, ambient\nIndian devotional, world music, cinematic\nIndian devotional, world music, electronic pop\nIndian disco\nIndian electronic\nIndian electronic bhajan\nIndian electronic dance\nIndian electronic dance-pop\nIndian electronic devotional\nIndian electronic folk\nIndian electronic funk\nIndian electronic fusion\nIndian electronic hip-hop\nIndian electronic pop\nIndian electronic, hip-hop\nIndian electronica\nIndian film\nIndian film anthem\nIndian film ballad\nIndian film dance\nIndian film lullaby\nIndian film music\nIndian film music Latin fusion\nIndian film music chiptune\nIndian film music cumbia\nIndian film music disco-funk\nIndian film music folk-pop\nIndian film music funk\nIndian film music funk electronic\nIndian film music funk hip-hop\nIndian film music funk jazz\nIndian film music funk rock\nIndian film music funk-pop\nIndian film music jazz fusion\nIndian film music lo-fi\nIndian film music lounge\nIndian film music retro\nIndian film music retro synth\nIndian film music retro synth-pop\nIndian film music samba salsa\nIndian film music swing\nIndian film music, Christian devotional, dholak\nIndian film music, European folk, cinematic\nIndian film music, European, cinematic\nIndian film music, Latin, funk\nIndian film music, R&B\nIndian film music, R&B, hip-hop\nIndian film music, R&B, pop\nIndian film music, Western pop, fusion\nIndian film music, ambient electronic, cinematic\nIndian film music, chiptune, funk\nIndian film music, chiptune, retro\nIndian film music, cinematic rock, world fusion\nIndian film music, dance-pop, new-age\nIndian film music, devotional, electronic\nIndian film music, devotional, spiritual\nIndian film music, electronic dance\nIndian film music, electronic dance, fusion\nIndian film music, electronic pop\nIndian film music, electronic, dance-pop\nIndian film music, electronic, devotional\nIndian film music, electronic, ethereal\nIndian film music, electronic, fusion\nIndian film music, electronic, hip-hop\nIndian film music, electronic, jazz\nIndian film music, electronic, world music\nIndian film music, festive, Western Christmas\nIndian film music, funk, jazz fusion\nIndian film music, funk, pop\nIndian film music, funk, pop-funk\nIndian film music, hard rock\nIndian film music, hip-hop, electronic\nIndian film music, hyper-digital electronica\nIndian film music, lounge, Latin\nIndian film music, pop, ambient\nIndian film music, pop, electronic\nIndian film music, pop, fusion\nIndian film music, pop, jazz fusion\nIndian film music, pop-dance, electronic\nIndian film music, retro electronic, lo-fi pop\nIndian film music, retro, chiptune\nIndian film music, synth-pop, dance\nIndian film music, synth-pop, disco\nIndian film music, synthwave, lo-fi\nIndian film music, trap, ambient\nIndian film music, world fusion, cinematic\nIndian film music, world fusion, ghazal\nIndian film rock\nIndian film score\nIndian film score funk disco\nIndian film score lo-fi\nIndian film score, big band jazz, cinematic\nIndian film score, big band swing\nIndian film score, electronic dance, cinematic\nIndian film score, electronic dance, fusion\nIndian film score, electronic pop\nIndian film score, electronic worldbeat, devotional fusion\nIndian film score, hip-hop, trap\nIndian film score, surf rock, exotica\nIndian film score, synth-pop, disco\nIndian film song\nIndian film song retro\nIndian film song, retro, chiptune\nIndian film, retro synth, 80s style\nIndian film-pop\nIndian film-pop chiptune\nIndian film-pop lo-fi\nIndian film-pop, Eurodance\nIndian filmi\nIndian filmi ballad\nIndian filmi dance-pop\nIndian filmi fusion\nIndian filmi pop\nIndian filmi, chiptune, retro synth\nIndian filmi, cinematic, electronic\nIndian filmi, ghazal\nIndian filmi-pop\nIndian folk\nIndian folk Bhajan\nIndian folk EDM\nIndian folk Kuthu\nIndian folk Sufi\nIndian folk a cappella\nIndian folk acoustic\nIndian folk acoustic pop\nIndian folk anthem\nIndian folk ballad\nIndian folk bhajan\nIndian folk blues\nIndian folk blues-rock\nIndian folk chiptune\nIndian folk cinematic\nIndian folk classical fusion\nIndian folk comedy\nIndian folk dance\nIndian folk devotional\nIndian folk electronic\nIndian folk electronic funk\nIndian folk electronic hip-hop\nIndian folk electronic pop\nIndian folk electronic rock\nIndian folk electronica\nIndian folk filmi\nIndian folk funk\nIndian folk funk rock\nIndian folk funk-rock\nIndian folk fusion\nIndian folk gospel\nIndian folk gypsy jazz\nIndian folk hip-hop\nIndian folk hip-hop rock\nIndian folk house\nIndian folk jazz\nIndian folk jazz-rock\nIndian folk lo-fi\nIndian folk orchestral\nIndian folk pop\nIndian folk pop-rock\nIndian folk pop-trap\nIndian folk protest\nIndian folk reggae\nIndian folk rock\nIndian folk rockabilly\nIndian folk satire\nIndian folk tango\nIndian folk trap\nIndian folk world\nIndian folk world music\nIndian folk, Bhangra\nIndian folk, Bhangra, ambient\nIndian folk, Bhangra, cinematic\nIndian folk, Bhangra, ghazal\nIndian folk, Bhangra, world fusion\nIndian folk, Bhojpuri, Pahari\nIndian folk, Bollywood\nIndian folk, Bollywood ballad, cinematic pop\nIndian folk, Bollywood, cinematic\nIndian folk, Bollywood, devotional\nIndian folk, Bollywood, electronic\nIndian folk, Bollywood, electronic dance\nIndian folk, Bollywood, world music\nIndian folk, Carnatic, devotional\nIndian folk, Christian devotional\nIndian folk, Christian devotional, celebratory\nIndian folk, Christian devotional, upbeat\nIndian folk, Christian worship\nIndian folk, European cabaret\nIndian folk, French pop, electronic\nIndian folk, Latin, devotional\nIndian folk, Latin, festive\nIndian folk, Latin, flamenco\nIndian folk, Punjabi pop\nIndian folk, R&B/Pop\nIndian folk, Rajasthani, pop fusion\nIndian folk, Sufi devotional\nIndian folk, Sufi music\nIndian folk, Sufi, ambient\nIndian folk, Sufi, blues-rock\nIndian folk, Sufi, dholak\nIndian folk, Sufi, live recording\nIndian folk, Sufi, lo-fi\nIndian folk, Sufi, world music\nIndian folk, Vocaloid, quirky pop\nIndian folk, acoustic ballad, ambient\nIndian folk, acoustic folk\nIndian folk, acoustic, choral\nIndian folk, acoustic, cinematic\nIndian folk, acoustic, duet\nIndian folk, acoustic, ghazal\nIndian folk, alternative rock, cinematic\nIndian folk, ambient electronic\nIndian folk, ambient electronica\nIndian folk, ambient fusion\nIndian folk, ambient, cinematic\nIndian folk, ambient, electronic\nIndian folk, ambient, electronic fusion\nIndian folk, ambient, ghazal\nIndian folk, ambient, lo-fi\nIndian folk, ambient, world fusion\nIndian folk, bhajan\nIndian folk, bhajan, devotional\nIndian folk, bhajan, electronic\nIndian folk, big band swing\nIndian folk, children's music, nursery rhyme\nIndian folk, children's music, upbeat\nIndian folk, chiptune\nIndian folk, chiptune, ambient\nIndian folk, chiptune, cinematic\nIndian folk, chiptune, electronic\nIndian folk, chiptune, electronic dance\nIndian folk, chiptune, electronic fusion\nIndian folk, chiptune, trap\nIndian folk, cinematic fusion, devotional\nIndian folk, cinematic orchestral\nIndian folk, cinematic pop\nIndian folk, cinematic pop, ambient acoustic\nIndian folk, cinematic world\nIndian folk, cinematic, European fusion\nIndian folk, cinematic, ambient\nIndian folk, cinematic, choral\nIndian folk, cinematic, devotional\nIndian folk, cinematic, electronic\nIndian folk, cinematic, epic\nIndian folk, cinematic, film music\nIndian folk, cinematic, fusion\nIndian folk, cinematic, melancholic\nIndian folk, cinematic, orchestral\nIndian folk, cinematic, rock\nIndian folk, cinematic, spiritual\nIndian folk, cinematic, traditional\nIndian folk, cinematic, whimsical\nIndian folk, cinematic, world fusion\nIndian folk, cinematic, world music\nIndian folk, classical, devotional\nIndian folk, classical, patriotic\nIndian folk, comedic\nIndian folk, contemporary Christian\nIndian folk, dance, shehnai\nIndian folk, devotional\nIndian folk, devotional, South Indian\nIndian folk, devotional, electronic\nIndian folk, devotional, electronic fusion\nIndian folk, devotional, folk-rock\nIndian folk, devotional, fusion\nIndian folk, devotional, gospel\nIndian folk, devotional, hip-hop\nIndian folk, devotional, pop\nIndian folk, devotional, upbeat\nIndian folk, electronic\nIndian folk, electronic dance\nIndian folk, electronic dance, Bollywood\nIndian folk, electronic dance, Bollywood disco\nIndian folk, electronic dance, EDM\nIndian folk, electronic dance, bhajan\nIndian folk, electronic dance, chiptune\nIndian folk, electronic dance, cinematic\nIndian folk, electronic dance, fusion\nIndian folk, electronic dance, high-energy\nIndian folk, electronic dance, hyperpop\nIndian folk, electronic dance, moombahton\nIndian folk, electronic dance, pop\nIndian folk, electronic dance, reggaeton\nIndian folk, electronic dance, trance\nIndian folk, electronic dance, trap\nIndian folk, electronic fusion\nIndian folk, electronic fusion, devotional\nIndian folk, electronic pop\nIndian folk, electronic pop, ambient\nIndian folk, electronic, Bollywood\nIndian folk, electronic, ambient\nIndian folk, electronic, bhajan\nIndian folk, electronic, chiptune\nIndian folk, electronic, cinematic\nIndian folk, electronic, dance\nIndian folk, electronic, devotional\nIndian folk, electronic, dream pop\nIndian folk, electronic, fusion\nIndian folk, electronic, hip-hop\nIndian folk, electronic, pop\nIndian folk, electronic, romantic\nIndian folk, electronic, spiritual\nIndian folk, electronic, trap\nIndian folk, electronic, upbeat\nIndian folk, electronic, vaporwave\nIndian folk, electronic, world fusion\nIndian folk, electronic, worldbeat\nIndian folk, filmi music, Bollywood ballad\nIndian folk, filmi soundtrack, world music\nIndian folk, filmi, devotional\nIndian folk, filmi, romantic\nIndian folk, funk, electronic\nIndian folk, ghazal\nIndian folk, ghazal, Christian contemporary\nIndian folk, ghazal, acoustic\nIndian folk, ghazal, acoustic pop\nIndian folk, ghazal, acoustic singer-songwriter\nIndian folk, ghazal, ambient\nIndian folk, ghazal, ballad\nIndian folk, ghazal, bhajan\nIndian folk, ghazal, cinematic\nIndian folk, ghazal, contemporary\nIndian folk, ghazal, contemporary fusion\nIndian folk, ghazal, dream pop\nIndian folk, ghazal, electronic\nIndian folk, ghazal, electronic fusion\nIndian folk, ghazal, smooth jazz\nIndian folk, ghazal, soft pop\nIndian folk, ghazal, world music\nIndian folk, hard electronic\nIndian folk, hard electronic, Bhangra\nIndian folk, hard electronic, dance\nIndian folk, hard electronic, trap\nIndian folk, hard rock\nIndian folk, hard trance\nIndian folk, hip-hop, emotional\nIndian folk, lo-fi electronic, ambient\nIndian folk, melancholic, cinematic\nIndian folk, microtonal, ambient\nIndian folk, modern production, patriotic\nIndian folk, modern, spiritual\nIndian folk, operatic, Hindustani classical\nIndian folk, pop, ambient\nIndian folk, psychedelic funk-rock\nIndian folk, retro electronic\nIndian folk, retro video game\nIndian folk, semi-classical\nIndian folk, singer-songwriter\nIndian folk, soft pop-rock\nIndian folk, synth-pop\nIndian folk, trap, EDM\nIndian folk, trap, electronic dance\nIndian folk, trip-hop\nIndian folk, world fusion\nIndian folk, world music\nIndian folk, world music, acoustic\nIndian folk, world music, acoustic pop\nIndian folk, world music, ambient\nIndian folk, world music, ambient ballad\nIndian folk, world music, ambient fusion\nIndian folk, world music, cinematic\nIndian folk, world music, contemporary ballad\nIndian folk, world music, devotional\nIndian folk, world music, electronic\nIndian folk, world music, lo-fi acoustic\nIndian folk, world music, romantic\nIndian folk, world music, spiritual\nIndian folk, worldbeat\nIndian folk-dance\nIndian folk-disco\nIndian folk-electronic\nIndian folk-funk\nIndian folk-fusion\nIndian folk-pop\nIndian folk-pop chiptune\nIndian folk-pop cumbia\nIndian folk-pop dance-pop\nIndian folk-pop electronic\nIndian folk-pop electronic dance\nIndian folk-pop funk-rock\nIndian folk-pop fusion\nIndian folk-pop hip-hop\nIndian folk-pop rock\nIndian folk-pop soft rock\nIndian folk-pop world music\nIndian folk-pop, chiptune, electronic\nIndian folk-pop, chiptune, electronic dance\nIndian folk-pop, chiptune, synth-pop\nIndian folk-pop, cinematic orchestral\nIndian folk-pop, electronic dance\nIndian folk-pop, electronic dance music\nIndian folk-pop, electronic dance, dancehall\nIndian folk-pop, electronic dance, rock\nIndian folk-pop, folk-fusion\nIndian folk-pop, hard rock\nIndian folk-pop, hardstyle\nIndian folk-pop, hip-hop\nIndian folk-pop, hip-hop/trap\nIndian folk-rock\nIndian folk-rock funk-rock\nIndian funk\nIndian funk disco\nIndian funk fusion\nIndian funk rock\nIndian funk-pop\nIndian funk-rock\nIndian funkot\nIndian fusion\nIndian fusion R&B\nIndian fusion ambient\nIndian fusion ambient pop\nIndian fusion ballad\nIndian fusion funk\nIndian fusion funk rock\nIndian fusion funk-rock\nIndian fusion hip-hop\nIndian fusion lo-fi hip-hop\nIndian fusion pop\nIndian fusion pop-rock\nIndian fusion reggaeton\nIndian fusion rock\nIndian fusion trap\nIndian fusion trap R&B\nIndian fusion trip-hop\nIndian fusion, Punjabi pop, Bhangra\nIndian fusion, electronic dance, classical vocals\nIndian fusion, electronic rock\nIndian fusion, electronic, cinematic\nIndian fusion, future bass, trance\nIndian fusion, trap, ambient\nIndian fusion, trap, cinematic\nIndian fusion, world music, soft rock\nIndian gangster rap, EDM\nIndian garage\nIndian ghazal\nIndian ghazal pop\nIndian ghazal pop-rock\nIndian ghazal rock\nIndian ghazal, electronic fusion\nIndian ghazal, electronic, world music\nIndian ghazal, pop fusion\nIndian ghazal, trap, EDM\nIndian gospel folk-pop\nIndian hand percussion\nIndian hard dance\nIndian hard rock\nIndian hardstyle\nIndian hip-hop\nIndian hip-hop chiptune\nIndian hip-hop fusion\nIndian hip-hop hyperpop\nIndian hip-hop lo-fi\nIndian hip-hop moombahton\nIndian hip-hop trap\nIndian hip-hop trap metal\nIndian hip-hop, EDM\nIndian hip-hop, chiptune, Bollywood pop\nIndian hip-hop, devotional, cinematic\nIndian hip-hop, electronic dance\nIndian hip-hop, electronic fusion\nIndian hip-hop, hard trap\nIndian hip-hop, hard trap, hardstyle\nIndian hip-hop, hardstyle trap\nIndian hip-hop, hardstyle, EDM\nIndian hip-hop, hardstyle, trap\nIndian hip-hop, trap, drill\nIndian hip-hop, trap, electronic\nIndian house\nIndian indie-pop\nIndian instrumental\nIndian jazz fusion\nIndian jazz-pop\nIndian lullaby\nIndian metal\nIndian new age\nIndian nursery rhyme\nIndian party\nIndian party anthem\nIndian patriotic\nIndian patriotic, chiptune\nIndian percussion\nIndian political anthem\nIndian political folk\nIndian political hip-hop\nIndian political pop\nIndian pop\nIndian pop 80s\nIndian pop 80s filmi\nIndian pop Bhangra\nIndian pop Bhojpuri\nIndian pop EDM\nIndian pop Latin\nIndian pop R&B\nIndian pop R&B funk\nIndian pop R&B lo-fi\nIndian pop R&B lo-fi hip-hop\nIndian pop R&B lounge\nIndian pop R&B trap\nIndian pop Tollywood\nIndian pop acoustic ballad\nIndian pop acoustic folk\nIndian pop ballad\nIndian pop ballad, R&B, trap\nIndian pop chillwave\nIndian pop chiptune\nIndian pop chiptune funk\nIndian pop dance-pop\nIndian pop dancehall\nIndian pop disco funk\nIndian pop downtempo\nIndian pop electronic\nIndian pop filmi\nIndian pop folk\nIndian pop folk fusion\nIndian pop funk\nIndian pop funk R&B\nIndian pop funk chiptune\nIndian pop funk disco\nIndian pop funk electronic\nIndian pop funk hip-hop\nIndian pop funk jazz\nIndian pop funk jazz fusion\nIndian pop funk lo-fi\nIndian pop funk lounge\nIndian pop funk neo-soul\nIndian pop funk reggae\nIndian pop funk rock\nIndian pop funk world music\nIndian pop funk-pop\nIndian pop funk-rock\nIndian pop fusion\nIndian pop future bass\nIndian pop future bass trap\nIndian pop gabber\nIndian pop hip hop\nIndian pop hip-hop\nIndian pop hip-hop indie pop\nIndian pop hip-hop rock\nIndian pop indie pop\nIndian pop jazz lounge\nIndian pop lo-fi\nIndian pop lo-fi R&B\nIndian pop lo-fi hip hop\nIndian pop lo-fi hip-hop\nIndian pop lo-fi hip-hop R&B\nIndian pop lo-fi hip-hop rock\nIndian pop lo-fi hip-hop trap\nIndian pop lo-fi trap\nIndian pop lounge\nIndian pop lounge world fusion\nIndian pop nu-disco funk\nIndian pop progressive house\nIndian pop reggaeton\nIndian pop rock\nIndian pop salsa\nIndian pop soft rock\nIndian pop synth-pop rock\nIndian pop trap\nIndian pop trap R&B\nIndian pop trap hardstyle\nIndian pop trip-hop\nIndian pop tropical house\nIndian pop world music\nIndian pop worldbeat\nIndian pop, 80s filmi, cinematic\nIndian pop, 80s funk, disco\nIndian pop, 80s synth-pop\nIndian pop, 80s synth-pop, filmi\nIndian pop, 90s dance-pop\nIndian pop, 90s dance-pop, chiptune\nIndian pop, 90s dance-pop, retro\nIndian pop, 90s funk, dance\nIndian pop, Afrobeats, dancehall\nIndian pop, Bhangra\nIndian pop, Bhangra, Christian devotional\nIndian pop, Bhangra, electronic\nIndian pop, Bhangra, electronic dance\nIndian pop, Bhangra, political pop\nIndian pop, Bhangra, upbeat\nIndian pop, Bhojpuri folk\nIndian pop, Bhojpuri folk, chiptune\nIndian pop, Bhojpuri folk, dance pop\nIndian pop, Bhojpuri folk, electronic\nIndian pop, Bhojpuri folk, electronic dance\nIndian pop, Bhojpuri folk, upbeat\nIndian pop, Bhojpuri, Bollywood\nIndian pop, EDM\nIndian pop, EDM, Bhangra\nIndian pop, EDM, Bhojpuri\nIndian pop, EDM, Bollywood\nIndian pop, EDM, Tollywood\nIndian pop, EDM, acoustic\nIndian pop, EDM, atmospheric\nIndian pop, EDM, cinematic\nIndian pop, EDM, dance-pop\nIndian pop, EDM, devotional\nIndian pop, EDM, filmi\nIndian pop, EDM, folk fusion\nIndian pop, EDM, future bass\nIndian pop, EDM, global dance\nIndian pop, EDM, hip-hop\nIndian pop, EDM, moombahton\nIndian pop, EDM, pop\nIndian pop, EDM, rock\nIndian pop, EDM, trap\nIndian pop, European folk, fusion\nIndian pop, Haryanvi folk, cinematic\nIndian pop, Haryanvi folk, electronic\nIndian pop, Haryanvi folk, trap\nIndian pop, Haryanvi, chiptune\nIndian pop, Haryanvi, electronic\nIndian pop, Latin dance\nIndian pop, Latin electronica, lo-fi hip hop\nIndian pop, Latin funk, fusion\nIndian pop, Latin funk, hip-hop\nIndian pop, Latin fusion, devotional\nIndian pop, Latin groove\nIndian pop, Latin pop\nIndian pop, Latin pop, bossa nova\nIndian pop, Latin, electronic\nIndian pop, Latin, flamenco\nIndian pop, R&B\nIndian pop, R&B, ambient\nIndian pop, R&B, ballad\nIndian pop, R&B, chillwave\nIndian pop, R&B, cinematic\nIndian pop, R&B, electronic\nIndian pop, R&B, funk\nIndian pop, R&B, hip-hop\nIndian pop, R&B, lo-fi\nIndian pop, R&B, lo-fi hip-hop\nIndian pop, R&B, pop\nIndian pop, R&B, trap\nIndian pop, R&B, world music\nIndian pop, Sufi, electronic\nIndian pop, Tollywood, festive\nIndian pop, Tollywood, hip-hop\nIndian pop, acoustic world music\nIndian pop, alternative R&B\nIndian pop, ambient electronica\nIndian pop, ambient pop\nIndian pop, ambient, cinematic\nIndian pop, ambient, dream pop\nIndian pop, ambient, ghazal\nIndian pop, chill electronic\nIndian pop, chill-out\nIndian pop, chillwave\nIndian pop, chillwave, electronic\nIndian pop, chillwave, lo-fi\nIndian pop, chillwave, lo-fi hip-hop\nIndian pop, chiptune\nIndian pop, chiptune, EDM\nIndian pop, chiptune, children's music\nIndian pop, chiptune, devotional\nIndian pop, chiptune, electro-pop\nIndian pop, chiptune, electronic\nIndian pop, chiptune, electronic dance\nIndian pop, chiptune, funk\nIndian pop, chiptune, hip-hop\nIndian pop, chiptune, smooth jazz\nIndian pop, chiptune, trap\nIndian pop, chiptune, video game music\nIndian pop, cinematic ballad\nIndian pop, cinematic ballad, ghazal\nIndian pop, cinematic ballad, trap\nIndian pop, cinematic electronic, trap\nIndian pop, cinematic fusion, devotional\nIndian pop, cinematic rock\nIndian pop, cinematic trap, future bass\nIndian pop, cinematic, ambient\nIndian pop, cinematic, devotional\nIndian pop, cinematic, electronic\nIndian pop, cinematic, epic\nIndian pop, cinematic, ethereal\nIndian pop, cinematic, orchestral\nIndian pop, cinematic, trap\nIndian pop, contemporary Christian\nIndian pop, dance music\nIndian pop, dance pop, electronic\nIndian pop, dance, Christian devotional\nIndian pop, dance, electronic\nIndian pop, dance, rock\nIndian pop, dance-pop\nIndian pop, dance-pop, EDM\nIndian pop, dancehall, afrobeats\nIndian pop, dancehall, electronic\nIndian pop, dancehall, folk fusion\nIndian pop, dancehall, reggae\nIndian pop, dancehall, reggaeton\nIndian pop, electronic\nIndian pop, electronic R&B\nIndian pop, electronic R&B, future bass\nIndian pop, electronic R&B, trap\nIndian pop, electronic ballad\nIndian pop, electronic dance\nIndian pop, electronic dance music\nIndian pop, electronic dance music, Christian devotional\nIndian pop, electronic dance, Bollywood\nIndian pop, electronic dance, ambient\nIndian pop, electronic dance, chiptune\nIndian pop, electronic dance, devotional\nIndian pop, electronic dance, folk fusion\nIndian pop, electronic dance, fusion\nIndian pop, electronic dance, global pop\nIndian pop, electronic dance, hip-hop\nIndian pop, electronic dance, hyperpop\nIndian pop, electronic dance, moombahton\nIndian pop, electronic dance, political pop\nIndian pop, electronic dance, retro-pop\nIndian pop, electronic dance, rock\nIndian pop, electronic dance, synth-pop\nIndian pop, electronic fusion\nIndian pop, electronic hip-hop\nIndian pop, electronic lounge\nIndian pop, electronic pop, fusion\nIndian pop, electronic, R&B\nIndian pop, electronic, ambient\nIndian pop, electronic, chiptune\nIndian pop, electronic, cinematic\nIndian pop, electronic, dance\nIndian pop, electronic, dancehall\nIndian pop, electronic, devotional\nIndian pop, electronic, dream pop\nIndian pop, electronic, duet\nIndian pop, electronic, experimental\nIndian pop, electronic, folk fusion\nIndian pop, electronic, funk\nIndian pop, electronic, fusion\nIndian pop, electronic, hip-hop\nIndian pop, electronic, lo-fi\nIndian pop, electronic, melancholic\nIndian pop, electronic, meme\nIndian pop, electronic, reggaeton\nIndian pop, electronic, rock\nIndian pop, electronic, trap\nIndian pop, electronic, video game\nIndian pop, electronic, world fusion\nIndian pop, electronic, world music\nIndian pop, festive, modern classical\nIndian pop, flamenco, hip-hop\nIndian pop, folk fusion\nIndian pop, folk fusion, upbeat\nIndian pop, folk, Latin\nIndian pop, folk, hip-hop\nIndian pop, funk, synth-pop\nIndian pop, funk, world music\nIndian pop, future bass\nIndian pop, future bass, trap\nIndian pop, ghazal\nIndian pop, ghazal, acoustic\nIndian pop, ghazal, acoustic ballad\nIndian pop, ghazal, ambient\nIndian pop, ghazal, ballad\nIndian pop, ghazal, cinematic\nIndian pop, ghazal, electronic\nIndian pop, ghazal, lo-fi hip hop\nIndian pop, ghazal, world music\nIndian pop, hard rock\nIndian pop, hardstyle\nIndian pop, hardstyle, EDM\nIndian pop, hardstyle, trap\nIndian pop, hip-hop\nIndian pop, hip-hop, Bollywood\nIndian pop, hip-hop, EDM\nIndian pop, hip-hop, R&B\nIndian pop, hip-hop, atmospheric rock\nIndian pop, hip-hop, chiptune\nIndian pop, hip-hop, cinematic\nIndian pop, hip-hop, electronic\nIndian pop, hip-hop, electronic dance\nIndian pop, hip-hop, folk\nIndian pop, hip-hop, reggaeton\nIndian pop, hip-hop, trap\nIndian pop, lo-fi ballad\nIndian pop, lo-fi hip hop\nIndian pop, lo-fi hip hop, R&B\nIndian pop, lo-fi hip hop, ambient\nIndian pop, lo-fi hip hop, ballad\nIndian pop, lo-fi hip hop, chiptune\nIndian pop, lo-fi hip hop, future bass\nIndian pop, lo-fi hip hop, melancholic\nIndian pop, lo-fi hip-hop\nIndian pop, lo-fi hip-hop, R&B\nIndian pop, lo-fi hip-hop, acoustic pop\nIndian pop, lo-fi hip-hop, ballad\nIndian pop, lo-fi hip-hop, trap\nIndian pop, lo-fi pop\nIndian pop, lo-fi pop, R&B\nIndian pop, lo-fi pop, chillwave\nIndian pop, lo-fi pop, smooth jazz\nIndian pop, lo-fi, chillwave\nIndian pop, melancholic ballad\nIndian pop, melancholic ballad, atmospheric\nIndian pop, moombahton\nIndian pop, moombahton, electronic dance\nIndian pop, moombahton, trap\nIndian pop, nu-disco\nIndian pop, nu-metal\nIndian pop, pop ballad\nIndian pop, pop-rock\nIndian pop, pop-trap\nIndian pop, reggaeton, Tollywood\nIndian pop, reggaeton, dancehall\nIndian pop, retro electronic\nIndian pop, retro electronic, chiptune\nIndian pop, retro electronic, dance\nIndian pop, retro hip-hop, funk\nIndian pop, retro, chiptune\nIndian pop, retro-electronic\nIndian pop, retro-futuristic\nIndian pop, retro-futuristic, dance-pop\nIndian pop, rock, electronic\nIndian pop, sad hip-hop\nIndian pop, ska, big band\nIndian pop, smooth jazz, lounge\nIndian pop, soft R&B\nIndian pop, soft rock\nIndian pop, soft rock, ambient\nIndian pop, soft rock, jazz\nIndian pop, soft rock, world music\nIndian pop, synth-pop\nIndian pop, synth-pop, 80s\nIndian pop, synth-pop, EDM\nIndian pop, synth-pop, chiptune\nIndian pop, synth-pop, cinematic\nIndian pop, synth-pop, dance-pop\nIndian pop, synth-pop, disco\nIndian pop, trap\nIndian pop, trap, EDM\nIndian pop, trap, R&B\nIndian pop, trap, ambient\nIndian pop, trap, atmospheric R&B\nIndian pop, trap, chiptune\nIndian pop, trap, cinematic\nIndian pop, trap, electronic\nIndian pop, trap, ethereal\nIndian pop, trap, folk fusion\nIndian pop, trap, future bass\nIndian pop, trap, hardstyle\nIndian pop, trap, hip-hop\nIndian pop, trap, melodic\nIndian pop, trap, world music\nIndian pop, trip-hop, ambient\nIndian pop, trip-hop, world fusion\nIndian pop, world fusion, cinematic\nIndian pop, world fusion, ghazal\nIndian pop, world fusion, rock\nIndian pop, world music\nIndian pop, world music, ambient\nIndian pop, world music, ambient electronica\nIndian pop, world music, chiptune\nIndian pop, world music, devotional\nIndian pop, world music, electronic\nIndian pop, world music, jazz fusion\nIndian pop, world music, lo-fi\nIndian pop, world music, soft rock\nIndian pop, world music, soul\nIndian pop, worldbeat, electronic lounge\nIndian pop, worldbeat, fusion\nIndian pop-EDM\nIndian pop-R&B\nIndian pop-dance\nIndian pop-folk\nIndian pop-funk\nIndian pop-fusion\nIndian pop-rap\nIndian pop-rap, folk, trap, Hindi pop, Punjabi bhangra\nIndian pop-rock\nIndian pop-rock, chiptune, electronic dance\nIndian pop-rock, electronic dance\nIndian pop-trap\nIndian protest\nIndian protest anthem\nIndian rave\nIndian revolutionary\nIndian revolutionary anthem\nIndian revolutionary folk\nIndian revolutionary march\nIndian rhythm\nIndian rock\nIndian rock funk\nIndian rock fusion\nIndian rock, Latin rock\nIndian rock, trap metal, electronic fusion\nIndian romantic ballad\nIndian semi-classical\nIndian semi-classical ballad\nIndian spiritual\nIndian spiritual hip-hop\nIndian sports anthem\nIndian street music\nIndian traditional\nIndian trap\nIndian trap R&B\nIndian trap chiptune\nIndian trap phonk\nIndian trap, EDM\nIndian trap, moombahton\nIndian tribute\nIndian vocal percussion\nIndian wedding\nIndian wedding music\nIndian world music\nIndie Filmi\nIndie Folk\nIndie Folk Fusion\nIndie Folk Hip-Hop\nIndie Folk Pop\nIndie Folk R&B\nIndie Folk, Ambient Pop\nIndie Folk, Ethno-Lo-Fi\nIndie Folk, Funk Rock\nIndie Folk, Lo-fi, Indian Pop\nIndie Folk, R&B\nIndie Folk, Spiritual Pop\nIndie Folk, World Fusion\nIndie Pop\nIndie Pop R&B\nIndie Pop, Indian Film Music\nIndie Pop, World Fusion\nIndie R&B\nIndie Rock\nIndie ballad\nIndie folk\nIndie folk fusion\nIndie folk pop\nIndie folk rock\nIndie folk, Indian classical, lo-fi pop\nIndie folk, cinematic, Indian classical\nIndie fusion\nIndie pop\nIndie pop, electronic, Indian fusion\nIndie pop, flamenco fusion\nIndie rock\nIndie rock, folk-rock\nIndipop\nIndipop Latin fusion\nIndipop R&B\nIndipop R&B deep house\nIndipop R&B funk\nIndipop R&B hip-hop\nIndipop R&B lo-fi\nIndipop ballad\nIndipop chiptune\nIndipop dance-pop\nIndipop folk\nIndipop folk-rock\nIndipop funk\nIndipop funk Latin\nIndipop funk R&B\nIndipop funk disco\nIndipop funk soul\nIndipop funk-rock\nIndipop future bass\nIndipop jazz\nIndipop lounge\nIndipop lounge neo-soul\nIndipop rockabilly\nIndipop tango\nIndipop world music\nIndipop, EDM\nIndipop, Latin fusion\nIndipop, bedroom pop\nIndipop, dance-pop, EDM\nIndipop, dance-pop, chiptune\nIndipop, funk, 90s Bollywood\nIndipop, hyperpop, Bollywood\nIndipop, synth-pop, retro\nIndo hip-hop\nIndo pop\nIndo pop chiptune\nIndo-American fusion\nIndo-Latin fusion\nIndo-R&B\nIndo-Western fusion\nIndo-Western hip-hop\nIndo-classical ballad\nIndo-electronic\nIndo-film pop\nIndo-filmi\nIndo-filmi pop\nIndo-folk\nIndo-folk filmi\nIndo-folk fusion\nIndo-folk pop\nIndo-folk rock\nIndo-funk\nIndo-fusion\nIndo-fusion pop-rock\nIndo-fusion rock\nIndo-pop\nIndo-pop R&B\nIndo-pop ballad\nIndo-pop funk\nIndo-pop fusion\nIndo-pop future bass\nIndo-pop rock\nIndo-pop trap\nIndo-pop, electronic, R&B\nIndo-pop, global bass, cinematic hip-hop\nIndo-rock\nIndo-rock fusion\nIndo-tango fusion\nIndo-trap\nIndo-trap R&B\nIndo-trap pop\nIndonesian Christian\nIndonesian Christian children's\nIndonesian Christian pop\nIndonesian Christian pop-rock\nIndonesian Christian power ballad\nIndonesian Christmas\nIndonesian Funkot\nIndonesian Pop\nIndonesian Pop Melayu\nIndonesian Pop R&B\nIndonesian Pop chiptune\nIndonesian Pop lo-fi bedroom pop\nIndonesian Pop, Dangdut\nIndonesian Pop, Malay Pop, pop duet\nIndonesian Pop, Malay Pop, upbeat pop\nIndonesian Pop, R&B, City Pop\nIndonesian Pop-R&B\nIndonesian R&B\nIndonesian R&B hip-hop\nIndonesian R&B lo-fi hip-hop\nIndonesian acoustic\nIndonesian acoustic ballad\nIndonesian acoustic folk\nIndonesian acoustic pop\nIndonesian alternative rock\nIndonesian ballad\nIndonesian ballad rock\nIndonesian cabaret\nIndonesian children's\nIndonesian children's disco\nIndonesian children's music\nIndonesian children's pop\nIndonesian children's, Latin cha-cha\nIndonesian city pop\nIndonesian city pop funk\nIndonesian city pop nu-disco\nIndonesian classical\nIndonesian dance\nIndonesian dance-pop\nIndonesian dancehall\nIndonesian disco\nIndonesian disco-funk\nIndonesian disco-pop\nIndonesian folk\nIndonesian folk Latin\nIndonesian folk pop\nIndonesian folk protest\nIndonesian folk rock\nIndonesian folk, bluegrass, country\nIndonesian folk, psychedelic cumbia, rock\nIndonesian folk-pop\nIndonesian folk-rock\nIndonesian funk\nIndonesian funk disco\nIndonesian funk fusion\nIndonesian funk rock\nIndonesian funk-pop\nIndonesian funk-rock\nIndonesian funkot\nIndonesian fusion\nIndonesian gospel pop\nIndonesian hard rock\nIndonesian hip hop\nIndonesian hip-hop\nIndonesian hip-hop funkot\nIndonesian hip-hop trap\nIndonesian hip-hop, chiptune, hyperpop\nIndonesian hip-hop, cinematic trap\nIndonesian house\nIndonesian indie folk\nIndonesian indie folk-pop\nIndonesian indie pop\nIndonesian indie rock\nIndonesian indie-folk\nIndonesian lullaby\nIndonesian new wave\nIndonesian patriotic\nIndonesian pop\nIndonesian pop 80s\nIndonesian pop 90s\nIndonesian pop Afrobeats\nIndonesian pop Bollywood\nIndonesian pop Bossa Nova\nIndonesian pop Dangdut\nIndonesian pop EDM\nIndonesian pop Eurodance\nIndonesian pop Funkot\nIndonesian pop J-Pop\nIndonesian pop J-pop\nIndonesian pop J-pop chiptune\nIndonesian pop Javanese folk\nIndonesian pop Keroncong\nIndonesian pop Latin\nIndonesian pop R&B\nIndonesian pop R&B K-pop\nIndonesian pop R&B city pop\nIndonesian pop R&B funk\nIndonesian pop R&B reggae fusion\nIndonesian pop R&B trap\nIndonesian pop alternative rock\nIndonesian pop ballad\nIndonesian pop ballad, dangdut koplo, cinematic\nIndonesian pop ballad, pop-rock, dangdut koplo\nIndonesian pop big band\nIndonesian pop big band swing\nIndonesian pop bossa nova\nIndonesian pop cabaret\nIndonesian pop calypso\nIndonesian pop chiptune\nIndonesian pop cinematic\nIndonesian pop city pop\nIndonesian pop city pop R&B\nIndonesian pop city pop funk\nIndonesian pop city pop lounge\nIndonesian pop city pop lounge jazz\nIndonesian pop city pop smooth jazz\nIndonesian pop city pop tropical\nIndonesian pop city-pop\nIndonesian pop country\nIndonesian pop dancehall\nIndonesian pop dancehall reggaeton\nIndonesian pop dangdut\nIndonesian pop dangdut koplo\nIndonesian pop disco\nIndonesian pop disco funk\nIndonesian pop exotica lounge\nIndonesian pop folk\nIndonesian pop funk\nIndonesian pop funk R&B\nIndonesian pop funk city pop\nIndonesian pop funk disco\nIndonesian pop funk rock\nIndonesian pop funk soul\nIndonesian pop funkot\nIndonesian pop future bass\nIndonesian pop future bass hyperpop\nIndonesian pop future bass tropical house\nIndonesian pop gospel\nIndonesian pop hip-hop\nIndonesian pop hip-hop funk\nIndonesian pop house\nIndonesian pop jazz\nIndonesian pop jazz lounge\nIndonesian pop jazz soul\nIndonesian pop jazz swing\nIndonesian pop keroncong\nIndonesian pop lo-fi\nIndonesian pop lounge\nIndonesian pop lounge city pop\nIndonesian pop lounge exotica\nIndonesian pop lounge jazz\nIndonesian pop lounge soul\nIndonesian pop neo-soul\nIndonesian pop neo-soul funk\nIndonesian pop new wave funk\nIndonesian pop novelty\nIndonesian pop psychedelic\nIndonesian pop reggae\nIndonesian pop reggae Latin\nIndonesian pop reggae dancehall\nIndonesian pop reggae ska\nIndonesian pop reggae-dancehall\nIndonesian pop reggae-pop\nIndonesian pop reggaeton\nIndonesian pop retro\nIndonesian pop retro surf-rock\nIndonesian pop retro-dangdut\nIndonesian pop retro-funk\nIndonesian pop rock\nIndonesian pop rock, Dangdut\nIndonesian pop rockabilly\nIndonesian pop samba\nIndonesian pop soul\nIndonesian pop soul jazz\nIndonesian pop surf rock\nIndonesian pop swing\nIndonesian pop trap\nIndonesian pop world fusion\nIndonesian pop world music\nIndonesian pop worldbeat\nIndonesian pop, 80s city pop, synth-pop\nIndonesian pop, 80s dance-pop, retro synth\nIndonesian pop, 80s pop, funk\nIndonesian pop, 80s pop, romantic ballad\nIndonesian pop, 80s synth pop\nIndonesian pop, 90s dance-pop\nIndonesian pop, 90s dance-pop, dangdut koplo\nIndonesian pop, Bollywood dance\nIndonesian pop, Bollywood, cinematic\nIndonesian pop, Bossa Nova\nIndonesian pop, Bossa Nova, Latin jazz\nIndonesian pop, Bossa Nova, jazz\nIndonesian pop, Christian contemporary\nIndonesian pop, Cumbia\nIndonesian pop, Cumbia, Latin pop\nIndonesian pop, Cumbia, Salsa\nIndonesian pop, Dangdut\nIndonesian pop, Dangdut Koplo\nIndonesian pop, Dangdut Koplo, EDM\nIndonesian pop, Dangdut Koplo, electronic\nIndonesian pop, Dangdut Koplo, worldbeat\nIndonesian pop, Dangdut, Javanese\nIndonesian pop, Dangdut, Middle Eastern\nIndonesian pop, Dangdut, Middle Eastern fusion\nIndonesian pop, Dangdut, Middle Eastern pop\nIndonesian pop, Dangdut, ambient fusion\nIndonesian pop, Dangdut, cinematic\nIndonesian pop, Dangdut, cinematic ballad\nIndonesian pop, Dangdut, cinematic pop\nIndonesian pop, Dangdut, pop-rock\nIndonesian pop, Dangdut, synth-pop\nIndonesian pop, Dangdut, world music\nIndonesian pop, EDM\nIndonesian pop, EDM, dance-pop\nIndonesian pop, EDM, funk\nIndonesian pop, EDM, future bass\nIndonesian pop, EDM, hip-hop\nIndonesian pop, EDM, tropical house\nIndonesian pop, Eurodance\nIndonesian pop, Eurodance, Dangdut Koplo\nIndonesian pop, Eurodance, chiptune\nIndonesian pop, Eurodance, happy hardcore\nIndonesian pop, Eurodance, trance\nIndonesian pop, European folk\nIndonesian pop, Funkot\nIndonesian pop, Funkot, happy hardcore\nIndonesian pop, Indian classical\nIndonesian pop, Javanese, pop\nIndonesian pop, Javanese, pop-rock\nIndonesian pop, Javanese, romantic\nIndonesian pop, Keroncong, ballad\nIndonesian pop, Latin Cumbia\nIndonesian pop, Latin cha-cha-chá\nIndonesian pop, Latin disco, funk\nIndonesian pop, Latin funk\nIndonesian pop, Latin jazz\nIndonesian pop, Latin jazz, bossa nova\nIndonesian pop, Latin jazz, exotica\nIndonesian pop, Latin jazz, mambo\nIndonesian pop, Latin mambo, vintage\nIndonesian pop, Latin pop\nIndonesian pop, Latin pop, 80s Melayu\nIndonesian pop, Latin pop, 80s pop\nIndonesian pop, Latin pop, Bollywood pop\nIndonesian pop, Latin pop, Cumbia\nIndonesian pop, Latin pop, Dangdut\nIndonesian pop, Latin pop, Melayu\nIndonesian pop, Latin pop, ballad\nIndonesian pop, Latin pop, big band\nIndonesian pop, Latin pop, cha-cha-chá\nIndonesian pop, Latin pop, cinematic\nIndonesian pop, Latin pop, cinematic ballad\nIndonesian pop, Latin pop, city pop\nIndonesian pop, Latin pop, cumbia\nIndonesian pop, Latin pop, dance-pop\nIndonesian pop, Latin pop, disco\nIndonesian pop, Latin pop, folk\nIndonesian pop, Latin pop, jazz fusion\nIndonesian pop, Latin pop, keroncong\nIndonesian pop, Latin pop, psychedelic\nIndonesian pop, Latin pop, psychedelic pop\nIndonesian pop, Latin pop, reggae\nIndonesian pop, Latin pop, retro\nIndonesian pop, Latin pop, salsa\nIndonesian pop, Latin pop, ska\nIndonesian pop, Latin pop, surf rock\nIndonesian pop, Latin pop, vintage pop\nIndonesian pop, Latin pop, vintage rock\nIndonesian pop, Latin pop, world music\nIndonesian pop, Latin rock, 80s pop\nIndonesian pop, Latin rock, surf rock\nIndonesian pop, Latin rock, vintage pop\nIndonesian pop, Latin, big band\nIndonesian pop, Latin, cha-cha-chá\nIndonesian pop, Latin, mambo\nIndonesian pop, Latin, psychedelic\nIndonesian pop, Latin, reggae\nIndonesian pop, Latin, world music\nIndonesian pop, Malaysian pop, upbeat pop\nIndonesian pop, Middle Eastern fusion\nIndonesian pop, Middle Eastern, Malay\nIndonesian pop, Pop Melayu, Dangdut\nIndonesian pop, Pop Sunda\nIndonesian pop, Pop Sunda, pop-rock\nIndonesian pop, R&B\nIndonesian pop, R&B, acoustic ballad\nIndonesian pop, R&B, ballad\nIndonesian pop, R&B, cinematic\nIndonesian pop, R&B, city pop\nIndonesian pop, R&B, dance-pop\nIndonesian pop, R&B, early 2000s pop\nIndonesian pop, R&B, funk\nIndonesian pop, R&B, hip-hop\nIndonesian pop, R&B, lo-fi hip-hop\nIndonesian pop, R&B, pop\nIndonesian pop, alternative rock\nIndonesian pop, ambient synth, Vocaloid\nIndonesian pop, anime soundtrack\nIndonesian pop, bedroom pop\nIndonesian pop, big band\nIndonesian pop, big band jazz\nIndonesian pop, big band swing\nIndonesian pop, big band, Latin\nIndonesian pop, big band, keroncong\nIndonesian pop, big band, lounge\nIndonesian pop, big band, rock and roll\nIndonesian pop, big band, soul\nIndonesian pop, big band, swing\nIndonesian pop, big band, vintage\nIndonesian pop, bossa nova, cha-cha-cha\nIndonesian pop, bossa nova, surf rock\nIndonesian pop, chiptune\nIndonesian pop, chiptune, J-pop\nIndonesian pop, chiptune, bubblegum pop\nIndonesian pop, chiptune, dangdut koplo\nIndonesian pop, chiptune, electronic dance\nIndonesian pop, chiptune, funk\nIndonesian pop, chiptune, lo-fi\nIndonesian pop, chiptune, novelty\nIndonesian pop, chiptune, video game music\nIndonesian pop, cinematic ballad, European influence\nIndonesian pop, cinematic orchestral\nIndonesian pop, cinematic pop\nIndonesian pop, cinematic rock\nIndonesian pop, cinematic, Dangdut\nIndonesian pop, cinematic, ballad\nIndonesian pop, cinematic, orchestral\nIndonesian pop, cinematic, psychedelic rock\nIndonesian pop, cinematic, rock\nIndonesian pop, cinematic, vintage film score\nIndonesian pop, cinematic, world fusion\nIndonesian pop, city pop\nIndonesian pop, city pop, 80s aesthetic\nIndonesian pop, city pop, 80s new wave\nIndonesian pop, city pop, 80s synth-pop\nIndonesian pop, city pop, 90s dance-pop\nIndonesian pop, city pop, Dangdut Koplo\nIndonesian pop, city pop, Latin pop\nIndonesian pop, city pop, R&B\nIndonesian pop, city pop, big band\nIndonesian pop, city pop, dangdut koplo\nIndonesian pop, city pop, disco\nIndonesian pop, city pop, dream pop\nIndonesian pop, city pop, funk\nIndonesian pop, city pop, jazz\nIndonesian pop, city pop, jazz fusion\nIndonesian pop, city pop, jazz-fusion\nIndonesian pop, city pop, lounge jazz\nIndonesian pop, city pop, new jack swing\nIndonesian pop, city pop, new wave\nIndonesian pop, city pop, pop Melayu\nIndonesian pop, city pop, pop keroncong\nIndonesian pop, city pop, pop-rock\nIndonesian pop, city pop, retro\nIndonesian pop, city pop, smooth jazz\nIndonesian pop, city pop, synth-pop\nIndonesian pop, city pop, vintage big band\nIndonesian pop, city pop, vintage disco\nIndonesian pop, city pop, vintage jazz\nIndonesian pop, city-pop\nIndonesian pop, city-pop, dreamy\nIndonesian pop, cumbia\nIndonesian pop, cumbia, Latin pop\nIndonesian pop, cumbia, bossa nova\nIndonesian pop, cumbia, dangdut koplo\nIndonesian pop, cumbia, disco\nIndonesian pop, cumbia, reggae\nIndonesian pop, cumbia, salsa\nIndonesian pop, cumbia, ska\nIndonesian pop, cumbia, surf rock\nIndonesian pop, cumbia, vintage pop\nIndonesian pop, dance-pop\nIndonesian pop, dance-pop, EDM\nIndonesian pop, dance-pop, dangdut koplo\nIndonesian pop, dance-pop, hyperpop\nIndonesian pop, dance-pop, new jack swing\nIndonesian pop, dancehall, reggaeton\nIndonesian pop, dangdut\nIndonesian pop, dangdut koplo\nIndonesian pop, dangdut koplo, 2000s pop\nIndonesian pop, dangdut koplo, 90s Melayu\nIndonesian pop, dangdut koplo, children's music\nIndonesian pop, dangdut koplo, chiptune\nIndonesian pop, dangdut koplo, electronic\nIndonesian pop, dangdut koplo, electronic pop\nIndonesian pop, dangdut koplo, hip-hop\nIndonesian pop, dangdut koplo, pop-rap\nIndonesian pop, dangdut koplo, pop-rock\nIndonesian pop, dangdut koplo, reggae\nIndonesian pop, dangdut koplo, reggaeton\nIndonesian pop, dangdut koplo, retro pop\nIndonesian pop, dangdut koplo, synthwave\nIndonesian pop, dangdut, big band\nIndonesian pop, dangdut, cinematic\nIndonesian pop, dangdut, folk\nIndonesian pop, dangdut, gospel\nIndonesian pop, dangdut, pop-rock\nIndonesian pop, dangdut, power ballad\nIndonesian pop, dangdut, theatrical pop\nIndonesian pop, disco, city pop\nIndonesian pop, disco, funk\nIndonesian pop, disco-funk\nIndonesian pop, early 2000s house\nIndonesian pop, electro-pop, dangdut\nIndonesian pop, electronic dance\nIndonesian pop, electronic dance music\nIndonesian pop, electronic dance, retro synth\nIndonesian pop, electronic, Dangdut\nIndonesian pop, electronic, EDM\nIndonesian pop, electronic, trance\nIndonesian pop, festive, cinematic\nIndonesian pop, folk pop\nIndonesian pop, funk, 80s synth\nIndonesian pop, funk, Latin\nIndonesian pop, funk, city pop\nIndonesian pop, funk, electronic pop\nIndonesian pop, funkot, electronic dance\nIndonesian pop, future bass\nIndonesian pop, future bass, cinematic\nIndonesian pop, future bass, dream pop\nIndonesian pop, garage rock, surf rock\nIndonesian pop, garage rock, yeh-yeh\nIndonesian pop, gospel, 80s pop\nIndonesian pop, gospel, 80s synth\nIndonesian pop, gospel, disco\nIndonesian pop, gospel, pop-rock\nIndonesian pop, gospel, soul\nIndonesian pop, gospel, vintage\nIndonesian pop, hard rock\nIndonesian pop, hard rock, Dangdut Koplo\nIndonesian pop, hard rock, metal\nIndonesian pop, hip-hop\nIndonesian pop, hip-hop, R&B\nIndonesian pop, hip-hop, electronic\nIndonesian pop, hyperpop, funk\nIndonesian pop, jazz ballad\nIndonesian pop, jazz, R&B\nIndonesian pop, jazz, bossa nova\nIndonesian pop, jazz, soul\nIndonesian pop, lounge, exotica\nIndonesian pop, new jack swing\nIndonesian pop, new jack swing, funk\nIndonesian pop, new jack swing, retro\nIndonesian pop, new wave\nIndonesian pop, novelty pop\nIndonesian pop, pop ballad, flamenco\nIndonesian pop, pop-dangdut\nIndonesian pop, pop-punk\nIndonesian pop, pop-rock\nIndonesian pop, pop-rock, dangdut koplo\nIndonesian pop, pop-rock, rock\nIndonesian pop, psychedelic rock\nIndonesian pop, psychedelic rock, ballad\nIndonesian pop, psychedelic rock, blues-rock\nIndonesian pop, psychedelic, Latin funk\nIndonesian pop, psychedelic, vintage\nIndonesian pop, reggae, dancehall\nIndonesian pop, retro bubblegum pop\nIndonesian pop, retro dance-pop\nIndonesian pop, retro electronic, chiptune\nIndonesian pop, retro funk, city pop\nIndonesian pop, retro pop, bubblegum pop\nIndonesian pop, retro pop, chiptune\nIndonesian pop, retro pop, dangdut\nIndonesian pop, retro pop, novelty\nIndonesian pop, retro surf-rock\nIndonesian pop, retro video game\nIndonesian pop, retro, Middle Eastern\nIndonesian pop, retro, chiptune\nIndonesian pop, retro, city pop\nIndonesian pop, retro, gospel\nIndonesian pop, retro-dangdut, pop\nIndonesian pop, slow rock\nIndonesian pop, slow rock, dangdut\nIndonesian pop, smooth jazz\nIndonesian pop, smooth jazz, Dangdut\nIndonesian pop, smooth jazz, adult contemporary\nIndonesian pop, soul, big band\nIndonesian pop, surf rock, keroncong\nIndonesian pop, surf rock, pop keroncong\nIndonesian pop, synth-pop\nIndonesian pop, synth-pop, 80s city pop\nIndonesian pop, synth-pop, chiptune\nIndonesian pop, synth-pop, city pop\nIndonesian pop, synth-pop, pop-rock\nIndonesian pop, synthpop\nIndonesian pop, trance-pop\nIndonesian pop, trap R&B\nIndonesian pop, trap-R&B\nIndonesian pop, vintage big band, swing\nIndonesian pop, vintage film score\nIndonesian pop, vintage soul, big band\nIndonesian pop, world music\nIndonesian pop, world music, Pop Sunda\nIndonesian pop, world music, ambient ballad\nIndonesian pop, world music, ballad\nIndonesian pop-EDM\nIndonesian pop-R&B\nIndonesian pop-dance\nIndonesian pop-dancehall\nIndonesian pop-dangdut\nIndonesian pop-folk\nIndonesian pop-funk\nIndonesian pop-gospel\nIndonesian pop-jazz\nIndonesian pop-punk\nIndonesian pop-rap\nIndonesian pop-reggae\nIndonesian pop-reggaeton\nIndonesian pop-rock\nIndonesian pop-rock 80s\nIndonesian pop-rock bossa nova\nIndonesian pop-rock chiptune\nIndonesian pop-rock city pop\nIndonesian pop-rock funk\nIndonesian pop-rock funk disco\nIndonesian pop-rock jazz fusion\nIndonesian pop-rock reggae\nIndonesian pop-rock, Dangdut Koplo\nIndonesian pop-rock, EDM, electronic\nIndonesian pop-rock, J-rock\nIndonesian pop-rock, Middle Eastern fusion\nIndonesian pop-rock, alternative metal\nIndonesian pop-rock, cinematic ambient\nIndonesian pop-rock, city pop\nIndonesian pop-rock, city-pop\nIndonesian pop-rock, dance-rock, hardstyle\nIndonesian pop-rock, dangdut koplo\nIndonesian pop-rock, funk pop\nIndonesian pop-rock, hard rock\nIndonesian pop-rock, new wave, city pop\nIndonesian pop-rock, power metal\nIndonesian pop-rock, power metal, dangdut koplo\nIndonesian pop-rock, ska-punk, thrash metal\nIndonesian pop-rock, world music\nIndonesian pop-ska\nIndonesian pop-trap\nIndonesian pop-trap, future bass, hyperpop\nIndonesian power ballad\nIndonesian power ballad, J-rock\nIndonesian punk rock\nIndonesian rock\nIndonesian rock ballad\nIndonesian rock funk rock\nIndonesian rock fusion\nIndonesian rock reggae ska\nIndonesian rock surf rock\nIndonesian rock, Dangdut, rock ballad\nIndonesian rock, Middle Eastern fusion\nIndonesian rock, heavy metal\nIndonesian rock, psychedelic rock\nIndonesian rock, psychedelic rock, garage rock\nIndonesian rock, surf rock\nIndonesian slow jam\nIndonesian slow rock\nIndonesian slow rock, power metal\nIndonesian soul\nIndonesian soul-pop\nIndonesian spiritual pop-rock\nIndonesian trap\nIrish drill\nIrish folk\nIrish folk comedy\nIrish folk country\nIrish folk drill\nIrish folk hip-hop\nIrish folk house\nIrish folk reggae\nIrish folk rock\nIrish folk trap\nIrish folk, Dixieland jazz\nIrish folk, Middle Eastern, fusion\nIrish folk, big band\nIrish folk, bluegrass\nIrish folk, country\nIrish folk, country swing\nIrish folk, country, polka\nIrish folk, country, pub rock\nIrish folk, music hall, skiffle\nIrish folk, skiffle, early rock and roll\nIrish folk-country\nIrish folk-pop\nIrish folk-punk\nIrish folk-rock\nIrish hip-hop\nIrish pub rock\nIrish rock\nIrish trap\nIsicathamiya\nIsicathamiya Afrobeat\nIsicathamiya, Cumbia\nIslamic Naat\nIslamic Nasheed\nIslamic Nasyid\nIslamic Nasyid pop-rock\nIslamic R&B\nIslamic a cappella\nIslamic aat\nIslamic ambient\nIslamic anasheed\nIslamic anthem\nIslamic ballad\nIslamic bhajan\nIslamic chant\nIslamic children's music\nIslamic children's pop\nIslamic chiptune\nIslamic devotional\nIslamic devotional hip-hop\nIslamic devotional pop\nIslamic devotional pop-rock\nIslamic devotional salsa\nIslamic devotional trap\nIslamic devotional, French pop, hip-hop\nIslamic devotional, Latin fusion, Middle Eastern\nIslamic devotional, Middle Eastern pop\nIslamic devotional, Middle Eastern pop, Malay pop\nIslamic devotional, Middle Eastern pop, South Asian fusion\nIslamic devotional, Middle Eastern, Eastern European\nIslamic devotional, Middle Eastern, Latin\nIslamic devotional, Middle Eastern, Malay\nIslamic devotional, Middle Eastern, South Asian\nIslamic devotional, Middle Eastern, modern\nIslamic devotional, North African, electronic\nIslamic devotional, R&B, hip-hop\nIslamic devotional, South Asian folk\nIslamic devotional, South Asian folk, Bollywood\nIslamic devotional, South Asian folk, Middle Eastern folk\nIslamic devotional, South Asian folk, ghazal\nIslamic devotional, South Asian folk, qawwali\nIslamic devotional, South Asian pop\nIslamic devotional, South Asian qawwali\nIslamic devotional, South Asian, Middle Eastern\nIslamic devotional, South Asian, Qawwali\nIslamic devotional, South Asian, choral\nIslamic devotional, South Asian, electronic\nIslamic devotional, South Indian film music\nIslamic devotional, South Indian folk\nIslamic devotional, South Indian folk, qawwali\nIslamic devotional, South Indian pop\nIslamic devotional, South Indian, ambient\nIslamic devotional, chiptune\nIslamic devotional, cinematic pop\nIslamic devotional, cinematic, pop\nIslamic devotional, electronic pop\nIslamic devotional, electronic pop, trap\nIslamic devotional, electronic, Arabic\nIslamic devotional, electronic, celebratory\nIslamic devotional, electronic, cinematic\nIslamic devotional, electronic, modern\nIslamic devotional, electronic, pop\nIslamic devotional, electronic, trap\nIslamic devotional, soca, Caribbean\nIslamic devotional, synth-pop\nIslamic devotional, trap, hip-hop\nIslamic devotional, world folk\nIslamic devotional, world fusion\nIslamic devotional, world music\nIslamic devotional, world music, ambient pop\nIslamic devotional, world music, pop\nIslamic disco-funk\nIslamic educational\nIslamic educational, Latin, Middle Eastern\nIslamic electronic\nIslamic electronic pop\nIslamic folk\nIslamic hip-hop\nIslamic hip-hop chiptune\nIslamic hymn\nIslamic music\nIslamic nasheed\nIslamic nasheed electronic\nIslamic nasheed hip-hop\nIslamic nasheed hip-hop chiptune\nIslamic nasheed pop\nIslamic nasheed, R&B, pop\nIslamic nasheed, pop, hip-hop\nIslamic nasheed, trap, pop\nIslamic pop\nIslamic pop Eurodance\nIslamic pop J-pop\nIslamic pop Latin\nIslamic pop R&B\nIslamic pop chiptune\nIslamic pop fusion\nIslamic pop hip-hop\nIslamic pop nasheed\nIslamic pop reggae\nIslamic pop salsa\nIslamic pop world music\nIslamic pop, Arabic fusion, devotional\nIslamic pop, Bollywood\nIslamic pop, Dangdut Koplo\nIslamic pop, Dangdut, Pop Sunda\nIslamic pop, EDM\nIslamic pop, Pop Sunda\nIslamic pop, chiptune, modern C-pop\nIslamic pop, electronic dance music\nIslamic pop, modern Dangdut\nIslamic pop-EDM\nIslamic pop-dance\nIslamic pop-folk\nIslamic pop-rap\nIslamic pop-rock\nIslamic pop-trap\nIslamic rock\nIslamic spiritual\nIslamic trap\nIslamic world music\nIsraeli R&B\nIsraeli art-pop\nIsraeli ballad\nIsraeli blues-rock\nIsraeli dance-pop\nIsraeli dancehall\nIsraeli disco-funk\nIsraeli disco-pop\nIsraeli drill\nIsraeli electronic\nIsraeli electronic dance\nIsraeli electronic pop\nIsraeli folk\nIsraeli folk pop-rock\nIsraeli folk rock\nIsraeli folk, Latin, salsa\nIsraeli folk-gospel\nIsraeli folk-pop\nIsraeli folk-rock\nIsraeli funk-rock\nIsraeli hip-hop\nIsraeli hip-hop Mizrahi\nIsraeli hip-hop R&B\nIsraeli hip-hop chiptune\nIsraeli hip-hop reggaeton\nIsraeli hip-hop trap\nIsraeli hip-hop, Mizrahi, trap\nIsraeli indie pop\nIsraeli indie rock\nIsraeli marching\nIsraeli pop\nIsraeli pop Mizrahi\nIsraeli pop ballad\nIsraeli pop cabaret\nIsraeli pop chiptune\nIsraeli pop disco-funk\nIsraeli pop funk\nIsraeli pop funk dancehall\nIsraeli pop funk disco\nIsraeli pop reggaeton\nIsraeli pop trap\nIsraeli pop, 80s Mizrahi\nIsraeli pop, 80s Mizrahi, funk\nIsraeli pop, 80s Mizrahi, theatrical pop\nIsraeli pop, 80s Mizrahi, upbeat\nIsraeli pop, 80s synth pop\nIsraeli pop, Afrobeat, dancehall\nIsraeli pop, Balkan, Klezmer\nIsraeli pop, EDM\nIsraeli pop, Eurodance\nIsraeli pop, Latin pop\nIsraeli pop, Latin pop, Mediterranean\nIsraeli pop, Latin pop, Mizrahi\nIsraeli pop, Latin pop, cumbia\nIsraeli pop, Latin pop, retro\nIsraeli pop, Latin pop, theatrical\nIsraeli pop, Latin pop, vintage pop\nIsraeli pop, Latin, Mizrahi\nIsraeli pop, Latin, big band\nIsraeli pop, Mizrahi, 80s synth\nIsraeli pop, Mizrahi, EDM\nIsraeli pop, Mizrahi, Eurodance\nIsraeli pop, Mizrahi, Mediterranean\nIsraeli pop, Mizrahi, cinematic pop\nIsraeli pop, Mizrahi, dance\nIsraeli pop, Mizrahi, dance pop\nIsraeli pop, Mizrahi, dance-pop\nIsraeli pop, Mizrahi, dancehall\nIsraeli pop, Mizrahi, electronic\nIsraeli pop, Mizrahi, electronic dance\nIsraeli pop, Mizrahi, modern pop\nIsraeli pop, Mizrahi, pop-dance\nIsraeli pop, Mizrahi, pop-rock\nIsraeli pop, Mizrahi, reggaeton\nIsraeli pop, Mizrahi, synth pop\nIsraeli pop, Mizrahi, trap\nIsraeli pop, Mizrahi, upbeat\nIsraeli pop, Moombahton, dancehall\nIsraeli pop, dance pop, electronic\nIsraeli pop, dance-pop, Mizrahi\nIsraeli pop, dancehall, afrobeat\nIsraeli pop, dancehall, reggaeton\nIsraeli pop, electronic, dance-pop\nIsraeli pop, electronic, funk\nIsraeli pop, electronic, trap\nIsraeli pop, funk, Mizrahi\nIsraeli pop, funk, disco\nIsraeli pop, hip-hop, dancehall\nIsraeli pop, hip-hop, electronic\nIsraeli pop, hip-hop, electronic dance\nIsraeli pop, hip-hop, trap\nIsraeli pop, lo-fi hip-hop\nIsraeli pop, lounge, big band\nIsraeli pop, reggae, dancehall\nIsraeli pop, reggaeton\nIsraeli pop, reggaeton, dancehall\nIsraeli pop, reggaeton, moombahton\nIsraeli pop, retro, big-band\nIsraeli pop, retro, surf rock\nIsraeli pop, synth-pop, dance-pop\nIsraeli pop, theatrical pop, polka\nIsraeli pop, trap, Middle Eastern\nIsraeli pop, trap, R&B\nIsraeli pop, trap, electronic\nIsraeli pop, trap, electronic dance\nIsraeli pop, trap, hyperpop\nIsraeli pop-R&B\nIsraeli pop-folk\nIsraeli pop-funk\nIsraeli pop-rap\nIsraeli pop-reggae\nIsraeli pop-reggaeton\nIsraeli pop-rock\nIsraeli pop-rock country\nIsraeli pop-rock funk\nIsraeli pop-rock reggae ska\nIsraeli pop-rock, 80s revival\nIsraeli pop-rock, Eurodance\nIsraeli pop-rock, Mizrahi, 90s\nIsraeli pop-trap\nIsraeli power ballad\nIsraeli psytrance\nIsraeli reggae\nIsraeli rock\nIsraeli rock funk disco\nIsraeli rock surf rock\nIsraeli rock surf-rock\nIsraeli rock, Balkan, Klezmer\nIsraeli rock, Middle Eastern folk\nIsraeli rock, new wave\nIsraeli rock, surf rock\nIsraeli trance\nIsraeli trance-pop\nIsraeli trap\nIsraeli trap-pop\nItalian Christian power ballad\nItalian Christmas\nItalian Christmas pop\nItalian Christmas, 60s rock, big band\nItalian R&B\nItalian R&B trap\nItalian R&B trap-soul\nItalian R&B, UK drill\nItalian R&B, hip-hop\nItalian R&B, lo-fi hip hop\nItalian R&B, trap, pop R&B\nItalian alt-rock\nItalian alternative R&B\nItalian alternative pop\nItalian alternative rock\nItalian art song\nItalian art song jazz\nItalian art song, big band, cinematic\nItalian art song, jazz, chanson\nItalian art-pop\nItalian art-rock\nItalian ballad\nItalian ballad flamenco\nItalian ballad jazz\nItalian ballad jazz blues\nItalian ballad jazz lounge\nItalian ballad jazz tango\nItalian ballad tango\nItalian ballad, Bossa Nova, Latin jazz\nItalian ballad, Latin jazz\nItalian ballad, Latin pop, romantic\nItalian ballad, Latin, bolero\nItalian ballad, Latin-pop\nItalian ballad, Neapolitan folk\nItalian ballad, Neapolitan style\nItalian ballad, Western, folk\nItalian ballad, art rock, cinematic\nItalian ballad, big band jazz\nItalian ballad, big band, cinematic\nItalian ballad, blues, cinematic\nItalian ballad, bolero, tango\nItalian ballad, cinematic folk, ethereal pop\nItalian ballad, cinematic rock\nItalian ballad, cinematic synth, operatic pop\nItalian ballad, cinematic, Western\nItalian ballad, cinematic, jazz\nItalian ballad, cinematic, orchestral\nItalian ballad, film noir, lo-fi\nItalian ballad, folk, cinematic\nItalian ballad, jazz, cinematic\nItalian ballad, jazz, melancholic\nItalian ballad, jazz, soul\nItalian ballad, mambo, swing\nItalian ballad, operatic pop, theatrical\nItalian ballad, operatic, theatrical\nItalian ballad, pop-rock, Latin jam\nItalian ballad, pop-rock, theatrical\nItalian ballad, rock anthem\nItalian ballad, rock, jazz fusion\nItalian ballad, stadium rock\nItalian ballad, tango, Latin\nItalian ballad, theatrical rock, cinematic\nItalian blues\nItalian bolero\nItalian cabaret\nItalian cantautore\nItalian cantautore, flamenco, jazz\nItalian canzone\nItalian cartoon\nItalian cartoon theme\nItalian chanson\nItalian chanson jazz waltz\nItalian chanson tango\nItalian chanson tango gypsy jazz\nItalian chanson, Bossa Nova\nItalian chanson, folk, cinematic\nItalian chanson, gypsy jazz, tango\nItalian children's carnival\nItalian children's cartoon\nItalian children's music\nItalian children's pop\nItalian children's, vintage theatrical, surf rock\nItalian chopper rap\nItalian cloud rap\nItalian cloud rap, hyperpop, chiptune\nItalian conscious hip-hop\nItalian crooner\nItalian cumbia\nItalian dance-pop\nItalian dancehall\nItalian disco salsa\nItalian disco-funk\nItalian disco-pop\nItalian drill\nItalian drill trap\nItalian drill, trap\nItalian emo rap\nItalian emo-rap\nItalian film score\nItalian folk\nItalian folk ballad\nItalian folk blues-rock\nItalian folk cabaret\nItalian folk cabaret tango\nItalian folk cumbia\nItalian folk dance\nItalian folk fusion\nItalian folk hip-hop\nItalian folk jazz\nItalian folk lounge\nItalian folk mambo\nItalian folk pop\nItalian folk pop-rock\nItalian folk protest\nItalian folk punk\nItalian folk rock\nItalian folk rockabilly big band\nItalian folk satire\nItalian folk ska\nItalian folk swing\nItalian folk tango\nItalian folk tango cabaret\nItalian folk waltz\nItalian folk, Arabic vocal, melancholic ballad\nItalian folk, French chanson\nItalian folk, Gipsy Jazz, Latin\nItalian folk, Latin American, folk rock\nItalian folk, Latin fusion\nItalian folk, Latin jazz, cinematic\nItalian folk, Latin, Cumbia\nItalian folk, Latin, Mediterranean\nItalian folk, Latin, big band\nItalian folk, Latin, mariachi\nItalian folk, Latin, samba\nItalian folk, Latin, theatrical\nItalian folk, North African, fusion\nItalian folk, Spanish Latin, Mediterranean pop\nItalian folk, Western, polka\nItalian folk, Western, upbeat\nItalian folk, big band\nItalian folk, big band swing\nItalian folk, big band swing, free jazz\nItalian folk, big band, swing\nItalian folk, big band, theatrical\nItalian folk, bluegrass\nItalian folk, bluegrass, country-folk\nItalian folk, boogie-woogie, Latin\nItalian folk, boogie-woogie, cabaret\nItalian folk, boogie-woogie, theatrical\nItalian folk, boogie-woogie, vintage\nItalian folk, cabaret, Latin\nItalian folk, cabaret, chanson\nItalian folk, cabaret, comedic\nItalian folk, cabaret, flamenco\nItalian folk, cabaret, theatrical\nItalian folk, canzone\nItalian folk, chanson, gypsy-jazz\nItalian folk, children's music, tarantella\nItalian folk, chiptune\nItalian folk, cinematic\nItalian folk, cinematic pop, manouche\nItalian folk, cinematic, opera\nItalian folk, cinematic, orchestral\nItalian folk, comedic skit\nItalian folk, comedic, tarantella\nItalian folk, communal singalong\nItalian folk, flamenco, Latin\nItalian folk, flamenco, tango\nItalian folk, flamenco, theatrical\nItalian folk, folk-punk\nItalian folk, folk-rock, Latin\nItalian folk, folk-rock, psychedelic rock\nItalian folk, forró\nItalian folk, gypsy jazz\nItalian folk, gypsy jazz, Balkan\nItalian folk, gypsy jazz, theatrical\nItalian folk, industrial rock\nItalian folk, klezmer, cinematic\nItalian folk, mambo, cha-cha\nItalian folk, mambo, operatic\nItalian folk, mambo, salsa\nItalian folk, mambo, theatrical\nItalian folk, mariachi, theatrical\nItalian folk, novelty folk\nItalian folk, novelty, polka\nItalian folk, novelty, theatrical\nItalian folk, operatic, cinematic\nItalian folk, polka\nItalian folk, pop-punk\nItalian folk, power ballad\nItalian folk, psychedelic rock\nItalian folk, retro, novelty\nItalian folk, swing, rockabilly\nItalian folk, tango, Balkan\nItalian folk, tango, Latin\nItalian folk, tango, cabaret\nItalian folk, tarantella\nItalian folk, tarantella, theatrical\nItalian folk, theatrical pop, cinematic\nItalian folk, theatrical, Balkan folk\nItalian folk, theatrical, Balkan fusion\nItalian folk, theatrical, Western\nItalian folk, theatrical, choral\nItalian folk, theatrical, flamenco\nItalian folk, theatrical, operatic\nItalian folk, theatrical, polka\nItalian folk-blues\nItalian folk-dance\nItalian folk-pop\nItalian folk-pop country-rock\nItalian folk-pop gypsy jazz\nItalian folk-punk\nItalian folk-rap\nItalian folk-reggae\nItalian folk-rock\nItalian folk-rock blues-rock\nItalian folk-rock, lo-fi hip hop\nItalian funk\nItalian funk-fusion\nItalian funk-pop\nItalian funk-rap\nItalian funk-rock\nItalian gangsta rap\nItalian hardcore punk\nItalian hip hop\nItalian hip-hop\nItalian hip-hop alternative R&B\nItalian hip-hop boom-bap\nItalian hip-hop chiptune\nItalian hip-hop chiptune funk\nItalian hip-hop chiptune trap\nItalian hip-hop cumbia\nItalian hip-hop emo-rap\nItalian hip-hop funk\nItalian hip-hop indie rock\nItalian hip-hop lo-fi\nItalian hip-hop lo-fi boom-bap\nItalian hip-hop nu-disco funk\nItalian hip-hop pop\nItalian hip-hop reggae-ska\nItalian hip-hop reggaeton\nItalian hip-hop trap\nItalian hip-hop vaporwave\nItalian hip-hop, Latin dancehall, funk\nItalian hip-hop, Latin fusion\nItalian hip-hop, atmospheric R&B, trap\nItalian hip-hop, chiptune\nItalian hip-hop, chiptune, boom-bap\nItalian hip-hop, chiptune, trap\nItalian hip-hop, dance-pop\nItalian hip-hop, dream pop, shoegaze\nItalian hip-hop, dreamy synth-pop\nItalian hip-hop, funk-infused hip-hop\nItalian hip-hop, gangsta rap, cinematic\nItalian hip-hop, glitch-hop, industrial\nItalian hip-hop, hard techno\nItalian hip-hop, hyperpop, electronic\nItalian hip-hop, industrial trap, cloud rap\nItalian hip-hop, lo-fi hip-hop, emo rap\nItalian hip-hop, lo-fi, trap\nItalian hip-hop, new jack swing\nItalian hip-hop, pop/R&B\nItalian hip-hop, reggaeton\nItalian hip-hop, reggaeton, breakcore\nItalian hip-hop, rock, electronic\nItalian hip-hop, synth-pop\nItalian hip-hop, trap\nItalian hip-hop, trap, R&B\nItalian hip-hop, trap, atmospheric\nItalian hip-hop, trap, blues-rock\nItalian hip-hop, trap, chiptune\nItalian hip-hop, trap, electronic\nItalian hip-hop, world music, lo-fi\nItalian hip-house\nItalian house\nItalian hymn\nItalian indie dance\nItalian indie folk\nItalian indie folk-rock\nItalian indie pop\nItalian indie pop chiptune\nItalian indie pop funk\nItalian indie pop lo-fi hip-hop\nItalian indie pop-rock\nItalian indie rock\nItalian indie-folk\nItalian indie-pop\nItalian indie-pop lo-fi hip-hop\nItalian jazz\nItalian jazz ballad\nItalian jazz cabaret\nItalian jazz tango\nItalian jazz-blues\nItalian jazz-pop\nItalian jazz-pop tango\nItalian lounge\nItalian lullaby\nItalian mambo\nItalian march\nItalian marching band\nItalian narrative\nItalian narrative ballad\nItalian new wave\nItalian novelty\nItalian novelty, Latin pop, tropical\nItalian novelty, polka, ska\nItalian novelty, tropical, show tune\nItalian opera\nItalian polka\nItalian pop\nItalian pop J-pop\nItalian pop R&B\nItalian pop anime\nItalian pop ballad\nItalian pop ballad, pop-rock\nItalian pop ballad, psychedelic rock\nItalian pop bossa nova\nItalian pop cabaret\nItalian pop cabaret tango\nItalian pop chiptune\nItalian pop cumbia\nItalian pop exotica\nItalian pop folk\nItalian pop funk soul\nItalian pop future bass\nItalian pop jazz\nItalian pop jazz-funk\nItalian pop lo-fi hip-hop\nItalian pop lounge\nItalian pop lounge big band\nItalian pop lounge exotica\nItalian pop lounge jazz\nItalian pop lounge swing\nItalian pop reggaeton\nItalian pop rock\nItalian pop ska\nItalian pop tango\nItalian pop tango cabaret\nItalian pop tango swing\nItalian pop trap\nItalian pop, 80s new wave\nItalian pop, 80s pop, theatrical\nItalian pop, 80s power ballad\nItalian pop, 80s synth, cinematic\nItalian pop, 80s synth, cinematic ballad\nItalian pop, 80s synth, operatic pop\nItalian pop, 80s synth, romantic ballad\nItalian pop, 80s synth, theatrical\nItalian pop, 80s, Schlager\nItalian pop, 90s R&B\nItalian pop, 90s R&B, new jack swing\nItalian pop, Afrobeat, Latin\nItalian pop, Afrobeats, dancehall\nItalian pop, Balkan pop, Latin pop\nItalian pop, Balkan pop, klezmer\nItalian pop, Bossa Nova\nItalian pop, Bossa Nova, Latin\nItalian pop, Bossa Nova, Latin pop\nItalian pop, Bossa Nova, Samba\nItalian pop, Bossa Nova, cinematic\nItalian pop, Bossa Nova, jazz\nItalian pop, Bossa Nova, light jazz\nItalian pop, Bossa Nova, lounge\nItalian pop, Bossa Nova, lounge jazz\nItalian pop, EDM\nItalian pop, EDM, future bass\nItalian pop, Eurodance\nItalian pop, European folk\nItalian pop, European folk, tango\nItalian pop, European folk, theatrical\nItalian pop, European folk, theatrical pop\nItalian pop, J-pop\nItalian pop, J-pop, anime\nItalian pop, J-pop, anime theme\nItalian pop, Latin dance\nItalian pop, Latin dance, cumbia\nItalian pop, Latin dance, reggaeton\nItalian pop, Latin jazz, big band\nItalian pop, Latin jazz, tango\nItalian pop, Latin pop\nItalian pop, Latin pop, Bossa Nova\nItalian pop, Latin pop, Caribbean pop\nItalian pop, Latin pop, Euro-pop\nItalian pop, Latin pop, Mediterranean\nItalian pop, Latin pop, cha-cha-cha\nItalian pop, Latin pop, cha-cha-chá\nItalian pop, Latin pop, cinematic\nItalian pop, Latin pop, cinematic ballad\nItalian pop, Latin pop, cumbia\nItalian pop, Latin pop, dance\nItalian pop, Latin pop, exotica\nItalian pop, Latin pop, flamenco\nItalian pop, Latin pop, flamenco pop\nItalian pop, Latin pop, folk fusion\nItalian pop, Latin pop, mambo\nItalian pop, Latin pop, merengue\nItalian pop, Latin pop, pop-rock\nItalian pop, Latin pop, reggaeton\nItalian pop, Latin pop, retro\nItalian pop, Latin pop, salsa\nItalian pop, Latin pop, samba\nItalian pop, Latin pop, tango\nItalian pop, Latin pop, theatrical\nItalian pop, Latin pop, theatrical pop\nItalian pop, Latin pop, tropical house\nItalian pop, Latin pop, upbeat\nItalian pop, Latin pop, vintage\nItalian pop, Latin pop, world music\nItalian pop, Latin rhythm, ballad\nItalian pop, Latin rhythm, romantic ballad\nItalian pop, Latin rumba\nItalian pop, Latin, big band\nItalian pop, Latin, cha-cha-chá\nItalian pop, Latin, cinematic\nItalian pop, Latin, exotica\nItalian pop, Latin, flamenco\nItalian pop, Latin, mambo\nItalian pop, Latin, ska\nItalian pop, Latin, tango\nItalian pop, Latin, vintage\nItalian pop, Latin-pop, theatrical\nItalian pop, Mediterranean, theatrical\nItalian pop, Mediterranean, world music\nItalian pop, Neapolitan, Latin\nItalian pop, Neapolitan, ballad\nItalian pop, Neapolitan, cinematic\nItalian pop, Neapolitan, jazz\nItalian pop, Neapolitan, pop-rock\nItalian pop, Neapolitan, romantic\nItalian pop, Neapolitan, tango\nItalian pop, Neapolitan, tarantella\nItalian pop, Neapolitan, theatrical\nItalian pop, R&B\nItalian pop, R&B, electronic\nItalian pop, R&B, funk\nItalian pop, R&B, hip-hop\nItalian pop, R&B, late-90s\nItalian pop, R&B, trap\nItalian pop, Schlager\nItalian pop, Spanish flair, festive\nItalian pop, Spanish pop, theatrical\nItalian pop, anime soundtrack\nItalian pop, anime theme\nItalian pop, anime theme, theatrical pop\nItalian pop, art-pop, theatrical\nItalian pop, ballad, Neapolitan\nItalian pop, baroque pop, theatrical\nItalian pop, beat music\nItalian pop, big band\nItalian pop, big band jazz\nItalian pop, big band jazz, tango\nItalian pop, big band swing\nItalian pop, big band swing, rock and roll\nItalian pop, big band, Latin\nItalian pop, big band, lounge\nItalian pop, big band, mambo\nItalian pop, big band, show tune\nItalian pop, big band, swing\nItalian pop, big band, theatrical\nItalian pop, big band, vintage\nItalian pop, big-band swing, theatrical\nItalian pop, big-band swing, theatrical pop\nItalian pop, big-band, cabaret\nItalian pop, big-band, theatrical\nItalian pop, blues, soul\nItalian pop, bolero\nItalian pop, boom-bap hip-hop\nItalian pop, bossa nova\nItalian pop, bossa nova, Latin pop\nItalian pop, cabaret, Balkan fusion\nItalian pop, cabaret, big band\nItalian pop, cabaret, chiptune\nItalian pop, cabaret, lounge jazz\nItalian pop, cabaret, swing\nItalian pop, cabaret, tango\nItalian pop, cabaret, theatrical\nItalian pop, cha-cha, Latin pop\nItalian pop, cha-cha-chá\nItalian pop, chanson, theatrical pop\nItalian pop, chiptune\nItalian pop, chiptune, ballad\nItalian pop, chiptune, theatrical pop\nItalian pop, chiptune, video game music\nItalian pop, cinematic folk\nItalian pop, cinematic orchestral\nItalian pop, cinematic, Bossa Nova\nItalian pop, cinematic, Latin\nItalian pop, cinematic, Latin rhythm\nItalian pop, cinematic, ballad\nItalian pop, cinematic, folk\nItalian pop, cinematic, opera\nItalian pop, cinematic, operatic\nItalian pop, cinematic, orchestral\nItalian pop, cinematic, power ballad\nItalian pop, cinematic, romantic\nItalian pop, cinematic, spaghetti western\nItalian pop, cinematic, theatrical\nItalian pop, cinematic, trip-hop\nItalian pop, cinematic, vintage\nItalian pop, classical crossover\nItalian pop, cumbia\nItalian pop, cumbia, Latin dance\nItalian pop, cumbia, Latin pop\nItalian pop, cumbia, brass pop\nItalian pop, cumbia, cha-cha-chá\nItalian pop, cumbia, dance\nItalian pop, cumbia, folk\nItalian pop, cumbia, merengue\nItalian pop, cumbia, ska\nItalian pop, cumbia, synth pop\nItalian pop, cumbia, upbeat\nItalian pop, dance, Latin\nItalian pop, dance-pop\nItalian pop, dance-pop, R&B\nItalian pop, dark R&B\nItalian pop, deep house\nItalian pop, doo-wop, early rock and roll\nItalian pop, electronic dance\nItalian pop, exotica, Latin\nItalian pop, flamenco, Latin\nItalian pop, flamenco, Latin pop\nItalian pop, flamenco, Mediterranean\nItalian pop, folk pop\nItalian pop, folk pop, dance-pop\nItalian pop, folk, dance\nItalian pop, folk, polka\nItalian pop, folk, theatrical\nItalian pop, folk, waltz\nItalian pop, folk-pop, power ballad\nItalian pop, future bass\nItalian pop, future bass, pop-rap\nItalian pop, gypsy jazz, tango\nItalian pop, hard rock\nItalian pop, hardstyle\nItalian pop, jazz ballad\nItalian pop, jazz fusion\nItalian pop, jazz, Bossa Nova\nItalian pop, jazz, blues\nItalian pop, jazz, bossa nova\nItalian pop, jazz, cabaret\nItalian pop, jazz, canzone\nItalian pop, jazz, lounge\nItalian pop, jazz, soul\nItalian pop, jazz, swing\nItalian pop, latin-pop\nItalian pop, lo-fi hip hop, cinematic\nItalian pop, lo-fi hip-hop\nItalian pop, lo-fi, vintage\nItalian pop, lounge jazz\nItalian pop, lounge jazz, cinematic\nItalian pop, lounge, Latin\nItalian pop, lounge, jazz\nItalian pop, lounge, operatic pop\nItalian pop, lounge, smooth jazz\nItalian pop, mambo\nItalian pop, mambo, Latin\nItalian pop, mambo, big band\nItalian pop, mambo, cha-cha-chá\nItalian pop, mambo, exotica\nItalian pop, mambo, lounge\nItalian pop, mambo, surf rock\nItalian pop, mambo, swing\nItalian pop, mambo, theatrical\nItalian pop, neo-soul, jazz-hop\nItalian pop, operatic pop\nItalian pop, operatic pop, cinematic\nItalian pop, operatic pop, cinematic ballad\nItalian pop, operatic pop, theatrical rock\nItalian pop, operatic, cinematic\nItalian pop, operatic, pop-rock\nItalian pop, operatic, theatrical\nItalian pop, orchestral, big band\nItalian pop, orchestral, cinematic\nItalian pop, orchestral, mid-20th century\nItalian pop, polka, marching band\nItalian pop, polka, theatrical\nItalian pop, pop-rock\nItalian pop, pop-rock, arena rock\nItalian pop, pop-rock, cinematic\nItalian pop, pop-rock, power ballad\nItalian pop, power ballad\nItalian pop, power ballad, arena rock\nItalian pop, power ballad, cinematic\nItalian pop, power ballad, pop-rock\nItalian pop, power ballad, theatrical\nItalian pop, progressive pop, art-pop\nItalian pop, psychedelic, theatrical\nItalian pop, reggae, Latin\nItalian pop, reggae, dancehall\nItalian pop, reggaeton\nItalian pop, reggaeton, Latin\nItalian pop, reggaeton, Latin dance\nItalian pop, reggaeton, Latin pop\nItalian pop, reggaeton, Mediterranean\nItalian pop, reggaeton, Middle Eastern\nItalian pop, reggaeton, Neapolitan\nItalian pop, reggaeton, dance\nItalian pop, reggaeton, dancehall\nItalian pop, reggaeton-lite\nItalian pop, retro pop\nItalian pop, retro swing\nItalian pop, retro synth, theatrical\nItalian pop, retro, beach party\nItalian pop, retro, beat music\nItalian pop, retro, big band\nItalian pop, retro, boogie-woogie\nItalian pop, retro, novelty\nItalian pop, retro, schlager\nItalian pop, retro, theatrical\nItalian pop, rock and roll\nItalian pop, rock and roll, swing\nItalian pop, rockabilly\nItalian pop, rockabilly, swing\nItalian pop, rockabilly, vintage pop\nItalian pop, salsa, Latin pop\nItalian pop, salsa, Neapolitan\nItalian pop, samba, bossa nova\nItalian pop, samba, theatrical pop\nItalian pop, show tune\nItalian pop, show tune, big band\nItalian pop, ska, polka\nItalian pop, ska-pop, retro\nItalian pop, smooth jazz\nItalian pop, smooth jazz, Latin\nItalian pop, smooth jazz, R&B\nItalian pop, smooth jazz, lounge\nItalian pop, spaghetti western\nItalian pop, surf rock\nItalian pop, surf rock, mambo\nItalian pop, swing\nItalian pop, swing, big band\nItalian pop, swing, jive\nItalian pop, swing, mambo\nItalian pop, synth-pop, ambient synth\nItalian pop, tango\nItalian pop, tango, Latin\nItalian pop, tango, ballad\nItalian pop, tango, musette\nItalian pop, tango, theatrical\nItalian pop, tango, waltz\nItalian pop, tarantella\nItalian pop, tarantella, dance\nItalian pop, tarantella, theatrical\nItalian pop, tarantella, upbeat\nItalian pop, theatrical pop\nItalian pop, theatrical pop, 80s synth\nItalian pop, theatrical pop, Neapolitan\nItalian pop, theatrical pop, big band\nItalian pop, theatrical pop, chanson\nItalian pop, theatrical pop, cinematic pop\nItalian pop, theatrical pop, folk tango\nItalian pop, theatrical pop, operatic\nItalian pop, theatrical pop, operatic pop\nItalian pop, theatrical pop, polka\nItalian pop, theatrical pop, pop-rock\nItalian pop, theatrical pop, power ballad\nItalian pop, theatrical pop, show tune\nItalian pop, theatrical pop, tarantella\nItalian pop, theatrical pop, vintage film score\nItalian pop, theatrical rock\nItalian pop, theatrical, 80s film score\nItalian pop, theatrical, 80s synth\nItalian pop, theatrical, Neapolitan\nItalian pop, theatrical, big band\nItalian pop, theatrical, big-band\nItalian pop, theatrical, chiptune\nItalian pop, theatrical, cinematic\nItalian pop, theatrical, dramatic\nItalian pop, theatrical, film score\nItalian pop, theatrical, folk tango\nItalian pop, theatrical, lounge\nItalian pop, theatrical, operatic\nItalian pop, theatrical, orchestral\nItalian pop, theatrical, romantic\nItalian pop, theatrical, synth-pop\nItalian pop, theatrical, vintage\nItalian pop, theatrical, vintage film score\nItalian pop, theatrical, waltz\nItalian pop, trap\nItalian pop, trap, R&B\nItalian pop, trap, dark pop\nItalian pop, trap, electronic\nItalian pop, trap, modern\nItalian pop, trip-hop, R&B\nItalian pop, trip-hop, lounge\nItalian pop, vintage big band, swing\nItalian pop, vintage jazz, lounge\nItalian pop, vintage jazz, swing\nItalian pop, vintage mambo\nItalian pop, vintage mambo, big band\nItalian pop, vintage mambo, cha-cha-chá\nItalian pop, vintage swing, rock and roll\nItalian pop, world music, funk\nItalian pop, world music, theatrical\nItalian pop-EDM\nItalian pop-R&B\nItalian pop-dance\nItalian pop-folk\nItalian pop-funk\nItalian pop-house\nItalian pop-jazz\nItalian pop-punk\nItalian pop-rap\nItalian pop-rap ambient\nItalian pop-rap reggaeton\nItalian pop-rap trap\nItalian pop-rap tropical house\nItalian pop-rap, hyperpop\nItalian pop-reggae\nItalian pop-reggaeton\nItalian pop-rock\nItalian pop-rock bossa nova\nItalian pop-rock cabaret\nItalian pop-rock chiptune\nItalian pop-rock funk\nItalian pop-rock jazz fusion\nItalian pop-rock reggae\nItalian pop-rock ska\nItalian pop-rock, 80s new wave\nItalian pop-rock, Italo-disco\nItalian pop-rock, J-pop\nItalian pop-rock, J-rock\nItalian pop-rock, Latin funk\nItalian pop-rock, Latin pop, psychedelic rock\nItalian pop-rock, Latin, theatrical\nItalian pop-rock, Middle Eastern fusion\nItalian pop-rock, chiptune, funk\nItalian pop-rock, disco-funk\nItalian pop-rock, funk, Latin\nItalian pop-rock, hardstyle\nItalian pop-rock, hardstyle, big room house\nItalian pop-rock, hyperpop, electronic\nItalian pop-rock, melancholic ballad\nItalian pop-rock, noise-rock\nItalian pop-rock, power ballad, choral\nItalian pop-rock, progressive rock\nItalian pop-rock, punk rock\nItalian pop-rock, rockabilly\nItalian pop-rock, ska, upbeat\nItalian pop-rock, smooth jazz\nItalian pop-rock, tango, theatrical\nItalian pop-rock, theatrical, Eastern European folk\nItalian pop-rock, world music\nItalian pop-rock, world music, funk\nItalian pop-samba\nItalian pop-trap\nItalian popular\nItalian popular song\nItalian power ballad\nItalian protest\nItalian protest folk\nItalian protest song\nItalian protest, theatrical, cabaret\nItalian psychedelic rock\nItalian punk rock\nItalian rap\nItalian rap, Middle Eastern fusion, electronic\nItalian rap, chiptune, cumbia\nItalian rap, chiptune, electronic\nItalian rap, electronic, chiptune\nItalian rap, electronic, hardcore\nItalian rap, melodic rock, chiptune\nItalian rap, trap, tribal\nItalian reggae-pop\nItalian rock\nItalian rock and roll\nItalian rock ballad\nItalian rock cabaret\nItalian rock cabaret ska\nItalian rock country-rock\nItalian rock folk-rock\nItalian rock funk psychedelic\nItalian rock funk reggae\nItalian rock opera\nItalian rock power-pop\nItalian rock tango\nItalian rock, 80s new wave\nItalian rock, Latin mambo, free jazz\nItalian rock, Latin rock\nItalian rock, boogie-woogie, Latin rock\nItalian rock, cabaret, theatrical rock\nItalian rock, new wave, ska\nItalian rock, post-punk, dream-pop\nItalian rock, post-rock, cinematic\nItalian rock, ska, Latin rock\nItalian rock, ska, folk-punk\nItalian rock, ska, live energy\nItalian rock, ska, rockabilly\nItalian rock, ska, swing\nItalian rock, ska-punk\nItalian rock, ska-punk, surf rock\nItalian rock, surf rock, garage rock\nItalian rock, surf rock, rockabilly\nItalian rock, surf rock, ska\nItalian rock, tango, theatrical rock\nItalian romance\nItalian romantic\nItalian romantic ballad\nItalian rumba\nItalian singer-songwriter\nItalian singer-songwriter, blues, lounge-jazz\nItalian singer-songwriter, classic rock, ambient\nItalian singer-songwriter, hard rock\nItalian singer-songwriter, jazz, acoustic\nItalian ska\nItalian ska-funk\nItalian ska-pop\nItalian ska-punk\nItalian ska-reggae\nItalian soul\nItalian soul-jazz\nItalian soul-pop\nItalian soul-rock\nItalian sports anthem\nItalian summer pop\nItalian swing\nItalian swing exotica\nItalian swing gypsy jazz\nItalian swing jazz\nItalian swing rock\nItalian swing-pop\nItalian swing-rap\nItalian swing-rock\nItalian synth-pop\nItalian tango\nItalian theatrical\nItalian torch song\nItalian trap\nItalian trap R&B\nItalian trap hip-hop\nItalian trap, Latin pop\nItalian trap, chiptune\nItalian trap, chiptune, meme rap\nItalian trap, cloud rap\nItalian trap, cloud rap, chiptune\nItalian trap, cloud rap, emo-rap\nItalian trap, cloud rap, hyperpop\nItalian trap, drill, ambient\nItalian trap, emo rap, lo-fi\nItalian trap, emo-rap\nItalian trap, emo-trap\nItalian trap, hard dance\nItalian trap, hard trap, phonk\nItalian trap, hardstyle\nItalian trap, hardstyle, EDM\nItalian trap, hyperpop\nItalian trap, lo-fi hip hop\nItalian trap, lo-fi, vaporwave\nItalian trap, phonk\nItalian trap, synth-pop\nItalian trap-R&B\nItalian trap-pop\nItalian trap-soul\nItalian twist\nItalian waltz\nItalian waltz big band\nItalian-American ballad\nItalian-American crooner\nItalian-American folk\nItalian-American polka\nItalian-American pop\nItalian-American theatrical\nItalian-Brazilian pop\nItalo Dance\nItalo beat\nItalo children's\nItalo children's pop\nItalo children's, Balkan pop, Middle Eastern electronic\nItalo dance\nItalo dance Eurodance\nItalo dance chiptune\nItalo dance progressive trance\nItalo dance, Eurodance\nItalo dance, chiptune, J-pop\nItalo dance, chiptune, happy hardcore\nItalo dance, cinematic, Eurodance\nItalo dance, cinematic, ambient\nItalo dance, happy hardcore\nItalo dance, pop-rock\nItalo dance-pop\nItalo disco\nItalo disco Eurodance\nItalo disco chiptune\nItalo disco electro-funk\nItalo disco funk\nItalo disco funk-pop\nItalo disco house\nItalo disco hyperpop\nItalo disco nu-disco\nItalo disco power metal\nItalo disco revival\nItalo disco rock\nItalo disco ska-punk Balkan folk\nItalo disco synth-funk\nItalo disco synth-pop\nItalo disco, Balkan pop\nItalo disco, Eurobeat\nItalo disco, Eurobeat, arcade\nItalo disco, Eurobeat, synthwave\nItalo disco, Eurobeat, video game music\nItalo disco, Eurodance\nItalo disco, Eurodance, Eastern European pop\nItalo disco, Eurodance, Polish pop\nItalo disco, Eurodance, ambient\nItalo disco, Eurodance, chiptune\nItalo disco, Eurodance, retro-futuristic\nItalo disco, Europop, schlager\nItalo disco, French synth-pop\nItalo disco, Hi-NRG\nItalo disco, Hi-NRG, dance-pop\nItalo disco, Hi-NRG, early house\nItalo disco, K-pop, retro-futuristic\nItalo disco, Polish pop\nItalo disco, chiptune, Polish pop\nItalo disco, cinematic, orchestral\nItalo disco, city pop, retro-futuristic\nItalo disco, dance-pop\nItalo disco, disco polo\nItalo disco, early house, electronic dance\nItalo disco, electro-funk\nItalo disco, flamenco pop, 80s synth-pop\nItalo disco, hard rock\nItalo disco, hip-house\nItalo disco, house, retro dance\nItalo disco, novelty, tropical\nItalo disco, retro-futuristic, dance-pop\nItalo disco, schlager\nItalo disco, synth-funk\nItalo disco, synth-pop\nItalo disco, synth-pop, Hi-NRG\nItalo disco, synth-pop, Latin funk\nItalo disco, synth-pop, cinematic\nItalo disco, synth-pop, glam rock\nItalo disco, synth-pop, retro-futuristic\nItalo disco, synth-pop, rock\nItalo disco, synth-pop, video game soundtrack\nItalo disco, synth-pop, world fusion\nItalo funk\nItalo house\nItalo house nu-disco\nItalo new wave\nItalo pop\nItalo pop funk\nItalo pop reggae\nItalo pop rock\nItalo pop, Balkan fusion, Middle Eastern pop\nItalo pop, Eurodance\nItalo pop, J-pop\nItalo pop, Middle Eastern dance\nItalo pop, Middle Eastern fusion\nItalo pop, R&B, dance\nItalo pop, electronic dance, hard rock\nItalo pop, jazz funk, synth-pop\nItalo pop, power ballad, synthwave\nItalo pop, synth-pop\nItalo pop-funk\nItalo pop-rock\nItalo pop-rock, Middle Eastern fusion\nItalo pop-rock, synth-pop\nItalo power ballad\nItalo rock\nItalo-dance\nItalo-dance Latin\nItalo-dance folk\nItalo-dance house\nItalo-dance pop\nItalo-dance reggaeton Neapolitan\nItalo-dance, Eurodance, children's music\nItalo-disco\nItalo-disco Balkan pop\nItalo-disco Euro-pop\nItalo-disco Eurobeat\nItalo-disco Eurodance\nItalo-disco Hi-NRG\nItalo-disco Latin\nItalo-disco Latin pop\nItalo-disco Neapolitan pop\nItalo-disco Soviet synth-pop\nItalo-disco art-pop\nItalo-disco children's\nItalo-disco children's music\nItalo-disco children's pop\nItalo-disco chiptune\nItalo-disco cinematic\nItalo-disco dance-pop\nItalo-disco dream pop\nItalo-disco electro-pop\nItalo-disco flamenco\nItalo-disco freestyle\nItalo-disco funk\nItalo-disco funk synth-pop\nItalo-disco funk-pop\nItalo-disco funk-rap\nItalo-disco funk-rock\nItalo-disco hip-hop\nItalo-disco hip-house\nItalo-disco house\nItalo-disco hyperpop\nItalo-disco kids\nItalo-disco lo-fi\nItalo-disco nu-disco\nItalo-disco orchestral\nItalo-disco pop-rock\nItalo-disco progressive house\nItalo-disco protest\nItalo-disco psychedelic\nItalo-disco punk\nItalo-disco rock\nItalo-disco surf rock\nItalo-disco synth-funk\nItalo-disco synth-pop\nItalo-disco synth-rock\nItalo-disco synthwave\nItalo-disco tango\nItalo-disco tropical\nItalo-disco, Arabic pop, electronic\nItalo-disco, EBM, cinematic\nItalo-disco, Euro-pop\nItalo-disco, Euro-pop, cinematic\nItalo-disco, Eurobeat\nItalo-disco, Eurobeat, synthwave\nItalo-disco, Eurodance, children's music\nItalo-disco, Eurodance, cinematic\nItalo-disco, Eurodance, reggaeton\nItalo-disco, Eurodance, rock\nItalo-disco, Eurodance, sentimental ballad\nItalo-disco, Eurodance, synthwave\nItalo-disco, Hi-NRG\nItalo-disco, Hi-NRG, Eurobeat\nItalo-disco, Hi-NRG, synth-pop\nItalo-disco, Italian pop, cinematic\nItalo-disco, Italian pop, folk\nItalo-disco, Latin pop, Eurodance\nItalo-disco, Latin pop, Italian disco\nItalo-disco, Middle Eastern, anthemic\nItalo-disco, Middle Eastern, electronic\nItalo-disco, Neapolitan pop\nItalo-disco, North African pop\nItalo-disco, Persian pop\nItalo-disco, Persian pop, 80s\nItalo-disco, Russian pop\nItalo-disco, Schlager\nItalo-disco, Soviet synth-pop\nItalo-disco, Turkish pop\nItalo-disco, a cappella, pop\nItalo-disco, children's pop, retro\nItalo-disco, chiptune\nItalo-disco, chiptune, children's music\nItalo-disco, cinematic\nItalo-disco, cinematic synth, 80s movie soundtrack\nItalo-disco, cinematic synth, Hebrew pop\nItalo-disco, cinematic synth, epic\nItalo-disco, cinematic synth, orchestral\nItalo-disco, cinematic synth, retro-futuristic\nItalo-disco, cinematic synth, synth-pop\nItalo-disco, cinematic, 80s synth\nItalo-disco, cinematic, C-pop\nItalo-disco, cinematic, Neapolitan\nItalo-disco, cinematic, cabaret\nItalo-disco, cinematic, chanson\nItalo-disco, cinematic, epic\nItalo-disco, cinematic, operatic\nItalo-disco, cinematic, orchestral\nItalo-disco, cinematic, synthwave\nItalo-disco, cinematic, theatrical\nItalo-disco, classical crossover\nItalo-disco, classical, tango\nItalo-disco, cumbia\nItalo-disco, dance-pop, cinematic\nItalo-disco, dance-pop, pop-rock\nItalo-disco, early house, retro synth\nItalo-disco, early house, retro-electronic\nItalo-disco, electro, retro-futuristic\nItalo-disco, electronic, dance-pop\nItalo-disco, folk pop, theatrical\nItalo-disco, hard rock\nItalo-disco, house, retro-futuristic\nItalo-disco, lo-fi, Eurodance\nItalo-disco, mambo, summer pop\nItalo-disco, new jack swing\nItalo-disco, new wave\nItalo-disco, new wave, pop-rock\nItalo-disco, novelty pop, Italian pop\nItalo-disco, polka, novelty\nItalo-disco, pop, big band\nItalo-disco, pop-rock, ballad\nItalo-disco, retro-futuristic, chiptune\nItalo-disco, retrowave, synthwave\nItalo-disco, schlager\nItalo-disco, schlager, novelty\nItalo-disco, smooth jazz\nItalo-disco, synth-orchestral, power-pop\nItalo-disco, synth-pop\nItalo-disco, synth-pop, 80s\nItalo-disco, synth-pop, Arabic electronic\nItalo-disco, synth-pop, Arabic folk\nItalo-disco, synth-pop, Arabic fusion\nItalo-disco, synth-pop, Eurodance\nItalo-disco, synth-pop, German rap\nItalo-disco, synth-pop, Hi-NRG\nItalo-disco, synth-pop, Indian film music\nItalo-disco, synth-pop, Middle Eastern\nItalo-disco, synth-pop, Middle Eastern fusion\nItalo-disco, synth-pop, Persian electronic\nItalo-disco, synth-pop, Turkish fusion\nItalo-disco, synth-pop, cinematic\nItalo-disco, synth-pop, funk-pop\nItalo-disco, synth-pop, operatic\nItalo-disco, synth-pop, retro-futuristic\nItalo-disco, synth-pop, smooth jazz\nItalo-disco, theatrical pop\nItalo-funk\nItalo-funk dance-pop\nItalo-funk pop-rock\nItalo-pop\nItalo-pop Europop\nItalo-pop J-pop\nItalo-pop children's\nItalo-pop, Latin fusion, rock\nItalo-reggaeton\nItalo-rock\nJ-Core\nJ-Folk\nJ-Hip Hop\nJ-Hip Hop, Latin Pop\nJ-Hip-Hop\nJ-Pop\nJ-Pop Anisong\nJ-Pop Bossa Nova\nJ-Pop Christmas\nJ-Pop City Pop\nJ-Pop City Pop AOR\nJ-Pop City Pop Funk\nJ-Pop City Pop Jazz-Funk\nJ-Pop City Pop R&B\nJ-Pop City Pop funk\nJ-Pop City Pop smooth jazz\nJ-Pop EDM\nJ-Pop Eurobeat\nJ-Pop J-Rock\nJ-Pop J-Rock Anisong\nJ-Pop K-Pop fusion\nJ-Pop Latin\nJ-Pop Latin fusion\nJ-Pop Neo-Soul\nJ-Pop Neo-Soul R&B\nJ-Pop R&B\nJ-Pop R&B Bossa Nova\nJ-Pop R&B Neo-Soul\nJ-Pop R&B ballad\nJ-Pop R&B chillwave\nJ-Pop R&B chiptune\nJ-Pop R&B cinematic\nJ-Pop R&B city pop\nJ-Pop R&B city-pop\nJ-Pop R&B crossover\nJ-Pop R&B funk\nJ-Pop R&B fusion\nJ-Pop R&B gospel\nJ-Pop R&B hip-hop\nJ-Pop R&B jazz\nJ-Pop R&B lo-fi\nJ-Pop R&B lo-fi hip-hop\nJ-Pop R&B neo-soul\nJ-Pop R&B soul\nJ-Pop R&B trap\nJ-Pop anime theme\nJ-Pop ballad\nJ-Pop cinematic\nJ-Pop city pop\nJ-Pop city pop funk\nJ-Pop city pop lo-fi hip-hop\nJ-Pop dance-pop Eurobeat\nJ-Pop dance-pop R&B\nJ-Pop dancehall reggaeton\nJ-Pop funk\nJ-Pop funk R&B\nJ-Pop funk rock\nJ-Pop funk-rock\nJ-Pop future bass\nJ-Pop future bass EDM\nJ-Pop gospel\nJ-Pop hip-hop\nJ-Pop lo-fi hip-hop\nJ-Pop neo-soul\nJ-Pop pop-rock\nJ-Pop power ballad\nJ-Pop rock\nJ-Pop synth-pop dance-pop\nJ-Pop trap\nJ-Pop trap R&B\nJ-Pop trap-R&B\nJ-Pop, Anisong\nJ-Pop, Contemporary Christian Music\nJ-Pop, EDM, Trance\nJ-Pop, EDM, ballad\nJ-Pop, EDM, cinematic\nJ-Pop, EDM, dance-pop\nJ-Pop, EDM, future bass\nJ-Pop, Eurobeat, Trance\nJ-Pop, J-Rock\nJ-Pop, J-Rock, EDM\nJ-Pop, J-Rock, hip-hop\nJ-Pop, Latin pop\nJ-Pop, Latin, R&B\nJ-Pop, New Jack Swing, R&B\nJ-Pop, R&B\nJ-Pop, R&B, 2000s\nJ-Pop, R&B, Christmas\nJ-Pop, R&B, City Pop\nJ-Pop, R&B, New Jack Swing\nJ-Pop, R&B, city pop\nJ-Pop, R&B, dance-pop\nJ-Pop, R&B, festive\nJ-Pop, R&B, funk\nJ-Pop, R&B, gospel\nJ-Pop, R&B, hip-hop\nJ-Pop, R&B, lo-fi hip-hop\nJ-Pop, R&B, neo-soul\nJ-Pop, R&B, pop-rap\nJ-Pop, R&B, pop-rock\nJ-Pop, R&B, soul\nJ-Pop, R&B, synth-pop\nJ-Pop, R&B, trap\nJ-Pop, city pop, R&B\nJ-Pop, city pop, funk\nJ-Pop, city pop, synth-pop\nJ-Pop, funk, R&B\nJ-Pop, funk, city pop\nJ-Pop, funk, rock\nJ-Pop, hip-hop, R&B\nJ-Pop, neo-soul, R&B\nJ-Pop, neo-soul, city pop\nJ-Pop, pop-rock\nJ-Pop, synth-pop, city pop\nJ-R&B\nJ-R&B cinematic\nJ-R&B city pop\nJ-R&B city pop funk\nJ-R&B dancehall\nJ-R&B deep house afrobeat\nJ-R&B electronic pop\nJ-R&B future bass\nJ-R&B hip hop\nJ-R&B hip-hop\nJ-R&B lo-fi hip hop\nJ-R&B lo-fi hip-hop\nJ-R&B lo-fi trap\nJ-R&B pop-rock\nJ-R&B trap\nJ-R&B trap-soul\nJ-R&B, hip-hop\nJ-R&B, trap, vaporwave\nJ-R&B, trap-soul, ambient\nJ-RPG\nJ-RPG ambient\nJ-RPG ballad\nJ-RPG battle theme\nJ-RPG music\nJ-RPG orchestral\nJ-RPG soundtrack\nJ-RPG soundtrack progressive rock\nJ-RPG synth\nJ-Rap\nJ-Rap chiptune trap\nJ-Rap funk\nJ-Rap lo-fi\nJ-Rap trap\nJ-Rap, cinematic hip-hop, boom-bap\nJ-Rap, cyberpunk, electronic\nJ-Rap, trap, melodic\nJ-Rap, trap, orchestral\nJ-Rock\nJ-Rock Anisong\nJ-Rock Anisong cinematic\nJ-Rock Balkan folk\nJ-Rock C-Pop\nJ-Rock C-Pop rock\nJ-Rock C-Rock\nJ-Rock City Pop AOR\nJ-Rock City Pop funk\nJ-Rock Dancehall\nJ-Rock Funk-Pop\nJ-Rock Funk-Rock\nJ-Rock J-Hip-Hop\nJ-Rock J-Pop\nJ-Rock J-Pop electronic\nJ-Rock J-Pop fusion\nJ-Rock J-Rap\nJ-Rock J-Rap cinematic\nJ-Rock K-Pop rock\nJ-Rock K-Rock\nJ-Rock Latin fusion\nJ-Rock Pop-Pop\nJ-Rock Pop-Punk\nJ-Rock Pop-Rock\nJ-Rock R&B\nJ-Rock R&B fusion\nJ-Rock anime\nJ-Rock anime opening\nJ-Rock anime rock\nJ-Rock anime theme\nJ-Rock anison\nJ-Rock anisong\nJ-Rock anisong chiptune\nJ-Rock anisong cinematic\nJ-Rock ballad\nJ-Rock chiptune\nJ-Rock chiptune anime\nJ-Rock cinematic\nJ-Rock city pop\nJ-Rock electronic\nJ-Rock electronic hip-hop\nJ-Rock electronicore\nJ-Rock flamenco\nJ-Rock funk\nJ-Rock funk anime\nJ-Rock funk city pop\nJ-Rock funk disco\nJ-Rock funk electronic\nJ-Rock funk hip-hop\nJ-Rock funk jazz fusion\nJ-Rock funk pop\nJ-Rock funk ska\nJ-Rock funk-rock\nJ-Rock hip hop\nJ-Rock hip-hop\nJ-Rock hip-hop crossover\nJ-Rock hip-hop fusion\nJ-Rock nu-metal\nJ-Rock orchestral\nJ-Rock pop\nJ-Rock pop-punk\nJ-Rock pop-punk rap-rock\nJ-Rock power ballad\nJ-Rock power metal\nJ-Rock power metal chiptune\nJ-Rock power-pop\nJ-Rock progressive metal\nJ-Rock rap-rock\nJ-Rock ska-punk\nJ-Rock symphonic\nJ-Rock trap\nJ-Rock trap metal\nJ-Rock, Anisong\nJ-Rock, Anisong, City Pop\nJ-Rock, Anisong, Eurobeat\nJ-Rock, Anisong, Japanese rock\nJ-Rock, Anisong, chiptune\nJ-Rock, Anisong, funk\nJ-Rock, Anisong, hyperpop\nJ-Rock, Anisong, jazz fusion\nJ-Rock, Anisong, pop-punk\nJ-Rock, Anisong, ska-punk\nJ-Rock, C-Pop rock\nJ-Rock, Celtic folk, folk-rock\nJ-Rock, City Pop, funk\nJ-Rock, EDM\nJ-Rock, Japanese Hip-Hop\nJ-Rock, Pop-Punk\nJ-Rock, cinematic rock\nJ-Rock, cinematic rock, video game soundtrack\nJ-Rock, cinematic, Anisong\nJ-Rock, cinematic, orchestral\nJ-Rock, cinematic, pop-rock\nJ-Rock, city pop, funk\nJ-Rock, electronic dance, trance\nJ-Rock, funk, nu-metal\nJ-Rock, nu-metal\nJ-Rock, orchestral, anime theme\nJ-Rock, pop-rock, metalcore\nJ-ballad\nJ-core\nJ-core C-pop fusion\nJ-core Eurobeat\nJ-core Eurodance\nJ-core UK garage\nJ-core Vocaloid\nJ-core artcore\nJ-core artcore drum and bass\nJ-core artcore gabber\nJ-core artcore hardstyle\nJ-core breakcore\nJ-core breakcore chiptune\nJ-core chiptune\nJ-core chiptune artcore\nJ-core chiptune breakcore\nJ-core chiptune gabber\nJ-core chiptune happy hardcore\nJ-core chiptune hardcore techno\nJ-core chiptune metalcore\nJ-core chiptune pop\nJ-core chiptune pop-rock\nJ-core chiptune rock\nJ-core chiptune symphonic electronic\nJ-core chiptune trance\nJ-core chiptune trancecore\nJ-core cyberpop\nJ-core denpa\nJ-core denpa gabber\nJ-core denpa-kei\nJ-core drum and bass\nJ-core dubstep\nJ-core electronic\nJ-core electronic rock\nJ-core emotional trance\nJ-core future bass\nJ-core gabber\nJ-core gabber denpa\nJ-core gabber happy hardcore\nJ-core happy hardcore\nJ-core hard trance\nJ-core hardcore\nJ-core hardcore artcore\nJ-core hardcore techno\nJ-core hardstyle\nJ-core hardstyle trap\nJ-core hip-hop\nJ-core hyperpop\nJ-core hyperpop artcore\nJ-core hyperpop breakcore\nJ-core hyperpop chiptune\nJ-core hyperpop denpa\nJ-core hyperpop drum and bass\nJ-core hyperpop hardcore techno\nJ-core hyperpop speedcore\nJ-core hyperpop trance\nJ-core metalcore\nJ-core metalcore chiptune\nJ-core nightcore\nJ-core orchestral\nJ-core orchestral trance\nJ-core power metal\nJ-core power metal chiptune\nJ-core rap-rock\nJ-core reggaeton\nJ-core speedcore\nJ-core speedcore artcore\nJ-core speedcore chiptune\nJ-core speedcore denpa\nJ-core speedcore dubstep\nJ-core speedcore glitchcore\nJ-core speedcore hyperpop\nJ-core speedcore metalcore\nJ-core symphonic trance\nJ-core symphonic trancecore\nJ-core trance\nJ-core trance chiptune\nJ-core trance hardcore techno\nJ-core trance metalcore\nJ-core trance-pop\nJ-core trancecore\nJ-core trancecore chiptune\nJ-core trap\nJ-core trap hyperpop\nJ-core, C-core, happy hardcore\nJ-core, C-pop, happy hardcore\nJ-core, Chinese electronic\nJ-core, Chinese electronic, happy hardcore\nJ-core, Chinese fusion, happy hardcore\nJ-core, Chinese-style, happy hardcore\nJ-core, UK garage\nJ-core, UK garage, breakbeat\nJ-core, UK hardcore\nJ-core, UK hardcore, electronic\nJ-core, Vocaloid, glitch\nJ-core, Vocaloid, happy hardcore\nJ-core, Vocaloid, hardstyle\nJ-core, anime electronic\nJ-core, anime-style electronic\nJ-core, artcore, C-pop\nJ-core, artcore, Mandopop\nJ-core, artcore, ambient\nJ-core, artcore, chiptune\nJ-core, artcore, cinematic\nJ-core, artcore, cinematic electronic\nJ-core, artcore, complextro\nJ-core, artcore, drum and bass\nJ-core, artcore, dubstep\nJ-core, artcore, electronic\nJ-core, artcore, hardstyle\nJ-core, breakbeat, video game music\nJ-core, breakcore, Vocaloid\nJ-core, breakcore, chiptune\nJ-core, breakcore, denpa\nJ-core, breakcore, hyper-pop\nJ-core, brostep, electronic\nJ-core, chillhop\nJ-core, chiptune\nJ-core, chiptune pop\nJ-core, chiptune, Vocaloid\nJ-core, chiptune, artcore\nJ-core, chiptune, breakbeat\nJ-core, chiptune, breakcore\nJ-core, chiptune, complextro\nJ-core, chiptune, denpa-kei\nJ-core, chiptune, electronic\nJ-core, chiptune, gabber\nJ-core, chiptune, happy hardcore\nJ-core, chiptune, hardcore\nJ-core, chiptune, hardcore techno\nJ-core, chiptune, hardstyle\nJ-core, chiptune, hyperpop\nJ-core, chiptune, metalcore\nJ-core, chiptune, neurofunk\nJ-core, chiptune, orchestral\nJ-core, chiptune, speedcore\nJ-core, chiptune, symphonic electronic\nJ-core, chiptune, trance\nJ-core, cinematic, denpa-kei\nJ-core, cinematic, electronic\nJ-core, cinematic, happy hardcore\nJ-core, cinematic, orchestral\nJ-core, cinematic, trance\nJ-core, classical piano, trance\nJ-core, denpa\nJ-core, denpa, artcore\nJ-core, denpa, chiptune\nJ-core, denpa, happy hardcore\nJ-core, denpa, speedcore\nJ-core, denpa-kei, hardcore techno\nJ-core, denpa-kei, hyperpop\nJ-core, drum and bass, chiptune\nJ-core, drum and bass, dubstep\nJ-core, dubstep, hardstyle\nJ-core, electronic dance, lo-fi hip hop\nJ-core, electronic, C-pop\nJ-core, electronic, Chinese fusion\nJ-core, electronic, cinematic\nJ-core, electronic, denpa-kei\nJ-core, future bass, hardcore techno\nJ-core, gabber, Vocaloid\nJ-core, gabber, anime\nJ-core, gabber, breakcore\nJ-core, gabber, chiptune\nJ-core, gabber, cinematic\nJ-core, gabber, denpa\nJ-core, gabber, denpa-kei\nJ-core, gabber, happy hardcore\nJ-core, gabber, hardcore\nJ-core, gabber, hardcore techno\nJ-core, gabber, hardstyle\nJ-core, gabber, hyperpop\nJ-core, gabber, speedcore\nJ-core, hands-up trance, electronic\nJ-core, happy hardcore\nJ-core, happy hardcore, C-core\nJ-core, happy hardcore, C-pop\nJ-core, happy hardcore, Chinese electronic\nJ-core, happy hardcore, Chinese fusion\nJ-core, happy hardcore, East Asian melodic\nJ-core, happy hardcore, Eurobeat\nJ-core, happy hardcore, J-rock\nJ-core, happy hardcore, K-pop\nJ-core, happy hardcore, Mandarin pop\nJ-core, happy hardcore, Mandarin rap\nJ-core, happy hardcore, Mandopop\nJ-core, happy hardcore, UK Hardcore\nJ-core, happy hardcore, UK hardcore\nJ-core, happy hardcore, Vocaloid\nJ-core, happy hardcore, ambient\nJ-core, happy hardcore, ambient ballad\nJ-core, happy hardcore, anime soundtrack\nJ-core, happy hardcore, anime theme\nJ-core, happy hardcore, artcore\nJ-core, happy hardcore, baroque\nJ-core, happy hardcore, breakbeat\nJ-core, happy hardcore, breakcore\nJ-core, happy hardcore, chipbeat\nJ-core, happy hardcore, chiptune\nJ-core, happy hardcore, cinematic\nJ-core, happy hardcore, cinematic piano\nJ-core, happy hardcore, classical fusion\nJ-core, happy hardcore, comedy rap\nJ-core, happy hardcore, complextro\nJ-core, happy hardcore, denpa\nJ-core, happy hardcore, denpa-kei\nJ-core, happy hardcore, drum and bass\nJ-core, happy hardcore, dubstep\nJ-core, happy hardcore, electro-metal\nJ-core, happy hardcore, electronic\nJ-core, happy hardcore, electronic dance\nJ-core, happy hardcore, funk-rock\nJ-core, happy hardcore, future bass\nJ-core, happy hardcore, gabber\nJ-core, happy hardcore, glitch\nJ-core, happy hardcore, gospel rap\nJ-core, happy hardcore, hardstyle\nJ-core, happy hardcore, heavy metal\nJ-core, happy hardcore, hyper-pop\nJ-core, happy hardcore, hyperpop\nJ-core, happy hardcore, kawaii future bass\nJ-core, happy hardcore, lo-fi\nJ-core, happy hardcore, nightcore\nJ-core, happy hardcore, power metal\nJ-core, happy hardcore, rap\nJ-core, happy hardcore, rave\nJ-core, happy hardcore, rhythm game\nJ-core, happy hardcore, speedcore\nJ-core, happy hardcore, symphonic electronic\nJ-core, happy hardcore, symphonic metal\nJ-core, happy hardcore, symphonic rock\nJ-core, happy hardcore, symphonic trance\nJ-core, happy hardcore, traditional East Asian\nJ-core, happy hardcore, trance\nJ-core, happy hardcore, trance-pop\nJ-core, happy hardcore, trancecore\nJ-core, happy hardcore, trap\nJ-core, happy hardcore, video game\nJ-core, happy hardcore, video game music\nJ-core, hard trance, artcore\nJ-core, hardcore techno\nJ-core, hardcore techno, Vocaloid\nJ-core, hardcore techno, anime\nJ-core, hardcore techno, anime theme\nJ-core, hardcore techno, anison\nJ-core, hardcore techno, artcore\nJ-core, hardcore techno, chiptune\nJ-core, hardcore techno, denpa\nJ-core, hardcore techno, electronic\nJ-core, hardcore techno, gabber\nJ-core, hardcore techno, hardstyle\nJ-core, hardcore techno, hyperpop\nJ-core, hardcore techno, trance\nJ-core, hardcore, electronic\nJ-core, hardcore, gabber\nJ-core, hardcore, glitch\nJ-core, hardcore, trance\nJ-core, hardstyle\nJ-core, hardstyle, C-pop\nJ-core, hardstyle, EDM\nJ-core, hardstyle, Vocaloid\nJ-core, hardstyle, artcore\nJ-core, hardstyle, chiptune\nJ-core, hardstyle, cinematic\nJ-core, hardstyle, complextro\nJ-core, hardstyle, denpa-kei\nJ-core, hardstyle, dubstep\nJ-core, hardstyle, electronic\nJ-core, hardstyle, future bass\nJ-core, hardstyle, gabber\nJ-core, hardstyle, happy hardcore\nJ-core, hardstyle, hyperpop\nJ-core, hardstyle, kawaii-pop\nJ-core, hardstyle, orchestral\nJ-core, hardstyle, speedcore\nJ-core, hardstyle, trance\nJ-core, hyper-pop, chiptune\nJ-core, hyper-pop, hardcore\nJ-core, hyperpop\nJ-core, hyperpop, Vocaloid\nJ-core, hyperpop, anime\nJ-core, hyperpop, ballad\nJ-core, hyperpop, breakbeat\nJ-core, hyperpop, chiptune\nJ-core, hyperpop, denpa\nJ-core, hyperpop, denpa-kei\nJ-core, hyperpop, drum and bass\nJ-core, hyperpop, electronic\nJ-core, hyperpop, gabber\nJ-core, hyperpop, glitch\nJ-core, hyperpop, happy hardcore\nJ-core, hyperpop, hardcore techno\nJ-core, hyperpop, hardstyle\nJ-core, hyperpop, trap\nJ-core, melodic trance, hardcore\nJ-core, nightcore, denpa\nJ-core, nightcore, electronic dance\nJ-core, nightcore, happy hardcore\nJ-core, nightcore, hardstyle\nJ-core, orchestral, gabber\nJ-core, speedcore\nJ-core, speedcore, Vocaloid\nJ-core, speedcore, chiptune\nJ-core, speedcore, denpa\nJ-core, speedcore, denpa-kei\nJ-core, speedcore, dubstep\nJ-core, speedcore, gabber\nJ-core, speedcore, happy hardcore\nJ-core, speedcore, hyperpop\nJ-core, speedcore, trance\nJ-core, symphonic electronica, video game music\nJ-core, symphonic rock, chiptune\nJ-core, trance\nJ-core, trance, C-pop\nJ-core, trance, UK Hardcore\nJ-core, trance, artcore\nJ-core, trance, chiptune\nJ-core, trance, electronic\nJ-core, trance, happy hardcore\nJ-core, trance, hardcore\nJ-core, trance, hardcore techno\nJ-core, trance, hardstyle\nJ-core, trance, metalcore\nJ-core, trance, symphonic metal\nJ-core, trance, video game music\nJ-core, trancecore\nJ-core, trancecore, chiptune\nJ-core, trap, melodic rap\nJ-core, video game music, electronic\nJ-core, video game music, electronic dance\nJ-dancehall\nJ-folk\nJ-folk Celtic\nJ-funk\nJ-funk R&B\nJ-funk acid jazz\nJ-funk city pop\nJ-funk dance-pop\nJ-funk disco\nJ-funk disco-pop\nJ-funk electro-pop\nJ-funk hip-hop\nJ-funk new jack swing\nJ-funk nu-disco\nJ-funk pop-rap\nJ-funk pop-rock\nJ-funk rock\nJ-funk ska-pop\nJ-funk soul\nJ-funk, city pop, new jack swing\nJ-funk, new jack swing\nJ-funk, nu-disco, city pop\nJ-funk, party hip-hop\nJ-funk, video game music\nJ-hip-hop\nJ-hip-hop G-funk\nJ-hip-hop J-pop\nJ-hip-hop K-pop R&B\nJ-hip-hop R&B\nJ-hip-hop alternative rock\nJ-hip-hop boom-bap\nJ-hip-hop chiptune\nJ-hip-hop chiptune pop-rap\nJ-hip-hop chiptune synth-pop\nJ-hip-hop chiptune trap\nJ-hip-hop cinematic\nJ-hip-hop city pop neo-soul\nJ-hip-hop cloud rap\nJ-hip-hop cyberpunk\nJ-hip-hop electronic\nJ-hip-hop emo rap\nJ-hip-hop funk\nJ-hip-hop funk chiptune\nJ-hip-hop funk jazz\nJ-hip-hop funk ska\nJ-hip-hop funk-rock\nJ-hip-hop lo-fi\nJ-hip-hop lo-fi pop-rap\nJ-hip-hop lo-fi trap\nJ-hip-hop neo-soul\nJ-hip-hop pop\nJ-hip-hop pop-rap\nJ-hip-hop pop-rock\nJ-hip-hop rap-rock\nJ-hip-hop trap\nJ-hip-hop trap R&B\nJ-hip-hop trap chiptune\nJ-hip-hop trap hyperpop\nJ-hip-hop vaporwave\nJ-hip-hop, Christmas trap\nJ-hip-hop, EDM, cinematic\nJ-hip-hop, J-pop\nJ-hip-hop, chiptune, electronic\nJ-hip-hop, cinematic, anime\nJ-hip-hop, cinematic, motivational\nJ-hip-hop, cloud rap\nJ-hip-hop, cloud rap, chiptune\nJ-hip-hop, emotional J-rock\nJ-hip-hop, orchestral, trap\nJ-hip-hop, trap, cinematic\nJ-hope\nJ-hope hip hop\nJ-hope trap\nJ-metal\nJ-metal kawaii metal\nJ-metal melodic metalcore\nJ-metal metalcore\nJ-metal power metal\nJ-metal symphonic metalcore\nJ-metal symphonic power metal\nJ-metalcore, symphonic metal\nJ-pop\nJ-pop 80s\nJ-pop 80s anime\nJ-pop Afrobeats dancehall\nJ-pop Bollywood\nJ-pop Bollywood fusion\nJ-pop Bossa Nova\nJ-pop Bossa Nova Latin jazz\nJ-pop Brazilian pop-rock\nJ-pop C-pop\nJ-pop C-pop Christmas pop\nJ-pop C-pop acoustic pop\nJ-pop C-pop anime\nJ-pop C-pop anime soundtrack\nJ-pop C-pop anime theme\nJ-pop C-pop anthemic\nJ-pop C-pop ballad\nJ-pop C-pop chiptune\nJ-pop C-pop cinematic\nJ-pop C-pop dance-pop\nJ-pop C-pop electronic\nJ-pop C-pop electronic pop-rock\nJ-pop C-pop funk\nJ-pop C-pop fusion\nJ-pop C-pop futuristic\nJ-pop C-pop hyperpop\nJ-pop C-pop idol\nJ-pop C-pop orchestral\nJ-pop C-pop pop-rock\nJ-pop C-pop power ballad\nJ-pop Cantopop\nJ-pop Celtic folk\nJ-pop Christmas\nJ-pop City Pop\nJ-pop City Pop AOR\nJ-pop City Pop Anison\nJ-pop City Pop Anisong\nJ-pop City Pop Eurobeat\nJ-pop City Pop anime\nJ-pop City Pop funk\nJ-pop EDM\nJ-pop EDM J-rock\nJ-pop EDM anison\nJ-pop EDM dance-pop\nJ-pop EDM fusion\nJ-pop EDM hardstyle\nJ-pop EDM hip-hop\nJ-pop EDM rap\nJ-pop EDM rock\nJ-pop EDM trance\nJ-pop EDM-pop\nJ-pop Enka\nJ-pop Eurobeat\nJ-pop Eurobeat Anisong\nJ-pop Eurobeat Trance\nJ-pop Eurobeat dance-pop\nJ-pop Eurobeat trance\nJ-pop Eurodance\nJ-pop J-hip-hop\nJ-pop J-rap\nJ-pop J-rap J-rock\nJ-pop J-rap chiptune\nJ-pop J-rap cinematic\nJ-pop J-rap orchestral\nJ-pop J-rap trap\nJ-pop J-rock\nJ-pop J-rock anison\nJ-pop J-rock chiptune\nJ-pop J-rock cinematic\nJ-pop J-rock hip-hop\nJ-pop J-rock hyperpop\nJ-pop J-rock jazz\nJ-pop J-rock rap-rock\nJ-pop K-pop\nJ-pop K-pop Christmas pop\nJ-pop K-pop EDM\nJ-pop K-pop fusion\nJ-pop K-pop hard rock\nJ-pop K-pop hybrid\nJ-pop K-pop trap\nJ-pop Latin\nJ-pop Latin blues-rock\nJ-pop Latin dance\nJ-pop Latin dance-pop\nJ-pop Latin flamenco\nJ-pop Latin folk\nJ-pop Latin fusion\nJ-pop Latin house\nJ-pop Latin jazz\nJ-pop Latin jazz fusion\nJ-pop Latin jazz salsa\nJ-pop Latin pop\nJ-pop Latin pop salsa\nJ-pop Latin rock\nJ-pop Latin rumba\nJ-pop Latin salsa\nJ-pop Latin tango\nJ-pop Latin tropical\nJ-pop Mandopop\nJ-pop R&B\nJ-pop R&B New Jack Swing\nJ-pop R&B a cappella\nJ-pop R&B ballad\nJ-pop R&B boom-bap\nJ-pop R&B chillwave\nJ-pop R&B chiptune\nJ-pop R&B cinematic\nJ-pop R&B city pop\nJ-pop R&B club\nJ-pop R&B crossover\nJ-pop R&B dance-pop\nJ-pop R&B dancehall-lite\nJ-pop R&B dreamy\nJ-pop R&B early 2000s\nJ-pop R&B electronic\nJ-pop R&B flamenco\nJ-pop R&B funk\nJ-pop R&B fusion\nJ-pop R&B future bass\nJ-pop R&B gospel\nJ-pop R&B hip-hop\nJ-pop R&B jazz\nJ-pop R&B jazz fusion\nJ-pop R&B lo-fi\nJ-pop R&B lo-fi hip-hop\nJ-pop R&B neo-soul\nJ-pop R&B orchestral\nJ-pop R&B pop\nJ-pop R&B pop-rock\nJ-pop R&B trap\nJ-pop T-pop\nJ-pop UK drill\nJ-pop UK garage\nJ-pop V-pop\nJ-pop Vocaloid\nJ-pop a cappella\nJ-pop acid jazz\nJ-pop acid jazz Shibuya-kei\nJ-pop acid jazz hip-hop\nJ-pop acoustic\nJ-pop acoustic ballad\nJ-pop acoustic duet\nJ-pop acoustic pop\nJ-pop acoustic rock\nJ-pop alternative R&B\nJ-pop alternative rock\nJ-pop ambient\nJ-pop anime\nJ-pop anime ballad\nJ-pop anime ballad symphonic rock\nJ-pop anime electronic\nJ-pop anime opening\nJ-pop anime pop\nJ-pop anime pop-rock\nJ-pop anime power ballad\nJ-pop anime power pop\nJ-pop anime power-pop\nJ-pop anime rock\nJ-pop anime soundtrack\nJ-pop anime sports anthem\nJ-pop anime theme\nJ-pop anime-pop\nJ-pop anime-rock\nJ-pop anime-style pop-rock\nJ-pop anison\nJ-pop anison chiptune\nJ-pop anison city pop\nJ-pop anison dance-pop\nJ-pop anison denpa\nJ-pop anison denpa-kei\nJ-pop anison idol pop\nJ-pop anison pop-rock\nJ-pop anison power metal\nJ-pop anison rock\nJ-pop anison ska-punk\nJ-pop anison symphonic rock\nJ-pop anison trance\nJ-pop anisong\nJ-pop anisong symphonic rock\nJ-pop art pop\nJ-pop art pop electronic\nJ-pop art pop future bass\nJ-pop art rock denpa\nJ-pop art rock electronic\nJ-pop art rock symphonic\nJ-pop art-pop\nJ-pop art-pop electronic\nJ-pop art-pop rock\nJ-pop artcore\nJ-pop artcore art rock\nJ-pop artcore breakbeat\nJ-pop artcore breakcore\nJ-pop artcore chiptune\nJ-pop artcore denpa\nJ-pop artcore drum and bass\nJ-pop artcore glitchcore\nJ-pop artcore symphonic rock\nJ-pop artcore trance\nJ-pop ballad\nJ-pop ballad cinematic\nJ-pop ballad, French R&B, funk-pop\nJ-pop ballad, J-rock\nJ-pop ballad, J-rock anthem\nJ-pop ballad, J-rock, cinematic\nJ-pop ballad, J-rock, hip-hop\nJ-pop ballad, J-rock, indie-pop\nJ-pop ballad, J-rock, metalcore\nJ-pop ballad, J-rock, rap\nJ-pop ballad, anime rock\nJ-pop ballad, artcore, ambient\nJ-pop ballad, cinematic rock\nJ-pop ballad, electronic, hyperpop\nJ-pop ballad, emotional rock\nJ-pop ballad, future bass, art-pop\nJ-pop ballad, lo-fi hip-hop\nJ-pop ballad, modern R&B\nJ-pop ballad, orchestral fantasy, anime rock\nJ-pop ballad, pop-rap\nJ-pop ballad, pop-rock\nJ-pop ballad, pop-rock, cinematic\nJ-pop ballad, pop-rock, hip-hop\nJ-pop ballad, pop-rock, hip-hop/trap\nJ-pop ballad, symphonic J-rock\nJ-pop ballad, symphonic metalcore\nJ-pop ballad, symphonic rock\nJ-pop ballad, synth-funk\nJ-pop baroque\nJ-pop bedroom pop\nJ-pop big band\nJ-pop big band fusion\nJ-pop big band jazz\nJ-pop big band ska\nJ-pop big band swing\nJ-pop bluegrass\nJ-pop bluegrass country\nJ-pop bluegrass fusion\nJ-pop blues\nJ-pop boogie-woogie\nJ-pop boom-bap\nJ-pop bossa nova\nJ-pop bossa nova city pop\nJ-pop bossa nova indie pop\nJ-pop bossa nova lounge\nJ-pop breakbeat\nJ-pop breakcore\nJ-pop breakcore chiptune\nJ-pop breakcore jazz fusion\nJ-pop bubblegum dance\nJ-pop bubblegum pop\nJ-pop cabaret\nJ-pop cabaret circus\nJ-pop children's\nJ-pop children's music\nJ-pop children's pop\nJ-pop chillhop\nJ-pop chillhop R&B\nJ-pop chillhop city pop\nJ-pop chillwave\nJ-pop chillwave video game\nJ-pop chiptune\nJ-pop chiptune Latin\nJ-pop chiptune anison\nJ-pop chiptune art-pop\nJ-pop chiptune artcore\nJ-pop chiptune baroque\nJ-pop chiptune city pop\nJ-pop chiptune denpa\nJ-pop chiptune drum and bass\nJ-pop chiptune electro-house\nJ-pop chiptune electronic rock\nJ-pop chiptune electropop\nJ-pop chiptune emo rap\nJ-pop chiptune funk\nJ-pop chiptune funk-pop\nJ-pop chiptune funk-rock\nJ-pop chiptune fusion\nJ-pop chiptune hip-hop\nJ-pop chiptune hyperpop\nJ-pop chiptune jazz-fusion\nJ-pop chiptune lo-fi\nJ-pop chiptune lo-fi hip-hop\nJ-pop chiptune math rock\nJ-pop chiptune orchestral\nJ-pop chiptune pop-rock\nJ-pop chiptune rock\nJ-pop chiptune synth-pop\nJ-pop chiptune trance\nJ-pop chiptune trap\nJ-pop chiptune video game\nJ-pop cinematic\nJ-pop cinematic electronic\nJ-pop cinematic pop\nJ-pop cinematic rock\nJ-pop city pop\nJ-pop city pop AOR\nJ-pop city pop Latin\nJ-pop city pop Latin fusion\nJ-pop city pop Latin jazz\nJ-pop city pop R&B\nJ-pop city pop Shibuya-kei\nJ-pop city pop acid jazz\nJ-pop city pop anime\nJ-pop city pop big band\nJ-pop city pop boogie-woogie\nJ-pop city pop bossa nova\nJ-pop city pop chiptune\nJ-pop city pop cinematic\nJ-pop city pop disco\nJ-pop city pop disco-funk\nJ-pop city pop dream pop\nJ-pop city pop funk\nJ-pop city pop funk-rock\nJ-pop city pop funky\nJ-pop city pop future funk\nJ-pop city pop hip-hop\nJ-pop city pop indie pop\nJ-pop city pop indie rock\nJ-pop city pop jazz\nJ-pop city pop jazz fusion\nJ-pop city pop jazz-funk\nJ-pop city pop jazz-fusion\nJ-pop city pop lo-fi\nJ-pop city pop lo-fi hip-hop\nJ-pop city pop lounge\nJ-pop city pop math rock\nJ-pop city pop neo-soul\nJ-pop city pop new jack swing\nJ-pop city pop nu-disco\nJ-pop city pop orchestral\nJ-pop city pop reggae\nJ-pop city pop samba\nJ-pop city pop smooth jazz\nJ-pop city pop soft rock\nJ-pop city pop soul\nJ-pop city pop surf rock\nJ-pop city pop synth-funk\nJ-pop city pop synth-pop\nJ-pop city pop tropical\nJ-pop city pop tropical house\nJ-pop city pop video game\nJ-pop city-pop\nJ-pop city-pop Shibuya-kei\nJ-pop city-pop funk\nJ-pop cloud rap\nJ-pop complextro\nJ-pop country bluegrass\nJ-pop country blues-rock\nJ-pop country folk\nJ-pop country swing\nJ-pop country-pop\nJ-pop country-rock\nJ-pop dance\nJ-pop dance-pop\nJ-pop dance-pop EDM\nJ-pop dance-pop K-pop\nJ-pop dance-pop Latin\nJ-pop dance-pop R&B\nJ-pop dance-pop anison\nJ-pop dance-pop disco\nJ-pop dance-pop electro-pop\nJ-pop dance-pop electropop\nJ-pop dance-pop funk\nJ-pop dance-pop hip-hop\nJ-pop dance-pop house\nJ-pop dance-pop rock\nJ-pop dance-pop tropical\nJ-pop dance-pop tropical house\nJ-pop dance-rock\nJ-pop dancehall\nJ-pop dancehall afrobeats\nJ-pop dancehall fusion\nJ-pop dancehall hip-hop\nJ-pop dancehall moombahton\nJ-pop dancehall reggae\nJ-pop dancehall reggaeton\nJ-pop dark cabaret\nJ-pop deep house\nJ-pop denpa\nJ-pop denpa anison\nJ-pop denpa artcore\nJ-pop denpa chiptune\nJ-pop denpa happy hardcore\nJ-pop denpa idol\nJ-pop denpa speedcore\nJ-pop denpa-kei\nJ-pop denpa-kei anison\nJ-pop denpa-kei chiptune\nJ-pop denpa-kei happy hardcore\nJ-pop disco funk\nJ-pop disco-funk\nJ-pop disco-pop\nJ-pop downtempo R&B\nJ-pop dream pop\nJ-pop drill\nJ-pop drill R&B\nJ-pop drill trap\nJ-pop drum and bass\nJ-pop drum and bass artcore\nJ-pop drum and bass breakcore\nJ-pop electro house\nJ-pop electro house chiptune\nJ-pop electro house future bass\nJ-pop electro-funk\nJ-pop electro-funk chiptune\nJ-pop electro-funk nu-disco\nJ-pop electro-house\nJ-pop electro-house chiptune\nJ-pop electro-house synth-pop\nJ-pop electro-pop\nJ-pop electro-pop anison\nJ-pop electro-pop chiptune\nJ-pop electro-pop dance\nJ-pop electro-pop dance-pop\nJ-pop electro-pop dance-rock\nJ-pop electro-pop funk\nJ-pop electro-pop future bass\nJ-pop electro-rock\nJ-pop electro-swing\nJ-pop electro-swing chiptune\nJ-pop electro-swing funk\nJ-pop electro-swing happy hardcore\nJ-pop electronic\nJ-pop electronic R&B\nJ-pop electronic art-pop\nJ-pop electronic dance\nJ-pop electronic funk\nJ-pop electronic hip-hop\nJ-pop electronic pop\nJ-pop electronic pop hyperpop\nJ-pop electronic pop-rock\nJ-pop electronic rock\nJ-pop electronic rock dance-pop\nJ-pop electronic rock drum and bass\nJ-pop electronic rock trap\nJ-pop electronic trap\nJ-pop electropop\nJ-pop electropop chiptune\nJ-pop electropop dance-pop\nJ-pop electropop future bass\nJ-pop electropop hyperpop\nJ-pop emo rap\nJ-pop emo rap lo-fi hip-hop\nJ-pop emo rap trap\nJ-pop emo trap\nJ-pop emo-pop\nJ-pop emo-rap\nJ-pop emo-rap alternative rock\nJ-pop emo-rap hyperpop\nJ-pop emo-rap indie rock\nJ-pop emo-rap lo-fi hip-hop\nJ-pop emo-rap trap\nJ-pop emo-trap\nJ-pop epic\nJ-pop exotica\nJ-pop experimental\nJ-pop fantasy\nJ-pop flamenco\nJ-pop folk\nJ-pop folk Latin\nJ-pop folk country\nJ-pop folk island\nJ-pop folk world music\nJ-pop folk-country\nJ-pop folk-pop\nJ-pop folk-pop video game\nJ-pop folk-rock\nJ-pop funk\nJ-pop funk Latin\nJ-pop funk Latin dance\nJ-pop funk R&B\nJ-pop funk Shibuya-kei\nJ-pop funk acid jazz\nJ-pop funk big band\nJ-pop funk breakbeat\nJ-pop funk chiptune\nJ-pop funk city pop\nJ-pop funk dance\nJ-pop funk dance-pop\nJ-pop funk dancehall\nJ-pop funk disco\nJ-pop funk disco rock\nJ-pop funk electro-rock\nJ-pop funk electronic\nJ-pop funk electronic dance\nJ-pop funk electronic rock\nJ-pop funk fusion\nJ-pop funk glitch-hop\nJ-pop funk hip-hop\nJ-pop funk indie rock\nJ-pop funk jazz\nJ-pop funk jazz fusion\nJ-pop funk math rock\nJ-pop funk new jack swing\nJ-pop funk pop-rock\nJ-pop funk reggae\nJ-pop funk rock\nJ-pop funk salsa\nJ-pop funk ska\nJ-pop funk soul\nJ-pop funk video game\nJ-pop funk world music\nJ-pop funk-disco\nJ-pop funk-pop\nJ-pop funk-rap\nJ-pop funk-rock\nJ-pop funk-rock chiptune\nJ-pop funk-rock video game\nJ-pop fusion\nJ-pop future bass\nJ-pop future bass EDM\nJ-pop future bass J-rock\nJ-pop future bass R&B\nJ-pop future bass UK garage\nJ-pop future bass art pop\nJ-pop future bass artcore\nJ-pop future bass breakcore\nJ-pop future bass chiptune\nJ-pop future bass city pop\nJ-pop future bass deep house\nJ-pop future bass drum and bass\nJ-pop future bass electro house\nJ-pop future bass electro-house\nJ-pop future bass electro-pop\nJ-pop future bass electropop\nJ-pop future bass hip-hop\nJ-pop future bass house\nJ-pop future bass hyperpop\nJ-pop future bass kawaii bass\nJ-pop future bass lo-fi\nJ-pop future bass synth-pop\nJ-pop future bass trap\nJ-pop future funk\nJ-pop future funk city pop\nJ-pop future funk electro house\nJ-pop future funk hyperpop\nJ-pop future funk nu-disco\nJ-pop future house\nJ-pop gospel\nJ-pop gospel R&B\nJ-pop gufeng\nJ-pop happy hardcore\nJ-pop hardcore\nJ-pop hardcore electronic\nJ-pop hardcore techno\nJ-pop hardstyle\nJ-pop hip hop\nJ-pop hip hop chiptune\nJ-pop hip-hop\nJ-pop hip-hop J-rock\nJ-pop hip-hop Latin jazz\nJ-pop hip-hop R&B\nJ-pop hip-hop ballad\nJ-pop hip-hop chiptune\nJ-pop hip-hop cinematic\nJ-pop hip-hop crossover\nJ-pop hip-hop cyberpunk\nJ-pop hip-hop dancehall\nJ-pop hip-hop electronic\nJ-pop hip-hop funk\nJ-pop hip-hop fusion\nJ-pop hip-hop hardstyle\nJ-pop hip-hop jazz fusion\nJ-pop hip-hop lo-fi\nJ-pop hip-hop orchestral\nJ-pop hip-hop pop-rock\nJ-pop hip-hop reggae\nJ-pop hip-hop rock\nJ-pop hip-hop trap\nJ-pop hip-hop, Latin funk\nJ-pop hip-house\nJ-pop house\nJ-pop house dance-pop\nJ-pop hyper-disco\nJ-pop hyper-funk\nJ-pop hyper-pop\nJ-pop hyper-pop anime\nJ-pop hyper-pop anison\nJ-pop hyper-pop chiptune\nJ-pop hyper-pop denpa-kei\nJ-pop hyperpop\nJ-pop hyperpop EDM\nJ-pop hyperpop Eurobeat\nJ-pop hyperpop K-pop\nJ-pop hyperpop UK garage\nJ-pop hyperpop Vocaloid\nJ-pop hyperpop anime\nJ-pop hyperpop anison\nJ-pop hyperpop art pop\nJ-pop hyperpop art-pop\nJ-pop hyperpop artcore\nJ-pop hyperpop breakbeat\nJ-pop hyperpop breakcore\nJ-pop hyperpop bubblegum bass\nJ-pop hyperpop bubblegum pop\nJ-pop hyperpop chiptune\nJ-pop hyperpop city pop\nJ-pop hyperpop dance\nJ-pop hyperpop dance-pop\nJ-pop hyperpop denpa\nJ-pop hyperpop denpa-kei\nJ-pop hyperpop drum and bass\nJ-pop hyperpop electro house\nJ-pop hyperpop electro-house\nJ-pop hyperpop electro-pop\nJ-pop hyperpop electro-swing\nJ-pop hyperpop electronic dance\nJ-pop hyperpop electronic rock\nJ-pop hyperpop electropop\nJ-pop hyperpop emo-rap\nJ-pop hyperpop emo-rock\nJ-pop hyperpop funk\nJ-pop hyperpop funk-rock\nJ-pop hyperpop future bass\nJ-pop hyperpop future funk\nJ-pop hyperpop happy hardcore\nJ-pop hyperpop hardcore techno\nJ-pop hyperpop hardstyle\nJ-pop hyperpop idol\nJ-pop hyperpop idol-pop\nJ-pop hyperpop jazz fusion\nJ-pop hyperpop jazz-fusion\nJ-pop hyperpop jungle\nJ-pop hyperpop kawaii\nJ-pop hyperpop kawaii future bass\nJ-pop hyperpop nightcore\nJ-pop hyperpop orchestral\nJ-pop hyperpop trance\nJ-pop hyperpop trap\nJ-pop hyperpop video game\nJ-pop idol\nJ-pop idol metal\nJ-pop idol pop\nJ-pop idol pop anison\nJ-pop idol rock\nJ-pop idol, happy hardcore\nJ-pop indie pop\nJ-pop indie pop lo-fi hip-hop\nJ-pop indie rock\nJ-pop indie rock math rock\nJ-pop indie-folk\nJ-pop indie-pop\nJ-pop instrumental\nJ-pop jazz\nJ-pop jazz anime\nJ-pop jazz ballad\nJ-pop jazz city pop\nJ-pop jazz fusion\nJ-pop jazz fusion art pop\nJ-pop jazz fusion chiptune\nJ-pop jazz fusion city pop\nJ-pop jazz fusion funk\nJ-pop jazz fusion math rock\nJ-pop jazz fusion progressive rock\nJ-pop jazz swing\nJ-pop jazz-funk\nJ-pop jazz-fusion\nJ-pop jazz-pop\nJ-pop jazz-rock\nJ-pop jungle\nJ-pop lo-fi\nJ-pop lo-fi R&B\nJ-pop lo-fi chiptune\nJ-pop lo-fi city pop\nJ-pop lo-fi electronic\nJ-pop lo-fi hip hop\nJ-pop lo-fi hip-hop\nJ-pop lo-fi hip-hop R&B\nJ-pop lo-fi hip-hop chiptune\nJ-pop lo-fi hip-hop city pop\nJ-pop lo-fi hip-hop future bass\nJ-pop lo-fi hip-hop jazz\nJ-pop lo-fi hip-hop kawaii future bass\nJ-pop lo-fi hip-hop neo-soul\nJ-pop lo-fi hip-hop trap\nJ-pop lo-fi house\nJ-pop lo-fi hyperpop\nJ-pop lo-fi pop\nJ-pop lounge\nJ-pop lounge city pop\nJ-pop lounge exotica\nJ-pop lounge jazz\nJ-pop lullaby\nJ-pop math rock chiptune\nJ-pop math rock funk\nJ-pop math rock video game\nJ-pop melancholic\nJ-pop melodic hip-hop\nJ-pop melodic trap\nJ-pop metalcore\nJ-pop musical theater\nJ-pop neo-soul\nJ-pop neo-soul R&B\nJ-pop neo-soul chillhop\nJ-pop neo-soul city pop\nJ-pop neo-soul hip-hop\nJ-pop neo-soul lo-fi hip-hop\nJ-pop noir jazz fusion\nJ-pop novelty\nJ-pop nu-disco\nJ-pop nu-disco city pop\nJ-pop nu-disco electro-funk\nJ-pop nu-disco funk\nJ-pop nu-jazz city pop\nJ-pop nu-metal\nJ-pop orchestral\nJ-pop orchestral anime\nJ-pop orchestral pop\nJ-pop orchestral rock\nJ-pop piano-rock\nJ-pop pop ballad\nJ-pop pop-punk\nJ-pop pop-rock\nJ-pop post-rock\nJ-pop power ballad\nJ-pop power metal\nJ-pop progressive house\nJ-pop progressive house trance\nJ-pop progressive metal\nJ-pop progressive rock\nJ-pop progressive rock chiptune\nJ-pop progressive trance\nJ-pop protest\nJ-pop punk\nJ-pop rap\nJ-pop reggae\nJ-pop reggae dancehall\nJ-pop reggae fusion\nJ-pop reggae hip-hop\nJ-pop reggae ska\nJ-pop reggae-dancehall\nJ-pop reggae-pop\nJ-pop reggae-ska\nJ-pop reggaeton\nJ-pop retro funk ska\nJ-pop retro rock\nJ-pop retro surf-rock\nJ-pop retro video game\nJ-pop rock\nJ-pop rock electronic\nJ-pop rock rap\nJ-pop rock, C-pop rock\nJ-pop rock, city pop, jazz\nJ-pop rock, lounge jazz, cinematic\nJ-pop rockabilly\nJ-pop rockabilly surf rock\nJ-pop salsa\nJ-pop samba\nJ-pop sentimental ballad\nJ-pop sentimental pop\nJ-pop shoegaze\nJ-pop show tune\nJ-pop singer-songwriter\nJ-pop ska\nJ-pop ska anime\nJ-pop ska big band\nJ-pop ska fusion\nJ-pop ska reggae\nJ-pop ska surf rock\nJ-pop ska-punk\nJ-pop ska-punk big band\nJ-pop ska-punk surf rock\nJ-pop soul\nJ-pop soul fusion\nJ-pop soul jazz\nJ-pop speed metal\nJ-pop speedcore\nJ-pop speedcore big band\nJ-pop speedcore chiptune\nJ-pop surf rock\nJ-pop swing\nJ-pop swing jazz\nJ-pop symphonic\nJ-pop symphonic rock\nJ-pop synth-funk\nJ-pop synth-pop\nJ-pop synth-pop EDM\nJ-pop synth-pop Latin R&B\nJ-pop synth-pop anime\nJ-pop synth-pop chillwave\nJ-pop synth-pop chiptune\nJ-pop synth-pop city pop\nJ-pop synth-pop dance\nJ-pop synth-pop dance-pop\nJ-pop synth-pop dance-rock\nJ-pop synth-pop electro-house\nJ-pop synth-pop electro-pop\nJ-pop synth-pop electronic rock\nJ-pop synth-pop electropop\nJ-pop synth-pop funk\nJ-pop synth-pop rock\nJ-pop synth-pop trance\nJ-pop synth-pop video game\nJ-pop synth-rock\nJ-pop synthpop\nJ-pop synthpop chiptune\nJ-pop synthpop cyberpunk\nJ-pop synthpop electro-pop\nJ-pop synthpop trance\nJ-pop synthwave\nJ-pop synthwave chiptune\nJ-pop synthwave cyberpunk\nJ-pop tango\nJ-pop tango Latin\nJ-pop tango flamenco\nJ-pop theatrical\nJ-pop trance\nJ-pop trance EDM\nJ-pop trance Eurobeat\nJ-pop trance anime\nJ-pop trance anison\nJ-pop trance artcore\nJ-pop trance chiptune\nJ-pop trance electronic rock\nJ-pop trance eurobeat\nJ-pop trance progressive house\nJ-pop trance-pop\nJ-pop trancecore\nJ-pop trap\nJ-pop trap EDM\nJ-pop trap K-hip-hop\nJ-pop trap R&B\nJ-pop trap ambient\nJ-pop trap anime\nJ-pop trap chillwave\nJ-pop trap chiptune\nJ-pop trap electronic\nJ-pop trap electronic rock\nJ-pop trap fusion\nJ-pop trap hardstyle\nJ-pop trap horrorcore\nJ-pop trap hyperpop\nJ-pop trap rock\nJ-pop trap soul\nJ-pop trap synth-pop\nJ-pop trap-R&B\nJ-pop trap-pop\nJ-pop trap-soul\nJ-pop trip-hop\nJ-pop trip-hop art pop\nJ-pop tropical\nJ-pop tropical Latin\nJ-pop tropical big band\nJ-pop tropical house\nJ-pop tropical house EDM\nJ-pop tropical house dance-pop\nJ-pop tropical house dancehall\nJ-pop tropical house future bass\nJ-pop tropical house trap\nJ-pop vintage\nJ-pop violin\nJ-pop waltz\nJ-pop world fusion\nJ-pop world music\nJ-pop, 80s Kayōkyoku, classic rock\nJ-pop, 80s Kayōkyoku, synth pop\nJ-pop, 80s anime\nJ-pop, 80s anime, city pop\nJ-pop, 80s anime, hard rock\nJ-pop, 80s anime, theatrical\nJ-pop, 80s anime, upbeat\nJ-pop, 80s synth, anime soundtrack\nJ-pop, 80s synth, anime theme\nJ-pop, 80s synth-pop\nJ-pop, 80s synth-pop, anime\nJ-pop, 80s, funk\nJ-pop, 90s R&B, hip-hop\nJ-pop, 90s R&B, new jack swing\nJ-pop, 90s anime, Christmas ballad\nJ-pop, 90s dance-pop\nJ-pop, 90s dance-pop, video game music\nJ-pop, 90s video game\nJ-pop, Afrobeats, dancehall\nJ-pop, Anisong\nJ-pop, Anisong, J-rock\nJ-pop, Anisong, electronic\nJ-pop, Anisong, nightcore\nJ-pop, Anisong, pop-rock\nJ-pop, Anisong, rock\nJ-pop, Anisong, symphonic rock\nJ-pop, Anisong, trance\nJ-pop, Anisong, video game music\nJ-pop, Baroque, Vocaloid\nJ-pop, Bollywood, Latin\nJ-pop, Bollywood, Latin fusion\nJ-pop, Bollywood, educational\nJ-pop, Bollywood, electronic\nJ-pop, Bossa Nova, Latin\nJ-pop, Bossa Nova, Latin jazz\nJ-pop, Brazilian funk\nJ-pop, Broadway, big band\nJ-pop, C-pop\nJ-pop, C-pop, J-rock\nJ-pop, C-pop, Vocaloid\nJ-pop, C-pop, ambient\nJ-pop, C-pop, anime\nJ-pop, C-pop, anime soundtrack\nJ-pop, C-pop, anime theme\nJ-pop, C-pop, chiptune\nJ-pop, C-pop, educational\nJ-pop, C-pop, electronic\nJ-pop, C-pop, gǔfēng, orchestral\nJ-pop, C-pop, hip-hop\nJ-pop, C-pop, synth pop\nJ-pop, C-pop, synthpop\nJ-pop, C-pop, video game music\nJ-pop, C-pop, video game soundtrack\nJ-pop, Celtic folk\nJ-pop, Celtic folk, dance rock\nJ-pop, Celtic folk, rock\nJ-pop, Chinese New Year, anime soundtrack\nJ-pop, Chinese fusion, Vocaloid\nJ-pop, Chinese fusion, anime soundtrack\nJ-pop, Chinese traditional, anime soundtrack\nJ-pop, Christian pop-rock\nJ-pop, Christmas\nJ-pop, Christmas ballad\nJ-pop, Christmas pop\nJ-pop, Christmas pop, anime\nJ-pop, Christmas pop, anime theme\nJ-pop, Christmas pop, big band\nJ-pop, Christmas pop, video game music\nJ-pop, Christmas, anime\nJ-pop, Christmas, hip-hop\nJ-pop, City Pop, 80s\nJ-pop, City Pop, AOR\nJ-pop, City Pop, Anison\nJ-pop, City Pop, Enka\nJ-pop, City Pop, Eurobeat\nJ-pop, City Pop, Kayōkyoku\nJ-pop, City Pop, anime theme\nJ-pop, City Pop, cinematic\nJ-pop, City Pop, disco\nJ-pop, City Pop, power ballad\nJ-pop, City Pop, synth-pop\nJ-pop, Denpa, Anison\nJ-pop, Denpa, happy hardcore\nJ-pop, Denpa-kei\nJ-pop, EDM\nJ-pop, EDM, ambient\nJ-pop, EDM, anime\nJ-pop, EDM, anison\nJ-pop, EDM, artcore\nJ-pop, EDM, chiptune\nJ-pop, EDM, cinematic\nJ-pop, EDM, dance\nJ-pop, EDM, dance-pop\nJ-pop, EDM, electronic\nJ-pop, EDM, future bass\nJ-pop, EDM, gospel\nJ-pop, EDM, happy hardcore\nJ-pop, EDM, hardstyle\nJ-pop, EDM, hip-hop\nJ-pop, EDM, house\nJ-pop, EDM, hyperpop\nJ-pop, EDM, matsuri\nJ-pop, EDM, pop\nJ-pop, EDM, rock\nJ-pop, EDM, synth pop\nJ-pop, EDM, synth-pop\nJ-pop, EDM, traditional Japanese\nJ-pop, EDM, trance\nJ-pop, EDM, trap\nJ-pop, EDM, world music\nJ-pop, EDM-pop, future bass\nJ-pop, East Asian fusion\nJ-pop, Eurobeat\nJ-pop, Eurobeat, 2000s dance-pop\nJ-pop, Eurobeat, 80s synth\nJ-pop, Eurobeat, 80s synth-pop\nJ-pop, Eurobeat, 90s\nJ-pop, Eurobeat, 90s anime\nJ-pop, Eurobeat, 90s dance-pop\nJ-pop, Eurobeat, Anisong\nJ-pop, Eurobeat, City Pop\nJ-pop, Eurobeat, Happy Hardcore\nJ-pop, Eurobeat, Hi-NRG\nJ-pop, Eurobeat, Italo disco\nJ-pop, Eurobeat, Italo-disco\nJ-pop, Eurobeat, J-rock\nJ-pop, Eurobeat, Latin\nJ-pop, Eurobeat, Trance\nJ-pop, Eurobeat, anime\nJ-pop, Eurobeat, anime theme\nJ-pop, Eurobeat, arcade\nJ-pop, Eurobeat, chiptune\nJ-pop, Eurobeat, cinematic\nJ-pop, Eurobeat, city pop\nJ-pop, Eurobeat, dance\nJ-pop, Eurobeat, dance rock\nJ-pop, Eurobeat, dance-pop\nJ-pop, Eurobeat, dancehall\nJ-pop, Eurobeat, disco\nJ-pop, Eurobeat, early 2000s trance\nJ-pop, Eurobeat, electronic\nJ-pop, Eurobeat, funk\nJ-pop, Eurobeat, happy hardcore\nJ-pop, Eurobeat, hard dance\nJ-pop, Eurobeat, hard rock\nJ-pop, Eurobeat, high-energy\nJ-pop, Eurobeat, house\nJ-pop, Eurobeat, hyperpop\nJ-pop, Eurobeat, industrial\nJ-pop, Eurobeat, pop-punk\nJ-pop, Eurobeat, retro-futuristic\nJ-pop, Eurobeat, synth-pop\nJ-pop, Eurobeat, synthwave\nJ-pop, Eurobeat, trance\nJ-pop, Eurobeat, video game music\nJ-pop, Eurobeat, video game soundtrack\nJ-pop, Eurodance\nJ-pop, Eurodance, chiptune\nJ-pop, Eurodance, happy hardcore\nJ-pop, Eurodance, trance\nJ-pop, European folk\nJ-pop, European folk, cinematic\nJ-pop, European folk, musette\nJ-pop, European folk, theatrical\nJ-pop, European folk, video game soundtrack\nJ-pop, European folk, waltz\nJ-pop, Future Bass\nJ-pop, Future Bass, video game music\nJ-pop, German hip hop\nJ-pop, Guofeng\nJ-pop, Indian fusion\nJ-pop, J-core\nJ-pop, J-core, EDM\nJ-pop, J-core, happy hardcore\nJ-pop, J-core, hardstyle\nJ-pop, J-hip-hop\nJ-pop, J-hip-hop, cinematic\nJ-pop, J-hip-hop, funk\nJ-pop, J-rap\nJ-pop, J-rap, chiptune\nJ-pop, J-rap, electronic dance\nJ-pop, J-rap, trap\nJ-pop, J-rock\nJ-pop, J-rock, Christmas\nJ-pop, J-rock, EDM\nJ-pop, J-rock, UK Hardcore\nJ-pop, J-rock, Vocaloid\nJ-pop, J-rock, anime\nJ-pop, J-rock, anime theme\nJ-pop, J-rock, anison\nJ-pop, J-rock, ballad\nJ-pop, J-rock, chiptune\nJ-pop, J-rock, cinematic\nJ-pop, J-rock, cinematic orchestral\nJ-pop, J-rock, cinematic rock\nJ-pop, J-rock, electronic\nJ-pop, J-rock, future bass\nJ-pop, J-rock, hip-hop\nJ-pop, J-rock, hyperpop\nJ-pop, J-rock, jazz-rock\nJ-pop, J-rock, lo-fi\nJ-pop, J-rock, lo-fi hip hop\nJ-pop, J-rock, metalcore\nJ-pop, J-rock, orchestral\nJ-pop, J-rock, post-hardcore\nJ-pop, J-rock, speedcore\nJ-pop, J-rock, symphonic metal\nJ-pop, J-rock, symphonic power metal\nJ-pop, J-rock, symphonic rock\nJ-pop, J-rock, synth pop\nJ-pop, J-rock, synth-pop\nJ-pop, J-rock, traditional fusion\nJ-pop, J-rock, vaporwave\nJ-pop, J-rock, world music\nJ-pop, JRPG, fantasy\nJ-pop, Javanese pop\nJ-pop, K-pop, Eurobeat\nJ-pop, K-pop, chiptune\nJ-pop, K-pop, funk\nJ-pop, Kayōkyoku\nJ-pop, Kayōkyoku, 80s synth\nJ-pop, Kayōkyoku, Latin\nJ-pop, Kayōkyoku, Latin pop\nJ-pop, Kayōkyoku, ballad\nJ-pop, Kayōkyoku, big band\nJ-pop, Kayōkyoku, cinematic\nJ-pop, Kayōkyoku, cinematic ballad\nJ-pop, Kayōkyoku, cinematic rock\nJ-pop, Kayōkyoku, power ballad\nJ-pop, Kayōkyoku, rock\nJ-pop, Kayōkyoku, tango\nJ-pop, Kayōkyoku, theatrical\nJ-pop, Kayōkyoku, world music\nJ-pop, Latin dance\nJ-pop, Latin dance, chiptune\nJ-pop, Latin dance, electronic\nJ-pop, Latin dance, reggaeton\nJ-pop, Latin folk\nJ-pop, Latin folk, European folk\nJ-pop, Latin funk\nJ-pop, Latin house, funk\nJ-pop, Latin jazz, anime\nJ-pop, Latin jazz, big band\nJ-pop, Latin jazz, bossa nova\nJ-pop, Latin jazz, city pop\nJ-pop, Latin jazz, salsa\nJ-pop, Latin jazz, samba\nJ-pop, Latin jazz, world music\nJ-pop, Latin pop\nJ-pop, Latin pop, city pop\nJ-pop, Latin pop, pop-rock\nJ-pop, Latin pop, reggaeton\nJ-pop, Latin pop, tropical\nJ-pop, Latin rock, dance-pop\nJ-pop, Latin salsa\nJ-pop, Latin samba\nJ-pop, Latin, Afro-Cuban\nJ-pop, Latin, Bossa Nova\nJ-pop, Latin, City Pop\nJ-pop, Latin, Eastern European\nJ-pop, Latin, anime\nJ-pop, Latin, big band\nJ-pop, Latin, children's\nJ-pop, Latin, electronic\nJ-pop, Latin, flamenco\nJ-pop, Latin, hyperpop\nJ-pop, Latin, retro\nJ-pop, Latin, salsa\nJ-pop, Latin, samba\nJ-pop, Latin, ska\nJ-pop, Latin, tango\nJ-pop, Latin, theatrical\nJ-pop, Latin, upbeat\nJ-pop, Latin, video game\nJ-pop, Latin, video game music\nJ-pop, Latin, vintage\nJ-pop, Latin, world music\nJ-pop, Latin-pop\nJ-pop, Latin-pop, video game music\nJ-pop, Mandarin rap, anime theme\nJ-pop, Middle Eastern fusion\nJ-pop, Middle Eastern, anime\nJ-pop, New Jack Swing\nJ-pop, New Jack Swing, R&B\nJ-pop, New Jack Swing, chiptune\nJ-pop, New Jack Swing, funk\nJ-pop, R&B\nJ-pop, R&B, 2000s\nJ-pop, R&B, Christmas\nJ-pop, R&B, EDM\nJ-pop, R&B, Eurobeat\nJ-pop, R&B, New Jack Swing\nJ-pop, R&B, chillhop\nJ-pop, R&B, chillwave\nJ-pop, R&B, chiptune\nJ-pop, R&B, cinematic\nJ-pop, R&B, cinematic orchestral\nJ-pop, R&B, city pop\nJ-pop, R&B, club\nJ-pop, R&B, dance-pop\nJ-pop, R&B, dancehall\nJ-pop, R&B, dream pop\nJ-pop, R&B, early 2000s\nJ-pop, R&B, electronic\nJ-pop, R&B, electronic dance\nJ-pop, R&B, funk\nJ-pop, R&B, gospel\nJ-pop, R&B, hip-hop\nJ-pop, R&B, hyperpop\nJ-pop, R&B, late-90s\nJ-pop, R&B, lo-fi hip-hop\nJ-pop, R&B, neo-soul\nJ-pop, R&B, new jack swing\nJ-pop, R&B, orchestral\nJ-pop, R&B, pop\nJ-pop, R&B, pop-rock\nJ-pop, R&B, power ballad\nJ-pop, R&B, trap\nJ-pop, R&B, trip-hop\nJ-pop, Shibuya-kei\nJ-pop, Shibuya-kei, Latin\nJ-pop, Shibuya-kei, Latin jazz\nJ-pop, Shibuya-kei, art-pop\nJ-pop, Shibuya-kei, artcore\nJ-pop, Shibuya-kei, breakbeat\nJ-pop, Shibuya-kei, chiptune\nJ-pop, Shibuya-kei, city pop\nJ-pop, Shibuya-kei, drum and bass\nJ-pop, Shibuya-kei, funk\nJ-pop, Shibuya-kei, happy hardcore\nJ-pop, Shibuya-kei, jazz\nJ-pop, Shibuya-kei, jazz fusion\nJ-pop, Shibuya-kei, jazz-fusion\nJ-pop, Shibuya-kei, video game\nJ-pop, Shibuya-kei, video game music\nJ-pop, Showa Kayōkyoku, theatrical\nJ-pop, Showa-era, big band\nJ-pop, Spanish-style, anime theme\nJ-pop, UK Hardcore\nJ-pop, UK Hardcore, anime pop\nJ-pop, UK Hardcore, complextro\nJ-pop, UK Hardcore, hardstyle\nJ-pop, UK garage, 2-step\nJ-pop, UK garage, electronic\nJ-pop, UK garage, future bass\nJ-pop, UK garage, trance\nJ-pop, UK garage, video game music\nJ-pop, UK hardcore\nJ-pop, Vocaloid\nJ-pop, Vocaloid, Chinese folk\nJ-pop, Vocaloid, EDM\nJ-pop, Vocaloid, ambient\nJ-pop, Vocaloid, anime\nJ-pop, Vocaloid, anime soundtrack\nJ-pop, Vocaloid, anime theme\nJ-pop, Vocaloid, anime-style pop\nJ-pop, Vocaloid, ballad\nJ-pop, Vocaloid, chiptune\nJ-pop, Vocaloid, chiptune rock\nJ-pop, Vocaloid, cinematic\nJ-pop, Vocaloid, city pop\nJ-pop, Vocaloid, electronic\nJ-pop, Vocaloid, fantasy\nJ-pop, Vocaloid, futuristic\nJ-pop, Vocaloid, glitch\nJ-pop, Vocaloid, hyper-pop\nJ-pop, Vocaloid, hyperpop\nJ-pop, Vocaloid, quirky\nJ-pop, Vocaloid, synthpop\nJ-pop, Vocaloid, synthwave\nJ-pop, Vocaloid, video game\nJ-pop, a cappella, cinematic\nJ-pop, acid jazz, R&B\nJ-pop, acid jazz, city pop\nJ-pop, acid jazz, funk\nJ-pop, acid jazz, hip-hop\nJ-pop, acoustic, lo-fi, pop-rock\nJ-pop, alternative R&B, dark electronic\nJ-pop, ambient\nJ-pop, ambient, R&B\nJ-pop, ambient, Vocaloid\nJ-pop, ambient, breakbeat\nJ-pop, ambient, cinematic\nJ-pop, ambient, deep house\nJ-pop, ambient, drum and bass\nJ-pop, ambient, electronic\nJ-pop, ambient, lo-fi\nJ-pop, ambient, trap\nJ-pop, anime\nJ-pop, anime EDM, C-pop\nJ-pop, anime ballad\nJ-pop, anime ballad, Vocaloid\nJ-pop, anime ballad, cinematic\nJ-pop, anime ballad, orchestral\nJ-pop, anime ballad, pop-rock\nJ-pop, anime ballad, synth-driven\nJ-pop, anime opening, children's music\nJ-pop, anime opening, video game boss\nJ-pop, anime opening, video game soundtrack\nJ-pop, anime power ballad\nJ-pop, anime rock\nJ-pop, anime rock, ambient\nJ-pop, anime rock, breakcore\nJ-pop, anime rock, cinematic\nJ-pop, anime rock, orchestral\nJ-pop, anime rock, piano ballad\nJ-pop, anime rock, synth-rock\nJ-pop, anime soundtrack\nJ-pop, anime soundtrack, Christmas pop\nJ-pop, anime soundtrack, J-rock\nJ-pop, anime soundtrack, Vocaloid\nJ-pop, anime soundtrack, ambient\nJ-pop, anime soundtrack, ballad\nJ-pop, anime soundtrack, children's music\nJ-pop, anime soundtrack, cinematic\nJ-pop, anime soundtrack, electronic\nJ-pop, anime soundtrack, instrumental\nJ-pop, anime soundtrack, orchestral\nJ-pop, anime soundtrack, piano ballad\nJ-pop, anime soundtrack, pop-rock\nJ-pop, anime soundtrack, power ballad\nJ-pop, anime soundtrack, synthwave\nJ-pop, anime soundtrack, upbeat\nJ-pop, anime soundtrack, video game music\nJ-pop, anime style\nJ-pop, anime style, Mandarin\nJ-pop, anime style, Mandarin pop\nJ-pop, anime style, cinematic\nJ-pop, anime style, pop-rock\nJ-pop, anime style, power ballad\nJ-pop, anime theme\nJ-pop, anime theme, J-rock\nJ-pop, anime theme, children's\nJ-pop, anime theme, children's music\nJ-pop, anime theme, children's pop\nJ-pop, anime theme, chiptune\nJ-pop, anime theme, cinematic\nJ-pop, anime theme, cinematic rock\nJ-pop, anime theme, city pop\nJ-pop, anime theme, city-pop\nJ-pop, anime theme, denpa-kei\nJ-pop, anime theme, electronic\nJ-pop, anime theme, electronic rock\nJ-pop, anime theme, funk\nJ-pop, anime theme, future bass\nJ-pop, anime theme, future funk\nJ-pop, anime theme, hyperpop\nJ-pop, anime theme, late-90s\nJ-pop, anime theme, lo-fi hip-hop\nJ-pop, anime theme, orchestral\nJ-pop, anime theme, pop\nJ-pop, anime theme, pop duet\nJ-pop, anime theme, pop-rock\nJ-pop, anime theme, power ballad\nJ-pop, anime theme, rock\nJ-pop, anime theme, synthwave\nJ-pop, anime theme, theatrical\nJ-pop, anime theme, traditional Japanese\nJ-pop, anime theme, video game soundtrack\nJ-pop, anime, Chinese New Year\nJ-pop, anime, Christmas\nJ-pop, anime, EDM\nJ-pop, anime, Mandarin pop\nJ-pop, anime, Vocaloid\nJ-pop, anime, ambient\nJ-pop, anime, children's\nJ-pop, anime, children's music\nJ-pop, anime, children's pop\nJ-pop, anime, chiptune\nJ-pop, anime, cinematic\nJ-pop, anime, dance\nJ-pop, anime, dance-pop\nJ-pop, anime, electronic\nJ-pop, anime, funk\nJ-pop, anime, future bass\nJ-pop, anime, glitch\nJ-pop, anime, happy hardcore\nJ-pop, anime, hardstyle\nJ-pop, anime, hyperpop\nJ-pop, anime, jazz fusion\nJ-pop, anime, lo-fi\nJ-pop, anime, metalcore\nJ-pop, anime, musical theater\nJ-pop, anime, orchestral\nJ-pop, anime, pop\nJ-pop, anime, pop ballad\nJ-pop, anime, pop-rap\nJ-pop, anime, pop-rock\nJ-pop, anime, power ballad\nJ-pop, anime, retro-futuristic\nJ-pop, anime, rock\nJ-pop, anime, synth pop\nJ-pop, anime, synth-pop\nJ-pop, anime, synthpop\nJ-pop, anime, synthwave\nJ-pop, anime, theatrical\nJ-pop, anime, trap\nJ-pop, anime, video game\nJ-pop, anime, video game music\nJ-pop, anime-style\nJ-pop, anime-style pop-rock\nJ-pop, anime-style, dance\nJ-pop, anime-style, electronic\nJ-pop, anime-style, pop-rock\nJ-pop, anime-style, power pop\nJ-pop, anime-style, synth-pop\nJ-pop, anison, EDM\nJ-pop, anison, Eurobeat\nJ-pop, anison, J-rock\nJ-pop, anison, chiptune\nJ-pop, anison, dance-pop\nJ-pop, anison, denpa\nJ-pop, anison, festive\nJ-pop, anison, happy hardcore\nJ-pop, anison, hyperpop\nJ-pop, anison, idol pop\nJ-pop, anison, pop-punk\nJ-pop, anison, pop-rock\nJ-pop, anison, power metal\nJ-pop, anison, power-pop\nJ-pop, anison, rock\nJ-pop, anison, symphonic rock\nJ-pop, anison, trance\nJ-pop, anisong, EDM\nJ-pop, arcade, electronic\nJ-pop, art pop, Vocaloid\nJ-pop, art pop, breakbeat\nJ-pop, art pop, electronic\nJ-pop, art pop, hyperpop\nJ-pop, art rock, symphonic metal\nJ-pop, art-pop, Vocaloid\nJ-pop, art-pop, anime soundtrack\nJ-pop, art-pop, electronic\nJ-pop, art-pop, electronica\nJ-pop, art-pop, future bass\nJ-pop, artcore\nJ-pop, artcore, J-core\nJ-pop, artcore, breakcore\nJ-pop, artcore, chiptune\nJ-pop, artcore, cinematic\nJ-pop, artcore, drum and bass\nJ-pop, artcore, electronic\nJ-pop, artcore, happy hardcore\nJ-pop, artcore, hyper-speed\nJ-pop, artcore, hyperpop\nJ-pop, artcore, lo-fi\nJ-pop, artcore, lo-fi hip-hop\nJ-pop, artcore, speedcore\nJ-pop, artcore, trance\nJ-pop, artcore, video game\nJ-pop, ballad, video game soundtrack\nJ-pop, baroque, anime\nJ-pop, baroque-pop\nJ-pop, big band\nJ-pop, big band jazz\nJ-pop, big band jazz fusion\nJ-pop, big band jazz, anime\nJ-pop, big band jazz, anime theme\nJ-pop, big band jazz, electronic\nJ-pop, big band jazz, video game music\nJ-pop, big band swing\nJ-pop, big band swing, Christmas\nJ-pop, big band swing, cinematic\nJ-pop, big band, Kayōkyoku\nJ-pop, big band, Latin jazz\nJ-pop, big band, Showa Kayōkyoku\nJ-pop, big band, anime\nJ-pop, big band, anime theme\nJ-pop, big band, boogie-woogie\nJ-pop, big band, cinematic\nJ-pop, big band, city pop\nJ-pop, big band, funk\nJ-pop, big band, hyperpop\nJ-pop, big band, jazz\nJ-pop, big band, jazz fusion\nJ-pop, big band, show tune\nJ-pop, big band, ska\nJ-pop, big band, swing\nJ-pop, big band, swing jazz\nJ-pop, big beat\nJ-pop, big beat, hip-hop\nJ-pop, boogie-woogie\nJ-pop, boogie-woogie, children's music\nJ-pop, boogie-woogie, chiptune\nJ-pop, boogie-woogie, electronic\nJ-pop, boogie-woogie, funk\nJ-pop, boogie-woogie, jazz\nJ-pop, boom-bap, retro\nJ-pop, boom-bap, soul\nJ-pop, bossa nova, chiptune\nJ-pop, bossa nova, future bass\nJ-pop, bossa nova, video game music\nJ-pop, breakbeat\nJ-pop, breakbeat, chiptune\nJ-pop, breakbeat, electronic\nJ-pop, breakbeat, hip-hop\nJ-pop, breakbeat, video game\nJ-pop, breakbeat, world music\nJ-pop, breakcore\nJ-pop, breakcore, J-rock\nJ-pop, breakcore, R&B\nJ-pop, breakcore, artcore\nJ-pop, breakcore, chiptune\nJ-pop, breakcore, drum and bass\nJ-pop, breakcore, electronic\nJ-pop, breakcore, lo-fi\nJ-pop, breakcore, lo-fi hip hop\nJ-pop, breakcore, symphonic metal\nJ-pop, cabaret, tango\nJ-pop, cha-cha-chá\nJ-pop, chamber pop\nJ-pop, children's Christian\nJ-pop, children's Christian pop, video game music\nJ-pop, children's music\nJ-pop, children's music, big band\nJ-pop, children's music, chiptune\nJ-pop, children's music, pop\nJ-pop, children's music, synthwave\nJ-pop, children's music, video game\nJ-pop, children's music, video game music\nJ-pop, children's music, video game soundtrack\nJ-pop, children's music, whimsical pop\nJ-pop, children's pop\nJ-pop, children's pop, Christian pop\nJ-pop, children's pop, anime\nJ-pop, children's pop, chiptune\nJ-pop, children's pop, festive\nJ-pop, children's pop, synth-pop\nJ-pop, children's pop, video game\nJ-pop, children's pop, video game music\nJ-pop, chiptune\nJ-pop, chiptune, EDM\nJ-pop, chiptune, J-rock\nJ-pop, chiptune, Vocaloid\nJ-pop, chiptune, ambient\nJ-pop, chiptune, anime\nJ-pop, chiptune, anime ballad\nJ-pop, chiptune, anime rock\nJ-pop, chiptune, anime theme\nJ-pop, chiptune, anison\nJ-pop, chiptune, arcade\nJ-pop, chiptune, art pop\nJ-pop, chiptune, art-pop\nJ-pop, chiptune, artcore\nJ-pop, chiptune, bedroom pop\nJ-pop, chiptune, breakbeat\nJ-pop, chiptune, breakcore\nJ-pop, chiptune, children's music\nJ-pop, chiptune, cinematic\nJ-pop, chiptune, city pop\nJ-pop, chiptune, complextro\nJ-pop, chiptune, dance\nJ-pop, chiptune, dance-pop\nJ-pop, chiptune, dancehall\nJ-pop, chiptune, denpa\nJ-pop, chiptune, denpa-kei\nJ-pop, chiptune, electronic\nJ-pop, chiptune, electronic R&B\nJ-pop, chiptune, electronic dance\nJ-pop, chiptune, electronic rock\nJ-pop, chiptune, funk\nJ-pop, chiptune, future bass\nJ-pop, chiptune, glitch\nJ-pop, chiptune, happy hardcore\nJ-pop, chiptune, hip-hop\nJ-pop, chiptune, hyperpop\nJ-pop, chiptune, idol\nJ-pop, chiptune, jazz rock\nJ-pop, chiptune, jazz-funk\nJ-pop, chiptune, jazz-fusion\nJ-pop, chiptune, kawaii\nJ-pop, chiptune, kawaii bass\nJ-pop, chiptune, kawaii future bass\nJ-pop, chiptune, lo-fi\nJ-pop, chiptune, math rock\nJ-pop, chiptune, pop\nJ-pop, chiptune, pop-rock\nJ-pop, chiptune, progressive rock\nJ-pop, chiptune, racing game\nJ-pop, chiptune, retro-futuristic\nJ-pop, chiptune, rock\nJ-pop, chiptune, show tune\nJ-pop, chiptune, speedcore\nJ-pop, chiptune, symphonic rock\nJ-pop, chiptune, synth-pop\nJ-pop, chiptune, synth-rock\nJ-pop, chiptune, synthpop\nJ-pop, chiptune, synthwave\nJ-pop, chiptune, trance\nJ-pop, chiptune, upbeat\nJ-pop, chiptune, video game\nJ-pop, chiptune, video game music\nJ-pop, cinematic\nJ-pop, cinematic ballad\nJ-pop, cinematic electronic, anime soundtrack\nJ-pop, cinematic lo-fi\nJ-pop, cinematic orchestral\nJ-pop, cinematic orchestral, J-rock\nJ-pop, cinematic pop\nJ-pop, cinematic pop, anime\nJ-pop, cinematic pop, anime soundtrack\nJ-pop, cinematic pop, progressive house\nJ-pop, cinematic rock\nJ-pop, cinematic rock, ambient\nJ-pop, cinematic rock, anime theme\nJ-pop, cinematic rock, progressive rock\nJ-pop, cinematic synth\nJ-pop, cinematic synth, glitch dubstep\nJ-pop, cinematic synth, rock\nJ-pop, cinematic, 80s\nJ-pop, cinematic, 80s Kayōkyoku\nJ-pop, cinematic, 80s anime\nJ-pop, cinematic, 80s synth\nJ-pop, cinematic, C-pop\nJ-pop, cinematic, EDM\nJ-pop, cinematic, East Asian\nJ-pop, cinematic, East Asian fantasy\nJ-pop, cinematic, Eurobeat\nJ-pop, cinematic, J-rock\nJ-pop, cinematic, Kayōkyoku\nJ-pop, cinematic, Vocaloid\nJ-pop, cinematic, ambient\nJ-pop, cinematic, anime\nJ-pop, cinematic, anime ballad\nJ-pop, cinematic, anime soundtrack\nJ-pop, cinematic, anime theme\nJ-pop, cinematic, baroque-pop\nJ-pop, cinematic, blues-rock\nJ-pop, cinematic, breakcore\nJ-pop, cinematic, chiptune\nJ-pop, cinematic, dance-pop\nJ-pop, cinematic, disco-funk\nJ-pop, cinematic, dreamy\nJ-pop, cinematic, dubstep\nJ-pop, cinematic, electronic\nJ-pop, cinematic, emotional\nJ-pop, cinematic, erhu\nJ-pop, cinematic, ethereal\nJ-pop, cinematic, fantasy\nJ-pop, cinematic, funk\nJ-pop, cinematic, glitch\nJ-pop, cinematic, hardstyle\nJ-pop, cinematic, hip-hop\nJ-pop, cinematic, holiday\nJ-pop, cinematic, hyperpop\nJ-pop, cinematic, lo-fi\nJ-pop, cinematic, lo-fi, ambient\nJ-pop, cinematic, orchestral\nJ-pop, cinematic, pop-rock\nJ-pop, cinematic, power ballad\nJ-pop, cinematic, power-pop\nJ-pop, cinematic, progressive house\nJ-pop, cinematic, progressive metal\nJ-pop, cinematic, rock\nJ-pop, cinematic, spy theme\nJ-pop, cinematic, spy thriller\nJ-pop, cinematic, symphonic metal\nJ-pop, cinematic, symphonic rock\nJ-pop, cinematic, synth\nJ-pop, cinematic, synth funk\nJ-pop, cinematic, synthwave\nJ-pop, cinematic, taiko\nJ-pop, cinematic, traditional\nJ-pop, cinematic, traditional East Asian\nJ-pop, cinematic, traditional fusion\nJ-pop, cinematic, trance\nJ-pop, cinematic, trap\nJ-pop, cinematic, upbeat\nJ-pop, cinematic, video game\nJ-pop, cinematic, video game music\nJ-pop, cinematic, video game soundtrack\nJ-pop, cinematic, world music\nJ-pop, city pop\nJ-pop, city pop, 80s synth\nJ-pop, city pop, 80s synth-pop\nJ-pop, city pop, 90s R&B\nJ-pop, city pop, 90s hip-hop\nJ-pop, city pop, Latin pop\nJ-pop, city pop, R&B\nJ-pop, city pop, Shibuya-kei\nJ-pop, city pop, acid jazz\nJ-pop, city pop, anime\nJ-pop, city pop, anime theme\nJ-pop, city pop, anison\nJ-pop, city pop, blues-rock\nJ-pop, city pop, children's music\nJ-pop, city pop, chiptune\nJ-pop, city pop, cinematic\nJ-pop, city pop, dance pop\nJ-pop, city pop, dance-pop\nJ-pop, city pop, funk\nJ-pop, city pop, future funk\nJ-pop, city pop, jazz\nJ-pop, city pop, jazz fusion\nJ-pop, city pop, jazz-funk\nJ-pop, city pop, lo-fi\nJ-pop, city pop, neo-soul\nJ-pop, city pop, new jack swing\nJ-pop, city pop, new wave\nJ-pop, city pop, nu-disco\nJ-pop, city pop, orchestral\nJ-pop, city pop, power ballad\nJ-pop, city pop, retro synth\nJ-pop, city pop, retro-futuristic\nJ-pop, city pop, synth-funk\nJ-pop, city pop, synth-pop\nJ-pop, city pop, synthwave\nJ-pop, city pop, video game music\nJ-pop, city-pop\nJ-pop, city-pop, 80s\nJ-pop, city-pop, 80s-inspired\nJ-pop, city-pop, J-rock\nJ-pop, city-pop, anime\nJ-pop, city-pop, cinematic\nJ-pop, city-pop, electronic\nJ-pop, city-pop, funk\nJ-pop, city-pop, retro-funk\nJ-pop, city-pop, synth-pop\nJ-pop, city-pop, video game music\nJ-pop, classical, anime\nJ-pop, cloud rap, R&B\nJ-pop, cloud rap, dream pop\nJ-pop, cloud rap, trap\nJ-pop, complexro, dubstep\nJ-pop, complexro, hardcore\nJ-pop, complextro\nJ-pop, complextro, artcore\nJ-pop, complextro, cinematic\nJ-pop, complextro, dubstep\nJ-pop, complextro, future bass\nJ-pop, complextro, hardstyle\nJ-pop, conscious hip-hop\nJ-pop, country pop\nJ-pop, cyberpunk, J-rock\nJ-pop, cyberpunk, electronic\nJ-pop, cyberpunk, trance\nJ-pop, cyberpunk, trap\nJ-pop, dance, early 2000s house\nJ-pop, dance, holiday\nJ-pop, dance-pop\nJ-pop, dance-pop, 2000s\nJ-pop, dance-pop, EDM\nJ-pop, dance-pop, Eurobeat\nJ-pop, dance-pop, R&B\nJ-pop, dance-pop, anison\nJ-pop, dance-pop, cinematic\nJ-pop, dance-pop, electronic\nJ-pop, dance-pop, electropop\nJ-pop, dance-pop, funk\nJ-pop, dance-pop, future bass\nJ-pop, dance-pop, hyperpop\nJ-pop, dance-pop, orchestral\nJ-pop, dance-pop, retro\nJ-pop, dance-pop, ska\nJ-pop, dance-pop, synth-pop\nJ-pop, dancehall, Latin\nJ-pop, dancehall, cinematic\nJ-pop, dancehall, moombahton\nJ-pop, dancehall, trap\nJ-pop, denpa\nJ-pop, denpa, anime\nJ-pop, denpa, anime opening\nJ-pop, denpa, anime theme\nJ-pop, denpa, chiptune\nJ-pop, denpa, festive\nJ-pop, denpa, happy hardcore\nJ-pop, denpa, hyperpop\nJ-pop, denpa, speedcore\nJ-pop, denpa-kei\nJ-pop, denpa-kei, Vocaloid\nJ-pop, denpa-kei, chiptune\nJ-pop, denpa-kei, happy hardcore\nJ-pop, denpa-kei, hyperpop\nJ-pop, denpa-kei, idol pop\nJ-pop, denpa-kei, video game music\nJ-pop, disco, city pop\nJ-pop, disco, funk\nJ-pop, disco-funk, cinematic\nJ-pop, downtempo, ambient\nJ-pop, dream pop\nJ-pop, dream pop, hyperpop\nJ-pop, dream pop, indie rock\nJ-pop, dream pop, lo-fi\nJ-pop, dream pop, synth-pop\nJ-pop, dream pop, synthwave\nJ-pop, dream pop, trap\nJ-pop, dream trap\nJ-pop, dreamy, Vocaloid\nJ-pop, dreamy, trap\nJ-pop, drum and bass\nJ-pop, drum and bass, ambient\nJ-pop, drum and bass, breakbeat\nJ-pop, drum and bass, electronic\nJ-pop, drum and bass, retro-futuristic\nJ-pop, drum and bass, rock\nJ-pop, dubstep\nJ-pop, dubstep, complextro\nJ-pop, dubstep, glitch-hop\nJ-pop, dubstep, hardstyle\nJ-pop, early 2000s R&B\nJ-pop, educational, high-energy\nJ-pop, electro house, future bass\nJ-pop, electro, chiptune\nJ-pop, electro, disco\nJ-pop, electro-funk, chiptune\nJ-pop, electro-house, future bass\nJ-pop, electro-pop\nJ-pop, electro-pop, chiptune\nJ-pop, electro-pop, future bass\nJ-pop, electro-pop, hyperpop\nJ-pop, electro-rock, hyperpop\nJ-pop, electronic\nJ-pop, electronic ballad, anime soundtrack\nJ-pop, electronic dance\nJ-pop, electronic dance music\nJ-pop, electronic dance rock, trancecore\nJ-pop, electronic dance, anime\nJ-pop, electronic dance, chiptune\nJ-pop, electronic dance, cinematic\nJ-pop, electronic dance, dubstep\nJ-pop, electronic dance, future bass\nJ-pop, electronic dance, hardstyle\nJ-pop, electronic dance, hyperpop\nJ-pop, electronic dance, lo-fi\nJ-pop, electronic dance, matsuri\nJ-pop, electronic dance, traditional East Asian\nJ-pop, electronic dance, traditional Japanese\nJ-pop, electronic dance, traditional fusion\nJ-pop, electronic dance, trap\nJ-pop, electronic dance, video game\nJ-pop, electronic dance, video game music\nJ-pop, electronic dance, world fusion\nJ-pop, electronic pop\nJ-pop, electronic pop, anime theme\nJ-pop, electronic pop, future bass\nJ-pop, electronic rock\nJ-pop, electronic rock, anison\nJ-pop, electronic rock, hyperpop\nJ-pop, electronic, Chinese fusion\nJ-pop, electronic, K-pop\nJ-pop, electronic, R&B\nJ-pop, electronic, Vocaloid\nJ-pop, electronic, ambient\nJ-pop, electronic, anime\nJ-pop, electronic, anime theme\nJ-pop, electronic, arcade\nJ-pop, electronic, art pop\nJ-pop, electronic, art-pop\nJ-pop, electronic, artcore\nJ-pop, electronic, breakbeat\nJ-pop, electronic, celebratory\nJ-pop, electronic, chiptune\nJ-pop, electronic, cinematic\nJ-pop, electronic, cyberpunk\nJ-pop, electronic, dance-pop\nJ-pop, electronic, dream pop\nJ-pop, electronic, festival\nJ-pop, electronic, festive\nJ-pop, electronic, funk\nJ-pop, electronic, futuristic\nJ-pop, electronic, hip hop\nJ-pop, electronic, hip-hop\nJ-pop, electronic, hyperpop\nJ-pop, electronic, metalcore\nJ-pop, electronic, pop-rap\nJ-pop, electronic, rhythm game\nJ-pop, electronic, rock\nJ-pop, electronic, synthwave\nJ-pop, electronic, traditional Japanese\nJ-pop, electronic, trance\nJ-pop, electronic, trap\nJ-pop, electronic, video game\nJ-pop, electronic, video game music\nJ-pop, electronic, world fusion\nJ-pop, emo rap, trap\nJ-pop, emotional pop, future bass\nJ-pop, epic fantasy, cinematic\nJ-pop, epic, Middle Eastern\nJ-pop, ethereal\nJ-pop, experimental electronic\nJ-pop, experimental, glitch\nJ-pop, fantasy waltz\nJ-pop, fantasy, JRPG\nJ-pop, fantasy, orchestral\nJ-pop, fantasy, video game\nJ-pop, festival, chiptune\nJ-pop, festival, electronic\nJ-pop, festival, rock\nJ-pop, festive, electronic\nJ-pop, flamenco, Latin\nJ-pop, flamenco, acoustic\nJ-pop, folk ballad, cinematic rock\nJ-pop, folk, anime\nJ-pop, folk, pop-rock\nJ-pop, folk, ska\nJ-pop, folk, ukulele\nJ-pop, folk, waltz\nJ-pop, folk, world music\nJ-pop, folk-pop\nJ-pop, funk\nJ-pop, funk fusion, video game music\nJ-pop, funk, 90s hip-hop\nJ-pop, funk, Latin\nJ-pop, funk, R&B\nJ-pop, funk, anime\nJ-pop, funk, big band\nJ-pop, funk, big band jazz\nJ-pop, funk, big beat\nJ-pop, funk, chiptune\nJ-pop, funk, cinematic\nJ-pop, funk, city pop\nJ-pop, funk, city-pop\nJ-pop, funk, cyber-pop\nJ-pop, funk, dance-pop\nJ-pop, funk, disco\nJ-pop, funk, electronic\nJ-pop, funk, electronic dance\nJ-pop, funk, electronic rock\nJ-pop, funk, experimental\nJ-pop, funk, hip-hop\nJ-pop, funk, hyperpop\nJ-pop, funk, jazz\nJ-pop, funk, jazz fusion\nJ-pop, funk, musical theater\nJ-pop, funk, new jack swing\nJ-pop, funk, retro video game\nJ-pop, funk, rock\nJ-pop, funk, soul\nJ-pop, funk, video game\nJ-pop, funk, video game music\nJ-pop, funk-pop, chiptune\nJ-pop, funk-rock, video game music\nJ-pop, funky, anime\nJ-pop, future bass\nJ-pop, future bass, EDM\nJ-pop, future bass, UK garage\nJ-pop, future bass, ambient\nJ-pop, future bass, anime\nJ-pop, future bass, chiptune\nJ-pop, future bass, cinematic\nJ-pop, future bass, denpa\nJ-pop, future bass, electro-pop\nJ-pop, future bass, electronic\nJ-pop, future bass, electronic dance\nJ-pop, future bass, hardstyle\nJ-pop, future bass, hyperpop\nJ-pop, future bass, lo-fi\nJ-pop, future bass, lo-fi hip-hop\nJ-pop, future bass, video game music\nJ-pop, futuristic, cinematic\nJ-pop, futuristic, synthwave\nJ-pop, glitch, breakcore\nJ-pop, glitch, electronic\nJ-pop, glitch, lo-fi\nJ-pop, glitch-hop\nJ-pop, glitchcore, ambient\nJ-pop, gǔfēng\nJ-pop, happy hardcore\nJ-pop, happy hardcore, Chinese New Year\nJ-pop, happy hardcore, Eurobeat\nJ-pop, happy hardcore, J-core\nJ-pop, happy hardcore, Latin\nJ-pop, happy hardcore, anime\nJ-pop, happy hardcore, anime theme\nJ-pop, happy hardcore, anime-core\nJ-pop, happy hardcore, anison\nJ-pop, happy hardcore, breakcore\nJ-pop, happy hardcore, children's music\nJ-pop, happy hardcore, children's pop\nJ-pop, happy hardcore, chipbeat\nJ-pop, happy hardcore, chiptune\nJ-pop, happy hardcore, cinematic\nJ-pop, happy hardcore, cinematic synth\nJ-pop, happy hardcore, complextro\nJ-pop, happy hardcore, dance-pop\nJ-pop, happy hardcore, denpa\nJ-pop, happy hardcore, denpa-kei\nJ-pop, happy hardcore, electronic\nJ-pop, happy hardcore, electronic dance\nJ-pop, happy hardcore, festival\nJ-pop, happy hardcore, future bass\nJ-pop, happy hardcore, gabber\nJ-pop, happy hardcore, hardcore techno\nJ-pop, happy hardcore, hardstyle\nJ-pop, happy hardcore, hyper-pop\nJ-pop, happy hardcore, hyperpop\nJ-pop, happy hardcore, kawaii future bass\nJ-pop, happy hardcore, pop-rock\nJ-pop, happy hardcore, rock\nJ-pop, happy hardcore, speedcore\nJ-pop, happy hardcore, synth pop\nJ-pop, happy hardcore, traditional Japanese\nJ-pop, happy hardcore, trance\nJ-pop, happy hardcore, trancecore\nJ-pop, happy hardcore, video game music\nJ-pop, hard dance\nJ-pop, hard dance, artcore\nJ-pop, hard rock\nJ-pop, hard rock, cinematic\nJ-pop, hardcore EDM\nJ-pop, hardcore electronic\nJ-pop, hardcore electronic, speedcore\nJ-pop, hardcore techno\nJ-pop, hardcore trance\nJ-pop, hardcore, ambient\nJ-pop, hardstyle\nJ-pop, hardstyle, EDM\nJ-pop, hardstyle, ambient\nJ-pop, hardstyle, anime theme\nJ-pop, hardstyle, artcore\nJ-pop, hardstyle, dubstep\nJ-pop, hardstyle, electronic\nJ-pop, hardstyle, future bass\nJ-pop, hardstyle, happy hardcore\nJ-pop, hardstyle, speedcore\nJ-pop, hardstyle, trance\nJ-pop, hip hop\nJ-pop, hip-hop\nJ-pop, hip-hop, EDM\nJ-pop, hip-hop, J-rock\nJ-pop, hip-hop, R&B\nJ-pop, hip-hop, acid jazz\nJ-pop, hip-hop, ballad\nJ-pop, hip-hop, chiptune\nJ-pop, hip-hop, cinematic\nJ-pop, hip-hop, city pop\nJ-pop, hip-hop, dance-pop\nJ-pop, hip-hop, dancehall\nJ-pop, hip-hop, electronic\nJ-pop, hip-hop, electronic dance\nJ-pop, hip-hop, electronic rock\nJ-pop, hip-hop, emo-rock\nJ-pop, hip-hop, funk\nJ-pop, hip-hop, hardstyle\nJ-pop, hip-hop, hyperpop\nJ-pop, hip-hop, late-90s R&B\nJ-pop, hip-hop, orchestral\nJ-pop, hip-hop, pop-rock\nJ-pop, hip-hop, rock\nJ-pop, hip-hop, trap\nJ-pop, hip-hop, tropical\nJ-pop, hip-hop, video game music\nJ-pop, hyper-pop\nJ-pop, hyper-pop, Christmas\nJ-pop, hyper-pop, anime theme\nJ-pop, hyper-pop, anison\nJ-pop, hyper-pop, chiptune\nJ-pop, hyper-pop, denpa\nJ-pop, hyper-pop, denpa-kei\nJ-pop, hyper-pop, electronic\nJ-pop, hyper-pop, happy hardcore\nJ-pop, hyper-pop, idol music\nJ-pop, hyper-pop, kawaii\nJ-pop, hyperpop\nJ-pop, hyperpop, 90s dance-pop\nJ-pop, hyperpop, Christmas pop\nJ-pop, hyperpop, EDM\nJ-pop, hyperpop, Eurobeat\nJ-pop, hyperpop, Vocaloid\nJ-pop, hyperpop, ambient\nJ-pop, hyperpop, anime\nJ-pop, hyperpop, anime opening\nJ-pop, hyperpop, anime theme\nJ-pop, hyperpop, anison\nJ-pop, hyperpop, art-pop\nJ-pop, hyperpop, artcore\nJ-pop, hyperpop, breakbeat\nJ-pop, hyperpop, breakcore\nJ-pop, hyperpop, breakcore, rock\nJ-pop, hyperpop, bubblegum pop\nJ-pop, hyperpop, children's music\nJ-pop, hyperpop, chiptune\nJ-pop, hyperpop, cinematic\nJ-pop, hyperpop, cinematic electronic\nJ-pop, hyperpop, city pop\nJ-pop, hyperpop, dance\nJ-pop, hyperpop, denpa\nJ-pop, hyperpop, denpa-kei\nJ-pop, hyperpop, drum and bass\nJ-pop, hyperpop, electro\nJ-pop, hyperpop, electro-pop\nJ-pop, hyperpop, electronic\nJ-pop, hyperpop, electronic dance\nJ-pop, hyperpop, electronic rock\nJ-pop, hyperpop, emo-rap\nJ-pop, hyperpop, funk\nJ-pop, hyperpop, future bass\nJ-pop, hyperpop, happy hardcore\nJ-pop, hyperpop, hardstyle\nJ-pop, hyperpop, idol\nJ-pop, hyperpop, kawaii future bass\nJ-pop, hyperpop, lo-fi\nJ-pop, hyperpop, nightcore\nJ-pop, hyperpop, trap\nJ-pop, hyperpop, video game music\nJ-pop, idol, chiptune\nJ-pop, indie folk\nJ-pop, indie rock\nJ-pop, indie rock, city pop\nJ-pop, jazz fusion\nJ-pop, jazz fusion, Shibuya-kei\nJ-pop, jazz fusion, anime\nJ-pop, jazz fusion, art rock\nJ-pop, jazz fusion, big band\nJ-pop, jazz fusion, chiptune\nJ-pop, jazz fusion, city pop\nJ-pop, jazz fusion, funk\nJ-pop, jazz fusion, hyperpop\nJ-pop, jazz fusion, math rock\nJ-pop, jazz fusion, ska\nJ-pop, jazz fusion, video game music\nJ-pop, jazz, Shibuya-kei\nJ-pop, jazz, anime\nJ-pop, jazz, big band\nJ-pop, jazz, hip-hop\nJ-pop, jazz, orchestral\nJ-pop, jazz, swing\nJ-pop, jazz, upbeat\nJ-pop, jazz, video game music\nJ-pop, jazz-funk, city pop\nJ-pop, jazz-funk, math rock\nJ-pop, jazz-fusion\nJ-pop, jazz-fusion, art-pop\nJ-pop, kawaii future bass, chiptune\nJ-pop, kawaii future bass, denpa\nJ-pop, kawaii, Halloween\nJ-pop, kawaii, chiptune\nJ-pop, liquid drum and bass\nJ-pop, lo-fi hip hop\nJ-pop, lo-fi hip hop, J-rap\nJ-pop, lo-fi hip hop, R&B\nJ-pop, lo-fi hip hop, ambient\nJ-pop, lo-fi hip hop, chiptune\nJ-pop, lo-fi hip-hop, J-rock\nJ-pop, lo-fi pop\nJ-pop, lo-fi, Vocaloid\nJ-pop, lo-fi, ambient\nJ-pop, lo-fi, anime rock\nJ-pop, lo-fi, chiptune\nJ-pop, lo-fi, cinematic\nJ-pop, lo-fi, glitch\nJ-pop, lo-fi, pop-rock\nJ-pop, marching band, Vocaloid\nJ-pop, math rock, chiptune\nJ-pop, matsuri, electronic\nJ-pop, matsuri, enka\nJ-pop, melancholic, flamenco\nJ-pop, melancholic, hyperpop, cinematic\nJ-pop, melodic hip-hop, trap\nJ-pop, melodic trap, future bass\nJ-pop, minimal electronic, video game music\nJ-pop, minimalist, ambient\nJ-pop, musical theater\nJ-pop, musical theatre\nJ-pop, neo-soul, 90s R&B\nJ-pop, neo-soul, R&B\nJ-pop, neo-soul, ambient\nJ-pop, neo-soul, city pop\nJ-pop, neo-soul, funk\nJ-pop, new age, cinematic\nJ-pop, new jack swing\nJ-pop, new jack swing, R&B\nJ-pop, new jack swing, breakbeat\nJ-pop, new jack swing, funk\nJ-pop, new jack swing, hip-hop\nJ-pop, new jack swing, synthwave\nJ-pop, new-age, cinematic\nJ-pop, nu-disco, Shibuya-kei\nJ-pop, nu-disco, city pop\nJ-pop, nu-metal, electronic\nJ-pop, orchestral pop, anime\nJ-pop, orchestral pop, anime soundtrack\nJ-pop, orchestral pop, video game music\nJ-pop, orchestral rock\nJ-pop, orchestral, Broadway\nJ-pop, orchestral, anime soundtrack\nJ-pop, orchestral, anime theme\nJ-pop, orchestral, electronic\nJ-pop, orchestral, rock\nJ-pop, polka, anime\nJ-pop, pop\nJ-pop, pop ballad\nJ-pop, pop ballad, 2000s pop\nJ-pop, pop ballad, anime soundtrack\nJ-pop, pop, R&B\nJ-pop, pop, bilingual\nJ-pop, pop, chiptune\nJ-pop, pop, electronic\nJ-pop, pop, romantic\nJ-pop, pop, video game music\nJ-pop, pop-R&B\nJ-pop, pop-punk\nJ-pop, pop-rap, cinematic\nJ-pop, pop-rock\nJ-pop, pop-rock, EDM\nJ-pop, pop-rock, J-rock\nJ-pop, pop-rock, Vocaloid\nJ-pop, pop-rock, anime\nJ-pop, pop-rock, anime rock\nJ-pop, pop-rock, anime theme\nJ-pop, pop-rock, anison\nJ-pop, pop-rock, chiptune\nJ-pop, pop-rock, cinematic\nJ-pop, pop-rock, electronic\nJ-pop, pop-rock, festive\nJ-pop, pop-rock, future bass\nJ-pop, pop-rock, hardstyle\nJ-pop, pop-rock, hip-hop\nJ-pop, pop-rock, nu-metal\nJ-pop, pop-rock, power ballad\nJ-pop, pop-rock, ska-punk\nJ-pop, pop-rock, synth-pop\nJ-pop, pop-trap, electronic\nJ-pop, power ballad, 80s\nJ-pop, power ballad, 80s rock\nJ-pop, power ballad, Christmas\nJ-pop, power ballad, anime\nJ-pop, power ballad, anime theme\nJ-pop, power ballad, cinematic\nJ-pop, power ballad, synthwave\nJ-pop, power metal\nJ-pop, power metal, cinematic\nJ-pop, praise and worship, video game music\nJ-pop, progressive house, math rock\nJ-pop, progressive house, trance\nJ-pop, progressive house, video game music\nJ-pop, progressive rock\nJ-pop, progressive rock, classical piano\nJ-pop, progressive rock, video game music\nJ-pop, progressive trance, EDM\nJ-pop, punk rock\nJ-pop, rap, R&B\nJ-pop, reggae, chiptune\nJ-pop, reggaeton, Latin dance\nJ-pop, reggaeton, dance\nJ-pop, retro anime, theatrical\nJ-pop, retro dance-pop\nJ-pop, retro funk, city pop\nJ-pop, retro game\nJ-pop, retro synth, children's music\nJ-pop, retro video game\nJ-pop, retro video game, synth funk\nJ-pop, retro, doo-wop\nJ-pop, retro-futuristic, city pop\nJ-pop, retro-futuristic, electronic\nJ-pop, retro-futuristic, video game\nJ-pop, retro-pop, chiptune\nJ-pop, rock, anison\nJ-pop, rock, folk\nJ-pop, rock, hip-hop\nJ-pop, rockabilly, Kayōkyoku\nJ-pop, rockabilly, doo-wop\nJ-pop, salsa, Latin\nJ-pop, salsa, merengue\nJ-pop, samba, carnival\nJ-pop, samba, electronic\nJ-pop, sea shanty, anime theme\nJ-pop, shoegaze\nJ-pop, shoegaze, alternative rock\nJ-pop, shoegaze, anime\nJ-pop, shoegaze, post-rock\nJ-pop, show tune\nJ-pop, show tune, folk-pop\nJ-pop, show tune, orchestral\nJ-pop, show tune, retro\nJ-pop, show tune, vintage\nJ-pop, ska, big band\nJ-pop, ska, funk\nJ-pop, ska, polka\nJ-pop, ska, pop\nJ-pop, ska-punk\nJ-pop, ska-punk, big band\nJ-pop, ska-punk, video game music\nJ-pop, speedcore, artcore\nJ-pop, speedcore, chiptune\nJ-pop, speedcore, glitchcore\nJ-pop, speedcore, hardcore techno\nJ-pop, surf rock, anime\nJ-pop, symphonic J-rock\nJ-pop, symphonic J-rock, cinematic\nJ-pop, symphonic metal\nJ-pop, symphonic metal, J-rock\nJ-pop, symphonic metalcore\nJ-pop, symphonic pop, art-pop\nJ-pop, symphonic rock\nJ-pop, symphonic rock, Latin pop\nJ-pop, symphonic rock, anison\nJ-pop, symphonic rock, baroque\nJ-pop, symphonic rock, baroque pop\nJ-pop, symphonic rock, cinematic\nJ-pop, symphonic rock, electronic\nJ-pop, symphonic rock, electronic rock\nJ-pop, symphonic rock, glitch\nJ-pop, symphonic rock, power ballad\nJ-pop, symphonic, anime\nJ-pop, symphonic, artcore\nJ-pop, symphonic, baroque\nJ-pop, synth pop\nJ-pop, synth pop, video game music\nJ-pop, synth rock, chiptune\nJ-pop, synth-funk, video game music\nJ-pop, synth-pop\nJ-pop, synth-pop, 80s\nJ-pop, synth-pop, Eurobeat\nJ-pop, synth-pop, J-rock\nJ-pop, synth-pop, R&B\nJ-pop, synth-pop, anime\nJ-pop, synth-pop, anime soundtrack\nJ-pop, synth-pop, anime theme\nJ-pop, synth-pop, anison\nJ-pop, synth-pop, chiptune\nJ-pop, synth-pop, cinematic\nJ-pop, synth-pop, city pop\nJ-pop, synth-pop, dance-pop\nJ-pop, synth-pop, electro-pop\nJ-pop, synth-pop, electro-rock\nJ-pop, synth-pop, electronic rock\nJ-pop, synth-pop, electropop\nJ-pop, synth-pop, future bass\nJ-pop, synth-pop, futuristic\nJ-pop, synth-pop, hyperpop\nJ-pop, synth-pop, trance\nJ-pop, synth-pop, video game music\nJ-pop, synth-rock, J-rock\nJ-pop, synth-rock, chiptune\nJ-pop, synth-rock, video game music\nJ-pop, synthpop\nJ-pop, synthpop, Vocaloid\nJ-pop, synthpop, city pop\nJ-pop, synthwave, Vocaloid\nJ-pop, synthwave, chiptune\nJ-pop, synthwave, electronic\nJ-pop, synthwave, video game music\nJ-pop, taiko, festival\nJ-pop, theatrical pop, video game soundtrack\nJ-pop, theatrical, Halloween\nJ-pop, theatrical, big band\nJ-pop, theatrical, dark fairytale\nJ-pop, theatrical, jazz\nJ-pop, theatrical, orchestral\nJ-pop, theatrical, quirky\nJ-pop, theatrical, tango\nJ-pop, theatrical, traditional Japanese\nJ-pop, theatrical, video game\nJ-pop, theatrical, vintage\nJ-pop, traditional East Asian, anime\nJ-pop, traditional East Asian, electronic\nJ-pop, traditional Japanese folk\nJ-pop, traditional Japanese, hyperpop\nJ-pop, traditional Japanese, rock\nJ-pop, traditional fusion, electronic\nJ-pop, trance\nJ-pop, trance, Chinese fusion\nJ-pop, trance, EDM\nJ-pop, trance, Eurobeat\nJ-pop, trance, UK hardcore\nJ-pop, trance, Vocaloid\nJ-pop, trance, anime\nJ-pop, trance, anison\nJ-pop, trance, artcore\nJ-pop, trance, chiptune\nJ-pop, trance, cinematic\nJ-pop, trance, dance-pop\nJ-pop, trance, drum and bass\nJ-pop, trance, electronic\nJ-pop, trance, electronic rock\nJ-pop, trance, eurobeat\nJ-pop, trance, happy hardcore\nJ-pop, trance, hard dance\nJ-pop, trance, hardstyle\nJ-pop, trance, hip-hop\nJ-pop, trance, hyperpop\nJ-pop, trance, progressive house\nJ-pop, trance, rock\nJ-pop, trance, symphonic rock\nJ-pop, trance, synth-pop\nJ-pop, trance, video game\nJ-pop, trance, video game music\nJ-pop, trance-pop\nJ-pop, trance-pop, cinematic\nJ-pop, trancecore, J-rock\nJ-pop, trancecore, happy hardcore\nJ-pop, trap R&B\nJ-pop, trap, C-pop\nJ-pop, trap, EDM\nJ-pop, trap, J-rap\nJ-pop, trap, R&B\nJ-pop, trap, Vocaloid\nJ-pop, trap, ambient\nJ-pop, trap, chiptune\nJ-pop, trap, cinematic\nJ-pop, trap, dream pop\nJ-pop, trap, electronic\nJ-pop, trap, emotional\nJ-pop, trap, future bass\nJ-pop, trap, hardstyle\nJ-pop, trap, hyperpop\nJ-pop, trap, orchestral\nJ-pop, trip-hop, downtempo\nJ-pop, trip-hop, electronic\nJ-pop, tropical house, hip-hop\nJ-pop, tropical, Latin\nJ-pop, tropical, electronic\nJ-pop, tropical, video game\nJ-pop, upbeat, electronic\nJ-pop, video game\nJ-pop, video game music\nJ-pop, video game music, 90s electronic\nJ-pop, video game music, Christmas\nJ-pop, video game music, East Asian fusion\nJ-pop, video game music, Halloween\nJ-pop, video game music, J-rock\nJ-pop, video game music, Latin percussion\nJ-pop, video game music, Vocaloid\nJ-pop, video game music, anime\nJ-pop, video game music, art pop\nJ-pop, video game music, art-pop\nJ-pop, video game music, artcore\nJ-pop, video game music, big band jazz\nJ-pop, video game music, children's music\nJ-pop, video game music, chiptune\nJ-pop, video game music, city pop\nJ-pop, video game music, dance-pop\nJ-pop, video game music, dreamy\nJ-pop, video game music, electronic\nJ-pop, video game music, electronic dance\nJ-pop, video game music, epic\nJ-pop, video game music, festive\nJ-pop, video game music, funk\nJ-pop, video game music, funk fusion\nJ-pop, video game music, funk-rock\nJ-pop, video game music, happy hardcore\nJ-pop, video game music, idol pop\nJ-pop, video game music, instrumental\nJ-pop, video game music, jazz fusion\nJ-pop, video game music, lo-fi\nJ-pop, video game music, orchestral\nJ-pop, video game music, pop-rock\nJ-pop, video game music, progressive rock\nJ-pop, video game music, rock\nJ-pop, video game music, symphonic rock\nJ-pop, video game music, synth funk\nJ-pop, video game music, synth pop\nJ-pop, video game music, synth-funk\nJ-pop, video game music, synth-pop\nJ-pop, video game music, synthpop\nJ-pop, video game music, synthwave\nJ-pop, video game music, upbeat\nJ-pop, video game music, upbeat pop\nJ-pop, video game music, upbeat synth\nJ-pop, video game soundtrack\nJ-pop, video game soundtrack, ambient\nJ-pop, video game soundtrack, bossa nova\nJ-pop, video game soundtrack, chiptune\nJ-pop, video game soundtrack, cinematic\nJ-pop, video game soundtrack, electronic\nJ-pop, video game soundtrack, energetic\nJ-pop, video game soundtrack, festive\nJ-pop, video game soundtrack, instrumental\nJ-pop, video game soundtrack, lo-fi\nJ-pop, video game soundtrack, orchestral\nJ-pop, video game soundtrack, orchestral electronic\nJ-pop, video game soundtrack, orchestral pop\nJ-pop, video game soundtrack, piano instrumental\nJ-pop, video game soundtrack, pop\nJ-pop, video game soundtrack, pop-rock\nJ-pop, video game soundtrack, synthwave\nJ-pop, video game soundtrack, theatrical\nJ-pop, video game soundtrack, theatrical pop\nJ-pop, video game soundtrack, trance\nJ-pop, video game soundtrack, upbeat\nJ-pop, video game soundtrack, upbeat synth\nJ-pop, video game soundtrack, uplifting\nJ-pop, video game theme\nJ-pop, video game, Halloween\nJ-pop, video game, ambient\nJ-pop, video game, breakbeat\nJ-pop, video game, dance-pop\nJ-pop, video game, electronic\nJ-pop, video game, festive\nJ-pop, video game, funk\nJ-pop, video game, lo-fi\nJ-pop, video game, pop\nJ-pop, video game, rock\nJ-pop, video game, synthwave\nJ-pop, video game, upbeat\nJ-pop, vintage rock, surf rock\nJ-pop, world fusion, electronic\nJ-pop, world music fusion, J-rock\nJ-pop, world music, ambient\nJ-pop, world music, synth fusion\nJ-pop, world music, video game soundtrack\nJ-rap\nJ-rap J-rock\nJ-rap anime\nJ-rap chiptune\nJ-rap chiptune trap\nJ-rap dancehall\nJ-rap electro house\nJ-rap electronic\nJ-rap funk city pop\nJ-rap hardstyle\nJ-rap hardstyle trap\nJ-rap house\nJ-rap hyperpop\nJ-rap hyperpop artcore\nJ-rap hyperpop chiptune\nJ-rap reggae\nJ-rap trap\nJ-rap trap chiptune\nJ-rap trap dancehall\nJ-rap trap pop\nJ-rap, Latin electronic\nJ-rap, Latin hip hop\nJ-rap, chiptune, trap\nJ-rap, cinematic, electronic\nJ-rap, club, electronic\nJ-rap, cyberpunk, chiptune\nJ-rap, electronic, pirate\nJ-rap, electronic, video game music\nJ-rap, festival, electronic\nJ-rap, hyperpop, artcore\nJ-rap, hyperpop, breakbeat\nJ-rap, hyperpop, chiptune\nJ-rap, lo-fi hip-hop, drum and bass\nJ-rap, trap, chiptune\nJ-rap, trap, cyberpunk\nJ-rap, trap, futuristic\nJ-rap, trap, hyperpop\nJ-reggae\nJ-reggae Christmas\nJ-reggae city pop\nJ-reggae dancehall\nJ-reggae lovers rock\nJ-reggaeton\nJ-rock\nJ-rock Arabic rock fusion\nJ-rock Bhangra fusion\nJ-rock C-pop\nJ-rock C-pop anime\nJ-rock C-pop anime rock\nJ-rock C-pop anime theme\nJ-rock C-pop ballad\nJ-rock C-pop cinematic\nJ-rock C-pop electronic rock\nJ-rock C-pop epic rock\nJ-rock C-pop fusion\nJ-rock C-pop rock\nJ-rock C-rock\nJ-rock C-rock fusion\nJ-rock Canto-rock\nJ-rock Canto-rock power rock\nJ-rock Cantopop\nJ-rock Cantopop fusion\nJ-rock Cantopop hyperpop\nJ-rock Celtic folk\nJ-rock Celtic fusion\nJ-rock Christian pop\nJ-rock City Pop\nJ-rock Dangdut Koplo\nJ-rock EDM\nJ-rock Eurobeat\nJ-rock Eurodance\nJ-rock J-pop\nJ-rock Javanese pop\nJ-rock K-pop\nJ-rock K-pop fusion\nJ-rock K-pop hybrid\nJ-rock K-pop rock\nJ-rock K-rock\nJ-rock K-rock fusion\nJ-rock Kayōkyoku\nJ-rock Latin folk\nJ-rock Latin fusion\nJ-rock Latin jazz\nJ-rock Latin pop-rock\nJ-rock Latin rock\nJ-rock Nintendocore\nJ-rock Vocaloid\nJ-rock acoustic\nJ-rock acoustic pop\nJ-rock alternative\nJ-rock alternative hip-hop\nJ-rock alternative metal\nJ-rock alternative rock\nJ-rock ambient\nJ-rock ambient pop\nJ-rock ambient rock\nJ-rock anime\nJ-rock anime ballad\nJ-rock anime metal\nJ-rock anime opening\nJ-rock anime pop\nJ-rock anime pop rock\nJ-rock anime pop-punk\nJ-rock anime pop-rock\nJ-rock anime power ballad\nJ-rock anime power pop\nJ-rock anime power rock\nJ-rock anime power-pop\nJ-rock anime punk\nJ-rock anime rock\nJ-rock anime soundtrack\nJ-rock anime theme\nJ-rock anime-core\nJ-rock anime-core lo-fi\nJ-rock anison\nJ-rock anison Eurobeat\nJ-rock anison chiptune\nJ-rock anison dance-pop\nJ-rock anison denpa\nJ-rock anison electronic\nJ-rock anison funk-rock\nJ-rock anison metalcore\nJ-rock anison power metal\nJ-rock anison symphonic\nJ-rock anison symphonic metal\nJ-rock anison trance\nJ-rock anisong\nJ-rock anisong electronic\nJ-rock anisong symphonic metal\nJ-rock arena rock\nJ-rock art pop\nJ-rock art rock\nJ-rock art rock math rock\nJ-rock art-pop\nJ-rock artcore\nJ-rock artcore denpa\nJ-rock artcore speedcore\nJ-rock avant-garde\nJ-rock ballad\nJ-rock ballad alternative rock\nJ-rock ballad, symphonic metal\nJ-rock big band\nJ-rock big band swing\nJ-rock big band video game\nJ-rock bluegrass fusion\nJ-rock blues\nJ-rock blues-rock\nJ-rock boogie-woogie\nJ-rock boogie-woogie Latin jazz\nJ-rock breakbeat\nJ-rock breakcore\nJ-rock breakcore chiptune\nJ-rock cabaret\nJ-rock chiptune\nJ-rock chiptune anime\nJ-rock chiptune anison\nJ-rock chiptune art rock\nJ-rock chiptune artcore\nJ-rock chiptune baroque\nJ-rock chiptune electronic\nJ-rock chiptune electronic rock\nJ-rock chiptune fusion\nJ-rock chiptune hardcore\nJ-rock chiptune hyperpop\nJ-rock chiptune jazz fusion\nJ-rock chiptune math rock\nJ-rock chiptune metal\nJ-rock chiptune metalcore\nJ-rock chiptune orchestral\nJ-rock chiptune power metal\nJ-rock chiptune progressive house\nJ-rock chiptune progressive metal\nJ-rock chiptune rap-metal\nJ-rock chiptune symphonic\nJ-rock chiptune symphonic metal\nJ-rock chiptune synth rock\nJ-rock chiptune synth-pop\nJ-rock cinematic\nJ-rock cinematic pop\nJ-rock circus\nJ-rock city pop\nJ-rock city pop Latin\nJ-rock city pop R&B\nJ-rock city pop anime\nJ-rock city pop anisong\nJ-rock city pop big band\nJ-rock city pop disco\nJ-rock city pop funk\nJ-rock city pop jazz fusion\nJ-rock city pop jazz-funk\nJ-rock city pop jazz-fusion\nJ-rock city pop rockabilly\nJ-rock city pop ska\nJ-rock city pop surf rock\nJ-rock city pop synth-pop\nJ-rock city-pop\nJ-rock complextro\nJ-rock country folk-rock\nJ-rock cumbia folk\nJ-rock cyber metal\nJ-rock cyberpunk\nJ-rock cyberpunk synth-pop\nJ-rock dance-pop\nJ-rock dance-punk\nJ-rock dancehall\nJ-rock dangdut koplo\nJ-rock denpa\nJ-rock denpa anime\nJ-rock denpa artcore\nJ-rock denpa chiptune\nJ-rock denpa-kei\nJ-rock digital hardcore\nJ-rock dream pop\nJ-rock drum and bass\nJ-rock dubstep\nJ-rock electronic\nJ-rock electronic artcore\nJ-rock electronic chiptune\nJ-rock electronic dance\nJ-rock electronic fusion\nJ-rock electronic hip-hop\nJ-rock electronic pop\nJ-rock electronic rock\nJ-rock electronic trap\nJ-rock electronicore\nJ-rock electronicore chiptune\nJ-rock electronicore lo-fi\nJ-rock electropop\nJ-rock emo\nJ-rock emo alternative\nJ-rock emo math rock\nJ-rock emo rap\nJ-rock emo rock\nJ-rock emo-pop\nJ-rock emo-rap\nJ-rock emo-rock\nJ-rock emo-trap\nJ-rock epic\nJ-rock experimental\nJ-rock festival\nJ-rock festival anthem\nJ-rock festival folk\nJ-rock festival rock\nJ-rock flamenco\nJ-rock flamenco fusion\nJ-rock folk\nJ-rock folk country\nJ-rock folk metal\nJ-rock folk-metal\nJ-rock folk-pop\nJ-rock folk-punk\nJ-rock folk-rock\nJ-rock funk\nJ-rock funk Latin\nJ-rock funk acid jazz\nJ-rock funk alternative\nJ-rock funk anime\nJ-rock funk anison\nJ-rock funk big band\nJ-rock funk big beat\nJ-rock funk blues\nJ-rock funk blues-rock\nJ-rock funk breakbeat\nJ-rock funk chiptune\nJ-rock funk city pop\nJ-rock funk disco\nJ-rock funk electronic\nJ-rock funk fusion\nJ-rock funk hip-hop\nJ-rock funk jazz fusion\nJ-rock funk math rock\nJ-rock funk metal\nJ-rock funk pop\nJ-rock funk pop-punk\nJ-rock funk reggae\nJ-rock funk rock\nJ-rock funk ska\nJ-rock funk ska-punk\nJ-rock funk soul\nJ-rock funk surf rock\nJ-rock funk synth-pop\nJ-rock funk video game\nJ-rock funk video game music\nJ-rock funk-metal\nJ-rock funk-pop\nJ-rock funk-punk\nJ-rock funk-rap\nJ-rock funk-rock\nJ-rock fusion\nJ-rock future bass\nJ-rock garage rock\nJ-rock glam metal\nJ-rock glam punk\nJ-rock gospel\nJ-rock gospel pop\nJ-rock gothic\nJ-rock gothic anime\nJ-rock gypsy jazz\nJ-rock gypsy jazz polka\nJ-rock gypsy-jazz\nJ-rock gǔfēng\nJ-rock happy hardcore\nJ-rock hard rock\nJ-rock hard trance\nJ-rock hardcore electronic\nJ-rock hardcore punk\nJ-rock hardcore techno\nJ-rock hardstyle\nJ-rock hip-hop\nJ-rock hip-hop C-pop\nJ-rock hip-hop crossover\nJ-rock hip-hop funk\nJ-rock hip-hop fusion\nJ-rock hyper-funk\nJ-rock hyper-pop\nJ-rock hyper-punk\nJ-rock hyperpop\nJ-rock hyperpop anime\nJ-rock hyperpop anison\nJ-rock hyperpop artcore\nJ-rock hyperpop breakcore\nJ-rock hyperpop chiptune\nJ-rock hyperpop denpa\nJ-rock hyperpop electronic\nJ-rock hyperpop emo\nJ-rock hyperpop funk\nJ-rock hyperpop idol\nJ-rock hyperpop math rock\nJ-rock hyperpop speedcore\nJ-rock idol pop\nJ-rock idol-pop\nJ-rock indie folk\nJ-rock indie pop\nJ-rock indie rock\nJ-rock industrial\nJ-rock industrial metal\nJ-rock jazz\nJ-rock jazz fusion\nJ-rock jazz piano rock\nJ-rock jazz-funk\nJ-rock jazz-fusion\nJ-rock jazz-punk\nJ-rock jazz-rock\nJ-rock kawaii\nJ-rock kawaii metal\nJ-rock lo-fi\nJ-rock lo-fi chiptune\nJ-rock lo-fi hip-hop\nJ-rock math rock\nJ-rock math rock chiptune\nJ-rock math rock city pop\nJ-rock math rock funk\nJ-rock math rock jazz fusion\nJ-rock math rock progressive metal\nJ-rock math rock progressive rock\nJ-rock math rock video game music\nJ-rock math-rock\nJ-rock math-rock chiptune\nJ-rock math-rock post-hardcore\nJ-rock mathcore\nJ-rock melodic hardcore\nJ-rock metal\nJ-rock metal fusion\nJ-rock metalcore\nJ-rock metalcore anison\nJ-rock metalcore chiptune\nJ-rock metalcore denpa\nJ-rock metalcore denpa-kei\nJ-rock metalcore electronic\nJ-rock metalcore electronicore\nJ-rock metalcore hyperpop\nJ-rock metalcore lo-fi\nJ-rock metalcore symphonic\nJ-rock metalcore trance\nJ-rock metalcore trancecore\nJ-rock metalcore video game\nJ-rock min'yō\nJ-rock musical theater\nJ-rock neoclassical metal chiptune\nJ-rock neoclassical power metal\nJ-rock noise rock\nJ-rock nu-metal\nJ-rock nu-metal alternative\nJ-rock nu-metal chiptune\nJ-rock nu-metal electronic\nJ-rock nu-metal rap-rock\nJ-rock orchestral\nJ-rock orchestral pop\nJ-rock orchestral trance\nJ-rock piano rock\nJ-rock pop\nJ-rock pop ballad\nJ-rock pop-ballad\nJ-rock pop-ballad cinematic\nJ-rock pop-funk\nJ-rock pop-punk\nJ-rock pop-punk emo\nJ-rock pop-punk indie rock\nJ-rock pop-punk rap-rock\nJ-rock pop-rap\nJ-rock pop-rock\nJ-rock pop-rock cinematic\nJ-rock pop-rock math-rock\nJ-rock post-hardcore\nJ-rock post-rock\nJ-rock power ballad\nJ-rock power metal\nJ-rock power metal anison\nJ-rock power metal chiptune\nJ-rock power metal symphonic\nJ-rock power pop\nJ-rock power pop video game\nJ-rock power-pop\nJ-rock praise\nJ-rock progressive\nJ-rock progressive math rock\nJ-rock progressive metal\nJ-rock progressive metal chiptune\nJ-rock progressive metal symphonic rock\nJ-rock progressive metalcore\nJ-rock progressive pop\nJ-rock progressive rock\nJ-rock progressive rock orchestral\nJ-rock progressive rock video game music\nJ-rock punk\nJ-rock punk rock\nJ-rock rap\nJ-rock rap fusion\nJ-rock rap-metal\nJ-rock rap-rock\nJ-rock rap-rock electronic\nJ-rock rap-rock fusion\nJ-rock rapcore\nJ-rock reggae\nJ-rock reggae ska\nJ-rock rockabilly\nJ-rock rockabilly surf rock\nJ-rock salsa\nJ-rock shoegaze\nJ-rock shoegaze alternative rock\nJ-rock shoegaze chiptune\nJ-rock shoegaze dream pop\nJ-rock singer-songwriter\nJ-rock ska Latin\nJ-rock ska Latin rock\nJ-rock ska anison\nJ-rock ska reggae\nJ-rock ska surf rock\nJ-rock ska-punk\nJ-rock ska-punk big band\nJ-rock ska-punk festival anthem\nJ-rock ska-punk hip-hop\nJ-rock ska-punk reggae\nJ-rock skate punk\nJ-rock soulful\nJ-rock speed metal\nJ-rock speedcore\nJ-rock speedcore chiptune\nJ-rock speedcore glitchcore\nJ-rock stadium anthem\nJ-rock surf punk\nJ-rock surf rock\nJ-rock surf rock big band\nJ-rock surf-pop\nJ-rock symphonic\nJ-rock symphonic J-pop\nJ-rock symphonic artcore\nJ-rock symphonic chiptune\nJ-rock symphonic drum & bass\nJ-rock symphonic electronic\nJ-rock symphonic electronica\nJ-rock symphonic metal\nJ-rock symphonic metal anison\nJ-rock symphonic metal chiptune\nJ-rock symphonic metal power metal\nJ-rock symphonic metalcore\nJ-rock symphonic pop\nJ-rock symphonic pop-rock\nJ-rock symphonic power metal\nJ-rock symphonic rock\nJ-rock symphonic rock video game music\nJ-rock symphonic trance\nJ-rock synth-pop\nJ-rock synth-rock\nJ-rock synthwave\nJ-rock synthwave video game\nJ-rock technical funk\nJ-rock technical metal\nJ-rock techno\nJ-rock trance\nJ-rock trance artcore\nJ-rock trancecore\nJ-rock trap\nJ-rock trap R&B\nJ-rock trap electronic\nJ-rock trap metal\nJ-rock trap-rock\nJ-rock vaporwave\nJ-rock video game\nJ-rock video game metal\nJ-rock video game music\nJ-rock visual kei\nJ-rock world fusion\nJ-rock world music\nJ-rock worship\nJ-rock, 90s video game music\nJ-rock, Americana, Mandarin rock\nJ-rock, Anisong\nJ-rock, Anisong, symphonic metal\nJ-rock, Anisong, trance\nJ-rock, Brazilian carnival, pop-punk\nJ-rock, C-pop\nJ-rock, C-pop fusion\nJ-rock, C-pop rock\nJ-rock, C-pop rock, glitch-hop\nJ-rock, C-pop, ambient\nJ-rock, C-pop, anime rock\nJ-rock, C-pop, chiptune\nJ-rock, C-pop, cinematic\nJ-rock, C-pop, cinematic rock\nJ-rock, C-pop, dream pop\nJ-rock, C-pop, electronic\nJ-rock, C-pop, electronic rock\nJ-rock, C-pop, fusion\nJ-rock, C-pop, glitch\nJ-rock, C-pop, jazz fusion\nJ-rock, C-pop, lo-fi\nJ-rock, C-pop, symphonic rock\nJ-rock, C-pop, synthpop\nJ-rock, C-pop, traditional fusion\nJ-rock, C-pop, video game soundtrack\nJ-rock, Celtic folk\nJ-rock, Chinese New Year\nJ-rock, Chinese folk\nJ-rock, Chinese folk fusion\nJ-rock, Chinese folk, Vocaloid\nJ-rock, Chinese folk, anime\nJ-rock, Chinese folk, anime rock\nJ-rock, Chinese folk, anime theme\nJ-rock, Chinese folk, epic\nJ-rock, Chinese folk, epic rock\nJ-rock, Chinese folk, fusion\nJ-rock, Chinese folk, rock\nJ-rock, Chinese fusion\nJ-rock, Chinese fusion, anime\nJ-rock, Chinese fusion, anime rock\nJ-rock, Chinese fusion, anime soundtrack\nJ-rock, Chinese fusion, chiptune\nJ-rock, Chinese fusion, cinematic rock\nJ-rock, Christian metalcore\nJ-rock, Christian rap, cinematic\nJ-rock, Christmas\nJ-rock, City Pop\nJ-rock, EDM\nJ-rock, EDM, rap\nJ-rock, East Asian folk\nJ-rock, East Asian fusion\nJ-rock, Enka, anthemic\nJ-rock, Enka, cinematic\nJ-rock, Enka, cinematic rock\nJ-rock, Eurobeat\nJ-rock, Eurobeat, Anisong\nJ-rock, Eurobeat, anime\nJ-rock, Eurobeat, anime theme\nJ-rock, Eurobeat, chiptune\nJ-rock, Eurobeat, dance-pop\nJ-rock, Eurobeat, happy hardcore\nJ-rock, Eurobeat, orchestral\nJ-rock, Eurobeat, trance\nJ-rock, Eurobeat, video game music\nJ-rock, German punk\nJ-rock, J-pop, Enka\nJ-rock, J-pop, J-core\nJ-rock, K-hip-hop, electronic\nJ-rock, K-pop, hip-hop\nJ-rock, Kayōkyoku\nJ-rock, Kayōkyoku, Enka\nJ-rock, Kayōkyoku, big band\nJ-rock, Kayōkyoku, cinematic rock\nJ-rock, Kayōkyoku, theatrical\nJ-rock, Kayōkyoku, theatrical rock\nJ-rock, Korean folk\nJ-rock, Latin Christian, anthemic\nJ-rock, Latin acoustic\nJ-rock, Latin dance, electronic\nJ-rock, Latin fusion\nJ-rock, Latin fusion, funk\nJ-rock, Latin percussion\nJ-rock, Latin percussion, Vocaloid\nJ-rock, Latin pop, anthemic\nJ-rock, Latin pop, pop-rock\nJ-rock, Latin rock, electronic\nJ-rock, Latin rock, flamenco rock\nJ-rock, Latin rock, tango\nJ-rock, Latin, electronic\nJ-rock, Latin, ska\nJ-rock, Latin-rock fusion\nJ-rock, Middle Eastern fusion\nJ-rock, Middle Eastern, cinematic\nJ-rock, Nintendocore\nJ-rock, Nintendocore, metalcore\nJ-rock, Nintendocore, pop-punk\nJ-rock, R&B, J-pop\nJ-rock, Spanish-style, electronic\nJ-rock, Turkish folk, anime theme\nJ-rock, UK Hardcore\nJ-rock, UK hardcore, electronic\nJ-rock, UK hardcore, electronic rock\nJ-rock, Vocaloid\nJ-rock, Vocaloid, chiptune\nJ-rock, Vocaloid, cinematic\nJ-rock, Vocaloid, denpa-kei\nJ-rock, Vocaloid, metalcore\nJ-rock, Vocaloid, speedcore\nJ-rock, alternative metal\nJ-rock, ambient, Vocaloid\nJ-rock, ambient, breakcore\nJ-rock, ambient, chiptune\nJ-rock, ambient, drum and bass\nJ-rock, ambient, hyperpop\nJ-rock, anime\nJ-rock, anime anthem\nJ-rock, anime ballad\nJ-rock, anime ballad, power ballad\nJ-rock, anime music\nJ-rock, anime pop\nJ-rock, anime pop rock\nJ-rock, anime pop, Christian pop\nJ-rock, anime pop-rock\nJ-rock, anime power ballad\nJ-rock, anime power ballad, C-pop\nJ-rock, anime power ballad, cinematic C-pop\nJ-rock, anime power ballad, cinematic pop\nJ-rock, anime power metal, C-pop\nJ-rock, anime power metal, Chinese folk fusion\nJ-rock, anime power pop\nJ-rock, anime power pop, lo-fi\nJ-rock, anime power-pop, C-pop\nJ-rock, anime power-pop, cinematic\nJ-rock, anime rock\nJ-rock, anime rock, C-pop\nJ-rock, anime rock, cinematic\nJ-rock, anime rock, cinematic rock\nJ-rock, anime rock, video game music\nJ-rock, anime soundtrack\nJ-rock, anime soundtrack, C-pop\nJ-rock, anime soundtrack, cinematic\nJ-rock, anime soundtrack, emotional ballad\nJ-rock, anime soundtrack, instrumental\nJ-rock, anime soundtrack, lo-fi hip hop\nJ-rock, anime soundtrack, power ballad\nJ-rock, anime style\nJ-rock, anime theme\nJ-rock, anime theme, C-pop\nJ-rock, anime theme, baroque pop\nJ-rock, anime theme, big band\nJ-rock, anime theme, children's music\nJ-rock, anime theme, chiptune\nJ-rock, anime theme, cinematic\nJ-rock, anime theme, cinematic rock\nJ-rock, anime theme, classical fusion\nJ-rock, anime theme, electronic\nJ-rock, anime theme, funk-rock\nJ-rock, anime theme, metal\nJ-rock, anime theme, metalcore\nJ-rock, anime theme, musical theater\nJ-rock, anime theme, piano ballad\nJ-rock, anime theme, power ballad\nJ-rock, anime theme, rock\nJ-rock, anime theme, traditional Japanese\nJ-rock, anime, C-pop\nJ-rock, anime, Cantonese pop\nJ-rock, anime, Christmas\nJ-rock, anime, Mandarin pop\nJ-rock, anime, Mandarin rock\nJ-rock, anime, ballad\nJ-rock, anime, children's\nJ-rock, anime, cinematic\nJ-rock, anime, electronic\nJ-rock, anime, high-energy\nJ-rock, anime, hip hop\nJ-rock, anime, hip-hop\nJ-rock, anime, instrumental\nJ-rock, anime, lo-fi\nJ-rock, anime, metalcore\nJ-rock, anime, orchestral\nJ-rock, anime, pop\nJ-rock, anime, power ballad\nJ-rock, anime, power-pop\nJ-rock, anime, rock\nJ-rock, anime-style\nJ-rock, anime-style, synth-pop\nJ-rock, anison, city pop\nJ-rock, anison, dance-pop\nJ-rock, anison, electronic\nJ-rock, anison, happy hardcore\nJ-rock, anison, hyperpop\nJ-rock, anison, pop-punk\nJ-rock, anison, power metal\nJ-rock, anison, synth-rock\nJ-rock, anison, trance\nJ-rock, art pop, electronic\nJ-rock, art-pop, hyperpop\nJ-rock, artcore, breakcore\nJ-rock, ballad\nJ-rock, baroque pop\nJ-rock, baroque, anime\nJ-rock, baroque, cinematic\nJ-rock, big band jazz\nJ-rock, big band jazz fusion\nJ-rock, big band jazz, video game music\nJ-rock, big band ska\nJ-rock, big band swing\nJ-rock, big band, anime rock\nJ-rock, big band, anime theme\nJ-rock, big band, fusion\nJ-rock, big band, video game music\nJ-rock, bluegrass\nJ-rock, boogie-woogie\nJ-rock, breakbeat\nJ-rock, breakbeat, electronic\nJ-rock, breakbeat, electronica\nJ-rock, breakcore\nJ-rock, breakcore, Vocaloid\nJ-rock, breakcore, denpa-kei\nJ-rock, breakcore, electronic\nJ-rock, breakcore, glitch\nJ-rock, breakcore, glitch-hop\nJ-rock, cabaret, cinematic\nJ-rock, chiptune\nJ-rock, chiptune, C-pop\nJ-rock, chiptune, Vocaloid\nJ-rock, chiptune, ambient\nJ-rock, chiptune, anime\nJ-rock, chiptune, anime rock\nJ-rock, chiptune, anime theme\nJ-rock, chiptune, artcore\nJ-rock, chiptune, cinematic\nJ-rock, chiptune, denpa\nJ-rock, chiptune, digital hardcore\nJ-rock, chiptune, dream pop\nJ-rock, chiptune, electronic\nJ-rock, chiptune, heavy metal\nJ-rock, chiptune, hyperpop\nJ-rock, chiptune, indie pop\nJ-rock, chiptune, instrumental rock\nJ-rock, chiptune, jazz-fusion\nJ-rock, chiptune, lo-fi\nJ-rock, chiptune, metal\nJ-rock, chiptune, metalcore\nJ-rock, chiptune, power ballad\nJ-rock, chiptune, progressive metal\nJ-rock, chiptune, progressive rock\nJ-rock, chiptune, rock\nJ-rock, chiptune, speed metal\nJ-rock, chiptune, symphonic\nJ-rock, chiptune, symphonic metal\nJ-rock, chiptune, synth-pop\nJ-rock, chiptune, video game music\nJ-rock, cinematic\nJ-rock, cinematic ballad\nJ-rock, cinematic metal\nJ-rock, cinematic orchestral\nJ-rock, cinematic piano\nJ-rock, cinematic pop\nJ-rock, cinematic pop, ambient\nJ-rock, cinematic pop, anime soundtrack\nJ-rock, cinematic pop, synth rock\nJ-rock, cinematic rock\nJ-rock, cinematic rock, C-pop\nJ-rock, cinematic rock, Chinese fusion\nJ-rock, cinematic rock, anime\nJ-rock, cinematic rock, anime theme\nJ-rock, cinematic rock, video game soundtrack\nJ-rock, cinematic synth\nJ-rock, cinematic synth, 80s anime\nJ-rock, cinematic synth-orchestral\nJ-rock, cinematic, 80s anime\nJ-rock, cinematic, C-pop\nJ-rock, cinematic, Chinese opera\nJ-rock, cinematic, Chinese style\nJ-rock, cinematic, Chinese traditional\nJ-rock, cinematic, EDM\nJ-rock, cinematic, East Asian\nJ-rock, cinematic, East Asian fantasy\nJ-rock, cinematic, Kayōkyoku\nJ-rock, cinematic, Mandarin pop\nJ-rock, cinematic, RPG soundtrack\nJ-rock, cinematic, Vocaloid\nJ-rock, cinematic, ambient\nJ-rock, cinematic, ancient style\nJ-rock, cinematic, anime\nJ-rock, cinematic, anime opening\nJ-rock, cinematic, anime soundtrack\nJ-rock, cinematic, anime theme\nJ-rock, cinematic, anison\nJ-rock, cinematic, ballad\nJ-rock, cinematic, breakcore\nJ-rock, cinematic, chiptune\nJ-rock, cinematic, city-pop\nJ-rock, cinematic, electronic\nJ-rock, cinematic, emotional\nJ-rock, cinematic, epic\nJ-rock, cinematic, fantasy\nJ-rock, cinematic, folk fusion\nJ-rock, cinematic, funk\nJ-rock, cinematic, fusion\nJ-rock, cinematic, futuristic\nJ-rock, cinematic, glitch\nJ-rock, cinematic, guzheng\nJ-rock, cinematic, guzheng fusion\nJ-rock, cinematic, hardcore\nJ-rock, cinematic, hardstyle\nJ-rock, cinematic, hip-hop\nJ-rock, cinematic, industrial rock\nJ-rock, cinematic, lo-fi\nJ-rock, cinematic, lo-fi hip hop\nJ-rock, cinematic, melancholic\nJ-rock, cinematic, metal\nJ-rock, cinematic, metalcore\nJ-rock, cinematic, neo-classical\nJ-rock, cinematic, nu-metal\nJ-rock, cinematic, operatic\nJ-rock, cinematic, orchestral\nJ-rock, cinematic, post-hardcore\nJ-rock, cinematic, power ballad\nJ-rock, cinematic, progressive metal\nJ-rock, cinematic, punk rock\nJ-rock, cinematic, rap-rock\nJ-rock, cinematic, symphonic\nJ-rock, cinematic, symphonic metal\nJ-rock, cinematic, symphonic rock\nJ-rock, cinematic, synth-pop\nJ-rock, cinematic, synthwave\nJ-rock, cinematic, traditional East Asian\nJ-rock, cinematic, traditional Japanese\nJ-rock, cinematic, trance\nJ-rock, cinematic, video game\nJ-rock, cinematic, video game music\nJ-rock, cinematic, world music\nJ-rock, cinematic, wuxia\nJ-rock, city pop\nJ-rock, city pop, 80s\nJ-rock, city pop, AOR\nJ-rock, city pop, anime\nJ-rock, city pop, anime theme\nJ-rock, city pop, anison\nJ-rock, city pop, ballad\nJ-rock, city pop, baroque pop\nJ-rock, city pop, big band\nJ-rock, city pop, boogie-woogie\nJ-rock, city pop, funk\nJ-rock, city pop, funk rock\nJ-rock, city pop, jazz\nJ-rock, city pop, jazz fusion\nJ-rock, city pop, synth-pop\nJ-rock, classic rock, blues-rock\nJ-rock, complextro\nJ-rock, complextro, chiptune\nJ-rock, country, folk\nJ-rock, denpa, anime\nJ-rock, denpa-kei\nJ-rock, denpa-kei, anime theme\nJ-rock, denpa-kei, anime-core\nJ-rock, denpa-kei, chiptune\nJ-rock, digital hardcore\nJ-rock, digital hardcore, hyperpop\nJ-rock, drum and bass\nJ-rock, drum and bass, cinematic\nJ-rock, dubstep\nJ-rock, dubstep, electronic\nJ-rock, electronic\nJ-rock, electronic dance\nJ-rock, electronic dance, Middle Eastern fusion\nJ-rock, electronic dance, anime\nJ-rock, electronic dance, anime theme\nJ-rock, electronic dance, dubstep\nJ-rock, electronic dance, high-energy\nJ-rock, electronic dance, hip hop\nJ-rock, electronic dance, hyperpop\nJ-rock, electronic dance, matsuri\nJ-rock, electronic dance, world fusion\nJ-rock, electronic metal, metalcore\nJ-rock, electronic rock, C-pop\nJ-rock, electronic rock, synth-pop\nJ-rock, electronic rock, traditional Japanese\nJ-rock, electronic, anime opening\nJ-rock, electronic, anime theme\nJ-rock, electronic, anison\nJ-rock, electronic, anisong\nJ-rock, electronic, art-pop\nJ-rock, electronic, artcore\nJ-rock, electronic, breakcore\nJ-rock, electronic, chiptune\nJ-rock, electronic, cinematic\nJ-rock, electronic, dance\nJ-rock, electronic, dance-pop\nJ-rock, electronic, digital hardcore\nJ-rock, electronic, dubstep\nJ-rock, electronic, folk fusion\nJ-rock, electronic, hardstyle\nJ-rock, electronic, high-BPM\nJ-rock, electronic, hip hop\nJ-rock, electronic, hyperpop\nJ-rock, electronic, industrial\nJ-rock, electronic, rap\nJ-rock, electronic, speedcore\nJ-rock, electronic, symphonic\nJ-rock, electronic, symphonic metal\nJ-rock, electronic, symphonic rock\nJ-rock, electronic, synth\nJ-rock, electronic, synth rock\nJ-rock, electronic, traditional Japanese\nJ-rock, electronic, trance\nJ-rock, electronicore, lo-fi\nJ-rock, epic fusion, anime theme\nJ-rock, ethereal pop, Christmas rock\nJ-rock, ethereal, Vocaloid\nJ-rock, festival music\nJ-rock, festival music, idol\nJ-rock, festival, chiptune\nJ-rock, flamenco, cinematic\nJ-rock, flamenco, synth-pop\nJ-rock, flamenco, theatrical\nJ-rock, folk fusion\nJ-rock, folk metal, Enka\nJ-rock, folk metal, Middle Eastern\nJ-rock, folk rock\nJ-rock, folk, Mandarin pop\nJ-rock, folk-metal\nJ-rock, funk rock, punk rock\nJ-rock, funk, city pop\nJ-rock, funk-rock\nJ-rock, future bass\nJ-rock, future bass, dubstep\nJ-rock, future bass, electronic\nJ-rock, future bass, happy hardcore\nJ-rock, glam metal, 80s rock\nJ-rock, glam metal, city pop\nJ-rock, glitch, breakcore\nJ-rock, glitch, electronic\nJ-rock, glitch-hop, breakcore\nJ-rock, glitchcore, industrial\nJ-rock, gothic, baroque\nJ-rock, guzheng fusion\nJ-rock, guzheng, quirky\nJ-rock, gǔyō\nJ-rock, happy hardcore\nJ-rock, happy hardcore, EDM\nJ-rock, happy hardcore, French pop\nJ-rock, happy hardcore, anison\nJ-rock, happy hardcore, chiptune\nJ-rock, happy hardcore, cinematic\nJ-rock, happy hardcore, hardstyle\nJ-rock, happy hardcore, metalcore\nJ-rock, happy hardcore, speedcore\nJ-rock, happy hardcore, trance\nJ-rock, happy hardcore, video game music\nJ-rock, hard rock, Latin rock\nJ-rock, hard rock, anison\nJ-rock, hard rock, glam metal\nJ-rock, hardcore electronic\nJ-rock, hardcore electronic, breakcore\nJ-rock, hardcore electronic, chiptune\nJ-rock, hardcore electronic, speedcore\nJ-rock, hardcore techno\nJ-rock, hardcore techno, speedcore\nJ-rock, hardstyle\nJ-rock, hardstyle, C-pop\nJ-rock, hardstyle, anime\nJ-rock, hardstyle, dream pop\nJ-rock, hardstyle, electronic\nJ-rock, hardstyle, electronic dance\nJ-rock, hardstyle, trap\nJ-rock, heavy metal\nJ-rock, heavy metal, cinematic\nJ-rock, hip hop, electronic\nJ-rock, hip-hop, C-pop\nJ-rock, hip-hop, ambient\nJ-rock, hip-hop, cinematic pop\nJ-rock, hip-hop, cinematic synth\nJ-rock, hip-hop, electronic\nJ-rock, hip-hop, nu-metal\nJ-rock, hip-hop, orchestral\nJ-rock, hyper-electronica\nJ-rock, hyper-pop\nJ-rock, hyper-pop, electronic\nJ-rock, hyper-pop, multi-lingual\nJ-rock, hyper-speed chiptune\nJ-rock, hyper-speed electronic\nJ-rock, hyper-speed rap\nJ-rock, hyperpop\nJ-rock, hyperpop, EDM\nJ-rock, hyperpop, ambient\nJ-rock, hyperpop, anime\nJ-rock, hyperpop, anison\nJ-rock, hyperpop, artcore\nJ-rock, hyperpop, breakcore\nJ-rock, hyperpop, chiptune\nJ-rock, hyperpop, denpa-kei\nJ-rock, hyperpop, electronic\nJ-rock, hyperpop, electronicore\nJ-rock, hyperpop, synth-pop\nJ-rock, hyperpop, theatrical\nJ-rock, industrial rock, synth-rock\nJ-rock, industrial, electronic\nJ-rock, instrumental rock, cinematic\nJ-rock, instrumental rock, video game music\nJ-rock, jazz fusion\nJ-rock, jazz fusion, Vocaloid\nJ-rock, jazz fusion, chiptune\nJ-rock, jazz fusion, city pop\nJ-rock, jazz fusion, drum and bass\nJ-rock, jazz fusion, funk\nJ-rock, jazz fusion, musical theater\nJ-rock, jazz fusion, progressive rock\nJ-rock, jazz fusion, video game music\nJ-rock, jazz, cinematic\nJ-rock, jazz, electronic\nJ-rock, jazz-funk, big band\nJ-rock, jazz-fusion\nJ-rock, jazz-fusion, anime rock\nJ-rock, jazz-fusion, electronic\nJ-rock, kawaii synth-pop\nJ-rock, lo-fi R&B\nJ-rock, lo-fi hip hop, rap rock\nJ-rock, lo-fi hip-hop, alternative rock\nJ-rock, lo-fi, ambient\nJ-rock, lo-fi, cinematic\nJ-rock, lo-fi, glitch\nJ-rock, lo-fi, pop-rock\nJ-rock, lo-fi, post-rock\nJ-rock, lounge-pop\nJ-rock, math rock, city pop\nJ-rock, math rock, electronic\nJ-rock, math rock, jazz-funk\nJ-rock, math-rock, cinematic\nJ-rock, matsuri, electronic\nJ-rock, matsuri, modern fusion\nJ-rock, matsuri, rock\nJ-rock, metalcore\nJ-rock, metalcore, anime\nJ-rock, metalcore, anime power pop\nJ-rock, metalcore, anime theme\nJ-rock, metalcore, chiptune\nJ-rock, metalcore, cinematic\nJ-rock, metalcore, cinematic rock\nJ-rock, metalcore, electronic\nJ-rock, metalcore, lo-fi\nJ-rock, metalcore, nu-metal\nJ-rock, metalcore, pop-rock\nJ-rock, metalcore, post-hardcore\nJ-rock, metalcore, shred guitar\nJ-rock, min'yō\nJ-rock, musical theater, video game music\nJ-rock, neo-classical\nJ-rock, neo-soul, city pop\nJ-rock, neoclassical metal\nJ-rock, neoclassical power metal\nJ-rock, neoclassical, electronic\nJ-rock, new wave\nJ-rock, new wave, city pop\nJ-rock, noise rock\nJ-rock, nu-disco, ambient\nJ-rock, nu-metal\nJ-rock, nu-metal, Mandarin rock\nJ-rock, nu-metal, anime theme\nJ-rock, nu-metal, cinematic rock\nJ-rock, nu-metal, electronic\nJ-rock, nu-metal, metalcore\nJ-rock, orchestral rock\nJ-rock, orchestral, anime theme\nJ-rock, orchestral, anison\nJ-rock, orchestral, cinematic\nJ-rock, orchestral, electronic\nJ-rock, orchestral, video game\nJ-rock, orchestral, video game soundtrack\nJ-rock, piano ballad\nJ-rock, piano rock\nJ-rock, piano rock, high-speed\nJ-rock, piano rock, hyperpop\nJ-rock, pirate metal, symphonic rock\nJ-rock, polka, fusion\nJ-rock, pop, ballad\nJ-rock, pop, electronic\nJ-rock, pop-punk\nJ-rock, pop-punk, C-pop\nJ-rock, pop-punk, Latin pop\nJ-rock, pop-punk, Vocaloid\nJ-rock, pop-punk, cinematic\nJ-rock, pop-punk, easycore\nJ-rock, pop-punk, electronic\nJ-rock, pop-punk, lo-fi\nJ-rock, pop-punk, metalcore\nJ-rock, pop-punk, nu-metal\nJ-rock, pop-punk, rap-rock\nJ-rock, pop-punk, synth-pop\nJ-rock, pop-rock\nJ-rock, pop-rock, C-pop\nJ-rock, pop-rock, K-pop\nJ-rock, pop-rock, Latin pop\nJ-rock, pop-rock, anime\nJ-rock, pop-rock, anime theme\nJ-rock, pop-rock, cinematic\nJ-rock, pop-rock, dream pop\nJ-rock, pop-rock, electronic\nJ-rock, pop-rock, electronicore\nJ-rock, pop-rock, metalcore\nJ-rock, post-hardcore\nJ-rock, post-hardcore, metalcore\nJ-rock, post-rock\nJ-rock, post-rock, cinematic\nJ-rock, post-rock, piano ballad\nJ-rock, post-rock, power ballad\nJ-rock, power ballad, anime\nJ-rock, power ballad, chiptune\nJ-rock, power ballad, cinematic\nJ-rock, power ballad, video game soundtrack\nJ-rock, power metal\nJ-rock, power metal, C-pop\nJ-rock, power metal, Chinese fusion\nJ-rock, power metal, anison\nJ-rock, power metal, cinematic\nJ-rock, power metal, symphonic\nJ-rock, power metal, symphonic metal\nJ-rock, power pop\nJ-rock, power-pop, cinematic\nJ-rock, progressive metal\nJ-rock, progressive rock, synth pop\nJ-rock, ragtime, boogie-woogie\nJ-rock, rap, anime theme\nJ-rock, rap-rock\nJ-rock, rap-rock, chiptune\nJ-rock, rap-rock, cinematic\nJ-rock, rock ballad, chiptune\nJ-rock, rockabilly, boogie-woogie\nJ-rock, shoegaze, anime theme\nJ-rock, shoegaze, post-rock\nJ-rock, shoegaze, rap-rock\nJ-rock, ska, big band\nJ-rock, ska-punk, Latin rock\nJ-rock, ska-punk, anison\nJ-rock, ska-punk, big band\nJ-rock, speed metal, chiptune\nJ-rock, speedcore\nJ-rock, speedcore, electronic\nJ-rock, surf rock, chiptune\nJ-rock, symphonic J-pop\nJ-rock, symphonic metal\nJ-rock, symphonic metal, C-pop\nJ-rock, symphonic metal, Middle Eastern folk\nJ-rock, symphonic metal, Vocaloid\nJ-rock, symphonic metal, acoustic\nJ-rock, symphonic metal, anime theme\nJ-rock, symphonic metal, anison\nJ-rock, symphonic metal, chiptune\nJ-rock, symphonic metal, cinematic\nJ-rock, symphonic metal, electronic\nJ-rock, symphonic metal, metalcore\nJ-rock, symphonic metal, power metal\nJ-rock, symphonic metal, rap-rock\nJ-rock, symphonic metal, video game music\nJ-rock, symphonic power metal\nJ-rock, symphonic rock\nJ-rock, symphonic rock, C-pop\nJ-rock, symphonic rock, Chinese folk fusion\nJ-rock, symphonic rock, anison\nJ-rock, symphonic rock, baroque pop\nJ-rock, symphonic rock, chiptune\nJ-rock, symphonic rock, cinematic\nJ-rock, symphonic rock, neoclassical metal\nJ-rock, symphonic rock, power metal\nJ-rock, symphonic rock, progressive metal\nJ-rock, symphonic rock, theatrical\nJ-rock, symphonic rock, traditional Japanese\nJ-rock, symphonic rock, video game music\nJ-rock, symphonic, anime theme\nJ-rock, symphonic, electronic\nJ-rock, symphonic, video game\nJ-rock, synth rock, chiptune\nJ-rock, synth-pop\nJ-rock, synth-pop, C-pop\nJ-rock, synth-pop, anime\nJ-rock, synth-pop, anison\nJ-rock, synth-pop, chiptune\nJ-rock, synth-pop, city pop\nJ-rock, synth-pop, electronic\nJ-rock, synth-pop, hyperpop\nJ-rock, synth-pop, trance\nJ-rock, synth-rock\nJ-rock, synth-rock, anime\nJ-rock, synth-rock, anime rock\nJ-rock, synth-rock, chiptune\nJ-rock, taiko, festival\nJ-rock, technical funk\nJ-rock, technical jazz\nJ-rock, technical metal\nJ-rock, theatrical rock, video game music\nJ-rock, thrash metal\nJ-rock, traditional East Asian\nJ-rock, traditional East Asian, anime rock\nJ-rock, traditional East Asian, anime theme\nJ-rock, traditional East Asian, explosive\nJ-rock, traditional East Asian, rock\nJ-rock, traditional Japanese folk\nJ-rock, traditional Japanese, anime\nJ-rock, traditional Japanese, anime theme\nJ-rock, traditional Japanese, anison\nJ-rock, traditional Japanese, cinematic\nJ-rock, traditional Japanese, electronic\nJ-rock, traditional Japanese, electronic fusion\nJ-rock, traditional Japanese, fusion\nJ-rock, traditional Japanese, metal\nJ-rock, traditional Japanese, rock\nJ-rock, traditional fusion, cinematic\nJ-rock, trance\nJ-rock, trance, anison\nJ-rock, trance, cinematic\nJ-rock, trance, happy hardcore\nJ-rock, trance, orchestral\nJ-rock, trance, speedcore\nJ-rock, trance, video game music\nJ-rock, trancecore, hardcore electronic\nJ-rock, trancecore, metalcore\nJ-rock, trap, R&B\nJ-rock, trap, electronic\nJ-rock, trip-hop, ambient\nJ-rock, uplifting trance\nJ-rock, video game\nJ-rock, video game metal\nJ-rock, video game music\nJ-rock, video game music, East Asian fusion\nJ-rock, video game music, anime\nJ-rock, video game music, anime soundtrack\nJ-rock, video game music, anime theme\nJ-rock, video game music, chiptune\nJ-rock, video game music, cinematic\nJ-rock, video game music, cinematic rock\nJ-rock, video game music, electronic\nJ-rock, video game music, electronic dance\nJ-rock, video game music, energetic\nJ-rock, video game music, epic\nJ-rock, video game music, epic instrumental\nJ-rock, video game music, epic rock\nJ-rock, video game music, epic synth\nJ-rock, video game music, folk-rock\nJ-rock, video game music, funk\nJ-rock, video game music, happy hardcore\nJ-rock, video game music, high-energy\nJ-rock, video game music, instrumental\nJ-rock, video game music, instrumental rock\nJ-rock, video game music, jazz fusion\nJ-rock, video game music, maximalist\nJ-rock, video game music, orchestral\nJ-rock, video game music, piano instrumental\nJ-rock, video game music, post-hardcore\nJ-rock, video game music, progressive fusion\nJ-rock, video game music, progressive metal\nJ-rock, video game music, progressive rock\nJ-rock, video game music, synth rock\nJ-rock, video game music, synth-rock\nJ-rock, video game music, synthpop\nJ-rock, video game music, synthwave\nJ-rock, video game music, upbeat\nJ-rock, video game music, world fusion\nJ-rock, video game soundtrack\nJ-rock, video game soundtrack, cinematic\nJ-rock, video game soundtrack, electronic\nJ-rock, video game soundtrack, energetic\nJ-rock, video game soundtrack, epic instrumental\nJ-rock, video game soundtrack, indie rock\nJ-rock, video game soundtrack, power pop\nJ-rock, video game soundtrack, synthwave\nJ-rock, video game soundtrack, upbeat\nJ-rock, video game style\nJ-rock, video game, chiptune\nJ-rock, video game, cinematic\nJ-rock, video game, electronic\nJ-rock, video game, synth rock\nJ-rock, world fusion, cinematic\nJ-rock, world music\nJ-rock, world music, anime theme\nJ-rock, world music, djent\nJ-rock, world music, hip-hop\nJ-trance\nJ-trap\nJ-trap EDM\nJ-trap cloud rap\nJ-trap drill\nJ-trap hyperpop\nJ-trap lo-fi\nJ-trap vaporwave\nJ-trap, Latin hip hop\nJ-trap, cloud rap\nJ-trap, cloud rap, emo trap\nJ-trap, cloud rap, synth pop\nJ-trap, cloud rap, trap\nJ-trap, hyperpop, anime\nJRPG\nJRPG ambient\nJRPG battle music\nJRPG battle theme\nJRPG orchestral\nJRPG soundtrack\nJRPG soundtrack, Eurodance, happy hardcore\nJRPG style\nJRPG style, pop-rock ballad\nJRPG style, synth-rock, symphonic metal\nJRPG synth\nJRPG synth-pop\nJRPG theme\nJRPG, progressive rock, jazz fusion\nJRPG, progressive rock, synth-pop\nJablesco\nJamaican Patois\nJamaican hip hop\nJamaican rap\nJamaican trap\nJambemé, Argentinian folk, live energy\nJapandi hip hop\nJapanese City Pop\nJapanese Eurobeat\nJapanese Latin folk\nJapanese Latin fusion\nJapanese R&B\nJapanese R&B acid jazz\nJapanese R&B city pop\nJapanese R&B hip-hop\nJapanese R&B neo-soul\nJapanese R&B, New Jack Swing\nJapanese R&B, dance-pop\nJapanese R&B, hip-hop\nJapanese R&B, hip-hop, city pop\nJapanese R&B, new jack swing\nJapanese RPG\nJapanese RPG soundtrack\nJapanese acoustic\nJapanese acoustic ballad\nJapanese acoustic folk\nJapanese acoustic pop\nJapanese acoustic pop-rock\nJapanese acoustic rock\nJapanese alternative rock\nJapanese ambient\nJapanese ambient pop\nJapanese arcade\nJapanese arcade dance\nJapanese art song\nJapanese art-pop\nJapanese artcore\nJapanese artcore speedcore\nJapanese ballad\nJapanese ballad, Latin pop, flamenco\nJapanese ballad, blues-rock\nJapanese ballad, film noir, lounge jazz\nJapanese battle rap\nJapanese big band rock\nJapanese big band swing\nJapanese blues\nJapanese blues jazz\nJapanese blues-rock\nJapanese breakbeat\nJapanese carnival\nJapanese chanson\nJapanese children's\nJapanese children's music\nJapanese children's, big band\nJapanese children's, big band swing, Christmas\nJapanese cinematic\nJapanese club, UK garage\nJapanese comedy rock\nJapanese country-rock\nJapanese dance\nJapanese dance music\nJapanese dance-pop\nJapanese dancehall\nJapanese dancehall reggae\nJapanese disco-funk\nJapanese drill\nJapanese drill trap\nJapanese drill, hardstyle\nJapanese drinking song\nJapanese electronic\nJapanese electronic dance music\nJapanese electronic rock\nJapanese emo\nJapanese festival\nJapanese festival music\nJapanese festival rock\nJapanese festival trap\nJapanese folk\nJapanese folk country\nJapanese folk garage rock\nJapanese folk metal\nJapanese folk rock\nJapanese folk trap\nJapanese folk, Latin jazz\nJapanese folk, big band\nJapanese folk, big band, cinematic\nJapanese folk, big band, enka\nJapanese folk, big band, theatrical\nJapanese folk, cinematic, operatic\nJapanese folk, jazz-blues\nJapanese folk, orchestral, theatrical\nJapanese folk, piano ballad\nJapanese folk-blues\nJapanese folk-country\nJapanese folk-fusion\nJapanese folk-jazz\nJapanese folk-metal\nJapanese folk-pop\nJapanese folk-punk\nJapanese folk-rock\nJapanese folk-rock garage rock\nJapanese funk\nJapanese funk R&B\nJapanese funk city pop\nJapanese funk disco\nJapanese funk fusion\nJapanese funk rock\nJapanese funk ska\nJapanese funk soul\nJapanese funk, city pop\nJapanese funk, disco\nJapanese funk, new jack swing\nJapanese funk, ska-punk\nJapanese funk-fusion\nJapanese funk-pop\nJapanese funk-rap\nJapanese funk-reggae\nJapanese funk-rock\nJapanese funk-rock anison\nJapanese fusion\nJapanese fusion funk\nJapanese fusion, chiptune, video game music\nJapanese fusion, video game music\nJapanese fusion, video game music, synthwave\nJapanese hard rock\nJapanese hardcore\nJapanese hardcore punk\nJapanese hardcore techno\nJapanese heavy metal\nJapanese hip hop\nJapanese hip-hop\nJapanese hip-hop G-funk\nJapanese hip-hop R&B\nJapanese hip-hop breakcore\nJapanese hip-hop chiptune\nJapanese hip-hop chiptune trap\nJapanese hip-hop dance-pop\nJapanese hip-hop dancehall\nJapanese hip-hop electronic rock\nJapanese hip-hop funk\nJapanese hip-hop funk acid jazz\nJapanese hip-hop funk dancehall\nJapanese hip-hop funk ska\nJapanese hip-hop funk soul\nJapanese hip-hop funk-rock\nJapanese hip-hop indie rock\nJapanese hip-hop lo-fi\nJapanese hip-hop lo-fi boom-bap\nJapanese hip-hop neo-soul\nJapanese hip-hop nu-metal\nJapanese hip-hop nu-metal chiptune\nJapanese hip-hop rap-rock\nJapanese hip-hop reggae\nJapanese hip-hop reggae dancehall\nJapanese hip-hop rock\nJapanese hip-hop techno\nJapanese hip-hop trap\nJapanese hip-hop, G-funk, city pop\nJapanese hip-hop, J-pop, chiptune\nJapanese hip-hop, J-rock\nJapanese hip-hop, J-rock, trap\nJapanese hip-hop, Latin, bossa nova\nJapanese hip-hop, R&B\nJapanese hip-hop, chiptune, boom-bap\nJapanese hip-hop, cinematic\nJapanese hip-hop, city pop\nJapanese hip-hop, electronic dance music\nJapanese hip-hop, gǔyō\nJapanese hip-hop, hardstyle\nJapanese hip-hop, horrorcore\nJapanese hip-hop, hyperpop, breakbeat\nJapanese hip-hop, hyperpop, trap\nJapanese hip-hop, nu-metal\nJapanese hip-hop, nu-metal, hard rock\nJapanese hip-hop, nu-metal, industrial\nJapanese hip-hop, rap-rock\nJapanese hip-hop, trap\nJapanese hip-hop, trap, cloud rap\nJapanese hip-hop, trap, orchestral\nJapanese house\nJapanese house, Eurobeat\nJapanese indie folk\nJapanese indie pop\nJapanese indie rock\nJapanese indie rock, city pop\nJapanese indie rock, city-pop\nJapanese indie-folk\nJapanese indie-pop\nJapanese instrumental\nJapanese jazz\nJapanese jazz-pop\nJapanese lullaby\nJapanese mambo\nJapanese march\nJapanese marching\nJapanese marching band\nJapanese metal\nJapanese metalcore\nJapanese narrative\nJapanese new wave\nJapanese novelty\nJapanese novelty, Latin pop\nJapanese orchestral\nJapanese party-rap\nJapanese phonk\nJapanese piano ballad\nJapanese polka\nJapanese pop-punk\nJapanese pop-rock\nJapanese power ballad\nJapanese power metal\nJapanese pub rock\nJapanese punk rock\nJapanese rap\nJapanese rap rock\nJapanese reggae\nJapanese reggae dancehall\nJapanese reggae fusion\nJapanese reggae hip-hop\nJapanese reggae lovers rock\nJapanese reggae ska-punk\nJapanese reggae-funk\nJapanese reggae-pop\nJapanese reggae-rap\nJapanese rock\nJapanese rock 'n' roll\nJapanese rock AOR\nJapanese rock AOR city pop\nJapanese rock and roll\nJapanese rock anison\nJapanese rock anison comedy rock\nJapanese rock anison denpa-kei\nJapanese rock anison hyperpop\nJapanese rock ballad\nJapanese rock big band\nJapanese rock bluegrass fusion\nJapanese rock blues\nJapanese rock chiptune\nJapanese rock chiptune progressive metal\nJapanese rock city pop\nJapanese rock denpa\nJapanese rock denpa-kei\nJapanese rock electronic\nJapanese rock electronicore\nJapanese rock enka\nJapanese rock funk\nJapanese rock funk ska\nJapanese rock funk video game\nJapanese rock fusion\nJapanese rock hardcore techno\nJapanese rock jazz fusion\nJapanese rock math rock\nJapanese rock metal\nJapanese rock metalcore\nJapanese rock metalcore chiptune\nJapanese rock metalcore electronic\nJapanese rock metalcore progressive\nJapanese rock nu-metal rap-rock\nJapanese rock opera\nJapanese rock post-hardcore math rock\nJapanese rock power metal\nJapanese rock power metal chiptune\nJapanese rock progressive metal\nJapanese rock progressive metal chiptune\nJapanese rock progressive rock video game music\nJapanese rock punk\nJapanese rock salsa\nJapanese rock ska punk\nJapanese rock ska surf\nJapanese rock ska-punk\nJapanese rock ska-punk anison\nJapanese rock speed metal\nJapanese rock speed metal chiptune\nJapanese rock surf rock\nJapanese rock surf-rock\nJapanese rock symphonic metal\nJapanese rock, Enka\nJapanese rock, Enka, cinematic rock\nJapanese rock, Kayōkyoku\nJapanese rock, Kayōkyoku, Anison\nJapanese rock, Kayōkyoku, City Pop\nJapanese rock, Kayōkyoku, Latin rock\nJapanese rock, Kayōkyoku, big band\nJapanese rock, Kayōkyoku, cinematic rock\nJapanese rock, Kayōkyoku, disco-rock\nJapanese rock, Kayōkyoku, tango\nJapanese rock, Latin fusion\nJapanese rock, Latin piano, video game music\nJapanese rock, big band\nJapanese rock, big band jazz\nJapanese rock, big band jazz fusion\nJapanese rock, big band jazz, instrumental\nJapanese rock, big band, Kayōkyoku\nJapanese rock, bluegrass\nJapanese rock, chiptune\nJapanese rock, chiptune, artcore\nJapanese rock, chiptune, breakcore\nJapanese rock, chiptune, classical piano\nJapanese rock, chiptune, electronic dance\nJapanese rock, chiptune, progressive metal\nJapanese rock, chiptune, speed metal\nJapanese rock, chiptune, video game music\nJapanese rock, cinematic rock\nJapanese rock, city pop\nJapanese rock, city pop, AOR\nJapanese rock, city pop, anime\nJapanese rock, city pop, boogie-woogie\nJapanese rock, city pop, funk\nJapanese rock, city pop, jazz fusion\nJapanese rock, city pop, showa Kayō\nJapanese rock, city pop, synth-funk\nJapanese rock, classical piano, video game music\nJapanese rock, electronic dance music\nJapanese rock, flamenco rock\nJapanese rock, guzheng fusion\nJapanese rock, hardcore techno\nJapanese rock, metalcore, chiptune\nJapanese rock, power metal, Nintendocore\nJapanese rock, power metal, symphonic metal\nJapanese rock, power metal, video game music\nJapanese rock, progressive metal, Nintendocore\nJapanese rock, progressive metal, chiptune\nJapanese rock, progressive metal, video game music\nJapanese rock, punk rock, noise rock\nJapanese rock, ska, big band\nJapanese rock, ska-punk, big band\nJapanese rock, speed metal, chiptune\nJapanese rock, speed metal, video game music\nJapanese rock, symphonic metal\nJapanese rock, symphonic metal, chiptune\nJapanese rock, symphonic metal, power metal\nJapanese rock, symphonic metal, video game music\nJapanese rock, synth-funk\nJapanese rock, trance, video game music\nJapanese rock, video game metal\nJapanese rock, video game music\nJapanese rock, video game music, J-pop\nJapanese rock, video game music, chiptune\nJapanese rock, video game music, electronic\nJapanese rock, video game music, electronic dance\nJapanese rock, video game music, funk rock\nJapanese rock, video game music, happy hardcore\nJapanese rock, video game music, instrumental\nJapanese rock, video game music, progressive fusion\nJapanese rock, video game music, progressive metal\nJapanese rock, video game music, synth rock\nJapanese rock, video game music, synthwave\nJapanese rock, video game music, traditional East Asian\nJapanese rumba\nJapanese salsa\nJapanese samba\nJapanese samba-pop\nJapanese ska-punk\nJapanese speed metal\nJapanese speed metal anison\nJapanese speed-rap\nJapanese speedcore\nJapanese speedcore metalcore\nJapanese swing\nJapanese swing jazz\nJapanese techno\nJapanese traditional\nJapanese traditional, cinematic\nJapanese trance\nJapanese trance, happy hardcore\nJapanese trap\nJapanese trap metal\nJapanese trap, cloud rap\nJapanese trap, hyperpop\nJapanese trap-metal\nJapanese tropical pop\nJapanese video game\nJapanese video game music\nJapanese video game music, Latin jazz\nJapanese video game music, happy hardcore, trance\nJapanese video game soundtrack\nJaripeo\nJaripeo corrido\nJaripeo folk\nJaripeo mariachi\nJaripeo ranchera\nJaroana\nJarocho\nJavanese Dangdut Koplo, smooth jazz, sentimental pop\nJavanese Dangdut pop-rock\nJavanese Dangdut, smooth jazz, pop\nJavanese Gamelan\nJavanese acoustic\nJavanese acoustic pop\nJavanese ambient\nJavanese ballad\nJavanese children's music\nJavanese devotional\nJavanese electronic\nJavanese electronic pop\nJavanese folk\nJavanese folk Sundanese folk\nJavanese folk pop\nJavanese folk pop-rock\nJavanese folk rock\nJavanese folk, Bossa Nova\nJavanese folk, chiptune, electronic\nJavanese folk, flamenco fusion\nJavanese folk, world music, new age\nJavanese folk-pop\nJavanese folk-rock\nJavanese fusion\nJavanese fusion pop-rock\nJavanese fusion rock\nJavanese gamelan\nJavanese hip-hop\nJavanese hip-hop chiptune\nJavanese hip-hop funkot\nJavanese hip-hop trap\nJavanese hip-hop, Dangdut Koplo\nJavanese indie\nJavanese jazz-pop\nJavanese metal\nJavanese modern\nJavanese music\nJavanese pop\nJavanese pop Latin\nJavanese pop ballad\nJavanese pop ballad, Dangdut Koplo, pop-rock\nJavanese pop big band\nJavanese pop bossa nova lounge jazz\nJavanese pop chiptune\nJavanese pop cinematic\nJavanese pop city pop\nJavanese pop country\nJavanese pop dangdut\nJavanese pop dangdut koplo\nJavanese pop funk\nJavanese pop jazz\nJavanese pop jazz cabaret\nJavanese pop power ballad\nJavanese pop reggae\nJavanese pop rock\nJavanese pop ska jazz\nJavanese pop smooth jazz\nJavanese pop soul rock\nJavanese pop surf rock\nJavanese pop world music\nJavanese pop, Dangdut\nJavanese pop, Dangdut Koplo\nJavanese pop, Dangdut Koplo, cinematic pop\nJavanese pop, Dangdut Koplo, electronic pop\nJavanese pop, Dangdut, Middle Eastern fusion\nJavanese pop, Dangdut, cinematic\nJavanese pop, Dangdut, melancholic\nJavanese pop, Dangdut, pop-rock\nJavanese pop, Latin pop\nJavanese pop, Malay pop, pop\nJavanese pop, big band jazz, dangdut koplo\nJavanese pop, chiptune, sentimental pop\nJavanese pop, cinematic pop, pop-rock\nJavanese pop, cinematic pop-rock\nJavanese pop, classic rock\nJavanese pop, dangdut koplo\nJavanese pop, dangdut koplo, pop-rock\nJavanese pop, electronic dance, happy hardcore\nJavanese pop, electronic, video game\nJavanese pop, funk rock\nJavanese pop, hard rock\nJavanese pop, hip-hop, R&B\nJavanese pop, old-school hip-hop, chiptune\nJavanese pop, pop duet\nJavanese pop, pop-punk, alternative rock\nJavanese pop, pop-rock\nJavanese pop, pop-rock, Dangdut Koplo\nJavanese pop, pop-rock, cinematic\nJavanese pop, pop-rock, dangdut koplo\nJavanese pop, pop-rock, hip-hop\nJavanese pop, retro video game, punk rock\nJavanese pop, ska, rock\nJavanese pop-folk\nJavanese pop-jazz\nJavanese pop-punk\nJavanese pop-rap\nJavanese pop-reggae\nJavanese pop-rock\nJavanese pop-rock chiptune\nJavanese pop-rock hip-hop\nJavanese pop-rock power metal\nJavanese pop-rock reggae\nJavanese pop-rock ska\nJavanese pop-rock, Dangdut Koplo\nJavanese pop-rock, dangdut koplo\nJavanese pop-rock, hard rock\nJavanese pop-rock, heavy metal\nJavanese pop-rock, pop-punk\nJavanese pop-rock, psychedelic rock\nJavanese pop-rock, surf rock, dangdut koplo\nJavanese power ballad\nJavanese psychedelic rock\nJavanese punk rock\nJavanese punk rock, Dangdut Koplo\nJavanese reggae\nJavanese religious chant\nJavanese religious music\nJavanese rock\nJavanese rock fusion\nJavanese traditional\nJazz fusion R&B\nJersey Club\nJersey club\nJersey club hyperpop\nJersey club trap\nJersey club, bounce, hard house\nJersey club, future bass, R&B\nJersey club, retro synth, cinematic\nJoropo\nJoropo Candombe\nJoropo Cumbia\nJoropo Huayno\nJoropo Llanero\nJoropo Sertanejo\nJoropo salsa\nJota\nJota Candombe\nJota, Cumbia Andina\nJota, Rumba Flamenca\nJovem Guarda\nJovem Sertanejo\nJíbaro\nJíbaro Candombe\nJíbaro Cumbia\nJíbaro Gaita\nJíbaro Gaita Zuliana\nJíbaro de Salsa\nJíbaro salsa\nK-Indie\nK-Indie City Pop\nK-Indie City Pop Jazz Pop\nK-Indie R&B\nK-Indie bedroom pop\nK-Indie lo-fi\nK-Indie lo-fi hip hop\nK-Indie lo-fi hip-hop\nK-Indie lo-fi neo-soul\nK-Indie neo-soul\nK-Indie neo-soul lo-fi hip-hop\nK-Indie, Neo-Soul, City Pop\nK-Indie, Neo-Soul, jazz-pop\nK-Indie, neo-soul, lo-fi jazz\nK-Pop\nK-Pop City Pop video game music\nK-Pop EDM\nK-Pop Latin Pop\nK-Pop New Jack Swing\nK-Pop R&B\nK-Pop R&B hip-hop\nK-Pop R&B trap\nK-Pop future bass\nK-Pop gospel\nK-Pop, Christmas ballad\nK-Pop, Eurodance, Hi-NRG\nK-Pop, New Jack Swing\nK-Pop, New Jack Swing, City Pop\nK-Pop, New Jack Swing, Funk\nK-Pop, New Jack Swing, R&B\nK-Pop, R&B, New Jack Swing\nK-Pop, R&B, cinematic\nK-Pop, R&B, early 2000s\nK-Pop, R&B, electronic\nK-Pop, R&B, hip-hop\nK-Pop, R&B, pop\nK-Pop, R&B, trap\nK-Pop, new jack swing, hip-hop\nK-R&B\nK-R&B Bossa Nova\nK-R&B Latin pop\nK-R&B bossa nova\nK-R&B chill pop\nK-R&B chillwave\nK-R&B chiptune\nK-R&B cinematic\nK-R&B city pop\nK-R&B city pop funk\nK-R&B city pop lo-fi hip-hop\nK-R&B city-pop\nK-R&B cloud rap\nK-R&B deep house\nK-R&B dream pop\nK-R&B emo-rap\nK-R&B funk\nK-R&B future bass\nK-R&B future funk\nK-R&B hip-hop\nK-R&B indie pop\nK-R&B jazz-hop\nK-R&B lo-fi\nK-R&B lo-fi hip hop\nK-R&B lo-fi hip-hop\nK-R&B lo-fi hip-hop chiptune\nK-R&B lo-fi hip-hop neo-soul\nK-R&B lo-fi neo-soul\nK-R&B lo-fi pop\nK-R&B lo-fi trap-soul\nK-R&B neo-soul\nK-R&B neo-soul city pop\nK-R&B nu-disco\nK-R&B pop\nK-R&B pop-rap\nK-R&B pop-rock\nK-R&B trap\nK-R&B trap chiptune\nK-R&B trap pop-rap\nK-R&B trap soul\nK-R&B trap-pop\nK-R&B trap-soul\nK-R&B vaporwave\nK-R&B, bedroom pop\nK-R&B, city pop\nK-R&B, city pop, neo-soul\nK-R&B, city-pop\nK-R&B, cloud rap, trap\nK-R&B, electronic, alternative R&B\nK-R&B, emo rap, trap\nK-R&B, emo-rap, trap\nK-R&B, funk, nu-disco\nK-R&B, hip-hop\nK-R&B, hip-hop, ambient\nK-R&B, hip-hop, chiptune\nK-R&B, hip-hop, cinematic\nK-R&B, hip-hop, jazz-infused\nK-R&B, hip-hop, jazzy\nK-R&B, hip-hop, lo-fi\nK-R&B, hip-hop, trap\nK-R&B, lo-fi\nK-R&B, lo-fi hip hop\nK-R&B, lo-fi hip hop, jazz\nK-R&B, lo-fi hip hop, jazzy\nK-R&B, lo-fi hip hop, trap\nK-R&B, lo-fi hip-hop\nK-R&B, lo-fi hip-hop, jazz\nK-R&B, lo-fi hip-hop, jazzy\nK-R&B, lo-fi pop\nK-R&B, lo-fi, trap-soul\nK-R&B, modern R&B, jazz fusion\nK-R&B, neo-soul\nK-R&B, neo-soul, lo-fi\nK-R&B, neo-soul, lo-fi hip-hop\nK-R&B, pop-rap, chill hop\nK-R&B, pop-rock\nK-R&B, pop-trap\nK-R&B, reggaeton, slow-jam R&B, ballad, Latin pop\nK-R&B, trap hip-hop\nK-R&B, trap, ambient\nK-R&B, trap, hip-hop\nK-R&B, trap, jazzy hip-hop\nK-R&B, trap, vaporwave\nK-R&B, trap-R&B\nK-R&B, trap-soul\nK-R&B, vaporwave, trap\nK-Trap\nK-ballad\nK-ballad Bossa Nova\nK-ballad Latin\nK-ballad Latin pop\nK-ballad R&B\nK-ballad R&B hip-hop\nK-ballad R&B jazz\nK-ballad R&B lo-fi\nK-ballad R&B lounge\nK-ballad R&B neo-soul\nK-ballad R&B pop\nK-ballad R&B soul\nK-ballad R&B-pop\nK-ballad acoustic pop\nK-ballad alternative rock\nK-ballad bossa nova\nK-ballad cinematic\nK-ballad city pop R&B\nK-ballad city pop jazz\nK-ballad city pop jazz fusion\nK-ballad electronic rock\nK-ballad future bass\nK-ballad hip-hop\nK-ballad hip-hop pop-rock\nK-ballad hip-hop rock\nK-ballad indie pop\nK-ballad indie rock\nK-ballad jazz\nK-ballad jazz R&B\nK-ballad jazz indie\nK-ballad jazz lounge\nK-ballad jazz-pop\nK-ballad lo-fi\nK-ballad lo-fi hip hop\nK-ballad lo-fi hip-hop\nK-ballad lo-fi jazz\nK-ballad lo-fi neo-soul\nK-ballad lo-fi pop\nK-ballad lounge jazz\nK-ballad neo-soul\nK-ballad neo-soul lo-fi jazz\nK-ballad orchestral\nK-ballad pop-rock\nK-ballad pop-rock hip-hop\nK-ballad rock\nK-ballad soul\nK-ballad trap\nK-ballad, Bossa Nova\nK-ballad, R&B, funk\nK-ballad, R&B, funk-pop\nK-ballad, R&B, lo-fi hip-hop\nK-ballad, R&B, neo-soul\nK-ballad, cinematic hip-hop, ambient soul\nK-ballad, cinematic hip-hop, orchestral\nK-ballad, cinematic pop, pop-rock\nK-ballad, cinematic, synthwave\nK-ballad, city pop, R&B\nK-ballad, dubstep\nK-ballad, electronic, anime theme\nK-ballad, electronic, drum and bass\nK-ballad, hip-hop, pop-rock\nK-ballad, jazz, lo-fi\nK-ballad, late-90s R&B\nK-ballad, lo-fi hip hop\nK-ballad, lo-fi hip hop, R&B\nK-ballad, lo-fi hip hop, pop-rock\nK-ballad, lo-fi, cinematic\nK-ballad, pop-hip hop, cinematic\nK-ballad, pop-rock, hip-hop\nK-ballad, power rock, emotional\nK-ballad, rap-rock, emotional rock\nK-drama\nK-drama OST\nK-drama ballad\nK-drama soundtrack\nK-hip hop\nK-hip hop, cinematic\nK-hip hop, cinematic synth, R&B\nK-hip-hop\nK-hip-hop Afrobeat\nK-hip-hop EDM\nK-hip-hop J-pop funk\nK-hip-hop R&B\nK-hip-hop R&B pop\nK-hip-hop alternative R&B\nK-hip-hop ballad\nK-hip-hop boom-bap\nK-hip-hop chiptune\nK-hip-hop chiptune trap\nK-hip-hop cinematic\nK-hip-hop city pop\nK-hip-hop dance-pop\nK-hip-hop dancehall\nK-hip-hop dark pop\nK-hip-hop electronic\nK-hip-hop electronic pop\nK-hip-hop emo rap\nK-hip-hop emo-rap\nK-hip-hop funk\nK-hip-hop funk chiptune\nK-hip-hop funk disco\nK-hip-hop funk pop\nK-hip-hop funk-pop\nK-hip-hop hardstyle\nK-hip-hop hyperpop\nK-hip-hop hyperpop electronic\nK-hip-hop indie rock\nK-hip-hop jazz\nK-hip-hop lo-fi\nK-hip-hop lo-fi pop\nK-hip-hop neo-soul\nK-hip-hop pop\nK-hip-hop pop-ballad\nK-hip-hop pop-punk\nK-hip-hop pop-rap\nK-hip-hop pop-rock\nK-hip-hop rap-rock\nK-hip-hop retro funk\nK-hip-hop synth-pop\nK-hip-hop tech house\nK-hip-hop trap\nK-hip-hop trap EDM\nK-hip-hop trap chiptune\nK-hip-hop trap emo rap\nK-hip-hop trap pop-rap\nK-hip-hop trap-R&B\nK-hip-hop trap-pop\nK-hip-hop tropical house\nK-hip-hop vaporwave\nK-hip-hop, EDM\nK-hip-hop, EDM, cinematic\nK-hip-hop, EDM, hardstyle\nK-hip-hop, EDM, trap\nK-hip-hop, K-R&B\nK-hip-hop, K-pop, hardstyle\nK-hip-hop, R&B\nK-hip-hop, R&B, boom-bap\nK-hip-hop, chiptune, lo-fi hip hop\nK-hip-hop, chiptune, trap\nK-hip-hop, cinematic pop\nK-hip-hop, cinematic, hardstyle\nK-hip-hop, cinematic, orchestral\nK-hip-hop, cinematic, trap\nK-hip-hop, electronic, retro synth\nK-hip-hop, emo rap, synthwave\nK-hip-hop, festive, boom-bap\nK-hip-hop, hard rock, rap\nK-hip-hop, hardstyle, EDM\nK-hip-hop, hardstyle, cinematic\nK-hip-hop, hardstyle, dubstep\nK-hip-hop, hardstyle, electronic\nK-hip-hop, hyperpop, electronic\nK-hip-hop, hyperpop, glitch\nK-hip-hop, melodic rap\nK-hip-hop, new jack swing\nK-hip-hop, new jack swing, retro\nK-hip-hop, nu-metal, electronic\nK-hip-hop, party-pop\nK-hip-hop, pop-rap, acoustic\nK-hip-hop, pop-rock\nK-hip-hop, pop-rock, atmospheric\nK-hip-hop, pop-rock, cinematic\nK-hip-hop, pop-rock, dubstep\nK-hip-hop, pop-rock, lo-fi\nK-hip-hop, rap-rock, cinematic\nK-hip-hop, synth-pop, new jack swing\nK-hip-hop, trap\nK-hip-hop, trap, EDM\nK-hip-hop, trap, electronic pop\nK-hip-hop, trap, emo rap\nK-hip-hop, trap, futuristic\nK-hip-hop, trap, hyperpop\nK-hip-hop, trap, pop-rap\nK-hiphop\nK-indie\nK-indie Bossa Nova\nK-indie acoustic\nK-indie ballad\nK-indie bossa nova\nK-indie folk\nK-indie lo-fi\nK-indie lo-fi hip hop\nK-indie lo-fi pop\nK-indie neo-soul\nK-indie neo-soul city pop\nK-indie neo-soul lo-fi R&B\nK-indie pop\nK-indie pop city pop\nK-indie pop jazz\nK-indie pop neo-soul\nK-indie, bedroom pop\nK-indie, bossa nova, lounge\nK-indie, lo-fi hip hop, drum and bass\nK-indie, lo-fi, jazz\nK-pop\nK-pop 80s\nK-pop 90s\nK-pop Afrobeats dancehall\nK-pop Bossa Nova\nK-pop C-pop\nK-pop C-pop fusion\nK-pop C-pop hybrid\nK-pop C-pop trap\nK-pop Christian\nK-pop Christmas\nK-pop City Pop\nK-pop City Pop Eurobeat\nK-pop City Pop New Jack Swing\nK-pop EDM\nK-pop EDM fusion\nK-pop EDM future bass\nK-pop EDM hardstyle\nK-pop EDM hip-hop\nK-pop EDM rock\nK-pop EDM rock fusion\nK-pop EDM synth-pop\nK-pop EDM trap\nK-pop EDM-pop\nK-pop Eurobeat\nK-pop Eurodance\nK-pop J-pop\nK-pop J-pop fusion\nK-pop J-pop hybrid\nK-pop J-pop trap\nK-pop J-rock\nK-pop J-rock fusion\nK-pop Latin\nK-pop Latin dance\nK-pop Latin dance-pop\nK-pop Latin flamenco\nK-pop Latin fusion\nK-pop Latin jazz\nK-pop Latin pop\nK-pop Latin pop R&B\nK-pop Latin pop fusion\nK-pop Latin trap\nK-pop Mandopop\nK-pop Mandopop trap\nK-pop New Jack Swing\nK-pop New Jack Swing City Pop\nK-pop R&B\nK-pop R&B Christmas\nK-pop R&B New Jack Swing\nK-pop R&B ballad\nK-pop R&B breakbeat\nK-pop R&B chiptune\nK-pop R&B cinematic\nK-pop R&B city pop\nK-pop R&B dance-pop\nK-pop R&B dancehall\nK-pop R&B deep house\nK-pop R&B dream pop\nK-pop R&B electronic\nK-pop R&B electronic pop\nK-pop R&B funk\nK-pop R&B funk soul\nK-pop R&B fusion\nK-pop R&B future bass\nK-pop R&B hip-hop\nK-pop R&B house\nK-pop R&B jazz\nK-pop R&B lo-fi\nK-pop R&B lo-fi hip hop\nK-pop R&B lo-fi hip-hop\nK-pop R&B neo-soul\nK-pop R&B orchestral\nK-pop R&B rock\nK-pop R&B soul\nK-pop R&B synth-pop\nK-pop R&B trap\nK-pop R&B tropical house\nK-pop R&B, neo-soul, lo-fi hip-hop\nK-pop R&B, synth-pop\nK-pop T-pop fusion\nK-pop V-pop\nK-pop a cappella\nK-pop acoustic\nK-pop acoustic ballad\nK-pop acoustic pop\nK-pop acoustic pop-rap\nK-pop acoustic-pop\nK-pop afrobeat\nK-pop alternative R&B synth-pop\nK-pop ambient\nK-pop anime\nK-pop anime theme\nK-pop ballad\nK-pop ballad Latin\nK-pop ballad Latin pop\nK-pop ballad R&B\nK-pop ballad acoustic pop\nK-pop ballad bossa nova\nK-pop ballad future bass\nK-pop ballad hip-hop\nK-pop ballad indie pop\nK-pop ballad indie pop-rock\nK-pop ballad jazz-pop\nK-pop ballad lo-fi\nK-pop ballad lo-fi R&B\nK-pop ballad lo-fi hip-hop\nK-pop ballad lounge-pop\nK-pop ballad pop-rap\nK-pop ballad rock\nK-pop ballad trot\nK-pop ballad, Bossa Nova\nK-pop ballad, EDM\nK-pop ballad, EDM, anthemic\nK-pop ballad, EDM, dance-pop\nK-pop ballad, EDM, future bass\nK-pop ballad, EDM, hard rock\nK-pop ballad, EDM, synth-pop\nK-pop ballad, EDM, trap\nK-pop ballad, EDM-pop\nK-pop ballad, Latin pop\nK-pop ballad, R&B\nK-pop ballad, R&B, hip-hop\nK-pop ballad, R&B, jazz fusion\nK-pop ballad, R&B, synth-pop\nK-pop ballad, anime OST, J-rock\nK-pop ballad, chillwave\nK-pop ballad, chillwave, future bass\nK-pop ballad, chiptune\nK-pop ballad, cinematic rock\nK-pop ballad, city pop\nK-pop ballad, city pop, jazz-pop\nK-pop ballad, city pop, smooth jazz\nK-pop ballad, city-pop, jazz\nK-pop ballad, city-pop, retro\nK-pop ballad, contemporary R&B\nK-pop ballad, dance-pop\nK-pop ballad, dance-pop, EDM\nK-pop ballad, early 2000s R&B\nK-pop ballad, early 2000s R&B, hip-hop\nK-pop ballad, electronic rock, dubstep\nK-pop ballad, electropop\nK-pop ballad, future bass\nK-pop ballad, future bass, trap\nK-pop ballad, happy hardcore, trancecore\nK-pop ballad, hip-hop\nK-pop ballad, hip-hop, R&B\nK-pop ballad, hip-hop, blues-rock\nK-pop ballad, hip-hop, cinematic\nK-pop ballad, hip-hop, classical\nK-pop ballad, hip-hop, pop-rock\nK-pop ballad, hip-hop, rock\nK-pop ballad, indie-pop\nK-pop ballad, jazz-pop\nK-pop ballad, lo-fi hip-hop\nK-pop ballad, modern R&B, trap\nK-pop ballad, nu-disco, ambient\nK-pop ballad, pop-rap\nK-pop ballad, pop-rap, R&B\nK-pop ballad, pop-rap, pop-rock\nK-pop ballad, pop-rock\nK-pop ballad, pop-rock, anime OST\nK-pop ballad, pop-rock, hip-hop\nK-pop ballad, pop-rock, pop-punk\nK-pop ballad, progressive house\nK-pop ballad, synth-pop\nK-pop ballad, synth-pop, 2000s\nK-pop ballad, synth-pop, cinematic\nK-pop ballad, synth-pop, future bass\nK-pop ballad, trap\nK-pop big band\nK-pop bossa nova\nK-pop bossa nova lounge\nK-pop bossa nova lounge jazz\nK-pop bubblegum\nK-pop bubblegum pop\nK-pop children's\nK-pop children's hip-hop\nK-pop children's music\nK-pop children's pop\nK-pop chiptune\nK-pop cinematic\nK-pop cinematic trap\nK-pop city pop\nK-pop city pop 90s R&B\nK-pop city pop Eurodance\nK-pop city pop R&B\nK-pop city pop anime\nK-pop city pop bossa nova\nK-pop city pop chiptune\nK-pop city pop funk\nK-pop city pop future bass\nK-pop city pop future funk\nK-pop city pop indie pop\nK-pop city pop jazz\nK-pop city pop jazz fusion\nK-pop city pop jazz-funk\nK-pop city pop jazz-fusion\nK-pop city pop jazz-pop\nK-pop city pop light funk\nK-pop city pop lo-fi hip-hop\nK-pop city pop lounge\nK-pop city pop lounge jazz\nK-pop city pop neo-soul\nK-pop city pop new jack swing\nK-pop city pop nu-disco\nK-pop city pop smooth jazz\nK-pop city pop synth-funk\nK-pop city pop synth-pop\nK-pop city pop tropical\nK-pop city pop tropical house\nK-pop city-pop\nK-pop city-pop funk\nK-pop city-pop lounge\nK-pop city-pop neo-soul\nK-pop classical crossover\nK-pop country-pop\nK-pop cyberpunk\nK-pop dance\nK-pop dance pop\nK-pop dance-pop\nK-pop dance-pop EDM\nK-pop dance-pop Latin\nK-pop dance-pop R&B\nK-pop dance-pop electronic\nK-pop dance-pop electropop\nK-pop dance-pop funk\nK-pop dance-pop funk-pop\nK-pop dance-pop hip-hop\nK-pop dance-pop house\nK-pop dance-pop moombahton\nK-pop dance-pop rock\nK-pop dance-pop trap\nK-pop dance-rock\nK-pop dance-rock electronic\nK-pop dancehall\nK-pop dancehall reggaeton\nK-pop deep house\nK-pop deep house UK garage\nK-pop deep house future bass\nK-pop disco-funk\nK-pop drum and bass\nK-pop electro house\nK-pop electro house future bass\nK-pop electro-funk\nK-pop electro-funk chiptune\nK-pop electro-funk dance-pop\nK-pop electro-house\nK-pop electro-house future bass\nK-pop electro-pop\nK-pop electro-pop chiptune\nK-pop electro-pop dance-pop\nK-pop electro-pop hip-hop\nK-pop electro-rock\nK-pop electro-rock chiptune\nK-pop electro-rock dance-pop\nK-pop electro-swing\nK-pop electro-swing funk\nK-pop electro-swing jazz-pop\nK-pop electronic\nK-pop electronic R&B\nK-pop electronic hip-hop\nK-pop electronic pop\nK-pop electronic rock\nK-pop electronic rock EDM\nK-pop electronic rock chiptune\nK-pop electronic rock dance-pop\nK-pop electronic rock dance-punk\nK-pop electronic rock dubstep\nK-pop electronic rock glitch-hop\nK-pop electronic rock hardstyle\nK-pop electronic rock hip-hop\nK-pop electronic rock hyperpop\nK-pop electronic rock industrial\nK-pop electronic rock nu-metal\nK-pop electronic rock trap\nK-pop electronic rock trap metal\nK-pop electronic trap\nK-pop electronicore hyperpop\nK-pop electropop\nK-pop electropop bubblegum pop\nK-pop electropop chiptune\nK-pop electropop dance-pop\nK-pop electropop funk\nK-pop electropop future bass\nK-pop electropop hyperpop\nK-pop electropop synth-pop\nK-pop emo rap\nK-pop emo rock\nK-pop emo-rap\nK-pop emo-trap\nK-pop flamenco fusion\nK-pop folk\nK-pop folk-pop\nK-pop funk\nK-pop funk Latin\nK-pop funk R&B\nK-pop funk big band\nK-pop funk breakbeat\nK-pop funk chiptune\nK-pop funk city pop\nK-pop funk disco\nK-pop funk electronic\nK-pop funk hip-hop\nK-pop funk hyperpop\nK-pop funk indie rock\nK-pop funk jazz fusion\nK-pop funk nu-disco\nK-pop funk pop-rock\nK-pop funk rock\nK-pop funk soul\nK-pop funk-disco\nK-pop funk-pop\nK-pop funk-pop EDM\nK-pop funk-rock\nK-pop funk-rock R&B\nK-pop funk-rock anime\nK-pop funk-rock chiptune\nK-pop funk-rock dance-pop\nK-pop funk-rock disco\nK-pop funk-rock electronic\nK-pop funk-rock hip-hop\nK-pop fusion\nK-pop future bass\nK-pop future bass EDM\nK-pop future bass R&B\nK-pop future bass UK garage\nK-pop future bass chiptune\nK-pop future bass city pop\nK-pop future bass dance-pop\nK-pop future bass deep house\nK-pop future bass drum and bass\nK-pop future bass electro house\nK-pop future bass electro-pop\nK-pop future bass electronic rock\nK-pop future bass electropop\nK-pop future bass hardstyle\nK-pop future bass hip-hop\nK-pop future bass house\nK-pop future bass hyperpop\nK-pop future bass moombahton\nK-pop future bass synth-pop\nK-pop future bass trap\nK-pop future bass tropical house\nK-pop future funk\nK-pop future funk city pop\nK-pop future funk nu-disco\nK-pop future house\nK-pop future house future bass\nK-pop glam rock synth-pop\nK-pop gospel\nK-pop happy hardcore\nK-pop hard dance\nK-pop hard rock\nK-pop hardstyle\nK-pop hardstyle EDM\nK-pop hardstyle chiptune\nK-pop hardstyle electronic\nK-pop hardstyle electronic rock\nK-pop hardstyle trap\nK-pop hip hop\nK-pop hip-hop\nK-pop hip-hop R&B\nK-pop hip-hop ballad\nK-pop hip-hop chiptune\nK-pop hip-hop dance-pop\nK-pop hip-hop electronic\nK-pop hip-hop electronic rock\nK-pop hip-hop funk\nK-pop hip-hop fusion\nK-pop hip-hop hardstyle\nK-pop hip-hop industrial\nK-pop hip-hop pop-punk\nK-pop hip-hop pop-rock\nK-pop hip-hop synth-pop\nK-pop hip-hop trap\nK-pop house\nK-pop hyper-pop\nK-pop hyper-pop anime\nK-pop hyperpop\nK-pop hyperpop C-pop\nK-pop hyperpop EDM\nK-pop hyperpop J-core\nK-pop hyperpop J-pop\nK-pop hyperpop J-rock\nK-pop hyperpop UK garage\nK-pop hyperpop anime\nK-pop hyperpop bubblegum pop\nK-pop hyperpop chiptune\nK-pop hyperpop city pop\nK-pop hyperpop dance-pop\nK-pop hyperpop drum and bass\nK-pop hyperpop electro-house\nK-pop hyperpop electronic\nK-pop hyperpop electronic rock\nK-pop hyperpop electropop\nK-pop hyperpop funk\nK-pop hyperpop future bass\nK-pop hyperpop hardstyle\nK-pop hyperpop hip-hop\nK-pop hyperpop industrial\nK-pop hyperpop moombahton\nK-pop hyperpop nightcore\nK-pop hyperpop rock\nK-pop hyperpop trance\nK-pop hyperpop trap\nK-pop indie pop\nK-pop indie pop jangle pop\nK-pop indie pop-rock\nK-pop indie rock\nK-pop indie-pop\nK-pop indie-pop bossa nova\nK-pop industrial\nK-pop industrial rock\nK-pop jazz\nK-pop jazz R&B\nK-pop jazz ballad\nK-pop jazz big band\nK-pop jazz bossa nova\nK-pop jazz funk\nK-pop jazz fusion\nK-pop jazz swing\nK-pop jazz-funk\nK-pop jazz-funk city pop\nK-pop jazz-pop\nK-pop lo-fi\nK-pop lo-fi R&B\nK-pop lo-fi chiptune\nK-pop lo-fi hip hop\nK-pop lo-fi hip-hop\nK-pop lo-fi hip-hop chiptune\nK-pop lo-fi hip-hop trap\nK-pop lo-fi jazz\nK-pop lounge city-pop\nK-pop lounge jazz\nK-pop lounge swing\nK-pop lounge-jazz\nK-pop lounge-pop\nK-pop lullaby\nK-pop metalcore\nK-pop metalcore electronic\nK-pop metalcore hardstyle\nK-pop moombahton\nK-pop neo-soul\nK-pop neo-soul R&B\nK-pop neo-soul city pop\nK-pop neo-soul funk\nK-pop neo-soul jazz-funk\nK-pop neo-soul jazz-pop\nK-pop neo-soul lo-fi jazz\nK-pop new jack swing\nK-pop novelty\nK-pop nu-disco\nK-pop nu-disco city pop\nK-pop nu-disco funk\nK-pop nu-disco future funk\nK-pop nu-disco house\nK-pop nu-disco synth-funk\nK-pop nu-disco synth-pop\nK-pop nu-metal\nK-pop nu-metal breakbeat\nK-pop nu-metal electronic\nK-pop nu-metal electronic dance\nK-pop nu-metal electronic rock\nK-pop nu-metal rap-rock\nK-pop orchestral\nK-pop orchestral pop\nK-pop pop ballad\nK-pop pop-punk\nK-pop pop-rap\nK-pop pop-rap electronic\nK-pop pop-rock\nK-pop power ballad\nK-pop progressive house\nK-pop rap\nK-pop rap ballad\nK-pop rap-rock\nK-pop rap-rock electronic\nK-pop reggae dancehall\nK-pop retro\nK-pop retro dance-pop\nK-pop retro funk\nK-pop retro rock trot\nK-pop retro swing\nK-pop retro-funk\nK-pop rock\nK-pop rock ballad\nK-pop rock electronic\nK-pop rock electronicore\nK-pop rock fusion\nK-pop rock hybrid\nK-pop rock hyperpop\nK-pop rock reggae\nK-pop rock trot\nK-pop rock, city pop\nK-pop rock, city pop, AOR\nK-pop rock, city pop, funk\nK-pop rock, city pop, jazz\nK-pop rock, city pop, jazz fusion\nK-pop rock, city pop, synth-pop\nK-pop rock, city pop, trot\nK-pop rock, city-pop, theatrical\nK-pop rock, funk, city pop\nK-pop rock, jazz soul\nK-pop show tune\nK-pop soul\nK-pop synth-funk\nK-pop synth-pop\nK-pop synth-pop EDM\nK-pop synth-pop R&B\nK-pop synth-pop chiptune\nK-pop synth-pop city pop\nK-pop synth-pop dance-pop\nK-pop synth-pop electro-pop\nK-pop synth-pop electronic\nK-pop synth-pop electronic rock\nK-pop synth-pop electropop\nK-pop synth-pop funk\nK-pop synth-pop pop-rock\nK-pop synth-pop rock\nK-pop synth-rock\nK-pop synth-rock dance-pop\nK-pop tango cabaret\nK-pop techno\nK-pop trance\nK-pop trap\nK-pop trap EDM\nK-pop trap R&B\nK-pop trap chiptune\nK-pop trap dramatic pop\nK-pop trap dream pop\nK-pop trap electronic\nK-pop trap electronic rock\nK-pop trap hardstyle\nK-pop trap hip-hop\nK-pop trap hyperpop\nK-pop trap metal\nK-pop trap metal hardstyle\nK-pop trap rock\nK-pop trap soul\nK-pop trap-R&B\nK-pop trap-pop\nK-pop trip-hop\nK-pop tropical\nK-pop tropical house\nK-pop tropical house dancehall\nK-pop tropical house moombahton\nK-pop trot\nK-pop trot Eurodance\nK-pop world music\nK-pop, 80s power ballad\nK-pop, 80s, trot\nK-pop, 90s R&B\nK-pop, 90s R&B, hip-hop\nK-pop, 90s R&B, new jack swing\nK-pop, 90s anime, synthwave\nK-pop, 90s dance-pop, Eurobeat\nK-pop, 90s dance-pop, Eurodance\nK-pop, 90s dance-pop, R&B\nK-pop, 90s dance-pop, pop-rock\nK-pop, 90s hip-hop, R&B\nK-pop, 90s hip-hop, breakbeat\nK-pop, 90s house\nK-pop, 90s house, dance\nK-pop, Bossa Nova\nK-pop, Bossa Nova, Latin jazz\nK-pop, Bossa Nova, R&B\nK-pop, Bossa Nova, dance-pop\nK-pop, Bossa Nova, jazz\nK-pop, Bossa Nova, jazz lounge\nK-pop, Bossa Nova, light jazz\nK-pop, C-pop, pop-rap\nK-pop, Christmas\nK-pop, Christmas ballad\nK-pop, Christmas ballad, R&B\nK-pop, Christmas ballad, pop-rock\nK-pop, Christmas pop\nK-pop, Christmas pop, dance-pop\nK-pop, Christmas pop, hip-hop\nK-pop, Christmas, ballad\nK-pop, Christmas, electronic\nK-pop, Christmas, hip-hop\nK-pop, Christmas, pop-rock\nK-pop, City Pop, Eurodance\nK-pop, Contemporary Christian Music\nK-pop, EDM\nK-pop, EDM, R&B\nK-pop, EDM, R&B, hip-hop, rock\nK-pop, EDM, anthemic\nK-pop, EDM, atmospheric\nK-pop, EDM, ballad\nK-pop, EDM, big room house\nK-pop, EDM, chiptune\nK-pop, EDM, cinematic\nK-pop, EDM, cinematic pop\nK-pop, EDM, cyberpunk\nK-pop, EDM, dance\nK-pop, EDM, dance-pop\nK-pop, EDM, electro house\nK-pop, EDM, electronic\nK-pop, EDM, future bass\nK-pop, EDM, futuristic\nK-pop, EDM, hard rock\nK-pop, EDM, hardstyle\nK-pop, EDM, hip-hop\nK-pop, EDM, hyperpop\nK-pop, EDM, indie rock\nK-pop, EDM, industrial\nK-pop, EDM, industrial rock\nK-pop, EDM, live concert\nK-pop, EDM, moombahton\nK-pop, EDM, orchestral\nK-pop, EDM, party\nK-pop, EDM, pop\nK-pop, EDM, pop-rap\nK-pop, EDM, pop-rock\nK-pop, EDM, rock\nK-pop, EDM, rock fusion\nK-pop, EDM, stadium anthem\nK-pop, EDM, synth-pop\nK-pop, EDM, traditional East Asian\nK-pop, EDM, traditional Korean\nK-pop, EDM, trance\nK-pop, EDM, trap\nK-pop, EDM, tropical house\nK-pop, EDM-pop\nK-pop, EDM-pop, future bass\nK-pop, EDM-trap\nK-pop, Eurobeat\nK-pop, Eurobeat, 2000s dance-pop\nK-pop, Eurobeat, 90s dance-pop\nK-pop, Eurobeat, City Pop\nK-pop, Eurobeat, Italo disco\nK-pop, Eurobeat, J-pop\nK-pop, Eurobeat, J-rock\nK-pop, Eurobeat, anime\nK-pop, Eurobeat, anime theme\nK-pop, Eurobeat, bubblegum pop\nK-pop, Eurobeat, chiptune\nK-pop, Eurobeat, dance\nK-pop, Eurobeat, dance-pop\nK-pop, Eurobeat, electronic\nK-pop, Eurobeat, happy hardcore\nK-pop, Eurobeat, hyperpop\nK-pop, Eurobeat, retro-futuristic\nK-pop, Eurobeat, synthwave\nK-pop, Eurobeat, trance\nK-pop, Eurobeat, trot\nK-pop, Eurodance\nK-pop, Eurodance, 2000s\nK-pop, Eurodance, 2000s dance\nK-pop, Eurodance, 2000s dance-pop\nK-pop, Eurodance, 2000s pop\nK-pop, Eurodance, 90s R&B\nK-pop, Eurodance, 90s dance\nK-pop, Eurodance, 90s dance-pop\nK-pop, Eurodance, City Pop\nK-pop, Eurodance, EDM\nK-pop, Eurodance, Hi-NRG\nK-pop, Eurodance, Italo dance\nK-pop, Eurodance, Italo disco\nK-pop, Eurodance, J-pop\nK-pop, Eurodance, K trot\nK-pop, Eurodance, Latin\nK-pop, Eurodance, Latin pop\nK-pop, Eurodance, New Jack Swing\nK-pop, Eurodance, Trance\nK-pop, Eurodance, Y2K\nK-pop, Eurodance, anime\nK-pop, Eurodance, ballad\nK-pop, Eurodance, bubblegum pop\nK-pop, Eurodance, chiptune\nK-pop, Eurodance, dance\nK-pop, Eurodance, dance pop\nK-pop, Eurodance, dance-pop\nK-pop, Eurodance, dancehall\nK-pop, Eurodance, electronic\nK-pop, Eurodance, electropop\nK-pop, Eurodance, funk\nK-pop, Eurodance, happy hardcore\nK-pop, Eurodance, hip-hop\nK-pop, Eurodance, hip-house\nK-pop, Eurodance, house\nK-pop, Eurodance, hyperpop\nK-pop, Eurodance, industrial\nK-pop, Eurodance, lo-fi\nK-pop, Eurodance, new jack swing\nK-pop, Eurodance, retro\nK-pop, Eurodance, retro synth\nK-pop, Eurodance, retro-futuristic\nK-pop, Eurodance, rhythm game\nK-pop, Eurodance, rock\nK-pop, Eurodance, synth-pop\nK-pop, Eurodance, synthwave\nK-pop, Eurodance, techno\nK-pop, Eurodance, techno-pop\nK-pop, Eurodance, trance\nK-pop, Eurodance, trot\nK-pop, European folk\nK-pop, Indonesian pop, lo-fi hip hop\nK-pop, J-core, happy hardcore\nK-pop, J-pop\nK-pop, J-pop, Christmas\nK-pop, J-pop, Eurodance\nK-pop, J-pop, anime\nK-pop, J-pop, anime theme\nK-pop, J-pop, children's music\nK-pop, J-pop, chiptune\nK-pop, J-pop, cinematic\nK-pop, J-pop, cinematic pop\nK-pop, J-pop, dance-pop\nK-pop, J-pop, electronic dance\nK-pop, J-pop, electronic pop\nK-pop, J-pop, happy hardcore\nK-pop, J-pop, hardstyle\nK-pop, J-pop, lo-fi\nK-pop, J-pop, pop ballad\nK-pop, J-pop, sentimental pop\nK-pop, J-pop, trance\nK-pop, J-pop, video game music\nK-pop, J-rock\nK-pop, J-rock, anime\nK-pop, J-rock, anime theme\nK-pop, J-rock, anison\nK-pop, J-rock, chiptune\nK-pop, J-rock, cinematic\nK-pop, J-rock, cinematic ballad\nK-pop, J-rock, electronic\nK-pop, J-rock, electronic dance\nK-pop, J-rock, funk\nK-pop, J-rock, hyperpop\nK-pop, J-rock, lo-fi hip hop\nK-pop, J-rock, pop-rock\nK-pop, J-rock, power ballad\nK-pop, J-rock, rap-rock\nK-pop, J-rock, synth-pop\nK-pop, K-hip-hop\nK-pop, K-hip-hop, pop-rock\nK-pop, Korean hip-hop\nK-pop, Latin dance\nK-pop, Latin dance-pop\nK-pop, Latin jazz, city pop\nK-pop, Latin jazz, funk\nK-pop, Latin pop\nK-pop, Latin pop, Bossa Nova\nK-pop, Latin pop, dance\nK-pop, Latin pop, dance-pop\nK-pop, Latin pop, funk\nK-pop, Latin pop, reggaeton\nK-pop, Latin pop, retro\nK-pop, Latin pop, trap\nK-pop, Latin, Bossa Nova\nK-pop, Latin, cumbia\nK-pop, Latin, flamenco\nK-pop, Latin, novelty\nK-pop, Latin, retro\nK-pop, Latin-pop, dance-pop\nK-pop, Moombahton\nK-pop, Moombahton, EDM\nK-pop, Moombahton, Latin pop\nK-pop, Moombahton, dance-pop\nK-pop, New Jack Swing\nK-pop, New Jack Swing, City Pop\nK-pop, New Jack Swing, Eurodance\nK-pop, New Jack Swing, Funk\nK-pop, New Jack Swing, Hip Hop\nK-pop, New Jack Swing, R&B\nK-pop, New Jack Swing, cinematic\nK-pop, New Jack Swing, dance-pop\nK-pop, New Jack Swing, funk\nK-pop, New Jack Swing, retro\nK-pop, New Jack Swing, retro R&B\nK-pop, New Jack Swing, synth funk\nK-pop, R&B\nK-pop, R&B, 2000s\nK-pop, R&B, Christmas\nK-pop, R&B, Christmas ballad\nK-pop, R&B, Christmas pop\nK-pop, R&B, EDM\nK-pop, R&B, New Jack Swing\nK-pop, R&B, ambient\nK-pop, R&B, ballad\nK-pop, R&B, baroque-pop\nK-pop, R&B, cinematic\nK-pop, R&B, city pop\nK-pop, R&B, city-pop\nK-pop, R&B, dance-pop\nK-pop, R&B, dancehall\nK-pop, R&B, dream pop\nK-pop, R&B, electronic\nK-pop, R&B, electronic dance\nK-pop, R&B, experimental\nK-pop, R&B, funk\nK-pop, R&B, future bass\nK-pop, R&B, gospel\nK-pop, R&B, hip-hop\nK-pop, R&B, hip-hop, EDM\nK-pop, R&B, lo-fi\nK-pop, R&B, lo-fi hip-hop\nK-pop, R&B, neo-soul\nK-pop, R&B, new jack swing\nK-pop, R&B, piano ballad\nK-pop, R&B, pop\nK-pop, R&B, pop ballad\nK-pop, R&B, pop-rap\nK-pop, R&B, pop-rock\nK-pop, R&B, power ballad\nK-pop, R&B, rock\nK-pop, R&B, soul\nK-pop, R&B, synth funk\nK-pop, R&B, synth-pop\nK-pop, R&B, synthwave\nK-pop, R&B, trap\nK-pop, R&B, trip-hop\nK-pop, R&B, winter pop\nK-pop, UK Hardcore\nK-pop, UK garage\nK-pop, UK garage, 2-step\nK-pop, UK garage, ethereal\nK-pop, Western pop\nK-pop, Y2K dance-pop\nK-pop, Y2K, dance\nK-pop, acid jazz, city pop\nK-pop, acoustic pop-rock\nK-pop, acoustic-pop, jazz\nK-pop, alternative R&B, electronic\nK-pop, ambient pop\nK-pop, ambient pop, R&B\nK-pop, ambient synth\nK-pop, ambient trap\nK-pop, ambient, blues\nK-pop, ambient, cinematic\nK-pop, ambient, electronic\nK-pop, ambient, horror\nK-pop, anime\nK-pop, anime OST, cinematic\nK-pop, anime OST, emotional ballad\nK-pop, anime jazz\nK-pop, anime opening, EDM\nK-pop, anime opening, cinematic\nK-pop, anime opening, dance-pop\nK-pop, anime opening, electronic\nK-pop, anime opening, pop-rock\nK-pop, anime soundtrack\nK-pop, anime soundtrack, children's pop\nK-pop, anime soundtrack, early 2000s\nK-pop, anime soundtrack, electronic\nK-pop, anime soundtrack, pop-rock\nK-pop, anime theme\nK-pop, anime theme, children's music\nK-pop, anime theme, chiptune\nK-pop, anime theme, dance-pop\nK-pop, anime theme, dream pop\nK-pop, anime theme, electronic\nK-pop, anime theme, high-energy\nK-pop, anime theme, hyperpop\nK-pop, anime theme, jazzy\nK-pop, anime theme, orchestral\nK-pop, anime theme, pop ballad\nK-pop, anime theme, pop-rock\nK-pop, anime theme, power ballad\nK-pop, anime theme, rock\nK-pop, anime, children's\nK-pop, anime, children's music\nK-pop, anime, children's pop\nK-pop, anime, children's pop-rock\nK-pop, anime, pop\nK-pop, anime, video game\nK-pop, anime-style\nK-pop, atmospheric, trap\nK-pop, ballad\nK-pop, ballad, Christmas\nK-pop, ballad, EDM\nK-pop, bedroom pop, dreamy\nK-pop, big band swing\nK-pop, big band, electro-swing\nK-pop, big band, swing\nK-pop, big band, theatrical\nK-pop, big beat, breakbeat\nK-pop, boogie-woogie, swing\nK-pop, bossa nova, city pop\nK-pop, bossa nova, lo-fi hip-hop\nK-pop, breakbeat\nK-pop, breakbeat, lo-fi hip hop\nK-pop, breakbeat, synthwave\nK-pop, bubblegum\nK-pop, bubblegum pop\nK-pop, bubblegum pop, children's music\nK-pop, bubblegum pop, electropop\nK-pop, cabaret, swing\nK-pop, children's music\nK-pop, children's music, cartoon soundtrack\nK-pop, children's music, chiptune\nK-pop, children's music, dance\nK-pop, children's music, educational\nK-pop, children's music, electronic\nK-pop, children's music, pop\nK-pop, children's music, retro video game\nK-pop, children's music, rock\nK-pop, children's music, summer\nK-pop, children's music, upbeat\nK-pop, children's music, video game\nK-pop, children's music, video game music\nK-pop, children's music, video game soundtrack\nK-pop, children's music, vintage\nK-pop, children's pop\nK-pop, children's, anime\nK-pop, children's, chiptune\nK-pop, children's, electronic\nK-pop, children's, hyperpop\nK-pop, children's, playful\nK-pop, chiptune\nK-pop, chiptune, Eurodance\nK-pop, chiptune, J-rock\nK-pop, chiptune, R&B\nK-pop, chiptune, Y2K\nK-pop, chiptune, anime\nK-pop, chiptune, ballad\nK-pop, chiptune, bubblegum\nK-pop, chiptune, bubblegum pop\nK-pop, chiptune, children's\nK-pop, chiptune, children's music\nK-pop, chiptune, children's pop\nK-pop, chiptune, city-pop\nK-pop, chiptune, dance\nK-pop, chiptune, dance-pop\nK-pop, chiptune, electro-pop\nK-pop, chiptune, electronic\nK-pop, chiptune, electronic dance\nK-pop, chiptune, electronic rock\nK-pop, chiptune, festive\nK-pop, chiptune, funk\nK-pop, chiptune, future bass\nK-pop, chiptune, happy hardcore\nK-pop, chiptune, hip-hop\nK-pop, chiptune, hyper-pop\nK-pop, chiptune, hyperpop\nK-pop, chiptune, lo-fi\nK-pop, chiptune, novelty\nK-pop, chiptune, pop\nK-pop, chiptune, pop-rock\nK-pop, chiptune, retro\nK-pop, chiptune, retro-futuristic\nK-pop, chiptune, surf rock\nK-pop, chiptune, synth-pop\nK-pop, chiptune, synthwave\nK-pop, chiptune, trap\nK-pop, chiptune, trot\nK-pop, chiptune, upbeat\nK-pop, chiptune, video game music\nK-pop, cinematic\nK-pop, cinematic EDM\nK-pop, cinematic R&B\nK-pop, cinematic hip-hop\nK-pop, cinematic orchestral\nK-pop, cinematic pop\nK-pop, cinematic pop, musical theater\nK-pop, cinematic pop, pop-rock\nK-pop, cinematic pop, trot\nK-pop, cinematic rock\nK-pop, cinematic synth\nK-pop, cinematic synth, chiptune\nK-pop, cinematic synth, hip-hop\nK-pop, cinematic synth, retro video game\nK-pop, cinematic synth, trap\nK-pop, cinematic trap\nK-pop, cinematic, EDM\nK-pop, cinematic, R&B\nK-pop, cinematic, anime theme\nK-pop, cinematic, ballad\nK-pop, cinematic, dance\nK-pop, cinematic, dance-pop\nK-pop, cinematic, dark ballad\nK-pop, cinematic, dubstep\nK-pop, cinematic, electronic\nK-pop, cinematic, emotional\nK-pop, cinematic, epic\nK-pop, cinematic, festive\nK-pop, cinematic, funk\nK-pop, cinematic, future bass\nK-pop, cinematic, hip-hop\nK-pop, cinematic, horror\nK-pop, cinematic, late-90s\nK-pop, cinematic, lo-fi\nK-pop, cinematic, moombahton\nK-pop, cinematic, nu-metal\nK-pop, cinematic, orchestral\nK-pop, cinematic, pop-rock\nK-pop, cinematic, power ballad\nK-pop, cinematic, rock\nK-pop, cinematic, synthwave\nK-pop, cinematic, theatrical\nK-pop, cinematic, trap\nK-pop, cinematic, tribal\nK-pop, city pop\nK-pop, city pop, 90s R&B\nK-pop, city pop, J-pop\nK-pop, city pop, R&B\nK-pop, city pop, anime\nK-pop, city pop, anime soundtrack\nK-pop, city pop, ballad\nK-pop, city pop, bossa nova\nK-pop, city pop, dance\nK-pop, city pop, dance-pop\nK-pop, city pop, disco\nK-pop, city pop, dream pop\nK-pop, city pop, funk\nK-pop, city pop, future funk\nK-pop, city pop, indie-pop\nK-pop, city pop, jazz\nK-pop, city pop, jazz fusion\nK-pop, city pop, jazz-fusion\nK-pop, city pop, light jazz\nK-pop, city pop, lo-fi\nK-pop, city pop, lo-fi hip-hop\nK-pop, city pop, lounge\nK-pop, city pop, lounge jazz\nK-pop, city pop, neo-soul\nK-pop, city pop, new jack swing\nK-pop, city pop, new wave\nK-pop, city pop, nu-disco\nK-pop, city pop, pop-rock\nK-pop, city pop, retro\nK-pop, city pop, retro dance\nK-pop, city pop, retro dance-pop\nK-pop, city pop, retro rock\nK-pop, city pop, retro-funk\nK-pop, city pop, retro-futuristic\nK-pop, city pop, smooth jazz\nK-pop, city pop, soft rock\nK-pop, city pop, synth brass\nK-pop, city pop, synth funk\nK-pop, city pop, synth pop\nK-pop, city pop, synth-funk\nK-pop, city pop, synth-pop\nK-pop, city pop, synthwave\nK-pop, city pop, trot\nK-pop, city-pop\nK-pop, city-pop, R&B\nK-pop, city-pop, ballad\nK-pop, city-pop, dance\nK-pop, city-pop, dreamy ballad\nK-pop, city-pop, electronic\nK-pop, city-pop, funk\nK-pop, city-pop, jazz\nK-pop, city-pop, retro\nK-pop, city-pop, retro-funk, R&B, orchestral\nK-pop, city-pop, retro-futuristic\nK-pop, city-pop, synth-pop\nK-pop, city-pop, synthwave\nK-pop, classical crossover\nK-pop, classical, soul\nK-pop, complextro, electronic\nK-pop, complextro, hardstyle\nK-pop, cumbia\nK-pop, cyberpunk\nK-pop, cyberpunk, EDM\nK-pop, cyberpunk, dance-pop\nK-pop, cyberpunk, dubstep\nK-pop, cyberpunk, electronic\nK-pop, cyberpunk, hyperpop\nK-pop, cyberpunk, industrial\nK-pop, cyberpunk, synthwave\nK-pop, cyberpunk, trap\nK-pop, dance, Eurodance\nK-pop, dance, chiptune\nK-pop, dance, city pop\nK-pop, dance, early 2000s\nK-pop, dance, electronic\nK-pop, dance, hip-hop\nK-pop, dance, tropical\nK-pop, dance-pop\nK-pop, dance-pop, 2000s\nK-pop, dance-pop, 2000s pop\nK-pop, dance-pop, EDM\nK-pop, dance-pop, Eurobeat\nK-pop, dance-pop, Eurodance\nK-pop, dance-pop, Latin\nK-pop, dance-pop, R&B\nK-pop, dance-pop, anime\nK-pop, dance-pop, anime theme\nK-pop, dance-pop, breakbeat\nK-pop, dance-pop, bubblegum pop\nK-pop, dance-pop, chiptune\nK-pop, dance-pop, cinematic\nK-pop, dance-pop, cyberpunk\nK-pop, dance-pop, early 2000s\nK-pop, dance-pop, electronic\nK-pop, dance-pop, electronic rock\nK-pop, dance-pop, electropop\nK-pop, dance-pop, funk\nK-pop, dance-pop, futuristic\nK-pop, dance-pop, hip-hop\nK-pop, dance-pop, holiday\nK-pop, dance-pop, house\nK-pop, dance-pop, hyperpop\nK-pop, dance-pop, late-90s house\nK-pop, dance-pop, lo-fi\nK-pop, dance-pop, moombahton\nK-pop, dance-pop, new jack swing\nK-pop, dance-pop, nu-disco\nK-pop, dance-pop, orchestral\nK-pop, dance-pop, pop-rock\nK-pop, dance-pop, retro\nK-pop, dance-pop, retro synth\nK-pop, dance-pop, retro video game\nK-pop, dance-pop, retro-futuristic\nK-pop, dance-pop, synth-pop\nK-pop, dance-pop, traditional Korean\nK-pop, dance-pop, trap\nK-pop, dance-pop, trot\nK-pop, dance-pop, video game music\nK-pop, dance-pop, world music\nK-pop, dance-rock, traditional Korean\nK-pop, dancehall, moombahton\nK-pop, dancehall, rap\nK-pop, dancehall, reggaeton\nK-pop, dark R&B, trap\nK-pop, dark electro, cyberpunk\nK-pop, dark pop\nK-pop, dark pop, cinematic\nK-pop, dark synth-pop, electro-pop\nK-pop, dark trap\nK-pop, deep house\nK-pop, deep house, future bass\nK-pop, dembow\nK-pop, dembow, electronic\nK-pop, denpa, happy hardcore\nK-pop, disco, EDM\nK-pop, disco, city pop\nK-pop, disco, dance-pop\nK-pop, disco, funk\nK-pop, disco, trot\nK-pop, disco-funk\nK-pop, disco-funk, novelty\nK-pop, dream pop\nK-pop, dream pop, R&B\nK-pop, dream pop, emotional rock\nK-pop, dream pop, hip-hop\nK-pop, dream pop, pop-rock\nK-pop, dream trap\nK-pop, dreamy synth\nK-pop, drum and bass\nK-pop, drum and bass, J-pop\nK-pop, drum and bass, electronic\nK-pop, dubstep\nK-pop, dubstep, dance-pop\nK-pop, dubstep, hardstyle\nK-pop, dubstep, trap\nK-pop, early 2000s\nK-pop, early 2000s R&B\nK-pop, early 2000s R&B, hip-hop\nK-pop, early 2000s hip-hop\nK-pop, early 2000s house\nK-pop, early 2000s, dance\nK-pop, educational pop\nK-pop, electro house\nK-pop, electro house, dance-pop\nK-pop, electro house, dubstep\nK-pop, electro house, hyperpop\nK-pop, electro-funk, new jack swing\nK-pop, electro-house\nK-pop, electro-house, dance-pop\nK-pop, electro-house, hardstyle\nK-pop, electro-pop\nK-pop, electro-pop, bubblegum pop\nK-pop, electro-pop, chiptune\nK-pop, electro-pop, cinematic\nK-pop, electro-pop, cyberpunk\nK-pop, electro-pop, dance\nK-pop, electro-pop, dance-pop\nK-pop, electro-pop, future bass\nK-pop, electro-pop, hyperpop\nK-pop, electro-pop, new jack swing\nK-pop, electronic\nK-pop, electronic R&B\nK-pop, electronic dance\nK-pop, electronic dance music\nK-pop, electronic dance, cyberpunk\nK-pop, electronic dance, futuristic\nK-pop, electronic dance, hardstyle\nK-pop, electronic dance, hip-hop\nK-pop, electronic dance, industrial\nK-pop, electronic dance, rock\nK-pop, electronic dance, trap\nK-pop, electronic dance-pop\nK-pop, electronic hip-hop\nK-pop, electronic hip-hop, hardstyle\nK-pop, electronic hip-hop, orchestral\nK-pop, electronic hip-hop, trap\nK-pop, electronic pop\nK-pop, electronic pop, future bass\nK-pop, electronic rock\nK-pop, electronic rock, EDM\nK-pop, electronic rock, dance-pop\nK-pop, electronic rock, dubstep\nK-pop, electronic rock, futuristic\nK-pop, electronic rock, hardstyle\nK-pop, electronic rock, hip-hop\nK-pop, electronic rock, hyperpop\nK-pop, electronic rock, industrial\nK-pop, electronic rock, rap\nK-pop, electronic rock, synth-pop\nK-pop, electronic rock, trap metal\nK-pop, electronic, EDM\nK-pop, electronic, R&B\nK-pop, electronic, aggressive\nK-pop, electronic, ambient\nK-pop, electronic, anime\nK-pop, electronic, breakbeat\nK-pop, electronic, cinematic\nK-pop, electronic, club\nK-pop, electronic, cyberpunk\nK-pop, electronic, dance\nK-pop, electronic, dark\nK-pop, electronic, dream pop\nK-pop, electronic, emotional\nK-pop, electronic, flamenco\nK-pop, electronic, funk\nK-pop, electronic, futuristic\nK-pop, electronic, glitch\nK-pop, electronic, hip hop\nK-pop, electronic, hip-hop\nK-pop, electronic, horror\nK-pop, electronic, industrial\nK-pop, electronic, pop\nK-pop, electronic, pop-rock\nK-pop, electronic, retro game\nK-pop, electronic, ritual\nK-pop, electronic, rock\nK-pop, electronic, sci-fi\nK-pop, electronic, synthpop\nK-pop, electronic, synthwave\nK-pop, electronic, trap\nK-pop, electronic, video game\nK-pop, electropop\nK-pop, electropop, bubblegum pop\nK-pop, electropop, dance\nK-pop, electropop, dance-pop\nK-pop, electropop, future bass\nK-pop, electropop, trap\nK-pop, emotional, ambient\nK-pop, ethereal trap\nK-pop, experimental, glitch\nK-pop, festive\nK-pop, festive hip-hop\nK-pop, festive pop\nK-pop, festive, R&B\nK-pop, festive, cinematic\nK-pop, festive, comedic\nK-pop, festive, dance\nK-pop, festive, electronic\nK-pop, festive, late-90s pop\nK-pop, festive, pop\nK-pop, festive, romantic\nK-pop, flamenco, Latin\nK-pop, flamenco, ballad\nK-pop, flamenco, electronic\nK-pop, flamenco, pop\nK-pop, flamenco, pop-rock\nK-pop, flamenco, synth pop\nK-pop, flamenco, synthwave\nK-pop, folk fusion, pop-rap\nK-pop, funk\nK-pop, funk pop, R&B\nK-pop, funk rock\nK-pop, funk rock, chiptune\nK-pop, funk rock, cinematic\nK-pop, funk, 90s R&B\nK-pop, funk, EDM\nK-pop, funk, R&B\nK-pop, funk, acoustic pop-rock\nK-pop, funk, breakbeat\nK-pop, funk, city pop\nK-pop, funk, city-pop\nK-pop, funk, classical\nK-pop, funk, dance\nK-pop, funk, dance-pop\nK-pop, funk, disco\nK-pop, funk, early 2000s\nK-pop, funk, early 2000s R&B\nK-pop, funk, electro-pop\nK-pop, funk, electronic\nK-pop, funk, electronic pop\nK-pop, funk, electronic rock\nK-pop, funk, hip-hop\nK-pop, funk, hip-hop, EDM\nK-pop, funk, house\nK-pop, funk, new jack swing\nK-pop, funk, pop-rock\nK-pop, funk, retro\nK-pop, funk, retro-futuristic\nK-pop, funk, retro-modern\nK-pop, funk, rock\nK-pop, funk, synth-pop\nK-pop, funk, trap\nK-pop, funk, upbeat\nK-pop, funk, video game\nK-pop, funk-pop, rock\nK-pop, funk-rock\nK-pop, funk-rock, cinematic\nK-pop, funk-rock, dance-pop\nK-pop, funk-rock, electronic\nK-pop, funk-rock, electronic dance\nK-pop, funk-rock, hip-hop\nK-pop, funk-rock, new jack swing\nK-pop, funk-rock, pop-punk\nK-pop, future R&B, trap\nK-pop, future bass\nK-pop, future bass, EDM\nK-pop, future bass, J-core\nK-pop, future bass, R&B\nK-pop, future bass, UK garage\nK-pop, future bass, anime\nK-pop, future bass, cyberpunk\nK-pop, future bass, dance\nK-pop, future bass, dubstep\nK-pop, future bass, electronic\nK-pop, future bass, electronic pop\nK-pop, future bass, hip-hop\nK-pop, future bass, hyperpop\nK-pop, future bass, pop-rock\nK-pop, future bass, rock\nK-pop, future bass, trap\nK-pop, future bass, vaporwave\nK-pop, future funk, dance-pop\nK-pop, futuristic pop, bubblegum pop\nK-pop, futuristic, anime\nK-pop, futuristic, aquatic\nK-pop, futuristic, chiptune\nK-pop, futuristic, cosmic\nK-pop, futuristic, cyberpunk\nK-pop, futuristic, electronic\nK-pop, futuristic, trap\nK-pop, glitch hop\nK-pop, glitch hop, cyberpunk\nK-pop, glitch hop, electronic\nK-pop, glitch, ambient\nK-pop, glitch-hop\nK-pop, happy hardcore\nK-pop, happy hardcore, J-core\nK-pop, happy hardcore, chiptune\nK-pop, happy hardcore, cinematic\nK-pop, happy hardcore, denpa\nK-pop, happy hardcore, electronic\nK-pop, happy hardcore, electronic rock\nK-pop, happy hardcore, hardstyle\nK-pop, happy hardcore, hyperpop\nK-pop, happy hardcore, nightcore\nK-pop, happy hardcore, rap-rock\nK-pop, happy hardcore, trance\nK-pop, happy hardcore, video game music\nK-pop, hard rock\nK-pop, hard rock, EDM\nK-pop, hard rock, electronic\nK-pop, hard rock, electronic dance\nK-pop, hard rock, hip-hop\nK-pop, hard rock, hyperpop\nK-pop, hard rock, trap\nK-pop, hardcore techno\nK-pop, hardstyle\nK-pop, hardstyle, EDM\nK-pop, hardstyle, EDM trap\nK-pop, hardstyle, Eurodance\nK-pop, hardstyle, big room house\nK-pop, hardstyle, breakbeat\nK-pop, hardstyle, cinematic EDM\nK-pop, hardstyle, complextro\nK-pop, hardstyle, cyberpunk\nK-pop, hardstyle, dubstep\nK-pop, hardstyle, electro house\nK-pop, hardstyle, electro-pop\nK-pop, hardstyle, electronic\nK-pop, hardstyle, electronic rock\nK-pop, hardstyle, happy hardcore\nK-pop, hardstyle, hip-hop\nK-pop, hardstyle, hyperpop\nK-pop, hardstyle, moombahton\nK-pop, hardstyle, psytrance\nK-pop, hardstyle, synth-pop\nK-pop, hardstyle, trance\nK-pop, hardstyle, trap\nK-pop, hip-hop\nK-pop, hip-hop, EDM\nK-pop, hip-hop, J-pop\nK-pop, hip-hop, R&B\nK-pop, hip-hop, ballad\nK-pop, hip-hop, breakbeat\nK-pop, hip-hop, bubblegum pop\nK-pop, hip-hop, chiptune\nK-pop, hip-hop, cinematic\nK-pop, hip-hop, cinematic pop\nK-pop, hip-hop, dance\nK-pop, hip-hop, dance-pop\nK-pop, hip-hop, dubstep\nK-pop, hip-hop, electro-pop\nK-pop, hip-hop, electronic\nK-pop, hip-hop, electronic dance\nK-pop, hip-hop, electronic rock\nK-pop, hip-hop, emotional\nK-pop, hip-hop, epic rock\nK-pop, hip-hop, festive\nK-pop, hip-hop, flamenco\nK-pop, hip-hop, funk\nK-pop, hip-hop, funk-rock\nK-pop, hip-hop, hardstyle\nK-pop, hip-hop, jazz\nK-pop, hip-hop, lo-fi\nK-pop, hip-hop, new jack swing\nK-pop, hip-hop, orchestral\nK-pop, hip-hop, pop\nK-pop, hip-hop, pop-rock\nK-pop, hip-hop, power ballad\nK-pop, hip-hop, retro\nK-pop, hip-hop, rock\nK-pop, hip-hop, swing\nK-pop, hip-hop, synth-funk\nK-pop, hip-hop, synth-pop\nK-pop, hip-hop, traditional Korean\nK-pop, hip-hop, trap\nK-pop, house\nK-pop, house, R&B\nK-pop, house, dance\nK-pop, house, dance-pop\nK-pop, house, retro\nK-pop, hyper-pop\nK-pop, hyper-pop, EDM\nK-pop, hyper-pop, anime\nK-pop, hyper-pop, bubblegum\nK-pop, hyper-pop, children's\nK-pop, hyper-pop, children's music\nK-pop, hyper-pop, chiptune\nK-pop, hyper-pop, video game\nK-pop, hyperpop\nK-pop, hyperpop, 90s dance-pop\nK-pop, hyperpop, EDM\nK-pop, hyperpop, Eurobeat\nK-pop, hyperpop, Eurodance\nK-pop, hyperpop, J-core\nK-pop, hyperpop, J-pop\nK-pop, hyperpop, J-rock\nK-pop, hyperpop, R&B\nK-pop, hyperpop, R&B, pop-rock, pop-punk\nK-pop, hyperpop, UK garage\nK-pop, hyperpop, UK hardcore\nK-pop, hyperpop, Y2K\nK-pop, hyperpop, anime opening\nK-pop, hyperpop, bubblegum\nK-pop, hyperpop, bubblegum bass\nK-pop, hyperpop, bubblegum pop\nK-pop, hyperpop, bubblegum trap\nK-pop, hyperpop, children's music\nK-pop, hyperpop, chiptune\nK-pop, hyperpop, cyberpunk\nK-pop, hyperpop, dance\nK-pop, hyperpop, drum and bass\nK-pop, hyperpop, electronic\nK-pop, hyperpop, electronic dance\nK-pop, hyperpop, electronic dance music\nK-pop, hyperpop, electronic rock\nK-pop, hyperpop, electropop\nK-pop, hyperpop, future bass\nK-pop, hyperpop, glitch-hop\nK-pop, hyperpop, glitch-pop\nK-pop, hyperpop, happy hardcore\nK-pop, hyperpop, hard dance\nK-pop, hyperpop, hardstyle\nK-pop, hyperpop, industrial\nK-pop, hyperpop, moombahton\nK-pop, hyperpop, nightcore\nK-pop, hyperpop, trap\nK-pop, hyperpop, video game\nK-pop, hyperpop, video game music\nK-pop, indie pop, R&B\nK-pop, indie rock, hip-hop\nK-pop, indie rock, pop-rock\nK-pop, industrial\nK-pop, industrial rock, electronic\nK-pop, industrial rock, electronic dance\nK-pop, industrial rock, electronicore\nK-pop, industrial, aggressive\nK-pop, industrial, cinematic\nK-pop, industrial, cyberpunk\nK-pop, industrial, electronic\nK-pop, industrial, ethereal\nK-pop, industrial, hip-hop\nK-pop, industrial, nu-metal\nK-pop, industrial, trap\nK-pop, jazz\nK-pop, jazz ballad\nK-pop, jazz pop\nK-pop, jazz, R&B\nK-pop, jazz, ambient\nK-pop, jazz, big band\nK-pop, jazz, boogie-woogie\nK-pop, jazz, cinematic\nK-pop, jazz, city pop\nK-pop, jazz, cozy\nK-pop, jazz, funk\nK-pop, jazz, pop\nK-pop, jazz, romantic\nK-pop, jazz, spy movie\nK-pop, jazz, upbeat\nK-pop, jazz-funk, city pop\nK-pop, jazzy R&B\nK-pop, jazzy pop\nK-pop, jazzy, boogie-woogie\nK-pop, jazzy, romantic\nK-pop, jazzy, upbeat\nK-pop, light R&B\nK-pop, lo-fi R&B\nK-pop, lo-fi R&B, electronic\nK-pop, lo-fi electronic\nK-pop, lo-fi hip hop\nK-pop, lo-fi hip hop, anime soundtrack\nK-pop, lo-fi hip hop, electronic\nK-pop, lo-fi hip hop, hardstyle\nK-pop, lo-fi hip hop, jazz\nK-pop, lo-fi hip hop, neo-soul\nK-pop, lo-fi hip hop, vaporwave\nK-pop, lo-fi hip-hop\nK-pop, lo-fi hip-hop, dream pop\nK-pop, lo-fi jazz, ambient\nK-pop, lo-fi, EDM\nK-pop, lo-fi, ambient\nK-pop, lo-fi, bedroom pop\nK-pop, lo-fi, cinematic\nK-pop, lo-fi, dream pop\nK-pop, lo-fi, electronic\nK-pop, lo-fi, pop-rock\nK-pop, lo-fi, power ballad\nK-pop, lo-fi, retro-futuristic\nK-pop, lo-fi, soul\nK-pop, lo-fi, vaporwave\nK-pop, melancholic, trap\nK-pop, melodic hip-hop, pop-rap\nK-pop, melodic trap\nK-pop, melodic trap, chiptune\nK-pop, melodic trap, electronic\nK-pop, minimalist hip-hop\nK-pop, moombahton\nK-pop, moombahton, dancehall\nK-pop, moombahton, hard dance\nK-pop, moombahton, reggaeton\nK-pop, moombahton, trap\nK-pop, musical theater\nK-pop, musical theater, big band\nK-pop, musical theater, children's music\nK-pop, musical theater, cinematic ballad\nK-pop, neo-soul, R&B\nK-pop, neo-soul, city pop\nK-pop, neo-soul, funk\nK-pop, neo-soul, jazzy ballad\nK-pop, neo-soul, lo-fi hip-hop\nK-pop, new jack swing\nK-pop, new jack swing, 2000s pop\nK-pop, new jack swing, 90s R&B\nK-pop, new jack swing, 90s dance-pop\nK-pop, new jack swing, Eurodance\nK-pop, new jack swing, Latin\nK-pop, new jack swing, R&B\nK-pop, new jack swing, ballad\nK-pop, new jack swing, breakbeat\nK-pop, new jack swing, chiptune\nK-pop, new jack swing, cinematic\nK-pop, new jack swing, city pop\nK-pop, new jack swing, dance\nK-pop, new jack swing, dance-pop\nK-pop, new jack swing, electronic\nK-pop, new jack swing, funk\nK-pop, new jack swing, funk-pop\nK-pop, new jack swing, hip-hop\nK-pop, new jack swing, hip-house\nK-pop, new jack swing, house\nK-pop, new jack swing, hyperpop\nK-pop, new jack swing, pop\nK-pop, new jack swing, pop-rock\nK-pop, new jack swing, retro\nK-pop, new jack swing, retro dance\nK-pop, new jack swing, retro pop\nK-pop, new jack swing, retro synth\nK-pop, new jack swing, retro-futuristic\nK-pop, new jack swing, synth funk\nK-pop, new jack swing, synth-pop\nK-pop, new wave, synth-pop\nK-pop, novelty, dance\nK-pop, nu-disco\nK-pop, nu-disco, city pop\nK-pop, nu-disco, funk\nK-pop, nu-disco, future funk\nK-pop, nu-disco, house\nK-pop, nu-disco, pop\nK-pop, nu-disco, retro-futuristic\nK-pop, nu-disco, synth-pop\nK-pop, nu-metal, electronic dance\nK-pop, nu-metal, electronic rock\nK-pop, nu-metal, industrial rock\nK-pop, old-school hip-hop\nK-pop, orchestral pop\nK-pop, orchestral rock, electronic\nK-pop, orchestral, ballad\nK-pop, orchestral, dance-pop\nK-pop, orchestral, electronic\nK-pop, orchestral, festive\nK-pop, orchestral, funk\nK-pop, orchestral, synth-pop\nK-pop, orchestral, trap\nK-pop, piano ballad\nK-pop, pop\nK-pop, pop ballad, R&B\nK-pop, pop, rock\nK-pop, pop-R&B\nK-pop, pop-R&B, hip-hop\nK-pop, pop-ballad, hip-hop\nK-pop, pop-funk\nK-pop, pop-punk\nK-pop, pop-punk, EDM\nK-pop, pop-punk, electronic\nK-pop, pop-punk, electronic dance\nK-pop, pop-punk, electronic rock\nK-pop, pop-punk, hyperpop\nK-pop, pop-punk, rap-rock\nK-pop, pop-punk, rock\nK-pop, pop-punk, trap\nK-pop, pop-rap\nK-pop, pop-rock\nK-pop, pop-rock, Christmas\nK-pop, pop-rock, EDM\nK-pop, pop-rock, J-rock\nK-pop, pop-rock, R&B\nK-pop, pop-rock, anime\nK-pop, pop-rock, anime OST\nK-pop, pop-rock, anime rock\nK-pop, pop-rock, anime theme\nK-pop, pop-rock, atmospheric\nK-pop, pop-rock, children's music\nK-pop, pop-rock, chiptune\nK-pop, pop-rock, cinematic\nK-pop, pop-rock, dance\nK-pop, pop-rock, dance-pop\nK-pop, pop-rock, early 2000s\nK-pop, pop-rock, electronic\nK-pop, pop-rock, electronic dance\nK-pop, pop-rock, emotional\nK-pop, pop-rock, festive\nK-pop, pop-rock, funk\nK-pop, pop-rock, funky\nK-pop, pop-rock, future bass\nK-pop, pop-rock, hip-hop\nK-pop, pop-rock, jazz-funk\nK-pop, pop-rock, lo-fi\nK-pop, pop-rock, lo-fi hip hop\nK-pop, pop-rock, retro\nK-pop, pop-rock, retro anime\nK-pop, pop-rock, trot\nK-pop, pop-trap\nK-pop, pop-trap, R&B\nK-pop, pop/R&B\nK-pop, power ballad\nK-pop, power ballad, 80s synth\nK-pop, power ballad, R&B\nK-pop, power ballad, anime\nK-pop, power ballad, anime OST\nK-pop, power ballad, anime soundtrack\nK-pop, power ballad, anime theme\nK-pop, power ballad, cinematic\nK-pop, power ballad, hip-hop\nK-pop, power ballad, orchestral\nK-pop, power ballad, pop-rock\nK-pop, power ballad, rock\nK-pop, power ballad, synth-pop\nK-pop, power pop, dream pop\nK-pop, power-pop, hip-hop\nK-pop, progressive house\nK-pop, progressive house, big room\nK-pop, progressive house, trance\nK-pop, punk rock\nK-pop, punk rock, electronic dance\nK-pop, quirky pop\nK-pop, rap-rock, electronic\nK-pop, rave, electronic\nK-pop, reggaeton\nK-pop, reggaeton, Latin pop\nK-pop, reggaeton, electronic\nK-pop, reggaeton, moombahton\nK-pop, retro 90s, dance\nK-pop, retro Eurodance\nK-pop, retro R&B\nK-pop, retro anime, pop-rock\nK-pop, retro dance\nK-pop, retro dance, 90s pop\nK-pop, retro dance, Eurodance\nK-pop, retro dance, chiptune\nK-pop, retro dance, electronic\nK-pop, retro dance, funk\nK-pop, retro dance, synth funk\nK-pop, retro dance, synth pop\nK-pop, retro dance, video game music\nK-pop, retro dance-pop\nK-pop, retro dance-pop, Eurobeat\nK-pop, retro dance-pop, bubblegum pop\nK-pop, retro dance-pop, city pop\nK-pop, retro dance-pop, funk\nK-pop, retro dance-pop, house\nK-pop, retro dance-pop, new jack swing\nK-pop, retro dance-pop, trot\nK-pop, retro disco, city pop\nK-pop, retro electronic\nK-pop, retro funk\nK-pop, retro funk, R&B\nK-pop, retro funk, city pop\nK-pop, retro funk, disco\nK-pop, retro funk, new jack swing\nK-pop, retro game\nK-pop, retro game, chiptune\nK-pop, retro hip-hop\nK-pop, retro house\nK-pop, retro house, new jack swing\nK-pop, retro new jack swing\nK-pop, retro new jack swing, G-funk\nK-pop, retro new jack swing, hip-hop\nK-pop, retro pop-rock\nK-pop, retro rock, trot\nK-pop, retro swing, big band\nK-pop, retro synth\nK-pop, retro synth, dance\nK-pop, retro synth, electronic\nK-pop, retro synth, folk pop\nK-pop, retro synth-pop, city pop\nK-pop, retro trot\nK-pop, retro video game\nK-pop, retro video game, anime theme\nK-pop, retro video game, happy hardcore\nK-pop, retro, 2000s\nK-pop, retro, Eurodance\nK-pop, retro, R&B\nK-pop, retro, breakbeat\nK-pop, retro, children's\nK-pop, retro, chiptune\nK-pop, retro, cinematic\nK-pop, retro, dance\nK-pop, retro, dance-pop\nK-pop, retro, doo-wop\nK-pop, retro, electronic\nK-pop, retro, funk\nK-pop, retro, hip-hop\nK-pop, retro, new jack swing\nK-pop, retro, pop-funk\nK-pop, retro, synth funk\nK-pop, retro, synthwave\nK-pop, retro, trot\nK-pop, retro-funk\nK-pop, retro-funk, R&B\nK-pop, retro-funk, city pop\nK-pop, retro-funk, dance-pop\nK-pop, retro-funk, disco\nK-pop, retro-funk, new jack swing\nK-pop, retro-funk, trot\nK-pop, retro-funk, upbeat\nK-pop, retro-futuristic\nK-pop, retro-futuristic, 90s dance-pop\nK-pop, retro-futuristic, Eurodance\nK-pop, retro-futuristic, Y2K\nK-pop, retro-futuristic, anime\nK-pop, retro-futuristic, chiptune\nK-pop, retro-futuristic, city pop\nK-pop, retro-futuristic, dance\nK-pop, retro-futuristic, dance-pop\nK-pop, retro-futuristic, electronic\nK-pop, retro-futuristic, funk\nK-pop, retro-futuristic, glam rock\nK-pop, retro-futuristic, new jack swing\nK-pop, retro-futuristic, synth-pop\nK-pop, retro-futuristic, synthwave\nK-pop, retro-pop, musical theater\nK-pop, retro-swing, big band\nK-pop, rock, R&B\nK-pop, rock, electronic\nK-pop, rock, funk\nK-pop, rock, hip-hop\nK-pop, rock, nu-metal\nK-pop, rock, orchestral\nK-pop, rock, synth\nK-pop, rock-infused pop\nK-pop, rock-pop\nK-pop, rock-tronica, electronic\nK-pop, romantic ballad, 2000s OST\nK-pop, shoegaze, electronic\nK-pop, show tune\nK-pop, spy thriller\nK-pop, stadium rock\nK-pop, stadium rock, electronic\nK-pop, synth-funk\nK-pop, synth-pop\nK-pop, synth-pop, Christian\nK-pop, synth-pop, Christian praise\nK-pop, synth-pop, EDM\nK-pop, synth-pop, Eurobeat\nK-pop, synth-pop, Eurodance\nK-pop, synth-pop, Italo disco\nK-pop, synth-pop, Italo-disco\nK-pop, synth-pop, R&B\nK-pop, synth-pop, acoustic pop-rock\nK-pop, synth-pop, anime\nK-pop, synth-pop, anime theme\nK-pop, synth-pop, bubblegum pop\nK-pop, synth-pop, cartoonish\nK-pop, synth-pop, children's\nK-pop, synth-pop, children's music\nK-pop, synth-pop, chiptune\nK-pop, synth-pop, city pop\nK-pop, synth-pop, city-pop\nK-pop, synth-pop, cyberpunk\nK-pop, synth-pop, dance-pop\nK-pop, synth-pop, dance-rock\nK-pop, synth-pop, disco\nK-pop, synth-pop, electro-funk\nK-pop, synth-pop, electro-pop\nK-pop, synth-pop, electro-rock\nK-pop, synth-pop, electronic\nK-pop, synth-pop, electronic dance\nK-pop, synth-pop, electronic dance music\nK-pop, synth-pop, electronic rock\nK-pop, synth-pop, festive\nK-pop, synth-pop, funk\nK-pop, synth-pop, funk-pop\nK-pop, synth-pop, future bass\nK-pop, synth-pop, future funk\nK-pop, synth-pop, futuristic\nK-pop, synth-pop, hardstyle\nK-pop, synth-pop, hip-hop\nK-pop, synth-pop, house\nK-pop, synth-pop, lo-fi\nK-pop, synth-pop, new jack swing\nK-pop, synth-pop, nu-disco\nK-pop, synth-pop, pop-rock\nK-pop, synth-pop, retro\nK-pop, synth-pop, retro dance-pop\nK-pop, synth-pop, retro-futuristic\nK-pop, synth-pop, trance\nK-pop, synth-pop, trot\nK-pop, synth-rock, anime theme\nK-pop, synth-rock, dance-pop\nK-pop, synth-rock, electronicore\nK-pop, synth-rock, stadium rock\nK-pop, synthwave, Italo disco\nK-pop, synthwave, electronic rock\nK-pop, synthwave, lo-fi\nK-pop, synthwave, rock\nK-pop, synthwave, shoegaze\nK-pop, tango, ballad\nK-pop, techno, Eurodance\nK-pop, techno, hardstyle\nK-pop, theatrical pop\nK-pop, theatrical, electronic\nK-pop, theatrical, funk\nK-pop, theatrical, hip-hop\nK-pop, theatrical, orchestral\nK-pop, theatrical, show tune\nK-pop, traditional Korean folk\nK-pop, trance, EDM\nK-pop, trance, electronic\nK-pop, trance, happy hardcore\nK-pop, trance, rock\nK-pop, trap\nK-pop, trap R&B\nK-pop, trap R&B, cinematic\nK-pop, trap hip-hop\nK-pop, trap metal, electronic rock\nK-pop, trap metal, hardstyle\nK-pop, trap metal, traditional Korean\nK-pop, trap, EDM\nK-pop, trap, Middle Eastern\nK-pop, trap, Middle Eastern fusion\nK-pop, trap, R&B\nK-pop, trap, alternative R&B\nK-pop, trap, ambient\nK-pop, trap, ambient R&B\nK-pop, trap, atmospheric\nK-pop, trap, brass\nK-pop, trap, chiptune\nK-pop, trap, cinematic\nK-pop, trap, cyberpunk\nK-pop, trap, dance\nK-pop, trap, dance-pop\nK-pop, trap, dark\nK-pop, trap, dark pop\nK-pop, trap, dark synth\nK-pop, trap, dramatic\nK-pop, trap, dream pop\nK-pop, trap, dreamy\nK-pop, trap, dubstep\nK-pop, trap, electronic\nK-pop, trap, electronic dance\nK-pop, trap, electronic pop\nK-pop, trap, emotional\nK-pop, trap, ethereal\nK-pop, trap, future bass\nK-pop, trap, futuristic\nK-pop, trap, girl crush\nK-pop, trap, hardstyle\nK-pop, trap, hip-hop\nK-pop, trap, horror\nK-pop, trap, hyperpop\nK-pop, trap, industrial\nK-pop, trap, industrial hip-hop\nK-pop, trap, lo-fi\nK-pop, trap, moombahton\nK-pop, trap, orchestral\nK-pop, trap, pop\nK-pop, trap, pop ballad\nK-pop, trap, pop-rock\nK-pop, trap, rock\nK-pop, trap, synth\nK-pop, trap, synth bass\nK-pop, trap, synth pop\nK-pop, trap, synth-pop\nK-pop, trap, synthpop\nK-pop, trap, synthwave\nK-pop, trap, theatrical\nK-pop, trap, traditional East Asian\nK-pop, trap, traditional Korean\nK-pop, trip-hop, cinematic\nK-pop, tropical house\nK-pop, tropical pop, cinematic\nK-pop, trot\nK-pop, trot fusion\nK-pop, trot, Eurobeat\nK-pop, trot, Eurodance\nK-pop, trot, Latin dance\nK-pop, trot, anime\nK-pop, trot, big band\nK-pop, trot, cinematic\nK-pop, trot, dance\nK-pop, trot, dance-pop\nK-pop, trot, retro\nK-pop, trot, retro dance\nK-pop, trot, rock\nK-pop, trot, rockabilly\nK-pop, trot, synthwave\nK-pop, vaporwave, Moombahton\nK-pop, vaporwave, R&B\nK-pop, vaporwave, electronic\nK-pop, video game music\nK-pop, video game music, children's\nK-pop, video game music, children's music\nK-pop, vintage, ballad\nK-pop, worship, electronic\nK-rock\nK-rock J-rock\nK-rock anime theme\nK-rock ballad\nK-rock chiptune\nK-rock electronic\nK-rock electronicore\nK-rock funk\nK-rock hardstyle\nK-rock hip-hop\nK-rock hip-hop fusion\nK-rock hyperpop\nK-rock nu-metal\nK-rock nu-metal electronic\nK-rock pop-punk\nK-rock rap-rock\nK-rock trot-punk\nK-rock, K-ballad, pop, pop-rock\nK-rock, Latin rock\nK-rock, cinematic rock\nK-rock, cinematic, nu-metal\nK-rock, industrial, electronic\nK-rock, nu-metal, electronic\nK-rock, pop-punk, synth-pop, R&B, trap\nK-rock, pop-rock, emo\nK-rock, trap R&B\nK-rock, trip-hop, cinematic\nK-trap\nKannada EDM\nKannada anthem\nKannada ballad\nKannada bhajan\nKannada dance\nKannada dance remix\nKannada devotional\nKannada devotional, electronic fusion\nKannada electronic dance\nKannada film anthem\nKannada film music\nKannada film music retro\nKannada film music world fusion\nKannada film music world music\nKannada film song\nKannada film song, retro, chiptune\nKannada film-pop\nKannada filmi\nKannada folk\nKannada folk dance\nKannada folk funk-pop\nKannada folk hip-hop\nKannada folk pop-funk\nKannada folk rock\nKannada folk, chiptune, funk\nKannada folk, electronic dance\nKannada folk-funk\nKannada folk-pop\nKannada hip-hop\nKannada hip-hop chiptune\nKannada pop\nKannada pop EDM\nKannada pop R&B\nKannada pop R&B Latin\nKannada pop R&B funk\nKannada pop filmi\nKannada pop funk disco\nKannada pop retro\nKannada pop world music fusion\nKannada pop, Bhangra, EDM\nKannada pop, Bollywood, 2000s\nKannada pop, Bollywood, 2000s pop\nKannada pop, EDM\nKannada pop, EDM, dance-pop\nKannada pop, EDM, hip-hop\nKannada pop, Eurodance\nKannada pop, R&B, hip-hop\nKannada pop, electronic dance\nKannada pop, electronic dance music\nKannada pop, electronic dance, bhangra\nKannada pop, electronic dance, hip-hop\nKannada pop, electronic, Indian classical\nKannada pop, electronic, dance\nKannada pop, electronic, hip-hop\nKannada pop, electronic, world music\nKannada pop, funk, disco\nKannada pop, funk, electronic\nKannada pop, hard rock, electronic\nKannada pop, hip-hop, trap\nKannada pop, kuthu\nKannada pop, trap R&B\nKannada pop, world music fusion\nKannada pop-dance\nKannada pop-folk\nKannada pop-funk\nKannada pop-rap\nKannada pop-rock\nKannada rap, electronic dance music\nKannada rap, electronic dance, trap\nKayōkyoku\nKayōkyoku Bossa Nova\nKayōkyoku City Pop\nKayōkyoku City Pop AOR\nKayōkyoku City Pop disco\nKayōkyoku City Pop funk\nKayōkyoku City Pop lounge\nKayōkyoku Enka\nKayōkyoku J-pop\nKayōkyoku J-rock\nKayōkyoku Latin\nKayōkyoku Latin bolero\nKayōkyoku Latin disco\nKayōkyoku Latin groove\nKayōkyoku Latin jazz\nKayōkyoku Latin jazz big band\nKayōkyoku Latin jazz bolero\nKayōkyoku Latin jazz lounge\nKayōkyoku Latin jazz mambo\nKayōkyoku Latin jazz salsa\nKayōkyoku Latin jazz tango\nKayōkyoku Latin pop\nKayōkyoku acoustic rock\nKayōkyoku big band\nKayōkyoku big band jazz\nKayōkyoku big band rock\nKayōkyoku blues\nKayōkyoku blues big band\nKayōkyoku blues jazz\nKayōkyoku blues lounge jazz\nKayōkyoku blues rock\nKayōkyoku blues-rock\nKayōkyoku bolero\nKayōkyoku bossa nova\nKayōkyoku chamber pop\nKayōkyoku chanson\nKayōkyoku chiptune\nKayōkyoku cinematic\nKayōkyoku city pop\nKayōkyoku classical crossover\nKayōkyoku cool jazz\nKayōkyoku country\nKayōkyoku country-rock\nKayōkyoku disco Latin\nKayōkyoku disco funk\nKayōkyoku disco-funk\nKayōkyoku disco-pop\nKayōkyoku disco-rock\nKayōkyoku exotica\nKayōkyoku flamenco\nKayōkyoku folk-rock\nKayōkyoku funk disco\nKayōkyoku funk rock\nKayōkyoku funk-rock\nKayōkyoku hard rock\nKayōkyoku jazz\nKayōkyoku jazz big band\nKayōkyoku jazz blues\nKayōkyoku jazz lounge\nKayōkyoku lounge\nKayōkyoku lounge jazz\nKayōkyoku lounge jazz bossa nova\nKayōkyoku lounge-pop\nKayōkyoku mambo\nKayōkyoku orchestral\nKayōkyoku orchestral pop\nKayōkyoku rock\nKayōkyoku rockabilly surf rock\nKayōkyoku salsa\nKayōkyoku stadium rock\nKayōkyoku surf rock\nKayōkyoku surf-rock\nKayōkyoku tango\nKayōkyoku tango cabaret\nKayōkyoku, 1960s ballad\nKayōkyoku, City Pop\nKayōkyoku, City Pop, AOR\nKayōkyoku, City Pop, Enka\nKayōkyoku, City Pop, Latin\nKayōkyoku, City Pop, arena rock\nKayōkyoku, City Pop, cinematic ballad\nKayōkyoku, City Pop, disco\nKayōkyoku, City Pop, lounge jazz\nKayōkyoku, City Pop, rock\nKayōkyoku, European folk\nKayōkyoku, J-pop, Latin pop\nKayōkyoku, Latin bolero\nKayōkyoku, Latin disco, city pop\nKayōkyoku, Latin disco, mambo\nKayōkyoku, Latin disco, pop-rock\nKayōkyoku, Latin jazz\nKayōkyoku, Latin jazz, big band\nKayōkyoku, Latin jazz, mambo\nKayōkyoku, Latin tango, theatrical\nKayōkyoku, Latin, 70s spy\nKayōkyoku, Latin, anime theme\nKayōkyoku, Latin, big band\nKayōkyoku, Latin, cinematic\nKayōkyoku, Latin, theatrical\nKayōkyoku, anime soundtrack\nKayōkyoku, big band pop\nKayōkyoku, big band, Enka\nKayōkyoku, big band, children's music\nKayōkyoku, big band, disco-pop\nKayōkyoku, big band, swing\nKayōkyoku, chanson\nKayōkyoku, chanson, vintage\nKayōkyoku, cinematic\nKayōkyoku, cinematic ballad\nKayōkyoku, cinematic, Enka\nKayōkyoku, cinematic, surf rock\nKayōkyoku, city pop, big band\nKayōkyoku, classical crossover\nKayōkyoku, disco, city pop\nKayōkyoku, disco-funk\nKayōkyoku, dream pop, cinematic lounge\nKayōkyoku, hard rock\nKayōkyoku, hard rock, blues\nKayōkyoku, jazz lounge\nKayōkyoku, lounge jazz, film noir\nKayōkyoku, orchestral, Enka\nKayōkyoku, orchestral, big band\nKayōkyoku, rockabilly, swing\nKayōkyoku, surf rock, vintage ballad\nKayōkyoku, vocal jazz\nKazakh electronic\nKazakh folk\nKazakh folk, hard electronic, dance\nKazakh folk-pop\nKazakh hip-hop\nKazakh hip-hop trap\nKazakh pop\nKazakh pop Eurodance\nKazakh pop Latin dance\nKazakh pop, EDM\nKazakh pop, EDM, dance-pop\nKazakh pop, EDM, slap house\nKazakh pop, Eurodance\nKazakh pop, Eurodance, EDM\nKazakh pop, Eurodance, chiptune\nKazakh pop, Eurodance, happy hardcore\nKazakh pop, Eurodance, synth-pop\nKazakh pop, Eurodance, trance\nKazakh pop, Latin dance\nKazakh pop, Latin pop\nKazakh pop, R&B, electronic\nKazakh pop, modern trap, cinematic\nKazakh pop-dance\nKazakh pop-rap\nKazakh trap\nKeroncong\nKeroncong Cumbia\nKeroncong Latin\nKeroncong Pop Melayu\nKeroncong Salsa\nKeroncong ballad\nKeroncong pop\nKeroncong salsa\nKeroncong world music\nKeroncong, City Pop\nKeroncong, Cumbia, vintage Indonesian pop\nKeroncong, Pop Melayu, nostalgic\nKeroncong, Pop Sunda\nKeroncong, Pop Sunda, vintage Indonesian pop\nKeroncong, Sunda, vintage pop\nKeroncong, vintage Indonesian pop\nKeroncong, vintage pop\nKeroncong, vintage pop, dramatic ballad\nKhaleeji\nKhaleeji folk\nKhaleeji pop\nKhaleeji pop orchestral\nKhaleeji pop, cinematic Arabic\nKhaleeji pop, cinematic orchestral\nKhmer Pop EDM\nKhmer electronic\nKhmer folk\nKhmer hip-hop electronic\nKhmer pop\nKhmer pop trap\nKhmer pop, Eurodance, chiptune\nKhmer pop-rap\nKhmer trap\nKinderlied\nKinderlieder\nKirtan\nKizomba\nKizomba Afro-pop\nKizomba Afrobeat\nKizomba Afrobeats\nKizomba Bossa Nova\nKizomba Cumbia\nKizomba Dancehall\nKizomba New Jack Swing\nKizomba R&B\nKizomba R&B hip-hop\nKizomba R&B lo-fi\nKizomba Samba\nKizomba Zouk\nKizomba Zouk fusion\nKizomba chiptune\nKizomba cinematic\nKizomba electronic\nKizomba hip hop\nKizomba hip-hop\nKizomba pop\nKizomba pop chiptune\nKizomba soul\nKizomba synth-pop\nKizomba world music\nKizomba, Afrobeats, chiptune\nKizomba, Angolan folk\nKizomba, Dancehall, Afro-Latin\nKizomba, Zouk, pop\nKizomba, cinematic synth, orchestral\nKizomba, cinematic, Afro-electro\nKizomba, cinematic, ambient\nKizomba, cinematic, tango\nKizomba-pop\nKlezmer\nKlezmer Balkan\nKlezmer Balkan fusion\nKlezmer Eurodance\nKlezmer Latin fusion\nKlezmer big band\nKlezmer dance\nKlezmer dance-pop\nKlezmer electronic\nKlezmer folk\nKlezmer folk rock\nKlezmer folk-pop\nKlezmer folk-rock\nKlezmer funk\nKlezmer funk big band\nKlezmer funk pop-rock\nKlezmer funk rock\nKlezmer funk-rock\nKlezmer fusion\nKlezmer fusion, Balkan brass, pop-rock\nKlezmer fusion, Latin funk, salsa\nKlezmer hip-hop\nKlezmer jazz\nKlezmer metal\nKlezmer polka\nKlezmer pop\nKlezmer pop-rock\nKlezmer punk\nKlezmer punk rock\nKlezmer punk rock surf rock\nKlezmer rock\nKlezmer rockabilly\nKlezmer rockabilly big band\nKlezmer ska\nKlezmer ska salsa\nKlezmer ska-punk big band\nKlezmer ska-punk chiptune\nKlezmer ska-punk rock\nKlezmer surf rock\nKlezmer surf rock big band\nKlezmer swing\nKlezmer, Balkan brass\nKlezmer, Balkan brass, big band swing\nKlezmer, Balkan brass, surf rock\nKlezmer, Balkan folk\nKlezmer, Balkan folk, cinematic\nKlezmer, Balkan folk, free jazz\nKlezmer, Balkan folk, instrumental\nKlezmer, Balkan folk, jazz\nKlezmer, Balkan folk, piano ballad\nKlezmer, Balkan folk, theatrical jazz\nKlezmer, Balkan pop, theatrical cabaret\nKlezmer, Balkan, big band\nKlezmer, Balkan, dance\nKlezmer, Balkan, electronic dance\nKlezmer, Balkan, folk\nKlezmer, Eastern European, cinematic\nKlezmer, European folk\nKlezmer, ballad, Hebrew folk\nKlezmer, big band, choral\nKlezmer, cabaret, folk rock\nKlezmer, cinematic, Balkan\nKlezmer, cinematic, folk\nKlezmer, classical, folk\nKlezmer, electronic, quirky\nKlezmer, ethereal, folk fusion\nKlezmer, folk, C-pop\nKlezmer, folk, Eastern European\nKlezmer, folk, Middle Eastern\nKlezmer, folk, cinematic\nKlezmer, folk, instrumental\nKlezmer, folk, playful\nKlezmer, folk, world\nKlezmer, musette, folk\nKlezmer, opera, folk rock\nKlezmer, polka, theatrical\nKlezmer, theatrical, festive\nKlezmer, theatrical, folk\nKlezmer-inspired synth\nKlezmer-pop\nKlezmer-punk\nKlezmer-rock\nKlezmer-ska\nKlezmer-ska-punk\nKollywood\nKollywood dance\nKollywood dance-pop\nKollywood dance-pop, Eurodance\nKollywood film music\nKollywood film score\nKollywood funk\nKollywood fusion\nKollywood pop\nKollywood, festive, dance\nKolo euro\nKolo', African folk, high-energy\nKolo', South African folk\nKompa\nKompa Cumbia\nKompa Soca\nKompa Zouk\nKompa gospel\nKompa hip-hop\nKompa pop\nKompa, Zouk, Afro-Latin\nKompa, Zouk, chiptune\nKompa, cinematic\nKorean Christian\nKorean Christian ballad\nKorean Christian contemporary\nKorean Christian hymn\nKorean Christian pop\nKorean Christian pop-rock\nKorean Christian praise\nKorean Christian, retro trot, praise\nKorean Pansori\nKorean Pansori, boom-bap hip-hop\nKorean Pansori, cinematic, orchestral\nKorean Pansori, electronic\nKorean Pansori, electronic dance\nKorean Pansori, folk-rock\nKorean Pansori, hard rock\nKorean Pansori, retro funk, soul\nKorean R&B\nKorean R&B acoustic pop\nKorean R&B city pop\nKorean R&B funk-pop\nKorean R&B hip-hop\nKorean R&B lo-fi\nKorean R&B lo-fi hip hop\nKorean R&B lo-fi hip-hop\nKorean R&B soul\nKorean R&B trap\nKorean R&B, 90s hip-hop\nKorean R&B, City Pop\nKorean R&B, G-funk\nKorean R&B, Hip Hop\nKorean R&B, Hip-Hop\nKorean R&B, boom-bap, lo-fi hip hop\nKorean R&B, city pop\nKorean R&B, city pop, neo-soul\nKorean R&B, city-pop\nKorean R&B, dream pop\nKorean R&B, early 2000s hip-hop\nKorean R&B, emo rap\nKorean R&B, emo rap, lo-fi\nKorean R&B, funk-pop, 2000s\nKorean R&B, hip hop\nKorean R&B, hip-hop\nKorean R&B, hip-hop ballad\nKorean R&B, hip-hop, ballad\nKorean R&B, hip-hop, bedroom pop\nKorean R&B, hip-hop, boom-bap\nKorean R&B, hip-hop, funk\nKorean R&B, hip-hop, future bass\nKorean R&B, hip-hop, jazz\nKorean R&B, hip-hop, jazzy\nKorean R&B, hip-hop, lo-fi\nKorean R&B, hip-hop, neo-soul\nKorean R&B, hip-hop, trap\nKorean R&B, hip-hop, vaporwave\nKorean R&B, lo-fi hip hop\nKorean R&B, lo-fi hip hop, jazz\nKorean R&B, lo-fi hip-hop\nKorean R&B, lo-fi hip-hop, neo-soul\nKorean R&B, lo-fi trap\nKorean R&B, neo-soul\nKorean R&B, neo-soul, city pop\nKorean R&B, new jack swing\nKorean R&B, pop\nKorean R&B, pop ballad\nKorean R&B, pop ballad, hip-hop\nKorean R&B, pop-rap\nKorean R&B, pop-rock\nKorean R&B, pop-rock, cinematic\nKorean R&B, soul\nKorean R&B, trap\nKorean R&B, trap, ambient\nKorean R&B, trap, emotional\nKorean R&B, trap, hip-hop\nKorean R&B, trap, melancholic\nKorean R&B, trap, melodic hip-hop\nKorean R&B, trap-soul, lo-fi\nKorean acoustic ballad\nKorean acoustic pop\nKorean alternative rock\nKorean ambient\nKorean ballad\nKorean ballad Bossa Nova\nKorean ballad Latin\nKorean ballad R&B\nKorean ballad alternative rock\nKorean ballad blues-rock\nKorean ballad bossa nova\nKorean ballad cinematic\nKorean ballad city pop lounge\nKorean ballad funk-rock\nKorean ballad future bass\nKorean ballad hip-hop\nKorean ballad jazz\nKorean ballad jazz blues\nKorean ballad jazz bossa nova\nKorean ballad jazz-pop\nKorean ballad lounge jazz\nKorean ballad lounge jazz bossa nova\nKorean ballad orchestral\nKorean ballad pop-rock\nKorean ballad post-rock\nKorean ballad rock\nKorean ballad trot\nKorean ballad, 70s funk, soul\nKorean ballad, 70s jazz-pop, psychedelic\nKorean ballad, 80s city pop, synth-pop\nKorean ballad, 90s pop-rock, city pop\nKorean ballad, Bossa Nova\nKorean ballad, Bossa Nova, ambient\nKorean ballad, Bossa Nova, lounge jazz\nKorean ballad, European folk\nKorean ballad, Latin jazz, tango\nKorean ballad, Latin pop\nKorean ballad, Latin pop, tango\nKorean ballad, Latin pop-rock\nKorean ballad, Mandarin ballad\nKorean ballad, R&B, cinematic\nKorean ballad, R&B, indie pop\nKorean ballad, R&B, lo-fi hip-hop\nKorean ballad, acoustic pop-folk, Korean rock\nKorean ballad, blues, jazz\nKorean ballad, chiptune\nKorean ballad, cinematic orchestral\nKorean ballad, cinematic pop, orchestral\nKorean ballad, cinematic pop, traditional fusion\nKorean ballad, cinematic rock, ambient folk\nKorean ballad, cinematic, disco\nKorean ballad, cinematic, new-age\nKorean ballad, cinematic, orchestral\nKorean ballad, city pop\nKorean ballad, city pop, jazz\nKorean ballad, city pop, jazz-fusion\nKorean ballad, city pop, lounge\nKorean ballad, city pop, new wave\nKorean ballad, city pop, soft rock\nKorean ballad, city pop, trot\nKorean ballad, city-pop\nKorean ballad, city-pop, dream pop\nKorean ballad, country, trot\nKorean ballad, hard rock\nKorean ballad, hip-hop, pop-rock\nKorean ballad, hip-hop, rock\nKorean ballad, indie rock\nKorean ballad, jazz ballad\nKorean ballad, jazz soul\nKorean ballad, jazz, R&B\nKorean ballad, jazz, bossa nova\nKorean ballad, jazz, melancholic\nKorean ballad, jazz, soul\nKorean ballad, lo-fi, vintage\nKorean ballad, lounge jazz, cinematic\nKorean ballad, lounge, city pop\nKorean ballad, neo-soul, hip-hop\nKorean ballad, pop-rock\nKorean ballad, pop-rock, cinematic\nKorean ballad, pop-rock, hip-hop\nKorean ballad, power rock, blues rock\nKorean ballad, psychedelic funk\nKorean ballad, rock ballad\nKorean ballad, rock, cinematic\nKorean ballad, rock, shoegaze\nKorean ballad, soul, jazz\nKorean ballad, synth-pop\nKorean ballad, synth-pop, indie rock\nKorean ballad, tango, acoustic\nKorean ballad, trip-hop, lounge\nKorean ballad, trot, cinematic\nKorean ballad, trot, retro\nKorean ballad, world music, emotional\nKorean blues-rock\nKorean children's\nKorean children's ballad\nKorean children's music\nKorean chiptune\nKorean cinematic ballad\nKorean city pop\nKorean city pop funk-rock\nKorean city pop jazz-fusion\nKorean disco\nKorean disco-funk\nKorean drama\nKorean drama OST\nKorean drill\nKorean electronic\nKorean folk\nKorean folk ballad\nKorean folk chiptune\nKorean folk funk\nKorean folk funk-rock\nKorean folk fusion\nKorean folk hip-hop\nKorean folk metal\nKorean folk pop\nKorean folk rock\nKorean folk trot\nKorean folk, Buddhist chant\nKorean folk, big band jazz\nKorean folk, big band, swing\nKorean folk, big band, trot\nKorean folk, chiptune\nKorean folk, cinematic\nKorean folk, cinematic, Pansori\nKorean folk, cinematic, synth orchestral\nKorean folk, classical chamber\nKorean folk, gypsy jazz, classical folk\nKorean folk, melancholic ballad\nKorean folk, theatrical, pansori\nKorean folk, theatrical, tango\nKorean folk-blues\nKorean folk-pop\nKorean folk-rock\nKorean folk-rock, alternative rock\nKorean folk-trot\nKorean funk\nKorean funk city pop\nKorean funk disco\nKorean funk soul\nKorean funk, disco, 80s\nKorean funk, new jack swing\nKorean funk-disco\nKorean funk-pop\nKorean funk-rock\nKorean fusion\nKorean fusion hip-hop\nKorean fusion trap R&B\nKorean fusion trap-R&B\nKorean gospel\nKorean gospel pop-rock\nKorean gospel, hip-hop, R&B\nKorean hard rock\nKorean hip hop\nKorean hip hop rock\nKorean hip hop, cinematic rap\nKorean hip hop, cinematic trap, phonk\nKorean hip hop, cyberpunk\nKorean hip hop, hybrid trap\nKorean hip hop, trap, electronic\nKorean hip-hop\nKorean hip-hop 90s\nKorean hip-hop G-funk\nKorean hip-hop G-funk neo-soul\nKorean hip-hop R&B\nKorean hip-hop R&B soul\nKorean hip-hop alternative rock\nKorean hip-hop ballad\nKorean hip-hop chiptune\nKorean hip-hop funk\nKorean hip-hop funk neo-soul\nKorean hip-hop funk reggae\nKorean hip-hop funk soul\nKorean hip-hop funk-rock\nKorean hip-hop industrial\nKorean hip-hop lo-fi\nKorean hip-hop lo-fi neo-soul\nKorean hip-hop neo-soul\nKorean hip-hop rock\nKorean hip-hop trap\nKorean hip-hop, 2000s R&B\nKorean hip-hop, 90s R&B\nKorean hip-hop, R&B\nKorean hip-hop, R&B, cinematic\nKorean hip-hop, R&B, pop\nKorean hip-hop, alternative R&B\nKorean hip-hop, ambient trap\nKorean hip-hop, ambient, gospel\nKorean hip-hop, atmospheric R&B\nKorean hip-hop, ballad\nKorean hip-hop, boom-bap, trap\nKorean hip-hop, chiptune\nKorean hip-hop, chiptune, boom-bap\nKorean hip-hop, chiptune, trap\nKorean hip-hop, cinematic\nKorean hip-hop, cinematic R&B\nKorean hip-hop, cinematic R&B, trap\nKorean hip-hop, cinematic ballad\nKorean hip-hop, cinematic hip-hop\nKorean hip-hop, cinematic pop\nKorean hip-hop, cinematic trap\nKorean hip-hop, cinematic, industrial\nKorean hip-hop, cloud rap, futuristic\nKorean hip-hop, electronic, trap\nKorean hip-hop, glitch hop\nKorean hip-hop, glitch hop, electronic\nKorean hip-hop, hard rock\nKorean hip-hop, hardstyle, trap\nKorean hip-hop, hardstyle, trap metal\nKorean hip-hop, industrial hip-hop\nKorean hip-hop, industrial hip-hop, electronic\nKorean hip-hop, industrial trap\nKorean hip-hop, lo-fi hip-hop, R&B\nKorean hip-hop, lo-fi jazz\nKorean hip-hop, lo-fi trap\nKorean hip-hop, lo-fi, jazz\nKorean hip-hop, neo-soul\nKorean hip-hop, neo-soul, jazz-hop\nKorean hip-hop, new jack swing\nKorean hip-hop, new jack swing, funk rap\nKorean hip-hop, new jack swing, pop-R&B\nKorean hip-hop, new jack swing, retro\nKorean hip-hop, old-school funk\nKorean hip-hop, old-school hip-hop\nKorean hip-hop, pop-rap\nKorean hip-hop, pop-rock\nKorean hip-hop, pop-rock, electronic\nKorean hip-hop, synth-pop\nKorean hip-hop, trap\nKorean hip-hop, trap, cinematic\nKorean hip-hop, trap, cloud rap\nKorean hip-hop, trap, drill\nKorean hip-hop, trap, dubstep\nKorean hip-hop, trap, experimental electronic\nKorean hip-hop, trap, hyperpop\nKorean hip-hop, trap, phonk\nKorean hip-hop, vaporwave\nKorean hip-hop, vaporwave, R&B\nKorean indie\nKorean indie ballad\nKorean indie folk\nKorean indie pop\nKorean indie pop bossa nova\nKorean indie pop, 80s city pop\nKorean indie pop, city pop\nKorean indie pop-rock\nKorean indie rock\nKorean indie-folk\nKorean indie-pop\nKorean indie-pop chiptune\nKorean indie-pop city-pop\nKorean indie-pop funk city-pop\nKorean indie-pop lounge-jazz\nKorean indie-pop reggae ska\nKorean jazz\nKorean lo-fi\nKorean musical\nKorean new wave\nKorean opera\nKorean orchestral\nKorean pansori\nKorean pansori, Eurodance\nKorean pop\nKorean pop ballad\nKorean pop rock\nKorean pop, cinematic\nKorean pop, cinematic rock\nKorean pop, hardstyle, cinematic\nKorean pop, pop-rock, cinematic\nKorean pop, power ballad\nKorean pop, rock ballad, cinematic\nKorean pop, trap, traditional fusion\nKorean pop-ballad\nKorean pop-rock\nKorean power ballad\nKorean psychedelic folk\nKorean psychedelic pop\nKorean psychedelic rock\nKorean rock\nKorean rock ballad\nKorean rock blues\nKorean rock electronic\nKorean rock funk disco\nKorean rock funk psychedelic\nKorean rock surf rock\nKorean rock trot\nKorean rock, 80s new wave\nKorean rock, J-rock\nKorean rock, Latin rock\nKorean rock, Latin rock, trot\nKorean rock, alternative metal\nKorean rock, blues rock\nKorean rock, blues, city pop\nKorean rock, blues, country\nKorean rock, blues, trot\nKorean rock, city pop\nKorean rock, city pop, 80s synth rock\nKorean rock, city pop, AOR\nKorean rock, city pop, funk\nKorean rock, city pop, synth-pop\nKorean rock, funk, city pop\nKorean rock, jazz fusion\nKorean rock, post-rock\nKorean rock, psychedelic funk\nKorean rock, surf rock\nKorean rock, trot\nKorean rock, trot, blues rock\nKorean rock, trot, cinematic rock\nKorean soft rock\nKorean soul\nKorean soul trot\nKorean soul, jazz ballad, trot\nKorean soul-pop\nKorean soul-rock\nKorean spiritual\nKorean synth-pop\nKorean synth-pop, City Pop\nKorean theatrical rock\nKorean traditional\nKorean traditional fusion\nKorean traditional orchestral\nKorean traditional, cinematic, ambient\nKorean traditional, cinematic, orchestral\nKorean traditional, psychedelic rock\nKorean trap\nKorean trap R&B\nKorean trap drill\nKorean trap rock\nKorean trap, festival trap, hardstyle\nKorean trot\nKorean trot Eurodance\nKorean trot ballad\nKorean trot big band\nKorean trot blues-rock\nKorean trot chiptune\nKorean trot city pop\nKorean trot country-western\nKorean trot dance-pop\nKorean trot disco\nKorean trot disco funk\nKorean trot funk\nKorean trot funk disco\nKorean trot funk rock\nKorean trot funk soul\nKorean trot funk-pop\nKorean trot funk-rock\nKorean trot gospel\nKorean trot gypsy jazz\nKorean trot jazz\nKorean trot lo-fi\nKorean trot lounge jazz\nKorean trot orchestral\nKorean trot pop-rock\nKorean trot psychedelic rock\nKorean trot punk\nKorean trot reggae-ska\nKorean trot rock\nKorean trot rockabilly\nKorean trot ska-punk\nKorean trot surf rock\nKorean trot synth-pop\nKorean trot, 8-bit chiptune\nKorean trot, 80s dance pop\nKorean trot, 80s synth pop\nKorean trot, 80s synth, dance\nKorean trot, 80s synth, funk\nKorean trot, 80s synth, retro pop\nKorean trot, 80s synth-pop\nKorean trot, 90s dance-pop\nKorean trot, Eurobeat\nKorean trot, Eurobeat, electronic\nKorean trot, Eurobeat, retro\nKorean trot, Eurodance\nKorean trot, Eurodance, hip-hop\nKorean trot, Eurodance, retro\nKorean trot, European folk\nKorean trot, European folk, chanson\nKorean trot, Italo-disco\nKorean trot, J-rock\nKorean trot, Latin dance-pop\nKorean trot, Latin disco\nKorean trot, Latin funk\nKorean trot, Latin jazz\nKorean trot, Latin pop\nKorean trot, Latin tango\nKorean trot, Latin, acoustic\nKorean trot, Latin, big band\nKorean trot, Latin, cha-cha-cha\nKorean trot, Latin, lo-fi\nKorean trot, Latin, retro\nKorean trot, Latin, vintage\nKorean trot, anime rock\nKorean trot, big band\nKorean trot, big band jazz\nKorean trot, big band rock\nKorean trot, big band swing\nKorean trot, big band swing, rock\nKorean trot, big band swing, rockabilly\nKorean trot, big band swing, synth pop\nKorean trot, big band, cinematic\nKorean trot, big band, dance\nKorean trot, big band, disco\nKorean trot, big band, electronic\nKorean trot, big band, funk\nKorean trot, big band, retro\nKorean trot, big band, rock\nKorean trot, big band, swing\nKorean trot, big band, swing rock\nKorean trot, big band, theatrical\nKorean trot, blues rock\nKorean trot, blues, jazz\nKorean trot, children's music\nKorean trot, chiptune\nKorean trot, chiptune, 8-bit\nKorean trot, chiptune, anime theme\nKorean trot, chiptune, lo-fi\nKorean trot, chiptune, retro\nKorean trot, chiptune, retro electronic\nKorean trot, chiptune, synth-pop\nKorean trot, chiptune, video game music\nKorean trot, cinematic ballad\nKorean trot, cinematic orchestral\nKorean trot, cinematic pop, ballad\nKorean trot, cinematic pop, traditional fusion\nKorean trot, cinematic pop-rock\nKorean trot, cinematic synth\nKorean trot, cinematic, ambient\nKorean trot, city pop\nKorean trot, city pop, lounge jazz\nKorean trot, city pop, synth-pop\nKorean trot, classic rock\nKorean trot, country-rock\nKorean trot, cumbia\nKorean trot, dance-pop\nKorean trot, dance-rock\nKorean trot, disco\nKorean trot, disco, 80s pop\nKorean trot, disco, big band\nKorean trot, disco, boogie-woogie\nKorean trot, disco, cha-cha-cha\nKorean trot, disco, city pop\nKorean trot, disco, dance-pop\nKorean trot, disco, funk\nKorean trot, disco, retro\nKorean trot, disco, rock\nKorean trot, disco, synth funk\nKorean trot, disco, synth pop\nKorean trot, disco, synth-pop\nKorean trot, disco, synthwave\nKorean trot, disco-funk\nKorean trot, disco-rock\nKorean trot, early techno-pop\nKorean trot, electronic dance\nKorean trot, eurodance, Italo disco\nKorean trot, flamenco fusion\nKorean trot, flamenco, soul\nKorean trot, funk rock\nKorean trot, funk, soul\nKorean trot, happy hardcore\nKorean trot, hard dance\nKorean trot, hard rock\nKorean trot, jazz\nKorean trot, jazz ballad\nKorean trot, lo-fi electronic\nKorean trot, lounge jazz\nKorean trot, mambo\nKorean trot, noir jazz\nKorean trot, orchestral pop\nKorean trot, pop-rock\nKorean trot, pop-rock, ballad\nKorean trot, pop-rock, retro\nKorean trot, psychedelic funk\nKorean trot, psychedelic rock\nKorean trot, retro K-pop\nKorean trot, retro chiptune\nKorean trot, retro dance-pop\nKorean trot, retro electronic\nKorean trot, retro funk, disco\nKorean trot, retro pop\nKorean trot, retro pop, synthwave\nKorean trot, retro synth\nKorean trot, retro synth, 80s K-pop\nKorean trot, retro synth, 80s dance\nKorean trot, retro synth, 80s pop\nKorean trot, retro synth, chiptune\nKorean trot, retro synth, dance\nKorean trot, retro synth, dance pop\nKorean trot, retro synth, dance-pop\nKorean trot, retro synth-pop\nKorean trot, retro, dance\nKorean trot, retro, synthwave\nKorean trot, retro-pop, disco\nKorean trot, rock, jazz fusion\nKorean trot, rockabilly, big band\nKorean trot, stadium rock\nKorean trot, surf rock\nKorean trot, synth pop\nKorean trot, synth-pop\nKorean trot, synth-pop, Italo disco\nKorean trot, synth-pop, chiptune\nKorean trot, synth-pop, disco\nKorean trot, synth-pop, disco-funk\nKorean trot, synth-pop, retro\nKorean trot, synth-pop, rock\nKorean trot, synthwave, ambient\nKorean trot, tango\nKorean trot-pop\nKorean trot-rock\nKuduro\nKuduro Afrobeats\nKuduro Baile Funk\nKuduro Brazilian funk\nKuduro Cumbia\nKuduro Dancehall\nKuduro Kizomba\nKuduro Latin dance\nKuduro Latin dance-pop\nKuduro Sertanejo\nKuduro hip-hop\nKurdish dance\nKurdish dance-pop\nKurdish devotional\nKurdish electronic\nKurdish electronic dance\nKurdish folk\nKurdish folk dance\nKurdish folk, electronic dance\nKurdish folk-pop\nKurdish folk-rock\nKurdish hip-hop\nKurdish pop\nKurdish pop jazz\nKurdish pop reggaeton\nKurdish pop, Eurodance\nKurdish pop, Eurodance, 90s dance-pop\nKurdish pop, Persian pop, Middle Eastern folk\nKurdish pop, electronic dance\nKurdish pop, electronic dance music\nKurdish pop, reggaeton, dancehall\nKurdish pop, trap, emotional\nKurdish pop-dance\nKuthu\nKuthu Bhangra\nKuthu EDM\nKuthu EDM chiptune\nKuthu Eurodance\nKuthu Gaana\nKuthu Gana\nKuthu Latin pop\nKuthu chiptune\nKuthu chiptune funk\nKuthu chiptune hip-hop\nKuthu dance-pop\nKuthu dance-pop chiptune\nKuthu electro\nKuthu electro-funk\nKuthu electro-pop\nKuthu electronic\nKuthu electronic rock\nKuthu flamenco\nKuthu folk\nKuthu funk\nKuthu funk chiptune\nKuthu funk pop\nKuthu funk rock\nKuthu funk-pop\nKuthu funk-rock\nKuthu funk-rock electronic\nKuthu funk-rock hip-hop\nKuthu fusion\nKuthu fusion funk\nKuthu fusion funk-rock\nKuthu gospel\nKuthu hardstyle\nKuthu hip-hop\nKuthu hip-hop Bollywood\nKuthu hip-hop EDM\nKuthu hip-hop chiptune\nKuthu hip-hop cinematic pop\nKuthu hip-hop electronic\nKuthu hip-hop funk\nKuthu hip-hop fusion\nKuthu hip-hop hardstyle\nKuthu hip-hop hyperpop\nKuthu hip-hop rock\nKuthu hip-hop, global pop\nKuthu hyperpop\nKuthu jazz ska\nKuthu metal\nKuthu nu-metal\nKuthu pop\nKuthu pop funk\nKuthu pop hip-hop\nKuthu pop, Bollywood, Western pop-rap\nKuthu pop-rock\nKuthu rock\nKuthu salsa\nKuthu trap\nKuthu trap EDM\nKuthu worldbeat\nKuthu, Bollywood dance-pop\nKuthu, Bollywood, Eurodance\nKuthu, Bollywood, chiptune\nKuthu, Bollywood, dance\nKuthu, Bollywood, electronic dance\nKuthu, Carnatic, South Indian folk\nKuthu, Christian pop, devotional\nKuthu, Christian, Tamil\nKuthu, Christian, dance\nKuthu, Christian, devotional\nKuthu, Gaana, electronic dance\nKuthu, Latin dance\nKuthu, Salsa, Christian\nKuthu, South Indian folk\nKuthu, Sufi-pop, Christian devotional\nKuthu, Tamil folk, cinematic\nKuthu, UK garage, hip-hop\nKuthu, chiptune, electro-pop\nKuthu, chiptune, electronic dance\nKuthu, chiptune, hip-hop\nKuthu, electronic dance\nKuthu, electronic dance, folk fusion\nKuthu, electronic dance, fusion\nKuthu, electronic, club\nKuthu, moombahton, dancehall\nKuthu, samba, Bollywood\nLa pompe\nLaiko\nLaotian folk\nLaotian folk-pop\nLatin\nLatin Afro-Cuban\nLatin Afrobeat\nLatin American\nLatin American Christian\nLatin American Christian hymn\nLatin American Christmas\nLatin American anthem\nLatin American art song\nLatin American ballad\nLatin American carnival\nLatin American choral\nLatin American classical\nLatin American cumbia\nLatin American devotional\nLatin American folk\nLatin American folk gospel\nLatin American folk hymn\nLatin American folk worship\nLatin American folk, Christian hymn\nLatin American folk, children's music\nLatin American folk, classical\nLatin American folk, cumbia, Christian hymn\nLatin American folk, orchestral, operatic\nLatin American folk, orchestral, sacred\nLatin American folk, world music, chamber music\nLatin American folk-rock\nLatin American folk-trap\nLatin American gospel\nLatin American guitar\nLatin American harp\nLatin American hymn\nLatin American instrumental\nLatin American lullaby\nLatin American parade\nLatin American protest\nLatin American protest folk\nLatin American religious hymn\nLatin American rumba\nLatin American sacred music\nLatin American singer-songwriter\nLatin American spiritual\nLatin American villancico\nLatin American worship\nLatin American, baroque, instrumental\nLatin American, cumbia, choral\nLatin American, cumbia, surf rock\nLatin American, cumbia, villancico\nLatin American, festive, cumbia\nLatin American, festive, waltz\nLatin American, instrumental, trance\nLatin American, villancico, festive\nLatin Arabic pop\nLatin Balkan brass\nLatin Balkan fusion\nLatin Balkan synth\nLatin Banda\nLatin Banda hip-hop\nLatin Bollywood\nLatin Bollywood fusion\nLatin C-pop\nLatin Christian\nLatin Christian Cumbia\nLatin Christian EDM\nLatin Christian Norteño\nLatin Christian R&B\nLatin Christian ballad\nLatin Christian ballad merengue\nLatin Christian ballad tango\nLatin Christian banda\nLatin Christian bolero\nLatin Christian children's\nLatin Christian children's cumbia\nLatin Christian children's music\nLatin Christian chiptune\nLatin Christian choral\nLatin Christian contemporary\nLatin Christian country\nLatin Christian cumbia\nLatin Christian dance\nLatin Christian dance-pop\nLatin Christian dancehall\nLatin Christian folk\nLatin Christian folk-cumbia\nLatin Christian folk-pop\nLatin Christian folk-rock\nLatin Christian funk\nLatin Christian funk-pop\nLatin Christian hip-hop\nLatin Christian house\nLatin Christian hymn\nLatin Christian hymn mariachi\nLatin Christian march\nLatin Christian music\nLatin Christian pop\nLatin Christian pop chiptune\nLatin Christian pop reggae\nLatin Christian pop-rap\nLatin Christian pop-reggae\nLatin Christian pop-rock\nLatin Christian power ballad\nLatin Christian praise\nLatin Christian praise, big band funk-rock\nLatin Christian ranchera\nLatin Christian reggae\nLatin Christian reggaeton\nLatin Christian rock\nLatin Christian rockabilly\nLatin Christian salsa\nLatin Christian synth-pop\nLatin Christian trance\nLatin Christian trap\nLatin Christian worship\nLatin Christian worship cumbia\nLatin Christian worship cumbia norteño\nLatin Christian worship ranchera\nLatin Christian worship, smooth jazz\nLatin Christian, Banda, Norteño\nLatin Christian, Cumbia, vintage\nLatin Christian, Norteño\nLatin Christian, Norteño, Cumbia\nLatin Christian, Norteño, ballad\nLatin Christian, Norteño, ranchera\nLatin Christian, bolero\nLatin Christian, chiptune\nLatin Christian, chiptune, digital cumbia\nLatin Christian, chiptune, upbeat\nLatin Christian, chiptune, video game music\nLatin Christian, cumbia, merengue\nLatin Christian, retro synth\nLatin Christmas\nLatin Christmas ballad\nLatin Christmas bolero\nLatin Christmas cumbia\nLatin Christmas pop\nLatin Christmas, Cumbia\nLatin Christmas, Cumbia, Rock\nLatin Christmas, Joropo\nLatin Christmas, big band, mambo\nLatin Christmas, bolero\nLatin Christmas, bolero, ranchera\nLatin Christmas, bolero, salsa\nLatin Christmas, bossa nova\nLatin Christmas, cha-cha-chá\nLatin Christmas, chiptune\nLatin Christmas, cumbia\nLatin Christmas, cumbia, big band\nLatin Christmas, cumbia, brass\nLatin Christmas, cumbia, festive\nLatin Christmas, cumbia, merengue\nLatin Christmas, cumbia, norteño\nLatin Christmas, cumbia, ranchera\nLatin Christmas, cumbia, salsa\nLatin Christmas, cumbia, vallenato\nLatin Christmas, cumbia, villancico\nLatin Christmas, cumbia-reggaeton\nLatin Christmas, exotica, retro\nLatin Christmas, mambo, cha-cha-chá\nLatin Christmas, mambo, salsa\nLatin Christmas, polka, festive\nLatin Christmas, retro synth\nLatin Christmas, salsa\nLatin Christmas, salsa, cumbia\nLatin Christmas, synth-pop, cumbia-pop\nLatin Christmas, villancico, ranchera\nLatin Cumbia\nLatin Cumbia G-funk\nLatin Cumbia Pop\nLatin Cumbia Salsa\nLatin Cumbia chiptune\nLatin Cumbia funk-hop\nLatin Cumbia, 8-bit, synthpop\nLatin Cumbia, Arabic pop\nLatin Cumbia, Christian worship, retro\nLatin Cumbia, Filipino novelty\nLatin Cumbia, Indian Christian, vintage\nLatin Cumbia, Persian pop\nLatin Cumbia, chiptune\nLatin Cumbia, chiptune, 8-bit\nLatin Drill\nLatin EDM\nLatin EDM big room\nLatin EDM big room house\nLatin EDM electro-house\nLatin EDM future bass\nLatin EDM moombahton\nLatin EDM, hardstyle, cinematic synth\nLatin EDM-pop\nLatin Eurodance\nLatin Fado\nLatin House\nLatin J-pop\nLatin J-pop fusion\nLatin Jazz\nLatin Kayōkyoku\nLatin Mandopop\nLatin Plena\nLatin Pop\nLatin Pop Afrobeat R&B\nLatin Pop Bossa Nova\nLatin Pop Christian Pop\nLatin Pop Dance-Pop\nLatin Pop Dancehall\nLatin Pop Hip Hop\nLatin Pop R&B\nLatin Pop R&B Christian Pop\nLatin Pop R&B Hip Hop\nLatin Pop R&B Neo-Soul\nLatin Pop R&B hip-hop\nLatin Pop R&B reggaeton\nLatin Pop acoustic Pop\nLatin Pop bachata\nLatin Pop chillwave\nLatin Pop lo-fi R&B\nLatin Pop reggaeton\nLatin Pop, Atmospheric R&B\nLatin Pop, Christian Contemporary\nLatin Pop, Hip Hop\nLatin Pop, Pop-reggaeton\nLatin Pop, R&B\nLatin Pop, R&B, Reggaeton\nLatin Pop, reggaeton\nLatin Pop, reggaeton, tropical house\nLatin Pop, romantic R&B\nLatin R&B\nLatin R&B Bossa Nova\nLatin R&B Christian hip-hop\nLatin R&B acoustic\nLatin R&B chill-hop\nLatin R&B chillwave\nLatin R&B chiptune\nLatin R&B deep house\nLatin R&B dembow\nLatin R&B future bass\nLatin R&B hip hop\nLatin R&B hip-hop\nLatin R&B lo-fi\nLatin R&B lo-fi hip hop\nLatin R&B lo-fi hip-hop\nLatin R&B lo-fi pop\nLatin R&B lo-fi trap\nLatin R&B neo-soul\nLatin R&B reggaeton\nLatin R&B trap\nLatin R&B trap-pop\nLatin R&B trap-soul\nLatin R&B, Hip Hop\nLatin R&B, Latin house\nLatin R&B, Latin pop\nLatin R&B, Latin trap\nLatin R&B, Moombahton\nLatin R&B, ambient, dembow\nLatin R&B, cinematic hip-hop\nLatin R&B, deep house, bossa nova\nLatin R&B, dembow, ambient\nLatin R&B, dembow, dream pop\nLatin R&B, dembow, lo-fi\nLatin R&B, emo rap, lo-fi\nLatin R&B, future bass, hyperpop\nLatin R&B, glitch, hyperpop\nLatin R&B, glitch-hop, hyperpop\nLatin R&B, hardstyle\nLatin R&B, hip-hop\nLatin R&B, hip-hop, chill groove\nLatin R&B, hip-hop, world fusion\nLatin R&B, hyperpop\nLatin R&B, hyperpop, ambient\nLatin R&B, hyperpop, reggaeton\nLatin R&B, lo-fi hip hop\nLatin R&B, lo-fi hip hop, boom-bap\nLatin R&B, lo-fi hip-hop\nLatin R&B, lo-fi trap\nLatin R&B, lo-fi, acoustic ballad\nLatin R&B, lo-fi, emotional reggaeton\nLatin R&B, lo-fi, trap\nLatin R&B, phonk\nLatin R&B, pop-rock, hip-hop\nLatin R&B, reggaeton\nLatin R&B, reggaeton, acoustic ballad\nLatin R&B, reggaeton, ambient\nLatin R&B, reggaeton, chiptune\nLatin R&B, reggaeton, cinematic\nLatin R&B, reggaeton, cumbia\nLatin R&B, reggaeton, dream pop\nLatin R&B, reggaeton, electronic\nLatin R&B, reggaeton, hyperpop\nLatin R&B, reggaeton, lo-fi\nLatin R&B, reggaeton, melancholic\nLatin R&B, reggaeton, neurofunk\nLatin R&B, reggaeton, pop\nLatin R&B, reggaeton, trap\nLatin R&B, reggaeton, vaporwave\nLatin R&B, rock\nLatin R&B, sad reggaeton\nLatin R&B, sad reggaeton, ambient\nLatin R&B, sad reggaeton, trap\nLatin R&B, sad trap\nLatin R&B, sad trap, ambient\nLatin R&B, trap\nLatin R&B, trap soul\nLatin R&B, trap, acoustic ballad\nLatin R&B, trap, ambient\nLatin R&B, trap, cinematic\nLatin R&B, trap, dream pop\nLatin R&B, trap, hardstyle\nLatin R&B, trap, hip-hop\nLatin R&B, trap, hyperpop\nLatin R&B, trap, lo-fi\nLatin R&B, trap, lo-fi hip hop\nLatin R&B, trap, soul\nLatin R&B, trap, urban pop\nLatin R&B, trap-soul\nLatin R&B, trap-soul, ambient\nLatin R&B, trap-soul, cloud rap\nLatin R&B, trap-soul, lo-fi\nLatin Rumba\nLatin Schlager\nLatin South Asian fusion\nLatin Trap\nLatin Trap, Deutschrap\nLatin Trap, Mandarin Trap\nLatin Trap, Sad Trap\nLatin acoustic\nLatin acoustic ballad\nLatin acoustic pop\nLatin acoustic rock\nLatin adult contemporary\nLatin alternative\nLatin alternative dream pop\nLatin alternative folk-rock\nLatin alternative hip-hop\nLatin alternative pop\nLatin alternative rock\nLatin ambient\nLatin anthem\nLatin anthemic\nLatin arena rock\nLatin art rock\nLatin art song\nLatin art-pop\nLatin art-pop jazz fusion\nLatin art-pop tango\nLatin art-rock\nLatin ballad\nLatin ballad 80s synth\nLatin ballad Cumbia Norteña\nLatin ballad Fado\nLatin ballad alt-rock\nLatin ballad blues-rock\nLatin ballad bolero\nLatin ballad bolero jazz\nLatin ballad bolero-rock\nLatin ballad chiptune\nLatin ballad country\nLatin ballad cumbia\nLatin ballad cumbia bolero\nLatin ballad cumbia cinematic\nLatin ballad cumbia lo-fi\nLatin ballad cumbia norteña\nLatin ballad cumbia rock\nLatin ballad cumbia telenovela\nLatin ballad cumbia villera\nLatin ballad cumbia-reggaeton\nLatin ballad flamenco\nLatin ballad hip-hop fusion\nLatin ballad jazz\nLatin ballad jazz bolero\nLatin ballad jazz bossa nova\nLatin ballad jazz lounge\nLatin ballad jazz tango\nLatin ballad lo-fi\nLatin ballad lounge\nLatin ballad lounge jazz\nLatin ballad mambo\nLatin ballad merengue\nLatin ballad pop-punk\nLatin ballad pop-rock\nLatin ballad power ballad\nLatin ballad psychedelic\nLatin ballad psychedelic rock\nLatin ballad punk rock\nLatin ballad ranchera\nLatin ballad reggaeton\nLatin ballad rock\nLatin ballad rock en español\nLatin ballad salsa\nLatin ballad salsa dura\nLatin ballad salsa romántica\nLatin ballad salsa-pop\nLatin ballad salsa-romántica\nLatin ballad samba\nLatin ballad tango\nLatin ballad tango cumbia\nLatin ballad tango orchestral\nLatin ballad, 1980s synth\nLatin ballad, 80s pop, dramatic\nLatin ballad, 80s power ballad\nLatin ballad, 80s rock\nLatin ballad, 80s synth, cinematic\nLatin ballad, 80s synth, dramatic pop\nLatin ballad, Andean folk\nLatin ballad, Christian pop-rock\nLatin ballad, Christian rock\nLatin ballad, Cuarteto\nLatin ballad, Cumbia\nLatin ballad, Cumbia Norteña\nLatin ballad, Cumbia, Merengue\nLatin ballad, Cumbia, regional Mexican\nLatin ballad, European chanson, modern tango\nLatin ballad, Latin folk\nLatin ballad, Latin jazz\nLatin ballad, Latin pop, reggaeton\nLatin ballad, Latin pop-rock\nLatin ballad, Latin rock\nLatin ballad, Latin rock, salsa\nLatin ballad, Latin rock, ska-punk\nLatin ballad, Latin trap\nLatin ballad, Norteño, Cumbia\nLatin ballad, Russian punk\nLatin ballad, Samba\nLatin ballad, alt-rock, blues-rock\nLatin ballad, art rock\nLatin ballad, banda, norteño\nLatin ballad, big band\nLatin ballad, big band, mambo\nLatin ballad, bolero\nLatin ballad, bolero, big band\nLatin ballad, bolero, cinematic\nLatin ballad, bolero, dramatic\nLatin ballad, bolero, mambo\nLatin ballad, bolero, operatic\nLatin ballad, bolero, orchestral\nLatin ballad, bolero, salsa\nLatin ballad, chiptune, theatrical\nLatin ballad, cinematic piano, rock ballad\nLatin ballad, cinematic, bolero\nLatin ballad, cumbia\nLatin ballad, cumbia norteña\nLatin ballad, cumbia villera\nLatin ballad, cumbia, forró\nLatin ballad, cumbia-reggae, brass pop\nLatin ballad, electronic, melancholic\nLatin ballad, flamenco fusion\nLatin ballad, flamenco, cinematic rock\nLatin ballad, flamenco, progressive rock\nLatin ballad, flamenco, salsa\nLatin ballad, flamenco, soulful\nLatin ballad, folk-pop\nLatin ballad, hard rock\nLatin ballad, heavy metal\nLatin ballad, jazz, soul\nLatin ballad, mambo\nLatin ballad, mambo, chanson\nLatin ballad, mambo, ranchera\nLatin ballad, mambo, romantic waltz\nLatin ballad, mambo, salsa\nLatin ballad, mariachi, brass band\nLatin ballad, mariachi, salsa\nLatin ballad, merengue\nLatin ballad, merengue, mambo\nLatin ballad, merengue, salsa\nLatin ballad, modern cumbia\nLatin ballad, norteño\nLatin ballad, norteño, cumbia\nLatin ballad, norteño, regional Mexican\nLatin ballad, operatic, bolero\nLatin ballad, operatic, cinematic\nLatin ballad, operatic, classical crossover\nLatin ballad, orchestral pop, bolero\nLatin ballad, pop-rock, cinematic\nLatin ballad, power ballad, hard rock\nLatin ballad, psychedelic rock\nLatin ballad, psychedelic, vintage\nLatin ballad, reggaeton\nLatin ballad, reggaeton, electronic\nLatin ballad, regional Mexican, cumbia\nLatin ballad, retro synth, chiptune\nLatin ballad, retro, chiptune\nLatin ballad, rock opera\nLatin ballad, rock opera, melancholic\nLatin ballad, rock, progressive rock\nLatin ballad, rockabilly\nLatin ballad, rumba\nLatin ballad, salsa, bachata\nLatin ballad, salsa, jazz\nLatin ballad, soft rock, 90s pop\nLatin ballad, soft rock, power ballad\nLatin ballad, stadium rock\nLatin ballad, tango, cinematic\nLatin ballad, tango, theatrical\nLatin ballad, theatrical, psychedelic rock\nLatin ballad, trap, cinematic\nLatin ballad, trap, hip-hop\nLatin ballroom\nLatin ballroom cumbia\nLatin banda\nLatin bass\nLatin beat\nLatin beatbox\nLatin big band\nLatin big band salsa\nLatin big band, salsa, festive\nLatin big band, ska, mambo\nLatin blues\nLatin blues-rock\nLatin bolero\nLatin bolero big band\nLatin bolero disco\nLatin bolero jazz\nLatin bolero lo-fi\nLatin bolero mambo cumbia\nLatin bolero orchestral\nLatin bolero psychedelic rock\nLatin bolero ranchera\nLatin bolero reggae\nLatin bolero reggaeton\nLatin bolero salsa\nLatin bolero smooth jazz\nLatin bolero tango\nLatin bolero, Latin rock\nLatin bolero, MPB, cinematic\nLatin bolero, art song\nLatin bolero, big band\nLatin bolero, big band jazz\nLatin bolero, cabaret, big band jazz\nLatin bolero, candombe\nLatin bolero, cinematic ballad, tango\nLatin bolero, cinematic orchestral\nLatin bolero, cinematic worship\nLatin bolero, cinematic, brass\nLatin bolero, cinematic, dramatic ballad\nLatin bolero, cumbia\nLatin bolero, mambo\nLatin bolero, mambo, big band\nLatin bolero, mambo, cinematic\nLatin bolero, mambo, salsa\nLatin bolero, mambo, theatrical\nLatin bolero, merengue\nLatin bolero, orchestral, cinematic\nLatin bolero, power ballad\nLatin bolero, psychedelic rock\nLatin bolero, rock en español\nLatin bolero, romantic pop\nLatin bolero, salsa\nLatin bolero, salsa, jazz\nLatin bolero, salsa, piano ballad\nLatin boogaloo\nLatin boogie-woogie\nLatin brass\nLatin breakbeat\nLatin cabaret\nLatin candombe\nLatin carnival\nLatin cha-cha\nLatin cha-cha-cha\nLatin cha-cha-chá\nLatin chanson\nLatin chant\nLatin children's\nLatin children's cumbia\nLatin children's music\nLatin children's, indie pop-rock\nLatin chill\nLatin chiptune\nLatin choral\nLatin choral, MPB\nLatin cinematic\nLatin classical\nLatin classical fusion\nLatin classical pop-rap\nLatin club\nLatin club dembow\nLatin club, reggaeton, salsa\nLatin comedy\nLatin comedy rock\nLatin comedy-rock\nLatin corrido\nLatin country\nLatin country-folk\nLatin country-gospel\nLatin cumbia\nLatin cumbia children's music\nLatin cumbia chiptune\nLatin cumbia gospel\nLatin cumbia hip-hop\nLatin cumbia merengue\nLatin cumbia novelty\nLatin cumbia pop\nLatin cumbia pop-rock rap\nLatin cumbia praise\nLatin cumbia reggae\nLatin cumbia rock\nLatin cumbia salsa\nLatin cumbia salsa bolero\nLatin cumbia ska\nLatin cumbia surf rock\nLatin cumbia timba\nLatin cumbia tropical\nLatin cumbia tropical pop\nLatin cumbia vallenato\nLatin cumbia worship\nLatin cumbia, Balkan brass\nLatin cumbia, Balkan brass, indie rock\nLatin cumbia, Balkan folk\nLatin cumbia, Balkan party, dembow\nLatin cumbia, Christian devotional, Malayalam pop\nLatin cumbia, Dutch party, upbeat\nLatin cumbia, Eastern European folk\nLatin cumbia, European folk, tango\nLatin cumbia, Filipino Christian, live performance\nLatin cumbia, French chanson\nLatin cumbia, Indian devotional, upbeat fusion\nLatin cumbia, Israeli pop-rock\nLatin cumbia, Italian rap\nLatin cumbia, Middle Eastern fusion\nLatin cumbia, Middle Eastern fusion, reggae\nLatin cumbia, Middle Eastern pop\nLatin cumbia, Rai, fusion\nLatin cumbia, Turkish pop\nLatin cumbia, alternative rock, hip-hop\nLatin cumbia, baile funk\nLatin cumbia, big band swing\nLatin cumbia, blues-rock\nLatin cumbia, children's music\nLatin cumbia, children's music, Dutch pop\nLatin cumbia, children's music, electronic\nLatin cumbia, chiptune\nLatin cumbia, chiptune, electronic rock\nLatin cumbia, chiptune, retro\nLatin cumbia, chiptune, video game music\nLatin cumbia, chiptune, world music\nLatin cumbia, cinematic, theatrical\nLatin cumbia, dark pop\nLatin cumbia, electro-house\nLatin cumbia, electronic dance\nLatin cumbia, electronic, children's music\nLatin cumbia, electronic, children's novelty\nLatin cumbia, folk waltz, Christmas\nLatin cumbia, folk-pop\nLatin cumbia, gospel, cinematic\nLatin cumbia, hard rock\nLatin cumbia, lo-fi, vaporwave\nLatin cumbia, marching band\nLatin cumbia, merengue, ballad\nLatin cumbia, merengue, electronic\nLatin cumbia, operatic, festive\nLatin cumbia, psychedelic rock\nLatin cumbia, punk rock, reggae-funk\nLatin cumbia, reggaeton, Polish hip-hop\nLatin cumbia, reggaeton, children's music\nLatin cumbia, reggaeton, pop-ballad, salsa\nLatin cumbia, regional Mexican, urban fusion\nLatin cumbia, rockabilly\nLatin cumbia, salsa, cinematic\nLatin cumbia, salsa, novelty\nLatin cumbia, ska, children's music\nLatin cumbia, stadium rock\nLatin cumbia, surf rock, chiptune\nLatin cumbia, theatrical pop\nLatin cumbia, theatrical pop-rock\nLatin cumbia, theatrical, Halloween\nLatin cumbia, tropical pop\nLatin cumbia, tropical, dance\nLatin cumbia, tropical, merengue\nLatin cumbia, tropical, party\nLatin cumbia, tropical, ska\nLatin cumbia, turntablism, Russian rap\nLatin cumbia, video game music, children's music\nLatin cumbia-pop\nLatin cumbia-reggae fusion\nLatin cumbia-rock\nLatin cumbia-ska\nLatin cumbia-ska fusion\nLatin dance\nLatin dance bolero\nLatin dance cumbia\nLatin dance pop\nLatin dance salsa\nLatin dance, African fusion, retro synth\nLatin dance, Brazilian party, samba\nLatin dance, Eastern European folk\nLatin dance, Eurodance\nLatin dance, Kuduro\nLatin dance, Middle Eastern fusion\nLatin dance, Soca\nLatin dance, South Indian fusion\nLatin dance, Turkish pop\nLatin dance, ballad, merengue\nLatin dance, cha-cha-chá\nLatin dance, chiptune\nLatin dance, chiptune, cumbia\nLatin dance, chiptune, dembow\nLatin dance, chiptune, merengue\nLatin dance, chiptune, novelty\nLatin dance, chiptune, video game music\nLatin dance, classical fusion\nLatin dance, cumbia, Afro-Latin\nLatin dance, cumbia, chiptune\nLatin dance, cumbia, dangdut koplo\nLatin dance, cumbia, horn-driven\nLatin dance, cumbia, live\nLatin dance, cumbia, lo-fi\nLatin dance, cumbia, mariachi\nLatin dance, cumbia, merengue\nLatin dance, cumbia, novelty pop\nLatin dance, cumbia, reggaeton\nLatin dance, cumbia, retro electronic\nLatin dance, cumbia, retro synth\nLatin dance, cumbia, salsa\nLatin dance, cumbia, synth pop\nLatin dance, cumbia, techno-banda\nLatin dance, dembow, accordion\nLatin dance, dembow, electronic\nLatin dance, dembow, party\nLatin dance, dembow, steel pan\nLatin dance, dembow, synth pop\nLatin dance, dembow, urban\nLatin dance, electro, reggaeton\nLatin dance, forró, Brazilian fusion\nLatin dance, guaracha\nLatin dance, hardstyle, electro house\nLatin dance, hip-hop, reggae\nLatin dance, lo-fi, chiptune\nLatin dance, merengue, Eurodance\nLatin dance, merengue, bachata\nLatin dance, merengue, cumbia\nLatin dance, merengue, salsa\nLatin dance, merengue, urban\nLatin dance, modern cumbia\nLatin dance, modern cumbia, tropical\nLatin dance, novelty, electronic\nLatin dance, reggaeton, Brazilian\nLatin dance, reggaeton, Eurodance\nLatin dance, reggaeton, cumbia\nLatin dance, reggaeton, salsa\nLatin dance, reggaeton, synth-pop\nLatin dance, retro electronic\nLatin dance, retro pop, worldbeat\nLatin dance, retro synth, cumbia\nLatin dance, retro synth-pop\nLatin dance, retro, chiptune\nLatin dance, retro, funk\nLatin dance, retro, synth funk\nLatin dance, salsa, 90s house\nLatin dance, salsa, mambo\nLatin dance, timba, reggaeton\nLatin dance-pop\nLatin dance-pop Bollywood fusion\nLatin dance-pop Christian\nLatin dance-pop Eurodance\nLatin dance-pop chiptune\nLatin dance-pop cumbia\nLatin dance-pop deep house\nLatin dance-pop electro house\nLatin dance-pop eurodance\nLatin dance-pop freestyle\nLatin dance-pop moombahton\nLatin dance-pop progressive house\nLatin dance-pop reggaeton\nLatin dance-pop techno-house\nLatin dance-pop, Eurodance\nLatin dance-pop, reggaeton, EDM\nLatin dance-rock\nLatin dancehall\nLatin dancehall rap\nLatin deep house\nLatin dembow\nLatin devotional\nLatin devotional cumbia\nLatin devotional salsa\nLatin devotional waltz\nLatin disco\nLatin disco Mandopop\nLatin disco funk\nLatin disco, Mandopop\nLatin disco, Mandopop, retro\nLatin disco, V-Pop, retro\nLatin disco, funk, V-pop\nLatin disco, mambo, Filipino novelty\nLatin disco, retro Vietnamese pop\nLatin disco, retro pop, Vietnamese pop\nLatin disco-funk\nLatin disco-pop\nLatin dramatic\nLatin drill\nLatin drill lo-fi\nLatin drill reggaeton\nLatin drill trap\nLatin drill, cinematic orchestral\nLatin drill, lo-fi hip hop\nLatin drum\nLatin drum and bass\nLatin drum break\nLatin drum groove\nLatin drum machine\nLatin easy-listening\nLatin electro house\nLatin electro-house\nLatin electro-pop\nLatin electronic\nLatin electronic chiptune\nLatin electronic cumbia\nLatin electronic darkwave\nLatin electronic dembow\nLatin electronic funk\nLatin electronic funk carioca\nLatin electronic fusion\nLatin electronic hip-hop\nLatin electronic moombahton\nLatin electronic pop\nLatin electronic rock\nLatin electronic, Middle Eastern dance\nLatin electronic, South Asian fusion\nLatin electronic, chiptune\nLatin electronic, chiptune, dance\nLatin electronic, cumbia, Vocaloid\nLatin electronic, deep house\nLatin electronic, dembow, club\nLatin electronic, dembow, hardstyle\nLatin electronic, dembow, moombahton\nLatin electronic, funk carioca, dangdut koplo\nLatin electronic, hard techno, house\nLatin electronic, hardstyle, Eurodance\nLatin electronic, hardstyle, hyperpop\nLatin electronic, hardstyle, psytrance\nLatin electronic, hardstyle, reggaeton\nLatin electronic, hyperpop\nLatin electronic, hyperpop, chiptune\nLatin electronic, hyperpop, reggaeton\nLatin electronic, moombahton, dembow\nLatin electronic, moombahton, hardstyle\nLatin electronic, reggaeton, chiptune\nLatin electronic, reggaeton, moombahton\nLatin electronic, tech house, hyperpop\nLatin electronic, tribal house\nLatin electronica\nLatin electropop\nLatin electropop J-pop\nLatin emo\nLatin emo-rap\nLatin exotica\nLatin experimental\nLatin festival\nLatin fingerstyle\nLatin flamenco\nLatin flamenco fusion\nLatin flute\nLatin folk\nLatin folk a cappella\nLatin folk acoustic rock\nLatin folk ambient\nLatin folk ballad\nLatin folk blues\nLatin folk blues-rock\nLatin folk bolero\nLatin folk bossa nova\nLatin folk cabaret\nLatin folk chamber pop\nLatin folk children's\nLatin folk children's music\nLatin folk chiptune\nLatin folk choral\nLatin folk comedy\nLatin folk corrido\nLatin folk cumbia\nLatin folk dance\nLatin folk electronic\nLatin folk electronica\nLatin folk flamenco\nLatin folk fusion\nLatin folk gospel\nLatin folk gypsy jazz\nLatin folk hip-hop\nLatin folk indie rock\nLatin folk jazz\nLatin folk lo-fi\nLatin folk mambo\nLatin folk march\nLatin folk mariachi\nLatin folk metal\nLatin folk orchestral\nLatin folk pop\nLatin folk pop-rock\nLatin folk progressive metal\nLatin folk protest\nLatin folk punk\nLatin folk ranchera\nLatin folk reggae\nLatin folk reggaeton\nLatin folk revolution\nLatin folk rock\nLatin folk rockabilly\nLatin folk rumba\nLatin folk salsa\nLatin folk tango\nLatin folk trap\nLatin folk waltz\nLatin folk worship\nLatin folk, Afro-Latin\nLatin folk, Andean folk\nLatin folk, Andean folk, Christmas\nLatin folk, Andean, video game soundtrack\nLatin folk, Balkan brass, ska\nLatin folk, Christian music\nLatin folk, Christian, Cumbia\nLatin folk, Christian, cumbia\nLatin folk, Christmas, vocal harmony\nLatin folk, Cuban Son, Salsa\nLatin folk, European folk, theatrical\nLatin folk, Joropo\nLatin folk, Latin pop-rock\nLatin folk, Latin rock\nLatin folk, MPB\nLatin folk, Middle Eastern folk\nLatin folk, South African folk\nLatin folk, South African folk, world music\nLatin folk, Thai folk\nLatin folk, acoustic gospel\nLatin folk, acoustic rock\nLatin folk, acoustic worship\nLatin folk, alternative rock\nLatin folk, big band, ragtime\nLatin folk, bolero, cumbia\nLatin folk, bolero, theatrical\nLatin folk, brass band\nLatin folk, children's music\nLatin folk, children's music, funk-pop\nLatin folk, chiptune, cumbia\nLatin folk, choral\nLatin folk, cinematic orchestral\nLatin folk, cinematic, big band\nLatin folk, cinematic, operatic\nLatin folk, cinematic, orchestral\nLatin folk, classical choral, flamenco\nLatin folk, classical crossover\nLatin folk, conscious hip-hop\nLatin folk, contemporary Christian\nLatin folk, corrido tumbado, acoustic hip-hop\nLatin folk, cumbia\nLatin folk, cumbia, Latin rock\nLatin folk, cumbia, bolero\nLatin folk, cumbia, children's music\nLatin folk, cumbia, choral\nLatin folk, cumbia, folk\nLatin folk, cumbia, norteño\nLatin folk, cumbia-funk\nLatin folk, downtempo hip-hop\nLatin folk, dubstep, electronic\nLatin folk, electronic dance\nLatin folk, electronic, cinematic\nLatin folk, electronic, fusion\nLatin folk, flamenco, hip-hop\nLatin folk, flamenco, pop\nLatin folk, flamenco, progressive rock\nLatin folk, flamenco, rumba\nLatin folk, folk-rock\nLatin folk, hardstyle, trance\nLatin folk, hip-hop\nLatin folk, hip-hop, acoustic guitar\nLatin folk, hip-hop, cinematic\nLatin folk, joropo, flamenco\nLatin folk, liturgical\nLatin folk, melancholic pop-rock\nLatin folk, merengue\nLatin folk, new age\nLatin folk, new age, world music\nLatin folk, new-age\nLatin folk, noise rock\nLatin folk, norteño\nLatin folk, operatic, bolero\nLatin folk, operatic, choral\nLatin folk, orchestral, festive\nLatin folk, orchestral, operatic\nLatin folk, orchestral, ranchera\nLatin folk, piano ballad\nLatin folk, progressive rock\nLatin folk, psychedelic electronic\nLatin folk, psychedelic rock\nLatin folk, psychedelic, regional Mexican\nLatin folk, ranchera\nLatin folk, reggae, dancehall\nLatin folk, reggaeton\nLatin folk, regional Mexican\nLatin folk, regional Mexican, acoustic guitar\nLatin folk, regional Mexican, pop-rock\nLatin folk, retro electronic\nLatin folk, rumba flamenca\nLatin folk, sacred music\nLatin folk, salsa\nLatin folk, salsa, Cuban son\nLatin folk, salsa, Latin rock\nLatin folk, salsa, bolero\nLatin folk, salsa, piano ballad\nLatin folk, ska, big band\nLatin folk, ska-punk, reggae, surf rock\nLatin folk, soft rock, Christian\nLatin folk, stadium rock\nLatin folk, synth-pop\nLatin folk, tango, children's musical\nLatin folk, tango, cinematic\nLatin folk, trap, electronic\nLatin folk, world music, cinematic\nLatin folk, world music, new age\nLatin folk, world music, worship\nLatin folk, worship\nLatin folk-gospel\nLatin folk-pop\nLatin folk-pop world music\nLatin folk-punk\nLatin folk-rap\nLatin folk-reggae\nLatin folk-rock\nLatin folk-rock Christian rock\nLatin folk-rock alternative rock\nLatin folk-rock progressive hard rock\nLatin folk-rock punk\nLatin folk-rock punk rock\nLatin folk-rock, Latin rock\nLatin folk-rock, hard rock\nLatin folk-rock, heavy metal\nLatin folk-rock, heavy metal, ambient\nLatin folk-rock, psychedelic rock\nLatin folk-rock, reggaeton, melodic rock\nLatin folk-rock, thrash metal\nLatin football anthem\nLatin freestyle\nLatin freestyle funk hip-hop\nLatin freestyle house\nLatin freestyle, new jack swing\nLatin freestyle, old-school hip-hop\nLatin funk\nLatin funk Afro-Cuban jazz\nLatin funk R&B\nLatin funk acid jazz\nLatin funk boogaloo\nLatin funk boogie\nLatin funk bossa nova\nLatin funk breakbeat\nLatin funk chiptune\nLatin funk chiptune indie rock\nLatin funk cumbia\nLatin funk disco\nLatin funk fusion\nLatin funk gospel\nLatin funk hip-hop\nLatin funk house\nLatin funk jazz fusion\nLatin funk jazz-fusion\nLatin funk neo-soul\nLatin funk nu-disco\nLatin funk pop\nLatin funk protest\nLatin funk rap\nLatin funk reggae\nLatin funk reggae fusion\nLatin funk reggaeton\nLatin funk rock\nLatin funk salsa\nLatin funk ska\nLatin funk soul\nLatin funk surf rock\nLatin funk worldbeat\nLatin funk, Bollywood dance\nLatin funk, big band\nLatin funk, big band jazz\nLatin funk, big band swing\nLatin funk, breakbeat, big beat\nLatin funk, conscious hip-hop\nLatin funk, electronic fusion\nLatin funk, gospel\nLatin funk, hard rock\nLatin funk, hard techno\nLatin funk, indie pop\nLatin funk, old-school hip-hop\nLatin funk, psychedelic pop\nLatin funk, psychedelic rock\nLatin funk, psychedelic rock, hip-hop\nLatin funk, second-line\nLatin funk, ska, jazz fusion\nLatin funk, trap\nLatin funk, trip-hop, funk-rock\nLatin funk, video game music\nLatin funk, worldbeat, electronic lounge\nLatin funk, worldbeat, video game music\nLatin funk-hop\nLatin funk-house\nLatin funk-pop\nLatin funk-rap\nLatin funk-reggae\nLatin funk-rock\nLatin fusion\nLatin fusion French\nLatin fusion Middle Eastern dance\nLatin fusion chiptune\nLatin fusion cumbia\nLatin fusion funk hip-hop\nLatin fusion lo-fi\nLatin fusion reggaeton\nLatin fusion salsa\nLatin fusion salsa reggae\nLatin fusion tango\nLatin fusion, Central Asian, flamenco\nLatin fusion, Eastern European folk\nLatin fusion, Eastern European, trap\nLatin fusion, Middle Eastern dance\nLatin fusion, Middle Eastern, dance\nLatin fusion, Middle Eastern, downtempo\nLatin fusion, Middle Eastern, flamenco\nLatin fusion, Middle Eastern, folk\nLatin fusion, Middle Eastern, romantic\nLatin fusion, South Asian fusion\nLatin fusion, South Asian fusion, upbeat romance\nLatin fusion, South Asian, world music\nLatin fusion, South Indian, devotional\nLatin fusion, Turkish folk\nLatin fusion, flamenco, chanson\nLatin fusion, oud, cinematic\nLatin fusion, reggaeton, cumbia\nLatin fusion, reggaeton, dembow\nLatin fusion, turntablism, Eastern European pop\nLatin fusion, video game music, jazz fusion\nLatin gangsta rap\nLatin garage\nLatin gospel\nLatin gospel cumbia\nLatin gospel funk\nLatin gospel jazz\nLatin gospel pop\nLatin gospel pop-rock\nLatin gospel rock\nLatin gospel salsa\nLatin gospel ska-punk\nLatin gospel, Norteño\nLatin groove\nLatin groove cumbia\nLatin groove, indie pop, cinematic\nLatin groove, new-age, cumbia\nLatin groove, psychedelic rock\nLatin guitar\nLatin guitar flamenco\nLatin hard dance\nLatin hard rock\nLatin hardstyle\nLatin hip hop\nLatin hip hop, Eastern European fusion\nLatin hip hop, hardstyle\nLatin hip hop, stadium rock\nLatin hip-hop\nLatin hip-hop G-funk\nLatin hip-hop German hip-hop\nLatin hip-hop R&B\nLatin hip-hop bolero\nLatin hip-hop boom-bap\nLatin hip-hop chillhop\nLatin hip-hop chiptune\nLatin hip-hop cinematic\nLatin hip-hop cumbia\nLatin hip-hop cumbia-rap\nLatin hip-hop dembow\nLatin hip-hop dreamy indie pop\nLatin hip-hop electronic pop\nLatin hip-hop flamenco\nLatin hip-hop funk\nLatin hip-hop funk rock\nLatin hip-hop funk-rock\nLatin hip-hop fusion\nLatin hip-hop indie pop\nLatin hip-hop lo-fi\nLatin hip-hop lo-fi neo-soul\nLatin hip-hop neo-soul\nLatin hip-hop pop\nLatin hip-hop reggae\nLatin hip-hop reggaeton\nLatin hip-hop rock\nLatin hip-hop rumba\nLatin hip-hop salsa\nLatin hip-hop tango\nLatin hip-hop trap\nLatin hip-hop, Deutschrap\nLatin hip-hop, Latin trap\nLatin hip-hop, Middle Eastern fusion\nLatin hip-hop, R&B, soul\nLatin hip-hop, boom-bap\nLatin hip-hop, boom-bap, trap\nLatin hip-hop, cinematic pop\nLatin hip-hop, cinematic trap\nLatin hip-hop, conscious rap\nLatin hip-hop, electronic dance\nLatin hip-hop, neo-soul\nLatin hip-hop, pop-rap\nLatin hip-hop, reggaeton\nLatin hip-hop, reggaeton, ballad\nLatin hip-hop, reggaeton, trap\nLatin hip-hop, regional Mexican\nLatin hip-hop, trap\nLatin hip-hop, trap, lo-fi\nLatin hip-hop, trap, reggaeton\nLatin hip-hop, world fusion\nLatin hip-hop, world music\nLatin hip-house\nLatin holiday, Soviet estrada\nLatin house\nLatin house chiptune\nLatin house dance-pop\nLatin house flamenco\nLatin house funk\nLatin house hip-hop\nLatin house lounge\nLatin house lounge jazz\nLatin house nu-disco\nLatin house reggaeton\nLatin house soul\nLatin house tribal house\nLatin house worldbeat\nLatin house, Eurodance\nLatin house, Eurodance, dance-pop\nLatin house, Italo-disco\nLatin house, Neapolitan folk\nLatin house, South Asian fusion\nLatin house, afrobeat\nLatin house, big room house\nLatin house, cinematic, Dutch House\nLatin house, cinematic, world music\nLatin house, deep house\nLatin house, electro-house, Turkish pop\nLatin house, freestyle, dance-pop\nLatin house, hip-hop\nLatin house, hyperpop\nLatin house, moombahton\nLatin house, moombahton, electronic dance\nLatin house, progressive house, tech-trance\nLatin house, reggaeton\nLatin house, reggaeton, rock\nLatin house, tribal house\nLatin house, tribal house, EDM\nLatin house, tribal house, dance\nLatin house, tribal house, deep house\nLatin house, tribal house, electro\nLatin house, tribal house, electronic dance music\nLatin house, tribal, electronic\nLatin house, tribal, electronic dance\nLatin hyperpop\nLatin indie\nLatin indie folk\nLatin indie hip-hop\nLatin indie pop\nLatin indie pop-rock\nLatin indie rock\nLatin indie-folk\nLatin indie-pop\nLatin indie-pop lo-fi hip-hop\nLatin instrumental\nLatin jam\nLatin jazz\nLatin jazz Afro-Cuban\nLatin jazz Bossa Nova\nLatin jazz C-pop\nLatin jazz Cantopop\nLatin jazz J-pop\nLatin jazz J-pop fusion\nLatin jazz MPB\nLatin jazz Mandopop\nLatin jazz R&B\nLatin jazz ballad\nLatin jazz bebop\nLatin jazz big band\nLatin jazz blues\nLatin jazz blues fusion\nLatin jazz bolero\nLatin jazz boogaloo\nLatin jazz boogie-woogie\nLatin jazz bossa nova\nLatin jazz cabaret\nLatin jazz cabaret tango\nLatin jazz chiptune\nLatin jazz city pop\nLatin jazz classical\nLatin jazz cumbia\nLatin jazz deep house\nLatin jazz drum and bass\nLatin jazz exotica\nLatin jazz flamenco\nLatin jazz flamenco fusion\nLatin jazz flamenco progressive rock\nLatin jazz funk\nLatin jazz funk bossa nova\nLatin jazz funk disco\nLatin jazz funk lounge\nLatin jazz funk progressive rock\nLatin jazz funk rock\nLatin jazz funk soul\nLatin jazz fusion\nLatin jazz fusion, pop-rock\nLatin jazz gospel\nLatin jazz gypsy\nLatin jazz hip-hop\nLatin jazz house\nLatin jazz indie rock\nLatin jazz lounge\nLatin jazz lounge house\nLatin jazz mambo\nLatin jazz musical theater\nLatin jazz neo-soul\nLatin jazz orchestral\nLatin jazz pop\nLatin jazz pop-rock\nLatin jazz progressive rock\nLatin jazz punk\nLatin jazz reggae\nLatin jazz reggae fusion\nLatin jazz rock\nLatin jazz salsa\nLatin jazz salsa cabaret\nLatin jazz salsa chanson\nLatin jazz salsa rock\nLatin jazz samba\nLatin jazz samba-pop\nLatin jazz show tune\nLatin jazz ska-punk\nLatin jazz smooth jazz\nLatin jazz soul\nLatin jazz soulful lounge\nLatin jazz swing\nLatin jazz tango\nLatin jazz tango cabaret\nLatin jazz tango cumbia\nLatin jazz tango fusion\nLatin jazz trap\nLatin jazz trip-hop\nLatin jazz world fusion\nLatin jazz world music\nLatin jazz, African pop\nLatin jazz, Afro-Caribbean, experimental\nLatin jazz, Afro-Cuban, instrumental\nLatin jazz, Arabic funk\nLatin jazz, Azerbaijani, mambo\nLatin jazz, Balkan brass, world fusion\nLatin jazz, Bossa Nova\nLatin jazz, Bossa Nova, Samba\nLatin jazz, Bossa Nova, bilingual\nLatin jazz, Bossa Nova, cinematic orchestral\nLatin jazz, Bossa Nova, world fusion\nLatin jazz, Brazilian samba, progressive fusion\nLatin jazz, Broadway\nLatin jazz, C-pop\nLatin jazz, French chanson\nLatin jazz, French chanson, world music\nLatin jazz, J-pop, cinematic\nLatin jazz, J-pop, city pop\nLatin jazz, Japanese hip-hop\nLatin jazz, Kayōkyoku, big band\nLatin jazz, Kayōkyoku, cinematic\nLatin jazz, Latin pop\nLatin jazz, MPB\nLatin jazz, R&B, Christmas\nLatin jazz, ambient\nLatin jazz, art rock\nLatin jazz, art-pop\nLatin jazz, big band, bolero\nLatin jazz, big band, cinematic\nLatin jazz, big band, fusion\nLatin jazz, big band, show tune\nLatin jazz, blues-rock\nLatin jazz, bolero\nLatin jazz, bolero, Italian ballad\nLatin jazz, boogie-woogie\nLatin jazz, boogie-woogie, progressive rock\nLatin jazz, boogie-woogie, salsa\nLatin jazz, bossa nova\nLatin jazz, bossa nova, cinematic\nLatin jazz, bossa nova, flamenco\nLatin jazz, bossa nova, lo-fi hip hop\nLatin jazz, bossa nova, lounge\nLatin jazz, bossa nova, world music\nLatin jazz, children's music, mambo\nLatin jazz, cinematic orchestral\nLatin jazz, cinematic orchestral, Bossa Nova\nLatin jazz, cinematic rock, opera\nLatin jazz, cinematic, video game music\nLatin jazz, city pop\nLatin jazz, city pop, jazzy\nLatin jazz, classical ballad, operatic pop\nLatin jazz, classical, video game soundtrack\nLatin jazz, conscious hip-hop\nLatin jazz, electronic breakbeat\nLatin jazz, exotica, cinematic\nLatin jazz, exotica, mambo\nLatin jazz, flamenco, hard rock\nLatin jazz, funk house\nLatin jazz, gypsy jazz, ballad\nLatin jazz, mambo\nLatin jazz, mambo, big band\nLatin jazz, mambo, children's music\nLatin jazz, mambo, novelty\nLatin jazz, mambo, operatic\nLatin jazz, modern classical, boogie-woogie\nLatin jazz, neo-soul\nLatin jazz, progressive rock\nLatin jazz, psychedelic funk, funk rock\nLatin jazz, psychedelic rock\nLatin jazz, punk rock\nLatin jazz, retro video game\nLatin jazz, salsa\nLatin jazz, salsa, J-pop\nLatin jazz, salsa, Vietnamese pop\nLatin jazz, salsa, rock\nLatin jazz, samba-pop\nLatin jazz, show tune, big band\nLatin jazz, smooth funk\nLatin jazz, smooth fusion\nLatin jazz, smooth jazz\nLatin jazz, smooth pop\nLatin jazz, symphonic rock\nLatin jazz, theatrical, cabaret\nLatin jazz, trap-pop\nLatin jazz, video game music\nLatin jazz, vintage ballad\nLatin jazz, world fusion\nLatin jazz, world fusion, progressive instrumental\nLatin jazz, world music\nLatin jazz, world music, blues\nLatin jazz, world music, cinematic\nLatin jazz, world music, salsa\nLatin jazz, worldbeat, conscious hip-hop\nLatin jazz-blues\nLatin jazz-funk\nLatin jazz-fusion\nLatin jazz-fusion, Japanese rock\nLatin jazz-fusion, thrash metal, funk-rock\nLatin jazz-hop\nLatin jazz-pop\nLatin jazz-rap\nLatin jazz-rock\nLatin jazz-rock fusion\nLatin jingle\nLatin lament\nLatin lo-fi\nLatin lounge\nLatin lullaby\nLatin mambo\nLatin mambo, Hawaiian exotica\nLatin mambo, big band, Christmas\nLatin mambo, lounge pop, cabaret\nLatin march\nLatin marching\nLatin mashup\nLatin math rock\nLatin medley\nLatin metal\nLatin military march\nLatin music\nLatin musical\nLatin narrative\nLatin new age\nLatin new wave\nLatin novelty\nLatin opera\nLatin orchestral\nLatin party\nLatin party rap\nLatin party-rock\nLatin percussion\nLatin percussion rock\nLatin percussion, minimalist\nLatin piano\nLatin plena\nLatin polka\nLatin pop\nLatin pop 80s\nLatin pop 90s\nLatin pop Afro-Cuban\nLatin pop Afro-Cumbia\nLatin pop Afrobeat\nLatin pop Afrobeats\nLatin pop Afrobeats R&B\nLatin pop Arabic dance\nLatin pop Arabic fusion\nLatin pop Arabic pop\nLatin pop Arabic trap\nLatin pop Balkan fusion\nLatin pop Balkan rock\nLatin pop Bollywood\nLatin pop Bollywood pop\nLatin pop Bossa Nova\nLatin pop C-pop\nLatin pop Christian\nLatin pop Christian children's\nLatin pop Christian contemporary\nLatin pop Christian hip-hop\nLatin pop Cumbia\nLatin pop Dutch R&B\nLatin pop Dutch hip-hop\nLatin pop Dutch pop\nLatin pop EDM\nLatin pop Eurodance\nLatin pop European folk\nLatin pop Europop\nLatin pop Fado\nLatin pop French hip-hop\nLatin pop French pop\nLatin pop French rap\nLatin pop German hip-hop\nLatin pop J-pop\nLatin pop J-pop anime\nLatin pop K-R&B\nLatin pop K-ballad\nLatin pop K-pop\nLatin pop K-pop fusion\nLatin pop Malay pop\nLatin pop Mandopop\nLatin pop Mandopop R&B\nLatin pop Mandopop fusion\nLatin pop Mizrahi\nLatin pop North African pop\nLatin pop Punjabi R&B\nLatin pop R&B\nLatin pop R&B cinematic\nLatin pop R&B electronic\nLatin pop R&B flamenco\nLatin pop R&B funk\nLatin pop R&B fusion\nLatin pop R&B gospel\nLatin pop R&B hip-hop\nLatin pop R&B lo-fi\nLatin pop R&B lo-fi hip-hop\nLatin pop R&B neo-soul\nLatin pop R&B reggaeton\nLatin pop R&B soul\nLatin pop R&B trap\nLatin pop Scandinavian pop\nLatin pop a cappella\nLatin pop acoustic\nLatin pop acoustic R&B\nLatin pop acoustic folk-rock\nLatin pop acoustic hip-hop\nLatin pop acoustic pop\nLatin pop acoustic rock\nLatin pop afrobeat tropical house\nLatin pop afrobeats dancehall\nLatin pop alternative hip-hop\nLatin pop alternative rock\nLatin pop anime theme\nLatin pop arena rock\nLatin pop bachata\nLatin pop ballad\nLatin pop banda\nLatin pop big band\nLatin pop bolero\nLatin pop bolero lounge\nLatin pop boogaloo\nLatin pop bossa nova\nLatin pop cabaret\nLatin pop cabaret jazz\nLatin pop cabaret tango\nLatin pop children's\nLatin pop children's Christian\nLatin pop children's music\nLatin pop children's praise\nLatin pop chill reggaeton\nLatin pop chillhop\nLatin pop chillwave\nLatin pop chiptune\nLatin pop cinematic\nLatin pop city pop\nLatin pop classical\nLatin pop cumbia\nLatin pop cumbia Caribbean\nLatin pop cumbia Christian\nLatin pop cumbia Christian contemporary\nLatin pop cumbia accordion\nLatin pop cumbia andean folk\nLatin pop cumbia bachata\nLatin pop cumbia banda\nLatin pop cumbia beachy\nLatin pop cumbia bilingual\nLatin pop cumbia bolero\nLatin pop cumbia brass\nLatin pop cumbia children's music\nLatin pop cumbia chiptune\nLatin pop cumbia cinematic\nLatin pop cumbia dembow\nLatin pop cumbia flamenco\nLatin pop cumbia forró\nLatin pop cumbia lo-fi\nLatin pop cumbia merengue\nLatin pop cumbia norteña\nLatin pop cumbia norteño\nLatin pop cumbia psychedelic\nLatin pop cumbia psychedelic rock\nLatin pop cumbia quirky\nLatin pop cumbia reggae\nLatin pop cumbia reggaeton\nLatin pop cumbia regional Mexican\nLatin pop cumbia retro\nLatin pop cumbia rock\nLatin pop cumbia rumba\nLatin pop cumbia salsa\nLatin pop cumbia satirical\nLatin pop cumbia ska\nLatin pop cumbia synth\nLatin pop cumbia tango\nLatin pop cumbia theatrical\nLatin pop cumbia tropical\nLatin pop cumbia vallenato\nLatin pop cumbia villera\nLatin pop cumbia vintage\nLatin pop cumbia whimsical\nLatin pop cumbia-pop\nLatin pop dance-pop\nLatin pop dance-rock\nLatin pop dancehall\nLatin pop dancehall Christian hip-hop\nLatin pop deep house\nLatin pop dembow\nLatin pop desert rock\nLatin pop disco\nLatin pop doo-wop\nLatin pop dream pop\nLatin pop electronic\nLatin pop electronic rock\nLatin pop emo rap\nLatin pop emo trap hyperpop\nLatin pop emo-trap\nLatin pop emo-trap hyperpop\nLatin pop exotica\nLatin pop fado\nLatin pop flamenco\nLatin pop flamenco fado\nLatin pop flamenco fusion\nLatin pop folk\nLatin pop folk-pop\nLatin pop freestyle\nLatin pop funk\nLatin pop funk R&B\nLatin pop funk acid jazz\nLatin pop funk carioca\nLatin pop funk city pop\nLatin pop funk disco\nLatin pop funk jazz\nLatin pop funk jazz fusion\nLatin pop funk neo-soul\nLatin pop funk reggae\nLatin pop funk reggaeton\nLatin pop funk rock\nLatin pop funk salsa\nLatin pop funk ska\nLatin pop funk soul\nLatin pop funk-rock\nLatin pop fusion\nLatin pop future bass\nLatin pop future bass reggaeton\nLatin pop gospel\nLatin pop gypsy jazz swing\nLatin pop hip hop\nLatin pop hip-hop\nLatin pop house\nLatin pop hyperpop\nLatin pop indie pop\nLatin pop indie rock\nLatin pop jazz\nLatin pop jazz bolero\nLatin pop jazz bossa nova\nLatin pop jazz fusion\nLatin pop kizomba\nLatin pop lo-fi\nLatin pop lo-fi R&B\nLatin pop lo-fi hip hop\nLatin pop lo-fi hip-hop\nLatin pop lo-fi hip-hop chiptune\nLatin pop lounge\nLatin pop lounge jazz\nLatin pop mariachi\nLatin pop merengue\nLatin pop merengue salsa\nLatin pop moombahton\nLatin pop neo-soul\nLatin pop neo-soul funk\nLatin pop neo-soul hip-hop\nLatin pop norteño\nLatin pop novelty\nLatin pop nu-disco\nLatin pop nu-disco funk\nLatin pop nu-disco funk-pop\nLatin pop nu-disco house\nLatin pop orchestral\nLatin pop pimba\nLatin pop protest\nLatin pop ranchera\nLatin pop ranchera bolero\nLatin pop ranchera mariachi\nLatin pop rap\nLatin pop reggae\nLatin pop reggae cumbia\nLatin pop reggae dancehall\nLatin pop reggae funk\nLatin pop reggae fusion\nLatin pop reggae lovers rock\nLatin pop reggae rocksteady\nLatin pop reggae ska\nLatin pop reggae soul\nLatin pop reggae-dancehall\nLatin pop reggae-ska\nLatin pop reggaeton\nLatin pop reggaeton Christian hip-hop\nLatin pop reggaeton cumbia\nLatin pop reggaeton flamenco\nLatin pop reggaeton funk\nLatin pop reggaeton hyperpop\nLatin pop reggaeton salsa\nLatin pop reggaeton smooth jazz\nLatin pop regional Mexican\nLatin pop rock\nLatin pop rockabilly\nLatin pop rumba\nLatin pop salsa\nLatin pop salsa MPB\nLatin pop salsa cumbia\nLatin pop salsa gospel\nLatin pop salsa merengue\nLatin pop salsa reggae\nLatin pop salsa reggaeton\nLatin pop samba\nLatin pop satire\nLatin pop show tune\nLatin pop singer-songwriter\nLatin pop ska\nLatin pop ska reggae\nLatin pop slap house\nLatin pop smooth jazz\nLatin pop soul\nLatin pop surf-rock\nLatin pop synth-pop\nLatin pop tango\nLatin pop tango big band\nLatin pop tango bolero\nLatin pop tango cabaret\nLatin pop tango classical\nLatin pop tango cumbia\nLatin pop tango flamenco\nLatin pop tango regional Mexican\nLatin pop tech house\nLatin pop trap\nLatin pop trap R&B\nLatin pop trap-R&B\nLatin pop trip-hop\nLatin pop tropical house\nLatin pop vallenato\nLatin pop world fusion\nLatin pop world music\nLatin pop worldbeat\nLatin pop worship\nLatin pop zouk\nLatin pop, 80s aesthetic\nLatin pop, 80s aesthetic, cinematic\nLatin pop, 80s aesthetic, dramatic ballad\nLatin pop, 80s aesthetic, theatrical\nLatin pop, 80s anime, anthemic\nLatin pop, 80s pop\nLatin pop, 80s pop, ballad\nLatin pop, 80s pop, cinematic\nLatin pop, 80s pop, dramatic ballad\nLatin pop, 80s pop, theatrical\nLatin pop, 80s synth\nLatin pop, 80s synth, Eurodance\nLatin pop, 80s synth, cinematic\nLatin pop, 80s synth, disco\nLatin pop, 80s synth, dramatic ballad\nLatin pop, 80s synth, dramatic pop\nLatin pop, 80s synth, theatrical\nLatin pop, 80s synth-pop\nLatin pop, 80s synth-pop, Christian\nLatin pop, 80s synth-pop, Christian pop\nLatin pop, 80s synth-pop, cinematic\nLatin pop, 80s worldbeat\nLatin pop, 90s Eurodance\nLatin pop, 90s Europop\nLatin pop, 90s R&B\nLatin pop, 90s house, funk\nLatin pop, Afro-Caribbean, dance\nLatin pop, Afro-Cuban, bilingual\nLatin pop, Afro-Cuban, funk\nLatin pop, Afro-Cuban, upbeat\nLatin pop, Afro-Latin\nLatin pop, Afrobeat\nLatin pop, Afrobeat, reggaeton\nLatin pop, Afrobeats\nLatin pop, Afrobeats, Zouk\nLatin pop, Afrobeats, dancehall\nLatin pop, Afropop, worldbeat\nLatin pop, Andean folk\nLatin pop, Andean folk, synth pop\nLatin pop, Andean fusion\nLatin pop, Arabic dance\nLatin pop, Arabic fusion\nLatin pop, Arabic pop, bilingual\nLatin pop, Arabic pop, reggaeton\nLatin pop, Balkan brass\nLatin pop, Balkan dance\nLatin pop, Balkan folk\nLatin pop, Balkan folk, soul-infused pop-rock\nLatin pop, Balkan fusion\nLatin pop, Balkan fusion, Klezmer\nLatin pop, Balkan pop\nLatin pop, Bengali folk, world music\nLatin pop, Bengali pop\nLatin pop, Bollywood fusion\nLatin pop, Bollywood pop\nLatin pop, Bollywood, Indian classical\nLatin pop, Bollywood, South Asian pop\nLatin pop, Bossa Nova\nLatin pop, Bossa Nova, City Pop\nLatin pop, Bossa Nova, Samba\nLatin pop, Bossa Nova, flamenco\nLatin pop, Bossa Nova, jazz\nLatin pop, Bossa Nova, polka\nLatin pop, Bossa Nova, salsa\nLatin pop, Bossa Nova, smooth jazz\nLatin pop, Brazilian carnival\nLatin pop, Brazilian funk\nLatin pop, Brazilian pop-funk\nLatin pop, Brazilian, upbeat\nLatin pop, C-pop\nLatin pop, C-pop, ambient\nLatin pop, Central Asian dance\nLatin pop, Central Asian folk\nLatin pop, Central Asian fusion\nLatin pop, Central Asian pop\nLatin pop, Christian children's\nLatin pop, Christian contemporary\nLatin pop, Christian contemporary, folk\nLatin pop, Christian contemporary, reggaeton\nLatin pop, Christian contemporary, smooth jazz\nLatin pop, Christian contemporary, soft rock\nLatin pop, Christian contemporary, trap\nLatin pop, Christian dance-pop\nLatin pop, Christian hip-hop\nLatin pop, Christian hip-hop, acoustic folk\nLatin pop, Christian pop\nLatin pop, Christian pop, Eurodance\nLatin pop, Christian pop, Vietnamese\nLatin pop, Christian pop, cumbia\nLatin pop, Christian pop, salsa\nLatin pop, Christian pop-rock\nLatin pop, Christian praise\nLatin pop, Christian rock\nLatin pop, Christian worship\nLatin pop, Christian worship, synth-pop\nLatin pop, Christian, 80s pop\nLatin pop, Christian, Cumbia\nLatin pop, Christian, Eurodance\nLatin pop, Christian, ballad\nLatin pop, Christian, celebratory\nLatin pop, Christian, cinematic\nLatin pop, Christian, cumbia\nLatin pop, Christian, reggaeton\nLatin pop, Christian, retro\nLatin pop, Christian, trap\nLatin pop, Christian, triumphant\nLatin pop, Christmas\nLatin pop, Christmas pop\nLatin pop, Christmas, ballad\nLatin pop, Christmas, festive\nLatin pop, Christmas, salsa\nLatin pop, Cuban folk, upbeat\nLatin pop, Cumbia\nLatin pop, Cumbia Norteña\nLatin pop, Cumbia, Christian\nLatin pop, Cumbia, Norteño\nLatin pop, Desi hip-hop\nLatin pop, Dutch hip-hop\nLatin pop, EDM\nLatin pop, EDM, Christian\nLatin pop, EDM, Christian contemporary\nLatin pop, EDM, Christian dance\nLatin pop, EDM, French rap\nLatin pop, EDM, K-pop\nLatin pop, EDM, acoustic\nLatin pop, EDM, atmospheric\nLatin pop, EDM, ballad\nLatin pop, EDM, cinematic\nLatin pop, EDM, dance-pop\nLatin pop, EDM, flamenco\nLatin pop, EDM, hip-hop\nLatin pop, EDM, moombahton\nLatin pop, EDM, progressive house\nLatin pop, EDM, reggaeton\nLatin pop, EDM, synth pop\nLatin pop, EDM, trap\nLatin pop, Eastern European dance\nLatin pop, Eastern European folk\nLatin pop, Eastern European pop\nLatin pop, Eastern European rock\nLatin pop, Euro-pop\nLatin pop, Eurodance\nLatin pop, Eurodance, 90s dance\nLatin pop, Eurodance, 90s dance-pop\nLatin pop, Eurodance, Christian\nLatin pop, Eurodance, Dutch pop\nLatin pop, Eurodance, J-pop\nLatin pop, Eurodance, K-pop\nLatin pop, Eurodance, big band\nLatin pop, Eurodance, children's music\nLatin pop, Eurodance, cinematic\nLatin pop, Eurodance, flamenco\nLatin pop, Eurodance, funk\nLatin pop, Eurodance, gypsy tango\nLatin pop, Eurodance, hip-hop\nLatin pop, Eurodance, reggaeton\nLatin pop, Eurodance, salsa\nLatin pop, Eurodance, spiritual\nLatin pop, Eurodance, world music\nLatin pop, European folk\nLatin pop, European fusion\nLatin pop, Europop\nLatin pop, Europop, C-pop\nLatin pop, Fado\nLatin pop, Finnish hip-hop\nLatin pop, French chanson\nLatin pop, French chanson, worldbeat\nLatin pop, French cloud rap\nLatin pop, French dance-pop\nLatin pop, French house\nLatin pop, French pop\nLatin pop, French pop, world fusion\nLatin pop, French rap\nLatin pop, German R&B\nLatin pop, German hip-hop\nLatin pop, Greek pop\nLatin pop, Halloween, theatrical\nLatin pop, Indian film music\nLatin pop, Indonesian pop\nLatin pop, Israeli pop, EDM\nLatin pop, Israeli pop, electronic dance\nLatin pop, Italian pop\nLatin pop, Italian pop-rock\nLatin pop, Italo disco\nLatin pop, Italo disco, Eurodance\nLatin pop, Italo disco, new wave\nLatin pop, Italo-disco\nLatin pop, Italo-disco, synthwave\nLatin pop, J-pop\nLatin pop, J-pop, anime\nLatin pop, J-pop, electronic\nLatin pop, J-pop, flamenco\nLatin pop, J-pop, rock\nLatin pop, J-rock\nLatin pop, Japanese hip-hop\nLatin pop, K-pop\nLatin pop, K-pop, J-pop\nLatin pop, K-pop, hyperpop\nLatin pop, Kizomba\nLatin pop, Kizomba, R&B\nLatin pop, Kizomba, retro\nLatin pop, Kizomba, theatrical\nLatin pop, Latin rock\nLatin pop, Latin rock, flamenco\nLatin pop, Latin ska\nLatin pop, MPB\nLatin pop, Malay pop\nLatin pop, Mandarin pop\nLatin pop, Mediterranean\nLatin pop, Mediterranean dance\nLatin pop, Mediterranean folk\nLatin pop, Mediterranean pop\nLatin pop, Middle Eastern dance\nLatin pop, Middle Eastern fusion\nLatin pop, Middle Eastern fusion, exotica\nLatin pop, Middle Eastern fusion, reggaeton\nLatin pop, Middle Eastern pop\nLatin pop, Middle Eastern, Turkish\nLatin pop, Middle Eastern, dance\nLatin pop, Mizrahi dance\nLatin pop, Mizrahi dance, reggaeton\nLatin pop, Mizrahi fusion\nLatin pop, Mizrahi, dance\nLatin pop, Moombahton\nLatin pop, Norteño\nLatin pop, Norteño, Cumbia\nLatin pop, Norteño, cumbia\nLatin pop, Norteño, regional Mexican\nLatin pop, North African pop\nLatin pop, R&B\nLatin pop, R&B, Christian contemporary\nLatin pop, R&B, New Jack Swing\nLatin pop, R&B, Vietnamese pop\nLatin pop, R&B, acoustic ballad\nLatin pop, R&B, ambient\nLatin pop, R&B, atmospheric electronic\nLatin pop, R&B, chillwave\nLatin pop, R&B, chiptune\nLatin pop, R&B, cinematic\nLatin pop, R&B, cumbia\nLatin pop, R&B, dance-pop\nLatin pop, R&B, dancehall\nLatin pop, R&B, deep house\nLatin pop, R&B, dembow\nLatin pop, R&B, dream pop\nLatin pop, R&B, dreamy synth-pop\nLatin pop, R&B, early 2000s\nLatin pop, R&B, electronic\nLatin pop, R&B, flamenco\nLatin pop, R&B, flamenco fusion\nLatin pop, R&B, funk\nLatin pop, R&B, gospel\nLatin pop, R&B, hip-hop\nLatin pop, R&B, jazz\nLatin pop, R&B, lo-fi\nLatin pop, R&B, lo-fi hip-hop\nLatin pop, R&B, neo-soul\nLatin pop, R&B, new jack swing\nLatin pop, R&B, pop-rock\nLatin pop, R&B, power ballad\nLatin pop, R&B, reggaeton\nLatin pop, R&B, rock\nLatin pop, R&B, sentimental pop\nLatin pop, R&B, smooth jazz\nLatin pop, R&B, soul\nLatin pop, R&B, synth-pop\nLatin pop, R&B, synthwave\nLatin pop, R&B, trap\nLatin pop, Romanian pop-dance\nLatin pop, Russian estrada\nLatin pop, Russian hip-hop\nLatin pop, Russian pop\nLatin pop, Scandinavian party\nLatin pop, Schlager\nLatin pop, Schlager, Cumbia\nLatin pop, South African pop\nLatin pop, South Asian fusion\nLatin pop, South Asian pop\nLatin pop, South Indian fusion\nLatin pop, Southeast Asian pop\nLatin pop, Tamil pop\nLatin pop, Turkish children's\nLatin pop, Turkish dance-pop\nLatin pop, Turkish pop\nLatin pop, Turkish pop, Azerbaijani pop\nLatin pop, Turkish pop, dance pop\nLatin pop, Turkish pop, upbeat\nLatin pop, UK garage, deep house\nLatin pop, V-pop\nLatin pop, Vallenato\nLatin pop, Vallenato, reggaeton\nLatin pop, Vietnamese pop\nLatin pop, Zouk, Kizomba\nLatin pop, Zouk, R&B\nLatin pop, Zouk, Soca\nLatin pop, acid jazz\nLatin pop, acoustic rock\nLatin pop, alternative rock\nLatin pop, alternative singer-songwriter\nLatin pop, ambient\nLatin pop, anime-inspired\nLatin pop, arena rock\nLatin pop, atmospheric trap\nLatin pop, bachata\nLatin pop, bachata, 2000s pop\nLatin pop, bachata, reggaeton\nLatin pop, bachata, tropical\nLatin pop, banda\nLatin pop, banda, Christian\nLatin pop, banda, norteño\nLatin pop, banda, pop-rock\nLatin pop, bedroom pop\nLatin pop, big band\nLatin pop, big band jazz\nLatin pop, big band swing\nLatin pop, big band, Indonesian pop\nLatin pop, big band, bolero\nLatin pop, big band, cinematic\nLatin pop, big band, jazz\nLatin pop, big band, mambo\nLatin pop, big band, novelty\nLatin pop, big band, salsa\nLatin pop, big band, show tune\nLatin pop, big band, swing\nLatin pop, big band, theatrical\nLatin pop, big band, vintage\nLatin pop, big-band\nLatin pop, bilingual\nLatin pop, bilingual, flamenco\nLatin pop, blues-rock\nLatin pop, bolero\nLatin pop, bolero, Latin jazz\nLatin pop, bolero, big band\nLatin pop, bolero, big band jazz\nLatin pop, bolero, cha-cha-cha\nLatin pop, bolero, cinematic\nLatin pop, bolero, contemporary Christian\nLatin pop, bolero, dramatic ballad\nLatin pop, bolero, flamenco\nLatin pop, bolero, jazz\nLatin pop, bolero, melancholic\nLatin pop, bolero, ranchera\nLatin pop, bolero, salsa\nLatin pop, bolero, smooth jazz\nLatin pop, bolero, tango\nLatin pop, bolero, theatrical\nLatin pop, boom-bap, emotional\nLatin pop, bossa nova\nLatin pop, bossa nova, dream pop\nLatin pop, bossa nova, hip-hop\nLatin pop, bossa nova, lo-fi hip-hop\nLatin pop, bossa nova, neo-soul\nLatin pop, bossa nova, reggaeton\nLatin pop, bossa nova, retro\nLatin pop, bossa nova, smooth jazz\nLatin pop, children's Christian\nLatin pop, children's music\nLatin pop, children's music, Christian\nLatin pop, children's music, big band jazz\nLatin pop, children's music, cumbia\nLatin pop, children's music, festive\nLatin pop, children's music, folk\nLatin pop, children's music, hyperpop\nLatin pop, children's music, mambo\nLatin pop, children's music, reggaeton-lite\nLatin pop, children's music, salsa\nLatin pop, children's music, tropical\nLatin pop, children's pop\nLatin pop, chillwave\nLatin pop, chillwave, electronic\nLatin pop, chiptune\nLatin pop, chiptune, 8-bit\nLatin pop, chiptune, Christian\nLatin pop, chiptune, J-pop\nLatin pop, chiptune, children's music\nLatin pop, chiptune, cinematic\nLatin pop, chiptune, cumbia\nLatin pop, chiptune, cumbia-pop\nLatin pop, chiptune, cumbia-ska\nLatin pop, chiptune, dance\nLatin pop, chiptune, festive\nLatin pop, chiptune, lo-fi\nLatin pop, chiptune, lo-fi hip hop\nLatin pop, chiptune, pop\nLatin pop, chiptune, reggaeton\nLatin pop, chiptune, regional Mexican\nLatin pop, chiptune, retro\nLatin pop, chiptune, rock\nLatin pop, chiptune, synth-pop\nLatin pop, chiptune, video game\nLatin pop, chiptune, video game music\nLatin pop, choral\nLatin pop, cinematic\nLatin pop, cinematic ballad\nLatin pop, cinematic fusion\nLatin pop, cinematic orchestral\nLatin pop, cinematic orchestral, big band jazz\nLatin pop, cinematic pop\nLatin pop, cinematic pop, pop-rock\nLatin pop, cinematic pop-rock\nLatin pop, cinematic rock\nLatin pop, cinematic synth\nLatin pop, cinematic, C-pop\nLatin pop, cinematic, Christmas\nLatin pop, cinematic, EDM\nLatin pop, cinematic, ballad\nLatin pop, cinematic, bolero\nLatin pop, cinematic, bossa nova\nLatin pop, cinematic, choir\nLatin pop, cinematic, disco-funk\nLatin pop, cinematic, epic\nLatin pop, cinematic, flamenco\nLatin pop, cinematic, gospel\nLatin pop, cinematic, jazzy\nLatin pop, cinematic, mariachi\nLatin pop, cinematic, operatic\nLatin pop, cinematic, orchestral\nLatin pop, cinematic, power ballad\nLatin pop, cinematic, reggaeton\nLatin pop, cinematic, rock\nLatin pop, cinematic, romantic\nLatin pop, cinematic, salsa\nLatin pop, cinematic, synthwave\nLatin pop, cinematic, trap\nLatin pop, cinematic, world fusion\nLatin pop, cinematic, world music\nLatin pop, city pop\nLatin pop, city pop, funk\nLatin pop, classical crossover, gospel\nLatin pop, classical, ballad\nLatin pop, classical, devotional\nLatin pop, cloud rap, dancehall\nLatin pop, commercial pop\nLatin pop, conscious hip-hop\nLatin pop, contemporary Christian\nLatin pop, contemporary Christian worship\nLatin pop, contemporary Christian, EDM\nLatin pop, contemporary R&B\nLatin pop, contemporary worship\nLatin pop, cumbia\nLatin pop, cumbia villera\nLatin pop, cumbia villera, chiptune\nLatin pop, cumbia, Andean fusion\nLatin pop, cumbia, Christian\nLatin pop, cumbia, Christian music\nLatin pop, cumbia, Christian worship\nLatin pop, cumbia, bachata\nLatin pop, cumbia, ballad\nLatin pop, cumbia, banda\nLatin pop, cumbia, big band\nLatin pop, cumbia, chicha\nLatin pop, cumbia, children's music\nLatin pop, cumbia, chiptune\nLatin pop, cumbia, cinematic\nLatin pop, cumbia, dance\nLatin pop, cumbia, devotional\nLatin pop, cumbia, disco\nLatin pop, cumbia, dramatic ballad\nLatin pop, cumbia, electronic\nLatin pop, cumbia, gospel\nLatin pop, cumbia, hip-hop\nLatin pop, cumbia, lo-fi\nLatin pop, cumbia, mariachi\nLatin pop, cumbia, merengue\nLatin pop, cumbia, merengue, rock\nLatin pop, cumbia, música llanera\nLatin pop, cumbia, norteño\nLatin pop, cumbia, novelty\nLatin pop, cumbia, pop-rock\nLatin pop, cumbia, reggae\nLatin pop, cumbia, reggaeton\nLatin pop, cumbia, regional Mexican\nLatin pop, cumbia, regional Mexican, ballad\nLatin pop, cumbia, retro\nLatin pop, cumbia, retro Christmas\nLatin pop, cumbia, retro synth\nLatin pop, cumbia, salsa\nLatin pop, cumbia, synth-pop\nLatin pop, cumbia, tango\nLatin pop, cumbia, theatrical\nLatin pop, cumbia, tropical\nLatin pop, cumbia, tropical house\nLatin pop, cumbia, video game music\nLatin pop, cumbia, worship\nLatin pop, cumbia-pop\nLatin pop, cumbia-pop, pop-rock\nLatin pop, dance, cumbia\nLatin pop, dance, flamenco\nLatin pop, dance, flamenco fusion\nLatin pop, dance, tango nuevo\nLatin pop, dance-pop\nLatin pop, dance-pop, Christian praise\nLatin pop, dance-pop, EDM\nLatin pop, dance-pop, orchestral\nLatin pop, dance-pop, reggaeton\nLatin pop, dancehall, acoustic ballad\nLatin pop, dark R&B\nLatin pop, deep house\nLatin pop, deep house, ethereal\nLatin pop, deep house, reggaeton\nLatin pop, dembow\nLatin pop, dembow hardcore\nLatin pop, dembow, Arabic fusion\nLatin pop, dembow, ambient\nLatin pop, dembow, cinematic\nLatin pop, dembow, electronic\nLatin pop, dembow, emotional\nLatin pop, dembow, flamenco\nLatin pop, dembow, lo-fi\nLatin pop, dembow, psychedelic\nLatin pop, dembow, reggaeton\nLatin pop, dembow, trap\nLatin pop, disco\nLatin pop, disco, novelty\nLatin pop, disco, retro\nLatin pop, disco, theatrical\nLatin pop, dream pop\nLatin pop, dream pop, lo-fi electronic\nLatin pop, dream pop, trap\nLatin pop, dream pop, trip-hop\nLatin pop, dreamy synth-pop\nLatin pop, drum and bass\nLatin pop, early 2000s R&B\nLatin pop, early 90s house\nLatin pop, electro house\nLatin pop, electro-house\nLatin pop, electronic\nLatin pop, electronic R&B, contemporary Christian\nLatin pop, electronic dance\nLatin pop, electronic dance, cinematic\nLatin pop, electronic dance, flamenco fusion\nLatin pop, electronic dance, reggaeton\nLatin pop, electronic dance, worldbeat\nLatin pop, electronic pop\nLatin pop, electronic, a cappella\nLatin pop, electronic, cinematic\nLatin pop, electronic, cumbia\nLatin pop, electronic, flamenco\nLatin pop, electronic, moody pop\nLatin pop, electronic, world fusion\nLatin pop, emo rap, trap\nLatin pop, emo-rap, trap\nLatin pop, emotional trap\nLatin pop, exotica, mambo\nLatin pop, exotica, theatrical\nLatin pop, experimental, pop-rock\nLatin pop, festive, chiptune\nLatin pop, festive, cinematic\nLatin pop, festive, salsa\nLatin pop, flamenco\nLatin pop, flamenco fusion\nLatin pop, flamenco fusion, reggaeton\nLatin pop, flamenco pop\nLatin pop, flamenco rock\nLatin pop, flamenco, Arabic pop\nLatin pop, flamenco, C-pop\nLatin pop, flamenco, Christian worship\nLatin pop, flamenco, Italian singer-songwriter\nLatin pop, flamenco, Latin rock\nLatin pop, flamenco, Tamil pop\nLatin pop, flamenco, ambient\nLatin pop, flamenco, ballad\nLatin pop, flamenco, bolero\nLatin pop, flamenco, cinematic\nLatin pop, flamenco, cinematic pop\nLatin pop, flamenco, copla\nLatin pop, flamenco, dance\nLatin pop, flamenco, electronic\nLatin pop, flamenco, electronic dance\nLatin pop, flamenco, hip-hop\nLatin pop, flamenco, melancholic ballad\nLatin pop, flamenco, pop ballad\nLatin pop, flamenco, pop-rock\nLatin pop, flamenco, reggaeton\nLatin pop, flamenco, rumba\nLatin pop, flamenco, synth-pop\nLatin pop, flamenco, synthwave\nLatin pop, flamenco, tango\nLatin pop, flamenco, theatrical\nLatin pop, flamenco, trap\nLatin pop, flamenco, urban\nLatin pop, folk fusion\nLatin pop, folk pop\nLatin pop, funk rock\nLatin pop, funk, R&B\nLatin pop, funk, children's music\nLatin pop, funk, chiptune\nLatin pop, funk, cinematic\nLatin pop, funk, disco\nLatin pop, funk, hip-hop\nLatin pop, funk, neo-soul\nLatin pop, funk, reggaeton\nLatin pop, funk, rock\nLatin pop, funk-pop\nLatin pop, future bass\nLatin pop, future bass, blues\nLatin pop, future bass, chiptune\nLatin pop, future bass, hyperpop\nLatin pop, future bass, trap\nLatin pop, futuristic\nLatin pop, futuristic, cybernetic\nLatin pop, futuristic, electronic\nLatin pop, futuristic, hyperpop\nLatin pop, futuristic, synthwave\nLatin pop, garage rock\nLatin pop, glitch, reggaeton\nLatin pop, gospel\nLatin pop, gospel pop, children's music\nLatin pop, gospel, 80s pop\nLatin pop, gospel, Christian contemporary\nLatin pop, gospel, R&B\nLatin pop, gospel, ballad\nLatin pop, gospel, chiptune\nLatin pop, gospel, cinematic\nLatin pop, gospel, contemporary Christian\nLatin pop, gospel, cumbia\nLatin pop, gospel, dance\nLatin pop, gospel, disco-funk\nLatin pop, gospel, festive\nLatin pop, gospel, hip-hop\nLatin pop, gospel, pop-rock\nLatin pop, gospel, reggae-dancehall\nLatin pop, gospel, reggaeton\nLatin pop, gospel, retro\nLatin pop, gospel, salsa\nLatin pop, gospel, soul\nLatin pop, gospel, theatrical\nLatin pop, gospel, ukulele\nLatin pop, gospel-pop, salsa\nLatin pop, hard rock\nLatin pop, hardstyle\nLatin pop, hardstyle, big room house\nLatin pop, hardstyle, cinematic\nLatin pop, hardstyle, hip-hop\nLatin pop, hardstyle, trap\nLatin pop, hip hop, R&B\nLatin pop, hip hop, chiptune\nLatin pop, hip hop, club\nLatin pop, hip-hop\nLatin pop, hip-hop, R&B\nLatin pop, hip-hop, ballad\nLatin pop, hip-hop, breakbeat\nLatin pop, hip-hop, cinematic\nLatin pop, hip-hop, flamenco\nLatin pop, hip-hop, funk\nLatin pop, hip-hop, melancholic\nLatin pop, hip-hop, reggaeton\nLatin pop, hip-hop, regional Mexican\nLatin pop, house\nLatin pop, house, reggaeton\nLatin pop, hyperpop\nLatin pop, hyperpop, Eurodance\nLatin pop, hyperpop, electronic dance\nLatin pop, hyperpop, reggaeton\nLatin pop, hyperpop, trap\nLatin pop, indie pop, exotica\nLatin pop, indie rock, hip-hop\nLatin pop, jazz ballad\nLatin pop, jazz ballad, rock\nLatin pop, jazz fusion\nLatin pop, jazz, bolero\nLatin pop, jazz, bossa nova\nLatin pop, jazz, lounge\nLatin pop, jazz, orchestral\nLatin pop, jazz, soul\nLatin pop, jazz, tango\nLatin pop, liquid drum and bass\nLatin pop, lo-fi hip hop\nLatin pop, lo-fi hip hop, jazz\nLatin pop, lo-fi hip hop, trap\nLatin pop, lo-fi hip-hop\nLatin pop, lo-fi hip-hop, romantic R&B\nLatin pop, lo-fi synth, worldbeat\nLatin pop, lo-fi, C-pop\nLatin pop, lo-fi, cinematic\nLatin pop, lo-fi, dance\nLatin pop, lo-fi, electronic\nLatin pop, lo-fi, emotional\nLatin pop, lo-fi, reggaeton\nLatin pop, lo-fi, synthwave\nLatin pop, lo-fi, vaporwave\nLatin pop, mambo, bolero\nLatin pop, mambo, hip-hop\nLatin pop, mambo, theatrical\nLatin pop, mariachi\nLatin pop, mariachi, cinematic\nLatin pop, merengue\nLatin pop, merengue, reggaeton\nLatin pop, merengue, salsa\nLatin pop, modern trap\nLatin pop, moombahton\nLatin pop, moombahton, EDM\nLatin pop, moombahton, R&B\nLatin pop, moombahton, hyperpop\nLatin pop, moombahton, reggaeton\nLatin pop, musical theater\nLatin pop, neo-soul, R&B\nLatin pop, neo-soul, acid jazz\nLatin pop, neo-soul, funk\nLatin pop, neo-soul, jazz\nLatin pop, neo-soul, jazz fusion\nLatin pop, neo-soul, lo-fi hip-hop\nLatin pop, new age\nLatin pop, new jack swing\nLatin pop, new jack swing, chiptune\nLatin pop, new jack swing, funk\nLatin pop, new wave, rock en español\nLatin pop, novelty dance\nLatin pop, novelty, dance\nLatin pop, novelty, flamenco\nLatin pop, novelty, mambo\nLatin pop, nu-disco, funk\nLatin pop, nu-disco, house\nLatin pop, nu-metal, electronicore\nLatin pop, orchestral\nLatin pop, orchestral, bolero\nLatin pop, orchestral, cumbia\nLatin pop, orchestral, flamenco\nLatin pop, orchestral, jazz\nLatin pop, orchestral, reggaeton\nLatin pop, piano ballad\nLatin pop, pop-punk, hard rock\nLatin pop, pop-rock\nLatin pop, pop-rock, cinematic\nLatin pop, pop-rock, cumbia\nLatin pop, pop-rock, dance-pop\nLatin pop, pop-rock, hip-hop\nLatin pop, pop-rock, post-rock\nLatin pop, pop-rock, power ballad\nLatin pop, pop-rock, reggaeton\nLatin pop, pop-rock, rock\nLatin pop, pop-rock, soul\nLatin pop, pop-rock, theatrical pop, ballad\nLatin pop, power ballad\nLatin pop, power ballad, Chinese ambient\nLatin pop, power ballad, cinematic\nLatin pop, power ballad, cumbia\nLatin pop, power ballad, hard rock\nLatin pop, power ballad, pop-rock\nLatin pop, power ballad, rock\nLatin pop, power metal\nLatin pop, praise and worship, synth pop\nLatin pop, progressive house\nLatin pop, progressive house, reggaeton\nLatin pop, punk rock\nLatin pop, ranchera\nLatin pop, reggae, children's music\nLatin pop, reggae, conscious hip-hop\nLatin pop, reggae, cumbia\nLatin pop, reggae, dancehall\nLatin pop, reggae, dub\nLatin pop, reggae, retro pop\nLatin pop, reggae, ska\nLatin pop, reggae, tropical\nLatin pop, reggaeton\nLatin pop, reggaeton, 90s retro\nLatin pop, reggaeton, Afro-Caribbean\nLatin pop, reggaeton, Afrobeat\nLatin pop, reggaeton, Arabic fusion\nLatin pop, reggaeton, Arabic pop\nLatin pop, reggaeton, Arabic scale\nLatin pop, reggaeton, Balkan\nLatin pop, reggaeton, Balkan fusion\nLatin pop, reggaeton, Brazilian funk\nLatin pop, reggaeton, Caribbean\nLatin pop, reggaeton, Christian\nLatin pop, reggaeton, Christian contemporary\nLatin pop, reggaeton, Christian hip-hop\nLatin pop, reggaeton, Christian music\nLatin pop, reggaeton, Christian worship\nLatin pop, reggaeton, Christmas\nLatin pop, reggaeton, EDM\nLatin pop, reggaeton, Eurodance\nLatin pop, reggaeton, French rap\nLatin pop, reggaeton, Italian pop\nLatin pop, reggaeton, Latin house\nLatin pop, reggaeton, Latin trap\nLatin pop, reggaeton, Mandarin pop\nLatin pop, reggaeton, Manele\nLatin pop, reggaeton, Middle Eastern dance\nLatin pop, reggaeton, Middle Eastern fusion\nLatin pop, reggaeton, Mizrahi\nLatin pop, reggaeton, R&B\nLatin pop, reggaeton, acoustic\nLatin pop, reggaeton, afrobeat\nLatin pop, reggaeton, afrobeats\nLatin pop, reggaeton, ambient\nLatin pop, reggaeton, atmospheric\nLatin pop, reggaeton, bachata\nLatin pop, reggaeton, ballad\nLatin pop, reggaeton, blues\nLatin pop, reggaeton, brass\nLatin pop, reggaeton, children's Christian\nLatin pop, reggaeton, children's music\nLatin pop, reggaeton, chiptune\nLatin pop, reggaeton, cinematic\nLatin pop, reggaeton, contemporary Christian\nLatin pop, reggaeton, cosmic\nLatin pop, reggaeton, cumbia\nLatin pop, reggaeton, cumbia-pop\nLatin pop, reggaeton, cyberpunk\nLatin pop, reggaeton, dance-pop\nLatin pop, reggaeton, dancehall\nLatin pop, reggaeton, deep house\nLatin pop, reggaeton, dembow\nLatin pop, reggaeton, dream pop\nLatin pop, reggaeton, dreamy\nLatin pop, reggaeton, dreamy synth\nLatin pop, reggaeton, early 2000s\nLatin pop, reggaeton, electronic\nLatin pop, reggaeton, electronic dance\nLatin pop, reggaeton, electropop\nLatin pop, reggaeton, experimental\nLatin pop, reggaeton, fantasy\nLatin pop, reggaeton, festive\nLatin pop, reggaeton, flamenco\nLatin pop, reggaeton, flamenco fusion\nLatin pop, reggaeton, flamenco pop\nLatin pop, reggaeton, funk\nLatin pop, reggaeton, funk carioca\nLatin pop, reggaeton, fusion\nLatin pop, reggaeton, future bass\nLatin pop, reggaeton, futuristic\nLatin pop, reggaeton, glitch\nLatin pop, reggaeton, gospel\nLatin pop, reggaeton, hardstyle\nLatin pop, reggaeton, hip-hop\nLatin pop, reggaeton, hyper-pop\nLatin pop, reggaeton, hyperpop\nLatin pop, reggaeton, jazzy\nLatin pop, reggaeton, lo-fi\nLatin pop, reggaeton, lo-fi hip hop\nLatin pop, reggaeton, mariachi\nLatin pop, reggaeton, melancholic\nLatin pop, reggaeton, melancholic piano\nLatin pop, reggaeton, merengue\nLatin pop, reggaeton, moody electronic\nLatin pop, reggaeton, moombahton\nLatin pop, reggaeton, multilingual rap\nLatin pop, reggaeton, pop\nLatin pop, reggaeton, pop-rock\nLatin pop, reggaeton, regional Mexican\nLatin pop, reggaeton, retro\nLatin pop, reggaeton, rock\nLatin pop, reggaeton, salsa\nLatin pop, reggaeton, shoegaze\nLatin pop, reggaeton, spiritual ambient\nLatin pop, reggaeton, synth pop\nLatin pop, reggaeton, synth-pop\nLatin pop, reggaeton, synthwave\nLatin pop, reggaeton, tango\nLatin pop, reggaeton, techno\nLatin pop, reggaeton, trap\nLatin pop, reggaeton, trap-pop\nLatin pop, reggaeton, tropical house\nLatin pop, reggaeton, ukulele\nLatin pop, reggaeton, urban\nLatin pop, reggaeton, urban pop\nLatin pop, reggaeton, vallenato\nLatin pop, reggaeton, vaporwave\nLatin pop, reggaeton, world music\nLatin pop, reggaeton-lite\nLatin pop, reggaeton-lite, chiptune\nLatin pop, regional Mexican\nLatin pop, regional Mexican, ballad\nLatin pop, regional Mexican, cumbia\nLatin pop, regional Mexican, lo-fi\nLatin pop, regional Mexican, synth pop\nLatin pop, retro doo-wop\nLatin pop, retro synth\nLatin pop, retro synth, cinematic\nLatin pop, retro synth, video game music\nLatin pop, retro video game\nLatin pop, retro wave\nLatin pop, retro, 80s\nLatin pop, retro, bolero\nLatin pop, retro, chiptune\nLatin pop, retro, cumbia\nLatin pop, retro, freestyle\nLatin pop, retro, funk\nLatin pop, retro, lo-fi\nLatin pop, retro, synth\nLatin pop, retro, synth funk\nLatin pop, retro, theatrical\nLatin pop, retro-funk, disco\nLatin pop, rock\nLatin pop, rock ballad, salsa\nLatin pop, rock, ballad\nLatin pop, rock, synth-pop\nLatin pop, rockabilly, novelty\nLatin pop, rockabilly, vintage\nLatin pop, romantic reggaeton\nLatin pop, sad reggaeton\nLatin pop, sad trap\nLatin pop, salsa\nLatin pop, salsa, Arabic fusion\nLatin pop, salsa, Christian\nLatin pop, salsa, ambient\nLatin pop, salsa, ballad\nLatin pop, salsa, big band\nLatin pop, salsa, children's music\nLatin pop, salsa, cinematic\nLatin pop, salsa, dancehall\nLatin pop, salsa, flamenco\nLatin pop, salsa, hip-hop\nLatin pop, salsa, merengue\nLatin pop, salsa, power ballad\nLatin pop, salsa, reggaeton\nLatin pop, salsa, tropical house\nLatin pop, salsa, urban\nLatin pop, samba, children's music\nLatin pop, samba-reggae, Brazilian funk\nLatin pop, show tune, salsa\nLatin pop, ska, children's music\nLatin pop, ska, reggae\nLatin pop, ska, upbeat\nLatin pop, ska-pop\nLatin pop, slap house\nLatin pop, smooth jazz\nLatin pop, smooth jazz, Christian contemporary\nLatin pop, smooth jazz, R&B\nLatin pop, smooth jazz, adult contemporary\nLatin pop, smooth jazz, bossa nova\nLatin pop, smooth jazz, fusion\nLatin pop, smooth jazz, world fusion\nLatin pop, smooth rock\nLatin pop, soft rock\nLatin pop, soft rock, dreamy\nLatin pop, soft rock, hard rock\nLatin pop, soulful R&B\nLatin pop, stadium rock\nLatin pop, symphonic rock\nLatin pop, synth-pop\nLatin pop, synth-pop, 80s\nLatin pop, synth-pop, Christian contemporary\nLatin pop, synth-pop, Eurodance\nLatin pop, synth-pop, Italo-disco\nLatin pop, synth-pop, chiptune\nLatin pop, synth-pop, city pop\nLatin pop, synth-pop, dance\nLatin pop, synth-pop, dance-pop\nLatin pop, synth-pop, funk\nLatin pop, synth-pop, hip-hop\nLatin pop, synth-pop, new wave\nLatin pop, synth-pop, reggaeton\nLatin pop, synth-pop, rock\nLatin pop, synth-pop, synthwave\nLatin pop, synthwave\nLatin pop, tango, ballad\nLatin pop, tango, bolero\nLatin pop, tango, cinematic\nLatin pop, tango, dramatic ballad\nLatin pop, tango, flamenco\nLatin pop, tango, regional Mexican\nLatin pop, theatrical\nLatin pop, theatrical folk\nLatin pop, theatrical pop\nLatin pop, theatrical pop, cinematic pop\nLatin pop, theatrical pop, pop-rock\nLatin pop, theatrical pop, reggaeton\nLatin pop, theatrical, big band\nLatin pop, theatrical, chiptune\nLatin pop, theatrical, cinematic\nLatin pop, trap\nLatin pop, trap R&B\nLatin pop, trap, Christian\nLatin pop, trap, R&B\nLatin pop, trap, ambient\nLatin pop, trap, ballad\nLatin pop, trap, bilingual pop\nLatin pop, trap, chiptune\nLatin pop, trap, cinematic\nLatin pop, trap, dark pop\nLatin pop, trap, deep house\nLatin pop, trap, dreamy\nLatin pop, trap, emotional\nLatin pop, trap, emotional pop\nLatin pop, trap, flamenco\nLatin pop, trap, future bass\nLatin pop, trap, hyperpop\nLatin pop, trap, lo-fi hip hop\nLatin pop, trap, melancholic\nLatin pop, trap, melodic rap\nLatin pop, trap, modern\nLatin pop, trap, rap\nLatin pop, trap, reggaeton\nLatin pop, trap, synthwave\nLatin pop, trap, tropical\nLatin pop, trap, vaporwave\nLatin pop, trap-R&B\nLatin pop, trap-pop, R&B\nLatin pop, tribal, Bossa Nova\nLatin pop, trip-hop\nLatin pop, trip-hop, cinematic\nLatin pop, tropical house\nLatin pop, tropical house, worship\nLatin pop, tropical pop, K-pop\nLatin pop, urban R&B, cinematic\nLatin pop, vaporwave\nLatin pop, vaporwave, lo-fi\nLatin pop, vaporwave, reggaeton\nLatin pop, vaporwave, trap\nLatin pop, video game music\nLatin pop, vintage cumbia\nLatin pop, vintage cumbia, chanson\nLatin pop, vintage, theatrical\nLatin pop, world fusion\nLatin pop, world fusion, reggae\nLatin pop, world fusion, reggaeton\nLatin pop, world music\nLatin pop, world music, acoustic folk\nLatin pop, world music, anthemic\nLatin pop, world music, big band\nLatin pop, world music, cinematic\nLatin pop, world music, dance-pop\nLatin pop, world music, dembow\nLatin pop, world music, electronic\nLatin pop, world music, emotional pop\nLatin pop, world music, festive\nLatin pop, world music, flamenco\nLatin pop, world music, pop-rock\nLatin pop, world music, reggaeton\nLatin pop, world music, video game soundtrack\nLatin pop, worldbeat\nLatin pop, worldbeat, electronic dance\nLatin pop, worldbeat, soul\nLatin pop, worldbeat, upbeat pop\nLatin pop, worldbeat, zouk\nLatin pop, worship\nLatin pop, worship, ballad\nLatin pop, worship, power ballad\nLatin pop, worship, salsa\nLatin pop-dance\nLatin pop-folk\nLatin pop-folk, ballad, R&B\nLatin pop-funk\nLatin pop-gospel\nLatin pop-punk\nLatin pop-rap\nLatin pop-rap chiptune\nLatin pop-rap, chiptune, dream-pop\nLatin pop-rap, nu-metal, reggaeton\nLatin pop-reggae\nLatin pop-reggaeton, Christian rock\nLatin pop-rock\nLatin pop-rock Christian rock\nLatin pop-rock chiptune\nLatin pop-rock cumbia\nLatin pop-rock flamenco\nLatin pop-rock funk\nLatin pop-rock future bass\nLatin pop-rock gospel\nLatin pop-rock norteño\nLatin pop-rock reggae\nLatin pop-rock salsa\nLatin pop-rock tango\nLatin pop-rock worship\nLatin pop-rock, Balkan dance\nLatin pop-rock, Christian contemporary\nLatin pop-rock, Christian rock\nLatin pop-rock, Christian worship, salsa\nLatin pop-rock, EDM, big room house\nLatin pop-rock, Eurodance\nLatin pop-rock, Eurodance, trance\nLatin pop-rock, J-pop\nLatin pop-rock, Mediterranean\nLatin pop-rock, Middle Eastern dance\nLatin pop-rock, cinematic orchestral\nLatin pop-rock, cinematic, emo-pop\nLatin pop-rock, cinematic, folk ballad\nLatin pop-rock, cinematic, theatrical\nLatin pop-rock, cumbia\nLatin pop-rock, dance-pop\nLatin pop-rock, electronic rock\nLatin pop-rock, hard rock\nLatin pop-rock, hard rock, boogie-rock\nLatin pop-rock, hard rock, cumbia\nLatin pop-rock, hardstyle\nLatin pop-rock, industrial rock\nLatin pop-rock, moombahton, cinematic\nLatin pop-rock, pop-punk, J-rock\nLatin pop-rock, pop-punk, melodic metalcore\nLatin pop-rock, power metal, folk\nLatin pop-rock, progressive house\nLatin pop-rock, salsa\nLatin pop-rock, salsa, disco-pop\nLatin pop-rock, salsa, funk soul\nLatin pop-rock, salsa, hip-hop\nLatin pop-rock, salsa, soul\nLatin pop-trap\nLatin power ballad\nLatin power ballad cumbia\nLatin power ballad merengue\nLatin power ballad, salsa\nLatin praise\nLatin praise and worship\nLatin praise cumbia\nLatin progressive house\nLatin protest\nLatin protest cumbia\nLatin protest rap\nLatin protest rock\nLatin protest, cumbia, reggaeton\nLatin protest, cumbia-reggae, conscious hip-hop\nLatin protest, hip-hop, rock\nLatin psychedelic rock\nLatin punk\nLatin punk cumbia\nLatin punk rock\nLatin ragtime\nLatin rap\nLatin rap chiptune\nLatin rap, boom-bap, R&B\nLatin rap, boom-bap, chiptune\nLatin rap, dembow\nLatin rap, dembow, house\nLatin rap, trap\nLatin rap-rock\nLatin rave\nLatin rave, Eurodance\nLatin reggae\nLatin reggae cumbia\nLatin reggae funk\nLatin reggae fusion\nLatin reggae gospel\nLatin reggae hip-hop\nLatin reggae ska\nLatin reggae-pop\nLatin reggae-rock\nLatin reggaeton\nLatin rhythm\nLatin rock\nLatin rock Afro-Caribbean\nLatin rock Afro-Cuban salsa\nLatin rock Balkan pop-rock\nLatin rock J-pop\nLatin rock Kayōkyoku\nLatin rock alternative rock\nLatin rock ballad\nLatin rock banda\nLatin rock blues\nLatin rock blues fusion\nLatin rock blues rock\nLatin rock blues-rock\nLatin rock bolero\nLatin rock boogaloo\nLatin rock boogie-woogie\nLatin rock bossa nova\nLatin rock cabaret\nLatin rock cha-cha-chá\nLatin rock chiptune\nLatin rock country\nLatin rock country-rock\nLatin rock cumbia\nLatin rock cumbia folk\nLatin rock cumbia norteño\nLatin rock cumbia psychedelic\nLatin rock cumbia ranchera\nLatin rock cumbia rock\nLatin rock cumbia ska\nLatin rock cumbia theatrical\nLatin rock cumbia vintage\nLatin rock cumbia-rock\nLatin rock cumbia-ska\nLatin rock doo-wop\nLatin rock flamenco\nLatin rock flamenco fusion\nLatin rock folk\nLatin rock folk-punk\nLatin rock folk-punk emo-rap\nLatin rock folk-rock\nLatin rock free-jazz\nLatin rock funk\nLatin rock funk blues\nLatin rock funk hip-hop\nLatin rock funk jazz fusion\nLatin rock funk pop\nLatin rock funk reggae\nLatin rock funk rock\nLatin rock funk salsa\nLatin rock funk ska\nLatin rock funk soul\nLatin rock funk surf rock\nLatin rock funk-rock\nLatin rock fusion\nLatin rock garage rock\nLatin rock gospel\nLatin rock gypsy punk\nLatin rock hard rock\nLatin rock hip-hop\nLatin rock indie pop\nLatin rock indie rock\nLatin rock jazz fusion\nLatin rock jazz-funk\nLatin rock jazz-fusion\nLatin rock jazz-rock\nLatin rock joropo\nLatin rock mariachi\nLatin rock norteño\nLatin rock norteño blues rock\nLatin rock norteño corrido\nLatin rock norteño cumbia\nLatin rock norteño ska\nLatin rock opera\nLatin rock post-punk\nLatin rock power pop\nLatin rock progressive acoustic\nLatin rock progressive metal\nLatin rock progressive rock\nLatin rock psychedelic\nLatin rock punk\nLatin rock punk rock\nLatin rock ranchera\nLatin rock rap-rock\nLatin rock reggae\nLatin rock reggae fusion\nLatin rock reggae hip-hop\nLatin rock reggaeton\nLatin rock rockabilly\nLatin rock rumba\nLatin rock salsa\nLatin rock salsa dura\nLatin rock salsa fusion\nLatin rock ska\nLatin rock ska cumbia\nLatin rock ska fusion\nLatin rock ska new wave\nLatin rock ska norteño\nLatin rock ska punk\nLatin rock ska reggae\nLatin rock ska rockabilly\nLatin rock ska surf rock\nLatin rock ska-punk\nLatin rock surf rock\nLatin rock surf-rock\nLatin rock tango\nLatin rock tango cabaret\nLatin rock tango folk\nLatin rock trip-hop\nLatin rock world music\nLatin rock worship\nLatin rock, 80s new wave\nLatin rock, Afro-Cuban, flamenco\nLatin rock, Americana\nLatin rock, Americana, country\nLatin rock, Andean folk\nLatin rock, Arabic fusion, cinematic rock\nLatin rock, Arabic world music\nLatin rock, Balkan brass\nLatin rock, Balkan folk\nLatin rock, Balkan fusion, theatrical rock\nLatin rock, Brazilian party\nLatin rock, C-pop\nLatin rock, EDM, big room house\nLatin rock, East Asian fusion\nLatin rock, Eurodance\nLatin rock, Indian folk\nLatin rock, J-rock\nLatin rock, K-rock\nLatin rock, Latin pop, alternative rock, punk rock\nLatin rock, MPB\nLatin rock, Mediterranean folk\nLatin rock, Middle Eastern folk\nLatin rock, Middle Eastern fusion\nLatin rock, Middle Eastern pop\nLatin rock, Norteño\nLatin rock, North African pop\nLatin rock, alternative metal\nLatin rock, big band\nLatin rock, big band jazz\nLatin rock, big band mambo\nLatin rock, big band swing\nLatin rock, big band, rockabilly\nLatin rock, big band, world music\nLatin rock, bolero, melancholic\nLatin rock, boogie-woogie\nLatin rock, boogie-woogie, brass rock\nLatin rock, boogie-woogie, rockabilly\nLatin rock, cinematic\nLatin rock, cinematic orchestral\nLatin rock, cinematic, psychedelic\nLatin rock, classic rock, soul\nLatin rock, cumbia\nLatin rock, cumbia rock\nLatin rock, cumbia villera\nLatin rock, cumbia, carnival\nLatin rock, cumbia, world music\nLatin rock, cumbia-rock\nLatin rock, doo-wop\nLatin rock, electronic\nLatin rock, flamenco, Brazilian groove\nLatin rock, flamenco, progressive rock\nLatin rock, funk, R&B\nLatin rock, garage rock, doo-wop\nLatin rock, garage rock, vintage\nLatin rock, gospel rock, folk rock\nLatin rock, gospel, operatic rock\nLatin rock, gospel, soul\nLatin rock, gypsy-punk\nLatin rock, hard rock\nLatin rock, hard rock, protest rock\nLatin rock, hard rock, punk rock\nLatin rock, heavy metal\nLatin rock, heavy metal, power metal\nLatin rock, hip hop, classical fusion\nLatin rock, hip-hop\nLatin rock, jazz fusion, cinematic\nLatin rock, jazz-funk, ska-punk\nLatin rock, mambo, big band\nLatin rock, mariachi, punk rock\nLatin rock, merengue\nLatin rock, metalcore\nLatin rock, pop-punk\nLatin rock, post-hardcore\nLatin rock, psychedelic funk\nLatin rock, psychedelic rock\nLatin rock, psychedelic rock, blues rock\nLatin rock, psychedelic, Javanese soul\nLatin rock, psychedelic, cinematic\nLatin rock, punk rock\nLatin rock, punk, flamenco\nLatin rock, punk, funk\nLatin rock, rap rock, nu-metal\nLatin rock, rap-metal\nLatin rock, rap-rock\nLatin rock, regional Mexican, acoustic ballad\nLatin rock, rockabilly, blues\nLatin rock, rockabilly, country\nLatin rock, rockabilly, surf rock\nLatin rock, rockabilly, swing\nLatin rock, ska\nLatin rock, ska, cartoon theme\nLatin rock, ska, children's music\nLatin rock, ska, festive\nLatin rock, ska, norteño\nLatin rock, ska, rock en español\nLatin rock, ska, swing\nLatin rock, ska, theatrical\nLatin rock, ska-punk\nLatin rock, ska-punk, danceable\nLatin rock, ska-punk, punk rock\nLatin rock, surf rock\nLatin rock, surf rock, high-energy\nLatin rock, surf rock, rock\nLatin rock, surf rock, rockabilly\nLatin rock, surf rock, vintage\nLatin rock, surf rock, vintage rock\nLatin rock, tango, rock en español\nLatin rock, traditional Mexican\nLatin rock, trip-hop\nLatin rock, video game music\nLatin rock, world music\nLatin rock, worship\nLatin rockabilly\nLatin romantic\nLatin romantic ballad\nLatin romantic waltz\nLatin rumba\nLatin rumba Mandopop\nLatin rumba flamenco\nLatin rumba punk\nLatin rumba salsa\nLatin rumba, Greek pop-rock\nLatin sad trap\nLatin salsa\nLatin salsa Arabic fusion\nLatin salsa Arabic pop\nLatin salsa chiptune\nLatin salsa gospel\nLatin salsa rock fusion\nLatin salsa, Arabic classical\nLatin salsa, French pop-rock\nLatin salsa, J-pop\nLatin salsa, Middle Eastern pop\nLatin salsa, South Indian Christian devotional, rock fusion\nLatin salsa, bolero, blues\nLatin salsa, cinematic orchestral\nLatin salsa, cinematic, ritualistic\nLatin salsa, operatic pop\nLatin salsa, retro video game\nLatin salsa, video game music\nLatin samba\nLatin serenade\nLatin show tune\nLatin singer-songwriter\nLatin ska\nLatin ska Balkan brass\nLatin ska banda\nLatin ska big band\nLatin ska cumbia\nLatin ska cumbia rock\nLatin ska funk\nLatin ska fusion\nLatin ska protest\nLatin ska protest rock\nLatin ska punk\nLatin ska reggae\nLatin ska rock\nLatin ska salsa\nLatin ska surf rock\nLatin ska, French hip-hop\nLatin ska, pop-rock, cinematic\nLatin ska-cumbia\nLatin ska-funk\nLatin ska-pop\nLatin ska-pop, folk ballad\nLatin ska-punk\nLatin ska-punk cumbia rock\nLatin ska-rap\nLatin ska-reggae\nLatin ska-rock\nLatin soft rock\nLatin son\nLatin son montuno\nLatin soul\nLatin soul ballad\nLatin soul boogaloo\nLatin soul funk\nLatin soul funk-rock\nLatin soul gospel\nLatin soul jazz-funk\nLatin soul reggae\nLatin soul rock\nLatin soul, big band\nLatin soul-rock\nLatin spiritual\nLatin spiritual pop\nLatin sports anthem\nLatin storytelling\nLatin street\nLatin street parade\nLatin street party\nLatin swing\nLatin swing rockabilly\nLatin swing-pop\nLatin synth-pop\nLatin synth-pop chiptune\nLatin tango\nLatin tango-rock\nLatin tech\nLatin tech house\nLatin tech house, Latin trap, reggaeton\nLatin tech-house\nLatin tech-trance\nLatin techno\nLatin theater\nLatin theatrical\nLatin trance\nLatin trap\nLatin trap Balkan hip-hop\nLatin trap Brazilian funk\nLatin trap Dutch hip-hop\nLatin trap R&B\nLatin trap UK drill\nLatin trap alternative R&B\nLatin trap ballad\nLatin trap chillwave\nLatin trap chiptune\nLatin trap cloud rap\nLatin trap cumbia\nLatin trap dancehall\nLatin trap dembow\nLatin trap drill\nLatin trap emo rap\nLatin trap emo trap\nLatin trap emo-rap\nLatin trap emo-trap\nLatin trap flamenco\nLatin trap lo-fi\nLatin trap lo-fi hip hop\nLatin trap pop\nLatin trap reggaeton\nLatin trap rock\nLatin trap salsa\nLatin trap soul\nLatin trap tango\nLatin trap vaporwave\nLatin trap, Afrobeat\nLatin trap, Balkan brass, reggaeton\nLatin trap, Brazilian funk\nLatin trap, Danish hip-hop\nLatin trap, Deutschrap\nLatin trap, Dutch hip-hop\nLatin trap, EDM, hardstyle\nLatin trap, East Asian hip-hop\nLatin trap, French cloud rap\nLatin trap, French hip-hop\nLatin trap, French rap\nLatin trap, German hip-hop\nLatin trap, Greek hip-hop\nLatin trap, Italian rap\nLatin trap, K-pop\nLatin trap, Mandarin hip-hop\nLatin trap, Mediterranean hip-hop\nLatin trap, R&B\nLatin trap, R&B, Latin pop\nLatin trap, R&B, cloud rap\nLatin trap, R&B, dream pop\nLatin trap, R&B, electronic\nLatin trap, R&B, hyperpop\nLatin trap, R&B, pop-punk\nLatin trap, Rai\nLatin trap, Rai, lo-fi\nLatin trap, Romanian hip-hop\nLatin trap, Russian rap, dark hip-hop\nLatin trap, UK drill\nLatin trap, alternative R&B\nLatin trap, ambient, melodic rap\nLatin trap, atmospheric R&B\nLatin trap, atmospheric R&B, vaporwave\nLatin trap, baile funk\nLatin trap, bilingual hip-hop\nLatin trap, boom-bap\nLatin trap, boom-bap hip-hop\nLatin trap, chiptune\nLatin trap, chiptune, electronic\nLatin trap, chiptune, hyperpop\nLatin trap, chiptune, reggaeton\nLatin trap, chiptune, sad trap\nLatin trap, chopped and screwed\nLatin trap, cinematic\nLatin trap, cinematic orchestral\nLatin trap, cinematic, Māori chant\nLatin trap, cinematic, flamenco\nLatin trap, cinematic, horrorcore\nLatin trap, cloud rap\nLatin trap, cloud rap, R&B\nLatin trap, cloud rap, chiptune\nLatin trap, cloud rap, pluggnb\nLatin trap, cloud rap, synth-pop\nLatin trap, cloud rap, vaporwave\nLatin trap, contemporary R&B\nLatin trap, cumbia, hyperpop\nLatin trap, dancehall\nLatin trap, dancehall, reggae\nLatin trap, dark R&B\nLatin trap, dark ambient\nLatin trap, dark pop\nLatin trap, dark synthwave\nLatin trap, deep house\nLatin trap, dembow\nLatin trap, dembow, hyperpop\nLatin trap, dream pop\nLatin trap, drill\nLatin trap, drill, Middle Eastern fusion\nLatin trap, drill, lo-fi hip hop\nLatin trap, drill, pluggnb\nLatin trap, electronic\nLatin trap, emo rap\nLatin trap, emo rap, lo-fi\nLatin trap, emo rap, sad pop\nLatin trap, emo rap, sad trap\nLatin trap, emo rap, synthwave\nLatin trap, emo trap\nLatin trap, emo-rap\nLatin trap, emotional R&B\nLatin trap, experimental electronic\nLatin trap, experimental pop\nLatin trap, flamenco R&B\nLatin trap, futuristic, boom-bap\nLatin trap, gospel, lo-fi hip hop\nLatin trap, gospel, psychedelic\nLatin trap, gospel, trap\nLatin trap, hardstyle\nLatin trap, hardstyle, drum and bass\nLatin trap, hardstyle, psytrance\nLatin trap, hip-hop\nLatin trap, hip-hop, C-pop\nLatin trap, hip-hop, hyperpop\nLatin trap, horrorcore\nLatin trap, hyper-trap\nLatin trap, hyperpop\nLatin trap, hyperpop, chiptune\nLatin trap, hyperpop, cinematic\nLatin trap, hyperpop, cloud rap\nLatin trap, hyperpop, lo-fi\nLatin trap, introspective hip-hop\nLatin trap, lo-fi hip hop\nLatin trap, lo-fi hip hop, chillwave\nLatin trap, lo-fi hip-hop\nLatin trap, lo-fi hip-hop, R&B\nLatin trap, lo-fi synth, chiptune\nLatin trap, lo-fi, chiptune\nLatin trap, lo-fi, hyperpop\nLatin trap, lo-fi, melodic rap\nLatin trap, lo-fi, vaporwave\nLatin trap, melancholic, hyperpop\nLatin trap, melodic R&B\nLatin trap, melodic R&B, ambient\nLatin trap, melodic cloud rap\nLatin trap, melodic hip-hop\nLatin trap, melodic rap\nLatin trap, melodic trap\nLatin trap, moody R&B\nLatin trap, moombahton\nLatin trap, multilingual hip-hop\nLatin trap, phonk\nLatin trap, pluggnb\nLatin trap, pluggnb, chiptune\nLatin trap, pop-R&B\nLatin trap, pop-rap\nLatin trap, rage trap\nLatin trap, rage trap, melodic trap\nLatin trap, rage, pluggnb\nLatin trap, reggaeton\nLatin trap, reggaeton, ambient\nLatin trap, reggaeton, boom-bap\nLatin trap, reggaeton, chiptune\nLatin trap, reggaeton, hip-hop\nLatin trap, reggaeton, lo-fi hip hop\nLatin trap, reggaeton, rock-infused\nLatin trap, regional Mexican\nLatin trap, sad hip-hop\nLatin trap, sad reggaeton\nLatin trap, sad reggaeton, ambient\nLatin trap, sad reggaeton, cinematic\nLatin trap, sad reggaeton, lo-fi\nLatin trap, sad trap\nLatin trap, sad trap, modern R&B\nLatin trap, slap house\nLatin trap, synth-pop, trance-pop\nLatin trap, techno\nLatin trap, vaporwave\nLatin trap, vaporwave, R&B\nLatin trap, vaporwave, cloud rap\nLatin trap, vaporwave, glitch\nLatin trap, vaporwave, hyperpop\nLatin trap, world fusion\nLatin trap, world music\nLatin trap-metal\nLatin trap-pop\nLatin trap-rock\nLatin trap-soul\nLatin tribal\nLatin trip-hop\nLatin urban\nLatin urban dembow\nLatin urban funk\nLatin urban fusion\nLatin urban pop\nLatin urban salsa\nLatin urban worship\nLatin urban, Balkan fusion\nLatin urban, Melbourne Bounce, electro house\nLatin urban, chiptune, reggaeton\nLatin urban, cinematic\nLatin urban, dembow, chiptune\nLatin urban, dembow, cumbia\nLatin urban, flamenco fusion, reggaeton\nLatin urban, gospel trap, R&B\nLatin urban, gospel, EDM\nLatin urban, reggaeton, ballad\nLatin urban, regional Mexican, cumbia\nLatin urban, tech house, ancient style\nLatin video game\nLatin video game music\nLatin vocal\nLatin vocal group\nLatin waltz\nLatin world\nLatin world music\nLatin worldbeat\nLatin worship\nLatin worship cumbia\nLatin worship salsa\nLatin, Afro-Caribbean\nLatin, Afro-Cuban, Mambo\nLatin, Afro-Cuban, brass\nLatin, Afro-Cuban, dance\nLatin, Afro-Cuban, festive\nLatin, Afro-Cuban, funk\nLatin, Afro-Cuban, house\nLatin, Afro-Cuban, montuno\nLatin, Afro-Cuban, parranda\nLatin, Afro-Cuban, theatrical\nLatin, Afro-Cuban, world music\nLatin, Afro-Latin, Cumbia\nLatin, Afro-Latin, festive\nLatin, Afro-Latin, montuno\nLatin, Afro-Latin, narrative groove\nLatin, Afro-Latin, party\nLatin, Afro-Latin, protest\nLatin, Afro-Latin, urban\nLatin, Afrobeat, house\nLatin, Afrobeat, world music\nLatin, Andean, festive\nLatin, Bossa Nova, acoustic guitar\nLatin, Brazilian, electronic dance\nLatin, Caribbean, Afro-Latin\nLatin, Caribbean, Zouk\nLatin, Cuban son, party music\nLatin, Cuban son, rumba\nLatin, Cumbia, Live Energy\nLatin, Eastern European, melancholic\nLatin, Fado\nLatin, Fado, folk\nLatin, Kizomba, world music\nLatin, Mediterranean, instrumental\nLatin, Middle Eastern, cinematic\nLatin, Salsa, Son Cubano\nLatin, accordion, festive\nLatin, accordion, vibrant rhythm\nLatin, acoustic, festive\nLatin, acoustic, rhythmic\nLatin, acoustic, rumba\nLatin, banda, cumbia\nLatin, banda, norteño\nLatin, big band, Cumbia\nLatin, bolero, festive\nLatin, bolero, flamenco\nLatin, bolero, ranchera\nLatin, boogie-woogie, corrido\nLatin, brass band, regional Mexican\nLatin, brass, dance\nLatin, brass, festive\nLatin, brass-driven, energetic\nLatin, cha-cha-chá\nLatin, cha-cha-chá, vintage\nLatin, cumbia\nLatin, cumbia, bachata\nLatin, cumbia, brass band\nLatin, cumbia, dance\nLatin, cumbia, festive\nLatin, cumbia, reggaeton\nLatin, cumbia, rumba\nLatin, cumbia, salsa\nLatin, cumbia, son\nLatin, cumbia, street music\nLatin, cumbia, street party\nLatin, cumbia-salsa\nLatin, dance, accordion\nLatin, festive\nLatin, festive, accordion\nLatin, festive, acoustic\nLatin, festive, brass-driven\nLatin, festive, choir\nLatin, festive, choral\nLatin, festive, cinematic\nLatin, festive, dance\nLatin, festive, harmonica\nLatin, festive, instrumental\nLatin, flamenco, Afro-Caribbean\nLatin, flamenco, acoustic\nLatin, flamenco, bolero\nLatin, flamenco, choir\nLatin, flamenco, copla\nLatin, flamenco, folk\nLatin, flamenco, mambo\nLatin, flamenco, party\nLatin, flamenco, rumba\nLatin, flamenco, upbeat\nLatin, flamenco, world music\nLatin, folk\nLatin, folk, dance\nLatin, funk, electronic\nLatin, funk, hip-hop\nLatin, funk, house\nLatin, funk, pop\nLatin, funk, world music\nLatin, house\nLatin, house, afrobeat\nLatin, instrumental, rumba\nLatin, live performance\nLatin, live, high-energy\nLatin, mambo\nLatin, mambo, cha-cha-chá\nLatin, mambo, festive\nLatin, mambo, salsa\nLatin, mambo, son montuno\nLatin, mambo, vintage\nLatin, mariachi, Balkan brass\nLatin, mariachi, theatrical\nLatin, merengue, bachata\nLatin, merengue, salsa\nLatin, pop, electronic\nLatin, ragtime, montuno\nLatin, reggaeton, Cuban son\nLatin, regional Mexican\nLatin, regional Mexican, brass band\nLatin, rumba\nLatin, rumba, Afro-Latin\nLatin, rumba, flamenco\nLatin, salsa\nLatin, salsa, Afro-Latin\nLatin, salsa, Cuban son\nLatin, salsa, brass\nLatin, salsa, brass-driven\nLatin, salsa, cumbia\nLatin, salsa, festive\nLatin, salsa, flamenco\nLatin, salsa, lo-fi\nLatin, salsa, mambo, rock and roll\nLatin, salsa, merengue, ballad\nLatin, salsa, worldbeat\nLatin, samba, bossa nova\nLatin, son cubano\nLatin, son cubano, mambo\nLatin, son montuno, festive\nLatin, son montuno, rumba\nLatin, son, rumba\nLatin, tango, salsa\nLatin, theatrical, acoustic\nLatin, theatrical, brass-driven\nLatin, theatrical, dramatic\nLatin, theatrical, explosive\nLatin, theatrical, mariachi\nLatin, theatrical, salsa\nLatin, tribal, world music\nLatin, tropical, upbeat\nLatin, vintage, organ\nLatin, world music\nLatin, world music, cinematic\nLatin, world music, cumbia\nLatin, world music, upbeat\nLatin-African fusion\nLatin-Asian fusion\nLatin-Europe fusion\nLatin-Indian fusion\nLatin-Japanese fusion\nLatin-Persian fusion\nLatin-acoustic, Indian pop-rock\nLatin-electro fusion\nLatin-folk\nLatin-folk cumbia-ska\nLatin-folk rock\nLatin-funk\nLatin-gospel\nLatin-influenced C-pop\nLatin-influenced acoustic\nLatin-influenced ambient\nLatin-infused\nLatin-infused German pop\nLatin-infused Mandopop\nLatin-infused electronic\nLatin-inspired\nLatin-inspired C-pop\nLatin-inspired acoustic\nLatin-inspired children's\nLatin-inspired children's music\nLatin-inspired choral\nLatin-inspired cumbia\nLatin-inspired, theatrical, choral\nLatin-jazz fusion\nLatin-pop\nLatin-pop Afrobeat\nLatin-pop Bossa Nova\nLatin-pop C-pop\nLatin-pop Christmas\nLatin-pop Eurodance\nLatin-pop Mandopop\nLatin-pop R&B\nLatin-pop bossa nova\nLatin-pop children's\nLatin-pop children's music\nLatin-pop children's pop\nLatin-pop funk\nLatin-pop hardstyle\nLatin-pop hip-hop\nLatin-pop novelty\nLatin-pop praise\nLatin-pop reggaeton\nLatin-pop rock\nLatin-pop salsa\nLatin-pop show tune\nLatin-pop tropical house\nLatin-pop world music\nLatin-pop worship\nLatin-pop, C-pop\nLatin-pop, Christian, retro\nLatin-pop, Dutch Christmas\nLatin-pop, Sinhala pop, dance-pop\nLatin-pop, Vietnamese folk\nLatin-pop, cumbia, Eurodance\nLatin-pop, drum and bass\nLatin-pop, future bass, hip hop\nLatin-pop, progressive house\nLatin-pop, synth-pop, chiptune\nLatin-rock\nLatin-rock fusion\nLatin-ska\nLatin-style theatrical\nLatin-tinged pop-rock\nLatin-trap\nLatin-trap fusion\nLatvian folk\nLatvian hip-hop\nLatvian schlager\nLatvian trap\nLaïko\nLaïko EDM\nLaïko Eurodance\nLaïko Greek folk\nLaïko Latin pop\nLaïko Manele chiptune\nLaïko Rebetiko\nLaïko chiptune\nLaïko chiptune rock\nLaïko dance-pop\nLaïko electronic\nLaïko funk\nLaïko funk-rock\nLaïko hip-hop\nLaïko jazz swing\nLaïko pop\nLaïko pop-rock\nLaïko rock\nLaïko surf rock\nLaïko world fusion\nLaïko, Balkan folk\nLaïko, Balkan folk, rock\nLaïko, Balkan pop\nLaïko, Balkan pop, dance-pop\nLaïko, Balkan pop-rock\nLaïko, Greek art music\nLaïko, Greek folk\nLaïko, Greek folk, oud\nLaïko, Greek folk, theatrical rock\nLaïko, Greek pop\nLaïko, Greek pop-rock\nLaïko, Latin pop\nLaïko, Latin, dance\nLaïko, Middle Eastern dance\nLaïko, Middle Eastern pop\nLaïko, Sirtaki\nLaïko, Sirtaki, Greek folk\nLaïko, art song\nLaïko, atmospheric, rock\nLaïko, big band, swing\nLaïko, choral, Greek\nLaïko, cinematic ballad\nLaïko, cinematic, Greek ballad\nLaïko, cinematic, Greek folk\nLaïko, cinematic, Greek pop\nLaïko, cinematic, ambient\nLaïko, cinematic, blues\nLaïko, cinematic, electronic\nLaïko, cinematic, orchestral\nLaïko, electronic dance\nLaïko, electronic, Balkan folk\nLaïko, electronic, Greek\nLaïko, electronic, dance\nLaïko, electronic, oud\nLaïko, folk rock\nLaïko, operatic, melancholic\nLaïko, orchestral folk-pop\nLaïko, orchestral, Greek traditional\nLaïko, surf-rock\nLaïko, synth-pop\nLaïko, synth-pop, Greek\nLaïko, tango, jazz\nLaïko, theatrical piano\nLaïko-pop\nLaïko-rock\nLiedermacher\nLithuanian R&B, hip-hop\nLithuanian drill\nLithuanian estrada\nLithuanian folk-pop\nLithuanian hip-hop\nLithuanian pop\nLithuanian pop Eurodance\nLithuanian trap\nLondon drill\nLuk Thung\nLuk Thung Mor Lam\nLuk Thung Rock\nLuk Thung blues-rock\nLuk Thung chiptune\nLuk Thung country\nLuk Thung country rock\nLuk Thung country-rock\nLuk Thung dance-pop\nLuk Thung disco-funk\nLuk Thung electronic\nLuk Thung folk-rock\nLuk Thung funk\nLuk Thung funk disco\nLuk Thung jazz\nLuk Thung metal\nLuk Thung orchestral\nLuk Thung pop\nLuk Thung pop-dance\nLuk Thung pop-rock\nLuk Thung psychedelic rock\nLuk Thung rock\nLuk Thung rock fusion\nLuk Thung rock ska\nLuk Thung rockabilly\nLuk Thung rockabilly surf rock\nLuk Thung ska-punk\nLuk Thung surf rock\nLuk Thung synth-pop\nLuk Thung, Chinese folk, rock\nLuk Thung, Chinese fusion\nLuk Thung, Eurodance\nLuk Thung, J-rock\nLuk Thung, Mor Lam\nLuk Thung, Mor Lam, Thai folk\nLuk Thung, Mor Lam, cinematic\nLuk Thung, Mor Lam, cinematic orchestral\nLuk Thung, R&B, hip-hop\nLuk Thung, Thai pop, dance\nLuk Thung, big band, cinematic\nLuk Thung, big band, patriotic\nLuk Thung, chiptune\nLuk Thung, chiptune rock\nLuk Thung, chiptune, lo-fi\nLuk Thung, chiptune, retro video game\nLuk Thung, chiptune, synth-pop\nLuk Thung, cinematic\nLuk Thung, cinematic orchestral\nLuk Thung, cinematic, orchestral pop\nLuk Thung, cinematic, traditional Thai\nLuk Thung, dance-pop\nLuk Thung, electronic fusion\nLuk Thung, electronic, cinematic\nLuk Thung, folk-pop, cinematic\nLuk Thung, orchestral pop\nLuk Thung, orchestral, cinematic\nLuk Thung, pop-rock, vintage Southeast Asian\nLuk Thung, pop-rock, vintage Thai\nLuk Thung, retro, synth pop\nLuk Thung, synth pop\nLuk Thung, synth-pop\nLuk Thung, vintage pop\nLuk Thung, vintage swing\nLuk thung\nLuk thung, Thai pop\nLusophone folk\nLusophone folk hip-hop\nLusophone funk\nLusophone pop\nLusophone pop reggae\nLăutărească\nM-Pop\nM-pop EDM dance-pop\nM-pop EDM future bass\nMIDI fanfare\nMIDI-pop\nMPB\nMPB Afro-Latin\nMPB Afrobeat\nMPB Afrobeat world music\nMPB Bossa Nova\nMPB Bossa Nova Axé\nMPB Bossa Nova R&B\nMPB Bossa Nova Samba\nMPB Bossa Nova Samba-Jazz\nMPB Bossa Nova cinematic\nMPB Bossa Nova jazz\nMPB Bossa Nova lounge jazz\nMPB Bossa Nova rock\nMPB Bossa Nova smooth jazz\nMPB Bossa Nova soul\nMPB Fado\nMPB Forró\nMPB Latin rock\nMPB R&B\nMPB R&B Kizomba\nMPB R&B funk\nMPB R&B fusion\nMPB R&B pop\nMPB R&B soul\nMPB Samba Bossa Nova\nMPB Samba-pop\nMPB Sertanejo\nMPB Sertanejo Axé\nMPB Sertanejo Romântico\nMPB Sertanejo cinematic\nMPB a cappella\nMPB acid jazz\nMPB acid jazz funk\nMPB acid jazz neo-soul\nMPB acid jazz trip-hop\nMPB acoustic\nMPB acoustic R&B\nMPB acoustic ballad\nMPB acoustic folk\nMPB acoustic folk-pop\nMPB acoustic gospel\nMPB acoustic hip-hop\nMPB acoustic pop\nMPB acoustic pop-rock\nMPB acoustic soul\nMPB adult contemporary\nMPB alternative rock\nMPB art song\nMPB art-pop\nMPB art-rock\nMPB ballad\nMPB baroque pop\nMPB big band\nMPB big band funk\nMPB big band jazz\nMPB blues\nMPB blues jazz\nMPB blues rock\nMPB blues rock jazz fusion\nMPB blues-rock\nMPB bolero\nMPB bolero cinematic\nMPB boogie\nMPB boogie-woogie\nMPB bossa nova\nMPB bossa nova cinematic\nMPB bossa nova cool jazz\nMPB bossa nova funk\nMPB bossa nova indie pop\nMPB bossa nova indie rock\nMPB bossa nova jazz\nMPB bossa nova lounge\nMPB bossa nova pop-rock\nMPB bossa nova psychedelic pop\nMPB bossa nova psychedelic rock\nMPB bossa nova samba\nMPB bossa nova samba-jazz\nMPB bossa nova samba-rock\nMPB bossa nova smooth jazz\nMPB bossa nova soft rock\nMPB bossa nova soul\nMPB brega\nMPB cabaret\nMPB cabaret jazz\nMPB cabaret samba\nMPB cabaret samba-jazz\nMPB cabaret tango\nMPB chamber\nMPB chamber folk\nMPB chamber pop\nMPB chanson\nMPB children's\nMPB chiptune\nMPB choro\nMPB cinematic\nMPB cinematic pop\nMPB cinematic psychedelic\nMPB city pop\nMPB city pop funk\nMPB city pop smooth jazz\nMPB classical\nMPB classical crossover\nMPB cool jazz bossa nova\nMPB country-rock\nMPB disco Latin\nMPB disco-funk\nMPB dream pop\nMPB dream pop psychedelic rock\nMPB dream pop smooth jazz\nMPB experimental\nMPB flamenco\nMPB flamenco classical\nMPB flamenco samba\nMPB folk\nMPB folk blues\nMPB folk-pop\nMPB folk-rock\nMPB for kids\nMPB forró\nMPB forró baião\nMPB funk\nMPB funk Latin\nMPB funk R&B\nMPB funk acid jazz\nMPB funk blues-rock\nMPB funk bossa nova\nMPB funk chiptune\nMPB funk disco\nMPB funk gospel\nMPB funk hip-hop\nMPB funk indie pop\nMPB funk indie rock\nMPB funk jazz\nMPB funk jazz fusion\nMPB funk neo-soul\nMPB funk pop-rock\nMPB funk psychedelic\nMPB funk psychedelic rock\nMPB funk psychedelic soul\nMPB funk reggae\nMPB funk rock\nMPB funk samba\nMPB funk samba-rock\nMPB funk soul\nMPB funk worldbeat\nMPB funk-pop\nMPB funk-rock\nMPB funk-rock jazz fusion\nMPB funk-rock samba-rock\nMPB garage rock\nMPB gospel\nMPB gospel big band\nMPB gospel reggae\nMPB gospel samba\nMPB gospel soft rock\nMPB gospel-pop\nMPB hip-hop\nMPB hip-hop fusion\nMPB indie folk\nMPB indie folk world music\nMPB indie pop\nMPB indie pop bossa nova\nMPB indie pop dream pop\nMPB indie pop funk\nMPB indie pop psychedelic rock\nMPB indie pop soul\nMPB indie rock\nMPB indie rock funk\nMPB indie rock psychedelic\nMPB indie rock surf rock\nMPB jazz\nMPB jazz Bossa Nova\nMPB jazz R&B\nMPB jazz ballad\nMPB jazz big band\nMPB jazz blues\nMPB jazz blues-rock\nMPB jazz bossa nova\nMPB jazz funk\nMPB jazz fusion\nMPB jazz fusion R&B\nMPB jazz fusion art rock\nMPB jazz fusion funk\nMPB jazz fusion samba\nMPB jazz fusion soul\nMPB jazz hip-hop\nMPB jazz lounge\nMPB jazz pop\nMPB jazz samba\nMPB jazz soft rock\nMPB jazz soul\nMPB jazz tango\nMPB jazz-funk\nMPB jazz-funk bossa nova\nMPB jazz-funk lounge\nMPB jazz-fusion\nMPB jazz-pop\nMPB jazz-rock\nMPB jazz-rock fusion\nMPB jazz-soul\nMPB lo-fi\nMPB lo-fi R&B\nMPB lo-fi hip hop\nMPB lo-fi hip-hop\nMPB lo-fi indie rock\nMPB lo-fi neo-soul\nMPB lo-fi pop\nMPB lo-fi vaporwave\nMPB lounge\nMPB lounge big band\nMPB lounge jazz\nMPB neo-soul\nMPB neo-soul R&B\nMPB neo-soul acid jazz\nMPB neo-soul bossa nova\nMPB neo-soul city pop\nMPB neo-soul dream pop\nMPB neo-soul funk\nMPB neo-soul indie rock\nMPB neo-soul jazz\nMPB neo-soul jazz fusion\nMPB neo-soul lo-fi\nMPB neo-soul lo-fi hip-hop\nMPB neo-soul pop-rock\nMPB noir-jazz\nMPB nu-disco\nMPB nu-disco city pop\nMPB orchestral\nMPB orchestral pop\nMPB pop\nMPB pop ballad\nMPB pop rock\nMPB pop-rock\nMPB post-rock\nMPB power ballad\nMPB psychedelic\nMPB psychedelic blues-rock\nMPB psychedelic bossa nova\nMPB psychedelic folk\nMPB psychedelic jazz\nMPB psychedelic pop\nMPB psychedelic rock\nMPB psychedelic soul\nMPB psychedelic surf rock\nMPB punk rock\nMPB reggae\nMPB reggae dub\nMPB reggae funk\nMPB reggae fusion\nMPB reggae jazz\nMPB reggae pop-rock\nMPB reggae psychedelic\nMPB reggae samba-reggae\nMPB reggae samba-rock\nMPB reggae ska\nMPB reggae soul\nMPB reggae-pop\nMPB rock\nMPB rock fusion\nMPB rock gospel\nMPB rock reggae\nMPB romantic\nMPB romantic orchestral\nMPB romantic pop\nMPB samba\nMPB samba Latin\nMPB samba Latin jazz\nMPB samba big band\nMPB samba bossa nova\nMPB samba choro\nMPB samba flamenco\nMPB samba forró\nMPB samba funk\nMPB samba jazz\nMPB samba pagode\nMPB samba pop-rock\nMPB samba ragtime\nMPB samba rock\nMPB samba salsa\nMPB samba soul\nMPB samba tango\nMPB samba-bossa nova\nMPB samba-jazz\nMPB samba-jazz bossa nova\nMPB samba-jazz funk\nMPB samba-pop\nMPB samba-reggae\nMPB samba-reggae Axé\nMPB samba-reggae gospel\nMPB samba-rock\nMPB samba-rock big band\nMPB samba-rock bossa nova\nMPB samba-rock cabaret\nMPB samba-rock funk\nMPB samba-rock jazz fusion\nMPB samba-rock pop-rock\nMPB samba-rock psychedelic\nMPB samba-rock reggae\nMPB samba-rock soul\nMPB sertanejo\nMPB sertanejo acoustic\nMPB smooth jazz\nMPB smooth jazz R&B\nMPB smooth jazz bossa nova\nMPB smooth jazz dream pop\nMPB smooth jazz gospel\nMPB smooth jazz soft rock\nMPB soft rock\nMPB soul\nMPB soul R&B\nMPB soul blues\nMPB soul blues-rock\nMPB soul funk\nMPB soul fusion\nMPB soul gospel\nMPB soul jazz\nMPB soul orchestral\nMPB soul pop-rock\nMPB soul psychedelic rock\nMPB soul rock\nMPB soul-blues\nMPB soul-funk\nMPB soul-jazz\nMPB soul-pop\nMPB soul-reggae\nMPB soul-rock\nMPB surf rock\nMPB surf rock indie\nMPB surf rock psychedelic\nMPB surf rock samba\nMPB surf-rock\nMPB synth-pop\nMPB tango\nMPB tango big band\nMPB tango cabaret\nMPB tango cinematic\nMPB tango psychedelic rock\nMPB tango samba\nMPB tango surf rock\nMPB trip-hop\nMPB trip-hop smooth jazz\nMPB vintage rock\nMPB world fusion\nMPB world music\nMPB, Afro-Brazilian, percussion\nMPB, Axé\nMPB, Axé, Samba-reggae\nMPB, Axé, samba-reggae\nMPB, Bossa Nova\nMPB, Bossa Nova, Brazilian pop\nMPB, Bossa Nova, Samba\nMPB, Bossa Nova, Samba Rock\nMPB, Bossa Nova, Samba-Jazz\nMPB, Bossa Nova, acoustic\nMPB, Bossa Nova, art rock\nMPB, Bossa Nova, cabaret\nMPB, Bossa Nova, chamber music\nMPB, Bossa Nova, chiptune\nMPB, Bossa Nova, cinematic\nMPB, Bossa Nova, cinematic orchestral\nMPB, Bossa Nova, cinematic pop\nMPB, Bossa Nova, cool jazz\nMPB, Bossa Nova, experimental\nMPB, Bossa Nova, gospel\nMPB, Bossa Nova, indie pop\nMPB, Bossa Nova, jazz\nMPB, Bossa Nova, lo-fi hip-hop\nMPB, Bossa Nova, lounge jazz\nMPB, Bossa Nova, melancholic ballad\nMPB, Bossa Nova, pop-rock\nMPB, Bossa Nova, smooth jazz\nMPB, Bossa Nova, soft rock\nMPB, Bossa Nova, spiritual\nMPB, Bossa Nova, vocal jazz\nMPB, Brazilian folk\nMPB, Brazilian folk, cinematic\nMPB, Brazilian folk, spiritual\nMPB, Brazilian pop, disco-funk\nMPB, Brazilian pop, world music\nMPB, Brazilian pop-rock\nMPB, Brazilian pop-rock, cinematic\nMPB, Brazilian rock\nMPB, Brega, romantic ballad\nMPB, Christmas, pop-rock\nMPB, European folk, acoustic\nMPB, Fado\nMPB, Fado, cinematic\nMPB, Fado, flamenco\nMPB, Fado, orchestral\nMPB, Forró\nMPB, Latin folk\nMPB, Latin folk, tango\nMPB, Latin jazz\nMPB, Latin pop, Brazilian ballad\nMPB, Latin, psychedelic folk\nMPB, R&B, Brazilian pop\nMPB, Samba\nMPB, Samba Romântico\nMPB, Samba Romântico, Brazilian pop\nMPB, Samba, Bossa Nova\nMPB, Samba, Brazilian\nMPB, Samba, Brazilian Christmas\nMPB, Samba, Brazilian pop\nMPB, Samba, Samba-Rock\nMPB, Samba, big band\nMPB, Samba-Jazz\nMPB, Samba-Pop\nMPB, Samba-rock\nMPB, Sertanejo\nMPB, Sertanejo Romântico\nMPB, Sertanejo de Raiz\nMPB, Sertanejo romântico\nMPB, Sertanejo, Brazilian pop\nMPB, Sertanejo, cinematic\nMPB, alternative rock\nMPB, ambient rock\nMPB, ambient, acoustic ballad\nMPB, art pop, cinematic\nMPB, art rock, free jazz\nMPB, art song\nMPB, art song, cabaret\nMPB, art-pop, Bossa Nova\nMPB, big band jazz\nMPB, big band jazz, psychedelic pop\nMPB, big band jazz, soul\nMPB, big band, samba\nMPB, blues rock\nMPB, blues-rock, samba-rock\nMPB, bolero, Brazilian romantic ballad\nMPB, bolero, cinematic\nMPB, bolero, orchestral\nMPB, bolero, romantic ballad\nMPB, boogie-funk\nMPB, bossa nova, lounge\nMPB, bossa nova, samba rock\nMPB, cabaret\nMPB, cabaret, cinematic\nMPB, cabaret, live piano\nMPB, cabaret, samba\nMPB, cabaret, samba-rock\nMPB, cabaret, tango\nMPB, cabaret, theatrical\nMPB, chamber pop, samba\nMPB, chanson\nMPB, chanson, baroque pop\nMPB, chiptune, Brazilian pop\nMPB, choral, musical theater\nMPB, cinematic ballad, jazz\nMPB, cinematic ballad, orchestral\nMPB, cinematic jazz\nMPB, cinematic orchestral\nMPB, cinematic pop\nMPB, cinematic rock\nMPB, cinematic, art song\nMPB, cinematic, bossa nova\nMPB, cinematic, choro\nMPB, cinematic, funk\nMPB, cinematic, gospel\nMPB, cinematic, jazz\nMPB, cinematic, musical theater\nMPB, cinematic, orchestral\nMPB, cinematic, rock\nMPB, cinematic, samba\nMPB, cinematic, samba-reggae\nMPB, cinematic, tango\nMPB, classical ballad\nMPB, classical chamber, art song\nMPB, classical crossover, world music\nMPB, classical, Brazilian folk\nMPB, classical, lo-fi\nMPB, conscious hip-hop\nMPB, conscious hip-hop, folk protest\nMPB, cumbia, Latin jazz\nMPB, devotional, ambient\nMPB, disco, Brazilian pop\nMPB, dream pop, rock\nMPB, dreamy, atmospheric\nMPB, flamenco, Brazilian popular music\nMPB, flamenco, cinematic\nMPB, flamenco, classical\nMPB, flamenco, rock\nMPB, flamenco, samba\nMPB, flamenco, tango\nMPB, folk, blues\nMPB, folk, live\nMPB, folk, theatrical\nMPB, folk-pop, conscious hip-hop\nMPB, folk-rock\nMPB, forró\nMPB, forró, Brazilian\nMPB, forró, Brazilian folk\nMPB, forró, Brazilian pop\nMPB, forró, cinematic folk\nMPB, forró, samba-rock\nMPB, free jazz\nMPB, free jazz, progressive rock\nMPB, gospel rock\nMPB, gospel, Brazilian folk\nMPB, gospel, cinematic\nMPB, gospel, funk\nMPB, gospel, pop-rock\nMPB, gospel, smooth jazz\nMPB, gospel-pop, cinematic\nMPB, hip-hop\nMPB, indie jazz\nMPB, indie pop, ambient\nMPB, indie pop, cinematic\nMPB, indie rock\nMPB, indie rock, Brazilian folk\nMPB, indie rock, electronic\nMPB, indie rock, funk\nMPB, jazz, cabaret\nMPB, jazz, cinematic\nMPB, jazz, samba\nMPB, jazz, samba-rock\nMPB, lo-fi hip hop, jazz\nMPB, lo-fi hip-hop, indie pop\nMPB, lo-fi, vaporwave\nMPB, neo-soul, lo-fi\nMPB, new age\nMPB, new age, spiritual pop\nMPB, noise rock\nMPB, nu-disco, Latin house\nMPB, orchestral, Bossa Nova\nMPB, orchestral, jazz\nMPB, orchestral, samba\nMPB, orchestral, samba-rock\nMPB, pop-R&B\nMPB, pop-punk, rockabilly\nMPB, pop-rock\nMPB, pop-rock, Brazilian folk\nMPB, pop-rock, ballad\nMPB, pop-rock, cinematic\nMPB, pop-rock, classic rock\nMPB, pop-rock, jazz\nMPB, pop-samba\nMPB, psychedelic folk\nMPB, psychedelic folk-rock\nMPB, psychedelic pop\nMPB, psychedelic rock\nMPB, psychedelic rock, Bossa Nova\nMPB, psychedelic rock, Brazilian pop\nMPB, psychedelic rock, flamenco\nMPB, psychedelic rock, jazz fusion\nMPB, psychedelic rock, ragtime\nMPB, psychedelic rock, samba-rock\nMPB, psychedelic rock, soul\nMPB, psychedelic, Brazilian folk\nMPB, psychedelic, samba-rock\nMPB, reggae, bossa nova\nMPB, samba\nMPB, samba rock\nMPB, samba, Brazilian\nMPB, samba, Brazilian pop\nMPB, samba, acoustic pop\nMPB, samba, art pop\nMPB, samba, big band\nMPB, samba, big band jazz\nMPB, samba, bluegrass\nMPB, samba, bossa nova\nMPB, samba, children's music\nMPB, samba, cinematic\nMPB, samba, indie\nMPB, samba, romantic pop\nMPB, samba, soul\nMPB, samba, spiritual\nMPB, samba, tango\nMPB, samba-jazz\nMPB, samba-jazz, live soul\nMPB, samba-jazz, psychedelic\nMPB, samba-reggae\nMPB, samba-reggae, Afro-Brazilian\nMPB, samba-rock\nMPB, samba-rock, Afro-Brazilian\nMPB, samba-rock, art-rock\nMPB, samba-rock, cabaret\nMPB, samba-rock, children's\nMPB, samba-rock, cinematic\nMPB, samba-rock, funk\nMPB, samba-rock, jazz fusion\nMPB, samba-rock, jazz-fusion\nMPB, samba-rock, psychedelic rock\nMPB, samba-rock, rock\nMPB, smooth jazz, Brazilian pop\nMPB, smooth jazz, funk rock\nMPB, soft rock\nMPB, soft rock, Brazilian ballad\nMPB, soft rock, Brazilian pop\nMPB, soft rock, cinematic\nMPB, soft rock, gospel\nMPB, soft rock, live rock\nMPB, soft rock, orchestral\nMPB, soft rock, smooth jazz\nMPB, soul, Brazilian pop\nMPB, soul, ballad\nMPB, soul, romantic pop\nMPB, spiritual ballad\nMPB, surf rock\nMPB, surf rock, blues rock\nMPB, surf rock, retro\nMPB, synth-pop\nMPB, synth-pop, cinematic\nMPB, tango\nMPB, tango folk\nMPB, tango, Brazilian\nMPB, tango, Brazilian folk\nMPB, tango, Brazilian pop\nMPB, tango, Latin\nMPB, tango, ballad\nMPB, tango, cinematic\nMPB, tango, live performance\nMPB, tango, orchestral\nMPB, theatrical bolero\nMPB, theatrical, satirical\nMPB, world fusion\nMPB, world music, Brazilian folk\nMPB, world music, flamenco\nMPB, world music, new age\nMPB-pop\nMPB-rock\nMahraganat\nMahraganat electro-shaabi\nMahraganat hyperpop\nMahraganat rap\nMahraganat trap\nMahraganat, Arabic Mawwal, trap\nMahraganat, Arabic pop, cinematic\nMahraganat, cinematic Arabic, electronic fusion\nMahraganat, electronic, Arabic pop\nMalay Melayu, cinematic, ney flute\nMalay Pop\nMalay Pop rock\nMalay Pop, hard rock\nMalay R&B\nMalay ballad\nMalay ballad rock\nMalay classical\nMalay classical tango\nMalay classical, Javanese fusion, pop-rock\nMalay classical, pop-rock\nMalay folk\nMalay folk fusion\nMalay folk hip-hop\nMalay folk, Indonesian folk\nMalay fusion\nMalay fusion rock\nMalay fusion, Latin, operatic\nMalay hip hop\nMalay hip-hop\nMalay hip-hop pop\nMalay pop\nMalay pop Latin\nMalay pop R&B\nMalay pop ballad\nMalay pop chiptune\nMalay pop cinematic\nMalay pop folk\nMalay pop orchestral\nMalay pop rock\nMalay pop world music\nMalay pop, Bollywood, Middle Eastern\nMalay pop, Bollywood, synth pop\nMalay pop, Dangdut\nMalay pop, Dangdut, modern pop\nMalay pop, Dangdut, pop-rock\nMalay pop, Indian classical, romantic ballad\nMalay pop, Indonesian pop\nMalay pop, Indonesian pop, dance pop\nMalay pop, Indonesian pop, folk\nMalay pop, Indonesian pop, pop\nMalay pop, Indonesian pop, theatrical pop\nMalay pop, Latin ballad\nMalay pop, Latin dance\nMalay pop, Middle Eastern\nMalay pop, Middle Eastern pop\nMalay pop, Middle Eastern, traditional fusion\nMalay pop, ballad, cinematic\nMalay pop, cinematic ballad\nMalay pop, cinematic pop, 80s pop-rock\nMalay pop, cinematic pop, dance pop\nMalay pop, cinematic pop, orchestral\nMalay pop, cinematic pop, pop-rock\nMalay pop, cinematic pop-rock\nMalay pop, cinematic, funk rock\nMalay pop, cinematic, world fusion\nMalay pop, dance, hip-hop\nMalay pop, dangdut koplo\nMalay pop, dangdut koplo, cinematic\nMalay pop, dangdut, modern pop\nMalay pop, electronic dance\nMalay pop, electronic dance, hip-hop\nMalay pop, electronic, romantic\nMalay pop, hard rock\nMalay pop, hyper-digital, electronic dance\nMalay pop, modern pop, dance\nMalay pop, modern rock\nMalay pop, orchestral, anthem\nMalay pop, pop-rock\nMalay pop, pop-rock, cinematic\nMalay pop, pop-rock, oud\nMalay pop, pop-rock, traditional\nMalay pop, retro, chiptune\nMalay pop, trance, synth-pop\nMalay pop, world music, pop rock\nMalay pop, world music, pop-rock\nMalay pop-R&B\nMalay pop-rap\nMalay pop-rock\nMalay pop-rock chiptune\nMalay pop-rock fusion\nMalay pop-rock, hard rock\nMalay rock\nMalay rock ballad\nMalay rock fusion\nMalay rock orchestral\nMalay traditional\nMalay traditional ballad\nMalay traditional fusion\nMalay traditional, cinematic pop\nMalay traditional, electronic, pop\nMalay trap\nMalayalam Christian pop\nMalayalam Christian, Latin, Caribbean\nMalayalam ballad\nMalayalam devotional\nMalayalam film music\nMalayalam film music pop-rock\nMalayalam film music, Eurodance\nMalayalam film music, hard rock\nMalayalam film score\nMalayalam film song\nMalayalam film-pop\nMalayalam filmi\nMalayalam folk\nMalayalam folk pop\nMalayalam folk rock\nMalayalam folk, electronic pop\nMalayalam folk, world music\nMalayalam folk-pop\nMalayalam fusion\nMalayalam hip-hop\nMalayalam hip-hop trap\nMalayalam pop\nMalayalam pop filmi\nMalayalam pop funk disco\nMalayalam pop funk electronic\nMalayalam pop world music\nMalayalam pop, EDM\nMalayalam pop, Eurodance\nMalayalam pop, R&B, hip-hop\nMalayalam pop, chiptune\nMalayalam pop, electronic dance music\nMalayalam pop, electronic, world music\nMalayalam pop, world fusion\nMalayalam pop-EDM\nMalayalam pop-rap\nMalayalam pop-rock\nMalayalam rap\nMalayalam rap, dubstep\nMalayalam rap, electronic fusion, traditional percussion\nMalayalam rock\nMalayalam trap\nMalaysian Pop\nMalaysian Pop Dangdut\nMalaysian hip-hop\nMalaysian pop\nMalaysian pop folk\nMalaysian pop retro\nMalaysian pop, Indonesian pop, folk pop\nMalaysian pop, Latin pop\nMalaysian pop, big band, Latin\nMalaysian pop, dangdut koplo\nMalaysian pop-rap\nMalaysian pop-rock\nMalaysian rock\nMalaysian slow rock\nMaloya\nMandarin EDM\nMandarin R&B\nMandarin R&B pop\nMandarin R&B trap\nMandarin R&B trap-pop\nMandarin R&B, atmospheric pop\nMandarin R&B, cinematic trap\nMandarin R&B, dream trap\nMandarin R&B, flamenco fusion\nMandarin R&B, future bass\nMandarin R&B, hyperpop, trap\nMandarin R&B, lo-fi hip hop, trap\nMandarin R&B, lo-fi, trap\nMandarin R&B, trap, vaporwave\nMandarin ballad\nMandarin blues\nMandarin boom-bap\nMandarin drill\nMandarin folk\nMandarin folk jazz\nMandarin folk pop\nMandarin folk-pop, big band swing\nMandarin folk-rock\nMandarin hip hop\nMandarin hip hop, trap\nMandarin hip-hop\nMandarin hip-hop R&B\nMandarin hip-hop chiptune\nMandarin hip-hop lo-fi\nMandarin hip-hop trap\nMandarin hip-hop, R&B, trap\nMandarin hip-hop, cinematic R&B\nMandarin hip-hop, disco-pop\nMandarin hip-hop, future bass\nMandarin hip-hop, lo-fi R&B, cinematic pop\nMandarin hip-hop, lo-fi trap\nMandarin hip-hop, trap\nMandarin hip-hop, trap, EDM\nMandarin hip-hop, trap, lo-fi\nMandarin lo-fi hip hop\nMandarin pop\nMandarin pop R&B\nMandarin pop ballad\nMandarin pop ballad, pop-rock, Cantonese rap\nMandarin pop chiptune\nMandarin pop future bass\nMandarin pop hip hop\nMandarin pop hip-hop\nMandarin pop rock\nMandarin pop trap\nMandarin pop, R&B\nMandarin pop, R&B, ballad\nMandarin pop, R&B, trap\nMandarin pop, boom-bap, cinematic hip-hop\nMandarin pop, cha-cha-chá\nMandarin pop, cinematic trap\nMandarin pop, disco-pop, cinematic\nMandarin pop, emotional rap, cinematic ballad\nMandarin pop, future bass\nMandarin pop, future bass, melodic rap\nMandarin pop, lo-fi hip hop\nMandarin pop, lo-fi hip hop, cinematic\nMandarin pop, pop-rock\nMandarin pop, pop-rock, R&B\nMandarin pop, pop-rock, cinematic\nMandarin pop, pop-rock, rap\nMandarin pop, trap, dream pop\nMandarin pop-R&B\nMandarin pop-folk\nMandarin pop-hip hop\nMandarin pop-r&b\nMandarin pop-rap\nMandarin pop-rap, future bass\nMandarin pop-rock\nMandarin pop-rock, EDM, trance\nMandarin pop-rock, trap, electronic\nMandarin pop-trap\nMandarin rap\nMandarin rap, R&B, soul\nMandarin rap, hardstyle, trap\nMandarin rap, pop-rock\nMandarin rap, pop-rock, trap\nMandarin rap, trap, pop-rap\nMandarin rock\nMandarin tango\nMandarin trap\nMandarin trap R&B\nMandarin trap pop\nMandarin trap, cloud rap, R&B\nMandarin trap, future bass\nMandarin trap, hardstyle, ambient\nMandarin trap, hip-hop\nMandarin trap, hyperpop\nMandarin trap, lo-fi R&B, hyperpop\nMandarin trap, lo-fi boom-bap\nMandarin trap-R&B\nMandarin trap-pop\nMando-pop EDM\nMando-pop EDM hip-hop\nMando-pop hip-hop EDM\nMando-pop trap EDM\nMando-pop, EDM, future bass\nMando-pop, hip-hop, EDM\nMandopop\nMandopop 80s\nMandopop 80s campus rock\nMandopop 80s dance-pop\nMandopop Afrobeat dancehall\nMandopop Afrobeats\nMandopop Afrobeats R&B\nMandopop Afrobeats dancehall\nMandopop Afrobeats tropical house\nMandopop Bossa Nova\nMandopop Bossa Nova lounge jazz\nMandopop C-pop J-pop\nMandopop Cantopop\nMandopop Christmas\nMandopop City Pop\nMandopop City Pop Eurobeat\nMandopop City Pop funk\nMandopop Cumbia\nMandopop EDM\nMandopop EDM J-pop\nMandopop EDM K-pop\nMandopop EDM chiptune\nMandopop EDM dance-pop\nMandopop EDM future bass\nMandopop EDM hardstyle\nMandopop EDM hip-hop\nMandopop EDM pop-rock\nMandopop EDM rock\nMandopop EDM synth-pop\nMandopop EDM trance\nMandopop EDM trap\nMandopop Eurobeat\nMandopop Eurodance\nMandopop Eurodance J-pop\nMandopop Eurodance J-rock\nMandopop Eurodance chiptune\nMandopop Eurodance hip-hop\nMandopop Eurodance synth-pop\nMandopop Eurodance trance\nMandopop European folk\nMandopop Indian fusion\nMandopop Italo-disco\nMandopop J-pop\nMandopop J-pop EDM\nMandopop J-pop Eurodance\nMandopop J-pop anime\nMandopop J-pop chiptune\nMandopop J-pop city pop\nMandopop J-pop electronic\nMandopop J-pop hip-hop\nMandopop J-pop lo-fi hip-hop\nMandopop J-pop pop-rock\nMandopop J-pop synth-pop\nMandopop J-pop trance\nMandopop J-rock\nMandopop J-rock anime\nMandopop J-rock funk\nMandopop K-pop\nMandopop Latin\nMandopop Latin Cumbia\nMandopop Latin R&B\nMandopop Latin cha-cha\nMandopop Latin cha-cha-cha\nMandopop Latin cha-cha-chá\nMandopop Latin dance\nMandopop Latin dance-pop\nMandopop Latin disco\nMandopop Latin flamenco\nMandopop Latin fusion\nMandopop Latin groove\nMandopop Latin jazz\nMandopop Latin mambo\nMandopop Latin pop\nMandopop Latin pop-rock\nMandopop Latin rock\nMandopop Latin rumba\nMandopop Latin salsa\nMandopop Latin tropical\nMandopop Latin-pop\nMandopop R&B\nMandopop R&B EDM\nMandopop R&B Latin\nMandopop R&B Latin pop\nMandopop R&B acoustic pop\nMandopop R&B blues-rock\nMandopop R&B bossa nova\nMandopop R&B chillwave\nMandopop R&B chiptune\nMandopop R&B cinematic\nMandopop R&B city pop\nMandopop R&B city-pop\nMandopop R&B dance-pop\nMandopop R&B dancehall\nMandopop R&B dream pop\nMandopop R&B electronic\nMandopop R&B electronic dance\nMandopop R&B electronic dance-pop\nMandopop R&B electronic pop\nMandopop R&B funk\nMandopop R&B future bass\nMandopop R&B hardstyle\nMandopop R&B hip-hop\nMandopop R&B jazz\nMandopop R&B jazz fusion\nMandopop R&B lo-fi\nMandopop R&B lo-fi hip hop\nMandopop R&B lo-fi hip-hop\nMandopop R&B lo-fi pop\nMandopop R&B lo-fi trap\nMandopop R&B lounge\nMandopop R&B melodic trap\nMandopop R&B neo-soul\nMandopop R&B pop-rap\nMandopop R&B pop-rock\nMandopop R&B smooth jazz\nMandopop R&B soul\nMandopop R&B synth-pop\nMandopop R&B trap\nMandopop R&B trap-pop\nMandopop R&B trap-soul\nMandopop R&B trip-hop\nMandopop R&B tropical house\nMandopop R&B, cloud rap, lo-fi hip-hop\nMandopop R&B, pop-punk\nMandopop R&B-pop\nMandopop Shidaiqu\nMandopop acoustic\nMandopop acoustic ballad\nMandopop acoustic pop\nMandopop acoustic pop hip-hop\nMandopop acoustic pop lo-fi hip-hop\nMandopop afrobeats\nMandopop alternative rock\nMandopop anime\nMandopop anime ballad\nMandopop anime soundtrack\nMandopop anime theme\nMandopop anime-pop\nMandopop arena rock\nMandopop art song\nMandopop ballad\nMandopop ballad indie rock\nMandopop ballad, electronic\nMandopop ballad, lo-fi hip-hop\nMandopop ballad, narrative hip-hop\nMandopop ballad, pop-rock, cinematic\nMandopop ballad, smooth jazz\nMandopop ballroom\nMandopop bedroom pop\nMandopop bedroom pop chiptune\nMandopop bedroom pop lo-fi\nMandopop big band\nMandopop big band jazz\nMandopop big band surf rock\nMandopop big band swing\nMandopop big-band\nMandopop blues\nMandopop blues R&B\nMandopop blues folk\nMandopop blues jazz\nMandopop blues lounge\nMandopop blues rock\nMandopop blues soul\nMandopop blues-rock\nMandopop blues-rock country-rock\nMandopop blues-rock folk\nMandopop blues-rock funk\nMandopop blues-rock jazz\nMandopop blues-rock jazz fusion\nMandopop blues-rock soul\nMandopop bolero\nMandopop boogie-woogie\nMandopop boom-bap\nMandopop bossa nova\nMandopop bossa nova lounge\nMandopop breakbeat\nMandopop bubblegum pop\nMandopop cabaret\nMandopop cabaret jazz\nMandopop cabaret swing\nMandopop cabaret tango\nMandopop calypso\nMandopop cha-cha-cha\nMandopop cha-cha-chá\nMandopop chamber pop\nMandopop chillwave\nMandopop chiptune\nMandopop chiptune J-pop\nMandopop chiptune R&B\nMandopop chiptune hip-hop\nMandopop chiptune lo-fi\nMandopop chiptune lo-fi hip-hop\nMandopop chiptune synth-pop\nMandopop chiptune trap\nMandopop cinematic\nMandopop cinematic rock\nMandopop city pop\nMandopop city pop R&B\nMandopop city pop funk\nMandopop city pop jazz\nMandopop city pop jazz fusion\nMandopop city pop jazz-funk\nMandopop city pop jazz-fusion\nMandopop city pop lo-fi\nMandopop city pop lo-fi hip-hop\nMandopop city pop lounge\nMandopop city pop neo-soul\nMandopop city pop smooth jazz\nMandopop city-pop\nMandopop city-pop R&B\nMandopop classical\nMandopop classical crossover\nMandopop country\nMandopop country bluegrass\nMandopop country blues-rock\nMandopop country folk-rock\nMandopop country rock synth-pop\nMandopop country rockabilly\nMandopop country-pop\nMandopop country-rock\nMandopop country-western\nMandopop cumbia\nMandopop dance\nMandopop dance-pop\nMandopop dance-pop K-pop\nMandopop dance-pop hip-hop\nMandopop dance-rock\nMandopop dancehall\nMandopop dancehall R&B\nMandopop dancehall afrobeats\nMandopop dancehall reggae\nMandopop dancehall reggaeton\nMandopop dancehall tropical house\nMandopop dark R&B trap\nMandopop deep house\nMandopop disco\nMandopop disco Latin\nMandopop disco city pop\nMandopop disco funk\nMandopop disco rock\nMandopop disco synth-pop\nMandopop disco, Mandopop ballad\nMandopop disco, sentimental ballad\nMandopop disco-funk\nMandopop disco-house\nMandopop disco-pop\nMandopop disco-rock\nMandopop dream pop\nMandopop dream-pop\nMandopop electro-pop\nMandopop electronic\nMandopop electronic hip-hop\nMandopop electronic pop\nMandopop electronic rock\nMandopop electronic rock EDM\nMandopop electropop dance-pop\nMandopop emo rap\nMandopop emo rap R&B\nMandopop emo rap lo-fi hip-hop\nMandopop emo rap pop-rock\nMandopop emo rap synth-pop\nMandopop emo rap trap\nMandopop emo rap trap-R&B\nMandopop emo rap trap-pop\nMandopop emo rap trap-soul\nMandopop emo-rap trap\nMandopop exotica\nMandopop flamenco\nMandopop flamenco rock\nMandopop folk\nMandopop folk blues\nMandopop folk rock\nMandopop folk, Bossa Nova\nMandopop folk-ballad\nMandopop folk-pop\nMandopop folk-rock\nMandopop funk\nMandopop funk R&B\nMandopop funk city pop\nMandopop funk dance-pop\nMandopop funk disco\nMandopop funk electronic\nMandopop funk electronic dance\nMandopop funk hip-hop\nMandopop funk jazz fusion\nMandopop funk pop-rock\nMandopop funk rock\nMandopop funk ska\nMandopop funk soul\nMandopop funk synth-pop\nMandopop funk-pop\nMandopop funk-rock\nMandopop funk-rock dance-pop\nMandopop future bass\nMandopop future bass EDM\nMandopop future bass R&B\nMandopop future bass chiptune\nMandopop future bass hip-hop\nMandopop future bass synth-pop\nMandopop future bass trap\nMandopop garage rock\nMandopop garage rock surf rock\nMandopop gospel\nMandopop gospel R&B\nMandopop hard dance\nMandopop hard rock\nMandopop hardstyle\nMandopop hardstyle EDM\nMandopop hip hop\nMandopop hip-hop\nMandopop hip-hop EDM\nMandopop hip-hop R&B\nMandopop hip-hop chiptune\nMandopop hip-hop dance-pop\nMandopop hip-hop dream pop\nMandopop hip-hop electronic\nMandopop hip-hop funk\nMandopop hip-hop future bass\nMandopop hip-hop pop-rock\nMandopop hip-hop rock\nMandopop hip-hop synth-pop\nMandopop hip-hop tropical house\nMandopop house\nMandopop hyperpop\nMandopop hyperpop EDM\nMandopop hyperpop J-pop\nMandopop hyperpop electronic dance\nMandopop hyperpop trap\nMandopop indie pop\nMandopop indie pop lo-fi hip-hop\nMandopop indie pop-rock\nMandopop indie rock\nMandopop indie rock city pop\nMandopop indie rock hip-hop\nMandopop indie-pop\nMandopop inspirational pop\nMandopop jazz\nMandopop jazz R&B\nMandopop jazz ballad\nMandopop jazz big band\nMandopop jazz blues\nMandopop jazz bossa nova\nMandopop jazz city pop\nMandopop jazz funk\nMandopop jazz fusion\nMandopop jazz fusion city pop\nMandopop jazz fusion soul\nMandopop jazz lounge\nMandopop jazz soul\nMandopop jazz swing\nMandopop jazz-fusion\nMandopop jazz-fusion city pop\nMandopop jazz-fusion soul\nMandopop jazz-pop\nMandopop jazz-pop bossa nova\nMandopop jazz-rock\nMandopop jazzy\nMandopop light-jazz bossa nova\nMandopop liquid drum and bass\nMandopop lo-fi\nMandopop lo-fi R&B\nMandopop lo-fi bedroom pop\nMandopop lo-fi city-pop\nMandopop lo-fi hip hop\nMandopop lo-fi hip-hop\nMandopop lo-fi hip-hop R&B\nMandopop lo-fi hip-hop chiptune\nMandopop lo-fi hip-hop dream pop\nMandopop lo-fi hip-hop future bass\nMandopop lo-fi hip-hop trap\nMandopop lo-fi neo-soul\nMandopop lo-fi pop\nMandopop lo-fi synth-pop\nMandopop lo-fi trap\nMandopop lofi-pop\nMandopop lounge\nMandopop lounge big band\nMandopop lounge blues\nMandopop lounge city pop\nMandopop lounge exotica\nMandopop lounge jazz\nMandopop lounge jazz bossa nova\nMandopop lounge jazz chanson\nMandopop lounge rockabilly\nMandopop lounge smooth jazz\nMandopop lounge soul\nMandopop lounge surf rock\nMandopop lounge swing\nMandopop lounge-pop\nMandopop mambo\nMandopop neo-soul\nMandopop neo-soul R&B\nMandopop neo-soul city pop\nMandopop neo-soul funk\nMandopop neo-soul lo-fi\nMandopop neo-soul lo-fi hip-hop\nMandopop neo-soul lo-fi jazz\nMandopop nu-disco city pop\nMandopop nu-disco funk\nMandopop nu-metal\nMandopop orchestral\nMandopop pop-rap\nMandopop pop-rock\nMandopop pop-rock hip-hop\nMandopop pop-rock synth-pop\nMandopop power ballad\nMandopop progressive house\nMandopop psychedelic rock\nMandopop psychedelic surf-rock\nMandopop rap\nMandopop rap ballad\nMandopop rap rock\nMandopop rap-rock hardstyle\nMandopop reggae\nMandopop reggae dancehall\nMandopop reggae rocksteady\nMandopop reggae ska\nMandopop reggae tropical\nMandopop reggae-dancehall\nMandopop reggae-pop\nMandopop reggae-ska\nMandopop reggaeton\nMandopop retro\nMandopop retro 80s\nMandopop retro big-band\nMandopop retro country surf rock\nMandopop retro dance-pop\nMandopop retro funk\nMandopop retro funk disco\nMandopop retro rock\nMandopop retro rock disco\nMandopop retro rock swing\nMandopop retro surf rock\nMandopop retro surf-rock\nMandopop retro swing\nMandopop retro-dance\nMandopop retro-funk disco\nMandopop retro-swing\nMandopop rock\nMandopop rock ballad\nMandopop rock shidaiqu\nMandopop rock swing\nMandopop rock, ambient, electronic\nMandopop rock, cinematic rock, Chinese opera\nMandopop rock, happy hardcore, trancecore\nMandopop rock, pop-rock\nMandopop rockabilly\nMandopop rockabilly big band\nMandopop rockabilly country\nMandopop rockabilly surf rock\nMandopop rockabilly swing\nMandopop rocksteady reggae\nMandopop romantic\nMandopop romantic ballad\nMandopop salsa\nMandopop singer-songwriter\nMandopop ska-punk\nMandopop smooth jazz\nMandopop smooth jazz Latin\nMandopop smooth jazz R&B\nMandopop smooth jazz funk\nMandopop smooth rock\nMandopop soft rock\nMandopop soul\nMandopop soul R&B\nMandopop soul blues\nMandopop soul funk\nMandopop soul jazz\nMandopop stadium rock\nMandopop surf rock\nMandopop surf rock blues\nMandopop surf rock exotica\nMandopop surf rock lounge\nMandopop surf-rock\nMandopop swing\nMandopop swing lounge\nMandopop swing rockabilly\nMandopop synth-pop\nMandopop synth-pop EDM\nMandopop synth-pop J-pop\nMandopop synth-pop R&B\nMandopop synth-pop chiptune\nMandopop synth-pop dance-pop\nMandopop synth-pop funk\nMandopop synth-pop future bass\nMandopop synth-pop rock\nMandopop tango\nMandopop techno\nMandopop trance\nMandopop trap\nMandopop trap EDM\nMandopop trap R&B\nMandopop trap afrobeat\nMandopop trap afrobeats\nMandopop trap ambient\nMandopop trap chiptune\nMandopop trap dance-pop\nMandopop trap dancehall\nMandopop trap dream pop\nMandopop trap emo-rap\nMandopop trap future bass\nMandopop trap hip-hop\nMandopop trap hyperpop\nMandopop trap metal\nMandopop trap pop-rock\nMandopop trap rock\nMandopop trap synth-pop\nMandopop trap tropical house\nMandopop trap-R&B\nMandopop trap-pop\nMandopop trap-soul\nMandopop trip-hop\nMandopop trip-hop R&B\nMandopop tropical\nMandopop tropical house\nMandopop tropical house EDM\nMandopop tropical house dance-pop\nMandopop tropical house future bass\nMandopop vaporwave\nMandopop vintage\nMandopop vintage big band\nMandopop vintage rock\nMandopop vintage rock and roll swing\nMandopop vintage rock soul\nMandopop vintage rock swing\nMandopop vintage surf-rock\nMandopop waltz\nMandopop world fusion\nMandopop world music\nMandopop worldbeat\nMandopop wuxia\nMandopop, 2000s dance\nMandopop, 60s rock\nMandopop, 60s rock, ballad\nMandopop, 80s anime, power pop\nMandopop, 80s dance\nMandopop, 80s dance, synth-pop\nMandopop, 80s disco\nMandopop, 80s disco-pop\nMandopop, 80s pop\nMandopop, 80s pop, Southeast Asian pop\nMandopop, 80s pop, cha-cha-cha\nMandopop, 80s pop, chiptune\nMandopop, 80s pop, cinematic\nMandopop, 80s pop, retro synth\nMandopop, 80s power ballad\nMandopop, 80s power ballad, cinematic\nMandopop, 80s power ballad, stadium rock\nMandopop, 80s retro, festive\nMandopop, 80s rock\nMandopop, 80s rock, C-pop ballad\nMandopop, 80s rock, Hokkien pop\nMandopop, 80s rock, cinematic\nMandopop, 80s rock, power ballad\nMandopop, 80s rock, theatrical\nMandopop, 80s synth\nMandopop, 80s synth pop\nMandopop, 80s synth, Latin-pop\nMandopop, 80s synth, ballad\nMandopop, 80s synth, cinematic\nMandopop, 80s synth, festive\nMandopop, 80s synth, funk\nMandopop, 80s synth, glam rock\nMandopop, 80s synth, power ballad\nMandopop, 80s synth, upbeat\nMandopop, 80s synth, vintage pop\nMandopop, 80s synth-pop\nMandopop, 80s synth-pop, cinematic\nMandopop, 80s synth-pop, power ballad\nMandopop, 80s, Christmas\nMandopop, 80s, Latin\nMandopop, 80s, anthemic\nMandopop, 80s, ballad\nMandopop, 80s, cha-cha-cha\nMandopop, 80s, cinematic\nMandopop, 80s, disco-funk\nMandopop, 80s, disco-pop\nMandopop, 80s, disco-rock\nMandopop, 80s, festive\nMandopop, 80s, power ballad\nMandopop, 80s, synthwave\nMandopop, 80s, theatrical\nMandopop, 90s R&B, city pop\nMandopop, 90s R&B, funk\nMandopop, 90s R&B, hip-hop\nMandopop, 90s R&B, new jack swing\nMandopop, 90s R&B, power ballad\nMandopop, 90s anime\nMandopop, 90s dance\nMandopop, 90s dance, synth-pop\nMandopop, 90s dance-pop\nMandopop, 90s dance-pop, Eurodance\nMandopop, 90s dance-pop, disco\nMandopop, 90s dance-pop, hip-hop\nMandopop, 90s dance-pop, new jack swing\nMandopop, 90s dance-pop, pop-rock\nMandopop, 90s rock, power ballad\nMandopop, 90s synth-pop\nMandopop, 90s synth-pop, power ballad\nMandopop, A-go-go, psychedelic rock\nMandopop, A-go-go, surf rock\nMandopop, A-go-go, vintage\nMandopop, Afrobeats, R&B\nMandopop, Balkan folk, electronic\nMandopop, Bollywood, dance\nMandopop, Bossa Nova\nMandopop, Bossa Nova, Latin jazz\nMandopop, Bossa Nova, R&B\nMandopop, C-pop\nMandopop, C-pop, R&B\nMandopop, C-pop, R&B, dance-pop\nMandopop, C-pop, ballad\nMandopop, C-pop, hip-hop\nMandopop, C-pop, trap\nMandopop, Cantopop rock\nMandopop, Chinese New Year, festive\nMandopop, Chinese folk\nMandopop, Chinese folk, cinematic\nMandopop, Chinese folk, pop-rock\nMandopop, Chinese folk, synth pop\nMandopop, Chinese folk, upbeat\nMandopop, Chinese folk-pop\nMandopop, Christian contemporary\nMandopop, Christian pop, upbeat\nMandopop, Christmas\nMandopop, Christmas pop\nMandopop, Christmas, R&B\nMandopop, Christmas, ballad\nMandopop, Christmas, pop\nMandopop, Christmas, pop-rock\nMandopop, Christmas, romantic\nMandopop, Christmas, synth ballad\nMandopop, City Pop\nMandopop, City Pop, 80s\nMandopop, City Pop, Adult Contemporary\nMandopop, City Pop, disco-funk\nMandopop, City Pop, disco-pop\nMandopop, Cumbia\nMandopop, Cumbia, Eurodance\nMandopop, Cumbia, vintage ballad\nMandopop, Cumbia, vintage pop\nMandopop, Dutch House\nMandopop, EDM\nMandopop, EDM trap\nMandopop, EDM, Eurodance\nMandopop, EDM, Guofeng\nMandopop, EDM, K-pop\nMandopop, EDM, R&B\nMandopop, EDM, Vocaloid\nMandopop, EDM, anthemic\nMandopop, EDM, ballad\nMandopop, EDM, big room house\nMandopop, EDM, chiptune\nMandopop, EDM, cinematic\nMandopop, EDM, dance\nMandopop, EDM, dance-pop\nMandopop, EDM, dubstep\nMandopop, EDM, electro house\nMandopop, EDM, electronic\nMandopop, EDM, emotional dance\nMandopop, EDM, festive\nMandopop, EDM, funk\nMandopop, EDM, future bass\nMandopop, EDM, hardstyle\nMandopop, EDM, hip-hop\nMandopop, EDM, hyperpop\nMandopop, EDM, melancholic\nMandopop, EDM, melodic rap\nMandopop, EDM, pop-rock\nMandopop, EDM, progressive house\nMandopop, EDM, rock\nMandopop, EDM, synth-pop\nMandopop, EDM, theatrical\nMandopop, EDM, trance\nMandopop, EDM, trance-pop\nMandopop, EDM, trap\nMandopop, EDM, tropical house\nMandopop, EDM-pop\nMandopop, Eurobeat, 90s dance-pop\nMandopop, Eurobeat, Hi-NRG\nMandopop, Eurobeat, dance\nMandopop, Eurodance\nMandopop, Eurodance, 2000s\nMandopop, Eurodance, 2000s dance\nMandopop, Eurodance, 2000s dance-pop\nMandopop, Eurodance, 2000s pop\nMandopop, Eurodance, 2000s trance\nMandopop, Eurodance, 90s\nMandopop, Eurodance, 90s dance\nMandopop, Eurodance, 90s dance-pop\nMandopop, Eurodance, 90s retro\nMandopop, Eurodance, City Pop\nMandopop, Eurodance, Dutch House\nMandopop, Eurodance, EDM\nMandopop, Eurodance, Hardstyle\nMandopop, Eurodance, Hi-NRG\nMandopop, Eurodance, Italo disco\nMandopop, Eurodance, J-pop\nMandopop, Eurodance, J-rock\nMandopop, Eurodance, K-pop\nMandopop, Eurodance, Latin\nMandopop, Eurodance, Trance\nMandopop, Eurodance, Trance-pop\nMandopop, Eurodance, bubblegum pop\nMandopop, Eurodance, chiptune\nMandopop, Eurodance, cinematic\nMandopop, Eurodance, dance\nMandopop, Eurodance, dance pop\nMandopop, Eurodance, dance rock\nMandopop, Eurodance, dance-pop\nMandopop, Eurodance, dancehall\nMandopop, Eurodance, disco\nMandopop, Eurodance, electronic\nMandopop, Eurodance, emotional dance\nMandopop, Eurodance, funk\nMandopop, Eurodance, happy hardcore\nMandopop, Eurodance, hard dance\nMandopop, Eurodance, hardstyle\nMandopop, Eurodance, hip-hop\nMandopop, Eurodance, hip-house\nMandopop, Eurodance, hyperpop\nMandopop, Eurodance, pop-rock\nMandopop, Eurodance, reggaeton\nMandopop, Eurodance, retro\nMandopop, Eurodance, retro dance\nMandopop, Eurodance, retro dance-pop\nMandopop, Eurodance, retro synth\nMandopop, Eurodance, rock\nMandopop, Eurodance, synth-funk\nMandopop, Eurodance, synth-pop\nMandopop, Eurodance, synthwave\nMandopop, Eurodance, trance\nMandopop, Eurodance, trance-pop\nMandopop, European folk\nMandopop, European folk, ballad\nMandopop, European folk, theatrical\nMandopop, European folk, upbeat\nMandopop, French cafe, waltz\nMandopop, J-pop, EDM\nMandopop, J-pop, Eurodance\nMandopop, J-pop, anime theme\nMandopop, J-pop, chiptune\nMandopop, J-pop, dance-pop\nMandopop, J-pop, electronic\nMandopop, J-pop, electronic dance\nMandopop, J-pop, hyperpop\nMandopop, J-pop, synth-pop\nMandopop, J-pop, video game\nMandopop, J-rock\nMandopop, J-rock, EDM\nMandopop, J-rock, anime\nMandopop, J-rock, anime theme\nMandopop, J-rock, chiptune\nMandopop, J-rock, cinematic\nMandopop, J-rock, dreamy pop-rock, uplifting pop-rock\nMandopop, J-rock, electronic\nMandopop, J-rock, electronic dance\nMandopop, J-rock, funk\nMandopop, J-rock, hyperpop\nMandopop, J-rock, pop-rock\nMandopop, J-rock, power ballad\nMandopop, J-rock, synth-pop\nMandopop, K-pop, hip-hop\nMandopop, Latin Cumbia\nMandopop, Latin big band, theatrical\nMandopop, Latin cha-cha\nMandopop, Latin cha-cha, big band\nMandopop, Latin cha-cha-cha\nMandopop, Latin cha-cha-chá\nMandopop, Latin dance, anthemic\nMandopop, Latin dance-pop\nMandopop, Latin disco\nMandopop, Latin disco, big band\nMandopop, Latin disco, mambo\nMandopop, Latin disco, retro\nMandopop, Latin folk\nMandopop, Latin folk, vintage\nMandopop, Latin folk, vintage pop\nMandopop, Latin groove\nMandopop, Latin groove, ballad\nMandopop, Latin groove, retro\nMandopop, Latin groove, uplifting\nMandopop, Latin groove, vintage\nMandopop, Latin house\nMandopop, Latin jazz, Bossa Nova\nMandopop, Latin jazz, bossa nova\nMandopop, Latin jazz, cinematic\nMandopop, Latin jazz, mambo\nMandopop, Latin jazz, smooth jazz\nMandopop, Latin mambo, big band\nMandopop, Latin mambo, retro\nMandopop, Latin mambo, theatrical\nMandopop, Latin pop\nMandopop, Latin pop, 80s dance-pop\nMandopop, Latin pop, R&B\nMandopop, Latin pop, acoustic ballad\nMandopop, Latin pop, ballad\nMandopop, Latin pop, dance\nMandopop, Latin pop, disco\nMandopop, Latin pop, lo-fi\nMandopop, Latin pop, retro\nMandopop, Latin pop, retro disco\nMandopop, Latin pop, surf rock\nMandopop, Latin pop, theatrical\nMandopop, Latin pop, theatrical pop\nMandopop, Latin pop, tropical house\nMandopop, Latin pop, vintage\nMandopop, Latin salsa\nMandopop, Latin salsa, retro\nMandopop, Latin, 80s\nMandopop, Latin, 80s funk\nMandopop, Latin, Flamenco\nMandopop, Latin, big band\nMandopop, Latin, cha-cha-cha\nMandopop, Latin, cha-cha-chá\nMandopop, Latin, dance\nMandopop, Latin, dance-pop\nMandopop, Latin, flamenco\nMandopop, Latin, funk\nMandopop, Latin, jazz\nMandopop, Latin, orchestral\nMandopop, Latin, retro\nMandopop, Latin, salsa\nMandopop, Latin, synth\nMandopop, Latin, synth funk\nMandopop, Latin, theatrical\nMandopop, Latin, vintage\nMandopop, Latin, world music\nMandopop, Mongolian folk, ambient\nMandopop, New Jack Swing, R&B\nMandopop, Parisian cafe, romantic ballad\nMandopop, R&B\nMandopop, R&B, 2000s\nMandopop, R&B, 2000s hip-hop\nMandopop, R&B, 2000s pop\nMandopop, R&B, Eurodance\nMandopop, R&B, J-pop\nMandopop, R&B, New Jack Swing\nMandopop, R&B, atmospheric\nMandopop, R&B, ballad\nMandopop, R&B, bedroom pop\nMandopop, R&B, chiptune\nMandopop, R&B, cinematic\nMandopop, R&B, city pop\nMandopop, R&B, dance-pop\nMandopop, R&B, disco\nMandopop, R&B, dream pop\nMandopop, R&B, electronic\nMandopop, R&B, electronic dance\nMandopop, R&B, electronic pop\nMandopop, R&B, funk\nMandopop, R&B, future bass\nMandopop, R&B, hip-hop\nMandopop, R&B, hip-hop, Eurodance\nMandopop, R&B, jazz\nMandopop, R&B, jazz fusion\nMandopop, R&B, jazz-pop\nMandopop, R&B, lo-fi\nMandopop, R&B, lo-fi hip hop\nMandopop, R&B, lo-fi hip-hop\nMandopop, R&B, melancholic\nMandopop, R&B, melodic rap\nMandopop, R&B, melodic trap\nMandopop, R&B, neo-soul\nMandopop, R&B, pop\nMandopop, R&B, smooth jazz\nMandopop, R&B, soul\nMandopop, R&B, synth-pop\nMandopop, R&B, synthwave\nMandopop, R&B, trap\nMandopop, R&B, trap-soul\nMandopop, R&B, vaporwave\nMandopop, Shidaiqu\nMandopop, Shidaiqu, ballad\nMandopop, Shidaiqu, big band\nMandopop, Shidaiqu, cha-cha-cha\nMandopop, Shidaiqu, cinematic\nMandopop, Shidaiqu, orchestral\nMandopop, Shidaiqu, retro\nMandopop, Shidaiqu, vintage\nMandopop, Shidaiqu, vintage ballad\nMandopop, Taiwanese Hokkien folk, pop-rock\nMandopop, Y2K dance\nMandopop, Y2K dance-pop\nMandopop, Y2K electronic, hip-hop\nMandopop, Y2K, dance\nMandopop, acoustic ballad, pop-rock\nMandopop, acoustic folk-pop\nMandopop, acoustic pop, R&B\nMandopop, acoustic pop, contemporary R&B\nMandopop, acoustic pop, hip-hop\nMandopop, acoustic pop, pop-rap\nMandopop, acoustic, flamenco\nMandopop, alternative rock\nMandopop, ambient\nMandopop, ambient R&B\nMandopop, ambient, cinematic\nMandopop, ambient, dream pop\nMandopop, ambient, pop-rock\nMandopop, anime soundtrack\nMandopop, anime theme, pop-rock\nMandopop, anime, dream pop\nMandopop, anime, pop\nMandopop, arena rock\nMandopop, arena rock, 80s\nMandopop, arena rock, 80s synth\nMandopop, arena rock, power ballad\nMandopop, arena rock, synth pop\nMandopop, atmospheric R&B\nMandopop, atmospheric trap\nMandopop, atmospheric, R&B\nMandopop, atmospheric, electronic\nMandopop, ballad\nMandopop, ballad, disco-pop\nMandopop, ballroom lounge\nMandopop, ballroom march, vintage\nMandopop, bedroom pop\nMandopop, bedroom pop, chiptune\nMandopop, bedroom pop, lo-fi\nMandopop, bedroom pop, lo-fi hip-hop\nMandopop, big band\nMandopop, big band jazz\nMandopop, big band jazz, theatrical\nMandopop, big band swing\nMandopop, big band, Latin\nMandopop, big band, Latin rhythm\nMandopop, big band, Shidaiqu\nMandopop, big band, cha-cha\nMandopop, big band, cha-cha-cha\nMandopop, big band, cha-cha-chá\nMandopop, big band, cinematic\nMandopop, big band, disco\nMandopop, big band, disco-funk\nMandopop, big band, folk\nMandopop, big band, funk\nMandopop, big band, jazz\nMandopop, big band, lounge\nMandopop, big band, mambo\nMandopop, big band, polka\nMandopop, big band, retro\nMandopop, big band, rock\nMandopop, big band, rock-opera\nMandopop, big band, rockabilly\nMandopop, big band, show tune\nMandopop, big band, soul\nMandopop, big band, surf rock\nMandopop, big band, swing\nMandopop, big band, theatrical\nMandopop, big band, vintage\nMandopop, big room house\nMandopop, big-band jazz\nMandopop, big-band swing\nMandopop, big-band swing, retro\nMandopop, big-band swing, theatrical\nMandopop, big-band swing, vintage\nMandopop, big-band, cinematic\nMandopop, big-band, retro\nMandopop, big-band, theatrical\nMandopop, big-band, vintage\nMandopop, blues-rock\nMandopop, bluesy pop, cinematic rock\nMandopop, boogie-woogie, theatrical\nMandopop, boom-bap, blues-rock\nMandopop, boom-bap, cinematic\nMandopop, boom-bap, dream pop\nMandopop, boom-bap, dreamy\nMandopop, boom-bap, hip-hop\nMandopop, boom-bap, lo-fi hip hop\nMandopop, boy band, funk\nMandopop, bubblegum pop\nMandopop, bubblegum pop, 2000s\nMandopop, bubblegum pop, electronic\nMandopop, cabaret, Latin\nMandopop, cabaret, retro\nMandopop, campus folk\nMandopop, campus rock\nMandopop, cha-cha\nMandopop, cha-cha, cinematic\nMandopop, cha-cha, live\nMandopop, cha-cha, vintage\nMandopop, cha-cha-cha\nMandopop, cha-cha-cha, Latin pop\nMandopop, cha-cha-cha, big band\nMandopop, cha-cha-cha, cinematic\nMandopop, cha-cha-cha, disco-pop\nMandopop, cha-cha-cha, retro\nMandopop, cha-cha-cha, surf rock\nMandopop, cha-cha-cha, theatrical\nMandopop, cha-cha-cha, vintage\nMandopop, cha-cha-cha, vintage dance-pop\nMandopop, cha-cha-cha, vintage pop\nMandopop, cha-cha-chá\nMandopop, cha-cha-chá, big band\nMandopop, cha-cha-chá, mambo\nMandopop, cha-cha-chá, retro\nMandopop, cha-cha-chá, surf rock\nMandopop, cha-cha-chá, theatrical\nMandopop, cha-cha-chá, vintage\nMandopop, children's music\nMandopop, chill trap, melodic rap\nMandopop, chill-hop, R&B\nMandopop, chillwave\nMandopop, chiptune\nMandopop, chiptune hip-hop\nMandopop, chiptune, 8-bit\nMandopop, chiptune, Eurodance\nMandopop, chiptune, J-pop\nMandopop, chiptune, R&B\nMandopop, chiptune, anime soundtrack\nMandopop, chiptune, cinematic\nMandopop, chiptune, dance\nMandopop, chiptune, dance-pop\nMandopop, chiptune, electronic\nMandopop, chiptune, future bass\nMandopop, chiptune, happy hardcore\nMandopop, chiptune, hip-hop\nMandopop, chiptune, lo-fi\nMandopop, chiptune, lo-fi hip-hop\nMandopop, chiptune, pop-rock\nMandopop, chiptune, power ballad\nMandopop, chiptune, progressive metal\nMandopop, chiptune, retro\nMandopop, chiptune, synth-pop\nMandopop, chiptune, synth-rock\nMandopop, chiptune, trap\nMandopop, cinematic\nMandopop, cinematic ballad\nMandopop, cinematic ballad, Hokkien\nMandopop, cinematic orchestral\nMandopop, cinematic pop\nMandopop, cinematic pop, dream pop\nMandopop, cinematic pop, lo-fi\nMandopop, cinematic pop, melodic rap\nMandopop, cinematic pop, orchestral\nMandopop, cinematic pop, orchestral rock\nMandopop, cinematic pop, pop-rock\nMandopop, cinematic rock\nMandopop, cinematic rock, ambient pop\nMandopop, cinematic rock, emotional pop\nMandopop, cinematic rock, orchestral pop\nMandopop, cinematic synth, 80s film score\nMandopop, cinematic synth, 80s retro\nMandopop, cinematic synth, 80s revival\nMandopop, cinematic waltz\nMandopop, cinematic, 80s\nMandopop, cinematic, 80s ballad\nMandopop, cinematic, 80s pop\nMandopop, cinematic, 80s power ballad\nMandopop, cinematic, 80s rock\nMandopop, cinematic, 80s synth\nMandopop, cinematic, 80s/90s\nMandopop, cinematic, 90s ballad\nMandopop, cinematic, C-pop\nMandopop, cinematic, Chinese folk\nMandopop, cinematic, Chinese folk-pop\nMandopop, cinematic, Christmas\nMandopop, cinematic, EDM\nMandopop, cinematic, Eurodance\nMandopop, cinematic, J-rock\nMandopop, cinematic, Latin\nMandopop, cinematic, Latin fusion\nMandopop, cinematic, R&B\nMandopop, cinematic, ambient\nMandopop, cinematic, anime theme\nMandopop, cinematic, atmospheric\nMandopop, cinematic, ballad\nMandopop, cinematic, baroque pop\nMandopop, cinematic, big band\nMandopop, cinematic, big band jazz\nMandopop, cinematic, big-band\nMandopop, cinematic, blues-rock\nMandopop, cinematic, bossa nova\nMandopop, cinematic, city pop\nMandopop, cinematic, classic rock\nMandopop, cinematic, classical\nMandopop, cinematic, dance\nMandopop, cinematic, dance-pop\nMandopop, cinematic, disco\nMandopop, cinematic, disco-funk\nMandopop, cinematic, disco-pop\nMandopop, cinematic, electronic\nMandopop, cinematic, emotional\nMandopop, cinematic, epic\nMandopop, cinematic, erhu\nMandopop, cinematic, flamenco\nMandopop, cinematic, folk\nMandopop, cinematic, funk\nMandopop, cinematic, gospel\nMandopop, cinematic, hard rock\nMandopop, cinematic, hip-hop\nMandopop, cinematic, industrial metal\nMandopop, cinematic, jazz\nMandopop, cinematic, jazz-fusion\nMandopop, cinematic, lo-fi\nMandopop, cinematic, lo-fi hip hop\nMandopop, cinematic, lounge\nMandopop, cinematic, melancholic\nMandopop, cinematic, neo-classical\nMandopop, cinematic, new-age\nMandopop, cinematic, opera\nMandopop, cinematic, operatic\nMandopop, cinematic, orchestral\nMandopop, cinematic, orchestral rock\nMandopop, cinematic, patriotic\nMandopop, cinematic, pop-rock\nMandopop, cinematic, power ballad\nMandopop, cinematic, power rock\nMandopop, cinematic, retro\nMandopop, cinematic, rock\nMandopop, cinematic, rock ballad\nMandopop, cinematic, rock opera\nMandopop, cinematic, romantic\nMandopop, cinematic, synth\nMandopop, cinematic, synth rock\nMandopop, cinematic, synth-funk\nMandopop, cinematic, synth-orchestral\nMandopop, cinematic, synth-pop\nMandopop, cinematic, synthwave\nMandopop, cinematic, theatrical\nMandopop, cinematic, theatrical rock\nMandopop, cinematic, traditional Chinese\nMandopop, cinematic, traditional East Asian\nMandopop, cinematic, trap\nMandopop, cinematic, vintage\nMandopop, cinematic, waltz\nMandopop, cinematic, world music\nMandopop, cinematic, wuxia\nMandopop, city pop\nMandopop, city pop, 80s\nMandopop, city pop, 90s R&B\nMandopop, city pop, J-pop\nMandopop, city pop, R&B\nMandopop, city pop, acid jazz\nMandopop, city pop, ballad\nMandopop, city pop, big band\nMandopop, city pop, chiptune\nMandopop, city pop, cinematic\nMandopop, city pop, disco\nMandopop, city pop, disco-funk\nMandopop, city pop, funk\nMandopop, city pop, jazz ballad\nMandopop, city pop, jazz-fusion\nMandopop, city pop, lo-fi\nMandopop, city pop, lounge jazz\nMandopop, city pop, new jack swing\nMandopop, city pop, pop-rock\nMandopop, city pop, retro\nMandopop, city pop, synth-funk\nMandopop, city pop, synth-pop\nMandopop, city pop, synthwave\nMandopop, city-pop\nMandopop, city-pop, 80s\nMandopop, city-pop, 80s synth\nMandopop, city-pop, 90s\nMandopop, city-pop, 90s dance\nMandopop, city-pop, ambient\nMandopop, city-pop, dance\nMandopop, city-pop, funk\nMandopop, city-pop, jazzy\nMandopop, city-pop, lo-fi\nMandopop, classic rock\nMandopop, classic rock, soul\nMandopop, classic rock, theatrical\nMandopop, classic rock, vintage\nMandopop, classical\nMandopop, cloud rap, emo rap\nMandopop, comedic, synth pop\nMandopop, comedic, upbeat\nMandopop, contemporary R&B\nMandopop, cumbia\nMandopop, cumbia, vintage\nMandopop, dance\nMandopop, dance, 2000s\nMandopop, dance, 2000s disco\nMandopop, dance, 2000s nostalgia\nMandopop, dance, 90s pop\nMandopop, dance, 90s synth\nMandopop, dance, Chinese folk\nMandopop, dance, EDM\nMandopop, dance, Eurodance\nMandopop, dance, cheesy\nMandopop, dance, chiptune\nMandopop, dance, cinematic\nMandopop, dance, city-pop\nMandopop, dance, early 2000s\nMandopop, dance, electronic\nMandopop, dance, emotional\nMandopop, dance, eurodance\nMandopop, dance, festive\nMandopop, dance, folk\nMandopop, dance, house\nMandopop, dance, melancholic\nMandopop, dance, retro\nMandopop, dance, retro-futuristic\nMandopop, dance, synth-pop\nMandopop, dance, synthpop\nMandopop, dance, synthwave\nMandopop, dance, trance\nMandopop, dance, trance-pop\nMandopop, dance-pop\nMandopop, dance-pop, 2000s\nMandopop, dance-pop, 2000s C-pop\nMandopop, dance-pop, 2000s house\nMandopop, dance-pop, 2000s retro\nMandopop, dance-pop, 90s\nMandopop, dance-pop, EDM\nMandopop, dance-pop, Eurobeat\nMandopop, dance-pop, Eurodance\nMandopop, dance-pop, Latin\nMandopop, dance-pop, Latin fusion\nMandopop, dance-pop, breakbeat\nMandopop, dance-pop, chiptune\nMandopop, dance-pop, cinematic\nMandopop, dance-pop, early 2000s\nMandopop, dance-pop, electronic\nMandopop, dance-pop, festive\nMandopop, dance-pop, funk\nMandopop, dance-pop, futuristic\nMandopop, dance-pop, hip-hop\nMandopop, dance-pop, house\nMandopop, dance-pop, new jack swing\nMandopop, dance-pop, power ballad\nMandopop, dance-pop, retro\nMandopop, dance-pop, retro rock\nMandopop, dance-pop, retro synth\nMandopop, dance-pop, rock\nMandopop, dance-pop, synthwave\nMandopop, dance-pop, trance\nMandopop, dance-pop, tropical\nMandopop, dance-pop, world music\nMandopop, dark electronic\nMandopop, dark electronic, trap\nMandopop, deep house\nMandopop, disco, 80s\nMandopop, disco, 80s pop\nMandopop, disco, 90s dance-pop\nMandopop, disco, big band\nMandopop, disco, cha-cha-cha\nMandopop, disco, city pop\nMandopop, disco, dance-pop\nMandopop, disco, funk\nMandopop, disco, lounge\nMandopop, disco, retro\nMandopop, disco, soul\nMandopop, disco, synth-pop\nMandopop, disco-funk\nMandopop, disco-funk, 80s\nMandopop, disco-funk, 80s retro\nMandopop, disco-funk, big band\nMandopop, disco-funk, cinematic\nMandopop, disco-funk, city pop\nMandopop, disco-funk, folk-pop, ballad, pop-rock\nMandopop, disco-funk, orchestral\nMandopop, disco-funk, retro\nMandopop, disco-funk, theatrical\nMandopop, disco-funk, vintage\nMandopop, disco-pop\nMandopop, disco-pop, retro\nMandopop, disco-pop, theatrical\nMandopop, disco-rock\nMandopop, disco-rock, brass-driven\nMandopop, disco-rock, cinematic\nMandopop, doo-wop, swing\nMandopop, dream pop\nMandopop, dream pop, 80s power ballad\nMandopop, dream pop, EDM\nMandopop, dream pop, ambient\nMandopop, dream pop, cosmic\nMandopop, dream pop, electronic\nMandopop, dream pop, trap\nMandopop, dream trap\nMandopop, dream-pop, lo-fi\nMandopop, dreamy R&B\nMandopop, dreamy trap\nMandopop, dreamy trap, atmospheric\nMandopop, dreamy, R&B\nMandopop, dreamy, melodic rap\nMandopop, dreamy, romantic\nMandopop, early 2000s R&B\nMandopop, early 2000s R&B, funk\nMandopop, early 2000s R&B, hip-hop\nMandopop, early 2000s electronic\nMandopop, early 2000s hip-hop\nMandopop, electro house\nMandopop, electronic\nMandopop, electronic R&B\nMandopop, electronic R&B, future bass\nMandopop, electronic dance\nMandopop, electronic dance music\nMandopop, electronic dance, Guofeng\nMandopop, electronic dance, early 2000s\nMandopop, electronic dance, hip-hop\nMandopop, electronic dance-pop\nMandopop, electronic pop\nMandopop, electronic pop, future bass\nMandopop, electronic pop, lo-fi hip-hop\nMandopop, electronic rock\nMandopop, electronic rock, EDM\nMandopop, electronic rock, nu-metal\nMandopop, electronic, EDM\nMandopop, electronic, Latin pop\nMandopop, electronic, R&B\nMandopop, electronic, anime\nMandopop, electronic, anthemic\nMandopop, electronic, ballad\nMandopop, electronic, baroque-pop\nMandopop, electronic, blues-rock\nMandopop, electronic, chiptune\nMandopop, electronic, cinematic\nMandopop, electronic, dance\nMandopop, electronic, dream pop\nMandopop, electronic, dreamy\nMandopop, electronic, empowering\nMandopop, electronic, folk\nMandopop, electronic, future bass\nMandopop, electronic, future pop\nMandopop, electronic, futuristic\nMandopop, electronic, hip hop\nMandopop, electronic, hip-hop\nMandopop, electronic, lo-fi\nMandopop, electronic, lo-fi hip hop\nMandopop, electronic, melancholic\nMandopop, electronic, pop\nMandopop, electronic, pop-rock\nMandopop, electronic, rap\nMandopop, electronic, romantic\nMandopop, electronic, sweet\nMandopop, electronic, theatrical\nMandopop, electronic, traditional Chinese\nMandopop, electronic, trap\nMandopop, emo rap\nMandopop, emo rap, R&B\nMandopop, emo rap, cloud rap\nMandopop, emo rap, future bass\nMandopop, emo rap, lo-fi trap\nMandopop, emo rap, trap-pop\nMandopop, emotional pop, trap\nMandopop, emotional pop-rap, atmospheric electronic\nMandopop, emotional rock, rap\nMandopop, epic rock, cinematic\nMandopop, epic, wuxia\nMandopop, festive, big-band\nMandopop, festive, electronic\nMandopop, festive, pop-rock\nMandopop, festive, retro\nMandopop, festive, theatrical\nMandopop, film noir, jazz\nMandopop, film noir, theatrical\nMandopop, film noir, vintage\nMandopop, flamenco, Latin\nMandopop, flamenco, cinematic\nMandopop, folk pop\nMandopop, folk rock\nMandopop, folk, ballad\nMandopop, folk, dance\nMandopop, folk, festive\nMandopop, folk, pop-rock\nMandopop, folk, vintage\nMandopop, folk-pop\nMandopop, folk-pop, cinematic orchestral\nMandopop, folk-rock\nMandopop, funk rock\nMandopop, funk, 80s pop\nMandopop, funk, R&B\nMandopop, funk, big band\nMandopop, funk, chiptune\nMandopop, funk, city pop\nMandopop, funk, city-pop\nMandopop, funk, dance\nMandopop, funk, disco\nMandopop, funk, electronic\nMandopop, funk, electronic dance\nMandopop, funk, pop-rock\nMandopop, funk, retro\nMandopop, funk, soul\nMandopop, funk, synth pop\nMandopop, funk, video game music\nMandopop, funk-pop\nMandopop, funk-rock, pop-rock\nMandopop, future bass\nMandopop, future bass, EDM\nMandopop, future bass, R&B\nMandopop, future bass, cinematic\nMandopop, future bass, dream pop\nMandopop, future bass, electro-house\nMandopop, future bass, happy hardcore\nMandopop, future bass, lo-fi\nMandopop, future bass, pop-rock\nMandopop, future bass, trap\nMandopop, futuristic, dreamy\nMandopop, garage rock\nMandopop, garage rock, lo-fi\nMandopop, garage rock, psychedelic\nMandopop, garage rock, surf rock\nMandopop, glam metal, 80s rock\nMandopop, glam metal, 80s synth\nMandopop, glam metal, cinematic rock\nMandopop, glam metal, power ballad\nMandopop, gospel, R&B\nMandopop, gospel-pop, pop-rock\nMandopop, gypsy jazz, big band\nMandopop, happy hardcore\nMandopop, happy hardcore, Eurodance\nMandopop, happy hardcore, J-core\nMandopop, hard dance\nMandopop, hard rock\nMandopop, hard rock, dance\nMandopop, hard rock, power ballad\nMandopop, hardstyle\nMandopop, hardstyle, EDM\nMandopop, hardstyle, big room house\nMandopop, hardstyle, cinematic\nMandopop, hardstyle, dubstep\nMandopop, hardstyle, electronic\nMandopop, hardstyle, happy hardcore\nMandopop, hardstyle, pop-rock\nMandopop, hardstyle, rapcore\nMandopop, hardstyle, trap\nMandopop, heavy metal\nMandopop, hip hop\nMandopop, hip-hop\nMandopop, hip-hop, EDM\nMandopop, hip-hop, R&B\nMandopop, hip-hop, cinematic\nMandopop, hip-hop, dance-pop\nMandopop, hip-hop, dreamy\nMandopop, hip-hop, electronic\nMandopop, hip-hop, electronic dance\nMandopop, hip-hop, electronic rock\nMandopop, hip-hop, ethereal R&B\nMandopop, hip-hop, lo-fi rap\nMandopop, hip-hop, nostalgic\nMandopop, hip-hop, playful\nMandopop, hip-hop, pop\nMandopop, hip-hop, pop-punk\nMandopop, hip-hop, pop-rock\nMandopop, hip-hop, synth-pop\nMandopop, hip-hop, synthwave\nMandopop, house\nMandopop, house, EDM\nMandopop, house, city pop\nMandopop, house, dance\nMandopop, house, dreamy\nMandopop, house, electronic\nMandopop, house, emotional\nMandopop, house, festive\nMandopop, house, funk\nMandopop, house, melancholic\nMandopop, house, uplifting\nMandopop, hyperpop\nMandopop, hyperpop, Eurobeat\nMandopop, hyperpop, J-pop\nMandopop, hyperpop, electronic dance\nMandopop, hyperpop, electronic rock\nMandopop, hyperpop, hardstyle\nMandopop, hyperpop, nightcore\nMandopop, indie rock\nMandopop, indie rock, post-rock\nMandopop, jazz ballad\nMandopop, jazz lounge, cinematic\nMandopop, jazz, R&B\nMandopop, jazz, ballad\nMandopop, jazz, cinematic\nMandopop, jazz, dreamy\nMandopop, jazz, pop-rock\nMandopop, jazz, rap\nMandopop, jazz, smooth\nMandopop, jazz, soft pop\nMandopop, jazz, soft rock\nMandopop, jazzy\nMandopop, jazzy R&B, rock-rap\nMandopop, jazzy pop\nMandopop, jazzy, neo-soul\nMandopop, jazzy, romantic\nMandopop, lo-fi R&B\nMandopop, lo-fi electronic\nMandopop, lo-fi hip hop\nMandopop, lo-fi hip hop, R&B\nMandopop, lo-fi hip hop, ambient\nMandopop, lo-fi hip hop, chillwave\nMandopop, lo-fi hip hop, cinematic\nMandopop, lo-fi hip hop, dream pop\nMandopop, lo-fi hip hop, emotional\nMandopop, lo-fi hip hop, emotional ballad\nMandopop, lo-fi hip hop, festive\nMandopop, lo-fi hip hop, future bass\nMandopop, lo-fi hip hop, melancholic\nMandopop, lo-fi hip hop, melodic rap\nMandopop, lo-fi hip hop, pop-rap\nMandopop, lo-fi hip hop, vaporwave\nMandopop, lo-fi hip-hop\nMandopop, lo-fi hip-hop, R&B\nMandopop, lo-fi hip-hop, future bass\nMandopop, lo-fi hip-hop, jazz\nMandopop, lo-fi pop\nMandopop, lo-fi pop, R&B\nMandopop, lo-fi trap, R&B\nMandopop, lo-fi, 80s East Asian pop\nMandopop, lo-fi, EDM-pop\nMandopop, lo-fi, R&B\nMandopop, lo-fi, acoustic, ballad\nMandopop, lo-fi, ambient\nMandopop, lo-fi, anime\nMandopop, lo-fi, ballad\nMandopop, lo-fi, bedroom pop\nMandopop, lo-fi, chiptune\nMandopop, lo-fi, cinematic\nMandopop, lo-fi, dance\nMandopop, lo-fi, dream pop\nMandopop, lo-fi, dreamy\nMandopop, lo-fi, electronic\nMandopop, lo-fi, funk\nMandopop, lo-fi, future bass\nMandopop, lo-fi, garage rock\nMandopop, lo-fi, hip-hop\nMandopop, lo-fi, jazz\nMandopop, lo-fi, melancholic\nMandopop, lo-fi, novelty\nMandopop, lo-fi, pop\nMandopop, lo-fi, pop-rock\nMandopop, lo-fi, pop-trap\nMandopop, lo-fi, power ballad\nMandopop, lo-fi, synth-pop\nMandopop, lo-fi, trap\nMandopop, lo-fi, vaporwave\nMandopop, lo-fi, vintage\nMandopop, lounge jazz\nMandopop, lounge jazz, cinematic orchestral\nMandopop, mambo, Latin rock\nMandopop, mambo, big band\nMandopop, mambo, cha-cha\nMandopop, mambo, cha-cha-chá\nMandopop, melodic dubstep\nMandopop, melodic rap\nMandopop, melodic rap, R&B\nMandopop, melodic rap, atmospheric\nMandopop, melodic rap, atmospheric pop-rock\nMandopop, melodic rap, chill trap\nMandopop, melodic rap, dream pop\nMandopop, melodic rap, dreamy\nMandopop, melodic rap, hip-hop\nMandopop, melodic rap, trap\nMandopop, melodic trap\nMandopop, melodic trap, R&B\nMandopop, melodic trap, chiptune\nMandopop, musical theater, orchestral\nMandopop, narrative hip-hop\nMandopop, narrative hip-hop, pop-rock\nMandopop, neo-soul, city pop\nMandopop, new jack swing\nMandopop, new jack swing, 2000s R&B\nMandopop, new jack swing, R&B\nMandopop, new jack swing, city pop\nMandopop, new jack swing, dance-pop\nMandopop, new jack swing, funk\nMandopop, new jack swing, hip-hop\nMandopop, new jack swing, hip-house\nMandopop, new jack swing, synth-pop\nMandopop, new-age\nMandopop, new-age, 80s synth\nMandopop, noise rock\nMandopop, nostalgic hip-hop\nMandopop, nu-disco, city pop\nMandopop, nu-disco, house\nMandopop, nu-metal, cinematic\nMandopop, orchestral ballad\nMandopop, orchestral pop, big band\nMandopop, orchestral pop, cinematic\nMandopop, orchestral, cinematic\nMandopop, orchestral, disco-funk\nMandopop, orchestral, patriotic\nMandopop, orchestral, pop-rock\nMandopop, orchestral, power ballad\nMandopop, orchestral, rock\nMandopop, orchestral, theatrical\nMandopop, piano ballad\nMandopop, pop ballad, hip-hop\nMandopop, pop-R&B\nMandopop, pop-punk\nMandopop, pop-punk, R&B\nMandopop, pop-rap\nMandopop, pop-rap, R&B\nMandopop, pop-rap, anthemic\nMandopop, pop-rap, anthemic pop-rock\nMandopop, pop-rap, ballad\nMandopop, pop-rap, cinematic\nMandopop, pop-rap, cinematic rock\nMandopop, pop-rap, electronic\nMandopop, pop-rap, pop-rock\nMandopop, pop-rap, synth-pop\nMandopop, pop-rock\nMandopop, pop-rock, 2000s\nMandopop, pop-rock, Chinese folk-pop\nMandopop, pop-rock, Chinese fusion\nMandopop, pop-rock, EDM\nMandopop, pop-rock, J-rock\nMandopop, pop-rock, R&B\nMandopop, pop-rock, acoustic, power ballad\nMandopop, pop-rock, ballad\nMandopop, pop-rock, big room EDM\nMandopop, pop-rock, chiptune\nMandopop, pop-rock, cinematic\nMandopop, pop-rock, cinematic rock\nMandopop, pop-rock, city-pop\nMandopop, pop-rock, classical\nMandopop, pop-rock, country-rock\nMandopop, pop-rock, dubstep\nMandopop, pop-rock, electronic\nMandopop, pop-rock, emo-rap\nMandopop, pop-rock, experimental\nMandopop, pop-rock, flamenco\nMandopop, pop-rock, future bass\nMandopop, pop-rock, happy hardcore\nMandopop, pop-rock, hard rock\nMandopop, pop-rock, hardstyle\nMandopop, pop-rock, hip-hop\nMandopop, pop-rock, indie pop\nMandopop, pop-rock, jazz-funk\nMandopop, pop-rock, lo-fi\nMandopop, pop-rock, nu-metal\nMandopop, pop-rock, power ballad\nMandopop, pop-rock, rap\nMandopop, pop-rock, rap-rock\nMandopop, pop-rock, rock\nMandopop, pop-rock, theatrical\nMandopop, pop-rock, traditional fusion\nMandopop, pop-trap\nMandopop, pop-trap, cinematic\nMandopop, post-hardcore, metalcore\nMandopop, post-rock\nMandopop, power ballad\nMandopop, power ballad, 80s\nMandopop, power ballad, 80s rock\nMandopop, power ballad, 80s synth\nMandopop, power ballad, 90s pop-rock\nMandopop, power ballad, 90s rock\nMandopop, power ballad, anime soundtrack\nMandopop, power ballad, arena rock\nMandopop, power ballad, cinematic\nMandopop, power ballad, cinematic rock\nMandopop, power ballad, classic rock\nMandopop, power ballad, hard rock\nMandopop, power ballad, lo-fi\nMandopop, power ballad, nu-metal\nMandopop, power ballad, pop-rock\nMandopop, power ballad, rock\nMandopop, power ballad, stadium rock\nMandopop, power metal, cinematic\nMandopop, power rock\nMandopop, power rock, cinematic\nMandopop, power rock, jazz-fusion\nMandopop, progressive house\nMandopop, progressive house, EDM\nMandopop, progressive house, trance\nMandopop, psychedelic funk-rock\nMandopop, psychedelic garage rock\nMandopop, psychedelic pop\nMandopop, psychedelic rock\nMandopop, psychedelic rock, A-go-go\nMandopop, psychedelic rock, power ballad\nMandopop, psychedelic rock, theatrical\nMandopop, psychedelic, cinematic\nMandopop, psychedelic, lounge-jazz\nMandopop, psychedelic, retro\nMandopop, ragtime, rock\nMandopop, rap-rock, EDM\nMandopop, reggaeton\nMandopop, reggaeton, Latin pop\nMandopop, reggaeton, electronic\nMandopop, retro\nMandopop, retro R&B\nMandopop, retro anime, pop-rock\nMandopop, retro dance\nMandopop, retro dance, Eurodance\nMandopop, retro dance, indie rock\nMandopop, retro dance, lo-fi\nMandopop, retro dance, synth pop\nMandopop, retro dance-pop\nMandopop, retro dance-pop, hip-hop\nMandopop, retro disco\nMandopop, retro disco, big band\nMandopop, retro electronic\nMandopop, retro electronic, dance\nMandopop, retro folk-pop\nMandopop, retro funk, R&B\nMandopop, retro funk, disco\nMandopop, retro funk, soul\nMandopop, retro jazz\nMandopop, retro pop, bubblegum\nMandopop, retro pop, pop-rock\nMandopop, retro pop-rock, 80s Taiwan pop\nMandopop, retro rock\nMandopop, retro rock 'n' roll\nMandopop, retro rock, big band\nMandopop, retro rock, disco\nMandopop, retro rock, soul\nMandopop, retro rock, soul revue\nMandopop, retro rock, surf rock\nMandopop, retro rock, swing\nMandopop, retro rock, theatrical\nMandopop, retro surf-rock\nMandopop, retro swing, big band\nMandopop, retro swing, disco\nMandopop, retro synth\nMandopop, retro synth, anime theme\nMandopop, retro synth, dance\nMandopop, retro synth, dance-pop\nMandopop, retro synth, electronic\nMandopop, retro synth, funk\nMandopop, retro synth, theatrical\nMandopop, retro synth, video game\nMandopop, retro synth-pop\nMandopop, retro synth-pop, disco\nMandopop, retro video game\nMandopop, retro video game, dance\nMandopop, retro, 2000s pop\nMandopop, retro, 80s\nMandopop, retro, Latin\nMandopop, retro, Latin pop\nMandopop, retro, big band\nMandopop, retro, big-band\nMandopop, retro, blues-rock\nMandopop, retro, cha-cha-cha\nMandopop, retro, cha-cha-chambo\nMandopop, retro, cha-cha-chá\nMandopop, retro, children's music\nMandopop, retro, chiptune\nMandopop, retro, cinematic\nMandopop, retro, dance\nMandopop, retro, dance-pop\nMandopop, retro, disco-pop\nMandopop, retro, early 2000s\nMandopop, retro, electronic\nMandopop, retro, festive\nMandopop, retro, folk\nMandopop, retro, funk\nMandopop, retro, garage rock\nMandopop, retro, garage-pop\nMandopop, retro, karaoke\nMandopop, retro, kitsch\nMandopop, retro, pedal steel\nMandopop, retro, playful\nMandopop, retro, pop-rock\nMandopop, retro, psychedelic garage rock\nMandopop, retro, reggae\nMandopop, retro, rock\nMandopop, retro, spy theme\nMandopop, retro, surf rock\nMandopop, retro, surf-rock\nMandopop, retro, synth brass\nMandopop, retro, synth funk\nMandopop, retro, synth-pop\nMandopop, retro, synthwave\nMandopop, retro, theatrical\nMandopop, retro, upbeat\nMandopop, retro, video game\nMandopop, retro-dance\nMandopop, retro-disco, synth-pop\nMandopop, retro-funk, disco\nMandopop, retro-futuristic, dance\nMandopop, retro-futuristic, synthwave\nMandopop, revolutionary era\nMandopop, rock and roll, surf rock\nMandopop, rock and roll, swing\nMandopop, rock ballad\nMandopop, rock ballad, cinematic\nMandopop, rock, ballad\nMandopop, rock, cinematic\nMandopop, rock, power ballad\nMandopop, rockabilly\nMandopop, rockabilly, blues\nMandopop, romantic R&B\nMandopop, salsa, dance\nMandopop, show tune\nMandopop, show tune, theatrical\nMandopop, show tune, vintage\nMandopop, smooth jazz\nMandopop, soft rock\nMandopop, soft rock, city pop\nMandopop, soul, big band\nMandopop, stadium rock\nMandopop, sunshine pop\nMandopop, surf rock\nMandopop, surf rock, A-go-go\nMandopop, surf rock, Shidaiqu\nMandopop, surf rock, blues\nMandopop, surf rock, cha-cha-cha\nMandopop, surf rock, classic rock\nMandopop, surf rock, doo-wop\nMandopop, surf rock, early rock and roll\nMandopop, surf rock, garage pop\nMandopop, surf rock, garage rock\nMandopop, surf rock, lounge\nMandopop, surf rock, mambo\nMandopop, surf rock, psychedelic rock\nMandopop, surf rock, rock and roll\nMandopop, surf rock, rockabilly\nMandopop, surf rock, vintage\nMandopop, surf rock, vintage rock\nMandopop, surf-rock, garage-rock\nMandopop, symphonic metal\nMandopop, symphonic rock\nMandopop, synth pop, retro\nMandopop, synth-funk, cinematic\nMandopop, synth-pop\nMandopop, synth-pop, 80s\nMandopop, synth-pop, 80s dance\nMandopop, synth-pop, 80s disco\nMandopop, synth-pop, 90s dance-pop\nMandopop, synth-pop, Bossa Nova\nMandopop, synth-pop, Chinese classical\nMandopop, synth-pop, EDM\nMandopop, synth-pop, Eurodance\nMandopop, synth-pop, J-pop\nMandopop, synth-pop, Latin\nMandopop, synth-pop, R&B\nMandopop, synth-pop, ambient\nMandopop, synth-pop, anime\nMandopop, synth-pop, anime theme\nMandopop, synth-pop, bossa nova\nMandopop, synth-pop, cha-cha-chá\nMandopop, synth-pop, chiptune\nMandopop, synth-pop, cinematic\nMandopop, synth-pop, cinematic, ballroom\nMandopop, synth-pop, city pop\nMandopop, synth-pop, city-pop\nMandopop, synth-pop, classic rock\nMandopop, synth-pop, classical fusion\nMandopop, synth-pop, cyberpunk\nMandopop, synth-pop, dance\nMandopop, synth-pop, dance-pop\nMandopop, synth-pop, disco\nMandopop, synth-pop, disco-funk\nMandopop, synth-pop, dream pop\nMandopop, synth-pop, dream-pop\nMandopop, synth-pop, dreamy\nMandopop, synth-pop, electronic\nMandopop, synth-pop, festive\nMandopop, synth-pop, funk\nMandopop, synth-pop, future bass\nMandopop, synth-pop, hip-hop\nMandopop, synth-pop, light EDM\nMandopop, synth-pop, lo-fi\nMandopop, synth-pop, lo-fi hip-hop\nMandopop, synth-pop, melodic rap\nMandopop, synth-pop, new jack swing\nMandopop, synth-pop, new wave\nMandopop, synth-pop, new-age\nMandopop, synth-pop, pop-rock\nMandopop, synth-pop, power ballad\nMandopop, synth-pop, retro\nMandopop, synth-pop, retro dance-pop\nMandopop, synth-pop, rock\nMandopop, synth-pop, theatrical\nMandopop, synth-pop, traditional Chinese\nMandopop, synth-pop, trap\nMandopop, synth-pop, trap-rap\nMandopop, synth-pop, vintage\nMandopop, synth-rock, cinematic\nMandopop, synthpop\nMandopop, synthpop, Vocaloid\nMandopop, synthwave\nMandopop, synthwave, dance-pop\nMandopop, synthwave, retro pop\nMandopop, tango, Latin\nMandopop, tango, cinematic\nMandopop, theatrical pop\nMandopop, theatrical pop, ragtime\nMandopop, theatrical pop, synthwave\nMandopop, theatrical rock\nMandopop, theatrical waltz, big-band jazz\nMandopop, theatrical, 80s\nMandopop, theatrical, 80s ballad\nMandopop, theatrical, Latin pop\nMandopop, theatrical, accordion\nMandopop, theatrical, big band\nMandopop, theatrical, chiptune\nMandopop, theatrical, cinematic\nMandopop, theatrical, epic\nMandopop, theatrical, funk\nMandopop, theatrical, jazz\nMandopop, theatrical, live performance\nMandopop, theatrical, operatic\nMandopop, theatrical, orchestral\nMandopop, theatrical, pop-rock\nMandopop, theatrical, power ballad\nMandopop, theatrical, shidaiqu\nMandopop, theatrical, show tune\nMandopop, theatrical, soul\nMandopop, theatrical, vintage\nMandopop, theatrical, vintage film score\nMandopop, theatrical, vintage folk-pop\nMandopop, theatrical, vintage show tune\nMandopop, traditional Chinese folk\nMandopop, traditional Chinese folk, theatrical\nMandopop, trance\nMandopop, trance, happy hardcore\nMandopop, trap\nMandopop, trap R&B\nMandopop, trap R&B, hyperpop\nMandopop, trap R&B, lo-fi\nMandopop, trap hip-hop, emotional pop\nMandopop, trap metal, electronic rock\nMandopop, trap pop\nMandopop, trap soul, R&B\nMandopop, trap, EDM\nMandopop, trap, R&B\nMandopop, trap, acoustic pop\nMandopop, trap, ambient\nMandopop, trap, atmospheric\nMandopop, trap, ballad\nMandopop, trap, chiptune\nMandopop, trap, cinematic\nMandopop, trap, dance-pop\nMandopop, trap, dream pop\nMandopop, trap, dreamy\nMandopop, trap, electronic\nMandopop, trap, electronic pop\nMandopop, trap, emotional\nMandopop, trap, emotional R&B\nMandopop, trap, emotional ballad\nMandopop, trap, emotional rap\nMandopop, trap, epic pop\nMandopop, trap, ethereal\nMandopop, trap, future bass\nMandopop, trap, hip-hop\nMandopop, trap, hyperpop\nMandopop, trap, lo-fi\nMandopop, trap, lo-fi hip hop\nMandopop, trap, melodic rap\nMandopop, trap, pop\nMandopop, trap, pop-rap\nMandopop, trap, pop-rock\nMandopop, trap, smooth R&B\nMandopop, trap, synth\nMandopop, trap, synth-pop\nMandopop, trap, synthwave\nMandopop, trap, vaporwave\nMandopop, trap-R&B\nMandopop, trap-R&B, ambient\nMandopop, trap-R&B, cinematic\nMandopop, trap-R&B, contemporary R&B\nMandopop, trap-R&B, lo-fi\nMandopop, trap-R&B, urban pop\nMandopop, trap-pop\nMandopop, trap-pop, Christmas\nMandopop, trap-pop, R&B\nMandopop, trap-pop, ballad\nMandopop, trap-pop, dreamy synth\nMandopop, trap-pop, electronic\nMandopop, trap-rap, pop\nMandopop, trap-soul\nMandopop, trap-soul, R&B\nMandopop, trap-soul, contemporary R&B\nMandopop, trip-hop, electronic\nMandopop, tropical house\nMandopop, tropical, calypso\nMandopop, vaporwave, lo-fi hip hop\nMandopop, vaporwave, trap\nMandopop, video game music\nMandopop, vintage big band, lounge\nMandopop, vintage disco, cha-cha\nMandopop, vintage disco, funk\nMandopop, vintage funk, disco\nMandopop, vintage funk, soul\nMandopop, vintage lounge, exotica\nMandopop, vintage orchestral\nMandopop, vintage pop, festive\nMandopop, vintage pop, soulful rock\nMandopop, vintage pop, surf rock\nMandopop, vintage rock\nMandopop, vintage rock and roll\nMandopop, vintage rock and roll, big band\nMandopop, vintage rock and roll, soul\nMandopop, vintage rock and roll, surf rock\nMandopop, vintage rock and roll, swing\nMandopop, vintage rock, big band\nMandopop, vintage rock, cha-cha\nMandopop, vintage rock, disco\nMandopop, vintage rock, soul\nMandopop, vintage rock, surf rock\nMandopop, vintage rock, swing\nMandopop, vintage soul, funk\nMandopop, vintage, Latin\nMandopop, vintage, Latin pop\nMandopop, vintage, big band\nMandopop, vintage, cha-cha\nMandopop, vintage, cha-cha-cha\nMandopop, vintage, disco-pop\nMandopop, vintage, festive\nMandopop, vintage, folk\nMandopop, vintage, garage rock\nMandopop, vintage, lo-fi\nMandopop, vintage, theatrical\nMandopop, world fusion, Middle Eastern\nMandopop, world music\nMandopop, world music, Latin\nMandopop, world music, ballad\nMandopop, world music, cinematic\nMandopop, world music, nostalgic\nMandopop, wuxia, cinematic\nMandopop, wuxia, power ballad\nMandopop-rock\nManele\nManele Christian\nManele EDM\nManele Eurodance\nManele Pop\nManele chiptune\nManele cinematic\nManele club\nManele cumbia\nManele dance\nManele dance-pop\nManele dance-pop chiptune\nManele dance-pop reggaeton\nManele dancehall\nManele electronic\nManele etno\nManele fusion\nManele hip-hop\nManele pop\nManele pop dance\nManele pop hip-hop\nManele pop reggaeton\nManele pop-R&B\nManele pop-dance\nManele pop-reggaeton\nManele pop-rock\nManele reggaeton\nManele rock\nManele surf rock\nManele trap\nManele trap EDM\nManele trap hip-hop\nManele trap reggaeton\nManele trap-pop\nManele trap-reggaeton\nManele, Arabic pop\nManele, Balkan party\nManele, Balkan pop\nManele, Christian folk-pop\nManele, Christian pop\nManele, EDM, dance-pop\nManele, EDM, pop\nManele, Etno Pop\nManele, Eurodance\nManele, Eurodance, electronic\nManele, Moombahton\nManele, Romanian folk\nManele, Romanian pop\nManele, ballad\nManele, cinematic, electronic\nManele, dance-pop, trap\nManele, electronic dance\nManele, electronic dance, Romanian folk\nManele, electronic dance, pop\nManele, electronic dance, world music\nManele, electronic dance-pop\nManele, electronic fusion\nManele, electronic pop, Romanian folk\nManele, electronic, Balkan\nManele, electronic, festive\nManele, forró\nManele, pop-rock, synth-pop, power ballad\nManele, reggaeton\nManele, trap, EDM\nManele, trap, folk\nManele, trap, microtonal\nManele, trap, pop\nManele-dance\nManele-pop\nManele-pop, Balkan folk-rock\nManele-reggaeton\nManele-trap\nMaqam\nMaracatu\nMaracatu rock\nMarathi EDM\nMarathi bhajan\nMarathi bhajan, electronic, modern\nMarathi dance\nMarathi dance pop\nMarathi dance-pop\nMarathi devotional\nMarathi devotional, dance-pop, cinematic\nMarathi devotional, electronic dance\nMarathi electronic\nMarathi electronic dance\nMarathi film music\nMarathi film song\nMarathi folk\nMarathi folk chiptune\nMarathi folk dance\nMarathi folk metal\nMarathi folk pop\nMarathi folk rock\nMarathi folk, electronic dance\nMarathi folk, electronic dance, cinematic\nMarathi folk, electronic, trap\nMarathi folk-dance\nMarathi folk-electronic\nMarathi folk-pop\nMarathi hip-hop\nMarathi party\nMarathi party anthem\nMarathi pop\nMarathi pop lo-fi\nMarathi pop tropical\nMarathi pop, EDM, Bollywood\nMarathi pop, EDM, chiptune\nMarathi pop, EDM, dance-pop\nMarathi pop, EDM, hip-hop\nMarathi pop, Latin pop\nMarathi pop, cinematic, ambient\nMarathi pop, dance-pop\nMarathi pop, dancehall, reggaeton\nMarathi pop, electronic dance\nMarathi pop, electronic dance, folk fusion\nMarathi pop, electronic dance, synth-pop\nMarathi pop, folk, lo-fi\nMarathi pop, hip-hop\nMarathi pop, hip-hop, dancehall\nMarathi pop-funk\nMarathi pop-rap\nMarathi pop-rock\nMarathi sports anthem\nMariachi\nMariachi corrido\nMawwal\nMawwal Khaleeji pop\nMawwal, Arabic folk\nMawwal, ambient, world fusion\nMbalax\nMbalax world music\nMbalax, desert blues\nMbalax, desert blues, rock\nMbaqanga\nMediterranean\nMediterranean R&B\nMediterranean ambient\nMediterranean ballad\nMediterranean classical\nMediterranean electronic\nMediterranean folk\nMediterranean folk hip-hop\nMediterranean folk pop\nMediterranean folk pop-rock\nMediterranean folk punk\nMediterranean folk rock\nMediterranean folk, cinematic rock, opera\nMediterranean folk-pop\nMediterranean folk-pop rock\nMediterranean folk-rock\nMediterranean fusion\nMediterranean fusion dance-pop\nMediterranean fusion rock\nMediterranean hip-hop\nMediterranean instrumental\nMediterranean opera\nMediterranean pop\nMediterranean pop, dance\nMediterranean pop, dance, flamenco fusion\nMediterranean pop-rock\nMediterranean power ballad\nMediterranean rock\nMediterranean soul\nMediterranean synth-pop\nMediterranean tango\nMediterranean traditional\nMediterranean trap\nMega Brega\nMelayu pop\nMelbourne Bounce\nMelbourne bounce\nMemphis blues\nMemphis blues folk rock\nMemphis blues rock\nMemphis blues, garage rock\nMemphis crunk, G-funk\nMemphis drill\nMemphis phonk\nMemphis rap\nMemphis rap, G-funk\nMemphis rap, Southern hip-hop\nMemphis rap, cinematic hip hop\nMemphis rap, crunk\nMemphis rap, crunk, trap\nMemphis rock\nMemphis soul\nMemphis soul funk\nMemphis trap\nMexican Banda\nMexican Banda hip-hop\nMexican chiptune\nMexican corrido\nMexican cumbia\nMexican cumbia chiptune\nMexican cumbia, chiptune\nMexican folk\nMexican folk ballad\nMexican folk hip-hop\nMexican folk march\nMexican folk, G-funk, hip-hop\nMexican folk, big band, operatic\nMexican folk, ranchera\nMexican folk, theatrical, martial\nMexican folk-rock\nMexican funk, psychedelic rock\nMexican fusion chiptune\nMexican fusion, chiptune, dance\nMexican hip-hop\nMexican polka\nMexican pop\nMexican rap\nMexican regional\nMexican regional folk\nMexican regional, chiptune\nMexican rock\nMexican rock and roll\nMexican trap\nMiami Bass\nMiami G-funk\nMiami bass\nMiami drill\nMiami hip-hop\nMiami trap\nMiddle Eastern\nMiddle Eastern Flamenco fusion\nMiddle Eastern R&B\nMiddle Eastern Taqsim\nMiddle Eastern acoustic\nMiddle Eastern ambient\nMiddle Eastern art music\nMiddle Eastern art pop\nMiddle Eastern art rock\nMiddle Eastern ballad\nMiddle Eastern chant\nMiddle Eastern choral\nMiddle Eastern cinematic\nMiddle Eastern classical\nMiddle Eastern classical, orchestral\nMiddle Eastern cumbia\nMiddle Eastern dance\nMiddle Eastern dance-pop\nMiddle Eastern devotional\nMiddle Eastern electronic\nMiddle Eastern electronica\nMiddle Eastern epic\nMiddle Eastern film score\nMiddle Eastern folk\nMiddle Eastern folk dance\nMiddle Eastern folk fusion\nMiddle Eastern folk metal\nMiddle Eastern folk pop\nMiddle Eastern folk rock\nMiddle Eastern folk, dance-pop\nMiddle Eastern folk, psychedelic rock\nMiddle Eastern folk, world music, acoustic rock\nMiddle Eastern folk-dance\nMiddle Eastern folk-pop\nMiddle Eastern folk-rock\nMiddle Eastern funk\nMiddle Eastern funk rock\nMiddle Eastern funk-rock\nMiddle Eastern fusion\nMiddle Eastern fusion Balkan\nMiddle Eastern fusion alternative rock\nMiddle Eastern fusion dance-pop\nMiddle Eastern fusion funk-rock\nMiddle Eastern fusion rock\nMiddle Eastern fusion, Latin dance, world beat\nMiddle Eastern fusion, psychedelic rock\nMiddle Eastern fusion, trap, phonk\nMiddle Eastern groove\nMiddle Eastern guitar\nMiddle Eastern hip hop\nMiddle Eastern hip-hop\nMiddle Eastern hip-hop, electronic dance\nMiddle Eastern hip-hop, rap-rock\nMiddle Eastern house\nMiddle Eastern improvisation\nMiddle Eastern instrumental\nMiddle Eastern jazz\nMiddle Eastern lament\nMiddle Eastern loop\nMiddle Eastern lute\nMiddle Eastern melancholic\nMiddle Eastern metal\nMiddle Eastern music\nMiddle Eastern opera\nMiddle Eastern orchestral\nMiddle Eastern orchestral pop\nMiddle Eastern percussion\nMiddle Eastern pop\nMiddle Eastern pop Balkan folk\nMiddle Eastern pop Latin dance\nMiddle Eastern pop chiptune\nMiddle Eastern pop dancehall reggaeton\nMiddle Eastern pop electronic\nMiddle Eastern pop funk\nMiddle Eastern pop funk rock\nMiddle Eastern pop funk-rock\nMiddle Eastern pop gospel\nMiddle Eastern pop reggaeton\nMiddle Eastern pop rock\nMiddle Eastern pop, 90s synth-pop, Eurodance\nMiddle Eastern pop, EDM\nMiddle Eastern pop, Eastern European folk, hyperpop\nMiddle Eastern pop, Latin dance, reggaeton\nMiddle Eastern pop, Latin pop\nMiddle Eastern pop, Latin salsa\nMiddle Eastern pop, Latin world\nMiddle Eastern pop, South Asian pop\nMiddle Eastern pop, big band jazz\nMiddle Eastern pop, big band jazz, funk\nMiddle Eastern pop, cumbia, electronic\nMiddle Eastern pop, dance\nMiddle Eastern pop, dance, cinematic\nMiddle Eastern pop, dance, electronic\nMiddle Eastern pop, electronic dance\nMiddle Eastern pop, electronic dance, fusion\nMiddle Eastern pop, electronic dance, hip-hop\nMiddle Eastern pop, electronic dance, reggaeton\nMiddle Eastern pop, hard rock\nMiddle Eastern pop, hip-hop\nMiddle Eastern pop, hip-hop, Moombahton\nMiddle Eastern pop, hip-hop, dance\nMiddle Eastern pop, hip-hop, electronic dance\nMiddle Eastern pop, ska, polka\nMiddle Eastern pop, stadium rock\nMiddle Eastern pop, synth-pop\nMiddle Eastern pop, trap\nMiddle Eastern pop-dance\nMiddle Eastern pop-rap\nMiddle Eastern pop-rock\nMiddle Eastern pop-rock Balkan dance\nMiddle Eastern pop-rock chiptune\nMiddle Eastern pop-rock flamenco\nMiddle Eastern pop-rock, Balkan dance\nMiddle Eastern pop-rock, Latin cumbia\nMiddle Eastern pop-rock, Latin dance\nMiddle Eastern pop-rock, electronic dance\nMiddle Eastern pop-rock, hard rock\nMiddle Eastern pop-rock, surf rock\nMiddle Eastern pop-rock, synth-pop\nMiddle Eastern pop-trap\nMiddle Eastern power ballad\nMiddle Eastern protest\nMiddle Eastern revolutionary\nMiddle Eastern rhythm\nMiddle Eastern rock\nMiddle Eastern rock Balkan folk\nMiddle Eastern rock funk\nMiddle Eastern rock opera\nMiddle Eastern rock power metal\nMiddle Eastern rock progressive\nMiddle Eastern rock surf rock\nMiddle Eastern rock, Balkan folk, synth-funk\nMiddle Eastern rock, Latin fusion\nMiddle Eastern rock, electronic dance\nMiddle Eastern rock, electronic pop\nMiddle Eastern rock, surf rock\nMiddle Eastern rockabilly fusion\nMiddle Eastern soul\nMiddle Eastern spiritual\nMiddle Eastern storytelling\nMiddle Eastern synth\nMiddle Eastern synth pop\nMiddle Eastern taksim\nMiddle Eastern taqsim\nMiddle Eastern theatrical\nMiddle Eastern traditional\nMiddle Eastern trance\nMiddle Eastern trap\nMiddle Eastern trap chiptune\nMiddle Eastern trap hyperpop\nMiddle Eastern trap pop\nMiddle Eastern trap, epic rock\nMiddle Eastern trap, experimental electronic\nMiddle Eastern trap, hardstyle\nMiddle Eastern video game\nMiddle Eastern vocal\nMiddle Eastern world music\nMiddle Eastern worship\nMiddle Eastern, Arabic, cinematic\nMiddle Eastern, Arabic, instrumental\nMiddle Eastern, Balkan, Klezmer\nMiddle Eastern, Balkan, cinematic\nMiddle Eastern, Balkan, folk fusion\nMiddle Eastern, Balkan, instrumental\nMiddle Eastern, Brazilian forró\nMiddle Eastern, Spiritual, Neo-Traditional\nMiddle Eastern, Sufi, traditional\nMiddle Eastern, Taqsim\nMiddle Eastern, Taqsim, Choral\nMiddle Eastern, Turkish pop\nMiddle Eastern, Turkish, cinematic\nMiddle Eastern, Turkish, instrumental\nMiddle Eastern, choral, epic\nMiddle Eastern, choral, ethnic fusion\nMiddle Eastern, choral, live\nMiddle Eastern, choral, oud\nMiddle Eastern, cinematic\nMiddle Eastern, cinematic, Mediterranean\nMiddle Eastern, cinematic, Turkish\nMiddle Eastern, cinematic, choral\nMiddle Eastern, cinematic, dramatic\nMiddle Eastern, cinematic, emotional\nMiddle Eastern, cinematic, emotive\nMiddle Eastern, cinematic, folk\nMiddle Eastern, cinematic, hypnotic\nMiddle Eastern, cinematic, ney\nMiddle Eastern, cinematic, oud\nMiddle Eastern, cinematic, spiritual\nMiddle Eastern, cinematic, taqsim\nMiddle Eastern, fantasy\nMiddle Eastern, fantasy, cinematic\nMiddle Eastern, fantasy, instrumental\nMiddle Eastern, instrumental, belly dance\nMiddle Eastern, instrumental, oud\nMiddle Eastern, live performance\nMiddle Eastern, live, oud\nMiddle Eastern, ney, orchestral\nMiddle Eastern, oud, cinematic\nMiddle Eastern, ritual ambient\nMiddle Eastern, ritual music\nMiddle Eastern, spiritual, Turkish\nMiddle Eastern, spiritual, ambient\nMiddle Eastern, spiritual, classical\nMiddle Eastern, spiritual, epic\nMiddle Eastern, spiritual, live performance\nMiddle Eastern, spiritual, rock\nMiddle Eastern, taqsim\nMiddle Eastern, taqsim, cinematic\nMiddle Eastern, taqsim, folk\nMiddle Eastern, taqsim, percussive\nMiddle Eastern, traditional\nMiddle Eastern, traditional, celebratory\nMiddle Eastern, traditional, choral\nMiddle Eastern, traditional, epic\nMiddle Eastern, traditional, live performance\nMiddle Eastern, traditional, ney\nMiddle Eastern, traditional, spiritual\nMiddle Eastern, traditional, taqsim\nMiddle Eastern, tribal, cinematic\nMiddle Eastern, world fusion\nMidwest hip-hop\nMinyō\nMinyō Enka\nMizrahi\nMizrahi EDM\nMizrahi ballad\nMizrahi dance\nMizrahi dance pop\nMizrahi dance-pop\nMizrahi electronic\nMizrahi folk\nMizrahi fusion\nMizrahi hip hop\nMizrahi hip-hop\nMizrahi music\nMizrahi pop\nMizrahi pop Afrobeat\nMizrahi pop Balkan dance\nMizrahi pop Balkan folk\nMizrahi pop Latin dance\nMizrahi pop Latin rock\nMizrahi pop chiptune\nMizrahi pop cinematic\nMizrahi pop cumbia\nMizrahi pop dance\nMizrahi pop dance-rock\nMizrahi pop funk\nMizrahi pop funk rock\nMizrahi pop funk-rock\nMizrahi pop hip-hop\nMizrahi pop orchestral\nMizrahi pop progressive rock\nMizrahi pop reggae dancehall\nMizrahi pop rock\nMizrahi pop stadium rock\nMizrahi pop surf rock\nMizrahi pop trap\nMizrahi pop, Balkan dance\nMizrahi pop, EDM\nMizrahi pop, Eurodance\nMizrahi pop, Eurodance, trance\nMizrahi pop, Latin dance\nMizrahi pop, cinematic, hardstyle\nMizrahi pop, cinematic, orchestral\nMizrahi pop, dance\nMizrahi pop, dance-rock\nMizrahi pop, electronic dance\nMizrahi pop, electronic dance, fusion\nMizrahi pop, electronic dance, hardstyle\nMizrahi pop, hard rock\nMizrahi pop, hardstyle\nMizrahi pop, hardstyle, psytrance\nMizrahi pop, pop-rock, cinematic\nMizrahi pop, progressive rock\nMizrahi pop, rock\nMizrahi pop, stadium rock\nMizrahi pop, surf rock, Middle Eastern fusion\nMizrahi pop-rock\nMizrahi pop-rock Balkan folk\nMizrahi pop-rock chiptune\nMizrahi pop-rock surf rock\nMizrahi pop-rock, Balkan dance\nMizrahi pop-rock, Balkan folk\nMizrahi pop-rock, Latin dance\nMizrahi pop-rock, chiptune\nMizrahi pop-rock, dance\nMizrahi pop-rock, dance, rock\nMizrahi pop-rock, electronic dance\nMizrahi pop-rock, electronic dance, trance\nMizrahi pop-rock, surf rock\nMizrahi power ballad\nMizrahi rock\nMizrahi rock progressive metal\nMizrahi rock, electronic dance\nMizrahi rock, pop\nMizrahi surf rock\nMizrahi trance\nMizrahi, cinematic, Middle Eastern\nMizrahi, cinematic, dance\nMizrahi, cinematic, orchestral\nMizrahi-pop\nMongolian R&B\nMongolian club-rap\nMongolian dance-pop\nMongolian drill\nMongolian folk\nMongolian folk electronic\nMongolian folk hip-hop\nMongolian folk metal\nMongolian folk pop-rock\nMongolian folk rock\nMongolian folk trap\nMongolian folk, chiptune, epic\nMongolian folk, cinematic, ethnic fusion\nMongolian folk, electronic dance\nMongolian folk, electronic dance, dance-pop\nMongolian folk, electronic pop\nMongolian folk, synthwave\nMongolian folk, trap, ambient\nMongolian folk-pop\nMongolian folk-pop rock\nMongolian folk-pop, electronic dance\nMongolian folk-rock\nMongolian funk-pop\nMongolian hip hop\nMongolian hip-hop\nMongolian hip-hop trap\nMongolian house\nMongolian long song\nMongolian long-song chiptune\nMongolian pop\nMongolian pop R&B\nMongolian pop dance-pop\nMongolian pop synth-pop\nMongolian pop, Eurodance, retro\nMongolian pop, synth-pop\nMongolian pop-R&B\nMongolian pop-rap\nMongolian pop-rock\nMongolian pop-trap\nMongolian rock\nMongolian traditional\nMongolian trap\nMongolian trap R&B\nMoombahton\nMoombahton Arabic fusion\nMoombahton Arabic pop\nMoombahton Bollywood pop\nMoombahton C-pop\nMoombahton Dance-Pop\nMoombahton Dancehall\nMoombahton Dancehall Pop\nMoombahton Desi Pop\nMoombahton Dutch hip-hop\nMoombahton EDM\nMoombahton K-pop\nMoombahton Latin EDM\nMoombahton Latin House\nMoombahton Latin Pop\nMoombahton Latin dance-pop\nMoombahton Latin dancehall\nMoombahton Latin pop\nMoombahton Latin trap\nMoombahton Mandopop\nMoombahton R&B\nMoombahton Russian pop-rap\nMoombahton dance-pop\nMoombahton dancehall\nMoombahton hip-hop Arabic pop\nMoombahton reggaeton\nMoombahton trap\nMoombahton world fusion\nMoombahton, C-pop\nMoombahton, Chinese fusion\nMoombahton, Chinese hip hop\nMoombahton, Dance-Pop\nMoombahton, French rap, North African pop\nMoombahton, Indian fusion\nMoombahton, Latin pop, Middle Eastern EDM\nMoombahton, Middle Eastern trap\nMoombahton, Rai, French rap\nMoombahton, cinematic, K-pop\nMoombahton, cinematic, R&B\nMoombahton, hip hop, pop-R&B\nMoombahton, pop-dance, Romanian Manele\nMoombahton, reggaeton, dancehall\nMoombahton, trap, cinematic\nMor Lam\nMor Lam Luk Thung\nMor Lam, Luk Thung\nMor Lam, Luk Thung, Southeast Asian pop\nMor Lam, Thai folk-rock\nMor Lam, chiptune, electronic\nMoral sexto\nMoroccan Arabic hip-hop\nMoroccan R&B\nMoroccan drill\nMoroccan drill trap\nMoroccan hip hop\nMoroccan hip-hop\nMoroccan hip-hop chiptune\nMoroccan pop\nMoroccan pop Afrobeat dancehall\nMoroccan pop hip-hop\nMoroccan pop, Afrobeats, dancehall\nMoroccan pop, French hip-hop\nMoroccan pop, French hip-hop, pop-dance\nMoroccan pop, hip-hop\nMoroccan pop-rap\nMoroccan rap\nMoroccan rap trap\nMoroccan trap\nMotown\nMotown soul\nMurga\nMurga Candombe\nMurga cumbia\nMurga folk-rock\nMuzic-box\nMuzică Lăutărească\nMuzică Populară\nMuzică Populară tango\nMuzică de petrecere\nMúsica Gaita\nMúsica Gaúcha\nMúsica Gaúcha Sertanejo de Raiz\nMúsica Gaúcha reggae-pop\nMúsica Llanera\nMúsica Popular Brasileira\nMāori folk\nNaat\nNaat, Islamic devotional, South Asian\nNarrative Hip-Hop\nNarrative Rap\nNasheed\nNasheed, ambient pop, electronic\nNashville Sound\nNashville Sound lounge jazz\nNashville sound\nNasyid\nNasyid pop\nNative American flute\nNeapolitan\nNeapolitan art song\nNeapolitan art song, jazz, swing\nNeapolitan ballad\nNeapolitan ballad, Italian pop-rock\nNeapolitan cabaret\nNeapolitan classical\nNeapolitan folk\nNeapolitan folk pop-rock\nNeapolitan folk rock\nNeapolitan folk-pop\nNeapolitan folk-rock\nNeapolitan fusion\nNeapolitan fusion trap\nNeapolitan hip-hop\nNeapolitan hip-hop funk rock\nNeapolitan jazz\nNeapolitan opera\nNeapolitan pop\nNeapolitan pop reggaeton\nNeapolitan pop, Latin pop, electronic\nNeapolitan pop, big band funk\nNeapolitan pop-funk\nNeapolitan pop-rap\nNeapolitan pop-rock\nNeapolitan pop-rock surf rock\nNeapolitan pop-rock, Italo-disco\nNeapolitan pop-rock, Latin dance\nNeapolitan pop-rock, Latin rhythm\nNeapolitan pop-rock, electronic dance\nNeapolitan pop-rock, hard rock\nNeapolitan pop-trap\nNeapolitan power ballad\nNeapolitan rap\nNeapolitan rock\nNeapolitan song\nNeapolitan style\nNeapolitan swing\nNeapolitan trap\nNeapolitan trap R&B\nNeapolitan, Latin, folk\nNeapolitan, cinematic, orchestral\nNeapolitan, folk, Latin\nNeapolitan, mambo, cha-cha-chá\nNeapolitan, theatrical, rock\nNederhop\nNederhop trap\nNederhop, Afrobeats, lo-fi hip hop\nNederpop\nNederpop Schlager\nNederpop country-rock\nNederpop folk-rock\nNederpop funk disco\nNederpop retro rock\nNederpop rockabilly\nNederpop rockabilly ska\nNederpop, 80s Europop\nNederpop, 80s new wave\nNederpop, 80s rock\nNederpop, Greek folk, dance\nNederpop, Greek-inspired, folk-pop\nNederpop, Schlager, pop-rock\nNederpop, new wave\nNeo-Soul\nNeo-Soul R&B\nNeo-Traditional\nNeo-Traditional Middle Eastern\nNeo-Traditional Turkish\nNepali Christian\nNepali Christian bhajan\nNepali Christian devotional\nNepali Christian folk\nNepali Christian folk, contemporary worship\nNepali Christian folk-pop\nNepali Christian koly\nNepali Christian pop\nNepali Christian pop-folk\nNepali Christian pop-rock\nNepali Christian worship\nNepali Christian, Latin folk\nNepali Christian, world music\nNepali Christian, world music, devotional\nNepali Christian, world music, worship\nNepali Cumbia\nNepali Latin fusion\nNepali R&B\nNepali R&B lo-fi hip-hop\nNepali R&B, lo-fi pop\nNepali acoustic\nNepali acoustic ballad\nNepali ballad\nNepali bhajan\nNepali children's music\nNepali children's music world fusion\nNepali country-rock\nNepali dance\nNepali dance-pop\nNepali devotional\nNepali devotional pop\nNepali devotional pop-rock\nNepali drill\nNepali electronic\nNepali electronic dance\nNepali film music\nNepali film music retro synth\nNepali film music, cha-cha-cha\nNepali film music, synth-pop\nNepali film score\nNepali film song\nNepali film-pop\nNepali filmi\nNepali filmi, cinematic, traditional fusion\nNepali folk\nNepali folk chiptune\nNepali folk electronic\nNepali folk funk\nNepali folk funk-rock\nNepali folk fusion\nNepali folk fusion funk-rock\nNepali folk gypsy jazz\nNepali folk hip-hop\nNepali folk pop\nNepali folk pop-rock\nNepali folk protest\nNepali folk rock\nNepali folk world music\nNepali folk, EDM\nNepali folk, chiptune, electronic dance\nNepali folk, cinematic, ambient\nNepali folk, contemporary folk\nNepali folk, electronic dance\nNepali folk, electronic dance, folk-pop\nNepali folk, electronic dance, fusion\nNepali folk, electronic dance, hip-hop\nNepali folk, electronic dance, rock\nNepali folk, electronic pop\nNepali folk, electronic, fusion\nNepali folk, world music\nNepali folk-fusion\nNepali folk-pop\nNepali folk-pop chiptune\nNepali folk-pop funk-rock\nNepali folk-pop rock\nNepali folk-pop, Eurodance\nNepali folk-pop, electronic dance\nNepali folk-pop, hard rock\nNepali folk-rap\nNepali folk-rock\nNepali folk-rock, cinematic ballad\nNepali folk-rock, hard rock\nNepali funk-pop\nNepali funk-reggae\nNepali funk-rock\nNepali ghazal\nNepali hard rock\nNepali hip hop\nNepali hip-hop\nNepali hip-hop Latin\nNepali hip-hop moombahton\nNepali hip-hop trap\nNepali hip-hop, trap, drill\nNepali indie folk\nNepali indie pop\nNepali indie rock\nNepali indie-folk\nNepali indie-pop\nNepali indie-pop reggae ska\nNepali pop\nNepali pop Afrobeats\nNepali pop Latin\nNepali pop R&B\nNepali pop R&B dancehall\nNepali pop R&B funk\nNepali pop R&B lo-fi hip-hop\nNepali pop R&B trap\nNepali pop ambient\nNepali pop chiptune\nNepali pop cumbia\nNepali pop dance-pop\nNepali pop dancehall\nNepali pop dancehall afrobeats\nNepali pop dancehall tropical house\nNepali pop disco\nNepali pop filmi\nNepali pop folk\nNepali pop funk\nNepali pop funk chiptune\nNepali pop jazz swing\nNepali pop lo-fi\nNepali pop lo-fi hip-hop\nNepali pop reggae\nNepali pop reggae dancehall\nNepali pop reggae ska\nNepali pop reggaeton\nNepali pop world music\nNepali pop, 80s synth, retro dance\nNepali pop, Afrobeats, dancehall\nNepali pop, Bhangra, Bollywood\nNepali pop, Bollywood, festive\nNepali pop, Bollywood, vintage\nNepali pop, EDM\nNepali pop, EDM, dance-pop\nNepali pop, EDM, dancehall\nNepali pop, EDM, hip-hop\nNepali pop, Indian bhajan, Indian folk\nNepali pop, Latin pop\nNepali pop, Latin pop, tropical\nNepali pop, Latin, world music\nNepali pop, R&B, lo-fi hip-hop\nNepali pop, R&B, rock\nNepali pop, R&B, trap\nNepali pop, ballad, R&B\nNepali pop, chiptune, cinematic\nNepali pop, chiptune, dance-pop\nNepali pop, chiptune, electronic\nNepali pop, chiptune, festive\nNepali pop, chiptune, synth-pop\nNepali pop, cinematic orchestral\nNepali pop, cinematic, ballad\nNepali pop, cinematic, electronic\nNepali pop, cinematic, festive\nNepali pop, cinematic, romantic\nNepali pop, cumbia\nNepali pop, dance, EDM\nNepali pop, dance-pop\nNepali pop, dance-pop, electronic\nNepali pop, dancehall, afrobeats\nNepali pop, dancehall, electronic\nNepali pop, dancehall, folk\nNepali pop, dancehall, reggaeton\nNepali pop, dreamy, trap\nNepali pop, electronic R&B\nNepali pop, electronic dance\nNepali pop, electronic dance, children's music\nNepali pop, electronic dance, chiptune\nNepali pop, electronic dance, folk\nNepali pop, electronic dance, folk fusion\nNepali pop, electronic, dancehall\nNepali pop, electronic, folk\nNepali pop, electronic, folk fusion\nNepali pop, electronic, spiritual\nNepali pop, festive, electronic\nNepali pop, folk\nNepali pop, folk dance\nNepali pop, folk fusion\nNepali pop, folk pop\nNepali pop, folk rock\nNepali pop, folk, electronic\nNepali pop, folk, lo-fi\nNepali pop, folk, romantic\nNepali pop, folk, upbeat\nNepali pop, hip-hop, chiptune\nNepali pop, hip-hop, dancehall\nNepali pop, hip-hop, electronic dance\nNepali pop, reggae\nNepali pop, reggaeton, electronic\nNepali pop, retro Bollywood\nNepali pop, retro Bollywood, synth pop\nNepali pop, retro dance\nNepali pop, retro disco\nNepali pop, retro disco, funk\nNepali pop, retro pop, dance-pop\nNepali pop, retro synth, 80s electronic\nNepali pop, retro synth, dance-pop\nNepali pop, retro, 80s\nNepali pop, retro, folk\nNepali pop, smooth jazz\nNepali pop, soft rock\nNepali pop, synth pop, smooth jazz\nNepali pop, synth-pop\nNepali pop, synth-pop, dance-pop\nNepali pop, synth-pop, disco\nNepali pop, world music, classic rock\nNepali pop-R&B\nNepali pop-dance\nNepali pop-folk\nNepali pop-funk\nNepali pop-fusion\nNepali pop-rap\nNepali pop-reggae\nNepali pop-rock\nNepali pop-rock funk disco\nNepali pop-rock jazz fusion\nNepali pop-rock jazz lounge\nNepali pop-rock, dance\nNepali protest\nNepali rap, electronic dance\nNepali rock\nNepali romantic\nNepali romantic duet\nNepali salsa\nNepali ska-reggae\nNepali trap\nNeue Deutsche Härte\nNeue Deutsche Härte chiptune\nNeue Deutsche Härte chiptune industrial metal\nNeue Deutsche Härte funk-rock\nNeue Deutsche Härte gothic metal\nNeue Deutsche Härte industrial metal\nNeue Deutsche Härte industrial metal chiptune\nNeue Deutsche Härte industrial rock\nNeue Deutsche Härte power metal\nNeue Deutsche Härte punk\nNeue Deutsche Härte rap-metal\nNeue Deutsche Härte synth-punk\nNeue Deutsche Härte synth-rock\nNeue Deutsche Härte, German Schlager\nNeue Deutsche Härte, folk metal\nNeue Deutsche Härte, folk metal, Middle Eastern\nNeue Deutsche Welle\nNeue Deutsche Welle alternative rock\nNeue Deutsche Welle chiptune\nNeue Deutsche Welle chiptune-punk\nNeue Deutsche Welle funk ska\nNeue Deutsche Welle funk-rock\nNeue Deutsche Welle punk\nNeue Deutsche Welle punk rock\nNeue Deutsche Welle rock\nNeue Deutsche Welle rockabilly\nNeue Deutsche Welle ska-punk\nNeue Deutsche Welle surf punk\nNeue Deutsche Welle surf rock\nNeue Deutsche Welle tropical\nNeue Deutsche Welle, German rock, Latin rock\nNeue Deutsche Welle, Italo-disco\nNeue Deutsche Welle, Schlager, German rock\nNeue Deutsche Welle, Schlager, synth pop\nNeue Deutsche Welle, Schlager-rock, German rock\nNeue Deutsche Welle, art-rock, psychedelic cumbia\nNeue Deutsche Welle, hard rock\nNeue Deutsche Welle, hard rock, synth punk\nNeue Deutsche Welle, ska, rock\nNeue Deutsche Welle, surf rock, German rock\nNew Age, C-pop, ambient\nNew Age, Chinese folk, ambient\nNew Age, Chinese traditional, ambient\nNew Age, Traditional Chinese, Ambient\nNew Age, ambient, traditional Chinese\nNew Age, traditional Chinese, meditative\nNew Jack Swing\nNew Jack Swing City Pop\nNew Jack Swing French House\nNew Jack Swing G-funk\nNew Jack Swing Gospel\nNew Jack Swing R&B\nNew Jack Swing Southern Hip Hop\nNew Jack Swing gospel\nNew Jack Swing hip hop\nNew Jack Swing, G-funk, Christmas\nNew Jack Swing, German pop, R&B\nNew Mexico style\nNew Orleans Bounce\nNew Orleans R&B\nNew Orleans big band\nNew Orleans blues\nNew Orleans blues R&B\nNew Orleans blues jazz\nNew Orleans blues, country rock\nNew Orleans brass\nNew Orleans brass band\nNew Orleans funk\nNew Orleans funk R&B\nNew Orleans funk boogie-woogie\nNew Orleans funk soul\nNew Orleans hip-hop\nNew Orleans jazz\nNew Orleans jazz blues\nNew Orleans jazz funk\nNew Orleans jazz swing\nNew Orleans jazz, Dixieland, Christmas music\nNew Orleans jazz, gospel, big band\nNew Orleans jazz, western swing\nNew Orleans jazz-blues\nNew Orleans mambo\nNew Orleans marching band\nNew Orleans party\nNew Orleans rock\nNew Orleans rock and roll\nNew Orleans second-line\nNew Orleans soul\nNew Orleans soul funk\nNew Orleans swing\nNew Swing\nNew York House\nNew York drill\nNew York drill trap\nNey flute\nNigerian Gospel\nNigerian Gospel Afrobeat\nNigerian Gospel Afrobeats\nNigerian Gospel Highlife\nNigerian drill\nNigerian folk\nNigerian gospel\nNigerian gospel, Highlife\nNigerian hip-hop\nNigerian trap\nNintendocore\nNintendocore Celtic punk\nNintendocore German pop-punk\nNintendocore German punk\nNintendocore crossover thrash\nNintendocore cybergrind\nNintendocore cyberpunk rock\nNintendocore digital hardcore\nNintendocore easycore\nNintendocore electronic rock\nNintendocore extreme metal\nNintendocore funk metal\nNintendocore happy hardcore\nNintendocore hard rock\nNintendocore hardcore techno\nNintendocore hyper-punk\nNintendocore hyperpop\nNintendocore math rock\nNintendocore mathcore\nNintendocore melodic death metal\nNintendocore melodic hardcore\nNintendocore melodic metalcore\nNintendocore metalcore\nNintendocore pop-punk\nNintendocore post-hardcore\nNintendocore power metal\nNintendocore power-pop\nNintendocore progressive metal\nNintendocore progressive metalcore\nNintendocore punk rock\nNintendocore skate punk\nNintendocore speed metal\nNintendocore speedcore\nNintendocore synth-punk\nNintendocore synthwave\nNintendocore technical metal\nNintendocore technical metalcore\nNintendocore theatrical punk\nNintendocore theatrical rock\nNintendocore thrash metal\nNintendocore, djent, post-hardcore\nNintendocore, electronic rock, hip-hop\nNintendocore, metalcore, chiptune\nNintendocore, metalcore, cinematic\nNintendocore, theatrical metal\nNordic folk\nNordic folk rock\nNordic folk, Celtic folk\nNorteño\nNorteño Christian\nNorteño Christian corrido\nNorteño Christian folk\nNorteño Christian hip-hop\nNorteño Christian polka\nNorteño Christian pop\nNorteño Christmas\nNorteño Cumbia\nNorteño French Chanson\nNorteño Mariachi\nNorteño Ranchera\nNorteño Rock\nNorteño Romántico\nNorteño Tejano\nNorteño Western Swing\nNorteño alt-country\nNorteño ballad\nNorteño bolero\nNorteño chiptune\nNorteño comedy\nNorteño corrido\nNorteño corrido, cinematic orchestral\nNorteño corrido, cinematic rock\nNorteño corrido, lo-fi hip hop\nNorteño country\nNorteño cumbia\nNorteño folk\nNorteño fusion\nNorteño gospel\nNorteño hip hop\nNorteño hip-hop\nNorteño hip-hop fusion\nNorteño lo-fi\nNorteño merengue\nNorteño novelty\nNorteño polka\nNorteño polka, rockabilly\nNorteño pop\nNorteño pop-rock\nNorteño praise\nNorteño protest\nNorteño punk\nNorteño ranchera\nNorteño ranchero\nNorteño rap-rock\nNorteño reggaeton\nNorteño rock\nNorteño rockabilly\nNorteño ska\nNorteño swing\nNorteño trap\nNorteño umbia\nNorteño waltz\nNorteño worship\nNorteño, Banda\nNorteño, Christian Cumbia\nNorteño, Christian music\nNorteño, Corrido\nNorteño, Cumbia\nNorteño, Cumbia, Ballad\nNorteño, Latin rock\nNorteño, Latin trap\nNorteño, Ranchera\nNorteño, Regional Mexican\nNorteño, Tejano\nNorteño, ballad\nNorteño, blues-rock\nNorteño, cinematic\nNorteño, cinematic rock\nNorteño, cinematic, epic\nNorteño, hip hop\nNorteño, hip-hop, EDM\nNorteño, lo-fi hip hop\nNorteño, lo-fi, regional Mexican\nNorteño, mariachi, Latin folk\nNorteño, polka\nNorteño, regional Mexican\nNorteño-Banda\nNorteño-Banda chiptune\nNorteño-Banda cinematic\nNorteño-Banda corrido\nNorteño-Banda, Bolero, Ranchera\nNorteño-Cumbia\nNorteño-Polka\nNorteño-Rock\nNorteño-Romántico\nNorteño-pop\nNorteño-rock\nNorteño-ska\nNorteño-trap\nNorth African\nNorth African Arabic\nNorth African Latin fusion\nNorth African Nasheed\nNorth African dance\nNorth African devotional\nNorth African electronic\nNorth African electronic funk\nNorth African electronica\nNorth African folk\nNorth African folk dance\nNorth African folk fusion\nNorth African folk hip-hop\nNorth African folk indie rock\nNorth African folk pop\nNorth African folk rock\nNorth African folk, Latin pop\nNorth African folk, big band jazz\nNorth African folk, boom-bap hip-hop\nNorth African folk, chiptune\nNorth African folk, electronic dance\nNorth African folk, electronic dance, pop\nNorth African folk, electronic, Afrobeat\nNorth African folk, electronic, dance\nNorth African folk, electronic, devotional\nNorth African folk, electronic, festive\nNorth African folk, electronic, fusion\nNorth African folk, electronic, reggaeton\nNorth African folk, electronic, spiritual\nNorth African folk, electronic, upbeat\nNorth African folk, experimental electronic\nNorth African folk, psychedelic rock\nNorth African folk, retro electronic\nNorth African folk, retro synth\nNorth African folk, salsa\nNorth African folk, spiritual, electronic\nNorth African folk, taqsim, electronic\nNorth African folk-dance\nNorth African folk-pop\nNorth African folk-rock\nNorth African funk\nNorth African funk rock\nNorth African funk, psychedelic rock\nNorth African fusion\nNorth African fusion funk\nNorth African fusion pop-rock\nNorth African fusion rock\nNorth African fusion, hard trance, psytrance\nNorth African hip hop\nNorth African hip-hop\nNorth African music\nNorth African oud\nNorth African polyphony\nNorth African pop\nNorth African pop French pop\nNorth African pop chiptune\nNorth African pop funk\nNorth African pop funk rock\nNorth African pop hip-hop\nNorth African pop reggae\nNorth African pop reggaeton\nNorth African pop rock\nNorth African pop trap\nNorth African pop, French hip-hop\nNorth African pop, French hip-hop, pop\nNorth African pop, French rap, R&B\nNorth African pop, French rap, trap\nNorth African pop, Latin pop\nNorth African pop, Latin salsa\nNorth African pop, dance music\nNorth African pop, dance, funk\nNorth African pop, electronic dance\nNorth African pop, hip-hop, chiptune\nNorth African pop, pop-rock\nNorth African pop, retro electronic, chiptune\nNorth African pop, smooth jazz, funk\nNorth African pop-folk\nNorth African pop-rap\nNorth African pop-rock\nNorth African pop-rock funk\nNorth African reggae\nNorth African rock\nNorth African traditional\nNorth African trance\nNorth African trap\nNorth African world music\nNorth Indian folk\nNorth Korean folk\nNorth Korean pop\nNorth Korean pop-march\nNorth Korean trot\nNorwegian Christmas\nNorwegian Christmas novelty\nNorwegian Christmas vise\nNorwegian Christmas, theatrical, choral\nNorwegian EDM\nNorwegian ballad\nNorwegian cabaret\nNorwegian carnival\nNorwegian club-rap\nNorwegian country-folk\nNorwegian country-folk rockabilly\nNorwegian country-rock\nNorwegian dance-pop\nNorwegian danseband\nNorwegian drill\nNorwegian folk\nNorwegian folk, bluegrass, country\nNorwegian folk, country\nNorwegian folk, country western\nNorwegian folk, country, boogie-woogie\nNorwegian folk, country, western\nNorwegian folk, schlager\nNorwegian folk-country\nNorwegian folk-pop\nNorwegian folk-rock\nNorwegian gangsta rap\nNorwegian gospel, country-folk\nNorwegian hip-hop\nNorwegian hip-hop chiptune\nNorwegian hip-hop trap\nNorwegian hip-hop, chiptune, trap\nNorwegian hip-hop, hyperpop, glitch\nNorwegian hip-hop, jazz rap\nNorwegian hip-hop, trap, cinematic\nNorwegian indie pop\nNorwegian party\nNorwegian party hip-hop\nNorwegian party rap\nNorwegian party-rap\nNorwegian party-rock\nNorwegian phonk\nNorwegian polka\nNorwegian polka-rock\nNorwegian pop\nNorwegian pop, dancehall, reggaeton\nNorwegian pop, rockabilly, schlager\nNorwegian pop-rap\nNorwegian pop-rock\nNorwegian rock\nNorwegian rock 'n' roll\nNorwegian rock and roll\nNorwegian schlager\nNorwegian trap\nNorwegian vise\nNueva Canción\nNueva Cantautor\nNueva Onda\nNueva canción\nOPM\nOPM Christmas\nOPM City Pop\nOPM Latin\nOPM R&B\nOPM R&B dancehall\nOPM R&B hip-hop\nOPM acoustic\nOPM acoustic ballad\nOPM acoustic pop\nOPM ballad\nOPM ballad, 80s synth-pop\nOPM bolero\nOPM folk\nOPM funk soul\nOPM future bass\nOPM hip-hop\nOPM pop\nOPM pop ballad\nOPM pop-rock\nOPM power ballad\nOPM rock\nOPM singer-songwriter\nOPM, 80s pop, cumbia\nOPM, Christmas pop\nOPM, J-pop\nOPM, R&B, 2000s pop\nOPM, R&B, electronic\nOPM, R&B, hip-hop\nOPM, bubblegum pop\nOPM, cinematic, orchestral\nOPM, dance-pop, acoustic-pop\nOPM, dancehall, afrobeats\nOPM, dream pop, electronic\nOPM, lo-fi hip-hop, R&B\nOPM, pop-rock, nostalgic\nOPM, pop-rock, vintage Filipino\nOPM, retro pop, Eurobeat\nOkinawan folk\nOpera\nOperatic Folk\nOrchestral Arabic\nOrchestral Bolero\nOrchestral Enka\nOrchestral MPB\nOrchestral Samba\nOrchestral copla\nOrchestral, Arabic Mawwal, Cinematic\nOrchestral, Big Band, Show Tunes\nOrchestral, Middle Eastern classical\nOrchestral, Romantic era, cinematic\nOrchestral, cinematic\nOriental trap\nOrquestal, copla, vintage\nOud taqsim\nOud trap\nOud, Balkan, Turkish\nOyun Havası\nP-Funk\nP-Pop\nP-pop, hip-hop, electronic dance\nPahari folk\nPahari folk Bhojpuri\nPak Newetic\nPandeiro\nPansori\nParaguayan folk\nParisian cafe\nParisian chanson\nParisian jazz\nParisian waltz\nPartyschlager\nPartyschlager Eurodance\nPasodoble\nPatriotic C-pop\nPersian EDM\nPersian Eurodance\nPersian Nasheed\nPersian R&B\nPersian R&B trap\nPersian acoustic ballad\nPersian acoustic pop\nPersian ambient\nPersian art music\nPersian art pop\nPersian art-pop\nPersian ballad\nPersian ballad flamenco\nPersian blues\nPersian chiptune\nPersian cinematic\nPersian classical\nPersian classical crossover\nPersian classical, Latin jazz\nPersian classical, cinematic orchestral\nPersian classical, cinematic, big band\nPersian classical, cinematic, melancholic\nPersian classical, cinematic, operatic\nPersian classical, cinematic, orchestral\nPersian classical, dance-pop\nPersian classical, flamenco, cinematic\nPersian classical, folk-pop\nPersian classical, romantic ballad\nPersian classical, trap, cinematic\nPersian dance\nPersian dance-pop\nPersian dance-pop moombahton\nPersian deep house\nPersian devotional\nPersian disco\nPersian disco-funk\nPersian drill\nPersian electronic\nPersian electronic future bass\nPersian electronic pop\nPersian electronic, hardstyle\nPersian electronica\nPersian flamenco\nPersian flamenco fusion\nPersian folk\nPersian folk dance\nPersian folk flamenco\nPersian folk fusion\nPersian folk metal\nPersian folk rock\nPersian folk, electronic dance\nPersian folk-pop\nPersian folk-rock\nPersian funk\nPersian funk-pop\nPersian fusion\nPersian fusion cinematic\nPersian fusion trap\nPersian fusion, progressive house\nPersian hip hop\nPersian hip-hop\nPersian hip-hop boom-bap\nPersian hip-hop chiptune\nPersian hip-hop lo-fi\nPersian hip-hop trap\nPersian hip-hop, Arabic rap, cinematic pop\nPersian hip-hop, Latin acoustic\nPersian hip-hop, Latin trap\nPersian hip-hop, trap\nPersian jazz\nPersian jazz fusion\nPersian opera\nPersian orchestral\nPersian pop\nPersian pop Afrobeat\nPersian pop Balkan folk\nPersian pop Latin\nPersian pop Latin dance\nPersian pop R&B\nPersian pop R&B hip-hop\nPersian pop R&B trap\nPersian pop ambient\nPersian pop ballad\nPersian pop chiptune\nPersian pop cinematic\nPersian pop cumbia\nPersian pop dance-pop\nPersian pop dancehall\nPersian pop deep house\nPersian pop flamenco\nPersian pop flamenco Latin\nPersian pop flamenco fusion\nPersian pop funk\nPersian pop funk R&B\nPersian pop funk disco\nPersian pop funk hip-hop\nPersian pop funk synth-pop\nPersian pop funk-rock\nPersian pop future bass\nPersian pop hip-hop\nPersian pop jazz lounge\nPersian pop lo-fi hip hop\nPersian pop lo-fi hip-hop\nPersian pop moombahton\nPersian pop nu-disco deep house\nPersian pop nu-disco funk\nPersian pop nu-disco lounge\nPersian pop nu-disco synth-pop\nPersian pop orchestral\nPersian pop progressive house\nPersian pop progressive trance\nPersian pop reggaeton\nPersian pop rock\nPersian pop salsa\nPersian pop salsa funk\nPersian pop tango\nPersian pop trap\nPersian pop world music\nPersian pop worldbeat\nPersian pop, 80s new wave\nPersian pop, 80s synth\nPersian pop, 80s synth pop\nPersian pop, 80s synth, funk\nPersian pop, 80s synth, theatrical pop\nPersian pop, 80s synth-pop\nPersian pop, 90s dance-pop\nPersian pop, 90s dance-pop, chiptune\nPersian pop, Central Asian folk, lo-fi\nPersian pop, EDM\nPersian pop, Eurodance\nPersian pop, Eurodance, Latin\nPersian pop, Eurodance, hip-hop\nPersian pop, Eurodance, trance\nPersian pop, Latin cha-cha-chá\nPersian pop, Latin cumbia\nPersian pop, Latin dance\nPersian pop, Latin dance, reggaeton\nPersian pop, Latin dance-pop\nPersian pop, Latin funk\nPersian pop, Latin fusion, Middle Eastern\nPersian pop, Latin jazz\nPersian pop, Latin pop\nPersian pop, Latin pop, Euro-disco\nPersian pop, Latin pop, Middle Eastern\nPersian pop, Latin pop, cumbia\nPersian pop, Latin pop, disco\nPersian pop, Latin pop, flamenco\nPersian pop, Latin pop, modern\nPersian pop, Latin pop, reggaeton\nPersian pop, Latin pop, retro\nPersian pop, Latin pop, salsa\nPersian pop, Latin salsa\nPersian pop, Latin, Middle Eastern\nPersian pop, Latin, big band\nPersian pop, Latin, salsa\nPersian pop, Latin-disco\nPersian pop, R&B, electronic\nPersian pop, R&B, hip-hop\nPersian pop, R&B, synth-pop\nPersian pop, R&B, trap\nPersian pop, acoustic ballad, hip-hop\nPersian pop, big band jazz\nPersian pop, big band, Latin pop\nPersian pop, big band, swing\nPersian pop, chiptune\nPersian pop, chiptune, electronic dance\nPersian pop, chiptune, future bass\nPersian pop, chiptune, video game music\nPersian pop, cinematic fusion, Middle Eastern\nPersian pop, cinematic orchestral\nPersian pop, cinematic, ambient\nPersian pop, cinematic, electronic\nPersian pop, cinematic, epic\nPersian pop, cinematic, orchestral\nPersian pop, complextro\nPersian pop, conscious hip-hop\nPersian pop, cumbia\nPersian pop, cumbia, Latin\nPersian pop, cumbia, Latin pop\nPersian pop, cumbia, dance\nPersian pop, cumbia, psychedelic\nPersian pop, cumbia, salsa\nPersian pop, dance\nPersian pop, dance-pop\nPersian pop, dance-pop, EDM\nPersian pop, dance-pop, emotional ballad\nPersian pop, dance-pop, pop-rock\nPersian pop, dancehall, moombahton\nPersian pop, dancehall, reggaeton\nPersian pop, deep house\nPersian pop, deep house, R&B\nPersian pop, deep house, ethnic electronica\nPersian pop, deep house, trap\nPersian pop, downtempo, R&B\nPersian pop, dream pop, trap\nPersian pop, electronic\nPersian pop, electronic dance\nPersian pop, electronic dance, hip-hop\nPersian pop, electronic dance, world music\nPersian pop, electronic, Dari\nPersian pop, electronic, chiptune\nPersian pop, electronic, cinematic\nPersian pop, electronic, dance\nPersian pop, electronic, dance-pop\nPersian pop, electronic, dubstep\nPersian pop, electronic, reggaeton\nPersian pop, electronic, trap\nPersian pop, flamenco fusion\nPersian pop, flamenco, cinematic\nPersian pop, folk ballad\nPersian pop, folk-dance, cinematic\nPersian pop, funk, R&B\nPersian pop, funk, disco\nPersian pop, hard rock\nPersian pop, hardstyle\nPersian pop, hardstyle, cinematic\nPersian pop, hip-hop, duduk\nPersian pop, hip-hop, trap\nPersian pop, lo-fi hip hop\nPersian pop, lo-fi hip hop, chiptune\nPersian pop, melodic rap, atmospheric\nPersian pop, nu-disco, dance-pop\nPersian pop, nu-disco, deep house\nPersian pop, nu-disco, funk\nPersian pop, nu-disco, synth-pop\nPersian pop, pop-rock, hard rock\nPersian pop, pop-rock, hip-hop\nPersian pop, progressive house\nPersian pop, progressive house, trance\nPersian pop, psychedelic rock\nPersian pop, reggaeton\nPersian pop, reggaeton, Latin pop\nPersian pop, reggaeton, cumbia\nPersian pop, reggaeton, dance\nPersian pop, reggaeton, dancehall\nPersian pop, reggaeton, flamenco\nPersian pop, reggaeton, moombahton\nPersian pop, retro dance\nPersian pop, retro pop, chiptune\nPersian pop, retro, Latin pop\nPersian pop, retro-funk\nPersian pop, soul, blues\nPersian pop, symphonic metal\nPersian pop, synth-pop\nPersian pop, synth-pop, Italo-disco\nPersian pop, synth-pop, dance\nPersian pop, synth-pop, dance-pop\nPersian pop, synth-pop, disco\nPersian pop, synth-pop, dream-pop\nPersian pop, synth-pop, electronic\nPersian pop, synth-pop, nu-disco\nPersian pop, synth-pop, trance\nPersian pop, synth-pop, trap\nPersian pop, trap, Middle Eastern fusion\nPersian pop, trap, R&B\nPersian pop, trap, ambient\nPersian pop, trap, atmospheric\nPersian pop, trap, chiptune\nPersian pop, trap, cinematic\nPersian pop, trap, hip-hop\nPersian pop, trap, microtonal\nPersian pop, world music, classical guitar\nPersian pop, worldbeat\nPersian pop, worldbeat, funk\nPersian pop-R&B\nPersian pop-dance\nPersian pop-folk\nPersian pop-funk\nPersian pop-rap\nPersian pop-rock\nPersian pop-rock, worldbeat\nPersian pop-trap\nPersian power ballad\nPersian psychedelic rock\nPersian rap\nPersian rap, electronic dance music\nPersian rock\nPersian salsa\nPersian soul\nPersian spiritual\nPersian spoken word\nPersian synth-pop\nPersian tech house\nPersian tech-house\nPersian techno\nPersian theatrical\nPersian traditional\nPersian trance\nPersian trance-pop\nPersian trap\nPersian trap R&B\nPersian trap metal\nPersian trap reggaeton\nPersian trap, R&B\nPersian trap, boom-bap hip-hop\nPersian trap, drill\nPersian trap, jazzy hip-hop\nPersian trap, lo-fi hip hop\nPersian wedding music\nPersian world music\nPeruvian Chicha\nPeruvian Cumbia\nPeruvian Gaita\nPeruvian carnival\nPeruvian cumbia\nPeruvian folk\nPeruvian folk cumbia\nPeruvian folk waltz\nPeruvian folk-pop\nPeruvian guajira\nPeruvian mambo\nPeruvian waltz\nPimba\nPimba Forró\nPimba forró\nPimba pop\nPimba rock\nPimba, Angolan folk\nPimba, Cumbia\nPimba, Forró\nPimba, Forró, Portuguese folk\nPimba, Forró, Portuguese pop\nPimba, Forró, dance\nPimba, Forró, novelty\nPimba, Forró, synth-pop\nPimba, Kizomba\nPimba, Salsa, ballad\nPimba, forró\nPimba, forró, novelty\nPimba, pop-rock, Latin pop\nPiseiro\nPiseiro Brega\nPiseiro Forró\nPiseiro Funk\nPiseiro chiptune\nPiseiro funk carioca\nPiseiro, Forró, electronic\nPlena\nPolish Christian pop\nPolish Christmas\nPolish Christmas ballad\nPolish Christmas carol\nPolish Christmas pop\nPolish Christmas, Latin pop, festive\nPolish Christmas, big band, festive\nPolish Christmas, synth waltz\nPolish EDM-rap\nPolish EDM-trap\nPolish Eurodance\nPolish R&B\nPolish R&B hip-hop\nPolish R&B lo-fi hip-hop\nPolish R&B trap\nPolish R&B, dance-pop\nPolish R&B, hip-hop\nPolish R&B, pop, reggaeton\nPolish Schlager\nPolish anthem\nPolish art song\nPolish ballad\nPolish ballad Latin\nPolish ballad flamenco\nPolish ballad, Latin bolero, jazz\nPolish ballad, Latin exotica\nPolish ballad, tango, bolero\nPolish bard music\nPolish bard, flamenco\nPolish boom-bap\nPolish brass band\nPolish cabaret\nPolish chanson\nPolish chanson cabaret\nPolish chanson cabaret tango\nPolish chanson tango\nPolish chanson, Latin bolero\nPolish chanson, Latin jazz\nPolish chanson, big band jazz\nPolish children's\nPolish children's music\nPolish choral\nPolish club\nPolish club-rap\nPolish comedy rock\nPolish conscious hip-hop\nPolish cumbia\nPolish dancehall\nPolish disco\nPolish disco polo\nPolish disco-folk\nPolish disco-funk\nPolish disco-pop\nPolish disco-pop, Middle Eastern fusion\nPolish drill\nPolish drill trap\nPolish electronic\nPolish folk\nPolish folk big band\nPolish folk cabaret\nPolish folk chiptune\nPolish folk cumbia\nPolish folk flamenco\nPolish folk hip-hop\nPolish folk punk\nPolish folk rock\nPolish folk tango\nPolish folk, Balkan brass\nPolish folk, Balkan brass, Christmas carol\nPolish folk, Balkan folk\nPolish folk, Balkan folk, Christmas music\nPolish folk, Balkan fusion\nPolish folk, Latin, dance\nPolish folk, bluegrass, country\nPolish folk, cabaret, Latin fusion\nPolish folk, cabaret, chanson\nPolish folk, cabaret, circus\nPolish folk, cabaret, tavern song\nPolish folk, cabaret, theatrical\nPolish folk, chiptune\nPolish folk, chiptune, synth-pop\nPolish folk, electronic, dance\nPolish folk, gospel, live performance\nPolish folk, novelty, retro synth\nPolish folk, polka\nPolish folk, polka, Balkan\nPolish folk, polka, Balkan brass\nPolish folk, polka, big band\nPolish folk, polka, dance\nPolish folk, polka, electronic fusion\nPolish folk, polka, ska\nPolish folk, retro video game\nPolish folk, schlager\nPolish folk, theatrical, orchestral\nPolish folk, turbo-folk\nPolish folk-country\nPolish folk-polka\nPolish folk-pop\nPolish folk-pop chiptune\nPolish folk-pop disco polo\nPolish folk-pop reggae-ska\nPolish folk-rock\nPolish freestyle hip-hop\nPolish funk\nPolish funk soul\nPolish funk-pop\nPolish funk-rock\nPolish gangsta rap\nPolish gangsta rap, cinematic trap\nPolish grime\nPolish hardcore hip-hop\nPolish hip hop\nPolish hip hop, boom-bap, industrial\nPolish hip-hop\nPolish hip-hop G-funk\nPolish hip-hop R&B\nPolish hip-hop chiptune\nPolish hip-hop funk\nPolish hip-hop funk disco\nPolish hip-hop lo-fi\nPolish hip-hop nu-disco funk\nPolish hip-hop nu-disco synth-pop\nPolish hip-hop nu-metal\nPolish hip-hop pop\nPolish hip-hop reggae\nPolish hip-hop reggaeton\nPolish hip-hop rock\nPolish hip-hop trap\nPolish hip-hop, Balkan folk\nPolish hip-hop, Eurodance\nPolish hip-hop, Eurodance, Italo disco\nPolish hip-hop, chiptune\nPolish hip-hop, chiptune, 8-bit\nPolish hip-hop, chiptune, boom-bap\nPolish hip-hop, chiptune, synth-pop\nPolish hip-hop, chiptune, trap\nPolish hip-hop, cinematic trap\nPolish hip-hop, cinematic, boom-bap\nPolish hip-hop, dancehall, reggae\nPolish hip-hop, dark ambient, cinematic\nPolish hip-hop, electro-house, dance\nPolish hip-hop, electronic, folk\nPolish hip-hop, emo-rap, trap\nPolish hip-hop, hardstyle, electronic\nPolish hip-hop, horrorcore\nPolish hip-hop, hyperpop, electronic\nPolish hip-hop, hyperpop, electronic dance\nPolish hip-hop, lo-fi hip-hop, trap\nPolish hip-hop, nu-metal, electronic\nPolish hip-hop, reggaeton\nPolish hip-hop, synth-pop\nPolish hip-hop, techno\nPolish hip-hop, trap\nPolish hip-hop, trap, EDM\nPolish hip-hop, trap, chiptune\nPolish hip-hop, trap, conscious rap\nPolish hip-hop, trap, glitch\nPolish hip-hop, trap, hyperpop\nPolish hip-hop, trap, industrial techno\nPolish hip-hop, trap, psychedelic\nPolish hymn\nPolish indie rock\nPolish kolyadka\nPolish lullaby\nPolish march\nPolish military march\nPolish new wave\nPolish novelty\nPolish novelty, Latin, flamenco\nPolish patriotic march\nPolish patriotic waltz\nPolish phonk\nPolish phonk, hardstyle, hardcore techno\nPolish polka\nPolish pop\nPolish pop 80s disco\nPolish pop R&B\nPolish pop cabaret\nPolish pop chanson\nPolish pop folk\nPolish pop reggaeton\nPolish pop trap\nPolish pop tropical\nPolish pop, 80s Eurodance\nPolish pop, 80s disco\nPolish pop, Balkan, disco polo\nPolish pop, Eurodance\nPolish pop, Eurodance, Schlager\nPolish pop, Eurodance, disco\nPolish pop, Eurodance, disco polo\nPolish pop, Eurodance, retro\nPolish pop, Europop, disco polo\nPolish pop, Latin cumbia\nPolish pop, Latin dance\nPolish pop, Latin pop\nPolish pop, Latin pop, Euro-pop\nPolish pop, Latin pop, Eurodance\nPolish pop, Latin pop, ballroom\nPolish pop, Latin pop, big band\nPolish pop, Latin pop, bolero\nPolish pop, Latin pop, cumbia\nPolish pop, Latin pop, dance\nPolish pop, Latin pop, folk-pop\nPolish pop, Latin pop, mambo\nPolish pop, Latin pop, reggaeton\nPolish pop, Latin pop, retro\nPolish pop, Latin pop, salsa\nPolish pop, Latin pop, theatrical\nPolish pop, Latin, big band\nPolish pop, Latin, retro\nPolish pop, R&B, funk\nPolish pop, R&B, lo-fi hip-hop\nPolish pop, Schlager\nPolish pop, beat music\nPolish pop, big band jazz\nPolish pop, big band, Latin pop\nPolish pop, big band, cabaret\nPolish pop, big band, doo-wop\nPolish pop, big band, exotica\nPolish pop, big band, swing\nPolish pop, big band, theatrical\nPolish pop, cabaret, big band\nPolish pop, cabaret, disco polo\nPolish pop, chanson, big band\nPolish pop, chiptune\nPolish pop, chiptune, 8-bit\nPolish pop, cinematic, orchestral\nPolish pop, cumbia\nPolish pop, cumbia, synthpop\nPolish pop, dancehall, reggaeton\nPolish pop, disco\nPolish pop, disco polo, Eurodance\nPolish pop, disco polo, Latin pop\nPolish pop, disco polo, big band\nPolish pop, disco polo, folk\nPolish pop, disco, folk\nPolish pop, disco, schlager\nPolish pop, disco, ska\nPolish pop, disco, synthwave\nPolish pop, folk pop, schlager\nPolish pop, folk, disco polo\nPolish pop, hip-hop\nPolish pop, hip-hop, trap\nPolish pop, jazz, lounge\nPolish pop, neo-soul, funk\nPolish pop, orchestral, big-band\nPolish pop, polka\nPolish pop, polka, synth pop\nPolish pop, retro Eurodance\nPolish pop, retro disco\nPolish pop, retro, Eurodance\nPolish pop, retro, big-band\nPolish pop, retro, chiptune\nPolish pop, retro, estrada\nPolish pop, retro, theatrical\nPolish pop, salsa, Latin pop\nPolish pop, smooth jazz\nPolish pop, synth-pop, Eurodance\nPolish pop, theatrical pop, folk pop\nPolish pop, trap\nPolish pop, trap, R&B\nPolish pop, trap, cabaret\nPolish pop, vintage orchestral, big band\nPolish pop-R&B\nPolish pop-dance\nPolish pop-funk\nPolish pop-rap\nPolish pop-reggae\nPolish pop-reggaeton\nPolish pop-rock\nPolish pop-rock 80s\nPolish pop-rock cabaret\nPolish pop-rock disco polo\nPolish pop-rock jazz\nPolish pop-rock reggae\nPolish pop-rock, 80s disco, retro\nPolish pop-rock, Latin groove\nPolish pop-rock, nu-disco\nPolish pop-rock, reggae, funk\nPolish pop-trap\nPolish power ballad\nPolish protest cabaret\nPolish rap\nPolish reggae\nPolish reggaeton\nPolish rock\nPolish rock 'n' roll\nPolish rock and roll\nPolish rock art rock\nPolish rock cabaret\nPolish rock cabaret jazz\nPolish rock country-rock\nPolish rock disco-polo\nPolish rock folk\nPolish rock reggae ska\nPolish rock ska\nPolish rock, big band, swing\nPolish rock, blues, soul\nPolish rock, boogie-woogie, blues-rock\nPolish rock, cabaret, theatrical\nPolish rock, disco polo, theatrical rock\nPolish rock, disco, ska\nPolish rock, flamenco rock, Latin rock\nPolish rock, new wave\nPolish rock, new wave, 80s rock\nPolish rock, new wave, disco\nPolish rock, new wave, ska\nPolish rock, retro, Latin rock\nPolish rock, swing, big band\nPolish rock, world fusion\nPolish salsa\nPolish schlager\nPolish sea shanty\nPolish singer-songwriter\nPolish street rap\nPolish sung poetry\nPolish tango\nPolish tango cabaret\nPolish tango-milonga\nPolish techno\nPolish trap\nPolish trap, Middle Eastern fusion\nPolish trap, ambient\nPolish trap, cloud rap\nPolish trap, hard dance\nPolish trap, hip-hop\nPolish trap, lo-fi hip-hop\nPolish trap, slap house\nPolish trap-house\nPolish trap-pop\nPolish trap-rap\nPolish underground hip-hop\nPolish waltz\nPolka\nPolka Paraguaya\nPolka folk\nPolka, Balkan folk, dance\nPolka, Schlager\nPolka, children's music\nPolka, folk, Christmas\nPolynesian chant\nPolynesian folk\nPolynesian folk-pop\nPolynesian folk-rock\nPolynesian funk\nPolynesian hip-hop\nPolynesian pop\nPolynesian pop-rock\nPolynesian reggae\nPolynesian rock\nPop Dangdut\nPop Jawa\nPop Jawa, Pop Melayu\nPop Jawa, Pop Melayu, R&B\nPop Melayu\nPop Melayu Dangdut\nPop Melayu Dangdut Koplo\nPop Melayu Keroncong\nPop Melayu Pop Sunda\nPop Melayu chiptune rock\nPop Melayu rock ballad\nPop Melayu salsa\nPop Melayu, Dangdut\nPop Melayu, Dangdut Koplo\nPop Melayu, Dangdut Koplo, electronic pop\nPop Melayu, Dangdut, Indonesian pop\nPop Melayu, Dangdut, Latin pop\nPop Melayu, Dangdut, Malay pop\nPop Melayu, Dangdut, cinematic\nPop Melayu, Dangdut, cinematic pop\nPop Melayu, Dangdut, modern pop\nPop Melayu, Dangdut, upbeat pop\nPop Melayu, Latin, Big Band\nPop Melayu, big band, upbeat pop\nPop Melayu, cinematic, orchestral\nPop Melayu, dance pop, dangdut\nPop Melayu, dance-pop, dangdut koplo\nPop Melayu, modern Dangdut\nPop Melayu, modern Dangdut, pop-rock\nPop Pop\nPop R&B\nPop Sunda\nPop Sunda Cumbia\nPop Sunda Dangdut\nPop Sunda Dangdut Koplo\nPop Sunda Funkot\nPop Sunda Funkot EDM\nPop Sunda Pop Melayu\nPop Sunda chiptune\nPop Sunda cumbia\nPop Sunda hip-hop\nPop Sunda rock\nPop Sunda rockabilly surf rock\nPop Sunda surf rock\nPop Sunda, Cumbia\nPop Sunda, Dangdut\nPop Sunda, Dangdut Koplo\nPop Sunda, Pop Melayu\nPop Sunda, hard rock\nPop Sunda, hip-hop\nPop Sundanese\nPop keroncong\nPop-R&B\nPortuguese Christmas\nPortuguese Eurodance\nPortuguese R&B\nPortuguese R&B trap\nPortuguese R&B, Afro-Lusophone, hip-hop\nPortuguese ballad\nPortuguese dance\nPortuguese devotional\nPortuguese drill\nPortuguese drill trap\nPortuguese folk\nPortuguese folk punk\nPortuguese folk rock\nPortuguese folk, Latin jazz\nPortuguese folk, choral, a cappella\nPortuguese folk, cumbia\nPortuguese folk, fado, swing\nPortuguese folk-pop\nPortuguese gospel\nPortuguese hip-hop\nPortuguese hip-hop trap\nPortuguese hymn\nPortuguese indie rock\nPortuguese jazz\nPortuguese pop\nPortuguese pop 80s\nPortuguese pop R&B\nPortuguese pop jazz Latin\nPortuguese pop, 80s pop\nPortuguese pop, Eurodance\nPortuguese pop, Eurodance, Italo disco\nPortuguese pop, Eurodance, Pimba\nPortuguese pop, Fado, cinematic pop\nPortuguese pop, Italo disco, Eurodance\nPortuguese pop, Kizomba\nPortuguese pop, Kizomba, Sertanejo\nPortuguese pop, Kizomba, pop-rock\nPortuguese pop, Kizomba, retro\nPortuguese pop, Kizomba, retro pop\nPortuguese pop, Kizomba, retro synth\nPortuguese pop, Latin pop\nPortuguese pop, Latin pop, 80s pop\nPortuguese pop, Latin pop, Euro-pop\nPortuguese pop, Latin pop, Eurodance\nPortuguese pop, Latin pop, cumbia\nPortuguese pop, Latin pop, dance\nPortuguese pop, Latin pop, gospel\nPortuguese pop, Latin pop, novelty\nPortuguese pop, Latin pop, retro\nPortuguese pop, Latin pop, retro synth\nPortuguese pop, Latin pop, samba\nPortuguese pop, Latin pop, vintage\nPortuguese pop, Latin, cha-cha-cha\nPortuguese pop, dancehall, Latin\nPortuguese pop, folk pop, Christmas\nPortuguese pop, folk pop, pimba\nPortuguese pop, polka\nPortuguese pop, retro pop\nPortuguese pop, retro pop, novelty\nPortuguese pop, retro, Latin pop\nPortuguese pop, retro, chiptune\nPortuguese pop, rock and roll, disco\nPortuguese pop, rockabilly, country\nPortuguese pop, vintage rock and roll, Latin dance\nPortuguese pop-R&B\nPortuguese pop-rap\nPortuguese pop-rock\nPortuguese pop-rock 80s\nPortuguese pop-rock, Eurodance, Latin pop\nPortuguese popular\nPortuguese popular music\nPortuguese rock\nPortuguese rock 'n' roll\nPortuguese romantic ballad\nPortuguese trap\nPuerto Rican Christmas\nPuerto Rican folk\nPunjabi Bhajan\nPunjabi Bhangra\nPunjabi Bhangra G-funk\nPunjabi Bhangra chiptune\nPunjabi Bhangra hardstyle\nPunjabi Bhangra hip-hop\nPunjabi Bhangra metal\nPunjabi Bhangra pop\nPunjabi Bhangra trap\nPunjabi Bhangra, EDM trap\nPunjabi Bhangra, R&B, Pop\nPunjabi Bhangra, UK drill, trap\nPunjabi Bhangra, UK garage, 2-step\nPunjabi Bhangra, chiptune\nPunjabi Bhangra, chiptune hip-hop\nPunjabi Bhangra, chiptune, electronic dance\nPunjabi Bhangra, electronic dance\nPunjabi Bhangra, electronic trap\nPunjabi Bhangra, electronic, hard dance\nPunjabi Bhangra, electronic, trap\nPunjabi Bhangra, hard rock\nPunjabi Bhangra, neurofunk, cinematic\nPunjabi Bhangra, old-school hip-hop\nPunjabi Bhangra, reggaeton\nPunjabi Bhangra, trap\nPunjabi Bhangra, trap, electronic\nPunjabi Christian\nPunjabi Christian Bhangra\nPunjabi Christian EDM\nPunjabi Christian bhajan\nPunjabi Christian chiptune\nPunjabi Christian devotional\nPunjabi Christian electronic\nPunjabi Christian folk\nPunjabi Christian folk-pop\nPunjabi Christian pop\nPunjabi Christian pop-rock\nPunjabi Christian, Bhangra, synth-pop\nPunjabi Christian, chiptune, Bhangra\nPunjabi Christian, early 2000s Bollywood\nPunjabi EDM\nPunjabi Latin fusion\nPunjabi Pop\nPunjabi Pop R&B\nPunjabi Pop trap\nPunjabi Pop, EDM\nPunjabi Pop, Latin Acoustic\nPunjabi Pop, Western Pop\nPunjabi Pop, Western Pop-R&B\nPunjabi Pop, modern R&B\nPunjabi Pop, trap-R&B\nPunjabi Pop-EDM\nPunjabi R&B\nPunjabi R&B hip-hop\nPunjabi R&B lo-fi\nPunjabi R&B lo-fi hip-hop\nPunjabi R&B trap\nPunjabi Sufi\nPunjabi Sufi rock\nPunjabi acoustic\nPunjabi ambient\nPunjabi ballad\nPunjabi ballad lo-fi\nPunjabi ballad, Bhangra\nPunjabi ballad, R&B, folk\nPunjabi ballad, trap, lo-fi\nPunjabi bhajan\nPunjabi bhajan pop fusion\nPunjabi bhajan, chiptune\nPunjabi bhajan, dance-pop\nPunjabi dance\nPunjabi dance pop\nPunjabi dance-pop\nPunjabi devotional\nPunjabi devotional chiptune\nPunjabi devotional fusion\nPunjabi devotional hip-hop\nPunjabi devotional pop\nPunjabi devotional trap\nPunjabi devotional, Bhangra, electronic fusion\nPunjabi devotional, chiptune, folk\nPunjabi devotional, electronic fusion\nPunjabi devotional, electronic, ambient\nPunjabi devotional, electronic, spiritual\nPunjabi drill\nPunjabi electronic\nPunjabi electronic funk\nPunjabi electronic fusion\nPunjabi electronic hip-hop\nPunjabi electronic pop\nPunjabi film music\nPunjabi film song\nPunjabi folk\nPunjabi folk Bhangra\nPunjabi folk R&B\nPunjabi folk Sufi\nPunjabi folk chiptune\nPunjabi folk cinematic\nPunjabi folk drum and bass\nPunjabi folk electronic\nPunjabi folk electronic hip-hop\nPunjabi folk electronica\nPunjabi folk filmi\nPunjabi folk funk-rock\nPunjabi folk fusion\nPunjabi folk hip-hop\nPunjabi folk indie rock\nPunjabi folk lo-fi hip-hop\nPunjabi folk metal\nPunjabi folk pop\nPunjabi folk pop-rock\nPunjabi folk protest\nPunjabi folk rock\nPunjabi folk trap\nPunjabi folk trap R&B\nPunjabi folk trap lo-fi hip-hop\nPunjabi folk trap-pop\nPunjabi folk world music\nPunjabi folk, Bhangra\nPunjabi folk, Bhangra, Bollywood\nPunjabi folk, Bhangra, ambient\nPunjabi folk, Bhangra, cinematic metal\nPunjabi folk, Bhangra, electronic\nPunjabi folk, Bhangra, ghazal\nPunjabi folk, Bhangra, modern pop\nPunjabi folk, Bhangra, traditional Indian\nPunjabi folk, Bhangra, world fusion\nPunjabi folk, Bhangra, world music\nPunjabi folk, Bhangra-pop\nPunjabi folk, Bollywood\nPunjabi folk, Bollywood, Eurodance\nPunjabi folk, Bollywood, microtonal\nPunjabi folk, Bollywood, pop\nPunjabi folk, EDM\nPunjabi folk, EDM, trap\nPunjabi folk, Indian pop\nPunjabi folk, Latin, flamenco\nPunjabi folk, Latin, fusion\nPunjabi folk, R&B, trap-soul\nPunjabi folk, UK drill\nPunjabi folk, UK garage, fusion\nPunjabi folk, ambient, electronic\nPunjabi folk, breakbeat, electronic\nPunjabi folk, chiptune\nPunjabi folk, chiptune, EDM\nPunjabi folk, chiptune, electronic\nPunjabi folk, chiptune, electronic dance\nPunjabi folk, chiptune, hardstyle\nPunjabi folk, chiptune, retro game\nPunjabi folk, chiptune, trap\nPunjabi folk, cinematic, devotional\nPunjabi folk, cinematic, electronic\nPunjabi folk, cinematic, epic\nPunjabi folk, cinematic, trap\nPunjabi folk, dance, pop\nPunjabi folk, electronic\nPunjabi folk, electronic dance\nPunjabi folk, electronic dance, Bhangra\nPunjabi folk, electronic dance, bhangra\nPunjabi folk, electronic dance, chiptune\nPunjabi folk, electronic dance, fusion\nPunjabi folk, electronic dance, hardstyle\nPunjabi folk, electronic dance, trap\nPunjabi folk, electronic pop\nPunjabi folk, electronic trap\nPunjabi folk, electronic, ambient\nPunjabi folk, electronic, chiptune\nPunjabi folk, electronic, cinematic\nPunjabi folk, electronic, dance\nPunjabi folk, electronic, devotional\nPunjabi folk, electronic, dholak\nPunjabi folk, electronic, dubstep\nPunjabi folk, electronic, fusion\nPunjabi folk, electronic, hardstyle\nPunjabi folk, electronic, lo-fi\nPunjabi folk, electronic, melancholic\nPunjabi folk, electronic, pop-EDM\nPunjabi folk, electronic, pop-folk\nPunjabi folk, electronic, spiritual\nPunjabi folk, electronic, trance\nPunjabi folk, electronic, trap\nPunjabi folk, electronic, world music\nPunjabi folk, flamenco, world fusion\nPunjabi folk, hard electronic\nPunjabi folk, hard electronic, dance\nPunjabi folk, hardstyle\nPunjabi folk, hardstyle, EDM\nPunjabi folk, hardstyle, electronic\nPunjabi folk, hardstyle, trance\nPunjabi folk, hardstyle, trap\nPunjabi folk, hip-hop, fusion\nPunjabi folk, hip-hop, trap\nPunjabi folk, industrial electronic\nPunjabi folk, industrial, electronic\nPunjabi folk, lo-fi hip hop\nPunjabi folk, lo-fi hip hop, R&B\nPunjabi folk, neurofunk, drum and bass\nPunjabi folk, pop, electronic\nPunjabi folk, psychedelic rock\nPunjabi folk, trap, R&B\nPunjabi folk, trap, acoustic fusion\nPunjabi folk, trap, cinematic\nPunjabi folk, trap, cinematic pop\nPunjabi folk, trap, electronic\nPunjabi folk, trap, hip-hop\nPunjabi folk, trap, lo-fi hip hop\nPunjabi folk, trap, lo-fi hip-hop\nPunjabi folk, vintage Bollywood\nPunjabi folk, world fusion\nPunjabi folk, world music, acoustic pop\nPunjabi folk, worldbeat, electronic\nPunjabi folk-fusion\nPunjabi folk-pop\nPunjabi folk-pop reggaeton\nPunjabi folk-pop, trap R&B, Hindi hip-hop\nPunjabi folk-rap\nPunjabi folk-rock\nPunjabi folk-trap\nPunjabi funk\nPunjabi funk hip-hop\nPunjabi funk-rock\nPunjabi fusion\nPunjabi fusion hip-hop\nPunjabi fusion rock\nPunjabi fusion trap\nPunjabi ghazal\nPunjabi gospel\nPunjabi hardstyle\nPunjabi hip hop\nPunjabi hip-hop\nPunjabi hip-hop G-funk\nPunjabi hip-hop Latin fusion\nPunjabi hip-hop acoustic pop\nPunjabi hip-hop boom-bap\nPunjabi hip-hop chillwave\nPunjabi hip-hop chiptune\nPunjabi hip-hop dancehall\nPunjabi hip-hop funk\nPunjabi hip-hop lo-fi\nPunjabi hip-hop trap\nPunjabi hip-hop trap metal\nPunjabi hip-hop, EDM trap\nPunjabi hip-hop, Indian pop\nPunjabi hip-hop, Latin guitar\nPunjabi hip-hop, R&B\nPunjabi hip-hop, UK drill\nPunjabi hip-hop, UK drill, trap\nPunjabi hip-hop, atmospheric trap\nPunjabi hip-hop, boom-bap\nPunjabi hip-hop, chiptune\nPunjabi hip-hop, chiptune, electronic dance\nPunjabi hip-hop, chiptune, trap\nPunjabi hip-hop, electronic, trap\nPunjabi hip-hop, gangsta rap\nPunjabi hip-hop, hard rock\nPunjabi hip-hop, hard trap\nPunjabi hip-hop, hardstyle trap\nPunjabi hip-hop, hardstyle, EDM\nPunjabi hip-hop, hardstyle, trap\nPunjabi hip-hop, reggaeton\nPunjabi hip-hop, trap\nPunjabi hip-hop, trap, Bhangra EDM\nPunjabi hip-hop, trap, R&B\nPunjabi indie\nPunjabi lo-fi\nPunjabi lo-fi hip hop\nPunjabi metal\nPunjabi nu-metal\nPunjabi pop\nPunjabi pop Afrobeats\nPunjabi pop R&B\nPunjabi pop R&B funk\nPunjabi pop R&B lo-fi hip-hop\nPunjabi pop R&B trap\nPunjabi pop R&B, hyperpop\nPunjabi pop UK hip-hop\nPunjabi pop amapiano\nPunjabi pop ambient\nPunjabi pop ballad\nPunjabi pop bhangra\nPunjabi pop chiptune\nPunjabi pop cinematic\nPunjabi pop dance-pop\nPunjabi pop dancehall\nPunjabi pop dancehall hip-hop\nPunjabi pop dancehall reggae\nPunjabi pop electronic\nPunjabi pop filmi\nPunjabi pop funk\nPunjabi pop funk disco\nPunjabi pop funk-hop\nPunjabi pop funk-rock\nPunjabi pop fusion\nPunjabi pop future bass\nPunjabi pop hip hop\nPunjabi pop hip-hop\nPunjabi pop hip-hop funk\nPunjabi pop indie pop\nPunjabi pop indie rock\nPunjabi pop jazz lounge\nPunjabi pop lo-fi\nPunjabi pop lo-fi hip hop\nPunjabi pop lo-fi hip-hop\nPunjabi pop lo-fi trap\nPunjabi pop reggae\nPunjabi pop reggae dancehall\nPunjabi pop reggaeton\nPunjabi pop rock\nPunjabi pop trap\nPunjabi pop trap EDM\nPunjabi pop trap R&B\nPunjabi pop trap chiptune\nPunjabi pop trap-R&B\nPunjabi pop, Afrobeats, dancehall\nPunjabi pop, Arabic dance\nPunjabi pop, Bhangra\nPunjabi pop, Bhangra hip hop\nPunjabi pop, Bhangra, Dancehall\nPunjabi pop, Bhangra, Desi pop\nPunjabi pop, Bhangra, EDM\nPunjabi pop, Bhangra, chiptune\nPunjabi pop, Bhangra, cinematic\nPunjabi pop, Bhangra, dance-pop\nPunjabi pop, Bhangra, dancehall\nPunjabi pop, Bhangra, electronic\nPunjabi pop, Bhangra, electronic dance\nPunjabi pop, Bhangra, fusion\nPunjabi pop, Bhangra, hip-hop\nPunjabi pop, Bhangra, hip-hop, Bollywood\nPunjabi pop, Bhangra, lo-fi\nPunjabi pop, Bhangra, lo-fi hip hop\nPunjabi pop, Bhangra, trap\nPunjabi pop, Bhangra, trap hip-hop\nPunjabi pop, Desi Hip Hop, trap\nPunjabi pop, EDM\nPunjabi pop, EDM trap\nPunjabi pop, EDM, Bhangra\nPunjabi pop, EDM, atmospheric\nPunjabi pop, EDM, cinematic\nPunjabi pop, EDM, dancehall\nPunjabi pop, EDM, hip-hop\nPunjabi pop, EDM, synth-pop\nPunjabi pop, EDM, trap\nPunjabi pop, Eurodance\nPunjabi pop, G-funk\nPunjabi pop, Hindi hip-hop, electronic dance\nPunjabi pop, Hindi pop, EDM\nPunjabi pop, Hindi pop, trap\nPunjabi pop, Hindi rap, electronic fusion\nPunjabi pop, Latin acoustic\nPunjabi pop, Latin dance\nPunjabi pop, Latin fusion\nPunjabi pop, Latin fusion, trap\nPunjabi pop, Latin pop\nPunjabi pop, Latin pop, trap\nPunjabi pop, R&B\nPunjabi pop, R&B, chillwave\nPunjabi pop, R&B, cinematic\nPunjabi pop, R&B, hip-hop\nPunjabi pop, R&B, lo-fi\nPunjabi pop, R&B, lo-fi hip-hop\nPunjabi pop, R&B, trap\nPunjabi pop, UK drill, trap\nPunjabi pop, UK garage, chiptune\nPunjabi pop, UK garage, electronic\nPunjabi pop, UK grime\nPunjabi pop, UK hip-hop\nPunjabi pop, UK hip-hop, trap\nPunjabi pop, alternative rock\nPunjabi pop, ambient ballad\nPunjabi pop, chiptune\nPunjabi pop, chiptune hip-hop\nPunjabi pop, chiptune trap\nPunjabi pop, chiptune, electro-pop\nPunjabi pop, chiptune, trance\nPunjabi pop, chiptune, trap\nPunjabi pop, cinematic orchestral\nPunjabi pop, cinematic trap\nPunjabi pop, cinematic, R&B\nPunjabi pop, cinematic, Sufi fusion\nPunjabi pop, cinematic, electronic\nPunjabi pop, cinematic, trap\nPunjabi pop, dance music\nPunjabi pop, dance, electronic\nPunjabi pop, dance-pop\nPunjabi pop, dance-pop, Bhangra\nPunjabi pop, dance-pop, cinematic\nPunjabi pop, dancehall, reggaeton\nPunjabi pop, dancehall, trap\nPunjabi pop, deep house\nPunjabi pop, deep house, dancehall\nPunjabi pop, dream pop, trap\nPunjabi pop, electro house\nPunjabi pop, electronic dance\nPunjabi pop, electronic dance music\nPunjabi pop, electronic dance, fusion\nPunjabi pop, electronic, chiptune\nPunjabi pop, electronic, dancehall\nPunjabi pop, electronic, trap\nPunjabi pop, folk fusion\nPunjabi pop, future bass\nPunjabi pop, hard rock\nPunjabi pop, hardstyle\nPunjabi pop, hardstyle, EDM\nPunjabi pop, hardstyle, trap\nPunjabi pop, hip-hop\nPunjabi pop, hip-hop, Bhangra\nPunjabi pop, hip-hop, EDM\nPunjabi pop, hip-hop, R&B\nPunjabi pop, hip-hop, chillwave\nPunjabi pop, hip-hop, chiptune\nPunjabi pop, hip-hop, electronic dance\nPunjabi pop, hip-hop, funk\nPunjabi pop, hip-hop, hyperpop\nPunjabi pop, hip-hop, trap\nPunjabi pop, liquid drum and bass\nPunjabi pop, lo-fi hip hop\nPunjabi pop, lo-fi hip hop, R&B\nPunjabi pop, lo-fi hip hop, ambient\nPunjabi pop, lo-fi hip hop, chiptune\nPunjabi pop, lo-fi hip hop, electronic fusion\nPunjabi pop, lo-fi hip hop, trap\nPunjabi pop, lo-fi hip-hop\nPunjabi pop, lo-fi trap, R&B\nPunjabi pop, modern ghazal\nPunjabi pop, nu-disco, funk\nPunjabi pop, reggae, funk\nPunjabi pop, reggaeton\nPunjabi pop, reggaeton, Latin\nPunjabi pop, reggaeton, Latin pop\nPunjabi pop, reggaeton, dancehall\nPunjabi pop, reggaeton, flamenco\nPunjabi pop, retro-funk, disco\nPunjabi pop, sad pop\nPunjabi pop, sad trap\nPunjabi pop, synth-pop, chiptune\nPunjabi pop, synth-pop, dance\nPunjabi pop, synth-pop, electronic\nPunjabi pop, trap\nPunjabi pop, trap R&B\nPunjabi pop, trap fusion, ambient\nPunjabi pop, trap pop\nPunjabi pop, trap, Afrobeats\nPunjabi pop, trap, Bhangra\nPunjabi pop, trap, EDM\nPunjabi pop, trap, R&B\nPunjabi pop, trap, ambient\nPunjabi pop, trap, atmospheric\nPunjabi pop, trap, ballad\nPunjabi pop, trap, chiptune\nPunjabi pop, trap, cinematic\nPunjabi pop, trap, devotional\nPunjabi pop, trap, dreamy synth\nPunjabi pop, trap, electronic\nPunjabi pop, trap, emotional\nPunjabi pop, trap, folk\nPunjabi pop, trap, folk fusion\nPunjabi pop, trap, fusion\nPunjabi pop, trap, hip-hop\nPunjabi pop, trap, lo-fi\nPunjabi pop, trap, lo-fi hip hop\nPunjabi pop, trap, melancholic\nPunjabi pop, trap, melodic\nPunjabi pop, trap-R&B\nPunjabi pop, trap-pop, cinematic\nPunjabi pop, vaporwave, trap\nPunjabi pop-R&B\nPunjabi pop-rap\nPunjabi pop-rock\nPunjabi pop-trap\nPunjabi protest\nPunjabi reggaeton\nPunjabi rock\nPunjabi romantic\nPunjabi soul\nPunjabi spiritual\nPunjabi trap\nPunjabi trap R&B\nPunjabi trap fusion\nPunjabi trap, acoustic ballad\nPunjabi trap, hardstyle\nPunjabi trap-pop\nQawwali\nQawwali Sufi\nQawwali fusion\nQawwali pop\nQuebec punk rock\nQuebecois country\nQuebecois folk\nQuebecois folk rock\nQuebecois folk-country\nQuebecois rock\nR&B\nR&B 90s\nR&B Afro-Latin\nR&B Afro-fusion\nR&B Afrobeat\nR&B Afrobeat Caribbean\nR&B Afrobeat Dancehall\nR&B Afrobeat Kizomba\nR&B Afrobeat Latin\nR&B Afrobeat dancehall\nR&B Afrobeat trap\nR&B Afrobeats\nR&B Afrobeats Dancehall\nR&B Afrobeats French pop\nR&B Afrobeats Gospel\nR&B Afrobeats Kizomba\nR&B Afrobeats Latin\nR&B Afrobeats Latin pop\nR&B Afrobeats Quiet Storm\nR&B Afrobeats South Asian pop\nR&B Afrobeats Trap\nR&B Afrobeats Zouk\nR&B Afrobeats dancehall\nR&B Afrobeats gospel\nR&B Afrobeats lo-fi hip-hop\nR&B Afrobeats pop\nR&B Afrobeats smooth jazz\nR&B Afrobeats soul\nR&B Afrobeats trap\nR&B Afropop\nR&B Afropop Middle Eastern\nR&B Afropop Zouk\nR&B Afropop gospel\nR&B Arabic pop\nR&B Bollywood\nR&B Bollywood fusion\nR&B Bossa Nova\nR&B C-Pop\nR&B C-pop\nR&B C-pop future bass\nR&B C-pop lo-fi hip-hop\nR&B Cantopop\nR&B Christian pop\nR&B Christmas\nR&B Christmas ballad\nR&B Christmas pop\nR&B City Pop\nR&B Dancehall\nR&B French pop\nR&B G-funk\nR&B Gospel\nR&B Gospel Hip Hop\nR&B Hip Hop Soul\nR&B Indian Pop\nR&B Indian fusion\nR&B Indian pop\nR&B Indipop\nR&B J-Pop\nR&B J-pop\nR&B J-pop chiptune\nR&B J-pop cinematic\nR&B J-pop fusion\nR&B J-pop rock\nR&B K-Pop\nR&B K-ballad\nR&B K-hip-hop\nR&B K-pop\nR&B K-pop ballad\nR&B K-pop cinematic\nR&B K-pop fusion\nR&B K-pop neo-soul\nR&B Kizomba\nR&B Kizomba Zouk\nR&B Latin\nR&B Latin Jazz\nR&B Latin Pop\nR&B Latin house\nR&B Latin jazz\nR&B Latin pop\nR&B Latin pop lo-fi hip-hop\nR&B Latin pop vaporwave\nR&B Latin trap\nR&B MPB cinematic\nR&B Mandopop\nR&B Mandopop lo-fi hip-hop\nR&B Neo-Soul\nR&B New Jack Swing\nR&B Pop\nR&B Punjabi Pop\nR&B Punjabi fusion\nR&B Punjabi pop\nR&B UK garage\nR&B UK garage hip-hop\nR&B UK hip-hop\nR&B V-Pop\nR&B West Coast\nR&B Zouk\nR&B Zouk Afrobeats\nR&B Zouk Afropop\nR&B Zouk Caribbean\nR&B Zouk Kizomba\nR&B Zouk Kompa\nR&B Zouk Quiet Storm\nR&B Zouk chiptune\nR&B Zouk conscious hip-hop\nR&B Zouk dancehall\nR&B Zouk fusion\nR&B a cappella\nR&B acid jazz\nR&B acoustic\nR&B acoustic hip-hop\nR&B acoustic pop\nR&B acoustic soul\nR&B afrobeat\nR&B afrobeats\nR&B afrobeats dancehall\nR&B afrobeats trap\nR&B bachata\nR&B ballad\nR&B ballad, K-pop, pop\nR&B ballad, Latin pop\nR&B ballad, Latin pop-rock\nR&B ballad, Mandopop, 2000s dance\nR&B ballad, Mandopop, synth-pop\nR&B ballad, melancholic pop, contemporary R&B\nR&B ballad, pop\nR&B ballad, pop-gospel\nR&B bedroom pop\nR&B big band\nR&B blues\nR&B blues rock\nR&B blues-rock\nR&B boogie\nR&B boogie-funk\nR&B boogie-woogie\nR&B boom-bap\nR&B bossa nova\nR&B boy band\nR&B chillhop\nR&B chillwave\nR&B chillwave lo-fi hip-hop\nR&B chiptune\nR&B chiptune hip-hop\nR&B chiptune synth-pop\nR&B chiptune trap\nR&B cinematic\nR&B city pop\nR&B city pop funk\nR&B city pop jazz fusion\nR&B city pop lo-fi\nR&B city pop neo-soul\nR&B city pop smooth jazz\nR&B city-pop\nR&B club\nR&B conscious hip-hop\nR&B contemporary Christian\nR&B country-dancehall\nR&B country-trap\nR&B cyberpunk\nR&B dance\nR&B dance-pop\nR&B dance-pop J-pop\nR&B dance-pop hip-hop\nR&B dancehall\nR&B dancehall afrobeats\nR&B dancehall chiptune\nR&B dancehall fusion\nR&B dancehall gospel\nR&B dancehall hip-hop\nR&B dancehall pop\nR&B dancehall reggae\nR&B dancehall zouk\nR&B dancehall-pop\nR&B deep house\nR&B deep house UK garage\nR&B dembow\nR&B disco\nR&B disco funk\nR&B doo-wop\nR&B downtempo\nR&B dream pop\nR&B drill\nR&B drum and bass\nR&B dubstep hip-hop\nR&B electro-funk\nR&B electro-pop\nR&B electronic\nR&B electronic pop\nR&B en español\nR&B folk-pop\nR&B funk\nR&B funk blues\nR&B funk blues-rock\nR&B funk city pop\nR&B funk disco\nR&B funk gospel\nR&B funk hip-hop\nR&B funk jazz\nR&B funk jazz fusion\nR&B funk neo-soul\nR&B funk pop\nR&B funk reggae\nR&B funk rock\nR&B funk soul\nR&B funk, hard rock\nR&B funk-pop\nR&B funk-pop hip-hop\nR&B funk-rock\nR&B fusion\nR&B future bass\nR&B future bass pop\nR&B future bass trap\nR&B future bass trap-soul\nR&B future bass tropical house\nR&B gospel\nR&B gospel Afrobeats\nR&B gospel Afropop\nR&B gospel Caribbean\nR&B gospel Zouk\nR&B gospel afrobeat\nR&B gospel blues\nR&B gospel dancehall\nR&B gospel funk\nR&B gospel fusion\nR&B gospel hip-hop\nR&B gospel jazz\nR&B gospel lo-fi hip-hop\nR&B gospel pop\nR&B gospel pop-rock\nR&B gospel reggae\nR&B gospel rock\nR&B gospel smooth jazz\nR&B gospel trap\nR&B gospel-pop\nR&B gospel-trap\nR&B hip hop\nR&B hip hop crossover\nR&B hip hop soul\nR&B hip-hop\nR&B hip-hop Afrobeats\nR&B hip-hop Bollywood\nR&B hip-hop C-pop\nR&B hip-hop East African\nR&B hip-hop French\nR&B hip-hop G-funk\nR&B hip-hop J-Pop\nR&B hip-hop J-pop\nR&B hip-hop Kizomba\nR&B hip-hop Latin\nR&B hip-hop Mandopop\nR&B hip-hop North African\nR&B hip-hop ambient\nR&B hip-hop chillwave\nR&B hip-hop chiptune\nR&B hip-hop cinematic\nR&B hip-hop crossover\nR&B hip-hop dancehall\nR&B hip-hop electronic\nR&B hip-hop funk\nR&B hip-hop fusion\nR&B hip-hop future bass\nR&B hip-hop gospel\nR&B hip-hop nu-metal\nR&B hip-hop pop\nR&B hip-hop pop-rock\nR&B hip-hop reggaeton\nR&B hip-hop rock\nR&B hip-hop soul\nR&B hip-hop trap\nR&B hip-hop vaporwave\nR&B hip-hop world music\nR&B hip-hop worldbeat\nR&B hip-hop, South Asian pop\nR&B hip-hop, neo-soul\nR&B holiday\nR&B house\nR&B hyperpop\nR&B indie pop\nR&B indie rock\nR&B jazz\nR&B jazz a cappella\nR&B jazz blues\nR&B jazz fusion\nR&B jazz fusion city pop\nR&B jazz gospel\nR&B jazz lounge\nR&B jazz-funk\nR&B jazz-fusion\nR&B jazz-pop\nR&B lo-fi\nR&B lo-fi Mandopop\nR&B lo-fi hip hop\nR&B lo-fi hip-hop\nR&B lo-fi hip-hop Afrobeats\nR&B lo-fi hip-hop Mandopop\nR&B lo-fi hip-hop chillwave\nR&B lo-fi hip-hop trap\nR&B lo-fi pop\nR&B lo-fi trap\nR&B lounge\nR&B lounge jazz\nR&B lounge pop\nR&B lounge-pop\nR&B lovers rock\nR&B lovers rock reggae\nR&B neo-soul\nR&B neo-soul Afrobeats\nR&B neo-soul C-pop\nR&B neo-soul French touch\nR&B neo-soul G-funk\nR&B neo-soul J-R&B\nR&B neo-soul J-pop\nR&B neo-soul K-pop\nR&B neo-soul Latin pop\nR&B neo-soul Mandopop\nR&B neo-soul UK garage\nR&B neo-soul UK hip-hop\nR&B neo-soul bedroom pop\nR&B neo-soul chill-hop\nR&B neo-soul chillhop\nR&B neo-soul chillwave\nR&B neo-soul chiptune\nR&B neo-soul city pop\nR&B neo-soul dancehall\nR&B neo-soul funk\nR&B neo-soul future bass\nR&B neo-soul future funk\nR&B neo-soul gospel\nR&B neo-soul hip-hop\nR&B neo-soul jazz-pop\nR&B neo-soul lo-fi\nR&B neo-soul lo-fi hip-hop\nR&B neo-soul lounge\nR&B neo-soul pop\nR&B neo-soul smooth jazz\nR&B neo-soul synth-pop\nR&B neo-soul trap\nR&B new jack swing\nR&B nu-disco\nR&B nu-disco city pop\nR&B nu-metal\nR&B party anthem\nR&B piano ballad\nR&B pop\nR&B pop Bollywood\nR&B pop Bollywood fusion\nR&B pop Bossa Nova\nR&B pop Brazilian\nR&B pop EDM\nR&B pop J-pop\nR&B pop Mandopop\nR&B pop Mongolian\nR&B pop a cappella\nR&B pop ballad\nR&B pop chiptune\nR&B pop city pop\nR&B pop dancehall\nR&B pop dream pop\nR&B pop electronic\nR&B pop funk\nR&B pop fusion\nR&B pop future bass\nR&B pop gospel\nR&B pop hip-hop\nR&B pop lo-fi\nR&B pop lo-fi hip-hop\nR&B pop neo-soul\nR&B pop rap\nR&B pop rock\nR&B pop trap\nR&B pop world percussion\nR&B pop, Eurodance\nR&B pop, Punjabi pop\nR&B pop, UK Hardcore, J-Core\nR&B pop, city-pop\nR&B pop, dancehall, brostep\nR&B pop, flamenco, jazz\nR&B pop, future bass\nR&B pop, hip-hop\nR&B pop, lo-fi hip-hop\nR&B pop, piano ballad, atmospheric ballad\nR&B pop-EDM\nR&B pop-ballad\nR&B pop-funk\nR&B pop-funk Christmas\nR&B pop-punk\nR&B pop-rap\nR&B pop-rap Mandopop\nR&B pop-rock\nR&B pop-rock funk\nR&B pop-soul\nR&B pop-swing\nR&B pop-trap\nR&B power ballad\nR&B protest\nR&B reggae\nR&B reggae dancehall\nR&B reggae fusion\nR&B reggae-dancehall\nR&B reggae-pop\nR&B reggaeton\nR&B rock\nR&B rock fusion\nR&B salsa\nR&B shoegaze\nR&B slow jam\nR&B slow-jam\nR&B smooth jazz\nR&B smooth jazz Latin\nR&B smooth jazz funk\nR&B smooth jazz fusion\nR&B smooth jazz gospel\nR&B smooth jazz pop\nR&B soft rock\nR&B soul\nR&B soul Latin jazz\nR&B soul blues\nR&B soul funk\nR&B soul funk-rock\nR&B soul gospel\nR&B soul gospel rock\nR&B soul hip-hop\nR&B soul jazz\nR&B soul lo-fi hip-hop\nR&B soul pop\nR&B soul reggae\nR&B soul revue\nR&B soul smooth jazz\nR&B soul trap\nR&B soul, Caribbean zouk, kompa\nR&B soul, cinematic hip-hop, gospel\nR&B soul, smooth jazz\nR&B soul, soul-rock, soft rock funk\nR&B soul, theatrical, musical theater\nR&B soul-pop\nR&B soulful house\nR&B surf-rock\nR&B synth-pop\nR&B trap\nR&B trap Afrobeat\nR&B trap Caribbean\nR&B trap French pop\nR&B trap Indian pop\nR&B trap J-pop\nR&B trap K-pop\nR&B trap Mandopop\nR&B trap North African\nR&B trap UK drill\nR&B trap afrobeat\nR&B trap afrobeats\nR&B trap ambient\nR&B trap ambient pop\nR&B trap ballad\nR&B trap boom-bap\nR&B trap chillwave\nR&B trap chiptune\nR&B trap cloud rap\nR&B trap dancehall\nR&B trap dream pop\nR&B trap drill\nR&B trap electronic\nR&B trap emo rap\nR&B trap future bass\nR&B trap gospel\nR&B trap hardstyle\nR&B trap hip-hop\nR&B trap hyperpop\nR&B trap lo-fi\nR&B trap lo-fi hip-hop\nR&B trap pop\nR&B trap pop-rap\nR&B trap reggaeton\nR&B trap rock\nR&B trap soul\nR&B trap vaporwave\nR&B trap world music\nR&B trap zouk\nR&B trap, South Asian pop\nR&B trap, lo-fi hip hop\nR&B trap, pop, South Asian fusion\nR&B trap-pop\nR&B trap-pop chiptune\nR&B trap-soul\nR&B trap-soul synth-pop\nR&B trip-hop\nR&B tropical\nR&B tropical house\nR&B tropical pop\nR&B vaporwave\nR&B vaporwave city pop\nR&B vintage\nR&B world music\nR&B worship pop\nR&B zouk\nR&B, 2-step garage\nR&B, 2000s club\nR&B, 2000s revival, soul\nR&B, 80s new jack swing, synth-pop\nR&B, 80s soul, smooth soul\nR&B, 90s K-pop\nR&B, 90s R&B, Mandarin pop\nR&B, 90s R&B, bilingual\nR&B, 90s dancehall\nR&B, 90s hip-hop\nR&B, 90s hip-hop soul\nR&B, 90s hip-hop, Filipino soul\nR&B, 90s hip-hop, festive\nR&B, 90s house\nR&B, 90s new jack swing\nR&B, 90s new jack swing, Korean R&B\nR&B, 90s new jack swing, city pop\nR&B, 90s new jack swing, festive\nR&B, 90s soul, Christmas\nR&B, 90s soul, Mandarin pop\nR&B, 90s soul, Mongolian pop\nR&B, 90s soul, festive\nR&B, 90s soul, lo-fi\nR&B, 90s video game, lo-fi hip hop\nR&B, 90s, Christmas\nR&B, Afro-Caribbean, Christmas\nR&B, Afro-Hip-Hop\nR&B, Afro-Latin, Gospel\nR&B, Afro-Latin, soul\nR&B, Afro-R&B\nR&B, Afro-fusion\nR&B, Afro-pop\nR&B, Afro-soul\nR&B, Afro-soul, jazzy\nR&B, Afrobeat\nR&B, Afrobeat, Bilingual\nR&B, Afrobeat, Dancehall\nR&B, Afrobeat, Dream Pop\nR&B, Afrobeat, French Pop\nR&B, Afrobeat, Latin\nR&B, Afrobeat, Trap\nR&B, Afrobeat, ambient\nR&B, Afrobeat, atmospheric\nR&B, Afrobeat, dream pop\nR&B, Afrobeat, gospel\nR&B, Afrobeat, lo-fi\nR&B, Afrobeat, soul\nR&B, Afrobeat, synth soul\nR&B, Afrobeats\nR&B, Afrobeats, Arabic\nR&B, Afrobeats, Christmas\nR&B, Afrobeats, French pop\nR&B, Afrobeats, Latin\nR&B, Afrobeats, Latin pop\nR&B, Afrobeats, North African\nR&B, Afrobeats, UK garage\nR&B, Afrobeats, Zouk\nR&B, Afrobeats, ambient\nR&B, Afrobeats, atmospheric\nR&B, Afrobeats, cinematic\nR&B, Afrobeats, dancehall\nR&B, Afrobeats, gospel\nR&B, Afrobeats, jazzy\nR&B, Afrobeats, lo-fi\nR&B, Afrobeats, neo-soul\nR&B, Afrobeats, pop\nR&B, Afrobeats, soul\nR&B, Afrobeats, trap\nR&B, Afrobeats-lite\nR&B, Afroswing, Dancehall\nR&B, Arabic fusion\nR&B, Arabic pop\nR&B, Arabic pop, electronic\nR&B, Arabic, hip-hop\nR&B, Asian ambient\nR&B, Bilingual, Ballad\nR&B, Bollywood\nR&B, Bollywood pop, trap\nR&B, Bossa Nova\nR&B, Brazilian\nR&B, Brazilian Funk\nR&B, Brazilian Funk, cinematic\nR&B, Brazilian Funk, lo-fi\nR&B, Brazilian funk\nR&B, Brazilian funk, ambient\nR&B, Brazilian funk, chiptune\nR&B, Brazilian funk, cinematic\nR&B, Brazilian funk, lo-fi\nR&B, Brazilian funk, soul\nR&B, Brazilian funk, trap\nR&B, Brazilian hip-hop\nR&B, Brazilian pop\nR&B, Brazilian pop, Afrobeats\nR&B, Brazilian pop, Bossa Nova\nR&B, Brazilian pop, funk carioca\nR&B, Brazilian pop, gospel\nR&B, Brazilian pop, hip-hop\nR&B, Brazilian pop, neo-soul\nR&B, Brazilian pop, samba\nR&B, Brazilian pop, soul\nR&B, Brazilian pop-funk\nR&B, Brazilian pop-soul\nR&B, Brazilian soul\nR&B, Brazilian trap\nR&B, Brazilian, baile funk\nR&B, Brazilian, chillwave\nR&B, Brazilian, lo-fi\nR&B, Brazilian, lo-fi hip-hop\nR&B, Brazilian, modern\nR&B, Brazilian, neo-soul\nR&B, Brazilian, sensual\nR&B, Brazilian, smooth\nR&B, Brazilian, soul\nR&B, Brazilian, trap\nR&B, Burmese pop\nR&B, C-pop\nR&B, C-pop, ambient\nR&B, C-pop, cinematic\nR&B, C-pop, dream pop\nR&B, C-pop, electronic\nR&B, C-pop, flamenco\nR&B, C-pop, funk\nR&B, C-pop, future bass\nR&B, C-pop, lo-fi\nR&B, C-pop, lo-fi hip hop\nR&B, C-pop, neo-soul\nR&B, C-pop, orchestral\nR&B, Cantopop, electronic\nR&B, Caribbean, Zouk\nR&B, Central Asian pop\nR&B, Central Asian, pop\nR&B, Chinese Soul\nR&B, Chinese ambient\nR&B, Chinese electronic\nR&B, Chinese folk, ambient\nR&B, Chinese fusion\nR&B, Chinese hip-hop\nR&B, Chinese hip-hop, ambient\nR&B, Chinese pop\nR&B, Chinese pop, lo-fi\nR&B, Chinese pop, lo-fi hip hop\nR&B, Chinese pop, trap\nR&B, Chinese, cinematic\nR&B, Christian hip-hop, soul\nR&B, Christmas\nR&B, Christmas pop\nR&B, Christmas, 80s\nR&B, Christmas, 80s soul\nR&B, Christmas, Korean pop\nR&B, Christmas, New Jack Swing\nR&B, Christmas, blues\nR&B, Christmas, cinematic\nR&B, Christmas, dreamy\nR&B, Christmas, early 2000s\nR&B, Christmas, early 2000s hip-hop\nR&B, Christmas, funk\nR&B, Christmas, hip-hop\nR&B, Christmas, jazz\nR&B, Christmas, jazzy\nR&B, Christmas, late 90s soul\nR&B, Christmas, melancholic\nR&B, Christmas, neo-soul\nR&B, Christmas, new jack swing\nR&B, Christmas, pop\nR&B, Christmas, slow-jam\nR&B, Christmas, smooth soul\nR&B, Christmas, soul\nR&B, Christmas, trap\nR&B, City Pop\nR&B, City Pop, J-Pop\nR&B, EDM, trap\nR&B, EDM-pop\nR&B, EDM-pop, future bass\nR&B, Eurodance, Trance\nR&B, Eurodance, house\nR&B, Filipino Pop\nR&B, French R&B, atmospheric\nR&B, French R&B, smooth hip-hop\nR&B, French hip-hop\nR&B, French pop\nR&B, French pop, 90s soul\nR&B, French pop, lo-fi hip-hop\nR&B, French rap, soul\nR&B, French soul\nR&B, French soul, ambient\nR&B, French soul, hip-hop\nR&B, French soul, trap\nR&B, French, Zulu\nR&B, French, atmospheric\nR&B, G-funk\nR&B, G-funk, Christmas\nR&B, G-funk, West Coast hip-hop\nR&B, G-funk, contemporary\nR&B, G-funk, hip-hop\nR&B, G-funk, vaporwave\nR&B, German pop\nR&B, Haitian Creole, acoustic\nR&B, Haitian Creole, lo-fi hip hop\nR&B, Haitian Creole, melancholic\nR&B, Haitian Creole, smooth\nR&B, Hindi hip hop, cinematic\nR&B, Hindi pop\nR&B, Hip Hop Soul\nR&B, Hip Hop Soul, Neo-Soul\nR&B, Hip Hop Soul, New Jack Swing\nR&B, Hip Hop, Neo-Soul\nR&B, Hip Hop, Soul\nR&B, Hip Hop-Soul\nR&B, Hip Hop-Soul, Neo-Soul\nR&B, Indian classical\nR&B, Indian folk, ambient\nR&B, Indian fusion, lo-fi hip hop\nR&B, Indian pop\nR&B, Indian pop, dream pop\nR&B, Indian pop, lo-fi\nR&B, Indian pop, lo-fi hip-hop\nR&B, Indian pop, trap\nR&B, Indonesian pop\nR&B, Italian hip-hop, soul\nR&B, J-Pop\nR&B, J-Pop, neo-soul\nR&B, J-pop\nR&B, J-pop, chiptune\nR&B, J-pop, jazz-infused\nR&B, J-pop, neo-soul\nR&B, J-pop, power ballad\nR&B, J-pop, trap\nR&B, J-pop, video game music\nR&B, Jazzy, Smooth\nR&B, K-Pop\nR&B, K-Pop, Latin\nR&B, K-Pop, hip-hop\nR&B, K-Pop, neo-soul\nR&B, K-R&B, indie pop\nR&B, K-hip-hop\nR&B, K-hip-hop, cinematic\nR&B, K-hip-hop, lo-fi\nR&B, K-pop\nR&B, K-pop, alternative rock\nR&B, K-pop, ambient\nR&B, K-pop, cinematic\nR&B, K-pop, dream pop\nR&B, K-pop, early 2000s\nR&B, K-pop, hip-hop\nR&B, K-pop, lo-fi\nR&B, K-pop, lo-fi hip hop\nR&B, K-pop, neo-soul\nR&B, K-pop, new jack swing\nR&B, K-pop, trap\nR&B, Kizomba\nR&B, Kizomba, 2000s\nR&B, Kizomba, Afro-pop\nR&B, Kizomba, Zouk\nR&B, Kizomba, ambient\nR&B, Kizomba, electronic\nR&B, Kizomba, pop\nR&B, Korean R&B\nR&B, Korean hip hop\nR&B, Korean pop\nR&B, Latin R&B\nR&B, Latin groove\nR&B, Latin hip hop\nR&B, Latin hip-hop\nR&B, Latin jazz\nR&B, Latin jazz, cinematic pop\nR&B, Latin jazz, funk\nR&B, Latin jazz, soul\nR&B, Latin pop\nR&B, Latin pop, ambient\nR&B, Latin pop, cinematic\nR&B, Latin pop, club\nR&B, Latin pop, dancehall\nR&B, Latin pop, early 2000s\nR&B, Latin pop, flamenco fusion\nR&B, Latin pop, hip-hop\nR&B, Latin pop, lo-fi\nR&B, Latin pop, reggaeton\nR&B, Latin pop, soul\nR&B, Latin pop, trap\nR&B, Latin pop, trap-soul\nR&B, Latin salsa\nR&B, Latin soul\nR&B, Latin soul, world music\nR&B, Latin trap\nR&B, Latin trap, lo-fi\nR&B, Latin, Afro-pop\nR&B, Latin, Bossa Nova\nR&B, Latin, Brazilian\nR&B, Latin, C-pop\nR&B, Latin, South Asian\nR&B, Latin, acoustic\nR&B, Latin, ambient\nR&B, Latin, ballad\nR&B, Latin, bilingual\nR&B, Latin, boogie-woogie\nR&B, Latin, dream pop\nR&B, Latin, early 2000s\nR&B, Latin, gospel\nR&B, Latin, hip-hop\nR&B, Latin, jazz\nR&B, Latin, lo-fi\nR&B, Latin, smooth\nR&B, Latin, soul\nR&B, Latin, synth groove\nR&B, Latin, trap\nR&B, Latin, world music\nR&B, Latin-influenced\nR&B, Latin-influenced, UK rap\nR&B, Latin-influenced, ambient\nR&B, Latin-influenced, bilingual\nR&B, Latin-influenced, hip-hop\nR&B, Latin-influenced, modern\nR&B, Latin-influenced, smooth\nR&B, Latin-pop\nR&B, Latin-pop, hip-hop\nR&B, Lusophone, ambient\nR&B, MPB\nR&B, MPB, smooth jazz\nR&B, MPB, soul\nR&B, Malay hip-hop\nR&B, Mandarin R&B, chill\nR&B, Mandarin R&B, lo-fi\nR&B, Mandarin R&B, lo-fi hip hop\nR&B, Mandarin hip hop\nR&B, Mandarin hip hop, Latin pop\nR&B, Mandarin hip hop, cinematic soul\nR&B, Mandarin hip hop, lo-fi\nR&B, Mandarin hip-hop\nR&B, Mandarin pop\nR&B, Mandarin pop, acoustic ballad\nR&B, Mandarin pop, groove\nR&B, Mandarin pop, lo-fi\nR&B, Mandarin pop, trap\nR&B, Mandarin, lo-fi\nR&B, Mandarin, smooth\nR&B, Mandarin, trap\nR&B, Mandopop\nR&B, Mandopop, 2000s\nR&B, Mandopop, atmospheric\nR&B, Mandopop, electronic\nR&B, Mandopop, funk\nR&B, Mandopop, hip-hop\nR&B, Mandopop, jazz-infused\nR&B, Mandopop, lo-fi hip hop\nR&B, Mandopop, pop-rap\nR&B, Mandopop, soul\nR&B, Mandopop, trap-soul\nR&B, Middle Eastern fusion\nR&B, Middle Eastern pop\nR&B, Middle Eastern, cinematic\nR&B, Middle Eastern, emotive\nR&B, Middle Eastern, hip-hop\nR&B, Middle Eastern, pop\nR&B, Middle Eastern, trap\nR&B, Moombahton\nR&B, Motown\nR&B, Neo-Soul, J-Pop\nR&B, New Jack Swing\nR&B, New Jack Swing, 2000s\nR&B, New Jack Swing, 2000s club\nR&B, New Jack Swing, 2000s pop\nR&B, New Jack Swing, 90s\nR&B, New Jack Swing, 90s slow jam\nR&B, New Jack Swing, Christmas\nR&B, New Jack Swing, G-funk\nR&B, New Jack Swing, Hip Hop Soul\nR&B, New Jack Swing, K-pop\nR&B, New Jack Swing, Mandopop\nR&B, New Jack Swing, Quiet Storm\nR&B, New Jack Swing, cinematic\nR&B, New Jack Swing, club\nR&B, New Jack Swing, dancehall\nR&B, New Jack Swing, early 2000s\nR&B, New Jack Swing, festive\nR&B, New Jack Swing, funk\nR&B, New Jack Swing, hip-hop\nR&B, New Jack Swing, late 90s\nR&B, New Jack Swing, late-90s\nR&B, New Jack Swing, pop\nR&B, New Jack Swing, pop-R&B\nR&B, New Jack Swing, smooth jazz\nR&B, New Jack Swing, theatrical\nR&B, New Orleans jazz, Dixieland\nR&B, New Orleans, blues\nR&B, Pop, New Jack Swing\nR&B, Punjabi hip-hop\nR&B, Punjabi pop, dream pop\nR&B, Punjabi pop, electronic\nR&B, Punjabi pop, lo-fi\nR&B, Punjabi pop, trap\nR&B, Punjabi, acoustic fusion\nR&B, Punjabi, atmospheric\nR&B, Punjabi, dreamy\nR&B, Quiet Storm\nR&B, Quiet Storm, 80s soul\nR&B, Quiet Storm, Smooth Soul\nR&B, Romanian hip-hop\nR&B, South African\nR&B, South Asian fusion\nR&B, South Asian pop\nR&B, South Asian, atmospheric\nR&B, South Asian, contemporary\nR&B, South Asian, dreamy\nR&B, South Indian folk, trap\nR&B, South Indian fusion\nR&B, Southern Hip Hop\nR&B, Southern hip-hop\nR&B, Southern hip-hop, club\nR&B, Southern hip-hop, synth soul\nR&B, Southern pop\nR&B, Southern soul, funk\nR&B, Spanish pop\nR&B, Spanish-influenced, acoustic\nR&B, Spanish-style, early 2000s\nR&B, Spanish-style, hip-hop\nR&B, T-Pop, trap\nR&B, Tamil soul\nR&B, Thai pop\nR&B, Thai rap, soul\nR&B, Thai vibe, atmospheric\nR&B, Turkish pop\nR&B, UK drill\nR&B, UK drill, lo-fi\nR&B, UK drill, lo-fi hip hop\nR&B, UK drill, psychedelic\nR&B, UK drill, trap\nR&B, UK garage\nR&B, UK garage, 2-step\nR&B, UK garage, 2000s club\nR&B, UK garage, acoustic\nR&B, UK garage, ambient\nR&B, UK garage, atmospheric\nR&B, UK garage, breakbeat\nR&B, UK garage, dancehall\nR&B, UK garage, dreamy\nR&B, UK garage, early 2000s\nR&B, UK garage, future bass\nR&B, UK garage, late-90s\nR&B, UK garage, lo-fi\nR&B, UK garage, lo-fi hip hop\nR&B, UK garage, soul\nR&B, UK garage, trap soul\nR&B, UK hip hop, ambient\nR&B, UK hip-hop\nR&B, UK hip-hop, ambient\nR&B, UK hip-hop, cinematic\nR&B, UK hip-hop, soul\nR&B, UK hip-hop, vaporwave\nR&B, West Coast\nR&B, West Coast hip hop\nR&B, West Coast hip hop, mid-2000s club\nR&B, West Coast hip-hop\nR&B, West Coast hip-hop, lo-fi\nR&B, West Coast, Christmas\nR&B, West Coast, lo-fi\nR&B, Zouk\nR&B, Zouk, Afrobeats\nR&B, Zouk, Caribbean\nR&B, Zouk, Kizomba\nR&B, Zouk, Quiet Storm\nR&B, Zouk, ambient\nR&B, Zouk, dancehall\nR&B, Zouk, early 2000s\nR&B, Zouk, neo-soul\nR&B, Zouk, pop\nR&B, acoustic soul\nR&B, acoustic, Mandarin pop\nR&B, acoustic, melancholic\nR&B, acoustic, multilingual\nR&B, acoustic, romantic\nR&B, adult contemporary\nR&B, adult contemporary, cinematic\nR&B, adult contemporary, soul\nR&B, afrobeat\nR&B, afrobeat, dancehall\nR&B, afrobeats\nR&B, afrobeats, dancehall\nR&B, alternative pop\nR&B, alternative rock\nR&B, alternative soul\nR&B, ambient\nR&B, ambient hip-hop\nR&B, ambient pop\nR&B, ambient pop, future garage\nR&B, ambient pop, gospel\nR&B, ambient pop, hip-hop\nR&B, ambient soul\nR&B, ambient trap\nR&B, ambient, Arabic\nR&B, ambient, Arabic fusion\nR&B, ambient, Arabic hip hop\nR&B, ambient, Arabic pop\nR&B, ambient, Brazilian\nR&B, ambient, C-pop\nR&B, ambient, Chinese\nR&B, ambient, Chinese hip hop\nR&B, ambient, Chinese pop\nR&B, ambient, Chinese soul\nR&B, ambient, Chinese urban\nR&B, ambient, Christmas\nR&B, ambient, Filipino\nR&B, ambient, French pop\nR&B, ambient, Hawaiian soul\nR&B, ambient, Indian pop\nR&B, ambient, Indonesian\nR&B, ambient, J-pop\nR&B, ambient, K-pop\nR&B, ambient, Kazakh pop\nR&B, ambient, Korean\nR&B, ambient, Korean pop\nR&B, ambient, Latin\nR&B, ambient, Mandarin\nR&B, ambient, Mandarin pop\nR&B, ambient, Mongolian\nR&B, ambient, Mongolian pop\nR&B, ambient, Portuguese soul\nR&B, ambient, Sinhala pop\nR&B, ambient, Spanish\nR&B, ambient, Thai pop\nR&B, ambient, Vietnamese R&B\nR&B, ambient, West African\nR&B, ambient, Zulu soul\nR&B, ambient, bilingual\nR&B, ambient, blues-rock\nR&B, ambient, chill\nR&B, ambient, chopped and screwed\nR&B, ambient, cinematic\nR&B, ambient, downtempo\nR&B, ambient, dream pop\nR&B, ambient, dreamy\nR&B, ambient, electronic\nR&B, ambient, emotional\nR&B, ambient, ethereal\nR&B, ambient, experimental\nR&B, ambient, future bass\nR&B, ambient, future soul\nR&B, ambient, glitch\nR&B, ambient, gospel\nR&B, ambient, hip hop\nR&B, ambient, hip-hop\nR&B, ambient, live performance\nR&B, ambient, lo-fi\nR&B, ambient, lo-fi hip hop\nR&B, ambient, melancholic\nR&B, ambient, neo-soul\nR&B, ambient, new-age\nR&B, ambient, psychedelic\nR&B, ambient, rock\nR&B, ambient, soul\nR&B, ambient, traditional South Asian\nR&B, ambient, trap\nR&B, ambient, trap-soul\nR&B, ambient, tropical house\nR&B, ambient, vaporwave\nR&B, ambient, world fusion\nR&B, anime soundtrack\nR&B, atmospheric\nR&B, atmospheric hip-hop\nR&B, atmospheric pop\nR&B, atmospheric pop, hip-hop\nR&B, atmospheric pop, trap\nR&B, atmospheric trap\nR&B, atmospheric, Afrikaans hip-hop\nR&B, atmospheric, C-pop\nR&B, atmospheric, Chinese\nR&B, atmospheric, French\nR&B, atmospheric, French R&B\nR&B, atmospheric, French hip-hop\nR&B, atmospheric, French soul\nR&B, atmospheric, Jamaican Patois\nR&B, atmospheric, Mandarin\nR&B, atmospheric, Mandarin hip-hop\nR&B, atmospheric, Mandarin pop\nR&B, atmospheric, Mandarin rap\nR&B, atmospheric, Middle Eastern\nR&B, atmospheric, Portuguese\nR&B, atmospheric, bilingual\nR&B, atmospheric, cinematic\nR&B, atmospheric, deep bass\nR&B, atmospheric, deep house\nR&B, atmospheric, downtempo\nR&B, atmospheric, dreamy\nR&B, atmospheric, electronic\nR&B, atmospheric, emotional\nR&B, atmospheric, experimental\nR&B, atmospheric, hip-hop\nR&B, atmospheric, lo-fi\nR&B, atmospheric, melancholic\nR&B, atmospheric, melodic\nR&B, atmospheric, oud-inspired\nR&B, atmospheric, rock\nR&B, atmospheric, sensual\nR&B, atmospheric, soul\nR&B, atmospheric, soulful\nR&B, atmospheric, trap\nR&B, atmospheric, trap soul\nR&B, atmospheric, trap-influenced\nR&B, atmospheric, urban\nR&B, baile funk\nR&B, baile funk, reggaeton\nR&B, ballad, 90s style\nR&B, ballad, Punjabi pop\nR&B, baroque pop, soul\nR&B, bass music, electronic\nR&B, beatbox, a cappella\nR&B, bedroom pop\nR&B, big band\nR&B, big band jazz\nR&B, big band, Christmas\nR&B, big band, holiday\nR&B, big band, soul\nR&B, big room house, hardstyle\nR&B, bilingual\nR&B, bilingual, ambient\nR&B, bilingual, atmospheric\nR&B, bilingual, ballad\nR&B, bilingual, chill\nR&B, bilingual, dreamy\nR&B, bilingual, electronic\nR&B, bilingual, funk\nR&B, bilingual, lo-fi\nR&B, bilingual, melancholic\nR&B, bilingual, modern\nR&B, bilingual, moody\nR&B, bilingual, smooth\nR&B, bilingual, synth funk\nR&B, bilingual, synth groove\nR&B, bilingual, synth pop\nR&B, bilingual, synth soul\nR&B, bilingual, synth-pop\nR&B, bluegrass, country-infused\nR&B, blues\nR&B, blues rock\nR&B, blues, Christmas\nR&B, blues, ambient\nR&B, blues, soul\nR&B, blues-rock\nR&B, blues-rock, Latin\nR&B, blues-rock, ambient\nR&B, blues-rock, contemporary\nR&B, body percussion\nR&B, boogie-funk\nR&B, boogie-woogie\nR&B, boogie-woogie, gospel\nR&B, boogie-woogie, jump blues\nR&B, boogie-woogie, piano rock\nR&B, boogie-woogie, soul\nR&B, boom-bap\nR&B, boom-bap, 2000s style\nR&B, boom-bap, Latin\nR&B, boom-bap, Mandarin\nR&B, boom-bap, Mandarin soul\nR&B, boom-bap, West Coast\nR&B, boom-bap, atmospheric\nR&B, boom-bap, cinematic\nR&B, boom-bap, hip-hop\nR&B, boom-bap, lo-fi\nR&B, boom-bap, lo-fi hip hop\nR&B, boom-bap, smooth\nR&B, boom-bap, soul\nR&B, boom-bap, soulful\nR&B, boom-bap, vaporwave\nR&B, bossa nova\nR&B, bossa nova, lo-fi\nR&B, brass, anthemic\nR&B, breakbeat\nR&B, breakbeat, jungle\nR&B, breakcore\nR&B, breakcore, drum and bass\nR&B, brostep\nR&B, chill hop, C-pop\nR&B, chill hop, festive\nR&B, chill pop\nR&B, chill trap\nR&B, chill trap, pop\nR&B, chill, Thai pop\nR&B, chill, atmospheric\nR&B, chill, bilingual\nR&B, chill, jazzy\nR&B, chill, modern\nR&B, chill, trap\nR&B, chill, urban\nR&B, chill-hop\nR&B, chillwave\nR&B, chillwave, Indian pop\nR&B, chillwave, electronic\nR&B, chillwave, electronic pop\nR&B, chillwave, gospel\nR&B, chillwave, neo-soul\nR&B, chillwave, pop\nR&B, chillwave, pop-R&B\nR&B, chillwave, smooth house\nR&B, chillwave, synth-pop\nR&B, chillwave, trap-soul\nR&B, chillwave, vaporwave\nR&B, chiptune, British pop\nR&B, chiptune, K-pop\nR&B, chiptune, ambient\nR&B, chiptune, bilingual\nR&B, chiptune, dance\nR&B, chiptune, dance-pop\nR&B, chiptune, dreamy\nR&B, chiptune, early 2000s\nR&B, chiptune, electronic\nR&B, chiptune, hip-hop\nR&B, chiptune, hyperpop\nR&B, chiptune, lo-fi hip hop\nR&B, chiptune, melancholic\nR&B, chiptune, retro-futurism\nR&B, chiptune, soul\nR&B, chiptune, synth-pop\nR&B, chiptune, synthpop\nR&B, chiptune, trap\nR&B, chiptune, urban pop\nR&B, chopped and screwed\nR&B, choral, pop\nR&B, cinematic\nR&B, cinematic hip-hop\nR&B, cinematic pop\nR&B, cinematic pop, Indian classical\nR&B, cinematic pop, K-pop\nR&B, cinematic soul\nR&B, cinematic, 2000s\nR&B, cinematic, 80s soul\nR&B, cinematic, 80s synth\nR&B, cinematic, 90s soul\nR&B, cinematic, Afro-pop\nR&B, cinematic, Caribbean\nR&B, cinematic, Christmas\nR&B, cinematic, French pop\nR&B, cinematic, Haitian Creole\nR&B, cinematic, Hindi pop\nR&B, cinematic, Indian fusion\nR&B, cinematic, Indonesian\nR&B, cinematic, K-pop\nR&B, cinematic, Latin hip-hop\nR&B, cinematic, Mandarin pop\nR&B, cinematic, Mandarin soul\nR&B, cinematic, Portuguese\nR&B, cinematic, Portuguese soul\nR&B, cinematic, Spanish-influenced\nR&B, cinematic, UK rap\nR&B, cinematic, acoustic\nR&B, cinematic, alternative\nR&B, cinematic, ambient\nR&B, cinematic, ballad\nR&B, cinematic, baroque pop\nR&B, cinematic, bilingual\nR&B, cinematic, chiptune\nR&B, cinematic, dance-pop\nR&B, cinematic, dream pop\nR&B, cinematic, dreamy\nR&B, cinematic, early 2000s\nR&B, cinematic, electronic\nR&B, cinematic, emotional\nR&B, cinematic, fantasy\nR&B, cinematic, gospel\nR&B, cinematic, hip-hop\nR&B, cinematic, jazz fusion\nR&B, cinematic, late-90s\nR&B, cinematic, lo-fi\nR&B, cinematic, lo-fi hip hop\nR&B, cinematic, modern\nR&B, cinematic, new jack swing\nR&B, cinematic, orchestral\nR&B, cinematic, playful\nR&B, cinematic, pop\nR&B, cinematic, pop-rap\nR&B, cinematic, shoegaze\nR&B, cinematic, soul\nR&B, cinematic, soulful\nR&B, cinematic, synth\nR&B, cinematic, synth-pop\nR&B, cinematic, trap\nR&B, cinematic, trap-soul\nR&B, cinematic, vaporwave\nR&B, city pop\nR&B, city pop, J-pop\nR&B, city pop, K-R&B\nR&B, city pop, K-pop\nR&B, city pop, funk\nR&B, city pop, neo-soul\nR&B, city pop, nu-disco\nR&B, city pop, synth-pop\nR&B, city-pop\nR&B, classical fusion\nR&B, classical, cinematic\nR&B, classical, lo-fi hip hop\nR&B, cloud rap\nR&B, cloud rap, electronic\nR&B, cloud rap, emo trap\nR&B, cloud rap, experimental\nR&B, cloud rap, lo-fi\nR&B, cloud rap, lo-fi hip-hop\nR&B, cloud rap, trap\nR&B, cloud rap, trap-soul\nR&B, club, 2000s\nR&B, club, Latin pop\nR&B, club, early 2000s\nR&B, club, electronic\nR&B, club, funk\nR&B, club, hip-hop\nR&B, club, mid-2000s\nR&B, club, soul\nR&B, club, synth\nR&B, club, trap\nR&B, conscious hip-hop\nR&B, conscious hip-hop, ambient\nR&B, conscious hip-hop, introspective\nR&B, conscious hip-hop, lo-fi\nR&B, conscious hip-hop, neo-soul\nR&B, conscious hip-hop, soul\nR&B, contemporary, dreamy\nR&B, cumbia, upbeat\nR&B, dance, early 2000s\nR&B, dance-pop\nR&B, dance-pop, 90s style\nR&B, dance-pop, EDM\nR&B, dance-pop, K-pop\nR&B, dance-pop, New Jack Swing\nR&B, dance-pop, UK garage\nR&B, dance-pop, ambient\nR&B, dance-pop, cinematic\nR&B, dance-pop, early 2000s\nR&B, dance-pop, gospel\nR&B, dance-pop, hip-hop\nR&B, dance-pop, jazz-infused\nR&B, dance-pop, late 90s\nR&B, dance-pop, late-90s\nR&B, dance-pop, live performance\nR&B, dance-pop, lo-fi R&B\nR&B, dance-pop, theatrical\nR&B, dancehall\nR&B, dancehall, Afrobeats\nR&B, dancehall, Mandarin pop\nR&B, dancehall, afrobeat\nR&B, dancehall, afrobeats\nR&B, dancehall, breakbeat\nR&B, dancehall, chiptune\nR&B, dancehall, early 2000s\nR&B, dancehall, lo-fi\nR&B, dancehall, reggae\nR&B, dancehall, reggaeton\nR&B, dancehall, soul\nR&B, dancehall, tropical\nR&B, dancehall, vaporwave\nR&B, dancehall-pop\nR&B, dark pop, electronic\nR&B, dark pop, trap\nR&B, deep house\nR&B, deep house, UK garage\nR&B, deep house, dance-pop\nR&B, deep house, electronic\nR&B, deep house, future bass\nR&B, deep house, lo-fi hip-hop\nR&B, deep house, synth-pop\nR&B, deep house, tropical house\nR&B, digital reggae, lovers rock\nR&B, disco, funk\nR&B, doo-wop\nR&B, doo-wop, gospel\nR&B, doo-wop, soul\nR&B, doo-wop, vocal jazz\nR&B, downtempo, ambient\nR&B, downtempo, fusion\nR&B, downtempo, soulful trap\nR&B, downtempo, trap\nR&B, dream pop\nR&B, dream pop, C-pop\nR&B, dream pop, Chinese ambient\nR&B, dream pop, Chinese hip-hop\nR&B, dream pop, Chinese pop\nR&B, dream pop, Christmas\nR&B, dream pop, French rap\nR&B, dream pop, K-R&B\nR&B, dream pop, K-pop\nR&B, dream pop, Latin R&B\nR&B, dream pop, Mandarin\nR&B, dream pop, Mandarin pop\nR&B, dream pop, Tamil soul\nR&B, dream pop, ambient\nR&B, dream pop, atmospheric\nR&B, dream pop, bilingual\nR&B, dream pop, cinematic\nR&B, dream pop, contemporary pop\nR&B, dream pop, electronic\nR&B, dream pop, gospel\nR&B, dream pop, hip-hop\nR&B, dream pop, indie pop\nR&B, dream pop, indie rock\nR&B, dream pop, jazz-infused\nR&B, dream pop, lo-fi\nR&B, dream pop, lo-fi hip hop\nR&B, dream pop, new jack swing\nR&B, dream pop, pop\nR&B, dream pop, rock\nR&B, dream pop, soul\nR&B, dream pop, trap\nR&B, dream-pop\nR&B, dream-pop, cinematic hip-hop\nR&B, dreamy\nR&B, dreamy lo-fi\nR&B, dreamy synth\nR&B, dreamy, Christmas\nR&B, dreamy, Korean hip hop\nR&B, dreamy, Mandarin\nR&B, dreamy, Mandarin pop\nR&B, dreamy, Portuguese\nR&B, dreamy, Portuguese soul\nR&B, dreamy, Thai\nR&B, dreamy, Thai pop\nR&B, dreamy, Vietnamese\nR&B, dreamy, ambient\nR&B, dreamy, atmospheric\nR&B, dreamy, bilingual\nR&B, dreamy, downtempo\nR&B, dreamy, electronic\nR&B, dreamy, hip-hop\nR&B, dreamy, jazzy\nR&B, dreamy, lo-fi\nR&B, dreamy, melancholic\nR&B, dreamy, neo-soul\nR&B, dreamy, romantic\nR&B, dreamy, soulful\nR&B, dreamy, trap\nR&B, drum and bass\nR&B, drum and bass, ambient\nR&B, drum and bass, hip hop\nR&B, drum and bass, neo-soul\nR&B, dubstep, electronic\nR&B, dubstep, future bass\nR&B, dubstep, pop\nR&B, early 2000s\nR&B, early 2000s K-Pop\nR&B, early 2000s K-pop\nR&B, early 2000s K-pop, hip-hop\nR&B, early 2000s boy band\nR&B, early 2000s hip-hop\nR&B, early 2000s hip-hop, Latin groove\nR&B, early 2000s hip-hop, club\nR&B, early 2000s hip-hop, festive\nR&B, early 2000s pop\nR&B, early 2000s pop, cinematic\nR&B, early 2000s pop, club\nR&B, early 2000s pop, dance\nR&B, early 2000s pop, dancehall\nR&B, early 2000s pop, festive\nR&B, early 2000s pop, hip-hop\nR&B, early 2000s pop, holiday\nR&B, early 2000s, Christmas\nR&B, early 2000s, German R&B\nR&B, early 2000s, Indian fusion\nR&B, early 2000s, J-R&B\nR&B, early 2000s, J-pop\nR&B, early 2000s, Mandarin pop\nR&B, early 2000s, Middle Eastern fusion\nR&B, early 2000s, Turkish pop\nR&B, early 2000s, atmospheric\nR&B, early 2000s, bilingual\nR&B, early 2000s, chiptune\nR&B, early 2000s, club\nR&B, early 2000s, dance\nR&B, early 2000s, dancehall\nR&B, early 2000s, gospel\nR&B, early 2000s, hip-hop\nR&B, early 2000s, pop\nR&B, early 2000s, soul\nR&B, early 2000s, soulful\nR&B, early 2000s, summer vibe\nR&B, early rock and roll\nR&B, electro house\nR&B, electro-pop, synth-funk\nR&B, electronic\nR&B, electronic pop\nR&B, electronic pop, future bass\nR&B, electronic rock\nR&B, electronic, C-pop\nR&B, electronic, Dutch\nR&B, electronic, J-pop\nR&B, electronic, K-pop\nR&B, electronic, Latin\nR&B, electronic, Mandarin pop\nR&B, electronic, Mandopop\nR&B, electronic, South Asian fusion\nR&B, electronic, Thai pop\nR&B, electronic, ambient\nR&B, electronic, anthemic\nR&B, electronic, atmospheric\nR&B, electronic, bilingual\nR&B, electronic, breakbeat\nR&B, electronic, cinematic\nR&B, electronic, classical fusion\nR&B, electronic, club\nR&B, electronic, contemporary\nR&B, electronic, dance-pop\nR&B, electronic, deep house\nR&B, electronic, dream pop\nR&B, electronic, dreamy\nR&B, electronic, experimental\nR&B, electronic, funk\nR&B, electronic, future bass\nR&B, electronic, future pop\nR&B, electronic, genre-bending\nR&B, electronic, glitch\nR&B, electronic, global\nR&B, electronic, hip hop\nR&B, electronic, hip-hop\nR&B, electronic, industrial\nR&B, electronic, jazz\nR&B, electronic, lo-fi\nR&B, electronic, lo-fi hip hop\nR&B, electronic, melancholic\nR&B, electronic, modern\nR&B, electronic, pop\nR&B, electronic, pop-rock\nR&B, electronic, psychedelic\nR&B, electronic, rock\nR&B, electronic, shoegaze\nR&B, electronic, soul\nR&B, electronic, spy theme\nR&B, electronic, synth pop\nR&B, electronic, synthwave\nR&B, electronic, trap\nR&B, electronic, tribal\nR&B, electronic, vaporwave\nR&B, electronic, world fusion\nR&B, emo rap\nR&B, emo rap, funk\nR&B, emo rap, lo-fi hip-hop\nR&B, emo rap, pop-rap\nR&B, emo rap, trap\nR&B, ethereal, cinematic\nR&B, experimental electronic\nR&B, experimental electronic, acoustic\nR&B, experimental hip-hop, electronic\nR&B, experimental pop\nR&B, experimental trap\nR&B, experimental, electronic\nR&B, experimental, industrial hip-hop\nR&B, festive\nR&B, festive, Mandarin pop\nR&B, festive, cinematic\nR&B, festive, early 2000s\nR&B, festive, funk\nR&B, festive, hip-hop\nR&B, festive, lo-fi\nR&B, festive, modern\nR&B, festive, smooth\nR&B, festive, soul\nR&B, festive, soulful\nR&B, festive, trap\nR&B, flamenco fusion\nR&B, flamenco, French pop\nR&B, flamenco, trap\nR&B, folk-country, soul\nR&B, folk-rock, soul\nR&B, funk rock\nR&B, funk soul, holiday\nR&B, funk, Christmas\nR&B, funk, J-pop\nR&B, funk, bilingual\nR&B, funk, city pop\nR&B, funk, disco\nR&B, funk, early 2000s\nR&B, funk, electronic\nR&B, funk, gospel\nR&B, funk, hip-hop\nR&B, funk, jazz fusion\nR&B, funk, live\nR&B, funk, multilingual\nR&B, funk, neo-soul\nR&B, funk, new jack swing\nR&B, funk, pop\nR&B, funk, pop, soul\nR&B, funk, psychedelic\nR&B, funk, soul\nR&B, funk, trap\nR&B, funk-pop\nR&B, funk-pop, Christmas\nR&B, funk-pop, early 2000s\nR&B, future bass\nR&B, future bass, Chinese hip hop\nR&B, future bass, Chinese soul\nR&B, future bass, UK garage\nR&B, future bass, ambient\nR&B, future bass, atmospheric\nR&B, future bass, chill trap\nR&B, future bass, cinematic\nR&B, future bass, dance-pop\nR&B, future bass, electronic\nR&B, future bass, electronic pop\nR&B, future bass, experimental\nR&B, future bass, gospel\nR&B, future bass, hardstyle\nR&B, future bass, hip-hop\nR&B, future bass, hyperpop\nR&B, future bass, lo-fi\nR&B, future bass, lo-fi hip hop\nR&B, future bass, neo-soul\nR&B, future bass, pop\nR&B, future bass, pop-EDM\nR&B, future bass, pop-R&B\nR&B, future bass, pop-hip hop\nR&B, future bass, soul\nR&B, future bass, trap\nR&B, future bass, trap-soul\nR&B, ghazal, electronic\nR&B, glitch hop, soulful\nR&B, glitch, ambient\nR&B, glitch, jazz\nR&B, glitch-hop, experimental bass\nR&B, glitch-hop, experimental hip-hop\nR&B, global pop\nR&B, gospel\nR&B, gospel hip-hop\nR&B, gospel rock\nR&B, gospel, 80s funk\nR&B, gospel, 90s R&B\nR&B, gospel, 90s dance-pop\nR&B, gospel, 90s hip-hop\nR&B, gospel, 90s soul\nR&B, gospel, Afro-Latin\nR&B, gospel, Afro-pop\nR&B, gospel, Afro-soul\nR&B, gospel, Afrobeat\nR&B, gospel, Afrobeats\nR&B, gospel, Afropop\nR&B, gospel, Christmas\nR&B, gospel, Christmas ballad\nR&B, gospel, K-pop\nR&B, gospel, Latin\nR&B, gospel, Latin pop\nR&B, gospel, UK hip-hop\nR&B, gospel, adult contemporary\nR&B, gospel, afro-soul\nR&B, gospel, afrobeat\nR&B, gospel, afrobeats\nR&B, gospel, ambient\nR&B, gospel, anthemic\nR&B, gospel, atmospheric\nR&B, gospel, ballad\nR&B, gospel, boom-bap hip-hop\nR&B, gospel, cinematic\nR&B, gospel, city pop\nR&B, gospel, conscious hip-hop\nR&B, gospel, contemporary\nR&B, gospel, contemporary Christian\nR&B, gospel, dance-pop\nR&B, gospel, dancehall\nR&B, gospel, early 2000s\nR&B, gospel, early 2000s pop\nR&B, gospel, electronic\nR&B, gospel, experimental\nR&B, gospel, festive\nR&B, gospel, funk\nR&B, gospel, hip-hop\nR&B, gospel, holiday\nR&B, gospel, inspirational\nR&B, gospel, jazz\nR&B, gospel, jazz fusion\nR&B, gospel, jazz-fusion\nR&B, gospel, live performance\nR&B, gospel, lo-fi\nR&B, gospel, lo-fi hip hop\nR&B, gospel, lo-fi hip-hop\nR&B, gospel, musical theater\nR&B, gospel, neo-soul\nR&B, gospel, new jack swing\nR&B, gospel, pop\nR&B, gospel, pop-rock\nR&B, gospel, power ballad\nR&B, gospel, smooth jazz\nR&B, gospel, soul\nR&B, gospel, spiritual\nR&B, gospel, synth-pop\nR&B, gospel, theatrical\nR&B, gospel, trap\nR&B, gospel, trap-soul\nR&B, gospel, trip-hop\nR&B, gospel, world music\nR&B, gospel, zouk\nR&B, gospel-pop\nR&B, gospel-pop, ambient\nR&B, gospel-pop, cinematic\nR&B, gospel-pop, early 2000s\nR&B, gospel-pop, hip-hop\nR&B, gospel-pop, orchestral\nR&B, grime, atmospheric\nR&B, groove, soul\nR&B, hard rock\nR&B, hardstyle\nR&B, hardstyle, J-pop\nR&B, hardstyle, cinematic\nR&B, hardstyle, trap\nR&B, hip hop\nR&B, hip hop soul\nR&B, hip hop, ambient\nR&B, hip hop, atmospheric\nR&B, hip hop, cinematic\nR&B, hip hop, dance\nR&B, hip hop, electronic\nR&B, hip hop, experimental\nR&B, hip hop, mid-2000s\nR&B, hip hop, psychedelic\nR&B, hip hop, soul\nR&B, hip hop, trap\nR&B, hip-hop\nR&B, hip-hop ballad\nR&B, hip-hop soul\nR&B, hip-hop soul, festive\nR&B, hip-hop soul, late-90s\nR&B, hip-hop, 2000s\nR&B, hip-hop, 2000s club\nR&B, hip-hop, 2000s pop\nR&B, hip-hop, Afro-pop\nR&B, hip-hop, Afrofusion\nR&B, hip-hop, Arabic pop\nR&B, hip-hop, C-pop\nR&B, hip-hop, Cantopop\nR&B, hip-hop, Christmas\nR&B, hip-hop, Filipino pop\nR&B, hip-hop, G-funk\nR&B, hip-hop, Haitian Creole\nR&B, hip-hop, J-pop\nR&B, hip-hop, K-pop\nR&B, hip-hop, Latin\nR&B, hip-hop, Latin pop\nR&B, hip-hop, Latin soul\nR&B, hip-hop, Mandarin\nR&B, hip-hop, Mandarin pop\nR&B, hip-hop, Mandopop\nR&B, hip-hop, Middle Eastern fusion\nR&B, hip-hop, New Jack Swing\nR&B, hip-hop, Punjabi\nR&B, hip-hop, South Asian fusion\nR&B, hip-hop, South Asian pop\nR&B, hip-hop, South Indian pop\nR&B, hip-hop, Spanish-influenced\nR&B, hip-hop, Thai pop\nR&B, hip-hop, UK rap\nR&B, hip-hop, West Coast\nR&B, hip-hop, acoustic\nR&B, hip-hop, ambient\nR&B, hip-hop, ambient piano\nR&B, hip-hop, atmospheric\nR&B, hip-hop, atmospheric electronic\nR&B, hip-hop, atmospheric pop\nR&B, hip-hop, ballad\nR&B, hip-hop, bilingual\nR&B, hip-hop, blues-rock\nR&B, hip-hop, chill-hop\nR&B, hip-hop, chillwave\nR&B, hip-hop, chiptune\nR&B, hip-hop, cinematic\nR&B, hip-hop, cinematic pop\nR&B, hip-hop, cinematic soul\nR&B, hip-hop, city pop\nR&B, hip-hop, city-pop\nR&B, hip-hop, club\nR&B, hip-hop, contemporary\nR&B, hip-hop, dance\nR&B, hip-hop, dance-pop\nR&B, hip-hop, dancehall\nR&B, hip-hop, dream pop\nR&B, hip-hop, dreamy\nR&B, hip-hop, early 2000s\nR&B, hip-hop, electro-funk\nR&B, hip-hop, electronic\nR&B, hip-hop, emotional\nR&B, hip-hop, ethereal pop\nR&B, hip-hop, festive\nR&B, hip-hop, funk\nR&B, hip-hop, gospel\nR&B, hip-hop, house\nR&B, hip-hop, jazz\nR&B, hip-hop, jazz lounge\nR&B, hip-hop, jazz-infused\nR&B, hip-hop, jazzy\nR&B, hip-hop, late-90s\nR&B, hip-hop, lo-fi\nR&B, hip-hop, melancholic\nR&B, hip-hop, neo-soul\nR&B, hip-hop, new jack swing\nR&B, hip-hop, piano ballad\nR&B, hip-hop, pop\nR&B, hip-hop, pop ballad\nR&B, hip-hop, pop-rap\nR&B, hip-hop, shoegaze\nR&B, hip-hop, smooth\nR&B, hip-hop, soul\nR&B, hip-hop, spiritual\nR&B, hip-hop, synth\nR&B, hip-hop, synth pop\nR&B, hip-hop, synth-pop\nR&B, hip-hop, synthwave\nR&B, hip-hop, trap\nR&B, hip-hop, vaporwave\nR&B, holiday\nR&B, holiday, comedic\nR&B, holiday, hip-hop\nR&B, holiday, pop\nR&B, holiday, soul\nR&B, house, Brazilian\nR&B, house, dreamy\nR&B, house, hyperpop\nR&B, house, soul\nR&B, hyperpop\nR&B, hyperpop, ambient\nR&B, hyperpop, ambient trap\nR&B, hyperpop, bilingual\nR&B, hyperpop, breakcore\nR&B, hyperpop, electronic\nR&B, hyperpop, trap\nR&B, indie pop\nR&B, indie pop, Punjabi fusion\nR&B, indie rock\nR&B, industrial, atmospheric\nR&B, inspirational pop, light EDM\nR&B, introspective, lo-fi\nR&B, jazz fusion\nR&B, jazz fusion, city pop\nR&B, jazz fusion, modern pop\nR&B, jazz, French rap\nR&B, jazz, Greek\nR&B, jazz, K-pop\nR&B, jazz, Korean pop\nR&B, jazz, Mandarin pop\nR&B, jazz, Mandopop\nR&B, jazz, Vietnamese ballad\nR&B, jazz, ambient\nR&B, jazz, bilingual\nR&B, jazz, blues\nR&B, jazz, boom-bap\nR&B, jazz, cinematic\nR&B, jazz, dream pop\nR&B, jazz, electronic\nR&B, jazz, gospel\nR&B, jazz, hip hop\nR&B, jazz, hip-hop\nR&B, jazz, lo-fi\nR&B, jazz, lo-fi hip hop\nR&B, jazz, neo-soul\nR&B, jazz, smooth soul\nR&B, jazz, soul\nR&B, jazz, trap\nR&B, jazz, urban\nR&B, jazz, vaporwave\nR&B, jazz-funk\nR&B, jazz-funk, Christmas\nR&B, jazz-hop\nR&B, jazz-infused, bilingual\nR&B, jazz-infused, hip-hop\nR&B, jazz-infused, lo-fi\nR&B, jazzy hip-hop\nR&B, jazzy trap\nR&B, jazzy, Christmas\nR&B, jazzy, Korean pop\nR&B, jazzy, Latin\nR&B, jazzy, Mandarin\nR&B, jazzy, Mandarin hip hop\nR&B, jazzy, Mandarin hip-hop\nR&B, jazzy, Mandarin pop\nR&B, jazzy, Mandarin rap\nR&B, jazzy, Mandarin soul\nR&B, jazzy, ambient\nR&B, jazzy, atmospheric\nR&B, jazzy, bedroom pop\nR&B, jazzy, bilingual\nR&B, jazzy, boom-bap\nR&B, jazzy, chill\nR&B, jazzy, emotional\nR&B, jazzy, hip-hop\nR&B, jazzy, lo-fi\nR&B, jazzy, lounge\nR&B, jazzy, melancholic\nR&B, jazzy, multilingual\nR&B, jazzy, smooth\nR&B, jazzy, soulful\nR&B, jazzy, synth soul\nR&B, jazzy, trap\nR&B, jump blues, swing\nR&B, late 90s hip-hop\nR&B, late-90s\nR&B, late-90s hip-hop\nR&B, late-90s, bilingual\nR&B, late-90s, cinematic\nR&B, lo-fi\nR&B, lo-fi K-R&B, trap\nR&B, lo-fi hip hop\nR&B, lo-fi hip hop, Afro-R&B\nR&B, lo-fi hip hop, Afro-soul\nR&B, lo-fi hip hop, Asian pop\nR&B, lo-fi hip hop, Bossa Nova\nR&B, lo-fi hip hop, Brazilian\nR&B, lo-fi hip hop, Brazilian pop\nR&B, lo-fi hip hop, Brazilian soul\nR&B, lo-fi hip hop, Cantonese pop\nR&B, lo-fi hip hop, Cantopop\nR&B, lo-fi hip hop, Chinese ambient\nR&B, lo-fi hip hop, Chinese ballad\nR&B, lo-fi hip hop, Chinese indie\nR&B, lo-fi hip hop, Chinese pop\nR&B, lo-fi hip hop, Chinese rap\nR&B, lo-fi hip hop, Chinese soul\nR&B, lo-fi hip hop, Christmas\nR&B, lo-fi hip hop, Filipino pop\nR&B, lo-fi hip hop, French R&B\nR&B, lo-fi hip hop, French soul\nR&B, lo-fi hip hop, Hindi R&B\nR&B, lo-fi hip hop, Hindi soul\nR&B, lo-fi hip hop, Indian classical\nR&B, lo-fi hip hop, Indian fusion\nR&B, lo-fi hip hop, Indonesian R&B\nR&B, lo-fi hip hop, Korean R&B\nR&B, lo-fi hip hop, Korean rap\nR&B, lo-fi hip hop, Latin\nR&B, lo-fi hip hop, Latin R&B\nR&B, lo-fi hip hop, Latin pop\nR&B, lo-fi hip hop, Latin soul\nR&B, lo-fi hip hop, Mandarin\nR&B, lo-fi hip hop, Mandarin R&B\nR&B, lo-fi hip hop, Mandarin pop\nR&B, lo-fi hip hop, Mandarin rap\nR&B, lo-fi hip hop, Sinhala\nR&B, lo-fi hip hop, South Asian\nR&B, lo-fi hip hop, South Asian fusion\nR&B, lo-fi hip hop, Spanish guitar\nR&B, lo-fi hip hop, Spanish soul\nR&B, lo-fi hip hop, Thai soul\nR&B, lo-fi hip hop, acapella\nR&B, lo-fi hip hop, ambient\nR&B, lo-fi hip hop, aquatic\nR&B, lo-fi hip hop, atmospheric\nR&B, lo-fi hip hop, atmospheric pop\nR&B, lo-fi hip hop, bedroom pop\nR&B, lo-fi hip hop, bilingual\nR&B, lo-fi hip hop, bilingual pop\nR&B, lo-fi hip hop, boom-bap\nR&B, lo-fi hip hop, chillwave\nR&B, lo-fi hip hop, cinematic\nR&B, lo-fi hip hop, cinematic soul\nR&B, lo-fi hip hop, cloud rap\nR&B, lo-fi hip hop, dream pop\nR&B, lo-fi hip hop, dreamy\nR&B, lo-fi hip hop, early 2000s\nR&B, lo-fi hip hop, experimental\nR&B, lo-fi hip hop, gospel\nR&B, lo-fi hip hop, hyperpop\nR&B, lo-fi hip hop, indie pop\nR&B, lo-fi hip hop, jazz\nR&B, lo-fi hip hop, jazzy\nR&B, lo-fi hip hop, melancholic pop\nR&B, lo-fi hip hop, neo-soul\nR&B, lo-fi hip hop, pop\nR&B, lo-fi hip hop, pop-rap\nR&B, lo-fi hip hop, soul\nR&B, lo-fi hip hop, trap\nR&B, lo-fi hip hop, vaporwave\nR&B, lo-fi hip hop, world music\nR&B, lo-fi hip-hop\nR&B, lo-fi hip-hop, Brazilian pop\nR&B, lo-fi hip-hop, C-pop\nR&B, lo-fi hip-hop, Chinese R&B\nR&B, lo-fi hip-hop, Chinese pop\nR&B, lo-fi hip-hop, Chinese soul\nR&B, lo-fi hip-hop, Christmas\nR&B, lo-fi hip-hop, Filipino pop\nR&B, lo-fi hip-hop, French R&B\nR&B, lo-fi hip-hop, French soul\nR&B, lo-fi hip-hop, Indian R&B\nR&B, lo-fi hip-hop, Indian pop\nR&B, lo-fi hip-hop, Japanese pop\nR&B, lo-fi hip-hop, Korean ballad\nR&B, lo-fi hip-hop, Latin\nR&B, lo-fi hip-hop, Latin R&B\nR&B, lo-fi hip-hop, Mandarin\nR&B, lo-fi hip-hop, Mandarin R&B\nR&B, lo-fi hip-hop, Mandarin pop\nR&B, lo-fi hip-hop, Mandarin rap\nR&B, lo-fi hip-hop, Mandopop\nR&B, lo-fi hip-hop, Punjabi pop\nR&B, lo-fi hip-hop, Punjabi soul\nR&B, lo-fi hip-hop, Tagalog soul\nR&B, lo-fi hip-hop, Thai R&B\nR&B, lo-fi hip-hop, acoustic pop\nR&B, lo-fi hip-hop, afrobeat\nR&B, lo-fi hip-hop, ambient\nR&B, lo-fi hip-hop, ambient pop\nR&B, lo-fi hip-hop, atmospheric\nR&B, lo-fi hip-hop, atmospheric pop\nR&B, lo-fi hip-hop, bedroom pop\nR&B, lo-fi hip-hop, blues-rock\nR&B, lo-fi hip-hop, breakcore\nR&B, lo-fi hip-hop, chillwave\nR&B, lo-fi hip-hop, cinematic\nR&B, lo-fi hip-hop, contemporary pop-R&B\nR&B, lo-fi hip-hop, dream pop\nR&B, lo-fi hip-hop, dreamy\nR&B, lo-fi hip-hop, emotional\nR&B, lo-fi hip-hop, emotional trap\nR&B, lo-fi hip-hop, gospel\nR&B, lo-fi hip-hop, indie soul\nR&B, lo-fi hip-hop, jazz\nR&B, lo-fi hip-hop, jazz fusion\nR&B, lo-fi hip-hop, jazzy\nR&B, lo-fi hip-hop, melancholic pop\nR&B, lo-fi hip-hop, modern pop\nR&B, lo-fi hip-hop, neo-soul\nR&B, lo-fi hip-hop, noise-rock\nR&B, lo-fi hip-hop, pop\nR&B, lo-fi hip-hop, pop-rap\nR&B, lo-fi hip-hop, pop-rock\nR&B, lo-fi hip-hop, psychedelic\nR&B, lo-fi hip-hop, rock\nR&B, lo-fi hip-hop, soul\nR&B, lo-fi hip-hop, trap\nR&B, lo-fi hip-hop, trap-soul\nR&B, lo-fi indie rock\nR&B, lo-fi neo-soul\nR&B, lo-fi pop\nR&B, lo-fi trap\nR&B, lo-fi trap, atmospheric\nR&B, lo-fi, 90s hip-hop\nR&B, lo-fi, Afro-soul\nR&B, lo-fi, Asian pop\nR&B, lo-fi, Brazilian\nR&B, lo-fi, C-pop\nR&B, lo-fi, Chinese\nR&B, lo-fi, Chinese pop\nR&B, lo-fi, Chinese soul\nR&B, lo-fi, Chinese trap\nR&B, lo-fi, Christmas\nR&B, lo-fi, French\nR&B, lo-fi, French pop\nR&B, lo-fi, French soul\nR&B, lo-fi, Hindi hip-hop\nR&B, lo-fi, Indonesian\nR&B, lo-fi, Japanese soul\nR&B, lo-fi, Latin\nR&B, lo-fi, Malay\nR&B, lo-fi, Mandarin\nR&B, lo-fi, Mandarin hip hop\nR&B, lo-fi, Mandarin hip-hop\nR&B, lo-fi, Mandarin pop\nR&B, lo-fi, Mandarin soul\nR&B, lo-fi, Spanish\nR&B, lo-fi, Spanish flavor\nR&B, lo-fi, Tagalog\nR&B, lo-fi, Thai\nR&B, lo-fi, Thai pop\nR&B, lo-fi, Vietnamese\nR&B, lo-fi, Vietnamese pop\nR&B, lo-fi, ambient\nR&B, lo-fi, ambient trap\nR&B, lo-fi, atmospheric\nR&B, lo-fi, bilingual\nR&B, lo-fi, boom-bap\nR&B, lo-fi, chiptune\nR&B, lo-fi, cinematic\nR&B, lo-fi, contemporary\nR&B, lo-fi, dance\nR&B, lo-fi, dancehall\nR&B, lo-fi, dream pop\nR&B, lo-fi, dreamy\nR&B, lo-fi, electronic\nR&B, lo-fi, emotional\nR&B, lo-fi, experimental\nR&B, lo-fi, festive\nR&B, lo-fi, future bass\nR&B, lo-fi, gospel\nR&B, lo-fi, hip-hop\nR&B, lo-fi, hyperpop\nR&B, lo-fi, jazz\nR&B, lo-fi, jazzy\nR&B, lo-fi, melancholic\nR&B, lo-fi, melodic hip-hop\nR&B, lo-fi, modern\nR&B, lo-fi, piano ballad\nR&B, lo-fi, pop\nR&B, lo-fi, pop-rap\nR&B, lo-fi, retro\nR&B, lo-fi, rock\nR&B, lo-fi, slow jam\nR&B, lo-fi, soul\nR&B, lo-fi, trap\nR&B, lo-fi, trap-soul\nR&B, lo-fi, vaporwave\nR&B, lo-fi, video game\nR&B, melancholic pop\nR&B, melancholic, Korean ballad\nR&B, melancholic, Mandarin\nR&B, melancholic, atmospheric\nR&B, melancholic, electronic\nR&B, melancholic, industrial\nR&B, melancholic, jazzy\nR&B, melodic hip-hop\nR&B, melodic rap, trap\nR&B, melodic synth, Mandarin\nR&B, melodic trap\nR&B, metalcore\nR&B, mid-2000s\nR&B, modern ghazal\nR&B, modern hip-hop\nR&B, modern pop\nR&B, modern trap, soulful\nR&B, musical theater\nR&B, neo-soul\nR&B, neo-soul, 90s style\nR&B, neo-soul, Afrobeats\nR&B, neo-soul, Brazilian pop\nR&B, neo-soul, C-pop\nR&B, neo-soul, Chinese\nR&B, neo-soul, Christmas\nR&B, neo-soul, French pop\nR&B, neo-soul, G-funk\nR&B, neo-soul, J-R&B\nR&B, neo-soul, J-pop\nR&B, neo-soul, K-Pop\nR&B, neo-soul, K-R&B\nR&B, neo-soul, K-pop\nR&B, neo-soul, Latin\nR&B, neo-soul, Latin R&B\nR&B, neo-soul, Latin pop\nR&B, neo-soul, Mandarin hip-hop\nR&B, neo-soul, Mandopop\nR&B, neo-soul, Tamil pop\nR&B, neo-soul, Thai soul\nR&B, neo-soul, UK garage\nR&B, neo-soul, West Coast hip-hop\nR&B, neo-soul, ambient\nR&B, neo-soul, bedroom pop\nR&B, neo-soul, bilingual\nR&B, neo-soul, chill-hop\nR&B, neo-soul, chillhop\nR&B, neo-soul, chillwave\nR&B, neo-soul, chiptune\nR&B, neo-soul, chopped and screwed\nR&B, neo-soul, city pop\nR&B, neo-soul, club\nR&B, neo-soul, dancehall\nR&B, neo-soul, dreamy\nR&B, neo-soul, early 2000s\nR&B, neo-soul, festive\nR&B, neo-soul, flamenco\nR&B, neo-soul, funk\nR&B, neo-soul, future bass\nR&B, neo-soul, future funk\nR&B, neo-soul, gospel\nR&B, neo-soul, hip-hop\nR&B, neo-soul, holiday\nR&B, neo-soul, jazz\nR&B, neo-soul, jazz fusion\nR&B, neo-soul, lo-fi\nR&B, neo-soul, lo-fi hip hop\nR&B, neo-soul, lo-fi hip-hop\nR&B, neo-soul, lovers rock\nR&B, neo-soul, new jack swing\nR&B, neo-soul, pop\nR&B, neo-soul, pop-R&B\nR&B, neo-soul, slow jam\nR&B, neo-soul, smooth jazz\nR&B, neo-soul, trap\nR&B, neo-soul, trap-soul\nR&B, neo-soul, vocal percussion\nR&B, new age\nR&B, new age, world music\nR&B, new jack swing\nR&B, new jack swing, 80s soul\nR&B, new jack swing, 90s\nR&B, new jack swing, Afropop\nR&B, new jack swing, Christmas\nR&B, new jack swing, K-pop\nR&B, new jack swing, ambient\nR&B, new jack swing, bilingual\nR&B, new jack swing, boogie funk\nR&B, new jack swing, chiptune\nR&B, new jack swing, cinematic\nR&B, new jack swing, city pop\nR&B, new jack swing, club\nR&B, new jack swing, dancehall\nR&B, new jack swing, early 2000s\nR&B, new jack swing, festive\nR&B, new jack swing, funk\nR&B, new jack swing, funk-pop\nR&B, new jack swing, gospel\nR&B, new jack swing, hip-hop\nR&B, new jack swing, holiday\nR&B, new jack swing, house\nR&B, new jack swing, modern\nR&B, new jack swing, pop\nR&B, new jack swing, pop-funk\nR&B, new jack swing, quiet storm\nR&B, new jack swing, retro\nR&B, new jack swing, retro pop\nR&B, new jack swing, retro-futuristic\nR&B, new jack swing, smooth jazz\nR&B, new jack swing, soul\nR&B, new jack swing, synth funk\nR&B, new jack swing, synth-funk\nR&B, new jack swing, synth-pop\nR&B, new jack swing, synthwave\nR&B, new jack swing, theatrical\nR&B, new-age\nR&B, new-age, soul\nR&B, nu-disco\nR&B, nu-disco, ambient\nR&B, nu-disco, hip-hop\nR&B, nu-metal\nR&B, nu-metal, electronic\nR&B, orchestral, soul\nR&B, oud, soul\nR&B, piano ballad\nR&B, piano, soul\nR&B, pluggnb\nR&B, pop\nR&B, pop jingle\nR&B, pop, 90s groove\nR&B, pop, Afro-pop\nR&B, pop, Afrobeat\nR&B, pop, Afrobeats\nR&B, pop, Central Asian\nR&B, pop, Central Asian pop\nR&B, pop, Chinese\nR&B, pop, Christmas\nR&B, pop, Filipino\nR&B, pop, German\nR&B, pop, Hindi soul\nR&B, pop, Indian fusion\nR&B, pop, Indian pop\nR&B, pop, K-pop\nR&B, pop, Mandarin\nR&B, pop, Mandarin hip hop\nR&B, pop, Middle Eastern\nR&B, pop, New Jack Swing\nR&B, pop, North African\nR&B, pop, South Indian\nR&B, pop, Southeast Asian pop\nR&B, pop, Tagalog\nR&B, pop, Vietnamese\nR&B, pop, a cappella\nR&B, pop, afrobeat\nR&B, pop, ambient\nR&B, pop, atmospheric\nR&B, pop, bedroom pop\nR&B, pop, chiptune\nR&B, pop, cinematic\nR&B, pop, contemporary\nR&B, pop, dancehall\nR&B, pop, downtempo\nR&B, pop, dream pop\nR&B, pop, dreamy\nR&B, pop, early 2000s\nR&B, pop, electronic\nR&B, pop, festive\nR&B, pop, gospel\nR&B, pop, hip hop\nR&B, pop, hip-hop\nR&B, pop, hyperpop\nR&B, pop, jazz\nR&B, pop, late-90s\nR&B, pop, lo-fi\nR&B, pop, lo-fi hip-hop\nR&B, pop, power pop\nR&B, pop, soul\nR&B, pop, spiritual\nR&B, pop, traditional Central Asian\nR&B, pop, trap\nR&B, pop, urban\nR&B, pop, vaporwave\nR&B, pop, vocal harmony\nR&B, pop, world fusion\nR&B, pop, world music\nR&B, pop-R&B, doo-wop\nR&B, pop-R&B, trap\nR&B, pop-funk\nR&B, pop-funk, 90s soul\nR&B, pop-funk, early 2000s\nR&B, pop-funk, holiday\nR&B, pop-funk, late 90s\nR&B, pop-funk, late-90s\nR&B, pop-funk, lo-fi\nR&B, pop-gospel, flamenco\nR&B, pop-punk\nR&B, pop-punk, alternative rock\nR&B, pop-rap\nR&B, pop-rap, French\nR&B, pop-rap, V-Pop\nR&B, pop-rap, atmospheric\nR&B, pop-rap, atmospheric electronic\nR&B, pop-rap, chillwave\nR&B, pop-rap, cinematic\nR&B, pop-rap, dreamy\nR&B, pop-rap, lo-fi\nR&B, pop-rap, lo-fi hip hop\nR&B, pop-rap, melancholic\nR&B, pop-rock\nR&B, pop-rock, dance-pop\nR&B, pop-rock, gospel\nR&B, pop-soul\nR&B, pop-soul, Christmas\nR&B, pop-soul, early 2000s\nR&B, pop-trap\nR&B, pop-trap, atmospheric\nR&B, post-hardcore, melodic rap\nR&B, post-rock, trap\nR&B, power ballad, 80s soul\nR&B, power ballad, cinematic\nR&B, power-pop\nR&B, progressive house\nR&B, progressive house, EDM\nR&B, progressive metal\nR&B, protest soul\nR&B, psychedelic soul\nR&B, psychedelic, electronic\nR&B, psychedelic, trap\nR&B, quiet storm\nR&B, quiet storm, new jack swing\nR&B, quiet storm, smooth jazz\nR&B, rap-rock\nR&B, reggae\nR&B, reggae, dancehall\nR&B, reggaeton\nR&B, reggaeton, Latin pop\nR&B, reggaeton, UK rap\nR&B, reggaeton, ambient\nR&B, reggaeton, atmospheric\nR&B, reggaeton, chiptune\nR&B, reggaeton, lo-fi\nR&B, reggaeton, pop\nR&B, retro\nR&B, retro gaming, cinematic\nR&B, retro soul\nR&B, retro synth\nR&B, retro-funk, new jack swing\nR&B, retro-pop\nR&B, rhythm and blues, boogie-woogie\nR&B, rock soul\nR&B, rock, ambient\nR&B, rock, electronic\nR&B, sad pop\nR&B, samba-pop\nR&B, samba-rock\nR&B, slap house\nR&B, slap house, future bass\nR&B, slow jam\nR&B, slow jam, Christmas\nR&B, slow jam, electronic\nR&B, slow jam, trap soul\nR&B, slow-jam, trap\nR&B, slowed + reverb\nR&B, smooth jazz\nR&B, smooth jazz, Christmas\nR&B, smooth jazz, adult contemporary\nR&B, smooth jazz, quiet storm\nR&B, soft rock, Christmas\nR&B, soul, 80s pop\nR&B, soul, 90s style\nR&B, soul, Afro-Hip-Hop\nR&B, soul, Afro-R&B\nR&B, soul, Afro-pop\nR&B, soul, Afro-soul\nR&B, soul, Afrofusion\nR&B, soul, Brazilian\nR&B, soul, Chinese pop\nR&B, soul, Christmas\nR&B, soul, French pop\nR&B, soul, Indonesian\nR&B, soul, Indonesian pop\nR&B, soul, Jamaican Patois\nR&B, soul, K-pop\nR&B, soul, Latin\nR&B, soul, Latin hip-hop\nR&B, soul, Latin pop\nR&B, soul, Mandarin ballad\nR&B, soul, Middle Eastern fusion\nR&B, soul, Māori\nR&B, soul, Thai pop\nR&B, soul, Turkish pop\nR&B, soul, UK hip hop\nR&B, soul, Vietnamese\nR&B, soul, Vietnamese ballad\nR&B, soul, acoustic\nR&B, soul, ambient\nR&B, soul, ambient hip-hop\nR&B, soul, atmospheric\nR&B, soul, baroque pop\nR&B, soul, big band\nR&B, soul, blues-rock\nR&B, soul, chiptune\nR&B, soul, choral\nR&B, soul, cinematic\nR&B, soul, conscious hip-hop\nR&B, soul, downtempo hip-hop\nR&B, soul, electronic\nR&B, soul, festive\nR&B, soul, funk\nR&B, soul, gospel\nR&B, soul, hip hop\nR&B, soul, hip-hop\nR&B, soul, holiday\nR&B, soul, jazz\nR&B, soul, jazz fusion\nR&B, soul, jazz-infused hip-hop\nR&B, soul, jazzy\nR&B, soul, live band\nR&B, soul, lo-fi\nR&B, soul, lo-fi hip hop\nR&B, soul, modern trap\nR&B, soul, mystical\nR&B, soul, neo-soul\nR&B, soul, new jack swing\nR&B, soul, piano ballad\nR&B, soul, pop\nR&B, soul, protest\nR&B, soul, spiritual\nR&B, soul, theatrical\nR&B, soul, trap\nR&B, soul, world music\nR&B, spiritual, acoustic\nR&B, spiritual, gospel\nR&B, symphonic rock\nR&B, synth brass, modern soul\nR&B, synth funk\nR&B, synth funk, cinematic pop\nR&B, synth pop\nR&B, synth pop, C-pop\nR&B, synth pop, Chinese hip hop\nR&B, synth pop, East Asian\nR&B, synth pop, Mandopop\nR&B, synth pop, hip-hop\nR&B, synth-funk\nR&B, synth-funk, 80s\nR&B, synth-funk, modern pop\nR&B, synth-pop\nR&B, synth-pop, ambient\nR&B, synth-pop, chillwave\nR&B, synth-pop, chiptune\nR&B, synth-pop, city pop\nR&B, synth-pop, drum and bass\nR&B, synth-pop, electro-house\nR&B, synth-pop, funk\nR&B, synth-pop, future bass\nR&B, synth-pop, future funk\nR&B, synth-pop, hip-hop\nR&B, synth-pop, lo-fi hip-hop\nR&B, synth-pop, new jack swing\nR&B, synth-pop, pop\nR&B, synth-pop, pop-rock\nR&B, synth-pop, smooth jazz\nR&B, synth-pop, trap\nR&B, synth-pop, vaporwave\nR&B, synthpop\nR&B, synthwave\nR&B, synthwave, C-pop\nR&B, synthwave, French pop\nR&B, synthwave, Mandopop\nR&B, synthwave, chiptune\nR&B, synthwave, dark pop\nR&B, synthwave, emotional\nR&B, synthwave, guitar-driven\nR&B, synthwave, hip-hop\nR&B, synthwave, industrial\nR&B, synthwave, lo-fi\nR&B, synthwave, lo-fi hip hop\nR&B, synthwave, trap\nR&B, theatrical soul, new jack swing\nR&B, trap\nR&B, trap R&B, Mandarin pop\nR&B, trap soul\nR&B, trap soul, Christmas\nR&B, trap soul, Middle Eastern\nR&B, trap soul, ambient\nR&B, trap soul, ambient pop\nR&B, trap soul, atmospheric\nR&B, trap soul, atmospheric pop\nR&B, trap soul, jazz\nR&B, trap soul, jazzy\nR&B, trap soul, lo-fi\nR&B, trap soul, pop\nR&B, trap soul, pop-R&B\nR&B, trap, Afrikaans\nR&B, trap, Afro-R&B\nR&B, trap, Afro-pop\nR&B, trap, Afrobeat\nR&B, trap, Afrobeats\nR&B, trap, Afrofusion\nR&B, trap, Arabic pop\nR&B, trap, Brazilian\nR&B, trap, C-pop\nR&B, trap, Chinese pop\nR&B, trap, Chinese soul\nR&B, trap, Chinese traditional\nR&B, trap, Christmas\nR&B, trap, Dutch\nR&B, trap, Dutch R&B\nR&B, trap, Dutch hip hop\nR&B, trap, EDM\nR&B, trap, East Asian\nR&B, trap, East Asian pop\nR&B, trap, Filipino\nR&B, trap, French\nR&B, trap, French R&B\nR&B, trap, French pop\nR&B, trap, Hindi\nR&B, trap, Indian classical\nR&B, trap, Indian fusion\nR&B, trap, Indian pop\nR&B, trap, Indonesian\nR&B, trap, Indonesian pop\nR&B, trap, Italian soul\nR&B, trap, J-pop\nR&B, trap, Korean\nR&B, trap, Korean R&B\nR&B, trap, Korean pop\nR&B, trap, Latin\nR&B, trap, Latin R&B\nR&B, trap, Latin pop\nR&B, trap, Mandarin\nR&B, trap, Mandarin hip hop\nR&B, trap, Mandarin pop\nR&B, trap, Mandopop\nR&B, trap, Middle Eastern\nR&B, trap, North African\nR&B, trap, Portuguese\nR&B, trap, Punjabi\nR&B, trap, Russian\nR&B, trap, Russian soul\nR&B, trap, South Asian\nR&B, trap, South Asian fusion\nR&B, trap, South Asian pop\nR&B, trap, Spanish acoustic\nR&B, trap, Spanish guitar\nR&B, trap, Spanish-influenced\nR&B, trap, Swedish\nR&B, trap, Tagalog\nR&B, trap, Thai R&B\nR&B, trap, Thai pop\nR&B, trap, Turkish pop\nR&B, trap, UK hip-hop\nR&B, trap, Vietnamese pop\nR&B, trap, acoustic\nR&B, trap, acoustic ballad\nR&B, trap, afrobeat\nR&B, trap, ambient\nR&B, trap, ambient pop\nR&B, trap, atmospheric\nR&B, trap, atmospheric pop\nR&B, trap, ballad\nR&B, trap, bilingual\nR&B, trap, blues-rock\nR&B, trap, chill\nR&B, trap, chillwave\nR&B, trap, chiptune\nR&B, trap, chopped and screwed\nR&B, trap, cinematic\nR&B, trap, cloud rap\nR&B, trap, contemporary\nR&B, trap, dancehall\nR&B, trap, dream pop\nR&B, trap, dreamy\nR&B, trap, dreamy synth\nR&B, trap, dubstep\nR&B, trap, electronic\nR&B, trap, emotional\nR&B, trap, emotional ballad\nR&B, trap, ethereal\nR&B, trap, experimental\nR&B, trap, festive\nR&B, trap, funk carioca\nR&B, trap, future bass\nR&B, trap, future soul\nR&B, trap, futuristic\nR&B, trap, gospel\nR&B, trap, hardstyle\nR&B, trap, hip hop\nR&B, trap, hip-hop\nR&B, trap, holiday\nR&B, trap, horrorcore\nR&B, trap, hyperpop\nR&B, trap, indie rock\nR&B, trap, inspirational pop\nR&B, trap, jazz\nR&B, trap, jazz fusion\nR&B, trap, jazz-infused\nR&B, trap, jazzy\nR&B, trap, live performance\nR&B, trap, lo-fi\nR&B, trap, lo-fi hip hop\nR&B, trap, lo-fi hip-hop\nR&B, trap, melancholic\nR&B, trap, melodic\nR&B, trap, melodic hip hop\nR&B, trap, modern\nR&B, trap, multilingual\nR&B, trap, neo-soul\nR&B, trap, piano ballad\nR&B, trap, pop\nR&B, trap, pop-rap\nR&B, trap, psychedelic\nR&B, trap, quirky\nR&B, trap, reggae fusion\nR&B, trap, reggaeton\nR&B, trap, rock\nR&B, trap, sensual\nR&B, trap, shoegaze\nR&B, trap, smooth\nR&B, trap, smooth jazz\nR&B, trap, soul\nR&B, trap, spiritual\nR&B, trap, spoken word\nR&B, trap, synth-pop\nR&B, trap, synthwave\nR&B, trap, vaporwave\nR&B, trap-R&B, Haitian Creole\nR&B, trap-R&B, gospel\nR&B, trap-metal, industrial rock\nR&B, trap-pop, ambient\nR&B, trap-pop, electro-funk\nR&B, trap-soul\nR&B, trap-soul, Afrobeats\nR&B, trap-soul, Brazilian\nR&B, trap-soul, C-pop\nR&B, trap-soul, Chinese contemporary\nR&B, trap-soul, French hip-hop\nR&B, trap-soul, Korean\nR&B, trap-soul, Latin pop\nR&B, trap-soul, Mandopop\nR&B, trap-soul, ambient\nR&B, trap-soul, ambient pop\nR&B, trap-soul, atmospheric\nR&B, trap-soul, atmospheric pop\nR&B, trap-soul, bilingual\nR&B, trap-soul, chillwave\nR&B, trap-soul, cinematic\nR&B, trap-soul, cloud rap\nR&B, trap-soul, dancehall\nR&B, trap-soul, dream pop\nR&B, trap-soul, dream-pop\nR&B, trap-soul, dreamy\nR&B, trap-soul, gospel\nR&B, trap-soul, hip-hop\nR&B, trap-soul, jazz\nR&B, trap-soul, jazzy\nR&B, trap-soul, lo-fi\nR&B, trap-soul, lo-fi hip-hop\nR&B, trap-soul, modern pop\nR&B, trap-soul, neo-soul\nR&B, trap-soul, pop\nR&B, trap-soul, pop-R&B\nR&B, tribal, ambient\nR&B, trip-hop\nR&B, trip-hop, ambient\nR&B, tropical house\nR&B, tropical house, hip-hop\nR&B, tropical, festive\nR&B, urban pop, ambient\nR&B, vaporwave\nR&B, vaporwave, Arabic soul\nR&B, vaporwave, Chinese pop\nR&B, vaporwave, Italian pop\nR&B, vaporwave, K-pop\nR&B, vaporwave, Latin soul\nR&B, vaporwave, ambient\nR&B, vaporwave, blues-rock\nR&B, vaporwave, cinematic\nR&B, vaporwave, electronic\nR&B, vaporwave, hip hop\nR&B, vaporwave, hip-hop\nR&B, vaporwave, lo-fi\nR&B, vaporwave, lo-fi hip hop\nR&B, vaporwave, melodic rap\nR&B, vaporwave, pop-rap\nR&B, vaporwave, soul\nR&B, vaporwave, synth soul\nR&B, vaporwave, trap\nR&B, vaporwave, trap-soul\nR&B, vintage soul\nR&B, vintage soul, funk\nR&B, vintage, soul\nR&B, vocal percussion, hip-hop\nR&B, winter holiday, Mandarin pop\nR&B, world fusion\nR&B, world fusion, pop\nR&B, world fusion, sensual\nR&B, world music\nR&B, world music, Middle Eastern\nR&B, world music, ambient\nR&B, world music, atmospheric\nR&B, world music, dance\nR&B, world music, lo-fi\nR&B, world music, lo-fi hip hop\nR&B, world music, soul\nR&B, world music, synth soul\nR&B, world music, trap\nR&B, zouk, kizomba\nR&B, zouk, kompa\nR&B-infused C-pop\nR&B-infused Swedish pop\nR&B-infused pop\nR&B-infused pop-rap\nR&B-pop\nR&B-pop trap\nR&B/Pop\nR&B/pop\nRPG ambient\nRPG game music\nRPG music\nRPG soundtrack\nRPG town music\nRPG video game\nRPG video game music\nRai\nRai electronic\nRai electronic pop\nRai funk\nRai fusion\nRai hip-hop\nRai hip-hop electronic\nRai music\nRai pop\nRai pop, reggaeton, Latin pop\nRai pop, trap, French hip hop\nRai trap\nRai, electronic Arabic pop\nRai, electronic Dabke\nRai, electronic dance\nRai, electronic dance, North African pop\nRai, electronic, Afrobeat\nRai, electronic, Chaabi\nRai, electronic, North African pop\nRai, electronic, upbeat\nRai, lo-fi hip hop, melancholic\nRai-pop\nRai-pop lo-fi hip-hop\nRajasthani folk\nRajasthani folk electronic\nRajasthani folk fusion\nRajasthani folk hip-hop\nRajasthani folk trap\nRajasthani folk, electronic dance\nRajasthani folk, electronic dance, fusion\nRajasthani folk-fusion\nRajasthani folk-pop\nRajasthani fusion\nRajasthani hip-hop\nRajasthani pop\nRanchera\nRastafarian chant\nRaï\nRaï Chaabi\nRaï dance-pop\nRaï dancehall\nRaï desert blues\nRaï electronic\nRaï electronica\nRaï funk\nRaï funk rock\nRaï fusion\nRaï fusion funk rock\nRaï hip-hop\nRaï house\nRaï pop\nRaï pop fusion\nRaï pop-dance\nRaï pop-rock\nRaï psychedelic rock\nRaï rock\nRaï salsa\nRaï trap\nRaï, Afropop\nRaï, Arabic Mawwal\nRaï, Arabic Mawwal, atmospheric\nRaï, Arabic Mawwal, cinematic\nRaï, Arabic folk\nRaï, Arabic folk, Balkan\nRaï, Arabic pop\nRaï, Arabic pop, electronic\nRaï, Arabic, electronic\nRaï, Arabic, ney\nRaï, Balkan folk\nRaï, Chaabi\nRaï, Chaabi, North African folk\nRaï, Chaabi, North African pop\nRaï, Chaabi, modern pop\nRaï, Dabke\nRaï, Dabke, Arabic electronic\nRaï, Dabke, Arabic fusion\nRaï, chiptune, electronic\nRaï, cinematic\nRaï, cinematic orchestral\nRaï, cinematic, Arabic\nRaï, cinematic, Arabic fusion\nRaï, cinematic, North African\nRaï, cinematic, electronic\nRaï, classical, North African\nRaï, dance pop, North African\nRaï, dance-pop, Arabic ballad\nRaï, desert blues\nRaï, electronic belly dance\nRaï, electronic dance\nRaï, electronic dance, North African pop\nRaï, electronic desert\nRaï, electronic folk\nRaï, electronic folk, Arabic\nRaï, electronic fusion\nRaï, electronic, Arabic\nRaï, electronic, North African pop\nRaï, electronic, dance\nRaï, electronic, modern pop\nRaï, folk-pop\nRaï, modern Arabic pop\nRaï, modern Chaabi\nRaï, modern North African pop\nRaï, modern North African pop, cinematic\nRaï, modern Thisa\nRaï, retro electronic\nRaï, retro synth, electronic\nRaï-pop\nRegional Mexican\nRegional Mexican R&B\nRegional Mexican Sierreño\nRegional Mexican hip-hop\nRegional Mexican jazz\nRegional Mexican trap\nRegional Mexican, chiptune\nRegional Mexican, dembow\nRegional Mexican, trap\nRhythm and Blues\nRock Kapak\nRomani folk\nRomani music\nRomanian Christian\nRomanian Christian ballad\nRomanian Christian folk\nRomanian Christian folk-pop\nRomanian Christian pop\nRomanian Christian pop-folk\nRomanian Christmas\nRomanian Christmas ballad\nRomanian Christmas carol\nRomanian Christmas pop\nRomanian Eurodance\nRomanian Gospel\nRomanian Manele\nRomanian Manele trap\nRomanian R&B\nRomanian art song\nRomanian ballad\nRomanian ballad, Latin pop, dramatic soul\nRomanian bolero, Latin jazz\nRomanian carol\nRomanian chanson\nRomanian club\nRomanian club rap\nRomanian club-rap\nRomanian colindă\nRomanian dance\nRomanian dance-pop\nRomanian dancehall\nRomanian deep house\nRomanian disco-pop\nRomanian drill\nRomanian folk\nRomanian folk ballad\nRomanian folk cabaret\nRomanian folk chiptune\nRomanian folk dance\nRomanian folk dance-pop\nRomanian folk electronic\nRomanian folk hip-hop\nRomanian folk house\nRomanian folk jazz\nRomanian folk lăutărească\nRomanian folk pop\nRomanian folk pop-rock\nRomanian folk rock\nRomanian folk techno\nRomanian folk trap\nRomanian folk, Eurodance\nRomanian folk, Gypsy jazz\nRomanian folk, boogie-woogie, ragtime\nRomanian folk, cabaret, chanson\nRomanian folk, cabaret, theatrical\nRomanian folk, children's music, synth pop\nRomanian folk, cinematic, Manele\nRomanian folk, cinematic, ambient\nRomanian folk, cinematic, melancholic\nRomanian folk, classical, theatrical\nRomanian folk, cumbia, dance\nRomanian folk, electronic dance\nRomanian folk, electronic pop\nRomanian folk, electronic, melancholic\nRomanian folk, electronic, spiritual\nRomanian folk, ethno, lăutărească\nRomanian folk, festive, electronic\nRomanian folk, festive, synth pop\nRomanian folk, gypsy jazz\nRomanian folk, lo-fi, cinematic\nRomanian folk, manele\nRomanian folk, pop-folk, cinematic\nRomanian folk, smooth jazz\nRomanian folk, synthwave\nRomanian folk, tango, big band jazz\nRomanian folk, theatrical, cabaret\nRomanian folk-pop\nRomanian folk-pop cabaret\nRomanian folk-pop, Italo-disco, retro-futuristic\nRomanian folk-pop, Manele\nRomanian folk-pop, electronic dance\nRomanian folk-rock\nRomanian gangsta rap\nRomanian gospel\nRomanian gospel folk\nRomanian gospel-pop\nRomanian hip-hop\nRomanian hip-hop G-funk\nRomanian hip-hop chiptune\nRomanian hip-hop pop\nRomanian hip-hop reggae fusion\nRomanian hip-hop reggaeton\nRomanian hip-hop trap\nRomanian hip-hop, Balkan dancehall\nRomanian hip-hop, Balkan folk\nRomanian hip-hop, chiptune, trap\nRomanian hip-hop, reggaeton, Latin pop\nRomanian hip-hop, trap, futuristic\nRomanian hip-hop, trap-soul, R&B\nRomanian house\nRomanian lullaby\nRomanian party\nRomanian party anthem\nRomanian party folk\nRomanian party music\nRomanian party music big band swing\nRomanian party music hip-hop\nRomanian party music, Latin, Balkan\nRomanian party music, electronic dance\nRomanian party rap\nRomanian party, reggaeton, flamenco pop\nRomanian party-house\nRomanian party-rap\nRomanian party-rock\nRomanian pop\nRomanian pop Manele\nRomanian pop R&B\nRomanian pop ballad\nRomanian pop jazz\nRomanian pop manele\nRomanian pop reggaeton\nRomanian pop trap\nRomanian pop, 70s disco, theatrical\nRomanian pop, Arabic trap\nRomanian pop, Balkan dance\nRomanian pop, Balkan folk, electronic\nRomanian pop, Balkan folk, theatrical pop\nRomanian pop, Balkan pop, reggaeton\nRomanian pop, Balkan pop, trap\nRomanian pop, EDM\nRomanian pop, EDM, anthemic\nRomanian pop, EDM, trap\nRomanian pop, Euro-pop\nRomanian pop, Eurodance\nRomanian pop, Eurodance, Manele\nRomanian pop, Eurodance, disco\nRomanian pop, Eurodance, hip-hop\nRomanian pop, Europop\nRomanian pop, Italo disco, schlager\nRomanian pop, Italo-disco\nRomanian pop, Latin cha-cha\nRomanian pop, Latin dance\nRomanian pop, Latin pop\nRomanian pop, Latin pop, 20th century\nRomanian pop, Latin pop, cha-cha\nRomanian pop, Latin pop, cumbia\nRomanian pop, Latin pop, electronic\nRomanian pop, Latin pop, flamenco pop\nRomanian pop, Latin pop, reggaeton\nRomanian pop, Latin schlager, European pop\nRomanian pop, Latin trap\nRomanian pop, Manele\nRomanian pop, Manele, Balkan pop\nRomanian pop, Manele, Eurodance\nRomanian pop, Manele, Latin pop\nRomanian pop, Manele, ballad\nRomanian pop, Manele, cinematic\nRomanian pop, Manele, cinematic ballad\nRomanian pop, Manele, cinematic pop\nRomanian pop, Manele, dance\nRomanian pop, Manele, dance pop\nRomanian pop, Manele, dance-pop\nRomanian pop, Manele, dramatic ballad\nRomanian pop, Manele, electronic\nRomanian pop, Manele, electronic dance\nRomanian pop, Manele, emotional ballad\nRomanian pop, Manele, festive\nRomanian pop, Manele, folk-pop\nRomanian pop, Manele, jazz fusion\nRomanian pop, Manele, melancholic\nRomanian pop, Manele, melancholic ballad\nRomanian pop, Manele, pop-dance\nRomanian pop, Manele, pop-rock\nRomanian pop, Manele, reggaeton\nRomanian pop, Manele, synth pop\nRomanian pop, Manele, trap\nRomanian pop, Manele, trap-pop\nRomanian pop, R&B\nRomanian pop, R&B, Latin pop\nRomanian pop, R&B, early 2000s\nRomanian pop, R&B, hip-hop\nRomanian pop, R&B, trap\nRomanian pop, big band, swing\nRomanian pop, dance-pop, EDM\nRomanian pop, dance-pop, Euro-pop\nRomanian pop, deep house\nRomanian pop, deep house, dance-pop\nRomanian pop, deep house, reggaeton\nRomanian pop, deep house, trap\nRomanian pop, electronic R&B\nRomanian pop, euro-disco, retro\nRomanian pop, flamenco, Latin pop\nRomanian pop, flamenco, reggaeton\nRomanian pop, folk pop, theatrical pop\nRomanian pop, folk, Christian contemporary\nRomanian pop, hip-hop\nRomanian pop, reggaeton\nRomanian pop, reggaeton, Balkan\nRomanian pop, reggaeton, Balkan pop\nRomanian pop, reggaeton, EDM\nRomanian pop, reggaeton, Latin\nRomanian pop, reggaeton, Latin pop\nRomanian pop, reggaeton, Manele\nRomanian pop, reggaeton, dancehall\nRomanian pop, reggaeton, electronic\nRomanian pop, reggaeton, moombahton\nRomanian pop, reggaeton, trap\nRomanian pop, reggaeton, tropical house\nRomanian pop, retro pop, children's music\nRomanian pop, schlager\nRomanian pop, schlager, folk\nRomanian pop, trap\nRomanian pop, trap, Balkan\nRomanian pop, trap, Balkan fusion\nRomanian pop, trap, Manele\nRomanian pop, trap, R&B\nRomanian pop, trap, chiptune\nRomanian pop, trap, dance-pop\nRomanian pop, trap, electronic\nRomanian pop, trap, folk\nRomanian pop, trap, melancholic\nRomanian pop, trap-pop\nRomanian pop, vintage pop, estrada\nRomanian pop-EDM\nRomanian pop-R&B\nRomanian pop-dance\nRomanian pop-dance trap\nRomanian pop-dance tropical house\nRomanian pop-dancehall\nRomanian pop-folk\nRomanian pop-funk\nRomanian pop-manele\nRomanian pop-manle\nRomanian pop-rap\nRomanian pop-rap, Latin pop, electronic\nRomanian pop-reggae\nRomanian pop-reggaeton\nRomanian pop-rock\nRomanian pop-trap\nRomanian power ballad\nRomanian reggaeton\nRomanian rock\nRomanian rock, tango rock\nRomanian sports anthem\nRomanian summer pop\nRomanian tango\nRomanian tango-pop\nRomanian tech house\nRomanian trap\nRomanian trap chiptune\nRomanian trap, Brazilian trap\nRomanian trap, cloud rap\nRomanian trap, lo-fi, vaporwave\nRomanian trap-R&B\nRomanian trap-manele\nRomanian trap-pop\nRomanian trap-reggaeton\nRomantic Folk\nRomantic Lied\nRomantic chamber music\nRomantic classical\nRomantic era\nRomantic era piano\nRomantic era, German Lied, orchestral\nRomantic era, cinematic, virtuoso\nRomantic jazz\nRomantic orchestral\nRomantic piano\nRomantic symphonic\nRomántero\nRumba Flamenca\nRumba Flamenca Bolero\nRussian Chanson\nRussian EDM\nRussian Eurodance\nRussian J-pop\nRussian R&B\nRussian R&B lo-fi hip-hop\nRussian R&B trap\nRussian R&B, early 2000s hip-hop\nRussian R&B, hip-hop\nRussian R&B, pop-R&B, trap\nRussian alternative rock\nRussian art song\nRussian ballad\nRussian ballad bossa nova\nRussian ballad, bossa nova\nRussian ballad, pop-rock, cinematic\nRussian bard\nRussian bard folk-rock\nRussian bard punk\nRussian bard rock\nRussian bard satire\nRussian bard, Bossa Nova\nRussian bard, Bossa Nova, light jazz\nRussian bard, Latin folk, cinematic\nRussian bard, Latin groove\nRussian bard, Latin pop\nRussian bard, Latin rock\nRussian bard, Latin rumba\nRussian bard, big band, cinematic\nRussian bard, bossa nova\nRussian bard, cabaret, klezmer\nRussian bard, chiptune\nRussian bard, country and western\nRussian bard, flamenco folk\nRussian bard, flamenco, Latin\nRussian bard, flamenco, acoustic\nRussian bard, flamenco, cumbia\nRussian bard, flamenco, folk rock\nRussian bard, flamenco, rumba\nRussian bard, flamenco, theatrical\nRussian bard, folk-rock\nRussian bard, folk-rock, big band\nRussian bard, gypsy jazz\nRussian bard, hard rock\nRussian bard, indie folk, hip-hop\nRussian bard, indie rock, experimental\nRussian bard, klezmer, theatrical\nRussian bard, melancholic ballad, pop-rock\nRussian bard, ragtime\nRussian bard, reggae\nRussian bard, tango, Latin\nRussian bard, tango, blues\nRussian bard, theatrical rock, acoustic folk\nRussian bard, world music, acoustic\nRussian bard-rock\nRussian bass house\nRussian battle rap\nRussian blues-folk\nRussian brass band\nRussian cabaret\nRussian chanson\nRussian chanson Balkan folk\nRussian chanson Latin\nRussian chanson blues jazz\nRussian chanson blues-rock\nRussian chanson bolero\nRussian chanson bossa nova\nRussian chanson cabaret\nRussian chanson cabaret klezmer\nRussian chanson cabaret swing\nRussian chanson cool jazz\nRussian chanson cumbia\nRussian chanson dance-pop\nRussian chanson dembow\nRussian chanson disco-funk\nRussian chanson flamenco\nRussian chanson flamenco gypsy jazz\nRussian chanson folk-pop\nRussian chanson folk-rock\nRussian chanson gypsy jazz cabaret\nRussian chanson hip-hop\nRussian chanson jazz\nRussian chanson jazz blues\nRussian chanson jazz bossa nova\nRussian chanson jazz lounge\nRussian chanson jazz swing\nRussian chanson klezmer\nRussian chanson lo-fi\nRussian chanson lounge jazz\nRussian chanson pop-rock\nRussian chanson rap\nRussian chanson reggae\nRussian chanson rock\nRussian chanson rockabilly\nRussian chanson rockabilly surf rock\nRussian chanson ska polka\nRussian chanson ska-punk\nRussian chanson surf-rock\nRussian chanson synth-pop\nRussian chanson tango\nRussian chanson, Balkan folk, dance\nRussian chanson, Euro-disco\nRussian chanson, Eurodance\nRussian chanson, Eurodance, happy hardcore\nRussian chanson, Eurodance, synth rock\nRussian chanson, Latin jazz, bossa nova\nRussian chanson, Latin jazz, mambo\nRussian chanson, Latin jazz, tango\nRussian chanson, Latin pop\nRussian chanson, Latin rhythm\nRussian chanson, Latin, flamenco\nRussian chanson, Latin, theatrical\nRussian chanson, big band swing\nRussian chanson, big band swing, folk jazz\nRussian chanson, big band, swing\nRussian chanson, bolero\nRussian chanson, boom-bap hip hop\nRussian chanson, bossa nova\nRussian chanson, cabaret, big band\nRussian chanson, cabaret, big band swing\nRussian chanson, cabaret, klezmer\nRussian chanson, cabaret, lounge jazz\nRussian chanson, chiptune\nRussian chanson, dance-pop, synth\nRussian chanson, disco-funk\nRussian chanson, electronic dance music\nRussian chanson, eurodance, rock\nRussian chanson, folk rock, ambient\nRussian chanson, folk-pop, synth-pop\nRussian chanson, folk-rock\nRussian chanson, gypsy jazz\nRussian chanson, gypsy jazz, Latin\nRussian chanson, gypsy jazz, cabaret\nRussian chanson, gypsy jazz, ska\nRussian chanson, gypsy jazz, swing\nRussian chanson, gypsy jazz, theatrical\nRussian chanson, honky-tonk, folk rock\nRussian chanson, klezmer, big band\nRussian chanson, klezmer, electronic\nRussian chanson, klezmer, polka\nRussian chanson, klezmer, theatrical\nRussian chanson, klezmer, upbeat\nRussian chanson, modern rock\nRussian chanson, polka\nRussian chanson, polka, live performance\nRussian chanson, polka, synth\nRussian chanson, polka, synth folk\nRussian chanson, pop-rock\nRussian chanson, power ballad, flamenco\nRussian chanson, rock ballad\nRussian chanson, rockabilly, cinematic\nRussian chanson, synth pop, dance\nRussian chanson, synth-pop\nRussian chanson, synth-pop, chiptune\nRussian chanson, synth-pop, disco\nRussian chanson, synth-pop, estrada\nRussian chanson, tango, Latin\nRussian chanson, tango, jazz\nRussian chanson-pop\nRussian chanson-rap\nRussian chanson-rock\nRussian children's music\nRussian chopper rap\nRussian choral\nRussian choral, synthwave\nRussian club\nRussian club-rap\nRussian conscious hip-hop\nRussian dance\nRussian dance-pop\nRussian dance-pop chiptune\nRussian dance-pop moombahton\nRussian dance-pop nu-disco\nRussian dance-pop, EDM, hyperpop\nRussian dance-pop, Latin house\nRussian dance-pop, Russian R&B\nRussian dance-pop, hardbass, folk-influenced\nRussian dance-pop, hardbass, hip-hop\nRussian dance-pop, hardstyle, EDM\nRussian dance-pop, hyperpop\nRussian dance-rap\nRussian dancehall\nRussian dancehall reggaeton\nRussian disco-funk\nRussian disco-pop\nRussian drill\nRussian drill hyperpop\nRussian drill trap\nRussian drill, trap, cinematic\nRussian electronic\nRussian electronic pop\nRussian estrada\nRussian estrada bossa nova\nRussian estrada cabaret\nRussian estrada country-rock\nRussian estrada folk-rock\nRussian estrada jazz\nRussian estrada jazz lounge\nRussian estrada jazz tango\nRussian estrada pop\nRussian estrada pop-rock\nRussian estrada salsa\nRussian estrada swing\nRussian estrada tango\nRussian estrada, Bossa Nova\nRussian estrada, Latin jazz, tango\nRussian estrada, Latin pop\nRussian estrada, Latin rock\nRussian estrada, Turkish pop, Azerbaijani folk\nRussian estrada, big band swing\nRussian estrada, big band, pop-rock\nRussian estrada, big band, theatrical march\nRussian estrada, blues, lounge jazz\nRussian estrada, bolero\nRussian estrada, bossa nova, lounge jazz\nRussian estrada, cabaret, disco-pop\nRussian estrada, jazz lounge\nRussian estrada, oud, chanson\nRussian estrada, power ballad, rock\nRussian estrada, psychedelic rock, waltz\nRussian estrada, smooth jazz\nRussian folk\nRussian folk bossa nova\nRussian folk cabaret\nRussian folk cabaret big band\nRussian folk cabaret klezmer\nRussian folk country\nRussian folk dance\nRussian folk dance-pop\nRussian folk electronic\nRussian folk fusion\nRussian folk hip-hop\nRussian folk house\nRussian folk klezmer\nRussian folk polka\nRussian folk pop\nRussian folk punk\nRussian folk reggae\nRussian folk rock\nRussian folk romance\nRussian folk ska\nRussian folk waltz\nRussian folk, Balkan brass, Klezmer\nRussian folk, Balkan dance\nRussian folk, Balkan, folk rock\nRussian folk, Celtic folk\nRussian folk, Eurodance\nRussian folk, European chanson\nRussian folk, Gypsy, Romani\nRussian folk, Klezmer, Balkan dance\nRussian folk, Klezmer, Balkan folk\nRussian folk, Latin dance, flamenco\nRussian folk, Latin, cabaret\nRussian folk, big band jazz\nRussian folk, big band, rockabilly\nRussian folk, bluegrass\nRussian folk, cabaret, musical theater\nRussian folk, cabaret, theatrical\nRussian folk, choral, electronic\nRussian folk, choral, orchestral\nRussian folk, cinematic, ambient\nRussian folk, cinematic, anthem\nRussian folk, cinematic, operatic\nRussian folk, dance, electronic\nRussian folk, electronic dance\nRussian folk, electronic dance, anthemic\nRussian folk, electronic dance, chiptune\nRussian folk, electronic dance, fusion\nRussian folk, electronic dance, trance\nRussian folk, electronic, hardstyle\nRussian folk, electronic, trap\nRussian folk, ethno-pop, cinematic\nRussian folk, flamenco, Latin\nRussian folk, gypsy jazz\nRussian folk, gypsy jazz, klezmer\nRussian folk, happy hardcore\nRussian folk, klezmer, Balkan folk\nRussian folk, klezmer, chanson\nRussian folk, klezmer, gypsy jazz\nRussian folk, klezmer, marching\nRussian folk, klezmer, theatrical\nRussian folk, military march, polka\nRussian folk, military march, theatrical\nRussian folk, operatic, orchestral\nRussian folk, operatic, theatrical\nRussian folk, polka\nRussian folk, polka, chanson\nRussian folk, polka, klezmer\nRussian folk, sea shanty\nRussian folk, synth folk\nRussian folk, theatrical, cinematic\nRussian folk, theatrical, klezmer\nRussian folk, theatrical, patriotic\nRussian folk, theatrical, ragtime\nRussian folk-dance\nRussian folk-polka\nRussian folk-pop\nRussian folk-pop cabaret\nRussian folk-pop chiptune\nRussian folk-pop chiptune synth-rock\nRussian folk-pop cumbia\nRussian folk-pop disco\nRussian folk-pop klezmer\nRussian folk-pop rock\nRussian folk-pop ska\nRussian folk-pop surf rock\nRussian folk-pop, Eurodance\nRussian folk-pop, dance\nRussian folk-pop, dance, electronic\nRussian folk-pop, video game music\nRussian folk-punk\nRussian folk-rap\nRussian folk-rock\nRussian folk-rock punk\nRussian folk-rock, electronic, quirky\nRussian folk-rock, hard rock\nRussian folk-rock, heavy metal\nRussian folk-rock, psychedelic cumbia, surf-rock\nRussian folk-rock, punk rock\nRussian folk-rock, synth-pop\nRussian funk-pop\nRussian gangsta rap\nRussian gangster rap\nRussian gangster rap tango\nRussian grime\nRussian happy hardcore\nRussian hard bass\nRussian hard rock\nRussian hardbass\nRussian hardcore hip-hop\nRussian heavy metal\nRussian hip hop\nRussian hip hop, cinematic, boom-bap\nRussian hip hop, lo-fi, dream pop\nRussian hip hop, trip-hop\nRussian hip-hop\nRussian hip-hop G-funk\nRussian hip-hop R&B\nRussian hip-hop chanson\nRussian hip-hop chiptune\nRussian hip-hop dance-pop\nRussian hip-hop deep house\nRussian hip-hop funk-rock\nRussian hip-hop lo-fi\nRussian hip-hop reggaeton\nRussian hip-hop techno\nRussian hip-hop trap\nRussian hip-hop, Latin hip-hop\nRussian hip-hop, Latin pop\nRussian hip-hop, Middle Eastern folk\nRussian hip-hop, Middle Eastern fusion\nRussian hip-hop, alternative rock, trip-hop\nRussian hip-hop, chiptune\nRussian hip-hop, chiptune, boom-bap\nRussian hip-hop, chiptune, trap\nRussian hip-hop, cinematic trap\nRussian hip-hop, dance-pop, EDM\nRussian hip-hop, drill, trap\nRussian hip-hop, dubstep\nRussian hip-hop, flamenco hip-hop\nRussian hip-hop, folk fusion\nRussian hip-hop, hardstyle, electronic\nRussian hip-hop, hardstyle, trap\nRussian hip-hop, hyperpop, breakcore\nRussian hip-hop, hyperpop, chiptune\nRussian hip-hop, indie rock\nRussian hip-hop, lo-fi, cinematic\nRussian hip-hop, retro synth\nRussian hip-hop, rock, electronic\nRussian hip-hop, trap\nRussian hip-hop, trap, Balkan fusion\nRussian hip-hop, trap, Latin pop\nRussian hip-hop, trap, chiptune\nRussian hip-hop, trap, cinematic\nRussian hip-hop, trap, nu-metal\nRussian hip-hop, trap, rock\nRussian hip-house\nRussian house\nRussian indie pop\nRussian indie pop trip-hop\nRussian indie rock\nRussian indie-pop\nRussian lullaby\nRussian march\nRussian meme-rap\nRussian military folk\nRussian military march\nRussian military rock\nRussian narrative\nRussian new wave\nRussian novelty\nRussian novelty, polka, chiptune\nRussian novelty, polka, synth pop\nRussian party anthem\nRussian party-rap\nRussian patriotic, retro synth, kitsch\nRussian phonk\nRussian phonk trap\nRussian pop\nRussian pop Eurodance\nRussian pop Europop\nRussian pop Europop Latin\nRussian pop J-pop\nRussian pop Latin\nRussian pop Latin pop\nRussian pop R&B\nRussian pop R&B funk\nRussian pop R&B trap\nRussian pop ballad\nRussian pop bossa nova\nRussian pop cabaret\nRussian pop cabaret klezmer\nRussian pop cabaret ska\nRussian pop cabaret swing\nRussian pop cabaret tango\nRussian pop chanson\nRussian pop chiptune\nRussian pop cumbia\nRussian pop dancehall\nRussian pop disco-funk\nRussian pop estrada\nRussian pop flamenco\nRussian pop folk\nRussian pop funk\nRussian pop funk R&B\nRussian pop funk disco\nRussian pop jazz\nRussian pop reggaeton\nRussian pop ska\nRussian pop ska chanson\nRussian pop ska reggae\nRussian pop surf rock\nRussian pop tango\nRussian pop tango chanson\nRussian pop trap\nRussian pop waltz\nRussian pop, 80s synth-pop\nRussian pop, Azerbaijani pop, dance pop\nRussian pop, Balkan dance\nRussian pop, Balkan folk, Eastern European dance\nRussian pop, Balkan folk, dance pop\nRussian pop, Balkan folk, dance-pop\nRussian pop, Balkan folk, electronic\nRussian pop, Balkan folk, electronic dance\nRussian pop, Balkan folk, funk\nRussian pop, Balkan pop, Klezmer\nRussian pop, Balkan pop, Middle Eastern pop\nRussian pop, Balkan pop, gypsy jazz\nRussian pop, Bossa Nova\nRussian pop, Caucasian folk, dance\nRussian pop, Caucasian folk, dance pop\nRussian pop, EDM\nRussian pop, EDM, hyperpop\nRussian pop, EDM-pop\nRussian pop, Eastern European, Middle Eastern\nRussian pop, Estrada, synth pop\nRussian pop, Euro-pop\nRussian pop, Eurodance\nRussian pop, Eurodance, 2000s pop\nRussian pop, Eurodance, Italo disco\nRussian pop, Eurodance, Latin\nRussian pop, Eurodance, Latin pop\nRussian pop, Eurodance, Middle Eastern\nRussian pop, Eurodance, R&B\nRussian pop, Eurodance, chanson\nRussian pop, Eurodance, chiptune\nRussian pop, Eurodance, cinematic\nRussian pop, Eurodance, dance-pop\nRussian pop, Eurodance, disco\nRussian pop, Eurodance, disco-funk\nRussian pop, Eurodance, estrada\nRussian pop, Eurodance, folk\nRussian pop, Eurodance, folk dance\nRussian pop, Eurodance, folk pop\nRussian pop, Eurodance, folk-pop\nRussian pop, Eurodance, happy hardcore\nRussian pop, Eurodance, hardstyle\nRussian pop, Eurodance, hip-hop\nRussian pop, Eurodance, hyperpop\nRussian pop, Eurodance, orchestral\nRussian pop, Eurodance, oriental\nRussian pop, Eurodance, polka\nRussian pop, Eurodance, popsa\nRussian pop, Eurodance, retro\nRussian pop, Eurodance, ska\nRussian pop, Eurodance, synth-pop\nRussian pop, Eurodance, synthwave\nRussian pop, Eurodance, trance\nRussian pop, Europop\nRussian pop, Italo disco, Eurodance\nRussian pop, J-pop, hyperpop\nRussian pop, Klezmer, Eastern European folk\nRussian pop, Latin dance\nRussian pop, Latin dance, Eurodance\nRussian pop, Latin dance, flamenco\nRussian pop, Latin dance, reggaeton\nRussian pop, Latin dance-pop\nRussian pop, Latin disco\nRussian pop, Latin jazz\nRussian pop, Latin jazz, bolero\nRussian pop, Latin pop\nRussian pop, Latin pop, 80s estrada\nRussian pop, Latin pop, 80s synth\nRussian pop, Latin pop, Balkan pop\nRussian pop, Latin pop, Eastern European\nRussian pop, Latin pop, Eastern European folk\nRussian pop, Latin pop, Eurodance\nRussian pop, Latin pop, ballad\nRussian pop, Latin pop, big band\nRussian pop, Latin pop, bossa nova\nRussian pop, Latin pop, cumbia\nRussian pop, Latin pop, dance-pop\nRussian pop, Latin pop, disco\nRussian pop, Latin pop, estrada\nRussian pop, Latin pop, flamenco\nRussian pop, Latin pop, flamenco pop\nRussian pop, Latin pop, folk\nRussian pop, Latin pop, folk pop\nRussian pop, Latin pop, gypsy jazz\nRussian pop, Latin pop, reggaeton\nRussian pop, Latin pop, retro\nRussian pop, Latin pop, salsa\nRussian pop, Latin pop, samba\nRussian pop, Latin pop, ska\nRussian pop, Latin pop, tango\nRussian pop, Latin pop, theatrical\nRussian pop, Latin, big band\nRussian pop, Latin, dance\nRussian pop, Latin, world music\nRussian pop, Middle Eastern dance\nRussian pop, Middle Eastern folk\nRussian pop, Middle Eastern folk, dance-pop\nRussian pop, Middle Eastern fusion\nRussian pop, Middle Eastern pop, Turkish pop\nRussian pop, Middle Eastern, Balkan\nRussian pop, R&B\nRussian pop, R&B, dance-pop\nRussian pop, R&B, deep house\nRussian pop, R&B, hip-hop\nRussian pop, R&B, trap\nRussian pop, Romani, Gypsy\nRussian pop, bossa nova\nRussian pop, cabaret, big band jazz\nRussian pop, cabaret, klezmer\nRussian pop, cabaret, ska\nRussian pop, chanson, folk\nRussian pop, chastushka\nRussian pop, chiptune\nRussian pop, chiptune, dance\nRussian pop, chiptune, electronic\nRussian pop, chiptune, estrada\nRussian pop, chiptune, polka\nRussian pop, cinematic synth-pop\nRussian pop, cumbia\nRussian pop, cumbia, Latin pop\nRussian pop, cumbia, folk\nRussian pop, cumbia, retro\nRussian pop, cumbia, synth-pop\nRussian pop, dance, patriotic\nRussian pop, dance-pop\nRussian pop, dance-pop, EDM\nRussian pop, dance-pop, Eastern European\nRussian pop, dance-pop, folk\nRussian pop, dancehall, afrobeat\nRussian pop, dancehall, reggaeton\nRussian pop, dark R&B\nRussian pop, deep house\nRussian pop, dembow, folk\nRussian pop, disco\nRussian pop, disco, chanson\nRussian pop, disco, estrada\nRussian pop, disco, folk\nRussian pop, disco, funk\nRussian pop, disco, satirical\nRussian pop, disco, ska\nRussian pop, disco-funk\nRussian pop, disco-pop\nRussian pop, disco-pop, theatrical\nRussian pop, early 2000s R&B\nRussian pop, electronic dance\nRussian pop, electronic, Balkan fusion\nRussian pop, electronic, Middle Eastern\nRussian pop, electronic, melancholic\nRussian pop, estrada\nRussian pop, estrada, 80s pop\nRussian pop, estrada, 80s synth\nRussian pop, estrada, ballad\nRussian pop, estrada, chanson\nRussian pop, estrada, cinematic\nRussian pop, estrada, dance-pop\nRussian pop, estrada, electronic\nRussian pop, estrada, folk\nRussian pop, estrada, folk pop\nRussian pop, estrada, kitschy\nRussian pop, estrada, pop-rock\nRussian pop, estrada, retro\nRussian pop, estrada, retro synth\nRussian pop, estrada, smooth jazz\nRussian pop, estrada, synth-pop\nRussian pop, estrada, synthwave\nRussian pop, estrada, theatrical\nRussian pop, estrada, theatrical pop\nRussian pop, flamenco pop\nRussian pop, flamenco, Latin\nRussian pop, flamenco, Latin pop\nRussian pop, flamenco, ballad\nRussian pop, flamenco, pop-rock\nRussian pop, folk dance\nRussian pop, folk dance, estrada\nRussian pop, folk disco\nRussian pop, folk electronic\nRussian pop, folk pop\nRussian pop, folk pop, dance\nRussian pop, folk pop, estrada\nRussian pop, folk pop, theatrical pop\nRussian pop, folk rock\nRussian pop, folk trap\nRussian pop, folk, Eurodance\nRussian pop, folk, Latin\nRussian pop, folk, cabaret\nRussian pop, folk, chanson\nRussian pop, folk, dance\nRussian pop, folk, estrada\nRussian pop, folk, klezmer\nRussian pop, folk, oriental\nRussian pop, folk, polka\nRussian pop, folk, retro\nRussian pop, folk, ska\nRussian pop, folk, theatrical\nRussian pop, folk-pop\nRussian pop, folktronica\nRussian pop, gypsy jazz, flamenco\nRussian pop, gypsy jazz, klezmer\nRussian pop, hip-hop\nRussian pop, hip-hop, R&B\nRussian pop, house\nRussian pop, klezmer, Balkan\nRussian pop, klezmer, big band\nRussian pop, klezmer, cabaret\nRussian pop, klezmer, chanson\nRussian pop, klezmer, dance\nRussian pop, klezmer, dance pop\nRussian pop, klezmer, folk\nRussian pop, klezmer, polka\nRussian pop, klezmer, ska\nRussian pop, lo-fi hip hop, chiptune\nRussian pop, new jack swing\nRussian pop, polka\nRussian pop, polka, folk-pop\nRussian pop, polka, synth pop\nRussian pop, polka, upbeat\nRussian pop, power ballad, pop-rock\nRussian pop, reggae, ska\nRussian pop, reggaeton\nRussian pop, reggaeton, Latin pop\nRussian pop, reggaeton, Middle Eastern\nRussian pop, reggaeton, cumbia\nRussian pop, reggaeton, dancehall\nRussian pop, reggaeton, dream pop\nRussian pop, reggaeton, flamenco\nRussian pop, reggaeton, lo-fi\nRussian pop, reggaeton, melancholic\nRussian pop, retro Eurodance\nRussian pop, retro disco, funk\nRussian pop, retro estrada, theatrical\nRussian pop, retro pop\nRussian pop, retro synth, chiptune\nRussian pop, retro, chiptune\nRussian pop, retro, estrada\nRussian pop, rock, synth-pop\nRussian pop, ska, big band\nRussian pop, ska, chanson\nRussian pop, ska, estrada\nRussian pop, ska, polka\nRussian pop, tango, Latin\nRussian pop, tango, Latin pop\nRussian pop, tango, bolero\nRussian pop, theatrical pop, folk chanson\nRussian pop, theatrical, waltz\nRussian pop, trap\nRussian pop, trap, R&B\nRussian pop, trap, cinematic\nRussian pop, trap, dancehall\nRussian pop, trap, dream pop\nRussian pop, trap, electronic\nRussian pop, trap, ethnic\nRussian pop, trap, future bass\nRussian pop, trap, hyperpop\nRussian pop, trap, melancholic\nRussian pop, trap, melancholic dance\nRussian pop, trap, synthpop\nRussian pop, trap, world music\nRussian pop, trap-pop\nRussian pop, trip-hop\nRussian pop, trip-hop, melancholic\nRussian pop, tropical house, moombahton\nRussian pop, turbo-folk\nRussian pop-R&B\nRussian pop-R&B future bass\nRussian pop-R&B lo-fi hip-hop\nRussian pop-ballad\nRussian pop-chanson\nRussian pop-chanson, Eurodance\nRussian pop-dance\nRussian pop-disco\nRussian pop-folk\nRussian pop-funk\nRussian pop-house\nRussian pop-rap\nRussian pop-rap lo-fi hip hop\nRussian pop-rap trap\nRussian pop-rap, Balkan folk\nRussian pop-rap, Latin dance\nRussian pop-rap, deep house\nRussian pop-rap, deep house, dance-pop\nRussian pop-rap, deep house, slap house\nRussian pop-rap, hyperpop, trap\nRussian pop-rap, indie-pop, R&B\nRussian pop-rap, reggaeton\nRussian pop-reggae\nRussian pop-rock\nRussian pop-rock cabaret\nRussian pop-rock chiptune\nRussian pop-rock future bass\nRussian pop-rock ska\nRussian pop-rock tango\nRussian pop-rock, EDM, hardstyle\nRussian pop-rock, Eurodance\nRussian pop-rock, Latin acoustic\nRussian pop-rock, Latin pop\nRussian pop-rock, Latin pop, flamenco\nRussian pop-rock, Latin rhythm\nRussian pop-rock, Latin rhythms\nRussian pop-rock, boom-bap hip-hop\nRussian pop-rock, cabaret, klezmer\nRussian pop-rock, chiptune, eurodance\nRussian pop-rock, chiptune, happy hardcore\nRussian pop-rock, chiptune, video game music\nRussian pop-rock, electronic dance\nRussian pop-rock, estrada, theatrical\nRussian pop-rock, smooth jazz\nRussian pop-rock, world music\nRussian pop-trap\nRussian post-punk\nRussian post-punk, synth-pop\nRussian power ballad\nRussian punk rock\nRussian punk-pop\nRussian rap\nRussian rap reggaeton\nRussian rap, chiptune, electronic\nRussian rap, chiptune, hardcore\nRussian rap, chiptune, trap\nRussian rap, dembow, electronic\nRussian rap, drum and bass, aggressive\nRussian rap, electronic, ambient\nRussian rap, lo-fi hip hop, boom-bap\nRussian rap, trance, electronic\nRussian rap, trap, chiptune\nRussian rave\nRussian reggae\nRussian rock\nRussian rock and roll\nRussian rock blues\nRussian rock cabaret\nRussian rock cabaret ska\nRussian rock chanson\nRussian rock chiptune\nRussian rock country-rock\nRussian rock pop-rock\nRussian rock post-punk\nRussian rock punk\nRussian rock reggae\nRussian rock shanson\nRussian rock ska-punk\nRussian rock surf-rock\nRussian rock, Latin rock, ska\nRussian rock, Latin rock, tango\nRussian rock, cabaret, ska\nRussian rock, chanson, ska\nRussian rock, cinematic, synth orchestral\nRussian rock, funk\nRussian rock, gypsy-punk, tango\nRussian rock, hard rock\nRussian rock, hardstyle, folk\nRussian rock, heavy metal\nRussian rock, klezmer, ska\nRussian rock, new wave\nRussian rock, post-punk\nRussian rock, power metal\nRussian rock, rockabilly, big band\nRussian rock, rockabilly, boogie-woogie\nRussian rock, rockabilly, country rock\nRussian rock, ska, big band\nRussian rock, ska, cabaret\nRussian rock, ska, surf rock\nRussian rock, space rock\nRussian rock, surf rock, chanson\nRussian rock, surf rock, ska\nRussian rock, tango, cabaret\nRussian romance\nRussian romance cabaret\nRussian romance jazz\nRussian romance, cinematic orchestral, operatic\nRussian romance, cinematic, operatic\nRussian romance, cinematic, orchestral\nRussian romance, jazz noir, cinematic\nRussian romance, operatic pop, theatrical rock\nRussian romance, operatic, folk\nRussian romance, theatrical, film score\nRussian sea shanty\nRussian street rap\nRussian tango\nRussian techno\nRussian trance\nRussian trap\nRussian trap metal\nRussian trap, Latin trap\nRussian trap, boom-bap\nRussian trap, cloud rap\nRussian trap, cloud rap, rage music\nRussian trap, dance-pop\nRussian trap, dance-pop, Moombahton\nRussian trap, drill\nRussian trap, ethnic electronic\nRussian trap, hardstyle, anime\nRussian trap, hip-house\nRussian trap, hyperpop\nRussian trap, lo-fi hip hop\nRussian trap, moombahton\nRussian trap-pop\nRussian underground hip-hop\nRussian-style march\nRéunion Creole\nRéunion Creole folk\nSalsa\nSalsa Candombe\nSalsa Romántica\nSalsa, Cumbia, Banda\nSalsa, Son Cubano\nSamba\nSamba Axé\nSamba Bossa Nova\nSamba Brega\nSamba Choro\nSamba Forró\nSamba MPB\nSamba de Bamba\nSamba de Carioca\nSamba de Choro\nSamba de Gafieira\nSamba de Mandelão\nSamba de Partida\nSamba de Partido\nSamba de Partilha\nSamba de Partiteiro\nSamba de Partleda\nSamba de Partysamba\nSamba de Raiz\nSamba de Raiz Choro\nSamba de Rolar\nSamba de Samba\nSamba de Serra\nSamba de Vai\nSamba de Vela\nSamba de roda\nSamba folk\nSamba, Brazilian ballad\nSamba, Choro\nSamba, MPB\nSamba, MPB, Brazilian ballad\nSamba, Pagode, Brazilian pop\nSamba, cinematic, philosophical\nSamba, forró, lo-fi\nSamba-Canção\nSamba-Jazz\nSamba-Pagode\nSamba-Pop\nSamba-Rock\nSamba-enredo\nSamba-pop\nSamba-reggae\nSamba-rock\nSambalpuri folk\nSardinian folk\nScandinavian EDM\nScandinavian R&B\nScandinavian art song\nScandinavian ballad\nScandinavian club\nScandinavian club-rap\nScandinavian country-pop\nScandinavian dance\nScandinavian dance-pop\nScandinavian drill\nScandinavian electropop\nScandinavian folk\nScandinavian folk, schlager\nScandinavian folk-pop\nScandinavian folk-rock\nScandinavian hip-hop\nScandinavian hip-hop trap\nScandinavian house\nScandinavian indie pop\nScandinavian jazz lounge\nScandinavian party\nScandinavian pop\nScandinavian pop dance-pop\nScandinavian pop trap\nScandinavian pop tropical house\nScandinavian pop, Afrobeats, tropical house\nScandinavian pop, deep house\nScandinavian pop, hip-hop, trap\nScandinavian pop, reggaeton, synth-pop\nScandinavian pop, schlager\nScandinavian pop, trap, ambient\nScandinavian pop, tropical house\nScandinavian pop-R&B\nScandinavian pop-ballad\nScandinavian pop-folk\nScandinavian pop-rap\nScandinavian pop-rock\nScandinavian pop-trap\nScandinavian punk-pop\nScandinavian rock\nScandinavian rock 'n' roll\nScandinavian rockabilly\nScandinavian schlager\nScandinavian soft rock\nScandinavian summer pop\nScandinavian trap\nScandinavian trap R&B\nScandinavian trap, cloud rap\nScandinavian trap-pop\nScandinavian vise\nScandipop\nSchlager\nSchlager Ballermann\nSchlager Bossa Nova\nSchlager Christmas\nSchlager Euro-pop\nSchlager Eurodance\nSchlager Europop\nSchlager Italo-disco\nSchlager Latin\nSchlager Latin pop\nSchlager Neue Deutsche Welle\nSchlager Polka\nSchlager Volksmusik\nSchlager cabaret\nSchlager chiptune\nSchlager country\nSchlager country-pop\nSchlager country-rock\nSchlager country-rockabilly\nSchlager disco\nSchlager disco-pop\nSchlager exotica\nSchlager folk\nSchlager folk-pop\nSchlager folk-rock\nSchlager hip-hop\nSchlager jazz-pop\nSchlager novelty\nSchlager orchestral\nSchlager polka\nSchlager polka novelty\nSchlager pop\nSchlager pop, Eurodance, synth-pop\nSchlager pop, salsa\nSchlager pop-rock\nSchlager power metal\nSchlager reggae\nSchlager rock\nSchlager rockabilly\nSchlager rockabilly Eurodance\nSchlager rockabilly country\nSchlager samba\nSchlager tango\nSchlager waltz\nSchlager world music\nSchlager, 60s pop-rock, cinematic\nSchlager, 8-bit chiptune\nSchlager, 80s Dutch, levenslied\nSchlager, 80s Europop\nSchlager, 80s pop-rock\nSchlager, Après-ski\nSchlager, Ballermann, polka\nSchlager, Bossa Nova\nSchlager, Carnaval\nSchlager, Christian folk\nSchlager, Christian hymn\nSchlager, Christian pop\nSchlager, Christmas pop\nSchlager, Christmas pop, German pop\nSchlager, Cumbia\nSchlager, Dutch pop\nSchlager, Dutch pop, disco\nSchlager, Dutch pop, novelty\nSchlager, Dutch, polka\nSchlager, Dutch, retro\nSchlager, Euro-pop\nSchlager, Euro-pop, 80s\nSchlager, Euro-pop, 80s pop\nSchlager, Euro-pop, Greek folk\nSchlager, Euro-pop, flamenco\nSchlager, Euro-pop, pop-rock\nSchlager, Euro-pop, power ballad\nSchlager, Eurodance\nSchlager, Eurodance, 80s\nSchlager, Eurodance, 90s\nSchlager, Eurodance, Disco\nSchlager, Eurodance, Italo-disco\nSchlager, Eurodance, Schlager-Rock\nSchlager, Eurodance, Western\nSchlager, Eurodance, children's music\nSchlager, Eurodance, hardstyle\nSchlager, Eurodance, novelty pop\nSchlager, Eurodance, samba\nSchlager, European ballad\nSchlager, European folk, novelty\nSchlager, European folk, theatrical waltz\nSchlager, Garmoniksmusik, polka\nSchlager, German pop, Christmas\nSchlager, German pop, retro\nSchlager, Greek folk\nSchlager, Greek folk, dance\nSchlager, Italian folk\nSchlager, Italian pop, vintage pop\nSchlager, Italo-disco\nSchlager, Italo-disco, 80s pop\nSchlager, Italo-disco, Eurodance\nSchlager, Italo-disco, chiptune\nSchlager, Italo-disco, power ballad\nSchlager, Italo-pop\nSchlager, Latin Cumbia\nSchlager, Latin dance\nSchlager, Latin mambo, dance\nSchlager, Latin pop\nSchlager, Latin pop, 80s Europop\nSchlager, Latin pop, Dutch pop\nSchlager, Latin pop, Eurodance\nSchlager, Latin pop, Neue Deutsche Welle\nSchlager, Latin pop, disco\nSchlager, Latin pop, flamenco\nSchlager, Latin pop, salsa\nSchlager, Latin pop, vintage German pop\nSchlager, Latin, Dutch\nSchlager, Latin, Mariachi\nSchlager, Latin, Neue Deutsche Welle\nSchlager, Latin, ballad\nSchlager, Latin, boogie-woogie\nSchlager, Latin, cinematic\nSchlager, Latin, dance\nSchlager, Latin, polka\nSchlager, Latin, salsa\nSchlager, Latin, upbeat\nSchlager, Latin-pop, tropical\nSchlager, Levenslied, European pop\nSchlager, Neue Deutsche Welle\nSchlager, Neue Deutsche Welle, 80s\nSchlager, Neue Deutsche Welle, 80s dance\nSchlager, Neue Deutsche Welle, synth-pop\nSchlager, Partyschlager\nSchlager, Polka\nSchlager, Polka, Eurodance\nSchlager, Polka, German\nSchlager, Russian folk, theatrical\nSchlager, Samba\nSchlager, Ska\nSchlager, Volksmusik\nSchlager, Volksmusik, Eurodance\nSchlager, Volksmusik, folk-pop\nSchlager, big band, German pop\nSchlager, big band, rockabilly\nSchlager, boogie-woogie, party\nSchlager, cabaret\nSchlager, cabaret, German\nSchlager, cabaret, German pop\nSchlager, carnival\nSchlager, carnival, Dutch party\nSchlager, carnival, German folk\nSchlager, carnival, oompah\nSchlager, carnival, polka\nSchlager, chanson, vintage\nSchlager, children's fitness\nSchlager, children's music\nSchlager, children's music, retro\nSchlager, children's party\nSchlager, children's pop\nSchlager, children's pop, German pop\nSchlager, chiptune\nSchlager, chiptune, party\nSchlager, chiptune, retro\nSchlager, cinematic pop, German pop\nSchlager, comedy rock\nSchlager, country-folk\nSchlager, dance-pop\nSchlager, dance-pop, 80s pop\nSchlager, early rock 'n' roll\nSchlager, electronic, Après-ski\nSchlager, folk, carnival\nSchlager, folk, polka\nSchlager, folk-pop\nSchlager, folk-pop, Christian praise\nSchlager, folk-pop, German\nSchlager, folk-pop, chiptune\nSchlager, levenslied\nSchlager, levenslied, salsa\nSchlager, musical theater\nSchlager, musical theater, German pop\nSchlager, novelty, cabaret\nSchlager, novelty, polka\nSchlager, novelty, sea shanty\nSchlager, old-time folk, Appalachian\nSchlager, polka\nSchlager, polka, Dutch\nSchlager, polka, Dutch carnival\nSchlager, polka, German pop\nSchlager, polka, German theatrical\nSchlager, polka, Halloween\nSchlager, polka, big band\nSchlager, polka, children's music\nSchlager, polka, cumbia\nSchlager, polka, folk-pop\nSchlager, polka, novelty\nSchlager, polka-rock\nSchlager, pop-rock\nSchlager, retro synth\nSchlager, retro synth, children's music\nSchlager, sea shanty\nSchlager, sea shanty, children's music\nSchlager, sea shanty, novelty\nSchlager, sea shanty, party music\nSchlager, ska\nSchlager, surf rock, polka\nSchlager, synth-pop\nSchlager, synth-pop, Italo disco\nSchlager, synth-pop, Italo-disco\nSchlager, synth-pop, Neue Deutsche Welle\nSchlager, theatrical, pop\nSchlager-EDM\nSchlager-pop\nSchlager-pop chiptune\nSchlager-pop, Arabic fusion, electronic dance\nSchlager-pop, Mariachi, electronic dance\nSchlager-punk\nSchlager-rock\nSchlager-rock ska-punk\nSchlager-rock, Eurodance\nSchlager-rock, big band swing\nSchlagerpop\nScottish drill, trap\nScottish folk\nScottish folk hip-hop\nScottish marching band\nScottish traditional\nSerbian trap\nSertanejo\nSertanejo Axé\nSertanejo Axé Pop-Rock\nSertanejo Bossa Nova\nSertanejo Brega\nSertanejo Choro\nSertanejo Forró\nSertanejo Forró Axé\nSertanejo Forró Eletrônico\nSertanejo Forró Pop-Rock\nSertanejo Gospel\nSertanejo MPB\nSertanejo Raiz\nSertanejo Romântico\nSertanejo Universitário\nSertanejo Universitário MPB\nSertanejo Universitário, Bossa Nova\nSertanejo Universitário, Gospel, Ballad\nSertanejo acoustic\nSertanejo ballad\nSertanejo country rock\nSertanejo country-rock\nSertanejo de Raiz\nSertanejo de Raiz Forró\nSertanejo de Raiz MPB\nSertanejo de Raiz, Forró\nSertanejo de Raiz, Forró Eletrônico\nSertanejo de Rodeo\nSertanejo de Vaneira\nSertanejo de Verão\nSertanejo folk\nSertanejo folk-rock\nSertanejo forró\nSertanejo gospel\nSertanejo pop\nSertanejo pop, Axé, live pop\nSertanejo pop-rock\nSertanejo power ballad\nSertanejo reggae\nSertanejo rock\nSertanejo romance\nSertanejo romântico\nSertanejo tango\nSertanejo, Axé, pop-rock\nSertanejo, Boi-Bumbá\nSertanejo, Brega\nSertanejo, Forró\nSertanejo, Forró Eletrônico, Axé\nSertanejo, Forró Eletrônico, pop ballad\nSertanejo, Forró, MPB\nSertanejo, Forró, folk-pop\nSertanejo, Forró, power ballad\nSertanejo, Gaúcho, cinematic\nSertanejo, MPB\nSertanejo, MPB, Brazilian folk\nSertanejo, MPB, forró\nSertanejo, MPB, pop-rock, pop-funk\nSertanejo, blues-rock\nSevillana\nSevillana pasodoble\nShibuya-kei\nShibuya-kei acid jazz\nShibuya-kei funk-rock\nShibuya-kei future funk\nShibuya-kei, alternative dance\nShidaiqu\nShidaiqu Mandopop\nShidaiqu lounge jazz\nShidaiqu lounge-pop\nShidaiqu, Latin fusion, traditional Chinese folk\nShidaiqu, Mandopop, jazz\nShidaiqu, big band, Mandopop\nShidaiqu, big band, operatic\nShidaiqu, big band, swing\nShidaiqu, cinematic, orchestral\nShidaiqu, mambo, cinematic\nShidaiqu, orchestral, cinematic\nSichuanese hip-hop\nSichuanese rap\nSichuanese rap chiptune\nSichuanese rap funk\nSichuanese rap, trap, drill\nSichuanese trap\nSierraño\nSierreño\nSierreño Christian\nSierreño Cumbia\nSierreño Cumbia Norteña\nSierreño Norteño\nSierreño corrido\nSierreño corrido, Norteño-rock\nSierreño cumbia\nSierreño gospel\nSierreño lo-fi\nSierreño reggaeton\nSierreño trap\nSinaloense Banda\nSinhala DJ remix\nSinhala R&B\nSinhala ballad\nSinhala cinema\nSinhala classical\nSinhala dance\nSinhala devotional\nSinhala film music\nSinhala folk\nSinhala folk ballad\nSinhala folk dance\nSinhala folk fusion\nSinhala folk hip-hop\nSinhala folk pop\nSinhala folk rock\nSinhala folk, Latin folk, world music\nSinhala folk, chiptune, electronic\nSinhala folk-pop\nSinhala folk-pop rock\nSinhala folk-rock\nSinhala fusion\nSinhala ghazal\nSinhala hip hop\nSinhala indie\nSinhala kirtan\nSinhala march\nSinhala pop\nSinhala pop Latin\nSinhala pop ballad\nSinhala pop dancehall\nSinhala pop filmi\nSinhala pop folk\nSinhala pop funk disco\nSinhala pop reggae ska\nSinhala pop reggaeton\nSinhala pop retro\nSinhala pop world music\nSinhala pop, Arabic pop, upbeat dance\nSinhala pop, Eurodance, trance\nSinhala pop, Latin Cumbia\nSinhala pop, Latin cumbia\nSinhala pop, Latin funk\nSinhala pop, Latin pop\nSinhala pop, Latin pop, Caribbean\nSinhala pop, Latin pop, Caribbean pop\nSinhala pop, Latin pop, tropical\nSinhala pop, Latin, cumbia\nSinhala pop, chiptune, electronic\nSinhala pop, chiptune, electronic dance\nSinhala pop, cumbia\nSinhala pop, cumbia, Latin\nSinhala pop, dancehall, reggae\nSinhala pop, electronic dance\nSinhala pop, electronic dance, fusion\nSinhala pop, festive, nostalgic\nSinhala pop, retro electronic\nSinhala pop, worldbeat, dancehall\nSinhala pop-funk\nSinhala pop-fusion\nSinhala pop-rap\nSinhala pop-reggae\nSinhala pop-rock\nSinhala rock\nSinhala romantic\nSinhala romantic ballad\nSinhala traditional\nSinhala trap\nSka, Italo-disco, big band swing\nSka, Schlager-pop\nSka-Punk, Schlager-rock\nSka-punk, Schlager-pop\nSlavic folk\nSlavic folk dance pop\nSlavic folk electronic\nSlavic folk jazz\nSlavic folk pop-rock\nSlavic folk rock\nSlavic folk techno\nSlavic folk trap\nSlavic folk, electronic dance\nSlavic folk, electronic dance, cinematic\nSlavic folk, electronic, cinematic\nSlavic folk, electronic, dark wave\nSlavic folk, electronic, trap\nSlavic folk, trap, electronic\nSlavic hardstyle\nSlavic house\nSlovak drill\nSlovak drill trap\nSlovak folk\nSlovak folk bluegrass\nSlovak folk polka\nSlovak folk-polka\nSlovak folk-pop\nSlovak freestyle rap\nSlovak hip-hop\nSlovak hip-hop trap\nSlovak polka\nSlovak pop\nSlovak pop, Latin pop\nSlovak pop-rap\nSlovak schlager\nSlovak trap\nSoca\nSoca Afrobeats\nSoca Afropop\nSoca Bollywood\nSoca Christmas\nSoca Dancehall\nSoca Dancehall Arcade\nSoca EDM\nSoca EDM Dancehall\nSoca Gospel\nSoca Latin pop\nSoca Zouk\nSoca dance-pop\nSoca de Serra\nSoca hip-hop\nSoca pop\nSoca, Afro-Caribbean\nSoca, Zouk, Caribbean\nSoca, video game music\nSoca-pop\nSolo brass\nSolo piano\nSon Cubano\nSon Huasteco\nSon Jarocho\nSon Palesero\nSon Salsa\nSonidero\nSonidero Cumbia\nSoukous\nSoukous African folk\nSoukous Amapiano\nSoukous Benga\nSoukous Highlife\nSoukous Maracou\nSoukous Rumba\nSoukous Zouk\nSoukous funk\nSoukous gospel\nSoukous highlife\nSoukous hip-hop\nSoukous rock\nSoulful Ballad\nSouth African Gospel\nSouth African Jive\nSouth African a cappella\nSouth African choral\nSouth African country-folk\nSouth African folk\nSouth African folk-gospel\nSouth African funk\nSouth African gospel\nSouth African gospel house\nSouth African hip-hop\nSouth African house\nSouth African house chiptune\nSouth African house, 90s dance-pop\nSouth African jazz\nSouth African pop\nSouth African pop-gospel\nSouth African rock\nSouth American folk\nSouth Asian Christian\nSouth Asian Christian bhajan\nSouth Asian Christian devotional\nSouth Asian Christian folk\nSouth Asian Christian hymn\nSouth Asian Latin fusion\nSouth Asian ambient\nSouth Asian ballad\nSouth Asian ballad, electronic, romantic\nSouth Asian classical\nSouth Asian classical fusion\nSouth Asian classical, dholak, cinematic\nSouth Asian dance\nSouth Asian dance-pop\nSouth Asian devotional\nSouth Asian devotional folk\nSouth Asian devotional, electronic fusion\nSouth Asian devotional, electronic, dance\nSouth Asian electronic\nSouth Asian electronic pop\nSouth Asian film music\nSouth Asian film music, synth-pop\nSouth Asian film score\nSouth Asian film song\nSouth Asian filmi\nSouth Asian folk\nSouth Asian folk ballad\nSouth Asian folk dance\nSouth Asian folk fusion\nSouth Asian folk hip-hop\nSouth Asian folk pop\nSouth Asian folk pop-rock\nSouth Asian folk rock\nSouth Asian folk waltz\nSouth Asian folk, Bhangra, Bollywood\nSouth Asian folk, Bollywood, spiritual\nSouth Asian folk, Christian devotional\nSouth Asian folk, Latin pop, acoustic\nSouth Asian folk, Middle Eastern folk, devotional\nSouth Asian folk, Western classical\nSouth Asian folk, ambient electronica\nSouth Asian folk, ambient, cinematic\nSouth Asian folk, boom-bap hip-hop\nSouth Asian folk, chiptune, electronic dance\nSouth Asian folk, cinematic, modern\nSouth Asian folk, electronic\nSouth Asian folk, electronic dance\nSouth Asian folk, electronic dance, fusion\nSouth Asian folk, electronic fusion\nSouth Asian folk, electronic pop\nSouth Asian folk, electronic pop, pop-rock\nSouth Asian folk, electronic pop, rock\nSouth Asian folk, electronic, ambient\nSouth Asian folk, electronic, cinematic\nSouth Asian folk, electronic, duet\nSouth Asian folk, electronic, fusion\nSouth Asian folk, electronic, melodic\nSouth Asian folk, electronic, trap\nSouth Asian folk, festive, pop\nSouth Asian folk, filmi, devotional\nSouth Asian folk, filmi, duet\nSouth Asian folk, ghazal\nSouth Asian folk, hard electronic, dance\nSouth Asian folk, hip-hop, flamenco\nSouth Asian folk, orchestral, ghazal\nSouth Asian folk, pop-rock\nSouth Asian folk, retro electronic\nSouth Asian folk, retro electronic, pop\nSouth Asian folk, trap, R&B\nSouth Asian folk, trap, ambient\nSouth Asian folk, vintage pop\nSouth Asian folk, world music\nSouth Asian folk, world music, fusion\nSouth Asian folk-fusion\nSouth Asian folk-pop\nSouth Asian folk-pop funk rock\nSouth Asian folk-pop rock\nSouth Asian funk-rock\nSouth Asian fusion\nSouth Asian fusion hip-hop\nSouth Asian fusion pop\nSouth Asian fusion rock\nSouth Asian ghazal\nSouth Asian hip-hop\nSouth Asian hip-hop trap\nSouth Asian hip-hop, moombahton\nSouth Asian melancholic\nSouth Asian party\nSouth Asian patriotic\nSouth Asian pop\nSouth Asian pop 80s\nSouth Asian pop Eurodance\nSouth Asian pop Latin\nSouth Asian pop Latin dance\nSouth Asian pop R&B\nSouth Asian pop chiptune\nSouth Asian pop dancehall\nSouth Asian pop funk disco\nSouth Asian pop funk reggae\nSouth Asian pop fusion\nSouth Asian pop hip-hop\nSouth Asian pop rock\nSouth Asian pop trap\nSouth Asian pop, Eurodance\nSouth Asian pop, Latin dance\nSouth Asian pop, Latin pop\nSouth Asian pop, Latin, electronic\nSouth Asian pop, Latin, flamenco\nSouth Asian pop, Latin, world music\nSouth Asian pop, Middle Eastern pop, electronic dance\nSouth Asian pop, chiptune, electronic dance\nSouth Asian pop, cumbia\nSouth Asian pop, cumbia, Latin pop\nSouth Asian pop, cumbia, chiptune\nSouth Asian pop, dance, electronic\nSouth Asian pop, electronic dance\nSouth Asian pop, electronic dance music\nSouth Asian pop, electronic dance, fusion\nSouth Asian pop, electronic dance, hard rock\nSouth Asian pop, electronic dance, reggaeton\nSouth Asian pop, electronic dance, rock\nSouth Asian pop, hard rock, EDM\nSouth Asian pop, hip-hop, breakbeat\nSouth Asian pop, hip-hop, dance\nSouth Asian pop, hip-hop, funk\nSouth Asian pop, retro electronic, chiptune\nSouth Asian pop, retro video game\nSouth Asian pop, rock, electronic\nSouth Asian pop, trap\nSouth Asian pop, trap, EDM\nSouth Asian pop, trap, R&B\nSouth Asian pop-funk\nSouth Asian pop-fusion\nSouth Asian pop-rock\nSouth Asian pop-rock, hard rock\nSouth Asian protest\nSouth Asian rock\nSouth Asian romantic ballad\nSouth Asian romantic pop\nSouth Asian soul\nSouth Asian spiritual\nSouth Asian vocal\nSouth Asian wedding\nSouth Asian wedding music\nSouth Indian Christian\nSouth Indian Christian bhajan\nSouth Indian Christian devotional\nSouth Indian Christian folk\nSouth Indian Christian hymn\nSouth Indian Christian music\nSouth Indian Christian music chiptune\nSouth Indian Christian pop\nSouth Indian Christian pop-rock\nSouth Indian Christmas\nSouth Indian R&B\nSouth Indian ballad\nSouth Indian bhajan\nSouth Indian children's\nSouth Indian children's music\nSouth Indian dance\nSouth Indian devotional\nSouth Indian devotional pop\nSouth Indian devotional, electronic, upbeat\nSouth Indian electronic\nSouth Indian electronic dance\nSouth Indian film music\nSouth Indian film music R&B\nSouth Indian film music R&B funk\nSouth Indian film music funk\nSouth Indian film music funk electronic\nSouth Indian film music funk-pop\nSouth Indian film music funk-rock\nSouth Indian film music jazz fusion\nSouth Indian film music pop\nSouth Indian film music pop-rock\nSouth Indian film music, 90s R&B, hip-hop\nSouth Indian film music, Arabic pop\nSouth Indian film music, EDM, trap\nSouth Indian film music, Eurodance\nSouth Indian film music, European folk\nSouth Indian film music, Latin dance, fusion\nSouth Indian film music, Latin pop, fusion\nSouth Indian film music, Latin salsa\nSouth Indian film music, Latin, flamenco\nSouth Indian film music, Latin, hip-hop\nSouth Indian film music, Middle Eastern fusion, electronic\nSouth Indian film music, R&B, pop\nSouth Indian film music, R&B, trap\nSouth Indian film music, Western pop\nSouth Indian film music, Western pop, dance\nSouth Indian film music, breakbeat, fusion\nSouth Indian film music, chiptune, dance-pop\nSouth Indian film music, dance, hip-hop\nSouth Indian film music, electronic dance\nSouth Indian film music, electronic dance, Latin fusion\nSouth Indian film music, electronic dance, fusion\nSouth Indian film music, electronic, trap\nSouth Indian film music, folk pop, cinematic\nSouth Indian film music, funk, electronic\nSouth Indian film music, funk, pop\nSouth Indian film music, hard rock\nSouth Indian film music, pop, electronic\nSouth Indian film music, pop, fusion\nSouth Indian film music, pop, hip-hop\nSouth Indian film music, pop-rap, electronic\nSouth Indian film music, pop-rock\nSouth Indian film music, pop-rock, shred guitar\nSouth Indian film music, synth-pop, dance-pop\nSouth Indian film music, trap, R&B\nSouth Indian film music, world fusion, romantic duet\nSouth Indian film score\nSouth Indian film-pop\nSouth Indian filmi\nSouth Indian folk\nSouth Indian folk dance\nSouth Indian folk fusion\nSouth Indian folk pop\nSouth Indian folk rock\nSouth Indian folk, Bollywood, Sufi\nSouth Indian folk, Carnatic, devotional\nSouth Indian folk, Christian devotional, dance anthem\nSouth Indian folk, Christian devotional, upbeat\nSouth Indian folk, Christian music\nSouth Indian folk, Christian music, world music\nSouth Indian folk, Christian praise\nSouth Indian folk, chiptune, electronic dance\nSouth Indian folk, cinematic pop\nSouth Indian folk, cinematic, devotional\nSouth Indian folk, contemporary Christian\nSouth Indian folk, devotional, upbeat\nSouth Indian folk, electronic dance\nSouth Indian folk, electronic dance, Carnatic fusion\nSouth Indian folk, electronic dance, devotional\nSouth Indian folk, electronic dance, fusion\nSouth Indian folk, electronic dance, kuthu\nSouth Indian folk, electronic dance, surf-rock\nSouth Indian folk, electronic pop\nSouth Indian folk, electronic, devotional\nSouth Indian folk, electronic, upbeat\nSouth Indian folk, electronic, world fusion\nSouth Indian folk, funk-rock, hip-hop\nSouth Indian folk, pop, hip-hop\nSouth Indian folk-dance\nSouth Indian folk-electronic\nSouth Indian folk-fusion\nSouth Indian folk-pop\nSouth Indian folk-pop hip-hop\nSouth Indian funk\nSouth Indian funk pop\nSouth Indian fusion\nSouth Indian fusion pop\nSouth Indian fusion pop rock\nSouth Indian gospel\nSouth Indian hip-hop\nSouth Indian hip-hop chiptune\nSouth Indian hip-hop dancehall\nSouth Indian hip-hop funk-rock\nSouth Indian hip-hop moombahton\nSouth Indian hip-hop trap\nSouth Indian hip-hop, Arabic fusion\nSouth Indian hip-hop, breakbeat\nSouth Indian hip-hop, cinematic orchestral\nSouth Indian hip-hop, electronic dance\nSouth Indian hip-hop, electronic dance music\nSouth Indian hip-hop, hardstyle, EDM\nSouth Indian hip-hop, hardstyle, trap\nSouth Indian hip-hop, moombahton, trap\nSouth Indian hip-hop, trap, EDM\nSouth Indian hip-hop, trap, funk\nSouth Indian percussion\nSouth Indian pop\nSouth Indian pop chiptune\nSouth Indian pop funk\nSouth Indian pop funk-rock electronic\nSouth Indian pop fusion\nSouth Indian pop hip-hop\nSouth Indian pop, dance, electronic\nSouth Indian pop, dance, fusion\nSouth Indian pop, electronic, trap\nSouth Indian pop, hip-hop\nSouth Indian pop, hip-hop, electronic\nSouth Indian pop, hip-hop, electronic dance\nSouth Indian pop, world music, hip-hop\nSouth Indian pop-dance\nSouth Indian pop-funk\nSouth Indian pop-rock\nSouth Indian protest\nSouth Indian rock\nSouth Indian wedding music\nSoutheast Asian ballad\nSoutheast Asian classical\nSoutheast Asian devotional\nSoutheast Asian film music\nSoutheast Asian film score\nSoutheast Asian folk\nSoutheast Asian folk jazz\nSoutheast Asian folk pop\nSoutheast Asian folk pop-rock\nSoutheast Asian folk rock\nSoutheast Asian folk, video game, synth pop\nSoutheast Asian folk-pop\nSoutheast Asian folk-pop rock\nSoutheast Asian fusion\nSoutheast Asian lullaby\nSoutheast Asian pop\nSoutheast Asian pop Latin\nSoutheast Asian pop ballad\nSoutheast Asian pop chiptune\nSoutheast Asian pop funky\nSoutheast Asian pop retro synth\nSoutheast Asian pop rock\nSoutheast Asian pop trap\nSoutheast Asian pop, Latin cha-cha-cha\nSoutheast Asian pop, Luk Thung\nSoutheast Asian pop, cumbia, salsa\nSoutheast Asian pop, electronic\nSoutheast Asian pop, hard rock, chiptune\nSoutheast Asian pop, pop-rock, vintage\nSoutheast Asian pop, retro synth-pop\nSoutheast Asian pop-rock\nSoutheast Asian power ballad\nSoutheast Asian rock\nSoutheast Asian slow rock\nSoutheast Asian traditional\nSouthern Christian hip-hop\nSouthern G-funk\nSouthern G-funk hip-hop\nSouthern Gospel\nSouthern Gospel Hip Hop\nSouthern Gospel R&B\nSouthern Gospel blues-rock\nSouthern Gospel hip-hop\nSouthern Gothic\nSouthern Gothic Hip Hop\nSouthern Gothic blues\nSouthern Gothic hip-hop\nSouthern Gothic rock\nSouthern Hip Hop\nSouthern Italian folk\nSouthern R&B\nSouthern R&B funk\nSouthern R&B hip-hop\nSouthern R&B, New Jack Swing\nSouthern Trap\nSouthern drill\nSouthern funk R&B\nSouthern gangsta rap\nSouthern gospel\nSouthern gospel country\nSouthern gospel, country-blues\nSouthern hip hop\nSouthern hip-hop\nSouthern hip-hop G-funk\nSouthern hip-hop R&B\nSouthern hip-hop chiptune\nSouthern hip-hop country\nSouthern hip-hop crunk\nSouthern hip-hop crunk snap\nSouthern hip-hop gospel\nSouthern hip-hop lo-fi\nSouthern hip-hop neo-soul\nSouthern hip-hop trap\nSouthern hip-hop vaporwave\nSouthern hip-hop, G-funk\nSouthern hip-hop, G-funk, crunk\nSouthern hip-hop, Latin hip-hop\nSouthern hip-hop, R&B\nSouthern hip-hop, cinematic\nSouthern hip-hop, cinematic orchestral\nSouthern hip-hop, cinematic synth\nSouthern hip-hop, cinematic, ambient\nSouthern hip-hop, cloud rap, vaporwave\nSouthern hip-hop, crunk\nSouthern hip-hop, crunk, Memphis rap\nSouthern hip-hop, crunk, dirty south\nSouthern hip-hop, crunk, gangsta rap\nSouthern hip-hop, crunk, holiday rap\nSouthern hip-hop, crunk, snap\nSouthern hip-hop, crunk, trap\nSouthern hip-hop, drill\nSouthern hip-hop, funk-pop\nSouthern hip-hop, horrorcore, cinematic\nSouthern hip-hop, industrial trap, rock-infused rap\nSouthern hip-hop, melodic trap\nSouthern hip-hop, neo-soul\nSouthern hip-hop, psychedelic soul\nSouthern hip-hop, trap\nSouthern hip-hop, trap, crunk\nSouthern rock\nSouthern rock blues\nSouthern rock blues rock\nSouthern rock blues-rock\nSouthern rock country rap\nSouthern rock hip-hop\nSouthern rock soul\nSouthern rock trap-hop\nSouthern rock, Americana, roots rock\nSouthern rock, blues rock, New Orleans\nSouthern rock, conscious hip-hop\nSouthern rock, country\nSouthern rock, country blues\nSouthern rock, country gospel\nSouthern rock, country-gospel\nSouthern rock, country-gospel, cinematic\nSouthern soul\nSouthern soul G-funk\nSouthern soul hip-hop\nSouthern trap\nSoviet anthem\nSoviet art song\nSoviet ballad\nSoviet bard\nSoviet brass\nSoviet brass march\nSoviet cabaret\nSoviet cartoon\nSoviet chanson\nSoviet children's march\nSoviet children's music\nSoviet children's, Latin, synth pop\nSoviet children's, big band swing\nSoviet children's, big band, swing\nSoviet choral\nSoviet disco funk\nSoviet disco-funk\nSoviet disco-pop\nSoviet estrada\nSoviet estrada cabaret\nSoviet estrada chiptune\nSoviet estrada funk\nSoviet estrada lounge\nSoviet estrada lounge jazz\nSoviet estrada pop\nSoviet estrada reggae\nSoviet estrada, Latin bolero\nSoviet estrada, bolero\nSoviet estrada, surf rock\nSoviet estrada, synth-pop\nSoviet folk\nSoviet folk march\nSoviet folk-pop\nSoviet folk-rock\nSoviet funk\nSoviet funk disco\nSoviet funk-pop\nSoviet funk-rock\nSoviet jazz-pop\nSoviet march\nSoviet march, sea shanty, theatrical\nSoviet military ballad\nSoviet military march\nSoviet new wave\nSoviet new wave surf rock\nSoviet novelty\nSoviet novelty, Latin, big band\nSoviet orchestral\nSoviet patriotic\nSoviet pop\nSoviet pop Latin\nSoviet pop cabaret\nSoviet pop chiptune\nSoviet pop disco\nSoviet pop exotica ska\nSoviet pop surf-rock\nSoviet pop, Latin exotica\nSoviet pop, Latin jazz, exotica\nSoviet pop, Latin pop, retro\nSoviet pop, Latin pop, theatrical\nSoviet pop, Latin, cabaret\nSoviet pop, Latin, cinematic\nSoviet pop, Latin, theatrical\nSoviet pop, big band swing\nSoviet pop, big band, swing\nSoviet pop, big band, theatrical\nSoviet pop, bossa nova\nSoviet pop, mambo, big band\nSoviet pop, spy movie, exotica\nSoviet pop, tropical exotica\nSoviet pop-funk\nSoviet pop-rock\nSoviet rock\nSoviet rock space rock\nSoviet rock, surf rock\nSoviet romance\nSoviet surf rock\nSoviet swing\nSoviet synth-pop\nSoviet tango\nSoviet-era Latin pop\nSoviet-era anthem\nSoviet-era art song\nSoviet-era ballad\nSoviet-era children's march\nSoviet-era children's music\nSoviet-era educational\nSoviet-era estrada\nSoviet-era estrada bossa nova\nSoviet-era estrada jazz\nSoviet-era estrada pop\nSoviet-era estrada pop, Latin cumbia\nSoviet-era estrada rock\nSoviet-era estrada tango\nSoviet-era estrada, lounge jazz\nSoviet-era estrada, mambo\nSoviet-era film score\nSoviet-era jazz-pop\nSoviet-era mambo\nSoviet-era march\nSoviet-era military ballad, chiptune, retro RPG\nSoviet-era military march\nSoviet-era orchestral\nSoviet-era patriotic\nSoviet-era power ballad\nSoviet-era propaganda\nSoviet-era romance\nSoviet-era surf rock\nSoviet-era synth\nSoviet-era waltz\nSoviet-era, theatrical, cinematic\nSoviet-style march\nSoviet-wave synth-pop\nSovietwave\nSovietwave darkwave\nSovietwave synth-pop\nSovietwave, Italo-disco\nSovietwave, Italo-disco, synth-pop\nSovietwave, synth-pop, post-punk\nSpanish Christian hymn\nSpanish Christmas\nSpanish Christmas carol\nSpanish Christmas, big band, vintage\nSpanish Christmas, chiptune\nSpanish Christmas, chiptune, festive\nSpanish Christmas, folk, choral\nSpanish Christmas, polka, festive\nSpanish Christmas, retro synth\nSpanish Christmas, retro synth, video game music\nSpanish Christmas, synth pop\nSpanish Christmas, vintage, theatrical\nSpanish R&B\nSpanish R&B lo-fi hip hop\nSpanish R&B lo-fi hip-hop\nSpanish R&B, hip-hop\nSpanish R&B, trap\nSpanish Rumba\nSpanish acoustic\nSpanish alternative rock\nSpanish anthem\nSpanish art song\nSpanish ballad\nSpanish ballad tango\nSpanish ballad, power rock\nSpanish ballad, reggaeton, flamenco\nSpanish ballad, rock opera\nSpanish ballad, theatrical, Christmas\nSpanish ballad, theatrical, cinematic\nSpanish banda\nSpanish big band\nSpanish bolero\nSpanish bolero, mambo, salsa\nSpanish bullfight theme\nSpanish cabaret\nSpanish carnival\nSpanish chanson\nSpanish chanson cool jazz blues\nSpanish choral\nSpanish classical\nSpanish copla\nSpanish copla, big band, swing\nSpanish copla, military march\nSpanish copla, operatic, theatrical\nSpanish copla, orchestral, theatrical\nSpanish copla, pasodoble\nSpanish copla, patriotic anthem\nSpanish dance hall\nSpanish disco-funk\nSpanish disco-pop\nSpanish drill\nSpanish drill trap\nSpanish drill, lo-fi hip hop\nSpanish drill, reggaeton\nSpanish drill, trap, Eastern European\nSpanish drill, vaporwave\nSpanish emo rap\nSpanish emo-rap\nSpanish festival\nSpanish festival march\nSpanish flamenco\nSpanish folk\nSpanish folk ballad\nSpanish folk cabaret\nSpanish folk cumbia\nSpanish folk flamenco\nSpanish folk fusion\nSpanish folk lo-fi\nSpanish folk march\nSpanish folk parody\nSpanish folk punk\nSpanish folk rock\nSpanish folk rumba\nSpanish folk satire\nSpanish folk waltz\nSpanish folk, Christmas, villancico\nSpanish folk, Latin rock\nSpanish folk, Sevillana, cinematic\nSpanish folk, baroque, theatrical\nSpanish folk, big band\nSpanish folk, chiptune\nSpanish folk, cumbia, festive\nSpanish folk, cumbia, theatrical\nSpanish folk, dark trap, ambient\nSpanish folk, electronic pop\nSpanish folk, festive, cinematic\nSpanish folk, flamenco, rumba\nSpanish folk, folk-rock\nSpanish folk, mambo, salsa\nSpanish folk, musical theater\nSpanish folk, operatic, theatrical\nSpanish folk, pasodoble\nSpanish folk, pasodoble, big band\nSpanish folk, polka\nSpanish folk, polka, rock\nSpanish folk, polka, theatrical\nSpanish folk, revolutionary folk, baroque-folk\nSpanish folk, sea shanty, rockabilly\nSpanish folk, theatrical, orchestral\nSpanish folk, theatrical, ragtime\nSpanish folk, villancico\nSpanish folk-blues\nSpanish folk-polka\nSpanish folk-pop\nSpanish folk-rock\nSpanish folk-rock, hard rock\nSpanish football chant\nSpanish freestyle\nSpanish funk-rock\nSpanish gangsta rap\nSpanish guitar\nSpanish guitar, French hip-hop, ambient\nSpanish hard rock\nSpanish hip hop\nSpanish hip-hop\nSpanish hip-hop boom-bap\nSpanish hip-hop chiptune\nSpanish hip-hop funk\nSpanish hip-hop lo-fi\nSpanish hip-hop lo-fi trap\nSpanish hip-hop trap\nSpanish hip-hop, Latin house\nSpanish hip-hop, cinematic, ambient\nSpanish hip-hop, indie-pop\nSpanish hip-hop, retro video game\nSpanish hip-hop, trap, boom-bap\nSpanish hymn\nSpanish indie pop\nSpanish indie rock\nSpanish indie-folk\nSpanish indie-pop hip-hop\nSpanish lullaby\nSpanish march\nSpanish marching band\nSpanish musical\nSpanish novelty\nSpanish orchestral\nSpanish polka\nSpanish pop\nSpanish pop R&B\nSpanish pop ballad\nSpanish pop big band\nSpanish pop cumbia\nSpanish pop cumbia chiptune\nSpanish pop flamenco\nSpanish pop lo-fi hip-hop\nSpanish pop reggaeton\nSpanish pop rock\nSpanish pop rumba\nSpanish pop, 80s synth, festive\nSpanish pop, 80s synth, theatrical\nSpanish pop, Europop, Latin pop\nSpanish pop, Latin, flamenco\nSpanish pop, R&B, synth-pop\nSpanish pop, big band\nSpanish pop, big-band, theatrical\nSpanish pop, boom-bap hip-hop\nSpanish pop, cinematic orchestral\nSpanish pop, copla, theatrical\nSpanish pop, flamenco\nSpanish pop, flamenco pop, 80s pop\nSpanish pop, flamenco, cinematic\nSpanish pop, flamenco, copla\nSpanish pop, flamenco, synth pop\nSpanish pop, hardstyle\nSpanish pop, lo-fi hip hop\nSpanish pop, retro, big-band\nSpanish pop, rock and roll, salsa\nSpanish pop, rock, bolero\nSpanish pop, rock, salsa\nSpanish pop, synth-pop, retro\nSpanish pop-R&B\nSpanish pop-folk\nSpanish pop-funk\nSpanish pop-rap\nSpanish pop-reggaeton\nSpanish pop-rock\nSpanish pop-rock, 80s new wave\nSpanish pop-rock, J-pop\nSpanish pop-rock, Latin pop, 80s synth\nSpanish pop-rock, disco-funk, cumbia\nSpanish pop-rock, flamenco, theatrical\nSpanish pop-rock, garage rock\nSpanish pop-rock, new wave\nSpanish pop-rock, synth-pop, power ballad\nSpanish pop-rumba\nSpanish pop-trap\nSpanish popular\nSpanish power ballad\nSpanish punk rock\nSpanish rap\nSpanish rap, boom-bap, dubstep\nSpanish rap, chiptune\nSpanish rap, chiptune, boom-bap\nSpanish rap, dubstep, hardstyle\nSpanish rap, hard trap, hardstyle\nSpanish rap, hardstyle, big room house\nSpanish rap, lo-fi hip-hop\nSpanish rap, trap, chiptune\nSpanish reggae\nSpanish regional anthem\nSpanish rock\nSpanish rock Americana\nSpanish rock and roll\nSpanish rock ballad\nSpanish rock blues\nSpanish rock cabaret\nSpanish rock funk reggae\nSpanish rock post-punk\nSpanish rock punk\nSpanish rock rumba\nSpanish rock surf rock\nSpanish rock, Americana, country rock\nSpanish rock, Latin rock, rumba\nSpanish rock, Latin rumba\nSpanish rock, Latin ska\nSpanish rock, country-rock, Americana\nSpanish rock, cumbia, Latin rock\nSpanish rock, new wave, post-punk\nSpanish rock, new wave, power pop\nSpanish rock, polka, ska\nSpanish rock, pop-rock\nSpanish rock, pub rock, rockabilly\nSpanish rock, punk rock\nSpanish rock, punk rock, oud\nSpanish rock, rockabilly\nSpanish rock, rockabilly, country rock\nSpanish rock, rockabilly, surf rock\nSpanish rock, rockabilly, theatrical\nSpanish rock, surf rock\nSpanish rockabilly\nSpanish romantic ballad\nSpanish romantic pop\nSpanish rumba\nSpanish rumba, hip-hop\nSpanish show tune\nSpanish singer-songwriter\nSpanish sports anthem\nSpanish tango\nSpanish tech-house\nSpanish theatrical\nSpanish trap\nSpanish trap, R&B, lo-fi\nSpanish trap, atmospheric R&B\nSpanish trap, cloud rap\nSpanish trap, deep house, reggaeton\nSpanish trap, emo rap\nSpanish trap, emo-rap\nSpanish trap, lo-fi hip-hop\nSpanish trap, pluggnb\nSpanish trap-pop\nSpanish urban pop\nSpanish villancico\nSpanish worship\nSpanish-influenced instrumental\nSpanish-style C-pop\nSpiritual Arabic\nSri Lankan ballad\nSri Lankan folk\nSri Lankan pop\nSufi Bhangra\nSufi Kirtan\nSufi Mawwal\nSufi Nasheed\nSufi Qawwali\nSufi a cappella\nSufi aalap\nSufi aat\nSufi ambient\nSufi bhajan\nSufi chant\nSufi devotional\nSufi electronic\nSufi electronica\nSufi folk\nSufi folk fusion\nSufi folk pop\nSufi folk, Bhangra, ambient\nSufi folk-pop\nSufi fusion\nSufi music\nSufi pop\nSufi pop fusion\nSufi pop rock\nSufi pop-rock\nSufi qawwali\nSufi rock\nSufi rock Bollywood\nSufi rock Indian folk\nSufi rock funk\nSufi rock pop\nSufi rock pop-rock\nSufi rock psychedelic blues\nSufi rock, Bollywood devotional\nSufi rock, Bollywood pop-rock\nSufi rock, Kuthu, Christian worship\nSufi rock, electronic dance\nSufi trap\nSufi vocal\nSufi-folk\nSufi-inspired\nSufi-inspired aalap\nSufi-pop\nSufi-style aalap\nSundanese Pop\nSundanese ballad\nSundanese chiptune\nSundanese devotional\nSundanese electronic\nSundanese folk\nSundanese folk pop\nSundanese folk-pop\nSundanese funk rock\nSundanese hip-hop\nSundanese keroncong\nSundanese music\nSundanese pop\nSundanese pop dangdut\nSundanese pop gospel\nSundanese pop reggae dancehall\nSundanese pop rock\nSundanese pop, Dangdut\nSundanese pop, dancehall, reggaeton\nSundanese pop, dangdut koplo\nSundanese pop, dangdut koplo, electronic\nSundanese pop, rock\nSundanese pop, rock and roll, dangdut\nSundanese pop, synth-pop\nSundanese pop-rap\nSundanese pop-rock\nSundanese pop-rock chiptune\nSundanese pop-rock, hard rock\nSundanese pop-rock, surf rock\nSundanese power ballad\nSundanese punk\nSundanese rock\nSundanese rock ballad\nSundanese traditional\nSuomirock\nSwahili drill\nSwahili hip-hop\nSwahili hip-hop trap\nSwahili trap\nSwedish Christmas\nSwedish Christmas pop\nSwedish Christmas, orchestral, vintage\nSwedish EDM\nSwedish EDM hip hop\nSwedish Eurodance\nSwedish R&B\nSwedish R&B lo-fi hip-hop\nSwedish R&B trap\nSwedish R&B, hip-hop\nSwedish R&B, trap hip-hop\nSwedish R&B, trap, atmospheric hip-hop\nSwedish art song\nSwedish ballad\nSwedish cabaret\nSwedish chanson\nSwedish children's music\nSwedish comedy-pop\nSwedish country-folk\nSwedish country-gospel\nSwedish country-pop\nSwedish country-rock\nSwedish dance-pop\nSwedish dancehall\nSwedish disco-pop\nSwedish drill\nSwedish drill trap\nSwedish drill, afro-trap, chiptune\nSwedish drill, trap\nSwedish electropop\nSwedish folk\nSwedish folk EDM\nSwedish folk bossa nova\nSwedish folk cabaret\nSwedish folk pop\nSwedish folk schlager\nSwedish folk tango\nSwedish folk, Latin American, cabaret\nSwedish folk, bluegrass, country\nSwedish folk, bossa nova\nSwedish folk, cabaret, musical theater\nSwedish folk, chanson, gypsy jazz\nSwedish folk, country, blues\nSwedish folk, cumbia, salsa\nSwedish folk, dansband, Christian\nSwedish folk, funk, electronic dance\nSwedish folk, schlager\nSwedish folk, schlager, country\nSwedish folk, theatrical folk\nSwedish folk, theatrical, cabaret\nSwedish folk-country\nSwedish folk-polka\nSwedish folk-pop\nSwedish folk-pop, Eurodance\nSwedish folk-rock\nSwedish folk-swing\nSwedish funk-rap\nSwedish funk-reggae\nSwedish gangsta rap\nSwedish gospel\nSwedish gospel schlager\nSwedish hip-hop\nSwedish hip-hop Afrobeat\nSwedish hip-hop G-funk\nSwedish hip-hop chiptune\nSwedish hip-hop funk\nSwedish hip-hop lo-fi\nSwedish hip-hop nu-disco funk\nSwedish hip-hop pop\nSwedish hip-hop reggaeton\nSwedish hip-hop trap\nSwedish hip-hop, G-funk\nSwedish hip-hop, Latin hip-hop\nSwedish hip-hop, Latin trap\nSwedish hip-hop, Middle Eastern pop\nSwedish hip-hop, chiptune, cinematic\nSwedish hip-hop, chiptune, hyperpop\nSwedish hip-hop, lo-fi hip hop\nSwedish hip-hop, pop-rap, electronic\nSwedish hip-hop, trap\nSwedish hip-hop, trap, atmospheric\nSwedish hip-hop, trap, cloud rap\nSwedish hip-hop, trap, futuristic\nSwedish hip-hop, trap, world music\nSwedish house\nSwedish house, Afrobeat, dancehall\nSwedish hymn\nSwedish indie folk\nSwedish indie pop\nSwedish indie pop-rock\nSwedish indie rock\nSwedish indie-folk\nSwedish indie-pop\nSwedish jazz\nSwedish jazz-pop\nSwedish novelty\nSwedish party\nSwedish party anthem\nSwedish party-rap\nSwedish polka\nSwedish pop\nSwedish pop R&B\nSwedish pop ballad\nSwedish pop bossa nova\nSwedish pop chiptune\nSwedish pop deep house\nSwedish pop jazz\nSwedish pop lo-fi hip-hop\nSwedish pop reggaeton\nSwedish pop, 80s Europop\nSwedish pop, 80s new wave\nSwedish pop, 80s schlager\nSwedish pop, 90s hip-hop\nSwedish pop, Afrobeats, tropical house\nSwedish pop, EDM\nSwedish pop, EDM, dance-pop\nSwedish pop, EDM, hip-hop\nSwedish pop, EDM, reggaeton\nSwedish pop, Eurodance\nSwedish pop, Eurodance, funk\nSwedish pop, Eurodance, lo-fi\nSwedish pop, J-pop\nSwedish pop, Latin pop\nSwedish pop, Latin pop, reggaeton\nSwedish pop, Latin pop, tropical\nSwedish pop, R&B\nSwedish pop, R&B, Afrobeats\nSwedish pop, R&B, electronic\nSwedish pop, R&B, hip-hop\nSwedish pop, R&B, trap\nSwedish pop, Schlager\nSwedish pop, afrobeats, dancehall\nSwedish pop, bossa nova\nSwedish pop, chiptune\nSwedish pop, country-pop\nSwedish pop, dancehall, reggaeton\nSwedish pop, deep house\nSwedish pop, disco-funk\nSwedish pop, folk, schlager\nSwedish pop, hyperpop, J-pop\nSwedish pop, reggaeton, Christmas\nSwedish pop, reggaeton, Latin pop\nSwedish pop, reggaeton, anthemic\nSwedish pop, reggaeton, dancehall\nSwedish pop, retro pop, bubblegum pop\nSwedish pop, schlager\nSwedish pop, schlager, Christmas\nSwedish pop, schlager, Eurodance\nSwedish pop, schlager, funk\nSwedish pop, schlager, summer pop\nSwedish pop, smooth jazz\nSwedish pop, trap, future bass\nSwedish pop-EDM\nSwedish pop-R&B\nSwedish pop-R&B future bass\nSwedish pop-dance\nSwedish pop-folk\nSwedish pop-funk\nSwedish pop-gospel\nSwedish pop-house\nSwedish pop-rap\nSwedish pop-reggae\nSwedish pop-rock\nSwedish pop-rock cabaret\nSwedish pop-rock, complextro\nSwedish pop-schlager\nSwedish pop-soul\nSwedish pop-trap\nSwedish power ballad\nSwedish punk rock\nSwedish rap, dancehall, trap\nSwedish reggae\nSwedish rock\nSwedish rock 'n' roll\nSwedish rock and roll\nSwedish rock cabaret\nSwedish rock funk soul\nSwedish rock, 80s new wave\nSwedish rock, dansband, schlager\nSwedish rock, dansband, theatrical rock\nSwedish rock, new wave\nSwedish rock, new wave, schlager\nSwedish rock, rockabilly, country rock\nSwedish rock, rockabilly, retro\nSwedish rock, schlager\nSwedish rock, schlager, anthemic rock\nSwedish rockabilly\nSwedish schlager\nSwedish schlager, Latin pop\nSwedish schlager, Latin salsa\nSwedish schlager, children's music\nSwedish schlager, novelty, Christmas\nSwedish schlager, polka, chiptune\nSwedish schlager, winter pop\nSwedish schlager-pop\nSwedish sea shanty\nSwedish singer-songwriter\nSwedish summer pop\nSwedish trap\nSwedish trap, cloud rap\nSwedish trap, cloud rap, emo trap\nSwedish trap, melodic pop\nSwedish trap-pop\nSwedish waltz\nSwiss German ballad\nSwiss House\nSwiss folk\nSwiss-German children's\nSwiss-German drill\nSwiss-German folk\nSwiss-German folk-pop\nSwiss-German hip-hop\nSwiss-German trap\nT-Pop\nT-Pop City Pop Eurobeat\nT-Pop City Pop Funk\nT-Pop City Pop R&B\nT-Pop City Pop funk\nT-Pop EDM\nT-Pop EDM hip-hop\nT-Pop Eurodance\nT-Pop J-Pop\nT-Pop J-Pop anime\nT-Pop J-pop\nT-Pop J-pop anime\nT-Pop R&B\nT-Pop R&B hip-hop\nT-Pop R&B jazz\nT-Pop R&B neo-soul\nT-Pop anime\nT-Pop anime soundtrack\nT-Pop ballad\nT-Pop chiptune\nT-Pop city pop\nT-Pop city pop funk\nT-Pop dance-pop\nT-Pop electropop future bass\nT-Pop funk\nT-Pop funk R&B\nT-Pop funk breakbeat\nT-Pop funk city pop\nT-Pop funk dance-pop\nT-Pop funk disco\nT-Pop funk hip-hop\nT-Pop funk-pop\nT-Pop future bass\nT-Pop future funk\nT-Pop hip-hop\nT-Pop lo-fi hip hop\nT-Pop lo-fi hip-hop\nT-Pop lo-fi pop\nT-Pop trap-soul\nT-Pop, Christian Contemporary\nT-Pop, City Pop, funk\nT-Pop, EDM\nT-Pop, EDM, dance-pop\nT-Pop, EDM, electro-pop\nT-Pop, EDM, future bass\nT-Pop, EDM, hardstyle\nT-Pop, EDM, hip-hop\nT-Pop, EDM, trance\nT-Pop, Eurobeat, City Pop\nT-Pop, Eurobeat, J-Pop\nT-Pop, Eurodance\nT-Pop, Eurodance, 90s dance-pop\nT-Pop, Eurodance, J-Pop\nT-Pop, Eurodance, J-pop\nT-Pop, Eurodance, Latin house\nT-Pop, Eurodance, Trance\nT-Pop, Eurodance, bubblegum pop\nT-Pop, Eurodance, cinematic\nT-Pop, Eurodance, dance-pop\nT-Pop, Eurodance, happy hardcore\nT-Pop, J-Pop, anime\nT-Pop, J-Pop, chiptune\nT-Pop, J-Rock\nT-Pop, J-pop, anime\nT-Pop, J-rock\nT-Pop, K-pop\nT-Pop, Latin jazz, Bossa Nova\nT-Pop, R&B, 2000s pop\nT-Pop, R&B, ballad\nT-Pop, R&B, chiptune\nT-Pop, R&B, city pop\nT-Pop, R&B, hip-hop\nT-Pop, R&B, lo-fi hip-hop\nT-Pop, R&B, lo-fi trap\nT-Pop, R&B, synth-pop\nT-Pop, anime theme, pop-rock\nT-Pop, chill R&B, lo-fi hip-hop\nT-Pop, chiptune\nT-Pop, chiptune, trap\nT-Pop, early 2000s R&B\nT-Pop, electronic pop, Luk Thung\nT-Pop, electronic, dance\nT-Pop, folk pop\nT-Pop, funk, disco\nT-Pop, funk, early 2000s R&B\nT-Pop, funk, electronic dance\nT-Pop, funk, hip-hop\nT-Pop, hip-hop\nT-Pop, hip-hop, R&B\nT-Pop, hip-hop, chiptune\nT-Pop, hip-hop, electronic\nT-Pop, hip-hop, funk\nT-Pop, hyperpop, EDM\nT-Pop, hyperpop, chiptune\nT-Pop, kawaii, anime\nT-Pop, lo-fi R&B\nT-Pop, lo-fi hip hop, R&B\nT-Pop, lo-fi, R&B\nT-Pop, synth-pop, city pop\nT-Pop, synth-pop, dance-pop\nT-Pop, synth-pop, hip-hop\nT-Pop, trap, R&B\nT-Pop, trap, Thai hip-hop\nT-Pop, trap, kawaii\nT-pop\nT-pop Bossa Nova\nT-pop EDM\nT-pop EDM dance-pop\nT-pop Eurodance\nT-pop J-Pop\nT-pop J-pop\nT-pop J-pop anime\nT-pop R&B\nT-pop anime\nT-pop anime theme\nT-pop ballad\nT-pop bubblegum pop city pop\nT-pop chiptune\nT-pop city pop\nT-pop city pop R&B\nT-pop city pop funk\nT-pop dance-pop\nT-pop dance-pop tropical house\nT-pop funk\nT-pop funk disco\nT-pop future bass\nT-pop future bass hyperpop\nT-pop hip-hop\nT-pop hyperpop\nT-pop hyperpop J-pop\nT-pop hyperpop chiptune\nT-pop hyperpop trap\nT-pop kawaii\nT-pop lo-fi\nT-pop lo-fi hip-hop\nT-pop rap\nT-pop rock\nT-pop, EDM\nT-pop, EDM, hardstyle\nT-pop, EDM, hyperpop\nT-pop, Eurobeat\nT-pop, Eurobeat, 90s dance-pop\nT-pop, Eurobeat, J-pop\nT-pop, Eurobeat, dance-pop\nT-pop, Eurobeat, happy hardcore\nT-pop, Eurobeat, hyperpop\nT-pop, Eurodance\nT-pop, Eurodance, 90s dance-pop\nT-pop, Eurodance, J-pop\nT-pop, Eurodance, bubblegum pop\nT-pop, Eurodance, happy hardcore\nT-pop, Eurodance, hyperpop\nT-pop, J-pop\nT-pop, J-pop, EDM\nT-pop, J-pop, Eurobeat\nT-pop, J-pop, anime\nT-pop, J-pop, chiptune\nT-pop, J-pop, hip-hop\nT-pop, J-pop, hyperpop\nT-pop, J-pop, video game music\nT-pop, J-rock\nT-pop, K-pop\nT-pop, K-pop, hip-hop\nT-pop, R&B, hip-hop\nT-pop, anime theme\nT-pop, chiptune\nT-pop, chiptune, hip-hop\nT-pop, cinematic, electronic\nT-pop, cinematic, power-pop\nT-pop, city pop, J-pop\nT-pop, city pop, synth-pop\nT-pop, dance-pop, Eurobeat\nT-pop, dance-pop, K-pop\nT-pop, dance-pop, hip-hop\nT-pop, dance-pop, video game\nT-pop, early 2000s R&B\nT-pop, electro-pop\nT-pop, funk, city pop\nT-pop, funk, disco\nT-pop, future bass, hyperpop\nT-pop, hip-hop\nT-pop, hip-hop, electronic\nT-pop, hip-hop, electronic dance\nT-pop, hyperpop\nT-pop, hyperpop, J-pop\nT-pop, hyperpop, K-pop\nT-pop, hyperpop, trap\nT-pop, pop-rock\nT-pop, retro dance-pop\nT-pop, retro, dance\nT-pop, synth-pop, dance-pop\nT-pop, synth-pop, hip-hop\nT-pop, trap, chiptune\nTV show\nTV theme\nTagalog hip-hop\nTaiwanese Enka\nTaiwanese Hokkien ballad\nTaiwanese Hokkien folk\nTaiwanese Hokkien pop\nTaiwanese Hokkien pop Enka\nTaiwanese Hokkien pop, Enka\nTaiwanese Hokkien pop, Latin pop\nTaiwanese Hokkien pop, big band\nTaiwanese Hokkien pop, big band swing\nTaiwanese Hokkien pop, chiptune\nTaiwanese Hokkien pop-rock\nTaiwanese Hokkien pop-rock, hard rock\nTaiwanese Hokkien power ballad\nTaiwanese Hokkien rock\nTaiwanese ballad\nTaiwanese disco\nTaiwanese folk\nTaiwanese folk rock\nTaiwanese folk-pop\nTaiwanese folk-rock\nTaiwanese hip-hop\nTaiwanese indie rock\nTaiwanese pop\nTaiwanese pop 70s\nTaiwanese pop 80s\nTaiwanese pop Enka\nTaiwanese pop ballad\nTaiwanese pop chiptune\nTaiwanese pop disco\nTaiwanese pop disco funk\nTaiwanese pop disco-funk\nTaiwanese pop funk disco\nTaiwanese pop lounge exotica\nTaiwanese pop psychedelic garage rock\nTaiwanese pop rock\nTaiwanese pop, 80s pop, Hokkien\nTaiwanese pop, 80s synth, Hokkien\nTaiwanese pop, Bossa Nova, Latin pop\nTaiwanese pop, Enka\nTaiwanese pop, Hokkien pop, retro rock\nTaiwanese pop, Hokkien pop, vintage pop\nTaiwanese pop, Hokkien, retro\nTaiwanese pop, Hokkien, vintage pop\nTaiwanese pop, Latin pop, retro\nTaiwanese pop, big band, cha-cha\nTaiwanese pop, big band, swing\nTaiwanese pop, blues, jazz\nTaiwanese pop, cha-cha-cha, retro\nTaiwanese pop, cha-cha-cha, vintage pop\nTaiwanese pop, cha-cha-chá\nTaiwanese pop, retro pop\nTaiwanese pop, retro pop, Hokkien\nTaiwanese pop, retro synth-pop, cha-cha\nTaiwanese pop, retro, Hokkien\nTaiwanese pop, retro, cha-cha-cha\nTaiwanese pop, retro, cha-cha-chá\nTaiwanese pop-funk\nTaiwanese pop-rock\nTaiwanese rock\nTamil Christian\nTamil Christian EDM\nTamil Christian Kuthu\nTamil Christian bhajan\nTamil Christian bhajan dance-pop\nTamil Christian cumbia\nTamil Christian devotional\nTamil Christian folk\nTamil Christian folk-pop\nTamil Christian music\nTamil Christian pop\nTamil Christian pop-rock\nTamil Christian rock\nTamil Christian, Eurodance, Kollywood\nTamil Christian, Latin dance\nTamil Christian, Latin funk, devotional\nTamil Christian, Latin funk, gospel dance\nTamil Christian, Latin, Bollywood\nTamil Christian, chiptune, synth-pop\nTamil Christian, dance-pop\nTamil Christian, dance-pop, Eurodance\nTamil Christian, dance-pop, Kuthu\nTamil Christian, synth-pop, dance-pop\nTamil Christmas pop\nTamil EDM\nTamil EDM hip-hop\nTamil EDM, trap, hardstyle\nTamil Gaana\nTamil Gaana, electronic dance\nTamil Kuthu\nTamil Kuthu funk electronic\nTamil Kuthu funk hip-hop\nTamil Kuthu hip-hop\nTamil Kuthu hip-hop chiptune\nTamil Kuthu metal\nTamil Kuthu rock\nTamil Kuthu trap\nTamil Kuthu, Bollywood, hip-hop\nTamil Kuthu, electronic dance\nTamil Kuthu, electronic hip-hop\nTamil Kuthu, hard rock\nTamil Kuthu, hip-hop, EDM\nTamil Kuthu, hip-hop, electronic dance\nTamil M vampa\nTamil R&B\nTamil R&B hip-hop\nTamil R&B lo-fi hip-hop\nTamil R&B lo-fi trap\nTamil R&B trap\nTamil R&B, hip-hop\nTamil R&B, lo-fi hip hop, ambient\nTamil R&B, trap\nTamil R&B, trap, ambient\nTamil R&B, trap, hardstyle\nTamil R&B, trap, melodic rap\nTamil ambient\nTamil ambient pop\nTamil ballad\nTamil ballad, R&B\nTamil ballad, trap\nTamil ballad, trap, electronic\nTamil bhajan\nTamil bhajan, dance-pop\nTamil children's\nTamil children's music\nTamil children's music world music\nTamil children's music, synth-pop, dance-pop\nTamil children's pop\nTamil cinema\nTamil cinema, electronic, hip-hop\nTamil cinematic\nTamil classical fusion\nTamil dance\nTamil dance, Balkan brass, Indian percussion\nTamil dance, EDM, hip-hop\nTamil dance, Kuthu, electronic\nTamil dance, Kuthu, samba\nTamil dance, electronic, Kuthu\nTamil dance, electronic, chiptune\nTamil dance, electronic, hip-hop\nTamil dance, electronic, rock\nTamil dance, hard dance, techno\nTamil dance, hard rock, electronic\nTamil dance, hip-hop, electronic\nTamil dance, kuthu, electronic\nTamil dance, kuthu, gaana\nTamil dance-pop\nTamil dance-pop chiptune\nTamil dance-pop electro house\nTamil dance-pop hyperpop\nTamil dance-pop moombahton\nTamil dance-pop, EDM, trance\nTamil dance-pop, chiptune, electro-house\nTamil dance-pop, hyperpop, nightcore\nTamil dance-pop, moombahton\nTamil dancehall\nTamil devotional\nTamil devotional dance\nTamil devotional pop\nTamil devotional rock\nTamil devotional, South Indian folk, electronic\nTamil devotional, dance-pop\nTamil devotional, electronic, Carnatic\nTamil devotional, funk, cinematic\nTamil devotional, pop, hip-hop\nTamil devotional, retro funk, disco\nTamil devotional, trap, R&B\nTamil drill\nTamil electronic\nTamil electronic dance\nTamil electronic pop\nTamil electronic trap\nTamil electronic, chiptune, trap\nTamil electronic, cinematic EDM, Kuthu\nTamil film ballad\nTamil film music\nTamil film music lo-fi\nTamil film music retro\nTamil film music, EDM, hip-hop\nTamil film music, Latin pop, synth-pop\nTamil film music, pop, EDM\nTamil film score\nTamil film score, retro, lo-fi\nTamil film song\nTamil film-pop\nTamil filmi\nTamil filmi-pop\nTamil folk\nTamil folk dance\nTamil folk electronic\nTamil folk funk rock\nTamil folk funk-rock\nTamil folk fusion\nTamil folk hip-hop\nTamil folk hip-hop electronic\nTamil folk jazz\nTamil folk kuthu\nTamil folk pop\nTamil folk pop-rock\nTamil folk rock\nTamil folk rock hip-hop\nTamil folk rock, electronic dance\nTamil folk trap\nTamil folk, Gaana, Kuthu\nTamil folk, Kollywood dance\nTamil folk, Kuthu\nTamil folk, electronic dance\nTamil folk, electronic dance, world fusion\nTamil folk, electronic fusion\nTamil folk, electronic, fusion\nTamil folk, electronic, trap\nTamil folk-dance\nTamil folk-electronic\nTamil folk-funk\nTamil folk-fusion\nTamil folk-pop\nTamil folk-pop, progressive house\nTamil folk-rap\nTamil folk-rock\nTamil funk\nTamil funk fusion\nTamil funk-pop\nTamil funk-rap\nTamil funk-rock\nTamil hip-hop\nTamil hip-hop chiptune\nTamil hip-hop funk chiptune\nTamil hip-hop funk-rock\nTamil hip-hop lo-fi\nTamil hip-hop nu-metal\nTamil hip-hop trap\nTamil hip-hop, Kollywood, trap\nTamil hip-hop, Kuthu, trap\nTamil hip-hop, Malay fusion\nTamil hip-hop, cinematic dubstep\nTamil hip-hop, cinematic, folk fusion\nTamil hip-hop, dance-pop\nTamil hip-hop, electro-house\nTamil hip-hop, electronic\nTamil hip-hop, electronic dance music\nTamil hip-hop, electronic dance, Indian folk\nTamil hip-hop, electronic dance, rock\nTamil hip-hop, funk, boom-bap\nTamil hip-hop, hardstyle\nTamil hip-hop, trap, cinematic\nTamil hip-hop, trap, devotional\nTamil indie\nTamil kuthu\nTamil marching\nTamil narrative\nTamil party anthem\nTamil political satire\nTamil pop\nTamil pop EDM\nTamil pop EDM trap\nTamil pop Latin\nTamil pop Latin flamenco\nTamil pop R&B\nTamil pop R&B funk\nTamil pop R&B hip-hop\nTamil pop R&B trap\nTamil pop big band jazz\nTamil pop chiptune\nTamil pop dance-pop\nTamil pop dancehall\nTamil pop dancehall reggaeton\nTamil pop dembow\nTamil pop filmi\nTamil pop folk\nTamil pop funk\nTamil pop funk R&B\nTamil pop funk dance\nTamil pop funk disco\nTamil pop funk electronic\nTamil pop funk jazz\nTamil pop funk rock\nTamil pop hip-hop\nTamil pop jazz\nTamil pop lo-fi\nTamil pop lo-fi hip hop\nTamil pop reggaeton\nTamil pop retro-funk\nTamil pop trap\nTamil pop world music\nTamil pop world music fusion\nTamil pop, 80s synth-pop, disco\nTamil pop, 90s Kollywood, dance\nTamil pop, 90s Kollywood, hip-hop\nTamil pop, 90s R&B, hip-hop\nTamil pop, 90s R&B, new jack swing\nTamil pop, 90s dance-pop\nTamil pop, 90s dance-pop, filmi\nTamil pop, 90s dance-pop, hip-hop\nTamil pop, 90s electronic, dance\nTamil pop, 90s house, dance-pop\nTamil pop, Afrobeats, dancehall\nTamil pop, Bhangra, Kollywood\nTamil pop, Carnatic fusion\nTamil pop, EDM\nTamil pop, EDM fusion\nTamil pop, EDM, Indian fusion\nTamil pop, EDM, R&B\nTamil pop, EDM, chiptune\nTamil pop, EDM, dance-pop\nTamil pop, EDM, future bass\nTamil pop, EDM, hip-hop\nTamil pop, EDM, pop\nTamil pop, EDM, trance\nTamil pop, EDM, trap\nTamil pop, Eurodance\nTamil pop, Hindi pop, R&B\nTamil pop, Indian classical, cinematic pop\nTamil pop, Indian film music\nTamil pop, Indian folk, cinematic\nTamil pop, Indian fusion\nTamil pop, Kollywood, Arabic pop\nTamil pop, Kollywood, Latin\nTamil pop, Kollywood, chiptune\nTamil pop, Kollywood, electronic dance\nTamil pop, Kollywood, funk\nTamil pop, Kollywood, hip-hop\nTamil pop, Kollywood, synth pop\nTamil pop, Kollywood, upbeat\nTamil pop, Kuthu\nTamil pop, Kuthu, Carnatic fusion\nTamil pop, Kuthu, Gaana\nTamil pop, Kuthu, electronic\nTamil pop, Kuthu, electronic hip-hop\nTamil pop, Kuthu, filmi\nTamil pop, Kuthu, folk\nTamil pop, Kuthu, folk fusion\nTamil pop, Kuthu, hip-hop\nTamil pop, Latin acoustic\nTamil pop, Latin funk\nTamil pop, Latin fusion, R&B\nTamil pop, Latin jazz fusion\nTamil pop, Latin pop\nTamil pop, Latin pop, Bollywood\nTamil pop, Latin pop, Kollywood\nTamil pop, Latin pop, flamenco\nTamil pop, Latin salsa\nTamil pop, Latin salsa, dance\nTamil pop, Latin, world music\nTamil pop, R&B\nTamil pop, R&B, EDM\nTamil pop, R&B, ambient\nTamil pop, R&B, cinematic\nTamil pop, R&B, folk fusion\nTamil pop, R&B, funk\nTamil pop, R&B, hip-hop\nTamil pop, R&B, smooth jazz\nTamil pop, R&B, synth-pop\nTamil pop, R&B, trap\nTamil pop, R&B, video game\nTamil pop, R&B, world music\nTamil pop, South Indian film music\nTamil pop, UK hip-hop, dancehall\nTamil pop, acoustic ballad, Spanish fusion\nTamil pop, ambient, lo-fi hip-hop\nTamil pop, boogie-woogie, swing\nTamil pop, breakbeat hardcore\nTamil pop, chiptune\nTamil pop, chiptune, 8-bit\nTamil pop, chiptune, Kollywood\nTamil pop, chiptune, dance-pop\nTamil pop, chiptune, electronic\nTamil pop, chiptune, funk\nTamil pop, chiptune, lo-fi hip-hop\nTamil pop, chiptune, retro\nTamil pop, chiptune, synth-pop\nTamil pop, chiptune, video game music\nTamil pop, cinematic EDM\nTamil pop, cinematic ambient, electronic\nTamil pop, cinematic orchestral\nTamil pop, cinematic trap\nTamil pop, cinematic, 80s synth\nTamil pop, cinematic, Carnatic fusion\nTamil pop, cinematic, Indian classical\nTamil pop, cinematic, Indian fusion\nTamil pop, cinematic, ambient\nTamil pop, cinematic, choral\nTamil pop, cinematic, dance\nTamil pop, cinematic, electronic\nTamil pop, cinematic, ethereal\nTamil pop, cinematic, experimental\nTamil pop, cinematic, fusion\nTamil pop, cinematic, hyperpop\nTamil pop, cinematic, romantic\nTamil pop, cinematic, trap\nTamil pop, cinematic, world music\nTamil pop, dance fusion\nTamil pop, dance, brass\nTamil pop, dance-pop\nTamil pop, dance-pop, EDM\nTamil pop, dance-pop, Indian classical\nTamil pop, dance-pop, Indian fusion\nTamil pop, dance-pop, Kollywood\nTamil pop, dance-pop, electronic\nTamil pop, dance-pop, folk fusion\nTamil pop, dance-pop, funk\nTamil pop, dance-pop, hip-hop\nTamil pop, dance-pop, world music\nTamil pop, dancehall, afrobeats\nTamil pop, dancehall, folk fusion\nTamil pop, dancehall, reggaeton\nTamil pop, disco, funk\nTamil pop, electronic R&B\nTamil pop, electronic dance\nTamil pop, electronic dance music\nTamil pop, electronic dance, Carnatic\nTamil pop, electronic dance, Indian classical\nTamil pop, electronic dance, Indian folk\nTamil pop, electronic dance, Indian fusion\nTamil pop, electronic dance, Kollywood\nTamil pop, electronic dance, folk fusion\nTamil pop, electronic dance, fusion\nTamil pop, electronic dance, global bass\nTamil pop, electronic dance, hip-hop\nTamil pop, electronic dance-pop\nTamil pop, electronic fusion, Indian classical\nTamil pop, electronic fusion, funk\nTamil pop, electronic, Carnatic\nTamil pop, electronic, Indian classical\nTamil pop, electronic, Indian fusion\nTamil pop, electronic, Indian percussion\nTamil pop, electronic, Kollywood\nTamil pop, electronic, R&B\nTamil pop, electronic, South Indian\nTamil pop, electronic, ambient\nTamil pop, electronic, cinematic\nTamil pop, electronic, classical Indian\nTamil pop, electronic, dance\nTamil pop, electronic, dance-pop\nTamil pop, electronic, dancehall\nTamil pop, electronic, folk\nTamil pop, electronic, folk fusion\nTamil pop, electronic, folk-dance\nTamil pop, electronic, funk\nTamil pop, electronic, fusion\nTamil pop, electronic, genre-bending\nTamil pop, electronic, hip hop\nTamil pop, electronic, hip-hop\nTamil pop, electronic, melismatic\nTamil pop, electronic, orchestral\nTamil pop, electronic, percussion\nTamil pop, electronic, rap\nTamil pop, electronic, rock\nTamil pop, electronic, traditional Indian\nTamil pop, electronic, trap\nTamil pop, electronic, world music\nTamil pop, ethereal, cinematic\nTamil pop, experimental, R&B\nTamil pop, folk dance, dancehall\nTamil pop, folk fusion\nTamil pop, folk hip-hop\nTamil pop, folk, Latin\nTamil pop, folk, world music\nTamil pop, funk, 90s Kollywood\nTamil pop, funk, R&B\nTamil pop, funk, breakbeat\nTamil pop, funk, disco\nTamil pop, funk, electronic\nTamil pop, funk, synth-pop\nTamil pop, funk, world music\nTamil pop, future bass, ethereal\nTamil pop, hard rock\nTamil pop, hard rock, electronic\nTamil pop, hardstyle, EDM\nTamil pop, hip-hop\nTamil pop, hip-hop, Kollywood\nTamil pop, hip-hop, R&B\nTamil pop, hip-hop, dance\nTamil pop, hip-hop, dancehall\nTamil pop, hip-hop, electronic\nTamil pop, hip-hop, electronic dance\nTamil pop, hip-hop, folk fusion\nTamil pop, hip-hop, funk\nTamil pop, hip-hop, jazz\nTamil pop, hip-hop, trap\nTamil pop, hyperpop, electronic dance\nTamil pop, jazz fusion\nTamil pop, jazzy, upbeat\nTamil pop, kuthu, gaana\nTamil pop, lo-fi hip hop\nTamil pop, lo-fi, electronic\nTamil pop, pop-funk, Kollywood\nTamil pop, reggaeton\nTamil pop, reggaeton, Latin pop\nTamil pop, reggaeton, dancehall\nTamil pop, retro dance-pop, Kollywood\nTamil pop, retro electronic, South Indian film music\nTamil pop, retro funk, disco\nTamil pop, retro pop, chiptune\nTamil pop, retro synth\nTamil pop, retro-futuristic, 90s Kollywood\nTamil pop, retro-futuristic, synthwave\nTamil pop, synth-pop\nTamil pop, synth-pop, 80s pop\nTamil pop, synth-pop, Kollywood\nTamil pop, synth-pop, chiptune\nTamil pop, synth-pop, funk\nTamil pop, synth-pop, retro-futuristic\nTamil pop, trap\nTamil pop, trap R&B\nTamil pop, trap, EDM\nTamil pop, trap, Indian classical\nTamil pop, trap, Kollywood\nTamil pop, trap, R&B\nTamil pop, trap, ambient\nTamil pop, trap, cinematic\nTamil pop, trap, dappan kuthu\nTamil pop, trap, electronic\nTamil pop, trap, electronic dance\nTamil pop, trap, hardstyle\nTamil pop, trap, hip-hop\nTamil pop, trap, kuthu\nTamil pop, world music\nTamil pop, world music fusion\nTamil pop, world music, cinematic\nTamil pop, world music, electronic\nTamil pop, world music, pop-funk\nTamil pop-EDM\nTamil pop-R&B\nTamil pop-folk\nTamil pop-funk\nTamil pop-fusion\nTamil pop-rap\nTamil pop-rap, R&B, experimental electronic\nTamil pop-rap, chiptune\nTamil pop-rap, chiptune, hip-hop\nTamil pop-rock\nTamil pop-rock chiptune\nTamil pop-rock funk\nTamil pop-rock, EDM, anthemic\nTamil pop-rock, Nintendocore\nTamil pop-rock, cinematic folk\nTamil pop-rock, electronic dance\nTamil pop-rock, electronic dance music\nTamil protest\nTamil protest hip-hop\nTamil rap\nTamil rap, cinematic, electronic\nTamil rap, hardstyle, trap\nTamil rap, trap\nTamil rap-rock funk\nTamil rap-rock nu-metal\nTamil rock\nTamil rock funk metal\nTamil rock nu-metal\nTamil rock punk\nTamil rock, heavy metal\nTamil rock, neoclassical metal\nTamil romantic ballad\nTamil sports anthem\nTamil trap\nTamil trap, hardstyle, Indian classical\nTamil trap-pop\nTamil trap-rap\nTango Nuevo\nTaqsim\nTaregufi\nTatar electronic dance\nTejano\nTejano Western Swing\nTejano rockabilly\nTejano, Norteño\nTelugu Christian\nTelugu Christian EDM\nTelugu Christian bhajan\nTelugu Christian dance-pop\nTelugu Christian devotional\nTelugu Christian devotional, Tollywood film music\nTelugu Christian filmi\nTelugu Christian folk\nTelugu Christian hymn\nTelugu Christian music\nTelugu Christian pop\nTelugu Christian, Latin, salsa\nTelugu Christian, dance-pop\nTelugu Christmas\nTelugu EDM\nTelugu R&B trap\nTelugu acoustic\nTelugu ballad\nTelugu bhajan\nTelugu bhajan, electronic dance, devotional\nTelugu bhajan, electronic dance, devotional pop\nTelugu bhajan, electronic, devotional\nTelugu children's music\nTelugu cinematic\nTelugu comedy\nTelugu dance\nTelugu dance pop\nTelugu dance, electronic, folk fusion\nTelugu dance-pop\nTelugu dance-pop chiptune\nTelugu dance-pop hyperpop\nTelugu dance-pop moombahton\nTelugu dance-pop, chiptune EDM\nTelugu dance-pop, hip-hop\nTelugu devotional\nTelugu devotional dance\nTelugu devotional pop\nTelugu devotional pop-rock\nTelugu devotional, EDM\nTelugu devotional, EDM, electronic\nTelugu devotional, dance-pop\nTelugu devotional, electronic dance\nTelugu devotional, electronic dance music\nTelugu electronic\nTelugu electronic dance\nTelugu film anthem\nTelugu film music\nTelugu film music chiptune\nTelugu film music retro-pop\nTelugu film music trap\nTelugu film music, chiptune, electro-pop\nTelugu film music, chiptune, electronic dance\nTelugu film music, dance pop\nTelugu film music, dance pop, electronic\nTelugu film music, electronic dance, Indian fusion\nTelugu film music, electronic, folk fusion\nTelugu film music, festive, electronic\nTelugu film music, folk fusion, dance\nTelugu film music, folk, upbeat\nTelugu film music, pop-dance\nTelugu film music, retro, chiptune\nTelugu film music, trap\nTelugu film song\nTelugu film song, dance-pop\nTelugu film song, electronic dance-pop, folk fusion\nTelugu film song, synth-pop\nTelugu film-pop\nTelugu filmi\nTelugu folk\nTelugu folk dance\nTelugu folk fusion\nTelugu folk hip-hop\nTelugu folk pop\nTelugu folk pop-rap\nTelugu folk pop-rock\nTelugu folk rock\nTelugu folk trap\nTelugu folk, Kuthu\nTelugu folk, cinematic pop\nTelugu folk, dance-pop, hip-hop\nTelugu folk, electronic dance\nTelugu folk, electronic dance, EDM\nTelugu folk, electronic dance, rock\nTelugu folk, electronic pop\nTelugu folk, future bass, electronic\nTelugu folk, hip-hop, devotional\nTelugu folk, old-school hip-hop\nTelugu folk-dance\nTelugu folk-fusion\nTelugu folk-pop\nTelugu folk-pop chiptune\nTelugu folk-rap\nTelugu folk-rock\nTelugu funk fusion\nTelugu hip hop\nTelugu hip-hop\nTelugu hip-hop moombahton\nTelugu hip-hop, Kuthu, cinematic\nTelugu party\nTelugu pop\nTelugu pop R&B\nTelugu pop R&B funk\nTelugu pop dance-pop\nTelugu pop dancehall\nTelugu pop filmi\nTelugu pop folk\nTelugu pop folk fusion\nTelugu pop funk R&B\nTelugu pop funk disco\nTelugu pop fusion\nTelugu pop reggaeton\nTelugu pop rock\nTelugu pop trap\nTelugu pop, Bossa Nova, Latin pop\nTelugu pop, EDM, Bollywood\nTelugu pop, EDM, Indian classical\nTelugu pop, EDM, big room house\nTelugu pop, EDM, dance-pop\nTelugu pop, EDM, hip-hop\nTelugu pop, EDM, synth-pop\nTelugu pop, Indian folk, electronic fusion\nTelugu pop, Latin folk\nTelugu pop, Latin fusion\nTelugu pop, Latin pop, world music\nTelugu pop, R&B, funk\nTelugu pop, R&B, hip-hop\nTelugu pop, R&B, trap\nTelugu pop, chiptune, video game music\nTelugu pop, dance-pop\nTelugu pop, dance-pop, EDM\nTelugu pop, dance-pop, electronic\nTelugu pop, dance-pop, funk\nTelugu pop, dance-pop, hip-hop\nTelugu pop, dancehall, reggaeton\nTelugu pop, electronic dance\nTelugu pop, electronic dance, Tollywood\nTelugu pop, electronic dance, folk fusion\nTelugu pop, electronic dance-pop\nTelugu pop, electronic rock\nTelugu pop, electronic, chiptune\nTelugu pop, electronic, dancehall\nTelugu pop, electronic, hip-hop\nTelugu pop, electronic, trap\nTelugu pop, electronic, world music\nTelugu pop, folk, devotional\nTelugu pop, funk, R&B\nTelugu pop, funk, disco\nTelugu pop, funk, electronic\nTelugu pop, hard rock\nTelugu pop, hip-hop, R&B\nTelugu pop, retro synth-pop, chiptune\nTelugu pop, synth-pop\nTelugu pop, trap, EDM\nTelugu pop, trap, R&B\nTelugu pop, trap, electronic\nTelugu pop-funk\nTelugu pop-fusion\nTelugu pop-rap\nTelugu pop-rock\nTelugu pop-rock chiptune\nTelugu pop-rock, hip-hop, electronic\nTelugu pop-trap\nTelugu protest\nTelugu protest funk\nTelugu protest pop\nTelugu rap\nTelugu rap chiptune\nTelugu rap, hard rock\nTelugu rap-rock\nTelugu rap-rock chiptune\nTelugu rap-rock nu-metal\nTelugu rap-rock, electronic dance\nTelugu rock\nTelugu trap\nTelugu trap pop\nTexas blues\nTexas blues rock\nTexas blues, country rock\nTexas blues, country, rockabilly\nTexas blues, country-funk\nTexas blues-rock\nTexas boogie\nTexas country\nTexas country rock\nTexas country-folk\nTexas country-funk\nTexas country-gospel\nTexas country-rock\nTexas crunk\nTexas drill\nTexas folk\nTexas hip-hop\nTexas punk rock\nTexas trap\nThai City Pop\nThai EDM\nThai Eurodance\nThai Latin pop\nThai Latin pop-rock\nThai Latin salsa\nThai Luk Thung\nThai Luk Thung blues-rock\nThai Luk Thung chiptune\nThai Luk Thung chiptune rock\nThai Luk Thung cinematic\nThai Luk Thung funk\nThai Luk Thung funk disco\nThai Luk Thung hip-hop\nThai Luk Thung metal\nThai Luk Thung pop\nThai Luk Thung pop-rock\nThai Luk Thung rock\nThai Luk Thung rock ska\nThai Luk Thung surf rock\nThai Luk Thung synth-pop\nThai Luk Thung, EDM\nThai Luk Thung, Eurodance\nThai Luk Thung, Latin Cumbia\nThai Luk Thung, Mor Lam, chiptune\nThai Luk Thung, Mor Lam, folk\nThai Luk Thung, Southern rock\nThai Luk Thung, blues-rock\nThai Luk Thung, chiptune\nThai Luk Thung, chiptune rock\nThai Luk Thung, chiptune synth-pop\nThai Luk Thung, cinematic, martial\nThai Luk Thung, dance-pop\nThai Luk Thung, electronic dance\nThai Luk Thung, electronic rock\nThai Luk Thung, funk, psychedelic pop\nThai Luk Thung, hard rock\nThai Luk Thung, hard rock, chiptune\nThai Luk Thung, hardstyle, chiptune\nThai Luk Thung, neoclassical heavy metal\nThai Luk Thung, pop-rock\nThai Luk Thung, pop-rock, blues\nThai Luk Thung, psychedelic rock\nThai Luk Thung, surf rock\nThai Luk Thung, synth-pop\nThai Luk Thung, synth-pop, chiptune\nThai Mor Lam funk-rock\nThai Mor Lam rock\nThai Mor Lam, chiptune, electronic dance\nThai Mor Lam, electronic dance, rock\nThai Mor Lam, electronic pop\nThai Pop\nThai Pop Afrobeats\nThai Pop Bossa Nova\nThai Pop City Pop\nThai Pop City Pop Funk\nThai Pop City Pop J-pop\nThai Pop City Pop R&B\nThai Pop City Pop funk\nThai Pop City Pop lo-fi hip-hop\nThai Pop City Pop smooth jazz\nThai Pop EDM\nThai Pop J-pop\nThai Pop Neo-Soul City Pop\nThai Pop R&B\nThai Pop R&B Hip Hop\nThai Pop R&B Neo-Soul\nThai Pop R&B city pop\nThai Pop R&B funk\nThai Pop R&B hip-hop\nThai Pop R&B lo-fi\nThai Pop R&B lo-fi hip-hop\nThai Pop R&B neo-soul\nThai Pop R&B synth-pop\nThai Pop R&B trap\nThai Pop chiptune\nThai Pop city pop\nThai Pop city pop lo-fi hip-hop\nThai Pop city pop neo-soul\nThai Pop hip-hop\nThai Pop lo-fi\nThai Pop lo-fi hip-hop\nThai Pop lo-fi hip-hop R&B\nThai Pop reggae fusion\nThai Pop trap\nThai Pop, 80s synth-pop, city pop\nThai Pop, 90s R&B, City Pop\nThai Pop, City Pop, Funk\nThai Pop, City Pop, J-pop\nThai Pop, City Pop, Light R&B\nThai Pop, City Pop, R&B\nThai Pop, City Pop, Synth-Pop\nThai Pop, City Pop, lo-fi hip-hop\nThai Pop, EDM\nThai Pop, EDM, chiptune\nThai Pop, Eurodance, 90s dance-pop\nThai Pop, Hip Hop\nThai Pop, J-pop, City Pop\nThai Pop, Latin Pop\nThai Pop, Neo-Soul, City Pop\nThai Pop, Neo-Soul, Funk\nThai Pop, Neo-Soul, R&B\nThai Pop, New Jack Swing, City Pop\nThai Pop, Pop Rock\nThai Pop, R&B, City Pop\nThai Pop, R&B, Neo-Soul\nThai Pop, R&B, New Jack Swing\nThai Pop, R&B, future bass\nThai Pop, R&B, hip-hop\nThai Pop, R&B, lo-fi\nThai Pop, R&B, lo-fi hip-hop\nThai Pop, R&B, synth-pop\nThai Pop, R&B, trap\nThai Pop, R&B, vaporwave\nThai Pop, chiptune\nThai Pop, chiptune, synth-pop\nThai Pop, city pop, synth-pop\nThai Pop, dancehall, reggaeton\nThai Pop, hip-hop\nThai Pop, hip-hop, trap\nThai Pop, lo-fi hip hop\nThai Pop, modern R&B, chiptune\nThai Pop, synth-pop, city pop\nThai Pop, trap\nThai Pop-R&B\nThai Pop-R&B lo-fi hip-hop\nThai Pop-Rock\nThai Pop-Rock City Pop\nThai R&B\nThai R&B hip-hop\nThai R&B lo-fi\nThai R&B lo-fi hip hop\nThai R&B lo-fi hip-hop\nThai R&B neo-soul\nThai R&B trap\nThai R&B trap-pop\nThai R&B trap-soul\nThai R&B, city pop\nThai R&B, hip-hop\nThai R&B, hip-hop, chiptune\nThai R&B, hip-hop, lo-fi\nThai R&B, hip-hop, trap\nThai R&B, lo-fi\nThai R&B, lo-fi hip hop\nThai R&B, lo-fi hip-hop\nThai R&B, lo-fi hip-hop, chiptune\nThai R&B, lo-fi trap\nThai R&B, lo-fi, dreamy\nThai R&B, neo-soul, city pop\nThai R&B, pop\nThai R&B, pop-rap\nThai R&B, synthwave, trap\nThai R&B, trap\nThai R&B, trap hip-hop\nThai R&B, trap, acoustic hip-hop\nThai R&B, trap, atmospheric\nThai R&B, trap, lo-fi hip hop\nThai R&B, trap-pop\nThai R&B, trap-soul\nThai R&B-pop\nThai acoustic ballad\nThai acoustic pop\nThai acoustic pop-rock\nThai acoustic rock\nThai alternative rock\nThai ballad\nThai ballad, European chanson, vintage\nThai ballad, Latin pop, acoustic\nThai ballad, big band jazz\nThai big band\nThai big band swing\nThai blues-rock\nThai bolero\nThai bossa nova\nThai brass\nThai brass band\nThai breakbeat\nThai ceremonial\nThai children's\nThai children's music\nThai children's pop\nThai city pop\nThai city pop funk\nThai city-pop\nThai classical\nThai comedy rock\nThai country\nThai country-folk\nThai country-pop\nThai country-rock\nThai dance\nThai dance, happy hardcore\nThai dance-pop\nThai dance-pop electro-house\nThai dance-pop, happy hardcore, nightcore\nThai dancehall\nThai disco-funk\nThai disco-pop\nThai drill\nThai electronic\nThai electronic dance\nThai folk\nThai folk blues-rock\nThai folk funk-rock\nThai folk fusion\nThai folk hip-hop\nThai folk pop\nThai folk pop-rock\nThai folk protest\nThai folk rock\nThai folk, Latin pop\nThai folk, Luk Thung\nThai folk, big band swing\nThai folk, chiptune, electronic\nThai folk, country-rock\nThai folk-blues\nThai folk-funk\nThai folk-pop\nThai folk-pop chiptune\nThai folk-pop worldbeat\nThai folk-punk\nThai folk-rock\nThai folk-rock punk\nThai folk-rock surf rock\nThai folk-rock, hard rock\nThai folk-rock, hard rock, hip-hop fusion\nThai folk-rock, progressive metal\nThai funk\nThai funk soul\nThai funk-pop\nThai funk-rap\nThai funk-reggae\nThai funk-rock\nThai funkot\nThai fusion\nThai fusion funk\nThai fusion pop-rock\nThai garage rock\nThai hard rock\nThai hip hop\nThai hip-hop\nThai hip-hop G-funk\nThai hip-hop R&B\nThai hip-hop chiptune\nThai hip-hop electro-pop\nThai hip-hop funk\nThai hip-hop indie rock\nThai hip-hop lo-fi\nThai hip-hop lo-fi trap\nThai hip-hop pop-rock\nThai hip-hop reggaeton\nThai hip-hop trap\nThai hip-hop, EDM\nThai hip-hop, EDM, hardstyle\nThai hip-hop, EDM, hyperpop\nThai hip-hop, EDM, trap\nThai hip-hop, boom-bap\nThai hip-hop, chiptune\nThai hip-hop, chiptune, lo-fi\nThai hip-hop, chiptune, trap\nThai hip-hop, dance-pop\nThai hip-hop, hyperpop, chiptune\nThai hip-hop, hyperpop, electronic\nThai hip-hop, hyperpop, electronic dance\nThai hip-hop, hyperpop, trap\nThai hip-hop, lo-fi hip hop, chiptune\nThai hip-hop, lo-fi, chiptune\nThai hip-hop, lo-fi, trap\nThai hip-hop, trap\nThai hip-hop, trap, rap-rock\nThai hyperpop, happy hardcore\nThai indie folk\nThai indie pop\nThai indie pop-rock\nThai indie rock\nThai indie-pop\nThai jazz\nThai jazz-pop\nThai lullaby\nThai mambo\nThai marching band\nThai new wave\nThai new wave, chiptune\nThai novelty dance\nThai orchestral\nThai patriotic ballad\nThai patriotic march\nThai pop\nThai pop 80s\nThai pop 90s\nThai pop Bossa Nova\nThai pop EDM\nThai pop J-pop\nThai pop K-pop\nThai pop Latin\nThai pop Latin jazz\nThai pop Luk Thung\nThai pop R&B\nThai pop R&B city pop\nThai pop R&B funk\nThai pop R&B lo-fi\nThai pop R&B lo-fi hip hop\nThai pop R&B synth-pop\nThai pop R&B trap\nThai pop acoustic pop\nThai pop anime\nThai pop ballad\nThai pop blues jazz\nThai pop bossa nova\nThai pop bossa nova lounge\nThai pop bossa nova lounge jazz\nThai pop chiptune\nThai pop city pop\nThai pop city pop R&B\nThai pop city pop funk\nThai pop city pop jazz\nThai pop city pop jazz fusion\nThai pop city pop jazz-funk\nThai pop city pop neo-soul\nThai pop city pop smooth jazz\nThai pop country\nThai pop folk\nThai pop folk-pop\nThai pop funk\nThai pop funk R&B\nThai pop funk chiptune\nThai pop funk disco\nThai pop funk hip-hop\nThai pop future bass\nThai pop hip-hop\nThai pop jazz\nThai pop jazz bossa nova\nThai pop jazz fusion\nThai pop jazz soul\nThai pop lo-fi\nThai pop lo-fi R&B\nThai pop lo-fi city pop\nThai pop lo-fi hip-hop\nThai pop lo-fi neo-soul\nThai pop lo-fi pop\nThai pop lounge\nThai pop lounge bossa nova\nThai pop lounge exotica\nThai pop lounge jazz\nThai pop neo-soul\nThai pop reggae\nThai pop reggae R&B\nThai pop reggae ska\nThai pop reggaeton\nThai pop rock\nThai pop trap\nThai pop trap R&B\nThai pop vaporwave\nThai pop world music\nThai pop, 80s city pop, synth-pop\nThai pop, 80s pop-rock\nThai pop, 80s synth, cinematic\nThai pop, 80s synth, cinematic ballad\nThai pop, 80s synth-pop\nThai pop, 90s R&B\nThai pop, 90s R&B, city pop\nThai pop, 90s R&B, soul\nThai pop, 90s dance-pop\nThai pop, 90s dance-pop, funk\nThai pop, 90s hip-hop, retro\nThai pop, Bossa Nova\nThai pop, Bossa Nova, Latin jazz\nThai pop, Bossa Nova, jazz\nThai pop, Bossa Nova, light jazz\nThai pop, Bossa Nova, lounge jazz\nThai pop, Christian contemporary\nThai pop, City Pop, Luk Thung\nThai pop, EDM\nThai pop, EDM, Luk Thung\nThai pop, EDM, future bass\nThai pop, EDM, hip-hop\nThai pop, EDM-pop, hip-hop\nThai pop, Eurobeat, J-pop\nThai pop, Eurobeat, chiptune\nThai pop, Eurodance\nThai pop, Eurodance, 90s dance-pop\nThai pop, Eurodance, Hi-NRG\nThai pop, Eurodance, Italo disco\nThai pop, Eurodance, Luk Thung\nThai pop, Eurodance, chiptune\nThai pop, Eurodance, dance-pop\nThai pop, Eurodance, happy hardcore\nThai pop, Eurodance, hip-hop\nThai pop, Eurodance, synth-pop\nThai pop, Eurodance, trance\nThai pop, European folk\nThai pop, J-pop\nThai pop, J-pop, chiptune\nThai pop, J-pop, hyperpop\nThai pop, Latin cha-cha-chá\nThai pop, Latin dance\nThai pop, Latin dance, Euro-pop\nThai pop, Latin funk\nThai pop, Latin jazz\nThai pop, Latin jazz, Bossa Nova\nThai pop, Latin pop\nThai pop, Latin pop, Cumbia\nThai pop, Latin pop, acoustic ballad\nThai pop, Latin pop, dance-pop\nThai pop, Latin pop, merengue\nThai pop, Latin pop, retro\nThai pop, Latin pop, salsa\nThai pop, Latin pop, theatrical\nThai pop, Latin pop, tropical\nThai pop, Latin pop, world music\nThai pop, Latin salsa\nThai pop, Latin, big band\nThai pop, Latin, worldbeat\nThai pop, Luk Thung\nThai pop, Luk Thung, Eurodance\nThai pop, Luk Thung, Mor Lam\nThai pop, Luk Thung, big band\nThai pop, Luk Thung, chiptune\nThai pop, Luk Thung, cinematic\nThai pop, Luk Thung, dance\nThai pop, Luk Thung, dance pop\nThai pop, Luk Thung, dance-pop\nThai pop, Luk Thung, electronic\nThai pop, Luk Thung, electronic dance\nThai pop, Luk Thung, electronic pop\nThai pop, Luk Thung, funk\nThai pop, Luk Thung, garage rock\nThai pop, Luk Thung, pop-rock\nThai pop, Luk Thung, retro\nThai pop, Luk Thung, retro pop\nThai pop, Luk Thung, retro synth\nThai pop, Luk Thung, synth pop\nThai pop, Luk Thung, synth-pop\nThai pop, Luk Thung, synthwave\nThai pop, Luk thung\nThai pop, Luk thung, dance\nThai pop, Luk thung, pop-rock\nThai pop, Luk thung, retro\nThai pop, R&B\nThai pop, R&B, ballad\nThai pop, R&B, city pop\nThai pop, R&B, hip-hop\nThai pop, R&B, lo-fi hip-hop\nThai pop, R&B, synth-pop\nThai pop, R&B, trap\nThai pop, Thai rock\nThai pop, acoustic pop, pop-rap\nThai pop, anime soundtrack\nThai pop, ballad, theatrical\nThai pop, big band\nThai pop, big band jazz\nThai pop, big band, Latin\nThai pop, big band, Luk Thung\nThai pop, big band, ballad\nThai pop, big band, boom-bap hip-hop\nThai pop, big band, lounge\nThai pop, big band, ska\nThai pop, big band, swing\nThai pop, bossa nova, exotica\nThai pop, bossa nova, lounge jazz\nThai pop, chanson, acoustic\nThai pop, chiptune\nThai pop, chiptune, EDM\nThai pop, chiptune, J-pop\nThai pop, chiptune, electronic\nThai pop, chiptune, orchestral\nThai pop, chiptune, pop-R&B\nThai pop, chiptune, pop-rock\nThai pop, chiptune, retro\nThai pop, chiptune, retro game\nThai pop, chiptune, video game music\nThai pop, cinematic\nThai pop, cinematic ballad\nThai pop, cinematic orchestral\nThai pop, cinematic pop\nThai pop, cinematic, Luk Thung\nThai pop, cinematic, ballad\nThai pop, cinematic, melancholic\nThai pop, cinematic, orchestral\nThai pop, city pop\nThai pop, city pop, 90s R&B\nThai pop, city pop, R&B\nThai pop, city pop, disco\nThai pop, city pop, easy-listening\nThai pop, city pop, funk\nThai pop, city pop, indie pop\nThai pop, city pop, jazz\nThai pop, city pop, jazz-funk\nThai pop, city pop, new jack swing\nThai pop, city pop, new wave\nThai pop, city pop, smooth jazz\nThai pop, city pop, surf rock\nThai pop, city pop, synth-funk\nThai pop, city pop, synth-pop\nThai pop, city-pop\nThai pop, city-pop, jazz\nThai pop, cumbia\nThai pop, electro-mor Lam\nThai pop, electronic dance\nThai pop, electronic, chiptune\nThai pop, flamenco, disco\nThai pop, funk, chiptune\nThai pop, funk, dangdut\nThai pop, funk, disco\nThai pop, funk, electronic dance\nThai pop, funk, hip-hop\nThai pop, funk, hyperpop\nThai pop, future bass, city pop\nThai pop, future bass, kawaii\nThai pop, hip-hop\nThai pop, hip-hop, EDM\nThai pop, hip-hop, chiptune\nThai pop, hip-hop, dancehall\nThai pop, hyperpop\nThai pop, hyperpop, kawaii future bass\nThai pop, jazz, R&B\nThai pop, jazz, soul\nThai pop, lo-fi R&B\nThai pop, lo-fi hip hop\nThai pop, lo-fi hip hop, R&B\nThai pop, lo-fi hip hop, ambient\nThai pop, lo-fi hip-hop\nThai pop, lo-fi, retro\nThai pop, lo-fi, soulful ballad\nThai pop, neo-soul, R&B\nThai pop, neo-soul, city pop\nThai pop, neo-soul, lo-fi hip-hop\nThai pop, new age, world music\nThai pop, new jack swing\nThai pop, new jack swing, city pop\nThai pop, new jack swing, funk\nThai pop, new jack swing, retro\nThai pop, new jack swing, synth-pop\nThai pop, nu-disco, city pop\nThai pop, power ballad\nThai pop, psychedelic pop\nThai pop, reggae\nThai pop, reggae, dancehall\nThai pop, retro big band\nThai pop, retro dance-pop\nThai pop, retro funk, disco\nThai pop, retro funk, synth-pop\nThai pop, retro swing\nThai pop, retro synth, video game\nThai pop, retro video game\nThai pop, retro, big band\nThai pop, ska, Latin\nThai pop, ska, big band\nThai pop, ska, polka\nThai pop, smooth jazz\nThai pop, soul, ballad\nThai pop, soul, jazz\nThai pop, synth-pop\nThai pop, synth-pop, 80s\nThai pop, synth-pop, city pop\nThai pop, synth-pop, disco\nThai pop, trap\nThai pop, trap, Luk Thung\nThai pop, trap, R&B\nThai pop, trap, hyperpop\nThai pop, trap, lo-fi hip-hop\nThai pop, vaporwave, R&B\nThai pop, world music fusion\nThai pop-R&B\nThai pop-R&B lo-fi hip-hop\nThai pop-R&B, lo-fi hip-hop\nThai pop-country\nThai pop-folk\nThai pop-funk\nThai pop-funk city pop\nThai pop-gospel\nThai pop-jazz\nThai pop-punk\nThai pop-rap\nThai pop-rap chiptune\nThai pop-rap emo-rap\nThai pop-rap lo-fi hip-hop\nThai pop-rap, hyperpop, electronic\nThai pop-rap, lo-fi hip-hop\nThai pop-rap, lo-fi hip-hop, chiptune\nThai pop-reggae\nThai pop-rock\nThai pop-rock 80s\nThai pop-rock 90s\nThai pop-rock chiptune\nThai pop-rock city pop\nThai pop-rock funk\nThai pop-rock jazz\nThai pop-rock reggae\nThai pop-rock, EDM, synthwave\nThai pop-rock, Eurodance\nThai pop-rock, J-pop\nThai pop-rock, Luk Thung\nThai pop-rock, city pop\nThai pop-rock, city pop, big band\nThai pop-rock, city pop, funk\nThai pop-rock, city pop, retro\nThai pop-rock, future bass, hardstyle\nThai pop-rock, hip-hop\nThai pop-rock, lo-fi, vaporwave\nThai pop-rock, neo-soul, R&B\nThai pop-rock, smooth jazz\nThai pop-trap\nThai power ballad\nThai psychedelic rock\nThai punk rock\nThai punk rock chiptune\nThai reggae\nThai reggae hip-hop\nThai reggae-pop\nThai rock\nThai rock 'n' roll\nThai rock Luk Thung\nThai rock and roll\nThai rock ballad\nThai rock chiptune\nThai rock country-rock\nThai rock funk\nThai rock funk disco\nThai rock funk ska\nThai rock fusion\nThai rock nu-metal\nThai rock opera\nThai rock ska-punk\nThai rock surf rock\nThai rock, Latin percussion\nThai rock, Latin rock\nThai rock, Luk Thung\nThai rock, Luk Thung, blues-rock\nThai rock, Luk Thung, country-pop\nThai rock, Luk Thung, funk rock\nThai rock, Luk Thung, rock\nThai rock, Luk thung\nThai rock, Middle Eastern fusion\nThai rock, Mor Lam\nThai rock, Mor Lam fusion\nThai rock, Mor Lam, hard rock\nThai rock, Mor Lam, rock fusion\nThai rock, big band swing\nThai rock, blues rock\nThai rock, boogie-woogie, Latin rock\nThai rock, chiptune, synth-pop\nThai rock, dance-pop\nThai rock, electronic dance, fusion\nThai rock, hard rock\nThai rock, neoclassical metal\nThai rock, rap-rock\nThai rock, surf rock\nThai rockabilly\nThai romantic\nThai romantic ballad\nThai roots-rock\nThai sad trap\nThai salsa\nThai show tune, big band, swing\nThai singer-songwriter\nThai ska\nThai ska Luk Thung\nThai ska-funk\nThai ska-pop\nThai ska-punk\nThai ska-punk funk-rock\nThai ska-reggae\nThai ska-rock\nThai surf rock\nThai swing\nThai synth-pop\nThai theatrical\nThai traditional\nThai traditional, cinematic, epic\nThai trap\nThai trap R&B\nThai trap, cloud rap, R&B\nThai trap, hardstyle, cinematic EDM\nThai trap-pop\nThai-pop\nThai-pop EDM\nThai-pop Eurodance\nThai-pop J-pop\nThai-pop, EDM\nThai-pop, Eurobeat, City Pop\nThai-pop, Eurobeat, J-pop\nThai-pop, Eurodance\nThai-pop, Eurodance, J-pop\nThai-pop, Eurodance, chiptune\nThai-pop, Eurodance, happy hardcore\nThai-pop, dancehall, hip-hop\nThai-pop, disco-funk\nThai-pop, hyperpop, chiptune\nThai-pop, new jack swing, dance-pop\nTibetan dance-pop\nTibetan electronic\nTibetan electronic dance\nTibetan electronic dance-pop\nTibetan electronic pop\nTibetan electronic rock\nTibetan folk\nTibetan folk electronic\nTibetan folk fusion\nTibetan folk pop-rock\nTibetan folk rock\nTibetan folk, electronic dance\nTibetan folk, electronic dance, worldbeat\nTibetan folk, electronic pop\nTibetan folk, electronic pop, worldbeat\nTibetan folk, electronic, trap\nTibetan folk, retro electronic\nTibetan folk, world music\nTibetan folk-pop\nTibetan folk-pop rock\nTibetan folk-pop, electronic dance\nTibetan folk-pop, hard rock\nTibetan fusion\nTibetan fusion hip-hop\nTibetan fusion, electronic dance\nTibetan fusion, electronic dance, ethnic pop\nTibetan fusion, electronic dance-pop\nTibetan pop\nTibetan pop R&B\nTibetan pop hip-hop\nTibetan pop trap\nTibetan pop, EDM, trap\nTibetan pop, chiptune, electronic dance\nTibetan pop, electronic dance\nTibetan pop, electronic dance music\nTibetan pop, future bass\nTibetan pop-funk\nTibetan pop-rap\nTibetan pop-rock\nTibetan pop-rock, electronic dance\nTibetan rock\nTollywood\nTollywood Christian devotional\nTollywood Christian pop\nTollywood Christmas\nTollywood EDM\nTollywood anthem\nTollywood children's music\nTollywood cinematic\nTollywood dance\nTollywood dance pop\nTollywood dance, EDM, hip-hop\nTollywood dance, electronic, R&B\nTollywood dance, moombahton\nTollywood dance-pop\nTollywood devotional\nTollywood disco-funk\nTollywood electronic\nTollywood electronica\nTollywood film music\nTollywood film score\nTollywood film-pop\nTollywood filmi\nTollywood filmi, electronic, Indian classical\nTollywood filmi-pop\nTollywood folk\nTollywood folk-pop\nTollywood funk\nTollywood funk-pop\nTollywood funk-rock\nTollywood hip-hop\nTollywood party anthem\nTollywood pop\nTollywood pop dancehall\nTollywood pop funk disco\nTollywood pop fusion\nTollywood pop, EDM\nTollywood pop, Latin pop\nTollywood pop, chiptune, electronic\nTollywood pop, cinematic, hip-hop\nTollywood pop, electronic, hip-hop\nTollywood pop, hip-hop, pop\nTollywood pop-funk\nTollywood pop-rock\nTollywood rock\nTollywood, 2000s pop, romantic\nTollywood, Indian film music, vintage\nTollywood, Indian film score, playful\nTollywood, Latin pop\nTollywood, chiptune, retro\nTollywood, electronic dance, cinematic\nTollywood, electronic, cinematic\nTollywood, electronic, rock\nTraditional Arabic\nTraditional Arabic Folk\nTraditional Asian\nTraditional Central Asian\nTraditional Chinese\nTraditional Chinese Art Song\nTraditional Chinese Ballad\nTraditional Chinese Classical\nTraditional Chinese Folk\nTraditional Chinese Instrumental\nTraditional Chinese Music\nTraditional Chinese Opera\nTraditional Chinese ballad\nTraditional Chinese children's music\nTraditional Chinese folk\nTraditional Chinese music\nTraditional Chinese, Instrumental, Folk Fusion\nTraditional Chinese, Martial, Percussive\nTraditional Chinese, Opera, Guzheng\nTraditional Chinese, cinematic\nTraditional East Asian\nTraditional East Asian folk\nTraditional Folk\nTraditional Hawaiian\nTraditional Holiday\nTraditional Japanese\nTraditional Middle Eastern\nTraditional Mongolian\nTraditional North African\nTraditional Persian\nTraditional Pop\nTrinidadian hip-hop\nTuna, Cumbia\nTurkish Arabesque\nTurkish EDM\nTurkish EDM-pop\nTurkish Eurodance\nTurkish Eurodance nu-metal\nTurkish Hardcore\nTurkish Islamic\nTurkish Islamic devotional\nTurkish Islamic music\nTurkish Islamic zeynate\nTurkish Latin fusion\nTurkish Latin jazz\nTurkish Latin pop\nTurkish Latin pop-rock\nTurkish Latin trap\nTurkish Latin-pop\nTurkish Mawwal\nTurkish Mawwal, cinematic, epic\nTurkish Nasheed\nTurkish R&B\nTurkish R&B lo-fi\nTurkish R&B lo-fi hip-hop\nTurkish R&B trap\nTurkish R&B, German rap, trap\nTurkish R&B, hip-hop\nTurkish R&B, lo-fi hip-hop\nTurkish R&B, modern trap\nTurkish R&B, trap, Arabic chant\nTurkish Sufi\nTurkish acoustic\nTurkish acoustic ballad\nTurkish acoustic folk\nTurkish acoustic folk-pop\nTurkish acoustic pop\nTurkish acoustic pop-rock\nTurkish acoustic rock\nTurkish alternative R&B\nTurkish alternative hip-hop\nTurkish alternative pop\nTurkish alternative pop dream pop\nTurkish alternative pop, hip-hop\nTurkish alternative pop, modern trap\nTurkish alternative pop, synth-pop\nTurkish alternative pop, trip-hop\nTurkish alternative pop-rock\nTurkish alternative rock\nTurkish alternative rock dream pop\nTurkish alternative rock hip-hop\nTurkish alternative rock, emo rap\nTurkish alternative rock, hip-hop\nTurkish alternative rock, trip-hop\nTurkish alternative rock, trip-hop, psychedelic\nTurkish ambient\nTurkish ambient trap\nTurkish arabesque\nTurkish arabesque cinematic\nTurkish arabesque hip-hop\nTurkish arabesque jazz\nTurkish arabesque pop\nTurkish arabesque pop-rock\nTurkish arabesque progressive rock\nTurkish arabesque rap\nTurkish arabesque rock\nTurkish arabesque tango\nTurkish arabesque trap\nTurkish arabesque, Turkish pop\nTurkish arabesque, boom-bap hip-hop\nTurkish arabesque, cinematic\nTurkish arabesque, cinematic folk-pop\nTurkish arabesque, cinematic metal\nTurkish arabesque, cinematic orchestral\nTurkish arabesque, cinematic pop\nTurkish arabesque, cinematic pop, classical fusion\nTurkish arabesque, cinematic pop, world fusion\nTurkish arabesque, cinematic pop-rock\nTurkish arabesque, cinematic rock\nTurkish arabesque, cinematic trap\nTurkish arabesque, cinematic, Middle Eastern fusion\nTurkish arabesque, cinematic, dance pop\nTurkish arabesque, cinematic, disco-rock\nTurkish arabesque, cinematic, electronic dance\nTurkish arabesque, cinematic, orchestral\nTurkish arabesque, cinematic, oud\nTurkish arabesque, cinematic, trap\nTurkish arabesque, cinematic, violin\nTurkish arabesque, cinematic, world fusion\nTurkish arabesque, electronic dance\nTurkish arabesque, electronic, ambient\nTurkish arabesque, electronic, melancholic\nTurkish arabesque, hip-hop\nTurkish arabesque, hip-hop, ambient\nTurkish arabesque, old-school hip-hop\nTurkish arabesque, pop-rap\nTurkish arabesque, pop-rock\nTurkish arabesque, pop-rock, cinematic\nTurkish arabesque, pop-rock, dance\nTurkish arabesque, smooth jazz\nTurkish arabesque, symphonic rock\nTurkish arabesque, trap\nTurkish arabesque, trap hip-hop\nTurkish arabesque, trap, Middle Eastern fusion\nTurkish arabesque, trap, cinematic\nTurkish arabesque, trap, hip-hop\nTurkish arabesque, trap, lo-fi\nTurkish arabesque, trap, microtonal\nTurkish arabesque, trap, rock\nTurkish art music\nTurkish art music big band\nTurkish art music, classical, folk\nTurkish art rock\nTurkish art song\nTurkish art-pop\nTurkish ballad\nTurkish ballad, Bossa Nova\nTurkish ballad, European folk, melancholic\nTurkish battle rap\nTurkish big band\nTurkish blues-rock\nTurkish bolero\nTurkish boom-bap\nTurkish bossa nova\nTurkish cabaret\nTurkish chanson\nTurkish chanson, cabaret, jazz\nTurkish chanson, cabaret, klezmer\nTurkish children's\nTurkish children's anthem\nTurkish children's dance-pop\nTurkish children's music\nTurkish children's music world music\nTurkish children's pop\nTurkish children's pop reggaeton\nTurkish children's pop-rock\nTurkish children's, Eurodance\nTurkish children's, Eurodance, chiptune\nTurkish children's, Latin, world music\nTurkish children's, cumbia\nTurkish choral\nTurkish choral trap\nTurkish choral, martial anthem\nTurkish cinematic\nTurkish classical\nTurkish classical crossover\nTurkish classical fusion\nTurkish classical tango\nTurkish classical, Arabesque\nTurkish classical, Middle Eastern, cinematic\nTurkish classical, Middle Eastern, orchestral\nTurkish classical, arabesque\nTurkish classical, arabesque, cinematic\nTurkish classical, cinematic, Middle Eastern\nTurkish classical, cinematic, arabesque\nTurkish classical, cinematic, dramatic\nTurkish classical, cinematic, epic\nTurkish classical, cinematic, orchestral\nTurkish classical, cinematic, oud\nTurkish classical, cinematic, world fusion\nTurkish classical, cinematic, world music\nTurkish classical, folk fusion\nTurkish classical, folk rock\nTurkish classical, folk, cinematic\nTurkish classical, orchestral, operatic\nTurkish classical, trap\nTurkish club\nTurkish club rap\nTurkish club-rap\nTurkish conscious hip-hop\nTurkish dance\nTurkish dance-pop\nTurkish dance-pop chiptune\nTurkish dance-pop, EDM, trap\nTurkish dance-pop, cinematic, Eurodance\nTurkish dance-pop, hyperpop, nightcore\nTurkish dancehall\nTurkish dark trap\nTurkish devotional\nTurkish devotional pop\nTurkish devotional pop-rock\nTurkish disco funk\nTurkish disco-funk\nTurkish disco-pop\nTurkish dramatic pop-rap\nTurkish drill\nTurkish drill trap\nTurkish drill, trap\nTurkish electronic\nTurkish electronic dance\nTurkish electronic dance-pop\nTurkish electronic folk-pop\nTurkish electronic pop\nTurkish electronic trap\nTurkish electronic, Italo-disco, synth-pop\nTurkish emo rap\nTurkish emo trap\nTurkish emo-rap\nTurkish emotional hip-hop\nTurkish emotional trap\nTurkish ethereal trap\nTurkish ethno-house\nTurkish ethno-pop\nTurkish film score\nTurkish flamenco\nTurkish folk\nTurkish folk Bossa Nova\nTurkish folk a cappella\nTurkish folk arabesque\nTurkish folk ballad\nTurkish folk blues\nTurkish folk cabaret\nTurkish folk chiptune\nTurkish folk cinematic\nTurkish folk classical\nTurkish folk dance\nTurkish folk dance-pop\nTurkish folk electronic\nTurkish folk electronica\nTurkish folk flamenco\nTurkish folk funk rock\nTurkish folk funk-rock\nTurkish folk fusion\nTurkish folk gypsy jazz\nTurkish folk hip-hop\nTurkish folk house\nTurkish folk jazz\nTurkish folk jazz fusion\nTurkish folk lament\nTurkish folk lo-fi\nTurkish folk march\nTurkish folk metal\nTurkish folk neo-classical\nTurkish folk pop\nTurkish folk pop-rock\nTurkish folk protest\nTurkish folk psychedelic rock\nTurkish folk punk\nTurkish folk rap\nTurkish folk rock\nTurkish folk spiritual\nTurkish folk surf rock\nTurkish folk swing\nTurkish folk tango\nTurkish folk tango cabaret\nTurkish folk tango classical\nTurkish folk tango flamenco\nTurkish folk tango jazz\nTurkish folk trap\nTurkish folk world music\nTurkish folk, Arabesque\nTurkish folk, Arabic mawwal, world fusion\nTurkish folk, Arabic music, Western classical\nTurkish folk, Arabic music, cinematic\nTurkish folk, Balkan brass\nTurkish folk, Balkan folk, gypsy jazz\nTurkish folk, Balkan folk, romantic duet\nTurkish folk, Balkan music, world fusion\nTurkish folk, Balkan, cinematic\nTurkish folk, Balkan, polka\nTurkish folk, Eastern European folk\nTurkish folk, Eurodance\nTurkish folk, Eurodance, dance-pop\nTurkish folk, European cabaret\nTurkish folk, Latin jazz, world music\nTurkish folk, Latin, European\nTurkish folk, Mediterranean, melancholic\nTurkish folk, Middle Eastern classical\nTurkish folk, Middle Eastern fusion\nTurkish folk, Middle Eastern, ambient\nTurkish folk, Middle Eastern, cinematic\nTurkish folk, Middle Eastern, electronic\nTurkish folk, Middle Eastern, modern fusion\nTurkish folk, Middle Eastern, spiritual\nTurkish folk, Sufi music\nTurkish folk, acoustic singer-songwriter\nTurkish folk, ambient electronica\nTurkish folk, ambient, downtempo\nTurkish folk, ambient, electronic\nTurkish folk, arabesque\nTurkish folk, arabesque, cinematic\nTurkish folk, arabesque, dramatic pop-rock\nTurkish folk, arabesque, dramatic rock\nTurkish folk, arabesque, electronic\nTurkish folk, arabesque, flamenco\nTurkish folk, arabesque, melancholic\nTurkish folk, arabesque, oud\nTurkish folk, arabesque, pop-folk\nTurkish folk, arabesque, psychedelic rock\nTurkish folk, arabesque, world music\nTurkish folk, atmospheric, melancholic\nTurkish folk, big band jazz\nTurkish folk, bluegrass\nTurkish folk, cabaret\nTurkish folk, cabaret, tango\nTurkish folk, children's music\nTurkish folk, children's music, chiptune\nTurkish folk, children's music, world music\nTurkish folk, chiptune\nTurkish folk, chiptune, folk anthem\nTurkish folk, cinematic\nTurkish folk, cinematic pop\nTurkish folk, cinematic pop, world music\nTurkish folk, cinematic world music\nTurkish folk, cinematic, Eastern European\nTurkish folk, cinematic, Middle Eastern\nTurkish folk, cinematic, ambient\nTurkish folk, cinematic, arabesque\nTurkish folk, cinematic, classical\nTurkish folk, cinematic, dramatic\nTurkish folk, cinematic, electronic\nTurkish folk, cinematic, electronic fusion\nTurkish folk, cinematic, emotional\nTurkish folk, cinematic, epic\nTurkish folk, cinematic, lo-fi\nTurkish folk, cinematic, melancholic\nTurkish folk, cinematic, operatic\nTurkish folk, cinematic, orchestral\nTurkish folk, cinematic, oud\nTurkish folk, cinematic, progressive\nTurkish folk, cinematic, rock\nTurkish folk, cinematic, world fusion\nTurkish folk, classical\nTurkish folk, classical chamber, world music\nTurkish folk, classical crossover, film score\nTurkish folk, classical crossover, world music\nTurkish folk, classical, psychedelic\nTurkish folk, classical, world music\nTurkish folk, dance-pop\nTurkish folk, downtempo, trap\nTurkish folk, electronic\nTurkish folk, electronic dance\nTurkish folk, electronic fusion\nTurkish folk, electronic pop\nTurkish folk, electronic, Middle Eastern fusion\nTurkish folk, electronic, ambient\nTurkish folk, electronic, cinematic\nTurkish folk, electronic, dance\nTurkish folk, electronic, epic\nTurkish folk, electronic, fusion\nTurkish folk, electronic, melancholic\nTurkish folk, electronic, pop-rock\nTurkish folk, electronic, world fusion\nTurkish folk, energetic, saz\nTurkish folk, epic hip-hop\nTurkish folk, flamenco, acoustic\nTurkish folk, flamenco, classical\nTurkish folk, flamenco, melancholic acoustic\nTurkish folk, gypsy jazz\nTurkish folk, gypsy jazz, boogie-woogie\nTurkish folk, gypsy jazz, tango\nTurkish folk, hard electronic, dance\nTurkish folk, hip-hop\nTurkish folk, melancholic, cinematic\nTurkish folk, melancholic, modern production\nTurkish folk, modern production\nTurkish folk, new age\nTurkish folk, ney, ambient\nTurkish folk, operatic, electronic\nTurkish folk, orchestral, epic\nTurkish folk, orchestral, jazz fusion\nTurkish folk, pop-rock\nTurkish folk, pop-rock, arabesque\nTurkish folk, psychedelic rock\nTurkish folk, reggaeton, dance-pop\nTurkish folk, reggaeton, world fusion\nTurkish folk, retro electronic\nTurkish folk, spiritual, children's choir\nTurkish folk, spiritual, modern\nTurkish folk, symphonic metal\nTurkish folk, synth pop\nTurkish folk, tango, Latin\nTurkish folk, theatrical\nTurkish folk, theatrical, operatic\nTurkish folk, theatrical, tango\nTurkish folk, trap\nTurkish folk, trap, cinematic\nTurkish folk, trap, emotional fusion\nTurkish folk, trap, microtonal\nTurkish folk, world music\nTurkish folk, world music, ambient\nTurkish folk, world music, cinematic\nTurkish folk, world music, dramatic ballad\nTurkish folk, world music, electronic fusion\nTurkish folk, world music, melancholic\nTurkish folk, world music, pop-rock\nTurkish folk, worldbeat, electronic\nTurkish folk-dance\nTurkish folk-electronic\nTurkish folk-pop\nTurkish folk-pop cabaret\nTurkish folk-pop chiptune\nTurkish folk-pop surf-rock\nTurkish folk-pop, electronic dance\nTurkish folk-rap\nTurkish folk-rock\nTurkish folk-trap\nTurkish funk\nTurkish funk-pop\nTurkish funk-rap\nTurkish funk-reggae\nTurkish funk-rock\nTurkish fusion\nTurkish fusion hip-hop\nTurkish fusion pop-rock\nTurkish fusion rock\nTurkish fusion trap\nTurkish fusion trap-pop\nTurkish fusion, electronic pop\nTurkish fusion, electronic, cinematic\nTurkish fusion, electronic, dramatic\nTurkish fusion, electronic, emotive vocals\nTurkish fusion, electronic, melancholic\nTurkish fusion, electronic, oud\nTurkish gangsta rap\nTurkish hard dance\nTurkish hard rock\nTurkish hardcore hip-hop\nTurkish heavy metal\nTurkish hip hop\nTurkish hip hop, boom-bap, cyberpunk\nTurkish hip-hop\nTurkish hip-hop G-funk\nTurkish hip-hop alternative rock\nTurkish hip-hop arabesque pop\nTurkish hip-hop chiptune\nTurkish hip-hop dance-pop\nTurkish hip-hop electronic\nTurkish hip-hop epic rock\nTurkish hip-hop flamenco\nTurkish hip-hop funk\nTurkish hip-hop funk psychedelic rock\nTurkish hip-hop industrial trap\nTurkish hip-hop lo-fi\nTurkish hip-hop reggaeton\nTurkish hip-hop trap\nTurkish hip-hop, G-funk\nTurkish hip-hop, Latin acoustic\nTurkish hip-hop, Middle Eastern fusion\nTurkish hip-hop, Middle Eastern fusion, cinematic\nTurkish hip-hop, R&B, atmospheric\nTurkish hip-hop, alternative rock, atmospheric pop\nTurkish hip-hop, boom-bap\nTurkish hip-hop, chiptune, trap\nTurkish hip-hop, cinematic\nTurkish hip-hop, cinematic orchestral\nTurkish hip-hop, cinematic trap\nTurkish hip-hop, cinematic violin\nTurkish hip-hop, cinematic, Middle Eastern fusion\nTurkish hip-hop, cinematic, chiptune\nTurkish hip-hop, cinematic, emotional\nTurkish hip-hop, cinematic, melancholic\nTurkish hip-hop, cinematic, trap\nTurkish hip-hop, dark trap\nTurkish hip-hop, electronic dance\nTurkish hip-hop, electronic dance music\nTurkish hip-hop, electronic dance, cinematic\nTurkish hip-hop, electronic dance, protest music\nTurkish hip-hop, emotional ballad, cinematic piano\nTurkish hip-hop, emotional pop\nTurkish hip-hop, flamenco pop\nTurkish hip-hop, folk fusion\nTurkish hip-hop, lo-fi boom-bap, hyperpop\nTurkish hip-hop, nu-metal\nTurkish hip-hop, rap-rock\nTurkish hip-hop, reggaeton, electronic\nTurkish hip-hop, soulful R&B\nTurkish hip-hop, synth-pop\nTurkish hip-hop, trap\nTurkish hip-hop, trap, cinematic\nTurkish hip-house\nTurkish house\nTurkish hyperpop\nTurkish indie folk\nTurkish indie pop\nTurkish indie pop jazz\nTurkish indie pop-rock\nTurkish indie rock\nTurkish indie-folk\nTurkish indie-pop\nTurkish jazz\nTurkish jazz fusion\nTurkish jazz-pop\nTurkish lo-fi hip hop\nTurkish lounge-pop\nTurkish lullaby\nTurkish makam\nTurkish march\nTurkish marching\nTurkish melodic rap, reggaeton\nTurkish melodic trap\nTurkish metal\nTurkish military march\nTurkish military march, Eurodance, trance\nTurkish music\nTurkish new wave\nTurkish ney\nTurkish ney, trap, cinematic\nTurkish novelty\nTurkish orchestral\nTurkish oud, boom-bap hip-hop\nTurkish oud, trap, hip-hop\nTurkish party\nTurkish party rap\nTurkish patriotic\nTurkish patriotic march\nTurkish pavyon\nTurkish percussive\nTurkish political anthem\nTurkish political pop\nTurkish pop\nTurkish pop 80s\nTurkish pop 90s\nTurkish pop 90s dance-pop\nTurkish pop Afrobeat\nTurkish pop Afrobeat Latin\nTurkish pop Arabesque\nTurkish pop Arabic pop\nTurkish pop Balkan brass\nTurkish pop Balkan dance\nTurkish pop Balkan folk\nTurkish pop Bossa Nova\nTurkish pop Eurodance\nTurkish pop J-pop chiptune\nTurkish pop Latin\nTurkish pop Latin dance\nTurkish pop Latin fusion\nTurkish pop Latin jazz\nTurkish pop R&B\nTurkish pop R&B funk\nTurkish pop R&B trap\nTurkish pop ambient\nTurkish pop arabesque\nTurkish pop ballad\nTurkish pop big band\nTurkish pop bossa nova\nTurkish pop cabaret\nTurkish pop cabaret tango\nTurkish pop chiptune\nTurkish pop cinematic\nTurkish pop cumbia\nTurkish pop dance\nTurkish pop dance-pop\nTurkish pop dancehall\nTurkish pop dancehall-reggae\nTurkish pop dembow\nTurkish pop downtempo\nTurkish pop electronic\nTurkish pop flamenco\nTurkish pop flamenco Latin\nTurkish pop flamenco tango\nTurkish pop flamenco world music\nTurkish pop folk\nTurkish pop funk\nTurkish pop funk R&B\nTurkish pop funk big band\nTurkish pop funk disco\nTurkish pop funk jazz\nTurkish pop funk jazz fusion\nTurkish pop funk soul\nTurkish pop funk-disco\nTurkish pop funk-rock\nTurkish pop fusion\nTurkish pop future bass\nTurkish pop hip-hop\nTurkish pop industrial rock\nTurkish pop jazz\nTurkish pop jazz Latin\nTurkish pop jazz fusion funk\nTurkish pop jazz lounge\nTurkish pop lo-fi\nTurkish pop lo-fi hip hop\nTurkish pop lounge\nTurkish pop lounge jazz\nTurkish pop progressive rock\nTurkish pop psychedelic rock\nTurkish pop reggae dancehall\nTurkish pop reggaeton\nTurkish pop reggaeton chiptune\nTurkish pop rock\nTurkish pop salsa\nTurkish pop surf rock\nTurkish pop tango\nTurkish pop tango Latin jazz\nTurkish pop tango cabaret\nTurkish pop tango classical\nTurkish pop tango flamenco\nTurkish pop trap\nTurkish pop trap R&B\nTurkish pop trip-hop\nTurkish pop world fusion\nTurkish pop world music\nTurkish pop, 70s disco, cinematic\nTurkish pop, 8-bit chiptune\nTurkish pop, 80s pop, synthwave\nTurkish pop, 80s synth\nTurkish pop, 80s synth pop\nTurkish pop, 80s synth, arabesque\nTurkish pop, 80s synth, cinematic\nTurkish pop, 80s synth, dance\nTurkish pop, 80s synth, dance pop\nTurkish pop, 80s synth, dramatic pop\nTurkish pop, 80s synth-pop\nTurkish pop, 90s R&B, lo-fi\nTurkish pop, 90s R&B, lo-fi hip hop\nTurkish pop, 90s breakbeat, trip-hop\nTurkish pop, 90s dance\nTurkish pop, 90s dance-pop\nTurkish pop, 90s dance-pop, Eurodance\nTurkish pop, 90s dance-pop, disco\nTurkish pop, Afrobeats, dancehall\nTurkish pop, Anatolian rock\nTurkish pop, Anatolian rock, 80s pop\nTurkish pop, Anatolian rock, psychedelic pop\nTurkish pop, Arabesque\nTurkish pop, Arabesque, 90s dance-pop\nTurkish pop, Arabesque, Eurodance\nTurkish pop, Arabesque, Middle Eastern\nTurkish pop, Arabesque, belly dance\nTurkish pop, Arabesque, cinematic\nTurkish pop, Arabesque, cinematic pop\nTurkish pop, Arabesque, dance\nTurkish pop, Arabesque, dance pop\nTurkish pop, Arabesque, electronic\nTurkish pop, Arabesque, electronic dance\nTurkish pop, Arabesque, folk\nTurkish pop, Arabesque, funk\nTurkish pop, Arabesque, microtonal\nTurkish pop, Azerbaijani folk\nTurkish pop, Azerbaijani folk, electronic\nTurkish pop, Balkan brass\nTurkish pop, Balkan brass, Klezmer\nTurkish pop, Balkan folk\nTurkish pop, Balkan folk, Middle Eastern folk\nTurkish pop, Balkan fusion, electronic\nTurkish pop, Balkan fusion, jazz\nTurkish pop, Balkan jazz\nTurkish pop, Balkan, Klezmer\nTurkish pop, Balkan, Latin\nTurkish pop, Balkan, Middle Eastern\nTurkish pop, Balkan, gypsy jazz\nTurkish pop, Balkan, tango\nTurkish pop, Bossa Nova\nTurkish pop, Bossa Nova, Latin jazz\nTurkish pop, Bossa Nova, jazz\nTurkish pop, EDM\nTurkish pop, EDM, atmospheric\nTurkish pop, EDM, cinematic\nTurkish pop, EDM, dance-pop\nTurkish pop, EDM, oriental\nTurkish pop, EDM, trap\nTurkish pop, Euro-disco\nTurkish pop, Eurodance\nTurkish pop, Eurodance, 90s dance-pop\nTurkish pop, Eurodance, Balkan pop\nTurkish pop, Eurodance, Dabke\nTurkish pop, Eurodance, Italo disco\nTurkish pop, Eurodance, Italo-disco\nTurkish pop, Eurodance, Latin pop\nTurkish pop, Eurodance, Middle Eastern\nTurkish pop, Eurodance, belly dance\nTurkish pop, Eurodance, chiptune\nTurkish pop, Eurodance, cinematic\nTurkish pop, Eurodance, dance-pop\nTurkish pop, Eurodance, disco\nTurkish pop, Eurodance, electronic\nTurkish pop, Eurodance, flamenco\nTurkish pop, Eurodance, folk\nTurkish pop, Eurodance, funk\nTurkish pop, Eurodance, fusion\nTurkish pop, Eurodance, happy hardcore\nTurkish pop, Eurodance, hip-hop\nTurkish pop, Eurodance, hip-house\nTurkish pop, Eurodance, hyperpop\nTurkish pop, Eurodance, late-90s dance-pop\nTurkish pop, Eurodance, lo-fi\nTurkish pop, Eurodance, microtonal\nTurkish pop, Eurodance, new jack swing\nTurkish pop, Eurodance, ney flute\nTurkish pop, Eurodance, oriental\nTurkish pop, Eurodance, reggaeton\nTurkish pop, Eurodance, retro\nTurkish pop, Eurodance, retro dance\nTurkish pop, Eurodance, synthpop\nTurkish pop, Eurodance, trance\nTurkish pop, Eurodance, worldbeat\nTurkish pop, European folk\nTurkish pop, French chanson, Middle Eastern fusion\nTurkish pop, French chanson, funk\nTurkish pop, German hip-hop\nTurkish pop, German schlager\nTurkish pop, Italo disco, Eurodance\nTurkish pop, Italo-disco, retro synth-pop\nTurkish pop, Latin acoustic\nTurkish pop, Latin cumbia\nTurkish pop, Latin dance\nTurkish pop, Latin dance, Eurodance\nTurkish pop, Latin dance, dembow\nTurkish pop, Latin disco\nTurkish pop, Latin disco, 80s pop\nTurkish pop, Latin funk\nTurkish pop, Latin fusion\nTurkish pop, Latin fusion, Middle Eastern\nTurkish pop, Latin jazz\nTurkish pop, Latin jazz, Bossa Nova\nTurkish pop, Latin jazz, big band\nTurkish pop, Latin jazz, tango\nTurkish pop, Latin pop\nTurkish pop, Latin pop, Arabesque\nTurkish pop, Latin pop, Caribbean pop\nTurkish pop, Latin pop, Cumbia\nTurkish pop, Latin pop, Eurodance\nTurkish pop, Latin pop, Mediterranean\nTurkish pop, Latin pop, Middle Eastern fusion\nTurkish pop, Latin pop, Middle Eastern pop\nTurkish pop, Latin pop, ballad\nTurkish pop, Latin pop, big band\nTurkish pop, Latin pop, cinematic\nTurkish pop, Latin pop, cumbia\nTurkish pop, Latin pop, dance\nTurkish pop, Latin pop, dance pop\nTurkish pop, Latin pop, disco\nTurkish pop, Latin pop, dream pop\nTurkish pop, Latin pop, flamenco\nTurkish pop, Latin pop, mambo\nTurkish pop, Latin pop, merengue\nTurkish pop, Latin pop, psychedelic\nTurkish pop, Latin pop, reggaeton\nTurkish pop, Latin pop, rock and roll\nTurkish pop, Latin pop, salsa\nTurkish pop, Latin pop, ska\nTurkish pop, Latin pop, surf rock\nTurkish pop, Latin pop, tango\nTurkish pop, Latin pop, theatrical\nTurkish pop, Latin pop, vintage\nTurkish pop, Latin pop, vintage big band\nTurkish pop, Latin pop, world music\nTurkish pop, Latin salsa\nTurkish pop, Latin salsa, flamenco\nTurkish pop, Latin, Balkan\nTurkish pop, Latin, Cumbia\nTurkish pop, Latin, Eurodance\nTurkish pop, Latin, Middle Eastern\nTurkish pop, Latin, big band\nTurkish pop, Latin, cha-cha\nTurkish pop, Latin, cinematic\nTurkish pop, Latin, flamenco\nTurkish pop, Latin, merengue\nTurkish pop, Latin, psychedelic\nTurkish pop, Latin, salsa\nTurkish pop, Latin, tango\nTurkish pop, Latin, vintage\nTurkish pop, Latin, world music\nTurkish pop, Middle Eastern ballad\nTurkish pop, Middle Eastern folk\nTurkish pop, Middle Eastern fusion\nTurkish pop, Middle Eastern fusion, pop-rock\nTurkish pop, Middle Eastern, Persian\nTurkish pop, Middle Eastern, cinematic\nTurkish pop, Middle Eastern, folk\nTurkish pop, Middle Eastern, psychedelic\nTurkish pop, R&B\nTurkish pop, R&B, deep house\nTurkish pop, R&B, early 2000s\nTurkish pop, R&B, funk\nTurkish pop, R&B, lo-fi\nTurkish pop, R&B, reggaeton\nTurkish pop, R&B, synth-pop\nTurkish pop, R&B, trap\nTurkish pop, Russian dance-pop\nTurkish pop, Russian estrada, dance\nTurkish pop, Russian folk, electronic\nTurkish pop, Russian pop\nTurkish pop, Sufi music, world music\nTurkish pop, Turkish disco\nTurkish pop, Turkish hip-hop\nTurkish pop, afrobeat, dancehall\nTurkish pop, ambient\nTurkish pop, arabesque\nTurkish pop, arabesque, 80s pop\nTurkish pop, arabesque, Latin pop\nTurkish pop, arabesque, Middle Eastern\nTurkish pop, arabesque, belly dance\nTurkish pop, arabesque, chiptune\nTurkish pop, arabesque, cinematic\nTurkish pop, arabesque, cinematic ambient\nTurkish pop, arabesque, cinematic ballad\nTurkish pop, arabesque, cinematic folk\nTurkish pop, arabesque, cinematic fusion\nTurkish pop, arabesque, cinematic pop\nTurkish pop, arabesque, cinematic rock\nTurkish pop, arabesque, cinematic trap\nTurkish pop, arabesque, dance\nTurkish pop, arabesque, dance pop\nTurkish pop, arabesque, dance rock\nTurkish pop, arabesque, dance-pop\nTurkish pop, arabesque, electronic\nTurkish pop, arabesque, electronic dance\nTurkish pop, arabesque, flamenco\nTurkish pop, arabesque, flamenco fusion\nTurkish pop, arabesque, ney flute\nTurkish pop, arabesque, orchestral\nTurkish pop, arabesque, pop-rock\nTurkish pop, arabesque, pop-trap\nTurkish pop, arabesque, power ballad\nTurkish pop, arabesque, synthwave\nTurkish pop, arabesque, trap\nTurkish pop, arabesque, trap-pop\nTurkish pop, arabesque, world fusion\nTurkish pop, ballad, rock\nTurkish pop, ballad, soulful\nTurkish pop, baroque-pop, cinematic\nTurkish pop, belly dance\nTurkish pop, belly house\nTurkish pop, big band funk, ska\nTurkish pop, big band jazz\nTurkish pop, big band swing\nTurkish pop, big band, Latin\nTurkish pop, big band, cinematic\nTurkish pop, big band, retro\nTurkish pop, big band, swing\nTurkish pop, big band, theatrical\nTurkish pop, big band, vintage\nTurkish pop, big-band, cinematic\nTurkish pop, big-band, theatrical\nTurkish pop, breakbeat hip-hop\nTurkish pop, breakbeat, dramatic\nTurkish pop, breakbeat, electronic dance\nTurkish pop, chiptune\nTurkish pop, chiptune, arabesque\nTurkish pop, chiptune, dance pop\nTurkish pop, chiptune, electronic\nTurkish pop, chiptune, electropop\nTurkish pop, chiptune, lo-fi\nTurkish pop, chiptune, melancholic\nTurkish pop, chiptune, synthwave\nTurkish pop, chiptune, trap\nTurkish pop, chiptune, world music\nTurkish pop, cinematic ballad\nTurkish pop, cinematic electronic\nTurkish pop, cinematic orchestral\nTurkish pop, cinematic pop\nTurkish pop, cinematic pop, arabesque\nTurkish pop, cinematic tango\nTurkish pop, cinematic trap\nTurkish pop, cinematic, 70s\nTurkish pop, cinematic, Arabesque\nTurkish pop, cinematic, Eurodance\nTurkish pop, cinematic, Middle Eastern\nTurkish pop, cinematic, Middle Eastern fusion\nTurkish pop, cinematic, action score\nTurkish pop, cinematic, ambient\nTurkish pop, cinematic, arabesque\nTurkish pop, cinematic, ballad\nTurkish pop, cinematic, classical\nTurkish pop, cinematic, electronic\nTurkish pop, cinematic, epic\nTurkish pop, cinematic, flamenco\nTurkish pop, cinematic, folkloric\nTurkish pop, cinematic, hip-hop\nTurkish pop, cinematic, lo-fi\nTurkish pop, cinematic, melancholic\nTurkish pop, cinematic, ney\nTurkish pop, cinematic, noir\nTurkish pop, cinematic, operatic\nTurkish pop, cinematic, orchestral\nTurkish pop, cinematic, retro pop\nTurkish pop, cinematic, rock\nTurkish pop, cinematic, tango\nTurkish pop, cinematic, trap\nTurkish pop, cinematic, world fusion\nTurkish pop, cloud rap\nTurkish pop, cumbia\nTurkish pop, cumbia, Latin pop\nTurkish pop, cumbia, funk\nTurkish pop, cumbia, theatrical\nTurkish pop, dance\nTurkish pop, dance pop\nTurkish pop, dance, electronic\nTurkish pop, dance, hip-hop\nTurkish pop, dance, ney flute\nTurkish pop, dance-pop\nTurkish pop, dance-pop, oriental\nTurkish pop, dance-pop, reggaeton\nTurkish pop, dancehall, reggaeton\nTurkish pop, dark trap, rock\nTurkish pop, deep house, R&B\nTurkish pop, deep house, ambient\nTurkish pop, dembow, Middle Eastern\nTurkish pop, dembow, electronic\nTurkish pop, dembow, oriental\nTurkish pop, dramatic pop-rap\nTurkish pop, electronic dance\nTurkish pop, electronic dance music\nTurkish pop, electronic dance, Middle Eastern\nTurkish pop, electronic dance, Middle Eastern fusion\nTurkish pop, electronic dance, arabesque\nTurkish pop, electronic dance, chiptune\nTurkish pop, electronic dance, cinematic\nTurkish pop, electronic dance, dancehall\nTurkish pop, electronic dance, folk fusion\nTurkish pop, electronic dance, folk-fusion\nTurkish pop, electronic dance, fusion\nTurkish pop, electronic dance, hip-hop\nTurkish pop, electronic dance, hyperpop\nTurkish pop, electronic dance, jazz fusion\nTurkish pop, electronic dance, oriental\nTurkish pop, electronic dance, oriental synth\nTurkish pop, electronic dance, rock\nTurkish pop, electronic dance-pop\nTurkish pop, electronic fusion\nTurkish pop, electronic, Anatolian\nTurkish pop, electronic, Middle Eastern\nTurkish pop, electronic, arabesque\nTurkish pop, electronic, chiptune\nTurkish pop, electronic, cinematic\nTurkish pop, electronic, dance\nTurkish pop, electronic, dramatic\nTurkish pop, electronic, epic\nTurkish pop, electronic, folk fusion\nTurkish pop, electronic, fusion\nTurkish pop, electronic, hip-hop\nTurkish pop, electronic, oriental\nTurkish pop, electronic, trance\nTurkish pop, electronic, trap\nTurkish pop, electronic, world music\nTurkish pop, ethno-funk, rock\nTurkish pop, ethno-pop\nTurkish pop, ethno-pop, belly dance\nTurkish pop, ethno-pop, dance\nTurkish pop, ethno-pop, oriental\nTurkish pop, flamenco pop\nTurkish pop, flamenco rock\nTurkish pop, flamenco, Latin\nTurkish pop, flamenco, Latin pop\nTurkish pop, flamenco, Mediterranean\nTurkish pop, flamenco, acoustic\nTurkish pop, flamenco, arabesque\nTurkish pop, flamenco, ballad\nTurkish pop, flamenco, classical\nTurkish pop, flamenco, melancholic\nTurkish pop, flamenco, tango\nTurkish pop, folk dance, electronic\nTurkish pop, folk fusion\nTurkish pop, folk pop\nTurkish pop, folk, arabesque\nTurkish pop, folk, classical\nTurkish pop, folk, dance\nTurkish pop, funk, Middle Eastern\nTurkish pop, funk, acid jazz\nTurkish pop, funk, arabesque\nTurkish pop, funk, disco\nTurkish pop, funk, hip hop\nTurkish pop, funk, novelty\nTurkish pop, funk, pop-funk\nTurkish pop, funk, retro\nTurkish pop, funk-pop, ballad\nTurkish pop, future bass, dance-pop\nTurkish pop, hard rock\nTurkish pop, heavy rock\nTurkish pop, hip-hop\nTurkish pop, hip-hop, Middle Eastern\nTurkish pop, hip-hop, arabesque\nTurkish pop, hip-hop, cinematic\nTurkish pop, hip-hop, classical\nTurkish pop, hip-hop, electronic\nTurkish pop, hip-hop, soul\nTurkish pop, hip-hop, trap\nTurkish pop, hip-hop, world fusion\nTurkish pop, hyperpop\nTurkish pop, jazz lounge\nTurkish pop, jazz, Bossa Nova\nTurkish pop, jazz, lounge\nTurkish pop, jazz, soul\nTurkish pop, lo-fi hip hop\nTurkish pop, lo-fi hip hop, ballad\nTurkish pop, lo-fi hip hop, melancholic\nTurkish pop, lo-fi, cinematic\nTurkish pop, lo-fi, dance\nTurkish pop, lounge jazz\nTurkish pop, melancholic pop, cinematic pop\nTurkish pop, melancholic, trap\nTurkish pop, modern trap\nTurkish pop, modern trap, cinematic\nTurkish pop, new age\nTurkish pop, new jack swing\nTurkish pop, new jack swing, chiptune\nTurkish pop, new jack swing, funk\nTurkish pop, nu-disco, world music\nTurkish pop, orchestral hip-hop\nTurkish pop, orchestral, anthemic\nTurkish pop, orchestral, arabesque\nTurkish pop, oriental pop\nTurkish pop, oriental, belly dance\nTurkish pop, oriental, electronic\nTurkish pop, pop-dance\nTurkish pop, pop-rock\nTurkish pop, pop-rock, funk\nTurkish pop, pop-rock, rap fusion\nTurkish pop, pop-rock, world music\nTurkish pop, pop-trap\nTurkish pop, progressive house\nTurkish pop, psychedelic pop\nTurkish pop, psychedelic pop, Anatolian rock\nTurkish pop, psychedelic rock\nTurkish pop, psychedelic rock, Anatolian rock\nTurkish pop, psychedelic rock, cinematic\nTurkish pop, psychedelic rock, progressive rock\nTurkish pop, psychedelic, Anatolian rock\nTurkish pop, psychedelic, Middle Eastern\nTurkish pop, psychedelic, arabesque\nTurkish pop, quirky pop\nTurkish pop, reggaeton\nTurkish pop, reggaeton, Balkan pop\nTurkish pop, reggaeton, Latin pop\nTurkish pop, reggaeton, Middle Eastern\nTurkish pop, reggaeton, Middle Eastern fusion\nTurkish pop, reggaeton, afrobeat\nTurkish pop, reggaeton, chiptune\nTurkish pop, reggaeton, cinematic\nTurkish pop, reggaeton, dancehall\nTurkish pop, reggaeton, dembow\nTurkish pop, reggaeton, dramatic\nTurkish pop, reggaeton, electronic\nTurkish pop, reggaeton, flamenco\nTurkish pop, reggaeton, lo-fi\nTurkish pop, reggaeton, melancholic\nTurkish pop, reggaeton, moombahton\nTurkish pop, reggaeton, oriental\nTurkish pop, reggaeton, synthwave\nTurkish pop, retro dance\nTurkish pop, retro electronic\nTurkish pop, retro funk, disco\nTurkish pop, retro surf-rock\nTurkish pop, retro swing\nTurkish pop, retro synth, chiptune\nTurkish pop, retro synth, video game music\nTurkish pop, retro video game\nTurkish pop, retro, big-band\nTurkish pop, retro, chiptune\nTurkish pop, retro, psychedelic\nTurkish pop, retro, surf rock\nTurkish pop, retro, surf-rock\nTurkish pop, retro-funk, G-funk\nTurkish pop, retro-funk, breakbeat\nTurkish pop, retro-funk, disco\nTurkish pop, retro-funk, new jack swing\nTurkish pop, retro-futuristic, funk\nTurkish pop, rock, electronic\nTurkish pop, salsa, Latin brass\nTurkish pop, smooth jazz, trip-hop\nTurkish pop, soft Latin ballad\nTurkish pop, soft rock\nTurkish pop, stadium rock\nTurkish pop, stadium rock, EDM\nTurkish pop, surf rock\nTurkish pop, surf rock, exotica\nTurkish pop, surf rock, vintage pop\nTurkish pop, symphonic rock\nTurkish pop, synth-pop\nTurkish pop, synth-pop, Anatolian rock\nTurkish pop, synth-pop, Italo-disco\nTurkish pop, synth-pop, arabesque\nTurkish pop, synth-pop, disco\nTurkish pop, synth-pop, disco-funk\nTurkish pop, synth-pop, dramatic pop\nTurkish pop, synth-pop, eurodance\nTurkish pop, synth-pop, new wave\nTurkish pop, synth-pop, pop-rock\nTurkish pop, synth-pop, rock\nTurkish pop, tango, Latin\nTurkish pop, tango, jazz\nTurkish pop, tango, psychedelic rock\nTurkish pop, theatrical pop\nTurkish pop, trap\nTurkish pop, trap, EDM\nTurkish pop, trap, Middle Eastern\nTurkish pop, trap, Middle Eastern fusion\nTurkish pop, trap, R&B\nTurkish pop, trap, ambient\nTurkish pop, trap, arabesque\nTurkish pop, trap, atmospheric\nTurkish pop, trap, blues-rock\nTurkish pop, trap, chiptune\nTurkish pop, trap, cinematic\nTurkish pop, trap, electronic\nTurkish pop, trap, emotional\nTurkish pop, trap, future bass\nTurkish pop, trap, hip-hop\nTurkish pop, trap, lo-fi\nTurkish pop, trap, melancholic\nTurkish pop, trap, microtonal\nTurkish pop, trap, ney flute\nTurkish pop, trap, reggaeton\nTurkish pop, trap, vaporwave\nTurkish pop, trap-pop\nTurkish pop, trap-pop, German rap\nTurkish pop, trip-hop\nTurkish pop, trip-hop, breakbeat\nTurkish pop, trip-hop, cinematic\nTurkish pop, world fusion\nTurkish pop, world music\nTurkish pop, world music, cinematic\nTurkish pop, world music, cinematic orchestral\nTurkish pop, world music, cinematic trap\nTurkish pop, world music, electronic\nTurkish pop, world music, funk\nTurkish pop, world music, fusion\nTurkish pop, world music, oud\nTurkish pop, world music, psychedelic\nTurkish pop, world music, soft rock\nTurkish pop, worldbeat, electronic\nTurkish pop, worldbeat, synth-pop\nTurkish pop-R&B\nTurkish pop-arabesque\nTurkish pop-ballad\nTurkish pop-dance\nTurkish pop-folk\nTurkish pop-folk chiptune\nTurkish pop-folk, Latin pop\nTurkish pop-funk\nTurkish pop-jazz\nTurkish pop-rap\nTurkish pop-rap German rap\nTurkish pop-rap chiptune\nTurkish pop-rap, dark R&B, trap\nTurkish pop-reggae\nTurkish pop-reggaeton\nTurkish pop-rock\nTurkish pop-rock 80s\nTurkish pop-rock Anatolian rock\nTurkish pop-rock arabesque\nTurkish pop-rock chiptune\nTurkish pop-rock flamenco\nTurkish pop-rock funk\nTurkish pop-rock funk disco\nTurkish pop-rock funk-rock\nTurkish pop-rock nu-metal\nTurkish pop-rock progressive jazz\nTurkish pop-rock progressive metal\nTurkish pop-rock reggae\nTurkish pop-rock surf rock\nTurkish pop-rock tango\nTurkish pop-rock world music\nTurkish pop-rock, 80s synth, cinematic\nTurkish pop-rock, Balkan brass\nTurkish pop-rock, Balkan folk\nTurkish pop-rock, Balkan, tango\nTurkish pop-rock, Eurodance\nTurkish pop-rock, J-rock\nTurkish pop-rock, Latin pop, cumbia\nTurkish pop-rock, Latin rhythms\nTurkish pop-rock, Latin, salsa\nTurkish pop-rock, Middle Eastern folk\nTurkish pop-rock, Middle Eastern fusion\nTurkish pop-rock, arabesque, cinematic\nTurkish pop-rock, big band jazz\nTurkish pop-rock, big band swing\nTurkish pop-rock, chiptune\nTurkish pop-rock, chiptune, video game music\nTurkish pop-rock, cinematic, orchestral\nTurkish pop-rock, electronic dance\nTurkish pop-rock, electronic dance music\nTurkish pop-rock, electronic dance, cinematic\nTurkish pop-rock, electronic, cinematic\nTurkish pop-rock, hard rock\nTurkish pop-rock, hardstyle\nTurkish pop-rock, hip-hop\nTurkish pop-rock, lo-fi hip hop\nTurkish pop-rock, progressive house\nTurkish pop-rock, progressive, world music\nTurkish pop-rock, psychedelic rock\nTurkish pop-rock, psychedelic, cinematic\nTurkish pop-rock, smooth jazz\nTurkish pop-rock, surf rock\nTurkish pop-rock, surf rock, chiptune\nTurkish pop-rock, symphonic metal\nTurkish pop-rock, symphonic rock\nTurkish pop-rock, synth-pop, new age\nTurkish pop-rock, trip-hop, industrial\nTurkish pop-rock, world music\nTurkish pop-trap\nTurkish post-punk\nTurkish power ballad\nTurkish progressive rock\nTurkish protest\nTurkish protest folk\nTurkish protest funk\nTurkish protest music\nTurkish protest rap\nTurkish protest rock\nTurkish protest-pop\nTurkish psychedelic folk\nTurkish psychedelic folk-rock\nTurkish psychedelic funk\nTurkish psychedelic pop\nTurkish psychedelic rock\nTurkish psytrance\nTurkish punk rock\nTurkish rap\nTurkish rap, cinematic synth-pop\nTurkish rap, cinematic trap\nTurkish rap, cinematic trap, electronic\nTurkish rap, hardstyle trap\nTurkish rap-rock\nTurkish reggae\nTurkish reggae-pop\nTurkish reggaeton\nTurkish revolutionary\nTurkish revolutionary folk\nTurkish revolutionary march\nTurkish rock\nTurkish rock and roll\nTurkish rock ballad\nTurkish rock blues\nTurkish rock chiptune\nTurkish rock electronic\nTurkish rock opera\nTurkish rock surf-rock\nTurkish rock, Balkan folk\nTurkish rock, Balkan folk, theatrical rock\nTurkish rock, Latin rock, mambo\nTurkish rock, Middle Eastern folk\nTurkish rock, Middle Eastern fusion\nTurkish rock, arabesque, cinematic rock\nTurkish rock, electronic, folk\nTurkish rock, hip-hop, flamenco rock\nTurkish rock, industrial rock, electronic rock\nTurkish rock, nu-metal, industrial\nTurkish rock, spiritual chant\nTurkish rock, symphonic metal\nTurkish rumba\nTurkish sad pop\nTurkish saz\nTurkish saz, Eurodance, trance\nTurkish ska-reggae\nTurkish soul\nTurkish soul funk\nTurkish soul, trap R&B\nTurkish soul-pop\nTurkish spiritual\nTurkish spiritual music\nTurkish spiritual pop\nTurkish spiritual rock\nTurkish sports anthem\nTurkish storytelling rap\nTurkish surf-rock\nTurkish swing\nTurkish swing jazz\nTurkish swing-folk\nTurkish synth-pop\nTurkish tango\nTurkish tango arabesque\nTurkish tech house\nTurkish tech-house\nTurkish techno\nTurkish theater\nTurkish traditional\nTurkish trance\nTurkish trance-pop\nTurkish trap\nTurkish trap R&B\nTurkish trap arabesque\nTurkish trap chiptune\nTurkish trap dream pop\nTurkish trap drill\nTurkish trap metal\nTurkish trap reggaeton\nTurkish trap rock\nTurkish trap, UK drill, cinematic\nTurkish trap, Western hip-hop\nTurkish trap, alternative R&B\nTurkish trap, arabesque\nTurkish trap, chiptune\nTurkish trap, cinematic drill\nTurkish trap, cinematic rock\nTurkish trap, cinematic synth, chiptune\nTurkish trap, cinematic, dark trap\nTurkish trap, cloud rap\nTurkish trap, cloud rap, vaporwave\nTurkish trap, dark pop\nTurkish trap, drill, cinematic\nTurkish trap, electronic dance\nTurkish trap, emo rap\nTurkish trap, emo rap, pop\nTurkish trap, emo rap, synth-pop\nTurkish trap, emo-rap\nTurkish trap, emotional pop\nTurkish trap, gangsta rap, drill\nTurkish trap, hard dance\nTurkish trap, horrorcore\nTurkish trap, hyperpop, chiptune\nTurkish trap, lo-fi hip hop\nTurkish trap, reggaeton\nTurkish trap, sad trap, emotional R&B\nTurkish trap-R&B\nTurkish trap-metal\nTurkish trap-pop\nTurkish trap-rock\nTurkish trap-soul\nTurkish wedding dance\nTurkish wedding music\nTurkish world music\nTurkish zaffa\nTürkü, world music\nTết pop\nTết pop, retro electronic\nUK Afro-Drill\nUK Afro-swing\nUK Afro-swing lo-fi\nUK Afrobeats\nUK Afroswing\nUK Afroswing classical fusion\nUK Afroswing lo-fi\nUK Christian hip-hop\nUK Dancehall\nUK Garage\nUK Hardcore\nUK Hardcore Chiptune\nUK Hardcore Trancecore\nUK Hardcore, Hardcore House\nUK Hardcore, Hardcore Trance\nUK Hardcore, Hardstyle, Gabber\nUK Hardcore, J-Core\nUK Hardcore, Trance, Trap\nUK Hardcore, complextro\nUK Hardcore, pop\nUK Hardcore, pop-punk\nUK R&B\nUK R&B dancehall\nUK R&B drill\nUK R&B hip-hop\nUK R&B lo-fi\nUK R&B lo-fi hip hop\nUK R&B trap\nUK R&B trap-soul\nUK R&B, UK drill, lo-fi\nUK R&B, hip-hop\nUK R&B, hip-hop, atmospheric\nUK R&B, hip-hop, trap\nUK R&B, lo-fi, trap\nUK R&B, trap, atmospheric\nUK R&B, trap, hip-hop\nUK R&B, trap, melancholic\nUK alternative R&B\nUK bass\nUK bass grime\nUK bass house\nUK battle rap\nUK boom-bap\nUK cloud rap\nUK cloud rap, UK drill\nUK cloud rap, lo-fi hip-hop\nUK conscious hip-hop\nUK drill\nUK drill Afro-Drill\nUK drill Afro-swing\nUK drill Afrobeats\nUK drill French drill\nUK drill German drill\nUK drill German rap\nUK drill Indian pop\nUK drill Latin drill\nUK drill Latin trap\nUK drill Polish drill\nUK drill Portuguese drill\nUK drill Punjabi pop\nUK drill R&B\nUK drill Turkish drill\nUK drill afro-swing\nUK drill ambient\nUK drill chiptune\nUK drill dance-pop\nUK drill dancehall\nUK drill drillhall\nUK drill gospel\nUK drill grime\nUK drill grime, synth-pop\nUK drill hardstyle\nUK drill house\nUK drill hyperpop\nUK drill lo-fi\nUK drill lo-fi hip hop\nUK drill orchestral\nUK drill trap\nUK drill trap-R&B\nUK drill trap-pop\nUK drill vaporwave\nUK drill, Afro-Caribbean, lo-fi\nUK drill, Afro-Swahili\nUK drill, Afro-fusion\nUK drill, Afro-swing\nUK drill, Afrobeats, R&B\nUK drill, Afroswing\nUK drill, Ancient Style\nUK drill, Australian drill\nUK drill, Balkan folk\nUK drill, Bhangra\nUK drill, Bollywood\nUK drill, Brazilian funk\nUK drill, Brazilian grime\nUK drill, Brazilian trap\nUK drill, C-pop\nUK drill, Celtic folk\nUK drill, Celtic fusion\nUK drill, Danish drill\nUK drill, Dutch drill\nUK drill, Eastern fusion\nUK drill, French drill\nUK drill, French rap\nUK drill, G-funk\nUK drill, German drill\nUK drill, German gangsta rap\nUK drill, German rap\nUK drill, Hindi pop\nUK drill, Indian classical\nUK drill, Italian pop\nUK drill, J-pop\nUK drill, K-hip-hop\nUK drill, Latin fusion\nUK drill, Latin hip hop\nUK drill, Latin pop\nUK drill, Latin samba\nUK drill, Latin trap\nUK drill, Latin-influenced\nUK drill, Latin-infused\nUK drill, Mandarin hip hop\nUK drill, Mandarin rap\nUK drill, Middle Eastern fusion\nUK drill, Middle Eastern synth\nUK drill, Middle Eastern, Eastern European\nUK drill, Nigerian Pidgin hip hop\nUK drill, North African trap\nUK drill, Punjabi folk\nUK drill, Punjabi fusion\nUK drill, Punjabi hip-hop\nUK drill, Punjabi pop\nUK drill, Punjabi pop, lo-fi hip hop\nUK drill, Punjabi trap\nUK drill, R&B\nUK drill, R&B, ambient\nUK drill, R&B, lo-fi hip hop\nUK drill, R&B, melodic rap\nUK drill, South Asian fusion\nUK drill, South Asian hip-hop\nUK drill, South Asian pop\nUK drill, Tamil fusion\nUK drill, UK rap\nUK drill, a cappella\nUK drill, acoustic\nUK drill, afro-swing\nUK drill, afro-swing, lo-fi\nUK drill, alternative R&B\nUK drill, ambient\nUK drill, ambient hip hop\nUK drill, ambient hip-hop\nUK drill, ambient pop\nUK drill, ambient soul\nUK drill, ambient synth\nUK drill, ambient trap\nUK drill, ambient, cinematic\nUK drill, ambient, indie-pop\nUK drill, anime pop\nUK drill, atmospheric hip-hop\nUK drill, baroque hip-hop\nUK drill, baroque pop\nUK drill, bass house\nUK drill, big band\nUK drill, boom-bap\nUK drill, chiptune\nUK drill, chiptune, R&B\nUK drill, chiptune, trap\nUK drill, chopped and screwed\nUK drill, cinematic\nUK drill, cinematic fusion\nUK drill, cinematic hip hop\nUK drill, cinematic hip-hop\nUK drill, cinematic lo-fi\nUK drill, cinematic orchestral\nUK drill, cinematic soul\nUK drill, cinematic synth\nUK drill, cinematic trap\nUK drill, cinematic, Scottish\nUK drill, cinematic, ambient\nUK drill, cinematic, lo-fi hip hop\nUK drill, cinematic, melancholic\nUK drill, cloud rap\nUK drill, cloud rap, pluggnb\nUK drill, conscious hip-hop\nUK drill, cyberpunk\nUK drill, dancehall\nUK drill, dancehall, jazz\nUK drill, dancehall, lo-fi hip hop\nUK drill, drill hip-hop\nUK drill, drill-pop\nUK drill, drillhall\nUK drill, drum and bass, neurofunk\nUK drill, dubstep\nUK drill, electronic\nUK drill, emo rap\nUK drill, emo-rap\nUK drill, emotional pop\nUK drill, ethereal pop\nUK drill, ethereal trap\nUK drill, flamenco\nUK drill, flamenco fusion\nUK drill, folk fusion\nUK drill, gangsta rap\nUK drill, gospel\nUK drill, gospel hip-hop\nUK drill, gospel, Balkan folk\nUK drill, grime\nUK drill, grime, R&B\nUK drill, grime, cinematic\nUK drill, grime, cinematic soul\nUK drill, grime, dubstep\nUK drill, grime, lo-fi hip hop\nUK drill, grime, orchestral\nUK drill, grime, soul\nUK drill, hard techno\nUK drill, hardstyle\nUK drill, hardstyle, electronic\nUK drill, hip hop\nUK drill, hip-hop\nUK drill, hyperpop\nUK drill, hyperpop, cinematic\nUK drill, industrial hip hop\nUK drill, jazz\nUK drill, jazz rap\nUK drill, jazzy soul\nUK drill, lo-fi\nUK drill, lo-fi R&B\nUK drill, lo-fi ambient\nUK drill, lo-fi cinematic\nUK drill, lo-fi classical\nUK drill, lo-fi flamenco\nUK drill, lo-fi hip hop\nUK drill, lo-fi hip hop, cinematic\nUK drill, lo-fi hip-hop\nUK drill, lo-fi jazz\nUK drill, lo-fi piano\nUK drill, lo-fi soul\nUK drill, lo-fi synth\nUK drill, lo-fi trap\nUK drill, lo-fi, Middle Eastern\nUK drill, lo-fi, R&B\nUK drill, lo-fi, ambient\nUK drill, lo-fi, cinematic\nUK drill, lo-fi, dancehall\nUK drill, lo-fi, melancholic\nUK drill, melodic R&B\nUK drill, melodic hip-hop\nUK drill, melodic rap\nUK drill, melodic trap\nUK drill, melodic trap, alternative R&B\nUK drill, modern R&B\nUK drill, mythological fusion\nUK drill, neurofunk\nUK drill, ney flute, mythic hip hop\nUK drill, old-school hip-hop\nUK drill, operatic hip hop\nUK drill, orchestral\nUK drill, orchestral hip hop\nUK drill, orchestral trap\nUK drill, party trap\nUK drill, pluggnb\nUK drill, pop\nUK drill, pop-R&B\nUK drill, pop-punk\nUK drill, psychedelic hip hop\nUK drill, reggae, ambient\nUK drill, reggaeton\nUK drill, soul\nUK drill, soul, gospel\nUK drill, soulful R&B\nUK drill, soulful hip hop\nUK drill, soulful pop\nUK drill, soulful rap\nUK drill, spoken word\nUK drill, synthwave\nUK drill, trap\nUK drill, trap R&B\nUK drill, trap metal\nUK drill, trap metal, phonk\nUK drill, trap soul\nUK drill, trap, C-pop\nUK drill, trap, Chinese hip hop\nUK drill, trap, Eastern fusion\nUK drill, trap, Indian classical\nUK drill, trap, Latin hip hop\nUK drill, trap, R&B\nUK drill, trap, South Asian fusion\nUK drill, trap, acoustic\nUK drill, trap, alternative rock\nUK drill, trap, ambient\nUK drill, trap, boom-bap\nUK drill, trap, chiptune\nUK drill, trap, cinematic\nUK drill, trap, cinematic synth\nUK drill, trap, dream pop\nUK drill, trap, electronic\nUK drill, trap, emotional pop\nUK drill, trap, ethereal\nUK drill, trap, ethereal pop\nUK drill, trap, experimental\nUK drill, trap, gospel\nUK drill, trap, hardstyle\nUK drill, trap, jazz\nUK drill, trap, lo-fi\nUK drill, trap, lo-fi fusion\nUK drill, trap, lo-fi hip hop\nUK drill, trap, lo-fi soul\nUK drill, trap, melodic rap\nUK drill, trap, pop-R&B\nUK drill, trap, pop-rap\nUK drill, trap, psychedelic\nUK drill, trap, sitar loop\nUK drill, trap, vaporwave\nUK drill, vaporwave\nUK drill, vaporwave, R&B\nUK drill, vaporwave, cloud rap\nUK drill, vaporwave, lo-fi hip hop\nUK drill, video game\nUK drill, world fusion\nUK drill, world music\nUK drill, world-trap, trap\nUK emo rap\nUK folk\nUK funk\nUK garage\nUK garage 2-step\nUK garage 2-step R&B\nUK garage Bhangra\nUK garage Punjabi Bhangra\nUK garage Punjabi pop\nUK garage R&B\nUK garage afro-swing\nUK garage ambient\nUK garage baile funk\nUK garage bass house\nUK garage bassline\nUK garage bassline house\nUK garage breakbeat\nUK garage chiptune\nUK garage dance-pop\nUK garage dancehall\nUK garage deep house\nUK garage drill\nUK garage drum and bass\nUK garage future bass\nUK garage future bass hip-hop\nUK garage future garage\nUK garage future garage lo-fi\nUK garage future garage trap\nUK garage grime\nUK garage grime dancehall\nUK garage grime hyperpop\nUK garage grime rave\nUK garage hardstyle\nUK garage hip hop\nUK garage hip-hop\nUK garage house\nUK garage hyperpop\nUK garage lo-fi\nUK garage lo-fi hip hop\nUK garage lo-fi hip-hop\nUK garage pop\nUK garage pop-R&B\nUK garage pop-dance\nUK garage pop-funk\nUK garage pop-rap\nUK garage soulful house\nUK garage synth-pop\nUK garage trap\nUK garage, 2-step\nUK garage, 2-step garage, R&B\nUK garage, 2-step house\nUK garage, 2-step, Bollywood electronica\nUK garage, 2-step, R&B\nUK garage, 2-step, ambient\nUK garage, 2-step, atmospheric\nUK garage, 2-step, atmospheric hip-hop\nUK garage, 2-step, breakbeat\nUK garage, 2-step, chiptune\nUK garage, 2-step, conscious hip-hop\nUK garage, 2-step, dream pop\nUK garage, 2-step, dreamy R&B\nUK garage, 2-step, dreamy pop\nUK garage, 2-step, dreamy synth\nUK garage, 2-step, electronic pop\nUK garage, 2-step, ethereal\nUK garage, 2-step, ethereal pop\nUK garage, 2-step, future garage\nUK garage, 2-step, grime\nUK garage, 2-step, indie electronic\nUK garage, 2-step, instrumental\nUK garage, 2-step, liquid funk\nUK garage, 2-step, lo-fi\nUK garage, 2-step, lo-fi hip-hop\nUK garage, 2-step, pop\nUK garage, 2-step, pop-rap\nUK garage, 2-step, pop/R&B\nUK garage, 2-step, soulful\nUK garage, 2-step, soulful R&B\nUK garage, 2-step, vaporwave\nUK garage, Bhangra\nUK garage, Bollywood\nUK garage, Bollywood pop\nUK garage, Eurodance\nUK garage, J-pop, synthwave\nUK garage, K-pop\nUK garage, K-pop, future bass\nUK garage, Punjabi pop\nUK garage, Punjabi pop, house\nUK garage, R&B\nUK garage, R&B, atmospheric\nUK garage, R&B, future garage\nUK garage, R&B, grime\nUK garage, R&B, lo-fi\nUK garage, R&B, soul\nUK garage, Russian pop, hip-hop\nUK garage, afro house, deep house\nUK garage, alternative R&B\nUK garage, ambient pop\nUK garage, ambient, experimental\nUK garage, bass house\nUK garage, bass house, electronic\nUK garage, bassline\nUK garage, bassline house\nUK garage, bassline, grime\nUK garage, breakbeat\nUK garage, breakbeat, art pop\nUK garage, breakbeat, chiptune\nUK garage, breakbeat, electronic\nUK garage, breakbeat, euphoric house\nUK garage, breakbeat, future bass\nUK garage, breakbeat, grime\nUK garage, breakbeat, hip-hop\nUK garage, breakbeat, lo-fi\nUK garage, breakbeat, synth-pop\nUK garage, breakbeat, synthwave\nUK garage, chill R&B\nUK garage, chiptune, R&B\nUK garage, cinematic, ambient\nUK garage, cinematic, synthwave\nUK garage, dance-pop\nUK garage, dance-pop, future bass\nUK garage, dancehall, breakbeat\nUK garage, deep house\nUK garage, deep house, 90s house\nUK garage, deep house, Afrobeats\nUK garage, deep house, R&B\nUK garage, deep house, ambient\nUK garage, deep house, dancehall\nUK garage, deep house, house\nUK garage, deep house, lo-fi\nUK garage, deep house, vaporwave\nUK garage, diva house, deep house\nUK garage, diva house, house\nUK garage, dream pop\nUK garage, dream pop, electronic\nUK garage, drum and bass\nUK garage, drum and bass, cinematic\nUK garage, early 2000s house\nUK garage, electro-pop\nUK garage, electronic pop\nUK garage, electronic, K-pop\nUK garage, ethereal pop\nUK garage, ethereal pop, K-pop\nUK garage, ethereal, pop\nUK garage, future bass\nUK garage, future bass, J-pop\nUK garage, future bass, K-pop\nUK garage, future bass, R&B\nUK garage, future bass, dance-pop\nUK garage, future bass, dream pop\nUK garage, future funk, house\nUK garage, future garage, ambient\nUK garage, future garage, liquid drum and bass\nUK garage, grime\nUK garage, grime, South Asian pop\nUK garage, grime, ambient\nUK garage, grime, breakbeat\nUK garage, grime, chiptune\nUK garage, grime, cinematic\nUK garage, grime, drill\nUK garage, grime, drum and bass\nUK garage, grime, experimental\nUK garage, grime, hip-hop\nUK garage, grime, neurofunk\nUK garage, grime, vaporwave\nUK garage, happy hardcore\nUK garage, happy hardcore, breakbeat\nUK garage, hard dance\nUK garage, hard house\nUK garage, hardstyle\nUK garage, hardstyle, electronic\nUK garage, hip hop, pop\nUK garage, hip hop, soul\nUK garage, hip-hop\nUK garage, hip-hop, R&B\nUK garage, hip-hop, cinematic soul\nUK garage, hip-house\nUK garage, house\nUK garage, hyperpop\nUK garage, hyperpop, UK drill\nUK garage, hyperpop, breakbeat\nUK garage, hyperpop, cinematic\nUK garage, hyperpop, future bass\nUK garage, hyperpop, lo-fi\nUK garage, indie pop\nUK garage, liquid drum and bass\nUK garage, lo-fi hip hop\nUK garage, lo-fi hip hop, ambient\nUK garage, lo-fi hip hop, experimental\nUK garage, lo-fi, emotional\nUK garage, moombahton\nUK garage, neurofunk\nUK garage, nightcore\nUK garage, pop ballad, 2-step\nUK garage, pop-R&B\nUK garage, pop-R&B, dream pop\nUK garage, progressive house\nUK garage, soul, chiptune\nUK garage, soul, gospel\nUK garage, soulful pop\nUK garage, soulful, atmospheric\nUK garage, synth-pop, K-pop\nUK garage, trap, cinematic\nUK garage, tropical house\nUK garage, vaporwave\nUK garage, vaporwave, 2-step\nUK garage, vaporwave, R&B\nUK garage, wobble house\nUK grime\nUK grime Punjabi Bhangra\nUK grime Punjabi folk\nUK grime Punjabi hip-hop\nUK grime chiptune\nUK grime classical fusion\nUK grime dancehall\nUK grime drill\nUK grime drum and bass\nUK grime dubstep\nUK grime future bass pop-R&B\nUK grime hardstyle\nUK grime hip-hop\nUK grime synth-pop R&B\nUK grime trap\nUK grime, G-funk, hip-hop\nUK grime, Punjabi folk\nUK grime, Punjabi pop\nUK grime, Punjabi pop, hip-hop\nUK grime, South Asian pop\nUK grime, UK hip-hop\nUK grime, chiptune\nUK grime, hip-hop, chiptune\nUK grime, neurofunk\nUK grime, neurofunk, dark ambient\nUK grime, trap, cinematic\nUK grime, world music, electronic\nUK hardcore\nUK hardcore chiptune\nUK hardcore trancecore\nUK hardcore, chiptune\nUK hardcore, drum and bass, chiptune\nUK hardcore, happy hardcore, children's music\nUK hip hop\nUK hip hop chiptune\nUK hip-hop\nUK hip-hop Afrobeats\nUK hip-hop Bollywood pop\nUK hip-hop G-funk\nUK hip-hop Indian classical\nUK hip-hop Islamic devotional\nUK hip-hop Punjabi fusion\nUK hip-hop R&B\nUK hip-hop alternative R&B\nUK hip-hop alternative rock\nUK hip-hop alternative rock chiptune\nUK hip-hop boom-bap\nUK hip-hop chiptune\nUK hip-hop chiptune funk\nUK hip-hop chiptune funk-rock\nUK hip-hop cinematic\nUK hip-hop dancehall\nUK hip-hop deep house\nUK hip-hop dream pop\nUK hip-hop electronic\nUK hip-hop experimental\nUK hip-hop funk\nUK hip-hop funk soul\nUK hip-hop future bass\nUK hip-hop grime\nUK hip-hop grime hyperpop\nUK hip-hop hyperpop\nUK hip-hop lo-fi\nUK hip-hop neo-soul\nUK hip-hop nu-metal\nUK hip-hop pop\nUK hip-hop pop-R&B\nUK hip-hop pop-funk\nUK hip-hop pop-rap\nUK hip-hop pop-rock\nUK hip-hop rock\nUK hip-hop soul\nUK hip-hop trap\nUK hip-hop vaporwave\nUK hip-hop, Christmas trap\nUK hip-hop, Punjabi pop, Bhangra\nUK hip-hop, Punjabi, cinematic\nUK hip-hop, R&B\nUK hip-hop, R&B, chiptune\nUK hip-hop, R&B, cinematic\nUK hip-hop, R&B, neo-soul\nUK hip-hop, South Asian fusion\nUK hip-hop, South Asian pop\nUK hip-hop, afro-swing\nUK hip-hop, alternative R&B\nUK hip-hop, alternative R&B, emo rap\nUK hip-hop, alternative R&B, lo-fi\nUK hip-hop, alternative R&B, trap\nUK hip-hop, alternative rock\nUK hip-hop, alternative rock, ambient\nUK hip-hop, ambient, cinematic\nUK hip-hop, ambient, electronic\nUK hip-hop, big band, trap\nUK hip-hop, boom-bap, lo-fi\nUK hip-hop, chiptune\nUK hip-hop, chiptune, Christian rap\nUK hip-hop, chiptune, lo-fi\nUK hip-hop, cinematic\nUK hip-hop, cinematic soul\nUK hip-hop, cinematic synth, soulful R&B\nUK hip-hop, cinematic, atmospheric\nUK hip-hop, cinematic, grime\nUK hip-hop, cinematic, lo-fi\nUK hip-hop, cloud rap\nUK hip-hop, conscious rap, vaporwave\nUK hip-hop, contemporary R&B\nUK hip-hop, cyberpunk, trap\nUK hip-hop, dream-pop\nUK hip-hop, dreamy trap\nUK hip-hop, drill, R&B\nUK hip-hop, drill, lo-fi\nUK hip-hop, dubstep, cinematic\nUK hip-hop, electronic rock\nUK hip-hop, emotional R&B\nUK hip-hop, emotional pop\nUK hip-hop, ethereal R&B\nUK hip-hop, experimental, art rap\nUK hip-hop, grime, ambient\nUK hip-hop, grime, chiptune\nUK hip-hop, grime, experimental\nUK hip-hop, hard rock\nUK hip-hop, lo-fi soul\nUK hip-hop, lo-fi, cinematic\nUK hip-hop, lo-fi, soul\nUK hip-hop, melodic R&B\nUK hip-hop, neurofunk, dubstep\nUK hip-hop, new jack swing\nUK hip-hop, orchestral, grime\nUK hip-hop, pop-R&B\nUK hip-hop, pop-punk, cinematic\nUK hip-hop, pop-rock\nUK hip-hop, psychedelic soul\nUK hip-hop, rock, jazz\nUK hip-hop, soul, flamenco\nUK hip-hop, soulful R&B, cinematic\nUK hip-hop, synth pop\nUK hip-hop, synth-pop\nUK hip-hop, synth-pop, chiptune\nUK hip-hop, trap\nUK hip-hop, trap, chiptune\nUK hip-hop, trap, cinematic\nUK hip-hop, trap, dubstep\nUK hip-hop, trap, festive\nUK hip-hop, trap, melancholic\nUK hip-hop, trap, orchestral\nUK hip-hop, trap-soul\nUK house\nUK indie\nUK melodic rap\nUK melodic trap\nUK pop\nUK pop-rap\nUK rap\nUK rap chiptune\nUK rap soul\nUK rap, Caribbean hip-hop, sunny synth\nUK rap, Punjabi pop\nUK rap, lo-fi, trap\nUK rap, soul, lo-fi hip hop\nUK rave\nUK spoken word\nUK trap\nUK trap R&B\nUK trap drill\nUkrainian Christmas\nUkrainian R&B\nUkrainian dance-pop\nUkrainian drill\nUkrainian estrada\nUkrainian estrada pop\nUkrainian folk\nUkrainian folk EDM\nUkrainian folk chiptune\nUkrainian folk dance-pop\nUkrainian folk hip-hop\nUkrainian folk jazz\nUkrainian folk pop\nUkrainian folk pop-rock\nUkrainian folk rock\nUkrainian folk ska-polka\nUkrainian folk trap\nUkrainian folk trip-hop\nUkrainian folk, Eurodance\nUkrainian folk, Eurodance, dance-pop\nUkrainian folk, Eurodance, electronic\nUkrainian folk, big beat\nUkrainian folk, chiptune\nUkrainian folk, chiptune, dance-pop\nUkrainian folk, chiptune, electro-pop\nUkrainian folk, dance-pop\nUkrainian folk, electronic dance\nUkrainian folk, electronic dance, dance-pop\nUkrainian folk, electronic dance, techno\nUkrainian folk, electronic pop\nUkrainian folk, electronic, anthemic\nUkrainian folk, turbo-folk\nUkrainian folk-pop\nUkrainian folk-pop chiptune\nUkrainian folk-pop, Eurodance\nUkrainian folk-pop, dance\nUkrainian folk-pop, synth-rock\nUkrainian folk-rock\nUkrainian folk-trap\nUkrainian hip-hop\nUkrainian hip-hop trap\nUkrainian house\nUkrainian pop\nUkrainian pop reggaeton\nUkrainian pop trap\nUkrainian pop, Eurodance\nUkrainian pop, R&B, trap\nUkrainian pop, dancehall, reggaeton\nUkrainian pop, estrada, synth folk\nUkrainian pop, retro disco, funk\nUkrainian pop, trap, R&B\nUkrainian pop, trap, atmospheric\nUkrainian pop, trap, hip-hop\nUkrainian pop, trap, pop\nUkrainian pop-R&B\nUkrainian pop-dance\nUkrainian pop-folk\nUkrainian pop-rap\nUkrainian pop-rock\nUkrainian pop-trap\nUkrainian rap, trap, phonk\nUkrainian trap\nUkrainian trap-pop\nUrdu spoken word\nUyghur dance-pop\nUyghur folk\nUyghur folk dance\nUyghur folk-pop\nUyghur hip-hop\nUyghur pop\nUyghur pop reggaeton\nUyghur pop, dancehall, reggaeton\nUyghur pop-rap\nUyghur pop-rock\nUyghur trap\nUzbek Eurodance\nUzbek dance-pop\nUzbek estrada\nUzbek folk\nUzbek folk-pop\nUzbek hip-hop\nUzbek pop\nUzbek pop Eurodance\nUzbek pop Latin\nUzbek pop Latin dance\nUzbek pop R&B\nUzbek pop dance-pop\nUzbek pop reggaeton\nUzbek pop, Eurodance\nUzbek pop, Eurodance, EDM\nUzbek pop, Eurodance, Latin\nUzbek pop, Eurodance, Latin pop\nUzbek pop, Eurodance, Middle Eastern\nUzbek pop, Eurodance, chiptune\nUzbek pop, Eurodance, folk\nUzbek pop, Eurodance, folk dance\nUzbek pop, Eurodance, funk\nUzbek pop, Eurodance, happy hardcore\nUzbek pop, Eurodance, moombahton\nUzbek pop, Eurodance, reggaeton\nUzbek pop, Eurodance, synth-pop\nUzbek pop, Eurodance, trance\nUzbek pop, Latin dance\nUzbek pop, Latin dance, folk-pop\nUzbek pop, Latin dance, reggaeton\nUzbek pop, Latin pop, Eurodance\nUzbek pop, R&B\nUzbek pop, chiptune, folk\nUzbek pop, cinematic, trap\nUzbek pop, cumbia, Latin pop\nUzbek pop, dance-pop\nUzbek pop, dancehall, reggaeton\nUzbek pop, electronic\nUzbek pop, electronic dance\nUzbek pop, electronic dance, oriental\nUzbek pop, electronic dance, traditional fusion\nUzbek pop, estrada\nUzbek pop, oriental rock\nUzbek pop, reggaeton\nUzbek pop, reggaeton, Latin pop\nUzbek pop, reggaeton, dancehall\nUzbek pop, reggaeton, moombahton\nUzbek pop-R&B\nUzbek pop-dance\nUzbek pop-folk\nUzbek pop-funk\nUzbek pop-rap\nUzbek pop-rock\nUzbek pop-trap\nUzbek rap\nV-Pop\nV-Pop Afrobeats Dancehall\nV-Pop Bossa Nova\nV-Pop Bossa Nova R&B\nV-Pop C-Pop hip-hop\nV-Pop Christmas\nV-Pop City Pop\nV-Pop EDM\nV-Pop EDM Latin house\nV-Pop EDM dance-pop\nV-Pop EDM hip-hop\nV-Pop EDM house\nV-Pop EDM trance\nV-Pop EDM trap\nV-Pop EDM-pop\nV-Pop EDM-trap\nV-Pop Eurodance\nV-Pop Eurodance Trance\nV-Pop Eurodance trance\nV-Pop J-Pop\nV-Pop J-Rock\nV-Pop J-pop\nV-Pop Latin\nV-Pop Latin Pop R&B\nV-Pop Latin ballad\nV-Pop Latin bolero\nV-Pop Latin dance\nV-Pop Latin dance-pop\nV-Pop Latin fusion\nV-Pop Latin jazz\nV-Pop Latin pop\nV-Pop R&B\nV-Pop R&B Latin\nV-Pop R&B city pop\nV-Pop R&B funk\nV-Pop R&B future bass\nV-Pop R&B hip-hop\nV-Pop R&B jazz\nV-Pop R&B lo-fi\nV-Pop R&B lo-fi hip-hop\nV-Pop R&B neo-soul\nV-Pop R&B orchestral\nV-Pop R&B soul\nV-Pop R&B trap\nV-Pop R&B trap-pop\nV-Pop V-Rap\nV-Pop Vinahouse\nV-Pop acoustic\nV-Pop acoustic ballad\nV-Pop anime soundtrack\nV-Pop ballad\nV-Pop ballad, Vietnamese folk cumbia\nV-Pop ballad, future bass, trap\nV-Pop ballad, lo-fi hip hop\nV-Pop ballad, smooth jazz\nV-Pop big band jazz\nV-Pop bolero\nV-Pop bossa nova\nV-Pop chill\nV-Pop chiptune\nV-Pop chiptune Eurodance\nV-Pop chiptune J-pop\nV-Pop chiptune R&B\nV-Pop chiptune synth-pop\nV-Pop cinematic\nV-Pop cinematic pop\nV-Pop city pop funk\nV-Pop city-pop\nV-Pop dance\nV-Pop dance-pop\nV-Pop dance-pop EDM\nV-Pop dance-pop hip-hop\nV-Pop dance-pop reggaeton\nV-Pop dance-pop tropical house\nV-Pop dancehall\nV-Pop deep house\nV-Pop dream pop\nV-Pop dream-pop\nV-Pop electro house\nV-Pop electro-pop\nV-Pop electro-pop chiptune\nV-Pop electro-swing chiptune\nV-Pop folk\nV-Pop folk pop\nV-Pop funk\nV-Pop funk R&B\nV-Pop funk disco\nV-Pop funk hip-hop\nV-Pop future bass\nV-Pop future bass EDM\nV-Pop future bass chiptune\nV-Pop future bass dream pop\nV-Pop future bass hip-hop\nV-Pop future bass trap\nV-Pop future bass trap-pop\nV-Pop future bass tropical house\nV-Pop hardstyle\nV-Pop hardstyle EDM\nV-Pop hip-hop\nV-Pop hip-hop Latin\nV-Pop hip-hop R&B\nV-Pop hip-hop ballad\nV-Pop hip-hop chiptune\nV-Pop hip-hop electronic\nV-Pop hip-hop tropical\nV-Pop hyperpop chiptune\nV-Pop indie pop city pop\nV-Pop inspirational pop\nV-Pop jazz\nV-Pop jazz R&B\nV-Pop jazz ballad\nV-Pop jazz lounge\nV-Pop jazz soul\nV-Pop jazz-pop\nV-Pop jazz-pop bossa nova\nV-Pop lo-fi\nV-Pop lo-fi R&B\nV-Pop lo-fi chiptune\nV-Pop lo-fi city pop\nV-Pop lo-fi hip hop\nV-Pop lo-fi hip-hop\nV-Pop lo-fi hip-hop R&B\nV-Pop lo-fi hip-hop chiptune\nV-Pop lo-fi hip-hop neo-soul\nV-Pop lo-fi hip-hop trap\nV-Pop lo-fi pop\nV-Pop lo-fi trap-R&B\nV-Pop lo-fi trap-pop\nV-Pop lounge\nV-Pop lounge jazz\nV-Pop lounge-pop\nV-Pop neo-soul\nV-Pop neo-soul R&B\nV-Pop neo-soul city pop\nV-Pop nu-disco\nV-Pop nu-disco city pop\nV-Pop nu-disco funk\nV-Pop orchestral\nV-Pop power ballad\nV-Pop progressive house\nV-Pop rap\nV-Pop reggaeton\nV-Pop retro\nV-Pop rock\nV-Pop rock ballad\nV-Pop salsa\nV-Pop smooth jazz\nV-Pop smooth jazz R&B\nV-Pop smooth jazz funk\nV-Pop soul\nV-Pop soul folk\nV-Pop synth-funk\nV-Pop synth-pop\nV-Pop synth-pop R&B\nV-Pop synth-pop chiptune\nV-Pop synth-pop dance-pop\nV-Pop synth-pop future bass\nV-Pop tango\nV-Pop trance\nV-Pop trap\nV-Pop trap EDM\nV-Pop trap R&B\nV-Pop trap ambient\nV-Pop trap chillwave\nV-Pop trap-R&B\nV-Pop trap-pop\nV-Pop trap-soul\nV-Pop trip-hop\nV-Pop tropical\nV-Pop tropical dance-pop\nV-Pop tropical house\nV-Pop, 80s synth, dance\nV-Pop, 80s synth, funk\nV-Pop, 80s synth, nostalgic\nV-Pop, 80s, disco-funk\nV-Pop, 90s Eurodance\nV-Pop, 90s R&B\nV-Pop, 90s R&B, city pop\nV-Pop, 90s dance-pop\nV-Pop, 90s electronic, Eurodance\nV-Pop, 90s retro, Eurodance\nV-Pop, Asian fusion\nV-Pop, Bossa Nova, jazz\nV-Pop, Chinese fusion, electronic\nV-Pop, EDM\nV-Pop, EDM, Eurodance\nV-Pop, EDM, Trance\nV-Pop, EDM, V-Rap\nV-Pop, EDM, Vina House\nV-Pop, EDM, Vinahouse\nV-Pop, EDM, ballad\nV-Pop, EDM, big room house\nV-Pop, EDM, chiptune\nV-Pop, EDM, cinematic\nV-Pop, EDM, cinematic pop\nV-Pop, EDM, dance\nV-Pop, EDM, dance-pop\nV-Pop, EDM, electro house\nV-Pop, EDM, emotional\nV-Pop, EDM, festive\nV-Pop, EDM, folk-electronic\nV-Pop, EDM, folk-pop\nV-Pop, EDM, future bass\nV-Pop, EDM, hardstyle\nV-Pop, EDM, hip-hop\nV-Pop, EDM, house\nV-Pop, EDM, hyperpop\nV-Pop, EDM, lo-fi hip hop\nV-Pop, EDM, melancholic\nV-Pop, EDM, melancholic ballad\nV-Pop, EDM, nightcore\nV-Pop, EDM, nu-disco\nV-Pop, EDM, pop\nV-Pop, EDM, progressive house\nV-Pop, EDM, rap\nV-Pop, EDM, synth-pop\nV-Pop, EDM, traditional Vietnamese\nV-Pop, EDM, trance\nV-Pop, EDM, trap\nV-Pop, EDM, trap-pop\nV-Pop, EDM, tropical house\nV-Pop, EDM-pop\nV-Pop, EDM-pop, future bass\nV-Pop, EDM-trap\nV-Pop, East Asian fusion\nV-Pop, Euro-pop\nV-Pop, Eurobeat\nV-Pop, Eurodance\nV-Pop, Eurodance, 2000s\nV-Pop, Eurodance, 2000s Trance\nV-Pop, Eurodance, 2000s dance-pop\nV-Pop, Eurodance, 2000s nostalgia\nV-Pop, Eurodance, 2000s pop\nV-Pop, Eurodance, 90s dance-pop\nV-Pop, Eurodance, 90s pop\nV-Pop, Eurodance, EDM\nV-Pop, Eurodance, Hi-NRG\nV-Pop, Eurodance, Italo dance\nV-Pop, Eurodance, Italo disco\nV-Pop, Eurodance, J-pop\nV-Pop, Eurodance, K-pop\nV-Pop, Eurodance, Latin\nV-Pop, Eurodance, Latin pop\nV-Pop, Eurodance, Trance\nV-Pop, Eurodance, Trance-pop\nV-Pop, Eurodance, V-Rap\nV-Pop, Eurodance, Vina House\nV-Pop, Eurodance, Vinahouse\nV-Pop, Eurodance, ballad\nV-Pop, Eurodance, chiptune\nV-Pop, Eurodance, cinematic\nV-Pop, Eurodance, dance\nV-Pop, Eurodance, dance-pop\nV-Pop, Eurodance, disco\nV-Pop, Eurodance, early 2000s Vina House\nV-Pop, Eurodance, early 2000s trance\nV-Pop, Eurodance, early trance\nV-Pop, Eurodance, festive\nV-Pop, Eurodance, folk pop\nV-Pop, Eurodance, funk\nV-Pop, Eurodance, happy hardcore\nV-Pop, Eurodance, hip-hop\nV-Pop, Eurodance, nightcore\nV-Pop, Eurodance, nostalgic\nV-Pop, Eurodance, pop\nV-Pop, Eurodance, retro\nV-Pop, Eurodance, retro pop\nV-Pop, Eurodance, retro synth\nV-Pop, Eurodance, synthwave\nV-Pop, Eurodance, trance\nV-Pop, Eurodance, upbeat\nV-Pop, Indian classical, electronic\nV-Pop, Italo disco, Eurodance\nV-Pop, J-Pop, chiptune\nV-Pop, J-pop\nV-Pop, Latin Cumbia\nV-Pop, Latin cumbia\nV-Pop, Latin dance\nV-Pop, Latin dance, reggaeton\nV-Pop, Latin dance, retro\nV-Pop, Latin dance-pop\nV-Pop, Latin folk\nV-Pop, Latin pop\nV-Pop, Latin pop, early 2000s\nV-Pop, Latin, 90s\nV-Pop, Latin, cha-cha-cha\nV-Pop, Latin, dance\nV-Pop, New Jack Swing, 90s dance-pop\nV-Pop, New Jack Swing, late-90s R&B\nV-Pop, R&B\nV-Pop, R&B, 2000s\nV-Pop, R&B, EDM\nV-Pop, R&B, ambient\nV-Pop, R&B, ballad\nV-Pop, R&B, chiptune\nV-Pop, R&B, cinematic\nV-Pop, R&B, city pop\nV-Pop, R&B, deep house\nV-Pop, R&B, funk\nV-Pop, R&B, future bass\nV-Pop, R&B, hardstyle\nV-Pop, R&B, hip-hop\nV-Pop, R&B, lo-fi\nV-Pop, R&B, lo-fi hip-hop\nV-Pop, R&B, melancholic\nV-Pop, R&B, neo-classical\nV-Pop, R&B, synth-pop\nV-Pop, R&B, trap\nV-Pop, V-Rap\nV-Pop, V-Rap, EDM\nV-Pop, V-Rap, trap\nV-Pop, Vietnamese folk, synth pop\nV-Pop, Vina House\nV-Pop, Vinahouse\nV-Pop, Vinahouse, EDM\nV-Pop, Vinahouse, Eurodance\nV-Pop, Vinahouse, ballad\nV-Pop, Vinahouse, chiptune\nV-Pop, Vinahouse, cinematic\nV-Pop, Vinahouse, dance\nV-Pop, Vinahouse, dance pop\nV-Pop, Vinahouse, dance-pop\nV-Pop, Vinahouse, electronic\nV-Pop, Vinahouse, emotional EDM\nV-Pop, Vinahouse, emotional ballad\nV-Pop, Vinahouse, emotional pop\nV-Pop, Vinahouse, guzheng\nV-Pop, Vinahouse, happy hardcore\nV-Pop, Vinahouse, hardstyle\nV-Pop, Y2K, Eurodance\nV-Pop, adult contemporary\nV-Pop, ambient ballad, lo-fi\nV-Pop, ambient electronic\nV-Pop, ambient pop\nV-Pop, ambient, downtempo\nV-Pop, ambient, electronic\nV-Pop, ambient, lo-fi\nV-Pop, ambient, melancholic\nV-Pop, anime soundtrack, ballad\nV-Pop, atmospheric ballad\nV-Pop, ballad, EDM\nV-Pop, ballad, R&B\nV-Pop, big band, tango\nV-Pop, big-band, retro\nV-Pop, bolero, traditional folk\nV-Pop, boogie-woogie, swing\nV-Pop, bossa nova\nV-Pop, breakcore, glitch-hop\nV-Pop, chill R&B\nV-Pop, chiptune\nV-Pop, chiptune, EDM\nV-Pop, chiptune, Eurodance\nV-Pop, chiptune, J-pop\nV-Pop, chiptune, R&B\nV-Pop, chiptune, Vinahouse\nV-Pop, chiptune, ballad\nV-Pop, chiptune, dance\nV-Pop, chiptune, dance-pop\nV-Pop, chiptune, electro-pop\nV-Pop, chiptune, electronic\nV-Pop, chiptune, eurodance\nV-Pop, chiptune, future bass\nV-Pop, chiptune, happy hardcore\nV-Pop, chiptune, hip-hop\nV-Pop, chiptune, lo-fi hip-hop\nV-Pop, chiptune, pop\nV-Pop, chiptune, pop-rock\nV-Pop, chiptune, retro pop\nV-Pop, chiptune, synth-pop\nV-Pop, cinematic ballad\nV-Pop, cinematic ballad, hip-hop\nV-Pop, cinematic hip-hop\nV-Pop, cinematic pop\nV-Pop, cinematic, EDM\nV-Pop, cinematic, ambient\nV-Pop, cinematic, ballad\nV-Pop, cinematic, dance-pop\nV-Pop, cinematic, electronic\nV-Pop, cinematic, ethereal\nV-Pop, cinematic, folk\nV-Pop, cinematic, folk fusion\nV-Pop, cinematic, funk\nV-Pop, cinematic, glitch\nV-Pop, cinematic, lo-fi\nV-Pop, cinematic, melancholic\nV-Pop, cinematic, power ballad\nV-Pop, cinematic, traditional East Asian\nV-Pop, cinematic, traditional Vietnamese\nV-Pop, cinematic, trap\nV-Pop, cinematic, upbeat\nV-Pop, cinematic, world music\nV-Pop, city pop, R&B\nV-Pop, city pop, funk\nV-Pop, city pop, synth-pop\nV-Pop, cloud rap, dream trap\nV-Pop, dance pop\nV-Pop, dance, EDM\nV-Pop, dance, Eurodance\nV-Pop, dance, electronic\nV-Pop, dance, festive\nV-Pop, dance, melancholic\nV-Pop, dance, synthwave\nV-Pop, dance-pop\nV-Pop, dance-pop, 90s\nV-Pop, dance-pop, EDM\nV-Pop, dance-pop, Eurodance\nV-Pop, dance-pop, early 2000s\nV-Pop, dance-pop, electronic\nV-Pop, dance-pop, emotional\nV-Pop, dance-pop, festive\nV-Pop, dance-pop, future bass\nV-Pop, dance-pop, hip-hop\nV-Pop, dance-pop, melancholic\nV-Pop, dance-pop, pop-rock\nV-Pop, dance-pop, synth\nV-Pop, dance-pop, synth ballad\nV-Pop, dance-pop, traditional fusion\nV-Pop, dance-pop, tropical house\nV-Pop, dancehall, afrobeats\nV-Pop, deep house\nV-Pop, disco, synth pop\nV-Pop, disco-funk\nV-Pop, disco-funk, retro\nV-Pop, downtempo R&B\nV-Pop, downtempo, ambient\nV-Pop, downtempo, emotional\nV-Pop, dream pop\nV-Pop, dream pop, EDM\nV-Pop, dreamy EDM\nV-Pop, dreamy R&B\nV-Pop, dreamy ballad\nV-Pop, dreamy ballad, lo-fi hip-hop\nV-Pop, dreamy synth, R&B\nV-Pop, dreamy trap\nV-Pop, early 2000s\nV-Pop, early 2000s R&B\nV-Pop, early 2000s R&B, hip-hop\nV-Pop, early 2000s electronic\nV-Pop, early 2000s electronic dance\nV-Pop, early 2000s hip-hop\nV-Pop, early 2000s, funk\nV-Pop, electro-dangdut\nV-Pop, electronic\nV-Pop, electronic dance\nV-Pop, electronic dance-pop\nV-Pop, electronic, EDM\nV-Pop, electronic, East Asian pop\nV-Pop, electronic, South Asian fusion\nV-Pop, electronic, ambient\nV-Pop, electronic, ballad\nV-Pop, electronic, cinematic\nV-Pop, electronic, classical\nV-Pop, electronic, dance\nV-Pop, electronic, folk fusion\nV-Pop, electronic, guzheng fusion\nV-Pop, electronic, hip-hop\nV-Pop, electronic, melancholic\nV-Pop, electronic, pop\nV-Pop, electronic, rock\nV-Pop, electronic, romantic\nV-Pop, electronic, spiritual\nV-Pop, electronic, traditional East Asian\nV-Pop, electronic, traditional fusion\nV-Pop, electronic, trap\nV-Pop, emotional EDM\nV-Pop, emotional EDM, hip-hop\nV-Pop, emotional ballad, EDM\nV-Pop, festive pop\nV-Pop, festive, electronic\nV-Pop, folk ballad\nV-Pop, folk fusion\nV-Pop, folk pop\nV-Pop, folk pop, pop-rock\nV-Pop, folk, ambient\nV-Pop, folk, ballad\nV-Pop, folk, cinematic\nV-Pop, folk-dance, ambient\nV-Pop, folk-pop\nV-Pop, folk-pop, cinematic\nV-Pop, funk, cinematic\nV-Pop, funk, city-pop\nV-Pop, funk, nu-disco\nV-Pop, funk, pop-rock\nV-Pop, funk, rap\nV-Pop, funk, synthwave\nV-Pop, future bass\nV-Pop, future bass, EDM\nV-Pop, future bass, R&B\nV-Pop, future bass, ballad\nV-Pop, future bass, cinematic\nV-Pop, future bass, cinematic pop\nV-Pop, future bass, dance-pop\nV-Pop, future bass, electro-pop\nV-Pop, future bass, electronic ballad\nV-Pop, future bass, emotional ballad\nV-Pop, future bass, hardstyle\nV-Pop, future bass, lo-fi\nV-Pop, future bass, pop-rap\nV-Pop, happy hardcore\nV-Pop, happy hardcore, Eurodance\nV-Pop, happy hardcore, chiptune\nV-Pop, happy hardcore, nightcore\nV-Pop, hardstyle\nV-Pop, hardstyle, EDM\nV-Pop, hardstyle, cinematic\nV-Pop, hardstyle, electronic\nV-Pop, hardstyle, trance\nV-Pop, hip hop\nV-Pop, hip-hop\nV-Pop, hip-hop, EDM\nV-Pop, hip-hop, R&B\nV-Pop, hip-hop, ambient\nV-Pop, hip-hop, atmospheric\nV-Pop, hip-hop, cinematic\nV-Pop, hip-hop, club\nV-Pop, hip-hop, contemporary pop\nV-Pop, hip-hop, dance-pop\nV-Pop, hip-hop, electronic\nV-Pop, hip-hop, electronic pop\nV-Pop, hip-hop, folk\nV-Pop, hip-hop, melancholic\nV-Pop, hip-hop, pop\nV-Pop, hip-hop, traditional East Asian\nV-Pop, hip-hop, traditional fusion\nV-Pop, hip-hop, trap\nV-Pop, house, EDM\nV-Pop, hyperpop\nV-Pop, hyperpop, J-pop\nV-Pop, karaoke, folk ballad\nV-Pop, lo-fi R&B\nV-Pop, lo-fi ballad\nV-Pop, lo-fi hip hop\nV-Pop, lo-fi hip hop, R&B\nV-Pop, lo-fi hip hop, ambient\nV-Pop, lo-fi hip hop, atmospheric\nV-Pop, lo-fi hip hop, ballad\nV-Pop, lo-fi hip hop, chillwave\nV-Pop, lo-fi hip hop, cinematic\nV-Pop, lo-fi hip hop, future bass\nV-Pop, lo-fi hip hop, vaporwave\nV-Pop, lo-fi hip-hop\nV-Pop, lo-fi hip-hop, R&B\nV-Pop, lo-fi hip-hop, ambient\nV-Pop, lo-fi pop, dream pop\nV-Pop, lo-fi, EDM\nV-Pop, lo-fi, R&B\nV-Pop, lo-fi, ambient\nV-Pop, lo-fi, ballad\nV-Pop, lo-fi, dreamy\nV-Pop, lo-fi, electronic\nV-Pop, lo-fi, melancholic\nV-Pop, lo-fi, trap\nV-Pop, melancholic R&B\nV-Pop, melancholic ballad\nV-Pop, melancholic, atmospheric\nV-Pop, melancholic, downtempo R&B\nV-Pop, melancholic, electronic\nV-Pop, melancholic, hip-hop\nV-Pop, melancholic, trap\nV-Pop, modern R&B\nV-Pop, modern R&B, trap\nV-Pop, neo-classical\nV-Pop, new jack swing, dance-pop\nV-Pop, new jack swing, funk\nV-Pop, new jack swing, hip-house\nV-Pop, new jack swing, retro\nV-Pop, nightcore, happy hardcore\nV-Pop, nightcore, hyperpop\nV-Pop, nu-disco, city pop\nV-Pop, orchestral, rock\nV-Pop, pop, synthpop\nV-Pop, pop-R&B, hip-hop\nV-Pop, pop-rap, chiptune\nV-Pop, pop-rap, electronic\nV-Pop, pop-rap, emotional ballad\nV-Pop, pop-rock\nV-Pop, progressive house, EDM\nV-Pop, reggaeton\nV-Pop, reggaeton, Latin\nV-Pop, reggaeton, tropical\nV-Pop, retro dance-pop\nV-Pop, retro electronic, chiptune\nV-Pop, retro funk, disco\nV-Pop, retro pop\nV-Pop, retro pop, theatrical\nV-Pop, retro synth, Eurodance\nV-Pop, retro synth, dance\nV-Pop, retro, funk\nV-Pop, retro, surf-rock\nV-Pop, retro, synthwave\nV-Pop, retro, upbeat\nV-Pop, retro-funk, disco\nV-Pop, soft rock\nV-Pop, soul, R&B\nV-Pop, soulful hip-hop\nV-Pop, synth pop, retro\nV-Pop, synth-pop\nV-Pop, synth-pop, EDM\nV-Pop, synth-pop, Eurodance\nV-Pop, synth-pop, chiptune\nV-Pop, synth-pop, cinematic\nV-Pop, synth-pop, city pop\nV-Pop, synth-pop, dance-pop\nV-Pop, synth-pop, disco\nV-Pop, synth-pop, future bass\nV-Pop, synth-pop, hip-hop\nV-Pop, synth-pop, pop-rock\nV-Pop, synth-pop, retro\nV-Pop, synth-pop, traditional Vietnamese folk\nV-Pop, synthwave, Eurodance\nV-Pop, theatrical pop, folk-pop\nV-Pop, theatrical pop, world music\nV-Pop, traditional East Asian, electronic\nV-Pop, traditional East Asian, electronic fusion\nV-Pop, traditional Vietnamese folk\nV-Pop, traditional Vietnamese, electronic\nV-Pop, traditional Vietnamese, folk fusion\nV-Pop, traditional Vietnamese, modern pop\nV-Pop, traditional fusion\nV-Pop, trance, Vinahouse\nV-Pop, trance, dance\nV-Pop, trance, hardstyle\nV-Pop, trance-pop, hardstyle\nV-Pop, trap\nV-Pop, trap, Asian fusion\nV-Pop, trap, EDM\nV-Pop, trap, R&B\nV-Pop, trap, ambient\nV-Pop, trap, cinematic\nV-Pop, trap, dreamy\nV-Pop, trap, festive\nV-Pop, trap, future bass\nV-Pop, trap, hyperpop\nV-Pop, trap, jazz\nV-Pop, trap, lo-fi\nV-Pop, trap, pop-R&B\nV-Pop, trap-R&B\nV-Pop, trap-R&B, dreamy\nV-Pop, trap-pop\nV-Pop, trap-pop, ballad\nV-Pop, trap-pop, dreamy\nV-Pop, trap-pop, lo-fi\nV-Pop, trap-rap, emotional pop\nV-Pop, world music\nV-Pop, world music, future bass\nV-Rap\nV-Rap chiptune\nV-Rap electronic hip-hop\nV-Rap lo-fi hip-hop\nV-Rap trap\nV-Rap, EDM, future bass\nV-Rap, EDM, trap\nV-pop\nV-pop EDM\nV-pop EDM dance-pop\nV-pop EDM hip-hop\nV-pop EDM trap\nV-pop EDM-pop\nV-pop Eurodance\nV-pop J-pop\nV-pop J-pop anime\nV-pop Latin\nV-pop Latin dance\nV-pop Latin dance-pop\nV-pop Latin pop\nV-pop R&B\nV-pop R&B dance-pop\nV-pop R&B trap\nV-pop ballad\nV-pop ballad, EDM, synthwave\nV-pop ballad, Eurodance, trance\nV-pop ballad, R&B, dance-pop\nV-pop ballad, pop-rock\nV-pop ballad, smooth jazz\nV-pop ballad, synth-pop, pop-rock\nV-pop big band\nV-pop big band swing\nV-pop bolero\nV-pop bubblegum pop\nV-pop cha-cha-cha\nV-pop chiptune\nV-pop cinematic\nV-pop cinematic ballad\nV-pop city pop\nV-pop city pop funk\nV-pop city pop future funk\nV-pop cumbia\nV-pop dance\nV-pop dance-pop\nV-pop dance-pop EDM\nV-pop dance-pop electropop\nV-pop dance-pop tropical house\nV-pop electro house chiptune\nV-pop electro-dance\nV-pop electro-folk\nV-pop electro-funk\nV-pop electro-house\nV-pop electro-pop\nV-pop electro-pop dance-pop\nV-pop electro-swing\nV-pop electropop\nV-pop electropop future bass\nV-pop funk\nV-pop funk R&B\nV-pop funk city pop\nV-pop funk disco\nV-pop funk hip-hop\nV-pop future bass\nV-pop future bass EDM\nV-pop future bass chiptune\nV-pop future bass city pop\nV-pop future bass dance-pop\nV-pop future bass electropop\nV-pop future bass hardstyle\nV-pop future bass hyperpop\nV-pop future bass synth-pop\nV-pop future bass trap\nV-pop future funk\nV-pop hip-hop\nV-pop hip-hop R&B\nV-pop jazz ballad\nV-pop jazz lounge\nV-pop kawaii future bass\nV-pop lo-fi\nV-pop lo-fi chiptune\nV-pop lo-fi hip hop\nV-pop lo-fi hip-hop\nV-pop lo-fi hip-hop R&B\nV-pop lo-fi hip-hop city pop\nV-pop neo-soul\nV-pop neo-soul funk\nV-pop nu-disco funk\nV-pop orchestral\nV-pop pop-rock\nV-pop power ballad\nV-pop reggae dancehall\nV-pop reggaeton\nV-pop retro\nV-pop rock\nV-pop rock ballad\nV-pop salsa\nV-pop swing\nV-pop synth-pop\nV-pop tango\nV-pop trap\nV-pop, 8-bit chiptune\nV-pop, 8-bit, retro\nV-pop, 80s ballad, synth-pop\nV-pop, Christmas, ballad\nV-pop, EDM\nV-pop, EDM, Vinahouse\nV-pop, EDM, chiptune\nV-pop, EDM, dance\nV-pop, EDM, dance-pop\nV-pop, EDM, dream pop\nV-pop, EDM, electro-pop\nV-pop, EDM, future bass\nV-pop, EDM, gamer aesthetic\nV-pop, EDM, hardstyle\nV-pop, EDM, hip-hop\nV-pop, EDM, hyperpop\nV-pop, EDM, nightcore\nV-pop, EDM, progressive house\nV-pop, EDM, traditional Vietnamese\nV-pop, EDM, traditional folk\nV-pop, EDM, trance\nV-pop, EDM, trap\nV-pop, EDM-pop\nV-pop, Euro-pop\nV-pop, Eurodance\nV-pop, Eurodance, EDM\nV-pop, Eurodance, Italo disco\nV-pop, Eurodance, J-pop\nV-pop, Eurodance, Vina House\nV-pop, Eurodance, cabaret\nV-pop, Eurodance, chiptune\nV-pop, Eurodance, dance\nV-pop, Eurodance, dance-pop\nV-pop, Eurodance, funk\nV-pop, Eurodance, happy hardcore\nV-pop, Eurodance, hyperpop\nV-pop, Eurodance, nightcore\nV-pop, Eurodance, pop-rock\nV-pop, Eurodance, power metal\nV-pop, Eurodance, retro\nV-pop, Eurodance, retro pop\nV-pop, Eurodance, rock\nV-pop, Eurodance, trance\nV-pop, French chanson, synth-pop\nV-pop, J-pop\nV-pop, J-pop, EDM\nV-pop, J-pop, anime\nV-pop, J-pop, chiptune\nV-pop, J-pop, happy hardcore\nV-pop, J-pop, nightcore\nV-pop, J-pop, video game music\nV-pop, J-rock\nV-pop, J-rock, anime\nV-pop, J-rock, anime theme\nV-pop, K-pop, hip-hop\nV-pop, Latin cumbia\nV-pop, Latin dance\nV-pop, Latin dance, reggaeton\nV-pop, Latin dance, retro\nV-pop, Latin jazz, big band\nV-pop, Latin pop\nV-pop, Latin pop, cinematic\nV-pop, Latin pop, dance\nV-pop, Latin pop, disco\nV-pop, Latin pop, salsa\nV-pop, Latin pop, synth pop\nV-pop, Latin, theatrical\nV-pop, R&B, pop-funk\nV-pop, Vinahouse\nV-pop, Vinahouse, EDM\nV-pop, Vinahouse, dance-pop\nV-pop, Vinahouse, electronic\nV-pop, Vinahouse, traditional Vietnamese\nV-pop, ambient ballad\nV-pop, ambient, traditional fusion\nV-pop, anime soundtrack\nV-pop, anime soundtrack, electronic\nV-pop, ballad, classic rock\nV-pop, ballad, electronic\nV-pop, bedroom pop, lo-fi\nV-pop, big band swing\nV-pop, big band, swing\nV-pop, bolero, ambient\nV-pop, bolero, pop ballad\nV-pop, bolero, traditional East Asian\nV-pop, bubblegum pop\nV-pop, bubblegum pop, kawaii\nV-pop, cha-cha-cha\nV-pop, cha-cha-cha, retro\nV-pop, cha-cha-cha, vintage\nV-pop, chiptune\nV-pop, chiptune, 8-bit\nV-pop, chiptune, EDM\nV-pop, chiptune, Eurodance\nV-pop, chiptune, J-pop\nV-pop, chiptune, Vinahouse\nV-pop, chiptune, ambient\nV-pop, chiptune, bubblegum pop\nV-pop, chiptune, children's music\nV-pop, chiptune, dance-pop\nV-pop, chiptune, electro-house\nV-pop, chiptune, electro-pop\nV-pop, chiptune, electronic\nV-pop, chiptune, future bass\nV-pop, chiptune, happy hardcore\nV-pop, chiptune, hyperpop\nV-pop, chiptune, kawaii\nV-pop, chiptune, lo-fi\nV-pop, chiptune, nightcore\nV-pop, chiptune, novelty\nV-pop, chiptune, pop\nV-pop, chiptune, retro\nV-pop, chiptune, retro electronic\nV-pop, chiptune, synth-pop\nV-pop, chiptune, traditional Vietnamese\nV-pop, chiptune, trap\nV-pop, chiptune, trap-pop\nV-pop, chiptune, upbeat\nV-pop, chiptune, video game music\nV-pop, cinematic ballad\nV-pop, cinematic folk\nV-pop, cinematic pop, Eurodance\nV-pop, cinematic pop, folk fusion\nV-pop, cinematic, Eurodance\nV-pop, cinematic, ambient\nV-pop, cinematic, dance\nV-pop, cinematic, dance-pop\nV-pop, cinematic, dream pop\nV-pop, cinematic, electronic\nV-pop, cinematic, ethereal\nV-pop, cinematic, folk\nV-pop, cinematic, hardstyle\nV-pop, cinematic, melancholic\nV-pop, cinematic, orchestral\nV-pop, cinematic, power ballad\nV-pop, cinematic, romantic\nV-pop, cinematic, traditional East Asian\nV-pop, cinematic, traditional Vietnamese\nV-pop, cinematic, traditional folk\nV-pop, cinematic, traditional fusion\nV-pop, cinematic, trap\nV-pop, city pop, R&B\nV-pop, city pop, nu-disco\nV-pop, comedic pop\nV-pop, dance, EDM\nV-pop, dance-pop\nV-pop, dance-pop, EDM\nV-pop, dance-pop, Vinahouse\nV-pop, dance-pop, ambient\nV-pop, dance-pop, cinematic\nV-pop, dance-pop, deep house\nV-pop, dance-pop, electronic\nV-pop, dance-pop, electropop\nV-pop, dance-pop, funk\nV-pop, dance-pop, future bass\nV-pop, dance-pop, hip-hop\nV-pop, dance-pop, hyperpop\nV-pop, dance-pop, nightcore\nV-pop, dance-pop, retro\nV-pop, dancehall-lite, tropical\nV-pop, dream pop, EDM\nV-pop, dream pop, dance-pop\nV-pop, dream pop, lo-fi\nV-pop, early 2000s\nV-pop, early 2000s pop, hip-hop\nV-pop, early 2000s, synth pop\nV-pop, electro-dance, chiptune\nV-pop, electro-funk, hyperpop\nV-pop, electronic dance\nV-pop, electronic dance, chiptune\nV-pop, electronic dance-pop\nV-pop, electronic pop\nV-pop, electronic, cinematic\nV-pop, electronic, comedic\nV-pop, electronic, dance\nV-pop, electronic, dreamy\nV-pop, electronic, folk\nV-pop, electronic, folk fusion\nV-pop, ethereal, traditional fusion\nV-pop, festive, traditional fusion\nV-pop, folk ballad\nV-pop, folk ballad, ambient\nV-pop, folk fusion\nV-pop, folk fusion, cinematic pop\nV-pop, folk, Cumbia Vàng\nV-pop, folk, Latin pop\nV-pop, folk, electronic\nV-pop, folk, retro\nV-pop, folk, synth\nV-pop, folk-electronic\nV-pop, funk, ambient\nV-pop, funk, dance-pop\nV-pop, funk, disco\nV-pop, funk, electronic\nV-pop, funk, new jack swing\nV-pop, funk, traditional Asian\nV-pop, future bass\nV-pop, future bass, EDM\nV-pop, future bass, hyperpop\nV-pop, future bass, kawaii\nV-pop, happy hardcore, nightcore\nV-pop, hard rock\nV-pop, hardstyle\nV-pop, hardstyle, Vinahouse\nV-pop, hardstyle, cinematic electronic\nV-pop, hip-hop, cinematic rock\nV-pop, hip-hop, dance-pop\nV-pop, hip-hop, future bass\nV-pop, hyperpop\nV-pop, hyperpop, J-pop\nV-pop, hyperpop, city pop\nV-pop, hyperpop, dance-pop\nV-pop, hyperpop, electro-house\nV-pop, hyperpop, future bass\nV-pop, hyperpop, kawaii future bass\nV-pop, hyperpop, nightcore\nV-pop, hyperpop, trap\nV-pop, karaoke, synth pop\nV-pop, kawaii future bass\nV-pop, lo-fi hip hop\nV-pop, lo-fi hip hop, ambient\nV-pop, lo-fi hip hop, atmospheric ballad\nV-pop, lo-fi hip-hop\nV-pop, lo-fi hip-hop, pop-rock\nV-pop, lo-fi, EDM\nV-pop, lo-fi, ambient\nV-pop, lo-fi, ballad\nV-pop, lo-fi, dream pop\nV-pop, marching band, upbeat\nV-pop, new jack swing, retro\nV-pop, nightcore\nV-pop, nightcore, chiptune\nV-pop, nightcore, happy hardcore\nV-pop, nightcore, hard dance\nV-pop, nightcore, hyperpop\nV-pop, nu-disco, city pop\nV-pop, nu-disco, house\nV-pop, orchestral ballad, bolero\nV-pop, orchestral, bolero\nV-pop, pop-rap\nV-pop, pop-rock\nV-pop, pop-rock, Latin\nV-pop, pop-rock, hip-hop\nV-pop, power ballad\nV-pop, power ballad, R&B\nV-pop, power ballad, pop-rock\nV-pop, power ballad, theatrical\nV-pop, retro dance-pop\nV-pop, retro electronic\nV-pop, retro electronic, synth funk\nV-pop, retro funk, disco\nV-pop, retro pop\nV-pop, retro rock, big band\nV-pop, retro synth\nV-pop, retro synth, 80s pop\nV-pop, retro synth, early digital\nV-pop, retro, 80s anime\nV-pop, retro, 90s\nV-pop, retro, 90s synth\nV-pop, retro, cha-cha-cha\nV-pop, retro, chiptune\nV-pop, retro, cinematic\nV-pop, retro, comedic\nV-pop, retro, dance\nV-pop, retro, electronic\nV-pop, retro, karaoke\nV-pop, retro, synth-pop\nV-pop, retro, synthwave\nV-pop, retro, theatrical\nV-pop, retro, traditional fusion\nV-pop, retro-disco, funk\nV-pop, retro-funk, disco\nV-pop, retro-futuristic, synthwave\nV-pop, retro-pop\nV-pop, rock, folk\nV-pop, sentimental ballad\nV-pop, smooth jazz\nV-pop, smooth jazz, pop ballad\nV-pop, synth-pop\nV-pop, synth-pop, 90s dance-pop\nV-pop, synth-pop, Eurodance\nV-pop, synth-pop, city pop\nV-pop, synth-pop, dance-pop\nV-pop, synth-pop, disco\nV-pop, synth-pop, future bass\nV-pop, synth-pop, musical comedy\nV-pop, synth-pop, retro\nV-pop, synth-pop, theatrical\nV-pop, synth-pop, trap, pop-rap\nV-pop, theatrical opera, cinematic\nV-pop, theatrical pop, Gufeng\nV-pop, theatrical pop, quirky pop\nV-pop, theatrical pop, show tune\nV-pop, theatrical, early 2000s\nV-pop, theatrical, funk\nV-pop, traditional Asian, melancholic\nV-pop, traditional East Asian, electronic\nV-pop, traditional Vietnamese folk\nV-pop, traditional Vietnamese, cinematic\nV-pop, traditional Vietnamese, electronic\nV-pop, traditional Vietnamese, folk fusion\nV-pop, traditional folk\nV-pop, traditional folk, melancholic pop\nV-pop, traditional fusion\nV-pop, traditional fusion, electronic\nV-pop, trap\nV-pop, trap, EDM\nV-pop, trap, R&B\nV-pop, trap, future bass\nV-pop, trap, hyperpop\nV-pop, trap, pop-rap\nV-pop, trap, synth pop\nV-pop, trap, synthpop\nV-pop, tropical house\nVacarria\nVallenato\nVallenato Christian\nVallenato Christmas\nVallenato Cumbia\nVallenato Norteño\nVallenato Reggaeton\nVallenato Sertanejo\nVallenato cumbia\nVallenato gospel\nVallenato hip-hop\nVallenato pop\nVallenato reggae\nVallenato reggaeton\nVallenato urban\nVallenato, Cumbia\nVallenato-pop\nVallenato-reggaeton\nVals criollo\nVaneira\nVaneira Cumbia\nVaneira Gaucho\nVaneira Gaúcha\nVaneira, Brazilian folk\nVaneira, música Gaúcha\nVaporwave, EDM, Mandopop\nVaquejada\nVedic metal\nVenezuelan Cumbia\nVenezuelan Gaita\nVenezuelan folk\nVenezuelan folk, Joropo, protest music\nVenezuelan gaita\nVenezuelan hip-hop\nVietnamese Bolero\nVietnamese Buddhist\nVietnamese Buddhist folk\nVietnamese Buddhist pop\nVietnamese Buddhist spiritual\nVietnamese Christian\nVietnamese Christian ballad\nVietnamese Christian hymn\nVietnamese Christian pop\nVietnamese Christian pop, Latin cumbia\nVietnamese Christian pop-rock\nVietnamese Christian power ballad\nVietnamese Christian rock\nVietnamese Christian worship\nVietnamese Christmas ballad\nVietnamese Christmas pop\nVietnamese EDM\nVietnamese New Year, EDM, pop\nVietnamese New Year, marching band, festive\nVietnamese Pop-R&B\nVietnamese R&B\nVietnamese R&B lo-fi hip-hop\nVietnamese R&B trap\nVietnamese R&B, early 2000s hip-hop\nVietnamese R&B, hip-hop\nVietnamese R&B, lo-fi hip-hop\nVietnamese R&B, pop\nVietnamese R&B, trap\nVietnamese R&B, trap, lo-fi hip hop\nVietnamese Tết music\nVietnamese acoustic\nVietnamese acoustic ballad\nVietnamese acoustic pop\nVietnamese acoustic pop lo-fi hip-hop\nVietnamese alternative rock\nVietnamese anthem\nVietnamese art song\nVietnamese ballad\nVietnamese ballad 1980s\nVietnamese ballad V-pop\nVietnamese ballad bolero\nVietnamese ballad jazz\nVietnamese ballad jazz lounge\nVietnamese ballad pop-rock\nVietnamese ballad rock\nVietnamese ballad, Eurodance, V-Pop\nVietnamese ballad, Latin bolero\nVietnamese ballad, Latin pop\nVietnamese ballad, Latin salsa\nVietnamese ballad, R&B, trap\nVietnamese ballad, Tết pop\nVietnamese ballad, V-pop, Eurodance\nVietnamese ballad, ambient, trip-hop\nVietnamese ballad, bossa nova, cinematic\nVietnamese ballad, chiptune\nVietnamese ballad, chiptune, lo-fi\nVietnamese ballad, cinematic pop-rock, upbeat Vietnamese pop\nVietnamese ballad, cinematic, pop-rock\nVietnamese ballad, folk, cinematic\nVietnamese ballad, folk-pop\nVietnamese ballad, funk pop-rock\nVietnamese ballad, hard rock\nVietnamese ballad, hard rock, cinematic\nVietnamese ballad, jazz lounge\nVietnamese ballad, jazz, romantic\nVietnamese ballad, jazz, sentimental\nVietnamese ballad, lo-fi R&B\nVietnamese ballad, lo-fi, vintage\nVietnamese ballad, piano ballad, acoustic folk\nVietnamese ballad, pop ballad, cinematic\nVietnamese ballad, pop, cinematic\nVietnamese ballad, pop-R&B\nVietnamese ballad, pop-ballad, traditional fusion\nVietnamese ballad, pop-rock\nVietnamese ballad, pop-rock, cinematic\nVietnamese ballad, pop-rock, folk fusion\nVietnamese ballad, pop-rock, rock\nVietnamese ballad, power ballad\nVietnamese ballad, power ballad, cinematic\nVietnamese ballad, power ballad, cinematic rock\nVietnamese ballad, power ballad, classical\nVietnamese ballad, power rock\nVietnamese ballad, retro, chiptune\nVietnamese ballad, rock, emotional\nVietnamese ballad, rock, traditional fusion\nVietnamese ballad, smooth jazz\nVietnamese ballad, synth-pop\nVietnamese ballad, synth-pop, Eurodance\nVietnamese bolero\nVietnamese bolero jazz\nVietnamese bolero jazz lounge\nVietnamese bolero lounge jazz\nVietnamese bolero lounge-pop\nVietnamese bolero pop\nVietnamese bolero rock\nVietnamese bolero tango\nVietnamese bolero, C-pop, cinematic\nVietnamese bolero, Eurodance\nVietnamese bolero, Latin bolero\nVietnamese bolero, Latin cha-cha-cha\nVietnamese bolero, Latin groove\nVietnamese bolero, Latin jazz\nVietnamese bolero, Latin jazz, funk\nVietnamese bolero, Latin pop\nVietnamese bolero, Latin salsa\nVietnamese bolero, R&B, soul\nVietnamese bolero, V-Pop\nVietnamese bolero, V-pop\nVietnamese bolero, V-pop, dance-pop\nVietnamese bolero, V-pop, folk\nVietnamese bolero, Vietnamese folk\nVietnamese bolero, Vina House\nVietnamese bolero, Vinahouse\nVietnamese bolero, ambient fusion\nVietnamese bolero, ambient, cinematic\nVietnamese bolero, big band swing\nVietnamese bolero, blues, acoustic\nVietnamese bolero, cha-cha-chá\nVietnamese bolero, chiptune\nVietnamese bolero, cinematic ambient\nVietnamese bolero, cinematic ballad, rock fusion\nVietnamese bolero, cinematic orchestral\nVietnamese bolero, cinematic pop\nVietnamese bolero, cinematic pop, orchestral\nVietnamese bolero, cinematic, ambient\nVietnamese bolero, cinematic, blues\nVietnamese bolero, cinematic, electronic\nVietnamese bolero, cinematic, orchestral\nVietnamese bolero, disco-funk\nVietnamese bolero, electronic pop, cinematic\nVietnamese bolero, electronic, melancholic\nVietnamese bolero, folk\nVietnamese bolero, folk ballad\nVietnamese bolero, folk-pop\nVietnamese bolero, folk-pop, cinematic\nVietnamese bolero, funk, soul\nVietnamese bolero, hard rock\nVietnamese bolero, hip-hop/R&B\nVietnamese bolero, jazz lounge\nVietnamese bolero, jazz, soul\nVietnamese bolero, modern V-Pop\nVietnamese bolero, modern ballad, traditional Asian\nVietnamese bolero, modern pop, traditional East Asian\nVietnamese bolero, nu-disco\nVietnamese bolero, pop ballad, traditional fusion\nVietnamese bolero, pop-ballad, traditional folk\nVietnamese bolero, pop-rock\nVietnamese bolero, pop-rock, acoustic\nVietnamese bolero, pop-rock, cinematic\nVietnamese bolero, pop-rock, traditional fusion\nVietnamese bolero, power ballad, cinematic\nVietnamese bolero, psychedelic rock\nVietnamese bolero, retro synth, lo-fi\nVietnamese bolero, smooth jazz, pop ballad\nVietnamese bolero, soul, disco-funk\nVietnamese bolero, synth-pop\nVietnamese bolero, synth-pop, V-pop\nVietnamese bolero, synth-pop, funk\nVietnamese bolero, traditional Chinese, melancholic\nVietnamese bolero, traditional East Asian, melancholic pop\nVietnamese bolero, traditional folk, cinematic orchestral\nVietnamese bolero-pop\nVietnamese children's\nVietnamese children's music\nVietnamese children's pop\nVietnamese children's song, pop-rock ballad\nVietnamese children's song, sentimental ballad\nVietnamese children's spiritual\nVietnamese comedy pop\nVietnamese comedy rap\nVietnamese disco\nVietnamese electronic\nVietnamese electronic dance\nVietnamese electronic folk-pop\nVietnamese folk\nVietnamese folk ballad\nVietnamese folk blues\nVietnamese folk chiptune\nVietnamese folk fusion\nVietnamese folk hip-hop\nVietnamese folk opera\nVietnamese folk opera, cinematic, orchestral\nVietnamese folk pop\nVietnamese folk pop-funk\nVietnamese folk pop-rap\nVietnamese folk pop-rock\nVietnamese folk pop-trap\nVietnamese folk rock\nVietnamese folk rock funk\nVietnamese folk, MIDI style\nVietnamese folk, V-Pop, Cumbia Vàng\nVietnamese folk, V-pop\nVietnamese folk, ambient\nVietnamese folk, ambient ballad\nVietnamese folk, ambient fusion\nVietnamese folk, ambient, cinematic\nVietnamese folk, ambient, downtempo\nVietnamese folk, ambient, folk-rock\nVietnamese folk, big band swing\nVietnamese folk, cinematic electronic\nVietnamese folk, cinematic pop\nVietnamese folk, cinematic pop, operatic rock\nVietnamese folk, cinematic, ambient\nVietnamese folk, cinematic, ballad\nVietnamese folk, cinematic, electronic\nVietnamese folk, cinematic, epic\nVietnamese folk, cinematic, operatic\nVietnamese folk, cinematic, orchestral\nVietnamese folk, electronic fusion\nVietnamese folk, electronic pop\nVietnamese folk, electronic, ambient\nVietnamese folk, electronic, pop\nVietnamese folk, electronic, pop-EDM\nVietnamese folk, funk, soul\nVietnamese folk, pop ballad\nVietnamese folk, pop ballad, cinematic\nVietnamese folk, pop, traditional\nVietnamese folk, pop-rock\nVietnamese folk, pop-rock, hip-hop\nVietnamese folk, pop-rock, smooth jazz\nVietnamese folk, symphonic rock\nVietnamese folk, synth-pop, V-pop\nVietnamese folk, synth-pop, cinematic\nVietnamese folk, world fusion\nVietnamese folk, world music\nVietnamese folk-pop\nVietnamese folk-pop chiptune\nVietnamese folk-pop reggae-ska\nVietnamese folk-pop, V-pop\nVietnamese folk-pop, electronic dancehall\nVietnamese folk-pop, hard rock\nVietnamese folk-pop, modern rock\nVietnamese folk-pop, retro synth-pop\nVietnamese folk-rock\nVietnamese folk-rock punk\nVietnamese fusion\nVietnamese fusion, retro funk, cinematic pop\nVietnamese gospel\nVietnamese hip hop\nVietnamese hip-hop\nVietnamese hip-hop chiptune\nVietnamese hip-hop lo-fi\nVietnamese hip-hop trap\nVietnamese hip-hop, global dance\nVietnamese hip-hop, lo-fi, hyperpop\nVietnamese hip-hop, trap\nVietnamese hip-hop, trap, EDM\nVietnamese hip-hop, trap, Middle Eastern fusion\nVietnamese hip-hop, trap, cloud rap\nVietnamese hip-hop, trap, dubstep\nVietnamese hip-hop, trap, hardstyle\nVietnamese hip-hop, trap, pop-rap\nVietnamese jazz\nVietnamese jazz-pop\nVietnamese lo-fi hip hop\nVietnamese lullaby\nVietnamese march\nVietnamese new-age, folk, V-Pop\nVietnamese opera\nVietnamese opera, big band, theatrical\nVietnamese operatic pop\nVietnamese party-rap\nVietnamese patriotic\nVietnamese patriotic ballad\nVietnamese patriotic march\nVietnamese patriotic pop\nVietnamese patriotic, retro synth, MIDI music\nVietnamese pop\nVietnamese pop 80s\nVietnamese pop 90s\nVietnamese pop EDM\nVietnamese pop Eurodance\nVietnamese pop Latin\nVietnamese pop Latin bolero\nVietnamese pop Latin dance\nVietnamese pop Latin disco\nVietnamese pop Latin groove\nVietnamese pop R&B\nVietnamese pop ballad\nVietnamese pop ballad, dance-pop\nVietnamese pop big band jazz\nVietnamese pop blues-rock\nVietnamese pop bolero\nVietnamese pop cha-cha-cha\nVietnamese pop chiptune\nVietnamese pop cumbia\nVietnamese pop disco\nVietnamese pop disco funk\nVietnamese pop folk\nVietnamese pop funk\nVietnamese pop funk R&B\nVietnamese pop funk disco\nVietnamese pop fusion\nVietnamese pop future bass\nVietnamese pop hip-hop\nVietnamese pop jazz\nVietnamese pop jazz blues\nVietnamese pop jazz lounge\nVietnamese pop lo-fi\nVietnamese pop lounge\nVietnamese pop lounge jazz\nVietnamese pop reggae dancehall\nVietnamese pop reggaeton\nVietnamese pop retro\nVietnamese pop retro funk disco\nVietnamese pop rock\nVietnamese pop rockabilly\nVietnamese pop salsa\nVietnamese pop, 80s disco\nVietnamese pop, 80s disco, Latin\nVietnamese pop, 80s disco, funk\nVietnamese pop, 80s rock\nVietnamese pop, 80s synth ballad\nVietnamese pop, 80s synth pop\nVietnamese pop, 80s synth, ballad\nVietnamese pop, 90s R&B, city pop\nVietnamese pop, 90s R&B, smooth jazz\nVietnamese pop, 90s dance-pop\nVietnamese pop, 90s hip-hop, new jack swing\nVietnamese pop, Bossa Nova, pop-rock\nVietnamese pop, Christian pop\nVietnamese pop, Christmas ballad\nVietnamese pop, Christmas, nostalgic\nVietnamese pop, Cumbia Vàng\nVietnamese pop, EDM\nVietnamese pop, EDM, dance-pop\nVietnamese pop, EDM, folk-pop\nVietnamese pop, EDM, hip-hop\nVietnamese pop, Eurodance\nVietnamese pop, Eurodance, 2000s V-Pop\nVietnamese pop, Eurodance, 90s dance\nVietnamese pop, Eurodance, 90s retro\nVietnamese pop, Eurodance, Italo disco\nVietnamese pop, Eurodance, Latin freestyle\nVietnamese pop, Eurodance, Latin pop\nVietnamese pop, Eurodance, R&B\nVietnamese pop, Eurodance, V-Pop\nVietnamese pop, Eurodance, disco\nVietnamese pop, Eurodance, happy hardcore\nVietnamese pop, Eurodance, hip-hop\nVietnamese pop, Eurodance, retro\nVietnamese pop, Eurodance, retro dance-pop\nVietnamese pop, Eurodance, synth-pop\nVietnamese pop, Eurodance, trance\nVietnamese pop, European ballad\nVietnamese pop, European flair\nVietnamese pop, European folk\nVietnamese pop, Indian classical\nVietnamese pop, J-pop, cinematic pop\nVietnamese pop, Latin bolero\nVietnamese pop, Latin cha-cha-cha\nVietnamese pop, Latin cha-cha-cha, retro\nVietnamese pop, Latin cha-cha-cha, synthwave\nVietnamese pop, Latin cumbia\nVietnamese pop, Latin dance\nVietnamese pop, Latin dance, cinematic\nVietnamese pop, Latin dance, cumbia\nVietnamese pop, Latin dance-pop\nVietnamese pop, Latin disco\nVietnamese pop, Latin folk, cinematic pop\nVietnamese pop, Latin jazz, cha-cha\nVietnamese pop, Latin jazz, funk\nVietnamese pop, Latin pop\nVietnamese pop, Latin pop, Bossa Nova\nVietnamese pop, Latin pop, Cumbia\nVietnamese pop, Latin pop, Eurodance\nVietnamese pop, Latin pop, bolero\nVietnamese pop, Latin pop, folk pop\nVietnamese pop, Latin pop, retro\nVietnamese pop, Latin pop, retro synth\nVietnamese pop, Latin pop, salsa\nVietnamese pop, Latin pop, theatrical\nVietnamese pop, Latin pop, tropical\nVietnamese pop, Latin pop, world music\nVietnamese pop, Latin salsa\nVietnamese pop, Latin salsa, retro synth\nVietnamese pop, Latin, cha-cha-cha\nVietnamese pop, Middle Eastern, Arabic\nVietnamese pop, R&B\nVietnamese pop, R&B, ballad\nVietnamese pop, R&B, future bass\nVietnamese pop, R&B, hip-hop\nVietnamese pop, R&B, trap\nVietnamese pop, V-Pop\nVietnamese pop, V-Pop, traditional folk\nVietnamese pop, Vietnamese rock\nVietnamese pop, Vinahouse\nVietnamese pop, Vinahouse, EDM\nVietnamese pop, Vinahouse, emotional ballad\nVietnamese pop, Vinahouse, hardstyle\nVietnamese pop, ballad, dizi\nVietnamese pop, ballad, guzheng\nVietnamese pop, big band, ballad\nVietnamese pop, big band, swing\nVietnamese pop, blues, soul\nVietnamese pop, blues, swing\nVietnamese pop, bolero\nVietnamese pop, bolero, hip-hop\nVietnamese pop, bolero, retro\nVietnamese pop, cha-cha-cha\nVietnamese pop, cha-cha-cha, retro\nVietnamese pop, cha-cha-cha, vintage pop\nVietnamese pop, chiptune\nVietnamese pop, chiptune, electronic\nVietnamese pop, chiptune, retro game\nVietnamese pop, chiptune, theatrical\nVietnamese pop, chiptune, theatrical pop\nVietnamese pop, cinematic\nVietnamese pop, cinematic ballad\nVietnamese pop, cinematic ballad, pop-rock\nVietnamese pop, cinematic ballad, rock\nVietnamese pop, cinematic orchestral\nVietnamese pop, cinematic pop\nVietnamese pop, cinematic pop, pop-rock\nVietnamese pop, cinematic rock\nVietnamese pop, cinematic rock, folk\nVietnamese pop, cinematic rock, patriotic\nVietnamese pop, cinematic, EDM\nVietnamese pop, cinematic, Latin pop\nVietnamese pop, cinematic, acoustic pop-rock\nVietnamese pop, cinematic, ballad\nVietnamese pop, cinematic, classical\nVietnamese pop, cinematic, folk\nVietnamese pop, cinematic, new-age\nVietnamese pop, cinematic, orchestral\nVietnamese pop, cinematic, synth-pop\nVietnamese pop, cinematic, taqsim\nVietnamese pop, cinematic, traditional fusion\nVietnamese pop, classic rock\nVietnamese pop, classical cello\nVietnamese pop, cumbia\nVietnamese pop, cumbia, dance\nVietnamese pop, dance\nVietnamese pop, dance-pop\nVietnamese pop, dance-pop, folk\nVietnamese pop, dance-pop, folk-influenced\nVietnamese pop, dance-pop, hip-hop, hardstyle\nVietnamese pop, dance-pop, new-age\nVietnamese pop, disco, funk\nVietnamese pop, disco, salsa\nVietnamese pop, disco-funk\nVietnamese pop, disco-funk, Latin ballad\nVietnamese pop, disco-funk, folk-pop\nVietnamese pop, disco-pop\nVietnamese pop, disco-pop, EDM\nVietnamese pop, disco-pop, cinematic\nVietnamese pop, downtempo R&B, atmospheric\nVietnamese pop, dreamy ballad, Latin salsa\nVietnamese pop, dreamy new-age\nVietnamese pop, early 2000s R&B\nVietnamese pop, electronic ballad\nVietnamese pop, electronic dance\nVietnamese pop, electronic pop\nVietnamese pop, electronic, chiptune\nVietnamese pop, electronic, cinematic\nVietnamese pop, electronic, folk\nVietnamese pop, festive, electronic\nVietnamese pop, folk\nVietnamese pop, folk ballad, cinematic\nVietnamese pop, folk cumbia\nVietnamese pop, folk pop\nVietnamese pop, folk pop, pop-rock\nVietnamese pop, folk, V-pop\nVietnamese pop, folk, dramatic\nVietnamese pop, folk, synth-pop\nVietnamese pop, folk-pop\nVietnamese pop, funk, disco\nVietnamese pop, future bass\nVietnamese pop, future bass, R&B\nVietnamese pop, future bass, hardstyle\nVietnamese pop, future bass, trap\nVietnamese pop, hard rock\nVietnamese pop, hardstyle\nVietnamese pop, hardstyle, Eurodance\nVietnamese pop, hip-hop\nVietnamese pop, hip-hop, ballad\nVietnamese pop, hip-hop, chiptune\nVietnamese pop, hip-hop, traditional East Asian\nVietnamese pop, jazz fusion, city pop\nVietnamese pop, lo-fi hip hop\nVietnamese pop, lo-fi hip hop, ballad\nVietnamese pop, lo-fi hip-hop\nVietnamese pop, lo-fi hip-hop, R&B\nVietnamese pop, lo-fi hip-hop, nu-metal\nVietnamese pop, lo-fi, R&B\nVietnamese pop, lo-fi, folk\nVietnamese pop, melancholic hip-hop\nVietnamese pop, new age, spiritual\nVietnamese pop, new jack swing\nVietnamese pop, new jack swing, funk\nVietnamese pop, new jack swing, hip-hop\nVietnamese pop, new jack swing, pop-funk\nVietnamese pop, new jack swing, retro\nVietnamese pop, new-age, spiritual\nVietnamese pop, nu-disco, funk\nVietnamese pop, oud, cinematic\nVietnamese pop, pop-rock\nVietnamese pop, pop-rock, folk fusion\nVietnamese pop, power metal\nVietnamese pop, power rock\nVietnamese pop, progressive house\nVietnamese pop, psychedelic funk, world music\nVietnamese pop, retro chiptune\nVietnamese pop, retro disco, funk\nVietnamese pop, retro electronic\nVietnamese pop, retro pop\nVietnamese pop, retro swing, big band\nVietnamese pop, retro synth, chiptune\nVietnamese pop, retro synth, theatrical pop\nVietnamese pop, retro synth-pop, disco\nVietnamese pop, retro synth-pop, disco-funk\nVietnamese pop, retro video game, melancholic\nVietnamese pop, retro video game, synthwave\nVietnamese pop, retro, 90s video game\nVietnamese pop, retro, big-band\nVietnamese pop, retro, cha-cha-cha\nVietnamese pop, retro, chiptune\nVietnamese pop, retro, synth funk\nVietnamese pop, retro, theatrical\nVietnamese pop, retro-funk, disco\nVietnamese pop, rock\nVietnamese pop, rock, folk\nVietnamese pop, rockabilly, retro\nVietnamese pop, sentimental ballad\nVietnamese pop, smooth jazz\nVietnamese pop, smooth jazz, adult contemporary\nVietnamese pop, soft rock\nVietnamese pop, soft rock, smooth jazz\nVietnamese pop, symphonic metal\nVietnamese pop, synth-pop\nVietnamese pop, synth-pop, bolero\nVietnamese pop, synth-pop, chiptune\nVietnamese pop, synth-pop, disco\nVietnamese pop, synth-pop, disco, funk\nVietnamese pop, synth-pop, folk\nVietnamese pop, synth-pop, game show\nVietnamese pop, synth-pop, military march\nVietnamese pop, theatrical pop, funk\nVietnamese pop, theatrical pop-rock\nVietnamese pop, traditional Vietnamese folk\nVietnamese pop, traditional folk\nVietnamese pop, trap R&B\nVietnamese pop, trap, EDM\nVietnamese pop, trap, R&B\nVietnamese pop, trap, hyperpop\nVietnamese pop, trip-hop\nVietnamese pop, world music, cinematic\nVietnamese pop-R&B\nVietnamese pop-dance\nVietnamese pop-folk\nVietnamese pop-funk\nVietnamese pop-funk, hard rock\nVietnamese pop-jazz\nVietnamese pop-rap\nVietnamese pop-rap, Vinahouse\nVietnamese pop-rock\nVietnamese pop-rock, J-rock\nVietnamese pop-rock, Latin percussion\nVietnamese pop-rock, Latin pop\nVietnamese pop-rock, big band swing, dance-pop\nVietnamese pop-rock, cinematic rock, power metal\nVietnamese pop-rock, soul ballad, Latin pop\nVietnamese pop-rock, theatrical rock\nVietnamese pop-trap\nVietnamese power ballad\nVietnamese power ballad, 80s rock\nVietnamese rap\nVietnamese rap, chiptune, electronic\nVietnamese rap, electro-house\nVietnamese rap, piano ballad\nVietnamese revolutionary folk\nVietnamese rock\nVietnamese rock ballad\nVietnamese rock opera\nVietnamese rock, Eurodance\nVietnamese rock, disco, Latin rock\nVietnamese soul funk\nVietnamese spiritual\nVietnamese spiritual ballad\nVietnamese spiritual folk\nVietnamese spiritual pop\nVietnamese traditional\nVietnamese trap\nVietnamese trap, cinematic hip-hop, electronic fusion\nVietnamese trap-rap\nVietnamese wedding music\nVietnamese wedding music, retro pop, karaoke\nViking metal\nViking metal, hardstyle, gabber\nVina House\nVina House, Cumbia Vàng\nVina House, EDM\nVina House, EDM, pop\nVina House, Eurodance\nVina House, Eurodance, Vietnamese folk\nVina House, hardstyle\nVinahouse\nVinahouse EDM\nVinahouse hardstyle\nVinahouse, EDM, V-Pop\nVinahouse, EDM, Vietnamese pop\nVinahouse, EDM, children's music\nVinahouse, EDM, jazz swing\nVinahouse, EDM, lo-fi\nVinahouse, Eurodance\nVinahouse, Eurodance, cinematic\nVinahouse, Eurodance, flamenco\nVinahouse, V-Pop, electronic\nVinahouse, V-Pop, electronic dance\nVinahouse, V-Rap, electronic dance\nVinahouse, cinematic orchestral, Vietnamese folk pop\nVinahouse, cinematic, electronic\nVinahouse, electronic, C-pop\nVinahouse, folk, electronic\nVinahouse, hardstyle, C-pop\nVinahouse, hardstyle, EDM\nVinahouse, hardstyle, Melbourne bounce\nVinahouse, hardstyle, Vietnamese pop\nVinahouse, hardstyle, ambient\nVinahouse, hardstyle, electronic\nVinahouse, hardstyle, pop\nVinahouse, melodic trance, hardstyle\nVocaloid\nVocaloid C-pop\nVocaloid Christmas\nVocaloid J-pop\nVocaloid J-pop future bass\nVocaloid J-rock\nVocaloid ambient\nVocaloid ballad\nVocaloid chiptune\nVocaloid folk\nVocaloid folk-pop\nVocaloid hip-hop\nVocaloid metalcore\nVocaloid pop\nVocaloid pop, ambient electronic\nVocaloid pop-rock\nVocaloid post-rock\nVocaloid rock\nVocaloid style\nVocaloid trap\nVocaloid, Chinese ambient, electronic\nVocaloid, Chinese ballad, ambient pop\nVocaloid, Chinese electronic\nVocaloid, Chinese electronic, anime soundtrack\nVocaloid, Chinese folk\nVocaloid, Christmas pop\nVocaloid, J-core, Eurobeat\nVocaloid, J-pop, cinematic\nVocaloid, J-pop, piano ballad\nVocaloid, Latin fusion, dance\nVocaloid, ambient pop\nVocaloid, ambient pop, Chinese electronic\nVocaloid, ambient pop, JRPG\nVocaloid, ambient pop, fantasy RPG\nVocaloid, ambient, Chinese electronic\nVocaloid, ambient, Chinese traditional\nVocaloid, ambient, East Asian\nVocaloid, ambient, JRPG\nVocaloid, ambient, cinematic\nVocaloid, ambient, electronic\nVocaloid, ambient, lo-fi\nVocaloid, ambient, melancholic\nVocaloid, ambient, traditional Chinese\nVocaloid, anime, lo-fi\nVocaloid, breakcore, ambient\nVocaloid, children's music\nVocaloid, children's music, chiptune\nVocaloid, chiptune, C-pop\nVocaloid, chiptune, ambient\nVocaloid, chiptune, cinematic\nVocaloid, chiptune, electronic\nVocaloid, chiptune, hyperpop\nVocaloid, cinematic chiptune\nVocaloid, cinematic, East Asian ambient\nVocaloid, cinematic, East Asian folk\nVocaloid, cinematic, ambient\nVocaloid, electronic, C-pop\nVocaloid, electronic, East Asian\nVocaloid, electronic, ambient\nVocaloid, electronic, cinematic\nVocaloid, electronic, fantasy\nVocaloid, fantasy RPG, ambient\nVocaloid, future bass, electronic\nVocaloid, hardstyle, ambient\nVocaloid, hardstyle, chiptune\nVocaloid, hardstyle, happy hardcore\nVocaloid, lo-fi hip hop, cinematic\nVocaloid, lo-fi, fantasy\nVocaloid, melancholic ballad, Chinese ambient\nVocaloid, melancholic, classical\nVocaloid, orchestral, epic\nVocaloid, retro pop\nVocaloid, symphonic rock, East Asian fusion\nVocaloid, synth pop, ambient\nVocaloid, synthwave, Chinese electronic\nVocaloid, video game, orchestral\nVolksmusik\nVolksmusik Schlager\nVolksmusik rock\nVolksmusik, Schlager\nWest African\nWest African acoustic\nWest African blues\nWest African chant\nWest African choral\nWest African drumming\nWest African folk\nWest African folk-pop\nWest African funk\nWest African gospel\nWest African groove\nWest African hip-hop\nWest African instrumental\nWest African percussion\nWest African pop\nWest African rhythm\nWest African soul\nWest African spoken word\nWest African traditional\nWest African world music\nWest Coast G-funk\nWest Coast G-funk, cloud rap\nWest Coast G-funk, cloud rap, trap\nWest Coast R&B\nWest Coast drill\nWest Coast funk\nWest Coast funk, dubstep, bass music\nWest Coast gangsta rap\nWest Coast hip hop\nWest Coast hip-hop\nWest Coast hip-hop G-funk\nWest Coast hip-hop chiptune\nWest Coast hip-hop trap\nWest Coast hip-hop vaporwave\nWest Coast hip-hop, G-funk, lo-fi hip-hop\nWest Coast hip-hop, hard rock\nWest Coast hip-hop, trap\nWest Coast house\nWest Coast pop\nWest Coast pop-rap\nWest Coast reggae\nWest Coast trap\nWestern\nWestern Swing\nWestern Swing Gypsy Jazz\nWestern Swing Norteño\nWestern Swing jump blues\nWestern Swing rockabilly\nWestern anthem\nWestern ballad\nWestern cinematic\nWestern folk\nWestern narrative\nWestern narrative ballad\nWestern novelty\nWestern storytelling\nWestern style\nWestern swing\nWestern swing musette\nWestern swing, rockabilly, Christmas\nWestern-schlager\nWorld Fusion\nWorld Music\nY2K R&B\nY2K R&B Mandopop\nY2K R&B hip-hop\nY2K breakbeat\nY2K dance-pop\nY2K hip-hop\nY2K hip-hop R&B\nY2K pop\nY2K pop-R&B\nYiddish folk\nYiddish folk ballad\nYé-yé\nYé-yé pop\nZaffa\nZamba\nZamba Candombe\nZouglou\nZouk\nZouk Afro-Caribbean pop\nZouk Afrobeats\nZouk Afrobeats R&B\nZouk Afrobeats pop\nZouk Afropop\nZouk Bossa Nova\nZouk Caribbean folk\nZouk Caribbean fusion\nZouk Caribbean pop\nZouk Caribbean pop-rock\nZouk Dancehall\nZouk Eurodance\nZouk French pop\nZouk Gospel\nZouk Kizomba\nZouk Kizomba cinematic\nZouk Kompa\nZouk Kompa Afrobeats\nZouk Kompa R&B\nZouk Kompa chiptune\nZouk Kompa cinematic\nZouk Kompa hip-hop\nZouk Kompa salsa\nZouk Kompa, Dancehall, Soca\nZouk R&B\nZouk R&B Afrobeat\nZouk R&B Kizomba\nZouk R&B cinematic\nZouk R&B fusion\nZouk R&B gospel\nZouk R&B hip-hop\nZouk R&B pop\nZouk Samba\nZouk Soca\nZouk Soca Afropop\nZouk Soca dance-pop\nZouk Soca pop\nZouk Soca synth-pop\nZouk Soukous\nZouk ballad\nZouk chiptune\nZouk cinematic\nZouk dance-pop\nZouk dancehall\nZouk dancehall hip-hop\nZouk funk\nZouk funk chiptune\nZouk funk gospel\nZouk fusion\nZouk gospel\nZouk gospel world music\nZouk hip-hop\nZouk new jack swing\nZouk pop\nZouk pop Kizomba\nZouk pop Kompa\nZouk pop, Kizomba, dance pop\nZouk pop, Kizomba, multi-lingual pop\nZouk pop, Latin pop\nZouk pop, Soukous fusion\nZouk reggae\nZouk rock\nZouk soca\nZouk synth-pop\nZouk trap\nZouk, Afro-Caribbean\nZouk, Afrobeats, French pop\nZouk, Caribbean folk-pop\nZouk, Caribbean pop\nZouk, Caribbean, Christmas\nZouk, Caribbean, festive\nZouk, Caribbean, world music\nZouk, Eurodance\nZouk, French novelty, Caribbean\nZouk, French pop, R&B\nZouk, French pop, live performance\nZouk, Kizomba\nZouk, Kompa\nZouk, Kompa, Afrobeats\nZouk, Kompa, C-pop\nZouk, Kompa, Caribbean pop\nZouk, Kompa, Christmas\nZouk, Kompa, French Caribbean\nZouk, Kompa, French Caribbean pop\nZouk, Kompa, R&B\nZouk, Kompa, ambient\nZouk, Kompa, chanson\nZouk, Kompa, chiptune\nZouk, Kompa, dance\nZouk, Kompa, dancehall\nZouk, Kompa, gospel\nZouk, Kompa, spiritual\nZouk, Kompa, synth pop\nZouk, Kompa, trap\nZouk, Kompa, tropical\nZouk, R&B, Haitian Creole\nZouk, Soukous, French Caribbean\nZouk, dream pop\nZouk, electronic, world music\nZouk, synth pop\nZouk, world music, French Caribbean\nZouk-pop\nZumba\nZumba dance-pop\nZumba, Latin, dance\nZumba, dance-pop, Brazilian\nZydeco\na cappella\na cappella Arabic\na cappella Christmas pop\na cappella J-pop\na cappella K-pop\na cappella K-pop R&B\na cappella Latin\na cappella R&B\na cappella R&B funk\na cappella R&B gospel\na cappella ballad\na cappella barbershop\na cappella beatbox\na cappella beatboxing\na cappella blues\na cappella bolero\na cappella cabaret\na cappella chanson\na cappella children's music\na cappella chiptune\na cappella choral\na cappella choral jazz\na cappella cinematic\na cappella comedy\na cappella country\na cappella devotional\na cappella doo-wop\na cappella educational\na cappella experimental\na cappella folk\na cappella funk\na cappella funk soul\na cappella funk-pop\na cappella funk-rock\na cappella gospel\na cappella gospel J-Pop\na cappella gospel R&B\na cappella hip hop\na cappella hip-hop\na cappella holiday\na cappella house\na cappella indie pop\na cappella jazz\na cappella jazz doo-wop\na cappella jazz soul\na cappella jazz-pop\na cappella lullaby\na cappella mambo\na cappella metal\na cappella minimalist\na cappella nasheed\na cappella novelty\na cappella pop\na cappella pop R&B\na cappella pop anime\na cappella pop ballad\na cappella pop rock\na cappella pop soul\na cappella pop-R&B\na cappella pop-chanson\na cappella pop-country\na cappella pop-funk\na cappella pop-gospel\na cappella pop-punk\na cappella pop-rap\na cappella pop-reggae\na cappella pop-rock\na cappella pop-soul\na cappella protest\na cappella protest folk\na cappella punk\na cappella rap\na cappella reggae\na cappella reggaeton\na cappella rock\na cappella rock opera\na cappella rockabilly\na cappella sacred\na cappella salsa\na cappella samba\na cappella satire\na cappella sea shanty\na cappella show tune\na cappella soul\na cappella soul funk\na cappella soul funk gospel\na cappella soul house\na cappella soul-pop\na cappella spiritual\na cappella swing\na cappella tango\na cappella theater\na cappella theatrical\na cappella worship\na cappella, African choral\na cappella, African choral, gospel\na cappella, Afro-pop, gospel\na cappella, Arabic Mawwal\na cappella, Arabic chant, choir\na cappella, Arabic choral\na cappella, Arabic classical\na cappella, Arabic devotional\na cappella, Arabic folk\na cappella, Arabic nasheed, cinematic\na cappella, Arabic traditional\na cappella, Arabic, Mawwal\na cappella, Arabic, spiritual\na cappella, Arabic, traditional\na cappella, Balkan folk\na cappella, Brazilian folk\na cappella, Brazilian, vocal jazz\na cappella, C-pop\na cappella, Chinese art song\na cappella, Chinese ballad\na cappella, Chinese folk\na cappella, Chinese folk, contemporary ballad\na cappella, Chinese folk, operatic\na cappella, Chinese opera\na cappella, Chinese opera, musical theater\na cappella, Chinese-style ballad\na cappella, Christmas novelty, barbershop\na cappella, European folk, Schlager\na cappella, German Schlager\na cappella, German chanson, cabaret\na cappella, German pop\na cappella, German pop, doo-wop\na cappella, Hawaiian, choral\na cappella, Hindi fusion\na cappella, Indian classical\na cappella, Indian classical, devotional\na cappella, Indian folk\na cappella, Jíbaro, Candombe\na cappella, K-pop ballad, contemporary R&B\na cappella, Latin folk\na cappella, Latin pop\na cappella, Latin pop, R&B\na cappella, Latin, Cuban son\na cappella, Latin, choir\na cappella, Latin, festive\na cappella, Latin, vocal group\na cappella, Latin, vocal jazz\na cappella, Latin, vocal rhythm\na cappella, MPB\na cappella, Middle Eastern classical\na cappella, R&B, Bollywood\na cappella, R&B, Christmas\na cappella, R&B, Haitian Creole\na cappella, R&B, doo-wop\na cappella, R&B, funk\na cappella, R&B, gospel\na cappella, R&B, hip-hop\na cappella, R&B, jazz\na cappella, R&B, pop\na cappella, R&B, smooth jazz\na cappella, R&B, soul\na cappella, Scottish folk\na cappella, South African\na cappella, South African choral\na cappella, South African gospel\na cappella, South African, choral\na cappella, South African, polyrhythmic\na cappella, South African, spiritual\na cappella, South Asian folk\na cappella, Southern folk\na cappella, Spanish folk\na cappella, Swedish Christmas, vocal ensemble\na cappella, Telugu, rhythmic\na cappella, Turkish art song\na cappella, Turkish folk\na cappella, Turkish folk, folk-pop\na cappella, West African folk\na cappella, alternative rock\na cappella, ambient folk\na cappella, ambient pop\na cappella, ambient, Chinese folk\na cappella, ambient, choral\na cappella, ambient, traditional Chinese\na cappella, ambient, traditional Chinese folk\na cappella, barbershop, Broadway\na cappella, barbershop, French chanson\na cappella, barbershop, cabaret\na cappella, barbershop, choral\na cappella, barbershop, doo-wop\na cappella, barbershop, musical theater\na cappella, barbershop, schlager\na cappella, barbershop, soul\na cappella, baroque, theatrical\na cappella, beatbox, R&B\na cappella, beatbox, comedic hip hop\na cappella, beatbox, funk\na cappella, beatbox, playful\na cappella, beatbox, pop-rap\na cappella, beatboxing, Latin hip hop\na cappella, big band, theatrical\na cappella, bilingual\na cappella, bolero, flamenco\na cappella, cante jondo\na cappella, chanson\na cappella, chanson, beatboxing\na cappella, chanson, cabaret\na cappella, chanson, musical theater\na cappella, choral pop\na cappella, choral, African\na cappella, choral, Arabic\na cappella, choral, Christmas\na cappella, choral, Latin\na cappella, choral, Slavic folk\na cappella, choral, ambient\na cappella, choral, cinematic\na cappella, choral, comedic\na cappella, choral, folk\na cappella, choral, hip-hop\na cappella, choral, operatic\na cappella, choral, pop\na cappella, choral, sacred\na cappella, choral, show tune\na cappella, choral, vocal percussion\na cappella, choral, world music\na cappella, cinematic folk, Mandarin ballad\na cappella, cinematic, J-pop\na cappella, cinematic, ancient style\na cappella, cinematic, folk\na cappella, cinematic, theatrical\na cappella, comedic, barbershop\na cappella, comedic, novelty\na cappella, contemporary gospel\na cappella, contemporary, Christmas\na cappella, country, comedy\na cappella, dance-pop\na cappella, dark cabaret\na cappella, death metal\na cappella, devotional, Arabic\na cappella, devotional, Arabic Mawwal\na cappella, devotional, Indian bhajan\na cappella, devotional, South Asian\na cappella, devotional, South Asian classical\na cappella, devotional, ambient\na cappella, devotional, ghazal\na cappella, doo-wop\na cappella, doo-wop, choral\na cappella, doo-wop, country\na cappella, doo-wop, festive\na cappella, doo-wop, soul\na cappella, doo-wop, theatrical\na cappella, doo-wop, upbeat\na cappella, doo-wop, vocal jazz\na cappella, ethereal, Arabic Mawwal\na cappella, ethereal, Arabic classical\na cappella, ethereal, Arabic devotional\na cappella, ethereal, South Asian\na cappella, ethereal, ballad\na cappella, ethereal, cinematic\na cappella, ethereal, melancholic\na cappella, ethereal, whimsical\na cappella, festive, Chinese New Year\na cappella, festive, doo-wop\na cappella, folk\na cappella, folk ballad\na cappella, folk, Celtic\na cappella, folk, French\na cappella, folk, South Asian\na cappella, folk, ambient\na cappella, folk, devotional\na cappella, folk, operatic\na cappella, folk, party\na cappella, folk, quirky\na cappella, folk, sea shanty\na cappella, funk, barbershop\na cappella, funk, holiday\na cappella, funk, soul\na cappella, futuristic, choral\na cappella, ghazal\na cappella, gospel\na cappella, gospel, Christmas\na cappella, gospel, R&B\na cappella, gospel, neo-classical\na cappella, gospel, world fusion\na cappella, hip hop\na cappella, hip-hop\na cappella, holiday, doo-wop\na cappella, holiday, gospel\na cappella, holiday, rock and roll\na cappella, jazz, Swedish vocal\na cappella, jazz, swing\na cappella, lo-fi, traditional\na cappella, mawwal, ambient\na cappella, melancholic, spiritual\na cappella, melodic rap, atmospheric\na cappella, musical theater\na cappella, novelty, synth pop\na cappella, operatic, Chinese epic\na cappella, piano ballad, soul\na cappella, pop\na cappella, pop, R&B\na cappella, pop, choral\na cappella, pop, electronic\na cappella, pop-R&B, Indian classical\na cappella, pop-country\na cappella, pop-funk\na cappella, pop-gospel\na cappella, pop-reggae\na cappella, pop-rock, Christmas\na cappella, pop-schlager\na cappella, pub rock\na cappella, punk rock\na cappella, ragtime, hymn\na cappella, reggae, vocal percussion\na cappella, retro, Zulu\na cappella, sacred, Arabic\na cappella, sacred, Arabic devotional\na cappella, sacred, cinematic\na cappella, sacred, pop\na cappella, satirical, doo-wop\na cappella, sea shanty\na cappella, sea shanty, choral\na cappella, sea shanty, polka\na cappella, show tune, pop-rock\na cappella, soul, Latin\na cappella, soul, R&B\na cappella, soul, christmas\na cappella, soul, flamenco\na cappella, soul, gospel\na cappella, soul, sea shanty\na cappella, soulful pop\na cappella, soulful pop, R&B\na cappella, southern rock\na cappella, spiritual, Anatolian folk\na cappella, spiritual, Arabic\na cappella, spiritual, Arabic Mawwal\na cappella, spiritual, Islamic\na cappella, spiritual, Islamic devotional\na cappella, spiritual, Sufi\na cappella, spiritual, choral\na cappella, spiritual, world fusion\na cappella, theatrical\na cappella, theatrical, French chanson\na cappella, theatrical, Swahili\na cappella, theatrical, alternative rock\na cappella, theatrical, barbershop\na cappella, theatrical, baroque\na cappella, theatrical, camp\na cappella, theatrical, chanson\na cappella, theatrical, choral\na cappella, theatrical, comedic\na cappella, theatrical, festive\na cappella, theatrical, gospel\na cappella, theatrical, novelty\na cappella, theatrical, piano\na cappella, theatrical, polyphonic\na cappella, theatrical, power metal\na cappella, theatrical, ragtime\na cappella, theatrical, sea shanty\na cappella, theatrical, show tune\na cappella, theatrical, synthetic\na cappella, theatrical, whimsical\na cappella, traditional African\na cappella, traditional African choral\na cappella, traditional Chinese ballad\na cappella, traditional Chinese folk\na cappella, traditional Chinese, cinematic\na cappella, traditional Chinese, ethereal\na cappella, traditional German\na cappella, traditional Indonesian, martial chant\na cappella, traditional South Asian\na cappella, tribal, lo-fi\na cappella, tribal, polyrhythmic\na cappella, tribal, world\na cappella, vocal fusion\na cappella, vocal jazz\na cappella, vocal jazz, Christmas\na cappella, vocal jazz, barbershop\na cappella, vocal jazz, theatrical\na cappella, vocal jazz, urban\na cappella, vocal jazz, world fusion\na cappella, world fusion, gospel\na cappella, world music\na cappella, world music, vocal harmony\na cappella, wuxia ballad\nabstract beat\nabstract hip hop\nabstract hip-hop\nabstract hip-hop, chiptune, J-hip-hop\nacademic lecture\nacapella\nacapella R&B\nacapella R&B dancehall\nacapella ballad\nacapella beatbox\nacapella beatboxing\nacapella blues\nacapella comedy\nacapella country\nacapella dance\nacapella electronic pop\nacapella folk\nacapella funk\nacapella funk-rock\nacapella gospel\nacapella hip hop\nacapella hip-hop\nacapella novelty\nacapella pop\nacapella pop R&B\nacapella pop-R&B\nacapella pop-rock\nacapella rap\nacapella reggae\nacapella rock\nacapella soul\nacapella, Arabic music, vocal jazz\nacapella, Caribbean, choral\nacapella, South Asian fusion\nacapella, beatbox, UK rap\nacapella, beatbox, soul\nacapella, beatboxing, Portuguese soul\nacapella, hip hop\nacapella, soul, R&B\nacapella, theatrical, choral\nacapella, vocal beatboxing, hip hop\nacapella, vocal percussion, sea shanty\nacappella beatbox\naccordion\naccordion folk\naccordion funk\naccordion fusion\naccordion jazz fusion\naccordion music\naccordion music, European film score, whimsical\naccordion polka\naccordion pop\naccordion punk\naccordion rock\naccordion solo\naccordion tango\naccordion virtuosity\naccordion virtuoso\naccordion waltz\naccordion, Balkan, funk\naccordion, European, playful\naccordion, European, whimsical\naccordion, Latin, festive\naccordion, balkan folk, progressive rock\naccordion, big band, theatrical\naccordion, chiptune, oompah\naccordion, circus music, playful\naccordion, circus music, polka\naccordion, comedic, European\naccordion, cumbia, musette\naccordion, cumbia, polka\naccordion, folk, Latin\naccordion, folk, polka\naccordion, forró, high-energy\naccordion, forró, polka\naccordion, klezmer, musette\naccordion, musette, klezmer\naccordion, polka, cumbia\naccordion, polka, electronic\naccordion, polka, funk\naccordion, polka, klezmer\naccordion, polka, musette\naccordion, polka, norteño\naccordion, polka, tango\naccordion, tango nova, Parisian cafe\naccordion, tango, cumbia\naccordion, tango, musette\naccordion, waltz, European\naccordion, whimsical, cartoon\naccordion-driven folk\nacid breakbeat\nacid drum and bass\nacid electro\nacid funk\nacid house\nacid house electro\nacid house electro-pop\nacid house funk breakbeat\nacid house techno\nacid house, French house, synth-pop\nacid house, big beat, drum and bass\nacid house, big beat, retro-futuristic\nacid house, breakcore, experimental electronic\nacid house, dangdut koplo\nacid house, hard techno\nacid house, techno\nacid jazz\nacid jazz R&B\nacid jazz bossa nova\nacid jazz chill-out\nacid jazz chillout\nacid jazz city pop\nacid jazz conscious hip-hop\nacid jazz deep house\nacid jazz funk\nacid jazz funk chiptune\nacid jazz funk disco\nacid jazz funk fusion\nacid jazz funk hip-hop\nacid jazz funk house\nacid jazz funk lo-fi hip-hop\nacid jazz funk lounge\nacid jazz funk neo-soul\nacid jazz funk pop\nacid jazz funk rock\nacid jazz funk soul\nacid jazz funk world music\nacid jazz funk-hop\nacid jazz funk-house\nacid jazz funk-pop\nacid jazz funk-rap\nacid jazz funk-rock\nacid jazz hip-hop\nacid jazz latin fusion\nacid jazz lo-fi\nacid jazz lo-fi hip hop\nacid jazz lounge\nacid jazz lounge chill-out\nacid jazz lounge funk\nacid jazz lounge house\nacid jazz lounge neo-soul\nacid jazz lounge-pop\nacid jazz neo-soul\nacid jazz neo-soul Latin\nacid jazz neo-soul cinematic\nacid jazz neo-soul funk-rock\nacid jazz neo-soul lo-fi hip-hop\nacid jazz neo-soul lounge\nacid jazz nu-jazz\nacid jazz smooth funk\nacid jazz smooth jazz\nacid jazz soul\nacid jazz soul latin\nacid jazz soulful house\nacid jazz trip-hop\nacid jazz trip-hop lounge\nacid jazz, Brazilian pop\nacid jazz, French pop\nacid jazz, French pop, cinematic orchestral\nacid jazz, G-funk, hip-hop\nacid jazz, R&B\nacid jazz, city pop\nacid jazz, complextro\nacid jazz, conscious hip-hop\nacid jazz, downtempo, trip-hop\nacid jazz, drum and bass\nacid jazz, funk, Middle Eastern fusion\nacid jazz, funk, cinematic\nacid jazz, funk, free jazz\nacid jazz, funk, instrumental\nacid jazz, funk, noir-jazz\nacid jazz, funk, trip-hop\nacid jazz, funky house, tech house\nacid jazz, golden-age hip-hop\nacid jazz, golden-age hip-hop, funk-rap\nacid jazz, lo-fi trip-hop\nacid jazz, lounge jazz\nacid jazz, neo-soul\nacid jazz, neo-soul, boom-bap\nacid jazz, neo-soul, funk\nacid jazz, neo-soul, hip-hop\nacid jazz, neo-soul, lo-fi\nacid jazz, new jack swing\nacid jazz, nu-jazz, hip-hop\nacid jazz, old-school hip-hop\nacid jazz, pop-rock\nacid jazz, smooth R&B\nacid jazz, smooth funk\nacid jazz, smooth jazz\nacid jazz, smooth jazz, funk\nacid jazz, trip-hop\nacid jazz, trip-hop, boom-bap\nacid jazz, trip-hop, hip-hop\nacid jazz, trip-hop, instrumental hip-hop\nacid jazz, trip-hop, orchestral\nacid rock\nacid techno\nacid techno funk jazz\nacid techno, breakbeat, IDM\nacid techno, cinematic, electronic\nacid techno, cinematic, glitch\nacid techno, electro, video game music\nacid techno, progressive trance\nacid techno, psytrance\nacid trance\nacid-jazz\nacid-pop\nacoustic\nacoustic C-pop\nacoustic C-pop hip-hop\nacoustic C-pop lo-fi hip-hop\nacoustic C-pop rap\nacoustic Christian\nacoustic Christian rock\nacoustic Christmas\nacoustic Christmas ballad\nacoustic EDM\nacoustic German pop\nacoustic Hawaiian\nacoustic Italian folk\nacoustic J-pop\nacoustic J-rock\nacoustic Javanese ballad\nacoustic K-pop\nacoustic Latin\nacoustic Latin R&B\nacoustic Latin ballad\nacoustic Latin folk\nacoustic Latin pop\nacoustic Latin rock\nacoustic R&B\nacoustic R&B Mandopop\nacoustic R&B hip-hop\nacoustic R&B lo-fi\nacoustic R&B lo-fi hip hop\nacoustic R&B lo-fi hip-hop\nacoustic R&B pop\nacoustic R&B trap\nacoustic R&B, K-pop\nacoustic R&B, dance-pop\nacoustic R&B, hip-hop\nacoustic R&B, lo-fi hip-hop, modern hip-hop\nacoustic R&B, modern R&B\nacoustic Spanish\nacoustic Tamil\nacoustic ambient\nacoustic anthem\nacoustic art-pop\nacoustic ballad\nacoustic ballad Indian fusion\nacoustic ballad alt-rock\nacoustic ballad alternative rock\nacoustic ballad cumbia\nacoustic ballad flamenco\nacoustic ballad folk-rock\nacoustic ballad funk-pop\nacoustic ballad garage punk\nacoustic ballad ghazal\nacoustic ballad gospel\nacoustic ballad hip-hop\nacoustic ballad hip-hop crossover\nacoustic ballad hip-hop fusion\nacoustic ballad indie rock\nacoustic ballad jazz-funk\nacoustic ballad lo-fi hip hop\nacoustic ballad lo-fi hip-hop\nacoustic ballad metalcore\nacoustic ballad pop-rap crossover\nacoustic ballad pop-rock\nacoustic ballad post-rock\nacoustic ballad punk rock\nacoustic ballad reggae\nacoustic ballad rock\nacoustic ballad rumba\nacoustic ballad soft rock\nacoustic ballad trap R&B\nacoustic ballad worship\nacoustic ballad, Axé\nacoustic ballad, Bollywood\nacoustic ballad, Brazilian funk carioca\nacoustic ballad, Brazilian pop-rock\nacoustic ballad, Indian classical, folk fusion\nacoustic ballad, Indian classical, melancholic\nacoustic ballad, Indian classical, romantic\nacoustic ballad, Indian folk, Sufi\nacoustic ballad, Indian folk, ghazal\nacoustic ballad, Indian folk, indie pop\nacoustic ballad, Indian pop, ghazal\nacoustic ballad, J-rock\nacoustic ballad, J-rock, ambient\nacoustic ballad, K-pop, empowering anthem\nacoustic ballad, Latin fusion, theatrical pop\nacoustic ballad, Latin jazz, Bossa Nova\nacoustic ballad, Latin pop\nacoustic ballad, Latin pop, Indian folk\nacoustic ballad, Latin pop, cinematic\nacoustic ballad, Latin pop-rock\nacoustic ballad, Latin rumba\nacoustic ballad, Mandarin folk, cinematic\nacoustic ballad, Middle Eastern, Bengali\nacoustic ballad, Middle Eastern, flamenco\nacoustic ballad, R&B\nacoustic ballad, R&B trap\nacoustic ballad, R&B, hard rock\nacoustic ballad, R&B, trap\nacoustic ballad, R&B/funk\nacoustic ballad, South Asian folk\nacoustic ballad, South Asian folk, ghazal\nacoustic ballad, South Asian, Middle Eastern\nacoustic ballad, South Asian, cinematic\nacoustic ballad, South Asian, melancholic\nacoustic ballad, South Asian, melodic\nacoustic ballad, Spanish influence, Hindi folk\nacoustic ballad, Turkish folk, ambient\nacoustic ballad, Turkish pop, Spanish guitar\nacoustic ballad, alt-rock\nacoustic ballad, alt-rock, indie rap\nacoustic ballad, alt-rock, melancholic\nacoustic ballad, alternative rock\nacoustic ballad, alternative rock, Mandarin indie\nacoustic ballad, alternative rock, Vocaloid\nacoustic ballad, alternative rock, flamenco\nacoustic ballad, anthemic rock, cinematic\nacoustic ballad, arena rock\nacoustic ballad, arena rock, 80s rock\nacoustic ballad, arena rock, blues rock\nacoustic ballad, arena rock, emotional rock\nacoustic ballad, arena rock, shred guitar\nacoustic ballad, art-pop\nacoustic ballad, atmospheric rock\nacoustic ballad, big band\nacoustic ballad, blues, Russian bard\nacoustic ballad, blues-rock, pop-rock\nacoustic ballad, cinematic rock\nacoustic ballad, cinematic rock, Mandarin pop\nacoustic ballad, cinematic, C-pop\nacoustic ballad, cinematic, Christmas\nacoustic ballad, cinematic, Hawaiian\nacoustic ballad, classic rock\nacoustic ballad, cumbia\nacoustic ballad, dance-pop\nacoustic ballad, dance-pop, gospel\nacoustic ballad, dream pop, rock\nacoustic ballad, emo rock\nacoustic ballad, emotional rock\nacoustic ballad, emotional rock, Mandarin pop\nacoustic ballad, emotional rock, melancholic\nacoustic ballad, epic pop-rock\nacoustic ballad, epic rock\nacoustic ballad, eurodance\nacoustic ballad, flamenco jazz\nacoustic ballad, flamenco, Anatolian folk\nacoustic ballad, flamenco, Latin pop\nacoustic ballad, flamenco, Mandarin pop\nacoustic ballad, flamenco, Punjabi folk\nacoustic ballad, flamenco, Turkish folk\nacoustic ballad, flamenco, indie folk\nacoustic ballad, folk, Central Asian\nacoustic ballad, folk, South Asian\nacoustic ballad, folk-rock, Punjabi pop\nacoustic ballad, forró\nacoustic ballad, free jazz, Latin pop\nacoustic ballad, funk pop-rock\nacoustic ballad, funk rock\nacoustic ballad, funk, Mandarin folk\nacoustic ballad, future bass, indie pop\nacoustic ballad, garage punk\nacoustic ballad, garage rock\nacoustic ballad, ghazal, Indian folk\nacoustic ballad, ghazal, ambient folk\nacoustic ballad, gospel rock\nacoustic ballad, gospel, R&B\nacoustic ballad, gospel, spiritual\nacoustic ballad, hard rock\nacoustic ballad, hard rock, alternative metal\nacoustic ballad, hard rock, anthemic rock\nacoustic ballad, hard rock, blues rock\nacoustic ballad, hard rock, classic rock\nacoustic ballad, hard rock, emotional\nacoustic ballad, hard rock, melodic rock\nacoustic ballad, hard rock, rock\nacoustic ballad, hard rock, soulful vocals\nacoustic ballad, heavy metal\nacoustic ballad, heavy rock\nacoustic ballad, hip-hop\nacoustic ballad, hip-hop, J-pop\nacoustic ballad, hip-hop, pop-rap\nacoustic ballad, indie folk, bilingual\nacoustic ballad, indie rock\nacoustic ballad, indie rock, Hindi folk\nacoustic ballad, industrial rock\nacoustic ballad, jazz, cinematic\nacoustic ballad, jazz, tango\nacoustic ballad, lo-fi hip hop\nacoustic ballad, lo-fi hip hop, C-pop\nacoustic ballad, lo-fi hip hop, indie folk\nacoustic ballad, lo-fi hip-hop, Mandarin pop\nacoustic ballad, lo-fi, indie folk\nacoustic ballad, nu-metal\nacoustic ballad, orchestral rock\nacoustic ballad, pop R&B\nacoustic ballad, pop-R&B\nacoustic ballad, pop-punk\nacoustic ballad, pop-punk, alternative rock\nacoustic ballad, pop-punk, emo-rock\nacoustic ballad, pop-rock\nacoustic ballad, pop-rock, Brazilian\nacoustic ballad, pop-rock, C-pop\nacoustic ballad, pop-rock, Chinese folk\nacoustic ballad, pop-rock, Javanese folk\nacoustic ballad, pop-rock, K-pop\nacoustic ballad, pop-rock, Latin soul\nacoustic ballad, pop-rock, Mandarin\nacoustic ballad, pop-rock, Mandarin folk\nacoustic ballad, pop-rock, Mandarin pop\nacoustic ballad, pop-rock, Mandopop\nacoustic ballad, pop-rock, Thai indie\nacoustic ballad, pop-rock, anthemic rock\nacoustic ballad, pop-rock, blues-rock\nacoustic ballad, pop-rock, cinematic\nacoustic ballad, pop-rock, classical\nacoustic ballad, pop-rock, dance-pop, EDM, rock, folk\nacoustic ballad, pop-rock, emotional\nacoustic ballad, pop-rock, emotional rock\nacoustic ballad, pop-rock, folk rock\nacoustic ballad, pop-rock, folk-pop\nacoustic ballad, pop-rock, funk\nacoustic ballad, pop-rock, live performance\nacoustic ballad, pop-rock, melancholic\nacoustic ballad, pop-rock, rock anthem\nacoustic ballad, pop-rock, sentimental\nacoustic ballad, post-rock\nacoustic ballad, post-rock, Mandarin rock\nacoustic ballad, post-rock, Spanish folk\nacoustic ballad, post-rock, blues\nacoustic ballad, post-rock, indie rock\nacoustic ballad, post-rock, shoegaze\nacoustic ballad, power ballad, Japanese pop\nacoustic ballad, power ballad, Mandarin rock\nacoustic ballad, power-pop\nacoustic ballad, progressive house, dance-pop\nacoustic ballad, punk rock\nacoustic ballad, rap-rock, cinematic\nacoustic ballad, reggae pop-rock\nacoustic ballad, reggaeton\nacoustic ballad, retro-funk, R&B\nacoustic ballad, rock anthem\nacoustic ballad, rock anthem, Cantonese pop\nacoustic ballad, rock anthem, Hindi folk\nacoustic ballad, rock anthem, Mandarin folk\nacoustic ballad, rock anthem, Mandarin pop\nacoustic ballad, rock anthem, Mandopop\nacoustic ballad, rock anthem, South Asian folk\nacoustic ballad, rock anthem, cinematic\nacoustic ballad, rock anthem, hip-hop\nacoustic ballad, rock anthem, psychedelic rock\nacoustic ballad, rock ballad\nacoustic ballad, rock instrumental\nacoustic ballad, rock opera, emotional\nacoustic ballad, rock, Italian pop\nacoustic ballad, rock, Mandarin folk\nacoustic ballad, rock, Mandarin indie\nacoustic ballad, rock, Mandarin pop\nacoustic ballad, rock, Portuguese folk\nacoustic ballad, rock, Spanish folk\nacoustic ballad, rock, bilingual\nacoustic ballad, rock, blues\nacoustic ballad, rock, cinematic\nacoustic ballad, rock, emotional\nacoustic ballad, rock, flamenco\nacoustic ballad, rock, hard rock\nacoustic ballad, rock, jazz fusion\nacoustic ballad, rock, live performance\nacoustic ballad, rock, power ballad\nacoustic ballad, samba pop-rock\nacoustic ballad, sertanejo\nacoustic ballad, shoegaze, psychedelic\nacoustic ballad, slap house, electronic\nacoustic ballad, soft rock\nacoustic ballad, soft rock, Spanish folk\nacoustic ballad, soft rock, blues rock\nacoustic ballad, soft rock, hard rock\nacoustic ballad, soft rock, lounge\nacoustic ballad, soulful pop, bluesy jazz\nacoustic ballad, stadium rock\nacoustic ballad, synth-pop\nacoustic ballad, theatrical metal\nacoustic ballad, theatrical rock\nacoustic ballad, thrash metal\nacoustic ballad, trap R&B\nacoustic ballad, trap R&B, ambient\nacoustic ballad, trap, Mandarin pop\nacoustic ballad, trap-pop\nacoustic ballad, trip-hop, ambient\nacoustic ballad, tropical house, dance-pop\nacoustic ballad, world fusion, Indian pop\nacoustic ballad, world music, cinematic\nacoustic ballad, world music, folk\nacoustic bass\nacoustic blues\nacoustic blues bossa nova\nacoustic blues funk\nacoustic blues rock\nacoustic blues rockabilly\nacoustic blues, indie rock\nacoustic blues-folk\nacoustic blues-rock\nacoustic body percussion\nacoustic bolero\nacoustic bossa nova\nacoustic cabaret\nacoustic cello\nacoustic chamber\nacoustic chanson\nacoustic chant\nacoustic chillhop\nacoustic choir\nacoustic christmas\nacoustic cinematic\nacoustic comedy\nacoustic comedy cabaret\nacoustic comedy folk\nacoustic comedy rap\nacoustic comedy rock\nacoustic comedy-rock\nacoustic corrido\nacoustic country\nacoustic country-blues\nacoustic country-folk\nacoustic country-pop\nacoustic country-rap\nacoustic country-rock\nacoustic cover\nacoustic crooner\nacoustic cumbia\nacoustic dance\nacoustic dance-pop\nacoustic dancehall\nacoustic devotional\nacoustic disco\nacoustic drama\nacoustic dream\nacoustic dream pop\nacoustic drum\nacoustic drum break\nacoustic drum fill\nacoustic drum groove\nacoustic drum kit\nacoustic drum loop\nacoustic drum solo\nacoustic drumming\nacoustic duet\nacoustic duet bluegrass\nacoustic duet flamenco\nacoustic duet rock\nacoustic duet rock ballad\nacoustic duet, Latin pop, reggae\nacoustic duet, flamenco, Middle Eastern\nacoustic duet, folk-pop, Latin guitar\nacoustic duet, world music, singer-songwriter\nacoustic duo\nacoustic electronica\nacoustic emo\nacoustic emo rap\nacoustic emo-pop\nacoustic emo-rap\nacoustic fingerpicking\nacoustic fingerstyle\nacoustic flamenco\nacoustic folk\nacoustic folk Afro-Latin\nacoustic folk Latin\nacoustic folk MPB\nacoustic folk alternative rock\nacoustic folk blues-rock\nacoustic folk chillwave\nacoustic folk comedy\nacoustic folk country\nacoustic folk doom metal\nacoustic folk flamenco\nacoustic folk funk flamenco\nacoustic folk gospel\nacoustic folk hip-hop\nacoustic folk hymn\nacoustic folk indie rock\nacoustic folk indie-pop\nacoustic folk klezmer\nacoustic folk lo-fi\nacoustic folk lo-fi hip-hop\nacoustic folk noise-rock\nacoustic folk pop-rap\nacoustic folk pop-rock\nacoustic folk post-hardcore\nacoustic folk post-rock\nacoustic folk progressive rock\nacoustic folk protest\nacoustic folk punk\nacoustic folk rap\nacoustic folk reggae\nacoustic folk rock\nacoustic folk screamo\nacoustic folk shoegaze\nacoustic folk soul\nacoustic folk tango\nacoustic folk trap\nacoustic folk world music\nacoustic folk worship\nacoustic folk, 90s alternative rock\nacoustic folk, African gospel\nacoustic folk, C-pop, lo-fi hip-hop\nacoustic folk, Chinese hip-hop\nacoustic folk, Christian rock\nacoustic folk, EBM\nacoustic folk, European cabaret, chanson\nacoustic folk, German hip-hop\nacoustic folk, Indian film music\nacoustic folk, J-pop, rock\nacoustic folk, J-rock\nacoustic folk, Latin folk\nacoustic folk, Latin fusion\nacoustic folk, Middle Eastern, Anatolian\nacoustic folk, Vocaloid\nacoustic folk, alt-rock\nacoustic folk, alternative pop-rock, conscious hip-hop\nacoustic folk, alternative rock\nacoustic folk, alternative rock, ambient\nacoustic folk, alternative rock, blues rock\nacoustic folk, alternative rock, blues-rock\nacoustic folk, alternative rock, emo\nacoustic folk, alternative rock, hard rock\nacoustic folk, alternative rock, industrial metal\nacoustic folk, alternative rock, instrumental shred\nacoustic folk, alternative rock, post-grunge\nacoustic folk, alternative rock, post-hardcore\nacoustic folk, alternative rock, shoegaze\nacoustic folk, arena rock\nacoustic folk, big band\nacoustic folk, big band swing\nacoustic folk, bluegrass\nacoustic folk, blues-rock\nacoustic folk, boom-bap hip-hop\nacoustic folk, chamber pop\nacoustic folk, cinematic\nacoustic folk, cinematic rock\nacoustic folk, cinematic rock, Chinese fusion\nacoustic folk, cinematic rock, progressive rock\nacoustic folk, cinematic, Hebrew\nacoustic folk, cinematic, electronic\nacoustic folk, cinematic, world music\nacoustic folk, classic rock\nacoustic folk, classic rock, blues rock\nacoustic folk, conscious hip-hop\nacoustic folk, conscious hip-hop, spoken word\nacoustic folk, contemporary Christian\nacoustic folk, contemporary Christian, French chanson\nacoustic folk, contemporary Christian, Hawaiian\nacoustic folk, contemporary R&B\nacoustic folk, contemporary gospel\nacoustic folk, country-rock, Americana\nacoustic folk, dance-rock\nacoustic folk, dark ambient, downtempo\nacoustic folk, electronic, ambient\nacoustic folk, epic rock\nacoustic folk, epic rock, ambient\nacoustic folk, flamenco, C-pop\nacoustic folk, flamenco, Latin\nacoustic folk, flamenco, indie rock\nacoustic folk, folk-rock\nacoustic folk, funk-pop\nacoustic folk, garage rock\nacoustic folk, gospel rock\nacoustic folk, hard rock\nacoustic folk, heavy metal\nacoustic folk, hip-hop\nacoustic folk, indie rock\nacoustic folk, lo-fi hip hop\nacoustic folk, lo-fi hip-hop\nacoustic folk, melodic hip-hop\nacoustic folk, melodic metal\nacoustic folk, narrative hip-hop\nacoustic folk, neo-soul\nacoustic folk, neo-soul, breakcore\nacoustic folk, neo-soul, conscious hip-hop\nacoustic folk, new age\nacoustic folk, new age, world music\nacoustic folk, new-age, spiritual\nacoustic folk, noise rock\nacoustic folk, piano ballad, synth-pop\nacoustic folk, pop-punk\nacoustic folk, pop-rap, C-pop\nacoustic folk, pop-rock\nacoustic folk, pop-rock, cinematic\nacoustic folk, pop-rock, novelty\nacoustic folk, post-hardcore\nacoustic folk, post-hardcore, cinematic\nacoustic folk, post-hardcore, emo\nacoustic folk, post-rock\nacoustic folk, post-rock, ambient\nacoustic folk, post-rock, rock\nacoustic folk, post-rock, shoegaze\nacoustic folk, power ballad\nacoustic folk, power-pop\nacoustic folk, psychedelic rock\nacoustic folk, psychedelic rock, blues-rock\nacoustic folk, punk rock\nacoustic folk, rock\nacoustic folk, rock, cinematic\nacoustic folk, roots rock\nacoustic folk, shoegaze\nacoustic folk, shoegaze, C-pop\nacoustic folk, shoegaze, noise rock\nacoustic folk, shoegaze, post-rock\nacoustic folk, smooth jazz, new age\nacoustic folk, soft rock, gospel\nacoustic folk, soft rock, psychedelic rock\nacoustic folk, soul, conscious hip-hop\nacoustic folk, soulful pop, zouk\nacoustic folk, spoken word hip-hop\nacoustic folk, stadium rock\nacoustic folk, synth-pop\nacoustic folk, thrash metal\nacoustic folk, world music\nacoustic folk, world music, Bongo Flava\nacoustic folk, world music, French chanson\nacoustic folk, world music, ambient\nacoustic folk, world music, bossa nova\nacoustic folk, world music, island style\nacoustic folk, zouk, gospel\nacoustic folk-blues\nacoustic folk-country\nacoustic folk-fusion\nacoustic folk-gospel\nacoustic folk-pop\nacoustic folk-pop lo-fi hip-hop\nacoustic folk-punk\nacoustic folk-rap\nacoustic folk-reggae\nacoustic folk-rock\nacoustic folk-rock, alternative metal\nacoustic folk-rock, post-metal\nacoustic folk-soul\nacoustic funk\nacoustic funk blues\nacoustic funk hip-hop\nacoustic funk rock\nacoustic funk soul\nacoustic funk, Latin jazz, world music\nacoustic funk-blues\nacoustic funk-pop\nacoustic funk-rock\nacoustic fusion\nacoustic fusion dubstep\nacoustic ghazal\nacoustic gospel\nacoustic gospel country\nacoustic gospel folk\nacoustic groove\nacoustic grunge\nacoustic guitar\nacoustic guitar duet\nacoustic guitar duo\nacoustic guitar fusion\nacoustic guitar, Latin, Spanish\nacoustic guitar, Latin, cheerful\nacoustic guitar, Latin, instrumental\nacoustic guitar, Latin, melancholic\nacoustic guitar, Latin, upbeat\nacoustic guitar, Spanish folk, Latin folk\nacoustic guitar, Spanish style, Latin\nacoustic guitar, Spanish, rhythmic\nacoustic guitar, Spanish-influenced, melancholic\nacoustic guitar, blues rock, Latin\nacoustic guitar, blues-rock, Spanish-influenced\nacoustic guitar, cinematic, Latin\nacoustic guitar, classical, Christmas\nacoustic guitar, corrido, ranchera\nacoustic guitar, epic, mystical\nacoustic guitar, flamenco, Latin\nacoustic guitar, flamenco, Latin folk\nacoustic guitar, flamenco, ambient\nacoustic guitar, flamenco, instrumental\nacoustic guitar, flamenco, latin\nacoustic guitar, flamenco, world music\nacoustic guitar, folk, latin\nacoustic guitar, hard rock\nacoustic guitar, hymn, Latin\nacoustic guitar, math rock, flamenco\nacoustic guitar, neoclassical, devotional\nacoustic guitar, new-age\nacoustic guitar, regional Mexican, urban pop\nacoustic guitar, rumba, Latin\nacoustic guitar, thrash metal\nacoustic gypsy jazz\nacoustic harp\nacoustic heartland rock\nacoustic hip hop\nacoustic hip-hop\nacoustic hip-hop J-pop\nacoustic hip-hop country-rock\nacoustic hip-hop emo-rap\nacoustic hip-hop indie pop\nacoustic hip-hop lo-fi\nacoustic hip-hop pop-rock\nacoustic hip-hop, cloud rap\nacoustic hip-hop, deep house, ambient\nacoustic hip-hop, romantic pop-rap\nacoustic holiday\nacoustic house\nacoustic hymn\nacoustic improvisation\nacoustic indie\nacoustic indie folk\nacoustic indie rock\nacoustic instrumental\nacoustic introspection\nacoustic introspection, doom metal, ambient piano\nacoustic introspective\nacoustic jam\nacoustic jazz\nacoustic jazz fusion\nacoustic jazz-pop\nacoustic jingle\nacoustic live\nacoustic lo-fi\nacoustic lo-fi hip hop\nacoustic lo-fi hip-hop\nacoustic loop\nacoustic lounge\nacoustic lullaby\nacoustic lullaby, atmospheric rock\nacoustic mandolin\nacoustic math\nacoustic math rock\nacoustic math-rock\nacoustic meditation\nacoustic medley\nacoustic melancholic\nacoustic melancholy\nacoustic melancholy, hip-hop, cinematic ambient\nacoustic minimalism\nacoustic narrative\nacoustic neo-soul\nacoustic noir\nacoustic novelty\nacoustic nu-metal\nacoustic opera\nacoustic oud\nacoustic parody\nacoustic party anthem\nacoustic party-rock\nacoustic percussion\nacoustic piano\nacoustic piano ballad\nacoustic piano, Brazilian popular music, chanson\nacoustic piano, holiday, lullaby\nacoustic piano, melancholic, Portuguese vocal\nacoustic piano, romantic, nostalgic\nacoustic poetry\nacoustic pop\nacoustic pop Afro-pop Bossa Nova\nacoustic pop Afrobeats R&B\nacoustic pop Bollywood\nacoustic pop C-pop K-pop\nacoustic pop European folk\nacoustic pop Indian\nacoustic pop Indian film music\nacoustic pop Indian folk\nacoustic pop Indian fusion\nacoustic pop J-pop\nacoustic pop K-R&B\nacoustic pop K-pop\nacoustic pop K-pop ballad\nacoustic pop K-pop hip-hop\nacoustic pop Latin\nacoustic pop MPB\nacoustic pop OPM\nacoustic pop R&B\nacoustic pop R&B Afrobeats\nacoustic pop R&B Latin\nacoustic pop R&B dancehall\nacoustic pop R&B hip-hop\nacoustic pop R&B neo-soul\nacoustic pop R&B reggae\nacoustic pop R&B soul\nacoustic pop alternative rock\nacoustic pop blues\nacoustic pop blues swing\nacoustic pop bossa nova\nacoustic pop cabaret\nacoustic pop chanson\nacoustic pop chill hip-hop\nacoustic pop conscious hip-hop\nacoustic pop country\nacoustic pop dance-pop\nacoustic pop emo rap\nacoustic pop emo-pop\nacoustic pop emo-rap\nacoustic pop flamenco\nacoustic pop folk\nacoustic pop folk blues\nacoustic pop folk-country\nacoustic pop folk-pop\nacoustic pop folk-reggae\nacoustic pop funk\nacoustic pop funk R&B\nacoustic pop funk dancehall\nacoustic pop funk soul\nacoustic pop funk-pop\nacoustic pop fusion\nacoustic pop future bass\nacoustic pop gospel\nacoustic pop gypsy jazz\nacoustic pop hip-hop\nacoustic pop indie folk\nacoustic pop indie pop lo-fi hip-hop\nacoustic pop indie rock\nacoustic pop jazz\nacoustic pop jazz bossa nova\nacoustic pop lo-fi\nacoustic pop lo-fi R&B\nacoustic pop lo-fi bedroom pop\nacoustic pop lo-fi hip hop\nacoustic pop lo-fi hip-hop\nacoustic pop mandopop\nacoustic pop neo-soul\nacoustic pop progressive house\nacoustic pop reggae\nacoustic pop reggae Latin\nacoustic pop reggae fusion\nacoustic pop reggae jazz\nacoustic pop reggae ska\nacoustic pop reggae soul\nacoustic pop reggaeton\nacoustic pop retro video game\nacoustic pop rock\nacoustic pop sertanejo\nacoustic pop smooth jazz\nacoustic pop soul\nacoustic pop trap\nacoustic pop trap R&B\nacoustic pop trap-R&B\nacoustic pop tropical\nacoustic pop tropical folk\nacoustic pop tropical house\nacoustic pop tropical rock\nacoustic pop world music\nacoustic pop worship\nacoustic pop, Arabic pop, pop-rock\nacoustic pop, Bhangra\nacoustic pop, Bollywood, romantic\nacoustic pop, Brazilian MPB\nacoustic pop, Brazilian hip-hop\nacoustic pop, Brazilian pop, reggae fusion\nacoustic pop, Brazilian pop, reggaeton\nacoustic pop, C-pop, anime\nacoustic pop, C-pop, lo-fi hip hop\nacoustic pop, Central Asian folk\nacoustic pop, Christian hip-hop\nacoustic pop, EDM, house\nacoustic pop, Eurodance\nacoustic pop, European folk\nacoustic pop, European folk, Mandarin lullaby\nacoustic pop, Filipino hip-hop\nacoustic pop, Indian film music\nacoustic pop, Indian folk\nacoustic pop, Indian folk, folk-pop\nacoustic pop, Indian folk-pop, world music\nacoustic pop, Indian fusion, Western fusion\nacoustic pop, Indian pop, world music\nacoustic pop, J-rock\nacoustic pop, K-pop rock\nacoustic pop, K-pop, contemporary R&B\nacoustic pop, Korean R&B\nacoustic pop, Korean hip-hop\nacoustic pop, Korean hip-hop, R&B\nacoustic pop, Latin jazz\nacoustic pop, Latin pop\nacoustic pop, Latin pop, Bollywood\nacoustic pop, Latin pop, Indian classical\nacoustic pop, Latin pop, disco-pop\nacoustic pop, Latin pop, flamenco\nacoustic pop, Latin pop, reggaeton\nacoustic pop, Latin pop, tropical\nacoustic pop, Latin, Bollywood\nacoustic pop, Latin, cabaret\nacoustic pop, Latin, flamenco\nacoustic pop, MPB\nacoustic pop, Mandopop, lo-fi R&B\nacoustic pop, Punjabi hip-hop\nacoustic pop, R&B, Brazilian\nacoustic pop, R&B, Brazilian pop\nacoustic pop, R&B, Indian fusion\nacoustic pop, R&B, hip-hop\nacoustic pop, R&B, lo-fi hip hop\nacoustic pop, South Asian folk\nacoustic pop, South Asian fusion\nacoustic pop, alt-rock\nacoustic pop, alternative rock\nacoustic pop, bossa nova\nacoustic pop, bossa nova, Latin pop\nacoustic pop, bossa nova, latin pop\nacoustic pop, bossa nova, mandopop\nacoustic pop, cinematic pop-rock\nacoustic pop, cinematic, world music\nacoustic pop, comedy folk\nacoustic pop, conscious Latin hip-hop\nacoustic pop, conscious hip-hop\nacoustic pop, contemporary Christian\nacoustic pop, contemporary R&B\nacoustic pop, contemporary R&B, K-pop\nacoustic pop, dance-pop\nacoustic pop, eurodance\nacoustic pop, flamenco, melancholic\nacoustic pop, folk-pop, hip-hop\nacoustic pop, future bass\nacoustic pop, future bass, pop-rock\nacoustic pop, hardstyle, Mandarin pop\nacoustic pop, hip-hop\nacoustic pop, hip-hop, pop-rock\nacoustic pop, hyperpop, trap\nacoustic pop, indie folk, Bollywood\nacoustic pop, light R&B\nacoustic pop, lo-fi hip hop, Hindi indie\nacoustic pop, lo-fi hip hop, Russian romantic\nacoustic pop, lo-fi hip hop, V-Pop\nacoustic pop, lo-fi hip-hop\nacoustic pop, lo-fi hip-hop, R&B\nacoustic pop, melodic trap\nacoustic pop, modern pop, hip-hop\nacoustic pop, noise rock\nacoustic pop, pop R&B, electronic rock\nacoustic pop, pop-punk\nacoustic pop, pop-punk, J-rock\nacoustic pop, pop-punk, ambient\nacoustic pop, pop-rap, rock\nacoustic pop, pop-rock\nacoustic pop, pop-rock, Brazilian pop\nacoustic pop, pop-rock, J-rock\nacoustic pop, pop-rock, alternative rock\nacoustic pop, pop-rock, cinematic\nacoustic pop, pop/R&B, K-pop\nacoustic pop, progressive house\nacoustic pop, progressive house, hardstyle\nacoustic pop, rap rock, pop-rock\nacoustic pop, rap-rock, emotional rock\nacoustic pop, reggae, ska\nacoustic pop, reggaeton\nacoustic pop, reggaeton, Latin pop\nacoustic pop, regional hip-hop\nacoustic pop, romantic hip-hop\nacoustic pop, smooth jazz\nacoustic pop, soul, rock\nacoustic pop, synth-pop, 80s synth-pop\nacoustic pop, synth-pop, lo-fi\nacoustic pop, traditional East Asian\nacoustic pop, trap R&B\nacoustic pop, trap, hyperpop\nacoustic pop, world music\nacoustic pop, world music, South Asian ballad\nacoustic pop, zouk, kompa\nacoustic pop-R&B\nacoustic pop-R&B future bass\nacoustic pop-bhangra\nacoustic pop-country\nacoustic pop-folk\nacoustic pop-folk future bass\nacoustic pop-folk, funk pop-rock\nacoustic pop-folk, future bass\nacoustic pop-folk, happy hardcore\nacoustic pop-folk, pop-punk\nacoustic pop-folk, progressive house\nacoustic pop-funk\nacoustic pop-funk, R&B ballad\nacoustic pop-fusion\nacoustic pop-gospel\nacoustic pop-punk\nacoustic pop-punk, emo-pop\nacoustic pop-punk, emo-rap, post-hardcore\nacoustic pop-rap\nacoustic pop-rap, Bollywood fusion\nacoustic pop-rap, Latin pop, reggaeton\nacoustic pop-rap, dance-pop\nacoustic pop-reggae\nacoustic pop-rock\nacoustic pop-rock Bollywood\nacoustic pop-rock Indian folk\nacoustic pop-rock emo-rap\nacoustic pop-rock gypsy jazz\nacoustic pop-rock hip-hop\nacoustic pop-rock progressive house\nacoustic pop-rock reggae\nacoustic pop-rock worship\nacoustic pop-rock, Brazilian pop-rock\nacoustic pop-rock, J-rock\nacoustic pop-rock, Latin rumba, R&B/soul, power ballad\nacoustic pop-rock, T-Pop\nacoustic pop-rock, T-Pop, Eurodance\nacoustic pop-rock, electro-house\nacoustic pop-rock, future bass, hip-hop\nacoustic pop-rock, progressive house, EDM\nacoustic pop-rock, sertanejo\nacoustic pop-soul\nacoustic post-rock\nacoustic power ballad\nacoustic praise\nacoustic prayer\nacoustic progressive\nacoustic protest\nacoustic protest folk\nacoustic punk\nacoustic punk rock\nacoustic punk-folk\nacoustic punk-rap\nacoustic ragtime\nacoustic rap\nacoustic rap-rock\nacoustic reggae\nacoustic reggae R&B\nacoustic reggae folk\nacoustic reggae gospel\nacoustic reggae samba\nacoustic reggae ska\nacoustic reggae-pop\nacoustic reggaeton\nacoustic rock\nacoustic rock alternative hip-hop\nacoustic rock alternative metal\nacoustic rock alternative rock\nacoustic rock blues-rock\nacoustic rock country-folk\nacoustic rock emo\nacoustic rock emo rap\nacoustic rock emo-pop\nacoustic rock emo-punk\nacoustic rock emo-rap\nacoustic rock emo-rock\nacoustic rock flamenco\nacoustic rock folk\nacoustic rock folk-rock\nacoustic rock funk\nacoustic rock garage rock\nacoustic rock gospel\nacoustic rock grunge\nacoustic rock hip-hop\nacoustic rock indie folk\nacoustic rock indie rock\nacoustic rock metal\nacoustic rock metalcore\nacoustic rock pop-punk\nacoustic rock post-grunge\nacoustic rock post-hardcore\nacoustic rock post-rock\nacoustic rock progressive metal\nacoustic rock progressive rock\nacoustic rock punk\nacoustic rock punk rock\nacoustic rock rap\nacoustic rock reggae-rock\nacoustic rock thrash metal\nacoustic rock worship\nacoustic rock, Chinese folk, Latin\nacoustic rock, J-rock\nacoustic rock, MPB, protest music\nacoustic rock, Turkish folk\nacoustic rock, alt-rock, hard rock\nacoustic rock, alternative metal\nacoustic rock, alternative rock\nacoustic rock, alternative rock, post-hardcore\nacoustic rock, arena rock, hard rock\nacoustic rock, choral\nacoustic rock, classic rock\nacoustic rock, classic rock, blues-rock\nacoustic rock, conscious hip-hop\nacoustic rock, flamenco rock, hard rock\nacoustic rock, folk-rock, Latin folk\nacoustic rock, happy hardcore\nacoustic rock, happy hardcore, trance\nacoustic rock, hard rock\nacoustic rock, hard rock, Chinese rock\nacoustic rock, hard rock, French rock\nacoustic rock, hard rock, blues-rock\nacoustic rock, hard rock, flamenco rock\nacoustic rock, hard rock, folk-rock\nacoustic rock, hardstyle\nacoustic rock, heavy metal\nacoustic rock, metal, ambient\nacoustic rock, metalcore\nacoustic rock, pop-punk\nacoustic rock, pop-punk, flamenco\nacoustic rock, pop-rock, Christian rock\nacoustic rock, post-hardcore\nacoustic rock, post-hardcore, alternative metal\nacoustic rock, post-hardcore, metalcore\nacoustic rock, progressive metal\nacoustic rock, thrash metal\nacoustic romance\nacoustic roots\nacoustic rumba\nacoustic samba\nacoustic samba rock\nacoustic samba-reggae\nacoustic show tune\nacoustic shred\nacoustic singer-songwriter\nacoustic singer-songwriter emo-rock\nacoustic singer-songwriter hip-hop crossover\nacoustic singer-songwriter pop\nacoustic singer-songwriter rap-rock\nacoustic singer-songwriter, Afrobeats, conscious hip-hop\nacoustic singer-songwriter, alternative rock\nacoustic singer-songwriter, conscious hip-hop\nacoustic singer-songwriter, emo-rock\nacoustic singer-songwriter, hard rock\nacoustic singer-songwriter, lo-fi hip hop\nacoustic singer-songwriter, rap-rock\nacoustic sketch\nacoustic soft rock\nacoustic soul\nacoustic soul bossa nova\nacoustic soul calypso\nacoustic soul conscious hip-hop\nacoustic soul experimental hip-hop\nacoustic soul folk-pop\nacoustic soul funk-rock\nacoustic soul hip-hop\nacoustic soul indie folk\nacoustic soul lo-fi hip-hop\nacoustic soul neo-soul\nacoustic soul world music\nacoustic soul, French chanson\nacoustic soul, classic rock\nacoustic soul, conscious hip-hop\nacoustic soul, conscious hip-hop, gospel\nacoustic soul-pop\nacoustic soul-rock\nacoustic space rock\nacoustic spiritual\nacoustic storytelling\nacoustic swing\nacoustic tango\nacoustic theater\nacoustic trap\nacoustic trap soul\nacoustic ukulele\nacoustic violin\nacoustic virtuosity\nacoustic waltz\nacoustic whimsy\nacoustic world\nacoustic world fusion\nacoustic world gospel\nacoustic world music\nacoustic world-folk\nacoustic world-pop\nacoustic worship\nacoustic, African rumba, soukous\nacoustic, Afro-Spanish fusion\nacoustic, Americana, ambient\nacoustic, Arabic folk\nacoustic, Arabic folk, Spanish guitar\nacoustic, Arabic folk, Spanish-influenced\nacoustic, Arabic folk, indie\nacoustic, Arabic fusion, Latin\nacoustic, Arabic, ambient\nacoustic, Arabic, melancholic\nacoustic, Arabic, spiritual\nacoustic, Bollywood, Latin\nacoustic, Bossa Nova, Mandarin folk\nacoustic, Brazilian MPB\nacoustic, Brazilian ballad\nacoustic, Brazilian folk\nacoustic, Brazilian hip-hop\nacoustic, Brazilian pop\nacoustic, Brazilian pop, pagode\nacoustic, Brazilian, Afro-Cuban\nacoustic, Brazilian, Italian\nacoustic, Brazilian, Latin\nacoustic, Brazilian, classical\nacoustic, Brazilian, folk\nacoustic, Brazilian, funk\nacoustic, Brazilian, melancholic\nacoustic, Brazilian, rap\nacoustic, Brazilian, soul\nacoustic, Cantonese rap, Mandarin ballad\nacoustic, Caribbean, Latin\nacoustic, Caribbean, ambient\nacoustic, Caribbean, folk\nacoustic, Caribbean, soulful\nacoustic, Caribbean, zouk\nacoustic, Christmas, duet\nacoustic, Christmas, folk\nacoustic, Christmas, hymnal\nacoustic, Christmas, jazz\nacoustic, Christmas, lullaby\nacoustic, European cafe, melancholic\nacoustic, Farsi, flamenco\nacoustic, French chanson, Latin folk\nacoustic, French folk\nacoustic, French folk, dramatic\nacoustic, French pop, flamenco\nacoustic, French pop, folk\nacoustic, French rap, lo-fi\nacoustic, Haitian Creole, folk\nacoustic, Hawaiian, folk\nacoustic, Hawaiian, spiritual\nacoustic, Hindi folk\nacoustic, Indian classical, ambient\nacoustic, Indian classical, cinematic\nacoustic, Indian classical, devotional\nacoustic, Indian classical, folk\nacoustic, Indian classical, ghazal\nacoustic, Indian classical, melancholic\nacoustic, Indian folk\nacoustic, Indian folk, ambient\nacoustic, Indian folk, introspective\nacoustic, Italian folk\nacoustic, Japanese folk\nacoustic, Japanese folk, lo-fi\nacoustic, Javanese, flamenco\nacoustic, Javanese, melancholic\nacoustic, K-pop, indie folk\nacoustic, Korean folk\nacoustic, Korean folk, ambient\nacoustic, Latin blues, folk\nacoustic, Latin folk\nacoustic, Latin folk, indie\nacoustic, Latin groove, folk soul\nacoustic, Latin jazz\nacoustic, Latin jazz, flamenco\nacoustic, Latin pop\nacoustic, Latin pop, R&B\nacoustic, Latin pop, sunshine pop\nacoustic, Latin, Afro-Caribbean\nacoustic, Latin, French chanson\nacoustic, Latin, French pop\nacoustic, Latin, Hawaiian\nacoustic, Latin, Italian folk\nacoustic, Latin, Japanese folk\nacoustic, Latin, Mediterranean\nacoustic, Latin, Russian folk\nacoustic, Latin, Tatar folk\nacoustic, Latin, ambient\nacoustic, Latin, bilingual\nacoustic, Latin, blues\nacoustic, Latin, cheerful\nacoustic, Latin, chill\nacoustic, Latin, cinematic\nacoustic, Latin, classical\nacoustic, Latin, comedy\nacoustic, Latin, feel-good\nacoustic, Latin, fingerstyle\nacoustic, Latin, flamenco\nacoustic, Latin, folk\nacoustic, Latin, hip-hop\nacoustic, Latin, indie folk\nacoustic, Latin, inspirational\nacoustic, Latin, instrumental\nacoustic, Latin, lo-fi\nacoustic, Latin, melancholic\nacoustic, Latin, quirky\nacoustic, Latin, soul\nacoustic, Latin, spiritual\nacoustic, Latin, spoken word\nacoustic, Latin, tango\nacoustic, Latin, theatrical\nacoustic, Latin, tropical\nacoustic, Latin, whimsical\nacoustic, Latin, world\nacoustic, Latin, world music\nacoustic, Latin-inspired, quirky\nacoustic, Latin-inspired, upbeat\nacoustic, MPB\nacoustic, MPB, ambient\nacoustic, MPB, spiritual\nacoustic, Mandarin folk\nacoustic, Mandarin indie\nacoustic, Mandarin, melancholic\nacoustic, Mediterranean, Latin\nacoustic, Mediterranean, Persian folk\nacoustic, Mediterranean, folk\nacoustic, Mediterranean, melancholic\nacoustic, Middle Eastern, Andalusian\nacoustic, Middle Eastern, ambient\nacoustic, Middle Eastern, flamenco\nacoustic, Middle Eastern, folk\nacoustic, Middle Eastern, spiritual\nacoustic, New Orleans, groove\nacoustic, Persian folk, indie\nacoustic, Persian, folk\nacoustic, Persian, melancholic\nacoustic, Portuguese folk\nacoustic, Punjabi, R&B\nacoustic, Punjabi, folk\nacoustic, R&B, Latin\nacoustic, R&B, bossa nova\nacoustic, R&B, indie folk\nacoustic, Russian folk, raw\nacoustic, Sinhala folk\nacoustic, Spanish folk\nacoustic, Spanish folk, breezy\nacoustic, Spanish folk, requinto\nacoustic, Spanish lullaby\nacoustic, Spanish style\nacoustic, Spanish style, melancholic\nacoustic, Spanish-influenced, emotional\nacoustic, Spanish-influenced, folk\nacoustic, Spanish-influenced, indie folk\nacoustic, Spanish-influenced, soulful\nacoustic, Sundanese folk\nacoustic, Swahili folk\nacoustic, Swahili rap, R&B\nacoustic, Swedish folk\nacoustic, Tamil folk\nacoustic, Tamil folk, ambient\nacoustic, Tamil folk, flamenco\nacoustic, Tamil folk, indie\nacoustic, Tamil folk, introspective\nacoustic, Thai folk\nacoustic, Thai folk, lo-fi\nacoustic, Turkish folk\nacoustic, Turkish folk, flamenco\nacoustic, Turkish folk, introspective\nacoustic, Vietnamese folk\nacoustic, Vocaloid\nacoustic, Vocaloid, Japanese pop\nacoustic, Vocaloid, ambient\nacoustic, West African folk\nacoustic, West African, folk\nacoustic, Zulu folk\nacoustic, a cappella, Christmas\nacoustic, ambient, Arabic folk\nacoustic, ambient, Chinese folk\nacoustic, ambient, Christmas\nacoustic, ambient, Indian classical\nacoustic, ambient, Indian folk\nacoustic, ambient, Italian folk\nacoustic, ambient, Japanese folk\nacoustic, ambient, Japanese lullaby\nacoustic, ambient, Latin\nacoustic, ambient, Mandopop\nacoustic, ambient, Portuguese folk\nacoustic, ambient, Russian folk\nacoustic, ambient, Sinhala folk\nacoustic, ambient, South Asian\nacoustic, ambient, Spanish ballad\nacoustic, ambient, Spanish folk\nacoustic, ambient, Thai folk\nacoustic, ambient, bossa nova\nacoustic, ambient, cinematic\nacoustic, ambient, filipino folk\nacoustic, ambient, flamenco\nacoustic, ambient, folk\nacoustic, ambient, indie folk\nacoustic, ambient, lo-fi\nacoustic, bansuri, melancholic\nacoustic, baroque, choral\nacoustic, beach, Latin folk\nacoustic, beatbox, folk rock\nacoustic, bilingual, flamenco\nacoustic, bilingual, folk\nacoustic, bilingual, indie folk\nacoustic, bluegrass, newgrass\nacoustic, blues, Italian folk\nacoustic, blues, folk\nacoustic, bossa nova\nacoustic, bossa nova, Arabic folk\nacoustic, bossa nova, French chanson\nacoustic, bossa nova, French folk\nacoustic, bossa nova, French pop\nacoustic, bossa nova, Japanese folk\nacoustic, bossa nova, Latin\nacoustic, bossa nova, Latin folk\nacoustic, bossa nova, Mandarin folk\nacoustic, bossa nova, Portuguese folk\nacoustic, bossa nova, Turkish folk\nacoustic, bossa nova, ambient\nacoustic, bossa nova, cafe music\nacoustic, bossa nova, flamenco\nacoustic, bossa nova, folk\nacoustic, bossa nova, french chanson\nacoustic, bossa nova, indie folk\nacoustic, bossa nova, instrumental\nacoustic, bossa nova, introspective\nacoustic, bossa nova, jazz\nacoustic, bossa nova, korean folk\nacoustic, bossa nova, latin\nacoustic, bossa nova, live\nacoustic, bossa nova, lo-fi\nacoustic, bossa nova, melancholic\nacoustic, bossa nova, mpb\nacoustic, bossa nova, playful\nacoustic, bossa nova, romantic\nacoustic, bossa nova, singer-songwriter\nacoustic, bossa nova, soul\nacoustic, bossa nova, spiritual\nacoustic, bossa nova, spoken word\nacoustic, bossa nova, theatrical\nacoustic, bossa nova, whimsical\nacoustic, bossa nova, world\nacoustic, bossa nova, world music\nacoustic, cabaret, folk\nacoustic, cafe music, European\nacoustic, candombe, folk\nacoustic, cello, Mandarin\nacoustic, cello, Mandarin folk\nacoustic, cello, Mandarin vocal\nacoustic, chanson, Latin ballad\nacoustic, chanson, melancholic\nacoustic, chanson, rap\nacoustic, chant, world music\nacoustic, children's music\nacoustic, children's music, educational\nacoustic, choir, Latin\nacoustic, choral, Christmas\nacoustic, choral, Spanish style\nacoustic, choral, ambient\nacoustic, choral, cinematic\nacoustic, choral, classical\nacoustic, choral, folk\nacoustic, choral, inspirational\nacoustic, choral, jazz\nacoustic, choral, pastoral\nacoustic, choral, traditional\nacoustic, choral, world music\nacoustic, choro, French pop\nacoustic, christmas, ambient\nacoustic, christmas, choir\nacoustic, christmas, hymn\nacoustic, christmas, orchestral\nacoustic, cinematic\nacoustic, cinematic, Christmas\nacoustic, cinematic, French folk\nacoustic, cinematic, Hindi folk\nacoustic, cinematic, Italian spoken word\nacoustic, cinematic, Japanese folk\nacoustic, cinematic, Korean indie\nacoustic, cinematic, Portuguese\nacoustic, cinematic, Portuguese folk\nacoustic, cinematic, Tamil folk\nacoustic, cinematic, ambient\nacoustic, cinematic, bossa nova\nacoustic, cinematic, choral\nacoustic, cinematic, devotional\nacoustic, cinematic, dramatic\nacoustic, cinematic, holiday\nacoustic, cinematic, hopeful\nacoustic, cinematic, lo-fi\nacoustic, cinematic, melancholic\nacoustic, cinematic, soul\nacoustic, cinematic, tango\nacoustic, cinematic, theatrical\nacoustic, cinematic, uplifting\nacoustic, cinematic, waltz\nacoustic, cinematic, world\nacoustic, cinematic, world fusion\nacoustic, classical, Brazilian\nacoustic, classical, Italian folk\nacoustic, classical, Latin\nacoustic, classical, ambient\nacoustic, classical, devotional\nacoustic, classical, flamenco\nacoustic, classical, folk\nacoustic, classical, melancholic\nacoustic, classical, sacred\nacoustic, classical, spiritual\nacoustic, classical, tango\nacoustic, contemplative, Brazilian\nacoustic, contemplative, Korean\nacoustic, devotional, Arabic\nacoustic, devotional, Spanish folk\nacoustic, devotional, ambient\nacoustic, devotional, world\nacoustic, dramatic, experimental\nacoustic, dramatic, melancholic\nacoustic, dream pop\nacoustic, dream pop, cinematic\nacoustic, dream pop, folk\nacoustic, dream-pop, cinematic\nacoustic, dreamy, Arabic\nacoustic, dreamy, Indian folk\nacoustic, dreamy, bossa nova\nacoustic, dreamy, lo-fi\nacoustic, educational, French\nacoustic, educational, Latin-inspired\nacoustic, educational, folk\nacoustic, emo-rap, Spanish-influenced\nacoustic, emotional, Mandarin folk\nacoustic, emotional, choral\nacoustic, emotional, folk\nacoustic, emotional, indie folk\nacoustic, emotional, instrumental\nacoustic, emotional, raw\nacoustic, erhu, Japanese folk\nacoustic, ethereal, French\nacoustic, ethereal, Italian folk\nacoustic, ethereal, Spanish folk\nacoustic, ethereal, ambient\nacoustic, ethereal, anime soundtrack\nacoustic, ethereal, bossa nova\nacoustic, ethereal, indie folk\nacoustic, ethereal, world music\nacoustic, experimental, indie folk\nacoustic, festive, Christmas\nacoustic, festive, rock\nacoustic, festive, tropical\nacoustic, fingerstyle, Afro-Latin\nacoustic, fingerstyle, Brazilian\nacoustic, fingerstyle, French chanson\nacoustic, fingerstyle, Japanese folk\nacoustic, fingerstyle, Korean folk\nacoustic, fingerstyle, Latin-influenced\nacoustic, fingerstyle, Portuguese folk\nacoustic, fingerstyle, Russian folk\nacoustic, fingerstyle, Spanish\nacoustic, fingerstyle, Spanish folk\nacoustic, fingerstyle, Tamil folk\nacoustic, fingerstyle, Turkish folk\nacoustic, fingerstyle, ambient\nacoustic, fingerstyle, bossa nova\nacoustic, fingerstyle, flamenco\nacoustic, fingerstyle, melancholic\nacoustic, fingerstyle, romantic\nacoustic, flamenco, Arabic\nacoustic, flamenco, Arabic folk\nacoustic, flamenco, Chinese ballad\nacoustic, flamenco, Chinese folk\nacoustic, flamenco, French folk\nacoustic, flamenco, Indian folk\nacoustic, flamenco, Latin\nacoustic, flamenco, Latin rock\nacoustic, flamenco, Mandarin folk\nacoustic, flamenco, Persian\nacoustic, flamenco, Persian folk\nacoustic, flamenco, Portuguese folk\nacoustic, flamenco, South Asian classical\nacoustic, flamenco, Spanish folk\nacoustic, flamenco, Swahili soul\nacoustic, flamenco, Tamil folk\nacoustic, flamenco, Turkish folk\nacoustic, flamenco, ambient\nacoustic, flamenco, art song\nacoustic, flamenco, bossa nova\nacoustic, flamenco, chanson\nacoustic, flamenco, cinematic\nacoustic, flamenco, classical\nacoustic, flamenco, dream pop\nacoustic, flamenco, ethereal\nacoustic, flamenco, folk\nacoustic, flamenco, folk rock\nacoustic, flamenco, indie folk\nacoustic, flamenco, instrumental\nacoustic, flamenco, melancholic\nacoustic, flamenco, operatic\nacoustic, flamenco, quirky\nacoustic, flamenco, regional Mexican\nacoustic, flamenco, rumba\nacoustic, flamenco, singer-songwriter\nacoustic, flamenco, soulful\nacoustic, flamenco, spiritual\nacoustic, flamenco, spoken word\nacoustic, flamenco, theatrical\nacoustic, flamenco, torch song\nacoustic, flamenco, world\nacoustic, flamenco, world fusion\nacoustic, flamenco, world music\nacoustic, flute, whimsical\nacoustic, flute, world\nacoustic, folk\nacoustic, folk, Anatolian\nacoustic, folk, Brazilian\nacoustic, folk, Christmas\nacoustic, folk, French\nacoustic, folk, Hungarian\nacoustic, folk, Indian\nacoustic, folk, Japanese\nacoustic, folk, Latin\nacoustic, folk, Mandarin\nacoustic, folk, Mandarin ballad\nacoustic, folk, Mandarin folk\nacoustic, folk, Mandarin pop\nacoustic, folk, Mandopop\nacoustic, folk, Persian-inspired\nacoustic, folk, Polish sung poetry\nacoustic, folk, Portuguese\nacoustic, folk, South Asian\nacoustic, folk, Spanish\nacoustic, folk, Spanish rap\nacoustic, folk, Tamil\nacoustic, folk, Turkish\nacoustic, folk, Vietnamese\nacoustic, folk, Yoruba\nacoustic, folk, Zulu\nacoustic, folk, Zulu hip hop\nacoustic, folk, ambient\nacoustic, folk, bossa nova\nacoustic, folk, chamber\nacoustic, folk, cinematic\nacoustic, folk, classical\nacoustic, folk, emotional\nacoustic, folk, experimental\nacoustic, folk, horror\nacoustic, folk, indie\nacoustic, folk, jazz\nacoustic, folk, lo-fi\nacoustic, folk, regional Mexican\nacoustic, folk, spoken word\nacoustic, folk, theatrical\nacoustic, folk, world\nacoustic, folk, world music\nacoustic, gentle, Korean folk\nacoustic, ghazal, Indian classical\nacoustic, ghazal, ambient\nacoustic, ghazal, melancholic\nacoustic, ghazal, soulful\nacoustic, glitch, Vocaloid\nacoustic, gospel, Christmas\nacoustic, gospel, Spanish style\nacoustic, gospel, ambient\nacoustic, gospel, world\nacoustic, gypsy jazz, Latin\nacoustic, gypsy jazz, chanson\nacoustic, gypsy-jazz, flamenco\nacoustic, harp, cinematic\nacoustic, hip hop, R&B\nacoustic, hip-hop, ballad\nacoustic, hip-hop, flamenco\nacoustic, hymn, christmas\nacoustic, indie folk\nacoustic, indie folk, Chinese rap\nacoustic, indie folk, Hindi folk\nacoustic, indie folk, Indian folk\nacoustic, indie folk, Indonesian folk\nacoustic, indie folk, Mandarin pop\nacoustic, indie folk, Punjabi hip hop\nacoustic, indie folk, Spanish\nacoustic, indie folk, Spanish ballad\nacoustic, indie folk, ambient\nacoustic, indie folk, cantopop\nacoustic, indie folk, hip hop\nacoustic, indie folk, lo-fi\nacoustic, indie folk, lo-fi hip hop\nacoustic, indie, lo-fi\nacoustic, inspirational, contemporary Christian\nacoustic, instrumental, Portuguese\nacoustic, instrumental, folk\nacoustic, instrumental, math rock\nacoustic, instrumental, rhapsodic\nacoustic, intimate, Sinhala folk\nacoustic, introspective, Brazilian\nacoustic, introspective, Indian classical\nacoustic, introspective, Indian folk\nacoustic, island, dreamy\nacoustic, jazz noir, ambient\nacoustic, jazz, Christmas\nacoustic, jazz, Korean ballad\nacoustic, jazz, Latin\nacoustic, jazz, ambient\nacoustic, jazz, tango\nacoustic, jazz, theatrical\nacoustic, jazzy, Japanese folk\nacoustic, klezmer, cabaret\nacoustic, klezmer, melancholic\nacoustic, latin, French pop\nacoustic, latin, folk\nacoustic, lighthearted, instrumental\nacoustic, live, Brazilian\nacoustic, lo-fi hip hop, indie folk\nacoustic, lo-fi, Brazilian\nacoustic, lo-fi, Brazilian folk\nacoustic, lo-fi, Caribbean hip hop\nacoustic, lo-fi, Indian folk\nacoustic, lo-fi, Korean folk\nacoustic, lo-fi, Latin hip hop\nacoustic, lo-fi, Mandarin folk\nacoustic, lo-fi, Spanish folk\nacoustic, lo-fi, Vocaloid\nacoustic, lo-fi, ambient\nacoustic, lo-fi, anime\nacoustic, lo-fi, bossa nova\nacoustic, lo-fi, folk\nacoustic, lo-fi, indie folk\nacoustic, lo-fi, jazz\nacoustic, lo-fi, korean folk\nacoustic, lo-fi, romantic\nacoustic, lo-fi, spiritual\nacoustic, lullaby, Indonesian folk\nacoustic, lullaby, Portuguese\nacoustic, lullaby, folk\nacoustic, lullaby, melancholic\nacoustic, lullaby, world folk\nacoustic, mandopop, ambient\nacoustic, mariachi, folk\nacoustic, meditative, Chinese folk\nacoustic, melancholic, Arabic\nacoustic, melancholic, Arabic folk\nacoustic, melancholic, Arabic jazz\nacoustic, melancholic, Bengali folk\nacoustic, melancholic, Brazilian\nacoustic, melancholic, Cantonese folk\nacoustic, melancholic, Chinese folk\nacoustic, melancholic, French\nacoustic, melancholic, French chanson\nacoustic, melancholic, French folk\nacoustic, melancholic, French indie\nacoustic, melancholic, German folk\nacoustic, melancholic, Greek folk\nacoustic, melancholic, Gujarati folk\nacoustic, melancholic, Hebrew folk\nacoustic, melancholic, Hindi folk\nacoustic, melancholic, Indian classical\nacoustic, melancholic, Indian folk\nacoustic, melancholic, Indonesian folk\nacoustic, melancholic, Italian\nacoustic, melancholic, Italian folk\nacoustic, melancholic, Japanese folk\nacoustic, melancholic, Korean folk\nacoustic, melancholic, Korean indie\nacoustic, melancholic, Latin\nacoustic, melancholic, Latin folk\nacoustic, melancholic, Latin-influenced\nacoustic, melancholic, Mandarin\nacoustic, melancholic, Mandarin folk\nacoustic, melancholic, Middle Eastern\nacoustic, melancholic, Persian\nacoustic, melancholic, Persian folk\nacoustic, melancholic, Polish folk\nacoustic, melancholic, Portuguese\nacoustic, melancholic, Portuguese folk\nacoustic, melancholic, Punjabi\nacoustic, melancholic, R&B\nacoustic, melancholic, Russian folk\nacoustic, melancholic, Sinhala folk\nacoustic, melancholic, South Asian\nacoustic, melancholic, Spanish\nacoustic, melancholic, Spanish folk\nacoustic, melancholic, Spanish guitar\nacoustic, melancholic, Spanish rap\nacoustic, melancholic, Spanish-influenced\nacoustic, melancholic, Tamil folk\nacoustic, melancholic, Thai folk\nacoustic, melancholic, Tigrinya\nacoustic, melancholic, Turkish folk\nacoustic, melancholic, Turkish jazz\nacoustic, melancholic, Vietnamese folk\nacoustic, melancholic, ambient\nacoustic, melancholic, bansuri\nacoustic, melancholic, baroque\nacoustic, melancholic, bossa nova\nacoustic, melancholic, cello\nacoustic, melancholic, chanson\nacoustic, melancholic, cinematic\nacoustic, melancholic, classical\nacoustic, melancholic, classical guitar\nacoustic, melancholic, duduk\nacoustic, melancholic, duet\nacoustic, melancholic, ethereal\nacoustic, melancholic, fingerstyle\nacoustic, melancholic, flamenco\nacoustic, melancholic, folk\nacoustic, melancholic, ghazal\nacoustic, melancholic, indie\nacoustic, melancholic, indie folk\nacoustic, melancholic, intimate\nacoustic, melancholic, jazz\nacoustic, melancholic, klezmer\nacoustic, melancholic, lo-fi\nacoustic, melancholic, lullaby\nacoustic, melancholic, minimalist\nacoustic, melancholic, oud\nacoustic, melancholic, rock opera\nacoustic, melancholic, rumba\nacoustic, melancholic, spoken word\nacoustic, melancholic, tango\nacoustic, melancholic, waltz\nacoustic, melancholic, world\nacoustic, melancholic, world folk\nacoustic, melancholic, world fusion\nacoustic, melancholic, world music\nacoustic, minimalist, Chinese folk\nacoustic, minimalist, Korean folk\nacoustic, minimalist, Mandopop\nacoustic, modern Christmas, sacred\nacoustic, neo-soul, math rock\nacoustic, nylon-string, Portuguese folk\nacoustic, operatic, cinematic\nacoustic, operatic, flamenco\nacoustic, operatic, melancholic\nacoustic, operatic, romantic\nacoustic, oud, world music\nacoustic, pastoral\nacoustic, playful, children's music\nacoustic, playful, ragtime\nacoustic, post-rock, cinematic\nacoustic, psychedelic rock, MPB\nacoustic, quirky, French spoken word\nacoustic, quirky, theatrical\nacoustic, rap, emotional\nacoustic, regional Mexican\nacoustic, regional Mexican, folk\nacoustic, regional Mexican, sierreño\nacoustic, romantic, Haitian Creole\nacoustic, romantic, Indian classical\nacoustic, romantic, Indian folk\nacoustic, romantic, Portuguese\nacoustic, romantic, South Asian\nacoustic, romantic, Spanish-influenced\nacoustic, romantic, bossa nova\nacoustic, romantic, classical\nacoustic, romantic, flamenco\nacoustic, romantic, folk\nacoustic, romantic, lo-fi\nacoustic, romantic, melancholic\nacoustic, romantic, nostalgic\nacoustic, romantic, world\nacoustic, rumba, Spanish\nacoustic, rumba, flamenco\nacoustic, rumba, folk\nacoustic, rumba, soukous\nacoustic, rumba, theatrical\nacoustic, sacred, Latin\nacoustic, samba, melancholic\nacoustic, samba, pagode\nacoustic, samba, quirky\nacoustic, samba-rock\nacoustic, sentimental, ambient\nacoustic, sertanejo, mpb\nacoustic, sierreño\nacoustic, sierreño, folk\nacoustic, sierreño, folk rock\nacoustic, singer-songwriter\nacoustic, soul, Latin jazz\nacoustic, soul, ambient\nacoustic, soul, indie\nacoustic, soulful, Brazilian\nacoustic, soulful, Christmas\nacoustic, soulful, Portuguese\nacoustic, soulful, Punjabi\nacoustic, soulful, South Asian\nacoustic, soulful, South Asian classical\nacoustic, soulful, classical\nacoustic, spiritual, Arabic\nacoustic, spiritual, Brazilian\nacoustic, spiritual, Caribbean\nacoustic, spiritual, French chanson\nacoustic, spiritual, Hawaiian\nacoustic, spiritual, Indian folk\nacoustic, spiritual, Latin\nacoustic, spiritual, Latin folk\nacoustic, spiritual, Middle Eastern\nacoustic, spiritual, Portuguese folk\nacoustic, spiritual, Sinhala folk\nacoustic, spiritual, Spanish\nacoustic, spiritual, Spanish folk\nacoustic, spiritual, Tamil folk\nacoustic, spiritual, ambient\nacoustic, spiritual, bossa nova\nacoustic, spiritual, choral\nacoustic, spiritual, classical\nacoustic, spiritual, devotional\nacoustic, spiritual, flamenco\nacoustic, spiritual, folk\nacoustic, spiritual, gospel\nacoustic, spiritual, meditative\nacoustic, spiritual, pan flute\nacoustic, spiritual, world\nacoustic, spiritual, world music\nacoustic, spoken word, French rap\nacoustic, spoken word, Latin\nacoustic, spoken word, Latin hip hop\nacoustic, spoken word, Turkish\nacoustic, spoken word, emotional\nacoustic, spoken word, flamenco\nacoustic, spoken word, folk\nacoustic, spoken word, indie folk\nacoustic, spoken word, rap\nacoustic, tango, dramatic\nacoustic, tango, gypsy jazz\nacoustic, tango, operatic\nacoustic, theatrical, Latin jazz\nacoustic, theatrical, Mandarin folk\nacoustic, theatrical, Russian folk\nacoustic, theatrical, baritone\nacoustic, theatrical, choral\nacoustic, theatrical, flamenco\nacoustic, theatrical, folk\nacoustic, theatrical, klezmer\nacoustic, theatrical, melancholic\nacoustic, trip-hop, French indie\nacoustic, tropical, ambient\nacoustic, tropical, dream pop\nacoustic, tropical, folk\nacoustic, tropical, instrumental\nacoustic, ukulele, Italian folk\nacoustic, ukulele, Japanese folk\nacoustic, ukulele, bossa nova\nacoustic, ukulele, cheerful\nacoustic, ukulele, country\nacoustic, uplifting, devotional\nacoustic, uplifting, instrumental\nacoustic, waltz, sentimental\nacoustic, whimsical, Christmas\nacoustic, whimsical, French chanson\nacoustic, whimsical, ambient\nacoustic, whimsical, folk\nacoustic, world folk\nacoustic, world fusion, ambient folk\nacoustic, world fusion, melodic\nacoustic, world music\nacoustic, world music, Haitian Creole\nacoustic, world music, Spanish folk\nacoustic, world music, hypnotic\nacoustic, world music, meditative\nacoustic, world music, spiritual\nacoustic, world, ambient\nacoustic, world, christmas\nacoustic, world, theatrical\nacoustic, zouk, kompa\nacoustic-electronic\nacoustic-pop\naction\naction rock\nadult contemporary\nadult contemporary R&B\nadult contemporary R&B Latin\nadult contemporary blues-rock\nadult contemporary bossa nova\nadult contemporary country\nadult contemporary country-pop\nadult contemporary jazz\nadult contemporary jazz lounge\nadult contemporary jazz-fusion\nadult contemporary lounge\nadult contemporary pop\nadult contemporary pop-rock\nadult contemporary reggae-pop\nadult contemporary rock\nadult contemporary smooth jazz\nadult contemporary soul\nadult contemporary world gospel\nadult contemporary world music\nadult contemporary, Latin pop\nadult contemporary, bossa nova, latin\nadult contemporary, funk rock\nadult contemporary, future bass, jazz\nadult contemporary, gospel\nadult contemporary, gospel rock, cinematic\nadult contemporary, hip-hop\nadult contemporary, new-age, world music\nadult contemporary, power ballad\nadult contemporary, progressive rock, cinematic\nadult contemporary, smooth jazz\nadult contemporary, soft rock, cinematic\nafro fusion\nafro house\nafro house funk\nafro house soulful house\nafro house, deep house, acid jazz\nafro house, deep house, soul\nafro house, latin tech\nafro trap\nafro-R&B\nafro-dancehall\nafro-dancehall R&B\nafro-dancehall chiptune\nafro-dancehall fusion\nafro-dancehall lo-fi\nafro-dancehall lo-fi hip-hop\nafro-dancehall pop\nafro-dancehall soul\nafro-disco\nafro-dub\nafro-folk\nafro-funk\nafro-funk cabaret\nafro-fusion\nafro-fusion R&B\nafro-fusion ambient\nafro-fusion ambient pop\nafro-fusion chillwave\nafro-fusion dancehall\nafro-fusion downtempo\nafro-fusion lo-fi\nafro-fusion neo-soul\nafro-fusion orchestral\nafro-fusion trap\nafro-fusion vaporwave\nafro-fusion, UK hip-hop\nafro-fusion, ambient, chopped and screwed\nafro-gospel\nafro-house\nafro-house chiptune\nafro-house dancehall\nafro-house deep house\nafro-house gospel\nafro-house lounge\nafro-house tech-house\nafro-house, Dutch pop-rap\nafro-house, deep house\nafro-house, deep house, world music\nafro-house, gospel, house\nafro-house, latin house\nafro-house, latin tech\nafro-jazz\nafro-latin\nafro-latin deep house\nafro-latin dembow\nafro-latin electronic\nafro-latin funk\nafro-latin house\nafro-latin jazz\nafro-latin jazz-funk\nafro-latin pop\nafro-lounge\nafro-pop\nafro-pop Caribbean\nafro-pop French pop\nafro-pop R&B\nafro-pop R&B French\nafro-pop ambient\nafro-pop chiptune\nafro-pop cinematic\nafro-pop cumbia reggae\nafro-pop dancehall\nafro-pop funk\nafro-pop gospel\nafro-pop latin\nafro-pop lo-fi\nafro-pop reggae\nafro-pop reggae Caribbean\nafro-pop reggaeton\nafro-pop retro\nafro-pop tropical\nafro-pop world music\nafro-pop worldbeat\nafro-pop, reggaeton, chiptune\nafro-rap\nafro-reggae\nafro-rock\nafro-ska\nafro-soul\nafro-soul ambient\nafro-soul chill R&B\nafro-soul chill house\nafro-soul deep house R&B\nafro-soul downtempo\nafro-soul lo-fi R&B\nafro-soul smooth jazz\nafro-soul trap\nafro-swing\nafro-swing dancehall\nafro-tech\nafro-tech deep house\nafro-tech house\nafro-trap\nafro-trap French R&B\nafro-trap French cloud rap\nafro-trap French pop\nafro-trap French pop-rap\nafro-trap R&B\nafro-trap R&B French pop\nafro-trap ambient pop\nafro-trap ballad\nafro-trap chillwave\nafro-trap chiptune\nafro-trap cloud rap\nafro-trap dancehall\nafro-trap experimental\nafro-trap hip-hop\nafro-trap lo-fi\nafro-trap pop\nafro-trap pop-rap\nafro-trap tropical\nafro-trap vaporwave\nafro-trap, Dutch hip-hop\nafro-trap, French R&B\nafro-trap, French cloud rap\nafro-trap, French pop-rap\nafro-trap, French rap, pop\nafro-trap, chiptune, French pop-rap\nafro-trap, cinematic, oriental\nafro-trap, cloud rap\nafro-trap, cloud rap, French\nafro-trap, cloud rap, French trap\nafro-trap, contemporary R&B\nafro-trap, dancehall, Dutch hip-hop\nafro-trap, dancehall, club\nafro-trap, dream pop, hyperpop\nafro-trap, electronic, dance\nafro-trap, experimental electronic\nafro-trap, moody hip-hop\nafro-trap, reggaeton, French R&B\nafro-trap, synthwave, French pop\nafro-trap, trap, R&B\nafro-trap, trap, dancehall\nafro-trap, trap, vaporwave\nafro-trap, tropical house\nafro-trap, vaporwave\nafrobeat\nafrobeat French pop\nafrobeat Latin pop\nafrobeat R&B\nafrobeat R&B cinematic\nafrobeat R&B dancehall\nafrobeat afro-pop neo-soul\nafrobeat alternative R&B\nafrobeat chill\nafrobeat chillwave\nafrobeat chillwave lounge\nafrobeat chiptune\nafrobeat cinematic\nafrobeat dancehall\nafrobeat dancehall R&B\nafrobeat dancehall chiptune\nafrobeat dancehall electronic\nafrobeat dancehall lo-fi\nafrobeat dancehall lounge\nafrobeat dancehall pop\nafrobeat dancehall trap\nafrobeat dancehall tropical house\nafrobeat deep house\nafrobeat electronic\nafrobeat electronic gospel\nafrobeat electronic pop\nafrobeat funk\nafrobeat funk electronic\nafrobeat funk reggae\nafrobeat funk rock\nafrobeat funk worldbeat\nafrobeat funk-rock\nafrobeat future bass\nafrobeat gospel\nafrobeat gospel hip-hop\nafrobeat gospel pop\nafrobeat highlife\nafrobeat hip hop tribal house\nafrobeat hip-hop\nafrobeat house\nafrobeat jazz\nafrobeat latin house\nafrobeat latin pop gospel\nafrobeat lo-fi\nafrobeat lo-fi hip-hop\nafrobeat minimal house\nafrobeat pop\nafrobeat pop-rap\nafrobeat reggae\nafrobeat reggae fusion\nafrobeat reggae-ska\nafrobeat reggaeton\nafrobeat reggaeton chiptune\nafrobeat soul\nafrobeat spiritual\nafrobeat tech house\nafrobeat trap\nafrobeat trap world music\nafrobeat tribal house\nafrobeat tropical\nafrobeat tropical house\nafrobeat tropical house chillwave\nafrobeat ukulele\nafrobeat vaporwave\nafrobeat world fusion\nafrobeat world music\nafrobeat worldbeat\nafrobeat, French dancehall\nafrobeat, French pop, lo-fi\nafrobeat, French rap, pop\nafrobeat, Latin house\nafrobeat, Middle Eastern\nafrobeat, Middle Eastern, dance\nafrobeat, afro-soul, R&B\nafrobeat, afro-trap, pop\nafrobeat, alternative R&B, world music\nafrobeat, baile funk, dance\nafrobeat, chiptune, French pop\nafrobeat, cinematic, lo-fi\nafrobeat, cinematic, pop-R&B\nafrobeat, dancehall, ethereal pop\nafrobeat, deep house, dancehall\nafrobeat, dream pop\nafrobeat, future bass, R&B\nafrobeat, future bass, cyberpunk\nafrobeat, gospel, dance\nafrobeat, gospel, world music\nafrobeat, hyperpop\nafrobeat, latin house\nafrobeat, latin house, electronic\nafrobeat, latin house, house\nafrobeat, latin house, tech house\nafrobeat, latin house, tribal house\nafrobeat, latin pop\nafrobeat, lo-fi hip hop\nafrobeat, lo-fi, dream pop\nafrobeat, synth-pop, vaporwave\nafrobeat, synthwave, hip hop\nafrobeat, vaporwave, R&B\nafrobeat, world music, corporate\nafrobeat, world music, pop\nafrobeat-pop\nafrobeats\nafrobeats French pop\nafrobeats R&B\nafrobeats R&B acoustic pop\nafrobeats R&B afro-fusion\nafrobeats R&B dancehall\nafrobeats R&B pop\nafrobeats ambient\nafrobeats ambient pop\nafrobeats chill\nafrobeats chillwave\nafrobeats chillwave tropical house\nafrobeats chiptune\nafrobeats chiptune French rap\nafrobeats dancehall\nafrobeats dancehall French pop\nafrobeats dancehall R&B\nafrobeats dancehall afro-pop\nafrobeats dancehall afropop\nafrobeats dancehall chiptune\nafrobeats dancehall inspirational hip-hop\nafrobeats dancehall pop\nafrobeats dancehall tropical\nafrobeats dancehall-pop\nafrobeats experimental pop\nafrobeats funk\nafrobeats gospel\nafrobeats hip-hop\nafrobeats hip-hop gospel\nafrobeats j-pop\nafrobeats jazz\nafrobeats jazzy\nafrobeats jazzy lo-fi\nafrobeats latin\nafrobeats lo-fi\nafrobeats lo-fi R&B\nafrobeats lo-fi hip hop\nafrobeats neo-soul\nafrobeats pop\nafrobeats pop world music\nafrobeats pop-R&B\nafrobeats pop-r&b\nafrobeats pop-rap\nafrobeats reggae dancehall\nafrobeats reggaeton\nafrobeats romantic\nafrobeats spiritual\nafrobeats trap\nafrobeats trap dancehall\nafrobeats tropical\nafrobeats tropical house\nafrobeats tropical pop\nafrobeats vaporwave\nafrobeats worldbeat\nafrobeats, French pop\nafrobeats, French pop, dancehall\nafrobeats, French rap\nafrobeats, R&B, afro-fusion\nafrobeats, UK hip-hop\nafrobeats, UK hip-hop, cloud rap\nafrobeats, UK hip-hop, pop\nafrobeats, afro-soul, dancehall\nafrobeats, alternative R&B, dancehall\nafrobeats, chill R&B\nafrobeats, chiptune, R&B\nafrobeats, chiptune, dancehall\nafrobeats, chiptune, smooth soul\nafrobeats, dancehall, Latin pop\nafrobeats, dancehall, R&B\nafrobeats, dancehall, chiptune\nafrobeats, dancehall, lo-fi\nafrobeats, dream pop, synthwave\nafrobeats, electronic dance music, synthwave\nafrobeats, funk, lo-fi\nafrobeats, hardstyle\nafrobeats, latin pop\nafrobeats, latin, reggaeton\nafrobeats, tropical house, lo-fi hip hop\nafrobeats, tropical, dancehall\nafrobeats, world pop\nafrobeats-pop\nafrofuturistic trap\naggressive\naggressive Arabic protest\naggressive C-pop\naggressive K-hip-hop\naggressive R&B\naggressive acapella\naggressive bass music\naggressive beatbox\naggressive boom-bap\naggressive breakbeat\naggressive chiptune\naggressive chiptune metal\naggressive chiptune trap\naggressive club\naggressive comedy rap\naggressive crossover\naggressive dembow\naggressive drum & bass\naggressive drum and bass\naggressive electro\naggressive electronic\naggressive electronic hip-hop\naggressive electronic rock\naggressive fusion\naggressive hip hop\naggressive hip-hop\naggressive house\naggressive hybrid\naggressive metal trap\naggressive oud fusion\naggressive percussion\naggressive pop\naggressive rap\naggressive rap battle\naggressive rap, bass music, electronic\naggressive rap, chiptune, synth-pop\naggressive rock\naggressive techno\naggressive trap\naggressive trap metal\naggressive trap phonk\naggressive trap rap\naggressive trap, phonk\naggressive vocal\naggressive vocal hip hop\naggressive, genre-bending, electronic\naggressive, hypnotic, vocal loop\nagro-funk\nagro-funk carioca\nagro-pop\nal Greek art\nalpine trap\nalt rock\nalt-R&B\nalt-R&B trap\nalt-R&B, trap, hyperpop\nalt-country\nalt-country americana\nalt-country blues-rock\nalt-country cinematic\nalt-country folk-rock\nalt-country garage rock\nalt-country gothic americana\nalt-country grunge\nalt-country heartland rock\nalt-country hip-hop\nalt-country indie rock\nalt-country jangle pop\nalt-country latin\nalt-country lo-fi\nalt-country lo-fi hip-hop\nalt-country pop-punk\nalt-country pop-rock\nalt-country post-rock\nalt-country psychedelic rock\nalt-country punk\nalt-country punk rock\nalt-country ragtime\nalt-country rock\nalt-country rock grunge\nalt-country rock, post-hardcore, nu-metal\nalt-country rock, trap, hyperpop\nalt-country rockabilly\nalt-country rockabilly blues-rock\nalt-country rockabilly honky-tonk\nalt-country roots rock\nalt-country roots-rock\nalt-country soul-rock\nalt-country southern rock\nalt-country spaghetti western\nalt-country swamp-rock\nalt-country, Americana\nalt-country, alt-rock\nalt-country, disco-rock\nalt-country, garage punk\nalt-country, hard rock\nalt-country, indie rock\nalt-country, post-grunge\nalt-country, psychedelic rock\nalt-country, psychedelic rock, punk\nalt-country, rap-rock, heavy rock\nalt-country, rap-rock, indie rock\nalt-country, southern rock\nalt-folk\nalt-folk grunge\nalt-folk indie rock\nalt-folk rock\nalt-metal\nalt-metal cyberpunk\nalt-metal nu-metal\nalt-metal nu-metal pop-punk\nalt-metal, rap-metal, thrash metal\nalt-pop\nalt-pop electronic rock\nalt-pop emo-trap\nalt-pop future bass\nalt-pop j-rock\nalt-pop lo-fi hip-hop\nalt-pop metalcore\nalt-pop nu-metal\nalt-pop trap\nalt-pop, color bass, glitch-hop\nalt-pop, future bass, trap\nalt-pop, hyperpop\nalt-pop, trap, K-pop\nalt-rock\nalt-rock 90s\nalt-rock Americana\nalt-rock Latin\nalt-rock alt-country\nalt-rock americana\nalt-rock ballad\nalt-rock blues\nalt-rock blues-rock\nalt-rock chiptune\nalt-rock cinematic\nalt-rock comedy\nalt-rock country\nalt-rock country bluegrass\nalt-rock country blues\nalt-rock country rock\nalt-rock country southern rock\nalt-rock country-rock\nalt-rock country-rock americana\nalt-rock dream-pop\nalt-rock drum and bass\nalt-rock electronic\nalt-rock electronicore metalcore\nalt-rock emo\nalt-rock emo rock\nalt-rock emo-rock\nalt-rock flamenco\nalt-rock folk-rock\nalt-rock funk\nalt-rock funk blues-rock\nalt-rock funk-rock\nalt-rock future bass\nalt-rock garage rock\nalt-rock grunge\nalt-rock grunge nu-metal\nalt-rock grunge post-metal\nalt-rock grunge punk\nalt-rock hard rock\nalt-rock heartland rock\nalt-rock hip-hop\nalt-rock hip-hop electronic\nalt-rock hip-hop fusion\nalt-rock indie rock\nalt-rock industrial\nalt-rock jangle-pop\nalt-rock lo-fi\nalt-rock metal\nalt-rock metalcore\nalt-rock nu-metal\nalt-rock nu-metal j-rock\nalt-rock nu-metal pop-punk\nalt-rock pop\nalt-rock pop-punk\nalt-rock pop-punk emo\nalt-rock pop-punk hip-hop\nalt-rock pop-punk metalcore\nalt-rock pop-punk nu-metal\nalt-rock pop-punk psychedelic\nalt-rock pop-punk rap-rock\nalt-rock pop-rock\nalt-rock post-grunge\nalt-rock post-grunge emo\nalt-rock post-hardcore\nalt-rock post-punk\nalt-rock post-rock\nalt-rock post-rock metal\nalt-rock power metal\nalt-rock power-pop\nalt-rock progressive rock\nalt-rock pub rock\nalt-rock punk\nalt-rock punk blues-rock\nalt-rock punk rock\nalt-rock rap-rock\nalt-rock reggae-rock\nalt-rock rockabilly country-rock\nalt-rock satire\nalt-rock shoegaze\nalt-rock skate punk\nalt-rock southern rock\nalt-rock thrash metal\nalt-rock world music\nalt-rock, Americana, cinematic\nalt-rock, Americana, heartland rock\nalt-rock, Americana, roots-rock\nalt-rock, Brazilian pop-rock\nalt-rock, EDM, hip-hop\nalt-rock, Indian classical, experimental\nalt-rock, Indian classical, indie\nalt-rock, Indian fusion, cinematic rock\nalt-rock, J-rock\nalt-rock, J-rock, funk rock\nalt-rock, J-rock, nu-metal\nalt-rock, K-pop, trap\nalt-rock, Spanish rock\nalt-rock, alternative metal\nalt-rock, anthemic, gospel\nalt-rock, bossa nova\nalt-rock, bossa nova, blues\nalt-rock, bossa nova, rock\nalt-rock, brostep, ambient\nalt-rock, chiptune, C-pop\nalt-rock, chiptune, power rock\nalt-rock, cinematic, Indian rock\nalt-rock, complextro, hardstyle\nalt-rock, dance-pop\nalt-rock, dark cabaret\nalt-rock, dream-pop, psychedelic\nalt-rock, dubstep\nalt-rock, dubstep, electronic\nalt-rock, dubstep, electronic rock\nalt-rock, electronic, chiptune\nalt-rock, electronic, dubstep\nalt-rock, electronic, hip-hop\nalt-rock, emo, dream pop\nalt-rock, emo, metalcore\nalt-rock, emo, nu-metal\nalt-rock, emo, pop-punk\nalt-rock, flamenco, metalcore\nalt-rock, folk, Americana\nalt-rock, folk-rock, punk rock\nalt-rock, funk, Cantonese rock\nalt-rock, funk, jazz funk\nalt-rock, funk-rock, rap rock\nalt-rock, future bass\nalt-rock, garage rock\nalt-rock, garage rock, pop-punk\nalt-rock, garage-punk\nalt-rock, grunge, shoegaze\nalt-rock, hard rock\nalt-rock, hard rock, J-rock\nalt-rock, hard rock, K-pop\nalt-rock, hard rock, Latin fusion\nalt-rock, hard rock, alternative metal\nalt-rock, hard rock, blues-rock\nalt-rock, hard rock, funk rock\nalt-rock, hard rock, heavy metal\nalt-rock, hard rock, metal\nalt-rock, hard rock, metalcore\nalt-rock, hard rock, nu-metal\nalt-rock, hard rock, post-hardcore\nalt-rock, hard rock, punk\nalt-rock, hard rock, shred guitar\nalt-rock, hard rock, symphonic rock\nalt-rock, hard rock, thrash metal\nalt-rock, hardcore punk, ska-punk\nalt-rock, hardstyle\nalt-rock, hardstyle, electronic\nalt-rock, heartland rock\nalt-rock, heavy metal\nalt-rock, heavy metal, blues-rock\nalt-rock, heavy metal, hard rock\nalt-rock, hip hop, C-pop\nalt-rock, hip-hop, atmospheric\nalt-rock, hip-hop, cinematic\nalt-rock, hip-hop, emotional\nalt-rock, hip-hop, emotional rock\nalt-rock, hip-hop, nu-metal\nalt-rock, hyperpop\nalt-rock, industrial metal, progressive rock\nalt-rock, industrial rock\nalt-rock, industrial rock, hyperpop\nalt-rock, industrial, rap rock\nalt-rock, lo-fi hip-hop\nalt-rock, melodic hardcore, skate punk\nalt-rock, melodic metalcore\nalt-rock, metal, acoustic ballad\nalt-rock, metal, cinematic\nalt-rock, metal, industrial\nalt-rock, metalcore\nalt-rock, metalcore, acoustic\nalt-rock, metalcore, cinematic\nalt-rock, metalcore, emotional\nalt-rock, metalcore, folk\nalt-rock, metalcore, pop-punk\nalt-rock, metalcore, post-hardcore\nalt-rock, metalcore, post-rock\nalt-rock, minimalist, Greek pop\nalt-rock, neurofunk, drum and bass\nalt-rock, noir-jazz, C-pop\nalt-rock, noise rock, melancholic\nalt-rock, noise rock, shoegaze\nalt-rock, noise-rock\nalt-rock, nu-disco, cinematic\nalt-rock, nu-metal\nalt-rock, nu-metal, Indian folk\nalt-rock, nu-metal, atmospheric\nalt-rock, nu-metal, cinematic\nalt-rock, nu-metal, electronic\nalt-rock, nu-metal, industrial rock\nalt-rock, nu-metal, lo-fi\nalt-rock, nu-metal, pop-punk\nalt-rock, nu-metal, rap rock\nalt-rock, nu-metal, rap-rock\nalt-rock, pop-punk\nalt-rock, pop-punk, Filipino rock\nalt-rock, pop-punk, J-rock\nalt-rock, pop-punk, cinematic\nalt-rock, pop-punk, electronic\nalt-rock, pop-punk, emo\nalt-rock, pop-punk, funk\nalt-rock, pop-punk, hard rock\nalt-rock, pop-punk, hardcore punk\nalt-rock, pop-punk, hyperpop\nalt-rock, pop-punk, metalcore\nalt-rock, pop-punk, nu-metal\nalt-rock, pop-punk, post-grunge\nalt-rock, pop-punk, post-hardcore\nalt-rock, pop-rock, dream pop\nalt-rock, pop-rock, experimental\nalt-rock, pop-rock, nu-metal\nalt-rock, post-grunge\nalt-rock, post-grunge, hard rock\nalt-rock, post-grunge, post-hardcore\nalt-rock, post-hardcore\nalt-rock, post-hardcore, Spanish rock\nalt-rock, post-hardcore, cinematic\nalt-rock, post-hardcore, emo\nalt-rock, post-hardcore, experimental\nalt-rock, post-hardcore, indie rock\nalt-rock, post-hardcore, metalcore\nalt-rock, post-hardcore, psychedelic rock\nalt-rock, post-hardcore, shoegaze\nalt-rock, post-metal\nalt-rock, post-rock\nalt-rock, post-rock, C-pop\nalt-rock, post-rock, hard rock\nalt-rock, power pop\nalt-rock, power-pop\nalt-rock, power-pop, punk\nalt-rock, psychedelic rock\nalt-rock, psychedelic rock, rap-rock\nalt-rock, punk rock\nalt-rock, punk rock, Chinese blues\nalt-rock, punk rock, chiptune\nalt-rock, punk rock, hip-hop\nalt-rock, punk rock, metalcore\nalt-rock, punk rock, rap-rock\nalt-rock, punk, aggressive\nalt-rock, punk, experimental\nalt-rock, punk, hip-hop\nalt-rock, punk, industrial rock\nalt-rock, punk, psychedelic\nalt-rock, punk, rap-rock\nalt-rock, punk, synth-rock\nalt-rock, punk-rock\nalt-rock, punk-rock, Tamil rock\nalt-rock, rap rock, Thai hip hop\nalt-rock, rap rock, dream-pop\nalt-rock, rap-rock\nalt-rock, rap-rock, cinematic\nalt-rock, rap-rock, funk\nalt-rock, rap-rock, pop-punk\nalt-rock, rap-rock, punk\nalt-rock, rock, electronic\nalt-rock, shoegaze, post-grunge\nalt-rock, shoegaze, post-rock\nalt-rock, skate punk, cinematic\nalt-rock, southern rock\nalt-rock, synth rock\nalt-rock, theatrical, funk\nalt-rock, thrash-punk, Spanish rock\nalt-rock, trap, Punjabi hip hop\nalt-rock, trap, electronic\nalt-rock, world music\nalternative\nalternative R&B\nalternative R&B Afro-fusion\nalternative R&B Afrobeats\nalternative R&B afrobeats dancehall\nalternative R&B ambient pop\nalternative R&B chillwave\nalternative R&B chiptune\nalternative R&B cloud rap\nalternative R&B dancehall\nalternative R&B dark pop\nalternative R&B deep house\nalternative R&B dream pop\nalternative R&B dream pop lo-fi hip-hop\nalternative R&B drum and bass\nalternative R&B emo pop\nalternative R&B emo rap\nalternative R&B emo rap hyperpop\nalternative R&B emo trap\nalternative R&B emo-pop\nalternative R&B emo-rap\nalternative R&B emo-trap\nalternative R&B experimental hip-hop dream pop\nalternative R&B experimental pop\nalternative R&B experimental trap\nalternative R&B funk\nalternative R&B funk Afrobeats\nalternative R&B funk experimental\nalternative R&B funk-pop\nalternative R&B future bass\nalternative R&B future bass trap\nalternative R&B future garage trap\nalternative R&B hip-hop\nalternative R&B hyperpop trap\nalternative R&B indie pop\nalternative R&B indie pop hip-hop\nalternative R&B lo-fi\nalternative R&B lo-fi hip hop\nalternative R&B lo-fi hip-hop\nalternative R&B lo-fi hip-hop soul\nalternative R&B lo-fi pop\nalternative R&B lo-fi trap\nalternative R&B neo-soul\nalternative R&B reggaeton\nalternative R&B trap\nalternative R&B trap Afro-Latin\nalternative R&B trap Afrobeat\nalternative R&B trap J-pop\nalternative R&B trap K-pop\nalternative R&B trap Latin\nalternative R&B trap dream pop\nalternative R&B trap electronic\nalternative R&B trap hyperpop\nalternative R&B trap lo-fi\nalternative R&B trap metal\nalternative R&B trap post-punk\nalternative R&B trap psychedelic rock\nalternative R&B trap soul\nalternative R&B trap vaporwave\nalternative R&B trap world music\nalternative R&B trap-soul\nalternative R&B trip-hop\nalternative R&B world music\nalternative R&B, Afrobeat, dream pop\nalternative R&B, Brazilian pop\nalternative R&B, C-pop, lo-fi\nalternative R&B, French cloud rap\nalternative R&B, French pop, trap\nalternative R&B, G-funk\nalternative R&B, Indian pop, lo-fi hip hop\nalternative R&B, K-R&B\nalternative R&B, K-R&B, downtempo\nalternative R&B, K-pop\nalternative R&B, Korean hip-hop\nalternative R&B, Latin alternative pop, downtempo\nalternative R&B, Latin hip-hop, downtempo\nalternative R&B, Latin pop\nalternative R&B, Latin soul\nalternative R&B, Latin trap\nalternative R&B, Persian pop\nalternative R&B, Persian, downtempo\nalternative R&B, Turkish hip-hop, emotional pop\nalternative R&B, UK drill, lo-fi\nalternative R&B, UK garage\nalternative R&B, UK garage, ambient\nalternative R&B, UK garage, electronic\nalternative R&B, UK garage, vaporwave\nalternative R&B, UK hip-hop\nalternative R&B, ambient pop\nalternative R&B, ambient, trap\nalternative R&B, baile funk\nalternative R&B, bedroom pop\nalternative R&B, boom-bap hip-hop\nalternative R&B, chill trap\nalternative R&B, chillhop\nalternative R&B, chillwave\nalternative R&B, chillwave, downtempo\nalternative R&B, cinematic hip hop\nalternative R&B, cinematic hip-hop, gospel\nalternative R&B, cinematic, trap\nalternative R&B, cloud rap\nalternative R&B, cloud rap, Brazilian pop\nalternative R&B, cloud rap, Latin urban\nalternative R&B, cloud rap, ambient\nalternative R&B, cloud rap, dark pop\nalternative R&B, cloud rap, dream pop\nalternative R&B, cloud rap, electronic\nalternative R&B, cloud rap, trap\nalternative R&B, conscious hip-hop\nalternative R&B, conscious hip-hop, experimental electronic\nalternative R&B, dark pop\nalternative R&B, dark pop, electronic\nalternative R&B, dark pop, experimental\nalternative R&B, deep house\nalternative R&B, dream pop\nalternative R&B, dream pop, chillwave\nalternative R&B, dream pop, conscious hip-hop\nalternative R&B, dream pop, electronic\nalternative R&B, dream pop, lo-fi hip-hop\nalternative R&B, dream pop, trap\nalternative R&B, dreamy, trap\nalternative R&B, electro-funk\nalternative R&B, electronic\nalternative R&B, electronic pop\nalternative R&B, electronic pop, C-pop\nalternative R&B, electronic pop, ambient\nalternative R&B, electronic pop, chillwave\nalternative R&B, electronic pop, future bass\nalternative R&B, electronic pop, psychedelic\nalternative R&B, electronic pop, synth-pop\nalternative R&B, electronic pop, trap\nalternative R&B, electronic trip-hop\nalternative R&B, electronic, cinematic\nalternative R&B, electronic, gospel\nalternative R&B, electronic, lo-fi\nalternative R&B, electronic, trip-hop\nalternative R&B, emo rap\nalternative R&B, emo rap, dream pop\nalternative R&B, emo rap, indie pop\nalternative R&B, emo rap, lo-fi hip hop\nalternative R&B, emo rap, lo-fi hip-hop\nalternative R&B, emo rap, trap\nalternative R&B, emo trap\nalternative R&B, emo trap, K-R&B\nalternative R&B, emo-trap\nalternative R&B, experimental Latin hip-hop\nalternative R&B, experimental electronic\nalternative R&B, experimental hip-hop\nalternative R&B, experimental pop\nalternative R&B, experimental trap\nalternative R&B, future bass\nalternative R&B, future bass, dream pop\nalternative R&B, future bass, electronic pop\nalternative R&B, future bass, lo-fi hip-hop\nalternative R&B, future garage, ambient\nalternative R&B, hip-hop\nalternative R&B, hip-hop, dream pop\nalternative R&B, hip-hop, pop-rap\nalternative R&B, hip-hop, psychedelic rock\nalternative R&B, hyperpop, funk\nalternative R&B, hyperpop, rock\nalternative R&B, hyperpop, trap\nalternative R&B, indie pop\nalternative R&B, indie pop, Latin pop\nalternative R&B, indie pop, Middle Eastern\nalternative R&B, indie pop, chiptune\nalternative R&B, indie pop, hip-hop\nalternative R&B, indie pop, hyperpop\nalternative R&B, indie pop, lo-fi\nalternative R&B, indie pop, lo-fi hip hop\nalternative R&B, lo-fi R&B, Brazilian pop\nalternative R&B, lo-fi funk, Brazilian funk\nalternative R&B, lo-fi hip hop\nalternative R&B, lo-fi hip hop, ambient\nalternative R&B, lo-fi hip hop, chillwave\nalternative R&B, lo-fi hip hop, chiptune\nalternative R&B, lo-fi hip hop, cinematic\nalternative R&B, lo-fi hip hop, dream pop\nalternative R&B, lo-fi hip hop, industrial trap\nalternative R&B, lo-fi hip hop, soul\nalternative R&B, lo-fi hip hop, trap\nalternative R&B, lo-fi hip-hop\nalternative R&B, lo-fi hip-hop, ambient\nalternative R&B, lo-fi hip-hop, chillwave\nalternative R&B, lo-fi hip-hop, dream pop\nalternative R&B, lo-fi hip-hop, emo rap\nalternative R&B, lo-fi hip-hop, industrial\nalternative R&B, lo-fi hip-hop, neo-soul\nalternative R&B, lo-fi pop\nalternative R&B, lo-fi pop, Afrobeats\nalternative R&B, lo-fi, cinematic\nalternative R&B, metalcore, electronic\nalternative R&B, minimal wave\nalternative R&B, modern trap\nalternative R&B, neo-soul\nalternative R&B, phonk\nalternative R&B, pop-punk, hip-hop\nalternative R&B, pop-rap\nalternative R&B, pop-rap, chiptune\nalternative R&B, pop-rock, ambient\nalternative R&B, psychedelic soul\nalternative R&B, psychedelic soul, funk\nalternative R&B, psychedelic, hip-hop\nalternative R&B, psychedelic, trap-soul\nalternative R&B, rock, electronic\nalternative R&B, sad pop\nalternative R&B, soul, conscious hip-hop\nalternative R&B, synth-pop\nalternative R&B, synth-pop, dream pop\nalternative R&B, synth-pop, trap\nalternative R&B, trap\nalternative R&B, trap soul\nalternative R&B, trap, Brazilian\nalternative R&B, trap, Indian fusion\nalternative R&B, trap, J-pop\nalternative R&B, trap, Latin\nalternative R&B, trap, South Asian\nalternative R&B, trap, ambient\nalternative R&B, trap, art pop\nalternative R&B, trap, chiptune\nalternative R&B, trap, cloud rap\nalternative R&B, trap, dark pop\nalternative R&B, trap, dream pop\nalternative R&B, trap, electronic\nalternative R&B, trap, electronic pop\nalternative R&B, trap, experimental electronic\nalternative R&B, trap, experimental pop\nalternative R&B, trap, flamenco\nalternative R&B, trap, hyperpop\nalternative R&B, trap, industrial\nalternative R&B, trap, lo-fi\nalternative R&B, trap, lo-fi hip hop\nalternative R&B, trap, pop\nalternative R&B, trap, vaporwave\nalternative R&B, trap, world music\nalternative R&B, trap-soul\nalternative R&B, trap-soul, ambient\nalternative R&B, trap-soul, cinematic\nalternative R&B, trap-soul, lo-fi\nalternative R&B, trip-hop\nalternative R&B, trip-hop, ambient\nalternative R&B, trip-hop, art pop\nalternative R&B, trip-hop, blues\nalternative R&B, trip-hop, cinematic\nalternative R&B, trip-hop, dark pop\nalternative R&B, trip-hop, experimental electronic\nalternative R&B, trip-hop, lo-fi\nalternative R&B, trip-hop, lo-fi hip-hop\nalternative R&B, trip-hop, trap\nalternative R&B, vaporwave, hip-hop\nalternative R&B, world music\nalternative dance\nalternative dance cumbia\nalternative dance funk-pop\nalternative dance funk-rock\nalternative dance-rock\nalternative folk\nalternative funk\nalternative funk rock\nalternative funk-rock\nalternative hard rock\nalternative hip hop\nalternative hip-hop\nalternative hip-hop big beat\nalternative hip-hop chiptune\nalternative hip-hop chiptune indie pop\nalternative hip-hop chiptune synth-pop\nalternative hip-hop dream pop\nalternative hip-hop electronic\nalternative hip-hop electronic funk\nalternative hip-hop electronic rock\nalternative hip-hop experimental pop\nalternative hip-hop funk\nalternative hip-hop funk rock\nalternative hip-hop funk-rock\nalternative hip-hop hyperpop breakcore\nalternative hip-hop indie electronic\nalternative hip-hop indie pop\nalternative hip-hop indie rock\nalternative hip-hop industrial rock\nalternative hip-hop neo-soul\nalternative hip-hop nu-metal industrial rock\nalternative hip-hop nu-metal punk rock\nalternative hip-hop post-punk\nalternative hip-hop post-rock\nalternative hip-hop synth-pop\nalternative hip-hop synth-pop chiptune\nalternative hip-hop world music\nalternative hip-hop, alternative rock, emo\nalternative hip-hop, hyperpop, indie pop\nalternative hip-hop, psychedelic funk\nalternative hip-hop, synth-pop\nalternative hip-hop, trap, rock\nalternative lounge\nalternative metal\nalternative metal J-rock\nalternative metal chiptune\nalternative metal grunge\nalternative metal industrial rock\nalternative metal nu-metal\nalternative metal nu-metal post-grunge\nalternative metal post-grunge\nalternative metal post-hardcore\nalternative metal shoegaze\nalternative metal trance\nalternative metal, J-rock\nalternative metal, J-rock, ambient\nalternative metal, cinematic rock\nalternative metal, cinematic synth, Chinese rock\nalternative metal, funk metal, cinematic\nalternative metal, gothic rock\nalternative metal, jazz fusion\nalternative metal, metalcore\nalternative metal, metalcore, cinematic\nalternative metal, metalcore, folk\nalternative metal, metalcore, post-rock\nalternative metal, nu-metal, chiptune\nalternative metal, nu-metal, cinematic\nalternative metal, nu-metal, cinematic rock\nalternative metal, nu-metal, hip-hop\nalternative metal, nu-metal, rap-metal\nalternative metal, post-hardcore\nalternative metal, post-hardcore, nu-metal\nalternative metal, post-hardcore, rap-rock\nalternative metal, post-rock, C-pop\nalternative metal, power metal, metalcore\nalternative metalcore\nalternative pop\nalternative pop emo-pop trap\nalternative pop future bass\nalternative pop lo-fi hip hop\nalternative pop trip-hop\nalternative pop, lo-fi hip hop, Turkish\nalternative pop, lo-fi hip-hop\nalternative pop, synth-pop\nalternative pop-rap\nalternative pop-rock\nalternative pop-rock hip-hop classical\nalternative pop-rock, hardstyle, ambient\nalternative pop-rock, industrial rock, lo-fi\nalternative rap\nalternative rap rock\nalternative rock\nalternative rock C-rock\nalternative rock Indian folk\nalternative rock Latin\nalternative rock chiptune\nalternative rock chiptune hip-hop\nalternative rock cloud rap\nalternative rock dream pop\nalternative rock drum and bass\nalternative rock electronic\nalternative rock electronic breakbeat\nalternative rock electronic hip-hop\nalternative rock electronic rock\nalternative rock electronicore\nalternative rock emo\nalternative rock emo J-rock\nalternative rock emo hyperpop\nalternative rock emo indie rock\nalternative rock emo nu-metal\nalternative rock emo pop-punk\nalternative rock emo post-grunge\nalternative rock emo post-hardcore\nalternative rock emo post-rock\nalternative rock emo rap\nalternative rock emo rap electronic\nalternative rock emo rap hyperpop\nalternative rock emo rap pop-punk\nalternative rock emo rap post-hardcore\nalternative rock emo rap post-rock\nalternative rock emo rap shoegaze\nalternative rock emo rap-rock\nalternative rock emo shoegaze\nalternative rock emo trap\nalternative rock emo-pop\nalternative rock emo-rap\nalternative rock emo-rap nu-metal\nalternative rock emo-rap pop-punk\nalternative rock emo-rap post-hardcore\nalternative rock emo-rap post-rock\nalternative rock emo-rap shoegaze\nalternative rock emo-rap trap\nalternative rock emo-rock\nalternative rock flamenco\nalternative rock flamenco Latin rock\nalternative rock flamenco theatrical\nalternative rock folk-rock\nalternative rock funk\nalternative rock funk chiptune\nalternative rock funk electronic\nalternative rock funk hip-hop\nalternative rock funk jazz fusion\nalternative rock funk psychedelic\nalternative rock funk rap-rock\nalternative rock funk reggae\nalternative rock funk rock\nalternative rock funk ska\nalternative rock funk surf rock\nalternative rock funk-rock\nalternative rock funk-rock rap-rock\nalternative rock future bass\nalternative rock gothic rock\nalternative rock grunge\nalternative rock grunge nu-metal\nalternative rock hardcore punk\nalternative rock hip-hop\nalternative rock hip-hop chiptune\nalternative rock hip-hop cinematic\nalternative rock hip-hop electronic\nalternative rock hip-hop funk\nalternative rock hip-hop future bass\nalternative rock hip-hop nu-metal\nalternative rock hip-hop soul\nalternative rock indie pop\nalternative rock indie rock\nalternative rock industrial\nalternative rock industrial gothic\nalternative rock industrial hip-hop\nalternative rock industrial rock\nalternative rock jazz fusion\nalternative rock jungle\nalternative rock lo-fi\nalternative rock lo-fi hip hop\nalternative rock lo-fi hip-hop\nalternative rock metal\nalternative rock metalcore\nalternative rock noise rock\nalternative rock nu-metal\nalternative rock nu-metal electronic\nalternative rock nu-metal emo\nalternative rock nu-metal emo rap\nalternative rock nu-metal industrial\nalternative rock nu-metal metalcore\nalternative rock nu-metal post-hardcore\nalternative rock nu-metal rap-rock\nalternative rock pop R&B\nalternative rock pop-punk\nalternative rock post-grunge\nalternative rock post-grunge emo\nalternative rock post-grunge nu-metal\nalternative rock post-hardcore\nalternative rock post-hardcore metalcore\nalternative rock post-hardcore nu-metal\nalternative rock post-punk\nalternative rock post-rock\nalternative rock progressive metal\nalternative rock psychedelic\nalternative rock punk\nalternative rock punk rock\nalternative rock rap-rock\nalternative rock shoegaze\nalternative rock ska-punk\nalternative rock soul\nalternative rock synth-pop\nalternative rock synth-pop hip-hop\nalternative rock tango\nalternative rock thrash metal\nalternative rock trap\nalternative rock trap hip-hop\nalternative rock trip-hop\nalternative rock world music\nalternative rock worldbeat\nalternative rock, 80s new wave\nalternative rock, 80s new wave, pop-rock\nalternative rock, Arabic Nasheed, Javanese spiritual\nalternative rock, C-pop\nalternative rock, C-pop, ambient\nalternative rock, C-pop, free jazz\nalternative rock, C-pop, lo-fi\nalternative rock, C-pop, rap-rock\nalternative rock, Canto-rock\nalternative rock, Chinese folk\nalternative rock, Chinese fusion\nalternative rock, Eastern European, flamenco\nalternative rock, Indian folk\nalternative rock, Indonesian hip-hop\nalternative rock, J-rock\nalternative rock, J-rock, anime\nalternative rock, J-rock, chiptune\nalternative rock, J-rock, cinematic\nalternative rock, J-rock, dream pop\nalternative rock, J-rock, electronic\nalternative rock, J-rock, emo\nalternative rock, J-rock, emo-rap\nalternative rock, J-rock, hyperpop\nalternative rock, J-rock, lo-fi hip hop\nalternative rock, J-rock, nu-metal\nalternative rock, J-rock, post-hardcore\nalternative rock, J-rock, power metal\nalternative rock, J-rock, shoegaze\nalternative rock, J-rock, synth-pop\nalternative rock, Javanese fusion\nalternative rock, Latin funk\nalternative rock, Latin fusion\nalternative rock, Latin pop, synthwave\nalternative rock, Latin pop-rock\nalternative rock, Latin rock\nalternative rock, Latin rock, cinematic\nalternative rock, Latin rock, heavy metal\nalternative rock, Latin rock, lo-fi\nalternative rock, Latin, world music\nalternative rock, MPB\nalternative rock, Middle Eastern folk\nalternative rock, Neue Deutsche Härte\nalternative rock, Neue Deutsche Welle\nalternative rock, Persian folk\nalternative rock, R&B, hip-hop\nalternative rock, South Asian folk\nalternative rock, South Asian rock\nalternative rock, Turkish folk, flamenco\nalternative rock, Turkish hip-hop\nalternative rock, UK garage\nalternative rock, UK grime\nalternative rock, acoustic ballad, Hungarian folk\nalternative rock, acoustic folk\nalternative rock, acoustic pop, post-hardcore\nalternative rock, alternative metal\nalternative rock, ambient, Indian fusion\nalternative rock, ambient, cinematic\nalternative rock, ambient, hip-hop\nalternative rock, big band, soul\nalternative rock, breakbeat, acoustic\nalternative rock, breakbeat, electronic\nalternative rock, brostep\nalternative rock, chiptune, Mandarin rap-rock\nalternative rock, chiptune, Nintendocore\nalternative rock, chiptune, Persian rock\nalternative rock, chiptune, electronic\nalternative rock, chiptune, hip hop\nalternative rock, chiptune, industrial\nalternative rock, chiptune, math rock\nalternative rock, chiptune, metalcore\nalternative rock, chiptune, nu-metal\nalternative rock, chiptune, rap-rock\nalternative rock, cinematic, C-pop\nalternative rock, cinematic, Persian rap\nalternative rock, cinematic, Uyghur hip hop\nalternative rock, cinematic, dark ambient\nalternative rock, cinematic, dubstep\nalternative rock, cinematic, electronic\nalternative rock, cinematic, hip-hop\nalternative rock, cinematic, indie\nalternative rock, cinematic, metalcore\nalternative rock, cinematic, post-grunge\nalternative rock, cinematic, post-hardcore\nalternative rock, cinematic, techno\nalternative rock, cinematic, trap\nalternative rock, classic rock\nalternative rock, cloud rap\nalternative rock, cloud rap, psychedelic\nalternative rock, complextro\nalternative rock, conscious hip-hop\nalternative rock, country\nalternative rock, crossover thrash\nalternative rock, cumbia, Mandarin rock\nalternative rock, dancehall, afro-fusion\nalternative rock, dangdut koplo\nalternative rock, dark ambient, trap\nalternative rock, dark electronic\nalternative rock, djent, post-rock\nalternative rock, dream pop\nalternative rock, dream pop, emotional\nalternative rock, dream pop, shoegaze\nalternative rock, drum and bass, lo-fi\nalternative rock, dubstep\nalternative rock, dubstep, brostep\nalternative rock, dubstep, cinematic\nalternative rock, dubstep, electronic\nalternative rock, dubstep, trap metal\nalternative rock, electronic\nalternative rock, electronic dance music\nalternative rock, electronic rock, future bass\nalternative rock, electronic, C-pop\nalternative rock, electronic, J-pop\nalternative rock, electronic, J-rock\nalternative rock, electronic, Middle Eastern\nalternative rock, electronic, ambient\nalternative rock, electronic, cinematic\nalternative rock, electronic, dark ambient\nalternative rock, electronic, dubstep\nalternative rock, electronic, hip hop\nalternative rock, electronic, hip-hop\nalternative rock, electronic, industrial\nalternative rock, electronic, nu-metal\nalternative rock, electronic, pop\nalternative rock, electronic, pop-punk\nalternative rock, electronic, trap\nalternative rock, electronicore\nalternative rock, electronicore, ambient\nalternative rock, electronicore, chiptune\nalternative rock, electronicore, cinematic\nalternative rock, electronicore, dubstep\nalternative rock, emo rap, hyperpop\nalternative rock, emo, Korean rock\nalternative rock, emo, post-hardcore\nalternative rock, emo, post-rock\nalternative rock, emo, rap-rock\nalternative rock, emo-pop, trap hip-hop\nalternative rock, emo-rock\nalternative rock, flamenco, thrash metal\nalternative rock, folk, Chinese indie\nalternative rock, folk, hard rock\nalternative rock, folk-punk, gypsy-punk\nalternative rock, funk rock, K-pop\nalternative rock, funk rock, rap rock\nalternative rock, funk, nu-metal\nalternative rock, future bass\nalternative rock, future bass, EDM\nalternative rock, future bass, dubstep\nalternative rock, future bass, melodic dubstep\nalternative rock, future bass, shoegaze\nalternative rock, hard rock\nalternative rock, hard rock, Hungarian rock\nalternative rock, hard rock, cinematic\nalternative rock, hard rock, metal\nalternative rock, hard rock, metalcore\nalternative rock, hard rock, progressive metal\nalternative rock, hard rock, thrash metal\nalternative rock, hardcore punk\nalternative rock, hardcore punk, post-rock\nalternative rock, hardstyle\nalternative rock, hardstyle, electronic\nalternative rock, hardstyle, hip-hop\nalternative rock, hardstyle, rap rock\nalternative rock, heavy metal\nalternative rock, heavy metal, cinematic\nalternative rock, heavy metal, djent\nalternative rock, heavy metal, flamenco\nalternative rock, hip hop\nalternative rock, hip hop, electronic\nalternative rock, hip hop, pop\nalternative rock, hip-hop\nalternative rock, hip-hop, Cantopop\nalternative rock, hip-hop, Indian fusion\nalternative rock, hip-hop, J-rock\nalternative rock, hip-hop, R&B\nalternative rock, hip-hop, acoustic ballad\nalternative rock, hip-hop, ambient\nalternative rock, hip-hop, cinematic\nalternative rock, hip-hop, electronic\nalternative rock, hip-hop, emotional\nalternative rock, hip-hop, emotional ballad\nalternative rock, hip-hop, experimental\nalternative rock, hip-hop, jazz\nalternative rock, hip-hop, lo-fi\nalternative rock, hip-hop, metalcore\nalternative rock, hip-hop, nu-metal\nalternative rock, hip-hop, psychedelic\nalternative rock, hip-hop, rap\nalternative rock, hip-hop, trap\nalternative rock, hip-hop, video game soundtrack\nalternative rock, hyperpop\nalternative rock, hyperpop, electronic\nalternative rock, hyperpop, electronic rock\nalternative rock, industrial metal, Neue Deutsche Härte\nalternative rock, industrial metalcore\nalternative rock, industrial metalcore, cinematic\nalternative rock, industrial rock, Turkish electronic\nalternative rock, industrial rock, world music\nalternative rock, industrial, ambient\nalternative rock, industrial, electronic\nalternative rock, industrial, emo\nalternative rock, industrial, nu-metal\nalternative rock, industrial, rap-rock\nalternative rock, industrial-pop\nalternative rock, industrial-pop, cinematic\nalternative rock, jazz noir, Romanian rock\nalternative rock, lo-fi hip hop, Arabic rap\nalternative rock, lo-fi hip hop, Chinese pop\nalternative rock, lo-fi hip hop, ambient\nalternative rock, lo-fi hip hop, emo\nalternative rock, lo-fi hip hop, soul\nalternative rock, lo-fi hip-hop\nalternative rock, lo-fi, C-pop\nalternative rock, lo-fi, Russian rap\nalternative rock, lo-fi, electronic\nalternative rock, lo-fi, hip hop\nalternative rock, lo-fi, nu-metal\nalternative rock, lounge, C-pop\nalternative rock, math rock, cinematic\nalternative rock, math rock, electronic\nalternative rock, metal, post-grunge\nalternative rock, metalcore\nalternative rock, metalcore, C-pop\nalternative rock, metalcore, French indie\nalternative rock, metalcore, ambient\nalternative rock, metalcore, atmospheric\nalternative rock, metalcore, chiptune\nalternative rock, metalcore, cinematic\nalternative rock, metalcore, cinematic synth\nalternative rock, metalcore, deathcore\nalternative rock, metalcore, desert rock\nalternative rock, metalcore, hard rock\nalternative rock, metalcore, indie rock\nalternative rock, metalcore, lo-fi\nalternative rock, metalcore, post-rock\nalternative rock, metalcore, progressive rock\nalternative rock, metalcore, psychedelic\nalternative rock, metalcore, rap-metal\nalternative rock, neurofunk\nalternative rock, new wave\nalternative rock, noir jazz, grunge\nalternative rock, noise rock\nalternative rock, noise rock, Russian rap\nalternative rock, noise rock, psychedelic\nalternative rock, noise rock, shoegaze\nalternative rock, nu-disco, dance-pop\nalternative rock, nu-metal\nalternative rock, nu-metal, C-pop\nalternative rock, nu-metal, Russian folk\nalternative rock, nu-metal, Russian rock\nalternative rock, nu-metal, UK hip-hop\nalternative rock, nu-metal, acoustic ballad\nalternative rock, nu-metal, ambient\nalternative rock, nu-metal, atmospheric\nalternative rock, nu-metal, atmospheric rock\nalternative rock, nu-metal, cinematic\nalternative rock, nu-metal, cinematic rock\nalternative rock, nu-metal, electronic\nalternative rock, nu-metal, electronic rock\nalternative rock, nu-metal, emo-rap\nalternative rock, nu-metal, emotional ballad\nalternative rock, nu-metal, emotional rock\nalternative rock, nu-metal, glitch\nalternative rock, nu-metal, hard rock\nalternative rock, nu-metal, hip-hop\nalternative rock, nu-metal, indie rock\nalternative rock, nu-metal, industrial\nalternative rock, nu-metal, industrial rock\nalternative rock, nu-metal, lo-fi\nalternative rock, nu-metal, lo-fi hip hop\nalternative rock, nu-metal, metal\nalternative rock, nu-metal, metalcore\nalternative rock, nu-metal, post-hardcore\nalternative rock, nu-metal, post-rock\nalternative rock, nu-metal, rap rock\nalternative rock, nu-metal, rap-rock\nalternative rock, nu-metal, synth funk\nalternative rock, nu-metal, trap\nalternative rock, nu-metal, world music\nalternative rock, pop-punk\nalternative rock, pop-punk, J-rock\nalternative rock, pop-punk, emo\nalternative rock, pop-punk, lo-fi\nalternative rock, pop-punk, metalcore\nalternative rock, pop-punk, rap-rock\nalternative rock, pop-rock\nalternative rock, pop-rock, nu-metal\nalternative rock, post-grunge\nalternative rock, post-grunge, Hindi rock\nalternative rock, post-grunge, Middle Eastern rock\nalternative rock, post-grunge, Persian rock\nalternative rock, post-grunge, alternative metal\nalternative rock, post-grunge, cinematic\nalternative rock, post-grunge, cinematic rock\nalternative rock, post-grunge, dream pop\nalternative rock, post-grunge, emo\nalternative rock, post-grunge, nu-metal\nalternative rock, post-grunge, progressive metal\nalternative rock, post-hardcore\nalternative rock, post-hardcore, Chinese rap\nalternative rock, post-hardcore, J-rock\nalternative rock, post-hardcore, ambient\nalternative rock, post-hardcore, chiptune\nalternative rock, post-hardcore, cinematic\nalternative rock, post-hardcore, djent\nalternative rock, post-hardcore, electronic\nalternative rock, post-hardcore, electronicore\nalternative rock, post-hardcore, emo\nalternative rock, post-hardcore, emo-rap\nalternative rock, post-hardcore, indie rock\nalternative rock, post-hardcore, lo-fi\nalternative rock, post-hardcore, lo-fi hip hop\nalternative rock, post-hardcore, math rock\nalternative rock, post-hardcore, metalcore\nalternative rock, post-hardcore, nu-metal\nalternative rock, post-hardcore, pop-punk\nalternative rock, post-hardcore, shoegaze\nalternative rock, post-punk\nalternative rock, post-punk, Eastern European\nalternative rock, post-punk, atmospheric\nalternative rock, post-punk, dream pop\nalternative rock, post-punk, indie rock\nalternative rock, post-punk, industrial\nalternative rock, post-punk, lo-fi\nalternative rock, post-punk, nu-metal\nalternative rock, post-punk, rap-rock\nalternative rock, post-punk, shoegaze\nalternative rock, post-rock\nalternative rock, post-rock, C-pop\nalternative rock, post-rock, Italian\nalternative rock, post-rock, Spanish indie\nalternative rock, post-rock, ambient\nalternative rock, post-rock, cinematic\nalternative rock, post-rock, dream pop\nalternative rock, post-rock, jazz-rock\nalternative rock, post-rock, lo-fi\nalternative rock, post-rock, math rock\nalternative rock, post-rock, metalcore\nalternative rock, post-rock, rap-rock\nalternative rock, post-rock, shoegaze\nalternative rock, post-rock, thrash metal\nalternative rock, post-rock, world music\nalternative rock, progressive house\nalternative rock, progressive house, EDM\nalternative rock, progressive metal\nalternative rock, progressive metal, Indian folk\nalternative rock, progressive metal, cinematic\nalternative rock, progressive rock, cinematic\nalternative rock, psychedelic rock, shoegaze\nalternative rock, psychedelic rock, sludge metal\nalternative rock, psychedelic, Brazilian rhythms\nalternative rock, psychedelic, hip-hop\nalternative rock, punk rock\nalternative rock, punk rock, cinematic\nalternative rock, punk rock, noise rock\nalternative rock, punk, funk-rock\nalternative rock, punk, hip-hop\nalternative rock, punk, nu-metal\nalternative rock, punk, rap-rock\nalternative rock, rap rock, lo-fi\nalternative rock, rap, shoegaze\nalternative rock, rap-rock\nalternative rock, rap-rock, cinematic\nalternative rock, rap-rock, emo\nalternative rock, rap-rock, folk rock\nalternative rock, rap-rock, industrial\nalternative rock, rap-rock, metalcore\nalternative rock, rap-rock, nu-metal\nalternative rock, rap-rock, punk\nalternative rock, rap-rock, singer-songwriter\nalternative rock, shoegaze\nalternative rock, shoegaze, Basque folk\nalternative rock, shoegaze, C-pop\nalternative rock, shoegaze, Indian indie\nalternative rock, shoegaze, J-rock\nalternative rock, shoegaze, R&B\nalternative rock, shoegaze, ambient\nalternative rock, shoegaze, cinematic\nalternative rock, shoegaze, dream pop\nalternative rock, shoegaze, noise rock\nalternative rock, shoegaze, post-hardcore\nalternative rock, shoegaze, post-rock\nalternative rock, shoegaze, trap\nalternative rock, ska-punk\nalternative rock, skate punk\nalternative rock, soul, hip hop\nalternative rock, southern rock\nalternative rock, surf rock, synth-pop\nalternative rock, symphonic metal\nalternative rock, symphonic metal, ambient\nalternative rock, synth-pop\nalternative rock, synth-pop, J-rock\nalternative rock, synth-pop, chiptune\nalternative rock, synth-pop, hip-hop\nalternative rock, synth-pop, new wave\nalternative rock, synth-pop, piano ballad\nalternative rock, synth-pop, world music\nalternative rock, theatrical rock, operatic rock\nalternative rock, thrash metal\nalternative rock, thrash metal, classical guitar\nalternative rock, thrash metal, lo-fi\nalternative rock, thrash metal, progressive rock\nalternative rock, thrash metal, shoegaze\nalternative rock, trap\nalternative rock, trap R&B\nalternative rock, trap metal\nalternative rock, trap metal, emo rap\nalternative rock, trap metal, hyperpop\nalternative rock, trap, Thai hip hop\nalternative rock, trap, ambient\nalternative rock, trap, cinematic\nalternative rock, trap, cloud rap\nalternative rock, trap, electronic\nalternative rock, trap, emo rap\nalternative rock, trap, glitch-hop\nalternative rock, trap, hip hop\nalternative rock, trap, hip-hop\nalternative rock, trap, hyperpop\nalternative rock, trap, industrial\nalternative rock, trap, lo-fi\nalternative rock, trap-metal\nalternative rock, trip-hop\nalternative rock, trip-hop, Turkish\nalternative rock, trip-hop, ambient\nalternative rock, trip-hop, cinematic\nalternative rock, trip-hop, electronic\nalternative rock, trip-hop, jazzy\nalternative rock, trip-hop, noise rock\nalternative rock, trip-hop, shoegaze\nalternative rock, world folk, C-pop\nalternative rock, world fusion, Middle Eastern\nalternative rock, world music\nalternative rock, world music, C-pop\nalternative rock, world music, Hebrew vocal\nalternative rock, world music, funk\nalternative rock, world music, post-rock\nalternative rock, world music, synthwave\nalternative soul\nalternative trap\nalternative, video game, synthwave\nambient\nambient Americana\nambient Arabic\nambient Bollywood\nambient C-pop\nambient Chinese\nambient Chinese classical\nambient Chinese flute\nambient Chinese folk\nambient Chinese pop\nambient Christian rock\nambient Christmas\nambient EDM\nambient IDM\nambient Indian\nambient Indian ballad\nambient Indian classical\nambient Indian electronica\nambient Indian folk\nambient Indian fusion\nambient Islamic\nambient Islamic devotional\nambient J-pop\nambient K-pop\nambient Latin\nambient Latin folk\nambient Latin jazz\nambient Latin pop\nambient R&B\nambient R&B future bass\nambient R&B trap\nambient R&B trap soul\nambient R&B trap-soul\nambient R&B, cloud rap, lo-fi hip-hop\nambient R&B, conscious hip-hop, cinematic\nambient R&B, trap-R&B\nambient Sufi\nambient Tamil\nambient UK garage\nambient a cappella\nambient acapella\nambient acid jazz\nambient acoustic\nambient afro-fusion\nambient afrobeat\nambient afrobeats\nambient alternative rock\nambient americana\nambient anasheed\nambient anthemic\nambient arabesque\nambient arabic\nambient art pop\nambient art song\nambient art-pop\nambient art-rock\nambient ballad\nambient ballad, Bollywood fusion\nambient baroque\nambient bass\nambient beatbox\nambient beatboxing\nambient bhajan\nambient big beat\nambient blues\nambient blues-rock\nambient bossa nova\nambient breakbeat\nambient breakbeat IDM\nambient breakcore\nambient breakcore chiptune\nambient breakcore techno\nambient cello\nambient chamber\nambient chanson\nambient chant\nambient children's\nambient children's choir\nambient children's music\nambient chill\nambient chill trap\nambient chillhop\nambient chillout\nambient chillwave\nambient chillwave cinematic\nambient chillwave downtempo\nambient chillwave post-rock\nambient chillwave progressive house\nambient chiptune\nambient chiptune cinematic\nambient chiptune orchestral\nambient choir\nambient choral\nambient christmas\nambient cinematic\nambient cinematic lo-fi hip-hop\nambient classical\nambient classical crossover\nambient country\nambient dark\nambient dark ambient\nambient dark choir\nambient dark choral\nambient dark classical\nambient dark fairytale\nambient dark fantasy\nambient dark pop\nambient dark wave\nambient darkwave\nambient deep house\nambient dembow\nambient devotional\nambient dizi\nambient dnb\nambient downtempo\nambient downtempo chillwave\nambient downtempo cinematic\nambient downtempo trip-hop\nambient downtempo world music\nambient drama\nambient dream\nambient dream pop\nambient dream pop post-rock\nambient dream pop vaporwave\nambient dream pop, synthwave\nambient dream-pop\nambient drone\nambient drone post-rock\nambient drone trap\nambient drone, chillwave, Indian classical\nambient drone, cinematic, orchestral\nambient drone, post-rock, psychedelic rock\nambient drone, techno, progressive house\nambient drum\nambient drum & bass\nambient drum and bass\nambient drum and bass chillwave\nambient dub\nambient dubstep\nambient duduk\nambient duet\nambient educational\nambient electro\nambient electro-funk\nambient electronic\nambient electronic rock\nambient electronic worship\nambient electronic, chillwave, Indian classical fusion\nambient electronica\nambient electronica chillwave\nambient electronica lo-fi hip-hop\nambient electronica trip-hop\nambient erhu\nambient ethereal\nambient ethno\nambient ethno-electronic\nambient experimental\nambient falsetto\nambient fantasy\nambient field recording\nambient film score\nambient filmi\nambient fingerstyle\nambient flamenco\nambient flute\nambient folk\nambient folk metalcore\nambient folk pop\nambient folk post-rock\nambient folk rock\nambient folk, funk, pop\nambient folk-pop\nambient folk-rock\nambient funk\nambient funk lounge\nambient funk rock\nambient funk soul\nambient funk-rock\nambient funk-rock jazz fusion\nambient fusion\nambient future bass\nambient future garage\nambient future garage cinematic electronic\nambient gamelan\nambient ghazal\nambient glitch\nambient glitch hip-hop\nambient glitch jazz\nambient glitch-hop\nambient glitch-hop future bass\nambient gospel\nambient gospel hip-hop\nambient gospel rock\nambient gospel salsa\nambient gospel trap\nambient gothic\nambient grime\nambient groove\nambient grooves\nambient guitar\nambient guzheng\nambient hard trance\nambient hardstyle\nambient harp\nambient hip hop\nambient hip-hop\nambient hip-hop trip-hop\nambient holiday\nambient horror\nambient house\nambient house future bass\nambient house soul\nambient hymn\nambient hyperpop\nambient indie\nambient indie folk\nambient indie pop\nambient indie rock\nambient indie-folk\nambient indie-pop\nambient industrial\nambient industrial metal\nambient industrial rock\nambient instrumental\nambient jazz\nambient jazz cabaret\nambient jazz fusion\nambient jazz lounge\nambient jazz-funk\nambient jazz-fusion\nambient jungle\nambient kalimba\nambient korean\nambient koto\nambient lament\nambient liquid drum and bass\nambient lo-fi\nambient lo-fi R&B\nambient lo-fi chillwave\nambient lo-fi future bass\nambient lo-fi hip hop\nambient lo-fi hip-hop\nambient lo-fi trap\nambient loop\nambient lounge\nambient lullaby\nambient mallet\nambient mantra\nambient math-rock\nambient medieval\nambient meditation\nambient melancholic\nambient melancholy\nambient metal\nambient metalcore\nambient minimal\nambient minimalism\nambient music box\nambient narrative\nambient nasheed\nambient nature\nambient neo-classical\nambient neo-soul\nambient neo-soul gospel\nambient neoclassical\nambient new age\nambient new age, traditional Chinese folk, electronic\nambient new jack swing\nambient new-age\nambient ney\nambient noir\nambient noise\nambient noise rock\nambient nu-disco\nambient nu-jazz\nambient opera\nambient orchestral\nambient organ\nambient oud\nambient pastoral\nambient percussion\nambient phonk\nambient piano\nambient piano lo-fi\nambient piano, acoustic folk\nambient poetry\nambient polka\nambient pop\nambient pop chillwave\nambient pop downtempo R&B\nambient pop dream pop\nambient pop emo rap\nambient pop emo trap\nambient pop future bass\nambient pop future garage\nambient pop lo-fi\nambient pop lo-fi R&B\nambient pop lo-fi hip-hop\nambient pop post-rock\nambient pop rock\nambient pop trap\nambient pop vaporwave\nambient pop world music\nambient pop, C-pop, R&B\nambient pop, Christian hip-hop, worship\nambient pop, Indian R&B, trap\nambient pop, Indian electronic\nambient pop, R&B\nambient pop, R&B, South African soul\nambient pop, R&B, gospel\nambient pop, Turkish hip-hop\nambient pop, UK hip-hop\nambient pop, UK trap\nambient pop, alternative R&B\nambient pop, alternative R&B, lo-fi hip hop\nambient pop, alternative R&B, lo-fi hip-hop\nambient pop, alternative rock\nambient pop, bhajan, lo-fi hip hop\nambient pop, breakcore\nambient pop, chillwave\nambient pop, cinematic, future bass\nambient pop, cinematic, trap\nambient pop, cinematic, trip-hop\nambient pop, cloud rap, emotional trap\nambient pop, cloud rap, lo-fi trap\nambient pop, conscious hip-hop\nambient pop, deep house\nambient pop, deep house, minimal techno\nambient pop, downtempo, trip-hop\nambient pop, dream pop, cinematic\nambient pop, dream pop, lo-fi electronic\nambient pop, dubstep, EDM\nambient pop, electronic, C-pop rock\nambient pop, epic new age\nambient pop, experimental R&B, lo-fi trap\nambient pop, future bass\nambient pop, future bass, electronic rock\nambient pop, future garage, lo-fi trap\nambient pop, hardstyle\nambient pop, hyperpop\nambient pop, hyperpop, J-pop\nambient pop, industrial breakbeat\nambient pop, lo-fi hip hop\nambient pop, lo-fi hip hop, C-pop\nambient pop, lo-fi hip hop, CCM\nambient pop, lo-fi hip hop, French R&B\nambient pop, lo-fi hip hop, South Asian\nambient pop, lo-fi hip hop, Vietnamese folk\nambient pop, lo-fi hip hop, contemporary R&B\nambient pop, lo-fi hip hop, trap\nambient pop, lo-fi hip-hop\nambient pop, lo-fi hip-hop, Indian music\nambient pop, lo-fi hip-hop, emotional R&B\nambient pop, lo-fi hip-hop, emotional indie\nambient pop, metalcore, dubstep\nambient pop, modern Arabic\nambient pop, neo-soul, trip-hop\nambient pop, neo-soul, world music\nambient pop, new age\nambient pop, spiritual music\nambient pop, trap\nambient pop, trap R&B\nambient pop, trap, C-pop\nambient pop, trap, Indian music\nambient pop, trap, R&B\nambient pop, trap, alternative R&B\nambient pop, trap, electronic\nambient pop, trap, hip-hop\nambient pop, trip-hop, lo-fi hip hop\nambient pop, world music\nambient pop-punk\nambient pop-rock\nambient post-hardcore\nambient post-punk\nambient post-rock\nambient prayer\nambient progressive\nambient progressive electronic\nambient progressive house\nambient progressive house drum and bass\nambient progressive metal\nambient progressive rock\nambient progressive trance\nambient protest\nambient psychedelic\nambient psychedelic funk\nambient psychedelic rock\nambient psytrance\nambient qanun\nambient qawwali\nambient raga\nambient rap\nambient reggae\nambient reggaeton\nambient ritual\nambient ritualistic\nambient rock\nambient rock dream pop\nambient rock emo-rap\nambient rock future bass\nambient rock grunge\nambient rock heartland rock\nambient rock indie rock\nambient rock lo-fi hip-hop\nambient rock metalcore\nambient rock post-hardcore\nambient rock post-metal\nambient rock post-rock\nambient rock progressive metal\nambient rock trap\nambient rock, Brazilian MPB\nambient rock, Christian rock, ska-punk\nambient rock, future bass\nambient rock, future bass, electronic\nambient rock, post-rock, shoegaze\nambient rock, trap, C-pop\nambient sacred\nambient samba-rock\nambient sci-fi\nambient sermon\nambient shoegaze\nambient singer-songwriter\nambient sitar\nambient slide guitar\nambient smooth jazz\nambient sorrow\nambient soul\nambient sound\nambient sound design\nambient sounds\nambient soundscapes\nambient spiritual\nambient spirituality\nambient spoken word\nambient storytelling\nambient surf-rock\nambient synth\nambient synth-pop\nambient synthwave\nambient synthwave downtempo\nambient synthwave dream pop\nambient tabla\nambient tango\nambient tango progressive rock\nambient tech house\nambient tech-house\nambient techno\nambient techno darkwave\nambient techno, deep house\nambient techno, drum and bass\nambient tension\nambient theater\nambient torch\nambient torch song\nambient toy\nambient traditional\nambient trance\nambient trap\nambient trap R&B\nambient trap chillwave\nambient trap cinematic\nambient trap future bass\nambient trap future garage\nambient trap gospel\nambient trap lo-fi hip-hop\nambient trap metal\nambient trap metalcore\nambient trap phonk\nambient trap post-rock\nambient trap psytrance\nambient trap soul\nambient trap vaporwave\nambient trap world music\nambient tribal\nambient tribal house\nambient trip-hop\nambient trip-hop Indian fusion\nambient trip-hop cinematic\nambient trip-hop downtempo\nambient trip-hop dream pop\nambient trip-hop dream-pop\nambient trip-hop electronica\nambient trip-hop experimental\nambient trip-hop future garage\nambient trip-hop lo-fi\nambient tropical\nambient tropical house\nambient ukulele\nambient urban\nambient vaporwave\nambient video game\nambient violin\nambient vocal\nambient woodwind\nambient world\nambient world beat\nambient world cinematic\nambient world electronic\nambient world fusion\nambient world jazz\nambient world music\nambient world pop\nambient worldbeat\nambient worship\nambient worship, future bass\nambient yoga\nambient zither\nambient, Arabic Mawwal, ethereal\nambient, Arabic, cinematic\nambient, Arabic, epic\nambient, Arabic, ethereal\nambient, Arabic, melancholic\nambient, Arabic, minimalist\nambient, Brazilian, cinematic\nambient, Carnatic, ethereal\nambient, Celtic folk-rock\nambient, Celtic, cinematic\nambient, Chinese ambient, lo-fi\nambient, Chinese classical, lo-fi\nambient, Chinese classical, meditative\nambient, Chinese flute, cinematic\nambient, Chinese flute, meditative\nambient, Chinese folk, meditative\nambient, Chinese traditional, cinematic\nambient, Chinese traditional, ethereal\nambient, Chinese traditional, lo-fi\nambient, EBM, cinematic\nambient, EBM, industrial techno\nambient, East Asian\nambient, East Asian, cinematic\nambient, East Asian, fantasy\nambient, East Asian, instrumental\nambient, East Asian, lo-fi\nambient, East Asian, meditative\nambient, East Asian, minimalist\nambient, Gu Feng, traditional Chinese\nambient, Hawaiian, cinematic\nambient, IDM\nambient, IDM, breakcore\nambient, IDM, cinematic\nambient, IDM, drum and bass\nambient, IDM, electronic\nambient, IDM, experimental\nambient, IDM, future garage\nambient, IDM, glitch\nambient, IDM, modern classical\nambient, Indian classical, chamber\nambient, Indian classical, chant\nambient, Indian classical, cinematic\nambient, Indian classical, electronic\nambient, Indian classical, ethereal\nambient, Indian classical, lo-fi\nambient, Indian classical, meditative\nambient, Indian classical, new age\nambient, Indian classical, spiritual\nambient, Indian devotional, spiritual\nambient, Indian folk, meditative\nambient, Islamic devotional\nambient, Japanese folk, cinematic\nambient, Latin jazz fusion\nambient, Middle Eastern, instrumental\nambient, Slavic folk, cinematic\nambient, Turkish folk, microtonal\nambient, Turkish lament\nambient, ancient style\nambient, ancient style, instrumental\nambient, ancient style, lo-fi\nambient, ancient style, meditation\nambient, ancient style, meditative\nambient, atmospheric, Chinese ambient\nambient, baile funk, experimental\nambient, bansuri, meditative\nambient, baroque, cinematic\nambient, baroque, fantasy\nambient, breakbeat, IDM\nambient, breakbeat, cinematic\nambient, breakcore, drum and bass\nambient, breakcore, shoegaze\nambient, cabaret-rock\nambient, celestial, choral\nambient, children's music, traditional Chinese\nambient, chill, cinematic\nambient, chillwave, cinematic\nambient, chillwave, downtempo\nambient, chillwave, drum and bass\nambient, chillwave, future garage\nambient, chillwave, lo-fi hip-hop\nambient, chiptune, baroque\nambient, chiptune, cinematic\nambient, chiptune, electronic\nambient, choral, Christmas\nambient, choral, ancient style\nambient, choral, cinematic\nambient, choral, new age\nambient, choral, spiritual\nambient, choral, world music\nambient, cinematic electronica, progressive trance\nambient, cinematic, African narrative\nambient, cinematic, Arabic\nambient, cinematic, Arabic spoken word\nambient, cinematic, Arabic vocal\nambient, cinematic, C-pop\nambient, cinematic, Chinese ambient\nambient, cinematic, Chinese classical\nambient, cinematic, Chinese ethereal\nambient, cinematic, Chinese experimental\nambient, cinematic, Chinese flute\nambient, cinematic, Chinese folk\nambient, cinematic, Chinese melancholy\nambient, cinematic, Chinese mystical\nambient, cinematic, Chinese spoken word\nambient, cinematic, Chinese traditional\nambient, cinematic, East Asian\nambient, cinematic, Hindi\nambient, cinematic, Indian classical\nambient, cinematic, Indonesian\nambient, cinematic, Japanese ambient\nambient, cinematic, Japanese vocal\nambient, cinematic, Korean ballad\nambient, cinematic, Middle Eastern\nambient, cinematic, Native American flute\nambient, cinematic, Persian classical\nambient, cinematic, Persian folk\nambient, cinematic, RPG\nambient, cinematic, Russian opera\nambient, cinematic, South Asian classical\nambient, cinematic, Turkish classical\nambient, cinematic, Turkish folk\nambient, cinematic, ancient style\nambient, cinematic, breakbeat\nambient, cinematic, chamber\nambient, cinematic, chillwave\nambient, cinematic, chiptune\nambient, cinematic, choral\nambient, cinematic, christmas\nambient, cinematic, classical\nambient, cinematic, dark ambient\nambient, cinematic, dark wave\nambient, cinematic, downtempo\nambient, cinematic, dream-pop\nambient, cinematic, drum and bass\nambient, cinematic, educational\nambient, cinematic, electronic\nambient, cinematic, epic\nambient, cinematic, ethereal\nambient, cinematic, experimental\nambient, cinematic, fantasy\nambient, cinematic, flamenco\nambient, cinematic, folk\nambient, cinematic, future garage\nambient, cinematic, glitch\nambient, cinematic, glitch hop\nambient, cinematic, gregorian\nambient, cinematic, guzheng\nambient, cinematic, hymn-like\nambient, cinematic, industrial\nambient, cinematic, industrial electronic\nambient, cinematic, jazz fusion\nambient, cinematic, liturgical\nambient, cinematic, lo-fi\nambient, cinematic, lo-fi electronic\nambient, cinematic, meditative\nambient, cinematic, mystical\nambient, cinematic, neo-classical\nambient, cinematic, neoclassical\nambient, cinematic, neurofunk\nambient, cinematic, new age\nambient, cinematic, ney\nambient, cinematic, ney flute\nambient, cinematic, operatic\nambient, cinematic, orchestral\nambient, cinematic, post-rock\nambient, cinematic, progressive house\nambient, cinematic, progressive trance\nambient, cinematic, ritual\nambient, cinematic, sacred\nambient, cinematic, shakuhachi\nambient, cinematic, shoegaze\nambient, cinematic, spiritual\nambient, cinematic, traditional\nambient, cinematic, traditional Chinese\nambient, cinematic, traditional Chinese folk\nambient, cinematic, traditional East Asian\nambient, cinematic, traditional Japanese\nambient, cinematic, traditional Korean\nambient, cinematic, trance\nambient, cinematic, tribal\nambient, cinematic, trip-hop\nambient, cinematic, video game music\nambient, cinematic, world\nambient, cinematic, world fusion\nambient, cinematic, world music\nambient, cinematic, world percussion\nambient, classical, choral\nambient, classical, cinematic\nambient, classical, ethereal\nambient, classical, lo-fi\nambient, cyber-pop\nambient, dark ambient, Middle Eastern\nambient, dark ambient, ethereal\nambient, dark wave, cinematic\nambient, devotional, Islamic\nambient, devotional, South Asian\nambient, downtempo, cinematic\nambient, downtempo, electronic lounge\nambient, downtempo, ethereal\nambient, downtempo, lo-fi\nambient, downtempo, new age\nambient, downtempo, spiritual\nambient, downtempo, spiritual electronic\nambient, downtempo, tribal house\nambient, downtempo, world\nambient, downtempo, world music\nambient, dream pop, Arabic ambient\nambient, dream pop, Chinese ambient\nambient, dream-pop, post-rock\nambient, drone, Indian classical\nambient, drum and bass, IDM\nambient, drum and bass, cinematic\nambient, duduk, meditative\nambient, east asian, instrumental\nambient, electronic, C-pop\nambient, electronic, Chinese experimental\nambient, electronic, experimental\nambient, electronic, neo-psychedelia\nambient, electronic, synthwave\nambient, electronic, traditional Chinese\nambient, emotional, Arabic\nambient, epic rock, choral\nambient, erhu, melancholic\nambient, ethereal, Arabic\nambient, ethereal, Arabic Mawwal\nambient, ethereal, Arabic ambient\nambient, ethereal, Arabic fusion\nambient, ethereal, Arabic vocal\nambient, ethereal, Chinese ambient\nambient, ethereal, Chinese classical\nambient, ethereal, Chinese experimental\nambient, ethereal, Chinese flute\nambient, ethereal, Chinese opera\nambient, ethereal, Chinese traditional\nambient, ethereal, East Asian\nambient, ethereal, Greek vocal\nambient, ethereal, Indian classical\nambient, ethereal, Japanese folk\nambient, ethereal, Japanese vocal\nambient, ethereal, Middle Eastern\nambient, ethereal, Persian traditional\nambient, ethereal, South Asian\nambient, ethereal, South Asian classical\nambient, ethereal, Tamil\nambient, ethereal, Turkish classical\nambient, ethereal, Turkish lullaby\nambient, ethereal, ancient style\nambient, ethereal, bansuri\nambient, ethereal, choral\nambient, ethereal, cinematic\nambient, ethereal, classical\nambient, ethereal, devotional\nambient, ethereal, electronic\nambient, ethereal, experimental\nambient, ethereal, guzheng\nambient, ethereal, lo-fi\nambient, ethereal, meditation\nambient, ethereal, meditative\nambient, ethereal, new age\nambient, ethereal, operatic\nambient, ethereal, oriental\nambient, ethereal, oud\nambient, ethereal, sacred\nambient, ethereal, spiritual\nambient, ethereal, traditional Chinese\nambient, ethereal, traditional fusion\nambient, ethereal, trance\nambient, ethereal, trap\nambient, ethereal, vocal\nambient, ethereal, world\nambient, ethereal, world fusion\nambient, ethereal, world music\nambient, ethnic electronica, cinematic\nambient, experimental drum and bass, hyperpop\nambient, experimental, Chinese avant-garde\nambient, experimental, IDM\nambient, experimental, chiptune\nambient, experimental, cinematic\nambient, experimental, dark ambient\nambient, experimental, glitch\nambient, experimental, new age\nambient, funk-rock, cinematic\nambient, future garage, cinematic\nambient, future pop\nambient, futuristic, electronic\nambient, glitch, drum and bass\nambient, glitch, electronic\nambient, glitch, experimental\nambient, guzheng, cinematic\nambient, guzheng, dizi\nambient, guzheng, ethereal\nambient, guzheng, lo-fi\nambient, guzheng, meditation\nambient, guzheng, meditative\nambient, guzheng, shakuhachi\nambient, guzheng, spiritual\nambient, happy hardcore, hardstyle\nambient, hardstyle, cinematic\nambient, hardstyle, lo-fi\nambient, indie rock\nambient, industrial electronic\nambient, industrial techno\nambient, industrial, cinematic\nambient, industrial, electronic\nambient, instrumental, Chinese traditional\nambient, instrumental, East Asian\nambient, instrumental, ancient style\nambient, instrumental, bansuri\nambient, instrumental, cinematic\nambient, instrumental, lo-fi\nambient, instrumental, meditation\nambient, instrumental, meditative\nambient, instrumental, traditional\nambient, instrumental, traditional fusion\nambient, liquid drum and bass\nambient, liquid drum and bass, cinematic\nambient, lo-fi hip hop, cinematic\nambient, lo-fi hip hop, experimental\nambient, lo-fi hip-hop, post-rock\nambient, lo-fi hip-hop, progressive electronic\nambient, lo-fi, Chinese atmospheric\nambient, lo-fi, Chinese ethereal\nambient, lo-fi, Chinese poetry\nambient, lo-fi, Indian classical\nambient, lo-fi, Indonesian spoken word\nambient, lo-fi, ancient style\nambient, lo-fi, bansuri\nambient, lo-fi, chillwave\nambient, lo-fi, cinematic\nambient, lo-fi, contemplative\nambient, lo-fi, indie-electronic\nambient, lo-fi, traditional Chinese\nambient, lo-fi, traditional East Asian\nambient, meditative, C-pop\nambient, meditative, Chinese ambient\nambient, meditative, Chinese classical\nambient, meditative, Chinese flute\nambient, meditative, Chinese folk\nambient, meditative, Chinese traditional\nambient, meditative, East Asian\nambient, meditative, East Asian folk\nambient, meditative, Eastern-influenced\nambient, meditative, Indian classical\nambient, meditative, Indian fusion\nambient, meditative, ancient style\nambient, meditative, bansuri\nambient, meditative, cinematic\nambient, meditative, electronic\nambient, meditative, guzheng\nambient, meditative, instrumental\nambient, meditative, lo-fi\nambient, meditative, shakuhachi\nambient, meditative, sitar\nambient, meditative, spiritual\nambient, meditative, traditional\nambient, meditative, traditional Chinese\nambient, meditative, traditional fusion\nambient, meditative, world\nambient, meditative, world fusion\nambient, meditative, world instrumental\nambient, meditative, world music\nambient, melancholic, Arabic\nambient, melancholic, Arabic electronica\nambient, melancholic, Arabic vocal\nambient, melancholic, Indian classical\nambient, melancholic, Middle Eastern\nambient, melancholic, Mongolian folk\nambient, melancholic, ancient style\nambient, melancholic, bansuri\nambient, melancholic, cinematic\nambient, melancholic, experimental\nambient, melancholic, traditional South Asian\nambient, microtonal, Arabic\nambient, microtonal, world\nambient, minimal, electronic\nambient, minimalist, guzheng\nambient, music box, traditional Chinese\nambient, mystical, Middle Eastern\nambient, mystical, ancient style\nambient, mystical, downtempo\nambient, mystical, experimental\nambient, mystical, lo-fi\nambient, neo-ambient, world\nambient, neo-classical, experimental\nambient, neo-classical, shakuhachi\nambient, neo-classical, spiritual\nambient, neoclassical, choral\nambient, neoclassical, cinematic\nambient, neoclassical, darkwave\nambient, neoclassical, trip-hop\nambient, neurofunk, drum and bass\nambient, new age\nambient, new age, Buddhist music\nambient, new age, C-pop\nambient, new age, Chinese traditional\nambient, new age, East Asian\nambient, new age, East Asian folk\nambient, new age, Indian classical\nambient, new age, Indian devotional\nambient, new age, Javanese devotional\nambient, new age, acapella\nambient, new age, chiptune\nambient, new age, cinematic\nambient, new age, classical crossover\nambient, new age, downtempo\nambient, new age, electronic\nambient, new age, ethereal\nambient, new age, ethereal wave\nambient, new age, fantasy\nambient, new age, gospel\nambient, new age, progressive electronic\nambient, new age, psytrance\nambient, new age, sacred music\nambient, new age, smooth jazz\nambient, new age, spiritual\nambient, new age, spiritual electronic\nambient, new age, synthwave\nambient, new age, traditional Chinese\nambient, new age, world fusion\nambient, new age, world music\nambient, new-age, C-pop\nambient, new-age, Gregorian\nambient, new-age, cinematic\nambient, new-age, downtempo\nambient, new-age, ethereal\nambient, new-age, guzheng\nambient, new-age, spiritual\nambient, new-age, traditional East Asian\nambient, new-age, world fusion\nambient, ney flute, meditative\nambient, ney flute, spiritual\nambient, ney, Middle Eastern\nambient, ney, cinematic\nambient, ney, meditative\nambient, ney, oud\nambient, ney, spiritual\nambient, noise rock, experimental\nambient, operatic, sacred\nambient, orchestral electronic, new age\nambient, orchestral, indie rock\nambient, oud, ethereal\nambient, pastoral, instrumental\nambient, playful, instrumental\nambient, post-rock, cinematic\nambient, post-rock, indie rock\nambient, progressive electronic\nambient, progressive electronic, trap\nambient, progressive house\nambient, progressive house, industrial rock\nambient, progressive house, melodic techno\nambient, progressive house, trance\nambient, progressive metal\nambient, progressive rock\nambient, progressive rock, cinematic\nambient, progressive rock, ethereal\nambient, progressive trance, chillwave\nambient, progressive trance, experimental\nambient, progressive trance, melodic techno\nambient, progressive trance, synthwave\nambient, psychedelic rock, ethereal\nambient, psytrance, hardstyle\nambient, rock, operatic\nambient, sacred, cinematic\nambient, sacred, folk\nambient, sacred, world\nambient, shakuhachi, cinematic\nambient, shakuhachi, downtempo\nambient, shakuhachi, meditative\nambient, shakuhachi, spiritual\nambient, shoegaze, dream pop\nambient, soul, electronic\nambient, spiritual, Arabic\nambient, spiritual, Arabic Mawwal\nambient, spiritual, C-pop\nambient, spiritual, Celtic new age\nambient, spiritual, Chinese\nambient, spiritual, Chinese traditional\nambient, spiritual, Indian classical\nambient, spiritual, Indian devotional\nambient, spiritual, Indian folk\nambient, spiritual, Islamic chant\nambient, spiritual, Japanese\nambient, spiritual, Middle Eastern\nambient, spiritual, Persian classical\nambient, spiritual, Sanskrit chant\nambient, spiritual, South Asian devotional\nambient, spiritual, Sufi\nambient, spiritual, Turkish folk\nambient, spiritual, Vietnamese traditional\nambient, spiritual, acoustic\nambient, spiritual, ancient style\nambient, spiritual, bansuri\nambient, spiritual, choral\nambient, spiritual, cinematic\nambient, spiritual, devotional\nambient, spiritual, drone\nambient, spiritual, electronic\nambient, spiritual, ethereal\nambient, spiritual, folk\nambient, spiritual, lo-fi\nambient, spiritual, mantra\nambient, spiritual, meditative\nambient, spiritual, neo-ethnic\nambient, spiritual, post-rock\nambient, spiritual, shakuhachi\nambient, spiritual, synth-pop\nambient, spiritual, tanpura\nambient, spiritual, traditional Chinese\nambient, spiritual, world\nambient, spiritual, world fusion\nambient, spoken word, ancient style\nambient, synthwave, cinematic\nambient, synthwave, progressive rock\nambient, theatrical, ancient style\nambient, traditional Arabic, spiritual\nambient, traditional Asian, meditative\nambient, traditional Chinese folk, meditative\nambient, traditional Chinese, cinematic\nambient, traditional Chinese, electronic\nambient, traditional Chinese, ethereal\nambient, traditional Chinese, lo-fi\nambient, traditional Chinese, meditative\nambient, traditional Chinese, spiritual\nambient, traditional East Asian\nambient, traditional East Asian, chillout\nambient, traditional East Asian, cinematic\nambient, traditional East Asian, electronic\nambient, traditional East Asian, instrumental\nambient, traditional East Asian, meditative\nambient, traditional East Asian, spiritual\nambient, traditional Japanese, electronic\nambient, traditional Japanese, ethereal\nambient, traditional South Asian, downtempo\nambient, traditional, east asian\nambient, traditional, ethereal\nambient, traditional, lo-fi\nambient, trance, world music\nambient, trap, spiritual\nambient, tribal electronic, cinematic\nambient, tribal, cinematic\nambient, tribal, meditative\nambient, tribal, mystical\nambient, tribal, world\nambient, trip-hop, cinematic\nambient, trip-hop, downtempo\nambient, trip-hop, drum and bass\nambient, trip-hop, industrial\nambient, trip-hop, lo-fi\nambient, trip-hop, progressive house\nambient, trip-hop, shoegaze\nambient, trip-hop, spiritual\nambient, vocal, experimental\nambient, world fusion, chillout\nambient, world fusion, cinematic\nambient, world fusion, electronic\nambient, world fusion, ethereal\nambient, world fusion, meditative\nambient, world fusion, new age\nambient, world fusion, new age electronica\nambient, world fusion, progressive house\nambient, world fusion, spiritual\nambient, world fusion, spiritual electronic\nambient, world music, choral\nambient, world music, cinematic\nambient, world music, devotional\nambient, world music, downtempo\nambient, world music, electronic\nambient, world music, ethereal\nambient, world music, meditative\nambient, world music, new age\nambient, world music, spiritual\nambient, world music, spiritual chant\nambient, world music, tribal house\nambient, world, classical\nambient, world, electronic\nambient, world, lo-fi\nambient, world, meditation\nambient, world, meditative\nambient, worldbeat, new age\nanasheed\nancient style\nancient style, duduk, cinematic\nancient trap\nancient world folk\nanimated film score\nanimation sound effect\nanime\nanime C-pop\nanime C-pop rock\nanime EDM\nanime J-pop\nanime J-rock\nanime ambient\nanime anthem\nanime ballad\nanime ballad lo-fi hip-hop\nanime ballad, J-rock\nanime ballad, J-rock, cinematic\nanime ballad, J-rock, cinematic pop\nanime ballad, artcore, electronic\nanime ballad, cinematic pop, C-pop\nanime ballad, cinematic pop, East Asian fusion\nanime ballad, cinematic pop, chiptune\nanime ballad, cinematic, J-pop\nanime ballad, cinematic, lo-fi\nanime ballad, hardstyle, C-pop\nanime ballad, power metal, cinematic rock\nanime ballad, symphonic rock, metalcore\nanime ballad, trap metal, rock\nanime battle\nanime battle anthem\nanime battle music\nanime battle rap\nanime battle theme\nanime cumbia\nanime electronic\nanime electronic ballad\nanime electronic pop\nanime electronic rock\nanime electronic, C-pop, Guofeng\nanime ending\nanime ending theme\nanime funk rock\nanime funk-pop\nanime fusion\nanime hardstyle\nanime hip hop\nanime hip-hop\nanime hip-hop trap\nanime horror\nanime jazz-pop\nanime jazz-rock\nanime lo-fi\nanime lullaby\nanime music\nanime opening\nanime orchestral\nanime orchestral pop\nanime ost\nanime pop\nanime pop ballad\nanime pop future bass\nanime pop rap\nanime pop rock\nanime pop trap\nanime pop world music\nanime pop, J-rock\nanime pop, UK hardcore\nanime pop, Vocaloid, electronic\nanime pop, big band, theatrical\nanime pop, children's pop, J-pop\nanime pop, emo-rap, lo-fi\nanime pop, hardstyle, cinematic\nanime pop, hyperpop\nanime pop, kawaii future bass, Chinese folk\nanime pop, lo-fi hip hop, hyperpop\nanime pop-punk\nanime pop-rap\nanime pop-rock\nanime pop-trap\nanime power ballad\nanime power metal\nanime power pop\nanime power pop-rock\nanime power rock\nanime power-pop\nanime punk rock\nanime rap\nanime rap lo-fi hip hop\nanime rap trap\nanime rap-rock\nanime rock\nanime rock ballad\nanime rock hip-hop\nanime rock metalcore\nanime rock power metal\nanime rock, cinematic rock, J-rock\nanime rock, electronic, traditional Chinese\nanime rock, hyperpop\nanime rock, metal, Chinese fusion\nanime rock, pop-punk, Latin pop\nanime rockabilly\nanime score\nanime show tune\nanime soundtrack\nanime soundtrack, Chinese folk, lo-fi\nanime soundtrack, future bass, J-pop\nanime soundtracks\nanime style\nanime style, J-rock, lo-fi ambient\nanime style, ambient, traditional Chinese\nanime style, dream pop, cinematic\nanime style, hardstyle, cinematic\nanime style, synth funk, chiptune\nanime style, trap, electronic\nanime swing\nanime synth\nanime synth-rock\nanime synthwave\nanime theme\nanime theme ballad\nanime theme medley\nanime theme song\nanime theme, 80s J-pop, Italo-disco\nanime theme, C-pop, rock\nanime theme, J-pop, Eurobeat\nanime theme, J-pop, big band\nanime theme, J-pop, circus pop\nanime theme, J-pop, orchestral\nanime theme, J-rock, Chinese pop\nanime theme, J-rock, cinematic\nanime theme, Kayōkyoku, retro\nanime theme, Latin jazz fusion\nanime theme, big band, J-pop\nanime theme, big band, Latin fusion\nanime theme, big band, Showa era\nanime theme, big band, disco-funk\nanime theme, big band, funk\nanime theme, big band, rock\nanime theme, big band, surf rock\nanime theme, big band, swing\nanime theme, cinematic, Eurobeat\nanime theme, city pop\nanime theme, city pop, J-pop\nanime theme, disco-funk, electronic\nanime theme, funk, disco\nanime theme, funk-rock, city pop\nanime theme, happy hardcore, hardstyle\nanime theme, jazz fusion, big band\nanime theme, orchestral, eurobeat\nanime theme, retro funk, disco\nanime theme, salsa, disco\nanime trance\nanime trap\nanime trap hip-hop\nanime trap lo-fi\nanime trap metal\nanime trap phonk\nanime trap rock\nanime vocal\nanime-core synth-pop\nanime-inspired electronic\nanime-inspired electronic pop\nanime-pop\nanime-pop hyperpop\nanime-pop lo-fi\nanime-rap\nanime-style J-rock\nanime-style electronic pop\nanime-style march\nanime-trap\nanison\nanison metalcore\nanison rock\nanison, J-rock, electronic\nanison, J-rock, hyperpop\nanison, Kayōkyoku, Japanese rock\nanthem\nanthem rock\nanthem, gospel, world music\nanthem, patriotic, Indian classical\nanthemic\nanthemic C-pop\nanthemic EDM\nanthemic Indian pop\nanthemic R&B\nanthemic a cappella\nanthemic acapella\nanthemic acoustic\nanthemic alternative rock\nanthemic ambient\nanthemic ballad\nanthemic body percussion\nanthemic brass\nanthemic chanson\nanthemic chant\nanthemic choir\nanthemic choral\nanthemic dance\nanthemic devotional\nanthemic drum\nanthemic electronic\nanthemic folk\nanthemic folk rock\nanthemic football chant\nanthemic funk\nanthemic fusion\nanthemic gospel\nanthemic gospel rock\nanthemic hip hop\nanthemic hip-hop\nanthemic hip-hop rock\nanthemic house\nanthemic hymn\nanthemic indie\nanthemic indie rock\nanthemic instrumental\nanthemic live\nanthemic lo-fi\nanthemic male choir\nanthemic march\nanthemic orchestral\nanthemic patriotic\nanthemic patriotic march\nanthemic percussion\nanthemic piano\nanthemic piano ballad\nanthemic piano rock\nanthemic polka\nanthemic pop\nanthemic pop ballad\nanthemic pop reggaeton world music\nanthemic pop rock\nanthemic pop world music\nanthemic pop, Central Asian folk\nanthemic pop, EDM\nanthemic pop, EDM, big room\nanthemic pop, EDM, gospel\nanthemic pop, EDM, progressive house\nanthemic pop, EDM, world music\nanthemic pop, Eastern European, patriotic\nanthemic pop, Middle Eastern, Central Asian\nanthemic pop, South Asian pop\nanthemic pop, candombe\nanthemic pop, gospel hip-hop\nanthemic pop, gospel, world music\nanthemic pop, new jack swing, gospel\nanthemic pop, new-age, world music\nanthemic pop, pop-rock\nanthemic pop, world music, dance-pop\nanthemic pop-rock\nanthemic pop-rock worship\nanthemic pop-soul\nanthemic power ballad\nanthemic praise\nanthemic protest\nanthemic protest rock\nanthemic rock\nanthemic rock ballad\nanthemic rock chiptune\nanthemic rock folk\nanthemic rock gospel\nanthemic ska-punk\nanthemic soul\nanthemic spiritual\nanthemic sports\nanthemic sports chant\nanthemic stadium\nanthemic stadium chant\nanthemic synth\nanthemic synthpop\nanthemic trance\nanthemic tribal\nanthemic vocal\nanthemic world\nanthemic world fusion\nanthemic world music\nanthemic world pop\nanthemic worship\nanthemic worship rock\nanthemic, comedic, tribal\nanthemic, early digital, synthpop\nanthemic, patriotic, Indian classical\nanthemic, patriotic, South Asian\nanthemic, tribal, revolutionary\nanti-Christmas\nanti-folk\nanti-folk country-rock\nanti-folk indie rock\nanti-folk noise-rock\nanti-folk pop-punk\nanti-folk punk\napocalyptic R&B\napocalyptic disco\napocalyptic folk\napocalyptic hip-hop\nappalachian folk\naquatic trap\narabesque\narabesque pop\narabesque pop-rock\narabesque rock\narabesque, Turkish folk\narabesque, Turkish folk, cinematic\narabesque, cinematic, Turkish folk\narabesque, cinematic, electronic\narabesque, flamenco, cinematic\narabesque, power ballad, Turkish rock\narcade dance\narcade funk\narcade game\narena ballad\narena folk\narena gospel\narena pop\narena rock\narena rock alternative rock\narena rock chiptune\narena rock electronic rock\narena rock folk-rock\narena rock funk-rock\narena rock glam metal\narena rock glam rock\narena rock gospel\narena rock hip-hop\narena rock hip-hop electronic\narena rock post-hardcore\narena rock power ballad\narena rock progressive metal\narena rock reggae fusion\narena rock synth-pop\narena rock synthwave\narena rock worship\narena rock, C-pop, cinematic\narena rock, C-pop, emotional rock\narena rock, J-rock\narena rock, Latin pop-rock\narena rock, ambient, cinematic\narena rock, chiptune\narena rock, city pop, video game music\narena rock, classic rock, heartland rock\narena rock, complextro, cinematic\narena rock, conscious hip-hop\narena rock, electronicore, synth pop\narena rock, eurodance, cinematic\narena rock, funk, power ballad\narena rock, glam metal, Mandarin rock\narena rock, new wave\narena rock, pop-rock, glam metal\narena rock, post-rock, J-rock\narena rock, psychedelic pop, new wave\narena rock, psychedelic rock\narena rock, punk rock, chiptune funk\narena rock, rap-rock, metalcore\narena rock, synth-pop\narena rock, synth-pop, cinematic\narena rock, synth-pop, video game music\narena rock, synthwave, video game\narena rock, worship, R&B\narena worship\narrocha\narrocha chiptune\narrocha pagode\narrocha piseiro\narrocha rap\narrocha sertanejo\nart ballad\nart folk\nart house\nart jazz\nart music\nart music tango\nart music, folk, cinematic\nart music, melancholic ballad, trip-hop\nart music, melancholic, cinematic\nart music, tango, folk\nart pop\nart pop alternative rock\nart pop ambient pop\nart pop chiptune\nart pop chiptune lo-fi\nart pop drum and bass j-pop\nart pop future bass\nart pop future bass trap\nart pop jazz\nart pop jungle\nart pop lo-fi trip-hop\nart pop trip-hop\nart pop, IDM\nart pop, IDM, ambient\nart pop, Indian classical, folk\nart pop, J-pop\nart pop, J-pop, anime soundtrack\nart pop, J-pop, breakcore\nart pop, J-pop, chiptune\nart pop, J-pop, drum and bass\nart pop, J-pop, electronic\nart pop, J-pop, future bass\nart pop, J-pop, glitch\nart pop, J-pop, hyperpop\nart pop, J-pop, trance\nart pop, MPB, art rock\nart pop, Persian classical\nart pop, Turkish folk\nart pop, UK garage, breakbeat\nart pop, alternative R&B\nart pop, ambient, future pop\nart pop, ambient, trap\nart pop, breakbeat, experimental electronic\nart pop, breakcore, ambient\nart pop, chiptune, breakcore\nart pop, cinematic folk\nart pop, cinematic rock\nart pop, cinematic rock, symphonic metal\nart pop, cinematic, baroque pop\nart pop, dream pop\nart pop, dream pop, shoegaze\nart pop, dreamy synth-pop, breakcore\nart pop, dreamy synth-pop, hyperpop\nart pop, drum and bass\nart pop, electronic rock\nart pop, electronic rock, ambient\nart pop, electronic rock, trip-hop\nart pop, electronica, J-rock\nart pop, electronica, breakbeat\nart pop, electronica, cinematic\nart pop, electronica, piano ballad\nart pop, ethereal, world fusion\nart pop, experimental\nart pop, experimental hip-hop, glitch-hop\nart pop, experimental rock\nart pop, experimental trap\nart pop, folk-rock\nart pop, future bass\nart pop, future bass, J-pop\nart pop, future bass, hardstyle\nart pop, future garage, drum and bass\nart pop, garage rock\nart pop, glitch, breakcore\nart pop, glitch, chiptune\nart pop, glitch-hop, future bass\nart pop, hyperpop\nart pop, hyperpop, J-pop\nart pop, hyperpop, ambient\nart pop, hyperpop, breakcore\nart pop, hyperpop, drum and bass\nart pop, hyperpop, electronic\nart pop, industrial\nart pop, liquid drum and bass\nart pop, liquid drum and bass, R&B\nart pop, lo-fi hip hop\nart pop, lo-fi, dream pop\nart pop, melodic techno\nart pop, modern trap\nart pop, new wave, art rock\nart pop, progressive rock\nart pop, psychedelic, Latin pop\nart pop, smooth jazz\nart pop, smooth jazz, cinematic\nart pop, synth-pop, breakbeat\nart pop, synth-pop, hyperpop\nart pop, synth-pop, trance\nart pop, theatrical folk\nart pop, trap soul\nart pop, trap, gospel\nart pop, trip-hop\nart pop, trip-hop, J-pop\nart pop, trip-hop, ambient\nart pop, trip-hop, art rock\nart pop, trip-hop, electronic\nart pop, trip-hop, industrial\nart pop, world music\nart pop, world music, gospel\nart rap\nart rock\nart rock cabaret\nart rock cabaret big band\nart rock cabaret blues\nart rock cabaret chanson\nart rock cabaret jazz\nart rock cabaret punk\nart rock cabaret surf rock\nart rock cabaret tango\nart rock drum and bass\nart rock funk\nart rock funk disco\nart rock funk jazz fusion\nart rock funk lounge\nart rock garage rock\nart rock glam rock\nart rock indie rock\nart rock industrial\nart rock industrial rock\nart rock jazz\nart rock jazz cabaret\nart rock jazz fusion\nart rock jazz lounge\nart rock jazz noir\nart rock jazz soul\nart rock jazz-funk\nart rock jazz-fusion lounge\nart rock lounge big band\nart rock lounge jazz\nart rock lounge show tune\nart rock neoclassical\nart rock post-rock\nart rock progressive metal\nart rock progressive rock\nart rock psychedelic\nart rock punk\nart rock soul-rock\nart rock tango\nart rock world music\nart rock, 80s new wave, theatrical\nart rock, Americana, Southern Gothic\nart rock, Anatolian rock, melancholic\nart rock, Brazilian, post-rock\nart rock, IDM, ambient\nart rock, Italo-disco, synth-pop\nart rock, J-rock, electronic\nart rock, Latin rock, psychedelic\nart rock, MPB, ambient\nart rock, MPB, big band\nart rock, Polish new wave\nart rock, R&B\nart rock, Russian estrada, synth ballad\nart rock, Turkish folk\nart rock, ambient, glitch\nart rock, ambient, industrial\nart rock, art pop, cinematic\nart rock, baroque pop\nart rock, baroque pop, vintage\nart rock, big band jazz\nart rock, big band jazz, theatrical\nart rock, big-band jazz\nart rock, blues rock, cinematic\nart rock, blues-rock, rap-rock\nart rock, cabaret, Eastern European\nart rock, cabaret, Eastern European folk\nart rock, chiptune, French chanson\nart rock, chiptune, video game music\nart rock, cinematic\nart rock, cinematic folk\nart rock, cinematic pop\nart rock, cinematic, Chinese ambient\nart rock, cinematic, MPB\nart rock, cinematic, ambient\nart rock, cinematic, free jazz\nart rock, cinematic, operatic\nart rock, classical, cinematic\nart rock, dark cabaret\nart rock, dark cabaret, theatrical rock\nart rock, electronic, J-rock\nart rock, electronic, ambient\nart rock, experimental, punk\nart rock, film noir, cabaret\nart rock, folk dance\nart rock, free jazz, experimental\nart rock, glam rock\nart rock, glitch, electronic\nart rock, grunge, alternative metal\nart rock, heavy metal\nart rock, industrial electronic, ambient\nart rock, industrial rock\nart rock, jazz fusion, progressive rock\nart rock, lo-fi, free jazz\nart rock, metal, ambient\nart rock, neo-soul, experimental\nart rock, new wave\nart rock, new wave, post-punk\nart rock, new wave, theatrical\nart rock, ney flute, Turkish folk\nart rock, noise rock\nart rock, nu-disco, cinematic\nart rock, polka-rock, cinematic\nart rock, post-rock, ambient\nart rock, post-rock, experimental\nart rock, post-rock, noir\nart rock, progressive hard rock\nart rock, progressive metal\nart rock, progressive metal, cinematic\nart rock, progressive metal, video game music\nart rock, progressive rock\nart rock, progressive rock, chiptune\nart rock, psychedelic hard rock, jazz rock\nart rock, psychedelic rock, Middle Eastern\nart rock, psychedelic, MPB\nart rock, punk rock\nart rock, punk rock, funk\nart rock, swing jazz\nart rock, symphonic metal\nart rock, symphonic metal, cinematic\nart rock, symphonic metal, metalcore\nart rock, symphonic metal, neoclassical\nart rock, symphonic rock, progressive metal\nart rock, synth-pop, math rock\nart rock, theatrical rock, punk rock\nart rock, theatrical, post-punk\nart rock, world fusion, Balkan folk\nart rock, world music, Arabic pop\nart rock, world music, ambient\nart song\nart song bebop\nart song blues\nart song bossa nova\nart song cabaret\nart song fado\nart song folk\nart song jazz\nart song klezmer\nart song progressive rock\nart song samba classical\nart song samba-jazz\nart song tango\nart song tango cabaret\nart song tango copla\nart song, Balkan folk-rock, theatrical\nart song, European folk, chanson\nart song, Greek folk, Latin-inspired\nart song, Greek folk-rock\nart song, Greek laïko, classical\nart song, Greek, theatrical\nart song, Italian folk\nart song, Italian folk, operatic\nart song, Latin folk, Middle Eastern\nart song, Latin mambo\nart song, Latin, operatic\nart song, MPB\nart song, MPB, Fado\nart song, MPB, chamber music\nart song, MPB, choral\nart song, MPB, cinematic\nart song, MPB, classical crossover\nart song, Russian romance, cabaret\nart song, avant-garde jazz, cabaret\nart song, avant-garde, piano trio\nart song, big band jazz\nart song, big band swing\nart song, big band, operatic\nart song, cabaret, big band jazz\nart song, cabaret, flamenco\nart song, cabaret, folk\nart song, cabaret, melancholic\nart song, cabaret, musical theater\nart song, cabaret, theatrical\nart song, cabaret, waltz\nart song, chamber jazz\nart song, chanson, European folk\nart song, chanson, cinematic\nart song, choral, cabaret\nart song, choral, patriotic\nart song, cinematic, Chinese traditional\nart song, cinematic, Latin ballad\nart song, cinematic, Mandarin opera\nart song, cinematic, ambient\nart song, cinematic, choral\nart song, cinematic, melancholic\nart song, cinematic, opera\nart song, cinematic, operatic\nart song, cinematic, orchestral\nart song, classical crossover\nart song, classical crossover, Greek folk\nart song, classical, Azerbaijani folk\nart song, classical, Chinese revolutionary\nart song, classical, Italian\nart song, classical, MPB\nart song, classical, Persian\nart song, classical, romantic\nart song, classical, theatrical\nart song, cumbia\nart song, dark cabaret, chanson\nart song, dark cabaret, theatrical\nart song, experimental, electronic\nart song, fado, cinematic\nart song, flamenco, cinematic\nart song, folk dance\nart song, jazz, Russian romance\nart song, klezmer, balkan folk\nart song, musical theater, classical\nart song, operatic, Chinese classical\nart song, operatic, Chinese folk opera\nart song, operatic, Fado\nart song, operatic, Indian classical\nart song, operatic, Mediterranean folk\nart song, operatic, cinematic\nart song, operatic, pansori\nart song, operatic, tango\nart song, patriotic, Chinese classical\nart song, pop-rock ballad\nart song, ragtime, jazz\nart song, rock ballad\nart song, salsa\nart song, samba-reggae\nart song, soul-rock, cinematic\nart song, swing jazz, melancholic jazz\nart song, tango, MPB\nart song, tango, classical\nart song, tango, orchestral\nart song, theatrical rock\nart song, theatrical rock, cinematic\nart song, theatrical, chamber music\nart song, theatrical, cinematic\nart song, theatrical, free jazz\nart song, theatrical, rock-opera\nart song, trap\nart song, turbo-folk\nart song, world fusion, cinematic\nart-folk\nart-folk flamenco\nart-funk\nart-funk jazz-fusion\nart-gospel\nart-house\nart-jazz\nart-pop\nart-pop 80s aesthetic\nart-pop Balkan folk\nart-pop European folk\nart-pop J-pop whimsical\nart-pop MPB\nart-pop alternative rock\nart-pop ambient\nart-pop ambient lounge\nart-pop ambient trip-hop\nart-pop anime\nart-pop anime soundtrack\nart-pop arena rock\nart-pop art-rock\nart-pop avant-garde jazz cabaret\nart-pop baroque\nart-pop baroque pop\nart-pop baroque-pop\nart-pop blues\nart-pop bossa nova\nart-pop cabaret\nart-pop cabaret big band\nart-pop cabaret classical\nart-pop cabaret exotica\nart-pop cabaret funk\nart-pop cabaret jazz\nart-pop cabaret klezmer\nart-pop cabaret lounge-jazz\nart-pop cabaret operatic\nart-pop cabaret psychedelic\nart-pop cabaret psychedelic rock\nart-pop cabaret tango\nart-pop cabaret trip-hop\nart-pop cabaret-rock\nart-pop chamber music\nart-pop chiptune\nart-pop chiptune J-pop\nart-pop chiptune hyperpop\nart-pop chiptune j-pop\nart-pop chiptune lo-fi\nart-pop chiptune synth-pop\nart-pop chiptune video game music\nart-pop cinematic\nart-pop cinematic rock\nart-pop city pop\nart-pop city pop jazz fusion\nart-pop classical crossover\nart-pop cyberpunk\nart-pop dark cabaret\nart-pop darkwave\nart-pop disco-funk\nart-pop dream pop\nart-pop dream pop hyperpop\nart-pop dream-pop\nart-pop drum and bass\nart-pop electronic rock\nart-pop electronica\nart-pop exotica carnival\nart-pop experimental\nart-pop experimental hip-hop\nart-pop fado jazz\nart-pop flamenco\nart-pop flamenco Latin\nart-pop flamenco jazz\nart-pop flamenco latin jazz\nart-pop folk-pop\nart-pop folk-rock\nart-pop funk\nart-pop funk disco\nart-pop funk hip-hop\nart-pop funk jazz fusion\nart-pop funk lounge\nart-pop funk new wave\nart-pop funk soul\nart-pop funk-rock\nart-pop funk-rock punk\nart-pop future bass\nart-pop glam rock\nart-pop glitch\nart-pop glitch-hop\nart-pop gospel\nart-pop gothic\nart-pop gothic baroque\nart-pop gothic trip-hop\nart-pop gypsy jazz theatrical\nart-pop hyperpop\nart-pop hyperpop chiptune\nart-pop hyperpop trap\nart-pop indie pop cinematic rock\nart-pop indie rock\nart-pop industrial rock\nart-pop italo-disco new wave\nart-pop j-pop\nart-pop j-pop anime\nart-pop j-pop breakbeat\nart-pop j-pop breakcore\nart-pop j-pop chiptune\nart-pop j-pop city-pop\nart-pop j-pop electronic\nart-pop j-pop math rock\nart-pop j-pop shibuya-kei\nart-pop j-pop shoegaze\nart-pop j-pop video game\nart-pop jangle-pop late-80s\nart-pop jazz\nart-pop jazz cabaret\nart-pop jazz dream pop\nart-pop jazz fusion\nart-pop jazz fusion dream pop\nart-pop jazz fusion progressive rock\nart-pop jazz lounge\nart-pop jazz noir\nart-pop jazz soul\nart-pop jazz world music\nart-pop jazz-funk\nart-pop jazz-funk trip-hop\nart-pop jazz-fusion\nart-pop jazz-pop\nart-pop latin\nart-pop latin jazz\nart-pop latin jazz bossa nova\nart-pop latin jazz funk\nart-pop latin jazz fusion\nart-pop lo-fi\nart-pop lo-fi chiptune\nart-pop lo-fi electronic\nart-pop lo-fi future bass\nart-pop lo-fi hip-hop\nart-pop lo-fi hip-hop experimental\nart-pop lo-fi jazz\nart-pop lo-fi trap hyperpop\nart-pop lo-fi trip-hop\nart-pop lounge\nart-pop lounge cabaret\nart-pop lounge jazz\nart-pop lounge soul\nart-pop lounge-jazz\nart-pop mathcore\nart-pop metalcore\nart-pop neo-soul\nart-pop neoclassical\nart-pop new wave\nart-pop noir-jazz\nart-pop noise-rock\nart-pop nu-disco\nart-pop nu-disco funk\nart-pop nu-jazz funk\nart-pop nu-metal\nart-pop orchestral\nart-pop piano rock\nart-pop post-rock\nart-pop progressive rock\nart-pop psychedelic\nart-pop psychedelic funk\nart-pop psychedelic pop\nart-pop psychedelic rock\nart-pop punk\nart-pop punk rock\nart-pop rock\nart-pop samba-reggae\nart-pop shoegaze\nart-pop steampunk\nart-pop symphonic rock\nart-pop synth-pop\nart-pop synthwave\nart-pop tango\nart-pop tango cabaret\nart-pop tango cinematic\nart-pop tango flamenco\nart-pop tango jazz\nart-pop tango melancholic\nart-pop tango rock\nart-pop techno\nart-pop theatrical\nart-pop trip-hop\nart-pop trip-hop cinematic\nart-pop trip-hop electronic\nart-pop trip-hop shoegaze\nart-pop vintage\nart-pop vintage lounge\nart-pop world music\nart-pop, 70s Polish rock\nart-pop, 80s new wave\nart-pop, 80s synth-pop\nart-pop, Anatolian rock, cinematic\nart-pop, Balkan folk\nart-pop, Balkan, tango\nart-pop, Brazilian funk, dark electronic\nart-pop, C-pop, electronic\nart-pop, C-pop, world music\nart-pop, Eastern European, theatrical\nart-pop, French chanson, cinematic\nart-pop, French chanson, lounge-jazz\nart-pop, French new wave, theatrical\nart-pop, French pop-rock, cinematic\nart-pop, Greek folk, Balkan folk\nart-pop, Greek folk-rock\nart-pop, IDM, J-pop\nart-pop, Israeli rock, synth-pop\nart-pop, Italo-disco, synth-pop\nart-pop, J-pop\nart-pop, J-pop, anime soundtrack\nart-pop, J-pop, breakcore\nart-pop, J-pop, chiptune\nart-pop, J-pop, city pop\nart-pop, J-pop, city-pop\nart-pop, J-pop, drum and bass\nart-pop, J-pop, electronic\nart-pop, J-pop, experimental electronic\nart-pop, J-pop, futuristic\nart-pop, J-pop, glitch\nart-pop, J-pop, hyperpop\nart-pop, J-pop, progressive rock\nart-pop, J-pop, video game music\nart-pop, J-rock, ambient\nart-pop, J-rock, anime soundtrack\nart-pop, J-rock, cinematic\nart-pop, J-rock, electronic\nart-pop, J-rock, hyperpop\nart-pop, J-rock, math rock\nart-pop, J-rock, video game music\nart-pop, JRPG soundtrack, theatrical\nart-pop, K-pop, future bass\nart-pop, Latin groove, theatrical\nart-pop, Latin jazz\nart-pop, Latin jazz, bossa nova\nart-pop, Latin jazz, funk\nart-pop, Latin rock\nart-pop, Latin, psychedelic\nart-pop, Latin, world music\nart-pop, MPB\nart-pop, MPB, theatrical rock\nart-pop, MPB, trip-hop\nart-pop, Middle Eastern, Persian\nart-pop, Middle Eastern, psychedelic\nart-pop, Polish new wave\nart-pop, Polish new wave, cinematic\nart-pop, Polish new wave, synth-pop\nart-pop, Polish new wave, vintage\nart-pop, Polish rock, cinematic\nart-pop, Polish rock, theatrical\nart-pop, R&B, lo-fi hip-hop\nart-pop, Russian estrada, lo-fi\nart-pop, Shibuya-kei, glitch-pop\nart-pop, Shibuya-kei, video game music\nart-pop, Soviet estrada, theatrical\nart-pop, Soviet-era, synthwave\nart-pop, Turkish, psychedelic rock\nart-pop, Vocaloid, lo-fi\nart-pop, alternative rock, C-pop\nart-pop, alternative rock, piano ballad\nart-pop, ambient, trip-hop\nart-pop, art-rock\nart-pop, art-rock, avant-garde\nart-pop, art-rock, cinematic\nart-pop, art-rock, free jazz\nart-pop, baroque pop\nart-pop, baroque-pop, theatrical\nart-pop, baroque-pop, vintage\nart-pop, big band, funk\nart-pop, big band, theatrical\nart-pop, breakcore\nart-pop, breakcore, ambient\nart-pop, breakcore, anime\nart-pop, breakcore, glitch\nart-pop, breakcore, jazz\nart-pop, breakcore, orchestral\nart-pop, cabaret jazz, cinematic\nart-pop, cabaret rock\nart-pop, cabaret, Eastern European\nart-pop, cabaret, Latin\nart-pop, cabaret, cinematic\nart-pop, cabaret, exotica\nart-pop, cabaret, funk\nart-pop, cabaret, jazz\nart-pop, cabaret, theatrical\nart-pop, chamber pop, art-rock\nart-pop, chanson, European\nart-pop, chiptune, electronic\nart-pop, chiptune, experimental\nart-pop, chiptune, hyperpop\nart-pop, chiptune, jazz fusion\nart-pop, chiptune, lo-fi\nart-pop, cinematic electronic\nart-pop, cinematic lounge\nart-pop, cinematic rock, ambient\nart-pop, cinematic rock, gothic\nart-pop, cinematic synth, lo-fi\nart-pop, cinematic, French chanson\nart-pop, cinematic, Turkish\nart-pop, cinematic, cabaret\nart-pop, cinematic, chanson\nart-pop, cinematic, choral\nart-pop, cinematic, eclectic\nart-pop, cinematic, electronic\nart-pop, cinematic, experimental\nart-pop, cinematic, funk\nart-pop, cinematic, hip-hop\nart-pop, cinematic, indie rock\nart-pop, cinematic, jazz\nart-pop, cinematic, neoclassical\nart-pop, cinematic, operatic\nart-pop, cinematic, orchestral\nart-pop, cinematic, punk\nart-pop, cinematic, rock\nart-pop, cinematic, rock-opera\nart-pop, cinematic, symphonic rock\nart-pop, cinematic, theatrical\nart-pop, cinematic, vintage film score\nart-pop, cinematic, world music\nart-pop, dark cabaret, cinematic\nart-pop, dark cabaret, theatrical\nart-pop, dream pop, MPB\nart-pop, dream pop, trap\nart-pop, dream-pop, electronic\nart-pop, dream-pop, experimental\nart-pop, drum and bass\nart-pop, drum and bass, ambient\nart-pop, drum and bass, neurofunk\nart-pop, electronic, ambient\nart-pop, electronic, cinematic\nart-pop, estrada, theatrical\nart-pop, ethereal, electronic\nart-pop, experimental electronic, alternative R&B\nart-pop, experimental electronic, trip-hop\nart-pop, experimental, breakcore\nart-pop, experimental, chiptune\nart-pop, experimental, cinematic\nart-pop, experimental, electronic\nart-pop, experimental, glitch\nart-pop, experimental, hyperpop\nart-pop, experimental, jazz-fusion\nart-pop, experimental, lo-fi\nart-pop, experimental, lo-fi hip-hop\nart-pop, experimental, math-rock\nart-pop, experimental, world music\nart-pop, film-noir, Italian\nart-pop, film-noir, tango\nart-pop, free jazz\nart-pop, funk, art-rock\nart-pop, funk-rock\nart-pop, future bass, breakcore\nart-pop, future garage, glitch\nart-pop, futuristic, anime-inspired\nart-pop, glitch, IDM\nart-pop, glitch, breakcore\nart-pop, glitch, chiptune\nart-pop, glitch, electronic\nart-pop, glitch, experimental\nart-pop, glitch, lo-fi\nart-pop, glitch-hop, lo-fi\nart-pop, gothic, anime soundtrack\nart-pop, gothic, progressive rock\nart-pop, gothic, theatrical\nart-pop, hardstyle\nart-pop, hip-hop, piano ballad\nart-pop, hyperpop\nart-pop, hyperpop, J-pop\nart-pop, hyperpop, J-rock\nart-pop, hyperpop, ambient\nart-pop, hyperpop, breakcore\nart-pop, hyperpop, experimental\nart-pop, hyperpop, glitch\nart-pop, hyperpop, grime\nart-pop, indie rock, shoegaze\nart-pop, indie-electronic, hyperpop\nart-pop, indie-pop, C-pop\nart-pop, industrial electronic\nart-pop, industrial rock\nart-pop, industrial rock, cinematic\nart-pop, jazz lounge, glitch\nart-pop, jazz, Brazilian\nart-pop, jazz-rock, minimalist\nart-pop, jungle, ambient\nart-pop, late-80s Korean new wave\nart-pop, lo-fi electronic\nart-pop, lo-fi hip-hop, experimental\nart-pop, lo-fi, Vocaloid\nart-pop, lo-fi, experimental\nart-pop, lo-fi, minimalist\nart-pop, lo-fi, trip-hop\nart-pop, lounge, exotica\nart-pop, lounge-jazz, Soviet estrada\nart-pop, neo-classical\nart-pop, new wave\nart-pop, new wave, Eastern European\nart-pop, new wave, art-rock\nart-pop, new wave, cabaret\nart-pop, new wave, cinematic\nart-pop, new wave, funk\nart-pop, new wave, glam rock\nart-pop, new wave, jangle pop\nart-pop, new wave, post-punk\nart-pop, new wave, retro-futuristic\nart-pop, new wave, rock opera\nart-pop, new wave, synth-pop\nart-pop, new wave, theatrical\nart-pop, new wave, vintage\nart-pop, noir-jazz, experimental\nart-pop, noise-rock\nart-pop, noise-rock, ambient\nart-pop, nu-disco, jazz\nart-pop, pop-rock, cinematic\nart-pop, post-hardcore\nart-pop, post-punk\nart-pop, post-punk, Brazilian\nart-pop, post-rock\nart-pop, post-rock, ambient\nart-pop, post-rock, cinematic\nart-pop, progressive jazz-fusion, theatrical\nart-pop, progressive metalcore\nart-pop, progressive rock\nart-pop, progressive rock, cinematic\nart-pop, progressive rock, electronic\nart-pop, progressive rock, industrial\nart-pop, progressive rock, jazz\nart-pop, psychedelic funk\nart-pop, psychedelic funk-rock\nart-pop, psychedelic rock, Turkish\nart-pop, psychedelic rock, ambient\nart-pop, psychedelic rock, cinematic\nart-pop, psychedelic, Brazilian\nart-pop, psychedelic, Latin\nart-pop, psychedelic, Turkish\nart-pop, psychedelic, ambient\nart-pop, psychedelic, downtempo\nart-pop, psychedelic, experimental\nart-pop, psychedelic, garage rock\nart-pop, psychedelic, hypnotic\nart-pop, psychedelic, lo-fi\nart-pop, psychedelic, new wave\nart-pop, psychedelic, theatrical\nart-pop, psychedelic, trip-hop\nart-pop, psychedelic, vintage\nart-pop, punk rock, nu-metal\nart-pop, schlager, vintage\nart-pop, symphonic metal\nart-pop, symphonic rock\nart-pop, symphonic rock, Greek\nart-pop, symphonic rock, baroque\nart-pop, symphonic rock, cinematic\nart-pop, synth-pop, C-pop\nart-pop, synth-pop, chiptune\nart-pop, synth-pop, cinematic\nart-pop, synth-pop, funk\nart-pop, theatrical rock\nart-pop, theatrical, Greek\nart-pop, theatrical, Latin rock\nart-pop, theatrical, cabaret\nart-pop, theatrical, cinematic\nart-pop, theatrical, circus\nart-pop, theatrical, classical\nart-pop, theatrical, electronic\nart-pop, theatrical, folk\nart-pop, theatrical, psychedelic\nart-pop, theatrical, punk-rock\nart-pop, theatrical, rock opera\nart-pop, theatrical, trap\nart-pop, traditional Chinese, theatrical\nart-pop, trip-hop, ambient\nart-pop, trip-hop, bilingual\nart-pop, trip-hop, breakcore\nart-pop, trip-hop, cinematic\nart-pop, trip-hop, experimental\nart-pop, trip-hop, free jazz\nart-pop, trip-hop, future bass\nart-pop, trip-hop, rock\nart-pop, trip-hop, theatrical\nart-pop, vintage jazz, Shibuya-kei\nart-pop, vintage rock, psychedelic\nart-pop, world music, new age\nart-punk\nart-punk lo-fi\nart-punk, alternative rock, funk\nart-punk, disco-rock, experimental\nart-punk, new wave, chiptune\nart-punk, power-pop, indie rock\nart-rock\nart-rock alternative\nart-rock alternative metal\nart-rock alternative rock\nart-rock americana blues\nart-rock big band\nart-rock big band jazz\nart-rock blues\nart-rock blues-rock\nart-rock cabaret\nart-rock cabaret big band\nart-rock cabaret jazz\nart-rock cabaret punk\nart-rock cabaret surf-rock\nart-rock cabaret tango\nart-rock chiptune\nart-rock cumbia Latin\nart-rock drum and bass\nart-rock funk\nart-rock funk jazz fusion\nart-rock funk-rock\nart-rock garage punk\nart-rock garage rock\nart-rock glam cabaret\nart-rock glam rock cabaret\nart-rock glam-rock\nart-rock indie punk\nart-rock indie rock\nart-rock indie rock post-rock\nart-rock indie rock shoegaze\nart-rock industrial\nart-rock industrial rock\nart-rock jazz lounge\nart-rock jazz-funk\nart-rock jazz-fusion\nart-rock latin\nart-rock latin theatrical\nart-rock lo-fi hip-hop\nart-rock lounge-jazz\nart-rock mathcore\nart-rock metalcore post-hardcore\nart-rock noir-jazz\nart-rock noise-rock\nart-rock noise-rock jazz\nart-rock nu-metal metalcore\nart-rock post-hardcore\nart-rock post-punk\nart-rock post-punk lounge-jazz\nart-rock post-punk new wave\nart-rock post-rock\nart-rock power-pop\nart-rock progressive metal\nart-rock progressive metal jazz\nart-rock progressive rock\nart-rock psychedelic\nart-rock psychedelic funk\nart-rock punk\nart-rock punk funk\nart-rock shoegaze\nart-rock shoegaze post-rock\nart-rock soul\nart-rock soul jazz\nart-rock surf-punk\nart-rock surf-rock\nart-rock symphonic metal\nart-rock tango cabaret\nart-rock trip-hop\nart-rock, J-pop, math-rock\nart-rock, J-rock, math-rock\nart-rock, Latin jazz, progressive rock\nart-rock, Latin rock\nart-rock, Latin, big band\nart-rock, MPB, theatrical\nart-rock, Neue Deutsche Welle\nart-rock, alt-rock, progressive rock\nart-rock, alternative rock, progressive metal\nart-rock, ambient, melodic death metal\nart-rock, art-punk\nart-rock, baroque-pop, theatrical\nart-rock, cabaret, boogie-woogie\nart-rock, cabaret, free jazz\nart-rock, cinematic, noise-rock\nart-rock, city-pop, dream pop\nart-rock, cumbia, Latin rock\nart-rock, cyberpunk, experimental\nart-rock, dark cabaret, theatrical\nart-rock, dream-pop, shoegaze\nart-rock, electronic, pop-punk\nart-rock, experimental, electro-rock\nart-rock, funk-pop, metalcore\nart-rock, funk-rock, hyperpop\nart-rock, glam metal\nart-rock, hard rock, punk rock\nart-rock, hard rock, thrash metal\nart-rock, heavy metal\nart-rock, industrial rock\nart-rock, industrial, hyperpop\nart-rock, jazz, psychedelic\nart-rock, math-rock, theatrical\nart-rock, metalcore, ambient\nart-rock, new wave\nart-rock, new wave, 80s\nart-rock, new wave, experimental rock\nart-rock, new wave, post-punk\nart-rock, new wave, synth-pop\nart-rock, noir-jazz, trip-hop\nart-rock, noise-rock, progressive rock\nart-rock, post-punk, experimental\nart-rock, post-punk, industrial metal\nart-rock, post-punk, synth-pop\nart-rock, post-rock\nart-rock, post-rock, cinematic\nart-rock, power metal, cinematic\nart-rock, progressive rock, psychedelic\nart-rock, psychedelic funk, jazz\nart-rock, psychedelic funk, jazz fusion\nart-rock, psychedelic rock, jazz fusion\nart-rock, psychedelic rock, lo-fi hip-hop\nart-rock, psychedelic rock, noise-rock\nart-rock, psychedelic rock, progressive rock\nart-rock, psychedelic, ambient\nart-rock, psychedelic, funk\nart-rock, psychedelic, post-rock\nart-rock, psychedelic, trip-hop\nart-rock, surf-rock, chanson\nart-rock, surf-rock, noir\nart-rock, symphonic power metal\nart-rock, synth-pop\nart-rock, synth-pop, new wave\nart-rock, tango, cinematic\nart-rock, theatrical rock, horror soundtrack\nart-rock, thrash metal\nart-song\nart-song boogie-woogie\nart-song cabaret\nart-song tango\nart-song, post-rock, avant-garde\nart-soul\nartcore\nartcore C-pop\nartcore J-core\nartcore J-pop\nartcore J-rock\nartcore ambient\nartcore breakcore\nartcore breakcore chiptune\nartcore breakcore j-pop\nartcore chiptune\nartcore chiptune breakcore\nartcore chiptune happy hardcore\nartcore chiptune j-pop\nartcore chiptune trance\nartcore cinematic\nartcore complextro\nartcore complextro dubstep\nartcore denpa\nartcore denpa breakcore\nartcore denpa-kei\nartcore drum and bass\nartcore drum and bass chiptune\nartcore drum and bass j-core\nartcore dubstep\nartcore electronicore\nartcore future bass\nartcore future bass j-pop\nartcore gabber\nartcore glitch-hop\nartcore glitch-hop j-pop\nartcore happy hardcore\nartcore hardcore techno\nartcore hardstyle\nartcore hyperpop\nartcore hyperpop breakcore\nartcore hyperpop chiptune\nartcore hyperpop j-pop\nartcore hyperpop trance\nartcore j-core\nartcore j-pop\nartcore j-pop breakcore\nartcore j-pop video game\nartcore j-rock trance\nartcore jazz fusion\nartcore neurofunk\nartcore nightcore\nartcore progressive metal\nartcore speedcore\nartcore speedcore symphonic metal\nartcore symphonic J-rock\nartcore symphonic metal\nartcore trance\nartcore trancecore\nartcore vocaloid\nartcore, C-pop, hardstyle\nartcore, J-core\nartcore, J-core, Vocaloid\nartcore, J-core, ambient\nartcore, J-core, cinematic\nartcore, J-core, drum and bass\nartcore, J-core, electronic\nartcore, J-core, happy hardcore\nartcore, J-core, hardcore techno\nartcore, J-core, hardstyle\nartcore, J-core, hyperpop\nartcore, J-core, symphonic electronic\nartcore, J-core, trance\nartcore, J-pop, ambient\nartcore, J-pop, chiptune\nartcore, J-pop, drum and bass\nartcore, J-pop, electronic\nartcore, J-pop, glitch\nartcore, J-rock, hyperpop\nartcore, J-rock, symphonic\nartcore, J-rock, trance\nartcore, UK hardcore, ambient\nartcore, Vocaloid, dubstep\nartcore, anime, cinematic\nartcore, breakbeat, drum and bass\nartcore, breakcore, J-pop\nartcore, breakcore, ambient\nartcore, breakcore, chiptune\nartcore, breakcore, glitch\nartcore, breakcore, lo-fi\nartcore, chiptune, J-pop\nartcore, chiptune, ambient\nartcore, chiptune, cinematic\nartcore, chiptune, electronic\nartcore, chiptune, futurecore\nartcore, chiptune, hardstyle\nartcore, chiptune, speedcore\nartcore, cinematic, glitch\nartcore, classical piano, video game music\nartcore, color bass, ambient\nartcore, complextro, dubstep\nartcore, drum & bass, neurofunk\nartcore, drum and bass\nartcore, drum and bass, J-core\nartcore, drum and bass, J-pop\nartcore, drum and bass, ambient\nartcore, drum and bass, chiptune\nartcore, drum and bass, emotional piano\nartcore, drum and bass, neurofunk\nartcore, drum and bass, symphonic rock\nartcore, electronic rock, Chinese fusion\nartcore, electronic, C-pop\nartcore, electronic, ambient\nartcore, electronic, cinematic\nartcore, electronic, lo-fi\nartcore, ethereal, hyperpop\nartcore, future bass\nartcore, future bass, C-pop\nartcore, future bass, J-core\nartcore, future bass, ambient\nartcore, future bass, ambient pop\nartcore, future bass, breakcore\nartcore, future bass, hardstyle\nartcore, gabber, cinematic\nartcore, glitch, Vocaloid\nartcore, glitch-hop, J-pop\nartcore, happy hardcore\nartcore, happy hardcore, chiptune\nartcore, happy hardcore, lo-fi hip hop\nartcore, happy hardcore, trance\nartcore, hardcore techno, classical piano\nartcore, hardcore techno, speedcore\nartcore, hardstyle, C-pop\nartcore, hardstyle, J-pop\nartcore, hardstyle, ambient\nartcore, hardstyle, cinematic\nartcore, hyperpop, C-pop\nartcore, hyperpop, Chinese traditional\nartcore, hyperpop, J-core\nartcore, hyperpop, J-pop\nartcore, hyperpop, J-rock\nartcore, hyperpop, chiptune\nartcore, hyperpop, drum and bass\nartcore, hyperpop, hardstyle\nartcore, liquid drum and bass\nartcore, neurofunk\nartcore, neurofunk, cinematic\nartcore, neurofunk, drum and bass\nartcore, progressive rock, chiptune\nartcore, psytrance, C-pop\nartcore, speedcore, J-pop\nartcore, speedcore, breakcore\nartcore, speedcore, chiptune\nartcore, trance, Japanese rhythm game\nartcore, trance, ambient\nartcore, trance, breakcore\nartcore, trance, chiptune\nartcore, trance, hardstyle\nartcore, trance, symphonic rock\nartcore, trance, video game music\nartcore, video game music\nartcore, video game music, Japanese\nartcore, video game music, classical piano\nartcore, video game music, electronic\nartcore, video game, electronic\natmospheric\natmospheric C-pop\natmospheric Christmas ballad\natmospheric EDM\natmospheric EDM-pop\natmospheric Latin trap\natmospheric R&B\natmospheric R&B deep house\natmospheric R&B future bass\natmospheric R&B trap\natmospheric R&B trap-soul\natmospheric R&B, Filipino hip-hop, trap\natmospheric R&B, Latin trap\natmospheric R&B, trap, Indian pop\natmospheric a cappella\natmospheric acapella\natmospheric alt-rock\natmospheric alternative rock\natmospheric ambient\natmospheric anthem\natmospheric ballad\natmospheric blues-rock\natmospheric breakbeat\natmospheric country\natmospheric dark pop\natmospheric deep house\natmospheric doom metal\natmospheric drum and bass\natmospheric dubstep\natmospheric duet\natmospheric electronic\natmospheric electronic pop\natmospheric electronic rock\natmospheric electronica\natmospheric electropop\natmospheric folk\natmospheric folk rock\natmospheric folk-rock\natmospheric future bass\natmospheric future garage\natmospheric grunge\natmospheric hip hop\natmospheric hip-hop\natmospheric house\natmospheric hymn\natmospheric hyperpop\natmospheric indie\natmospheric indie rock\natmospheric jazz\natmospheric jazz-funk\natmospheric lo-fi\natmospheric melancholic\natmospheric metal\natmospheric piano\natmospheric piano ballad\natmospheric pop\natmospheric pop R&B\natmospheric pop afrobeat\natmospheric pop future bass\natmospheric pop reggaeton\natmospheric pop trap\natmospheric pop tropical house\natmospheric pop world music\natmospheric pop, EDM, big room house\natmospheric pop, conscious hip-hop\natmospheric pop, contemporary R&B\natmospheric pop, contemporary trap\natmospheric pop, dark trap, hip-hop\natmospheric pop, deep house\natmospheric pop, future bass\natmospheric pop, hyperpop\natmospheric pop, modern R&B\natmospheric pop, modern R&B, Middle Eastern\natmospheric pop, nu-disco\natmospheric pop, trap, R&B\natmospheric pop, trap, world music\natmospheric pop, world-pop\natmospheric pop-EDM\natmospheric pop-R&B\natmospheric pop-dance\natmospheric pop-gospel\natmospheric pop-r&b\natmospheric pop-rap\natmospheric pop-reggae\natmospheric pop-reggaeton\natmospheric pop-rock\natmospheric pop-trap\natmospheric post-rock\natmospheric progressive metal\natmospheric progressive rock\natmospheric reggaeton\natmospheric rock\natmospheric rock symphonic metal\natmospheric soft rock\natmospheric soul\natmospheric synth\natmospheric synth-pop\natmospheric techno\natmospheric trance\natmospheric trap\natmospheric trap R&B\natmospheric trap metalcore\natmospheric trap, cinematic orchestral\natmospheric trap, global pop\natmospheric trap-pop\natmospheric trip-hop\natmospheric vocal\natmospheric world\natmospheric world fusion\natmospheric worship\naudio drama\naudio logo\naudio sting\naudiobook\navant-garde\navant-garde J-pop\navant-garde J-rock\navant-garde a cappella\navant-garde ambient\navant-garde art song\navant-garde art-rock\navant-garde big band\navant-garde blues\navant-garde bossa nova\navant-garde cabaret\navant-garde cello\navant-garde chamber\navant-garde chanson\navant-garde circus\navant-garde classical\navant-garde electronic\navant-garde experimental\navant-garde film score\navant-garde flamenco\navant-garde folk\navant-garde folk-jazz\navant-garde funk\navant-garde fusion\navant-garde guitar\navant-garde hip hop\navant-garde hip-hop\navant-garde jazz\navant-garde jazz fusion\navant-garde jazz progressive rock\navant-garde jazz rock\navant-garde jazz, breakcore, chiptune\navant-garde jazz, modern classical\navant-garde jazz, progressive metal, chiptune\navant-garde jazz-funk\navant-garde jazz-pop\navant-garde jazz-rock\navant-garde metal\navant-garde metalcore free jazz\navant-garde musical\navant-garde musical theatre\navant-garde opera\navant-garde oud\navant-garde percussion\navant-garde piano\navant-garde piano progressive metal\navant-garde psychedelic rock\navant-garde punk\navant-garde punk rock\navant-garde ragtime\navant-garde rock\navant-garde rock, Turkish folk\navant-garde show tune\navant-garde spoken word\navant-garde tango\navant-garde theater\navant-garde vocal\navant-garde, cinematic, big band\navant-garde, experimental, Balkan folk\navant-garde, shakuhachi, vocal improvisation\navant-garde, surf rock, klezmer\navant-garde, theatrical, experimental\navant-garde, theatrical, folk\navant-garde, theatrical, klezmer\navant-pop\navtorskaya pesnya\nbachata\nbachata R&B\nbachata chiptune\nbachata cinematic\nbachata dembow\nbachata drill\nbachata electro\nbachata flamenco\nbachata fusion\nbachata hip-hop\nbachata jazz\nbachata pop\nbachata ranchera\nbachata reggaeton\nbachata remix\nbachata satirical\nbachata tumbada\nbachata urbana\nbachata, reggaeton, pop\nbachata-pop\nbachata-reggaeton\nbackground music\nbackground pop\nbaile funk\nbaile funk R&B\nbaile funk carioca\nbaile funk chiptune\nbaile funk cumbia\nbaile funk dancehall\nbaile funk hyperpop\nbaile funk hyperpop chiptune\nbaile funk hyperpop trap\nbaile funk kawaii\nbaile funk lo-fi\nbaile funk lo-fi hip hop\nbaile funk lo-fi vaporwave\nbaile funk reggaeton\nbaile funk trap\nbaile funk uk garage\nbaile funk vaporwave\nbaile funk, Bollywood, electronic\nbaile funk, French rap, dance\nbaile funk, German rap\nbaile funk, Russian hip-hop\nbaile funk, UK drill\nbaile funk, UK drill, trap\nbaile funk, UK garage, chiptune\nbaile funk, afrobeat, electronic\nbaile funk, chiptune\nbaile funk, chiptune, electronic dance\nbaile funk, chiptune, lo-fi\nbaile funk, chiptune, trap\nbaile funk, cinematic, chiptune\nbaile funk, cinematic, spoken word\nbaile funk, club\nbaile funk, dreamy, ethereal\nbaile funk, electro\nbaile funk, electronic, Brazilian funk\nbaile funk, flamenco, electronic\nbaile funk, glitch, deep house\nbaile funk, guzheng fusion\nbaile funk, hard trap\nbaile funk, hardstyle\nbaile funk, hyperpop\nbaile funk, hyperpop, Brazilian funk\nbaile funk, hyperpop, UK garage\nbaile funk, hyperpop, experimental electronic\nbaile funk, lo-fi hip hop\nbaile funk, moombahton\nbaile funk, moombahton, electronic\nbaile funk, moombahton, global club\nbaile funk, pop R&B\nbaile funk, reggaeton\nbaile funk, reggaeton, Brazilian pop\nbaile funk, reggaeton, Latin trap\nbaile funk, reggaeton, dream pop\nbaile funk, reggaeton, electronic\nbaile funk, synthwave\nbaile funk, trap\nbaile funk, trap, cinematic\nbaile funk, trap, hip-hop\nbaile funk, trap, hyperpop\nbaião\nbaião forró\nbaião frevo\nbaião rock\nbaião sertanejo\nbaião, Brazilian, children's music\nbalada\nbalada romántica\nbalkan brass\nbalkan folk funk\nbalkan folk, chiptune, polka\nbalkan-pop\nballad\nballad flamenco\nballad jazz\nballad rock\nballad salsa\nballad tango\nballad, 1960s, theatrical\nballad, 80s pop, Latin pop\nballad, 80s pop, cinematic\nballad, 80s pop, romantic\nballad, 80s pop, synth pop\nballad, Axé, cinematic\nballad, Brazilian funk, dance\nballad, C-pop, acoustic\nballad, C-pop, ambient\nballad, C-pop, cinematic\nballad, C-pop, emotional\nballad, C-pop, indie folk\nballad, C-pop, inspirational\nballad, C-pop, lo-fi\nballad, Chinese opera, acoustic\nballad, Chinese opera, indie folk\nballad, European folk, chanson\nballad, European, Latin\nballad, European, cafe\nballad, European, melancholic\nballad, European, tango\nballad, Haitian Creole, tender\nballad, Hindi, Gujarati\nballad, Indian classical, ambient\nballad, Italian crooner, melancholic\nballad, Italian folk, cinematic\nballad, Italian, acoustic\nballad, Italian, cinematic\nballad, K-pop, cinematic\nballad, Khmer pop, sentimental\nballad, Korean pop, emotional\nballad, Latin pop\nballad, Latin pop, acoustic\nballad, Latin, chanson\nballad, Latin, emotional\nballad, Latin-pop\nballad, Mandarin pop, Hokkien folk\nballad, Mandarin pop, Taiwanese Hokkien\nballad, Mandarin pop, acoustic\nballad, Mandarin pop, cinematic\nballad, Mandarin pop, emotional\nballad, Mandarin pop, folk\nballad, Mandarin pop, soft rock\nballad, Mandarin pop, soulful\nballad, Mandarin, Taiwanese Hokkien\nballad, Mandarin, acoustic\nballad, Mandarin, live\nballad, Portuguese pop, cinematic\nballad, Portuguese pop, emotional\nballad, R&B, acoustic\nballad, R&B, ambient\nballad, Sinhala, ambient\nballad, Spanish folk, acoustic\nballad, Spanish, acoustic\nballad, Spanish, emotional\nballad, Spanish-influenced, acoustic\nballad, Spanish-influenced, ambient\nballad, Spanish-influenced, atmospheric\nballad, Spanish-influenced, cinematic\nballad, Spanish-influenced, dramatic\nballad, Spanish-influenced, emotional\nballad, Sundanese, acoustic\nballad, Sundanese, cinematic\nballad, Taiwanese Hokkien, ambient\nballad, Tamil pop, ambient\nballad, Tamil, emotional\nballad, Thai pop, acoustic\nballad, Vocaloid style, ambient pop\nballad, accordion, bilingual\nballad, accordion, emotional\nballad, acoustic, C-pop\nballad, acoustic, Filipino\nballad, acoustic, French pop\nballad, acoustic, Italian\nballad, acoustic, Italian folk\nballad, acoustic, Japanese folk\nballad, acoustic, Latin\nballad, acoustic, Mandarin\nballad, acoustic, Mandarin folk\nballad, acoustic, Mandarin pop\nballad, acoustic, Portuguese\nballad, acoustic, Spanish\nballad, acoustic, Sundanese folk\nballad, acoustic, Tagalog\nballad, acoustic, ambient\nballad, acoustic, bilingual\nballad, acoustic, cabaret\nballad, acoustic, choral\nballad, acoustic, cinematic\nballad, acoustic, classical\nballad, acoustic, emotional\nballad, acoustic, filipino\nballad, acoustic, flamenco\nballad, acoustic, folk\nballad, acoustic, indie folk\nballad, acoustic, jazz-influenced\nballad, acoustic, melancholic\nballad, acoustic, multi-lingual\nballad, acoustic, power ballad\nballad, acoustic, romantic\nballad, acoustic, soulful\nballad, ambient pop, Italian\nballad, ambient pop, bilingual\nballad, ambient, C-pop\nballad, ambient, Latin\nballad, ambient, Latin pop\nballad, ambient, Mandarin pop\nballad, ambient, Portuguese pop\nballad, ambient, Sinhala folk\nballad, ambient, South Asian\nballad, ambient, Spanish\nballad, ambient, bilingual\nballad, ambient, choral\nballad, ambient, cinematic\nballad, ambient, indie folk\nballad, ambient, lo-fi\nballad, atmospheric, Bengali folk\nballad, atmospheric, Filipino\nballad, atmospheric, Mandarin pop\nballad, atmospheric, Spanish pop\nballad, atmospheric, cinematic\nballad, barbershop, doo-wop\nballad, baroque pop, filipino\nballad, big band rock\nballad, bilingual, acoustic\nballad, bilingual, ambient\nballad, bilingual, cinematic\nballad, bilingual, indie pop\nballad, bilingual, soft piano\nballad, blues, Spanish vocal\nballad, blues, bilingual\nballad, blues, cinematic\nballad, blues, dramatic\nballad, blues, introspective\nballad, blues-rock, Italian\nballad, blues-rock, Mandarin pop\nballad, bolero, cabaret\nballad, bolero, chanson\nballad, bossa nova, acoustic\nballad, bossa nova, cinematic\nballad, bossa nova, jazz\nballad, bossa nova, melancholic\nballad, bossa nova, tango\nballad, brega-pop, pagode\nballad, cabaret, introspective\nballad, cello, cinematic\nballad, chanson, acoustic\nballad, chanson, cinematic\nballad, chanson, classic pop\nballad, chanson, musical theatre\nballad, chanson, theatrical\nballad, choral, cinematic\nballad, choral, patriotic\nballad, cinematic rock, Spanish folk\nballad, cinematic, Afrikaans\nballad, cinematic, C-pop\nballad, cinematic, Chinese folk\nballad, cinematic, Filipino pop\nballad, cinematic, Hebrew vocal\nballad, cinematic, Italian\nballad, cinematic, Italian crooner\nballad, cinematic, Japanese folk\nballad, cinematic, Japanese pop\nballad, cinematic, K-pop\nballad, cinematic, Korean indie\nballad, cinematic, Korean pop\nballad, cinematic, Latin\nballad, cinematic, Latin pop\nballad, cinematic, Mandarin\nballad, cinematic, Mandarin folk\nballad, cinematic, Mandarin pop\nballad, cinematic, Portuguese\nballad, cinematic, Sinhala folk\nballad, cinematic, Spanish\nballad, cinematic, Spanish folk\nballad, cinematic, Spanish pop\nballad, cinematic, Spanish style\nballad, cinematic, Swedish folk\nballad, cinematic, Tagalog\nballad, cinematic, Tagalog pop\nballad, cinematic, Vietnamese folk\nballad, cinematic, acoustic\nballad, cinematic, ambient\nballad, cinematic, baroque\nballad, cinematic, bilingual\nballad, cinematic, bolero\nballad, cinematic, cabaret\nballad, cinematic, classical\nballad, cinematic, emotional\nballad, cinematic, flamenco\nballad, cinematic, folk\nballad, cinematic, indie folk\nballad, cinematic, jazz\nballad, cinematic, korean folk\nballad, cinematic, lo-fi\nballad, cinematic, melancholic\nballad, cinematic, piano\nballad, cinematic, romantic\nballad, cinematic, show tune\nballad, cinematic, soul\nballad, classical crossover\nballad, classical crossover, acoustic\nballad, classical guitar, Latin\nballad, classical guitar, Spanish\nballad, classical guitar, cinematic\nballad, classical guitar, emotional\nballad, classical guitar, melancholic\nballad, classical guitar, operatic\nballad, classical piano, emotional\nballad, classical pop, estrada\nballad, classical, C-pop\nballad, classical, French chanson\nballad, classical, J-pop\nballad, classical, Latin bolero\nballad, classical, Mandarin pop\nballad, classical, acoustic\nballad, classical, ambient\nballad, classical, bolero\nballad, classical, cinematic\nballad, classical, copla\nballad, classical, emotional\nballad, classical, flamenco\nballad, classical, folk\nballad, classical, indie folk\nballad, classical, lo-fi\nballad, classical, melancholic\nballad, classical, romantic\nballad, classical, synth pop\nballad, classical, tango\nballad, crooner, acoustic\nballad, crooner, ambient\nballad, crooner, blues\nballad, crooner, cinematic\nballad, crooner, melancholic\nballad, crooner, nostalgic\nballad, crooner, orchestral\nballad, crooner, show tune\nballad, crooner, vintage\nballad, downtempo, ambient\nballad, dramatic, Portuguese\nballad, dramatic, Spanish\nballad, dream pop, Tagalog pop\nballad, dream pop, ambient\nballad, emotional, Hindi pop\nballad, emotional, Portuguese\nballad, emotional, Portuguese pop\nballad, emotional, Spanish\nballad, emotional, Spanish pop\nballad, emotional, Tagalog\nballad, emotional, Tagalog pop\nballad, emotional, acoustic\nballad, emotional, ambient\nballad, emotional, atmospheric\nballad, emotional, bilingual\nballad, emotional, cinematic\nballad, emotional, dramatic\nballad, emotional, electronic\nballad, emotional, filipino\nballad, emotional, romantic\nballad, emotional, soul\nballad, emotive, nostalgic\nballad, ethereal, acoustic\nballad, fado, classical\nballad, fado, melancholic\nballad, flamenco, Mandarin pop\nballad, flamenco, acoustic\nballad, flamenco, bilingual\nballad, flamenco, cabaret\nballad, flamenco, cinematic\nballad, flamenco, emotional\nballad, flamenco, indie folk\nballad, flamenco, jazz\nballad, flamenco, melancholic\nballad, flamenco, romantic\nballad, flamenco, theatrical\nballad, folk pop, Mandarin pop\nballad, folk, C-pop\nballad, folk, Latin\nballad, folk, Mandarin\nballad, folk, Mandarin pop\nballad, folk, Tagalog\nballad, folk, cinematic\nballad, folk, classical\nballad, folk, emotional\nballad, folk, indie\nballad, folk, melancholic\nballad, folk, tango\nballad, gentle, sentimental\nballad, gospel rock, free jazz\nballad, gospel, Afro-pop\nballad, gospel, Latin\nballad, gospel, ambient\nballad, indie folk, K-pop\nballad, indie folk, bilingual\nballad, indie folk, cinematic\nballad, indie folk, emotional\nballad, introspective, Portuguese pop\nballad, jazz lounge, melancholic\nballad, jazz, C-pop\nballad, jazz, Latin\nballad, jazz, Mandarin pop\nballad, jazz, acoustic\nballad, jazz, cinematic\nballad, jazz, classical\nballad, jazz, emotional\nballad, jazz, indie folk\nballad, jazz, introspective\nballad, jazz, lo-fi\nballad, jazz, melancholic\nballad, jazz, piano\nballad, jazz, soft pop\nballad, jazz, theatrical\nballad, jazz-rock, melancholic\nballad, jump blues, big band\nballad, kayōkyoku, chanson\nballad, lo-fi hip hop, emotional\nballad, lo-fi, Spanish\nballad, lo-fi, ambient\nballad, lo-fi, art song\nballad, lo-fi, crooner\nballad, lo-fi, emotional\nballad, lo-fi, jazz\nballad, lullaby, waltz\nballad, melancholic, C-pop\nballad, melancholic, Chinese folk\nballad, melancholic, European\nballad, melancholic, Italian\nballad, melancholic, Italian folk\nballad, melancholic, Khmer\nballad, melancholic, Latin pop\nballad, melancholic, Mandarin\nballad, melancholic, Mandarin folk\nballad, melancholic, Mandarin pop\nballad, melancholic, Portuguese\nballad, melancholic, Spanish\nballad, melancholic, Spanish folk\nballad, melancholic, Spanish-influenced\nballad, melancholic, Turkish folk\nballad, melancholic, accordion\nballad, melancholic, acoustic\nballad, melancholic, ambient\nballad, melancholic, bilingual\nballad, melancholic, cabaret\nballad, melancholic, cinematic\nballad, melancholic, classical\nballad, melancholic, classical crossover\nballad, melancholic, filipino\nballad, melancholic, flamenco\nballad, melancholic, folk\nballad, melancholic, indie folk\nballad, melancholic, minimalist\nballad, melancholic, modern chanson\nballad, melancholic, piano\nballad, melancholic, romantic\nballad, melancholic, soul\nballad, melancholic, tango\nballad, melancholic, traditional Chinese\nballad, melancholic, waltz\nballad, multilingual, cinematic\nballad, neapolitan folk, acoustic\nballad, ney, emotional\nballad, nostalgic, crooner\nballad, nylon-string guitar, cinematic\nballad, nylon-string guitar, melancholic\nballad, operatic, acoustic\nballad, orchestral, Latin\nballad, orchestral, cinematic\nballad, orchestral, classical guitar\nballad, pan flute, emotional\nballad, piano, Mandarin vocal\nballad, piano, Thai traditional\nballad, piano, ambient\nballad, piano, chanson\nballad, piano, emotional\nballad, piano, live\nballad, piano, lo-fi\nballad, piano, operatic\nballad, pop, Filipino\nballad, pop, emotional\nballad, pop-rock, acoustic\nballad, pop-rock, cinematic\nballad, pop-rock, classical\nballad, pop/R&B\nballad, rock, acoustic\nballad, rock, orchestral\nballad, romance, acoustic\nballad, romantic, Brazilian\nballad, romantic, Hawaiian fusion\nballad, romantic, Italian folk\nballad, romantic, Spanish\nballad, romantic, acoustic\nballad, romantic, ambient\nballad, romantic, bilingual\nballad, romantic, cinematic\nballad, romantic, classical\nballad, romantic, classical guitar\nballad, romantic, introspective\nballad, smooth jazz, C-pop\nballad, soft pop, Vietnamese\nballad, soft pop, indie folk\nballad, soft rock, Italian\nballad, soul, Caribbean\nballad, soul, Taiwanese Hokkien\nballad, soul, blues\nballad, soul, cinematic\nballad, soul, classical crossover\nballad, soul, jazz\nballad, soul, reggae\nballad, soulful, acoustic\nballad, soulful, cinematic\nballad, soulful, jazz-infused\nballad, soulful, melancholic\nballad, tango, acoustic\nballad, tango, bolero\nballad, tango, cinematic\nballad, tango, classical\nballad, tango, classical guitar\nballad, tango, melancholic\nballad, theatrical pop, dreamy\nballad, theatrical, Chinese storytelling\nballad, theatrical, Hawaiian\nballad, theatrical, Spanish\nballad, theatrical, acoustic\nballad, theatrical, bilingual\nballad, theatrical, bolero\nballad, theatrical, chanson\nballad, theatrical, classical\nballad, theatrical, jazz\nballad, theatrical, melancholic\nballad, theatrical, piano\nballad, torch song, cinematic folk\nballad, traditional, sentimental\nballad, trap, emotional\nballad, vintage, Haitian Creole\nballad, vintage, Mandarin pop\nballad, vintage, bilingual\nballad, vintage, cinematic\nballad, vintage, film score\nballad, vintage, sentimental\nballad, vocal jazz, cinematic\nballroom\nballroom ballad\nballroom hip-hop\nballroom house\nballroom house vogue\nballroom jazz\nballroom pop\nballroom pop exotica\nballroom pop lounge exotica\nballroom tango\nballroom waltz\nballroom, romantic, cinematic\nbanda\nbar rock\nbar-band rock\nbar-rock\nbar-rock, rockabilly, jump blues\nbar-room blues\nbar-room rock\nbarbershop\nbarbershop a cappella\nbarbershop gospel\nbarbershop jazz\nbarbershop rock\nbarbershop, bluegrass, folk\nbarbershop, operatic\nbarbershop, ragtime, show tune\nbarbershop, sea shanty, theatrical\nbard rock\nbard-rock\nbard-rock, gypsy jazz, klezmer\nbardcore\nbardcore folk\nbaritone a cappella\nbaritone ballad\nbaritone crooner\nbaroque\nbaroque ambient\nbaroque bossa nova\nbaroque cabaret\nbaroque cello\nbaroque chamber\nbaroque chamber music\nbaroque chamber, video game music\nbaroque chiptune\nbaroque cinematic\nbaroque classical\nbaroque classical, chiptune, video game music\nbaroque classical, hard trance, techno\nbaroque classical, video game soundtrack\nbaroque concerto grosso\nbaroque cumbia\nbaroque electronic\nbaroque electronica\nbaroque folk\nbaroque folk-rock\nbaroque funk\nbaroque harp\nbaroque hip hop\nbaroque hip-hop\nbaroque metal\nbaroque opera\nbaroque orchestral\nbaroque organ\nbaroque pop\nbaroque pop R&B\nbaroque pop chiptune\nbaroque pop garage rock\nbaroque pop indie rock\nbaroque pop psychedelic rock\nbaroque pop rock\nbaroque pop, Latin tango\nbaroque pop, chiptune, electronic\nbaroque pop, folk rock, chiptune\nbaroque pop, garage rock, noise rock\nbaroque pop, hard rock\nbaroque pop, musical theater, bluegrass\nbaroque pop, pop-rock, cinematic\nbaroque pop, surf rock\nbaroque pop, turbo-folk\nbaroque pop-rock\nbaroque pop-rock garage rock\nbaroque punk\nbaroque rock\nbaroque salsa\nbaroque synth\nbaroque synth-pop\nbaroque trap\nbaroque trap-pop\nbaroque video game\nbaroque, ambient, choral\nbaroque, ambient, cinematic\nbaroque, choral, folk\nbaroque, cinematic, choral\nbaroque, cinematic, gothic\nbaroque, cinematic, orchestral\nbaroque, cinematic, video game\nbaroque, fantasy, video game\nbaroque, spooky, lo-fi\nbaroque, world music, cinematic\nbaroque-inspired, cinematic, fantasy\nbaroque-pop\nbaroque-pop alternative rock\nbaroque-pop chiptune\nbaroque-pop cinematic\nbaroque-pop funk rock\nbaroque-pop funk soul\nbaroque-pop garage rock\nbaroque-pop hip-hop\nbaroque-pop indie rock\nbaroque-pop power ballad\nbaroque-pop rock\nbaroque-pop, Latin pop\nbaroque-pop, funk soul, gospel\nbaroque-pop, new wave\nbaroque-trap\nbarroom piano rock\nbarroom rock\nbass\nbass house\nbass house trap\nbass house, UK garage\nbass house, UK garage, hyperpop\nbass house, UK grime\nbass house, grime, UK rap\nbass house, hardstyle\nbass house, hardstyle, glitch\nbass house, hardstyle, neurofunk\nbass house, hardstyle, trap\nbass house, phonk, trap\nbass music\nbass virtuosity\nbass-heavy electronic\nbattle rap\nbattle rap chiptune\nbattle rap, chiptune, 8-bit\nbattle rap, chiptune, electronic\nbattle rap, retro electronic\nbatucada\nbatucada samba\nbatucada samba-reggae\nbatucada, electronic, world music\nbeach country\nbeach funk\nbeach pop\nbeach rock\nbeach rock country-rock\nbeach-pop\nbeat music\nbeat poetry\nbeatbox\nbeatbox hip hop\nbeatbox hip-hop\nbeatboxing\nbeatboxing hip hop\nbebop\nbebop cool jazz\nbebop free jazz\nbebop funk rock\nbebop jazz\nbebop jazz exotica\nbebop jazz hip-hop\nbebop jazz, video game music\nbebop piano\nbebop swing klezmer\nbebop, cinematic, jazz\nbebop, trip-hop, jazz\nbedroom R&B\nbedroom folk\nbedroom pop\nbedroom pop R&B\nbedroom pop alt-rock\nbedroom pop alternative R&B\nbedroom pop alternative rock\nbedroom pop bossa nova\nbedroom pop chiptune\nbedroom pop city pop\nbedroom pop dream pop\nbedroom pop dream-pop\nbedroom pop emo\nbedroom pop emo rap\nbedroom pop emo-pop\nbedroom pop emo-rap\nbedroom pop emo-rock\nbedroom pop future bass\nbedroom pop garage rock\nbedroom pop hip-hop\nbedroom pop indie R&B\nbedroom pop indie folk\nbedroom pop indie pop\nbedroom pop indie rock\nbedroom pop indie rock shoegaze\nbedroom pop indie-folk\nbedroom pop indie-pop\nbedroom pop lo-fi\nbedroom pop lo-fi C-pop\nbedroom pop lo-fi R&B\nbedroom pop lo-fi bossa nova\nbedroom pop lo-fi chiptune\nbedroom pop lo-fi electronic\nbedroom pop lo-fi hip hop\nbedroom pop lo-fi hip-hop\nbedroom pop lo-fi hip-hop hyperpop\nbedroom pop lo-fi indie\nbedroom pop lo-fi indie pop\nbedroom pop lo-fi indie rock\nbedroom pop lo-fi neo-soul\nbedroom pop lo-fi pop\nbedroom pop lo-fi reggaeton\nbedroom pop lo-fi trap\nbedroom pop lo-fi trap-pop\nbedroom pop lounge jazz\nbedroom pop neo-soul\nbedroom pop neo-soul lo-fi\nbedroom pop neo-soul lounge\nbedroom pop reggaeton\nbedroom pop shoegaze\nbedroom pop trap\nbedroom pop, C-pop, lo-fi hip hop\nbedroom pop, C-pop, video game music\nbedroom pop, MPB, lo-fi\nbedroom pop, R&B\nbedroom pop, R&B, trap\nbedroom pop, alt-rock\nbedroom pop, alt-rock, dream-pop\nbedroom pop, alternative R&B\nbedroom pop, alternative R&B, chiptune\nbedroom pop, alternative R&B, lo-fi electronic\nbedroom pop, alternative R&B, lo-fi hip-hop\nbedroom pop, alternative rock\nbedroom pop, alternative rock, nu-metal\nbedroom pop, breakcore\nbedroom pop, chillwave, indie pop\nbedroom pop, chiptune, C-pop\nbedroom pop, chiptune, kawaii future bass\nbedroom pop, cinematic, R&B\nbedroom pop, cloud rap\nbedroom pop, deep house\nbedroom pop, downtempo\nbedroom pop, downtempo R&B\nbedroom pop, emo rap\nbedroom pop, emo rap, lo-fi\nbedroom pop, emo rap, lo-fi hip hop\nbedroom pop, emo-rap, hyperpop\nbedroom pop, future bass\nbedroom pop, future bass, hyperpop\nbedroom pop, hyperpop\nbedroom pop, hyperpop, emo-rap\nbedroom pop, hyperpop, glitchcore\nbedroom pop, hyperpop, indie pop\nbedroom pop, hyperpop, trap\nbedroom pop, indie R&B, lo-fi hip-hop\nbedroom pop, indie pop, R&B\nbedroom pop, indie pop, hyperpop\nbedroom pop, indie pop, pop-punk\nbedroom pop, indie pop, reggaeton\nbedroom pop, indie rock, chiptune\nbedroom pop, indie rock, lo-fi\nbedroom pop, indie rock, shoegaze\nbedroom pop, latin pop, R&B\nbedroom pop, lo-fi hip hop\nbedroom pop, lo-fi hip hop, Latin pop\nbedroom pop, lo-fi hip hop, R&B\nbedroom pop, lo-fi hip-hop\nbedroom pop, lo-fi, cinematic\nbedroom pop, lo-fi, indie rock\nbedroom pop, lo-fi, jazzy\nbedroom pop, melodic hip-hop\nbedroom pop, modern R&B\nbedroom pop, neo-soul\nbedroom pop, pop-punk\nbedroom pop, pop-punk, cinematic\nbedroom pop, pop-rock\nbedroom pop, pop-rock, synth-pop\nbedroom pop, shoegaze\nbedroom pop, shoegaze, indie rock\nbedroom pop, shoegaze, lo-fi hip-hop\nbedroom pop, shoegaze, noise rock\nbedroom pop, shoegaze, post-rock\nbedroom pop, synth-pop\nbedroom pop, trap\nbedroom pop, trap, dream pop\nbedroom pop, trap, lo-fi\nbedroom soul\nbeer hall\nbelly dance\nbelly house\nbhajan\nbhajan ambient\nbhajan chiptune\nbhajan folk-pop\nbhajan fusion\nbhajan kirtan\nbhajan pop fusion\nbhajan qasheed\nbhajan qawwali\nbhajan, ambient, Indian classical\nbhajan, cinematic, ambient\nbhajan, electronic, Indian classical\nbhajan, electronic, Indian fusion\nbhajan, electronic, devotional\nbhajan, world music, pop-rock\nbhajan-pop\nbhangra\nbhangra electronic\nbhangra hip-hop\nbhangra remix\nbhangra trap\nbhangra-pop\nbhangra-trap\nbig band\nbig band Christmas\nbig band J-pop\nbig band Latin\nbig band Latin ballad\nbig band Latin pop\nbig band Mandopop\nbig band R&B\nbig band ballad\nbig band blues\nbig band bolero\nbig band boogie-woogie\nbig band bossa nova\nbig band cabaret\nbig band cabaret klezmer\nbig band cabaret tango\nbig band calypso\nbig band cha-cha-chá\nbig band christmas\nbig band circus\nbig band comedy\nbig band cumbia\nbig band fado\nbig band folk\nbig band funk\nbig band funk jazz-fusion\nbig band funk rock\nbig band funk soul\nbig band funk-rock\nbig band fusion\nbig band gospel\nbig band hip-hop\nbig band jazz\nbig band jazz Arabic pop\nbig band jazz J-pop\nbig band jazz anime\nbig band jazz bossa nova\nbig band jazz breakbeat\nbig band jazz cabaret\nbig band jazz chiptune\nbig band jazz cinematic\nbig band jazz city pop\nbig band jazz funk\nbig band jazz funk J-pop\nbig band jazz funk Kayōkyoku\nbig band jazz funk Latin jazz\nbig band jazz funk rock\nbig band jazz funk soul\nbig band jazz funk-pop\nbig band jazz funk-rock\nbig band jazz fusion\nbig band jazz gospel\nbig band jazz hip-hop\nbig band jazz kayōkyoku\nbig band jazz klezmer musette\nbig band jazz klezmer video game music\nbig band jazz nu-metal\nbig band jazz pop-rock\nbig band jazz progressive metal\nbig band jazz progressive metal video game music\nbig band jazz progressive rock\nbig band jazz progressive rock surf rock\nbig band jazz rock\nbig band jazz salsa\nbig band jazz samba\nbig band jazz samba-jazz\nbig band jazz ska\nbig band jazz ska-punk theatrical rock\nbig band jazz soul\nbig band jazz surf rock spy movie\nbig band jazz world music\nbig band jazz, Arabic music\nbig band jazz, Arabic pop\nbig band jazz, Balkan, Middle Eastern\nbig band jazz, Bollywood jazz\nbig band jazz, Brazilian popular music\nbig band jazz, Eastern European folk\nbig band jazz, Filipino jazz-pop\nbig band jazz, French chanson\nbig band jazz, German Schlager\nbig band jazz, Greek Laïko\nbig band jazz, J-pop\nbig band jazz, J-pop, J-rock\nbig band jazz, J-pop, anime theme\nbig band jazz, J-pop, city pop\nbig band jazz, J-pop, rock\nbig band jazz, J-rock\nbig band jazz, Japanese rock\nbig band jazz, K-pop, R&B\nbig band jazz, Kayōkyoku\nbig band jazz, Kayōkyoku, Enka\nbig band jazz, Kayōkyoku, theatrical\nbig band jazz, Latin jazz\nbig band jazz, Latin jazz, anime theme\nbig band jazz, Latin jazz, atmospheric piano\nbig band jazz, Latin jazz, cabaret\nbig band jazz, Latin jazz, mambo\nbig band jazz, Latin mambo\nbig band jazz, Latin pop, Turkish pop\nbig band jazz, Latin rhythm\nbig band jazz, Latin rhythms, progressive rock\nbig band jazz, Latin salsa\nbig band jazz, Latin, dramatic pop\nbig band jazz, Luk Thung\nbig band jazz, Persian pop\nbig band jazz, R&B, Christmas\nbig band jazz, Russian estrada\nbig band jazz, Tamil film music\nbig band jazz, Turkish pop\nbig band jazz, city pop\nbig band jazz, city pop, Latin jazz\nbig band jazz, concert band\nbig band jazz, dangdut\nbig band jazz, hardcore punk\nbig band jazz, musical theater, whimsical\nbig band jazz, operatic, cinematic\nbig band jazz, pop-rock\nbig band jazz, ragtime, cinematic orchestral\nbig band jazz, retro video game\nbig band jazz, salsa\nbig band jazz, soulful pop-rock, hard rock\nbig band jazz, swing-pop, anime-inspired\nbig band jazz, synth-pop, R&B\nbig band jazz, theatrical ballad, Vietnamese\nbig band jazz, video game music\nbig band jazz, video game music, surf rock\nbig band jazz-funk\nbig band jazz-fusion\nbig band jazz-pop\nbig band jazz-rock\nbig band jazz-rock fusion\nbig band lounge\nbig band mambo\nbig band metal\nbig band noir\nbig band novelty\nbig band orchestral\nbig band polka\nbig band pop\nbig band pop rock\nbig band pop schlager\nbig band pop, Latin pop, cinematic\nbig band pop, Latin, salsa\nbig band pop-gospel\nbig band pop-rock\nbig band pop-soul\nbig band punk\nbig band rock\nbig band rock and roll\nbig band rock trot\nbig band salsa\nbig band samba\nbig band samba-jazz\nbig band samba-pop\nbig band samba-rock\nbig band schlager\nbig band show tune\nbig band showtune\nbig band ska\nbig band ska-punk\nbig band soul\nbig band soul funk\nbig band soul swing\nbig band swing\nbig band swing Afro-Cuban\nbig band swing Arabic pop\nbig band swing Bollywood\nbig band swing Indian folk\nbig band swing J-pop\nbig band swing Mandopop\nbig band swing anime\nbig band swing anime soundtrack\nbig band swing anime theme\nbig band swing blues rock\nbig band swing boogie-woogie\nbig band swing bossa nova\nbig band swing cabaret\nbig band swing cabaret jazz\nbig band swing cabaret klezmer\nbig band swing cabaret pop\nbig band swing cabaret tango\nbig band swing chiptune\nbig band swing cinematic\nbig band swing doo-wop\nbig band swing exotica\nbig band swing folk-rock\nbig band swing funk\nbig band swing funk Bollywood\nbig band swing funk Indian film music\nbig band swing funk disco\nbig band swing funk gospel\nbig band swing funk hip-hop\nbig band swing funk jazz\nbig band swing funk jazz fusion\nbig band swing funk klezmer\nbig band swing funk rock\nbig band swing funk ska\nbig band swing funk soul\nbig band swing gospel\nbig band swing gypsy jazz\nbig band swing hip-hop\nbig band swing hip-hop funk-rock\nbig band swing indie pop funk\nbig band swing indie rock world music\nbig band swing j-pop\nbig band swing jazz, J-pop, chiptune\nbig band swing jazz, J-rock\nbig band swing jazz-funk\nbig band swing jump blues\nbig band swing kayōkyoku\nbig band swing klezmer\nbig band swing mambo\nbig band swing noir cabaret\nbig band swing polka\nbig band swing pop\nbig band swing pop-rock\nbig band swing punk rock\nbig band swing rock\nbig band swing rock and roll\nbig band swing rock funk\nbig band swing rock ska\nbig band swing rock soul\nbig band swing rockabilly\nbig band swing rockabilly cabaret\nbig band swing rockabilly country\nbig band swing rockabilly folk\nbig band swing rockabilly schlager\nbig band swing rockabilly ska\nbig band swing rockabilly sokou\nbig band swing rockabilly surf rock\nbig band swing samba\nbig band swing samba-rock\nbig band swing schlager\nbig band swing ska\nbig band swing ska Latin\nbig band swing ska calypso\nbig band swing ska reggae\nbig band swing ska-punk\nbig band swing ska-punk Indian film music\nbig band swing soul\nbig band swing steampunk\nbig band swing surf rock\nbig band swing surf rock rockabilly\nbig band swing tango\nbig band swing theatrical rock\nbig band swing trot\nbig band swing, Arabic vocals, hard rock\nbig band swing, Balkan brass, cabaret\nbig band swing, Bollywood\nbig band swing, Brazilian funk\nbig band swing, Broadway, funk-rock\nbig band swing, Cantopop, theatrical jazz\nbig band swing, Dutch pop\nbig band swing, Finnish schlager\nbig band swing, French chanson\nbig band swing, German Schlager\nbig band swing, German Schlager, theatrical\nbig band swing, German cabaret\nbig band swing, German cabaret, mambo\nbig band swing, German schlager\nbig band swing, Hawaiian exotica\nbig band swing, Indonesian pop\nbig band swing, Italian folk\nbig band swing, Italian folk, cinematic\nbig band swing, Italian folk-rock\nbig band swing, Italian mambo\nbig band swing, Italian pop\nbig band swing, Italian pop, rock and roll\nbig band swing, Italian pop, theatrical\nbig band swing, Italian pop-rock\nbig band swing, Italian-American polka\nbig band swing, Italo-disco, theatrical pop\nbig band swing, J-pop\nbig band swing, J-rock\nbig band swing, J-rock, Kayōkyoku\nbig band swing, J-rock, anime theme\nbig band swing, Japanese rap\nbig band swing, Japanese rock\nbig band swing, Kayōkyoku\nbig band swing, Korean trot\nbig band swing, Latin bolero\nbig band swing, Latin jazz\nbig band swing, Latin jazz, mambo\nbig band swing, Latin mambo\nbig band swing, Latin mambo, rock and roll\nbig band swing, Latin percussion, jazz fusion\nbig band swing, Latin pop, reggaeton\nbig band swing, Latin pop-rock\nbig band swing, Latin rock\nbig band swing, Latin samba\nbig band swing, Latin, theatrical\nbig band swing, Luk Thung\nbig band swing, Mandopop\nbig band swing, North African pop\nbig band swing, Parisian chanson\nbig band swing, Polish pop-rock\nbig band swing, R&B, hip-hop\nbig band swing, Russian estrada, pop\nbig band swing, Shidaiqu\nbig band swing, South Indian film music\nbig band swing, Tamil film music\nbig band swing, Thai Luk Thung\nbig band swing, Turkish pop\nbig band swing, bebop, lo-fi\nbig band swing, blues-rock\nbig band swing, blues-rock, soul\nbig band swing, boogie-woogie, cinematic\nbig band swing, boogie-woogie, rock and roll\nbig band swing, breakbeat, electronic\nbig band swing, breakbeat, grime\nbig band swing, cabaret pop\nbig band swing, cabaret rock\nbig band swing, cabaret, art-song\nbig band swing, calypso, soulful ballad, rockabilly, salsa\nbig band swing, chiptune, J-pop\nbig band swing, chiptune, cartoon soundtrack\nbig band swing, city pop\nbig band swing, city pop, video game music\nbig band swing, dubstep, theatrical pop\nbig band swing, electronic fusion\nbig band swing, eurodance\nbig band swing, free jazz, romantic ballad\nbig band swing, funk, jazz\nbig band swing, hard house\nbig band swing, hard rock\nbig band swing, hard rock, chiptune\nbig band swing, hard rock, fusion\nbig band swing, hip-hop\nbig band swing, jazz, J-pop\nbig band swing, jump blues\nbig band swing, jump blues, Hanukkah\nbig band swing, jump blues, rock and roll\nbig band swing, klezmer pop-rock\nbig band swing, klezmer, cabaret\nbig band swing, klezmer, cartoon soundtrack\nbig band swing, kuthu, hip-hop\nbig band swing, laïko\nbig band swing, mambo, rock and roll\nbig band swing, modern rock, C-pop\nbig band swing, pansori\nbig band swing, pop-rock\nbig band swing, pop-rock, cinematic\nbig band swing, pop-soul\nbig band swing, retro rock and roll\nbig band swing, rock and roll, J-rock\nbig band swing, rock and roll, Latin jazz\nbig band swing, rock and roll, theatrical\nbig band swing, rockabilly, Japanese Christmas\nbig band swing, samba\nbig band swing, samba, Brazilian\nbig band swing, samba, theatrical\nbig band swing, samba-rock\nbig band swing, schlager\nbig band swing, schlager, Christmas\nbig band swing, soulful ballad, gospel rock\nbig band swing, surf rock\nbig band swing, surf rock, video game music\nbig band swing, theatrical cabaret\nbig band swing, theatrical chanson\nbig band swing, theatrical rock\nbig band swing, trap, theatrical\nbig band swing, trot\nbig band swing, video game music\nbig band swing, vintage Italian pop\nbig band swing-pop\nbig band swing-rock\nbig band tango\nbig band trot\nbig band vocal jazz\nbig band waltz\nbig band, Afro-Caribbean, jazz\nbig band, Arabic folk, dance\nbig band, Arabic jazz\nbig band, Arabic jazz, cinematic\nbig band, Arabic pop, cinematic\nbig band, Balkan brass, jazz\nbig band, Balkan folk, theatrical\nbig band, Balkan swing, rock and roll\nbig band, Balkan, Klezmer\nbig band, Balkan, ballad\nbig band, Bollywood, show tune\nbig band, Bollywood, theatrical\nbig band, Brazilian gospel, MPB\nbig band, Brazilian jazz\nbig band, Brazilian pop, orchestral pop\nbig band, Brazilian pop, theatrical\nbig band, Brazilian popular music\nbig band, Brazilian popular music, theatrical\nbig band, Brazilian popular music, theatrical jazz\nbig band, Broadway, Christmas\nbig band, Broadway, theatrical\nbig band, C-pop, cinematic\nbig band, Cantopop\nbig band, Christmas novelty\nbig band, Christmas pop\nbig band, Christmas pop, retro\nbig band, Christmas, children's choir\nbig band, Christmas, jazz\nbig band, Christmas, pop\nbig band, Christmas, show tune\nbig band, Christmas, swing\nbig band, Christmas, theatrical\nbig band, Enka, Kayōkyoku\nbig band, Finnish folk, theatrical\nbig band, French chanson, cinematic\nbig band, French chanson, swing\nbig band, French chanson, theatrical\nbig band, Greek, Balkan\nbig band, Hawaiian, festive\nbig band, Israeli pop, vintage\nbig band, Italian folk, theatrical\nbig band, J-pop, Christmas\nbig band, J-pop, swing\nbig band, Kayōkyoku\nbig band, Kayōkyoku, Enka\nbig band, Kayōkyoku, Latin jazz\nbig band, Kayōkyoku, blues rock\nbig band, Kayōkyoku, cinematic\nbig band, Kayōkyoku, funk\nbig band, Kayōkyoku, jazz\nbig band, Kayōkyoku, lounge\nbig band, Kayōkyoku, mambo\nbig band, Kayōkyoku, orchestral\nbig band, Kayōkyoku, retro\nbig band, Kayōkyoku, rock and roll\nbig band, Kayōkyoku, soul\nbig band, Kayōkyoku, tango\nbig band, Kayōkyoku, theatrical\nbig band, Kayōkyoku, theatrical jazz\nbig band, Kayōkyoku, theatrical pop\nbig band, Kayōkyoku, vintage jazz\nbig band, Korean trot\nbig band, Latin bolero, cinematic\nbig band, Latin bolero, copla\nbig band, Latin bolero, mambo\nbig band, Latin bolero, ranchera\nbig band, Latin bolero, theatrical\nbig band, Latin cabaret\nbig band, Latin jazz\nbig band, Latin jazz, C-pop\nbig band, Latin jazz, Christmas\nbig band, Latin jazz, Kayōkyoku\nbig band, Latin jazz, bolero\nbig band, Latin jazz, cha-cha-chá\nbig band, Latin jazz, cinematic\nbig band, Latin jazz, devotional\nbig band, Latin jazz, lounge\nbig band, Latin jazz, mambo\nbig band, Latin jazz, rock\nbig band, Latin jazz, show tune\nbig band, Latin jazz, soul\nbig band, Latin jazz, surf rock\nbig band, Latin jazz, swing\nbig band, Latin jazz, theatrical\nbig band, Latin jazz, theatrical pop\nbig band, Latin jazz, vintage\nbig band, Latin jazz, vintage lounge\nbig band, Latin mambo, boogaloo\nbig band, Latin mambo, jazz\nbig band, Latin mambo, swing\nbig band, Latin mambo, theatrical\nbig band, Latin pop, Israeli folk-pop\nbig band, Latin pop, vintage\nbig band, Latin, Arabic\nbig band, Latin, Enka\nbig band, Latin, Hebrew folk\nbig band, Latin, Klezmer\nbig band, Latin, Luk Thung\nbig band, Latin, Mandopop\nbig band, Latin, Mediterranean\nbig band, Latin, Middle Eastern\nbig band, Latin, Southeast Asian\nbig band, Latin, ballad\nbig band, Latin, brass\nbig band, Latin, chanson\nbig band, Latin, cinematic\nbig band, Latin, exotica\nbig band, Latin, klezmer\nbig band, Latin, mambo\nbig band, Latin, swing\nbig band, Latin, tango\nbig band, Latin, theatrical\nbig band, Latin, trot\nbig band, Latin, vintage\nbig band, Latin-cha-cha, Kayōkyoku\nbig band, Luk Thung\nbig band, Luk Thung, Thai\nbig band, Luk Thung, cinematic\nbig band, Luk Thung, vintage\nbig band, MPB\nbig band, MPB, Bossa Nova\nbig band, MPB, samba\nbig band, MPB, soul\nbig band, Mandopop\nbig band, Mandopop, Kayōkyoku\nbig band, Mandopop, Shidaiqu\nbig band, Mandopop, cinematic\nbig band, Mandopop, jazz\nbig band, Mandopop, orchestral\nbig band, Mandopop, swing\nbig band, Mandopop, theatrical\nbig band, Mandopop, vintage\nbig band, North Korean folk\nbig band, R&B, Christmas\nbig band, R&B, gospel\nbig band, Russian estrada, theatrical\nbig band, Russian estrada, vintage\nbig band, Russian folk, cabaret\nbig band, Russian romance, theatrical\nbig band, Shidaiqu\nbig band, Shidaiqu, swing\nbig band, South Asian film music\nbig band, Southeast Asian jazz\nbig band, Soviet-era estrada, theatrical\nbig band, Spanish copla, theatrical\nbig band, Taiwanese Hokkien pop\nbig band, anime theme, orchestral\nbig band, anime theme, theatrical\nbig band, blues, free jazz\nbig band, blues-rock, theatrical\nbig band, bolero, Latin ballroom\nbig band, bolero, Latin jazz\nbig band, bolero, cinematic\nbig band, bolero, jazz\nbig band, bolero, mambo\nbig band, bolero, ranchera\nbig band, bolero, romantic\nbig band, bolero, salsa\nbig band, bolero, theatrical\nbig band, bolero-samba, theatrical\nbig band, boogie-woogie, jazz\nbig band, bossa nova, cinematic\nbig band, bossa nova, jazz\nbig band, cabaret, Eastern European\nbig band, cabaret, Eastern European folk\nbig band, cabaret, Latin\nbig band, cabaret, Russian jazz\nbig band, cabaret, Schlager\nbig band, cabaret, circus music\nbig band, cabaret, orchestral\nbig band, cabaret, polka\nbig band, cabaret, protest\nbig band, cabaret, rock\nbig band, cabaret, show tune\nbig band, cabaret, tango\nbig band, cabaret, theatrical\nbig band, carnival, theatrical\nbig band, cartoonish, theatrical\nbig band, ceremonial, Thai traditional\nbig band, chanson, cinematic\nbig band, chanson, jazz\nbig band, chanson, levenslied\nbig band, chanson, polka\nbig band, children's music, cinematic\nbig band, children's music, swing\nbig band, children's music, theatrical\nbig band, children's show tune\nbig band, choral, Christmas\nbig band, choral, theatrical\nbig band, cinematic, Brazilian pop\nbig band, cinematic, Brazilian popular\nbig band, cinematic, Enka\nbig band, cinematic, Filipino pop\nbig band, cinematic, French chanson\nbig band, cinematic, Kayōkyoku\nbig band, cinematic, Latin\nbig band, cinematic, Latin jazz\nbig band, cinematic, Luk Thung\nbig band, cinematic, Mandopop\nbig band, cinematic, Russian estrada\nbig band, cinematic, Turkish pop\nbig band, cinematic, ballad\nbig band, cinematic, bolero\nbig band, cinematic, bossa nova\nbig band, cinematic, cartoon chase\nbig band, cinematic, chanson\nbig band, cinematic, enka\nbig band, cinematic, estrada\nbig band, cinematic, film noir\nbig band, cinematic, jazz\nbig band, cinematic, lounge\nbig band, cinematic, operatic\nbig band, cinematic, orchestral\nbig band, cinematic, retro\nbig band, cinematic, salsa\nbig band, cinematic, samba\nbig band, cinematic, show tune\nbig band, cinematic, spy movie\nbig band, cinematic, spy theme\nbig band, cinematic, spy thriller\nbig band, cinematic, tango\nbig band, cinematic, theatrical\nbig band, cinematic, torch song\nbig band, cinematic, trot\nbig band, cinematic, vintage\nbig band, circus, disco\nbig band, comedic, show tune\nbig band, copla, Latin jazz\nbig band, copla, Spanish drama\nbig band, copla, cinematic\nbig band, copla, flamenco\nbig band, copla, theatrical\nbig band, dangdut, Indonesian pop\nbig band, dramatic ballad, MPB\nbig band, enka, cinematic\nbig band, enka, kayōkyoku\nbig band, enka, theatrical\nbig band, enka, theatrical jazz\nbig band, enka, theatrical rock\nbig band, estrada, Soviet\nbig band, estrada, Soviet jazz\nbig band, estrada, Soviet-era\nbig band, estrada, nostalgic\nbig band, estrada, orchestral\nbig band, estrada, swing\nbig band, exotica, Latin\nbig band, exotica, show tune\nbig band, experimental\nbig band, fado, theatrical\nbig band, festive, cinematic\nbig band, festive, circus\nbig band, festive, orchestral\nbig band, film score, Shidaiqu\nbig band, flamenco, copla\nbig band, flamenco, salsa\nbig band, folk fusion, instrumental\nbig band, folk, cinematic\nbig band, free jazz, psychedelic rock\nbig band, funk, Arabic jazz\nbig band, funk, Brazilian\nbig band, funk, chiptune\nbig band, funk, cinematic\nbig band, funk, city pop\nbig band, funk, disco\nbig band, funk-rock, cinematic\nbig band, funk-rock, theatrical\nbig band, gospel, Christmas\nbig band, gospel, theatrical\nbig band, holiday, orchestral\nbig band, jazz, Christmas\nbig band, jazz, Christmas novelty\nbig band, jazz, Latin, ballad\nbig band, jazz, Luk Thung\nbig band, jazz, Thai pop\nbig band, jazz, choral\nbig band, jazz, cinematic\nbig band, jazz, pop\nbig band, jazz, theatrical\nbig band, jump blues, Christmas\nbig band, klezmer, Eastern European folk\nbig band, klezmer, Israeli folk\nbig band, klezmer, cartoon soundtrack\nbig band, klezmer, folk\nbig band, klezmer, show tune\nbig band, klezmer, ska\nbig band, klezmer, swing\nbig band, laïko\nbig band, laïko, theatrical\nbig band, lounge jazz, boogie-woogie\nbig band, lounge, Christmas\nbig band, lounge, Latin jazz\nbig band, luk thung\nbig band, mambo, Arabic jazz\nbig band, mambo, European folk\nbig band, mambo, Latin jazz\nbig band, mambo, enka\nbig band, mambo, jazz\nbig band, mambo, romantic ballad\nbig band, mambo, salsa\nbig band, mambo, theatrical\nbig band, marching band, cinematic\nbig band, musical theater, vintage\nbig band, musical theatre, swing\nbig band, nostalgic pop, cinematic\nbig band, novelty, Christmas\nbig band, novelty, Italian-American\nbig band, novelty, Latin jazz\nbig band, novelty, theatrical\nbig band, operatic pop, vintage Mandopop\nbig band, operatic, Kayōkyoku\nbig band, operatic, cinematic\nbig band, operatic, enka\nbig band, operatic, theatrical\nbig band, operatic, trot\nbig band, orchestral pop\nbig band, orchestral, Christmas\nbig band, orchestral, Schlager\nbig band, orchestral, Turkish pop\nbig band, orchestral, cinematic\nbig band, orchestral, lounge\nbig band, orchestral, theatrical\nbig band, pansori, cinematic\nbig band, pasodoble, brass\nbig band, patriotic, choral\nbig band, polka, Christmas\nbig band, polka, theatrical\nbig band, pop ballad, cinematic\nbig band, pop-rock, brass\nbig band, pop-rock, retro pop\nbig band, punk-jazz, free jazz\nbig band, quirky, theatrical\nbig band, retro anime, festive\nbig band, retro, anime theme\nbig band, retro, estrada\nbig band, revolutionary folk-pop\nbig band, rock and roll\nbig band, rock and roll, show tune\nbig band, rock and roll, theatrical\nbig band, rockabilly, country\nbig band, rockabilly, jump blues\nbig band, salsa, orchestral\nbig band, samba, bossa nova\nbig band, samba, cinematic\nbig band, samba, gospel\nbig band, samba, theatrical\nbig band, samba-funk, cinematic\nbig band, samba-reggae, theatrical\nbig band, samba-rock, theatrical\nbig band, satirical, show tune\nbig band, schlager, humppa\nbig band, schlager, show tune\nbig band, schlager, theatrical\nbig band, show tune, Christmas\nbig band, show tune, Christmas novelty\nbig band, show tune, Mandopop\nbig band, show tune, comedic\nbig band, show tune, comedic jazz\nbig band, show tune, novelty\nbig band, show tune, satirical\nbig band, show tune, theatrical\nbig band, ska-punk, jazz\nbig band, soul, Christmas\nbig band, soul, funk\nbig band, soul, gospel\nbig band, soul, swing\nbig band, soul, theatrical\nbig band, spy thriller, noir\nbig band, surf rock, cartoon\nbig band, surf rock, enka\nbig band, surf rock, spy thriller\nbig band, surf-rock, Kayōkyoku\nbig band, swing jazz, theatrical\nbig band, swing rock, trot\nbig band, swing, Christmas\nbig band, swing, J-pop\nbig band, swing, South Asian folk\nbig band, swing, children's music\nbig band, swing, gospel\nbig band, swing, holiday\nbig band, swing, jazz\nbig band, swing, rock and roll\nbig band, swing, show tune\nbig band, swing, theatrical\nbig band, tango, Eastern European folk\nbig band, tango, bolero\nbig band, tango, cabaret\nbig band, tango, cinematic\nbig band, tango, fado\nbig band, tango, mambo\nbig band, tango, theatrical\nbig band, theatrical jazz, Japanese vocal\nbig band, theatrical pop, Balkan pop\nbig band, theatrical pop, psychedelic\nbig band, theatrical pop, rock\nbig band, theatrical, Balkan jazz\nbig band, theatrical, Brazilian popular\nbig band, theatrical, Brazilian popular music\nbig band, theatrical, C-pop\nbig band, theatrical, Canto-pop\nbig band, theatrical, Christmas\nbig band, theatrical, Christmas novelty\nbig band, theatrical, European\nbig band, theatrical, Finnish show tune\nbig band, theatrical, French chanson\nbig band, theatrical, Indonesian pop\nbig band, theatrical, Italian opera\nbig band, theatrical, Italian popular\nbig band, theatrical, Kayōkyoku\nbig band, theatrical, Korean trot\nbig band, theatrical, Latin\nbig band, theatrical, Latin jazz\nbig band, theatrical, animated musical\nbig band, theatrical, anthemic\nbig band, theatrical, bolero\nbig band, theatrical, bouzouki\nbig band, theatrical, cabaret\nbig band, theatrical, cartoonish\nbig band, theatrical, children's music\nbig band, theatrical, chiptune\nbig band, theatrical, choral\nbig band, theatrical, cinematic\nbig band, theatrical, circus\nbig band, theatrical, comedic\nbig band, theatrical, comedy\nbig band, theatrical, copla\nbig band, theatrical, enka\nbig band, theatrical, estrada\nbig band, theatrical, film score\nbig band, theatrical, flamenco\nbig band, theatrical, gospel pop\nbig band, theatrical, industrial\nbig band, theatrical, jazz\nbig band, theatrical, klezmer\nbig band, theatrical, lo-fi\nbig band, theatrical, mambo\nbig band, theatrical, musical theatre\nbig band, theatrical, operatic\nbig band, theatrical, operatic pop\nbig band, theatrical, orchestral\nbig band, theatrical, patriotic\nbig band, theatrical, polka\nbig band, theatrical, revolutionary anthem\nbig band, theatrical, samba\nbig band, theatrical, satire\nbig band, theatrical, satirical\nbig band, theatrical, schlager\nbig band, theatrical, show tune\nbig band, theatrical, swing\nbig band, theatrical, tango\nbig band, theatrical, vintage\nbig band, theatrical, vintage musical\nbig band, torch song, cinematic\nbig band, traditional Thai, vintage\nbig band, trot\nbig band, trot, blues\nbig band, trot, cinematic\nbig band, trot, jazz\nbig band, trot, orchestral\nbig band, trot, retro\nbig band, trot, swing rock\nbig band, trot, theatrical\nbig band, trot, vintage\nbig band, vintage Indonesian pop\nbig band, vintage Polish pop\nbig band, vintage pop, Taiwanese Hokkien\nbig band, vintage pop, Thai pop\nbig band, vintage pop, theatrical\nbig band, vocal jazz, swing\nbig beat\nbig beat R&B\nbig beat acid house\nbig beat acid techno\nbig beat alternative rock\nbig beat breakbeat\nbig beat breakcore\nbig beat chiptune\nbig beat chiptune breakbeat\nbig beat dance-punk\nbig beat dancehall\nbig beat drum and bass\nbig beat drum and bass electronic rock\nbig beat drum and bass hard trance\nbig beat electro\nbig beat electro chiptune\nbig beat electro funk\nbig beat electro house\nbig beat electro-funk\nbig beat electro-pop\nbig beat electro-punk\nbig beat electro-rock\nbig beat electro-swing\nbig beat electroclash\nbig beat electronic rock\nbig beat experimental hip-hop\nbig beat funk\nbig beat funk acid jazz\nbig beat funk breaks\nbig beat funk carioca\nbig beat funk chiptune\nbig beat funk electronic\nbig beat funk experimental\nbig beat funk experimental hip-hop\nbig beat funk fusion\nbig beat funk hip-hop\nbig beat funk house\nbig beat funk rap\nbig beat funk rock\nbig beat funk rock electronic\nbig beat funk rock electronic dance\nbig beat funk rock hip hop\nbig beat funk world music\nbig beat funk-pop\nbig beat funk-rap\nbig beat funk-rock\nbig beat glitch-hop\nbig beat happy hardcore\nbig beat hip-hop\nbig beat industrial\nbig beat industrial breakbeat\nbig beat industrial drum and bass\nbig beat industrial electronic\nbig beat industrial funk\nbig beat industrial hip-hop\nbig beat industrial rock\nbig beat industrial techno\nbig beat jungle\nbig beat lounge\nbig beat neurofunk\nbig beat nu-disco\nbig beat nu-funk\nbig beat nu-jazz\nbig beat nu-metal\nbig beat pop-punk\nbig beat pop-rap\nbig beat pop-rock\nbig beat progressive house\nbig beat psytrance\nbig beat punk\nbig beat punk rock\nbig beat punk rock electronic\nbig beat rap-rock\nbig beat rave\nbig beat rock\nbig beat ska-punk C-pop\nbig beat surf rock\nbig beat techno\nbig beat techstep\nbig beat trip-hop\nbig beat trip-hop world music\nbig beat, Bollywood pop\nbig beat, Bollywood, breakbeat\nbig beat, Bollywood, electronic\nbig beat, J-pop\nbig beat, J-pop, breakbeat\nbig beat, J-pop, electronic\nbig beat, Latin funk\nbig beat, Latin funk, drum and bass\nbig beat, UK garage, breakbeat\nbig beat, UK garage, funk\nbig beat, acid techno\nbig beat, alternative rock, hip-hop\nbig beat, breakbeat, South Indian film music\nbig beat, breakbeat, chiptune\nbig beat, breakbeat, hip-hop\nbig beat, breakbeat, video game\nbig beat, cinematic, electronic\nbig beat, disco, funk\nbig beat, drum and bass, Arabic pop\nbig beat, drum and bass, electro-pop\nbig beat, drum and bass, industrial\nbig beat, dubstep, breakbeat\nbig beat, electronic dance, video game music\nbig beat, electronic rock, conscious hip-hop\nbig beat, experimental electronic\nbig beat, experimental hip-hop\nbig beat, experimental hip-hop, breakbeat\nbig beat, hard breakbeat\nbig beat, hard techno\nbig beat, hard techno, breakbeat\nbig beat, hip-hop, K-pop\nbig beat, industrial rock\nbig beat, industrial rock, chiptune\nbig beat, industrial rock, cinematic\nbig beat, jungle, ambient\nbig beat, kuthu, Tamil rap\nbig beat, neurofunk\nbig beat, nu-metal, chiptune\nbig beat, nu-metal, rap-rock\nbig beat, pop-rock, C-pop\nbig beat, psytrance, world music\nbig beat, rap rock, electronic\nbig beat, rapcore\nbig beat, southern rock\nbig beat, trance, industrial rock\nbig beat, trip-hop, Eastern European pop-rock\nbig beat, world fusion, Bollywood electronica\nbig beat, world music, alternative rock\nbig room\nbig room EDM\nbig room EDM hardstyle\nbig room EDM, Tamil rap\nbig room EDM, hardstyle, cinematic\nbig room electro house\nbig room house\nbig room house chiptune\nbig room house electro\nbig room house festival trap\nbig room house hardstyle\nbig room house hip-hop\nbig room house melbourne bounce\nbig room house pop-rap\nbig room house, EDM, rap\nbig room house, Latin house, EDM\nbig room house, Latin pop\nbig room house, Latin pop, EDM\nbig room house, complextro, cinematic\nbig room house, electro, EDM\nbig room house, hardstyle\nbig room house, hardstyle, C-pop\nbig room house, hardstyle, EDM\nbig room house, hardstyle, ambient\nbig room house, hardstyle, cinematic\nbig room house, hardstyle, electronic dance\nbig room house, hardstyle, gabber\nbig room house, hardstyle, rock\nbig room house, hardstyle, trap\nbig room house, hip-hop, electro house\nbig room house, rap, melodic pop\nbig room techno\nbig room trance\nbig room, EDM, Middle Eastern\nbig room, electro house\nbig room, hardstyle, cinematic\nbig room, hardstyle, cinematic EDM\nbig room, hardstyle, festival\nbig-band\nbig-band Christmas pop\nbig-band Latin\nbig-band jazz\nbig-band jazz-pop\nbig-band pop\nbig-band pop-rock\nbig-band rock\nbig-band swing\nbig-band, theatrical, Halloween\nbig-room house\nbig-room progressive house\nbiker rock\nbilingual R&B\nbilingual R&B trap\nbilingual ballad\nbilingual club\nbilingual cumbia\nbilingual dance pop\nbilingual folk\nbilingual fusion\nbilingual hip-hop\nbilingual hip-hop rock\nbilingual party rap\nbilingual pop\nbilingual pop R&B\nbilingual pop ballad\nbilingual pop cumbia\nbilingual pop hip-hop\nbilingual pop reggaeton\nbilingual pop, Bollywood pop, R&B\nbilingual pop, Brazilian rhythms\nbilingual pop, EDM, ballad\nbilingual pop, EDM, funk\nbilingual pop, Latin folk, Eastern European folk\nbilingual pop, Latin pop, pop-rock\nbilingual pop, Latin, Middle Eastern\nbilingual pop, Middle Eastern fusion, hip-hop\nbilingual pop, Middle Eastern pop, Southeast Asian pop\nbilingual pop, Middle Eastern pop, electronic dance\nbilingual pop, North African, Latin\nbilingual pop, R&B, South Asian\nbilingual pop, ambient trap\nbilingual pop, chiptune\nbilingual pop, chiptune, EDM\nbilingual pop, chiptune, Indian pop\nbilingual pop, chiptune, South Asian pop\nbilingual pop, chiptune, electronic\nbilingual pop, chiptune, video game music\nbilingual pop, dark pop, reggaeton\nbilingual pop, electronic, Indian fusion\nbilingual pop, electronic, emotional\nbilingual pop, funk, EDM\nbilingual pop, funk, electronic\nbilingual pop, hip-hop, R&B\nbilingual pop, hip-hop, chiptune\nbilingual pop, lo-fi, Latin pop\nbilingual pop, reggaeton\nbilingual pop, reggaeton, Latin pop\nbilingual pop, reggaeton, cinematic pop\nbilingual pop, reggaeton, dancehall\nbilingual pop, reggaeton, dark pop\nbilingual pop, reggaeton, melancholic\nbilingual pop, trap R&B\nbilingual pop, trap pop\nbilingual pop, trap, R&B\nbilingual pop, trap, atmospheric\nbilingual pop, trap, dancehall\nbilingual pop, trap, dreamy electronic\nbilingual pop-fusion\nbilingual pop-rap\nbilingual pop-rock\nbilingual rock\nbilingual trap\nbit-crushed\nbit-crushed synth\nbitcore\nbitcrush\nbitcrushed\nbitcrushed chiptune\nbitcrushed electro\nbitcrushed electronic\nbitcrushed synth\nbitpop\nbitpop electroclash\nbitpop lo-fi chiptune\nbitpop lo-fi electronic\nbitpop synth-pop\nbitpop, Nintendocore, chiptune\nbitpop, electronic, synthwave\nbitpop, lo-fi electronic\nbitpop, synth-pop, electro-punk\nbitwave\nblack MIDI\nblack metal\nblatnaya pesnya\nbluegrass\nbluegrass Americana\nbluegrass Christmas\nbluegrass French folk\nbluegrass J-pop\nbluegrass R&B\nbluegrass a cappella\nbluegrass americana\nbluegrass blues\nbluegrass chanson\nbluegrass children's\nbluegrass children's folk\nbluegrass children's music\nbluegrass chiptune\nbluegrass comedy\nbluegrass comedy folk\nbluegrass country\nbluegrass country acoustic rock\nbluegrass country boogie\nbluegrass country gospel\nbluegrass country novelty\nbluegrass country parody\nbluegrass country rock\nbluegrass country rock folk\nbluegrass country-blues\nbluegrass country-folk\nbluegrass country-funk\nbluegrass country-gospel\nbluegrass country-pop\nbluegrass country-rock\nbluegrass cumbia\nbluegrass drum and bass\nbluegrass eurodance\nbluegrass fiddle\nbluegrass flamenco\nbluegrass flamenco fusion\nbluegrass folk\nbluegrass folk indie rock\nbluegrass folk polka\nbluegrass folk rock\nbluegrass folk-gospel\nbluegrass folk-pop\nbluegrass folk-punk\nbluegrass folk-rock\nbluegrass folk-rock gypsy punk\nbluegrass funk\nbluegrass funk-rock\nbluegrass fusion\nbluegrass fusion world music\nbluegrass gospel\nbluegrass gospel blues\nbluegrass gospel country rock\nbluegrass gospel folk\nbluegrass gospel rockabilly\nbluegrass gothic country\nbluegrass gypsy jazz\nbluegrass gypsy jazz chanson\nbluegrass gypsy-folk\nbluegrass happy hardcore\nbluegrass hip-hop\nbluegrass hip-hop rock\nbluegrass honky-tonk\nbluegrass hyperpop\nbluegrass indie rock\nbluegrass mandolin\nbluegrass metal\nbluegrass metalcore\nbluegrass newgrass\nbluegrass novelty\nbluegrass old-time\nbluegrass old-time country\nbluegrass old-time folk\nbluegrass orchestral folk\nbluegrass outlaw country\nbluegrass pirate rock\nbluegrass polka\nbluegrass pop chiptune\nbluegrass pop-country\nbluegrass pop-punk\nbluegrass pop-rock\nbluegrass psychedelic pop\nbluegrass punk\nbluegrass punk cowpunk\nbluegrass punk garage rock\nbluegrass punk rock\nbluegrass punk rockabilly\nbluegrass punk, hard rock\nbluegrass punk, rockabilly\nbluegrass ragtime\nbluegrass ragtime novelty\nbluegrass rap\nbluegrass rap-rock\nbluegrass rock\nbluegrass rock, Celtic punk\nbluegrass rockabilly\nbluegrass rockabilly country\nbluegrass rockabilly country rock\nbluegrass rockabilly polka\nbluegrass satire\nbluegrass sea shanty\nbluegrass show tune\nbluegrass shred\nbluegrass ska\nbluegrass ska-punk\nbluegrass soul\nbluegrass southern rock\nbluegrass swing\nbluegrass swing rockabilly\nbluegrass synth-pop\nbluegrass techno\nbluegrass video game\nbluegrass, American folk\nbluegrass, Americana\nbluegrass, Balkan folk, gypsy jazz\nbluegrass, Celtic folk\nbluegrass, Celtic folk, pop-rock\nbluegrass, Celtic, gypsy jazz\nbluegrass, Irish folk\nbluegrass, Italian pop-folk\nbluegrass, South Asian folk\nbluegrass, Western swing\nbluegrass, Western swing, lap steel blues\nbluegrass, americana\nbluegrass, country\nbluegrass, country gospel\nbluegrass, country rock\nbluegrass, country rock, devotional\nbluegrass, country, French-Canadian folk\nbluegrass, country, folk-rock\nbluegrass, country-blues\nbluegrass, country-folk\nbluegrass, country-rock\nbluegrass, country-rock, ambient\nbluegrass, country-rock, experimental\nbluegrass, country-western\nbluegrass, country-western, children's music\nbluegrass, country-western, novelty\nbluegrass, dubstep, EDM\nbluegrass, electronic dance\nbluegrass, electronic dance music\nbluegrass, folk-punk\nbluegrass, gypsy jazz\nbluegrass, gypsy jazz, mandolin\nbluegrass, happy hardcore\nbluegrass, old-time country\nbluegrass, old-time folk\nbluegrass, rockabilly\nbluegrass, traditional country\nbluegrass, western swing\nbluegrass-EDM\nbluegrass-funk\nbluegrass-pop\nbluegrass-punk\nbluegrass-punk folk-rock\nbluegrass-rock\nblues\nblues Christmas\nblues R&B\nblues a cappella\nblues acoustic\nblues americana\nblues ballad\nblues bass\nblues big band\nblues boogie-woogie\nblues cabaret\nblues chanson\nblues country\nblues country art rock\nblues country boogie-woogie\nblues country folk\nblues country punk\nblues country rock\nblues country-blues\nblues country-folk\nblues crooner\nblues electronica\nblues fingerstyle\nblues flamenco\nblues folk\nblues folk americana\nblues folk fusion\nblues folk gospel\nblues folk pop\nblues folk ragtime\nblues folk rock\nblues funk\nblues funk boogie-woogie\nblues funk neo-soul\nblues funk rock\nblues funk soul\nblues funk surf rock\nblues fusion\nblues gospel\nblues gospel ragtime\nblues guitar\nblues hip hop\nblues hip-hop\nblues indie rock\nblues instrumental\nblues jazz\nblues jazz ballad\nblues jazz cabaret\nblues jazz flamenco\nblues jazz gospel\nblues jazz soul\nblues lounge\nblues lounge jazz\nblues lullaby\nblues noir\nblues piano\nblues piano ballad\nblues piano trio\nblues pop\nblues pop rock\nblues pop-punk\nblues pop-rock\nblues power ballad\nblues protest\nblues punk\nblues ragtime\nblues ragtime cabaret\nblues rap\nblues rock\nblues rock Arabic\nblues rock R&B\nblues rock a cappella\nblues rock alternative rock\nblues rock ambient\nblues rock big band\nblues rock boogie-woogie\nblues rock cabaret\nblues rock city pop\nblues rock country\nblues rock country rock\nblues rock country rockabilly\nblues rock country western swing\nblues rock country-rock\nblues rock country-western\nblues rock flamenco\nblues rock folk\nblues rock forró\nblues rock funk\nblues rock funk boogie-woogie\nblues rock funk city pop\nblues rock funk latin\nblues rock funk psychedelic\nblues rock funk rock\nblues rock funk soul\nblues rock garage rock\nblues rock glam rock\nblues rock gospel\nblues rock gospel rock\nblues rock gospel rockabilly\nblues rock gypsy jazz\nblues rock hip-hop\nblues rock indie\nblues rock jazz\nblues rock jazz fusion\nblues rock jazz lounge\nblues rock jazz rock\nblues rock lo-fi hip-hop\nblues rock lounge\nblues rock lounge jazz\nblues rock noise rock\nblues rock outlaw country\nblues rock polka\nblues rock protest\nblues rock psychedelic\nblues rock psychedelic rock\nblues rock punk\nblues rock rap\nblues rock reggae\nblues rock rockabilly\nblues rock samba-rock\nblues rock ska\nblues rock soul\nblues rock southern rock\nblues rock surf rock\nblues rock thrash metal\nblues rock, Balkan folk\nblues rock, Bengali folk rock\nblues rock, French chanson, psychedelic rock\nblues rock, Italian folk\nblues rock, Latin rock\nblues rock, Latin rock, Afro-Cuban\nblues rock, MPB\nblues rock, americana, cabaret\nblues rock, big band swing, hip-hop\nblues rock, big band, Christmas\nblues rock, boogie-woogie\nblues rock, boogie-woogie, jump blues\nblues rock, country rock, honky-tonk\nblues rock, country, rockabilly\nblues rock, cumbia, Latin rock\nblues rock, gospel, rap\nblues rock, hard rock\nblues rock, hard rock, Chinese rock\nblues rock, hip-hop\nblues rock, kayōkyoku\nblues rock, noise rock\nblues rock, rockabilly\nblues rock, rockabilly, boogie-woogie\nblues rock, rockabilly, country\nblues rock, rockabilly, country-western\nblues rock, rockabilly, early rock and roll\nblues rock, rockabilly, jump blues\nblues rock, rockabilly, saxophone\nblues rock, rockabilly, surf rock\nblues rock, rockabilly, swing\nblues rock, rockabilly, vintage\nblues rock, southern rock\nblues rock, southern rock, R&B\nblues rock, southern rock, boogie-woogie\nblues rock, southern rock, funk rock\nblues rock, southern rock, gospel\nblues rock, southern rock, gospel rock\nblues rock, southern rock, guitar rock\nblues rock, southern rock, honky-tonk\nblues rock, southern rock, live rock\nblues rock, southern rock, rock\nblues rock, southern rock, rockabilly\nblues rockabilly\nblues sax\nblues saxophone\nblues show tune\nblues shuffle\nblues soul\nblues soul country\nblues soul downtempo\nblues soul gospel\nblues soul jazz\nblues soul jazz funk\nblues stride piano\nblues swing\nblues swing cabaret\nblues trap\nblues ukulele\nblues world music\nblues, Americana, country-western\nblues, Chinese opera, acoustic\nblues, Christmas novelty, jazz\nblues, Christmas, novelty\nblues, Italian folk\nblues, Japanese folk\nblues, Latin blues\nblues, Latin folk\nblues, MPB\nblues, MPB, live\nblues, Mandarin folk\nblues, New Orleans jazz\nblues, New Orleans jazz, Dixieland\nblues, R&B\nblues, R&B, big band\nblues, acoustic, Japanese folk\nblues, acoustic, Mandarin folk\nblues, ambient, folk\nblues, americana\nblues, americana, acoustic\nblues, americana, folk\nblues, americana, lounge jazz\nblues, americana, soul\nblues, americana, western swing\nblues, big band\nblues, big band jazz\nblues, big band, Christmas\nblues, big band, cinematic\nblues, big band, film noir\nblues, big band, free jazz\nblues, big band, jazz\nblues, big band, jump jive\nblues, big band, soul\nblues, big band, theatrical\nblues, boogie-woogie\nblues, boogie-woogie, New Orleans\nblues, boogie-woogie, cabaret\nblues, boogie-woogie, free jazz\nblues, boogie-woogie, gospel\nblues, boogie-woogie, jazz\nblues, boogie-woogie, show tune\nblues, boogie-woogie, soul\nblues, boogie-woogie, stride piano\nblues, boogie-woogie, theatrical\nblues, bossa nova, theatrical\nblues, chanson, acoustic\nblues, country, Americana\nblues, country, gospel\nblues, country, lo-fi\nblues, country, ragtime\nblues, country-blues\nblues, country-blues, honky-tonk\nblues, country-western, fingerstyle\nblues, early R&B, jazz\nblues, early jazz\nblues, electronic, soul\nblues, flamenco, jazz\nblues, folk\nblues, folk rock\nblues, folk, French vocal\nblues, folk, Italian folk\nblues, folk, Polish soul\nblues, folk, live performance\nblues, folk, vintage\nblues, folk-rock, Dutch levenslied\nblues, free jazz, soul\nblues, gospel, folk\nblues, gospel, rockabilly\nblues, gypsy jazz, Balkan folk\nblues, jazz, Italian ballad\nblues, jazz, Latin, hip hop\nblues, jazz, big band\nblues, jazz, lo-fi\nblues, jazz, show tune\nblues, jazz, theatrical\nblues, jazz, world music\nblues, jump blues\nblues, jump blues, big band\nblues, jump blues, rockabilly\nblues, lo-fi hip hop, world fusion\nblues, lounge jazz, Christmas\nblues, quirky, instrumental\nblues, ragtime, big band\nblues, ragtime, boogie-woogie\nblues, ragtime, lo-fi\nblues, ragtime, theatrical pop\nblues, rock and roll, novelty\nblues, rockabilly, doo-wop\nblues, roots, world fusion\nblues, salsa, cinematic\nblues, show tune, novelty\nblues, show tune, ragtime\nblues, soul, Brazilian\nblues, soul, Christmas\nblues, soul, R&B\nblues, soul, boogie-woogie\nblues, soul, choral\nblues, soul, jazz\nblues, soul, live performance\nblues, southern rock, Greek folk\nblues, theatrical\nblues, theatrical, acoustic\nblues, theatrical, boogie-woogie\nblues, theatrical, piano\nblues, torch song\nblues, western swing, vintage\nblues-country\nblues-folk\nblues-folk garage rock\nblues-folk hip-hop\nblues-folk novelty\nblues-folk, bluegrass\nblues-folk, hard rock\nblues-folk, lo-fi hip-hop, soul\nblues-folk, southern rock\nblues-funk\nblues-gospel\nblues-gothic\nblues-inflected country-rock\nblues-infused Americana\nblues-infused country rock\nblues-infused indie rock\nblues-jazz\nblues-jazz bossa nova\nblues-jazz cabaret\nblues-jazz lounge\nblues-jazz noir\nblues-jazz rock\nblues-jazz, big band, theatrical\nblues-jazz, bluegrass\nblues-noir\nblues-pop\nblues-rock\nblues-rock 90s alternative\nblues-rock Arabic\nblues-rock Arabic fusion\nblues-rock C-pop\nblues-rock Indian folk\nblues-rock Indian fusion\nblues-rock J-rock\nblues-rock Javanese pop-rock\nblues-rock Latin\nblues-rock MPB\nblues-rock Mandopop\nblues-rock R&B\nblues-rock alt-country\nblues-rock alt-rock\nblues-rock alternative\nblues-rock alternative rock\nblues-rock americana\nblues-rock ballad\nblues-rock boogie-woogie\nblues-rock bossa nova\nblues-rock cabaret\nblues-rock cabaret big band\nblues-rock cabaret boogie-woogie\nblues-rock cabaret chanson\nblues-rock cabaret free-jazz\nblues-rock cabaret gypsy-jazz\nblues-rock cabaret jazz\nblues-rock cabaret lounge\nblues-rock cabaret lounge-jazz\nblues-rock cabaret ragtime\nblues-rock cabaret swing\nblues-rock cabaret tango\nblues-rock chanson\nblues-rock children's\nblues-rock chiptune\nblues-rock city pop\nblues-rock city pop AOR\nblues-rock comedy\nblues-rock country\nblues-rock country MPB\nblues-rock country americana\nblues-rock country boogie-woogie\nblues-rock country folk\nblues-rock country gospel\nblues-rock country novelty\nblues-rock country outback\nblues-rock country pub-rock\nblues-rock country rockabilly\nblues-rock country russian chanson\nblues-rock country show tune\nblues-rock country southern rock\nblues-rock country swing\nblues-rock country-folk\nblues-rock country-rock\nblues-rock country-western\nblues-rock cumbia pop-rock\nblues-rock desert rock\nblues-rock drill\nblues-rock enka\nblues-rock flamenco\nblues-rock folk country-western\nblues-rock folk-rock\nblues-rock funk\nblues-rock funk Latin\nblues-rock funk boogie-woogie\nblues-rock funk city pop\nblues-rock funk country\nblues-rock funk jazz\nblues-rock funk jazz fusion\nblues-rock funk lounge\nblues-rock funk psychedelic\nblues-rock funk reggae\nblues-rock funk rock\nblues-rock funk rockabilly\nblues-rock funk soul\nblues-rock funk-metal\nblues-rock funk-pop\nblues-rock funk-reggae\nblues-rock funk-rock\nblues-rock fusion\nblues-rock garage punk\nblues-rock garage rock\nblues-rock garage rock psychedelic rock\nblues-rock gospel\nblues-rock gospel americana\nblues-rock gospel rock\nblues-rock gospel-rock\nblues-rock grunge\nblues-rock gypsy jazz\nblues-rock gypsy jazz cabaret\nblues-rock gypsy rock\nblues-rock hard rock\nblues-rock heartland rock\nblues-rock highlife\nblues-rock hip hop\nblues-rock hip-hop\nblues-rock hip-hop fusion\nblues-rock horror\nblues-rock indie\nblues-rock indie rock\nblues-rock indie-rock\nblues-rock jazz\nblues-rock jazz cabaret\nblues-rock jazz funk\nblues-rock jazz fusion\nblues-rock jazz lounge\nblues-rock jazz-fusion\nblues-rock klezmer fusion\nblues-rock latin\nblues-rock latin jazz\nblues-rock lo-fi\nblues-rock lounge\nblues-rock lounge-jazz\nblues-rock metal\nblues-rock metalcore\nblues-rock nederpop\nblues-rock neo-soul\nblues-rock noir\nblues-rock noir-jazz\nblues-rock outlaw country\nblues-rock pirate rock\nblues-rock pirate-rock\nblues-rock pop\nblues-rock pop-rock\nblues-rock post-punk\nblues-rock power ballad\nblues-rock protest\nblues-rock psychedelic\nblues-rock psychedelic rock\nblues-rock pub rock\nblues-rock pub-rock\nblues-rock punk\nblues-rock punk post-rock\nblues-rock punk rock\nblues-rock rap\nblues-rock rap-metal\nblues-rock rap-rock\nblues-rock reggae\nblues-rock reggae Latin\nblues-rock reggae-rock\nblues-rock reggaeton\nblues-rock rockabilly\nblues-rock rockabilly boogie-woogie\nblues-rock rockabilly country-rock\nblues-rock rockabilly surf rock\nblues-rock samba-rock\nblues-rock sertanejo\nblues-rock shoegaze\nblues-rock show tune\nblues-rock ska-punk\nblues-rock smooth jazz\nblues-rock soul\nblues-rock soul funk\nblues-rock soul jazz\nblues-rock southern rock\nblues-rock spaghetti western\nblues-rock surf rock\nblues-rock surf-rock\nblues-rock swing\nblues-rock tango\nblues-rock tango rock\nblues-rock tango theatrical\nblues-rock theatrical\nblues-rock trap\nblues-rock trip-hop\nblues-rock world music\nblues-rock worship\nblues-rock, Brazilian pop-rock\nblues-rock, Brazilian rock\nblues-rock, Chinese folk\nblues-rock, Chinese folk-rock\nblues-rock, Chinese fusion\nblues-rock, Christmas rock\nblues-rock, French chanson\nblues-rock, Hindi rock, cinematic rock\nblues-rock, Indian film music\nblues-rock, Indian folk, fusion\nblues-rock, Indonesian pop\nblues-rock, Italian rock, theatrical rock\nblues-rock, Italo-disco\nblues-rock, Kayōkyoku\nblues-rock, Korean folk, fusion\nblues-rock, Latin ballad\nblues-rock, Latin pop, ballad\nblues-rock, Latin pop-rock\nblues-rock, Latin rock\nblues-rock, Latin rock, classic rock\nblues-rock, Latin rock, cumbia rock\nblues-rock, Latin, tango\nblues-rock, Latin, theatrical\nblues-rock, Luk Thung\nblues-rock, MPB\nblues-rock, MPB, samba-rock\nblues-rock, Mandopop, pop-rock\nblues-rock, Mandopop, power ballad\nblues-rock, Middle Eastern fusion\nblues-rock, Persian pop, cinematic rock\nblues-rock, R&B\nblues-rock, R&B, Zouk\nblues-rock, Russian rock, quirky\nblues-rock, South Asian folk\nblues-rock, Southern rock, rock and roll\nblues-rock, Thai folk, funk rock\nblues-rock, Tibetan folk\nblues-rock, Turkish folk\nblues-rock, Turkish fusion\nblues-rock, Turkish rock, hard rock\nblues-rock, americana, swamp rock\nblues-rock, art-rock, rock\nblues-rock, art-rock, symphonic rock\nblues-rock, boogie-woogie, French chanson\nblues-rock, boogie-woogie, gospel\nblues-rock, boogie-woogie, gospel rock\nblues-rock, boogie-woogie, jump blues\nblues-rock, boogie-woogie, rock\nblues-rock, boogie-woogie, rock and roll\nblues-rock, boogie-woogie, theatrical\nblues-rock, brostep\nblues-rock, cabaret, gypsy-jazz\nblues-rock, cabaret, jazz\nblues-rock, cabaret, theatrical\nblues-rock, cabaret, western\nblues-rock, cinematic, pop-R&B\nblues-rock, cinematic, rock\nblues-rock, classic rock\nblues-rock, country, Americana\nblues-rock, country, Southern rock\nblues-rock, country, rockabilly\nblues-rock, country, southern rock\nblues-rock, dance-pop\nblues-rock, dangdut koplo\nblues-rock, disco-rock, K-rock\nblues-rock, dream pop\nblues-rock, electro-funk\nblues-rock, folk\nblues-rock, folk, cinematic\nblues-rock, folk-pop, Nepali\nblues-rock, free-jazz\nblues-rock, funk R&B\nblues-rock, funk rock\nblues-rock, funk-rock, hard rock\nblues-rock, gospel rock, atmospheric rock\nblues-rock, gospel rock, hip-hop\nblues-rock, gospel, MPB\nblues-rock, gospel, rap\nblues-rock, gospel, soul\nblues-rock, gospel-rock\nblues-rock, gospel-rock, indie rock\nblues-rock, gypsy punk, Balkan swing\nblues-rock, hard rock\nblues-rock, hard rock, Bossa Nova\nblues-rock, hard rock, C-pop\nblues-rock, hard rock, Chinese rock\nblues-rock, hard rock, cinematic rock\nblues-rock, hard rock, classic rock\nblues-rock, hard rock, experimental rock\nblues-rock, hard rock, folk rock\nblues-rock, hard rock, gospel\nblues-rock, hard rock, grunge\nblues-rock, hard rock, jazz fusion\nblues-rock, hard rock, nu-metal\nblues-rock, hard rock, punk rock\nblues-rock, hard rock, rap-rock\nblues-rock, hard rock, theatrical rock\nblues-rock, heavy metal\nblues-rock, heavy metal, jazz-fusion\nblues-rock, hip hop, C-pop\nblues-rock, hip hop, rock ballad\nblues-rock, hip-hop, jazz\nblues-rock, house, boogie-woogie\nblues-rock, indie rock\nblues-rock, jazz, cinematic\nblues-rock, melancholic rock\nblues-rock, metalcore, Balkan rock\nblues-rock, noise rock\nblues-rock, pop-rock\nblues-rock, pop-rock, C-pop\nblues-rock, pop-rock, Javanese\nblues-rock, pop-rock, Mandarin rock\nblues-rock, pop-rock, cinematic\nblues-rock, pop-rock, rap-rock\nblues-rock, pop-rock, synth\nblues-rock, power ballad, arena rock\nblues-rock, power ballad, gospel rock\nblues-rock, psychedelic rock\nblues-rock, psychedelic rock, hard rock\nblues-rock, psychedelic, Persian\nblues-rock, punk rock\nblues-rock, punk rock, southern rock\nblues-rock, rap, Turkish hip hop\nblues-rock, rap-rock, German rock\nblues-rock, rap-rock, cinematic\nblues-rock, rock ballad\nblues-rock, rock en español\nblues-rock, rock, Middle Eastern rock\nblues-rock, rockabilly, Christmas novelty\nblues-rock, rockabilly, country\nblues-rock, rockabilly, gospel\nblues-rock, rockabilly, soul\nblues-rock, rockabilly, swing\nblues-rock, rockabilly, theatrical\nblues-rock, shoegaze, noise rock\nblues-rock, show tune, Latin mambo\nblues-rock, southern rock\nblues-rock, southern rock, bar-band\nblues-rock, southern rock, boogie-rock\nblues-rock, southern rock, classic rock\nblues-rock, southern rock, funk\nblues-rock, southern rock, instrumental\nblues-rock, southern rock, live energy\nblues-rock, southern rock, rock\nblues-rock, southern rock, soulful\nblues-rock, surf-punk\nblues-rock, surf-rock\nblues-rock, tango, folk\nblues-rock, theatrical cabaret\nblues-rock, theatrical, gospel rock\nblues-rock, thrash metal\nblues-rock, western swing, big band\nblues-rock, world music, electronic\nblues-soul\nblues-soul funk\nblues-swing\nblues-trap\nbluesy Americana\nbluesy Arabic soul\nbluesy C-pop\nbluesy Christmas\nbluesy R&B\nbluesy acoustic\nbluesy acoustic ballad\nbluesy ballad\nbluesy big band\nbluesy bluegrass\nbluesy cinematic\nbluesy country\nbluesy country rock\nbluesy country-folk\nbluesy country-funk\nbluesy electronic\nbluesy folk\nbluesy folk-rock\nbluesy gospel\nbluesy hip-hop\nbluesy holiday\nbluesy indie rock\nbluesy jazz\nbluesy piano ballad\nbluesy pop\nbluesy pop-rock\nbluesy rock\nbluesy singer-songwriter\nbluesy soul\nbluesy swing\nbluesy whimsy\nbody percussion\nboeremusiek\nboeremusiek funk\nbolero\nbolero Latin jazz\nbolero MPB\nbolero V-Pop\nbolero ballad\nbolero big band\nbolero big band jazz\nbolero bossa nova\nbolero brega\nbolero cabaret\nbolero cha-cha-chá\nbolero chanson\nbolero chiptune\nbolero chiptune fusion\nbolero cinematic\nbolero copla\nbolero country\nbolero cumbia\nbolero cumbia cinematic\nbolero cumbia rock\nbolero cumbia villera\nbolero flamenco\nbolero funk-rock\nbolero gospel\nbolero jazz\nbolero jazz lounge\nbolero lo-fi\nbolero lounge\nbolero lounge jazz\nbolero mambo\nbolero mariachi\nbolero merengue\nbolero orchestral\nbolero psychedelic rock\nbolero ranchera\nbolero ranchera choral\nbolero ranchera, Latin folk, flamenco\nbolero reggaeton\nbolero rock\nbolero rockabilly\nbolero romántica\nbolero romántico\nbolero rumba\nbolero rumba flamenca\nbolero rumba flamenco\nbolero salsa\nbolero salsa orchestral\nbolero salsa-romántica\nbolero samba\nbolero samba orchestral\nbolero sertanejo\nbolero son\nbolero son cubano\nbolero son montuno\nbolero soul\nbolero tango\nbolero tango cinematic\nbolero tango classical\nbolero tango cumbia\nbolero tango flamenco\nbolero tango gospel\nbolero tango lo-fi\nbolero tango opera\nbolero tango orchestral\nbolero tango salsa\nbolero tango spiritual\nbolero vallenato\nbolero waltz\nbolero, 80s synth, cinematic\nbolero, Andean folk\nbolero, Andean, traditional\nbolero, Caribbean, jazz\nbolero, Latin American, sacred\nbolero, Latin ballad\nbolero, Latin ballad, cinematic\nbolero, Latin ballad, jazz lounge\nbolero, Latin ballad, romantic pop\nbolero, Latin ballad, vintage\nbolero, Latin big band\nbolero, Latin big band, passionate\nbolero, Latin big band, soulful\nbolero, Latin big band, theatrical\nbolero, Latin folk\nbolero, Latin folk, flamenco\nbolero, Latin folk, rumba\nbolero, Latin folk, tango\nbolero, Latin jazz\nbolero, Latin jazz, brass\nbolero, Latin jazz, classical tango\nbolero, Latin jazz, mambo\nbolero, Latin jazz, soul\nbolero, Latin jazz, theatrical\nbolero, Latin pop\nbolero, Latin pop, rock\nbolero, Latin rock\nbolero, Latin rock, synth rock\nbolero, Latin, cinematic\nbolero, Latin, cumbia\nbolero, Latin, dramatic\nbolero, Latin, flamenco\nbolero, Latin, male vocals\nbolero, Latin, operatic\nbolero, Latin, orchestral\nbolero, Latin, pop\nbolero, Latin, theatrical\nbolero, Latin, traditional\nbolero, Latin, vintage\nbolero, Latin, vocal\nbolero, MPB\nbolero, MPB, romantic\nbolero, Mandarin ballad, cinematic\nbolero, V-Pop\nbolero, V-Pop, 80s synth\nbolero, V-Pop, emotional\nbolero, V-Pop, retro\nbolero, V-Pop, synth\nbolero, V-Pop, synth-pop\nbolero, V-pop, sentimental\nbolero, V-pop, smooth jazz\nbolero, Vietnamese pop\nbolero, big band\nbolero, big band jazz\nbolero, big band, Latin\nbolero, big band, Latin jazz\nbolero, big band, Latin rock\nbolero, big band, cinematic\nbolero, big band, dramatic\nbolero, big band, jazz\nbolero, big band, latin jazz\nbolero, big band, orchestral\nbolero, big band, romantic\nbolero, big band, theatrical\nbolero, bossa nova, Latin ballad\nbolero, bossa nova, vintage ballad\nbolero, chanson, Latin ballad\nbolero, christmas, romantic\nbolero, cinematic, Christmas\nbolero, cinematic, Latin\nbolero, cinematic, Latin ballad\nbolero, cinematic, big band\nbolero, cinematic, classical\nbolero, cinematic, dramatic\nbolero, cinematic, flamenco\nbolero, cinematic, live performance\nbolero, cinematic, melancholic\nbolero, cinematic, opera\nbolero, cinematic, operatic\nbolero, cinematic, orchestral\nbolero, cinematic, power ballad\nbolero, cinematic, romantic\nbolero, classical, cinematic\nbolero, classical, operatic\nbolero, classical, orchestral\nbolero, classical, romantic\nbolero, copla, Latin ballad\nbolero, copla, cinematic\nbolero, country-western\nbolero, cumbia\nbolero, doo-wop, Latin ballad\nbolero, flamenco, cinematic\nbolero, flamenco, mambo\nbolero, folk ballad\nbolero, folk-pop, cinematic\nbolero, jazz, operatic\nbolero, latin jazz\nbolero, latin, cinematic\nbolero, library music, latin\nbolero, mambo\nbolero, mambo, Latin\nbolero, mambo, Latin ballad\nbolero, mambo, Latin jazz\nbolero, mambo, Latin orchestral\nbolero, mambo, Latin soul\nbolero, mambo, big band\nbolero, mambo, cha-cha-chá\nbolero, mambo, jazz\nbolero, mambo, latin jazz\nbolero, mambo, orchestral\nbolero, mambo, salsa\nbolero, mambo, tango\nbolero, mariachi, cinematic\nbolero, merengue\nbolero, opera, Latin orchestral\nbolero, opera, latin\nbolero, operatic, cinematic\nbolero, operatic, dramatic\nbolero, operatic, gothic\nbolero, operatic, jazz\nbolero, operatic, theatrical\nbolero, orchestral, Latin\nbolero, orchestral, Latin ballad\nbolero, orchestral, Latin jazz\nbolero, orchestral, Latin romantic\nbolero, orchestral, cinematic\nbolero, orchestral, dramatic\nbolero, orchestral, opera\nbolero, orchestral, operatic\nbolero, orchestral, rock\nbolero, orchestral, romantic\nbolero, orchestral, world music\nbolero, pop-rock\nbolero, rock\nbolero, romantic Latin pop\nbolero, romantic ballad, Latin\nbolero, romantic ballad, cinematic\nbolero, romantic latin pop, orchestral\nbolero, romantic, Christmas\nbolero, salsa\nbolero, salsa, Latin\nbolero, salsa, Latin jazz\nbolero, salsa, cinematic\nbolero, salsa, mambo\nbolero, salsa, operatic\nbolero, salsa, tango\nbolero, smooth jazz\nbolero, stadium rock\nbolero, tango, cabaret\nbolero, tango, cinematic\nbolero, tango, folk\nbolero, theatrical, cinematic\nbolero, theatrical, melancholic\nbolero, theatrical, opera\nbolero, theatrical, operatic\nbolero, trip-hop, cinematic\nbolero, vintage big-band\nbolero, vintage, big band\nbolero-jazz\nbolero-pop\nbolero-rock\nbolero-rumba\nbolero-salsa\nbolero-samba\nbomba\nbomba y boogaloo\nbomba y booguero\nbomba y plena\nbomba y salsa\nbombo legüero\nboogaloo\nboogie\nboogie MPB\nboogie funk\nboogie post-disco\nboogie rock\nboogie rock rockabilly\nboogie soul\nboogie synth-funk\nboogie, 80s, synth funk\nboogie, Brazilian, funk\nboogie, MPB, analog\nboogie, MPB, disco-funk\nboogie, MPB, funk\nboogie, South African pop, 80s funk\nboogie, post-disco, 80s\nboogie, post-disco, funk\nboogie, quiet storm, funk\nboogie, soul-funk, Brazilian\nboogie, synth-funk\nboogie, synth-funk, post-disco\nboogie-funk\nboogie-funk soul\nboogie-rock\nboogie-rock country-rock\nboogie-rock southern rock\nboogie-rock, Southern rock\nboogie-woogie\nboogie-woogie blues\nboogie-woogie blues rock\nboogie-woogie cabaret\nboogie-woogie children's\nboogie-woogie children's music\nboogie-woogie country\nboogie-woogie country rock\nboogie-woogie folk\nboogie-woogie funk\nboogie-woogie funk-rock\nboogie-woogie fusion\nboogie-woogie gospel\nboogie-woogie hip-hop\nboogie-woogie house\nboogie-woogie jazz\nboogie-woogie jive\nboogie-woogie jump blues\nboogie-woogie novelty\nboogie-woogie pop\nboogie-woogie pop-rock\nboogie-woogie punk\nboogie-woogie ragtime\nboogie-woogie rock\nboogie-woogie rock 'n' roll\nboogie-woogie rock and roll\nboogie-woogie rock show tune\nboogie-woogie rock, Latin mambo\nboogie-woogie rockabilly\nboogie-woogie rockabilly blues\nboogie-woogie rockabilly cabaret\nboogie-woogie rockabilly country rock\nboogie-woogie rockabilly western swing\nboogie-woogie samba\nboogie-woogie soul\nboogie-woogie soul-funk\nboogie-woogie soul-jazz\nboogie-woogie stride\nboogie-woogie swing\nboogie-woogie swing cabaret\nboogie-woogie swing jazz\nboogie-woogie, Christmas, jazz\nboogie-woogie, Christmas, novelty\nboogie-woogie, Italian pop-rock\nboogie-woogie, Latin jazz\nboogie-woogie, Latin jazz, cinematic\nboogie-woogie, Latin jazz, instrumental\nboogie-woogie, Latin jazz, ragtime\nboogie-woogie, Latin, comedy\nboogie-woogie, big band, circus jazz\nboogie-woogie, big band, jazz\nboogie-woogie, big band, rockabilly\nboogie-woogie, big band, show tune\nboogie-woogie, blues, country\nboogie-woogie, brass, rock and roll\nboogie-woogie, cabaret rock\nboogie-woogie, cabaret, Cantonese rock\nboogie-woogie, cabaret, MPB\nboogie-woogie, cabaret, klezmer\nboogie-woogie, children's music, big band\nboogie-woogie, chiptune, electro-swing\nboogie-woogie, chiptune, electronic\nboogie-woogie, early rock and roll, novelty\nboogie-woogie, folk, big band\nboogie-woogie, funk-rock, theatrical\nboogie-woogie, gospel, Christmas\nboogie-woogie, gospel, R&B\nboogie-woogie, gospel, live performance\nboogie-woogie, gospel, video game music\nboogie-woogie, gypsy jazz, swing\nboogie-woogie, honky-tonk, Christmas\nboogie-woogie, jazz, cabaret\nboogie-woogie, jump blues\nboogie-woogie, jump blues, blues-rock\nboogie-woogie, jump blues, jazz\nboogie-woogie, jump blues, novelty Christmas\nboogie-woogie, jump blues, rock and roll\nboogie-woogie, jump blues, rockabilly\nboogie-woogie, jump blues, swing\nboogie-woogie, jump blues, vintage rock and roll\nboogie-woogie, lo-fi, theatrical pop\nboogie-woogie, musette, swing\nboogie-woogie, novelty, satire\nboogie-woogie, novelty, swing\nboogie-woogie, novelty, theatrical\nboogie-woogie, playful, world music\nboogie-woogie, polka, comedy music\nboogie-woogie, psychedelic rock\nboogie-woogie, punk, comedy\nboogie-woogie, ragtime, children's music\nboogie-woogie, ragtime, stride piano\nboogie-woogie, retro, exotica\nboogie-woogie, rock and roll\nboogie-woogie, rock and roll, Christmas\nboogie-woogie, rock and roll, jazz\nboogie-woogie, rockabilly, Christmas novelty\nboogie-woogie, rockabilly, jump blues\nboogie-woogie, samba-rock\nboogie-woogie, show tune\nboogie-woogie, show tune, children's music\nboogie-woogie, show tune, novelty\nboogie-woogie, ska, big band\nboogie-woogie, soul rock, Latin rhythm\nboogie-woogie, soul, big band\nboogie-woogie, soul, hip-hop\nboogie-woogie, soul, jazz\nboogie-woogie, soul, live performance\nboogie-woogie, stride piano, blues\nboogie-woogie, stride piano, jazz\nboogie-woogie, stride piano, soul\nboogie-woogie, stride, Latin jazz\nboogie-woogie, surf rock\nboogie-woogie, surf-rock, instrumental\nboogie-woogie, swing jazz\nboogie-woogie, swing jazz, children's music\nboogie-woogie, swing jazz, novelty\nboogie-woogie, swing, Christmas\nboogie-woogie, swing, accordion\nboogie-woogie, swing, children's music\nboogie-woogie, swing, funk\nboogie-woogie, swing, jazz\nboogie-woogie, swing, novelty\nboogie-woogie, swing, retro jingle\nboogie-woogie, swing, rock and roll\nboogie-woogie, swing, theatrical rock\nboogie-woogie, synth funk, chiptune\nboogie-woogie, synth pop, video game music\nboogie-woogie, theatrical, novelty\nboogie-woogie, theatrical, quirky\nboogie-woogie, theatrical, rock\nboogie-woogie, theatrical, rock and roll\nboogie-woogie, theatrical, soul\nboom bap\nboom bap hip hop\nboom bap hip-hop\nboom bap hip-hop nu-metal\nboom bap reggae\nboom bap, Latin hip-hop\nboom bap, Mandarin hip hop\nboom bap, cinematic, French rap\nboom bap, cinematic, orchestral hip hop\nboom bap, hip hop\nboom bap, hip hop, Latin hip hop\nboom bap, lo-fi hip hop\nboom bap, lo-fi hip hop, Chinese hip hop\nboom bap, lo-fi hip hop, cloud rap\nboom bap, lo-fi hip hop, vaporwave\nboom-bap\nboom-bap Arabic hip hop\nboom-bap Christian hip-hop\nboom-bap R&B\nboom-bap chiptune\nboom-bap dembow\nboom-bap hip hop\nboom-bap hip hop, lo-fi hip hop\nboom-bap hip hop, trap\nboom-bap hip-hop\nboom-bap hip-hop C-pop\nboom-bap hip-hop European folk\nboom-bap hip-hop J-pop\nboom-bap hip-hop Punjabi\nboom-bap hip-hop alpine folk\nboom-bap hip-hop alternative rock\nboom-bap hip-hop chiptune\nboom-bap hip-hop country\nboom-bap hip-hop cumbia\nboom-bap hip-hop flamenco\nboom-bap hip-hop funk-rock\nboom-bap hip-hop gospel\nboom-bap hip-hop jazz\nboom-bap hip-hop jazz-hop\nboom-bap hip-hop jazz-rap\nboom-bap hip-hop neo-soul\nboom-bap hip-hop nu-metal\nboom-bap hip-hop polka\nboom-bap hip-hop reggae\nboom-bap hip-hop reggae dancehall\nboom-bap hip-hop reggaeton\nboom-bap hip-hop tango\nboom-bap hip-hop, Chinese opera\nboom-bap hip-hop, Chinese traditional\nboom-bap hip-hop, East Asian fusion\nboom-bap hip-hop, Eastern European folk, soul\nboom-bap hip-hop, G-funk\nboom-bap hip-hop, Latin jazz\nboom-bap hip-hop, Latin soul\nboom-bap hip-hop, Punjabi folk\nboom-bap hip-hop, R&B\nboom-bap hip-hop, South Asian fusion\nboom-bap hip-hop, alternative rock\nboom-bap hip-hop, ambient R&B\nboom-bap hip-hop, atmospheric trap\nboom-bap hip-hop, big band jazz\nboom-bap hip-hop, big band swing\nboom-bap hip-hop, bolero\nboom-bap hip-hop, cinematic, Arabic fusion\nboom-bap hip-hop, city pop\nboom-bap hip-hop, cloud rap\nboom-bap hip-hop, cloud rap, trap\nboom-bap hip-hop, cumbia\nboom-bap hip-hop, dubstep\nboom-bap hip-hop, funk-infused hip-hop\nboom-bap hip-hop, funk-rock\nboom-bap hip-hop, heavy metal\nboom-bap hip-hop, jazz rap\nboom-bap hip-hop, jazz-hop, psychedelic rock\nboom-bap hip-hop, lo-fi acoustic\nboom-bap hip-hop, lo-fi hip-hop\nboom-bap hip-hop, lo-fi hip-hop, ambient\nboom-bap hip-hop, lo-fi indie rock\nboom-bap hip-hop, lo-fi, Italian rap\nboom-bap hip-hop, neo-soul\nboom-bap hip-hop, neurofunk\nboom-bap hip-hop, pop-rock\nboom-bap hip-hop, psychedelic world music\nboom-bap hip-hop, raï\nboom-bap hip-hop, soul ballad\nboom-bap hip-hop, soulful R&B\nboom-bap hip-hop, synth-pop\nboom-bap hip-hop, trap\nboom-bap hip-hop, trap R&B\nboom-bap jazz hip-hop\nboom-bap jazz rap\nboom-bap jazz-rap\nboom-bap lo-fi\nboom-bap lo-fi hip hop\nboom-bap lo-fi hip-hop\nboom-bap rap\nboom-bap rap-rock\nboom-bap soul\nboom-bap trap\nboom-bap trip-hop\nboom-bap, 90s East Coast hip-hop\nboom-bap, 90s hip-hop, lo-fi\nboom-bap, Arabic hip hop\nboom-bap, Arabic hip hop, North African\nboom-bap, Arabic hip hop, cinematic\nboom-bap, Arabic hip hop, gritty\nboom-bap, Arabic hip hop, lo-fi\nboom-bap, Arabic hip hop, underground\nboom-bap, Arabic hip-hop, atmospheric\nboom-bap, Arabic hip-hop, cinematic\nboom-bap, Arabic hip-hop, lo-fi\nboom-bap, Arabic hip-hop, melancholic\nboom-bap, Brazilian hip hop\nboom-bap, C-pop, lo-fi hip hop\nboom-bap, Caribbean hip hop\nboom-bap, Chinese hip hop\nboom-bap, Chinese hip hop, dark ambient\nboom-bap, Chinese hip hop, dark trap\nboom-bap, Chinese hip hop, diss track\nboom-bap, Chinese hip hop, lo-fi\nboom-bap, Chinese hip hop, underground\nboom-bap, Chinese hip-hop\nboom-bap, Chinese hip-hop, introspective\nboom-bap, Chinese hip-hop, lo-fi\nboom-bap, Chinese hip-hop, raw hip-hop\nboom-bap, Chinese hip-hop, underground rap\nboom-bap, Chinese martial arts, underground hip hop\nboom-bap, Chinese spiritual, mystical hip-hop\nboom-bap, Chinese traditional\nboom-bap, Christian hip-hop, East Coast hip-hop\nboom-bap, Christian hip-hop, Spanish rap\nboom-bap, Christian hip-hop, soulful\nboom-bap, Czech hip-hop, underground rap\nboom-bap, Deutschrap, cinematic hip hop\nboom-bap, East Coast hip-hop\nboom-bap, East Coast hip-hop, lo-fi\nboom-bap, East Coast hip-hop, sample-based\nboom-bap, French hip hop, East Coast\nboom-bap, French hip-hop\nboom-bap, French hip-hop, conscious rap\nboom-bap, French hip-hop, dark trap\nboom-bap, French hip-hop, lo-fi\nboom-bap, French hip-hop, underground\nboom-bap, French hip-hop, world music\nboom-bap, French rap, cinematic\nboom-bap, French rap, dark ambient\nboom-bap, French rap, introspective\nboom-bap, French rap, video game\nboom-bap, G-funk\nboom-bap, G-funk, West Coast hip-hop\nboom-bap, G-funk, instrumental hip-hop\nboom-bap, G-funk, neo-soul\nboom-bap, G-funk, soulful hip-hop\nboom-bap, German hip hop, Balkan fusion\nboom-bap, German hip hop, Middle Eastern fusion\nboom-bap, German hip hop, lo-fi\nboom-bap, German hip hop, street rap\nboom-bap, German hip hop, synth funk\nboom-bap, German hip-hop\nboom-bap, German hip-hop, chiptune\nboom-bap, German hip-hop, cinematic\nboom-bap, German hip-hop, lo-fi\nboom-bap, German street rap, lo-fi hip hop\nboom-bap, Italian hip hop\nboom-bap, Italian hip hop, cinematic\nboom-bap, Italian hip-hop\nboom-bap, Italian hip-hop, lo-fi\nboom-bap, Italian rap, dark ambient\nboom-bap, Italian rap, lo-fi\nboom-bap, Italian rap, lo-fi hip hop\nboom-bap, Japanese hip-hop\nboom-bap, Latin folk\nboom-bap, Latin hip hop\nboom-bap, Latin hip hop, introspective\nboom-bap, Latin hip hop, mambo\nboom-bap, Latin hip hop, street rap\nboom-bap, Latin hip-hop\nboom-bap, Latin jazz, funk\nboom-bap, Mandarin rap, jazzy hip hop\nboom-bap, Mexican regional rap\nboom-bap, Middle Eastern hip hop\nboom-bap, Middle Eastern hip-hop\nboom-bap, Middle Eastern, cinematic\nboom-bap, Persian rap\nboom-bap, Romanian rap, aggressive hip hop\nboom-bap, Russian hip hop\nboom-bap, Russian hip-hop\nboom-bap, Russian hip-hop, cinematic\nboom-bap, Russian rap, cinematic\nboom-bap, Spanish hip hop\nboom-bap, Spanish hip hop, lo-fi\nboom-bap, Spanish hip-hop, cinematic\nboom-bap, Spanish hip-hop, folk\nboom-bap, Spanish hip-hop, lo-fi\nboom-bap, Spanish rap\nboom-bap, Spanish rap, aggressive\nboom-bap, Spanish rap, turntablism\nboom-bap, Spanish rap, underground hip hop\nboom-bap, Spanish-style, introspective\nboom-bap, Spanish-style, lo-fi hip hop\nboom-bap, Turkish hip hop, cinematic\nboom-bap, Turkish hip hop, turntablism\nboom-bap, Turkish hip-hop\nboom-bap, Turkish hip-hop, atmospheric\nboom-bap, Turkish hip-hop, jazzy\nboom-bap, Turkish hip-hop, lo-fi\nboom-bap, Turkish rap, dark hip hop\nboom-bap, acid jazz, hip-hop\nboom-bap, acid jazz, instrumental hip-hop\nboom-bap, acid jazz, sample-based hip-hop\nboom-bap, ambient, German hip hop\nboom-bap, apocalyptic, orchestral hip hop\nboom-bap, atmospheric hip hop\nboom-bap, baroque, hip hop\nboom-bap, battle rap, Spanish hip hop\nboom-bap, battle rap, lo-fi hip hop\nboom-bap, chiptune\nboom-bap, chiptune, Mandarin rap\nboom-bap, chiptune, hip hop\nboom-bap, chiptune, hip-hop\nboom-bap, chiptune, lo-fi hip hop\nboom-bap, chopped and screwed\nboom-bap, cinematic hip hop\nboom-bap, cinematic hip hop, Arabic rap\nboom-bap, cinematic hip hop, Chinese rap\nboom-bap, cinematic hip hop, Dutch rap\nboom-bap, cinematic hip hop, Russian rap\nboom-bap, cinematic hip hop, analog\nboom-bap, cinematic hip hop, lo-fi\nboom-bap, cinematic hip-hop\nboom-bap, cinematic hip-hop, Chinese film score\nboom-bap, cinematic hip-hop, Chinese rap\nboom-bap, cinematic hip-hop, East Coast\nboom-bap, cinematic hip-hop, French rap\nboom-bap, cinematic hip-hop, German rap\nboom-bap, cinematic hip-hop, Spanish rap\nboom-bap, cinematic hip-hop, dark trap\nboom-bap, cinematic hip-hop, superhero\nboom-bap, cinematic rap\nboom-bap, cinematic, Arabic hip hop\nboom-bap, cinematic, Chinese hip hop\nboom-bap, cinematic, Chinese hip-hop\nboom-bap, cinematic, East African hip-hop\nboom-bap, cinematic, Eastern European\nboom-bap, cinematic, French Creole rap\nboom-bap, cinematic, French rap\nboom-bap, cinematic, German hip hop\nboom-bap, cinematic, Italian hip hop\nboom-bap, cinematic, Italian hip-hop\nboom-bap, cinematic, Moroccan hip-hop\nboom-bap, cinematic, Portuguese hip hop\nboom-bap, cinematic, Spanish hip hop\nboom-bap, cinematic, Spanish hip-hop\nboom-bap, cinematic, Western\nboom-bap, cinematic, dark hip hop\nboom-bap, cinematic, dystopian\nboom-bap, cinematic, hip hop\nboom-bap, cinematic, hip-hop\nboom-bap, cinematic, lo-fi\nboom-bap, cinematic, lo-fi hip hop\nboom-bap, cinematic, noir\nboom-bap, cinematic, orchestral\nboom-bap, cinematic, political hip hop\nboom-bap, cinematic, sample-based\nboom-bap, cinematic, soulful\nboom-bap, cinematic, trap\nboom-bap, cinematic, underground\nboom-bap, cinematic, underground hip hop\nboom-bap, city-pop, vaporwave\nboom-bap, classical hip hop\nboom-bap, classical, German hip hop\nboom-bap, classical, hip hop\nboom-bap, classical, introspective\nboom-bap, cloud rap\nboom-bap, cloud rap, hip-hop\nboom-bap, comedic hip hop\nboom-bap, conscious hip hop, lo-fi\nboom-bap, conscious hip hop, underground rap\nboom-bap, conscious hip-hop\nboom-bap, conscious hip-hop, Brazilian hip-hop\nboom-bap, conscious hip-hop, Latin folk\nboom-bap, cyberpunk hip-hop\nboom-bap, cyberpunk, lo-fi hip hop\nboom-bap, dark hip hop\nboom-bap, dark hip hop, Middle Eastern hip hop\nboom-bap, dark hip hop, Spanish rap\nboom-bap, dark hip hop, cinematic\nboom-bap, dark hip hop, ritualistic\nboom-bap, dark hip-hop\nboom-bap, dark hip-hop, French rap\nboom-bap, dark hip-hop, Turkish rap\nboom-bap, dark hip-hop, cinematic\nboom-bap, dark hip-hop, noir\nboom-bap, east coast hip-hop\nboom-bap, funk rap, lo-fi hip hop\nboom-bap, gangsta rap\nboom-bap, gangsta rap, lo-fi hip hop\nboom-bap, gangster rap\nboom-bap, gangster rap, cinematic hip-hop\nboom-bap, gothic hip hop\nboom-bap, grime\nboom-bap, hardcore hip-hop\nboom-bap, hardcore hip-hop, East Coast\nboom-bap, hip hop\nboom-bap, hip hop, 90s East Coast\nboom-bap, hip hop, Arabic rap\nboom-bap, hip hop, Bengali rap\nboom-bap, hip hop, Cantonese rap\nboom-bap, hip hop, Chinese\nboom-bap, hip hop, Chinese flavor\nboom-bap, hip hop, Chinese hip hop\nboom-bap, hip hop, Chinese rap\nboom-bap, hip hop, Chinese traditional\nboom-bap, hip hop, Chinese underground\nboom-bap, hip hop, Cuban hip hop\nboom-bap, hip hop, Dutch rap\nboom-bap, hip hop, German rap\nboom-bap, hip hop, Italian\nboom-bap, hip hop, Italian rap\nboom-bap, hip hop, Latin\nboom-bap, hip hop, Latin rap\nboom-bap, hip hop, Mandarin rap\nboom-bap, hip hop, Middle Eastern\nboom-bap, hip hop, Mongolian rap\nboom-bap, hip hop, Moroccan Arabic rap\nboom-bap, hip hop, Persian rap\nboom-bap, hip hop, Russian rap\nboom-bap, hip hop, Spanish rap\nboom-bap, hip hop, Turkish hip hop\nboom-bap, hip hop, Wolof rap\nboom-bap, hip hop, aggressive\nboom-bap, hip hop, cartoon style\nboom-bap, hip hop, chiptune\nboom-bap, hip hop, cinematic\nboom-bap, hip hop, comedic\nboom-bap, hip hop, dark\nboom-bap, hip hop, dark ambient\nboom-bap, hip hop, dark rap\nboom-bap, hip hop, dark trap\nboom-bap, hip hop, diss track\nboom-bap, hip hop, experimental\nboom-bap, hip hop, jazzy\nboom-bap, hip hop, klezmer\nboom-bap, hip hop, lo-fi\nboom-bap, hip hop, multilingual\nboom-bap, hip hop, noir\nboom-bap, hip hop, orchestral hip hop\nboom-bap, hip hop, political rap\nboom-bap, hip hop, posse cut\nboom-bap, hip hop, protest\nboom-bap, hip hop, psychedelic\nboom-bap, hip hop, rock\nboom-bap, hip hop, trap\nboom-bap, hip hop, underground\nboom-bap, hip hop, underground rap\nboom-bap, hip-hop\nboom-bap, hip-hop, 90s East Coast\nboom-bap, hip-hop, Arabic hip-hop\nboom-bap, hip-hop, Arabic rap\nboom-bap, hip-hop, Balkan hip-hop\nboom-bap, hip-hop, Chinese\nboom-bap, hip-hop, Chinese fusion\nboom-bap, hip-hop, Chinese hip-hop\nboom-bap, hip-hop, Chinese rap\nboom-bap, hip-hop, East Asian\nboom-bap, hip-hop, East Asian fusion\nboom-bap, hip-hop, East Coast\nboom-bap, hip-hop, Eastern fusion\nboom-bap, hip-hop, Eastern-influenced\nboom-bap, hip-hop, French rap\nboom-bap, hip-hop, G-funk\nboom-bap, hip-hop, German rap\nboom-bap, hip-hop, Haitian Creole\nboom-bap, hip-hop, Indian hip-hop\nboom-bap, hip-hop, Latin\nboom-bap, hip-hop, Latin hip-hop\nboom-bap, hip-hop, Latin rap\nboom-bap, hip-hop, Malay rap\nboom-bap, hip-hop, Mandarin rap\nboom-bap, hip-hop, Middle Eastern\nboom-bap, hip-hop, Persian rap\nboom-bap, hip-hop, Portuguese\nboom-bap, hip-hop, Portuguese hip-hop\nboom-bap, hip-hop, Punjabi rap\nboom-bap, hip-hop, Russian\nboom-bap, hip-hop, Russian rap\nboom-bap, hip-hop, Spanish acoustic\nboom-bap, hip-hop, Spanish hip-hop\nboom-bap, hip-hop, Spanish rap\nboom-bap, hip-hop, Turkish fusion\nboom-bap, hip-hop, Turkish hip-hop\nboom-bap, hip-hop, aggressive\nboom-bap, hip-hop, atmospheric\nboom-bap, hip-hop, chiptune\nboom-bap, hip-hop, cinematic\nboom-bap, hip-hop, classical\nboom-bap, hip-hop, cumbia\nboom-bap, hip-hop, dancehall\nboom-bap, hip-hop, dark\nboom-bap, hip-hop, drum and bass\nboom-bap, hip-hop, emotional\nboom-bap, hip-hop, experimental\nboom-bap, hip-hop, folk\nboom-bap, hip-hop, funk\nboom-bap, hip-hop, industrial\nboom-bap, hip-hop, introspective\nboom-bap, hip-hop, jazz rap\nboom-bap, hip-hop, jazzy\nboom-bap, hip-hop, lo-fi\nboom-bap, hip-hop, melancholic\nboom-bap, hip-hop, multilingual\nboom-bap, hip-hop, nu-metal\nboom-bap, hip-hop, old-school\nboom-bap, hip-hop, orchestral\nboom-bap, hip-hop, philosophical\nboom-bap, hip-hop, protest rap\nboom-bap, hip-hop, raw\nboom-bap, hip-hop, regional Mexican\nboom-bap, hip-hop, underground\nboom-bap, horrorcore\nboom-bap, horrorcore, experimental\nboom-bap, horrorcore, lo-fi hip hop\nboom-bap, instrumental hip-hop, Turkish fusion\nboom-bap, introspective hip-hop\nboom-bap, jazz hip hop\nboom-bap, jazz rap\nboom-bap, jazz rap, Chinese hip hop\nboom-bap, jazz rap, German hip hop\nboom-bap, jazz rap, Korean hip hop\nboom-bap, jazz rap, Latin hip-hop\nboom-bap, jazz rap, Spanish hip hop\nboom-bap, jazz rap, cinematic\nboom-bap, jazz rap, hip hop\nboom-bap, jazz rap, lo-fi\nboom-bap, jazz rap, lo-fi hip hop\nboom-bap, jazz rap, noir\nboom-bap, jazz-hop, East Asian hip-hop\nboom-bap, jazz-hop, lo-fi hip hop\nboom-bap, jazzy hip hop, R&B\nboom-bap, jazzy hip hop, romantic\nboom-bap, jazzy hip-hop, Mandarin rap\nboom-bap, jazzy, lo-fi hip hop\nboom-bap, lo-fi hip hop\nboom-bap, lo-fi hip hop, 90s East Coast\nboom-bap, lo-fi hip hop, Arabic fusion\nboom-bap, lo-fi hip hop, Arabic rap\nboom-bap, lo-fi hip hop, Azerbaijani rap\nboom-bap, lo-fi hip hop, Brazilian rap\nboom-bap, lo-fi hip hop, British rap\nboom-bap, lo-fi hip hop, C-pop\nboom-bap, lo-fi hip hop, Cantopop\nboom-bap, lo-fi hip hop, Chinese R&B\nboom-bap, lo-fi hip hop, Chinese ambient\nboom-bap, lo-fi hip hop, Chinese hip hop\nboom-bap, lo-fi hip hop, Chinese hip-hop\nboom-bap, lo-fi hip hop, Chinese narrative\nboom-bap, lo-fi hip hop, Chinese narrative rap\nboom-bap, lo-fi hip hop, Chinese rap\nboom-bap, lo-fi hip hop, Chinese storytelling\nboom-bap, lo-fi hip hop, Chinese underground\nboom-bap, lo-fi hip hop, Dutch rap\nboom-bap, lo-fi hip hop, East Coast hip hop\nboom-bap, lo-fi hip hop, East Coast hip-hop\nboom-bap, lo-fi hip hop, East Coast rap\nboom-bap, lo-fi hip hop, Eastern fusion\nboom-bap, lo-fi hip hop, French hip-hop\nboom-bap, lo-fi hip hop, French rap\nboom-bap, lo-fi hip hop, German rap\nboom-bap, lo-fi hip hop, Greek rap\nboom-bap, lo-fi hip hop, Italian rap\nboom-bap, lo-fi hip hop, Japanese rap\nboom-bap, lo-fi hip hop, Korean rap\nboom-bap, lo-fi hip hop, Latin rap\nboom-bap, lo-fi hip hop, Mandarin rap\nboom-bap, lo-fi hip hop, Middle Eastern\nboom-bap, lo-fi hip hop, Moroccan hip hop\nboom-bap, lo-fi hip hop, Moroccan rap\nboom-bap, lo-fi hip hop, Nigerian Pidgin rap\nboom-bap, lo-fi hip hop, Nigerian rap\nboom-bap, lo-fi hip hop, Persian rap\nboom-bap, lo-fi hip hop, Polish rap\nboom-bap, lo-fi hip hop, Portuguese rap\nboom-bap, lo-fi hip hop, Romanian hip hop\nboom-bap, lo-fi hip hop, Romanian rap\nboom-bap, lo-fi hip hop, Russian hip hop\nboom-bap, lo-fi hip hop, Russian hip-hop\nboom-bap, lo-fi hip hop, Russian rap\nboom-bap, lo-fi hip hop, Spanish hip hop\nboom-bap, lo-fi hip hop, Spanish rap\nboom-bap, lo-fi hip hop, Swahili rap\nboom-bap, lo-fi hip hop, Turkish hip hop\nboom-bap, lo-fi hip hop, Turkish rap\nboom-bap, lo-fi hip hop, UK rap\nboom-bap, lo-fi hip hop, ambient\nboom-bap, lo-fi hip hop, bilingual hip hop\nboom-bap, lo-fi hip hop, bilingual rap\nboom-bap, lo-fi hip hop, chiptune\nboom-bap, lo-fi hip hop, cinematic\nboom-bap, lo-fi hip hop, cinematic hip hop\nboom-bap, lo-fi hip hop, conscious hip-hop\nboom-bap, lo-fi hip hop, conscious rap\nboom-bap, lo-fi hip hop, crime rap\nboom-bap, lo-fi hip hop, dark ambient\nboom-bap, lo-fi hip hop, dark rap\nboom-bap, lo-fi hip hop, dystopian\nboom-bap, lo-fi hip hop, electronic\nboom-bap, lo-fi hip hop, experimental\nboom-bap, lo-fi hip hop, gangster rap\nboom-bap, lo-fi hip hop, horrorcore\nboom-bap, lo-fi hip hop, introspective\nboom-bap, lo-fi hip hop, introspective rap\nboom-bap, lo-fi hip hop, jazz rap\nboom-bap, lo-fi hip hop, jazz-hop\nboom-bap, lo-fi hip hop, neo-soul\nboom-bap, lo-fi hip hop, political rap\nboom-bap, lo-fi hip hop, psychedelic\nboom-bap, lo-fi hip hop, psychedelic hip hop\nboom-bap, lo-fi hip hop, sample-based\nboom-bap, lo-fi hip hop, soul\nboom-bap, lo-fi hip hop, soulful rap\nboom-bap, lo-fi hip hop, trap\nboom-bap, lo-fi hip hop, trip-hop\nboom-bap, lo-fi hip hop, underground\nboom-bap, lo-fi hip hop, underground hip hop\nboom-bap, lo-fi hip hop, underground rap\nboom-bap, lo-fi hip hop, vaporwave\nboom-bap, lo-fi hip-hop\nboom-bap, lo-fi hip-hop, jazz rap\nboom-bap, lo-fi, Mandarin rap\nboom-bap, lo-fi, jazz rap\nboom-bap, melancholic hip hop\nboom-bap, melancholic, hip-hop\nboom-bap, melancholic, lo-fi hip hop\nboom-bap, microtonal, gang vocal\nboom-bap, militant hip hop, Latin rap\nboom-bap, neo-soul, hip-hop\nboom-bap, neo-soul, jazz rap\nboom-bap, neo-soul, jazz-rap\nboom-bap, nu-metal, world music\nboom-bap, orchestral, hip-hop\nboom-bap, political hip hop\nboom-bap, political hip hop, Azerbaijani rap\nboom-bap, political hip hop, underground rap\nboom-bap, political hip-hop\nboom-bap, political hip-hop, choral\nboom-bap, political hip-hop, cinematic\nboom-bap, psychedelic hip hop\nboom-bap, psychedelic hip-hop\nboom-bap, punk rap, garage rock\nboom-bap, ragtime, hip hop\nboom-bap, ragtime, hip-hop\nboom-bap, rap, Russian hip hop\nboom-bap, rap, cinematic\nboom-bap, rap-metal, nu-metal\nboom-bap, rap-rock\nboom-bap, ritualistic hip hop, lo-fi\nboom-bap, sci-fi, hip hop\nboom-bap, soul, Chinese hip hop\nboom-bap, soul, Latin hip hop\nboom-bap, soul, Mandarin hip hop\nboom-bap, soul, Sundanese\nboom-bap, soul, hip hop\nboom-bap, soul, hip-hop\nboom-bap, soul, jazz-hop\nboom-bap, soulful R&B, German rap\nboom-bap, soulful hip hop\nboom-bap, soulful hip-hop\nboom-bap, soulful hip-hop, sample-based\nboom-bap, spoken word hip hop\nboom-bap, stoner rap, East Coast hip hop\nboom-bap, tango, Spanish hip hop\nboom-bap, trap\nboom-bap, trap, Arabic hip-hop\nboom-bap, trap, French hip-hop\nboom-bap, trap, Latin hip hop\nboom-bap, trap, chiptune\nboom-bap, trap, cinematic hip-hop\nboom-bap, trap, dubstep\nboom-bap, trap, electronic\nboom-bap, trap, introspective hip-hop\nboom-bap, trap, lo-fi hip hop\nboom-bap, trap, soul\nboom-bap, trap, soulful hip hop\nboom-bap, trip-hop\nboom-bap, trip-hop, cinematic hip hop\nboom-bap, trip-hop, instrumental hip-hop\nboom-bap, trip-hop, lo-fi hip hop\nboom-bap, trip-hop, sample-based hip-hop\nboom-bap, underground hip hop\nboom-bap, underground hip hop, cinematic\nboom-bap, underground hip hop, cinematic rap\nboom-bap, underground hip hop, lo-fi\nboom-bap, underground hip hop, soulful rap\nboom-bap, underground hip-hop\nboom-bap, underground hip-hop, cinematic\nboom-bap, underground hip-hop, dark ambient\nboom-bap, underground hip-hop, lo-fi\nboom-bap, vaporwave, German hip hop\nboom-bap, vaporwave, Latin hip hop\nboom-bap, vaporwave, hip hop\nboom-bap, vaporwave, lo-fi hip hop\nboom-bap, world music, lo-fi hip hop\nboom-bap, world music, sample-based\nboom-bap, wuxia, hip hop\nboombap\nboombap hip hop\nboombap hip-hop\nbossa nova\nbossa nova French pop\nbossa nova J-pop\nbossa nova K-pop\nbossa nova MPB\nbossa nova Mandopop\nbossa nova R&B\nbossa nova acoustic pop\nbossa nova adult contemporary\nbossa nova alternative rock\nbossa nova arabic pop\nbossa nova ballad\nbossa nova breakcore\nbossa nova cabaret\nbossa nova chanson\nbossa nova chillwave\nbossa nova chiptune\nbossa nova cinematic\nbossa nova city pop\nbossa nova city-pop\nbossa nova cool jazz\nbossa nova disco\nbossa nova doo-wop\nbossa nova dream pop\nbossa nova dream-pop\nbossa nova exotica\nbossa nova exotica lounge\nbossa nova flamenco\nbossa nova folk\nbossa nova funk\nbossa nova funk acid jazz\nbossa nova funk carioca\nbossa nova funk electronic lounge\nbossa nova funk indie pop\nbossa nova funk jazz-fusion\nbossa nova funk lounge jazz\nbossa nova funk rock\nbossa nova funk soul\nbossa nova funk-pop\nbossa nova funk-rock\nbossa nova funk-rock breakcore\nbossa nova hip hop\nbossa nova hip-hop\nbossa nova indie folk\nbossa nova indie pop\nbossa nova indie pop lo-fi hip-hop\nbossa nova indie rock\nbossa nova indie-pop\nbossa nova j-pop\nbossa nova jazz\nbossa nova jazz pop\nbossa nova jazz-funk\nbossa nova jazz-pop\nbossa nova lo-fi\nbossa nova lo-fi hip hop\nbossa nova lo-fi hip-hop\nbossa nova lo-fi pop\nbossa nova lo-fi trip-hop\nbossa nova lounge\nbossa nova lounge jazz\nbossa nova lounge jazz video game\nbossa nova lounge pop\nbossa nova lounge psychedelic pop\nbossa nova lounge-pop\nbossa nova mandopop\nbossa nova neo-soul\nbossa nova noir jazz\nbossa nova nu-disco house\nbossa nova orchestral\nbossa nova pop\nbossa nova pop-punk\nbossa nova pop-rock\nbossa nova punk rock\nbossa nova rap\nbossa nova reggae\nbossa nova reggaeton\nbossa nova rock\nbossa nova rock fusion\nbossa nova samba\nbossa nova samba rock\nbossa nova samba-pop\nbossa nova samba-reggae\nbossa nova samba-rock\nbossa nova shoegaze\nbossa nova ska-punk\nbossa nova smooth jazz\nbossa nova soft rock\nbossa nova soul\nbossa nova soul-jazz\nbossa nova synth-pop\nbossa nova tango\nbossa nova tango cumbia\nbossa nova tango folk\nbossa nova tech house\nbossa nova trip-hop\nbossa nova trip-hop indie pop\nbossa nova, Brazilian funk, carioca\nbossa nova, C-pop, ambient\nbossa nova, C-pop, lo-fi\nbossa nova, C-pop, soul\nbossa nova, French chanson\nbossa nova, French chanson, Brazilian pop\nbossa nova, French pop\nbossa nova, Hawaiian Christmas\nbossa nova, Indian classical\nbossa nova, Indian classical, jazz fusion\nbossa nova, Indonesian pop\nbossa nova, J-rock, art-pop\nbossa nova, K-pop, J-pop\nbossa nova, Latin jazz\nbossa nova, Latin pop\nbossa nova, Latin rock\nbossa nova, Latin, lounge\nbossa nova, MPB, ambient\nbossa nova, R&B, hip-hop\nbossa nova, Thai exotica\nbossa nova, Turkish pop\nbossa nova, alt-rock, Brazilian pop\nbossa nova, ambient, C-pop\nbossa nova, baile funk\nbossa nova, ballad, jazz\nbossa nova, big band jazz\nbossa nova, big band, cinematic\nbossa nova, big band, free jazz\nbossa nova, blues, ska-punk\nbossa nova, breakbeat, classical fusion\nbossa nova, breakcore, funk rock\nbossa nova, chiptune, video game music\nbossa nova, cinematic, ambient\nbossa nova, cinematic, dark ambient\nbossa nova, cinematic, melancholic\nbossa nova, city pop\nbossa nova, dream pop, industrial rock\nbossa nova, drum and bass, jazz fusion\nbossa nova, electronic, Brazilian pop\nbossa nova, flamenco, art pop\nbossa nova, funk carioca, R&B\nbossa nova, heavy metal\nbossa nova, indie pop\nbossa nova, indie pop, bedroom pop\nbossa nova, indie rock\nbossa nova, indie rock, Mandarin pop\nbossa nova, jazz, Christmas\nbossa nova, jazz, Indian fusion\nbossa nova, jazzy pop-rock, rock\nbossa nova, latin jazz\nbossa nova, latin pop, reggaeton\nbossa nova, light jazz\nbossa nova, lo-fi hip hop, R&B\nbossa nova, lo-fi hip hop, ambient pop\nbossa nova, lounge pop\nbossa nova, lounge, ambient\nbossa nova, neo-soul, funk\nbossa nova, noise rock\nbossa nova, pop, bilingual\nbossa nova, pop, lo-fi\nbossa nova, pop-punk\nbossa nova, pop-rock\nbossa nova, psychedelic funk\nbossa nova, psychedelic funk, rock\nbossa nova, psychedelic pop\nbossa nova, psychedelic rock\nbossa nova, psychedelic rock, funk\nbossa nova, psychedelic rock, indie rock\nbossa nova, psychedelic rock, jazz fusion\nbossa nova, punk rock, free jazz\nbossa nova, reggae, ambient\nbossa nova, retro video game\nbossa nova, samba rock\nbossa nova, samba, C-pop\nbossa nova, samba-reggae, dream pop\nbossa nova, soul, indie folk\nbossa nova, techno, trance\nbossa nova, theatrical, vocal jazz\nbossa nova, trap R&B\nbossa nova, video game music\nbossa nova, video game soundtrack, lo-fi\nbossa nova-pop\nbounce\nbounce music\nbouncy house\nboy band\nboy band pop\nbrass\nbrass band\nbrass band ballad\nbrass band folk\nbrass band hymn\nbrass band jazz hip-hop\nbrass band march\nbrass band polka\nbrass band pop\nbrass band punk rock\nbrass band rock\nbrass band, Latin American folk\nbrass band, Latin American folk, regional Mexican\nbrass band, Latin ballad\nbrass band, Latin, New Orleans\nbrass band, chiptune\nbrass band, cumbia, Latin American\nbrass band, festive, Indonesian traditional\nbrass band, polka, regional Mexican\nbrass band, polka, rock\nbrass band, regional Mexican\nbrass band, regional Mexican, energetic\nbrass band, regional Mexican, festive\nbrass band, regional Mexican, live performance\nbrass band, samba, polka\nbrass band, ska, rockabilly\nbrass band, traditional Mexican, triumphant\nbrass band, traditional Spanish, Christmas\nbrass ensemble\nbrass etude\nbrass fanfare\nbrass folk\nbrass funk\nbrass polka\nbrass pop\nbrass punk\nbrass rock\nbrass solo\nbrass-hop\nbrass-pop\nbrass-punk\nbreakbeat\nbreakbeat 90s\nbreakbeat Bollywood\nbreakbeat IDM\nbreakbeat IDM chiptune\nbreakbeat J-pop\nbreakbeat Latin\nbreakbeat Latin funk\nbreakbeat Latin house\nbreakbeat R&B\nbreakbeat acid funk\nbreakbeat acid house\nbreakbeat acid house progressive trance\nbreakbeat acid techno\nbreakbeat big beat\nbreakbeat big beat industrial\nbreakbeat chiptune\nbreakbeat chiptune acid house\nbreakbeat chiptune drum and bass\nbreakbeat chiptune funk\nbreakbeat chiptune indie pop\nbreakbeat chiptune rap-rock\nbreakbeat chiptune trance\nbreakbeat cinematic\nbreakbeat cyberpunk\nbreakbeat drum and bass\nbreakbeat drum and bass big beat\nbreakbeat dubstep\nbreakbeat electro\nbreakbeat electro-funk\nbreakbeat funk\nbreakbeat funk acid house\nbreakbeat funk big beat\nbreakbeat funk chiptune\nbreakbeat funk dubstep\nbreakbeat funk electronic\nbreakbeat funk jazz\nbreakbeat funk rock\nbreakbeat funk vaporwave\nbreakbeat funk world fusion\nbreakbeat funk world music\nbreakbeat funkot hip-hop\nbreakbeat glitch-hop\nbreakbeat glitchcore\nbreakbeat hardcore\nbreakbeat hardcore hyperpop\nbreakbeat hardstyle\nbreakbeat hip hop\nbreakbeat hip-hop\nbreakbeat hip-hop J-pop\nbreakbeat hip-hop alternative rock\nbreakbeat hip-hop chiptune\nbreakbeat hip-house\nbreakbeat house\nbreakbeat house experimental\nbreakbeat indie electronic\nbreakbeat indie pop\nbreakbeat industrial\nbreakbeat industrial cinematic\nbreakbeat industrial rock\nbreakbeat jazz fusion\nbreakbeat jazz fusion chiptune\nbreakbeat jungle\nbreakbeat jungle chiptune\nbreakbeat jungle hip-hop\nbreakbeat latin\nbreakbeat lo-fi\nbreakbeat lounge\nbreakbeat math rock video game music\nbreakbeat moombahton\nbreakbeat neurofunk\nbreakbeat nu-funk\nbreakbeat nu-metal\nbreakbeat nu-metal chiptune\nbreakbeat pop\nbreakbeat pop-R&B\nbreakbeat pop-rock\nbreakbeat punk\nbreakbeat rave\nbreakbeat soul\nbreakbeat tech house\nbreakbeat tech-trance\nbreakbeat techno\nbreakbeat techno electro\nbreakbeat trance big beat\nbreakbeat trance chiptune\nbreakbeat, 90s fitness, ambient\nbreakbeat, 90s fitness, retro\nbreakbeat, 90s video game, funk\nbreakbeat, 90s video game, synthwave\nbreakbeat, Bollywood, electronic\nbreakbeat, Brazilian funk, reggae\nbreakbeat, Cantopop, hardcore hip-hop\nbreakbeat, IDM, chiptune\nbreakbeat, IDM, drum and bass\nbreakbeat, IDM, electronic\nbreakbeat, IDM, experimental techno\nbreakbeat, J-pop, chiptune\nbreakbeat, J-pop, electronic\nbreakbeat, J-pop, video game\nbreakbeat, Latin electronic, aggressive\nbreakbeat, Latin electronic, experimental club\nbreakbeat, Latin funk, chiptune\nbreakbeat, Latin funk, electronic\nbreakbeat, Latin hip hop\nbreakbeat, Latin house\nbreakbeat, Latin, big beat\nbreakbeat, Latin, experimental\nbreakbeat, Middle Eastern fusion\nbreakbeat, Middle Eastern, electronic\nbreakbeat, Middle Eastern, rave\nbreakbeat, North African pop\nbreakbeat, Polish rap, electronic\nbreakbeat, Punjabi folk, electronic\nbreakbeat, Punjabi hip hop\nbreakbeat, R&B, electronic\nbreakbeat, R&B, hip hop\nbreakbeat, Russian hip hop\nbreakbeat, Russian hip hop, electronic\nbreakbeat, Russian rap, Eurodance\nbreakbeat, Russian rap, aggressive\nbreakbeat, Russian rap, gritty\nbreakbeat, Russian rap, industrial\nbreakbeat, Shibuya-kei, funk\nbreakbeat, South Indian film music, hip-hop\nbreakbeat, Tamil hip hop\nbreakbeat, UK garage, 2-step\nbreakbeat, UK garage, cinematic\nbreakbeat, UK garage, experimental\nbreakbeat, UK garage, experimental electronic\nbreakbeat, UK garage, house\nbreakbeat, UK garage, hyperpop\nbreakbeat, UK grime, glitch hop\nbreakbeat, UK rap, 80s electronic\nbreakbeat, acid house, ambient\nbreakbeat, acid house, big beat\nbreakbeat, acid house, chiptune\nbreakbeat, acid house, cinematic\nbreakbeat, acid house, electronic\nbreakbeat, acid house, experimental\nbreakbeat, acid house, funk-rock\nbreakbeat, acid house, glitch\nbreakbeat, acid house, hardstyle\nbreakbeat, acid house, industrial\nbreakbeat, acid house, industrial techno\nbreakbeat, acid house, rave\nbreakbeat, acid house, tech-trance\nbreakbeat, acid house, techno\nbreakbeat, acid house, trance\nbreakbeat, acid jazz, video game music\nbreakbeat, acid techno\nbreakbeat, acid techno, aggressive\nbreakbeat, acid techno, big beat\nbreakbeat, acid techno, chiptune\nbreakbeat, acid techno, cyberpunk\nbreakbeat, acid techno, drum and bass\nbreakbeat, acid techno, electronic\nbreakbeat, acid techno, experimental\nbreakbeat, acid techno, futuristic\nbreakbeat, acid techno, glitch\nbreakbeat, acid techno, industrial\nbreakbeat, acid techno, rave\nbreakbeat, acid techno, sci-fi\nbreakbeat, acid techno, tech-trance\nbreakbeat, acid, electronic\nbreakbeat, acid, glitch\nbreakbeat, ambient\nbreakbeat, ambient techno\nbreakbeat, ambient, C-pop\nbreakbeat, ambient, Latin percussion\nbreakbeat, ambient, chiptune\nbreakbeat, ambient, drum and bass\nbreakbeat, ambient, electronic\nbreakbeat, ambient, glitch\nbreakbeat, ambient, hip hop\nbreakbeat, ambient, jazz-fusion\nbreakbeat, anime, video game\nbreakbeat, baile funk, big beat\nbreakbeat, bass house, UK garage\nbreakbeat, big beat\nbreakbeat, big beat, Indian fusion\nbreakbeat, big beat, acid jazz\nbreakbeat, big beat, alternative rock\nbreakbeat, big beat, chiptune\nbreakbeat, big beat, cyberpunk\nbreakbeat, big beat, drum and bass\nbreakbeat, big beat, electronic hip-hop\nbreakbeat, big beat, electronic rock\nbreakbeat, big beat, experimental electronic\nbreakbeat, big beat, hard electronic\nbreakbeat, big beat, hardcore techno\nbreakbeat, big beat, hip-hop\nbreakbeat, big beat, industrial\nbreakbeat, big beat, jungle\nbreakbeat, big beat, rap-rock\nbreakbeat, big beat, rave\nbreakbeat, big beat, techstep\nbreakbeat, big beat, video game\nbreakbeat, chiptune\nbreakbeat, chiptune, 2000s video game\nbreakbeat, chiptune, Bengali hip hop\nbreakbeat, chiptune, IDM\nbreakbeat, chiptune, J-core\nbreakbeat, chiptune, Japanese video game\nbreakbeat, chiptune, UK garage\nbreakbeat, chiptune, acid\nbreakbeat, chiptune, anime\nbreakbeat, chiptune, big beat\nbreakbeat, chiptune, cinematic\nbreakbeat, chiptune, demoscene\nbreakbeat, chiptune, drum and bass\nbreakbeat, chiptune, electro\nbreakbeat, chiptune, electro-funk\nbreakbeat, chiptune, electroclash\nbreakbeat, chiptune, electronic\nbreakbeat, chiptune, funk\nbreakbeat, chiptune, glitch\nbreakbeat, chiptune, happy hardcore\nbreakbeat, chiptune, hip hop\nbreakbeat, chiptune, hyperpop\nbreakbeat, chiptune, industrial\nbreakbeat, chiptune, jungle\nbreakbeat, chiptune, lo-fi hip hop\nbreakbeat, chiptune, rave\nbreakbeat, chiptune, retro game\nbreakbeat, chiptune, retro hip hop\nbreakbeat, chiptune, retro video game\nbreakbeat, chiptune, synth-pop\nbreakbeat, chiptune, synthwave\nbreakbeat, chiptune, techstep\nbreakbeat, chiptune, trance\nbreakbeat, chiptune, trap\nbreakbeat, chiptune, video game\nbreakbeat, chiptune, video game music\nbreakbeat, chiptune, video game soundtrack\nbreakbeat, cinematic, ambient\nbreakbeat, cinematic, chiptune\nbreakbeat, cinematic, electronic\nbreakbeat, cinematic, neurofunk\nbreakbeat, cinematic, spy thriller\nbreakbeat, cinematic, spy-thriller\nbreakbeat, complexo, hardstyle\nbreakbeat, complextro, drum and bass\nbreakbeat, cyberpunk, acid\nbreakbeat, cyberpunk, acid techno\nbreakbeat, cyberpunk, chiptune\nbreakbeat, cyberpunk, electronic\nbreakbeat, cyberpunk, experimental\nbreakbeat, cyberpunk, glitch\nbreakbeat, cyberpunk, industrial\nbreakbeat, cyberpunk, retro-futuristic\nbreakbeat, dance-pop, Bengali pop\nbreakbeat, dancehall, big beat\nbreakbeat, dancehall, sci-fi\nbreakbeat, drum and bass\nbreakbeat, drum and bass, Latin\nbreakbeat, drum and bass, Latin funk\nbreakbeat, drum and bass, acid house\nbreakbeat, drum and bass, alternative rock\nbreakbeat, drum and bass, ambient\nbreakbeat, drum and bass, big beat\nbreakbeat, drum and bass, chiptune\nbreakbeat, drum and bass, dark electronic pop\nbreakbeat, drum and bass, electronic\nbreakbeat, drum and bass, experimental\nbreakbeat, drum and bass, futuristic\nbreakbeat, drum and bass, glitch\nbreakbeat, drum and bass, happy hardcore\nbreakbeat, drum and bass, hyperpop\nbreakbeat, drum and bass, industrial\nbreakbeat, drum and bass, sci-fi rap\nbreakbeat, drum and bass, soulful\nbreakbeat, drum and bass, video game music\nbreakbeat, drum and bass, video game soundtrack\nbreakbeat, dubstep\nbreakbeat, dubstep, UK garage\nbreakbeat, dubstep, chiptune\nbreakbeat, dubstep, dancehall\nbreakbeat, dubstep, funk\nbreakbeat, electro, big beat\nbreakbeat, electro-funk, South Asian fusion\nbreakbeat, electronic rock, big beat\nbreakbeat, electronic rock, conscious hip-hop\nbreakbeat, electronic rock, hard rock\nbreakbeat, electronic, Arabic fusion\nbreakbeat, electronic, Brazilian hip hop\nbreakbeat, electronic, Chinese pop\nbreakbeat, electronic, Latin\nbreakbeat, electronic, Mandopop\nbreakbeat, electronic, North African\nbreakbeat, electronic, Portuguese vocal\nbreakbeat, electronic, Russian hip hop\nbreakbeat, electronic, Russian hip-hop\nbreakbeat, electronic, Russian rap\nbreakbeat, electronic, acid\nbreakbeat, electronic, aggressive\nbreakbeat, electronic, ambient\nbreakbeat, electronic, chiptune\nbreakbeat, electronic, experimental\nbreakbeat, electronic, folk\nbreakbeat, electronic, hip hop\nbreakbeat, electronic, indie rock\nbreakbeat, electronic, industrial\nbreakbeat, electronic, jazz lounge\nbreakbeat, electronic, neo-classical\nbreakbeat, electronic, novelty\nbreakbeat, electronic, political hip hop\nbreakbeat, electronic, quirky\nbreakbeat, electronic, rave\nbreakbeat, electronic, sci-fi\nbreakbeat, electronic, theatrical\nbreakbeat, electronic, trance\nbreakbeat, electronic, world fusion\nbreakbeat, electronic, world music\nbreakbeat, experimental electronic\nbreakbeat, experimental electronic, big beat\nbreakbeat, experimental hip-hop\nbreakbeat, experimental, Indian electronic\nbreakbeat, experimental, electronic\nbreakbeat, experimental, vaporwave\nbreakbeat, filmi, R&B\nbreakbeat, funk, IDM\nbreakbeat, funk, Latin\nbreakbeat, funk, Latin hip-hop\nbreakbeat, funk, acid jazz\nbreakbeat, funk, experimental hip-hop\nbreakbeat, funk, hip-hop\nbreakbeat, funk, pop\nbreakbeat, funk, retro\nbreakbeat, funk, retro electronic\nbreakbeat, funk, video game\nbreakbeat, funk, world music\nbreakbeat, funk-rap\nbreakbeat, future bass, cyberpunk\nbreakbeat, future bass, industrial\nbreakbeat, future bass, video game\nbreakbeat, futuristic, cybernetic\nbreakbeat, gabber\nbreakbeat, gabber, glitch\nbreakbeat, gabber, rave\nbreakbeat, glitch, Indian fusion\nbreakbeat, glitch, Japanese rap\nbreakbeat, glitch, Middle Eastern fusion\nbreakbeat, glitch, ambient\nbreakbeat, glitch, chiptune\nbreakbeat, glitch, dubstep\nbreakbeat, glitch, electronic\nbreakbeat, glitch, future bass\nbreakbeat, glitch, industrial\nbreakbeat, glitch, industrial hip hop\nbreakbeat, glitch, neurofunk\nbreakbeat, glitch, satirical rap\nbreakbeat, glitch, sci-fi\nbreakbeat, glitch-hop, chiptune\nbreakbeat, glitch-hop, electronic\nbreakbeat, happy hardcore\nbreakbeat, happy hardcore, 90s rave\nbreakbeat, happy hardcore, chiptune\nbreakbeat, happy hardcore, drum and bass\nbreakbeat, happy hardcore, video game music\nbreakbeat, hardcore, Polish rap\nbreakbeat, hardcore, electronic\nbreakbeat, hardstyle, UK garage\nbreakbeat, hardstyle, ambient\nbreakbeat, hardstyle, glitch\nbreakbeat, hip hop, Cantonese rap\nbreakbeat, hip hop, Chinese rap\nbreakbeat, hip hop, Chinese underground\nbreakbeat, hip hop, Indian hip hop\nbreakbeat, hip hop, aggressive\nbreakbeat, hip hop, dancehall\nbreakbeat, hip hop, electronic\nbreakbeat, hip hop, experimental\nbreakbeat, hip hop, funk\nbreakbeat, hip hop, psychedelic\nbreakbeat, hip-hop, Russian rap\nbreakbeat, hip-hop, big beat\nbreakbeat, hip-hop, chiptune\nbreakbeat, hip-hop, electronic\nbreakbeat, hip-hop, funk\nbreakbeat, hip-hop, jungle\nbreakbeat, hip-hop, lo-fi\nbreakbeat, hip-hop, new jack swing\nbreakbeat, hip-hop, rave\nbreakbeat, hip-house, retro\nbreakbeat, house, Latin\nbreakbeat, hyperpop, UK garage\nbreakbeat, hyperpop, funk\nbreakbeat, hyperpop, industrial\nbreakbeat, industrial dance, big beat\nbreakbeat, industrial electronic\nbreakbeat, industrial hip-hop\nbreakbeat, industrial rock, big beat\nbreakbeat, industrial rock, drum and bass\nbreakbeat, industrial rock, nu-metal\nbreakbeat, industrial techno, drum and bass\nbreakbeat, industrial, EBM\nbreakbeat, industrial, Russian hip hop\nbreakbeat, industrial, Russian rap\nbreakbeat, industrial, acid\nbreakbeat, industrial, aggressive\nbreakbeat, industrial, ambient\nbreakbeat, industrial, big beat\nbreakbeat, industrial, cyberpunk\nbreakbeat, industrial, electronic\nbreakbeat, industrial, futurecore\nbreakbeat, industrial, gabber\nbreakbeat, industrial, glitch\nbreakbeat, industrial, hardcore\nbreakbeat, industrial, lo-fi\nbreakbeat, industrial, metal\nbreakbeat, industrial, nu-metal\nbreakbeat, industrial, punk\nbreakbeat, industrial, punk rock\nbreakbeat, industrial, rave\nbreakbeat, jazz fusion, big beat\nbreakbeat, jazz fusion, progressive trance\nbreakbeat, jazz, electronic\nbreakbeat, jungle, J-pop\nbreakbeat, jungle, baile funk\nbreakbeat, jungle, big beat\nbreakbeat, jungle, drum and bass\nbreakbeat, jungle, dub\nbreakbeat, jungle, electronic rock\nbreakbeat, jungle, gabber\nbreakbeat, jungle, hard techno\nbreakbeat, jungle, synth-pop\nbreakbeat, jungle, video game\nbreakbeat, klezmer, hip-hop\nbreakbeat, latin, tribal\nbreakbeat, liquid funk, electronic\nbreakbeat, lo-fi hip hop\nbreakbeat, lo-fi hip hop, Indian fusion\nbreakbeat, lo-fi hip hop, Russian rap\nbreakbeat, lo-fi hip hop, neo-soul\nbreakbeat, lo-fi hip hop, rap-rock\nbreakbeat, lo-fi, Indian experimental\nbreakbeat, lo-fi, Indian folk\nbreakbeat, lo-fi, R&B\nbreakbeat, lo-fi, aggressive\nbreakbeat, lo-fi, chiptune\nbreakbeat, lo-fi, digital\nbreakbeat, lo-fi, experimental\nbreakbeat, lo-fi, hip hop\nbreakbeat, lo-fi, industrial\nbreakbeat, lo-fi, punk\nbreakbeat, mashup, electronic\nbreakbeat, neurofunk, chiptune\nbreakbeat, neurofunk, electronic\nbreakbeat, neurofunk, techstep\nbreakbeat, new jack swing, big beat\nbreakbeat, new jack swing, dance-pop\nbreakbeat, new jack swing, hip hop\nbreakbeat, new jack swing, house\nbreakbeat, nightcore, electronic\nbreakbeat, old-school hip hop, dance-pop\nbreakbeat, old-school hip-hop, big beat\nbreakbeat, pop-punk, electronic\nbreakbeat, post-rock, Persian vocal\nbreakbeat, psybass, electronic\nbreakbeat, psychedelic, funk\nbreakbeat, psychedelic, lo-fi\nbreakbeat, psytrance, acid house\nbreakbeat, psytrance, electronic\nbreakbeat, psytrance, hard trance\nbreakbeat, punk rock, electronic\nbreakbeat, punk, big beat\nbreakbeat, punk, electronic\nbreakbeat, ragga, Middle Eastern fusion\nbreakbeat, rap-rock, big beat\nbreakbeat, rave, Japanese arcade\nbreakbeat, rave, UK garage\nbreakbeat, rave, acid\nbreakbeat, rave, big beat\nbreakbeat, rave, chiptune\nbreakbeat, rave, electronic\nbreakbeat, rave, happy hardcore\nbreakbeat, rave, hip-hop\nbreakbeat, rave, trip-hop\nbreakbeat, rave, world fusion\nbreakbeat, retro electronic, dance\nbreakbeat, retro video game\nbreakbeat, retro video game, electronic\nbreakbeat, retro video game, funk\nbreakbeat, retro video game, synthwave\nbreakbeat, retro, chiptune\nbreakbeat, retro, dance\nbreakbeat, retro, hip hop\nbreakbeat, retro-futuristic, synthwave\nbreakbeat, sci-fi, video game\nbreakbeat, surf-rock, acid\nbreakbeat, synth-pop, progressive house\nbreakbeat, synthpop, chiptune\nbreakbeat, synthwave, J-pop\nbreakbeat, synthwave, chiptune\nbreakbeat, tech trance, video game soundtrack\nbreakbeat, tech-trance\nbreakbeat, tech-trance, acid\nbreakbeat, tech-trance, big beat\nbreakbeat, tech-trance, video game\nbreakbeat, tech-trance, video game soundtrack\nbreakbeat, techno\nbreakbeat, techno, big beat\nbreakbeat, techno, free jazz\nbreakbeat, techno, industrial\nbreakbeat, techno, tech-house\nbreakbeat, techstep, drum and bass\nbreakbeat, tribal, futuristic\nbreakbeat, trip-hop, ambient\nbreakbeat, video game music, electronic\nbreakbeat, video game music, synthwave\nbreakbeat, video game soundtrack, chiptune\nbreakbeat, video game soundtrack, funk\nbreakbeat, video game soundtrack, synthwave\nbreakbeat, video game, J-pop\nbreakbeat, video game, cinematic\nbreakbeat, video game, lo-fi\nbreakbeat, video game, lo-fi hip hop\nbreakbeat, video game, retro-electronic\nbreakbeat, video game, synthwave\nbreakbeat, world fusion\nbreakbeat, world fusion, funk\nbreakbeat, world fusion, industrial\nbreakbeat, world music, electronic\nbreakcore\nbreakcore art-pop\nbreakcore artcore\nbreakcore artcore chiptune\nbreakcore artcore trance\nbreakcore avant-garde piano\nbreakcore chiptune\nbreakcore chiptune IDM\nbreakcore chiptune J-pop\nbreakcore chiptune acid\nbreakcore chiptune acid techno\nbreakcore chiptune art rock\nbreakcore chiptune artcore\nbreakcore chiptune classical\nbreakcore chiptune experimental J-pop\nbreakcore chiptune glitch\nbreakcore chiptune glitch-hop\nbreakcore chiptune happy hardcore\nbreakcore chiptune hyper-funk\nbreakcore chiptune jazz fusion\nbreakcore chiptune jazz-rock\nbreakcore chiptune jungle\nbreakcore chiptune metalcore\nbreakcore chiptune surf rock\nbreakcore chiptune symphonic\nbreakcore chiptune trance\nbreakcore cinematic\nbreakcore classical chiptune\nbreakcore cybergrind\nbreakcore digital hardcore\nbreakcore drum and bass\nbreakcore drum and bass chiptune\nbreakcore dubstep\nbreakcore electroclash\nbreakcore electronic rock\nbreakcore funk\nbreakcore fusion\nbreakcore gabber\nbreakcore gabber chiptune\nbreakcore gabber experimental\nbreakcore gabber hardcore\nbreakcore glitch\nbreakcore glitch hop artcore\nbreakcore glitch hop chiptune\nbreakcore glitch hop dubstep\nbreakcore glitch world music\nbreakcore glitch-hop\nbreakcore glitch-hop experimental bass\nbreakcore glitch-hop hyperpop\nbreakcore glitchcore\nbreakcore hardcore hip-hop\nbreakcore hardcore techno\nbreakcore hip-hop\nbreakcore hyperpop\nbreakcore hyperpop glitch\nbreakcore hyperpop j-pop\nbreakcore indie rock\nbreakcore industrial\nbreakcore industrial dark electronic\nbreakcore industrial metal\nbreakcore industrial rock\nbreakcore j-pop\nbreakcore jazz fusion\nbreakcore jazz fusion J-pop\nbreakcore jazz fusion chiptune\nbreakcore jazz-funk J-pop\nbreakcore jazz-funk chiptune\nbreakcore jungle\nbreakcore lo-fi\nbreakcore lo-fi hip-hop\nbreakcore math rock\nbreakcore math rock chiptune\nbreakcore metal\nbreakcore metalcore\nbreakcore metalcore cinematic\nbreakcore neurofunk\nbreakcore shoegaze\nbreakcore speedcore\nbreakcore speedcore chiptune\nbreakcore techno\nbreakcore techstep\nbreakcore trance cinematic ambient\nbreakcore trap\nbreakcore vaporwave\nbreakcore, IDM\nbreakcore, IDM, chiptune\nbreakcore, IDM, cinematic\nbreakcore, IDM, experimental\nbreakcore, IDM, glitch\nbreakcore, IDM, jungle\nbreakcore, IDM, techno\nbreakcore, J-core\nbreakcore, J-core, artcore\nbreakcore, J-core, chiptune\nbreakcore, J-core, denpa\nbreakcore, J-core, happy hardcore\nbreakcore, J-core, jungle\nbreakcore, J-core, speedcore\nbreakcore, J-pop, Vocaloid\nbreakcore, J-pop, artcore\nbreakcore, J-pop, denpa-kei\nbreakcore, J-pop, glitch\nbreakcore, J-pop, speedcore\nbreakcore, J-rock\nbreakcore, J-rock, J-pop\nbreakcore, J-rock, electronicore\nbreakcore, J-rock, hyperpop\nbreakcore, J-rock, metal\nbreakcore, Middle Eastern fusion\nbreakcore, Nintendocore\nbreakcore, R&B, experimental\nbreakcore, UK hip-hop\nbreakcore, Vocaloid\nbreakcore, ambient\nbreakcore, ambient piano\nbreakcore, ambient, C-pop\nbreakcore, ambient, Chinese ethereal\nbreakcore, ambient, Vocaloid\nbreakcore, ambient, chiptune\nbreakcore, ambient, cinematic\nbreakcore, ambient, electronic\nbreakcore, ambient, experimental\nbreakcore, ambient, jungle\nbreakcore, art pop, J-pop\nbreakcore, art-pop, hyperpop\nbreakcore, artcore, J-pop\nbreakcore, big band jazz\nbreakcore, bossa nova\nbreakcore, chiptune\nbreakcore, chiptune, J-core\nbreakcore, chiptune, J-pop\nbreakcore, chiptune, Latin electronic\nbreakcore, chiptune, Vocaloid\nbreakcore, chiptune, ambient\nbreakcore, chiptune, artcore\nbreakcore, chiptune, cinematic\nbreakcore, chiptune, classical piano\nbreakcore, chiptune, drum and bass\nbreakcore, chiptune, electronic\nbreakcore, chiptune, gabber\nbreakcore, chiptune, glitch\nbreakcore, chiptune, glitch-hop\nbreakcore, chiptune, hardstyle\nbreakcore, chiptune, hyperpop\nbreakcore, chiptune, industrial metal\nbreakcore, chiptune, lo-fi\nbreakcore, chiptune, metalcore\nbreakcore, chiptune, neurofunk\nbreakcore, chiptune, nightcore\nbreakcore, chiptune, punk\nbreakcore, chiptune, speedcore\nbreakcore, chiptune, video game music\nbreakcore, cinematic\nbreakcore, cinematic, Tamil pop\nbreakcore, cinematic, ambient\nbreakcore, cinematic, baroque\nbreakcore, cinematic, chiptune\nbreakcore, cinematic, glitch\nbreakcore, cinematic, industrial\nbreakcore, cinematic, lo-fi\nbreakcore, cinematic, neurofunk\nbreakcore, cinematic, orchestral\nbreakcore, complextro, indie-pop\nbreakcore, cyberpunk, ambient\nbreakcore, denpa-kei, chiptune\nbreakcore, digital hardcore\nbreakcore, digital hardcore, speedcore\nbreakcore, dream pop, ambient\nbreakcore, dream pop, glitch-hop\nbreakcore, drum and bass\nbreakcore, drum and bass, ambient\nbreakcore, drum and bass, chiptune\nbreakcore, drum and bass, cinematic\nbreakcore, drum and bass, techno\nbreakcore, dubstep, glitch\nbreakcore, electronic rock, rap\nbreakcore, electronic, C-pop\nbreakcore, electronic, guzheng\nbreakcore, electronic, world fusion\nbreakcore, emo rap\nbreakcore, experimental electronic\nbreakcore, experimental hip-hop\nbreakcore, experimental, vocal glitch\nbreakcore, future bass\nbreakcore, future bass, ambient\nbreakcore, gabber\nbreakcore, gabber, Vocaloid\nbreakcore, gabber, chiptune\nbreakcore, gabber, hyperpop\nbreakcore, gabber, speedcore\nbreakcore, glitch\nbreakcore, glitch, ambient\nbreakcore, glitch, chiptune\nbreakcore, glitch, cinematic\nbreakcore, glitch, dubstep\nbreakcore, glitch, electronic\nbreakcore, glitch, experimental\nbreakcore, glitch, hyperpop\nbreakcore, glitch, industrial\nbreakcore, glitch, nu-disco\nbreakcore, glitch-hop\nbreakcore, glitch-hop, chiptune\nbreakcore, glitchcore, hyperpop\nbreakcore, happy hardcore\nbreakcore, happy hardcore, J-core\nbreakcore, hard techno\nbreakcore, hard trance, glitch\nbreakcore, hardcore punk, chiptune\nbreakcore, hardstyle, chiptune\nbreakcore, hardstyle, cinematic\nbreakcore, hardstyle, gabber\nbreakcore, hardstyle, glitch\nbreakcore, hip-hop, nu-metal\nbreakcore, hyper-funk\nbreakcore, hyperpop\nbreakcore, hyperpop, J-core\nbreakcore, hyperpop, chiptune\nbreakcore, hyperpop, cinematic\nbreakcore, hyperpop, dubstep\nbreakcore, hyperpop, experimental\nbreakcore, hyperpop, experimental electronic\nbreakcore, hyperpop, gabber\nbreakcore, hyperpop, hardstyle\nbreakcore, hyperpop, industrial\nbreakcore, industrial hip-hop, Middle Eastern fusion\nbreakcore, industrial techno\nbreakcore, industrial techno, cinematic ambient\nbreakcore, industrial, experimental\nbreakcore, j-core, happy hardcore\nbreakcore, j-core, speedcore\nbreakcore, jazz fusion, neurofunk\nbreakcore, jazz hip-hop, drum and bass\nbreakcore, jazz-hop, soulful hip-hop\nbreakcore, jungle\nbreakcore, jungle, artcore\nbreakcore, jungle, drum and bass\nbreakcore, lo-fi hip hop, ambient\nbreakcore, lo-fi hip hop, choral\nbreakcore, lo-fi, ambient\nbreakcore, lo-fi, neurofunk\nbreakcore, mathcore\nbreakcore, metalcore, dark cabaret\nbreakcore, neo-soul\nbreakcore, neurofunk\nbreakcore, neurofunk, ambient\nbreakcore, neurofunk, chiptune\nbreakcore, neurofunk, cinematic\nbreakcore, neurofunk, gabber\nbreakcore, neurofunk, glitch\nbreakcore, neurofunk, hardstyle\nbreakcore, neurofunk, korean rap\nbreakcore, neurofunk, trance\nbreakcore, orchestral rock, funk-rock\nbreakcore, pop-punk, ambient\nbreakcore, progressive house, emotional ballad\nbreakcore, progressive house, hardstyle\nbreakcore, ragtime, video game music\nbreakcore, speedcore\nbreakcore, speedcore, J-core\nbreakcore, speedcore, artcore\nbreakcore, synth-pop, ambient\nbreakcore, trap, dancehall\nbreakcore, trip-hop, drum and bass\nbreakcore, vaporwave, future bass\nbreakcore, world music, heavy metal\nbreezy pop\nbrega\nbrega MPB\nbrega arrocha\nbrega carimbó\nbrega carioca\nbrega carnaval\nbrega chiptune\nbrega eletrônico\nbrega forró\nbrega funk\nbrega funk carioca\nbrega funk chiptune\nbrega funk, baile funk\nbrega funk, carioca funk\nbrega funk, chiptune, electronic\nbrega funk, electro-pop\nbrega funk, forró, Brazilian pop\nbrega funk, piseiro, Brazilian pop\nbrega funk, reggaeton, Brazilian pop\nbrega funk, synth-pop\nbrega nova\nbrega piseiro\nbrega pop\nbrega reggae\nbrega rock\nbrega romântico\nbrega salsa\nbrega samba\nbrega samba, hard rock, heavy metal\nbrega samba-pop\nbrega samba-rock\nbrega seresta\nbrega sertanejo\nbrega soul\nbrega synth-pop\nbrega techno\nbrega, MPB\nbrega, arrocha\nbrega, carnaval\nbrega, forró\nbrega, forró eletrônico\nbrega, forró romântico\nbrega, forró, Brazilian pop\nbrega, forró, synth\nbrega, pagode, Brazilian pop\nbrega, piseiro, Brazilian pop\nbrega, romantic pop\nbrega-brega\nbrega-funk\nbrega-pop\nbrega-reggae\nbrega-rock\nbrega-trap\nbrostep\nbrostep chiptune\nbrostep dubstep\nbrostep glitch hop hardstyle\nbrostep glitch-hop\nbrostep hardstyle\nbrostep hip-hop\nbrostep hip-hop chiptune\nbrostep metalcore\nbrostep pop\nbrostep trap\nbrostep, chiptune, ambient\nbrostep, chiptune, complextro\nbrostep, chiptune, electronic\nbrostep, cinematic, ambient\nbrostep, cinematic, orchestral\nbrostep, color bass, melodic riddim\nbrostep, dancehall, neurofunk\nbrostep, dubstep, electronic\nbrostep, dubstep, neurofunk\nbrostep, hardstyle, electronic\nbrostep, hardstyle, pop\nbrostep, hardstyle, synth-pop\nbrostep, pop-punk, electronic\nbrostep, rap, electronic\nbubblegum C-pop\nbubblegum C-pop hyperpop\nbubblegum K-pop\nbubblegum bass\nbubblegum dance\nbubblegum dance, J-pop\nbubblegum dance, hyperpop, C-pop\nbubblegum dance-pop\nbubblegum dance-pop, hyperpop\nbubblegum disco\nbubblegum funk, J-pop\nbubblegum hip-hop\nbubblegum pop\nbubblegum pop chiptune\nbubblegum pop hyperpop\nbubblegum pop neo-soul\nbubblegum pop, C-pop, video game music\nbubblegum pop, Eurodance\nbubblegum pop, J-pop\nbubblegum pop, J-pop, anime theme\nbubblegum pop, J-pop, chiptune\nbubblegum pop, J-pop, hyperpop\nbubblegum pop, J-pop, video game music\nbubblegum pop, K-pop\nbubblegum pop, K-pop, funk\nbubblegum pop, K-pop, hyperpop\nbubblegum pop, anime theme, C-pop\nbubblegum pop, chiptune\nbubblegum pop, chiptune, J-pop\nbubblegum pop, chiptune, hyperpop\nbubblegum pop, city pop\nbubblegum pop, dance-pop\nbubblegum pop, eurodance\nbubblegum pop, hyperpop\nbubblegum pop, hyperpop, C-pop\nbubblegum pop, hyperpop, K-pop\nbubblegum pop, hyperpop, children's music\nbubblegum pop, hyperpop, chiptune\nbubblegum pop, rockabilly\nbubblegum pop, surf rock, Latin percussion\nbubblegum pop-punk\nbubblegum pop-rock\nbubblegum synth-pop\nbubblegum trap\nbumbá parranda\ncabaret\ncabaret Christmas\ncabaret a cappella\ncabaret art-pop\ncabaret ballad\ncabaret big band\ncabaret blues\ncabaret blues-rock\ncabaret boogie-woogie\ncabaret bossa nova\ncabaret chanson\ncabaret children's\ncabaret children's music\ncabaret comedy\ncabaret electronica\ncabaret fado\ncabaret flamenco\ncabaret folk\ncabaret folk-musical\ncabaret folk-pop\ncabaret folk-punk\ncabaret folk-rock\ncabaret funk\ncabaret fusion\ncabaret hip hop\ncabaret hip-hop\ncabaret indie pop\ncabaret indie rock\ncabaret jazz\ncabaret jazz pop\ncabaret jazz pop salsa\ncabaret jazz rock\ncabaret jazz salsa\ncabaret jazz tango\ncabaret jazz, Eastern European folk\ncabaret jazz, Latin jazz\ncabaret jazz-pop\ncabaret jazz-rock\ncabaret klezmer\ncabaret march\ncabaret metal\ncabaret musette\ncabaret musical\ncabaret noir\ncabaret novelty\ncabaret opera\ncabaret piano\ncabaret polka\ncabaret pop\ncabaret pop cumbia\ncabaret pop disco polo\ncabaret pop exotica\ncabaret pop jazz\ncabaret pop lounge jazz\ncabaret pop rock\ncabaret pop swing\ncabaret pop tango\ncabaret pop, Eastern European, theatrical\ncabaret pop, European chanson\ncabaret pop, J-pop, anime\ncabaret pop, Latin dance-pop\ncabaret pop, Latin pop\ncabaret pop, Latin pop, big band\ncabaret pop, Latin pop, world music\ncabaret pop, klezmer, theatrical\ncabaret pop, schlager, theatrical pop\ncabaret pop, tango, Latin\ncabaret pop-rock\ncabaret protest\ncabaret punk\ncabaret punk rock\ncabaret punk, klezmer, theatrical\ncabaret punk, polka rock\ncabaret punk, theatrical rock\ncabaret punk-jazz\ncabaret ragtime\ncabaret rock\ncabaret rock opera\ncabaret rock psychedelic\ncabaret rock punk\ncabaret rock tango\ncabaret rock, jazz ballad, theatrical\ncabaret rock, musical theater\ncabaret rock, psychedelic, punk rock\ncabaret rock, swing, rockabilly\ncabaret rockabilly\ncabaret salsa\ncabaret samba\ncabaret samba-rock\ncabaret schlager\ncabaret show tune\ncabaret ska\ncabaret soul\ncabaret swing\ncabaret swing rock\ncabaret swing rockabilly\ncabaret swing, Latin jazz, soul\ncabaret swing, hard rock\ncabaret synth-pop\ncabaret tango\ncabaret tango big band\ncabaret tango folk\ncabaret tango jazz\ncabaret tango latin folk\ncabaret tango orchestral\ncabaret tango polish pop\ncabaret tango world music\ncabaret tango, big band swing\ncabaret waltz\ncabaret, Balkan brass, chanson\ncabaret, Balkan, Klezmer\ncabaret, Brazilian, circus\ncabaret, Christmas, theatrical\ncabaret, Dutch chanson, theatrical\ncabaret, Dutch, theatrical\ncabaret, Eastern European folk, theatrical\ncabaret, Eastern European, chanson\ncabaret, Eastern European, theatrical\ncabaret, European chanson, theatrical\ncabaret, French chanson, theatrical\ncabaret, German chanson, theatrical\ncabaret, Latin jazz\ncabaret, Latin jazz, cinematic\ncabaret, Latin jazz, theatrical\ncabaret, Latin musical theater, art pop\ncabaret, Latin pop-rock\ncabaret, Latin, theatrical\ncabaret, Latin, upbeat\ncabaret, MPB, theatrical\ncabaret, Neue Deutsche Welle, free jazz\ncabaret, Polish chanson, theatrical\ncabaret, Russian chanson, lounge jazz\ncabaret, Russian chanson, musette\ncabaret, Russian chanson, theatrical\ncabaret, Turkish pop\ncabaret, art rock, French chanson\ncabaret, art song, waltz\ncabaret, art-pop, klezmer\ncabaret, avant-garde, operatic\ncabaret, big band\ncabaret, big band jazz, dramatic pop\ncabaret, big band, Eastern European pop\ncabaret, big band, German chanson\ncabaret, big band, Latin\ncabaret, big band, avant-garde jazz\ncabaret, big band, cinematic\ncabaret, big band, jazz\ncabaret, big band, klezmer\ncabaret, big band, musical theater\ncabaret, big band, show tune\ncabaret, big band, theatrical\ncabaret, bluegrass, blues-rock\ncabaret, bolero, Latin chanson\ncabaret, boogie-woogie, German satire\ncabaret, boogie-woogie, Latin show tune\ncabaret, boogie-woogie, blues\ncabaret, boogie-woogie, gypsy jazz\ncabaret, boogie-woogie, ragtime\ncabaret, boogie-woogie, show tune\ncabaret, boogie-woogie, swing\ncabaret, boogie-woogie, theatrical\ncabaret, boogie-woogie, theatrical rock\ncabaret, bossa nova, jazz\ncabaret, chanson\ncabaret, chanson, Dutch\ncabaret, chanson, Dutch folk\ncabaret, chanson, Eastern European folk\ncabaret, chanson, European folk\ncabaret, chanson, cinematic\ncabaret, chanson, folk\ncabaret, chanson, polish\ncabaret, chanson, theatrical\ncabaret, chanson, torch song\ncabaret, chanson, vintage Polish\ncabaret, chanson, vintage pop\ncabaret, chiptune, klezmer\ncabaret, cinematic, Portuguese pop\ncabaret, cinematic, ballad\ncabaret, cinematic, chanson\ncabaret, cinematic, k-pop\ncabaret, cinematic, klezmer\ncabaret, cinematic, orchestral\ncabaret, cinematic, tango\ncabaret, cinematic, theatrical\ncabaret, cinematic, whimsical\ncabaret, cool jazz, cinematic\ncabaret, electro-industrial, EBM\ncabaret, electro-trap, avant-garde\ncabaret, electronic pop, world music\ncabaret, eurodance\ncabaret, film noir, vintage\ncabaret, flamenco, chanson\ncabaret, flamenco, theatrical\ncabaret, folk, avant-garde\ncabaret, folk, klezmer\ncabaret, folk, theatrical\ncabaret, folk, world music\ncabaret, folk-rock, theatrical\ncabaret, folk-swing, Danish\ncabaret, gypsy jazz, Balkan\ncabaret, gypsy jazz, Eastern European folk\ncabaret, gypsy jazz, French chanson\ncabaret, gypsy jazz, Persian art music\ncabaret, gypsy jazz, flamenco\ncabaret, gypsy jazz, theatrical\ncabaret, holiday, theatrical\ncabaret, indie rock\ncabaret, industrial, electronic\ncabaret, jazz, Hungarian folk\ncabaret, jazz, chanson\ncabaret, jazz, children's music\ncabaret, jazz, cinematic\ncabaret, jazz, flamenco\ncabaret, jazz, folk\ncabaret, jazz, orchestral\ncabaret, jazz, punk rock\ncabaret, jazz, theatrical\ncabaret, jazz, world\ncabaret, jump blues\ncabaret, jump blues, swing revival\ncabaret, klezmer swing\ncabaret, klezmer, Balkan\ncabaret, klezmer, Eastern European folk\ncabaret, klezmer, European\ncabaret, klezmer, European folk\ncabaret, klezmer, French chanson\ncabaret, klezmer, balkan folk\ncabaret, klezmer, big band\ncabaret, klezmer, chamber music\ncabaret, klezmer, chanson\ncabaret, klezmer, children's music\ncabaret, klezmer, european folk\ncabaret, klezmer, folk\ncabaret, klezmer, indie rock\ncabaret, klezmer, musical theater\ncabaret, klezmer, polka\ncabaret, klezmer, ragtime\ncabaret, klezmer, swing\ncabaret, klezmer, theatrical\ncabaret, klezmer, theatrical pop\ncabaret, klezmer, theatrical rock\ncabaret, klezmer, vintage\ncabaret, latin jazz, cinematic\ncabaret, latin pop, cinematic\ncabaret, latin, theatrical\ncabaret, levenslied, theatrical\ncabaret, lo-fi, jazz\ncabaret, lo-fi, ragtime\ncabaret, mariachi, theatrical\ncabaret, melancholic, Eastern European\ncabaret, metal, theatrical\ncabaret, musette, European\ncabaret, musette, French chanson\ncabaret, musette, chanson\ncabaret, musette, novelty\ncabaret, musette, polka\ncabaret, musette, theatrical\ncabaret, musical theater, European\ncabaret, musical theater, European folk\ncabaret, musical theater, Halloween\ncabaret, musical theater, big band\ncabaret, musical theater, ragtime\ncabaret, musical theater, theatrical\ncabaret, neo-classical, theatrical\ncabaret, noir, jazz\ncabaret, novelty, polka\ncabaret, novelty, spooky\ncabaret, novelty, theatrical\ncabaret, novelty, waltz\ncabaret, operatic, chanson\ncabaret, operatic, folk\ncabaret, operatic, ragtime\ncabaret, operatic, theatrical\ncabaret, orchestral film score, European folk\ncabaret, orchestral, cinematic\ncabaret, orchestral, musical theater\ncabaret, orchestral, musical theatre\ncabaret, orchestral, operatic\ncabaret, orchestral, theatrical\ncabaret, orchestral, vintage European\ncabaret, piano ballad, Latin jazz\ncabaret, polka, Dutch chanson\ncabaret, polka, French chanson\ncabaret, polka, German chanson\ncabaret, polka, Halloween\ncabaret, polka, novelty music\ncabaret, polka, ska\ncabaret, polka, spooky\ncabaret, polka, surf rock\ncabaret, polka, theatrical\ncabaret, pop-rock, show tune\ncabaret, protest, klezmer\ncabaret, psychedelic, cinematic\ncabaret, ragtime, French chanson\ncabaret, ragtime, Italian theatrical\ncabaret, ragtime, Latin jazz\ncabaret, ragtime, accordion\ncabaret, ragtime, estrada\ncabaret, ragtime, jazz\ncabaret, ragtime, musical theater\ncabaret, ragtime, operatic\ncabaret, ragtime, schlager\ncabaret, ragtime, stride\ncabaret, ragtime, swing\ncabaret, ragtime, theatrical\ncabaret, rockabilly, klezmer\ncabaret, salsa, theatrical\ncabaret, schlager, European folk\ncabaret, schlager, Neue Deutsche Welle\ncabaret, schlager, novelty\ncabaret, schlager, theatrical\ncabaret, stride piano, ragtime\ncabaret, swing jazz, German chanson\ncabaret, swing, Dutch chanson\ncabaret, swing, French chanson\ncabaret, swing, German chanson\ncabaret, swing, klezmer\ncabaret, swing, theatrical\ncabaret, tango, Greek folk\ncabaret, tango, art song\ncabaret, tango, avant-garde jazz\ncabaret, tango, chanson\ncabaret, tango, cinematic\ncabaret, tango, folk\ncabaret, tango, jazz\ncabaret, tango, noir\ncabaret, tango, theatrical\ncabaret, theatrical, Arabic pop\ncabaret, theatrical, Chinese pop\ncabaret, theatrical, D&D\ncabaret, theatrical, Dutch chanson\ncabaret, theatrical, Eastern European\ncabaret, theatrical, Eastern European folk\ncabaret, theatrical, European\ncabaret, theatrical, European chanson\ncabaret, theatrical, European folk\ncabaret, theatrical, Filipino pop\ncabaret, theatrical, French chanson\ncabaret, theatrical, German\ncabaret, theatrical, German musical\ncabaret, theatrical, German musical theatre\ncabaret, theatrical, Halloween\ncabaret, theatrical, Hebrew folk\ncabaret, theatrical, Hebrew pop\ncabaret, theatrical, Israeli musical\ncabaret, theatrical, Latin\ncabaret, theatrical, Latin-inspired\ncabaret, theatrical, Mandarin pop\ncabaret, theatrical, Polish\ncabaret, theatrical, Russian\ncabaret, theatrical, Soviet estrada\ncabaret, theatrical, Soviet-era estrada\ncabaret, theatrical, Turkish art music\ncabaret, theatrical, Yiddish\ncabaret, theatrical, avant-garde\ncabaret, theatrical, baroque pop\ncabaret, theatrical, big band\ncabaret, theatrical, boogie-woogie\ncabaret, theatrical, chanson\ncabaret, theatrical, choral\ncabaret, theatrical, christmas\ncabaret, theatrical, cinematic\ncabaret, theatrical, circus\ncabaret, theatrical, dark cabaret\ncabaret, theatrical, dark circus\ncabaret, theatrical, dark comedy\ncabaret, theatrical, dark jazz\ncabaret, theatrical, dark pop\ncabaret, theatrical, dramatic\ncabaret, theatrical, flamenco\ncabaret, theatrical, folk\ncabaret, theatrical, folk rock\ncabaret, theatrical, jazz\ncabaret, theatrical, klezmer\ncabaret, theatrical, macabre\ncabaret, theatrical, melancholic\ncabaret, theatrical, musical theater\ncabaret, theatrical, noir\ncabaret, theatrical, old-timey\ncabaret, theatrical, operatic\ncabaret, theatrical, orchestral\ncabaret, theatrical, piano\ncabaret, theatrical, piano virtuoso\ncabaret, theatrical, piano-driven\ncabaret, theatrical, polka\ncabaret, theatrical, punk\ncabaret, theatrical, punk rock\ncabaret, theatrical, quirky\ncabaret, theatrical, ragtime\ncabaret, theatrical, rock-opera\ncabaret, theatrical, spooky\ncabaret, theatrical, swing\ncabaret, theatrical, synth-pop\ncabaret, theatrical, tango\ncabaret, theatrical, villainous\ncabaret, theatrical, vintage Polish\ncabaret, theatrical, world fusion\ncabaret, vaudeville, Italian folk\ncabaret, vaudeville, children's music\ncabaret, vaudeville, ragtime\ncabaret, video game, theatrical\ncabaret, vintage Bollywood\ncabaret, vintage, klezmer\ncabaret, vintage, theatrical\ncabaret, vintage, torch song\ncabaret-metal\ncabaret-pop\ncabaret-pop gothic\ncabaret-pop steampunk\ncabaret-pop tango\ncabaret-pop, Italian pop, funk\ncabaret-pop, Latin jazz, theatrical\ncabaret-punk\ncabaret-punk electronic rock\ncabaret-punk klezmer-punk\ncabaret-punk, chiptune, theatrical\ncabaret-rock\ncabaret-ska\ncafe jazz\ncalypso\ncalypso Mediterranean\ncalypso ballad\ncalypso big band\ncalypso bossa nova\ncalypso children's\ncalypso children's music\ncalypso folk\ncalypso jazz\ncalypso novelty\ncalypso pop\ncalypso reggae\ncalypso rock\ncalypso rock and roll\ncalypso rocksteady\ncalypso salsa\ncalypso samba\ncalypso show tune\ncalypso ska\ncalypso soca\ncalypso swing\ncalypso tropical pop\ncalypso world music\ncalypso, Caribbean folk\ncalypso, Caribbean, novelty\ncalypso, Christmas, Caribbean\ncalypso, Latin rock\ncalypso, children's music, video game music\ncalypso, sea shanty, vintage\ncalypso, soca, Christmas\ncalypso, tropical, Christmas\ncalypso, tropical, children's music\ncalypso, world music, novelty\ncalypso-pop\ncalypso-reggae\ncampfire folk\ncampus folk\ncampus folk-pop\ncampus folk-rock\ncampus pop\ncampus pop-rock\ncampus rock\ncampy Halloween\ncanción de autor\ncanción de gas\ncanción de gesta\ncanción de género\ncandombe\ncantautore\ncante jondo\ncanzone\ncanzone Italiana\ncapoeira\ncapoeira samba\ncaporales cumbia\ncarimbó\ncarioca funk\ncarnaval\ncarnavalito\ncarnavalito cumbia\ncarnavalsmusiek\ncarnavalsmuziek\ncarnival\ncarnival funk\ncarnival march\ncarnival marchinha\ncarnival music\ncarnival polka\ncarnival polka-ska\ncarnival pop\ncarnival pop, children's music, celebratory pop\ncarnival rock\ncarnival samba\ncartoon\ncartoon boogie\ncartoon chase\ncartoon chase music\ncartoon chase, mambo, surf rock\ncartoon hip hop\ncartoon hip-hop\ncartoon jazz\ncartoon music\ncartoon orchestral\ncartoon polka\ncartoon pop\ncartoon punk rock\ncartoon rock\ncartoon score\ncartoon sound design\ncartoon sound effect\ncartoon sound effects\ncartoon soundtrack\ncartoon swing jazz\ncartoon theme\ncartoon-noir\ncartoon-pop\ncartoonish\ncartoonish Halloween\ncartoonish big band\ncartoonish instrumental\ncartoonish jingle\ncartoonish polka\ncartoonish soundtrack\ncartoonish spooky\ncartoonish spy theme\ncartoonish synth\ncartoonish, playful, klezmer\ncartoonish, quirky, cinematic\ncelebratory\ncelebratory piano\ncelebratory pop\ncelebratory synth\ncello-rock\nceremonial\nceremonial Arabic orchestral\nceremonial Japanese\nceremonial Latin\nceremonial ambient\nceremonial anthem\nceremonial brass\nceremonial chant\nceremonial drumming\nceremonial folk\nceremonial march\nceremonial music\nceremonial percussion\nceremonial synth\nceremonial waltz\ncha-cha\ncha-cha, retro Latin, synth pop\ncha-cha-cha\ncha-cha-chá\ncha-cha-chá, Latin big band\ncha-cha-chá, Latin jazz\nchacarera\nchamamé\nchamber ambient\nchamber blues\nchamber choir\nchamber folk\nchamber folk cabaret\nchamber folk indie rock\nchamber folk klezmer\nchamber folk progressive rock\nchamber folk, alternative rock\nchamber folk, neoclassical\nchamber folk, psychedelic rock\nchamber folk, psychedelic rock, blues\nchamber folk, world music\nchamber fusion\nchamber guitar\nchamber hip hop\nchamber jazz\nchamber jazz art-rock\nchamber jazz bebop\nchamber jazz, big band swing\nchamber lullaby\nchamber music\nchamber music bossa nova\nchamber music classical\nchamber music funk-rock cinematic\nchamber music ragtime\nchamber music, Latin tango, theatrical pop\nchamber music, funk-rock, cinematic\nchamber music, klezmer, Eastern European folk\nchamber piano\nchamber pop\nchamber pop indie rock\nchamber pop, J-rock\nchamber pop, light jazz\nchamber pop, shoegaze, post-rock\nchamber rock\nchamber samba\nchamber soul\nchamber synth\nchamber-folk\nchamber-folk, Brazilian pop-rock\nchanson\nchanson blues-rock cabaret\nchanson bolero\nchanson bossa nova\nchanson cabaret\nchanson cool jazz\nchanson exotica\nchanson fado\nchanson folk\nchanson forró\nchanson française\nchanson gypsy jazz\nchanson hip-hop\nchanson indie folk\nchanson indie pop\nchanson indie rock\nchanson jazz\nchanson jazz cabaret\nchanson latin\nchanson lo-fi hip hop\nchanson lounge jazz\nchanson musette\nchanson paillarde\nchanson pop\nchanson pop rock\nchanson pop-rock\nchanson protest\nchanson punk rock\nchanson rap\nchanson rock\nchanson rockabilly\nchanson rockabilly country-rock\nchanson synth-pop\nchanson tango\nchanson trip-hop\nchanson, European folk, accordion\nchanson, European, folk\nchanson, Kayōkyoku, melancholic ballad\nchanson, Latin house, folk narrative\nchanson, Latin jazz, acoustic\nchanson, MPB, European folk\nchanson, R&B, trap\nchanson, Russian bard, cinematic\nchanson, acoustic, Japanese folk\nchanson, acoustic, comedy music\nchanson, alternative rock, French pop\nchanson, art pop, vintage ballad\nchanson, atmospheric, cinematic\nchanson, bal musette, novelty\nchanson, big band, free jazz\nchanson, bilingual, acoustic\nchanson, cabaret, French\nchanson, cabaret, cinematic\nchanson, cabaret, lounge\nchanson, cabaret, melancholic\nchanson, cabaret, melancholic piano\nchanson, cabaret, orchestral\nchanson, cinematic, ambient\nchanson, cinematic, art pop\nchanson, cinematic, ballad\nchanson, cinematic, dream pop\nchanson, cinematic, epic\nchanson, cinematic, folk\nchanson, cinematic, orchestral\nchanson, cinematic, waltz\nchanson, classical, theatrical\nchanson, dark pop, lo-fi\nchanson, fiesta, novelty\nchanson, flamenco, cinematic\nchanson, folk ballad, cinematic\nchanson, folk ballad, emotional piano\nchanson, folk pop\nchanson, folk, cinematic\nchanson, folk, live\nchanson, folk, melancholic\nchanson, gypsy jazz, klezmer\nchanson, gypsy-punk, folk-punk\nchanson, jazz, orchestral\nchanson, lo-fi, cinematic\nchanson, lo-fi, electronic\nchanson, melancholic, theatrical\nchanson, musette, lounge-pop\nchanson, musette, tango\nchanson, musical theatre, folk\nchanson, musical theatre, sentimental ballad\nchanson, oud, Middle Eastern\nchanson, post-rock, ambient\nchanson, post-rock, cinematic\nchanson, post-rock, dream pop\nchanson, retro, surf rock\nchanson, salsa, classical guitar\nchanson, schlager, ballad\nchanson, schlager, vintage ballad\nchanson, soul, gospel\nchanson, synth-pop\nchanson, synth-pop, chillwave\nchanson, theatrical ballad, levenslied\nchanson, theatrical ballad, melancholic piano\nchanson, theatrical pop, European pop\nchanson, theatrical rock, classical\nchanson, theatrical, accordion\nchanson, waltz, cinematic\nchanson, waltz, lo-fi\nchanson-pop\nchanson-rap\nchanson-rock\nchant rock\nchant-rock\nchaotic mashup\nchaotic polka\ncharacter voice\ncharanga\ncharanga cumbia\nchicha\nchild vocal, gentle pop, lullaby\nchild vocal, uplifting, ambient pop\nchildlike synth pop\nchildren's Arabic\nchildren's Arabic pop\nchildren's C-pop\nchildren's C-pop chiptune\nchildren's Christian\nchildren's Christian chiptune\nchildren's Christian country-folk\nchildren's Christian country-pop\nchildren's Christian cumbia\nchildren's Christian dance-pop\nchildren's Christian folk\nchildren's Christian funk\nchildren's Christian hymn\nchildren's Christian music\nchildren's Christian pop\nchildren's Christian pop-folk\nchildren's Christian pop-rock\nchildren's Christian rock\nchildren's Christian, Brazilian funk carioca\nchildren's Christian, Brazilian pop\nchildren's Christian, Brazilian, 80s synth\nchildren's Christian, Eastern European folk\nchildren's Christian, Latin cumbia\nchildren's Christian, Latin folk\nchildren's Christian, Latin folk, cumbia\nchildren's Christian, Latin pop\nchildren's Christian, Latin pop, cumbia\nchildren's Christian, chiptune\nchildren's Christian, cumbia\nchildren's Christian, lo-fi, chiptune\nchildren's Christian, lo-fi, retro\nchildren's Christian, retro MIDI\nchildren's Christian, retro funk, soul\nchildren's Christian, retro pop\nchildren's Christmas\nchildren's Christmas carol\nchildren's EDM\nchildren's Halloween\nchildren's Halloween ragtime\nchildren's Islamic devotional\nchildren's Islamic music\nchildren's Islamic pop\nchildren's J-pop\nchildren's K-pop\nchildren's Latin\nchildren's Mandopop\nchildren's Spanish, Latin cumbia\nchildren's TV theme\nchildren's adventure\nchildren's ambient\nchildren's animation\nchildren's anthem\nchildren's audio\nchildren's audio drama\nchildren's audio story\nchildren's audiobook\nchildren's bluegrass\nchildren's blues\nchildren's boogie-woogie\nchildren's cabaret\nchildren's carol\nchildren's cartoon\nchildren's cha-cha-chá\nchildren's chant\nchildren's chiptune\nchildren's choir\nchildren's choir, eerie, music box\nchildren's choir, festive, Christmas\nchildren's choir, festive, synth orchestra\nchildren's choir, waltz, classical\nchildren's country\nchildren's country-folk\nchildren's country-funk\nchildren's country-gospel\nchildren's country-pop\nchildren's country-rock\nchildren's country-western\nchildren's cumbia\nchildren's cumbia rock\nchildren's cumbia-pop\nchildren's cumbia-reggaeton\nchildren's dance\nchildren's dance pop\nchildren's dance-pop\nchildren's dance-pop chiptune\nchildren's dance-pop, folk-pop\nchildren's devotional\nchildren's devotional pop\nchildren's devotional, South Asian\nchildren's devotional, South Asian folk\nchildren's devotional, South Asian, Middle Eastern\nchildren's disco\nchildren's disco-pop\nchildren's education\nchildren's educational\nchildren's educational pop\nchildren's educational, Eurodance, synth-pop\nchildren's educational, ambient, cinematic\nchildren's educational, cinematic, Chinese classical\nchildren's educational, cinematic, traditional Chinese\nchildren's electronic\nchildren's electronic dance\nchildren's electronic pop\nchildren's exercise\nchildren's fairytale\nchildren's film score\nchildren's fitness\nchildren's folk\nchildren's folk cabaret\nchildren's folk chiptune\nchildren's folk klezmer\nchildren's folk waltz\nchildren's folk, Latin cumbia\nchildren's folk, cabaret jazz\nchildren's folk, pop-gospel, funk\nchildren's folk, show tune, hip hop\nchildren's folk-country\nchildren's folk-gospel\nchildren's folk-pop\nchildren's folk-pop, Latin funk\nchildren's folk-pop, synth-pop, calypso\nchildren's folk-rock\nchildren's funk\nchildren's funk-pop\nchildren's game music\nchildren's game show\nchildren's gospel\nchildren's gospel chiptune\nchildren's gospel country\nchildren's gospel country-folk\nchildren's gospel country-pop\nchildren's gospel funk\nchildren's gospel funk soul\nchildren's gospel pop\nchildren's gospel pop-rock\nchildren's gospel ragtime\nchildren's gospel synth-pop\nchildren's hard rock\nchildren's hip-hop\nchildren's hip-hop funk\nchildren's hip-hop pop\nchildren's holiday\nchildren's horror\nchildren's hymn\nchildren's jazz\nchildren's jazz cabaret\nchildren's jazz funk\nchildren's jazz, synth-pop\nchildren's jazz-pop\nchildren's jazz-swing\nchildren's jingle\nchildren's jingle, theatrical ballad\nchildren's jive\nchildren's lullaby\nchildren's lullaby, Brazilian folk\nchildren's lullaby, klezmer, folk\nchildren's mambo\nchildren's march\nchildren's marching\nchildren's marching band\nchildren's meditation\nchildren's military march\nchildren's music\nchildren's music Indian film\nchildren's music Indian folk\nchildren's music Indian style\nchildren's music Latin\nchildren's music Latin pop\nchildren's music baroque\nchildren's music big band\nchildren's music boogie-woogie\nchildren's music boogie-woogie jazz\nchildren's music boogie-woogie rock\nchildren's music boogie-woogie show tune\nchildren's music boogie-woogie swing\nchildren's music bossa nova\nchildren's music box\nchildren's music cabaret\nchildren's music calypso\nchildren's music cartoon soundtrack\nchildren's music chamber\nchildren's music chiptune\nchildren's music circus\nchildren's music circus polka\nchildren's music classical\nchildren's music country-folk\nchildren's music cumbia\nchildren's music cumbia folk\nchildren's music cumbia ska\nchildren's music eurodance\nchildren's music flamenco\nchildren's music funk\nchildren's music funk disco\nchildren's music funk jazz\nchildren's music funk lounge\nchildren's music funk neo-soul\nchildren's music funk reggae\nchildren's music funk soul\nchildren's music funk-rock\nchildren's music gospel\nchildren's music gospel-pop lullaby\nchildren's music hip-hop\nchildren's music indie-pop\nchildren's music jazz\nchildren's music jazz orchestral\nchildren's music jazz swing\nchildren's music jazzy\nchildren's music klezmer\nchildren's music latin\nchildren's music latin groove\nchildren's music latin pop\nchildren's music lo-fi\nchildren's music mariachi\nchildren's music orchestral\nchildren's music orchestral pop\nchildren's music polka\nchildren's music punk rock\nchildren's music ragtime\nchildren's music reggae-pop\nchildren's music retro\nchildren's music retro Bollywood\nchildren's music retro MIDI\nchildren's music retro Soviet\nchildren's music retro big band\nchildren's music retro big-band\nchildren's music retro boogie-woogie\nchildren's music retro cartoon\nchildren's music retro doo-wop\nchildren's music retro electronic\nchildren's music retro funk\nchildren's music retro funk-reggae\nchildren's music retro jazz\nchildren's music retro klezmer\nchildren's music retro polka\nchildren's music retro pop\nchildren's music retro rock\nchildren's music retro show tune\nchildren's music retro space\nchildren's music retro swing\nchildren's music retro synth\nchildren's music retro video game\nchildren's music retro-futuristic\nchildren's music rockabilly\nchildren's music rockabilly boogie-woogie\nchildren's music samba\nchildren's music schlager\nchildren's music sea shanty\nchildren's music show tune\nchildren's music spiritual pop\nchildren's music surf rock\nchildren's music swing\nchildren's music swing jazz\nchildren's music tropical\nchildren's music vintage swing\nchildren's music world music\nchildren's music, 8-bit, upbeat\nchildren's music, 80s pop, Vietnamese pop\nchildren's music, 80s pop, indie-pop\nchildren's music, Arabic folk\nchildren's music, Arabic, synth pop\nchildren's music, Australian, pop\nchildren's music, Balkan folk, folk pop\nchildren's music, Balkan folk, polka\nchildren's music, Bollywood, synth pop\nchildren's music, Brazilian carnival\nchildren's music, Brazilian folk\nchildren's music, Brazilian folk-pop\nchildren's music, Brazilian folk-pop, polka\nchildren's music, Brazilian funk\nchildren's music, Brazilian funk carioca\nchildren's music, Brazilian funk, retro\nchildren's music, Brazilian march\nchildren's music, Brazilian pop\nchildren's music, Brazilian pop, 80s synth\nchildren's music, Brazilian pop, festive\nchildren's music, Brazilian pop, folk-pop\nchildren's music, Brazilian pop, retro-pop\nchildren's music, Brazilian pop, synth pop\nchildren's music, Brazilian, Afro-Latin\nchildren's music, Brazilian, accordion\nchildren's music, Brazilian, acoustic\nchildren's music, Brazilian, dance\nchildren's music, Brazilian, folk\nchildren's music, Brazilian, funk\nchildren's music, Brazilian, lo-fi\nchildren's music, Brazilian, playful\nchildren's music, Brazilian, pop\nchildren's music, Brazilian, retro synth\nchildren's music, Brazilian, samba\nchildren's music, Brazilian, synth pop\nchildren's music, Brazilian, upbeat\nchildren's music, C-pop, ambient\nchildren's music, C-pop, ambient pop\nchildren's music, C-pop, electronic\nchildren's music, C-pop, lo-fi\nchildren's music, C-pop, synth pop\nchildren's music, Celtic folk, synth pop\nchildren's music, Chinese New Year, festive\nchildren's music, Chinese New Year, festive pop\nchildren's music, Chinese New Year, pop\nchildren's music, Chinese New Year, synth pop\nchildren's music, Chinese New Year, upbeat\nchildren's music, Chinese folk\nchildren's music, Chinese folk, pop\nchildren's music, Chinese-style, educational\nchildren's music, Christmas, Italian pop\nchildren's music, Christmas, synth pop\nchildren's music, Dutch levenslied\nchildren's music, Dutch pop, polka\nchildren's music, Eastern European folk, synth pop\nchildren's music, Eurodance\nchildren's music, European folk\nchildren's music, European folk, polka\nchildren's music, French folk\nchildren's music, French pop, theatrical\nchildren's music, German folk, Schlager\nchildren's music, German folk, Western\nchildren's music, German folk, theatrical\nchildren's music, Halloween, cartoon\nchildren's music, Halloween, funk\nchildren's music, Halloween, playful\nchildren's music, Halloween, polka\nchildren's music, Halloween, synth orchestra\nchildren's music, Halloween, synth pop\nchildren's music, Halloween, theatrical\nchildren's music, Hawaiian pop\nchildren's music, Hawaiian pop, J-pop\nchildren's music, Indian classical, educational\nchildren's music, Indian classical, playful\nchildren's music, Indian film music\nchildren's music, Indian film music, synth pop\nchildren's music, Indian folk\nchildren's music, Indian folk, Bollywood\nchildren's music, Indian folk, synth pop\nchildren's music, Indian pop, educational\nchildren's music, Israeli folk-pop\nchildren's music, Italian film score, ragtime\nchildren's music, Italian film score, vintage pop\nchildren's music, Italian folk\nchildren's music, Italian folk, dance\nchildren's music, Italian folk, festive\nchildren's music, Italian folk, polka\nchildren's music, Italian folk, tarantella\nchildren's music, Italian pop, festive\nchildren's music, Italian pop, synth pop\nchildren's music, Italian, Western\nchildren's music, Italian, circus pop\nchildren's music, Italian, pirate pop\nchildren's music, Italian, polka\nchildren's music, Italian, retro film score\nchildren's music, Italian, vintage\nchildren's music, Italo disco\nchildren's music, J-pop\nchildren's music, J-pop, show tune\nchildren's music, Japanese, theatrical\nchildren's music, K-pop, chiptune\nchildren's music, K-pop, educational\nchildren's music, K-pop, synth pop\nchildren's music, Latin acoustic\nchildren's music, Latin cumbia\nchildren's music, Latin cumbia, synth pop\nchildren's music, Latin electronic\nchildren's music, Latin folk\nchildren's music, Latin folk, Turkish folk\nchildren's music, Latin folk, cumbia\nchildren's music, Latin folk, polka\nchildren's music, Latin funk\nchildren's music, Latin groove\nchildren's music, Latin march\nchildren's music, Latin percussion\nchildren's music, Latin pop\nchildren's music, Latin pop, Brazilian\nchildren's music, Latin pop, Caribbean\nchildren's music, Latin pop, Christmas\nchildren's music, Latin pop, Italian folk\nchildren's music, Latin pop, K-pop\nchildren's music, Latin pop, calypso\nchildren's music, Latin pop, cartoon\nchildren's music, Latin pop, chiptune\nchildren's music, Latin pop, cumbia\nchildren's music, Latin pop, disco\nchildren's music, Latin pop, educational\nchildren's music, Latin pop, electronic\nchildren's music, Latin pop, festive\nchildren's music, Latin pop, flamenco\nchildren's music, Latin pop, folk\nchildren's music, Latin pop, mariachi\nchildren's music, Latin pop, show tune\nchildren's music, Latin pop, synth pop\nchildren's music, Latin pop, theatrical\nchildren's music, Latin pop, tropical\nchildren's music, Latin pop, upbeat\nchildren's music, Latin pop, video game music\nchildren's music, Latin pop, vintage\nchildren's music, Latin rhythm\nchildren's music, Latin, Caribbean\nchildren's music, Latin, Italian\nchildren's music, Latin, J-pop\nchildren's music, Latin, Middle Eastern\nchildren's music, Latin, bossa nova\nchildren's music, Latin, cha-cha-cha\nchildren's music, Latin, cumbia\nchildren's music, Latin, educational\nchildren's music, Latin, exotica\nchildren's music, Latin, flamenco\nchildren's music, Latin, honky-tonk\nchildren's music, Latin, klezmer\nchildren's music, Latin, mambo\nchildren's music, Latin, playful\nchildren's music, Latin, samba\nchildren's music, Latin, sea shanty\nchildren's music, Latin, theatrical\nchildren's music, Latin, upbeat\nchildren's music, Latin, world music\nchildren's music, MIDI, Vocaloid\nchildren's music, MIDI, educational\nchildren's music, MPB, chiptune\nchildren's music, Mediterranean folk\nchildren's music, Middle Eastern folk, synth pop\nchildren's music, Middle Eastern pop\nchildren's music, Middle Eastern, educational\nchildren's music, Middle Eastern, electronic\nchildren's music, Middle Eastern, synth pop\nchildren's music, Portuguese folk, polka\nchildren's music, Portuguese folk, upbeat pop\nchildren's music, Russian folk, polka\nchildren's music, Schlager, synth pop\nchildren's music, South Asian folk\nchildren's music, South Asian pop, playful pop\nchildren's music, South Asian, Middle Eastern\nchildren's music, South Asian, dance\nchildren's music, South Asian, playful\nchildren's music, South Indian film music\nchildren's music, South Indian film music, playful\nchildren's music, South Indian film music, synth pop\nchildren's music, South Indian folk, pop\nchildren's music, South Indian folk, upbeat\nchildren's music, South Indian, pop\nchildren's music, Spanish folk, Catalan\nchildren's music, Spanish folk, polka\nchildren's music, Spanish pop, playful\nchildren's music, Turkish folk, educational\nchildren's music, Vietnamese folk\nchildren's music, Vietnamese folk, festive\nchildren's music, Vietnamese pop\nchildren's music, Vietnamese pop, festive\nchildren's music, Vocaloid\nchildren's music, Vocaloid, anime\nchildren's music, Western, theatrical\nchildren's music, acoustic folk\nchildren's music, ambient, cinematic\nchildren's music, big band\nchildren's music, big band swing\nchildren's music, big band, Italian\nchildren's music, big band, cartoon\nchildren's music, big band, circus\nchildren's music, big band, mambo\nchildren's music, big band, playful\nchildren's music, big band, show tune\nchildren's music, big band, swing\nchildren's music, big band, theatrical\nchildren's music, big band, vintage\nchildren's music, big band, vintage cartoon\nchildren's music, big-band jazz\nchildren's music, bilingual, educational\nchildren's music, bilingual, electronic\nchildren's music, bilingual, pop\nchildren's music, bilingual, synth pop\nchildren's music, boogie-woogie\nchildren's music, boogie-woogie, Italian\nchildren's music, boogie-woogie, J-pop\nchildren's music, boogie-woogie, acoustic ballad\nchildren's music, boogie-woogie, country-folk\nchildren's music, boogie-woogie, polka\nchildren's music, boogie-woogie, ragtime\nchildren's music, boogie-woogie, rock and roll\nchildren's music, boogie-woogie, show tune\nchildren's music, boogie-woogie, surf rock\nchildren's music, boogie-woogie, swing\nchildren's music, boogie-woogie, swing jazz\nchildren's music, boogie-woogie, theatrical\nchildren's music, bossa nova\nchildren's music, bossa nova, world music\nchildren's music, cabaret, klezmer\nchildren's music, calypso\nchildren's music, calypso, reggae\nchildren's music, calypso, tropical\nchildren's music, chiptune\nchildren's music, chiptune, Arabic pop\nchildren's music, chiptune, Brazilian\nchildren's music, chiptune, Brazilian pop\nchildren's music, chiptune, C-pop\nchildren's music, chiptune, Halloween\nchildren's music, chiptune, Latin pop\nchildren's music, chiptune, early 2000s C-pop\nchildren's music, chiptune, educational\nchildren's music, chiptune, electronic\nchildren's music, chiptune, festive\nchildren's music, chiptune, folk\nchildren's music, chiptune, patriotic\nchildren's music, chiptune, pop\nchildren's music, chiptune, reggae-pop\nchildren's music, chiptune, retro\nchildren's music, chiptune, retro synth\nchildren's music, chiptune, synth pop\nchildren's music, cinematic orchestral\nchildren's music, cinematic pop, theatrical\nchildren's music, cinematic, cartoon\nchildren's music, cinematic, narrative\nchildren's music, circus folk\nchildren's music, circus, polka\nchildren's music, country folk\nchildren's music, country, bluegrass\nchildren's music, country-western\nchildren's music, country-western, rockabilly\nchildren's music, cumbia\nchildren's music, cumbia, French pop\nchildren's music, cumbia, German pop\nchildren's music, cumbia, Halloween\nchildren's music, cumbia, Latin\nchildren's music, cumbia, Latin folk\nchildren's music, cumbia, Latin pop\nchildren's music, cumbia, baroque\nchildren's music, cumbia, chiptune\nchildren's music, cumbia, electronic\nchildren's music, cumbia, festive\nchildren's music, cumbia, folk\nchildren's music, cumbia, forró\nchildren's music, cumbia, lo-fi\nchildren's music, cumbia, lullaby\nchildren's music, cumbia, mariachi\nchildren's music, cumbia, merengue\nchildren's music, cumbia, novelty\nchildren's music, cumbia, samba\nchildren's music, cumbia, ska\nchildren's music, cumbia, synth pop\nchildren's music, cumbia, theatrical\nchildren's music, cumbia-pop\nchildren's music, cumbia-pop, surf rock\nchildren's music, dance, Vietnamese pop\nchildren's music, dance-pop, theatrical\nchildren's music, disco, funk\nchildren's music, disco-pop\nchildren's music, doo-wop, retro\nchildren's music, dream pop\nchildren's music, early jazz, Dixieland\nchildren's music, educational, Latin pop\nchildren's music, educational, Spanish\nchildren's music, educational, electronic\nchildren's music, educational, folk\nchildren's music, educational, pop\nchildren's music, educational, synth pop\nchildren's music, eerie, lo-fi\nchildren's music, electronic\nchildren's music, electronic pop\nchildren's music, electronic, Chinese New Year\nchildren's music, electronic, Hindi pop\nchildren's music, electronic, Indian\nchildren's music, electronic, Indian folk\nchildren's music, electronic, Indian pop\nchildren's music, electronic, Latin\nchildren's music, electronic, Latin pop\nchildren's music, electronic, Middle Eastern\nchildren's music, electronic, Romanian folk\nchildren's music, electronic, Vietnamese pop\nchildren's music, electronic, Vocaloid\nchildren's music, electronic, adult contemporary\nchildren's music, electronic, carnival\nchildren's music, electronic, chiptune\nchildren's music, electronic, educational\nchildren's music, electronic, funk\nchildren's music, electronic, pop\nchildren's music, electronic, quirky\nchildren's music, eurodance\nchildren's music, eurodance, happy hardcore\nchildren's music, festive pop\nchildren's music, festive pop, lullaby\nchildren's music, festive, Chinese pop\nchildren's music, festive, German Weihnachtslied\nchildren's music, festive, Latin pop\nchildren's music, festive, Spanish\nchildren's music, festive, Vietnamese\nchildren's music, festive, Vietnamese pop\nchildren's music, festive, accordion\nchildren's music, festive, holiday\nchildren's music, festive, klezmer-inspired\nchildren's music, festive, orchestral\nchildren's music, festive, pop\nchildren's music, festive, synth pop\nchildren's music, festive, waltz\nchildren's music, flamenco pop\nchildren's music, flamenco, French pop\nchildren's music, flamenco, Latin\nchildren's music, flamenco, Spanish folk\nchildren's music, folk\nchildren's music, folk pop\nchildren's music, folk, Latin\nchildren's music, folk, festive\nchildren's music, folk, klezmer\nchildren's music, folk, polka\nchildren's music, folk, vintage European\nchildren's music, folk-pop\nchildren's music, folk-pop, Latin pop\nchildren's music, folk-pop, indie-folk\nchildren's music, football, playful\nchildren's music, forró, ambient\nchildren's music, forró, baião\nchildren's music, forró, chiptune\nchildren's music, forró, synth pop\nchildren's music, funk\nchildren's music, funk pop\nchildren's music, funk, disco\nchildren's music, funk, educational\nchildren's music, funk, electronic\nchildren's music, funk, jazz\nchildren's music, funk, retro\nchildren's music, funk, ska\nchildren's music, funk, synth pop\nchildren's music, funk, synth-pop\nchildren's music, funk, theatrical\nchildren's music, funk, video game\nchildren's music, funky electronic\nchildren's music, gypsy jazz, western\nchildren's music, hardstyle, ragtime\nchildren's music, holiday, German folk\nchildren's music, holiday, electronic\nchildren's music, honky-tonk, Western\nchildren's music, indie-pop, Latin\nchildren's music, jazz\nchildren's music, jazz, pop\nchildren's music, jazz, theatrical\nchildren's music, jazzy boogie-woogie, pop, hip-hop\nchildren's music, karaoke, MIDI\nchildren's music, klezmer\nchildren's music, klezmer, Balkan pop\nchildren's music, klezmer, Eastern European folk\nchildren's music, klezmer, European folk\nchildren's music, klezmer, Israeli folk\nchildren's music, klezmer, big band\nchildren's music, klezmer, folk\nchildren's music, klezmer, polka\nchildren's music, lo-fi, Brazilian\nchildren's music, lo-fi, Halloween\nchildren's music, lo-fi, Vocaloid\nchildren's music, lo-fi, brass band\nchildren's music, lo-fi, video game music\nchildren's music, mambo\nchildren's music, mambo, big band\nchildren's music, mambo, salsa\nchildren's music, marching band, polka\nchildren's music, marchinha, Brazilian carnival\nchildren's music, mariachi\nchildren's music, mariachi, Latin\nchildren's music, musette, jazz\nchildren's music, new jack swing\nchildren's music, new jack swing, gospel\nchildren's music, novelty pop\nchildren's music, novelty, Halloween\nchildren's music, orchestral pop\nchildren's music, orchestral, C-pop\nchildren's music, pirate theme, polka\nchildren's music, playful, cinematic\nchildren's music, polka\nchildren's music, polka, Eastern European folk\nchildren's music, polka, European folk\nchildren's music, polka, German\nchildren's music, polka, German folk\nchildren's music, polka, Halloween\nchildren's music, polka, Russian folk\nchildren's music, polka, circus\nchildren's music, polka, educational\nchildren's music, polka, folk\nchildren's music, polka, folk dance\nchildren's music, polka, forró\nchildren's music, polka, pirate theme\nchildren's music, polka, sea shanty\nchildren's music, polka, synth pop\nchildren's music, polka, theatrical\nchildren's music, pop\nchildren's music, pop, Asian fusion\nchildren's music, pop, Chinese traditional\nchildren's music, pop, Latin\nchildren's music, pop, bilingual\nchildren's music, pop, educational\nchildren's music, pop, electronic\nchildren's music, pop, funk\nchildren's music, pop, theatrical\nchildren's music, pop, world\nchildren's music, pop-rock\nchildren's music, pop-rock, electronic\nchildren's music, pop-rock, funk\nchildren's music, pop-rock, orchestral\nchildren's music, punk rock, free jazz\nchildren's music, quirky pop, fantasy\nchildren's music, ragtime\nchildren's music, ragtime, Italian\nchildren's music, ragtime, boogie-woogie\nchildren's music, ragtime, cartoon\nchildren's music, ragtime, educational\nchildren's music, ragtime, folk\nchildren's music, ragtime, honky-tonk\nchildren's music, ragtime, lo-fi\nchildren's music, ragtime, musical theater\nchildren's music, ragtime, show tune\nchildren's music, ragtime, theatrical\nchildren's music, ragtime, vintage\nchildren's music, ragtime, vintage cartoon\nchildren's music, reggaeton-lite\nchildren's music, retro Italian, vintage cartoon\nchildren's music, retro MIDI\nchildren's music, retro MIDI, Indonesian pop\nchildren's music, retro MIDI, Vietnamese pop\nchildren's music, retro Mandopop\nchildren's music, retro funk\nchildren's music, retro funk, J-pop\nchildren's music, retro pop\nchildren's music, retro pop, Israeli pop\nchildren's music, retro pop, Soviet pop\nchildren's music, retro pop, Soviet-era\nchildren's music, retro pop, big band\nchildren's music, retro synth\nchildren's music, retro synth, 2000s video game\nchildren's music, retro synth, 80s pop\nchildren's music, retro synth, 90s VHS\nchildren's music, retro synth, 90s pop\nchildren's music, retro synth, 90s video game\nchildren's music, retro synth, C-pop\nchildren's music, retro synth, Cantopop\nchildren's music, retro synth, Christmas\nchildren's music, retro synth, French pop\nchildren's music, retro synth, K-pop\nchildren's music, retro synth, MIDI\nchildren's music, retro synth, MIDI pop\nchildren's music, retro synth, Vietnamese\nchildren's music, retro synth, Vietnamese folk\nchildren's music, retro synth, Vietnamese pop\nchildren's music, retro synth, Vocaloid\nchildren's music, retro synth, cartoon pop\nchildren's music, retro synth, early 2000s\nchildren's music, retro synth, early 2000s C-pop\nchildren's music, retro synth, early digital\nchildren's music, retro synth, educational\nchildren's music, retro synth, lo-fi\nchildren's music, retro synth, pop\nchildren's music, retro synth, video game\nchildren's music, retro synth, video game music\nchildren's music, retro video game\nchildren's music, retro video game, C-pop\nchildren's music, retro video game, Latin pop\nchildren's music, retro video game, chiptune\nchildren's music, retro video game, educational\nchildren's music, retro video game, quirky pop\nchildren's music, retro video game, synth pop\nchildren's music, retro video game, theatrical\nchildren's music, retro, Italo disco\nchildren's music, retro, MIDI\nchildren's music, retro, Neue Deutsche Welle\nchildren's music, retro, Soviet cartoon\nchildren's music, retro, cartoon\nchildren's music, retro, estrada\nchildren's music, retro, surf rock\nchildren's music, rockabilly\nchildren's music, rockabilly, show tune\nchildren's music, rockabilly, surf rock\nchildren's music, rockabilly, techno-pop, country-western, funk\nchildren's music, salsa, big band\nchildren's music, samba\nchildren's music, samba, Brazilian\nchildren's music, samba, acoustic\nchildren's music, samba, bossa nova\nchildren's music, samba, carnival\nchildren's music, samba, video game music\nchildren's music, samba-pop, bossa nova\nchildren's music, samba-reggae, Brazilian carnival\nchildren's music, satirical pop\nchildren's music, schlager\nchildren's music, schlager, polka\nchildren's music, sea shanty, cartoon\nchildren's music, sea shanty, festive\nchildren's music, sea shanty, folk pop\nchildren's music, sea shanty, polka\nchildren's music, sea shanty, synth folk\nchildren's music, sea shanty, theatrical\nchildren's music, show tune\nchildren's music, show tune, Chinese folk\nchildren's music, show tune, Halloween\nchildren's music, show tune, Italian\nchildren's music, show tune, Japanese\nchildren's music, show tune, educational\nchildren's music, show tune, festive\nchildren's music, show tune, kawaii pop\nchildren's music, show tune, pop\nchildren's music, show tune, ragtime\nchildren's music, show tune, vintage\nchildren's music, show tune, vintage Japanese\nchildren's music, soca\nchildren's music, spooky pop\nchildren's music, spooky pop, cumbia\nchildren's music, spooky, polka\nchildren's music, surf rock, vintage cartoon\nchildren's music, swing, big band\nchildren's music, swing, boogie-woogie\nchildren's music, synth orchestral, dark pop\nchildren's music, synth pop\nchildren's music, synth pop, Brazilian\nchildren's music, synth pop, Chinese pop\nchildren's music, synth pop, Chinese traditional\nchildren's music, synth pop, Ukrainian\nchildren's music, synth pop, Vietnamese\nchildren's music, synth pop, Vocaloid\nchildren's music, synth pop, big band\nchildren's music, synth pop, big band jazz\nchildren's music, synth pop, cumbia\nchildren's music, synth pop, eerie\nchildren's music, synth pop, festive\nchildren's music, synth pop, funk rock\nchildren's music, synth pop, holiday\nchildren's music, synth pop, theatrical\nchildren's music, synth-pop\nchildren's music, synth-pop, Brazilian\nchildren's music, synth-pop, East Asian\nchildren's music, synth-pop, Islamic\nchildren's music, synth-pop, R&B-pop\nchildren's music, synth-pop, Russian folk\nchildren's music, synth-pop, festive\nchildren's music, synth-pop, folk-pop\nchildren's music, synth-pop, holiday\nchildren's music, synth-pop, lullaby\nchildren's music, synth-pop, pop-rock\nchildren's music, synth-pop, retro MIDI\nchildren's music, synth-pop, samba\nchildren's music, synth-pop, swing\nchildren's music, synth-pop, video game music\nchildren's music, synth-pop, world music\nchildren's music, tango, Latin\nchildren's music, tarantella\nchildren's music, tarantella, polka\nchildren's music, tarantella, synth pop\nchildren's music, theatrical pop\nchildren's music, theatrical pop, Halloween\nchildren's music, theatrical pop, a cappella\nchildren's music, theatrical pop, magical\nchildren's music, theatrical pop, synth-pop\nchildren's music, theatrical, Halloween\nchildren's music, theatrical, Italian\nchildren's music, theatrical, accordion\nchildren's music, theatrical, cabaret\nchildren's music, theatrical, cartoon\nchildren's music, theatrical, jazz\nchildren's music, theatrical, polka\nchildren's music, theatrical, vintage\nchildren's music, theatrical, vintage Italian\nchildren's music, theatrical, whimsical\nchildren's music, traditional Chinese folk\nchildren's music, traditional Chinese, electronic\nchildren's music, traditional Chinese, pentatonic\nchildren's music, tropical house, video game\nchildren's music, tropical pop, festive\nchildren's music, upbeat, patriotic\nchildren's music, video game music\nchildren's music, video game music, playful\nchildren's music, video game music, playful pop\nchildren's music, video game music, quirky pop\nchildren's music, video game music, synth pop\nchildren's music, video game soundtrack\nchildren's music, video game soundtrack, French pop\nchildren's music, video game soundtrack, chiptune\nchildren's music, video game soundtrack, orchestral pop\nchildren's music, video game soundtrack, playful\nchildren's music, video game soundtrack, synth pop\nchildren's music, video game soundtrack, whimsical\nchildren's music, video game, C-pop\nchildren's music, video game, K-pop\nchildren's music, video game, anime\nchildren's music, video game, lo-fi pop\nchildren's music, video game, playful\nchildren's music, video game, synth pop\nchildren's music, video game, tropical\nchildren's music, vintage European, big band\nchildren's music, vintage Italian cartoon, honky-tonk\nchildren's music, vintage Italian film score\nchildren's music, vintage pop, French chanson\nchildren's music, vintage pop, showtime\nchildren's music, vintage swing, Italian style\nchildren's music, vintage, theatrical\nchildren's music, whimsical, French folk\nchildren's music, whimsical, eerie\nchildren's music, world music, French pop\nchildren's music, world music, German folk\nchildren's musical\nchildren's musical theater\nchildren's musical theatre\nchildren's narrative\nchildren's novelty\nchildren's novelty chiptune\nchildren's novelty cumbia\nchildren's novelty polka\nchildren's novelty rock\nchildren's novelty, rock and roll, doo-wop\nchildren's party\nchildren's patriotic march\nchildren's pirate\nchildren's pirate music\nchildren's pirate polka\nchildren's pirate pop\nchildren's pirate rock\nchildren's pirate, theatrical, synth-pop\nchildren's polka\nchildren's polka mariachi\nchildren's pop\nchildren's pop Afrobeat\nchildren's pop C-pop\nchildren's pop C-pop chiptune\nchildren's pop J-pop\nchildren's pop K-pop\nchildren's pop Latin\nchildren's pop R&B\nchildren's pop anime\nchildren's pop boogie-woogie\nchildren's pop bossa nova\nchildren's pop cabaret\nchildren's pop calypso\nchildren's pop chiptune\nchildren's pop country\nchildren's pop country-folk\nchildren's pop dangdut koplo\nchildren's pop disco-funk\nchildren's pop eurodance\nchildren's pop folk\nchildren's pop folk-country\nchildren's pop funk\nchildren's pop funk disco\nchildren's pop gospel\nchildren's pop hip-hop\nchildren's pop jazz\nchildren's pop polka\nchildren's pop punk\nchildren's pop reggae\nchildren's pop reggae ska\nchildren's pop reggae-pop\nchildren's pop reggaeton\nchildren's pop retro Mandopop\nchildren's pop retro funk\nchildren's pop retro funk disco\nchildren's pop rock\nchildren's pop schlager\nchildren's pop ska\nchildren's pop ska reggae\nchildren's pop surf-rock\nchildren's pop trap\nchildren's pop world music\nchildren's pop, 90s Eurodance, retro Vietnamese\nchildren's pop, Balkan folk, synth pop\nchildren's pop, Bollywood\nchildren's pop, Bollywood, electronic\nchildren's pop, Brazilian funk carioca\nchildren's pop, Dutch, Middle Eastern\nchildren's pop, EDM\nchildren's pop, EDM, hip-hop\nchildren's pop, Eurodance\nchildren's pop, Italo-disco\nchildren's pop, J-pop, Dutch pop\nchildren's pop, K-pop\nchildren's pop, Latin cumbia\nchildren's pop, Latin dance\nchildren's pop, Latin pop\nchildren's pop, Latin pop, cumbia\nchildren's pop, Latin pop, electronic\nchildren's pop, Latin pop, theatrical\nchildren's pop, Latin pop, tropical\nchildren's pop, MPB\nchildren's pop, alternative rock\nchildren's pop, chiptune\nchildren's pop, chiptune, J-pop\nchildren's pop, dance-pop\nchildren's pop, folk-pop, synth-pop\nchildren's pop, funk-pop, synth-pop\nchildren's pop, inspirational pop-rock\nchildren's pop, lullaby\nchildren's pop, piano ballad, novelty music\nchildren's pop, pop-rock, praise and worship, funk-pop, lullaby\nchildren's pop, retro dance-pop\nchildren's pop, retro disco\nchildren's pop, retro funk, disco\nchildren's pop, retro synth\nchildren's pop, schlager\nchildren's pop, synth-pop\nchildren's pop, synth-pop, spy theme\nchildren's pop, theatrical rock\nchildren's pop-folk\nchildren's pop-funk\nchildren's pop-gospel\nchildren's pop-punk\nchildren's pop-rap\nchildren's pop-reggae\nchildren's pop-rock\nchildren's pop-rock, funk\nchildren's praise\nchildren's praise pop-rock\nchildren's praise, Brazilian, upbeat\nchildren's praise, Latin, cumbia\nchildren's praise, chiptune\nchildren's praise, cumbia\nchildren's praise, new jack swing\nchildren's praise, retro funk-pop\nchildren's praise, retro video game\nchildren's praise, world music\nchildren's protest\nchildren's rap\nchildren's reggae\nchildren's reggae ska\nchildren's reggae-ska\nchildren's reggaeton\nchildren's religious\nchildren's revolutionary\nchildren's rock\nchildren's rock and roll\nchildren's rock country-rock\nchildren's rock opera\nchildren's rock ska\nchildren's rock-pop\nchildren's rockabilly\nchildren's salsa\nchildren's samba\nchildren's schlager\nchildren's sea shanty\nchildren's show theme\nchildren's show tune\nchildren's show tune boogie-woogie\nchildren's spiritual\nchildren's spooky\nchildren's square dance\nchildren's story\nchildren's story, whimsical, fairytale\nchildren's story-song\nchildren's storytelling\nchildren's superhero\nchildren's swing\nchildren's swing jazz\nchildren's synth pop\nchildren's synth-pop\nchildren's synth-pop, reggae dub\nchildren's tango\nchildren's theater\nchildren's theme\nchildren's trap\nchildren's ukulele pop\nchildren's waltz\nchildren's world music\nchildren's worship\nchildren's worship pop-rock\nchildren's worship synth-pop\nchilena\nchill Afrobeats\nchill C-pop\nchill C-pop lo-fi hip-hop\nchill French rap\nchill Latin\nchill Mandopop\nchill R&B\nchill R&B French pop\nchill R&B city pop\nchill R&B future bass\nchill R&B hip-hop\nchill R&B lo-fi\nchill R&B lo-fi hip hop\nchill R&B lo-fi hip-hop\nchill R&B lo-fi pop\nchill R&B trap\nchill R&B trap-soul\nchill R&B trap-soul Mandopop\nchill R&B, French pop, lo-fi hip hop\nchill R&B, future bass, glitch-hop\nchill R&B, lo-fi hip-hop\nchill R&B, lo-fi hip-hop, dream pop\nchill R&B, trap-soul, ambient\nchill afrobeat\nchill afrobeats\nchill bossa nova\nchill dance-pop\nchill drill\nchill drum and bass\nchill electronic\nchill electronic pop\nchill folk\nchill funk\nchill groove\nchill groovy\nchill groovy instrumental\nchill hip hop\nchill hip-hop\nchill hip-hop ambient pop\nchill hip-hop future bass\nchill hip-hop reggae\nchill hip-hop, city-pop, chiptune\nchill hip-hop, psychedelic pop\nchill hop\nchill house\nchill house future bass\nchill house lo-fi house\nchill house lounge\nchill house tropical house\nchill instrumental\nchill jazz\nchill jazz hop\nchill jazz lounge\nchill jazz lounge, funk rock\nchill lo-fi\nchill lounge\nchill neo-soul\nchill pop\nchill pop future bass\nchill pop lo-fi R&B\nchill pop lounge\nchill pop reggaeton\nchill pop, R&B, future bass\nchill pop-rap\nchill rap\nchill reggae\nchill reggaeton\nchill soul\nchill trap\nchill trap C-pop\nchill trap R&B\nchill trap ambient\nchill trap ambient R&B\nchill trap cloud rap\nchill trap future bass\nchill trap lo-fi\nchill trap lo-fi hip hop\nchill trap lo-fi hip-hop\nchill trap soul\nchill trap vaporwave\nchill trap, C-pop\nchill trap, C-pop, R&B\nchill trap, French cloud rap\nchill trap, French pop-rap\nchill trap, German cloud rap, lo-fi hip hop\nchill trap, Greek hip-hop\nchill trap, Latin R&B\nchill trap, Latin rap\nchill trap, R&B\nchill trap, R&B, Latin urban\nchill trap, R&B, Mandopop\nchill trap, R&B, atmospheric pop\nchill trap, R&B, dream pop\nchill trap, R&B, lo-fi\nchill trap, alternative R&B, dream pop\nchill trap, alternative R&B, lo-fi hip-hop\nchill trap, chiptune\nchill trap, cloud rap\nchill trap, cloud rap, C-pop\nchill trap, cloud rap, Mandopop\nchill trap, cloud rap, atmospheric R&B\nchill trap, cloud rap, lo-fi hip-hop\nchill trap, dream pop\nchill trap, dream pop, R&B\nchill trap, lo-fi hip hop\nchill trap, lo-fi hip hop, R&B\nchill trap, lo-fi hip hop, atmospheric pop\nchill trap, lo-fi hip hop, pop-rap\nchill trap, lo-fi hip-hop\nchill trap, lo-fi hip-hop, C-pop\nchill trap, lo-fi hip-hop, German R&B\nchill trap, lo-fi hip-hop, cloud rap\nchill trap, melodic R&B\nchill trap, melodic hip-hop\nchill trap, phonk, cloud rap\nchill trap, pop-rap\nchill trap, pop-rap, atmospheric electronic\nchill trap, progressive house\nchill trap, romantic C-pop\nchill trap, vaporwave, chiptune\nchill trap-pop\nchill wave\nchill wave, funk, lo-fi hip hop\nchill-hop\nchill-hop C-pop\nchill-hop R&B\nchill-hop cloud rap\nchill-hop dancehall\nchill-hop indie pop\nchill-hop lo-fi\nchill-hop melodic trap\nchill-hop neo-soul\nchill-hop party rap\nchill-hop trap\nchill-hop, Filipino R&B\nchill-hop, Southern hip-hop\nchill-hop, Southern rap\nchill-hop, West Coast hip-hop\nchill-hop, alternative R&B\nchill-hop, cloud rap\nchill-hop, conscious hip-hop\nchill-hop, emotional pop-rap\nchill-hop, lo-fi hip hop, modern R&B\nchill-hop, modern R&B\nchill-hop, pop-rap\nchill-hop, psychedelic R&B\nchill-hop, vaporwave, boom-bap\nchill-out\nchill-out fusion\nchill-out world music\nchill-pop\nchill-pop ambient\nchill-pop city pop\nchill-pop lo-fi\nchill-pop lo-fi R&B\nchill-pop lo-fi hip hop\nchill-pop lo-fi hip-hop\nchill-pop lo-fi pop\nchill-pop neo-soul\nchill-trap\nchillena\nchillhop\nchillhop 90s R&B video game\nchillhop C-pop\nchillhop C-pop lo-fi hip hop\nchillhop Dutch hip-hop\nchillhop Mandopop R&B\nchillhop R&B\nchillhop R&B lo-fi\nchillhop R&B lo-fi hip hop\nchillhop acoustic hip-hop\nchillhop acoustic pop\nchillhop acoustic rap\nchillhop ambient\nchillhop ambient pop\nchillhop boom-bap\nchillhop bossa nova\nchillhop cinematic\nchillhop cloud rap\nchillhop conscious hip-hop\nchillhop downtempo\nchillhop dream pop\nchillhop dream-pop\nchillhop emo rap\nchillhop funk lounge\nchillhop future bass\nchillhop hip-hop\nchillhop indie R&B\nchillhop indie pop\nchillhop indie rock\nchillhop jazz rap\nchillhop jazz-hop\nchillhop jazz-rap\nchillhop jazzy R&B\nchillhop latin\nchillhop lo-fi\nchillhop lo-fi Afro-fusion\nchillhop lo-fi chiptune\nchillhop lo-fi cinematic\nchillhop lo-fi downtempo\nchillhop lo-fi funk\nchillhop lo-fi guzheng\nchillhop lo-fi hip hop\nchillhop lo-fi hip hop dream pop\nchillhop lo-fi hip hop future bass\nchillhop lo-fi hip-hop\nchillhop lo-fi hip-hop C-pop\nchillhop lo-fi hip-hop R&B\nchillhop lo-fi hip-hop ambient\nchillhop lo-fi hip-hop neo-soul\nchillhop lo-fi jazz\nchillhop lo-fi video game\nchillhop lounge\nchillhop lounge smooth jazz\nchillhop mandopop\nchillhop mandopop r&b\nchillhop neo-soul\nchillhop neo-soul experimental\nchillhop neo-soul jazz\nchillhop nu-jazz\nchillhop nu-jazz lounge\nchillhop phonk\nchillhop pop-rap\nchillhop reggae\nchillhop rock\nchillhop smooth jazz\nchillhop smooth jazz lounge\nchillhop trap\nchillhop vaporwave\nchillhop world music\nchillhop, Arabic hip-hop\nchillhop, Brazilian hip-hop\nchillhop, Brazilian pop\nchillhop, Brazilian rap\nchillhop, C-pop\nchillhop, C-pop rap\nchillhop, C-pop, lo-fi hip hop\nchillhop, Chinese-style hip-hop\nchillhop, Christian hip-hop\nchillhop, Filipino R&B\nchillhop, French cloud rap\nchillhop, French hip-hop\nchillhop, French pop-rap, neo-soul\nchillhop, French rap\nchillhop, German conscious rap\nchillhop, J-pop\nchillhop, J-pop, emotional R&B\nchillhop, J-pop, lo-fi hip hop\nchillhop, K-R&B, lo-fi hip hop\nchillhop, Latin R&B\nchillhop, Latin acoustic, cinematic\nchillhop, Punjabi pop\nchillhop, R&B\nchillhop, R&B, Mandopop\nchillhop, R&B, Turkish music\nchillhop, R&B, acoustic pop\nchillhop, R&B, dreamy pop\nchillhop, R&B, lo-fi hip hop\nchillhop, R&B, lo-fi hip-hop\nchillhop, Russian rap\nchillhop, UK rap\nchillhop, UK rap, lo-fi hip hop\nchillhop, acoustic pop, dreamy pop\nchillhop, alternative R&B\nchillhop, alternative R&B, cosmic hip-hop\nchillhop, ambient, traditional Chinese\nchillhop, chiptune, lo-fi hip hop\nchillhop, cinematic, C-pop\nchillhop, cinematic, ambient\nchillhop, cloud rap\nchillhop, cloud rap, lo-fi hip-hop\nchillhop, conscious R&B\nchillhop, conscious hip-hop\nchillhop, conscious hip-hop, Latin guitar\nchillhop, conscious hip-hop, lo-fi\nchillhop, conscious hip-hop, lo-fi hip hop\nchillhop, conscious hip-hop, neo-soul\nchillhop, conscious hip-hop, soulful R&B\nchillhop, conscious rap, emo-rap\nchillhop, downtempo, ambient\nchillhop, downtempo, traditional Chinese\nchillhop, dream pop\nchillhop, dream pop, lo-fi hip hop\nchillhop, easy-listening\nchillhop, emo rap\nchillhop, emotional C-pop rap\nchillhop, emotional R&B\nchillhop, hip-hop, lo-fi\nchillhop, indie R&B, lo-fi hip hop\nchillhop, indie pop\nchillhop, indie pop, J-pop\nchillhop, lo-fi R&B, neo-soul\nchillhop, lo-fi hip hop\nchillhop, lo-fi hip hop, Latin guitar\nchillhop, lo-fi hip hop, R&B\nchillhop, lo-fi hip hop, chiptune\nchillhop, lo-fi hip hop, cinematic\nchillhop, lo-fi hip hop, melancholic R&B\nchillhop, lo-fi hip hop, melodic rap\nchillhop, lo-fi hip hop, romantic R&B\nchillhop, lo-fi hip-hop\nchillhop, lo-fi hip-hop, C-pop\nchillhop, lo-fi hip-hop, Chinese traditional\nchillhop, lo-fi hip-hop, R&B\nchillhop, melodic rap\nchillhop, melodic rap, R&B\nchillhop, neo-classical, ambient\nchillhop, neo-soul\nchillhop, neo-soul, R&B\nchillhop, neo-soul, alternative rock\nchillhop, neo-soul, ambient\nchillhop, neo-soul, jazz rap\nchillhop, neo-soul, lo-fi hip hop\nchillhop, neo-soul, lo-fi hip-hop\nchillhop, nu-disco, lo-fi\nchillhop, psychedelic R&B, conscious hip-hop\nchillhop, psychedelic hip-hop, neo-soul\nchillhop, romantic pop-rap\nchillhop, sad pop\nchillhop, soulful R&B\nchillhop, trip-hop, ambient\nchillhop, vaporwave, R&B\nchillhop, vaporwave, UK hip-hop\nchillhop, vaporwave, West Coast hip-hop\nchillhop, vaporwave, synth-pop\nchillhop, world music, Latin groove\nchillout\nchillout Afro-Latin\nchillout C-pop\nchillout Latin\nchillout ambient\nchillout electronica\nchillout house\nchillout lo-fi ambient\nchillout lo-fi hip hop\nchillout lo-fi hip-hop\nchillout lo-fi hip-hop ambient\nchillout lounge\nchillout lounge smooth jazz\nchillout lounge vaporwave\nchillout lounge world music\nchillout smooth jazz\nchillout trip-hop\nchillout trip-hop downtempo\nchillout world music\nchillout, ambient, Chinese Buddhist\nchillout, ambient, electronic\nchillout, bossa nova, latin\nchillout, electronic, ambient\nchillout, electronic, traditional Chinese\nchillout, new age\nchillout, new age, world music\nchillout, progressive trance, ambient\nchillstep\nchillstep downtempo\nchillstep lo-fi hip-hop\nchillwave\nchillwave Afro-pop\nchillwave Arabic R&B\nchillwave C-pop\nchillwave C-pop R&B\nchillwave French pop\nchillwave Indian pop\nchillwave K-R&B\nchillwave K-pop\nchillwave Latin\nchillwave R&B\nchillwave R&B Indian pop\nchillwave R&B Mandopop\nchillwave R&B hip-hop\nchillwave R&B lo-fi hip hop\nchillwave R&B lo-fi hip-hop\nchillwave R&B trap\nchillwave acoustic pop\nchillwave afro-trap dancehall\nchillwave afrobeat\nchillwave afrobeat ambient\nchillwave afrobeats\nchillwave afrobeats r&b\nchillwave afropop dream pop\nchillwave alternative R&B\nchillwave alternative rock\nchillwave ambient\nchillwave ambient R&B\nchillwave ambient downtempo\nchillwave ambient electronica\nchillwave ambient future garage\nchillwave ambient hip-hop\nchillwave ambient house\nchillwave ambient lo-fi\nchillwave ambient pop\nchillwave ambient pop future bass\nchillwave ambient rock\nchillwave ambient techno\nchillwave ambient trance\nchillwave ambient trap\nchillwave bedroom pop\nchillwave bollywood pop\nchillwave bossa nova\nchillwave breakbeat\nchillwave breakcore\nchillwave cantopop\nchillwave city pop\nchillwave cloud rap\nchillwave dance-pop\nchillwave dark pop\nchillwave darkwave\nchillwave deep house\nchillwave deep house future bass\nchillwave deep house melodic techno\nchillwave deep house nu-disco\nchillwave dembow\nchillwave downtempo\nchillwave downtempo R&B\nchillwave downtempo ambient\nchillwave downtempo future bass\nchillwave downtempo future garage\nchillwave downtempo lo-fi hip-hop\nchillwave downtempo nu-jazz\nchillwave downtempo pop\nchillwave downtempo world music\nchillwave dream pop\nchillwave dream pop ambient\nchillwave dream pop downtempo\nchillwave dream pop lounge\nchillwave dream pop neo-soul\nchillwave dream pop synth-pop\nchillwave drum and bass\nchillwave dubstep\nchillwave electro-pop\nchillwave electronica\nchillwave emo rap\nchillwave emotional electronic\nchillwave emotional hip-hop\nchillwave emotional pop\nchillwave folk-pop\nchillwave french pop\nchillwave funk\nchillwave funk world music\nchillwave future bass\nchillwave future bass ambient\nchillwave future bass ambient rock\nchillwave future bass dream pop\nchillwave future bass drum and bass\nchillwave future bass indie pop\nchillwave future bass lo-fi hip-hop\nchillwave future bass reggaeton\nchillwave future funk\nchillwave future garage\nchillwave future garage ambient\nchillwave future garage electronica\nchillwave future-bass\nchillwave g-funk\nchillwave hardstyle\nchillwave hip hop\nchillwave hip-hop\nchillwave hip-hop indie rock\nchillwave indie dance\nchillwave indie electronic\nchillwave indie pop\nchillwave indie pop funk\nchillwave indie rock\nchillwave indie rock jazz\nchillwave indie-pop\nchillwave industrial rock\nchillwave instrumental\nchillwave instrumental funk\nchillwave instrumental hip-hop\nchillwave instrumental indie pop\nchillwave instrumental pop\nchillwave instrumental pop-rock\nchillwave j-pop\nchillwave jazz\nchillwave latin\nchillwave latin pop\nchillwave latin r&b\nchillwave liquid drum and bass\nchillwave lo-fi\nchillwave lo-fi C-pop\nchillwave lo-fi R&B\nchillwave lo-fi R&B future bass\nchillwave lo-fi beats\nchillwave lo-fi electronic\nchillwave lo-fi electronica\nchillwave lo-fi funk\nchillwave lo-fi fusion\nchillwave lo-fi hip hop\nchillwave lo-fi hip hop future bass\nchillwave lo-fi hip hop neo-soul\nchillwave lo-fi hip-hop\nchillwave lo-fi hip-hop C-pop\nchillwave lo-fi hip-hop French pop\nchillwave lo-fi hip-hop Mandopop\nchillwave lo-fi hip-hop R&B\nchillwave lo-fi hip-hop ambient\nchillwave lo-fi hip-hop ambient R&B\nchillwave lo-fi hip-hop atmospheric pop\nchillwave lo-fi hip-hop breakbeat\nchillwave lo-fi hip-hop cinematic pop\nchillwave lo-fi hip-hop city pop\nchillwave lo-fi hip-hop downtempo\nchillwave lo-fi hip-hop dream pop\nchillwave lo-fi hip-hop funk\nchillwave lo-fi hip-hop future bass\nchillwave lo-fi hip-hop future garage\nchillwave lo-fi hip-hop neo-soul\nchillwave lo-fi hip-hop smooth jazz\nchillwave lo-fi hip-hop trap\nchillwave lo-fi hip-hop vaporwave\nchillwave lo-fi hip-hop video game\nchillwave lo-fi house\nchillwave lo-fi house downtempo\nchillwave lo-fi house vaporwave\nchillwave lo-fi indie\nchillwave lo-fi pop\nchillwave lo-fi reggaeton\nchillwave lo-fi synth-pop\nchillwave lo-fi trap\nchillwave lo-fi video game\nchillwave lofi hip-hop\nchillwave lounge\nchillwave lounge jazz\nchillwave lounge latin electronic\nchillwave lounge nu-jazz\nchillwave lounge smooth jazz\nchillwave lounge worldbeat\nchillwave mandopop\nchillwave math rock\nchillwave melodic hip-hop\nchillwave melodic trap\nchillwave moombahton\nchillwave neo-soul\nchillwave nu-disco\nchillwave nu-disco French house\nchillwave nu-disco lounge\nchillwave nu-jazz\nchillwave nu-jazz lounge\nchillwave phonk\nchillwave pop\nchillwave pop-R&B\nchillwave pop-rap\nchillwave pop-reggaeton\nchillwave pop-rock\nchillwave post-rock\nchillwave progressive electronic\nchillwave progressive house\nchillwave progressive metal\nchillwave reggae\nchillwave reggae-funk\nchillwave reggae-pop\nchillwave reggaeton\nchillwave reggaeton lo-fi\nchillwave reggaeton synth-rock\nchillwave reggaeton vaporwave\nchillwave shoegaze\nchillwave smooth jazz\nchillwave synth-funk\nchillwave synth-funk vaporwave\nchillwave synth-pop\nchillwave synth-pop electro house\nchillwave synth-pop future bass\nchillwave synthwave\nchillwave synthwave ambient\nchillwave synthwave downtempo\nchillwave techno\nchillwave trap\nchillwave trap C-pop\nchillwave trap Persian pop\nchillwave trap R&B\nchillwave trap ambient\nchillwave trap experimental pop\nchillwave trap hardstyle\nchillwave trap soul\nchillwave trap-R&B\nchillwave trap-pop\nchillwave trap-r&b\nchillwave trap-soul\nchillwave trip-hop\nchillwave tropical\nchillwave tropical house\nchillwave uk garage\nchillwave vaporwave\nchillwave vaporwave ambient trap\nchillwave vaporwave deep house\nchillwave vaporwave lo-fi hip-hop\nchillwave vaporwave trap\nchillwave world fusion\nchillwave world music\nchillwave worldbeat\nchillwave worship\nchillwave, Afro-Latin\nchillwave, Bollywood pop\nchillwave, Bollywood-pop, lo-fi hip-hop\nchillwave, Brazilian R&B\nchillwave, Brazilian funk\nchillwave, Brazilian funk, trap\nchillwave, Brazilian pop\nchillwave, Brazilian pop, deep house\nchillwave, Brazilian trap\nchillwave, C-pop\nchillwave, C-pop, R&B\nchillwave, C-pop, ambient\nchillwave, C-pop, downtempo\nchillwave, C-pop, electronic\nchillwave, Canto-pop\nchillwave, Filipino hip-hop\nchillwave, French cloud rap\nchillwave, French house\nchillwave, French house, lo-fi house\nchillwave, French pop-rap\nchillwave, French trap\nchillwave, IDM\nchillwave, Indian folk\nchillwave, Indian pop\nchillwave, Indian pop, R&B\nchillwave, Indian pop, contemporary R&B\nchillwave, Indian pop, electronic\nchillwave, Italian trap\nchillwave, J-pop\nchillwave, J-pop, ambient electronica\nchillwave, J-pop, lo-fi hip-hop\nchillwave, J-rock\nchillwave, Japanese electronic\nchillwave, K-hip-hop\nchillwave, Latin R&B\nchillwave, Latin R&B, dembow\nchillwave, Latin R&B, reggaeton\nchillwave, Latin R&B, trap\nchillwave, Latin R&B, trap-soul\nchillwave, Latin hip-hop\nchillwave, Latin house\nchillwave, Latin pop\nchillwave, Latin pop, R&B\nchillwave, Latin trap\nchillwave, Latin trap, R&B\nchillwave, Latin, world music\nchillwave, Mandopop, trap\nchillwave, Polish hip-hop\nchillwave, R&B\nchillwave, R&B, Brazilian hip-hop\nchillwave, R&B, Latin pop\nchillwave, R&B, Russian pop\nchillwave, R&B, Swedish pop\nchillwave, R&B, Thai hip-hop\nchillwave, R&B, electronic\nchillwave, R&B, glitch hop\nchillwave, R&B, hyperpop\nchillwave, R&B, jazz\nchillwave, R&B, lo-fi\nchillwave, R&B, lo-fi hip hop\nchillwave, R&B, lo-fi hip-hop\nchillwave, R&B, pop\nchillwave, R&B, trap\nchillwave, R&B, trap-soul\nchillwave, Russian hip-hop\nchillwave, Russian pop\nchillwave, Southern hip-hop\nchillwave, Turkish pop\nchillwave, UK garage\nchillwave, UK garage, R&B\nchillwave, V-Pop, trap\nchillwave, alternative R&B\nchillwave, alternative R&B, K-R&B\nchillwave, alternative R&B, Polish hip-hop\nchillwave, alternative R&B, dream pop\nchillwave, alternative R&B, lo-fi\nchillwave, alternative R&B, lo-fi hip hop\nchillwave, alternative R&B, lo-fi hip-hop\nchillwave, alternative R&B, neo-soul\nchillwave, ambient R&B\nchillwave, ambient electronic\nchillwave, ambient pop\nchillwave, ambient pop, lo-fi hip-hop\nchillwave, ambient, C-pop\nchillwave, ambient, Indian classical\nchillwave, ambient, South Asian fusion\nchillwave, ambient, electronic\nchillwave, ambient, lo-fi electronic\nchillwave, ambient, progressive house\nchillwave, ambient, traditional Chinese\nchillwave, ambient, traditional East Asian\nchillwave, ambient, world fusion\nchillwave, anime soundtrack, ambient pop\nchillwave, atmospheric synthwave\nchillwave, baile funk\nchillwave, bollywood pop\nchillwave, breakbeat, IDM\nchillwave, breakbeat, video game\nchillwave, brostep, electronic\nchillwave, cinematic, C-pop\nchillwave, cinematic, Chinese opera\nchillwave, cinematic, Sinhala pop\nchillwave, city pop, R&B\nchillwave, cloud rap\nchillwave, cloud rap, Brazilian trap\nchillwave, cloud rap, French pop-rap\nchillwave, cloud rap, French trap\nchillwave, cloud rap, Latin R&B\nchillwave, cloud rap, afro-trap\nchillwave, cloud rap, atmospheric R&B\nchillwave, cloud rap, lo-fi hip hop\nchillwave, cloud rap, lo-fi hip-hop\nchillwave, cloud rap, pop-trap\nchillwave, cloud rap, synth-pop\nchillwave, cloud rap, trap\nchillwave, cloud rap, vaporwave\nchillwave, contemporary R&B\nchillwave, dance-pop\nchillwave, dance-pop, Mandopop\nchillwave, dark hip-hop\nchillwave, deep house\nchillwave, deep house, Brazilian indie dance\nchillwave, deep house, Middle Eastern\nchillwave, deep house, R&B\nchillwave, deep house, Romanian pop-rap\nchillwave, deep house, Russian pop\nchillwave, deep house, lo-fi\nchillwave, devotional electronic\nchillwave, downtempo\nchillwave, downtempo, C-pop\nchillwave, downtempo, ambient\nchillwave, downtempo, ambient pop\nchillwave, downtempo, cinematic\nchillwave, downtempo, electronic\nchillwave, downtempo, smooth jazz\nchillwave, downtempo, spiritual electronic\nchillwave, downtempo, world music\nchillwave, dream pop, instrumental indie rock\nchillwave, dream pop, synth-pop\nchillwave, drum and bass, ambient\nchillwave, drum and bass, neurofunk\nchillwave, electronic C-pop\nchillwave, electronic pop\nchillwave, electronic pop, Chinese ambient\nchillwave, electronic pop, traditional East Asian\nchillwave, electronic, C-pop\nchillwave, electronic, Indian fusion\nchillwave, electronic, Indian pop\nchillwave, electronic, Middle Eastern\nchillwave, electronic, trap\nchillwave, emo-rap\nchillwave, emotional R&B\nchillwave, experimental electronic\nchillwave, experimental electronic, neurofunk\nchillwave, future bass\nchillwave, future bass, C-pop\nchillwave, future bass, R&B\nchillwave, future bass, Russian pop\nchillwave, future bass, cinematic\nchillwave, future bass, dream pop\nchillwave, future bass, lo-fi hip hop\nchillwave, future garage, ambient\nchillwave, ghazal\nchillwave, hardstyle\nchillwave, hardstyle, big room house\nchillwave, hardstyle, trap\nchillwave, hip-hop\nchillwave, hip-hop, pop/R&B\nchillwave, hyperpop, R&B\nchillwave, hyperpop, pop-punk\nchillwave, instrumental electronica\nchillwave, kawaii pop\nchillwave, latin pop, dembow\nchillwave, liquid drum and bass\nchillwave, lo-fi R&B, ambient pop\nchillwave, lo-fi R&B, synth-pop\nchillwave, lo-fi hip hop\nchillwave, lo-fi hip hop, C-pop\nchillwave, lo-fi hip hop, French cloud rap\nchillwave, lo-fi hip hop, Latin R&B\nchillwave, lo-fi hip hop, Mongolian folk\nchillwave, lo-fi hip hop, R&B\nchillwave, lo-fi hip hop, ambient\nchillwave, lo-fi hip hop, cinematic\nchillwave, lo-fi hip hop, dream pop\nchillwave, lo-fi hip hop, future bass\nchillwave, lo-fi hip hop, traditional Chinese\nchillwave, lo-fi hip hop, trap\nchillwave, lo-fi hip hop, trap-soul\nchillwave, lo-fi hip hop, vaporwave\nchillwave, lo-fi hip-hop\nchillwave, lo-fi hip-hop, Brazilian pop-trap\nchillwave, lo-fi hip-hop, East Asian electronic\nchillwave, lo-fi hip-hop, R&B\nchillwave, lo-fi hip-hop, cinematic C-pop\nchillwave, lo-fi hip-hop, psychedelic rock\nchillwave, lo-fi hip-hop, synth-pop\nchillwave, lo-fi hip-hop, synthwave\nchillwave, lo-fi indie pop\nchillwave, lo-fi pop, bilingual pop\nchillwave, lo-fi, Indian folk\nchillwave, lo-fi, K-pop\nchillwave, lo-fi, electronic\nchillwave, lounge\nchillwave, melodic techno\nchillwave, melodic trap, cloud rap\nchillwave, metalcore, rap\nchillwave, minimal techno, tech house\nchillwave, modern R&B\nchillwave, modern R&B, lo-fi\nchillwave, motivational hip-hop\nchillwave, neo-soul, future bass\nchillwave, neo-soul, lo-fi hip hop\nchillwave, new-age, C-pop\nchillwave, nightcore, reggaeton\nchillwave, nu-disco, soulful electronic\nchillwave, pluggnb, hyperpop\nchillwave, pop, South Asian fusion\nchillwave, pop-R&B\nchillwave, pop-rap, R&B\nchillwave, pop-rap, contemporary R&B\nchillwave, pop-rock\nchillwave, pop-trap\nchillwave, pop-trap, R&B\nchillwave, pop-trap, future bass\nchillwave, progressive house\nchillwave, progressive house, ambient\nchillwave, progressive house, lo-fi hip hop\nchillwave, progressive house, world fusion\nchillwave, reggaeton\nchillwave, reggaeton, dream-pop\nchillwave, reggaeton, trap\nchillwave, synth-pop\nchillwave, synth-pop, Indian classical\nchillwave, synth-pop, Latin rap\nchillwave, synth-pop, R&B\nchillwave, synth-pop, ambient\nchillwave, synth-pop, chill R&B\nchillwave, synth-pop, cinematic\nchillwave, synth-pop, city pop\nchillwave, synth-pop, dream pop\nchillwave, synth-pop, future bass\nchillwave, synth-pop, hip-hop\nchillwave, synth-pop, lo-fi hip-hop\nchillwave, synth-pop, lo-fi house\nchillwave, synth-pop, multilingual hip-hop\nchillwave, synthwave, ambient techno\nchillwave, synthwave, vaporwave\nchillwave, tech house\nchillwave, techno\nchillwave, trap\nchillwave, trap R&B\nchillwave, trap, Brazilian funk\nchillwave, trap, Brazilian hip-hop\nchillwave, trap, Chinese hip hop\nchillwave, trap, French R&B\nchillwave, trap, French rap\nchillwave, trap, Indian classical\nchillwave, trap, K-pop\nchillwave, trap, Mandopop\nchillwave, trap, R&B\nchillwave, trap, bhajan\nchillwave, trap, cloud rap\nchillwave, trap, future bass\nchillwave, trap, hardstyle\nchillwave, trap, hyperpop\nchillwave, trap, lo-fi\nchillwave, trap, lo-fi hip hop\nchillwave, trap, lo-fi hip-hop\nchillwave, trap, nu-disco\nchillwave, trap, spiritual electronic\nchillwave, trap, vaporwave\nchillwave, trap-R&B\nchillwave, trap-R&B, future bass\nchillwave, trip-hop, C-pop\nchillwave, trip-hop, UK garage\nchillwave, trip-hop, ambient\nchillwave, trip-hop, cinematic\nchillwave, trip-hop, deep house\nchillwave, tropical house, Latin pop\nchillwave, tropical house, indie pop\nchillwave, vaporwave, synth-pop\nchillwave, world electronic\nchillwave, world fusion, Indian classical\nchillwave, world fusion, ambient\nchillwave, world fusion, devotional electronic\nchillwave, world music\nchillwave, world music, Indian pop\nchillwave, world music, ambient\nchillwave, world music, ambient electronic\nchillwave, worldbeat, electronic pop\nchip tune\nchip-hop\nchip-hop trap\nchip-hop, boom-bap, jazz rap\nchip-hop, dark trap\nchipbeat\nchipbeat trap\nchipmunk\nchipmunk hip hop\nchipmunk pop\nchipmunk soul\nchiptune\nchiptune 2-step\nchiptune 8-bit\nchiptune Afrobeat dancehall\nchiptune Arabic\nchiptune Arabic children's\nchiptune Arabic children's music\nchiptune Arabic dance\nchiptune Arabic folk\nchiptune Arabic fusion\nchiptune Arabic pop\nchiptune Balkan folk\nchiptune Balkan pop\nchiptune Bhojpuri\nchiptune Bhojpuri pop\nchiptune Bollywood\nchiptune Bollywood pop\nchiptune C-pop\nchiptune C-pop J-pop\nchiptune C-pop R&B\nchiptune C-pop anime\nchiptune C-pop dance-pop\nchiptune C-pop hip-hop\nchiptune C-pop lo-fi\nchiptune C-pop lo-fi hip-hop\nchiptune C-pop rock\nchiptune C-pop synth-pop\nchiptune Christian\nchiptune Christian pop\nchiptune Christmas\nchiptune EDM\nchiptune Eurodance\nchiptune French R&B\nchiptune French chanson\nchiptune French hip-hop\nchiptune French rap\nchiptune G-funk\nchiptune Greek pop\nchiptune Halloween\nchiptune IDM\nchiptune IDM world music\nchiptune Indian\nchiptune Indian classical\nchiptune Indian devotional\nchiptune Indian film music\nchiptune Indian folk\nchiptune Indian folk-pop\nchiptune Indian fusion\nchiptune Indian pop\nchiptune Indian pop-rock\nchiptune Islamic\nchiptune Islamic devotional\nchiptune Islamic pop\nchiptune J-core\nchiptune J-pop\nchiptune J-pop R&B\nchiptune J-pop breakcore\nchiptune J-pop future bass\nchiptune J-pop hip-hop\nchiptune J-pop hyperpop\nchiptune J-pop rock\nchiptune J-rock\nchiptune J-rock fusion\nchiptune J-rock math rock\nchiptune JRPG\nchiptune Javanese fusion\nchiptune Javanese pop\nchiptune Javanese pop-rock\nchiptune K-hip-hop\nchiptune K-pop\nchiptune K-pop R&B\nchiptune K-pop hip-hop\nchiptune K-rock\nchiptune Kizomba\nchiptune Kizomba Latin pop\nchiptune Latin\nchiptune Latin Christian\nchiptune Latin Christian dance\nchiptune Latin dance\nchiptune Latin dance-pop\nchiptune Latin folk\nchiptune Latin hip-hop\nchiptune Latin house\nchiptune Latin jazz\nchiptune Latin pop\nchiptune Latin pop hip-hop\nchiptune Latin pop-rap\nchiptune Latin pop-rock\nchiptune Latin rock\nchiptune Latin trap\nchiptune Luk Thung\nchiptune MPB indie rock\nchiptune Mandopop\nchiptune Norteño\nchiptune Persian pop\nchiptune R&B\nchiptune R&B French pop\nchiptune R&B hip-hop\nchiptune R&B pop\nchiptune R&B trap\nchiptune R&B trap-soul\nchiptune R&B world music\nchiptune T-pop\nchiptune Tamil pop\nchiptune UK hip-hop\nchiptune V-pop\nchiptune Western\nchiptune Zouk\nchiptune acid house\nchiptune acid jazz\nchiptune acoustic guitar\nchiptune afro\nchiptune afrobeat\nchiptune afrobeats\nchiptune afrobeats gospel\nchiptune alt-country\nchiptune alternative hip-hop pop-rock\nchiptune alternative metal\nchiptune alternative rock\nchiptune alternative rock electronic\nchiptune alternative rock nu-metal\nchiptune ambient\nchiptune anime\nchiptune arabic children's\nchiptune arabic folk\nchiptune arabic pop\nchiptune arena rock\nchiptune art pop\nchiptune art rock\nchiptune artcore\nchiptune artcore breakbeat\nchiptune artcore drum and bass\nchiptune baile funk\nchiptune ballad\nchiptune banda\nchiptune baroque\nchiptune baroque world music\nchiptune baroque-pop\nchiptune bhajan\nchiptune bhangra\nchiptune bhangra pop\nchiptune big band\nchiptune big band jazz\nchiptune big beat\nchiptune bitpop\nchiptune bluegrass\nchiptune blues-rock\nchiptune bolero\nchiptune bollywood\nchiptune boogie-woogie\nchiptune boom bap\nchiptune boom-bap\nchiptune bossa nova\nchiptune breakbeat\nchiptune breakbeat art rock\nchiptune breakbeat artcore\nchiptune breakbeat funk\nchiptune breakbeat glitch-hop\nchiptune breakbeat happy hardcore\nchiptune breakbeat hip-hop\nchiptune breakbeat jazz fusion\nchiptune breakbeat synth-rock\nchiptune breakcore\nchiptune breakcore Latin\nchiptune breakcore ambient\nchiptune breakcore art pop\nchiptune breakcore artcore\nchiptune breakcore drum and bass\nchiptune breakcore dubstep\nchiptune breakcore electro-funk\nchiptune breakcore glitch\nchiptune breakcore glitch hop\nchiptune breakcore glitch-hop\nchiptune breakcore happy hardcore\nchiptune breakcore j-core\nchiptune breakcore jazz fusion\nchiptune breakcore metal\nchiptune breakcore speedcore\nchiptune brega\nchiptune cabaret\nchiptune cabaret rock\nchiptune cajun\nchiptune children's\nchiptune children's music\nchiptune children's pirate\nchiptune children's pop\nchiptune chillwave\nchiptune cinematic\nchiptune city pop\nchiptune city pop lo-fi hip-hop\nchiptune classical\nchiptune classical balkan\nchiptune classical folk\nchiptune classical progressive rock\nchiptune classical world\nchiptune cloud rap\nchiptune comedy rap\nchiptune comedy rock\nchiptune complextro\nchiptune complextro hyperpop\nchiptune corrido\nchiptune corridos tumbados\nchiptune country\nchiptune country rock\nchiptune country-pop\nchiptune crunkcore\nchiptune cumbia\nchiptune cumbia funk\nchiptune cumbia fusion\nchiptune cumbia hip-hop\nchiptune cumbia kids\nchiptune cumbia novelty\nchiptune cumbia pop\nchiptune cumbia reggae\nchiptune cumbia reggaeton\nchiptune cumbia synth\nchiptune cumbia villera\nchiptune cumbia world fusion\nchiptune cyberpunk synth-rock\nchiptune dance\nchiptune dance pop\nchiptune dance-pop\nchiptune dance-punk\nchiptune dance-rock\nchiptune dancehall\nchiptune dancehall reggae\nchiptune dancehall-pop\nchiptune dangdut\nchiptune dangdut koplo\nchiptune dark comedy\nchiptune darksynth\nchiptune darkwave\nchiptune deep house\nchiptune dembow\nchiptune denpa\nchiptune denpa-kei\nchiptune devotional\nchiptune devotional Indian\nchiptune disco\nchiptune dream pop\nchiptune dream-pop\nchiptune drill\nchiptune drill metal\nchiptune drum & bass\nchiptune drum and bass\nchiptune drum and bass breakcore\nchiptune dub reggae\nchiptune dubstep\nchiptune dubstep drum and bass\nchiptune dubstep glitch hop\nchiptune dubstep glitch-hop\nchiptune dubstep grime\nchiptune dubstep hardstyle\nchiptune dubstep metalcore\nchiptune dubstep trap\nchiptune dubstep trap metal\nchiptune educational\nchiptune electro\nchiptune electro hip-hop\nchiptune electro house\nchiptune electro-folk\nchiptune electro-funk\nchiptune electro-funk rock\nchiptune electro-house\nchiptune electro-industrial\nchiptune electro-pop\nchiptune electro-punk\nchiptune electro-rock\nchiptune electro-swing\nchiptune electroclash\nchiptune electroclash experimental pop\nchiptune electronic\nchiptune electronic Indian film music\nchiptune electronic rock\nchiptune electronic rock trance\nchiptune emo rap\nchiptune emo rap hyperpop\nchiptune emo-electronic\nchiptune emo-pop\nchiptune emo-rap\nchiptune enka\nchiptune epic\nchiptune epic orchestral\nchiptune eurobeat\nchiptune eurodance\nchiptune experimental\nchiptune experimental pop\nchiptune fairytale\nchiptune fantasy\nchiptune folk\nchiptune folk dance\nchiptune folk electronic\nchiptune folk fusion\nchiptune folk pop\nchiptune folk-dance\nchiptune folk-pop\nchiptune folk-punk\nchiptune folk-rock\nchiptune forró\nchiptune funk\nchiptune funk acid jazz\nchiptune funk art-pop\nchiptune funk big beat\nchiptune funk breakbeat\nchiptune funk carioca\nchiptune funk disco\nchiptune funk electronic rock\nchiptune funk fusion\nchiptune funk hip-hop\nchiptune funk jazz fusion\nchiptune funk kuthu\nchiptune funk lounge\nchiptune funk pop-rap\nchiptune funk rap\nchiptune funk rock\nchiptune funk synth-pop\nchiptune funk-jazz\nchiptune funk-pop\nchiptune funk-reggae\nchiptune funk-rock\nchiptune funk-rock breakbeat\nchiptune funk-rock hip-hop\nchiptune funk-rock progressive\nchiptune funk-rock psychedelic rock\nchiptune funkot\nchiptune fusion\nchiptune future bass\nchiptune future bass alternative R&B\nchiptune future bass glitch-hop\nchiptune future bass kawaii bass\nchiptune future bass trap\nchiptune g-funk\nchiptune gabber\nchiptune garage\nchiptune garage rock\nchiptune ghazal\nchiptune glitch\nchiptune glitch-hop\nchiptune glitch-hop cinematic\nchiptune glitch-hop future bass\nchiptune glitch-pop\nchiptune gospel\nchiptune gospel hip-hop\nchiptune gospel rap\nchiptune gospel rock\nchiptune gothic\nchiptune gothic rock\nchiptune happy hardcore\nchiptune hard rock\nchiptune hard trance\nchiptune hardcore\nchiptune hardcore hip-hop\nchiptune hardcore industrial\nchiptune hardcore speedcore\nchiptune hardcore techno\nchiptune hardcore trance\nchiptune hardstyle\nchiptune hardstyle breakcore\nchiptune hardstyle trap\nchiptune haryanvi\nchiptune hip hop\nchiptune hip hop dancehall\nchiptune hip-hop\nchiptune hip-hop C-pop\nchiptune hip-hop J-rock\nchiptune hip-hop R&B\nchiptune hip-hop alternative pop\nchiptune hip-hop alternative rock\nchiptune hip-hop brostep\nchiptune hip-hop dance-pop\nchiptune hip-hop drum and bass\nchiptune hip-hop electro-funk\nchiptune hip-hop experimental\nchiptune hip-hop gospel\nchiptune hip-hop hard rock\nchiptune hip-hop industrial rock\nchiptune hip-hop lo-fi\nchiptune hip-hop pop\nchiptune hip-hop pop-punk\nchiptune hip-hop pop-rock\nchiptune hip-hop power metal\nchiptune hip-hop rock\nchiptune hip-hop trap\nchiptune hip-hop world music\nchiptune hip-hop, hardstyle\nchiptune hip-hop, pop-rock\nchiptune horror\nchiptune horror-cumbia\nchiptune house\nchiptune hymnal\nchiptune hyper-pop\nchiptune hyperpop\nchiptune hyperpop C-pop\nchiptune hyperpop J-core\nchiptune hyperpop J-pop\nchiptune hyperpop j-core\nchiptune hyperpop trap\nchiptune indie dance\nchiptune indie electronic\nchiptune indie pop\nchiptune indie pop J-pop\nchiptune indie pop alternative hip-hop\nchiptune indie pop funk\nchiptune indie rock\nchiptune indie rock dream pop\nchiptune indie rock hip-hop\nchiptune indie rock synth-pop\nchiptune indie-pop\nchiptune industrial\nchiptune industrial breakbeat\nchiptune industrial breakcore\nchiptune industrial cyberpunk\nchiptune industrial dark synth-pop\nchiptune industrial hip-hop\nchiptune industrial metal\nchiptune industrial metal glitch-hop\nchiptune industrial metal hip-hop\nchiptune industrial rock\nchiptune industrial synthwave\nchiptune industrial techno\nchiptune industrial trance\nchiptune italo-disco\nchiptune j-core\nchiptune j-fusion\nchiptune j-pop\nchiptune j-pop jazz fusion\nchiptune j-rock\nchiptune jazz\nchiptune jazz funk\nchiptune jazz fusion\nchiptune jazz fusion funk\nchiptune jazz fusion progressive rock\nchiptune jazz lounge\nchiptune jazz-funk\nchiptune jazz-funk progressive rock\nchiptune jazz-fusion\nchiptune jazz-rock\nchiptune jungle\nchiptune k-pop\nchiptune kawaii\nchiptune kawaii future bass\nchiptune kawaii-core\nchiptune kawaii-pop\nchiptune kids\nchiptune kizomba\nchiptune klezmer\nchiptune klezmer electronic\nchiptune klezmer novelty\nchiptune kuduro\nchiptune latin\nchiptune latin dance\nchiptune latin jazz\nchiptune lo-fi\nchiptune lo-fi electronic\nchiptune lo-fi hip hop\nchiptune lo-fi hip-hop\nchiptune lo-fi hip-hop chillwave\nchiptune lo-fi hip-hop future bass\nchiptune lo-fi hip-hop neo-soul\nchiptune lo-fi indie rock\nchiptune lo-fi pop\nchiptune lo-fi synth-pop\nchiptune lo-fi trap\nchiptune lofi\nchiptune lofi hip-hop\nchiptune lounge\nchiptune lounge jazz\nchiptune luk thung\nchiptune lullaby\nchiptune march\nchiptune math rock\nchiptune math rock breakcore\nchiptune math rock progressive metal\nchiptune melancholic\nchiptune metal\nchiptune metal nintendocore\nchiptune metal techno\nchiptune metalcore\nchiptune metalcore dubstep\nchiptune metalcore electronic rock\nchiptune metalcore electronicore\nchiptune metalcore speedcore\nchiptune minimal\nchiptune minimal house\nchiptune moombahton\nchiptune musical theater\nchiptune neo-baroque\nchiptune neo-classical\nchiptune neo-soul\nchiptune neo-soul conscious hip-hop\nchiptune neo-soul funk\nchiptune neo-soul lo-fi hip-hop\nchiptune neoclassical\nchiptune neurofunk\nchiptune neurofunk hardcore\nchiptune new jack swing\nchiptune nightcore\nchiptune noise rock\nchiptune noise-rock\nchiptune norteño\nchiptune novelty\nchiptune novelty pop\nchiptune novelty pop-rock\nchiptune nu-disco\nchiptune nu-metal\nchiptune nursery rhyme\nchiptune opera\nchiptune orchestral\nchiptune orchestral pop\nchiptune orchestral pop hip-hop\nchiptune orchestral swing\nchiptune orchestral synth-pop\nchiptune phonk\nchiptune pirate\nchiptune pirate shanty\nchiptune piseiro\nchiptune polka\nchiptune polka hip-hop\nchiptune polka klezmer\nchiptune polka novelty\nchiptune polka-rock\nchiptune pop\nchiptune pop R&B\nchiptune pop Tollywood\nchiptune pop ballad\nchiptune pop hip hop\nchiptune pop hip-hop\nchiptune pop klezmer\nchiptune pop rap\nchiptune pop, Pop Melayu\nchiptune pop-R&B\nchiptune pop-funk\nchiptune pop-punk\nchiptune pop-punk R&B\nchiptune pop-punk electronic\nchiptune pop-punk rap-rock\nchiptune pop-r&b\nchiptune pop-rap\nchiptune pop-rock\nchiptune pop-rock emo-rap\nchiptune pop-rock metal\nchiptune pop-rock metalcore\nchiptune pop-rock rap\nchiptune pop-trap\nchiptune post-hardcore\nchiptune post-hardcore hip-hop\nchiptune post-punk\nchiptune post-rock\nchiptune power ballad\nchiptune power metal\nchiptune power metal synth-rock\nchiptune power metal synthwave\nchiptune power metal trance\nchiptune power pop\nchiptune power pop surf rock\nchiptune power rock\nchiptune power-pop\nchiptune power-pop J-rock\nchiptune power-pop surf rock\nchiptune power-pop theatrical rock\nchiptune praise\nchiptune progressive house\nchiptune progressive metal\nchiptune progressive metal J-rock\nchiptune progressive metal jazz fusion\nchiptune progressive rock\nchiptune progressive rock funk\nchiptune progressive rock jazz fusion\nchiptune progressive rock metal\nchiptune progressive rock synth-pop\nchiptune protest\nchiptune psytrance\nchiptune punk\nchiptune punk breakcore\nchiptune punk rock\nchiptune punk, hyperpop\nchiptune ragtime\nchiptune ragtime jazz\nchiptune ragtime surf rock\nchiptune ragtime swing\nchiptune ranchera\nchiptune rap\nchiptune rap-metal\nchiptune rap-rock\nchiptune rap-rock alternative metal\nchiptune rapcore\nchiptune reggae\nchiptune reggae dancehall\nchiptune reggae dub\nchiptune reggae hip-hop\nchiptune reggae world music\nchiptune reggae-dub\nchiptune reggae-funk\nchiptune reggae-pop\nchiptune reggae-ska\nchiptune reggae-soca\nchiptune reggaeton\nchiptune reggaeton breakcore\nchiptune reggaeton electro-house\nchiptune regional Mexican\nchiptune revolutionary anthem\nchiptune rock\nchiptune rock dangdut\nchiptune rock funk\nchiptune rock hip-hop\nchiptune rock meme-core\nchiptune rock opera\nchiptune rock speedcore\nchiptune rock, J-rock\nchiptune romance\nchiptune salsa\nchiptune samba\nchiptune samba-pop\nchiptune samba-rock\nchiptune schlager\nchiptune schlager pop\nchiptune sea shanty\nchiptune shoegaze\nchiptune show tune\nchiptune shred\nchiptune shred metal\nchiptune ska\nchiptune ska pop\nchiptune ska punk\nchiptune ska-punk\nchiptune ska-punk big band\nchiptune soca\nchiptune soul\nchiptune southern rock\nchiptune speed metal\nchiptune speed metal symphonic rock\nchiptune speedcore\nchiptune speedcore J-core\nchiptune speedcore J-pop\nchiptune speedcore artcore\nchiptune speedcore big band jazz\nchiptune speedcore breakcore\nchiptune speedcore complextro\nchiptune speedcore glitch\nchiptune speedcore glitch hop\nchiptune speedcore power metal\nchiptune speedcore symphonic metal\nchiptune sports anthem\nchiptune stadium rock\nchiptune sufi\nchiptune surf rock\nchiptune surf-rock\nchiptune swing\nchiptune swing jazz\nchiptune symphonic\nchiptune symphonic metal\nchiptune symphonic metal J-rock\nchiptune symphonic metal trance\nchiptune symphonic rock\nchiptune synth-funk\nchiptune synth-funk vaporwave\nchiptune synth-pop\nchiptune synth-pop C-pop\nchiptune synth-pop ambient\nchiptune synth-pop breakcore\nchiptune synth-pop folk\nchiptune synth-pop funk\nchiptune synth-pop future bass\nchiptune synth-pop hip-hop\nchiptune synth-pop rock\nchiptune synth-pop vaporwave\nchiptune synth-punk\nchiptune synth-rock\nchiptune synth-rock power metal\nchiptune synthrock\nchiptune synthwave\nchiptune synthwave breakbeat\nchiptune synthwave dream pop\nchiptune synthwave electro\nchiptune synthwave electro house\nchiptune synthwave electro-rock\nchiptune synthwave electronic rock\nchiptune synthwave lo-fi\nchiptune synthwave power metal\nchiptune synthwave trance\nchiptune tango\nchiptune tango latin\nchiptune tech house\nchiptune tech-house\nchiptune techno\nchiptune techno-ska\nchiptune theatrical\nchiptune thrash metal\nchiptune trance\nchiptune trance breakbeat\nchiptune trance drum and bass\nchiptune trance eurodance\nchiptune trance hardstyle\nchiptune trance industrial metal\nchiptune trance power metal\nchiptune trance progressive house\nchiptune trance world music\nchiptune trap\nchiptune trap C-pop\nchiptune trap K-pop\nchiptune trap R&B\nchiptune trap drum and bass\nchiptune trap electro\nchiptune trap emo rap\nchiptune trap future bass\nchiptune trap hardstyle\nchiptune trap hip-hop\nchiptune trap hyperpop\nchiptune trap metal\nchiptune trap phonk\nchiptune trap rap\nchiptune trap rock\nchiptune trap soul\nchiptune trap synthwave\nchiptune trap, cloud rap\nchiptune trap, lo-fi hip hop, chopped and screwed\nchiptune trap-R&B\nchiptune trap-pop\nchiptune trap-soul\nchiptune trip-hop\nchiptune tropical\nchiptune tropical house\nchiptune trot\nchiptune turbo-folk\nchiptune turbo-funk\nchiptune vaporwave\nchiptune video game\nchiptune video game music\nchiptune vocaloid\nchiptune waltz\nchiptune western\nchiptune world fusion\nchiptune world music\nchiptune worldbeat\nchiptune worldbeat gospel\nchiptune worship\nchiptune zouk\nchiptune, 16-bit, electronic\nchiptune, 16-bit, video game\nchiptune, 16-bit, video game music\nchiptune, 8-bit, children's music\nchiptune, 8-bit, children's novelty\nchiptune, 8-bit, electronic\nchiptune, 8-bit, lo-fi\nchiptune, 8-bit, novelty\nchiptune, 80s synth, romantic ballad\nchiptune, Arabic children's music\nchiptune, Arabic children's, synth-pop\nchiptune, Arabic children's, video game\nchiptune, Arabic children's, video game music\nchiptune, Arabic pop, Indonesian pop\nchiptune, Arabic pop, electronic\nchiptune, Balkan brass, lo-fi\nchiptune, Balkan folk, electronic\nchiptune, Balkan hip-hop, electro-swing\nchiptune, Balkan pop, electronic\nchiptune, Balkan rock, electronic\nchiptune, Balkan, Klezmer\nchiptune, Balkan, Middle Eastern\nchiptune, Bhojpuri folk, electronic\nchiptune, Bollywood dance-pop\nchiptune, Bollywood dance-pop, electronic\nchiptune, Bollywood pop\nchiptune, Bollywood pop, electronic dance\nchiptune, Bollywood, children's music\nchiptune, Bollywood, dance\nchiptune, Bollywood, electronic\nchiptune, Bollywood, hyperpop\nchiptune, Bollywood, synthwave\nchiptune, Bollywood-pop, children's music\nchiptune, Brazilian Funk\nchiptune, Brazilian funk\nchiptune, Brazilian funk, Christian\nchiptune, Brazilian funk, R&B\nchiptune, Brazilian funk, hip hop\nchiptune, Brazilian funk, lo-fi\nchiptune, Brazilian funk, lo-fi hip hop\nchiptune, Brazilian funk, retro game\nchiptune, Brazilian funk, retro-futuristic\nchiptune, Brazilian funk, trap\nchiptune, Brazilian pop\nchiptune, Brazilian pop, retro-futuristic\nchiptune, Brazilian pop, synth-pop\nchiptune, Brazilian pop-rap\nchiptune, Brazilian pop-rock\nchiptune, Brazilian, dance\nchiptune, Brazilian, upbeat\nchiptune, C-pop\nchiptune, C-pop, J-pop\nchiptune, C-pop, ambient\nchiptune, C-pop, anime soundtrack\nchiptune, C-pop, cinematic\nchiptune, C-pop, electronic\nchiptune, C-pop, electronic dance\nchiptune, C-pop, festive\nchiptune, C-pop, lo-fi\nchiptune, C-pop, lo-fi hip hop\nchiptune, C-pop, retro game\nchiptune, C-pop, romantic\nchiptune, C-pop, synthwave\nchiptune, C-pop, video game\nchiptune, C-pop, video game music\nchiptune, Caribbean, hip hop\nchiptune, Carnatic fusion, upbeat\nchiptune, Central Asian pop, electronic\nchiptune, Chinese MC, electronic\nchiptune, Chinese electronic\nchiptune, Chinese electronic, dance\nchiptune, Chinese folk, anime\nchiptune, Chinese folk, lo-fi\nchiptune, Christian EDM\nchiptune, Christian pop, upbeat\nchiptune, Christian, orchestral\nchiptune, Christian, synth\nchiptune, Christmas pop, German pop\nchiptune, Christmas, German\nchiptune, Christmas, German pop\nchiptune, Christmas, J-RPG\nchiptune, Christmas, Spanish\nchiptune, Christmas, children's music\nchiptune, Christmas, hymnal\nchiptune, Christmas, musical theater\nchiptune, Christmas, novelty\nchiptune, Christmas, synth pop\nchiptune, Christmas, video game\nchiptune, Christmas, video game music\nchiptune, Dappan Kabican, electronic\nchiptune, Dutch hip-hop, pop\nchiptune, EBM\nchiptune, EBM, industrial\nchiptune, EBM, lo-fi\nchiptune, EDM\nchiptune, EDM, Vocaloid\nchiptune, EDM, electronic\nchiptune, EDM, funk\nchiptune, East Asian fusion\nchiptune, East Asian pop, lo-fi\nchiptune, East Asian, RPG\nchiptune, East Asian, ambient\nchiptune, East Asian, electronic\nchiptune, East Asian, lo-fi\nchiptune, East Asian, video game\nchiptune, Eurodance, children's\nchiptune, French chanson, rock\nchiptune, French hip-hop, synth-pop\nchiptune, French pop, Christmas\nchiptune, French pop, lo-fi\nchiptune, French pop, synthwave\nchiptune, French rap, emo-pop\nchiptune, French rap, theatrical rock\nchiptune, G-funk, soulful rap\nchiptune, German rap\nchiptune, Greek folk\nchiptune, Greek folk, Laïko\nchiptune, Greek folk, dance-pop\nchiptune, Greek folk, laiko\nchiptune, Halloween, theatrical\nchiptune, IDM, art pop\nchiptune, Indian classical, electronic\nchiptune, Indian classical, pop\nchiptune, Indian dance-pop\nchiptune, Indian devotional\nchiptune, Indian devotional, Bollywood\nchiptune, Indian devotional, electronic\nchiptune, Indian devotional, electronic dance\nchiptune, Indian devotional, folk fusion\nchiptune, Indian devotional, fusion\nchiptune, Indian devotional, lo-fi\nchiptune, Indian devotional, retro-futuristic\nchiptune, Indian film music\nchiptune, Indian film music, retro-futuristic\nchiptune, Indian film music, synthpop\nchiptune, Indian film music, upbeat duet\nchiptune, Indian folk\nchiptune, Indian folk, bhajan\nchiptune, Indian folk, dance\nchiptune, Indian folk, electronic\nchiptune, Indian folk, electronic dance\nchiptune, Indian folk, melancholic\nchiptune, Indian folk, retro video game\nchiptune, Indian folk, upbeat\nchiptune, Indian folk, upbeat fusion\nchiptune, Indian folk-pop\nchiptune, Indian folk-pop, electronic\nchiptune, Indian fusion\nchiptune, Indian fusion, electronic\nchiptune, Indian fusion, retro-electro\nchiptune, Indian fusion, upbeat\nchiptune, Indian pop\nchiptune, Indian pop, electronic\nchiptune, Indian pop, electronic dance\nchiptune, Indian pop, funk\nchiptune, Indian pop, retro-futuristic\nchiptune, Indian pop, synthwave\nchiptune, Indonesian pop\nchiptune, Indonesian pop, funk-rock\nchiptune, Islamic devotional, lo-fi\nchiptune, Islamic hip-hop, cross-cultural\nchiptune, Italian rap, alternative rock\nchiptune, Italo-disco\nchiptune, Italo-disco, Eurobeat\nchiptune, Italo-disco, children's music\nchiptune, Italo-disco, cinematic pop\nchiptune, J-RPG, orchestral\nchiptune, J-core\nchiptune, J-core, EDM\nchiptune, J-core, artcore\nchiptune, J-core, breakcore\nchiptune, J-core, complextro\nchiptune, J-core, denpa\nchiptune, J-core, denpa-kei\nchiptune, J-core, electronic\nchiptune, J-core, electronic dance\nchiptune, J-core, happy hardcore\nchiptune, J-core, hardcore\nchiptune, J-core, hardcore techno\nchiptune, J-core, hardstyle\nchiptune, J-core, high-BPM\nchiptune, J-core, hyperpop\nchiptune, J-core, kawaii\nchiptune, J-core, kawaii future bass\nchiptune, J-core, trancecore\nchiptune, J-pop\nchiptune, J-pop, Arabic pop\nchiptune, J-pop, C-pop\nchiptune, J-pop, J-rock\nchiptune, J-pop, Vocaloid\nchiptune, J-pop, anime\nchiptune, J-pop, breakcore\nchiptune, J-pop, children's Christian\nchiptune, J-pop, cloud rap\nchiptune, J-pop, denpa\nchiptune, J-pop, denpa-kei\nchiptune, J-pop, electronic\nchiptune, J-pop, electronic dance\nchiptune, J-pop, future bass\nchiptune, J-pop, glitch\nchiptune, J-pop, glitch-hop\nchiptune, J-pop, happy hardcore\nchiptune, J-pop, hyperpop\nchiptune, J-pop, lo-fi\nchiptune, J-pop, lo-fi hip-hop\nchiptune, J-pop, pop-rock, orchestral\nchiptune, J-pop, retro\nchiptune, J-pop, retro electronic\nchiptune, J-pop, video game music\nchiptune, J-rock\nchiptune, J-rock, C-pop\nchiptune, J-rock, C-rock\nchiptune, J-rock, Vocaloid\nchiptune, J-rock, anime pop\nchiptune, J-rock, cartoon\nchiptune, J-rock, children's music\nchiptune, J-rock, electronic\nchiptune, J-rock, funk\nchiptune, J-rock, hyperpop\nchiptune, J-rock, lo-fi hip hop\nchiptune, J-rock, metalcore\nchiptune, J-rock, pop-punk\nchiptune, J-rock, symphonic metal\nchiptune, J-rock, synth-pop\nchiptune, J-rock, video game\nchiptune, J-rock, video game music\nchiptune, JRPG soundtrack\nchiptune, JRPG, anime\nchiptune, JRPG, baroque-pop\nchiptune, JRPG, cinematic\nchiptune, JRPG, electronic\nchiptune, JRPG, fantasy\nchiptune, JRPG, heroic\nchiptune, JRPG, orchestral\nchiptune, JRPG, synth\nchiptune, JRPG, upbeat\nchiptune, Japanese RPG, electronic\nchiptune, Japanese RPG, epic\nchiptune, Japanese RPG, synthwave\nchiptune, Japanese electronic\nchiptune, Japanese hip-hop\nchiptune, Japanese hip-hop, retro-futuristic\nchiptune, Japanese rock\nchiptune, Japanese rock, speed metal\nchiptune, Japanese rock, video game music\nchiptune, Japanese video game music\nchiptune, Japanese video game music, funk\nchiptune, Japanese video game music, upbeat\nchiptune, Japanese, energetic\nchiptune, Javanese pop\nchiptune, Javanese pop, funk\nchiptune, Javanese, electronic\nchiptune, Javanese, upbeat\nchiptune, K-hip-hop, cinematic\nchiptune, K-pop, children's music\nchiptune, K-pop, electronic\nchiptune, Latin dance, electronic\nchiptune, Latin dance-pop\nchiptune, Latin electronic\nchiptune, Latin electronic, dance\nchiptune, Latin electronic, moombahton\nchiptune, Latin electronic, retro-futuristic\nchiptune, Latin electronic, synthpop\nchiptune, Latin folk, Bossa Nova\nchiptune, Latin folk, lo-fi\nchiptune, Latin folk, upbeat\nchiptune, Latin folk, video game\nchiptune, Latin groove, electronic\nchiptune, Latin groove, retro game\nchiptune, Latin groove, video game\nchiptune, Latin percussion, video game music\nchiptune, Latin pop\nchiptune, Latin pop, children's music\nchiptune, Latin pop, children's worship\nchiptune, Latin pop, power ballad\nchiptune, Latin pop, reggaeton\nchiptune, Latin pop, synthwave\nchiptune, Latin rock\nchiptune, Latin trap, anime electronica\nchiptune, Latin urban, hardstyle\nchiptune, Latin urban, synth pop\nchiptune, Latin, children's music\nchiptune, Latin, electronic\nchiptune, Latin, klezmer\nchiptune, Latin, novelty\nchiptune, Latin, playful\nchiptune, Latin, reggaeton\nchiptune, Latin, upbeat\nchiptune, Latin, video game music\nchiptune, Luk Thung, Southeast Asian folk\nchiptune, Luk Thung, Southeast Asian fusion\nchiptune, Luk Thung, electronic\nchiptune, Malay pop, electronic\nchiptune, Marathi folk, electronic\nchiptune, Middle Eastern\nchiptune, Middle Eastern dance\nchiptune, Middle Eastern dance, electronic\nchiptune, Middle Eastern folk\nchiptune, Middle Eastern folk, electronic\nchiptune, Middle Eastern fusion\nchiptune, Middle Eastern fusion, electronic\nchiptune, Middle Eastern fusion, video game music\nchiptune, Middle Eastern pop\nchiptune, Middle Eastern pop, retro electronic\nchiptune, Middle Eastern, Balkan\nchiptune, Middle Eastern, North African\nchiptune, Middle Eastern, Phrygian\nchiptune, Middle Eastern, anime\nchiptune, Middle Eastern, dance\nchiptune, Middle Eastern, dramatic\nchiptune, Middle Eastern, electronic\nchiptune, Middle Eastern, lo-fi\nchiptune, Middle Eastern, narrative pop\nchiptune, Middle Eastern, video game\nchiptune, Middle Eastern, video game music\nchiptune, Nintendocore\nchiptune, Nintendocore, J-pop\nchiptune, Nintendocore, electro-rock\nchiptune, Nintendocore, happy hardcore\nchiptune, Nintendocore, lo-fi\nchiptune, Nintendocore, lo-fi hip hop\nchiptune, Nintendocore, punk\nchiptune, North African folk, electronic\nchiptune, North African folk, lo-fi\nchiptune, North African fusion, electronic\nchiptune, North African pop\nchiptune, North African pop, lo-fi\nchiptune, North African pop, retro-futuristic\nchiptune, North African, dance\nchiptune, North African, electronic\nchiptune, North African, funk\nchiptune, North African, retro\nchiptune, North African, retro electronic\nchiptune, North African, upbeat\nchiptune, Polish Christmas, nostalgic\nchiptune, Portuguese pop\nchiptune, Portuguese pop, theatrical\nchiptune, Punjabi pop\nchiptune, Punjabi pop, electronic\nchiptune, R&B, electronic\nchiptune, R&B, hip hop\nchiptune, R&B, hip-hop\nchiptune, R&B, lo-fi\nchiptune, RPG, baroque\nchiptune, RPG, orchestral\nchiptune, Romanian folk\nchiptune, Romanian party music\nchiptune, Russian bard\nchiptune, Russian chanson\nchiptune, Russian chanson, narrative pop\nchiptune, Russian estrada\nchiptune, Russian estrada, synth-pop\nchiptune, Russian folk\nchiptune, Russian folk, dance\nchiptune, Russian folk, electronic\nchiptune, Russian folk, happy hardcore\nchiptune, Russian folk, operatic\nchiptune, Russian folk, polka\nchiptune, Russian hip-hop\nchiptune, Russian rap\nchiptune, Sinhala folk, electronic\nchiptune, Sinhala folk, retro\nchiptune, South Asian film music, retro-futuristic\nchiptune, South Asian folk\nchiptune, South Asian folk, electronic\nchiptune, South Asian fusion, electronic\nchiptune, South Asian pop\nchiptune, South Asian pop, hip-hop\nchiptune, South Asian pop, lo-fi\nchiptune, South Asian pop, retro\nchiptune, South Asian pop, retro-futuristic\nchiptune, South Asian pop, trap\nchiptune, South Asian, lo-fi\nchiptune, South Indian dance, electronic\nchiptune, South Indian devotional, electronic\nchiptune, South Indian film music\nchiptune, South Indian film music, electronic\nchiptune, South Indian film music, retro game\nchiptune, South Indian film music, retro-futuristic\nchiptune, South Indian film music, video game\nchiptune, South Indian folk\nchiptune, South Indian folk, electronic\nchiptune, South Indian folk, retro game\nchiptune, South Indian pop\nchiptune, South Indian pop, electronic\nchiptune, South Indian, electronic\nchiptune, South Indian, upbeat\nchiptune, Southeast Asian folk\nchiptune, Southeast Asian pop\nchiptune, Sundanese fusion\nchiptune, Sundanese, dance\nchiptune, Sundanese, playful\nchiptune, Sundanese, upbeat\nchiptune, T-pop, dance-pop\nchiptune, Tamil film music, lo-fi\nchiptune, Tamil folk, playful\nchiptune, Tamil pop, ambient\nchiptune, Tamil pop, electronic\nchiptune, Thai folk, electronic\nchiptune, Thai hip-hop\nchiptune, Thai pop\nchiptune, Thai pop, 8-bit\nchiptune, Thai rap\nchiptune, Thai rap, electronic\nchiptune, Tibetan folk, electronic\nchiptune, Tibetan pop, electronic dance\nchiptune, Turkish folk\nchiptune, Turkish folk, cinematic\nchiptune, Turkish folk, electronic\nchiptune, Turkish folk, emotional pop\nchiptune, Turkish folk, lo-fi\nchiptune, Turkish pop\nchiptune, Turkish pop, lo-fi\nchiptune, Turkish pop, synthwave\nchiptune, Turkish pop-rock\nchiptune, UK garage, electronic\nchiptune, UK garage, trap\nchiptune, UK hip-hop\nchiptune, Ukrainian folk\nchiptune, Ukrainian folk, electronic\nchiptune, Ukrainian folk, polka\nchiptune, Vietnamese folk\nchiptune, Vietnamese pop, folk-pop\nchiptune, Vietnamese pop, video game music\nchiptune, Vocaloid, 16-bit\nchiptune, Vocaloid, C-pop\nchiptune, Vocaloid, Christmas\nchiptune, Vocaloid, East Asian\nchiptune, Vocaloid, East Asian fusion\nchiptune, Vocaloid, Hindi pop\nchiptune, Vocaloid, J-pop\nchiptune, Vocaloid, RPG soundtrack\nchiptune, Vocaloid, ambient\nchiptune, Vocaloid, anime\nchiptune, Vocaloid, educational\nchiptune, Vocaloid, electronic\nchiptune, Vocaloid, hip-hop\nchiptune, Vocaloid, hyperpop\nchiptune, Vocaloid, internet music\nchiptune, Vocaloid, nostalgic\nchiptune, Vocaloid, orchestral\nchiptune, Vocaloid, rock\nchiptune, Vocaloid, world pop\nchiptune, afro-trap, French rap\nchiptune, afrobeat, dancehall\nchiptune, afrobeats\nchiptune, alternative rock, hip-hop\nchiptune, alternative rock, hyperpop\nchiptune, alternative rock, post-hardcore\nchiptune, ambient, Arabic\nchiptune, ambient, C-pop\nchiptune, ambient, J-pop\nchiptune, ambient, JRPG\nchiptune, ambient, South Asian\nchiptune, ambient, breakbeat\nchiptune, ambient, breakcore\nchiptune, ambient, cinematic\nchiptune, ambient, electronic\nchiptune, ambient, glitch\nchiptune, ambient, lo-fi\nchiptune, ambient, spiritual\nchiptune, ambient, synthwave\nchiptune, ambient, traditional Chinese\nchiptune, ambient, trance\nchiptune, ambient, trap\nchiptune, ambient, video game\nchiptune, anime, JRPG\nchiptune, anime, children's\nchiptune, anime, electronic\nchiptune, anime, lo-fi\nchiptune, anime, pop\nchiptune, anime, rock\nchiptune, arabic, electronic\nchiptune, art rock, noise rock\nchiptune, axé, forró\nchiptune, baile funk, lo-fi pop\nchiptune, ballad, French chanson\nchiptune, baroque pop, electronic\nchiptune, baroque pop, theatrical\nchiptune, baroque, cinematic\nchiptune, baroque, electronic\nchiptune, baroque, epic\nchiptune, baroque, fantasy\nchiptune, baroque, spooky\nchiptune, baroque, synth-pop\nchiptune, baroque, video game music\nchiptune, bedroom pop, J-pop\nchiptune, bedroom pop, lo-fi hip-hop\nchiptune, big band, rockabilly\nchiptune, big band, show tune\nchiptune, big band, surf rock\nchiptune, big band, swing\nchiptune, big beat, electronic\nchiptune, big room house, happy hardcore\nchiptune, bitpop, IDM\nchiptune, bitpop, J-pop\nchiptune, bitpop, Nintendocore\nchiptune, bitpop, acid techno\nchiptune, bitpop, electro\nchiptune, bitpop, electro-funk\nchiptune, bitpop, electroclash\nchiptune, bitpop, hardcore techno\nchiptune, boogie-woogie, electronic\nchiptune, boogie-woogie, video game\nchiptune, boom-bap, electronic\nchiptune, bossa nova, Latin pop\nchiptune, brass band, funk\nchiptune, breakbeat, IDM\nchiptune, breakbeat, J-core\nchiptune, breakbeat, ambient\nchiptune, breakbeat, art pop\nchiptune, breakbeat, art rock\nchiptune, breakbeat, artcore\nchiptune, breakbeat, baroque\nchiptune, breakbeat, big beat\nchiptune, breakbeat, cinematic\nchiptune, breakbeat, drum and bass\nchiptune, breakbeat, electro house\nchiptune, breakbeat, funk\nchiptune, breakbeat, glitch-hop\nchiptune, breakbeat, happy hardcore\nchiptune, breakbeat, hardcore\nchiptune, breakbeat, instrumental\nchiptune, breakbeat, lo-fi\nchiptune, breakbeat, speedcore\nchiptune, breakbeat, trance\nchiptune, breakbeat, world music\nchiptune, breakcore\nchiptune, breakcore, 8-bit\nchiptune, breakcore, J-core\nchiptune, breakcore, J-pop\nchiptune, breakcore, Vocaloid\nchiptune, breakcore, ambient\nchiptune, breakcore, anime\nchiptune, breakcore, drum and bass\nchiptune, breakcore, electro-funk\nchiptune, breakcore, glitch\nchiptune, breakcore, glitch hop\nchiptune, breakcore, industrial\nchiptune, breakcore, lo-fi\nchiptune, breakcore, lo-fi hip hop\nchiptune, breakcore, orchestral\nchiptune, breakcore, retro game\nchiptune, breakcore, shoegaze\nchiptune, breakcore, speedcore\nchiptune, breakcore, trance\nchiptune, brostep\nchiptune, brostep, electronic\nchiptune, carioca, lo-fi hip hop\nchiptune, carioca, pop\nchiptune, children's Christian, video game music\nchiptune, children's dance, 8-bit\nchiptune, children's music\nchiptune, children's music, 8-bit\nchiptune, children's music, Arabic\nchiptune, children's music, Arabic pop\nchiptune, children's music, Brazilian\nchiptune, children's music, C-pop\nchiptune, children's music, Christian\nchiptune, children's music, Christmas\nchiptune, children's music, Dutch pop\nchiptune, children's music, Filipino\nchiptune, children's music, French pop\nchiptune, children's music, German pop\nchiptune, children's music, Greek\nchiptune, children's music, Hindi pop\nchiptune, children's music, Indian pop\nchiptune, children's music, Indonesian pop\nchiptune, children's music, Islamic pop\nchiptune, children's music, Italian\nchiptune, children's music, Italian pop\nchiptune, children's music, J-pop\nchiptune, children's music, K-pop\nchiptune, children's music, Latin pop\nchiptune, children's music, Mandarin pop\nchiptune, children's music, Nepali\nchiptune, children's music, Romanian\nchiptune, children's music, Tamil\nchiptune, children's music, Tamil pop\nchiptune, children's music, Telugu\nchiptune, children's music, Turkish\nchiptune, children's music, Turkish pop\nchiptune, children's music, V-pop\nchiptune, children's music, Vietnamese pop\nchiptune, children's music, Vocaloid\nchiptune, children's music, digital-folk\nchiptune, children's music, educational\nchiptune, children's music, electronic\nchiptune, children's music, eurodance\nchiptune, children's music, experimental\nchiptune, children's music, festive\nchiptune, children's music, funk\nchiptune, children's music, holiday\nchiptune, children's music, hyperpop\nchiptune, children's music, indie pop\nchiptune, children's music, k-pop\nchiptune, children's music, karaoke\nchiptune, children's music, lo-fi\nchiptune, children's music, lo-fi pop\nchiptune, children's music, orchestral jingle\nchiptune, children's music, patriotic\nchiptune, children's music, playful\nchiptune, children's music, pop\nchiptune, children's music, pop-rock\nchiptune, children's music, retro\nchiptune, children's music, retro game\nchiptune, children's music, retro pop\nchiptune, children's music, synth pop\nchiptune, children's music, synth-pop\nchiptune, children's music, synthpop\nchiptune, children's music, upbeat\nchiptune, children's music, video game\nchiptune, children's music, video game music\nchiptune, children's music, video game soundtrack\nchiptune, children's music, western\nchiptune, children's novelty, video game music\nchiptune, children's party, video game music\nchiptune, children's pop, retro game\nchiptune, children's, Arabic pop\nchiptune, children's, Hindi pop\nchiptune, children's, J-pop\nchiptune, children's, comedy\nchiptune, children's, educational\nchiptune, children's, electronic\nchiptune, children's, lo-fi\nchiptune, children's, theatrical\nchiptune, children's, western\nchiptune, choral, cinematic\nchiptune, cinematic electronic, breakbeat\nchiptune, cinematic electronic, video game music\nchiptune, cinematic rock, breakcore\nchiptune, cinematic, 16-bit\nchiptune, cinematic, C-pop\nchiptune, cinematic, Cantonese\nchiptune, cinematic, French chanson\nchiptune, cinematic, Indian fusion\nchiptune, cinematic, K-pop\nchiptune, cinematic, RPG\nchiptune, cinematic, Vocaloid\nchiptune, cinematic, ambient\nchiptune, cinematic, baroque\nchiptune, cinematic, choir\nchiptune, cinematic, electronic\nchiptune, cinematic, epic\nchiptune, cinematic, ethereal\nchiptune, cinematic, fairytale\nchiptune, cinematic, fantasy\nchiptune, cinematic, fantasy RPG\nchiptune, cinematic, glitch\nchiptune, cinematic, heroic\nchiptune, cinematic, lo-fi\nchiptune, cinematic, musical theater\nchiptune, cinematic, operatic\nchiptune, cinematic, orchestral\nchiptune, cinematic, pop\nchiptune, cinematic, pop-punk\nchiptune, cinematic, rock\nchiptune, cinematic, synthwave\nchiptune, cinematic, video game\nchiptune, cinematic, world fusion\nchiptune, circus, Latin\nchiptune, city pop\nchiptune, city pop, 16-bit\nchiptune, city pop, J-pop\nchiptune, city pop, funk\nchiptune, city pop, retro-futuristic\nchiptune, city pop, synth-funk\nchiptune, classical, J-RPG\nchiptune, classical, synth-pop\nchiptune, classical, world music\nchiptune, cloud rap, German trap\nchiptune, cloud rap, UK grime\nchiptune, cloud rap, emo rap\nchiptune, cloud rap, emo trap\nchiptune, cloud rap, hyperpop\nchiptune, cloud rap, lo-fi hip-hop\nchiptune, cloud rap, synth-pop\nchiptune, cloud rap, vaporwave\nchiptune, coldwave, lo-fi\nchiptune, color bass, dubstep\nchiptune, comedic, polka\nchiptune, comedic, theatrical\nchiptune, comedy, satirical\nchiptune, complextro\nchiptune, complextro, J-core\nchiptune, complextro, ambient\nchiptune, complextro, artcore\nchiptune, complextro, breakcore\nchiptune, complextro, cinematic\nchiptune, complextro, dubstep\nchiptune, complextro, electro house\nchiptune, complextro, electronic\nchiptune, complextro, electronic dance\nchiptune, complextro, glitch\nchiptune, complextro, glitch-hop\nchiptune, complextro, hardcore\nchiptune, complextro, hardstyle\nchiptune, complextro, neurofunk\nchiptune, complextro, pop\nchiptune, complextro, pop-punk\nchiptune, complextro, trance\nchiptune, cumbia, electronic\nchiptune, cumbia, merengue\nchiptune, cumbia, reggaeton\nchiptune, cyber-pop, J-pop\nchiptune, cyberpunk, electronic\nchiptune, cyberpunk, lo-fi\nchiptune, cyberpunk, synthwave\nchiptune, dance, lo-fi\nchiptune, dangdut koplo, electronic\nchiptune, dangdut koplo, electronic dance\nchiptune, dangdut koplo, happy hardcore\nchiptune, dark pop, electronic\nchiptune, dark synthpop\nchiptune, darksynth, industrial\nchiptune, darkwave, industrial\nchiptune, darkwave, synth rock\nchiptune, dembow, electronic\nchiptune, demoscene, electronic\nchiptune, demoscene, synthwave\nchiptune, denpa, kawaii\nchiptune, denpa-kei\nchiptune, denpa-kei, J-pop\nchiptune, denpa-kei, hyperpop\nchiptune, denpa-kei, k-pop\nchiptune, denpa-kei, video game\nchiptune, desert ambient\nchiptune, devotional, Indian\nchiptune, devotional, Indian electronic\nchiptune, devotional, Indian fusion\nchiptune, devotional, South Asian\nchiptune, devotional, electronic\nchiptune, digital bhajan\nchiptune, digital cumbia, dembow\nchiptune, digital hardcore, lo-fi\nchiptune, dream pop\nchiptune, dream pop, Christmas\nchiptune, dream pop, ambient\nchiptune, dream pop, cinematic\nchiptune, dream pop, dance-pop\nchiptune, dream pop, electronic\nchiptune, dream pop, electronica\nchiptune, dream pop, glitch\nchiptune, dream pop, lo-fi\nchiptune, dream pop, lo-fi hip hop\nchiptune, dream pop, noise rock\nchiptune, dream pop, retro\nchiptune, dream pop, rock\nchiptune, dream pop, shoegaze\nchiptune, dream-pop, hip hop\nchiptune, drum & bass, dubstep\nchiptune, drum and bass, electronic\nchiptune, drum and bass, neurofunk\nchiptune, drum and bass, pop-punk\nchiptune, dubstep, C-pop\nchiptune, dubstep, Cantopop\nchiptune, dubstep, complextro\nchiptune, dubstep, electronic\nchiptune, dubstep, emotional electronic\nchiptune, dubstep, hip hop\nchiptune, early techno, retro-futuristic\nchiptune, educational, 8-bit\nchiptune, educational, Arabic\nchiptune, educational, Arabic pop\nchiptune, educational, Thai pop\nchiptune, educational, Vocaloid\nchiptune, educational, children's\nchiptune, educational, k-pop\nchiptune, educational, lo-fi\nchiptune, educational, pop\nchiptune, educational, quirky\nchiptune, educational, upbeat\nchiptune, educational, video game music\nchiptune, electro hip hop\nchiptune, electro house\nchiptune, electro house, bitpop\nchiptune, electro house, synth-pop\nchiptune, electro, aggressive\nchiptune, electro, glitch\nchiptune, electro, instrumental hip-hop\nchiptune, electro, lo-fi\nchiptune, electro, progressive house\nchiptune, electro, tech house\nchiptune, electro-funk\nchiptune, electro-house, hardstyle\nchiptune, electro-pop\nchiptune, electro-pop, brostep\nchiptune, electro-pop, complextro\nchiptune, electro-pop, cyberpunk\nchiptune, electronic dance\nchiptune, electronic dance music\nchiptune, electronic dance music, South Asian folk\nchiptune, electronic dance, Bollywood\nchiptune, electronic dance, Central Asian folk\nchiptune, electronic dance, Chinese folk opera\nchiptune, electronic dance, Indian folk\nchiptune, electronic dance, Indian fusion\nchiptune, electronic dance, Indian pop\nchiptune, electronic dance, Japanese video game\nchiptune, electronic dance, Mandarin pop\nchiptune, electronic dance, Middle Eastern\nchiptune, electronic dance, Middle Eastern fusion\nchiptune, electronic dance, North African\nchiptune, electronic dance, Persian vocal\nchiptune, electronic dance, Sinhala pop\nchiptune, electronic dance, South Asian\nchiptune, electronic dance, South Asian folk\nchiptune, electronic dance, South Asian fusion\nchiptune, electronic dance, South Asian pop\nchiptune, electronic dance, South Indian devotional\nchiptune, electronic dance, South Indian film music\nchiptune, electronic dance, South Indian folk\nchiptune, electronic dance, Southeast Asian pop\nchiptune, electronic dance, cinematic\nchiptune, electronic dance, glitch\nchiptune, electronic dance, hyperpop\nchiptune, electronic dance, lo-fi hip hop\nchiptune, electronic dance, synthpop\nchiptune, electronic dance, synthwave\nchiptune, electronic dance, upbeat\nchiptune, electronic pop\nchiptune, electronic pop, C-pop\nchiptune, electronic pop, Vocaloid\nchiptune, electronic rock, J-rock\nchiptune, electronic rock, brostep\nchiptune, electronic rock, dubstep\nchiptune, electronic rock, future bass\nchiptune, electronic rock, hyperpop\nchiptune, electronic rock, industrial\nchiptune, electronic, 8-bit\nchiptune, electronic, Arabic\nchiptune, electronic, Arabic fusion\nchiptune, electronic, Arabic pop\nchiptune, electronic, Arabic synth\nchiptune, electronic, Bollywood\nchiptune, electronic, C-pop\nchiptune, electronic, EDM\nchiptune, electronic, East Asian\nchiptune, electronic, Eastern European\nchiptune, electronic, French pop\nchiptune, electronic, French rap\nchiptune, electronic, French vocal\nchiptune, electronic, German pop\nchiptune, electronic, Greek pop\nchiptune, electronic, Hebrew rap\nchiptune, electronic, IDM\nchiptune, electronic, Indian classical\nchiptune, electronic, Indian comedy\nchiptune, electronic, Indian devotional\nchiptune, electronic, Indian fusion\nchiptune, electronic, Indian pop\nchiptune, electronic, Indonesian pop\nchiptune, electronic, J-core\nchiptune, electronic, J-pop\nchiptune, electronic, J-rap\nchiptune, electronic, JRPG\nchiptune, electronic, Japanese video game\nchiptune, electronic, Javanese pop\nchiptune, electronic, K-pop\nchiptune, electronic, Latin\nchiptune, electronic, Latin hip hop\nchiptune, electronic, Latin pop\nchiptune, electronic, Mandarin hip hop\nchiptune, electronic, Mandarin opera\nchiptune, electronic, Mandarin rap\nchiptune, electronic, Mandopop\nchiptune, electronic, Marathi pop\nchiptune, electronic, Middle Eastern\nchiptune, electronic, Middle Eastern dance\nchiptune, electronic, Middle Eastern folk\nchiptune, electronic, Middle Eastern fusion\nchiptune, electronic, Persian hip hop\nchiptune, electronic, Persian pop\nchiptune, electronic, Punjabi pop\nchiptune, electronic, R&B\nchiptune, electronic, Russian hip hop\nchiptune, electronic, Russian pop\nchiptune, electronic, Russian rap\nchiptune, electronic, Sinhala pop\nchiptune, electronic, South Asian\nchiptune, electronic, Tibetan\nchiptune, electronic, UK garage\nchiptune, electronic, Ukrainian rap\nchiptune, electronic, Vietnamese rap\nchiptune, electronic, Vocaloid\nchiptune, electronic, aggressive\nchiptune, electronic, ambient\nchiptune, electronic, anime\nchiptune, electronic, anthem\nchiptune, electronic, anthemic\nchiptune, electronic, baroque\nchiptune, electronic, battle rap\nchiptune, electronic, brass\nchiptune, electronic, breakbeat\nchiptune, electronic, children's\nchiptune, electronic, cinematic\nchiptune, electronic, club\nchiptune, electronic, comedy\nchiptune, electronic, complexo\nchiptune, electronic, complextro\nchiptune, electronic, cyberpunk\nchiptune, electronic, dance\nchiptune, electronic, dark ambient\nchiptune, electronic, dark pop\nchiptune, electronic, demoscene\nchiptune, electronic, dream pop\nchiptune, electronic, energetic\nchiptune, electronic, epic\nchiptune, electronic, experimental\nchiptune, electronic, festive\nchiptune, electronic, folk\nchiptune, electronic, folk fusion\nchiptune, electronic, funk\nchiptune, electronic, funk carioca\nchiptune, electronic, future bass\nchiptune, electronic, glitch\nchiptune, electronic, happy hardcore\nchiptune, electronic, hardcore\nchiptune, electronic, hardstyle\nchiptune, electronic, heroic\nchiptune, electronic, hip hop\nchiptune, electronic, hyperpop\nchiptune, electronic, indie rock\nchiptune, electronic, industrial\nchiptune, electronic, industrial rock\nchiptune, electronic, kawaii future bass\nchiptune, electronic, lo-fi\nchiptune, electronic, lo-fi hip hop\nchiptune, electronic, lo-fi hip-hop\nchiptune, electronic, melodic rap\nchiptune, electronic, meme\nchiptune, electronic, minimal house\nchiptune, electronic, modern\nchiptune, electronic, orchestral\nchiptune, electronic, patriotic\nchiptune, electronic, playful\nchiptune, electronic, pop\nchiptune, electronic, pop-punk\nchiptune, electronic, post-punk\nchiptune, electronic, protest pop\nchiptune, electronic, quirky\nchiptune, electronic, rap\nchiptune, electronic, reggaeton\nchiptune, electronic, retro\nchiptune, electronic, retro game\nchiptune, electronic, retro-futuristic\nchiptune, electronic, rock\nchiptune, electronic, rock-opera\nchiptune, electronic, synthpop\nchiptune, electronic, synthwave\nchiptune, electronic, techno\nchiptune, electronic, theatrical\nchiptune, electronic, trance\nchiptune, electronic, trap\nchiptune, electronic, upbeat\nchiptune, electronic, uplifting\nchiptune, electronic, video game\nchiptune, electronic, video game music\nchiptune, electronic, video game soundtrack\nchiptune, electronic, world music\nchiptune, emo trap, cloud rap\nchiptune, emo-rap, synthpop\nchiptune, emotional synth, anime theme\nchiptune, epic, East Asian\nchiptune, epic, JRPG\nchiptune, epic, cinematic\nchiptune, estrada pop, video game music\nchiptune, ethereal, lo-fi\nchiptune, ethereal, operatic\nchiptune, euro-pop, lo-fi\nchiptune, eurobeat\nchiptune, eurobeat, j-core\nchiptune, eurodance\nchiptune, eurodance, 8-bit\nchiptune, eurodance, Russian pop\nchiptune, eurodance, Turkish pop\nchiptune, eurodance, electronic\nchiptune, eurodance, happy hardcore\nchiptune, eurodance, italo-disco\nchiptune, eurodance, lo-fi\nchiptune, eurodance, novelty\nchiptune, eurodance, pop\nchiptune, eurodance, trance\nchiptune, eurodance, video game\nchiptune, experimental electronic, lo-fi\nchiptune, experimental hip-hop, lo-fi\nchiptune, experimental, liturgical\nchiptune, experimental, quirky\nchiptune, fado, lo-fi\nchiptune, fantasy, synthwave\nchiptune, festive, C-pop\nchiptune, festive, German pop\nchiptune, festive, Spanish pop\nchiptune, festive, Vocaloid\nchiptune, festive, lo-fi\nchiptune, festive, pop\nchiptune, festive, video game music\nchiptune, flamenco, Middle Eastern\nchiptune, folk dance, lo-fi\nchiptune, folk fusion, Southeast Asian\nchiptune, folk fusion, dance\nchiptune, folk fusion, dance-pop\nchiptune, folk fusion, electronic\nchiptune, folk fusion, electronic dance\nchiptune, folk fusion, high-energy\nchiptune, folk fusion, upbeat\nchiptune, folk fusion, video game music\nchiptune, folk rock, cinematic\nchiptune, folk, 8-bit\nchiptune, folk, Bengali\nchiptune, folk, Southeast Asian\nchiptune, folk, ambient\nchiptune, folk, children's music\nchiptune, folk, cinematic\nchiptune, folk, dance\nchiptune, folk, electronic\nchiptune, folk, euro pop\nchiptune, folk, lo-fi\nchiptune, folk, opera\nchiptune, folk, polka\nchiptune, folk, retro\nchiptune, folk, rock\nchiptune, folk, upbeat\nchiptune, folk, video game music\nchiptune, folk-electronic, South Asian fusion\nchiptune, folk-pop, South Asian fusion\nchiptune, folk-pop, novelty\nchiptune, folk-pop, rock\nchiptune, folk-pop, synth-pop\nchiptune, forró eletrônico\nchiptune, forró, frevo\nchiptune, funk, Caribbean pop\nchiptune, funk, French pop\nchiptune, funk, French rap\nchiptune, funk, South Asian fusion\nchiptune, funk, ambient\nchiptune, funk, breakbeat\nchiptune, funk, city pop\nchiptune, funk, electronic\nchiptune, funk, glitch\nchiptune, funk, jazz fusion\nchiptune, funk, lo-fi\nchiptune, funk, narrative pop\nchiptune, funk, synthwave\nchiptune, funk-rock, punk rock\nchiptune, future bass, J-core\nchiptune, future bass, UK garage\nchiptune, future bass, UK hardcore\nchiptune, future bass, Vocaloid\nchiptune, future bass, artcore\nchiptune, future bass, complextro\nchiptune, future bass, dream pop\nchiptune, future bass, electro house\nchiptune, future bass, electronic\nchiptune, future bass, happy hardcore\nchiptune, future bass, hardstyle\nchiptune, future bass, house\nchiptune, future bass, kawaii\nchiptune, future bass, trap\nchiptune, future funk, J-core\nchiptune, future garage\nchiptune, gabber, hardstyle\nchiptune, ghazal, electronic\nchiptune, ghazal, retro electronic\nchiptune, glam rock, new wave\nchiptune, glitch hop, world music\nchiptune, glitch, Vocaloid\nchiptune, glitch, breakcore\nchiptune, glitch, dark ambient\nchiptune, glitch, electronic\nchiptune, glitch, lo-fi\nchiptune, glitch, synthwave\nchiptune, glitch-hop, electronic\nchiptune, glitch-hop, lo-fi hip hop\nchiptune, glitch-hop, trap\nchiptune, gospel, Christian\nchiptune, gospel, orchestral\nchiptune, grime, dubstep\nchiptune, gufeng, video game music\nchiptune, guzheng, electronic\nchiptune, guzheng, playful\nchiptune, hands-up trance\nchiptune, happy hardcore\nchiptune, happy hardcore, C-pop\nchiptune, happy hardcore, J-core\nchiptune, happy hardcore, J-pop electronic\nchiptune, happy hardcore, Japanese electronic\nchiptune, happy hardcore, Japanese video game music\nchiptune, happy hardcore, Nintendocore\nchiptune, happy hardcore, South Indian devotional\nchiptune, happy hardcore, Southeast Asian fusion\nchiptune, happy hardcore, UK hardcore\nchiptune, happy hardcore, breakcore\nchiptune, happy hardcore, children's music\nchiptune, happy hardcore, cinematic\nchiptune, happy hardcore, complextro\nchiptune, happy hardcore, dubstep\nchiptune, happy hardcore, electro house\nchiptune, happy hardcore, electronic\nchiptune, happy hardcore, electronic dance\nchiptune, happy hardcore, eurobeat\nchiptune, happy hardcore, gabber\nchiptune, happy hardcore, hardstyle\nchiptune, happy hardcore, hyperpop\nchiptune, happy hardcore, novelty\nchiptune, happy hardcore, piano ballad\nchiptune, happy hardcore, pop\nchiptune, happy hardcore, rap\nchiptune, happy hardcore, speedcore\nchiptune, happy hardcore, synth-pop\nchiptune, happy hardcore, trance\nchiptune, happy hardcore, video game music\nchiptune, hard dance\nchiptune, hard dance, electronic\nchiptune, hard dance, trance\nchiptune, hard electronic\nchiptune, hard rock, EDM\nchiptune, hard rock, acoustic folk\nchiptune, hard rock, electronic dance music\nchiptune, hard techno\nchiptune, hard trance\nchiptune, hard trance, happy hardcore\nchiptune, hard trance, hardcore techno\nchiptune, hard trance, synthwave\nchiptune, hard trance, techno\nchiptune, hard trance, video game music\nchiptune, hardcore techno\nchiptune, hardcore techno, J-core\nchiptune, hardcore techno, Japanese rhythm game\nchiptune, hardcore techno, gabber\nchiptune, hardcore techno, nintendocore\nchiptune, hardcore techno, trance\nchiptune, hardcore, gabber\nchiptune, hardcore, speedcore\nchiptune, hardstyle\nchiptune, hardstyle, J-pop\nchiptune, hardstyle, Vocaloid\nchiptune, hardstyle, ambient\nchiptune, hardstyle, cinematic\nchiptune, hardstyle, electronic\nchiptune, hardstyle, emotional pop\nchiptune, hardstyle, emotional synth\nchiptune, hardstyle, happy hardcore\nchiptune, hardstyle, lo-fi\nchiptune, hardstyle, pop\nchiptune, hardstyle, techno\nchiptune, hardstyle, trance\nchiptune, heroic, Middle Eastern\nchiptune, hip hop, C-pop\nchiptune, hip hop, Cebuano rap\nchiptune, hip hop, French rap\nchiptune, hip hop, Portuguese rap\nchiptune, hip hop, electronic\nchiptune, hip-hop\nchiptune, holiday, electronic\nchiptune, hymnal, folk\nchiptune, hyper-pop\nchiptune, hyper-pop, kawaii\nchiptune, hyper-speed ragtime\nchiptune, hyperpop\nchiptune, hyperpop, Brazilian funk\nchiptune, hyperpop, C-pop\nchiptune, hyperpop, J-core\nchiptune, hyperpop, J-pop\nchiptune, hyperpop, J-rock\nchiptune, hyperpop, Malayalam pop\nchiptune, hyperpop, Moroccan hip-hop\nchiptune, hyperpop, Vocaloid\nchiptune, hyperpop, ambient\nchiptune, hyperpop, bedroom pop\nchiptune, hyperpop, bitpop\nchiptune, hyperpop, comedic\nchiptune, hyperpop, dark pop\nchiptune, hyperpop, electronic\nchiptune, hyperpop, emo rap\nchiptune, hyperpop, emo-rap\nchiptune, hyperpop, glitch\nchiptune, hyperpop, happy hardcore\nchiptune, hyperpop, kawaii future bass\nchiptune, hyperpop, lo-fi\nchiptune, hyperpop, lo-fi hip hop\nchiptune, hyperpop, nintendocore\nchiptune, hyperpop, trap\nchiptune, indie folk, cinematic\nchiptune, indie folk, hip-hop\nchiptune, indie rock, Latin hip hop\nchiptune, indie rock, bedroom pop\nchiptune, indie rock, lo-fi\nchiptune, indie rock, lo-fi hip hop\nchiptune, indie rock, shoegaze\nchiptune, indie rock, synth pop\nchiptune, indie synth-pop, lo-fi\nchiptune, indie-pop, electronic\nchiptune, industrial electro, cyberpunk\nchiptune, industrial hip-hop\nchiptune, industrial metal\nchiptune, industrial rock\nchiptune, industrial rock, French pop\nchiptune, industrial rock, ambient\nchiptune, industrial rock, lo-fi\nchiptune, industrial rock, lo-fi hip hop\nchiptune, industrial rock, synthwave\nchiptune, industrial, French pop\nchiptune, industrial, breakcore\nchiptune, industrial, cinematic\nchiptune, industrial, cyberpunk\nchiptune, industrial, electronic\nchiptune, industrial, lo-fi\nchiptune, industrial, rap\nchiptune, instrumental hip-hop, electro\nchiptune, instrumental, Latin fusion\nchiptune, j-pop, electronic\nchiptune, jangle pop\nchiptune, jazz, Vocaloid\nchiptune, jingle, anime\nchiptune, jungle, ambient\nchiptune, jungle, drum and bass\nchiptune, k-pop, children's music\nchiptune, k-pop, pansori\nchiptune, kawaii future bass\nchiptune, kawaii future bass, J-pop\nchiptune, kawaii, C-pop\nchiptune, kawaii, anime\nchiptune, kawaii, dark pop\nchiptune, kawaii, electronic\nchiptune, kawaii, video game music\nchiptune, klezmer, Russian folk\nchiptune, klezmer, electronic\nchiptune, klezmer, video game music\nchiptune, latin jazz, bossa nova\nchiptune, liturgical, epic\nchiptune, lo-fi electronic, Hindi pop\nchiptune, lo-fi electronic, Japanese pop\nchiptune, lo-fi electronic, Vocaloid\nchiptune, lo-fi hip hop\nchiptune, lo-fi hip hop, Brazilian funk\nchiptune, lo-fi hip hop, Brazilian pop\nchiptune, lo-fi hip hop, C-pop\nchiptune, lo-fi hip hop, Chinese rap\nchiptune, lo-fi hip hop, Filipino rap\nchiptune, lo-fi hip hop, French rap\nchiptune, lo-fi hip hop, German rap\nchiptune, lo-fi hip hop, Indian electronic\nchiptune, lo-fi hip hop, Italian pop\nchiptune, lo-fi hip hop, J-pop\nchiptune, lo-fi hip hop, J-rap\nchiptune, lo-fi hip hop, Javanese pop\nchiptune, lo-fi hip hop, K-pop\nchiptune, lo-fi hip hop, Latin\nchiptune, lo-fi hip hop, Latin R&B\nchiptune, lo-fi hip hop, Mandopop\nchiptune, lo-fi hip hop, R&B\nchiptune, lo-fi hip hop, Russian rap\nchiptune, lo-fi hip hop, Slovak rap\nchiptune, lo-fi hip hop, UK rap\nchiptune, lo-fi hip hop, ambient\nchiptune, lo-fi hip hop, bedroom pop\nchiptune, lo-fi hip hop, cloud rap\nchiptune, lo-fi hip hop, electronic\nchiptune, lo-fi hip hop, emo-rap\nchiptune, lo-fi hip hop, glitch\nchiptune, lo-fi hip hop, hyperpop\nchiptune, lo-fi hip hop, indie folk, dream pop\nchiptune, lo-fi hip hop, neo-soul\nchiptune, lo-fi hip hop, polka\nchiptune, lo-fi hip hop, pop\nchiptune, lo-fi hip hop, trap\nchiptune, lo-fi hip hop, video game music\nchiptune, lo-fi hip-hop, C-pop\nchiptune, lo-fi hip-hop, synth-pop\nchiptune, lo-fi house, electronic\nchiptune, lo-fi pop, C-pop\nchiptune, lo-fi pop, bedroom pop\nchiptune, lo-fi, Brazilian funk\nchiptune, lo-fi, C-pop\nchiptune, lo-fi, Eastern European\nchiptune, lo-fi, French hip-hop\nchiptune, lo-fi, Javanese pop\nchiptune, lo-fi, Kollywood pop\nchiptune, lo-fi, Latin pop\nchiptune, lo-fi, Mandopop\nchiptune, lo-fi, R&B\nchiptune, lo-fi, Russian pop\nchiptune, lo-fi, Tamil pop\nchiptune, lo-fi, Turkish folk\nchiptune, lo-fi, Vietnamese pop\nchiptune, lo-fi, Vocaloid\nchiptune, lo-fi, aggressive\nchiptune, lo-fi, ambient\nchiptune, lo-fi, ambient pop\nchiptune, lo-fi, anime\nchiptune, lo-fi, arcade\nchiptune, lo-fi, baroque-pop\nchiptune, lo-fi, bedroom pop\nchiptune, lo-fi, breakcore\nchiptune, lo-fi, cinematic\nchiptune, lo-fi, comedic\nchiptune, lo-fi, dance\nchiptune, lo-fi, dark synth\nchiptune, lo-fi, demoscene\nchiptune, lo-fi, dubstep\nchiptune, lo-fi, eerie\nchiptune, lo-fi, electric guitar\nchiptune, lo-fi, electro\nchiptune, lo-fi, electronic\nchiptune, lo-fi, ethereal\nchiptune, lo-fi, experimental\nchiptune, lo-fi, folk\nchiptune, lo-fi, funk-rock\nchiptune, lo-fi, gabber\nchiptune, lo-fi, garage rock\nchiptune, lo-fi, glitch\nchiptune, lo-fi, happy hardcore\nchiptune, lo-fi, hyperpop\nchiptune, lo-fi, indie folk\nchiptune, lo-fi, indie-pop\nchiptune, lo-fi, industrial\nchiptune, lo-fi, k-pop\nchiptune, lo-fi, kawaii\nchiptune, lo-fi, melancholic\nchiptune, lo-fi, new wave\nchiptune, lo-fi, noise rock\nchiptune, lo-fi, nostalgic\nchiptune, lo-fi, novelty\nchiptune, lo-fi, pop\nchiptune, lo-fi, protest\nchiptune, lo-fi, punk\nchiptune, lo-fi, quirky\nchiptune, lo-fi, retro\nchiptune, lo-fi, retro-futuristic\nchiptune, lo-fi, schlager\nchiptune, lo-fi, shoegaze\nchiptune, lo-fi, synthpop\nchiptune, lo-fi, synthwave\nchiptune, lo-fi, video game music\nchiptune, lounge jazz\nchiptune, lounge, Vocaloid\nchiptune, lounge-jazz, synthpop\nchiptune, luk thung, electronic\nchiptune, luk thung, electronic pop\nchiptune, lullaby\nchiptune, math rock, progressive electronic\nchiptune, math rock, video game music\nchiptune, melancholic, Italian pop\nchiptune, melancholic, electronic\nchiptune, military march, estrada\nchiptune, minimal synth, electronic\nchiptune, minimal synth, lo-fi\nchiptune, music box, dark pop\nchiptune, musical theater, Christmas novelty\nchiptune, musical theater, lo-fi\nchiptune, musical theater, novelty\nchiptune, musical theater, video game\nchiptune, narrative, lo-fi\nchiptune, neo-baroque\nchiptune, neo-classical, electronic\nchiptune, neo-soul, city pop\nchiptune, neo-soul, funk\nchiptune, neo-soul, hip-hop\nchiptune, neo-soul, lo-fi hip-hop\nchiptune, neoclassical, gothic\nchiptune, neoclassical, video game\nchiptune, neoclassical, video game music\nchiptune, new jack swing, French R&B\nchiptune, new jack swing, retro pop\nchiptune, new jack swing, soul\nchiptune, new jack swing, synthpop\nchiptune, nightcore, lo-fi\nchiptune, noise rock, electronic\nchiptune, novelty pop, Vocaloid\nchiptune, novelty pop, lo-fi hip hop\nchiptune, novelty, 8-bit\nchiptune, novelty, Christmas\nchiptune, novelty, Dutch pop\nchiptune, novelty, Filipino pop\nchiptune, novelty, German Schlager\nchiptune, novelty, Italian pop\nchiptune, novelty, J-pop\nchiptune, novelty, Latin pop\nchiptune, novelty, Turkish pop\nchiptune, novelty, calypso\nchiptune, novelty, children's dance\nchiptune, novelty, children's music\nchiptune, novelty, country-folk\nchiptune, novelty, dance\nchiptune, novelty, electronic\nchiptune, novelty, polka\nchiptune, novelty, video game music\nchiptune, operatic, Mandarin\nchiptune, operatic, ambient\nchiptune, operatic, cinematic\nchiptune, operatic, electronic\nchiptune, operatic, world music\nchiptune, orchestral synth, lo-fi\nchiptune, orchestral synth, synth-rock\nchiptune, orchestral, 8-bit\nchiptune, orchestral, Arabic pop\nchiptune, orchestral, anime\nchiptune, orchestral, cinematic\nchiptune, orchestral, epic\nchiptune, orchestral, hardstyle\nchiptune, orchestral, hymn\nchiptune, orchestral, lo-fi\nchiptune, orchestral, retro game\nchiptune, orchestral, synth-pop\nchiptune, orchestral, trap\nchiptune, orchestral, video game\nchiptune, piano ballad\nchiptune, piano ballad, Vocaloid\nchiptune, piseiro, electronic\nchiptune, piseiro, lo-fi\nchiptune, piseiro, pop\nchiptune, playful, Hindi pop\nchiptune, playful, ambient\nchiptune, playful, educational\nchiptune, pluggnb, trap\nchiptune, polka, C-pop\nchiptune, polka, J-rock\nchiptune, polka, Russian folk-pop\nchiptune, polka, children's music\nchiptune, polka, educational\nchiptune, polka, electronic\nchiptune, polka, energetic\nchiptune, polka, playful\nchiptune, pop\nchiptune, pop, Indian\nchiptune, pop, Indonesian children's\nchiptune, pop, Indonesian pop\nchiptune, pop, Italian folk\nchiptune, pop, Latin\nchiptune, pop, Middle Eastern\nchiptune, pop, Thai\nchiptune, pop, Vocaloid\nchiptune, pop, children's music\nchiptune, pop, electronic\nchiptune, pop, hip hop\nchiptune, pop, lo-fi\nchiptune, pop, operatic\nchiptune, pop, orchestral\nchiptune, pop-punk, electronic\nchiptune, pop-rock, anime\nchiptune, post-punk, coldwave\nchiptune, post-punk, electronic\nchiptune, power ballad, cinematic\nchiptune, progressive electronic, synthwave\nchiptune, progressive house\nchiptune, progressive house, emotional pop\nchiptune, progressive house, synthwave\nchiptune, progressive house, trance\nchiptune, progressive house, tribal house\nchiptune, progressive metal, electronic rock\nchiptune, progressive metal, synthwave\nchiptune, progressive rock, heavy metal\nchiptune, progressive rock, orchestral\nchiptune, progressive trance\nchiptune, psytrance, hardstyle\nchiptune, punk, lo-fi\nchiptune, ragtime, Nintendocore\nchiptune, ragtime, Vocaloid\nchiptune, ragtime, electronic\nchiptune, rap, operatic\nchiptune, rap-rock\nchiptune, reggae-ska, video game\nchiptune, reggaeton, Brazilian funk\nchiptune, reggaeton, cinematic\nchiptune, reggaeton, cumbia\nchiptune, reggaeton, electronic\nchiptune, reggaeton, lo-fi\nchiptune, reggaeton-trap, hyperpop\nchiptune, regional Mexican, Latin pop\nchiptune, regional Mexican, dance\nchiptune, regional Mexican, norteño\nchiptune, regional Mexican, synth pop\nchiptune, retro Indian, children's music\nchiptune, retro electronic, C-pop\nchiptune, retro electronic, Southeast Asian fusion\nchiptune, retro game, Halloween\nchiptune, retro game, funk\nchiptune, retro pop, Eastern European pop\nchiptune, retro, C-pop\nchiptune, retro, Filipino Christmas\nchiptune, retro, Indian pop\nchiptune, retro, Southeast Asian pop\nchiptune, retro, Sundanese pop\nchiptune, retro, Tamil film music\nchiptune, retro, lo-fi\nchiptune, retro, spy theme\nchiptune, retro, theatrical\nchiptune, retro-electronic, K-pop\nchiptune, retro-futuristic, Bollywood\nchiptune, retro-futuristic, C-pop\nchiptune, retro-futuristic, Indian film music\nchiptune, retro-futuristic, South Asian\nchiptune, retro-futuristic, corporate anthem\nchiptune, retro-futuristic, electronic\nchiptune, retro-futuristic, flamenco\nchiptune, retro-futuristic, synthwave\nchiptune, retro-futuristic, world music\nchiptune, rock, Nintendocore\nchiptune, rock, cinematic\nchiptune, rock-opera, electronic\nchiptune, romantic, nostalgic\nchiptune, sacred, cinematic\nchiptune, sad trap, hyperpop\nchiptune, schlager\nchiptune, schlager, retro\nchiptune, sertanejo, pop\nchiptune, shoegaze, ambient\nchiptune, shoegaze, indie rock\nchiptune, shoegaze, lo-fi\nchiptune, shoegaze, noise rock\nchiptune, shoegaze, noise-pop\nchiptune, shoegaze, post-rock\nchiptune, shoegaze, punk rock\nchiptune, shred guitar, electronic\nchiptune, soulful, cinematic\nchiptune, speedcore\nchiptune, speedcore, J-core\nchiptune, speedcore, Japanese rock\nchiptune, speedcore, Japanese video game music\nchiptune, speedcore, artcore\nchiptune, speedcore, breakcore\nchiptune, speedcore, classical piano\nchiptune, speedcore, electronic\nchiptune, speedcore, happy hardcore\nchiptune, speedcore, hyperpop\nchiptune, speedcore, lo-fi\nchiptune, speedcore, nintendocore\nchiptune, speedcore, video game\nchiptune, speedcore, video game music\nchiptune, spiritual, ambient\nchiptune, spiritual, lo-fi\nchiptune, spy thriller, C-pop\nchiptune, surf rock, cinematic\nchiptune, symphonic electronic, JRPG\nchiptune, symphonic rock\nchiptune, symphonic rock, J-pop\nchiptune, symphonic rock, Nintendocore\nchiptune, synth brass, video game\nchiptune, synth fusion, cinematic\nchiptune, synth orchestral, Vocaloid\nchiptune, synth pop, cinematic\nchiptune, synth pop, lo-fi\nchiptune, synth rock, RPG soundtrack\nchiptune, synth-funk, J-R&B\nchiptune, synth-funk, electro-pop\nchiptune, synth-pop\nchiptune, synth-pop, 80s electronic\nchiptune, synth-pop, C-pop\nchiptune, synth-pop, Chinese opera\nchiptune, synth-pop, Christmas\nchiptune, synth-pop, Indian film music\nchiptune, synth-pop, Indian folk\nchiptune, synth-pop, Indian pop\nchiptune, synth-pop, Indonesian pop\nchiptune, synth-pop, Islamic devotional\nchiptune, synth-pop, Italo-disco\nchiptune, synth-pop, J-core\nchiptune, synth-pop, J-pop\nchiptune, synth-pop, Vocaloid\nchiptune, synth-pop, ambient\nchiptune, synth-pop, anime\nchiptune, synth-pop, baroque\nchiptune, synth-pop, children's\nchiptune, synth-pop, children's Christian\nchiptune, synth-pop, children's music\nchiptune, synth-pop, dream-pop\nchiptune, synth-pop, drum and bass\nchiptune, synth-pop, dubstep\nchiptune, synth-pop, electro\nchiptune, synth-pop, electro-house\nchiptune, synth-pop, electro-pop\nchiptune, synth-pop, electro-rock\nchiptune, synth-pop, electronic rock\nchiptune, synth-pop, experimental electronic\nchiptune, synth-pop, happy hardcore\nchiptune, synth-pop, hip-hop\nchiptune, synth-pop, hymnal\nchiptune, synth-pop, indie pop\nchiptune, synth-pop, industrial rock\nchiptune, synth-pop, lo-fi\nchiptune, synth-pop, luk thung\nchiptune, synth-pop, novelty Christmas\nchiptune, synth-pop, orchestral\nchiptune, synth-pop, patriotic\nchiptune, synth-pop, pop-rock\nchiptune, synth-pop, retro\nchiptune, synth-pop, rock\nchiptune, synth-pop, theatrical\nchiptune, synth-pop, video game\nchiptune, synth-pop, video game music\nchiptune, synth-pop, world music\nchiptune, synth-rock\nchiptune, synth-rock, Vocaloid\nchiptune, synth-rock, hyperpop\nchiptune, synth-rock, lo-fi\nchiptune, synthpop, French rap\nchiptune, synthpop, baroque\nchiptune, synthpop, circus\nchiptune, synthpop, lo-fi\nchiptune, synthpop, lo-fi hip hop\nchiptune, synthpop, metal\nchiptune, synthpop, rock opera\nchiptune, synthwave\nchiptune, synthwave, C-pop\nchiptune, synthwave, French electronic\nchiptune, synthwave, French pop\nchiptune, synthwave, Japanese RPG\nchiptune, synthwave, Kazakh pop\nchiptune, synthwave, Latin pop\nchiptune, synthwave, Vocaloid\nchiptune, synthwave, ambient\nchiptune, synthwave, cinematic\nchiptune, synthwave, cyberpunk\nchiptune, synthwave, dark pop\nchiptune, synthwave, electro\nchiptune, synthwave, electro house\nchiptune, synthwave, electro-funk\nchiptune, synthwave, electronic\nchiptune, synthwave, future bass\nchiptune, synthwave, lo-fi\nchiptune, synthwave, retro-futuristic\nchiptune, synthwave, spy thriller\nchiptune, synthwave, video game music\nchiptune, synthwave, vocaloid\nchiptune, techno, electronic\nchiptune, theatrical pop\nchiptune, theatrical pop, electronic\nchiptune, theatrical pop, retro\nchiptune, theatrical pop, synth-pop\nchiptune, theatrical, 8-bit\nchiptune, theatrical, C-pop\nchiptune, theatrical, Eastern European\nchiptune, theatrical, comedic\nchiptune, theatrical, duet\nchiptune, theatrical, electronic\nchiptune, theatrical, gothic\nchiptune, theatrical, lo-fi\nchiptune, theatrical, pop\nchiptune, theatrical, retro\nchiptune, theatrical, retro game\nchiptune, theatrical, video game\nchiptune, traditional Southeast Asian, dance\nchiptune, trance, dubstep\nchiptune, trance, electronic\nchiptune, trance, happy hardcore\nchiptune, trance, hardstyle\nchiptune, trance, synthwave\nchiptune, trance, techno\nchiptune, trap\nchiptune, trap, Brazilian funk\nchiptune, trap, J-pop\nchiptune, trap, Mandopop\nchiptune, trap, R&B\nchiptune, trap, ambient\nchiptune, trap, cloud rap\nchiptune, trap, dubstep\nchiptune, trap, electronic\nchiptune, trap, emo-rap\nchiptune, trap, hyperpop\nchiptune, trap, lo-fi\nchiptune, trap, lo-fi hip hop\nchiptune, trap, synth-pop\nchiptune, trap, synthpop\nchiptune, tribal, electronic\nchiptune, tropical house, world music\nchiptune, tropical, electronic\nchiptune, trot, electronic\nchiptune, trot, lo-fi\nchiptune, trot, retro\nchiptune, upbeat, Bollywood\nchiptune, upbeat, Middle Eastern\nchiptune, upbeat, children's music\nchiptune, upbeat, playful\nchiptune, upbeat, retro game\nchiptune, vaporwave, funk\nchiptune, vaporwave, lo-fi hip hop\nchiptune, vaporwave, phonk\nchiptune, video game music\nchiptune, video game music, Christmas\nchiptune, video game music, French cartoon\nchiptune, video game music, Halloween\nchiptune, video game music, J-pop\nchiptune, video game music, Japanese children's\nchiptune, video game music, Latin pop\nchiptune, video game music, Thai pop\nchiptune, video game music, acoustic\nchiptune, video game music, ambient\nchiptune, video game music, cartoon\nchiptune, video game music, children's music\nchiptune, video game music, educational\nchiptune, video game music, electronic\nchiptune, video game music, energetic\nchiptune, video game music, festive\nchiptune, video game music, folk\nchiptune, video game music, folk dance\nchiptune, video game music, funk\nchiptune, video game music, future bass\nchiptune, video game music, holiday\nchiptune, video game music, instrumental\nchiptune, video game music, lo-fi\nchiptune, video game music, lo-fi hip hop\nchiptune, video game music, lounge\nchiptune, video game music, orchestral\nchiptune, video game music, playful\nchiptune, video game music, pop\nchiptune, video game music, quirky\nchiptune, video game music, synthpop\nchiptune, video game music, synthwave\nchiptune, video game music, upbeat\nchiptune, video game music, upbeat electronic\nchiptune, video game music, upbeat pop\nchiptune, video game soundtrack, RPG\nchiptune, video game soundtrack, ambient\nchiptune, video game soundtrack, baroque\nchiptune, video game soundtrack, energetic\nchiptune, video game soundtrack, orchestral\nchiptune, video game, East Asian\nchiptune, video game, baroque\nchiptune, video game, heroic\nchiptune, video game, lo-fi\nchiptune, video game, musical theater\nchiptune, video game, orchestral\nchiptune, video game, playful\nchiptune, video game, pop\nchiptune, video game, synthwave\nchiptune, video game, whimsical\nchiptune, video game, world fusion\nchiptune, vocaloid, hyperpop\nchiptune, western, children's\nchiptune, world fusion, lo-fi pop\nchiptune, world music, Islamic devotional\nchiptune, world music, children's\nchiptune, world music, dancehall\nchiptune, world music, devotional\nchiptune, world music, electronic\nchiptune, world music, epic fantasy\nchiptune, zouk, kompa\nchiptune, 喊麦, electronic\nchiptune,喊麦, electronic\nchiptune-electro\nchiptune-metal\nchiptune-pop\nchiptune-pop future bass\nchiptune-pop hyperpop\nchiptune-pop lo-fi hip-hop\nchiptune-pop metalcore\nchiptune-pop noise-rock\nchiptune-pop nu-metal\nchiptune-punk\nchirigota\nchirigota comparsa\nchoir\nchoir pop\nchoir, acoustic, emotional\nchoir, acoustic, hymn\nchoir, brass band, operatic\nchoir, classical, spiritual\nchoir, devotional, synth\nchoir, gospel, cinematic\nchoir, gospel, marching\nchoir, gospel, vintage\nchoir, sacred, organ\nchoir, worship, ukulele\nchopped and screwed\nchopped and screwed R&B\nchopped and screwed hip-hop\nchopped and screwed trap\nchopper hip-hop\nchopper rap\nchoral\nchoral Christmas\nchoral Latin\nchoral ambient\nchoral anthem\nchoral ballad\nchoral electronic\nchoral epic\nchoral flamenco\nchoral folk\nchoral gospel\nchoral grandeur\nchoral hymn\nchoral jazz\nchoral march\nchoral opera\nchoral pop\nchoral rock\nchoral sacred\nchoral synth-pop\nchoral worship\nchoral, Brazilian, traditional\nchoral, Christmas, festive\nchoral, Christmas, satirical\nchoral, Christmas, theatrical\nchoral, Christmas, traditional\nchoral, Latin march\nchoral, Latin, acoustic\nchoral, Latin, anthemic\nchoral, Latin, uplifting\nchoral, accordion, sacred\nchoral, acoustic, Latin\nchoral, acoustic, cinematic\nchoral, acoustic, classical\nchoral, acoustic, mariachi\nchoral, acoustic, sacred\nchoral, ambient, cinematic\nchoral, ambient, sacred\nchoral, anasheed\nchoral, ancient style\nchoral, big band, Christmas\nchoral, christmas, classical\nchoral, christmas, orchestral\nchoral, cinematic, Mandarin\nchoral, cinematic, ambient\nchoral, cinematic, classical\nchoral, cinematic, devotional\nchoral, classical guitar, Latin\nchoral, classical, Latin\nchoral, classical, ambient\nchoral, classical, christmas\nchoral, classical, folk\nchoral, classical, liturgical\nchoral, contemporary, Christmas\nchoral, gospel, country\nchoral, gospel, flamenco\nchoral, holiday, cinematic\nchoral, liturgical, anthemic\nchoral, orchestral, Christmas\nchoral, orchestral, celebratory\nchoral, orchestral, liturgical\nchoral, orchestral, pop-gospel\nchoral, orchestral, sacred\nchoral, progressive rock, baroque pop\nchoral, sacred, Christmas\nchoral, sacred, ambient\nchoral, sacred, christmas\nchoral, sacred, cinematic\nchoral, spiritual, ambient\nchoral, synth, christmas\nchoral, traditional, Christmas\nchoral, traditional, festive\nchoral, vocal percussion, cinematic\nchoral, world music, ambient\nchoral, world music, live performance\nchoral, worship, ambient\nchorale\nchoro\nchoro MPB\nchoro samba\nchoro samba jazz\nchoro tango\nchoro, Brazilian folk\nchoro, MPB\nchoro, MPB, Brazilian folk\nchurch hymn\nchurch music\nchurch organ\nchutney-soca\ncinematic\ncinematic 80s film score\ncinematic Afro-Cuban\ncinematic Afro-Latin\ncinematic Afro-pop\ncinematic Afrobeat\ncinematic Afrobeats\ncinematic Afropop\ncinematic Americana\ncinematic Andean\ncinematic Andean folk\ncinematic Arabic\ncinematic Arabic Christian worship\ncinematic Arabic anthem\ncinematic Arabic art song\ncinematic Arabic ballad\ncinematic Arabic classical\ncinematic Arabic crossover\ncinematic Arabic dance\ncinematic Arabic dance-pop\ncinematic Arabic devotional\ncinematic Arabic electronic\ncinematic Arabic electronica\ncinematic Arabic folk\ncinematic Arabic folk-pop\ncinematic Arabic fusion\ncinematic Arabic hip-hop\ncinematic Arabic jazz\ncinematic Arabic opera\ncinematic Arabic orchestral\ncinematic Arabic pop\ncinematic Arabic pop-rock\ncinematic Arabic protest\ncinematic Arabic rap\ncinematic Arabic rock\ncinematic Arabic spiritual\ncinematic Arabic trap\ncinematic Arabic worship\ncinematic Axé\ncinematic Balkan\ncinematic Balkan ballad\ncinematic Balkan folk\ncinematic Balkan fusion\ncinematic Balkan jazz\ncinematic Balkan pop\ncinematic Balkan pop-folk\ncinematic Balkan pop-rock\ncinematic Bengali\ncinematic Bhangra\ncinematic Bhangra-pop\ncinematic Bhojpuri\ncinematic Bollywood\ncinematic Bollywood dance-pop\ncinematic Brazilian\ncinematic Brazilian ballad\ncinematic Brazilian folk\ncinematic Brazilian funk\ncinematic Brazilian hymn\ncinematic C-pop\ncinematic C-pop chiptune\ncinematic C-pop future bass\ncinematic C-pop hip-hop\ncinematic C-pop jazz\ncinematic C-pop jazz fusion\ncinematic C-pop lo-fi hip-hop\ncinematic C-pop metalcore\ncinematic C-pop reggaeton\ncinematic C-pop rock\ncinematic C-pop salsa\ncinematic C-pop trap\ncinematic C-pop trip-hop\ncinematic C-pop, African gospel, Soukous\ncinematic C-pop, Brazilian forró\ncinematic C-pop, Christian rock\ncinematic C-pop, Dangdut Koplo\ncinematic C-pop, Eurodance, Latin pop\ncinematic C-pop, Eurodance, happy hardcore\ncinematic C-pop, German pop-rock\ncinematic C-pop, Indian classical, trap\ncinematic C-pop, J-rock\ncinematic C-pop, K-pop, hip-hop, R&B, dance-pop, lounge-pop\ncinematic C-pop, Latin salsa\ncinematic C-pop, Middle Eastern, dangdut koplo\ncinematic C-pop, Vietnamese folk\ncinematic C-pop, cyberpunk, electronic\ncinematic C-pop, dangdut koplo\ncinematic C-pop, electro-industrial\ncinematic C-pop, electronic rock\ncinematic C-pop, electronic rock, ancient style\ncinematic C-pop, electronic rock, trap\ncinematic C-pop, electronic, glitch\ncinematic C-pop, hardstyle\ncinematic C-pop, hardstyle EDM\ncinematic C-pop, hardstyle, Eurodance\ncinematic C-pop, hardstyle, dubstep\ncinematic C-pop, hardstyle, electronic\ncinematic C-pop, hip-hop, operatic\ncinematic C-pop, industrial ambient\ncinematic C-pop, jazz lounge, funk pop-rock\ncinematic C-pop, lo-fi hip hop\ncinematic C-pop, lo-fi hip-hop\ncinematic C-pop, nu-metal, traditional fusion\ncinematic C-pop, schlager, humppa\ncinematic C-pop, symphonic power metal\ncinematic C-pop, trap hip-hop\ncinematic C-pop, trap, ambient\ncinematic C-pop, trap, electronic rock\ncinematic C-pop, trap, operatic\ncinematic C-pop, trip-hop, electronic\ncinematic Carnatic\ncinematic Celtic\ncinematic Celtic folk\ncinematic Chinese\ncinematic Chinese anthem\ncinematic Chinese art song\ncinematic Chinese ballad\ncinematic Chinese classical\ncinematic Chinese electronic\ncinematic Chinese electronic pop\ncinematic Chinese fantasy\ncinematic Chinese flute\ncinematic Chinese folk\ncinematic Chinese folk-pop\ncinematic Chinese fusion\ncinematic Chinese hip-hop\ncinematic Chinese instrumental\ncinematic Chinese opera\ncinematic Chinese orchestra\ncinematic Chinese orchestral\ncinematic Chinese pop\ncinematic Chinese pop-rock\ncinematic Chinese rock\ncinematic Christian\ncinematic Christian ballad\ncinematic Christian country\ncinematic Christian hip-hop\ncinematic Christian hymn\ncinematic Christian pop\ncinematic Christian pop-rock\ncinematic Christian power ballad\ncinematic Christian rock\ncinematic Christmas\ncinematic Christmas ballad\ncinematic Christmas rock\ncinematic City Pop\ncinematic Cumbia\ncinematic D&B\ncinematic Dangdut\ncinematic Dangdut Koplo\ncinematic EBM\ncinematic EDM\ncinematic EDM C-pop\ncinematic EDM Indian pop\ncinematic EDM, C-pop\ncinematic EDM-pop\ncinematic East Asian\ncinematic East Asian ballad\ncinematic Euro-pop\ncinematic Eurobeat\ncinematic Eurodance\ncinematic Europop\ncinematic Fado\ncinematic Filipino power ballad\ncinematic Forró\ncinematic French ballad\ncinematic French chanson\ncinematic French hip-hop\ncinematic French pop\ncinematic French pop-rap\ncinematic French pop-rock\ncinematic French power ballad\ncinematic French rap\ncinematic G-funk\ncinematic German Schlager\ncinematic German chanson\ncinematic German hip-hop\ncinematic Greek\ncinematic Greek Laïko\ncinematic Greek art music\ncinematic Greek art song\ncinematic Greek art-song salsa\ncinematic Greek ballad\ncinematic Greek folk\ncinematic Greek folk-pop\ncinematic Greek opera\ncinematic Greek pop\ncinematic Greek pop-rock\ncinematic Greek power ballad\ncinematic Greek rock\ncinematic IDM\ncinematic Indian\ncinematic Indian Christian\ncinematic Indian ambient\ncinematic Indian anthem\ncinematic Indian ballad\ncinematic Indian bhajan\ncinematic Indian classical\ncinematic Indian classical fusion\ncinematic Indian dance-pop\ncinematic Indian devotional\ncinematic Indian devotional synth-pop\ncinematic Indian electronic\ncinematic Indian electronica\ncinematic Indian film\ncinematic Indian film ballad\ncinematic Indian film music\ncinematic Indian film score\ncinematic Indian filmi\ncinematic Indian folk\ncinematic Indian folk-pop\ncinematic Indian fusion\ncinematic Indian hip-hop\ncinematic Indian lullaby\ncinematic Indian orchestral\ncinematic Indian patriotic\ncinematic Indian pop\ncinematic Indian pop-rock\ncinematic Indian rock\ncinematic Indian score\ncinematic Indonesian\ncinematic Islamic\ncinematic Islamic devotional\ncinematic Italian\ncinematic Italian art song\ncinematic Italian ballad\ncinematic Italian ballad, surf-rock\ncinematic Italian canzone\ncinematic Italian pop\ncinematic Italian power ballad\ncinematic Italo dance\ncinematic Italo disco\ncinematic Italo-disco\ncinematic J-RPG\ncinematic J-core\ncinematic J-pop\ncinematic J-rock\ncinematic JRPG\ncinematic Japanese\ncinematic Japanese Kayōkyoku\ncinematic Japanese RPG\ncinematic Japanese ballad\ncinematic Japanese folk\ncinematic Javanese\ncinematic Javanese folk\ncinematic Javanese pop\ncinematic K-ballad\ncinematic K-drama OST\ncinematic K-folk\ncinematic K-pop\ncinematic K-trot\ncinematic Kizomba\ncinematic Klezmer\ncinematic Korean trot\ncinematic Latin\ncinematic Latin Christian\ncinematic Latin ballad\ncinematic Latin big band\ncinematic Latin cumbia\ncinematic Latin dance\ncinematic Latin folk\ncinematic Latin funk\ncinematic Latin fusion\ncinematic Latin jazz\ncinematic Latin orchestral\ncinematic Latin pop\ncinematic Latin pop-rock\ncinematic Latin psychedelic\ncinematic Latin rock\ncinematic Latin soul\ncinematic Latin trap\ncinematic MPB\ncinematic MPB gospel\ncinematic Malay fusion\ncinematic Malay pop\ncinematic Malayalam\ncinematic Mandopop\ncinematic Mediterranean\ncinematic Middle Eastern\ncinematic Middle Eastern ballad\ncinematic Middle Eastern dance\ncinematic Middle Eastern fusion\ncinematic Middle Eastern pop\ncinematic Middle Eastern power ballad\ncinematic Māori\ncinematic Nepali\ncinematic Nepali ballad\ncinematic Nepali film score\ncinematic Nepali fusion\ncinematic Norteño\ncinematic Persian\ncinematic Persian ballad\ncinematic Persian classical\ncinematic Persian electronic\ncinematic Persian electronica\ncinematic Persian fusion\ncinematic Polish art song\ncinematic Punjabi\ncinematic Punjabi ballad\ncinematic Punjabi devotional\ncinematic Punjabi folk\ncinematic Punjabi folk-pop\ncinematic Punjabi fusion\ncinematic Punjabi pop\ncinematic R&B\ncinematic R&B gospel\ncinematic R&B hip-hop\ncinematic R&B lo-fi hip hop\ncinematic R&B pop\ncinematic R&B pop-rock\ncinematic R&B salsa\ncinematic R&B trap\ncinematic R&B zouk\ncinematic R&B, trap, South Asian fusion\ncinematic R&B-pop\ncinematic Rai\ncinematic Raï\ncinematic Russian chanson\ncinematic Russian estrada\ncinematic Russian pop\ncinematic Russian power ballad\ncinematic Russian romance\ncinematic Schlager\ncinematic Sinhala film music\ncinematic South Asian\ncinematic South Indian film score\ncinematic Soviet ballad\ncinematic Soviet march\ncinematic Soviet romance\ncinematic Soviet-era\ncinematic Spanish\ncinematic Spanish anthem\ncinematic Spanish ballad\ncinematic Spanish copla\ncinematic Spanish folk\ncinematic Spanish lullaby\ncinematic Spanish spoken word\ncinematic Sufi\ncinematic Tamil\ncinematic Tamil film music\ncinematic Tamil folk\ncinematic Tamil pop\ncinematic Tamil romance\ncinematic Tamil score\ncinematic Telugu folk\ncinematic Thai\ncinematic Thai Luk Thung\ncinematic Thai folk\ncinematic Thai lullaby\ncinematic Tollywood filmi\ncinematic Turkish\ncinematic Turkish arabesque\ncinematic Turkish art music\ncinematic Turkish ballad\ncinematic Turkish classical\ncinematic Turkish devotional\ncinematic Turkish electronica\ncinematic Turkish folk\ncinematic Turkish fusion\ncinematic Turkish orchestral\ncinematic Turkish pop\ncinematic Turkish pop-rock\ncinematic Turkish protest\ncinematic UK garage\ncinematic UK hip-hop\ncinematic V-pop\ncinematic Vallenato\ncinematic Vietnamese\ncinematic Vocaloid\ncinematic Western\ncinematic Western ballad\ncinematic Western rock\ncinematic Zouk\ncinematic a cappella\ncinematic acapella\ncinematic accordion\ncinematic acoustic\ncinematic action\ncinematic adult contemporary\ncinematic afrobeat\ncinematic afrobeats\ncinematic alt-country\ncinematic alt-rock\ncinematic alternative\ncinematic alternative hip-hop\ncinematic alternative metal\ncinematic alternative pop\ncinematic alternative rock\ncinematic ambient\ncinematic ambient blues-rock\ncinematic ambient cumbia\ncinematic ambient dream pop\ncinematic ambient flamenco\ncinematic ambient future bass\ncinematic ambient hip-hop\ncinematic ambient indie rock\ncinematic ambient industrial rock\ncinematic ambient metalcore\ncinematic ambient phonk\ncinematic ambient post-hardcore\ncinematic ambient post-rock\ncinematic ambient progressive metal\ncinematic ambient progressive trance\ncinematic ambient psytrance\ncinematic ambient rock\ncinematic ambient ska-reggae\ncinematic ambient synthwave\ncinematic ambient trap\ncinematic ambient, Balkan folk, electronic\ncinematic ambient, French pop-rock, synth-pop\ncinematic ambient, Indian classical, Bollywood\ncinematic ambient, Indian classical, psychedelic rock\ncinematic ambient, Indian folk, electronic fusion\ncinematic ambient, Italo-disco\ncinematic ambient, J-pop, piano ballad, J-rock\ncinematic ambient, Latin cumbia\ncinematic ambient, Turkish pop\ncinematic ambient, big band jazz\ncinematic ambient, chiptune, hip-hop\ncinematic ambient, electronic, C-pop\ncinematic ambient, electronic, Indian fusion\ncinematic ambient, eurodance, operatic\ncinematic ambient, eurodance, synth-pop\ncinematic ambient, eurodance, trance\ncinematic ambient, folk-pop, electronic\ncinematic ambient, future bass, dubstep\ncinematic ambient, glitch-hop, hyperpop\ncinematic ambient, hard rock\ncinematic ambient, hardstyle\ncinematic ambient, hardstyle, C-pop\ncinematic ambient, hardstyle, trancecore\ncinematic ambient, industrial metal\ncinematic ambient, lo-fi hip hop, trap\ncinematic ambient, lo-fi hip-hop, future bass\ncinematic ambient, neo-classical\ncinematic ambient, nu-metal, hip-hop\ncinematic ambient, phonk, trap metal\ncinematic ambient, polka-pop\ncinematic ambient, progressive house\ncinematic ambient, progressive house, hardstyle\ncinematic ambient, progressive house, melodic techno\ncinematic ambient, progressive metal, Indian classical\ncinematic ambient, progressive rock\ncinematic ambient, progressive trance\ncinematic ambient, progressive trance, arena rock\ncinematic ambient, psytrance\ncinematic ambient, retro pop\ncinematic ambient, synth-pop, trap-pop\ncinematic ambient, trap, Indian classical\ncinematic anime\ncinematic anime ballad\ncinematic anime power ballad\ncinematic anthem\ncinematic arabesque\ncinematic arabic\ncinematic art pop\ncinematic art rock\ncinematic art song\ncinematic art song, Latin salsa\ncinematic art song, big band swing\ncinematic art song, folk dance\ncinematic art song, piano rock\ncinematic art song, theatrical rock\ncinematic art-pop\ncinematic art-rock\ncinematic artcore\ncinematic avant-garde\ncinematic axé\ncinematic bachata\ncinematic ballad\ncinematic ballad axé\ncinematic ballad cumbia\ncinematic ballad cumbia norteña\ncinematic ballad enka\ncinematic ballad fado\ncinematic ballad gospel-pop\ncinematic ballad hip-hop\ncinematic ballad indie rock\ncinematic ballad jazz-funk\ncinematic ballad lo-fi hip-hop\ncinematic ballad lounge jazz\ncinematic ballad reggaeton\ncinematic ballad rockabilly\ncinematic ballad salsa\ncinematic ballad samba\ncinematic ballad samba-jazz\ncinematic ballad symphonic metal\ncinematic ballad trot\ncinematic ballad, 80s East Asian pop, synthwave\ncinematic ballad, 80s power ballad\ncinematic ballad, 90s hip-hop, R&B\ncinematic ballad, Arabic folk, orchestral\ncinematic ballad, Bollywood dance-pop\ncinematic ballad, C-pop, K-pop\ncinematic ballad, C-pop, ambient\ncinematic ballad, C-pop, emotional\ncinematic ballad, C-pop, orchestral\ncinematic ballad, Chinese art-pop, ambient\ncinematic ballad, Chinese art-pop, orchestral\ncinematic ballad, Chinese folk, melancholic\ncinematic ballad, Chinese opera, orchestral\ncinematic ballad, Chinese orchestral pop\ncinematic ballad, Chinese orchestral, epic\ncinematic ballad, Chinese traditional, ambient pop\ncinematic ballad, Chinese traditional, epic\ncinematic ballad, Chinese traditional, orchestral\ncinematic ballad, Chinese-style\ncinematic ballad, Chinese-style, melancholic\ncinematic ballad, Chinese-style, orchestral\ncinematic ballad, Chinese-style, pop-rock\ncinematic ballad, Christian power ballad, epic rock\ncinematic ballad, Christian rock, orchestral\ncinematic ballad, Dangdut Koplo\ncinematic ballad, Dangdut Koplo, funkot\ncinematic ballad, Eastern European folk, synth orchestral\ncinematic ballad, Enka, orchestral\ncinematic ballad, Eurodance\ncinematic ballad, Europop, dance-pop\ncinematic ballad, Filipino pop\ncinematic ballad, Greek folk\ncinematic ballad, Indian classical, ambient\ncinematic ballad, Indian film music, pop\ncinematic ballad, Indian folk, Bollywood\ncinematic ballad, Indonesian pop\ncinematic ballad, Italo-disco, dance-pop\ncinematic ballad, J-pop, C-pop\ncinematic ballad, J-pop, anime rock\ncinematic ballad, J-rock\ncinematic ballad, J-rock, C-pop\ncinematic ballad, J-rock, anime\ncinematic ballad, J-rock, power ballad\ncinematic ballad, Kayōkyoku\ncinematic ballad, Kayōkyoku, Enka\ncinematic ballad, Kayōkyoku, orchestral\ncinematic ballad, Korean trot\ncinematic ballad, Korean trot, orchestral\ncinematic ballad, Korean trot, orchestral pop\ncinematic ballad, Latin American folk\ncinematic ballad, Latin big band\ncinematic ballad, Latin bolero\ncinematic ballad, Latin bolero, lo-fi\ncinematic ballad, Latin cumbia\ncinematic ballad, Latin dance, salsa\ncinematic ballad, Latin groove\ncinematic ballad, Latin jazz\ncinematic ballad, Latin jazz, salsa\ncinematic ballad, Latin mambo\ncinematic ballad, Latin pop\ncinematic ballad, Latin pop, classical fusion\ncinematic ballad, Latin pop, orchestral\ncinematic ballad, Latin pop-rock\ncinematic ballad, Latin salsa\ncinematic ballad, Latin salsa, cabaret\ncinematic ballad, Latin, bolero\ncinematic ballad, R&B, orchestral pop\ncinematic ballad, Romanian folk, dance\ncinematic ballad, Romanian folk-pop\ncinematic ballad, Russian estrada, synthwave\ncinematic ballad, South Asian film music\ncinematic ballad, Turkish arabesque, orchestral\ncinematic ballad, Turkish pop-dance\ncinematic ballad, Vietnamese bolero\ncinematic ballad, Vietnamese bolero, ambient\ncinematic ballad, Vietnamese bolero, orchestral\ncinematic ballad, Vietnamese bolero, synth-pop\ncinematic ballad, Vietnamese folk, orchestral\ncinematic ballad, Vietnamese folk-pop, orchestral\ncinematic ballad, ambient, Chinese traditional\ncinematic ballad, big band jazz\ncinematic ballad, big band jazz, cabaret\ncinematic ballad, big band jazz, operatic pop\ncinematic ballad, big band mambo\ncinematic ballad, big band swing\ncinematic ballad, big band swing, orchestral\ncinematic ballad, big band, orchestral\ncinematic ballad, big band, vocal pop\ncinematic ballad, cabaret jazz, big band\ncinematic ballad, cabaret rock\ncinematic ballad, cabaret swing\ncinematic ballad, cabaret, theatrical pop\ncinematic ballad, chiptune, Vietnamese bolero\ncinematic ballad, comedy rock\ncinematic ballad, cumbia\ncinematic ballad, cumbia, oud\ncinematic ballad, dance-pop, traditional Middle Eastern\ncinematic ballad, dangdut koplo\ncinematic ballad, dangdut koplo, pop-rock\ncinematic ballad, drum and bass, electronic\ncinematic ballad, enka, guzheng\ncinematic ballad, enka, kayōkyoku\ncinematic ballad, enka, orchestral\ncinematic ballad, eurodance\ncinematic ballad, eurodance, dance-pop\ncinematic ballad, eurodance, trance\ncinematic ballad, forró\ncinematic ballad, forró, baião\ncinematic ballad, free jazz, orchestral\ncinematic ballad, funk, disco\ncinematic ballad, gospel-pop\ncinematic ballad, gospel-pop, operatic\ncinematic ballad, gypsy jazz, klezmer\ncinematic ballad, gǔfēng, orchestral pop\ncinematic ballad, happy hardcore\ncinematic ballad, happy hardcore, hardstyle\ncinematic ballad, hardstyle\ncinematic ballad, hardstyle trance\ncinematic ballad, hardstyle, trance\ncinematic ballad, jazz swing, ambient\ncinematic ballad, latin folk, orchestral\ncinematic ballad, mambo, salsa\ncinematic ballad, mariachi, classical pop\ncinematic ballad, new jack swing\ncinematic ballad, nu-disco\ncinematic ballad, operatic pop, Indonesian pop\ncinematic ballad, orchestral rock, Vietnamese bolero\ncinematic ballad, orchestral rock, dubstep\ncinematic ballad, orchestral, Chinese-style\ncinematic ballad, pop-rock\ncinematic ballad, pop-rock, Chinese-style\ncinematic ballad, pop-rock, hard rock\ncinematic ballad, power ballad, C-pop\ncinematic ballad, power ballad, K-pop\ncinematic ballad, power ballad, Turkish folk\ncinematic ballad, power rock, C-pop\ncinematic ballad, psychedelic funk-rock\ncinematic ballad, psychedelic rock\ncinematic ballad, reggaeton\ncinematic ballad, rockabilly, theatrical pop\ncinematic ballad, romantic pop, Indian pop\ncinematic ballad, samba-pop\ncinematic ballad, samba-reggae\ncinematic ballad, samba-reggae, carnival\ncinematic ballad, samba-reggae, orchestral\ncinematic ballad, swing-pop, orchestral\ncinematic ballad, synth-pop\ncinematic ballad, synth-pop, Vietnamese traditional\ncinematic ballad, theatrical waltz\ncinematic ballad, traditional Chinese, melancholic\ncinematic ballad, traditional Chinese, orchestral\ncinematic ballad, trap R&B\ncinematic ballad, trip-hop, electronic\ncinematic ballad, trip-hop, emotional pop\ncinematic ballad, trot, orchestral\ncinematic ballad, trot, orchestral pop\ncinematic ballad, vintage, bolero\ncinematic ballad, world-pop\ncinematic ballroom\ncinematic ballroom bolero\ncinematic ballroom waltz\ncinematic banda\ncinematic baritone\ncinematic baroque\ncinematic baroque pop\ncinematic bass\ncinematic bass house\ncinematic belly dance\ncinematic bhajan\ncinematic bhangra\ncinematic big band\ncinematic big band enka\ncinematic big band jazz\ncinematic big band pop\ncinematic big band, French chanson\ncinematic big band, Greek Laïko\ncinematic big band, canzone Italiana\ncinematic big beat\ncinematic big room\ncinematic bluegrass\ncinematic blues\ncinematic blues rock\ncinematic blues-rock\ncinematic bolero\ncinematic bolero cumbia\ncinematic bolero jazz\ncinematic bolero merengue\ncinematic bolero salsa\ncinematic bolero, Latin folk\ncinematic bolero, mambo, salsa\ncinematic bolero, salsa, orchestral pop\ncinematic boogie-woogie\ncinematic boom-bap\ncinematic boombap\ncinematic bossa nova\ncinematic bossa nova samba\ncinematic bossa nova samba-pop\ncinematic brass\ncinematic brass, Greek pop-rock\ncinematic brass, Kayōkyoku, blues-rock\ncinematic brass, Latin folk\ncinematic brass, vintage pop, Indian fusion\ncinematic breakbeat\ncinematic breakcore\ncinematic brostep\ncinematic cabaret\ncinematic cartoon\ncinematic cello\ncinematic chamber\ncinematic chamber music\ncinematic chamber music art-rock\ncinematic chamber music, Latin jazz, cabaret\ncinematic chamber music, world fusion rock\ncinematic chamber pop\ncinematic chanson\ncinematic chanson, funk-rock, pop-rock\ncinematic chanson, orchestral rock\ncinematic children's\ncinematic children's music\ncinematic chillhop\ncinematic chillstep\ncinematic chillwave\ncinematic chiptune\ncinematic chiptune cumbia\ncinematic chiptune rock\ncinematic choir\ncinematic choral\ncinematic choral hip-hop\ncinematic choral pop\ncinematic choral, Afropop\ncinematic choral, gospel pop\ncinematic city pop\ncinematic classical\ncinematic classical crossover\ncinematic classical, psychedelic rock, Indonesian pop\ncinematic comedy\ncinematic complextro\ncinematic concert band\ncinematic copla\ncinematic corrido\ncinematic country\ncinematic country gospel\ncinematic country rock\ncinematic country-folk\ncinematic country-gospel\ncinematic country-pop\ncinematic country-rock\ncinematic country-soul\ncinematic crossover\ncinematic cumbia\ncinematic cumbia pop\ncinematic cumbia villera\ncinematic dance\ncinematic dance pop\ncinematic dance-pop\ncinematic dancehall\ncinematic dancehall-pop\ncinematic dangdut koplo\ncinematic dark\ncinematic dark ambient\ncinematic dark cabaret\ncinematic dark electronic\ncinematic dark fantasy\ncinematic dark jazz\ncinematic dark pop\ncinematic dark synth\ncinematic dark wave\ncinematic darksynth\ncinematic darkwave\ncinematic death metal\ncinematic deep house\ncinematic dembow\ncinematic desert rock\ncinematic devotional\ncinematic devotional pop\ncinematic disco\ncinematic disco funk\ncinematic disco rock\ncinematic disco soul\ncinematic disco-funk\ncinematic disco-pop\ncinematic disco-rock\ncinematic disco-soul\ncinematic disco-tango\ncinematic dizi\ncinematic dnb\ncinematic doo-wop\ncinematic downtempo\ncinematic dream pop\ncinematic dream-pop\ncinematic drill\ncinematic drone\ncinematic drone industrial\ncinematic drone, Middle Eastern fusion\ncinematic drone, synthwave, chiptune\ncinematic drone, tribal house, Middle Eastern\ncinematic drum\ncinematic drum & bass\ncinematic drum and bass\ncinematic drumming\ncinematic dub\ncinematic dubstep\ncinematic dubstep rock\ncinematic duduk\ncinematic easy-listening\ncinematic electro\ncinematic electro house\ncinematic electro-funk\ncinematic electro-house\ncinematic electro-pop\ncinematic electro-rock\ncinematic electro-swing\ncinematic electronic\ncinematic electronic C-pop\ncinematic electronic J-pop\ncinematic electronic dark pop\ncinematic electronic fusion\ncinematic electronic future bass\ncinematic electronic hip-hop\ncinematic electronic pop\ncinematic electronic pop-rock\ncinematic electronic rock\ncinematic electronic trap\ncinematic electronic trap J-pop\ncinematic electronic worship\ncinematic electronic, C-pop, ancient style\ncinematic electronic, C-pop, dubstep\ncinematic electronic, C-pop, synthwave\ncinematic electronic, C-pop, trap\ncinematic electronic, C-pop, video game music\ncinematic electronic, Chinese EDM, hardstyle\ncinematic electronic, Chinese fusion\ncinematic electronic, Chinese fusion, bass music\ncinematic electronic, Chinese fusion, drum and bass\ncinematic electronic, Chinese fusion, dubstep\ncinematic electronic, Chinese fusion, trap\ncinematic electronic, Indian fusion, trap\ncinematic electronic, J-rock, trance\ncinematic electronic, dubstep, C-pop\ncinematic electronic, dubstep, Chinese fusion\ncinematic electronic, trance, C-pop\ncinematic electronic, trap, C-pop\ncinematic electronic, trap, Indian film music\ncinematic electronic, trap, J-rock\ncinematic electronic, trap, Middle Eastern\ncinematic electronic, trap, dubstep\ncinematic electronic, trap, future bass\ncinematic electronic, trap, hardstyle\ncinematic electronic, trap, phonk\ncinematic electronic, trap, synth-pop\ncinematic electronic-pop\ncinematic electronica\ncinematic electropop\ncinematic emo\ncinematic emo-pop\ncinematic emo-rap\ncinematic enka\ncinematic epic\ncinematic ethnic electronica\ncinematic ethnic fusion\ncinematic ethnic pop\ncinematic ethno-pop\ncinematic euro-pop\ncinematic eurodance\ncinematic exotica\ncinematic experimental\ncinematic fado\ncinematic fairytale\ncinematic fanfare\ncinematic fantasy\ncinematic fantasy rock\ncinematic filmi\ncinematic filmi-pop\ncinematic fingerstyle\ncinematic flamenco\ncinematic flamenco pop\ncinematic flamenco rock\ncinematic flamenco trap\ncinematic flute\ncinematic folk\ncinematic folk ballad\ncinematic folk fusion\ncinematic folk gospel\ncinematic folk hip-hop\ncinematic folk indie rock\ncinematic folk jazz\ncinematic folk metal\ncinematic folk pop\ncinematic folk protest\ncinematic folk punk\ncinematic folk rock\ncinematic folk soul\ncinematic folk synth-pop\ncinematic folk trap\ncinematic folk, boom-bap hip-hop\ncinematic folk, dance-pop, Tamil\ncinematic folk, eurodance\ncinematic folk, polka-punk, ska-punk\ncinematic folk, progressive metal\ncinematic folk, world music, funk-pop\ncinematic folk-ballad\ncinematic folk-fusion\ncinematic folk-gospel\ncinematic folk-metal\ncinematic folk-orchestral\ncinematic folk-pop\ncinematic folk-rock\ncinematic folktronica\ncinematic forró\ncinematic forró chiptune\ncinematic funk\ncinematic funk fusion\ncinematic funk gospel\ncinematic funk rap\ncinematic funk rock\ncinematic funk soul\ncinematic funk-hop\ncinematic funk-pop\ncinematic funk-rock\ncinematic funk-soul\ncinematic fusion\ncinematic future bass\ncinematic future garage\ncinematic future trap\ncinematic game music\ncinematic gamelan\ncinematic gangsta rap\ncinematic gangster rap\ncinematic ghazal\ncinematic glitch\ncinematic glitch pop\ncinematic glitch-hop\ncinematic glitch-pop\ncinematic gospel\ncinematic gospel R&B\ncinematic gospel afrobeats\ncinematic gospel dancehall\ncinematic gospel hip-hop\ncinematic gospel pop\ncinematic gospel pop-rock\ncinematic gospel reggae\ncinematic gospel rock\ncinematic gospel soul\ncinematic gospel world music\ncinematic gospel-funk\ncinematic gospel-pop\ncinematic gospel-rock\ncinematic gothic\ncinematic gothic orchestral\ncinematic gothic rock\ncinematic grunge\ncinematic gufeng\ncinematic guitar\ncinematic guzheng\ncinematic gypsy jazz\ncinematic gǔfēng\ncinematic hard dance\ncinematic hard rock\ncinematic hardcore\ncinematic hardstyle\ncinematic harp\ncinematic hip hop\ncinematic hip hop, glitch-hop, hyperpop\ncinematic hip-hop\ncinematic hip-hop cumbia\ncinematic hip-hop nu-metal\ncinematic hip-hop pop-R&B\ncinematic hip-hop punk\ncinematic hip-hop rock\ncinematic hip-hop soul\ncinematic hip-hop tango\ncinematic hip-hop trap\ncinematic hip-hop, Arabic soul, R&B\ncinematic hip-hop, Bollywood, epic anthem\ncinematic hip-hop, G-funk\ncinematic hip-hop, boom-bap, wuxia\ncinematic hip-hop, lo-fi hip-hop\ncinematic hip-hop, nu-metal\ncinematic hip-hop, pop-rock, Chinese pop\ncinematic hip-hop, rap-rock, trap\ncinematic hip-hop, soulful R&B, synth-pop\ncinematic hip-hop, trap, Chinese fusion\ncinematic hip-hop, trap, R&B\ncinematic hip-hop, trap, industrial rock\ncinematic holiday\ncinematic horror\ncinematic horror rock\ncinematic horror, mambo, operatic\ncinematic horror-funk\ncinematic house\ncinematic hybrid\ncinematic hybrid orchestral\ncinematic hybrid trailer\ncinematic hybrid trap\ncinematic hybrid, tribal house, Javanese ambient\ncinematic hybrid-trap\ncinematic hymn\ncinematic hyperpop\ncinematic indie\ncinematic indie dance\ncinematic indie folk\ncinematic indie pop\ncinematic indie pop-rock\ncinematic indie rock\ncinematic indie-electronic\ncinematic indie-folk\ncinematic indie-pop\ncinematic industrial\ncinematic industrial hip-hop\ncinematic industrial metal\ncinematic industrial rock\ncinematic industrial techno\ncinematic industrial trap\ncinematic instrumental\ncinematic instrumental, Latin jazz\ncinematic jazz\ncinematic jazz boom-bap\ncinematic jazz funk\ncinematic jazz fusion\ncinematic jazz hip-hop\ncinematic jazz lounge\ncinematic jazz noir\ncinematic jazz pop\ncinematic jazz progressive rock\ncinematic jazz punk\ncinematic jazz rock\ncinematic jazz tango\ncinematic jazz, funk soul\ncinematic jazz, smooth jazz, synth-pop\ncinematic jazz, soulful pop-rock\ncinematic jazz-funk\ncinematic jazz-gospel\ncinematic jazz-hop\ncinematic jazz-noir\ncinematic jazz-pop\ncinematic jazz-rap\ncinematic jazz-rock\ncinematic jazz-soul\ncinematic jungle\ncinematic k-pop\ncinematic kayōkyoku\ncinematic klezmer\ncinematic klezmer-pop\ncinematic korean\ncinematic korean ballad\ncinematic korean folk\ncinematic korean opera\ncinematic korean trot\ncinematic kuthu\ncinematic lament\ncinematic laïko\ncinematic library music\ncinematic lo-fi\ncinematic lo-fi hip hop\ncinematic lo-fi hip-hop\ncinematic lo-fi indie\ncinematic lo-fi indie rock\ncinematic lo-fi trap\ncinematic lo-fi trip-hop\ncinematic lounge\ncinematic lounge jazz\ncinematic lounge jazz, theatrical rock\ncinematic lounge pop\ncinematic lounge, Latin jazz\ncinematic lounge-jazz\ncinematic lounge-pop\ncinematic lullaby\ncinematic lullaby, Latin big band, orchestral\ncinematic lullaby, Latin jazz, orchestral\ncinematic lullaby, acoustic lullaby\ncinematic lullaby, chiptune\ncinematic lullaby, indie-pop\ncinematic mambo\ncinematic mandolin\ncinematic manele\ncinematic mariachi\ncinematic martial\ncinematic melancholy\ncinematic merengue\ncinematic metal\ncinematic metal, lo-fi hip hop\ncinematic metalcore\ncinematic military\ncinematic minimalism\ncinematic moombahton\ncinematic musette\ncinematic music box\ncinematic musical\ncinematic musical theater\ncinematic nasheed\ncinematic neo-classical\ncinematic neo-folk\ncinematic neo-soul\ncinematic new age\ncinematic new age, C-pop\ncinematic new jack swing\ncinematic new wave\ncinematic new-age\ncinematic new-age pop\ncinematic new-age pop-rock\ncinematic new-age rock\ncinematic new-age, Latin pop\ncinematic new-age, power-pop, progressive metal\ncinematic ney\ncinematic noir\ncinematic noir funk\ncinematic noir jazz\ncinematic noir rock\ncinematic noir-jazz\ncinematic noise-rock\ncinematic norteño-cumbia\ncinematic nu-disco\ncinematic nu-metal\ncinematic nursery rhyme\ncinematic opera\ncinematic opera rock\ncinematic orchestral\ncinematic orchestral Afro-Cuban\ncinematic orchestral Afrobeats\ncinematic orchestral Arabic\ncinematic orchestral Arabic classical\ncinematic orchestral Arabic folk\ncinematic orchestral Arabic folk-pop\ncinematic orchestral Arabic pop\ncinematic orchestral Arabic pop-rock\ncinematic orchestral Arabic trap\ncinematic orchestral Balkan ballad\ncinematic orchestral Balkan folk-pop\ncinematic orchestral Bhangra\ncinematic orchestral Bollywood\ncinematic orchestral C-pop\ncinematic orchestral C-pop rock\ncinematic orchestral Christian cumbia\ncinematic orchestral Christian pop-rock\ncinematic orchestral Christian rock\ncinematic orchestral French chanson\ncinematic orchestral French pop\ncinematic orchestral Indian film music\ncinematic orchestral Indian folk-pop\ncinematic orchestral Indian pop\ncinematic orchestral Italian pop\ncinematic orchestral Italo-disco\ncinematic orchestral J-RPG\ncinematic orchestral J-Rock\ncinematic orchestral J-pop\ncinematic orchestral J-pop hip-hop\ncinematic orchestral J-pop rock\ncinematic orchestral J-rock\ncinematic orchestral K-ballad\ncinematic orchestral K-pop\ncinematic orchestral Latin\ncinematic orchestral Latin ballad\ncinematic orchestral Latin bolero\ncinematic orchestral Latin jazz\ncinematic orchestral Latin jazz fusion\ncinematic orchestral Latin pop\ncinematic orchestral Latin pop-rock\ncinematic orchestral MPB\ncinematic orchestral MPB soul\ncinematic orchestral Mandopop\ncinematic orchestral Persian pop\ncinematic orchestral Punjabi folk\ncinematic orchestral Punjabi pop\ncinematic orchestral Punjabi pop-rock\ncinematic orchestral R&B\ncinematic orchestral Spanish pop\ncinematic orchestral Tollywood dance-pop\ncinematic orchestral V-Pop\ncinematic orchestral V-pop\ncinematic orchestral adult contemporary\ncinematic orchestral ambient\ncinematic orchestral anime\ncinematic orchestral art rock\ncinematic orchestral art-pop\ncinematic orchestral ballad\ncinematic orchestral bhajan\ncinematic orchestral bhangra\ncinematic orchestral big band\ncinematic orchestral bolero\ncinematic orchestral bolero jazz\ncinematic orchestral bolero salsa\ncinematic orchestral bossa nova\ncinematic orchestral cabaret\ncinematic orchestral chanson\ncinematic orchestral children's music\ncinematic orchestral chiptune\ncinematic orchestral city pop\ncinematic orchestral cool jazz\ncinematic orchestral disco-pop\ncinematic orchestral dream pop\ncinematic orchestral electronic\ncinematic orchestral enka\ncinematic orchestral ethnic pop\ncinematic orchestral fado\ncinematic orchestral flamenco\ncinematic orchestral folk-pop\ncinematic orchestral funk\ncinematic orchestral funk-rock progressive metal\ncinematic orchestral future bass\ncinematic orchestral gospel rock\ncinematic orchestral gypsy jazz\ncinematic orchestral gǔfēng\ncinematic orchestral hip-hop\ncinematic orchestral hybrid\ncinematic orchestral indie rock\ncinematic orchestral industrial metal\ncinematic orchestral jazz\ncinematic orchestral jazz-funk\ncinematic orchestral jazz-fusion\ncinematic orchestral joropo\ncinematic orchestral k-pop\ncinematic orchestral kayōkyoku\ncinematic orchestral klezmer\ncinematic orchestral korean ballad\ncinematic orchestral lo-fi hip hop\ncinematic orchestral lo-fi hip-hop\ncinematic orchestral lounge\ncinematic orchestral lounge jazz\ncinematic orchestral lounge-pop\ncinematic orchestral mambo\ncinematic orchestral merengue\ncinematic orchestral metalcore\ncinematic orchestral neo-soul\ncinematic orchestral new age\ncinematic orchestral new jack swing\ncinematic orchestral noir-jazz\ncinematic orchestral nu-disco\ncinematic orchestral pop\ncinematic orchestral pop-rock\ncinematic orchestral post-rock\ncinematic orchestral power ballad\ncinematic orchestral progressive house\ncinematic orchestral progressive rock\ncinematic orchestral progressive trance\ncinematic orchestral psychedelic rock\ncinematic orchestral reggae-pop\ncinematic orchestral rock\ncinematic orchestral romanian pop\ncinematic orchestral samba\ncinematic orchestral samba-pop\ncinematic orchestral samba-reggae\ncinematic orchestral schlager\ncinematic orchestral sertanejo\ncinematic orchestral show tune\ncinematic orchestral smooth jazz\ncinematic orchestral smooth jazz funk\ncinematic orchestral soft rock\ncinematic orchestral surf-rock\ncinematic orchestral swing\ncinematic orchestral tango\ncinematic orchestral trap\ncinematic orchestral trip-hop\ncinematic orchestral world fusion\ncinematic orchestral world music\ncinematic orchestral world-pop\ncinematic orchestral worldbeat\ncinematic orchestral worship\ncinematic orchestral zouk\ncinematic orchestral, 80s Bollywood pop-rock\ncinematic orchestral, 80s Christian power ballad\ncinematic orchestral, 80s German pop-rock\ncinematic orchestral, 80s J-pop\ncinematic orchestral, 80s J-rock\ncinematic orchestral, 80s Latin pop\ncinematic orchestral, 80s Mandopop\ncinematic orchestral, 80s Mandopop, power ballad\ncinematic orchestral, 80s Mandopop, soulful ballad\ncinematic orchestral, 80s adult contemporary\ncinematic orchestral, 80s pop, Southeast Asian pop\ncinematic orchestral, 80s power ballad\ncinematic orchestral, 90s Christian pop-rock\ncinematic orchestral, 90s R&B\ncinematic orchestral, 90s R&B, Christmas\ncinematic orchestral, 90s R&B, dance-pop\ncinematic orchestral, 90s R&B, gospel\ncinematic orchestral, 90s R&B, gospel soul\ncinematic orchestral, 90s R&B, new jack swing\ncinematic orchestral, 90s R&B, soul\ncinematic orchestral, Anatolian rock\ncinematic orchestral, Anatolian rock, ambient\ncinematic orchestral, Andean folk, operatic\ncinematic orchestral, Arabic Mawwal, Middle Eastern fusion\ncinematic orchestral, Arabic Mawwal, Raï\ncinematic orchestral, Arabic ballad\ncinematic orchestral, Arabic ballad, downtempo hip-hop\ncinematic orchestral, Arabic classical\ncinematic orchestral, Arabic classical, electronic\ncinematic orchestral, Arabic classical, folk dance\ncinematic orchestral, Arabic classical, fusion\ncinematic orchestral, Arabic classical, modern dance\ncinematic orchestral, Arabic classical, world fusion\ncinematic orchestral, Arabic dance-pop\ncinematic orchestral, Arabic dance-pop, hardstyle\ncinematic orchestral, Arabic devotional\ncinematic orchestral, Arabic devotional, electronic\ncinematic orchestral, Arabic folk\ncinematic orchestral, Arabic folk, belly dance\ncinematic orchestral, Arabic folk, choral\ncinematic orchestral, Arabic folk, epic\ncinematic orchestral, Arabic folk-pop\ncinematic orchestral, Arabic fusion\ncinematic orchestral, Arabic fusion, belly dance\ncinematic orchestral, Arabic fusion, dance-pop\ncinematic orchestral, Arabic fusion, modern pop\ncinematic orchestral, Arabic mawwal, epic fusion\ncinematic orchestral, Arabic pop\ncinematic orchestral, Arabic pop, Khaleeji\ncinematic orchestral, Arabic pop, Middle Eastern\ncinematic orchestral, Arabic pop, Middle Eastern fusion\ncinematic orchestral, Arabic pop, Shaabi\ncinematic orchestral, Arabic pop, electronic\ncinematic orchestral, Arabic pop, epic\ncinematic orchestral, Arabic pop, epic score\ncinematic orchestral, Arabic pop, folk dance\ncinematic orchestral, Arabic pop, jazz fusion\ncinematic orchestral, Arabic pop, modern pop\ncinematic orchestral, Arabic pop, modern rock\ncinematic orchestral, Arabic pop, ney\ncinematic orchestral, Arabic pop, ney flute\ncinematic orchestral, Arabic pop, operatic\ncinematic orchestral, Arabic pop, pop-rock\ncinematic orchestral, Arabic pop, world fusion\ncinematic orchestral, Arabic pop, world music\ncinematic orchestral, Arabic pop-rock\ncinematic orchestral, Arabic protest, electronic\ncinematic orchestral, Arabic traditional\ncinematic orchestral, Arabic traditional, epic\ncinematic orchestral, Arabic trap\ncinematic orchestral, Axé\ncinematic orchestral, Axé music\ncinematic orchestral, Axé, Brazilian\ncinematic orchestral, Axé, live concert\ncinematic orchestral, Balkan folk\ncinematic orchestral, Balkan folk, ambient\ncinematic orchestral, Balkan folk, festive\ncinematic orchestral, Balkan fusion\ncinematic orchestral, Balkan fusion, Klezmer\ncinematic orchestral, Balkan pop, electronic\ncinematic orchestral, Balkan pop-rock\ncinematic orchestral, Bhangra-pop\ncinematic orchestral, Bhojpuri folk-pop\ncinematic orchestral, Bollywood\ncinematic orchestral, Bollywood ballad\ncinematic orchestral, Bollywood dance\ncinematic orchestral, Bollywood dance-pop\ncinematic orchestral, Bollywood filmi, ghazal\ncinematic orchestral, Bollywood fusion, Indian classical\ncinematic orchestral, Bollywood pop\ncinematic orchestral, Bollywood pop-rock\ncinematic orchestral, Bollywood, Indian classical\ncinematic orchestral, Bollywood, classical fusion\ncinematic orchestral, Bollywood, electronic\ncinematic orchestral, Bollywood, electronic dance\ncinematic orchestral, Bollywood, operatic\ncinematic orchestral, Bollywood, orchestral\ncinematic orchestral, Bollywood, orchestral pop\ncinematic orchestral, Bollywood, pop fusion\ncinematic orchestral, Brazilian Axé\ncinematic orchestral, Brazilian Boi-Bumbá\ncinematic orchestral, Brazilian ballad\ncinematic orchestral, Brazilian ballad, power ballad\ncinematic orchestral, Brazilian bolero\ncinematic orchestral, Brazilian bolero, MPB\ncinematic orchestral, Brazilian carnival\ncinematic orchestral, Brazilian folk\ncinematic orchestral, Brazilian folk, operatic\ncinematic orchestral, Brazilian folk, rock\ncinematic orchestral, Brazilian folk, shamanic ritual\ncinematic orchestral, Brazilian funk\ncinematic orchestral, Brazilian funk, trap\ncinematic orchestral, Brazilian gospel\ncinematic orchestral, Brazilian gospel pop-rock\ncinematic orchestral, Brazilian gospel, Axé\ncinematic orchestral, Brazilian gospel, forró\ncinematic orchestral, Brazilian gospel, operatic\ncinematic orchestral, Brazilian gospel, pop-rock\ncinematic orchestral, Brazilian gospel, rock\ncinematic orchestral, Brazilian gospel, samba-reggae\ncinematic orchestral, Brazilian gospel, soul\ncinematic orchestral, Brazilian pagode\ncinematic orchestral, Brazilian pop\ncinematic orchestral, Brazilian pop, gospel\ncinematic orchestral, Brazilian pop, pop-rock\ncinematic orchestral, Brazilian pop, samba\ncinematic orchestral, Brazilian pop, samba-reggae\ncinematic orchestral, Brazilian pop-rock\ncinematic orchestral, Brazilian power ballad\ncinematic orchestral, Brazilian power ballad, rock\ncinematic orchestral, Brazilian rhythm\ncinematic orchestral, Brazilian rhythm, rock\ncinematic orchestral, Brazilian romantic ballad\ncinematic orchestral, Brazilian romantic pop, brega\ncinematic orchestral, Brazilian spiritual\ncinematic orchestral, Broadway, choral\ncinematic orchestral, C-pop, J-pop\ncinematic orchestral, Chinese art song\ncinematic orchestral, Chinese art-pop\ncinematic orchestral, Chinese ballad\ncinematic orchestral, Chinese ballad, epic\ncinematic orchestral, Chinese fantasy\ncinematic orchestral, Chinese fantasy, dramatic\ncinematic orchestral, Chinese fantasy, epic\ncinematic orchestral, Chinese fantasy, wuxia\ncinematic orchestral, Chinese folk\ncinematic orchestral, Chinese folk, epic\ncinematic orchestral, Chinese folk, epic fusion\ncinematic orchestral, Chinese folk, operatic\ncinematic orchestral, Chinese folk-pop\ncinematic orchestral, Chinese fusion\ncinematic orchestral, Chinese fusion, trap\ncinematic orchestral, Chinese influence\ncinematic orchestral, Chinese pop-rock, wuxia\ncinematic orchestral, Chinese traditional\ncinematic orchestral, Chinese traditional, dramatic\ncinematic orchestral, Chinese traditional, epic\ncinematic orchestral, Chinese traditional, epic fantasy\ncinematic orchestral, Chinese traditional, epic rock\ncinematic orchestral, Chinese traditional, rock fusion\ncinematic orchestral, Chinese traditional, wuxia\ncinematic orchestral, Christian contemporary\ncinematic orchestral, Christian contemporary, gospel\ncinematic orchestral, Christian contemporary, power ballad\ncinematic orchestral, Christian country-gospel\ncinematic orchestral, Christian pop, Bollywood\ncinematic orchestral, Christian pop, Indian fusion\ncinematic orchestral, Christian pop-rock\ncinematic orchestral, Christian pop-rock, gospel\ncinematic orchestral, Christian power ballad\ncinematic orchestral, Christian power ballad, arena rock\ncinematic orchestral, Christian power ballad, gospel\ncinematic orchestral, Christian power ballad, pop-rock\ncinematic orchestral, Christian power ballad, rock\ncinematic orchestral, Christian rock\ncinematic orchestral, Christian rock, gospel\ncinematic orchestral, Christian rock, piano ballad\ncinematic orchestral, Christian rock, power ballad\ncinematic orchestral, Christian worship, world music\ncinematic orchestral, Christmas pop\ncinematic orchestral, Christmas pop, pop-rock\ncinematic orchestral, City Pop\ncinematic orchestral, Dangdut Koplo\ncinematic orchestral, Dutch Schlager\ncinematic orchestral, Dutch chanson\ncinematic orchestral, East Asian fusion\ncinematic orchestral, Eurobeat, J-core\ncinematic orchestral, European ballad\ncinematic orchestral, European ballad, levenslied\ncinematic orchestral, European chanson\ncinematic orchestral, European chanson, operatic\ncinematic orchestral, Filipino ballad\ncinematic orchestral, Filipino ballad, power ballad\ncinematic orchestral, Filipino pop\ncinematic orchestral, Filipino pop, ballad\ncinematic orchestral, Filipino pop-rock\ncinematic orchestral, Finnish schlager\ncinematic orchestral, Finnish schlager, humppa\ncinematic orchestral, Finnish schlager, pop-rock\ncinematic orchestral, French chanson\ncinematic orchestral, French chanson, Christmas\ncinematic orchestral, French chanson, Dutch levenslied\ncinematic orchestral, French chanson, Latin jazz\ncinematic orchestral, French chanson, accordion\ncinematic orchestral, French chanson, ballad\ncinematic orchestral, French chanson, baritone\ncinematic orchestral, French chanson, big band\ncinematic orchestral, French chanson, big band jazz\ncinematic orchestral, French chanson, bossa nova\ncinematic orchestral, French chanson, folk-punk\ncinematic orchestral, French chanson, jazz\ncinematic orchestral, French chanson, jazz lounge\ncinematic orchestral, French chanson, live performance\ncinematic orchestral, French chanson, lounge jazz\ncinematic orchestral, French chanson, melancholic\ncinematic orchestral, French chanson, operatic\ncinematic orchestral, French chanson, operatic pop\ncinematic orchestral, French chanson, operatic rock\ncinematic orchestral, French chanson, orchestral pop\ncinematic orchestral, French chanson, pop-rock\ncinematic orchestral, French chanson, swing\ncinematic orchestral, French chanson, theatrical\ncinematic orchestral, French chanson, theatrical rock\ncinematic orchestral, French chanson, waltz\ncinematic orchestral, French pop\ncinematic orchestral, French pop, ballad\ncinematic orchestral, French pop-rock\ncinematic orchestral, German Schlager\ncinematic orchestral, German Schlager, Christian contemporary\ncinematic orchestral, German Schlager, Euro-pop\ncinematic orchestral, German Schlager, pop\ncinematic orchestral, German Schlager, pop-rock\ncinematic orchestral, German Schlager, power ballad\ncinematic orchestral, German battle rap\ncinematic orchestral, German boom-bap\ncinematic orchestral, German chanson, theatrical ballad\ncinematic orchestral, German gangsta rap\ncinematic orchestral, German hip-hop\ncinematic orchestral, German pop-rock\ncinematic orchestral, German pop-schlager\ncinematic orchestral, Greek Laïko\ncinematic orchestral, Greek art song, operatic\ncinematic orchestral, Greek ballad\ncinematic orchestral, Greek folk\ncinematic orchestral, Greek folk, laïko\ncinematic orchestral, Greek folk-pop\ncinematic orchestral, Greek folk-rock\ncinematic orchestral, Greek pop-rock\ncinematic orchestral, Indian bhajan\ncinematic orchestral, Indian bhajan, hip-hop\ncinematic orchestral, Indian classical\ncinematic orchestral, Indian classical fusion\ncinematic orchestral, Indian classical, Carnatic\ncinematic orchestral, Indian classical, Latin salsa\ncinematic orchestral, Indian classical, ambient\ncinematic orchestral, Indian classical, bhajan\ncinematic orchestral, Indian classical, devotional\ncinematic orchestral, Indian classical, electronic\ncinematic orchestral, Indian classical, film score\ncinematic orchestral, Indian classical, fusion\ncinematic orchestral, Indian classical, operatic\ncinematic orchestral, Indian classical, pop-rock\ncinematic orchestral, Indian dance, electronic\ncinematic orchestral, Indian devotional\ncinematic orchestral, Indian devotional, bhajan\ncinematic orchestral, Indian devotional, electronic fusion\ncinematic orchestral, Indian devotional, fusion\ncinematic orchestral, Indian devotional, modern fusion\ncinematic orchestral, Indian devotional, pop-rock\ncinematic orchestral, Indian devotional, world fusion\ncinematic orchestral, Indian film music\ncinematic orchestral, Indian film music, electronic\ncinematic orchestral, Indian film music, electronic fusion\ncinematic orchestral, Indian film music, fusion\ncinematic orchestral, Indian film music, hip-hop\ncinematic orchestral, Indian film score\ncinematic orchestral, Indian film score, funk fusion\ncinematic orchestral, Indian film-pop, fusion\ncinematic orchestral, Indian filmi\ncinematic orchestral, Indian filmi, operatic\ncinematic orchestral, Indian filmi, pop-rock\ncinematic orchestral, Indian filmi-pop\ncinematic orchestral, Indian folk\ncinematic orchestral, Indian folk fusion\ncinematic orchestral, Indian folk, epic\ncinematic orchestral, Indian folk, trap\ncinematic orchestral, Indian folk-fusion\ncinematic orchestral, Indian folk-pop\ncinematic orchestral, Indian fusion\ncinematic orchestral, Indian ghazal\ncinematic orchestral, Indian pop\ncinematic orchestral, Indian pop, devotional\ncinematic orchestral, Indonesian pop\ncinematic orchestral, Indonesian pop, Keroncong\ncinematic orchestral, Indonesian pop, ballad\ncinematic orchestral, Islamic devotional\ncinematic orchestral, Islamic devotional, Middle Eastern\ncinematic orchestral, Islamic devotional, pop\ncinematic orchestral, Islamic devotional, pop-rock\ncinematic orchestral, Israeli pop\ncinematic orchestral, Italian ballad\ncinematic orchestral, Italian ballad, French chanson\ncinematic orchestral, Italian ballad, operatic\ncinematic orchestral, Italian ballad, operatic pop\ncinematic orchestral, Italian folk\ncinematic orchestral, Italian pop\ncinematic orchestral, Italian pop, ballad\ncinematic orchestral, Italian pop, dream-pop\ncinematic orchestral, Italian pop, mambo\ncinematic orchestral, Italian pop, operatic\ncinematic orchestral, Italian pop, operatic ballad\ncinematic orchestral, Italian pop, pop-rock\ncinematic orchestral, Italian pop, power ballad\ncinematic orchestral, Italian pop, romantic ballad\ncinematic orchestral, Italian pop, soulful R&B\ncinematic orchestral, Italian pop-rock\ncinematic orchestral, Italian pop-rock, blues-rock\ncinematic orchestral, Italian power ballad\ncinematic orchestral, Italian power ballad, operatic rock\ncinematic orchestral, Italian power ballad, rock\ncinematic orchestral, Italo-disco\ncinematic orchestral, Italo-disco, operatic pop\ncinematic orchestral, Italo-disco, synth-pop\ncinematic orchestral, J-Rock, power ballad\ncinematic orchestral, J-core, happy hardcore\ncinematic orchestral, J-pop\ncinematic orchestral, J-pop rock\ncinematic orchestral, J-pop rock, power metal\ncinematic orchestral, J-pop, C-pop\ncinematic orchestral, J-pop, City Pop\ncinematic orchestral, J-pop, Eurobeat\ncinematic orchestral, J-pop, J-rock\ncinematic orchestral, J-pop, Vocaloid\ncinematic orchestral, J-pop, anime\ncinematic orchestral, J-pop, anime power ballad\ncinematic orchestral, J-pop, anime theme\ncinematic orchestral, J-pop, anthemic\ncinematic orchestral, J-pop, city pop\ncinematic orchestral, J-pop, funk\ncinematic orchestral, J-pop, future bass\ncinematic orchestral, J-pop, hardcore techno\ncinematic orchestral, J-pop, progressive rock\ncinematic orchestral, J-pop, rock\ncinematic orchestral, J-pop, video game music\ncinematic orchestral, J-pop, vocaloid\ncinematic orchestral, J-rock\ncinematic orchestral, J-rock, C-pop\ncinematic orchestral, J-rock, Vocaloid\ncinematic orchestral, J-rock, electronic\ncinematic orchestral, J-rock, electronicore\ncinematic orchestral, J-rock, metalcore\ncinematic orchestral, J-rock, piano ballad\ncinematic orchestral, J-rock, power ballad\ncinematic orchestral, J-rock, rap-rock\ncinematic orchestral, Japanese ballad\ncinematic orchestral, Japanese folk, Kayōkyoku\ncinematic orchestral, Japanese folk, operatic\ncinematic orchestral, Javanese pop\ncinematic orchestral, Javanese pop-rock\ncinematic orchestral, Javanese traditional\ncinematic orchestral, K-ballad\ncinematic orchestral, K-ballad, jazz-pop\ncinematic orchestral, K-pop\ncinematic orchestral, K-pop ballad\ncinematic orchestral, K-pop ballad, 80s synth\ncinematic orchestral, K-pop ballad, hard rock\ncinematic orchestral, K-pop ballad, rock\ncinematic orchestral, K-pop ballad, soulful ballad\ncinematic orchestral, K-pop, New Jack Swing\ncinematic orchestral, K-pop, festive\ncinematic orchestral, K-pop, funk\ncinematic orchestral, K-pop, funk-pop\ncinematic orchestral, K-pop, hip-hop\ncinematic orchestral, K-pop, power ballad\ncinematic orchestral, Kayōkyoku\ncinematic orchestral, Kayōkyoku, Enka\ncinematic orchestral, Kayōkyoku, big band\ncinematic orchestral, Kayōkyoku, blues rock\ncinematic orchestral, Kayōkyoku, emotional ballad\ncinematic orchestral, Kayōkyoku, rock\ncinematic orchestral, Kayōkyoku, soulful rock\ncinematic orchestral, Kayōkyoku, surf rock\ncinematic orchestral, Khaleeji pop, Arabic pop\ncinematic orchestral, Kollywood dance-pop, funk\ncinematic orchestral, Kollywood pop\ncinematic orchestral, Korean ballad\ncinematic orchestral, Korean ballad, jazz fusion\ncinematic orchestral, Korean ballad, rock ballad\ncinematic orchestral, Korean trot\ncinematic orchestral, Korean trot, disco\ncinematic orchestral, Korean trot, pop-rock\ncinematic orchestral, Kurdish folk-pop\ncinematic orchestral, Latin Christian pop-rock\ncinematic orchestral, Latin Christian, ballad\ncinematic orchestral, Latin Christian, salsa\ncinematic orchestral, Latin Cumbia\ncinematic orchestral, Latin ballad\ncinematic orchestral, Latin ballad, blues-rock\ncinematic orchestral, Latin ballad, bolero\ncinematic orchestral, Latin ballad, cumbia\ncinematic orchestral, Latin ballad, flamenco\ncinematic orchestral, Latin ballad, operatic\ncinematic orchestral, Latin ballad, operatic pop\ncinematic orchestral, Latin ballad, pop-rock\ncinematic orchestral, Latin ballad, power ballad\ncinematic orchestral, Latin ballad, romantic\ncinematic orchestral, Latin ballad, salsa\ncinematic orchestral, Latin ballad, tango\ncinematic orchestral, Latin bolero\ncinematic orchestral, Latin bolero, big band\ncinematic orchestral, Latin bolero, jazz\ncinematic orchestral, Latin bolero, mambo\ncinematic orchestral, Latin bolero, operatic\ncinematic orchestral, Latin bolero, ranchera\ncinematic orchestral, Latin bolero, tango\ncinematic orchestral, Latin carnival, samba\ncinematic orchestral, Latin cumbia\ncinematic orchestral, Latin cumbia, classical\ncinematic orchestral, Latin dance-pop\ncinematic orchestral, Latin disco, doom metal\ncinematic orchestral, Latin folk\ncinematic orchestral, Latin folk, choral\ncinematic orchestral, Latin folk, patriotic\ncinematic orchestral, Latin funk\ncinematic orchestral, Latin groove\ncinematic orchestral, Latin groove, Kayōkyoku\ncinematic orchestral, Latin jazz\ncinematic orchestral, Latin jazz fusion\ncinematic orchestral, Latin jazz, Balkan fusion\ncinematic orchestral, Latin jazz, Bossa Nova\ncinematic orchestral, Latin jazz, art song\ncinematic orchestral, Latin jazz-rock\ncinematic orchestral, Latin mambo\ncinematic orchestral, Latin percussion\ncinematic orchestral, Latin pop\ncinematic orchestral, Latin pop, C-pop\ncinematic orchestral, Latin pop, Christian contemporary\ncinematic orchestral, Latin pop, ballad\ncinematic orchestral, Latin pop, big band\ncinematic orchestral, Latin pop, classic rock\ncinematic orchestral, Latin pop, festive pop\ncinematic orchestral, Latin pop, flamenco\ncinematic orchestral, Latin pop, gospel\ncinematic orchestral, Latin pop, inspirational\ncinematic orchestral, Latin pop, inspirational ballad\ncinematic orchestral, Latin pop, operatic\ncinematic orchestral, Latin pop, pop-rock\ncinematic orchestral, Latin pop, power ballad\ncinematic orchestral, Latin pop, rock-opera\ncinematic orchestral, Latin pop, romantic ballad\ncinematic orchestral, Latin pop-rock\ncinematic orchestral, Latin pop-rock, anthemic rock\ncinematic orchestral, Latin pop-rock, ballad\ncinematic orchestral, Latin pop-rock, gospel\ncinematic orchestral, Latin pop-rock, power ballad\ncinematic orchestral, Latin power ballad\ncinematic orchestral, Latin power ballad, 80s pop-rock\ncinematic orchestral, Latin power ballad, operatic\ncinematic orchestral, Latin power ballad, rock\ncinematic orchestral, Latin rock\ncinematic orchestral, Latin salsa\ncinematic orchestral, Latin worship, cumbia\ncinematic orchestral, Latin, Arabic pop\ncinematic orchestral, Latin, gospel\ncinematic orchestral, Latin, operatic\ncinematic orchestral, Latin, theatrical\ncinematic orchestral, Luk Thung\ncinematic orchestral, Luk Thung, Mor Lam\ncinematic orchestral, MPB\ncinematic orchestral, MPB, Brazilian ballad\ncinematic orchestral, MPB, gospel\ncinematic orchestral, MPB, gospel pop\ncinematic orchestral, MPB, samba\ncinematic orchestral, MPB, soul\ncinematic orchestral, Malay pop\ncinematic orchestral, Malayalam rap, rock\ncinematic orchestral, Mandopop\ncinematic orchestral, Mandopop, classic rock\ncinematic orchestral, Mandopop, pop-rock\ncinematic orchestral, Mandopop, power ballad\ncinematic orchestral, Mandopop, rock ballad\ncinematic orchestral, Mandopop, vintage lounge\ncinematic orchestral, Middle Eastern classical, pop ballad\ncinematic orchestral, Middle Eastern dance\ncinematic orchestral, Middle Eastern dance, oud\ncinematic orchestral, Middle Eastern dance-pop\ncinematic orchestral, Middle Eastern folk\ncinematic orchestral, Middle Eastern folk, ambient\ncinematic orchestral, Middle Eastern folk, epic\ncinematic orchestral, Middle Eastern folk, epic choir\ncinematic orchestral, Middle Eastern folk, modern pop\ncinematic orchestral, Middle Eastern folk, rock\ncinematic orchestral, Middle Eastern folk-pop\ncinematic orchestral, Middle Eastern fusion\ncinematic orchestral, Middle Eastern fusion, electronic dance\ncinematic orchestral, Middle Eastern pop\ncinematic orchestral, Middle Eastern pop-rock\ncinematic orchestral, Middle Eastern, Anatolian folk\ncinematic orchestral, Middle Eastern, Arabic\ncinematic orchestral, Middle Eastern, Arabic fusion\ncinematic orchestral, Middle Eastern, Arabic pop\ncinematic orchestral, Middle Eastern, Balkan\ncinematic orchestral, Middle Eastern, Turkish\ncinematic orchestral, Middle Eastern, choral\ncinematic orchestral, Middle Eastern, epic\ncinematic orchestral, Middle Eastern, film score\ncinematic orchestral, Middle Eastern, ney\ncinematic orchestral, Middle Eastern, traditional\ncinematic orchestral, Middle Eastern, world fusion\ncinematic orchestral, Nepali film music\ncinematic orchestral, Nepali folk-pop\ncinematic orchestral, Nepali pop\ncinematic orchestral, Nepali pop, synth pop\ncinematic orchestral, Norteño\ncinematic orchestral, OPM\ncinematic orchestral, Persian ballad\ncinematic orchestral, Persian classical, crossover\ncinematic orchestral, Persian folk\ncinematic orchestral, Persian folk, electronic dance\ncinematic orchestral, Persian folk, world music\ncinematic orchestral, Persian pop\ncinematic orchestral, Persian pop, dance\ncinematic orchestral, Persian pop, pop-rock\ncinematic orchestral, Persian pop, power ballad\ncinematic orchestral, Portuguese pop, ballad\ncinematic orchestral, Punjabi folk\ncinematic orchestral, Punjabi folk-pop\ncinematic orchestral, Punjabi pop, electronic\ncinematic orchestral, Punjabi pop, trap\ncinematic orchestral, R&B pop\ncinematic orchestral, R&B, J-pop\ncinematic orchestral, R&B, MPB\ncinematic orchestral, Raï\ncinematic orchestral, Raï, Arabic pop\ncinematic orchestral, Romanian folk-pop\ncinematic orchestral, Romanian pop, electronic\ncinematic orchestral, Russian bard\ncinematic orchestral, Russian chanson\ncinematic orchestral, Russian estrada\ncinematic orchestral, Russian estrada, pop\ncinematic orchestral, Russian estrada, pop-rock\ncinematic orchestral, Russian estrada, synth pop\ncinematic orchestral, Russian folk-pop, estrada\ncinematic orchestral, Russian folk-rock, blues-rock\ncinematic orchestral, Russian pop\ncinematic orchestral, South Asian film music\ncinematic orchestral, South Asian film music, orchestral pop\ncinematic orchestral, South Asian folk\ncinematic orchestral, South Asian folk, ghazal\ncinematic orchestral, South Asian folk-pop\ncinematic orchestral, South Asian fusion, trap\ncinematic orchestral, South Asian pop\ncinematic orchestral, South Indian film music\ncinematic orchestral, South Indian film music, devotional\ncinematic orchestral, South Indian film music, electronic fusion\ncinematic orchestral, South Indian pop, hip-hop\ncinematic orchestral, Soviet estrada\ncinematic orchestral, Soviet-era estrada, baritone\ncinematic orchestral, Spanish ballad\ncinematic orchestral, Spanish ballad, Christmas\ncinematic orchestral, Spanish carnival\ncinematic orchestral, Spanish folk\ncinematic orchestral, Spanish folk, choral\ncinematic orchestral, Spanish folk, operatic\ncinematic orchestral, Spanish folk-pop\ncinematic orchestral, Spanish pop-rock\ncinematic orchestral, Spanish romantic ballad\ncinematic orchestral, Tamil folk dance\ncinematic orchestral, Tamil folk-fusion\ncinematic orchestral, Tamil pop, electronic\ncinematic orchestral, Tamil pop, electronic dance\ncinematic orchestral, Thai Luk Thung, pop-rock\ncinematic orchestral, Thai folk\ncinematic orchestral, Thai folk, pop\ncinematic orchestral, Thai folk-rock\ncinematic orchestral, Thai pop\ncinematic orchestral, Thai pop, 80s pop\ncinematic orchestral, Thai pop-rock\ncinematic orchestral, Turkish arabesque\ncinematic orchestral, Turkish arabesque, dance\ncinematic orchestral, Turkish arabesque, world fusion\ncinematic orchestral, Turkish art music\ncinematic orchestral, Turkish classical\ncinematic orchestral, Turkish classical, arabesque\ncinematic orchestral, Turkish folk\ncinematic orchestral, Turkish folk, Anatolian music\ncinematic orchestral, Turkish folk, Sufi music\ncinematic orchestral, Turkish folk, arabesque\ncinematic orchestral, Turkish folk, epic\ncinematic orchestral, Turkish folk, epic anthem\ncinematic orchestral, Turkish folk, epic choral\ncinematic orchestral, Turkish folk, operatic\ncinematic orchestral, Turkish folk, oud\ncinematic orchestral, Turkish folk, oud music\ncinematic orchestral, Turkish folk, pop\ncinematic orchestral, Turkish folk, rock fusion\ncinematic orchestral, Turkish folk, world fusion\ncinematic orchestral, Turkish folk-pop\ncinematic orchestral, Turkish folk-pop, arabesque\ncinematic orchestral, Turkish folk-rock\ncinematic orchestral, Turkish pop\ncinematic orchestral, Turkish pop, 80s synth\ncinematic orchestral, Turkish pop, Arabesque\ncinematic orchestral, Turkish pop, Eurodance\ncinematic orchestral, Turkish pop, Middle Eastern\ncinematic orchestral, Turkish pop, arabesque\ncinematic orchestral, Turkish pop, dance\ncinematic orchestral, Turkish pop, electronic\ncinematic orchestral, Turkish pop, flamenco\ncinematic orchestral, Turkish pop, ney flute\ncinematic orchestral, Turkish pop, oud\ncinematic orchestral, Turkish pop, patriotic\ncinematic orchestral, Turkish pop, pop-rock\ncinematic orchestral, Turkish pop-folk\ncinematic orchestral, Turkish pop-funk, video game score\ncinematic orchestral, Turkish pop-rock\ncinematic orchestral, V-Pop\ncinematic orchestral, V-Pop, ballad\ncinematic orchestral, V-pop, operatic\ncinematic orchestral, V-pop, patriotic\ncinematic orchestral, Vietnamese ballad\ncinematic orchestral, Vietnamese ballad, pop-rock\ncinematic orchestral, Vietnamese ballad, synth pop\ncinematic orchestral, Vietnamese bolero\ncinematic orchestral, Vietnamese bolero, pop ballad\ncinematic orchestral, Vietnamese bolero, traditional folk\ncinematic orchestral, Vietnamese folk\ncinematic orchestral, Vietnamese pop\ncinematic orchestral, Vietnamese pop, ballad\ncinematic orchestral, Vietnamese pop, fusion\ncinematic orchestral, Vietnamese pop, pop-rock\ncinematic orchestral, Vietnamese pop, power ballad\ncinematic orchestral, Vietnamese pop, retro pop\ncinematic orchestral, Vietnamese pop, rock\ncinematic orchestral, Vietnamese pop, synth ballad\ncinematic orchestral, Wuxia, Chinese fantasy\ncinematic orchestral, adult contemporary\ncinematic orchestral, adult contemporary, power ballad\ncinematic orchestral, ancient style\ncinematic orchestral, ancient style, C-pop\ncinematic orchestral, ancient style, guzheng\ncinematic orchestral, ancient style, pop\ncinematic orchestral, anime pop-rock\ncinematic orchestral, arabesque pop\ncinematic orchestral, arabesque, Turkish folk\ncinematic orchestral, arabesque, Turkish pop\ncinematic orchestral, arabesque, dance\ncinematic orchestral, arabesque, duduk\ncinematic orchestral, art rock\ncinematic orchestral, art-pop\ncinematic orchestral, art-pop, big band jazz\ncinematic orchestral, art-pop, funk\ncinematic orchestral, art-rock, progressive rock\ncinematic orchestral, bhangra-pop\ncinematic orchestral, big band\ncinematic orchestral, big band jazz\ncinematic orchestral, big band jazz, Broadway\ncinematic orchestral, big band jazz, Christmas ballad\ncinematic orchestral, big band jazz, free jazz\ncinematic orchestral, big band jazz, operatic\ncinematic orchestral, big band jazz, operatic pop\ncinematic orchestral, big band swing\ncinematic orchestral, big band swing, C-pop\ncinematic orchestral, big band swing, anime music\ncinematic orchestral, big band swing, jazz\ncinematic orchestral, big band swing, operatic\ncinematic orchestral, big band swing, soul\ncinematic orchestral, big band, Broadway\ncinematic orchestral, big band, Latin jazz\ncinematic orchestral, big band, Mandarin pop\ncinematic orchestral, big band, choral\ncinematic orchestral, big band, crooner\ncinematic orchestral, big band, holiday\ncinematic orchestral, big band, jazz\ncinematic orchestral, big band, lounge\ncinematic orchestral, big band, mambo\ncinematic orchestral, big band, show tune\ncinematic orchestral, big band, soulful\ncinematic orchestral, big band, spy thriller\ncinematic orchestral, big band, swing\ncinematic orchestral, big band, torch song\ncinematic orchestral, big band, vocal jazz\ncinematic orchestral, big-band jazz, vocal drama\ncinematic orchestral, bolero\ncinematic orchestral, bolero, Filipino pop\ncinematic orchestral, bolero, Latin ballad\ncinematic orchestral, bolero, Vietnamese\ncinematic orchestral, bolero, flamenco\ncinematic orchestral, bolero, mambo\ncinematic orchestral, bolero, operatic\ncinematic orchestral, bolero, salsa\ncinematic orchestral, bolero, samba\ncinematic orchestral, bolero, tango\ncinematic orchestral, boom-bap hip-hop\ncinematic orchestral, bossa nova\ncinematic orchestral, bossa nova, Japanese pop\ncinematic orchestral, bossa nova, MPB\ncinematic orchestral, bossa nova, big band\ncinematic orchestral, bossa nova, big band jazz\ncinematic orchestral, bossa nova, latin jazz\ncinematic orchestral, cabaret pop\ncinematic orchestral, cabaret, European chanson\ncinematic orchestral, cabaret, operatic\ncinematic orchestral, cabaret, schlager\ncinematic orchestral, cabaret, show tune\ncinematic orchestral, chanson, schlager\ncinematic orchestral, chanson, tango\ncinematic orchestral, children's Christmas, Spanish pop\ncinematic orchestral, children's educational, rock\ncinematic orchestral, children's music\ncinematic orchestral, children's music, synth pop\ncinematic orchestral, children's pop\ncinematic orchestral, chiptune\ncinematic orchestral, chiptune, J-pop\ncinematic orchestral, chiptune, breakbeat\ncinematic orchestral, chiptune, electronic dance\ncinematic orchestral, chiptune, industrial\ncinematic orchestral, chiptune, trancecore\ncinematic orchestral, city pop\ncinematic orchestral, city pop, Kayōkyoku\ncinematic orchestral, city pop, jazz-fusion\ncinematic orchestral, city pop, video game music\ncinematic orchestral, city-pop\ncinematic orchestral, classical crossover, Christian rock\ncinematic orchestral, classical crossover, rock\ncinematic orchestral, complextro, hardstyle\ncinematic orchestral, contemporary Christian\ncinematic orchestral, contemporary Christian pop\ncinematic orchestral, contemporary Christian pop, R&B ballad\ncinematic orchestral, contemporary Christian, gospel\ncinematic orchestral, contemporary Christian, pop-rock\ncinematic orchestral, contemporary Christian, power ballad\ncinematic orchestral, contemporary Christian, rock-gospel\ncinematic orchestral, copla, salsa\ncinematic orchestral, cumbia, children's music\ncinematic orchestral, dance-pop\ncinematic orchestral, dancehall-trap\ncinematic orchestral, dangdut koplo\ncinematic orchestral, dangdut koplo, pop-rock\ncinematic orchestral, dansktop\ncinematic orchestral, dark electronic\ncinematic orchestral, devotional Indian, fusion\ncinematic orchestral, devotional, Indian classical\ncinematic orchestral, devotional, South Indian film music\ncinematic orchestral, disco polo\ncinematic orchestral, disco-funk, anime theme\ncinematic orchestral, disco-funk, ballad\ncinematic orchestral, disco-pop\ncinematic orchestral, disco-pop, theatrical\ncinematic orchestral, doo-wop, rock and roll\ncinematic orchestral, dubstep\ncinematic orchestral, dubstep, drum and bass\ncinematic orchestral, early 2000s R&B, hip-hop\ncinematic orchestral, early 2000s R&B, pop\ncinematic orchestral, electronic dance, world fusion\ncinematic orchestral, electronic fusion, Indian classical\ncinematic orchestral, electronic fusion, devotional\ncinematic orchestral, electronic pop, Middle Eastern\ncinematic orchestral, electronic, hybrid\ncinematic orchestral, electronic, video game score\ncinematic orchestral, enka\ncinematic orchestral, enka, Japanese traditional\ncinematic orchestral, enka, traditional Japanese\ncinematic orchestral, estrada, Soviet-era\ncinematic orchestral, eurodance\ncinematic orchestral, eurodance, 90s dance-pop\ncinematic orchestral, eurodance, dance-pop\ncinematic orchestral, eurodance, trance\ncinematic orchestral, film noir, big band swing\ncinematic orchestral, film score, Indian filmi\ncinematic orchestral, filmi pop, Indian fusion\ncinematic orchestral, filmi, Indian pop\ncinematic orchestral, flamenco\ncinematic orchestral, flamenco, Latin pop\ncinematic orchestral, flamenco, Latin trap\ncinematic orchestral, flamenco, Spanish folk\ncinematic orchestral, flamenco, Turkish pop\ncinematic orchestral, flamenco, copla\ncinematic orchestral, flamenco, epic choir\ncinematic orchestral, folk fusion\ncinematic orchestral, folk-pop\ncinematic orchestral, folk-pop, Nepali\ncinematic orchestral, folk-pop, rock\ncinematic orchestral, folk-rock\ncinematic orchestral, folk-rock, Chinese pop\ncinematic orchestral, forró, Halloween pop\ncinematic orchestral, forró, axé\ncinematic orchestral, forró, baião\ncinematic orchestral, forró, gospel\ncinematic orchestral, funk, anime\ncinematic orchestral, funk, city pop\ncinematic orchestral, funk-rock\ncinematic orchestral, funk-rock, ambient\ncinematic orchestral, ghazal, filmi\ncinematic orchestral, gospel rock, orchestral\ncinematic orchestral, gospel rock, power ballad\ncinematic orchestral, gospel, power ballad\ncinematic orchestral, gospel-pop\ncinematic orchestral, gospel-pop, rock\ncinematic orchestral, hard trance, ambient\ncinematic orchestral, hardstyle\ncinematic orchestral, hardstyle, dubstep\ncinematic orchestral, heavy metal\ncinematic orchestral, hip-hop, nu-metal\ncinematic orchestral, humppa-rock\ncinematic orchestral, hybrid trap\ncinematic orchestral, industrial dubstep\ncinematic orchestral, jazz\ncinematic orchestral, jazz ballad\ncinematic orchestral, jazz swing, big band\ncinematic orchestral, jazz, Christmas\ncinematic orchestral, jazz-rock\ncinematic orchestral, kayōkyoku, enka\ncinematic orchestral, klezmer, baroque\ncinematic orchestral, korean power ballad\ncinematic orchestral, lo-fi hip hop\ncinematic orchestral, lounge jazz\ncinematic orchestral, lounge jazz, ballad\ncinematic orchestral, lounge jazz, operatic\ncinematic orchestral, lounge-jazz, pop-rock\ncinematic orchestral, lounge-pop, European chanson\ncinematic orchestral, luk thung\ncinematic orchestral, minimalist electronic, neo-classical\ncinematic orchestral, modern ballad, Southeast Asian folk\ncinematic orchestral, musical theater\ncinematic orchestral, neo-soul\ncinematic orchestral, neurofunk\ncinematic orchestral, new age\ncinematic orchestral, new jack swing\ncinematic orchestral, new jack swing, gospel R&B\ncinematic orchestral, new jack swing, soul\ncinematic orchestral, nu-disco, French house\ncinematic orchestral, operatic pop, Latin bolero\ncinematic orchestral, operatic rock, Thai folk\ncinematic orchestral, operatic, Italian art song\ncinematic orchestral, operatic, bolero\ncinematic orchestral, oud, taqsim\ncinematic orchestral, patriotic ballad, Vietnamese\ncinematic orchestral, patriotic pop, Vietnamese fusion\ncinematic orchestral, pop ballad\ncinematic orchestral, pop ballad, synth-pop\ncinematic orchestral, pop, Latin salsa\ncinematic orchestral, pop-dabke, Arabic pop\ncinematic orchestral, pop-folk, Mongolian long song\ncinematic orchestral, pop-rock\ncinematic orchestral, pop-rock, Indonesian\ncinematic orchestral, pop-rock, Middle Eastern pop\ncinematic orchestral, pop-rock, Neapolitan\ncinematic orchestral, pop-rock, Vietnamese traditional\ncinematic orchestral, pop-rock, jazz\ncinematic orchestral, pop-rock, power ballad\ncinematic orchestral, post-disco, boogie\ncinematic orchestral, power ballad\ncinematic orchestral, power ballad, 90s rock\ncinematic orchestral, power ballad, C-pop\ncinematic orchestral, power ballad, K-pop\ncinematic orchestral, power ballad, Vietnamese pop\ncinematic orchestral, power ballad, inspirational\ncinematic orchestral, power ballad, pop-rock\ncinematic orchestral, power ballad, rock\ncinematic orchestral, power metal, Chinese-style\ncinematic orchestral, psychedelic lounge, operatic pop\ncinematic orchestral, psytrance\ncinematic orchestral, ragtime, show tune\ncinematic orchestral, raï, electronic\ncinematic orchestral, retro Mandopop\ncinematic orchestral, retro Mandopop, 80s disco-pop\ncinematic orchestral, retro Mandopop, disco-funk\ncinematic orchestral, retro dance-pop\ncinematic orchestral, retro pop, Indonesian pop\ncinematic orchestral, retro-pop, Korean trot\ncinematic orchestral, romantic ballad, Hindi pop\ncinematic orchestral, romantic ballad, Italian style\ncinematic orchestral, salsa, Latin fusion\ncinematic orchestral, samba-gospel\ncinematic orchestral, samba-pop\ncinematic orchestral, samba-pop, MPB\ncinematic orchestral, samba-reggae\ncinematic orchestral, samba-reggae, Brazilian carnival\ncinematic orchestral, samba-reggae, heavy metal\ncinematic orchestral, schlager\ncinematic orchestral, schlager, big band\ncinematic orchestral, schlager, chanson\ncinematic orchestral, schlager, dansband\ncinematic orchestral, schlager, folk waltz\ncinematic orchestral, schlager, operatic pop\ncinematic orchestral, schlager, pop\ncinematic orchestral, schlager, pop ballad\ncinematic orchestral, schlager, pop-rock\ncinematic orchestral, schlager, romantic ballad\ncinematic orchestral, schlager-rock, party rock\ncinematic orchestral, sertanejo, emotional pop\ncinematic orchestral, show tune, jazz\ncinematic orchestral, smooth jazz\ncinematic orchestral, smooth jazz, jazz fusion\ncinematic orchestral, smooth jazz, progressive rock\ncinematic orchestral, soft rock\ncinematic orchestral, soul, R&B\ncinematic orchestral, soulful Christmas ballad\ncinematic orchestral, soulful ballad, zouk\ncinematic orchestral, spy jazz\ncinematic orchestral, spy thriller, surf rock\ncinematic orchestral, surf rock\ncinematic orchestral, symphonic metal\ncinematic orchestral, symphonic rock\ncinematic orchestral, synth-pop\ncinematic orchestral, synth-pop, Eurodance\ncinematic orchestral, synth-pop, Italo-disco\ncinematic orchestral, synth-pop, new jack swing\ncinematic orchestral, synth-pop, nostalgic\ncinematic orchestral, synth-rock, romantic orchestral\ncinematic orchestral, tango, operatic\ncinematic orchestral, theatrical pop, Christmas\ncinematic orchestral, theatrical show tune, big band\ncinematic orchestral, theatrical, ragtime\ncinematic orchestral, traditional Chinese\ncinematic orchestral, traditional Chinese, epic\ncinematic orchestral, traditional Spanish, choral\ncinematic orchestral, traditional Spanish, festive\ncinematic orchestral, trap\ncinematic orchestral, trap, Chinese traditional\ncinematic orchestral, trap, Indian fusion\ncinematic orchestral, trap, operatic\ncinematic orchestral, trap, rock\ncinematic orchestral, trap, rock opera\ncinematic orchestral, trip-hop\ncinematic orchestral, trip-hop, world fusion\ncinematic orchestral, trot\ncinematic orchestral, trot, big band\ncinematic orchestral, trot, disco-pop\ncinematic orchestral, trot, emotional ballad\ncinematic orchestral, trot, jazz\ncinematic orchestral, trot, soulful pop\ncinematic orchestral, video game music\ncinematic orchestral, video game music, synthwave\ncinematic orchestral, video game, synthwave\ncinematic orchestral, vintage Indonesian pop\ncinematic orchestral, vocal jazz\ncinematic orchestral, vocal jazz, operatic pop\ncinematic orchestral, world fusion\ncinematic orchestral, world fusion, ambient\ncinematic orchestral, world fusion, epic\ncinematic orchestral, world fusion, funk\ncinematic orchestral, world music, C-pop\ncinematic orchestral, world-pop, Latin\ncinematic orchestral, worship ballad, J-pop\ncinematic orchestral, wuxia, Chinese epic\ncinematic orchestral, wuxia, Chinese fantasy\ncinematic orchestral, wuxia, electronic\ncinematic orchestral, wuxia, historical fantasy\ncinematic orchestral, wuxia, traditional Chinese\ncinematic orchestral, zouk, R&B\ncinematic orchestral, zouk, kompa\ncinematic orchestral,古风\ncinematic organ\ncinematic oud\ncinematic pastoral\ncinematic patriotic\ncinematic percussion\ncinematic phonk\ncinematic piano\ncinematic piano ballad\ncinematic piano ballad alternative rock\ncinematic piano ballad, J-pop, Eurobeat\ncinematic piano ballad, J-rock, power ballad\ncinematic piano ballad, bilingual hip-hop\ncinematic piano ballad, rumba-flamenco\ncinematic piano ballad, trip-hop\ncinematic piano chiptune\ncinematic piano jazz\ncinematic piano post-rock\ncinematic piano rock\ncinematic piano trap\ncinematic piano, Brazilian funk\ncinematic piano, Chinese traditional, modern rock\ncinematic piano, J-rock\ncinematic piano, J-rock, orchestral\ncinematic piano, Latin jazz\ncinematic piano, baritone vocal, French chanson\ncinematic piano, drum and bass, alternative rock\ncinematic piano, funk, disco\ncinematic piano, lo-fi hip-hop, chillwave\ncinematic piano, nu-disco, synth-pop\ncinematic piano, ragtime, synth-pop\ncinematic piano, salsa, ballad\ncinematic pirate metal\ncinematic pirate rock\ncinematic polka\ncinematic pop\ncinematic pop Afrobeat\ncinematic pop Bollywood\ncinematic pop J-pop\ncinematic pop Latin\ncinematic pop R&B\ncinematic pop ambient\ncinematic pop anime\ncinematic pop ballad\ncinematic pop cabaret\ncinematic pop chanson\ncinematic pop classical crossover\ncinematic pop dancehall\ncinematic pop dangdut\ncinematic pop disco\ncinematic pop funk\ncinematic pop fusion\ncinematic pop future bass\ncinematic pop gospel\ncinematic pop hip-hop\ncinematic pop neo-soul\ncinematic pop progressive house\ncinematic pop rap\ncinematic pop reggae\ncinematic pop rock\ncinematic pop salsa\ncinematic pop schlager\ncinematic pop soul\ncinematic pop tango\ncinematic pop trap\ncinematic pop world music\ncinematic pop worldbeat\ncinematic pop, 80s Israeli pop\ncinematic pop, 80s boogie, gospel soul\ncinematic pop, Arabic pop\ncinematic pop, Arabic pop, R&B\ncinematic pop, Arabic pop, ballad\ncinematic pop, Arabic pop, classical fusion\ncinematic pop, Arabic pop, dreamy R&B\ncinematic pop, Arabic pop, folk orchestral\ncinematic pop, Azerbaijani folk\ncinematic pop, Azerbaijani folk, hip-hop\ncinematic pop, Balkan electronic\ncinematic pop, Balkan folk, Eastern European\ncinematic pop, Balkan pop, Latin dance-pop\ncinematic pop, Bollywood\ncinematic pop, Bollywood funk\ncinematic pop, Brazilian Funk\ncinematic pop, Brazilian pop\ncinematic pop, Brazilian pop, gospel\ncinematic pop, Brazilian pop-rock\ncinematic pop, Brazilian pop-rock, European folk\ncinematic pop, C-pop, J-pop\ncinematic pop, C-pop, orchestral\ncinematic pop, C-pop, traditional Chinese\ncinematic pop, C-pop, traditional fusion\ncinematic pop, Central Asian pop, Middle Eastern pop\ncinematic pop, Chinese fantasy, orchestral\ncinematic pop, Chinese hip-hop\ncinematic pop, Chinese opera, orchestral\ncinematic pop, Chinese opera, orchestral pop\ncinematic pop, Chinese pop\ncinematic pop, Chinese traditional, ballad\ncinematic pop, Chinese traditional, orchestral\ncinematic pop, Christian rock\ncinematic pop, Christian trap\ncinematic pop, Dangdut Koplo\ncinematic pop, Dutch hip-hop\ncinematic pop, EDM, Telugu pop\ncinematic pop, EDM, traditional East Asian\ncinematic pop, EDM, trap\ncinematic pop, East Asian pop\ncinematic pop, East Asian traditional\ncinematic pop, Eurodance, chanson\ncinematic pop, Eurodance, operatic\ncinematic pop, Filipino pop\ncinematic pop, Filipino pop, 80s pop\ncinematic pop, Finnish hip-hop\ncinematic pop, French R&B, trap\ncinematic pop, French chanson, Latin dance-pop\ncinematic pop, German Schlager\ncinematic pop, German Schlager, Christmas\ncinematic pop, Indian classical, electronic\ncinematic pop, Indian film music, electronic\ncinematic pop, Indian fusion, electronic\ncinematic pop, Indian fusion, rock\ncinematic pop, Indian melodicism, electronic\ncinematic pop, Italian pop-rock\ncinematic pop, Italo-disco\ncinematic pop, Italo-disco, operatic\ncinematic pop, J-pop, anime soundtrack\ncinematic pop, J-pop, anime theme\ncinematic pop, J-pop, happy hardcore\ncinematic pop, J-pop, orchestral\ncinematic pop, J-pop, trance\ncinematic pop, J-rock\ncinematic pop, K-pop, Christmas\ncinematic pop, Kizomba, hip-hop\ncinematic pop, Latin dance-pop\ncinematic pop, Latin fusion\ncinematic pop, Latin pop\ncinematic pop, Latin pop, Christmas\ncinematic pop, Latin pop, Eurodance\ncinematic pop, Latin pop, reggaeton\ncinematic pop, Latin pop-rock\ncinematic pop, Latin-pop, ethereal\ncinematic pop, Luk Thung\ncinematic pop, Middle Eastern fusion, hip-hop\ncinematic pop, Middle Eastern, electronic\ncinematic pop, Mongolian folk, epic ballad\ncinematic pop, Nepali pop\ncinematic pop, Persian dance-pop\ncinematic pop, Persian pop, orchestral\ncinematic pop, Persian pop, orchestral dance\ncinematic pop, R&B\ncinematic pop, R&B trap\ncinematic pop, R&B, Arabic fusion\ncinematic pop, R&B, South Indian fusion\ncinematic pop, R&B, funk\ncinematic pop, R&B, hip-hop\ncinematic pop, R&B, synth-pop\ncinematic pop, R&B, trap\ncinematic pop, Russian estrada\ncinematic pop, Russian estrada, 80s ballad\ncinematic pop, Russian estrada, late-90s pop\ncinematic pop, Russian estrada, synth ballad\ncinematic pop, Russian pop\ncinematic pop, Russian pop-rock, Eurodance\ncinematic pop, Schlager\ncinematic pop, South Asian folk, hip-hop\ncinematic pop, South Asian fusion\ncinematic pop, South Asian fusion, electronic\ncinematic pop, South Asian pop\ncinematic pop, South Indian, electronic\ncinematic pop, Southeast Asian pop\ncinematic pop, Southeast Asian pop, pop rock\ncinematic pop, Soviet estrada\ncinematic pop, Soviet estrada, orchestral\ncinematic pop, Tamil dance\ncinematic pop, Tamil pop-funk\ncinematic pop, Thai Luk Thung\ncinematic pop, Turkish dance-pop\ncinematic pop, Turkish folk, Balkan fusion\ncinematic pop, Turkish folk, flamenco fusion\ncinematic pop, Turkish fusion\ncinematic pop, Turkish fusion, orchestral\ncinematic pop, Turkish pop\ncinematic pop, Turkish pop-dance\ncinematic pop, Turkish pop-rock\ncinematic pop, Vietnamese bolero\ncinematic pop, Vietnamese folk-pop, disco\ncinematic pop, Vocaloid, Chinese classical\ncinematic pop, ambient, world music\ncinematic pop, arabesque, Turkish pop\ncinematic pop, arabesque, big band\ncinematic pop, arabesque, disco\ncinematic pop, big band jazz\ncinematic pop, cabaret, schlager\ncinematic pop, chanson, epic rock\ncinematic pop, children's pop\ncinematic pop, city pop, funk\ncinematic pop, city pop, lounge\ncinematic pop, complextro, hardstyle\ncinematic pop, conscious hip-hop\ncinematic pop, contemporary Christian, pop-rock\ncinematic pop, cumbia, ballad\ncinematic pop, dance-pop, Middle Eastern\ncinematic pop, dancehall, moombahton\ncinematic pop, dangdut koplo\ncinematic pop, dangdut, rock\ncinematic pop, dark trap\ncinematic pop, disco dangdut\ncinematic pop, dubstep, hardstyle\ncinematic pop, electronic hip-hop\ncinematic pop, electronic trap, art pop\ncinematic pop, electronic world music\ncinematic pop, electronic, Central Asian\ncinematic pop, electronic, classical\ncinematic pop, emotional hip-hop, trap\ncinematic pop, epic trailer music\ncinematic pop, estrada, orchestral\ncinematic pop, estrada, synth ballad\ncinematic pop, estrada, synthwave\ncinematic pop, estrada, vintage film score\ncinematic pop, eurodance\ncinematic pop, eurodance, oud fusion\ncinematic pop, eurodance, trance\ncinematic pop, experimental electronic\ncinematic pop, festive, Indian fusion\ncinematic pop, folk fusion\ncinematic pop, funk, R&B\ncinematic pop, funk-pop, hip-hop\ncinematic pop, funk-rock\ncinematic pop, future bass, hardstyle\ncinematic pop, future bass, trap\ncinematic pop, gospel, Haitian Creole\ncinematic pop, hardstyle\ncinematic pop, hardstyle, anime theme\ncinematic pop, hardstyle, big room\ncinematic pop, hardstyle, big room house\ncinematic pop, hardstyle, trap\ncinematic pop, hip-hop\ncinematic pop, hip-hop, dubstep\ncinematic pop, hip-hop, ethereal\ncinematic pop, hyperpop\ncinematic pop, kuthu\ncinematic pop, metalcore\ncinematic pop, modern trap\ncinematic pop, new age, world music\ncinematic pop, nu-disco\ncinematic pop, nu-metal, lo-fi hip hop\ncinematic pop, orchestral pop, J-rock\ncinematic pop, orchestral, Ancient Style\ncinematic pop, orchestral, Chinese folk\ncinematic pop, orchestral, Chinese folk-pop\ncinematic pop, orchestral, Chinese fusion\ncinematic pop, orchestral, Chinese influence\ncinematic pop, orchestral, Chinese traditional\ncinematic pop, orchestral, East Asian\ncinematic pop, orchestral, East Asian fantasy\ncinematic pop, orchestral, arabesque\ncinematic pop, orchestral, traditional Chinese\ncinematic pop, orchestral, world fusion\ncinematic pop, pop keroncong\ncinematic pop, pop-rap\ncinematic pop, pop-rock\ncinematic pop, progressive rock, tango\ncinematic pop, progressive rock, world music\ncinematic pop, rap-rock\ncinematic pop, reggaeton\ncinematic pop, reggaeton, flamenco\ncinematic pop, retro Indonesian pop\ncinematic pop, retro Nepali pop\ncinematic pop, retro Soviet pop\ncinematic pop, schlager\ncinematic pop, schlager, christmas\ncinematic pop, schlager, orchestral\ncinematic pop, schlager, synth pop\ncinematic pop, sertanejo, orchestral\ncinematic pop, show tune, funk rock\ncinematic pop, synth-pop\ncinematic pop, synth-pop, R&B soul, power ballad\ncinematic pop, synth-pop, orchestral\ncinematic pop, synth-pop, pop-rock\ncinematic pop, traditional Chinese, ballad\ncinematic pop, traditional Chinese, orchestral\ncinematic pop, traditional Chinese, power ballad\ncinematic pop, traditional Malay, vintage Indonesian pop\ncinematic pop, trap\ncinematic pop, trap, Arabic ballad\ncinematic pop, trap, C-pop\ncinematic pop, trap, Central Asian\ncinematic pop, trap, Central Asian fusion\ncinematic pop, trap, Dutch rap\ncinematic pop, trap, Middle Eastern\ncinematic pop, trap, R&B\ncinematic pop, trap, South Asian\ncinematic pop, trap, hip-hop\ncinematic pop, trap, orchestral\ncinematic pop, trap, spoken word\ncinematic pop, trap, world fusion\ncinematic pop, trip-hop\ncinematic pop, trip-hop, Latin pop, Eurodance\ncinematic pop, vintage Indonesian pop-rock\ncinematic pop, vintage pop, Kayōkyoku\ncinematic pop, world fusion\ncinematic pop, world music\ncinematic pop, world music, Arabic\ncinematic pop, world music, electronic\ncinematic pop, world music, operatic rock\ncinematic pop-EDM\ncinematic pop-R&B\ncinematic pop-ballad\ncinematic pop-chanson\ncinematic pop-country\ncinematic pop-dangdut\ncinematic pop-folk\ncinematic pop-funk\ncinematic pop-gospel\ncinematic pop-hip hop\ncinematic pop-hip-hop\ncinematic pop-punk\ncinematic pop-r&b\ncinematic pop-rap\ncinematic pop-rock\ncinematic pop-rock J-pop\ncinematic pop-rock hip-hop\ncinematic pop-rock, hardstyle, dubstep\ncinematic pop-rock, hip-hop\ncinematic pop-schlager\ncinematic pop-soul\ncinematic pop-trap\ncinematic post-hardcore\ncinematic post-metal\ncinematic post-punk\ncinematic post-rock\ncinematic power ballad\ncinematic power metal\ncinematic power pop\ncinematic power-ballad, Latin Christian cumbia\ncinematic power-pop\ncinematic prog\ncinematic prog rock\ncinematic progressive\ncinematic progressive house\ncinematic progressive metal\ncinematic progressive rock\ncinematic progressive trance\ncinematic protest\ncinematic psychedelic\ncinematic psychedelic Latin\ncinematic psychedelic pop\ncinematic psychedelic rock\ncinematic psytrance\ncinematic punk\ncinematic punk cabaret\ncinematic punk rock\ncinematic qanun\ncinematic qawwali\ncinematic ragtime\ncinematic ranchera\ncinematic rap\ncinematic rap rock\ncinematic rap-rock\ncinematic raï\ncinematic reggae\ncinematic reggae-pop\ncinematic reggaeton\ncinematic reggaeton-pop\ncinematic retro-funk\ncinematic ritual\ncinematic rock\ncinematic rock C-pop\ncinematic rock C-pop wuxia\ncinematic rock ballad\ncinematic rock fusion\ncinematic rock hip-hop\ncinematic rock opera\ncinematic rock pop\ncinematic rock, C-pop, ancient style\ncinematic rock, C-rock, wuxia\ncinematic rock, Chinese folk rock\ncinematic rock, Chinese fusion\ncinematic rock, Chinese opera, symphonic rock\ncinematic rock, EDM, Bollywood\ncinematic rock, J-rock, Chinese rock\ncinematic rock, J-rock, epic rock\ncinematic rock, Latin rock\ncinematic rock, Middle Eastern fusion, orchestral\ncinematic rock, arabesque, Turkish fusion\ncinematic rock, cabaret, Chinese opera\ncinematic rock, contemporary Christian rock, gospel rap\ncinematic rock, dangdut koplo, Javanese folk\ncinematic rock, dangdut, traditional Indonesian\ncinematic rock, electronic dance\ncinematic rock, electronicore\ncinematic rock, future bass, lo-fi\ncinematic rock, hip-hop, nu-metal\ncinematic rock, hip-hop, soul\ncinematic rock, nu-metal, Chinese fusion\ncinematic rock, pop-dangdut, Javanese pop\ncinematic rock, pop-rock, Ancient Style\ncinematic rock, pop-rock, Chinese hip hop\ncinematic rock, synth-pop, Tamil indie\ncinematic rock, thrash metal, dangdut koplo\ncinematic rock, traditional Chinese, epic ballad\ncinematic rock, world fusion, rap\ncinematic rock, wuxia, J-rock\ncinematic rock-pop\ncinematic rockabilly\ncinematic romance\ncinematic romantic\ncinematic rumba\ncinematic rumba flamenco\ncinematic sacred\ncinematic salsa\ncinematic salsa-pop\ncinematic samba\ncinematic samba-jazz\ncinematic samba-pop\ncinematic samba-reggae\ncinematic samba-rock\ncinematic saxophone\ncinematic schlager\ncinematic sci-fi\ncinematic score\ncinematic sea shanty\ncinematic shoegaze\ncinematic show tune\ncinematic singer-songwriter\ncinematic sitar\ncinematic ska-punk\ncinematic slide guitar\ncinematic smooth jazz\ncinematic soft rock\ncinematic soft-rock\ncinematic sorrow\ncinematic soul\ncinematic soul funk\ncinematic soul gospel\ncinematic soul jazz\ncinematic soul rock\ncinematic soul trap\ncinematic soul-funk\ncinematic soul-pop\ncinematic soul-rock\ncinematic sound design\ncinematic soundtrack\ncinematic spiritual\ncinematic spoken word\ncinematic sports anthem\ncinematic spy\ncinematic spy theme\ncinematic steampunk\ncinematic stinger\ncinematic storytelling\ncinematic string\ncinematic string quartet\ncinematic surf rock\ncinematic surf-punk\ncinematic surf-rock\ncinematic surf-ska\ncinematic suspense\ncinematic swing\ncinematic swing-pop\ncinematic symphonic\ncinematic symphonic metal\ncinematic synth\ncinematic synth ballad\ncinematic synth funk\ncinematic synth pop\ncinematic synth rock\ncinematic synth, 2000s R&B\ncinematic synth, 80s Latin pop\ncinematic synth, 80s adult contemporary\ncinematic synth, 80s boogie-funk\ncinematic synth, 80s hard rock\ncinematic synth, 80s metal\ncinematic synth, 90s R&B\ncinematic synth, Balkan pop-rock\ncinematic synth, Brazilian Boi-Bumbá\ncinematic synth, Brazilian funk carioca\ncinematic synth, Dangdut Koplo\ncinematic synth, Eurobeat, J-pop\ncinematic synth, French drill\ncinematic synth, French hip-hop\ncinematic synth, G-funk\ncinematic synth, German Schlager, musical theater\ncinematic synth, German gangsta rap, trap\ncinematic synth, J-pop, Eurobeat\ncinematic synth, J-rock\ncinematic synth, Middle Eastern, electronic\ncinematic synth, R&B, gospel-pop\ncinematic synth, Russian chanson\ncinematic synth, Russian rock\ncinematic synth, UK drill, trap\ncinematic synth, UK hip-hop, R&B\ncinematic synth, Vietnamese pop, orchestral\ncinematic synth, boom-bap hip hop\ncinematic synth, boom-bap hip-hop\ncinematic synth, drum and bass, Middle Eastern fusion\ncinematic synth, indie rock\ncinematic synth, lo-fi hip hop, Cantonese rap\ncinematic synth, lo-fi trap, C-pop\ncinematic synth, merengue\ncinematic synth, neo-soul, UK garage\ncinematic synth, pop-rock, J-rock\ncinematic synth, pop-rock, dangdut\ncinematic synth, post-punk\ncinematic synth, raï, electronic dance\ncinematic synth, retro-funk\ncinematic synth, smooth jazz\ncinematic synth, world fusion\ncinematic synth-funk\ncinematic synth-orchestral\ncinematic synth-orchestral J-rock\ncinematic synth-orchestral complextro\ncinematic synth-orchestral gothic rock\ncinematic synth-orchestral jazz-funk\ncinematic synth-orchestral power ballad\ncinematic synth-orchestral power-pop\ncinematic synth-orchestral, 80s Eurodance\ncinematic synth-orchestral, 80s arena rock\ncinematic synth-orchestral, 80s pop-rock\ncinematic synth-orchestral, C-pop, trap\ncinematic synth-orchestral, French pop-rock\ncinematic synth-orchestral, J-pop\ncinematic synth-orchestral, eurodance\ncinematic synth-pop\ncinematic synth-pop metalcore\ncinematic synth-pop rock\ncinematic synth-rock\ncinematic synthpop\ncinematic synthpunk\ncinematic synthwave\ncinematic synthwave trap\ncinematic tango\ncinematic tango ballad\ncinematic tango cumbia\ncinematic tango pop\ncinematic tango reggaeton\ncinematic tech house\ncinematic tech-house\ncinematic techno\ncinematic tension\ncinematic theater\ncinematic thrash metal\ncinematic thriller\ncinematic torch song\ncinematic torch song, big band swing\ncinematic trailer\ncinematic trailer music\ncinematic trailer score\ncinematic trance\ncinematic trance progressive house\ncinematic trance psytrance\ncinematic trance techno\ncinematic trance, EBM, industrial techno\ncinematic trance, J-pop, electro house\ncinematic trance, complextro, dubstep\ncinematic trance, eurodance\ncinematic trance, eurodance, hardstyle\ncinematic trance, happy hardcore\ncinematic trance, hardstyle\ncinematic trance, hardstyle, EDM\ncinematic trance, hardstyle, Mandarin spoken word\ncinematic trance, hardstyle, dubstep\ncinematic trance, psytrance, hardstyle\ncinematic trance, techno, psytrance\ncinematic trance-pop\ncinematic trap\ncinematic trap R&B\ncinematic trap metal\ncinematic trap metalcore\ncinematic trap rock\ncinematic trap soul\ncinematic trap, Chinese aesthetics, modern hip-hop\ncinematic trap, Chinese hip-hop\ncinematic trap, Chinese opera, modern hip-hop\ncinematic trap, Latin Cumbia\ncinematic trap, hardstyle, Thai fusion\ncinematic trap, hardstyle, dubstep\ncinematic trap, hyperpop, C-pop\ncinematic trap, lo-fi hip hop\ncinematic trap, melodic hip-hop\ncinematic trap, neo-soul\ncinematic trap-pop\ncinematic trap-rock\ncinematic tribal\ncinematic tribal house\ncinematic tribal rock\ncinematic trip-hop\ncinematic trip-hop industrial rock\ncinematic trip-hop worldbeat\ncinematic tropical house\ncinematic trot\ncinematic turbo-folk\ncinematic ukulele\ncinematic vallenato\ncinematic video game\ncinematic villain anthem\ncinematic violin\ncinematic vocal\ncinematic vocal jazz\ncinematic vocal pop\ncinematic waltz\ncinematic waltz, Latin salsa\ncinematic western\ncinematic western rock\ncinematic western-noir\ncinematic whimsy\ncinematic world\ncinematic world beat\ncinematic world dance\ncinematic world drum\ncinematic world electronica\ncinematic world folk\ncinematic world fusion\ncinematic world house\ncinematic world jazz\ncinematic world music\ncinematic world music pop-rock\ncinematic world percussion\ncinematic world pop\ncinematic world rock\ncinematic world-folk\ncinematic world-pop\ncinematic worldbeat\ncinematic worship\ncinematic worship chiptune\ncinematic worship rock\ncinematic worship, Latin pop-rock\ncinematic worship, South Indian, epic\ncinematic wuxia\ncinematic wuxia pop-rock\ncinematic wuxia, electronic pop, Chinese aesthetics\ncinematic, Americana, orchestral\ncinematic, Anatolian, Middle Eastern\ncinematic, Arabic classical, epic\ncinematic, Arabic classical, orchestral\ncinematic, Arabic fusion, orchestral\ncinematic, Arabic opera, emotional\ncinematic, Arabic, Indonesian\ncinematic, Arabic, ambient\ncinematic, Arabic, choral\ncinematic, Arabic, epic\ncinematic, Arabic, melancholic\ncinematic, Arabic, operatic\ncinematic, Arabic, orchestral\ncinematic, Balkan brass, cabaret\ncinematic, Balkan folk, electronic dance\ncinematic, Balkan, Arabic\ncinematic, Balkan, Klezmer\ncinematic, Balkan, Middle Eastern\ncinematic, Balkan, lo-fi\ncinematic, Balkan, orchestral\ncinematic, Bhangra, rock\ncinematic, Boi-Bumbá\ncinematic, Bollywood, ambient\ncinematic, Bollywood, epic\ncinematic, Bollywood, orchestral\ncinematic, Bollywood, taiko\ncinematic, Brazilian carnival, orchestral\ncinematic, C-pop, ambient\ncinematic, C-pop, orchestral\ncinematic, Carnatic, orchestral\ncinematic, Celtic, ethereal\ncinematic, Celtic, instrumental\ncinematic, Celtic, orchestral\ncinematic, Chinese classical, ambient\ncinematic, Chinese classical, instrumental\ncinematic, Chinese classical, orchestral\ncinematic, Chinese flute, ambient\ncinematic, Chinese flute, cello\ncinematic, Chinese flute, emotional\ncinematic, Chinese flute, epic\ncinematic, Chinese flute, instrumental\ncinematic, Chinese flute, orchestral\ncinematic, Chinese flute, piano\ncinematic, Chinese orchestral, downtempo\ncinematic, Chinese orchestral, emotional\ncinematic, Chinese orchestral, epic\ncinematic, Chinese orchestral, instrumental\ncinematic, Chinese orchestral, orchestral\ncinematic, Chinese, ambient\ncinematic, Chinese, epic\ncinematic, Chinese, instrumental\ncinematic, Chinese, orchestral\ncinematic, Christmas, operatic\ncinematic, Christmas, orchestral\ncinematic, East Asian classical, orchestral\ncinematic, East Asian fantasy, ambient\ncinematic, East Asian fantasy, orchestral\ncinematic, East Asian fusion, ambient\ncinematic, East Asian fusion, instrumental\ncinematic, East Asian, JRPG\ncinematic, East Asian, RPG\ncinematic, East Asian, action\ncinematic, East Asian, ambient\ncinematic, East Asian, choral\ncinematic, East Asian, dramatic\ncinematic, East Asian, electronic\ncinematic, East Asian, epic\ncinematic, East Asian, instrumental\ncinematic, East Asian, modern\ncinematic, East Asian, orchestral\ncinematic, East Asian, synth\ncinematic, East Asian, video game\ncinematic, Eastern classical, Western classical\ncinematic, European, classical\ncinematic, European, theatrical\ncinematic, European, waltz\ncinematic, European, whimsical\ncinematic, French chanson, ambient\ncinematic, French chanson, classical\ncinematic, French chanson, orchestral\ncinematic, Greek folk, classical\ncinematic, Hawaiian, orchestral\ncinematic, Hindi, breakbeat\ncinematic, Indian classical, ambient\ncinematic, Indian classical, art song\ncinematic, Indian classical, choral\ncinematic, Indian classical, electronic\ncinematic, Indian classical, epic\ncinematic, Indian classical, filmi\ncinematic, Indian classical, folk\ncinematic, Indian classical, orchestral\ncinematic, Indian classical, piano\ncinematic, Indian classical, spiritual\ncinematic, Indian devotional, electronic\ncinematic, Indian devotional, orchestral\ncinematic, Indian film music, ambient\ncinematic, Indian film, hip-hop\ncinematic, Indian folk, electronic\ncinematic, Indian folk, epic rock\ncinematic, Indian folk, melancholic\ncinematic, Indian fusion, electronic\ncinematic, Indian fusion, epic\ncinematic, Indian fusion, epic score\ncinematic, Indian fusion, inspirational\ncinematic, Indian fusion, orchestral\ncinematic, Indonesian pop\ncinematic, Italo-disco, baroque\ncinematic, JRPG, ambient\ncinematic, JRPG, world music\ncinematic, Japanese folk, orchestral\ncinematic, Javanese, electronic\ncinematic, Javanese, epic\ncinematic, K-trot, synthwave\ncinematic, Kayōkyoku, orchestral\ncinematic, Latin funk, instrumental\ncinematic, Latin fusion, orchestral\ncinematic, Latin groove, psychedelic rock\ncinematic, Latin jazz\ncinematic, Latin, acoustic\ncinematic, Latin, chaotic\ncinematic, Latin, orchestral\ncinematic, Latin, vibraphone\ncinematic, MPB, operatic\ncinematic, Middle Eastern classical, orchestral\ncinematic, Middle Eastern folk, ney\ncinematic, Middle Eastern fusion, ambient\ncinematic, Middle Eastern fusion, orchestral\ncinematic, Middle Eastern orchestral\ncinematic, Middle Eastern, Arabic\ncinematic, Middle Eastern, Balkan\ncinematic, Middle Eastern, Balkan folk\ncinematic, Middle Eastern, Laïko\ncinematic, Middle Eastern, Turkish\ncinematic, Middle Eastern, Turkish classical\ncinematic, Middle Eastern, Turkish folk\ncinematic, Middle Eastern, ambient\ncinematic, Middle Eastern, anthem\ncinematic, Middle Eastern, arabesque\ncinematic, Middle Eastern, choral\ncinematic, Middle Eastern, classical\ncinematic, Middle Eastern, devotional\ncinematic, Middle Eastern, dramatic\ncinematic, Middle Eastern, electronic\ncinematic, Middle Eastern, emotional\ncinematic, Middle Eastern, emotive\ncinematic, Middle Eastern, epic\ncinematic, Middle Eastern, fantasy\ncinematic, Middle Eastern, flamenco\ncinematic, Middle Eastern, folk\ncinematic, Middle Eastern, instrumental\ncinematic, Middle Eastern, melancholic\ncinematic, Middle Eastern, narrative\ncinematic, Middle Eastern, ney flute\ncinematic, Middle Eastern, operatic\ncinematic, Middle Eastern, orchestral\ncinematic, Middle Eastern, oud\ncinematic, Middle Eastern, piano\ncinematic, Middle Eastern, spiritual\ncinematic, Middle Eastern, theatrical\ncinematic, Middle Eastern, tribal\ncinematic, Mongolian folk, orchestral\ncinematic, Persian art music, orchestral\ncinematic, Persian classical, ambient\ncinematic, Persian classical, emotional\ncinematic, Persian classical, epic\ncinematic, Persian classical, orchestral\ncinematic, Persian folk, classical fusion\ncinematic, Persian opera, orchestral\ncinematic, Persian, ambient\ncinematic, Persian, baritone\ncinematic, Persian, classical\ncinematic, Persian, emotional\ncinematic, Persian, emotive\ncinematic, Persian, melancholic\ncinematic, Persian, orchestral\ncinematic, Persian, soulful\ncinematic, RPG soundtrack, East Asian\ncinematic, RPG, anime\ncinematic, Russian romance, orchestral\ncinematic, South Asian film music, melancholic\ncinematic, South Asian folk, ghazal\ncinematic, South Indian film music, electronic\ncinematic, Spanish, soul\ncinematic, Tamil, militaristic\ncinematic, Turkish arabesque, classical\ncinematic, Turkish arabesque, epic\ncinematic, Turkish arabesque, melancholic\ncinematic, Turkish arabesque, orchestral\ncinematic, Turkish art music, classical\ncinematic, Turkish art music, emotional\ncinematic, Turkish art music, melancholic\ncinematic, Turkish art music, orchestral\ncinematic, Turkish classical, Middle Eastern\ncinematic, Turkish classical, ambient\ncinematic, Turkish classical, arabesque\ncinematic, Turkish classical, dramatic\ncinematic, Turkish classical, emotional\ncinematic, Turkish classical, epic\ncinematic, Turkish classical, film score\ncinematic, Turkish classical, melancholic\ncinematic, Turkish classical, ney\ncinematic, Turkish classical, operatic\ncinematic, Turkish classical, orchestral\ncinematic, Turkish folk, ambient\ncinematic, Turkish folk, arabesque\ncinematic, Turkish folk, classical\ncinematic, Turkish folk, electronic\ncinematic, Turkish folk, emotional\ncinematic, Turkish folk, epic\ncinematic, Turkish folk, melancholic\ncinematic, Turkish folk, ney\ncinematic, Turkish folk, operatic\ncinematic, Turkish folk, orchestral\ncinematic, Turkish folk, oud\ncinematic, Turkish folk, spiritual\ncinematic, Turkish orchestral, Middle Eastern\ncinematic, Turkish, Middle Eastern\ncinematic, Turkish, Sufi\ncinematic, Turkish, ambient\ncinematic, Turkish, emotional\ncinematic, Turkish, epic\ncinematic, Turkish, ney\ncinematic, Turkish, operatic\ncinematic, Turkish, orchestral\ncinematic, Turkish, oud\ncinematic, Turkish, synth orchestral\ncinematic, Turkish-inspired, emotive\ncinematic, Vietnamese folk opera, orchestral\ncinematic, Vocaloid, Chinese orchestral\ncinematic, accordion, Mandarin opera\ncinematic, accordion, orchestral\ncinematic, acid jazz, Latin percussion\ncinematic, acoustic, Indian classical\ncinematic, acoustic, orchestral\ncinematic, ambient, C-pop\ncinematic, ambient, Chinese classical\ncinematic, ambient, Chinese flute\ncinematic, ambient, Chinese traditional\ncinematic, ambient, East Asian\ncinematic, ambient, Middle Eastern\ncinematic, ambient, Persian vocal\ncinematic, ambient, ancient style\ncinematic, ambient, folk\ncinematic, ambient, martial\ncinematic, ambient, traditional\ncinematic, ambient, traditional Chinese\ncinematic, ambient, traditional East Asian\ncinematic, ambient, traditional Japanese\ncinematic, ancient style, choral\ncinematic, ancient style, electronic\ncinematic, ancient style, ney\ncinematic, ancient style, orchestral\ncinematic, ancient style, rock\ncinematic, anime, orchestral\ncinematic, arabesque, Turkish pop\ncinematic, arabesque, classical\ncinematic, arabesque, epic\ncinematic, arabesque, mystical\ncinematic, arabesque, ney\ncinematic, arabesque, orchestral\ncinematic, arabesque, world fusion\ncinematic, art music, Turkish\ncinematic, art music, melancholic\ncinematic, art song, European cabaret\ncinematic, avant-garde, Turkish arabesque\ncinematic, avant-garde, operatic\ncinematic, ballad, pop\ncinematic, bansuri, ghazal\ncinematic, bansuri, orchestral\ncinematic, bansuri, soulful\ncinematic, baritone, cabaret\ncinematic, baroque pop, chanson\ncinematic, baroque, Middle Eastern\ncinematic, baroque, horror\ncinematic, baroque, orchestral\ncinematic, big band, Latin\ncinematic, big band, choral\ncinematic, big band, microtonal\ncinematic, big band, operatic\ncinematic, big band, orchestral\ncinematic, bolero, synth-pop\ncinematic, bossa nova, orchestral\ncinematic, cabaret, big band\ncinematic, cabaret, chanson\ncinematic, cartoon, folk\ncinematic, chamber, ambient\ncinematic, chanson, ambient\ncinematic, chanson, orchestral\ncinematic, children's music, orchestral\ncinematic, chiptune, baroque\ncinematic, chiptune, heavy metal\ncinematic, choral, Arabic classical\ncinematic, choral, Christmas\ncinematic, choral, Hawaiian\ncinematic, choral, Tamil classical\ncinematic, choral, ambient\ncinematic, choral, classical\ncinematic, choral, gospel\ncinematic, choral, orchestral\ncinematic, choral, theatrical\ncinematic, choral, world fusion\ncinematic, circus, polka\ncinematic, classical crossover, Christmas\ncinematic, classical crossover, Turkish art music\ncinematic, classical crossover, orchestral\ncinematic, classical fusion, Indian film music\ncinematic, classical, Arabic folk\ncinematic, classical, Chinese traditional\ncinematic, classical, European\ncinematic, classical, Indian classical\ncinematic, classical, Indian fusion\ncinematic, classical, Persian\ncinematic, classical, Persian classical\ncinematic, classical, Persian folk\ncinematic, classical, Persian opera\ncinematic, classical, Persian traditional\ncinematic, classical, South Asian\ncinematic, classical, Turkish\ncinematic, classical, Turkish art music\ncinematic, classical, Turkish art song\ncinematic, classical, Turkish folk\ncinematic, classical, ambient\ncinematic, classical, choral\ncinematic, classical, flamenco\ncinematic, classical, folk\ncinematic, classical, ghazal\ncinematic, classical, opera\ncinematic, classical, operatic\ncinematic, classical, oud\ncinematic, classical, samba\ncinematic, classical, soul\ncinematic, classical, spiritual\ncinematic, classical, tango\ncinematic, classical, theatrical\ncinematic, dark ambient, Middle Eastern\ncinematic, dark ambient, Tamil spoken word\ncinematic, dark ambient, world fusion\ncinematic, dark, chanson\ncinematic, dark, epic\ncinematic, devotional, Arabic\ncinematic, devotional, Indian classical\ncinematic, devotional, ambient\ncinematic, devotional, orchestral\ncinematic, dhol, epic\ncinematic, downtempo, flamenco\ncinematic, dramatic, Indian classical\ncinematic, dramatic, Middle Eastern\ncinematic, dramatic, Persian classical\ncinematic, dramatic, Turkish art music\ncinematic, dramatic, Turkish folk\ncinematic, dramatic, world fusion\ncinematic, duduk, Persian opera\ncinematic, duduk, Persian traditional\ncinematic, duduk, Turkish art music\ncinematic, duduk, Turkish folk\ncinematic, duduk, arabesque\ncinematic, duduk, emotional\ncinematic, duduk, epic\ncinematic, duduk, operatic\ncinematic, electro-industrial, Tamil\ncinematic, electronic, Balkan\ncinematic, electronic, Chinese orchestral\ncinematic, electronic, East Asian\ncinematic, electronic, Indian classical\ncinematic, electronic, Indian devotional\ncinematic, electronic, Indian fusion\ncinematic, electronic, Malay traditional\ncinematic, electronic, Middle Eastern\ncinematic, electronic, South Asian\ncinematic, electronic, South Asian fusion\ncinematic, electronic, South Indian folk\ncinematic, electronic, Turkish folk\ncinematic, electronic, ancient style\ncinematic, electronic, dizi\ncinematic, electronic, folk\ncinematic, electronic, hip-hop\ncinematic, electronic, orchestral\ncinematic, electronic, rock\ncinematic, electronic, traditional East Asian\ncinematic, emotional, Arabic classical\ncinematic, emotional, Chinese classical\ncinematic, emotional, Chinese zither\ncinematic, emotional, East Asian\ncinematic, emotional, Hawaiian\ncinematic, emotional, Indian classical\ncinematic, emotional, Middle Eastern\ncinematic, emotional, South Asian fusion\ncinematic, emotional, Tamil\ncinematic, emotional, accordion\ncinematic, emotional, arabesque\ncinematic, emotional, duduk\ncinematic, emotional, erhu\ncinematic, emotional, ghazal\ncinematic, emotional, guzheng\ncinematic, emotional, world fusion\ncinematic, emotive, South Asian\ncinematic, enka, ambient\ncinematic, enka, blues-rock\ncinematic, enka, orchestral\ncinematic, enka, taiko\ncinematic, epic, Ancient Style\ncinematic, epic, Arabic\ncinematic, epic, Arabic Mawwal\ncinematic, epic, Arabic choral\ncinematic, epic, Arabic classical\ncinematic, epic, Arabic fusion\ncinematic, epic, Arabic opera\ncinematic, epic, Arabic orchestral\ncinematic, epic, Arabic prayer\ncinematic, epic, C-pop\ncinematic, epic, Chinese classical\ncinematic, epic, Chinese orchestral\ncinematic, epic, East Asian\ncinematic, epic, Indian classical\ncinematic, epic, Indian film music\ncinematic, epic, Indian folk\ncinematic, epic, Indian fusion\ncinematic, epic, Japanese ambient\ncinematic, epic, Javanese folk\ncinematic, epic, Middle Eastern\ncinematic, epic, Middle Eastern fusion\ncinematic, epic, Mizrahi\ncinematic, epic, Mongolian folk\ncinematic, epic, Persian\ncinematic, epic, Persian classical\ncinematic, epic, Persian traditional\ncinematic, epic, Persian vocal\ncinematic, epic, South Asian\ncinematic, epic, South Indian classical\ncinematic, epic, Tamil\ncinematic, epic, Telugu\ncinematic, epic, Tibetan\ncinematic, epic, Turkish classical\ncinematic, epic, Turkish folk\ncinematic, epic, Turkish fusion\ncinematic, epic, ambient\ncinematic, epic, ancient style\ncinematic, epic, anime\ncinematic, epic, art pop\ncinematic, epic, choral\ncinematic, epic, devotional\ncinematic, epic, dhol\ncinematic, epic, duduk\ncinematic, epic, electronic\ncinematic, epic, fantasy\ncinematic, epic, folk\ncinematic, epic, guzheng\ncinematic, epic, lo-fi hip hop\ncinematic, epic, martial\ncinematic, epic, operatic\ncinematic, epic, orchestral\ncinematic, epic, oud\ncinematic, epic, ritual\ncinematic, epic, sacred\ncinematic, epic, spiritual\ncinematic, epic, traditional\ncinematic, epic, traditional Persian\ncinematic, epic, traditional Tamil\ncinematic, epic, traditional fusion\ncinematic, epic, winter\ncinematic, epic, world fusion\ncinematic, epic, worship\ncinematic, erhu, ambient\ncinematic, erhu, emotional\ncinematic, erhu, epic\ncinematic, erhu, melancholic\ncinematic, erhu, operatic\ncinematic, erhu, orchestral\ncinematic, erhu, piano\ncinematic, erhu, traditional Chinese\ncinematic, erhu, virtuosic\ncinematic, ethereal, C-pop\ncinematic, ethereal, Chinese classical\ncinematic, ethereal, Chinese folk\ncinematic, ethereal, Chinese opera\ncinematic, ethereal, Christmas\ncinematic, ethereal, Middle Eastern\ncinematic, ethereal, ancient style\ncinematic, ethereal, choral\ncinematic, ethereal, classical\ncinematic, ethereal, guzheng\ncinematic, ethereal, world music\ncinematic, ethno-dance, operatic\ncinematic, eurodance, happy hardcore\ncinematic, experimental electronic, C-pop\ncinematic, experimental, accordion\ncinematic, fantasy, C-pop\ncinematic, fantasy, Middle Eastern\ncinematic, fantasy, ambient\ncinematic, fantasy, anime\ncinematic, film noir, progressive rock\ncinematic, flamenco, Arabic\ncinematic, flamenco, Latin\ncinematic, flamenco, Middle Eastern\ncinematic, flamenco, Persian classical\ncinematic, flamenco, Turkish folk\ncinematic, flamenco, arabesque\ncinematic, flamenco, fado\ncinematic, flamenco, orchestral\ncinematic, folk fusion, orchestral\ncinematic, folk, Chinese traditional\ncinematic, folk, classical\ncinematic, folk, operatic\ncinematic, folk, tango\ncinematic, ghazal, orchestral\ncinematic, ghazal, world fusion\ncinematic, glitch-hop, neo-classical\ncinematic, gospel, electronic\ncinematic, gospel-samba, orchestral\ncinematic, gothic tango, orchestral\ncinematic, gothic, orchestral\ncinematic, guzheng, ambient\ncinematic, guzheng, classical\ncinematic, guzheng, dizi\ncinematic, guzheng, folk\ncinematic, guzheng, orchestral\ncinematic, guzheng, taiko\ncinematic, gypsy jazz, cabaret\ncinematic, gypsy jazz, klezmer\ncinematic, gypsy jazz, operatic\ncinematic, happy hardcore, orchestral\ncinematic, hardstyle, classical\ncinematic, hardstyle, electronic\ncinematic, hardstyle, orchestral\ncinematic, hip-hop, classical\ncinematic, industrial metal, ambient\ncinematic, industrial, Middle Eastern\ncinematic, inspirational, Swahili pop\ncinematic, instrumental, Andean\ncinematic, instrumental, Asian fusion\ncinematic, instrumental, Chinese classical\ncinematic, instrumental, Chinese traditional\ncinematic, instrumental, East Asian\ncinematic, instrumental, East-meets-West\ncinematic, instrumental, Middle Eastern\ncinematic, instrumental, ancient style\ncinematic, instrumental, dizi\ncinematic, instrumental, erhu\ncinematic, instrumental, guzheng\ncinematic, jazz, orchestral\ncinematic, klezmer, baritone\ncinematic, klezmer, cumbia\ncinematic, klezmer, orchestral\ncinematic, klezmer, spoken word\ncinematic, klezmer, theatrical\ncinematic, lo-fi hip hop\ncinematic, lo-fi, Turkish classical\ncinematic, lo-fi, ballad\ncinematic, lullaby, Portuguese folk\ncinematic, mandolin, classical\ncinematic, martial, Turkish folk\ncinematic, martial, epic\ncinematic, melancholic, Arabic classical\ncinematic, melancholic, Arabic folk\ncinematic, melancholic, Arabic fusion\ncinematic, melancholic, C-pop\ncinematic, melancholic, Central Asian\ncinematic, melancholic, Chinese ambient\ncinematic, melancholic, Chinese classical\ncinematic, melancholic, Chinese folk\ncinematic, melancholic, Chinese opera\ncinematic, melancholic, Chinese orchestral\ncinematic, melancholic, Chinese traditional\ncinematic, melancholic, East Asian\ncinematic, melancholic, French chanson\ncinematic, melancholic, French pop\ncinematic, melancholic, Indian classical\ncinematic, melancholic, Japanese ballad\ncinematic, melancholic, Japanese classical\ncinematic, melancholic, Latin-influenced\ncinematic, melancholic, Middle Eastern\ncinematic, melancholic, Middle Eastern classical\ncinematic, melancholic, Middle Eastern folk\ncinematic, melancholic, Persian\ncinematic, melancholic, Persian classical\ncinematic, melancholic, Portuguese folk\ncinematic, melancholic, South Asian film music\ncinematic, melancholic, Spanish classical\ncinematic, melancholic, Turkish\ncinematic, melancholic, Turkish arabesque\ncinematic, melancholic, Turkish art music\ncinematic, melancholic, Turkish classical\ncinematic, melancholic, Turkish folk\ncinematic, melancholic, accordion\ncinematic, melancholic, ancient style\ncinematic, melancholic, art song\ncinematic, melancholic, baroque\ncinematic, melancholic, chanson\ncinematic, melancholic, classical\ncinematic, melancholic, classical fusion\ncinematic, melancholic, duduk\ncinematic, melancholic, flamenco\ncinematic, melancholic, ghazal\ncinematic, melancholic, opera\ncinematic, melancholic, operatic\ncinematic, melancholic, orchestral\ncinematic, melancholic, tango\ncinematic, melancholic, traditional Indonesian\ncinematic, melancholic, waltz\ncinematic, melancholic, world fusion\ncinematic, melancholic, world music\ncinematic, modern classical, world music\ncinematic, mournful, C-pop\ncinematic, music hall, choral\ncinematic, musical theater, whimsical\ncinematic, mystical, C-pop\ncinematic, mystical, Greek folk\ncinematic, mystical, folk\ncinematic, narrative, Chinese ballad\ncinematic, narrative, world fusion\ncinematic, neo-classical, operatic\ncinematic, neo-classical, orchestral\ncinematic, neo-romantic, big band\ncinematic, neoclassical, orchestral\ncinematic, neurofunk, ambient\ncinematic, ney flute, Turkish classical\ncinematic, ney flute, Turkish folk\ncinematic, ney flute, epic\ncinematic, ney flute, folk\ncinematic, ney flute, melodic\ncinematic, ney flute, operatic\ncinematic, ney flute, zither\ncinematic, ney, Greek\ncinematic, ney, Middle Eastern\ncinematic, ney, Turkish classical\ncinematic, ney, Turkish folk\ncinematic, ney, arabesque\ncinematic, ney, cello\ncinematic, ney, electronic\ncinematic, ney, operatic\ncinematic, ney, orchestral\ncinematic, ney, oud\ncinematic, ney, rock\ncinematic, ney, traditional\ncinematic, noise rock, korean ballad\ncinematic, nostalgic, C-pop\ncinematic, operatic, Arabic\ncinematic, operatic, Arabic fusion\ncinematic, operatic, Balkan\ncinematic, operatic, Balkan folk\ncinematic, operatic, Christmas\ncinematic, operatic, French chanson\ncinematic, operatic, Indian classical\ncinematic, operatic, Italian film score\ncinematic, operatic, Japanese\ncinematic, operatic, Latin\ncinematic, operatic, Latin fusion\ncinematic, operatic, MPB\ncinematic, operatic, Middle Eastern\ncinematic, operatic, Persian\ncinematic, operatic, Persian classical\ncinematic, operatic, Punjabi\ncinematic, operatic, Russian romance\ncinematic, operatic, South Asian classical\ncinematic, operatic, Sufi\ncinematic, operatic, Turkish art music\ncinematic, operatic, Turkish classical\ncinematic, operatic, Turkish folk\ncinematic, operatic, ambient\ncinematic, operatic, ancient style\ncinematic, operatic, arabesque\ncinematic, operatic, chanson\ncinematic, operatic, choral\ncinematic, operatic, classical\ncinematic, operatic, epic\ncinematic, operatic, fantasy\ncinematic, operatic, flamenco\ncinematic, operatic, folk\ncinematic, operatic, mambo\ncinematic, operatic, mandolin\ncinematic, operatic, melancholic\ncinematic, operatic, orchestral\ncinematic, operatic, oud\ncinematic, operatic, polka\ncinematic, operatic, sacred\ncinematic, operatic, synthwave\ncinematic, operatic, tango\ncinematic, operatic, theatrical\ncinematic, operatic, traditional\ncinematic, operatic, trot\ncinematic, operatic, world fusion\ncinematic, operatic, world music\ncinematic, orchestral, Anatolian folk\ncinematic, orchestral, Andean\ncinematic, orchestral, Arabic\ncinematic, orchestral, Arabic folk\ncinematic, orchestral, Arabic fusion\ncinematic, orchestral, Arabic opera\ncinematic, orchestral, Arabic pop\ncinematic, orchestral, C-pop\ncinematic, orchestral, Chinese art song\ncinematic, orchestral, Chinese classical\ncinematic, orchestral, Chinese epic\ncinematic, orchestral, Chinese folk\ncinematic, orchestral, Chinese fusion\ncinematic, orchestral, Chinese opera\ncinematic, orchestral, Chinese patriotic\ncinematic, orchestral, Chinese traditional\ncinematic, orchestral, Christmas\ncinematic, orchestral, East Asian\ncinematic, orchestral, East Asian fantasy\ncinematic, orchestral, East Asian fusion\ncinematic, orchestral, French chanson\ncinematic, orchestral, Greek\ncinematic, orchestral, Greek folk\ncinematic, orchestral, Indian classical\ncinematic, orchestral, Indian folk\ncinematic, orchestral, Indian fusion\ncinematic, orchestral, Italian ballad\ncinematic, orchestral, J-RPG\ncinematic, orchestral, JRPG\ncinematic, orchestral, Japanese\ncinematic, orchestral, Japanese operatic\ncinematic, orchestral, Japanese traditional\ncinematic, orchestral, Malayalam\ncinematic, orchestral, Middle Eastern\ncinematic, orchestral, Persian\ncinematic, orchestral, Persian art song\ncinematic, orchestral, Persian classical\ncinematic, orchestral, Persian folk\ncinematic, orchestral, Persian fusion\ncinematic, orchestral, Persian opera\ncinematic, orchestral, Persian spoken word\ncinematic, orchestral, Portuguese vocal\ncinematic, orchestral, Russian bard\ncinematic, orchestral, South Asian folk\ncinematic, orchestral, Tamil classical\ncinematic, orchestral, Turkish\ncinematic, orchestral, Turkish arabesque\ncinematic, orchestral, Turkish art music\ncinematic, orchestral, Turkish classical\ncinematic, orchestral, Turkish folk\ncinematic, orchestral, Turkish fusion\ncinematic, orchestral, Turkish opera\ncinematic, orchestral, Turkish pop\ncinematic, orchestral, accordion\ncinematic, orchestral, ambient\ncinematic, orchestral, ancient style\ncinematic, orchestral, arabesque\ncinematic, orchestral, baritone\ncinematic, orchestral, bossa nova\ncinematic, orchestral, cabaret\ncinematic, orchestral, chanson\ncinematic, orchestral, chiptune\ncinematic, orchestral, choral\ncinematic, orchestral, circus\ncinematic, orchestral, classical\ncinematic, orchestral, cool jazz\ncinematic, orchestral, dizi\ncinematic, orchestral, electronic\ncinematic, orchestral, epic\ncinematic, orchestral, erhu\ncinematic, orchestral, ethereal\ncinematic, orchestral, fado\ncinematic, orchestral, fairytale\ncinematic, orchestral, fantasy\ncinematic, orchestral, flamenco\ncinematic, orchestral, folk\ncinematic, orchestral, fusion\ncinematic, orchestral, guzheng\ncinematic, orchestral, industrial metal\ncinematic, orchestral, klezmer\ncinematic, orchestral, korean classical\ncinematic, orchestral, lo-fi\ncinematic, orchestral, melancholic\ncinematic, orchestral, musical theater\ncinematic, orchestral, operatic\ncinematic, orchestral, patriotic\ncinematic, orchestral, rock\ncinematic, orchestral, rock fusion\ncinematic, orchestral, romantic\ncinematic, orchestral, spiritual\ncinematic, orchestral, spoken word\ncinematic, orchestral, tango\ncinematic, orchestral, traditional\ncinematic, orchestral, traditional Chinese\ncinematic, orchestral, traditional East Asian\ncinematic, orchestral, trap\ncinematic, orchestral, whimsical\ncinematic, orchestral, world fusion\ncinematic, oud, Arabic\ncinematic, oud, Persian opera\ncinematic, oud, Turkish\ncinematic, oud, Turkish classical\ncinematic, oud, arabesque\ncinematic, oud, cello\ncinematic, oud, dramatic\ncinematic, oud, epic\ncinematic, oud, female vocal\ncinematic, oud, operatic\ncinematic, oud, orchestral\ncinematic, patriotic, Indian fusion\ncinematic, patriotic, orchestral\ncinematic, piano, accordion\ncinematic, playful, Latin\ncinematic, playful, orchestral\ncinematic, playful, world fusion\ncinematic, progressive rock, Turkish folk\ncinematic, progressive rock, video game music\ncinematic, psychedelic, classical\ncinematic, qanun, piano\ncinematic, quirky, cartoon\ncinematic, quirky, instrumental\ncinematic, ragtime, oud\ncinematic, ragtime, video game\ncinematic, revolutionary, Indian folk\ncinematic, ritual, world fusion\ncinematic, ritualistic, ambient\ncinematic, romantic, Spanish\ncinematic, romantic, melancholic\ncinematic, sacred, choral\ncinematic, sacred, epic\ncinematic, sacred, orchestral\ncinematic, sacred, traditional\ncinematic, sacred, traditional pop\ncinematic, sacred, world fusion\ncinematic, salsa, Persian traditional\ncinematic, schlager, humppa\ncinematic, sertanejo, pop\ncinematic, soulful, Middle Eastern\ncinematic, soulful, Portuguese\ncinematic, soulful, South Asian classical\ncinematic, soulful, epic\ncinematic, soulful, gospel\ncinematic, spiritual, Anatolian folk\ncinematic, spiritual, Andalusian\ncinematic, spiritual, Arabic\ncinematic, spiritual, Arabic Mawwal\ncinematic, spiritual, Arabic classical\ncinematic, spiritual, Arabic devotional\ncinematic, spiritual, Arabic fusion\ncinematic, spiritual, Arabic orchestral\ncinematic, spiritual, C-pop\ncinematic, spiritual, Chinese ambient\ncinematic, spiritual, Chinese classical\ncinematic, spiritual, Chinese orchestral\ncinematic, spiritual, Chinese traditional\ncinematic, spiritual, Christmas\ncinematic, spiritual, East Asian\ncinematic, spiritual, Indian classical\ncinematic, spiritual, Middle Eastern\ncinematic, spiritual, Persian classical\ncinematic, spiritual, Persian fusion\ncinematic, spiritual, Turkish folk\ncinematic, spiritual, ambient\ncinematic, spiritual, ancient style\ncinematic, spiritual, choral\ncinematic, spiritual, classical\ncinematic, spiritual, devotional\ncinematic, spiritual, electronic\ncinematic, spiritual, guzheng\ncinematic, spiritual, orchestral\ncinematic, spiritual, tribal\ncinematic, spiritual, world fusion\ncinematic, spy theme, ambient pop\ncinematic, spy, quirky\ncinematic, spy-thriller, electronic\ncinematic, swing, orchestral\ncinematic, taiko, Chinese instrumental\ncinematic, taiko, Chinese opera\ncinematic, taiko, East Asian\ncinematic, taiko, Indian classical\ncinematic, taiko, Indian fusion\ncinematic, taiko, Middle Eastern\ncinematic, taiko, ambient\ncinematic, taiko, ancient style\ncinematic, taiko, electronic\ncinematic, taiko, epic\ncinematic, taiko, guzheng\ncinematic, taiko, industrial\ncinematic, taiko, martial\ncinematic, taiko, operatic\ncinematic, taiko, orchestral\ncinematic, taiko, patriotic\ncinematic, taiko, sci-fi\ncinematic, taiko, shakuhachi\ncinematic, taiko, sitar\ncinematic, taiko, traditional East Asian\ncinematic, taiko, video game\ncinematic, taiko, world fusion\ncinematic, tango, folk\ncinematic, tango, operatic\ncinematic, tango, orchestral\ncinematic, theatrical, Japanese pop\ncinematic, theatrical, ambient\ncinematic, theatrical, epic\ncinematic, theatrical, klezmer\ncinematic, theatrical, operatic\ncinematic, theatrical, orchestral\ncinematic, theatrical, tango\ncinematic, torch song, film noir\ncinematic, traditional Chinese, ambient\ncinematic, traditional Chinese, classical\ncinematic, traditional Chinese, orchestral\ncinematic, traditional East Asian\ncinematic, traditional East Asian, ambient\ncinematic, traditional East Asian, epic\ncinematic, traditional East Asian, instrumental\ncinematic, traditional East Asian, orchestral\ncinematic, traditional Indonesian, operatic\ncinematic, traditional Vietnamese, ambient\ncinematic, traditional, orchestral\ncinematic, trap, duduk\ncinematic, tribal, Bollywood\ncinematic, tribal, Middle Eastern\ncinematic, tribal, Māori\ncinematic, tribal, Telugu\ncinematic, tribal, ambient\ncinematic, tribal, electronic\ncinematic, tribal, epic\ncinematic, tribal, instrumental\ncinematic, tribal, lo-fi hip-hop\ncinematic, tribal, orchestral\ncinematic, tribal, world fusion\ncinematic, trip-hop, Chinese orchestral\ncinematic, trip-hop, Turkish folk\ncinematic, trip-hop, operatic\ncinematic, trip-hop, orchestral\ncinematic, video game, East Asian fusion\ncinematic, video game, Middle Eastern\ncinematic, video game, jazzy synth\ncinematic, video game, whimsical\ncinematic, vintage, operatic\ncinematic, violin, Indian classical\ncinematic, whimsical, European\ncinematic, whimsical, flamenco\ncinematic, whimsical, instrumental\ncinematic, whimsical, orchestral\ncinematic, whimsical, video game\ncinematic, world fusion, ambient\ncinematic, world fusion, classical\ncinematic, world fusion, electronic\ncinematic, world fusion, epic\ncinematic, world fusion, orchestral\ncinematic, world music, emotional\ncinematic, world music, epic\ncinematic, world music, neoclassical\ncinematic, world music, operatic\ncinematic, world music, uplifting\ncinematic, wuxia, ambient\ncircus march\ncircus metal\ncircus music\ncircus polka\ncircus pop\ncircus punk\ncircus rock\ncircus waltz\ncircus-punk\ncity pop\ncity pop AOR\ncity pop R&B\ncity pop acid jazz\ncity pop blues-rock\ncity pop bossa nova\ncity pop chiptune\ncity pop disco-funk\ncity pop dream pop\ncity pop exotica\ncity pop funk\ncity pop funk J-pop\ncity pop funk R&B\ncity pop funk acid jazz\ncity pop funk big band\ncity pop funk disco\ncity pop funk fusion\ncity pop funk hip-hop\ncity pop funk indie\ncity pop funk indie rock\ncity pop funk jazz fusion\ncity pop funk lo-fi hip-hop\ncity pop funk lounge\ncity pop funk neo-soul\ncity pop funk nu-disco\ncity pop funk progressive rock\ncity pop funk rock\ncity pop funk soul\ncity pop funk video game\ncity pop funk-pop\ncity pop funk-pop lo-fi\ncity pop funk-pop neo-soul\ncity pop funk-rock\ncity pop fusion jazz\ncity pop future bass\ncity pop future funk\ncity pop future funk nu-disco\ncity pop hip-hop\ncity pop hip-hop chiptune\ncity pop indie pop\ncity pop indie rock\ncity pop indie-pop\ncity pop jazz\ncity pop jazz bossa nova\ncity pop jazz fusion\ncity pop jazz fusion anime rock\ncity pop jazz lo-fi\ncity pop jazz lounge\ncity pop jazz-funk\ncity pop jazz-funk chiptune\ncity pop jazz-fusion\ncity pop jazz-fusion chiptune\ncity pop jazz-fusion lo-fi\ncity pop jazz-fusion lo-fi hip-hop\ncity pop jazz-pop\ncity pop lo-fi\ncity pop lo-fi acid jazz\ncity pop lo-fi bedroom pop\ncity pop lo-fi bossa nova\ncity pop lo-fi hip hop\ncity pop lo-fi hip-hop\ncity pop lo-fi synth-pop\ncity pop lounge\ncity pop lounge bossa nova\ncity pop lounge exotica\ncity pop lounge jazz\ncity pop lounge-pop\ncity pop neo-soul\ncity pop neo-soul R&B\ncity pop neo-soul chiptune\ncity pop neo-soul funk\ncity pop neo-soul jazz fusion\ncity pop neo-soul lo-fi hip-hop\ncity pop neo-soul lounge jazz\ncity pop nu-disco\ncity pop nu-disco chiptune\ncity pop nu-disco funk\ncity pop nu-disco funky pop\ncity pop nu-disco lo-fi\ncity pop nu-disco synth-funk\ncity pop nu-disco synth-pop\ncity pop orchestral\ncity pop reggae\ncity pop reggae-ska\ncity pop salsa\ncity pop samba\ncity pop smooth jazz\ncity pop soul\ncity pop synth-funk\ncity pop synth-pop\ncity pop synth-rock\ncity pop synthwave\ncity pop tango\ncity pop tropical house\ncity pop trot\ncity pop vaporwave\ncity pop vaporwave hip-hop\ncity pop vaporwave synth-pop\ncity pop, 16-bit video game music\ncity pop, 80s anime, Indonesian pop\ncity pop, 80s rock\ncity pop, 90s Japanese RPG, synthwave\ncity pop, 90s K-pop\ncity pop, 90s R&B\ncity pop, 90s R&B, Chinese pop\ncity pop, 90s R&B, K-ballad\ncity pop, 90s R&B, lo-fi\ncity pop, 90s R&B, pop\ncity pop, 90s video game music\ncity pop, 90s video game, synth funk\ncity pop, AOR\ncity pop, AOR, J-rock\ncity pop, AOR, Japanese rock\ncity pop, AOR, jazz-fusion\ncity pop, AOR, pop-rock\ncity pop, AOR, soft rock\ncity pop, AOR, soul\ncity pop, C-pop, R&B\ncity pop, C-pop, anime\ncity pop, C-pop, anime soundtrack\ncity pop, C-pop, anime theme\ncity pop, C-pop, lo-fi\ncity pop, C-pop, upbeat\ncity pop, C-pop, video game music\ncity pop, French house\ncity pop, J-Pop, R&B\ncity pop, J-funk\ncity pop, J-pop\ncity pop, J-pop, 90s\ncity pop, J-pop, C-pop\ncity pop, J-pop, J-rock\ncity pop, J-pop, Latin\ncity pop, J-pop, R&B\ncity pop, J-pop, ambient\ncity pop, J-pop, anime\ncity pop, J-pop, anime soundtrack\ncity pop, J-pop, chiptune\ncity pop, J-pop, cinematic\ncity pop, J-pop, funk pop\ncity pop, J-pop, hip-hop\ncity pop, J-pop, latin\ncity pop, J-pop, light funk\ncity pop, J-pop, reggae\ncity pop, J-pop, synth-funk\ncity pop, J-pop, synth-pop\ncity pop, J-pop, video game music\ncity pop, J-rock\ncity pop, Japanese R&B\ncity pop, Japanese RPG, synthwave\ncity pop, Japanese funk\ncity pop, Japanese rock\ncity pop, K-R&B, synth-pop\ncity pop, K-pop\ncity pop, K-pop ballad\ncity pop, K-pop, funk\ncity pop, K-pop, future bass\ncity pop, K-pop, lounge\ncity pop, K-pop, retro-pop\ncity pop, Kayōkyoku, theatrical\ncity pop, Latin disco\ncity pop, Latin funk\ncity pop, Latin fusion\ncity pop, Latin jazz\ncity pop, Latin jazz fusion\ncity pop, Latin jazz fusion, J-pop\ncity pop, Latin jazz, J-pop\ncity pop, Latin jazz, fusion\ncity pop, Latin pop\ncity pop, Latin pop, 80s Indonesian pop\ncity pop, Latin pop, Indonesian pop\ncity pop, Latin pop-rock\ncity pop, Latin, jazz fusion\ncity pop, Latin, reggae\ncity pop, MPB, funk\ncity pop, Mandopop, Latin\ncity pop, Mandopop, R&B\ncity pop, Mandopop, anime soundtrack\ncity pop, Mandopop, anime theme\ncity pop, Mandopop, light R&B\ncity pop, Mandopop, retro pop\ncity pop, R&B\ncity pop, R&B, C-pop\ncity pop, R&B, K-pop\ncity pop, R&B, Mandopop\ncity pop, R&B, Thai Pop\ncity pop, R&B, Thai pop\ncity pop, R&B, anime\ncity pop, R&B, dream pop\ncity pop, R&B, jazz\ncity pop, R&B, jazz fusion\ncity pop, R&B, jazzy pop\ncity pop, R&B, new jack swing\ncity pop, R&B, pop\ncity pop, Shibuya-kei\ncity pop, Shibuya-kei, J-pop\ncity pop, Shibuya-kei, funk\ncity pop, Shibuya-kei, synth pop\ncity pop, acid jazz\ncity pop, acid jazz, J-pop\ncity pop, adult contemporary\ncity pop, anime\ncity pop, anime soundtrack\ncity pop, anime soundtrack, Indonesian pop\ncity pop, anime soundtrack, Thai pop\ncity pop, anime soundtrack, lo-fi\ncity pop, anime soundtrack, synthwave\ncity pop, anime theme\ncity pop, anime theme, 80s synth\ncity pop, anime theme, C-pop\ncity pop, anime theme, J-pop\ncity pop, anime theme, Thai pop\ncity pop, anime theme, funk\ncity pop, anime, C-pop\ncity pop, anime, Indonesian pop\ncity pop, anime, Thai pop\ncity pop, anime, instrumental\ncity pop, anime, pop-rock\ncity pop, arena rock\ncity pop, big band jazz\ncity pop, big band, J-pop\ncity pop, big band, anime\ncity pop, big band, soul\ncity pop, blues-rock\ncity pop, boogie\ncity pop, boom-bap, jazz hop\ncity pop, bossa nova\ncity pop, bossa nova, C-pop\ncity pop, bossa nova, J-pop\ncity pop, bossa nova, Mandopop\ncity pop, bossa nova, cinematic\ncity pop, bossa nova, jazzy pop\ncity pop, bossa nova, pop\ncity pop, bossa nova, pop-rock\ncity pop, bossa nova, retro-pop\ncity pop, chiptune\ncity pop, chiptune, C-pop\ncity pop, chiptune, Indonesian pop\ncity pop, chiptune, J-pop\ncity pop, chiptune, Mandopop\ncity pop, chiptune, funk\ncity pop, chiptune, jazz\ncity pop, chiptune, kawaii\ncity pop, chiptune, lo-fi\ncity pop, chiptune, playful\ncity pop, chiptune, retro\ncity pop, chiptune, synth funk\ncity pop, chiptune, synth-pop\ncity pop, cinematic\ncity pop, cinematic orchestral\ncity pop, cinematic, big band\ncity pop, cinematic, funk fusion\ncity pop, cinematic, gospel\ncity pop, dangdut koplo\ncity pop, dangdut koplo, 80s Indonesian pop\ncity pop, disco, C-pop\ncity pop, disco, Indonesian pop\ncity pop, disco, J-pop\ncity pop, disco, Kayōkyoku\ncity pop, disco, Mandopop\ncity pop, disco, Sundanese fusion\ncity pop, disco, Vietnamese pop\ncity pop, disco, children's\ncity pop, disco, funk\ncity pop, disco-funk\ncity pop, disco-funk, novelty\ncity pop, doo-wop\ncity pop, dream pop\ncity pop, dream pop, C-pop\ncity pop, dream pop, rock\ncity pop, dream pop, synth-pop\ncity pop, easy-listening\ncity pop, easy-listening, Korean ballad\ncity pop, eurobeat, 90s dance-pop\ncity pop, eurobeat, J-pop\ncity pop, exotica, Indonesian pop\ncity pop, funk\ncity pop, funk fusion, progressive rock\ncity pop, funk fusion, smooth jazz\ncity pop, funk fusion, video game music\ncity pop, funk fusion, video game soundtrack\ncity pop, funk rock\ncity pop, funk rock, chiptune\ncity pop, funk, 80s\ncity pop, funk, 80s anime\ncity pop, funk, C-pop\ncity pop, funk, Cantopop\ncity pop, funk, Indonesian pop\ncity pop, funk, J-Pop\ncity pop, funk, J-pop\ncity pop, funk, J-rock\ncity pop, funk, Japanese\ncity pop, funk, K-pop\ncity pop, funk, Mandopop\ncity pop, funk, Shibuya-kei\ncity pop, funk, T-Pop\ncity pop, funk, Thai pop\ncity pop, funk, children's pop\ncity pop, funk, chiptune\ncity pop, funk, dance-pop\ncity pop, funk, disco\ncity pop, funk, fusion\ncity pop, funk, indie pop\ncity pop, funk, jazz\ncity pop, funk, jazz fusion\ncity pop, funk, lo-fi\ncity pop, funk, neo-soul\ncity pop, funk, new jack swing\ncity pop, funk, nu-disco\ncity pop, funk, orchestral pop\ncity pop, funk, pop\ncity pop, funk, pop-rock\ncity pop, funk, retro disco\ncity pop, funk, retro pop\ncity pop, funk, retro-pop\ncity pop, funk, rock\ncity pop, funk, synth\ncity pop, funk, synth pop\ncity pop, funk, synth-pop\ncity pop, funk, synthwave\ncity pop, funk, vaporwave\ncity pop, funk, video game music\ncity pop, funk-pop\ncity pop, funk-pop, cinematic\ncity pop, funk-pop, lo-fi\ncity pop, funk-rock\ncity pop, funk-rock, hard rock\ncity pop, funk-rock, synth-pop\ncity pop, fusion jazz\ncity pop, fusion jazz, synth funk\ncity pop, fusion jazz, synth pop\ncity pop, fusion jazz, synth-funk\ncity pop, fusion jazz, video game music\ncity pop, future bass\ncity pop, future bass, kawaii\ncity pop, future funk\ncity pop, future funk, C-pop\ncity pop, future funk, J-pop\ncity pop, future funk, dance-pop\ncity pop, future funk, synth-pop\ncity pop, house, J-pop\ncity pop, indie pop, C-pop\ncity pop, indie pop, J-pop\ncity pop, indie pop, Mandopop\ncity pop, indie pop, jazz\ncity pop, indie pop, lo-fi\ncity pop, indie rock\ncity pop, indie rock, C-pop\ncity pop, indie rock, Mandopop\ncity pop, j-pop, R&B\ncity pop, j-pop, chiptune\ncity pop, j-pop, jazz\ncity pop, j-pop, jazz fusion\ncity pop, j-pop, lo-fi\ncity pop, j-pop, r&b\ncity pop, j-pop, reggae\ncity pop, j-pop, rock\ncity pop, j-pop, video game music\ncity pop, jazz fusion\ncity pop, jazz fusion, Indonesian pop\ncity pop, jazz fusion, J-pop\ncity pop, jazz fusion, Kayōkyoku\ncity pop, jazz fusion, Mandopop\ncity pop, jazz fusion, Shibuya-kei\ncity pop, jazz fusion, anime soundtrack\ncity pop, jazz fusion, chiptune\ncity pop, jazz fusion, cinematic\ncity pop, jazz fusion, lounge\ncity pop, jazz fusion, pop-rock\ncity pop, jazz fusion, video game music\ncity pop, jazz, C-pop\ncity pop, jazz, Indonesian pop\ncity pop, jazz, J-pop\ncity pop, jazz, K-ballad\ncity pop, jazz, K-pop\ncity pop, jazz, Mandopop\ncity pop, jazz, ballad\ncity pop, jazz, melancholic\ncity pop, jazz-funk\ncity pop, jazz-funk, Filipino Christmas\ncity pop, jazz-funk, Indonesian pop\ncity pop, jazz-funk, J-pop\ncity pop, jazz-funk, Mandopop\ncity pop, jazz-funk, Thai pop\ncity pop, jazz-funk, flamenco\ncity pop, jazz-funk, indie pop\ncity pop, jazz-funk, kayōkyoku\ncity pop, jazz-fusion\ncity pop, jazz-fusion, C-pop\ncity pop, jazz-fusion, Indonesian pop\ncity pop, jazz-fusion, K-ballad\ncity pop, jazz-fusion, Mandopop\ncity pop, jazz-fusion, lo-fi\ncity pop, jazz-fusion, pop-rock\ncity pop, jazz-pop, K-pop\ncity pop, jazz-pop, Mandopop\ncity pop, jazzy K-pop\ncity pop, jazzy Thai pop\ncity pop, jazzy pop, anime\ncity pop, jazzy pop-rock\ncity pop, jazzy synth, chiptune\ncity pop, jungle, breakbeat\ncity pop, kawaii future bass, C-pop\ncity pop, kawaii future bass, lo-fi\ncity pop, kawaii, C-pop\ncity pop, kayōkyoku, cinematic\ncity pop, latin jazz\ncity pop, latin salsa\ncity pop, light funk, C-pop\ncity pop, light funk, Mandopop\ncity pop, light funk, Thai pop\ncity pop, light funk, pop\ncity pop, light jazz\ncity pop, light jazz, C-pop\ncity pop, light jazz, Thai pop\ncity pop, lo-fi\ncity pop, lo-fi bedroom pop\ncity pop, lo-fi hip hop\ncity pop, lo-fi hip hop, C-pop\ncity pop, lo-fi hip hop, J-pop\ncity pop, lo-fi hip hop, K-pop\ncity pop, lo-fi hip hop, Mandopop\ncity pop, lo-fi hip hop, synth-pop\ncity pop, lo-fi hip-hop\ncity pop, lo-fi hip-hop, C-pop\ncity pop, lo-fi hip-hop, J-pop\ncity pop, lo-fi hip-hop, K-pop\ncity pop, lo-fi hip-hop, Thai pop\ncity pop, lo-fi hip-hop, synth-pop\ncity pop, lo-fi synth-pop\ncity pop, lo-fi, C-pop\ncity pop, lo-fi, J-pop\ncity pop, lo-fi, Mandopop\ncity pop, lo-fi, R&B\ncity pop, lo-fi, jazzy\ncity pop, lo-fi, synth-pop\ncity pop, lo-fi, vaporwave\ncity pop, lounge\ncity pop, lounge jazz\ncity pop, lounge jazz, Indonesian pop\ncity pop, lounge jazz, J-pop\ncity pop, lounge jazz, Mandopop\ncity pop, lounge jazz, video game music\ncity pop, lounge pop, jazz\ncity pop, lounge, Indonesian pop\ncity pop, lounge, J-pop\ncity pop, lounge, Thai pop\ncity pop, lounge, ballad\ncity pop, lounge, jazz pop\ncity pop, lounge-pop, video game music\ncity pop, math rock, chiptune\ncity pop, math rock, jazz fusion\ncity pop, modern R&B\ncity pop, modern funk\ncity pop, neo-soul\ncity pop, neo-soul, C-pop\ncity pop, neo-soul, Filipino pop\ncity pop, neo-soul, J-pop\ncity pop, neo-soul, K-pop\ncity pop, neo-soul, Mandopop\ncity pop, neo-soul, R&B\ncity pop, neo-soul, Thai pop\ncity pop, neo-soul, ambient\ncity pop, neo-soul, chiptune\ncity pop, neo-soul, funk\ncity pop, neo-soul, indie pop\ncity pop, neo-soul, jazz\ncity pop, neo-soul, jazz fusion\ncity pop, neo-soul, jazz pop\ncity pop, neo-soul, jazzy pop\ncity pop, neo-soul, lo-fi\ncity pop, neo-soul, lo-fi hip-hop\ncity pop, neo-soul, modern R&B\ncity pop, neo-soul, pop-rock\ncity pop, neo-soul, psychedelic pop\ncity pop, neo-soul, synth pop\ncity pop, new age\ncity pop, new age, dream pop\ncity pop, new jack swing\ncity pop, new jack swing, 90s R&B\ncity pop, new jack swing, C-pop\ncity pop, new jack swing, Filipino pop\ncity pop, new jack swing, J-pop\ncity pop, new jack swing, K-pop\ncity pop, new jack swing, anime\ncity pop, new jack swing, chiptune\ncity pop, new jack swing, hip-hop\ncity pop, new jack swing, hyperpop\ncity pop, new jack swing, lo-fi\ncity pop, new jack swing, modern R&B\ncity pop, new jack swing, pop\ncity pop, new jack swing, retro-futuristic\ncity pop, new jack swing, synthwave\ncity pop, new jack swing, video game music\ncity pop, new wave, synth-pop\ncity pop, noir, kayōkyoku\ncity pop, nu-disco\ncity pop, nu-disco, C-pop\ncity pop, nu-disco, J-pop\ncity pop, nu-disco, K-pop\ncity pop, nu-disco, funk\ncity pop, nu-disco, pop\ncity pop, nu-disco, retro-funk\ncity pop, nu-disco, synth-funk\ncity pop, nu-disco, synth-pop\ncity pop, nu-disco, vaporwave\ncity pop, nu-disco, video game music\ncity pop, orchestral, funk-pop\ncity pop, orchestral, jazz-fusion\ncity pop, pop Melayu\ncity pop, pop dangdut\ncity pop, pop keroncong\ncity pop, pop-rock\ncity pop, pop-rock, Indonesian pop\ncity pop, pop-rock, Mandopop\ncity pop, pop-rock, jazz\ncity pop, psychedelic rock, Japanese rock\ncity pop, reggae, J-pop\ncity pop, reggae, dub\ncity pop, retro Filipino pop, synth-pop\ncity pop, retro funk\ncity pop, retro funk, C-pop\ncity pop, retro funk, Mandopop\ncity pop, retro rock, soul\ncity pop, retro video game\ncity pop, retro-funk\ncity pop, retro-funk, C-pop\ncity pop, retro-funk, K-pop\ncity pop, retro-funk, cinematic\ncity pop, retro-funk, new jack swing\ncity pop, retro-funk, pop-rap\ncity pop, rock\ncity pop, rock, Japanese\ncity pop, salsa\ncity pop, samba-rock\ncity pop, ska, J-pop\ncity pop, smooth R&B\ncity pop, smooth jazz\ncity pop, smooth jazz, 80s\ncity pop, smooth jazz, 90s video game\ncity pop, smooth jazz, Brazilian pop-rock\ncity pop, smooth jazz, C-pop\ncity pop, smooth jazz, Filipino pop\ncity pop, smooth jazz, J-pop\ncity pop, smooth jazz, Japanese ballad\ncity pop, smooth jazz, Mandopop\ncity pop, smooth jazz, Thai pop\ncity pop, smooth jazz, Vietnamese pop\ncity pop, smooth jazz, bilingual pop\ncity pop, smooth jazz, cinematic\ncity pop, smooth jazz, funk\ncity pop, smooth jazz, fusion\ncity pop, smooth jazz, global pop\ncity pop, smooth jazz, instrumental\ncity pop, smooth jazz, lounge\ncity pop, smooth jazz, pop-funk\ncity pop, smooth jazz, romantic pop\ncity pop, smooth jazz, synth funk\ncity pop, smooth jazz, synth pop\ncity pop, smooth jazz, synth-pop\ncity pop, smooth jazz, synthwave\ncity pop, smooth jazz, video game music\ncity pop, soft rock\ncity pop, soft rock, Filipino Christmas\ncity pop, soul\ncity pop, soul, pop-rock\ncity pop, soul, rock\ncity pop, soulful R&B, cinematic\ncity pop, surf rock\ncity pop, surf rock, J-pop\ncity pop, surf rock, indie pop\ncity pop, surf rock, pop-rock\ncity pop, synth-funk\ncity pop, synth-funk, 80s\ncity pop, synth-funk, 80s Japanese\ncity pop, synth-funk, 90s video game\ncity pop, synth-funk, C-pop\ncity pop, synth-funk, Indonesian pop\ncity pop, synth-funk, J-pop\ncity pop, synth-funk, Japanese\ncity pop, synth-funk, Mandopop\ncity pop, synth-funk, R&B\ncity pop, synth-funk, a cappella\ncity pop, synth-funk, anime\ncity pop, synth-funk, bilingual\ncity pop, synth-funk, chiptune\ncity pop, synth-funk, disco\ncity pop, synth-funk, funk\ncity pop, synth-funk, hip-hop\ncity pop, synth-funk, jazz fusion\ncity pop, synth-funk, lo-fi\ncity pop, synth-funk, new jack swing\ncity pop, synth-funk, retro\ncity pop, synth-funk, retro-futuristic\ncity pop, synth-funk, retro-pop\ncity pop, synth-funk, video game music\ncity pop, synth-funk, video game soundtrack\ncity pop, synth-pop\ncity pop, synth-pop, 80s\ncity pop, synth-pop, C-pop\ncity pop, synth-pop, Christmas\ncity pop, synth-pop, Indonesian pop\ncity pop, synth-pop, J-pop\ncity pop, synth-pop, K-pop\ncity pop, synth-pop, Mandopop\ncity pop, synth-pop, R&B\ncity pop, synth-pop, Thai pop\ncity pop, synth-pop, Vietnamese pop\ncity pop, synth-pop, anime\ncity pop, synth-pop, anime soundtrack\ncity pop, synth-pop, anime theme\ncity pop, synth-pop, bilingual pop\ncity pop, synth-pop, chiptune\ncity pop, synth-pop, cinematic\ncity pop, synth-pop, early K-pop\ncity pop, synth-pop, eurobeat\ncity pop, synth-pop, funk\ncity pop, synth-pop, hip-hop\ncity pop, synth-pop, jazz fusion\ncity pop, synth-pop, lo-fi\ncity pop, synth-pop, new jack swing\ncity pop, synth-pop, orchestral\ncity pop, synth-pop, pop ballad\ncity pop, synth-pop, retro pop\ncity pop, synth-pop, retro-funk\ncity pop, synth-pop, retro-pop\ncity pop, synth-pop, smooth jazz\ncity pop, synth-pop, synth-funk\ncity pop, synth-pop, theatrical\ncity pop, synth-pop, traditional East Asian\ncity pop, synth-pop, tropical\ncity pop, synth-pop, vaporwave\ncity pop, synth-pop, video game music\ncity pop, synth-pop, worldbeat\ncity pop, synth-rock\ncity pop, synthwave\ncity pop, synthwave, Japanese video game\ncity pop, synthwave, funk\ncity pop, synthwave, synth-pop\ncity pop, synthwave, video game music\ncity pop, synthwave, video game soundtrack\ncity pop, trap\ncity pop, tropical pop, Latin\ncity pop, tropical, J-pop\ncity pop, tropical, V-Pop\ncity pop, trot\ncity pop, trot, retro-pop\ncity pop, vaporwave\ncity pop, vaporwave, J-pop\ncity pop, vaporwave, R&B\ncity pop, vaporwave, funk fusion\ncity pop, vaporwave, hyperpop\ncity pop, vaporwave, lo-fi\ncity pop, vaporwave, lo-fi hip-hop\ncity pop, vaporwave, new jack swing\ncity pop, vaporwave, synth-pop\ncity pop, video game music\ncity pop, video game music, 90s dance-pop\ncity pop, video game music, C-pop\ncity pop, video game music, Japanese\ncity pop, video game music, children's\ncity pop, video game music, children's music\ncity pop, video game music, electronic\ncity pop, video game music, funk\ncity pop, video game music, jazz fusion\ncity pop, video game music, jazzy\ncity pop, video game music, lounge jazz\ncity pop, video game music, synth funk\ncity pop, video game music, synthwave\ncity pop, video game soundtrack\ncity pop, video game soundtrack, cinematic\ncity pop, video game soundtrack, funk\ncity pop, worldbeat, video game music\ncity-pop\ncity-pop K-pop\ncity-pop R&B\ncity-pop R&B neo-soul\ncity-pop chiptune\ncity-pop chiptune synth-pop\ncity-pop funk\ncity-pop funk-pop\ncity-pop future bass\ncity-pop future bass lo-fi\ncity-pop future funk\ncity-pop hip-hop\ncity-pop indie pop\ncity-pop indie rock\ncity-pop jazz\ncity-pop jazz fusion\ncity-pop lo-fi\ncity-pop lo-fi hip hop\ncity-pop lo-fi hip-hop\ncity-pop lounge\ncity-pop lounge jazz\ncity-pop neo-soul\ncity-pop nu-disco\ncity-pop nu-disco lo-fi\ncity-pop nu-disco synth-pop\ncity-pop rock\ncity-pop soft rock\ncity-pop soul\ncity-pop, J-pop, Mandopop\ncity-pop, J-rock\ncity-pop, J-rock, rap\ncity-pop, J-rock, synthwave\ncity-pop, K-R&B, lo-fi\ncity-pop, K-pop, EDM\ncity-pop, Mandopop, R&B\ncity-pop, R&B, C-pop\ncity-pop, R&B, Mandopop\ncity-pop, R&B, jazz\ncity-pop, Shibuya-kei, jazz\ncity-pop, Vocaloid\ncity-pop, breakcore, J-pop\ncity-pop, breakcore, gabber\ncity-pop, chiptune\ncity-pop, chiptune, electronic\ncity-pop, chiptune, lo-fi\ncity-pop, dreamy, lo-fi\ncity-pop, hard rock\ncity-pop, hard rock, psychedelic rock\ncity-pop, light hip-hop, C-pop\ncity-pop, light jazz, Japanese pop\ncity-pop, lounge-pop, video game music\ncity-pop, neo-soul, K-pop\ncity-pop, neo-soul, R&B\ncity-pop, neo-soul, jazzy R&B\ncity-pop, neo-soul, lo-fi\ncity-pop, pop-punk, hip-hop\ncity-pop, pop-punk, lo-fi\ncity-pop, pop-rock\ncity-pop, pop-rock, hip-hop\ncity-pop, pop-rock, rap\ncity-pop, retro-funk, new jack swing\ncity-pop, synth-pop, C-pop\ncity-pop, synth-pop, Mandopop\ncity-pop, synth-pop, R&B\ncity-pop, synth-pop, chill R&B\ncity-pop, synth-pop, chiptune\ncity-pop, synth-pop, video game music\ncity-pop, video game music, quirky pop\ncity-pop, video game, synth pop\nclarinet solo\nclassic R&B\nclassic ballad\nclassic bolero\nclassic country\nclassic disco\nclassic electro\nclassic funk\nclassic funk soul\nclassic heavy metal\nclassic hip hop\nclassic hip-hop\nclassic house\nclassic house disco\nclassic house disco-funk\nclassic house reggae dancehall\nclassic house world pop\nclassic house, disco-funk\nclassic house, freestyle\nclassic house, soulful disco\nclassic house-pop\nclassic jazz\nclassic mambo\nclassic pop\nclassic pop, Southeast Asian pop\nclassic pop-rock\nclassic rave\nclassic reggae\nclassic rock\nclassic rock AOR\nclassic rock Latin\nclassic rock americana\nclassic rock and roll\nclassic rock ballad\nclassic rock blues\nclassic rock blues americana\nclassic rock blues southern rock\nclassic rock blues-rock\nclassic rock country americana\nclassic rock doo-wop\nclassic rock en español\nclassic rock funk\nclassic rock funk rock\nclassic rock funk soul\nclassic rock garage rock\nclassic rock glam rock\nclassic rock gospel\nclassic rock gospel soul\nclassic rock mandopop\nclassic rock opera\nclassic rock power pop\nclassic rock power-pop\nclassic rock psychedelic\nclassic rock psychedelic rock\nclassic rock punk\nclassic rock rockabilly\nclassic rock soul\nclassic rock spaghetti western\nclassic rock world music\nclassic rock, Latin rock\nclassic rock, R&B, boogie-woogie\nclassic rock, R&B, doo-wop\nclassic rock, R&B, soul\nclassic rock, doo-wop\nclassic rock, doo-wop, blues\nclassic rock, drum and bass, happy hardcore\nclassic rock, funk soul\nclassic rock, gospel, blues\nclassic rock, hard rock\nclassic rock, pop-rock\nclassic rock, pop-rock, funk-rock\nclassic rock, pop-rock, southern rock\nclassic rock, punk rock, cinematic\nclassic rock, rockabilly\nclassic rock, surf rock\nclassic rock, surf rock, chanson\nclassic salsa\nclassic soul\nclassic soul funk\nclassic soul gospel\nclassic tango\nclassic techno\nclassic trance\nclassical\nclassical Arabic\nclassical Arabic music\nclassical C-pop\nclassical Chinese\nclassical Christian\nclassical Christmas\nclassical French\nclassical German Lied\nclassical Indian\nclassical Indian ghazal\nclassical Korean art song\nclassical Lied\nclassical Persian\nclassical Russian romance\nclassical South Asian\nclassical Turkish music\nclassical a cappella\nclassical adagio\nclassical ambient\nclassical anthem\nclassical art song\nclassical art song tango\nclassical art song, Greek folk\nclassical art song, Latin bolero\nclassical art song, Latin jazz-rock fusion\nclassical art song, Latin salsa\nclassical art song, Latin, salsa\nclassical art song, big band\nclassical art song, big band mambo\nclassical art song, musical theater\nclassical art song, ragtime, operatic\nclassical avant-garde\nclassical ballad\nclassical ballad, Latin salsa\nclassical baroque\nclassical bolero\nclassical brass\nclassical cabaret\nclassical caprice\nclassical carol\nclassical cartoon\nclassical ceremonial\nclassical chamber\nclassical chamber music\nclassical chanson\nclassical chant\nclassical children's\nclassical chiptune\nclassical choir\nclassical choral\nclassical choral pop-rock\nclassical choral, chiptune\nclassical choral, chiptune, orchestral\nclassical choral, gospel-pop\nclassical choral, synth-pop\nclassical chorale\nclassical church\nclassical copla\nclassical crooner\nclassical crossover\nclassical crossover chiptune\nclassical crossover funk-rock\nclassical crossover progressive rock\nclassical crossover rock\nclassical crossover salsa\nclassical crossover tango\nclassical crossover, Latin folk\nclassical crossover, Latin jazz\nclassical crossover, Latin pop\nclassical crossover, Persian music\nclassical crossover, big band jazz\nclassical crossover, downtempo trip-hop\nclassical crossover, musical theater, Arabic music\nclassical devotional\nclassical education\nclassical educational\nclassical electronic\nclassical electronica\nclassical etude\nclassical fairytale\nclassical fanfare\nclassical fantasy\nclassical fiddle\nclassical fingerstyle\nclassical flamenco\nclassical flute\nclassical flute, European folk\nclassical folk\nclassical folk fusion\nclassical fusion\nclassical fusion rock\nclassical fusion, Japanese speed metal\nclassical gospel\nclassical guitar\nclassical guitar ballad\nclassical guitar, French chanson, cinematic\nclassical guitar, Korean trot, flamenco\nclassical guitar, Latin folk, sacred music\nclassical guitar, Latin, choral\nclassical guitar, Latin, flute\nclassical guitar, Spanish, piano\nclassical guitar, baritone, Russian romance\nclassical guitar, bluegrass, Celtic folk\nclassical guitar, cello, flamenco\nclassical guitar, chanson, epic\nclassical guitar, chanson, spiritual\nclassical guitar, cinematic, Portuguese folk\nclassical guitar, cinematic, tango\nclassical guitar, emotional rock, cinematic\nclassical guitar, flamenco, ambient\nclassical guitar, flamenco, ethereal\nclassical guitar, flamenco, pop\nclassical guitar, flute, Latin folk\nclassical guitar, flute, Spanish-influenced\nclassical guitar, flute, ambient\nclassical guitar, flute, chamber music\nclassical guitar, mambo, Latin jazz\nclassical guitar, melancholic, baritone\nclassical guitar, melancholic, theatrical\nclassical guitar, operatic folk, melancholic\nclassical guitar, operatic pop, dramatic\nclassical guitar, operatic, Fado\nclassical guitar, operatic, Latin\nclassical guitar, operatic, Latin folk\nclassical guitar, operatic, Russian folk\nclassical guitar, operatic, Russian romance\nclassical guitar, operatic, Spanish\nclassical guitar, operatic, ambient\nclassical guitar, operatic, bossa nova\nclassical guitar, operatic, cinematic\nclassical guitar, operatic, dramatic\nclassical guitar, operatic, flamenco\nclassical guitar, operatic, melancholic\nclassical guitar, romantic, ambient\nclassical guitar, theatrical, French\nclassical guitar, theatrical, melancholic\nclassical guitar, transverse flute, Latin\nclassical harp\nclassical hip hop\nclassical hip-hop\nclassical hymn\nclassical hymnal\nclassical jazz\nclassical jazz ragtime\nclassical lament\nclassical lullaby\nclassical lullaby jazz\nclassical melancholy\nclassical metal\nclassical modern\nclassical opera\nclassical oratorio\nclassical orchestral\nclassical organ\nclassical pastoral\nclassical piano\nclassical piano, Arabic vocal, melancholic\nclassical piano, Klezmer, pop-rock\nclassical piano, Russian chanson, hard rock\nclassical piano, boogie-woogie, Latin\nclassical piano, folk rock\nclassical piano, pop-rock, musical theater\nclassical piano, salsa, big band\nclassical piano, spoken word, Spanish folk\nclassical pop\nclassical ragtime\nclassical ragtime Brazilian\nclassical rap\nclassical reggaeton\nclassical rock\nclassical romance\nclassical romantic\nclassical romanticism\nclassical romanticism cabaret\nclassical romanticism fado\nclassical romanticism ragtime\nclassical sacred\nclassical scherzo\nclassical soul\nclassical storytelling\nclassical swing\nclassical tango\nclassical taqsim\nclassical theatrical\nclassical trap\nclassical virtuosity\nclassical virtuoso\nclassical vocal\nclassical waltz\nclassical wind ensemble\nclassical world music\nclassical worship\nclassical, Azerbaijani romance\nclassical, Brazilian folk\nclassical, Christmas, hymnal\nclassical, Christmas, operatic\nclassical, Christmas, sacred\nclassical, East Asian\nclassical, East Asian, solo piano\nclassical, J-rock, progressive rock\nclassical, Latin American folk, choral\nclassical, Middle Eastern, Turkish folk\nclassical, Spanish ballad, theatrical\nclassical, Spanish, choral\nclassical, Turkish folk, cinematic\nclassical, ambient, choral\nclassical, ambient, lo-fi\nclassical, anime soundtrack\nclassical, baroque, Spanish folk\nclassical, baroque, choral\nclassical, baroque, cinematic\nclassical, baroque, oratorio\nclassical, chamber music, Brazilian art song\nclassical, chamber music, folk\nclassical, chanson, musical theater\nclassical, chanson, theatrical\nclassical, choral\nclassical, choral, Christmas\nclassical, choral, ambient\nclassical, choral, baroque\nclassical, choral, christmas\nclassical, choral, cinematic\nclassical, choral, electronic\nclassical, choral, folk\nclassical, choral, jazz\nclassical, choral, liturgical\nclassical, choral, opera\nclassical, choral, orchestral\nclassical, choral, rock\nclassical, choral, sacred\nclassical, choral, vintage\nclassical, cinematic\nclassical, cinematic, choral\nclassical, cinematic, flamenco\nclassical, cinematic, opera\nclassical, cinematic, patriotic\nclassical, cinematic, sacred\nclassical, ethereal, sacred\nclassical, flamenco\nclassical, flamenco, art song\nclassical, flamenco, cinematic\nclassical, flamenco, operatic\nclassical, folk, art song\nclassical, folk, choral\nclassical, folk, cinematic\nclassical, folk, operatic\nclassical, folk, sacred\nclassical, folk-gospel, choral\nclassical, holiday, orchestral\nclassical, hymnal, sacred\nclassical, jazz\nclassical, jazz, cabaret\nclassical, jazz, operatic\nclassical, klezmer\nclassical, klezmer, jazz\nclassical, klezmer, tango\nclassical, liturgical, choral\nclassical, liturgical, orchestral\nclassical, lo-fi, ambient\nclassical, melancholic, lullaby\nclassical, melancholic, operatic\nclassical, opera buffa, orchestral\nclassical, opera, Italian art song\nclassical, opera, art song\nclassical, operatic, Christmas\nclassical, operatic, Russian romance\nclassical, operatic, choral\nclassical, operatic, cinematic\nclassical, operatic, folk\nclassical, operatic, gospel\nclassical, operatic, melancholic\nclassical, operatic, musical theater\nclassical, operatic, sea shanty\nclassical, orchestral, Christmas\nclassical, orchestral, baroque\nclassical, orchestral, choral\nclassical, orchestral, opera\nclassical, oud, operatic\nclassical, pop-gospel, cinematic\nclassical, ragtime, MPB\nclassical, ragtime, boogie-woogie\nclassical, ragtime, choral\nclassical, ragtime, theatrical\nclassical, romantic, flamenco\nclassical, sacred music\nclassical, sacred music, European folk\nclassical, sacred, Brazilian\nclassical, sacred, Celtic\nclassical, sacred, Korean traditional\nclassical, sacred, ambient\nclassical, sacred, baroque\nclassical, sacred, choral\nclassical, sacred, cinematic\nclassical, sacred, hymn\nclassical, sacred, operatic\nclassical, sacred, oratorio\nclassical, sacred, orchestral\nclassical, sacred, organ\nclassical, spiritual, choral\nclassical, spoken word\nclassical, spoken word, cinematic\nclassical, stride piano, ragtime\nclassical, stride, ragtime\nclassical, theatrical\nclassical, theatrical, Christmas\nclassical, theatrical, Latin American\nclassical, theatrical, folk\nclassical, theatrical, romantic\nclassical, torch song, cabaret\nclassical, world music, art song\nclassical-pop\nclassical-rock\nclassical-trap\nclassical-trap phonk\ncloud pop\ncloud rap\ncloud rap C-pop\ncloud rap C-pop lo-fi\ncloud rap French R&B\ncloud rap J-pop\ncloud rap R&B\ncloud rap afro-trap\ncloud rap alternative R&B\ncloud rap alternative R&B glitch pop\ncloud rap alternative R&B trap\ncloud rap alternative rock\ncloud rap ambient\ncloud rap ambient R&B\ncloud rap ambient pop\ncloud rap ambient trap\ncloud rap ambient trip-hop\ncloud rap chill trap\ncloud rap chillwave\ncloud rap chiptune\ncloud rap dark R&B\ncloud rap dark pop\ncloud rap dark pop ambient trap\ncloud rap dark trap\ncloud rap darkwave\ncloud rap deep house\ncloud rap dream pop\ncloud rap emo\ncloud rap emo rap\ncloud rap emo rap C-pop\ncloud rap emo rap Cantopop\ncloud rap emo rap French pop\ncloud rap emo rap J-pop\ncloud rap emo rap Mandopop\ncloud rap emo rap ambient\ncloud rap emo rap ambient pop\ncloud rap emo rap ambient rock\ncloud rap emo rap atmospheric R&B\ncloud rap emo rap atmospheric pop\ncloud rap emo rap atmospheric trap\ncloud rap emo rap chiptune\ncloud rap emo rap dark trap\ncloud rap emo rap dream pop\ncloud rap emo rap hyperpop\ncloud rap emo rap lo-fi\ncloud rap emo rap pluggnb\ncloud rap emo rap vaporwave\ncloud rap emo rock\ncloud rap emo trap\ncloud rap emo trap C-pop\ncloud rap emo trap J-pop\ncloud rap emo trap ambient\ncloud rap emo trap ambient pop\ncloud rap emo trap dark pop\ncloud rap emo trap dream pop\ncloud rap emo trap hyperpop\ncloud rap emo trap lo-fi hip-hop\ncloud rap emo trap synth-pop\ncloud rap emo-rap\ncloud rap emo-trap\ncloud rap emotional trap\ncloud rap emotional trap C-pop\ncloud rap experimental R&B\ncloud rap experimental trap\ncloud rap future bass\ncloud rap glitch-hop\ncloud rap gospel\ncloud rap hyperpop\ncloud rap indie rock\ncloud rap lo-fi\ncloud rap lo-fi R&B\ncloud rap lo-fi hip hop\ncloud rap lo-fi hip-hop\ncloud rap lo-fi house\ncloud rap lo-fi indie rock\ncloud rap lo-fi trap\ncloud rap meme rap\ncloud rap nu-metal\ncloud rap phonk\ncloud rap pluggnb\ncloud rap post-punk\ncloud rap rage trap\ncloud rap reggaeton\ncloud rap shoegaze\ncloud rap synth-pop\ncloud rap trap\ncloud rap trap C-pop\ncloud rap trap ambient\ncloud rap trap dream pop\ncloud rap trap rock\ncloud rap trap soul\ncloud rap trap-soul\ncloud rap vaporwave\ncloud rap vaporwave J-pop\ncloud rap witch house\ncloud rap, Afro-fusion\ncloud rap, Afrobeats\ncloud rap, Arabic fusion\ncloud rap, Arabic trap\ncloud rap, Balkan trap\ncloud rap, Brazilian trap\ncloud rap, Brazilian trap, lo-fi\ncloud rap, Brazilian trap, lo-fi hip hop\ncloud rap, Brazilian trap, vaporwave\ncloud rap, C-Pop trap\ncloud rap, C-pop\ncloud rap, C-pop trap\ncloud rap, C-pop, lo-fi\ncloud rap, C-pop, melodic trap\ncloud rap, C-pop, trap\ncloud rap, C-pop, trap-R&B\ncloud rap, C-pop, vaporwave\ncloud rap, Christian hip-hop\ncloud rap, Danish hip-hop\ncloud rap, Deutschrap\ncloud rap, Dutch hip-hop\ncloud rap, Finnish hip-hop\ncloud rap, French R&B\ncloud rap, French hip-hop\ncloud rap, French pop\ncloud rap, French pop, R&B\ncloud rap, French pop-rap\ncloud rap, French trap\ncloud rap, French trap, synth-pop\ncloud rap, French trap, vaporwave\ncloud rap, French, oriental\ncloud rap, German R&B\ncloud rap, German cloud rap\ncloud rap, German cloud rap, synth-pop\ncloud rap, German emo-rap\ncloud rap, German emo-rap, lo-fi\ncloud rap, German gangsta rap\ncloud rap, German hip-hop\ncloud rap, German hip-hop, lo-fi\ncloud rap, German melodic trap\ncloud rap, German pop, ambient\ncloud rap, German pop-rap\ncloud rap, German trap\ncloud rap, German trap, vaporwave\ncloud rap, Greek trap\ncloud rap, Italian hip hop\ncloud rap, Italian trap\ncloud rap, J-R&B\ncloud rap, J-hip-hop\ncloud rap, J-hip-hop, chill trap\ncloud rap, J-hip-hop, trap\ncloud rap, J-hip-hop, vaporwave\ncloud rap, J-pop\ncloud rap, J-pop, trap\ncloud rap, J-rap\ncloud rap, J-rap, chiptune\ncloud rap, J-rap, vaporwave\ncloud rap, J-trap\ncloud rap, K-hip-hop\ncloud rap, Latin R&B\ncloud rap, Latin R&B, lo-fi hip hop\ncloud rap, Latin hip-hop\ncloud rap, Latin pop\ncloud rap, Latin trap\ncloud rap, Latin, French\ncloud rap, Latin, melancholic\ncloud rap, Mandopop\ncloud rap, Mandopop, R&B\ncloud rap, Mandopop, lo-fi hip hop\ncloud rap, Mandopop, trap\ncloud rap, North African trap\ncloud rap, North African, melancholic\ncloud rap, R&B\ncloud rap, R&B trap\ncloud rap, R&B trap soul\ncloud rap, R&B, Afro-trap\ncloud rap, R&B, Mandarin\ncloud rap, R&B, Turkish hip hop\ncloud rap, R&B, anime\ncloud rap, R&B, lo-fi\ncloud rap, R&B, lo-fi hip hop\ncloud rap, R&B, lo-fi hip-hop\ncloud rap, R&B, pop\ncloud rap, R&B, trap\ncloud rap, R&B, vaporwave\ncloud rap, R&B, world music\ncloud rap, Rai, French\ncloud rap, Russian pop-rap\ncloud rap, Russian trap\ncloud rap, Scandinavian trap\ncloud rap, Southern hip-hop\ncloud rap, Southern trap\ncloud rap, Spanish guitar, melancholic\ncloud rap, Swedish hip-hop\ncloud rap, Swedish trap\ncloud rap, Thai hip-hop\ncloud rap, Turkish trap\ncloud rap, UK drill\ncloud rap, UK garage\ncloud rap, UK hip-hop\ncloud rap, UK hip-hop, atmospheric R&B\ncloud rap, UK trap\ncloud rap, West Coast hip-hop\ncloud rap, acoustic pop\ncloud rap, afro-trap\ncloud rap, afro-trap, French\ncloud rap, afro-trap, chiptune\ncloud rap, afro-trap, tropical house\ncloud rap, aggressive trap\ncloud rap, alternative R&B\ncloud rap, alternative R&B, K-pop\ncloud rap, alternative R&B, afro-trap\ncloud rap, alternative R&B, ambient pop\ncloud rap, alternative R&B, atmospheric pop\ncloud rap, alternative R&B, dream pop\ncloud rap, alternative R&B, electronic\ncloud rap, alternative R&B, electronic pop\ncloud rap, alternative R&B, experimental electronic\ncloud rap, alternative R&B, experimental hip-hop\ncloud rap, alternative R&B, glitch pop\ncloud rap, alternative R&B, lo-fi hip hop\ncloud rap, alternative R&B, lo-fi hip-hop\ncloud rap, alternative R&B, lo-fi trap\ncloud rap, alternative R&B, psychedelic hip-hop\ncloud rap, alternative R&B, synth-pop\ncloud rap, alternative R&B, trap\ncloud rap, ambient pop, trap\ncloud rap, ambient trap\ncloud rap, ambient trap, emo rap\ncloud rap, ambient, French hip hop\ncloud rap, ambient, hyperpop\ncloud rap, ambient, trap\ncloud rap, anime hip hop\ncloud rap, anime, lo-fi\ncloud rap, anime, lo-fi hip hop\ncloud rap, atmospheric R&B\ncloud rap, atmospheric R&B, trap\ncloud rap, atmospheric R&B, vaporwave\ncloud rap, atmospheric pop\ncloud rap, atmospheric pop, trap\ncloud rap, atmospheric trap\ncloud rap, atmospheric trap, French pop\ncloud rap, atmospheric trap, emo rap\ncloud rap, atmospheric trap, vaporwave\ncloud rap, bedroom pop\ncloud rap, boom-bap\ncloud rap, boom-bap, ambient hip-hop\ncloud rap, boom-bap, lo-fi hip hop\ncloud rap, boom-bap, melodic hip-hop\ncloud rap, chill trap\ncloud rap, chill trap, C-pop\ncloud rap, chillwave\ncloud rap, chillwave, hyperpop\ncloud rap, chillwave, lo-fi\ncloud rap, chillwave, trap\ncloud rap, chillwave, vaporwave\ncloud rap, chiptune\ncloud rap, chiptune, anime\ncloud rap, chiptune, digicore\ncloud rap, chiptune, emo rap\ncloud rap, chiptune, future bass\ncloud rap, chiptune, hyperpop\ncloud rap, chiptune, lo-fi\ncloud rap, chiptune, lo-fi hip hop\ncloud rap, chiptune, pluggnb\ncloud rap, chiptune, synthwave\ncloud rap, chiptune, trap\ncloud rap, chiptune, vaporwave\ncloud rap, chopped and screwed\ncloud rap, cinematic hip hop\ncloud rap, cinematic hip-hop\ncloud rap, cinematic pop\ncloud rap, cinematic synth, pop\ncloud rap, cinematic trap\ncloud rap, cinematic, French rap\ncloud rap, cinematic, ambient\ncloud rap, cinematic, dark ambient\ncloud rap, cinematic, lo-fi\ncloud rap, cinematic, oud\ncloud rap, cinematic, psychedelic\ncloud rap, cinematic, trap\ncloud rap, conscious hip-hop\ncloud rap, contemporary R&B\ncloud rap, dancehall\ncloud rap, dark R&B\ncloud rap, dark ambient\ncloud rap, dark pop\ncloud rap, dark trap\ncloud rap, dark trap, vaporwave\ncloud rap, darkwave, lo-fi\ncloud rap, deep house, ambient\ncloud rap, deep house, melodic techno\ncloud rap, dream pop\ncloud rap, dream pop, C-pop\ncloud rap, dream pop, Thai pop\ncloud rap, dream pop, emo rap\ncloud rap, dream pop, lo-fi hip hop\ncloud rap, dream pop, lo-fi hip-hop\ncloud rap, dream-pop, trap\ncloud rap, dreamy indie pop\ncloud rap, drill\ncloud rap, drill, lo-fi\ncloud rap, drill, trap\ncloud rap, electronic\ncloud rap, electronic pop, dance\ncloud rap, emo rap\ncloud rap, emo rap, C-pop\ncloud rap, emo rap, Cantopop\ncloud rap, emo rap, French\ncloud rap, emo rap, French hip-hop\ncloud rap, emo rap, French pop\ncloud rap, emo rap, German\ncloud rap, emo rap, German hip hop\ncloud rap, emo rap, J-pop\ncloud rap, emo rap, Latin trap\ncloud rap, emo rap, Mandopop\ncloud rap, emo rap, R&B\ncloud rap, emo rap, Russian pop-rap\ncloud rap, emo rap, acoustic\ncloud rap, emo rap, alternative R&B\ncloud rap, emo rap, ambient\ncloud rap, emo rap, ambient R&B\ncloud rap, emo rap, ambient pop\ncloud rap, emo rap, ambient trap\ncloud rap, emo rap, atmospheric\ncloud rap, emo rap, atmospheric R&B\ncloud rap, emo rap, atmospheric pop\ncloud rap, emo rap, atmospheric trap\ncloud rap, emo rap, bedroom pop\ncloud rap, emo rap, chiptune\ncloud rap, emo rap, cinematic\ncloud rap, emo rap, cinematic trap\ncloud rap, emo rap, contemporary R&B\ncloud rap, emo rap, dream pop\ncloud rap, emo rap, hazy trap\ncloud rap, emo rap, hyperpop\ncloud rap, emo rap, hyperpop R&B\ncloud rap, emo rap, indie rock\ncloud rap, emo rap, lo-fi\ncloud rap, emo rap, lo-fi hip hop\ncloud rap, emo rap, lo-fi hip-hop\ncloud rap, emo rap, lo-fi trap\ncloud rap, emo rap, phonk\ncloud rap, emo rap, pluggnb\ncloud rap, emo rap, pop\ncloud rap, emo rap, pop-trap\ncloud rap, emo rap, synth-pop\ncloud rap, emo rap, trap\ncloud rap, emo rap, vaporwave\ncloud rap, emo trap\ncloud rap, emo trap, Brazilian\ncloud rap, emo trap, C-pop\ncloud rap, emo trap, Cantopop\ncloud rap, emo trap, Chinese ambient\ncloud rap, emo trap, Chinese electronic\ncloud rap, emo trap, Chinese trap\ncloud rap, emo trap, French\ncloud rap, emo trap, J-pop\ncloud rap, emo trap, J-rap\ncloud rap, emo trap, Latin pop\ncloud rap, emo trap, Latin trap\ncloud rap, emo trap, Mandopop\ncloud rap, emo trap, Polish hip-hop\ncloud rap, emo trap, R&B\ncloud rap, emo trap, ambient\ncloud rap, emo trap, ambient pop\ncloud rap, emo trap, atmospheric R&B\ncloud rap, emo trap, atmospheric pop\ncloud rap, emo trap, boom-bap\ncloud rap, emo trap, chiptune\ncloud rap, emo trap, dark pop\ncloud rap, emo trap, dream-pop\ncloud rap, emo trap, dreamy\ncloud rap, emo trap, hyperpop\ncloud rap, emo trap, lo-fi\ncloud rap, emo trap, lo-fi hip hop\ncloud rap, emo trap, lo-fi hip-hop\ncloud rap, emo trap, modern trap\ncloud rap, emo trap, synth-pop\ncloud rap, emo trap, synthwave\ncloud rap, emo trap, vaporwave\ncloud rap, emo trap, world music\ncloud rap, emo-rap\ncloud rap, emo-rap, C-pop\ncloud rap, emo-rap, alternative R&B\ncloud rap, emo-rap, lo-fi hip hop\ncloud rap, emo-rap, pop-rap\ncloud rap, emo-rap, trap-soul\ncloud rap, emo-rock\ncloud rap, emo-trap\ncloud rap, emo-trap, lo-fi hip hop\ncloud rap, emotional J-pop\ncloud rap, emotional R&B\ncloud rap, emotional hip-hop\ncloud rap, emotional pop\ncloud rap, emotional pop, trap\ncloud rap, emotional pop-rap\ncloud rap, emotional pop-trap\ncloud rap, emotional trap\ncloud rap, emotional trap, J-pop\ncloud rap, emotional trap, hyperpop\ncloud rap, emotional trap, vaporwave\ncloud rap, ethereal wave\ncloud rap, experimental R&B, vaporwave\ncloud rap, experimental hip-hop\ncloud rap, experimental hip-hop, lo-fi\ncloud rap, experimental hip-hop, trap\ncloud rap, experimental trap\ncloud rap, experimental trap, ambient\ncloud rap, future bass\ncloud rap, future bass, glitch pop\ncloud rap, future bass, hardstyle\ncloud rap, futuristic trap\ncloud rap, futuristic, synthwave\ncloud rap, futuristic, trap\ncloud rap, gospel trap\ncloud rap, hardstyle, phonk\ncloud rap, hardwave\ncloud rap, hip-hop\ncloud rap, hip-hop, rock\ncloud rap, hyper-trap\ncloud rap, hyper-trap, psychedelic hip-hop\ncloud rap, hyperpop\ncloud rap, hyperpop, Chinese hip hop\ncloud rap, hyperpop, German\ncloud rap, hyperpop, J-pop\ncloud rap, hyperpop, R&B\ncloud rap, hyperpop, Russian emo\ncloud rap, hyperpop, ambient\ncloud rap, hyperpop, ambient trap\ncloud rap, hyperpop, anime\ncloud rap, hyperpop, anime-core\ncloud rap, hyperpop, chiptune\ncloud rap, hyperpop, cinematic\ncloud rap, hyperpop, electronic\ncloud rap, hyperpop, emo rap\ncloud rap, hyperpop, emo trap\ncloud rap, hyperpop, emo-trap\ncloud rap, hyperpop, future bass\ncloud rap, hyperpop, lo-fi\ncloud rap, hyperpop, lo-fi hip hop\ncloud rap, hyperpop, lo-fi trap\ncloud rap, hyperpop, nightcore\ncloud rap, hyperpop, pluggnb\ncloud rap, hyperpop, rage trap\ncloud rap, hyperpop, rage-trap\ncloud rap, hyperpop, synthwave\ncloud rap, hyperpop, trap\ncloud rap, hyperpop, trap metal\ncloud rap, hyperpop, vaporwave\ncloud rap, indie pop\ncloud rap, indie rock, alternative R&B\ncloud rap, indie-pop\ncloud rap, jazz hip hop\ncloud rap, jazzy hip-hop, R&B\ncloud rap, latin trap, vaporwave\ncloud rap, lo-fi R&B\ncloud rap, lo-fi hip hop\ncloud rap, lo-fi hip hop, C-pop\ncloud rap, lo-fi hip hop, German\ncloud rap, lo-fi hip hop, German rap\ncloud rap, lo-fi hip hop, Italian rap\ncloud rap, lo-fi hip hop, R&B\ncloud rap, lo-fi hip hop, Russian rap\ncloud rap, lo-fi hip hop, ambient\ncloud rap, lo-fi hip hop, ambient pop\ncloud rap, lo-fi hip hop, atmospheric trap\ncloud rap, lo-fi hip hop, dream pop\ncloud rap, lo-fi hip hop, emo rap\ncloud rap, lo-fi hip hop, emo trap\ncloud rap, lo-fi hip hop, emo-trap\ncloud rap, lo-fi hip hop, hyperpop\ncloud rap, lo-fi hip hop, jazz hop\ncloud rap, lo-fi hip hop, psychedelic R&B\ncloud rap, lo-fi hip hop, trap\ncloud rap, lo-fi hip hop, vaporwave\ncloud rap, lo-fi hip-hop\ncloud rap, lo-fi hip-hop, Brazilian\ncloud rap, lo-fi hip-hop, emo rap\ncloud rap, lo-fi hip-hop, emotional R&B\ncloud rap, lo-fi hip-hop, modern R&B\ncloud rap, lo-fi hip-hop, vaporwave\ncloud rap, lo-fi indie rock\ncloud rap, lo-fi pop\ncloud rap, lo-fi trap\ncloud rap, lo-fi trap, French pop\ncloud rap, lo-fi trap, Russian hip hop\ncloud rap, lo-fi trap, Spanish hip hop\ncloud rap, lo-fi trap, alternative R&B\ncloud rap, lo-fi trap, chiptune\ncloud rap, lo-fi trap, dream pop\ncloud rap, lo-fi trap, emo rap\ncloud rap, lo-fi, Mandarin hip hop\ncloud rap, lo-fi, R&B\ncloud rap, lo-fi, ambient\ncloud rap, lo-fi, hardstyle\ncloud rap, lo-fi, jazzy\ncloud rap, lo-fi, psychedelic\ncloud rap, lo-fi, trap\ncloud rap, lo-fi, trap-soul\ncloud rap, lo-fi, vaporwave\ncloud rap, melodic trap\ncloud rap, melodic trap, French trap\ncloud rap, melodic trap, Italian\ncloud rap, melodic trap, R&B\ncloud rap, melodic trap, lo-fi\ncloud rap, melodic trap, lo-fi hip hop\ncloud rap, melodic trap, vaporwave\ncloud rap, modern R&B\ncloud rap, modern hip-hop\ncloud rap, modern trap\ncloud rap, modern trap, chiptune\ncloud rap, modern trap, vaporwave\ncloud rap, motivational hip-hop\ncloud rap, neo-soul\ncloud rap, orchestral dubstep, trap-metal\ncloud rap, oriental, trap\ncloud rap, phonk\ncloud rap, phonk, deep house\ncloud rap, phonk, trap\ncloud rap, phonk, trap metal\ncloud rap, pluggnb\ncloud rap, pluggnb, ambient\ncloud rap, pluggnb, ambient trap\ncloud rap, pluggnb, chiptune\ncloud rap, pluggnb, emo rap\ncloud rap, pluggnb, emo trap\ncloud rap, pluggnb, lo-fi\ncloud rap, pluggnb, lo-fi synth\ncloud rap, pluggnb, rage\ncloud rap, pluggnb, synthwave\ncloud rap, pluggnb, trap\ncloud rap, pluggnb, vaporwave\ncloud rap, pop-punk\ncloud rap, pop-trap\ncloud rap, pop-trap, emo rap\ncloud rap, psychedelic R&B\ncloud rap, psychedelic hip-hop, hyperpop\ncloud rap, psychedelic rock, German hip hop\ncloud rap, psychedelic soul, alternative R&B\ncloud rap, psychedelic trap\ncloud rap, rage music\ncloud rap, rage trap\ncloud rap, rage trap, chiptune\ncloud rap, rage trap, ethereal R&B\ncloud rap, reggaeton\ncloud rap, reggaeton, Latin\ncloud rap, regional Mexican hip-hop\ncloud rap, rock\ncloud rap, romantic R&B\ncloud rap, romantic trap\ncloud rap, sad pop\ncloud rap, sci-fi, trap\ncloud rap, shoegaze\ncloud rap, shoegaze, dream pop\ncloud rap, soulful R&B\ncloud rap, soulful trap\ncloud rap, southern hip-hop\ncloud rap, southern trap\ncloud rap, stoner trap\ncloud rap, synth-pop\ncloud rap, synth-pop, Italo-disco\ncloud rap, synth-pop, emo rap\ncloud rap, synth-pop, lo-fi hip hop\ncloud rap, synth-pop, trap\ncloud rap, synth-pop, vaporwave\ncloud rap, synthwave, trap\ncloud rap, trap\ncloud rap, trap R&B, C-pop\ncloud rap, trap R&B, atmospheric R&B\ncloud rap, trap metal\ncloud rap, trap soul\ncloud rap, trap soul, lo-fi\ncloud rap, trap soul, modern R&B\ncloud rap, trap, Arabic music\ncloud rap, trap, Balkan hip hop\ncloud rap, trap, Brazilian\ncloud rap, trap, C-pop\ncloud rap, trap, Chinese ambient\ncloud rap, trap, Chinese electronic\ncloud rap, trap, Chinese hip hop\ncloud rap, trap, European hip-hop\ncloud rap, trap, French hip hop\ncloud rap, trap, French pop\ncloud rap, trap, German\ncloud rap, trap, German hip hop\ncloud rap, trap, J-pop\ncloud rap, trap, Latin pop\ncloud rap, trap, Latin trap\ncloud rap, trap, Mandarin hip hop\ncloud rap, trap, North African\ncloud rap, trap, North African hip-hop\ncloud rap, trap, R&B\ncloud rap, trap, Russian hip hop\ncloud rap, trap, Southern hip-hop\ncloud rap, trap, West Coast\ncloud rap, trap, alternative R&B\ncloud rap, trap, ambient\ncloud rap, trap, ambient R&B\ncloud rap, trap, ambient pop\ncloud rap, trap, anime\ncloud rap, trap, atmospheric R&B\ncloud rap, trap, atmospheric pop\ncloud rap, trap, boom-bap\ncloud rap, trap, chillwave\ncloud rap, trap, chiptune\ncloud rap, trap, chopped and screwed\ncloud rap, trap, cinematic\ncloud rap, trap, contemporary R&B\ncloud rap, trap, dark ambient\ncloud rap, trap, dark pop\ncloud rap, trap, darkwave\ncloud rap, trap, dream pop\ncloud rap, trap, dreamy\ncloud rap, trap, electronic\ncloud rap, trap, ethereal R&B\ncloud rap, trap, ethereal wave\ncloud rap, trap, experimental\ncloud rap, trap, experimental R&B\ncloud rap, trap, experimental hip-hop\ncloud rap, trap, horrorcore\ncloud rap, trap, hyperpop\ncloud rap, trap, indie rock\ncloud rap, trap, lo-fi\ncloud rap, trap, lo-fi hip hop\ncloud rap, trap, melodic hip hop\ncloud rap, trap, melodic rap\ncloud rap, trap, modern R&B\ncloud rap, trap, pluggnb\ncloud rap, trap, psychedelic\ncloud rap, trap, psychedelic pop\ncloud rap, trap, reggaeton\ncloud rap, trap, rock\ncloud rap, trap, synth-pop\ncloud rap, trap, techno\ncloud rap, trap, tribal hip-hop\ncloud rap, trap, vaporwave\ncloud rap, trap, video game\ncloud rap, trap, world music\ncloud rap, trap-R&B\ncloud rap, trap-pop\ncloud rap, trap-soul\ncloud rap, trap-soul, lo-fi\ncloud rap, trap-soul, vaporwave\ncloud rap, tribal, ambient\ncloud rap, vaporwave\ncloud rap, vaporwave, C-pop\ncloud rap, vaporwave, Dutch hip-hop\ncloud rap, vaporwave, German hip hop\ncloud rap, vaporwave, J-pop\ncloud rap, vaporwave, Korean hip-hop\ncloud rap, vaporwave, Mandarin hip hop\ncloud rap, vaporwave, R&B\ncloud rap, vaporwave, alternative R&B\ncloud rap, vaporwave, ambient trap\ncloud rap, vaporwave, chiptune\ncloud rap, vaporwave, dream pop\ncloud rap, vaporwave, drill\ncloud rap, vaporwave, emo rap\ncloud rap, vaporwave, emo trap\ncloud rap, vaporwave, hyperpop\ncloud rap, vaporwave, lo-fi\ncloud rap, vaporwave, lo-fi hip hop\ncloud rap, vaporwave, modern R&B\ncloud rap, vaporwave, modern trap\ncloud rap, vaporwave, pluggnb\ncloud rap, vaporwave, pop-trap\ncloud rap, vaporwave, psychedelic\ncloud rap, vaporwave, trap\ncloud rap, world music\ncloud trap\nclub R&B\nclub R&B hip-hop\nclub R&B trap\nclub banger, R&B, South Asian pop\nclub hip-hop\nclub jazz\nclub pop\nclub rap\nclub rap, twerk, trap\nclub, bass, electronic\nclub, hip hop, R&B\nclub-pop\nclub-pop trap\nclub-rap\ncoastal boombap\ncoastal country-rock\ncoastal folk\ncoastal folk-rock\ncoastal hip-hop\ncoastal indie pop\ncoastal indie rock\ncoastal indie-pop\ncoastal pop\ncoastal pop-rock\ncoastal rock\ncold trap\ncold wave\ncoldwave\ncoldwave darkwave\ncoldwave dream pop\ncoldwave post-punk\ncoldwave synth-pop\ncoldwave techno\ncoldwave, Neue Deutsche Welle, synthwave\ncoldwave, darkwave\ncoldwave, darkwave, post-punk\ncoldwave, darkwave, retro-futuristic\ncoldwave, darkwave, synth-pop\ncoldwave, darkwave, synthwave\ncoldwave, dream pop, synth-pop\ncoldwave, dream-pop, lo-fi\ncoldwave, indie rock\ncoldwave, lo-fi, glitch\ncoldwave, post-punk\ncoldwave, post-punk, darkwave\ncoldwave, post-punk, synthwave\ncoldwave, synth-pop\ncoldwave, synth-pop, darkwave\ncoldwave, synth-pop, new wave\ncoldwave, synthwave\ncolor bass\ncomedy\ncomedy R&B\ncomedy R&B hip-hop\ncomedy a cappella\ncomedy ambient\ncomedy bluegrass\ncomedy blues\ncomedy brass\ncomedy country\ncomedy country folk\ncomedy country rock\ncomedy country-folk\ncomedy drill\ncomedy electronic\ncomedy fanfare\ncomedy folk\ncomedy folk-rock\ncomedy funk\ncomedy hip hop\ncomedy hip-hop\ncomedy hip-hop chiptune\ncomedy hip-hop funk\ncomedy hip-hop funk-pop\ncomedy hip-hop nu-metal\ncomedy hip-hop polka\ncomedy house\ncomedy jazz\ncomedy jingle\ncomedy metal\ncomedy metal punk rock\ncomedy metalcore\ncomedy music\ncomedy music, Latin, novelty\ncomedy musical\ncomedy novelty\ncomedy parody\ncomedy piano\ncomedy polka\ncomedy pop\ncomedy pop reggaeton\ncomedy pop, Turkish pop, electronic\ncomedy pop-rap\ncomedy pop-rock\ncomedy punk\ncomedy punk rock\ncomedy rap\ncomedy rap funk-rock\ncomedy rap funk-ska\ncomedy rap lo-fi\ncomedy rap synth-pop\ncomedy rap, battle rap, cabaret\ncomedy rap, chiptune, 8-bit\ncomedy rap, chiptune, breakbeat\ncomedy rap, chiptune, trap\ncomedy rap, cinematic hip hop, anime soundtrack\ncomedy rap, funk, hyperpop\ncomedy rap, glitch hop, indie-pop\ncomedy rap, showtune, chiptune\ncomedy rap, trap, chiptune\ncomedy rap, trap, hyperpop\ncomedy rap, trap, jazz\ncomedy rock\ncomedy rock big band\ncomedy rock blues-rock\ncomedy rock cabaret\ncomedy rock cabaret balkan\ncomedy rock cabaret polka\ncomedy rock cabaret punk\ncomedy rock cabaret swing\ncomedy rock chiptune\ncomedy rock country\ncomedy rock country-folk\ncomedy rock country-pop\ncomedy rock country-rock\ncomedy rock folk-punk\ncomedy rock funk\ncomedy rock funk rap\ncomedy rock funk rockabilly\ncomedy rock garage punk\ncomedy rock geek rock\ncomedy rock hip-hop\ncomedy rock indie pop\ncomedy rock lounge-pop punk\ncomedy rock music hall\ncomedy rock nerdcore\ncomedy rock novelty\ncomedy rock polka\ncomedy rock pop-punk\ncomedy rock power metal\ncomedy rock power metal J-rock\ncomedy rock pub rock\ncomedy rock punk\ncomedy rock punk surf rock\ncomedy rock ragtime\ncomedy rock reggae\ncomedy rock ska\ncomedy rock ska big band\ncomedy rock ska circus\ncomedy rock ska funk\ncomedy rock ska polka\ncomedy rock ska punk\ncomedy rock ska reggae\ncomedy rock ska russian chanson\ncomedy rock ska-punk\ncomedy rock ska-punk swing\ncomedy rock surf rock\ncomedy rock surf-rock\ncomedy rock surf-rock rockabilly\ncomedy rock synth-pop\ncomedy rock waltz\ncomedy rock, Brazilian, bossa nova\ncomedy rock, Eurodance, happy hardcore\ncomedy rock, German Schlager, electronic\ncomedy rock, German punk\ncomedy rock, German punk, Neue Deutsche Welle\ncomedy rock, Japanese thematic, power-pop\ncomedy rock, Javanese fusion\ncomedy rock, Latin rock\ncomedy rock, Latin rock, mariachi\ncomedy rock, Latin rock, world music\ncomedy rock, Latin, cabaret\ncomedy rock, Portuguese folk\ncomedy rock, Schlager\ncomedy rock, Schlager, boogie-woogie\ncomedy rock, Schlager, theatrical rock\ncomedy rock, big band, rockabilly\ncomedy rock, big band, swing\ncomedy rock, big band, theatrical\ncomedy rock, cabaret rock, Italian rock\ncomedy rock, cabaret, polka\ncomedy rock, chiptune, musical theater\ncomedy rock, chiptune, power-pop\ncomedy rock, country rock, rockabilly\ncomedy rock, country, rockabilly\ncomedy rock, cumbia, world music\ncomedy rock, folk punk, polka-punk\ncomedy rock, folk rock, polka\ncomedy rock, musical theater, J-rock\ncomedy rock, musical theater, pop-punk\ncomedy rock, musical theater, pop-rock\ncomedy rock, musical theater, rock\ncomedy rock, musical theater, rock opera\ncomedy rock, musical theater, show tune\ncomedy rock, punk rock, Deutschrock\ncomedy rock, punk, nu-metal\ncomedy rock, retro rock, schlager\ncomedy rock, rock opera, theatrical rock\ncomedy rock, rockabilly\ncomedy rock, rockabilly, country\ncomedy rock, rockabilly, schlager\ncomedy rock, rockabilly, surf rock\ncomedy rock, rockabilly, swing\ncomedy rock, rockabilly, theatrical\ncomedy rock, southern rock\ncomedy rock, surf rock, rockabilly\ncomedy rock, surf rock, ska\ncomedy rock, synth-pop, nu-metal\ncomedy rock, theatrical rock, eclectic\ncomedy rock, world fusion, hard rock\ncomedy samba\ncomedy schlager\ncomedy sea shanty\ncomedy ska\ncomedy sketch\ncomedy sound effect\ncomedy spoken word\ncomedy swing\ncomedy tango\ncomedy trap\ncomedy ukulele\ncomedy-pop\ncomedy-pop Bollywood Middle Eastern\ncomedy-pop MPB\ncomedy-pop cabaret\ncomedy-pop cabaret polka\ncomedy-pop jazz\ncomedy-pop musical theater\ncomedy-pop ska\ncomedy-punk\ncomedy-punk chiptune\ncomedy-rock, punk, alternative metal\ncomical brass\ncomical instrumental\ncommercial hip-hop\ncommercial house\ncommercial jingle\ncommercial pop\ncompas\ncompas salsa\ncomplexo\ncomplexo J-core\ncomplexo drum and bass\ncomplexo dubstep\ncomplexo dubstep chiptune\ncomplexo hardstyle\ncomplexo house\ncomplexo neurofunk\ncomplexo, artcore, electronic\ncomplexo, big room, cinematic electronic\ncomplexo, chiptune\ncomplexo, chiptune, cinematic\ncomplexo, cinematic, electronic\ncomplexo, cinematic, future bass\ncomplexo, color bass, cinematic\ncomplexo, dubstep\ncomplexo, electro house, chiptune\ncomplexo, electronic, R&B\ncomplexo, ethereal, electronic\ncomplexo, glitch, ambient\ncomplexo, glitch-hop, ambient\ncomplexo, hardstyle\ncomplexo, hardstyle, J-pop\ncomplexo, hardstyle, ambient\ncomplexo, hardstyle, cinematic\ncomplexo, hardstyle, dubstep\ncomplexo, hardstyle, electronic\ncomplexo, hardstyle, future pop\ncomplexo, hardstyle, melodic pop\ncomplexo, hardstyle, pop\ncomplexo, hardstyle, video game music\ncomplexo, neurofunk\ncomplexo, neurofunk, speedcore\ncomplexo, synth-pop, color bass\ncomplexo, vaporwave, pop\ncomplexro\ncomplexro brostep\ncomplexro chiptune\ncomplexro drum and bass\ncomplexro dubstep\ncomplexro future bass\ncomplexro glitch-hop future bass\ncomplexro hardcore techno\ncomplexro hardstyle\ncomplexro hardstyle dubstep\ncomplexro neurofunk\ncomplexro neurofunk chiptune\ncomplexro progressive house\ncomplexro, brostep\ncomplexro, chiptune, dubstep\ncomplexro, chiptune, hardcore techno\ncomplexro, cinematic\ncomplexro, cinematic synth, sci-fi\ncomplexro, cinematic, hardstyle\ncomplexro, dubstep, ambient\ncomplexro, hardstyle\ncomplexro, hardstyle, breakcore\ncomplexro, hardstyle, cinematic\ncomplexro, hyperpop, glitchcore\ncomplexro, nu-disco, hardstyle\ncomplexro, speedcore, chiptune\ncomplexro, trance, cinematic\ncomplextro\ncomplextro C-pop\ncomplextro R&B\ncomplextro anime\ncomplextro artcore\ncomplextro big room\ncomplextro bossa nova\ncomplextro breakcore\ncomplextro brostep\ncomplextro chiptune\ncomplextro cinematic\ncomplextro color bass\ncomplextro cyberpunk\ncomplextro dubstep\ncomplextro dubstep chiptune\ncomplextro dubstep techno\ncomplextro electro house\ncomplextro electro-pop\ncomplextro electro-swing\ncomplextro future bass\ncomplextro glitch hop\ncomplextro glitch hop hardcore\ncomplextro glitch-hop\ncomplextro hardcore\ncomplextro hardstyle\ncomplextro hardstyle chiptune\ncomplextro hip-hop\ncomplextro indie-folk\ncomplextro lo-fi\ncomplextro lounge-funk\ncomplextro metalcore\ncomplextro neurofunk\ncomplextro nu-metal\ncomplextro orchestral\ncomplextro pop-punk\ncomplextro pop-rock\ncomplextro progressive house\ncomplextro vaporwave\ncomplextro vocalwave\ncomplextro, C-pop, cinematic\ncomplextro, J-core, happy hardcore\ncomplextro, J-core, hardstyle\ncomplextro, ambient, electronic\ncomplextro, ambient, emotional EDM\ncomplextro, breakcore, ambient\ncomplextro, chiptune, J-core\ncomplextro, chiptune, dubstep\ncomplextro, chiptune, electro house\ncomplextro, chiptune, happy hardcore\ncomplextro, chiptune, hard dance\ncomplextro, chiptune, hardcore\ncomplextro, chiptune, hardstyle\ncomplextro, chiptune, neurofunk\ncomplextro, chiptune, video game music\ncomplextro, cinematic, Chinese villain\ncomplextro, cinematic, French pop\ncomplextro, cinematic, Middle Eastern\ncomplextro, cinematic, baroque\ncomplextro, cinematic, chiptune\ncomplextro, cinematic, hardstyle\ncomplextro, cinematic, orchestral\ncomplextro, cinematic, pop-rock\ncomplextro, cinematic, sci-fi\ncomplextro, cinematic, trance\ncomplextro, drum and bass, Russian vocal\ncomplextro, dubstep, ambient\ncomplextro, dubstep, brostep\ncomplextro, dubstep, chiptune\ncomplextro, dubstep, electro house\ncomplextro, electro house, chiptune\ncomplextro, electro house, dubstep\ncomplextro, electro-metal\ncomplextro, electro-swing\ncomplextro, electronic, cinematic\ncomplextro, ethereal, Arabic chant\ncomplextro, future bass, ambient\ncomplextro, future bass, hardcore\ncomplextro, future bass, hardstyle\ncomplextro, glitch hop, hardstyle\ncomplextro, glitch, chiptune\ncomplextro, glitch, hardstyle\ncomplextro, hard electro, dubstep\ncomplextro, hard electro, glitch\ncomplextro, hardstyle\ncomplextro, hardstyle, ambient\ncomplextro, hardstyle, chiptune\ncomplextro, hardstyle, cinematic\ncomplextro, lo-fi, glitch\ncomplextro, neurofunk\ncomplextro, nu-disco, cinematic\ncomplextro, trancecore, cinematic\nconcert band\nconcert band march\nconcert march\nconfrontational hip-hop\nconscious Arabic hip-hop\nconscious Brazilian hip-hop\nconscious Brazilian rap\nconscious Christian hip-hop\nconscious Desi hip-hop\nconscious Filipino hip-hop\nconscious French hip-hop\nconscious French rap\nconscious French trap\nconscious German hip-hop\nconscious Italian hip-hop\nconscious Latin hip-hop\nconscious Latin rap\nconscious R&B\nconscious Southern hip-hop\nconscious Turkish hip-hop\nconscious UK hip-hop\nconscious West Coast hip-hop\nconscious boom-bap\nconscious dancehall\nconscious dancehall lo-fi hip hop\nconscious dancehall lo-fi hip-hop\nconscious drill\nconscious folk\nconscious funk\nconscious funk carioca\nconscious hip hop\nconscious hip-hop\nconscious hip-hop Afrobeat\nconscious hip-hop R&B\nconscious hip-hop R&B Caribbean\nconscious hip-hop R&B smooth jazz\nconscious hip-hop R&B zouk\nconscious hip-hop afrobeat\nconscious hip-hop afrobeats\nconscious hip-hop alternative rock\nconscious hip-hop ambient\nconscious hip-hop chiptune\nconscious hip-hop classical fusion\nconscious hip-hop dancehall\nconscious hip-hop dancehall gospel\nconscious hip-hop dream-pop\nconscious hip-hop electronic\nconscious hip-hop emo rap\nconscious hip-hop funk\nconscious hip-hop future bass\nconscious hip-hop glitch-hop\nconscious hip-hop gospel\nconscious hip-hop gospel Caribbean\nconscious hip-hop indie pop\nconscious hip-hop indie rock\nconscious hip-hop indie-folk\nconscious hip-hop indie-pop\nconscious hip-hop jazz\nconscious hip-hop lo-fi\nconscious hip-hop neo-soul\nconscious hip-hop nu-metal\nconscious hip-hop rap-rock\nconscious hip-hop reggae\nconscious hip-hop reggae funk\nconscious hip-hop rock crossover\nconscious hip-hop soul\nconscious hip-hop synth-pop\nconscious hip-hop trap\nconscious hip-hop trap dancehall\nconscious hip-hop vaporwave\nconscious hip-hop world music\nconscious hip-hop, Arabic fusion\nconscious hip-hop, Indian classical\nconscious hip-hop, Latin rap\nconscious hip-hop, R&B\nconscious hip-hop, alternative R&B\nconscious hip-hop, cinematic orchestral\nconscious hip-hop, cinematic synth-pop\nconscious hip-hop, cloud-rap\nconscious hip-hop, cyberpunk\nconscious hip-hop, dream-pop R&B\nconscious hip-hop, drum and bass, reggae fusion\nconscious hip-hop, emo-rap\nconscious hip-hop, emotional R&B\nconscious hip-hop, ethereal R&B\nconscious hip-hop, inspirational R&B\nconscious hip-hop, lo-fi\nconscious hip-hop, lo-fi hip hop\nconscious hip-hop, lo-fi jazz\nconscious hip-hop, lo-fi, chopped and screwed\nconscious hip-hop, lo-fi, cloud rap\nconscious hip-hop, melodic R&B\nconscious hip-hop, pop-rock, Turkish folk\nconscious hip-hop, psychedelic trap\nconscious hip-hop, soulful R&B\nconscious hip-hop, soulful R&B, cinematic\nconscious hip-hop, trap\nconscious hip-hop, world music\nconscious house\nconscious pop\nconscious rap\nconscious rap, French hip hop, Afrobeat\nconscious rap, pop-rock, atmospheric\nconscious reggae\nconscious reggae hip-hop\nconscious reggaeton\nconscious trance\nconscious trap\nconscious trip-hop\nconscious underground hip-hop\ncontemplative C-pop\ncontemplative acoustic\ncontemplative ambient\ncontemplative ballad\ncontemplative classical\ncontemplative folk\ncontemplative hip-hop\ncontemplative hymn\ncontemplative indie\ncontemplative instrumental\ncontemplative jazz\ncontemplative piano\ncontemplative pop\ncontemplative pop-ballad\ncontemplative pop-rap\ncontemplative pop-rock\ncontemplative rap\ncontemplative rock\ncontemplative trap\ncontemplative worship\ncontemporary Arabic devotional\ncontemporary Christian\ncontemporary Christian EDM\ncontemporary Christian R&B\ncontemporary Christian bhajan\ncontemporary Christian country\ncontemporary Christian country-gospel\ncontemporary Christian country-rock\ncontemporary Christian dancehall\ncontemporary Christian folk\ncontemporary Christian folk-pop\ncontemporary Christian folk-rock\ncontemporary Christian gospel\ncontemporary Christian hip-hop\ncontemporary Christian music\ncontemporary Christian pop\ncontemporary Christian pop afrobeat\ncontemporary Christian pop jazz\ncontemporary Christian pop, smooth jazz\ncontemporary Christian pop-gospel\ncontemporary Christian pop-rock\ncontemporary Christian rock\ncontemporary Christian trap\ncontemporary Christian world music\ncontemporary Christian worship\ncontemporary Christian worship, Latin pop-rock\ncontemporary Christian, Celtic folk\ncontemporary Christian, Indian classical\ncontemporary Christian, Indian film music\ncontemporary Christian, Indian film music, pop-rock\ncontemporary Christian, Indian fusion\ncontemporary Christian, Latin cumbia\ncontemporary Christian, Latin folk\ncontemporary Christian, Latin pop\ncontemporary Christian, Latin, world music\ncontemporary Christian, MPB\ncontemporary Christian, South Asian pop\ncontemporary Christian, South Indian folk\ncontemporary Christian, South Indian, devotional\ncontemporary Christian, South Indian, pop-rock\ncontemporary Christian, bossa nova\ncontemporary Christian, cinematic pop\ncontemporary Christian, indie folk\ncontemporary Christian, lo-fi hip-hop, pop\ncontemporary Christian, new age, Hawaiian\ncontemporary Christian, smooth jazz\ncontemporary Christian, smooth jazz, R&B\ncontemporary Christian, smooth jazz, gospel\ncontemporary Christian, trap, R&B\ncontemporary Christian, world music\ncontemporary Christmas\ncontemporary Christmas ballad\ncontemporary Indian\ncontemporary Islamic\ncontemporary Islamic devotional\ncontemporary R&B\ncontemporary R&B Afrobeats\ncontemporary R&B C-pop\ncontemporary R&B Indian fusion\ncontemporary R&B Mandopop\ncontemporary R&B acoustic pop\ncontemporary R&B chillwave\ncontemporary R&B country-rock\ncontemporary R&B dancehall\ncontemporary R&B dream pop\ncontemporary R&B future bass\ncontemporary R&B gospel\ncontemporary R&B gospel-pop\ncontemporary R&B hip-hop\ncontemporary R&B lo-fi hip-hop\ncontemporary R&B pop\ncontemporary R&B soul\ncontemporary R&B trap\ncontemporary R&B trap world music\ncontemporary R&B world music\ncontemporary R&B, Afrobeats, Gospel\ncontemporary R&B, C-pop\ncontemporary R&B, Central Asian pop\ncontemporary R&B, Chinese hip-hop\ncontemporary R&B, Christian hip-hop\ncontemporary R&B, French pop, trap\ncontemporary R&B, Gospel\ncontemporary R&B, Latin pop\ncontemporary R&B, Middle Eastern fusion\ncontemporary R&B, North African pop\ncontemporary R&B, South African\ncontemporary R&B, South African fusion\ncontemporary R&B, South Asian fusion\ncontemporary R&B, South Asian pop\ncontemporary R&B, South Indian fusion\ncontemporary R&B, UK hip-hop\ncontemporary R&B, chillwave\ncontemporary R&B, conscious hip-hop\ncontemporary R&B, emo-rap\ncontemporary R&B, gospel\ncontemporary R&B, gospel, hip-hop\ncontemporary R&B, gospel, trap\ncontemporary R&B, gospel, world music\ncontemporary R&B, gospel-pop\ncontemporary R&B, hip-hop\ncontemporary R&B, inspirational pop\ncontemporary R&B, lo-fi hip-hop\ncontemporary R&B, lo-fi, Chinese hip hop\ncontemporary R&B, pop\ncontemporary R&B, pop, trap\ncontemporary R&B, pop-gospel\ncontemporary R&B, pop-rap, dreamy\ncontemporary R&B, synth-pop\ncontemporary R&B, synth-pop, chillwave\ncontemporary R&B, trap\ncontemporary R&B, trap hip-hop\ncontemporary R&B, trap, Chinese pop\ncontemporary R&B, trap, world music\ncontemporary R&B, trap-soul, Chinese pop\ncontemporary R&B, world music\ncontemporary a cappella\ncontemporary bhajan\ncontemporary choral\ncontemporary classical\ncontemporary devotional\ncontemporary electronic pop\ncontemporary folk\ncontemporary folk-gospel\ncontemporary folk-pop\ncontemporary funk\ncontemporary ghazal\ncontemporary gospel\ncontemporary gospel Afro-pop\ncontemporary gospel R&B\ncontemporary gospel afro-pop\ncontemporary gospel afrobeat\ncontemporary gospel afrobeats\ncontemporary gospel afropop\ncontemporary gospel funk-rock\ncontemporary gospel reggae\ncontemporary gospel rock\ncontemporary gospel soul\ncontemporary hip-hop\ncontemporary hymn\ncontemporary instrumental\ncontemporary jazz\ncontemporary nasheed\ncontemporary nasyid\ncontemporary piano\ncontemporary pop\ncontemporary pop R&B\ncontemporary pop ballad\ncontemporary pop gospel\ncontemporary pop, R&B\ncontemporary pop, R&B, world music\ncontemporary pop, Tibetan hip-hop\ncontemporary pop-ballad\ncontemporary pop-rock\ncontemporary sacred\ncontemporary solo\ncontemporary world music\ncontemporary worship\ncontemporary worship afrobeats\ncontemporary worship, Latin-pop\ncool jazz\ncool jazz ambient\ncool jazz bossa nova\ncool jazz hip-hop\ncool jazz lounge\ncool jazz orchestral\ncool jazz, French chanson\ncool jazz, Italian ballad\ncool jazz, Russian romance\ncool jazz, big band swing\ncool jazz, blues, Spanish chanson\ncool jazz, cinematic, progressive rock\ncool jazz, jazz-rap\ncool jazz, lounge, Greek art song\ncopla\ncopla flamenco\ncopla orchestral\ncopla tango\ncopla, Spanish folk, tango\ncopla, Spanish folk, theatrical\ncopla, Spanish theatrical\ncopla, Spanish, festive\ncopla, Spanish, operatic\ncopla, Spanish, orchestral\ncopla, Spanish, theatrical\ncopla, big band, flamenco\ncopla, big band, theatrical\ncopla, brass band\ncopla, brass band, Spanish\ncopla, brass, theatrical\ncopla, cinematic, power ballad\ncopla, flamenco, Latin\ncopla, flamenco, Spanish folk\ncopla, flamenco, big band\ncopla, flamenco, cinematic\ncopla, flamenco, orchestral\ncopla, flamenco, theatrical\ncopla, marching band, Spanish\ncopla, operatic, Spanish\ncopla, operatic, Spanish folk\ncopla, operatic, cinematic\ncopla, operatic, dramatic\ncopla, operatic, orchestral\ncopla, operatic, theatrical\ncopla, orchestral, Spanish\ncopla, orchestral, dramatic\ncopla, orchestral, flamenco\ncopla, orchestral, operatic\ncopla, orchestral, theatrical\ncopla, tango, flamenco\ncopla, tango, operatic\ncopla, theatrical\ncopla, theatrical, Spanish\ncopla, theatrical, brass band\ncopla, theatrical, cinematic\ncopla, theatrical, classical\ncopla, theatrical, flamenco\ncopla, theatrical, marching band\ncopla, theatrical, opera\ncopla, theatrical, orchestral\ncopla, theatrical, tango\ncorporate\ncorporate ambient\ncorporate anthem\ncorporate electronic\ncorporate electronica\ncorporate funk\ncorporate hip-hop\ncorporate house\ncorporate instrumental\ncorporate jingle\ncorporate pop\ncorporate pop Bollywood\ncorporate pop afro-pop\ncorporate pop funk disco\ncorporate pop reggaeton\ncorporate pop, EDM\ncorporate pop, EDM, progressive house\ncorporate pop, synth-pop, power ballad, cartoon pop\ncorporate pop-funk\ncorporate pop-rap\ncorporate pop-rock\ncorporate rock\ncorporate-pop\ncorrido\ncorrido banda\ncorrido belica\ncorrido bélico\ncorrido bélico trap\ncorrido bélico, norteño\ncorrido béuoso\ncorrido chiptune\ncorrido confrontador\ncorrido cumbia\ncorrido garage rock\ncorrido hyperpop punk rock\ncorrido lo-fi hip hop\ncorrido norteño\ncorrido progressive\ncorrido punk\ncorrido ranchera\ncorrido ranchero\ncorrido rap\ncorrido sierrano\ncorrido sierreño\ncorrido ska\ncorrido synth-pop\ncorrido trap\ncorrido tumbado\ncorrido tumbado hip-hop\ncorrido tumbado trap\ncorrido tumbado, trap, urban\ncorridos punk\ncorridos tumbados\ncorridos tumbados trap\ncorridos tumbados, hyperpop, electronic\ncosmic R&B\ncosmic country\ncosmic country-rock\ncosmic disco-funk\ncosmic electro-swing\ncosmic funk\ncosmic funk disco\ncosmic funk-pop\ncosmic hip-hop\ncosmic pop\ncosmic pop-R&B\ncosmic reggae\ncosmic reggaeton\ncosmic trap\ncosmic trap-pop\ncountry\ncountry Christmas\ncountry EDM\ncountry Norteño\ncountry R&B\ncountry a cappella\ncountry adult contemporary\ncountry and western\ncountry and western swing\ncountry ballad\ncountry ballad lounge jazz\ncountry ballad rockabilly\ncountry ballad rockabilly doo-wop\ncountry ballad rockabilly western swing\ncountry ballad, Latin country, western swing\ncountry ballad, alt-country rock\ncountry ballad, bluegrass, cowpunk\ncountry ballad, country-rock\ncountry ballad, rockabilly\ncountry ballad, rockabilly, cinematic orchestral\ncountry ballad, rockabilly, melancholic\ncountry ballad, southern rock\ncountry ballad, traditional pop\ncountry barbershop\ncountry bluegrass\ncountry bluegrass americana\ncountry blues\ncountry blues acoustic blues\ncountry blues folk\ncountry blues gospel\ncountry blues psychedelic rock\ncountry blues rock\ncountry blues rockabilly\ncountry blues-rock\ncountry boogie\ncountry brostep\ncountry children's\ncountry comedy\ncountry crooner\ncountry cumbia\ncountry dance\ncountry dubstep\ncountry duet\ncountry folk\ncountry folk blues rock\ncountry folk hip-hop\ncountry folk honky-tonk\ncountry folk rock\ncountry folk, country rock\ncountry folk, honky-tonk, country-rock\ncountry funk\ncountry funk-pop\ncountry fusion\ncountry gospel\ncountry gospel hip-hop\ncountry gospel novelty\ncountry gospel rock\ncountry gospel rockabilly\ncountry gospel sertanejo\ncountry gospel, Celtic folk, contemporary Christian\ncountry gospel, bluegrass\ncountry hawaiian\ncountry hip-hop\ncountry hoedown\ncountry honky-tonk\ncountry house\ncountry instrumental\ncountry jazz\ncountry march\ncountry metal\ncountry narrative\ncountry noir\ncountry novelty\ncountry parody\ncountry polka\ncountry polka novelty\ncountry polka video game\ncountry pop\ncountry pop rock\ncountry pop, rockabilly\ncountry power ballad\ncountry protest\ncountry ragtime\ncountry rap\ncountry rap acoustic rock\ncountry rap funk pop\ncountry rap indie rock\ncountry rap nu-metal\ncountry rap southern rock\ncountry rap trap\ncountry rap, electronic trap, hardstyle\ncountry rap, party rock\ncountry rap, southern rock\ncountry rap-rock\ncountry reggae\ncountry rock\ncountry rock bluegrass\ncountry rock blues\ncountry rock blues rock\ncountry rock blues swing\ncountry rock boogie-woogie\ncountry rock cumbia\ncountry rock disco-funk\ncountry rock folk punk\ncountry rock forró\ncountry rock funk\ncountry rock funk carioca\ncountry rock funk-disco\ncountry rock future bass\ncountry rock gospel\ncountry rock hard rock\ncountry rock heartland rock\ncountry rock hick-hop\ncountry rock hip-hop\ncountry rock hip-hop electronic\ncountry rock klezmer\ncountry rock metal\ncountry rock norteño\ncountry rock pirate metal\ncountry rock polka\ncountry rock psychedelic\ncountry rock punk\ncountry rock reggae\ncountry rock rockabilly\ncountry rock sertanejo\ncountry rock surf rock\ncountry rock, EDM\ncountry rock, Eastern European folk\ncountry rock, Middle Eastern folk\ncountry rock, Norteño\ncountry rock, Southern hip-hop\ncountry rock, bluegrass\ncountry rock, bluegrass, instrumental\ncountry rock, bluegrass, pirate rock\ncountry rock, boogie-woogie\ncountry rock, electronic dance music\ncountry rock, electronic dance, apocalyptic\ncountry rock, forró\ncountry rock, hard rock\ncountry rock, heavy metal\ncountry rock, honky-tonk blues\ncountry rock, metalcore, rap-metal\ncountry rock, norteño\ncountry rock, polka, novelty\ncountry rock, rockabilly\ncountry rock, rockabilly, French chanson\ncountry rock, rockabilly, Latin rock\ncountry rock, rockabilly, Nederpop\ncountry rock, rockabilly, Norteño\ncountry rock, rockabilly, Tex-Mex\ncountry rock, rockabilly, danseband\ncountry rock, rockabilly, dansktop\ncountry rock, rockabilly, early rock and roll\ncountry rock, rockabilly, honky-tonk\ncountry rock, rockabilly, pub rock\ncountry rock, rockabilly, southern rock\ncountry rock, rockabilly, western swing\ncountry rock, schlager\ncountry rock, southern hip-hop\ncountry rock, southern metal, hard rock\ncountry rock, southern rock\ncountry rock, southern rock, gospel\ncountry rock, swamp rock\ncountry rock, swamp rock, rockabilly\ncountry rock, thrash metal\ncountry rock, western swing\ncountry rockabilly\ncountry rockabilly Latin\ncountry rockabilly bluegrass\ncountry rockabilly hip-hop\ncountry rockabilly novelty\ncountry rockabilly western swing\ncountry satire\ncountry shuffle\ncountry soul\ncountry storytelling\ncountry swing\ncountry synth-pop\ncountry trap\ncountry twang, western swing, rockabilly\ncountry two-step\ncountry waltz\ncountry western\ncountry western swing\ncountry, Hawaiian, ballad\ncountry, bluegrass, classic country\ncountry, bluegrass, gospel\ncountry, lounge, gospel\ncountry-EDM\ncountry-bluegrass\ncountry-blues\ncountry-blues folk\ncountry-blues rock\ncountry-blues rockabilly\ncountry-blues, hard rock\ncountry-blues, southern rock\ncountry-cumbia\ncountry-dance\ncountry-dancehall\ncountry-disco\ncountry-dubstep\ncountry-folk\ncountry-folk Latin\ncountry-folk alt-rock\ncountry-folk ballad\ncountry-folk bluegrass\ncountry-folk blues\ncountry-folk blues reggae\ncountry-folk blues-rock\ncountry-folk chiptune\ncountry-folk cinematic\ncountry-folk cinematic orchestral\ncountry-folk comedy\ncountry-folk comedy rock\ncountry-folk cumbia\ncountry-folk gospel\ncountry-folk heartland rock\ncountry-folk hip-hop\ncountry-folk indie rock\ncountry-folk mariachi\ncountry-folk novelty\ncountry-folk nu-metal\ncountry-folk polka\ncountry-folk pop\ncountry-folk pop-rock\ncountry-folk protest\ncountry-folk rock\ncountry-folk rockabilly\ncountry-folk satire\ncountry-folk soft rock\ncountry-folk southern rock\ncountry-folk synth-pop\ncountry-folk trap\ncountry-folk tropical\ncountry-folk waltz\ncountry-folk, Arabic fusion\ncountry-folk, Irish pub-rock\ncountry-folk, adult contemporary, cinematic\ncountry-folk, alt-rock\ncountry-folk, conscious hip-hop\ncountry-folk, country-rock\ncountry-folk, country-rock, noise-rock\ncountry-folk, country-rock, piano ballad\ncountry-folk, country-rock, southern rock\ncountry-folk, country-rock, swamp rock\ncountry-folk, electro-pop, country-rock\ncountry-folk, garage rock\ncountry-folk, hard rock\ncountry-folk, heartland rock\ncountry-folk, honky-tonk rock\ncountry-folk, indie rock, experimental\ncountry-folk, schlager\ncountry-folk, southern rock\ncountry-folk, southern rock, blues\ncountry-folk, southern rock, blues-rock\ncountry-folk, western swing\ncountry-funk\ncountry-funk hip-hop\ncountry-funk rock\ncountry-gospel\ncountry-gospel children's\ncountry-gospel folk-rock\ncountry-gospel novelty\ncountry-gospel rock\ncountry-gospel rockabilly\ncountry-gospel worship\ncountry-hop\ncountry-house\ncountry-jazz\ncountry-jazz lounge\ncountry-jazz western swing\ncountry-metal\ncountry-noir\ncountry-polka\ncountry-pop\ncountry-pop R&B\ncountry-pop adult contemporary\ncountry-pop beach-rock\ncountry-pop bluegrass\ncountry-pop chiptune\ncountry-pop dance-pop\ncountry-pop doo-wop\ncountry-pop emo-pop\ncountry-pop folk\ncountry-pop future bass\ncountry-pop gospel\ncountry-pop hip-hop\ncountry-pop lounge jazz\ncountry-pop lounge-jazz\ncountry-pop novelty\ncountry-pop orchestral\ncountry-pop rock\ncountry-pop rockabilly\ncountry-pop rockabilly doo-wop\ncountry-pop satire\ncountry-pop schlager\ncountry-pop smooth jazz\ncountry-pop soft rock\ncountry-pop soul\ncountry-pop surf rock\ncountry-pop synth-pop\ncountry-pop trap\ncountry-pop tropical\ncountry-pop tropical folk\ncountry-pop, Nederpop\ncountry-pop, Tejano\ncountry-pop, doo-wop, novelty\ncountry-pop, electro-house\ncountry-pop, festival EDM\ncountry-pop, future bass, EDM\ncountry-pop, pop-punk\ncountry-pop, schlager, Danish Christmas\ncountry-pop, soft rock\ncountry-punk\ncountry-punk rock\ncountry-punk, lo-fi, hip-hop\ncountry-r&b\ncountry-rap\ncountry-rap chill-hop\ncountry-rap chiptune\ncountry-rap fusion\ncountry-rap hick-hop\ncountry-rap lo-fi\ncountry-rap nu-metal\ncountry-rap rock\ncountry-rap trap\ncountry-rap, chiptune, trap\ncountry-rap, nu-metal, hip-hop\ncountry-rap, nu-metal, southern hip-hop\ncountry-rap-rock\ncountry-reggae\ncountry-reggae fusion\ncountry-reggaeton\ncountry-rock\ncountry-rock ballad\ncountry-rock bluegrass\ncountry-rock blues\ncountry-rock blues rock\ncountry-rock blues rockabilly\ncountry-rock blues shuffle\ncountry-rock blues southern rock\ncountry-rock blues-rock\ncountry-rock boogie-woogie\ncountry-rock comedy rock\ncountry-rock dance-pop\ncountry-rock dansband\ncountry-rock disco-funk\ncountry-rock dubstep\ncountry-rock funk-rock\ncountry-rock gospel\ncountry-rock heartland rock\ncountry-rock hip-hop\ncountry-rock metal\ncountry-rock nederpop\ncountry-rock novelty\ncountry-rock nu-metal\ncountry-rock outlaw\ncountry-rock pop\ncountry-rock post-rock\ncountry-rock punk\ncountry-rock rap-rock\ncountry-rock rockabilly\ncountry-rock rockabilly americana\ncountry-rock rockabilly honky-tonk\ncountry-rock rockabilly pub rock\ncountry-rock rockabilly schlager\ncountry-rock rockabilly western swing\ncountry-rock roots-rock\ncountry-rock satire\ncountry-rock sertanejo\ncountry-rock show tune\ncountry-rock southern rock\ncountry-rock spaghetti western\ncountry-rock surf-rock\ncountry-rock trap\ncountry-rock worship\ncountry-rock, Schlager\ncountry-rock, blues, boogie\ncountry-rock, boogie-woogie, rock and roll\ncountry-rock, brostep\ncountry-rock, cinematic, orchestral\ncountry-rock, electronic dance\ncountry-rock, hard rock\ncountry-rock, heavy metal, German rock\ncountry-rock, honky-tonk\ncountry-rock, novelty, Italian\ncountry-rock, nu-metal, hard rock\ncountry-rock, pop-funk, hyperpop\ncountry-rock, progressive house\ncountry-rock, progressive metal\ncountry-rock, rockabilly\ncountry-rock, rockabilly, Latin\ncountry-rock, rockabilly, boogie-woogie\ncountry-rock, rockabilly, gospel\ncountry-rock, rockabilly, levenslied\ncountry-rock, rockabilly, schlager\ncountry-rock, southern rock\ncountry-rockabilly\ncountry-schlager\ncountry-schlager rockabilly\ncountry-soul\ncountry-swing\ncountry-techno\ncountry-trap\ncountry-trap fusion\ncountry-trap hip-hop\ncountry-trap lo-fi\ncountry-trap meme rap\ncountry-trap, Norwegian party\ncountry-western\ncountry-western Latin\ncountry-western bluegrass\ncountry-western blues-rock\ncountry-western chanson\ncountry-western children's\ncountry-western dance-pop\ncountry-western flamenco\ncountry-western folk\ncountry-western hardstyle\ncountry-western hoedown\ncountry-western lounge jazz\ncountry-western lounge-jazz\ncountry-western novelty\ncountry-western rock\ncountry-western rockabilly\ncountry-western satire\ncountry-western sertanejo\ncountry-western surf-rock\ncountry-western swing\ncountry-western, Brazilian, upbeat\ncountry-western, Latin, ballad\ncountry-western, Latin, melancholic\ncountry-western, Schlager\ncountry-western, country-rap\ncountry-western, eurodance\ncountry-western, folk\ncountry-western, folk, bilingual\ncountry-western, folk-rock\ncountry-western, rockabilly, novelty\ncountry-western, schlager\ncowpunk\ncowpunk bluegrass\ncowpunk bluegrass rock\ncowpunk garage rock\ncowpunk hard rock\ncowpunk outlaw country\ncowpunk pirate metal\ncowpunk rock\ncowpunk rockabilly\ncowpunk rockabilly bluegrass\ncowpunk ska-punk\ncowpunk skate punk\ncowpunk southern rock\ncowpunk surf rock\ncowpunk, heavy metal\ncowpunk, southern rock\ncreepy-cute\ncrispică\ncrooner\ncrooner ballad\ncrooner jazz\ncross-cultural hip-hop\ncrossover hip-hop\ncrossover pop ballad\ncrossover rock\ncrossover thrash\ncrossover thrash digital hardcore\ncrossover thrash hardcore punk\ncrossover thrash punk\ncrossover thrash rapcore\ncrossover thrash ska-punk\ncrossover thrash, German rap\ncrossover thrash, rap metal\ncrossover thrash, rap-rock, electronic\ncrunk\ncrunk bounce\ncrunk dancehall\ncrunk dirty south\ncrunk funk\ncrunk hip hop\ncrunk hip-hop\ncrunk hip-house\ncrunk house\ncrunk rap\ncrunk snap\ncrunk trap\ncrunk twerk\ncrunk&B\ncrunk, 8-bit, electronic\ncrunk, Dirty South\ncrunk, Dirty South, Southern hip-hop\ncrunk, G-funk, Southern hip-hop\ncrunk, Memphis rap\ncrunk, Memphis rap, Southern hip-hop\ncrunk, Memphis rap, lo-fi hip hop\ncrunk, R&B, Southern hip-hop\ncrunk, Southern hip-hop\ncrunk, Southern hip-hop, cinematic\ncrunk, Southern hip-hop, retro synth\ncrunk, Southern hip-hop, trap\ncrunk, chiptune, electronic\ncrunk, cinematic synth, dirty south\ncrunk, club rap\ncrunk, club, electronic hip-hop\ncrunk, crunkcore\ncrunk, dirty south\ncrunk, dirty south hip-hop\ncrunk, dirty south, Southern hip-hop\ncrunk, dirty south, hip-hop\ncrunk, dirty south, southern hip-hop\ncrunk, dirty south, synth hip-hop\ncrunk, dirty south, trap\ncrunk, funk, Southern hip-hop\ncrunk, gangsta rap\ncrunk, gangsta rap, Southern hip-hop\ncrunk, go-go, Southern hip-hop\ncrunk, hip hop, latin hip hop\ncrunk, memphis rap\ncrunk, memphis rap, cinematic hip-hop\ncrunk, snap, Southern hip-hop\ncrunk, southern hip hop\ncrunk, southern hip-hop\ncrunk, southern hip-hop, bounce\ncrunk, southern trap\ncrunk, thunk, Southern hip-hop\ncrunkcore\ncrypto-reggaeton\ncrypto-trap\ncuarteto\ncumbia\ncumbia a cappella\ncumbia andean\ncumbia andean folk\ncumbia andina\ncumbia bachata\ncumbia ballad\ncumbia banda\ncumbia barola\ncumbia barulera\ncumbia belica\ncumbia bhangra fusion\ncumbia blues rock\ncumbia bolero\ncumbia boogaloo\ncumbia brass\ncumbia brega\ncumbia cabaret\ncumbia carnaval\ncumbia carnavalera\ncumbia carnavalito\ncumbia carnivalera\ncumbia chacarera\ncumbia charanga\ncumbia chicha\ncumbia children's\ncumbia children's music\ncumbia children's story\ncumbia chiptune\ncumbia chiptune french chanson\ncumbia choro\ncumbia chup-hop\ncumbia cinematic\ncumbia comedy\ncumbia corrido\ncumbia country\ncumbia country rock\ncumbia cristiana\ncumbia descarga\ncumbia devotional\ncumbia digital\ncumbia disco\ncumbia dramática\ncumbia educativa\ncumbia electro\ncumbia electronic\ncumbia electronica\ncumbia electropop\ncumbia electrónica\ncumbia flamenco\ncumbia folk\ncumbia folk-pop\ncumbia folk-rock\ncumbia forró\ncumbia funk\ncumbia funk hip-hop\ncumbia funk rock\ncumbia fusion\ncumbia gaita\ncumbia garage rock\ncumbia gospel\ncumbia guacharaca\ncumbia guapango\ncumbia guaya\ncumbia hip-hop\ncumbia hip-hop revolutionary\ncumbia house\ncumbia huapango\ncumbia huayno\ncumbia indie rock\ncumbia indie-pop\ncumbia jarocha\ncumbia joropo\ncumbia kids\ncumbia lo-fi\ncumbia mambo\ncumbia mariachi\ncumbia melanchólica\ncumbia merengue\ncumbia merengue Latin\ncumbia merengue Latin dance\ncumbia metal\ncumbia minimalera\ncumbia murga\ncumbia narrative\ncumbia norteña\ncumbia norteño\ncumbia norteño funk\ncumbia novelty\ncumbia oud\ncumbia pach\ncumbia pachanga\ncumbia parody\ncumbia polka\ncumbia pop\ncumbia pop norteño\ncumbia pop, Latin pop\ncumbia pop, R&B, sad pop\ncumbia pop, chiptune\ncumbia pop, chiptune, meme culture\ncumbia pop, merengue\ncumbia pop, reggaeton\ncumbia pop, reggaeton, ballad\ncumbia pop, reggaeton, dance\ncumbia pop, reggaeton, rock ballad\ncumbia pop-rock\ncumbia protest\ncumbia psychedelic\ncumbia psychedelic rock\ncumbia punk\ncumbia punk experimental rock\ncumbia punk protest\ncumbia punk rap\ncumbia punk reggaeton\ncumbia punk rock\ncumbia punk rock surf rock\ncumbia punk, rap-rock\ncumbia r-fi\ncumbia ranchera\ncumbia rap\ncumbia rap-rock\ncumbia rave\ncumbia reggae\ncumbia reggae chiptune\ncumbia reggae electronic\ncumbia reggae fusion\ncumbia reggae ska\ncumbia reggaeton\ncumbia reggaeton Latin trap\ncumbia reggaeton rock\ncumbia remix\ncumbia retro\ncumbia revolution\ncumbia rkt\ncumbia rock\ncumbia rock blues\ncumbia rock hip-hop\ncumbia rock punk\ncumbia rock, Latin pop, reggaeton\ncumbia rockabilly\ncumbia rockabilly surf\ncumbia rockabilly surf rock\ncumbia rocksteady\ncumbia romantic\ncumbia romántica\ncumbia rumba\ncumbia salsa\ncumbia salsa bolero\ncumbia salsa reggae\ncumbia samba\ncumbia samba-rock\ncumbia satirical\ncumbia sentimental\ncumbia show tune\ncumbia sierreña\ncumbia sirenera\ncumbia ska\ncumbia ska balkan brass\ncumbia ska fusion\ncumbia ska latin rock\ncumbia ska protest\ncumbia ska protest rock\ncumbia ska punk\ncumbia ska reggae\ncumbia ska rock\ncumbia ska rockabilly\ncumbia ska-punk\ncumbia son cubano\ncumbia son montuno\ncumbia sonidera\ncumbia sonidera reggaeton\ncumbia sonidero\ncumbia soul\ncumbia spiritual\ncumbia surf rock\ncumbia surf rock chiptune\ncumbia swing\ncumbia synth\ncumbia synth-pop\ncumbia synthwave\ncumbia tango\ncumbia tango folk\ncumbia tango fusion\ncumbia tech-house\ncumbia techno\ncumbia theatrical\ncumbia timba\ncumbia tonero\ncumbia trap\ncumbia tropical\ncumbia tropical house\ncumbia tropical pop\ncumbia tumbao\ncumbia urbana\ncumbia vallenato\ncumbia vaquera\ncumbia video game\ncumbia villancico\ncumbia villera\ncumbia villera chiptune\ncumbia villera punk\ncumbia villera punk rock\ncumbia villera rap\ncumbia villera rap-rock\ncumbia villera reggaeton\ncumbia villera rock electronic\ncumbia villera, Latin pop\ncumbia villera, bachata-pop, Latin urban\ncumbia villera, chiptune\ncumbia villera, cumbia romántica\ncumbia villera, dream pop\ncumbia villera, ranchera, Latin pop\ncumbia villera, reggaeton, pop\ncumbia villera, rock, electronic\ncumbia villera, synthwave, emotional pop\ncumbia violesina\ncumbia wapachberas\ncumbia western\ncumbia world music\ncumbia worship\ncumbia, 80s Latin pop\ncumbia, Andean folk\ncumbia, Andean folk, Latin dance\ncumbia, Andean folk, Latin fusion\ncumbia, Andean folk, Latin party\ncumbia, Andean folk, cinematic\ncumbia, Andean fusion, Latin carnival\ncumbia, Andean, folk\ncumbia, Andean, folk fusion\ncumbia, Balkan folk\ncumbia, French chanson, ambient\ncumbia, Halloween, playful\ncumbia, Latin American, Christian\ncumbia, Latin Christian, festive\ncumbia, Latin Christian, upbeat\ncumbia, Latin Christmas\ncumbia, Latin Christmas, festive\ncumbia, Latin Christmas, lo-fi\ncumbia, Latin Christmas, melancholic pop\ncumbia, Latin Christmas, vintage synth\ncumbia, Latin ballad, ambient\ncumbia, Latin ballad, cinematic\ncumbia, Latin comedy, theatrical\ncumbia, Latin dance\ncumbia, Latin dance, bilingual\ncumbia, Latin dance, electronic\ncumbia, Latin dance, world music\ncumbia, Latin folk\ncumbia, Latin folk, Christmas\ncumbia, Latin folk, accordion\ncumbia, Latin folk, children's music\ncumbia, Latin folk, chiptune\ncumbia, Latin folk, comedic\ncumbia, Latin folk, festive\ncumbia, Latin folk, folk rock\ncumbia, Latin folk, gospel\ncumbia, Latin folk, protest song\ncumbia, Latin folk, world music\ncumbia, Latin folk-rock\ncumbia, Latin house\ncumbia, Latin novelty\ncumbia, Latin party, high-energy\ncumbia, Latin pop\ncumbia, Latin pop, cinematic\ncumbia, Latin pop, festive\ncumbia, Latin pop, holiday\ncumbia, Latin pop, quirky\ncumbia, Latin pop, reggaeton\ncumbia, Latin pop, rock\ncumbia, Latin pop, synth\ncumbia, Latin pop-rock\ncumbia, Latin rock\ncumbia, Latin, Balkan brass\ncumbia, Latin, Italian\ncumbia, Latin, carnival\ncumbia, Latin, festive\ncumbia, Latin, novelty\ncumbia, Latin, theatrical\ncumbia, Middle Eastern fusion\ncumbia, Spanish folk\ncumbia, ambient, cinematic\ncumbia, ambient, electronic\ncumbia, andean folk\ncumbia, atmospheric, synth\ncumbia, balkan brass, electronic dance\ncumbia, ballad, Latin\ncumbia, ballad, Spanish folk\ncumbia, ballad, pop\ncumbia, big band, Latin jazz\ncumbia, blues-rock\ncumbia, bolero\ncumbia, bolero, cinematic\ncumbia, bolero, merengue\ncumbia, cabaret, theatrical\ncumbia, carnaval, Andean folk\ncumbia, carnaval, Latin folk\ncumbia, carnavalito, Latin folk\ncumbia, carnival, vintage Latin\ncumbia, cha-cha-chá, Latin dance\ncumbia, chacarera\ncumbia, children's music\ncumbia, children's music, Italian\ncumbia, children's music, Italian folk\ncumbia, children's music, Latin\ncumbia, children's music, Latin American\ncumbia, children's music, Vietnamese\ncumbia, children's music, electronic\ncumbia, children's music, playful\ncumbia, children's music, retro electronic\ncumbia, children's music, retro video game\ncumbia, chiptune\ncumbia, chiptune, Latin ballad\ncumbia, chiptune, Latin pop\ncumbia, chiptune, dance\ncumbia, chiptune, electronic\ncumbia, chiptune, emotional ballad\ncumbia, chiptune, hip hop\ncumbia, chiptune, latin pop\ncumbia, chiptune, lo-fi\ncumbia, chiptune, novelty\ncumbia, chiptune, satirical\ncumbia, chiptune, upbeat\ncumbia, choro, Latin folk\ncumbia, cinematic, Latin\ncumbia, cinematic, Latin pop\ncumbia, cinematic, ambient\ncumbia, cinematic, ballad\ncumbia, cinematic, electronic\ncumbia, cinematic, emotional\ncumbia, cinematic, festive\ncumbia, cinematic, folk\ncumbia, cinematic, melancholic\ncumbia, cinematic, orchestral\ncumbia, cinematic, oud\ncumbia, cinematic, pop\ncumbia, cinematic, sacred\ncumbia, cinematic, spiritual\ncumbia, cinematic, synth\ncumbia, cinematic, theatrical\ncumbia, circus, Halloween\ncumbia, classical, emotional\ncumbia, dance, latin\ncumbia, dembow, electronic\ncumbia, dream pop\ncumbia, dream pop, indie folk\ncumbia, educational, children's music\ncumbia, electronic\ncumbia, electronic, Latin\ncumbia, electronic, Latin dance\ncumbia, electronic, Latin pop\ncumbia, electronic, bilingual\ncumbia, electronic, chiptune\ncumbia, electronic, cinematic\ncumbia, electronic, dance\ncumbia, electronic, devotional\ncumbia, electronic, party\ncumbia, electronic, pop\ncumbia, electronic, reggaeton\ncumbia, electronic, retro\ncumbia, electronic, rock\ncumbia, electronic, satirical\ncumbia, electronic, synth-pop\ncumbia, electronic, world music\ncumbia, emotional ballad\ncumbia, festive, Latin pop\ncumbia, festive, Tamil pop\ncumbia, festive, accordion\ncumbia, festive, children's\ncumbia, festive, christmas\ncumbia, festive, dance\ncumbia, festive, eerie\ncumbia, festive, ethereal\ncumbia, festive, instrumental\ncumbia, festive, melancholic\ncumbia, festive, synth\ncumbia, flamenco, Latin pop\ncumbia, flamenco, cinematic\ncumbia, folk pop, Latin\ncumbia, folk, accordion\ncumbia, folk, electronic\ncumbia, folk, latin\ncumbia, folk, parade\ncumbia, folk, stadium anthem\ncumbia, folk-rock, cinematic\ncumbia, folkloric, ceremonial\ncumbia, forró\ncumbia, forró, Latin folk\ncumbia, forró, dance\ncumbia, forró, devotional\ncumbia, forró, latin dance\ncumbia, forró, party\ncumbia, gospel, Latin pop\ncumbia, hard rock\ncumbia, hip-hop\ncumbia, hip-hop, cinematic\ncumbia, indie rock, Latin rap\ncumbia, j-pop\ncumbia, latin electronic\ncumbia, latin folk\ncumbia, latin folk, cinematic\ncumbia, latin hip-hop, mambo\ncumbia, latin pop\ncumbia, latin pop, 80s synth\ncumbia, latin pop, cinematic\ncumbia, latin pop, dreamy synth\ncumbia, latin pop, retro\ncumbia, latin ska, merengue\ncumbia, latin, brass\ncumbia, latin, dream pop\ncumbia, live performance, romantic ballad\ncumbia, lo-fi, chiptune\ncumbia, lo-fi, electronic\ncumbia, lo-fi, emotional\ncumbia, lo-fi, novelty\ncumbia, mambo, Latin\ncumbia, mambo, Latin jazz\ncumbia, melancholic ballad\ncumbia, melancholic, Christmas\ncumbia, melancholic, atmospheric\ncumbia, melancholic, cinematic\ncumbia, meme music, electronic\ncumbia, merengue\ncumbia, merengue, Latin Christmas\ncumbia, merengue, Latin carnival\ncumbia, merengue, Latin dance\ncumbia, merengue, Latin live\ncumbia, merengue, Latin party\ncumbia, merengue, Latin pop\ncumbia, merengue, dance\ncumbia, merengue, latin dance\ncumbia, merengue, synth pop\ncumbia, merengue, synth-pop\ncumbia, musette, fusion\ncumbia, nerdcore, video game\ncumbia, ney flute, spiritual\ncumbia, norteño\ncumbia, norteño, Latin Christmas\ncumbia, novelty, Italian\ncumbia, novelty, live\ncumbia, novelty, parody\ncumbia, novelty, playful\ncumbia, novelty, synth pop\ncumbia, novelty, upbeat\ncumbia, operatic pop, theatrical\ncumbia, orchestral, Middle Eastern\ncumbia, pasodoble, festive\ncumbia, piano ballad\ncumbia, piano ballad, emotional pop\ncumbia, polka, Italian\ncumbia, polka, R&B\ncumbia, psychedelic, Latin\ncumbia, reggaeton\ncumbia, reggaeton, Latin trap\ncumbia, reggaeton, ballad\ncumbia, reggaeton, electronic\ncumbia, reggaeton, folk\ncumbia, regional Mexican\ncumbia, regional Mexican, Latin Christmas\ncumbia, regional Mexican, Latin fusion\ncumbia, retro Latin pop\ncumbia, retro electronic\ncumbia, retro electronic, Latin pop\ncumbia, retro pop, devotional\ncumbia, retro synth\ncumbia, retro video game\ncumbia, retro, chiptune\ncumbia, retro, dance\ncumbia, retro, electronic\ncumbia, retro, lo-fi\ncumbia, retro, synth\ncumbia, retro, synthwave\ncumbia, retro, video game\ncumbia, retro-electronic\ncumbia, rock and roll, Latin\ncumbia, rock en español\ncumbia, salsa, Latin Christian\ncumbia, salsa, Latin Christmas\ncumbia, salsa, Latin sports anthem\ncumbia, salsa, mambo\ncumbia, salsa, protest\ncumbia, salsa, theatrical\ncumbia, sci-fi, electronic\ncumbia, sci-fi, quirky\ncumbia, sentimental ballad\ncumbia, sentimental waltz\ncumbia, son cubano\ncumbia, soul, live performance\ncumbia, soul, noir\ncumbia, spiritual folk\ncumbia, surf rock, Latin\ncumbia, synth pop, Latin folk\ncumbia, synth, chiptune\ncumbia, synth, latin\ncumbia, synth, latin electronic\ncumbia, synth, lo-fi\ncumbia, synthwave, Latin electronic\ncumbia, synthwave, chiptune\ncumbia, synthwave, latin electronic\ncumbia, synthwave, retro\ncumbia, tejano\ncumbia, theatrical pop\ncumbia, theatrical pop, Spanish\ncumbia, theatrical, cinematic\ncumbia, theatrical, folk\ncumbia, theatrical, folk rock\ncumbia, theatrical, melancholic\ncumbia, tropical, Latin pop\ncumbia, tropical, brass\ncumbia, tropical, pop\ncumbia, vallenato\ncumbia, vallenato, folk\ncumbia, video game, synth pop\ncumbia, video game, upbeat\ncumbia, villancico, Latin American\ncumbia, villancico, Latin Christmas\ncumbia, vintage, library music\ncumbia, vintage, retro\ncumbia, world folk, holiday\ncumbia, world music, Latin\ncumbia, world music, folk\ncumbia-electro\ncumbia-electronica\ncumbia-merengue\ncumbia-metal\ncumbia-polka\ncumbia-pop\ncumbia-pop chillwave\ncumbia-pop chiptune\ncumbia-punk\ncumbia-rap\ncumbia-reggae\ncumbia-reggae chiptune\ncumbia-reggae fusion\ncumbia-reggae, Russian pop\ncumbia-reggae, chiptune, hip hop\ncumbia-reggaeton\ncumbia-reggaeton, gospel, chiptune\ncumbia-rock\ncumbia-rock, theatrical, protest anthem\ncumbia-salsa\ncumbia-sierreño\ncumbia-ska\ncumbia-ska fusion\ncumbia-ska punk\ncumbia-ska rock\ncumbia-sousa\ncumbia-trap\ncute pop\ncyber hip-hop\ncyber metal\ncyber metal chiptune\ncyber metal electronicore\ncyber metal, J-rock\ncyber pop\ncyber trance\ncyber-cumbia\ncyber-dancehall\ncyber-funk\ncyber-funk, baile funk, electronic\ncyber-industrial\ncyber-metal\ncyber-metal, industrial metal, hyperpop\ncyber-noir\ncyber-noir trip-hop\ncyber-pop\ncyber-pop C-pop\ncyber-pop Mandopop\ncyber-pop hardstyle\ncyber-pop j-core\ncyber-pop trap\ncyber-pop, hyperpop, electronic dance\ncyber-punk rock\ncyber-rap\ncyber-reggae\ncyber-reggaeton\ncyber-rock\ncyber-techno\ncyber-trance\ncyber-trap\ncyber-trap chiptune\ncyber-trap hyperpop\ncyber-trap, glitch-hop, hyperpop\ncyber-trap, hyperpop\ncybercore\ncybercore speedcore\ncybercore, happy hardcore\ncybergrind\ncybergrind chiptune metalcore\ncybergrind dubstep metalcore\ncybergrind hyperpop\ncybergrind metalcore\ncybergrind neurofunk\ncybergrind speedcore\ncybergrind, Nintendocore\ncyberpop\ncyberpop chiptune\ncyberpop glitchcore\ncyberpop trap\ncyberpop, hyperpop, industrial dance\ncyberpunk\ncyberpunk C-pop\ncyberpunk EDM\ncyberpunk J-pop\ncyberpunk K-pop\ncyberpunk R&B\ncyberpunk ambient\ncyberpunk ambient trap\ncyberpunk breakbeat\ncyberpunk cabaret\ncyberpunk chiptune\ncyberpunk country\ncyberpunk country rock\ncyberpunk dance-pop\ncyberpunk dancehall\ncyberpunk dream pop\ncyberpunk drum & bass\ncyberpunk drum and bass\ncyberpunk dub\ncyberpunk dubstep\ncyberpunk electro\ncyberpunk electro-funk\ncyberpunk electro-rock\ncyberpunk electronic\ncyberpunk electronic pop\ncyberpunk electronic rock\ncyberpunk electropop\ncyberpunk hardstyle\ncyberpunk hip hop\ncyberpunk hip-hop\ncyberpunk house\ncyberpunk metal\ncyberpunk metalcore\ncyberpunk metalcore chiptune\ncyberpunk metalcore electronicore\ncyberpunk metalcore, nintendocore\ncyberpunk pop\ncyberpunk pop-rock\ncyberpunk power metal\ncyberpunk punk rock\ncyberpunk rap\ncyberpunk reggaeton\ncyberpunk rock\ncyberpunk rock electronicore\ncyberpunk symphonic metal\ncyberpunk synth\ncyberpunk synth-pop\ncyberpunk synth-rock\ncyberpunk synthwave\ncyberpunk techno\ncyberpunk trance\ncyberpunk trancecore\ncyberpunk trap\ncyberpunk trap metal\ncyberpunk, chiptune, trap\ncyberpunk, cinematic, electronic\ncyberpunk, darksynth, EBM\ncyberpunk, darksynth, industrial\ncyberpunk, dubstep, industrial\ncyberpunk, electronic, K-pop\ncyberpunk, electronic, hip hop\ncyberpunk, electronic, rap\ncyberpunk, electronic, synthwave\ncyberpunk, electronic, trap\ncyberpunk, forró, electronic\ncyberpunk, hardstyle, electronic\ncyberpunk, hardstyle, neurofunk\ncyberpunk, industrial hip-hop, glitch-pop\ncyberpunk, industrial rock, EBM\ncyberpunk, industrial techno, darksynth\ncyberpunk, industrial, electronic\ncyberpunk, nu-metal, industrial\ncyberpunk, trap, electronic\ncypher hip-hop\ndabke\ndance\ndance a cappella\ndance bhajan\ndance country\ndance fitness\ndance fusion\ndance hip hop\ndance house\ndance pagode\ndance pop\ndance pop, Brazilian Piseiro\ndance pop, Middle Eastern, emotional\ndance pop, South Asian folk, European folk\ndance rap\ndance rock\ndance, 80s funk, instructional\ndance, Afro-Latin, hip-hop\ndance, Afrobeat, electronic\ndance, East African, Middle Eastern\ndance, J-pop\ndance, Latin, African\ndance, Latin, instructional\ndance, Latin, synth\ndance, Middle Eastern, South Asian\ndance, accordion, party\ndance, brass, Latin\ndance, electronic, Afro-Latin\ndance, electronic, Afrobeat\ndance, electronic, Balkan folk\ndance, electronic, Latin pop\ndance, electronic, Portuguese\ndance, electronic, Sinhala pop\ndance, electronic, South Asian\ndance, electronic, South Indian fusion\ndance, electronic, fitness\ndance, electronic, hip hop\ndance, electronic, instructional\ndance, electronic, klezmer\ndance, electronic, multilingual\ndance, electronic, vocal house\ndance, electronic, vocal percussion\ndance, electronic, world fusion\ndance, folk fusion, Middle Eastern\ndance, funk, early 2000s\ndance, funk, electronic\ndance, novelty, Portuguese\ndance, novelty, chiptune\ndance, percussion, electronic\ndance, retro, afro house\ndance, stadium house, choral\ndance, steel pan, electronic\ndance, steel pan, tropical\ndance, tribal, novelty\ndance, vocal percussion, spoken word\ndance, world fusion, electronic\ndance, zouk, kompa\ndance-funk\ndance-funk house\ndance-funk new jack swing\ndance-funk, new jack swing\ndance-pop\ndance-pop 1960s\ndance-pop 80s\ndance-pop 80s Bollywood\ndance-pop 80s revival\ndance-pop 80s synth-pop\ndance-pop 90s\ndance-pop 90s C-pop Eurodance\ndance-pop 90s house\ndance-pop 90s house Eurodance\ndance-pop 90s house R&B\ndance-pop 90s house UK garage\ndance-pop 90s house dancehall\ndance-pop 90s throwback\ndance-pop Afro-Caribbean\ndance-pop Afro-Cuban\ndance-pop Afro-Latin\ndance-pop Afro-Latin French pop\ndance-pop Afrobeat\ndance-pop Afrobeat French house\ndance-pop Afrobeat Latin\ndance-pop Afrobeat Latin house\ndance-pop Afrobeat Latin pop\ndance-pop Afrobeat Soca\ndance-pop Afrobeat dancehall\ndance-pop Afrobeat gospel\ndance-pop Afrobeat house\ndance-pop Bhajan\ndance-pop Bollywood\ndance-pop Bollywood Eurodance\ndance-pop Bollywood Latin\ndance-pop Bollywood filmi-pop\ndance-pop Bollywood funk\ndance-pop Bollywood-pop\ndance-pop C-pop\ndance-pop C-pop EDM\ndance-pop C-pop Eurodance\ndance-pop C-pop J-pop\ndance-pop C-pop K-pop\ndance-pop C-pop R&B\ndance-pop C-pop folk\ndance-pop C-pop hip-hop\ndance-pop C-pop world music\ndance-pop Celtic\ndance-pop EDM\ndance-pop EDM Bollywood\ndance-pop EDM C-pop\ndance-pop EDM J-pop\ndance-pop EDM K-pop\ndance-pop EDM Latin\ndance-pop EDM Latin house\ndance-pop EDM Latin pop\ndance-pop EDM Mandopop\ndance-pop EDM R&B\ndance-pop EDM V-pop\ndance-pop EDM dancehall\ndance-pop EDM funk\ndance-pop EDM hip-hop\ndance-pop EDM house\ndance-pop EDM reggaeton\ndance-pop EDM synth-pop\ndance-pop Eastern European\ndance-pop Eurodance\ndance-pop European\ndance-pop Europop\ndance-pop French house\ndance-pop Indian\ndance-pop Indian film music\ndance-pop Indian folk\ndance-pop J-Pop\ndance-pop J-pop\ndance-pop J-pop C-pop\ndance-pop J-pop EDM\ndance-pop J-pop Eurobeat\ndance-pop J-pop Eurodance\ndance-pop J-pop K-pop\ndance-pop J-pop Latin\ndance-pop J-pop Latin house\ndance-pop J-pop R&B\ndance-pop J-pop UK garage\ndance-pop J-pop anime\ndance-pop J-pop children's\ndance-pop J-pop chiptune\ndance-pop J-pop funk\ndance-pop J-pop trance\ndance-pop J-pop video game\ndance-pop Javanese pop\ndance-pop K-pop\ndance-pop K-pop C-pop\ndance-pop K-pop EDM\ndance-pop K-pop Eurodance\ndance-pop K-pop J-pop\ndance-pop K-pop Latin\ndance-pop K-pop Latin pop\ndance-pop K-pop Mandopop\ndance-pop K-pop R&B\ndance-pop K-pop T-pop\ndance-pop K-pop UK garage\ndance-pop K-pop disco-funk\ndance-pop K-pop electro house\ndance-pop K-pop funk\ndance-pop K-pop future house\ndance-pop K-pop hip-hop\ndance-pop K-pop house\ndance-pop K-pop moombahton\ndance-pop K-pop nu-disco\ndance-pop K-pop trap\ndance-pop K-pop trot\ndance-pop Latin\ndance-pop Latin Eastern European\ndance-pop Latin Middle Eastern\ndance-pop Latin flamenco\ndance-pop Latin folk\ndance-pop Latin house\ndance-pop Latin pop\ndance-pop Mandopop\ndance-pop Mandopop Eurodance\ndance-pop Mediterranean\ndance-pop R&B\ndance-pop R&B 90s\ndance-pop R&B Afrobeats\ndance-pop R&B New Jack Swing\ndance-pop R&B dancehall\ndance-pop R&B early 2000s pop\ndance-pop R&B funk\ndance-pop R&B gospel\ndance-pop R&B hip-hop\ndance-pop R&B house\ndance-pop R&B trap\ndance-pop R&B tropical house\ndance-pop T-pop\ndance-pop T-pop K-pop\ndance-pop Tibetan\ndance-pop Tibetan pop\ndance-pop Tollywood\ndance-pop UK garage\ndance-pop V-Pop\ndance-pop V-Pop Eurodance\ndance-pop V-pop\ndance-pop Y2K\ndance-pop a cappella\ndance-pop afrobeat\ndance-pop afrobeat dancehall\ndance-pop afrobeat funk\ndance-pop afrobeat tropical\ndance-pop afrobeat tropical house\ndance-pop afrobeats\ndance-pop afrobeats caribbean\ndance-pop afrobeats dancehall\ndance-pop afrobeats french house\ndance-pop afrobeats latin\ndance-pop afrobeats latin pop\ndance-pop afrobeats soca\ndance-pop afrobeats tamil pop\ndance-pop afrobeats tropical house\ndance-pop afrobeats uk garage\ndance-pop afrobeats zouk\ndance-pop anime\ndance-pop arena rock\ndance-pop axé\ndance-pop bachata\ndance-pop ballad\ndance-pop bhajan\ndance-pop bhangra\ndance-pop bhangra Bollywood\ndance-pop bhangra EDM\ndance-pop bhangra bollywood\ndance-pop bhangra edm\ndance-pop bhangra eurodance\ndance-pop bhangra hip-hop\ndance-pop big beat\ndance-pop big room house\ndance-pop boy band\ndance-pop bubblegum hip-hop\ndance-pop bubblegum pop\ndance-pop cabaret\ndance-pop celtic folk\ndance-pop celtic fusion\ndance-pop children's\ndance-pop children's Christian\ndance-pop children's world music\ndance-pop chiptune\ndance-pop chiptune 8-bit\ndance-pop chiptune Bollywood\ndance-pop chiptune Eastern European\ndance-pop chiptune Eastern European folk\ndance-pop chiptune Filipino pop\ndance-pop chiptune Gujarati\ndance-pop chiptune Indian pop\ndance-pop chiptune J-pop\ndance-pop chiptune Latin\ndance-pop chiptune Middle Eastern\ndance-pop chiptune Persian\ndance-pop chiptune South Asian pop\ndance-pop chiptune Southeast Asian\ndance-pop chiptune Tamil Christian pop\ndance-pop chiptune bollywood\ndance-pop chiptune cinematic\ndance-pop chiptune electro-house\ndance-pop chiptune electro-pop\ndance-pop chiptune electropop\ndance-pop chiptune eurodance\ndance-pop chiptune folk\ndance-pop chiptune funk\ndance-pop chiptune happy hardcore\ndance-pop chiptune j-pop\ndance-pop chiptune k-pop\ndance-pop chiptune kids\ndance-pop chiptune lo-fi\ndance-pop chiptune novelty\ndance-pop chiptune reggaeton\ndance-pop chiptune synth-pop\ndance-pop chiptune tropical\ndance-pop cinematic\ndance-pop city pop\ndance-pop city pop funk\ndance-pop classical crossover\ndance-pop classical fusion\ndance-pop country\ndance-pop country hoedown\ndance-pop country polka\ndance-pop country-dance\ndance-pop country-pop\ndance-pop cumbia\ndance-pop dangdut\ndance-pop deep house\ndance-pop deep house Latin pop\ndance-pop deep house nu-disco\ndance-pop deep house reggaeton\ndance-pop deep house tech house\ndance-pop deep house uk garage\ndance-pop dembow\ndance-pop disco Latin\ndance-pop disco funk\ndance-pop disco-funk\ndance-pop electro\ndance-pop electro funk\ndance-pop electro house\ndance-pop electro-funk\ndance-pop electro-funk chiptune\ndance-pop electro-house\ndance-pop electro-house funk\ndance-pop electro-house hip-house\ndance-pop electro-pop\ndance-pop electro-pop K-pop\ndance-pop electro-pop Latin\ndance-pop electro-pop Latin pop\ndance-pop electro-pop commercial house\ndance-pop electro-pop global pop\ndance-pop electro-pop hip-house\ndance-pop electro-pop house\ndance-pop electro-pop nu-disco\ndance-pop electro-pop reggaeton\ndance-pop electronic\ndance-pop electropop\ndance-pop electropop C-pop\ndance-pop electropop Mandopop\ndance-pop electropop R&B\ndance-pop electropop early 2010s R&B\ndance-pop emo-rap\ndance-pop ethnic\ndance-pop ethnic fusion\ndance-pop euro\ndance-pop euro-pop\ndance-pop eurobeat\ndance-pop eurobeat city pop\ndance-pop eurobeat j-pop\ndance-pop eurobeat j-rock\ndance-pop eurobeat k-pop\ndance-pop eurobeat trot\ndance-pop eurodance\ndance-pop eurodance 2000s club\ndance-pop eurodance 90s house\ndance-pop eurodance 90s j-pop\ndance-pop eurodance balkan house\ndance-pop eurodance balkan pop\ndance-pop eurodance bollywood\ndance-pop eurodance c-pop\ndance-pop eurodance cantopop\ndance-pop eurodance chalga\ndance-pop eurodance chiptune\ndance-pop eurodance dancehall\ndance-pop eurodance edm\ndance-pop eurodance filipino pop\ndance-pop eurodance french house\ndance-pop eurodance funk\ndance-pop eurodance gospel house\ndance-pop eurodance happy hardcore\ndance-pop eurodance hardbass\ndance-pop eurodance hip-hop\ndance-pop eurodance hip-house\ndance-pop eurodance house\ndance-pop eurodance israeli pop\ndance-pop eurodance italo dance\ndance-pop eurodance italo disco\ndance-pop eurodance j-pop\ndance-pop eurodance k-pop\ndance-pop eurodance klezmer\ndance-pop eurodance kollywood\ndance-pop eurodance latin\ndance-pop eurodance latin house\ndance-pop eurodance latin pop\ndance-pop eurodance mandopop\ndance-pop eurodance nepali pop\ndance-pop eurodance pop-rap\ndance-pop eurodance reggae\ndance-pop eurodance reggaeton\ndance-pop eurodance slap house\ndance-pop eurodance synth-pop\ndance-pop eurodance t-pop\ndance-pop eurodance tibetan pop\ndance-pop eurodance trance\ndance-pop eurodance trot\ndance-pop eurodance turkish pop\ndance-pop eurodance uk garage\ndance-pop eurodance v-pop\ndance-pop eurovision\ndance-pop fado\ndance-pop fiddle\ndance-pop flamenco\ndance-pop folk\ndance-pop folk country\ndance-pop folk fusion\ndance-pop folk violin\ndance-pop folk-dance\ndance-pop folk-dance fusion\ndance-pop folk-infused\ndance-pop folk-pop\ndance-pop forró\ndance-pop freestyle\ndance-pop freestyle new jack swing\ndance-pop funk\ndance-pop funk Bollywood\ndance-pop funk EDM\ndance-pop funk K-pop\ndance-pop funk Latin\ndance-pop funk R&B\ndance-pop funk breakbeat\ndance-pop funk carioca\ndance-pop funk dancehall\ndance-pop funk disco\ndance-pop funk electro-house\ndance-pop funk gospel\ndance-pop funk hip-hop\ndance-pop funk house\ndance-pop funk latin\ndance-pop funk novelty\ndance-pop funk nu-disco\ndance-pop funk rock\ndance-pop funk world music\ndance-pop funk worldbeat\ndance-pop funk-pop\ndance-pop funk-rock\ndance-pop funkot\ndance-pop funkot dangdut\ndance-pop funkot dangdut koplo\ndance-pop funkot happy hardcore\ndance-pop fusion\ndance-pop future bass\ndance-pop future bass J-pop\ndance-pop future bass K-pop\ndance-pop future bass hyperpop\ndance-pop future bass moombahton\ndance-pop future bass slap house\ndance-pop future bass trap\ndance-pop future bass tropical house\ndance-pop future bass uk garage\ndance-pop future funk city pop\ndance-pop future house\ndance-pop future-bass\ndance-pop glam rock\ndance-pop global\ndance-pop gospel\ndance-pop gospel Caribbean\ndance-pop gospel EDM\ndance-pop gospel R&B\ndance-pop gospel funk\ndance-pop gospel house\ndance-pop gospel j-pop\ndance-pop gospel soul\ndance-pop happy hardcore J-pop\ndance-pop hardbass\ndance-pop hip hop\ndance-pop hip-hop\ndance-pop hip-hop Bollywood\ndance-pop hip-hop EDM\ndance-pop hip-hop J-pop\ndance-pop hip-hop K-pop\ndance-pop hip-hop Latin\ndance-pop hip-hop Mandopop\ndance-pop hip-hop Middle Eastern\ndance-pop hip-hop R&B\ndance-pop hip-hop bhangra\ndance-pop hip-hop breakbeat\ndance-pop hip-hop chiptune\ndance-pop hip-hop dancehall\ndance-pop hip-hop eurodance\ndance-pop hip-hop funk\ndance-pop hip-hop hyperpop\ndance-pop hip-hop trap\ndance-pop hip-hop tropical house\ndance-pop hip-house\ndance-pop hip-house Latin\ndance-pop hip-house dancehall\ndance-pop house\ndance-pop house Latin\ndance-pop house R&B\ndance-pop house UK hip-hop\ndance-pop house afrobeat\ndance-pop house ballroom\ndance-pop house dancehall\ndance-pop house funk\ndance-pop house gospel\ndance-pop house nu-disco\ndance-pop hyperpop\ndance-pop hyperpop C-pop\ndance-pop hyperpop J-pop\ndance-pop hyperpop K-pop\ndance-pop hyperpop eurodance\ndance-pop hyperpop nightcore\ndance-pop hyperpop trap\ndance-pop hyperpop uk garage\ndance-pop hǎnmài\ndance-pop indie rock\ndance-pop italo disco\ndance-pop italo-disco\ndance-pop italo-disco chiptune\ndance-pop italo-disco eurodance\ndance-pop italo-disco funk\ndance-pop italo-disco latin\ndance-pop italo-disco latin pop\ndance-pop italo-disco neapolitan folk\ndance-pop italo-disco synth-pop\ndance-pop j-pop\ndance-pop j-pop anime\ndance-pop j-pop chiptune\ndance-pop j-pop cinematic\ndance-pop j-pop city pop\ndance-pop j-pop early 2000s r&b\ndance-pop j-pop edm\ndance-pop j-pop eurobeat\ndance-pop j-pop eurodance\ndance-pop j-pop funk\ndance-pop j-pop happy hardcore\ndance-pop j-pop hip-hop\ndance-pop j-pop k-pop\ndance-pop j-pop late-90s house\ndance-pop j-pop latin\ndance-pop j-pop r&b\ndance-pop j-pop trance\ndance-pop j-pop video game\ndance-pop j-rock\ndance-pop jazz\ndance-pop jungle\ndance-pop kids\ndance-pop kizomba\ndance-pop kizomba retro-futuristic\ndance-pop klezmer\ndance-pop klezmer middle eastern\ndance-pop kuthu\ndance-pop kuthu cinematic\ndance-pop latin\ndance-pop latin EDM\ndance-pop latin eurodance\ndance-pop latin funk\ndance-pop latin hip-hop\ndance-pop latin house\ndance-pop latin house moombahton\ndance-pop latin pop\ndance-pop latin pop edm\ndance-pop latin pop eurodance\ndance-pop latin pop future bass\ndance-pop latin pop k-pop\ndance-pop latin pop reggaeton\ndance-pop latin r&b\ndance-pop lo-fi\ndance-pop lo-fi hip hop\ndance-pop mandopop\ndance-pop mandopop edm\ndance-pop mandopop electro-pop\ndance-pop manele\ndance-pop maneles\ndance-pop mediterranean\ndance-pop moombahton\ndance-pop moombahton Bollywood\ndance-pop moombahton Latin\ndance-pop moombahton Latin pop\ndance-pop moombahton R&B\ndance-pop moombahton arabic pop\ndance-pop moombahton dancehall\ndance-pop moombahton hip-hop\ndance-pop moombahton latin\ndance-pop moombahton latin house\ndance-pop moombahton latin pop\ndance-pop moombahton reggaeton\ndance-pop moombahton trap\ndance-pop new jack swing\ndance-pop new jack swing funk\ndance-pop new jack swing house\ndance-pop new wave\ndance-pop new-age\ndance-pop novelty\ndance-pop nu-disco\ndance-pop nu-disco city pop\ndance-pop nu-disco funk\ndance-pop nu-disco funk-pop\ndance-pop nu-disco future bass\ndance-pop nu-disco house\ndance-pop nu-disco synth-pop\ndance-pop nu-disco tropical house\ndance-pop nu-metal\ndance-pop orchestral\ndance-pop oriental\ndance-pop pimba\ndance-pop polka\ndance-pop pop-punk\ndance-pop progressive house\ndance-pop reggae dancehall\ndance-pop reggae fusion\ndance-pop reggae house\ndance-pop reggae tropical house\ndance-pop reggae-ska\ndance-pop reggaeton\ndance-pop reggaeton Arabic pop\ndance-pop reggaeton Central Asian\ndance-pop reggaeton EDM\ndance-pop reggaeton Latin hip-hop\ndance-pop reggaeton Latin house\ndance-pop reggaeton Latin pop\ndance-pop reggaeton Mandopop\ndance-pop reggaeton Mediterranean\ndance-pop reggaeton Middle Eastern\ndance-pop reggaeton Middle Eastern pop\ndance-pop reggaeton Punjabi\ndance-pop reggaeton afrobeat\ndance-pop reggaeton baile funk\ndance-pop reggaeton balkan pop\ndance-pop reggaeton chiptune\ndance-pop reggaeton dancehall\ndance-pop reggaeton edm\ndance-pop reggaeton flamenco\ndance-pop reggaeton french house\ndance-pop reggaeton funk carioca\ndance-pop reggaeton future\ndance-pop reggaeton hip-hop\ndance-pop reggaeton kids\ndance-pop reggaeton kuduro\ndance-pop reggaeton latin pop\ndance-pop reggaeton moombahton\ndance-pop reggaeton oriental\ndance-pop reggaeton tropical\ndance-pop reggaeton tropical house\ndance-pop reggaeton worldbeat\ndance-pop reggaeton-lite\ndance-pop retro\ndance-pop retro funk\ndance-pop retro surf-rock\ndance-pop retro-funk\ndance-pop retro-futuristic\ndance-pop rock\ndance-pop rockabilly\ndance-pop samba\ndance-pop samba children's music\ndance-pop satire\ndance-pop schlager\ndance-pop sea shanty\ndance-pop slap house\ndance-pop slap house deep house\ndance-pop soca\ndance-pop soca tropical\ndance-pop soul\ndance-pop stadium rock\ndance-pop synth-pop\ndance-pop tango\ndance-pop techno\ndance-pop trance\ndance-pop trance J-pop\ndance-pop trap\ndance-pop trap moombahton\ndance-pop tribal\ndance-pop tribal house\ndance-pop tropical\ndance-pop tropical house\ndance-pop tropical house EDM\ndance-pop tropical house K-pop\ndance-pop tropical house afrobeat\ndance-pop tropical house afrobeats\ndance-pop tropical house freestyle\ndance-pop tropical house funk\ndance-pop tropical house future bass\ndance-pop tropical house moombahton\ndance-pop tropical house reggaeton\ndance-pop tropical house soca\ndance-pop tropical house uk garage\ndance-pop trot\ndance-pop trot eurodance\ndance-pop uk garage\ndance-pop uk garage future bass\ndance-pop vaporwave\ndance-pop world\ndance-pop world fusion\ndance-pop world music\ndance-pop worldbeat\ndance-pop worldbeat funk\ndance-pop worldbeat gospel\ndance-pop worldbeat reggae\ndance-pop zoubk afrobeats\ndance-pop zoubou\ndance-pop zouk caribbean\ndance-pop zouk kizomba\ndance-pop zouk r&b\ndance-pop zouk soca\ndance-pop, 80s Bollywood, retro\ndance-pop, 80s house, Italo disco\ndance-pop, 80s pop, South Asian\ndance-pop, 80s rock, Latin pop\ndance-pop, 80s synth-funk, Bhangra\ndance-pop, 80s synth-pop\ndance-pop, 80s synth-pop, Bollywood\ndance-pop, 80s synth-pop, Bollywood disco\ndance-pop, 80s synth-pop, Hi-NRG\ndance-pop, 80s synth-pop, Latin pop\ndance-pop, 80s synth-pop, new jack swing\ndance-pop, 80s, South Asian\ndance-pop, 80s, tropical\ndance-pop, 90s Bollywood, Eurodance\ndance-pop, 90s Bollywood, retro\ndance-pop, 90s Bollywood, retro South Asian\ndance-pop, 90s Eurodance\ndance-pop, 90s Eurodance, Arabic pop\ndance-pop, 90s Eurodance, Bollywood\ndance-pop, 90s Eurodance, C-pop\ndance-pop, 90s Eurodance, Christian\ndance-pop, 90s Eurodance, Christmas\ndance-pop, 90s Eurodance, City Pop\ndance-pop, 90s Eurodance, Czech\ndance-pop, 90s Eurodance, Filipino\ndance-pop, 90s Eurodance, Hi-NRG\ndance-pop, 90s Eurodance, Israeli\ndance-pop, 90s Eurodance, Mandopop\ndance-pop, 90s Eurodance, Russian pop\ndance-pop, 90s Eurodance, Thai pop\ndance-pop, 90s Eurodance, Tollywood filmi\ndance-pop, 90s Eurodance, Turkish\ndance-pop, 90s Eurodance, V-Pop\ndance-pop, 90s Eurodance, bilingual\ndance-pop, 90s Eurodance, children's music\ndance-pop, 90s Eurodance, festive\ndance-pop, 90s Eurodance, synthwave\ndance-pop, 90s J-pop, City Pop\ndance-pop, 90s J-pop, anime theme\ndance-pop, 90s Mandopop, funk\ndance-pop, 90s R&B\ndance-pop, 90s R&B, house\ndance-pop, 90s UK garage, 2-step\ndance-pop, 90s eurodance, Sinhala pop\ndance-pop, 90s house\ndance-pop, 90s house, Latin\ndance-pop, 90s house, R&B\ndance-pop, 90s house, bilingual\ndance-pop, 90s house, breakbeat\ndance-pop, 90s house, cinematic\ndance-pop, 90s house, diva house\ndance-pop, 90s house, eurodance\ndance-pop, 90s house, funk\ndance-pop, 90s house, gospel\ndance-pop, 90s house, hip-house\ndance-pop, 90s house, novelty\ndance-pop, 90s kids\ndance-pop, 90s pop, R&B\ndance-pop, 90s pop, South Indian pop\ndance-pop, 90s pop, festive\ndance-pop, 90s rave, video game\ndance-pop, 90s, Bollywood\ndance-pop, 90s, South Asian\ndance-pop, 90s, Southeast Asian pop\ndance-pop, Afrobeat, Brazilian\ndance-pop, Afrobeat, dancehall\ndance-pop, Afrobeats, tropical house\ndance-pop, Anatolian, hip-hop\ndance-pop, Arabic fusion, EDM\ndance-pop, Arabic fusion, cinematic\ndance-pop, Arabic pop, French rap\ndance-pop, Arabic pop, hip-hop\ndance-pop, Arabic pop, summer vibe\ndance-pop, Arabic, electronic\ndance-pop, Armenian folk\ndance-pop, Azerbaijani folk\ndance-pop, Azerbaijani folk, Turkish folk\ndance-pop, Azerbaijani folk, electronic\ndance-pop, Azerbaijani folk, moombahton\ndance-pop, Azerbaijani fusion\ndance-pop, Azerbaijani pop, Turkish pop\ndance-pop, Azerbaijani, EDM\ndance-pop, Azerbaijani, Turkish\ndance-pop, Balkan brass\ndance-pop, Balkan brass, folk-pop\ndance-pop, Balkan folk\ndance-pop, Balkan folk, Eurodance\ndance-pop, Balkan folk, Klezmer\ndance-pop, Balkan folk, Romani\ndance-pop, Balkan folk, cinematic\ndance-pop, Balkan folk, electronic\ndance-pop, Balkan folk, house\ndance-pop, Balkan fusion\ndance-pop, Balkan house\ndance-pop, Balkan house, Latin house\ndance-pop, Balkan pop\ndance-pop, Balkan pop, EDM\ndance-pop, Balkan pop, Gipsy-pop\ndance-pop, Balkan pop, electronic\ndance-pop, Balkan, Eastern European\ndance-pop, Balkan, Eurodance\ndance-pop, Balkan, Klezmer\ndance-pop, Balkan, Latin\ndance-pop, Balkan, Middle Eastern\ndance-pop, Balkan, cinematic\ndance-pop, Balkan, electronic\ndance-pop, Balkan, gypsy-punk\ndance-pop, Balkan, klezmer\ndance-pop, Balkan, reggaeton\ndance-pop, Balkan, trap\ndance-pop, Balkan-inspired, electronic\ndance-pop, Balkan-pop, klezmer\ndance-pop, Bhangra, Bollywood\ndance-pop, Bhangra, Desi pop\ndance-pop, Bhangra, electronic\ndance-pop, Bhojpuri folk\ndance-pop, Bhojpuri, electronic\ndance-pop, Bollywood\ndance-pop, Bollywood pop, funk\ndance-pop, Bollywood pop, retro\ndance-pop, Bollywood, 2000s\ndance-pop, Bollywood, 80s pop\ndance-pop, Bollywood, 90s\ndance-pop, Bollywood, 90s fusion\ndance-pop, Bollywood, Bhangra\ndance-pop, Bollywood, Bhojpuri\ndance-pop, Bollywood, Christmas\ndance-pop, Bollywood, EDM\ndance-pop, Bollywood, Eastern European\ndance-pop, Bollywood, Eurodance\ndance-pop, Bollywood, Latin\ndance-pop, Bollywood, Latin fusion\ndance-pop, Bollywood, Middle Eastern\ndance-pop, Bollywood, Middle Eastern fusion\ndance-pop, Bollywood, Punjabi pop\ndance-pop, Bollywood, South Asian\ndance-pop, Bollywood, South Indian\ndance-pop, Bollywood, South Indian film music\ndance-pop, Bollywood, Telugu Christian\ndance-pop, Bollywood, children's\ndance-pop, Bollywood, children's music\ndance-pop, Bollywood, chiptune\ndance-pop, Bollywood, dancehall\ndance-pop, Bollywood, early 2000s\ndance-pop, Bollywood, electronic\ndance-pop, Bollywood, festive\ndance-pop, Bollywood, global fusion\ndance-pop, Bollywood, hip hop\ndance-pop, Bollywood, hip-hop\ndance-pop, Bollywood, hyperpop\ndance-pop, Bollywood, moombahton\ndance-pop, Bollywood, novelty\ndance-pop, Bollywood, reggaeton\ndance-pop, Bollywood, retro\ndance-pop, Bollywood, retro-futuristic\ndance-pop, Bollywood, trance\ndance-pop, Bollywood, upbeat\ndance-pop, Bollywood, world music\ndance-pop, Bollywood-pop\ndance-pop, Bollywood-pop, Eurodance\ndance-pop, Brazilian funk\ndance-pop, Brazilian funk, EDM\ndance-pop, Brazilian funk, R&B\ndance-pop, Brazilian funk, children's music\ndance-pop, Brazilian funk, deep house\ndance-pop, Brazilian funk, house\ndance-pop, Brazilian pop, house\ndance-pop, Brazilian, 90s\ndance-pop, Brazilian, 90s Eurodance\ndance-pop, Brazilian, Christian\ndance-pop, Brazilian, EDM\ndance-pop, Brazilian, Eurodance\ndance-pop, Brazilian, Hi-NRG\ndance-pop, Brazilian, Latin\ndance-pop, Brazilian, Y2K\ndance-pop, Brazilian, children's\ndance-pop, Brazilian, electronic\ndance-pop, Brazilian, funk\ndance-pop, Brazilian, futuristic\ndance-pop, Brazilian, house\ndance-pop, Brazilian, late-90s house\ndance-pop, Brazilian, pop-funk\ndance-pop, Brazilian, reggae\ndance-pop, Brazilian, retro\ndance-pop, Brazilian, upbeat\ndance-pop, C-pop\ndance-pop, C-pop, Cantopop\ndance-pop, C-pop, EDM\ndance-pop, C-pop, Eurodance\ndance-pop, C-pop, J-pop\ndance-pop, C-pop, K-pop\ndance-pop, C-pop, chiptune\ndance-pop, C-pop, club-rap\ndance-pop, C-pop, dancehall\ndance-pop, C-pop, electronic\ndance-pop, C-pop, festive\ndance-pop, C-pop, future pop\ndance-pop, C-pop, happy hardcore\ndance-pop, C-pop, hyperpop\ndance-pop, C-pop, mai tledian\ndance-pop, C-pop, pop-rap\ndance-pop, C-pop, video game music\ndance-pop, Cantopop, hip-hop\ndance-pop, Caribbean, quirky\ndance-pop, Caucasian folk\ndance-pop, Caucasian folk, electronic\ndance-pop, Central Asian\ndance-pop, Central Asian folk\ndance-pop, Central Asian folk, electronic\ndance-pop, Central Asian folk, rock\ndance-pop, Central Asian fusion\ndance-pop, Central Asian pop\ndance-pop, Central Asian pop, early 2000s\ndance-pop, Central Asian pop, rock\ndance-pop, Central Asian, Bollywood\ndance-pop, Central Asian, Eastern European\ndance-pop, Central Asian, Eurodance\ndance-pop, Central Asian, Latin\ndance-pop, Central Asian, Middle Eastern\ndance-pop, Central Asian, Turkish\ndance-pop, Central Asian, accordion\ndance-pop, Central Asian, atmospheric\ndance-pop, Central Asian, chiptune\ndance-pop, Central Asian, cinematic\ndance-pop, Central Asian, dramatic\ndance-pop, Central Asian, early 2000s\ndance-pop, Central Asian, electronic\ndance-pop, Central Asian, emotional\ndance-pop, Central Asian, emotional pop\ndance-pop, Central Asian, emotive\ndance-pop, Central Asian, folk-dance\ndance-pop, Central Asian, folk-dance fusion\ndance-pop, Central Asian, folk-electronic\ndance-pop, Central Asian, folk-pop\ndance-pop, Central Asian, glitch\ndance-pop, Central Asian, hip-hop\ndance-pop, Central Asian, house\ndance-pop, Central Asian, lo-fi\ndance-pop, Central Asian, modern pop\ndance-pop, Central Asian, oud\ndance-pop, Central Asian, pop\ndance-pop, Central Asian, retro synth\ndance-pop, Central Asian, synth\ndance-pop, Central Asian, synth folk\ndance-pop, Central Asian, synth funk\ndance-pop, Central Asian, synth-driven\ndance-pop, Central Asian, synth-funk\ndance-pop, Central Asian, synth-pop\ndance-pop, Central Asian, synthwave\ndance-pop, Central Asian, upbeat\ndance-pop, Chinese MC, anthemic\ndance-pop, Chinese New Year, Eurodance\ndance-pop, Chinese New Year, electronic\ndance-pop, Chinese New Year, festive\ndance-pop, Chinese New Year, late-90s pop\ndance-pop, Chinese folk\ndance-pop, Chinese, Mai Tledian\ndance-pop, Christian praise, South Indian\ndance-pop, Christian, EDM\ndance-pop, Christian, reggaeton\ndance-pop, Christmas, Eurodance\ndance-pop, Christmas, summer\ndance-pop, City Pop, 90s Eurodance\ndance-pop, City Pop, 90s J-pop\ndance-pop, City Pop, Eurobeat\ndance-pop, City Pop, retro\ndance-pop, EDM\ndance-pop, EDM, Arabic pop\ndance-pop, EDM, Balkan\ndance-pop, EDM, Balkan fusion\ndance-pop, EDM, Balkan pop\ndance-pop, EDM, Bhangra\ndance-pop, EDM, Bollywood\ndance-pop, EDM, Brazilian funk\ndance-pop, EDM, C-pop\ndance-pop, EDM, Central Asian\ndance-pop, EDM, Central Asian pop\ndance-pop, EDM, Chinese New Year\ndance-pop, EDM, Eastern European\ndance-pop, EDM, Eurodance\ndance-pop, EDM, Filipino\ndance-pop, EDM, German pop\ndance-pop, EDM, Greek pop\ndance-pop, EDM, Hindi pop\ndance-pop, EDM, Indian fusion\ndance-pop, EDM, Indonesian\ndance-pop, EDM, Israeli\ndance-pop, EDM, Italian pop\ndance-pop, EDM, J-pop\ndance-pop, EDM, K-pop\ndance-pop, EDM, Kannada pop\ndance-pop, EDM, Latin\ndance-pop, EDM, Latin house\ndance-pop, EDM, Latin pop\ndance-pop, EDM, Mandopop\ndance-pop, EDM, Middle Eastern\ndance-pop, EDM, Middle Eastern fusion\ndance-pop, EDM, Mizrahi\ndance-pop, EDM, Mongolian folk\ndance-pop, EDM, Mongolian pop\ndance-pop, EDM, Nepali\ndance-pop, EDM, Persian pop\ndance-pop, EDM, Punjabi\ndance-pop, EDM, R&B\ndance-pop, EDM, Rai\ndance-pop, EDM, Romanian\ndance-pop, EDM, Romanian pop\ndance-pop, EDM, Russian\ndance-pop, EDM, Russian folk\ndance-pop, EDM, Russian pop\ndance-pop, EDM, Russian vocal\ndance-pop, EDM, Scandinavian pop\ndance-pop, EDM, South Asian\ndance-pop, EDM, South Asian pop\ndance-pop, EDM, South Indian\ndance-pop, EDM, South Indian film music\ndance-pop, EDM, Spanish-style\ndance-pop, EDM, Tamil\ndance-pop, EDM, Turkish pop\ndance-pop, EDM, UK garage\ndance-pop, EDM, Ukrainian pop\ndance-pop, EDM, anthemic\ndance-pop, EDM, atmospheric\ndance-pop, EDM, bilingual\ndance-pop, EDM, children's\ndance-pop, EDM, chiptune\ndance-pop, EDM, cinematic\ndance-pop, EDM, dancehall\ndance-pop, EDM, electronic\ndance-pop, EDM, empowering\ndance-pop, EDM, festival\ndance-pop, EDM, folk-pop\ndance-pop, EDM, future bass\ndance-pop, EDM, global pop\ndance-pop, EDM, gospel\ndance-pop, EDM, hardstyle\ndance-pop, EDM, high-energy\ndance-pop, EDM, high-gloss\ndance-pop, EDM, hip-hop\ndance-pop, EDM, hip-house\ndance-pop, EDM, holiday\ndance-pop, EDM, house\ndance-pop, EDM, hyperpop\ndance-pop, EDM, lo-fi\ndance-pop, EDM, moombahton\ndance-pop, EDM, multilingual\ndance-pop, EDM, nightcore\ndance-pop, EDM, oriental pop\ndance-pop, EDM, oriental synth\ndance-pop, EDM, pop\ndance-pop, EDM, pop-R&B\ndance-pop, EDM, progressive house\ndance-pop, EDM, reggaeton\ndance-pop, EDM, slap house\ndance-pop, EDM, synth brass\ndance-pop, EDM, synth-pop\ndance-pop, EDM, trance\ndance-pop, EDM, trap\ndance-pop, EDM, tropical house\ndance-pop, EDM, upbeat\ndance-pop, EDM, uplifting\ndance-pop, EDM, world fusion\ndance-pop, EDM, world music\ndance-pop, Eastern European\ndance-pop, Eastern European folk\ndance-pop, Eastern European folk, Caucasian folk\ndance-pop, Eastern European folk, Central Asian folk\ndance-pop, Eastern European folk, Turkish folk\ndance-pop, Eastern European folk, electronic\ndance-pop, Eastern European folk, house\ndance-pop, Eastern European pop, Azerbaijani pop\ndance-pop, Eastern European pop, Caucasian pop\ndance-pop, Eastern European pop, Turkish pop\ndance-pop, Eastern European, Armenian\ndance-pop, Eastern European, Central Asian\ndance-pop, Eastern European, Latin\ndance-pop, Eastern European, Middle Eastern\ndance-pop, Eastern European, Turkish\ndance-pop, Eastern European, Turkish folk\ndance-pop, Eastern European, accordion\ndance-pop, Eastern European, cinematic\ndance-pop, Eastern European, electronic\ndance-pop, Eastern European, emotive\ndance-pop, Eastern European, festive\ndance-pop, Eastern European, flamenco\ndance-pop, Eastern European, house\ndance-pop, Eastern European, melancholic\ndance-pop, Eastern European, synth\ndance-pop, Eastern European, synth folk\ndance-pop, Eastern European, synth-pop\ndance-pop, Eastern European, synthwave\ndance-pop, Eurobeat, 90s J-pop\ndance-pop, Eurobeat, C-pop\ndance-pop, Eurobeat, Cantopop\ndance-pop, Eurobeat, City Pop\ndance-pop, Eurobeat, J-pop\ndance-pop, Eurobeat, children's music\ndance-pop, Eurobeat, trance\ndance-pop, Eurobeat, video game music\ndance-pop, Eurodance\ndance-pop, Eurodance, 2000s\ndance-pop, Eurodance, 90s\ndance-pop, Eurodance, 90s house\ndance-pop, Eurodance, Arabic pop\ndance-pop, Eurodance, Azerbaijani folk\ndance-pop, Eurodance, Bollywood\ndance-pop, Eurodance, Brazilian funk\ndance-pop, Eurodance, C-pop\ndance-pop, Eurodance, Cantopop\ndance-pop, Eurodance, Central Asian\ndance-pop, Eurodance, Central Asian pop\ndance-pop, Eurodance, Chinese\ndance-pop, Eurodance, Chinese pop\ndance-pop, Eurodance, Dangdut\ndance-pop, Eurodance, Dangdut Koplo\ndance-pop, Eurodance, Filipino\ndance-pop, Eurodance, Hi-NRG\ndance-pop, Eurodance, Hokkien pop\ndance-pop, Eurodance, Indian pop\ndance-pop, Eurodance, Indonesian pop\ndance-pop, Eurodance, Israeli\ndance-pop, Eurodance, Israeli pop\ndance-pop, Eurodance, Italo disco\ndance-pop, Eurodance, J-pop\ndance-pop, Eurodance, K-pop\ndance-pop, Eurodance, Kollywood\ndance-pop, Eurodance, Latin house\ndance-pop, Eurodance, Latin pop\ndance-pop, Eurodance, Mandopop\ndance-pop, Eurodance, Middle Eastern\ndance-pop, Eurodance, Middle Eastern fusion\ndance-pop, Eurodance, Middle Eastern pop\ndance-pop, Eurodance, Mizrahi\ndance-pop, Eurodance, Nepali\ndance-pop, Eurodance, North African pop\ndance-pop, Eurodance, Romanian\ndance-pop, Eurodance, Russian\ndance-pop, Eurodance, South Indian\ndance-pop, Eurodance, South Indian film music\ndance-pop, Eurodance, Thai pop\ndance-pop, Eurodance, Tibetan pop\ndance-pop, Eurodance, Tollywood\ndance-pop, Eurodance, Turkish\ndance-pop, Eurodance, Turkish pop\ndance-pop, Eurodance, Uzbek\ndance-pop, Eurodance, V-Pop\ndance-pop, Eurodance, Vietnamese pop\ndance-pop, Eurodance, anthemic\ndance-pop, Eurodance, bilingual\ndance-pop, Eurodance, children's\ndance-pop, Eurodance, children's music\ndance-pop, Eurodance, chiptune\ndance-pop, Eurodance, dancehall\ndance-pop, Eurodance, folk-pop\ndance-pop, Eurodance, happy hardcore\ndance-pop, Eurodance, novelty\ndance-pop, Eurodance, reggae fusion\ndance-pop, Eurodance, retro\ndance-pop, Eurodance, trance\ndance-pop, Filipino pop\ndance-pop, Filipino pop, hip-hop\ndance-pop, Filipino, future house\ndance-pop, Filipino, late-90s\ndance-pop, Filipino, world music\ndance-pop, French Caribbean, retro\ndance-pop, French chanson, Turkish pop\ndance-pop, French house, nu-disco\ndance-pop, French pop, funk\ndance-pop, French, hip-hop\ndance-pop, German hip-hop, vaporwave\ndance-pop, Greek Laïko, EDM\ndance-pop, Greek Laïko, Europop\ndance-pop, Greek folk\ndance-pop, Greek folk, electronic\ndance-pop, Greek fusion\ndance-pop, Greek influence\ndance-pop, Greek, Europop\ndance-pop, Greek, Latin\ndance-pop, Greek, electronic\ndance-pop, Halloween, theatrical\ndance-pop, Hi-NRG\ndance-pop, Hi-NRG, Italo disco\ndance-pop, Hi-NRG, camp\ndance-pop, Hi-NRG, electronic\ndance-pop, Hungarian folk\ndance-pop, Hungarian folk, electronic\ndance-pop, Indian Christian, devotional\ndance-pop, Indian bhajan, electronic\ndance-pop, Indian classical, cinematic\ndance-pop, Indian classical, synthwave\ndance-pop, Indian devotional\ndance-pop, Indian devotional, electronic\ndance-pop, Indian devotional, modern bhajan\ndance-pop, Indian film music\ndance-pop, Indian film music, retro-futuristic\ndance-pop, Indian folk, electronic\ndance-pop, Indian folk, film music\ndance-pop, Indian fusion\ndance-pop, Indian fusion, cinematic\ndance-pop, Indian fusion, electronic\ndance-pop, Indian pop, EDM\ndance-pop, Indian pop, Sinhala pop\ndance-pop, Indian pop, South Indian\ndance-pop, Indian pop, electronic\ndance-pop, Indian pop, folk fusion\ndance-pop, Indian pop, hip-hop\ndance-pop, Indian, Bollywood\ndance-pop, Indian, EDM\ndance-pop, Indian, Eurodance\ndance-pop, Indian, electronic\ndance-pop, Indian, retro\ndance-pop, Italian folk\ndance-pop, Italian folk, reggaeton\ndance-pop, Italian hip-hop\ndance-pop, Italian, Middle Eastern\ndance-pop, Italian, Neapolitan\ndance-pop, Italo dance, children's music\ndance-pop, Italo disco, 90s house\ndance-pop, Italo disco, Hi-NRG\ndance-pop, Italo disco, South Asian pop\ndance-pop, Italo disco, early house\ndance-pop, Italo disco, new wave\ndance-pop, Italo disco, retro\ndance-pop, Italo disco, retro synth\ndance-pop, Italo disco, retro-futuristic\ndance-pop, Italo disco, synth-pop\ndance-pop, Italo-disco\ndance-pop, Italo-disco, Bollywood\ndance-pop, Italo-disco, Christmas\ndance-pop, Italo-disco, Eurodance\ndance-pop, Italo-disco, children's music\ndance-pop, Italo-disco, funk\ndance-pop, J-Pop, K-Pop\ndance-pop, J-pop\ndance-pop, J-pop, Brazilian funk\ndance-pop, J-pop, C-pop\ndance-pop, J-pop, Christmas\ndance-pop, J-pop, City Pop\ndance-pop, J-pop, Eurobeat\ndance-pop, J-pop, Eurodance\ndance-pop, J-pop, Filipino\ndance-pop, J-pop, French\ndance-pop, J-pop, German\ndance-pop, J-pop, Indonesian pop\ndance-pop, J-pop, Italian\ndance-pop, J-pop, K-pop\ndance-pop, J-pop, Latin pop\ndance-pop, J-pop, Russian\ndance-pop, J-pop, UK garage\ndance-pop, J-pop, anime\ndance-pop, J-pop, anime theme\ndance-pop, J-pop, breakbeat\ndance-pop, J-pop, children's music\ndance-pop, J-pop, chiptune\ndance-pop, J-pop, city pop\ndance-pop, J-pop, festive\ndance-pop, J-pop, funk\ndance-pop, J-pop, future bass\ndance-pop, J-pop, futuristic\ndance-pop, J-pop, happy hardcore\ndance-pop, J-pop, hip-hop\ndance-pop, J-pop, hip-house\ndance-pop, J-pop, hyperpop\ndance-pop, J-pop, kawaii future bass\ndance-pop, J-pop, nightcore\ndance-pop, J-pop, nu-disco\ndance-pop, J-pop, rock\ndance-pop, J-pop, trance\ndance-pop, J-pop, video game\ndance-pop, J-pop, video game music\ndance-pop, J-rock\ndance-pop, J-rock, nu-metal\ndance-pop, K-Pop\ndance-pop, K-Pop, J-Pop\ndance-pop, K-pop\ndance-pop, K-pop, C-pop\ndance-pop, K-pop, Cantopop\ndance-pop, K-pop, Christmas\ndance-pop, K-pop, EDM\ndance-pop, K-pop, Eurobeat\ndance-pop, K-pop, Eurodance\ndance-pop, K-pop, Indonesian pop\ndance-pop, K-pop, J-pop\ndance-pop, K-pop, Latin pop\ndance-pop, K-pop, Middle Eastern\ndance-pop, K-pop, Moombahton\ndance-pop, K-pop, R&B\ndance-pop, K-pop, Russian pop\ndance-pop, K-pop, T-pop\ndance-pop, K-pop, UK garage\ndance-pop, K-pop, Y2K\ndance-pop, K-pop, boy band\ndance-pop, K-pop, children's\ndance-pop, K-pop, children's music\ndance-pop, K-pop, early 2000s\ndance-pop, K-pop, electronic\ndance-pop, K-pop, electropop\ndance-pop, K-pop, eurodance\ndance-pop, K-pop, festive\ndance-pop, K-pop, funk\ndance-pop, K-pop, future bass\ndance-pop, K-pop, future house\ndance-pop, K-pop, hardstyle\ndance-pop, K-pop, hip-hop\ndance-pop, K-pop, hyperpop\ndance-pop, K-pop, late-90s\ndance-pop, K-pop, moombahton\ndance-pop, K-pop, new jack swing\ndance-pop, K-pop, retro\ndance-pop, K-pop, retro synth\ndance-pop, K-pop, trap\ndance-pop, K-pop, trot\ndance-pop, Kazakh folk\ndance-pop, Kazakh pop\ndance-pop, Kazakh, upbeat\ndance-pop, Kollywood, South Indian\ndance-pop, Kollywood, Tamil Christian\ndance-pop, Kollywood, Tamil pop\ndance-pop, Kurdish, electronic\ndance-pop, Latin EDM\ndance-pop, Latin cumbia, children's music\ndance-pop, Latin cumbia, novelty\ndance-pop, Latin electronic\ndance-pop, Latin freestyle\ndance-pop, Latin funk\ndance-pop, Latin funk, Brazilian funk\ndance-pop, Latin funk, C-pop\ndance-pop, Latin funk, Mandarin pop\ndance-pop, Latin hip-hop\ndance-pop, Latin hip-hop, German hip-hop\ndance-pop, Latin house\ndance-pop, Latin house, 2000s club\ndance-pop, Latin house, Balkan house\ndance-pop, Latin house, Bollywood pop\ndance-pop, Latin house, Eurodance\ndance-pop, Latin house, ambient\ndance-pop, Latin house, dancehall\ndance-pop, Latin house, electro\ndance-pop, Latin house, festival\ndance-pop, Latin house, moombahton\ndance-pop, Latin house, reggaeton\ndance-pop, Latin house, tribal house\ndance-pop, Latin house, tropical house\ndance-pop, Latin house, worldbeat\ndance-pop, Latin pop\ndance-pop, Latin pop, 2000s pop\ndance-pop, Latin pop, Czech pop\ndance-pop, Latin pop, Dutch\ndance-pop, Latin pop, EDM\ndance-pop, Latin pop, Eastern European pop\ndance-pop, Latin pop, Eurodance\ndance-pop, Latin pop, European dance\ndance-pop, Latin pop, Europop\ndance-pop, Latin pop, Italian\ndance-pop, Latin pop, K-pop\ndance-pop, Latin pop, Mandarin pop\ndance-pop, Latin pop, Moombahton\ndance-pop, Latin pop, Romanian\ndance-pop, Latin pop, Russian\ndance-pop, Latin pop, Swedish\ndance-pop, Latin pop, bilingual\ndance-pop, Latin pop, children's music\ndance-pop, Latin pop, chiptune\ndance-pop, Latin pop, electro-house\ndance-pop, Latin pop, electronic\ndance-pop, Latin pop, freestyle\ndance-pop, Latin pop, funk\ndance-pop, Latin pop, hip-hop\ndance-pop, Latin pop, house\ndance-pop, Latin pop, moombahton\ndance-pop, Latin pop, novelty\ndance-pop, Latin pop, reggaeton\ndance-pop, Latin pop, synthwave\ndance-pop, Latin pop, tropical house\ndance-pop, Latin pop, upbeat\ndance-pop, Latin pop, worldbeat\ndance-pop, Latin trap\ndance-pop, Latin, Afrobeat\ndance-pop, Latin, Afrobeats\ndance-pop, Latin, Arabic\ndance-pop, Latin, Balkan\ndance-pop, Latin, Bollywood\ndance-pop, Latin, Bossa Nova\ndance-pop, Latin, C-pop\ndance-pop, Latin, Caribbean\ndance-pop, Latin, Central Asian\ndance-pop, Latin, Christian\ndance-pop, Latin, Christmas\ndance-pop, Latin, Czech\ndance-pop, Latin, EDM\ndance-pop, Latin, Eastern European\ndance-pop, Latin, Eurodance\ndance-pop, Latin, French\ndance-pop, Latin, Halloween\ndance-pop, Latin, Italian\ndance-pop, Latin, Italo-dance\ndance-pop, Latin, Italo-disco\ndance-pop, Latin, K-pop\ndance-pop, Latin, Kizomba\ndance-pop, Latin, Mandarin pop\ndance-pop, Latin, Mandopop\ndance-pop, Latin, Mediterranean\ndance-pop, Latin, Middle Eastern\ndance-pop, Latin, Moombahton\ndance-pop, Latin, Neapolitan\ndance-pop, Latin, North African\ndance-pop, Latin, Romanian\ndance-pop, Latin, Russian\ndance-pop, Latin, South African\ndance-pop, Latin, South Asian\ndance-pop, Latin, V-pop\ndance-pop, Latin, Vietnamese\ndance-pop, Latin, Vietnamese pop\ndance-pop, Latin, anthemic\ndance-pop, Latin, apocalyptic carnival\ndance-pop, Latin, atmospheric\ndance-pop, Latin, bilingual\ndance-pop, Latin, children's\ndance-pop, Latin, children's TV\ndance-pop, Latin, children's music\ndance-pop, Latin, chiptune\ndance-pop, Latin, cinematic\ndance-pop, Latin, cumbia\ndance-pop, Latin, dancehall\ndance-pop, Latin, disco-funk\ndance-pop, Latin, electronic\ndance-pop, Latin, festive\ndance-pop, Latin, flamenco\ndance-pop, Latin, funk\ndance-pop, Latin, future bass\ndance-pop, Latin, global\ndance-pop, Latin, high-energy\ndance-pop, Latin, hip-hop\ndance-pop, Latin, house\ndance-pop, Latin, moombahton\ndance-pop, Latin, multilingual\ndance-pop, Latin, novelty\ndance-pop, Latin, reggaeton\ndance-pop, Latin, retro\ndance-pop, Latin, synth\ndance-pop, Latin, synth-pop\ndance-pop, Latin, synthwave\ndance-pop, Latin, tango\ndance-pop, Latin, theatrical\ndance-pop, Latin, tropical\ndance-pop, Latin, upbeat\ndance-pop, Latin, video game\ndance-pop, Latin, world music\ndance-pop, Latin, worldbeat\ndance-pop, Latin, zouk\ndance-pop, Latin-infused, electronic\ndance-pop, Latin-pop\ndance-pop, Latin-pop, Zumba\ndance-pop, Luk Thung, Mor Lam\ndance-pop, Luk Thung, electronic\ndance-pop, Mai Tledian\ndance-pop, Malayalam, filmi\ndance-pop, Mandopop\ndance-pop, Mandopop, 2000s\ndance-pop, Mandopop, 90s pop\ndance-pop, Mandopop, Brazilian funk\ndance-pop, Mandopop, Central Asian\ndance-pop, Mandopop, EDM\ndance-pop, Mandopop, Eurodance\ndance-pop, Mandopop, J-rock\ndance-pop, Mandopop, R&B\ndance-pop, Mandopop, early 2000s\ndance-pop, Mandopop, electronic\ndance-pop, Mandopop, retro\ndance-pop, Manele\ndance-pop, Manele, Romanian\ndance-pop, Manele, electronic\ndance-pop, Marathi, EDM\ndance-pop, Marathi, electronic\ndance-pop, Mediterranean folk\ndance-pop, Mediterranean fusion\ndance-pop, Middle Eastern\ndance-pop, Middle Eastern folk\ndance-pop, Middle Eastern folk, Balkan fusion\ndance-pop, Middle Eastern folk, Caucasian folk\ndance-pop, Middle Eastern folk, fusion\ndance-pop, Middle Eastern fusion\ndance-pop, Middle Eastern fusion, Balkan pop\ndance-pop, Middle Eastern fusion, cinematic\ndance-pop, Middle Eastern house, Latin house\ndance-pop, Middle Eastern pop\ndance-pop, Middle Eastern pop, Azerbaijani pop\ndance-pop, Middle Eastern pop, Latin dance\ndance-pop, Middle Eastern pop, R&B\ndance-pop, Middle Eastern pop, electronic\ndance-pop, Middle Eastern pop, hip-hop\ndance-pop, Middle Eastern, 80s synth\ndance-pop, Middle Eastern, 90s pop\ndance-pop, Middle Eastern, Arabic\ndance-pop, Middle Eastern, Armenian\ndance-pop, Middle Eastern, Azerbaijani\ndance-pop, Middle Eastern, Azerbaijani folk\ndance-pop, Middle Eastern, Azerbaijani pop\ndance-pop, Middle Eastern, Balkan\ndance-pop, Middle Eastern, Bollywood\ndance-pop, Middle Eastern, C-pop\ndance-pop, Middle Eastern, Caucasian\ndance-pop, Middle Eastern, Caucasian folk\ndance-pop, Middle Eastern, Central Asian\ndance-pop, Middle Eastern, EDM\ndance-pop, Middle Eastern, Eastern European\ndance-pop, Middle Eastern, Eurodance\ndance-pop, Middle Eastern, Klezmer\ndance-pop, Middle Eastern, Kurdish\ndance-pop, Middle Eastern, Latin\ndance-pop, Middle Eastern, Mandarin\ndance-pop, Middle Eastern, Mediterranean\ndance-pop, Middle Eastern, North African\ndance-pop, Middle Eastern, Persian\ndance-pop, Middle Eastern, South Asian\ndance-pop, Middle Eastern, Turkic\ndance-pop, Middle Eastern, Turkish\ndance-pop, Middle Eastern, a cappella\ndance-pop, Middle Eastern, anthemic\ndance-pop, Middle Eastern, atmospheric\ndance-pop, Middle Eastern, bilingual\ndance-pop, Middle Eastern, cinematic\ndance-pop, Middle Eastern, desert\ndance-pop, Middle Eastern, early 2000s\ndance-pop, Middle Eastern, electronic\ndance-pop, Middle Eastern, emotional\ndance-pop, Middle Eastern, energetic\ndance-pop, Middle Eastern, epic\ndance-pop, Middle Eastern, flamenco\ndance-pop, Middle Eastern, funk\ndance-pop, Middle Eastern, house\ndance-pop, Middle Eastern, late-90s\ndance-pop, Middle Eastern, microtonal\ndance-pop, Middle Eastern, modern\ndance-pop, Middle Eastern, mystical\ndance-pop, Middle Eastern, pop\ndance-pop, Middle Eastern, retro\ndance-pop, Middle Eastern, rock\ndance-pop, Middle Eastern, theatrical\ndance-pop, Middle Eastern, trance\ndance-pop, Mizrahi pop\ndance-pop, Mizrahi pop, electronic\ndance-pop, Mizrahi, 80s pop\ndance-pop, Mizrahi, 90s\ndance-pop, Mizrahi, EDM\ndance-pop, Mizrahi, Eurodance\ndance-pop, Mizrahi, Israeli\ndance-pop, Mizrahi, Mediterranean\ndance-pop, Mizrahi, Middle Eastern\ndance-pop, Mizrahi, chiptune\ndance-pop, Mizrahi, electronic\ndance-pop, Mizrahi, funk\ndance-pop, Mizrahi, hip-hop\ndance-pop, Mizrahi, reggaeton\ndance-pop, Mizrahi-pop\ndance-pop, Moombahton, Middle Eastern pop\ndance-pop, Nepali folk\ndance-pop, Nepali, 2000s Bollywood\ndance-pop, Nepali, EDM\ndance-pop, Nepali, Eurodance\ndance-pop, Nepali, electronic\ndance-pop, New Jack Swing\ndance-pop, New Jack Swing, 90s pop\ndance-pop, North African pop, atmospheric\ndance-pop, North African pop, dancehall\ndance-pop, North African, Middle Eastern\ndance-pop, OPM\ndance-pop, P-Pop\ndance-pop, Persian folk\ndance-pop, Persian pop, electronic\ndance-pop, Persian pop, retro\ndance-pop, Persian, Eurodance\ndance-pop, Persian, electronic\ndance-pop, Polish folk\ndance-pop, Polish folk, electronic\ndance-pop, Punjabi pop\ndance-pop, Punjabi pop, R&B\ndance-pop, R&B\ndance-pop, R&B, 90s pop\ndance-pop, R&B, Afro-Cuban\ndance-pop, R&B, Afrobeats\ndance-pop, R&B, Bollywood\ndance-pop, R&B, C-pop\ndance-pop, R&B, EDM\ndance-pop, R&B, Eurodance\ndance-pop, R&B, J-pop\ndance-pop, R&B, K-pop\ndance-pop, R&B, Latin\ndance-pop, R&B, Latin house\ndance-pop, R&B, Latin pop\ndance-pop, R&B, Mandopop\ndance-pop, R&B, Russian\ndance-pop, R&B, UK garage\ndance-pop, R&B, bilingual\ndance-pop, R&B, chiptune\ndance-pop, R&B, dancehall\ndance-pop, R&B, early 2000s\ndance-pop, R&B, early 2000s pop\ndance-pop, R&B, electronic\ndance-pop, R&B, funk\ndance-pop, R&B, funk-pop, pop-rock\ndance-pop, R&B, future bass\ndance-pop, R&B, hip-hop\ndance-pop, R&B, house\ndance-pop, R&B, late-90s pop\ndance-pop, R&B, lo-fi hip hop\ndance-pop, R&B, new jack swing\ndance-pop, R&B, reggae dancehall\ndance-pop, R&B, tropical house\ndance-pop, Rai, French chanson\ndance-pop, Rai, electronic\ndance-pop, Rai, reggaeton\ndance-pop, Romanian folk\ndance-pop, Romanian folk, electronic\ndance-pop, Romanian party music\ndance-pop, Romanian, Europop\ndance-pop, Romanian, club\ndance-pop, Russian estrada, Eurodance\ndance-pop, Russian folk\ndance-pop, Russian folk, Balkan\ndance-pop, Russian folk, Eurodance\ndance-pop, Russian folk, electronic\ndance-pop, Russian folk, flamenco\ndance-pop, Russian folk, polka\ndance-pop, Russian folk, reggaeton\ndance-pop, Russian pop\ndance-pop, Russian pop, 90s pop\ndance-pop, Russian pop, EDM\ndance-pop, Russian pop, world music\ndance-pop, Russian rap, chiptune\ndance-pop, Russian, 2000s\ndance-pop, Russian, 90s pop\ndance-pop, Russian, Balkan\ndance-pop, Russian, Bollywood\ndance-pop, Russian, EDM\ndance-pop, Russian, Eastern European\ndance-pop, Russian, Eurodance\ndance-pop, Russian, J-pop\ndance-pop, Russian, Latin\ndance-pop, Russian, Middle Eastern\ndance-pop, Russian, electronic\ndance-pop, Russian, estrada\ndance-pop, Russian, festive\ndance-pop, Russian, folk\ndance-pop, Russian, house\ndance-pop, Russian, hyperpop\ndance-pop, Russian, oriental\ndance-pop, Russian, satirical\ndance-pop, Russian, synth\ndance-pop, Russian, tango\ndance-pop, Schlager, children's music\ndance-pop, Sinhala pop, electronic\ndance-pop, Slavic folk, atmospheric\ndance-pop, South African house\ndance-pop, South Asian\ndance-pop, South Asian classical, electronic\ndance-pop, South Asian fusion\ndance-pop, South Asian fusion, Middle Eastern pop\ndance-pop, South Asian pop\ndance-pop, South Asian, 2000s Bollywood\ndance-pop, South Asian, 80s synth\ndance-pop, South Asian, 90s pop\ndance-pop, South Asian, Eurodance\ndance-pop, South Asian, Middle Eastern\ndance-pop, South Asian, Sinhala\ndance-pop, South Asian, electronic\ndance-pop, South Asian, pop-rock\ndance-pop, South Asian, synthwave\ndance-pop, South Asian, upbeat\ndance-pop, South Asian, vintage\ndance-pop, South Indian devotional, electronic\ndance-pop, South Indian film music\ndance-pop, South Indian fusion\ndance-pop, South Indian fusion, Latin pop\ndance-pop, South Indian pop, electronic\ndance-pop, South Indian, 2000s Bollywood\ndance-pop, South Indian, 2000s Kollywood\ndance-pop, South Indian, 80s Kollywood\ndance-pop, South Indian, Eurodance\ndance-pop, South Indian, Kollywood\ndance-pop, South Indian, Latin\ndance-pop, South Indian, Middle Eastern\ndance-pop, South Indian, bilingual\ndance-pop, South Indian, chiptune\ndance-pop, South Indian, cinematic\ndance-pop, South Indian, electronic\ndance-pop, South Indian, funk\ndance-pop, South Indian, orchestral\ndance-pop, Southeast Asian folk, hip-hop\ndance-pop, Southeast Asian pop\ndance-pop, Southeast Asian pop, Bollywood\ndance-pop, Southeast Asian, Eurodance\ndance-pop, Southeast Asian, Sinhala\ndance-pop, Southeast Asian, electronic\ndance-pop, Southeast Asian, upbeat\ndance-pop, T-Pop\ndance-pop, T-pop, electro-pop\ndance-pop, Tamil Christian, EDM\ndance-pop, Tamil Christian, Eurodance\ndance-pop, Tamil Christian, Kollywood\ndance-pop, Tamil Christian, devotional\ndance-pop, Tamil Christian, late-90s pop\ndance-pop, Tamil, 90s Kollywood\ndance-pop, Tamil, Bhangra\ndance-pop, Tamil, EDM\ndance-pop, Tamil, Eurodance\ndance-pop, Tamil, Kollywood\ndance-pop, Tamil, early 2000s Kollywood\ndance-pop, Tamil, electronic\ndance-pop, Tamil, hip-hop\ndance-pop, Tamil, late-90s\ndance-pop, Tamil, quirky\ndance-pop, Telugu Christian, devotional\ndance-pop, Telugu Christian, festive\ndance-pop, Telugu film music\ndance-pop, Telugu, 2000s Kollywood\ndance-pop, Telugu, Indian film music\ndance-pop, Telugu, hip-hop\ndance-pop, Thai pop\ndance-pop, Thai pop, EDM\ndance-pop, Thai, 2000s Eurodance\ndance-pop, Thai, electronic\ndance-pop, Thai, synth-heavy\ndance-pop, Tollywood, Bhangra\ndance-pop, Turkish arabesque, cinematic\ndance-pop, Turkish electronic\ndance-pop, Turkish folk, electronic\ndance-pop, Turkish folk, fusion\ndance-pop, Turkish fusion\ndance-pop, Turkish pop\ndance-pop, Turkish pop, Middle Eastern\ndance-pop, Turkish pop, electronic\ndance-pop, Turkish pop, hyper-pop\ndance-pop, Turkish, Balkan\ndance-pop, Turkish, Balkan folk\ndance-pop, Turkish, EDM\ndance-pop, Turkish, Latin\ndance-pop, Turkish, Middle Eastern\ndance-pop, Turkish, dancehall\ndance-pop, Turkish, electronic\ndance-pop, Turkish, oriental\ndance-pop, Turkish, synth\ndance-pop, UK garage\ndance-pop, UK garage, 2-step\ndance-pop, UK garage, Bollywood\ndance-pop, UK garage, dancehall\ndance-pop, UK garage, deep house\ndance-pop, UK garage, ethereal\ndance-pop, UK garage, future bass\ndance-pop, UK garage, grime\ndance-pop, UK garage, hip-house\ndance-pop, UK garage, house\ndance-pop, UK garage, hyperpop\ndance-pop, UK garage, pop-funk\ndance-pop, UK hardcore, happy hardcore\ndance-pop, Uyghur, Central Asian\ndance-pop, Uyghur, electronic\ndance-pop, Uzbek folk, cinematic\ndance-pop, Uzbek, EDM\ndance-pop, V-Pop, EDM\ndance-pop, V-Pop, early 2000s\ndance-pop, V-Pop, retro\ndance-pop, V-pop, Eurodance\ndance-pop, V-pop, K-pop\ndance-pop, V-pop, children's music\ndance-pop, Vietnamese folk\ndance-pop, Vina House, Mandopop\ndance-pop, Y2K, Eurodance\ndance-pop, Y2K, J-pop\ndance-pop, Y2K, chiptune\ndance-pop, Zumba, electronic\ndance-pop, afro-pop, worldbeat\ndance-pop, afrobeat, dancehall\ndance-pop, afrobeat, tropical house\ndance-pop, ambient, Indian fusion\ndance-pop, ambient, Mongolian pop\ndance-pop, ambient, Telugu\ndance-pop, atmospheric, Eastern-influenced\ndance-pop, axé, eurodance\ndance-pop, axé, funk\ndance-pop, axé, retro\ndance-pop, axé, samba-reggae\ndance-pop, baile funk\ndance-pop, bhangra, 80s pop\ndance-pop, bhangra, Bollywood\ndance-pop, bhangra, EDM\ndance-pop, bhangra, electronic\ndance-pop, bhangra, uk garage\ndance-pop, bhangra-pop\ndance-pop, big beat, early 2000s\ndance-pop, bilingual, electronic\ndance-pop, bilingual, pop-rock\ndance-pop, bilingual, retro\ndance-pop, bilingual, synth-pop\ndance-pop, breakbeat\ndance-pop, breakbeat, J-pop\ndance-pop, brega funk\ndance-pop, bubblegum pop\ndance-pop, bubblegum pop, 2000s pop\ndance-pop, carioca, Mandopop\ndance-pop, carioca, bilingual\ndance-pop, chanson, Russian\ndance-pop, children's music\ndance-pop, children's music, 90s Eurodance\ndance-pop, children's music, Balkan\ndance-pop, children's music, Brazilian\ndance-pop, children's music, Eastern European\ndance-pop, children's music, Eurodance\ndance-pop, children's music, Latin pop\ndance-pop, children's music, Middle Eastern\ndance-pop, children's music, Turkish\ndance-pop, children's music, Turkish pop\ndance-pop, children's music, bilingual\ndance-pop, children's music, cumbia\ndance-pop, children's music, estrada\ndance-pop, children's music, eurodance\ndance-pop, children's music, hyperpop\ndance-pop, children's music, novelty\ndance-pop, children's music, retro\ndance-pop, children's music, retro Brazilian\ndance-pop, children's music, retro pop\ndance-pop, children's music, retro video game\ndance-pop, children's music, tropical\ndance-pop, children's music, video game\ndance-pop, children's pop, Vietnamese\ndance-pop, chiptune\ndance-pop, chiptune, 8-bit\ndance-pop, chiptune, 90s house\ndance-pop, chiptune, Bollywood\ndance-pop, chiptune, Brazilian\ndance-pop, chiptune, C-pop\ndance-pop, chiptune, Central Asian\ndance-pop, chiptune, Central Asian folk\ndance-pop, chiptune, Central Asian pop\ndance-pop, chiptune, EDM\ndance-pop, chiptune, Eastern European\ndance-pop, chiptune, Eurodance\ndance-pop, chiptune, Indian pop\ndance-pop, chiptune, Israeli\ndance-pop, chiptune, J-core\ndance-pop, chiptune, J-pop\ndance-pop, chiptune, Middle Eastern\ndance-pop, chiptune, Nepali\ndance-pop, chiptune, Russian\ndance-pop, chiptune, Russian folk\ndance-pop, chiptune, Russian pop\ndance-pop, chiptune, South Asian\ndance-pop, chiptune, South Indian\ndance-pop, chiptune, Thai\ndance-pop, chiptune, Thai pop\ndance-pop, chiptune, Turkish children's\ndance-pop, chiptune, bilingual\ndance-pop, chiptune, cartoonish\ndance-pop, chiptune, children's\ndance-pop, chiptune, children's music\ndance-pop, chiptune, dangdut koplo\ndance-pop, chiptune, electro-pop\ndance-pop, chiptune, eurodance\ndance-pop, chiptune, funkot\ndance-pop, chiptune, happy hardcore\ndance-pop, chiptune, hyperpop\ndance-pop, chiptune, k-pop\ndance-pop, chiptune, oriental\ndance-pop, chiptune, retro\ndance-pop, chiptune, video game\ndance-pop, chiptune, world fusion\ndance-pop, cinematic synth, Indonesian pop\ndance-pop, cinematic, Balkan\ndance-pop, cinematic, Balkan fusion\ndance-pop, cinematic, C-pop\ndance-pop, cinematic, Central Asian\ndance-pop, cinematic, Central Asian fusion\ndance-pop, cinematic, Christmas\ndance-pop, cinematic, EDM\ndance-pop, cinematic, Indian film\ndance-pop, cinematic, Indian fusion\ndance-pop, cinematic, Indian pop\ndance-pop, cinematic, Middle Eastern\ndance-pop, cinematic, Russian\ndance-pop, cinematic, South Asian fusion\ndance-pop, cinematic, South Indian\ndance-pop, cinematic, electronic\ndance-pop, cinematic, ethnic fusion\ndance-pop, cinematic, folk\ndance-pop, cinematic, folk-pop\ndance-pop, cinematic, funk\ndance-pop, cinematic, hip-hop\ndance-pop, cinematic, oriental style\ndance-pop, cinematic, spy-thriller\ndance-pop, cinematic, world fusion\ndance-pop, cinematic, world music\ndance-pop, city pop, 90s K-pop\ndance-pop, city pop, 90s R&B\ndance-pop, city pop, 90s funk\ndance-pop, city pop, 90s house\ndance-pop, city pop, K-pop\ndance-pop, city pop, new jack swing\ndance-pop, city pop, nu-disco\ndance-pop, city pop, retro\ndance-pop, club rap, Mandopop\ndance-pop, cumbia, children's music\ndance-pop, cumbia, kids\ndance-pop, cumbia, merengue\ndance-pop, cumbia, world music\ndance-pop, cyberpunk, electronic\ndance-pop, dancehall, EDM\ndance-pop, dancehall, UK rap\ndance-pop, dancehall, electronic\ndance-pop, dancehall, moombahton\ndance-pop, dancehall, reggae\ndance-pop, dancehall, synthpop\ndance-pop, dangdut koplo\ndance-pop, dangdut koplo, chiptune\ndance-pop, dangdut koplo, funkot\ndance-pop, dangdut koplo, hip-hop\ndance-pop, dangdut koplo, house\ndance-pop, dangdut koplo, hyperpop\ndance-pop, deep house\ndance-pop, deep house, Brazilian funk\ndance-pop, deep house, Latin\ndance-pop, deep house, Romanian\ndance-pop, deep house, Russian\ndance-pop, deep house, afrobeat\ndance-pop, deep house, future bass\ndance-pop, deep house, slap house\ndance-pop, dembow, Brazilian\ndance-pop, dembow, Latin\ndance-pop, dembow, South Asian pop\ndance-pop, disco polo\ndance-pop, disco, C-pop\ndance-pop, drum and bass, bilingual\ndance-pop, dubstep, lo-fi\ndance-pop, early 2000s C-pop, Eurodance\ndance-pop, early 2000s Mandopop\ndance-pop, early 2000s R&B\ndance-pop, early 2000s R&B, Eurodance\ndance-pop, early 2000s R&B, hip-hop\ndance-pop, early 2000s R&B, house\ndance-pop, early 2000s R&B, lo-fi hip-hop\ndance-pop, early 2000s house\ndance-pop, early 2000s, Eurodance\ndance-pop, early 2000s, bilingual\ndance-pop, early 2000s, multilingual\ndance-pop, early 2000s, pop\ndance-pop, early 90s house\ndance-pop, early house, disco\ndance-pop, electro-brega, piseiro\ndance-pop, electro-cumbia\ndance-pop, electro-cumbia, laiko\ndance-pop, electro-gaana, Tamil\ndance-pop, electro-house, Balkan\ndance-pop, electro-house, chiptune\ndance-pop, electro-mor Lam\ndance-pop, electro-pop, EDM\ndance-pop, electro-pop, bilingual\ndance-pop, electro-pop, hyperpop\ndance-pop, electro-pop, retro\ndance-pop, electronic, Afro-Euro\ndance-pop, electronic, Arabic\ndance-pop, electronic, Armenian\ndance-pop, electronic, Bollywood pop\ndance-pop, electronic, C-pop\ndance-pop, electronic, Central Asian\ndance-pop, electronic, Central Asian folk\ndance-pop, electronic, Hanukkah\ndance-pop, electronic, Hindi pop\ndance-pop, electronic, Indian\ndance-pop, electronic, Indian folk\ndance-pop, electronic, Indian pop\ndance-pop, electronic, Indonesian\ndance-pop, electronic, Israeli\ndance-pop, electronic, Jewish\ndance-pop, electronic, Kurdish\ndance-pop, electronic, Middle Eastern\ndance-pop, electronic, Middle Eastern fusion\ndance-pop, electronic, Mizrahi\ndance-pop, electronic, Nepali\ndance-pop, electronic, North African\ndance-pop, electronic, Persian pop\ndance-pop, electronic, R&B\ndance-pop, electronic, Romanian\ndance-pop, electronic, Russian\ndance-pop, electronic, Russian pop\ndance-pop, electronic, South Asian\ndance-pop, electronic, South Indian\ndance-pop, electronic, Tibetan\ndance-pop, electronic, Turkish\ndance-pop, electronic, bilingual\ndance-pop, electronic, chiptune\ndance-pop, electronic, cinematic\ndance-pop, electronic, folk\ndance-pop, electronic, folk-inspired\ndance-pop, electronic, folk-pop\ndance-pop, electronic, funk\ndance-pop, electronic, global fusion\ndance-pop, electronic, oriental\ndance-pop, electronic, oriental style\ndance-pop, electronic, rock\ndance-pop, electronic, world fusion\ndance-pop, electronic, world music\ndance-pop, epic, Central Asian\ndance-pop, ethereal, Central Asian fusion\ndance-pop, ethnic folk, electronic\ndance-pop, ethnic fusion\ndance-pop, ethnic fusion, cinematic\ndance-pop, ethnic, Middle Eastern\ndance-pop, ethnic-electronic, Middle Eastern\ndance-pop, ethno-pop\ndance-pop, ethno-pop, Turkish\ndance-pop, euro-pop, 2000s\ndance-pop, eurobeat, cantopop\ndance-pop, eurodance\ndance-pop, eurodance, 2000s\ndance-pop, eurodance, 90s\ndance-pop, eurodance, 90s house\ndance-pop, eurodance, Bollywood\ndance-pop, eurodance, C-pop\ndance-pop, eurodance, Central Asian\ndance-pop, eurodance, Chinese\ndance-pop, eurodance, Chinese pop\ndance-pop, eurodance, R&B\ndance-pop, eurodance, Russian\ndance-pop, eurodance, Russian pop\ndance-pop, eurodance, Swedish\ndance-pop, eurodance, balkan\ndance-pop, eurodance, big room house\ndance-pop, eurodance, bilingual\ndance-pop, eurodance, bollywood\ndance-pop, eurodance, bubblegum pop\ndance-pop, eurodance, cartoon\ndance-pop, eurodance, children's\ndance-pop, eurodance, children's music\ndance-pop, eurodance, chiptune\ndance-pop, eurodance, christian\ndance-pop, eurodance, christmas\ndance-pop, eurodance, cinematic\ndance-pop, eurodance, city pop\ndance-pop, eurodance, commercial house\ndance-pop, eurodance, disco\ndance-pop, eurodance, disco polo\ndance-pop, eurodance, early 2000s\ndance-pop, eurodance, edm\ndance-pop, eurodance, festive\ndance-pop, eurodance, filipino pop\ndance-pop, eurodance, folk\ndance-pop, eurodance, folk-dance\ndance-pop, eurodance, folk-pop\ndance-pop, eurodance, french house\ndance-pop, eurodance, funk\ndance-pop, eurodance, happy hardcore\ndance-pop, eurodance, hardstyle\ndance-pop, eurodance, hi-nrg\ndance-pop, eurodance, hip-hop\ndance-pop, eurodance, hip-house\ndance-pop, eurodance, house\ndance-pop, eurodance, hyperpop\ndance-pop, eurodance, italo disco\ndance-pop, eurodance, j-pop\ndance-pop, eurodance, kids' music\ndance-pop, eurodance, late-90s\ndance-pop, eurodance, latin\ndance-pop, eurodance, latin house\ndance-pop, eurodance, latin pop\ndance-pop, eurodance, mandopop\ndance-pop, eurodance, manele\ndance-pop, eurodance, maneles\ndance-pop, eurodance, middle eastern pop\ndance-pop, eurodance, new jack swing\ndance-pop, eurodance, novelty\ndance-pop, eurodance, oriental\ndance-pop, eurodance, oriental pop\ndance-pop, eurodance, persian pop\ndance-pop, eurodance, reggae\ndance-pop, eurodance, reggaeton\ndance-pop, eurodance, romanian\ndance-pop, eurodance, russian\ndance-pop, eurodance, russian pop\ndance-pop, eurodance, schlager\ndance-pop, eurodance, slap house\ndance-pop, eurodance, spiritual\ndance-pop, eurodance, synth-pop\ndance-pop, eurodance, trance\ndance-pop, eurodance, uk garage\ndance-pop, eurodance, v-pop\ndance-pop, festive, Middle Eastern\ndance-pop, festive, South Indian\ndance-pop, filmi, retro\ndance-pop, flamenco, Eurodance\ndance-pop, flamenco, Russian\ndance-pop, folk fusion\ndance-pop, folk fusion, Central Asian\ndance-pop, folk fusion, Eastern European\ndance-pop, folk fusion, Turkish pop\ndance-pop, folk fusion, Uzbek\ndance-pop, folk fusion, chiptune\ndance-pop, folk house\ndance-pop, folk, Central Asian\ndance-pop, folk, EDM\ndance-pop, folk, Eastern European\ndance-pop, folk, Nepali\ndance-pop, folk, Russian\ndance-pop, folk, cinematic\ndance-pop, folk, electronic\ndance-pop, folk, epic\ndance-pop, folk, hip-hop\ndance-pop, folk, klezmer\ndance-pop, folk, ney flute\ndance-pop, folk, polka\ndance-pop, folk, techno\ndance-pop, folk-dance\ndance-pop, folk-dance, Eastern European\ndance-pop, folk-dance, electronic\ndance-pop, folk-electro\ndance-pop, folk-electronic\ndance-pop, folk-electronic, Central Asian\ndance-pop, folk-pop\ndance-pop, folk-pop, Central Asian\ndance-pop, folk-pop, Eastern European\ndance-pop, folk-pop, Latin\ndance-pop, folk-pop, electronic\ndance-pop, folk-pop, polka\ndance-pop, forró eletrônico\ndance-pop, forró, Brazilian\ndance-pop, forró, electronic\ndance-pop, forró, hyperpop\ndance-pop, forró, piseiro\ndance-pop, freestyle, house\ndance-pop, freestyle, new jack swing\ndance-pop, freestyle, synth-pop\ndance-pop, funk carioca, Brazilian\ndance-pop, funk carioca, Eurodance\ndance-pop, funk carioca, children's music\ndance-pop, funk, Balkan\ndance-pop, funk, Bollywood-pop\ndance-pop, funk, C-pop\ndance-pop, funk, Central Asian\ndance-pop, funk, K-pop\ndance-pop, funk, Middle Eastern\ndance-pop, funk, Middle Eastern fusion\ndance-pop, funk, R&B\ndance-pop, funk, breakbeat\ndance-pop, funk, disco\ndance-pop, funk, freestyle\ndance-pop, funk, hip-hop\ndance-pop, funk, hyperpop\ndance-pop, funk, late 90s house\ndance-pop, funk, new jack swing\ndance-pop, funk, retro-futuristic\ndance-pop, funkot, dangdut koplo\ndance-pop, fusion, Arabic pop\ndance-pop, fusion, Tamil pop\ndance-pop, future bass\ndance-pop, future bass, bilingual\ndance-pop, future bass, cinematic\ndance-pop, future bass, deep house\ndance-pop, future bass, hyperpop\ndance-pop, future bass, lo-fi\ndance-pop, future pop\ndance-pop, future pop, hyperpop\ndance-pop, future pop, trance\ndance-pop, futuristic, EDM\ndance-pop, futuristic, anime\ndance-pop, futuristic, bilingual\ndance-pop, futuristic, cosmic\ndance-pop, futuristic, cybernetic\ndance-pop, futuristic, electronic\ndance-pop, global bass, Middle Eastern\ndance-pop, global hip-hop\ndance-pop, global, electronic\ndance-pop, global, uplifting\ndance-pop, gospel, EDM\ndance-pop, gospel, children's music\ndance-pop, gospel, early 2000s R&B\ndance-pop, happy hardcore\ndance-pop, happy hardcore, Eurodance\ndance-pop, happy hardcore, J-pop\ndance-pop, happy hardcore, Luk Thung\ndance-pop, happy hardcore, children's music\ndance-pop, happy hardcore, chiptune\ndance-pop, happy hardcore, kids' music\ndance-pop, happy hardcore, nightcore\ndance-pop, happy hardcore, trance\ndance-pop, hardbass\ndance-pop, hardbass, eurodance\ndance-pop, hardstyle\ndance-pop, hardstyle, C-pop\ndance-pop, hardstyle, Central Asian\ndance-pop, hardstyle, EDM\ndance-pop, hardstyle, Russian\ndance-pop, hardstyle, ambient\ndance-pop, hardstyle, big room house\ndance-pop, hardstyle, eurodance\ndance-pop, hardstyle, synthwave\ndance-pop, hip-hop\ndance-pop, hip-hop, Arabic pop\ndance-pop, hip-hop, Balkan fusion\ndance-pop, hip-hop, Bollywood\ndance-pop, hip-hop, C-pop\ndance-pop, hip-hop, EDM\ndance-pop, hip-hop, Eurodance\ndance-pop, hip-hop, Indian pop\ndance-pop, hip-hop, Italian\ndance-pop, hip-hop, K-pop\ndance-pop, hip-hop, Latin pop\ndance-pop, hip-hop, Mandopop\ndance-pop, hip-hop, Middle Eastern fusion\ndance-pop, hip-hop, R&B\ndance-pop, hip-hop, South Asian\ndance-pop, hip-hop, South Indian film music\ndance-pop, hip-hop, South Indian pop\ndance-pop, hip-hop, Tamil pop\ndance-pop, hip-hop, Tết\ndance-pop, hip-hop, Uyghur\ndance-pop, hip-hop, chiptune\ndance-pop, hip-hop, dancehall\ndance-pop, hip-hop, electro-pop\ndance-pop, hip-hop, electronic\ndance-pop, hip-hop, funk\ndance-pop, hip-hop, hyperpop\ndance-pop, hip-hop, lo-fi\ndance-pop, hip-hop, moombahton\ndance-pop, hip-hop, reggaeton\ndance-pop, hip-hop, trap\ndance-pop, hip-hop, tropical house\ndance-pop, hip-house\ndance-pop, hip-house, 90s\ndance-pop, hip-house, Bollywood\ndance-pop, hip-house, C-pop\ndance-pop, hip-house, Eurodance\ndance-pop, hip-house, Latin pop\ndance-pop, hip-house, Mandarin pop\ndance-pop, hip-house, big room\ndance-pop, hip-house, cinematic\ndance-pop, hip-house, early 2000s\ndance-pop, hip-house, electronic\ndance-pop, hip-house, freestyle\ndance-pop, hip-house, funk\ndance-pop, hip-house, new jack swing\ndance-pop, hip-house, retro\ndance-pop, hip-house, retro house\ndance-pop, hip-house, vogue\ndance-pop, house\ndance-pop, house, Afro-pop\ndance-pop, house, Arabic pop\ndance-pop, house, Bollywood\ndance-pop, house, C-pop\ndance-pop, house, Central Asian\ndance-pop, house, Central Asian pop\ndance-pop, house, EDM\ndance-pop, house, Eastern European\ndance-pop, house, Eurodance\ndance-pop, house, Filipino\ndance-pop, house, Hi-NRG\ndance-pop, house, Italo disco\ndance-pop, house, K-pop\ndance-pop, house, Latin\ndance-pop, house, Latin house\ndance-pop, house, Latin pop\ndance-pop, house, Mandarin rap\ndance-pop, house, Middle Eastern\ndance-pop, house, Mongolian\ndance-pop, house, Persian\ndance-pop, house, R&B\ndance-pop, house, Russian\ndance-pop, house, Turkish\ndance-pop, house, Turkish pop\ndance-pop, house, Vietnamese pop\ndance-pop, house, bilingual\ndance-pop, house, cinematic\ndance-pop, house, conscious hip-hop\ndance-pop, house, electro\ndance-pop, house, electronic\ndance-pop, house, ethnic fusion\ndance-pop, house, funk\ndance-pop, house, future bass\ndance-pop, house, hip-hop\ndance-pop, house, hip-house\ndance-pop, house, jazz fusion\ndance-pop, house, lo-fi\ndance-pop, house, multilingual\ndance-pop, house, new jack swing\ndance-pop, house, novelty\ndance-pop, house, protest\ndance-pop, house, reggaeton\ndance-pop, house, retro\ndance-pop, house, slap house\ndance-pop, house, soulful\ndance-pop, house, spiritual\ndance-pop, house, synth-pop\ndance-pop, house, world music\ndance-pop, hyper-pop, children's music\ndance-pop, hyperpop\ndance-pop, hyperpop, C-pop\ndance-pop, hyperpop, Eurodance\ndance-pop, hyperpop, J-pop\ndance-pop, hyperpop, Javanese\ndance-pop, hyperpop, R&B\ndance-pop, hyperpop, Russian\ndance-pop, hyperpop, chiptune\ndance-pop, hyperpop, choral\ndance-pop, hyperpop, club\ndance-pop, hyperpop, eurodance\ndance-pop, hyperpop, futuristic\ndance-pop, hyperpop, happy hardcore\ndance-pop, hyperpop, hardstyle\ndance-pop, hyperpop, nightcore\ndance-pop, hyperpop, reggaeton\ndance-pop, hyperpop, slap house\ndance-pop, hǎnmài\ndance-pop, hǎnmài, cheesy rave\ndance-pop, industrial, synthwave\ndance-pop, jazz fusion, classical\ndance-pop, kizomba, eurodance\ndance-pop, kizomba, tropical\ndance-pop, klezmer, Eastern European\ndance-pop, klezmer, eurodance\ndance-pop, klezmer, pop\ndance-pop, kuthu\ndance-pop, kuthu, EDM\ndance-pop, kuthu, edm\ndance-pop, laiko\ndance-pop, late-90s house\ndance-pop, late-90s house, Indonesian\ndance-pop, late-90s house, hip-house\ndance-pop, laïko\ndance-pop, laïko, Greek\ndance-pop, laïko, electronic\ndance-pop, laïko-pop\ndance-pop, lo-fi electronic, retro Chinese\ndance-pop, lo-fi, Balkan\ndance-pop, lo-fi, cinematic\ndance-pop, lo-fi, electronic\ndance-pop, lo-fi, funk\ndance-pop, lo-fi, futuristic\ndance-pop, lo-fi, vaporwave\ndance-pop, manele, balkan fusion\ndance-pop, moombahton, Arabic pop\ndance-pop, moombahton, EDM\ndance-pop, moombahton, Israeli\ndance-pop, moombahton, Latin\ndance-pop, moombahton, Latin EDM\ndance-pop, moombahton, Latin pop\ndance-pop, moombahton, Romanian\ndance-pop, moombahton, Russian\ndance-pop, moombahton, South Indian\ndance-pop, moombahton, Tamil\ndance-pop, moombahton, hip-hop\ndance-pop, moombahton, latin\ndance-pop, moombahton, latin pop\ndance-pop, moombahton, reggaeton\ndance-pop, motivational house, synth-pop\ndance-pop, multilingual, accordion\ndance-pop, musical theater\ndance-pop, neo-classical\ndance-pop, new jack swing\ndance-pop, new jack swing, 80s house\ndance-pop, new jack swing, 90s\ndance-pop, new jack swing, 90s R&B\ndance-pop, new jack swing, Cantopop\ndance-pop, new jack swing, Christmas\ndance-pop, new jack swing, Italo disco\ndance-pop, new jack swing, K-pop\ndance-pop, new jack swing, Latin freestyle\ndance-pop, new jack swing, Latin house\ndance-pop, new jack swing, Latin pop\ndance-pop, new jack swing, afrobeat\ndance-pop, new jack swing, city pop\ndance-pop, new jack swing, country-pop\ndance-pop, new jack swing, dancehall\ndance-pop, new jack swing, early house\ndance-pop, new jack swing, festive\ndance-pop, new jack swing, freestyle\ndance-pop, new jack swing, funk\ndance-pop, new jack swing, funk-rock\ndance-pop, new jack swing, gospel\ndance-pop, new jack swing, hip-house\ndance-pop, new jack swing, house\ndance-pop, new jack swing, retro\ndance-pop, new jack swing, retro-futuristic\ndance-pop, new jack swing, synth-funk\ndance-pop, new jack swing, worldbeat\ndance-pop, new wave\ndance-pop, new wave, bilingual\ndance-pop, new wave, novelty\ndance-pop, nightcore, EDM\ndance-pop, nightcore, J-pop\ndance-pop, nightcore, hyperpop\ndance-pop, novelty, Balkan\ndance-pop, novelty, Christmas\ndance-pop, novelty, Filipino\ndance-pop, novelty, Filipino pop\ndance-pop, novelty, French\ndance-pop, novelty, Indonesian\ndance-pop, novelty, Israeli\ndance-pop, novelty, South Indian\ndance-pop, novelty, children's\ndance-pop, novelty, chiptune\ndance-pop, novelty, early 2000s\ndance-pop, novelty, happy hardcore\ndance-pop, novelty, retro\ndance-pop, novelty, retro video game\ndance-pop, nu-disco, Russian\ndance-pop, nu-disco, house\ndance-pop, nu-disco, synth-pop\ndance-pop, orchestral, C-pop\ndance-pop, orchestral, EDM\ndance-pop, orchestral, Turkish\ndance-pop, orchestral, cinematic\ndance-pop, oriental fusion\ndance-pop, oriental house\ndance-pop, oriental house, Armenian pop\ndance-pop, oriental synth, electronic\ndance-pop, oriental, Middle Eastern\ndance-pop, oriental, balkan\ndance-pop, oriental, electronic\ndance-pop, oriental, emotional\ndance-pop, piseiro, forró eletrônico\ndance-pop, pop ballad, Southeast Asian pop\ndance-pop, pop, Central Asian\ndance-pop, pop-funk, new jack swing\ndance-pop, pop-fusion\ndance-pop, pop-punk, early 2000s\ndance-pop, pop-rap, C-pop\ndance-pop, pop-rap, Middle Eastern\ndance-pop, pop-rap, cinematic\ndance-pop, pop-rock\ndance-pop, pop-rock, Eurodance\ndance-pop, progressive house\ndance-pop, progressive house, EDM\ndance-pop, progressive house, Italo dance\ndance-pop, progressive house, Latin pop\ndance-pop, progressive house, Turkish\ndance-pop, progressive house, trance\ndance-pop, progressive house, world music\ndance-pop, progressive trance\ndance-pop, psychedelic, Middle Eastern\ndance-pop, rap, EDM\ndance-pop, raï, electronic\ndance-pop, reggae, dancehall\ndance-pop, reggaeton\ndance-pop, reggaeton, Arabic pop\ndance-pop, reggaeton, Balkan\ndance-pop, reggaeton, Balkan fusion\ndance-pop, reggaeton, Brazilian\ndance-pop, reggaeton, C-pop\ndance-pop, reggaeton, Central Asian\ndance-pop, reggaeton, EDM\ndance-pop, reggaeton, Eastern European\ndance-pop, reggaeton, French\ndance-pop, reggaeton, German\ndance-pop, reggaeton, Greek\ndance-pop, reggaeton, Greek pop\ndance-pop, reggaeton, Italian\ndance-pop, reggaeton, K-pop\ndance-pop, reggaeton, Latin\ndance-pop, reggaeton, Latin house\ndance-pop, reggaeton, Latin pop\ndance-pop, reggaeton, Mediterranean\ndance-pop, reggaeton, Middle Eastern\ndance-pop, reggaeton, Mizrahi\ndance-pop, reggaeton, Nepali\ndance-pop, reggaeton, Persian pop\ndance-pop, reggaeton, Romanian\ndance-pop, reggaeton, Russian\ndance-pop, reggaeton, South Asian\ndance-pop, reggaeton, Swedish\ndance-pop, reggaeton, Turkish\ndance-pop, reggaeton, Turkish pop\ndance-pop, reggaeton, Uzbek\ndance-pop, reggaeton, afrobeat\ndance-pop, reggaeton, big room\ndance-pop, reggaeton, bilingual\ndance-pop, reggaeton, children's music\ndance-pop, reggaeton, chiptune\ndance-pop, reggaeton, cinematic\ndance-pop, reggaeton, cumbia\ndance-pop, reggaeton, dancehall\ndance-pop, reggaeton, electronic\ndance-pop, reggaeton, emotional piano\ndance-pop, reggaeton, eurodance\ndance-pop, reggaeton, flamenco\ndance-pop, reggaeton, folk-pop\ndance-pop, reggaeton, global bass\ndance-pop, reggaeton, house\ndance-pop, reggaeton, lo-fi\ndance-pop, reggaeton, moombahton\ndance-pop, reggaeton, mystical\ndance-pop, reggaeton, novelty\ndance-pop, reggaeton, oud\ndance-pop, reggaeton, tropical\ndance-pop, reggaeton, tropical house\ndance-pop, reggaeton, worldbeat\ndance-pop, reggaeton-lite, tropical\ndance-pop, retro Bollywood\ndance-pop, retro C-pop, Eurobeat\ndance-pop, retro Chinese disco\ndance-pop, retro Eurodance\ndance-pop, retro Eurodance, Chinese\ndance-pop, retro Eurodance, Chinese New Year\ndance-pop, retro Indian, 80s filmi\ndance-pop, retro Indian, 80s pop\ndance-pop, retro K-pop, children's music\ndance-pop, retro K-pop, trot\ndance-pop, retro disco, children's music\ndance-pop, retro disco, funk\ndance-pop, retro funk, disco\ndance-pop, retro house, funk\ndance-pop, retro house, new jack swing\ndance-pop, retro rock and roll, children's music\ndance-pop, retro rock and roll, swing\ndance-pop, retro rock, big band\ndance-pop, retro rock, swing\ndance-pop, retro surf-rock\ndance-pop, retro video game\ndance-pop, retro, 80s\ndance-pop, retro, 80s/90s\ndance-pop, retro, 90s\ndance-pop, retro, Afro-pop\ndance-pop, retro, Balkan fusion\ndance-pop, retro, Bengali pop\ndance-pop, retro, Bollywood\ndance-pop, retro, C-pop\ndance-pop, retro, Cantopop\ndance-pop, retro, Central Asian\ndance-pop, retro, Chinese\ndance-pop, retro, Chinese New Year\ndance-pop, retro, Chinese disco\ndance-pop, retro, Christmas\ndance-pop, retro, City Pop\ndance-pop, retro, Eurodance\ndance-pop, retro, Filipino pop\ndance-pop, retro, Hindi pop\ndance-pop, retro, Indian\ndance-pop, retro, Indian film music\ndance-pop, retro, Indian pop\ndance-pop, retro, J-pop\ndance-pop, retro, K-pop\ndance-pop, retro, Kollywood\ndance-pop, retro, Latin\ndance-pop, retro, Mandopop\ndance-pop, retro, Middle Eastern\ndance-pop, retro, Nepali\ndance-pop, retro, Russian\ndance-pop, retro, South Asian\ndance-pop, retro, South Indian\ndance-pop, retro, South Indian film music\ndance-pop, retro, Southeast Asian\ndance-pop, retro, Taiwanese Hokkien\ndance-pop, retro, Telugu pop\ndance-pop, retro, Thai\ndance-pop, retro, Turkish\ndance-pop, retro, V-Pop\ndance-pop, retro, V-pop\ndance-pop, retro, Vietnamese\ndance-pop, retro, anime\ndance-pop, retro, bengali\ndance-pop, retro, children's\ndance-pop, retro, chiptune\ndance-pop, retro, city pop\ndance-pop, retro, electronic\ndance-pop, retro, filmi\ndance-pop, retro, funk\ndance-pop, retro, hip-hop\ndance-pop, retro, hip-house\ndance-pop, retro, new jack swing\ndance-pop, retro, new wave\ndance-pop, retro, novelty\ndance-pop, retro, synthwave\ndance-pop, retro, video game\ndance-pop, retro, worldbeat\ndance-pop, retro-funk, C-pop\ndance-pop, retro-funk, hip-hop\ndance-pop, retro-futuristic\ndance-pop, retro-futuristic, 80s South Asian\ndance-pop, retro-futuristic, Bollywood\ndance-pop, retro-futuristic, Bollywood synth\ndance-pop, retro-futuristic, C-pop\ndance-pop, retro-futuristic, Hi-NRG\ndance-pop, retro-futuristic, Indian\ndance-pop, retro-futuristic, Italo disco\ndance-pop, retro-futuristic, K-pop\ndance-pop, retro-futuristic, Turkish\ndance-pop, retro-futuristic, chiptune\ndance-pop, retro-futuristic, filmi\ndance-pop, retro-futuristic, multilingual\ndance-pop, retro-futuristic, synth-pop\ndance-pop, retro-futuristic, synthwave\ndance-pop, retro-pop, Indian Christian\ndance-pop, rock, K-pop\ndance-pop, rock, cyberpunk\ndance-pop, rockabilly, retro\ndance-pop, samba-reggae\ndance-pop, saxophone, Eastern European\ndance-pop, schlager\ndance-pop, schlager, electronic\ndance-pop, sci-fi, cinematic\ndance-pop, sci-fi, funk\ndance-pop, slap house\ndance-pop, slap house, Brazilian\ndance-pop, slap house, Brazilian bass\ndance-pop, slap house, EDM\ndance-pop, slap house, Romanian\ndance-pop, slap house, Russian\ndance-pop, slap house, deep house\ndance-pop, smooth jazz\ndance-pop, soul ballad, theatrical rock\ndance-pop, spiritual, Central Asian\ndance-pop, spiritual, EDM\ndance-pop, spiritual, Middle Eastern fusion\ndance-pop, stadium anthem\ndance-pop, stadium anthem, Latin pop\ndance-pop, synth-pop\ndance-pop, synth-pop, C-pop\ndance-pop, synth-pop, Central Asian\ndance-pop, synth-pop, Christian\ndance-pop, synth-pop, Eastern European\ndance-pop, synth-pop, J-pop\ndance-pop, synth-pop, Latin pop\ndance-pop, synth-pop, Mandopop\ndance-pop, synth-pop, Middle Eastern influence\ndance-pop, synth-pop, North African pop\ndance-pop, synth-pop, South Asian\ndance-pop, synth-pop, South Asian fusion\ndance-pop, synth-pop, Southeast Asian\ndance-pop, synth-pop, bilingual\ndance-pop, synth-pop, funk\ndance-pop, synth-pop, nu-disco\ndance-pop, synth-pop, world music\ndance-pop, synthwave, C-pop\ndance-pop, tango, cinematic\ndance-pop, tarantella, Italian\ndance-pop, teen pop, early 2000s\ndance-pop, theatrical pop, Kazakh pop\ndance-pop, theatrical, Balkan\ndance-pop, theatrical, Halloween\ndance-pop, traditional Central Asian\ndance-pop, traditional Central Asian, electronic\ndance-pop, traditional Central Asian, fusion\ndance-pop, trance, C-pop\ndance-pop, trance, Eurodance\ndance-pop, trance, happy hardcore\ndance-pop, trance, hyperpop\ndance-pop, trap, Indonesian\ndance-pop, trap, K-pop\ndance-pop, trap, Middle Eastern fusion\ndance-pop, trap, electronic\ndance-pop, trap, hyperpop\ndance-pop, trap, moombahton\ndance-pop, trap, multilingual\ndance-pop, trap, synth-pop\ndance-pop, tribal house\ndance-pop, tribal, hip-hop\ndance-pop, tropical house\ndance-pop, tropical house, EDM\ndance-pop, tropical house, Filipino\ndance-pop, tropical house, Latin pop\ndance-pop, tropical house, Russian\ndance-pop, tropical house, moombahton\ndance-pop, tropical, Russian\ndance-pop, tropical, chiptune\ndance-pop, turbo-folk, electronic\ndance-pop, tǔ waps, electronic\ndance-pop, vaporwave, R&B\ndance-pop, vaporwave, lo-fi\ndance-pop, video game music\ndance-pop, video game, late-90s\ndance-pop, vintage South Asian\ndance-pop, world fusion\ndance-pop, world fusion, Mediterranean\ndance-pop, world fusion, cinematic\ndance-pop, world fusion, electronic\ndance-pop, world music\ndance-pop, world music, EDM\ndance-pop, world music, Middle Eastern\ndance-pop, world music, cinematic\ndance-pop, world music, electronic\ndance-pop, world music, gospel\ndance-pop, world music, tribal\ndance-pop, worldbeat\ndance-pop, worldbeat, Eurodance\ndance-pop, worldbeat, Latin\ndance-pop, worldbeat, Middle Eastern\ndance-pop, worldbeat, South Asian fusion\ndance-pop, worldbeat, chiptune\ndance-pop, worldbeat, electronic\ndance-pop, worldbeat, funk\ndance-pop, worldbeat, new jack swing\ndance-pop, worldbeat, retro\ndance-pop, worldbeat, synthwave\ndance-pop, zouk, Caribbean\ndance-pop, zouk, soca\ndance-punk\ndance-punk alternative rock\ndance-punk chiptune\ndance-punk electro-rock\ndance-punk electroclash\ndance-punk electronic rock\ndance-punk electropop\ndance-punk electropunk\ndance-punk flamenco\ndance-punk folk-punk\ndance-punk garage rock\ndance-punk glam rock\ndance-punk happy hardcore\ndance-punk hyperpop\ndance-punk indie rock\ndance-punk new wave\ndance-punk pop-punk\ndance-punk pop-rock\ndance-punk synth-rock\ndance-punk, Latin, funk\ndance-punk, dream-pop\ndance-punk, garage rock, indie rock\ndance-punk, happy hardcore\ndance-punk, hyperpop\ndance-punk, new wave\ndance-punk, new wave, punk\ndance-punk, new wave, synth punk\ndance-punk, post-punk, Russian\ndance-rap\ndance-rock\ndance-rock K-pop\ndance-rock bhangra-pop\ndance-rock big beat\ndance-rock chiptune\ndance-rock electro-pop\ndance-rock electronic pop\ndance-rock eurodance\ndance-rock funk\ndance-rock house\ndance-rock hyperpop\ndance-rock latin\ndance-rock latin funk\ndance-rock new wave\ndance-rock nu-metal\ndance-rock pop-punk\ndance-rock synth-pop\ndance-rock theatrical pop\ndance-rock trot\ndance-rock trot-rock\ndance-rock world music\ndance-rock, Italo disco\ndance-rock, K-pop\ndance-rock, K-pop, electronic\ndance-rock, new wave, 80s\ndance-rock, synth-pop, 80s new wave\ndance-rock, trot-metal\ndance-trot\ndancehall\ndancehall Afro-Latin\ndancehall Afrobeat\ndancehall Afrobeat electronic\ndancehall C-pop tropical house\ndancehall EDM\ndancehall EDM soca\ndancehall French hip-hop\ndancehall French pop\ndancehall French rap\ndancehall J-pop fusion\ndancehall J-pop video game\ndancehall K-pop fusion\ndancehall Punjabi pop\ndancehall R&B\ndancehall R&B Afrobeats\ndancehall R&B afrobeat\ndancehall R&B afrobeats\ndancehall R&B chiptune\ndancehall R&B conscious hip-hop\ndancehall R&B fusion\ndancehall R&B gospel\ndancehall R&B hip-hop\ndancehall R&B pop\ndancehall R&B reggae fusion\ndancehall R&B trap\ndancehall UK garage\ndancehall afro-fusion\ndancehall afro-fusion lo-fi\ndancehall afro-fusion trap\ndancehall afro-house\ndancehall afro-pop\ndancehall afro-swing\ndancehall afro-trap\ndancehall afro-trap chiptune\ndancehall afrobeat\ndancehall afrobeat European hip-hop\ndancehall afrobeat R&B\ndancehall afrobeat conscious hip-hop\ndancehall afrobeat electronic\ndancehall afrobeat gospel\ndancehall afrobeat hip-hop\ndancehall afrobeat lo-fi\ndancehall afrobeat moombahton\ndancehall afrobeat pop\ndancehall afrobeat pop-rap\ndancehall afrobeat trap\ndancehall afrobeats\ndancehall afrobeats R&B\ndancehall afrobeats afropop\ndancehall afrobeats arabic pop\ndancehall afrobeats chiptune\ndancehall afrobeats electronic\ndancehall afrobeats experimental electronic\ndancehall afrobeats french pop\ndancehall afrobeats gospel\ndancehall afrobeats hip-hop\ndancehall afrobeats hyperpop\ndancehall afrobeats lo-fi\ndancehall afrobeats lounge\ndancehall afrobeats moombahton\ndancehall afrobeats pop\ndancehall afrobeats r&b\ndancehall afrobeats reggae\ndancehall afrobeats reggaeton\ndancehall afrobeats rnb\ndancehall afrobeats trap\ndancehall afrobeats tropical\ndancehall afrobeats zouk\ndancehall alternative R&B\ndancehall ambient\ndancehall ambient pop\ndancehall arabic pop\ndancehall bass house\ndancehall bhangra\ndancehall bhangra fusion\ndancehall big beat\ndancehall big beat electronic rock\ndancehall big room\ndancehall bollywood\ndancehall bollywood pop\ndancehall breakbeat\ndancehall brostep\ndancehall chiptune\ndancehall cloud rap\ndancehall cumbia\ndancehall cyberpunk\ndancehall dance-pop\ndancehall deep house\ndancehall deep house afrobeat\ndancehall dembow\ndancehall drill\ndancehall drum and bass\ndancehall dub\ndancehall dub hip-hop\ndancehall dubstep\ndancehall dubstep brostep\ndancehall dubstep neurofunk\ndancehall dubstep reggae\ndancehall electro house\ndancehall electro-house\ndancehall electronic\ndancehall electronic pop\ndancehall electronic rock\ndancehall eurodance\ndancehall freestyle\ndancehall funk\ndancehall fusion\ndancehall gabber\ndancehall gospel\ndancehall gospel afrobeat\ndancehall gospel electronic\ndancehall gospel house\ndancehall gospel pop\ndancehall gospel r&b\ndancehall gospel reggae\ndancehall grime\ndancehall grime trap\ndancehall happy hardcore\ndancehall hardcore\ndancehall hardstyle\ndancehall hardstyle trap\ndancehall hip hop\ndancehall hip hop pop\ndancehall hip-hop\ndancehall hip-hop afrobeat\ndancehall hip-hop afrobeats\ndancehall hip-hop chiptune\ndancehall hip-hop electronic\ndancehall hip-hop fusion\ndancehall hip-hop gospel\ndancehall hip-hop trap\ndancehall horror\ndancehall horrorcore\ndancehall house\ndancehall house reggae\ndancehall hyperpop\ndancehall hyperpop afrobeats\ndancehall hyperpop nightcore\ndancehall indie pop\ndancehall industrial rock\ndancehall j-dancehall\ndancehall j-pop\ndancehall j-pop reggaeton\ndancehall j-rap\ndancehall jazz\ndancehall jazz lounge\ndancehall jazzy\ndancehall jungle\ndancehall latin\ndancehall lo-fi\ndancehall lo-fi hip hop\ndancehall lo-fi hip-hop\ndancehall lover's rock\ndancehall lovers rock\ndancehall mandopop\ndancehall metal\ndancehall moombahton\ndancehall moombahton EDM\ndancehall moombahton bollywood\ndancehall moombahton chiptune\ndancehall moombahton edm\ndancehall moombahton pop\ndancehall moombahton reggaeton\ndancehall moombahton trap\ndancehall nasheed\ndancehall neo-soul\ndancehall neo-soul UK hip-hop\ndancehall neo-soul funk\ndancehall neurofunk\ndancehall new jack swing\ndancehall nu-metal\ndancehall orchestral\ndancehall pop\ndancehall pop R&B\ndancehall pop afrobeat\ndancehall pop afrobeats\ndancehall pop bollywood\ndancehall pop-R&B\ndancehall pop-funk\ndancehall pop-rap\ndancehall pop-rap chiptune\ndancehall pop-reggae\ndancehall pop-reggaeton\ndancehall pop-rock\ndancehall punjabi fusion\ndancehall punjabi pop\ndancehall punk\ndancehall r&b\ndancehall r&b afrobeats\ndancehall r&b reggae fusion\ndancehall ragga\ndancehall rap\ndancehall rap-metal\ndancehall reggae\ndancehall reggae afrobeats\ndancehall reggae chiptune\ndancehall reggae dub\ndancehall reggae fusion\ndancehall reggae gospel\ndancehall reggae latin\ndancehall reggae pop\ndancehall reggae pop-funk\ndancehall reggae ska\ndancehall reggae trap\ndancehall reggae-pop\ndancehall reggaeton\ndancehall reggaeton EDM\ndancehall reggaeton Middle Eastern electronic\ndancehall reggaeton afrobeat\ndancehall reggaeton afrobeats\ndancehall reggaeton balkan pop\ndancehall reggaeton chiptune\ndancehall reggaeton funk\ndancehall reggaeton hyperpop\ndancehall reggaeton moombahton\ndancehall reggaeton pop\ndancehall reggaeton trap\ndancehall reggaeton tropical\ndancehall riddim\ndancehall rock\ndancehall ska\ndancehall soca\ndancehall soca EDM\ndancehall soca gospel\ndancehall soul\ndancehall spiritual\ndancehall synth-pop\ndancehall synth-pop experimental\ndancehall trap\ndancehall trap EDM\ndancehall trap R&B\ndancehall trap afro-fusion\ndancehall trap afrobeats\ndancehall trap drill\ndancehall trap dub\ndancehall trap dubstep\ndancehall trap electronic pop\ndancehall trap gospel\ndancehall trap hardstyle\ndancehall trap lo-fi\ndancehall trap soul\ndancehall trap-soul\ndancehall trip-hop\ndancehall uk garage\ndancehall vaporwave\ndancehall world music\ndancehall zouk\ndancehall zouk afrobeats\ndancehall zouk kompa\ndancehall, 8-bit, chiptune\ndancehall, 90s R&B\ndancehall, 90s house\ndancehall, Balkan brass, electronic dance music\ndancehall, Balkan fusion\ndancehall, Balkan pop\ndancehall, Balkan pop, German rap\ndancehall, Balkan, Middle Eastern\ndancehall, Bollywood\ndancehall, Bollywood pop\ndancehall, Bollywood, electronic\ndancehall, C-pop\ndancehall, Caribbean club\ndancehall, Christmas, upbeat\ndancehall, Desi pop\ndancehall, EDM, trap\ndancehall, Eastern European, Middle Eastern\ndancehall, Eastern European, synthwave\ndancehall, French hip-hop\ndancehall, French rap\ndancehall, French rap, Haitian Creole\ndancehall, German rap\ndancehall, German, comedic\ndancehall, Indonesian, happy hardcore\ndancehall, Japanese hip-hop\ndancehall, Latin hip-hop\ndancehall, Latin pop\ndancehall, Latin, European\ndancehall, Latin, pop\ndancehall, R&B\ndancehall, R&B, Afrobeats\ndancehall, R&B, club\ndancehall, R&B, electronic\ndancehall, R&B, synth-pop\ndancehall, Romanian pop, electronic\ndancehall, South Asian, Middle Eastern\ndancehall, South Asian, electronic\ndancehall, South Asian, pop\ndancehall, South Asian, upbeat\ndancehall, South Indian film music\ndancehall, South Indian pop\ndancehall, Swedish, gangster rap\ndancehall, UK drill\ndancehall, UK garage\ndancehall, UK hip-hop\ndancehall, UK rap, electronic\ndancehall, afro-dancehall, gospel\ndancehall, afro-fusion, gospel\ndancehall, afro-soul\ndancehall, afrobeat\ndancehall, afrobeat, Polish\ndancehall, afrobeat, electronic\ndancehall, afrobeat, emotional pop\ndancehall, afrobeat, hyperpop\ndancehall, afrobeat, moombahton\ndancehall, afrobeat, trap\ndancehall, afrobeat, tropical\ndancehall, afrobeats, R&B\ndancehall, afrobeats, hyperpop\ndancehall, afrobeats, trap\ndancehall, alternative R&B\ndancehall, big room house\ndancehall, bilingual, electronic\ndancehall, brass pop, multilingual\ndancehall, breakbeat, big beat\ndancehall, brostep, electronic\ndancehall, brostep, reggae-pop\ndancehall, children's music, island\ndancehall, chiptune\ndancehall, chiptune, R&B\ndancehall, chiptune, digital\ndancehall, chiptune, electronic\ndancehall, chiptune, funk carioca\ndancehall, chiptune, future bass\ndancehall, chiptune, reggaeton\ndancehall, cinematic\ndancehall, cinematic, dark\ndancehall, cinematic, dub\ndancehall, cinematic, electronic\ndancehall, cinematic, gospel\ndancehall, cinematic, orchestral\ndancehall, cinematic, ragga\ndancehall, cinematic, trap\ndancehall, city pop, retro\ndancehall, cloud rap\ndancehall, cloud rap, afro-fusion\ndancehall, conscious reggae\ndancehall, dangdut koplo\ndancehall, dark ambient, lo-fi\ndancehall, dark sci-fi, horror\ndancehall, dark wave, sci-fi\ndancehall, dark, aggressive\ndancehall, dark, trap\ndancehall, dembow, bilingual\ndancehall, dembow, club\ndancehall, dembow, electronic\ndancehall, dembow, multi-lingual\ndancehall, dembow, multilingual\ndancehall, dembow, pop\ndancehall, digital, chiptune\ndancehall, drum and bass, French\ndancehall, dub, electronic\ndancehall, dub, militant\ndancehall, dub, political\ndancehall, dubstep, electronic\ndancehall, early house\ndancehall, electronic dance\ndancehall, electronic dance music\ndancehall, electronic funk, Christmas\ndancehall, electronic, Brazilian funk\ndancehall, electronic, Hindi pop\ndancehall, electronic, Middle Eastern\ndancehall, electronic, Southeast Asian\ndancehall, electronic, bilingual\ndancehall, electronic, chiptune\ndancehall, electronic, folk fusion\ndancehall, electronic, hip hop\ndancehall, electronic, hyperpop\ndancehall, electronic, minimalist\ndancehall, electronic, multilingual\ndancehall, electronic, pop\ndancehall, electronic, reggaeton\ndancehall, electronic, sci-fi\ndancehall, festive, R&B\ndancehall, festive, electronic\ndancehall, festive, melancholic\ndancehall, festive, reggae\ndancehall, future bass\ndancehall, future bass, chiptune\ndancehall, future bass, electronic\ndancehall, future bass, trap\ndancehall, gangster rap\ndancehall, glitch, experimental\ndancehall, global beat\ndancehall, happy hardcore, hardstyle\ndancehall, hard rock, electronic dance music\ndancehall, hardstyle\ndancehall, hardstyle, moombahton\ndancehall, hardstyle, reggae\ndancehall, heavy bass\ndancehall, heavy bass, trap\ndancehall, hip hop\ndancehall, hip-hop\ndancehall, horror, electronic\ndancehall, horrorcore\ndancehall, hyperpop\ndancehall, hyperpop, chiptune\ndancehall, industrial, dark electronic\ndancehall, laïko, fusion\ndancehall, lo-fi hip hop, electronic\ndancehall, lo-fi, R&B\ndancehall, lo-fi, atmospheric\ndancehall, lo-fi, bilingual\ndancehall, lo-fi, emotional\ndancehall, lo-fi, melancholic\ndancehall, lo-fi, trap\ndancehall, moombahton\ndancehall, moombahton, EDM\ndancehall, moombahton, Indian pop\ndancehall, moombahton, Middle Eastern\ndancehall, moombahton, Punjabi fusion\ndancehall, moombahton, R&B\ndancehall, moombahton, dembow\ndancehall, moombahton, dubstep\ndancehall, moombahton, electronic\ndancehall, moombahton, electronic trap\ndancehall, moombahton, global pop\ndancehall, moombahton, hard dancehall\ndancehall, moombahton, hyperpop\ndancehall, moombahton, pop\ndancehall, neurofunk\ndancehall, neurofunk, drum and bass\ndancehall, new jack swing\ndancehall, new jack swing, R&B\ndancehall, new jack swing, chiptune\ndancehall, new jack swing, funk\ndancehall, nightcore, happy hardcore\ndancehall, orchestral, electronic\ndancehall, party, bilingual\ndancehall, pop, Indonesian\ndancehall, pop, chiptune\ndancehall, pop, cinematic\ndancehall, pop, electronic\ndancehall, pop, fusion\ndancehall, pop-folk, hip-hop\ndancehall, reggae\ndancehall, reggae, pop\ndancehall, reggae, protest\ndancehall, reggaeton\ndancehall, reggaeton, Eastern European\ndancehall, reggaeton, Indonesian\ndancehall, reggaeton, Uzbek\ndancehall, reggaeton, afrobeat\ndancehall, reggaeton, chiptune\ndancehall, reggaeton, moombahton\ndancehall, reggaeton, multilingual\ndancehall, reggaeton, world fusion\ndancehall, retro digital\ndancehall, retro synth, Latin pop\ndancehall, retro, synthpop\ndancehall, retro-futuristic, chiptune\ndancehall, sci-fi, electronic\ndancehall, soca\ndancehall, soul\ndancehall, synth-pop\ndancehall, synthwave, funk-rock\ndancehall, trap\ndancehall, trap, R&B\ndancehall, trap, aggro\ndancehall, trap, ambient\ndancehall, trap, cinematic\ndancehall, trap, dark\ndancehall, trap, dark ambient\ndancehall, trap, drill\ndancehall, trap, electronic\ndancehall, trap, future bass\ndancehall, trap, futuristic\ndancehall, trap, hard bass\ndancehall, trap, lo-fi\ndancehall, trap, pop\ndancehall, trap-soul\ndancehall, tropical pop, dembow\ndancehall, tropical pop, electronic\ndancehall, tropical, K-pop\ndancehall, tropical, chill\ndancehall, tropical, dembow\ndancehall, tropical, reggaeton\ndancehall, tropical, synth\ndancehall, world fusion\ndancehall, world fusion, electronic\ndancehall, world music, ambient\ndancehall, zouk, afrobeats\ndancehall-EDM\ndancehall-lite\ndancehall-pop\ndancehall-pop afrobeats\ndancehall-pop chiptune\ndancehall-pop moombahton\ndancehall-pop reggaeton\ndancehall-pop, cinematic, theatrical\ndancehall-reggae\ndancehall-reggae fusion\ndancehall-reggae, Islamic devotional\ndancehall-reggaeton\ndancehall-reggaeton hip-hop\ndancehall-trap\ndangdut\ndangdut campursari\ndangdut disco\ndangdut funk\ndangdut house\ndangdut kids\ndangdut koplo\ndangdut koplo chiptune\ndangdut koplo cinematic\ndangdut koplo city pop\ndangdut koplo funk\ndangdut koplo funkot\ndangdut koplo happy hardcore\ndangdut koplo hip-hop\ndangdut koplo metal\ndangdut koplo pop\ndangdut koplo pop ballad\ndangdut koplo pop-rock\ndangdut koplo psychedelic rock\ndangdut koplo punk rock\ndangdut koplo rock\ndangdut koplo, Javanese pop, cinematic\ndangdut koplo, campursari, Indonesian pop\ndangdut koplo, chiptune, electronic dance\ndangdut koplo, chiptune, pop\ndangdut koplo, chiptune, pop-rock\ndangdut koplo, cinematic pop, Sundanese traditional\ndangdut koplo, cinematic pop, traditional fusion\ndangdut koplo, cinematic pop, vocaloid\ndangdut koplo, cinematic, Indonesian pop\ndangdut koplo, cinematic, Javanese\ndangdut koplo, cinematic, Malay traditional\ndangdut koplo, cinematic, ambient\ndangdut koplo, cinematic, ballad\ndangdut koplo, cinematic, electronic\ndangdut koplo, cinematic, ney flute\ndangdut koplo, cinematic, pop-rock\ndangdut koplo, cinematic, traditional\ndangdut koplo, cinematic, traditional Javanese\ndangdut koplo, cinematic, traditional Malay\ndangdut koplo, city pop, pop\ndangdut koplo, dance-pop, acoustic\ndangdut koplo, electronic dance, pop\ndangdut koplo, electronic, Javanese pop\ndangdut koplo, funk, pop\ndangdut koplo, happy hardcore, gabber\ndangdut koplo, hard rock\ndangdut koplo, heavy metal\ndangdut koplo, heavy rock\ndangdut koplo, jazz, pop-rock\ndangdut koplo, piano ballad\ndangdut koplo, pop, Javanese\ndangdut koplo, pop, hip-hop\ndangdut koplo, pop-rock, Javanese\ndangdut koplo, pop-rock, cinematic ballad\ndangdut koplo, pop-ska, 80s pop\ndangdut koplo, sentimental pop\ndangdut koplo, sentimental pop, Javanese ballad\ndangdut koplo, traditional Javanese, ambient\ndangdut pop\ndangdut pop chanson\ndangdut pop chiptune\ndangdut pop rock\ndangdut reggae\ndangdut rock\ndangdut ska\ndangdut, Sundanese pop\ndangdut, baroque pop\ndangdut, campursari, lo-fi pop\ndangdut, cinematic, nostalgic\ndanish hip hop\ndanish hip-hop\ndansband\ndansband cabaret\ndansband country-pop\ndansband country-rock\ndansband rockabilly\ndansband schlager\ndansband, Latin pop\ndansband, schlager, Christmas\ndanseband\ndansktop\ndark Americana\ndark C-pop\ndark C-pop trap\ndark EDM\ndark German trap\ndark K-pop hip-hop\ndark K-pop trap-R&B\ndark K-pop, trap, industrial metal\ndark Latin pop\ndark Latin trap\ndark R&B\ndark R&B trap\ndark R&B trap hyperpop\ndark R&B trap-pop\ndark R&B trap-soul\ndark R&B, Latin trap\ndark R&B, dancehall, trap\ndark R&B, trap\ndark R&B, trap, Latin\ndark R&B, trap, Latin pop\ndark R&B, trap, ambient\ndark R&B, trap, future bass\ndark R&B, trap, hyperpop\ndark R&B, trap, lo-fi\ndark R&B, trap-soul\ndark Turkish hip-hop\ndark acoustic\ndark alt-pop\ndark alternative R&B\ndark alternative pop\ndark ambient\ndark ambient EBM\ndark ambient deep house\ndark ambient hip hop\ndark ambient hip-hop\ndark ambient industrial\ndark ambient reggaeton\ndark ambient rock\ndark ambient techno\ndark ambient trap\ndark ambient trip-hop\ndark ambient, IDM, industrial rock\ndark ambient, cinematic, Chinese opera\ndark ambient, cinematic, folktronica\ndark ambient, darkwave, EBM\ndark ambient, electronic, trap\ndark ambient, hardstyle, cinematic\ndark ambient, industrial techno\ndark ambient, neurofunk, industrial\ndark ambient, trap, future bass\ndark ambient, trip-hop, experimental electronica\ndark ambient, world music, meditative\ndark art-pop\ndark ballad\ndark bass\ndark boom-bap\ndark breakbeat\ndark cabaret\ndark cabaret chiptune\ndark cabaret funk-rock industrial\ndark cabaret hip-hop\ndark cabaret jazz\ndark cabaret punk\ndark cabaret punk rock\ndark cabaret rock\ndark cabaret trip-hop\ndark cabaret, Eastern European folk\ndark cabaret, cyberpunk, lo-fi\ndark cabaret, operatic, film score\ndark chamber music\ndark chanson\ndark children's music\ndark chiptune\ndark cinematic\ndark cloud rap\ndark club\ndark comedy\ndark comedy folk\ndark country\ndark country rock\ndark country trap\ndark country-rock\ndark dance-pop\ndark dancehall\ndark dancehall trap\ndark dancehall trap-reggae\ndark deep house\ndark disco\ndark disco, EBM, electro-pop\ndark drill\ndark electro\ndark electro house\ndark electro phonk\ndark electro, synth-pop\ndark electro-pop\ndark electronic\ndark electronic J-pop\ndark electronic J-pop trap\ndark electronic R&B\ndark electronic breakcore\ndark electronic hip-hop\ndark electronic phonk\ndark electronic pop\ndark electronic rock\ndark electronic trap\ndark electronic trap synth-pop\ndark electronic, reggaeton, Middle Eastern synth\ndark electronic, trap, Arabic fusion\ndark electronic, trap, Middle Eastern\ndark electropop\ndark fairy tale\ndark fairytale\ndark fantasy\ndark fantasy rock\ndark folk\ndark folk ambient\ndark folk gothic americana\ndark folk metal\ndark folk, industrial rock\ndark folk-rock\ndark folk-trap\ndark funk\ndark funk-rock\ndark hip hop\ndark hip-hop\ndark hip-hop chiptune\ndark hip-hop drum and bass hyperpop\ndark hip-hop, trap\ndark house\ndark humor children's music\ndark hyperpop\ndark indie pop\ndark indie rock\ndark indie-pop\ndark jazz\ndark lullaby\ndark metal\ndark nursery rhyme\ndark phonk\ndark pop\ndark pop R&B\ndark pop R&B trap\ndark pop alternative R&B\ndark pop alternative rock\ndark pop chiptune\ndark pop cyberpunk\ndark pop electro\ndark pop electro-pop\ndark pop electro-swing\ndark pop electronic\ndark pop electronic rock\ndark pop electronic trap\ndark pop electropop\ndark pop emo rap\ndark pop emo trap\ndark pop funk\ndark pop future bass\ndark pop future garage\ndark pop glitchcore\ndark pop hip-hop\ndark pop industrial\ndark pop industrial electronic\ndark pop industrial pop\ndark pop industrial rock\ndark pop jazz hip-hop\ndark pop latin\ndark pop reggaeton\ndark pop slap house\ndark pop synthwave trap\ndark pop techno\ndark pop trap\ndark pop trap R&B\ndark pop trap ambient\ndark pop trap industrial\ndark pop trap industrial rock\ndark pop trap metal\ndark pop trap-R&B\ndark pop trap-soul\ndark pop trip-hop\ndark pop witch house\ndark pop, EDM\ndark pop, EDM, cyberpunk\ndark pop, EDM, electro-pop\ndark pop, EDM, future bass\ndark pop, J-pop, cinematic electronic\ndark pop, K-pop\ndark pop, K-pop, electronic rock\ndark pop, K-pop, trap\ndark pop, Latin R&B, trap\ndark pop, Latin electronic\ndark pop, Latin pop\ndark pop, Latin trap\ndark pop, Latin trap, hyperpop\ndark pop, R&B\ndark pop, R&B, cinematic\ndark pop, R&B, nu-metal\ndark pop, R&B, trap\ndark pop, alternative R&B\ndark pop, alternative R&B, Latin pop\ndark pop, alternative R&B, electronic pop\ndark pop, alternative R&B, trap\ndark pop, alternative rock, trap\ndark pop, ambient, trap\ndark pop, bass music\ndark pop, chiptune, trap\ndark pop, cinematic, Middle Eastern\ndark pop, cinematic, electronic\ndark pop, cinematic, industrial metal\ndark pop, cinematic, theatrical\ndark pop, cinematic, trap\ndark pop, cloud rap\ndark pop, cyberpunk, cinematic\ndark pop, cyberpunk, trap\ndark pop, dance-pop\ndark pop, deep house\ndark pop, dubstep\ndark pop, dubstep, chiptune\ndark pop, dubstep, metalcore\ndark pop, electro-pop, EBM\ndark pop, electro-pop, dance\ndark pop, electronic\ndark pop, electronic dance\ndark pop, electronic dance music\ndark pop, electronic dance, hip-hop\ndark pop, electronic dance, house\ndark pop, electronic rock\ndark pop, electronic trap\ndark pop, electronic, Middle Eastern\ndark pop, electronic, cinematic\ndark pop, electronic, cyberpunk\ndark pop, electronic, experimental\ndark pop, electronic, hip-hop\ndark pop, electronic, lo-fi hip hop\ndark pop, electronic, trap\ndark pop, emotional trap\ndark pop, ethnic trap\ndark pop, experimental electronic\ndark pop, future bass, electronic\ndark pop, hardstyle, electronic\ndark pop, hardwave, lo-fi country\ndark pop, hip-hop\ndark pop, hip-hop, electronic\ndark pop, hyperpop\ndark pop, hyperpop, electronic rock\ndark pop, hyperpop, experimental electronic\ndark pop, hyperpop, industrial\ndark pop, hyperpop, trap\ndark pop, industrial electronic\ndark pop, industrial rock, cinematic\ndark pop, industrial, EBM\ndark pop, industrial, electronic rock\ndark pop, industrial, glitch-hop\ndark pop, industrial, trap\ndark pop, latin trap\ndark pop, latin urban\ndark pop, lo-fi, industrial\ndark pop, metalcore\ndark pop, metalcore, electronic\ndark pop, neoclassical electronica\ndark pop, phonk, industrial\ndark pop, slap house\ndark pop, synth-pop\ndark pop, synth-pop, electronic\ndark pop, tech house\ndark pop, techno, hyperpop\ndark pop, theatrical, Persian\ndark pop, trance, techno\ndark pop, trap\ndark pop, trap metal\ndark pop, trap, Chinese rap\ndark pop, trap, K-pop\ndark pop, trap, R&B\ndark pop, trap, alternative R&B\ndark pop, trap, ambient\ndark pop, trap, bilingual\ndark pop, trap, chiptune\ndark pop, trap, cinematic\ndark pop, trap, cyberpunk\ndark pop, trap, dance-pop\ndark pop, trap, dubstep\ndark pop, trap, electronic\ndark pop, trap, experimental R&B\ndark pop, trap, experimental electronic\ndark pop, trap, future bass\ndark pop, trap, hard electronic\ndark pop, trap, hip-hop\ndark pop, trap, hyperpop\ndark pop, trap, industrial\ndark pop, trap, reggaeton\ndark pop, trap, synth-pop\ndark pop, trap, synthwave\ndark pop, trap, theatrical\ndark pop, trap, vaporwave\ndark pop, trap-R&B\ndark pop, trip-hop\ndark pop, trip-hop, ambient\ndark pop, trip-hop, electronic\ndark pop, trip-hop, lo-fi hip-hop\ndark pop-R&B\ndark pop-metal\ndark pop-punk\ndark pop-rap\ndark pop-rock\ndark pop-rock metalcore\ndark pop-trap\ndark progressive house\ndark progressive techno\ndark psytrance\ndark reggaeton\ndark reggaeton trap\ndark rock\ndark soul\ndark synth\ndark synth hip-hop\ndark synth rock\ndark synth-funk\ndark synth-pop\ndark synth-pop EBM\ndark synth-pop industrial pop\ndark synth-pop industrial rock\ndark synth-pop trap\ndark synthpop\ndark synthpop chiptune\ndark synthpop industrial\ndark synthpop, dubstep\ndark synthwave\ndark synthwave chiptune\ndark synthwave trap\ndark tech house\ndark tech-house\ndark techno\ndark techno progressive house\ndark techno, EBM\ndark techno, EBM, electro-pop\ndark techno, EBM, hardstyle\ndark techno, EBM, hip-hop\ndark techno, EBM, industrial\ndark techno, Polish hip-hop\ndark techno, Turkish hip-hop\ndark techno, hardstyle, ambient\ndark techno, synthwave, trance\ndark trance\ndark trap\ndark trap R&B\ndark trap alternative R&B\ndark trap alternative rock\ndark trap ambient\ndark trap chiptune\ndark trap drill\ndark trap emo rap\ndark trap fantasy\ndark trap future bass\ndark trap gothic rock\ndark trap hip-hop\ndark trap hyperpop\ndark trap industrial rock\ndark trap lo-fi\ndark trap metalcore\ndark trap nu-metal\ndark trap orchestral\ndark trap phonk\ndark trap witch house\ndark trap, Brazilian hip-hop\ndark trap, C-Rap\ndark trap, Chinese hip-hop\ndark trap, Eastern European folk\ndark trap, French rap\ndark trap, German battle rap\ndark trap, German cloud rap\ndark trap, German gangsta rap\ndark trap, Greek hip-hop\ndark trap, J-rock\ndark trap, J-rock, nu-metal\ndark trap, Korean hip-hop\ndark trap, Latin hip-hop\ndark trap, Latin trap\ndark trap, Latin urban\ndark trap, Middle Eastern\ndark trap, Middle Eastern electronic\ndark trap, Middle Eastern fusion\ndark trap, North African hip-hop\ndark trap, R&B\ndark trap, Russian hip-hop\ndark trap, South Asian hip-hop\ndark trap, Turkish hip-hop\ndark trap, Turkish hip-hop, theatrical\ndark trap, Turkish rap\ndark trap, alternative R&B\ndark trap, alternative R&B, glitch-pop\ndark trap, alternative pop\ndark trap, ambient\ndark trap, ambient pop, experimental electronic\ndark trap, atmospheric electronic\ndark trap, chiptune electronica\ndark trap, chiptune, gangsta rap\ndark trap, chiptune, hyperpop\ndark trap, chiptune, phonk\ndark trap, cinematic\ndark trap, cinematic electronic\ndark trap, cinematic electronic, ethereal folk\ndark trap, cinematic hip hop\ndark trap, cinematic hip-hop\ndark trap, cinematic horrorcore\ndark trap, cinematic synth, chiptune\ndark trap, cinematic synth-pop\ndark trap, cinematic, Chinese hip hop\ndark trap, cinematic, Middle Eastern fusion\ndark trap, cinematic, anime\ndark trap, cinematic, baroque\ndark trap, cinematic, experimental\ndark trap, cinematic, experimental electronic\ndark trap, cinematic, hardwave\ndark trap, cinematic, orchestral\ndark trap, cinematic, world music\ndark trap, cloud rap\ndark trap, cloud rap, cinematic\ndark trap, cloud rap, cyberpunk\ndark trap, cloud rap, world music\ndark trap, conscious hip-hop\ndark trap, dubstep\ndark trap, emo rap\ndark trap, emo rap, alternative hip-hop\ndark trap, emo rap, cinematic electronic\ndark trap, emo rap, cloud rap\ndark trap, emo rap, hyperpop\ndark trap, emotional pop\ndark trap, ethereal R&B\ndark trap, experimental electronic\ndark trap, experimental hip-hop\ndark trap, experimental, psychedelic\ndark trap, future bass, experimental electronic\ndark trap, glitch-hop\ndark trap, gothic pop\ndark trap, hardstyle\ndark trap, hardstyle, EDM\ndark trap, hardstyle, cinematic\ndark trap, hardstyle, dubstep\ndark trap, hardstyle, phonk\ndark trap, hip-hop\ndark trap, horrorcore\ndark trap, horrorcore, Balkan rap\ndark trap, horrorcore, Turkish hip-hop\ndark trap, horrorcore, industrial\ndark trap, horrorcore, industrial hip-hop\ndark trap, horrorcore, video game\ndark trap, hyperpop\ndark trap, hyperpop, Chinese rap\ndark trap, hyperpop, chiptune\ndark trap, hyperpop, electronic pop\ndark trap, hyperpop, glitchcore\ndark trap, hyperpop, pluggnb\ndark trap, industrial hip-hop, chiptune\ndark trap, industrial metal\ndark trap, industrial rock\ndark trap, industrial, Japanese\ndark trap, industrial, glitch\ndark trap, industrial, hyperpop\ndark trap, latin trap\ndark trap, lo-fi hip hop, jazz rap\ndark trap, lo-fi hip-hop\ndark trap, melodic R&B\ndark trap, metalcore\ndark trap, nerdcore\ndark trap, operatic hip hop\ndark trap, orchestral, anime\ndark trap, orchestral, cinematic\ndark trap, phonk\ndark trap, phonk, East Asian melodic\ndark trap, phonk, cinematic electronic\ndark trap, phonk, electronic\ndark trap, phonk, experimental electronic\ndark trap, phonk, experimental hip-hop\ndark trap, phonk, horrorcore\ndark trap, phonk, industrial\ndark trap, psychedelic rock\ndark trap, ritualistic, cinematic\ndark trap, synth-pop, chiptune\ndark trap, synth-pop, metalcore\ndark trap, synthwave\ndark trap, witch house\ndark trap, world music, Hindi hip hop\ndark trap-pop\ndark trap-reggaeton\ndark trip-hop\ndark wave\ndark wave, hard rock, baroque synth\ndark-pop\ndarksynth\ndarksynth ambient\ndarksynth cyberpunk\ndarksynth ebm\ndarksynth electro\ndarksynth industrial\ndarksynth industrial metal\ndarksynth industrial metalcore\ndarksynth industrial techno\ndarksynth lo-fi\ndarksynth, EBM, industrial techno\ndarksynth, EBM, synthwave\ndarksynth, industrial techno, synthwave\ndarksynth, industrial, trance\ndarksynth, synthwave\ndarksynth, trip-hop, cinematic\ndarkwave\ndarkwave EBM\ndarkwave alternative rock\ndarkwave ambient\ndarkwave chanson\ndarkwave chiptune\ndarkwave cinematic\ndarkwave coldwave synth-pop\ndarkwave cyberpop\ndarkwave cyberpunk\ndarkwave dream pop\ndarkwave electronic\ndarkwave electronic pop\ndarkwave emo-rap\ndarkwave future bass\ndarkwave goth rock\ndarkwave goth rock chiptune\ndarkwave gothic metal\ndarkwave gothic rock\ndarkwave hip-hop\ndarkwave hyperpop\ndarkwave indie dance\ndarkwave industrial\ndarkwave industrial chiptune\ndarkwave industrial dance\ndarkwave industrial gothic\ndarkwave industrial hyperpop\ndarkwave industrial metal\ndarkwave industrial post-punk\ndarkwave industrial rock\ndarkwave industrial techno\ndarkwave lo-fi\ndarkwave lo-fi indie\ndarkwave metal\ndarkwave phonk\ndarkwave post-punk\ndarkwave post-punk alternative rock\ndarkwave post-punk trap\ndarkwave progressive trance\ndarkwave psychedelic rock\ndarkwave reggaeton\ndarkwave shoegaze\ndarkwave symphonic metal\ndarkwave synth-pop\ndarkwave synth-pop hip-hop\ndarkwave synth-rock\ndarkwave synthwave\ndarkwave synthwave EBM\ndarkwave synthwave industrial\ndarkwave synthwave industrial techno\ndarkwave tech-house\ndarkwave techno\ndarkwave techno ambient\ndarkwave techno-pop\ndarkwave trance\ndarkwave trap\ndarkwave trap metal\ndarkwave trip-hop\ndarkwave trip-hop Middle Eastern\ndarkwave witch house\ndarkwave, 80s gothic, chiptune\ndarkwave, 80s post-punk, synth-pop\ndarkwave, 80s, Neue Deutsche Welle\ndarkwave, EBM\ndarkwave, EBM, 80s synth\ndarkwave, EBM, Persian electronic\ndarkwave, EBM, Turkish hip-hop\ndarkwave, EBM, ambient\ndarkwave, EBM, ambient electronic\ndarkwave, EBM, chiptune\ndarkwave, EBM, cinematic\ndarkwave, EBM, cinematic electronic\ndarkwave, EBM, cinematic horror\ndarkwave, EBM, cinematic rock\ndarkwave, EBM, cinematic synth\ndarkwave, EBM, cinematic techno\ndarkwave, EBM, cold wave\ndarkwave, EBM, cyberpunk\ndarkwave, EBM, dream-pop\ndarkwave, EBM, electronic\ndarkwave, EBM, ethereal wave\ndarkwave, EBM, futurepop\ndarkwave, EBM, gothic industrial\ndarkwave, EBM, gothic rock\ndarkwave, EBM, hard techno\ndarkwave, EBM, hard trance\ndarkwave, EBM, hip-hop\ndarkwave, EBM, hypnotic electronic\ndarkwave, EBM, industrial\ndarkwave, EBM, industrial dance\ndarkwave, EBM, industrial hip-hop\ndarkwave, EBM, industrial metal\ndarkwave, EBM, industrial rock\ndarkwave, EBM, industrial techno\ndarkwave, EBM, minimal techno\ndarkwave, EBM, neoclassical\ndarkwave, EBM, pop\ndarkwave, EBM, post-punk\ndarkwave, EBM, retro-futuristic\ndarkwave, EBM, retrowave\ndarkwave, EBM, synth-pop\ndarkwave, EBM, synth-punk\ndarkwave, EBM, synthwave\ndarkwave, EBM, techno\ndarkwave, EBM, theatrical\ndarkwave, EBM, tribal pop\ndarkwave, EDM, rap\ndarkwave, German cloud rap\ndarkwave, German rap\ndarkwave, Neue Deutsche Härte\ndarkwave, Neue Deutsche Welle\ndarkwave, Neue Deutsche Welle, synthwave\ndarkwave, Russian post-punk\ndarkwave, Turkish rock\ndarkwave, alternative R&B\ndarkwave, ambient, EBM\ndarkwave, ambient, electronic\ndarkwave, ambient, ethereal\ndarkwave, chiptune, electronic\ndarkwave, chiptune, gothic synth\ndarkwave, chiptune, industrial\ndarkwave, chiptune, post-punk\ndarkwave, chiptune, synthwave\ndarkwave, chiptune, theatrical\ndarkwave, cinematic pop\ndarkwave, cinematic synth\ndarkwave, cinematic synth, Russian pop\ndarkwave, cinematic synth, industrial rock\ndarkwave, cinematic synth, sci-fi\ndarkwave, cinematic, EBM\ndarkwave, cinematic, cyberpunk\ndarkwave, cinematic, dream-pop\ndarkwave, cinematic, electronic\ndarkwave, cinematic, horror\ndarkwave, cinematic, industrial techno\ndarkwave, cinematic, techno\ndarkwave, coldwave, chiptune\ndarkwave, coldwave, post-punk\ndarkwave, coldwave, synth-pop\ndarkwave, coldwave, synthwave\ndarkwave, cyberpunk, EBM\ndarkwave, cyberpunk, ambient\ndarkwave, cyberpunk, electronic\ndarkwave, cyberpunk, ethereal\ndarkwave, cyberpunk, industrial rock\ndarkwave, cyberpunk, synthwave\ndarkwave, dream pop\ndarkwave, dream pop, synth-pop\ndarkwave, dream-pop, synth-pop\ndarkwave, electronic dance music\ndarkwave, electronic pop, C-pop\ndarkwave, electronic, Russian pop-rap\ndarkwave, electronic, Russian rap\ndarkwave, electronic, ethnic\ndarkwave, electronic, industrial\ndarkwave, electronic, synthwave\ndarkwave, ethereal wave\ndarkwave, ethno-electronic, ambient\ndarkwave, ethno-techno\ndarkwave, eurodance\ndarkwave, experimental electronic\ndarkwave, experimental electronic, psychedelic\ndarkwave, experimental pop\ndarkwave, experimental post-punk\ndarkwave, futurewave, trap\ndarkwave, goth rock, 80s synth\ndarkwave, gothic pop, synth-pop\ndarkwave, gothic rock\ndarkwave, gothic rock, 80s\ndarkwave, gothic rock, cinematic\ndarkwave, gothic rock, industrial\ndarkwave, gothic rock, post-punk\ndarkwave, gothic rock, synth-pop\ndarkwave, gothic rock, synthwave\ndarkwave, gothic synth-pop\ndarkwave, gothic techno\ndarkwave, hard techno\ndarkwave, hyperpop\ndarkwave, industrial\ndarkwave, industrial EBM\ndarkwave, industrial EBM, Turkish electronic\ndarkwave, industrial dance\ndarkwave, industrial dance, EBM\ndarkwave, industrial electronic\ndarkwave, industrial metal, ambient\ndarkwave, industrial metal, cinematic\ndarkwave, industrial pop, ambient\ndarkwave, industrial rock\ndarkwave, industrial rock, EBM\ndarkwave, industrial rock, ambient\ndarkwave, industrial rock, cinematic synth\ndarkwave, industrial rock, gothic\ndarkwave, industrial rock, shoegaze\ndarkwave, industrial techno\ndarkwave, industrial techno, Middle Eastern\ndarkwave, industrial techno, Turkish rap\ndarkwave, industrial techno, ambient\ndarkwave, industrial techno, cinematic electronic\ndarkwave, industrial, EBM\ndarkwave, industrial, Persian rap\ndarkwave, industrial, ambient\ndarkwave, industrial, chiptune\ndarkwave, industrial, cinematic\ndarkwave, industrial, cinematic electronic\ndarkwave, industrial, cyberpunk\ndarkwave, industrial, electronic\ndarkwave, industrial, gothic\ndarkwave, industrial, gothic rock\ndarkwave, industrial, synth-pop\ndarkwave, lo-fi, industrial\ndarkwave, melodic techno\ndarkwave, minimal synth-pop\ndarkwave, new wave, synth-pop\ndarkwave, post-punk\ndarkwave, post-punk, 80s synth\ndarkwave, post-punk, EBM\ndarkwave, post-punk, alternative rock\ndarkwave, post-punk, ambient electronic\ndarkwave, post-punk, chiptune\ndarkwave, post-punk, coldwave\ndarkwave, post-punk, electronic\ndarkwave, post-punk, gothic rock\ndarkwave, post-punk, industrial rock\ndarkwave, post-punk, synth-driven\ndarkwave, post-punk, synth-pop\ndarkwave, post-punk, synthwave\ndarkwave, post-punk, trap\ndarkwave, progressive house\ndarkwave, progressive trance\ndarkwave, retro-futuristic, cinematic\ndarkwave, ritualistic chant, world music\ndarkwave, slap house\ndarkwave, symphonic metal\ndarkwave, synth-pop\ndarkwave, synth-pop, 80s new wave\ndarkwave, synth-pop, EBM\ndarkwave, synth-pop, French cloud rap\ndarkwave, synth-pop, German cloud rap\ndarkwave, synth-pop, Persian cinematic\ndarkwave, synth-pop, Russian post-punk\ndarkwave, synth-pop, aggressive hip-hop\ndarkwave, synth-pop, ambient\ndarkwave, synth-pop, anime soundtrack\ndarkwave, synth-pop, chiptune\ndarkwave, synth-pop, cinematic\ndarkwave, synth-pop, dream pop\ndarkwave, synth-pop, electro-pop\ndarkwave, synth-pop, electronic hip-hop\ndarkwave, synth-pop, electronic pop\ndarkwave, synth-pop, goth rock\ndarkwave, synth-pop, lo-fi hip-hop\ndarkwave, synth-pop, post-punk\ndarkwave, synth-pop, techno\ndarkwave, synth-rock\ndarkwave, synth-rock, 80s\ndarkwave, synthpop, EBM\ndarkwave, synthwave\ndarkwave, synthwave, Russian hip-hop\ndarkwave, synthwave, chiptune\ndarkwave, synthwave, electronic\ndarkwave, tech house\ndarkwave, tech-trance\ndarkwave, techno, EBM\ndarkwave, techno, ambient\ndarkwave, techno, electronic\ndarkwave, techno, ethereal\ndarkwave, techno, neo-classical\ndarkwave, trance, ritual ambient\ndarkwave, trap, synth-pop\ndarkwave, trap, synthwave\ndarkwave, trip-hop, experimental pop\ndarkwave, trip-hop, industrial electronic\ndarkwave, vaporwave, lo-fi\ndeath metal\ndeath metal grindcore\ndeath metal thrash metal\ndeath metal, cinematic, ambient\ndeathcore\ndeathcore chiptune\ndeathcore dubstep\ndeathcore grindcore\ndeathstep\ndeconstructed club\ndeconstructed hip-hop\ndeconstructed reggaeton\ndeep house\ndeep house Afro-Latin\ndeep house Afro-house\ndeep house Afro-tinged\ndeep house Arabic fusion\ndeep house Bollywood\ndeep house C-pop\ndeep house Indian devotional\ndeep house K-R&B\ndeep house Mandopop\ndeep house Punjabi\ndeep house R&B\ndeep house R&B hip-hop\ndeep house acid jazz\ndeep house afro house\ndeep house afro-house\ndeep house afro-house tribal\ndeep house afro-latin\ndeep house afro-tech\ndeep house afrobeat\ndeep house afrobeat R&B\ndeep house afrobeat dancehall\ndeep house afrobeat pop\ndeep house afrobeats r&b\ndeep house afrofuturist\ndeep house alternative R&B\ndeep house amapiano\ndeep house ambient\ndeep house ambient pop\ndeep house ambient techno\ndeep house bossa nova\ndeep house chillwave\ndeep house chillwave afrobeat\ndeep house chillwave world music\ndeep house cinematic\ndeep house downtempo\ndeep house downtempo lounge\ndeep house dream pop\ndeep house electro chiptune\ndeep house electro-pop\ndeep house ethnic electronica\ndeep house experimental pop\ndeep house flamenco\ndeep house flamenco pop\ndeep house funk\ndeep house funk jazz fusion\ndeep house funk lounge\ndeep house future bass\ndeep house future garage\ndeep house garage house\ndeep house gospel\ndeep house hip-hop\ndeep house hip-house\ndeep house indie dance\ndeep house j-pop\ndeep house jazz\ndeep house jazz funk\ndeep house k-pop\ndeep house latin\ndeep house latin house\ndeep house latin jazz\ndeep house latin pop\ndeep house latin urban\ndeep house lo-fi\ndeep house lo-fi hip hop\ndeep house lo-fi hip-hop\ndeep house lounge\ndeep house lounge bossa nova\ndeep house lounge jazz\ndeep house lounge-pop\ndeep house mandopop\ndeep house melancholic pop\ndeep house neo-soul\ndeep house nu-disco\ndeep house nu-disco chiptune\ndeep house nu-disco funk\ndeep house nu-jazz\ndeep house oriental\ndeep house oriental house\ndeep house oud\ndeep house pop\ndeep house pop R&B\ndeep house pop-rap\ndeep house progressive house\ndeep house progressive rock\ndeep house r&b\ndeep house reggae\ndeep house reggae dancehall\ndeep house reggae fusion\ndeep house reggaeton\ndeep house soul\ndeep house soulful R&B\ndeep house soulful house\ndeep house soulful house chillwave\ndeep house synth-pop\ndeep house synthwave\ndeep house tech house\ndeep house techno\ndeep house trap\ndeep house tribal\ndeep house tribal house\ndeep house trip-hop\ndeep house tropical\ndeep house tropical house\ndeep house tropical pop\ndeep house uk garage\ndeep house vaporwave\ndeep house world music\ndeep house worldbeat\ndeep house, Afro-house\ndeep house, Arabic pop\ndeep house, Balkan pop\ndeep house, Brazilian\ndeep house, Brazilian pop\ndeep house, Dutch hip-hop\ndeep house, French house, nu-disco\ndeep house, French rap\ndeep house, German cloud rap\ndeep house, Italian pop\ndeep house, Latin R&B\ndeep house, Latin house\ndeep house, Latin house, R&B\ndeep house, Latin house, flamenco\ndeep house, Latin house, worldbeat\ndeep house, Latin pop\ndeep house, Latin pop, Romanian pop\ndeep house, Middle Eastern\ndeep house, Middle Eastern, ambient\ndeep house, North African hip-hop\ndeep house, Persian fusion\ndeep house, Persian, ethnic\ndeep house, Punjabi pop\ndeep house, R&B\ndeep house, Russian hip-hop\ndeep house, Russian pop\ndeep house, Russian pop, cinematic\ndeep house, Russian pop-rap\ndeep house, Turkish pop\ndeep house, UK garage\ndeep house, UK garage, K-pop\ndeep house, UK garage, R&B\ndeep house, UK garage, Russian pop\ndeep house, UK garage, ambient\ndeep house, UK garage, lo-fi\ndeep house, UK garage, pop\ndeep house, UK garage, soul\ndeep house, UK garage, spoken word\ndeep house, afro house, ambient\ndeep house, afro-house\ndeep house, afro-house, world music\ndeep house, afrobeat, R&B\ndeep house, alternative R&B\ndeep house, ambient, cinematic\ndeep house, ambient, traditional Central Asian\ndeep house, atmospheric techno\ndeep house, bass house\ndeep house, bass house, ambient\ndeep house, bass house, glitch\ndeep house, breakbeat, ambient\ndeep house, chillwave\ndeep house, chillwave, Brazilian bass\ndeep house, chillwave, German pop\ndeep house, chillwave, Russian pop\ndeep house, chillwave, future bass\ndeep house, chillwave, tech house\ndeep house, cinematic, Persian\ndeep house, cinematic, ambient\ndeep house, city pop\ndeep house, city pop, synth-pop\ndeep house, classic garage house\ndeep house, classical fusion, ambient\ndeep house, dark pop\ndeep house, darkwave\ndeep house, darkwave, EBM\ndeep house, diva house\ndeep house, electro house\ndeep house, electronic dance music, Russian pop\ndeep house, electronica, world music\ndeep house, emotional pop\ndeep house, ethnic electronica\ndeep house, ethnic electronica, melodic house\ndeep house, ethnic fusion\ndeep house, folk fusion\ndeep house, future bass\ndeep house, future bass, Russian pop\ndeep house, future bass, UK garage\ndeep house, future bass, cinematic\ndeep house, future bass, dance-pop\ndeep house, future bass, lo-fi\ndeep house, future bass, melodic house\ndeep house, future bass, pop\ndeep house, future bass, progressive house\ndeep house, future garage\ndeep house, future garage, R&B\ndeep house, future garage, ambient\ndeep house, future garage, lo-fi\ndeep house, future house\ndeep house, glitchy electronica\ndeep house, hard techno\ndeep house, hardstyle\ndeep house, hardstyle, ambient\ndeep house, hip-hop, Russian pop\ndeep house, industrial rock\ndeep house, latin house\ndeep house, latin pop\ndeep house, lo-fi hip-hop, German pop-rap\ndeep house, lo-fi hip-hop, Russian pop\ndeep house, melodic house, future garage\ndeep house, melodic techno\ndeep house, melodic techno, French vocal\ndeep house, melodic techno, ambient\ndeep house, melodic techno, nu-disco\ndeep house, melodic trap\ndeep house, minimal tech house\ndeep house, minimal techno\ndeep house, minimal techno, Latin electronic\ndeep house, minimal techno, nu-disco\ndeep house, noir-jazz, dream-pop\ndeep house, nu-disco, future funk\ndeep house, nu-disco, future funk, soul funk\ndeep house, nu-disco, synth-funk\ndeep house, nu-disco, tribal house\ndeep house, nu-jazz, vaporwave\ndeep house, oriental, cinematic\ndeep house, post-punk\ndeep house, progressive house\ndeep house, progressive house, Russian pop\ndeep house, progressive house, ambient\ndeep house, progressive house, lo-fi\ndeep house, progressive house, melodic techno\ndeep house, progressive house, trance\ndeep house, progressive house, world music\ndeep house, progressive tech house\ndeep house, progressive techno, ambient\ndeep house, progressive, melodic techno\ndeep house, reggaeton, atmospheric pop\ndeep house, slap house\ndeep house, slap house, Eastern European pop\ndeep house, slap house, Russian pop\ndeep house, slap house, cinematic\ndeep house, slap house, electronic\ndeep house, slap house, electronic pop\ndeep house, slap house, lo-fi\ndeep house, synth-pop\ndeep house, synth-pop, Turkish pop\ndeep house, tech house\ndeep house, tech house, Brazilian funk\ndeep house, tech house, Latin house\ndeep house, tech house, ambient\ndeep house, tech house, emotional\ndeep house, tech house, lo-fi\ndeep house, tech house, tribal house\ndeep house, tech-house\ndeep house, tech-house, Afro-Latin\ndeep house, tech-house, ambient\ndeep house, techno\ndeep house, techno, R&B\ndeep house, techno, ambient\ndeep house, techno, vaporwave\ndeep house, trance, bass house\ndeep house, trap\ndeep house, trap R&B\ndeep house, trap, Russian pop\ndeep house, trap, soulful vocals\ndeep house, tribal, ambient\ndeep house, trip-hop\ndeep house, uk garage\ndeep house, uk garage, hip-hop\ndeep house, vaporwave, lo-fi hip hop\ndeep house, vaporwave, pop-R&B\ndeep house, world music, progressive house\ndeep soul\ndeep tech house\ndeep tech-house\ndeep techno\ndeep trap\ndembo\ndembo reggaeton\ndembo reggaeton chiptune\ndembo swing\ndembo-trap\ndembo-trap, reggaeton, R&B\ndembow\ndembow R&B\ndembow chiptune\ndembow dancehall\ndembow hard techno\ndembow hardcore\ndembow hardstyle\ndembow hip-hop\ndembow house\ndembow hyperpop trap\ndembow mambo\ndembow moombahton\ndembow pop\ndembow punk\ndembow rap\ndembow reggaeton\ndembow trap\ndembow trapeton\ndembow, Latin pop\ndembow, Latin pop, cinematic\ndembow, Latin trap\ndembow, Latin trap, reggaeton\ndembow, Latin urban\ndembow, Middle Eastern fusion\ndembow, ambient, cinematic\ndembow, chiptune\ndembow, chiptune, breakcore\ndembow, chiptune, electronic\ndembow, chiptune, meme rap\ndembow, cinematic, ambient\ndembow, cinematic, orchestral\ndembow, cinematic, trap\ndembow, club, bilingual\ndembow, club, hip hop\ndembow, electronic, dark pop\ndembow, electronic, spoken word\ndembow, future bass\ndembow, hardstyle, moombahton\ndembow, hyperpop\ndembow, hyperpop, glitchcore\ndembow, latin pop\ndembow, lo-fi hip hop\ndembow, lo-fi hip hop, Latin trap\ndembow, moombahton, Latin club\ndembow, moombahton, Latin party\ndembow, moombahton, club\ndembow, moombahton, reggaeton\ndembow, neurofunk, dubstep\ndembow, orchestral, club\ndembow, oud, cinematic\ndembow, reggaeton\ndembow, reggaeton, house\ndembow, shehnai fusion\ndembow, trance, cinematic\ndembow, trap\ndembow, trap, Latin hip hop\ndembow, trap, chiptune\ndemon voice\ndemonic trap\ndemonic vocal\ndenpa\ndenpa J-pop\ndenpa chiptune\ndenpa music\ndenpa, J-core, chiptune\ndenpa, J-pop, chiptune\ndenpa, J-rock, speedcore\ndenpa, chiptune, hyperpop\ndenpa, electronic, ambient\ndenpa, happy hardcore, J-pop\ndenpa, happy hardcore, chiptune\ndenpa, hyperpop\ndenpa, hyperpop, J-pop\ndenpa, kawaii future bass\ndenpa, kawaii future bass, J-pop\ndenpa, speedcore, gabber\ndenpa-kei\ndenpa-kei J-core\ndenpa-kei anison\ndenpa-kei breakcore\ndenpa-kei chiptune\ndenpa-kei chiptune J-pop\ndenpa-kei happy hardcore\ndenpa-kei hyperpop\ndenpa-kei metalcore\ndenpa-kei speedcore\ndenpa-kei, J-core, gabber\ndenpa-kei, J-core, happy hardcore\ndenpa-kei, J-core, hyperpop\ndenpa-kei, J-core, speedcore\ndenpa-kei, J-rock\ndenpa-kei, J-rock, breakcore\ndenpa-kei, J-rock, chiptune\ndenpa-kei, J-rock, electronic\ndenpa-kei, J-rock, hyperpop\ndenpa-kei, J-rock, metal\ndenpa-kei, J-rock, metalcore\ndenpa-kei, J-rock, speedcore\ndenpa-kei, artcore, Vocaloid\ndenpa-kei, big band jazz, Vocaloid\ndenpa-kei, chiptune, J-pop\ndenpa-kei, happy hardcore, chiptune\ndenpa-kei, happy hardcore, gabber\ndenpa-kei, hardcore techno, gabber\ndenpa-kei, hyperpop\ndesert ambient\ndesert blues\ndesert blues funk rock\ndesert blues rawa\ndesert blues rock\ndesert blues soukous\ndesert blues-rock\ndesert dance\ndesert dance-pop\ndesert folk\ndesert folk-rock\ndesert funk\ndesert fusion\ndesert groove\ndesert hip-hop\ndesert house\ndesert jazz\ndesert pop\ndesert punk\ndesert punk rock\ndesert reggae\ndesert reggae funk\ndesert reggae world music\ndesert rock\ndesert rock Arabic folk\ndesert rock Arabic fusion\ndesert rock blues\ndesert rock blues rock\ndesert rock flamenco\ndesert rock funk\ndesert rock funk metal\ndesert rock funk psychedelic\ndesert rock funk rock\ndesert rock funk-rock\ndesert rock garage punk\ndesert rock hip-hop\ndesert rock lo-fi\ndesert rock outlaw country\ndesert rock psychedelic funk\ndesert rock punk\ndesert rock surf rock\ndesert rock, Arabic fusion\ndesert rock, Chinese folk\ndesert rock, Latin rhythm\ndesert rock, Middle Eastern folk\ndesert rock, Middle Eastern folk, rock\ndesert rock, North African folk\ndesert rock, North African, fusion\ndesert rock, electronic dance music\ndesert rock, electronic dance, fusion\ndesert rock, flamenco, rock\ndesert rock, folk metal\ndesert rock, heavy metal\ndesert rock, psychedelic funk\ndesert rock, stoner metal, post-hardcore\ndesert soul\ndesert soundtrack\ndesert techno\ndesert trance\ndesert trance oriental house\ndesert trap\ndesert-pop\ndesi hip-hop\ndesi hip-hop trap metal\ndesi trap\ndevotional\ndevotional Arabic\ndevotional C-pop\ndevotional EDM\ndevotional Indian\ndevotional Indian Christian\ndevotional Indian bhajan\ndevotional Indian chant\ndevotional Indian cinema\ndevotional Indian classical\ndevotional Indian film music\ndevotional Indian folk\ndevotional South Asian\ndevotional Tamil\ndevotional Telugu\ndevotional a cappella\ndevotional acoustic\ndevotional ambient\ndevotional anasheed\ndevotional anthem\ndevotional ballad\ndevotional bhajan\ndevotional bhajan chiptune\ndevotional bhajan funk\ndevotional bhajan pop-fusion\ndevotional bhajan pop-rock\ndevotional bhajan, kuthu, electronic\ndevotional bhajan, kuthu, electronic pop\ndevotional chant\ndevotional chanting\ndevotional chiptune\ndevotional choral\ndevotional classical\ndevotional cumbia\ndevotional dance\ndevotional dance, Indian electronic, chiptune\ndevotional dance-pop\ndevotional electronic\ndevotional electronica\ndevotional folk\ndevotional folk-pop\ndevotional folk-rock\ndevotional fusion\ndevotional hip-hop\ndevotional hymn\ndevotional jazz\ndevotional lullaby\ndevotional music\ndevotional piano\ndevotional pop\ndevotional pop bhangra\ndevotional pop, Indian fusion, ambient\ndevotional pop, South Indian pop\ndevotional pop-rock\ndevotional power ballad\ndevotional qawwali\ndevotional rap\ndevotional rock\ndevotional rock blues-rock\ndevotional rock nu-metal\ndevotional rock, Indian folk\ndevotional rock, electronic dance, fusion\ndevotional rock, heavy metal, hard rock\ndevotional soul\ndevotional synth\ndevotional trance\ndevotional trap\ndevotional world\ndevotional world fusion\ndevotional world music\ndevotional worldbeat\ndevotional, Indian classical, ambient\ndevotional, Indian classical, choral\ndevotional, Indian classical, cinematic\ndevotional, Indian classical, epic\ndevotional, Indian classical, gospel\ndevotional, Indian classical, orchestral\ndevotional, Indian fusion, cinematic\ndevotional, Indian fusion, electronic\ndevotional, Indian fusion, festive\ndevotional, Indian fusion, high-energy\ndevotional, Indian fusion, martial\ndevotional, Indian fusion, qawwali\ndevotional, Indian percussion, brass\ndevotional, Middle Eastern, choral\ndevotional, South Asian, Middle Eastern\ndevotional, South Asian, ambient\ndevotional, South Asian, classical\ndevotional, South Asian, contemporary\ndevotional, South Asian, modern\ndevotional, South Asian, spiritual\ndevotional, a cappella, world music\ndevotional, brass, Indian film music\ndevotional, brass, dholak\ndevotional, celebratory, dholak\ndevotional, choral, flamenco\ndevotional, cinematic, Indian film score\ndevotional, cinematic, South Asian\ndevotional, cinematic, ambient\ndevotional, cinematic, world fusion\ndevotional, classical, South Asian\ndevotional, dhol, oud\ndevotional, dholak, South Asian\ndevotional, dholak, shehnai\ndevotional, electronic, South Asian\ndevotional, electronic, dholak\ndevotional, melancholic, South Asian\ndevotional, orchestral, Indian classical\ndevotional, orchestral, Indian fusion\ndevotional, retro synth, Indian film music\ndevotional, retro, Indian film music\ndevotional, retro, synth\ndevotional, spiritual, Indian classical\ndevotional, synthwave, chiptune\ndevotional, traditional Southeast Asian, ambient\ndevotional, world fusion, electronic\ndevotional, world music, acoustic\ndhol beat\ndholak\ndholak dance\ndholak fusion\ndholak house\ndigital\ndigital Christmas\ndigital R&B\ndigital Raï\ndigital ambient\ndigital ballad\ndigital carol\ndigital chaabi\ndigital chiptune\ndigital cumbia\ndigital cumbia breakbeat\ndigital cumbia breakcore\ndigital cumbia chiptune\ndigital cumbia dancehall\ndigital cumbia hyperpop\ndigital cumbia punk\ndigital cumbia rap\ndigital cumbia reggaeton\ndigital cumbia rock\ndigital cumbia trap\ndigital cumbia, chiptune, Latin rock\ndigital cumbia, electronic hip-hop\ndigital cumbia, hyperpop\ndigital cumbia, rap-rock\ndigital cumbia, reggaeton, chiptune\ndigital cumbia, reggaeton, electronic rock\ndigital dancehall\ndigital dancehall breakbeat\ndigital dancehall soca\ndigital devotional\ndigital dub\ndigital folk\ndigital fusion\ndigital glitch\ndigital gospel\ndigital hardcore\ndigital hardcore breakbeat\ndigital hardcore breakcore\ndigital hardcore chiptune\ndigital hardcore chiptune metal\ndigital hardcore chiptune metalcore\ndigital hardcore chiptune punk\ndigital hardcore chiptune rock\ndigital hardcore chiptune-punk\ndigital hardcore cybergrind\ndigital hardcore dancehall\ndigital hardcore electronic rock\ndigital hardcore gabber\ndigital hardcore glitchcore\ndigital hardcore happy hardcore\ndigital hardcore hyperpop\ndigital hardcore hyperpop-punk\ndigital hardcore industrial rock\ndigital hardcore j-rock\ndigital hardcore metalcore\ndigital hardcore metalcore hyperpop\ndigital hardcore nintendocore\ndigital hardcore noise rock\ndigital hardcore pop-punk\ndigital hardcore punk\ndigital hardcore punk rock\ndigital hardcore rap metal\ndigital hardcore rap-rock\ndigital hardcore rapcore\ndigital hardcore reggae metal\ndigital hardcore synth-punk\ndigital hardcore trap metal\ndigital hardcore, J-rock\ndigital hardcore, J-rock, metalcore\ndigital hardcore, Latin rap\ndigital hardcore, Latin rap-rock\ndigital hardcore, Nintendocore\ndigital hardcore, Nintendocore, punk\ndigital hardcore, bachata, punk\ndigital hardcore, breakcore\ndigital hardcore, comedy metal\ndigital hardcore, hyperpop\ndigital hardcore, hyperpop, chiptune\ndigital hardcore, hyperpop-punk\ndigital hardcore, industrial rock\ndigital hardcore, metalcore\ndigital hardcore, metalcore, J-rock\ndigital hardcore, metalcore, ambient\ndigital hip-hop\ndigital metal\ndigital metalcore\ndigital piano\ndigital piano, boogie-woogie, ragtime\ndigital pop\ndigital punk\ndigital punk rock\ndigital qawwali\ndigital raï\ndigital reggae\ndigital reggae chiptune\ndigital reggae cyberpunk\ndigital reggae dancehall\ndigital reggae gospel\ndigital reggae lovers rock\ndigital reggaeton\ndigital rock\ndigital tango\ndigital worship\ndigital-punk\ndigital-punk pop-punk\ndigitalgrime\ndirty south\ndirty south hip-hop\ndirty south rap\ndirty south, crunk, hip-hop\ndisco\ndisco C-pop\ndisco Mandopop\ndisco a cappella\ndisco folk\ndisco funk\ndisco funk gospel\ndisco funk novelty\ndisco funk rock\ndisco funk show tune\ndisco funk, spiritual, gospel\ndisco house\ndisco polka\ndisco polo\ndisco polo chiptune\ndisco polo happy hardcore\ndisco polo, Balkan brass\ndisco polo, Eurodance, novelty\ndisco polo, cabaret, Polish pop\ndisco polo, children's music, eurodance\ndisco polo, chiptune\ndisco polo, chiptune, Eurodance\ndisco polo, chiptune, happy hardcore\ndisco polo, folk-pop\ndisco polo, hard dance, hardstyle\ndisco polo, hardstyle, chiptune\ndisco polo, polka, Polish pop\ndisco polo, ska, Polish pop\ndisco polo, turbo-folk\ndisco pop\ndisco pop-rock new wave\ndisco rock\ndisco soul\ndisco soul future bass\ndisco tango\ndisco trot\ndisco, Arabic fusion, funk\ndisco, Chinese New Year, retro\ndisco, Italo-disco, dance-pop\ndisco, ballad, cinematic\ndisco, big band, theatrical\ndisco, children's music, Eurodance\ndisco, children's music, eurodance\ndisco, cinematic, J-pop\ndisco, electronic, funk\ndisco, electronic, modern\ndisco, electronic, trip-hop\ndisco, new wave, pop-rock\ndisco, novelty, German\ndisco, pop, dance\ndisco, pop, synth-pop\ndisco, pop-rock, funk\ndisco, pop-rock, new wave\ndisco, schlager, retro-pop\ndisco, synth-pop, C-pop\ndisco, synth-pop, Mandopop\ndisco, synth-pop, Vietnamese pop\ndisco, synth-pop, polka\ndisco-folk\ndisco-funk\ndisco-funk Balkan pop\ndisco-funk J-pop\ndisco-funk Mandopop\ndisco-funk cabaret\ndisco-funk city pop\ndisco-funk gothic horror\ndisco-funk jazz-funk\ndisco-funk lounge\ndisco-funk orchestral\ndisco-funk show tune\ndisco-funk soul\ndisco-funk, Balkan new wave\ndisco-funk, Balkan pop\ndisco-funk, C-pop, synth-pop\ndisco-funk, J-pop\ndisco-funk, J-pop, anime theme\ndisco-funk, Latin, children's music\ndisco-funk, Latin, upbeat\ndisco-funk, Polish rock\ndisco-funk, Schlager, novelty\ndisco-funk, South Asian pop, filmi-pop\ndisco-funk, big band jazz\ndisco-funk, cha-cha-chá, hip-hop\ndisco-funk, city pop\ndisco-funk, classic rock, Latin pop\ndisco-funk, hardstyle\ndisco-funk, jazz, soul\ndisco-funk, new wave, rock\ndisco-funk, retro pop, Vietnamese pop\ndisco-funk, soft rock, soul\ndisco-funk, synth-pop, C-pop\ndisco-funk, theatrical, show tune\ndisco-gospel\ndisco-house\ndisco-polka\ndisco-polka eurodance\ndisco-polo\ndisco-pop\ndisco-pop Latin\ndisco-pop classical fusion\ndisco-pop funk\ndisco-pop lo-fi\ndisco-pop rock\ndisco-pop, Russian chanson\ndisco-pop, ballad\ndisco-pop, hard rock, synth-pop\ndisco-pop, theatrical, Christmas\ndisco-pop, theatrical, musical theater\ndisco-reggae\ndisco-rock\ndisco-rock Mandopop\ndisco-soul\ndisco-tango\ndisco-trot\ndiss track\ndiss track hip-hop\ndiva house\ndiva house, Italo house\ndiva house, Italo house, 90s house\ndiva house, Italo house, deep house\ndiva house, Italo house, electronic\ndiva house, Italo house, energetic house\ndixieland jazz\ndjembe\ndjent\ndjent chiptune\ndjent funk-metal\ndjent groove metal\ndjent groove metalcore\ndjent mathcore\ndjent mathcore chiptune\ndjent metal\ndjent metalcore\ndjent metalcore chiptune\ndjent progressive metal\ndjent progressive metalcore\ndjent, J-rock, rap-rock\ndjent, chiptune, Nintendocore\ndjent, chiptune, electronic\ndjent, chiptune, electronic metal\ndjent, chiptune, industrial metal\ndjent, chiptune, video game music\ndjent, cinematic metal\ndjent, cinematic metal, ambient\ndjent, cinematic metal, modern metalcore\ndjent, cinematic rock, metal\ndjent, cybergrind\ndjent, electronic, extreme metal\ndjent, electronic, metal\ndjent, extreme metal\ndjent, flamenco, ambient\ndjent, groove metal, ambient\ndjent, groove metal, instrumental metal\ndjent, industrial metal\ndjent, instrumental metal, technical metal\ndjent, math metal, electronic metal\ndjent, metal, cinematic\ndjent, metal, electronic\ndjent, metalcore, cinematic\ndjent, metalcore, industrial metal\ndjent, modern metal, instrumental\ndjent, modern metalcore\ndjent, modern metalcore, C-pop metal\ndjent, modern metalcore, cinematic metal\ndjent, modern metalcore, instrumental metal\ndjent, nu-metalcore, deathcore\ndjent, post-hardcore, atmospheric metal\ndjent, progressive metal\ndjent, progressive metal, J-rock\ndjent, progressive metal, atmospheric rock\ndjent, progressive metal, industrial\ndjent, progressive metal, instrumental\ndjent, progressive metal, video game boss music\ndjent, progressive metalcore\ndjent, progressive metalcore, aggressive metal\ndjent, progressive metalcore, instrumental metal\ndjent, progressive metalcore, trip-hop\ndjent, vaporwave, ambient metal\ndjent, video game music, electronic\ndocumentary\ndoo-wop\ndoo-wop Latin ballad\ndoo-wop R&B\ndoo-wop a cappella\ndoo-wop ballad\ndoo-wop barbershop\ndoo-wop early R&B\ndoo-wop early rock and roll\ndoo-wop early soul\ndoo-wop gospel\ndoo-wop lounge\ndoo-wop pop\ndoo-wop pop-rock\ndoo-wop revival\ndoo-wop rock\ndoo-wop rock and roll\ndoo-wop soul\ndoo-wop sunshine pop\ndoo-wop swing-pop\ndoo-wop vocal jazz\ndoo-wop, Christmas ballad\ndoo-wop, barbershop, a cappella\ndoo-wop, barbershop, bebop\ndoo-wop, barbershop, soul\ndoo-wop, barbershop, swing\ndoo-wop, barbershop, vintage vocal\ndoo-wop, big band, swing\ndoo-wop, early R&B\ndoo-wop, early rock 'n' roll\ndoo-wop, early rock and roll\ndoo-wop, early rock and roll, Christmas\ndoo-wop, early rock and roll, Italian-American\ndoo-wop, early rock and roll, Latin\ndoo-wop, early rock and roll, R&B\ndoo-wop, early rock and roll, big band\ndoo-wop, early rock and roll, dream pop\ndoo-wop, early rock and roll, easy listening\ndoo-wop, early rock and roll, pop ballad\ndoo-wop, early rock and roll, rockabilly\ndoo-wop, early rock and roll, vintage Christmas\ndoo-wop, early rock and roll, vintage ballad\ndoo-wop, early rock and roll, vintage pop\ndoo-wop, early rock and roll, vintage vocal group\ndoo-wop, early rock and roll, vocal group\ndoo-wop, early rock and roll, vocal harmony\ndoo-wop, early rock and roll, whimsical\ndoo-wop, early soul\ndoo-wop, novelty, Christmas\ndoo-wop, orchestral, vintage pop\ndoo-wop, pop rock\ndoo-wop, retro rock and roll\ndoo-wop, rock and roll\ndoo-wop, rock and roll, a cappella\ndoo-wop, rock and roll, holiday\ndoo-wop, rock and roll, pop\ndoo-wop, rock and roll, rockabilly\ndoo-wop, rock and roll, soul\ndoo-wop, rock and roll, vintage ballad\ndoo-wop, rock and roll, vintage pop\ndoo-wop, sentimental ballad, Christmas\ndoo-wop, swing, novelty\ndoo-wop, vintage ballad, early rock and roll\ndoo-wop, vocal jazz, big band\ndoom metal\ndoom metal stoner metal\ndoom metal thrash metal\ndoom metal, post-rock, operatic\ndoom metal, psychedelic rock\ndoom metal, psychedelic rock, thrash metal\ndoom metal, stoner rock, acoustic blues\ndoom metal, symphonic metal, cinematic\ndoom post-rock\ndoom rock\ndoom-gaze\ndoomgaze\ndowntempo\ndowntempo Afro-Latin\ndowntempo C-pop\ndowntempo C-pop R&B\ndowntempo C-pop lo-fi hip-hop\ndowntempo Latin\ndowntempo Latin folk\ndowntempo Latin lounge\ndowntempo Latin pop\ndowntempo R&B\ndowntempo R&B ambient\ndowntempo R&B, lo-fi hip hop\ndowntempo R&B, trap soul, ambient pop\ndowntempo UK garage\ndowntempo acid jazz trip-hop\ndowntempo afro-fusion\ndowntempo afrobeat\ndowntempo alternative\ndowntempo ambient\ndowntempo ambient chillwave\ndowntempo ambient jazz\ndowntempo ambient pop\ndowntempo ambient rock\ndowntempo ambient world fusion\ndowntempo bossa nova\ndowntempo chill R&B\ndowntempo chill house\ndowntempo chillhop\ndowntempo chillout\ndowntempo chillwave\ndowntempo chillwave C-pop\ndowntempo chillwave trip-hop\ndowntempo chiptune\ndowntempo cinematic\ndowntempo cumbia\ndowntempo deep house\ndowntempo deep house lounge\ndowntempo dream pop\ndowntempo dream-pop\ndowntempo drum and bass\ndowntempo electronic\ndowntempo electronic funk\ndowntempo electronic pop\ndowntempo electronic, worldbeat, soulful house\ndowntempo electronica\ndowntempo electropop\ndowntempo experimental\ndowntempo fado\ndowntempo flamenco\ndowntempo folk\ndowntempo funk\ndowntempo fusion\ndowntempo future bass\ndowntempo future garage\ndowntempo glitch\ndowntempo guzheng\ndowntempo hip hop\ndowntempo hip-hop\ndowntempo hip-hop, funky house\ndowntempo house\ndowntempo indie electronic\ndowntempo indie pop\ndowntempo indie rock\ndowntempo indie-pop\ndowntempo instrumental\ndowntempo jazz\ndowntempo lo-fi\ndowntempo lo-fi hip hop\ndowntempo lo-fi hip-hop\ndowntempo lo-fi hip-hop neo-soul\ndowntempo lo-fi house\ndowntempo lounge\ndowntempo lounge worldbeat\ndowntempo moombahton\ndowntempo neo-soul\ndowntempo neo-soul lounge\ndowntempo nu-disco\ndowntempo nu-jazz\ndowntempo nu-jazz trip-hop\ndowntempo oud\ndowntempo pop\ndowntempo pop, dance-pop, electronic\ndowntempo pop, future bass, cinematic\ndowntempo pop-R&B\ndowntempo pop-rock\ndowntempo reggae\ndowntempo reggaeton\ndowntempo ritual\ndowntempo soul\ndowntempo spiritual\ndowntempo synth-pop\ndowntempo trap\ndowntempo trap R&B\ndowntempo trap soul\ndowntempo trap-R&B\ndowntempo trip-hop\ndowntempo trip-hop ambient\ndowntempo trip-hop ambient pop\ndowntempo trip-hop ambient rock\ndowntempo trip-hop art pop\ndowntempo trip-hop chillwave\ndowntempo trip-hop cinematic\ndowntempo trip-hop dream pop\ndowntempo trip-hop electronic soul\ndowntempo trip-hop experimental\ndowntempo trip-hop lounge\ndowntempo trip-hop neo-soul\ndowntempo trip-hop world electronica\ndowntempo trip-hop world fusion\ndowntempo trip-hop world music\ndowntempo world\ndowntempo world beat\ndowntempo world electronic\ndowntempo world electronica\ndowntempo world fusion\ndowntempo world fusion trip-hop\ndowntempo world music\ndowntempo worldbeat\ndowntempo, Afro-Latin, electronic\ndowntempo, Azerbaijani folk, electronic\ndowntempo, Azerbaijani folk, melancholic\ndowntempo, Azerbaijani fusion, ambient\ndowntempo, C-pop, ambient\ndowntempo, Caribbean lounge, electronic\ndowntempo, Carnatic, R&B\ndowntempo, Central Asian, melancholic\ndowntempo, Chinese ambient\ndowntempo, Chinese ambient, electronic\ndowntempo, Chinese ambient, lo-fi\ndowntempo, Chinese classical, ambient\ndowntempo, Chinese folk, ambient\ndowntempo, Chinese instrumental, cinematic\ndowntempo, Chinese traditional, ambient\ndowntempo, Chinese traditional, chill-out\ndowntempo, Chinese traditional, cinematic\ndowntempo, East Asian, ambient\ndowntempo, East Asian, cinematic\ndowntempo, Indian ambient, cinematic\ndowntempo, Indian ambient, cinematic pop\ndowntempo, Indian classical, ambient\ndowntempo, Indian classical, ambient fusion\ndowntempo, Indian classical, cinematic\ndowntempo, Indian classical, electronic\ndowntempo, Indian classical, trip-hop\ndowntempo, Indian folk, trip-hop\ndowntempo, Indian fusion, ambient\ndowntempo, Indian pop, electronic\ndowntempo, Indian vocal, trip-hop\ndowntempo, Italian folk, lo-fi\ndowntempo, Latin R&B, deep house\ndowntempo, Latin electronic, dream pop\ndowntempo, Latin electronica\ndowntempo, Latin electronica, ambient\ndowntempo, Latin electronica, chillout\ndowntempo, Latin electronica, trip-hop\ndowntempo, Latin house, ambient\ndowntempo, Latin lounge, smooth jazz\ndowntempo, Latin, ambient\ndowntempo, Latin, world music\ndowntempo, Latin-infused, atmospheric\ndowntempo, Middle Eastern, ambient\ndowntempo, Middle Eastern, cinematic\ndowntempo, Middle Eastern, electronic\ndowntempo, Middle Eastern, instrumental\ndowntempo, Middle Eastern, lo-fi hip hop\ndowntempo, Middle Eastern, melancholic\ndowntempo, Middle Eastern, soulful\ndowntempo, Middle Eastern, trip-hop\ndowntempo, Persian electronic, ambient\ndowntempo, Persian pop, ambient\ndowntempo, Persian, cinematic\ndowntempo, Punjabi, ambient\ndowntempo, Turkish arabesque, cinematic\ndowntempo, Turkish folk, ambient\ndowntempo, Turkish folk, cinematic\ndowntempo, Turkish folk, melancholic\ndowntempo, Turkish folk, trip-hop\ndowntempo, Turkish fusion, electronic\ndowntempo, Turkish pop, trip-hop\ndowntempo, Turkish, ambient\ndowntempo, Turkish, cinematic\ndowntempo, Turkish, flamenco\ndowntempo, UK garage, ambient soul\ndowntempo, afro-house, ambient\ndowntempo, alternative rock, ambient\ndowntempo, ambient electronica, chillwave\ndowntempo, ambient pop, trip-hop\ndowntempo, ambient, Arabic electronica\ndowntempo, ambient, Arabic ethereal\ndowntempo, ambient, C-pop\ndowntempo, ambient, Chinese dream pop\ndowntempo, ambient, Chinese electronic\ndowntempo, ambient, Chinese ethereal\ndowntempo, ambient, Chinese lo-fi\ndowntempo, ambient, Chinese minimalist\ndowntempo, ambient, Chinese traditional\ndowntempo, ambient, East Asian fusion\ndowntempo, ambient, French electronic\ndowntempo, ambient, French ethereal\ndowntempo, ambient, Indian electronica\ndowntempo, ambient, Indian pop\ndowntempo, ambient, Japanese vocal\ndowntempo, ambient, Latin\ndowntempo, ambient, Middle Eastern\ndowntempo, ambient, Sinhala\ndowntempo, ambient, South Asian\ndowntempo, ambient, South Asian fusion\ndowntempo, ambient, chillwave\ndowntempo, ambient, cinematic\ndowntempo, ambient, deep house\ndowntempo, ambient, dream pop\ndowntempo, ambient, electronic\ndowntempo, ambient, emotional\ndowntempo, ambient, ethereal\ndowntempo, ambient, ethnic\ndowntempo, ambient, experimental\ndowntempo, ambient, glitch\ndowntempo, ambient, jazz fusion\ndowntempo, ambient, jazz lounge\ndowntempo, ambient, lo-fi\ndowntempo, ambient, lo-fi hip hop\ndowntempo, ambient, lounge\ndowntempo, ambient, minimalist\ndowntempo, ambient, mystical\ndowntempo, ambient, oud\ndowntempo, ambient, soul\ndowntempo, ambient, spiritual\ndowntempo, ambient, spiritual electronic\ndowntempo, ambient, traditional East Asian\ndowntempo, ambient, trap\ndowntempo, ambient, tribal\ndowntempo, ambient, tribal house\ndowntempo, ambient, trip-hop\ndowntempo, ambient, world electronic\ndowntempo, ambient, world fusion\ndowntempo, ambient, world music\ndowntempo, breakcore, ambient\ndowntempo, chillhop, Korean folk\ndowntempo, chillout, Chinese traditional\ndowntempo, chillout, ambient\ndowntempo, chillwave\ndowntempo, chillwave, Latin electronic\ndowntempo, chillwave, Latin electronica\ndowntempo, chillwave, acid house\ndowntempo, chillwave, ambient\ndowntempo, chillwave, cinematic\ndowntempo, chillwave, deep house\ndowntempo, chillwave, dream pop\ndowntempo, chillwave, future garage\ndowntempo, chillwave, lo-fi electronic\ndowntempo, chillwave, lo-fi hip-hop\ndowntempo, chillwave, lo-fi house\ndowntempo, chillwave, lounge\ndowntempo, chillwave, neo-soul\ndowntempo, chillwave, smooth jazz\ndowntempo, chillwave, spiritual electronic\ndowntempo, chillwave, synth-pop\ndowntempo, chillwave, trip-hop\ndowntempo, chillwave, vaporwave\ndowntempo, chillwave, world electronica\ndowntempo, chillwave, world fusion\ndowntempo, chillwave, world music\ndowntempo, chillwave, world music electronica\ndowntempo, cinematic, Chinese ambient\ndowntempo, cinematic, Chinese electronic\ndowntempo, cinematic, Chinese traditional\ndowntempo, cinematic, East Asian\ndowntempo, cinematic, Italian\ndowntempo, cinematic, Middle Eastern\ndowntempo, cinematic, Middle Eastern fusion\ndowntempo, cinematic, ambient\ndowntempo, cinematic, glitch\ndowntempo, cinematic, jazz noir\ndowntempo, cinematic, lo-fi\ndowntempo, cinematic, lo-fi hip-hop\ndowntempo, cinematic, trap\ndowntempo, cinematic, trip-hop\ndowntempo, deep house, ambient\ndowntempo, deep house, lo-fi\ndowntempo, deep house, lounge\ndowntempo, deep house, minimal techno\ndowntempo, dream pop, French chanson\ndowntempo, dream pop, French electronic\ndowntempo, dream pop, Latin electronica\ndowntempo, dream pop, ambient\ndowntempo, dream pop, chillwave\ndowntempo, dream pop, deep house\ndowntempo, dream pop, electronic\ndowntempo, dream pop, lo-fi\ndowntempo, dream pop, trip-hop\ndowntempo, dreamy, cinematic\ndowntempo, dreamy, lo-fi\ndowntempo, electronic, C-pop\ndowntempo, electronic, Latin hip hop\ndowntempo, electronic, Middle Eastern\ndowntempo, electronic, South Asian fusion\ndowntempo, electronic, world fusion\ndowntempo, ethereal, Middle Eastern\ndowntempo, ethereal, ambient\ndowntempo, ethereal, psychedelic\ndowntempo, ethnic electronica, oud\ndowntempo, ethnic electronica, worldbeat\ndowntempo, experimental electronic\ndowntempo, experimental, ambient\ndowntempo, experimental, glitch\ndowntempo, experimental, lo-fi\ndowntempo, folk, ambient\ndowntempo, glitch, ambient\ndowntempo, guzheng, ambient\ndowntempo, guzheng, ambient electronic\ndowntempo, guzheng, cinematic\ndowntempo, hardstyle, ambient\ndowntempo, hyperpop, ambient\ndowntempo, jazz, French pop\ndowntempo, jazz, sensual\ndowntempo, liquid drum and bass, ambient\ndowntempo, lo-fi electronic, Indian ambient\ndowntempo, lo-fi hip hop\ndowntempo, lo-fi hip hop, Central Asian\ndowntempo, lo-fi hip hop, Chinese traditional\ndowntempo, lo-fi hip hop, Indian classical\ndowntempo, lo-fi hip hop, Indian devotional\ndowntempo, lo-fi hip hop, South Asian fusion\ndowntempo, lo-fi hip hop, Turkish folk\ndowntempo, lo-fi hip hop, ambient\ndowntempo, lo-fi hip hop, atmospheric\ndowntempo, lo-fi hip hop, chillwave\ndowntempo, lo-fi hip hop, cinematic\ndowntempo, lo-fi hip hop, dream pop\ndowntempo, lo-fi hip hop, ethereal\ndowntempo, lo-fi hip hop, oud\ndowntempo, lo-fi hip hop, spiritual\ndowntempo, lo-fi trip-hop, ambient\ndowntempo, lo-fi, ambient\ndowntempo, lo-fi, cinematic\ndowntempo, lo-fi, dream pop\ndowntempo, lo-fi, trip-hop\ndowntempo, lo-fi, vaporwave\ndowntempo, lounge, ambient\ndowntempo, lounge, chillout\ndowntempo, neo-oriental, ambient\ndowntempo, neo-soul, ambient\ndowntempo, neo-soul, trip-hop\ndowntempo, new age, smooth jazz\ndowntempo, new age, world music\ndowntempo, oud, ambient\ndowntempo, post-rock, cinematic\ndowntempo, progressive house, ambient\ndowntempo, psychedelic rock, world music\ndowntempo, psychedelic, ambient\ndowntempo, psychedelic, trip-hop\ndowntempo, soul, ambient\ndowntempo, spiritual electronic, ambient\ndowntempo, spiritual, Indian devotional\ndowntempo, spiritual, ambient\ndowntempo, spiritual, tribal house\ndowntempo, spiritual, trip-hop\ndowntempo, tribal house, ambient\ndowntempo, trip-hop, Anatolian folk\ndowntempo, trip-hop, C-pop\ndowntempo, trip-hop, Chinese ambient\ndowntempo, trip-hop, Indian ambient\ndowntempo, trip-hop, Indian classical\ndowntempo, trip-hop, Indian classical fusion\ndowntempo, trip-hop, Indian pop\ndowntempo, trip-hop, Latin\ndowntempo, trip-hop, Latin house\ndowntempo, trip-hop, Latin indie pop\ndowntempo, trip-hop, Middle Eastern\ndowntempo, trip-hop, Middle Eastern fusion\ndowntempo, trip-hop, South Asian fusion\ndowntempo, trip-hop, Turkish art music\ndowntempo, trip-hop, Turkish folk\ndowntempo, trip-hop, Turkish fusion\ndowntempo, trip-hop, alternative R&B\ndowntempo, trip-hop, ambient\ndowntempo, trip-hop, cinematic\ndowntempo, trip-hop, deep house\ndowntempo, trip-hop, dream pop\ndowntempo, trip-hop, electronic\ndowntempo, trip-hop, electronica\ndowntempo, trip-hop, ethereal\ndowntempo, trip-hop, experimental\ndowntempo, trip-hop, folk fusion\ndowntempo, trip-hop, house\ndowntempo, trip-hop, lo-fi\ndowntempo, trip-hop, lounge\ndowntempo, trip-hop, new-age\ndowntempo, trip-hop, smooth jazz\ndowntempo, trip-hop, spiritual\ndowntempo, trip-hop, world fusion\ndowntempo, trip-hop, world music\ndowntempo, vaporwave, Italo-disco\ndowntempo, vaporwave, ambient\ndowntempo, world electronic, ambient\ndowntempo, world fusion, Chinese traditional\ndowntempo, world fusion, Indian classical\ndowntempo, world fusion, ambient\ndowntempo, world fusion, ambient electronic\ndowntempo, world fusion, electronic\ndowntempo, world fusion, flamenco\ndowntempo, world fusion, lo-fi hip hop\ndowntempo, world fusion, spiritual electronic\ndowntempo, world music, ambient\ndowntempo, world music, ambient pop\ndowntempo, world music, chillout\ndowntempo, world music, lounge\ndowntempo, world music, trip-hop\ndowntempo, worldbeat, ambient\ndramatic\ndramatic C-pop\ndramatic R&B\ndramatic a cappella\ndramatic acapella\ndramatic acoustic\ndramatic ambient\ndramatic art song\ndramatic ballad\ndramatic brass\ndramatic cello\ndramatic chamber pop\ndramatic chiptune\ndramatic cinematic\ndramatic classical\ndramatic cue\ndramatic drum and bass\ndramatic electronic pop\ndramatic fanfare\ndramatic folk\ndramatic house\ndramatic instrumental\ndramatic orchestral\ndramatic piano\ndramatic piano ballad\ndramatic piano ballad, Latin folk\ndramatic piano, Latin pop, theatrical ballad\ndramatic pop\ndramatic pop R&B\ndramatic pop ballad\ndramatic pop, Central Asian, Eastern European\ndramatic pop, Eastern European, Turkish\ndramatic pop-rock\ndramatic power ballad\ndramatic rap\ndramatic rock\ndramatic soul\ndramatic sting\ndramatic string\ndramatic synth\ndramatic tango\ndramatic violin\ndramatic vocal\ndramatic waltz\ndramatic world\ndream R&B\ndream folk\ndream funk\ndream hip hop\ndream hip-hop\ndream hop\ndream house\ndream metal\ndream pop\ndream pop Afrobeat\ndream pop C-pop\ndream pop R&B\ndream pop R&B Kizomba\ndream pop R&B lo-fi hip-hop\ndream pop R&B trap\ndream pop acoustic\ndream pop alternative R&B\ndream pop alternative dance\ndream pop alternative metal\ndream pop alternative rock\ndream pop alternative rock post-rock\ndream pop ambient\ndream pop ambient R&B\ndream pop ambient chillwave\ndream pop ambient electronic\ndream pop ambient electronica\ndream pop ambient folk\ndream pop ambient hip-hop\ndream pop ambient house\ndream pop ambient indie folk\ndream pop ambient indie rock\ndream pop ambient lo-fi hip-hop\ndream pop ambient pop\ndream pop ambient pop cinematic electronica\ndream pop ambient pop future bass\ndream pop ambient pop lo-fi electronic\ndream pop ambient pop neo-soul\ndream pop ambient pop soulful ballad\ndream pop ambient pop world music\ndream pop ambient rock\ndream pop ambient singer-songwriter\ndream pop ambient synth-pop\ndream pop art pop\ndream pop bedroom pop\ndream pop bossa nova\ndream pop bossa nova indie pop\ndream pop chanson\ndream pop chillwave\ndream pop chiptune\ndream pop chiptune breakcore\ndream pop cinematic ballad\ndream pop city pop\ndream pop cloud rap\ndream pop cloud rap ambient\ndream pop cloud rap atmospheric electronic\ndream pop cloud rap emo rap\ndream pop coldwave\ndream pop cumbia\ndream pop dark jazz ambient\ndream pop darkwave\ndream pop deep house\ndream pop downtempo\ndream pop drum and bass\ndream pop electronic\ndream pop electronic pop\ndream pop electronic rock\ndream pop electronica\ndream pop electropop\ndream pop emo\ndream pop emo pop\ndream pop emo rap\ndream pop emo rock\ndream pop emo trap\ndream pop emo-pop\ndream pop emo-rap\ndream pop emo-rock\ndream pop experimental pop\ndream pop folk\ndream pop funk\ndream pop funk rock\ndream pop funk soul\ndream pop funk-rock\ndream pop future bass\ndream pop future bass K-pop\ndream pop future bass electronic pop\ndream pop future garage\ndream pop future garage chillwave\ndream pop garage rock\ndream pop hip hop\ndream pop hip-hop\ndream pop hip-hop ambient rock\ndream pop hip-hop electronic\ndream pop indie\ndream pop indie R&B\ndream pop indie dance\ndream pop indie dance synth-pop\ndream pop indie electronic\ndream pop indie folk\ndream pop indie funk\ndream pop indie pop\ndream pop indie pop K-pop\ndream pop indie pop R&B\ndream pop indie pop chillwave\ndream pop indie pop contemporary R&B\ndream pop indie pop downtempo\ndream pop indie pop emo rap\ndream pop indie pop lo-fi hip-hop\ndream pop indie pop-rock\ndream pop indie rock\ndream pop indie rock lo-fi hip-hop\ndream pop indie rock post-punk\ndream pop indie rock shoegaze\ndream pop indie soul\ndream pop industrial\ndream pop industrial rock\ndream pop industrial rock synthwave\ndream pop jangle pop indie pop\ndream pop jangle pop indie rock\ndream pop jazz\ndream pop jazz fusion experimental electronic\ndream pop lo-fi\ndream pop lo-fi R&B\ndream pop lo-fi ambient\ndream pop lo-fi chillwave\ndream pop lo-fi electronic\ndream pop lo-fi hip hop\ndream pop lo-fi hip hop ambient\ndream pop lo-fi hip-hop\ndream pop lo-fi hip-hop C-pop\ndream pop lo-fi hip-hop R&B\ndream pop lo-fi hip-hop ambient\ndream pop lo-fi hip-hop emo rap\ndream pop lo-fi hip-hop vaporwave\ndream pop lo-fi indie\ndream pop lo-fi indie rock\ndream pop lo-fi pop\ndream pop lo-fi r&b\ndream pop lo-fi rock\ndream pop lo-fi synth-pop\ndream pop lo-fi trap\ndream pop lofi electronic\ndream pop lofi hip-hop\ndream pop lofi indie\ndream pop lounge\ndream pop lounge doo-wop\ndream pop lounge jazz\ndream pop lounge pop\ndream pop lounge rock\ndream pop mandopop\ndream pop math rock\ndream pop metalcore\ndream pop neo-soul\ndream pop neo-soul downtempo\ndream pop noise rock\ndream pop nu-disco\ndream pop nu-disco vaporwave\ndream pop nu-metal\ndream pop post-hardcore\ndream pop post-punk\ndream pop post-rock\ndream pop post-rock shoegaze\ndream pop progressive house\ndream pop progressive rock\ndream pop psychedelic pop\ndream pop psychedelic soul\ndream pop rap\ndream pop reggaeton\ndream pop rock\ndream pop shoegaze\ndream pop shoegaze alternative rock\ndream pop shoegaze ambient\ndream pop shoegaze indie rock\ndream pop shoegaze post-rock\ndream pop smooth jazz\ndream pop soft rock\ndream pop soulful funk cinematic lounge\ndream pop surf rock\ndream pop synth-pop\ndream pop synth-pop chillwave\ndream pop synthwave\ndream pop trap\ndream pop trap C-pop\ndream pop trap R&B\ndream pop trap-pop\ndream pop trip-hop\ndream pop trip-hop smooth jazz\ndream pop vaporwave\ndream pop vaporwave ambient\ndream pop world fusion\ndream pop world music\ndream pop worldbeat\ndream pop worship\ndream pop, 80s new wave\ndream pop, 80s new wave, psychedelic pop\ndream pop, 80s new wave, rock\ndream pop, 80s new wave, synth pop\ndream pop, 80s pop, anime soundtrack\ndream pop, 80s synth-pop\ndream pop, 90s anime, ambient pop\ndream pop, Arabic fusion\ndream pop, Arabic pop\ndream pop, Arabic pop, contemporary R&B\ndream pop, Arabic rock\ndream pop, Bengali rap, cinematic\ndream pop, Bollywood\ndream pop, Bollywood fusion\ndream pop, Bollywood pop, ambient electronic\ndream pop, Brazilian funk, ambient\ndream pop, Brazilian funk, trap\ndream pop, Brazilian indie\ndream pop, Brazilian indie pop\ndream pop, C-pop\ndream pop, C-pop ballad\ndream pop, C-pop, ambient electronic\ndream pop, C-pop, electronic\ndream pop, C-pop, indie rock\ndream pop, C-pop, lo-fi\ndream pop, C-pop, lo-fi hip hop\ndream pop, C-rock\ndream pop, Chinese folk\ndream pop, Chinese folk, ambient rock\ndream pop, Chinese hip-hop\ndream pop, Chinese indie\ndream pop, Chinese pop\ndream pop, Chinese pop, ambient rock\ndream pop, EBM, ambient\ndream pop, EDM, Vietnamese pop\ndream pop, East Asian pop\ndream pop, Fado, 80s pop-rock\ndream pop, French pop, lo-fi hip hop\ndream pop, French pop-rock\ndream pop, French synth-pop\ndream pop, IDM, glitch pop\ndream pop, Indian classical fusion\ndream pop, Indian classical, ambient electronica\ndream pop, Indian classical, lo-fi hip hop\ndream pop, Indian filmi, ambient\ndream pop, Indian fusion\ndream pop, Indian indie pop\ndream pop, Indian pop\ndream pop, Indian pop, ambient trap\ndream pop, Indian pop, electronic\ndream pop, Indian pop, synth pop\ndream pop, Indian pop, world music\ndream pop, Italian indie rock\ndream pop, Italian pop, smooth jazz\ndream pop, J-pop\ndream pop, J-pop, C-pop\ndream pop, J-pop, R&B\ndream pop, J-pop, ambient\ndream pop, J-pop, chillwave\ndream pop, J-pop, electronic\ndream pop, J-pop, pop-rock\ndream pop, J-pop, video game music\ndream pop, J-rock\ndream pop, Javanese ambient\ndream pop, Javanese pop\ndream pop, K-indie\ndream pop, K-pop, ambient\ndream pop, Latin electronic\ndream pop, Latin fusion\ndream pop, Latin jazz\ndream pop, Latin pop, R&B\ndream pop, Latin pop, chillwave\ndream pop, Latin pop, indie pop\ndream pop, Latin rock\ndream pop, Latin trap\ndream pop, MPB\ndream pop, MPB, 80s new wave\ndream pop, Malay pop\ndream pop, Mandarin pop, atmospheric\ndream pop, Mandarin pop, atmospheric rock\ndream pop, Mandarin pop, cinematic\ndream pop, Mandarin pop, electronic rock\ndream pop, Mandopop\ndream pop, R&B\ndream pop, R&B, Arabic pop\ndream pop, R&B, C-pop\ndream pop, R&B, French pop\ndream pop, R&B, Latin pop\ndream pop, R&B, Mandarin pop\ndream pop, R&B, Vietnamese pop\ndream pop, R&B, ambient\ndream pop, R&B, ambient trap\ndream pop, R&B, electronic\ndream pop, R&B, folk fusion\ndream pop, R&B, hip-hop\ndream pop, R&B, lo-fi hip hop\ndream pop, R&B, synthwave\ndream pop, R&B, trap\ndream pop, Turkish alternative pop\ndream pop, Turkish alternative pop, lo-fi hip hop\ndream pop, Turkish alternative rock\ndream pop, Turkish folk\ndream pop, UK drill\ndream pop, UK garage\ndream pop, UK garage, future bass\ndream pop, Vietnamese hip-hop\ndream pop, Vietnamese pop-rock\ndream pop, alt-country, indie rock\ndream pop, alt-rock\ndream pop, alternative R&B, electronic\ndream pop, alternative R&B, lo-fi hip-hop\ndream pop, alternative R&B, trap\ndream pop, alternative hip-hop\ndream pop, alternative rock\ndream pop, alternative rock, 80s new wave\ndream pop, alternative rock, C-pop\ndream pop, alternative rock, Hungarian rock\ndream pop, alternative rock, Indian ambient\ndream pop, alternative rock, J-rock\ndream pop, alternative rock, K-pop\ndream pop, alternative rock, ambient\ndream pop, alternative rock, cinematic\ndream pop, alternative rock, emo\ndream pop, alternative rock, hard rock\ndream pop, alternative rock, indie rock\ndream pop, alternative rock, lo-fi\ndream pop, alternative rock, math rock\ndream pop, alternative rock, metalcore\ndream pop, alternative rock, post-hardcore\ndream pop, alternative rock, shoegaze\ndream pop, ambient\ndream pop, ambient C-pop\ndream pop, ambient R&B\ndream pop, ambient ballad\ndream pop, ambient electronic\ndream pop, ambient electronic, Indian pop\ndream pop, ambient electronic, Mongolian folk\ndream pop, ambient electronic, lo-fi hip hop\ndream pop, ambient electronic, world music\ndream pop, ambient electronica\ndream pop, ambient folk\ndream pop, ambient fusion\ndream pop, ambient hip hop\ndream pop, ambient hip-hop\ndream pop, ambient pop\ndream pop, ambient pop, C-pop\ndream pop, ambient pop, South Asian\ndream pop, ambient pop, South Asian pop\ndream pop, ambient pop, South Indian pop\ndream pop, ambient trap\ndream pop, ambient world\ndream pop, ambient, Arabic fusion\ndream pop, ambient, C-pop\ndream pop, ambient, Chinese folk\ndream pop, ambient, Chinese indie\ndream pop, ambient, Chinese traditional\ndream pop, ambient, Indian classical\ndream pop, ambient, Indian fusion\ndream pop, ambient, Indian indie\ndream pop, ambient, Malay traditional\ndream pop, ambient, South Asian fusion\ndream pop, ambient, Vietnamese folk\ndream pop, ambient, cinematic\ndream pop, ambient, electronic\ndream pop, ambient, electronica\ndream pop, ambient, industrial rock\ndream pop, ambient, lo-fi hip hop\ndream pop, ambient, spiritual\ndream pop, ambient, trance\ndream pop, ambient, world fusion\ndream pop, americana\ndream pop, arena rock\ndream pop, arena rock, 80s new wave\ndream pop, arena rock, chanson\ndream pop, arena rock, world music\ndream pop, art pop, Turkish folk\ndream pop, art rock\ndream pop, art rock, cinematic\ndream pop, art rock, psychedelic\ndream pop, art rock, shoegaze\ndream pop, art-pop, electronic\ndream pop, atmospheric drum and bass, electronica\ndream pop, ballad\ndream pop, bedroom pop\ndream pop, big band jazz, trip-hop\ndream pop, big beat\ndream pop, big room house\ndream pop, bilingual pop\ndream pop, breakbeat, art pop\ndream pop, breakcore\ndream pop, breakcore, ambient\ndream pop, breakcore, drum and bass\ndream pop, carnival music\ndream pop, children's music\ndream pop, chillwave\ndream pop, chillwave, French cloud rap\ndream pop, chillwave, Indian pop\ndream pop, chillwave, ambient\ndream pop, chillwave, electronic\ndream pop, chillwave, lo-fi\ndream pop, chillwave, lo-fi hip-hop\ndream pop, chillwave, minimal electronic\ndream pop, chillwave, pop-R&B\ndream pop, chillwave, post-rock\ndream pop, chillwave, rock\ndream pop, chillwave, shoegaze\ndream pop, chiptune, ambient\ndream pop, chiptune, electronic\ndream pop, chiptune, synthwave\ndream pop, cinematic dubstep\ndream pop, cinematic electronic, industrial rock\ndream pop, cinematic piano\ndream pop, cinematic pop, Vietnamese ballad\ndream pop, cinematic pop, world fusion\ndream pop, cinematic rock\ndream pop, cinematic rock, ambient\ndream pop, cinematic, Bollywood\ndream pop, cinematic, C-pop\ndream pop, cinematic, Chinese folk\ndream pop, cinematic, East Asian\ndream pop, cinematic, Javanese\ndream pop, cinematic, ambient\ndream pop, cinematic, electronic\ndream pop, cinematic, lo-fi\ndream pop, cinematic, new-age\ndream pop, cinematic, shoegaze\ndream pop, cinematic, world fusion\ndream pop, classic rock\ndream pop, cloud rap\ndream pop, cloud rap, ambient R&B\ndream pop, cloud rap, ambient pop\ndream pop, cloud rap, atmospheric electronic\ndream pop, cloud rap, indie pop\ndream pop, cloud rap, indie rock\ndream pop, cloud rap, vaporwave\ndream pop, conscious hip-hop\ndream pop, conscious hip-hop, lo-fi\ndream pop, contemporary R&B\ndream pop, contemporary R&B, trap\ndream pop, cyberpunk, electronic\ndream pop, dance-pop, ambient\ndream pop, dancehall R&B\ndream pop, dark ambient, K-pop\ndream pop, dark electronic, synth-pop\ndream pop, dark pop, cinematic trap\ndream pop, dark pop, electronic\ndream pop, dark synthpop\ndream pop, darkwave\ndream pop, deep house\ndream pop, downtempo electronic\ndream pop, downtempo electronic, ambient\ndream pop, downtempo electronic, cinematic\ndream pop, downtempo trap\ndream pop, downtempo, electronic\ndream pop, downtempo, trip-hop\ndream pop, downtempo, world music\ndream pop, drum and bass\ndream pop, drum and bass, electronica\ndream pop, dubstep\ndream pop, electronic\ndream pop, electronic R&B, synth rock\ndream pop, electronic fusion, Indian classical\ndream pop, electronic hip-hop\ndream pop, electronic pop\ndream pop, electronic pop, Russian vocal\ndream pop, electronic rock\ndream pop, electronic, Arabic fusion\ndream pop, electronic, Arabic pop\ndream pop, electronic, C-pop\ndream pop, electronic, Chinese fusion\ndream pop, electronic, French hip hop\ndream pop, electronic, French indie\ndream pop, electronic, Hindi pop\ndream pop, electronic, Indian classical\ndream pop, electronic, Indian fusion\ndream pop, electronic, K-pop\ndream pop, electronic, Latin\ndream pop, electronic, Malayalam\ndream pop, electronic, Mandarin hip hop\ndream pop, electronic, Mandopop\ndream pop, electronic, Middle Eastern\ndream pop, electronic, Persian pop\ndream pop, electronic, R&B\ndream pop, electronic, South Asian\ndream pop, electronic, South Asian fusion\ndream pop, electronic, Southeast Asian pop\ndream pop, electronic, Tamil\ndream pop, electronic, ambient\ndream pop, electronic, breakcore\ndream pop, electronic, chiptune\ndream pop, electronic, cinematic\ndream pop, electronic, glitch\ndream pop, electronic, hip-hop\ndream pop, electronic, hyperpop\ndream pop, electronic, indie\ndream pop, electronic, pop-rock\ndream pop, electronic, rock\ndream pop, electronic, trap\ndream pop, electronic, world fusion\ndream pop, electronica, chillwave\ndream pop, emo rap\ndream pop, emo rap, alternative rock\ndream pop, emo rap, atmospheric rock\ndream pop, emo rap, lo-fi hip hop\ndream pop, emo rap, trap\ndream pop, emo rock, indie rock\ndream pop, emo, alternative rock\ndream pop, emo, post-hardcore\ndream pop, emo-rap\ndream pop, emo-rap, synthwave\ndream pop, emotional hip-hop\ndream pop, emotional pop-rock, ambient hip-hop\ndream pop, emotional trap\ndream pop, ethereal rock\ndream pop, eurodance\ndream pop, eurodance, trance\ndream pop, experimental C-pop\ndream pop, experimental electronic\ndream pop, experimental electronic, art pop\ndream pop, experimental hip-hop\ndream pop, experimental rock\ndream pop, experimental trap, glitch-hop\ndream pop, flamenco, C-pop\ndream pop, folk rock\ndream pop, funk rock, post-rock\ndream pop, future bass\ndream pop, future bass, C-pop\ndream pop, future bass, R&B\ndream pop, future bass, UK garage\ndream pop, future bass, ambient\ndream pop, future bass, atmospheric electronic\ndream pop, future bass, cinematic\ndream pop, future bass, indie hip-hop\ndream pop, future bass, lo-fi\ndream pop, future bass, modern pop\ndream pop, future bass, progressive house\ndream pop, future bass, synth-pop\ndream pop, future bass, trap\ndream pop, future bass, trap pop\ndream pop, future bass, trip-hop\ndream pop, garage rock\ndream pop, glitch hop\ndream pop, glitch hop, ambient\ndream pop, glitch hop, electronic\ndream pop, glitch hop, trap\ndream pop, glitch-pop\ndream pop, glitchcore\ndream pop, hard rock\ndream pop, hard rock, ambient\ndream pop, hardstyle\ndream pop, heavy metal\ndream pop, hip hop\ndream pop, hip hop, indie rock\ndream pop, hip-hop\ndream pop, hip-hop, C-pop\ndream pop, hip-hop, Lithuanian\ndream pop, hip-hop, ambient\ndream pop, hip-hop, electronic\ndream pop, hybrid trap\ndream pop, hyperpop\ndream pop, hyperpop, C-pop\ndream pop, hyperpop, ambient\ndream pop, hyperpop, ambient electronic\ndream pop, hyperpop, chiptune\ndream pop, hyperpop, electronic\ndream pop, hyperpop, trap\ndream pop, hyperpop, trip-hop\ndream pop, indie dance\ndream pop, indie electronic\ndream pop, indie electronic, chiptune\ndream pop, indie electronic, downtempo\ndream pop, indie electronic, future bass\ndream pop, indie folk\ndream pop, indie folk, pop-rock\ndream pop, indie pop\ndream pop, indie pop, Arabic ballad\ndream pop, indie pop, Bollywood\ndream pop, indie pop, C-pop\ndream pop, indie pop, R&B\ndream pop, indie pop, South Asian\ndream pop, indie pop, Thai pop\ndream pop, indie pop, Turkish pop\ndream pop, indie pop, emo\ndream pop, indie pop, hip-hop\ndream pop, indie pop, lo-fi\ndream pop, indie pop, lo-fi hip hop\ndream pop, indie pop, lo-fi hip-hop\ndream pop, indie pop, world music\ndream pop, indie rock\ndream pop, indie rock, 80s new wave\ndream pop, indie rock, Americana\ndream pop, indie rock, Arabic ethereal\ndream pop, indie rock, C-pop\ndream pop, indie rock, Chinese hip hop\ndream pop, indie rock, Hindi pop\ndream pop, indie rock, Italian rock\ndream pop, indie rock, K-pop\ndream pop, indie rock, Latin rock\ndream pop, indie rock, R&B\ndream pop, indie rock, South Asian\ndream pop, indie rock, alternative hip-hop\ndream pop, indie rock, ambient\ndream pop, indie rock, chillwave\ndream pop, indie rock, electronic\ndream pop, indie rock, heartland rock\ndream pop, indie rock, hip hop\ndream pop, indie rock, jazz\ndream pop, indie rock, jazz fusion\ndream pop, indie rock, lo-fi\ndream pop, indie rock, lo-fi hip hop\ndream pop, indie rock, pop-rock\ndream pop, indie rock, post-punk\ndream pop, indie rock, post-rock\ndream pop, indie rock, shoegaze\ndream pop, indie rock, surf rock\ndream pop, indie rock, synth-pop\ndream pop, indie rock, synthwave\ndream pop, indie-pop, Indian indie\ndream pop, indie-pop, cinematic\ndream pop, indie-pop, synth pop\ndream pop, industrial electronica\ndream pop, industrial rock\ndream pop, industrial rock, ambient\ndream pop, industrial, ambient\ndream pop, industrial, electronic\ndream pop, industrial, post-punk\ndream pop, jangle pop, indie pop\ndream pop, jazz fusion\ndream pop, jazz fusion, modern pop\ndream pop, jazz fusion, post-rock\ndream pop, jazzy indie pop\ndream pop, latin pop\ndream pop, liquid drum and bass\ndream pop, lo-fi R&B\ndream pop, lo-fi bedroom pop\ndream pop, lo-fi electronic\ndream pop, lo-fi hip hop\ndream pop, lo-fi hip hop, C-pop\ndream pop, lo-fi hip hop, Mandarin trap\ndream pop, lo-fi hip hop, R&B\ndream pop, lo-fi hip hop, Thai indie\ndream pop, lo-fi hip hop, Turkish alternative pop\ndream pop, lo-fi hip hop, alternative rock\ndream pop, lo-fi hip hop, ambient\ndream pop, lo-fi hip hop, ambient R&B\ndream pop, lo-fi hip hop, chillwave\ndream pop, lo-fi hip hop, contemporary R&B\ndream pop, lo-fi hip hop, electronic\ndream pop, lo-fi hip hop, emo rap\ndream pop, lo-fi hip hop, indie\ndream pop, lo-fi hip hop, metalcore\ndream pop, lo-fi hip hop, neo-soul\ndream pop, lo-fi hip hop, trap\ndream pop, lo-fi hip-hop, C-pop\ndream pop, lo-fi hip-hop, K-pop\ndream pop, lo-fi hip-hop, indie pop\ndream pop, lo-fi indie\ndream pop, lo-fi indie pop\ndream pop, lo-fi indie rock\ndream pop, lo-fi pop\ndream pop, lo-fi trap\ndream pop, lo-fi, C-pop\ndream pop, lo-fi, Latin\ndream pop, lo-fi, Mandarin ballad\ndream pop, lo-fi, ambient\ndream pop, lo-fi, ambient pop\ndream pop, lo-fi, bedroom pop\ndream pop, lo-fi, hyperpop\ndream pop, lo-fi, indie rock\ndream pop, lo-fi, trip-hop\ndream pop, lo-fi, vaporwave\ndream pop, math rock\ndream pop, math rock, electronic\ndream pop, melancholic ballad\ndream pop, melancholic pop\ndream pop, metalcore\ndream pop, metalcore, dubstep\ndream pop, midwest emo\ndream pop, minimal synth-pop\ndream pop, modern R&B\ndream pop, neo-classical, C-pop\ndream pop, neo-soul\ndream pop, neo-soul, R&B\ndream pop, neo-soul, trap\ndream pop, new age, ambient\ndream pop, new age, cinematic\ndream pop, new age, orchestral pop\ndream pop, new age, world music\ndream pop, new wave, ambient\ndream pop, new wave, pop-rock\ndream pop, new-age\ndream pop, new-age, pop-rock\ndream pop, noise rock\ndream pop, noise rock, ambient\ndream pop, nu-disco\ndream pop, nu-disco, indie rock\ndream pop, pop rock, Southeast Asian pop\ndream pop, pop, reggaeton\ndream pop, pop-punk\ndream pop, pop-punk, hip-hop\ndream pop, pop-rap, C-pop\ndream pop, pop-rock\ndream pop, pop-rock, C-pop\ndream pop, pop-rock, K-pop\ndream pop, pop-rock, ambient\ndream pop, pop-rock, electronic\ndream pop, pop-rock, hip-hop\ndream pop, pop-rock, new-age\ndream pop, pop-rock, tropical house\ndream pop, post-hardcore\ndream pop, post-hardcore, alternative rock\ndream pop, post-punk\ndream pop, post-punk, 80s new wave\ndream pop, post-punk, chiptune\ndream pop, post-punk, goth rock\ndream pop, post-punk, new wave\ndream pop, post-punk, rock\ndream pop, post-rock\ndream pop, post-rock, C-pop\ndream pop, post-rock, Mandarin pop\ndream pop, post-rock, Thai ambient\ndream pop, post-rock, alternative rock\ndream pop, post-rock, ambient\ndream pop, post-rock, cinematic\ndream pop, post-rock, electronic\ndream pop, post-rock, emo\ndream pop, post-rock, indie\ndream pop, post-rock, indie rock\ndream pop, post-rock, instrumental rock\ndream pop, post-rock, lo-fi\ndream pop, post-rock, lo-fi ambient\ndream pop, post-rock, progressive metal\ndream pop, post-rock, progressive rock\ndream pop, post-rock, psychedelic\ndream pop, post-rock, rock\ndream pop, post-rock, shoegaze\ndream pop, power pop, synth rock\ndream pop, progressive house\ndream pop, progressive house, ambient\ndream pop, progressive house, trance\ndream pop, progressive metal\ndream pop, progressive metal, jazz\ndream pop, progressive rock\ndream pop, progressive trance\ndream pop, psychedelic electronic, Latin-influenced\ndream pop, psychedelic folk\ndream pop, psychedelic funk, vaporwave\ndream pop, psychedelic indie rock\ndream pop, psychedelic pop\ndream pop, psychedelic pop, lo-fi\ndream pop, psychedelic pop, neo-soul\ndream pop, psychedelic rock\ndream pop, psychedelic rock, 8-bit\ndream pop, psychedelic rock, ambient\ndream pop, psychedelic rock, funk\ndream pop, psychedelic rock, indie\ndream pop, psychedelic rock, industrial rock\ndream pop, psychedelic rock, synthwave\ndream pop, psychedelic rock, world music\ndream pop, psychedelic soft rock\ndream pop, psychedelic soul\ndream pop, psychedelic, Mongolian\ndream pop, punk rock\ndream pop, rap rock\ndream pop, reggaeton\ndream pop, reggaeton, R&B\ndream pop, reggaeton, ambient\ndream pop, reggaeton, chillwave\ndream pop, reggaeton, latin pop\ndream pop, reggaeton, vaporwave\ndream pop, rock, ambient\ndream pop, rock, electronic\ndream pop, rock, hip hop\ndream pop, romantic ballad, new-age\ndream pop, romantic pop-rock\ndream pop, shoegaze\ndream pop, shoegaze, C-pop\ndream pop, shoegaze, J-pop\ndream pop, shoegaze, K-pop\ndream pop, shoegaze, K-rock\ndream pop, shoegaze, Latin hip hop\ndream pop, shoegaze, Portuguese indie\ndream pop, shoegaze, Thai indie\ndream pop, shoegaze, alternative rock\ndream pop, shoegaze, ambient\ndream pop, shoegaze, ambient electronica\ndream pop, shoegaze, ambient rock\ndream pop, shoegaze, breakbeat\ndream pop, shoegaze, chillwave\ndream pop, shoegaze, chiptune\ndream pop, shoegaze, cinematic\ndream pop, shoegaze, emo-rap\ndream pop, shoegaze, indie pop\ndream pop, shoegaze, indie rock\ndream pop, shoegaze, industrial rock\ndream pop, shoegaze, lo-fi\ndream pop, shoegaze, melancholic ballad\ndream pop, shoegaze, noise rock\ndream pop, shoegaze, post-hardcore\ndream pop, shoegaze, post-punk\ndream pop, shoegaze, post-rock\ndream pop, shoegaze, rock\ndream pop, shoegaze, screamo\ndream pop, shoegaze, synth-pop\ndream pop, shoegaze, vaporwave\ndream pop, slap house\ndream pop, slowcore, indie rock\ndream pop, smooth jazz\ndream pop, smooth jazz, city pop\ndream pop, soft rock\ndream pop, soft rock, South Asian pop\ndream pop, soft rock, soulful adult contemporary\ndream pop, surf rock\ndream pop, symphonic metal\ndream pop, symphonic rock\ndream pop, synth pop, ambient\ndream pop, synth-funk\ndream pop, synth-pop\ndream pop, synth-pop, Bollywood\ndream pop, synth-pop, C-pop\ndream pop, synth-pop, Chinese hip-hop\ndream pop, synth-pop, French chanson\ndream pop, synth-pop, French pop\ndream pop, synth-pop, K-pop ballad\ndream pop, synth-pop, Latin\ndream pop, synth-pop, Mandopop\ndream pop, synth-pop, R&B\ndream pop, synth-pop, South Asian\ndream pop, synth-pop, South Indian\ndream pop, synth-pop, Turkish alternative rock\ndream pop, synth-pop, ambient\ndream pop, synth-pop, ambient electronic\ndream pop, synth-pop, ambient electronica\ndream pop, synth-pop, chill hip-hop\ndream pop, synth-pop, chillwave\ndream pop, synth-pop, chiptune\ndream pop, synth-pop, cinematic\ndream pop, synth-pop, electronic\ndream pop, synth-pop, electronic R&B\ndream pop, synth-pop, electronic rock\ndream pop, synth-pop, electropop\ndream pop, synth-pop, ethereal wave\ndream pop, synth-pop, indie pop\ndream pop, synth-pop, indie-pop\ndream pop, synth-pop, lo-fi\ndream pop, synth-pop, lounge\ndream pop, synth-pop, post-punk revival\ndream pop, synth-pop, retro-futuristic\ndream pop, synth-pop, shoegaze\ndream pop, synth-pop, vaporwave\ndream pop, synth-pop, world music\ndream pop, synth-rock\ndream pop, synthwave\ndream pop, synthwave, techno\ndream pop, trance, hardstyle\ndream pop, trap\ndream pop, trap R&B\ndream pop, trap R&B, C-pop\ndream pop, trap R&B, vaporwave\ndream pop, trap pop\ndream pop, trap, Bollywood\ndream pop, trap, C-pop\ndream pop, trap, Chinese hip hop\ndream pop, trap, Chinese pop\ndream pop, trap, Chinese rap\ndream pop, trap, French indie\ndream pop, trap, Italian pop\ndream pop, trap, K-pop\ndream pop, trap, Latin pop\ndream pop, trap, Mandarin hip hop\ndream pop, trap, Mandarin pop\ndream pop, trap, Mandarin rap\ndream pop, trap, Mongolian folk\ndream pop, trap, R&B\ndream pop, trap, Scandinavian pop\ndream pop, trap, Turkish pop\ndream pop, trap, ambient\ndream pop, trap, ambient ballad\ndream pop, trap, cinematic\ndream pop, trap, drum and bass\ndream pop, trap, electronic\ndream pop, trap, emo-rap\ndream pop, trap, emotional\ndream pop, trap, gospel\ndream pop, trap, hip-hop\ndream pop, trap, hyperpop\ndream pop, trap, indie rock\ndream pop, trap, industrial rock\ndream pop, trap, jazz\ndream pop, trap, lo-fi\ndream pop, trap, lo-fi hip hop\ndream pop, trap, melodic rap\ndream pop, trap, modern\ndream pop, trap, pop-punk\ndream pop, trap, rock\ndream pop, trap, soul\ndream pop, trap, synth-pop\ndream pop, trap, vaporwave\ndream pop, trap-R&B, C-pop\ndream pop, trap-pop, R&B\ndream pop, trap-soul, alternative R&B\ndream pop, trip-hop\ndream pop, trip-hop, J-pop\ndream pop, trip-hop, ambient\ndream pop, trip-hop, cinematic\ndream pop, trip-hop, future bass\ndream pop, trip-hop, glitch\ndream pop, trip-hop, indie pop\ndream pop, trip-hop, jazz fusion\ndream pop, trip-hop, lo-fi\ndream pop, trip-hop, lo-fi hip hop\ndream pop, trip-hop, lo-fi hip-hop\ndream pop, trip-hop, shoegaze\ndream pop, tropical house\ndream pop, vaporwave, C-pop\ndream pop, vaporwave, French electronic\ndream pop, vaporwave, R&B\ndream pop, vaporwave, electronic\ndream pop, vaporwave, lo-fi\ndream pop, vaporwave, synth-pop\ndream pop, vaporwave, trap\ndream pop, vaporwave, trip-hop\ndream pop, world electronic\ndream pop, world fusion\ndream pop, world fusion, ambient electronica\ndream pop, world fusion, smooth jazz\ndream pop, world music\ndream pop, world music, Middle Eastern\ndream pop, world music, ambient\ndream pop, world music, ambient pop\ndream pop, world music, electronic\ndream pop, world music, electronic pop\ndream pop, world music, industrial rock\ndream pop, world music, romantic ballad\ndream pop, world pop, Arabic pop\ndream pop, worldbeat, synth-pop\ndream pop-rock\ndream pop-trap\ndream rap\ndream reggaeton\ndream rock\ndream techno\ndream trance\ndream trap\ndream world fusion\ndream world music\ndream-folk\ndream-hop\ndream-pop\ndream-pop C-pop\ndream-pop C-pop EDM\ndream-pop C-pop ambient\ndream-pop C-pop lo-fi hip-hop\ndream-pop C-pop trap\ndream-pop C-rock\ndream-pop J-pop future bass\ndream-pop R&B\ndream-pop R&B Mandopop\ndream-pop alt-rock\ndream-pop alternative metal\ndream-pop alternative rock\ndream-pop alternative rock hip-hop\ndream-pop ambient\ndream-pop ambient house\ndream-pop ambient pop\ndream-pop ambient rock\ndream-pop ambient-pop\ndream-pop arena rock\ndream-pop art-rock\ndream-pop bedroom pop\ndream-pop breakcore\ndream-pop chillwave\ndream-pop chiptune\ndream-pop cinematic\ndream-pop city-pop\ndream-pop coldwave\ndream-pop complextro\ndream-pop deep house\ndream-pop dubstep\ndream-pop electro\ndream-pop emo\ndream-pop emo rap\ndream-pop emo-rap hyperpop\ndream-pop emo-rap post-hardcore\ndream-pop funk-rock\ndream-pop future bass\ndream-pop gabber\ndream-pop garage rock\ndream-pop hard rock\ndream-pop hardstyle\ndream-pop heartland rock\ndream-pop hip-hop\ndream-pop hip-hop pop-rock\ndream-pop house\ndream-pop indie dance\ndream-pop indie pop\ndream-pop indie rock\ndream-pop indie rock jazz\ndream-pop indie rock post-hardcore\ndream-pop indie rock post-rock\ndream-pop indie rock shoegaze\ndream-pop indie-dance\ndream-pop indie-electronic\ndream-pop indie-folk\ndream-pop indie-pop\ndream-pop indie-rock\ndream-pop industrial\ndream-pop industrial hip-hop\ndream-pop industrial rock\ndream-pop latin\ndream-pop latin rock\ndream-pop lo-fi\ndream-pop lo-fi hip hop\ndream-pop lo-fi hip-hop\ndream-pop lo-fi indie pop\ndream-pop metal\ndream-pop metalcore\ndream-pop metalcore electronicore\ndream-pop neo-soul\ndream-pop new wave\ndream-pop noise rock\ndream-pop noise-rock\ndream-pop nu-disco\ndream-pop post-hardcore\ndream-pop post-hardcore metalcore\ndream-pop post-punk\ndream-pop post-punk shoegaze\ndream-pop post-rock\ndream-pop post-rock metalcore\ndream-pop post-rock shoegaze\ndream-pop power-pop\ndream-pop progressive house\ndream-pop progressive rock\ndream-pop progressive trance\ndream-pop psychedelic funk\ndream-pop psychedelic rock\ndream-pop reggae\ndream-pop rock\ndream-pop shoegaze\ndream-pop shoegaze ambient\ndream-pop shoegaze indie rock\ndream-pop shoegaze post-rock\ndream-pop smooth jazz\ndream-pop surf-punk\ndream-pop symphonic metal\ndream-pop synth-pop\ndream-pop synth-rock\ndream-pop synthwave\ndream-pop trance\ndream-pop trap\ndream-pop trap R&B\ndream-pop trap rock\ndream-pop trap-R&B\ndream-pop trip-hop\ndream-pop worldbeat\ndream-pop, Christian rock\ndream-pop, Christian rock, post-rock\ndream-pop, EDM, hip-hop\ndream-pop, Eurodance, K-pop\ndream-pop, J-core, hardstyle\ndream-pop, J-rock\ndream-pop, J-rock, anime rock\ndream-pop, J-rock, trancecore\ndream-pop, Mandarin pop, indie rock\ndream-pop, R&B, ambient\ndream-pop, UK drill\ndream-pop, UK garage, ethereal\ndream-pop, UK garage, house\ndream-pop, UK hip-hop\ndream-pop, alternative rock\ndream-pop, alternative rock, ambient\ndream-pop, alternative rock, cinematic\ndream-pop, alternative rock, emo\ndream-pop, alternative rock, post-rock\ndream-pop, alternative rock, shoegaze\ndream-pop, ambient, Indian folk\ndream-pop, art-pop, psychedelic\ndream-pop, art-rock\ndream-pop, art-rock, cinematic\ndream-pop, chiptune\ndream-pop, cinematic pop, children's music\ndream-pop, cinematic rock, C-pop\ndream-pop, cinematic, electronic\ndream-pop, cinematic, industrial rock\ndream-pop, cinematic, operatic\ndream-pop, cloud rap\ndream-pop, complextro, brostep\ndream-pop, complextro, hardstyle\ndream-pop, dark electro-industrial\ndream-pop, doom metal\ndream-pop, drum and bass\ndream-pop, drum and bass, ambient\ndream-pop, drum and bass, breakcore\ndream-pop, dubstep\ndream-pop, electro-pop, cumbia\ndream-pop, electronic, color bass\ndream-pop, emotional pop-rock\ndream-pop, epic rock, folk fusion\ndream-pop, eurodance, rock\ndream-pop, future bass, Latin pop\ndream-pop, future bass, R&B\ndream-pop, future bass, hyperpop\ndream-pop, future bass, liquid drum and bass\ndream-pop, future bass, trap\ndream-pop, glitch hop, Tamil rap\ndream-pop, grunge, nu-metal\ndream-pop, happy hardcore\ndream-pop, hard rock\ndream-pop, hard rock, alternative metal\ndream-pop, hard rock, heavy metal\ndream-pop, hard rock, psychedelic\ndream-pop, hardstyle\ndream-pop, hardstyle, funk\ndream-pop, hardstyle, trance\ndream-pop, heavy metal\ndream-pop, hyperpop\ndream-pop, hyperpop, J-pop\ndream-pop, hyperpop, breakcore\ndream-pop, hyperpop, industrial\ndream-pop, hyperpop, trap\ndream-pop, indie rock, cinematic\ndream-pop, indie rock, shoegaze\ndream-pop, indie-folk, synth-pop\ndream-pop, indie-pop, post-punk\ndream-pop, indie-pop, theatrical rock\ndream-pop, industrial dubstep, glitch-hop\ndream-pop, industrial electronic\ndream-pop, industrial electronic, dubstep\ndream-pop, industrial electronica, post-rock\ndream-pop, industrial techno\ndream-pop, industrial trap\ndream-pop, lo-fi hip hop, glitch\ndream-pop, lo-fi hip hop, political rap\ndream-pop, lo-fi hip-hop\ndream-pop, lo-fi hip-hop, ambient\ndream-pop, lo-fi trap, hip hop\ndream-pop, metalcore\ndream-pop, metalcore, happy hardcore\ndream-pop, neo-soul, psychedelic\ndream-pop, neo-soul, rock\ndream-pop, new wave\ndream-pop, new wave, ambient\ndream-pop, new wave, synth-pop\ndream-pop, new-age, pop-rock\ndream-pop, noise-rock\ndream-pop, nu-disco, funk house\ndream-pop, phonk, glitch\ndream-pop, pop-punk\ndream-pop, pop-rock\ndream-pop, pop-rock, C-pop\ndream-pop, pop-rock, cinematic\ndream-pop, pop-rock, cinematic rock\ndream-pop, pop-rock, dance-pop\ndream-pop, pop-rock, epic rock\ndream-pop, pop-rock, hip-hop\ndream-pop, post-hardcore, ambient\ndream-pop, post-rock\ndream-pop, post-rock, C-pop\ndream-pop, post-rock, alternative rock\ndream-pop, post-rock, ambient\ndream-pop, post-rock, cinematic\ndream-pop, post-rock, indie rock\ndream-pop, post-rock, industrial\ndream-pop, post-rock, rock\ndream-pop, post-rock, shoegaze\ndream-pop, progressive house\ndream-pop, progressive house, EDM\ndream-pop, progressive house, hardstyle\ndream-pop, progressive metal\ndream-pop, progressive trance\ndream-pop, psychedelic rock, art-pop\ndream-pop, psychedelic, Christmas\ndream-pop, psychedelic, ambient\ndream-pop, psychedelic, post-rock\ndream-pop, psychedelic, shoegaze\ndream-pop, psychedelic-pop\ndream-pop, retrowave\ndream-pop, shoegaze, alternative rock\ndream-pop, shoegaze, ambient\ndream-pop, shoegaze, hyperpop\ndream-pop, shoegaze, lo-fi\ndream-pop, shoegaze, lo-fi hip hop\ndream-pop, shoegaze, noise rock\ndream-pop, shoegaze, noise-rock\ndream-pop, shoegaze, post-punk\ndream-pop, speedcore\ndream-pop, speedcore, J-core\ndream-pop, surf-rock\ndream-pop, symphonic metal\ndream-pop, symphonic metal, baroque\ndream-pop, symphonic metalcore\ndream-pop, synth-pop\ndream-pop, synth-pop, 80s\ndream-pop, synth-pop, alternative rock\ndream-pop, synth-pop, ambient\ndream-pop, synth-pop, symphonic rock\ndream-pop, theatrical rock, cinematic\ndream-pop, trap R&B\ndream-pop, trap R&B, ambient\ndream-pop, trap, cinematic\ndream-pop, trap, hyperpop\ndream-pop, trap, lo-fi hip hop\ndream-pop, trap, pop-rock\ndream-pop, tribal, cinematic\ndream-pop, trip-hop, lo-fi\ndream-pop, trip-hop, shoegaze\ndreamcore\ndreamy Americana\ndreamy Brazilian funk\ndreamy C-pop\ndreamy C-pop chillwave\ndreamy C-pop future bass\ndreamy Christmas\ndreamy Latin\ndreamy R&B\ndreamy R&B lo-fi hip-hop\ndreamy R&B trap\ndreamy R&B, Brazilian trap\ndreamy R&B, emotional hip-hop, Mandarin trap\ndreamy R&B, modern trap\ndreamy R&B, trap, lo-fi hip hop\ndreamy accordion\ndreamy acoustic\ndreamy afrobeat\ndreamy ambient\ndreamy ballad\ndreamy bass\ndreamy blues-rock\ndreamy breakbeat\ndreamy cinematic\ndreamy dancehall\ndreamy dembow\ndreamy drum and bass\ndreamy electronic\ndreamy electronic hip-hop\ndreamy electronic, lo-fi R&B\ndreamy electronica\ndreamy folk\ndreamy folk-rock\ndreamy ghazal\ndreamy hip hop\ndreamy hip-hop\ndreamy house\ndreamy indie pop\ndreamy indie pop, drum and bass\ndreamy indie pop, lo-fi hip hop\ndreamy indie rock\ndreamy indie-pop\ndreamy instrumental\ndreamy instrumental rock\ndreamy jazz\ndreamy jazz-pop\ndreamy jungle\ndreamy lo-fi\ndreamy lo-fi hip hop\ndreamy lounge\ndreamy lullaby\ndreamy piano\ndreamy piano ballad\ndreamy pop\ndreamy pop ballad\ndreamy pop hip-hop\ndreamy pop trap\ndreamy pop world music\ndreamy pop world-pop\ndreamy pop, Eastern European, smooth jazz\ndreamy pop, Javanese Dangdut\ndreamy pop, South Indian, electronic\ndreamy pop, progressive house, big room EDM\ndreamy pop, synth-pop, hip-hop\ndreamy pop-R&B\ndreamy pop-rap\ndreamy pop-reggaeton\ndreamy pop-rock\ndreamy psychedelic rock\ndreamy reggae\ndreamy reggaeton\ndreamy rock\ndreamy synth\ndreamy synth R&B\ndreamy synth trap\ndreamy synth-pop\ndreamy synth-pop future bass\ndreamy synthwave\ndreamy trap\ndreamy trip-hop\ndreamy waltz\ndreamy world fusion\ndrift phonk\ndrill\ndrill R&B\ndrill dancehall\ndrill flamenco\ndrill grime\ndrill hip hop\ndrill hip-hop\ndrill metal\ndrill metalcore\ndrill music\ndrill music classical fusion\ndrill music, Greek folk\ndrill rap\ndrill trap\ndrill trap, lo-fi, R&B\ndrill, African fusion\ndrill, African hip hop\ndrill, Afro drill\ndrill, Afro-French\ndrill, Afro-Swahili\ndrill, Afroswing\ndrill, Arabic hip hop\ndrill, Arabic trap\ndrill, Balkan hip hop\ndrill, Balkan, Middle Eastern\ndrill, Bengali hip hop\ndrill, C-pop\ndrill, Cantonese hip hop\ndrill, Central Asian, trap\ndrill, Chinese drill\ndrill, Chinese hip hop\ndrill, Czech hip hop\ndrill, Dutch hip hop\ndrill, East African hip hop\ndrill, East African hip-hop\ndrill, East Asian, dark hip hop\ndrill, Eastern European folk\ndrill, Eastern European, Balkan\ndrill, Eastern European, dark hip hop\ndrill, Eastern European, lo-fi\ndrill, Eastern melodic\ndrill, French drill, Lingala drill\ndrill, French hip hop\ndrill, French rap\ndrill, French rap, Arabic hip hop\ndrill, French rap, psychedelic\ndrill, German hip hop\ndrill, German rap, English rap\ndrill, German rap, lo-fi\ndrill, Greek drill\ndrill, Greek hip hop\ndrill, Greek rap\ndrill, Haitian Creole rap\ndrill, Hausa, French\ndrill, Indian hip hop\ndrill, Italian drill\ndrill, Italian drill, bilingual drill\ndrill, Italian hip hop\ndrill, Italian rap\ndrill, J-rock, trap\ndrill, Jamaican Patois\ndrill, Jamaican Patois, dark hip hop\ndrill, Jamaican Patois, dark trap\ndrill, Jamaican Patois, electronic\ndrill, Japanese hip hop\ndrill, Kinyarwanda hip hop\ndrill, Korean hip hop\ndrill, Latin hip hop\ndrill, Latin percussion, trap\ndrill, Latin trap\ndrill, Mandarin hip hop\ndrill, Mandarin rap\ndrill, Mandarin rap, Spanish rap\ndrill, Mandarin rap, dark trap\ndrill, Mandarin, English\ndrill, Mediterranean, bilingual\ndrill, Middle Eastern\ndrill, Middle Eastern drill\ndrill, Middle Eastern fusion\ndrill, Middle Eastern, 808\ndrill, Middle Eastern, Dutch hip hop\ndrill, Middle Eastern, Indian\ndrill, Middle Eastern, Mongolian hip hop\ndrill, Middle Eastern, South Asian\ndrill, Middle Eastern, Turkish hip hop\ndrill, Middle Eastern, aggressive\ndrill, Middle Eastern, cinematic\ndrill, Middle Eastern, electronic\ndrill, Middle Eastern, hard-hitting\ndrill, Middle Eastern, hip hop\ndrill, Middle Eastern, lo-fi\ndrill, Middle Eastern, synth\ndrill, Middle Eastern, trap\ndrill, Mongolian hip hop\ndrill, Moroccan Arabic hip hop\ndrill, Nigerian Pidgin rap\ndrill, Nigerian Pidgin, aggressive\ndrill, Nigerian Pidgin, political hip hop\ndrill, Nigerian drill\ndrill, Persian hip hop\ndrill, Portuguese hip hop\ndrill, Portuguese rap\ndrill, Punjabi hip hop\ndrill, R&B\ndrill, R&B, lo-fi\ndrill, Romanian drill, dark trap\ndrill, Russian drill, German drill\ndrill, Russian rap\ndrill, Sinhala hip hop\ndrill, Slovak hip hop\ndrill, South Asian fusion\ndrill, South Asian, hip hop\ndrill, Spanish flavor\ndrill, Spanish hip hop\ndrill, Spanish rap\ndrill, Spanish-style\ndrill, Swahili hip hop\ndrill, Swahili rap\ndrill, Swedish drill\ndrill, Swedish rap, Arabic melodic\ndrill, Turkish hip hop\ndrill, UK drill\ndrill, UK drill, Dutch drill\ndrill, UK drill, German drill\ndrill, UK drill, Greek rap\ndrill, Uyghur hip hop\ndrill, acoustic, melancholic\ndrill, afro-swing\ndrill, afrobeats\ndrill, ambient\ndrill, ambient, Afrobeat\ndrill, ambient, J-pop\ndrill, ambient, dark trap\ndrill, ambient, electronic\ndrill, ambient, melodic rap\ndrill, ambient, sacred\ndrill, ancient style\ndrill, atmospheric, cinematic\ndrill, bilingual\ndrill, bilingual, aggressive\ndrill, bilingual, cinematic\ndrill, bilingual, lo-fi\ndrill, bilingual, trap\ndrill, boom-bap, G-funk, lo-fi hip hop\ndrill, breakcore\ndrill, chiptune\ndrill, chiptune, J-pop\ndrill, chiptune, lo-fi\ndrill, chiptune, trap\ndrill, cinematic\ndrill, cinematic hip hop\ndrill, cinematic trap\ndrill, cinematic trap, melodic hip-hop, ambient\ndrill, cinematic, Chinese hip hop\ndrill, cinematic, Chinese traditional\ndrill, cinematic, French rap\ndrill, cinematic, Hindi hip hop\ndrill, cinematic, Italian hip hop\ndrill, cinematic, Mandarin hip hop\ndrill, cinematic, Mandarin rap\ndrill, cinematic, Middle Eastern\ndrill, cinematic, Portuguese hip hop\ndrill, cinematic, Portuguese rap\ndrill, cinematic, Spanish rap\ndrill, cinematic, Turkish hip hop\ndrill, cinematic, afrobeats\ndrill, cinematic, dark\ndrill, cinematic, dark ambient\ndrill, cinematic, dark trap\ndrill, cinematic, electronic\ndrill, cinematic, gothic\ndrill, cinematic, hip hop\ndrill, cinematic, lo-fi\ndrill, cinematic, melancholic\ndrill, cinematic, microtonal\ndrill, cinematic, orchestral\ndrill, cinematic, synth\ndrill, cinematic, trap\ndrill, cinematic, world fusion\ndrill, classical\ndrill, classical, trap\ndrill, cumbia, trap\ndrill, dancehall\ndrill, dark ambient\ndrill, dark hip hop\ndrill, dark trap\ndrill, dark, Australian drill\ndrill, dark, Dutch drill\ndrill, dark, Dutch hip hop\ndrill, dark, Dutch rap\ndrill, dark, French rap\ndrill, dark, Italian rap\ndrill, dark, Mandarin hip hop\ndrill, dark, Nordic\ndrill, dark, Norwegian hip hop\ndrill, dark, Polish hip hop\ndrill, dark, Russian hip hop\ndrill, dark, Swahili rap\ndrill, dark, atmospheric\ndrill, dark, cinematic\ndrill, dark, electronic\ndrill, dark, lo-fi\ndrill, east-meets-west\ndrill, eastern\ndrill, electronic, Afro-urban\ndrill, electronic, Eastern flavor\ndrill, electronic, hip hop\ndrill, emotional rap\ndrill, epic, mythological\ndrill, ethnic fusion\ndrill, flamenco\ndrill, flamenco hip hop\ndrill, gangsta rap\ndrill, german drill\ndrill, grime\ndrill, hip hop\ndrill, hip hop, Chinese drill\ndrill, hip hop, cinematic\ndrill, hip-hop\ndrill, hip-hop, Mandarin rap\ndrill, horrorcore\ndrill, hyperpop\ndrill, isiZulu hip hop\ndrill, jazz, cinematic\ndrill, lo-fi\ndrill, lo-fi hip hop\ndrill, lo-fi hip hop, ambient\ndrill, lo-fi, Australian hip hop\ndrill, lo-fi, Brazilian hip hop\ndrill, lo-fi, C-pop\ndrill, lo-fi, Chinese hip hop\ndrill, lo-fi, French rap\ndrill, lo-fi, Portuguese rap\ndrill, lo-fi, Russian hip hop\ndrill, lo-fi, Spanish flavor\ndrill, lo-fi, Swedish hip hop\ndrill, lo-fi, acoustic\ndrill, lo-fi, ambient\ndrill, lo-fi, atmospheric\ndrill, lo-fi, bilingual\ndrill, lo-fi, cinematic\ndrill, lo-fi, dark hip hop\ndrill, lo-fi, ethereal\ndrill, lo-fi, hip hop\ndrill, lo-fi, melancholic\ndrill, lo-fi, synthwave\ndrill, lo-fi, trap\ndrill, melancholic, Italian rap\ndrill, melancholic, atmospheric\ndrill, metalcore, cinematic\ndrill, microtonal\ndrill, multilingual\ndrill, multilingual, lo-fi\ndrill, operatic, Middle Eastern\ndrill, orchestral\ndrill, orchestral, Chinese hip hop\ndrill, orchestral, German rap\ndrill, orchestral, Italian rap\ndrill, orchestral, Mandarin hip hop\ndrill, orchestral, Persian hip hop\ndrill, orchestral, cinematic\ndrill, orchestral, hip hop\ndrill, orchestral, melancholic\ndrill, orchestral, trap\ndrill, pluggnb\ndrill, pop, electronic\ndrill, rage\ndrill, reggaeton\ndrill, sad R&B\ndrill, spanish drill, dark trap\ndrill, spanish guitar, raw hip hop\ndrill, spanish hip hop\ndrill, spanish rap\ndrill, synthwave\ndrill, theatrical, political\ndrill, traditional fusion\ndrill, trap\ndrill, trap, African hip hop\ndrill, trap, Afro drill\ndrill, trap, Afro-Drill\ndrill, trap, Afrobeats\ndrill, trap, Arabic fusion\ndrill, trap, Arabic hip hop\ndrill, trap, Arabic mawwal\ndrill, trap, Australian hip hop\ndrill, trap, Balkan\ndrill, trap, Balkan fusion\ndrill, trap, Balkan hip hop\ndrill, trap, Bengali hip hop\ndrill, trap, Brazilian funk\ndrill, trap, Chinese drill\ndrill, trap, Chinese hip hop\ndrill, trap, Eastern European\ndrill, trap, Eastern tonality\ndrill, trap, French Creole hip hop\ndrill, trap, French hip hop\ndrill, trap, Greek hip hop\ndrill, trap, Haitian Creole\ndrill, trap, Hausa hip hop\ndrill, trap, Hausa rap\ndrill, trap, Italian hip hop\ndrill, trap, Jamaican Patois\ndrill, trap, Middle Eastern\ndrill, trap, Middle Eastern fusion\ndrill, trap, Middle Eastern hip hop\ndrill, trap, Nigerian Pidgin\ndrill, trap, Nigerian Pidgin rap\ndrill, trap, Patois hip hop\ndrill, trap, Punjabi hip hop\ndrill, trap, Sinhala hip hop\ndrill, trap, Slovak hip hop\ndrill, trap, Southern hip hop\ndrill, trap, Spanish drill\ndrill, trap, Spanish guitar\ndrill, trap, Spanish hip hop\ndrill, trap, Spanish rap\ndrill, trap, Swahili hip hop\ndrill, trap, Swahili rap\ndrill, trap, Swedish hip hop\ndrill, trap, UK drill\ndrill, trap, West African hip hop\ndrill, trap, afrobeats\ndrill, trap, ambient\ndrill, trap, atmospheric\ndrill, trap, bilingual\ndrill, trap, bilingual rap\ndrill, trap, chiptune\ndrill, trap, cinematic\ndrill, trap, classical\ndrill, trap, danish hip hop\ndrill, trap, dark\ndrill, trap, dark ambient\ndrill, trap, dark hip hop\ndrill, trap, electronic\ndrill, trap, experimental\ndrill, trap, gangsta rap\ndrill, trap, global hip-hop\ndrill, trap, hardcore\ndrill, trap, hip hop\ndrill, trap, hip-hop\ndrill, trap, klezmer\ndrill, trap, koto\ndrill, trap, lo-fi\ndrill, trap, lo-fi hip hop\ndrill, trap, multi-lingual\ndrill, trap, multilingual\ndrill, trap, multilingual hip hop\ndrill, trap, orchestral\ndrill, trap, orchestral drill\ndrill, trap, orchestral hip hop\ndrill, trap, political hip hop\ndrill, trap, raw hip hop\ndrill, trap, synth brass\ndrill, trap, world music\ndrill, turbo-folk\ndrill, world music, trap\ndrinking song\ndrone\ndrone metal\ndrone, breakcore, IDM\ndrum & bass\ndrum & bass hyperpop\ndrum & bass, artcore, J-pop\ndrum & bass, future bass\ndrum 'n' bass\ndrum ambient\ndrum and bass\ndrum and bass Balkan pop\ndrum and bass Bollywood\ndrum and bass IDM\ndrum and bass J-pop\ndrum and bass J-pop artcore\ndrum and bass Latin\ndrum and bass R&B\ndrum and bass R&B hip-hop\ndrum and bass acid jazz\ndrum and bass acid jazz funk\ndrum and bass acid techno\ndrum and bass alternative rock\ndrum and bass ambient\ndrum and bass ambient chillwave\ndrum and bass art pop\ndrum and bass artcore\ndrum and bass artcore chiptune\ndrum and bass artcore happy hardcore\ndrum and bass artcore trance\ndrum and bass big beat\ndrum and bass breakbeat experimental\ndrum and bass breakcore\ndrum and bass chiptune\ndrum and bass chiptune artcore\ndrum and bass cinematic\ndrum and bass classical fusion\ndrum and bass cyberpunk\ndrum and bass dancehall\ndrum and bass dark pop\ndrum and bass darkwave\ndrum and bass dream pop\ndrum and bass dubstep\ndrum and bass electro\ndrum and bass electro-punk\ndrum and bass electronic rock\ndrum and bass emo\ndrum and bass flamenco\ndrum and bass funk\ndrum and bass funk rock\ndrum and bass funk soul\ndrum and bass future bass\ndrum and bass future bass happy hardcore\ndrum and bass future bass hyperpop\ndrum and bass future bass neurofunk\ndrum and bass future garage\ndrum and bass glitch\ndrum and bass glitch hop\ndrum and bass glitch-pop\ndrum and bass grime\ndrum and bass happy hardcore\ndrum and bass hardcore\ndrum and bass hardcore artcore\ndrum and bass hardcore breakcore\ndrum and bass hardcore j-core\ndrum and bass hardcore trance\ndrum and bass hardstyle\ndrum and bass hardstyle dubstep\ndrum and bass hip-hop\ndrum and bass hip-hop pop\ndrum and bass hyperpop\ndrum and bass hyperpop J-core\ndrum and bass hyperpop art pop\ndrum and bass hyperpop artcore\ndrum and bass hyperpop breakcore\ndrum and bass hyperpop chiptune\ndrum and bass hyperpop emo\ndrum and bass hyperpop hardstyle\ndrum and bass hyperpop j-core\ndrum and bass hyperpop j-pop\ndrum and bass hyperpop neurofunk\ndrum and bass hyperpop rave\ndrum and bass hyperpop trance\ndrum and bass indie rock\ndrum and bass industrial\ndrum and bass industrial metal\ndrum and bass industrial rock\ndrum and bass industrial trance\ndrum and bass j-pop\ndrum and bass j-pop anime\ndrum and bass jazz\ndrum and bass jazz fusion\ndrum and bass jazz fusion chiptune\ndrum and bass jungle\ndrum and bass jungle breakbeat hardcore\ndrum and bass jungle dancehall\ndrum and bass jungle reggae\ndrum and bass liquid funk\ndrum and bass liquid funk jazz\ndrum and bass lo-fi\ndrum and bass lounge\ndrum and bass metal\ndrum and bass metalcore\ndrum and bass moombahton\ndrum and bass neo-soul\ndrum and bass neurofunk\ndrum and bass neurofunk artcore\ndrum and bass neurofunk breakcore\ndrum and bass neurofunk chiptune\ndrum and bass neurofunk cybergrind\ndrum and bass neurofunk future bass\ndrum and bass neurofunk hardstyle\ndrum and bass neurofunk hyperpop\ndrum and bass neurofunk k-pop\ndrum and bass neurofunk liquid funk\ndrum and bass neurofunk rock\ndrum and bass neurofunk techstep\ndrum and bass pop\ndrum and bass pop UK garage\ndrum and bass pop future bass\ndrum and bass pop-punk\ndrum and bass pop-rock\ndrum and bass progressive metal\ndrum and bass psytrance\ndrum and bass psytrance chiptune\ndrum and bass rap-rock\ndrum and bass rapcore\ndrum and bass reggae\ndrum and bass reggae dancehall\ndrum and bass reggaeton\ndrum and bass samba\ndrum and bass shoegaze\ndrum and bass ska-punk\ndrum and bass synth-pop\ndrum and bass synth-pop chiptune\ndrum and bass synth-pop post-punk\ndrum and bass synthwave\ndrum and bass synthwave electronic rock\ndrum and bass techstep\ndrum and bass trance\ndrum and bass trance J-core\ndrum and bass trance artcore\ndrum and bass trance hardcore\ndrum and bass trance hardstyle\ndrum and bass trance j-core\ndrum and bass trance world music\ndrum and bass trip-hop\ndrum and bass trip-hop ambient\ndrum and bass vaporwave synthwave\ndrum and bass world fusion\ndrum and bass world music\ndrum and bass, Afrobeat, psychedelic rock\ndrum and bass, Arabic R&B, ambient\ndrum and bass, Brazilian funk\ndrum and bass, C-pop, ambient\ndrum and bass, Eastern European folk\ndrum and bass, IDM\ndrum and bass, IDM, ambient\ndrum and bass, IDM, neurofunk\ndrum and bass, IDM, trance\ndrum and bass, Indian classical, ambient\ndrum and bass, Indian classical, neurofunk\ndrum and bass, J-core\ndrum and bass, J-core, artcore\ndrum and bass, J-core, happy hardcore\ndrum and bass, J-core, hyperpop\ndrum and bass, J-pop\ndrum and bass, J-pop, artcore\ndrum and bass, J-pop, hyperpop\ndrum and bass, J-pop, neurofunk\ndrum and bass, J-rock\ndrum and bass, J-rock, anime\ndrum and bass, J-rock, anime theme\ndrum and bass, J-rock, artcore\ndrum and bass, J-rock, breakbeat\ndrum and bass, Japanese hardcore, chiptune\ndrum and bass, K-pop, hyperpop\ndrum and bass, Latin electronic\ndrum and bass, Latin pop, bachata\ndrum and bass, Latin pop, hyperpop\ndrum and bass, Latin, tribal\ndrum and bass, Latin, world music\ndrum and bass, Middle Eastern folk\ndrum and bass, Middle Eastern, instrumental\ndrum and bass, Punjabi folk\ndrum and bass, Russian folk\ndrum and bass, Russian rap\ndrum and bass, Russian rap, breakbeat\ndrum and bass, Slavic folk\ndrum and bass, Slavic folk, neurofunk\ndrum and bass, Turkish folk\ndrum and bass, UK garage\ndrum and bass, UK garage, ambient\ndrum and bass, UK garage, chiptune\ndrum and bass, UK garage, grime\ndrum and bass, UK garage, pop\ndrum and bass, UK garage, punk\ndrum and bass, UK garage, soul\ndrum and bass, UK grime\ndrum and bass, UK grime, cinematic\ndrum and bass, UK hardcore\ndrum and bass, UK hardcore, cinematic\ndrum and bass, UK hip-hop\ndrum and bass, UK hip-hop, neurofunk\ndrum and bass, ambient, Chinese fusion\ndrum and bass, ambient, breakcore\ndrum and bass, ambient, cinematic\ndrum and bass, ambient, neurofunk\ndrum and bass, ambient, spiritual\ndrum and bass, art pop, cinematic\ndrum and bass, artcore, Indonesian vocal\ndrum and bass, artcore, J-core\ndrum and bass, artcore, ambient\ndrum and bass, artcore, chiptune\ndrum and bass, artcore, gabber\ndrum and bass, artcore, hyperpop\ndrum and bass, artcore, video game\ndrum and bass, atmospheric trance\ndrum and bass, big band swing\ndrum and bass, big beat\ndrum and bass, big beat, breakbeat\ndrum and bass, breakbeat, R&B\ndrum and bass, breakbeat, chiptune\ndrum and bass, breakbeat, cyberpunk\ndrum and bass, breakbeat, hyperpop\ndrum and bass, breakbeat, synth-pop\ndrum and bass, breakbeat, video game music\ndrum and bass, breakbeat, world music\ndrum and bass, breakcore\ndrum and bass, breakcore, J-core\ndrum and bass, breakcore, K-pop\ndrum and bass, breakcore, ambient\ndrum and bass, breakcore, art pop\ndrum and bass, breakcore, artcore\ndrum and bass, breakcore, chiptune\ndrum and bass, breakcore, cinematic\ndrum and bass, breakcore, glitch\ndrum and bass, breakcore, hardstyle\ndrum and bass, breakcore, hyperpop\ndrum and bass, breakcore, jungle\ndrum and bass, breakcore, neurofunk\ndrum and bass, breakcore, trance\ndrum and bass, chiptune\ndrum and bass, chiptune, J-core\ndrum and bass, chiptune, artcore\ndrum and bass, chiptune, electronic\ndrum and bass, chiptune, happy hardcore\ndrum and bass, chiptune, hyperpop\ndrum and bass, chiptune, neurofunk\ndrum and bass, chiptune, tech-trance\ndrum and bass, chiptune, trance\ndrum and bass, cinematic\ndrum and bass, cinematic folk\ndrum and bass, cinematic, J-rock\ndrum and bass, cinematic, Mandarin rap\ndrum and bass, cinematic, Middle Eastern fusion\ndrum and bass, cinematic, ambient\ndrum and bass, cinematic, chiptune\ndrum and bass, cinematic, electronic\ndrum and bass, cinematic, neurofunk\ndrum and bass, cinematic, operatic\ndrum and bass, cinematic, pop\ndrum and bass, cinematic, sci-fi\ndrum and bass, complexro, J-core\ndrum and bass, cyberpunk, hip-hop\ndrum and bass, cyberpunk, industrial rock\ndrum and bass, cyberpunk, neurofunk\ndrum and bass, dark ambient, neurofunk\ndrum and bass, dubstep, chiptune\ndrum and bass, dubstep, cinematic\ndrum and bass, dubstep, hardstyle\ndrum and bass, electronic rock\ndrum and bass, ethereal wave\ndrum and bass, ethnic electronica, ambient\ndrum and bass, eurodance\ndrum and bass, eurodance, happy hardcore\ndrum and bass, eurodance, industrial rock\ndrum and bass, eurodance, trance\ndrum and bass, flamenco, Middle Eastern\ndrum and bass, folk\ndrum and bass, folk, Eastern European\ndrum and bass, future bass, hyperpop\ndrum and bass, gospel, hyperpop\ndrum and bass, grime\ndrum and bass, grime, hardcore\ndrum and bass, grime, neurofunk\ndrum and bass, happy hardcore\ndrum and bass, happy hardcore, J-core\ndrum and bass, happy hardcore, UK hardcore\ndrum and bass, happy hardcore, chiptune\ndrum and bass, happy hardcore, hardstyle\ndrum and bass, happy hardcore, neurofunk\ndrum and bass, happy hardcore, soulful\ndrum and bass, happy hardcore, trance\ndrum and bass, hardbass\ndrum and bass, hardcore rap, German hip hop\ndrum and bass, hardcore, neurofunk\ndrum and bass, hardstyle\ndrum and bass, hardstyle, ambient\ndrum and bass, hardstyle, breakcore\ndrum and bass, hardstyle, cinematic\ndrum and bass, hardstyle, cyberpunk\ndrum and bass, hardstyle, dubstep\ndrum and bass, hardstyle, gabber\ndrum and bass, hardstyle, psytrance\ndrum and bass, hardstyle, trap\ndrum and bass, hip-hop\ndrum and bass, hyperpop\ndrum and bass, hyperpop, ambient\ndrum and bass, hyperpop, art pop\ndrum and bass, hyperpop, artcore\ndrum and bass, hyperpop, breakcore\ndrum and bass, hyperpop, glitchcore\ndrum and bass, hyperpop, lo-fi\ndrum and bass, hyperpop, neurofunk\ndrum and bass, hyperpop, nightcore\ndrum and bass, industrial metal, ambient\ndrum and bass, industrial, dark electronic\ndrum and bass, industrial, dark pop\ndrum and bass, industrial, neurofunk\ndrum and bass, jungle\ndrum and bass, jungle, breakcore\ndrum and bass, jungle, chiptune\ndrum and bass, lo-fi, cinematic\ndrum and bass, lo-fi, vaporwave\ndrum and bass, metalcore, cinematic\ndrum and bass, metalcore, rap\ndrum and bass, neurofunk\ndrum and bass, neurofunk, Asian fusion\ndrum and bass, neurofunk, Eastern European folk\ndrum and bass, neurofunk, J-core\ndrum and bass, neurofunk, Middle Eastern\ndrum and bass, neurofunk, UK garage\ndrum and bass, neurofunk, alternative rock\ndrum and bass, neurofunk, ambient\ndrum and bass, neurofunk, anime\ndrum and bass, neurofunk, artcore\ndrum and bass, neurofunk, atmospheric\ndrum and bass, neurofunk, breakbeat\ndrum and bass, neurofunk, breakcore\ndrum and bass, neurofunk, chiptune\ndrum and bass, neurofunk, cinematic\ndrum and bass, neurofunk, complextro\ndrum and bass, neurofunk, cyberpunk\ndrum and bass, neurofunk, darkwave\ndrum and bass, neurofunk, dubstep\ndrum and bass, neurofunk, electronic\ndrum and bass, neurofunk, ethereal\ndrum and bass, neurofunk, ethnic\ndrum and bass, neurofunk, ethno-electronic\ndrum and bass, neurofunk, future bass\ndrum and bass, neurofunk, futuristic\ndrum and bass, neurofunk, glitch\ndrum and bass, neurofunk, grime\ndrum and bass, neurofunk, happy hardcore\ndrum and bass, neurofunk, hardcore\ndrum and bass, neurofunk, hardstyle\ndrum and bass, neurofunk, hip-hop\ndrum and bass, neurofunk, hyperpop\ndrum and bass, neurofunk, jazz fusion\ndrum and bass, neurofunk, jungle\ndrum and bass, neurofunk, liquid funk\ndrum and bass, neurofunk, lo-fi\ndrum and bass, neurofunk, metal\ndrum and bass, neurofunk, political\ndrum and bass, neurofunk, political rap\ndrum and bass, neurofunk, pop\ndrum and bass, neurofunk, pop-punk\ndrum and bass, neurofunk, ritual ambient\ndrum and bass, neurofunk, rock\ndrum and bass, neurofunk, sci-fi\ndrum and bass, neurofunk, synthwave\ndrum and bass, neurofunk, techstep\ndrum and bass, neurofunk, world music\ndrum and bass, orchestral dubstep\ndrum and bass, post-punk, industrial rock\ndrum and bass, post-rock, math rock\ndrum and bass, psytrance, Middle Eastern\ndrum and bass, psytrance, artcore\ndrum and bass, psytrance, hardstyle\ndrum and bass, psytrance, video game soundtrack\ndrum and bass, speedcore, hardcore\ndrum and bass, spiritual, mantra\ndrum and bass, synth-pop\ndrum and bass, synth-pop, chiptune\ndrum and bass, synth-pop, cyberpunk\ndrum and bass, synth-pop, liquid funk\ndrum and bass, synth-pop, trance\ndrum and bass, synthwave\ndrum and bass, synthwave, chiptune\ndrum and bass, synthwave, cyberpunk\ndrum and bass, traditional East Asian, electronic\ndrum and bass, trance\ndrum and bass, trance, J-core\ndrum and bass, trance, J-pop\ndrum and bass, trance, artcore\ndrum and bass, trance, chiptune\ndrum and bass, trance, cinematic\ndrum and bass, trance, darkwave\ndrum and bass, trance, happy hardcore\ndrum and bass, trance, hardstyle\ndrum and bass, trance, hyperpop\ndrum and bass, trance, neurofunk\ndrum and bass, trip-hop\ndrum and bass, two-step, hip-hop\ndrum and bass, vaporwave\ndrum and bass, vaporwave, lo-fi\ndrum and bass, video game music\ndrum and bass, video game music, world fusion\ndrum and bass, world music, ambient\ndrum and bass, world music, psytrance\ndrum and percussion\ndrum beat\ndrum break\ndrum corps\ndrum ensemble\ndrum fill\ndrum groove\ndrum heavy\ndrum instrumental\ndrum intensity\ndrum intensive\ndrum intro\ndrum kit\ndrum loop\ndrum machine\ndrum metal\ndrum music\ndrum performance\ndrum roll\ndrum sample\ndrum showcase\ndrum solo\ndrum track\ndrum tutorial\ndrum-centric\ndrum-driven\ndrum-driven rock\ndrum-focused\ndrum-focused rock\ndrum-heavy\ndrum-intensive\ndrumline\ndrumline punk\ndrumming\ndub\ndub electronic\ndub funk\ndub funk world music\ndub hip hop\ndub hip-hop\ndub house\ndub lounge\ndub punk\ndub reggae\ndub reggae art music\ndub reggae chiptune\ndub reggae hip-hop\ndub reggae indie rock\ndub reggae latin\ndub reggae, Latin hip-hop\ndub reggae, neurofunk\ndub soul\ndub techno\ndub, Latin groove\ndub, afrobeat, funk\ndub, breakbeat, experimental\ndub, dancehall, experimental electronic\ndub, drum and bass, soul\ndub, hardstyle, psytrance\ndub, lo-fi hip hop, dancehall\ndub, psytrance\ndub, trip-hop, experimental\ndub, worldbeat, dance\ndub-funk\ndub-pop\ndub-reggae\ndub-reggae chiptune\ndub-reggae conscious hip-hop\ndub-reggae funk art-rock\ndub-reggae, jungle, gabber\ndubstep\ndubstep C-pop\ndubstep R&B\ndubstep alternative rock\ndubstep ambient\ndubstep bass house\ndubstep breakcore\ndubstep brostep\ndubstep chiptune\ndubstep chiptune rap\ndubstep cinematic\ndubstep complextro\ndubstep dancehall\ndubstep dancehall reggae\ndubstep drum and bass\ndubstep drum and bass chiptune\ndubstep electro house\ndubstep electro-pop\ndubstep festival trap\ndubstep future bass\ndubstep glitch hop\ndubstep glitch hop hardstyle\ndubstep glitch hop neurofunk\ndubstep glitch hop rap\ndubstep glitch-hop\ndubstep glitchcore\ndubstep grime\ndubstep hardcore\ndubstep hardstyle\ndubstep hardstyle chiptune\ndubstep hardstyle cinematic\ndubstep hardstyle cinematic rap\ndubstep hardstyle emo-rap\ndubstep hardstyle experimental bass\ndubstep hardstyle glitchcore\ndubstep hardstyle industrial\ndubstep hardstyle rap\ndubstep hip-hop\ndubstep hip-hop acoustic\ndubstep hybrid trap\ndubstep hyperpop\ndubstep industrial\ndubstep lo-fi\ndubstep metalcore\ndubstep metalcore chiptune\ndubstep metalstep\ndubstep moombahton pop\ndubstep neurofunk\ndubstep orchestral\ndubstep pop-rock\ndubstep rap\ndubstep rap-rock\ndubstep reggae-ska\ndubstep riddim\ndubstep rock\ndubstep synth-pop\ndubstep synthwave\ndubstep trap\ndubstep trap chiptune\ndubstep trap glitch hop\ndubstep trap hardstyle\ndubstep trap hyperpop\ndubstep trap metal\ndubstep trap metal dark pop\ndubstep trap metal glitch hop\ndubstep trap metal hyperpop\ndubstep, C-pop, cinematic\ndubstep, EDM, complextro\ndubstep, K-pop, cinematic\ndubstep, R&B, Latin hip hop\ndubstep, a cappella\ndubstep, ambient, C-pop\ndubstep, ambient, Middle Eastern\ndubstep, ambient, chiptune\ndubstep, ambient, cinematic\ndubstep, ambient, electronic\ndubstep, ambient, emotional\ndubstep, ambient, hardstyle\ndubstep, ambient, hip hop\ndubstep, anime, ambient\ndubstep, breakcore, ambient\ndubstep, brostep\ndubstep, brostep, carnival\ndubstep, brostep, cinematic\ndubstep, brostep, electronic\ndubstep, brostep, electronic pop\ndubstep, brostep, electronic rap\ndubstep, brostep, hardstyle\ndubstep, brostep, pop\ndubstep, chiptune, brostep\ndubstep, chiptune, cinematic\ndubstep, chiptune, complextro\ndubstep, chiptune, glitch-hop\ndubstep, chiptune, metalcore\ndubstep, chiptune, rap\ndubstep, chiptune, trap\ndubstep, cinematic ambient, chiptune\ndubstep, cinematic rock, electronic\ndubstep, cinematic trap\ndubstep, cinematic, Arabic fusion\ndubstep, cinematic, Hebrew vocal\ndubstep, cinematic, Indian fusion\ndubstep, cinematic, Middle Eastern\ndubstep, cinematic, Middle Eastern fusion\ndubstep, cinematic, UK garage\ndubstep, cinematic, acoustic\ndubstep, cinematic, ambient\ndubstep, cinematic, complexro\ndubstep, cinematic, complextro\ndubstep, cinematic, downtempo\ndubstep, cinematic, electronic\ndubstep, cinematic, emotional\ndubstep, cinematic, ethereal\ndubstep, cinematic, gospel\ndubstep, cinematic, hip hop\ndubstep, cinematic, industrial\ndubstep, cinematic, lo-fi\ndubstep, cinematic, metalcore\ndubstep, cinematic, orchestral\ndubstep, cinematic, post-hardcore\ndubstep, cinematic, sci-fi\ndubstep, cinematic, synth-pop\ndubstep, complextro, ambient\ndubstep, complextro, cinematic\ndubstep, complextro, cinematic electronic\ndubstep, complextro, pop\ndubstep, cyberpunk, electronic\ndubstep, dancehall, experimental electronic\ndubstep, dark ambient\ndubstep, drum and bass, emotional pop\ndubstep, electronic rock, brostep\ndubstep, electronic rock, cinematic\ndubstep, electronic, atmospheric\ndubstep, electronic, chiptune\ndubstep, electronic, cinematic\ndubstep, electronic, hard electro\ndubstep, electronic, lo-fi hip hop\ndubstep, electronic, pop\ndubstep, folk, hybrid\ndubstep, future bass\ndubstep, future bass, cinematic\ndubstep, glitch hop, hardstyle\ndubstep, glitch, cinematic\ndubstep, glitch-hop, ambient\ndubstep, glitch-hop, pop\ndubstep, grime\ndubstep, hard trap, electronic\ndubstep, hardstyle\ndubstep, hardstyle, R&B\ndubstep, hardstyle, ambient\ndubstep, hardstyle, chiptune\ndubstep, hardstyle, cinematic\ndubstep, hardstyle, cinematic electronic\ndubstep, hardstyle, electronic\ndubstep, hardstyle, electronic rap\ndubstep, hardstyle, glitch\ndubstep, hardstyle, hip hop\ndubstep, hardstyle, melodic pop\ndubstep, hardstyle, pop\ndubstep, hardwave, ambient\ndubstep, hip hop\ndubstep, hip-hop\ndubstep, hip-hop, EDM\ndubstep, hip-hop, ambient\ndubstep, hip-hop, cinematic\ndubstep, jazz lounge\ndubstep, jazz-funk, cinematic\ndubstep, lo-fi, ambient\ndubstep, lo-fi, cinematic\ndubstep, melodic dubstep\ndubstep, melodic riddim\ndubstep, neurofunk\ndubstep, neurofunk, chiptune\ndubstep, neurofunk, cinematic\ndubstep, neurofunk, trap\ndubstep, orchestral, baroque\ndubstep, orchestral, boom-bap\ndubstep, pop, EDM\ndubstep, pop-rock, cinematic\ndubstep, pop-rock, metalcore\ndubstep, progressive house, Chinese ambient\ndubstep, psytrance, cinematic\ndubstep, rap, ballad\ndubstep, rap, chiptune\ndubstep, rap, surf-rock\ndubstep, trance, ambient\ndubstep, trance, cinematic\ndubstep, trap, R&B\ndubstep, trap, ambient\ndubstep, vaporwave\ndubstep, world music, electronic\nduet ballad\ndutch house\ndystopian boom-bap\ndystopian cinematic\ndystopian electro\ndystopian electronic\ndystopian electronic reggae synth-pop\ndystopian hip-hop\ndystopian reggae\ndystopian rock\ndystopian synthwave\ndystopian techno\ndystopian trap\nearly 1960s pop\nearly 2000s R&B\nearly 2000s R&B hip-hop\nearly 2000s R&B pop\nearly 2000s hip-hop\nearly 2000s house\nearly 2000s pop\nearly 2000s ringtone\nearly 2010s hip-hop\nearly 90s R&B\nearly 90s electronic\nearly 90s house\nearly 90s house, Italo disco\nearly 90s techno\nearly EBM\nearly R&B\nearly hip-hop\nearly house\nearly house techno\nearly house, R&B\nearly house, disco-funk\nearly house, electro-funk\nearly jazz\nearly pop\nearly reggae\nearly rock and roll\nearly rock and roll doo-wop\nearly soul\nearly soul, rock and roll\nearly techno\nearly techno house\nearly techno, EBM\nearly trance\nearly-2000s R&B\nearly-90s house\neasy listening\neasy listening exotica\neasy listening pop\neasy-listening\neasy-listening Christmas pop\neasy-listening ballad\neasy-listening bossa nova\neasy-listening jazz\neasy-listening lounge\neasy-listening orchestral\neasy-listening pop\neasy-listening pop-rock\neasy-listening tropical\neasy-listening waltz\neasy-listening, Latin, exotica\neasycore\neasycore nintendocore\neccentric hip-hop\neclectic rock\neclectic, cinematic, ambient\nedm big room\neducational\neducational Latin\neducational ambient\neducational children's music\neducational chiptune\neducational comedy\neducational electronic\neducational folk\neducational hip hop\neducational hip-hop\neducational jingle\neducational music\neducational narration\neducational pop\neducational pop chiptune\neducational pop hip-hop\neducational pop schlager\neducational pop-rap\neducational pop-rock\neducational rap\neducational rock\neducational spoken word\neducational talk\neducational techno\neducational ukulele\neducational world music\neducational, cinematic, Chinese classical\neerie children's music\neerie lullaby\nelectric blues\nelectro\nelectro Arabic\nelectro Balkan\nelectro Balkan fusion\nelectro Bhojpuri\nelectro Indian\nelectro Latin\nelectro R&B\nelectro Rai\nelectro accordion\nelectro ambient\nelectro arabic\nelectro beat\nelectro bhajan\nelectro bhangra\nelectro big beat\nelectro bollywood\nelectro boogie\nelectro brass\nelectro breakbeat\nelectro brega\nelectro cabaret\nelectro chillwave\nelectro chiptune\nelectro chiptune breakbeat\nelectro chiptune synthwave\nelectro chiptune trance\nelectro classical\nelectro country\nelectro cumbia\nelectro dance\nelectro dance, chiptune, folk fusion\nelectro dance, retro, South Asian\nelectro dancehall worldbeat\nelectro darkwave\nelectro dembow\nelectro flamenco\nelectro folk\nelectro folk rave\nelectro funk\nelectro funk soul\nelectro fusion\nelectro game music\nelectro gospel\nelectro guzheng\nelectro gypsy jazz\nelectro hardcore\nelectro hip hop\nelectro hip-hop\nelectro hip-hop chiptune\nelectro hip-hop darkwave\nelectro hip-hop industrial\nelectro house\nelectro house Balkan\nelectro house C-pop\nelectro house C-pop Eurodance\nelectro house K-pop\nelectro house Latin\nelectro house R&B\nelectro house bhangra\nelectro house big room\nelectro house big room complextro\nelectro house bitpop\nelectro house bluegrass\nelectro house breakbeat\nelectro house brostep\nelectro house chiptune\nelectro house chiptune dubstep\nelectro house chiptune eurodance\nelectro house chiptune latin\nelectro house chiptune orchestral\nelectro house chiptune synth-pop\nelectro house chiptune synthwave\nelectro house complextro\nelectro house dance-pop\nelectro house dancehall\nelectro house dubstep\nelectro house funk\nelectro house future bass\nelectro house future bass J-core\nelectro house future bass glitch hop\nelectro house hardstyle\nelectro house hip hop\nelectro house hip-hop\nelectro house j-pop\nelectro house j-pop chiptune\nelectro house k-pop chiptune\nelectro house latin\nelectro house nu-disco chiptune\nelectro house nu-disco funk\nelectro house pop\nelectro house pop-punk\nelectro house punk rock\nelectro house rap\nelectro house sea shanty\nelectro house slap house\nelectro house synthwave\nelectro house techno\nelectro house tropical\nelectro house worldbeat\nelectro house, Arabic fusion\nelectro house, Arabic pop, North African fusion\nelectro house, Bollywood, nightcore\nelectro house, Brazilian funk\nelectro house, C-pop, hip-hop\nelectro house, Christian rock\nelectro house, Dutch House, Kannada rap\nelectro house, Dutch hip-hop\nelectro house, French rap\nelectro house, German party-rap, Eurodance\nelectro house, J-core, chiptune\nelectro house, J-core, future bass\nelectro house, J-core, happy hardcore\nelectro house, J-core, kawaii metal\nelectro house, J-core, nightcore\nelectro house, J-pop, C-pop\nelectro house, J-pop, future bass\nelectro house, J-pop, hardstyle\nelectro house, J-pop, hyperpop\nelectro house, K-pop\nelectro house, K-pop, big room\nelectro house, K-pop, happy hardcore\nelectro house, K-pop, hardstyle\nelectro house, K-pop, hyperpop\nelectro house, K-pop, moombahton\nelectro house, Kollywood dance\nelectro house, Latin\nelectro house, Latin dance, French rap\nelectro house, Latin house\nelectro house, Latin pop\nelectro house, Latin pop, moombahton\nelectro house, Latin urban\nelectro house, Latin, Arabic\nelectro house, Latin, big room\nelectro house, Latin, chiptune\nelectro house, Mandopop\nelectro house, Middle Eastern fusion\nelectro house, Middle Eastern, Balkan\nelectro house, Middle Eastern, Turkish\nelectro house, South Asian fusion, Middle Eastern electronic\nelectro house, Turkish folk, Middle Eastern fusion\nelectro house, UK garage\nelectro house, UK garage, big room\nelectro house, UK garage, chiptune\nelectro house, UK garage, grime\nelectro house, UK grime\nelectro house, V-pop\nelectro house, bhangra, Middle Eastern fusion\nelectro house, bhangra, hardstyle\nelectro house, big room\nelectro house, big room EDM\nelectro house, big room house\nelectro house, big room, Dutch House\nelectro house, big room, Mandarin rap\nelectro house, big room, acoustic pop\nelectro house, big room, aggressive\nelectro house, big room, chiptune\nelectro house, big room, cinematic\nelectro house, big room, electronic\nelectro house, big room, funk\nelectro house, big room, hardstyle\nelectro house, big room, pop R&B\nelectro house, big room, trap\nelectro house, bilingual club\nelectro house, chiptune\nelectro house, chiptune, 8-bit\nelectro house, chiptune, C-pop\nelectro house, chiptune, Indian electronic\nelectro house, chiptune, J-core\nelectro house, chiptune, South Asian fusion\nelectro house, chiptune, UK garage\nelectro house, chiptune, bhangra\nelectro house, chiptune, cinematic\nelectro house, chiptune, complextro\nelectro house, chiptune, cyberpunk\nelectro house, chiptune, happy hardcore\nelectro house, chiptune, hardstyle\nelectro house, chiptune, hip-hop\nelectro house, chiptune, hyperpop\nelectro house, chiptune, lo-fi hip hop\nelectro house, chiptune, lo-fi hip-hop\nelectro house, chiptune, pop-punk\nelectro house, chiptune, synthwave\nelectro house, chiptune, trap\nelectro house, chiptune, video game music\nelectro house, cinematic, synth-pop\nelectro house, complexro, cinematic\nelectro house, complextro\nelectro house, complextro, J-core\nelectro house, complextro, chiptune\nelectro house, complextro, cinematic\nelectro house, complextro, vaporwave\nelectro house, dance pop\nelectro house, dance-pop, South Asian fusion\nelectro house, dubstep\nelectro house, dubstep, chiptune\nelectro house, dubstep, hardstyle\nelectro house, ethnic electronica\nelectro house, future bass\nelectro house, future bass, J-core\nelectro house, future bass, chiptune\nelectro house, future bass, pop\nelectro house, future bass, rap\nelectro house, happy hardcore\nelectro house, happy hardcore, nightcore\nelectro house, hard dance, happy hardcore\nelectro house, hardcore, chiptune\nelectro house, hardstyle\nelectro house, hardstyle, Bollywood\nelectro house, hardstyle, C-pop\nelectro house, hardstyle, K-pop\nelectro house, hardstyle, Latin\nelectro house, hardstyle, Middle Eastern EDM\nelectro house, hardstyle, big room\nelectro house, hardstyle, breakcore\nelectro house, hardstyle, chiptune\nelectro house, hardstyle, complextro\nelectro house, hardstyle, cyberpunk\nelectro house, hardstyle, glitch\nelectro house, hardstyle, hip-hop\nelectro house, hardstyle, hyperpop\nelectro house, hardstyle, novelty\nelectro house, hardstyle, speedcore\nelectro house, hardstyle, synth-pop\nelectro house, hardstyle, trap\nelectro house, hip-hop, Indian pop\nelectro house, hip-hop, hardstyle\nelectro house, hyper-pop, chiptune\nelectro house, hyperpop\nelectro house, hyperpop, Bollywood\nelectro house, hyperpop, J-core\nelectro house, hyperpop, chiptune\nelectro house, hyperpop, dancehall\nelectro house, hyperpop, happy hardcore\nelectro house, hyperpop, hardstyle\nelectro house, hyperpop, nightcore\nelectro house, moombahton, Latin\nelectro house, moombahton, hyperpop\nelectro house, nu-disco, big room\nelectro house, pop-dance, rock\nelectro house, pop-rap, world music\nelectro house, progressive house, big room\nelectro house, psytrance\nelectro house, psytrance, hardstyle\nelectro house, reggaeton\nelectro house, reggaeton, Latin\nelectro house, synthwave\nelectro house, tiradera\nelectro house, trance, chiptune\nelectro house, trance, hardstyle\nelectro house, vaporwave, melbourne bounce\nelectro jungle\nelectro klezmer\nelectro marching\nelectro merengue\nelectro metal\nelectro minimal wave\nelectro orchestral\nelectro percussion\nelectro polka\nelectro pop\nelectro pop rock\nelectro pop, chiptune, Turkish pop\nelectro pop, dance, Latin trap\nelectro pop, hip-hop\nelectro pop, reggaeton, dance\nelectro punk\nelectro rap\nelectro rap, lo-fi hip hop\nelectro rap-metal\nelectro reggae\nelectro retro\nelectro rock\nelectro samba\nelectro soul\nelectro swing\nelectro synth\nelectro synth-pop\nelectro synthwave\nelectro synthwave chiptune\nelectro synthwave hip-hop\nelectro tango\nelectro tech house\nelectro techno\nelectro techno chiptune\nelectro techno funk\nelectro techno house\nelectro trance\nelectro trap chiptune\nelectro tribal\nelectro violin\nelectro world\nelectro worldbeat\nelectro, 8-bit, chiptune\nelectro, 80s synth-pop, early house\nelectro, Arabic hip hop, synthwave\nelectro, EBM\nelectro, EBM, Italo disco\nelectro, EBM, acid techno\nelectro, EBM, cinematic\nelectro, EBM, experimental\nelectro, EBM, hip-hop\nelectro, EBM, industrial\nelectro, EBM, industrial dance\nelectro, EBM, retro\nelectro, EBM, retro-futuristic\nelectro, EBM, synth-pop\nelectro, EBM, techno\nelectro, EBM, video game music\nelectro, French cold wave, chiptune\nelectro, German hip-hop, chiptune\nelectro, Italo disco, house\nelectro, Italo disco, retro synth\nelectro, Japanese arcade, rhythm game\nelectro, Latin rap, acid house\nelectro, Middle Eastern fusion\nelectro, Middle Eastern, industrial\nelectro, Russian, industrial\nelectro, UK hip-hop, EBM\nelectro, acid house, Nintendocore\nelectro, aggressive, Middle Eastern fusion\nelectro, aggro, African techno\nelectro, ambient, EBM\nelectro, ambient, drum and bass\nelectro, ambient, experimental\nelectro, ambient, minimal\nelectro, ambient, video game\nelectro, belly dance, Middle Eastern\nelectro, chiptune\nelectro, chiptune, 8-bit\nelectro, chiptune, Chinese electronic\nelectro, chiptune, French vocal\nelectro, chiptune, IDM\nelectro, chiptune, Latin trap\nelectro, chiptune, Mandarin hip hop\nelectro, chiptune, Middle Eastern\nelectro, chiptune, Spanish hip hop\nelectro, chiptune, acid\nelectro, chiptune, aggressive\nelectro, chiptune, ambient\nelectro, chiptune, bitpop\nelectro, chiptune, breakbeat\nelectro, chiptune, cyberpunk\nelectro, chiptune, demoscene\nelectro, chiptune, dubstep\nelectro, chiptune, educational\nelectro, chiptune, glitch\nelectro, chiptune, hardcore\nelectro, chiptune, industrial\nelectro, chiptune, lo-fi\nelectro, chiptune, multilingual hip-hop\nelectro, chiptune, neoclassical\nelectro, chiptune, political\nelectro, chiptune, rave\nelectro, chiptune, retro\nelectro, chiptune, retro-futuristic\nelectro, chiptune, techno\nelectro, chiptune, video game\nelectro, chiptune, video game music\nelectro, cinematic, Latin trap\nelectro, cinematic, ambient\nelectro, cinematic, chiptune\nelectro, cinematic, dark wave\nelectro, cinematic, lo-fi\nelectro, cinematic, synthwave\nelectro, cyberpunk, chiptune\nelectro, cyberpunk, complextro\nelectro, cyberpunk, industrial\nelectro, cyberpunk, rave\nelectro, cyberpunk, techno\nelectro, dancehall, hip-hop\nelectro, dark techno\nelectro, darkwave, synth-pop\nelectro, dubstep, chiptune\nelectro, dubstep, experimental\nelectro, dubstep, pop-punk\nelectro, dystopian, industrial\nelectro, futuristic, industrial\nelectro, gabber, chiptune\nelectro, glitch, complextro\nelectro, glitch, hyperpop\nelectro, glitch, lo-fi hip hop\nelectro, hardstyle, chiptune\nelectro, hardstyle, complextro\nelectro, hyperpop, lo-fi\nelectro, industrial, Latin electronic\nelectro, industrial, Russian rap\nelectro, industrial, South African house\nelectro, lo-fi hip hop, Thai rap\nelectro, lo-fi hip hop, chiptune\nelectro, lo-fi, chiptune\nelectro, lo-fi, coldwave\nelectro, lo-fi, ritualistic\nelectro, minimal wave\nelectro, rave, Polish hip hop\nelectro, rave, Russian techno\nelectro, retro wave, video game music\nelectro, retro-futuristic\nelectro, retro-futuristic, 80s synth\nelectro, retro-futuristic, 80s techno\nelectro, retro-futuristic, chiptune\nelectro, retro-futuristic, lo-fi\nelectro, retro-futuristic, synth-pop\nelectro, synth-funk, minimal house\nelectro, synth-pop\nelectro, synth-pop, EBM\nelectro, synth-pop, chiptune\nelectro, synth-pop, hip-hop\nelectro, synth-pop, house\nelectro, synth-pop, instrumental hip-hop\nelectro, synth-pop, minimal techno\nelectro, synth-pop, retro\nelectro, synth-pop, retro-futuristic\nelectro, synth-pop, video game music\nelectro, synthwave, 80s revival\nelectro, synthwave, EBM\nelectro, synthwave, Estonian rap\nelectro, synthwave, K-electro\nelectro, synthwave, electroclash\nelectro, synthwave, industrial\nelectro, synthwave, video game music\nelectro, tech house, hip-hop\nelectro, techno, early hip-hop\nelectro, techno, hip-hop\nelectro, trap, Spanish rap\nelectro, trap, chiptune\nelectro, tribal house\nelectro, vaporwave, retro-futuristic\nelectro, video game, ambient\nelectro-Bhangra\nelectro-Bhojpuri\nelectro-Bollywood\nelectro-Latin\nelectro-R&B\nelectro-Raï\nelectro-acoustic\nelectro-baroque\nelectro-berber\nelectro-bhajan\nelectro-bhangra\nelectro-bossa\nelectro-brega\nelectro-chaabi\nelectro-chaanga\nelectro-chanson\nelectro-classical\nelectro-classical hip-hop\nelectro-club\nelectro-club satire\nelectro-country\nelectro-cumbia\nelectro-cumbia chiptune\nelectro-cumbia moombahton\nelectro-cumbia reggaeton\nelectro-cumbia, hyperpop\nelectro-dabke\nelectro-dance\nelectro-dance chiptune funk\nelectro-dance chiptune funk carioca\nelectro-dance dembow\nelectro-dance funk chiptune\nelectro-dance reggaeton\nelectro-dance, Indian pop\nelectro-dance, hyperpop, chiptune\nelectro-dancehall\nelectro-dancehall chiptune\nelectro-dangdut\nelectro-dembow\nelectro-disco\nelectro-dub\nelectro-dubstep\nelectro-ethnic\nelectro-ethnic fusion\nelectro-folk\nelectro-folk chiptune\nelectro-folk dance-pop\nelectro-folk disco\nelectro-folk fusion\nelectro-folk hip-hop\nelectro-folk house\nelectro-folk klezmer\nelectro-folk pop\nelectro-folk, Balkan house, electronic dance\nelectro-folk, world pop, Balkan fusion\nelectro-folk-pop\nelectro-funk\nelectro-funk J-pop anime\nelectro-funk R&B\nelectro-funk acid jazz\nelectro-funk big beat\nelectro-funk boogie\nelectro-funk breakbeat\nelectro-funk chiptune\nelectro-funk comedy rap\nelectro-funk complextro\nelectro-funk cyberpunk\nelectro-funk dancehall\nelectro-funk dancehall hip-hop\nelectro-funk darkwave\nelectro-funk dubstep\nelectro-funk future bass\nelectro-funk glitch-hop\nelectro-funk glitch-pop\nelectro-funk hip-hop\nelectro-funk hip-house\nelectro-funk house\nelectro-funk hyperpop\nelectro-funk industrial rock\nelectro-funk lo-fi\nelectro-funk new jack swing\nelectro-funk nu-disco\nelectro-funk nu-disco chiptune\nelectro-funk nu-disco complextro\nelectro-funk ragga\nelectro-funk rap\nelectro-funk rock\nelectro-funk space-disco\nelectro-funk synth-pop\nelectro-funk tech-house\nelectro-funk vaporwave\nelectro-funk, 80s hip-hop, retro\nelectro-funk, 80s, filmi\nelectro-funk, Arabic pop\nelectro-funk, Balkan fusion\nelectro-funk, Balkan fusion, Middle Eastern dance\nelectro-funk, Balkan fusion, Middle Eastern electronic\nelectro-funk, EBM, synth-punk\nelectro-funk, French touch, chiptune\nelectro-funk, G-funk, West Coast\nelectro-funk, G-funk, synthwave\nelectro-funk, Latin urban\nelectro-funk, Middle Eastern fusion, electronic\nelectro-funk, Middle Eastern, Turkish\nelectro-funk, Neue Deutsche Welle\nelectro-funk, North African pop\nelectro-funk, Russian folk, pop\nelectro-funk, South Asian pop\nelectro-funk, South Indian film music\nelectro-funk, Turkish pop, dance\nelectro-funk, alternative R&B, experimental electronic\nelectro-funk, brostep, Brazilian\nelectro-funk, chiptune, 8-bit\nelectro-funk, chiptune, Bollywood\nelectro-funk, chiptune, Brazilian funk\nelectro-funk, chiptune, J-pop\nelectro-funk, chiptune, R&B\nelectro-funk, chiptune, ambient\nelectro-funk, chiptune, complextro\nelectro-funk, chiptune, retro-futuristic\nelectro-funk, chiptune, synthwave\nelectro-funk, chiptune, video game\nelectro-funk, chiptune, video game music\nelectro-funk, chiptune, worldbeat\nelectro-funk, cinematic, Kollywood\nelectro-funk, cinematic, retro-futuristic\nelectro-funk, city pop\nelectro-funk, city pop, video game music\nelectro-funk, complextro, C-pop\nelectro-funk, cyberpunk, spy-thriller\nelectro-funk, dancehall, hip-hop\nelectro-funk, digital hardcore\nelectro-funk, early hip-hop\nelectro-funk, hip-hop\nelectro-funk, hyperpop\nelectro-funk, hyperpop, sci-fi disco\nelectro-funk, hyperpop, video game\nelectro-funk, industrial metal, reggae\nelectro-funk, neo-soul\nelectro-funk, neo-soul, hip-hop\nelectro-funk, new jack swing\nelectro-funk, new jack swing, chiptune\nelectro-funk, nu-disco, city pop\nelectro-funk, nu-disco, synth-pop\nelectro-funk, reggaeton\nelectro-funk, synth-pop\nelectro-funk, synth-pop, electroclash\nelectro-funk, trot, chiptune\nelectro-funk, video game music, 80s synth\nelectro-funk, video game soundtrack, psychedelic rock\nelectro-fusion\nelectro-gaana\nelectro-gospel\nelectro-hip hop\nelectro-hip-hop\nelectro-hop\nelectro-hop chiptune\nelectro-house\nelectro-house C-pop\nelectro-house J-pop\nelectro-house K-pop\nelectro-house K-pop chiptune\nelectro-house Latin\nelectro-house bhangra\nelectro-house big room\nelectro-house bluegrass\nelectro-house chiptune\nelectro-house chiptune J-core\nelectro-house chiptune bollywood\nelectro-house chiptune breakbeat\nelectro-house chiptune eurodance\nelectro-house chiptune funk\nelectro-house chiptune synth-pop\nelectro-house chiptune synthwave\nelectro-house cinematic\nelectro-house dance-pop\nelectro-house french rap\nelectro-house funk\nelectro-house funkot\nelectro-house hip-hop\nelectro-house hip-house\nelectro-house hyperpop\nelectro-house hyperpop nightcore\nelectro-house hǎnmài\nelectro-house j-core happy hardcore\nelectro-house j-pop\nelectro-house j-pop chiptune\nelectro-house j-pop video game\nelectro-house k-pop\nelectro-house latin\nelectro-house latin pop\nelectro-house latin urban\nelectro-house lo-fi\nelectro-house moombahton\nelectro-house novelty\nelectro-house nu-disco\nelectro-house pop\nelectro-house pop-punk\nelectro-house pop-rock\nelectro-house synth-pop\nelectro-house synthwave\nelectro-house tech house\nelectro-house uk garage\nelectro-house v-pop\nelectro-house, Cantopop, hip hop\nelectro-house, Latin house\nelectro-house, Latin house, tribal house\nelectro-house, Latin pop, reggaeton\nelectro-house, Latin, reggaeton\nelectro-house, Middle Eastern, Balkan\nelectro-house, Thai hip-hop\nelectro-house, West Coast hip-hop\nelectro-house, chiptune, French touch\nelectro-house, chiptune, complextro\nelectro-house, cinematic, Chinese pop\nelectro-house, cinematic, operatic\nelectro-house, gypsy jazz, Balkan house\nelectro-house, hardstyle, bilingual\nelectro-house, hardstyle, gabber\nelectro-house, hardstyle, meme music\nelectro-house, hip-house, chiptune\nelectro-house, oriental, Middle Eastern\nelectro-house, tech-house, cinematic\nelectro-industrial\nelectro-industrial EBM\nelectro-industrial chiptune\nelectro-industrial glitch-hop\nelectro-industrial lo-fi\nelectro-industrial, Bhangra EDM, Indian folk\nelectro-jazz\nelectro-jazz-funk\nelectro-klezmer\nelectro-latin\nelectro-mambo\nelectro-merengue\nelectro-mor Lam\nelectro-mor lam\nelectro-oriental\nelectro-oud\nelectro-oud fusion\nelectro-polka\nelectro-pop\nelectro-pop 80s new wave\nelectro-pop 80s synth-pop\nelectro-pop 90s dance\nelectro-pop Bollywood\nelectro-pop C-pop\nelectro-pop C-pop EDM\nelectro-pop C-pop Eurodance\nelectro-pop C-pop J-pop\nelectro-pop C-pop anime\nelectro-pop Christmas\nelectro-pop EBM\nelectro-pop EBM chiptune\nelectro-pop EDM\nelectro-pop French house\nelectro-pop French-pop\nelectro-pop German hip-hop\nelectro-pop J-core\nelectro-pop J-pop\nelectro-pop J-pop anime\nelectro-pop J-pop chiptune\nelectro-pop K-Pop\nelectro-pop K-hip-hop\nelectro-pop K-pop\nelectro-pop K-pop chiptune\nelectro-pop Latin\nelectro-pop Latin dancehall\nelectro-pop Latin house\nelectro-pop R&B\nelectro-pop Tamil pop\nelectro-pop alternative rock\nelectro-pop ambient\nelectro-pop anime\nelectro-pop bhangra\nelectro-pop bhangra bollywood\nelectro-pop big beat\nelectro-pop big room\nelectro-pop big room house\nelectro-pop brostep\nelectro-pop cabaret\nelectro-pop chalga\nelectro-pop chiptune\nelectro-pop chiptune Arabic children's\nelectro-pop chiptune Bollywood\nelectro-pop chiptune C-pop\nelectro-pop chiptune J-pop\nelectro-pop chiptune K-pop\nelectro-pop chiptune Latin\nelectro-pop chiptune Latin pop\nelectro-pop chiptune R&B\nelectro-pop chiptune Tamil pop\nelectro-pop chiptune bollywood\nelectro-pop chiptune cinematic\nelectro-pop chiptune complextro\nelectro-pop chiptune dancehall\nelectro-pop chiptune eurodance\nelectro-pop chiptune funk\nelectro-pop chiptune future bass\nelectro-pop chiptune happy hardcore\nelectro-pop chiptune hip-hop\nelectro-pop chiptune lo-fi\nelectro-pop chiptune novelty\nelectro-pop chiptune polka\nelectro-pop chiptune reggaeton\nelectro-pop chiptune retro-futuristic\nelectro-pop chiptune schlager\nelectro-pop chiptune synth-pop\nelectro-pop chiptune synthwave\nelectro-pop chiptune trap\nelectro-pop cinematic\nelectro-pop cinematic pop\nelectro-pop city pop Shibuya-kei\nelectro-pop complextro\nelectro-pop cumbia\nelectro-pop cyberpunk\nelectro-pop dance\nelectro-pop dance-pop\nelectro-pop dancehall\nelectro-pop dark cabaret\nelectro-pop dark pop Latin electronic\nelectro-pop darkwave\nelectro-pop deep house\nelectro-pop dembow\nelectro-pop dubstep\nelectro-pop funk\nelectro-pop future bass\nelectro-pop future bass J-pop\nelectro-pop future bass funk\nelectro-pop future bass hip-hop\nelectro-pop future bass hyperpop\nelectro-pop future bass synth-pop\nelectro-pop future bass trap\nelectro-pop future funk city pop\nelectro-pop future house\nelectro-pop glam rock\nelectro-pop glam-rock\nelectro-pop glitch-pop\nelectro-pop gospel\nelectro-pop gospel EDM\nelectro-pop hardstyle\nelectro-pop hip hop\nelectro-pop hip-hop\nelectro-pop hip-hop R&B\nelectro-pop hip-hop chiptune\nelectro-pop hip-hop dancehall\nelectro-pop hip-house\nelectro-pop house\nelectro-pop hyperpop\nelectro-pop hyperpop J-pop\nelectro-pop hyperpop chiptune\nelectro-pop hyperpop uk garage\nelectro-pop j-pop\nelectro-pop j-pop anime\nelectro-pop j-pop chiptune\nelectro-pop j-pop shibuya-kei\nelectro-pop kuthu\nelectro-pop lo-fi\nelectro-pop lounge\nelectro-pop lounge world music\nelectro-pop lounge-jazz\nelectro-pop moombahton\nelectro-pop moombahton dancehall\nelectro-pop moombahton reggaeton\nelectro-pop moombahton trap\nelectro-pop neo-soul\nelectro-pop nightcore\nelectro-pop nu-disco\nelectro-pop nu-disco funk\nelectro-pop pirate\nelectro-pop rap-rock\nelectro-pop reggaeton\nelectro-pop rock\nelectro-pop satire\nelectro-pop soul\nelectro-pop synth-pop\nelectro-pop synthwave\nelectro-pop synthwave French house\nelectro-pop tech house\nelectro-pop tech-house\nelectro-pop trap\nelectro-pop trap dancehall\nelectro-pop trap hardstyle\nelectro-pop trap hyperpop\nelectro-pop tribal\nelectro-pop tropical\nelectro-pop tropical house\nelectro-pop vaporwave\nelectro-pop vaporwave psychedelic\nelectro-pop villain\nelectro-pop vogue house\nelectro-pop worldbeat\nelectro-pop, 90s dance, Cantopop\nelectro-pop, Arabic pop, modern belly dance\nelectro-pop, Balkan brass\nelectro-pop, Balkan folk, cinematic\nelectro-pop, Balkan pop\nelectro-pop, Balkan pop, Dutch House\nelectro-pop, Balkan, video game\nelectro-pop, Bollywood\nelectro-pop, Bollywood pop, synth-pop\nelectro-pop, Bollywood, EDM\nelectro-pop, Bollywood, South Asian\nelectro-pop, Bollywood, dance-pop\nelectro-pop, Brazilian funk, hyperpop\nelectro-pop, Central Asian\nelectro-pop, EBM, chiptune\nelectro-pop, EBM, darkwave\nelectro-pop, EBM, industrial dance\nelectro-pop, EBM, synth-pop\nelectro-pop, EBM, techno\nelectro-pop, EDM, Bollywood\nelectro-pop, EDM, French rap\nelectro-pop, EDM, chiptune\nelectro-pop, EDM, cinematic\nelectro-pop, European folk, C-pop\nelectro-pop, French coldwave\nelectro-pop, French house, synth-pop\nelectro-pop, French new wave\nelectro-pop, German party, hyperpop\nelectro-pop, German synth-pop\nelectro-pop, Italo-disco\nelectro-pop, Italo-disco, nu-disco\nelectro-pop, J-core\nelectro-pop, J-core, complextro\nelectro-pop, J-core, gaming music\nelectro-pop, J-pop, anime\nelectro-pop, J-pop, chiptune\nelectro-pop, J-pop, cyberpunk\nelectro-pop, J-pop, electroclash\nelectro-pop, J-pop, happy hardcore\nelectro-pop, J-pop, hardstyle\nelectro-pop, J-pop, hyperpop\nelectro-pop, J-pop, nightcore\nelectro-pop, K-pop, Eurodance\nelectro-pop, K-pop, chiptune\nelectro-pop, K-pop, future funk\nelectro-pop, K-pop, hyperpop\nelectro-pop, K-pop, nu-disco\nelectro-pop, K-pop, synth-pop\nelectro-pop, K-pop, trap\nelectro-pop, Kollywood, cyberpunk\nelectro-pop, Latin dance\nelectro-pop, Latin dance, futuristic\nelectro-pop, Latin hyperpop\nelectro-pop, Mahraganat, Arabic dance\nelectro-pop, Middle Eastern fusion\nelectro-pop, Middle Eastern pop, reggae-pop\nelectro-pop, Middle Eastern, Balkan\nelectro-pop, Middle Eastern, Bollywood\nelectro-pop, Middle Eastern, Eastern European\nelectro-pop, Middle Eastern, Turkish\nelectro-pop, Middle Eastern, dance\nelectro-pop, Neue Deutsche Welle\nelectro-pop, North African, anthemic\nelectro-pop, R&B, chiptune\nelectro-pop, South Asian fusion\nelectro-pop, T-pop, hyperpop\nelectro-pop, UK garage, chiptune\nelectro-pop, UK garage, grime\nelectro-pop, ambient, trance\nelectro-pop, bass house\nelectro-pop, big room EDM\nelectro-pop, big room house\nelectro-pop, big room house, trance\nelectro-pop, breakcore, gabber\nelectro-pop, brostep, ambient\nelectro-pop, brostep, dubstep\nelectro-pop, chalga, Balkan\nelectro-pop, chalga, Balkan pop\nelectro-pop, chiptune, Balkan brass\nelectro-pop, chiptune, Greek rap\nelectro-pop, chiptune, J-core\nelectro-pop, chiptune, J-pop\nelectro-pop, chiptune, J-rock\nelectro-pop, chiptune, K-pop\nelectro-pop, chiptune, Nintendocore\nelectro-pop, chiptune, Persian pop\nelectro-pop, chiptune, Russian folk\nelectro-pop, chiptune, South Asian\nelectro-pop, chiptune, Tamil\nelectro-pop, chiptune, Thai pop\nelectro-pop, chiptune, cinematic\nelectro-pop, chiptune, cyberpunk\nelectro-pop, chiptune, future bass\nelectro-pop, chiptune, happy hardcore\nelectro-pop, chiptune, hyperpop\nelectro-pop, chiptune, lo-fi\nelectro-pop, chiptune, nu-disco\nelectro-pop, chiptune, rave\nelectro-pop, chiptune, retro-futuristic\nelectro-pop, chiptune, synth-pop\nelectro-pop, chiptune, trap\nelectro-pop, cinematic, Chinese EDM\nelectro-pop, cinematic, EDM\nelectro-pop, cinematic, hip-hop\nelectro-pop, cinematic, orchestral\nelectro-pop, complextro, ambient\nelectro-pop, complextro, chiptune\nelectro-pop, complextro, hardstyle\nelectro-pop, cyberpunk, K-pop\nelectro-pop, dance, C-pop\nelectro-pop, dance-pop, French rap\nelectro-pop, dance-pop, electroclash\nelectro-pop, dance-pop, hyperpop\nelectro-pop, dancehall, Balkan\nelectro-pop, dark wave, metalcore\nelectro-pop, darkwave, EBM\nelectro-pop, death metal\nelectro-pop, devotional, South Indian\nelectro-pop, dubstep\nelectro-pop, eurodance, hyperpop\nelectro-pop, folk fusion\nelectro-pop, funk, Middle Eastern\nelectro-pop, future bass, J-core\nelectro-pop, future bass, ambient\nelectro-pop, future bass, chiptune\nelectro-pop, gospel, chiptune\nelectro-pop, happy hardcore, cabaret\nelectro-pop, hard dance, chiptune\nelectro-pop, hard rock\nelectro-pop, hardstyle\nelectro-pop, hardstyle, Bollywood\nelectro-pop, hardstyle, Eurodance\nelectro-pop, hardstyle, French rap\nelectro-pop, hardstyle, Vietnamese pop\nelectro-pop, hardstyle, chiptune\nelectro-pop, hardstyle, cinematic\nelectro-pop, hardstyle, cyberpunk\nelectro-pop, hardstyle, dubstep\nelectro-pop, hardstyle, hyperpop\nelectro-pop, hip-hop, chiptune\nelectro-pop, hip-hop, hyperpop\nelectro-pop, hip-house\nelectro-pop, hip-house, dance-pop\nelectro-pop, hip-house, funk\nelectro-pop, hip-house, hyperpop\nelectro-pop, house, hyperpop\nelectro-pop, hyper-pop\nelectro-pop, hyperpop\nelectro-pop, hyperpop, 80s synth-pop\nelectro-pop, hyperpop, Balkan\nelectro-pop, hyperpop, Balkan pop\nelectro-pop, hyperpop, Bollywood\nelectro-pop, hyperpop, Chinese pop\nelectro-pop, hyperpop, EBM\nelectro-pop, hyperpop, EDM\nelectro-pop, hyperpop, J-core\nelectro-pop, hyperpop, J-pop\nelectro-pop, hyperpop, K-pop\nelectro-pop, hyperpop, Latin pop\nelectro-pop, hyperpop, T-pop\nelectro-pop, hyperpop, ambient\nelectro-pop, hyperpop, cabaret\nelectro-pop, hyperpop, chiptune\nelectro-pop, hyperpop, cinematic\nelectro-pop, hyperpop, dance-punk\nelectro-pop, hyperpop, dark pop\nelectro-pop, hyperpop, dream pop\nelectro-pop, hyperpop, electronic rock\nelectro-pop, hyperpop, future bass\nelectro-pop, hyperpop, glitch-pop\nelectro-pop, hyperpop, hip-hop\nelectro-pop, hyperpop, industrial dance\nelectro-pop, hyperpop, synth-pop\nelectro-pop, hyperpop, synthwave\nelectro-pop, hyperpop, theatrical\nelectro-pop, hyperpop, trap\nelectro-pop, industrial, Latin-influenced\nelectro-pop, kuthu, video game\nelectro-pop, lo-fi, French pop\nelectro-pop, lo-fi, hyperpop\nelectro-pop, modern Bhangra\nelectro-pop, musical theater\nelectro-pop, musical theater, cinematic\nelectro-pop, new wave, industrial\nelectro-pop, nightcore, happy hardcore\nelectro-pop, nu-disco\nelectro-pop, nu-metal\nelectro-pop, pop-rock, dubstep\nelectro-pop, pop-rock, hardstyle\nelectro-pop, reggaeton\nelectro-pop, reggaeton, Latin\nelectro-pop, reggaeton, dance\nelectro-pop, reggaeton, hyperpop\nelectro-pop, reggaeton, moombahton\nelectro-pop, shoegaze, hyperpop\nelectro-pop, synth-pop, French pop\nelectro-pop, synth-pop, alternative R&B\nelectro-pop, synth-pop, electroclash\nelectro-pop, synth-pop, funk\nelectro-pop, synth-pop, minimal wave\nelectro-pop, synth-punk\nelectro-pop, synth-rock, R&B\nelectro-pop, tech house, Russian pop\nelectro-pop, tech-house, cinematic\nelectro-pop, theatrical, musical theater\nelectro-pop, theatrical, villain theme\nelectro-pop, trap, Balkan\nelectro-pop, trap, chiptune\nelectro-pop, trap, cinematic\nelectro-pop, trap, hyperpop\nelectro-pop, world music, Balkan brass\nelectro-pop, worldbeat, chiptune\nelectro-punk\nelectro-punk chiptune\nelectro-punk digital hardcore\nelectro-punk funk\nelectro-punk garage rock\nelectro-punk hyperpop\nelectro-punk industrial\nelectro-punk, EBM, Balkan rap\nelectro-punk, big beat, alternative hip-hop\nelectro-punk, brostep\nelectro-punk, hip-hop, C-pop\nelectro-punk, hyperpop\nelectro-raggada\nelectro-rap\nelectro-rap lo-fi\nelectro-rap metalcore\nelectro-rap, EBM, punk hip-hop\nelectro-rap, chiptune, synthwave\nelectro-rap, lo-fi techno, EBM\nelectro-reggae\nelectro-reggaeton\nelectro-rock\nelectro-rock big room\nelectro-rock chiptune\nelectro-rock chiptune Latin\nelectro-rock complextro\nelectro-rock cyberpunk\nelectro-rock dance-pop\nelectro-rock dance-punk\nelectro-rock digital hardcore\nelectro-rock dubstep\nelectro-rock folk-dance\nelectro-rock funk\nelectro-rock future bass\nelectro-rock hip-hop\nelectro-rock hyperpop\nelectro-rock industrial\nelectro-rock industrial metal\nelectro-rock nu-metal\nelectro-rock party rap\nelectro-rock pop-punk\nelectro-rock, EDM, hip-hop\nelectro-rock, dubstep, Christian hip-hop\nelectro-rock, hyperpop, industrial metal\nelectro-rock, nu-metal, chiptune\nelectro-rock, synth-punk, dance-punk\nelectro-romani\nelectro-salsa\nelectro-schlager\nelectro-sertanejo\nelectro-shaabi\nelectro-ska\nelectro-ska balkan house\nelectro-ska big beat\nelectro-soca\nelectro-soul\nelectro-swing\nelectro-swing Balkan folk\nelectro-swing C-pop chiptune\nelectro-swing French house\nelectro-swing J-pop\nelectro-swing J-pop anime\nelectro-swing K-pop\nelectro-swing Latin\nelectro-swing big band\nelectro-swing big band house\nelectro-swing big beat\nelectro-swing big beat chiptune\nelectro-swing big room house\nelectro-swing bluegrass\nelectro-swing boogie-woogie\nelectro-swing breakbeat\nelectro-swing breakcore\nelectro-swing cabaret\nelectro-swing cabaret folk\nelectro-swing chiptune\nelectro-swing chiptune gypsy jazz\nelectro-swing chiptune rock\nelectro-swing city pop\nelectro-swing complextro\nelectro-swing dark cabaret\nelectro-swing dubstep\nelectro-swing funk\nelectro-swing funk breakbeat\nelectro-swing funk rock\nelectro-swing funk-pop\nelectro-swing funk-rap\nelectro-swing funk-rock\nelectro-swing glitch-hop\nelectro-swing glitch-hop jazz fusion\nelectro-swing gypsy jazz\nelectro-swing gypsy jazz steampunk\nelectro-swing happy hardcore\nelectro-swing hard dance\nelectro-swing hardstyle\nelectro-swing hip-hop\nelectro-swing house\nelectro-swing hyperpop\nelectro-swing industrial metal\nelectro-swing j-pop\nelectro-swing j-pop anime\nelectro-swing jazz fusion\nelectro-swing klezmer\nelectro-swing latin\nelectro-swing lo-fi\nelectro-swing noir-jazz\nelectro-swing novelty pop\nelectro-swing nu-disco\nelectro-swing nu-jazz\nelectro-swing punk rock\nelectro-swing rap-rock\nelectro-swing show tune\nelectro-swing steampunk\nelectro-swing surf rock\nelectro-swing theatrical rock\nelectro-swing trap\nelectro-swing, Balkan beat, gothic\nelectro-swing, Balkan brass\nelectro-swing, Balkan folk, art pop\nelectro-swing, Balkan folk, dance\nelectro-swing, Balkan house\nelectro-swing, Balkan house, French rap\nelectro-swing, Balkan house, hard dance\nelectro-swing, J-core, video game\nelectro-swing, J-pop, anime\nelectro-swing, J-pop, big band jazz\nelectro-swing, J-pop, chiptune\nelectro-swing, J-pop, city pop\nelectro-swing, J-pop, hyperpop\nelectro-swing, J-pop, video game music\nelectro-swing, J-rock\nelectro-swing, K-hip-hop\nelectro-swing, Latin house, funk\nelectro-swing, Latin house, nu-disco\nelectro-swing, Soviet-era, theatrical\nelectro-swing, chiptune, J-pop\nelectro-swing, chiptune, K-pop\nelectro-swing, chiptune, big band\nelectro-swing, chiptune, dance-pop\nelectro-swing, chiptune, video game\nelectro-swing, chiptune, video game music\nelectro-swing, complextro, dubstep\nelectro-swing, dubstep, comedy rap\nelectro-swing, hardstyle, cinematic\nelectro-swing, hip-hop, steampunk\nelectro-swing, house, hip-hop\nelectro-swing, hyperpop\nelectro-swing, klezmer, glitch\nelectro-swing, noir-pop, theatrical\nelectro-swing, spy-rock\nelectro-swing, synth-pop, theatrical\nelectro-swing, theatrical pop\nelectro-swing, theatrical, rock\nelectro-swing, video game music\nelectro-synth\nelectro-tango\nelectro-tango, EDM\nelectro-techno\nelectro-trance\nelectro-trap\nelectro-trap chiptune\nelectro-trap, chiptune, cinematic hip hop\nelectro-tribal\nelectro-trot\nelectro-vallenato\nelectro-western\nelectroclash\nelectroclash chiptune\nelectroclash dark pop\nelectroclash hyperpop\nelectroclash lo-fi\nelectroclash minimal wave\nelectroclash, German techno\nelectroclash, breakcore, synth-pop\nelectroclash, chiptune, aggressive electro\nelectroclash, chiptune, punk\nelectroclash, dark pop\nelectroclash, dream pop\nelectroclash, hard techno\nelectroclash, hardstyle, gabber\nelectroclash, hyperpop\nelectroclash, hyperpop, ballroom\nelectroclash, hyperpop, dance-pop\nelectroclash, hyperpop, dance-punk\nelectroclash, hyperpop, gabber\nelectroclash, hyperpop, glitch\nelectroclash, hyperpop, lo-fi\nelectroclash, hyperpop, rave\nelectroclash, hyperpop, retro-futuristic\nelectroclash, hyperpop, techno-pop\nelectroclash, industrial dance\nelectroclash, industrial techno\nelectroclash, industrial, EBM\nelectroclash, industrial, dark pop\nelectroclash, synth-punk\nelectroclash, tech house\nelectroclash, techno-pop, hyperpop\nelectrofunk\nelectrofunk chiptune\nelectromambo\nelectronic\nelectronic Arabic\nelectronic Arabic fusion\nelectronic Arabic pop\nelectronic Arabic protest\nelectronic Balkan fusion\nelectronic Bhangra\nelectronic Bhojpuri\nelectronic Bollywood\nelectronic C-pop\nelectronic C-pop hip-hop\nelectronic Carnatic\nelectronic Christian\nelectronic Christian folk-pop\nelectronic Christian pop\nelectronic Christian, Bollywood dance\nelectronic Christmas\nelectronic Dabke\nelectronic Dangdut Koplo\nelectronic French pop\nelectronic Greek fusion\nelectronic IDM\nelectronic Indian\nelectronic Indian ballad\nelectronic Indian classical\nelectronic Indian dance\nelectronic Indian devotional\nelectronic Indian film\nelectronic Indian film music\nelectronic Indian folk\nelectronic Indian fusion\nelectronic Indian political\nelectronic Indian pop\nelectronic Indian protest\nelectronic Islamic devotional\nelectronic Islamic pop\nelectronic J-pop\nelectronic J-pop trap\nelectronic Javanese\nelectronic K-pop\nelectronic Latin\nelectronic Mizrahi\nelectronic Mongolian folk\nelectronic North African\nelectronic North African folk\nelectronic North African pop\nelectronic Punjabi\nelectronic R&B\nelectronic R&B future bass\nelectronic R&B pop\nelectronic R&B trap\nelectronic R&B trip-hop\nelectronic R&B, trap, world fusion\nelectronic Rai\nelectronic Raï\nelectronic Sufi\nelectronic Sufi fusion\nelectronic Tamil\nelectronic Tamil folk\nelectronic afrobeat\nelectronic alt-rock\nelectronic alternative\nelectronic alternative rock\nelectronic ambient\nelectronic anasheed\nelectronic anthem\nelectronic arabesque\nelectronic arabic\nelectronic arabic fusion\nelectronic arabic pop\nelectronic ballad\nelectronic banda\nelectronic baroque\nelectronic battle anthem\nelectronic belly dance\nelectronic bhajan\nelectronic bhangra\nelectronic bhojpuri\nelectronic big beat\nelectronic bluegrass\nelectronic blues\nelectronic blues-rock\nelectronic body music\nelectronic body music trance\nelectronic bollywood\nelectronic breakbeat\nelectronic breakbeat R&B\nelectronic brega\nelectronic carol\nelectronic cello\nelectronic chaabi\nelectronic children's\nelectronic children's music\nelectronic chiptune\nelectronic chiptune breakbeat\nelectronic chiptune cinematic\nelectronic chiptune cumbia\nelectronic choral\nelectronic chorale\nelectronic cinematic\nelectronic classical\nelectronic classical fusion\nelectronic club\nelectronic comedy\nelectronic country\nelectronic cumbia\nelectronic cumbia gospel\nelectronic cumbia villera\nelectronic cumbia, metalcore\nelectronic dabke\nelectronic dance\nelectronic dance C-pop\nelectronic dance music\nelectronic dance music Balkan folk\nelectronic dance music K-pop\nelectronic dance music hip-hop\nelectronic dance music phonk\nelectronic dance music world fusion\nelectronic dance music, Anatolian rock, psytrance\nelectronic dance music, Central Asian folk\nelectronic dance music, North African pop\nelectronic dance music, regional pop, hardstyle\nelectronic dance pop\nelectronic dance pop hip-hop\nelectronic dance rock\nelectronic dance, Arabic Mawwal\nelectronic dance, Arabic fusion\nelectronic dance, Arabic fusion, North African\nelectronic dance, Arabic fusion, cinematic\nelectronic dance, Arabic pop\nelectronic dance, Arabic pop, chiptune\nelectronic dance, Arabic pop, house\nelectronic dance, Arabic, Latin\nelectronic dance, Armenian folk\nelectronic dance, Armenian folk, fusion\nelectronic dance, Azerbaijani folk\nelectronic dance, Azerbaijani pop\nelectronic dance, Balkan brass, Middle Eastern fusion\nelectronic dance, Balkan folk\nelectronic dance, Balkan folk, Klezmer\nelectronic dance, Balkan folk, Middle Eastern\nelectronic dance, Balkan folk, cinematic\nelectronic dance, Balkan fusion\nelectronic dance, Balkan fusion, Hindi pop\nelectronic dance, Balkan fusion, Klezmer\nelectronic dance, Balkan fusion, Middle Eastern\nelectronic dance, Balkan house\nelectronic dance, Balkan pop\nelectronic dance, Balkan pop, reggaeton\nelectronic dance, Balkan, Latin\nelectronic dance, Balkan, Middle Eastern\nelectronic dance, Bengali fusion\nelectronic dance, Bengali pop, trance\nelectronic dance, Bhangra\nelectronic dance, Bhangra fusion\nelectronic dance, Bhangra, Bollywood\nelectronic dance, Bhangra, chiptune\nelectronic dance, Bhojpuri\nelectronic dance, Bhojpuri folk\nelectronic dance, Bhojpuri folk, chiptune\nelectronic dance, Bhojpuri folk, synthwave\nelectronic dance, Bhojpuri fusion\nelectronic dance, Bhojpuri, Bollywood\nelectronic dance, Bhojpuri, EDM\nelectronic dance, Bhojpuri, Indian folk\nelectronic dance, Bhojpuri, South Asian\nelectronic dance, Bhojpuri, South Asian fusion\nelectronic dance, Bhojpuri, chiptune\nelectronic dance, Bhojpuri, digital\nelectronic dance, Bhojpuri, folk fusion\nelectronic dance, Bhojpuri, high-energy\nelectronic dance, Bhojpuri, high-tempo\nelectronic dance, Bollywood\nelectronic dance, Bollywood fusion\nelectronic dance, Bollywood pop\nelectronic dance, Bollywood, Bhangra\nelectronic dance, Bollywood, Bhojpuri\nelectronic dance, Bollywood, EDM\nelectronic dance, Bollywood, Indian folk\nelectronic dance, Bollywood, South Asian\nelectronic dance, Bollywood, South Asian fusion\nelectronic dance, Bollywood, chiptune\nelectronic dance, Bollywood, devotional\nelectronic dance, Bollywood, high-energy\nelectronic dance, Bollywood, high-tempo\nelectronic dance, Bollywood, lo-fi\nelectronic dance, Bollywood, regional dance-pop\nelectronic dance, Bollywood, retro\nelectronic dance, C-pop, J-pop\nelectronic dance, C-pop, Tibetan pop\nelectronic dance, C-pop, cinematic\nelectronic dance, C-pop, fusion\nelectronic dance, C-pop, traditional fusion\nelectronic dance, Cantopop, synth-pop\nelectronic dance, Central Asian folk\nelectronic dance, Central Asian folk, C-pop\nelectronic dance, Central Asian folk, chiptune\nelectronic dance, Central Asian folk, fusion\nelectronic dance, Central Asian folk, modern fusion\nelectronic dance, Central Asian fusion\nelectronic dance, Central Asian pop\nelectronic dance, Chinese folk fusion\nelectronic dance, Chinese folk, EDM\nelectronic dance, Chinese folk, cinematic\nelectronic dance, Chinese folk, fusion\nelectronic dance, Chinese folk, high-energy\nelectronic dance, Chinese folk, hyperpop\nelectronic dance, Chinese folk, modern fusion\nelectronic dance, Chinese folk, synth\nelectronic dance, Chinese folk, upbeat\nelectronic dance, Chinese fusion\nelectronic dance, Chinese fusion, hardstyle\nelectronic dance, Chinese traditional, cinematic\nelectronic dance, Chinese traditional, modern\nelectronic dance, Dangdut Koplo, Funkot\nelectronic dance, East Asian folk\nelectronic dance, East Asian folk, modern fusion\nelectronic dance, East Asian folk, synth pop\nelectronic dance, East Asian fusion\nelectronic dance, East Asian, house\nelectronic dance, Eastern European, Middle Eastern\nelectronic dance, Gujarati folk\nelectronic dance, Gujarati folk, fusion\nelectronic dance, Gujarati fusion\nelectronic dance, Gujarati hip-hop\nelectronic dance, Haryanvi, Bhojpuri\nelectronic dance, Haryanvi, Gujarati\nelectronic dance, Haryanvi, North Indian\nelectronic dance, Haryanvi, folk fusion\nelectronic dance, Hindi trance\nelectronic dance, Hindu devotional, EDM\nelectronic dance, Iban pop, Sundanese pop\nelectronic dance, Indian Pahari, high-tempo\nelectronic dance, Indian devotional\nelectronic dance, Indian devotional, EDM\nelectronic dance, Indian devotional, chiptune\nelectronic dance, Indian devotional, dance-pop\nelectronic dance, Indian devotional, folk fusion\nelectronic dance, Indian devotional, high-tempo\nelectronic dance, Indian devotional, hyperpop\nelectronic dance, Indian devotional, synthwave\nelectronic dance, Indian devotional, trance\nelectronic dance, Indian devotional, tribal\nelectronic dance, Indian film music\nelectronic dance, Indian film music, fusion\nelectronic dance, Indian folk\nelectronic dance, Indian folk fusion\nelectronic dance, Indian folk, Bhojpuri\nelectronic dance, Indian folk, Bollywood\nelectronic dance, Indian folk, Bollywood pop\nelectronic dance, Indian folk, Chhattisgarh\nelectronic dance, Indian folk, EDM\nelectronic dance, Indian folk, bhajan\nelectronic dance, Indian folk, chiptune\nelectronic dance, Indian folk, cinematic\nelectronic dance, Indian folk, club\nelectronic dance, Indian folk, club remix\nelectronic dance, Indian folk, dance-pop\nelectronic dance, Indian folk, devotional\nelectronic dance, Indian folk, dhol\nelectronic dance, Indian folk, dholak\nelectronic dance, Indian folk, dubstep\nelectronic dance, Indian folk, fusion\nelectronic dance, Indian folk, high-energy\nelectronic dance, Indian folk, high-tempo\nelectronic dance, Indian folk, hyperpop\nelectronic dance, Indian folk, moombahton\nelectronic dance, Indian folk, party\nelectronic dance, Indian folk, political techno\nelectronic dance, Indian folk, rave\nelectronic dance, Indian folk, regional DJ\nelectronic dance, Indian folk, rock\nelectronic dance, Indian folk, synth pop\nelectronic dance, Indian folk, synthwave\nelectronic dance, Indian folk, upbeat\nelectronic dance, Indian fusion\nelectronic dance, Indian fusion, Gujarati\nelectronic dance, Indian fusion, Middle Eastern\nelectronic dance, Indian fusion, Pahari\nelectronic dance, Indian fusion, chiptune\nelectronic dance, Indian fusion, cinematic\nelectronic dance, Indian fusion, hyper-pop\nelectronic dance, Indian pahari\nelectronic dance, Indian party music\nelectronic dance, Indian party, EDM\nelectronic dance, Indian party, hard dance\nelectronic dance, Indian patriotic\nelectronic dance, Indian patriotic, devotional\nelectronic dance, Indian political anthem\nelectronic dance, Indian political, high-tempo\nelectronic dance, Indian political, rally\nelectronic dance, Indian pop\nelectronic dance, Indian pop, Bhangra\nelectronic dance, Indian pop, Bhojpuri\nelectronic dance, Indian pop, Latin pop\nelectronic dance, Indian pop, chiptune\nelectronic dance, Indian pop, hip-hop\nelectronic dance, Indian subregion, high-tempo\nelectronic dance, Indonesian pop\nelectronic dance, Italian folk\nelectronic dance, Italian folk, tarantella\nelectronic dance, J-pop\nelectronic dance, J-pop, anime\nelectronic dance, J-pop, nightcore\nelectronic dance, Javanese fusion\nelectronic dance, Javanese pop\nelectronic dance, Javanese pop, chiptune\nelectronic dance, Kannada folk\nelectronic dance, Kazakh folk\nelectronic dance, Kurdish folk\nelectronic dance, Kurdish folk, stadium anthem\nelectronic dance, Latin, Middle Eastern\nelectronic dance, Latin, chiptune\nelectronic dance, Latin, world music\nelectronic dance, Malay fusion\nelectronic dance, Malay pop\nelectronic dance, Malay pop, funk\nelectronic dance, Malay pop, trap\nelectronic dance, Malayalam folk, fusion\nelectronic dance, Malayalam folk, psytrance\nelectronic dance, Mandopop\nelectronic dance, Mandopop, nu-metal\nelectronic dance, Mediterranean folk, fusion\nelectronic dance, Mediterranean fusion\nelectronic dance, Middle Eastern club\nelectronic dance, Middle Eastern folk\nelectronic dance, Middle Eastern folk, South African folk\nelectronic dance, Middle Eastern folk, dance-pop\nelectronic dance, Middle Eastern folk, fusion\nelectronic dance, Middle Eastern fusion\nelectronic dance, Middle Eastern fusion, Balkan beats\nelectronic dance, Middle Eastern fusion, Italian folk\nelectronic dance, Middle Eastern fusion, Kurdish house\nelectronic dance, Middle Eastern fusion, South Asian fusion\nelectronic dance, Middle Eastern fusion, hardstyle\nelectronic dance, Middle Eastern fusion, rave\nelectronic dance, Middle Eastern fusion, rock\nelectronic dance, Middle Eastern house\nelectronic dance, Middle Eastern pop\nelectronic dance, Middle Eastern pop, Azerbaijani pop\nelectronic dance, Middle Eastern pop, Caucasian pop\nelectronic dance, Middle Eastern pop, Eastern European pop\nelectronic dance, Middle Eastern pop, Kurdish pop\nelectronic dance, Middle Eastern pop, Malay pop\nelectronic dance, Middle Eastern pop, Turkish pop\nelectronic dance, Middle Eastern pop-rock\nelectronic dance, Middle Eastern, Anatolian\nelectronic dance, Middle Eastern, Arabic\nelectronic dance, Middle Eastern, Arabic fusion\nelectronic dance, Middle Eastern, Arabic pop\nelectronic dance, Middle Eastern, Azerbaijani folk\nelectronic dance, Middle Eastern, Balkan\nelectronic dance, Middle Eastern, Bollywood\nelectronic dance, Middle Eastern, Central Asian\nelectronic dance, Middle Eastern, EDM\nelectronic dance, Middle Eastern, Eastern European\nelectronic dance, Middle Eastern, Islamic\nelectronic dance, Middle Eastern, Klezmer\nelectronic dance, Middle Eastern, Kurdish\nelectronic dance, Middle Eastern, Latin\nelectronic dance, Middle Eastern, North African\nelectronic dance, Middle Eastern, Persian\nelectronic dance, Middle Eastern, South Asian\nelectronic dance, Middle Eastern, Southeast Asian\nelectronic dance, Middle Eastern, Turkish\nelectronic dance, Middle Eastern, anthemic\nelectronic dance, Middle Eastern, chiptune\nelectronic dance, Middle Eastern, cinematic\nelectronic dance, Middle Eastern, house\nelectronic dance, Middle Eastern, pop\nelectronic dance, Middle Eastern, progressive house\nelectronic dance, Middle Eastern, remix\nelectronic dance, Middle Eastern, synth\nelectronic dance, Middle Eastern, synthwave\nelectronic dance, Middle Eastern, trance\nelectronic dance, Middle Eastern, zurna\nelectronic dance, Mizrahi, EDM\nelectronic dance, Mizrahi, Middle Eastern\nelectronic dance, Mizrahi, cinematic\nelectronic dance, Mizrahi, stadium anthem\nelectronic dance, Mongolian folk\nelectronic dance, Nepali folk\nelectronic dance, North African folk\nelectronic dance, North African folk, chiptune\nelectronic dance, North African folk, fusion\nelectronic dance, North African fusion\nelectronic dance, North African pop\nelectronic dance, North African pop, Latin fusion\nelectronic dance, North African pop, hip-hop\nelectronic dance, North African, Afro-house\nelectronic dance, North African, Arabic pop\nelectronic dance, North African, Middle Eastern\nelectronic dance, North African, South Asian\nelectronic dance, North African, high-energy\nelectronic dance, North African, live energy\nelectronic dance, North African, modern\nelectronic dance, North African, oriental\nelectronic dance, North African, synthwave\nelectronic dance, Pahari, South Asian\nelectronic dance, Pahari, South Asian fusion\nelectronic dance, Pahari, dholak\nelectronic dance, Pahari, festival\nelectronic dance, Pahari, festive\nelectronic dance, Pahari, high-energy\nelectronic dance, Pahari, high-tempo\nelectronic dance, Persian fusion\nelectronic dance, Persian pop\nelectronic dance, Persian, Middle Eastern\nelectronic dance, Portuguese novelty\nelectronic dance, Rai fusion\nelectronic dance, Rai, Chaabi\nelectronic dance, Rai, French pop\nelectronic dance, Rai, North African\nelectronic dance, Rai, backa\nelectronic dance, Rai, modern backa\nelectronic dance, Rai, modernizera\nelectronic dance, Romanian folk, party\nelectronic dance, Romanian party music\nelectronic dance, Romanian party, Balkan fusion\nelectronic dance, Sinhala folk\nelectronic dance, Sinhala folk, fusion\nelectronic dance, Sinhala folk, hyperpop\nelectronic dance, South African folk\nelectronic dance, South African folk, fusion\nelectronic dance, South Asian Christian\nelectronic dance, South Asian club\nelectronic dance, South Asian folk\nelectronic dance, South Asian folk, DJ remix\nelectronic dance, South Asian folk, EDM\nelectronic dance, South Asian folk, chiptune\nelectronic dance, South Asian folk, club\nelectronic dance, South Asian folk, dance-pop\nelectronic dance, South Asian folk, dhol\nelectronic dance, South Asian folk, dhol beat\nelectronic dance, South Asian folk, dholak\nelectronic dance, South Asian folk, festival\nelectronic dance, South Asian folk, fusion\nelectronic dance, South Asian folk, high-energy\nelectronic dance, South Asian folk, high-tempo\nelectronic dance, South Asian folk, hip-hop\nelectronic dance, South Asian folk, party\nelectronic dance, South Asian folk, synthpop\nelectronic dance, South Asian folk, synthwave\nelectronic dance, South Asian fusion\nelectronic dance, South Asian fusion, DJ remix\nelectronic dance, South Asian fusion, Middle Eastern\nelectronic dance, South Asian fusion, Middle Eastern EDM\nelectronic dance, South Asian fusion, Middle Eastern electronic\nelectronic dance, South Asian fusion, Middle Eastern pop\nelectronic dance, South Asian fusion, Middle Eastern synth\nelectronic dance, South Asian fusion, chiptune\nelectronic dance, South Asian party\nelectronic dance, South Asian pop\nelectronic dance, South Asian pop, Middle Eastern fusion\nelectronic dance, South Asian pop, chiptune\nelectronic dance, South Asian pop, moombahton\nelectronic dance, South Asian pop, video game music\nelectronic dance, South Asian, DJ\nelectronic dance, South Asian, Middle Eastern\nelectronic dance, South Asian, Pahari\nelectronic dance, South Asian, Sinhala\nelectronic dance, South Asian, Sufi\nelectronic dance, South Asian, club\nelectronic dance, South Asian, dance-pop\nelectronic dance, South Asian, happy hardcore\nelectronic dance, South Asian, high tempo\nelectronic dance, South Asian, high-tempo\nelectronic dance, South Asian, lo-fi\nelectronic dance, South Asian, party\nelectronic dance, South Asian, synthwave\nelectronic dance, South Indian cinematic\nelectronic dance, South Indian film music\nelectronic dance, South Indian film music, chiptune\nelectronic dance, South Indian filmi\nelectronic dance, South Indian folk\nelectronic dance, South Indian folk, EDM\nelectronic dance, South Indian folk, Pahari\nelectronic dance, South Indian folk, Tamil remix\nelectronic dance, South Indian folk, chiptune\nelectronic dance, South Indian folk, dholak\nelectronic dance, South Indian folk, high-energy\nelectronic dance, South Indian folk, high-tempo\nelectronic dance, South Indian fusion\nelectronic dance, South Indian pop\nelectronic dance, South Indian, EDM\nelectronic dance, South Indian, Eurodance\nelectronic dance, South Indian, Kannada\nelectronic dance, South Indian, Kollywood\nelectronic dance, South Indian, Sinhala\nelectronic dance, South Indian, Tamil\nelectronic dance, South Indian, Telugu\nelectronic dance, South Indian, chiptune\nelectronic dance, South Indian, high-tempo\nelectronic dance, South Indian, synth pop\nelectronic dance, South Indian, synthwave\nelectronic dance, Southeast Asian folk\nelectronic dance, Southeast Asian folk, fusion\nelectronic dance, Southeast Asian folk, modern fusion\nelectronic dance, Southeast Asian folk, modern pop\nelectronic dance, Southeast Asian folk, pop\nelectronic dance, Southeast Asian fusion\nelectronic dance, Southeast Asian fusion, chiptune\nelectronic dance, Southeast Asian fusion, hardstyle\nelectronic dance, Southeast Asian pop\nelectronic dance, Southeast Asian, DJ\nelectronic dance, Southeast Asian, chiptune\nelectronic dance, Southeast Asian, club\nelectronic dance, Southeast Asian, synthwave\nelectronic dance, Spanish folk, fusion\nelectronic dance, Sufi fusion\nelectronic dance, Sufi, South Asian\nelectronic dance, Sundanese fusion\nelectronic dance, Sundanese fusion, funkot\nelectronic dance, Sundanese pop\nelectronic dance, Sundanese pop, Javanese pop\nelectronic dance, Tamil Kuthu\nelectronic dance, Tamil fusion\nelectronic dance, Tamil pop\nelectronic dance, Tamil pop, Kollywood\nelectronic dance, Tamil pop, Malayalam pop\nelectronic dance, Tamil pop, South Indian\nelectronic dance, Telugu pop, cinematic\nelectronic dance, Tibetan folk\nelectronic dance, Tibetan fusion\nelectronic dance, Tibetan pop\nelectronic dance, Tollywood\nelectronic dance, Tollywood, chiptune\nelectronic dance, Tollywood, fusion\nelectronic dance, Tollywood, synthwave\nelectronic dance, Turkish folk\nelectronic dance, Turkish folk, aggro\nelectronic dance, Turkish folk, fusion\nelectronic dance, Turkish folk, lo-fi\nelectronic dance, Turkish political anthem\nelectronic dance, Turkish pop\nelectronic dance, Turkish pop, cinematic\nelectronic dance, Turkish sports anthem\nelectronic dance, Turkish, anthem\nelectronic dance, Vietnamese pop, cinematic\nelectronic dance, bhangra\nelectronic dance, bhangra, Bollywood\nelectronic dance, bhangra, Indian fusion\nelectronic dance, bhangra, Indian pop\nelectronic dance, bhangra, bollywood\nelectronic dance, bhangra, chiptune\nelectronic dance, bhangra, devotional\nelectronic dance, bhangra, dhol\nelectronic dance, bhangra, folk\nelectronic dance, bhangra, moombahton\nelectronic dance, bhangra, south asian\nelectronic dance, chiptune\nelectronic dance, chiptune, Bhojpuri\nelectronic dance, chiptune, Bollywood\nelectronic dance, chiptune, C-pop\nelectronic dance, chiptune, Indian folk\nelectronic dance, chiptune, Indian pop\nelectronic dance, chiptune, Indonesian pop\nelectronic dance, chiptune, J-core\nelectronic dance, chiptune, J-pop\nelectronic dance, chiptune, Latin\nelectronic dance, chiptune, Middle Eastern folk\nelectronic dance, chiptune, Middle Eastern fusion\nelectronic dance, chiptune, South Asian\nelectronic dance, chiptune, South Asian folk\nelectronic dance, chiptune, South Asian fusion\nelectronic dance, chiptune, Southeast Asian fusion\nelectronic dance, chiptune, children's music\nelectronic dance, chiptune, dangdut koplo\nelectronic dance, chiptune, folk\nelectronic dance, chiptune, happy hardcore\nelectronic dance, chiptune, video game music\nelectronic dance, cinematic, Hindi hip hop\nelectronic dance, cinematic, Indian fusion\nelectronic dance, cinematic, Middle Eastern fusion\nelectronic dance, cinematic, Punjabi fusion\nelectronic dance, cinematic, South Indian film\nelectronic dance, cinematic, folk fusion\nelectronic dance, dancehall, worldbeat\nelectronic dance, dangdut, pop\nelectronic dance, devotional, Hindu\nelectronic dance, devotional, Indian fusion\nelectronic dance, devotional, hardstyle\nelectronic dance, ethereal, Middle Eastern\nelectronic dance, eurodance, Indian electronic\nelectronic dance, festive, Malay pop\nelectronic dance, filmi\nelectronic dance, filmi pop\nelectronic dance, filmi pop, South Asian fusion\nelectronic dance, filmi, South Asian pop\nelectronic dance, filmi, South Indian\nelectronic dance, filmi, chiptune\nelectronic dance, folk fusion\nelectronic dance, folk fusion, South Asian\nelectronic dance, folk fusion, Southeast Asian\nelectronic dance, folk fusion, Telugu pop\nelectronic dance, folk, reggaeton\nelectronic dance, folk-infused, Indian fusion\nelectronic dance, funk carioca, dangdut koplo\nelectronic dance, funk, Afrofusion\nelectronic dance, funk, dancehall\nelectronic dance, funkot, dangdut\nelectronic dance, funkot, dangdut koplo\nelectronic dance, fusion, South Asian\nelectronic dance, guzheng, modern Asian\nelectronic dance, happy hardcore, nightcore\nelectronic dance, hard house, South Asian fusion\nelectronic dance, hardstyle\nelectronic dance, hardstyle, C-pop\nelectronic dance, hip-hop, Indian fusion\nelectronic dance, hip-hop, Sinhala fusion\nelectronic dance, hip-hop, folk fusion\nelectronic dance, hip-hop, traditional Southeast Asian\nelectronic dance, hip-house, C-pop\nelectronic dance, house, East Asian fusion\nelectronic dance, house, South Asian fusion\nelectronic dance, house, funk, disco\nelectronic dance, house, hip hop\nelectronic dance, klezmer, balkan brass\nelectronic dance, kuthu\nelectronic dance, kuthu, bhangra\nelectronic dance, kuthu, chiptune\nelectronic dance, kuthu, club\nelectronic dance, kuthu, comedic\nelectronic dance, kuthu, filmi\nelectronic dance, kuthu, gaana\nelectronic dance, kuthu, gospel dance\nelectronic dance, kuthu, haryanvi\nelectronic dance, kuthu, hip-hop\nelectronic dance, kuthu, south indian\nelectronic dance, meme music\nelectronic dance, militant, South Asian\nelectronic dance, modern bhangra\nelectronic dance, novelty, children's\nelectronic dance, novelty, nursery rhyme\nelectronic dance, pahari, South Asian fusion\nelectronic dance, pahari, high-energy\nelectronic dance, pahari, high-tempo\nelectronic dance, patriotic, South Asian fusion\nelectronic dance, pop melayu, dangdut\nelectronic dance, pop, Malay fusion\nelectronic dance, pop, cinematic\nelectronic dance, pop, world music\nelectronic dance, protest anthem, Telugu\nelectronic dance, raï, North African fusion\nelectronic dance, raï, chaabi\nelectronic dance, raï, chiptune\nelectronic dance, raï, dabke\nelectronic dance, reggaeton, South Asian fusion\nelectronic dance, reggaeton, hip hop\nelectronic dance, regional Indian, folk-infused\nelectronic dance, regional Indian, party music\nelectronic dance, regional dance\nelectronic dance, regional fusion\nelectronic dance, regional pop\nelectronic dance, regional pop, South Asian\nelectronic dance, retro techno\nelectronic dance, retro, South Indian pop\nelectronic dance, slap house, cinematic\nelectronic dance, synth-pop, Southeast Asian folk\nelectronic dance, traditional Chinese, trance\nelectronic dance, traditional East Asian, synth fusion\nelectronic dance, traditional East Asian, upbeat\nelectronic dance, traditional Indonesian\nelectronic dance, traditional Southeast Asian\nelectronic dance, trance, Indian fusion\nelectronic dance, trap, EDM\nelectronic dance, trot\nelectronic dance, world fusion\nelectronic dance, world music, South Asian pop\nelectronic dance, world music, pop\nelectronic dance, world music, synthwave\nelectronic dance, worldbeat, Tibetan folk\nelectronic dance, wuxia, C-pop\nelectronic dance-pop\nelectronic dance-pop Tollywood\nelectronic dance-pop classical fusion\nelectronic dance-pop, Middle Eastern fusion\nelectronic dancehall\nelectronic dancehall afrobeat\nelectronic dancehall trap\nelectronic dangdut\nelectronic dangdut koplo\nelectronic dembow\nelectronic devotional\nelectronic devotional fusion\nelectronic dholak\nelectronic dizi\nelectronic dream pop\nelectronic drum\nelectronic drum break\nelectronic drum programming\nelectronic dubstep\nelectronic duduk\nelectronic educational\nelectronic emo\nelectronic emo rap\nelectronic emo-rap\nelectronic enka\nelectronic fado-pop\nelectronic fantasy\nelectronic festive\nelectronic filmi\nelectronic fitness\nelectronic flamenco\nelectronic folk\nelectronic folk dance\nelectronic folk fusion\nelectronic folk hip-hop\nelectronic folk pop\nelectronic folk rock\nelectronic folk-dance\nelectronic folk-fusion\nelectronic folk-pop\nelectronic folk-rock\nelectronic football chant\nelectronic forró\nelectronic funk\nelectronic funk breakbeat\nelectronic funk dancehall\nelectronic funk hip-hop\nelectronic funk jazz\nelectronic funk jazz fusion\nelectronic funk jazz fusion chiptune\nelectronic funk klezmer\nelectronic funk lounge\nelectronic funk rock\nelectronic funk world music\nelectronic funk, Indian devotional, quirky fusion\nelectronic funk, Middle Eastern, video game music\nelectronic funk, breakbeat, Middle Eastern\nelectronic funk, rock, Balkan folk\nelectronic funk, trap, Chinese fusion\nelectronic funk-pop\nelectronic fusion\nelectronic ghazal\nelectronic gospel\nelectronic gospel trap\nelectronic hip hop\nelectronic hip-hop\nelectronic hip-hop EDM\nelectronic hip-hop J-pop\nelectronic hip-hop chiptune\nelectronic hip-hop dubstep\nelectronic hip-hop pop\nelectronic hip-hop pop-rock\nelectronic hip-hop rock\nelectronic hip-hop soul\nelectronic hip-hop synthwave\nelectronic hip-hop trance\nelectronic hip-hop, cinematic trance\nelectronic hip-hop, cinematic, Chinese opera\nelectronic hip-hop, epic rock\nelectronic hip-hop, hyperpop\nelectronic hip-hop, pop, Middle Eastern fusion\nelectronic hip-hop, pop, hardstyle\nelectronic hip-hop, pop-rock, EDM\nelectronic holiday\nelectronic horror\nelectronic house\nelectronic house breakbeat\nelectronic house world music\nelectronic hymn\nelectronic indie\nelectronic indie hip-hop\nelectronic indie pop\nelectronic indie rock\nelectronic jazz\nelectronic jazz fusion\nelectronic jingle\nelectronic klezmer\nelectronic laïko\nelectronic lounge\nelectronic lounge pop\nelectronic lullaby\nelectronic mantra\nelectronic mashup\nelectronic mawwal\nelectronic melancholic\nelectronic melancholy\nelectronic meme\nelectronic metal\nelectronic metalcore\nelectronic military march\nelectronic naat\nelectronic narrative\nelectronic nasheed\nelectronic norteño\nelectronic novelty\nelectronic nursery rhyme\nelectronic opera\nelectronic orchestral\nelectronic oud\nelectronic oud fusion\nelectronic percussion\nelectronic piseiro\nelectronic political satire\nelectronic polka\nelectronic pop\nelectronic pop Afrobeat\nelectronic pop Bollywood\nelectronic pop C-pop\nelectronic pop C-pop J-rock\nelectronic pop Indian\nelectronic pop J-pop\nelectronic pop J-pop trance\nelectronic pop Latin\nelectronic pop R&B\nelectronic pop Tollywood\nelectronic pop ambient\nelectronic pop ballad\nelectronic pop cabaret\nelectronic pop chiptune\nelectronic pop darkwave\nelectronic pop downtempo\nelectronic pop future bass\nelectronic pop gospel\nelectronic pop hip-hop\nelectronic pop indie pop\nelectronic pop jazz noir\nelectronic pop moombahton\nelectronic pop nasheed\nelectronic pop punk\nelectronic pop rap\nelectronic pop reggaeton\nelectronic pop rock\nelectronic pop soul\nelectronic pop trance\nelectronic pop trap\nelectronic pop trip-hop\nelectronic pop tropical house\nelectronic pop world fusion\nelectronic pop world music\nelectronic pop worldbeat\nelectronic pop, 90s Eurodance\nelectronic pop, Arabic Mawwal, North African fusion\nelectronic pop, Arabic fusion\nelectronic pop, Arabic fusion, trance\nelectronic pop, Arabic pop, Moroccan pop\nelectronic pop, Arabic pop, dance\nelectronic pop, Armenian folk, trap\nelectronic pop, Azerbaijani folk\nelectronic pop, Azerbaijani folk, dance\nelectronic pop, Azerbaijani fusion\nelectronic pop, Balkan folk, glitch\nelectronic pop, Bollywood\nelectronic pop, Bollywood pop\nelectronic pop, Bollywood, cinematic\nelectronic pop, Bollywood, festive\nelectronic pop, Bollywood, future bass\nelectronic pop, Bollywood, synthwave\nelectronic pop, Brazilian pop-rock\nelectronic pop, C-pop\nelectronic pop, C-pop, EDM\nelectronic pop, C-pop, ambient\nelectronic pop, C-pop, fusion\nelectronic pop, C-pop, hyperpop\nelectronic pop, C-pop, traditional fusion\nelectronic pop, C-pop, trap\nelectronic pop, C-pop, wuxia\nelectronic pop, Central Asian\nelectronic pop, Central Asian folk\nelectronic pop, Central Asian folk, anthemic\nelectronic pop, Central Asian folk, cinematic\nelectronic pop, Central Asian fusion\nelectronic pop, Chinese fusion\nelectronic pop, Chinese fusion, hardstyle\nelectronic pop, Chinese fusion, wuxia\nelectronic pop, EDM, Bollywood\nelectronic pop, EDM, C-pop\nelectronic pop, EDM, anthemic\nelectronic pop, EDM, hip-hop\nelectronic pop, EDM, trap\nelectronic pop, EDM, world music\nelectronic pop, East Asian folk\nelectronic pop, East Asian, modern\nelectronic pop, Indian classical, folk-pop\nelectronic pop, Indian devotional, worldbeat\nelectronic pop, Indian film music\nelectronic pop, Indian folk\nelectronic pop, Indian folk, cinematic\nelectronic pop, Indian folk, fusion\nelectronic pop, Indian fusion\nelectronic pop, Indian fusion, cinematic\nelectronic pop, J-pop\nelectronic pop, J-pop, anime\nelectronic pop, J-pop, chiptune\nelectronic pop, J-pop, future bass\nelectronic pop, J-pop, hyperpop\nelectronic pop, J-rock\nelectronic pop, K-pop\nelectronic pop, K-pop, J-pop, R&B\nelectronic pop, K-pop, trap\nelectronic pop, Khmer hip hop, EDM\nelectronic pop, Latin pop, anthemic\nelectronic pop, Latin urban, protest anthem\nelectronic pop, Mandopop, Eurodance\nelectronic pop, Middle Eastern fusion\nelectronic pop, Middle Eastern fusion, Persian pop\nelectronic pop, Middle Eastern fusion, cinematic\nelectronic pop, Middle Eastern pop, Azerbaijani pop\nelectronic pop, Middle Eastern pop, Turkish pop\nelectronic pop, Middle Eastern, Arabic\nelectronic pop, Middle Eastern, Azerbaijani\nelectronic pop, Middle Eastern, Persian pop\nelectronic pop, Middle Eastern, ambient\nelectronic pop, Middle Eastern, anthemic\nelectronic pop, Middle Eastern, cinematic\nelectronic pop, Middle Eastern, dance-pop\nelectronic pop, North African fusion\nelectronic pop, North African fusion, trap\nelectronic pop, R&B, C-pop\nelectronic pop, R&B, Chinese traditional\nelectronic pop, R&B, Indian fusion\nelectronic pop, R&B, Indian pop\nelectronic pop, R&B, South Asian fusion\nelectronic pop, R&B, UK garage\nelectronic pop, R&B, future bass\nelectronic pop, R&B, world music\nelectronic pop, Rai, Middle Eastern\nelectronic pop, Raï, Mawwal\nelectronic pop, Raï, ambient\nelectronic pop, Raï, cinematic\nelectronic pop, South Asian film music\nelectronic pop, South Asian folk\nelectronic pop, South Asian folk, Bollywood\nelectronic pop, South Asian folk, Hindustani classical\nelectronic pop, South Asian folk, fusion\nelectronic pop, South Asian fusion\nelectronic pop, South Asian, upbeat\nelectronic pop, South Indian fusion\nelectronic pop, South Indian fusion, chiptune\nelectronic pop, Southeast Asian folk\nelectronic pop, Southeast Asian folk, cinematic\nelectronic pop, Tibetan folk, worldbeat\nelectronic pop, Tibetan pop\nelectronic pop, Turkish folk\nelectronic pop, Turkish folk, cinematic\nelectronic pop, Turkish fusion\nelectronic pop, Vietnamese folk\nelectronic pop, Vietnamese folk, chiptune\nelectronic pop, Vietnamese fusion, trap\nelectronic pop, Vocaloid, C-pop\nelectronic pop, alternative rock, industrial rock\nelectronic pop, anime style\nelectronic pop, breakbeat\nelectronic pop, breakbeat, drum and bass\nelectronic pop, chiptune, East Asian fusion\nelectronic pop, chiptune, R&B\nelectronic pop, chiptune, South Asian folk\nelectronic pop, cinematic, Central Asian fusion\nelectronic pop, cinematic, Chinese folk\nelectronic pop, cinematic, rock\nelectronic pop, conscious hip-hop\nelectronic pop, cyberpunk, dubstep\nelectronic pop, dance-pop, EDM\nelectronic pop, dancehall\nelectronic pop, dancehall, chiptune\nelectronic pop, dancehall, reggae\nelectronic pop, deep house\nelectronic pop, devotional, cinematic\nelectronic pop, dubstep\nelectronic pop, dubstep, hardstyle\nelectronic pop, dubstep, lo-fi hip hop\nelectronic pop, folk dance, Turkish pop\nelectronic pop, future bass, C-pop\nelectronic pop, future bass, cinematic\nelectronic pop, future bass, hardstyle\nelectronic pop, future bass, hip-hop\nelectronic pop, ghazal\nelectronic pop, hardstyle\nelectronic pop, hardstyle, cinematic\nelectronic pop, hardstyle, dubstep\nelectronic pop, hip-hop\nelectronic pop, hip-hop, EDM\nelectronic pop, hip-hop, J-pop\nelectronic pop, hip-hop, Middle Eastern\nelectronic pop, hip-hop, R&B\nelectronic pop, hip-hop, South Asian fusion\nelectronic pop, hip-hop, Southeast Asian fusion\nelectronic pop, hybrid trap, cinematic\nelectronic pop, hyperpop\nelectronic pop, hyperpop, J-pop\nelectronic pop, hyperpop, anime theme\nelectronic pop, industrial rock\nelectronic pop, industrial, trap\nelectronic pop, modern nasheed\nelectronic pop, moombahton, Middle Eastern\nelectronic pop, musical theater\nelectronic pop, musical theater, cinematic\nelectronic pop, nu-metal, chiptune\nelectronic pop, pop-rock\nelectronic pop, reggaeton, Latin pop\nelectronic pop, rock, South Asian fusion\nelectronic pop, traditional Chinese, theatrical\nelectronic pop, trance\nelectronic pop, trance, Indian classical\nelectronic pop, trap, Indian classical\nelectronic pop, trap, Middle Eastern\nelectronic pop, trap, Russian pop\nelectronic pop, trap, South Asian\nelectronic pop, trap, South Indian fusion\nelectronic pop, trap, industrial\nelectronic pop, trap, melancholic hip-hop\nelectronic pop, trip-hop\nelectronic pop, trip-hop, K-pop\nelectronic pop, world fusion\nelectronic pop, world fusion, trap\nelectronic pop, world music\nelectronic pop, world music, ambient\nelectronic pop, world music, cinematic\nelectronic pop, world music, gospel\nelectronic pop, world music, hip-hop\nelectronic pop, world music, rock\nelectronic pop, worldbeat, spiritual\nelectronic pop-R&B\nelectronic pop-dance\nelectronic pop-funk\nelectronic pop-punk\nelectronic pop-r&b\nelectronic pop-rap\nelectronic pop-rock\nelectronic post-hardcore\nelectronic post-rock\nelectronic praise worship\nelectronic progressive metal\nelectronic protest\nelectronic punk\nelectronic punk folk\nelectronic punk, digital hardcore, chiptune\nelectronic qawwali\nelectronic quirky\nelectronic rai\nelectronic rap\nelectronic rap battle\nelectronic rap rock\nelectronic rap, J-rock\nelectronic rap, chiptune, battle rap\nelectronic rap, chiptune, synthwave\nelectronic rap, chiptune, video game\nelectronic rave\nelectronic raï\nelectronic reggae\nelectronic reggae dancehall\nelectronic reggaeton\nelectronic ritual\nelectronic rock\nelectronic rock J-rock\nelectronic rock K-pop\nelectronic rock Tamil pop\nelectronic rock alternative\nelectronic rock alternative pop\nelectronic rock anime\nelectronic rock anime opening\nelectronic rock arena rock\nelectronic rock big beat\nelectronic rock chiptune\nelectronic rock chiptune metalcore\nelectronic rock complextro\nelectronic rock cyberpunk\nelectronic rock dance-pop\nelectronic rock dance-punk\nelectronic rock dancehall\nelectronic rock dark synth-pop\nelectronic rock drum and bass\nelectronic rock dubstep\nelectronic rock dubstep nu-metal\nelectronic rock emo-pop\nelectronic rock emo-rap hyperpop\nelectronic rock future bass\nelectronic rock future bass melodic dubstep\nelectronic rock hardstyle\nelectronic rock hip-hop\nelectronic rock horror-cabaret\nelectronic rock hyperpop\nelectronic rock hyperpop chiptune\nelectronic rock hyperpop drum and bass\nelectronic rock hyperpop emo\nelectronic rock hyperpop emo-rap\nelectronic rock hyperpop j-rock\nelectronic rock hyperpop metalcore\nelectronic rock hyperpop-punk\nelectronic rock industrial\nelectronic rock industrial dance\nelectronic rock industrial metal\nelectronic rock industrial metalcore\nelectronic rock industrial nu-metal\nelectronic rock industrial pop\nelectronic rock mandopop\nelectronic rock metalcore\nelectronic rock nu-metal\nelectronic rock nu-metal chiptune\nelectronic rock nu-metal dubstep\nelectronic rock nu-metal emo-rap\nelectronic rock nu-metal hyperpop\nelectronic rock opera\nelectronic rock phonk\nelectronic rock pop-punk\nelectronic rock post-hardcore\nelectronic rock rap-metal\nelectronic rock rap-rock\nelectronic rock rapcore\nelectronic rock symphonic metal\nelectronic rock synth-pop\nelectronic rock synth-punk\nelectronic rock trance\nelectronic rock trancecore\nelectronic rock trap\nelectronic rock trap industrial\nelectronic rock trap nu-metal\nelectronic rock, Anatolian rock\nelectronic rock, Azerbaijani folk, cinematic\nelectronic rock, Bollywood\nelectronic rock, C-pop, ambient\nelectronic rock, C-pop, ancient style\nelectronic rock, C-pop, cinematic\nelectronic rock, C-pop, dubstep\nelectronic rock, C-pop, experimental\nelectronic rock, C-pop, fusion\nelectronic rock, C-pop, guzheng fusion\nelectronic rock, C-pop, nu-metal\nelectronic rock, C-pop, traditional fusion\nelectronic rock, C-pop, wuxia\nelectronic rock, Chinese fusion\nelectronic rock, Chinese fusion, cinematic\nelectronic rock, Chinese opera, trap\nelectronic rock, Indian devotional\nelectronic rock, Indian film music\nelectronic rock, Indian folk, retro-futuristic\nelectronic rock, J-pop, traditional East Asian\nelectronic rock, J-rock\nelectronic rock, J-rock, C-pop\nelectronic rock, J-rock, K-pop\nelectronic rock, J-rock, Latin rap\nelectronic rock, J-rock, anime\nelectronic rock, J-rock, artcore\nelectronic rock, J-rock, chiptune\nelectronic rock, J-rock, cinematic\nelectronic rock, J-rock, cyberpunk\nelectronic rock, J-rock, happy hardcore\nelectronic rock, J-rock, hardstyle\nelectronic rock, J-rock, hyperpop\nelectronic rock, J-rock, industrial\nelectronic rock, J-rock, nu-metal\nelectronic rock, J-rock, synth rock\nelectronic rock, J-rock, synth-rock\nelectronic rock, J-rock, trance\nelectronic rock, K-pop\nelectronic rock, K-pop, cyberpunk\nelectronic rock, K-pop, dubstep\nelectronic rock, K-pop, hardstyle\nelectronic rock, Middle Eastern fusion\nelectronic rock, Middle Eastern fusion, industrial metal\nelectronic rock, South Asian fusion\nelectronic rock, brostep, ambient\nelectronic rock, brostep, chiptune\nelectronic rock, chiptune, J-rock\nelectronic rock, chiptune, drum and bass\nelectronic rock, chiptune, dubstep\nelectronic rock, chiptune, hyperpop\nelectronic rock, dance, Middle Eastern fusion\nelectronic rock, dance-pop, Telugu folk\nelectronic rock, drum & bass, neurofunk\nelectronic rock, drum and bass\nelectronic rock, drum and bass, neurofunk\nelectronic rock, drum and bass, nu-metal\nelectronic rock, dubstep, C-pop\nelectronic rock, dubstep, chiptune\nelectronic rock, dubstep, cinematic\nelectronic rock, dubstep, metalcore\nelectronic rock, glitch, ambient\nelectronic rock, hardstyle, C-pop\nelectronic rock, hardstyle, cinematic\nelectronic rock, hardstyle, lo-fi\nelectronic rock, hardstyle, lo-fi hip hop\nelectronic rock, hyperpop\nelectronic rock, hyperpop, C-pop\nelectronic rock, hyperpop, J-rock\nelectronic rock, hyperpop, drum and bass\nelectronic rock, hyperpop, metalcore\nelectronic rock, hyperpop, synth-punk\nelectronic rock, hyperpop, trance\nelectronic rock, hyperpop, trap metal\nelectronic rock, industrial, Middle Eastern fusion\nelectronic rock, industrial, dubstep\nelectronic rock, metalcore, C-pop\nelectronic rock, metalcore, ambient\nelectronic rock, metalcore, ambient pop\nelectronic rock, metalcore, dubstep\nelectronic rock, metalcore, pop-punk\nelectronic rock, neurofunk, glitch\nelectronic rock, nu-metal, hyperpop\nelectronic rock, pop-punk\nelectronic rock, pop-punk, J-rock\nelectronic rock, pop-punk, emo-pop\nelectronic rock, pop-punk, hyperpop\nelectronic rock, pop-punk, metalcore\nelectronic rock, psychedelic funk, shred guitar\nelectronic rock, rap-metal\nelectronic rock, symphonic hardcore, J-rock\nelectronic rock, synth-pop\nelectronic rock, synth-pop, world music\nelectronic rock, trap, Bollywood\nelectronic rock, trap, Indonesian hip hop\nelectronic rock, trap, metalcore\nelectronic rock, world fusion, epic\nelectronic rock, world music, dubstep\nelectronic rock, worship\nelectronic rock, wuxia, Chinese fusion\nelectronic samba\nelectronic satire\nelectronic sea shanty\nelectronic show tune\nelectronic sitar\nelectronic soca\nelectronic soul\nelectronic spoken word\nelectronic sports anthem\nelectronic stadium\nelectronic stadium anthem\nelectronic tango\nelectronic techno\nelectronic theater\nelectronic trance hip-hop\nelectronic trap\nelectronic trap chiptune\nelectronic trap dubstep\nelectronic trap gospel\nelectronic trap hip-hop\nelectronic trap pop\nelectronic trap synth-pop\nelectronic trap, C-pop, cyberpunk\nelectronic trap, cinematic pop, C-pop\nelectronic tribal\nelectronic trip-hop ambient\nelectronic tropical\nelectronic trot\nelectronic urban\nelectronic whimsy\nelectronic workout\nelectronic world\nelectronic world beat\nelectronic world fusion\nelectronic world music\nelectronic world percussion\nelectronic world pop\nelectronic worldbeat\nelectronic worldbeat funk\nelectronic worship\nelectronic, 80s house, synth-pop\nelectronic, 80s retro\nelectronic, 80s retro, dance-pop\nelectronic, 80s retro, synthwave\nelectronic, 80s retro, techno\nelectronic, 80s synth\nelectronic, 80s synth, retro wave\nelectronic, 80s synth, rock\nelectronic, 80s synth-pop\nelectronic, 80s, retro\nelectronic, 80s, synthwave\nelectronic, 90s house, video game\nelectronic, 90s tech, upbeat jingle\nelectronic, 90s vibe, upbeat\nelectronic, 90s video game\nelectronic, 90s video game, corporate jingle\nelectronic, 90s video game, funk\nelectronic, 90s video game, library music\nelectronic, 90s video game, synthwave\nelectronic, Afro house, ambient\nelectronic, Afro house, deep house\nelectronic, Afro house, ritual techno\nelectronic, Afro-Cuban\nelectronic, Afro-Cuban, polyrhythmic\nelectronic, Afro-Latin, ambient\nelectronic, Afro-electro, dance\nelectronic, Afro-electronic, chiptune\nelectronic, Afro-electronic, soulful\nelectronic, Afro-electronic, trap\nelectronic, Afro-house, ambient\nelectronic, Afro-house, dance\nelectronic, Afro-house, hip hop\nelectronic, Afro-house, pop\nelectronic, Afro-house, progressive\nelectronic, Afro-house, retro synth\nelectronic, Afro-house, ritualistic\nelectronic, Afro-house, soul\nelectronic, Afro-house, spiritual\nelectronic, Afro-house, tribal techno\nelectronic, Afro-tech, industrial\nelectronic, Afrobeat, ambient\nelectronic, Afrobeat, dance\nelectronic, Afrobeat, hip hop\nelectronic, Afrobeat, rave\nelectronic, Afrobeat, synth bass\nelectronic, Afrobeat, synthwave\nelectronic, Afrohouse, Zulu vocal\nelectronic, Afrohouse, ambient\nelectronic, Afrohouse, choral\nelectronic, Afroswing, lo-fi hip hop\nelectronic, Anatolian folk, Middle Eastern\nelectronic, Anatolian folk, ambient\nelectronic, Anatolian folk, cinematic\nelectronic, Anatolian folk, dance\nelectronic, Anatolian folk, synthwave\nelectronic, Anatolian fusion, cinematic\nelectronic, Anatolian, ambient\nelectronic, Anatolian, cinematic\nelectronic, Anatolian, dance\nelectronic, Anatolian, melodic\nelectronic, Anatolian, synthwave\nelectronic, Anatolian, upbeat\nelectronic, Andean folk, ambient\nelectronic, Andean fusion, cinematic\nelectronic, Arabic EDM\nelectronic, Arabic chant, Middle Eastern\nelectronic, Arabic chant, dance\nelectronic, Arabic choral, anthemic\nelectronic, Arabic devotional, ambient\nelectronic, Arabic devotional, chiptune\nelectronic, Arabic devotional, dance\nelectronic, Arabic folk, chiptune\nelectronic, Arabic folk, dance\nelectronic, Arabic folk, ney flute\nelectronic, Arabic folk, synth pop\nelectronic, Arabic fusion\nelectronic, Arabic fusion, EDM\nelectronic, Arabic fusion, Mawwal\nelectronic, Arabic fusion, Middle Eastern\nelectronic, Arabic fusion, North African\nelectronic, Arabic fusion, ambient\nelectronic, Arabic fusion, anthemic\nelectronic, Arabic fusion, belly dance\nelectronic, Arabic fusion, cinematic\nelectronic, Arabic fusion, dance\nelectronic, Arabic fusion, dark ambient\nelectronic, Arabic fusion, deep house\nelectronic, Arabic fusion, duduk\nelectronic, Arabic fusion, flamenco\nelectronic, Arabic fusion, glitch\nelectronic, Arabic fusion, hard house\nelectronic, Arabic fusion, high-energy\nelectronic, Arabic fusion, hyperpop\nelectronic, Arabic fusion, industrial\nelectronic, Arabic fusion, lo-fi\nelectronic, Arabic fusion, mawwal\nelectronic, Arabic fusion, pop\nelectronic, Arabic fusion, progressive\nelectronic, Arabic fusion, psytrance\nelectronic, Arabic fusion, rave\nelectronic, Arabic fusion, spiritual\nelectronic, Arabic fusion, spiritual techno\nelectronic, Arabic fusion, techno\nelectronic, Arabic fusion, trance\nelectronic, Arabic fusion, trap\nelectronic, Arabic hip hop, cinematic\nelectronic, Arabic hip hop, dream pop\nelectronic, Arabic house, chiptune\nelectronic, Arabic hype, stadium techno\nelectronic, Arabic pop\nelectronic, Arabic pop, North African\nelectronic, Arabic pop, ambient\nelectronic, Arabic pop, atmospheric\nelectronic, Arabic pop, bilingual\nelectronic, Arabic pop, cinematic\nelectronic, Arabic pop, dance\nelectronic, Arabic pop, dark wave\nelectronic, Arabic pop, deep house\nelectronic, Arabic pop, drum and bass\nelectronic, Arabic pop, experimental\nelectronic, Arabic pop, lo-fi\nelectronic, Arabic pop, protest\nelectronic, Arabic pop, synthwave\nelectronic, Arabic techno\nelectronic, Arabic techno, dance\nelectronic, Arabic trance, dance\nelectronic, Arabic, Dabke\nelectronic, Arabic, Mawwal\nelectronic, Arabic, North African\nelectronic, Arabic, ambient\nelectronic, Arabic, chiptune\nelectronic, Arabic, cinematic\nelectronic, Arabic, dance\nelectronic, Arabic, deep house\nelectronic, Arabic, devotional\nelectronic, Arabic, epic\nelectronic, Arabic, fusion\nelectronic, Arabic, hypnotic\nelectronic, Arabic, lo-fi\nelectronic, Arabic, ney\nelectronic, Arabic, ney flute\nelectronic, Arabic, protest\nelectronic, Arabic, spiritual\nelectronic, Arabic, sports anthem\nelectronic, Arabic, trance\nelectronic, Arabic, trap\nelectronic, Armenian, hardstyle\nelectronic, Asian fusion, dance\nelectronic, Asian fusion, upbeat\nelectronic, Azerbaijani folk, cinematic\nelectronic, Azerbaijani folk, dance\nelectronic, Azerbaijani folk, mid-tempo\nelectronic, Azerbaijani fusion, cinematic\nelectronic, Azerbaijani pop, Middle Eastern\nelectronic, Azerbaijani pop, ambient\nelectronic, Azerbaijani pop, synthwave\nelectronic, Azerbaijani pop, trance\nelectronic, Azerbaijani pop, world music\nelectronic, Azerbaijani, cinematic\nelectronic, Azerbaijani, trap\nelectronic, Balkan beat\nelectronic, Balkan beat, Middle Eastern fusion\nelectronic, Balkan folk, Middle Eastern\nelectronic, Balkan folk, Middle Eastern fusion\nelectronic, Balkan folk, ambient\nelectronic, Balkan folk, cinematic\nelectronic, Balkan folk, dance\nelectronic, Balkan folk, dark wave\nelectronic, Balkan folk, house\nelectronic, Balkan folk, synthwave\nelectronic, Balkan fusion, Middle Eastern\nelectronic, Balkan fusion, Middle Eastern house\nelectronic, Balkan fusion, Middle Eastern techno\nelectronic, Balkan fusion, Romanian pop\nelectronic, Balkan fusion, cinematic\nelectronic, Balkan fusion, club\nelectronic, Balkan fusion, dance\nelectronic, Balkan fusion, lo-fi hip hop\nelectronic, Balkan fusion, rave\nelectronic, Balkan fusion, synthwave\nelectronic, Balkan house, Middle Eastern fusion\nelectronic, Balkan, French hip hop\nelectronic, Balkan, Middle Eastern\nelectronic, Balkan, Persian\nelectronic, Balkan, ambient\nelectronic, Balkan, cinematic\nelectronic, Balkan, dance\nelectronic, Balkan, deep house\nelectronic, Balkan, funk\nelectronic, Balkan, synth\nelectronic, Bengali hip hop\nelectronic, Bengali, ambient\nelectronic, Bhojpuri, club\nelectronic, Bollywood, Middle Eastern\nelectronic, Bollywood, ambient\nelectronic, Bollywood, children's music\nelectronic, Bollywood, cinematic\nelectronic, Bollywood, deep house\nelectronic, Bollywood, high-energy\nelectronic, Brazilian folk, anthemic\nelectronic, Brazilian funk, dangdut koplo\nelectronic, Brazilian funk, deep house\nelectronic, Brazilian fusion, anthemic pop\nelectronic, Brazilian, ambient\nelectronic, Brazilian, chiptune\nelectronic, C-pop, EDM\nelectronic, C-pop, Vocaloid\nelectronic, C-pop, ambient\nelectronic, C-pop, anime\nelectronic, C-pop, anthemic\nelectronic, C-pop, big room\nelectronic, C-pop, chiptune\nelectronic, C-pop, cinematic\nelectronic, C-pop, cyberpunk\nelectronic, C-pop, dance\nelectronic, C-pop, dream pop\nelectronic, C-pop, dubstep\nelectronic, C-pop, ethereal\nelectronic, C-pop, experimental\nelectronic, C-pop, fusion\nelectronic, C-pop, future bass\nelectronic, C-pop, future pop\nelectronic, C-pop, glitch\nelectronic, C-pop, hardstyle\nelectronic, C-pop, hip hop\nelectronic, C-pop, industrial\nelectronic, C-pop, lo-fi\nelectronic, C-pop, lo-fi hip hop\nelectronic, C-pop, retro game\nelectronic, C-pop, synthwave\nelectronic, C-pop, theatrical\nelectronic, C-pop, trance\nelectronic, C-pop, trap\nelectronic, C-pop, tribal house\nelectronic, C-pop, trip-hop\nelectronic, C-pop, vaporwave\nelectronic, C-pop, video game\nelectronic, C-pop, video game music\nelectronic, Cantonese hip hop, industrial\nelectronic, Cantonese pop, glitch\nelectronic, Cantonese pop, synthwave\nelectronic, Catalan hip hop, ambient\nelectronic, Central Asian folk, dance\nelectronic, Central Asian fusion\nelectronic, Central Asian fusion, cinematic\nelectronic, Central Asian, modern\nelectronic, Central Asian, synthwave\nelectronic, Chinese MC, lo-fi hip hop\nelectronic, Chinese ambient, synth-pop\nelectronic, Chinese classical, cinematic\nelectronic, Chinese folk, cinematic\nelectronic, Chinese folk, dance\nelectronic, Chinese folk, theatrical\nelectronic, Chinese folk, trance\nelectronic, Chinese fusion\nelectronic, Chinese fusion, EDM\nelectronic, Chinese fusion, cinematic\nelectronic, Chinese fusion, cyberpunk\nelectronic, Chinese fusion, dance\nelectronic, Chinese fusion, hardstyle\nelectronic, Chinese fusion, house\nelectronic, Chinese fusion, trap\nelectronic, Chinese hip hop\nelectronic, Chinese hip hop, EDM\nelectronic, Chinese hip hop, breakbeat\nelectronic, Chinese hip hop, synthwave\nelectronic, Chinese hǎnmài, digital marimba\nelectronic, Chinese opera, cinematic\nelectronic, Chinese opera, hardstyle\nelectronic, Chinese opera, trap\nelectronic, Chinese rap, lo-fi\nelectronic, Chinese traditional, ambient\nelectronic, Chinese traditional, breakbeat\nelectronic, Chinese traditional, cinematic\nelectronic, Chinese traditional, downtempo\nelectronic, Chinese, ambient\nelectronic, Chinese, cinematic\nelectronic, Chinese, video game\nelectronic, Chinese-style, cinematic\nelectronic, Chinese-style, theatrical\nelectronic, Czech rap, atmospheric\nelectronic, Dangdut, pop\nelectronic, Dutch hip hop, cinematic\nelectronic, EBM, ambient techno\nelectronic, EBM, chiptune\nelectronic, EBM, cyberpunk\nelectronic, EBM, darkwave\nelectronic, EBM, synthwave\nelectronic, EBM, techno\nelectronic, EBM, trance\nelectronic, EDM, East Asian\nelectronic, EDM, German rap\nelectronic, EDM, Indian fusion\nelectronic, EDM, Middle Eastern\nelectronic, EDM, Middle Eastern fusion\nelectronic, EDM, ambient\nelectronic, EDM, anthemic\nelectronic, EDM, chiptune\nelectronic, EDM, cinematic\nelectronic, EDM, complextro\nelectronic, EDM, cyberpunk\nelectronic, EDM, dance\nelectronic, EDM, dubstep\nelectronic, EDM, electro house\nelectronic, EDM, ethnic fusion\nelectronic, EDM, future\nelectronic, EDM, future bass\nelectronic, EDM, future house\nelectronic, EDM, guzheng\nelectronic, EDM, hardstyle\nelectronic, EDM, high-energy\nelectronic, EDM, industrial\nelectronic, EDM, instrumental\nelectronic, EDM, oriental synth\nelectronic, EDM, pop\nelectronic, EDM, reggaeton, moombahton\nelectronic, EDM, synthwave\nelectronic, EDM, trap\nelectronic, EDM, tropical house\nelectronic, EDM, uplifting\nelectronic, EDM, vaporwave\nelectronic, EDM, world beats\nelectronic, EDM, world house\nelectronic, East Asian fusion\nelectronic, East Asian fusion, breakbeat\nelectronic, East Asian fusion, cinematic\nelectronic, East Asian fusion, hip-hop\nelectronic, East Asian fusion, instrumental\nelectronic, East Asian, anime\nelectronic, East Asian, chiptune\nelectronic, East Asian, cinematic\nelectronic, East Asian, dance\nelectronic, East Asian, upbeat\nelectronic, East Asian, video game\nelectronic, Eurodance, hip-hop, Mandopop\nelectronic, French choral, synthwave\nelectronic, French hip hop, synth pop\nelectronic, French house, ambient\nelectronic, French house, anthemic\nelectronic, French house, cinematic\nelectronic, French narrative, ambient\nelectronic, French pop, ambient\nelectronic, French pop, atmospheric\nelectronic, French pop, cinematic\nelectronic, French pop, dark wave\nelectronic, French pop, experimental\nelectronic, French pop, industrial\nelectronic, French pop, lo-fi\nelectronic, French pop, melancholic\nelectronic, French pop, minimal techno\nelectronic, French pop, psychedelic\nelectronic, French pop, surreal\nelectronic, French pop, synthwave\nelectronic, French pop, trance\nelectronic, French pop, trap\nelectronic, French rap\nelectronic, French rap, Arabic pop\nelectronic, French rap, aggressive\nelectronic, French rap, ambient\nelectronic, French rap, cinematic\nelectronic, French rap, club\nelectronic, French rap, dance-pop\nelectronic, French rap, techno\nelectronic, French wave, trance\nelectronic, French whisper, retro-futuristic\nelectronic, French, ambient techno\nelectronic, German hip hop, synthpop\nelectronic, German hip-hop, ambient\nelectronic, German indie, techno\nelectronic, German party, stadium anthem\nelectronic, German pop, synthwave\nelectronic, German rap, lo-fi\nelectronic, German rap, quirky\nelectronic, German rap, synthwave\nelectronic, Greek pop, ambient\nelectronic, Greek pop, cinematic\nelectronic, Greek pop, high-energy\nelectronic, Greek rock, cinematic\nelectronic, Greek, anthemic\nelectronic, Greek, theatrical\nelectronic, Halloween, playful\nelectronic, Halloween, playful spooky\nelectronic, Halloween, synthpop\nelectronic, Hebrew pop, cinematic\nelectronic, Hebrew pop, synthwave\nelectronic, Hebrew rap, melancholic\nelectronic, Hebrew, cinematic\nelectronic, Hindi film, trap\nelectronic, Hindi fusion, breakbeat\nelectronic, Hindi hip hop, synthwave\nelectronic, Hindi hip hop, techno\nelectronic, Hindi pop, ambient\nelectronic, Hindi pop, anthemic\nelectronic, Hindi pop, big room house\nelectronic, Hindi pop, cinematic\nelectronic, Hindi pop, dance\nelectronic, Hindi pop, deep house\nelectronic, Hindi pop, experimental\nelectronic, Hindi pop, lo-fi hip hop\nelectronic, Hindi pop, retro synth\nelectronic, Hindi pop, synthwave\nelectronic, Hindi pop, trap\nelectronic, Hindi rap, melodic\nelectronic, Hindi rock, atmospheric\nelectronic, Hindi, ambient\nelectronic, Hindi, drum and bass\nelectronic, Hindi, melancholic\nelectronic, IDM, ambient\nelectronic, IDM, breakbeat\nelectronic, IDM, chiptune\nelectronic, IDM, experimental\nelectronic, IDM, future bass\nelectronic, IDM, glitch\nelectronic, IDM, synthwave\nelectronic, IDM, techno\nelectronic, IDM, video game music\nelectronic, Indian classical, EDM\nelectronic, Indian classical, ambient\nelectronic, Indian classical, chiptune\nelectronic, Indian classical, cinematic\nelectronic, Indian classical, dance\nelectronic, Indian classical, devotional\nelectronic, Indian classical, hardstyle\nelectronic, Indian classical, house\nelectronic, Indian classical, inspirational\nelectronic, Indian classical, lo-fi hip hop\nelectronic, Indian classical, moombahton\nelectronic, Indian classical, pop\nelectronic, Indian classical, pop/R&B\nelectronic, Indian classical, trance\nelectronic, Indian classical, trap\nelectronic, Indian dance, EDM\nelectronic, Indian dance, cinematic\nelectronic, Indian dance, folk fusion\nelectronic, Indian dance, high-tempo\nelectronic, Indian dance, pop\nelectronic, Indian devotional\nelectronic, Indian devotional, EDM\nelectronic, Indian devotional, dance\nelectronic, Indian devotional, hard dance\nelectronic, Indian devotional, hyperpop\nelectronic, Indian devotional, trap\nelectronic, Indian devotional, tribal\nelectronic, Indian film music, ambient\nelectronic, Indian film, dance\nelectronic, Indian folk, Bollywood\nelectronic, Indian folk, ambient\nelectronic, Indian folk, chiptune\nelectronic, Indian folk, cinematic\nelectronic, Indian folk, dance\nelectronic, Indian folk, hard house\nelectronic, Indian folk, upbeat\nelectronic, Indian fusion\nelectronic, Indian fusion, EDM\nelectronic, Indian fusion, ambient\nelectronic, Indian fusion, ambient dance\nelectronic, Indian fusion, chill trap\nelectronic, Indian fusion, chiptune\nelectronic, Indian fusion, cinematic\nelectronic, Indian fusion, dance\nelectronic, Indian fusion, dholak\nelectronic, Indian fusion, downtempo\nelectronic, Indian fusion, ethereal\nelectronic, Indian fusion, experimental\nelectronic, Indian fusion, festival\nelectronic, Indian fusion, future bass\nelectronic, Indian fusion, glitch\nelectronic, Indian fusion, high-energy\nelectronic, Indian fusion, hypnotic\nelectronic, Indian fusion, industrial\nelectronic, Indian fusion, lo-fi\nelectronic, Indian fusion, lo-fi hip hop\nelectronic, Indian fusion, trance\nelectronic, Indian fusion, trap\nelectronic, Indian fusion, urban\nelectronic, Indian fusion, video game music\nelectronic, Indian pop\nelectronic, Indian pop, EDM\nelectronic, Indian pop, ambient\nelectronic, Indian pop, chiptune\nelectronic, Indian pop, dance\nelectronic, Indian pop, dream pop\nelectronic, Indian pop, hip-hop\nelectronic, Indian remix\nelectronic, Indian vocal, ambient\nelectronic, Indian, melodic\nelectronic, Indian, nostalgic\nelectronic, Indonesian fusion, dance\nelectronic, Islamic dance, Arabic fusion\nelectronic, Islamic devotional, fusion\nelectronic, Islamic devotional, trance\nelectronic, Islamic, festive\nelectronic, Italian hip hop, glitch\nelectronic, Italo disco, cinematic\nelectronic, Italo disco, retro\nelectronic, Italo disco, synthwave\nelectronic, Italo house\nelectronic, Italo-Turkish fusion\nelectronic, Italo-disco, ambient\nelectronic, Italo-disco, cinematic\nelectronic, Italo-disco, synthwave\nelectronic, J-RPG, upbeat\nelectronic, J-core, rave\nelectronic, J-dance, chiptune\nelectronic, J-dance, synthwave\nelectronic, J-pop, C-pop\nelectronic, J-pop, Vocaloid\nelectronic, J-pop, ambient\nelectronic, J-pop, anime\nelectronic, J-pop, anime soundtrack\nelectronic, J-pop, art pop\nelectronic, J-pop, artcore\nelectronic, J-pop, cinematic\nelectronic, J-pop, glitch\nelectronic, J-pop, hardcore\nelectronic, J-pop, hip hop\nelectronic, J-pop, hyperpop\nelectronic, J-pop, industrial\nelectronic, J-pop, lo-fi hip hop\nelectronic, J-pop, nu-disco\nelectronic, J-pop, synthwave\nelectronic, J-pop, taiko\nelectronic, J-pop, trance\nelectronic, J-pop, trap\nelectronic, J-pop, video game\nelectronic, J-pop, video game music\nelectronic, J-rock, ambient\nelectronic, J-rock, anime\nelectronic, J-rock, chiptune\nelectronic, J-rock, cinematic\nelectronic, J-rock, trap\nelectronic, J-rock, video game music\nelectronic, Japanese fusion, cinematic\nelectronic, Japanese pop, glitch\nelectronic, Japanese rhythm game, anime opening\nelectronic, Japanese, instrumental\nelectronic, Javanese folk, Malay folk\nelectronic, Javanese fusion\nelectronic, Javanese fusion, chiptune\nelectronic, Javanese pop, ambient\nelectronic, Javanese pop, atmospheric\nelectronic, Javanese pop, fusion\nelectronic, Javanese rap, dance\nelectronic, Javanese, cinematic\nelectronic, Javanese, dance\nelectronic, Javanese, deep house\nelectronic, K-pop, ambient\nelectronic, K-pop, dance\nelectronic, K-pop, dubstep\nelectronic, K-pop, hip hop\nelectronic, K-pop, industrial\nelectronic, K-pop, lo-fi hip hop\nelectronic, K-pop, stadium house\nelectronic, K-pop, video game\nelectronic, Kurdish pop\nelectronic, Kurdish pop, ambient\nelectronic, Kurdish pop, cinematic\nelectronic, Kurdish, ambient\nelectronic, Latin\nelectronic, Latin dance\nelectronic, Latin fusion\nelectronic, Latin hip hop\nelectronic, Latin hip hop, synthwave\nelectronic, Latin house\nelectronic, Latin house, Afrobeat\nelectronic, Latin house, acid house\nelectronic, Latin house, ambient\nelectronic, Latin house, anthemic\nelectronic, Latin house, chiptune\nelectronic, Latin house, cinematic\nelectronic, Latin house, club\nelectronic, Latin house, dance\nelectronic, Latin house, deep house\nelectronic, Latin house, funk\nelectronic, Latin house, groovy\nelectronic, Latin house, industrial\nelectronic, Latin house, party\nelectronic, Latin house, ritual techno\nelectronic, Latin house, synthwave\nelectronic, Latin house, trap\nelectronic, Latin house, vocal house\nelectronic, Latin percussion\nelectronic, Latin percussion, high-energy\nelectronic, Latin percussion, instrumental\nelectronic, Latin pop, ambient\nelectronic, Latin pop, chiptune\nelectronic, Latin pop, cinematic\nelectronic, Latin pop, dance\nelectronic, Latin pop, deep house\nelectronic, Latin pop, experimental\nelectronic, Latin pop, synthwave\nelectronic, Latin techno, aggressive\nelectronic, Latin trap, stadium house\nelectronic, Latin, Afro-Cuban\nelectronic, Latin, Bossa Nova\nelectronic, Latin, Middle Eastern\nelectronic, Latin, aggressive\nelectronic, Latin, ambient\nelectronic, Latin, breakbeat\nelectronic, Latin, breakcore\nelectronic, Latin, cinematic\nelectronic, Latin, club\nelectronic, Latin, dance\nelectronic, Latin, deep house\nelectronic, Latin, drum & bass\nelectronic, Latin, experimental\nelectronic, Latin, funk\nelectronic, Latin, groove\nelectronic, Latin, high-energy\nelectronic, Latin, industrial\nelectronic, Latin, instrumental\nelectronic, Latin, klezmer\nelectronic, Latin, lo-fi\nelectronic, Latin, melancholic\nelectronic, Latin, minimal\nelectronic, Latin, percussion\nelectronic, Latin, reggaeton\nelectronic, Latin, tribal\nelectronic, Latin, video game music\nelectronic, Latin, world music\nelectronic, Latin-influenced, deep house\nelectronic, Latin-influenced, instrumental\nelectronic, Lithuanian rap, synthwave\nelectronic, Luk Thung, Mor Lam\nelectronic, Lusophone, dance\nelectronic, Malay fusion, dance\nelectronic, Malayalam folk, hardstyle\nelectronic, Malayalam pop, cinematic\nelectronic, Malayalam, anthemic\nelectronic, Mandarin hip hop\nelectronic, Mandarin pop, EDM\nelectronic, Mandarin pop, anime theme\nelectronic, Mandarin pop, breakbeat\nelectronic, Mandarin pop, glitch\nelectronic, Mandarin pop, lo-fi\nelectronic, Mandarin pop, synthwave\nelectronic, Mandarin pop, vaporwave\nelectronic, Mandarin rap, club\nelectronic, Mandarin rap, lo-fi\nelectronic, Mandopop, EDM\nelectronic, Mandopop, breakbeat\nelectronic, Mandopop, dark pop\nelectronic, Mandopop, future bass\nelectronic, Mandopop, glitch hop\nelectronic, Mandopop, synthwave\nelectronic, Marathi, festival\nelectronic, Mawwal, dance\nelectronic, Middle Eastern\nelectronic, Middle Eastern dance\nelectronic, Middle Eastern dance, instrumental\nelectronic, Middle Eastern devotional, fusion\nelectronic, Middle Eastern folk, chiptune\nelectronic, Middle Eastern folk, dance\nelectronic, Middle Eastern folk, instrumental\nelectronic, Middle Eastern folk, spiritual\nelectronic, Middle Eastern fusion\nelectronic, Middle Eastern fusion, EDM\nelectronic, Middle Eastern fusion, Malayalam\nelectronic, Middle Eastern fusion, South Asian techno\nelectronic, Middle Eastern fusion, aggressive\nelectronic, Middle Eastern fusion, ambient\nelectronic, Middle Eastern fusion, anthemic\nelectronic, Middle Eastern fusion, breakbeat\nelectronic, Middle Eastern fusion, chiptune\nelectronic, Middle Eastern fusion, cinematic\nelectronic, Middle Eastern fusion, cinematic pop\nelectronic, Middle Eastern fusion, club\nelectronic, Middle Eastern fusion, complextro\nelectronic, Middle Eastern fusion, dance\nelectronic, Middle Eastern fusion, dark ambient\nelectronic, Middle Eastern fusion, dark pop\nelectronic, Middle Eastern fusion, dark wave\nelectronic, Middle Eastern fusion, deep house\nelectronic, Middle Eastern fusion, drum and bass\nelectronic, Middle Eastern fusion, energetic\nelectronic, Middle Eastern fusion, epic\nelectronic, Middle Eastern fusion, experimental\nelectronic, Middle Eastern fusion, festival\nelectronic, Middle Eastern fusion, folk techno\nelectronic, Middle Eastern fusion, funk\nelectronic, Middle Eastern fusion, hard dance\nelectronic, Middle Eastern fusion, hard house\nelectronic, Middle Eastern fusion, hardstyle\nelectronic, Middle Eastern fusion, house\nelectronic, Middle Eastern fusion, instrumental\nelectronic, Middle Eastern fusion, melancholic\nelectronic, Middle Eastern fusion, melodic\nelectronic, Middle Eastern fusion, melodic dubstep\nelectronic, Middle Eastern fusion, moombahton\nelectronic, Middle Eastern fusion, pop\nelectronic, Middle Eastern fusion, progressive house\nelectronic, Middle Eastern fusion, psychedelic rock\nelectronic, Middle Eastern fusion, psytrance\nelectronic, Middle Eastern fusion, rave\nelectronic, Middle Eastern fusion, reggaeton\nelectronic, Middle Eastern fusion, spiritual\nelectronic, Middle Eastern fusion, synthwave\nelectronic, Middle Eastern fusion, tech house\nelectronic, Middle Eastern fusion, techno\nelectronic, Middle Eastern fusion, trance\nelectronic, Middle Eastern fusion, trap\nelectronic, Middle Eastern fusion, turbo-folk\nelectronic, Middle Eastern fusion, upbeat\nelectronic, Middle Eastern fusion, virtuoso\nelectronic, Middle Eastern fusion, vocal hip hop\nelectronic, Middle Eastern fusion, vocal house\nelectronic, Middle Eastern pop, cinematic\nelectronic, Middle Eastern, Anatolian\nelectronic, Middle Eastern, Arabic\nelectronic, Middle Eastern, Arabic fusion\nelectronic, Middle Eastern, Balkan\nelectronic, Middle Eastern, Balkan fusion\nelectronic, Middle Eastern, Bollywood\nelectronic, Middle Eastern, Central Asian\nelectronic, Middle Eastern, EDM\nelectronic, Middle Eastern, French pop\nelectronic, Middle Eastern, Greek\nelectronic, Middle Eastern, Indian\nelectronic, Middle Eastern, Latin\nelectronic, Middle Eastern, North African\nelectronic, Middle Eastern, Phrygian\nelectronic, Middle Eastern, South Asian\nelectronic, Middle Eastern, Turkish\nelectronic, Middle Eastern, Turkish dance\nelectronic, Middle Eastern, aggressive\nelectronic, Middle Eastern, ambient\nelectronic, Middle Eastern, anthemic\nelectronic, Middle Eastern, arpeggiated\nelectronic, Middle Eastern, breakbeat\nelectronic, Middle Eastern, chiptune\nelectronic, Middle Eastern, choral\nelectronic, Middle Eastern, cinematic\nelectronic, Middle Eastern, club\nelectronic, Middle Eastern, dance\nelectronic, Middle Eastern, dance-pop\nelectronic, Middle Eastern, deep house\nelectronic, Middle Eastern, devotional\nelectronic, Middle Eastern, downtempo\nelectronic, Middle Eastern, dramatic\nelectronic, Middle Eastern, dream pop\nelectronic, Middle Eastern, duduk\nelectronic, Middle Eastern, ethereal\nelectronic, Middle Eastern, festival\nelectronic, Middle Eastern, festive\nelectronic, Middle Eastern, flamenco\nelectronic, Middle Eastern, folk\nelectronic, Middle Eastern, folk fusion\nelectronic, Middle Eastern, fusion\nelectronic, Middle Eastern, hard dance\nelectronic, Middle Eastern, high-energy\nelectronic, Middle Eastern, hip-hop\nelectronic, Middle Eastern, house\nelectronic, Middle Eastern, hypnotic\nelectronic, Middle Eastern, instrumental\nelectronic, Middle Eastern, lo-fi\nelectronic, Middle Eastern, lo-fi hip hop\nelectronic, Middle Eastern, maqam\nelectronic, Middle Eastern, melancholic\nelectronic, Middle Eastern, melodic\nelectronic, Middle Eastern, microtonal\nelectronic, Middle Eastern, moombahton\nelectronic, Middle Eastern, percussive\nelectronic, Middle Eastern, political\nelectronic, Middle Eastern, pop\nelectronic, Middle Eastern, progressive\nelectronic, Middle Eastern, rave\nelectronic, Middle Eastern, reggaeton\nelectronic, Middle Eastern, retro pop\nelectronic, Middle Eastern, retro synth\nelectronic, Middle Eastern, ritual\nelectronic, Middle Eastern, rock\nelectronic, Middle Eastern, romantic\nelectronic, Middle Eastern, spiritual\nelectronic, Middle Eastern, synth\nelectronic, Middle Eastern, synthwave\nelectronic, Middle Eastern, techno\nelectronic, Middle Eastern, theatrical\nelectronic, Middle Eastern, trance\nelectronic, Middle Eastern, trap\nelectronic, Middle Eastern, tribal\nelectronic, Middle Eastern, urban\nelectronic, Middle Eastern, video game\nelectronic, Middle Eastern, virtuosic\nelectronic, Mizrahi, chiptune\nelectronic, Mongolian folk, EDM\nelectronic, Mongolian folk, ambient\nelectronic, Mongolian folk, cinematic\nelectronic, Mongolian folk, hip-hop\nelectronic, Mongolian fusion\nelectronic, Mongolian hip hop, ambient\nelectronic, Mongolian long-song, synthwave\nelectronic, Mongolian, house\nelectronic, Mor Lam, chiptune\nelectronic, Nepali pop\nelectronic, Nepali pop, ambient\nelectronic, Nintendocore, rave\nelectronic, North African folk, dance\nelectronic, North African fusion\nelectronic, North African fusion, anthemic\nelectronic, North African fusion, cinematic\nelectronic, North African fusion, dance\nelectronic, North African fusion, trance\nelectronic, North African pop, cinematic\nelectronic, North African pop, dance\nelectronic, North African pop, house\nelectronic, North African pop, stadium anthem\nelectronic, North African, Arabic\nelectronic, North African, Middle Eastern\nelectronic, North African, ambient\nelectronic, North African, cinematic\nelectronic, North African, club\nelectronic, North African, dance\nelectronic, North African, early dance\nelectronic, North African, folk fusion\nelectronic, North African, house\nelectronic, North African, lo-fi\nelectronic, North African, melancholic\nelectronic, North African, melismatic\nelectronic, North African, melodic\nelectronic, North African, oud\nelectronic, North African, rap\nelectronic, North African, soulful\nelectronic, North African, spiritual\nelectronic, North African, trance\nelectronic, Persian fusion\nelectronic, Persian fusion, cinematic\nelectronic, Persian fusion, dance\nelectronic, Persian hip hop, synthwave\nelectronic, Persian pop, ambient\nelectronic, Persian pop, cinematic\nelectronic, Persian pop, deep house\nelectronic, Persian soul, melancholic\nelectronic, Persian traditional, melodic\nelectronic, Persian, 90s dance\nelectronic, Persian, ambient\nelectronic, Persian, cinematic\nelectronic, Persian, flamenco\nelectronic, Persian, hard dance\nelectronic, Persian, house\nelectronic, Persian, lo-fi\nelectronic, Persian, melancholic\nelectronic, Persian, melodic\nelectronic, Persian, trap\nelectronic, Persian, zurna\nelectronic, Polish rap, synthwave\nelectronic, Punjabi hip hop, synthwave\nelectronic, Punjabi, ambient\nelectronic, R&B, ambient\nelectronic, R&B, chiptune\nelectronic, R&B, cinematic\nelectronic, R&B, glitch\nelectronic, R&B, hip hop\nelectronic, Rai, Chaabi\nelectronic, Rai, North African pop\nelectronic, Rai, cinematic\nelectronic, Rai, dance\nelectronic, Rai, house\nelectronic, Rai, modern Chaabi\nelectronic, Rai, modernizera\nelectronic, Romanian Manele, ambient\nelectronic, Romanian Manele, chiptune\nelectronic, Romanian hip hop, EDM\nelectronic, Romanian house\nelectronic, Romanian pop, anthemic\nelectronic, Romanian pop, cinematic\nelectronic, Romanian pop, synthwave\nelectronic, Romanian, anthemic\nelectronic, Russian anthemic, cinematic\nelectronic, Russian chant, anthemic\nelectronic, Russian hip hop, ambient\nelectronic, Russian hip hop, cinematic\nelectronic, Russian hip hop, dark wave\nelectronic, Russian hip hop, synthwave\nelectronic, Russian industrial, dark wave\nelectronic, Russian pop, ambient\nelectronic, Russian pop, anime\nelectronic, Russian pop, cinematic\nelectronic, Russian pop, experimental\nelectronic, Russian pop, glitch\nelectronic, Russian pop, synthwave\nelectronic, Russian rap, ambient\nelectronic, Russian rap, anthemic\nelectronic, Russian rap, cinematic\nelectronic, Russian rap, dark ambient\nelectronic, Russian rap, dark club\nelectronic, Russian rap, dark wave\nelectronic, Russian rap, dream pop\nelectronic, Russian rap, synthwave\nelectronic, Russian, deep house\nelectronic, Sinhala devotional, dance\nelectronic, Sinhala pop, ambient\nelectronic, Sinhala pop, retro\nelectronic, Sinhala pop, synthwave\nelectronic, South Asian dance\nelectronic, South Asian dance, EDM\nelectronic, South Asian dance, club\nelectronic, South Asian folk, ambient\nelectronic, South Asian folk, dance\nelectronic, South Asian fusion\nelectronic, South Asian fusion, ambient\nelectronic, South Asian fusion, club\nelectronic, South Asian fusion, dance\nelectronic, South Asian pop\nelectronic, South Asian pop, dance\nelectronic, South Asian pop, synthwave\nelectronic, South Asian, ambient\nelectronic, South Asian, cinematic\nelectronic, South Asian, dance\nelectronic, South Asian, devotional\nelectronic, South Asian, dream pop\nelectronic, South Asian, melancholic\nelectronic, South Asian, melodic\nelectronic, South Asian, romantic\nelectronic, South Asian, trap\nelectronic, South Asian, upbeat\nelectronic, South Indian dance, video game soundtrack\nelectronic, South Indian film music, ethereal\nelectronic, South Indian, ambient\nelectronic, South Indian, chiptune\nelectronic, South Indian, trap\nelectronic, Southeast Asian fusion\nelectronic, Southeast Asian fusion, dance\nelectronic, Southeast Asian fusion, upbeat\nelectronic, Southeast Asian pop, Dangdut\nelectronic, Southeast Asian, ambient\nelectronic, Southeast Asian, melodic\nelectronic, Southeast Asian, upbeat\nelectronic, Sufi, ambient\nelectronic, Sufi, trap\nelectronic, Swedish hip hop, synthwave\nelectronic, Swedish pop, dance\nelectronic, Swedish rap, aggressive\nelectronic, Swedish rap, ambient\nelectronic, Tagalog pop, hardstyle\nelectronic, Tamil cinema, cinematic\nelectronic, Tamil film music, cinematic\nelectronic, Tamil fusion, funk\nelectronic, Tamil hip hop, ambient\nelectronic, Tamil hip hop, breakbeat\nelectronic, Tamil hip hop, cinematic\nelectronic, Tamil pop, hip hop\nelectronic, Tamil pop, synthwave\nelectronic, Tamil pop, trap\nelectronic, Tamil pop, video game\nelectronic, Tamil, aggressive\nelectronic, Tamil, ambient\nelectronic, Tamil, dance\nelectronic, Tamil, high-energy\nelectronic, Telugu hip hop, bass\nelectronic, Telugu pop, ambient\nelectronic, Telugu pop, anthemic\nelectronic, Telugu pop, cinematic\nelectronic, Telugu pop, dubstep\nelectronic, Telugu pop, quirky dance\nelectronic, Telugu pop, trap\nelectronic, Telugu, cinematic\nelectronic, Telugu, high-energy\nelectronic, Telugu, high-tempo\nelectronic, Thai pop, cinematic\nelectronic, Tibetan hip hop\nelectronic, Tibetan, world fusion\nelectronic, Turkish folk, EDM\nelectronic, Turkish folk, Middle Eastern fusion\nelectronic, Turkish folk, ambient\nelectronic, Turkish folk, cinematic\nelectronic, Turkish folk, dance\nelectronic, Turkish folk, deep house\nelectronic, Turkish folk, fusion\nelectronic, Turkish folk, glitch\nelectronic, Turkish folk, lo-fi\nelectronic, Turkish folk, melancholic\nelectronic, Turkish folk, melodic\nelectronic, Turkish folk, oud\nelectronic, Turkish folk, political anthem\nelectronic, Turkish folk, quirky\nelectronic, Turkish folk, rave\nelectronic, Turkish folk, techno\nelectronic, Turkish fusion\nelectronic, Turkish fusion, Middle Eastern\nelectronic, Turkish fusion, anthemic\nelectronic, Turkish fusion, cinematic\nelectronic, Turkish fusion, dance\nelectronic, Turkish fusion, deep house\nelectronic, Turkish fusion, epic\nelectronic, Turkish fusion, ethereal\nelectronic, Turkish fusion, house\nelectronic, Turkish fusion, ney\nelectronic, Turkish fusion, trance\nelectronic, Turkish fusion, trap\nelectronic, Turkish fusion, world music\nelectronic, Turkish lament, tribal house\nelectronic, Turkish political rally\nelectronic, Turkish pop, Middle Eastern fusion\nelectronic, Turkish pop, ambient\nelectronic, Turkish pop, cinematic\nelectronic, Turkish pop, dance\nelectronic, Turkish pop, deep house\nelectronic, Turkish pop, flamenco fusion\nelectronic, Turkish pop, fusion\nelectronic, Turkish pop, lo-fi\nelectronic, Turkish pop, melancholic\nelectronic, Turkish pop, mid-tempo\nelectronic, Turkish pop, political anthem\nelectronic, Turkish pop, synth rock\nelectronic, Turkish pop, synthwave\nelectronic, Turkish pop, trap\nelectronic, Turkish pop, world music\nelectronic, Turkish rap, ambient\nelectronic, Turkish rap, club\nelectronic, Turkish saz, fusion\nelectronic, Turkish spiritual, fusion\nelectronic, Turkish, Arabic\nelectronic, Turkish, Middle Eastern\nelectronic, Turkish, ambient\nelectronic, Turkish, cinematic\nelectronic, Turkish, deep house\nelectronic, Turkish, experimental\nelectronic, Turkish, melancholic\nelectronic, Turkish, political anthem\nelectronic, UK garage, R&B\nelectronic, UK garage, ambient\nelectronic, UK garage, lo-fi\nelectronic, UK rap, glitch\nelectronic, Ukrainian pop, cinematic\nelectronic, Ukrainian, cinematic\nelectronic, Ukrainian, epic\nelectronic, Vietnamese fusion, deep house\nelectronic, Vietnamese vocal, ambient\nelectronic, Vocaloid, Arabic synth\nelectronic, Vocaloid, Asian pop\nelectronic, Vocaloid, EDM\nelectronic, Vocaloid, ambient\nelectronic, Vocaloid, chiptune\nelectronic, Vocaloid, future bass\nelectronic, Vocaloid, glitch\nelectronic, Vocaloid, hyperpop\nelectronic, Vocaloid, novelty\nelectronic, Vocaloid, synthpop\nelectronic, Vocaloid, synthwave\nelectronic, acid house, ambient\nelectronic, acid house, chiptune\nelectronic, acid techno, breakbeat\nelectronic, afrobeat, ambient\nelectronic, afrobeat, dream pop\nelectronic, afrobeats, ambient\nelectronic, afrobeats, anthemic\nelectronic, afrobeats, chiptune\nelectronic, afrobeats, dance\nelectronic, afrobeats, video game music\nelectronic, aggressive, Chinese EDM\nelectronic, aggressive, Chinese rap\nelectronic, aggressive, Chinese trap\nelectronic, aggressive, Middle Eastern\nelectronic, aggressive, Middle Eastern fusion\nelectronic, aggressive, South Asian fusion\nelectronic, aggressive, Vocaloid\nelectronic, aggressive, anthemic\nelectronic, aggressive, bitcrushed\nelectronic, aggressive, breakbeat\nelectronic, aggressive, chiptune\nelectronic, aggressive, cinematic\nelectronic, aggressive, competitive\nelectronic, aggressive, cyberpunk\nelectronic, aggressive, dance\nelectronic, aggressive, futuristic\nelectronic, aggressive, glitch\nelectronic, aggressive, high-energy\nelectronic, aggressive, industrial\nelectronic, aggressive, instrumental\nelectronic, aggressive, rave\nelectronic, aggressive, synthwave\nelectronic, aggressive, techno\nelectronic, aggressive, trap\nelectronic, aggressive, world fusion\nelectronic, aggro, Middle Eastern fusion\nelectronic, aggro, Middle Eastern hip hop\nelectronic, aggro, Pinoy techno\nelectronic, agressive, Turkish folk\nelectronic, ambient house\nelectronic, ambient pop\nelectronic, ambient pop, C-pop\nelectronic, ambient pop, Catalan indie\nelectronic, ambient pop, trap\nelectronic, ambient rock, retro synth\nelectronic, ambient techno\nelectronic, ambient techno, experimental\nelectronic, ambient techno, glitch\nelectronic, ambient techno, world fusion\nelectronic, ambient trap\nelectronic, ambient trap, Latin pop\nelectronic, ambient, Arabic fusion\nelectronic, ambient, Arabic hip hop\nelectronic, ambient, Arabic pop\nelectronic, ambient, Arabic soul\nelectronic, ambient, Arabic synth\nelectronic, ambient, Asian fusion\nelectronic, ambient, Azerbaijani pop\nelectronic, ambient, Bengali\nelectronic, ambient, Bengali pop\nelectronic, ambient, Brazilian pop\nelectronic, ambient, C-pop\nelectronic, ambient, Central Asian\nelectronic, ambient, Chinese experimental\nelectronic, ambient, Chinese fusion\nelectronic, ambient, Chinese traditional\nelectronic, ambient, EDM\nelectronic, ambient, East Asian\nelectronic, ambient, Finnish pop\nelectronic, ambient, French choral\nelectronic, ambient, French indie\nelectronic, ambient, French pop\nelectronic, ambient, French spoken word\nelectronic, ambient, German pop\nelectronic, ambient, Greek pop\nelectronic, ambient, Hebrew pop\nelectronic, ambient, Hebrew vocal\nelectronic, ambient, Hindi pop\nelectronic, ambient, Hindi soul\nelectronic, ambient, Hungarian pop\nelectronic, ambient, Hungarian rock\nelectronic, ambient, Indian classical\nelectronic, ambient, Indian electronica\nelectronic, ambient, Indian fusion\nelectronic, ambient, Italian indie\nelectronic, ambient, Italian pop\nelectronic, ambient, Italian rap\nelectronic, ambient, J-pop\nelectronic, ambient, J-rap\nelectronic, ambient, Japanese pop\nelectronic, ambient, Kazakh folk\nelectronic, ambient, Latin\nelectronic, ambient, Latin house\nelectronic, ambient, Latin pop\nelectronic, ambient, Latin techno\nelectronic, ambient, Lithuanian folk\nelectronic, ambient, Lithuanian pop\nelectronic, ambient, Malayalam pop\nelectronic, ambient, Mandopop\nelectronic, ambient, Middle Eastern\nelectronic, ambient, Middle Eastern fusion\nelectronic, ambient, Mongolian folk\nelectronic, ambient, Nordic dark wave\nelectronic, ambient, North African\nelectronic, ambient, Persian vocal\nelectronic, ambient, Punjabi fusion\nelectronic, ambient, R&B\nelectronic, ambient, Romanian pop\nelectronic, ambient, Russian opera\nelectronic, ambient, Russian pop\nelectronic, ambient, Russian vocal\nelectronic, ambient, Sinhala pop\nelectronic, ambient, Slovak hip hop\nelectronic, ambient, South Asian\nelectronic, ambient, South Asian folk\nelectronic, ambient, South Asian fusion\nelectronic, ambient, Spanish-influenced\nelectronic, ambient, Tamil fusion\nelectronic, ambient, Tibetan chant\nelectronic, ambient, Turkish folk\nelectronic, ambient, Turkish melancholic\nelectronic, ambient, Turkish pop\nelectronic, ambient, Turkish spoken word\nelectronic, ambient, UK house\nelectronic, ambient, Ukrainian pop\nelectronic, ambient, Vietnamese trap\nelectronic, ambient, Vocaloid\nelectronic, ambient, acid house\nelectronic, ambient, alternative\nelectronic, ambient, ancient style\nelectronic, ambient, anthemic\nelectronic, ambient, art pop\nelectronic, ambient, bilingual\nelectronic, ambient, bossa nova\nelectronic, ambient, breakbeat\nelectronic, ambient, breakcore\nelectronic, ambient, chillwave\nelectronic, ambient, chiptune\nelectronic, ambient, choral\nelectronic, ambient, cinematic\nelectronic, ambient, city pop\nelectronic, ambient, cyberpunk\nelectronic, ambient, dance\nelectronic, ambient, dark hip hop\nelectronic, ambient, dark pop\nelectronic, ambient, dark wave\nelectronic, ambient, deep house\nelectronic, ambient, devotional\nelectronic, ambient, downtempo\nelectronic, ambient, dream pop\nelectronic, ambient, drum and bass\nelectronic, ambient, dubstep\nelectronic, ambient, dystopian\nelectronic, ambient, emotional\nelectronic, ambient, epic\nelectronic, ambient, ethereal\nelectronic, ambient, ethereal pop\nelectronic, ambient, euphoric\nelectronic, ambient, experimental\nelectronic, ambient, funk\nelectronic, ambient, future bass\nelectronic, ambient, future house\nelectronic, ambient, future pop\nelectronic, ambient, glitch\nelectronic, ambient, hardstyle\nelectronic, ambient, hip hop\nelectronic, ambient, hip-hop\nelectronic, ambient, hopeful\nelectronic, ambient, hypnotic\nelectronic, ambient, indie\nelectronic, ambient, industrial\nelectronic, ambient, industrial rock\nelectronic, ambient, jazzy\nelectronic, ambient, lo-fi\nelectronic, ambient, mantra\nelectronic, ambient, melancholic\nelectronic, ambient, melodic\nelectronic, ambient, mid-tempo bass\nelectronic, ambient, minimal techno\nelectronic, ambient, moombahton\nelectronic, ambient, mystical\nelectronic, ambient, nu-metal\nelectronic, ambient, political\nelectronic, ambient, pop\nelectronic, ambient, post-rock\nelectronic, ambient, progressive house\nelectronic, ambient, rave\nelectronic, ambient, rhythmic\nelectronic, ambient, ritual\nelectronic, ambient, ritual techno\nelectronic, ambient, sci-fi\nelectronic, ambient, shoegaze\nelectronic, ambient, soul\nelectronic, ambient, spiritual\nelectronic, ambient, synthpop\nelectronic, ambient, synthwave\nelectronic, ambient, tech house\nelectronic, ambient, techno\nelectronic, ambient, traditional Chinese\nelectronic, ambient, traditional East Asian\nelectronic, ambient, traditional fusion\nelectronic, ambient, trance\nelectronic, ambient, trap\nelectronic, ambient, trap-metal\nelectronic, ambient, tribal\nelectronic, ambient, trip-hop\nelectronic, ambient, urban\nelectronic, ambient, video game\nelectronic, ambient, video game music\nelectronic, ambient, video game soundtrack\nelectronic, ambient, vocal house\nelectronic, ambient, world\nelectronic, ambient, world fusion\nelectronic, ambient, world music\nelectronic, ancient style, trap\nelectronic, anime soundtrack, Mandarin pop\nelectronic, anime theme, aggressive\nelectronic, anime theme, glitch\nelectronic, anime, JRPG\nelectronic, anime, Middle Eastern\nelectronic, anime, Vocaloid\nelectronic, anime, cinematic\nelectronic, anime, dance\nelectronic, anime, rhythm game\nelectronic, anime, synthwave\nelectronic, anime, video game\nelectronic, anthemic pop, cinematic\nelectronic, anthemic, EDM\nelectronic, anthemic, Hebrew pop\nelectronic, anthemic, Hindi fusion\nelectronic, anthemic, Lithuanian\nelectronic, anthemic, Russian pop\nelectronic, anthemic, Tibetan\nelectronic, anthemic, Urdu pop\nelectronic, anthemic, aggressive\nelectronic, anthemic, ambient\nelectronic, anthemic, atmospheric\nelectronic, anthemic, children's choir\nelectronic, anthemic, cinematic\nelectronic, anthemic, dance\nelectronic, anthemic, dreamy\nelectronic, anthemic, ethnic\nelectronic, anthemic, female vocal\nelectronic, anthemic, gaming\nelectronic, anthemic, hard dance\nelectronic, anthemic, high-energy\nelectronic, anthemic, liturgical\nelectronic, anthemic, lo-fi\nelectronic, anthemic, militant\nelectronic, anthemic, oriental fusion\nelectronic, anthemic, rave\nelectronic, anthemic, ritualistic\nelectronic, anthemic, social justice\nelectronic, anthemic, synth-driven\nelectronic, anthemic, synthpop\nelectronic, anthemic, taiko\nelectronic, anthemic, trap\nelectronic, anthemic, tribal\nelectronic, arabic fusion, synthwave\nelectronic, arabic synthwave\nelectronic, arabsynth, chiptune\nelectronic, arpeggiated, Middle Eastern\nelectronic, arpeggiated, cinematic\nelectronic, art pop, French indie\nelectronic, art pop, German pop\nelectronic, art pop, Hebrew vocal\nelectronic, art pop, Italian\nelectronic, art pop, Middle Eastern fusion\nelectronic, art pop, Turkish ambient\nelectronic, art pop, cinematic\nelectronic, art pop, experimental\nelectronic, art pop, industrial\nelectronic, art pop, lo-fi\nelectronic, art pop, trap\nelectronic, art rock, video game boss music\nelectronic, artcore, Japanese fusion\nelectronic, baile funk, moombahton\nelectronic, baile funk, quirky\nelectronic, bansuri, romantic\nelectronic, baroque pop, Halloween\nelectronic, baroque pop, dubstep\nelectronic, baroque pop, experimental\nelectronic, baroque, ambient\nelectronic, baroque, cinematic\nelectronic, baroque, industrial\nelectronic, baroque, instrumental\nelectronic, baroque, melancholic\nelectronic, baroque, synthwave\nelectronic, baroque, techno\nelectronic, baroque, video game\nelectronic, bass music, Middle Eastern\nelectronic, bass music, cinematic\nelectronic, battle rap, future bass\nelectronic, bengali, upbeat\nelectronic, bhajan, dance\nelectronic, bhajan, world music\nelectronic, bhangra, dance\nelectronic, bhangra, trap\nelectronic, big beat, IDM\nelectronic, big beat, ambient\nelectronic, big beat, cinematic\nelectronic, big beat, synthwave\nelectronic, big room house, C-pop\nelectronic, big room, chiptune\nelectronic, big room, synthwave\nelectronic, bilingual, deep house\nelectronic, bilingual, synthwave\nelectronic, body percussion, dance\nelectronic, bossa nova, hip-hop\nelectronic, bossa nova, instrumental\nelectronic, bossa nova, latin\nelectronic, brass, anthemic\nelectronic, brass, cinematic\nelectronic, brass, high-energy\nelectronic, breakbeat, 80s synth\nelectronic, breakbeat, Balkan fusion\nelectronic, breakbeat, C-pop\nelectronic, breakbeat, Cantopop\nelectronic, breakbeat, Hungarian vocal\nelectronic, breakbeat, Indonesian hip hop\nelectronic, breakbeat, J-pop\nelectronic, breakbeat, Latin house\nelectronic, breakbeat, Middle Eastern fusion\nelectronic, breakbeat, acid house\nelectronic, breakbeat, ambient\nelectronic, breakbeat, anime\nelectronic, breakbeat, arpeggiated\nelectronic, breakbeat, chiptune\nelectronic, breakbeat, cinematic\nelectronic, breakbeat, ethnic fusion\nelectronic, breakbeat, free-jazz\nelectronic, breakbeat, future bass\nelectronic, breakbeat, future pop\nelectronic, breakbeat, futurepop\nelectronic, breakbeat, glitch\nelectronic, breakbeat, gritty\nelectronic, breakbeat, hardstyle\nelectronic, breakbeat, hip hop\nelectronic, breakbeat, house\nelectronic, breakbeat, industrial\nelectronic, breakbeat, instrumental\nelectronic, breakbeat, jazz fusion\nelectronic, breakbeat, neurofunk\nelectronic, breakbeat, pop\nelectronic, breakbeat, synthwave\nelectronic, breakbeat, techno\nelectronic, breakbeat, video game\nelectronic, breakbeat, video game soundtrack\nelectronic, breakbeat, vocal house\nelectronic, breakbeat, world music\nelectronic, breakcore, FM synth\nelectronic, breakcore, R&B\nelectronic, breakcore, ambient\nelectronic, breakcore, chiptune\nelectronic, breakcore, cinematic\nelectronic, breakcore, glitch\nelectronic, breakcore, narrative\nelectronic, breakcore, synthwave\nelectronic, brostep, chiptune\nelectronic, brostep, complextro\nelectronic, brostep, hardstyle\nelectronic, brostep, synth-pop\nelectronic, brostep, trance\nelectronic, cabaret, cinematic\nelectronic, chant, deep house\nelectronic, children's choir, synth pop\nelectronic, children's, Indian\nelectronic, chill trap\nelectronic, chillstep, glitch\nelectronic, chillwave, Latin pop\nelectronic, chillwave, Latin synth\nelectronic, chillwave, synthwave\nelectronic, chiptune\nelectronic, chiptune, 8-bit\nelectronic, chiptune, 80s synth\nelectronic, chiptune, 90s video game\nelectronic, chiptune, Afro-Latin\nelectronic, chiptune, Arabic hip hop\nelectronic, chiptune, Arabic techno\nelectronic, chiptune, Balkan fusion\nelectronic, chiptune, Bollywood\nelectronic, chiptune, C-pop\nelectronic, chiptune, EBM\nelectronic, chiptune, EDM\nelectronic, chiptune, Greek pop\nelectronic, chiptune, Hebrew pop\nelectronic, chiptune, Hungarian pop\nelectronic, chiptune, IDM\nelectronic, chiptune, Indian folk\nelectronic, chiptune, Indian fusion\nelectronic, chiptune, Indian pop\nelectronic, chiptune, Italian rap\nelectronic, chiptune, Italo-dance\nelectronic, chiptune, J-core\nelectronic, chiptune, J-pop\nelectronic, chiptune, Latin dance\nelectronic, chiptune, Latin hip hop\nelectronic, chiptune, Latin pop\nelectronic, chiptune, Malayalam hip hop\nelectronic, chiptune, Mandarin pop\nelectronic, chiptune, Middle Eastern\nelectronic, chiptune, Middle Eastern fusion\nelectronic, chiptune, Middle Eastern pop\nelectronic, chiptune, North African\nelectronic, chiptune, Russian rap\nelectronic, chiptune, Russian spoken word\nelectronic, chiptune, South Asian\nelectronic, chiptune, South Asian folk\nelectronic, chiptune, South Asian fusion\nelectronic, chiptune, Telugu hip hop\nelectronic, chiptune, Thai hip hop\nelectronic, chiptune, Turkish pop\nelectronic, chiptune, Uzbek pop\nelectronic, chiptune, Vocaloid\nelectronic, chiptune, acid house\nelectronic, chiptune, aggressive\nelectronic, chiptune, ambient\nelectronic, chiptune, ambient house\nelectronic, chiptune, ambient techno\nelectronic, chiptune, anime\nelectronic, chiptune, anthemic\nelectronic, chiptune, art rock\nelectronic, chiptune, baroque\nelectronic, chiptune, big beat\nelectronic, chiptune, breakbeat\nelectronic, chiptune, breakcore\nelectronic, chiptune, cantopop\nelectronic, chiptune, children's\nelectronic, chiptune, cinematic\nelectronic, chiptune, club\nelectronic, chiptune, comedic\nelectronic, chiptune, comedy\nelectronic, chiptune, complextro\nelectronic, chiptune, cyberpunk\nelectronic, chiptune, dance\nelectronic, chiptune, dark ambient\nelectronic, chiptune, deep house\nelectronic, chiptune, demoscene\nelectronic, chiptune, dubstep\nelectronic, chiptune, electro\nelectronic, chiptune, electro-funk\nelectronic, chiptune, epic\nelectronic, chiptune, experimental\nelectronic, chiptune, festival\nelectronic, chiptune, folk\nelectronic, chiptune, folk dance\nelectronic, chiptune, folk fusion\nelectronic, chiptune, funk\nelectronic, chiptune, future bass\nelectronic, chiptune, future funk\nelectronic, chiptune, gabber\nelectronic, chiptune, game music\nelectronic, chiptune, ghazal\nelectronic, chiptune, glitch\nelectronic, chiptune, gospel\nelectronic, chiptune, hard dance\nelectronic, chiptune, hard rock\nelectronic, chiptune, hard trance\nelectronic, chiptune, hardcore\nelectronic, chiptune, hardstyle\nelectronic, chiptune, hardstyle, trance\nelectronic, chiptune, high-energy\nelectronic, chiptune, hip hop\nelectronic, chiptune, hip-hop\nelectronic, chiptune, house\nelectronic, chiptune, hype\nelectronic, chiptune, hyperpop\nelectronic, chiptune, industrial\nelectronic, chiptune, industrial dance-rock\nelectronic, chiptune, instrumental\nelectronic, chiptune, lo-fi\nelectronic, chiptune, lo-fi hip hop\nelectronic, chiptune, melancholic\nelectronic, chiptune, melancholic pop\nelectronic, chiptune, minimal\nelectronic, chiptune, minimal synth\nelectronic, chiptune, modern classical\nelectronic, chiptune, operatic\nelectronic, chiptune, orchestral\nelectronic, chiptune, party\nelectronic, chiptune, polyrhythmic\nelectronic, chiptune, pop\nelectronic, chiptune, pop-punk\nelectronic, chiptune, post-rock\nelectronic, chiptune, progressive\nelectronic, chiptune, progressive house\nelectronic, chiptune, protest\nelectronic, chiptune, punk\nelectronic, chiptune, quirky\nelectronic, chiptune, rap\nelectronic, chiptune, rave\nelectronic, chiptune, retro\nelectronic, chiptune, retro game\nelectronic, chiptune, retro house\nelectronic, chiptune, retro-futuristic\nelectronic, chiptune, ritual ambient\nelectronic, chiptune, satirical\nelectronic, chiptune, soul\nelectronic, chiptune, synth-pop\nelectronic, chiptune, synthpop\nelectronic, chiptune, synthwave\nelectronic, chiptune, techno\nelectronic, chiptune, theatrical pop\nelectronic, chiptune, trance\nelectronic, chiptune, trap\nelectronic, chiptune, upbeat\nelectronic, chiptune, urban pop\nelectronic, chiptune, urbano\nelectronic, chiptune, vaporwave\nelectronic, chiptune, video game\nelectronic, chiptune, video game music\nelectronic, chiptune, video game soundtrack\nelectronic, chiptune, vocaloid\nelectronic, chiptune, world fusion\nelectronic, chiptune, world music\nelectronic, choral, Afro-electronic\nelectronic, choral, French pop\nelectronic, choral, ambient\nelectronic, choral, cinematic\nelectronic, choral, hip hop\nelectronic, choral, world music\nelectronic, cinematic\nelectronic, cinematic, Afro-electronic\nelectronic, cinematic, Arabic fusion\nelectronic, cinematic, Arabic pop\nelectronic, cinematic, Armenian\nelectronic, cinematic, Asian fusion\nelectronic, cinematic, Balkan fusion\nelectronic, cinematic, Brazilian\nelectronic, cinematic, C-pop\nelectronic, cinematic, Central Asian\nelectronic, cinematic, Central Asian folk\nelectronic, cinematic, Chinese\nelectronic, cinematic, Chinese fusion\nelectronic, cinematic, Chinese hip hop\nelectronic, cinematic, Chinese traditional\nelectronic, cinematic, Chinese-style\nelectronic, cinematic, EDM\nelectronic, cinematic, East Asian\nelectronic, cinematic, East Asian fusion\nelectronic, cinematic, Eastern European\nelectronic, cinematic, French chanson\nelectronic, cinematic, French pop\nelectronic, cinematic, German pop\nelectronic, cinematic, Greek\nelectronic, cinematic, Greek pop\nelectronic, cinematic, Hebrew pop\nelectronic, cinematic, Hebrew vocal\nelectronic, cinematic, Hindi hip hop\nelectronic, cinematic, Hindi pop\nelectronic, cinematic, Hungarian pop\nelectronic, cinematic, Indian classical\nelectronic, cinematic, Indian fusion\nelectronic, cinematic, Italian opera\nelectronic, cinematic, Italian pop\nelectronic, cinematic, Italo-disco\nelectronic, cinematic, J-pop\nelectronic, cinematic, Javanese fusion\nelectronic, cinematic, K-pop\nelectronic, cinematic, Kazakh pop\nelectronic, cinematic, Latin\nelectronic, cinematic, Latin pop\nelectronic, cinematic, Latin pop-rock\nelectronic, cinematic, Mandopop\nelectronic, cinematic, Middle Eastern\nelectronic, cinematic, Middle Eastern fusion\nelectronic, cinematic, Mongolian fusion\nelectronic, cinematic, Persian\nelectronic, cinematic, Polish pop\nelectronic, cinematic, Punjabi pop\nelectronic, cinematic, Russian hip hop\nelectronic, cinematic, Russian pop\nelectronic, cinematic, Russian rap\nelectronic, cinematic, Sinhala pop\nelectronic, cinematic, South Asian\nelectronic, cinematic, South Asian fusion\nelectronic, cinematic, Spanish pop\nelectronic, cinematic, Spanish-style\nelectronic, cinematic, Telugu pop\nelectronic, cinematic, Thai pop\nelectronic, cinematic, Turkish\nelectronic, cinematic, Turkish folk\nelectronic, cinematic, Turkish fusion\nelectronic, cinematic, Turkish pop\nelectronic, cinematic, Uzbek pop\nelectronic, cinematic, Vocaloid\nelectronic, cinematic, action\nelectronic, cinematic, aggressive\nelectronic, cinematic, ambient\nelectronic, cinematic, ancient style\nelectronic, cinematic, anime\nelectronic, cinematic, anthemic\nelectronic, cinematic, art pop\nelectronic, cinematic, bass\nelectronic, cinematic, big beat\nelectronic, cinematic, bilingual\nelectronic, cinematic, breakbeat\nelectronic, cinematic, breakcore\nelectronic, cinematic, chiptune\nelectronic, cinematic, choral\nelectronic, cinematic, club\nelectronic, cinematic, complextro\nelectronic, cinematic, cyberpunk\nelectronic, cinematic, dance\nelectronic, cinematic, dark pop\nelectronic, cinematic, dark wave\nelectronic, cinematic, deep house\nelectronic, cinematic, dramatic\nelectronic, cinematic, dream pop\nelectronic, cinematic, drum and bass\nelectronic, cinematic, dubstep\nelectronic, cinematic, duet\nelectronic, cinematic, dystopian\nelectronic, cinematic, electro\nelectronic, cinematic, electro-funk\nelectronic, cinematic, emotional\nelectronic, cinematic, epic\nelectronic, cinematic, ethereal\nelectronic, cinematic, ethnic\nelectronic, cinematic, ethnic fusion\nelectronic, cinematic, ethno-pop\nelectronic, cinematic, euphoric\nelectronic, cinematic, experimental\nelectronic, cinematic, flamenco\nelectronic, cinematic, folk\nelectronic, cinematic, folktronica\nelectronic, cinematic, funk\nelectronic, cinematic, future\nelectronic, cinematic, future bass\nelectronic, cinematic, future house\nelectronic, cinematic, future pop\nelectronic, cinematic, futurecore\nelectronic, cinematic, game music\nelectronic, cinematic, genre-bending\nelectronic, cinematic, glitch\nelectronic, cinematic, gospel\nelectronic, cinematic, guzheng\nelectronic, cinematic, hard house\nelectronic, cinematic, hard-hitting\nelectronic, cinematic, hardstyle\nelectronic, cinematic, high-energy\nelectronic, cinematic, hip hop\nelectronic, cinematic, hip-hop\nelectronic, cinematic, hybrid trap\nelectronic, cinematic, indie pop\nelectronic, cinematic, industrial\nelectronic, cinematic, lo-fi\nelectronic, cinematic, lo-fi hip hop\nelectronic, cinematic, melancholic\nelectronic, cinematic, metalcore\nelectronic, cinematic, mystical\nelectronic, cinematic, mythic\nelectronic, cinematic, neurofunk\nelectronic, cinematic, nu-metal\nelectronic, cinematic, operatic\nelectronic, cinematic, orchestral\nelectronic, cinematic, oriental\nelectronic, cinematic, oriental style\nelectronic, cinematic, pop\nelectronic, cinematic, progressive\nelectronic, cinematic, progressive trance\nelectronic, cinematic, rap\nelectronic, cinematic, retro synth\nelectronic, cinematic, retro-futuristic\nelectronic, cinematic, revolutionary\nelectronic, cinematic, ritual techno\nelectronic, cinematic, rock\nelectronic, cinematic, sci-fi\nelectronic, cinematic, soul\nelectronic, cinematic, soulful\nelectronic, cinematic, spy-thriller\nelectronic, cinematic, synthwave\nelectronic, cinematic, tech house\nelectronic, cinematic, techno\nelectronic, cinematic, theatrical\nelectronic, cinematic, traditional East Asian\nelectronic, cinematic, traditional fusion\nelectronic, cinematic, trailer\nelectronic, cinematic, trailer music\nelectronic, cinematic, trance\nelectronic, cinematic, trap\nelectronic, cinematic, tribal\nelectronic, cinematic, trip-hop\nelectronic, cinematic, uplifting\nelectronic, cinematic, video game\nelectronic, cinematic, video game soundtrack\nelectronic, cinematic, vocal house\nelectronic, cinematic, workout\nelectronic, cinematic, world beat\nelectronic, cinematic, world fusion\nelectronic, cinematic, world music\nelectronic, city pop, future funk\nelectronic, classical fusion, drum and bass\nelectronic, classical, video game\nelectronic, club, Czech rap\nelectronic, club, Middle Eastern fusion\nelectronic, club, aggressive\nelectronic, club, bass-heavy\nelectronic, club, deep house\nelectronic, club, ethnic fusion\nelectronic, club, hip hop\nelectronic, club, multilingual\nelectronic, club, trap\nelectronic, color bass, ambient\nelectronic, color bass, melodic riddim\nelectronic, comedy, regional Indian\nelectronic, complexo, synthwave\nelectronic, complexro, ambient\nelectronic, complextro, Middle Eastern fusion\nelectronic, complextro, Vocaloid\nelectronic, complextro, ambient\nelectronic, complextro, anime\nelectronic, complextro, anthemic\nelectronic, complextro, atmospheric\nelectronic, complextro, cinematic\nelectronic, complextro, cyberpunk\nelectronic, complextro, dubstep\nelectronic, complextro, hardstyle\nelectronic, complextro, melodic\nelectronic, complextro, trance\nelectronic, corporate pop\nelectronic, cumbia, moombahton\nelectronic, cumbia, reggaeton\nelectronic, cumbia, tango\nelectronic, cute, lo-fi\nelectronic, cyberpunk\nelectronic, cyberpunk, C-pop\nelectronic, cyberpunk, EBM\nelectronic, cyberpunk, Latin pop\nelectronic, cyberpunk, Mandarin pop\nelectronic, cyberpunk, Mandarin rap\nelectronic, cyberpunk, action soundtrack\nelectronic, cyberpunk, aggressive\nelectronic, cyberpunk, ambient\nelectronic, cyberpunk, breakbeat\nelectronic, cyberpunk, cinematic\nelectronic, cyberpunk, dance\nelectronic, cyberpunk, deep house\nelectronic, cyberpunk, future bass\nelectronic, cyberpunk, glitch\nelectronic, cyberpunk, hard dance\nelectronic, cyberpunk, hard house\nelectronic, cyberpunk, hard techno\nelectronic, cyberpunk, hardcore\nelectronic, cyberpunk, high-energy\nelectronic, cyberpunk, hip hop\nelectronic, cyberpunk, industrial\nelectronic, cyberpunk, instrumental\nelectronic, cyberpunk, progressive\nelectronic, cyberpunk, rave\nelectronic, cyberpunk, synthwave\nelectronic, cyberpunk, techno\nelectronic, cyberpunk, trap\nelectronic, cyberpunk, video game\nelectronic, cyberpunk, video game soundtrack\nelectronic, dabke, cinematic\nelectronic, dance, Afro house\nelectronic, dance, Afrobeat\nelectronic, dance, Arabic fusion\nelectronic, dance, Arabic house\nelectronic, dance, Asian fusion\nelectronic, dance, Azerbaijani\nelectronic, dance, EDM\nelectronic, dance, East Asian\nelectronic, dance, East Asian fusion\nelectronic, dance, Haitian Creole\nelectronic, dance, Hebrew hip hop\nelectronic, dance, Hebrew pop\nelectronic, dance, Holi\nelectronic, dance, Indian fusion\nelectronic, dance, Italo house\nelectronic, dance, Latin\nelectronic, dance, Latin house\nelectronic, dance, Middle Eastern fusion\nelectronic, dance, North African\nelectronic, dance, North African fusion\nelectronic, dance, Rai\nelectronic, dance, Sinhala hip hop\nelectronic, dance, Sinhala pop\nelectronic, dance, South Asian\nelectronic, dance, South Asian fusion\nelectronic, dance, accordion\nelectronic, dance, ambient\nelectronic, dance, ambient techno\nelectronic, dance, anthemic\nelectronic, dance, bilingual\nelectronic, dance, breakbeat\nelectronic, dance, choral\nelectronic, dance, cinematic\nelectronic, dance, club\nelectronic, dance, ethnic fusion\nelectronic, dance, experimental\nelectronic, dance, folktronica\nelectronic, dance, fusion\nelectronic, dance, glitch\nelectronic, dance, hyped\nelectronic, dance, hǎnmài\nelectronic, dance, lo-fi\nelectronic, dance, multilingual\nelectronic, dance, oriental house\nelectronic, dance, oriental synth\nelectronic, dance, percussion\nelectronic, dance, pop\nelectronic, dance, protest\nelectronic, dance, rave\nelectronic, dance, reggae fusion\nelectronic, dance, saxophone\nelectronic, dance, soulful\nelectronic, dance, steel pan\nelectronic, dance, synth\nelectronic, dance, synthpop\nelectronic, dance, synthwave\nelectronic, dance, tropical house\nelectronic, dance, upbeat\nelectronic, dance, workout\nelectronic, dance, world fusion\nelectronic, dance, world music\nelectronic, dance-pop, Azerbaijani\nelectronic, dance-pop, Balkan\nelectronic, dance-pop, Chinese techno\nelectronic, dance-pop, Middle Eastern\nelectronic, dance-pop, ambient\nelectronic, dance-pop, cinematic\nelectronic, dance-pop, hip-house, Eurodance\nelectronic, dance-pop, new jack swing\nelectronic, dance-pop, retro\nelectronic, dance-pop, techno\nelectronic, dancehall, Middle Eastern fusion\nelectronic, dancehall, R&B\nelectronic, dancehall, Southeast Asian pop\nelectronic, dancehall, afrobeat\nelectronic, dancehall, ambient\nelectronic, dancehall, reggaeton\nelectronic, dancehall, trap\nelectronic, darbuka, Arabic fusion\nelectronic, darbuka, Middle Eastern\nelectronic, darbuka, hype\nelectronic, darbuka, zurna\nelectronic, dark ambient\nelectronic, dark ambient, Latin experimental\nelectronic, dark ambient, Middle Eastern fusion\nelectronic, dark ambient, Middle Eastern synth\nelectronic, dark ambient, Turkish fusion\nelectronic, dark ambient, breakbeat\nelectronic, dark ambient, cinematic\nelectronic, dark ambient, club\nelectronic, dark ambient, dubstep\nelectronic, dark ambient, experimental\nelectronic, dark ambient, flamenco fusion\nelectronic, dark ambient, glitch\nelectronic, dark ambient, hardstyle\nelectronic, dark ambient, industrial\nelectronic, dark ambient, industrial pop\nelectronic, dark ambient, techno\nelectronic, dark ambient, trap\nelectronic, dark pop\nelectronic, dark pop, Eastern European\nelectronic, dark pop, Latin\nelectronic, dark pop, Romanian\nelectronic, dark pop, ambient\nelectronic, dark pop, cinematic\nelectronic, dark pop, complextro\nelectronic, dark pop, dubstep\nelectronic, dark pop, experimental\nelectronic, dark pop, glitch\nelectronic, dark pop, hardstyle\nelectronic, dark pop, hyperpop\nelectronic, dark pop, industrial\nelectronic, dark pop, synthwave\nelectronic, dark pop, trap\nelectronic, dark pop, urban\nelectronic, dark pop, video game\nelectronic, dark synth, retro-futuristic\nelectronic, dark techno\nelectronic, dark techno, Middle Eastern\nelectronic, dark techno, world fusion\nelectronic, dark wave, Brazilian techno\nelectronic, dark wave, French pop\nelectronic, dark wave, French synth\nelectronic, dark wave, Latin futurism\nelectronic, dark wave, Middle Eastern fusion\nelectronic, dark wave, Persian rap\nelectronic, dark wave, Polish hip hop\nelectronic, dark wave, Romanian pop\nelectronic, dark wave, Russian pop\nelectronic, dark wave, Russian rap\nelectronic, dark wave, Russian synth\nelectronic, dark wave, Russian vocal\nelectronic, dark wave, Ukrainian hip hop\nelectronic, dark wave, ambient\nelectronic, dark wave, breakcore\nelectronic, dark wave, choral\nelectronic, dark wave, cinematic\nelectronic, dark wave, club\nelectronic, dark wave, cyberpunk\nelectronic, dark wave, ethereal\nelectronic, dark wave, ethnic techno\nelectronic, dark wave, experimental\nelectronic, dark wave, future house\nelectronic, dark wave, future pop\nelectronic, dark wave, glitch\nelectronic, dark wave, hardstyle\nelectronic, dark wave, hip hop\nelectronic, dark wave, industrial\nelectronic, dark wave, militant anthemic\nelectronic, dark wave, retro-futuristic\nelectronic, dark wave, synthpop\nelectronic, dark wave, synthwave\nelectronic, dark wave, techno\nelectronic, dark wave, tribal house\nelectronic, dark wave, trip-hop\nelectronic, dark wave, video game\nelectronic, dark, cinematic\nelectronic, dark, epic\nelectronic, darkwave, EBM\nelectronic, darkwave, chiptune\nelectronic, darkwave, experimental\nelectronic, deep house, Afro-tech\nelectronic, deep house, Balkan-inspired\nelectronic, deep house, Eastern European\nelectronic, deep house, Latin\nelectronic, deep house, Latin fusion\nelectronic, deep house, Latin house\nelectronic, deep house, Latin pop\nelectronic, deep house, Latin techno\nelectronic, deep house, Latin trap\nelectronic, deep house, Latin-infused\nelectronic, deep house, Middle Eastern\nelectronic, deep house, Middle Eastern fusion\nelectronic, deep house, Polish synth\nelectronic, deep house, Polish vocal\nelectronic, deep house, Portuguese pop\nelectronic, deep house, Portuguese vocal\nelectronic, deep house, Russian spoken word\nelectronic, deep house, Russian techno\nelectronic, deep house, Russian vocal\nelectronic, deep house, acid house\nelectronic, deep house, ambient\nelectronic, deep house, ambient techno\nelectronic, deep house, chiptune\nelectronic, deep house, cinematic\nelectronic, deep house, club\nelectronic, deep house, ethnic\nelectronic, deep house, future bass\nelectronic, deep house, hardstyle\nelectronic, deep house, hypnotic\nelectronic, deep house, instrumental\nelectronic, deep house, klezmer\nelectronic, deep house, lo-fi\nelectronic, deep house, lo-fi hip hop\nelectronic, deep house, melancholic\nelectronic, deep house, oriental fusion\nelectronic, deep house, oriental synth\nelectronic, deep house, percussive\nelectronic, deep house, polyrhythmic\nelectronic, deep house, progressive\nelectronic, deep house, psychedelic\nelectronic, deep house, retro synth\nelectronic, deep house, soulful\nelectronic, deep house, synthwave\nelectronic, deep house, techno\nelectronic, deep house, trance\nelectronic, deep house, tribal\nelectronic, deep house, tribal techno\nelectronic, deep house, world fusion\nelectronic, deep house, world music\nelectronic, dembow, Israeli\nelectronic, dembow, Latin\nelectronic, dembow, Latin pop\nelectronic, dembow, ambient\nelectronic, dembow, chiptune\nelectronic, dembow, club\nelectronic, dembow, house\nelectronic, dembow, lo-fi\nelectronic, dembow, percussive\nelectronic, dembow, pop\nelectronic, dembow, quirky\nelectronic, dembow, synthpop\nelectronic, desert ambient, cinematic\nelectronic, desert pop, ambient\nelectronic, devotional, Bollywood\nelectronic, devotional, Indian fusion\nelectronic, devotional, chiptune\nelectronic, devotional, cinematic\nelectronic, devotional, hardstyle\nelectronic, devotional, world fusion\nelectronic, dhol, festival\nelectronic, dhol, folk\nelectronic, dhol, folk fusion\nelectronic, dhol, fusion\nelectronic, dhol, sitar\nelectronic, dholak, anthemic\nelectronic, dholak, high-energy\nelectronic, dholak, shehnai\nelectronic, dizi, modern Chinese\nelectronic, dramatic pop, trap\nelectronic, dramatic, Latin\nelectronic, dramatic, Turkish melancholy\nelectronic, dream house, ambient\nelectronic, dream pop, Brazilian funk\nelectronic, dream pop, C-pop\nelectronic, dream pop, Chinese avant-garde\nelectronic, dream pop, Chinese pop\nelectronic, dream pop, Czech indie\nelectronic, dream pop, EDM\nelectronic, dream pop, Eurodance\nelectronic, dream pop, French electronic\nelectronic, dream pop, French hip-hop\nelectronic, dream pop, French house\nelectronic, dream pop, French indie\nelectronic, dream pop, French pop\nelectronic, dream pop, German pop\nelectronic, dream pop, Hungarian pop\nelectronic, dream pop, IDM\nelectronic, dream pop, Indian fusion\nelectronic, dream pop, Italian hip hop\nelectronic, dream pop, Italian rock\nelectronic, dream pop, K-electronic\nelectronic, dream pop, K-pop\nelectronic, dream pop, Kazakh pop\nelectronic, dream pop, Latin\nelectronic, dream pop, Latin electronica\nelectronic, dream pop, Latin fusion\nelectronic, dream pop, Latin hip hop\nelectronic, dream pop, Latin house\nelectronic, dream pop, Latin pop\nelectronic, dream pop, Mandarin pop\nelectronic, dream pop, Mandarin rap\nelectronic, dream pop, Mandopop\nelectronic, dream pop, Russian pop\nelectronic, dream pop, Vietnamese pop\nelectronic, dream pop, ambient\nelectronic, dream pop, anthemic\nelectronic, dream pop, art pop\nelectronic, dream pop, big room house\nelectronic, dream pop, bilingual\nelectronic, dream pop, breakbeat\nelectronic, dream pop, breakcore\nelectronic, dream pop, chiptune\nelectronic, dream pop, cinematic\nelectronic, dream pop, dance\nelectronic, dream pop, drum and bass\nelectronic, dream pop, dubstep\nelectronic, dream pop, electro house\nelectronic, dream pop, eurodance\nelectronic, dream pop, future bass\nelectronic, dream pop, glitch\nelectronic, dream pop, hardstyle\nelectronic, dream pop, hip hop\nelectronic, dream pop, hip-hop\nelectronic, dream pop, hyperpop\nelectronic, dream pop, indie\nelectronic, dream pop, industrial\nelectronic, dream pop, lo-fi\nelectronic, dream pop, lo-fi hip hop\nelectronic, dream pop, post-rock\nelectronic, dream pop, reggaeton\nelectronic, dream pop, shoegaze\nelectronic, dream pop, soulful house\nelectronic, dream pop, space pop\nelectronic, dream pop, synthwave\nelectronic, dream pop, trance\nelectronic, dream pop, trap\nelectronic, dream pop, vaporwave\nelectronic, dream-pop, lo-fi hip hop\nelectronic, drum & bass, chiptune\nelectronic, drum & bass, trance\nelectronic, drum and bass\nelectronic, drum and bass, C-pop\nelectronic, drum and bass, Middle Eastern fusion\nelectronic, drum and bass, Romanian pop\nelectronic, drum and bass, UK grime\nelectronic, drum and bass, ambient\nelectronic, drum and bass, chiptune\nelectronic, drum and bass, cinematic\nelectronic, drum and bass, club\nelectronic, drum and bass, emotional\nelectronic, drum and bass, emotional vocal\nelectronic, drum and bass, glitch\nelectronic, drum and bass, hard house\nelectronic, drum and bass, lo-fi hip hop\nelectronic, drum and bass, metalcore\nelectronic, drum and bass, neurofunk\nelectronic, drum and bass, soul\nelectronic, drum and bass, steel pan\nelectronic, drum and bass, synth-pop\nelectronic, drum and bass, synthwave\nelectronic, drum and bass, vocal chop\nelectronic, drum and bass, vocal house\nelectronic, drum and bass, world fusion\nelectronic, dubstep, Arabic hip hop\nelectronic, dubstep, C-pop\nelectronic, dubstep, Czech rap\nelectronic, dubstep, EDM\nelectronic, dubstep, Latin hip hop\nelectronic, dubstep, Mandarin pop\nelectronic, dubstep, Middle Eastern\nelectronic, dubstep, Middle Eastern fusion\nelectronic, dubstep, UK grime\nelectronic, dubstep, UK rap\nelectronic, dubstep, aggressive\nelectronic, dubstep, aggro\nelectronic, dubstep, alternative rock\nelectronic, dubstep, ambient\nelectronic, dubstep, anthemic\nelectronic, dubstep, atmospheric\nelectronic, dubstep, breakbeat\nelectronic, dubstep, brostep\nelectronic, dubstep, chiptune\nelectronic, dubstep, cinematic\nelectronic, dubstep, color bass\nelectronic, dubstep, cyberpunk\nelectronic, dubstep, dancehall\nelectronic, dubstep, drum and bass\nelectronic, dubstep, emotional\nelectronic, dubstep, ethereal\nelectronic, dubstep, experimental\nelectronic, dubstep, future bass\nelectronic, dubstep, glitch\nelectronic, dubstep, hardstyle\nelectronic, dubstep, hip hop\nelectronic, dubstep, indie rock\nelectronic, dubstep, industrial\nelectronic, dubstep, lo-fi hip hop\nelectronic, dubstep, metalcore\nelectronic, dubstep, oriental\nelectronic, dubstep, pop\nelectronic, dubstep, pop-rock\nelectronic, dubstep, quirky\nelectronic, dubstep, reggae\nelectronic, dubstep, synth-pop\nelectronic, dubstep, synthpop\nelectronic, dubstep, trap\nelectronic, duduk, ambient\nelectronic, duduk, cinematic\nelectronic, duduk, high-energy\nelectronic, dystopian, anthemic\nelectronic, dystopian, cinematic\nelectronic, electro house, chiptune\nelectronic, electro house, cinematic\nelectronic, electro house, moombahton\nelectronic, electro, EBM\nelectronic, electro-funk, big beat\nelectronic, emotional dubstep, cinematic\nelectronic, emotional, ambient\nelectronic, emotional, dubstep\nelectronic, emotional, hardstyle\nelectronic, emotional, industrial\nelectronic, emotional, trap\nelectronic, empowerment, Caribbean\nelectronic, enka, traditional Japanese\nelectronic, epic, Azerbaijani folk\nelectronic, epic, Lithuanian\nelectronic, epic, Middle Eastern\nelectronic, epic, Middle Eastern fusion\nelectronic, epic, Russian\nelectronic, epic, Turkish folk\nelectronic, epic, cinematic\nelectronic, epic, operatic\nelectronic, epic, synthwave\nelectronic, epic, techno\nelectronic, epic, video game\nelectronic, ethereal pop, ambient\nelectronic, ethereal pop, trap\nelectronic, ethereal, C-pop\nelectronic, ethereal, French pop\nelectronic, ethereal, Hebrew vocal\nelectronic, ethereal, Italian pop\nelectronic, ethereal, Lithuanian pop\nelectronic, ethereal, Middle Eastern\nelectronic, ethereal, Middle Eastern fusion\nelectronic, ethereal, Persian pop\nelectronic, ethereal, Romanian\nelectronic, ethereal, Russian pop\nelectronic, ethereal, Telugu pop\nelectronic, ethereal, Turkish fusion\nelectronic, ethereal, Ukrainian pop\nelectronic, ethereal, Uzbek pop\nelectronic, ethereal, ambient\nelectronic, ethereal, anthemic\nelectronic, ethereal, blues-rock\nelectronic, ethereal, chiptune\nelectronic, ethereal, cinematic\nelectronic, ethereal, dance\nelectronic, ethereal, dark pop\nelectronic, ethereal, desert pop\nelectronic, ethereal, desert wave\nelectronic, ethereal, dubstep\nelectronic, ethereal, glitch\nelectronic, ethereal, indie pop\nelectronic, ethereal, industrial techno\nelectronic, ethereal, pop\nelectronic, ethereal, progressive house\nelectronic, ethereal, synthwave\nelectronic, ethereal, trance\nelectronic, ethereal, trap\nelectronic, ethereal, tribal house\nelectronic, ethereal, world-influenced\nelectronic, ethnic electronica, world fusion\nelectronic, ethnic fusion, Polish pop\nelectronic, ethnic fusion, cinematic\nelectronic, ethnic fusion, deep house\nelectronic, ethnic fusion, future bass\nelectronic, ethnic fusion, rave\nelectronic, ethnic, hard house\nelectronic, ethnic, melancholic\nelectronic, ethnic, urban\nelectronic, ethno-pop, EDM\nelectronic, ethno-pop, deep house\nelectronic, ethno-trance, cinematic\nelectronic, ethno-trap, cinematic\nelectronic, ethno-trap, lo-fi\nelectronic, eurodance, 90s video game\nelectronic, eurodance, ambient\nelectronic, eurodance, hip-house\nelectronic, eurodance, retro\nelectronic, eurodance, trance\nelectronic, eurodance, turbo pop\nelectronic, experimental hip-hop, ambient\nelectronic, experimental, C-pop\nelectronic, experimental, Hungarian pop\nelectronic, experimental, Indian folk\nelectronic, experimental, Indian hip hop\nelectronic, experimental, Indonesian hip hop\nelectronic, experimental, Italian hip hop\nelectronic, experimental, J-pop\nelectronic, experimental, K-pop\nelectronic, experimental, Russian pop\nelectronic, experimental, UK drill\nelectronic, experimental, ambient\nelectronic, experimental, ambient hip hop\nelectronic, experimental, art pop\nelectronic, experimental, baroque\nelectronic, experimental, chiptune\nelectronic, experimental, cinematic\nelectronic, experimental, dark pop\nelectronic, experimental, ethno-trance\nelectronic, experimental, glitch\nelectronic, experimental, industrial\nelectronic, experimental, lo-fi\nelectronic, experimental, operatic pop\nelectronic, experimental, pop\nelectronic, experimental, post-rock\nelectronic, experimental, techno\nelectronic, experimental, theatrical\nelectronic, experimental, trap\nelectronic, experimental, tribal techno\nelectronic, experimental, world beat\nelectronic, experimental, world fusion\nelectronic, fado, ambient\nelectronic, fairytale, hardstyle\nelectronic, fantasy, JRPG\nelectronic, fantasy, synthwave\nelectronic, festival, Chinese fusion\nelectronic, festival, EDM\nelectronic, festival, Indian fusion\nelectronic, festival, anthemic\nelectronic, festival, chiptune\nelectronic, festival, cinematic\nelectronic, festival, hard dance\nelectronic, festival, world fusion\nelectronic, festive, Indian fusion\nelectronic, festive, cinematic\nelectronic, festive, dance\nelectronic, festive, lo-fi\nelectronic, festive, video game\nelectronic, festive, world fusion\nelectronic, fitness, dance\nelectronic, fitness, retro\nelectronic, flamenco fusion, glitch\nelectronic, flamenco, ambient\nelectronic, flamenco, breakcore\nelectronic, flamenco, cinematic\nelectronic, flamenco, dark dance\nelectronic, flamenco, dark pop\nelectronic, flamenco, deep house\nelectronic, flamenco, melancholic\nelectronic, flamenco, world dance\nelectronic, folk fusion, Anatolian\nelectronic, folk fusion, Azerbaijani\nelectronic, folk fusion, Central Asian\nelectronic, folk fusion, Hindi\nelectronic, folk fusion, Italian hip hop\nelectronic, folk fusion, Middle Eastern\nelectronic, folk fusion, Southeast Asian\nelectronic, folk fusion, dance\nelectronic, folk fusion, dance-pop\nelectronic, folk fusion, festival\nelectronic, folk fusion, high-energy\nelectronic, folk fusion, pop-dance\nelectronic, folk fusion, trance\nelectronic, folk fusion, trap\nelectronic, folk punk, hip-hop\nelectronic, folk, Anatolian\nelectronic, folk, Azerbaijani\nelectronic, folk, Balkan\nelectronic, folk, Central Asian\nelectronic, folk, Hebrew pop\nelectronic, folk, Indian\nelectronic, folk, Middle Eastern\nelectronic, folk, North African\nelectronic, folk, South Asian\nelectronic, folk, Turkish\nelectronic, folk, ambient\nelectronic, folk, chaotic\nelectronic, folk, chiptune\nelectronic, folk, cinematic\nelectronic, folk, dance\nelectronic, folk, dramatic\nelectronic, folk, epic\nelectronic, folk, festive\nelectronic, folk, house\nelectronic, folk, lo-fi\nelectronic, folk, melodic\nelectronic, folk, pop\nelectronic, folk, retro\nelectronic, folk, retro-digital\nelectronic, folk, tango\nelectronic, folk, trance\nelectronic, folk, video game\nelectronic, folk-dance, cinematic\nelectronic, folk-pop\nelectronic, folktronica, Balkan techno\nelectronic, folktronica, dance\nelectronic, folktronica, party\nelectronic, footwork, hip-hop\nelectronic, funk rock, cinematic\nelectronic, funk, Afrobeat\nelectronic, funk, Balkan fusion\nelectronic, funk, Kannada pop\nelectronic, funk, ambient\nelectronic, funk, breakbeat\nelectronic, funk, chiptune\nelectronic, funk, cinematic\nelectronic, funk, dream pop\nelectronic, funk, drum and bass\nelectronic, funk, experimental\nelectronic, funk, glitch\nelectronic, funk, industrial\nelectronic, funk, jazz\nelectronic, funk, narrative\nelectronic, funk, polyrhythmic\nelectronic, funk, retro\nelectronic, funk, retro-futuristic\nelectronic, funk, synthwave\nelectronic, funk, theatrical\nelectronic, funk, trance\nelectronic, funk, tribal\nelectronic, funk, video game\nelectronic, funk, world music\nelectronic, funkot, Southeast Asian pop\nelectronic, funkot, dangdut koplo\nelectronic, fusion, Indian fusion\nelectronic, fusion, dance\nelectronic, fusion, world beat\nelectronic, future bass\nelectronic, future bass, Afrobeat\nelectronic, future bass, Asian fusion\nelectronic, future bass, C-pop\nelectronic, future bass, EDM\nelectronic, future bass, East Asian fusion\nelectronic, future bass, Hindi pop\nelectronic, future bass, Latin house\nelectronic, future bass, UK garage\nelectronic, future bass, ambient\nelectronic, future bass, anime\nelectronic, future bass, anime synth\nelectronic, future bass, anthemic\nelectronic, future bass, atmospheric\nelectronic, future bass, breakbeat\nelectronic, future bass, chiptune\nelectronic, future bass, cinematic\nelectronic, future bass, cinematic pop\nelectronic, future bass, cyberpunk\nelectronic, future bass, dark techno\nelectronic, future bass, dubstep\nelectronic, future bass, dystopian\nelectronic, future bass, glitch\nelectronic, future bass, glitch hop\nelectronic, future bass, glitch-hop\nelectronic, future bass, hardstyle\nelectronic, future bass, melancholic\nelectronic, future bass, psychedelic\nelectronic, future bass, synthwave\nelectronic, future bass, tech house\nelectronic, future bass, trap\nelectronic, future bass, video game\nelectronic, future bass, video game soundtrack\nelectronic, future funk, ambient\nelectronic, future house\nelectronic, future house, EDM\nelectronic, future house, Latin pop\nelectronic, future house, ambient\nelectronic, future house, cinematic\nelectronic, future house, glitch\nelectronic, future house, synthwave\nelectronic, future house, trance\nelectronic, future pop\nelectronic, future pop, Latin\nelectronic, future pop, Mandopop\nelectronic, future pop, cinematic\nelectronic, future pop, cyberpunk\nelectronic, future pop, hardstyle\nelectronic, future pop, synthwave\nelectronic, future trance\nelectronic, future trance, hardstyle\nelectronic, future trance, video game music\nelectronic, future wave, cinematic\nelectronic, future, chiptune\nelectronic, future, cinematic\nelectronic, future, synthwave\nelectronic, futurecore, chiptune\nelectronic, futurecore, glitch\nelectronic, futurepop, Vocaloid\nelectronic, futurepop, chiptune\nelectronic, futurepop, glitch\nelectronic, futurepop, synthwave\nelectronic, futurepop, video game\nelectronic, futurepop, video game music\nelectronic, futurewave\nelectronic, futurewave, ambient\nelectronic, futurewave, cinematic\nelectronic, futurewave, synthwave\nelectronic, futurewave, video game soundtrack\nelectronic, gabber, Middle Eastern fusion\nelectronic, gabber, chiptune\nelectronic, gabber, video game\nelectronic, gamelan, ambient\nelectronic, gamelan, anthemic\nelectronic, gamelan, deep house\nelectronic, gamelan, lo-fi\nelectronic, gamer anthem, synthwave\nelectronic, german hip hop, rave\nelectronic, ghazal, ambient\nelectronic, glam rock, hardstyle\nelectronic, glitch\nelectronic, glitch hop, Mandarin rap\nelectronic, glitch hop, future pop\nelectronic, glitch pop, Vocaloid\nelectronic, glitch, C-pop\nelectronic, glitch, Chinese future bass\nelectronic, glitch, EDM\nelectronic, glitch, French pop\nelectronic, glitch, K-pop\nelectronic, glitch, Latin\nelectronic, glitch, Latin hip hop\nelectronic, glitch, Latin pop\nelectronic, glitch, Mandarin pop\nelectronic, glitch, R&B\nelectronic, glitch, Russian hip hop\nelectronic, glitch, aggressive\nelectronic, glitch, ambient\nelectronic, glitch, anthemic\nelectronic, glitch, breakbeat\nelectronic, glitch, breakcore\nelectronic, glitch, chiptune\nelectronic, glitch, cinematic\nelectronic, glitch, cyberpunk\nelectronic, glitch, dance\nelectronic, glitch, dark ambient\nelectronic, glitch, dark pop\nelectronic, glitch, dark synth\nelectronic, glitch, deep house\nelectronic, glitch, demoscene\nelectronic, glitch, drum and bass\nelectronic, glitch, dubstep\nelectronic, glitch, experimental\nelectronic, glitch, funky\nelectronic, glitch, future bass\nelectronic, glitch, future pop\nelectronic, glitch, hardstyle\nelectronic, glitch, hip hop\nelectronic, glitch, industrial\nelectronic, glitch, instrumental\nelectronic, glitch, intense\nelectronic, glitch, lo-fi\nelectronic, glitch, memecore\nelectronic, glitch, neurofunk\nelectronic, glitch, pop\nelectronic, glitch, punk\nelectronic, glitch, rock\nelectronic, glitch, soul\nelectronic, glitch, synth funk\nelectronic, glitch, synthpop\nelectronic, glitch, synthwave\nelectronic, glitch, techno\nelectronic, glitch, trance\nelectronic, glitch, trap\nelectronic, glitch, tribal\nelectronic, glitch, vaporwave\nelectronic, glitch, video game\nelectronic, glitch, world music\nelectronic, glitch-hop, dubstep\nelectronic, glitch-hop, hardstyle\nelectronic, global dance, glitch\nelectronic, gospel, ambient\nelectronic, gospel, hip hop\nelectronic, gothic, dubstep\nelectronic, guzheng, ambient\nelectronic, guzheng, chiptune\nelectronic, guzheng, cinematic\nelectronic, guzheng, dance\nelectronic, guzheng, dizi\nelectronic, guzheng, drum and bass\nelectronic, guzheng, high-energy\nelectronic, guzheng, hip-hop\nelectronic, guzheng, late-90s dance\nelectronic, guzheng, lo-fi\nelectronic, guzheng, modern\nelectronic, guzheng, modern Asian\nelectronic, guzheng, modern Chinese\nelectronic, guzheng, modern traditional\nelectronic, guzheng, video game\nelectronic, guzheng, worldbeat\nelectronic, happy hardcore, chiptune\nelectronic, happy hardcore, synthwave\nelectronic, hard dance\nelectronic, hard dance, Arabic fusion\nelectronic, hard dance, Indian fusion\nelectronic, hard dance, Middle Eastern fusion\nelectronic, hard dance, aggressive\nelectronic, hard dance, aggro\nelectronic, hard dance, chiptune\nelectronic, hard dance, cinematic\nelectronic, hard dance, dark synth\nelectronic, hard dance, future bass\nelectronic, hard dance, glitch\nelectronic, hard dance, hip hop\nelectronic, hard dance, industrial\nelectronic, hard dance, pop\nelectronic, hard dance, rap\nelectronic, hard dance, trap\nelectronic, hard dance, vocal house\nelectronic, hard dance, vocal trance\nelectronic, hard house\nelectronic, hard house, Arabic fusion\nelectronic, hard house, Chinese hip hop\nelectronic, hard house, Indian fusion\nelectronic, hard house, Italian vocal\nelectronic, hard house, Latin techno\nelectronic, hard house, Mandarin hip hop\nelectronic, hard house, Middle Eastern fusion\nelectronic, hard house, Russian vocal\nelectronic, hard house, cinematic\nelectronic, hard house, club\nelectronic, hard house, dark ambient\nelectronic, hard house, ritual techno\nelectronic, hard house, synthwave\nelectronic, hard house, trap\nelectronic, hard techno\nelectronic, hard techno, cyberpunk\nelectronic, hard-hitting, traditional fusion\nelectronic, hardcore techno\nelectronic, hardcore, Cantonese\nelectronic, hardcore, Finnish rap\nelectronic, hardcore, Hungarian rap\nelectronic, hardcore, Indian fusion\nelectronic, hardcore, J-pop\nelectronic, hardcore, Latin trap\nelectronic, hardcore, chiptune\nelectronic, hardcore, rap\nelectronic, hardstyle\nelectronic, hardstyle, Arabic fusion\nelectronic, hardstyle, C-pop\nelectronic, hardstyle, EDM\nelectronic, hardstyle, Eastern-influenced\nelectronic, hardstyle, K-pop\nelectronic, hardstyle, Mandopop\nelectronic, hardstyle, Middle Eastern fusion\nelectronic, hardstyle, aggressive\nelectronic, hardstyle, ambient\nelectronic, hardstyle, ambient pop\nelectronic, hardstyle, anthemic\nelectronic, hardstyle, atmospheric\nelectronic, hardstyle, ballad\nelectronic, hardstyle, big room house\nelectronic, hardstyle, chiptune\nelectronic, hardstyle, cinematic\nelectronic, hardstyle, cyberpunk\nelectronic, hardstyle, dream pop\nelectronic, hardstyle, dubstep\nelectronic, hardstyle, future bass\nelectronic, hardstyle, mid-tempo\nelectronic, hardstyle, pop\nelectronic, hardstyle, psytrance\nelectronic, hardstyle, rave\nelectronic, hardstyle, synthwave\nelectronic, hardstyle, techno\nelectronic, hardstyle, trap\nelectronic, hardstyle, video game\nelectronic, high-energy, South Asian fusion\nelectronic, high-energy, anthemic\nelectronic, high-energy, motivational\nelectronic, high-tempo, Sinhala pop\nelectronic, hip hop\nelectronic, hip hop, Afrobeat\nelectronic, hip hop, C-pop\nelectronic, hip hop, Chinese rap\nelectronic, hip hop, Chinese trap\nelectronic, hip hop, EDM\nelectronic, hip hop, Filipino\nelectronic, hip hop, Finnish rap\nelectronic, hip hop, Hungarian rap\nelectronic, hip hop, Indian\nelectronic, hip hop, Indian fusion\nelectronic, hip hop, Indian pop\nelectronic, hip hop, Mandopop\nelectronic, hip hop, Middle Eastern fusion\nelectronic, hip hop, Nordic\nelectronic, hip hop, R&B\nelectronic, hip hop, Sinhala pop\nelectronic, hip hop, aggressive\nelectronic, hip hop, ambient\nelectronic, hip hop, anthemic\nelectronic, hip hop, beatbox\nelectronic, hip hop, breakbeat\nelectronic, hip hop, cantopop\nelectronic, hip hop, chiptune\nelectronic, hip hop, choral\nelectronic, hip hop, cinematic\nelectronic, hip hop, club\nelectronic, hip hop, comedy\nelectronic, hip hop, dance\nelectronic, hip hop, dark synth\nelectronic, hip hop, dark wave\nelectronic, hip hop, deep house\nelectronic, hip hop, drum and bass\nelectronic, hip hop, dubstep\nelectronic, hip hop, experimental\nelectronic, hip hop, future bass\nelectronic, hip hop, glitch\nelectronic, hip hop, industrial\nelectronic, hip hop, pop-punk\nelectronic, hip hop, rave\nelectronic, hip hop, retro synth\nelectronic, hip hop, rock\nelectronic, hip hop, soul\nelectronic, hip hop, synthwave\nelectronic, hip hop, trap\nelectronic, hip hop, urban\nelectronic, hip hop, video game\nelectronic, hip hop, world fusion\nelectronic, hip-hop, Brazilian, ambient\nelectronic, hip-hop, Indian fusion\nelectronic, hip-hop, Latin pop\nelectronic, hip-hop, aggressive\nelectronic, hip-hop, ambient\nelectronic, hip-hop, breakbeat\nelectronic, hip-hop, chiptune\nelectronic, hip-hop, cinematic\nelectronic, hip-hop, dark\nelectronic, hip-hop, devotional\nelectronic, hip-hop, eurodance\nelectronic, hip-hop, future bass\nelectronic, hip-hop, pop-rock\nelectronic, hip-hop, synthwave\nelectronic, hip-hop, trap\nelectronic, house, 80s synth-pop\nelectronic, house, Arabic fusion\nelectronic, house, Latin\nelectronic, house, Middle Eastern\nelectronic, house, Middle Eastern fusion\nelectronic, house, North African pop\nelectronic, house, UK garage\nelectronic, house, ambient\nelectronic, house, arpeggiated\nelectronic, house, breakbeat\nelectronic, house, chiptune\nelectronic, house, cinematic\nelectronic, house, cumbia\nelectronic, house, deep house\nelectronic, house, folk\nelectronic, house, funk\nelectronic, house, lo-fi\nelectronic, house, melancholic\nelectronic, house, meme\nelectronic, house, minimal\nelectronic, house, motivational\nelectronic, house, pop\nelectronic, house, progressive\nelectronic, house, regional Mexican\nelectronic, house, synthwave\nelectronic, house, techno\nelectronic, hybrid trap, dubstep\nelectronic, hyperpop, aggro\nelectronic, hyperpop, ambient\nelectronic, hyperpop, blues\nelectronic, hyperpop, cinematic\nelectronic, hyperpop, glitch\nelectronic, hyperpop, post-hardcore\nelectronic, hyperpop, synthwave\nelectronic, hyperpop, trap\nelectronic, hypnotic, Middle Eastern\nelectronic, hypnotic, Middle Eastern fusion\nelectronic, hypnotic, Turkish ambient\nelectronic, hypnotic, ambient\nelectronic, hypnotic, breakbeat\nelectronic, hypnotic, dance\nelectronic, hypnotic, synthwave\nelectronic, hǎnmài, dance\nelectronic, indie folk, progressive house\nelectronic, indie pop, German vocal\nelectronic, indie pop, Hebrew vocal\nelectronic, indie pop, Hindi pop\nelectronic, indie pop, Indonesian\nelectronic, indie pop, Italian rap\nelectronic, indie pop, Latin\nelectronic, indie pop, dark wave\nelectronic, indie pop, experimental\nelectronic, indie pop, industrial\nelectronic, indie pop, lo-fi hip hop\nelectronic, indie pop, world fusion\nelectronic, indie rock, ambient\nelectronic, indie, ambient\nelectronic, indie, ethnic fusion\nelectronic, indie, pop\nelectronic, industrial\nelectronic, industrial pop\nelectronic, industrial pop, Russian pop\nelectronic, industrial pop, chiptune\nelectronic, industrial pop, cinematic\nelectronic, industrial pop, melancholic\nelectronic, industrial rock, ambient\nelectronic, industrial rock, big beat\nelectronic, industrial rock, shoegaze\nelectronic, industrial, 80s synth\nelectronic, industrial, Brazilian\nelectronic, industrial, C-pop\nelectronic, industrial, EDM\nelectronic, industrial, French pop\nelectronic, industrial, French spoken word\nelectronic, industrial, Russian rap\nelectronic, industrial, Turkish pop\nelectronic, industrial, aggressive\nelectronic, industrial, ambient\nelectronic, industrial, anthemic\nelectronic, industrial, big beat\nelectronic, industrial, breakbeat\nelectronic, industrial, chiptune\nelectronic, industrial, choral\nelectronic, industrial, cinematic\nelectronic, industrial, cyberpunk\nelectronic, industrial, dance\nelectronic, industrial, dark pop\nelectronic, industrial, dream pop\nelectronic, industrial, dubstep\nelectronic, industrial, emotional\nelectronic, industrial, ethereal\nelectronic, industrial, glitch\nelectronic, industrial, hardstyle\nelectronic, industrial, lo-fi\nelectronic, industrial, pop\nelectronic, industrial, retro\nelectronic, industrial, synthwave\nelectronic, industrial, techno\nelectronic, inspirational, ambient\nelectronic, instrumental, Middle Eastern\nelectronic, instrumental, ambient\nelectronic, instrumental, breakbeat\nelectronic, instrumental, lo-fi\nelectronic, instrumental, lo-fi hip hop\nelectronic, instrumental, polyrhythmic\nelectronic, instrumental, reggaeton\nelectronic, instrumental, tech house\nelectronic, instrumental, video game\nelectronic, instrumental, world beat\nelectronic, instrumental, world fusion\nelectronic, italo house, synth pop\nelectronic, j-pop, chiptune\nelectronic, jazz fusion, dream pop\nelectronic, jazz fusion, experimental\nelectronic, jazz fusion, future funk\nelectronic, jazz fusion, synthwave\nelectronic, jazz rap, dance\nelectronic, jazz, chiptune\nelectronic, k-pop, video game\nelectronic, klezmer, Balkan folk\nelectronic, klezmer, ambient\nelectronic, klezmer, cinematic\nelectronic, klezmer, synthwave\nelectronic, kuthro, jpega\nelectronic, kuthu, trap\nelectronic, liturgical, ambient\nelectronic, live, rave\nelectronic, lo-fi hip hop\nelectronic, lo-fi hip hop, Brazilian\nelectronic, lo-fi hip hop, Chinese pop\nelectronic, lo-fi hip hop, EDM\nelectronic, lo-fi hip hop, Indian fusion\nelectronic, lo-fi hip hop, Mandarin rap\nelectronic, lo-fi hip hop, UK garage\nelectronic, lo-fi hip hop, ambient\nelectronic, lo-fi hip hop, anime\nelectronic, lo-fi hip hop, chiptune\nelectronic, lo-fi hip hop, cinematic\nelectronic, lo-fi hip hop, dream pop\nelectronic, lo-fi hip hop, experimental\nelectronic, lo-fi hip hop, party anthem\nelectronic, lo-fi hip hop, video game\nelectronic, lo-fi, Arabic fusion\nelectronic, lo-fi, Asian pop\nelectronic, lo-fi, Brazilian\nelectronic, lo-fi, Brazilian funk\nelectronic, lo-fi, Latin hip hop\nelectronic, lo-fi, Russian rap\nelectronic, lo-fi, Turkish pop\nelectronic, lo-fi, Vocaloid\nelectronic, lo-fi, ambient\nelectronic, lo-fi, anime\nelectronic, lo-fi, arpeggiated\nelectronic, lo-fi, chiptune\nelectronic, lo-fi, dance\nelectronic, lo-fi, dream pop\nelectronic, lo-fi, dubstep\nelectronic, lo-fi, experimental\nelectronic, lo-fi, folk fusion\nelectronic, lo-fi, house\nelectronic, lo-fi, melancholic\nelectronic, lo-fi, party\nelectronic, lo-fi, playful\nelectronic, lo-fi, quirky\nelectronic, lo-fi, retro\nelectronic, lo-fi, synthwave\nelectronic, lo-fi, trap\nelectronic, lo-fi, vaporwave\nelectronic, lo-fi, video game\nelectronic, mandarin rap, hardstyle\nelectronic, mantra, ambient\nelectronic, marching band, rap\nelectronic, mawwal, Middle Eastern\nelectronic, mawwal, dance\nelectronic, melancholic house, cinematic\nelectronic, melancholic, C-pop\nelectronic, melancholic, EDM\nelectronic, melancholic, Eastern European\nelectronic, melancholic, French pop\nelectronic, melancholic, German pop\nelectronic, melancholic, Greek pop\nelectronic, melancholic, Hindi pop\nelectronic, melancholic, Italian\nelectronic, melancholic, Italian pop\nelectronic, melancholic, Kazakh\nelectronic, melancholic, Middle Eastern\nelectronic, melancholic, Persian\nelectronic, melancholic, Polish pop\nelectronic, melancholic, Portuguese\nelectronic, melancholic, Portuguese pop\nelectronic, melancholic, Russian pop\nelectronic, melancholic, South Asian\nelectronic, melancholic, Spanish pop\nelectronic, melancholic, Swedish pop\nelectronic, melancholic, Turkish\nelectronic, melancholic, Turkish folk\nelectronic, melancholic, Turkish pop\nelectronic, melancholic, Ukrainian\nelectronic, melancholic, ambient\nelectronic, melancholic, anthemic\nelectronic, melancholic, atmospheric\nelectronic, melancholic, big room house\nelectronic, melancholic, cinematic\nelectronic, melancholic, dance\nelectronic, melancholic, dubstep\nelectronic, melancholic, ethnic fusion\nelectronic, melancholic, future bass\nelectronic, melancholic, glitch\nelectronic, melancholic, hardstyle\nelectronic, melancholic, hyperpop\nelectronic, melancholic, industrial\nelectronic, melancholic, oriental\nelectronic, melancholic, synthwave\nelectronic, melancholic, trance\nelectronic, melancholic, trap\nelectronic, melodic dubstep, cinematic\nelectronic, melodic house, romantic\nelectronic, melodic rap, ambient\nelectronic, melodic, Middle Eastern\nelectronic, meme, chiptune\nelectronic, meme, dance\nelectronic, meme, hyperpop\nelectronic, meme, jingle\nelectronic, meme, lo-fi\nelectronic, metalcore\nelectronic, metalcore, ambient\nelectronic, metalcore, dubstep\nelectronic, mid-tempo bass, dubstep\nelectronic, militant, Arabic revolutionary\nelectronic, militant, Greek\nelectronic, militant, agitprop\nelectronic, militant, anthemic\nelectronic, militant, devotional\nelectronic, minimal house, electro\nelectronic, minimal techno\nelectronic, minimal techno, baroque synth\nelectronic, minimal techno, chiptune\nelectronic, minimal techno, vocaloid\nelectronic, minimal, chiptune\nelectronic, minimal, video game\nelectronic, modern, Middle Eastern fusion\nelectronic, moombahton, ambient\nelectronic, moombahton, baile funk\nelectronic, moombahton, cinematic\nelectronic, moombahton, dancehall\nelectronic, moombahton, pop\nelectronic, moombahton, reggaeton\nelectronic, moombahton, trap\nelectronic, motivational, dance\nelectronic, mystical, ambient\nelectronic, mystical, dance\nelectronic, mystical, hip hop\nelectronic, narrative house, dream pop\nelectronic, neapolitan pop, ambient hip hop\nelectronic, neo-classical metal, video game soundtrack\nelectronic, neo-classical, dance\nelectronic, neo-tribal, cinematic\nelectronic, nerdcore, hardcore\nelectronic, new wave\nelectronic, new-age, ambient\nelectronic, ney flute, Central Asian\nelectronic, ney flute, Middle Eastern\nelectronic, ney flute, Middle Eastern pop\nelectronic, ney flute, cinematic\nelectronic, ney flute, pop\nelectronic, ney flute, spiritual\nelectronic, ney, cinematic\nelectronic, nightcore\nelectronic, novelty, meme\nelectronic, novelty, playful\nelectronic, nu-disco, cinematic\nelectronic, nu-jazz, synthwave\nelectronic, nu-metal, Telugu\nelectronic, nu-metal, alternative\nelectronic, operatic rap, beatbox\nelectronic, operatic, EDM\nelectronic, operatic, Indian fusion\nelectronic, operatic, breakbeat\nelectronic, operatic, cinematic\nelectronic, operatic, glitch\nelectronic, orchestral, cinematic\nelectronic, orchestral, drum and bass\nelectronic, oriental house\nelectronic, oriental house, rave\nelectronic, oriental pop, ambient\nelectronic, oriental style, dream pop\nelectronic, oriental trance, Bollywood\nelectronic, oriental, ambient\nelectronic, oriental, ballad\nelectronic, oriental, cinematic\nelectronic, oriental, dance\nelectronic, oriental, deep house\nelectronic, oriental, folk\nelectronic, oriental, glitch\nelectronic, oriental, high-tempo\nelectronic, oriental, melancholic\nelectronic, oud fusion, dance\nelectronic, oud, Middle Eastern\nelectronic, oud, North African\nelectronic, oud, ambient\nelectronic, oud, breakbeat\nelectronic, oud, cinematic\nelectronic, oud, downtempo\nelectronic, oud, fusion\nelectronic, oud, high-energy\nelectronic, oud, house\nelectronic, oud, intense\nelectronic, oud, percussive\nelectronic, oud, reggaeton\nelectronic, oud, trap\nelectronic, party, dance\nelectronic, party, high-energy\nelectronic, patriotic, Indian\nelectronic, patriotic, Indian fusion\nelectronic, percussion, dance\nelectronic, percussive, Latin\nelectronic, percussive, Middle Eastern fusion\nelectronic, percussive, world beat\nelectronic, playful, breakbeat\nelectronic, playful, children's music\nelectronic, playful, eclectic\nelectronic, playful, educational\nelectronic, playful, hypnotic\nelectronic, playful, instrumental\nelectronic, playful, jingle\nelectronic, playful, lo-fi\nelectronic, playful, quirky\nelectronic, playful, synth pop\nelectronic, playful, synthpop\nelectronic, playful, tropical\nelectronic, playful, upbeat\nelectronic, playful, video game\nelectronic, political anthem, Bollywood fusion\nelectronic, political, techno\nelectronic, polyrhythmic, Balkan-inspired\nelectronic, polyrhythmic, ambient\nelectronic, polyrhythmic, celebratory\nelectronic, polyrhythmic, synthwave\nelectronic, pop, Bollywood\nelectronic, pop, Brazilian\nelectronic, pop, EDM\nelectronic, pop, Hebrew vocal\nelectronic, pop, Hungarian folk\nelectronic, pop, Indian folk\nelectronic, pop, Indian fusion\nelectronic, pop, Kazakh\nelectronic, pop, Latin\nelectronic, pop, Mandarin\nelectronic, pop, Marathi\nelectronic, pop, Middle Eastern\nelectronic, pop, Polish\nelectronic, pop, Romanian\nelectronic, pop, Sinhala\nelectronic, pop, South Asian\nelectronic, pop, South Asian fusion\nelectronic, pop, Southeast Asian pop\nelectronic, pop, ambient\nelectronic, pop, anime\nelectronic, pop, anthemic\nelectronic, pop, brostep\nelectronic, pop, chiptune\nelectronic, pop, cinematic\nelectronic, pop, complextro\nelectronic, pop, dance\nelectronic, pop, dark pop\nelectronic, pop, dubstep\nelectronic, pop, euphoric\nelectronic, pop, future bass\nelectronic, pop, glitch\nelectronic, pop, hardstyle\nelectronic, pop, hip hop\nelectronic, pop, hip-hop\nelectronic, pop, lo-fi hip hop\nelectronic, pop, oriental\nelectronic, pop, playful\nelectronic, pop, psychedelic\nelectronic, pop, spiritual\nelectronic, pop, theatrical\nelectronic, pop, trap\nelectronic, pop, world\nelectronic, pop, world fusion\nelectronic, pop-R&B, ambient\nelectronic, pop-R&B, cinematic\nelectronic, pop-R&B, dubstep\nelectronic, pop-R&B, future bass\nelectronic, pop-R&B, hard house\nelectronic, pop-R&B, trap\nelectronic, pop-anime, trance\nelectronic, pop-punk, UK rap\nelectronic, pop-punk, dubstep\nelectronic, pop-punk, synthwave\nelectronic, pop-rock, funk\nelectronic, pop-rock, world fusion\nelectronic, pop-trap, Russian hip hop\nelectronic, post-punk, dream-pop\nelectronic, post-rock, ambient\nelectronic, post-rock, cinematic\nelectronic, progressive house\nelectronic, progressive house, C-pop\nelectronic, progressive house, Middle Eastern fusion\nelectronic, progressive house, ambient\nelectronic, progressive house, cinematic\nelectronic, progressive house, synthwave\nelectronic, progressive house, trance\nelectronic, progressive house, world fusion\nelectronic, progressive rock, Persian pop\nelectronic, progressive rock, chiptune\nelectronic, progressive, Middle Eastern\nelectronic, progressive, cinematic\nelectronic, progressive, dark techno\nelectronic, progressive, epic\nelectronic, progressive, world fusion\nelectronic, protest, anthemic\nelectronic, protest, rave\nelectronic, protest, techno\nelectronic, psychedelic, ambient\nelectronic, psychedelic, funk\nelectronic, psychedelic, world music\nelectronic, psytrance, cinematic\nelectronic, psytrance, industrial\nelectronic, punk, chiptune\nelectronic, qawwali, ambient\nelectronic, quirky pop\nelectronic, quirky pop, synth pop\nelectronic, quirky, Eastern European\nelectronic, quirky, J-pop\nelectronic, quirky, Latin-inspired\nelectronic, quirky, chiptune\nelectronic, quirky, club\nelectronic, quirky, dance\nelectronic, quirky, jingle\nelectronic, quirky, lo-fi\nelectronic, quirky, meme\nelectronic, quirky, minimalist\nelectronic, quirky, mystical\nelectronic, quirky, playful\nelectronic, quirky, pop\nelectronic, quirky, synth\nelectronic, quirky, synth pop\nelectronic, quirky, synthpop\nelectronic, quirky, video game\nelectronic, quirky, world fusion\nelectronic, ragtime, video game\nelectronic, ranchera, club\nelectronic, rap rock, dubstep\nelectronic, rap, Italian\nelectronic, rap, J-pop\nelectronic, rap, anime\nelectronic, rap, anthemic\nelectronic, rap, dubstep\nelectronic, rap, industrial\nelectronic, rap, militant\nelectronic, rap, pop\nelectronic, rap, pop-rock\nelectronic, rap, protest\nelectronic, rap, synthwave\nelectronic, rave, Estonian hip hop\nelectronic, rave, Hebrew hip hop\nelectronic, rave, Middle Eastern fusion\nelectronic, rave, Russian rap\nelectronic, rave, UK hardcore\nelectronic, rave, ambient\nelectronic, rave, arabic techno\nelectronic, rave, breakbeat\nelectronic, rave, chiptune\nelectronic, rave, dance\nelectronic, rave, festival\nelectronic, rave, glitch\nelectronic, rave, hard dance\nelectronic, rave, hardcore\nelectronic, rave, hip hop\nelectronic, rave, hyperpop\nelectronic, rave, industrial\nelectronic, rave, pop-punk\nelectronic, rave, synthwave\nelectronic, rave, trance\nelectronic, rave, trap\nelectronic, rave, tribal house\nelectronic, rave, video game\nelectronic, raï, Middle Eastern fusion\nelectronic, raï, North African\nelectronic, raï, chaabi\nelectronic, raï, cinematic\nelectronic, raï, dance\nelectronic, raï, folk fusion\nelectronic, raï, fusion\nelectronic, raï, thisa\nelectronic, reggaeton, Latin\nelectronic, reggaeton, Middle Eastern\nelectronic, reggaeton, ambient\nelectronic, reggaeton, anthemic\nelectronic, reggaeton, chiptune\nelectronic, reggaeton, cinematic\nelectronic, reggaeton, club\nelectronic, reggaeton, dream pop\nelectronic, reggaeton, house\nelectronic, reggaeton, lo-fi\nelectronic, reggaeton, lo-fi hip hop\nelectronic, reggaeton, moombahton, dancehall, R&B\nelectronic, reggaeton, trap\nelectronic, regional Mexican, cinematic\nelectronic, regional pop, chiptune\nelectronic, regional, dance\nelectronic, retro game, Mandarin pop\nelectronic, retro game, ambient\nelectronic, retro game, children's music\nelectronic, retro game, lo-fi\nelectronic, retro game, synthwave\nelectronic, retro synth, techno\nelectronic, retro techno, video game music\nelectronic, retro wave, anime\nelectronic, retro wave, synthwave\nelectronic, retro, 80s\nelectronic, retro, Chinese hip hop\nelectronic, retro, South Asian\nelectronic, retro, chiptune\nelectronic, retro, dance\nelectronic, retro, dance-pop\nelectronic, retro, funk\nelectronic, retro, hip-hop\nelectronic, retro, house\nelectronic, retro, karaoke\nelectronic, retro, lo-fi\nelectronic, retro, lo-fi hip hop\nelectronic, retro, synthwave\nelectronic, retro, techno\nelectronic, retro, trance\nelectronic, retro, tropical\nelectronic, retro, video game\nelectronic, retro-digital, tech-trance\nelectronic, retro-digital, techno\nelectronic, retro-futuristic\nelectronic, retro-futuristic, EBM\nelectronic, retro-futuristic, breakbeat\nelectronic, retro-futuristic, chiptune\nelectronic, retro-futuristic, cinematic\nelectronic, retro-futuristic, cyberpunk\nelectronic, retro-futuristic, synthwave\nelectronic, retro-futuristic, techno\nelectronic, retro-futuristic, vaporwave\nelectronic, retro-futuristic, video game\nelectronic, retro-futuristic, video game music\nelectronic, rhythmic, instrumental\nelectronic, ritual ambient, Lithuanian folk\nelectronic, ritual ambient, cinematic\nelectronic, ritual ambient, dark wave\nelectronic, ritual ambient, deep house\nelectronic, ritual ambient, hip hop\nelectronic, ritual ambient, world fusion\nelectronic, ritual house, world fusion\nelectronic, ritual techno\nelectronic, ritual techno, Telugu vocal\nelectronic, ritual techno, aggressive\nelectronic, ritual techno, ambient\nelectronic, ritual techno, devotional\nelectronic, ritual techno, lo-fi\nelectronic, ritual, ambient\nelectronic, ritualistic, Persian fusion\nelectronic, ritualistic, ambient\nelectronic, ritualistic, anthemic\nelectronic, ritualistic, cinematic\nelectronic, ritualistic, epic\nelectronic, rock, Middle Eastern\nelectronic, rock, spiritual\nelectronic, sacred chant, ambient\nelectronic, sacred, 90s style\nelectronic, sacred, cinematic\nelectronic, sacred, funk\nelectronic, sacred, industrial\nelectronic, samba, high-energy\nelectronic, sci-fi, EDM\nelectronic, sci-fi, rave\nelectronic, sea shanty, novelty\nelectronic, sensual, atmospheric\nelectronic, shoegaze, French pop\nelectronic, shoegaze, aggressive\nelectronic, shoegaze, ambient\nelectronic, shoegaze, synthwave\nelectronic, soul, Arabic pop\nelectronic, soul, Celtic house\nelectronic, soul, South Asian\nelectronic, soul, Turkish pop\nelectronic, soul, ambient\nelectronic, soul, anthemic\nelectronic, soul, cinematic\nelectronic, soul, deep house\nelectronic, soul, dubstep\nelectronic, soul, experimental\nelectronic, soul, hip hop\nelectronic, soul, nu-disco\nelectronic, soulful, ambient\nelectronic, soulful, anthemic\nelectronic, soulful, atmospheric\nelectronic, soulful, cinematic\nelectronic, soulful, industrial\nelectronic, soulful, trap\nelectronic, spiritual, Anatolian\nelectronic, spiritual, Central Asian\nelectronic, spiritual, Middle Eastern\nelectronic, spiritual, North African\nelectronic, spiritual, Persian\nelectronic, spiritual, South Asian\nelectronic, spiritual, Turkish\nelectronic, spiritual, Turkish fusion\nelectronic, spiritual, ambient\nelectronic, spiritual, dance\nelectronic, spiritual, empowering\nelectronic, spiritual, industrial\nelectronic, spiritual, trap\nelectronic, spiritual, world fusion\nelectronic, spooky, nursery rhyme\nelectronic, sports anthem, pop\nelectronic, surf rock, video game music\nelectronic, synth brass, cinematic\nelectronic, synth, saxophone\nelectronic, synth-pop\nelectronic, synth-pop, Middle Eastern\nelectronic, synth-pop, North African pop\nelectronic, synth-pop, brostep\nelectronic, synth-pop, cinematic\nelectronic, synth-pop, hardstyle\nelectronic, synth-pop, hip-hop\nelectronic, synth-pop, house\nelectronic, synth-pop, nu-disco\nelectronic, synth-pop, progressive house\nelectronic, synth-rock, Italian rap\nelectronic, synth-rock, complextro\nelectronic, synthpop, Nordic\nelectronic, synthpop, Vocaloid\nelectronic, synthpop, ambient\nelectronic, synthpop, art pop\nelectronic, synthpop, chiptune\nelectronic, synthpop, cinematic\nelectronic, synthpop, playful\nelectronic, synthpop, pop\nelectronic, synthpop, trap\nelectronic, synthpop, video game\nelectronic, synthwave, C-pop\nelectronic, synthwave, Chinese EDM\nelectronic, synthwave, Chinese fusion\nelectronic, synthwave, EBM\nelectronic, synthwave, Eastern influence\nelectronic, synthwave, Eastern-influenced\nelectronic, synthwave, Finnish EDM\nelectronic, synthwave, Finnish pop\nelectronic, synthwave, French pop\nelectronic, synthwave, German pop\nelectronic, synthwave, Greek pop\nelectronic, synthwave, Hebrew vocal\nelectronic, synthwave, Hungarian pop\nelectronic, synthwave, IDM\nelectronic, synthwave, Italo-disco\nelectronic, synthwave, J-pop\nelectronic, synthwave, JRPG\nelectronic, synthwave, Latin house\nelectronic, synthwave, Latin pop\nelectronic, synthwave, Latin techno\nelectronic, synthwave, Lithuanian hip hop\nelectronic, synthwave, Mandarin pop\nelectronic, synthwave, Mandopop\nelectronic, synthwave, Middle Eastern\nelectronic, synthwave, Polish pop\nelectronic, synthwave, Russian pop\nelectronic, synthwave, Russian rap\nelectronic, synthwave, Russian vocal\nelectronic, synthwave, Swedish pop\nelectronic, synthwave, Turkish pop\nelectronic, synthwave, Vocaloid\nelectronic, synthwave, aggressive\nelectronic, synthwave, ambient\nelectronic, synthwave, ambient house\nelectronic, synthwave, ambient techno\nelectronic, synthwave, anime\nelectronic, synthwave, arcade\nelectronic, synthwave, arpeggiated\nelectronic, synthwave, arpeggio-driven\nelectronic, synthwave, bilingual pop\nelectronic, synthwave, breakbeat\nelectronic, synthwave, chiptune\nelectronic, synthwave, choral\nelectronic, synthwave, cinematic\nelectronic, synthwave, classical-inspired\nelectronic, synthwave, cyberpunk\nelectronic, synthwave, dance\nelectronic, synthwave, dark pop\nelectronic, synthwave, dark wave\nelectronic, synthwave, deep house\nelectronic, synthwave, dream pop\nelectronic, synthwave, dubstep\nelectronic, synthwave, dystopian\nelectronic, synthwave, electro\nelectronic, synthwave, emotional\nelectronic, synthwave, energetic\nelectronic, synthwave, experimental\nelectronic, synthwave, folk fusion\nelectronic, synthwave, funk\nelectronic, synthwave, future bass\nelectronic, synthwave, future pop\nelectronic, synthwave, futurecore\nelectronic, synthwave, futurepop\nelectronic, synthwave, glitch\nelectronic, synthwave, glitch hop\nelectronic, synthwave, happy hardcore\nelectronic, synthwave, hip hop\nelectronic, synthwave, industrial\nelectronic, synthwave, instrumental\nelectronic, synthwave, lo-fi\nelectronic, synthwave, lo-fi hip hop\nelectronic, synthwave, melancholic\nelectronic, synthwave, oriental pop\nelectronic, synthwave, pop\nelectronic, synthwave, post-punk\nelectronic, synthwave, post-rock\nelectronic, synthwave, progressive\nelectronic, synthwave, rave\nelectronic, synthwave, retro\nelectronic, synthwave, retro-futuristic\nelectronic, synthwave, rhythmic\nelectronic, synthwave, rock\nelectronic, synthwave, techno\nelectronic, synthwave, trance\nelectronic, synthwave, trap\nelectronic, synthwave, upbeat\nelectronic, synthwave, uplifting\nelectronic, synthwave, video game\nelectronic, synthwave, video game music\nelectronic, synthwave, video game soundtrack\nelectronic, synthwave, world fusion\nelectronic, tabla, shehnai\nelectronic, taiko, J-pop\nelectronic, taiko, anime\nelectronic, taiko, dance\nelectronic, taiko, glitch\nelectronic, tech house, 90s synth\nelectronic, tech house, ambient\nelectronic, tech house, chiptune\nelectronic, tech house, dark wave\nelectronic, tech house, synthwave\nelectronic, tech-trance\nelectronic, tech-trance, retro synth\nelectronic, techno, C-pop\nelectronic, techno, Dogecore\nelectronic, techno, EBM\nelectronic, techno, EDM\nelectronic, techno, Indian fusion\nelectronic, techno, Latin house\nelectronic, techno, Middle Eastern\nelectronic, techno, Middle Eastern fusion\nelectronic, techno, Russian rap\nelectronic, techno, Russian vocal\nelectronic, techno, acid house\nelectronic, techno, ambient\nelectronic, techno, analog\nelectronic, techno, arpeggiated\nelectronic, techno, breakbeat\nelectronic, techno, chiptune\nelectronic, techno, cinematic\nelectronic, techno, club\nelectronic, techno, cyberpunk\nelectronic, techno, dance\nelectronic, techno, dark\nelectronic, techno, dark ambient\nelectronic, techno, dark wave\nelectronic, techno, deep house\nelectronic, techno, dystopian\nelectronic, techno, electro\nelectronic, techno, experimental\nelectronic, techno, future\nelectronic, techno, future bass\nelectronic, techno, future house\nelectronic, techno, future pop\nelectronic, techno, future wave\nelectronic, techno, futurecore\nelectronic, techno, glitch\nelectronic, techno, house\nelectronic, techno, industrial\nelectronic, techno, italo\nelectronic, techno, lo-fi\nelectronic, techno, lo-fi hip hop\nelectronic, techno, operatic\nelectronic, techno, psychedelic\nelectronic, techno, rave\nelectronic, techno, retro wave\nelectronic, techno, retro-futuristic\nelectronic, techno, ritual ambient\nelectronic, techno, sample-based\nelectronic, techno, synth-pop\nelectronic, techno, synthwave\nelectronic, techno, trance\nelectronic, techno, tribal\nelectronic, techno, trip hop\nelectronic, techno, video game\nelectronic, techno, video game music\nelectronic, techno, vocal chop\nelectronic, techno, vocal trance\nelectronic, tension, Middle Eastern\nelectronic, theatrical pop, cinematic\nelectronic, theatrical, Latin pop\nelectronic, theatrical, Swedish pop\nelectronic, theatrical, ambient\nelectronic, theatrical, cinematic\nelectronic, theatrical, dark ambient\nelectronic, theatrical, experimental\nelectronic, theatrical, quirky\nelectronic, theatrical, synth-pop\nelectronic, theatrical, synthpop\nelectronic, tracker music, retro game\nelectronic, traditional Central Asian, cinematic\nelectronic, traditional East Asian, ambient\nelectronic, traditional East Asian, breakbeat\nelectronic, traditional East Asian, cinematic\nelectronic, traditional East Asian, virtuosic\nelectronic, traditional Malay, festive\nelectronic, traditional, cinematic\nelectronic, trance\nelectronic, trance, Arabic fusion\nelectronic, trance, C-pop\nelectronic, trance, EDM\nelectronic, trance, Hindi rap\nelectronic, trance, Indian folk\nelectronic, trance, Indian fusion\nelectronic, trance, Mandarin hip hop\nelectronic, trance, North African\nelectronic, trance, Romanian rap\nelectronic, trance, Russian house\nelectronic, trance, Urdu pop\nelectronic, trance, Vocaloid\nelectronic, trance, ambient\nelectronic, trance, anime\nelectronic, trance, anthemic\nelectronic, trance, arabic pop\nelectronic, trance, arpeggiated\nelectronic, trance, breakbeat\nelectronic, trance, chiptune\nelectronic, trance, cinematic\nelectronic, trance, club\nelectronic, trance, cyberpunk\nelectronic, trance, dance\nelectronic, trance, deep house\nelectronic, trance, dream pop\nelectronic, trance, epic\nelectronic, trance, experimental\nelectronic, trance, funk\nelectronic, trance, future\nelectronic, trance, future bass\nelectronic, trance, future house\nelectronic, trance, happy hardcore\nelectronic, trance, hard dance\nelectronic, trance, hardcore\nelectronic, trance, hardstyle\nelectronic, trance, hip hop\nelectronic, trance, house\nelectronic, trance, minimal\nelectronic, trance, oriental\nelectronic, trance, pop\nelectronic, trance, rave\nelectronic, trance, retro synth\nelectronic, trance, retro-futuristic\nelectronic, trance, ritual techno\nelectronic, trance, shoegaze\nelectronic, trance, synthpop\nelectronic, trance, synthwave\nelectronic, trance, techno\nelectronic, trance, uplifting\nelectronic, trance, video game\nelectronic, trance, video game music\nelectronic, trap, Arabic\nelectronic, trap, Arabic devotional\nelectronic, trap, Arabic fusion\nelectronic, trap, Arabic pop\nelectronic, trap, Balkan folk\nelectronic, trap, Bollywood\nelectronic, trap, C-pop\nelectronic, trap, Chinese hip hop\nelectronic, trap, EDM\nelectronic, trap, French rap\nelectronic, trap, Greek rap\nelectronic, trap, Halloween\nelectronic, trap, Hebrew pop\nelectronic, trap, Hebrew spoken word\nelectronic, trap, Hindi hip hop\nelectronic, trap, Hindi pop\nelectronic, trap, Indian classical\nelectronic, trap, Indian fusion\nelectronic, trap, Indonesian hip hop\nelectronic, trap, Italian hip hop\nelectronic, trap, Italian pop\nelectronic, trap, Italian rap\nelectronic, trap, J-pop\nelectronic, trap, K-pop\nelectronic, trap, Latin\nelectronic, trap, Latin hip hop\nelectronic, trap, Latin hyperpop\nelectronic, trap, Latin pop\nelectronic, trap, Latin trap\nelectronic, trap, Mandarin pop\nelectronic, trap, Mandopop\nelectronic, trap, Middle Eastern\nelectronic, trap, Middle Eastern fusion\nelectronic, trap, North African fusion\nelectronic, trap, Persian pop\nelectronic, trap, R&B\nelectronic, trap, Romanian hip hop\nelectronic, trap, Romanian pop\nelectronic, trap, Russian hip hop\nelectronic, trap, Russian pop\nelectronic, trap, Russian rap\nelectronic, trap, South Asian\nelectronic, trap, South Asian fusion\nelectronic, trap, Spanish vocal\nelectronic, trap, Tamil hip hop\nelectronic, trap, Turkish hip hop\nelectronic, trap, Uzbek pop\nelectronic, trap, Vietnamese folk\nelectronic, trap, Vietnamese pop\nelectronic, trap, Vocaloid\nelectronic, trap, aggressive\nelectronic, trap, aggro\nelectronic, trap, ambient\nelectronic, trap, ancient style\nelectronic, trap, anime\nelectronic, trap, anime theme\nelectronic, trap, anthemic\nelectronic, trap, arcade\nelectronic, trap, arpeggiated\nelectronic, trap, art pop\nelectronic, trap, atmospheric\nelectronic, trap, breakbeat\nelectronic, trap, chiptune\nelectronic, trap, cinematic\nelectronic, trap, club\nelectronic, trap, dance\nelectronic, trap, dancehall\nelectronic, trap, danish rap\nelectronic, trap, dark pop\nelectronic, trap, deep house\nelectronic, trap, dramatic\nelectronic, trap, dream pop\nelectronic, trap, dubstep\nelectronic, trap, emotional pop\nelectronic, trap, ethereal\nelectronic, trap, experimental\nelectronic, trap, folk\nelectronic, trap, future bass\nelectronic, trap, glitch\nelectronic, trap, gospel\nelectronic, trap, guzheng\nelectronic, trap, hard-hitting\nelectronic, trap, hardcore\nelectronic, trap, hardstyle\nelectronic, trap, high-energy\nelectronic, trap, hip hop\nelectronic, trap, hip-hop\nelectronic, trap, hype\nelectronic, trap, hyperpop\nelectronic, trap, industrial\nelectronic, trap, italo dance\nelectronic, trap, lo-fi\nelectronic, trap, lo-fi hip hop\nelectronic, trap, melancholic\nelectronic, trap, melodic\nelectronic, trap, metalcore\nelectronic, trap, minimal\nelectronic, trap, motivational\nelectronic, trap, oud\nelectronic, trap, phonk\nelectronic, trap, playful\nelectronic, trap, pop\nelectronic, trap, pop-R&B\nelectronic, trap, pop-rock\nelectronic, trap, quirky\nelectronic, trap, rap\nelectronic, trap, rave\nelectronic, trap, reggaeton\nelectronic, trap, sensual\nelectronic, trap, soul\nelectronic, trap, soulful\nelectronic, trap, spiritual\nelectronic, trap, spooky\nelectronic, trap, synth-pop\nelectronic, trap, synthwave\nelectronic, trap, techno\nelectronic, trap, theatrical\nelectronic, trap, traditional East Asian\nelectronic, trap, tribal\nelectronic, trap, video game\nelectronic, trap, video game soundtrack\nelectronic, trap, vocal house\nelectronic, trap, vocaloid\nelectronic, trap, world fusion\nelectronic, trap, world music\nelectronic, trap, worldbeat\nelectronic, tribal house\nelectronic, tribal house, Arabic hip hop\nelectronic, tribal house, Latin fusion\nelectronic, tribal house, Latin pop\nelectronic, tribal house, Latin synth\nelectronic, tribal house, Middle Eastern\nelectronic, tribal house, ambient\nelectronic, tribal house, ambient techno\nelectronic, tribal house, anthemic\nelectronic, tribal house, breakbeat\nelectronic, tribal house, cinematic\nelectronic, tribal house, club\nelectronic, tribal house, dark ambient\nelectronic, tribal house, dark synth\nelectronic, tribal house, dark wave\nelectronic, tribal house, deep house\nelectronic, tribal house, deep techno\nelectronic, tribal house, experimental\nelectronic, tribal house, funk\nelectronic, tribal house, glitch\nelectronic, tribal house, hard dance\nelectronic, tribal house, hardcore\nelectronic, tribal house, melodic techno\nelectronic, tribal house, progressive\nelectronic, tribal house, rave\nelectronic, tribal house, spiritual\nelectronic, tribal house, synthwave\nelectronic, tribal house, techno\nelectronic, tribal house, vocal chop\nelectronic, tribal house, vocal house\nelectronic, tribal house, vocal trance\nelectronic, tribal house, world beat\nelectronic, tribal house, world fusion\nelectronic, tribal techno, Eastern fusion\nelectronic, tribal techno, Middle Eastern fusion\nelectronic, tribal techno, chiptune\nelectronic, tribal techno, glitch\nelectronic, tribal techno, trance\nelectronic, tribal, Arabic mawwal\nelectronic, tribal, Latin\nelectronic, tribal, Middle Eastern\nelectronic, tribal, Turkish pop\nelectronic, tribal, aggressive\nelectronic, tribal, ambient\nelectronic, tribal, anthemic\nelectronic, tribal, cinematic\nelectronic, tribal, dark pop\nelectronic, tribal, deep house\nelectronic, tribal, desert rock\nelectronic, tribal, dystopian\nelectronic, tribal, epic\nelectronic, tribal, ethereal\nelectronic, tribal, flamenco\nelectronic, tribal, future pop\nelectronic, tribal, glitch\nelectronic, tribal, high-energy\nelectronic, tribal, hip hop\nelectronic, tribal, industrial\nelectronic, tribal, industrial techno\nelectronic, tribal, intense\nelectronic, tribal, lo-fi\nelectronic, tribal, melodic\nelectronic, tribal, operatic\nelectronic, tribal, oud\nelectronic, tribal, rave\nelectronic, tribal, soulful\nelectronic, tribal, spiritual\nelectronic, tribal, synthwave\nelectronic, tribal, vocal house\nelectronic, trip hop, 90s style\nelectronic, trip-hop, C-pop\nelectronic, trip-hop, Middle Eastern\nelectronic, trip-hop, anthemic pop\nelectronic, trip-hop, art pop\nelectronic, trip-hop, experimental\nelectronic, trip-hop, retro-futuristic\nelectronic, tropical house\nelectronic, tropical house, Indian pop\nelectronic, tropical house, cinematic\nelectronic, tropical house, lo-fi\nelectronic, tropical house, synth-pop\nelectronic, tropical house, upbeat\nelectronic, tropical house, video game\nelectronic, tropical house, video game music\nelectronic, tropical house, world beat\nelectronic, tropical house, worldbeat\nelectronic, tropical, video game\nelectronic, tropical, world music\nelectronic, underground, hip hop\nelectronic, upbeat, 2000s nostalgia\nelectronic, upbeat, Japanese pop\nelectronic, upbeat, anime\nelectronic, upbeat, hypnotic\nelectronic, upbeat, mandolin\nelectronic, upbeat, motivational\nelectronic, upbeat, retro\nelectronic, upbeat, synthpop\nelectronic, upbeat, synthwave\nelectronic, upbeat, tech house\nelectronic, upbeat, video game\nelectronic, uplifting, cinematic\nelectronic, uplifting, festival\nelectronic, uplifting, gospel house\nelectronic, uplifting, hardstyle\nelectronic, uplifting, instrumental\nelectronic, uplifting, progressive\nelectronic, urban, Latin hip hop\nelectronic, urban, anthemic\nelectronic, urbano, pop\nelectronic, vaporwave, C-pop\nelectronic, vaporwave, hip hop\nelectronic, vaporwave, melodic rap\nelectronic, video game music\nelectronic, video game music, East Asian\nelectronic, video game music, J-pop\nelectronic, video game music, anime\nelectronic, video game music, funk\nelectronic, video game music, lo-fi\nelectronic, video game music, lo-fi pop\nelectronic, video game music, synthwave\nelectronic, video game music, trance\nelectronic, video game music, upbeat\nelectronic, video game soundtrack, deep house\nelectronic, video game soundtrack, synthwave\nelectronic, video game, 80s synth\nelectronic, video game, 90s retro\nelectronic, video game, 90s synth\nelectronic, video game, Chinese fusion\nelectronic, video game, East Asian\nelectronic, video game, East Asian fusion\nelectronic, video game, Middle Eastern\nelectronic, video game, ambient\nelectronic, video game, ambient house\nelectronic, video game, anime\nelectronic, video game, chiptune\nelectronic, video game, cinematic\nelectronic, video game, corporate\nelectronic, video game, demoscene\nelectronic, video game, glitch\nelectronic, video game, intense\nelectronic, video game, pop-punk\nelectronic, video game, quirky\nelectronic, video game, retro-futuristic\nelectronic, video game, rhythm game\nelectronic, video game, synth\nelectronic, video game, synthwave\nelectronic, video game, upbeat\nelectronic, vocal house, breakbeat\nelectronic, vocal house, experimental\nelectronic, vocal house, percussive\nelectronic, vocal, ambient\nelectronic, whimsical, video game\nelectronic, workout, EDM\nelectronic, workout, deep house\nelectronic, workout, game music\nelectronic, workout, hardstyle\nelectronic, workout, instructional\nelectronic, world beat\nelectronic, world beat, Afro-tech\nelectronic, world beat, Russian hip hop\nelectronic, world beat, ambient\nelectronic, world beat, ambient techno\nelectronic, world beat, chiptune\nelectronic, world beat, dance\nelectronic, world beat, deep house\nelectronic, world beat, drum & bass\nelectronic, world beat, experimental\nelectronic, world beat, glitch\nelectronic, world beat, hip-hop\nelectronic, world beat, hypnotic\nelectronic, world beat, progressive\nelectronic, world beat, rhythmic\nelectronic, world beat, synth pop\nelectronic, world beat, synthwave\nelectronic, world beat, trance\nelectronic, world beat, trap\nelectronic, world drum, synth-pop\nelectronic, world fusion\nelectronic, world fusion, Arabic\nelectronic, world fusion, EDM\nelectronic, world fusion, Malay pop\nelectronic, world fusion, Middle Eastern\nelectronic, world fusion, Sinhala pop\nelectronic, world fusion, agogo\nelectronic, world fusion, ambient\nelectronic, world fusion, ambient techno\nelectronic, world fusion, anthemic\nelectronic, world fusion, breakbeat\nelectronic, world fusion, chillwave\nelectronic, world fusion, chiptune\nelectronic, world fusion, cinematic\nelectronic, world fusion, dance\nelectronic, world fusion, dance-pop\nelectronic, world fusion, deep house\nelectronic, world fusion, downtempo\nelectronic, world fusion, drum & bass\nelectronic, world fusion, drum and bass\nelectronic, world fusion, dubstep\nelectronic, world fusion, experimental\nelectronic, world fusion, funk\nelectronic, world fusion, hardstyle\nelectronic, world fusion, house\nelectronic, world fusion, hypnotic\nelectronic, world fusion, instrumental\nelectronic, world fusion, lo-fi\nelectronic, world fusion, lo-fi hip hop\nelectronic, world fusion, pop\nelectronic, world fusion, retro synth\nelectronic, world fusion, rhythmic\nelectronic, world fusion, soul\nelectronic, world fusion, techno\nelectronic, world fusion, trance\nelectronic, world fusion, trap\nelectronic, world fusion, video game music\nelectronic, world fusion, video game soundtrack\nelectronic, world house, ambient\nelectronic, world music\nelectronic, world music, Brazilian funk\nelectronic, world music, C-pop\nelectronic, world music, French pop\nelectronic, world music, ambient\nelectronic, world music, breakbeat\nelectronic, world music, chiptune\nelectronic, world music, deep house\nelectronic, world music, devotional\nelectronic, world music, experimental\nelectronic, world music, funk\nelectronic, world music, glitch\nelectronic, world music, hardstyle\nelectronic, world music, hip hop\nelectronic, world music, house\nelectronic, world music, industrial\nelectronic, world music, lo-fi\nelectronic, world music, lo-fi hip hop\nelectronic, world music, psychedelic\nelectronic, world music, psychedelic rock\nelectronic, world music, synthwave\nelectronic, world music, trance\nelectronic, world music, trap\nelectronic, world music, video game soundtrack\nelectronic, world percussion, drum & bass\nelectronic, world percussion, hip-hop\nelectronic, world pop, cinematic\nelectronic, world, instrumental\nelectronic, worldbeat, Arabic fusion\nelectronic, worldbeat, chiptune\nelectronic, worldbeat, cinematic\nelectronic, worldbeat, hip-hop\nelectronic, worldbeat, lo-fi\nelectronic, worldbeat, lounge\nelectronic, worldbeat, video game\nelectronic, worldbeat, video game music\nelectronic, wuxia, Chinese hip hop\nelectronic-folk\nelectronic-folk fusion\nelectronica\nelectronica IDM ambient house\nelectronica IDM deep house\nelectronica chillwave soulful R&B\nelectronica post-rock\nelectronica progressive house\nelectronicore\nelectronicore C-pop\nelectronicore J-rock\nelectronicore J-rock power metal\nelectronicore K-pop rock\nelectronicore K-rock\nelectronicore alternative metal\nelectronicore chiptune\nelectronicore chiptune future bass\nelectronicore chiptune metalcore\nelectronicore chiptune rock\nelectronicore cyber metal\nelectronicore cyber-metal\nelectronicore cybergrind\nelectronicore cyberpunk metal\nelectronicore cyberpunk rock\nelectronicore digital hardcore\nelectronicore djent\nelectronicore drum & bass\nelectronicore dubstep\nelectronicore dubstep metalcore\nelectronicore dubstep post-hardcore\nelectronicore emo-pop\nelectronicore future bass\nelectronicore glitchcore\nelectronicore happy hardcore\nelectronicore hardstyle\nelectronicore hyperpop\nelectronicore hyperpop metalcore\nelectronicore hyperpop trance\nelectronicore industrial metal\nelectronicore industrial rock\nelectronicore metalcore\nelectronicore metalcore J-rock\nelectronicore metalcore dubstep\nelectronicore metalcore hardstyle\nelectronicore metalcore j-rock\nelectronicore metalcore trance\nelectronicore nintendocore\nelectronicore nu-metal\nelectronicore nu-metal dubstep\nelectronicore pop-punk\nelectronicore post-hardcore\nelectronicore punk rock\nelectronicore rap metal\nelectronicore rap-rock\nelectronicore speed metal\nelectronicore symphonic metal\nelectronicore symphonic metalcore\nelectronicore synth-rock\nelectronicore trance\nelectronicore trancecore\nelectronicore worship\nelectronicore, J-rock, chiptune\nelectronicore, J-rock, cinematic\nelectronicore, J-rock, lo-fi\nelectronicore, J-rock, metalcore\nelectronicore, J-rock, rap-metal\nelectronicore, J-rock, trancecore\nelectronicore, K-rock\nelectronicore, dubstep, cinematic\nelectronicore, hardstyle, symphonic metal\nelectronicore, industrial rock, cinematic\nelectronicore, post-hardcore, metalcore\nelectronicore, post-hardcore, trap\nelectronicore, speed metal, chiptune\nelectropop\nelectropop 80s synth-pop\nelectropop C-pop\nelectropop Christian pop\nelectropop Christmas\nelectropop Indian pop\nelectropop J-pop\nelectropop J-pop anime\nelectropop Latin\nelectropop Latin-pop\nelectropop R&B\nelectropop Tollywood\nelectropop anime\nelectropop bubblegum pop\nelectropop chillwave\nelectropop chiptune\nelectropop chiptune J-pop\nelectropop chiptune dancehall\nelectropop chiptune reggaeton\nelectropop cinematic\nelectropop dance-pop\nelectropop dream pop\nelectropop dubstep\nelectropop future bass\nelectropop future bass J-pop\nelectropop future bass hardstyle\nelectropop future bass hyperpop\nelectropop future bass trap\nelectropop futurepop\nelectropop glitch\nelectropop gospel\nelectropop hip-hop\nelectropop hyperpop\nelectropop hyperpop K-pop\nelectropop hyperpop chiptune\nelectropop hyperpop j-pop\nelectropop hyperpop pop-punk\nelectropop indie pop\nelectropop j-pop\nelectropop j-pop chiptune\nelectropop lo-fi\nelectropop reggaeton\nelectropop trap\nelectropop trap K-pop\nelectropop trap R&B\nelectropop tropical\nelectropop tropical house\nelectropop, Balkan pop\nelectropop, Brazilian pop\nelectropop, Dutch, Eurodance\nelectropop, EDM\nelectropop, EDM, dance-pop\nelectropop, Eastern European, Turkish\nelectropop, J-pop\nelectropop, J-pop, Eurodance\nelectropop, J-pop, K-pop\nelectropop, J-pop, UK garage\nelectropop, J-pop, anime\nelectropop, J-pop, anime theme\nelectropop, J-pop, chiptune\nelectropop, J-pop, future bass\nelectropop, J-pop, happy hardcore\nelectropop, J-pop, hyperpop\nelectropop, J-pop, video game music\nelectropop, K-pop\nelectropop, K-pop, T-pop\nelectropop, K-pop, chiptune\nelectropop, K-pop, hyperpop\nelectropop, Latin pop\nelectropop, Latin, dance\nelectropop, Latin, pop\nelectropop, Latin, reggaeton\nelectropop, Latin, trap\nelectropop, Raï, Arabic pop\nelectropop, Turkish pop, Eastern European\nelectropop, UK garage, 2-step\nelectropop, ambient, pop-rock\nelectropop, chiptune, J-pop\nelectropop, chiptune, T-Pop\nelectropop, chiptune, cinematic\nelectropop, chiptune, high-energy\nelectropop, chiptune, hyperpop\nelectropop, chiptune, pop-punk\nelectropop, cinematic, dance-pop\nelectropop, cinematic, hyperpop\nelectropop, complextro\nelectropop, dancehall, moombahton\nelectropop, dubstep, cinematic\nelectropop, eurodance, hyperpop\nelectropop, folk pop\nelectropop, future bass\nelectropop, future bass, Brazilian\nelectropop, future bass, Latin pop\nelectropop, future bass, cinematic\nelectropop, future bass, dream pop\nelectropop, future bass, sad pop\nelectropop, hardstyle\nelectropop, hardstyle, happy hardcore\nelectropop, hardstyle, trap\nelectropop, hip hop, chiptune\nelectropop, hip-hop\nelectropop, hyperpop\nelectropop, hyperpop, German pop\nelectropop, hyperpop, J-pop\nelectropop, hyperpop, J-rock\nelectropop, hyperpop, K-pop\nelectropop, hyperpop, Latin pop\nelectropop, hyperpop, cinematic\nelectropop, hyperpop, dance-pop\nelectropop, hyperpop, hardstyle\nelectropop, hyperpop, nightcore\nelectropop, hyperpop, trap\nelectropop, kawaii, J-pop\nelectropop, musical theater, EDM\nelectropop, nightcore, hyperpop\nelectropop, pop-punk, hyperpop\nelectropop, progressive house\nelectropop, reggaeton\nelectropop, synth-pop, K-pop\nelectropop, synth-pop, dance-pop\nelectropop, synth-pop, future bass\nelectropop, trap, aggressive\nelectropop, trap, ambient\nelectropop, trap, chiptune\nelectropop, trap, cinematic\nelectropop, trap, hyperpop\nelectropop, trap, synthwave\nelectropop, video game, quirky\nelectropunk\nelegant piano\nemo\nemo R&B\nemo R&B trap\nemo R&B, trap, atmospheric hip-hop\nemo R&B, trap, chopped and screwed\nemo alternative rock\nemo ballad\nemo drill\nemo electronic\nemo folk\nemo folk rap\nemo future bass\nemo hip hop\nemo hip-hop\nemo house\nemo indie folk\nemo indie rock\nemo lo-fi hip hop\nemo metalcore\nemo piano\nemo piano ballad\nemo pop\nemo pop R&B\nemo pop future bass\nemo pop lo-fi hip-hop\nemo pop rap\nemo pop rock\nemo pop trap\nemo pop, trap\nemo pop, trap, cinematic\nemo pop-punk\nemo pop-punk metalcore\nemo pop-punk, metalcore\nemo pop-rap\nemo pop-rock\nemo post-hardcore\nemo punk\nemo rap\nemo rap C-pop\nemo rap C-pop trap\nemo rap Mandopop\nemo rap Mandopop R&B\nemo rap acoustic hip-hop\nemo rap acoustic pop\nemo rap acoustic trap\nemo rap alternative R&B\nemo rap alternative pop\nemo rap alternative rock\nemo rap alternative rock hyperpop\nemo rap ambient pop\nemo rap ambient rock\nemo rap chiptune\nemo rap cloud rap\nemo rap cloud rap C-pop\nemo rap cloud rap alternative rock\nemo rap cloud rap indie pop\nemo rap cloud rap indie rock\nemo rap cloud rap pop-trap\nemo rap dark pop\nemo rap dream pop\nemo rap funk\nemo rap hyperpop\nemo rap indie pop\nemo rap indie rock\nemo rap lo-fi\nemo rap lo-fi R&B\nemo rap lo-fi acoustic\nemo rap lo-fi hip hop\nemo rap lo-fi hip-hop\nemo rap lo-fi indie\nemo rap lo-fi pop\nemo rap lo-fi trap\nemo rap metalcore electronic\nemo rap pop-punk alternative rock\nemo rap rock\nemo rap shoegaze\nemo rap trap\nemo rap trap metal\nemo rap trap pop-rock\nemo rap trap soul\nemo rap trap synth-pop\nemo rap trap-soul\nemo rap vaporwave\nemo rap, Brazilian trap\nemo rap, C-Pop R&B\nemo rap, C-pop\nemo rap, C-pop ballad\nemo rap, C-pop trap\nemo rap, C-pop, acoustic pop\nemo rap, C-pop, ambient\nemo rap, C-pop, atmospheric pop\nemo rap, C-pop, chiptune\nemo rap, C-pop, contemporary R&B\nemo rap, C-pop, hyperpop\nemo rap, C-pop, indie-pop\nemo rap, C-pop, indie-rock\nemo rap, C-pop, lo-fi\nemo rap, C-pop, lo-fi hip hop\nemo rap, C-pop, lo-fi hip-hop\nemo rap, C-pop, lo-fi trap\nemo rap, C-pop, synth pop\nemo rap, C-pop, trap\nemo rap, C-pop, trap-R&B\nemo rap, C-pop, vaporwave\nemo rap, Christian hip-hop\nemo rap, Dutch trap\nemo rap, Filipino hip-hop\nemo rap, French cloud rap\nemo rap, French hip-hop\nemo rap, French pop, trap\nemo rap, German cloud rap\nemo rap, German hip-hop\nemo rap, Italian cloud rap\nemo rap, Italian hip-hop\nemo rap, Italian pop-rap\nemo rap, Italian trap\nemo rap, Italian trap, lo-fi\nemo rap, J-hip-hop\nemo rap, J-pop trap\nemo rap, J-pop, trap\nemo rap, J-rap, atmospheric trap\nemo rap, J-rock\nemo rap, J-rock, atmospheric pop\nemo rap, K-hip-hop\nemo rap, K-pop, synthwave\nemo rap, Korean R&B\nemo rap, Korean hip-hop\nemo rap, Latin R&B\nemo rap, Latin hip hop\nemo rap, Latin hip-hop\nemo rap, Latin pop, lo-fi trap\nemo rap, Latin trap\nemo rap, Latin trap, lo-fi\nemo rap, Latin trap, lo-fi hip-hop\nemo rap, Mandopop\nemo rap, Mandopop, bedroom pop\nemo rap, Mandopop, lo-fi hip hop\nemo rap, Mandopop, trap\nemo rap, Mandopop, trap-soul\nemo rap, Mandopop, vaporwave\nemo rap, R&B\nemo rap, R&B, lo-fi\nemo rap, R&B, lo-fi hip hop\nemo rap, Thai pop\nemo rap, Turkish trap\nemo rap, UK hip-hop, lo-fi hip-hop\nemo rap, acoustic pop\nemo rap, acoustic pop-punk\nemo rap, acoustic pop-rap\nemo rap, acoustic pop-trap\nemo rap, acoustic singer-songwriter\nemo rap, acoustic trap\nemo rap, afro trap\nemo rap, aggressive dubstep\nemo rap, alternative R&B\nemo rap, alternative R&B, cloud rap\nemo rap, alternative R&B, electronic\nemo rap, alternative R&B, hyperpop\nemo rap, alternative R&B, lo-fi hip hop\nemo rap, alternative R&B, lo-fi hip-hop\nemo rap, alternative R&B, pop-trap\nemo rap, alternative R&B, post-rock\nemo rap, alternative R&B, trap\nemo rap, alternative hip-hop\nemo rap, alternative hip-hop, lo-fi hip-hop\nemo rap, alternative pop, lo-fi hip hop\nemo rap, alternative rock\nemo rap, alternative rock, lo-fi\nemo rap, alternative rock, lo-fi hip-hop\nemo rap, alternative rock, pop-punk\nemo rap, alternative rock, post-punk\nemo rap, alternative rock, trap\nemo rap, atmospheric R&B\nemo rap, atmospheric hip-hop\nemo rap, atmospheric hip-hop, sad pop\nemo rap, atmospheric indie rock\nemo rap, atmospheric pop\nemo rap, atmospheric pop, trap\nemo rap, atmospheric pop-trap\nemo rap, atmospheric trap\nemo rap, atmospheric trap, lo-fi\nemo rap, atmospheric, trap\nemo rap, bedroom pop\nemo rap, bedroom pop, lo-fi\nemo rap, bedroom pop, lo-fi hip hop\nemo rap, bedroom pop, lo-fi hip-hop\nemo rap, bilingual R&B\nemo rap, chiptune hip-hop\nemo rap, cinematic pop, trap\nemo rap, cinematic rock, cloud rap\nemo rap, cinematic trap, ambient\nemo rap, cinematic, trap\nemo rap, cloud rap\nemo rap, cloud rap, Afrobeats\nemo rap, cloud rap, C-pop\nemo rap, cloud rap, Chinese trap\nemo rap, cloud rap, French pop\nemo rap, cloud rap, Italian hip-hop\nemo rap, cloud rap, Italian pop\nemo rap, cloud rap, J-pop\nemo rap, cloud rap, K-pop\nemo rap, cloud rap, Latin hip hop\nemo rap, cloud rap, Mandarin hip hop\nemo rap, cloud rap, Mandarin trap\nemo rap, cloud rap, Mandopop\nemo rap, cloud rap, R&B\nemo rap, cloud rap, acoustic\nemo rap, cloud rap, acoustic pop\nemo rap, cloud rap, alternative R&B\nemo rap, cloud rap, alternative rock\nemo rap, cloud rap, ambient\nemo rap, cloud rap, ambient pop\nemo rap, cloud rap, ambient trap\nemo rap, cloud rap, anime pop\nemo rap, cloud rap, atmospheric\nemo rap, cloud rap, atmospheric R&B\nemo rap, cloud rap, atmospheric pop\nemo rap, cloud rap, atmospheric trap\nemo rap, cloud rap, bedroom pop\nemo rap, cloud rap, chiptune\nemo rap, cloud rap, cinematic\nemo rap, cloud rap, cinematic trap\nemo rap, cloud rap, dark pop\nemo rap, cloud rap, dark trap\nemo rap, cloud rap, dream pop\nemo rap, cloud rap, hyperpop\nemo rap, cloud rap, indie pop\nemo rap, cloud rap, indie rock\nemo rap, cloud rap, indie trap\nemo rap, cloud rap, indie-pop\nemo rap, cloud rap, industrial\nemo rap, cloud rap, jazzy trap\nemo rap, cloud rap, lo-fi\nemo rap, cloud rap, lo-fi R&B\nemo rap, cloud rap, lo-fi hip hop\nemo rap, cloud rap, lo-fi hip-hop\nemo rap, cloud rap, lo-fi jazz\nemo rap, cloud rap, lo-fi pop\nemo rap, cloud rap, lo-fi trap\nemo rap, cloud rap, math rock\nemo rap, cloud rap, melodic trap\nemo rap, cloud rap, modern R&B\nemo rap, cloud rap, modern trap\nemo rap, cloud rap, pop\nemo rap, cloud rap, pop-R&B\nemo rap, cloud rap, pop-punk\nemo rap, cloud rap, pop-trap\nemo rap, cloud rap, sad trap\nemo rap, cloud rap, surf rock\nemo rap, cloud rap, synth pop\nemo rap, cloud rap, synth-pop\nemo rap, cloud rap, synthwave\nemo rap, cloud rap, trap\nemo rap, cloud rap, vaporwave\nemo rap, cloud rap, world music\nemo rap, contemporary R&B\nemo rap, contemporary R&B, trap\nemo rap, cyberpunk, future bass\nemo rap, dark R&B\nemo rap, dark hip-hop\nemo rap, dark pop\nemo rap, dark pop, atmospheric rock\nemo rap, dark pop, trap\nemo rap, dark trap\nemo rap, dark trap, lo-fi\nemo rap, dark trap, lo-fi hip hop\nemo rap, dream pop\nemo rap, dream pop, lo-fi hip hop\nemo rap, dream pop, trap\nemo rap, dream-pop, hyperpop\nemo rap, electronic hip-hop\nemo rap, electronic pop\nemo rap, future bass, trap\nemo rap, glitch-hop, hyperpop\nemo rap, hard trap\nemo rap, hyperpop\nemo rap, hyperpop, C-pop\nemo rap, hyperpop, Latin pop\nemo rap, hyperpop, alternative rock\nemo rap, hyperpop, ambient\nemo rap, hyperpop, ambient trap\nemo rap, hyperpop, atmospheric pop\nemo rap, hyperpop, atmospheric pop-punk\nemo rap, hyperpop, chiptune\nemo rap, hyperpop, cinematic trap\nemo rap, hyperpop, cloud rap\nemo rap, hyperpop, dark trap\nemo rap, hyperpop, dream pop\nemo rap, hyperpop, electronic\nemo rap, hyperpop, electronicore\nemo rap, hyperpop, future trap\nemo rap, hyperpop, hardstyle\nemo rap, hyperpop, indie rock\nemo rap, hyperpop, lo-fi\nemo rap, hyperpop, lo-fi bedroom pop\nemo rap, hyperpop, lo-fi hip hop\nemo rap, hyperpop, lo-fi hip-hop\nemo rap, hyperpop, lo-fi trap\nemo rap, hyperpop, math rock\nemo rap, hyperpop, pop\nemo rap, hyperpop, pop-punk\nemo rap, hyperpop, synthwave\nemo rap, hyperpop, trap\nemo rap, hyperpop, trap metal\nemo rap, hyperpop, vaporwave\nemo rap, indie pop\nemo rap, indie pop, C-pop\nemo rap, indie pop, lo-fi hip hop\nemo rap, indie pop, lo-fi hip-hop\nemo rap, indie rock\nemo rap, indie rock, Chinese hip-hop\nemo rap, indie rock, lo-fi\nemo rap, lo-fi R&B\nemo rap, lo-fi hip hop\nemo rap, lo-fi hip hop, C-pop\nemo rap, lo-fi hip hop, Chinese hip hop\nemo rap, lo-fi hip hop, Chinese indie\nemo rap, lo-fi hip hop, Chinese trap\nemo rap, lo-fi hip hop, J-hip-hop\nemo rap, lo-fi hip hop, Mandarin\nemo rap, lo-fi hip hop, Mandarin rap\nemo rap, lo-fi hip hop, ambient\nemo rap, lo-fi hip hop, anime\nemo rap, lo-fi hip hop, atmospheric\nemo rap, lo-fi hip hop, atmospheric pop\nemo rap, lo-fi hip hop, bedroom pop\nemo rap, lo-fi hip hop, cinematic\nemo rap, lo-fi hip hop, contemporary R&B\nemo rap, lo-fi hip hop, dream pop\nemo rap, lo-fi hip hop, hyperpop\nemo rap, lo-fi hip hop, indie rock\nemo rap, lo-fi hip hop, melancholic\nemo rap, lo-fi hip hop, melancholic pop\nemo rap, lo-fi hip hop, trap\nemo rap, lo-fi hip-hop\nemo rap, lo-fi hip-hop, C-pop\nemo rap, lo-fi hip-hop, C-pop ballad\nemo rap, lo-fi hip-hop, Chinese electronic\nemo rap, lo-fi hip-hop, Chinese emo\nemo rap, lo-fi hip-hop, Chinese indie\nemo rap, lo-fi hip-hop, J-pop\nemo rap, lo-fi hip-hop, Latin trap\nemo rap, lo-fi hip-hop, Mandarin\nemo rap, lo-fi hip-hop, Mandopop\nemo rap, lo-fi hip-hop, R&B\nemo rap, lo-fi hip-hop, atmospheric\nemo rap, lo-fi hip-hop, bedroom pop\nemo rap, lo-fi hip-hop, cloud rap\nemo rap, lo-fi hip-hop, contemporary R&B\nemo rap, lo-fi hip-hop, future bass\nemo rap, lo-fi hip-hop, indie pop\nemo rap, lo-fi hip-hop, indie rock\nemo rap, lo-fi hip-hop, melancholic\nemo rap, lo-fi hip-hop, pop-punk\nemo rap, lo-fi hip-hop, sad pop\nemo rap, lo-fi hip-hop, trap\nemo rap, lo-fi pop, dark trap\nemo rap, lo-fi trap\nemo rap, lo-fi, bedroom pop\nemo rap, lo-fi, chiptune\nemo rap, lo-fi, cloud rap\nemo rap, lo-fi, trap\nemo rap, melodic trap\nemo rap, melodic trap, Spanish flavor\nemo rap, melodic trap, chiptune\nemo rap, melodic trap, cinematic\nemo rap, melodic trap, lo-fi\nemo rap, melodic trap, lo-fi hip hop\nemo rap, modern trap\nemo rap, modern trap, Latin pop\nemo rap, modern trap, classical synth\nemo rap, nu-metal, lo-fi\nemo rap, nu-metal, math-rock\nemo rap, phonk, lo-fi\nemo rap, pluggnb\nemo rap, pluggnb, vaporwave\nemo rap, pop rap, lo-fi hip-hop\nemo rap, pop-punk\nemo rap, pop-punk, C-pop\nemo rap, pop-punk, atmospheric\nemo rap, pop-punk, trap\nemo rap, pop-rap\nemo rap, pop-rock\nemo rap, pop-trap\nemo rap, pop-trap, indie-pop\nemo rap, post-hardcore, metalcore\nemo rap, reggaeton\nemo rap, romantic C-pop\nemo rap, sad pop\nemo rap, sad pop, Indian hip-hop\nemo rap, sad pop-trap\nemo rap, sad trap\nemo rap, sad trap, lo-fi hip hop\nemo rap, sadcore hip-hop, cinematic rock\nemo rap, shoegaze, ambient\nemo rap, shoegaze, trap\nemo rap, trap\nemo rap, trap metal\nemo rap, trap metal, indie rock\nemo rap, trap metal, lo-fi\nemo rap, trap metal, nu-metal\nemo rap, trap metal, piano ballad\nemo rap, trap soul\nemo rap, trap, Arabic pop\nemo rap, trap, C-pop\nemo rap, trap, C-pop ballad\nemo rap, trap, C-rap\nemo rap, trap, Chinese indie\nemo rap, trap, Chinese pop\nemo rap, trap, Italian pop\nemo rap, trap, J-pop\nemo rap, trap, Korean hip-hop\nemo rap, trap, Latin R&B\nemo rap, trap, Latin guitar\nemo rap, trap, Latin pop\nemo rap, trap, Latin-influenced\nemo rap, trap, Latin-pop\nemo rap, trap, Mandarin pop\nemo rap, trap, Mandopop\nemo rap, trap, North African\nemo rap, trap, North African hip-hop\nemo rap, trap, Polish hip-hop\nemo rap, trap, R&B\nemo rap, trap, alternative R&B\nemo rap, trap, alternative rock\nemo rap, trap, ambient\nemo rap, trap, atmospheric R&B\nemo rap, trap, atmospheric pop\nemo rap, trap, chiptune\nemo rap, trap, chopped and screwed\nemo rap, trap, cinematic\nemo rap, trap, classical\nemo rap, trap, cloud rap\nemo rap, trap, contemporary R&B\nemo rap, trap, drill\nemo rap, trap, glitch\nemo rap, trap, hip-hop\nemo rap, trap, hyperpop\nemo rap, trap, industrial\nemo rap, trap, industrial hip-hop\nemo rap, trap, lo-fi\nemo rap, trap, lo-fi hip hop\nemo rap, trap, lo-fi hip-hop\nemo rap, trap, medieval ambient\nemo rap, trap, nu-metal\nemo rap, trap, pop\nemo rap, trap, psychedelic\nemo rap, trap, rock\nemo rap, trap, sad pop\nemo rap, trap, vaporwave\nemo rap, trap-soul\nemo rap, trap-soul, C-pop\nemo rap, trap-soul, R&B\nemo rap, vaporwave, hyperpop\nemo rap, vaporwave, lo-fi hip hop\nemo rap, vaporwave, trap\nemo revival\nemo revival trap\nemo revival, lo-fi hip hop, C-pop\nemo revival, lo-fi hip-hop, shoegaze\nemo revival, trap\nemo revival, trap, hyperpop\nemo rock\nemo rock post-hardcore\nemo rock, C-pop\nemo rock, J-rock\nemo rock, dubstep\nemo rock, hip-hop, ambient\nemo rock, hyperpop\nemo rock, indie rock, pop-punk\nemo rock, metalcore\nemo rock, post-hardcore\nemo rock, rap rock, pop-rock\nemo rock, trap\nemo rock, trap, C-pop\nemo rock, trap, indie\nemo soul\nemo synth\nemo trap\nemo trap ambient rock\nemo trap, Arabic hip-hop\nemo trap, C-pop\nemo trap, French cloud rap\nemo trap, Korean hip-hop\nemo trap, Latin R&B\nemo trap, Latin pop\nemo trap, Latin trap\nemo trap, Latin trap, lo-fi\nemo trap, alternative R&B\nemo trap, atmospheric R&B, cloud rap\nemo trap, cloud rap\nemo trap, cloud rap, C-pop\nemo trap, cloud rap, East Asian pop\nemo trap, cloud rap, Italian hip-hop\nemo trap, cloud rap, Latin trap\nemo trap, cloud rap, Latin urban\nemo trap, cloud rap, R&B\nemo trap, cloud rap, ambient\nemo trap, cloud rap, atmospheric R&B\nemo trap, cloud rap, atmospheric electronic\nemo trap, cloud rap, atmospheric pop\nemo trap, cloud rap, industrial hip hop\nemo trap, cloud rap, lo-fi\nemo trap, cloud rap, lo-fi hip hop\nemo trap, cloud rap, vaporwave\nemo trap, dark pop\nemo trap, future bass, sad pop\nemo trap, hyperpop\nemo trap, hyperpop, cinematic\nemo trap, lo-fi hip hop\nemo trap, lo-fi hip hop, C-pop\nemo trap, melodic hip-hop\nemo trap, melodic rap\nemo trap, sad rap\nemo trap, sad reggaeton\nemo trap, sad reggaeton, Latin trap\nemo trap, vaporwave\nemo, hyperpop, lo-fi\nemo, metalcore, alternative rock\nemo, pop-punk, metalcore\nemo, post-hardcore\nemo, post-hardcore, alternative rock\nemo, post-hardcore, chiptune\nemo, post-hardcore, djent\nemo, post-hardcore, doom\nemo, post-hardcore, hardcore punk\nemo, post-hardcore, hip-hop\nemo, post-hardcore, math rock\nemo, post-hardcore, metalcore\nemo, post-hardcore, screamo\nemo, post-rock\nemo, post-rock, C-pop\nemo, post-rock, indie rock\nemo, post-rock, metalcore\nemo-R&B\nemo-acoustic\nemo-acoustic alternative rock\nemo-acoustic indie folk\nemo-acoustic indie pop\nemo-acoustic pop-punk\nemo-acoustic, future bass\nemo-acoustic, hyperpop\nemo-electronic\nemo-folk\nemo-folk alternative rock\nemo-folk hyperpop\nemo-folk lo-fi\nemo-folk pop-punk\nemo-folk post-hardcore\nemo-folk trap\nemo-pop\nemo-pop alternative R&B\nemo-pop alternative pop\nemo-pop alternative rock\nemo-pop bedroom pop\nemo-pop chiptune\nemo-pop cloud rap\nemo-pop dance-pop\nemo-pop dubstep\nemo-pop electronic\nemo-pop electronic rock\nemo-pop future bass\nemo-pop hyperpop\nemo-pop indie pop\nemo-pop indie rock\nemo-pop indie-pop\nemo-pop latin pop\nemo-pop lo-fi\nemo-pop lo-fi hip-hop\nemo-pop lo-fi pop\nemo-pop math-rock\nemo-pop pop-punk\nemo-pop post-hardcore\nemo-pop rap-rock\nemo-pop rock\nemo-pop trap\nemo-pop trap hyperpop\nemo-pop trap metal\nemo-pop trap-pop\nemo-pop, cloud rap, hyperpop\nemo-pop, conscious hip-hop\nemo-pop, dubstep, cinematic\nemo-pop, future bass, pop-punk\nemo-pop, hyperpop\nemo-pop, hyperpop, UK garage\nemo-pop, hyperpop, cinematic\nemo-pop, hyperpop, electronic\nemo-pop, hyperpop, electronic rock\nemo-pop, hyperpop, lo-fi\nemo-pop, hyperpop, metalcore\nemo-pop, hyperpop, pop\nemo-pop, hyperpop, pop-punk\nemo-pop, pop-punk\nemo-pop, pop-punk, Latin hip-hop\nemo-pop, pop-punk, cloud-rap\nemo-pop, pop-punk, emo-rock\nemo-pop, pop-punk, lo-fi\nemo-pop, pop-punk, metalcore\nemo-pop, pop-punk, trap\nemo-pop, pop-rock\nemo-pop-punk\nemo-punk\nemo-punk lo-fi\nemo-rap\nemo-rap C-pop\nemo-rap C-pop trap\nemo-rap J-pop\nemo-rap K-pop\nemo-rap Latin trap\nemo-rap R&B\nemo-rap acoustic hip-hop\nemo-rap acoustic pop\nemo-rap alternative R&B\nemo-rap alternative rock\nemo-rap chiptune\nemo-rap chiptune hyperpop\nemo-rap chiptune trap\nemo-rap cloud rap\nemo-rap cloud-rap\nemo-rap country-pop\nemo-rap drill\nemo-rap dubstep\nemo-rap future bass\nemo-rap future bass hyperpop\nemo-rap hyperpop\nemo-rap hyperpop electronic rock\nemo-rap hyperpop trap\nemo-rap indie pop\nemo-rap indie rock\nemo-rap indie-pop\nemo-rap lo-fi\nemo-rap lo-fi bedroom pop\nemo-rap lo-fi hip hop\nemo-rap lo-fi hip-hop\nemo-rap lo-fi hip-hop chiptune\nemo-rap lo-fi hip-hop hyperpop\nemo-rap lo-fi pop\nemo-rap lo-fi trap\nemo-rap nu-metal\nemo-rap nu-metal hyperpop\nemo-rap pop-R&B\nemo-rap pop-punk\nemo-rap pop-punk hyperpop\nemo-rap pop-rap\nemo-rap pop-rock\nemo-rap pop-trap\nemo-rap post-hardcore\nemo-rap sad-trap\nemo-rap shoegaze\nemo-rap trap\nemo-rap trap Mandopop\nemo-rap trap R&B\nemo-rap trap hyperpop\nemo-rap trap metal\nemo-rap trap pop-punk\nemo-rap trap-metal\nemo-rap trap-rock\nemo-rap trap-soul\nemo-rap vaporwave\nemo-rap, C-pop\nemo-rap, C-pop, lo-fi hip hop\nemo-rap, C-pop, trap\nemo-rap, Chinese flute, trap\nemo-rap, Italian pop-rap, trap\nemo-rap, K-indie, bedroom-pop\nemo-rap, K-pop, pop-rock\nemo-rap, Latin trap\nemo-rap, Mandopop, trap\nemo-rap, R&B, ambient\nemo-rap, R&B, lo-fi\nemo-rap, R&B, trap\nemo-rap, acoustic, trap\nemo-rap, alternative R&B\nemo-rap, alternative R&B, pop-rock\nemo-rap, alternative R&B, trap\nemo-rap, alternative rock, ambient\nemo-rap, alternative rock, hip-hop\nemo-rap, alternative rock, lo-fi\nemo-rap, alternative rock, lo-fi hip hop\nemo-rap, alternative rock, pop-rock\nemo-rap, ambient pop, German choral\nemo-rap, ambient trap, Chinese pop\nemo-rap, ambient trap, experimental\nemo-rap, ambient, C-pop\nemo-rap, ambient, trap\nemo-rap, atmospheric, C-pop\nemo-rap, atmospheric, Mandarin\nemo-rap, atmospheric, hyperpop\nemo-rap, atmospheric, lo-fi\nemo-rap, atmospheric, trap\nemo-rap, bedroom pop\nemo-rap, bedroom pop, lo-fi hip hop\nemo-rap, bedroom pop, lo-fi hip-hop\nemo-rap, bilingual, acoustic\nemo-rap, chiptune, cloud rap\nemo-rap, chiptune, hyperpop\nemo-rap, chiptune, lo-fi hip-hop\nemo-rap, chiptune, trap\nemo-rap, cinematic pop-rock, lo-fi\nemo-rap, cinematic, French spoken word\nemo-rap, cinematic, lo-fi\nemo-rap, cinematic, lo-fi hip hop\nemo-rap, cinematic, metalcore\nemo-rap, cinematic, trap\nemo-rap, classical, trap\nemo-rap, cloud rap\nemo-rap, cloud rap, C-pop\nemo-rap, cloud rap, German pop\nemo-rap, cloud rap, Italian hip-hop\nemo-rap, cloud rap, Mandarin hip hop\nemo-rap, cloud rap, Mandopop\nemo-rap, cloud rap, R&B\nemo-rap, cloud rap, acoustic pop\nemo-rap, cloud rap, alternative R&B\nemo-rap, cloud rap, alternative guitar\nemo-rap, cloud rap, alternative pop\nemo-rap, cloud rap, alternative rock\nemo-rap, cloud rap, ambient pop\nemo-rap, cloud rap, atmospheric\nemo-rap, cloud rap, bedroom pop\nemo-rap, cloud rap, chiptune\nemo-rap, cloud rap, hyperpop\nemo-rap, cloud rap, indie guitar\nemo-rap, cloud rap, indie hip hop\nemo-rap, cloud rap, indie pop\nemo-rap, cloud rap, indie rock\nemo-rap, cloud rap, lo-fi\nemo-rap, cloud rap, lo-fi hip hop\nemo-rap, cloud rap, lo-fi hip-hop\nemo-rap, cloud rap, melodic trap\nemo-rap, cloud rap, modern R&B\nemo-rap, cloud rap, phonk\nemo-rap, cloud rap, pop\nemo-rap, cloud rap, pop-punk\nemo-rap, cloud rap, pop-trap\nemo-rap, cloud rap, sad pop\nemo-rap, cloud rap, sad trap\nemo-rap, cloud rap, trap\nemo-rap, cloud rap, vaporwave\nemo-rap, cloud-rap, lo-fi\nemo-rap, dark pop, trap\nemo-rap, dream pop, lo-fi hip hop\nemo-rap, dream pop, trap\nemo-rap, dream trap, atmospheric\nemo-rap, dreamy trap, atmospheric\nemo-rap, dreamy, lo-fi\nemo-rap, dreamy, trap\nemo-rap, drill, trap\nemo-rap, electronic rock, metal\nemo-rap, flamenco, trap\nemo-rap, future bass, lo-fi hip-hop\nemo-rap, future trap, chopped and screwed\nemo-rap, hardstyle, trap\nemo-rap, hip-hop, lo-fi\nemo-rap, hip-hop, pop-rock\nemo-rap, hyperpop\nemo-rap, hyperpop, C-pop\nemo-rap, hyperpop, ambient\nemo-rap, hyperpop, ambient trap\nemo-rap, hyperpop, atmospheric\nemo-rap, hyperpop, chiptune\nemo-rap, hyperpop, cloud rap\nemo-rap, hyperpop, cloud-rap\nemo-rap, hyperpop, glitchcore\nemo-rap, hyperpop, hardstyle\nemo-rap, hyperpop, lo-fi\nemo-rap, hyperpop, lo-fi hip hop\nemo-rap, hyperpop, lo-fi trap\nemo-rap, hyperpop, pop-punk\nemo-rap, hyperpop, pop-rock\nemo-rap, hyperpop, rap-rock\nemo-rap, hyperpop, shoegaze\nemo-rap, hyperpop, synth pop\nemo-rap, hyperpop, trap\nemo-rap, hyperpop, trap metal\nemo-rap, hyperpop-punk\nemo-rap, indie-pop\nemo-rap, lo-fi hip hop\nemo-rap, lo-fi hip hop, C-pop\nemo-rap, lo-fi hip hop, Japanese spoken word\nemo-rap, lo-fi hip hop, Korean trap\nemo-rap, lo-fi hip hop, Latin guitar\nemo-rap, lo-fi hip hop, UK drill\nemo-rap, lo-fi hip hop, ambient\nemo-rap, lo-fi hip hop, atmospheric\nemo-rap, lo-fi hip hop, bedroom pop\nemo-rap, lo-fi hip hop, chiptune\nemo-rap, lo-fi hip hop, cinematic\nemo-rap, lo-fi hip hop, hyperpop\nemo-rap, lo-fi hip hop, indie\nemo-rap, lo-fi hip hop, pop-punk\nemo-rap, lo-fi hip hop, trap\nemo-rap, lo-fi hip-hop\nemo-rap, lo-fi hip-hop, C-pop\nemo-rap, lo-fi hip-hop, Chinese\nemo-rap, lo-fi hip-hop, Chinese indie\nemo-rap, lo-fi hip-hop, French indie\nemo-rap, lo-fi hip-hop, Mandopop\nemo-rap, lo-fi hip-hop, Spanish rap\nemo-rap, lo-fi hip-hop, alternative R&B\nemo-rap, lo-fi hip-hop, alternative hip-hop\nemo-rap, lo-fi hip-hop, alternative rock\nemo-rap, lo-fi hip-hop, atmospheric\nemo-rap, lo-fi hip-hop, bedroom pop\nemo-rap, lo-fi hip-hop, chiptune\nemo-rap, lo-fi hip-hop, cloud rap\nemo-rap, lo-fi hip-hop, dream pop\nemo-rap, lo-fi hip-hop, hyperpop\nemo-rap, lo-fi hip-hop, pop-punk\nemo-rap, lo-fi hip-hop, trap\nemo-rap, lo-fi trap, Mandarin hip hop\nemo-rap, lo-fi trap, R&B\nemo-rap, lo-fi trap, atmospheric\nemo-rap, lo-fi trap, dreamy\nemo-rap, lo-fi, C-pop\nemo-rap, lo-fi, J-pop\nemo-rap, lo-fi, Mandarin hip hop\nemo-rap, lo-fi, ambient\nemo-rap, lo-fi, atmospheric\nemo-rap, lo-fi, bedroom pop\nemo-rap, lo-fi, cinematic\nemo-rap, lo-fi, hyperpop\nemo-rap, lo-fi, pop-punk\nemo-rap, lo-fi, post-rock\nemo-rap, lo-fi, trap\nemo-rap, lo-fi, vaporwave\nemo-rap, lo-fi, world music\nemo-rap, math-rock, cinematic\nemo-rap, melodic trap\nemo-rap, metalcore, ambient\nemo-rap, metalcore, lo-fi\nemo-rap, modern R&B\nemo-rap, nu-metal, atmospheric\nemo-rap, nu-metal, atmospheric trap\nemo-rap, nu-metal, lo-fi\nemo-rap, nu-metal, screamo\nemo-rap, nu-metal, trap\nemo-rap, nu-metal, trap-metal\nemo-rap, phonk, cinematic\nemo-rap, phonk, trap\nemo-rap, pop-R&B\nemo-rap, pop-R&B, hip-hop\nemo-rap, pop-punk\nemo-rap, pop-punk, German\nemo-rap, pop-punk, alternative rock\nemo-rap, pop-punk, atmospheric\nemo-rap, pop-punk, electronic\nemo-rap, pop-punk, hip-hop\nemo-rap, pop-punk, lo-fi\nemo-rap, pop-punk, lo-fi hip hop\nemo-rap, pop-punk, lo-fi hip-hop\nemo-rap, pop-punk, metalcore\nemo-rap, pop-punk, shoegaze\nemo-rap, pop-punk, synthwave\nemo-rap, pop-punk, trap\nemo-rap, pop-rap, hyperpop\nemo-rap, pop-rap, trap\nemo-rap, pop-rock\nemo-rap, pop-rock, cinematic\nemo-rap, pop-rock, trap\nemo-rap, pop-trap\nemo-rap, pop-trap, cinematic\nemo-rap, post-hardcore, electronic\nemo-rap, post-hardcore, lo-fi\nemo-rap, post-hardcore, piano ballad\nemo-rap, rage trap\nemo-rap, rage-rap\nemo-rap, sad pop\nemo-rap, shoegaze, alternative rock\nemo-rap, shoegaze, anime\nemo-rap, shoegaze, lo-fi hip hop\nemo-rap, shoegaze, pop-punk\nemo-rap, shoegaze, trap\nemo-rap, synth-pop, chiptune\nemo-rap, synthwave, lo-fi hip hop\nemo-rap, synthwave, trap\nemo-rap, trap\nemo-rap, trap metal, cinematic rock\nemo-rap, trap metal, hyperpop\nemo-rap, trap, C-pop\nemo-rap, trap, Chinese hip hop\nemo-rap, trap, Chinese indie\nemo-rap, trap, German punk\nemo-rap, trap, Italian pop-rap\nemo-rap, trap, J-pop\nemo-rap, trap, JRPG\nemo-rap, trap, Mandarin R&B\nemo-rap, trap, Mandarin hip hop\nemo-rap, trap, Mandopop\nemo-rap, trap, R&B\nemo-rap, trap, acoustic\nemo-rap, trap, acoustic folk\nemo-rap, trap, ambient\nemo-rap, trap, ambient rock\nemo-rap, trap, anime\nemo-rap, trap, atmospheric\nemo-rap, trap, bilingual\nemo-rap, trap, chiptune\nemo-rap, trap, chopped and screwed\nemo-rap, trap, cinematic\nemo-rap, trap, cloud rap\nemo-rap, trap, cloud-rap\nemo-rap, trap, dance-pop\nemo-rap, trap, dream pop\nemo-rap, trap, dreamy\nemo-rap, trap, future bass\nemo-rap, trap, gangsta rap\nemo-rap, trap, hip-hop\nemo-rap, trap, hyper-trap\nemo-rap, trap, hyperpop\nemo-rap, trap, indie rock\nemo-rap, trap, indie-pop\nemo-rap, trap, k-pop\nemo-rap, trap, lo-fi\nemo-rap, trap, lo-fi hip hop\nemo-rap, trap, lo-fi hip-hop\nemo-rap, trap, math rock\nemo-rap, trap, metalcore\nemo-rap, trap, nu-metal\nemo-rap, trap, pluggnb\nemo-rap, trap, pop\nemo-rap, trap, pop-punk\nemo-rap, trap, sad pop\nemo-rap, trap, shoegaze\nemo-rap, trap, slowed + reverb\nemo-rap, trap, synthwave\nemo-rap, trap, vaporwave\nemo-rap, trap-metal, ambient\nemo-rap, trap-metal, cinematic\nemo-rap, trap-metal, post-rock\nemo-rap, trap-soul, UK drill\nemo-rap, vaporwave, hip-hop\nemo-rap, vaporwave, lo-fi hip hop\nemo-rap, vaporwave, pop-punk\nemo-rap, vaporwave, trap\nemo-revival\nemo-revival hip-hop\nemo-revival hyperpop\nemo-revival lo-fi\nemo-revival lo-fi hip hop\nemo-revival lo-fi hip-hop\nemo-revival trap\nemo-revival trap metal\nemo-revival, C-pop\nemo-revival, hyperpop\nemo-revival, hyperpop, trap\nemo-revival, pop-punk, hyperpop\nemo-revival, trap, Italian rap\nemo-rock\nemo-rock J-rock\nemo-rock alternative\nemo-rock alternative rock\nemo-rock future bass\nemo-rock hip-hop\nemo-rock hyperpop electronic\nemo-rock indie\nemo-rock indie rock\nemo-rock indie-pop\nemo-rock lo-fi\nemo-rock lo-fi hip-hop\nemo-rock metalcore\nemo-rock nu-metal\nemo-rock pop\nemo-rock pop-punk\nemo-rock pop-punk hip-hop\nemo-rock pop-punk metalcore\nemo-rock post-hardcore\nemo-rock post-rock\nemo-rock rap-rock\nemo-rock trap\nemo-rock trap metal emo-rap\nemo-rock, J-rock\nemo-rock, J-rock, Mandarin rock\nemo-rock, dubstep\nemo-rock, dubstep, trap\nemo-rock, electronic, Russian hip hop\nemo-rock, electronicore, post-hardcore\nemo-rock, electronicore, trap metal\nemo-rock, future bass\nemo-rock, future bass, C-pop\nemo-rock, future bass, melodic dubstep\nemo-rock, glitch-hop, breakcore\nemo-rock, hip-hop, ambient\nemo-rock, hip-hop, pop-punk\nemo-rock, hip-hop, spoken word\nemo-rock, hyperpop\nemo-rock, hyperpop, electronicore\nemo-rock, hyperpop, glitchcore\nemo-rock, industrial metalcore\nemo-rock, lo-fi hip-hop, rap-rock\nemo-rock, lo-fi, hip hop\nemo-rock, math-rock\nemo-rock, nu-metal, alternative rock\nemo-rock, pop-punk\nemo-rock, pop-punk, Mandarin rap\nemo-rock, pop-punk, hip-hop\nemo-rock, pop-punk, post-hardcore\nemo-rock, pop-punk, rap-rock\nemo-rock, pop-punk, trap\nemo-rock, trap\nemo-rock, trap metal\nemo-rock, trap metal, hyperpop\nemo-rock, trap, C-pop\nemo-rock, trap, acoustic\nemo-rock, trap, emo-rap\nemo-rock, trap, glitch\nemo-rock, trap, hyperpop\nemo-trap\nemo-trap C-pop\nemo-trap J-pop Japanese hip-hop\nemo-trap R&B\nemo-trap alternative R&B\nemo-trap alternative rock\nemo-trap ambient\nemo-trap ambient pop\nemo-trap chiptune\nemo-trap cloud rap\nemo-trap hyperpop\nemo-trap hyperpop hardstyle\nemo-trap hyperpop rock\nemo-trap lo-fi\nemo-trap lo-fi hip hop\nemo-trap lo-fi hip-hop\nemo-trap metal\nemo-trap metalcore\nemo-trap metalcore shoegaze\nemo-trap nu-metal\nemo-trap pop-R&B\nemo-trap pop-punk\nemo-trap reggaeton\nemo-trap, Balkan pop\nemo-trap, Chinese hip hop\nemo-trap, German pop-R&B\nemo-trap, Korean hip-hop, trap\nemo-trap, Latin trap\nemo-trap, Mandarin rap, R&B\nemo-trap, R&B\nemo-trap, R&B, C-pop\nemo-trap, brostep, electronic\nemo-trap, chopped and screwed\nemo-trap, cloud rap\nemo-trap, cloud rap, C-pop\nemo-trap, cloud rap, Mandopop\nemo-trap, cloud rap, alternative R&B\nemo-trap, cloud rap, alternative rock\nemo-trap, cloud rap, ambient pop\nemo-trap, cloud rap, emotional R&B\nemo-trap, cloud rap, hyperpop\nemo-trap, cloud rap, lo-fi hip hop\nemo-trap, cloud rap, shoegaze\nemo-trap, cloud rap, vaporwave\nemo-trap, cloud-rap, trap\nemo-trap, dancehall\nemo-trap, hip-hop\nemo-trap, hyperpop\nemo-trap, hyperpop, C-pop\nemo-trap, hyperpop, ambient\nemo-trap, hyperpop, chiptune\nemo-trap, hyperpop, cinematic\nemo-trap, hyperpop, cloud rap\nemo-trap, hyperpop, lo-fi\nemo-trap, hyperpop, nightcore\nemo-trap, hyperpop, rage\nemo-trap, hyperpop, video game music\nemo-trap, indie rock\nemo-trap, lo-fi hip-hop, C-pop\nemo-trap, lo-fi, bedroom pop\nemo-trap, melodic trap\nemo-trap, metalcore\nemo-trap, nu-metal, cinematic\nemo-trap, pop-punk, cloud rap\nemo-trap, post-hardcore\nemo-trap, trap metal\nemo-trap, vaporwave, lo-fi\nemotional C-Pop R&B\nemotional C-pop\nemotional EDM\nemotional EDM-pop\nemotional German hip-hop\nemotional R&B\nemotional R&B hip-hop\nemotional R&B trap\nemotional R&B, hip-hop, ambient\nemotional Vietnamese hip-hop\nemotional a cappella\nemotional acapella\nemotional alt-rock\nemotional ambient\nemotional ballad\nemotional ballad, cinematic, trap hip-hop\nemotional ballad, hardstyle, happy hardcore\nemotional ballad, zouk, kompa\nemotional breakbeat\nemotional dance-pop\nemotional deep house\nemotional duet\nemotional electronic\nemotional electronic ballad\nemotional electronic pop\nemotional electronic pop-rock\nemotional electronic rock\nemotional folk\nemotional fusion\nemotional future bass\nemotional gangsta rap\nemotional hardstyle\nemotional hip hop\nemotional hip-hop\nemotional hip-hop ambient pop\nemotional hip-hop ballad\nemotional hip-hop dream pop\nemotional hip-hop lo-fi\nemotional hip-hop, atmospheric pop\nemotional hip-hop, atmospheric trap\nemotional hip-hop, trap\nemotional house\nemotional indie\nemotional piano\nemotional piano ballad\nemotional piano ballad hip-hop\nemotional piano ballad, modern trap\nemotional piano, cinematic, Hindi soul\nemotional pop\nemotional pop R&B\nemotional pop ballad\nemotional pop ballad, electronic, dubstep\nemotional pop ballad, future bass, trap\nemotional pop ballad, progressive trance\nemotional pop ballad, uplifting trance, progressive house\nemotional pop chillwave\nemotional pop future bass\nemotional pop hip-hop\nemotional pop trap\nemotional pop, Azerbaijani pop, Turkish pop\nemotional pop, Azerbaijani, Turkish\nemotional pop, Central Asian, Middle Eastern\nemotional pop, Eastern European, Turkish\nemotional pop, conscious hip-hop\nemotional pop, electronic, Central Asian\nemotional pop, electronic, cinematic\nemotional pop, future bass\nemotional pop, future bass, EDM\nemotional pop, hardstyle\nemotional pop, modern hip-hop\nemotional pop, modern trap\nemotional pop, modern trap, ethnic fusion\nemotional pop, modern trap, hip-hop\nemotional pop, moombahton\nemotional pop, progressive house, EDM\nemotional pop, progressive house, big room\nemotional pop, trap, C-pop\nemotional pop, trap, cinematic\nemotional pop, trap, electronic\nemotional pop-EDM\nemotional pop-R&B\nemotional pop-ballad\nemotional pop-r&b\nemotional pop-rap\nemotional pop-rock\nemotional pop-trap\nemotional power ballad\nemotional progressive house\nemotional rap\nemotional rap, video game soundtrack\nemotional reggaeton\nemotional rock\nemotional rock ballad\nemotional rock future bass\nemotional rock, future bass, ambient\nemotional rock, modern trap\nemotional synth-pop\nemotional trance\nemotional trap\nemotional trap ballad\nemotional trap future bass\nemotional trap lo-fi hip-hop\nemotional trap, C-pop\nemotional trap, cloud rap\nemotional trap, hyperpop, atmospheric R&B\nemotive ballad\nemotive drill\nemotive folk\nemotive piano ballad\nemotive pop\nemotive pop ballad\nemotive rock\nemotive violin\nempowering anthem\nempowering pop\nenka\nenka lo-fi\nenka pop rock\nenka, ambient, cinematic\nenka, ambient, lo-fi\nenka, cinematic ballad, acoustic\nenka, cinematic ballad, lo-fi\nenka, cinematic, orchestral\nenka, cinematic, traditional Japanese\nepic\nepic Arabic\nepic Arabic fusion\nepic Arabic synth\nepic C-pop\nepic C-pop rock\nepic C-pop, trap, orchestral\nepic Chinese\nepic Chinese ballad\nepic Chinese cinematic\nepic Chinese electronic\nepic Chinese folk\nepic Chinese instrumental\nepic Chinese opera\nepic Chinese orchestral\nepic Chinese pop\nepic Chinese power ballad\nepic Chinese rock\nepic Chinese soundtrack\nepic Chinese style\nepic Christian hymn\nepic Christian power ballad\nepic Christian rock\nepic Christmas ballad\nepic EDM\nepic EDM-pop\nepic Eurodance\nepic Greek Laïko-pop\nepic Greek ballad\nepic Indian anthem\nepic Indian classical\nepic Indian film score\nepic Indian fusion\nepic J-pop\nepic J-rock\nepic Middle Eastern\nepic Middle Eastern fantasy\nepic Middle Eastern folk\nepic Middle Eastern pop\nepic Persian rock\nepic R&B\nepic R&B trap\nepic a cappella\nepic acapella\nepic acoustic\nepic alternative rock\nepic ambient\nepic ambient rock\nepic anime\nepic anime theme\nepic anthem\nepic art-rock\nepic bagpipe\nepic ballad\nepic ballad, world music, ambient\nepic brass\nepic ceremonial\nepic chanson\nepic chant\nepic chiptune\nepic chiptune gospel\nepic choir\nepic choral\nepic choral pop\nepic choral world music\nepic choral, funk big band\nepic cinematic\nepic cinematic C-pop\nepic cinematic electronic\nepic cinematic rock\nepic cinematic, Middle Eastern pop\nepic cinematic, Turkish pop-rock\nepic classical\nepic dance\nepic dance-pop\nepic dark ambient\nepic dembow\nepic devotional\nepic devotional fusion\nepic devotional rock\nepic drum\nepic drum and bass\nepic dubstep\nepic electronic\nepic electronic hip-hop\nepic electronic pop\nepic electronic pop-rock\nepic electronic rock\nepic electronic rock, trap-rap\nepic fantasy\nepic fantasy ballad\nepic fantasy metal\nepic fantasy rock\nepic film score\nepic folk\nepic folk ballad\nepic folk gospel\nepic folk metal\nepic folk pop\nepic folk rock\nepic folk world music\nepic folk-dance\nepic folk-metal\nepic folk-pop\nepic folk-rock\nepic funk\nepic fusion\nepic future bass\nepic gospel\nepic gospel pop-rock\nepic gospel rock\nepic gothic\nepic guzheng\nepic hard rock\nepic hardstyle\nepic harp\nepic heavy metal\nepic hip hop\nepic hip-hop\nepic hip-hop gospel\nepic house\nepic hybrid\nepic hybrid orchestral\nepic hymn\nepic hymnal\nepic indie rock\nepic industrial rock\nepic instrumental\nepic march\nepic martial\nepic martial anthem\nepic mawwal\nepic melancholic\nepic metal\nepic metalcore\nepic military march\nepic new age\nepic opera\nepic orchestral\nepic orchestral Arabic\nepic orchestral C-pop\nepic orchestral EDM\nepic orchestral J-rock\nepic orchestral brostep\nepic orchestral chiptune\nepic orchestral dubstep\nepic orchestral electronic\nepic orchestral electronic rock\nepic orchestral hardstyle\nepic orchestral hip-hop\nepic orchestral hybrid\nepic orchestral pop\nepic orchestral pop-rock\nepic orchestral rock\nepic orchestral rock glam metal\nepic orchestral trance\nepic orchestral trap\nepic orchestral world music\nepic orchestral, Arabic fusion, electronic dance\nepic orchestral, Bollywood, Indian folk\nepic orchestral, Chinese traditional, cinematic\nepic orchestral, East Asian, cinematic\nepic orchestral, Greek power ballad\nepic orchestral, J-rock, C-pop\nepic orchestral, J-rock, metalcore\nepic orchestral, J-rock, nu-metal\nepic orchestral, J-rock, power metal\nepic orchestral, Middle Eastern, Turkish\nepic orchestral, Persian classical\nepic orchestral, Turkish pop, Middle Eastern fusion\nepic orchestral, cinematic, Chinese traditional\nepic orchestral, cinematic, patriotic\nepic orchestral, eurodance\nepic orchestral, hardstyle\nepic orchestral, hardstyle, EDM\nepic orchestral, hardstyle, big room house\nepic orchestral, hardstyle, cinematic\nepic organ\nepic patriotic\nepic percussion\nepic phonk\nepic piano\nepic piano ballad\nepic pop\nepic pop Afrobeat\nepic pop ballad\nepic pop dream-pop\nepic pop fusion\nepic pop future bass\nepic pop hip-hop\nepic pop rock\nepic pop trap\nepic pop trap world music\nepic pop world music\nepic pop, Central Asian, Eastern European\nepic pop, EDM, trap\nepic pop, EDM, world music\nepic pop, Persian pop, electronic dance\nepic pop, cinematic, power ballad\nepic pop, conscious hip-hop\nepic pop, electronic, Middle Eastern\nepic pop, patriotic, Middle Eastern\nepic pop-EDM\nepic pop-R&B\nepic pop-anthem\nepic pop-ballad\nepic pop-rap\nepic pop-rock\nepic pop-rock hip-hop\nepic pop-rock, hardstyle, cinematic\nepic pop-trap\nepic post-rock\nepic power ballad\nepic power metal\nepic power rock\nepic power-ballad\nepic power-pop\nepic progressive house\nepic progressive rock\nepic psytrance\nepic rap rock\nepic rap, dubstep\nepic reggaeton\nepic rock\nepic rock C-pop\nepic rock ballad\nepic rock flamenco\nepic rock fusion\nepic rock hip-hop\nepic rock house\nepic rock nu-metal\nepic rock opera\nepic rock world fusion\nepic rock worship\nepic rock, Anatolian rock\nepic rock, C-pop fusion\nepic rock, C-pop, ancient style\nepic rock, C-pop, anime theme\nepic rock, C-pop, cinematic\nepic rock, Chinese ballad\nepic rock, Chinese folk rock\nepic rock, Chinese folk, cinematic\nepic rock, Chinese fusion\nepic rock, Chinese fusion, cinematic\nepic rock, Chinese fusion, cinematic rock\nepic rock, Chinese opera, cinematic\nepic rock, Chinese orchestral, cinematic\nepic rock, Chinese traditional, cinematic\nepic rock, Indian fusion\nepic rock, J-rock\nepic rock, Middle Eastern fusion\nepic rock, Middle Eastern, Malay\nepic rock, Spanish folk, Middle Eastern fusion\nepic rock, Turkish folk\nepic rock, cinematic C-pop\nepic rock, cinematic, C-pop\nepic rock, cinematic, Chinese fusion\nepic rock, cinematic, Chinese opera\nepic rock, cinematic, Chinese traditional\nepic rock, cinematic, hip-hop\nepic rock, cinematic, oud\nepic rock, cinematic, trap\nepic rock, electronic, Indian fusion\nepic rock, gǔfēng, cinematic\nepic rock, ney flute, Arabic fusion\nepic rock, orchestral, Turkish folk\nepic rock, spiritual world music, Arabic fusion\nepic rock, symphonic metal, theatrical rock\nepic rock, world fusion, cinematic\nepic rock-pop\nepic sea shanty\nepic ska-punk\nepic soul\nepic soundtrack\nepic spiritual\nepic sports anthem\nepic sports chant\nepic stinger\nepic storytelling\nepic symphonic metal\nepic symphonic rock\nepic synth\nepic synth ballad, melodic metal\nepic synth orchestral\nepic synth pop\nepic synth rock\nepic synth-pop\nepic synth-pop Persian pop\nepic synth-pop trap\nepic synth-rock\nepic synthwave\nepic techno\nepic theatrical\nepic thrash metal\nepic trailer\nepic trailer music\nepic trailer score\nepic trance\nepic trance progressive house\nepic trance synthwave\nepic trance, hardstyle\nepic trance, hardstyle, operatic\nepic trance-pop\nepic trancecore power metal\nepic trap\nepic trap ballad\nepic trap chiptune\nepic trap future bass\nepic trap metal\nepic trap phonk\nepic trap, C-pop, cinematic\nepic trap, cinematic rock\nepic trap-rock\nepic tribal\nepic trip-hop\nepic video game\nepic video game music\nepic vocal\nepic vocal anthem\nepic vocal ballad\nepic world\nepic world beat\nepic world fusion\nepic world fusion rock\nepic world music\nepic world rock\nepic worldbeat\nepic worship\nepic worship pop\nepic worship rock\nepic wuxia\nepic, anthemic, Middle Eastern\nepic, cinematic\nepic, emotional, duduk\nepic, martial, ceremonial\nepic, melancholic, operatic\nesoteric trap\nestrada\nestrada cabaret\nestrada cumbia\nestrada disco funk\nestrada funk disco\nestrada gypsy jazz\nestrada jazz\nestrada jazz blues\nestrada jazz lounge\nestrada lounge jazz\nestrada lounge-pop\nestrada pop\nestrada pop tango\nestrada pop-rock\nestrada rock\nestrada salsa\nestrada synth-pop\nestrada tango\nestrada waltz\nestrada, Eastern European pop\nestrada, Latin jazz\nestrada, Latin jazz, Russian\nestrada, Latin jazz, Soviet-era\nestrada, Latin jazz, tango\nestrada, Latin pop\nestrada, Latin, Russian\nestrada, Latin, Soviet\nestrada, Latin, Soviet vintage\nestrada, Latin, flamenco\nestrada, Latin, salsa\nestrada, Latin, samba\nestrada, Latin-pop\nestrada, Russian folk, cinematic\nestrada, Russian, 80s pop\nestrada, Russian, cinematic\nestrada, Russian, dance\nestrada, Russian, theatrical\nestrada, Soviet era, melancholic waltz\nestrada, Soviet, orchestral\nestrada, Soviet, theatrical\nestrada, Soviet-era, theatrical\nestrada, Soviet-era, upbeat\nestrada, Soviet-era, waltz\nestrada, big band jazz, Russian\nestrada, big band jazz, Soviet-era\nestrada, big band, Russian\nestrada, big band, Soviet\nestrada, big band, Soviet era\nestrada, big band, Soviet-era\nestrada, big band, cinematic\nestrada, big band, folk\nestrada, big band, lo-fi\nestrada, big band, retro Soviet\nestrada, big band, show tune\nestrada, big band, ska\nestrada, big band, swing\nestrada, blues, funk\nestrada, blues, lounge\nestrada, cabaret, Russian\nestrada, cabaret, big band\nestrada, cabaret, big band jazz\nestrada, cabaret, chanson\nestrada, cabaret, folk-pop\nestrada, cabaret, klezmer\nestrada, cabaret, swing\nestrada, cabaret, tango\nestrada, cabaret, vintage\nestrada, cabaret, vintage pop\nestrada, chanson\nestrada, chanson, Russian\nestrada, chanson, Russian folk\nestrada, chanson, synth\nestrada, chanson, synth pop\nestrada, chanson, synthpop\nestrada, chiptune, dramatic ballad\nestrada, chiptune, electronic\nestrada, cinematic, vintage\nestrada, cinematic, vintage Soviet\nestrada, cumbia\nestrada, cumbia, Russian\nestrada, cumbia, latin\nestrada, cumbia, synth\nestrada, dance-pop, Russian\nestrada, disco-funk, 80s\nestrada, disco-funk, big band\nestrada, folk, Russian\nestrada, folk, pop-rock\nestrada, folk-pop\nestrada, folk-pop, Russian\nestrada, funk, synth\nestrada, gypsy folk, theatrical\nestrada, jazz, orchestral\nestrada, klezmer, big band\nestrada, klezmer, jazz\nestrada, latin jazz, big band\nestrada, latin jazz, exotica\nestrada, latin, nostalgic\nestrada, latin-pop\nestrada, lo-fi, Soviet pop\nestrada, lounge, big band\nestrada, lounge, exotica\nestrada, lounge, spy\nestrada, lounge-jazz, big band\nestrada, melancholic, vintage\nestrada, military march, Soviet era\nestrada, military pop, folk pop\nestrada, polka, Russian\nestrada, pop-rock, 80s\nestrada, pop-rock, chanson\nestrada, pop-rock, dramatic ballad\nestrada, pop-rock, smooth jazz\nestrada, power ballad, cinematic\nestrada, psychedelic rock, cinematic\nestrada, retro rock, big band\nestrada, retro, Soviet\nestrada, retro, Soviet-era\nestrada, retro, synthwave\nestrada, retro-pop, Eastern European\nestrada, ska, big band\nestrada, smooth jazz\nestrada, soft rock, chanson\nestrada, surf rock\nestrada, synth pop, Soviet era\nestrada, synth, cinematic\nestrada, synth-pop\nestrada, synth-pop, 80s\nestrada, synth-pop, Russian\nestrada, synth-pop, Russian chanson\nestrada, synth-pop, chanson\nestrada, synth-pop, retro\nestrada, synthpop, Russian pop\nestrada, synthwave, 80s pop\nestrada, synthwave, Eastern European\nestrada, synthwave, Soviet era\nestrada, synthwave, chanson\nestrada, tango, Soviet-era\nestrada, vintage, romantic\nethereal\nethereal Afro-pop\nethereal Afrobeat\nethereal Arabic\nethereal Arabic pop\nethereal Brazilian fusion\nethereal C-pop\nethereal Chinese ballad\nethereal Christmas\nethereal Christmas ballad\nethereal EDM\nethereal French pop\nethereal Indian fusion\nethereal Islamic ambient\nethereal J-pop\nethereal Javanese pop\nethereal Latin\nethereal Latin pop\nethereal R&B\nethereal R&B trap\nethereal R&B, modern trap\nethereal Tamil folk\nethereal a cappella\nethereal acapella\nethereal acoustic\nethereal afrobeat\nethereal alternative\nethereal alternative rock\nethereal ambient\nethereal anthem\nethereal ballad\nethereal beatboxing\nethereal bhajan\nethereal bossa nova\nethereal breakbeat\nethereal chant\nethereal choir\nethereal choral\nethereal choral pop\nethereal cinematic\nethereal classical\nethereal dance-pop\nethereal dark wave\nethereal deep house\nethereal desert pop\nethereal devotional\nethereal downtempo\nethereal drum and bass\nethereal dubstep\nethereal duet\nethereal electronic\nethereal electronic pop\nethereal electronic rock\nethereal electronica\nethereal electropop\nethereal fado\nethereal fantasy\nethereal flamenco\nethereal folk\nethereal folk rock\nethereal folk-dance\nethereal folk-fusion\nethereal folk-pop\nethereal folk-rock\nethereal funk\nethereal fusion\nethereal future bass\nethereal gospel\nethereal gothic\nethereal guzheng\nethereal harp\nethereal hip hop\nethereal hip-hop\nethereal house\nethereal hymn\nethereal indie\nethereal indie pop\nethereal indie rock\nethereal industrial\nethereal jazz\nethereal jazz fusion\nethereal jungle\nethereal lament\nethereal lo-fi\nethereal lo-fi hip-hop\nethereal lounge\nethereal lullaby\nethereal ney\nethereal opera\nethereal oud\nethereal phonk\nethereal piano\nethereal piano ballad\nethereal pop\nethereal pop ballad\nethereal pop trap\nethereal pop, Persian hip-hop\nethereal pop, cinematic, hip-hop\nethereal pop, cinematic, trap\nethereal pop, hip-hop\nethereal pop, modern trap\nethereal pop, trap\nethereal pop, trap hip-hop\nethereal pop-R&B\nethereal pop-rock\nethereal post-rock\nethereal power ballad\nethereal psytrance\nethereal reggaeton\nethereal ritual\nethereal rock\nethereal sea shanty\nethereal shoegaze\nethereal soul\nethereal synth\nethereal synth-pop\nethereal synthwave\nethereal tech-house\nethereal techno\nethereal trance\nethereal trap\nethereal trap R&B\nethereal trap-pop\nethereal tribal\nethereal trip-hop\nethereal vocal\nethereal vocal ballad\nethereal vocal house\nethereal vocals\nethereal waltz\nethereal wave\nethereal wave darkwave\nethereal wave trap\nethereal wave, dark trap\nethereal wave, darkwave, ambient techno\nethereal world\nethereal world folk\nethereal world fusion\nethereal world house\nethereal world music\nethereal world pop\nethereal world rock\nethereal worldbeat\nethereal worship\nethereal, spiritual, Hawaiian\nethereal, spiritual, world music\nethnic ambient\nethnic dance\nethnic dance-pop\nethnic dance-pop hardstyle\nethnic deep house\nethnic drill\nethnic electronic\nethnic electronic trap\nethnic electronica\nethnic electronica acid house\nethnic electronica dance-pop\nethnic electronica deep house\nethnic electronica hardstyle\nethnic electronica pop\nethnic electronica progressive house\nethnic electronica psytrance\nethnic electronica trap\nethnic electronica worldbeat\nethnic electronica, hardstyle, Middle Eastern\nethnic electronica, progressive house\nethnic electronica, psytrance\nethnic electronica, trap, hardstyle\nethnic folk-pop\nethnic fusion\nethnic hardstyle\nethnic hip-hop\nethnic house\nethnic percussion\nethnic pop\nethnic pop trap\nethnic pop-rock\nethnic pop-trap\nethnic rock\nethnic tech house\nethnic tech-house\nethnic techno\nethnic trap\nethnic trap ambient\nethnic trap drill\nethnic trap phonk\nethnic trap, hard dance\nethnic trap, hardstyle\nethnic trap, hardstyle, cinematic orchestral\nethnic trap, hip-hop\nethnic trap, hyperpop\nethnic trap, pop-R&B\nethnic trap, world bass\nethno ambient\nethno future bass\nethno hip-hop\nethno pop\nethno trap\nethno-acoustic\nethno-cinematic\nethno-classical\nethno-dance\nethno-electric\nethno-electro\nethno-electronic\nethno-electronic fusion\nethno-electronic progressive house\nethno-electronic worldbeat\nethno-electronica\nethno-folk\nethno-funk\nethno-house\nethno-jazz\nethno-minimalism\nethno-pop\nethno-pop flamenco\nethno-pop funk-rock\nethno-pop reggaeton\nethno-pop turbo-folk\nethno-pop, Eurodance, Central Asian\nethno-pop, dance-pop, hip-hop\nethno-pop, electronic dance, Central Asian folk\nethno-pop-rock\nethno-rock\nethno-rock symphonic metal\nethno-soul\nethno-trance\nethno-trap\neuphoric hardstyle\neuphoric house\neuphoric trance\neuphoric trance, hardstyle\neuro pop\neuro-pop\neuro-pop trance-pop\neuro-trance\neurodance\neurodance children's\neurodance children's music\neurodance chiptune\neurodance happy hardcore\neurodance house\neurodance novelty\neurodance trance\neurodance tropical\neurodance, Spanish pop\neurodance, chiptune, hyperpop\neurodance, chiptune, polka\neurodance, disco polo\neurodance, disco polo, novelty\neurodance, happy hardcore\neurodance, happy hardcore, Russian folk\neurodance, happy hardcore, children's music\neurodance, klezmer, Russian folk\neurodance, novelty, French\neuropean pop ballad\neuropop\neuropop ballad\neuropop chanson\neuropop folk\nexotic electronic\nexotic trap\nexotica\nexotica doo-wop retro\nexotica jazz\nexotica lounge\nexotica lounge jazz\nexotica lounge-pop\nexotica mambo\nexotica mambo novelty\nexotica nova\nexotica pop\nexotica soul\nexotica surf rock\nexotica swing\nexotica, Latin, lounge\nexotica, cinematic, jazz\nexotica, classic pop, live band\nexotica, lounge, exotica nova\nexotica, mambo, novelty\nexotica, mambo, vintage instrumental\nexotica-pop\nexotica-rock\nexperimental\nexperimental C-pop\nexperimental C-pop, trip-hop\nexperimental Chinese\nexperimental IDM\nexperimental Indian folk\nexperimental K-pop\nexperimental Latin electronic\nexperimental Latin house\nexperimental MPB\nexperimental R&B\nexperimental R&B art-pop\nexperimental R&B, experimental hip-hop\nexperimental R&B, psychedelic soul, lo-fi hip-hop\nexperimental R&B, synth-pop, UK hip-hop\nexperimental a cappella\nexperimental acapella\nexperimental acoustic\nexperimental ambient\nexperimental anthemic\nexperimental baroque-pop\nexperimental bass\nexperimental beat\nexperimental beat collage\nexperimental beatbox\nexperimental beatboxing\nexperimental blues\nexperimental boom-bap\nexperimental brass\nexperimental breakbeat\nexperimental breakcore\nexperimental cabaret\nexperimental cello\nexperimental chiptune\nexperimental choral\nexperimental cinematic\nexperimental classical\nexperimental club\nexperimental collage\nexperimental comedy\nexperimental dancehall\nexperimental dembow\nexperimental drum\nexperimental drum and bass\nexperimental dub\nexperimental electro\nexperimental electronic\nexperimental electronic hip-hop\nexperimental electronic pop\nexperimental electronic vaporwave\nexperimental electronic, art pop\nexperimental electronic, downtempo, world music\nexperimental electronic, hyperpop, Indonesian cabaret\nexperimental electronic, trip-hop, art pop\nexperimental electronica\nexperimental flamenco\nexperimental flute\nexperimental folk\nexperimental folk-rock\nexperimental funk\nexperimental funk-pop\nexperimental funk-rock\nexperimental fusion\nexperimental glitch\nexperimental gospel\nexperimental guitar\nexperimental hip hop\nexperimental hip-hop\nexperimental hip-hop ambient\nexperimental hip-hop art pop\nexperimental hip-hop art-pop\nexperimental hip-hop chiptune\nexperimental hip-hop dark electro\nexperimental hip-hop darkwave\nexperimental hip-hop glitch hop\nexperimental hip-hop nu-metal\nexperimental hip-hop nu-metal industrial\nexperimental hip-hop trap\nexperimental hip-hop trap metal\nexperimental hip-hop, Latin trap\nexperimental hip-hop, alternative R&B\nexperimental hip-hop, breakcore, electronic\nexperimental hip-hop, cloud rap\nexperimental hip-hop, digital hardcore\nexperimental hip-hop, operatic, trap\nexperimental hip-hop, psychedelic R&B\nexperimental hip-hop, reggaeton\nexperimental horror\nexperimental house\nexperimental indie folk\nexperimental indie pop\nexperimental indie rock\nexperimental instrumental\nexperimental jazz\nexperimental lo-fi\nexperimental lo-fi hip hop\nexperimental metal\nexperimental minimal\nexperimental music\nexperimental noise\nexperimental percussion\nexperimental piano\nexperimental polka\nexperimental pop\nexperimental pop reggaeton\nexperimental pop trap art pop\nexperimental pop, UK garage, lo-fi\nexperimental pop, dark electronica\nexperimental pop, future bass, ambient\nexperimental pop, trap, glitch-hop\nexperimental pop, trap, punk\nexperimental pop, trip-hop\nexperimental pop, trip-hop, ambient\nexperimental pop, trip-hop, electronica\nexperimental pop-rock\nexperimental punk\nexperimental reggae\nexperimental reggaeton\nexperimental ritual\nexperimental rock\nexperimental rock, lo-fi hip hop, post-jazz\nexperimental soul\nexperimental sound art\nexperimental sound collage\nexperimental sound design\nexperimental spoken word\nexperimental string\nexperimental techno\nexperimental techno, acid house\nexperimental theater\nexperimental trap\nexperimental trap, hyperpop\nexperimental trap, world percussion\nexperimental tribal\nexperimental trip-hop\nexperimental turntablism\nexperimental violin\nexperimental vocal\nexperimental vocal collage\nexperimental vocal percussion\nexperimental woodwind\nexperimental world\nexperimental world fusion\nexperimental world music\nexperimental, Latin, whimsical\nexperimental, agitator, glitch\nexperimental, chiptune, noise\nexperimental, funk, psychedelic\nexperimental, glitch, avant-garde\nexperimental, glitch, multilingual\nexperimental, glitch, tribal\nexperimental, hip-hop, neo-soul\nexperimental, hypnotic, Brazilian percussion\nexperimental, jungle, drum and bass\nexperimental, klezmer, world fusion\nexperimental, organic, ASMR\nexperimental, percussive, lo-fi\nexperimental, quirky, video game\nexperimental, sample-based, funk\nexperimental, surf rock, metal\nexperimental, tribal, ambient\nexperimental, tribal, industrial\nexperimental, trip-hop, ambient\nexperimental, vocal percussion, flamenco\nexperimental, whimsical, funk\nexperimental, whimsical, instrumental\nexplicit hip-hop\nexplosive drum fill\nextreme metal\nextreme metal chiptune\nextreme metal, mathcore, ambient\nextreme punk\nfado\nfado chiptune\nfado classical\nfado dance\nfado flamenco\nfado fun\nfado hip-hop\nfado pop\nfado rock\nfado tropical\nfado, European folk, accordion\nfado, Italian folk, live performance\nfado, Latin folk\nfado, Portuguese folk\nfado, art song\nfado, bossa nova, trap\nfado, cinematic, melancholic\nfado, latin, acoustic\nfado, orchestral swing, cinematic folk\nfado, orchestral, cinematic\nfado, tango, MPB\nfado-pop\nfairytale\nfairytale ambient\nfairytale ballad\nfairytale folk\nfairytale lullaby\nfairytale music\nfairytale pop\nfairytale waltz\nfairytale-pop\nfamily-friendly folk\nfamily-friendly pop\nfanfare\nfantasy\nfantasy RPG\nfantasy RPG soundtrack\nfantasy ambient\nfantasy ballad\nfantasy film score\nfantasy folk\nfantasy folk chiptune\nfantasy folk-pop\nfantasy game music\nfantasy hip-hop\nfantasy instrumental\nfantasy lo-fi\nfantasy lullaby\nfantasy music\nfantasy orchestral\nfantasy pop\nfantasy pop tropical\nfantasy pop-rock\nfantasy punk rock\nfantasy rock\nfantasy score\nfantasy soundtrack\nfantasy synth\nfantasy video game\nfantasy video game music\nfantasy video game soundtrack\nfantasy-pop\nfavela funk\nfavela funk slap house\nfavela funk, French rap\nfavela rap\nfeestmuziek\nfeestmuziek schlager\nfemale drill\nfemale rap\nfemale-led hip-hop\nfestival\nfestival anthem\nfestival brass\nfestival funk\nfestival fusion\nfestival groove\nfestival hip-hop\nfestival house\nfestival melancholy\nfestival pop\nfestival pop-rock\nfestival rock\nfestival soul\nfestival trap\nfestival trap, hardstyle\nfestive Indian fusion\nfestive accordion\nfestive ambient\nfestive brass\nfestive choral\nfestive dholak\nfestive electronic\nfestive hip-hop\nfestive instrumental\nfestive orchestral\nfestive pagode\nfestive percussion\nfestive pop\nfestive rock\nfestive world fusion\nfestive, eerie, children's choir\nfield recording\nfilm music\nfilm noir\nfilm noir ballad\nfilm noir jazz\nfilm noir jazz, mambo, cinematic\nfilm noir orchestral, big band jazz\nfilm noir swing\nfilm noir tango\nfilm noir, jazz ballad, trot\nfilm pop\nfilm score\nfilm score, South Asian, vintage\nfilm score, mambo, Latin folk\nfilm score, retro synth, Bollywood\nfilm scoring\nfilm sound design\nfilm-noir blues-rock\nfilmi\nfilmi ballad\nfilmi dance\nfilmi fusion\nfilmi ghazal\nfilmi music\nfilmi pop\nfilmi rock\nfilmi synth-pop\nfilmi, Indian pop, contemporary world\nfilmi, world music, upbeat\nfilmi-pop\nfilmi-pop dance-pop\nfilmi-pop, dance-pop, rock\nfilmibhangra\nfilmipop\nfilmipop, chiptune, South Indian\nfilter house\nfingerstyle\nfingerstyle acoustic\nfingerstyle blues\nfingerstyle guitar\nfingerstyle guitar, ambient folk, Indonesian indie\nfingerstyle jazz\nfingerstyle jazz neo-soul\nfingerstyle ukulele\nfitness music\nflamenco\nflamenco Arabic\nflamenco EDM\nflamenco Latin\nflamenco R&B\nflamenco a cappella\nflamenco acoustic\nflamenco ambient\nflamenco arabic fusion\nflamenco art song\nflamenco bachata\nflamenco ballad\nflamenco ballad, Latin pop-rock\nflamenco ballad, trot, soulful ballad\nflamenco banda\nflamenco big band\nflamenco bluegrass\nflamenco blues\nflamenco blues rock\nflamenco bolero\nflamenco bolero salsa\nflamenco bossa nova\nflamenco breakcore\nflamenco cabaret\nflamenco candombe\nflamenco canta\nflamenco cante jondo\nflamenco cello\nflamenco chanson\nflamenco cinematic\nflamenco classical\nflamenco classical crossover\nflamenco copla\nflamenco corrido\nflamenco cumbia\nflamenco cumbia pop\nflamenco dance\nflamenco drum and bass\nflamenco electronic\nflamenco electronica\nflamenco eurodance\nflamenco fado\nflamenco fingerstyle\nflamenco folk\nflamenco folk pop\nflamenco folk rock\nflamenco folk, Azerbaijani pop, electronic fusion\nflamenco folk-pop\nflamenco folk-rock\nflamenco funk\nflamenco funk rock\nflamenco funk soul\nflamenco funk-rock\nflamenco fusion\nflamenco fusion cabaret\nflamenco fusion funk-rock\nflamenco fusion lo-fi hip-hop\nflamenco fusion salsa\nflamenco fusion trap\nflamenco fusion, Indian classical, Bollywood pop\nflamenco fusion, Indian electronic\nflamenco fusion, Indian pop\nflamenco fusion, happy hardcore, J-core\nflamenco fusion, lo-fi hip hop\nflamenco fusion, reggaeton, R&B\nflamenco gospel\nflamenco guitar\nflamenco hardstyle\nflamenco hip hop\nflamenco hip-hop\nflamenco hip-hop R&B\nflamenco hip-hop alternative rock\nflamenco hip-hop rock\nflamenco house\nflamenco indie rock\nflamenco jazz\nflamenco jazz funk\nflamenco jazz fusion\nflamenco jazz rockabilly\nflamenco jazz salsa\nflamenco jazz, thrash metal\nflamenco joropo\nflamenco lo-fi\nflamenco lo-fi hip-hop\nflamenco mambo\nflamenco metal\nflamenco opera\nflamenco orchestral\nflamenco oud\nflamenco oud R&B\nflamenco oud, Arabic vocal, cinematic world\nflamenco oud, trot, cinematic ballad\nflamenco piano\nflamenco pop\nflamenco pop R&B\nflamenco pop fusion\nflamenco pop rap\nflamenco pop reggae\nflamenco pop reggaeton\nflamenco pop rock\nflamenco pop, Arabic pop\nflamenco pop, Finnish schlager\nflamenco pop, Latin rock\nflamenco pop, Middle Eastern pop\nflamenco pop, Turkish pop-rock\nflamenco pop, arabesque, theatrical rock\nflamenco pop, hard rock\nflamenco pop, hardstyle, cinematic\nflamenco pop, latin pop, reggaeton\nflamenco pop-folk\nflamenco pop-rock\nflamenco progressive\nflamenco punk\nflamenco punk folk\nflamenco punk rock\nflamenco rai\nflamenco rap\nflamenco rap-rock\nflamenco rave\nflamenco reggae\nflamenco reggae ska\nflamenco reggaeton\nflamenco reggaeton salsa\nflamenco rock\nflamenco rock salsa\nflamenco rock tango\nflamenco rock trot\nflamenco rock, Latin punk\nflamenco rock, progressive rock, Latin rock\nflamenco rock, psychedelic rock, Latin rock\nflamenco rock, rockabilly, swing\nflamenco rock, theatrical pop, rockabilly\nflamenco rumba\nflamenco rumba, Andean folk\nflamenco salsa\nflamenco samba\nflamenco sertanejo\nflamenco ska-punk\nflamenco soul\nflamenco swing\nflamenco synth-pop\nflamenco tango\nflamenco tango cabaret\nflamenco tango copla\nflamenco tango fado\nflamenco tango folk\nflamenco tango fusion\nflamenco tango jazz\nflamenco tango mariachi\nflamenco tango orchestral\nflamenco tango samba\nflamenco tango world music\nflamenco techno\nflamenco trance\nflamenco trap\nflamenco ukulele\nflamenco urbano\nflamenco world\nflamenco world music\nflamenco worldbeat\nflamenco worship\nflamenco, Afro-Latin\nflamenco, Afro-Latin, North African folk\nflamenco, Afro-Latin, world fusion\nflamenco, Afro-Latin, world music\nflamenco, Anatolian folk\nflamenco, Anatolian rock, Turkish folk\nflamenco, Andean folk\nflamenco, Andean, acoustic\nflamenco, Arabic folk\nflamenco, Arabic folk-pop\nflamenco, Arabic fusion\nflamenco, Arabic fusion, classical Spanish\nflamenco, Arabic music\nflamenco, Arabic music, melancholic\nflamenco, Arabic, acoustic\nflamenco, Arabic, cinematic\nflamenco, Arabic, instrumental\nflamenco, Arabic, live\nflamenco, Arabic, melancholic\nflamenco, Arabic, theatrical\nflamenco, Arabic, world fusion\nflamenco, Balkan brass\nflamenco, Balkan folk\nflamenco, Balkan folk-pop\nflamenco, Balkan folk-rock\nflamenco, Balkan pop, cinematic\nflamenco, Balkan pop-folk\nflamenco, Balkan, tango\nflamenco, Brazilian ballad\nflamenco, Brazilian folk\nflamenco, Brazilian popular music\nflamenco, Brazilian, acoustic\nflamenco, Brazilian, soul\nflamenco, Brazilian, theatrical\nflamenco, C-pop\nflamenco, C-pop, cinematic\nflamenco, Caribbean folk, C-pop\nflamenco, Chinese blues, acoustic\nflamenco, Christmas, Spanish\nflamenco, Christmas, choir\nflamenco, Cuban Son, Latin folk\nflamenco, European folk\nflamenco, French chanson\nflamenco, French chanson, Latin\nflamenco, French chanson, Latin acoustic\nflamenco, French chanson, Spanish folk\nflamenco, French chanson, accordion\nflamenco, French chanson, acoustic\nflamenco, French chanson, rumba\nflamenco, Greek art music\nflamenco, Greek ballad, cinematic\nflamenco, Greek folk\nflamenco, Greek folk, Middle Eastern\nflamenco, Greek folk, live performance\nflamenco, Greek folk, world music\nflamenco, Greek folk-pop\nflamenco, Indian folk, world music\nflamenco, Indonesian folk\nflamenco, Indonesian pop\nflamenco, Italian folk\nflamenco, J-pop, Latin\nflamenco, J-pop, R&B\nflamenco, J-pop, cinematic\nflamenco, J-rock\nflamenco, J-rock, cinematic\nflamenco, Japanese pop\nflamenco, Japanese traditional, cinematic\nflamenco, Japanese vocal, acoustic\nflamenco, Javanese, acoustic\nflamenco, Korean trot\nflamenco, Latin art song, piano\nflamenco, Latin ballad\nflamenco, Latin ballad, acoustic\nflamenco, Latin ballad, copla\nflamenco, Latin folk\nflamenco, Latin folk, Anatolian folk\nflamenco, Latin folk, Andean\nflamenco, Latin folk, Christmas\nflamenco, Latin folk, MPB\nflamenco, Latin folk, Nordic\nflamenco, Latin folk, acoustic guitar\nflamenco, Latin folk, acoustic rock\nflamenco, Latin folk, art song\nflamenco, Latin folk, copla\nflamenco, Latin folk, corrido\nflamenco, Latin folk, jazz\nflamenco, Latin folk, live performance\nflamenco, Latin folk, operatic folk\nflamenco, Latin folk, romantic ballad\nflamenco, Latin folk, rumba\nflamenco, Latin folk, sacred music\nflamenco, Latin folk, samba\nflamenco, Latin folk, theatrical\nflamenco, Latin folk, traditional\nflamenco, Latin folk, vocal\nflamenco, Latin folk, world music\nflamenco, Latin guitar, acoustic folk\nflamenco, Latin jazz\nflamenco, Latin jazz, big band\nflamenco, Latin jazz, bolero\nflamenco, Latin jazz, classical\nflamenco, Latin jazz, classical guitar\nflamenco, Latin jazz, folk\nflamenco, Latin jazz, salsa\nflamenco, Latin jazz, samba\nflamenco, Latin jazz, tango\nflamenco, Latin jazz, world fusion\nflamenco, Latin jazz, world music\nflamenco, Latin pop\nflamenco, Latin pop, Bossa Nova\nflamenco, Latin pop, French chanson\nflamenco, Latin pop, salsa\nflamenco, Latin pop, world music\nflamenco, Latin pop-rock\nflamenco, Latin rock\nflamenco, Latin rock, world fusion\nflamenco, Latin rumba, C-pop\nflamenco, Latin salsa, theatrical\nflamenco, Latin, Afro-Cuban\nflamenco, Latin, Arabic fusion\nflamenco, Latin, Brazilian\nflamenco, Latin, C-pop\nflamenco, Latin, French pop\nflamenco, Latin, Middle Eastern folk\nflamenco, Latin, Sinhala\nflamenco, Latin, Spanish guitar\nflamenco, Latin, acoustic\nflamenco, Latin, acoustic folk\nflamenco, Latin, acoustic guitar\nflamenco, Latin, bard rock\nflamenco, Latin, big band\nflamenco, Latin, chanson\nflamenco, Latin, cinematic\nflamenco, Latin, contemporary Christian\nflamenco, Latin, duet\nflamenco, Latin, folk\nflamenco, Latin, instrumental\nflamenco, Latin, jazz\nflamenco, Latin, pop\nflamenco, Latin, rumba\nflamenco, Latin, soul\nflamenco, Latin, spiritual\nflamenco, Latin, tango\nflamenco, Latin, theatrical\nflamenco, Latin, upbeat\nflamenco, Latin, vocal\nflamenco, Latin, world fusion\nflamenco, Latin, world music\nflamenco, MPB\nflamenco, MPB, Fado\nflamenco, MPB, Latin folk\nflamenco, MPB, acoustic\nflamenco, MPB, bossa nova\nflamenco, MPB, fado\nflamenco, MPB, live folk\nflamenco, MPB, samba\nflamenco, MPB, tango\nflamenco, Mandarin pop, Bossa Nova\nflamenco, Mediterranean folk\nflamenco, Mediterranean, Latin\nflamenco, Mediterranean, folk\nflamenco, Middle Eastern\nflamenco, Middle Eastern folk\nflamenco, Middle Eastern, Arabic pop\nflamenco, Middle Eastern, Mediterranean folk\nflamenco, Middle Eastern, Turkish folk\nflamenco, Middle Eastern, acoustic\nflamenco, Middle Eastern, acoustic guitar\nflamenco, Middle Eastern, ambient\nflamenco, Middle Eastern, ballad\nflamenco, Middle Eastern, cinematic\nflamenco, Middle Eastern, folk\nflamenco, Middle Eastern, instrumental\nflamenco, Middle Eastern, live\nflamenco, Middle Eastern, melancholic\nflamenco, Middle Eastern, operatic\nflamenco, Middle Eastern, vocal\nflamenco, Middle Eastern, world fusion\nflamenco, Middle Eastern, world music\nflamenco, Mizrahi, folk\nflamenco, Norteño\nflamenco, North African folk\nflamenco, North African folk, acoustic\nflamenco, Persian classical\nflamenco, Persian folk\nflamenco, Persian folk, world music\nflamenco, Persian music\nflamenco, Persian pop\nflamenco, Persian vocal, acoustic\nflamenco, Persian, acoustic\nflamenco, Persian, cinematic\nflamenco, Persian, dramatic\nflamenco, Persian, emotional\nflamenco, Persian, melancholic\nflamenco, Portuguese folk\nflamenco, Russian chanson, bard rock\nflamenco, Russian romance\nflamenco, Spanish classical\nflamenco, Spanish folk\nflamenco, Spanish folk, cinematic\nflamenco, Spanish folk, classical guitar\nflamenco, Spanish folk, rumba\nflamenco, Spanish folk, theatrical\nflamenco, Turkish art music\nflamenco, Turkish art music, acoustic\nflamenco, Turkish classical\nflamenco, Turkish folk\nflamenco, Turkish folk, Latin fusion\nflamenco, Turkish folk, Middle Eastern\nflamenco, Turkish folk, acoustic\nflamenco, Turkish folk, arabesque\nflamenco, Turkish folk, cinematic\nflamenco, Turkish folk, classical guitar\nflamenco, Turkish folk, melancholic\nflamenco, Turkish folk, ney\nflamenco, Turkish folk, oud\nflamenco, Turkish folk, passionate vocal\nflamenco, Turkish folk, world music\nflamenco, Turkish folk-pop\nflamenco, Turkish, Middle Eastern\nflamenco, Turkish, acoustic\nflamenco, Turkish, ambient\nflamenco, Turkish, cinematic\nflamenco, Turkish, classical\nflamenco, Turkish, emotional\nflamenco, Turkish, melancholic\nflamenco, Turkish, operatic\nflamenco, Venezuelan folk\nflamenco, Vietnamese folk\nflamenco, accordion, Portuguese folk\nflamenco, accordion, blues\nflamenco, accordion, rumba\nflamenco, acoustic folk-rock, world music\nflamenco, acoustic, Hebrew vocal\nflamenco, acoustic, Italian folk\nflamenco, acoustic, Mandarin folk\nflamenco, acoustic, Mandarin pop\nflamenco, acoustic, Russian folk\nflamenco, acoustic, Thai folk\nflamenco, acoustic, cantopop\nflamenco, acoustic, cinematic\nflamenco, acoustic, folk\nflamenco, acoustic, spoken word\nflamenco, acoustic, theatrical\nflamenco, ambient folk, cinematic\nflamenco, ambient, Chinese folk\nflamenco, ambient, French chanson\nflamenco, ambient, experimental\nflamenco, ambient, lo-fi\nflamenco, arabesque\nflamenco, arabesque, Turkish folk\nflamenco, arabesque, cinematic\nflamenco, arabesque, folk\nflamenco, arabesque, melancholic\nflamenco, arabesque, world fusion\nflamenco, bachata, reggaeton\nflamenco, ballad, bilingual\nflamenco, baroque, cinematic\nflamenco, big band, Latin\nflamenco, blues, ambient\nflamenco, bolero, French chanson\nflamenco, bolero, Latin\nflamenco, bolero, Latin ballad\nflamenco, bolero, Latin folk\nflamenco, bolero, Latin rumba\nflamenco, bolero, MPB\nflamenco, bolero, Vietnamese\nflamenco, bolero, acoustic\nflamenco, bolero, bossa nova\nflamenco, bolero, cinematic\nflamenco, bolero, copla\nflamenco, bolero, rumba\nflamenco, bolero, salsa\nflamenco, bolero, tango\nflamenco, bossa nova\nflamenco, bossa nova, Latin acoustic\nflamenco, bossa nova, Portuguese folk\nflamenco, bossa nova, latin\nflamenco, bossa nova, melancholic ballad\nflamenco, cabaret, Russian chanson\nflamenco, cabaret, Spanish folk\nflamenco, cabaret, tango\nflamenco, cantautore\nflamenco, cante jondo, Middle Eastern\nflamenco, carnival, Spanish\nflamenco, cello, emotional vocal\nflamenco, chalga, electronic\nflamenco, chanson\nflamenco, chanson, Latin\nflamenco, chanson, Vietnamese pop\nflamenco, chanson, acoustic\nflamenco, chanson, cinematic\nflamenco, chanson, classical fusion\nflamenco, chanson, levenslied\nflamenco, chanson, live\nflamenco, chanson, orchestral\nflamenco, chanson, theatrical rock\nflamenco, chanson, vocal ensemble\nflamenco, chillwave, worldbeat\nflamenco, chiptune, video game soundtrack\nflamenco, choir, jazz fusion\nflamenco, choral, Christmas\nflamenco, choral, Hawaiian\nflamenco, choral, Latin\nflamenco, choral, Latin folk\nflamenco, choral, ambient\nflamenco, choral, cinematic\nflamenco, choral, classical\nflamenco, choral, dramatic\nflamenco, choral, epic\nflamenco, choral, folk rock\nflamenco, choral, live\nflamenco, choral, live performance\nflamenco, choral, operatic\nflamenco, choral, world music\nflamenco, choro\nflamenco, choro, acoustic\nflamenco, choro, bossa nova\nflamenco, choro, classical guitar\nflamenco, choro, world guitar\nflamenco, cinematic ballad\nflamenco, cinematic ballad, European folk\nflamenco, cinematic orchestral\nflamenco, cinematic, Arabic\nflamenco, cinematic, Arabic chant\nflamenco, cinematic, Arabic fusion\nflamenco, cinematic, French chanson\nflamenco, cinematic, Hebrew vocal\nflamenco, cinematic, Latin\nflamenco, cinematic, Middle Eastern\nflamenco, cinematic, Persian classical\nflamenco, cinematic, Portuguese\nflamenco, cinematic, Turkish folk\nflamenco, cinematic, acoustic\nflamenco, cinematic, ambient\nflamenco, cinematic, anime\nflamenco, cinematic, ballad\nflamenco, cinematic, baroque\nflamenco, cinematic, big-band\nflamenco, cinematic, bolero\nflamenco, cinematic, cabaret\nflamenco, cinematic, choral\nflamenco, cinematic, classical\nflamenco, cinematic, classical crossover\nflamenco, cinematic, copla\nflamenco, cinematic, devotional\nflamenco, cinematic, dramatic\nflamenco, cinematic, emotional\nflamenco, cinematic, epic\nflamenco, cinematic, folk\nflamenco, cinematic, instrumental\nflamenco, cinematic, live\nflamenco, cinematic, melancholic\nflamenco, cinematic, neapolitan\nflamenco, cinematic, ney\nflamenco, cinematic, opera\nflamenco, cinematic, operatic\nflamenco, cinematic, orchestral\nflamenco, cinematic, power ballad\nflamenco, cinematic, soul\nflamenco, cinematic, soulful\nflamenco, cinematic, taiko\nflamenco, cinematic, tango\nflamenco, cinematic, world\nflamenco, cinematic, world fusion\nflamenco, cinematic, world music\nflamenco, classical, Bengali ballad\nflamenco, classical, Greek\nflamenco, classical, Japanese folk\nflamenco, classical, Latin jazz\nflamenco, classical, MPB\nflamenco, classical, Turkish art music\nflamenco, classical, ambient\nflamenco, classical, art song\nflamenco, classical, avant-garde folk\nflamenco, classical, choral\nflamenco, classical, cinematic\nflamenco, classical, copla\nflamenco, classical, klezmer\nflamenco, classical, melancholic ballad\nflamenco, classical, soul\nflamenco, classical, tango\nflamenco, classical, vocal\nflamenco, classical, world music\nflamenco, comedic, Spanish\nflamenco, copla\nflamenco, copla, Spanish\nflamenco, copla, Spanish dance\nflamenco, copla, Spanish folk\nflamenco, copla, Spanish jazz\nflamenco, copla, baroque\nflamenco, copla, choral\nflamenco, copla, cinematic\nflamenco, copla, classical\nflamenco, copla, dramatic\nflamenco, copla, operatic\nflamenco, copla, orchestral\nflamenco, copla, orchestral folk\nflamenco, copla, tango\nflamenco, copla, theatrical\nflamenco, copla, traditional Spanish\nflamenco, copla, villancico\nflamenco, copla, vintage\nflamenco, corrido, lo-fi\nflamenco, corrido, milonga\nflamenco, cumbia, copla\nflamenco, drum and bass, Latin\nflamenco, duduk, emotional vocal\nflamenco, electronic, indie\nflamenco, electronic, psychedelic\nflamenco, emotional, Turkish\nflamenco, enka\nflamenco, enka, cinematic\nflamenco, epic, Middle Eastern\nflamenco, epic, cinematic\nflamenco, eurodance\nflamenco, fado, Latin\nflamenco, fado, Latin folk\nflamenco, fado, Latin pop\nflamenco, fado, MPB\nflamenco, fado, Portuguese folk\nflamenco, fado, acoustic\nflamenco, fado, bossa nova\nflamenco, fado, cinematic\nflamenco, fado, soul\nflamenco, fado, tango\nflamenco, fado, theatrical rock\nflamenco, folk waltz, Latin American folk\nflamenco, folk, Anatolian\nflamenco, folk, Christmas\nflamenco, folk, Latin\nflamenco, folk, Russian folk\nflamenco, folk, Spanish\nflamenco, folk, acoustic\nflamenco, folk, emotional\nflamenco, folk, fusion\nflamenco, folk, instrumental\nflamenco, folk, live\nflamenco, folk, operatic\nflamenco, folk, polka\nflamenco, folk, romance\nflamenco, folk, rumba\nflamenco, folk, tango\nflamenco, folk, theatrical\nflamenco, folk, vocal\nflamenco, folk, waltz\nflamenco, folk, world\nflamenco, folk, world music\nflamenco, forró\nflamenco, forró, Brazilian folk\nflamenco, forró, samba\nflamenco, ghazal, cinematic\nflamenco, ghazal, world fusion\nflamenco, gospel\nflamenco, gospel R&B\nflamenco, gospel, Latin\nflamenco, gospel, acoustic\nflamenco, gospel, choral\nflamenco, gypsy jazz\nflamenco, gypsy jazz, Latin\nflamenco, gypsy jazz, chanson\nflamenco, gypsy jazz, cinematic\nflamenco, gypsy jazz, laiko\nflamenco, gypsy jazz, progressive folk\nflamenco, gypsy jazz, theatrical\nflamenco, jazz fusion\nflamenco, jazz, Persian vocal\nflamenco, klezmer, Balkan folk\nflamenco, klezmer, rumba\nflamenco, klezmer, theatrical rock\nflamenco, klezmer, world fusion\nflamenco, laiko\nflamenco, latin jazz\nflamenco, latin soul, gypsy jazz\nflamenco, latin trap, reggaeton\nflamenco, laïko, pop\nflamenco, liturgical, choral\nflamenco, live performance, passionate\nflamenco, lo-fi hip hop\nflamenco, lo-fi hip hop, Middle Eastern\nflamenco, lo-fi, traditional Spanish folk\nflamenco, mambo, Latin\nflamenco, mambo, theatrical pop\nflamenco, melancholic, C-pop\nflamenco, melancholic, Turkish\nflamenco, melancholic, cello\nflamenco, melancholic, theatrical\nflamenco, merengue\nflamenco, milonga, MPB\nflamenco, milonga, acoustic\nflamenco, modern classical, avant-garde jazz\nflamenco, neo-classical\nflamenco, neoclassical\nflamenco, ney, Arabic\nflamenco, ney, cinematic\nflamenco, ney, instrumental\nflamenco, ney, theatrical\nflamenco, ney, world fusion\nflamenco, operatic folk\nflamenco, operatic folk, cinematic\nflamenco, operatic, Greek\nflamenco, operatic, Greek art song\nflamenco, operatic, Italian folk\nflamenco, operatic, Latin folk\nflamenco, operatic, Persian\nflamenco, operatic, Southeast Asian classical\nflamenco, operatic, Turkish art music\nflamenco, operatic, ambient\nflamenco, operatic, anthemic\nflamenco, operatic, choral\nflamenco, operatic, cinematic\nflamenco, operatic, epic\nflamenco, operatic, folk\nflamenco, operatic, folk dance\nflamenco, operatic, gospel\nflamenco, operatic, melancholic\nflamenco, operatic, neapolitan\nflamenco, orchestral, Andalusian\nflamenco, orchestral, Spanish\nflamenco, orchestral, anime\nflamenco, orchestral, cinematic\nflamenco, orchestral, classical\nflamenco, orchestral, folk\nflamenco, oud, choral\nflamenco, pansori\nflamenco, regional Mexican\nflamenco, regional Mexican, acoustic\nflamenco, rock, Latin\nflamenco, rumba flamenca\nflamenco, rumba, German folk\nflamenco, rumba, Latin\nflamenco, rumba, Latin jazz\nflamenco, rumba, Russian bard\nflamenco, rumba, Spanish Christmas\nflamenco, rumba, Spanish folk\nflamenco, rumba, ballad\nflamenco, rumba, blues\nflamenco, rumba, folk\nflamenco, rumba, salsa\nflamenco, rumba, upbeat acoustic\nflamenco, sacred, choral\nflamenco, salsa\nflamenco, salsa, Latin\nflamenco, salsa, Latin Christian\nflamenco, salsa, Latin ballad\nflamenco, salsa, Latin jazz\nflamenco, salsa, Latin pop\nflamenco, salsa, mambo\nflamenco, samba\nflamenco, samba, MPB\nflamenco, samba-rock\nflamenco, samba-rock, MPB\nflamenco, schlager, latin pop\nflamenco, schlager, live performance\nflamenco, schlager, musical theater\nflamenco, soul, acoustic\nflamenco, soul, jazz\nflamenco, southern italian, melodic\nflamenco, spiritual, Middle Eastern\nflamenco, spiritual, gospel\nflamenco, spoken word\nflamenco, synth, copla\nflamenco, tango, Andean\nflamenco, tango, Arabic fusion\nflamenco, tango, Balkan\nflamenco, tango, European folk\nflamenco, tango, French chanson\nflamenco, tango, Kayōkyoku\nflamenco, tango, Latin\nflamenco, tango, Latin art song\nflamenco, tango, Latin folk\nflamenco, tango, MPB\nflamenco, tango, acoustic\nflamenco, tango, acoustic ballad\nflamenco, tango, bolero\nflamenco, tango, cinematic\nflamenco, tango, classical guitar\nflamenco, tango, copla\nflamenco, tango, fado\nflamenco, tango, folk\nflamenco, tango, operatic\nflamenco, tango, theatrical\nflamenco, theatrical, Andalusian\nflamenco, theatrical, Russian folk\nflamenco, theatrical, choral\nflamenco, theatrical, oompah\nflamenco, theatrical, opera\nflamenco, theatrical, rumba\nflamenco, traditional Spanish, Christmas\nflamenco, traditional Spanish, festive\nflamenco, traditional, cinematic\nflamenco, trip-hop, lo-fi\nflamenco, trot\nflamenco, video game music\nflamenco, villancico, Spanish Christmas\nflamenco, villancico, rumba\nflamenco, waltz, Portuguese folk\nflamenco, world fusion\nflamenco, world fusion, choral\nflamenco, world music\nflamenco, world music, Andalusian\nflamenco, world music, Arabic folk\nflamenco, world music, Balkan folk\nflamenco, world music, Hebrew folk\nflamenco, world music, Latin\nflamenco, world music, Latin folk\nflamenco, world music, Middle Eastern\nflamenco, world music, Persian\nflamenco, world music, Turkish folk\nflamenco, world music, acoustic\nflamenco, world music, acoustic guitar\nflamenco, world music, chanson\nflamenco, world music, cinematic\nflamenco, world music, cinematic ballad\nflamenco, world music, dramatic folk\nflamenco, world music, folk\nflamenco, world music, folk fusion\nflamenco, world music, instrumental\nflamenco, world music, live\nflamenco, world music, live performance\nflamenco, world music, melancholic\nflamenco, world music, operatic\nflamenco, world music, ritual\nflamenco, world music, rumba\nflamenco, world music, rumba flamenca\nflamenco, world music, soul\nflamenco, world music, theatrical\nflamenco, zamba, Latin folk\nflamenco-electronica\nflamenco-pop\nflamenco-pop rock\nflamenco-pop, Latin rock\nflamenco-pop, reggaeton\nflamenco-punk\nflamenco-rap\nflamenco-raï\nflamenco-reggaeton\nflute fusion\nflute jazz\nflute music\nflute solo\nflute, Middle Eastern, Balkan folk\nflute, acoustic, theatrical\nflute-driven pop\nfoley\nfoley loop\nfolk\nfolk Americana\nfolk Bhangra\nfolk Christian\nfolk Christmas\nfolk Latin\nfolk Latin American\nfolk Latin rumba\nfolk a cappella\nfolk accordion\nfolk acoustic\nfolk ambient\nfolk americana\nfolk anthem\nfolk art-rock\nfolk ballad\nfolk ballad bluegrass\nfolk ballad blues-rock\nfolk ballad cinematic\nfolk ballad classical\nfolk ballad classical chamber\nfolk ballad country-rock\nfolk ballad cumbia\nfolk ballad fado\nfolk ballad flamenco\nfolk ballad glam rock\nfolk ballad gypsy jazz\nfolk ballad heartland rock\nfolk ballad jazz-blues\nfolk ballad pop-rock\nfolk ballad post-rock\nfolk ballad progressive rock\nfolk ballad reggae\nfolk ballad rockabilly\nfolk ballad world music\nfolk ballad world-folk\nfolk ballad, Americana\nfolk ballad, Americana, singer-songwriter\nfolk ballad, Argentinian folk\nfolk ballad, Celtic folk\nfolk ballad, Celtic folk, cinematic\nfolk ballad, Celtic folk-rock\nfolk ballad, Celtic pub\nfolk ballad, Celtic punk\nfolk ballad, Celtic rock\nfolk ballad, Celtic, acoustic\nfolk ballad, Celtic, cinematic\nfolk ballad, Celtic, sea shanty\nfolk ballad, Czech folk\nfolk ballad, Latin dance\nfolk ballad, Latin folk, epic folk\nfolk ballad, Latin folk-rock\nfolk ballad, Latin jazz\nfolk ballad, Mandopop, ambient\nfolk ballad, alt-country, Americana\nfolk ballad, alternative rock, post-rock\nfolk ballad, ambient, cinematic\nfolk ballad, art rock, blues-rock\nfolk ballad, big band jazz\nfolk ballad, big band swing\nfolk ballad, big band, show tune\nfolk ballad, big band, theatrical\nfolk ballad, bluegrass\nfolk ballad, bluegrass, Appalachian folk\nfolk ballad, bluegrass, Celtic folk\nfolk ballad, bluegrass, newgrass\nfolk ballad, cabaret rock\nfolk ballad, chanson, Latin pop\nfolk ballad, chanson, theatrical\nfolk ballad, cinematic pop, power ballad\nfolk ballad, cinematic rock\nfolk ballad, cinematic rock, ambient\nfolk ballad, cinematic rock, atmospheric\nfolk ballad, cinematic score\nfolk ballad, cinematic, Celtic\nfolk ballad, cinematic, Central Asian\nfolk ballad, cinematic, Chinese\nfolk ballad, cinematic, Chinese folk\nfolk ballad, cinematic, Eastern European\nfolk ballad, cinematic, ambient\nfolk ballad, cinematic, epic\nfolk ballad, cinematic, melancholic\nfolk ballad, cinematic, new-age\nfolk ballad, cinematic, orchestral\nfolk ballad, cinematic, patriotic\nfolk ballad, cinematic, sea shanty\nfolk ballad, classic rock\nfolk ballad, country rock\nfolk ballad, country-blues\nfolk ballad, cumbia\nfolk ballad, electronic, downtempo\nfolk ballad, epic anthem\nfolk ballad, eurodance\nfolk ballad, flamenco, Persian folk\nfolk ballad, flamenco, world music\nfolk ballad, folk dance\nfolk ballad, folk-rock\nfolk ballad, hardstyle, cinematic\nfolk ballad, heartland rock\nfolk ballad, indie rock\nfolk ballad, indie rock, cinematic\nfolk ballad, jump blues, psychedelic\nfolk ballad, klezmer, cinematic\nfolk ballad, klezmer, folk-rock\nfolk ballad, latin rumba\nfolk ballad, mambo, choral\nfolk ballad, mandolin, Southern Italian\nfolk ballad, musette, Chinese folk\nfolk ballad, neo-soul\nfolk ballad, ney, Central Asian\nfolk ballad, polka, country-western\nfolk ballad, pop-rock\nfolk ballad, pop-rock, Mandarin\nfolk ballad, pop-rock, big band\nfolk ballad, pop-rock, cinematic\nfolk ballad, pop-rock, patriotic rock\nfolk ballad, post-rock, shoegaze\nfolk ballad, power ballad\nfolk ballad, power ballad, cinematic rock\nfolk ballad, power metal\nfolk ballad, psychedelic rock\nfolk ballad, psychedelic rock, blues-rock\nfolk ballad, revolutionary anthem\nfolk ballad, rock anthem\nfolk ballad, rockabilly\nfolk ballad, rockabilly, cinematic\nfolk ballad, rockabilly, country-rock\nfolk ballad, roots-rock, blues-rock\nfolk ballad, rumba-flamenco, gypsy jazz\nfolk ballad, sea shanty, cinematic\nfolk ballad, ska-punk, cinematic\nfolk ballad, symphonic rock\nfolk ballad, theatrical folk, chanson\nfolk ballad, theatrical pop\nfolk ballad, theatrical, chanson\nfolk ballad, theatrical, cinematic\nfolk ballad, theatrical, operatic\nfolk ballad, tribal folk-rock\nfolk ballad, world music, anthemic\nfolk ballad, zamba, South American folk\nfolk baroque\nfolk bhajan\nfolk bhangra\nfolk big band\nfolk bluegrass\nfolk blues\nfolk blues americana\nfolk blues chanson\nfolk blues gospel\nfolk blues jazz\nfolk blues ragtime\nfolk blues reggae\nfolk blues rock\nfolk blues soul\nfolk blues world music\nfolk blues-rock\nfolk bolero\nfolk boogie\nfolk bossa nova\nfolk brass\nfolk cabaret\nfolk calypso\nfolk carnival\nfolk carol\nfolk celebration\nfolk cello\nfolk chamber\nfolk chanson\nfolk chant\nfolk children's\nfolk chill house\nfolk chiptune\nfolk choir\nfolk choral\nfolk christmas\nfolk cinematic\nfolk circus\nfolk classical\nfolk classical tango\nfolk comedy\nfolk corrido\nfolk country\nfolk country blues\nfolk country gospel\nfolk country polka\nfolk country sea shanty\nfolk country-blues\nfolk cumbia\nfolk dance\nfolk dance polka\nfolk dance pop\nfolk dance, Carnatic, Tamil\nfolk dance, cinematic, Middle Eastern\nfolk dance, cumbia, Arabic pop\nfolk dance, electronic, South Asian\nfolk dance, hip-hop, Indian fusion\nfolk dance, tarantella, Italian\nfolk dance-pop\nfolk darkwave\nfolk deep house\nfolk devotional\nfolk doom metal\nfolk drama\nfolk drinking song\nfolk duet\nfolk duo\nfolk education\nfolk electronic\nfolk electronic fusion\nfolk electronic pop\nfolk electronica\nfolk epic\nfolk ethereal wave\nfolk fairytale\nfolk fantasy\nfolk fest\nfolk festival\nfolk fiddle\nfolk film score\nfolk filmi\nfolk flamenco\nfolk flute\nfolk funk\nfolk funk hip-hop\nfolk funk reggae\nfolk funk rock\nfolk fusion\nfolk fusion samba\nfolk fusion trap\nfolk fusion, cinematic, South Asian\nfolk fusion, industrial metal\nfolk ghazal\nfolk gospel\nfolk gospel hip-hop\nfolk gospel rock\nfolk groove\nfolk guitar\nfolk hardstyle\nfolk hip hop\nfolk hip-hop\nfolk hip-hop classical\nfolk hip-hop electronic\nfolk hip-hop fusion\nfolk hip-hop pop-rock\nfolk hip-hop, revolutionary pop\nfolk hoedown\nfolk holiday\nfolk hop\nfolk horror\nfolk house\nfolk humor\nfolk hymn\nfolk hymn, polka, folk-rock\nfolk incantation\nfolk indie\nfolk indie rock\nfolk instrumental\nfolk jam\nfolk jam, bluegrass\nfolk jazz\nfolk jazz gospel\nfolk jazz klezmer\nfolk jazz rock\nfolk jazz-funk\nfolk jingle\nfolk jump blues\nfolk klezmer\nfolk lament\nfolk lullaby\nfolk lullaby, theatrical show tune\nfolk lute\nfolk march\nfolk march, choral, cinematic\nfolk meditation\nfolk melancholic\nfolk melancholy\nfolk metal\nfolk metal chiptune\nfolk metal chiptune rock\nfolk metal comedy rock\nfolk metal electronic rock\nfolk metal electronicore\nfolk metal eurodance\nfolk metal flamenco\nfolk metal groove metal\nfolk metal happy hardcore\nfolk metal hard rock\nfolk metal industrial rock\nfolk metal metalcore\nfolk metal nu-metal\nfolk metal pirate metal\nfolk metal pirate punk\nfolk metal polka\nfolk metal polka rock\nfolk metal power metal\nfolk metal power pop\nfolk metal progressive metal\nfolk metal progressive rock\nfolk metal punk\nfolk metal punk rock\nfolk metal rap-rock\nfolk metal sea shanty\nfolk metal sea shanty rock\nfolk metal speed metal\nfolk metal symphonic\nfolk metal symphonic power metal\nfolk metal symphonic rock\nfolk metal theatrical rock\nfolk metal thrash metal\nfolk metal world music\nfolk metal, Anatolian rock\nfolk metal, Balkan rock\nfolk metal, Celtic punk\nfolk metal, J-rock\nfolk metal, J-rock, sea shanty\nfolk metal, Latin rock\nfolk metal, alternative rock, nu-metal\nfolk metal, ambient, ancient style\nfolk metal, comedy rock\nfolk metal, deathcore, ambient\nfolk metal, electronic dance music\nfolk metal, happy hardcore\nfolk metal, hard dance\nfolk metal, hard rock\nfolk metal, hard rock, Chinese punk\nfolk metal, hardstyle, happy hardcore\nfolk metal, melodic death metal\nfolk metal, melodic death metal, chiptune\nfolk metal, melodic punk\nfolk metal, nu-metal, Chinese folk\nfolk metal, polka\nfolk metal, power metal, melodic death metal\nfolk metal, symphonic rock\nfolk metal, theatrical hard rock\nfolk metal, theatrical rock, polka\nfolk metal, world music rock\nfolk metalcore\nfolk murder ballad\nfolk musette\nfolk music\nfolk musical\nfolk narrative\nfolk neo-classical\nfolk new age world music\nfolk new-age\nfolk noir\nfolk noise rock\nfolk novelty\nfolk novelty polka\nfolk opera\nfolk orchestral\nfolk parade\nfolk parody\nfolk percussion\nfolk piano\nfolk piano bar\nfolk polka\nfolk polka klezmer\nfolk pop\nfolk pop fusion\nfolk pop hip-hop\nfolk pop punk\nfolk pop rock\nfolk pop, Brazilian pop-rock\nfolk pop, Chinese rap, pop-rock\nfolk pop, EDM, cinematic\nfolk pop, Latin Christmas\nfolk pop, Latin salsa\nfolk pop, Punjabi pop\nfolk pop, bhangra, ambient\nfolk pop, big band swing\nfolk pop, chanson, theatrical rock\nfolk pop, conscious hip-hop\nfolk pop, novelty, theatrical\nfolk pop, swing\nfolk pop, traditional Dutch, comedic\nfolk pop-punk\nfolk pop-rock\nfolk pop-rock boogie-woogie\nfolk post-rock\nfolk power ballad\nfolk power metal\nfolk praise\nfolk prayer\nfolk protest\nfolk protest, Americana, singer-songwriter\nfolk psychedelic\nfolk psychedelic rock\nfolk pub\nfolk pub rock\nfolk punk\nfolk punk celtic punk\nfolk punk chiptune\nfolk punk gypsy punk\nfolk punk hip-hop\nfolk punk klezmer\nfolk punk pirate metal\nfolk punk power metal\nfolk punk pub rock\nfolk punk rock\nfolk punk rockabilly\nfolk punk ska\nfolk punk ska-punk\nfolk punk turbo-folk\nfolk punk, Balkan folk\nfolk punk, Balkan rock\nfolk punk, Celtic punk\nfolk punk, Celtic punk, punk rock\nfolk punk, country, hoedown\nfolk punk, folk metal\nfolk punk, gypsy punk\nfolk punk, gypsy punk, punk rock\nfolk punk, hard rock\nfolk punk, pirate metal, accordion shredding\nfolk punk, polka metal\nfolk punk, polka rock\nfolk punk, polka rock, bluegrass\nfolk punk, polka rock, high-energy\nfolk punk, polka rock, rock\nfolk punk, polka, punk rock\nfolk punk, revolutionary anthem\nfolk punk, sea shanty rock\nfolk punk, speed metal\nfolk ranchera\nfolk rap\nfolk rap rock\nfolk reel\nfolk reggae\nfolk reggae pop\nfolk revival\nfolk revolutionary\nfolk ritual\nfolk rock\nfolk rock alternative rock\nfolk rock ambient\nfolk rock country rock\nfolk rock cumbia\nfolk rock electronic\nfolk rock emo\nfolk rock gospel\nfolk rock gypsy punk\nfolk rock hard rock\nfolk rock industrial\nfolk rock jazz fusion\nfolk rock klezmer\nfolk rock metal\nfolk rock noise rock\nfolk rock opera\nfolk rock polka\nfolk rock progressive\nfolk rock progressive rock\nfolk rock psychedelic\nfolk rock psychedelic rock\nfolk rock reggae\nfolk rock tango\nfolk rock world music\nfolk rock, Arabic folk, lo-fi, cinematic\nfolk rock, Chinese folk, hard rock\nfolk rock, Latin American, anthemic\nfolk rock, Latin rock\nfolk rock, Latin rock, surf rock\nfolk rock, Latin, accordion\nfolk rock, Mongolian folk metal\nfolk rock, Southeast Asian, vintage pop\nfolk rock, arena rock\nfolk rock, avant-garde, choral\nfolk rock, balkan folk, polka\nfolk rock, blues rock, classic rock\nfolk rock, cinematic\nfolk rock, cinematic, indie\nfolk rock, cinematic, surf rock\nfolk rock, cinematic, theatrical rock\nfolk rock, funk, ambient\nfolk rock, hard rock\nfolk rock, hard rock, South Indian fusion\nfolk rock, hard rock, Telugu fusion\nfolk rock, hard rock, heavy metal\nfolk rock, hard rock, thrash metal\nfolk rock, heavy metal\nfolk rock, heavy metal, Middle Eastern\nfolk rock, industrial rock\nfolk rock, industrial, ambient\nfolk rock, klezmer, Latin folk\nfolk rock, lo-fi psychedelic\nfolk rock, metalcore\nfolk rock, metalcore, Chinese folk\nfolk rock, polka, cinematic\nfolk rock, polka, theatrical\nfolk rock, pop-punk, hard rock\nfolk rock, pop-rock, hard rock\nfolk rock, post-hardcore\nfolk rock, post-rock, Chinese folk\nfolk rock, post-rock, cinematic\nfolk rock, post-rock, shoegaze\nfolk rock, power metal, new age\nfolk rock, progressive metal, Anatolian folk\nfolk rock, psychedelic rock\nfolk rock, psychedelic rock, atmospheric\nfolk rock, psychedelic rock, cinematic\nfolk rock, psychedelic rock, grunge\nfolk rock, psychedelic rock, hard rock\nfolk rock, revolutionary march\nfolk rock, rockabilly\nfolk rock, rockabilly, surf rock\nfolk rock, rockabilly, theatrical\nfolk rock, southern rock\nfolk rock, southern rock, blues rock\nfolk rock, spiritual, bansuri\nfolk rock, stadium rock, world music\nfolk rock, symphonic metal\nfolk rock, symphonic power metal\nfolk rock, theatrical pop, rock opera\nfolk rock, theatrical rock, big band jazz\nfolk rock, theatrical rock, comedic rock\nfolk rock, thrash metal\nfolk rock, world music\nfolk rock, world music, Greek\nfolk rock, world music, Middle Eastern\nfolk rock, wuxia, blues rock\nfolk rumba\nfolk sacred\nfolk salsa\nfolk samba\nfolk satire\nfolk sea shanty\nfolk shanty\nfolk shoegaze\nfolk show tune\nfolk singalong\nfolk singer-songwriter\nfolk ska\nfolk ska-punk\nfolk ska-reggae\nfolk soft rock americana\nfolk soul\nfolk soul blues-rock\nfolk soul funk\nfolk soul hip-hop\nfolk soul world music\nfolk spiritual\nfolk storytelling\nfolk string\nfolk swing\nfolk synth-pop\nfolk tango\nfolk tango cinematic\nfolk tango cumbia\nfolk tango protest\nfolk techno\nfolk theater\nfolk theatre\nfolk theatrical\nfolk to synth-pop\nfolk trance\nfolk trap\nfolk trip-hop\nfolk ukulele\nfolk violin\nfolk virtuosity\nfolk virtuoso\nfolk waltz\nfolk waltz circus\nfolk waltz, Chinese folk, cinematic\nfolk waltz, Spanish cante, cinematic ballad\nfolk waltz, ambient, C-pop\nfolk waltz, bluegrass, acoustic blues\nfolk waltz, cinematic, ambient\nfolk waltz, classical piano\nfolk waltz, marching band, accordion\nfolk waltz, tango ballad, cinematic\nfolk war song\nfolk whimsy\nfolk world\nfolk world acoustic\nfolk world classical\nfolk world fusion\nfolk world music\nfolk worldbeat\nfolk worship\nfolk worship chiptune\nfolk worship cumbia\nfolk, American primitivism\nfolk, Americana\nfolk, Americana, blues\nfolk, Americana, chamber folk\nfolk, Americana, narrative\nfolk, Americana, singer-songwriter\nfolk, Anatolian folk, raw folk\nfolk, Anatolian, melancholic\nfolk, Anatolian, melodic\nfolk, Anatolian, raw\nfolk, Andean, Latin\nfolk, Andean, ambient\nfolk, Andean, carnavalito\nfolk, Andean, charango\nfolk, Andean, festive\nfolk, Andean, traditional\nfolk, Appalachian, lo-fi\nfolk, Arabic, Turkish\nfolk, Arabic, accordion\nfolk, Arabic, atmospheric\nfolk, Arabic, dance\nfolk, Arabic, energetic\nfolk, Balkan folk\nfolk, Balkan, Klezmer\nfolk, Balkan, Middle Eastern\nfolk, Balkan, emotive\nfolk, Balkan, energetic\nfolk, Balkan, live\nfolk, Bhangra, accordion\nfolk, Caribbean, Latin\nfolk, Caribbean, acoustic\nfolk, Carnatic, soul\nfolk, Celtic, British\nfolk, Celtic, Christmas\nfolk, Celtic, Nordic fantasy\nfolk, Celtic, Portuguese\nfolk, Celtic, ambient\nfolk, Celtic, atmospheric\nfolk, Celtic, bluegrass\nfolk, Celtic, cinematic\nfolk, Celtic, instrumental\nfolk, Celtic, maritime\nfolk, Celtic, narrative\nfolk, Celtic, pub rock\nfolk, Celtic, sea shanty\nfolk, Central Asian, Anatolian\nfolk, Central Asian, Middle Eastern\nfolk, Central Asian, accordion\nfolk, Central Asian, celebratory\nfolk, Central Asian, dance\nfolk, Central Asian, energetic\nfolk, Central Asian, festive\nfolk, Central Asian, oud\nfolk, Central Asian, raw\nfolk, Central Asian, traditional\nfolk, Central Asian, vocal\nfolk, Chinese folk\nfolk, Chinese folk, acoustic\nfolk, Chinese folk, narrative folk\nfolk, Chinese opera, ambient\nfolk, Chinese, spiritual\nfolk, Christian contemporary\nfolk, Christmas, Chinese traditional\nfolk, Christmas, Czech\nfolk, Christmas, bilingual\nfolk, Christmas, communal\nfolk, Christmas, guzheng\nfolk, Christmas, traditional\nfolk, Christmas, upbeat\nfolk, East Asian, acoustic\nfolk, Eastern European, Latin\nfolk, Eastern European, Middle Eastern\nfolk, Eastern European, accordion\nfolk, Eastern European, bard\nfolk, Eastern European, dance\nfolk, Eastern European, narrative\nfolk, European folk\nfolk, European folk, Hebrew folk\nfolk, European folk, Middle Eastern folk\nfolk, European folk, traditional\nfolk, European, Middle Eastern\nfolk, European, tavern\nfolk, French folk, accordion\nfolk, French folk, raw folk\nfolk, German folk\nfolk, Gujarati, festive\nfolk, Haitian Creole, upbeat\nfolk, Hawaiian, acoustic\nfolk, Hawaiian, choral\nfolk, Hebrew folk, upbeat\nfolk, Hebrew, accordion\nfolk, Hebrew, choral\nfolk, Hebrew, flamenco\nfolk, Indian classical, acoustic\nfolk, Indian classical, ambient\nfolk, Indian classical, celebratory\nfolk, Indian classical, cinematic\nfolk, Indian classical, melancholic\nfolk, Indian classical, qawwali\nfolk, Indian classical, raw\nfolk, Indian classical, raw vocal\nfolk, Indian classical, world music\nfolk, Indian folk, acoustic\nfolk, Indian folk, ambient\nfolk, Indian folk, melancholic\nfolk, Indian folk, qawwali\nfolk, Indian folk, raw folk\nfolk, Indian folk, soulful\nfolk, Indian folk, traditional\nfolk, Indian folk, world music\nfolk, Indian, acoustic\nfolk, Indian, celebratory\nfolk, Indian, dance\nfolk, Indian, energetic\nfolk, Indian, lo-fi\nfolk, Indian, melancholic\nfolk, Indian, raw\nfolk, Indian, traditional\nfolk, Indian, upbeat\nfolk, Italian folk\nfolk, Italian folk, choral\nfolk, Italian folk, melancholic\nfolk, Italian singer-songwriter, acoustic\nfolk, Italian, acoustic\nfolk, Italian, ambient\nfolk, Italian, energetic\nfolk, Japanese, lo-fi\nfolk, Javanese, acoustic\nfolk, Kurdish, upbeat\nfolk, Latin American folk\nfolk, Latin American, Andean\nfolk, Latin American, Huapango\nfolk, Latin American, Zamba\nfolk, Latin American, accordion\nfolk, Latin American, acoustic\nfolk, Latin American, cabaret\nfolk, Latin American, carnavalito\nfolk, Latin American, carnival\nfolk, Latin American, charango\nfolk, Latin American, choral\nfolk, Latin American, corrido\nfolk, Latin American, cumbia\nfolk, Latin American, dance\nfolk, Latin American, danceable\nfolk, Latin American, energetic\nfolk, Latin American, festive\nfolk, Latin American, fiddle\nfolk, Latin American, forró\nfolk, Latin American, gypsy\nfolk, Latin American, huapango\nfolk, Latin American, joropo\nfolk, Latin American, klezmer\nfolk, Latin American, live\nfolk, Latin American, lo-fi\nfolk, Latin American, melancholic\nfolk, Latin American, party\nfolk, Latin American, political\nfolk, Latin American, polka\nfolk, Latin American, ragtime\nfolk, Latin American, ranchera\nfolk, Latin American, traditional\nfolk, Latin American, traditional Spanish\nfolk, Latin American, tribal\nfolk, Latin American, upbeat\nfolk, Latin American, waltz\nfolk, Latin American, zamba\nfolk, Latin folk\nfolk, Latin folk, Portuguese folk\nfolk, Latin folk, melancholic\nfolk, Latin folk, rumba\nfolk, Latin rumba, flamenco\nfolk, Latin, Afro-Cuban\nfolk, Latin, Andean\nfolk, Latin, Caribbean\nfolk, Latin, Creole\nfolk, Latin, Dutch\nfolk, Latin, European\nfolk, Latin, Iberian\nfolk, Latin, Spanish\nfolk, Latin, accordion\nfolk, Latin, acoustic\nfolk, Latin, ambient\nfolk, Latin, bilingual\nfolk, Latin, blues\nfolk, Latin, cafe\nfolk, Latin, choral\nfolk, Latin, cinematic\nfolk, Latin, dance\nfolk, Latin, festive\nfolk, Latin, flamenco\nfolk, Latin, melancholic\nfolk, Latin, novelty\nfolk, Latin, salsa\nfolk, Latin, storytelling\nfolk, Latin, upbeat\nfolk, Latin, whimsical\nfolk, Latin, world music\nfolk, Malay, Indonesian\nfolk, Mandarin, acoustic\nfolk, Mandarin, melancholic\nfolk, Mediterranean, Eastern European\nfolk, Mediterranean, Hebrew folk\nfolk, Mediterranean, acoustic\nfolk, Mediterranean, ambient\nfolk, Mediterranean, anthemic\nfolk, Mediterranean, choral\nfolk, Mediterranean, classical\nfolk, Mediterranean, sea shanty\nfolk, Mexican folk, huapango\nfolk, Middle Eastern folk, Malay folk\nfolk, Middle Eastern, Anatolian\nfolk, Middle Eastern, Armenian\nfolk, Middle Eastern, Caucasian\nfolk, Middle Eastern, Central Asian\nfolk, Middle Eastern, Klezmer\nfolk, Middle Eastern, Kurdish\nfolk, Middle Eastern, Mediterranean\nfolk, Middle Eastern, South Asian\nfolk, Middle Eastern, accordion\nfolk, Middle Eastern, acoustic\nfolk, Middle Eastern, celebratory\nfolk, Middle Eastern, chant\nfolk, Middle Eastern, choral\nfolk, Middle Eastern, cinematic\nfolk, Middle Eastern, dance\nfolk, Middle Eastern, energetic\nfolk, Middle Eastern, festive\nfolk, Middle Eastern, flamenco\nfolk, Middle Eastern, live\nfolk, Middle Eastern, melancholic\nfolk, Middle Eastern, traditional\nfolk, Middle Eastern, upbeat\nfolk, Middle Eastern, vintage\nfolk, Middle Eastern, virtuosic\nfolk, Mongolian throat singing, raw\nfolk, Mongolian, acoustic\nfolk, Māori, acoustic\nfolk, Māori, vintage\nfolk, North African, Middle Eastern\nfolk, North Indian, Middle Eastern\nfolk, North Indian, South Asian\nfolk, Portuguese folk, rustic\nfolk, Punjabi folk, emotive\nfolk, Punjabi, North Indian\nfolk, Punjabi, electronic\nfolk, Punjabi, melancholic\nfolk, Sinhala, upbeat\nfolk, South American, accordion\nfolk, South American, charango\nfolk, South American, energetic\nfolk, South American, festive\nfolk, South American, traditional\nfolk, South Asian folk\nfolk, South Asian folk, Middle Eastern folk\nfolk, South Asian, Laotian\nfolk, South Asian, Malay\nfolk, South Asian, Middle Eastern\nfolk, South Asian, Tibetan\nfolk, South Asian, acoustic\nfolk, South Asian, ambient\nfolk, South Asian, celebratory\nfolk, South Asian, dance\nfolk, South Asian, danceable\nfolk, South Asian, devotional\nfolk, South Asian, dholak\nfolk, South Asian, energetic\nfolk, South Asian, festive\nfolk, South Asian, ghazal\nfolk, South Asian, melancholic\nfolk, South Asian, oud\nfolk, South Asian, raw\nfolk, South Asian, singer-songwriter\nfolk, South Asian, spiritual\nfolk, South Asian, traditional\nfolk, South Asian, upbeat\nfolk, South Indian, traditional\nfolk, Southeast Asian folk\nfolk, Southeast Asian, Binsant\nfolk, Southeast Asian, South Asian\nfolk, Southeast Asian, accordion\nfolk, Southeast Asian, celebratory\nfolk, Southeast Asian, traditional\nfolk, Southeast Asian, upbeat\nfolk, Spanish folk, Latin American folk\nfolk, Spanish folk, acoustic\nfolk, Spanish folk, pastoral\nfolk, Spanish folk, sea shanty\nfolk, Spanish, Latin American\nfolk, Spanish, acoustic\nfolk, Spanish, cinematic\nfolk, Spanish, narrative\nfolk, Spanish, upbeat\nfolk, Spanish-influenced, narrative\nfolk, Spanish-style, emotional\nfolk, Sufi, South Asian\nfolk, Sundanese, upbeat\nfolk, Swedish folk, acoustic\nfolk, Tamil, uplifting\nfolk, Tamil, world music\nfolk, Turkish folk, patriotic\nfolk, Turkish, emotional\nfolk, Turkish, melancholic\nfolk, a cappella, Christmas\nfolk, a cappella, ska-punk\nfolk, accordion, Balkan\nfolk, accordion, Brazilian\nfolk, accordion, Dutch\nfolk, accordion, Dutch folk\nfolk, accordion, European\nfolk, accordion, French\nfolk, accordion, Latin\nfolk, accordion, Middle Eastern\nfolk, accordion, Parisian cafe\nfolk, accordion, Quebecois\nfolk, accordion, South American\nfolk, accordion, Spanish\nfolk, accordion, Turkish\nfolk, accordion, choir\nfolk, accordion, cinematic\nfolk, accordion, communal\nfolk, accordion, dance\nfolk, accordion, duet\nfolk, accordion, festive\nfolk, accordion, gypsy jazz\nfolk, accordion, instrumental\nfolk, accordion, male choir\nfolk, accordion, melancholic\nfolk, accordion, musette\nfolk, accordion, norteño\nfolk, accordion, polka\nfolk, accordion, traditional\nfolk, accordion, waltz\nfolk, acoustic, Chinese folk\nfolk, acoustic, Greek\nfolk, acoustic, Indian folk\nfolk, acoustic, Italian\nfolk, acoustic, Javanese\nfolk, acoustic, Latin\nfolk, acoustic, Mandarin ballad\nfolk, acoustic, Russian vocal\nfolk, acoustic, Sinhala\nfolk, acoustic, South African\nfolk, acoustic, South Asian\nfolk, acoustic, Southeast Asian\nfolk, acoustic, Spanish\nfolk, acoustic, cantautore\nfolk, acoustic, island\nfolk, acoustic, live\nfolk, acoustic, world\nfolk, ambient, Andean\nfolk, ambient, C-pop\nfolk, ambient, Chinese\nfolk, ambient, Chinese classical\nfolk, ambient, Chinese folk\nfolk, ambient, Chinese indie\nfolk, ambient, Chinese traditional\nfolk, ambient, East Asian\nfolk, ambient, Indian classical\nfolk, ambient, Italian\nfolk, ambient, Latin\nfolk, ambient, Mandarin folk\nfolk, ambient, Middle Eastern\nfolk, ambient, Nordic\nfolk, ambient, South Asian\nfolk, ambient, Spanish\nfolk, ambient, Swedish folk\nfolk, ambient, Turkish\nfolk, ambient, Vietnamese\nfolk, ambient, ancient style\nfolk, ambient, cinematic\nfolk, ambient, classical\nfolk, ambient, experimental\nfolk, ambient, ghazal\nfolk, ambient, lo-fi\nfolk, ambient, melancholic\nfolk, ambient, psychedelic\nfolk, ambient, sacred\nfolk, ambient, space\nfolk, ambient, traditional\nfolk, ambient, traditional Chinese\nfolk, ambient, traditional Japanese\nfolk, ambient, world music\nfolk, americana\nfolk, americana, acoustic\nfolk, americana, acoustic rock\nfolk, americana, chamber folk\nfolk, americana, choral\nfolk, americana, christmas\nfolk, americana, country\nfolk, americana, duet\nfolk, americana, latin folk\nfolk, americana, narrative folk\nfolk, americana, orchestral\nfolk, americana, sea shanty\nfolk, ancient style, cinematic\nfolk, anthemic, Japanese\nfolk, argentinian, a cappella\nfolk, argentinian, acoustic\nfolk, argentinian, carnivalito\nfolk, argentinian, zamba\nfolk, art-pop, dream-pop\nfolk, atmospheric, Hebrew folk\nfolk, atmospheric, traditional\nfolk, atmospheric, traditional Chinese\nfolk, banda, sierreño\nfolk, bansuri, South Asian\nfolk, bansuri, ambient\nfolk, bansuri, atmospheric\nfolk, bansuri, celebratory\nfolk, bansuri, classical\nfolk, bansuri, dholak\nfolk, bansuri, soulful\nfolk, baroque, theatrical\nfolk, big band, musette\nfolk, big band, polka\nfolk, bilingual, accordion\nfolk, bilingual, festive\nfolk, bluegrass\nfolk, bluegrass, Americana\nfolk, bluegrass, Celtic\nfolk, bluegrass, Eastern European\nfolk, bluegrass, acoustic\nfolk, bluegrass, choral\nfolk, bluegrass, cinematic\nfolk, bluegrass, cowpunk\nfolk, bluegrass, holiday\nfolk, bluegrass, theatrical\nfolk, blues, American bayou\nfolk, blues, Chinese folk\nfolk, blues, Latin\nfolk, blues, Southeast Asian\nfolk, blues, Tamil folk\nfolk, blues, ambient\nfolk, bossa nova, Chinese folk\nfolk, bossa nova, Latin\nfolk, brass, mariachi\nfolk, cabaret, chanson\nfolk, cabaret, cinematic\nfolk, cabaret, klezmer\nfolk, cabaret, theatrical\nfolk, cajón, Portuguese\nfolk, call-and-response, celebratory\nfolk, calypso, Latin guitar\nfolk, carnavalito, Argentinian\nfolk, carnavalito, Latin\nfolk, carnival, Latin\nfolk, carnivalito, South American\nfolk, carnivalito, upbeat\nfolk, celebratory, Hebrew\nfolk, celebratory, South Asian\nfolk, celebratory, accordion\nfolk, celebratory, dance\nfolk, celebratory, danceable\nfolk, celebratory, dholak\nfolk, celebratory, electronic\nfolk, celebratory, energetic\nfolk, celebratory, traditional Chinese\nfolk, ceremonial, ambient\nfolk, chacarera\nfolk, chacarera, acoustic\nfolk, chacarera, argentinian\nfolk, chacarera, carnavalito\nfolk, chacarera, live\nfolk, chacarera, traditional\nfolk, chamber folk\nfolk, chanson\nfolk, chanson, Hebrew folk\nfolk, chanson, Spanish folk\nfolk, chanson, accordion\nfolk, chanson, bal-musette\nfolk, chanson, cabaret\nfolk, chanson, polka\nfolk, children's music\nfolk, chiptune, Latin\nfolk, chiptune, march\nfolk, chiptune, melancholic\nfolk, chiptune, retro\nfolk, choral, Arabic\nfolk, choral, Celtic\nfolk, choral, Christmas\nfolk, choral, Fado\nfolk, choral, French\nfolk, choral, German folk\nfolk, choral, Latin American\nfolk, choral, Latin folk\nfolk, choral, accordion\nfolk, choral, acoustic\nfolk, choral, cinematic\nfolk, choral, classical\nfolk, choral, epic\nfolk, choral, live performance\nfolk, choral, mandolin\nfolk, choral, revolutionary\nfolk, choral, spoken word\nfolk, choral, traditional\nfolk, choral, waltz\nfolk, choral, world\nfolk, choral, world music\nfolk, christmas, narrative\nfolk, cinematic, Anatolian\nfolk, cinematic, Andean\nfolk, cinematic, Arabic\nfolk, cinematic, Bengali\nfolk, cinematic, Chinese\nfolk, cinematic, Chinese folk\nfolk, cinematic, Chinese traditional\nfolk, cinematic, Greek\nfolk, cinematic, Greek traditional\nfolk, cinematic, Hebrew vocal\nfolk, cinematic, Indian classical\nfolk, cinematic, Italian\nfolk, cinematic, Mandarin\nfolk, cinematic, Mandarin folk\nfolk, cinematic, Mandarin pop\nfolk, cinematic, Mongolian\nfolk, cinematic, Nepali\nfolk, cinematic, Nordic\nfolk, cinematic, South Asian\nfolk, cinematic, Spanish\nfolk, cinematic, Spanish storytelling\nfolk, cinematic, accordion\nfolk, cinematic, ambient\nfolk, cinematic, americana\nfolk, cinematic, ancient style\nfolk, cinematic, atmospheric\nfolk, cinematic, bansuri\nfolk, cinematic, choral\nfolk, cinematic, classical\nfolk, cinematic, epic\nfolk, cinematic, fantasy\nfolk, cinematic, indie\nfolk, cinematic, klezmer\nfolk, cinematic, lo-fi\nfolk, cinematic, melancholic\nfolk, cinematic, ney\nfolk, cinematic, operatic\nfolk, cinematic, orchestral\nfolk, cinematic, patriotic\nfolk, cinematic, spoken word\nfolk, cinematic, tango\nfolk, cinematic, traditional\nfolk, cinematic, world\nfolk, cinematic, world music\nfolk, circus, klezmer\nfolk, classical, Arabic\nfolk, classical, Chinese indie\nfolk, classical, Christmas\nfolk, classical, Italian\nfolk, classical, Middle Eastern\nfolk, classical, South Asian\nfolk, classical, Spanish\nfolk, classical, ambient\nfolk, classical, cinematic\nfolk, classical, emotional\nfolk, classical, flamenco\nfolk, classical, klezmer\nfolk, communal, theatrical\nfolk, corrido, Latin American\nfolk, corrido, acoustic\nfolk, corrido, ranchera\nfolk, country, Brazilian folk\nfolk, country, jazz\nfolk, country, narrative folk\nfolk, country-rock\nfolk, country-western, sea shanty\nfolk, cumbia\nfolk, cumbia, Andean\nfolk, cumbia, Latin\nfolk, cumbia, Latin American\nfolk, cumbia, acoustic\nfolk, cumbia, carnavalito\nfolk, cumbia, forró\nfolk, cumbia, norteño\nfolk, cumbia, ranchera\nfolk, cumbia, rumba\nfolk, cumbia, vallenato\nfolk, dance, Bengali\nfolk, dance, Galician\nfolk, dance, Latin\nfolk, dance, Middle Eastern\nfolk, dance, South American\nfolk, dance, South Asian\nfolk, dance, accordion\nfolk, dance, celebration\nfolk, dance, celebratory\nfolk, dance, energetic\nfolk, dance, festive\nfolk, dance, traditional\nfolk, dance, world\nfolk, darbuka, oud\nfolk, desert music, world\nfolk, devotional, Indian classical\nfolk, devotional, energetic\nfolk, devotional, traditional\nfolk, dhol, celebratory\nfolk, dholak, Punjabi\nfolk, dholak, accordion\nfolk, dholak, celebratory\nfolk, dholak, ghazal\nfolk, dholak, harmonium\nfolk, dholak, melodic\nfolk, dholak, sarangi\nfolk, dholak, shehnai\nfolk, dholak, spiritual\nfolk, dholak, tabla\nfolk, dholak, traditional\nfolk, dholak, zurna\nfolk, dixieland, ragtime\nfolk, duduk, Anatolian\nfolk, duduk, Middle Eastern\nfolk, duduk, melancholic\nfolk, duduk, traditional\nfolk, eastern european, bard\nfolk, eastern european, cinematic\nfolk, electronic, Indian fusion\nfolk, electronic, South Asian\nfolk, electronic, Southeast Asian\nfolk, electronic, devotional\nfolk, electronic, festive\nfolk, emotional, Spanish-influenced\nfolk, emotional, cinematic\nfolk, energetic, celebratory\nfolk, energetic, traditional\nfolk, epic, Central Asian\nfolk, epic, Middle Eastern\nfolk, epic, ambient\nfolk, epic, choral\nfolk, epic, mystical\nfolk, ethereal, acoustic\nfolk, ethereal, cinematic\nfolk, ethereal, ritual\nfolk, ethereal, traditional Russian\nfolk, fado, European\nfolk, fairy tale, Russian folk\nfolk, fast, energetic\nfolk, festive, Slavic\nfolk, festive, Spanish\nfolk, festive, accordion\nfolk, festive, dance\nfolk, festive, lo-fi\nfolk, festive, mystical\nfolk, festive, world music\nfolk, filmi, ghazal\nfolk, flamenco, Anatolian\nfolk, flamenco, Catalan\nfolk, flamenco, Central Asian\nfolk, flamenco, Chinese folk\nfolk, flamenco, European\nfolk, flamenco, Hebrew folk\nfolk, flamenco, Italian\nfolk, flamenco, Latin\nfolk, flamenco, Mandarin vocal\nfolk, flamenco, Middle Eastern\nfolk, flamenco, North African\nfolk, flamenco, Persian\nfolk, flamenco, Spanish\nfolk, flamenco, accordion\nfolk, flamenco, acoustic\nfolk, flamenco, ambient\nfolk, flamenco, bossa nova\nfolk, flamenco, cinematic\nfolk, flamenco, classical\nfolk, flamenco, emotional\nfolk, flamenco, indie\nfolk, flamenco, lo-fi\nfolk, flamenco, sea shanty\nfolk, flamenco, theatrical\nfolk, flamenco, world\nfolk, flamenco, world music\nfolk, forró, Brazilian\nfolk, forró, choral\nfolk, forró, sertanejo\nfolk, ghazal, South Asian\nfolk, ghazal, acoustic\nfolk, ghazal, ambient\nfolk, ghazal, traditional Indian\nfolk, ghazal, traditional South Asian\nfolk, gospel, comedy\nfolk, gospel, polka\nfolk, guzheng, whimsical\nfolk, gypsy jazz, Hebrew folk\nfolk, gypsy jazz, Latin\nfolk, gypsy jazz, chanson\nfolk, gypsy jazz, flamenco\nfolk, gypsy jazz, klezmer\nfolk, gypsy jazz, theatrical\nfolk, gypsy-folk, Balkan\nfolk, gypsy-folk, world music\nfolk, holiday, Eastern European\nfolk, holiday, instrumental\nfolk, honky-tonk, storytelling\nfolk, huapango, son huasteco\nfolk, huapango, traditional mexican\nfolk, indie rock\nfolk, indie rock, choral\nfolk, instrumental, European\nfolk, joropo, Latin American\nfolk, joropo, cumbia\nfolk, joropo, latin\nfolk, joropo, latin american\nfolk, joropo, llanera\nfolk, joropo, música llanera\nfolk, klezmer\nfolk, klezmer, Balkan\nfolk, klezmer, Eastern European\nfolk, klezmer, European\nfolk, klezmer, ambient\nfolk, klezmer, balkan\nfolk, klezmer, cabaret\nfolk, klezmer, celebratory\nfolk, klezmer, cinematic\nfolk, klezmer, coastal\nfolk, klezmer, dance\nfolk, klezmer, european folk\nfolk, klezmer, fast-paced\nfolk, klezmer, holiday\nfolk, klezmer, instrumental\nfolk, klezmer, live\nfolk, klezmer, musette\nfolk, klezmer, operatic\nfolk, klezmer, piano accordion\nfolk, klezmer, polka\nfolk, klezmer, satirical\nfolk, klezmer, string ensemble\nfolk, klezmer, theatrical\nfolk, klezmer, traditional\nfolk, klezmer, upbeat\nfolk, latin folk, vintage\nfolk, latin, flamenco\nfolk, latin, melancholic\nfolk, levenslied, live\nfolk, live, accordion\nfolk, lo-fi chiptune\nfolk, lo-fi, Balkan\nfolk, lo-fi, Latin\nfolk, lo-fi, Latin American\nfolk, lo-fi, Mediterranean\nfolk, lo-fi, North African\nfolk, lo-fi, South Asian\nfolk, lo-fi, accordion\nfolk, lo-fi, ambient\nfolk, lo-fi, cinematic\nfolk, lo-fi, traditional South Asian\nfolk, lo-fi, vintage\nfolk, mariachi, Latin\nfolk, mariachi, anthemic\nfolk, mariachi, ranchera\nfolk, martial, traditional\nfolk, medieval, Middle Eastern\nfolk, medieval, renaissance\nfolk, medieval, theatrical\nfolk, meditative, Hebrew\nfolk, meditative, spiritual\nfolk, mediterranean, emotional\nfolk, melancholic, Arabic\nfolk, melancholic, Central Asian\nfolk, melancholic, Chinese folk\nfolk, melancholic, Hindi\nfolk, melancholic, Italian\nfolk, melancholic, Japanese\nfolk, melancholic, Middle Eastern\nfolk, melancholic, Mongolian\nfolk, melancholic, Portuguese\nfolk, melancholic, South Asian\nfolk, melancholic, Spanish\nfolk, melancholic, Turkish\nfolk, melancholic, accordion\nfolk, melancholic, acoustic\nfolk, melancholic, ambient\nfolk, melancholic, atmospheric\nfolk, melancholic, bansuri\nfolk, melancholic, cinematic\nfolk, melancholic, duet\nfolk, melancholic, ghazal\nfolk, melancholic, modern\nfolk, melancholic, mystical\nfolk, melancholic, operatic\nfolk, melancholic, traditional\nfolk, melancholic, waltz\nfolk, microtonal, traditional\nfolk, milonga, traditional Argentine\nfolk, musette, Balkan\nfolk, musette, European folk\nfolk, musette, accordion\nfolk, musette, cinematic\nfolk, musette, gypsy jazz\nfolk, musette, instrumental\nfolk, musette, klezmer\nfolk, musette, live\nfolk, musette, playful\nfolk, musette, polka\nfolk, musette, tango\nfolk, musette, tarantella\nfolk, musette, upbeat\nfolk, musette, waltz\nfolk, narrative, Chinese folk\nfolk, narrative, French pop\nfolk, nashid, traditional Arabic\nfolk, neo-classical\nfolk, neo-classical, Spanish\nfolk, neo-classical, ambient\nfolk, neo-classical, atmospheric\nfolk, neo-classical, world music\nfolk, neoclassical\nfolk, new age, inspirational\nfolk, new-age\nfolk, new-age, world folk\nfolk, ney flute, atmospheric\nfolk, ney, French\nfolk, ney, Middle Eastern\nfolk, ney, cinematic\nfolk, ney, melancholic\nfolk, ney, traditional\nfolk, novelty, bossa nova\nfolk, operatic, Balkan\nfolk, operatic, Eastern European\nfolk, operatic, European\nfolk, operatic, ambient\nfolk, operatic, choral\nfolk, operatic, cinematic\nfolk, operatic, liturgical\nfolk, orchestral, operatic\nfolk, oud, Anatolian\nfolk, oud, Caribbean\nfolk, oud, Central Asian\nfolk, oud, Indian classical\nfolk, oud, Middle Eastern\nfolk, oud, South Asian\nfolk, oud, celebratory\nfolk, oud, cinematic\nfolk, oud, darbuka\nfolk, oud, duduk\nfolk, oud, emotional\nfolk, oud, live\nfolk, oud, lo-fi\nfolk, oud, melancholic\nfolk, oud, melodic\nfolk, oud, spiritual\nfolk, oud, traditional\nfolk, pastoral, East Asian\nfolk, pastoral, Latin\nfolk, pastoral, Polish\nfolk, patriotic, Middle Eastern\nfolk, patriotic, accordion\nfolk, percussion, Latin\nfolk, piano, accordion\nfolk, piano, ambient\nfolk, piano, theatrical\nfolk, pimba, cumbia\nfolk, pimba, fado\nfolk, pimba, forró\nfolk, political, Latin folk\nfolk, political, Zulu\nfolk, polka, Americana\nfolk, polka, Balkan\nfolk, polka, European\nfolk, polka, Latin\nfolk, polka, accordion\nfolk, polka, ambient\nfolk, polka, bilingual\nfolk, polka, choral\nfolk, polka, cumbia\nfolk, polka, festive\nfolk, polka, levenslied\nfolk, polka, musette\nfolk, polka, pub rock\nfolk, polka, ranchera\nfolk, polka, sea shanty\nfolk, polka, theatrical\nfolk, polka, traditional\nfolk, polka, waltz\nfolk, post-rock\nfolk, post-rock, French indie\nfolk, post-rock, ambient\nfolk, post-rock, shoegaze\nfolk, power metal\nfolk, progressive house, big room\nfolk, psychedelic rock, Brazilian rhythm\nfolk, psychedelic, acoustic\nfolk, psychedelic, ambient\nfolk, psychedelic, cinematic\nfolk, psychedelic, hip-hop\nfolk, psychedelic, polka\nfolk, psychedelic, traditional\nfolk, qawwali, South Asian\nfolk, qawwali, world music\nfolk, ragtime, musette\nfolk, ragtime, party\nfolk, ranchera\nfolk, ranchera, acoustic\nfolk, ranchera, corrido\nfolk, ranchera, hoedown\nfolk, ranchera, lo-fi\nfolk, regional Mexican\nfolk, regional Mexican, Latin\nfolk, regional Mexican, accordion\nfolk, regional Mexican, raw\nfolk, retro synth, devotional\nfolk, ritual, ambient\nfolk, rumba, Catalan\nfolk, rumba, European\nfolk, rumba, Spanish\nfolk, rumba, acoustic\nfolk, rumba, spoken word\nfolk, sacred, choral\nfolk, sacred, classical\nfolk, satirical, Dutch\nfolk, satirical, bluegrass\nfolk, satirical, energetic\nfolk, sea shanty\nfolk, sea shanty, Americana\nfolk, sea shanty, Celtic\nfolk, sea shanty, European\nfolk, sea shanty, European folk\nfolk, sea shanty, Irish pub\nfolk, sea shanty, Mediterranean\nfolk, sea shanty, accordion\nfolk, sea shanty, comedic\nfolk, sea shanty, gypsy jazz\nfolk, sea shanty, instrumental\nfolk, sea shanty, polka\nfolk, sea shanty, pub rock\nfolk, sea shanty, pub song\nfolk, sea shanty, tavern music\nfolk, sea shanty, tavern song\nfolk, sea shanty, theatrical\nfolk, sea shanty, traditional\nfolk, shamanic, ancient style\nfolk, shehnai, celebratory\nfolk, shehnai, dandiya\nfolk, shehnai, dholak\nfolk, shehnai, energetic\nfolk, singer-songwriter, Americana\nfolk, soul, European\nfolk, soulful, South Asian\nfolk, soulful, shehnai\nfolk, spiritual, Indian\nfolk, spiritual, Latin\nfolk, spiritual, Middle Eastern\nfolk, spiritual, South Asian\nfolk, spiritual, choral\nfolk, spiritual, epic\nfolk, spiritual, melodic\nfolk, spiritual, traditional\nfolk, spiritual, tribal\nfolk, spoken word, world\nfolk, synth, Southeast Asian\nfolk, synth, children's\nfolk, synth, video game\nfolk, tango, Latin\nfolk, tango, acoustic\nfolk, tango, argentinian\nfolk, tango, cinematic\nfolk, tango, classical\nfolk, tango, fado\nfolk, tango, milonga\nfolk, tango, musette\nfolk, tango, ranchera\nfolk, tango, traditional\nfolk, tango, traditional Argentine\nfolk, tango, world music\nfolk, tarantella, Italian\nfolk, tarantella, Southern Italian\nfolk, theatrical, Eastern European\nfolk, theatrical, European folk\nfolk, theatrical, Hebrew vocal\nfolk, theatrical, Hungarian\nfolk, theatrical, Middle Eastern\nfolk, theatrical, Nordic\nfolk, theatrical, Russian\nfolk, theatrical, Spanish\nfolk, theatrical, accordion\nfolk, theatrical, cabaret\nfolk, theatrical, cinematic\nfolk, theatrical, enka\nfolk, theatrical, epic\nfolk, theatrical, festive\nfolk, theatrical, flamenco\nfolk, theatrical, klezmer\nfolk, theatrical, satirical\nfolk, theatrical, waltz\nfolk, thrash metal\nfolk, traditional Chinese, celebratory\nfolk, traditional East Asian, cinematic\nfolk, traditional Mongolian, epic\nfolk, traditional, Anatolian\nfolk, traditional, Argentine\nfolk, traditional, Central Asian\nfolk, traditional, Christmas\nfolk, traditional, Hebrew\nfolk, traditional, Indian\nfolk, traditional, Latin\nfolk, traditional, Middle Eastern\nfolk, traditional, Mongolian\nfolk, traditional, South American\nfolk, traditional, South Asian\nfolk, traditional, Southeast Asian\nfolk, traditional, Spanish\nfolk, traditional, acoustic\nfolk, traditional, argentinian\nfolk, traditional, celebratory\nfolk, traditional, cinematic\nfolk, traditional, dance\nfolk, traditional, dholak\nfolk, traditional, energetic\nfolk, traditional, lo-fi\nfolk, traditional, ney\nfolk, traditional, patriotic\nfolk, traditional, qawwali\nfolk, traditional, spiritual\nfolk, traditional, theatrical\nfolk, traditional, world\nfolk, traditional, world music\nfolk, trance, world music\nfolk, ukulele, island\nfolk, ukulele, tropical\nfolk, upbeat, Galician\nfolk, upbeat, Sinhala\nfolk, upbeat, South African\nfolk, upbeat, South Asian\nfolk, upbeat, celebratory\nfolk, upbeat, festive\nfolk, upbeat, nostalgic\nfolk, upbeat, whimsical\nfolk, vallenato, accordion\nfolk, vallenato, chacarera\nfolk, vallenato, cumbia\nfolk, vintage, Indian folk\nfolk, vintage, Persian\nfolk, virtuosic, Russian\nfolk, vocal, Russian\nfolk, waltz, Basque\nfolk, waltz, Galician\nfolk, waltz, Latin\nfolk, waltz, Persian\nfolk, waltz, South American\nfolk, waltz, cinematic\nfolk, waltz, polka\nfolk, waltz, sea shanty\nfolk, waltz, vintage\nfolk, western, narrative\nfolk, whimsical, cinematic\nfolk, world music\nfolk, world music, Balkan\nfolk, world music, Chinese folk\nfolk, world music, Indian folk\nfolk, world music, Mandarin folk\nfolk, world music, Mediterranean\nfolk, world music, Spanish guitar\nfolk, world music, acoustic ballad\nfolk, world music, ambient\nfolk, world music, art song\nfolk, world music, bansuri\nfolk, world music, cinematic\nfolk, world music, lo-fi hip hop\nfolk, world music, neo-classical\nfolk, world music, new age\nfolk, world music, spiritual\nfolk, world music, theatrical\nfolk, world music, traditional\nfolk, world music, upbeat\nfolk, world, Arabic\nfolk, world, Indian folk\nfolk, world, Portuguese\nfolk, world, Tamil folk\nfolk, world, accordion\nfolk, world, acoustic\nfolk, world, ambient\nfolk, world, ancient style\nfolk, world, celebratory\nfolk, world, choral\nfolk, world, cinematic\nfolk, world, communal\nfolk, world, dance\nfolk, world, devotional\nfolk, world, duduk\nfolk, world, emotional\nfolk, world, energetic\nfolk, world, erhu\nfolk, world, ethereal\nfolk, world, festive\nfolk, world, instrumental\nfolk, world, live\nfolk, world, melancholic\nfolk, world, microtonal\nfolk, world, percussion\nfolk, world, percussive\nfolk, world, protest\nfolk, world, raw\nfolk, world, soul\nfolk, world, spoken word\nfolk, world, traditional\nfolk, world, upbeat\nfolk, world, vocal\nfolk, zamba, Latin American\nfolk, zamba, chacarera\nfolk, zamba, traditional argentinian\nfolk-Americana\nfolk-ballad\nfolk-ballad pop-rock\nfolk-blues\nfolk-blues bluegrass\nfolk-blues hip-hop\nfolk-blues indie rock\nfolk-blues protest\nfolk-blues rock\nfolk-blues roots-rock\nfolk-blues, boogie-rock\nfolk-blues, free jazz, jam band\nfolk-blues, jump blues\nfolk-chanson\nfolk-chanson, rock, flamenco\nfolk-classical\nfolk-country\nfolk-country hip-hop\nfolk-country novelty\nfolk-country polka\nfolk-country rock\nfolk-country satire\nfolk-country trap\nfolk-cumbia\nfolk-dance\nfolk-dance EDM\nfolk-dance electronic\nfolk-dance fusion\nfolk-dance pop\nfolk-dance techno\nfolk-dance, Indian, ambient\nfolk-dance, Middle Eastern, dance\nfolk-dance, Middle Eastern, electronic\nfolk-dance, Middle Eastern, energetic\nfolk-dance, cinematic, Middle Eastern\nfolk-dance, cinematic, devotional\nfolk-dance, cinematic, electronic\nfolk-dance, electronic, Anatolian\nfolk-dance, electronic, Armenian\nfolk-dance, electronic, Azerbaijani\nfolk-dance, electronic, Central Asian\nfolk-dance, electronic, Indian\nfolk-dance, electronic, Middle Eastern\nfolk-dance, electronic, South Asian\nfolk-dance, electronic, Tamil\nfolk-dance, electronic, dance\nfolk-dance, electronic, klezmer\nfolk-dance, electronic, turbo-folk\nfolk-dance, electronic, world fusion\nfolk-dance, eurodance\nfolk-dance, ney, ambient\nfolk-dance, oud, darbuka\nfolk-dance, polka, electronic\nfolk-dance, pop-rock, Middle Eastern\nfolk-dance, progressive house\nfolk-dance, retro electronic, Indian\nfolk-dance, slap house, Eastern European\nfolk-dance, synth-pop, traditional\nfolk-disco\nfolk-electronic\nfolk-electronic dance-pop\nfolk-electronic fusion\nfolk-electronic worldbeat\nfolk-electronic, Latin rock, fusion\nfolk-electronica\nfolk-funk\nfolk-fusion\nfolk-fusion dance\nfolk-fusion ghazal\nfolk-fusion hip-hop\nfolk-fusion pop\nfolk-fusion worldbeat\nfolk-fusion, Bhangra, Indian classical\nfolk-fusion, Bhangra-pop\nfolk-fusion, Middle Eastern, pop-rock\nfolk-fusion, Sufi, pop-fusion\nfolk-fusion, cinematic, pop\nfolk-fusion, electronic, Indian classical\nfolk-gospel\nfolk-gospel ballad\nfolk-gospel bluegrass\nfolk-gospel country\nfolk-gospel cumbia\nfolk-gospel funk-rock\nfolk-gospel funk-rock psychedelic rock\nfolk-gospel indie pop-rock\nfolk-gospel indie rock\nfolk-gospel pop-rock\nfolk-gospel rock\nfolk-gospel rockabilly\nfolk-gospel, Christian rock\nfolk-gospel, Latin, upbeat\nfolk-gospel, soft rock\nfolk-gospel, southern rock\nfolk-gothic\nfolk-hop\nfolk-horror\nfolk-house\nfolk-hymn\nfolk-inflected pop-rock\nfolk-infused dance-pop\nfolk-infused hip-hop\nfolk-inspired\nfolk-inspired cinematic\nfolk-inspired, acoustic, Indian film music\nfolk-inspired, electronic, Indian\nfolk-jazz\nfolk-jazz bossa nova\nfolk-jazz cabaret\nfolk-jazz chanson\nfolk-jazz fusion\nfolk-jazz gypsy jazz\nfolk-jazz gypsy-jazz upbeat\nfolk-jazz noir\nfolk-metal\nfolk-metal J-rock\nfolk-metal alternative metal\nfolk-metal gypsy-punk\nfolk-metal melodic death metal\nfolk-metal neoclassical\nfolk-metal power metal\nfolk-metal progressive metal\nfolk-metal punk\nfolk-metal symphonic metal\nfolk-metal thrash\nfolk-metal, cinematic, hip-hop\nfolk-metal, cinematic, metalcore\nfolk-metal, melodic death metal\nfolk-metal, power metal, cinematic\nfolk-metal, trap, cinematic\nfolk-noir\nfolk-noir blues-rock\nfolk-noir country-rock\nfolk-noir hip-hop\nfolk-orchestral\nfolk-orchestral hardstyle\nfolk-polka\nfolk-polka, heavy metal\nfolk-pop\nfolk-pop Americana\nfolk-pop Balkan\nfolk-pop Bhojpuri\nfolk-pop C-pop\nfolk-pop C-pop upbeat\nfolk-pop Celtic\nfolk-pop Christmas\nfolk-pop EDM\nfolk-pop Eastern European\nfolk-pop European chanson\nfolk-pop Indian\nfolk-pop Indian fusion\nfolk-pop J-pop\nfolk-pop J-pop anime\nfolk-pop J-rock\nfolk-pop Latin\nfolk-pop Latin American\nfolk-pop Latin flamenco\nfolk-pop Latin groove\nfolk-pop Tibetan\nfolk-pop alt-rock\nfolk-pop alternative rock\nfolk-pop ambient\nfolk-pop americana\nfolk-pop anime soundtrack\nfolk-pop ballad\nfolk-pop big band\nfolk-pop big band jazz\nfolk-pop bluegrass\nfolk-pop bluegrass Tibetan\nfolk-pop bluegrass celtic\nfolk-pop bluegrass country\nfolk-pop blues\nfolk-pop blues boogie-woogie\nfolk-pop blues country\nfolk-pop blues-rock\nfolk-pop boogie-woogie\nfolk-pop bossa nova\nfolk-pop brass\nfolk-pop cabaret\nfolk-pop cabaret gypsy jazz\nfolk-pop cabaret klezmer\nfolk-pop cabaret swing\nfolk-pop cabaret tango\nfolk-pop calypso\nfolk-pop chanson\nfolk-pop chiptune\nfolk-pop chiptune sea shanty\nfolk-pop chiptune world music\nfolk-pop cinematic\nfolk-pop cinematic ballad\nfolk-pop country\nfolk-pop country bluegrass\nfolk-pop country boeremusiek\nfolk-pop country celtic\nfolk-pop country polka\nfolk-pop country pub-rock\nfolk-pop country rockabilly\nfolk-pop country show tune\nfolk-pop country swing\nfolk-pop country-gospel\nfolk-pop country-pop\nfolk-pop country-rock\nfolk-pop country-rockabilly\nfolk-pop cumbia\nfolk-pop cumbia accordion\nfolk-pop cumbia bilingual\nfolk-pop cumbia world music\nfolk-pop dance\nfolk-pop dance-pop\nfolk-pop dancehall\nfolk-pop danseband\nfolk-pop disco polo\nfolk-pop doo-wop vintage\nfolk-pop electro house\nfolk-pop electronic\nfolk-pop emo-trap\nfolk-pop estrada\nfolk-pop eurodance\nfolk-pop flamenco\nfolk-pop funk-rock\nfolk-pop fusion\nfolk-pop future bass\nfolk-pop gospel\nfolk-pop gypsy jazz\nfolk-pop gypsy jazz eastern european\nfolk-pop gypsy jazz flamenco\nfolk-pop gypsy jazz klezmer\nfolk-pop gypsy jazz manouche\nfolk-pop gypsy jazz theatrical\nfolk-pop gypsy jazz world music\nfolk-pop gypsy-jazz\nfolk-pop gypsy-jazz upbeat\nfolk-pop hip-hop\nfolk-pop hip-hop indie rock\nfolk-pop indie\nfolk-pop indie rock\nfolk-pop indie rock punk\nfolk-pop indie-pop\nfolk-pop klezmer\nfolk-pop lo-fi\nfolk-pop lo-fi hip-hop\nfolk-pop lounge-jazz\nfolk-pop mandopop\nfolk-pop manouche\nfolk-pop musical theater\nfolk-pop novelty\nfolk-pop orchestral\nfolk-pop orchestral pop\nfolk-pop pimba\nfolk-pop polka\nfolk-pop post-rock\nfolk-pop power metal\nfolk-pop progressive house\nfolk-pop protest\nfolk-pop psychedelic rock\nfolk-pop punk rock\nfolk-pop reggae\nfolk-pop reggae-ska\nfolk-pop retro\nfolk-pop retro synth\nfolk-pop rock\nfolk-pop rock electronic\nfolk-pop rockabilly\nfolk-pop rumba\nfolk-pop satire\nfolk-pop schlager\nfolk-pop schlager country\nfolk-pop sea shanty\nfolk-pop soft rock\nfolk-pop sunshine pop\nfolk-pop synth-pop\nfolk-pop tango\nfolk-pop tango Eastern European\nfolk-pop tango cabaret\nfolk-pop tango gypsy jazz\nfolk-pop theatrical hip-hop\nfolk-pop tropical\nfolk-pop tropical house\nfolk-pop turbo-folk\nfolk-pop waltz\nfolk-pop world music\nfolk-pop worldbeat\nfolk-pop worship\nfolk-pop zouk\nfolk-pop, 90s pop, South Asian\nfolk-pop, Anatolian, Middle Eastern\nfolk-pop, Anatolian, electronic\nfolk-pop, Anatolian, energetic\nfolk-pop, Anatolian, upbeat\nfolk-pop, Armenian, trap\nfolk-pop, Azerbaijani, synth\nfolk-pop, Balkan, gypsy jazz\nfolk-pop, Balkan, theatrical\nfolk-pop, Bhangra, ghazal\nfolk-pop, Bhangra, traditional\nfolk-pop, Bollywood dance-pop\nfolk-pop, Bollywood, pop-rock\nfolk-pop, Bollywood, upbeat\nfolk-pop, C-pop\nfolk-pop, Celtic rock\nfolk-pop, Celtic, Christmas\nfolk-pop, Celtic, uplifting\nfolk-pop, Central African, Muzică Populară\nfolk-pop, Central Asian\nfolk-pop, Central Asian, cinematic\nfolk-pop, Central Asian, electronic\nfolk-pop, Central Asian, energetic\nfolk-pop, Central Asian, estrada\nfolk-pop, Central Asian, microtonal\nfolk-pop, Central Asian, pop-dance\nfolk-pop, Central Asian, upbeat\nfolk-pop, Chinese folk, cinematic\nfolk-pop, Chinese folk, lo-fi\nfolk-pop, Chinese style, cinematic\nfolk-pop, Chinese, theatrical\nfolk-pop, Christian contemporary\nfolk-pop, Christian hip-hop\nfolk-pop, Christian worship, Eastern European\nfolk-pop, Christian, South Indian\nfolk-pop, Dutch, Western\nfolk-pop, EDM, Ukrainian\nfolk-pop, EDM, progressive house\nfolk-pop, EDM-pop, future bass\nfolk-pop, Eastern European, estrada\nfolk-pop, Eastern European, novelty\nfolk-pop, Eastern European, polka\nfolk-pop, Eastern European, satirical\nfolk-pop, Eastern European, theatrical\nfolk-pop, European, cumbia\nfolk-pop, French chanson\nfolk-pop, Hawaiian, upbeat\nfolk-pop, Indian classical\nfolk-pop, Indian classical, ambient\nfolk-pop, Indian classical, atmospheric\nfolk-pop, Indian classical, cinematic\nfolk-pop, Indian classical, dholak\nfolk-pop, Indian classical, electronic\nfolk-pop, Indian folk, ambient\nfolk-pop, Indian fusion\nfolk-pop, Indian fusion, cinematic\nfolk-pop, Indian fusion, electronic\nfolk-pop, Indian fusion, rock\nfolk-pop, Indian pop, ambient\nfolk-pop, Indian regional, Bhojpuri\nfolk-pop, Indian regional, dance\nfolk-pop, Indian, cinematic\nfolk-pop, Indian, electronic\nfolk-pop, Indian, modern\nfolk-pop, Indian, upbeat\nfolk-pop, J-rock\nfolk-pop, Kurdish, Middle Eastern\nfolk-pop, Latin American, Māori\nfolk-pop, Latin cumbia\nfolk-pop, Latin pop\nfolk-pop, Latin salsa\nfolk-pop, Latin, Caribbean\nfolk-pop, Latin, Dutch\nfolk-pop, Latin, Indian\nfolk-pop, Latin, Mediterranean\nfolk-pop, Latin, Russian\nfolk-pop, Latin, Schlager\nfolk-pop, Latin, big band\nfolk-pop, Latin, cabaret\nfolk-pop, Latin, cumbia\nfolk-pop, Latin, festive\nfolk-pop, Latin, gypsy jazz\nfolk-pop, Latin, klezmer\nfolk-pop, Latin, pop-rock\nfolk-pop, Latin, punk rock\nfolk-pop, Latin, upbeat\nfolk-pop, Latin, world music\nfolk-pop, Luk Thung, Mor Lam\nfolk-pop, MPB, spiritual\nfolk-pop, Middle Eastern, Anatolian\nfolk-pop, Middle Eastern, Arabic\nfolk-pop, Middle Eastern, Armenian\nfolk-pop, Middle Eastern, Azerbaijani\nfolk-pop, Middle Eastern, Central Asian\nfolk-pop, Middle Eastern, Kurdish\nfolk-pop, Middle Eastern, Persian\nfolk-pop, Middle Eastern, South Asian\nfolk-pop, Middle Eastern, cinematic\nfolk-pop, Middle Eastern, dance\nfolk-pop, Middle Eastern, electronic\nfolk-pop, Middle Eastern, melancholic\nfolk-pop, Middle Eastern, oud\nfolk-pop, Middle Eastern, upbeat\nfolk-pop, Middle Eastern, uplifting\nfolk-pop, Mizrahi, world music\nfolk-pop, Nepali Christian, celebratory\nfolk-pop, Polynesian, world music\nfolk-pop, Raï, Klezmer\nfolk-pop, Schlager, traditional European\nfolk-pop, South Asian, 80s pop\nfolk-pop, South Asian, cinematic\nfolk-pop, South Asian, dance\nfolk-pop, South Asian, electronic\nfolk-pop, South Asian, energetic\nfolk-pop, South Asian, future bass\nfolk-pop, South Asian, ghazal\nfolk-pop, South Asian, hyperpop\nfolk-pop, South Asian, modern\nfolk-pop, South Asian, upbeat\nfolk-pop, South Indian Christian, devotional\nfolk-pop, South Indian film music\nfolk-pop, South Indian, Gaana\nfolk-pop, South Indian, upbeat\nfolk-pop, Southeast Asian, cumbia\nfolk-pop, Southeast Asian, upbeat\nfolk-pop, Tamil Christian, devotional\nfolk-pop, Thai pop, blues rock\nfolk-pop, acoustic, Bengali\nfolk-pop, alt-rock\nfolk-pop, ambient, South Asian\nfolk-pop, ambient, traditional\nfolk-pop, atmospheric, Southeast Asian\nfolk-pop, belly dance, traditional\nfolk-pop, bhajan, Indian classical\nfolk-pop, blues-rock\nfolk-pop, blues-rock, cinematic\nfolk-pop, cabaret, Balkan\nfolk-pop, cabaret, European\nfolk-pop, cabaret, cinematic\nfolk-pop, cabaret, theatrical\nfolk-pop, calypso, tropical\nfolk-pop, chanson, Eastern European\nfolk-pop, chanson, musette\nfolk-pop, children's music, Latin funk\nfolk-pop, chiptune rock\nfolk-pop, chiptune, Central Asian\nfolk-pop, chiptune, Dutch\nfolk-pop, chiptune, Middle Eastern\nfolk-pop, chiptune, Southeast Asian\nfolk-pop, chiptune, electronic\nfolk-pop, chiptune, electronic dance\nfolk-pop, cinematic pop, C-pop\nfolk-pop, cinematic rock\nfolk-pop, cinematic, Azerbaijani\nfolk-pop, cinematic, Balkan folk\nfolk-pop, cinematic, C-pop\nfolk-pop, cinematic, Central Asian\nfolk-pop, cinematic, Chinese\nfolk-pop, cinematic, Chinese folk\nfolk-pop, cinematic, Chinese opera\nfolk-pop, cinematic, Chinese-style\nfolk-pop, cinematic, Christmas\nfolk-pop, cinematic, East Asian\nfolk-pop, cinematic, Eastern European\nfolk-pop, cinematic, Indian classical\nfolk-pop, cinematic, Indian fusion\nfolk-pop, cinematic, Marathi\nfolk-pop, cinematic, Middle Eastern\nfolk-pop, cinematic, South Asian\nfolk-pop, cinematic, South Indian\nfolk-pop, cinematic, Turkish arabesque\nfolk-pop, cinematic, Uzbek\nfolk-pop, cinematic, ambient\nfolk-pop, cinematic, breakbeat\nfolk-pop, cinematic, chiptune\nfolk-pop, cinematic, dance\nfolk-pop, cinematic, dance-pop\nfolk-pop, cinematic, electronic\nfolk-pop, cinematic, musical theater\nfolk-pop, cinematic, orchestral\nfolk-pop, cinematic, pop-rock\nfolk-pop, cinematic, rock\nfolk-pop, cinematic, traditional Chinese\nfolk-pop, cinematic, world fusion\nfolk-pop, cinematic, world music\nfolk-pop, classic rock\nfolk-pop, classical Indian, qawwali\nfolk-pop, classical crossover, estrada\nfolk-pop, country, polka\nfolk-pop, country, schlager\nfolk-pop, country-rock, Dutch\nfolk-pop, country-western, Portuguese\nfolk-pop, dance, hip-hop\nfolk-pop, dance-pop, Latin\nfolk-pop, dance-pop, chalga\nfolk-pop, devotional, Nepali\nfolk-pop, digital cumbia, Nepali\nfolk-pop, duduk, Central Asian\nfolk-pop, electronic dance, Central Asian\nfolk-pop, electronic dance, hip-hop\nfolk-pop, electronic fusion\nfolk-pop, electronic, Anatolian\nfolk-pop, electronic, Central Asian\nfolk-pop, electronic, Indian\nfolk-pop, electronic, Indian classical\nfolk-pop, electronic, Middle Eastern\nfolk-pop, electronic, South Asian\nfolk-pop, electronic, Southeast Asian\nfolk-pop, electronic, cinematic\nfolk-pop, electronic, classical\nfolk-pop, electronic, dance\nfolk-pop, electronic, dance-pop\nfolk-pop, electronic, hip-hop\nfolk-pop, electronic, oud\nfolk-pop, epic, patriotic\nfolk-pop, estrada\nfolk-pop, estrada, Eastern European\nfolk-pop, estrada, cinematic\nfolk-pop, estrada, electronic\nfolk-pop, estrada, polka\nfolk-pop, estrada, satirical\nfolk-pop, estrada, synth-pop\nfolk-pop, ethereal, South Asian\nfolk-pop, eurodance\nfolk-pop, flamenco, Latin\nfolk-pop, flamenco, chanson\nfolk-pop, folk-rock, hard rock\nfolk-pop, funk, rap\nfolk-pop, funk-rock, Mandarin ballad\nfolk-pop, future bass\nfolk-pop, ghazal\nfolk-pop, ghazal, Indian classical\nfolk-pop, ghazal, traditional Indian\nfolk-pop, glitch-hop\nfolk-pop, gospel-pop, Hebrew pop\nfolk-pop, gypsy jazz, Eastern European\nfolk-pop, gypsy punk, theatrical pop\nfolk-pop, gypsy-jazz\nfolk-pop, gypsy-punk, Balkan\nfolk-pop, hard rock\nfolk-pop, hardstyle\nfolk-pop, hip-hop, pop-rock\nfolk-pop, hyperpop, dance-pop\nfolk-pop, indie rock\nfolk-pop, klezmer, Eastern European\nfolk-pop, klezmer, European folk\nfolk-pop, klezmer, Russian\nfolk-pop, klezmer, classical\nfolk-pop, klezmer, polka\nfolk-pop, klezmer, polka-rock\nfolk-pop, klezmer, theatrical\nfolk-pop, lo-fi, Italian folk\nfolk-pop, lo-fi, electronic\nfolk-pop, lo-fi, hip-hop\nfolk-pop, melancholic, rock\nfolk-pop, melbourne bounce\nfolk-pop, musical theater, polka\nfolk-pop, mystical, Middle Eastern\nfolk-pop, nasyid, cinematic\nfolk-pop, new age\nfolk-pop, pahari, upbeat\nfolk-pop, patriotic, orchestral\nfolk-pop, piano ballad, Latin pop, rap\nfolk-pop, polka, 80s synth-pop\nfolk-pop, polka, Eastern European\nfolk-pop, polka, West African pop\nfolk-pop, polka, carnival\nfolk-pop, polka, electronic\nfolk-pop, polka, theatrical\nfolk-pop, pop-punk\nfolk-pop, pop-punk, alternative rock\nfolk-pop, pop-punk, theatrical\nfolk-pop, pop-rock\nfolk-pop, pop-rock, C-pop\nfolk-pop, pop-rock, Chinese classical\nfolk-pop, pop-rock, J-rock\nfolk-pop, pop-rock, Latin-jazz fusion\nfolk-pop, pop-rock, South Asian\nfolk-pop, pop-rock, alternative rock\nfolk-pop, pop-rock, cinematic\nfolk-pop, pop-rock, electronic\nfolk-pop, pop-rock, hard rock\nfolk-pop, pop-rock, hardstyle\nfolk-pop, pop-rock, hip-hop\nfolk-pop, pop-rock, rock\nfolk-pop, pop-rock, stadium rock\nfolk-pop, pop-rock, symphonic rock\nfolk-pop, pop-rock, traditional Chinese\nfolk-pop, post-rock, C-pop\nfolk-pop, power rock, cinematic\nfolk-pop, progressive house\nfolk-pop, progressive house, EDM\nfolk-pop, progressive house, big room\nfolk-pop, progressive house, cinematic\nfolk-pop, progressive house, stadium EDM\nfolk-pop, psychedelic rock\nfolk-pop, psychedelic rock, Latin rock\nfolk-pop, psychedelic rock, cinematic\nfolk-pop, qawwali, south asian\nfolk-pop, reggaeton, ambient\nfolk-pop, retro electronic, South Asian\nfolk-pop, retro, Eastern European\nfolk-pop, retro, chiptune\nfolk-pop, retro, estrada\nfolk-pop, retro-digital, South Asian\nfolk-pop, rock and roll, children's music\nfolk-pop, rock, C-pop\nfolk-pop, rock, cinematic\nfolk-pop, rock, microtonal\nfolk-pop, rockabilly, country\nfolk-pop, schlager, Danish\nfolk-pop, schlager, Dutch\nfolk-pop, schlager, Eastern European\nfolk-pop, schlager, European\nfolk-pop, schlager, Swedish\nfolk-pop, schlager, danish\nfolk-pop, schlager, danseband\nfolk-pop, schlager, polka\nfolk-pop, sea shanty, Celtic\nfolk-pop, sea shanty, schlager\nfolk-pop, spiritual, world music\nfolk-pop, symphonic rock, Chinese hip-hop\nfolk-pop, synth-pop, Central Asian\nfolk-pop, synth-pop, cinematic\nfolk-pop, synth-pop, rock\nfolk-pop, theatrical, Eastern European\nfolk-pop, theatrical, cabaret\nfolk-pop, theatrical, cinematic\nfolk-pop, theatrical, musical theater\nfolk-pop, theatrical, video game soundtrack\nfolk-pop, theatrical, waltz\nfolk-pop, traditional Chinese\nfolk-pop, traditional Mongolian, cinematic\nfolk-pop, traditional, cinematic\nfolk-pop, trap, EDM\nfolk-pop, trap, Sinhala hip-hop\nfolk-pop, world music, C-pop\nfolk-pop, world music, cinematic\nfolk-pop, world music, gypsy jazz\nfolk-pop, world music, new-age\nfolk-pop, world music, spiritual\nfolk-pop, world music, worship\nfolk-pop, worldbeat, Latin\nfolk-pop, worldbeat, traditional Vietnamese\nfolk-punk\nfolk-punk Celtic punk\nfolk-punk acoustic rock\nfolk-punk alternative rock\nfolk-punk bluegrass\nfolk-punk bluegrass rock\nfolk-punk brass\nfolk-punk cabaret\nfolk-punk celtic punk\nfolk-punk chiptune\nfolk-punk cinematic\nfolk-punk comedy rock\nfolk-punk country-rock\nfolk-punk cumbia\nfolk-punk cumbia ska\nfolk-punk emo\nfolk-punk emo-folk\nfolk-punk emo-rap\nfolk-punk emo-rock\nfolk-punk flamenco\nfolk-punk garage punk\nfolk-punk garage rock\nfolk-punk gipsy-punk\nfolk-punk gypsy jazz\nfolk-punk gypsy punk\nfolk-punk gypsy punk balkan folk\nfolk-punk gypsy-folk\nfolk-punk gypsy-jazz\nfolk-punk gypsy-punk\nfolk-punk gypsy-punk bluegrass\nfolk-punk gypsy-punk blues-rock\nfolk-punk gypsy-punk theatrical\nfolk-punk hard rock\nfolk-punk hardcore punk\nfolk-punk heartland rock\nfolk-punk indie rock\nfolk-punk klezmer\nfolk-punk melodic metal\nfolk-punk metal\nfolk-punk metalcore\nfolk-punk pirate metal\nfolk-punk pirate rock\nfolk-punk pirate-metal\nfolk-punk pirate-rock\nfolk-punk political punk rock\nfolk-punk polka\nfolk-punk polka rock\nfolk-punk polka-punk\nfolk-punk polka-rock\nfolk-punk pop-punk\nfolk-punk post-hardcore\nfolk-punk power metal\nfolk-punk power-pop\nfolk-punk protest\nfolk-punk protest rock\nfolk-punk protest-rock\nfolk-punk pub rock\nfolk-punk pub-rock\nfolk-punk rap-rock\nfolk-punk rock\nfolk-punk rumba\nfolk-punk sea shanty\nfolk-punk sea shanty rock\nfolk-punk sea-shanty\nfolk-punk ska\nfolk-punk ska-punk\nfolk-punk ska-punk electronicore\nfolk-punk skate punk\nfolk-punk speed metal\nfolk-punk speed-folk\nfolk-punk speedcore\nfolk-punk stadium rock\nfolk-punk surf rock\nfolk-punk symphonic rock\nfolk-punk synth-pop\nfolk-punk theatrical rock\nfolk-punk turbo-folk\nfolk-punk, Balkan punk\nfolk-punk, Balkan rock\nfolk-punk, Balkan rock, klezmer\nfolk-punk, Balkan, klezmer\nfolk-punk, Balkan-punk, world fusion\nfolk-punk, Celtic punk\nfolk-punk, Celtic punk, drum and bass\nfolk-punk, Celtic punk, punk\nfolk-punk, Celtic punk, punk rock\nfolk-punk, Celtic punk, rock\nfolk-punk, Celtic rock, high-energy\nfolk-punk, Celtic, pub rock\nfolk-punk, Chinese folk, rock\nfolk-punk, Christian rock\nfolk-punk, Eastern European rock\nfolk-punk, French chanson, theatrical\nfolk-punk, German polka, theatrical rock\nfolk-punk, German punk rock\nfolk-punk, Italian folk, cinematic\nfolk-punk, Latin rock\nfolk-punk, Latin rock, gypsy-punk\nfolk-punk, Russian bard-rock\nfolk-punk, Russian folk, free-jazz\nfolk-punk, Spanish pub-rock, rock\nfolk-punk, a cappella, Hebrew\nfolk-punk, alt-country, cinematic folk\nfolk-punk, alt-country, indie rock\nfolk-punk, bluegrass, sea shanty\nfolk-punk, chiptune rock\nfolk-punk, cinematic, sea shanty\nfolk-punk, cinematic, tarantella\nfolk-punk, eurodance, rock\nfolk-punk, folk-metal, European folk\nfolk-punk, gypsy punk, polka-rock\nfolk-punk, hard rock\nfolk-punk, hardcore punk, Italian\nfolk-punk, hardstyle\nfolk-punk, jazz, electronic\nfolk-punk, klezmer, Russian folk\nfolk-punk, klezmer, eastern european\nfolk-punk, klezmer, flamenco\nfolk-punk, klezmer, theatrical rock\nfolk-punk, melodic hardcore\nfolk-punk, pirate metal\nfolk-punk, pirate metal, European folk\nfolk-punk, pirate metal, polka\nfolk-punk, pirate metal, sea shanty\nfolk-punk, polka rock, German\nfolk-punk, polka rock, punk rock\nfolk-punk, polka, German\nfolk-punk, polka, klezmer\nfolk-punk, polka, rock\nfolk-punk, polka, sea shanty\nfolk-punk, polka-punk, punk rock\nfolk-punk, polka-rock, Swedish folk\nfolk-punk, polka-rock, punk rock\nfolk-punk, power metal, French folk\nfolk-punk, power-pop, cinematic rock\nfolk-punk, pub rock, energetic\nfolk-punk, punk rock\nfolk-punk, punk rock, Celtic punk\nfolk-punk, sea shanty rock, high-energy\nfolk-punk, sea shanty, klezmer\nfolk-punk, sea shanty, theatrical rock\nfolk-punk, ska-punk, French chanson\nfolk-punk, ska-punk, Russian\nfolk-punk, skiffle, German rock\nfolk-punk, speed metal\nfolk-punk, surf-rock, Italian\nfolk-punk, theatrical cabaret\nfolk-punk, theatrical rock\nfolk-punk, theatrical, comedy\nfolk-punk, whimsical, cinematic\nfolk-rap\nfolk-rap alternative rock\nfolk-rap cumbia\nfolk-rap indie folk-rock\nfolk-rap lo-fi country\nfolk-rap, funk, lo-fi hip hop\nfolk-rap, hip-hop, rock\nfolk-reggae\nfolk-reggae world music\nfolk-rock\nfolk-rock Balkan\nfolk-rock Celtic\nfolk-rock Indian\nfolk-rock J-rock\nfolk-rock Latin\nfolk-rock Latin party\nfolk-rock Latin tropical\nfolk-rock Mandopop\nfolk-rock R&B hip-hop\nfolk-rock acoustic pop\nfolk-rock alt-country\nfolk-rock alt-rock\nfolk-rock alt-rock hard rock\nfolk-rock alt-rock post-rock\nfolk-rock alternative\nfolk-rock alternative electronic\nfolk-rock alternative hip-hop\nfolk-rock alternative metal\nfolk-rock alternative metalcore\nfolk-rock alternative rock\nfolk-rock alternative rock blues-rock\nfolk-rock alternative rock post-hardcore\nfolk-rock alternative rock post-rock\nfolk-rock alternative rock progressive metal\nfolk-rock alternative rock rap-rock\nfolk-rock americana\nfolk-rock arena rock\nfolk-rock arena rock blues-rock\nfolk-rock art-rock\nfolk-rock ballad\nfolk-rock bluegrass\nfolk-rock bluegrass country\nfolk-rock blues\nfolk-rock blues americana\nfolk-rock blues boogie-woogie\nfolk-rock blues country\nfolk-rock blues country-western\nfolk-rock blues jazz\nfolk-rock blues-rock\nfolk-rock boogie-woogie\nfolk-rock bossa nova\nfolk-rock brass\nfolk-rock cabaret\nfolk-rock cabaret polka\nfolk-rock cabaret-rock\nfolk-rock cajun\nfolk-rock chiptune\nfolk-rock christian rock\nfolk-rock cinematic\nfolk-rock cinematic rock\nfolk-rock classic rock\nfolk-rock classic rock hard rock\nfolk-rock country\nfolk-rock country Latin\nfolk-rock country americana\nfolk-rock country big band\nfolk-rock country bluegrass\nfolk-rock country blues\nfolk-rock country boeremusiek\nfolk-rock country boogie-woogie\nfolk-rock country celtic\nfolk-rock country gospel\nfolk-rock country hawaiian\nfolk-rock country hoedown\nfolk-rock country italian folk\nfolk-rock country jangle-pop\nfolk-rock country latin\nfolk-rock country polka\nfolk-rock country psychedelic\nfolk-rock country pub rock\nfolk-rock country pub-rock\nfolk-rock country rock\nfolk-rock country rockabilly\nfolk-rock country schlager\nfolk-rock country surf-rock\nfolk-rock country-pop\nfolk-rock country-rock\nfolk-rock country-rock heavy rock\nfolk-rock country-western\nfolk-rock cumbia\nfolk-rock cumbia accordion\nfolk-rock cumbia punk\nfolk-rock cumbia ska\nfolk-rock dance-pop\nfolk-rock dance-rock\nfolk-rock drum and bass\nfolk-rock electronic\nfolk-rock emo-pop\nfolk-rock epic\nfolk-rock exotica\nfolk-rock fado\nfolk-rock flamenco\nfolk-rock funk\nfolk-rock funk soul\nfolk-rock funk-rock\nfolk-rock funk-rock psychedelic rock\nfolk-rock fusion\nfolk-rock garage punk\nfolk-rock garage rock\nfolk-rock garage rock psychedelic rock\nfolk-rock glam rock\nfolk-rock gospel\nfolk-rock gospel americana\nfolk-rock gospel-rock\nfolk-rock grunge\nfolk-rock gypsy cabaret\nfolk-rock gypsy eastern european\nfolk-rock gypsy jazz\nfolk-rock gypsy jazz Eastern European\nfolk-rock gypsy manouche\nfolk-rock gypsy punk\nfolk-rock gypsy rock\nfolk-rock gypsy-folk\nfolk-rock gypsy-jazz\nfolk-rock gypsy-jazz blues-rock\nfolk-rock gypsy-jazz cabaret\nfolk-rock gypsy-punk\nfolk-rock hard rock\nfolk-rock hardstyle\nfolk-rock heartland rock\nfolk-rock heartland rock blues-rock\nfolk-rock heartland rock psychedelic\nfolk-rock hip hop\nfolk-rock hip-hop\nfolk-rock honky-tonk\nfolk-rock house\nfolk-rock indie\nfolk-rock indie psychedelic\nfolk-rock indie rock\nfolk-rock indie rock alt-rock\nfolk-rock indie rock blues-rock\nfolk-rock indie rock garage rock\nfolk-rock indie rock hard rock\nfolk-rock indie rock post-rock\nfolk-rock indie rock psychedelic rock\nfolk-rock indie rock punk\nfolk-rock indie rock punk rock\nfolk-rock indie rock shoegaze\nfolk-rock indie-rock\nfolk-rock italo-disco\nfolk-rock jangle-pop\nfolk-rock jazz fusion\nfolk-rock jazz-fusion\nfolk-rock klezmer\nfolk-rock klezmer middle eastern\nfolk-rock klezmer pub rock\nfolk-rock klezmer theatrical\nfolk-rock latin\nfolk-rock latin rock\nfolk-rock lo-fi hip-hop punk rock\nfolk-rock metal\nfolk-rock metalcore\nfolk-rock new-age\nfolk-rock noir\nfolk-rock noise-rock\nfolk-rock novelty\nfolk-rock nu-metal\nfolk-rock opera\nfolk-rock orchestral\nfolk-rock oud\nfolk-rock outlaw country\nfolk-rock pimba\nfolk-rock pirate\nfolk-rock pirate metal\nfolk-rock polka\nfolk-rock polka humppa\nfolk-rock pop\nfolk-rock pop-punk\nfolk-rock pop-rock\nfolk-rock pop-rock arena rock\nfolk-rock pop-rock hard rock\nfolk-rock pop-rock post-hardcore\nfolk-rock post-grunge\nfolk-rock post-hardcore\nfolk-rock post-punk noise-rock\nfolk-rock post-rock\nfolk-rock power ballad\nfolk-rock power metal\nfolk-rock power-pop\nfolk-rock progressive folk\nfolk-rock progressive hard rock\nfolk-rock progressive metal\nfolk-rock progressive rock\nfolk-rock protest\nfolk-rock psychedelic\nfolk-rock psychedelic hard rock\nfolk-rock psychedelic rock\nfolk-rock pub rock\nfolk-rock pub-rock\nfolk-rock pub-rock sea shanty\nfolk-rock punk\nfolk-rock punk experimental\nfolk-rock punk funk\nfolk-rock punk rock\nfolk-rock punk rock rap-rock\nfolk-rock punk rock thrash metal\nfolk-rock rap-rock\nfolk-rock reggae\nfolk-rock reggae ska\nfolk-rock reggae-rock\nfolk-rock retro\nfolk-rock rockabilly\nfolk-rock rockabilly cabaret\nfolk-rock rockabilly surf-rock\nfolk-rock roots-rock\nfolk-rock rumba\nfolk-rock rumba electronica\nfolk-rock satire\nfolk-rock satirical\nfolk-rock schlager\nfolk-rock sea shanty\nfolk-rock sea-shanty\nfolk-rock sertanejo\nfolk-rock shoegaze\nfolk-rock ska\nfolk-rock ska reggae\nfolk-rock ska-punk\nfolk-rock ska-punk big band\nfolk-rock ska-punk punk\nfolk-rock soft rock arena rock\nfolk-rock soul\nfolk-rock southern rock\nfolk-rock stadium rock\nfolk-rock surf-rock\nfolk-rock symphonic metal\nfolk-rock symphonic rock\nfolk-rock synth-pop\nfolk-rock tango\nfolk-rock tango Balkan\nfolk-rock tango balkan\nfolk-rock tango blues\nfolk-rock tango cumbia\nfolk-rock tango oud\nfolk-rock tango-rock hard rock\nfolk-rock tarantella\nfolk-rock theatrical\nfolk-rock thrash metal\nfolk-rock tropical\nfolk-rock turbo-folk\nfolk-rock world\nfolk-rock world fusion\nfolk-rock world music\nfolk-rock worldbeat\nfolk-rock worship\nfolk-rock zouk\nfolk-rock, Americana\nfolk-rock, Americana, Celtic\nfolk-rock, Americana, Western\nfolk-rock, Americana, bluegrass\nfolk-rock, Americana, blues\nfolk-rock, Americana, country\nfolk-rock, Americana, country-folk\nfolk-rock, Americana, country-western\nfolk-rock, Americana, energetic\nfolk-rock, Americana, heartland rock\nfolk-rock, Americana, hoedown\nfolk-rock, Americana, lo-fi\nfolk-rock, Americana, narrative rock\nfolk-rock, Americana, outlaw country\nfolk-rock, Americana, protest\nfolk-rock, Americana, pub-rock\nfolk-rock, Americana, quirky\nfolk-rock, Americana, roots rock\nfolk-rock, Americana, soulful\nfolk-rock, Americana, swamp rock\nfolk-rock, Americana, upbeat\nfolk-rock, Anatolian folk, Russian chanson\nfolk-rock, Anatolian folk, melancholic\nfolk-rock, Anatolian rock\nfolk-rock, Anatolian, Middle Eastern\nfolk-rock, Anatolian, energetic\nfolk-rock, Anatolian, epic\nfolk-rock, Anatolian, oud\nfolk-rock, Andean, world music\nfolk-rock, Balkan brass\nfolk-rock, Balkan folk, choral\nfolk-rock, Balkan folk, theatrical rock\nfolk-rock, Balkan rock\nfolk-rock, Balkan, Eastern European\nfolk-rock, Balkan, Klezmer\nfolk-rock, Balkan, Middle Eastern\nfolk-rock, Balkan, cabaret\nfolk-rock, Balkan, energetic\nfolk-rock, Balkan, gypsy\nfolk-rock, Balkan, upbeat\nfolk-rock, Bollywood, rock\nfolk-rock, Brazilian, punk\nfolk-rock, C-pop, cinematic\nfolk-rock, Celtic punk\nfolk-rock, Celtic rock\nfolk-rock, Celtic rock, classic rock\nfolk-rock, Celtic, anthemic\nfolk-rock, Celtic, bardic\nfolk-rock, Celtic, bluegrass\nfolk-rock, Celtic, energetic\nfolk-rock, Celtic, epic\nfolk-rock, Celtic, pub rock\nfolk-rock, Celtic, pub-rock\nfolk-rock, Celtic, rock\nfolk-rock, Celtic, sea shanty\nfolk-rock, Celtic, show tune\nfolk-rock, Celtic, sokkie\nfolk-rock, Celtic, upbeat\nfolk-rock, Celtic, uplifting\nfolk-rock, Central Asian, improvisational\nfolk-rock, Chinese folk, ambient\nfolk-rock, Chinese folk, cinematic\nfolk-rock, Chinese folk, live\nfolk-rock, Chinese folk, melancholic\nfolk-rock, Chinese folk, melodic rock\nfolk-rock, Chinese folk-rock, rock\nfolk-rock, Chinese metal, experimental\nfolk-rock, Chinese opera, cinematic\nfolk-rock, Chinese opera, rock\nfolk-rock, Chinese opera, theatrical\nfolk-rock, Chinese style, cinematic\nfolk-rock, Chinese traditional, cinematic\nfolk-rock, Chinese traditional, rock\nfolk-rock, Chinese, blues-rock\nfolk-rock, Chinese, cinematic\nfolk-rock, Chinese, energetic\nfolk-rock, Chinese, epic\nfolk-rock, Chinese, rock\nfolk-rock, Chinese, theatrical\nfolk-rock, Christian rock, blues-rock\nfolk-rock, Christian rock, world music\nfolk-rock, Christmas, Latin\nfolk-rock, Christmas, theatrical\nfolk-rock, EDM\nfolk-rock, EDM, cinematic\nfolk-rock, EDM, future bass\nfolk-rock, East Asian, instrumental\nfolk-rock, Eastern European, Anatolian rock\nfolk-rock, Eastern European, big band\nfolk-rock, Eastern European, chanson\nfolk-rock, Eastern European, new wave\nfolk-rock, Eastern European, theatrical\nfolk-rock, Eastern European, theatrical rock\nfolk-rock, German pub rock\nfolk-rock, Indian classical, cinematic\nfolk-rock, Indian classical, rock\nfolk-rock, Indian classical, spiritual\nfolk-rock, Indian classical, uplifting\nfolk-rock, Indian filmi, indie folk\nfolk-rock, Indian folk, cinematic\nfolk-rock, Indian fusion, cinematic\nfolk-rock, Indian fusion, rock\nfolk-rock, Israeli rock\nfolk-rock, Italian rock, world music\nfolk-rock, Italian singer-songwriter, gypsy jazz\nfolk-rock, Italian, theatrical\nfolk-rock, J-rock\nfolk-rock, Javanese, kalimba\nfolk-rock, Korean trot\nfolk-rock, Latin folk, flamenco\nfolk-rock, Latin folk, polka\nfolk-rock, Latin folk, theatrical\nfolk-rock, Latin pop\nfolk-rock, Latin pop, Italian folk\nfolk-rock, Latin pop, cinematic\nfolk-rock, Latin rock\nfolk-rock, Latin rock, ambient\nfolk-rock, Latin rock, blues\nfolk-rock, Latin rock, blues-rock\nfolk-rock, Latin rock, pub rock\nfolk-rock, Latin, Basque\nfolk-rock, Latin, Dutch\nfolk-rock, Latin, Hawaiian\nfolk-rock, Latin, Mandarin rock\nfolk-rock, Latin, Polish\nfolk-rock, Latin, anthemic\nfolk-rock, Latin, blues\nfolk-rock, Latin, boogie-woogie\nfolk-rock, Latin, cumbia\nfolk-rock, Latin, energetic\nfolk-rock, Latin, flamenco\nfolk-rock, Latin, gypsy-jazz\nfolk-rock, Latin, hard rock\nfolk-rock, Latin, live\nfolk-rock, Latin, polka\nfolk-rock, Latin, rumba\nfolk-rock, Latin, sea shanty\nfolk-rock, Latin, ska\nfolk-rock, Latin, upbeat\nfolk-rock, Latin, uplifting\nfolk-rock, Latin, world music\nfolk-rock, Latin-rock, acoustic\nfolk-rock, Luk Thung, Southeast Asian\nfolk-rock, Mandopop, Americana\nfolk-rock, Mediterranean, Balkan\nfolk-rock, Mediterranean, Latin\nfolk-rock, Middle Eastern fusion\nfolk-rock, Middle Eastern, Anatolian\nfolk-rock, Middle Eastern, Balkan\nfolk-rock, Middle Eastern, Hebrew\nfolk-rock, Middle Eastern, Hebrew vocal\nfolk-rock, Middle Eastern, Hungarian\nfolk-rock, Middle Eastern, Klezmer\nfolk-rock, Middle Eastern, anthemic\nfolk-rock, Middle Eastern, celebratory\nfolk-rock, Middle Eastern, choral\nfolk-rock, Middle Eastern, cinematic\nfolk-rock, Middle Eastern, epic\nfolk-rock, Middle Eastern, flamenco\nfolk-rock, Middle Eastern, fusion\nfolk-rock, Middle Eastern, hip-hop\nfolk-rock, Middle Eastern, live\nfolk-rock, Middle Eastern, oud\nfolk-rock, Middle Eastern, progressive rock\nfolk-rock, Middle Eastern, punk\nfolk-rock, Middle Eastern, raw\nfolk-rock, Middle Eastern, rock\nfolk-rock, Middle Eastern, traditional\nfolk-rock, Mongolian long-song\nfolk-rock, Mongolian throat singing, Chinese folk\nfolk-rock, Mor Lam, Luk Thung\nfolk-rock, Mor Lam, Southeast Asian\nfolk-rock, Nederpop\nfolk-rock, Neue Deutsche Welle\nfolk-rock, North African, Arabic\nfolk-rock, Persian, cinematic\nfolk-rock, Persian, melancholic\nfolk-rock, Punjabi, cinematic\nfolk-rock, Quebecois, energetic\nfolk-rock, Russian bard-rock\nfolk-rock, Russian rock\nfolk-rock, Russian rock, blues-rock\nfolk-rock, Russian rock, hard rock\nfolk-rock, Russian, flamenco\nfolk-rock, Russian, rock\nfolk-rock, Russian, surf-rock\nfolk-rock, Russian, theatrical\nfolk-rock, Schlager\nfolk-rock, Schlager, German\nfolk-rock, Schlager, polka\nfolk-rock, South Asian, energetic\nfolk-rock, South Asian, live\nfolk-rock, South Asian, upbeat\nfolk-rock, Southeast Asian, energetic\nfolk-rock, Spanish pop, indie rock\nfolk-rock, Tibetan music\nfolk-rock, Turkish, improvisational\nfolk-rock, alt-country, Americana\nfolk-rock, alt-country, rockabilly\nfolk-rock, alt-rock\nfolk-rock, alt-rock, blues-rock\nfolk-rock, alt-rock, dream-pop\nfolk-rock, alt-rock, hard rock\nfolk-rock, alt-rock, noise rock\nfolk-rock, alternative metal\nfolk-rock, alternative rock\nfolk-rock, alternative rock, French indie\nfolk-rock, alternative rock, Hebrew vocal\nfolk-rock, alternative rock, grunge\nfolk-rock, alternative rock, hip-hop\nfolk-rock, alternative rock, metal\nfolk-rock, alternative rock, post-rock\nfolk-rock, ambient, Indian devotional\nfolk-rock, americana, celtic\nfolk-rock, americana, gospel\nfolk-rock, americana, rock\nfolk-rock, anthemic rock, hard rock\nfolk-rock, arena rock, 80s rock\nfolk-rock, arena rock, blues\nfolk-rock, arena rock, blues-rock\nfolk-rock, arena rock, power ballad\nfolk-rock, arena rock, synth rock\nfolk-rock, bardcore, whimsical\nfolk-rock, baroque pop, Italian tarantella\nfolk-rock, baroque pop, hard rock\nfolk-rock, big band jazz, Italian\nfolk-rock, big band, Latin\nfolk-rock, big band, klezmer\nfolk-rock, big band, theatrical\nfolk-rock, bluegrass, Americana\nfolk-rock, bluegrass, country-rock\nfolk-rock, bluegrass, sea shanty\nfolk-rock, blues, Latin\nfolk-rock, blues, Taiwanese Hokkien\nfolk-rock, blues, boogie-woogie\nfolk-rock, blues-rock, Indian fusion\nfolk-rock, blues-rock, cinematic\nfolk-rock, blues-rock, classic rock\nfolk-rock, blues-rock, hard rock\nfolk-rock, boeremusiek, country\nfolk-rock, boeremusiek, pub-rock\nfolk-rock, boeremusiek, sokkie\nfolk-rock, boogie-rock\nfolk-rock, boogie-woogie, swing\nfolk-rock, bossa nova\nfolk-rock, brass band\nfolk-rock, brostep\nfolk-rock, cabaret, Balkan\nfolk-rock, cabaret, Spanish\nfolk-rock, cabaret, klezmer\nfolk-rock, cabaret, theatrical\nfolk-rock, celtic rock\nfolk-rock, chanson, European\nfolk-rock, chanson, cinematic\nfolk-rock, chanson, musette\nfolk-rock, chanson, theatrical\nfolk-rock, cinematic rock, Chinese folk\nfolk-rock, cinematic rock, blues-rock\nfolk-rock, cinematic rock, hard rock\nfolk-rock, cinematic rock, progressive rock\nfolk-rock, cinematic world music\nfolk-rock, cinematic, Anatolian\nfolk-rock, cinematic, Balkan folk\nfolk-rock, cinematic, Bengali rock\nfolk-rock, cinematic, C-pop\nfolk-rock, cinematic, Celtic\nfolk-rock, cinematic, Chinese\nfolk-rock, cinematic, Chinese folk\nfolk-rock, cinematic, Chinese traditional\nfolk-rock, cinematic, Eastern European\nfolk-rock, cinematic, Eastern-influenced\nfolk-rock, cinematic, Hebrew\nfolk-rock, cinematic, Indian classical\nfolk-rock, cinematic, Indian fusion\nfolk-rock, cinematic, Italian\nfolk-rock, cinematic, Javanese\nfolk-rock, cinematic, Middle Eastern\nfolk-rock, cinematic, Mongolian\nfolk-rock, cinematic, Mongolian style\nfolk-rock, cinematic, Mongolian throat-singing\nfolk-rock, cinematic, Mongolian traditional\nfolk-rock, cinematic, Russian bard\nfolk-rock, cinematic, Tamil\nfolk-rock, cinematic, Turkish\nfolk-rock, cinematic, Turkish folk\nfolk-rock, cinematic, Vietnamese\nfolk-rock, cinematic, Yiddish\nfolk-rock, cinematic, ambient\nfolk-rock, cinematic, ancient style\nfolk-rock, cinematic, epic\nfolk-rock, cinematic, klezmer\nfolk-rock, cinematic, metal\nfolk-rock, cinematic, operatic\nfolk-rock, cinematic, orchestral\nfolk-rock, cinematic, oud\nfolk-rock, cinematic, post-rock\nfolk-rock, cinematic, progressive rock\nfolk-rock, cinematic, symphonic rock\nfolk-rock, cinematic, tango\nfolk-rock, cinematic, traditional Chinese\nfolk-rock, cinematic, traditional Thai\nfolk-rock, cinematic, trip-hop\nfolk-rock, cinematic, world fusion\nfolk-rock, cinematic, world music\nfolk-rock, circus, tarantella\nfolk-rock, classic rock\nfolk-rock, classic rock, ambient\nfolk-rock, classic rock, ballad\nfolk-rock, classic rock, blues\nfolk-rock, classic rock, blues rock\nfolk-rock, classic rock, blues-rock\nfolk-rock, classic rock, hard rock\nfolk-rock, classic rock, psychedelic rock\nfolk-rock, classical guitar, operatic\nfolk-rock, conscious hip-hop, indie pop\nfolk-rock, country, Americana\nfolk-rock, country, Dutch\nfolk-rock, country, Italian\nfolk-rock, country, Nederpop\nfolk-rock, country, Swedish\nfolk-rock, country, blues\nfolk-rock, country, gospel\nfolk-rock, country, jangle-pop\nfolk-rock, country, levenslied\nfolk-rock, country, polka\nfolk-rock, country, pub-rock\nfolk-rock, country, rockabilly\nfolk-rock, country, surf-rock\nfolk-rock, country-rock, Americana\nfolk-rock, country-rock, polka\nfolk-rock, country-rock, satirical\nfolk-rock, country-western, Italian\nfolk-rock, cumbia, Latin American\nfolk-rock, dance-rock, Russian\nfolk-rock, disco polo\nfolk-rock, doom metal\nfolk-rock, drum and bass, neurofunk\nfolk-rock, electro-rock, EDM\nfolk-rock, electronic dance, high-energy\nfolk-rock, electronic, Middle Eastern\nfolk-rock, electronic, dubstep\nfolk-rock, electronic, hip-hop\nfolk-rock, epic metal, medieval\nfolk-rock, epic, ancient style\nfolk-rock, epic, heavy metal\nfolk-rock, erhu, ancient style\nfolk-rock, festive anthem\nfolk-rock, flamenco, Italian folk\nfolk-rock, flamenco, Middle Eastern\nfolk-rock, flamenco, Russian bard\nfolk-rock, flamenco, gypsy jazz\nfolk-rock, folk-punk\nfolk-rock, forró, cinematic\nfolk-rock, funk rock\nfolk-rock, garage rock, proto-punk\nfolk-rock, glam rock, cinematic\nfolk-rock, gospel, Americana\nfolk-rock, gospel, blues\nfolk-rock, grunge, alternative rock\nfolk-rock, gypsy punk, Romanian\nfolk-rock, gypsy punk, Russian\nfolk-rock, gypsy punk, klezmer\nfolk-rock, gypsy-jazz, C-pop\nfolk-rock, gypsy-jazz, klezmer\nfolk-rock, gypsy-jazz, worship\nfolk-rock, gypsy-punk\nfolk-rock, gypsy-punk, Balkan\nfolk-rock, gypsy-punk, theatrical rock\nfolk-rock, gypsy-punk, world fusion\nfolk-rock, hard rock\nfolk-rock, hard rock, 80s arena rock\nfolk-rock, hard rock, C-pop\nfolk-rock, hard rock, Cantopop\nfolk-rock, hard rock, Chinese\nfolk-rock, hard rock, Chinese rock\nfolk-rock, hard rock, Hungarian rock\nfolk-rock, hard rock, Italian\nfolk-rock, hard rock, Latin\nfolk-rock, hard rock, Middle Eastern\nfolk-rock, hard rock, Nepali\nfolk-rock, hard rock, Southeast Asian\nfolk-rock, hard rock, Spanish rock\nfolk-rock, hard rock, Vietnamese traditional\nfolk-rock, hard rock, alternative metal\nfolk-rock, hard rock, ambient\nfolk-rock, hard rock, blues rock\nfolk-rock, hard rock, blues-rock\nfolk-rock, hard rock, cinematic\nfolk-rock, hard rock, experimental\nfolk-rock, hard rock, funk\nfolk-rock, hard rock, glam metal\nfolk-rock, hard rock, heavy metal\nfolk-rock, hard rock, metal\nfolk-rock, hard rock, metalcore\nfolk-rock, hard rock, noise-rock\nfolk-rock, hard rock, pop-funk\nfolk-rock, hard rock, post-hardcore\nfolk-rock, hard rock, post-rock\nfolk-rock, hard rock, progressive\nfolk-rock, hard rock, progressive rock\nfolk-rock, hard rock, psychedelic\nfolk-rock, hard rock, punk\nfolk-rock, hard rock, rap\nfolk-rock, hard rock, rap-rock\nfolk-rock, hard rock, rock-opera\nfolk-rock, hard rock, shred guitar\nfolk-rock, hard rock, spiritual\nfolk-rock, hard rock, symphonic rock\nfolk-rock, hard rock, synth-pop\nfolk-rock, hard rock, theatrical\nfolk-rock, hard rock, theatrical metal\nfolk-rock, hard rock, theatrical rock\nfolk-rock, hard rock, thrash metal\nfolk-rock, hardbass, cinematic\nfolk-rock, hardstyle, electronic\nfolk-rock, heartland rock, Americana\nfolk-rock, heavy metal\nfolk-rock, heavy metal, Hungarian folk\nfolk-rock, heavy metal, Indian classical\nfolk-rock, heavy metal, cinematic\nfolk-rock, heavy metal, power metal\nfolk-rock, hip-hop, Turkish pop\nfolk-rock, hip-hop, spiritual\nfolk-rock, holiday, upbeat\nfolk-rock, indie rock, cinematic rock\nfolk-rock, indie rock, emo\nfolk-rock, indie rock, post-punk\nfolk-rock, industrial rock\nfolk-rock, jazz, Balkan folk\nfolk-rock, jazz, French chanson\nfolk-rock, jazz, blues-rock\nfolk-rock, klezmer, Balkan brass\nfolk-rock, klezmer, Hebrew rock\nfolk-rock, klezmer, Russian\nfolk-rock, klezmer, balkan\nfolk-rock, klezmer, cinematic rock\nfolk-rock, klezmer, eastern european\nfolk-rock, klezmer, gypsy punk\nfolk-rock, klezmer, hard rock\nfolk-rock, klezmer, hip-hop\nfolk-rock, klezmer, operatic\nfolk-rock, klezmer, polka\nfolk-rock, klezmer, rock\nfolk-rock, klezmer, theatrical\nfolk-rock, klezmer, world music\nfolk-rock, melbourne bounce\nfolk-rock, melodic metal\nfolk-rock, metal, Mandarin rock\nfolk-rock, metal, cinematic\nfolk-rock, metalcore, indie\nfolk-rock, metalcore, oud\nfolk-rock, modern country\nfolk-rock, musette, tango\nfolk-rock, musical theater\nfolk-rock, ney, Anatolian\nfolk-rock, noise-rock\nfolk-rock, novelty, Dutch\nfolk-rock, nu-metal, C-pop\nfolk-rock, nu-metal, atmospheric\nfolk-rock, operatic, Latin\nfolk-rock, operatic, big band\nfolk-rock, oud, Persian\nfolk-rock, oud, traditional\nfolk-rock, patriotic, Chinese\nfolk-rock, pirate folk, Spanish-style\nfolk-rock, pirate metal\nfolk-rock, pirate, Schlager\nfolk-rock, pirate-folk, Spanish folk\nfolk-rock, polka\nfolk-rock, polka, Czech\nfolk-rock, polka, Eastern European\nfolk-rock, polka, German\nfolk-rock, polka, German folk\nfolk-rock, polka, Russian folk\nfolk-rock, polka, Schlager\nfolk-rock, polka, accordion\nfolk-rock, polka, bluegrass\nfolk-rock, polka, blues-rock\nfolk-rock, polka, brass\nfolk-rock, polka, cinematic\nfolk-rock, polka, drinking song\nfolk-rock, polka, energetic\nfolk-rock, polka, klezmer\nfolk-rock, polka, levenslied\nfolk-rock, polka, pub rock\nfolk-rock, polka, schlager\nfolk-rock, polka, ska\nfolk-rock, polka, surf rock\nfolk-rock, polka, theatrical\nfolk-rock, polka-punk, ambient\nfolk-rock, polka-rock\nfolk-rock, pop-punk, C-pop\nfolk-rock, pop-rock\nfolk-rock, pop-rock, German rock\nfolk-rock, pop-rock, Southeast Asian fusion\nfolk-rock, pop-rock, blues\nfolk-rock, pop-rock, epic rock\nfolk-rock, pop-rock, hard rock\nfolk-rock, post-hardcore\nfolk-rock, post-hardcore, metalcore\nfolk-rock, post-hardcore, spoken word\nfolk-rock, post-punk, Russian bard\nfolk-rock, post-rock, Chinese folk\nfolk-rock, post-rock, Chinese rock\nfolk-rock, post-rock, indie\nfolk-rock, post-rock, shoegaze\nfolk-rock, power ballad, Southeast Asian\nfolk-rock, power ballad, epic\nfolk-rock, power ballad, hard rock\nfolk-rock, power ballad, heavy metal\nfolk-rock, power ballad, symphonic rock\nfolk-rock, power metal\nfolk-rock, power metal, cinematic\nfolk-rock, power-rock, melodic metalcore\nfolk-rock, progressive house, EDM\nfolk-rock, progressive house, big room\nfolk-rock, progressive metal\nfolk-rock, progressive rock, European folk\nfolk-rock, progressive rock, Mediterranean\nfolk-rock, progressive rock, Turkish folk\nfolk-rock, progressive rock, symphonic folk\nfolk-rock, progressive rock, theatrical\nfolk-rock, psychedelic blues-rock\nfolk-rock, psychedelic funk, rock\nfolk-rock, psychedelic rock\nfolk-rock, psychedelic rock, blues-rock\nfolk-rock, psychedelic rock, cinematic\nfolk-rock, psychedelic rock, classic rock\nfolk-rock, psychedelic rock, noise-rock\nfolk-rock, psychedelic rock, orchestral rock\nfolk-rock, psychedelic rock, rockabilly\nfolk-rock, psychedelic, mystical\nfolk-rock, pub rock, Dutch rock\nfolk-rock, pub rock, sea shanty\nfolk-rock, pub-punk\nfolk-rock, pub-rock, Celtic\nfolk-rock, pub-rock, European\nfolk-rock, pub-rock, Schlager\nfolk-rock, pub-rock, blues-rock\nfolk-rock, pub-rock, skiffle\nfolk-rock, punk rock, Italian\nfolk-rock, punk rock, cinematic\nfolk-rock, punk rock, soul\nfolk-rock, punk, free-jazz\nfolk-rock, punk-rock\nfolk-rock, punk-rock, Chinese folk\nfolk-rock, punk-rock, Eastern European folk\nfolk-rock, punk-rock, experimental\nfolk-rock, ranchera, surf-rock\nfolk-rock, rock and roll\nfolk-rock, rock and roll, cinematic\nfolk-rock, rock, Italian pop\nfolk-rock, rock, Nepali\nfolk-rock, rockabilly, French chanson\nfolk-rock, rockabilly, Hebrew folk\nfolk-rock, roots rock, Americana\nfolk-rock, satirical, art-rock\nfolk-rock, schlager\nfolk-rock, schlager, German\nfolk-rock, schlager, Swedish\nfolk-rock, schlager, german\nfolk-rock, schlager, pub rock\nfolk-rock, schlager, sea shanty\nfolk-rock, sea shanty, Balkan folk\nfolk-rock, sea shanty, Celtic\nfolk-rock, sea shanty, Latin\nfolk-rock, sea shanty, bluegrass\nfolk-rock, sea shanty, cabaret\nfolk-rock, sea shanty, cinematic\nfolk-rock, sea shanty, live anthem\nfolk-rock, sea shanty, pub rock\nfolk-rock, sea shanty, satirical\nfolk-rock, sea shanty, theatrical\nfolk-rock, sea-shanty, theatrical\nfolk-rock, ska, Russian bard\nfolk-rock, smooth jazz\nfolk-rock, southern rock\nfolk-rock, southern rock, Americana\nfolk-rock, southern rock, blues-rock\nfolk-rock, southern rock, hard rock\nfolk-rock, southern rock, noise-rock\nfolk-rock, spiritual, Christian rock\nfolk-rock, stadium rock\nfolk-rock, stadium rock, Nepali\nfolk-rock, stadium rock, blues rock\nfolk-rock, surf rock, experimental\nfolk-rock, swamp-rock, pub-rock\nfolk-rock, symphonic metal\nfolk-rock, symphonic metal, Italian opera\nfolk-rock, symphonic metal, ambient\nfolk-rock, symphonic metal, pop-rock\nfolk-rock, symphonic metal, tango\nfolk-rock, symphonic power metal\nfolk-rock, symphonic rock, C-pop\nfolk-rock, symphonic rock, ambient\nfolk-rock, symphonic rock, cinematic\nfolk-rock, symphonic rock, progressive metal\nfolk-rock, synth-pop, rock\nfolk-rock, tango, operatic\nfolk-rock, tango, world fusion\nfolk-rock, tarantella, Italian\nfolk-rock, tarantella, cinematic\nfolk-rock, tarantella, live rock\nfolk-rock, tarantella, rock\nfolk-rock, theatrical pop-rock\nfolk-rock, theatrical rock\nfolk-rock, theatrical, Balkan folk\nfolk-rock, theatrical, Eastern European\nfolk-rock, theatrical, Italian\nfolk-rock, theatrical, Russian\nfolk-rock, theatrical, Vietnamese\nfolk-rock, theatrical, accordion\nfolk-rock, theatrical, cabaret\nfolk-rock, theatrical, cinematic\nfolk-rock, theatrical, comedic fantasy\nfolk-rock, theatrical, epic\nfolk-rock, theatrical, narrative\nfolk-rock, theatrical, operatic\nfolk-rock, theatrical, polka\nfolk-rock, theatrical, power metal\nfolk-rock, theatrical, satirical\nfolk-rock, theatrical, sea shanty\nfolk-rock, traditional Chinese, ambient\nfolk-rock, traditional Chinese, cinematic\nfolk-rock, traditional Lao, melodic fusion\nfolk-rock, turbo-folk\nfolk-rock, world fusion\nfolk-rock, world fusion, ska-punk\nfolk-rock, world music, Brazilian\nfolk-rock, world music, C-pop\nfolk-rock, world music, Chinese fusion\nfolk-rock, world music, bansuri\nfolk-rock, world music, cinematic\nfolk-rock, world music, epic\nfolk-rock, world music, epic ballad\nfolk-rock, world music, microtonal\nfolk-rock, world music, sea shanty\nfolk-rock, world music, stadium rock\nfolk-rock, worship, anthemic\nfolk-ska\nfolk-soul\nfolk-stomp\nfolk-sufi\nfolk-swing\nfolk-swing cabaret\nfolk-tango\nfolk-trap\nfolk-trap dance-pop\nfolk-trap hip-hop\nfolk-tronica\nfolk-waltz\nfolklore\nfolklore ambient\nfolklore argentinian\nfolklore argentino\nfolkloric\nfolkloric Brazilian\nfolkloric Latin\nfolkloric Latin American\nfolkloric Latin jazz\nfolkloric Latin percussion\nfolkloric Mexican\nfolkloric ambient\nfolkloric ballad\nfolkloric chant\nfolkloric choral\nfolkloric cinematic\nfolkloric electronic\nfolkloric epic\nfolkloric flamenco\nfolkloric folk\nfolkloric lament\nfolkloric orchestral\nfolkloric percussion\nfolkloric piano\nfolkloric polka\nfolkloric pop\nfolkloric reggae\nfolkloric tango\nfolkloric trance\nfolkloric world\nfolktronica\nfolktronica, Latin pop\nfootball anthem\nfootball chant\nfootball chant, schlager, polka\nfootwork, trap, phonk\nforró\nforró Axé\nforró MPB\nforró arrocha\nforró axé\nforró baião\nforró baião axé\nforró blues rock\nforró breakcore\nforró brega\nforró brega sertanejo\nforró brega-pop\nforró brega-rock\nforró carimbó\nforró children's\nforró children's music\nforró chiptune\nforró chiptune pop-rock\nforró country\nforró country rockabilly\nforró cumbia\nforró electronic\nforró eletrônico\nforró eletrônico brega funk\nforró eletrônico chiptune\nforró fado\nforró frevo\nforró funk\nforró funk rock\nforró fusion\nforró gospel\nforró gospel rock\nforró hip-hop\nforró indie pop\nforró jazz fusion\nforró jazz-rock\nforró kids\nforró lo-fi\nforró metal\nforró novelty\nforró pagode\nforró pimba\nforró piseiro\nforró piseiro brega\nforró pop\nforró pop brega\nforró pop-rock\nforró psychedelic rock\nforró punk\nforró punk rock\nforró reggae\nforró reggae-rock\nforró rock\nforró rock funk\nforró rock gospel\nforró rockabilly\nforró rockabilly big band\nforró romântico\nforró salsa\nforró samba\nforró samba-reggae\nforró sertanejo\nforró sertanejo axé\nforró ska\nforró surf rock\nforró swing\nforró synth-pop\nforró tango\nforró world music\nforró xote vaneira\nforró, Axé\nforró, Axé, Brazilian\nforró, Axé, Brazilian pop\nforró, Axé, dance\nforró, Axé, pop-rock\nforró, Brazilian Christian, synth pop\nforró, Brazilian pop\nforró, Brazilian romantic, electronic\nforró, Latin cumbia\nforró, MPB\nforró, axé\nforró, axé, samba-reggae\nforró, baião\nforró, baião, Brazilian\nforró, baião, Brazilian folk\nforró, baião, Brazilian pop\nforró, baião, Brazilian popular music\nforró, baião, Brazilian theatrical\nforró, baião, C-pop\nforró, baião, Christian\nforró, baião, acoustic\nforró, baião, children's music\nforró, baião, children's worship\nforró, baião, novelty\nforró, baião, political satire\nforró, baião, theatrical\nforró, brega\nforró, brega pop\nforró, brega, R&B\nforró, brega-pop\nforró, brega-pop, romantic ballad\nforró, cello, melancholic\nforró, children's dance\nforró, children's music\nforró, children's music, Brazilian\nforró, cinematic orchestral, Brazilian pop\nforró, cinematic, Brazilian\nforró, country, children's music\nforró, cumbia, dance\nforró, frevo, Brazilian carnival\nforró, frevo, children's music\nforró, funk carioca\nforró, gospel, funk-rock\nforró, novelty, funk carioca\nforró, piseiro\nforró, piseiro, Brazilian pop\nforró, piseiro, chiptune\nforró, piseiro, cinematic ballad\nforró, piseiro, electronic\nforró, pop brega\nforró, rock\nforró, samba, horror\nforró, samba-rock, Brazilian pop\nforró, sertanejo\nforró, sertanejo, cinematic\nforró, sertanejo, tango\nforró, xote, Gaúcho music\nforró-pop\nforró-reggae\nforró-rock\nforró-rock, brega funk\nforró-ska\nfree jazz\nfree jazz Afro-Cuban jazz\nfree jazz Latin\nfree jazz bebop\nfree jazz blues\nfree jazz blues-rock\nfree jazz cabaret\nfree jazz funk\nfree jazz funk rock\nfree jazz funk soul\nfree jazz funk-rock ska-punk\nfree jazz fusion\nfree jazz hip hop\nfree jazz hip-hop\nfree jazz post-rock\nfree jazz post-rock boogie-woogie\nfree jazz psychedelic rock\nfree jazz rock\nfree jazz salsa\nfree jazz soul\nfree jazz, Balkan folk, gypsy punk\nfree jazz, Italian ballad\nfree jazz, Latin jazz\nfree jazz, Latin jazz, psychedelic\nfree jazz, Latin jazz, vocal jazz\nfree jazz, big band, bebop\nfree jazz, big band, jazz vocal\nfree jazz, blues, Latin jazz\nfree jazz, boogie-woogie, art-pop\nfree jazz, folk-punk, Balkan\nfree jazz, folk-punk, Balkan-ska\nfree jazz, funk, J-pop\nfree jazz, funk, R&B\nfree jazz, jazz trio, soulful jazz\nfree jazz, jump blues, big band\nfree jazz, psychedelic rock, Afro-Brazilian\nfree jazz, vocal jazz, bebop\nfree-form jazz\nfree-jazz\nfree-jazz cabaret punk\nfree-jazz funk\nfree-jazz funk fusion\nfree-jazz funk soul\nfree-jazz funk-rock\nfree-jazz hip-hop\nfree-jazz metalcore\nfree-jazz rock\nfree-jazz, Afro-Cuban salsa\nfree-jazz, art-rock, theatrical\nfreestyle\nfreestyle 80s\nfreestyle dance-pop\nfreestyle hip hop\nfreestyle hip-hop\nfreestyle hip-house\nfreestyle house\nfreestyle new jack swing\nfreestyle rap\nfreestyle synth-pop\nfreestyle techno\nfreestyle, new jack swing\nfreestyle, new jack swing, 80s dance\nfreestyle, new jack swing, dance\nfreestyle, reggaeton\nfretless bass\nfrevo\nfrevo axé\nfrevo big band\nfrevo rap-rock\nfrevo rockabilly\nfrevo samba\nfrevo samba-reggae\nfun-punk\nfunhouse music\nfunk\nfunk Afro-Cuban\nfunk Afro-Cuban jazz\nfunk Afrobeat\nfunk Arabic\nfunk Arabic fusion\nfunk Arabic pop\nfunk Arabic pop Latin\nfunk C-pop\nfunk C-pop chiptune\nfunk J-pop\nfunk Latin\nfunk Latin alternative\nfunk Latin fusion\nfunk Latin jazz\nfunk Latin jazz big band\nfunk Latin jazz breakbeat\nfunk Latin jazz pop\nfunk Latin jazz video game\nfunk Latin pop\nfunk Latin pop R&B\nfunk Latin pop hip-hop\nfunk Latin pop worldbeat\nfunk Latin rock\nfunk Latin rock big band\nfunk Latin rock psychedelic rock\nfunk Latin rock world music\nfunk MPB\nfunk Mandopop\nfunk R&B\nfunk R&B Brazilian pop\nfunk R&B Caribbean\nfunk R&B Christmas\nfunk R&B Korean hip-hop\nfunk R&B Latin\nfunk R&B big band\nfunk R&B chiptune\nfunk R&B cinematic\nfunk R&B city pop\nfunk R&B city-pop\nfunk R&B comedy\nfunk R&B dancehall\nfunk R&B disco\nfunk R&B electronic pop\nfunk R&B gospel\nfunk R&B hip-hop\nfunk R&B jazz\nfunk R&B jazz fusion\nfunk R&B lo-fi\nfunk R&B neo-soul\nfunk R&B orchestral\nfunk R&B pop\nfunk R&B psychedelic\nfunk R&B soca\nfunk R&B soul\nfunk R&B world music\nfunk R&B, jungle, drum and bass\nfunk UK hip-hop\nfunk a cappella\nfunk acid jazz\nfunk acid jazz Brazilian pop\nfunk acid jazz J-pop\nfunk acid jazz J-rock\nfunk acid jazz Latin\nfunk acid jazz Shibuya-kei\nfunk acid jazz breakbeat\nfunk acid jazz chiptune\nfunk acid jazz hip-hop\nfunk acid jazz lo-fi\nfunk acid jazz lounge\nfunk acid jazz neo-soul\nfunk acid jazz soul\nfunk acid jazz trip-hop\nfunk acid jazz world music\nfunk acoustic\nfunk acoustic rock\nfunk afrobeat\nfunk afrobeat big band\nfunk afrobeat electronic\nfunk afrobeat pop\nfunk afrobeat protest\nfunk alternative dance\nfunk alternative rock\nfunk arabic pop\nfunk bass\nfunk bhangra\nfunk big band\nfunk big band Indian film music\nfunk big beat Bollywood\nfunk big beat Latin party\nfunk big beat video game\nfunk blues\nfunk blues rock\nfunk blues rock world music\nfunk blues world music\nfunk blues-rock\nfunk boogaloo\nfunk boogaloo soul-jazz\nfunk boogie\nfunk boogie-woogie\nfunk brasileiro, hyperpop\nfunk brass\nfunk break\nfunk breakbeat\nfunk breakbeat acid house\nfunk breakbeat big beat\nfunk breakbeat chiptune\nfunk breakbeat dancehall\nfunk breakbeat electronic\nfunk breakbeat electronic lounge\nfunk breakbeat electronic rock\nfunk breakbeat experimental\nfunk breakbeat free-jazz\nfunk breakbeat lo-fi\nfunk breakbeat turntablism\nfunk breakbeat video game\nfunk breakbeat video game music\nfunk breakbeat world music\nfunk breakbeat, soulful R&B\nfunk breakcore chiptune\nfunk breaks\nfunk calypso\nfunk carioca\nfunk carioca R&B\nfunk carioca baile funk\nfunk carioca big band\nfunk carioca big beat\nfunk carioca blues\nfunk carioca bossa nova\nfunk carioca breakcore\nfunk carioca chiptune\nfunk carioca classical\nfunk carioca classical fusion\nfunk carioca cumbia\nfunk carioca dream pop\nfunk carioca experimental electronic\nfunk carioca forró\nfunk carioca gospel\nfunk carioca hardstyle\nfunk carioca hip-hop\nfunk carioca hyperpop\nfunk carioca indie rock\nfunk carioca industrial rock\nfunk carioca lo-fi\nfunk carioca metal\nfunk carioca pagode\nfunk carioca pop\nfunk carioca pop-R&B\nfunk carioca punk rock\nfunk carioca rap-rock\nfunk carioca reggaeton\nfunk carioca reggaeton pop\nfunk carioca rock\nfunk carioca rock pagode\nfunk carioca samba\nfunk carioca samba-reggae\nfunk carioca sertanejo\nfunk carioca stadium rock\nfunk carioca surf rock\nfunk carioca tech house\nfunk carioca trap\nfunk carioca, Arabic pop\nfunk carioca, Balkan folk, Brazilian\nfunk carioca, Bollywood, Arabic fusion\nfunk carioca, Bollywood, dance\nfunk carioca, Brazilian country\nfunk carioca, EDM\nfunk carioca, R&B\nfunk carioca, R&B, Brazilian pop\nfunk carioca, R&B, hip-hop\nfunk carioca, R&B, trap\nfunk carioca, baroque, synth\nfunk carioca, big room house\nfunk carioca, children's music\nfunk carioca, children's pop\nfunk carioca, chiptune, Brazilian electronic\nfunk carioca, chiptune, electronic\nfunk carioca, chiptune, synth-pop\nfunk carioca, cinematic, hybrid\nfunk carioca, cumbia, Latin\nfunk carioca, electronic dance, Balkan fusion\nfunk carioca, electronic dance, Middle Eastern fusion\nfunk carioca, electronic dance-pop\nfunk carioca, electronic, Middle Eastern\nfunk carioca, hard dance, gabber\nfunk carioca, hard dance, hyperpop\nfunk carioca, hard rock\nfunk carioca, hardstyle, EDM\nfunk carioca, hardstyle, happy hardcore\nfunk carioca, heavy rock\nfunk carioca, heavy rock, synth metal\nfunk carioca, hyperpop\nfunk carioca, hyperpop, electronic\nfunk carioca, jazz-funk\nfunk carioca, pagode romântico\nfunk carioca, piseiro, electronic\nfunk carioca, psychedelic rock\nfunk carioca, psytrance, hardstyle\nfunk carioca, reggaeton, Latin trap\nfunk carioca, samba, hip hop\nfunk carioca, sertanejo, electronic\nfunk carioca, slap house, Brazilian electronic\nfunk carioca, synth-pop\nfunk carioca, trap R&B\nfunk carioca, tribal house, Brazilian electronic\nfunk carioca, world music, electronic\nfunk cello\nfunk chanson\nfunk children's\nfunk children's education\nfunk children's music\nfunk chiptune\nfunk chiptune electronic\nfunk chiptune synth-pop\nfunk cinematic\nfunk city pop\nfunk city pop indie rock\nfunk city pop smooth jazz\nfunk city pop video game\nfunk classical\nfunk classical fusion\nfunk comedy\nfunk comedy novelty\nfunk comedy rap\nfunk cumbia\nfunk cumbia fusion\nfunk cumbia pop\nfunk dance\nfunk dance-pop\nfunk dancehall\nfunk dancehall French rap\nfunk dancehall hip-hop\nfunk disco\nfunk disco Arabic pop\nfunk disco C-pop\nfunk disco Greek pop\nfunk disco J-pop\nfunk disco Latin\nfunk disco Latin jazz\nfunk disco big band\nfunk disco boogie-woogie\nfunk disco chiptune\nfunk disco city pop\nfunk disco dancehall\nfunk disco gospel\nfunk disco house\nfunk disco jazz\nfunk disco latin\nfunk disco latin jazz\nfunk disco lo-fi\nfunk disco novelty\nfunk disco pop\nfunk disco pop-rock\nfunk disco psychedelic pop\nfunk disco rock\nfunk disco schlager\nfunk disco show tune\nfunk disco soukous\nfunk disco soul\nfunk disco synth-pop\nfunk disco trot\nfunk disco video game\nfunk disco world music\nfunk disco, Italian ballad\nfunk disco-pop\nfunk drum\nfunk drum and bass\nfunk drum break\nfunk dub\nfunk dub hip-hop\nfunk dubstep\nfunk dubstep fusion\nfunk electro\nfunk electro acid jazz\nfunk electro chiptune\nfunk electro-funk\nfunk electro-pop\nfunk electronic\nfunk electronic chiptune\nfunk electronic devotional\nfunk electronic experimental\nfunk electronic jazz\nfunk electronic lounge\nfunk electronic pop\nfunk electronic world fusion\nfunk electronic world music\nfunk electronica\nfunk electronica dream pop\nfunk electronica world music\nfunk flamenco\nfunk folk fusion\nfunk folk world music\nfunk fusion\nfunk fusion hip-hop\nfunk fusion rock\nfunk fusion, Bollywood, Latin\nfunk fusion, J-pop, video game music\nfunk fusion, breakbeat, chiptune\nfunk fusion, city pop, video game soundtrack\nfunk fusion, rock, chiptune\nfunk fusion, rock, video game music\nfunk fusion, ska, video game music\nfunk fusion, synth-pop, video game music\nfunk fusion, video game music\nfunk fusion, video game music, rock\nfunk future bass\nfunk gospel\nfunk gospel Afrobeat\nfunk gospel R&B\nfunk gospel afrobeat\nfunk gospel big band\nfunk gospel dancehall\nfunk gospel hard rock\nfunk gospel hip-hop\nfunk gospel pop\nfunk gospel pop-rock\nfunk gospel progressive rock\nfunk gospel rock\nfunk groove\nfunk guitar\nfunk gypsy jazz\nfunk hip hop\nfunk hip hop gospel\nfunk hip hop pop\nfunk hip-hop\nfunk hip-hop Arabic fusion\nfunk hip-hop Armenian folk\nfunk hip-hop C-pop\nfunk hip-hop Indian film music\nfunk hip-hop Indian pop\nfunk hip-hop K-pop\nfunk hip-hop Latin\nfunk hip-hop Latin pop\nfunk hip-hop Middle Eastern\nfunk hip-hop R&B\nfunk hip-hop Turkish pop\nfunk hip-hop acid jazz\nfunk hip-hop art-pop\nfunk hip-hop bhangra\nfunk hip-hop big band\nfunk hip-hop big band jazz\nfunk hip-hop big beat\nfunk hip-hop blues\nfunk hip-hop brass\nfunk hip-hop breakbeat\nfunk hip-hop chiptune\nfunk hip-hop city pop\nfunk hip-hop drum and bass\nfunk hip-hop electronic\nfunk hip-hop experimental\nfunk hip-hop flamenco\nfunk hip-hop free-jazz\nfunk hip-hop fusion\nfunk hip-hop gospel\nfunk hip-hop gospel house\nfunk hip-hop gospel soul\nfunk hip-hop gypsy jazz\nfunk hip-hop indie pop\nfunk hip-hop indie rock\nfunk hip-hop jazz\nfunk hip-hop jungle\nfunk hip-hop kuthu\nfunk hip-hop musical theater\nfunk hip-hop neo-soul\nfunk hip-hop novelty\nfunk hip-hop polka\nfunk hip-hop pop\nfunk hip-hop psychedelic rock\nfunk hip-hop punk rock\nfunk hip-hop raï\nfunk hip-hop reggae\nfunk hip-hop regional pop\nfunk hip-hop rock\nfunk hip-hop samba\nfunk hip-hop ska\nfunk hip-hop soul\nfunk hip-hop tribal\nfunk hip-hop turntablism\nfunk hip-hop vaporwave\nfunk hip-hop world music\nfunk hip-hop, alternative rock\nfunk hip-hop, rock, industrial\nfunk hop\nfunk house\nfunk house breakbeat\nfunk house disco\nfunk house jazz\nfunk house, Latin house, world music\nfunk house, Latin pop\nfunk hyperpop\nfunk indie pop\nfunk indie pop South Asian\nfunk indie rock\nfunk indie rock psychedelic\nfunk indie rock soul\nfunk instrumental\nfunk jam\nfunk jazz\nfunk jazz J-pop\nfunk jazz North African pop\nfunk jazz balkan pop\nfunk jazz breakbeat\nfunk jazz city pop\nfunk jazz electronic\nfunk jazz experimental pop\nfunk jazz fusion\nfunk jazz fusion blues rock\nfunk jazz fusion chiptune\nfunk jazz fusion city pop\nfunk jazz fusion drum and bass\nfunk jazz fusion electronic\nfunk jazz fusion electronic lounge\nfunk jazz fusion neo-soul\nfunk jazz fusion progressive rock\nfunk jazz hip-hop\nfunk jazz lounge\nfunk jazz rap\nfunk jazz rock\nfunk jazz samba\nfunk jazz soul\nfunk jazz video game\nfunk jazz world fusion\nfunk jazz world music\nfunk jazz-fusion\nfunk jazz-fusion neo-soul\nfunk jazz-hop\nfunk jazz-hop soul\nfunk jazz-rap\nfunk klezmer big band\nfunk latin\nfunk latin jazz\nfunk lo-fi hip-hop\nfunk lounge\nfunk lounge breakbeat\nfunk lounge downtempo\nfunk lounge electronic\nfunk lounge latin\nfunk lounge world music\nfunk mandelão\nfunk mandelão, Brazilian funk, synthwave\nfunk math rock chiptune\nfunk metal\nfunk metal alternative metal\nfunk metal alternative rock\nfunk metal crossover thrash\nfunk metal fusion\nfunk metal groove metal\nfunk metal progressive metal\nfunk metal progressive rock\nfunk metal punk\nfunk metal punk rock\nfunk metal rap rock\nfunk metal rap-rock\nfunk metal reggae rock\nfunk metal ska-punk\nfunk metal thrash\nfunk metal, Christian rock\nfunk metal, Japanese hard rock\nfunk metal, Japanese rock\nfunk metal, alternative rock\nfunk metal, big band jazz\nfunk metal, chiptune, video game music\nfunk metal, hard rock\nfunk metal, hard rock, acid jazz\nfunk metal, hard rock, chiptune\nfunk metal, hard rock, ska-punk\nfunk metal, new jack swing\nfunk metal, progressive rock\nfunk metal, punk rock\nfunk metal, rap rock\nfunk metal, rap-rock\nfunk metal, rap-rock, dancehall\nfunk metal, rap-rock, hardcore punk\nfunk metal, rap-rock, nu-metal\nfunk metal, reggae rock, punk\nfunk metal, speed metal\nfunk metal, surf rock\nfunk metal, technical rock\nfunk metal, theatrical hard rock\nfunk metal, thrash metal, theatrical rock\nfunk metal, video game music\nfunk neo-soul\nfunk neo-soul Brazilian pop\nfunk neo-soul J-pop\nfunk neo-soul acid jazz\nfunk neo-soul afrobeat\nfunk neo-soul dream pop\nfunk neo-soul g-funk\nfunk neo-soul hip-hop\nfunk neo-soul lounge\nfunk neo-soul pop\nfunk neo-soul pop ballad\nfunk neo-soul psychedelic pop\nfunk neo-soul vaporwave\nfunk neo-soul video game music\nfunk new jack swing\nfunk noir\nfunk novelty\nfunk novelty rock\nfunk nu-disco\nfunk orchestral\nfunk orchestral Latin pop\nfunk ostentação\nfunk pagode\nfunk party\nfunk pluggnb\nfunk polka\nfunk pop\nfunk pop Bollywood\nfunk pop German hip-hop\nfunk pop Indian devotional\nfunk pop Indian film music\nfunk pop Indian fusion\nfunk pop Latin\nfunk pop MPB\nfunk pop Middle Eastern\nfunk pop R&B\nfunk pop acid jazz\nfunk pop afrobeat\nfunk pop bollywood\nfunk pop cabaret\nfunk pop chiptune\nfunk pop disco\nfunk pop electro\nfunk pop electronic\nfunk pop experimental\nfunk pop gospel\nfunk pop hip hop\nfunk pop hip-hop\nfunk pop jazz\nfunk pop kizomba\nfunk pop neo-soul\nfunk pop rap\nfunk pop reggae\nfunk pop retro\nfunk pop rock\nfunk pop soul\nfunk pop world music\nfunk pop worldbeat\nfunk pop, 80s synth-pop, Bengali pop\nfunk pop, C-pop, synth pop\nfunk pop, Caribbean pop\nfunk pop, Caribbean, dance\nfunk pop, Chinese fusion\nfunk pop, Desi hip-hop\nfunk pop, Indian film music\nfunk pop, Indian film music, late-90s\nfunk pop, Indian fusion\nfunk pop, Latin pop, Tamil pop\nfunk pop, Mandopop, retro\nfunk pop, Middle Eastern fusion\nfunk pop, Middle Eastern pop\nfunk pop, R&B, multilingual\nfunk pop, South Asian fusion\nfunk pop, South Indian film music\nfunk pop, bhangra, electronic\nfunk pop, city pop\nfunk pop, electro-pop, hyperpop\nfunk pop, hyperpop, R&B\nfunk pop, neo-soul, city pop\nfunk pop, retro synth-pop\nfunk pop-rap\nfunk pop-rap afrobeat\nfunk pop-rock\nfunk pop-rock big band\nfunk pop-rock ska\nfunk pop-rock world music\nfunk proibidão\nfunk protest\nfunk psychedelic\nfunk psychedelic rock\nfunk punk\nfunk punk rock\nfunk ragtime\nfunk rap\nfunk rap, city pop, nu-disco\nfunk rave\nfunk rave, Bollywood dance, electronic\nfunk reggae\nfunk reggae Caribbean\nfunk reggae French Caribbean\nfunk reggae French pop\nfunk reggae J-pop\nfunk reggae Latin\nfunk reggae Latin rock\nfunk reggae South Asian pop\nfunk reggae afrobeat\nfunk reggae dancehall\nfunk reggae dub\nfunk reggae electronic\nfunk reggae folk-pop\nfunk reggae fusion\nfunk reggae gospel\nfunk reggae gospel rock\nfunk reggae hip hop\nfunk reggae hip-hop\nfunk reggae instrumental\nfunk reggae novelty\nfunk reggae pop\nfunk reggae pop-reggae\nfunk reggae pop-rock\nfunk reggae psychedelic\nfunk reggae psychedelic rock\nfunk reggae rock\nfunk reggae soul\nfunk reggae world music\nfunk reggae zouk\nfunk reggae-ska\nfunk ritual\nfunk rock\nfunk rock Afro-Brazilian\nfunk rock Afrobeat\nfunk rock Arabic fusion\nfunk rock Arabic pop\nfunk rock R&B\nfunk rock acid jazz\nfunk rock alternative\nfunk rock alternative metal\nfunk rock alternative rock\nfunk rock axé\nfunk rock big band\nfunk rock blues\nfunk rock blues rock\nfunk rock boogie-woogie\nfunk rock breakbeat\nfunk rock chiptune\nfunk rock city pop\nfunk rock cumbia\nfunk rock dance-pop\nfunk rock dance-punk\nfunk rock dangdut\nfunk rock dangdut koplo\nfunk rock desert rock\nfunk rock disco\nfunk rock electronic\nfunk rock fusion\nfunk rock garage rock\nfunk rock gospel\nfunk rock gospel pop\nfunk rock grunge\nfunk rock hard rock\nfunk rock hip hop\nfunk rock hip-hop\nfunk rock industrial\nfunk rock j-pop\nfunk rock jazz\nfunk rock jazz fusion\nfunk rock latin pop\nfunk rock math rock\nfunk rock metal\nfunk rock nu-metal\nfunk rock pop-punk\nfunk rock progressive metal\nfunk rock progressive rock\nfunk rock psychedelic\nfunk rock psychedelic blues\nfunk rock psychedelic punk\nfunk rock psychedelic reggae\nfunk rock psychedelic rock\nfunk rock punk\nfunk rock rap metal\nfunk rock rap rock\nfunk rock rap-rock\nfunk rock reggae\nfunk rock reggae fusion\nfunk rock samba\nfunk rock samba rock\nfunk rock samba-reggae\nfunk rock samba-rock\nfunk rock ska\nfunk rock ska punk\nfunk rock ska-punk\nfunk rock soul\nfunk rock soul revue\nfunk rock surf rock\nfunk rock synth-pop\nfunk rock thrash metal\nfunk rock world music\nfunk rock, Afro-Brazilian\nfunk rock, Afro-Brazilian, spiritual\nfunk rock, Afro-Cuban\nfunk rock, Anatolian rock\nfunk rock, Arabic fusion\nfunk rock, Arabic pop\nfunk rock, Axé\nfunk rock, Balkan brass\nfunk rock, Balkan punk\nfunk rock, Bollywood\nfunk rock, Bollywood, vintage\nfunk rock, Bollywood, world fusion\nfunk rock, Brazilian MPB\nfunk rock, Brazilian carnival\nfunk rock, Brazilian carnival, live energy\nfunk rock, Brazilian hip-hop\nfunk rock, Brazilian party music\nfunk rock, Brazilian pop\nfunk rock, Brazilian rap\nfunk rock, Brazilian rhythms\nfunk rock, Brazilian, fusion\nfunk rock, Brazilian, psychedelic\nfunk rock, Christian pop-rock\nfunk rock, Christian rap-rock\nfunk rock, Christian rock\nfunk rock, Indian classical\nfunk rock, Indian folk\nfunk rock, Indian fusion, devotional\nfunk rock, Indian pop\nfunk rock, Indian pop, electronic fusion\nfunk rock, J-rock\nfunk rock, Javanese fusion\nfunk rock, Latin Christian, fusion\nfunk rock, Latin cumbia\nfunk rock, Latin dance\nfunk rock, Latin fusion\nfunk rock, Latin fusion, flamenco\nfunk rock, Latin groove, electronic\nfunk rock, Latin jazz\nfunk rock, Latin mambo\nfunk rock, Latin party\nfunk rock, Latin percussion\nfunk rock, Latin pop\nfunk rock, Latin punk\nfunk rock, Latin rock\nfunk rock, Latin rock, hard rock\nfunk rock, Latin salsa\nfunk rock, Latin ska\nfunk rock, Latin, accordion\nfunk rock, Latin, chiptune\nfunk rock, Latin, dance\nfunk rock, MPB\nfunk rock, Middle Eastern folk\nfunk rock, Middle Eastern folk, electronic fusion\nfunk rock, Middle Eastern fusion\nfunk rock, Middle Eastern fusion, quirky pop\nfunk rock, Middle Eastern pop\nfunk rock, North African fusion\nfunk rock, Punjabi folk\nfunk rock, South Asian pop\nfunk rock, South Indian folk\nfunk rock, Southern rock\nfunk rock, Sundanese pop\nfunk rock, Tamil folk\nfunk rock, Tamil rap\nfunk rock, Thai folk\nfunk rock, alternative punk\nfunk rock, alternative rock\nfunk rock, big band\nfunk rock, big band jazz\nfunk rock, big band jazz, video game music\nfunk rock, big band swing\nfunk rock, big band swing, ska-punk\nfunk rock, big band, Japanese fusion\nfunk rock, big band, swing\nfunk rock, big beat\nfunk rock, big beat, electronic\nfunk rock, big beat, hip-hop\nfunk rock, blues rock, Indian folk\nfunk rock, breakbeat, lo-fi\nfunk rock, candombe, Latin\nfunk rock, carnival music\nfunk rock, chiptune, J-pop\nfunk rock, chiptune, Japanese video game music\nfunk rock, chiptune, video game music\nfunk rock, city pop\nfunk rock, city pop, video game music\nfunk rock, electronic dance music\nfunk rock, electronic dance, pop\nfunk rock, electronic fusion, Greek pop\nfunk rock, enka, Japanese folk\nfunk rock, enka, traditional Japanese\nfunk rock, forró\nfunk rock, forró, chiptune\nfunk rock, gospel metal, hip-hop\nfunk rock, hard rock\nfunk rock, hard rock, heavy metal\nfunk rock, hard rock, metal\nfunk rock, hard rock, metalcore\nfunk rock, hard rock, rap rock\nfunk rock, heavy metal\nfunk rock, heavy metal, Latin rock\nfunk rock, hip-hop, nu-metal\nfunk rock, jazz fusion, thrash metal\nfunk rock, kayōkyoku\nfunk rock, klezmer, hip hop\nfunk rock, kuthu\nfunk rock, latin dance\nfunk rock, latin rock\nfunk rock, metal, rock\nfunk rock, narrative hip-hop\nfunk rock, new jack swing\nfunk rock, new wave\nfunk rock, new wave, 80s\nfunk rock, pop-metal\nfunk rock, progressive metal\nfunk rock, psychedelic rock\nfunk rock, psychedelic rock, Brazilian pop\nfunk rock, psychedelic rock, punk rock\nfunk rock, psychedelic, MPB\nfunk rock, punk rock, hip-hop\nfunk rock, rap metal\nfunk rock, rap metal, fusion\nfunk rock, rap-metal\nfunk rock, rockabilly, surf rock\nfunk rock, rumba, accordion\nfunk rock, samba-reggae\nfunk rock, samba-rock\nfunk rock, surf punk\nfunk rock, surf rock, Japanese action\nfunk rock, surf rock, Latin\nfunk rock, synth-rock, video game music\nfunk rock, theatrical rock\nfunk rock, thrash metal\nfunk rock, video game music\nfunk rock, video game music, fusion\nfunk rock, video game music, new jack swing\nfunk rock, video game soundtrack, electronic\nfunk rock, world music\nfunk rock, world music, electronic\nfunk rockabilly soul\nfunk salsa\nfunk samba\nfunk samba big band\nfunk samba fusion\nfunk samba-funk\nfunk samba-pop\nfunk samba-reggae\nfunk samba-reggae hip-hop\nfunk samba-rock\nfunk samba-rock big band\nfunk satire\nfunk ska\nfunk ska Balkan brass\nfunk ska Caribbean\nfunk ska French chanson\nfunk ska Latin jazz\nfunk ska Latin rock\nfunk ska big band\nfunk ska brass\nfunk ska children's\nfunk ska protest\nfunk ska protest rock\nfunk ska punk\nfunk ska rap\nfunk ska soul\nfunk ska world music\nfunk ska-punk\nfunk smooth jazz\nfunk soca\nfunk soul\nfunk soul Afro-Caribbean\nfunk soul Afro-Cuban jazz\nfunk soul Arabic pop\nfunk soul Caribbean\nfunk soul Italian pop\nfunk soul Latin\nfunk soul Latin jazz\nfunk soul Latin rock\nfunk soul MPB\nfunk soul R&B\nfunk soul Turkish pop\nfunk soul a cappella\nfunk soul acid jazz\nfunk soul afrobeat\nfunk soul big band\nfunk soul blues\nfunk soul blues-rock\nfunk soul boogie\nfunk soul cabaret\nfunk soul children's\nfunk soul children's music\nfunk soul chiptune\nfunk soul city pop\nfunk soul conscious hip-hop\nfunk soul cumbia\nfunk soul dance-pop\nfunk soul disco\nfunk soul dub\nfunk soul experimental pop\nfunk soul experimental rock\nfunk soul free-jazz\nfunk soul gospel\nfunk soul hip-hop\nfunk soul indie pop\nfunk soul jazz\nfunk soul jazz fusion\nfunk soul jazz-fusion\nfunk soul jazz-pop\nfunk soul jazz-rock\nfunk soul latin\nfunk soul latin boogaloo\nfunk soul latin jazz\nfunk soul lounge\nfunk soul orchestral\nfunk soul pop\nfunk soul pop-rock\nfunk soul protest\nfunk soul psychedelic\nfunk soul psychedelic lounge\nfunk soul psychedelic rock\nfunk soul psychedelic soul\nfunk soul r&b\nfunk soul rap\nfunk soul reggae\nfunk soul rock\nfunk soul rockabilly\nfunk soul salsa\nfunk soul ska\nfunk soul smooth jazz\nfunk soul southern rock\nfunk soul theatrical jazz\nfunk soul trap\nfunk soul trip-hop\nfunk soul world fusion\nfunk soul world music\nfunk soul worship\nfunk soul zouk\nfunk soul, blues rock\nfunk soul, blues-rock\nfunk soul, hip-hop R&B\nfunk soul-jazz\nfunk soul-jazz Latin\nfunk soul-pop\nfunk soul-rap\nfunk soul-rock\nfunk southern rock\nfunk surf rock\nfunk swing\nfunk synth\nfunk synth-pop\nfunk synth-pop chiptune\nfunk synth-pop experimental rock\nfunk theatrical\nfunk trap\nfunk trip-hop\nfunk trip-hop Latin\nfunk trip-hop electronica\nfunk trip-hop sci-fi\nfunk trip-hop world music\nfunk trot\nfunk world\nfunk world fusion\nfunk world jazz\nfunk world music\nfunk world music pop-rap\nfunk world pop\nfunk world psychedelic rock\nfunk worldbeat\nfunk worldbeat downtempo\nfunk worldbeat pop\nfunk worldbeat smooth jazz\nfunk worship\nfunk, 80s R&B\nfunk, 80s R&B, modern\nfunk, 80s boogie, new jack swing\nfunk, 80s dance, disco\nfunk, 80s pop, South Asian\nfunk, 80s synth\nfunk, 80s synth, new jack swing\nfunk, 80s synth, retro game\nfunk, 80s synth, soul\nfunk, 80s synth, video game soundtrack\nfunk, 80s video game, synth groove\nfunk, 80s, Christmas\nfunk, 80s, Japanese pop\nfunk, 80s, cinematic\nfunk, 80s, city pop\nfunk, 80s, dance\nfunk, 80s, synth\nfunk, 80s, synth funk\nfunk, 80s, upbeat\nfunk, 90s G-funk, video game music\nfunk, 90s R&B, retro\nfunk, 90s video game\nfunk, 90s video game, synth\nfunk, 90s video game, synthwave\nfunk, African funk\nfunk, Afro-Caribbean, soukous\nfunk, Afro-Caribbean, soul\nfunk, Afro-Cuban\nfunk, Afro-Cuban, Latin\nfunk, Afro-Cuban, dance\nfunk, Afro-Cuban, disco\nfunk, Afro-Cuban, soul\nfunk, Afro-Latin\nfunk, Afro-Latin, dance\nfunk, Afro-Latin, electronic\nfunk, Afro-Latin, groove\nfunk, Afro-Latin, instrumental\nfunk, Afro-Latin, vocal jazz\nfunk, Afro-funk\nfunk, Afro-pop, 80s\nfunk, Afro-soul\nfunk, Afrobeat\nfunk, Afrobeat, reggae\nfunk, Afrobeat, retro\nfunk, Afrobeat, soul\nfunk, Afrobeat, vintage\nfunk, Anatolian rock, vintage\nfunk, Andean, instrumental\nfunk, Arabic funk\nfunk, Arabic fusion, soul\nfunk, Arabic groove\nfunk, Arabic hip hop\nfunk, Arabic pop\nfunk, Arabic pop, dance\nfunk, Arabic pop, synth funk\nfunk, Arabic soul\nfunk, Arabic soul, electronic\nfunk, Arabic soul, lo-fi groove\nfunk, Arabic, dance\nfunk, Arabic, electronic\nfunk, Arabic, live band\nfunk, Arabic, soul\nfunk, Armenian folk, R&B\nfunk, Balkan beat, progressive rock\nfunk, Balkan fusion, electronic\nfunk, Balkan, Latin\nfunk, Balkan, electric guitar\nfunk, Balkan, electronic\nfunk, Balkan, jazz\nfunk, Balkan, klezmer\nfunk, Bengali pop, retro dance\nfunk, Bollywood disco\nfunk, Bollywood fusion\nfunk, Bollywood pop\nfunk, Bollywood pop, breakbeat\nfunk, Bollywood pop, worldbeat\nfunk, Bollywood, 80s\nfunk, Bollywood, Indian folk\nfunk, Bollywood, big band\nfunk, Bollywood, breakbeat\nfunk, Bollywood, chiptune\nfunk, Bollywood, dance\nfunk, Bollywood, electronic\nfunk, Bollywood, electronic dance\nfunk, Bollywood, hip-hop\nfunk, Bollywood, jazz fusion\nfunk, Bollywood, psychedelic rock\nfunk, Bollywood, retro\nfunk, Bollywood, world fusion\nfunk, Bollywood, world music\nfunk, Brazilian MPB\nfunk, Brazilian MPB, psychedelic soul\nfunk, Brazilian boogie, MPB\nfunk, Brazilian funk\nfunk, Brazilian funk, Latin hip hop\nfunk, Brazilian funk, carioca\nfunk, Brazilian funk, hip hop\nfunk, Brazilian funk, lo-fi\nfunk, Brazilian hip-hop\nfunk, Brazilian soul\nfunk, Brazilian, R&B\nfunk, Brazilian, children's\nfunk, Brazilian, dance\nfunk, Brazilian, electronic\nfunk, Brazilian, groove\nfunk, Brazilian, instrumental\nfunk, Brazilian, jazz fusion\nfunk, Brazilian, jingle\nfunk, Brazilian, live\nfunk, Brazilian, lo-fi\nfunk, Brazilian, party\nfunk, Brazilian, pop\nfunk, Brazilian, soul\nfunk, Brazilian, synthwave\nfunk, Cantopop, retro-funk\nfunk, Caribbean\nfunk, Caribbean fusion\nfunk, Caribbean, dance\nfunk, Caribbean, live\nfunk, Caribbean, live party\nfunk, Caribbean, party\nfunk, Caribbean, soul\nfunk, Carnatic, Tamil hip hop\nfunk, Chinese pop, electronic\nfunk, Christmas\nfunk, Christmas novelty\nfunk, Christmas, G-funk\nfunk, Christmas, R&B\nfunk, Christmas, jazz\nfunk, Christmas, novelty\nfunk, Christmas, pop\nfunk, Christmas, soul\nfunk, Christmas, synth-pop\nfunk, East Asian, video game\nfunk, European folk\nfunk, French chanson, cinematic\nfunk, French hip hop\nfunk, French hip hop, jazz fusion\nfunk, French pop\nfunk, French pop, Afrobeats\nfunk, French pop, electronic\nfunk, French pop, groove\nfunk, French pop, live\nfunk, French pop, lo-fi\nfunk, French pop, psychedelic\nfunk, French pop, retro\nfunk, French pop, soul\nfunk, French pop, synth funk\nfunk, French rap, R&B\nfunk, French rap, groove\nfunk, French rap, soul\nfunk, French, synth\nfunk, G-funk\nfunk, G-funk, acid jazz\nfunk, G-funk, electronic\nfunk, G-funk, instrumental hip-hop\nfunk, G-funk, modern\nfunk, G-funk, modern funk\nfunk, G-funk, neo-soul\nfunk, G-funk, new jack swing\nfunk, G-funk, synth funk\nfunk, Halloween, electronic\nfunk, Halloween, theatrical\nfunk, Hawaiian soul\nfunk, Hindi pop, electronic\nfunk, Indian classical, ambient\nfunk, Indian classical, jazz fusion\nfunk, Indian devotional, electronic\nfunk, Indian electronic, retro\nfunk, Indian film music\nfunk, Indian film music, cinematic\nfunk, Indian film music, disco\nfunk, Indian film music, fusion\nfunk, Indian folk, Bollywood\nfunk, Indian folk, fusion\nfunk, Indian folk, pop\nfunk, Indian folk, theatrical\nfunk, Indian fusion\nfunk, Indian fusion, cinematic\nfunk, Indian fusion, electronic\nfunk, Indian fusion, lo-fi\nfunk, Indian fusion, synthpop\nfunk, Indian pop\nfunk, Indian pop, electronic\nfunk, Indian pop, retro\nfunk, Indonesian percussion, glitch\nfunk, Irish folk\nfunk, Italian folk\nfunk, Italian groove\nfunk, Italian pop, dream-pop\nfunk, Italian pop, electronic\nfunk, Italian rap, electronic\nfunk, Italian, live\nfunk, Italo-disco\nfunk, J-pop, R&B\nfunk, J-pop, disco\nfunk, J-pop, electronic\nfunk, J-pop, soul\nfunk, J-pop, video game music\nfunk, J-rock, video game music\nfunk, Japanese pop, lo-fi\nfunk, K-funk, electronic\nfunk, K-pop\nfunk, K-pop, hip hop\nfunk, K-pop, modern\nfunk, K-pop, new jack swing\nfunk, K-pop, retro\nfunk, Latin boogaloo\nfunk, Latin boogaloo, hip-hop\nfunk, Latin dance, Portuguese\nfunk, Latin disco\nfunk, Latin folk, experimental\nfunk, Latin funk\nfunk, Latin funk, boogaloo\nfunk, Latin funk, dance\nfunk, Latin funk, instrumental\nfunk, Latin hip hop\nfunk, Latin house\nfunk, Latin jazz\nfunk, Latin jazz, Afro-Cuban\nfunk, Latin jazz, baritone sax\nfunk, Latin jazz, big band\nfunk, Latin jazz, electronic\nfunk, Latin jazz, experimental hip-hop\nfunk, Latin jazz, hip-hop\nfunk, Latin jazz, lounge\nfunk, Latin jazz, reggae\nfunk, Latin jazz, retro video game\nfunk, Latin jazz, salsa\nfunk, Latin jazz, soul\nfunk, Latin jazz, synth funk\nfunk, Latin jazz, world fusion\nfunk, Latin jazz, worldbeat\nfunk, Latin jazz-funk\nfunk, Latin percussion\nfunk, Latin percussion, big band jazz\nfunk, Latin pop\nfunk, Latin pop, Christian hip-hop\nfunk, Latin pop, eclectic\nfunk, Latin pop, electronic\nfunk, Latin pop, groove\nfunk, Latin pop, hip-hop\nfunk, Latin rock\nfunk, Latin rock, big band jazz\nfunk, Latin soul\nfunk, Latin soul, instrumental\nfunk, Latin soul, vintage\nfunk, Latin, Afro-Cuban\nfunk, Latin, Afrobeat\nfunk, Latin, Balkan\nfunk, Latin, Brazilian\nfunk, Latin, French pop\nfunk, Latin, German pop\nfunk, Latin, J-pop\nfunk, Latin, J-rap\nfunk, Latin, Mandarin soul\nfunk, Latin, Persian pop\nfunk, Latin, Polish pop\nfunk, Latin, Portuguese\nfunk, Latin, R&B\nfunk, Latin, ambient\nfunk, Latin, big band\nfunk, Latin, brass\nfunk, Latin, chiptune\nfunk, Latin, dance\nfunk, Latin, disco\nfunk, Latin, dub\nfunk, Latin, dubstep\nfunk, Latin, electronic\nfunk, Latin, groove\nfunk, Latin, hip hop\nfunk, Latin, hip-hop\nfunk, Latin, house\nfunk, Latin, instrumental\nfunk, Latin, jazz fusion\nfunk, Latin, lo-fi\nfunk, Latin, modern\nfunk, Latin, new jack swing\nfunk, Latin, party\nfunk, Latin, psychedelic\nfunk, Latin, psychedelic pop\nfunk, Latin, psychedelic rock\nfunk, Latin, reggae\nfunk, Latin, retro\nfunk, Latin, retro lounge\nfunk, Latin, soul\nfunk, Latin, synth\nfunk, Latin, synthwave\nfunk, Latin, theatrical\nfunk, Latin, trip-hop\nfunk, Latin, tropical\nfunk, Latin, upbeat\nfunk, Latin, video game music\nfunk, Latin, vintage\nfunk, Latin, world music\nfunk, Latin-funk, retro\nfunk, MPB, art-pop\nfunk, Mandarin pop, Latin pop\nfunk, Mandarin pop, soul\nfunk, Mandarin rap, jazzy\nfunk, Mandarin rap, modern funk\nfunk, Mandarin rap, soul\nfunk, Mandopop, electronic\nfunk, Mediterranean, groove\nfunk, Middle Eastern fusion\nfunk, Middle Eastern pop\nfunk, Middle Eastern, cinematic\nfunk, Middle Eastern, electronic\nfunk, Middle Eastern, jazz fusion\nfunk, Middle Eastern, lo-fi\nfunk, New Orleans, R&B\nfunk, New Orleans, big band\nfunk, New Orleans, brass\nfunk, New Orleans, comedy\nfunk, New Orleans, dance\nfunk, New Orleans, live band\nfunk, New Orleans, party\nfunk, North African pop\nfunk, Polish, electronic\nfunk, Punjabi, oud\nfunk, R&B\nfunk, R&B, Brazilian\nfunk, R&B, Brazilian pop\nfunk, R&B, Christmas\nfunk, R&B, Indian pop\nfunk, R&B, Latin\nfunk, R&B, New Orleans\nfunk, R&B, breakbeat\nfunk, R&B, cinematic\nfunk, R&B, electronic\nfunk, R&B, ethereal\nfunk, R&B, gospel\nfunk, R&B, hip hop\nfunk, R&B, hip-hop\nfunk, R&B, live\nfunk, R&B, modern\nfunk, R&B, new jack swing\nfunk, R&B, pop\nfunk, R&B, retro\nfunk, R&B, soul\nfunk, R&B, synthwave\nfunk, Russian pop\nfunk, Russian pop, big band\nfunk, South African folk\nfunk, South Asian folk, electronic\nfunk, South Asian funk\nfunk, South Asian pop\nfunk, South Indian film music, electronic\nfunk, South Indian pop\nfunk, Tagalog pop\nfunk, Tamil pop, brass-driven\nfunk, Tamil pop, electronic\nfunk, Tamil pop, rock\nfunk, Thai fusion\nfunk, Turkish pop, electronic\nfunk, Turkish pop, groove\nfunk, Turkish soul, lo-fi\nfunk, UK hip-hop, neo-soul\nfunk, Vietnamese pop, retro\nfunk, West Coast, pop\nfunk, a cappella, Telugu pop\nfunk, a cappella, electronic\nfunk, accordion, Southern hip hop\nfunk, accordion, dance\nfunk, accordion, electronic\nfunk, accordion, fusion\nfunk, acid house, experimental\nfunk, acid jazz\nfunk, acid jazz, 80s\nfunk, acid jazz, Brazilian pop\nfunk, acid jazz, G-funk\nfunk, acid jazz, Latin\nfunk, acid jazz, Latin funk\nfunk, acid jazz, ambient\nfunk, acid jazz, big beat\nfunk, acid jazz, cinematic\nfunk, acid jazz, city pop\nfunk, acid jazz, dub\nfunk, acid jazz, electronic\nfunk, acid jazz, electronic breakbeat\nfunk, acid jazz, electronic lounge\nfunk, acid jazz, experimental electronic\nfunk, acid jazz, hip-hop\nfunk, acid jazz, industrial rock\nfunk, acid jazz, instrumental\nfunk, acid jazz, instrumental hip-hop\nfunk, acid jazz, live band\nfunk, acid jazz, lo-fi\nfunk, acid jazz, lounge\nfunk, acid jazz, neo-soul\nfunk, acid jazz, new jack swing\nfunk, acid jazz, nu-funk\nfunk, acid jazz, retro\nfunk, acid jazz, retro hip-hop\nfunk, acid jazz, samba-rock\nfunk, acid jazz, soul\nfunk, acid jazz, synth funk\nfunk, acid jazz, trip-hop\nfunk, acid jazz, video game music\nfunk, acid jazz, world fusion\nfunk, acid jazz, world music\nfunk, acoustic, blues\nfunk, afrobeat\nfunk, afrobeat, dance-pop\nfunk, afrobeat, electronic\nfunk, afrobeat, video game music\nfunk, alternative R&B, pop\nfunk, alternative dance\nfunk, alternative pop, trip-hop\nfunk, alternative pop, world music\nfunk, alternative rock, J-rock\nfunk, alternative rock, Russian choral\nfunk, ambient, Afro-funk\nfunk, ambient, Brazilian\nfunk, ambient, French synth\nfunk, ambient, Korean folk\nfunk, ambient, South Asian\nfunk, ambient, blues-rock\nfunk, ambient, breakbeat\nfunk, ambient, cinematic\nfunk, ambient, dream pop\nfunk, ambient, punk\nfunk, ambient, soul\nfunk, ambient, spiritual\nfunk, ambient, synthwave\nfunk, ambient, traditional\nfunk, ambient, world music\nfunk, anime, video game\nfunk, art-pop, experimental\nfunk, art-pop, new wave\nfunk, baroque pop, theatrical\nfunk, big band\nfunk, big band jazz\nfunk, big band jazz, Indian film music\nfunk, big band jazz, J-rock\nfunk, big band jazz, Korean traditional\nfunk, big band jazz, Latin soul\nfunk, big band jazz, South Indian film music\nfunk, big band jazz, chiptune\nfunk, big band jazz, electronic\nfunk, big band jazz, fusion\nfunk, big band jazz, hip-hop\nfunk, big band jazz, pop-rock\nfunk, big band jazz, progressive rock\nfunk, big band jazz, theatrical pop\nfunk, big band jazz, video game music\nfunk, big band jazz, world music\nfunk, big band, 70s TV theme\nfunk, big band, Afro-funk\nfunk, big band, Brazilian\nfunk, big band, C-pop\nfunk, big band, Christmas\nfunk, big band, French\nfunk, big band, French soul\nfunk, big band, G-funk\nfunk, big band, Gujarati soul\nfunk, big band, Hebrew soul\nfunk, big band, Italian\nfunk, big band, Italian soul\nfunk, big band, J-pop\nfunk, big band, Japanese pop\nfunk, big band, Japanese soul\nfunk, big band, K-funk\nfunk, big band, Latin\nfunk, big band, Latin funk\nfunk, big band, Latin jazz\nfunk, big band, Latin soul\nfunk, big band, Mandarin pop\nfunk, big band, Mandarin soul\nfunk, big band, Mandopop\nfunk, big band, New Orleans\nfunk, big band, New Orleans jazz\nfunk, big band, Portuguese\nfunk, big band, Southern soul\nfunk, big band, Tagalog pop\nfunk, big band, Thai hip hop\nfunk, big band, ambient\nfunk, big band, anthemic\nfunk, big band, blues\nfunk, big band, blues rock\nfunk, big band, blues-rock\nfunk, big band, boogie-woogie\nfunk, big band, brass band\nfunk, big band, cartoon\nfunk, big band, cinematic\nfunk, big band, dance\nfunk, big band, educational\nfunk, big band, electric guitar\nfunk, big band, experimental\nfunk, big band, free jazz\nfunk, big band, fusion\nfunk, big band, game show\nfunk, big band, gospel\nfunk, big band, groove\nfunk, big band, hip hop\nfunk, big band, hip-hop\nfunk, big band, hip-hop fusion\nfunk, big band, holiday\nfunk, big band, instrumental\nfunk, big band, instrumental fusion\nfunk, big band, jazz\nfunk, big band, jazz fusion\nfunk, big band, jazz rap\nfunk, big band, latin jazz\nfunk, big band, live\nfunk, big band, lo-fi\nfunk, big band, lo-fi hip hop\nfunk, big band, party\nfunk, big band, psychedelic\nfunk, big band, rap\nfunk, big band, retro\nfunk, big band, rock\nfunk, big band, rock fusion\nfunk, big band, ska\nfunk, big band, soul\nfunk, big band, spy movie\nfunk, big band, surf rock\nfunk, big band, synth\nfunk, big band, synthwave\nfunk, big band, theatrical\nfunk, big band, turntablism\nfunk, big band, video game soundtrack\nfunk, big band, vintage\nfunk, big beat\nfunk, big beat, Middle Eastern fusion\nfunk, big beat, Turkish pop\nfunk, big beat, acid house\nfunk, big beat, alternative hip-hop\nfunk, big beat, chiptune\nfunk, big beat, cinematic hip-hop\nfunk, big beat, electronic\nfunk, big beat, electronic dance music\nfunk, big beat, hip-hop\nfunk, big beat, house\nfunk, big beat, instrumental\nfunk, big beat, instrumental hip-hop\nfunk, big beat, party\nfunk, big beat, trip-hop\nfunk, big beat, turntablism\nfunk, big beat, video game music\nfunk, big beat, world music\nfunk, bluegrass, country funk\nfunk, blues, Indonesian pop\nfunk, blues, electronic\nfunk, blues, jazz fusion\nfunk, blues, live jazz\nfunk, blues, soul\nfunk, blues, synth pop\nfunk, blues-rock\nfunk, blues-rock, Indian classical\nfunk, blues-rock, novelty\nfunk, blues-rock, sci-fi\nfunk, boogie, 80s\nfunk, boogie, cinematic\nfunk, boogie, city pop\nfunk, boogie, new jack swing\nfunk, boogie, post-disco\nfunk, boogie, soul\nfunk, boogie, synth\nfunk, boogie, synth funk\nfunk, boogie-woogie, Hammond organ\nfunk, boogie-woogie, cinematic\nfunk, boogie-woogie, instrumental\nfunk, boogie-woogie, live soul\nfunk, boogie-woogie, retro\nfunk, boogie-woogie, second-line\nfunk, boogie-woogie, soul\nfunk, boogie-woogie, swing\nfunk, bossa nova, Brazilian\nfunk, bossa nova, instrumental\nfunk, bossa nova, pop\nfunk, brass band\nfunk, brass band, New Orleans\nfunk, brass band, hip hop\nfunk, brass band, second-line\nfunk, brass, Balkan\nfunk, brass, French pop\nfunk, brass, Latin\nfunk, brass, South Asian pop\nfunk, brass, accordion\nfunk, brass, drum and bass\nfunk, brass, party\nfunk, brass, rap\nfunk, brass, theatrical\nfunk, breakbeat\nfunk, breakbeat, Indian pop\nfunk, breakbeat, Latin hip hop\nfunk, breakbeat, R&B\nfunk, breakbeat, Russian pop\nfunk, breakbeat, acid jazz\nfunk, breakbeat, big band\nfunk, breakbeat, big beat\nfunk, breakbeat, dance\nfunk, breakbeat, electronic\nfunk, breakbeat, hip-hop\nfunk, breakbeat, hip-house\nfunk, breakbeat, instrumental hip-hop\nfunk, breakbeat, jazz fusion\nfunk, breakbeat, lo-fi\nfunk, breakbeat, retro\nfunk, breakbeat, retro-electro\nfunk, breakbeat, synthwave\nfunk, breakcore, synthwave\nfunk, brostep, R&B\nfunk, cabaret, psychedelic\nfunk, cartoon, synth\nfunk, chanson, Eastern European folk\nfunk, chanson, Latin\nfunk, chanson, cinematic\nfunk, children's music\nfunk, children's music, educational\nfunk, children's music, retro\nfunk, chillwave\nfunk, chillwave, lo-fi\nfunk, chiptune\nfunk, chiptune, Afro-Latin\nfunk, chiptune, Bollywood\nfunk, chiptune, Brazilian soul\nfunk, chiptune, Indian film music\nfunk, chiptune, Italian rap\nfunk, chiptune, Japanese video game\nfunk, chiptune, Latin\nfunk, chiptune, Latin electronic\nfunk, chiptune, Latin pop\nfunk, chiptune, R&B\nfunk, chiptune, Russian rap\nfunk, chiptune, breakbeat\nfunk, chiptune, electronic\nfunk, chiptune, experimental rock\nfunk, chiptune, gospel\nfunk, chiptune, jazz fusion\nfunk, chiptune, lo-fi\nfunk, chiptune, lo-fi hip hop\nfunk, chiptune, lounge\nfunk, chiptune, new jack swing\nfunk, chiptune, retro\nfunk, chiptune, retro game\nfunk, chiptune, soul\nfunk, chiptune, synthwave\nfunk, choral, theatrical\nfunk, cinematic, French pop\nfunk, cinematic, Italian soul\nfunk, cinematic, J-pop\nfunk, cinematic, Latin\nfunk, cinematic, Middle Eastern\nfunk, cinematic, Persian\nfunk, cinematic, Spanish hip hop\nfunk, cinematic, ambient\nfunk, cinematic, big band\nfunk, cinematic, bluegrass\nfunk, cinematic, disco\nfunk, cinematic, disco-funk\nfunk, cinematic, electronic\nfunk, cinematic, experimental\nfunk, cinematic, gospel\nfunk, cinematic, groove\nfunk, cinematic, hip hop\nfunk, cinematic, instrumental\nfunk, cinematic, jazz fusion\nfunk, cinematic, psychedelic\nfunk, cinematic, retro-soul\nfunk, cinematic, soul\nfunk, cinematic, synthwave\nfunk, cinematic, theatrical\nfunk, cinematic, tropical\nfunk, cinematic, vintage\nfunk, city pop\nfunk, city pop, J-funk\nfunk, city pop, J-pop\nfunk, city pop, Japanese funk\nfunk, city pop, K-pop\nfunk, city pop, acid jazz\nfunk, city pop, big band\nfunk, city pop, big band jazz\nfunk, city pop, disco\nfunk, city pop, fusion\nfunk, city pop, hip-hop\nfunk, city pop, instrumental\nfunk, city pop, jazz fusion\nfunk, city pop, lo-fi hip hop\nfunk, city pop, modern\nfunk, city pop, modern funk\nfunk, city pop, neo-soul\nfunk, city pop, new jack swing\nfunk, city pop, nu-disco\nfunk, city pop, retro\nfunk, city pop, smooth jazz\nfunk, city pop, synth funk\nfunk, city pop, synth fusion\nfunk, city pop, synth-funk\nfunk, city pop, synth-pop\nfunk, city pop, synthwave\nfunk, city pop, video game music\nfunk, city pop, video game soundtrack\nfunk, city-pop\nfunk, city-pop, Japanese pop\nfunk, city-pop, Mandarin pop\nfunk, city-pop, disco-funk\nfunk, city-pop, modern\nfunk, city-pop, retro\nfunk, city-pop, synth funk\nfunk, comedy\nfunk, comedy, acoustic\nfunk, conscious hip-hop\nfunk, country, pop\nfunk, country, upbeat\nfunk, cumbia, forró\nfunk, dance, 80s\nfunk, dance, Brazilian\nfunk, dance, Caribbean pop\nfunk, dance, German pop\nfunk, dance, Latin pop\nfunk, dance, accordion\nfunk, dance, brass\nfunk, dance, electronic\nfunk, dance, party\nfunk, dance, pop\nfunk, dance, reggae\nfunk, dance-pop, K-pop\nfunk, dance-pop, new jack swing\nfunk, dance-pop, retro\nfunk, dancehall, Latin pop\nfunk, dancehall, R&B\nfunk, dancehall, chiptune\nfunk, dancehall, electronic\nfunk, dancehall, synth pop\nfunk, dark pop\nfunk, devotional, retro electronic\nfunk, disco house\nfunk, disco, 80s\nfunk, disco, Anatolian folk\nfunk, disco, Bollywood filmi\nfunk, disco, Chinese folk\nfunk, disco, Christmas\nfunk, disco, French pop\nfunk, disco, Indian film music\nfunk, disco, Japanese hip-hop\nfunk, disco, K-pop\nfunk, disco, Latin\nfunk, disco, R&B\nfunk, disco, Romanian soul\nfunk, disco, South Asian pop\nfunk, disco, South Indian\nfunk, disco, acid jazz\nfunk, disco, big band\nfunk, disco, big band jazz\nfunk, disco, boogie\nfunk, disco, children's music\nfunk, disco, chiptune\nfunk, disco, city pop\nfunk, disco, classical\nfunk, disco, educational\nfunk, disco, electronic\nfunk, disco, gospel\nfunk, disco, hip-hop\nfunk, disco, house\nfunk, disco, jazz-fusion\nfunk, disco, modern\nfunk, disco, modern funk\nfunk, disco, pop\nfunk, disco, retro\nfunk, disco, retro pop\nfunk, disco, soul\nfunk, disco, synth-pop\nfunk, disco, synthwave\nfunk, disco, trip-hop\nfunk, disco, video game music\nfunk, disco-house\nfunk, disco-house, Latin\nfunk, disco-house, hip-hop\nfunk, disco-pop\nfunk, disco-pop, Brazilian funk\nfunk, disco-pop, R&B\nfunk, disco-pop, city pop\nfunk, disco-pop, hip-hop\nfunk, disco-pop, modern\nfunk, dream pop, electronic\nfunk, dream pop, synthwave\nfunk, dream-pop, electronic\nfunk, drum and bass, reggae\nfunk, dub, dancehall\nfunk, dub, hip-hop\nfunk, dub, instrumental\nfunk, dub, psychedelic\nfunk, dubstep, Balkan fusion\nfunk, dubstep, electronic\nfunk, educational, 80s pop\nfunk, educational, French\nfunk, educational, children's\nfunk, educational, children's music\nfunk, educational, disco\nfunk, educational, lo-fi\nfunk, educational, retro\nfunk, electro\nfunk, electro, 80s\nfunk, electro, boogie\nfunk, electro, experimental\nfunk, electro, house\nfunk, electro, retro\nfunk, electro-funk\nfunk, electro-funk, 80s\nfunk, electro-funk, 80s boogie\nfunk, electro-funk, Italo-disco\nfunk, electro-funk, big beat\nfunk, electro-funk, boogie\nfunk, electro-funk, disco\nfunk, electro-funk, hip-hop\nfunk, electro-funk, house\nfunk, electro-funk, new jack swing\nfunk, electro-funk, novelty hip-hop\nfunk, electro-funk, nu-disco\nfunk, electro-funk, retro\nfunk, electro-funk, retro 80s\nfunk, electro-funk, retro synth\nfunk, electro-funk, video game music\nfunk, electro-pop\nfunk, electronic\nfunk, electronic dance, South Asian fusion\nfunk, electronic lounge, retro-futuristic\nfunk, electronic pop, Chinese traditional\nfunk, electronic, 80s synth\nfunk, electronic, Afro-French\nfunk, electronic, Afro-Latin\nfunk, electronic, Afro-funk\nfunk, electronic, Balkan folk\nfunk, electronic, Balkan fusion\nfunk, electronic, Brazilian\nfunk, electronic, British rap\nfunk, electronic, Catalan pop\nfunk, electronic, Czech\nfunk, electronic, Dutch rap\nfunk, electronic, Finnish rap\nfunk, electronic, French hip hop\nfunk, electronic, French pop\nfunk, electronic, French rap\nfunk, electronic, French spoken word\nfunk, electronic, Galician pop\nfunk, electronic, German hip hop\nfunk, electronic, German pop\nfunk, electronic, German spoken word\nfunk, electronic, Greek rap\nfunk, electronic, Hebrew hip hop\nfunk, electronic, Indian folk\nfunk, electronic, Indian fusion\nfunk, electronic, Indian pop\nfunk, electronic, Italian\nfunk, electronic, Italian hip-hop\nfunk, electronic, Italian pop\nfunk, electronic, J-pop\nfunk, electronic, K-pop\nfunk, electronic, Latin\nfunk, electronic, Latin dance\nfunk, electronic, Latin hip hop\nfunk, electronic, Latin pop\nfunk, electronic, Mandarin hip hop\nfunk, electronic, Mandarin pop\nfunk, electronic, Middle Eastern\nfunk, electronic, Middle Eastern fusion\nfunk, electronic, North African pop\nfunk, electronic, Polish pop\nfunk, electronic, Portuguese pop\nfunk, electronic, R&B\nfunk, electronic, Russian\nfunk, electronic, Russian hip hop\nfunk, electronic, Russian soul\nfunk, electronic, South Asian fusion\nfunk, electronic, Tamil pop\nfunk, electronic, Telugu pop\nfunk, electronic, Tollywood\nfunk, electronic, Turkish pop\nfunk, electronic, UK rap\nfunk, electronic, Ukrainian pop\nfunk, electronic, aggressive\nfunk, electronic, alternative pop\nfunk, electronic, ambient\nfunk, electronic, chiptune\nfunk, electronic, cinematic\nfunk, electronic, dance\nfunk, electronic, disco\nfunk, electronic, dream pop\nfunk, electronic, experimental\nfunk, electronic, glitch\nfunk, electronic, guzheng\nfunk, electronic, hip hop\nfunk, electronic, hip-hop\nfunk, electronic, industrial\nfunk, electronic, instrumental\nfunk, electronic, jazz fusion\nfunk, electronic, lo-fi\nfunk, electronic, minimal\nfunk, electronic, modern\nfunk, electronic, narrative\nfunk, electronic, new jack swing\nfunk, electronic, paranoid\nfunk, electronic, polyrhythmic\nfunk, electronic, pop\nfunk, electronic, post-punk\nfunk, electronic, progressive\nfunk, electronic, rap\nfunk, electronic, retro\nfunk, electronic, retro-futuristic\nfunk, electronic, rock\nfunk, electronic, sci-fi\nfunk, electronic, soul\nfunk, electronic, spoken word\nfunk, electronic, synth groove\nfunk, electronic, synthpop\nfunk, electronic, synthwave\nfunk, electronic, theatrical\nfunk, electronic, tribal\nfunk, electronic, video game\nfunk, electronic, video game soundtrack\nfunk, electronic, vocal house\nfunk, electronic, world fusion\nfunk, electronic, world music\nfunk, ethereal, Sundanese pop\nfunk, experimental electronic, breakbeat\nfunk, experimental, Sinhala\nfunk, experimental, art pop\nfunk, experimental, gospel\nfunk, experimental, jazz\nfunk, experimental, lo-fi\nfunk, experimental, lo-fi hip hop\nfunk, experimental, soul\nfunk, experimental, synth\nfunk, experimental, world funk\nfunk, festive, world music\nfunk, flamenco, electronic\nfunk, flamenco, lo-fi hip hop\nfunk, flamenco, rap\nfunk, flamenco, spoken word\nfunk, flamenco, storytelling\nfunk, flamenco, world fusion\nfunk, folk fusion, Middle Eastern\nfunk, folk rock, Armenian pop\nfunk, folk rock, anthemic\nfunk, folk, electronic\nfunk, free jazz\nfunk, g-funk, acid jazz\nfunk, g-funk, retro\nfunk, g-funk, video game music\nfunk, glitch, electronic\nfunk, gospel R&B\nfunk, gospel, 80s boogie\nfunk, gospel, Christmas\nfunk, gospel, French soul\nfunk, gospel, electronic\nfunk, gospel, electronic dance\nfunk, gospel, pop-rock\nfunk, gospel, soul\nfunk, grime, electronic\nfunk, gypsy jazz, Balkan pop\nfunk, hip hop, Afrobeat\nfunk, hip hop, British rap\nfunk, hip hop, C-pop\nfunk, hip hop, Italian groove\nfunk, hip hop, Italian rap\nfunk, hip hop, K-funk\nfunk, hip hop, Latin\nfunk, hip hop, Mandarin pop\nfunk, hip hop, Mandarin rap\nfunk, hip hop, R&B\nfunk, hip hop, a cappella\nfunk, hip hop, bilingual\nfunk, hip hop, brass\nfunk, hip hop, electronic\nfunk, hip hop, glitch\nfunk, hip hop, gospel\nfunk, hip hop, groove\nfunk, hip hop, jazz\nfunk, hip hop, jazz noir\nfunk, hip hop, novelty\nfunk, hip hop, pop-R&B\nfunk, hip hop, retro\nfunk, hip hop, soul\nfunk, hip hop, synthwave\nfunk, hip hop, world fusion\nfunk, hip house, new jack swing\nfunk, hip-hop\nfunk, hip-hop, C-pop\nfunk, hip-hop, Christmas\nfunk, hip-hop, French pop\nfunk, hip-hop, G-funk\nfunk, hip-hop, Latin\nfunk, hip-hop, R&B\nfunk, hip-hop, acid jazz\nfunk, hip-hop, big beat\nfunk, hip-hop, brass band\nfunk, hip-hop, breakbeat\nfunk, hip-hop, chiptune\nfunk, hip-hop, disco-pop\nfunk, hip-hop, electronic\nfunk, hip-hop, experimental\nfunk, hip-hop, experimental electronic\nfunk, hip-hop, indie rock\nfunk, hip-hop, instrumental\nfunk, hip-hop, neo-soul\nfunk, hip-hop, retro\nfunk, hip-hop, soul\nfunk, hip-hop, synth funk\nfunk, hip-hop, synth house\nfunk, hip-hop, synthwave\nfunk, holiday, soul\nfunk, house, big beat\nfunk, house, new jack swing\nfunk, indie electronic\nfunk, indie pop, lounge\nfunk, indie pop, retro\nfunk, indie rock\nfunk, indie rock, French pop\nfunk, indie rock, UK hip-hop\nfunk, industrial, ambient\nfunk, instrumental hip-hop\nfunk, instrumental hip-hop, acid jazz\nfunk, instrumental, East-meets-West\nfunk, instrumental, ambient\nfunk, instrumental, latin\nfunk, jazz fusion\nfunk, jazz fusion, Hammond organ\nfunk, jazz fusion, Italian pop\nfunk, jazz fusion, Nintendocore\nfunk, jazz fusion, anime theme\nfunk, jazz fusion, chiptune\nfunk, jazz fusion, city pop\nfunk, jazz fusion, dance\nfunk, jazz fusion, electronic\nfunk, jazz fusion, electronic breakbeat\nfunk, jazz fusion, hip hop\nfunk, jazz fusion, progressive rock\nfunk, jazz fusion, retro video game\nfunk, jazz fusion, vaporwave\nfunk, jazz fusion, video game music\nfunk, jazz, Brazilian\nfunk, jazz, Brazilian pop\nfunk, jazz, French hip hop\nfunk, jazz, French pop\nfunk, jazz, French rap\nfunk, jazz, French spoken word\nfunk, jazz, Italian pop\nfunk, jazz, Latin\nfunk, jazz, Latin jazz\nfunk, jazz, South Indian folk\nfunk, jazz, Tamil fusion\nfunk, jazz, ambient\nfunk, jazz, brass\nfunk, jazz, chiptune\nfunk, jazz, cinematic\nfunk, jazz, electronic\nfunk, jazz, free jazz\nfunk, jazz, hip hop\nfunk, jazz, hip-hop\nfunk, jazz, instrumental\nfunk, jazz, lo-fi\nfunk, jazz, retro lounge\nfunk, jazz, soul\nfunk, jazz, spoken word\nfunk, jazz, world music\nfunk, jazz-funk\nfunk, jungle, spoken word\nfunk, klezmer, Balkan folk\nfunk, klezmer, Portuguese\nfunk, klezmer, big band\nfunk, klezmer, rock\nfunk, klezmer, theatrical rap\nfunk, klezmer, urban\nfunk, latin funk\nfunk, latin funk, boogaloo\nfunk, latin funk, boogie-woogie\nfunk, latin funk, lo-fi hip hop\nfunk, latin funk, new jack swing\nfunk, latin jazz-funk\nfunk, latin soul\nfunk, latin, afro-cuban\nfunk, latin, big band\nfunk, latin, brass\nfunk, latin, dance\nfunk, latin, electric guitar\nfunk, latin, electronic\nfunk, latin, flamenco\nfunk, latin, groove\nfunk, latin, instrumental\nfunk, latin, jazz\nfunk, latin, live\nfunk, latin, psychedelic\nfunk, latin, soul\nfunk, latin, upbeat\nfunk, live, accordion\nfunk, lo-fi hip hop\nfunk, lo-fi hip hop, Afrofusion\nfunk, lo-fi hip hop, soul\nfunk, lo-fi hip hop, synth funk\nfunk, lo-fi, Arabic hip hop\nfunk, lo-fi, Brazilian\nfunk, lo-fi, Brazilian hip hop\nfunk, lo-fi, Japanese pop\nfunk, lo-fi, ambient\nfunk, lo-fi, art-rock\nfunk, lo-fi, chiptune\nfunk, lo-fi, electronic\nfunk, lo-fi, gospel\nfunk, lo-fi, nu-jazz\nfunk, lo-fi, psychedelic\nfunk, lo-fi, sample-based\nfunk, lo-fi, soul\nfunk, lo-fi, synth\nfunk, lo-fi, synth pop\nfunk, lo-fi, synthwave\nfunk, lo-fi, vintage\nfunk, lounge, Latin pop\nfunk, lounge, electronic\nfunk, lounge, narrative pop\nfunk, lounge, retro\nfunk, lounge, satire\nfunk, lounge, synthwave\nfunk, lounge, tropical\nfunk, mambo, Christmas\nfunk, math rock, jazz fusion\nfunk, math rock, video game music\nfunk, melancholic pop\nfunk, minimalist, electronic\nfunk, minimalist, lo-fi\nfunk, modern funk, disco\nfunk, modern, trap-influenced\nfunk, neo-classical, video game\nfunk, neo-soul\nfunk, neo-soul, Brazilian\nfunk, neo-soul, California vibe\nfunk, neo-soul, Christmas\nfunk, neo-soul, G-funk\nfunk, neo-soul, Latin jazz\nfunk, neo-soul, MPB\nfunk, neo-soul, R&B\nfunk, neo-soul, acid jazz\nfunk, neo-soul, big beat\nfunk, neo-soul, boom-bap\nfunk, neo-soul, city pop\nfunk, neo-soul, disco\nfunk, neo-soul, drum and bass\nfunk, neo-soul, electronic\nfunk, neo-soul, electronic pop\nfunk, neo-soul, free jazz\nfunk, neo-soul, gospel\nfunk, neo-soul, hip hop\nfunk, neo-soul, hip-hop\nfunk, neo-soul, indie pop\nfunk, neo-soul, instrumental\nfunk, neo-soul, instrumental hip-hop\nfunk, neo-soul, instrumental pop\nfunk, neo-soul, jazz fusion\nfunk, neo-soul, lo-fi\nfunk, neo-soul, lo-fi hip hop\nfunk, neo-soul, lo-fi hip-hop\nfunk, neo-soul, lounge jazz\nfunk, neo-soul, pop\nfunk, neo-soul, retro\nfunk, neo-soul, smooth jazz\nfunk, neo-soul, synth-funk\nfunk, neo-soul, trip-hop\nfunk, neo-soul, vaporwave\nfunk, neo-soul, video game music\nfunk, neo-soul, world fusion\nfunk, neo-soul, world music\nfunk, new jack swing\nfunk, new jack swing, 80s\nfunk, new jack swing, 80s boogie\nfunk, new jack swing, 80s instrumental\nfunk, new jack swing, French pop\nfunk, new jack swing, K-funk\nfunk, new jack swing, R&B\nfunk, new jack swing, atmospheric\nfunk, new jack swing, big band jazz\nfunk, new jack swing, boogie\nfunk, new jack swing, cinematic\nfunk, new jack swing, city pop\nfunk, new jack swing, early house\nfunk, new jack swing, g-funk\nfunk, new jack swing, hip hop\nfunk, new jack swing, hip-hop\nfunk, new jack swing, instrumental\nfunk, new jack swing, pop-R&B\nfunk, new jack swing, pop-funk\nfunk, new jack swing, retro\nfunk, new jack swing, retro-futuristic\nfunk, new jack swing, soul\nfunk, new jack swing, synth funk\nfunk, new jack swing, synthwave\nfunk, new jack swing, video game\nfunk, new jack swing, video game music\nfunk, new jack swing, zouk\nfunk, new wave\nfunk, new wave, chiptune\nfunk, new wave, synth funk\nfunk, new wave, synth pop\nfunk, noir-jazz, C-pop\nfunk, novelty, electronic\nfunk, novelty, hip hop\nfunk, nu-disco\nfunk, nu-disco, G-funk\nfunk, nu-disco, R&B\nfunk, nu-disco, city pop\nfunk, nu-disco, electronic\nfunk, nu-disco, neo-soul\nfunk, nu-disco, psychedelic\nfunk, nu-disco, retro\nfunk, nu-disco, synthwave\nfunk, nu-disco, turntablism\nfunk, nu-funk\nfunk, nu-funk, acid jazz\nfunk, old-school hip-hop\nfunk, oud, jazz fusion\nfunk, oud, soul\nfunk, pagode, Brazilian\nfunk, party, New Orleans\nfunk, party, accordion\nfunk, party, world fusion\nfunk, playful, lullaby\nfunk, political rap, soul\nfunk, polka, dance\nfunk, pop, Brazilian\nfunk, pop, Indian film music\nfunk, pop, R&B\nfunk, pop, South Asian folk\nfunk, pop, South Indian\nfunk, pop, South Indian film music\nfunk, pop, electronic\nfunk, pop, new wave\nfunk, pop, turntablism\nfunk, pop-R&B, K-pop\nfunk, pop-funk, retro\nfunk, pop-rock, Balkan folk\nfunk, pop-rock, North African fusion\nfunk, pop-rock, electronic\nfunk, post-disco, 80s boogie\nfunk, post-disco, boogie\nfunk, post-punk\nfunk, post-punk, disco\nfunk, post-punk, indie rock\nfunk, post-punk, lo-fi\nfunk, post-punk, new wave\nfunk, progressive rock, math rock\nfunk, protest music, worldbeat\nfunk, protest, Balkan-funk\nfunk, proto-punk\nfunk, psychedelic rock\nfunk, psychedelic rock, French chanson\nfunk, psychedelic rock, electronic\nfunk, psychedelic rock, lo-fi\nfunk, psychedelic rock, progressive rock\nfunk, psychedelic rock, synth pop\nfunk, psychedelic rock, world fusion\nfunk, psychedelic soul\nfunk, psychedelic, Brazilian\nfunk, psychedelic, French spoken word\nfunk, psychedelic, Latin\nfunk, psychedelic, Turkish soul\nfunk, psychedelic, ambient\nfunk, psychedelic, bossa nova\nfunk, psychedelic, electronic\nfunk, psychedelic, hip hop\nfunk, psychedelic, instrumental\nfunk, psychedelic, jazz fusion\nfunk, psychedelic, lo-fi\nfunk, psychedelic, samba\nfunk, psychedelic, soul\nfunk, psychedelic, surf rock\nfunk, psychedelic, synth\nfunk, quirky, accordion\nfunk, ragtime, big band\nfunk, ragtime, electronic\nfunk, ragtime, retro\nfunk, reggae, French pop\nfunk, reggae, Latin\nfunk, reggae, R&B\nfunk, reggae, electronic\nfunk, reggae, hip hop\nfunk, reggae, pop\nfunk, reggae, ska\nfunk, reggae, spoken word\nfunk, reggaeton, lo-fi\nfunk, regional Mexican, live jam\nfunk, retro disco\nfunk, retro disco, acid jazz\nfunk, retro electronic, Portuguese pop\nfunk, retro electronic, video game music\nfunk, retro hip-hop\nfunk, retro swing, futuristic\nfunk, retro synth\nfunk, retro synth, soul\nfunk, retro synth, video game\nfunk, retro video game\nfunk, retro video game, G-funk\nfunk, retro video game, anime soundtrack\nfunk, retro video game, chiptune\nfunk, retro video game, city pop\nfunk, retro video game, instrumental\nfunk, retro video game, lo-fi\nfunk, retro video game, new jack swing\nfunk, retro video game, nu-disco\nfunk, retro video game, playful\nfunk, retro video game, synth\nfunk, retro video game, synthwave\nfunk, retro, Brazilian\nfunk, retro, Caribbean\nfunk, retro, Christmas\nfunk, retro, French pop\nfunk, retro, German pop\nfunk, retro, Indian film music\nfunk, retro, Italian\nfunk, retro, Latin\nfunk, retro, Mandopop\nfunk, retro, Portuguese pop\nfunk, retro, Portuguese soul\nfunk, retro, R&B\nfunk, retro, South Asian pop\nfunk, retro, Soviet-era estrada\nfunk, retro, Taiwanese Hokkien\nfunk, retro, big-band\nfunk, retro, bilingual\nfunk, retro, boogie\nfunk, retro, cabaret\nfunk, retro, children's music\nfunk, retro, chiptune\nfunk, retro, cinematic\nfunk, retro, city pop\nfunk, retro, city-pop\nfunk, retro, comedy\nfunk, retro, dance\nfunk, retro, disco\nfunk, retro, electronic\nfunk, retro, hip hop\nfunk, retro, hip-hop\nfunk, retro, jazz\nfunk, retro, lounge\nfunk, retro, new jack swing\nfunk, retro, nu-disco\nfunk, retro, pop\nfunk, retro, pop-funk\nfunk, retro, soul\nfunk, retro, spy theme\nfunk, retro, synth\nfunk, retro, synth funk\nfunk, retro, synth-pop\nfunk, retro, synthwave\nfunk, retro, video game\nfunk, retro, workout\nfunk, retro-futuristic, French pop\nfunk, retro-futuristic, R&B\nfunk, retro-futuristic, chiptune\nfunk, retro-futuristic, electronic\nfunk, retro-futuristic, hip-hop\nfunk, retro-futuristic, instrumental\nfunk, retro-futuristic, jazz\nfunk, retro-futuristic, new jack swing\nfunk, retro-futuristic, nu-disco\nfunk, retro-futuristic, synth\nfunk, retro-futuristic, synthwave\nfunk, retro-futuristic, video game\nfunk, retro-modern, chiptune\nfunk, retro-soul\nfunk, retro-soul, disco\nfunk, retro-soul, modern\nfunk, ritualistic, political\nfunk, robotic, retro-futuristic\nfunk, sacred, Polish\nfunk, salsa, hip hop\nfunk, samba, hip-hop\nfunk, samba, jazz\nfunk, samba, party\nfunk, samba, retro electronic\nfunk, samba, surf rock\nfunk, samba-pop\nfunk, sci-fi, electro-pop\nfunk, sci-fi, electronic\nfunk, sci-fi, jazz-soul\nfunk, sci-fi, novelty\nfunk, sci-fi, retro-futuristic\nfunk, second-line, New Orleans\nfunk, second-line, brass\nfunk, ska, Latin\nfunk, ska, big band\nfunk, ska, dancehall\nfunk, ska, soul\nfunk, ska-punk, protest music\nfunk, ska-punk, swing\nfunk, smooth jazz\nfunk, smooth jazz, New Jack Swing\nfunk, smooth jazz, R&B\nfunk, smooth jazz, electronic\nfunk, smooth jazz, fusion\nfunk, smooth jazz, lounge\nfunk, smooth jazz, retro video game\nfunk, smooth jazz, soul\nfunk, smooth jazz, synth fusion\nfunk, smooth jazz, world fusion\nfunk, soul jazz, blues rock\nfunk, soul, 80s boogie\nfunk, soul, Afrobeat\nfunk, soul, Arabic pop\nfunk, soul, Brazilian\nfunk, soul, Brazilian jazz\nfunk, soul, Christmas\nfunk, soul, Christmas blues\nfunk, soul, French pop\nfunk, soul, Hebrew indie\nfunk, soul, Italian\nfunk, soul, Italian pop\nfunk, soul, Italian rap\nfunk, soul, J-pop\nfunk, soul, Latin\nfunk, soul, Latin jazz\nfunk, soul, Latin percussion\nfunk, soul, Latin pop\nfunk, soul, Latin soul\nfunk, soul, MPB\nfunk, soul, New Orleans funk\nfunk, soul, R&B\nfunk, soul, Russian hip hop\nfunk, soul, South Asian fusion\nfunk, soul, Turkish pop\nfunk, soul, acid jazz\nfunk, soul, ambient\nfunk, soul, big band\nfunk, soul, big band jazz\nfunk, soul, boogaloo\nfunk, soul, boogie\nfunk, soul, children's music\nfunk, soul, city pop\nfunk, soul, disco\nfunk, soul, educational\nfunk, soul, electronic\nfunk, soul, experimental\nfunk, soul, hip hop\nfunk, soul, hip-hop\nfunk, soul, instrumental rock\nfunk, soul, jazz\nfunk, soul, jazz fusion\nfunk, soul, live performance\nfunk, soul, pop-R&B\nfunk, soul, progressive rock\nfunk, soul, psychedelic\nfunk, soul, psychedelic funk\nfunk, soul, punk rock\nfunk, soul, retro\nfunk, soul, retro-futuristic\nfunk, soul, southern blues\nfunk, soul, spoken word\nfunk, soul, synthwave\nfunk, soul, world fusion\nfunk, soul, world music\nfunk, soul-jazz\nfunk, soul-jazz, Hammond B3\nfunk, soul-jazz, Hammond organ\nfunk, soul-jazz, big band\nfunk, soul-jazz, electronic\nfunk, soul-jazz, live\nfunk, soul-jazz, smooth jazz\nfunk, soulful pop, hip-hop\nfunk, southern funk, dance\nfunk, spiritual, lo-fi\nfunk, spoken word, soul\nfunk, spooky, soul\nfunk, spooky, synthpop\nfunk, spy theme, psychedelic\nfunk, surf rock, French pop\nfunk, surf rock, Indian pop\nfunk, surf rock, South Indian pop\nfunk, surf rock, Tamil pop\nfunk, surf rock, balkan brass\nfunk, surf rock, chiptune\nfunk, surf rock, cinematic\nfunk, surf rock, jazz fusion\nfunk, surf rock, quirky\nfunk, surf rock, world music\nfunk, surreal, Turkish spoken word\nfunk, synth funk, 80s retro\nfunk, synth funk, G-funk\nfunk, synth funk, chiptune\nfunk, synth funk, city pop\nfunk, synth funk, electronic\nfunk, synth funk, retro\nfunk, synth funk, retro electronic\nfunk, synth funk, retro-futuristic\nfunk, synth pop\nfunk, synth pop, J-pop\nfunk, synth pop, emotional\nfunk, synth pop, retro\nfunk, synth pop, soul\nfunk, synth, 80s\nfunk, synth, chiptune\nfunk, synth, electronic\nfunk, synth, instrumental\nfunk, synth, jazz\nfunk, synth, new jack swing\nfunk, synth, tropical\nfunk, synth, vaporwave\nfunk, synth-funk\nfunk, synth-funk, 80s\nfunk, synth-funk, Afro-funk\nfunk, synth-funk, French pop\nfunk, synth-funk, boogie\nfunk, synth-funk, city pop\nfunk, synth-funk, new jack swing\nfunk, synth-funk, nu-disco\nfunk, synth-funk, post-punk\nfunk, synth-funk, retro\nfunk, synth-pop\nfunk, synth-pop, 80s R&B\nfunk, synth-pop, Arabic pop\nfunk, synth-pop, ambient\nfunk, synth-pop, anthemic\nfunk, synth-pop, boogie\nfunk, synth-pop, chiptune\nfunk, synth-pop, hip-hop\nfunk, synth-pop, retro-futuristic\nfunk, synth-pop, video game\nfunk, synth-rock, ambient\nfunk, synthpop, 80s\nfunk, synthwave, 80s\nfunk, synthwave, 80s retro\nfunk, synthwave, 80s video game\nfunk, synthwave, Brazilian funk\nfunk, synthwave, French electronic\nfunk, synthwave, G-funk\nfunk, synthwave, Italian pop\nfunk, synthwave, Japanese fusion\nfunk, synthwave, Japanese video game\nfunk, synthwave, Latin\nfunk, synthwave, Latin funk\nfunk, synthwave, Latin percussion\nfunk, synthwave, Latin pop\nfunk, synthwave, Tamil pop\nfunk, synthwave, ambient\nfunk, synthwave, anime\nfunk, synthwave, blues rock\nfunk, synthwave, boogie\nfunk, synthwave, chiptune\nfunk, synthwave, cinematic\nfunk, synthwave, city pop\nfunk, synthwave, city-pop\nfunk, synthwave, dream pop\nfunk, synthwave, electro\nfunk, synthwave, electronic\nfunk, synthwave, electropop\nfunk, synthwave, ethereal\nfunk, synthwave, experimental\nfunk, synthwave, lo-fi\nfunk, synthwave, lo-fi hip hop\nfunk, synthwave, lounge\nfunk, synthwave, new jack swing\nfunk, synthwave, pop\nfunk, synthwave, post-punk\nfunk, synthwave, psychedelic\nfunk, synthwave, retro\nfunk, synthwave, retro electronic\nfunk, synthwave, retro game\nfunk, synthwave, retro pop\nfunk, synthwave, retro sci-fi\nfunk, synthwave, retro video game\nfunk, synthwave, retro-electro\nfunk, synthwave, retro-futuristic\nfunk, synthwave, soul\nfunk, synthwave, video game\nfunk, synthwave, video game music\nfunk, theatrical pop\nfunk, theatrical pop, electronic\nfunk, theatrical, Mandarin pop\nfunk, theatrical, brass\nfunk, theatrical, calypso\nfunk, theatrical, campy\nfunk, theatrical, electronic\nfunk, theatrical, narrative\nfunk, trap, breakcore\nfunk, trap, lo-fi\nfunk, tribal, French pop\nfunk, tribal, electronic\nfunk, tribal, soul\nfunk, trip-hop\nfunk, trip-hop, Latin soul\nfunk, trip-hop, Middle Eastern\nfunk, trip-hop, acid jazz\nfunk, trip-hop, alternative pop\nfunk, trip-hop, conscious hip-hop\nfunk, trip-hop, experimental\nfunk, trip-hop, experimental electronic\nfunk, trip-hop, instrumental electronic\nfunk, tropical house\nfunk, tropical house, instrumental\nfunk, trot\nfunk, turntablism, slap bass\nfunk, vaporwave, Arabic pop\nfunk, vaporwave, electronic\nfunk, vaporwave, retro-futuristic\nfunk, video game music\nfunk, video game music, jazz fusion\nfunk, video game music, retro\nfunk, video game music, world percussion\nfunk, video game soundtrack, Japanese\nfunk, video game soundtrack, lo-fi\nfunk, video game, synth pop\nfunk, video game, synthwave\nfunk, vintage, soul\nfunk, vocal jazz, hip hop\nfunk, vocal jazz, live performance\nfunk, vocal jazz, lo-fi hip hop\nfunk, vocal percussion, ambient\nfunk, world fusion\nfunk, world fusion, Latin\nfunk, world fusion, ambient\nfunk, world fusion, cinematic\nfunk, world fusion, dance\nfunk, world fusion, deep house\nfunk, world fusion, electronic\nfunk, world fusion, lo-fi\nfunk, world fusion, soul\nfunk, world fusion, upbeat\nfunk, world fusion, video game music\nfunk, world music\nfunk, world music, Arabic folk\nfunk, world music, French pop\nfunk, world music, Indian devotional\nfunk, world music, Latin\nfunk, world music, South Asian pop\nfunk, world music, alternative rock\nfunk, world music, ambient\nfunk, world music, chiptune\nfunk, world music, electronic\nfunk, world music, instrumental\nfunk, world music, live performance\nfunk, world music, lo-fi\nfunk, world music, lo-fi hip hop\nfunk, world music, old-school hip-hop\nfunk, world music, psychedelic\nfunk, world music, psychedelic pop\nfunk, world music, psychedelic rock\nfunk, world music, soul\nfunk, world music, synth groove\nfunk, world music, synthwave\nfunk, world music, theatrical pop\nfunk, world music, video game orchestral\nfunk, world, ambient\nfunk, world, instrumental\nfunk, worldbeat, 80s dance\nfunk, worldbeat, lounge\nfunk-blues\nfunk-breakbeat\nfunk-cumbia\nfunk-dance\nfunk-dangdut\nfunk-disco\nfunk-disco Mandopop\nfunk-disco, Indian fusion, electronic\nfunk-disco, chiptune, Greek pop\nfunk-disco, cinematic, orchestral\nfunk-disco, city pop, lo-fi\nfunk-disco, new wave, Eastern European\nfunk-electronic\nfunk-fusion\nfunk-fusion, city pop\nfunk-fusion, city pop, video game soundtrack\nfunk-gospel\nfunk-hop\nfunk-hop Balkan brass\nfunk-hop Bollywood\nfunk-hop Latin\nfunk-hop acid jazz\nfunk-hop big band jazz\nfunk-hop electronic\nfunk-hop experimental\nfunk-hop fusion\nfunk-hop jazz\nfunk-hop jazz-funk\nfunk-hop klezmer\nfunk-hop lo-fi\nfunk-hop soul\nfunk-hop, Greek rap, cinematic\nfunk-hop, bass music\nfunk-house\nfunk-infused breakbeat\nfunk-infused electronic\nfunk-infused electronic pop\nfunk-infused electronica\nfunk-infused hip-hop\nfunk-infused house\nfunk-jazz\nfunk-jazz fusion\nfunk-jazz hip-hop\nfunk-jazz rap\nfunk-latin\nfunk-metal\nfunk-metal alternative rock\nfunk-metal punk rock\nfunk-metal rap-rock\nfunk-metal ska-punk\nfunk-metal, Japanese rock\nfunk-pop\nfunk-pop 80s\nfunk-pop 80s anime\nfunk-pop 80s fusion\nfunk-pop Anatolian rock\nfunk-pop Bollywood\nfunk-pop C-pop\nfunk-pop Indian fusion\nfunk-pop J-pop\nfunk-pop J-pop K-pop\nfunk-pop J-pop anime\nfunk-pop J-pop disco\nfunk-pop J-rock\nfunk-pop K-R&B\nfunk-pop K-pop\nfunk-pop Kollywood\nfunk-pop Latin\nfunk-pop Latin jazz\nfunk-pop Latin pop\nfunk-pop Mandopop\nfunk-pop R&B\nfunk-pop R&B hip-hop\nfunk-pop acid jazz\nfunk-pop acoustic pop\nfunk-pop alternative hip-hop\nfunk-pop alternative rock\nfunk-pop alternative rock electronic\nfunk-pop anime\nfunk-pop bossa nova\nfunk-pop breakbeat\nfunk-pop children's\nfunk-pop children's music\nfunk-pop chiptune\nfunk-pop cinematic\nfunk-pop city pop\nfunk-pop city pop J-funk\nfunk-pop city pop J-pop\nfunk-pop city pop J-rock\nfunk-pop city pop acid jazz\nfunk-pop city pop anime\nfunk-pop city pop jazz fusion\nfunk-pop city pop neo-soul\nfunk-pop city pop smooth jazz\nfunk-pop city-pop\nfunk-pop cyberpunk\nfunk-pop dance-rock\nfunk-pop disco\nfunk-pop disco city pop\nfunk-pop disco-rock\nfunk-pop electro-funk\nfunk-pop electro-house\nfunk-pop future bass\nfunk-pop gospel\nfunk-pop hip-hop\nfunk-pop house\nfunk-pop indie pop\nfunk-pop indie-pop\nfunk-pop j-pop anime\nfunk-pop j-pop city pop\nfunk-pop j-pop video game\nfunk-pop j-rock\nfunk-pop jazz\nfunk-pop jazz fusion\nfunk-pop jazz fusion chiptune\nfunk-pop jazz fusion city pop\nfunk-pop kuthu\nfunk-pop latin\nfunk-pop lo-fi\nfunk-pop lo-fi hip hop\nfunk-pop lounge\nfunk-pop lounge-jazz\nfunk-pop metalcore\nfunk-pop neo-soul\nfunk-pop neo-soul acid jazz\nfunk-pop neo-soul city pop\nfunk-pop neo-soul lounge\nfunk-pop new jack swing\nfunk-pop new wave\nfunk-pop novelty\nfunk-pop nu-disco\nfunk-pop nu-disco city pop\nfunk-pop orchestral disco\nfunk-pop psychedelic soul\nfunk-pop reggae\nfunk-pop reggaeton chiptune\nfunk-pop reggaeton hip-hop\nfunk-pop reggaeton pop-rock\nfunk-pop retro\nfunk-pop rock\nfunk-pop schlager\nfunk-pop ska\nfunk-pop smooth jazz\nfunk-pop soul\nfunk-pop trap\nfunk-pop trap R&B\nfunk-pop tropical\nfunk-pop tropical house\nfunk-pop vaporwave\nfunk-pop world fusion\nfunk-pop world music\nfunk-pop worldbeat\nfunk-pop worship\nfunk-pop, Balkan brass\nfunk-pop, Balkan fusion\nfunk-pop, Bollywood, Bhangra\nfunk-pop, Bollywood, big band\nfunk-pop, Bollywood, chiptune\nfunk-pop, Bollywood, dance\nfunk-pop, Bollywood, electronic\nfunk-pop, Bollywood, hip-hop\nfunk-pop, Bollywood, lo-fi\nfunk-pop, Bollywood, rap\nfunk-pop, Bollywood, soul\nfunk-pop, Brazilian, upbeat\nfunk-pop, C-pop, electronic\nfunk-pop, Central Asian pop\nfunk-pop, Chinese folk, hip-hop\nfunk-pop, Chinese fusion\nfunk-pop, East Asian fusion\nfunk-pop, East Asian, instrumental\nfunk-pop, Indian folk\nfunk-pop, Indian fusion\nfunk-pop, Indian fusion, pop-R&B\nfunk-pop, Italian disco, theatrical\nfunk-pop, J-pop, city pop\nfunk-pop, J-pop, video game\nfunk-pop, J-rock, Eurodance, synthwave, Schlagerpop, German hip-hop\nfunk-pop, J-rock, video game music\nfunk-pop, K-pop\nfunk-pop, Latin jazz, Sinhala pop\nfunk-pop, Latin jazz, soul\nfunk-pop, Latin pop, rock\nfunk-pop, Latin rock\nfunk-pop, Latin, upbeat\nfunk-pop, Latin, vibrant\nfunk-pop, MPB\nfunk-pop, Middle Eastern fusion\nfunk-pop, Neue Deutsche Welle\nfunk-pop, North African, live\nfunk-pop, North African, traditional fusion\nfunk-pop, R&B\nfunk-pop, R&B, Bollywood\nfunk-pop, R&B, Vietnamese soul\nfunk-pop, R&B, ambient\nfunk-pop, R&B, city pop\nfunk-pop, Russian folk\nfunk-pop, South Asian folk\nfunk-pop, South Asian fusion\nfunk-pop, South Asian pop\nfunk-pop, South Indian film music\nfunk-pop, South Indian folk\nfunk-pop, South Indian fusion\nfunk-pop, South Indian pop\nfunk-pop, South Indian pop, disco\nfunk-pop, South Indian, live concert\nfunk-pop, Southeast Asian folk\nfunk-pop, Tamil Kuthu\nfunk-pop, Turkish hip-hop\nfunk-pop, acid jazz, city pop\nfunk-pop, big band jazz\nfunk-pop, big band jazz, Cantopop\nfunk-pop, big band jazz, Taiwanese Hokkien\nfunk-pop, big band jazz, hip-hop\nfunk-pop, big band, cinematic\nfunk-pop, big band, hip-hop\nfunk-pop, big band, jazz\nfunk-pop, big band, swing\nfunk-pop, chiptune, pop-rock\nfunk-pop, chiptune, retro-futuristic\nfunk-pop, cinematic rock\nfunk-pop, cinematic, C-pop\nfunk-pop, cinematic, Turkish folk\nfunk-pop, cinematic, electronic\nfunk-pop, city pop\nfunk-pop, city pop, 80s\nfunk-pop, city pop, 80s J-funk\nfunk-pop, city pop, 90s\nfunk-pop, city pop, 90s K-pop\nfunk-pop, city pop, K-pop\nfunk-pop, city pop, R&B\nfunk-pop, city pop, Shibuya-kei\nfunk-pop, city pop, anime\nfunk-pop, city pop, anime theme\nfunk-pop, city pop, indie pop\nfunk-pop, city pop, jazz fusion\nfunk-pop, city pop, jazzy\nfunk-pop, city pop, neo-soul\nfunk-pop, city pop, new jack swing\nfunk-pop, city pop, nu-disco\nfunk-pop, city pop, retro\nfunk-pop, city pop, retro-disco\nfunk-pop, city pop, retro-futuristic\nfunk-pop, city-pop\nfunk-pop, city-pop, Mandarin pop\nfunk-pop, city-pop, Mandarin rap\nfunk-pop, city-pop, cinematic\nfunk-pop, city-pop, electronic\nfunk-pop, city-pop, hip-hop\nfunk-pop, city-pop, neo-soul\nfunk-pop, city-pop, nu-disco\nfunk-pop, dance-pop, a cappella\nfunk-pop, disco, indie-pop\nfunk-pop, disco-house, novelty\nfunk-pop, electronic, Bengali hip hop\nfunk-pop, gospel, disco\nfunk-pop, hard rock, ambient\nfunk-pop, hard rock, synth-pop, surf-rock\nfunk-pop, hip-hop\nfunk-pop, hip-hop, city pop\nfunk-pop, hip-hop, musical theater\nfunk-pop, industrial, chiptune\nfunk-pop, jazz fusion\nfunk-pop, jazz lounge\nfunk-pop, kuthu, Tamil fusion\nfunk-pop, lo-fi hip-hop\nfunk-pop, lo-fi hip-hop, ambient\nfunk-pop, lo-fi, Chinese soul\nfunk-pop, lo-fi, Russian hip hop\nfunk-pop, lo-fi, city-pop\nfunk-pop, neo-soul, city pop\nfunk-pop, neo-soul, retro synth\nfunk-pop, new jack swing\nfunk-pop, new jack swing, 80s pop\nfunk-pop, new jack swing, G-funk\nfunk-pop, new jack swing, city pop\nfunk-pop, new wave\nfunk-pop, nu-disco, city pop\nfunk-pop, raï, North African fusion\nfunk-pop, retro Bollywood\nfunk-pop, retro Indian film music\nfunk-pop, retro K-pop\nfunk-pop, retro disco, city pop\nfunk-pop, retro disco, future funk\nfunk-pop, retro, chiptune\nfunk-pop, retro-futuristic, K-pop\nfunk-pop, synth-pop, 80s\nfunk-pop, theatrical, jazz\nfunk-pop, theatrical, political\nfunk-pop, theatrical, soul\nfunk-pop, trap, R&B\nfunk-pop, trap, dubstep\nfunk-pop, trip-hop\nfunk-pop, zouk, Caribbean\nfunk-punk\nfunk-punk rock\nfunk-punk thrash metal\nfunk-punk, psychedelic rock, experimental\nfunk-rap\nfunk-rap alternative rock\nfunk-rap nu-metal\nfunk-rap nu-metal emo-rock\nfunk-rap salsa\nfunk-rap samba\nfunk-rap, C-pop, lo-fi hip hop\nfunk-rap, J-pop, hip-hop\nfunk-rap, Latin hip-hop\nfunk-rap, R&B, synth pop\nfunk-rap, big band swing\nfunk-rap, big-band, hip-hop\nfunk-rap, cinematic, Cantonese hip-hop\nfunk-rap, city-pop\nfunk-rap, city-pop, retro-futuristic\nfunk-rap, dancehall, Polish hip hop\nfunk-rap, hip-hop, electronic\nfunk-reggae\nfunk-reggae chanson\nfunk-reggae fusion\nfunk-reggae hip-hop\nfunk-reggae lo-fi\nfunk-reggae pop-punk\nfunk-reggae punk rock\nfunk-reggae rock\nfunk-reggae, lo-fi hip hop, global fusion\nfunk-rock\nfunk-rock 80s anime\nfunk-rock 90s alternative\nfunk-rock Afro-Cuban\nfunk-rock Afrobeat\nfunk-rock Anatolian rock\nfunk-rock Arabic fusion\nfunk-rock Arabic hip-hop\nfunk-rock Arabic pop\nfunk-rock Bollywood\nfunk-rock C-pop\nfunk-rock C-pop retro\nfunk-rock Indian folk\nfunk-rock Indian fusion\nfunk-rock Indian pop\nfunk-rock J-hip-hop\nfunk-rock J-pop\nfunk-rock J-rock\nfunk-rock K-pop\nfunk-rock Latin\nfunk-rock Latin jazz\nfunk-rock Latin rock\nfunk-rock R&B\nfunk-rock acid jazz\nfunk-rock alt-rock\nfunk-rock alternative\nfunk-rock alternative dance\nfunk-rock alternative electronic\nfunk-rock alternative hip-hop\nfunk-rock alternative metal\nfunk-rock alternative pop\nfunk-rock alternative pop electronic\nfunk-rock alternative punk\nfunk-rock alternative rock\nfunk-rock americana\nfunk-rock anime\nfunk-rock anime theme\nfunk-rock avant-garde jazz\nfunk-rock ballad\nfunk-rock bhangra\nfunk-rock big band\nfunk-rock big band pop\nfunk-rock big beat\nfunk-rock bluegrass\nfunk-rock blues\nfunk-rock blues-rock\nfunk-rock boogie-woogie\nfunk-rock breakbeat\nfunk-rock cabaret\nfunk-rock cabaret jazz\nfunk-rock cantopop\nfunk-rock children's\nfunk-rock children's music\nfunk-rock chiptune\nfunk-rock chiptune Latin\nfunk-rock chiptune breakbeat\nfunk-rock chiptune electronic\nfunk-rock chiptune experimental\nfunk-rock chiptune math rock\nfunk-rock chiptune progressive\nfunk-rock chiptune synth-pop\nfunk-rock city pop\nfunk-rock city pop fusion\nfunk-rock city pop jazz fusion\nfunk-rock classical\nfunk-rock comedy\nfunk-rock comedy rap\nfunk-rock country\nfunk-rock country-blues\nfunk-rock country-rock\nfunk-rock cumbia\nfunk-rock cumbia Latin\nfunk-rock dance\nfunk-rock dance-pop\nfunk-rock dance-punk\nfunk-rock dancehall\nfunk-rock disco\nfunk-rock disco-funk\nfunk-rock disco-pop\nfunk-rock drum and bass\nfunk-rock dubstep\nfunk-rock electro-funk\nfunk-rock electro-house\nfunk-rock electro-pop\nfunk-rock electronic\nfunk-rock electronic chiptune\nfunk-rock electronic hip-hop\nfunk-rock electronic pop\nfunk-rock electronic psychedelic\nfunk-rock experimental\nfunk-rock experimental hip-hop\nfunk-rock experimental pop\nfunk-rock flamenco\nfunk-rock free-jazz\nfunk-rock fusion\nfunk-rock garage rock\nfunk-rock glam\nfunk-rock glam-rock\nfunk-rock gospel\nfunk-rock gospel R&B\nfunk-rock gospel pop\nfunk-rock gospel-pop\nfunk-rock hard rock\nfunk-rock hardcore punk\nfunk-rock hip hop\nfunk-rock hip-hop\nfunk-rock hip-hop big band\nfunk-rock hip-hop electronic\nfunk-rock hip-hop experimental\nfunk-rock hip-hop noise-rock\nfunk-rock hip-hop soul\nfunk-rock hip-hop world music\nfunk-rock hip-house\nfunk-rock hyper-pop\nfunk-rock hyperpop\nfunk-rock indie pop\nfunk-rock industrial\nfunk-rock italo-disco\nfunk-rock j-pop\nfunk-rock j-pop anime\nfunk-rock j-rock\nfunk-rock jazz\nfunk-rock jazz fusion\nfunk-rock jazz fusion chiptune\nfunk-rock jazz fusion progressive\nfunk-rock jazz swing\nfunk-rock jazz-fusion\nfunk-rock jazz-metal\nfunk-rock jazz-pop\nfunk-rock jazz-rock\nfunk-rock klezmer\nfunk-rock klezmer-punk\nfunk-rock kuthu\nfunk-rock latin\nfunk-rock latin dance\nfunk-rock latin pop\nfunk-rock latin rock\nfunk-rock lo-fi\nfunk-rock lounge jazz\nfunk-rock mandopop\nfunk-rock mariachi punk\nfunk-rock math rock\nfunk-rock math-rock\nfunk-rock metal\nfunk-rock metalcore\nfunk-rock musical\nfunk-rock neo-soul\nfunk-rock neo-soul acid jazz\nfunk-rock neo-soul psychedelic\nfunk-rock new wave\nfunk-rock noise rock\nfunk-rock noise-rock\nfunk-rock novelty\nfunk-rock nu-metal\nfunk-rock opera\nfunk-rock polka\nfunk-rock pop\nfunk-rock pop-R&B\nfunk-rock pop-metal\nfunk-rock pop-punk\nfunk-rock pop-rap\nfunk-rock post-hardcore\nfunk-rock post-punk\nfunk-rock power-pop\nfunk-rock progressive electronic\nfunk-rock progressive metal\nfunk-rock progressive rock\nfunk-rock progressive video game\nfunk-rock protest\nfunk-rock psychedelic\nfunk-rock psychedelic alternative\nfunk-rock psychedelic pop\nfunk-rock psychedelic punk\nfunk-rock psychedelic reggae\nfunk-rock psychedelic rock\nfunk-rock punk\nfunk-rock punk metal\nfunk-rock rap\nfunk-rock rap-metal\nfunk-rock rap-rock\nfunk-rock reggae\nfunk-rock reggae Latin\nfunk-rock reggae Middle Eastern\nfunk-rock reggae chiptune\nfunk-rock reggae dancehall\nfunk-rock reggae fusion\nfunk-rock reggae hip-hop\nfunk-rock reggae psychedelic\nfunk-rock reggae-metal\nfunk-rock retro-futuristic\nfunk-rock rumba flamenca\nfunk-rock salsa\nfunk-rock samba\nfunk-rock samba-reggae\nfunk-rock samba-rock\nfunk-rock satire\nfunk-rock schlager\nfunk-rock sci-fi\nfunk-rock ska\nfunk-rock ska Latin\nfunk-rock ska big band\nfunk-rock ska reggae\nfunk-rock ska-punk\nfunk-rock ska-punk big band\nfunk-rock ska-rap\nfunk-rock soul\nfunk-rock soul gospel\nfunk-rock soul jazz\nfunk-rock soul pop\nfunk-rock southern rock\nfunk-rock surf rock\nfunk-rock surf-pop\nfunk-rock surf-rock\nfunk-rock synth-pop\nfunk-rock synth-pop psychedelic\nfunk-rock synth-rock\nfunk-rock tango klezmer\nfunk-rock theatrical pop\nfunk-rock thrash metal\nfunk-rock trip-hop\nfunk-rock tropical\nfunk-rock turbo-folk\nfunk-rock world fusion\nfunk-rock world music\nfunk-rock worldbeat\nfunk-rock worship\nfunk-rock zouk\nfunk-rock zydeco\nfunk-rock, 80s new wave\nfunk-rock, Anatolian rock\nfunk-rock, Anatolian rock, chiptune\nfunk-rock, Anatolian rock, fusion\nfunk-rock, Anatolian rock, groove\nfunk-rock, Arabic fusion\nfunk-rock, Arabic fusion, electronic\nfunk-rock, Arabic fusion, soul\nfunk-rock, Arabic hip hop, punk\nfunk-rock, Arabic pop, psychedelic rock\nfunk-rock, Azerbaijani, fusion\nfunk-rock, Balkan brass\nfunk-rock, Balkan brass, jazz fusion\nfunk-rock, Balkan dance\nfunk-rock, Balkan folk\nfunk-rock, Balkan folk, chiptune\nfunk-rock, Balkan folk, rap\nfunk-rock, Balkan party\nfunk-rock, Balkan pop\nfunk-rock, Balkan rock\nfunk-rock, Balkan turbo-folk\nfunk-rock, Balkan, Klezmer\nfunk-rock, Balkan, live energy\nfunk-rock, Bengali folk\nfunk-rock, Bengali pop\nfunk-rock, Bollywood dance-pop\nfunk-rock, Bollywood disco, boogie-woogie\nfunk-rock, Bollywood pop\nfunk-rock, Bollywood pop, R&B\nfunk-rock, Bollywood, anthem\nfunk-rock, Bollywood, chiptune\nfunk-rock, Bollywood, cinematic\nfunk-rock, Bollywood, dance\nfunk-rock, Bollywood, eclectic\nfunk-rock, Bollywood, electronic\nfunk-rock, Bollywood, energetic\nfunk-rock, Bollywood, fusion\nfunk-rock, Bollywood, hip-hop\nfunk-rock, Bollywood, party\nfunk-rock, Bollywood, rock\nfunk-rock, Bollywood, vintage\nfunk-rock, Brazilian hip-hop\nfunk-rock, Brazilian pop\nfunk-rock, Brazilian pop, electronic\nfunk-rock, Brazilian pop-rock\nfunk-rock, Brazilian, Afro-Latin\nfunk-rock, Brazilian, energetic\nfunk-rock, Brazilian, groove\nfunk-rock, Brazilian, upbeat\nfunk-rock, C-pop, electronic\nfunk-rock, C-pop, experimental\nfunk-rock, C-pop, fusion\nfunk-rock, C-pop, synth ballad\nfunk-rock, C-pop, traditional Chinese\nfunk-rock, Cantopop\nfunk-rock, Carnatic music\nfunk-rock, Carnatic, fusion\nfunk-rock, Central Asian pop\nfunk-rock, Chinese New Year, energetic\nfunk-rock, Chinese folk, C-pop\nfunk-rock, Chinese folk, blues\nfunk-rock, Chinese folk, blues-rock\nfunk-rock, Chinese folk, electronic\nfunk-rock, Chinese folk, fusion\nfunk-rock, Chinese folk, quirky fusion\nfunk-rock, Chinese fusion\nfunk-rock, Chinese fusion, instrumental\nfunk-rock, Chinese fusion, modern rock\nfunk-rock, Chinese opera, modern fusion\nfunk-rock, Christian pop-rock\nfunk-rock, Christian rock, Latin rock\nfunk-rock, Christian worship, rock\nfunk-rock, City Pop, theatrical\nfunk-rock, Filipino, upbeat\nfunk-rock, Finnish hip-hop\nfunk-rock, French new wave\nfunk-rock, French pop, 80s\nfunk-rock, German hip-hop\nfunk-rock, German rap\nfunk-rock, German rap, free-jazz\nfunk-rock, Greek folk, dance\nfunk-rock, Greek pop\nfunk-rock, Greek rock\nfunk-rock, Greek, energetic\nfunk-rock, Indian classical\nfunk-rock, Indian classical, blues-rock\nfunk-rock, Indian classical, folk fusion\nfunk-rock, Indian classical, fusion\nfunk-rock, Indian classical, live\nfunk-rock, Indian classical, world music\nfunk-rock, Indian devotional, fusion\nfunk-rock, Indian film music\nfunk-rock, Indian film music, political anthem\nfunk-rock, Indian folk\nfunk-rock, Indian folk, Bollywood\nfunk-rock, Indian folk, big band\nfunk-rock, Indian folk, fusion\nfunk-rock, Indian folk, hard rock\nfunk-rock, Indian folk, progressive rock\nfunk-rock, Indian folk, rock\nfunk-rock, Indian folk-pop\nfunk-rock, Indian fusion\nfunk-rock, Indian fusion, rock\nfunk-rock, Indian hip-hop, Western hip-hop\nfunk-rock, Indian pop\nfunk-rock, Indian pop, hard rock\nfunk-rock, Indian pop, hip-hop\nfunk-rock, Indian pop-rock\nfunk-rock, Indonesian pop\nfunk-rock, Indonesian traditional\nfunk-rock, Israeli pop, late 70s\nfunk-rock, Italian hip-hop\nfunk-rock, J-funk, city pop\nfunk-rock, J-pop, alternative rock\nfunk-rock, J-rap\nfunk-rock, J-rock\nfunk-rock, J-rock, Vocaloid\nfunk-rock, J-rock, anime\nfunk-rock, J-rock, anime theme\nfunk-rock, J-rock, chiptune\nfunk-rock, J-rock, cinematic\nfunk-rock, J-rock, electronic\nfunk-rock, J-rock, explosive\nfunk-rock, J-rock, high-energy\nfunk-rock, J-rock, hip-hop\nfunk-rock, J-rock, instrumental\nfunk-rock, J-rock, metalcore\nfunk-rock, J-rock, rap-rock\nfunk-rock, J-rock, synth-heavy\nfunk-rock, Japanese hip-hop\nfunk-rock, Japanese hip-hop, chiptune\nfunk-rock, Japanese punk\nfunk-rock, Japanese rap\nfunk-rock, Japanese rap, electronic\nfunk-rock, Japanese rock, post-hardcore\nfunk-rock, Japanese traditional, fusion\nfunk-rock, Javanese hip-hop, chiptune\nfunk-rock, Javanese pop\nfunk-rock, Javanese, fusion\nfunk-rock, K-pop\nfunk-rock, K-pop, R&B\nfunk-rock, K-pop, hip-hop\nfunk-rock, K-pop, retro\nfunk-rock, Kayōkyoku\nfunk-rock, Kizomba\nfunk-rock, Latin acoustic\nfunk-rock, Latin big band\nfunk-rock, Latin big band, eclectic\nfunk-rock, Latin brass, rap\nfunk-rock, Latin cumbia\nfunk-rock, Latin dance, electronic\nfunk-rock, Latin fusion, eclectic\nfunk-rock, Latin hip-hop, R&B\nfunk-rock, Latin hip-hop, eclectic\nfunk-rock, Latin jazz\nfunk-rock, Latin party\nfunk-rock, Latin party, J-pop\nfunk-rock, Latin percussion, C-pop\nfunk-rock, Latin percussion, Nepali rock\nfunk-rock, Latin percussion, explosive\nfunk-rock, Latin percussion, jazz fusion\nfunk-rock, Latin percussion, rap\nfunk-rock, Latin percussion, retro synth\nfunk-rock, Latin pop\nfunk-rock, Latin pop, Afro-Latin\nfunk-rock, Latin pop, Bengali pop\nfunk-rock, Latin pop, chiptune\nfunk-rock, Latin pop, hip-hop\nfunk-rock, Latin pop, hyperpop\nfunk-rock, Latin rap\nfunk-rock, Latin rock\nfunk-rock, Latin rock, hard rock\nfunk-rock, Latin rock, hip-hop\nfunk-rock, Latin ska\nfunk-rock, Latin ska, chiptune\nfunk-rock, Latin ska, fusion\nfunk-rock, Latin ska, hip-hop\nfunk-rock, Latin soul\nfunk-rock, Latin, Balkan\nfunk-rock, Latin, Indonesian\nfunk-rock, Latin, accordion\nfunk-rock, Latin, acoustic\nfunk-rock, Latin, electronic\nfunk-rock, Latin, flamenco\nfunk-rock, Latin, fusion\nfunk-rock, Latin, hip-hop\nfunk-rock, Latin, live\nfunk-rock, Latin, party\nfunk-rock, Latin, psychedelic\nfunk-rock, Latin, ska\nfunk-rock, Latin, soul\nfunk-rock, Latin, theatrical\nfunk-rock, Latin, upbeat\nfunk-rock, Latin, world music\nfunk-rock, Latin-jazz, noise-rock\nfunk-rock, MPB\nfunk-rock, MPB, Brazilian\nfunk-rock, MPB, spiritual\nfunk-rock, Malay traditional\nfunk-rock, Middle Eastern folk\nfunk-rock, Middle Eastern fusion\nfunk-rock, Middle Eastern fusion, hip-hop\nfunk-rock, Middle Eastern pop\nfunk-rock, Middle Eastern, Balkan\nfunk-rock, Middle Eastern, Latin\nfunk-rock, Middle Eastern, electronic dance\nfunk-rock, Middle Eastern, energetic\nfunk-rock, Middle Eastern, fusion\nfunk-rock, Middle Eastern, groove\nfunk-rock, Middle Eastern, rock\nfunk-rock, Middle Eastern, satirical\nfunk-rock, Mizrahi pop\nfunk-rock, Neapolitan, rock\nfunk-rock, Nepali folk\nfunk-rock, Nepali folk-pop\nfunk-rock, Neue Deutsche Welle\nfunk-rock, New Orleans jam-band\nfunk-rock, New Orleans jazz\nfunk-rock, North African fusion\nfunk-rock, Persian pop\nfunk-rock, Persian, Middle Eastern\nfunk-rock, Polish hip-hop\nfunk-rock, Polish rock, vintage\nfunk-rock, Punjabi folk\nfunk-rock, Punjabi folk, fusion\nfunk-rock, Punjabi pop\nfunk-rock, R&B, ambient\nfunk-rock, R&B, chiptune\nfunk-rock, R&B, cinematic\nfunk-rock, R&B, modern\nfunk-rock, R&B, rap\nfunk-rock, Russian estrada, pop\nfunk-rock, Russian folk, fusion\nfunk-rock, South Asian devotional\nfunk-rock, South Asian folk\nfunk-rock, South Asian folk, theatrical\nfunk-rock, South Asian fusion\nfunk-rock, South Asian pop\nfunk-rock, South Asian pop-rock\nfunk-rock, South Indian film music\nfunk-rock, South Indian fusion\nfunk-rock, South Indian hip-hop\nfunk-rock, South Indian pop\nfunk-rock, Southern rock\nfunk-rock, Soviet Estrada\nfunk-rock, Soviet pop-rock\nfunk-rock, Sufi music\nfunk-rock, Sufi, blues-rock\nfunk-rock, Sufi-inspired\nfunk-rock, Tamil Christian, devotional\nfunk-rock, Tamil hip-hop\nfunk-rock, Tamil pop\nfunk-rock, Tamil pop, experimental\nfunk-rock, Tamil rap, cinematic\nfunk-rock, Telugu rap, R&B\nfunk-rock, Turkish dance-pop, hip-hop\nfunk-rock, Turkish folk\nfunk-rock, Turkish pop\nfunk-rock, UK hip-hop\nfunk-rock, UK indie, jazzy\nfunk-rock, a cappella, ancient style\nfunk-rock, acid jazz, city pop\nfunk-rock, acid jazz, electronic rock\nfunk-rock, acoustic pop/R&B\nfunk-rock, alt-rock, psychedelic\nfunk-rock, alternative dance\nfunk-rock, alternative hip-hop, drum and bass\nfunk-rock, alternative hip-hop, garage rock\nfunk-rock, alternative metal, Greek rock\nfunk-rock, alternative punk, J-rock\nfunk-rock, alternative rock, glitch\nfunk-rock, alternative, hip-hop\nfunk-rock, ambient, Indian classical\nfunk-rock, ambient, hyperpop\nfunk-rock, ambient, new-age\nfunk-rock, anthemic rock\nfunk-rock, art-pop\nfunk-rock, art-rock, soul\nfunk-rock, baroque pop, Indian fusion\nfunk-rock, big band\nfunk-rock, big band jazz\nfunk-rock, big band jazz fusion\nfunk-rock, big band jazz, Arabic fusion\nfunk-rock, big band jazz, Italian rap\nfunk-rock, big band jazz, Latin fusion\nfunk-rock, big band jazz, Middle Eastern\nfunk-rock, big band jazz, chiptune\nfunk-rock, big band jazz, hip-hop\nfunk-rock, big band jazz, narrative rock\nfunk-rock, big band pop\nfunk-rock, big band swing\nfunk-rock, big band swing, chiptune\nfunk-rock, big band, Chinese fusion\nfunk-rock, big band, Japanese hip-hop\nfunk-rock, big band, Latin jazz\nfunk-rock, big band, Middle Eastern\nfunk-rock, big band, anime theme\nfunk-rock, big band, blues rock\nfunk-rock, big band, boogie-woogie\nfunk-rock, big band, brass\nfunk-rock, big band, brass fusion\nfunk-rock, big band, chiptune\nfunk-rock, big band, free jazz\nfunk-rock, big band, hip hop\nfunk-rock, big band, hip-hop\nfunk-rock, big band, jazz fusion\nfunk-rock, big band, live energy\nfunk-rock, big band, party\nfunk-rock, big band, rebellious\nfunk-rock, big band, retro swing\nfunk-rock, big band, rock\nfunk-rock, big band, southern rock\nfunk-rock, big band, swing\nfunk-rock, big band, theatrical\nfunk-rock, big beat, J-rock\nfunk-rock, big beat, electronic\nfunk-rock, big beat, electronica\nfunk-rock, big beat, rap-rock\nfunk-rock, big beat, turntablism\nfunk-rock, blues rock, Latin rock\nfunk-rock, blues rock, cinematic ballad\nfunk-rock, blues-rock, Indian classical\nfunk-rock, blues-rock, New Orleans\nfunk-rock, blues-rock, cinematic\nfunk-rock, breakbeat, electronic\nfunk-rock, breakbeat, electronica\nfunk-rock, breakcore, ambient\nfunk-rock, brostep, EDM\nfunk-rock, cajun, New Orleans\nfunk-rock, chiptune, C-pop\nfunk-rock, chiptune, Japanese video game music\nfunk-rock, chiptune, anime\nfunk-rock, chiptune, hard rock\nfunk-rock, chiptune, hip hop\nfunk-rock, chiptune, noise-rock\nfunk-rock, chiptune, video game music\nfunk-rock, cinematic rock\nfunk-rock, cinematic rock, orchestral\nfunk-rock, cinematic rock, soul\nfunk-rock, cinematic, Chinese opera\nfunk-rock, cinematic, Hebrew rap\nfunk-rock, cinematic, Southeast Asian fusion\nfunk-rock, cinematic, electronic\nfunk-rock, cinematic, jazz\nfunk-rock, cinematic, lo-fi hip hop\nfunk-rock, cinematic, noir\nfunk-rock, cinematic, orchestral\nfunk-rock, cinematic, psychedelic\nfunk-rock, cinematic, rock\nfunk-rock, cinematic, soul\nfunk-rock, cinematic, theatrical\nfunk-rock, cinematic, world fusion\nfunk-rock, cinematic, world music\nfunk-rock, city pop\nfunk-rock, city pop, 80s\nfunk-rock, city pop, 80s Japanese\nfunk-rock, city pop, Japanese\nfunk-rock, city pop, acid jazz\nfunk-rock, city pop, anime\nfunk-rock, city pop, anime theme\nfunk-rock, city pop, cinematic\nfunk-rock, city pop, jazz fusion\nfunk-rock, city pop, math rock\nfunk-rock, city pop, video game music\nfunk-rock, city pop, video game soundtrack\nfunk-rock, city-pop, fusion\nfunk-rock, city-pop, retro\nfunk-rock, cloud rap, jazz fusion\nfunk-rock, conscious hip-hop\nfunk-rock, conscious hip-hop, R&B\nfunk-rock, conscious hip-hop, jazz fusion\nfunk-rock, dangdut\nfunk-rock, dangdut, rock\nfunk-rock, desert blues\nfunk-rock, devotional, South Asian fusion\nfunk-rock, digital hardcore, chiptune\nfunk-rock, disco, Soviet pop\nfunk-rock, disco, Soviet-era\nfunk-rock, disco-funk, novelty rock\nfunk-rock, dream pop, punk\nfunk-rock, dream-pop, industrial rock\nfunk-rock, drum and bass, psychedelic\nfunk-rock, drum and bass, shoegaze\nfunk-rock, electronic dance, fusion\nfunk-rock, electronic dance, hip-hop\nfunk-rock, electronic dance, rap\nfunk-rock, electronic dance, video game\nfunk-rock, electronic rock, cinematic\nfunk-rock, electronic, Czech rap\nfunk-rock, electronic, Mandarin pop\nfunk-rock, electronic, industrial\nfunk-rock, electronic, spoken word\nfunk-rock, ethereal, cinematic\nfunk-rock, eurodance\nfunk-rock, experimental electronic\nfunk-rock, experimental electronica\nfunk-rock, experimental hip-hop\nfunk-rock, experimental pop, industrial rock\nfunk-rock, experimental, breakcore\nfunk-rock, experimental, electronic\nfunk-rock, folk, klezmer\nfunk-rock, free-jazz, disco-funk, hip-hop\nfunk-rock, gospel, J-rock\nfunk-rock, gospel, blues-rock\nfunk-rock, gospel, flamenco\nfunk-rock, gospel, soul\nfunk-rock, happy hardcore, J-core\nfunk-rock, hard rock\nfunk-rock, hard rock, C-pop\nfunk-rock, hard rock, blues-rock\nfunk-rock, hard rock, cinematic\nfunk-rock, hard rock, heavy metal\nfunk-rock, hard rock, hip-hop\nfunk-rock, hard rock, jazz-funk\nfunk-rock, hard rock, metal\nfunk-rock, hard rock, metalcore\nfunk-rock, hard rock, psychedelic rock\nfunk-rock, hardcore, hardstyle\nfunk-rock, heavy metal\nfunk-rock, heavy metal, ambient\nfunk-rock, heavy metal, shred guitar\nfunk-rock, hip hop, Mandarin rap\nfunk-rock, hip hop, cinematic\nfunk-rock, hip-hop, Cantonese\nfunk-rock, hip-hop, Chinese\nfunk-rock, hip-hop, Hebrew rap\nfunk-rock, hip-hop, Indonesian pop\nfunk-rock, hip-hop, Latin pop\nfunk-rock, hip-hop, Mandarin rap\nfunk-rock, hip-hop, South Asian rock\nfunk-rock, hip-hop, West Coast\nfunk-rock, hip-hop, alternative rock\nfunk-rock, hip-hop, big beat\nfunk-rock, hip-hop, electronic\nfunk-rock, hip-hop, folk\nfunk-rock, hip-hop, pop\nfunk-rock, hip-hop, pop-rock\nfunk-rock, hip-hop, punk-rap\nfunk-rock, hip-hop, rock\nfunk-rock, hip-hop, soul\nfunk-rock, hyper-pop\nfunk-rock, indie rock, neo-soul\nfunk-rock, indie-pop\nfunk-rock, industrial rock, dance-punk\nfunk-rock, industrial rock, rap\nfunk-rock, industrial, Russian spoken word\nfunk-rock, industrial, hip-hop\nfunk-rock, jazz fusion, Bollywood pop\nfunk-rock, jazz fusion, breakbeat\nfunk-rock, jazz, Tamil hip hop\nfunk-rock, jazz-fusion, cinematic\nfunk-rock, jazz-fusion, soul\nfunk-rock, jazz-lounge, punk\nfunk-rock, klezmer pop\nfunk-rock, klezmer, Greek rap\nfunk-rock, klezmer, surf rock\nfunk-rock, kuthu, fusion\nfunk-rock, latin percussion, rap\nfunk-rock, laïko, fusion\nfunk-rock, lo-fi hip hop, psychedelic\nfunk-rock, lo-fi hip hop, punk rock\nfunk-rock, lo-fi hip hop, rock\nfunk-rock, lo-fi hip-hop\nfunk-rock, lo-fi hip-hop, cinematic\nfunk-rock, lo-fi, free jazz\nfunk-rock, lo-fi, jazz\nfunk-rock, lounge-jazz, bossa nova\nfunk-rock, math-rock, Korean spoken word\nfunk-rock, metal, punk\nfunk-rock, metalcore, J-pop\nfunk-rock, metalcore, ambient\nfunk-rock, metalcore, indie rock\nfunk-rock, musical theater\nfunk-rock, musical theater, electronic\nfunk-rock, neo-soul\nfunk-rock, neo-soul, ambient R&B\nfunk-rock, neo-soul, cinematic\nfunk-rock, new jack swing\nfunk-rock, new jack swing, pop-rock\nfunk-rock, new jack swing, retro\nfunk-rock, new jack swing, synth funk\nfunk-rock, new wave\nfunk-rock, new wave, 1980s\nfunk-rock, new wave, Eastern European\nfunk-rock, new wave, Soviet-era\nfunk-rock, new wave, post-punk\nfunk-rock, noise rock, alt-rock\nfunk-rock, noise-rock\nfunk-rock, nu-metal\nfunk-rock, nu-metal, big band jazz\nfunk-rock, nu-metal, hip-hop\nfunk-rock, old-school hip-hop\nfunk-rock, orchestral, cinematic\nfunk-rock, orchestral, electronic\nfunk-rock, orchestral, video game\nfunk-rock, orchestral, video game music\nfunk-rock, political hip-hop, alternative rock\nfunk-rock, political rap\nfunk-rock, pop-funk, Arabic hip-hop\nfunk-rock, pop-punk, alternative rock\nfunk-rock, pop-rock, Mandarin pop\nfunk-rock, pop-rock, electronic\nfunk-rock, post-hardcore, cinematic\nfunk-rock, post-punk, Eastern European\nfunk-rock, post-punk, Soviet-era\nfunk-rock, power ballad\nfunk-rock, progressive J-rock\nfunk-rock, progressive hip-hop\nfunk-rock, progressive rock, J-pop\nfunk-rock, progressive rock, jazz fusion\nfunk-rock, protest anthem, Indian cinematic\nfunk-rock, protest, Middle Eastern\nfunk-rock, protest, free-jazz\nfunk-rock, protest, jazz\nfunk-rock, psychedelic disco, late-70s\nfunk-rock, psychedelic electronica\nfunk-rock, psychedelic funk, ska-punk\nfunk-rock, psychedelic indie-pop, noise-rock\nfunk-rock, psychedelic rock\nfunk-rock, psychedelic rock, Latin rock\nfunk-rock, psychedelic rock, Latin soul\nfunk-rock, psychedelic rock, Persian rock\nfunk-rock, psychedelic rock, Turkish jazz\nfunk-rock, psychedelic rock, experimental\nfunk-rock, psychedelic rock, hard rock\nfunk-rock, psychedelic rock, soul\nfunk-rock, psychedelic soul\nfunk-rock, psychedelic, Italian rap\nfunk-rock, psychedelic, Latin\nfunk-rock, psychedelic, Middle Eastern\nfunk-rock, psychedelic, blues-rock\nfunk-rock, psychedelic, experimental\nfunk-rock, psychedelic, jazz-fusion\nfunk-rock, psychedelic, new wave\nfunk-rock, psychedelic, noise rock\nfunk-rock, psychedelic, surf-rock\nfunk-rock, psychedelic, synth-pop\nfunk-rock, punk rock, cinematic\nfunk-rock, punk rock, ska-funk\nfunk-rock, punk-rock, noise-rock\nfunk-rock, rap-rock\nfunk-rock, rap-rock, Japanese\nfunk-rock, rap-rock, Latin rock\nfunk-rock, rap-rock, Punjabi fusion\nfunk-rock, rap-rock, alternative\nfunk-rock, rap-rock, hard rock\nfunk-rock, rap-rock, industrial\nfunk-rock, rap-rock, psychedelic rock\nfunk-rock, reggae, Latin fusion\nfunk-rock, reggae, Persian\nfunk-rock, retro Bollywood\nfunk-rock, retro Korean rock, 80s rock\nfunk-rock, retro hip-hop, C-pop\nfunk-rock, retro, military\nfunk-rock, revolutionary anthem\nfunk-rock, salsa, orchestral\nfunk-rock, sci-fi rap, genre-bending\nfunk-rock, shoegaze, K-pop\nfunk-rock, ska, Latin hip hop\nfunk-rock, skate punk\nfunk-rock, soul, Christmas\nfunk-rock, soul, acid jazz\nfunk-rock, soul, blues-rock\nfunk-rock, soul, jazz-fusion\nfunk-rock, soul, synthwave\nfunk-rock, soul, theatrical\nfunk-rock, soul-funk, psychedelic rock\nfunk-rock, southern rock\nfunk-rock, spiritual, world fusion\nfunk-rock, surf rock, Balkan brass\nfunk-rock, surf-rock\nfunk-rock, surf-rock, rock\nfunk-rock, synth-pop, Chinese rock\nfunk-rock, synthwave, bilingual\nfunk-rock, tarantella, live energy\nfunk-rock, theatrical cabaret, boogie-woogie\nfunk-rock, theatrical pop\nfunk-rock, theatrical punk, jazz fusion\nfunk-rock, theatrical rock, Hebrew rock\nfunk-rock, theatrical, gospel\nfunk-rock, theatrical, musical theater\nfunk-rock, theatrical, narrative\nfunk-rock, theatrical, show tune\nfunk-rock, theatrical, soul\nfunk-rock, theatrical, trot\nfunk-rock, trap R&B, Chinese hip hop\nfunk-rock, trap, ambient piano\nfunk-rock, tribal fusion, electronic\nfunk-rock, trot\nfunk-rock, turntablism, Latin hip hop\nfunk-rock, turntablism, experimental hip-hop\nfunk-rock, turntablism, hip-hop\nfunk-rock, turntablism, nu-metal\nfunk-rock, turntablism, rock\nfunk-rock, turntablism, world music\nfunk-rock, video game music\nfunk-rock, video game music, Japanese synth\nfunk-rock, video game music, cinematic\nfunk-rock, video game music, synthwave\nfunk-rock, vintage Indonesian pop\nfunk-rock, world fusion\nfunk-rock, world music\nfunk-rock, world music, C-pop\nfunk-rock, world music, Latin\nfunk-rock, world music, chiptune\nfunk-rock, world music, electronic\nfunk-rock, world music, energetic\nfunk-rock, world music, experimental\nfunk-rock, world music, fusion\nfunk-rock, world music, hip-hop\nfunk-rock, world music, instrumental\nfunk-rock, world music, klezmer\nfunk-rock, world music, progressive rock\nfunk-rock, world music, psychedelic\nfunk-samba\nfunk-ska\nfunk-ska electro-rock\nfunk-soca\nfunk-soul\nfunk-soul UK hip-hop\nfunk-soul city pop\nfunk-soul disco\nfunk-soul electronic\nfunk-soul exotica\nfunk-soul hip-hop\nfunk-soul reggae\nfunk-soul rock\nfunk-soul trap\nfunk-soul tropical\nfunk-soul, Indian devotional, fusion\nfunk-swing\nfunk-trap\nfunk-trot\nfunkot\nfunkot chiptune\nfunkot gabber\nfunkot hardstyle\nfunkot house\nfunkot nightcore\nfunkot reggaeton\nfunkot, dangdut house, hardstyle\nfunkot, dangdut koplo\nfunkot, dangdut koplo, Indian devotional\nfunkot, dangdut koplo, electronic dance\nfunkot, happy hardcore\nfunkot, happy hardcore, Indonesian\nfunkot, pop-rap\nfunky\nfunky Arabic rap\nfunky Brazilian hip-hop\nfunky Brazilian pop\nfunky C-pop\nfunky Christian\nfunky Christian children's\nfunky Christian children's music\nfunky Christmas\nfunky Christmas novelty\nfunky Christmas pop\nfunky Dutch hip-hop\nfunky French boogie\nfunky French pop\nfunky Indian film\nfunky Indian film music\nfunky Indian film score\nfunky Israeli pop\nfunky Israeli rock\nfunky Italian pop\nfunky J-pop\nfunky K-pop\nfunky Kizomba synth-pop\nfunky Latin\nfunky Latin dance\nfunky Mandopop\nfunky R&B\nfunky R&B Mandopop\nfunky R&B chiptune\nfunky R&B gospel\nfunky R&B hip-hop\nfunky R&B pop\nfunky R&B soul\nfunky R&B, Cantopop, breakbeat\nfunky Russian pop\nfunky Soviet pop\nfunky Tollywood\nfunky Turkish pop\nfunky Vietnamese pop\nfunky Zouk\nfunky accordion\nfunky acoustic\nfunky acoustic rock\nfunky alternative rock\nfunky ambient\nfunky bass, cinematic, electronic\nfunky big band\nfunky big band jazz\nfunky big band swing\nfunky blues\nfunky blues rock\nfunky blues-rock\nfunky brass\nfunky breakbeat\nfunky breakbeat gospel\nfunky breakbeat, dubstep, electronic\nfunky breakbeat, psychedelic rock, chiptune\nfunky breaks\nfunky chanson\nfunky children's\nfunky children's R&B\nfunky children's chant\nfunky children's hip-hop\nfunky children's music\nfunky children's pop\nfunky chiptune\nfunky cinematic\nfunky country R&B\nfunky country-dance\nfunky country-gospel\nfunky country-soul\nfunky cumbia\nfunky dance\nfunky dance-pop\nfunky deep house\nfunky devotional pop\nfunky drum and bass\nfunky educational\nfunky electro\nfunky electronic\nfunky electronic chiptune\nfunky electronic pop\nfunky electronic, Indian film music\nfunky electronic, Indian film music, South Indian pop\nfunky experimental\nfunky folk\nfunky fusion\nfunky fusion, Indian pop, retro video game\nfunky fusion, hardstyle, gabber\nfunky fusion, new jack swing, baroque-pop\nfunky gospel\nfunky groove\nfunky guzheng\nfunky hip hop\nfunky hip-hop\nfunky hip-hop C-pop\nfunky hip-hop chiptune\nfunky hip-hop neo-soul\nfunky hip-hop rock\nfunky hip-hop soul\nfunky hip-hop, R&B, cinematic\nfunky house\nfunky house 90s\nfunky house soul\nfunky house, neo-classical\nfunky indie dance\nfunky indie pop\nfunky indie rock\nfunky indie-pop\nfunky instrumental\nfunky jazz\nfunky jazz-blues\nfunky jazz-pop\nfunky kota\nfunky lo-fi\nfunky lo-fi hip hop\nfunky lo-fi hip-hop\nfunky loop\nfunky lounge\nfunky narrative\nfunky novelty\nfunky organ\nfunky pagode\nfunky percussion\nfunky polka\nfunky pop\nfunky pop 80s\nfunky pop 90s\nfunky pop neo-soul\nfunky pop world music\nfunky pop worldbeat\nfunky pop, Balkan, dance\nfunky pop, Eastern European, retro hip-hop\nfunky pop, Indian film music\nfunky pop, Indian filmi, world music\nfunky pop, Latin pop, Mandarin hip hop\nfunky pop, Latin pop, reggaeton\nfunky pop, Mandarin R&B, trap\nfunky pop, Middle Eastern, EDM\nfunky pop, Russian estrada, 80s synth\nfunky pop, South Indian film music\nfunky pop, South Indian film music, electronic\nfunky pop, South Indian fusion\nfunky pop, South Indian, Tamil pop\nfunky pop, South Indian, cinematic\nfunky pop, Sundanese pop\nfunky pop, Tamil film music\nfunky pop, chiptune, Brazilian R&B\nfunky pop, cinematic trap, theatrical\nfunky pop, city-pop, Vietnamese pop\nfunky pop, jazz fusion, Central Asian\nfunky pop, late-90s R&B, city pop\nfunky pop, new jack swing, city pop\nfunky pop, retro electronic, South Asian pop\nfunky pop, synth-pop, Middle Eastern\nfunky pop, world music\nfunky pop-R&B\nfunky pop-country\nfunky pop-dance\nfunky pop-gospel\nfunky pop-rap\nfunky pop-reggae\nfunky pop-rock\nfunky pop-rock, hardstyle, chiptune\nfunky pop-soul\nfunky rap\nfunky reggae\nfunky retro\nfunky retro game\nfunky retro video game\nfunky rock\nfunky rock and roll\nfunky satire\nfunky soul\nfunky soul-gospel\nfunky soul-rock\nfunky spy theme\nfunky swing\nfunky synth\nfunky synth bass, progressive house, cinematic\nfunky synth pop\nfunky synth, chiptune, operatic C-pop\nfunky synth-pop\nfunky synthwave\nfunky tango\nfunky trap\nfunky trip-hop\nfunky world\nfunky world fusion\nfunky world music\nfunky worldbeat\nfunky worship\nfunky, Balkan, Latin\nfunky, Telugu pop, electronic\nfunky, children's music, playful\nfunky, cinematic, lo-fi\nfunky, tropical, playful\nfunny Halloween\nfunny brass\nfunny circus\nfunny fanfare\nfunny jazz\nfused urban rock\nfusion\nfusion ambient\nfusion ballad\nfusion bhajan\nfusion blues rock\nfusion dance\nfusion devotional\nfusion drum\nfusion drum break\nfusion drum solo\nfusion drumming\nfusion folk\nfusion folk rock\nfusion folk-pop\nfusion funk\nfusion funk gospel\nfusion funk jazz\nfusion funk rock\nfusion funk soul\nfusion ghazal\nfusion groove\nfusion hip-hop\nfusion instrumental\nfusion jazz\nfusion jazz funk\nfusion jazz, funk, chiptune\nfusion jazz, funk, video game music\nfusion jazz, synth-pop, video game music\nfusion metal\nfusion pop\nfusion pop rock\nfusion pop-rock\nfusion punk funk\nfusion qawwali\nfusion rock\nfusion rock hip-hop\nfusion rock, Indian folk, cinematic rock\nfusion rock, synth-pop\nfusion rumba\nfusion soul\nfusion trap\nfusion world\nfusion world music\nfusion world pop\nfusion, Arabic rock, world electric\nfusion, Arabic, Indian\nfusion, Arabic, live\nfusion, Arabic, world music\nfusion, Balkan folk, South Asian\nfusion, Balkan, Klezmer\nfusion, Balkan, Latin\nfusion, Balkan, Middle Eastern\nfusion, Balkan, beatboxing\nfusion, Balkan, electric guitar\nfusion, Balkan, funk\nfusion, Balkan, mariachi\nfusion, Bhangra, South Asian classical\nfusion, Chinese folk, rock\nfusion, Chinese fusion, cinematic\nfusion, Chinese rock, virtuosic\nfusion, Indian bhajan, electronic\nfusion, Indian classical, Latin groove\nfusion, Indian classical, ambient\nfusion, Indian classical, ambient pop\nfusion, Indian classical, ambient rock\nfusion, Indian classical, blues rock\nfusion, Indian classical, cinematic\nfusion, Indian classical, drum and bass\nfusion, Indian classical, electronic\nfusion, Indian classical, festive\nfusion, Indian classical, flamenco\nfusion, Indian classical, folk\nfusion, Indian classical, folk rock\nfusion, Indian classical, folk-dance\nfusion, Indian classical, funk\nfusion, Indian classical, funk hip-hop\nfusion, Indian classical, funk-rock\nfusion, Indian classical, high-energy\nfusion, Indian classical, jazz\nfusion, Indian classical, oud\nfusion, Indian classical, pop\nfusion, Indian classical, pop-rock\nfusion, Indian classical, psychedelic rock\nfusion, Indian classical, punk\nfusion, Indian classical, rock\nfusion, Indian classical, soulful\nfusion, Indian classical, spiritual\nfusion, Indian classical, trance\nfusion, Indian classical, world music\nfusion, Indian devotional, free jazz\nfusion, Indian devotional, rock\nfusion, Indian electronic, a cappella\nfusion, Indian electronic, cinematic\nfusion, Indian electronic, dance\nfusion, Indian electronic, folk techno\nfusion, Indian electronic, high-energy\nfusion, Indian electronic, spiritual dance\nfusion, Indian electronic, trance\nfusion, Indian electronic, world beat\nfusion, Indian electronica, Carnatic\nfusion, Indian electronica, dance\nfusion, Indian electronica, folk dance\nfusion, Indian electronica, folk rock\nfusion, Indian electronica, funk\nfusion, Indian electronica, high-energy\nfusion, Indian electronica, militant trance\nfusion, Indian electronica, modern world\nfusion, Indian electronica, spiritual\nfusion, Indian electronica, world beat\nfusion, Indian film music, electronic\nfusion, Indian folk, European folk\nfusion, Indian folk, Sufi\nfusion, Indian folk, ambient\nfusion, Indian folk, bluegrass\nfusion, Indian folk, cinematic\nfusion, Indian folk, dance\nfusion, Indian folk, devotional\nfusion, Indian folk, dholak\nfusion, Indian folk, electronic\nfusion, Indian folk, energetic\nfusion, Indian folk, festive\nfusion, Indian folk, groove\nfusion, Indian folk, high-energy\nfusion, Indian folk, jazz\nfusion, Indian folk, lo-fi\nfusion, Indian folk, pop\nfusion, Indian folk, rock\nfusion, Indian folk, spiritual\nfusion, Indian folk, surf rock\nfusion, Indian folk, theatrical\nfusion, Indian folk, trance\nfusion, Indian folk, upbeat\nfusion, Indian folk, world music\nfusion, Indian funk, brass\nfusion, Indian funk, electronic\nfusion, Indian fusion, dance\nfusion, Indian fusion, electronic\nfusion, Indian fusion, world beat\nfusion, Indian fusion, world music\nfusion, Indian jazz, dance\nfusion, Indian percussion, anthemic\nfusion, Indian percussion, brass\nfusion, Indian percussion, celebratory\nfusion, Indian percussion, choral\nfusion, Indian percussion, dance\nfusion, Indian percussion, electronic\nfusion, Indian percussion, high-energy\nfusion, Indian percussion, hypnotic\nfusion, Indian pop, ambient\nfusion, Indian pop, electronic\nfusion, Indian pop, electronic dance\nfusion, Indian pop, jazz\nfusion, Indian pop, rock\nfusion, Indian pop, spiritual\nfusion, Indian rock, dance\nfusion, Indian rock, pop\nfusion, Indian rock, world beat\nfusion, Indian trance, devotional\nfusion, Indian, Spanish\nfusion, Indian, dance\nfusion, Indian, festive\nfusion, Indian, klezmer\nfusion, Islamic devotional, South Indian pop\nfusion, Javanese, quirky\nfusion, Latin rock, folk-pop\nfusion, Latin, Balkan\nfusion, Latin, Middle Eastern\nfusion, Latin, dance\nfusion, Latin, electronic\nfusion, Latin, instrumental\nfusion, Latin, klezmer\nfusion, Latin, pop-rock\nfusion, Middle Eastern folk, pop-rock\nfusion, Middle Eastern pop, world music\nfusion, Middle Eastern, Balkan\nfusion, Middle Eastern, Eastern European\nfusion, Middle Eastern, South Asian\nfusion, Middle Eastern, big band\nfusion, Middle Eastern, cinematic\nfusion, Middle Eastern, dance\nfusion, Middle Eastern, electric\nfusion, Middle Eastern, electric guitar\nfusion, Middle Eastern, electronic\nfusion, Middle Eastern, folk\nfusion, Middle Eastern, folk rock\nfusion, Middle Eastern, funk\nfusion, Middle Eastern, high-energy\nfusion, Middle Eastern, pop-rock\nfusion, Middle Eastern, rap\nfusion, Middle Eastern, rock\nfusion, Middle Eastern, surf-rock\nfusion, Middle Eastern, virtuosic\nfusion, Middle Eastern, world music\nfusion, Punjabi folk, ambient\nfusion, Punjabi folk, electronic\nfusion, Punjabi folk, groove\nfusion, Punjabi folk, rock\nfusion, Punjabi pop, UK garage\nfusion, Punjabi, flamenco\nfusion, R&B, South Indian film music\nfusion, R&B, ambient\nfusion, R&B, folk\nfusion, R&B, ghazal\nfusion, South Asian folk, Spanish guitar\nfusion, South Asian folk, cinematic\nfusion, South Asian folk, dance\nfusion, South Asian folk, electronic\nfusion, South Asian folk, pop\nfusion, South Asian folk, trance\nfusion, South Asian, acoustic\nfusion, South Asian, ambient\nfusion, South Asian, brass\nfusion, South Asian, cinematic\nfusion, South Asian, dance\nfusion, South Asian, electronic\nfusion, South Asian, energetic\nfusion, South Asian, high-energy\nfusion, South Asian, world music\nfusion, Sufi, electronic\nfusion, Sundanese, dance\nfusion, Tamil pop, cinematic\nfusion, Tamil rap, cinematic\nfusion, accordion, Latin\nfusion, accordion, dance\nfusion, accordion, dholak\nfusion, accordion, energetic\nfusion, accordion, upbeat\nfusion, acoustic, Chinese traditional\nfusion, ambient pop, Indian classical\nfusion, ambient, Indian classical\nfusion, ambient, Indian electronic\nfusion, ambient, Indian electronica\nfusion, ambient, Indian filmi\nfusion, ambient, Indian folk\nfusion, ambient, Indian pop\nfusion, ambient, Middle Eastern\nfusion, ambient, Punjabi\nfusion, ambient, Punjabi folk\nfusion, ambient, South Asian folk\nfusion, ambient, Sufi pop\nfusion, ambient, devotional\nfusion, ambient, folk\nfusion, ambient, traditional\nfusion, ambient, traditional South Asian\nfusion, ambient, trap\nfusion, ambient, world music\nfusion, balkan, klezmer\nfusion, bansuri, cinematic\nfusion, bansuri, electronic\nfusion, bansuri, funk\nfusion, bansuri, soul\nfusion, bansuri, spiritual\nfusion, bhangra, ambient\nfusion, bhangra, cinematic\nfusion, bhangra, electronic\nfusion, big band, Latin\nfusion, big band, Middle Eastern\nfusion, big band, South Indian film music\nfusion, big band, funk\nfusion, big band, pop\nfusion, big band, rockabilly\nfusion, big beat, South Asian pop\nfusion, blues-rock, cinematic\nfusion, brass, Indian dance\nfusion, brass, dance\nfusion, brass, funk\nfusion, breakbeat, South Indian film music\nfusion, chiptune, Indian folk\nfusion, chiptune, devotional\nfusion, chiptune, electronic\nfusion, chiptune, orchestral\nfusion, chiptune, progressive rock\nfusion, choir, upbeat\nfusion, cinematic, Anatolian folk\nfusion, cinematic, Indian classical\nfusion, cinematic, Malayalam pop\nfusion, cinematic, Middle Eastern\nfusion, cinematic, Punjabi hip-hop\nfusion, cinematic, South Asian folk\nfusion, cinematic, electronic\nfusion, cinematic, folk rock\nfusion, cinematic, folk-dance\nfusion, cinematic, oud\nfusion, cinematic, world music\nfusion, classical, Indian folk\nfusion, classical, pop\nfusion, club, South Indian film music\nfusion, dance, Gujarati\nfusion, dance, Indian folk\nfusion, dance, Indian pop\nfusion, dance, Middle Eastern\nfusion, dance, South Asian\nfusion, dance, brass\nfusion, dance, classical\nfusion, dance, electronic\nfusion, dance, folk\nfusion, dance, folk-pop\nfusion, dance, traditional\nfusion, dance, upbeat\nfusion, dance, world beat\nfusion, dance, world music\nfusion, dance-pop, traditional Central Asian\nfusion, dancehall, funk\nfusion, darbuka, oud\nfusion, darbuka, zurna\nfusion, devotional, Indian classical\nfusion, devotional, cinematic\nfusion, devotional, electronic\nfusion, devotional, world beat\nfusion, devotional, world music\nfusion, dhol, Bollywood\nfusion, dhol, world beat\nfusion, dholak, Indian electronic\nfusion, dholak, Indian folk\nfusion, dholak, Punjabi folk\nfusion, dholak, South Asian\nfusion, dholak, anthemic\nfusion, dholak, bansuri\nfusion, dholak, celebratory\nfusion, dholak, chiptune\nfusion, dholak, cinematic\nfusion, dholak, dance\nfusion, dholak, devotional\nfusion, dholak, electronic\nfusion, dholak, energetic\nfusion, dholak, festive\nfusion, dholak, folk\nfusion, dholak, folk-electronic\nfusion, dholak, funk\nfusion, dholak, harmonium\nfusion, dholak, high-energy\nfusion, dholak, mandolin\nfusion, dholak, rock\nfusion, dholak, sarod\nfusion, dholak, shehnai\nfusion, dholak, surf rock\nfusion, dholak, synth\nfusion, dholak, tabla\nfusion, dholak, trance\nfusion, disco, Indian classical\nfusion, disco, funk\nfusion, downtempo, Punjabi pop\nfusion, dreamy, atmospheric\nfusion, electric guitar, Middle Eastern\nfusion, electronic, Andean\nfusion, electronic, Arabic\nfusion, electronic, Balkan\nfusion, electronic, Bengali\nfusion, electronic, Bollywood\nfusion, electronic, Carnatic\nfusion, electronic, Indian\nfusion, electronic, Indian classical\nfusion, electronic, Indian dance\nfusion, electronic, Indian folk\nfusion, electronic, Indian fusion\nfusion, electronic, Indian groove\nfusion, electronic, Indian hip hop\nfusion, electronic, Indian percussion\nfusion, electronic, Indian pop\nfusion, electronic, Indian rock\nfusion, electronic, Javanese\nfusion, electronic, Mediterranean\nfusion, electronic, Middle Eastern\nfusion, electronic, Punjabi\nfusion, electronic, Sinhala pop\nfusion, electronic, South Asian\nfusion, electronic, South Asian classical\nfusion, electronic, South Asian folk\nfusion, electronic, South Indian\nfusion, electronic, South Indian folk\nfusion, electronic, Tamil\nfusion, electronic, Tamil rap\nfusion, electronic, Telugu rap\nfusion, electronic, bansuri\nfusion, electronic, bhajan\nfusion, electronic, blues rock\nfusion, electronic, bollywood\nfusion, electronic, cinematic\nfusion, electronic, classical Indian\nfusion, electronic, dance\nfusion, electronic, devotional\nfusion, electronic, dholak\nfusion, electronic, festive\nfusion, electronic, folk\nfusion, electronic, folk dance\nfusion, electronic, funk\nfusion, electronic, ghazal\nfusion, electronic, gypsy-punk\nfusion, electronic, hip-hop\nfusion, electronic, klezmer\nfusion, electronic, orchestral\nfusion, electronic, oud\nfusion, electronic, pop\nfusion, electronic, rap\nfusion, electronic, reggae\nfusion, electronic, rock\nfusion, electronic, spiritual\nfusion, electronic, traditional\nfusion, electronic, world\nfusion, electronic, world beat\nfusion, electronic, world dance\nfusion, electronic, world music\nfusion, emotional pop, Middle Eastern\nfusion, festive, Bollywood\nfusion, festive, electronic\nfusion, festive, oud\nfusion, flamenco, Indian classical\nfusion, flamenco, Latin\nfusion, flamenco, cinematic\nfusion, flamenco, funk\nfusion, flamenco, slap bass\nfusion, flamenco, soul\nfusion, flamenco, spiritual\nfusion, flamenco, tango\nfusion, folk dance, pop\nfusion, folk dance, world beat\nfusion, folk rock, Bengali\nfusion, folk rock, Indian classical\nfusion, folk rock, Indian folk\nfusion, folk rock, Latin pop\nfusion, folk rock, Middle Eastern\nfusion, folk rock, ambient\nfusion, folk rock, dance\nfusion, folk rock, energetic\nfusion, folk rock, high-energy\nfusion, folk rock, instrumental\nfusion, folk rock, world music\nfusion, folk, Tamil\nfusion, folk, celebratory\nfusion, folk, cinematic\nfusion, folk, classical\nfusion, folk, dance\nfusion, folk, dance-pop\nfusion, folk, dholak\nfusion, folk, electronic\nfusion, folk, ghazal\nfusion, folk, pop-rock\nfusion, folk, tabla\nfusion, folk, world music\nfusion, folk-pop, R&B, Indian classical\nfusion, folk-pop, South Asian classical\nfusion, folk-pop, jazz\nfusion, funk rock, Indian film music\nfusion, funk, Arabic pop\nfusion, funk, Arabic rock\nfusion, funk, Chinese folk\nfusion, funk, Indian bhajan\nfusion, funk, Indian classical\nfusion, funk, Indian folk\nfusion, funk, Indian folk rock\nfusion, funk, Indian percussion\nfusion, funk, Indian pop\nfusion, funk, Indian rock\nfusion, funk, Middle Eastern\nfusion, funk, Middle Eastern pop\nfusion, funk, Persian\nfusion, funk, Tamil pop\nfusion, funk, accordion\nfusion, funk, anime\nfusion, funk, bansuri\nfusion, funk, big band\nfusion, funk, electronic\nfusion, funk, electronic dance\nfusion, funk, flamenco\nfusion, funk, jazz\nfusion, funk, jazz rock\nfusion, funk, klezmer\nfusion, funk, oud\nfusion, funk, pop\nfusion, funk, pop-rock\nfusion, funk, progressive rock\nfusion, funk, reggae\nfusion, funk, rock\nfusion, funk, soul\nfusion, funk, tribal\nfusion, funk, world beat\nfusion, funk, world music\nfusion, funk-rock, Indian classical\nfusion, funk-rock, Middle Eastern\nfusion, funk-rock, ambient\nfusion, funk-rock, electronic\nfusion, ghazal, ambient\nfusion, ghazal, cinematic\nfusion, ghazal, electronic\nfusion, ghazal, folk dance\nfusion, ghazal, pop-rock\nfusion, ghazal, trap\nfusion, ghazal, world music\nfusion, gospel, hip hop\nfusion, gypsy jazz, electronic\nfusion, gypsy jazz, flamenco\nfusion, gypsy jazz, klezmer\nfusion, hip hop, Punjabi folk\nfusion, hip-hop, Indian pop\nfusion, hip-hop, Middle Eastern\nfusion, hip-hop, flamenco\nfusion, hip-hop, world music\nfusion, indie folk, lo-fi\nfusion, instrumental, world beat\nfusion, jazz, Latin\nfusion, jazz, Malayalam pop\nfusion, jazz, bossa nova\nfusion, jazzy, Indian classical\nfusion, klezmer, big band\nfusion, klezmer, electric\nfusion, klezmer, electronic\nfusion, klezmer, folk rock\nfusion, klezmer, high-energy\nfusion, klezmer, jazz\nfusion, lo-fi hip hop, ambient\nfusion, lo-fi, ambient\nfusion, melancholic, cinematic\nfusion, melancholic, romantic\nfusion, neapolitan, dramatic\nfusion, ney flute, electronic\nfusion, ney flute, funk\nfusion, ney, funk\nfusion, ney, traditional\nfusion, oud rock, traditional folk\nfusion, oud, Balkan folk\nfusion, oud, Indian classical\nfusion, oud, Indian fusion\nfusion, oud, Indian rock\nfusion, oud, Middle Eastern\nfusion, oud, Punjabi\nfusion, oud, Turkish\nfusion, oud, ambient\nfusion, oud, bansuri\nfusion, oud, brass\nfusion, oud, cinematic\nfusion, oud, dance\nfusion, oud, darbuka\nfusion, oud, dramatic\nfusion, oud, electric guitar\nfusion, oud, electronic\nfusion, oud, emotional\nfusion, oud, energetic\nfusion, oud, folk\nfusion, oud, folk rock\nfusion, oud, funk\nfusion, oud, ghazal\nfusion, oud, groove\nfusion, oud, high-energy\nfusion, oud, ney\nfusion, oud, patriotic\nfusion, oud, pop-rock\nfusion, oud, rock\nfusion, oud, spiritual\nfusion, oud, theatrical\nfusion, oud, trance\nfusion, oud, trot\nfusion, oud, world music\nfusion, oud, world pop\nfusion, polka, Tamil pop\nfusion, pop, Indian classical\nfusion, pop, South Asian\nfusion, pop, South Asian folk\nfusion, pop, devotional\nfusion, pop, dholak\nfusion, pop, electronic\nfusion, pop, electronic dance\nfusion, pop, folk\nfusion, pop, ghazal\nfusion, pop, oud\nfusion, pop, rock\nfusion, pop, trap\nfusion, pop, world music\nfusion, pop-rock, Bollywood\nfusion, pop-rock, Indian classical\nfusion, pop-rock, Indian folk\nfusion, pop-rock, Middle Eastern\nfusion, pop-rock, South Asian\nfusion, pop-rock, South Asian folk\nfusion, pop-rock, devotional\nfusion, pop-rock, electronic\nfusion, pop-rock, traditional\nfusion, progressive metal, classical\nfusion, progressive rock, Indian classical\nfusion, progressive rock, Latin percussion\nfusion, progressive rock, jazz fusion\nfusion, progressive rock, lounge\nfusion, qawwali, ambient\nfusion, ragtime, boogie-woogie\nfusion, retro electronic, Indian pop\nfusion, retro electronic, South Asian folk\nfusion, retro-digital, Indian folk\nfusion, retro-funk, dance-pop\nfusion, ritual groove, South Asian folk\nfusion, rock, Arabic\nfusion, rock, Hindustani classical\nfusion, rock, Indian classical\nfusion, rock, Middle Eastern\nfusion, rock, cinematic\nfusion, rock, electronic\nfusion, rock, electronic dance\nfusion, rock, funk\nfusion, rock, oud\nfusion, rockabilly, Indian film music\nfusion, romantic, electronic\nfusion, romantic, melancholic\nfusion, romantic, spiritual\nfusion, romantic, world music\nfusion, shehnai, electronic\nfusion, shehnai, high-energy\nfusion, sitar, electronic\nfusion, sitar, rock\nfusion, soul, Indian classical\nfusion, soul, ambient\nfusion, soul, world pop\nfusion, soulful pop, cinematic\nfusion, soulful, Bengali ghazal\nfusion, soulful, Indian classical\nfusion, soulful, ambient\nfusion, soulful, instrumental\nfusion, soulful, world music\nfusion, spiritual rock, Indian classical\nfusion, spiritual, Indian electronica\nfusion, spiritual, cinematic\nfusion, spiritual, electronic\nfusion, spiritual, folk\nfusion, spiritual, oud\nfusion, spiritual, rock\nfusion, spiritual, world beat\nfusion, spiritual, world music\nfusion, surf rock, Indian percussion\nfusion, surf rock, Middle Eastern\nfusion, surf rock, psychedelic\nfusion, tabla, dance\nfusion, tabla, dholak\nfusion, tabla, oud\nfusion, tabla, sitar\nfusion, taqsim, South Asian\nfusion, theatrical, Arabic jazz\nfusion, theatrical, Indian fusion\nfusion, theatrical, world music\nfusion, traditional, pop\nfusion, traditional, pop-funk\nfusion, trance, world music\nfusion, trap, EDM\nfusion, trap, Indian classical\nfusion, trap, Middle Eastern\nfusion, trap, Punjabi\nfusion, trap, Punjabi folk\nfusion, trap, bansuri\nfusion, trap, cinematic\nfusion, trap, classical Indian\nfusion, trap, ghazal\nfusion, trap, oud\nfusion, trap, traditional\nfusion, trap, traditional Indian\nfusion, trap, world music\nfusion, tribal, Indian classical\nfusion, tribal, Middle Eastern\nfusion, tribal, cinematic\nfusion, tribal, electronic\nfusion, tribal, epic\nfusion, tribal, world music\nfusion, upbeat, festive\nfusion, upbeat, playful\nfusion, world beat, Bengali pop\nfusion, world beat, Indian folk\nfusion, world beat, Indian fusion\nfusion, world beat, anthemic\nfusion, world beat, celebratory\nfusion, world beat, dance\nfusion, world beat, electric oud\nfusion, world beat, electric rock\nfusion, world beat, electronic\nfusion, world beat, festive\nfusion, world beat, folk rock\nfusion, world beat, funk\nfusion, world beat, high energy\nfusion, world beat, high-energy\nfusion, world beat, hip-hop\nfusion, world beat, organ rock\nfusion, world beat, quirky\nfusion, world beat, rock\nfusion, world dance, anthemic\nfusion, world music, Arabic pop\nfusion, world music, Balkan folk\nfusion, world music, Hindi rock\nfusion, world music, Indian classical\nfusion, world music, Indian pop\nfusion, world music, Punjabi\nfusion, world music, Punjabi folk\nfusion, world music, R&B\nfusion, world music, South Asian\nfusion, world music, accordion rock\nfusion, world music, ambient\nfusion, world music, big band\nfusion, world music, blues-rock\nfusion, world music, cinematic\nfusion, world music, dance\nfusion, world music, dholak\nfusion, world music, electric\nfusion, world music, electric blues\nfusion, world music, electric violin\nfusion, world music, electronic\nfusion, world music, energetic\nfusion, world music, ethnic rock\nfusion, world music, festive\nfusion, world music, flamenco\nfusion, world music, folk\nfusion, world music, folk rock\nfusion, world music, funk\nfusion, world music, ghazal\nfusion, world music, high-energy\nfusion, world music, hip-hop\nfusion, world music, instrumental\nfusion, world music, microtonal\nfusion, world music, operatic\nfusion, world music, oud\nfusion, world music, percussive\nfusion, world music, qawwali\nfusion, world music, quirky pop\nfusion, world music, ritual\nfusion, world music, rock\nfusion, world music, romantic\nfusion, world music, soul\nfusion, world music, tabla\nfusion, world music, trance\nfusion, world music, upbeat\nfusion, world pop, Indian electronica\nfusion, world pop, cinematic\nfusion, world pop, classical Indian\nfusion, world pop, electronic\nfusion, world pop, ethnic dance\nfusion, world pop, folk dance\nfusion-pop\nfuture C-pop\nfuture C-pop trap\nfuture Chinese electronic\nfuture J-pop\nfuture R&B\nfuture R&B chiptune\nfuture R&B trap\nfuture R&B trap-pop\nfuture R&B, complextro, hardstyle\nfuture R&B, hyperpop\nfuture R&B, lo-fi hip-hop, indie-pop\nfuture acapella\nfuture ambient\nfuture bass\nfuture bass Bollywood\nfuture bass C-pop\nfuture bass C-pop EDM\nfuture bass C-pop J-pop\nfuture bass C-pop R&B\nfuture bass C-pop anime\nfuture bass C-pop trap\nfuture bass Indian classical\nfuture bass Indian pop\nfuture bass J-Pop\nfuture bass J-pop\nfuture bass K-R&B\nfuture bass K-pop\nfuture bass K-pop T-pop\nfuture bass Latin\nfuture bass Mandopop\nfuture bass R&B\nfuture bass R&B cinematic\nfuture bass R&B lo-fi\nfuture bass R&B pop\nfuture bass R&B trap\nfuture bass alternative R&B\nfuture bass ambient\nfuture bass ambient pop\nfuture bass anime\nfuture bass art pop\nfuture bass artcore\nfuture bass big room house\nfuture bass chill pop\nfuture bass chill trap\nfuture bass chillwave\nfuture bass chillwave emotional pop\nfuture bass chiptune\nfuture bass chiptune artcore\nfuture bass chiptune bollywood\nfuture bass chiptune electro house\nfuture bass chiptune hip-hop\nfuture bass chiptune pop\nfuture bass chiptune trap\nfuture bass cinematic\nfuture bass cinematic electronic\nfuture bass cinematic pop\nfuture bass cinematic trap\nfuture bass city pop\nfuture bass cloud rap\nfuture bass complextro\nfuture bass country-folk\nfuture bass dance-pop\nfuture bass dancehall\nfuture bass dark R&B\nfuture bass dark pop\nfuture bass dark synth-pop\nfuture bass deep house\nfuture bass downtempo\nfuture bass dream pop\nfuture bass dream pop K-pop\nfuture bass drum and bass\nfuture bass dubstep\nfuture bass dubstep glitch hop\nfuture bass electro house\nfuture bass electro-pop\nfuture bass electronic rock\nfuture bass electropop\nfuture bass emo rap\nfuture bass emo rap hyperpop\nfuture bass emo trap\nfuture bass emo-pop\nfuture bass emo-rap\nfuture bass emo-rock\nfuture bass emo-trap\nfuture bass emotional trap\nfuture bass experimental R&B\nfuture bass experimental pop\nfuture bass folk\nfuture bass funk-rock\nfuture bass fusion\nfuture bass future funk\nfuture bass glitch hop\nfuture bass glitch hop chiptune\nfuture bass glitch pop\nfuture bass glitch-hop\nfuture bass glitch-hop vaporwave\nfuture bass glitch-pop\nfuture bass gospel\nfuture bass gospel-trap\nfuture bass hardstyle\nfuture bass hardstyle dubstep\nfuture bass hardstyle trance\nfuture bass hip hop\nfuture bass hip-hop\nfuture bass house\nfuture bass house soulful pop\nfuture bass hyperpop\nfuture bass hyperpop chiptune\nfuture bass hyperpop drum and bass\nfuture bass hyperpop french house\nfuture bass hyperpop hardstyle\nfuture bass hyperpop j-pop\nfuture bass hyperpop nightcore\nfuture bass indie\nfuture bass indie pop\nfuture bass indie rock\nfuture bass indie-dance\nfuture bass indie-pop\nfuture bass j-core\nfuture bass j-pop\nfuture bass kawaii\nfuture bass kawaii bass C-pop\nfuture bass kawaii bass J-core\nfuture bass kawaii chiptune\nfuture bass kawaii hyperpop\nfuture bass kawaii lo-fi\nfuture bass latin\nfuture bass liquid drum and bass\nfuture bass lo-fi\nfuture bass lo-fi chillwave\nfuture bass lo-fi chiptune\nfuture bass lo-fi hip hop\nfuture bass lo-fi hip-hop\nfuture bass lo-fi pop\nfuture bass lofi\nfuture bass lounge\nfuture bass mandopop\nfuture bass melodic dubstep\nfuture bass melodic house\nfuture bass melodic techno\nfuture bass metalcore\nfuture bass metalcore dubstep\nfuture bass neo-soul\nfuture bass nu-disco\nfuture bass nu-disco city pop\nfuture bass nu-disco funk\nfuture bass nu-disco future funk\nfuture bass nu-disco house\nfuture bass nu-disco pop\nfuture bass orchestral\nfuture bass pop\nfuture bass pop EDM\nfuture bass pop R&B\nfuture bass pop ballad\nfuture bass pop dancehall\nfuture bass pop deep house\nfuture bass pop emo\nfuture bass pop hip-hop\nfuture bass pop r&b\nfuture bass pop rock\nfuture bass pop trap\nfuture bass pop tropical house\nfuture bass pop-EDM\nfuture bass pop-R&B\nfuture bass pop-funk\nfuture bass pop-house\nfuture bass pop-punk\nfuture bass pop-r&b\nfuture bass pop-rap\nfuture bass pop-rap lo-fi hip-hop\nfuture bass pop-rock\nfuture bass pop-trap\nfuture bass progressive house\nfuture bass reggaeton\nfuture bass rock\nfuture bass slap house\nfuture bass soul\nfuture bass synth-pop\nfuture bass synthwave\nfuture bass synthwave j-pop\nfuture bass tech house\nfuture bass trance\nfuture bass trap\nfuture bass trap Bollywood\nfuture bass trap C-pop\nfuture bass trap K-pop\nfuture bass trap R&B\nfuture bass trap alternative R&B\nfuture bass trap ambient pop\nfuture bass trap art pop\nfuture bass trap chiptune\nfuture bass trap dubstep\nfuture bass trap electronic\nfuture bass trap epic pop\nfuture bass trap experimental pop\nfuture bass trap glitch hop\nfuture bass trap glitch-hop\nfuture bass trap hardstyle\nfuture bass trap hyperpop\nfuture bass trap metal\nfuture bass trap pop\nfuture bass trap soul\nfuture bass trap-R&B\nfuture bass trap-pop\nfuture bass trap-soul\nfuture bass trip-hop\nfuture bass tropical\nfuture bass tropical house\nfuture bass uk garage\nfuture bass vaporwave\nfuture bass witch house trap\nfuture bass world fusion\nfuture bass world music\nfuture bass worship\nfuture bass, Arabic pop\nfuture bass, Arabic pop, cinematic\nfuture bass, Arabic pop, vaporwave\nfuture bass, Bhojpuri dance-pop\nfuture bass, Bollywood\nfuture bass, Bollywood pop\nfuture bass, Brazilian bass\nfuture bass, C-pop\nfuture bass, C-pop EDM\nfuture bass, C-pop, EDM\nfuture bass, C-pop, J-pop\nfuture bass, C-pop, R&B\nfuture bass, C-pop, ambient\nfuture bass, C-pop, anime\nfuture bass, C-pop, anime soundtrack\nfuture bass, C-pop, chiptune\nfuture bass, C-pop, cinematic\nfuture bass, C-pop, dream pop\nfuture bass, C-pop, electronic\nfuture bass, C-pop, electronic dance\nfuture bass, C-pop, electronic pop\nfuture bass, C-pop, emotional pop\nfuture bass, C-pop, future funk\nfuture bass, C-pop, hip hop\nfuture bass, C-pop, hip-hop\nfuture bass, C-pop, hyperpop\nfuture bass, C-pop, kawaii\nfuture bass, C-pop, lo-fi\nfuture bass, C-pop, lo-fi hip hop\nfuture bass, C-pop, synth-pop\nfuture bass, C-pop, trap\nfuture bass, C-pop, video game music\nfuture bass, Chinese electronic, trap\nfuture bass, Chinese folk, electronic\nfuture bass, Chinese fusion, electronic\nfuture bass, Chinese hip hop, R&B\nfuture bass, Chinese hip hop, cinematic\nfuture bass, Chinese hip-hop, cinematic\nfuture bass, Chinese pop, electronic\nfuture bass, Chinese rap, melodic trap\nfuture bass, Dutch house\nfuture bass, EDM, C-pop\nfuture bass, EDM, Christian pop\nfuture bass, EDM, German pop\nfuture bass, EDM, Indian pop\nfuture bass, EDM, J-pop\nfuture bass, EDM, K-pop\nfuture bass, EDM, Mandopop\nfuture bass, EDM, OPM\nfuture bass, EDM, Russian pop\nfuture bass, EDM, Tamil pop\nfuture bass, EDM, V-pop\nfuture bass, EDM, atmospheric pop\nfuture bass, EDM, bilingual\nfuture bass, EDM, cinematic\nfuture bass, EDM, dance-pop\nfuture bass, EDM, dubstep\nfuture bass, EDM, hip-hop\nfuture bass, EDM, pop\nfuture bass, EDM, pop-rap\nfuture bass, EDM-pop\nfuture bass, German pop\nfuture bass, German pop, R&B\nfuture bass, Hindi pop\nfuture bass, Hindi pop, cinematic\nfuture bass, Hindi pop, electronic\nfuture bass, Indian ambient, cinematic pop\nfuture bass, Indian classical, ambient\nfuture bass, Indian classical, ambient electronic\nfuture bass, Indian classical, electronic\nfuture bass, Indian classical, ethereal\nfuture bass, Indian classical, ghazal\nfuture bass, Indian folk, ambient pop\nfuture bass, Indian folk, cinematic\nfuture bass, Indian folk, spiritual fusion\nfuture bass, Indian fusion, EDM\nfuture bass, Indian pop\nfuture bass, Indian pop, electronic\nfuture bass, Indian pop, experimental electronic\nfuture bass, Indian pop, trap\nfuture bass, Italian pop, cinematic\nfuture bass, J-core\nfuture bass, J-core, EDM\nfuture bass, J-core, artcore\nfuture bass, J-core, chiptune\nfuture bass, J-core, color bass\nfuture bass, J-core, electronic\nfuture bass, J-core, electronic pop\nfuture bass, J-core, happy hardcore\nfuture bass, J-core, hardstyle\nfuture bass, J-core, hyperpop\nfuture bass, J-core, kawaii\nfuture bass, J-core, kawaii bass\nfuture bass, J-core, lo-fi\nfuture bass, J-core, nightcore\nfuture bass, J-pop\nfuture bass, J-pop, C-pop\nfuture bass, J-pop, EDM\nfuture bass, J-pop, K-pop\nfuture bass, J-pop, UK garage\nfuture bass, J-pop, V-pop\nfuture bass, J-pop, ambient\nfuture bass, J-pop, anime\nfuture bass, J-pop, anime score\nfuture bass, J-pop, anime soundtrack\nfuture bass, J-pop, art pop\nfuture bass, J-pop, chiptune\nfuture bass, J-pop, cinematic\nfuture bass, J-pop, city pop\nfuture bass, J-pop, dubstep\nfuture bass, J-pop, electronic pop\nfuture bass, J-pop, future funk\nfuture bass, J-pop, happy hardcore\nfuture bass, J-pop, hardstyle\nfuture bass, J-pop, hip-hop\nfuture bass, J-pop, hyperpop\nfuture bass, J-pop, kawaii\nfuture bass, J-pop, kawaii bass\nfuture bass, J-pop, kawaii future bass\nfuture bass, J-pop, melodic dubstep\nfuture bass, J-pop, nightcore\nfuture bass, J-pop, synth-pop\nfuture bass, J-pop, trap\nfuture bass, J-pop, video game music\nfuture bass, J-rock, chiptune\nfuture bass, K-R&B\nfuture bass, K-pop\nfuture bass, K-pop, EDM\nfuture bass, K-pop, R&B\nfuture bass, K-pop, UK garage\nfuture bass, K-pop, ambient\nfuture bass, K-pop, cinematic pop\nfuture bass, K-pop, city pop\nfuture bass, K-pop, electro-pop\nfuture bass, K-pop, emotional pop\nfuture bass, K-pop, future funk\nfuture bass, K-pop, glitch hop\nfuture bass, K-pop, hip-hop\nfuture bass, K-pop, hyperpop\nfuture bass, K-pop, lo-fi\nfuture bass, K-pop, lo-fi hip hop\nfuture bass, K-pop, pop ballad\nfuture bass, K-pop, pop-R&B\nfuture bass, K-pop, synth-pop\nfuture bass, K-pop, trap\nfuture bass, K-pop, vaporwave\nfuture bass, Latin R&B, reggaeton\nfuture bass, Latin pop\nfuture bass, Latin pop, EDM\nfuture bass, Latin pop, chiptune\nfuture bass, Latin trap\nfuture bass, Mandarin pop, lo-fi\nfuture bass, Mandopop\nfuture bass, Mandopop, EDM\nfuture bass, Mandopop, R&B\nfuture bass, Mandopop, trap\nfuture bass, Persian hip-hop\nfuture bass, Punjabi pop\nfuture bass, Punjabi pop, electronic\nfuture bass, R&B\nfuture bass, R&B, C-pop\nfuture bass, R&B, Chinese ambient\nfuture bass, R&B, Chinese electronic\nfuture bass, R&B, Chinese pop\nfuture bass, R&B, Hindi pop\nfuture bass, R&B, Indian fusion\nfuture bass, R&B, K-pop\nfuture bass, R&B, Latin pop\nfuture bass, R&B, Mandopop\nfuture bass, R&B, UK garage\nfuture bass, R&B, V-Pop\nfuture bass, R&B, ambient\nfuture bass, R&B, chillwave\nfuture bass, R&B, cinematic\nfuture bass, R&B, cinematic pop\nfuture bass, R&B, dancehall\nfuture bass, R&B, devotional\nfuture bass, R&B, downtempo\nfuture bass, R&B, drum and bass\nfuture bass, R&B, electronic pop\nfuture bass, R&B, glitch-hop\nfuture bass, R&B, hip-hop\nfuture bass, R&B, house\nfuture bass, R&B, hyperpop\nfuture bass, R&B, lo-fi\nfuture bass, R&B, lo-fi pop\nfuture bass, R&B, pop\nfuture bass, R&B, soul\nfuture bass, R&B, synth-pop\nfuture bass, R&B, trap\nfuture bass, R&B, vaporwave\nfuture bass, Russian pop\nfuture bass, Russian rap\nfuture bass, South Asian fusion, ambient\nfuture bass, South Asian fusion, electronic\nfuture bass, South Indian pop\nfuture bass, Tamil pop\nfuture bass, Tamil pop, R&B\nfuture bass, Telugu fusion, electronic\nfuture bass, Telugu pop, lo-fi hip hop\nfuture bass, Turkish pop, R&B\nfuture bass, UK garage\nfuture bass, UK garage, 2-step\nfuture bass, UK garage, J-pop\nfuture bass, UK garage, K-pop\nfuture bass, UK garage, ambient\nfuture bass, UK garage, atmospheric\nfuture bass, UK garage, cinematic\nfuture bass, UK garage, dancehall\nfuture bass, UK garage, electronic\nfuture bass, UK garage, electronic pop\nfuture bass, UK garage, future funk\nfuture bass, UK garage, gospel\nfuture bass, UK garage, hyperpop\nfuture bass, UK garage, lo-fi\nfuture bass, UK garage, pop-R&B\nfuture bass, UK hardcore\nfuture bass, UK hardcore, cinematic\nfuture bass, UK hip-hop\nfuture bass, V-Pop, R&B\nfuture bass, V-pop, EDM\nfuture bass, V-pop, chiptune\nfuture bass, V-pop, cinematic\nfuture bass, V-pop, kawaii\nfuture bass, V-pop, vaporwave\nfuture bass, Vietnamese pop, lo-fi hip hop\nfuture bass, Vocaloid, ambient\nfuture bass, Vocaloid, anime\nfuture bass, acoustic ballad\nfuture bass, alternative R&B\nfuture bass, alternative R&B, K-pop\nfuture bass, alternative R&B, chiptune\nfuture bass, alternative R&B, cinematic\nfuture bass, alternative R&B, dream pop\nfuture bass, alternative R&B, emotional pop\nfuture bass, alternative R&B, hyperpop\nfuture bass, alternative R&B, lo-fi\nfuture bass, ambient\nfuture bass, ambient pop, R&B\nfuture bass, ambient pop, bilingual\nfuture bass, ambient trap, cinematic\nfuture bass, ambient, C-pop\nfuture bass, ambient, Chinese electronic\nfuture bass, ambient, Chinese pop\nfuture bass, ambient, Hindi ethereal\nfuture bass, ambient, chiptune\nfuture bass, ambient, chopped and screwed\nfuture bass, ambient, cinematic\nfuture bass, ambient, dubstep\nfuture bass, ambient, glitch-hop\nfuture bass, ambient, hyperpop\nfuture bass, ambient, melodic dubstep\nfuture bass, ambient, nu-disco\nfuture bass, anime pop, C-pop\nfuture bass, anime pop, Chinese pop\nfuture bass, anime style, C-pop\nfuture bass, art pop\nfuture bass, art pop, ambient\nfuture bass, art pop, electronic\nfuture bass, artcore, C-pop\nfuture bass, artcore, cinematic\nfuture bass, atmospheric electronic\nfuture bass, bhajan\nfuture bass, big room house\nfuture bass, big room house, EDM\nfuture bass, big room house, ambient\nfuture bass, big room house, cinematic\nfuture bass, big room house, emotional synth\nfuture bass, big room house, hardstyle\nfuture bass, big room house, lo-fi\nfuture bass, bilingual pop\nfuture bass, breakbeat, ambient\nfuture bass, breakbeat, electronic\nfuture bass, breakcore\nfuture bass, breakcore, ambient\nfuture bass, brostep\nfuture bass, brostep, dubstep\nfuture bass, brostep, electronic\nfuture bass, brostep, hardstyle\nfuture bass, cantopop, lo-fi\nfuture bass, chill house\nfuture bass, chillwave\nfuture bass, chillwave, C-pop\nfuture bass, chillwave, Indian pop\nfuture bass, chillwave, Mandopop\nfuture bass, chillwave, lo-fi\nfuture bass, chillwave, trap\nfuture bass, chiptune pop, synth-pop\nfuture bass, chiptune, C-pop\nfuture bass, chiptune, EDM\nfuture bass, chiptune, J-core\nfuture bass, chiptune, J-pop\nfuture bass, chiptune, K-pop\nfuture bass, chiptune, R&B\nfuture bass, chiptune, Vocaloid\nfuture bass, chiptune, alternative R&B\nfuture bass, chiptune, ambient\nfuture bass, chiptune, cinematic\nfuture bass, chiptune, city pop\nfuture bass, chiptune, dubstep\nfuture bass, chiptune, electro house\nfuture bass, chiptune, electro-pop\nfuture bass, chiptune, emotional\nfuture bass, chiptune, ethereal pop\nfuture bass, chiptune, glitch-hop\nfuture bass, chiptune, happy hardcore\nfuture bass, chiptune, hardstyle\nfuture bass, chiptune, hip-hop\nfuture bass, chiptune, hyperpop\nfuture bass, chiptune, kawaii\nfuture bass, chiptune, kawaii bass\nfuture bass, chiptune, lo-fi\nfuture bass, chiptune, lo-fi R&B\nfuture bass, chiptune, lo-fi hip hop\nfuture bass, chiptune, pop\nfuture bass, chiptune, rap\nfuture bass, chiptune, trap\nfuture bass, chiptune, world music\nfuture bass, cinematic C-pop\nfuture bass, cinematic C-pop, ambient\nfuture bass, cinematic ambient\nfuture bass, cinematic ambient, K-pop\nfuture bass, cinematic ambient, melodic dubstep\nfuture bass, cinematic dubstep\nfuture bass, cinematic dubstep, ambient\nfuture bass, cinematic electronic\nfuture bass, cinematic electronic, wave\nfuture bass, cinematic lo-fi, ambient pop\nfuture bass, cinematic pop\nfuture bass, cinematic pop, EDM\nfuture bass, cinematic pop, Kazakh pop\nfuture bass, cinematic pop, R&B\nfuture bass, cinematic pop, electronic\nfuture bass, cinematic pop, glitch dubstep\nfuture bass, cinematic pop, trap\nfuture bass, cinematic rock\nfuture bass, cinematic synth, melodic dubstep\nfuture bass, cinematic synth-pop\nfuture bass, cinematic, Asian fusion\nfuture bass, cinematic, C-pop\nfuture bass, cinematic, Chinese ambient\nfuture bass, cinematic, Chinese electronic\nfuture bass, cinematic, Chinese orchestral\nfuture bass, cinematic, Chinese traditional\nfuture bass, cinematic, EDM\nfuture bass, cinematic, Hindi rap\nfuture bass, cinematic, Indian classical\nfuture bass, cinematic, Indian fusion\nfuture bass, cinematic, Indonesian pop\nfuture bass, cinematic, Middle Eastern\nfuture bass, cinematic, Persian pop\nfuture bass, cinematic, R&B\nfuture bass, cinematic, Russian pop\nfuture bass, cinematic, Sinhala pop\nfuture bass, cinematic, South Asian\nfuture bass, cinematic, South Asian fusion\nfuture bass, cinematic, ambient\nfuture bass, cinematic, color bass\nfuture bass, cinematic, dubstep\nfuture bass, cinematic, electronic\nfuture bass, cinematic, emotional\nfuture bass, cinematic, ethereal\nfuture bass, cinematic, ethnic fusion\nfuture bass, cinematic, glitch\nfuture bass, cinematic, glitch-hop\nfuture bass, cinematic, hardstyle\nfuture bass, cinematic, hardwave\nfuture bass, cinematic, hybrid trap\nfuture bass, cinematic, hyperpop\nfuture bass, cinematic, lo-fi\nfuture bass, cinematic, melodic dubstep\nfuture bass, cinematic, trap\nfuture bass, cinematic, vaporwave\nfuture bass, cinematic, world music\nfuture bass, cinematic, worship\nfuture bass, city pop, C-pop\nfuture bass, city pop, K-pop\nfuture bass, city pop, Mandopop\nfuture bass, city pop, chiptune\nfuture bass, city pop, kawaii\nfuture bass, city pop, lo-fi hip-hop\nfuture bass, city pop, vaporwave\nfuture bass, cloud rap, ambient\nfuture bass, cloud rap, electronic pop\nfuture bass, cloud rap, emo rap\nfuture bass, cloud rap, hyperpop\nfuture bass, cloud rap, lo-fi pop\nfuture bass, color bass\nfuture bass, color bass, C-pop\nfuture bass, color bass, ambient\nfuture bass, color bass, dubstep\nfuture bass, color bass, electronic\nfuture bass, color bass, melodic dubstep\nfuture bass, color bass, melodic riddim\nfuture bass, complextro\nfuture bass, complextro, chiptune\nfuture bass, complextro, cinematic\nfuture bass, complextro, color bass\nfuture bass, complextro, dubstep\nfuture bass, complextro, hardstyle\nfuture bass, contemporary R&B\nfuture bass, cyberpunk pop\nfuture bass, cyberpunk, cinematic\nfuture bass, cyberpunk, hyperpop\nfuture bass, dance-pop\nfuture bass, dance-pop, C-pop\nfuture bass, dance-pop, EDM\nfuture bass, dancehall, moombahton\nfuture bass, dangdut koplo, Indonesian pop\nfuture bass, dark pop\nfuture bass, dark pop, electronic pop\nfuture bass, dark pop, trap\nfuture bass, dark synth-pop\nfuture bass, deep house, K-pop\nfuture bass, deep house, R&B\nfuture bass, deep house, UK garage\nfuture bass, deep house, electronic pop\nfuture bass, dream pop, C-pop\nfuture bass, dream pop, alternative R&B\nfuture bass, dream pop, electronic\nfuture bass, dream pop, electronic R&B\nfuture bass, dream pop, electronic pop\nfuture bass, dream pop, hyperpop\nfuture bass, dream pop, melodic dubstep\nfuture bass, dream pop, synth-pop\nfuture bass, drum & bass, anime\nfuture bass, drum and bass\nfuture bass, drum and bass, R&B\nfuture bass, drum and bass, ambient\nfuture bass, drum and bass, chiptune\nfuture bass, drum and bass, cinematic\nfuture bass, drum and bass, electronic\nfuture bass, drum and bass, hardcore\nfuture bass, drum and bass, hyperpop\nfuture bass, drum and bass, neurofunk\nfuture bass, dubstep\nfuture bass, dubstep, C-pop\nfuture bass, dubstep, EDM\nfuture bass, dubstep, J-pop\nfuture bass, dubstep, K-pop\nfuture bass, dubstep, Sinhala pop\nfuture bass, dubstep, ambient\nfuture bass, dubstep, chiptune\nfuture bass, dubstep, cinematic\nfuture bass, dubstep, cinematic C-pop\nfuture bass, dubstep, cinematic hip hop\nfuture bass, dubstep, color bass\nfuture bass, dubstep, complextro\nfuture bass, dubstep, electronic\nfuture bass, dubstep, glitch\nfuture bass, dubstep, glitch hop\nfuture bass, dubstep, glitch-hop\nfuture bass, dubstep, hardstyle\nfuture bass, dubstep, lo-fi hip hop\nfuture bass, dubstep, melodic\nfuture bass, dubstep, pop-punk\nfuture bass, dubstep, pop-rock\nfuture bass, dubstep, rap\nfuture bass, dubstep, trap\nfuture bass, dubstep, trap metal\nfuture bass, electro house\nfuture bass, electro house, C-pop\nfuture bass, electro house, ambient\nfuture bass, electro house, cinematic\nfuture bass, electro house, emotional piano\nfuture bass, electro-pop\nfuture bass, electro-pop, C-pop\nfuture bass, electro-pop, J-pop\nfuture bass, electro-pop, Mandopop\nfuture bass, electro-pop, V-pop\nfuture bass, electronic R&B\nfuture bass, electronic R&B, Indian pop\nfuture bass, electronic R&B, J-pop\nfuture bass, electronic R&B, dream pop\nfuture bass, electronic hip-hop, ambient pop\nfuture bass, electronic pop\nfuture bass, electronic pop, C-pop\nfuture bass, electronic pop, Indian fusion\nfuture bass, electronic pop, K-pop\nfuture bass, electronic pop, South Asian fusion\nfuture bass, electronic pop, complextro\nfuture bass, electronic pop, hyperpop\nfuture bass, electronic pop, indie rock\nfuture bass, electronic pop, indie-pop\nfuture bass, electronic pop, worship\nfuture bass, electronic rock\nfuture bass, electronic rock, Ancient Style\nfuture bass, electronic rock, lo-fi\nfuture bass, electronic, C-pop\nfuture bass, electronic, Chinese pop\nfuture bass, electronic, Latin pop\nfuture bass, electronic, chiptune\nfuture bass, electronic, cinematic\nfuture bass, electronicore, J-pop\nfuture bass, emo rap, EDM\nfuture bass, emo rap, hyperpop\nfuture bass, emo rap, melodic dubstep\nfuture bass, emo-pop, hyperpop\nfuture bass, emo-rap, lo-fi\nfuture bass, emotional R&B\nfuture bass, emotional R&B, cinematic electronic\nfuture bass, emotional ballad\nfuture bass, emotional ballad, hardstyle\nfuture bass, emotional ballad, hip-hop\nfuture bass, emotional electronic\nfuture bass, emotional electronic pop\nfuture bass, emotional electronic pop, cinematic\nfuture bass, emotional pop\nfuture bass, emotional pop, electronic dance\nfuture bass, emotional pop, hard electronic\nfuture bass, emotional trance\nfuture bass, emotional trap\nfuture bass, emotional trap, cinematic\nfuture bass, ethereal R&B, electronic\nfuture bass, ethereal pop, C-pop\nfuture bass, ethereal pop, EDM\nfuture bass, ethereal wave\nfuture bass, ethereal wave, trap\nfuture bass, experimental R&B\nfuture bass, experimental, ambient\nfuture bass, experimental, trap\nfuture bass, folk, ambient\nfuture bass, future R&B\nfuture bass, future funk\nfuture bass, glitch hop\nfuture bass, glitch hop, dubstep\nfuture bass, glitch hop, lo-fi\nfuture bass, glitch pop\nfuture bass, glitch pop, chiptune\nfuture bass, glitch pop, cinematic\nfuture bass, glitch-hop, ambient\nfuture bass, glitch-pop\nfuture bass, glitch-pop, hyperpop\nfuture bass, happy hardcore\nfuture bass, happy hardcore, C-pop\nfuture bass, happy hardcore, EDM\nfuture bass, happy hardcore, J-core\nfuture bass, happy hardcore, J-pop\nfuture bass, happy hardcore, cinematic C-pop\nfuture bass, happy hardcore, hardstyle\nfuture bass, happy hardcore, hyperpop\nfuture bass, happy hardcore, pop-punk\nfuture bass, happy hardcore, rap\nfuture bass, hard dance\nfuture bass, hardcore, speedcore\nfuture bass, hardstyle\nfuture bass, hardstyle, C-pop\nfuture bass, hardstyle, Chinese hip hop\nfuture bass, hardstyle, EDM\nfuture bass, hardstyle, J-core\nfuture bass, hardstyle, J-pop\nfuture bass, hardstyle, K-pop\nfuture bass, hardstyle, R&B\nfuture bass, hardstyle, V-pop\nfuture bass, hardstyle, Vietnamese pop\nfuture bass, hardstyle, ambient\nfuture bass, hardstyle, ambient pop\nfuture bass, hardstyle, chillwave\nfuture bass, hardstyle, chiptune\nfuture bass, hardstyle, cinematic\nfuture bass, hardstyle, cinematic electronic\nfuture bass, hardstyle, cinematic pop\nfuture bass, hardstyle, complexro\nfuture bass, hardstyle, complextro\nfuture bass, hardstyle, dance-pop\nfuture bass, hardstyle, dark pop\nfuture bass, hardstyle, dream pop\nfuture bass, hardstyle, drum and bass\nfuture bass, hardstyle, dubstep\nfuture bass, hardstyle, electronic\nfuture bass, hardstyle, electronic pop\nfuture bass, hardstyle, electronic rock\nfuture bass, hardstyle, emotional pop\nfuture bass, hardstyle, glitchcore\nfuture bass, hardstyle, happy hardcore\nfuture bass, hardstyle, hybrid trap\nfuture bass, hardstyle, hyperpop\nfuture bass, hardstyle, kawaii\nfuture bass, hardstyle, lo-fi\nfuture bass, hardstyle, lo-fi hip hop\nfuture bass, hardstyle, melancholic pop\nfuture bass, hardstyle, pop\nfuture bass, hardstyle, pop-R&B\nfuture bass, hardstyle, pop-punk\nfuture bass, hardstyle, pop-rock\nfuture bass, hardstyle, psytrance\nfuture bass, hardstyle, trap\nfuture bass, hardstyle, vaporwave\nfuture bass, hardwave, ambient\nfuture bass, hardwave, cinematic\nfuture bass, hardwave, glitch hop\nfuture bass, hardwave, trap\nfuture bass, hip hop\nfuture bass, hip hop, K-pop\nfuture bass, hip hop, cinematic\nfuture bass, hip-hop\nfuture bass, hip-hop, C-pop\nfuture bass, hip-hop, K-pop\nfuture bass, hip-hop, acoustic ballad\nfuture bass, hip-hop, ambient\nfuture bass, hip-hop, ballad\nfuture bass, hip-hop, cinematic\nfuture bass, hip-hop, emotional pop\nfuture bass, hip-hop, house\nfuture bass, hip-hop, lo-fi\nfuture bass, hip-hop, pop\nfuture bass, hip-hop, pop-R&B\nfuture bass, house, C-pop\nfuture bass, house, Vietnamese pop\nfuture bass, hyperpop\nfuture bass, hyperpop, C-pop\nfuture bass, hyperpop, EDM\nfuture bass, hyperpop, French rap\nfuture bass, hyperpop, German pop-rap\nfuture bass, hyperpop, J-core\nfuture bass, hyperpop, J-pop\nfuture bass, hyperpop, K-pop\nfuture bass, hyperpop, R&B\nfuture bass, hyperpop, UK garage\nfuture bass, hyperpop, ambient\nfuture bass, hyperpop, ambient pop\nfuture bass, hyperpop, atmospheric R&B\nfuture bass, hyperpop, chiptune\nfuture bass, hyperpop, cinematic\nfuture bass, hyperpop, cinematic hip-hop\nfuture bass, hyperpop, dance-pop\nfuture bass, hyperpop, electronic\nfuture bass, hyperpop, electronic pop\nfuture bass, hyperpop, emo\nfuture bass, hyperpop, emo rap\nfuture bass, hyperpop, emo-pop\nfuture bass, hyperpop, emo-rap\nfuture bass, hyperpop, emo-trap\nfuture bass, hyperpop, emotional\nfuture bass, hyperpop, emotional electronic\nfuture bass, hyperpop, glitch-hop\nfuture bass, hyperpop, glitch-pop\nfuture bass, hyperpop, hardcore\nfuture bass, hyperpop, hardstyle\nfuture bass, hyperpop, hardwave\nfuture bass, hyperpop, indie-pop\nfuture bass, hyperpop, kawaii\nfuture bass, hyperpop, kawaii bass\nfuture bass, hyperpop, liquid drum and bass\nfuture bass, hyperpop, lo-fi\nfuture bass, hyperpop, lo-fi trap\nfuture bass, hyperpop, modern pop\nfuture bass, hyperpop, moombahton\nfuture bass, hyperpop, nightcore\nfuture bass, hyperpop, piano ballad\nfuture bass, hyperpop, pluggnb\nfuture bass, hyperpop, pop\nfuture bass, hyperpop, pop-R&B\nfuture bass, hyperpop, pop-punk\nfuture bass, hyperpop, soulful\nfuture bass, hyperpop, synth-pop\nfuture bass, hyperpop, trap\nfuture bass, indie pop, lo-fi hip hop\nfuture bass, indie rock, hip hop\nfuture bass, j-pop, kawaii bass\nfuture bass, jungle, hyperpop\nfuture bass, kawaii\nfuture bass, kawaii bass, C-pop\nfuture bass, kawaii bass, V-pop\nfuture bass, kawaii bass, chiptune\nfuture bass, kawaii metal, C-pop\nfuture bass, kawaii pop, Thai pop\nfuture bass, kawaii, C-pop\nfuture bass, kawaii, Chinese electronic\nfuture bass, kawaii, Chinese-style\nfuture bass, kawaii, J-core\nfuture bass, kawaii, J-pop\nfuture bass, kawaii, V-pop\nfuture bass, kawaii, chiptune\nfuture bass, kawaii, hyper-pop\nfuture bass, kawaii, hyperpop\nfuture bass, kawaii, lo-fi hip-hop\nfuture bass, liquid drum and bass\nfuture bass, liquid drum and bass, cinematic\nfuture bass, liquid drum and bass, neurofunk\nfuture bass, liquid drum and bass, piano ballad\nfuture bass, lo-fi chiptune, Mandopop\nfuture bass, lo-fi hip hop\nfuture bass, lo-fi hip hop, C-pop\nfuture bass, lo-fi hip hop, Cantopop\nfuture bass, lo-fi hip hop, Chinese pop\nfuture bass, lo-fi hip hop, Chinese rap\nfuture bass, lo-fi hip hop, Indian pop\nfuture bass, lo-fi hip hop, Mandarin rap\nfuture bass, lo-fi hip hop, Mandopop\nfuture bass, lo-fi hip hop, R&B\nfuture bass, lo-fi hip hop, Vietnamese pop\nfuture bass, lo-fi hip hop, Vietnamese rap\nfuture bass, lo-fi hip hop, cinematic\nfuture bass, lo-fi hip hop, emotional pop\nfuture bass, lo-fi hip hop, pop\nfuture bass, lo-fi hip hop, soul\nfuture bass, lo-fi hip hop, trap\nfuture bass, lo-fi hip-hop, C-pop\nfuture bass, lo-fi hip-hop, J-pop\nfuture bass, lo-fi hip-hop, R&B\nfuture bass, lo-fi pop, K-pop\nfuture bass, lo-fi pop, Vietnamese pop\nfuture bass, lo-fi pop, ambient trap\nfuture bass, lo-fi pop, cinematic\nfuture bass, lo-fi trap, Mandarin rap\nfuture bass, lo-fi, Arabic pop\nfuture bass, lo-fi, C-pop\nfuture bass, lo-fi, Latin urban\nfuture bass, lo-fi, R&B\nfuture bass, lo-fi, Vocaloid\nfuture bass, lo-fi, ambient\nfuture bass, lo-fi, chillwave\nfuture bass, lo-fi, cinematic\nfuture bass, lo-fi, hyper-pop\nfuture bass, lo-fi, hyperpop\nfuture bass, lo-fi, neurofunk\nfuture bass, lo-fi, vaporwave\nfuture bass, math rock, Mandarin rap\nfuture bass, melodic dubstep\nfuture bass, melodic dubstep, C-pop\nfuture bass, melodic dubstep, K-pop\nfuture bass, melodic dubstep, acoustic pop\nfuture bass, melodic dubstep, ambient\nfuture bass, melodic dubstep, chiptune\nfuture bass, melodic dubstep, cinematic\nfuture bass, melodic dubstep, cinematic pop\nfuture bass, melodic dubstep, color bass\nfuture bass, melodic dubstep, electronic\nfuture bass, melodic dubstep, hardstyle\nfuture bass, melodic dubstep, lo-fi\nfuture bass, melodic dubstep, metalcore\nfuture bass, melodic dubstep, pop\nfuture bass, melodic dubstep, pop-punk\nfuture bass, melodic dubstep, trap\nfuture bass, melodic rap, cinematic pop\nfuture bass, melodic rap, electronic\nfuture bass, melodic riddim, ambient\nfuture bass, melodic riddim, ethereal pop\nfuture bass, melodic techno\nfuture bass, melodic techno, glitch\nfuture bass, melodic trap\nfuture bass, metalcore, ambient\nfuture bass, metalcore, ambient pop\nfuture bass, metalcore, cinematic\nfuture bass, metalcore, lo-fi hip hop\nfuture bass, modern R&B\nfuture bass, moombahton, EDM\nfuture bass, neo-soul, experimental\nfuture bass, neo-soul, lo-fi\nfuture bass, neurofunk\nfuture bass, neurofunk, cinematic\nfuture bass, neurofunk, complextro\nfuture bass, neurofunk, dubstep\nfuture bass, neurofunk, glitch\nfuture bass, nightcore, hyperpop\nfuture bass, phonk, lo-fi hip hop\nfuture bass, pop R&B\nfuture bass, pop R&B, cinematic\nfuture bass, pop ballad\nfuture bass, pop ballad, Latin pop\nfuture bass, pop ballad, Vietnamese pop\nfuture bass, pop ballad, cinematic\nfuture bass, pop ballad, hardstyle\nfuture bass, pop, EDM\nfuture bass, pop, Indonesian pop\nfuture bass, pop, J-pop\nfuture bass, pop, K-pop\nfuture bass, pop, Punjabi\nfuture bass, pop, big room house\nfuture bass, pop, dream pop\nfuture bass, pop, electronic\nfuture bass, pop, hip-hop\nfuture bass, pop, klezmer\nfuture bass, pop, reggaeton\nfuture bass, pop, trap\nfuture bass, pop, world music\nfuture bass, pop-EDM, cinematic\nfuture bass, pop-EDM, lo-fi\nfuture bass, pop-EDM, rap\nfuture bass, pop-R&B\nfuture bass, pop-R&B, C-pop\nfuture bass, pop-R&B, Tibetan style\nfuture bass, pop-R&B, Vietnamese pop\nfuture bass, pop-R&B, chiptune\nfuture bass, pop-R&B, cinematic\nfuture bass, pop-R&B, dream pop\nfuture bass, pop-R&B, trap\nfuture bass, pop-R&B, vaporwave\nfuture bass, pop-anthem, bilingual\nfuture bass, pop-ballad, cinematic\nfuture bass, pop-hip hop, C-pop\nfuture bass, pop-punk, EDM\nfuture bass, pop-punk, hardstyle\nfuture bass, pop-rap, Chinese electronic\nfuture bass, pop-rap, EDM\nfuture bass, pop-rock\nfuture bass, pop-rock, C-pop\nfuture bass, pop-rock, Indian classical\nfuture bass, pop-rock, cinematic\nfuture bass, pop-rock, emo-rap\nfuture bass, pop-rock, hardstyle\nfuture bass, pop-trap, French ballad\nfuture bass, pop-trap, Indian classical\nfuture bass, post-rock, dubstep\nfuture bass, progressive house, C-pop\nfuture bass, progressive house, dubstep\nfuture bass, progressive house, emotional pop\nfuture bass, progressive house, hardstyle\nfuture bass, progressive house, lo-fi\nfuture bass, reggaeton, Latin pop\nfuture bass, reggaeton, lo-fi\nfuture bass, reggaeton, pop\nfuture bass, rock, hardstyle\nfuture bass, rock, lo-fi\nfuture bass, sentimental pop, Vietnamese pop\nfuture bass, slap house\nfuture bass, slap house, Brazilian electronic\nfuture bass, slap house, EDM\nfuture bass, slap house, South Asian pop\nfuture bass, slap house, ambient\nfuture bass, soulful pop, gospel\nfuture bass, soulful pop, hip-hop\nfuture bass, spiritual electronic, ambient\nfuture bass, synth-pop\nfuture bass, synth-pop, C-pop\nfuture bass, synth-pop, EDM\nfuture bass, synth-pop, J-pop\nfuture bass, synth-pop, K-pop\nfuture bass, synth-pop, Mandopop\nfuture bass, synth-pop, UK garage\nfuture bass, synth-pop, V-Pop\nfuture bass, synth-pop, ambient\nfuture bass, synth-pop, chiptune\nfuture bass, synth-pop, cinematic\nfuture bass, synth-pop, city pop\nfuture bass, synth-pop, electronic\nfuture bass, synth-pop, emotional electronic\nfuture bass, synth-pop, lo-fi\nfuture bass, synth-pop, rap\nfuture bass, synthwave\nfuture bass, tech house\nfuture bass, tech house, C-pop\nfuture bass, trance\nfuture bass, trance, C-pop\nfuture bass, trance, EDM\nfuture bass, trance, J-core\nfuture bass, trance, ambient\nfuture bass, trance, brostep\nfuture bass, trance, chiptune\nfuture bass, trance, cinematic\nfuture bass, trance, drum and bass\nfuture bass, trance, electronic\nfuture bass, trance, hardstyle\nfuture bass, trance-pop, cinematic\nfuture bass, trancecore, C-pop\nfuture bass, trap\nfuture bass, trap soul, R&B\nfuture bass, trap, Arabic electronic\nfuture bass, trap, C-pop\nfuture bass, trap, Chinese ambient\nfuture bass, trap, Chinese hip hop\nfuture bass, trap, EDM\nfuture bass, trap, East Asian fusion\nfuture bass, trap, East Asian melodic\nfuture bass, trap, Eastern European pop\nfuture bass, trap, Filipino pop\nfuture bass, trap, Hindi film music\nfuture bass, trap, Indian classical\nfuture bass, trap, Indian devotional\nfuture bass, trap, Indian electronic\nfuture bass, trap, Indian fusion\nfuture bass, trap, Indian pop\nfuture bass, trap, J-pop\nfuture bass, trap, K-pop\nfuture bass, trap, Mandopop\nfuture bass, trap, Mongolian pop\nfuture bass, trap, Persian vocal\nfuture bass, trap, R&B\nfuture bass, trap, Russian pop\nfuture bass, trap, South Asian\nfuture bass, trap, Tamil pop\nfuture bass, trap, Turkish folk\nfuture bass, trap, Turkish pop\nfuture bass, trap, V-pop\nfuture bass, trap, acoustic pop\nfuture bass, trap, ambient\nfuture bass, trap, ambient pop\nfuture bass, trap, anime\nfuture bass, trap, ballad\nfuture bass, trap, chiptune\nfuture bass, trap, cinematic\nfuture bass, trap, cinematic ambient\nfuture bass, trap, cinematic pop\nfuture bass, trap, dance-pop\nfuture bass, trap, dark pop\nfuture bass, trap, dream pop\nfuture bass, trap, dream-pop\nfuture bass, trap, drum and bass\nfuture bass, trap, dubstep\nfuture bass, trap, electronic\nfuture bass, trap, electronic pop\nfuture bass, trap, emotional EDM\nfuture bass, trap, emotional piano\nfuture bass, trap, emotional pop\nfuture bass, trap, ethereal\nfuture bass, trap, ethereal pop\nfuture bass, trap, experimental electronic\nfuture bass, trap, experimental pop\nfuture bass, trap, glitch hop\nfuture bass, trap, hardstyle\nfuture bass, trap, hyperpop\nfuture bass, trap, jazz\nfuture bass, trap, lo-fi\nfuture bass, trap, lo-fi chiptune\nfuture bass, trap, lo-fi hip hop\nfuture bass, trap, piano ballad\nfuture bass, trap, pop\nfuture bass, trap, pop-R&B\nfuture bass, trap, pop-punk\nfuture bass, trap, pop-rap\nfuture bass, trap, pop-rock\nfuture bass, trap, rap\nfuture bass, trap, reggae fusion\nfuture bass, trap, sentimental pop\nfuture bass, trap, vaporwave\nfuture bass, trap, world music\nfuture bass, trap-R&B, Chinese pop\nfuture bass, trap-R&B, Jersey club\nfuture bass, trap-R&B, ambient\nfuture bass, trap-pop\nfuture bass, trap-pop, cinematic\nfuture bass, trap-pop, lo-fi\nfuture bass, trap-soul, cinematic\nfuture bass, trap-soul, lo-fi hip hop\nfuture bass, trip-hop, ambient\nfuture bass, tropical house, C-pop\nfuture bass, uk garage\nfuture bass, uk garage, chiptune\nfuture bass, uk garage, deep house\nfuture bass, uk garage, hyperpop\nfuture bass, uk garage, lo-fi\nfuture bass, vaporwave, C-pop\nfuture bass, vaporwave, Cantopop\nfuture bass, vaporwave, French rap\nfuture bass, vaporwave, J-pop\nfuture bass, vaporwave, K-rap\nfuture bass, vaporwave, R&B\nfuture bass, vaporwave, color bass\nfuture bass, vaporwave, electronic\nfuture bass, vaporwave, emotional synth\nfuture bass, vaporwave, hardstyle\nfuture bass, vaporwave, hip hop\nfuture bass, vaporwave, hip-hop\nfuture bass, vaporwave, hyperpop\nfuture bass, vaporwave, kawaii\nfuture bass, vaporwave, lo-fi\nfuture bass, vaporwave, melodic dubstep\nfuture bass, vaporwave, rap\nfuture bass, vaporwave, trap\nfuture bass, vocaloid, chiptune\nfuture bass, wave, trap\nfuture bass, world music, C-pop\nfuture bass, world music, R&B\nfuture bass, world music, lo-fi\nfuture bass, wuxia, electronic\nfuture dance pop\nfuture dancehall\nfuture electronic\nfuture electronica\nfuture funk\nfuture funk chiptune\nfuture funk city pop\nfuture funk experimental R&B glitch-hop\nfuture funk glitch pop\nfuture funk lo-fi\nfuture funk nu-disco\nfuture funk nu-disco chiptune\nfuture funk, J-pop\nfuture funk, J-pop, electronic\nfuture funk, J-pop, hyperpop\nfuture funk, J-pop, video game music\nfuture funk, UK garage, glitch\nfuture funk, UK garage, lo-fi house\nfuture funk, chiptune, kawaii bass\nfuture funk, city pop\nfuture funk, city pop, C-pop\nfuture funk, city pop, J-pop\nfuture funk, city pop, R&B\nfuture funk, city pop, Shibuya-kei\nfuture funk, city pop, hyperpop\nfuture funk, city pop, nu-disco\nfuture funk, synth-pop\nfuture funk, vaporwave, hyperpop\nfuture garage\nfuture garage K-pop\nfuture garage alternative R&B\nfuture garage ambient\nfuture garage ambient R&B\nfuture garage ambient dream pop\nfuture garage ambient pop\nfuture garage ambient techno\nfuture garage ambient trap\nfuture garage breakcore\nfuture garage chillwave\nfuture garage chillwave neo-soul\nfuture garage cinematic ambient\nfuture garage cinematic trance\nfuture garage dark R&B\nfuture garage dark pop\nfuture garage deep house\nfuture garage dream pop\nfuture garage experimental R&B\nfuture garage experimental pop\nfuture garage experimental trap\nfuture garage future bass\nfuture garage liquid drum and bass\nfuture garage lo-fi\nfuture garage lo-fi house\nfuture garage synth-pop\nfuture garage trap\nfuture garage trip-hop\nfuture garage uk garage\nfuture garage wave\nfuture garage witch house\nfuture garage, IDM\nfuture garage, K-pop\nfuture garage, R&B\nfuture garage, UK garage, ambient electronic\nfuture garage, UK garage, cloud rap\nfuture garage, UK garage, dark electronic\nfuture garage, alternative R&B\nfuture garage, dark pop\nfuture garage, deep house\nfuture garage, deep house, vaporwave\nfuture garage, emotional R&B\nfuture garage, ethereal wave\nfuture garage, experimental pop\nfuture garage, experimental trap\nfuture garage, future bass\nfuture garage, future bass, happy hardcore\nfuture garage, hardstyle, ambient\nfuture garage, hyperpop\nfuture garage, liquid drum and bass\nfuture garage, liquid drum and bass, R&B\nfuture garage, liquid drum and bass, synth-pop\nfuture garage, neurofunk\nfuture garage, synth-pop\nfuture garage, trap, ambient\nfuture garage, trap, experimental R&B\nfuture garage, trap-soul, cinematic\nfuture hip hop\nfuture hip-hop\nfuture house\nfuture house dance-pop\nfuture nostalgic house\nfuture pop\nfuture pop trap\nfuture pop, trance, neurofunk\nfuture reggaeton\nfuture soul\nfuture soundscape\nfuture soundscapes\nfuture techno\nfuture trance\nfuture trap\nfuture trap C-pop\nfuture trap R&B\nfuture trap dancehall\nfuture trap, hyperpop\nfuture trap, lo-fi hip hop\nfuture vocal\nfuture wave\nfuture-pop\nfuturepop\nfuturepop hardstyle\nfuturepop industrial dance\nfuturepop, EBM\nfuturepop, EBM, darkwave\nfuturepop, cyberpunk, trance\nfuturistic Brazilian funk\nfuturistic Brazilian funk trap\nfuturistic Brazilian hip-hop\nfuturistic Brazilian pop\nfuturistic Brazilian trap\nfuturistic C-pop\nfuturistic C-pop EDM\nfuturistic C-pop R&B\nfuturistic C-pop electronic\nfuturistic C-pop hip-hop\nfuturistic C-pop hyperpop\nfuturistic C-pop trap\nfuturistic C-pop trap-R&B\nfuturistic C-pop, trap hip-hop\nfuturistic Cantonese hip-hop\nfuturistic Dutch hip-hop\nfuturistic EDM\nfuturistic French hip-hop\nfuturistic Italian hip-hop\nfuturistic J-pop\nfuturistic J-pop cloud rap\nfuturistic J-pop hip-hop\nfuturistic K-pop\nfuturistic Latin pop\nfuturistic Latin trap\nfuturistic Mandopop\nfuturistic Punjabi hip-hop\nfuturistic R&B\nfuturistic R&B electro-pop\nfuturistic R&B trap\nfuturistic R&B trap-pop\nfuturistic R&B, conscious hip-hop, experimental\nfuturistic Russian hip-hop\nfuturistic Southern hip-hop\nfuturistic a cappella\nfuturistic baile funk\nfuturistic bass house\nfuturistic boom bap\nfuturistic boom-bap\nfuturistic breakbeat\nfuturistic children's\nfuturistic conscious hip-hop\nfuturistic dance-pop\nfuturistic dancehall\nfuturistic drill\nfuturistic dub-reggae\nfuturistic dubstep\nfuturistic electro\nfuturistic electronic\nfuturistic electronic hip-hop\nfuturistic electronic pop\nfuturistic electronic rock\nfuturistic funk\nfuturistic garage\nfuturistic gospel\nfuturistic gospel trap\nfuturistic hip-hop\nfuturistic house\nfuturistic indie rock\nfuturistic jazz hop\nfuturistic jazz-hop\nfuturistic pop\nfuturistic pop metalcore\nfuturistic pop, trap, hip-hop\nfuturistic pop-R&B\nfuturistic pop-rap\nfuturistic pop-trap\nfuturistic power metal\nfuturistic reggaeton\nfuturistic sound design\nfuturistic synth\nfuturistic techno\nfuturistic trance\nfuturistic trance hip-hop\nfuturistic trance-pop\nfuturistic trap\nfuturistic trap R&B\nfuturistic trap metalcore\nfuturistic trap, cloud rap\nfuturistic trap, hyperpop\nfuturistic trap-rock\nfuturistic trip-hop\ngabber\ngabber chiptune\ngabber happy hardcore\ngabber hardcore\ngabber hardcore techno\ngabber hardstyle\ngabber rap\ngabber rave\ngabber speedcore\ngabber speedcore breakcore\ngabber techno\ngabber trap\ngabber, Chinese fusion, electronic\ngabber, Indian folk, hard electronic\ngabber, alternative rock, happy hardcore\ngabber, ambient, experimental\ngabber, ambient, happy hardcore\ngabber, breakcore, speedcore\ngabber, chiptune, hardcore\ngabber, chiptune, lo-fi electronic\ngabber, chiptune, vaporwave\ngabber, cinematic, trance\ngabber, comedy rap, Japanese novelty\ngabber, denpa-kei, happy hardcore\ngabber, denpa-kei, hardcore\ngabber, digital hardcore\ngabber, electronic, hip hop\ngabber, happy hardcore\ngabber, happy hardcore, J-pop\ngabber, happy hardcore, Russian rap\ngabber, happy hardcore, speedcore\ngabber, happy hardcore, trancecore\ngabber, happy hardcore, trap\ngabber, hard trance\ngabber, hardcore techno, Sinhala folk\ngabber, hardcore techno, chiptune\ngabber, hardcore techno, speedcore\ngabber, hardcore, chiptune\ngabber, hardstyle\ngabber, hardstyle, ambient\ngabber, hardstyle, electronic\ngabber, hardstyle, hardcore\ngabber, lo-fi, electronic\ngabber, speedcore\ngabber, speedcore, breakcore\ngabber, speedcore, chiptune\ngabber, speedcore, cinematic\ngabber, speedcore, drum and bass\ngabber, speedcore, glitch\ngabber, speedcore, hardcore\ngabber, speedcore, hardcore techno\ngabber, speedcore, hyperpop\ngabber, speedcore, industrial\ngabber, speedcore, lo-fi electronic\ngabber, trance, electronic\ngaita charranga\ngame jingle\ngame music\ngame music jazz fusion\ngame show\ngame show theme\ngamer rap\ngamer-pop\ngamer-trap\ngaming hip-hop\ngana haryanvi\ngangsta hip-hop\ngangsta rap\ngangsta rap chiptune\ngangsta rap chiptune trap\ngangsta rap drill\ngangsta rap trap\ngangsta rap, G-funk\ngangsta rap, G-funk, Latin hip hop\ngangsta rap, G-funk, West Coast\ngangsta rap, G-funk, West Coast hip-hop\ngangsta rap, G-funk, boom-bap\ngangsta rap, G-funk, chiptune\ngangsta rap, G-funk, cinematic\ngangsta rap, German street rap\ngangsta rap, Latin hip-hop\ngangsta rap, Latin trap\ngangsta rap, Middle Eastern synth, bilingual hip hop\ngangsta rap, Southern hip-hop\ngangsta rap, Southern hip-hop, trap\ngangsta rap, West Coast trap\ngangsta rap, boom-bap\ngangsta rap, boom-bap, chiptune\ngangsta rap, chiptune\ngangsta rap, chiptune, G-funk\ngangsta rap, chiptune, Southern hip-hop\ngangsta rap, chiptune, boom-bap\ngangsta rap, chiptune, electronic\ngangsta rap, chiptune, lo-fi\ngangsta rap, chiptune, trap\ngangsta rap, cinematic hip hop\ngangsta rap, cinematic, Brazilian\ngangsta rap, cinematic, German hip hop\ngangsta rap, cinematic, Russian\ngangsta rap, cinematic, West Coast\ngangsta rap, cinematic, boom-bap\ngangsta rap, cinematic, dark ambient\ngangsta rap, cinematic, dark wave\ngangsta rap, cinematic, orchestral\ngangsta rap, cinematic, synth brass\ngangsta rap, cinematic, trap\ngangsta rap, crunk, Southern hip-hop\ngangsta rap, cumbia, trap\ngangsta rap, darkwave, lo-fi hip hop\ngangsta rap, drill\ngangsta rap, drill, lo-fi\ngangsta rap, drill, lo-fi hip hop\ngangsta rap, drill, trap\ngangsta rap, electronic, cinematic\ngangsta rap, hip hop\ngangsta rap, hip-hop\ngangsta rap, horrorcore\ngangsta rap, industrial hip-hop\ngangsta rap, lo-fi hip hop, boom-bap\ngangsta rap, lo-fi, cinematic\ngangsta rap, nu-metal, trap\ngangsta rap, orchestral, trap\ngangsta rap, regional Mexican\ngangsta rap, rock opera\ngangsta rap, soulful hip-hop\ngangsta rap, southern hip-hop\ngangsta rap, synthwave\ngangsta rap, trap\ngangsta rap, trap, Balkan hip hop\ngangsta rap, trap, Dutch hip hop\ngangsta rap, trap, G-funk\ngangsta rap, trap, West Coast\ngangsta rap, trap, West Coast hip-hop\ngangsta rap, trap, bilingual\ngangsta rap, trap, chiptune\ngangsta rap, trap, cinematic\ngangsta rap, trap, classical hip hop\ngangsta rap, trap, drill\ngangsta rap, trap, jazz rap\ngangsta rap, trap, orchestral\ngangsta rap, west coast, g-funk\ngangsta reggaeton\ngangsta trap\ngangster hip-hop\ngangster rap\ngangster rap bhangra\ngangster rap chiptune\ngangster rap trap\ngangster rap, G-funk\ngangster rap, Indian folk\ngangster rap, cinematic hip-hop\ngarage blues\ngarage blues-rock\ngarage folk\ngarage funk\ngarage house\ngarage pop\ngarage punk\ngarage punk chiptune\ngarage punk noise rock\ngarage punk rock\ngarage punk, C-pop, cinematic\ngarage punk, alt-rock, rock\ngarage punk, blues-rock\ngarage punk, chiptune\ngarage punk, hard rock, alt-rock, R&B, funk-pop\ngarage punk, indie rock, shoegaze\ngarage punk, shoegaze, surf rock\ngarage punk, techno-rock\ngarage rock\ngarage rock alternative rock\ngarage rock blues\ngarage rock blues country\ngarage rock blues rock\ngarage rock blues-rock\ngarage rock boogie-woogie\ngarage rock chiptune\ngarage rock country-rock\ngarage rock desert rock\ngarage rock emo\ngarage rock enka\ngarage rock flamenco\ngarage rock folk-punk\ngarage rock funk\ngarage rock funk hip-hop\ngarage rock funk psychedelic\ngarage rock funk rock\ngarage rock funk soul\ngarage rock funk-rock\ngarage rock gospel\ngarage rock hip-hop\ngarage rock hyperpop\ngarage rock indie\ngarage rock indie rock\ngarage rock lo-fi\ngarage rock noise rock\ngarage rock noise rock funk rock\ngarage rock parody\ngarage rock post-punk\ngarage rock power pop\ngarage rock power-pop\ngarage rock psychedelic\ngarage rock psychedelic rock\ngarage rock pub rock\ngarage rock punk\ngarage rock punk rock\ngarage rock punk surf rock\ngarage rock revival\ngarage rock rockabilly\ngarage rock ska-punk\ngarage rock soul\ngarage rock soul latin\ngarage rock spaghetti western\ngarage rock surf rock\ngarage rock surf-punk\ngarage rock surf-rock\ngarage rock trap\ngarage rock, 60s French pop\ngarage rock, 60s French pop-rock\ngarage rock, 60s Latin rock\ngarage rock, 60s Mandopop\ngarage rock, 60s Nederpop\ngarage rock, French chanson\ngarage rock, French pop\ngarage rock, French pop-rock\ngarage rock, Indonesian pop-rock\ngarage rock, J-rock\ngarage rock, Kayōkyoku\ngarage rock, Latin rock\ngarage rock, Latin rock, surf rock\ngarage rock, Latin, cinematic\ngarage rock, Mandopop\ngarage rock, Neue Deutsche Welle\ngarage rock, Russian folk\ngarage rock, alt-country\ngarage rock, alt-country, country-rock\ngarage rock, art rock\ngarage rock, art-punk\ngarage rock, baroque pop, experimental\ngarage rock, big band, cinematic ballad\ngarage rock, big band, free jazz\ngarage rock, blues-rock\ngarage rock, britpop, rap\ngarage rock, classic rock\ngarage rock, country rock\ngarage rock, country rock, rockabilly\ngarage rock, country, rockabilly\ngarage rock, dream pop\ngarage rock, electro-rock\ngarage rock, electronic dance, happy hardcore\ngarage rock, experimental, post-punk\ngarage rock, flamenco, indie rock\ngarage rock, folk, theatrical\ngarage rock, hard rock, surf rock\ngarage rock, hyper-pop\ngarage rock, hyperpop\ngarage rock, indie ballad\ngarage rock, indie rock\ngarage rock, indie rock, French pop\ngarage rock, lo-fi, dream pop\ngarage rock, new wave\ngarage rock, noise rock\ngarage rock, noise rock, folk\ngarage rock, piano ballad\ngarage rock, pop-punk\ngarage rock, pop-rock\ngarage rock, post-punk\ngarage rock, post-rock\ngarage rock, power pop\ngarage rock, power-pop, British\ngarage rock, proto-punk, 60s rock\ngarage rock, psychedelic blues-rock\ngarage rock, psychedelic rock\ngarage rock, psychedelic rock, French chanson\ngarage rock, psychedelic rock, country\ngarage rock, psychedelic, 60s\ngarage rock, punk rock, Chinese rock\ngarage rock, punk rock, blues rock\ngarage rock, punk rock, industrial\ngarage rock, punk rock, psychedelic rock\ngarage rock, punk, Latin rock\ngarage rock, rap, indie folk\ngarage rock, rap-rock, psychedelic\ngarage rock, rockabilly\ngarage rock, rockabilly, blues\ngarage rock, rockabilly, country\ngarage rock, rockabilly, country rock\ngarage rock, rockabilly, country-rock\ngarage rock, rockabilly, psychedelic rock\ngarage rock, schlager, Scandinavian\ngarage rock, shoegaze, alternative rock\ngarage rock, soul, rockabilly\ngarage rock, southern rock\ngarage rock, spaghetti western\ngarage rock, surf rock\ngarage rock, surf rock, Japanese soul\ngarage rock, surf rock, lo-fi\ngarage rock, surf rock, novelty\ngarage rock, surf rock, retro\ngarage rock, surf rock, rock and roll\ngarage rock, surf rock, rockabilly\ngarage rock, surf rock, vintage rock\ngarage rock, surf-punk\ngarage rock, surf-punk, Latin rock\ngarage rock, world music\ngarage rockabilly\ngarage-folk\ngarage-punk\ngarage-punk thrash metal\ngarageba\ngarageet\ngeek-folk\ngenre-bending\ngenre-bending pop\ngenre-bending rock\ngenre-bending, R&B, synth-pop\ngenre-bending, cinematic, dancehall\ngenre-bending, cinematic, funk-pop\ngenre-bending, electronic, pop-rock\ngenre-bending, funk, Latin, cinematic\ngenre-bending, hip-hop, chiptune\ngenre-bending, new wave, indie-pop\ngenre-bending, nu-metal, pop-punk\ngenre-bending, punk rock, chiptune\ngenre-bending, punk rock, lo-fi\ngentle pop\ngentle pop ballad\nghazal\nghazal bhajan\nghazal bhangra\nghazal bhangra fusion\nghazal cinematic\nghazal electronica\nghazal filmi\nghazal folk\nghazal folk-dance\nghazal folk-pop\nghazal fusion\nghazal lo-fi\nghazal pop\nghazal pop-rock\nghazal qawwali\nghazal rock\nghazal trap\nghazal trap R&B\nghazal trap lo-fi\nghazal trap lo-fi hip-hop\nghazal, Bollywood, ambient ballad\nghazal, Indian classical, acoustic\nghazal, Indian classical, ambient\nghazal, Indian classical, ballad\nghazal, Indian classical, cinematic\nghazal, Indian classical, folk\nghazal, Indian classical, lo-fi\nghazal, Indian classical, melancholic\nghazal, Indian classical, qawwali\nghazal, Indian classical, soulful\nghazal, Indian classical, spiritual\nghazal, Indian classical, world fusion\nghazal, Indian folk, ambient\nghazal, Punjabi folk, ambient world\nghazal, R&B, cinematic\nghazal, R&B, electronic\nghazal, South Asian classical, fusion\nghazal, South Asian, cinematic\nghazal, South Asian, melancholic\nghazal, acoustic ballad, ambient\nghazal, acoustic ballad, world music\nghazal, acoustic pop, Indian semi-classical\nghazal, acoustic, melancholic\nghazal, acoustic, melodic\nghazal, ambient electronic\nghazal, ambient folk, cinematic\nghazal, ambient pop, Indian fusion\nghazal, ambient, Indian classical\nghazal, ambient, Indian folk\nghazal, ambient, South Asian\nghazal, ambient, South Asian classical\nghazal, ambient, acoustic\nghazal, ambient, cinematic\nghazal, ambient, classical\nghazal, ambient, classical Indian\nghazal, ambient, electronic\nghazal, ambient, ethereal\nghazal, ambient, lo-fi\nghazal, ambient, soul\nghazal, ambient, synthwave\nghazal, ambient, traditional\nghazal, ambient, traditional Indian\nghazal, ambient, world fusion\nghazal, ambient, world music\nghazal, bhangra\nghazal, bhangra-pop\nghazal, chiptune, ambient\nghazal, cinematic, Bollywood\nghazal, cinematic, Indian classical\nghazal, cinematic, ambient\nghazal, cinematic, lo-fi\nghazal, cinematic, melancholic\nghazal, cinematic, orchestral\nghazal, cinematic, sitar\nghazal, cinematic, soulful\nghazal, cinematic, world music\nghazal, classical, ambient\nghazal, classical, lo-fi\nghazal, classical, world fusion\nghazal, downtempo, ambient\nghazal, electronic pop, ambient\nghazal, electronic, Bollywood filmi-pop\nghazal, electronic, ambient\nghazal, electronic, cinematic\nghazal, electronic, devotional\nghazal, electronic, rock\nghazal, electronic, trap\nghazal, electronic, trip-hop\nghazal, electronic, world music\nghazal, ethereal, melancholic\nghazal, filmi, smooth jazz\nghazal, flamenco, ambient\nghazal, folk dance\nghazal, folk dance, electronic\nghazal, folk, ambient\nghazal, folk, cinematic\nghazal, folk, traditional South Asian\nghazal, folk-dance\nghazal, folk-dance, ambient\nghazal, folk-dance, operatic\nghazal, folk-pop, Indian classical\nghazal, folk-pop, ambient\nghazal, lo-fi electronic\nghazal, lo-fi hip hop, trap\nghazal, lo-fi, Indian film\nghazal, lo-fi, chillwave\nghazal, lounge, ambient pop\nghazal, melancholic ballad, ambient\nghazal, melancholic, Indian classical\nghazal, melancholic, ballad\nghazal, melancholic, blues\nghazal, retro, synth\nghazal, soft pop, smooth jazz\nghazal, soft rock, ambient\nghazal, soulful, Indian classical\nghazal, soulful, acoustic\nghazal, soulful, ambient\nghazal, soulful, melancholic\nghazal, synth, electronic\nghazal, world fusion, cinematic\nghazal, world fusion, classical Indian\nghazal, world fusion, devotional\nghazal, world music, cinematic\nghazal, world music, spiritual\nghazal, world music, traditional Indian\nghazal-inspired\nghazal-inspired ambient\nghazal-inspired ballad\nghazal-inspired, cinematic rock, ambient pop\nghazal-pop\nghazal-pop jazz lounge\nglam house vogue\nglam metal\nglam metal electronicore\nglam metal power metal\nglam metal synth-pop\nglam metal synth-rock\nglam metal, J-rock\nglam metal, hard rock\nglam metal, hyper-pop\nglam metal, new jack swing, R&B\nglam metal, power ballad, pop-rock\nglam metal, synth-pop, video game music\nglam pop\nglam punk\nglam rock\nglam rock R&B\nglam rock alternative rock\nglam rock cabaret\nglam rock disco\nglam rock funk\nglam rock pop\nglam rock progressive rock\nglam rock synth-pop\nglam rock synthwave\nglam rock, alternative rock, cinematic\nglam rock, city pop\nglam rock, dance-pop, soul\nglam rock, funk, operatic, theatrical\nglam rock, new wave\nglam rock, trap, ambient\nglam-disco\nglam-funk\nglam-punk\nglamorous house\nglitch\nglitch R&B\nglitch ambient\nglitch breakbeat\nglitch chiptune\nglitch classical\nglitch core\nglitch drum\nglitch dubstep\nglitch electonica\nglitch electro\nglitch electronica\nglitch electropop\nglitch folk\nglitch funk\nglitch hop\nglitch hop ambient\nglitch hop breakcore\nglitch hop dubstep\nglitch hop electro synthwave\nglitch hop experimental\nglitch hop hardstyle\nglitch hop industrial\nglitch hop rock\nglitch hop trap\nglitch hop, J-rock, breakbeat\nglitch hop, breakcore, chiptune\nglitch hop, breakcore, hardstyle\nglitch hop, chiptune, electronic\nglitch hop, color bass, hyperpop\nglitch hop, complextro\nglitch hop, experimental EDM\nglitch hop, experimental trap, hardwave\nglitch hop, hardstyle\nglitch hop, hyperpop, Swedish rap\nglitch hop, industrial rock, ambient\nglitch hop, speedcore, chiptune\nglitch hop, trap, Arabic electronic\nglitch house\nglitch jazz\nglitch metal\nglitch metalcore\nglitch microhouse\nglitch music\nglitch noise\nglitch percussion\nglitch pop\nglitch pop future bass\nglitch pop noise rock\nglitch pop, electronic, reggaeton\nglitch pop, trap, ambient\nglitch rock\nglitch soul\nglitch techno\nglitch trap\nglitch trap, cloud rap\nglitch vocal\nglitch, IDM, ambient\nglitch, IDM, ambient electronica\nglitch, IDM, chiptune\nglitch, IDM, experimental electronic\nglitch, IDM, experimental house\nglitch, ambient, cinematic\nglitch, ambient, electronic\nglitch, ambient, experimental\nglitch, ambient, industrial\nglitch, ambient, instrumental\nglitch, ambient, trip-hop\nglitch, art rock, J-rock\nglitch, breakcore, ambient\nglitch, breakcore, electronic\nglitch, chiptune\nglitch, chiptune, electronic\nglitch, chiptune, experimental electronic\nglitch, cinematic, acid techno\nglitch, cinematic, industrial\nglitch, cinematic, orchestral\nglitch, cinematic, synthwave\nglitch, dark ambient, experimental\nglitch, electronic, ambient\nglitch, electronic, ritual techno\nglitch, experimental, Afro-electronic\nglitch, experimental, ambient\nglitch, hyperpop\nglitch, industrial, cinematic\nglitch, industrial, experimental techno\nglitch, neurofunk, ambient\nglitch, neurofunk, electronic\nglitch, speedcore, chiptune\nglitch, world fusion, ambient techno\nglitch, world percussion, ambient\nglitch-funk\nglitch-hop\nglitch-hop IDM\nglitch-hop K-pop\nglitch-hop ambient\nglitch-hop art pop cinematic\nglitch-hop atmospheric trap\nglitch-hop boom-bap\nglitch-hop breakbeat\nglitch-hop breakcore\nglitch-hop breakcore experimental trap\nglitch-hop breakcore indie-folk\nglitch-hop chiptune\nglitch-hop chiptune experimental\nglitch-hop cinematic\nglitch-hop complextro\nglitch-hop dream-pop\nglitch-hop dubstep\nglitch-hop electro hyperpop\nglitch-hop electro-funk\nglitch-hop electro-house\nglitch-hop electronic pop\nglitch-hop experimental\nglitch-hop experimental R&B\nglitch-hop experimental bass\nglitch-hop experimental breakbeat\nglitch-hop experimental club\nglitch-hop experimental electronic\nglitch-hop experimental hip-hop\nglitch-hop experimental pop\nglitch-hop experimental rap\nglitch-hop experimental techno\nglitch-hop experimental trap\nglitch-hop french pop\nglitch-hop french rap\nglitch-hop funk\nglitch-hop future bass\nglitch-hop future bass emotional pop\nglitch-hop hyperpop\nglitch-hop hyperpop breakcore\nglitch-hop hyperpop chiptune\nglitch-hop hyperpop dream pop\nglitch-hop hyperpop industrial\nglitch-hop hyperpop trap\nglitch-hop industrial\nglitch-hop industrial hip-hop\nglitch-hop industrial-trap\nglitch-hop lo-fi\nglitch-hop lo-fi hip hop\nglitch-hop lo-fi hip-hop\nglitch-hop microhouse\nglitch-hop minimal tech\nglitch-hop minimal techno\nglitch-hop neurofunk\nglitch-hop trap\nglitch-hop trap K-pop\nglitch-hop trap metal\nglitch-hop world music\nglitch-hop, C-pop, electronic\nglitch-hop, Indian classical, electronic fusion\nglitch-hop, R&B, Christmas\nglitch-hop, breakbeat, C-pop\nglitch-hop, breakbeat, art pop\nglitch-hop, breakcore, J-pop\nglitch-hop, breakcore, Vocaloid\nglitch-hop, breakcore, ambient\nglitch-hop, breakcore, experimental bass\nglitch-hop, breakcore, experimental electronic\nglitch-hop, breakcore, future pop\nglitch-hop, breakcore, synth-pop\nglitch-hop, chiptune, hip-hop\nglitch-hop, chiptune, rap battle\nglitch-hop, cinematic, dubstep\nglitch-hop, cinematic, future bass\nglitch-hop, drum and bass, ambient\nglitch-hop, dubstep, ambient\nglitch-hop, dubstep, cyberpunk\nglitch-hop, experimental electronic, Bollywood\nglitch-hop, experimental electronic, electronic hip-hop\nglitch-hop, experimental hip-hop, industrial\nglitch-hop, experimental hip-hop, psychedelic R&B\nglitch-hop, hardstyle, cyberpunk\nglitch-hop, hyperpop, chiptune\nglitch-hop, hyperpop, complextro\nglitch-hop, hyperpop, experimental\nglitch-hop, orchestral hip-hop, dubstep\nglitch-hop, trap, chiptune\nglitch-hop, trap, cinematic\nglitch-hop, trap, cyberpunk\nglitch-hop, trap, neo-soul\nglitch-pop\nglitch-pop art pop\nglitch-pop art-pop\nglitch-pop avant-garde\nglitch-pop cyberpunk\nglitch-pop electronic rock\nglitch-pop experimental electronic\nglitch-pop future bass\nglitch-pop hyperpop\nglitch-pop j-pop jazz-fusion\nglitch-pop lo-fi\nglitch-pop neo-soul\nglitch-pop, hyperpop, experimental hip-hop\nglitchcore\nglitchcore ambient\nglitchcore artcore\nglitchcore breakcore\nglitchcore chiptune\nglitchcore complextro\nglitchcore hardwave\nglitchcore hyperpop\nglitchcore punk\nglitchcore trap\nglitchcore, ambient, future bass\nglitchcore, breakcore, ambient\nglitchcore, experimental hip-hop\nglitchy ambient\nglitchy breakbeat\nglitchy breakcore\nglitchy drum and bass\nglitchy microhouse\nglobal bass\nglobal bass baile funk\nglobal bass moombahton\nglobal bass, trap, experimental electronic\nglobal beat\nglobal fusion\nglobal fusion trap\nglobal gospel hip-hop\nglobal hip hop\nglobal hip-hop\nglobal house\nglobal pop\nglobal pop moombahton\nglobal pop reggaeton\nglobal pop, EDM, Bollywood\nglobal pop, South Asian fusion\nglobal pop, dancehall, reggaeton\nglobal pop-funk\nglobal pop-rap\nglobal trap\ngo-go\ngolden-age hip-hop\ngolden-era hip-hop\ngospel\ngospel Afrobeat\ngospel Afrobeat Highlife\ngospel Afrobeat dancehall\ngospel Afrobeat smooth jazz\ngospel Americana\ngospel CCM\ngospel Christmas\ngospel Christmas ballad\ngospel EDM\ngospel EDM chiptune\ngospel J-pop\ngospel Latin\ngospel Latin jazz\ngospel MPB\ngospel R&B\ngospel R&B Afrobeats\ngospel R&B Afropop\ngospel R&B Christmas\ngospel R&B a cappella\ngospel R&B afrobeat\ngospel R&B ambient\ngospel R&B chiptune\ngospel R&B conscious hip-hop\ngospel R&B dancehall\ngospel R&B electronic\ngospel R&B funk\ngospel R&B hip-hop\ngospel R&B lo-fi hip-hop\ngospel R&B neo-soul\ngospel R&B pop\ngospel R&B pop-rock\ngospel R&B smooth jazz\ngospel R&B soft rock\ngospel R&B soul\ngospel R&B synth-pop\ngospel R&B trap\ngospel R&B zouk\ngospel R&B, G-funk, funk\ngospel a cappella\ngospel adult contemporary\ngospel afro-caribbean\ngospel afro-house\ngospel afro-soul\ngospel afrobeat\ngospel afrobeat R&B\ngospel afrobeat boogie-woogie\ngospel afrobeat dancehall\ngospel afrobeat french pop\ngospel afrobeat funk\ngospel afrobeat highlife\ngospel afrobeat pop\ngospel afrobeat trap\ngospel afrobeat world music\ngospel afrobeats\ngospel afrobeats dancehall\ngospel afrobeats french pop\ngospel afrobeats highlife\ngospel afrobeats pop\ngospel afrobeats r&b\ngospel afrobeats rnb\ngospel afrobeats soca\ngospel afrobeats world music\ngospel afrobeats zouk\ngospel afropop\ngospel afropop highlife\ngospel afropop latin\ngospel afropop r&b\ngospel afropop reggae\ngospel afropop zouk\ngospel amapiano\ngospel ambient\ngospel anthem\ngospel art song\ngospel axé\ngospel ballad\ngospel ballad, Afropop, South African house\ngospel ballad, Latin rock\ngospel ballad, synth-pop\ngospel barbershop\ngospel big band\ngospel bluegrass\ngospel bluegrass country\ngospel blues\ngospel blues funk soul\ngospel blues rock\ngospel blues, Afro-Cuban jazz\ngospel blues, big band swing\ngospel blues, boogie-woogie, rock and roll\ngospel blues-rock\ngospel boogie-woogie\ngospel boogie-woogie big band\ngospel bossa nova\ngospel brega\ngospel calypso\ngospel chanson\ngospel children's\ngospel chiptune\ngospel chiptune afrobeat\ngospel chiptune afrobeats\ngospel chiptune dancehall\ngospel chiptune reggae\ngospel chiptune reggaeton\ngospel choir\ngospel choral\ngospel classical ambient\ngospel club\ngospel country\ngospel country bluegrass\ngospel country blues\ngospel country folk\ngospel country rock\ngospel country swing\ngospel country-pop\ngospel country-rock\ngospel crossover\ngospel cumbia\ngospel dance\ngospel dance-pop\ngospel dancehall\ngospel dancehall afrobeat\ngospel dancehall afrobeats\ngospel dancehall funk\ngospel dancehall hip-hop\ngospel disco\ngospel doo-wop\ngospel drill\ngospel electronic\ngospel folk\ngospel folk-rock\ngospel forró\ngospel funk\ngospel funk Afrobeat\ngospel funk Latin pop\ngospel funk R&B\ngospel funk afrobeat\ngospel funk big band\ngospel funk blues rock\ngospel funk dancehall\ngospel funk disco\ngospel funk disco neo-soul\ngospel funk electronic\ngospel funk electronic pop\ngospel funk hip-hop\ngospel funk latin\ngospel funk latin jazz\ngospel funk new jack swing\ngospel funk progressive rock\ngospel funk reggae\ngospel funk rock\ngospel funk rockabilly\ngospel funk soul\ngospel funk synth-pop\ngospel funk-pop\ngospel funk-rock\ngospel funk-rock hard rock\ngospel fusion\ngospel hard rock\ngospel highlife\ngospel hip hop\ngospel hip-hop\ngospel hip-hop cinematic\ngospel hip-hop electronic\ngospel hip-hop funk\ngospel hip-hop future bass\ngospel hip-hop pop\ngospel hip-hop rap-rock\ngospel hip-hop rock\ngospel hip-hop soul\ngospel hip-hop, French rap\ngospel hip-hop, anthemic rock\ngospel house\ngospel house hip hop\ngospel hymn\ngospel indie rock\ngospel jazz\ngospel jazz R&B\ngospel jazz ballad\ngospel jazz funk\ngospel jazz fusion\ngospel jazz progressive rock\ngospel latin pop\ngospel lo-fi hip hop\ngospel lo-fi hip-hop\ngospel lullaby\ngospel march\ngospel marching band\ngospel metal\ngospel neo-soul\ngospel neo-soul afrobeat\ngospel neo-soul funk\ngospel neo-soul jazz fusion\ngospel neo-soul lounge\ngospel new jack swing\ngospel piano ballad\ngospel polka\ngospel pop\ngospel pop R&B\ngospel pop afrobeats\ngospel pop afrobeats zouk\ngospel pop afropop\ngospel pop chiptune afrobeat\ngospel pop funk\ngospel pop hip-hop\ngospel pop jazz\ngospel pop reggaeton\ngospel pop rock\ngospel pop world music\ngospel pop zouk\ngospel pop, 80s synth-pop\ngospel pop, Brazilian pop\ngospel pop, Latin salsa\ngospel pop, big band jazz\ngospel pop, city pop\ngospel pop, city pop, funk\ngospel pop, zouk, afro-caribbean\ngospel pop-rap\ngospel pop-rock\ngospel pop-rock, EDM\ngospel pop-sertanejo\ngospel power ballad\ngospel power ballad, Brazilian Axé, samba-reggae\ngospel power metal\ngospel power-pop\ngospel praise\ngospel punk\ngospel ragtime\ngospel ragtime show tune\ngospel rap\ngospel rap R&B\ngospel rap afrobeats\ngospel rap cumbia\ngospel rap trap\ngospel rap, electronic dance, pop-rock\ngospel reggae\ngospel reggae R&B\ngospel reggae afrobeat\ngospel reggae dancehall\ngospel reggae highlife\ngospel reggae pop-rock\ngospel reggae rock\ngospel reggae roots reggae\ngospel reggae ska\ngospel reggae soul\ngospel reggaeton\ngospel rock\ngospel rock blues\ngospel rock blues rock\ngospel rock chiptune\ngospel rock country\ngospel rock country-rock\ngospel rock funk\ngospel rock hard rock\ngospel rock opera\ngospel rock salsa\ngospel rock samba\ngospel rock samba-reggae\ngospel rock samba-rock\ngospel rock, Latin rock\ngospel rock, alternative metal\ngospel rock, bossa nova, acoustic\ngospel rock, country rock, rockabilly\ngospel rock, electronic dance\ngospel rock, electronic dance music\ngospel rockabilly\ngospel rockabilly country\ngospel roots rock\ngospel salsa\ngospel samba\ngospel samba-reggae\ngospel schlager\ngospel sertanejo\ngospel sertanejo forró\ngospel show tune\ngospel show tunes big band\ngospel ska\ngospel smooth jazz\ngospel soca\ngospel soft rock\ngospel soukous\ngospel soul\ngospel soul country\ngospel soul funk\ngospel soul hip-hop\ngospel soul jazz\ngospel soul jazz-funk\ngospel soul rock\ngospel soul salsa\ngospel soul trip-hop\ngospel soul zouk\ngospel spiritual\ngospel spiritual, americana, folk-rock\ngospel spoken word\ngospel swing\ngospel swing balkan brass\ngospel swing klezmer\ngospel swing rockabilly\ngospel synth-funk\ngospel synth-pop\ngospel synth-pop afropop\ngospel synth-pop worldbeat\ngospel trance\ngospel trap\ngospel trap R&B\ngospel trot\ngospel video game\ngospel waltz\ngospel world music\ngospel worldbeat\ngospel worship\ngospel zouk\ngospel zouk afrobeats\ngospel zouk afropop\ngospel zouk r&b\ngospel zouk soca\ngospel zouk soukous\ngospel, 90s R&B, Afro-soul\ngospel, 90s R&B, synth-pop\ngospel, African gospel, Soukous\ngospel, African gospel, soukous\ngospel, Afro-Caribbean, Christmas\ngospel, Afro-Caribbean, Latin\ngospel, Afro-Caribbean, anthemic\ngospel, Afro-Caribbean, funk\ngospel, Afro-Caribbean, live\ngospel, Afro-Caribbean, soul\ngospel, Afro-Caribbean, upbeat\ngospel, Afro-Caribbean, worldbeat\ngospel, Afro-Caribbean, zouk\ngospel, Afro-funk, isicathamiya\ngospel, Afro-pop\ngospel, Afro-pop, Soukous\ngospel, Afro-pop, dance\ngospel, Afro-pop, zouk\ngospel, Afrobeat\ngospel, Afrobeat, Highlife\ngospel, Afrobeat, South African\ngospel, Afrobeat, soul\ngospel, Afrobeat, spiritual\ngospel, Arabic pop, world music\ngospel, Balkan brass, Latin\ngospel, Balkan, Klezmer\ngospel, Brazilian pop-rock\ngospel, Brazilian, choral\ngospel, Brazilian, cinematic\ngospel, Brazilian, rock\ngospel, Caribbean folk, zouk\ngospel, Caribbean, celebratory\ngospel, Caribbean, funk\ngospel, Caribbean, soul\ngospel, Christmas, soul\ngospel, Hawaiian, soul\ngospel, J-RPG, cinematic\ngospel, J-RPG, orchestral\ngospel, Latin folk, cumbia\ngospel, Latin pop\ngospel, Latin pop, rock\ngospel, Latin pop-rock\ngospel, Latin, African\ngospel, Latin, Caribbean\ngospel, Latin, live\ngospel, Latin, pop-rock\ngospel, Latin, soul\ngospel, Latin, upbeat\ngospel, Latin, world music\ngospel, MPB, cinematic\ngospel, MPB, cinematic pop\ngospel, MPB, funk\ngospel, Middle Eastern, Klezmer\ngospel, Middle Eastern, dance\ngospel, R&B\ngospel, R&B, cinematic\ngospel, South African house\ngospel, adult contemporary\ngospel, adult contemporary, power ballad\ngospel, afro gospel, vintage\ngospel, afro pop\ngospel, afro pop, reggae\ngospel, afro rumba, soukous\ngospel, afro-caribbean, funk\ngospel, afro-latin, soul\ngospel, afro-pop\ngospel, afro-pop, contemporary\ngospel, afro-pop, highlife\ngospel, afro-pop, jazz\ngospel, afro-pop, soul\ngospel, afro-pop, zouk\ngospel, afro-soukous\ngospel, afro-soul\ngospel, afrobeat, afro-jazz\ngospel, afrobeat, caribbean\ngospel, afrobeat, choir\ngospel, afrobeat, dancehall\ngospel, afrobeat, highlife\ngospel, afrobeat, soul\ngospel, afrobeat, world music\ngospel, afrobeats, cinematic\ngospel, afrobeats, dancehall\ngospel, afrobeats, highlife\ngospel, afrobeats, r&b\ngospel, afropop\ngospel, afropop, caribbean\ngospel, afropop, highlife\ngospel, afropop, r&b\ngospel, amapiano, afro-house\ngospel, ambient, Afro-soul\ngospel, ambient, world music\ngospel, axé, Brazilian\ngospel, axé, ambient\ngospel, axé, cinematic\ngospel, axé, live performance\ngospel, axé, samba-reggae\ngospel, big band, Latin\ngospel, big band, children's music\ngospel, big band, cinematic\ngospel, big band, retro\ngospel, big band, sacred\ngospel, big band, show tune\ngospel, bluegrass, country\ngospel, bluegrass, country-gospel\ngospel, bluegrass, newgrass\ngospel, boogie-woogie\ngospel, brass band, synth\ngospel, celtic folk\ngospel, chiptune, afrobeat\ngospel, chiptune, afrobeats\ngospel, christmas, soul\ngospel, cinematic, power ballad\ngospel, cinematic, rock\ngospel, classical choral, progressive rock\ngospel, classical, boogie-woogie\ngospel, classical, christmas\ngospel, contemporary Christian, cinematic\ngospel, contemporary, African\ngospel, country-gospel\ngospel, country-gospel, ragtime\ngospel, electronic, Afro-soul\ngospel, electronic, psychedelic\ngospel, forró\ngospel, forró, Brazilian\ngospel, forró, baião\ngospel, forró, cinematic\ngospel, forró, sertanejo\ngospel, funk, disco\ngospel, isicathamiya, dance\ngospel, isicathamiya, electronic\ngospel, isicathamiya, mbaqanga\ngospel, latin pop\ngospel, latin, cinematic\ngospel, latin, funk\ngospel, latin, salsa\ngospel, liturgical, choral\ngospel, lo-fi hip hop, cinematic\ngospel, lo-fi hip hop, jazz\ngospel, marching band\ngospel, musical theater\ngospel, musical theater, cinematic\ngospel, musical theater, power ballad\ngospel, neo-soul, funk\ngospel, new age, world music\ngospel, new jack swing, R&B\ngospel, new jack swing, piano ballad\ngospel, new jack swing, soul\ngospel, new jack swing, synth-pop\ngospel, pop-rock, Brazilian\ngospel, ragtime, choral\ngospel, ragtime, country gospel\ngospel, retro synth, Brazilian\ngospel, rockabilly\ngospel, salsa, funk\ngospel, samba-reggae\ngospel, smooth jazz, R&B\ngospel, sokkie, playhall\ngospel, soukous, afrobeat\ngospel, soul, Christmas\ngospel, soul, christmas\ngospel, spiritual, Americana\ngospel, synth-pop, dance-pop\ngospel, world music\ngospel, world music, R&B\ngospel, worldbeat, pop\ngospel, zouk, Caribbean\ngospel, zouk, Caribbean pop\ngospel, zouk, afrobeats\ngospel, zouk, afropop\ngospel, zouk, kompa\ngospel, zouk, r&b\ngospel, zouk, soukous\ngospel-blues\ngospel-blues country\ngospel-blues country-rock\ngospel-blues folk-rock\ngospel-blues funk\ngospel-blues funk soul\ngospel-blues rock\ngospel-blues, French chanson, spiritual\ngospel-blues, bluegrass\ngospel-blues, boogie-woogie, rock and roll\ngospel-country\ngospel-folk\ngospel-folk, bluegrass, gypsy-jazz\ngospel-funk\ngospel-infused pop\ngospel-jazz\ngospel-pop\ngospel-pop Afro-Caribbean\ngospel-pop Afro-Latin\ngospel-pop Afrobeat\ngospel-pop Afrobeat Latin\ngospel-pop Afrobeat funk\ngospel-pop Afrobeat smooth jazz\ngospel-pop J-pop anime soundtrack\ngospel-pop R&B\ngospel-pop afrobeat\ngospel-pop afrobeat dancehall\ngospel-pop afrobeats\ngospel-pop afrobeats dancehall\ngospel-pop afrobeats hip-hop\ngospel-pop bossa nova\ngospel-pop children's music\ngospel-pop chiptune\ngospel-pop chiptune R&B\ngospel-pop chiptune breakbeat\ngospel-pop country\ngospel-pop country swing\ngospel-pop cumbia\ngospel-pop disco-funk\ngospel-pop funk\ngospel-pop funk disco\ngospel-pop funk jazz fusion\ngospel-pop funk soul\ngospel-pop funk-rock\ngospel-pop future bass\ngospel-pop hip-hop\ngospel-pop j-pop\ngospel-pop jazz\ngospel-pop jazz swing\ngospel-pop latin\ngospel-pop lo-fi hip-hop\ngospel-pop nu-disco\ngospel-pop reggae\ngospel-pop reggae-dancehall\ngospel-pop retro\ngospel-pop salsa\ngospel-pop smooth jazz\ngospel-pop world music\ngospel-pop, 80s synth-pop\ngospel-pop, EDM\ngospel-pop, Latin jazz\ngospel-pop, Latin, celebratory\ngospel-pop, MPB\ngospel-pop, R&B, chiptune\ngospel-pop, big band jazz\ngospel-pop, bossa nova, smooth jazz\ngospel-pop, cinematic, Latin pop\ngospel-pop, funk-rock\ngospel-punk\ngospel-rap\ngospel-reggae\ngospel-rock\ngospel-rock jazz fusion\ngospel-rock opera\ngospel-rock, lo-fi funk\ngospel-samba\ngospel-ska\ngospel-soca\ngospel-soul\ngospel-soul funk-rock\ngospel-soul synth-funk\ngospel-soul, lo-fi hip-hop, cinematic\ngospel-soul, new jack swing\ngospel-trap\ngoth punk\ngoth rock\ngoth-punk\ngothic\ngothic Americana\ngothic Americana, trap\ngothic EBM\ngothic J-pop\ngothic alternative rock\ngothic ambient\ngothic americana\ngothic anime ballad\ngothic art song\ngothic art-pop\ngothic art-rock\ngothic ballad\ngothic baroque\ngothic bluegrass\ngothic blues\ngothic blues-rock\ngothic cabaret\ngothic cabaret rock\ngothic chiptune\ngothic cinematic\ngothic classical\ngothic country\ngothic country rock\ngothic country-rap\ngothic country-rock\ngothic cumbia\ngothic dance-pop\ngothic dream-pop\ngothic electronic\ngothic folk\ngothic folk metal\ngothic folk-rock\ngothic funk\ngothic hip hop\ngothic hip-hop\ngothic indie rock\ngothic industrial\ngothic instrumental\ngothic lullaby\ngothic metal\ngothic neoclassical\ngothic opera\ngothic orchestral\ngothic organ\ngothic pop\ngothic pop anime soundtrack\ngothic pop-rock\ngothic post-punk\ngothic punk\ngothic reggaeton\ngothic rock\ngothic rock alternative metal\ngothic rock cabaret\ngothic rock chiptune\ngothic rock darkwave\ngothic rock dream pop\ngothic rock metal\ngothic rock metalcore\ngothic rock opera\ngothic rock post-punk\ngothic rock shoegaze\ngothic rock spaghetti western\ngothic rock symphonic metal\ngothic rock symphonic rock\ngothic rock thrash metal\ngothic rock, Neue Deutsche Härte\ngothic rock, alternative metal\ngothic rock, cinematic, Afrikaans hip hop\ngothic rock, darkwave, theatrical\ngothic rock, heavy metal\ngothic rock, heavy metal, power metal\ngothic rock, post-punk\ngothic rock, symphonic metal, classical\ngothic rock, symphonic metal, dark pop\ngothic rock, synth-pop, Neue Deutsche Härte\ngothic rock, thrash metal\ngothic rock, trap\ngothic surf-rock\ngothic symphonic metal\ngothic synth\ngothic synth-pop\ngothic synth-rock\ngothic synthwave\ngothic trance\ngothic trap\ngothic trap metal\ngothic trap, cloud rap\ngothic waltz\ngothic-pop\ngrand rock\ngrandiose trap\ngrime\ngrime bhangra\ngrime cinematic\ngrime dancehall\ngrime drum and bass\ngrime dubstep\ngrime dubstep trap\ngrime garage\ngrime hip-hop\ngrime hyperpop dubstep\ngrime hyperpop electronic rock\ngrime hyperpop trap\ngrime jungle\ngrime rock\ngrime trap\ngrime trap metal\ngrime, UK drill\ngrime, dubstep, cinematic\ngrime, electronic, world music\ngrime, festive, synth\ngrime, hardstyle, moombahton\ngrime, hyperpop, hardcore techno\ngrime, orchestral, ambient\ngrindcore\ngrindcore death metal\ngrindcore mathcore\ngritty rock\ngroove metal\ngroove metal alternative rock\ngroove metal djent\ngroove metal industrial metal\ngroove metal metalcore\ngroove metal nu-metal\ngroove metal rap-metal\ngroove metal thrash\ngroove metal thrash metal\ngroove metal, deathcore, folk metal\ngroove metal, metalcore\ngroove metal, nu-metal, thrash metal\ngroove metal, symphonic metal, metalcore\ngroove metal, thrash metal, rap metal\ngroove metal, thrash metal, soul\ngroove soul\ngroovy hip-hop\ngroovy house\ngroovy instrumental\ngrunge\ngrunge alternative metal\ngrunge alternative rock\ngrunge metal\ngrunge rap\ngrunge rock\ngrunge rock indie rock\ngu aracha\nguacha\nguacha dembow\nguajira\nguajiro\nguapango\nguaracha\ngufeng\ngufeng C-pop\ngufeng chiptune\ngufeng cinematic\ngufeng electronic\ngufeng hip-hop\ngufeng pop\ngufeng, C-pop, cinematic\ngufeng, C-pop, pop-rock\ngufeng, cinematic C-pop\ngufeng, cinematic pop\ngufeng, cinematic pop, C-pop\ngufeng, cinematic pop, Chinese ballad\ngufeng, cinematic pop, ballad\ngufeng, cinematic pop, orchestral\ngufeng, cinematic, ambient\ngufeng, cinematic, electronic\ngufeng, cinematic, epic\ngufeng, cinematic, lo-fi\ngufeng, cinematic, orchestral\ngufeng, cinematic, pop\ngufeng, electronic pop\ngufeng, electronic, C-pop\ngufeng, electronic, ambient\ngufeng, electronic, cinematic\ngufeng, pop ballad, cinematic\nguitar trap\nguitar-driven trap\nguitar-trap\nguofeng\nguofeng cinematic\ngutters garage\ngypsy blues\ngypsy folk\ngypsy folk dance-pop\ngypsy folk manouche\ngypsy folk pop\ngypsy folk pop-rock\ngypsy folk rock\ngypsy folk-pop\ngypsy folk-rock\ngypsy fusion\ngypsy jazz\ngypsy jazz arabic fusion\ngypsy jazz bluegrass\ngypsy jazz blues\ngypsy jazz bossa nova\ngypsy jazz cabaret\ngypsy jazz cabaret pop\ngypsy jazz chamber folk\ngypsy jazz chamber pop\ngypsy jazz chanson\ngypsy jazz country blues\ngypsy jazz cyberpunk\ngypsy jazz dance-pop\ngypsy jazz electro-swing hip-hop\ngypsy jazz enka\ngypsy jazz exotica\ngypsy jazz flamenco\ngypsy jazz flamenco fusion\ngypsy jazz flamenco video game music\ngypsy jazz folk\ngypsy jazz folk rock\ngypsy jazz folk-rock\ngypsy jazz funk\ngypsy jazz funk electronic\ngypsy jazz funk rock\ngypsy jazz fusion\ngypsy jazz gospel\ngypsy jazz gospel swing\ngypsy jazz hip-hop\ngypsy jazz hip-hop pop-rock\ngypsy jazz indie pop\ngypsy jazz klezmer\ngypsy jazz klezmer cabaret\ngypsy jazz lo-fi hip-hop\ngypsy jazz manouche\ngypsy jazz musette\ngypsy jazz pop\ngypsy jazz pop electronic\ngypsy jazz pop-rock\ngypsy jazz punk\ngypsy jazz punk cabaret\ngypsy jazz ragtime\ngypsy jazz rock\ngypsy jazz rockabilly\ngypsy jazz rumba flamenca\ngypsy jazz ska-punk big band\ngypsy jazz soul-jazz\ngypsy jazz surf rock\ngypsy jazz swing\ngypsy jazz swing hip-hop\ngypsy jazz swing-pop\ngypsy jazz tango\ngypsy jazz tango classical\ngypsy jazz trot\ngypsy jazz western swing\ngypsy jazz, Arabic folk\ngypsy jazz, Arabic, Balkan\ngypsy jazz, Balkan brass\ngypsy jazz, Balkan brass, big band\ngypsy jazz, Balkan folk\ngypsy jazz, Balkan folk, French chanson\ngypsy jazz, Balkan folk, Latin American folk\ngypsy jazz, Balkan folk, acoustic\ngypsy jazz, Balkan folk, classical fusion\ngypsy jazz, Balkan folk, pop\ngypsy jazz, Balkan folk, punk rock\ngypsy jazz, Balkan folk, theatrical\ngypsy jazz, Balkan pop\ngypsy jazz, Balkan swing\ngypsy jazz, Balkan swing, French chanson\ngypsy jazz, Balkan, electronic\ngypsy jazz, Chinese pipa\ngypsy jazz, Eastern European folk\ngypsy jazz, Eastern European folk, cabaret\ngypsy jazz, French chanson\ngypsy jazz, French chanson, Latin\ngypsy jazz, French chanson, cabaret\ngypsy jazz, French chanson, comedic\ngypsy jazz, French chanson, surf rock\ngypsy jazz, French chanson, theatrical\ngypsy jazz, French chanson, traditional Korean\ngypsy jazz, Italian folk\ngypsy jazz, J-pop\ngypsy jazz, Latin jazz\ngypsy jazz, Latin pop-rock\ngypsy jazz, Latin rock\ngypsy jazz, Latin rumba\ngypsy jazz, Latin, French chanson\ngypsy jazz, Latin, chanson\ngypsy jazz, Latin, instrumental\ngypsy jazz, Latin, theatrical\ngypsy jazz, Mediterranean folk\ngypsy jazz, Parisian chanson\ngypsy jazz, Persian pop\ngypsy jazz, Russian bard\ngypsy jazz, Russian chanson\ngypsy jazz, Russian estrada\ngypsy jazz, Russian romance\ngypsy jazz, Turkish folk\ngypsy jazz, argentinian folk\ngypsy jazz, balkan folk\ngypsy jazz, big band swing\ngypsy jazz, bluegrass\ngypsy jazz, bluegrass, fusion\ngypsy jazz, blues-rock\ngypsy jazz, cabaret\ngypsy jazz, cabaret, Balkan swing\ngypsy jazz, cabaret, French chanson\ngypsy jazz, cabaret, theatrical\ngypsy jazz, chanson\ngypsy jazz, chanson, Arabic fusion\ngypsy jazz, chanson, cabaret\ngypsy jazz, cinematic\ngypsy jazz, cinematic, rockabilly\ngypsy jazz, classical, theatrical\ngypsy jazz, dramatic folk\ngypsy jazz, electro-swing\ngypsy jazz, electronic dance\ngypsy jazz, electronic dance music\ngypsy jazz, electronic dance, Balkan fusion\ngypsy jazz, flamenco, Russian romance\ngypsy jazz, flamenco, punk rock\ngypsy jazz, flamenco, swing\ngypsy jazz, folk rock, operatic\ngypsy jazz, forró, jazz fusion\ngypsy jazz, hard rock\ngypsy jazz, klezmer\ngypsy jazz, klezmer, Balkan\ngypsy jazz, klezmer, Balkan folk\ngypsy jazz, klezmer, French chanson\ngypsy jazz, klezmer, Latin folk\ngypsy jazz, klezmer, balkan swing\ngypsy jazz, klezmer, children's music\ngypsy jazz, klezmer, cinematic ballad\ngypsy jazz, klezmer, electronic\ngypsy jazz, klezmer, novelty\ngypsy jazz, klezmer, theatrical\ngypsy jazz, klezmer, theatrical folk\ngypsy jazz, modern classical\ngypsy jazz, musette, French chanson\ngypsy jazz, operatic pop\ngypsy jazz, pop-rock, hip-hop, indie-folk\ngypsy jazz, progressive metal, electronic\ngypsy jazz, sea shanty, folk\ngypsy jazz, show tune\ngypsy jazz, ska, French chanson\ngypsy jazz, skiffle, novelty\ngypsy jazz, swing, French chanson\ngypsy jazz, swing, children's music\ngypsy jazz, theatrical cabaret\ngypsy jazz, theatrical chanson\ngypsy jazz, theatrical folk-rock\ngypsy jazz, theatrical pop-rock\ngypsy jazz, theatrical pop-rock, tango\ngypsy jazz, theatrical rock\ngypsy jazz, theatrical swing\ngypsy jazz, theatrical, vintage\ngypsy jazz, western swing\ngypsy jazz, western swing, novelty\ngypsy jazz, world music, musical theater\ngypsy jazz-pop\ngypsy pop\ngypsy pop-rock\ngypsy punk\ngypsy punk flamenco rock\ngypsy punk folk rock\ngypsy punk folk-punk\ngypsy punk folk-rock\ngypsy punk klezmer\ngypsy punk latin rock\ngypsy punk rock\ngypsy punk rockabilly\ngypsy punk stadium rock\ngypsy punk theatrical rock\ngypsy punk turbo-folk\ngypsy punk, Balkan brass\ngypsy punk, Balkan brass, doom metal\ngypsy punk, Balkan brass, metal\ngypsy punk, Balkan folk\ngypsy punk, Balkan folk rock\ngypsy punk, Balkan folk, electronic\ngypsy punk, Balkan folk, flamenco\ngypsy punk, Balkan folk, fusion\ngypsy punk, Balkan folk, high-energy\ngypsy punk, Balkan folk, rock\ngypsy punk, Balkan folk, theatrical rock\ngypsy punk, Balkan folk-rock\ngypsy punk, Balkan folk-rock, French chanson\ngypsy punk, Balkan rock\ngypsy punk, Balkan swing\ngypsy punk, Christian rock\ngypsy punk, French chanson\ngypsy punk, French chanson, surf rock\ngypsy punk, alternative rock, Balkan folk\ngypsy punk, balkan brass\ngypsy punk, balkan folk\ngypsy punk, balkan folk, punk rock\ngypsy punk, balkan folk, surf rock\ngypsy punk, chiptune rock\ngypsy punk, digital hardcore\ngypsy punk, klezmer, rock\ngypsy punk, polka rock\ngypsy punk, punk rock\ngypsy punk, rap-rock\ngypsy punk, speed metal\ngypsy punk, theatrical cabaret\ngypsy punk, theatrical folk\ngypsy punk, theatrical rock\ngypsy punk, theatrical swing\ngypsy rock\ngypsy rock surf rock\ngypsy soul\ngypsy swing\ngypsy tango\ngypsy-funk\ngypsy-jazz\ngypsy-jazz hip-hop alternative rock\ngypsy-jazz hip-hop rock\ngypsy-jazz rock\ngypsy-pop\ngypsy-punk\ngypsy-punk flamenco\ngypsy-punk manouche\ngypsy-punk rock\ngypsy-punk, Balkan-ska, noir-jazz\ngypsy-ska\ngǔfēng\ngǔfēng cinematic\ngǔfēng orchestral\ngǔfēng pop\ngǔfēng rock\ngǔfēng, ambient, cinematic\ngǔfēng, ambient, lo-fi\ngǔfēng, cinematic pop, electronic\ngǔfēng, cinematic pop, epic ballad\ngǔfēng, cinematic pop, modern rock\ngǔfēng, cinematic pop, orchestral\ngǔfēng, cinematic pop, orchestral rock\ngǔfēng, cinematic pop, pop-rock\ngǔfēng, cinematic pop, rock\ngǔfēng, cinematic pop, synth rock\ngǔfēng, cinematic rock, Chinese drama\ngǔfēng, cinematic, Chinese period drama\ngǔfēng, cinematic, Chinese rock\ngǔfēng, cinematic, ambient\ngǔfēng, cinematic, electronic\ngǔfēng, cinematic, epic\ngǔfēng, cinematic, ethereal\ngǔfēng, cinematic, melancholic\ngǔfēng, cinematic, orchestral\ngǔfēng, cinematic, pop\ngǔfēng, cinematic, pop-rock\ngǔfēng, cinematic, rock\ngǔfēng, pop-rock, cinematic\nhair metal\nhand drum\nhand percussion\nhandpan\nhands-up\nhands-up trance\nhands-up trance chiptune\nhands-up trance hardstyle\nhands-up trance metalcore\nhands-up trance, J-core\nhands-up trance, J-core, hardstyle\nhands-up trance, hardstyle, chiptune\nhappy hardcore\nhappy hardcore big beat\nhappy hardcore bluegrass\nhappy hardcore chiptune\nhappy hardcore chiptune J-core\nhappy hardcore chiptune J-pop\nhappy hardcore chiptune breakbeat\nhappy hardcore chiptune breakcore\nhappy hardcore chiptune complextro\nhappy hardcore chiptune eurodance\nhappy hardcore chiptune meme\nhappy hardcore chiptune metalcore\nhappy hardcore chiptune polka\nhappy hardcore chiptune rock\nhappy hardcore chiptune synth-pop\nhappy hardcore chiptune trance\nhappy hardcore chiptune trancecore\nhappy hardcore complextro\nhappy hardcore denpa\nhappy hardcore drum and bass\nhappy hardcore drum and bass chiptune\nhappy hardcore drum and bass hardstyle\nhappy hardcore dubstep breakcore\nhappy hardcore dubstep glitchcore\nhappy hardcore dubstep hardstyle\nhappy hardcore electronic rock\nhappy hardcore electronicore\nhappy hardcore eurodance\nhappy hardcore folk\nhappy hardcore frenchcore\nhappy hardcore funkot dance-pop\nhappy hardcore gabber\nhappy hardcore gabber chiptune\nhappy hardcore german rap\nhappy hardcore hardstyle\nhappy hardcore hip-hop\nhappy hardcore hyperpop\nhappy hardcore industrial metal\nhappy hardcore j-core\nhappy hardcore j-pop\nhappy hardcore j-rock\nhappy hardcore metalcore\nhappy hardcore nightcore\nhappy hardcore nu-metal\nhappy hardcore polka\nhappy hardcore polka metal\nhappy hardcore pop-punk\nhappy hardcore pop-rock\nhappy hardcore power metal\nhappy hardcore punk rock\nhappy hardcore rapcore\nhappy hardcore rock\nhappy hardcore sea shanty\nhappy hardcore stadium rock\nhappy hardcore techno\nhappy hardcore trance\nhappy hardcore trance J-core\nhappy hardcore trance J-rock\nhappy hardcore trance breakbeat\nhappy hardcore trance chiptune\nhappy hardcore trance metalcore\nhappy hardcore trance-pop\nhappy hardcore trancecore\nhappy hardcore, Balkan folk\nhappy hardcore, Bhojpuri folk\nhappy hardcore, Bhojpuri folk, funkot\nhappy hardcore, Bollywood, electronic\nhappy hardcore, C-pop, children's music\nhappy hardcore, C-pop, electronic\nhappy hardcore, C-pop, traditional Chinese\nhappy hardcore, C-pop, video game music\nhappy hardcore, Chinese fusion\nhappy hardcore, Chinese fusion, hyperpop\nhappy hardcore, Dutch party, hardstyle\nhappy hardcore, EDM, C-pop\nhappy hardcore, Eurobeat\nhappy hardcore, Eurodance\nhappy hardcore, Eurodance, synth-pop\nhappy hardcore, German Schlager\nhappy hardcore, German Schlager-pop\nhappy hardcore, German punk rock\nhappy hardcore, German rap, hardstyle\nhappy hardcore, Indian folk\nhappy hardcore, Italian rap\nhappy hardcore, J-core\nhappy hardcore, J-core, C-pop\nhappy hardcore, J-core, Chinese-style\nhappy hardcore, J-core, UK hardcore\nhappy hardcore, J-core, artcore\nhappy hardcore, J-core, chiptune\nhappy hardcore, J-core, denpa\nhappy hardcore, J-core, drum and bass\nhappy hardcore, J-core, electronic\nhappy hardcore, J-core, gabber\nhappy hardcore, J-core, hardstyle\nhappy hardcore, J-core, metalcore\nhappy hardcore, J-core, nightcore\nhappy hardcore, J-core, trance\nhappy hardcore, J-core, trancecore\nhappy hardcore, J-core, video game music\nhappy hardcore, J-pop\nhappy hardcore, J-pop, C-pop\nhappy hardcore, J-pop, Thai pop\nhappy hardcore, J-pop, anime\nhappy hardcore, J-pop, chiptune\nhappy hardcore, J-pop, denpa\nhappy hardcore, J-pop, electronic dance\nhappy hardcore, J-pop, nightcore\nhappy hardcore, J-rock\nhappy hardcore, Japanese artcore\nhappy hardcore, K-pop\nhappy hardcore, K-pop, chiptune\nhappy hardcore, Latin party\nhappy hardcore, Russian folk\nhappy hardcore, Russian folk, gabber\nhappy hardcore, Schlagerpop\nhappy hardcore, Sundanese pop\nhappy hardcore, Turkish pop, chiptune\nhappy hardcore, UK hardcore\nhappy hardcore, UK hardcore, chiptune\nhappy hardcore, UK hardcore, hardstyle\nhappy hardcore, anime soundtrack, J-rock\nhappy hardcore, breakcore, cabaret\nhappy hardcore, breakcore, chiptune\nhappy hardcore, chiptune\nhappy hardcore, chiptune pop\nhappy hardcore, chiptune, Arabic children's\nhappy hardcore, chiptune, C-pop\nhappy hardcore, chiptune, Eurodance\nhappy hardcore, chiptune, J-core\nhappy hardcore, chiptune, J-pop\nhappy hardcore, chiptune, K-pop\nhappy hardcore, chiptune, V-pop\nhappy hardcore, chiptune, breakbeat\nhappy hardcore, chiptune, drum and bass\nhappy hardcore, chiptune, electronic\nhappy hardcore, chiptune, gabber\nhappy hardcore, chiptune, hardstyle\nhappy hardcore, chiptune, hyperpop\nhappy hardcore, chiptune, nightcore\nhappy hardcore, chiptune, speedcore\nhappy hardcore, chiptune, trance\nhappy hardcore, chiptune, trancecore\nhappy hardcore, chiptune, video game music\nhappy hardcore, choral, trance\nhappy hardcore, cinematic\nhappy hardcore, cinematic, C-pop\nhappy hardcore, cinematic, chiptune\nhappy hardcore, cinematic, classical\nhappy hardcore, cyberpunk synth-pop\nhappy hardcore, denpa\nhappy hardcore, denpa, Vocaloid\nhappy hardcore, denpa, chiptune\nhappy hardcore, denpa, gabber\nhappy hardcore, denpa, kawaii future bass\nhappy hardcore, denpa-kei\nhappy hardcore, drum and bass, Eurodance\nhappy hardcore, drum and bass, chiptune\nhappy hardcore, dubstep, Chinese pop\nhappy hardcore, electronic, Chinese fusion\nhappy hardcore, electronic, Vietnamese children's music\nhappy hardcore, eurobeat\nhappy hardcore, eurobeat, video game music\nhappy hardcore, eurodance\nhappy hardcore, eurodance, chiptune\nhappy hardcore, eurodance, folk dance\nhappy hardcore, eurodance, novelty Christmas\nhappy hardcore, funkot, J-pop\nhappy hardcore, gabber, J-pop\nhappy hardcore, gabber, Middle Eastern\nhappy hardcore, gabber, Vocaloid\nhappy hardcore, gabber, children's music\nhappy hardcore, gabber, chiptune\nhappy hardcore, gabber, cinematic\nhappy hardcore, gabber, electronic\nhappy hardcore, gabber, folk\nhappy hardcore, gabber, hardstyle, Eurodance\nhappy hardcore, hands-up trance\nhappy hardcore, hardstyle\nhappy hardcore, hardstyle, chiptune\nhappy hardcore, hardstyle, cinematic\nhappy hardcore, hardstyle, complextro\nhappy hardcore, hardstyle, show tune\nhappy hardcore, hardstyle, trance\nhappy hardcore, hardstyle, trap\nhappy hardcore, hyperpop\nhappy hardcore, hyperpop, chiptune\nhappy hardcore, meme music\nhappy hardcore, metalcore, ambient\nhappy hardcore, metalcore, chiptune\nhappy hardcore, nightcore\nhappy hardcore, nightcore, C-pop\nhappy hardcore, nightcore, J-core\nhappy hardcore, nightcore, J-pop\nhappy hardcore, nightcore, Thai pop\nhappy hardcore, nightcore, chiptune\nhappy hardcore, nightcore, electronic\nhappy hardcore, polka\nhappy hardcore, polka, novelty\nhappy hardcore, pop-punk\nhappy hardcore, protest rap\nhappy hardcore, schlager\nhappy hardcore, schlager, Dutch party\nhappy hardcore, speedcore, chiptune\nhappy hardcore, trance\nhappy hardcore, trance, C-pop\nhappy hardcore, trance, Chinese cinematic\nhappy hardcore, trance, EDM\nhappy hardcore, trance, Indian devotional\nhappy hardcore, trance, J-core\nhappy hardcore, trance, Japanese electronic\nhappy hardcore, trance, Latin cumbia\nhappy hardcore, trance, chiptune\nhappy hardcore, trance, cinematic\nhappy hardcore, trance, hardstyle\nhappy hardcore, trance, video game music\nhappy hardcore, trancecore\nhappy hardcore, trancecore, Spanish rumba\nhappy hardcore, trancecore, chiptune\nhappy hardcore, trancecore, video game music\nhappy hardcore, trap, ambient\nhappy hardcore, trot\nhappy hardcore, 喊麦\nhard bass\nhard bass, tech house\nhard breakbeat\nhard chiptune\nhard club\nhard dance\nhard dance C-pop\nhard dance bass house\nhard dance chiptune K-pop\nhard dance dembow\nhard dance electro\nhard dance gabber\nhard dance hip-hop\nhard dance hyperpop\nhard dance hǎnmài\nhard dance melbourne bounce\nhard dance moombahton dancehall\nhard dance moombahton trap\nhard dance phonk\nhard dance phonk bass house\nhard dance psytrance\nhard dance reggaeton\nhard dance slap house\nhard dance techno\nhard dance tropical house\nhard dance, Balkan folk\nhard dance, Balkan folk, folk rave\nhard dance, C-pop\nhard dance, Chinese hip-hop\nhard dance, Dutch House, Chinese New Year\nhard dance, EDM, South Asian club\nhard dance, Eastern European folk\nhard dance, J-core, chiptune\nhard dance, J-core, electronic\nhard dance, J-core, happy hardcore\nhard dance, J-core, hardcore techno\nhard dance, J-core, nightcore\nhard dance, K-pop\nhard dance, Latin electronic\nhard dance, Latin urban\nhard dance, Melbourne bounce\nhard dance, Melbourne bounce, Dutch House\nhard dance, Melbourne bounce, EDM\nhard dance, Melbourne bounce, hardstyle\nhard dance, Middle Eastern fusion\nhard dance, Polish folk, gabber\nhard dance, Russian folk\nhard dance, UK hardcore\nhard dance, dancehall, moombahton\nhard dance, dark electro-pop\nhard dance, dubstep, EDM\nhard dance, electronic rap, Bollywood\nhard dance, happy hardcore, J-core\nhard dance, happy hardcore, K-pop\nhard dance, happy hardcore, dubstep\nhard dance, hip hop, electronic\nhard dance, hyperpop\nhard dance, hyperpop, hardcore techno\nhard dance, hyperpop, trancecore\nhard dance, melbourne bounce\nhard dance, melbourne bounce, trance\nhard dance, melodic trance, dubstep\nhard dance, psytrance\nhard dance, psytrance, K-pop\nhard dance, psytrance, Middle Eastern\nhard dance, psytrance, future bass\nhard dance, psytrance, rave\nhard dance, reggaeton\nhard dance, spiritual techno\nhard dance, techno, Balkan folk\nhard dance, techno, Mandopop\nhard dance, techno, Southeast Asian fusion\nhard dance, trance, Eurodance\nhard dance, trance, electronic\nhard dancehall\nhard dembow\nhard dembow hyperpop\nhard electro\nhard electro glitch hop\nhard electronic\nhard electronic dance\nhard electronic dance music\nhard electronic hip-hop\nhard hip-hop\nhard hip-hop, hardstyle\nhard house\nhard house baile funk\nhard house breakbeat\nhard house gabber\nhard house metal\nhard house tech house\nhard house techno\nhard house, South Asian folk\nhard house, happy hardcore, Balkan brass\nhard house, rave, hyperpop\nhard phonk\nhard psytrance\nhard reggaeton\nhard rock\nhard rock AOR fusion\nhard rock C-pop folk-rock\nhard rock Carnatic fusion\nhard rock Indian film music\nhard rock Indian folk\nhard rock J-rock\nhard rock Javanese pop-rock\nhard rock Latin folk\nhard rock MPB\nhard rock Mandopop\nhard rock R&B\nhard rock Tamil pop\nhard rock alternative metal\nhard rock alternative rock\nhard rock ambient\nhard rock anime\nhard rock ballad\nhard rock big band\nhard rock big band Latin fusion\nhard rock bluegrass fusion\nhard rock blues\nhard rock blues rock\nhard rock blues-rock\nhard rock cantopop\nhard rock chiptune\nhard rock chiptune electronic\nhard rock country-rock\nhard rock cumbia\nhard rock cumbia norteña\nhard rock cumbia rock\nhard rock cyberpunk\nhard rock dance-pop\nhard rock dangdut\nhard rock dangdut koplo\nhard rock disco\nhard rock dubstep\nhard rock electronic\nhard rock electronicore\nhard rock enka\nhard rock flamenco\nhard rock flamenco fusion\nhard rock folk fusion\nhard rock folk metal\nhard rock folk rock\nhard rock folk-rock\nhard rock forró\nhard rock funk\nhard rock funk rock\nhard rock funk rock psychedelic rock\nhard rock funk synth-rock\nhard rock funk-reggae\nhard rock funk-rock\nhard rock fusion\nhard rock glam metal\nhard rock glam metal AOR\nhard rock glam metal j-rock\nhard rock glam rock\nhard rock gospel\nhard rock gospel soul\nhard rock grunge\nhard rock happy hardcore\nhard rock hip-hop\nhard rock hip-hop R&B\nhard rock hip-hop funk\nhard rock hip-hop fusion\nhard rock hip-hop pop\nhard rock hip-hop soul\nhard rock hip-house\nhard rock indie rock\nhard rock jazz fusion\nhard rock klezmer fusion\nhard rock korean traditional\nhard rock kuthu\nhard rock metal\nhard rock metalcore\nhard rock norteño\nhard rock nu-metal\nhard rock pop-punk\nhard rock pop-rock\nhard rock power ballad\nhard rock power metal\nhard rock progressive metal\nhard rock progressive rock\nhard rock proto-punk\nhard rock psychedelic lounge\nhard rock psychedelic rock\nhard rock pub rock\nhard rock punk\nhard rock punk rock\nhard rock punk ska\nhard rock rap-rock\nhard rock reggae\nhard rock reggae dancehall\nhard rock reggae fusion\nhard rock reggae ska\nhard rock reggae-rock\nhard rock reggaeton\nhard rock salsa\nhard rock samba-rock\nhard rock schlager\nhard rock ska-punk\nhard rock soul\nhard rock southern rock\nhard rock speed metal\nhard rock stoner metal\nhard rock synth-pop\nhard rock synth-rock\nhard rock tango\nhard rock tango fusion\nhard rock thrash metal\nhard rock trap\nhard rock trot\nhard rock turbo-folk\nhard rock world fusion\nhard rock worship\nhard rock, Anatolian rock\nhard rock, Arabic folk\nhard rock, Arabic fusion\nhard rock, Balkan folk\nhard rock, Balkan rock\nhard rock, Bengali folk\nhard rock, Bengali folk, cinematic\nhard rock, Bengali pop\nhard rock, Bengali pop-rock\nhard rock, Bhojpuri folk\nhard rock, C-pop\nhard rock, C-pop fusion\nhard rock, C-pop, ancient style\nhard rock, C-pop, cinematic\nhard rock, C-pop, fusion\nhard rock, C-pop, rap rock\nhard rock, C-pop, traditional Chinese\nhard rock, C-pop, wuxia\nhard rock, C-rock\nhard rock, Canto-rock\nhard rock, Cantonese opera\nhard rock, Caribbean fusion\nhard rock, Carnatic fusion\nhard rock, Central Asian folk\nhard rock, Chinese New Year, rock\nhard rock, Chinese folk\nhard rock, Chinese folk fusion\nhard rock, Chinese folk opera\nhard rock, Chinese folk, Peking Opera\nhard rock, Chinese folk, cinematic\nhard rock, Chinese folk, cinematic rock\nhard rock, Chinese folk, fusion\nhard rock, Chinese folk, theatrical rock\nhard rock, Chinese fusion\nhard rock, Chinese fusion, cinematic rock\nhard rock, Chinese fusion, metal\nhard rock, Chinese opera\nhard rock, Chinese opera, cinematic\nhard rock, Chinese opera, cinematic rock\nhard rock, Christian metal\nhard rock, Dangdut Koplo, Javanese folk\nhard rock, East Asian folk\nhard rock, East Asian fusion\nhard rock, East Asian fusion, cinematic\nhard rock, Eastern European folk\nhard rock, Enka, Kayōkyoku\nhard rock, Gaúcho folk\nhard rock, German rap, crossover\nhard rock, Greek folk\nhard rock, Indian cinematic\nhard rock, Indian classical\nhard rock, Indian film music\nhard rock, Indian folk\nhard rock, Indian folk, cinematic\nhard rock, Indian folk, cinematic rock\nhard rock, Indian fusion, Telugu rock\nhard rock, Indian pop\nhard rock, Indonesian fusion\nhard rock, Indonesian pop\nhard rock, Indonesian traditional\nhard rock, Italian folk\nhard rock, J-rock\nhard rock, J-rock, Cantopop\nhard rock, J-rock, electronic\nhard rock, J-rock, rap-rock\nhard rock, Japanese fusion\nhard rock, Javanese folk\nhard rock, Javanese folk, blues rock\nhard rock, Javanese folk, melodic rock\nhard rock, Javanese fusion\nhard rock, Javanese pop\nhard rock, Javanese pop-rock\nhard rock, Javanese power metal\nhard rock, Javanese traditional\nhard rock, Javanese, dangdut\nhard rock, Javanese, fusion\nhard rock, Latin folk\nhard rock, Latin jazz\nhard rock, Latin pop\nhard rock, Latin rock\nhard rock, Latin rock, ambient\nhard rock, Latin, video game\nhard rock, Luk Thung\nhard rock, Malay fusion\nhard rock, Malay traditional\nhard rock, Mandopop\nhard rock, Mediterranean folk\nhard rock, Middle Eastern folk\nhard rock, Middle Eastern folk, hip-hop\nhard rock, Middle Eastern fusion\nhard rock, Middle Eastern fusion, electronic\nhard rock, Middle Eastern pop\nhard rock, Mizrahi pop\nhard rock, Mizrahi pop-rock\nhard rock, Mor Lam\nhard rock, Nepali folk\nhard rock, Neue Deutsche Härte\nhard rock, Neue Deutsche Welle\nhard rock, Norteño\nhard rock, North African folk\nhard rock, North African fusion\nhard rock, Pop Melayu\nhard rock, Rai, North African pop\nhard rock, Schlager\nhard rock, South Asian folk\nhard rock, South Indian dance\nhard rock, South Indian folk\nhard rock, South Indian hip-hop\nhard rock, Southeast Asian fusion\nhard rock, Spanish folk\nhard rock, Sundanese fusion\nhard rock, Tamil folk\nhard rock, Tamil pop\nhard rock, Tamil pop-rock\nhard rock, Turkish rock\nhard rock, Turkish rock, cinematic rock\nhard rock, Vietnamese pop\nhard rock, acoustic ballad\nhard rock, acoustic ballad, Chinese rock\nhard rock, alternative metal\nhard rock, alternative metal, funk rock\nhard rock, ambient\nhard rock, ambient, South Asian classical\nhard rock, anime opening, video game\nhard rock, arena rock, J-rock\nhard rock, balkan brass\nhard rock, ballad\nhard rock, big band jazz\nhard rock, big band swing\nhard rock, big band, brass rock\nhard rock, big band, fusion\nhard rock, big room, hardstyle\nhard rock, blues rock, C-pop\nhard rock, blues rock, Persian rock\nhard rock, boogie-funk, 80s synth\nhard rock, cabaret rock, rap rock\nhard rock, chiptune\nhard rock, chiptune, Indian classical\nhard rock, cinematic rock\nhard rock, cinematic, C-pop\nhard rock, cinematic, Chinese opera\nhard rock, cinematic, Chinese rock\nhard rock, cinematic, Chinese traditional\nhard rock, classic rock\nhard rock, conscious hip-hop\nhard rock, conscious hip-hop, dancehall\nhard rock, conscious hip-hop, reggae-rock\nhard rock, cumbia rock, folk rock\nhard rock, cumbia, Spanish rock\nhard rock, cumbia, ambient\nhard rock, dance-pop\nhard rock, dangdut\nhard rock, dangdut koplo\nhard rock, dangdut rock\nhard rock, dangdut, traditional Indonesian\nhard rock, dangdut, world fusion\nhard rock, disco\nhard rock, electronic dance music\nhard rock, electronic dance music, Middle Eastern\nhard rock, electronic dance, fusion\nhard rock, electronic dance, rap rock\nhard rock, electronic, Mandarin rock\nhard rock, electronic, Middle Eastern\nhard rock, eurodance\nhard rock, flamenco rock, cinematic\nhard rock, flamenco, Indian classical\nhard rock, flamenco, Mandarin rock\nhard rock, folk fusion\nhard rock, folk fusion, C-pop\nhard rock, folk rock\nhard rock, funk rock, German rock\nhard rock, fusion, Javanese\nhard rock, glam metal\nhard rock, glam metal, ambient\nhard rock, glam metal, heavy metal\nhard rock, glam metal, synth-rock\nhard rock, gospel pop-rock\nhard rock, gospel rock, Sundanese rock\nhard rock, groove metal, progressive rock\nhard rock, hardstyle\nhard rock, hardstyle, C-pop\nhard rock, hardstyle, gabber\nhard rock, heavy metal\nhard rock, heavy metal, Khmer rock\nhard rock, hip-hop, southern rock\nhard rock, luk thung\nhard rock, metal, Turkish rock\nhard rock, metal, cinematic\nhard rock, metal, psychedelic rock\nhard rock, metal, theatrical rock\nhard rock, metalcore, C-pop\nhard rock, metalcore, J-rock\nhard rock, metalcore, chiptune\nhard rock, metalcore, cinematic\nhard rock, metalcore, progressive rock\nhard rock, new jack swing\nhard rock, noise rock, cinematic rock\nhard rock, nu-metal, Chinese spoken word\nhard rock, nu-metal, cinematic metal\nhard rock, nu-metal, cinematic rock\nhard rock, nu-metal, electronicore\nhard rock, nu-metal, piano ballad\nhard rock, nu-metal, rap-rock\nhard rock, oud, fusion\nhard rock, polka, Schlager\nhard rock, pop melayu, dangdut\nhard rock, pop-rock\nhard rock, pop-rock, 80s\nhard rock, pop-rock, C-pop\nhard rock, pop-rock, Dangdut Koplo\nhard rock, pop-rock, Indian classical\nhard rock, pop-rock, Indian classical fusion\nhard rock, pop-rock, Indonesian pop\nhard rock, pop-rock, J-rock\nhard rock, pop-rock, Javanese folk\nhard rock, pop-rock, Mandarin rock\nhard rock, pop-rock, Spanish rock\nhard rock, pop-rock, bilingual rock\nhard rock, pop-rock, dangdut\nhard rock, pop-rock, dangdut koplo\nhard rock, post-punk\nhard rock, post-rock\nhard rock, power ballad, Chinese fusion\nhard rock, power ballad, Chinese rock\nhard rock, power ballad, world music\nhard rock, power metal\nhard rock, power metal, J-rock\nhard rock, power metal, folk fusion\nhard rock, power metal, folk rock\nhard rock, power metal, shred\nhard rock, power metal, symphonic rock\nhard rock, power metal, thrash metal\nhard rock, progressive rock, metal\nhard rock, progressive rock, psychedelic rock\nhard rock, psychedelic indie rock\nhard rock, psychedelic jazz-funk, blues rock\nhard rock, psychedelic rock\nhard rock, psychedelic rock, C-pop\nhard rock, psychedelic rock, J-rock\nhard rock, psychedelic rock, ambient\nhard rock, psychedelic rock, cinematic\nhard rock, psychedelic rock, funk rock\nhard rock, psychedelic rock, noise rock\nhard rock, punk rock, Taiwanese Hokkien\nhard rock, punk rock, comedy rock\nhard rock, punk rock, gypsy-punk\nhard rock, rap, world music\nhard rock, rap-rock, Chinese fusion\nhard rock, rap-rock, Vietnamese rock\nhard rock, rap-rock, cinematic\nhard rock, rap-rock, comedic\nhard rock, rock opera, cinematic\nhard rock, schlager\nhard rock, schlager, eurodance\nhard rock, schlager, garmonie\nhard rock, shoegaze, noise rock\nhard rock, tarantella\nhard rock, theatrical rock, gospel rock\nhard rock, thrash metal\nhard rock, thrash metal, C-pop\nhard rock, thrash metal, blues rock\nhard rock, thrash metal, psychedelic\nhard rock, thrash metal, psychedelic rock\nhard rock, traditional Indonesian\nhard rock, traditional Malay\nhard rock, traditional Southeast Asian\nhard rock, trap, duet\nhard rock, trot\nhard rock, turbo-folk\nhard rock, uplifting trance\nhard rock, video game music\nhard rock, world fusion\nhard rock, world fusion, metal\nhard rock, world music\nhard rock, world music, C-pop\nhard rock, world music, power ballad\nhard techno\nhard techno acid house\nhard techno alpine folk\nhard techno breakbeat\nhard techno chiptune\nhard techno classical fusion\nhard techno dembow\nhard techno electroclash\nhard techno gabber\nhard techno hip-hop\nhard techno house\nhard techno industrial\nhard techno phonk\nhard techno psytrance\nhard techno trap\nhard techno, Anatolian folk\nhard techno, Bollywood\nhard techno, Brazilian funk, experimental electronic\nhard techno, EBM\nhard techno, EBM, cinematic\nhard techno, EBM, electro-punk\nhard techno, EBM, experimental club\nhard techno, EBM, industrial\nhard techno, EBM, multilingual rap\nhard techno, EBM, tribal house\nhard techno, Middle Eastern fusion\nhard techno, Russian rap, emo rock\nhard techno, Slavic folk\nhard techno, cinematic trance\nhard techno, cumbia, reggaeton\nhard techno, ethnic electronica\nhard techno, hardstyle\nhard techno, hardstyle, gabber\nhard techno, hyperpop\nhard techno, meme rap\nhard techno, progressive house, hardstyle\nhard techno, psytrance\nhard techno, psytrance, Middle Eastern electronic\nhard techno, psytrance, ancient style\nhard techno, psytrance, cinematic\nhard techno, psytrance, industrial techno\nhard techno, rap, dream pop\nhard techno, trance, Balkan folk\nhard techno, trance, hardstyle\nhard trance\nhard trance Arabic fusion\nhard trance Bhojpuri folk\nhard trance acid techno\nhard trance alternative rock\nhard trance bhangra\nhard trance big room house\nhard trance breakbeat\nhard trance chiptune\nhard trance classical\nhard trance drum and bass\nhard trance flamenco\nhard trance gabber\nhard trance hands-up\nhard trance happy hardcore\nhard trance hardcore techno\nhard trance industrial metal\nhard trance industrial techno\nhard trance metalcore\nhard trance power metal\nhard trance progressive house\nhard trance progressive house big room\nhard trance progressive trance\nhard trance psytrance\nhard trance psytrance chiptune\nhard trance rave\nhard trance synth-pop\nhard trance synthwave\nhard trance techno\nhard trance world music\nhard trance, Bollywood\nhard trance, Chinese fusion\nhard trance, EBM\nhard trance, EBM, electronic\nhard trance, Eurodance\nhard trance, J-core, happy hardcore\nhard trance, Mandopop, big room house\nhard trance, Mandopop, happy hardcore\nhard trance, Mandopop, hardstyle\nhard trance, Middle Eastern folk\nhard trance, Middle Eastern fusion\nhard trance, Middle Eastern pop\nhard trance, Middle Eastern, Turkish rap\nhard trance, South Asian folk\nhard trance, South Indian film music\nhard trance, Turkish pop\nhard trance, acid techno, chiptune\nhard trance, ambient, progressive house\nhard trance, artcore, chiptune\nhard trance, big room house\nhard trance, chiptune, industrial metal\nhard trance, cinematic, techno\nhard trance, electro-industrial, chiptune\nhard trance, gabber, bitpop\nhard trance, gabber, chiptune\nhard trance, hands-up, chiptune\nhard trance, happy hardcore, Japanese video game music\nhard trance, happy hardcore, chiptune\nhard trance, happy hardcore, video game\nhard trance, happy hardcore, video game music\nhard trance, hard house\nhard trance, hardcore techno, chiptune\nhard trance, hardstyle\nhard trance, hardstyle, C-pop\nhard trance, hardstyle, Indian electronic\nhard trance, hardstyle, R&B\nhard trance, hardstyle, ambient\nhard trance, hardstyle, ballad\nhard trance, hardstyle, cinematic\nhard trance, hip-hop, pop-rock\nhard trance, pop ballad, hardstyle\nhard trance, pop-rock, happy hardcore\nhard trance, progressive house\nhard trance, progressive house, hardstyle\nhard trance, psytrance\nhard trance, psytrance, Bollywood\nhard trance, psytrance, ambient\nhard trance, psytrance, chiptune\nhard trance, psytrance, cinematic\nhard trance, psytrance, ethnic\nhard trance, psytrance, hardstyle\nhard trance, psytrance, metalcore\nhard trance, psytrance, progressive house\nhard trance, reggaeton, hardstyle\nhard trance, synth-pop\nhard trance, synth-pop, hip-hop\nhard trance, synthwave\nhard trance, techno, Indian electronic\nhard trap\nhard trap bass house\nhard trap chiptune\nhard trap dancehall\nhard trap drill\nhard trap hardstyle\nhard trap house\nhard trap hyperpop hardstyle\nhard trap phonk\nhard trap, C-pop, electronic\nhard trap, Indian devotional\nhard trap, Indian hip-hop\nhard trap, Italian hip-hop, cinematic\nhard trap, Middle Eastern\nhard trap, Middle Eastern fusion\nhard trap, South Asian fusion\nhard trap, cinematic, J-rock\nhard trap, conscious hip-hop\nhard trap, cyberpunk\nhard trap, dark hip-hop\nhard trap, dark pop\nhard trap, drill, regional hip hop\nhard trap, dubstep, lo-fi hip hop\nhard trap, hardcore techno, chiptune\nhard trap, hardstyle\nhard trap, hardstyle, Dutch hip-hop\nhard trap, horrorcore\nhard trap, industrial, hyperpop\nhard-hitting boom-bap\nhard-hitting electronic\nhard-hitting hip-hop\nhardbass\nhardbass big room\nhardbass chiptune\nhardbass cyberpunk\nhardbass folk\nhardbass folk dance\nhardbass folk fusion\nhardbass gabber\nhardbass industrial\nhardbass phonk\nhardbass punk rock\nhardbass ska-pop\nhardbass trap\nhardbass, Russian estrada\nhardbass, Russian folk\nhardbass, chiptune, Russian\nhardbass, cinematic, Russian folk\nhardbass, dark electronic\nhardbass, electronic, hip-hop\nhardbass, eurodance, russian\nhardbass, folk-pop, Russian\nhardbass, happy hardcore, Russian electronic\nhardbass, hyperpop\nhardbass, hyperpop, hardstyle\nhardbass, military phonk\nhardcore\nhardcore boom bap\nhardcore breakbeat\nhardcore chiptune\nhardcore chiptune breakcore\nhardcore drum & bass\nhardcore drum and bass breakcore\nhardcore drum and bass chiptune\nhardcore drum and bass industrial\nhardcore drum and bass metalcore\nhardcore electronic\nhardcore electronic chiptune\nhardcore electronic metalcore\nhardcore electronic rapcore\nhardcore electronic, Chinese fusion\nhardcore electronic, J-core, hyperpop\nhardcore electronic, guzheng, speedcore\nhardcore gabber\nhardcore gabber chiptune\nhardcore hip hop\nhardcore hip-hop\nhardcore hip-hop alternative rock\nhardcore hip-hop breakcore\nhardcore hip-hop gabber\nhardcore hip-hop industrial\nhardcore hip-hop industrial trap metal\nhardcore hip-hop nu-metal\nhardcore hip-hop rap metal\nhardcore hip-hop rock\nhardcore hip-hop trap metal\nhardcore punk\nhardcore punk rap-rock\nhardcore punk rapcore\nhardcore punk, funk-reggae\nhardcore punk, hip-hop, screamo\nhardcore punk, indie rock, pop-punk\nhardcore punk, post-rock\nhardcore punk, post-rock, sludge\nhardcore punk, theatrical rock, protest music\nhardcore rap\nhardcore rap trap metal\nhardcore rap, trance\nhardcore rave\nhardcore reggaeton\nhardcore techno\nhardcore techno chiptune\nhardcore techno cybergrind\nhardcore techno drum and bass\nhardcore techno gabber\nhardcore techno hyperpop\nhardcore techno industrial metal\nhardcore techno jazz fusion\nhardcore techno metalcore\nhardcore techno rap\nhardcore techno rapcore\nhardcore techno speedcore chiptune\nhardcore techno trancecore\nhardcore techno, Chinese fusion\nhardcore techno, J-core\nhardcore techno, J-core, artcore\nhardcore techno, J-core, chiptune\nhardcore techno, J-core, hyperpop\nhardcore techno, J-core, video game music\nhardcore techno, J-pop, cinematic\nhardcore techno, ambient, trance\nhardcore techno, chiptune, C-pop\nhardcore techno, chiptune, J-core\nhardcore techno, chiptune, Japanese video game music\nhardcore techno, chiptune, breakcore\nhardcore techno, chiptune, speedcore\nhardcore techno, denpa-kei\nhardcore techno, happy hardcore\nhardcore techno, hyperpop\nhardcore techno, hyperpop, classical\nhardcore techno, speedcore, J-core\nhardcore techno, speedcore, chiptune\nhardcore techno, trance\nhardcore techno, trance, Japanese\nhardcore techno, trance, chiptune\nhardcore techno, trance, video game music\nhardcore techno, trance, video game soundtrack\nhardcore techno, trancecore\nhardcore trance\nhardcore trance artcore\nhardcore trance chiptune\nhardcore trap\nhardcore trap chiptune\nhardcore, J-core, K-pop\nhardcore, J-core, chiptune\nhardcore, J-core, gabber\nhardcore, J-core, happy hardcore\nhardcore, J-core, trance\nhardcore, chiptune\nhardcore, chiptune, speedcore\nhardcore, gabber, J-core\nhardcore, gabber, speedcore\nhardcore, speedcore, J-core\nhardcore, speedcore, chiptune\nhardcore, speedcore, classical\nhardcore, speedcore, complextro\nhardcore, speedcore, glitchcore\nhardstyle\nhardstyle Afro-Latin\nhardstyle Anatolian folk\nhardstyle Arabic fusion\nhardstyle Balkan folk\nhardstyle Balkan house\nhardstyle Bhojpuri\nhardstyle Bhojpuri fusion\nhardstyle Bollywood\nhardstyle C-pop\nhardstyle C-pop EDM\nhardstyle C-pop Eurodance\nhardstyle C-pop J-core\nhardstyle C-pop J-pop\nhardstyle C-pop cinematic\nhardstyle C-pop hyperpop\nhardstyle C-pop trance\nhardstyle C-pop trap\nhardstyle EDM\nhardstyle EDM Arabic pop\nhardstyle EDM Bhojpuri folk\nhardstyle EDM Indian classical\nhardstyle EDM Indian devotional\nhardstyle EDM Indian folk\nhardstyle EDM Indian fusion\nhardstyle EDM Indian hip-hop\nhardstyle EDM Indian pop\nhardstyle EDM J-pop\nhardstyle EDM J-rock\nhardstyle EDM K-pop\nhardstyle EDM Punjabi pop\nhardstyle EDM chiptune\nhardstyle EDM country\nhardstyle EDM country rap\nhardstyle EDM electronic rock\nhardstyle EDM folk metal\nhardstyle EDM hip-hop\nhardstyle EDM kuthu\nhardstyle EDM metalcore\nhardstyle EDM nu-metal\nhardstyle EDM pop-rap\nhardstyle EDM power metal\nhardstyle EDM rap-metal\nhardstyle EDM, Carnatic fusion\nhardstyle EDM, Central Asian pop\nhardstyle EDM, French rap\nhardstyle EDM, Hindi rap\nhardstyle EDM, Hindu devotional\nhardstyle EDM, Indian devotional\nhardstyle EDM, Indian filmi\nhardstyle EDM, Indian folk\nhardstyle EDM, Indian fusion\nhardstyle EDM, Indian pop\nhardstyle EDM, Indonesian rap\nhardstyle EDM, J-rock, rap\nhardstyle EDM, Kuthu, Bollywood\nhardstyle EDM, Middle Eastern fusion\nhardstyle EDM, Middle Eastern trance\nhardstyle EDM, Middle Eastern trap\nhardstyle EDM, South Asian folk\nhardstyle EDM, South Asian fusion\nhardstyle EDM, South Asian hip-hop\nhardstyle EDM, South Asian pop\nhardstyle EDM, South Indian film music\nhardstyle EDM, South Indian folk\nhardstyle EDM, Telugu rap, Indian film music\nhardstyle EDM, Turkish trap\nhardstyle EDM, dubstep trap\nhardstyle EDM, epic trance, classical fusion\nhardstyle EDM, epic trance-pop\nhardstyle EDM, pop-rock, cinematic\nhardstyle EDM, rap, melodic pop\nhardstyle EDM, rap-rock\nhardstyle EDM, theatrical rock\nhardstyle Indian devotional\nhardstyle Indian folk\nhardstyle Indian folk fusion\nhardstyle Indian fusion\nhardstyle Indian hip-hop\nhardstyle J-core\nhardstyle J-pop\nhardstyle Japanese rap\nhardstyle K-pop\nhardstyle Latin house\nhardstyle Mandopop\nhardstyle Mizrahi pop\nhardstyle Punjabi folk\nhardstyle Punjabi folk fusion\nhardstyle Punjabi fusion\nhardstyle R&B\nhardstyle Tamil dance\nhardstyle Tamil folk\nhardstyle V-pop\nhardstyle acid\nhardstyle acid techno\nhardstyle acid trance\nhardstyle afro-house\nhardstyle afro-house gospel\nhardstyle alternative rock\nhardstyle ambient\nhardstyle arabic\nhardstyle arabic pop\nhardstyle arabic rap\nhardstyle arabic trap\nhardstyle artcore\nhardstyle artcore chiptune\nhardstyle baile funk\nhardstyle balkan folk\nhardstyle balkan manele\nhardstyle balkan pop\nhardstyle balkan trap\nhardstyle bass house\nhardstyle bhajan\nhardstyle bhangra\nhardstyle bhangra bollywood\nhardstyle bhangra chiptune\nhardstyle bhojpuri\nhardstyle bhojpuri fusion\nhardstyle big beat\nhardstyle big beat industrial\nhardstyle big room\nhardstyle big room C-pop\nhardstyle big room Indian filmi\nhardstyle big room Indian pop\nhardstyle big room K-pop\nhardstyle big room Middle Eastern\nhardstyle big room chiptune\nhardstyle big room dancehall\nhardstyle big room hip-hop\nhardstyle big room house\nhardstyle big room house K-pop\nhardstyle big room kuthu\nhardstyle big room metalcore\nhardstyle big room techno\nhardstyle big room trance\nhardstyle big room trap\nhardstyle big room worship\nhardstyle bollywood\nhardstyle bounce\nhardstyle breakbeat\nhardstyle breakcore\nhardstyle breakcore chiptune\nhardstyle breakcore glitch\nhardstyle breakcore glitch hop\nhardstyle brostep\nhardstyle children's\nhardstyle children's music\nhardstyle chillwave\nhardstyle chiptune\nhardstyle chiptune C-pop\nhardstyle chiptune Indian\nhardstyle chiptune Indian film music\nhardstyle chiptune acid\nhardstyle chiptune breakbeat\nhardstyle chiptune breakcore\nhardstyle chiptune cinematic\nhardstyle chiptune circus\nhardstyle chiptune complextro\nhardstyle chiptune electro\nhardstyle chiptune emo rap\nhardstyle chiptune gabber\nhardstyle chiptune happy hardcore\nhardstyle chiptune hip-hop\nhardstyle chiptune hyperpop\nhardstyle chiptune industrial\nhardstyle chiptune latin\nhardstyle chiptune metalcore\nhardstyle chiptune multilingual rap\nhardstyle chiptune rap\nhardstyle chiptune trance\nhardstyle chiptune trap\nhardstyle cinematic\nhardstyle cinematic trance\nhardstyle classical\nhardstyle classical fusion\nhardstyle complextro\nhardstyle complextro chiptune\nhardstyle country\nhardstyle cumbia\nhardstyle cumbia latin\nhardstyle cumbia reggaeton\nhardstyle cumbia villera\nhardstyle cyberpunk\nhardstyle cyberpunk synthwave\nhardstyle dance-pop\nhardstyle dancehall\nhardstyle dancehall trap\nhardstyle dark electro\nhardstyle dark electro phonk\nhardstyle dark pop\nhardstyle dark synthpop\nhardstyle dark synthwave\nhardstyle dark techno\nhardstyle dark trap\nhardstyle darkwave\nhardstyle dembow\nhardstyle drum and bass\nhardstyle drum and bass complextro\nhardstyle drum and bass rap\nhardstyle dubstep\nhardstyle dubstep C-pop\nhardstyle dubstep J-rock\nhardstyle dubstep Japanese rap\nhardstyle dubstep K-pop\nhardstyle dubstep artcore\nhardstyle dubstep breakcore\nhardstyle dubstep chiptune\nhardstyle dubstep cinematic\nhardstyle dubstep complextro\nhardstyle dubstep dancehall\nhardstyle dubstep experimental\nhardstyle dubstep glitch hop\nhardstyle dubstep glitchcore\nhardstyle dubstep hardcore\nhardstyle dubstep hyperpop\nhardstyle dubstep industrial\nhardstyle dubstep j-rock\nhardstyle dubstep k-pop\nhardstyle dubstep latin rap\nhardstyle dubstep metalcore\nhardstyle dubstep pop-rap\nhardstyle dubstep rap\nhardstyle dubstep reggae\nhardstyle dubstep speedcore\nhardstyle dubstep trance\nhardstyle dubstep trap\nhardstyle dubstep trap metal\nhardstyle electro\nhardstyle electro house\nhardstyle electro rap\nhardstyle electro-industrial\nhardstyle electro-pop\nhardstyle electronic rock\nhardstyle electronicore\nhardstyle emo rap\nhardstyle emo-rap\nhardstyle epic dubstep\nhardstyle epic trance\nhardstyle ethnic\nhardstyle ethnic electronica\nhardstyle ethnic pop\nhardstyle ethnic trap\nhardstyle euphoric\nhardstyle euphoric trance\nhardstyle eurodance\nhardstyle experimental bass\nhardstyle experimental club\nhardstyle experimental trap\nhardstyle festival trance\nhardstyle festival trap\nhardstyle flamenco\nhardstyle folk\nhardstyle folk fusion\nhardstyle football anthem\nhardstyle forró\nhardstyle funk\nhardstyle funk carioca\nhardstyle funkot\nhardstyle fusion\nhardstyle future bass\nhardstyle future bass C-pop\nhardstyle future bass chiptune\nhardstyle future bass happy hardcore\nhardstyle gabber\nhardstyle gabber breakcore\nhardstyle gabber chiptune\nhardstyle gabber experimental\nhardstyle gabber happy hardcore\nhardstyle gabber trance\nhardstyle gabber trap\nhardstyle gabber, hardcore techno\nhardstyle german rap\nhardstyle glitch\nhardstyle glitch cinematic\nhardstyle glitch hop\nhardstyle glitch hop bass house\nhardstyle glitch-hop\nhardstyle glitchcore\nhardstyle glitchcore dubstep\nhardstyle gospel\nhardstyle grime\nhardstyle hands-up trance\nhardstyle happy hardcore\nhardstyle happy hardcore dancehall\nhardstyle happy hardcore schlager\nhardstyle hard trance\nhardstyle hardcore\nhardstyle hardcore metalcore\nhardstyle hardcore techno\nhardstyle haryanvi\nhardstyle haryanvi fusion\nhardstyle hip hop\nhardstyle hip-hop\nhardstyle hip-hop J-core\nhardstyle hip-hop chiptune\nhardstyle hip-hop hyperpop\nhardstyle hip-hop j-rap\nhardstyle hip-hop techno\nhardstyle horror\nhardstyle horrorcore\nhardstyle house\nhardstyle hybrid trap\nhardstyle hyperpop\nhardstyle hyperpop C-pop\nhardstyle hyperpop J-core\nhardstyle hyperpop J-pop\nhardstyle hyperpop K-pop\nhardstyle hyperpop Latin rap\nhardstyle hyperpop breakcore\nhardstyle hyperpop chiptune\nhardstyle hyperpop dark electronic\nhardstyle hyperpop darkwave\nhardstyle hyperpop dembow\nhardstyle hyperpop electronicore\nhardstyle hyperpop industrial\nhardstyle hyperpop nightcore\nhardstyle hyperpop rap\nhardstyle hyperpop trance\nhardstyle hyperpop trap\nhardstyle hǎnmài\nhardstyle indian folk\nhardstyle industrial\nhardstyle industrial big room\nhardstyle industrial breakcore\nhardstyle industrial brostep\nhardstyle industrial gabber\nhardstyle industrial hardcore techno\nhardstyle industrial metal\nhardstyle industrial metalcore\nhardstyle industrial rap-metal\nhardstyle industrial techno\nhardstyle industrial trance\nhardstyle italo dance\nhardstyle j-core\nhardstyle j-core artcore\nhardstyle j-core chiptune\nhardstyle j-core hyperpop\nhardstyle j-core trance\nhardstyle j-pop\nhardstyle jumpstyle\nhardstyle k-pop\nhardstyle k-pop chiptune\nhardstyle k-pop dubstep\nhardstyle k-pop fusion\nhardstyle k-pop industrial\nhardstyle k-pop j-core\nhardstyle k-pop rap\nhardstyle k-pop trance\nhardstyle k-pop video game\nhardstyle klezmer\nhardstyle kuthu\nhardstyle latin\nhardstyle latin club\nhardstyle latin electronic\nhardstyle latin house\nhardstyle latin pop\nhardstyle latin rap\nhardstyle latin tech\nhardstyle latin trap\nhardstyle latin urban\nhardstyle lo-fi\nhardstyle lo-fi chiptune\nhardstyle lo-fi hip-hop\nhardstyle mandopop\nhardstyle mandopop trance\nhardstyle mariachi\nhardstyle melbourne bounce\nhardstyle melodic dubstep\nhardstyle meme rap\nhardstyle meme rap glitchcore\nhardstyle meme-core\nhardstyle merengue\nhardstyle metalcore\nhardstyle metalcore Latin electronic\nhardstyle moombahton\nhardstyle moombahton Latin pop\nhardstyle moombahton dancehall\nhardstyle moombahton latin\nhardstyle moombahton reggaeton\nhardstyle moombahton trap\nhardstyle neurofunk\nhardstyle nightcore\nhardstyle nightcore funk\nhardstyle nightcore hyperpop\nhardstyle nu-metal\nhardstyle orchestral\nhardstyle oud\nhardstyle phonk\nhardstyle phonk bass house\nhardstyle phonk chiptune\nhardstyle phonk cinematic\nhardstyle phonk experimental\nhardstyle phonk meme rap\nhardstyle pirate\nhardstyle pirate rap\nhardstyle piseiro\nhardstyle polka\nhardstyle pop\nhardstyle pop-folk\nhardstyle pop-punk\nhardstyle pop-rap\nhardstyle pop-rock\nhardstyle power metal\nhardstyle progressive house\nhardstyle progressive house big room\nhardstyle psytrance\nhardstyle psytrance Arabic\nhardstyle psytrance Bollywood\nhardstyle psytrance C-pop\nhardstyle psytrance Indian film music\nhardstyle psytrance J-core\nhardstyle psytrance J-pop\nhardstyle psytrance K-pop\nhardstyle psytrance Latin rap\nhardstyle psytrance artcore\nhardstyle psytrance big room\nhardstyle psytrance breakbeat\nhardstyle psytrance breakcore\nhardstyle psytrance chiptune\nhardstyle psytrance cinematic\nhardstyle psytrance complextro\nhardstyle psytrance cyberpunk\nhardstyle psytrance dancehall\nhardstyle psytrance drum and bass\nhardstyle psytrance dubstep\nhardstyle psytrance experimental bass\nhardstyle psytrance experimental club\nhardstyle psytrance gabber\nhardstyle psytrance glitch\nhardstyle psytrance happy hardcore\nhardstyle psytrance hardcore\nhardstyle psytrance hyperpop\nhardstyle psytrance industrial\nhardstyle psytrance k-pop\nhardstyle psytrance latin\nhardstyle psytrance power metal\nhardstyle psytrance riddim\nhardstyle psytrance trap\nhardstyle punjabi fusion\nhardstyle rajasthani fusion\nhardstyle rap\nhardstyle rap industrial\nhardstyle rap-rock\nhardstyle rapcore\nhardstyle rapcore chiptune\nhardstyle rave\nhardstyle rave industrial\nhardstyle rave-rap\nhardstyle rawstyle\nhardstyle reggaeton\nhardstyle reggaeton hyperpop\nhardstyle reggaeton moombahton\nhardstyle riddim\nhardstyle riddim dubstep\nhardstyle rock\nhardstyle schlager\nhardstyle sci-fi\nhardstyle sea shanty\nhardstyle speedcore\nhardstyle speedcore big room\nhardstyle speedcore chiptune\nhardstyle speedcore glitch-hop\nhardstyle speedcore glitchcore\nhardstyle synth-pop\nhardstyle synth-punk\nhardstyle synth-rock\nhardstyle synthwave\nhardstyle synthwave chiptune\nhardstyle tearout dubstep\nhardstyle tech house\nhardstyle tech-trance\nhardstyle techno\nhardstyle techno big room house\nhardstyle techno industrial\nhardstyle techno, French rap\nhardstyle techno, German rap\nhardstyle techno, Middle Eastern folk\nhardstyle techno, Schlager-pop\nhardstyle techno, Turkish pop\nhardstyle techno, emo rap, metalcore\nhardstyle techno, filmi\nhardstyle techno, schlager\nhardstyle trance\nhardstyle trance C-pop\nhardstyle trance Christian rap\nhardstyle trance J-core\nhardstyle trance K-pop\nhardstyle trance Middle Eastern\nhardstyle trance acid techno\nhardstyle trance artcore\nhardstyle trance big room\nhardstyle trance bollywood\nhardstyle trance breakbeat\nhardstyle trance chiptune\nhardstyle trance cinematic\nhardstyle trance cinematic rock\nhardstyle trance complextro\nhardstyle trance dark electro\nhardstyle trance drum and bass\nhardstyle trance dubstep\nhardstyle trance future bass\nhardstyle trance glitchcore\nhardstyle trance happy hardcore\nhardstyle trance hardcore\nhardstyle trance hardcore techno\nhardstyle trance hyperpop\nhardstyle trance industrial\nhardstyle trance industrial metal\nhardstyle trance j-core\nhardstyle trance k-pop\nhardstyle trance metalcore\nhardstyle trance psytrance\nhardstyle trance rap\nhardstyle trance rock\nhardstyle trance synth-pop\nhardstyle trance synthwave\nhardstyle trance video game\nhardstyle trance-pop\nhardstyle trancecore\nhardstyle trancecore chiptune\nhardstyle trap\nhardstyle trap C-pop\nhardstyle trap Indian\nhardstyle trap Indian cinematic\nhardstyle trap Indian fusion\nhardstyle trap J-core\nhardstyle trap J-pop\nhardstyle trap K-hip-hop\nhardstyle trap K-pop\nhardstyle trap Latin pop\nhardstyle trap Latin urban\nhardstyle trap Mandopop\nhardstyle trap Middle Eastern\nhardstyle trap Middle Eastern electronic\nhardstyle trap R&B\nhardstyle trap Russian hardbass\nhardstyle trap balkan\nhardstyle trap balkan brass\nhardstyle trap balkan pop\nhardstyle trap bass\nhardstyle trap bass house\nhardstyle trap big room\nhardstyle trap bollywood\nhardstyle trap breakbeat\nhardstyle trap breakcore\nhardstyle trap chiptune\nhardstyle trap cinematic\nhardstyle trap country\nhardstyle trap dancehall\nhardstyle trap dark electronic\nhardstyle trap dark electronic pop\nhardstyle trap dark pop\nhardstyle trap electro house\nhardstyle trap electronic rock\nhardstyle trap ethnic electronica\nhardstyle trap experimental\nhardstyle trap experimental bass\nhardstyle trap experimental club\nhardstyle trap experimental hip-hop\nhardstyle trap experimental pop\nhardstyle trap fusion\nhardstyle trap gaming\nhardstyle trap glitch hop\nhardstyle trap glitch-hop\nhardstyle trap glitchcore\nhardstyle trap global bass\nhardstyle trap global pop\nhardstyle trap hardcore\nhardstyle trap hip-hop\nhardstyle trap hybrid trailer\nhardstyle trap hyperpop\nhardstyle trap industrial\nhardstyle trap kuthu\nhardstyle trap metal\nhardstyle trap metal Indian rap\nhardstyle trap metal dubstep\nhardstyle trap metal experimental\nhardstyle trap metal experimental bass\nhardstyle trap metal glitch hop\nhardstyle trap metal hardcore techno\nhardstyle trap metal hyperpop\nhardstyle trap metalcore\nhardstyle trap oud\nhardstyle trap phonk\nhardstyle trap political hip-hop\nhardstyle trap pop\nhardstyle trap pop-rock\nhardstyle trap psychedelic pop\nhardstyle trap rap\nhardstyle trap reggaeton\nhardstyle trap world music\nhardstyle trap, Bollywood\nhardstyle trap, hyperpop\nhardstyle trap, pop-rock, chiptune\nhardstyle tribal\nhardstyle tribal bass\nhardstyle tribal techno\nhardstyle tropical\nhardstyle turbo-folk\nhardstyle uk drill\nhardstyle uk garage\nhardstyle uk grime\nhardstyle uk hardcore\nhardstyle ukranian folk\nhardstyle ukranian rap\nhardstyle uplifting trance\nhardstyle v-pop\nhardstyle vaporwave\nhardstyle vina house\nhardstyle vinahouse\nhardstyle world music\nhardstyle, Arabic fusion\nhardstyle, Azerbaijani folk\nhardstyle, Azerbaijani folk-pop\nhardstyle, Azerbaijani pop\nhardstyle, Balkan brass\nhardstyle, Balkan folk\nhardstyle, Balkan folk, EDM\nhardstyle, Balkan folk, electronic\nhardstyle, Balkan folk, techno\nhardstyle, Balkan fusion\nhardstyle, Balkan fusion, electronic\nhardstyle, Balkan hardcore\nhardstyle, Balkan pop\nhardstyle, Balkan pop, EDM\nhardstyle, Balkan pop, chalga\nhardstyle, Balkan pop, trap\nhardstyle, Balkan trap\nhardstyle, Balkan turbo-folk\nhardstyle, Balkan, hardbass\nhardstyle, Balkan, trap\nhardstyle, Bengali folk\nhardstyle, Bengali folk, EDM\nhardstyle, Bhojpuri EDM\nhardstyle, Bhojpuri folk\nhardstyle, Bhojpuri folk, EDM\nhardstyle, Bhojpuri folk, Melbourne bounce\nhardstyle, Bhojpuri folk, electronic dance\nhardstyle, Bhojpuri folk, hyper-pop\nhardstyle, Bhojpuri folk, hyperpop\nhardstyle, Bhojpuri fusion\nhardstyle, Bhojpuri remix\nhardstyle, Bhojpuri, EDM\nhardstyle, Bhojpuri, electronic\nhardstyle, Bollywood\nhardstyle, Bollywood EDM\nhardstyle, Bollywood dance\nhardstyle, Bollywood dance, EDM\nhardstyle, Bollywood dance, hyperpop\nhardstyle, Bollywood fusion\nhardstyle, Bollywood, EDM\nhardstyle, Bollywood, electronic\nhardstyle, Bollywood, electronic dance\nhardstyle, Bollywood, happy hardcore\nhardstyle, Bollywood, hyperpop\nhardstyle, Bollywood, psytrance\nhardstyle, Brazilian baile funk\nhardstyle, Brazilian bass\nhardstyle, Brazilian funk\nhardstyle, Brazilian phonk\nhardstyle, C-EDM\nhardstyle, C-pop\nhardstyle, C-pop fusion\nhardstyle, C-pop, Tamil\nhardstyle, C-pop, ambient\nhardstyle, C-pop, anime\nhardstyle, C-pop, cinematic\nhardstyle, C-pop, electronic\nhardstyle, C-pop, emotional ballad\nhardstyle, C-pop, folk\nhardstyle, C-pop, folk fusion\nhardstyle, C-pop, happy hardcore\nhardstyle, C-pop, hip-hop\nhardstyle, C-pop, hyperpop\nhardstyle, C-pop, rap\nhardstyle, C-pop, traditional Chinese\nhardstyle, C-pop, traditional East Asian\nhardstyle, Cantopop, Eurodance\nhardstyle, Cantopop, hip-hop\nhardstyle, Cantopop, trance\nhardstyle, Celtic folk\nhardstyle, Central Asian folk\nhardstyle, Central Asian folk, electronic\nhardstyle, Chinese EDM\nhardstyle, Chinese MC\nhardstyle, Chinese MC, EDM\nhardstyle, Chinese MC, dance\nhardstyle, Chinese MC, trance\nhardstyle, Chinese ambient, electronic\nhardstyle, Chinese classical\nhardstyle, Chinese electronic\nhardstyle, Chinese flute, electronic\nhardstyle, Chinese folk\nhardstyle, Chinese folk, EDM\nhardstyle, Chinese folk, cinematic\nhardstyle, Chinese fusion\nhardstyle, Chinese fusion, psytrance\nhardstyle, Chinese hard dance\nhardstyle, Chinese hip hop\nhardstyle, Chinese hǎnmài\nhardstyle, Chinese rap\nhardstyle, Chinese rap, techno\nhardstyle, Chinese traditional, trap\nhardstyle, Chinese wuxia\nhardstyle, Chinese, Mandopop\nhardstyle, Chinese, cinematic\nhardstyle, Chinese, electronic\nhardstyle, Chinese, epic\nhardstyle, Chinese, 喊麦\nhardstyle, Christmas\nhardstyle, Christmas, electronic\nhardstyle, Christmas, theatrical\nhardstyle, Czech folk\nhardstyle, Dutch cabaret, trap\nhardstyle, EBM\nhardstyle, EBM, dark techno\nhardstyle, EBM, hyperpop\nhardstyle, EBM, trance\nhardstyle, EDM\nhardstyle, EDM, Bollywood\nhardstyle, EDM, C-pop\nhardstyle, EDM, Chinese New Year\nhardstyle, EDM, Chinese trap\nhardstyle, EDM, J-pop\nhardstyle, EDM, K-pop\nhardstyle, EDM, Kuthu\nhardstyle, EDM, Latin\nhardstyle, EDM, Latin urban\nhardstyle, EDM, Mandarin rap\nhardstyle, EDM, Russian dance-pop\nhardstyle, EDM, Schlager\nhardstyle, EDM, Uzbek pop\nhardstyle, EDM, cinematic\nhardstyle, EDM, hip-hop\nhardstyle, EDM, hyperpop\nhardstyle, EDM, piano ballad\nhardstyle, EDM, trap\nhardstyle, East Asian fusion\nhardstyle, Eastern European folk\nhardstyle, Eurodance\nhardstyle, Eurodance, EDM\nhardstyle, Eurodance, happy hardcore, synth-pop\nhardstyle, Eurodance, trance\nhardstyle, French rap\nhardstyle, German folk\nhardstyle, German rap\nhardstyle, German rap, Schlager\nhardstyle, German rap, electronic\nhardstyle, Greek folk\nhardstyle, Greek pop\nhardstyle, Haryanvi folk\nhardstyle, Haryanvi folk, EDM\nhardstyle, Haryanvi folk, electronic dance\nhardstyle, Indian bhajan\nhardstyle, Indian classical\nhardstyle, Indian classical, electronic\nhardstyle, Indian devotional\nhardstyle, Indian devotional, EDM\nhardstyle, Indian devotional, electronic\nhardstyle, Indian devotional, electronic dance\nhardstyle, Indian devotional, electronic fusion\nhardstyle, Indian electronic\nhardstyle, Indian film music\nhardstyle, Indian filmi\nhardstyle, Indian folk\nhardstyle, Indian folk fusion\nhardstyle, Indian folk, Bhangra\nhardstyle, Indian folk, Bollywood\nhardstyle, Indian folk, EDM\nhardstyle, Indian folk, Melbourne bounce\nhardstyle, Indian folk, electronic\nhardstyle, Indian folk, electronic dance\nhardstyle, Indian folk, gabber\nhardstyle, Indian folk, hyper-pop\nhardstyle, Indian folk, hyperpop\nhardstyle, Indian folk, psytrance\nhardstyle, Indian folk, trap\nhardstyle, Indian fusion\nhardstyle, Indian fusion, electronic\nhardstyle, Indian hip-hop\nhardstyle, Indian patriotic\nhardstyle, Indian pop\nhardstyle, Indian pop-rap\nhardstyle, Indian trap\nhardstyle, Indonesian funk\nhardstyle, Indonesian fusion\nhardstyle, Indonesian hip-hop\nhardstyle, Islamic devotional\nhardstyle, J-core\nhardstyle, J-core, C-pop\nhardstyle, J-core, EDM\nhardstyle, J-core, Vocaloid\nhardstyle, J-core, anime\nhardstyle, J-core, anthemic pop-rock\nhardstyle, J-core, artcore\nhardstyle, J-core, chiptune\nhardstyle, J-core, cinematic\nhardstyle, J-core, denpa\nhardstyle, J-core, denpa-kei\nhardstyle, J-core, electronic\nhardstyle, J-core, electronic pop\nhardstyle, J-core, happy hardcore\nhardstyle, J-core, hardcore\nhardstyle, J-core, hyperpop\nhardstyle, J-core, nightcore\nhardstyle, J-core, pop\nhardstyle, J-core, rap\nhardstyle, J-core, trance\nhardstyle, J-core, trance-pop\nhardstyle, J-core, trap\nhardstyle, J-core, trap metal\nhardstyle, J-pop\nhardstyle, J-pop, C-pop\nhardstyle, J-pop, Vocaloid\nhardstyle, J-pop, anime\nhardstyle, J-pop, chiptune\nhardstyle, J-pop, cinematic\nhardstyle, J-pop, electronic\nhardstyle, J-pop, hip-hop\nhardstyle, J-pop, hyperpop\nhardstyle, J-pop, rap\nhardstyle, J-pop, trap\nhardstyle, J-rock\nhardstyle, J-rock, anime\nhardstyle, J-rock, anime theme\nhardstyle, J-rock, hip-hop\nhardstyle, J-rock, lo-fi\nhardstyle, J-rock, rap\nhardstyle, JRPG, emotional\nhardstyle, Japanese hardcore\nhardstyle, Javanese folk\nhardstyle, Javanese fusion\nhardstyle, Javanese hip-hop\nhardstyle, K-hip-hop\nhardstyle, K-hip-hop, EDM\nhardstyle, K-pop\nhardstyle, K-pop, EDM\nhardstyle, K-pop, chiptune\nhardstyle, K-pop, electronic\nhardstyle, K-pop, electronic rock\nhardstyle, K-pop, hip-hop\nhardstyle, K-pop, hyperpop\nhardstyle, K-pop, industrial\nhardstyle, K-pop, rap\nhardstyle, Kollywood\nhardstyle, Latin electronic\nhardstyle, Latin fusion\nhardstyle, Latin house, tribal house\nhardstyle, Latin pop, electronic\nhardstyle, Latin trap\nhardstyle, Latin urban\nhardstyle, Laïko\nhardstyle, Luk Thung\nhardstyle, Mandopop\nhardstyle, Mandopop, EDM\nhardstyle, Mandopop, happy hardcore\nhardstyle, Mandopop, pop-rock\nhardstyle, Mandopop, trap rap\nhardstyle, Manele\nhardstyle, Marathi folk, electronic dance\nhardstyle, Marathi folk-pop\nhardstyle, Melbourne bounce\nhardstyle, Melbourne bounce, Chinese New Year\nhardstyle, Melbourne bounce, comedy\nhardstyle, Middle Eastern\nhardstyle, Middle Eastern electronic\nhardstyle, Middle Eastern folk\nhardstyle, Middle Eastern fusion\nhardstyle, Middle Eastern fusion, electronic dance\nhardstyle, Middle Eastern fusion, folk rave\nhardstyle, Middle Eastern fusion, hip-hop\nhardstyle, Middle Eastern pop\nhardstyle, Middle Eastern trap\nhardstyle, Middle Eastern, Arabic\nhardstyle, Middle Eastern, Balkan\nhardstyle, Middle Eastern, South Asian\nhardstyle, Middle Eastern, Turkish\nhardstyle, Middle Eastern, cinematic\nhardstyle, Middle Eastern, electronic\nhardstyle, Middle Eastern, hard bass\nhardstyle, Middle Eastern, hyperpop\nhardstyle, Middle Eastern, psytrance\nhardstyle, Middle Eastern, trap\nhardstyle, Mizrahi pop\nhardstyle, Mizrahi pop, electronic\nhardstyle, Mizrahi, Middle Eastern\nhardstyle, Mizrahi, electronic\nhardstyle, Mongolian folk\nhardstyle, Mor Lam\nhardstyle, Mor Lam, EDM\nhardstyle, Mor Lam, electronic\nhardstyle, Nepali rap\nhardstyle, Persian ambient\nhardstyle, Persian, Middle Eastern\nhardstyle, Persian, electronic\nhardstyle, Polish disco polo\nhardstyle, Polish folk\nhardstyle, Punjabi folk\nhardstyle, Punjabi folk, EDM\nhardstyle, Punjabi folk, cinematic\nhardstyle, Punjabi folk, electronic\nhardstyle, Punjabi folk, electronic dance\nhardstyle, Punjabi fusion\nhardstyle, R&B\nhardstyle, R&B, electronic\nhardstyle, Romanian pop\nhardstyle, Russian folk\nhardstyle, Russian folk, electronic\nhardstyle, Russian folk, happy hardcore\nhardstyle, Russian folk, trance\nhardstyle, Russian hardbass\nhardstyle, Russian hip hop\nhardstyle, Russian pop\nhardstyle, Russian pop-rap\nhardstyle, Russian rap\nhardstyle, Russian rap, chiptune\nhardstyle, Russian rap, cinematic electronic\nhardstyle, Russian rave\nhardstyle, Russian, hyperpop\nhardstyle, Schlager\nhardstyle, Schlager, Volksmusik\nhardstyle, Slavic folk\nhardstyle, South African house\nhardstyle, South Asian electronic\nhardstyle, South Asian folk\nhardstyle, South Asian folk, EDM\nhardstyle, South Asian folk, electronic\nhardstyle, South Asian folk, electronic dance\nhardstyle, South Asian fusion\nhardstyle, South Asian fusion, electronic\nhardstyle, South Asian fusion, electronic dance\nhardstyle, South Asian pop\nhardstyle, South Indian film music\nhardstyle, South Indian film music, future bass\nhardstyle, South Indian folk\nhardstyle, South Indian hip-hop\nhardstyle, South Indian rap\nhardstyle, Southeast Asian folk, electronic\nhardstyle, Tamil folk\nhardstyle, Tamil folk, electronic\nhardstyle, Tamil rap\nhardstyle, Telugu folk, electronic\nhardstyle, Tibetan folk\nhardstyle, Turkish folk\nhardstyle, Turkish folk, electronic\nhardstyle, Turkish fusion\nhardstyle, Turkish pop\nhardstyle, Turkish pop, electronic fusion\nhardstyle, Turkish rap\nhardstyle, Turkish, electronic\nhardstyle, Turkish, psytrance\nhardstyle, UK bass house\nhardstyle, UK drill\nhardstyle, UK drill, electronic\nhardstyle, UK garage\nhardstyle, UK garage, bass house\nhardstyle, UK garage, breakbeat\nhardstyle, UK garage, electronic\nhardstyle, UK garage, glitch\nhardstyle, UK hardcore\nhardstyle, UK hardcore, ambient\nhardstyle, UK hardcore, chiptune\nhardstyle, UK hardcore, cinematic\nhardstyle, UK hardcore, dancehall\nhardstyle, UK hardcore, electronic\nhardstyle, UK rap\nhardstyle, UK rap, big room\nhardstyle, Ukrainian folk\nhardstyle, V-Pop\nhardstyle, V-Pop, Eurodance\nhardstyle, V-Pop, trance-pop\nhardstyle, V-pop\nhardstyle, V-pop, hip-hop\nhardstyle, Vietnamese folk\nhardstyle, Vietnamese rap, pop\nhardstyle, Vocaloid\nhardstyle, Vocaloid, Chinese electronic\nhardstyle, Vocaloid, electronic\nhardstyle, Vocaloid, emotional EDM\nhardstyle, acoustic ballad\nhardstyle, ambient ballad\nhardstyle, ambient pop\nhardstyle, ambient techno\nhardstyle, ambient, C-pop\nhardstyle, ambient, EDM\nhardstyle, ambient, Indian folk\nhardstyle, ambient, Indian fusion\nhardstyle, ambient, Japanese hardcore\nhardstyle, ambient, breakcore\nhardstyle, ambient, chiptune\nhardstyle, ambient, cinematic\nhardstyle, ambient, dark electronic\nhardstyle, ambient, electronic\nhardstyle, ambient, emotional vocal\nhardstyle, ambient, ethereal\nhardstyle, ambient, ethnic fusion\nhardstyle, ambient, gabber\nhardstyle, ambient, glitch\nhardstyle, ambient, spiritual\nhardstyle, ambient, trance\nhardstyle, ambient, trap\nhardstyle, ancient spiritual, electronic\nhardstyle, ancient style\nhardstyle, anime pop\nhardstyle, anime, electronic\nhardstyle, arabic fusion, cinematic EDM\nhardstyle, artcore, hardcore\nhardstyle, baile funk\nhardstyle, baile funk, electronic\nhardstyle, balkan pop, chalga\nhardstyle, balkan, trap\nhardstyle, ballad\nhardstyle, ballad, Indonesian pop\nhardstyle, baroque\nhardstyle, bass house, pop-punk\nhardstyle, bass music, experimental electronic\nhardstyle, belly dance, electronic\nhardstyle, bhajan\nhardstyle, bhajan, electronic\nhardstyle, bhangra\nhardstyle, bhangra, electronic\nhardstyle, big room\nhardstyle, big room house\nhardstyle, big room house, Arabic devotional\nhardstyle, big room house, Arabic electronic\nhardstyle, big room house, C-pop\nhardstyle, big room house, Chinese cinematic\nhardstyle, big room house, Indian bhajan\nhardstyle, big room house, Indian devotional\nhardstyle, big room house, Latin electronic\nhardstyle, big room house, Latin trap\nhardstyle, big room house, Latin urban\nhardstyle, big room house, Middle Eastern fusion\nhardstyle, big room house, Norwegian rap\nhardstyle, big room house, R&B\nhardstyle, big room house, Russian dance-pop\nhardstyle, big room house, Russian rap\nhardstyle, big room house, Thai electronic\nhardstyle, big room house, ambient\nhardstyle, big room house, ambient hip-hop\nhardstyle, big room house, chiptune\nhardstyle, big room house, cinematic\nhardstyle, big room house, cinematic hip hop\nhardstyle, big room house, cinematic pop\nhardstyle, big room house, devotional EDM\nhardstyle, big room house, electro house\nhardstyle, big room house, emotional piano\nhardstyle, big room house, hip-hop\nhardstyle, big room house, kuthu\nhardstyle, big room house, lo-fi hip hop\nhardstyle, big room house, melodic hardstyle\nhardstyle, big room house, piano ballad\nhardstyle, big room house, pop-R&B\nhardstyle, big room house, rap\nhardstyle, big room house, rap-rock\nhardstyle, big room house, trance\nhardstyle, big room house, trap\nhardstyle, big room trance\nhardstyle, big room, C-pop\nhardstyle, big room, EDM\nhardstyle, big room, Middle Eastern fusion\nhardstyle, big room, cinematic\nhardstyle, big room, kuthu\nhardstyle, big room, pop\nhardstyle, big room, trance\nhardstyle, bluegrass, cyber-folk\nhardstyle, bluegrass, happy hardcore\nhardstyle, breakbeat, chiptune\nhardstyle, breakbeat, cinematic\nhardstyle, breakcore\nhardstyle, breakcore, J-pop\nhardstyle, breakcore, ambient\nhardstyle, breakcore, chiptune\nhardstyle, breakcore, cinematic\nhardstyle, breakcore, dubstep\nhardstyle, breakcore, novelty electronic\nhardstyle, breakcore, phonk\nhardstyle, breakcore, psytrance\nhardstyle, breakcore, trance\nhardstyle, brostep, chiptune\nhardstyle, brostep, dubstep\nhardstyle, chip-tune\nhardstyle, chiptune, C-pop\nhardstyle, chiptune, EDM\nhardstyle, chiptune, J-core\nhardstyle, chiptune, J-rock\nhardstyle, chiptune, Japanese\nhardstyle, chiptune, Latin pop\nhardstyle, chiptune, Norwegian rap\nhardstyle, chiptune, UK hardcore\nhardstyle, chiptune, Vocaloid\nhardstyle, chiptune, ambient\nhardstyle, chiptune, cinematic\nhardstyle, chiptune, complextro\nhardstyle, chiptune, dubstep\nhardstyle, chiptune, electro\nhardstyle, chiptune, electronic\nhardstyle, chiptune, flamenco\nhardstyle, chiptune, gabber\nhardstyle, chiptune, happy hardcore\nhardstyle, chiptune, hard trance\nhardstyle, chiptune, hardcore techno\nhardstyle, chiptune, hip-hop\nhardstyle, chiptune, hyperpop\nhardstyle, chiptune, industrial techno\nhardstyle, chiptune, lo-fi\nhardstyle, chiptune, meme-core\nhardstyle, chiptune, metalcore\nhardstyle, chiptune, pop\nhardstyle, chiptune, speedcore\nhardstyle, chiptune, synth-pop\nhardstyle, chiptune, trance\nhardstyle, chiptune, trap\nhardstyle, choral, electronic\nhardstyle, cinematic\nhardstyle, cinematic C-pop\nhardstyle, cinematic EDM\nhardstyle, cinematic ambient\nhardstyle, cinematic ambient, trance\nhardstyle, cinematic electronic\nhardstyle, cinematic electronic, C-pop\nhardstyle, cinematic electronic, artcore\nhardstyle, cinematic electronic, dark electronic\nhardstyle, cinematic horror\nhardstyle, cinematic orchestral\nhardstyle, cinematic pop\nhardstyle, cinematic pop, Cantonese ballad\nhardstyle, cinematic rap\nhardstyle, cinematic rock, K-pop\nhardstyle, cinematic rock, metalcore\nhardstyle, cinematic sci-fi\nhardstyle, cinematic synth-pop\nhardstyle, cinematic techno\nhardstyle, cinematic trance\nhardstyle, cinematic trap\nhardstyle, cinematic, Arabic fusion\nhardstyle, cinematic, Asian fusion\nhardstyle, cinematic, Bengali electronic\nhardstyle, cinematic, C-pop\nhardstyle, cinematic, Chinese ambient\nhardstyle, cinematic, Chinese folk\nhardstyle, cinematic, Chinese fusion\nhardstyle, cinematic, Chinese rap\nhardstyle, cinematic, Chinese traditional\nhardstyle, cinematic, EDM\nhardstyle, cinematic, East Asian\nhardstyle, cinematic, East Asian fusion\nhardstyle, cinematic, Eastern fusion\nhardstyle, cinematic, French pop\nhardstyle, cinematic, German Schlager\nhardstyle, cinematic, Hebrew vocal\nhardstyle, cinematic, Hindi pop\nhardstyle, cinematic, Indian fusion\nhardstyle, cinematic, Italian pop\nhardstyle, cinematic, Javanese\nhardstyle, cinematic, Middle Eastern\nhardstyle, cinematic, Sundanese\nhardstyle, cinematic, Tamil\nhardstyle, cinematic, UK hardcore\nhardstyle, cinematic, Vocaloid\nhardstyle, cinematic, ambient\nhardstyle, cinematic, arabic fusion\nhardstyle, cinematic, artcore\nhardstyle, cinematic, ballad\nhardstyle, cinematic, breakcore\nhardstyle, cinematic, chiptune\nhardstyle, cinematic, choral\nhardstyle, cinematic, cyberpunk\nhardstyle, cinematic, dubstep\nhardstyle, cinematic, dystopian\nhardstyle, cinematic, electronic\nhardstyle, cinematic, emotional\nhardstyle, cinematic, emotional piano\nhardstyle, cinematic, ethereal\nhardstyle, cinematic, ethereal pop\nhardstyle, cinematic, ethnic fusion\nhardstyle, cinematic, folk\nhardstyle, cinematic, gabber\nhardstyle, cinematic, glitch\nhardstyle, cinematic, gothic\nhardstyle, cinematic, happy hardcore\nhardstyle, cinematic, hard trance\nhardstyle, cinematic, hardcore\nhardstyle, cinematic, hardcore techno\nhardstyle, cinematic, hip hop\nhardstyle, cinematic, horror\nhardstyle, cinematic, hybrid orchestral\nhardstyle, cinematic, lo-fi\nhardstyle, cinematic, melodic\nhardstyle, cinematic, operatic\nhardstyle, cinematic, orchestral\nhardstyle, cinematic, orchestral synth\nhardstyle, cinematic, oriental\nhardstyle, cinematic, pop\nhardstyle, cinematic, pop-ballad\nhardstyle, cinematic, psytrance\nhardstyle, cinematic, rap\nhardstyle, cinematic, sci-fi\nhardstyle, cinematic, synthwave\nhardstyle, cinematic, trance\nhardstyle, cinematic, trap\nhardstyle, cinematic, tribal\nhardstyle, cinematic, video game\nhardstyle, cinematic, world fusion\nhardstyle, cinematic, world music\nhardstyle, cloud rap, hyperpop\nhardstyle, comedy, eurodance\nhardstyle, complextro\nhardstyle, complextro, C-pop\nhardstyle, complextro, J-pop\nhardstyle, complextro, J-rock\nhardstyle, complextro, K-electronic\nhardstyle, complextro, K-pop\nhardstyle, complextro, Korean pop\nhardstyle, complextro, artcore\nhardstyle, complextro, chiptune\nhardstyle, complextro, cinematic\nhardstyle, complextro, dubstep\nhardstyle, complextro, electronic pop\nhardstyle, complextro, synth-pop\nhardstyle, corridos tumbados\nhardstyle, cumbia\nhardstyle, cyberpunk\nhardstyle, cyberpunk, C-pop\nhardstyle, cyberpunk, EDM\nhardstyle, cyberpunk, brostep\nhardstyle, cyberpunk, electronic\nhardstyle, dancehall, Middle Eastern\nhardstyle, dancehall, moombahton\nhardstyle, dark electro, midtempo bass\nhardstyle, dark electro-pop\nhardstyle, dark techno\nhardstyle, dembow, Latin electronic\nhardstyle, devotional\nhardstyle, devotional Indian, electronic\nhardstyle, devotional, electronic\nhardstyle, devotional, reggaeton\nhardstyle, downtempo, Sinhala pop\nhardstyle, dream pop\nhardstyle, dream-pop, happy hardcore\nhardstyle, drum and bass, chiptune\nhardstyle, drum and bass, cinematic\nhardstyle, dubstep\nhardstyle, dubstep, C-pop\nhardstyle, dubstep, J-pop\nhardstyle, dubstep, J-rock\nhardstyle, dubstep, Middle Eastern electronic\nhardstyle, dubstep, ambient\nhardstyle, dubstep, anime\nhardstyle, dubstep, chiptune\nhardstyle, dubstep, cinematic\nhardstyle, dubstep, ethereal\nhardstyle, dubstep, experimental\nhardstyle, dubstep, hardcore\nhardstyle, dubstep, industrial\nhardstyle, dubstep, metalcore\nhardstyle, dubstep, pop\nhardstyle, dubstep, speedcore\nhardstyle, dubstep, symphonic trance\nhardstyle, dubstep, synth-pop\nhardstyle, electro-folk\nhardstyle, electro-house, cinematic\nhardstyle, electronic\nhardstyle, electronic pop, cinematic\nhardstyle, electronic pop, folk-influenced\nhardstyle, electronic, Asian fusion\nhardstyle, electronic, Brazilian funk\nhardstyle, electronic, C-pop\nhardstyle, electronic, Central Asian folk\nhardstyle, electronic, Chinese fusion\nhardstyle, electronic, Chinese rap\nhardstyle, electronic, EDM\nhardstyle, electronic, French pop\nhardstyle, electronic, German rap\nhardstyle, electronic, Indian fusion\nhardstyle, electronic, Indian pop\nhardstyle, electronic, K-pop\nhardstyle, electronic, Latin\nhardstyle, electronic, Latin club\nhardstyle, electronic, Mandarin\nhardstyle, electronic, Mandarin rap\nhardstyle, electronic, Mandopop\nhardstyle, electronic, Marathi fusion\nhardstyle, electronic, Middle Eastern\nhardstyle, electronic, Middle Eastern folk\nhardstyle, electronic, Middle Eastern fusion\nhardstyle, electronic, Russian rap\nhardstyle, electronic, Russian vocal\nhardstyle, electronic, South Asian fusion\nhardstyle, electronic, Southeast Asian fusion\nhardstyle, electronic, Spanish vocal\nhardstyle, electronic, ambient\nhardstyle, electronic, atmospheric\nhardstyle, electronic, baroque\nhardstyle, electronic, bilingual\nhardstyle, electronic, chiptune\nhardstyle, electronic, cinematic\nhardstyle, electronic, devotional\nhardstyle, electronic, dream pop\nhardstyle, electronic, epic pop\nhardstyle, electronic, ethereal\nhardstyle, electronic, folk fusion\nhardstyle, electronic, folk-inspired\nhardstyle, electronic, glitch\nhardstyle, electronic, jazz fusion\nhardstyle, electronic, pop\nhardstyle, electronic, spy theme\nhardstyle, electronic, theatrical\nhardstyle, electronic, trap\nhardstyle, electronic, urban\nhardstyle, electronic, vocal trance\nhardstyle, electronic, world fusion\nhardstyle, emo rap, gabber\nhardstyle, emotional piano, happy hardcore\nhardstyle, ethereal pop\nhardstyle, ethereal pop, C-pop\nhardstyle, ethereal, Indian fusion\nhardstyle, ethereal, rave\nhardstyle, ethnic electronic\nhardstyle, ethnic folk, EDM\nhardstyle, ethnic folk, cinematic\nhardstyle, ethnic folk, electronic\nhardstyle, ethnic fusion\nhardstyle, ethnic trap\nhardstyle, ethnic, Middle Eastern\nhardstyle, ethnic, electronic\nhardstyle, ethno-electronic, Slavic folk\nhardstyle, ethno-house\nhardstyle, euphoric trance\nhardstyle, eurodance\nhardstyle, eurodance, EDM\nhardstyle, eurodance, ambient\nhardstyle, eurodance, cinematic\nhardstyle, eurodance, dance-pop\nhardstyle, eurodance, trance\nhardstyle, experimental pop\nhardstyle, festival trap, chiptune\nhardstyle, festival trap, electronic\nhardstyle, festival trap, pop\nhardstyle, festive, dark pop\nhardstyle, festive, meme\nhardstyle, festive, theatrical\nhardstyle, flamenco-metal, cinematic\nhardstyle, folk electronic\nhardstyle, folk electronic, gabber\nhardstyle, folk fusion\nhardstyle, folk fusion, electronic\nhardstyle, folk metal, electronic\nhardstyle, folk, Eastern European\nhardstyle, folk, cinematic\nhardstyle, folk, classical\nhardstyle, folk, electronic\nhardstyle, folk, gabber\nhardstyle, folk-dance\nhardstyle, fusion, electronic\nhardstyle, future bass\nhardstyle, future bass, R&B\nhardstyle, future bass, ambient\nhardstyle, future bass, cinematic\nhardstyle, future bass, lo-fi hip hop\nhardstyle, future bass, trap\nhardstyle, futuristic rave, electronic\nhardstyle, gabber, Tamil dance\nhardstyle, gabber, Thai rave\nhardstyle, gabber, UK hardcore\nhardstyle, gabber, anime\nhardstyle, gabber, chiptune\nhardstyle, gabber, cinematic\nhardstyle, gabber, cinematic rock\nhardstyle, gabber, cinematic trance\nhardstyle, gabber, electronic\nhardstyle, gabber, folk\nhardstyle, gabber, hardcore techno\nhardstyle, gabber, hip hop\nhardstyle, gabber, hyperpop\nhardstyle, gabber, industrial\nhardstyle, gabber, industrial techno\nhardstyle, gabber, psytrance\nhardstyle, gabber, trance\nhardstyle, glitch, cinematic\nhardstyle, glitch, electronic\nhardstyle, glitch, psytrance\nhardstyle, gothic, cinematic\nhardstyle, guzheng, electronic\nhardstyle, hands-up trance\nhardstyle, hands-up, EDM\nhardstyle, happy hardcore\nhardstyle, happy hardcore, Bhangra\nhardstyle, happy hardcore, Bhojpuri dance\nhardstyle, happy hardcore, Bhojpuri folk\nhardstyle, happy hardcore, C-pop\nhardstyle, happy hardcore, Desi DJ\nhardstyle, happy hardcore, Dutch rap\nhardstyle, happy hardcore, EDM\nhardstyle, happy hardcore, East Asian melodic\nhardstyle, happy hardcore, German comedy rap\nhardstyle, happy hardcore, German party-rap\nhardstyle, happy hardcore, German pop\nhardstyle, happy hardcore, German rap\nhardstyle, happy hardcore, Indian folk\nhardstyle, happy hardcore, J-pop\nhardstyle, happy hardcore, Melbourne bounce\nhardstyle, happy hardcore, Middle Eastern\nhardstyle, happy hardcore, Partyschlager\nhardstyle, happy hardcore, South Asian folk\nhardstyle, happy hardcore, ambient\nhardstyle, happy hardcore, chiptune\nhardstyle, happy hardcore, cinematic\nhardstyle, happy hardcore, cinematic pop\nhardstyle, happy hardcore, dance-pop\nhardstyle, happy hardcore, dancehall\nhardstyle, happy hardcore, dream pop\nhardstyle, happy hardcore, emo rap\nhardstyle, happy hardcore, ethereal pop\nhardstyle, happy hardcore, folk\nhardstyle, happy hardcore, gabber\nhardstyle, happy hardcore, hyper-dance\nhardstyle, happy hardcore, hyperpop\nhardstyle, happy hardcore, kuthu\nhardstyle, happy hardcore, melbourne bounce\nhardstyle, happy hardcore, melodic\nhardstyle, happy hardcore, meme music\nhardstyle, happy hardcore, meme rap\nhardstyle, happy hardcore, metalcore\nhardstyle, happy hardcore, orchestral\nhardstyle, happy hardcore, party rap\nhardstyle, happy hardcore, piano ballad\nhardstyle, happy hardcore, polka\nhardstyle, happy hardcore, pop\nhardstyle, happy hardcore, punk rock\nhardstyle, happy hardcore, rap\nhardstyle, happy hardcore, rave\nhardstyle, happy hardcore, reggaeton\nhardstyle, happy hardcore, sea shanty\nhardstyle, happy hardcore, trance\nhardstyle, happy hardcore, trancecore\nhardstyle, hard trance\nhardstyle, hard trance, cinematic\nhardstyle, hard trance, rock\nhardstyle, hard trap, meme rap\nhardstyle, hardbass\nhardstyle, hardbass, hyperpop\nhardstyle, hardbass, meme rap\nhardstyle, hardcore techno\nhardstyle, hardcore techno, C-pop\nhardstyle, hardcore techno, Cantopop\nhardstyle, hardcore techno, East Asian fusion\nhardstyle, hardcore techno, East Asian melodic\nhardstyle, hardcore techno, J-pop\nhardstyle, hardcore techno, Portuguese rap\nhardstyle, hardcore techno, ambient\nhardstyle, hardcore techno, chiptune\nhardstyle, hardcore techno, classical electronic\nhardstyle, hardcore techno, gabber\nhardstyle, hardcore techno, hyperpop\nhardstyle, hardcore techno, industrial hip-hop\nhardstyle, hardcore techno, nintendocore\nhardstyle, hardcore techno, rap\nhardstyle, hardcore techno, speedcore\nhardstyle, hardcore techno, synth-pop\nhardstyle, hardcore techno, trance\nhardstyle, hardcore techno, video game\nhardstyle, hardcore techno, world music\nhardstyle, hardcore, Middle Eastern fusion\nhardstyle, hardcore, chiptune\nhardstyle, hardcore, complexro\nhardstyle, hardcore, speedcore\nhardstyle, hardtek, meme rap\nhardstyle, hip-hop, C-pop\nhardstyle, hip-hop, Indian fusion\nhardstyle, hip-hop, electronic\nhardstyle, hip-hop, kuthu\nhardstyle, hybrid trap\nhardstyle, hybrid trap, cinematic\nhardstyle, hyperpop\nhardstyle, hyperpop, Brazilian funk\nhardstyle, hyperpop, C-pop\nhardstyle, hyperpop, EDM\nhardstyle, hyperpop, J-core\nhardstyle, hyperpop, J-rock\nhardstyle, hyperpop, Russian EDM\nhardstyle, hyperpop, breakcore, dance-pop\nhardstyle, hyperpop, chiptune\nhardstyle, hyperpop, electronic rap\nhardstyle, hyperpop, folktronica\nhardstyle, hyperpop, gabber\nhardstyle, hyperpop, happy hardcore\nhardstyle, hyperpop, nightcore\nhardstyle, hyperpop, rap\nhardstyle, hyperpop, turbo-folk\nhardstyle, hǎnmài\nhardstyle, hǎnmài, electronic\nhardstyle, hǎnmài, rave\nhardstyle, hǎnmài, shouyoving\nhardstyle, indie-pop, rap\nhardstyle, industrial hip-hop, breakbeat\nhardstyle, industrial metal, chiptune\nhardstyle, industrial metal, psytrance\nhardstyle, industrial metal, trance\nhardstyle, industrial techno\nhardstyle, industrial techno, chiptune\nhardstyle, industrial techno, cinematic\nhardstyle, industrial techno, cinematic electronic\nhardstyle, industrial, K-pop\nhardstyle, industrial, Malayalam fusion\nhardstyle, industrial, aggressive electro\nhardstyle, industrial, big room techno\nhardstyle, industrial, chiptune\nhardstyle, industrial, psytrance\nhardstyle, j-core, happy hardcore\nhardstyle, k-pop, electronic\nhardstyle, klezmer\nhardstyle, klezmer, chiptune\nhardstyle, kuthu\nhardstyle, kuthu, bollywood\nhardstyle, kuthu, gaana\nhardstyle, laïko\nhardstyle, laïko, electronic\nhardstyle, lo-fi R&B\nhardstyle, lo-fi hip hop\nhardstyle, lo-fi hip hop, EDM\nhardstyle, lo-fi hip-hop\nhardstyle, lo-fi, C-pop\nhardstyle, lo-fi, French pop\nhardstyle, lo-fi, ambient\nhardstyle, lo-fi, chiptune\nhardstyle, manele\nhardstyle, maneles\nhardstyle, melancholic pop\nhardstyle, melbourne bounce\nhardstyle, melbourne bounce, cinematic\nhardstyle, melodic hardcore, techno\nhardstyle, melodic hardstyle\nhardstyle, melodic riddim\nhardstyle, melodic trance\nhardstyle, melodic trance, ambient\nhardstyle, melodic trance, hardcore techno\nhardstyle, meme music\nhardstyle, meme music, Indian folk fusion\nhardstyle, meme music, electronic\nhardstyle, meme rap, Hebrew electronic\nhardstyle, meme rap, hardcore techno\nhardstyle, meme rap, hardtek\nhardstyle, meme, chiptune\nhardstyle, metalcore, cinematic\nhardstyle, metalcore, happy hardcore\nhardstyle, metalcore, post-rock\nhardstyle, military march, electronic dance\nhardstyle, moombahton, Bhojpuri\nhardstyle, moombahton, Bollywood\nhardstyle, moombahton, Indian folk\nhardstyle, moombahton, Latin electronic\nhardstyle, moombahton, Middle Eastern\nhardstyle, moombahton, South Asian folk\nhardstyle, moombahton, trap\nhardstyle, neurofunk, electronic\nhardstyle, nightcore\nhardstyle, nightcore, EDM\nhardstyle, nightcore, J-core\nhardstyle, nightcore, Russian dance-pop\nhardstyle, nightcore, happy hardcore\nhardstyle, nightcore, hyperpop\nhardstyle, oom-pah techno, German schlager\nhardstyle, orchestral, cinematic\nhardstyle, orchestral, dubstep\nhardstyle, oriental EDM\nhardstyle, oriental hardstyle\nhardstyle, oriental, cinematic\nhardstyle, oriental, electronic\nhardstyle, partyschlager\nhardstyle, pasodoble, electronic\nhardstyle, patriotic pop\nhardstyle, phonk\nhardstyle, phonk, cinematic electronic\nhardstyle, phonk, trap\nhardstyle, pirate folk, comedy\nhardstyle, pop ballad\nhardstyle, pop ballad, big room house\nhardstyle, pop ballad, chiptune\nhardstyle, pop, electronic\nhardstyle, pop, hip hop\nhardstyle, pop-R&B\nhardstyle, pop-anthem\nhardstyle, pop-ballad, happy hardcore\nhardstyle, pop-punk\nhardstyle, pop-punk, choral\nhardstyle, pop-punk, happy hardcore\nhardstyle, pop-rap, bass house\nhardstyle, pop-rock\nhardstyle, pop-rock, C-pop\nhardstyle, pop-rock, ambient\nhardstyle, pop-rock, ballad\nhardstyle, pop-rock, cinematic\nhardstyle, pop-rock, electronic\nhardstyle, pop-rock, progressive house\nhardstyle, pop-rock, rap\nhardstyle, pop-rock, trance\nhardstyle, progressive house\nhardstyle, progressive house, EDM\nhardstyle, progressive house, ambient\nhardstyle, progressive house, big room\nhardstyle, progressive house, big room EDM\nhardstyle, progressive house, big room house\nhardstyle, progressive house, hip-hop\nhardstyle, progressive house, piano ballad\nhardstyle, progressive house, pop-ballad\nhardstyle, progressive house, trance\nhardstyle, progressive trance\nhardstyle, psytrance\nhardstyle, psytrance, Arabic chant\nhardstyle, psytrance, Arabic chiptune\nhardstyle, psytrance, Balkan brass\nhardstyle, psytrance, Bollywood\nhardstyle, psytrance, C-pop\nhardstyle, psytrance, Indian bhajan\nhardstyle, psytrance, Indian devotional\nhardstyle, psytrance, Indian folk\nhardstyle, psytrance, Indian fusion\nhardstyle, psytrance, K-pop\nhardstyle, psytrance, Latin urban\nhardstyle, psytrance, Middle Eastern\nhardstyle, psytrance, Middle Eastern fusion\nhardstyle, psytrance, Mizrahi pop\nhardstyle, psytrance, Persian electronic\nhardstyle, psytrance, R&B\nhardstyle, psytrance, Russian vocal\nhardstyle, psytrance, Sanskrit chanting\nhardstyle, psytrance, Turkish electronic\nhardstyle, psytrance, ambient\nhardstyle, psytrance, ancient style\nhardstyle, psytrance, big room\nhardstyle, psytrance, big room house\nhardstyle, psytrance, cinematic\nhardstyle, psytrance, dance\nhardstyle, psytrance, dark ambient\nhardstyle, psytrance, devotional\nhardstyle, psytrance, devotional electronic\nhardstyle, psytrance, electronic\nhardstyle, psytrance, ethereal\nhardstyle, psytrance, ethnic\nhardstyle, psytrance, folk\nhardstyle, psytrance, gabber\nhardstyle, psytrance, glitch\nhardstyle, psytrance, hardcore\nhardstyle, psytrance, hyperpop\nhardstyle, psytrance, industrial\nhardstyle, psytrance, industrial hardcore\nhardstyle, psytrance, lo-fi\nhardstyle, psytrance, orchestral\nhardstyle, psytrance, sci-fi electronic\nhardstyle, psytrance, spiritual\nhardstyle, psytrance, spiritual electronic\nhardstyle, psytrance, techno\nhardstyle, psytrance, trance\nhardstyle, psytrance, trap\nhardstyle, psytrance, tribal\nhardstyle, psytrance, tribal electronic\nhardstyle, psytrance, world fusion\nhardstyle, punk rock, happy hardcore\nhardstyle, rap, pop-rock\nhardstyle, rave\nhardstyle, rave rap\nhardstyle, rave, industrial\nhardstyle, rawstyle\nhardstyle, reggaeton\nhardstyle, reggaeton, EDM\nhardstyle, reggaeton, Latin\nhardstyle, reggaeton, Latin pop\nhardstyle, reggaeton, ethereal\nhardstyle, reggaeton, moombahton\nhardstyle, ritual ambient\nhardstyle, rock, Japanese hip-hop\nhardstyle, russian rave\nhardstyle, schlager\nhardstyle, schlager, EDM\nhardstyle, schlager, polka\nhardstyle, show tune\nhardstyle, speedcore\nhardstyle, speedcore, artcore\nhardstyle, speedcore, breakcore\nhardstyle, speedcore, chiptune\nhardstyle, speedcore, cinematic\nhardstyle, speedcore, gabber\nhardstyle, speedcore, happy hardcore\nhardstyle, speedcore, meme music\nhardstyle, speedcore, trance\nhardstyle, spiritual, electronic\nhardstyle, synth-pop\nhardstyle, synth-pop, EDM\nhardstyle, synth-pop, Mandopop\nhardstyle, synth-pop, chiptune\nhardstyle, synth-pop, electronic\nhardstyle, synth-pop, rap\nhardstyle, synth-pop, trance\nhardstyle, synthwave\nhardstyle, tearout dubstep\nhardstyle, tearout dubstep, ambient\nhardstyle, tearout dubstep, trap\nhardstyle, techno, klezmer\nhardstyle, theatrical pop, rap\nhardstyle, traditional Southeast Asian folk\nhardstyle, traditional Southeast Asian, electronic\nhardstyle, trance\nhardstyle, trance, Bollywood\nhardstyle, trance, C-pop\nhardstyle, trance, East Asian fusion\nhardstyle, trance, Greek pop\nhardstyle, trance, J-core\nhardstyle, trance, J-pop\nhardstyle, trance, K-pop\nhardstyle, trance, Mandarin pop\nhardstyle, trance, North African fusion\nhardstyle, trance, South Asian pop\nhardstyle, trance, UK hardcore\nhardstyle, trance, V-pop\nhardstyle, trance, ambient\nhardstyle, trance, anime theme\nhardstyle, trance, big room\nhardstyle, trance, big room house\nhardstyle, trance, breakcore\nhardstyle, trance, chiptune\nhardstyle, trance, cinematic\nhardstyle, trance, complextro\nhardstyle, trance, cyberpunk\nhardstyle, trance, dancehall\nhardstyle, trance, darksynth\nhardstyle, trance, dream-pop\nhardstyle, trance, drum and bass\nhardstyle, trance, dubstep\nhardstyle, trance, electronic\nhardstyle, trance, ethereal\nhardstyle, trance, glitch\nhardstyle, trance, happy hardcore\nhardstyle, trance, hardcore\nhardstyle, trance, hardcore techno\nhardstyle, trance, hip-hop\nhardstyle, trance, hyperpop\nhardstyle, trance, industrial techno\nhardstyle, trance, lo-fi\nhardstyle, trance, lo-fi hip hop\nhardstyle, trance, melodic\nhardstyle, trance, piano ballad\nhardstyle, trance, power metal\nhardstyle, trance, rap\nhardstyle, trance, video game music\nhardstyle, trance-pop\nhardstyle, trancecore, ambient\nhardstyle, trancecore, cinematic\nhardstyle, trap metal, R&B\nhardstyle, trap metal, chiptune\nhardstyle, trap metal, electronic rap\nhardstyle, trap, Balkan folk\nhardstyle, trap, Bollywood\nhardstyle, trap, C-pop\nhardstyle, trap, Chinese electronic\nhardstyle, trap, Chinese rap\nhardstyle, trap, Chinese traditional\nhardstyle, trap, Christmas\nhardstyle, trap, Dutch rap\nhardstyle, trap, EDM\nhardstyle, trap, East Asian electronic\nhardstyle, trap, East Asian fusion\nhardstyle, trap, German rap\nhardstyle, trap, Indian devotional\nhardstyle, trap, Indian electronic\nhardstyle, trap, Indian folk\nhardstyle, trap, Indian hip-hop\nhardstyle, trap, Islamic devotional\nhardstyle, trap, Javanese rap\nhardstyle, trap, K-pop\nhardstyle, trap, Latin electronic\nhardstyle, trap, Mandarin rap\nhardstyle, trap, Mandopop\nhardstyle, trap, Middle Eastern\nhardstyle, trap, Middle Eastern fusion\nhardstyle, trap, Russian rap\nhardstyle, trap, ambient\nhardstyle, trap, ancient style\nhardstyle, trap, baile funk\nhardstyle, trap, chiptune\nhardstyle, trap, cinematic\nhardstyle, trap, electronic\nhardstyle, trap, folk\nhardstyle, trap, folk fusion\nhardstyle, trap, glitch-hop\nhardstyle, trap, hardcore techno\nhardstyle, trap, melodic\nhardstyle, trap, orchestral\nhardstyle, trap, phonk\nhardstyle, trap, pop\nhardstyle, trap, pop-punk\nhardstyle, trap, progressive house\nhardstyle, trap, reggaeton, pop-rap\nhardstyle, trap, reggaeton, techno\nhardstyle, trap, spiritual EDM\nhardstyle, trap, trance\nhardstyle, trap, world bass\nhardstyle, trap, world music\nhardstyle, trap-metal\nhardstyle, tribal house, Latin urban\nhardstyle, trip-hop, techno\nhardstyle, trot\nhardstyle, turbo-folk\nhardstyle, uplifting trance\nhardstyle, vaporwave\nhardstyle, world fusion\nhardstyle, world music, C-pop\nhardstyle, world music, electronic\nhardstyle, 喊麦\nhardtek gabber\nhardwave\nhardwave chiptune\nhardwave dark synthwave\nhardwave dark techno\nhardwave experimental trap\nhardwave future bass\nhardwave phonk\nhardwave phonk trap\nhardwave trap\nhardwave trap chiptune\nhardwave trap ethnic electronic\nhardwave trap trance\nhardwave, trap, electronic pop\nharyanvi\nharyanvi dance\nharyanvi electronic\nhaunted hip-hop\nhaunted lullaby\nhaunting a cappella\nhaunting acapella\nhaunting ballad\nhaunting electronic\nhaunting folk\nhaunting hip-hop\nhaunting lullaby\nhaunting piano ballad\nhazy trap\nheartland hip-hop\nheartland rock\nheartland rock alt-country\nheartland rock country\nheartland rock country-pop\nheartland rock hip-hop\nheartland rock outlaw country\nheartland rock punk\nheartland rock skate punk\nheartland rock, Southern hip-hop\nheartland rock, cosmic country\nheartland rock, country rock, Eurodance\nheavy metal\nheavy metal Neue Deutsche Härte\nheavy metal Tamil rock\nheavy metal axé\nheavy metal big band\nheavy metal chiptune\nheavy metal forró\nheavy metal kuthu\nheavy metal norteño\nheavy metal power metal\nheavy metal revolutionary anthem\nheavy metal turbo-folk\nheavy metal, Arabic rock\nheavy metal, Balkan folk\nheavy metal, Bollywood anthem rock\nheavy metal, C-pop, ambient\nheavy metal, Carnatic fusion\nheavy metal, Chinese folk\nheavy metal, Chinese folk fusion\nheavy metal, Chinese fusion\nheavy metal, Chinese traditional\nheavy metal, East Asian folk\nheavy metal, Indian cinematic\nheavy metal, Indian classical\nheavy metal, Indian film music\nheavy metal, Indian folk\nheavy metal, Indian folk rock\nheavy metal, Indian rock\nheavy metal, Islamic devotional\nheavy metal, Japanese folk\nheavy metal, Javanese fusion\nheavy metal, Javanese music\nheavy metal, Latin rock\nheavy metal, Luk Thung\nheavy metal, Melayu pop\nheavy metal, Middle Eastern folk\nheavy metal, Middle Eastern fusion\nheavy metal, Mongolian folk\nheavy metal, North African folk\nheavy metal, Punjabi folk, electronic\nheavy metal, South Asian folk\nheavy metal, South Indian folk\nheavy metal, South Indian rock\nheavy metal, Southeast Asian fusion\nheavy metal, Tamil folk\nheavy metal, Tamil rock\nheavy metal, big band\nheavy metal, big band, swing\nheavy metal, cabaret rock, cumbia ska\nheavy metal, cumbia\nheavy metal, dangdut koplo\nheavy metal, folk fusion\nheavy metal, folk rock, South Asian\nheavy metal, forró, fusion\nheavy metal, kuthu\nheavy metal, luk thung\nheavy metal, pagode\nheavy metal, piano ballad\nheavy metal, power pop, theatrical rock\nheavy metal, traditional Malay, fusion\nheavy rock\nheavy rock kuthu\nheavy rock, Carnatic fusion\nheavy rock, Chinese folk, cinematic\nheavy rock, Chinese fusion\nheavy rock, East Asian folk, cinematic\nheavy rock, Indian classical\nheavy rock, Indian devotional\nheavy rock, Indian folk\nheavy rock, Japanese fusion\nheavy rock, South Asian folk\nheavy rock, South Indian cinematic\nheavy rock, South Indian folk\nheavy rock, classical Indian, Sanskrit chant\nheavy rock, min'yō\nheroic hip-hop\nheroic rock\nheroic trap\nhi-NRG\nhi-NRG dance-pop\nhick-hop\nhigh-energy rock\nhighlife\nhighlife soukous\nhighlife, soukous, Christmas\nhip hop\nhip hop EDM\nhip hop R&B\nhip hop dance\nhip hop dance-pop\nhip hop dancehall\nhip hop dancehall afrobeat\nhip hop dancehall gospel pop\nhip hop drum and bass\nhip hop electro house\nhip hop electro-pop\nhip hop electronic\nhip hop electronic pop\nhip hop electronic rock\nhip hop funk\nhip hop funk dancehall\nhip hop funk disco\nhip hop pop\nhip hop pop world music\nhip hop pop-funk\nhip hop pop-rock\nhip hop rock\nhip hop soul\nhip hop techno\nhip hop, 90s R&B\nhip hop, Balkan dance, electronic\nhip hop, Cantonese rap, Mandarin rap\nhip hop, Chinese hip hop\nhip hop, Chinese rap\nhip hop, EDM\nhip hop, EDM, Swedish party\nhip hop, EDM, bilingual\nhip hop, EDM, party\nhip hop, East Asian fusion\nhip hop, G-funk\nhip hop, Indian fusion\nhip hop, Indian hip hop\nhip hop, J-RPG, cinematic\nhip hop, Latin dance\nhip hop, Latin funk, retro\nhip hop, Latin pop\nhip hop, Latin rap\nhip hop, Latin trap\nhip hop, Latin urban\nhip hop, Latin, party\nhip hop, Latin, political\nhip hop, Middle Eastern\nhip hop, Middle Eastern dance\nhip hop, Middle Eastern fusion\nhip hop, Middle Eastern, Balkan\nhip hop, R&B\nhip hop, R&B, ambient\nhip hop, R&B, electronic\nhip hop, R&B, lo-fi\nhip hop, R&B, trip-hop\nhip hop, V-pop\nhip hop, ambient, dystopian\nhip hop, big room EDM\nhip hop, big-band swing, Christmas\nhip hop, boogie-woogie\nhip hop, boogie-woogie, R&B\nhip hop, boom-bap\nhip hop, boom-bap, Chinese hip hop\nhip hop, boom-bap, Chinese rap\nhip hop, boom-bap, East Asian fusion\nhip hop, boom-bap, Italian rap\nhip hop, boom-bap, cinematic\nhip hop, boom-bap, eastern\nhip hop, boom-bap, electronic\nhip hop, boom-bap, trap\nhip hop, carnaval\nhip hop, chiptune\nhip hop, chiptune, C-pop\nhip hop, chiptune, cinematic\nhip hop, chiptune, lo-fi\nhip hop, cinematic\nhip hop, cinematic, Chinese battle rap\nhip hop, cinematic, Chinese opera\nhip hop, cinematic, Chinese rap\nhip hop, cinematic, East Asian\nhip hop, cinematic, Indian\nhip hop, cinematic, Indian classical\nhip hop, cinematic, Indian hip hop\nhip hop, cinematic, Middle Eastern\nhip hop, cinematic, Persian rap\nhip hop, cinematic, R&B\nhip hop, cinematic, boom-bap\nhip hop, cinematic, chiptune\nhip hop, cinematic, chopped and screwed\nhip hop, cinematic, dark ambient\nhip hop, cinematic, dub\nhip hop, cinematic, dubstep\nhip hop, cinematic, electronic\nhip hop, cinematic, glitch\nhip hop, cinematic, jazzy\nhip hop, cinematic, lo-fi\nhip hop, cinematic, nu-metal\nhip hop, cinematic, orchestral\nhip hop, cinematic, psychedelic\nhip hop, cinematic, retro game\nhip hop, cinematic, trap\nhip hop, cinematic, underground\nhip hop, cinematic, world music\nhip hop, classical\nhip hop, comedy rap\nhip hop, dance-pop, Middle Eastern\nhip hop, dark ambient\nhip hop, dark trap\nhip hop, dubstep\nhip hop, electronic\nhip hop, electronic dance music\nhip hop, electronic dance, Middle Eastern fusion\nhip hop, electronic, Chinese underground\nhip hop, experimental\nhip hop, flamenco, ambient\nhip hop, flamenco, electronic\nhip hop, funk rock, indie pop\nhip hop, futuristic\nhip hop, g-funk\nhip hop, global club\nhip hop, gospel, ambient\nhip hop, gospel, vocal soul\nhip hop, hard dance\nhip hop, horrorcore\nhip hop, house\nhip hop, industrial, cinematic\nhip hop, jazz\nhip hop, jazz rap\nhip hop, jazz, world music\nhip hop, lo-fi, Eastern\nhip hop, lo-fi, ambient\nhip hop, lo-fi, boom-bap\nhip hop, lo-fi, cinematic\nhip hop, lo-fi, epic\nhip hop, lo-fi, experimental\nhip hop, lo-fi, psychedelic\nhip hop, lo-fi, underground\nhip hop, metal, cinematic\nhip hop, neo-soul\nhip hop, new jack swing\nhip hop, new jack swing, tropical\nhip hop, noir, lo-fi\nhip hop, noir-jazz\nhip hop, nu-metal\nhip hop, orchestral\nhip hop, pop-funk\nhip hop, pop-rock, lo-fi\nhip hop, protest music\nhip hop, psychedelic\nhip hop, psychedelic, lo-fi\nhip hop, psychedelic, world music\nhip hop, quirky\nhip hop, ragtime, Latin\nhip hop, ragtime, electronic\nhip hop, rap rock\nhip hop, sci-fi\nhip hop, sci-fi horror\nhip hop, soul, ambient\nhip hop, soul, cinematic\nhip hop, soul, jazz\nhip hop, traditional Japanese, cinematic\nhip hop, trap\nhip hop, trap, Indian fusion\nhip hop, trap, K-pop\nhip hop, trap, boom-bap\nhip hop, trap, cinematic\nhip hop, trap, cinematic hip hop\nhip hop, trap, electronic\nhip hop, trap, industrial\nhip hop, trap, lo-fi\nhip hop, underground\nhip hop, vaporwave\nhip hop, vaporwave, trap\nhip hop, world beat\nhip hop, world fusion, electronic\nhip hop, world music\nhip house\nhip house freestyle\nhip-hop\nhip-hop Afro-Caribbean\nhip-hop Afro-Cuban\nhip-hop Afrobeat\nhip-hop Afrobeat dancehall\nhip-hop Arabic fusion\nhip-hop Balkan\nhip-hop C-pop\nhip-hop C-pop J-pop\nhip-hop C-pop R&B\nhip-hop C-pop cinematic\nhip-hop C-pop trap\nhip-hop EDM\nhip-hop EDM pop\nhip-hop EDM trap\nhip-hop G-funk\nhip-hop G-funk chiptune\nhip-hop G-funk neo-soul\nhip-hop J-pop\nhip-hop J-pop R&B\nhip-hop J-pop anime\nhip-hop J-pop breakbeat\nhip-hop J-pop chiptune\nhip-hop J-pop electronic\nhip-hop J-pop fusion\nhip-hop J-pop trap\nhip-hop J-rock\nhip-hop K-pop fusion\nhip-hop Latin\nhip-hop Latin R&B\nhip-hop Latin funk\nhip-hop Latin fusion\nhip-hop Latin pop\nhip-hop Mandopop\nhip-hop Punjabi\nhip-hop Punjabi pop\nhip-hop R&B\nhip-hop R&B Afro-Latin\nhip-hop R&B Afrobeat\nhip-hop R&B Afrobeats\nhip-hop R&B Balkan\nhip-hop R&B Brazilian funk\nhip-hop R&B East Asian hip-hop\nhip-hop R&B Hawaiian\nhip-hop R&B Kizomba\nhip-hop R&B Latin\nhip-hop R&B North African\nhip-hop R&B South Asian\nhip-hop R&B Southern\nhip-hop R&B West Coast\nhip-hop R&B afrobeat\nhip-hop R&B afrobeats\nhip-hop R&B blues-rock\nhip-hop R&B chiptune\nhip-hop R&B cinematic\nhip-hop R&B conscious rap\nhip-hop R&B country\nhip-hop R&B crossover\nhip-hop R&B dancehall\nhip-hop R&B electronic\nhip-hop R&B flamenco\nhip-hop R&B funk\nhip-hop R&B fusion\nhip-hop R&B gospel\nhip-hop R&B lo-fi\nhip-hop R&B neo-soul\nhip-hop R&B new jack swing\nhip-hop R&B orchestral\nhip-hop R&B party\nhip-hop R&B pop\nhip-hop R&B pop-rock\nhip-hop R&B reggae\nhip-hop R&B soul\nhip-hop R&B synth-pop\nhip-hop R&B trap\nhip-hop R&B trap-soul\nhip-hop R&B vaporwave\nhip-hop R&B world music\nhip-hop R&B zouk\nhip-hop R&B, neo-soul\nhip-hop acid jazz\nhip-hop acid jazz funk\nhip-hop acid jazz trip-hop\nhip-hop acid jazz world music\nhip-hop afrobeat\nhip-hop afrobeat Latin pop\nhip-hop afrobeat chiptune\nhip-hop afrobeat dancehall\nhip-hop afrobeats\nhip-hop afrobeats dancehall\nhip-hop alternative R&B\nhip-hop alternative pop\nhip-hop alternative rock\nhip-hop alternative rock electronic\nhip-hop alternative rock psychedelic pop\nhip-hop ambient\nhip-hop anime\nhip-hop arabic pop\nhip-hop ballad\nhip-hop ballad, pop-rock, C-pop\nhip-hop bass\nhip-hop bhangra\nhip-hop bhangra fusion\nhip-hop big band\nhip-hop bilingual\nhip-hop blues\nhip-hop blues rock\nhip-hop blues-rock\nhip-hop bolero\nhip-hop bollywood\nhip-hop boogie\nhip-hop boom-bap\nhip-hop bossa nova\nhip-hop breakbeat\nhip-hop chillwave\nhip-hop chiptune\nhip-hop chiptune J-pop\nhip-hop chiptune R&B\nhip-hop chiptune afrobeat\nhip-hop chiptune afrobeats\nhip-hop chiptune balkan folk\nhip-hop chiptune comedy rap\nhip-hop chiptune dancehall\nhip-hop chiptune eurodance\nhip-hop chiptune funk\nhip-hop chiptune gospel\nhip-hop chiptune pop\nhip-hop chiptune punk\nhip-hop chiptune reggae\nhip-hop chiptune synth-pop\nhip-hop chiptune synthwave\nhip-hop chiptune trap\nhip-hop chiptune vaporwave\nhip-hop chiptune world music\nhip-hop cinematic\nhip-hop city pop\nhip-hop classical\nhip-hop classical crossover\nhip-hop classical fusion\nhip-hop club\nhip-hop comedy\nhip-hop corrido\nhip-hop country\nhip-hop country-rock\nhip-hop crooner\nhip-hop crunk\nhip-hop cumbia\nhip-hop cumbia bilingual\nhip-hop cumbia chiptune\nhip-hop dance\nhip-hop dance-pop\nhip-hop dancehall\nhip-hop dancehall R&B\nhip-hop dancehall afrobeat\nhip-hop dancehall afrobeats\nhip-hop dancehall chiptune\nhip-hop dancehall pop\nhip-hop dancehall reggae\nhip-hop dancehall reggaeton\nhip-hop dancehall tropical\nhip-hop deep house\nhip-hop dembow\nhip-hop desi\nhip-hop dream pop\nhip-hop dream-pop\nhip-hop drill\nhip-hop drum and bass\nhip-hop dub\nhip-hop dub reggae\nhip-hop dubstep\nhip-hop dubstep jazz\nhip-hop dubstep neurofunk\nhip-hop electro\nhip-hop electro-funk\nhip-hop electro-funk chiptune\nhip-hop electro-pop\nhip-hop electronic\nhip-hop electronic chiptune\nhip-hop electronic dancehall\nhip-hop electronic pop\nhip-hop electronic rock\nhip-hop electronic world music\nhip-hop experimental\nhip-hop fado\nhip-hop flamenco\nhip-hop flamenco piano ballad\nhip-hop folk\nhip-hop folk fusion\nhip-hop folk-rock\nhip-hop funk\nhip-hop funk Arabic\nhip-hop funk G-funk\nhip-hop funk J-pop\nhip-hop funk Latin\nhip-hop funk R&B\nhip-hop funk acid jazz\nhip-hop funk blues-rock\nhip-hop funk chiptune\nhip-hop funk city pop\nhip-hop funk dancehall\nhip-hop funk disco\nhip-hop funk electronic\nhip-hop funk fusion\nhip-hop funk g-funk\nhip-hop funk gospel\nhip-hop funk indie pop\nhip-hop funk jazz\nhip-hop funk jazz fusion\nhip-hop funk latin\nhip-hop funk neo-soul\nhip-hop funk nu-disco\nhip-hop funk pop\nhip-hop funk psychedelic rock\nhip-hop funk reggae\nhip-hop funk rock\nhip-hop funk ska\nhip-hop funk soul\nhip-hop funk trap\nhip-hop funk trip-hop\nhip-hop funk world music\nhip-hop funk-hop\nhip-hop funk-pop\nhip-hop funk-rock\nhip-hop fusion\nhip-hop future bass\nhip-hop future bass R&B\nhip-hop go-go\nhip-hop gospel\nhip-hop gospel R&B\nhip-hop gospel afrobeat\nhip-hop gospel big band\nhip-hop gospel electronic\nhip-hop gospel funk\nhip-hop gospel pop\nhip-hop gospel rock\nhip-hop gospel soul\nhip-hop grime\nhip-hop gypsy jazz\nhip-hop hardstyle\nhip-hop house\nhip-hop indie pop\nhip-hop indie rock\nhip-hop indie-pop\nhip-hop industrial\nhip-hop island\nhip-hop jazz\nhip-hop jazz funk\nhip-hop jazz lounge\nhip-hop jazz-funk\nhip-hop jazz-rock\nhip-hop klezmer\nhip-hop lo-fi\nhip-hop lounge\nhip-hop lounge R&B\nhip-hop lounge jazz\nhip-hop lullaby\nhip-hop mariachi\nhip-hop metal\nhip-hop metalcore\nhip-hop musical theater\nhip-hop neo-soul\nhip-hop neo-soul Latin\nhip-hop neo-soul R&B\nhip-hop neo-soul acid jazz\nhip-hop neo-soul chiptune\nhip-hop neo-soul funk\nhip-hop neo-soul g-funk\nhip-hop neo-soul gospel\nhip-hop neo-soul jazz\nhip-hop neo-soul jazz fusion\nhip-hop neo-soul jazz-funk\nhip-hop neo-soul jazz-rap\nhip-hop neo-soul vaporwave\nhip-hop new jack swing\nhip-hop new wave\nhip-hop noir\nhip-hop norteño fusion\nhip-hop novelty\nhip-hop nu-metal\nhip-hop nu-metal chiptune\nhip-hop nu-metal electronic\nhip-hop nu-metal industrial\nhip-hop opera\nhip-hop orchestral\nhip-hop oud\nhip-hop oud fusion\nhip-hop party\nhip-hop patriotic\nhip-hop pirate\nhip-hop polka\nhip-hop pop\nhip-hop pop Bollywood\nhip-hop pop EDM\nhip-hop pop R&B\nhip-hop pop chiptune\nhip-hop pop dancehall\nhip-hop pop electronic\nhip-hop pop electronic rock\nhip-hop pop funk\nhip-hop pop fusion\nhip-hop pop future bass\nhip-hop pop rock\nhip-hop pop soul\nhip-hop pop stadium rock\nhip-hop pop trap\nhip-hop pop world music\nhip-hop pop-R&B\nhip-hop pop-R&B fusion\nhip-hop pop-funk\nhip-hop pop-punk\nhip-hop pop-punk electronic\nhip-hop pop-r&b\nhip-hop pop-rap\nhip-hop pop-rock\nhip-hop pop-rock crossover\nhip-hop pop-rock electronic\nhip-hop pop-rock fusion\nhip-hop pop-rock world music\nhip-hop pop-trap\nhip-hop post-punk\nhip-hop protest\nhip-hop punk\nhip-hop punk rock\nhip-hop ragtime\nhip-hop rap-rock\nhip-hop reggae\nhip-hop reggae R&B\nhip-hop reggae chiptune\nhip-hop reggae dancehall\nhip-hop reggae dub\nhip-hop reggae funk\nhip-hop reggae fusion\nhip-hop reggae latin\nhip-hop reggae pop-rap\nhip-hop reggae rock\nhip-hop reggae smooth jazz\nhip-hop reggae soul\nhip-hop reggae tropical\nhip-hop reggae world music\nhip-hop reggae-dub\nhip-hop reggae-pop\nhip-hop reggaeton\nhip-hop reggaeton dancehall\nhip-hop reggaeton grime\nhip-hop regional mexicano\nhip-hop rock\nhip-hop rock crossover\nhip-hop rock dubstep\nhip-hop rock electronic\nhip-hop rock funk\nhip-hop rock fusion\nhip-hop rock gospel\nhip-hop rock latin\nhip-hop rock opera\nhip-hop rock soul\nhip-hop rock trap\nhip-hop rock world fusion\nhip-hop rock world music\nhip-hop rockabilly\nhip-hop salsa\nhip-hop samba\nhip-hop samba-rock\nhip-hop satire\nhip-hop sea shanty\nhip-hop singer-songwriter\nhip-hop soul\nhip-hop soul dream-pop\nhip-hop soul funk\nhip-hop soul gospel\nhip-hop soul house\nhip-hop soul jazz\nhip-hop soul psychedelic\nhip-hop soul reggae\nhip-hop soul-rock\nhip-hop spoken word\nhip-hop stadium rock\nhip-hop surf-rock\nhip-hop swing\nhip-hop synth-pop\nhip-hop synth-pop indie electronic\nhip-hop tango\nhip-hop tango balkan brass\nhip-hop tech house\nhip-hop techno\nhip-hop trap\nhip-hop trap R&B\nhip-hop trap boom-bap\nhip-hop trap neo-soul\nhip-hop trap world music\nhip-hop tribal fusion\nhip-hop trip-hop\nhip-hop tropical\nhip-hop vaporwave\nhip-hop vaporwave chillwave\nhip-hop vaporwave chiptune\nhip-hop world fusion\nhip-hop world music\nhip-hop world music electronic pop\nhip-hop worldbeat\nhip-hop worldbeat pop\nhip-hop, 2000s R&B\nhip-hop, 8-bit\nhip-hop, 80s video game, cinematic\nhip-hop, 80s, boom-bap\nhip-hop, 90s R&B\nhip-hop, 90s R&B, Afrobeat\nhip-hop, 90s R&B, French rap\nhip-hop, 90s R&B, dance\nhip-hop, 90s R&B, electronic\nhip-hop, 90s new jack swing\nhip-hop, 90s new jack swing, G-funk\nhip-hop, 90s new jack swing, retro\nhip-hop, African R&B\nhip-hop, African rhythms\nhip-hop, African rumba, funk\nhip-hop, African soul\nhip-hop, African traditional\nhip-hop, African, C-pop\nhip-hop, Afro-Caribbean, trap\nhip-hop, Afro-French, live percussion\nhip-hop, Afro-Latin, boom-bap\nhip-hop, Afro-Latin, folk\nhip-hop, Afro-Latin, multi-lingual\nhip-hop, Afro-hop\nhip-hop, Afrobeat\nhip-hop, Afrobeat, French rap\nhip-hop, Afrobeat, bilingual\nhip-hop, Afrobeat, dancehall\nhip-hop, Afrobeat, early 2000s\nhip-hop, Afrobeat, lo-fi\nhip-hop, Afrobeat, trap\nhip-hop, Afrobeats\nhip-hop, Afrobeats, Islamic devotional\nhip-hop, Afrobeats, R&B\nhip-hop, Afrobeats, dancehall\nhip-hop, Afrobeats, lo-fi\nhip-hop, Afrobeats, pop-R&B\nhip-hop, Anatolian folk\nhip-hop, Anatolian fusion\nhip-hop, Anatolian, lo-fi\nhip-hop, Anatolian, melancholic\nhip-hop, Anatolian, microtonal\nhip-hop, Anatolian, modern\nhip-hop, Anatolian, soul\nhip-hop, Andalusian, lo-fi\nhip-hop, Andean folk\nhip-hop, Andean folk, protest music\nhip-hop, Andean, Latin\nhip-hop, Andean, atmospheric\nhip-hop, Andean, lo-fi\nhip-hop, Andean, world music\nhip-hop, Arabic choral\nhip-hop, Arabic fusion\nhip-hop, Arabic fusion, cinematic\nhip-hop, Arabic hip-hop, political\nhip-hop, Arabic pop\nhip-hop, Arabic pop, boom-bap\nhip-hop, Arabic pop, trap\nhip-hop, Arabic rap, Latin rap\nhip-hop, Arabic rap, North African\nhip-hop, Arabic rap, lo-fi\nhip-hop, Arabic soul, jazz fusion\nhip-hop, Arabic, French\nhip-hop, Arabic, Middle Eastern\nhip-hop, Arabic, North African\nhip-hop, Arabic, ambient\nhip-hop, Arabic, atmospheric\nhip-hop, Arabic, boom-bap\nhip-hop, Arabic, cinematic\nhip-hop, Arabic, electronic\nhip-hop, Arabic, lo-fi\nhip-hop, Arabic, melancholic\nhip-hop, Arabic, mystical\nhip-hop, Arabic, spiritual\nhip-hop, Armenian folk\nhip-hop, Asian fusion, trap\nhip-hop, Azerbaijani fusion\nhip-hop, Azerbaijani, melancholic\nhip-hop, Balkan brass\nhip-hop, Balkan brass, lo-fi\nhip-hop, Balkan brass, nostalgic\nhip-hop, Balkan dance-pop\nhip-hop, Balkan folk\nhip-hop, Balkan folk, Middle Eastern\nhip-hop, Balkan folk, cinematic\nhip-hop, Balkan folk, electronic\nhip-hop, Balkan folk, lo-fi\nhip-hop, Balkan folk, political rap\nhip-hop, Balkan folk, theatrical\nhip-hop, Balkan fusion\nhip-hop, Balkan fusion, C-pop\nhip-hop, Balkan fusion, Middle Eastern\nhip-hop, Balkan hip-hop\nhip-hop, Balkan party\nhip-hop, Balkan pop, cinematic\nhip-hop, Balkan pop, klezmer\nhip-hop, Balkan, Klezmer\nhip-hop, Balkan, Latin\nhip-hop, Balkan, Middle Eastern\nhip-hop, Balkan, New Orleans\nhip-hop, Balkan, R&B\nhip-hop, Balkan, aggressive\nhip-hop, Balkan, boom-bap\nhip-hop, Balkan, cinematic\nhip-hop, Balkan, club\nhip-hop, Balkan, duduk\nhip-hop, Balkan, electronic\nhip-hop, Balkan, klezmer\nhip-hop, Balkan, lo-fi\nhip-hop, Balkan, political\nhip-hop, Balkan, polka\nhip-hop, Balkan, pop-rap\nhip-hop, Balkan, quirky\nhip-hop, Balkan, trap\nhip-hop, Balkan, turntablism\nhip-hop, Balkan, upbeat\nhip-hop, Balkan-inspired, quirky\nhip-hop, Bavarian, chiptune\nhip-hop, Bhangra, party\nhip-hop, Bollywood\nhip-hop, Bollywood dance-pop\nhip-hop, Bollywood fusion\nhip-hop, Bollywood pop\nhip-hop, Bollywood pop, retro\nhip-hop, Bollywood, Arabic rap\nhip-hop, Bollywood, Hindi rap\nhip-hop, Bollywood, boom-bap\nhip-hop, Bollywood, cinematic\nhip-hop, Bollywood, dance-pop\nhip-hop, Bollywood, electronic\nhip-hop, Bollywood, folk\nhip-hop, Bollywood, jazz, funk, soul\nhip-hop, Bollywood, lo-fi\nhip-hop, Bollywood, pop\nhip-hop, Bollywood, trap\nhip-hop, Brazilian choral\nhip-hop, Brazilian folk, free-jazz\nhip-hop, Brazilian funk\nhip-hop, Brazilian funk, hyperpop\nhip-hop, Brazilian funk, trap\nhip-hop, Brazilian fusion, cinematic\nhip-hop, Brazilian pop, reggaeton\nhip-hop, Brazilian, ambient\nhip-hop, Brazilian, boom-bap\nhip-hop, Brazilian, chiptune\nhip-hop, Brazilian, patriotic\nhip-hop, Brazilian, soulful\nhip-hop, C-pop\nhip-hop, C-pop, G-funk\nhip-hop, C-pop, Latin fusion\nhip-hop, C-pop, acoustic\nhip-hop, C-pop, ambient\nhip-hop, C-pop, ancient style\nhip-hop, C-pop, cinematic\nhip-hop, C-pop, electronic\nhip-hop, C-pop, emotional\nhip-hop, C-pop, experimental\nhip-hop, C-pop, fusion\nhip-hop, C-pop, lo-fi\nhip-hop, C-pop, soul\nhip-hop, C-pop, theatrical\nhip-hop, C-pop, traditional Chinese\nhip-hop, C-pop, traditional fusion\nhip-hop, C-pop, world fusion\nhip-hop, Caribbean, a cappella\nhip-hop, Caribbean, cinematic\nhip-hop, Caribbean, lo-fi\nhip-hop, Caribbean, soul\nhip-hop, Caribbean, trap\nhip-hop, Carnatic, Tamil\nhip-hop, Carnatic, electronic\nhip-hop, Celtic folk\nhip-hop, Celtic folk, chiptune\nhip-hop, Celtic fusion\nhip-hop, Celtic, boom-bap\nhip-hop, Central Asian\nhip-hop, Central Asian folk\nhip-hop, Central Asian folk, fusion\nhip-hop, Central Asian fusion\nhip-hop, Central Asian pop\nhip-hop, Central Asian, Middle Eastern\nhip-hop, Central Asian, epic\nhip-hop, Central Asian, lo-fi\nhip-hop, Central Asian, melodic\nhip-hop, Central Asian, modern\nhip-hop, Central Asian, underground\nhip-hop, Chinese folk, R&B\nhip-hop, Chinese folk, boom-bap\nhip-hop, Chinese folk, cinematic\nhip-hop, Chinese fusion\nhip-hop, Chinese fusion, boom-bap\nhip-hop, Chinese fusion, electronic\nhip-hop, Chinese fusion, folk\nhip-hop, Chinese fusion, funk\nhip-hop, Chinese fusion, theatrical\nhip-hop, Chinese opera\nhip-hop, Chinese opera, traditional fusion\nhip-hop, Chinese pop, trap\nhip-hop, Chinese storytelling, electronic\nhip-hop, Chinese traditional\nhip-hop, Chinese traditional, aggressive\nhip-hop, Chinese traditional, atmospheric\nhip-hop, Chinese traditional, boom-bap\nhip-hop, Chinese traditional, cinematic\nhip-hop, Chinese traditional, lo-fi\nhip-hop, Chinese, acoustic\nhip-hop, Chinese, ambient\nhip-hop, Chinese, boom-bap\nhip-hop, Chinese, electronic\nhip-hop, Chinese, instrumental\nhip-hop, Chinese, lo-fi\nhip-hop, Chinese, psychedelic\nhip-hop, Christmas, boom-bap\nhip-hop, Christmas, chiptune\nhip-hop, Christmas, early 2000s\nhip-hop, Christmas, novelty\nhip-hop, Creole, cinematic\nhip-hop, Cuban folk\nhip-hop, Cuban fusion\nhip-hop, Cuban, lo-fi\nhip-hop, Desi, 2000s\nhip-hop, Desi, boom-bap\nhip-hop, Desi, fusion\nhip-hop, Dutch rap, soul\nhip-hop, Dutch, novelty\nhip-hop, EDM\nhip-hop, EDM, Mandarin rap\nhip-hop, EDM, South Indian fusion\nhip-hop, EDM, big room\nhip-hop, EDM, chiptune\nhip-hop, EDM, cinematic\nhip-hop, EDM, dance-pop\nhip-hop, EDM, dubstep\nhip-hop, EDM, funk\nhip-hop, EDM, future bass\nhip-hop, EDM, hardstyle\nhip-hop, EDM, pop\nhip-hop, EDM, pop-R&B\nhip-hop, EDM, pop-rock\nhip-hop, EDM, progressive house\nhip-hop, EDM, trap\nhip-hop, EDM, trap-pop\nhip-hop, EDM, upbeat\nhip-hop, EDM-pop, cinematic\nhip-hop, EDM-trap\nhip-hop, East African\nhip-hop, East African, 2000s\nhip-hop, East African, club\nhip-hop, East Asian fusion\nhip-hop, East Asian, boom-bap\nhip-hop, East Asian, instrumental\nhip-hop, East Asian, modern\nhip-hop, East Asian, motivational\nhip-hop, East Coast, Punjabi hip-hop\nhip-hop, Eastern European\nhip-hop, Eastern European folk\nhip-hop, Eastern European pop\nhip-hop, Eastern European rap\nhip-hop, Eastern European, boom-bap\nhip-hop, Eastern European, folk\nhip-hop, Eastern European, lo-fi\nhip-hop, Eastern European, oud\nhip-hop, Eastern flavor\nhip-hop, Eastern fusion\nhip-hop, Eastern, experimental\nhip-hop, Eastern-influenced\nhip-hop, European folk\nhip-hop, Filipino hip-hop\nhip-hop, Filipino rap\nhip-hop, Filipino, trap\nhip-hop, Finnish, anthemic\nhip-hop, French R&B\nhip-hop, French hip-hop, R&B\nhip-hop, French rap, North African fusion\nhip-hop, French rap, electronic\nhip-hop, French rap, pop-R&B\nhip-hop, G-funk\nhip-hop, G-funk, 90s\nhip-hop, G-funk, Chicano soul\nhip-hop, G-funk, Latin\nhip-hop, G-funk, Portuguese pop\nhip-hop, G-funk, Punjabi\nhip-hop, G-funk, R&B\nhip-hop, G-funk, South African\nhip-hop, G-funk, Vietnamese rap\nhip-hop, G-funk, West Coast\nhip-hop, G-funk, acid jazz\nhip-hop, G-funk, big beat\nhip-hop, G-funk, bilingual\nhip-hop, G-funk, boom-bap\nhip-hop, G-funk, boom-bap, R&B, rock-rap\nhip-hop, G-funk, chiptune\nhip-hop, G-funk, cinematic\nhip-hop, G-funk, cloud rap\nhip-hop, G-funk, comedic\nhip-hop, G-funk, conscious hip-hop\nhip-hop, G-funk, electro-funk\nhip-hop, G-funk, funk\nhip-hop, G-funk, funk-rock\nhip-hop, G-funk, gangsta rap\nhip-hop, G-funk, live band\nhip-hop, G-funk, lo-fi\nhip-hop, G-funk, neo-soul\nhip-hop, G-funk, new jack swing\nhip-hop, G-funk, pop\nhip-hop, G-funk, pop-R&B\nhip-hop, G-funk, pop-funk\nhip-hop, G-funk, pop-rap\nhip-hop, G-funk, retro\nhip-hop, G-funk, retro funk\nhip-hop, G-funk, rock\nhip-hop, G-funk, soulful\nhip-hop, G-funk, synth-pop\nhip-hop, G-funk, trap\nhip-hop, G-funk, video game music\nhip-hop, G-funk, video game soundtrack\nhip-hop, German cabaret, neo-soul\nhip-hop, Greek folk\nhip-hop, Greek pop-rock\nhip-hop, Greek, aggressive\nhip-hop, Greek, funk\nhip-hop, Haryanvi folk\nhip-hop, Hawaiian, cinematic\nhip-hop, Hebrew folk\nhip-hop, Hindi pop, cinematic\nhip-hop, Indian classical\nhip-hop, Indian classical, Punjabi pop\nhip-hop, Indian classical, ambient\nhip-hop, Indian classical, boom-bap\nhip-hop, Indian classical, cinematic\nhip-hop, Indian classical, devotional\nhip-hop, Indian classical, electronic\nhip-hop, Indian classical, fusion\nhip-hop, Indian classical, lo-fi\nhip-hop, Indian classical, pop\nhip-hop, Indian classical, soul\nhip-hop, Indian devotional\nhip-hop, Indian devotional, lo-fi\nhip-hop, Indian film music\nhip-hop, Indian film music, breakbeat\nhip-hop, Indian flute, cinematic\nhip-hop, Indian folk\nhip-hop, Indian folk, electronic\nhip-hop, Indian folk, folk-pop\nhip-hop, Indian folk, lo-fi\nhip-hop, Indian fusion\nhip-hop, Indian fusion, 90s electronic\nhip-hop, Indian fusion, Middle Eastern\nhip-hop, Indian fusion, ambient\nhip-hop, Indian fusion, cinematic\nhip-hop, Indian fusion, lo-fi\nhip-hop, Indian fusion, soul\nhip-hop, Indian hip-hop\nhip-hop, Indian hip-hop, boom-bap\nhip-hop, Indian hip-hop, lo-fi\nhip-hop, Indian pop\nhip-hop, Indian pop, anthemic\nhip-hop, Indian pop, cinematic\nhip-hop, Indian pop, electronic\nhip-hop, Indian pop, funk\nhip-hop, Indian regional\nhip-hop, Indian, Middle Eastern\nhip-hop, Indian, boom-bap\nhip-hop, Indian, electronic\nhip-hop, Indian, melancholic\nhip-hop, Indonesian fusion\nhip-hop, Indonesian pop\nhip-hop, Irish folk\nhip-hop, Islamic devotional\nhip-hop, Israeli, late-90s\nhip-hop, Italian folk\nhip-hop, Italian hip-hop\nhip-hop, Italian rap\nhip-hop, Italian, party\nhip-hop, J-pop\nhip-hop, J-pop, C-pop\nhip-hop, J-pop, French rap\nhip-hop, J-pop, K-pop\nhip-hop, J-pop, acoustic\nhip-hop, J-pop, anime\nhip-hop, J-pop, boom-bap\nhip-hop, J-pop, chiptune\nhip-hop, J-pop, cinematic\nhip-hop, J-pop, electronic\nhip-hop, J-pop, folk\nhip-hop, J-pop, funk\nhip-hop, J-pop, hyperpop\nhip-hop, J-pop, new jack swing\nhip-hop, J-pop, trap\nhip-hop, J-pop, video game\nhip-hop, J-rock\nhip-hop, J-rock, anime\nhip-hop, J-rock, chiptune\nhip-hop, J-rock, electronic\nhip-hop, J-rock, lo-fi\nhip-hop, Japanese rap, turntablism\nhip-hop, Javanese, boom-bap\nhip-hop, Javanese, chiptune\nhip-hop, Javanese, lo-fi\nhip-hop, K-ballad, lo-fi\nhip-hop, K-pop\nhip-hop, K-pop, EDM\nhip-hop, K-pop, R&B\nhip-hop, K-pop, ambient\nhip-hop, K-pop, cinematic\nhip-hop, K-pop, dance-pop\nhip-hop, K-pop, lo-fi\nhip-hop, K-pop, old-school\nhip-hop, K-pop, rock\nhip-hop, K-rock, vaporwave\nhip-hop, Kannada rap, boom-bap\nhip-hop, Korean folk\nhip-hop, Kurdish, ambient\nhip-hop, Latin\nhip-hop, Latin R&B\nhip-hop, Latin ballad\nhip-hop, Latin ballad, experimental\nhip-hop, Latin cumbia\nhip-hop, Latin dance\nhip-hop, Latin folk\nhip-hop, Latin folk, boom-bap\nhip-hop, Latin folk, pop\nhip-hop, Latin freestyle\nhip-hop, Latin funk\nhip-hop, Latin fusion\nhip-hop, Latin groove, neo-soul\nhip-hop, Latin hip-hop\nhip-hop, Latin hip-hop, 2000s\nhip-hop, Latin hip-hop, R&B\nhip-hop, Latin hip-hop, aggressive\nhip-hop, Latin hip-hop, boom-bap\nhip-hop, Latin hip-hop, trap\nhip-hop, Latin house, tribal house\nhip-hop, Latin jazz\nhip-hop, Latin jazz, Afro-Cuban\nhip-hop, Latin pop\nhip-hop, Latin pop, R&B\nhip-hop, Latin pop, bilingual rap\nhip-hop, Latin pop, introspective\nhip-hop, Latin pop, soul\nhip-hop, Latin pop, summer vibes\nhip-hop, Latin rap\nhip-hop, Latin rap, cloud rap\nhip-hop, Latin rock\nhip-hop, Latin rock, cumbia\nhip-hop, Latin rumba\nhip-hop, Latin trap\nhip-hop, Latin trap, reggaeton\nhip-hop, Latin urban\nhip-hop, Latin, Afrobeat\nhip-hop, Latin, C-pop\nhip-hop, Latin, Caribbean\nhip-hop, Latin, Cuban\nhip-hop, Latin, G-funk\nhip-hop, Latin, J-pop\nhip-hop, Latin, Kizomba\nhip-hop, Latin, Malay rap\nhip-hop, Latin, Mandarin\nhip-hop, Latin, Moombahton\nhip-hop, Latin, R&B\nhip-hop, Latin, acoustic\nhip-hop, Latin, ambient\nhip-hop, Latin, beat\nhip-hop, Latin, bilingual\nhip-hop, Latin, boom-bap\nhip-hop, Latin, boombap\nhip-hop, Latin, chill\nhip-hop, Latin, cinematic\nhip-hop, Latin, club\nhip-hop, Latin, comedic\nhip-hop, Latin, dancehall\nhip-hop, Latin, dembow\nhip-hop, Latin, educational\nhip-hop, Latin, electronic\nhip-hop, Latin, experimental\nhip-hop, Latin, flamenco\nhip-hop, Latin, funk\nhip-hop, Latin, fusion\nhip-hop, Latin, indie rock\nhip-hop, Latin, instrumental\nhip-hop, Latin, jazz fusion\nhip-hop, Latin, jazzy\nhip-hop, Latin, lo-fi\nhip-hop, Latin, metal\nhip-hop, Latin, moody\nhip-hop, Latin, party\nhip-hop, Latin, pop-R&B\nhip-hop, Latin, quirky\nhip-hop, Latin, regional Mexican\nhip-hop, Latin, salsa\nhip-hop, Latin, soul\nhip-hop, Latin, tango\nhip-hop, Latin, trap\nhip-hop, Latin, world music\nhip-hop, Latin-influenced, soul\nhip-hop, Latin-pop\nhip-hop, MPB\nhip-hop, Malayalam, East Asian fusion\nhip-hop, Malayalam, ambient\nhip-hop, Malaysian fusion\nhip-hop, Mandopop\nhip-hop, Mandopop, festive\nhip-hop, Mandopop, lo-fi\nhip-hop, Mandopop, pop-rock\nhip-hop, Mediterranean folk\nhip-hop, Mediterranean fusion\nhip-hop, Mediterranean, Greek rap\nhip-hop, Mediterranean, Latin\nhip-hop, Mediterranean, ethereal\nhip-hop, Mediterranean, live\nhip-hop, Mediterranean, soul\nhip-hop, Mexican folk\nhip-hop, Miami freestyle\nhip-hop, Miami funk, new jack swing\nhip-hop, Middle Eastern\nhip-hop, Middle Eastern fusion\nhip-hop, Middle Eastern fusion, Balkan\nhip-hop, Middle Eastern fusion, R&B\nhip-hop, Middle Eastern fusion, cinematic\nhip-hop, Middle Eastern fusion, electronic\nhip-hop, Middle Eastern fusion, pop-rock\nhip-hop, Middle Eastern fusion, rock\nhip-hop, Middle Eastern fusion, trap\nhip-hop, Middle Eastern pop\nhip-hop, Middle Eastern synth, Russian rap\nhip-hop, Middle Eastern, Arabic rap\nhip-hop, Middle Eastern, Balkan\nhip-hop, Middle Eastern, Bollywood\nhip-hop, Middle Eastern, Central Asian\nhip-hop, Middle Eastern, Hebrew\nhip-hop, Middle Eastern, Indian fusion\nhip-hop, Middle Eastern, Latin\nhip-hop, Middle Eastern, North African\nhip-hop, Middle Eastern, Persian\nhip-hop, Middle Eastern, Persian rap\nhip-hop, Middle Eastern, Phrygian\nhip-hop, Middle Eastern, R&B\nhip-hop, Middle Eastern, South African\nhip-hop, Middle Eastern, South Asian\nhip-hop, Middle Eastern, Turkish\nhip-hop, Middle Eastern, Turkish fusion\nhip-hop, Middle Eastern, ambient\nhip-hop, Middle Eastern, anthemic\nhip-hop, Middle Eastern, atmospheric\nhip-hop, Middle Eastern, bilingual\nhip-hop, Middle Eastern, boom-bap\nhip-hop, Middle Eastern, chiptune\nhip-hop, Middle Eastern, cinematic\nhip-hop, Middle Eastern, classical Indian\nhip-hop, Middle Eastern, conscious rap\nhip-hop, Middle Eastern, dark\nhip-hop, Middle Eastern, electronic\nhip-hop, Middle Eastern, emotional\nhip-hop, Middle Eastern, ethereal\nhip-hop, Middle Eastern, experimental\nhip-hop, Middle Eastern, folk\nhip-hop, Middle Eastern, fusion\nhip-hop, Middle Eastern, instrumental\nhip-hop, Middle Eastern, introspective\nhip-hop, Middle Eastern, jazz\nhip-hop, Middle Eastern, lo-fi\nhip-hop, Middle Eastern, melancholic\nhip-hop, Middle Eastern, melodic\nhip-hop, Middle Eastern, microtonal\nhip-hop, Middle Eastern, modern\nhip-hop, Middle Eastern, oud\nhip-hop, Middle Eastern, political\nhip-hop, Middle Eastern, protest\nhip-hop, Middle Eastern, soul\nhip-hop, Middle Eastern, trap\nhip-hop, Middle Eastern, urban\nhip-hop, Middle Eastern, world fusion\nhip-hop, Mizrahi pop\nhip-hop, Mizrahi, electronic\nhip-hop, Mongolian folk, cinematic\nhip-hop, Mongolian rap, ambient\nhip-hop, Mongolian, playful\nhip-hop, Moroccan Arabic, acoustic\nhip-hop, Moroccan Arabic, cinematic\nhip-hop, Nepali pop\nhip-hop, Nepali pop, melodic hip-hop\nhip-hop, Nepali, boom-bap\nhip-hop, Nepali, cinematic\nhip-hop, Nepali, soul\nhip-hop, New Jack Swing\nhip-hop, New Jack Swing, 90s\nhip-hop, New Orleans, brass\nhip-hop, Nordic, ambient\nhip-hop, Norteño\nhip-hop, Norteño, accordion\nhip-hop, Norteño, cinematic\nhip-hop, North African\nhip-hop, North African folk\nhip-hop, North African fusion\nhip-hop, North African pop\nhip-hop, North African, Middle Eastern\nhip-hop, North African, ambient\nhip-hop, North African, anthemic\nhip-hop, North African, atmospheric\nhip-hop, North African, boom-bap\nhip-hop, North African, cinematic\nhip-hop, North African, electronic\nhip-hop, North African, funk\nhip-hop, North African, fusion\nhip-hop, North African, melancholic\nhip-hop, North African, melodic rap\nhip-hop, North African, modern\nhip-hop, North African, oud\nhip-hop, North African, percussion\nhip-hop, North African, traditional\nhip-hop, Persian rap, atmospheric\nhip-hop, Persian rap, boom-bap\nhip-hop, Persian, acoustic\nhip-hop, Persian, ambient\nhip-hop, Persian, boom-bap\nhip-hop, Persian, cinematic\nhip-hop, Persian, political\nhip-hop, Polish pop-rock\nhip-hop, Polynesian fusion\nhip-hop, Punjabi folk, boom-bap\nhip-hop, Punjabi folk, traditional Indian\nhip-hop, Punjabi fusion\nhip-hop, Punjabi pop\nhip-hop, Punjabi pop, Bhangra\nhip-hop, Punjabi rap\nhip-hop, Punjabi, Jamaican\nhip-hop, Punjabi, boom-bap\nhip-hop, Punjabi, electronic\nhip-hop, Punjabi, funk\nhip-hop, Punjabi, lo-fi\nhip-hop, Punjabi, synth-pop\nhip-hop, Punjabi, trap\nhip-hop, Quebecois rap\nhip-hop, R&B\nhip-hop, R&B, 90s style\nhip-hop, R&B, Afro fusion\nhip-hop, R&B, Afro-hop\nhip-hop, R&B, Afrobeat\nhip-hop, R&B, Afrobeats\nhip-hop, R&B, Afropop\nhip-hop, R&B, Arabic fusion\nhip-hop, R&B, Brazilian funk\nhip-hop, R&B, C-pop\nhip-hop, R&B, Chinese\nhip-hop, R&B, Chinese hip-hop\nhip-hop, R&B, Chinese pop\nhip-hop, R&B, Chinese urban\nhip-hop, R&B, French rap\nhip-hop, R&B, G-funk\nhip-hop, R&B, J-pop\nhip-hop, R&B, K-pop\nhip-hop, R&B, K-rap\nhip-hop, R&B, Latin\nhip-hop, R&B, Latin trap\nhip-hop, R&B, Mandopop\nhip-hop, R&B, Middle Eastern\nhip-hop, R&B, New Jack Swing\nhip-hop, R&B, North African\nhip-hop, R&B, Peking Opera\nhip-hop, R&B, Southern hip-hop\nhip-hop, R&B, Spanish\nhip-hop, R&B, Spanish folk\nhip-hop, R&B, Spanish-inflected\nhip-hop, R&B, Tamil hip-hop\nhip-hop, R&B, UK drill\nhip-hop, R&B, Vietnamese pop\nhip-hop, R&B, acoustic\nhip-hop, R&B, afrobeat\nhip-hop, R&B, ambient\nhip-hop, R&B, art-pop\nhip-hop, R&B, atmospheric\nhip-hop, R&B, bilingual\nhip-hop, R&B, boom-bap\nhip-hop, R&B, boom-bap, trap\nhip-hop, R&B, breakbeat\nhip-hop, R&B, chiptune\nhip-hop, R&B, chopped and screwed\nhip-hop, R&B, cinematic\nhip-hop, R&B, city pop\nhip-hop, R&B, cloud rap\nhip-hop, R&B, club\nhip-hop, R&B, conscious rap\nhip-hop, R&B, dancehall\nhip-hop, R&B, drum and bass\nhip-hop, R&B, dubstep\nhip-hop, R&B, early 2000s\nhip-hop, R&B, educational\nhip-hop, R&B, electronic\nhip-hop, R&B, festive\nhip-hop, R&B, funk\nhip-hop, R&B, future bass\nhip-hop, R&B, gospel\nhip-hop, R&B, hyperpop\nhip-hop, R&B, jazz fusion\nhip-hop, R&B, jazz-hop\nhip-hop, R&B, lo-fi\nhip-hop, R&B, melodic rap\nhip-hop, R&B, neo-soul\nhip-hop, R&B, new jack swing\nhip-hop, R&B, orchestral\nhip-hop, R&B, playful\nhip-hop, R&B, pop\nhip-hop, R&B, pop-rap\nhip-hop, R&B, pop-rock\nhip-hop, R&B, psychedelic\nhip-hop, R&B, ragtime\nhip-hop, R&B, reggaeton\nhip-hop, R&B, sad pop\nhip-hop, R&B, soul\nhip-hop, R&B, synth-pop\nhip-hop, R&B, synthwave\nhip-hop, R&B, trap\nhip-hop, R&B, trap soul\nhip-hop, R&B, trap-soul\nhip-hop, R&B, vaporwave\nhip-hop, R&B, world music\nhip-hop, Rai\nhip-hop, Rai, Latin pop\nhip-hop, Rai, North African fusion\nhip-hop, Rai, Spanish rap\nhip-hop, Rai, electronic\nhip-hop, Romanian rap, electronic\nhip-hop, Russian rap, funk\nhip-hop, Russian rap, lo-fi\nhip-hop, Russian, dancehall\nhip-hop, Scottish fusion\nhip-hop, Scottish fusion, trap\nhip-hop, Sinhala fusion\nhip-hop, South African\nhip-hop, South African, upbeat\nhip-hop, South Asian folk\nhip-hop, South Asian fusion\nhip-hop, South Asian pop\nhip-hop, South Asian, atmospheric\nhip-hop, South Asian, experimental\nhip-hop, South Asian, lo-fi\nhip-hop, South Asian, melodic\nhip-hop, South Asian, modern\nhip-hop, South Asian, trap\nhip-hop, South Indian dance music\nhip-hop, South Indian film music\nhip-hop, South Indian folk\nhip-hop, South Indian fusion\nhip-hop, South Indian pop\nhip-hop, South Indian pop, trap\nhip-hop, South Indian, Middle Eastern\nhip-hop, South Indian, R&B\nhip-hop, South Indian, boom-bap\nhip-hop, South Indian, cinematic\nhip-hop, South Indian, early 2000s\nhip-hop, South Indian, electronic\nhip-hop, South Indian, fusion\nhip-hop, South Indian, modern\nhip-hop, South Indian, trap\nhip-hop, South Indian, upbeat\nhip-hop, Southeast Asian folk\nhip-hop, Southeast Asian fusion\nhip-hop, Southeast Asian, lo-fi\nhip-hop, Southeast Asian, trap\nhip-hop, Spanish acoustic\nhip-hop, Spanish flavor\nhip-hop, Spanish folk\nhip-hop, Spanish folk, electronic\nhip-hop, Spanish folk, lo-fi\nhip-hop, Spanish hip-hop, boom-bap\nhip-hop, Spanish rap\nhip-hop, Spanish rap, boom-bap\nhip-hop, Spanish rap, lo-fi\nhip-hop, Spanish style\nhip-hop, Spanish, boom-bap\nhip-hop, Spanish, lo-fi\nhip-hop, Spanish-influenced, Russian rap\nhip-hop, Spanish-style, lo-fi\nhip-hop, Sundanese fusion\nhip-hop, Sundanese, ambient\nhip-hop, Sundanese, boom-bap\nhip-hop, Swedish, lo-fi\nhip-hop, Tamil film music, fusion\nhip-hop, Tamil fusion\nhip-hop, Tamil pop, Kuthu\nhip-hop, Tamil pop, R&B\nhip-hop, Tamil pop, cinematic\nhip-hop, Tamil pop, nu-metal\nhip-hop, Tamil rap\nhip-hop, Tamil rap, synthwave\nhip-hop, Tamil, cinematic\nhip-hop, Tamil, electronic\nhip-hop, Tamil, sitar\nhip-hop, Telugu, fusion\nhip-hop, Thai folk, cinematic\nhip-hop, Thai fusion\nhip-hop, Thai, modern\nhip-hop, Tibetan fusion\nhip-hop, Tibetan spiritual, ambient\nhip-hop, Turkish arabesque\nhip-hop, Turkish folk\nhip-hop, Turkish pop\nhip-hop, Turkish pop, R&B\nhip-hop, Turkish saz, Middle Eastern\nhip-hop, Turkish, Greek\nhip-hop, Turkish, cinematic\nhip-hop, Turkish, dancehall\nhip-hop, Turkish, lo-fi\nhip-hop, UK drill\nhip-hop, UK garage, electronic\nhip-hop, V-pop\nhip-hop, Vietnamese folk\nhip-hop, West African\nhip-hop, West African fusion\nhip-hop, West Coast, summer\nhip-hop, a cappella, boom-bap\nhip-hop, a cappella, cinematic\nhip-hop, accordion, European folk\nhip-hop, acid jazz\nhip-hop, acid jazz, boom-bap\nhip-hop, acid jazz, funk\nhip-hop, acid jazz, lo-fi\nhip-hop, acid jazz, lounge\nhip-hop, acid jazz, neo-soul\nhip-hop, acid jazz, trip-hop\nhip-hop, acoustic ballad, cinematic\nhip-hop, acoustic, cinematic\nhip-hop, acoustic, melancholic\nhip-hop, acoustic, world fusion\nhip-hop, afrobeat\nhip-hop, afrobeat, R&B\nhip-hop, afrobeat, dancehall\nhip-hop, afrobeat, trap\nhip-hop, afrobeats, dancehall\nhip-hop, afrobeats, r&b\nhip-hop, aggro, Afro-hip-hop\nhip-hop, alt-rock\nhip-hop, alternative R&B\nhip-hop, alternative pop-rock, cinematic\nhip-hop, alternative pop-rock, happy hardcore\nhip-hop, alternative rock\nhip-hop, alternative rock, Hebrew rap\nhip-hop, alternative rock, K-pop\nhip-hop, alternative rock, chiptune\nhip-hop, alternative rock, cinematic\nhip-hop, alternative rock, experimental\nhip-hop, alternative rock, lo-fi\nhip-hop, alternative rock, noise rap\nhip-hop, alternative rock, nu-metal\nhip-hop, alternative rock, piano ballad, nu-metal\nhip-hop, alternative rock, post-rock\nhip-hop, alternative rock, punk rock\nhip-hop, alternative rock, synth-pop\nhip-hop, ambient\nhip-hop, ambient, Afro fusion\nhip-hop, ambient, Arabic\nhip-hop, ambient, Arabic pop\nhip-hop, ambient, Arabic rap\nhip-hop, ambient, Bollywood\nhip-hop, ambient, C-pop\nhip-hop, ambient, Cantopop\nhip-hop, ambient, Chinese\nhip-hop, ambient, Chinese flute\nhip-hop, ambient, Chinese spoken word\nhip-hop, ambient, East Asian\nhip-hop, ambient, Eastern-influenced\nhip-hop, ambient, French pop\nhip-hop, ambient, Hindi soul\nhip-hop, ambient, Indian\nhip-hop, ambient, Indian classical\nhip-hop, ambient, Indian fusion\nhip-hop, ambient, Indian pop\nhip-hop, ambient, J-pop\nhip-hop, ambient, Japanese lo-fi\nhip-hop, ambient, Latin\nhip-hop, ambient, Marathi\nhip-hop, ambient, Nepali pop\nhip-hop, ambient, Nordic\nhip-hop, ambient, North African\nhip-hop, ambient, Persian\nhip-hop, ambient, Persian folk\nhip-hop, ambient, Persian rap\nhip-hop, ambient, Punjabi\nhip-hop, ambient, R&B\nhip-hop, ambient, South Asian\nhip-hop, ambient, South Asian folk\nhip-hop, ambient, Swahili rap\nhip-hop, ambient, Tamil\nhip-hop, ambient, Telugu\nhip-hop, ambient, Thai\nhip-hop, ambient, Thai pop\nhip-hop, ambient, Turkish\nhip-hop, ambient, Turkish folk\nhip-hop, ambient, academic\nhip-hop, ambient, ancient style\nhip-hop, ambient, bilingual\nhip-hop, ambient, blues\nhip-hop, ambient, breakcore\nhip-hop, ambient, chiptune\nhip-hop, ambient, choral\nhip-hop, ambient, cinematic\nhip-hop, ambient, classical\nhip-hop, ambient, cosmic\nhip-hop, ambient, dreamy\nhip-hop, ambient, dubstep\nhip-hop, ambient, electronic\nhip-hop, ambient, emotional\nhip-hop, ambient, ethereal\nhip-hop, ambient, ethnic\nhip-hop, ambient, experimental\nhip-hop, ambient, future bass\nhip-hop, ambient, future soul\nhip-hop, ambient, glitch\nhip-hop, ambient, gospel\nhip-hop, ambient, industrial\nhip-hop, ambient, introspective\nhip-hop, ambient, jazz\nhip-hop, ambient, lo-fi\nhip-hop, ambient, pop\nhip-hop, ambient, psychedelic\nhip-hop, ambient, reggae\nhip-hop, ambient, rock\nhip-hop, ambient, soul\nhip-hop, ambient, spiritual\nhip-hop, ambient, spoken word\nhip-hop, ambient, techno\nhip-hop, ambient, traditional\nhip-hop, ambient, traditional Asian\nhip-hop, ambient, traditional Central Asian\nhip-hop, ambient, traditional East Asian\nhip-hop, ambient, traditional Eastern\nhip-hop, ambient, traditional Indian\nhip-hop, ambient, traditional Japanese\nhip-hop, ambient, trap\nhip-hop, ambient, tribal\nhip-hop, ambient, trip-hop\nhip-hop, ambient, world fusion\nhip-hop, ambient, world music\nhip-hop, americana, blues\nhip-hop, ancient style, cinematic\nhip-hop, ancient style, fusion\nhip-hop, ancient style, lo-fi\nhip-hop, ancient style, trap\nhip-hop, anime soundtrack\nhip-hop, anime theme, lo-fi\nhip-hop, anime, cinematic\nhip-hop, anime, lo-fi\nhip-hop, anthemic, military\nhip-hop, anthemic, patriotic\nhip-hop, arabesque, melancholic\nhip-hop, atmospheric R&B\nhip-hop, atmospheric electronic\nhip-hop, atmospheric pop\nhip-hop, atmospheric pop-rap\nhip-hop, atmospheric, C-pop\nhip-hop, atmospheric, Greek\nhip-hop, atmospheric, Neapolitan\nhip-hop, atmospheric, R&B\nhip-hop, atmospheric, boom-bap\nhip-hop, atmospheric, cinematic\nhip-hop, atmospheric, dark\nhip-hop, atmospheric, electronic\nhip-hop, atmospheric, emotional\nhip-hop, atmospheric, introspective\nhip-hop, atmospheric, lo-fi\nhip-hop, atmospheric, melodic\nhip-hop, atmospheric, trap\nhip-hop, auto-tune, cinematic\nhip-hop, bagpipe, epic fusion\nhip-hop, ballad\nhip-hop, ballad, C-pop\nhip-hop, ballad, Mandarin pop\nhip-hop, ballad, ambient\nhip-hop, ballad, bilingual\nhip-hop, ballad, cinematic\nhip-hop, ballad, lo-fi\nhip-hop, ballroom, vogue\nhip-hop, baroque\nhip-hop, baroque pop\nhip-hop, baroque, Greek\nhip-hop, baroque, Greek rap\nhip-hop, baroque, Punjabi\nhip-hop, baroque, R&B\nhip-hop, baroque, Turkish rap\nhip-hop, baroque, bilingual\nhip-hop, baroque, cinematic\nhip-hop, baroque, dark ambient\nhip-hop, baroque, dark trap\nhip-hop, baroque, electronic\nhip-hop, baroque, fusion\nhip-hop, baroque, lo-fi\nhip-hop, baroque, operatic\nhip-hop, baroque, rock-opera\nhip-hop, baroque, trap\nhip-hop, bass house\nhip-hop, battle rap\nhip-hop, batucada, spoken word\nhip-hop, bhangra, Bollywood\nhip-hop, bhangra, pop\nhip-hop, bhangra, punjabi\nhip-hop, big band\nhip-hop, big band, Latin\nhip-hop, big band, funk\nhip-hop, big band, indie-pop\nhip-hop, big band, lo-fi\nhip-hop, big band, retro\nhip-hop, big band, swing\nhip-hop, big beat\nhip-hop, big beat, house\nhip-hop, big room house\nhip-hop, big-band, cinematic\nhip-hop, bilingual\nhip-hop, bilingual, Afrobeat\nhip-hop, bilingual, East Coast\nhip-hop, bilingual, boom-bap\nhip-hop, bilingual, chiptune\nhip-hop, bilingual, cinematic\nhip-hop, bilingual, club\nhip-hop, bilingual, electronic\nhip-hop, bilingual, ethereal\nhip-hop, bilingual, funk\nhip-hop, bilingual, lo-fi\nhip-hop, bilingual, raw\nhip-hop, bilingual, trap\nhip-hop, bluegrass, country\nhip-hop, blues\nhip-hop, blues, Greek folk\nhip-hop, blues, Japanese rap\nhip-hop, blues, R&B\nhip-hop, blues, cinematic\nhip-hop, blues, industrial\nhip-hop, blues, jazz\nhip-hop, blues, lo-fi\nhip-hop, blues, soul\nhip-hop, blues, southern rock\nhip-hop, blues-rock, Hebrew rap\nhip-hop, blues-rock, Latin rap\nhip-hop, blues-rock, cinematic\nhip-hop, blues-rock, soul\nhip-hop, blues-rock, trap\nhip-hop, bolero\nhip-hop, bolero, cinematic\nhip-hop, bolero, fusion\nhip-hop, bolero, jazz\nhip-hop, bolero, lo-fi\nhip-hop, boogie-woogie, C-pop\nhip-hop, boogie-woogie, Latin\nhip-hop, boogie-woogie, Quebecois rap\nhip-hop, boogie-woogie, eclectic\nhip-hop, boom bap, cinematic\nhip-hop, boom bap, reggaeton\nhip-hop, boom-bap\nhip-hop, boom-bap, Afro-Brazilian\nhip-hop, boom-bap, Afro-hip-hop\nhip-hop, boom-bap, Afro-hop\nhip-hop, boom-bap, Arabic hip-hop\nhip-hop, boom-bap, Arabic rap\nhip-hop, boom-bap, Asian fusion\nhip-hop, boom-bap, Balkan\nhip-hop, boom-bap, Brazilian\nhip-hop, boom-bap, C-pop\nhip-hop, boom-bap, Central Asian\nhip-hop, boom-bap, Chinese\nhip-hop, boom-bap, Chinese fusion\nhip-hop, boom-bap, Chinese hip-hop\nhip-hop, boom-bap, Chinese punk\nhip-hop, boom-bap, Chinese traditional\nhip-hop, boom-bap, Czech rap\nhip-hop, boom-bap, East Asian\nhip-hop, boom-bap, East Asian fusion\nhip-hop, boom-bap, East Coast\nhip-hop, boom-bap, East-meets-West\nhip-hop, boom-bap, Eastern European\nhip-hop, boom-bap, Eastern tonality\nhip-hop, boom-bap, Eastern-influenced\nhip-hop, boom-bap, French rap\nhip-hop, boom-bap, G-funk\nhip-hop, boom-bap, German hip-hop\nhip-hop, boom-bap, German rap\nhip-hop, boom-bap, Greek rap\nhip-hop, boom-bap, Hebrew rap\nhip-hop, boom-bap, Indian fusion\nhip-hop, boom-bap, Indian hip-hop\nhip-hop, boom-bap, Indonesian rap\nhip-hop, boom-bap, Italian rap\nhip-hop, boom-bap, Latin\nhip-hop, boom-bap, Latin hip-hop\nhip-hop, boom-bap, Latin rap\nhip-hop, boom-bap, Malay rap\nhip-hop, boom-bap, Mandarin rap\nhip-hop, boom-bap, Middle Eastern\nhip-hop, boom-bap, Middle Eastern fusion\nhip-hop, boom-bap, Middle Eastern hip-hop\nhip-hop, boom-bap, Middle Eastern synth\nhip-hop, boom-bap, Nigerian Pidgin\nhip-hop, boom-bap, North African\nhip-hop, boom-bap, Persian rap\nhip-hop, boom-bap, Punjabi\nhip-hop, boom-bap, Punjabi rap\nhip-hop, boom-bap, Quebecois\nhip-hop, boom-bap, R&B\nhip-hop, boom-bap, Russian rap\nhip-hop, boom-bap, Sinhala rap\nhip-hop, boom-bap, South African\nhip-hop, boom-bap, South African hip-hop\nhip-hop, boom-bap, South Asian fusion\nhip-hop, boom-bap, South Indian\nhip-hop, boom-bap, Spanish rap\nhip-hop, boom-bap, Tamil rap\nhip-hop, boom-bap, Turkish hip-hop\nhip-hop, boom-bap, Vietnamese rap\nhip-hop, boom-bap, aggro\nhip-hop, boom-bap, ambient\nhip-hop, boom-bap, atmospheric\nhip-hop, boom-bap, baroque hip-hop\nhip-hop, boom-bap, big band\nhip-hop, boom-bap, bilingual\nhip-hop, boom-bap, chiptune\nhip-hop, boom-bap, chopped and screwed\nhip-hop, boom-bap, cinematic\nhip-hop, boom-bap, comedic\nhip-hop, boom-bap, cross-cultural\nhip-hop, boom-bap, cypher\nhip-hop, boom-bap, dancehall\nhip-hop, boom-bap, dark\nhip-hop, boom-bap, dark trap\nhip-hop, boom-bap, disco-funk\nhip-hop, boom-bap, downtempo\nhip-hop, boom-bap, dubstep\nhip-hop, boom-bap, east coast\nhip-hop, boom-bap, electronic\nhip-hop, boom-bap, emotional\nhip-hop, boom-bap, experimental\nhip-hop, boom-bap, festive\nhip-hop, boom-bap, gangsta rap\nhip-hop, boom-bap, global hip-hop\nhip-hop, boom-bap, gospel\nhip-hop, boom-bap, gritty\nhip-hop, boom-bap, horrorcore\nhip-hop, boom-bap, indie-rock\nhip-hop, boom-bap, industrial\nhip-hop, boom-bap, jazz\nhip-hop, boom-bap, jazz hip-hop\nhip-hop, boom-bap, jazz rap\nhip-hop, boom-bap, jazzy\nhip-hop, boom-bap, jazzy hip-hop\nhip-hop, boom-bap, lo-fi\nhip-hop, boom-bap, multi-lingual\nhip-hop, boom-bap, multilingual\nhip-hop, boom-bap, orchestral hip-hop\nhip-hop, boom-bap, party\nhip-hop, boom-bap, political hip-hop\nhip-hop, boom-bap, political rap\nhip-hop, boom-bap, pop-R&B\nhip-hop, boom-bap, pop-rap\nhip-hop, boom-bap, posse cut\nhip-hop, boom-bap, protest\nhip-hop, boom-bap, rap\nhip-hop, boom-bap, reggae\nhip-hop, boom-bap, regional\nhip-hop, boom-bap, satirical\nhip-hop, boom-bap, soul\nhip-hop, boom-bap, soulful\nhip-hop, boom-bap, soulful R&B\nhip-hop, boom-bap, spoken word\nhip-hop, boom-bap, street rap\nhip-hop, boom-bap, taiko\nhip-hop, boom-bap, theatrical\nhip-hop, boom-bap, traditional fusion\nhip-hop, boom-bap, trap\nhip-hop, boom-bap, trip-hop\nhip-hop, boom-bap, turntablism\nhip-hop, boom-bap, underground\nhip-hop, boom-bap, urban\nhip-hop, boom-bap, video game\nhip-hop, boom-bap, world fusion\nhip-hop, boom-bap, world hip-hop\nhip-hop, boom-bap, world music\nhip-hop, bossa nova\nhip-hop, bossa nova, Mandarin rap\nhip-hop, bossa nova, latin\nhip-hop, bossa nova, narrative hip-hop\nhip-hop, bossa nova, samba\nhip-hop, brass band\nhip-hop, breakbeat\nhip-hop, breakcore\nhip-hop, breakcore, Middle Eastern\nhip-hop, breakcore, post-rock\nhip-hop, brostep, dubstep\nhip-hop, cabaret, dancehall\nhip-hop, chanson, ambient\nhip-hop, chill, Mandarin pop\nhip-hop, chillhop\nhip-hop, chillwave\nhip-hop, chillwave, G-funk\nhip-hop, chiptune\nhip-hop, chiptune, 8-bit\nhip-hop, chiptune, Afro-hip-hop\nhip-hop, chiptune, Afrobeat\nhip-hop, chiptune, Balkan\nhip-hop, chiptune, Bollywood\nhip-hop, chiptune, C-pop\nhip-hop, chiptune, Central Asian\nhip-hop, chiptune, French rap\nhip-hop, chiptune, G-funk\nhip-hop, chiptune, Greek rap\nhip-hop, chiptune, Haitian Creole\nhip-hop, chiptune, Haitian Creole rap\nhip-hop, chiptune, Haryanvi\nhip-hop, chiptune, Indian\nhip-hop, chiptune, Indian hip-hop\nhip-hop, chiptune, Indian pop\nhip-hop, chiptune, Indonesian rap\nhip-hop, chiptune, Italian rap\nhip-hop, chiptune, J-pop\nhip-hop, chiptune, K-pop\nhip-hop, chiptune, Latin\nhip-hop, chiptune, Latin hip-hop\nhip-hop, chiptune, Latin rap\nhip-hop, chiptune, Latin trap\nhip-hop, chiptune, Malayalam rap\nhip-hop, chiptune, Mandarin rap\nhip-hop, chiptune, Middle Eastern fusion\nhip-hop, chiptune, Nepali rap\nhip-hop, chiptune, Persian rap\nhip-hop, chiptune, R&B\nhip-hop, chiptune, Russian rap\nhip-hop, chiptune, South Indian\nhip-hop, chiptune, South Indian film music\nhip-hop, chiptune, Tagalog rap\nhip-hop, chiptune, Tamil fusion\nhip-hop, chiptune, Tamil rap\nhip-hop, chiptune, UK grime\nhip-hop, chiptune, aggressive\nhip-hop, chiptune, ambient\nhip-hop, chiptune, anime\nhip-hop, chiptune, ballad\nhip-hop, chiptune, baroque\nhip-hop, chiptune, bilingual\nhip-hop, chiptune, boom-bap\nhip-hop, chiptune, breakbeat\nhip-hop, chiptune, cantonese rap\nhip-hop, chiptune, cinematic\nhip-hop, chiptune, comedic\nhip-hop, chiptune, comedy\nhip-hop, chiptune, conscious hip-hop\nhip-hop, chiptune, crunk\nhip-hop, chiptune, dancehall\nhip-hop, chiptune, dark\nhip-hop, chiptune, dubstep\nhip-hop, chiptune, early 2000s\nhip-hop, chiptune, electro\nhip-hop, chiptune, electro-funk\nhip-hop, chiptune, electronic\nhip-hop, chiptune, emotional\nhip-hop, chiptune, funk\nhip-hop, chiptune, future bass\nhip-hop, chiptune, gamer\nhip-hop, chiptune, glitch-hop\nhip-hop, chiptune, gospel\nhip-hop, chiptune, horrorcore\nhip-hop, chiptune, hyperpop\nhip-hop, chiptune, industrial\nhip-hop, chiptune, inspirational\nhip-hop, chiptune, jazz\nhip-hop, chiptune, jazz rap\nhip-hop, chiptune, lo-fi\nhip-hop, chiptune, melodic\nhip-hop, chiptune, melodic rap\nhip-hop, chiptune, motivational\nhip-hop, chiptune, multilingual\nhip-hop, chiptune, nerdcore\nhip-hop, chiptune, nintendocore\nhip-hop, chiptune, novelty\nhip-hop, chiptune, nu-metal\nhip-hop, chiptune, party\nhip-hop, chiptune, pirate rap\nhip-hop, chiptune, playful\nhip-hop, chiptune, political\nhip-hop, chiptune, pop\nhip-hop, chiptune, pop-rap\nhip-hop, chiptune, protest\nhip-hop, chiptune, psychedelic\nhip-hop, chiptune, punk\nhip-hop, chiptune, rap-rock\nhip-hop, chiptune, reggae\nhip-hop, chiptune, reggaeton\nhip-hop, chiptune, retro\nhip-hop, chiptune, retro-futuristic\nhip-hop, chiptune, revolutionary\nhip-hop, chiptune, rock\nhip-hop, chiptune, romantic\nhip-hop, chiptune, sci-fi\nhip-hop, chiptune, soul\nhip-hop, chiptune, synth-pop\nhip-hop, chiptune, synthwave\nhip-hop, chiptune, trance\nhip-hop, chiptune, trap\nhip-hop, chiptune, turntablism\nhip-hop, chiptune, underground\nhip-hop, chiptune, upbeat\nhip-hop, chiptune, video game\nhip-hop, chiptune, video game music\nhip-hop, choral\nhip-hop, choral synth\nhip-hop, choral, Javanese\nhip-hop, choral, blues\nhip-hop, choral, boom-bap\nhip-hop, choral, cinematic\nhip-hop, choral, electric guitar\nhip-hop, choral, electronic\nhip-hop, choral, epic\nhip-hop, choral, pop\nhip-hop, choral, soul\nhip-hop, cinematic\nhip-hop, cinematic pop\nhip-hop, cinematic pop, wuxia\nhip-hop, cinematic rock\nhip-hop, cinematic rock, ambient\nhip-hop, cinematic, African\nhip-hop, cinematic, Afro fusion\nhip-hop, cinematic, Afro-hip-hop\nhip-hop, cinematic, Afrobeat\nhip-hop, cinematic, Arabic\nhip-hop, cinematic, Arabic fusion\nhip-hop, cinematic, Arabic rap\nhip-hop, cinematic, Asian fusion\nhip-hop, cinematic, Balkan\nhip-hop, cinematic, Balkan fusion\nhip-hop, cinematic, Bengali\nhip-hop, cinematic, Bollywood\nhip-hop, cinematic, Brazilian\nhip-hop, cinematic, British rap\nhip-hop, cinematic, C-pop\nhip-hop, cinematic, Central Asian\nhip-hop, cinematic, Chinese\nhip-hop, cinematic, Chinese flute\nhip-hop, cinematic, Chinese folk\nhip-hop, cinematic, Chinese fusion\nhip-hop, cinematic, Chinese opera\nhip-hop, cinematic, Chinese traditional\nhip-hop, cinematic, Czech rap\nhip-hop, cinematic, Dutch\nhip-hop, cinematic, Dutch rap\nhip-hop, cinematic, East Asian\nhip-hop, cinematic, East Asian fusion\nhip-hop, cinematic, Eastern\nhip-hop, cinematic, Eastern European\nhip-hop, cinematic, Eastern fusion\nhip-hop, cinematic, Eastern-Western fusion\nhip-hop, cinematic, Eastern-influenced\nhip-hop, cinematic, French Creole\nhip-hop, cinematic, French rap\nhip-hop, cinematic, French spoken word\nhip-hop, cinematic, G-funk\nhip-hop, cinematic, German rap\nhip-hop, cinematic, Greek\nhip-hop, cinematic, Greek rap\nhip-hop, cinematic, Haitian Creole\nhip-hop, cinematic, Hebrew rap\nhip-hop, cinematic, Hebrew vocal\nhip-hop, cinematic, Hindi rap\nhip-hop, cinematic, Indian\nhip-hop, cinematic, Indian classical\nhip-hop, cinematic, Indian film\nhip-hop, cinematic, Indian folk\nhip-hop, cinematic, Indian fusion\nhip-hop, cinematic, Indian hip-hop\nhip-hop, cinematic, Indian pop\nhip-hop, cinematic, Indonesian pop\nhip-hop, cinematic, Italian rap\nhip-hop, cinematic, K-hip-hop\nhip-hop, cinematic, K-pop\nhip-hop, cinematic, Khmer rap\nhip-hop, cinematic, Korean traditional\nhip-hop, cinematic, Latin\nhip-hop, cinematic, Latin folk\nhip-hop, cinematic, Malay rap\nhip-hop, cinematic, Mandarin\nhip-hop, cinematic, Mandarin rap\nhip-hop, cinematic, Marathi rap\nhip-hop, cinematic, Mediterranean\nhip-hop, cinematic, Middle Eastern\nhip-hop, cinematic, Māori\nhip-hop, cinematic, North African\nhip-hop, cinematic, Persian\nhip-hop, cinematic, Persian pop\nhip-hop, cinematic, Polish rap\nhip-hop, cinematic, Portuguese rap\nhip-hop, cinematic, Portuguese spoken word\nhip-hop, cinematic, Punjabi\nhip-hop, cinematic, R&B\nhip-hop, cinematic, Russian\nhip-hop, cinematic, Russian rap\nhip-hop, cinematic, Sinhala rap\nhip-hop, cinematic, Slavic folk\nhip-hop, cinematic, South Asian\nhip-hop, cinematic, South Asian fusion\nhip-hop, cinematic, South Indian\nhip-hop, cinematic, Soviet-era\nhip-hop, cinematic, Spanish\nhip-hop, cinematic, Spanish rap\nhip-hop, cinematic, Spanish-influenced\nhip-hop, cinematic, Swahili\nhip-hop, cinematic, Swahili rap\nhip-hop, cinematic, Swedish\nhip-hop, cinematic, Swiss German rap\nhip-hop, cinematic, Tamil\nhip-hop, cinematic, Tamil rap\nhip-hop, cinematic, Tibetan\nhip-hop, cinematic, Turkish folk\nhip-hop, cinematic, Turkish fusion\nhip-hop, cinematic, Turkish rap\nhip-hop, cinematic, Urdu rap\nhip-hop, cinematic, Zulu rap\nhip-hop, cinematic, ambient\nhip-hop, cinematic, ancient style\nhip-hop, cinematic, anime\nhip-hop, cinematic, anthemic\nhip-hop, cinematic, atmospheric\nhip-hop, cinematic, bagpipe\nhip-hop, cinematic, ballad\nhip-hop, cinematic, baroque\nhip-hop, cinematic, bilingual\nhip-hop, cinematic, blues-rock\nhip-hop, cinematic, boom-bap\nhip-hop, cinematic, brass\nhip-hop, cinematic, chiptune\nhip-hop, cinematic, chopped and screwed\nhip-hop, cinematic, choral\nhip-hop, cinematic, classical\nhip-hop, cinematic, classical fusion\nhip-hop, cinematic, dancehall\nhip-hop, cinematic, danish rap\nhip-hop, cinematic, dark\nhip-hop, cinematic, dark ambient\nhip-hop, cinematic, dark pop\nhip-hop, cinematic, dark trap\nhip-hop, cinematic, dramatic\nhip-hop, cinematic, dream pop\nhip-hop, cinematic, drum and bass\nhip-hop, cinematic, dystopian\nhip-hop, cinematic, electronic\nhip-hop, cinematic, emo\nhip-hop, cinematic, emotional\nhip-hop, cinematic, epic\nhip-hop, cinematic, erhu\nhip-hop, cinematic, ethereal\nhip-hop, cinematic, ethnic fusion\nhip-hop, cinematic, experimental\nhip-hop, cinematic, flamenco\nhip-hop, cinematic, folk\nhip-hop, cinematic, funk\nhip-hop, cinematic, fusion\nhip-hop, cinematic, future bass\nhip-hop, cinematic, futuristic\nhip-hop, cinematic, gospel\nhip-hop, cinematic, gothic\nhip-hop, cinematic, indigenous\nhip-hop, cinematic, industrial\nhip-hop, cinematic, inspirational\nhip-hop, cinematic, introspective\nhip-hop, cinematic, jazz\nhip-hop, cinematic, jazzy\nhip-hop, cinematic, klezmer\nhip-hop, cinematic, lo-fi\nhip-hop, cinematic, melancholic\nhip-hop, cinematic, melodic\nhip-hop, cinematic, microtonal\nhip-hop, cinematic, modern\nhip-hop, cinematic, motivational\nhip-hop, cinematic, multi-lingual\nhip-hop, cinematic, multilingual\nhip-hop, cinematic, new-age\nhip-hop, cinematic, noir\nhip-hop, cinematic, nostalgic\nhip-hop, cinematic, nu-metal\nhip-hop, cinematic, old-school\nhip-hop, cinematic, operatic\nhip-hop, cinematic, orchestral\nhip-hop, cinematic, oriental\nhip-hop, cinematic, patriotic\nhip-hop, cinematic, political\nhip-hop, cinematic, pop\nhip-hop, cinematic, pop-R&B\nhip-hop, cinematic, pop-punk\nhip-hop, cinematic, pop-rock\nhip-hop, cinematic, protest\nhip-hop, cinematic, psychedelic\nhip-hop, cinematic, rap battle\nhip-hop, cinematic, retro\nhip-hop, cinematic, retro game\nhip-hop, cinematic, revolutionary\nhip-hop, cinematic, rock\nhip-hop, cinematic, sci-fi\nhip-hop, cinematic, sentimental\nhip-hop, cinematic, soul\nhip-hop, cinematic, soulful\nhip-hop, cinematic, southern rap\nhip-hop, cinematic, spaghetti western\nhip-hop, cinematic, spiritual\nhip-hop, cinematic, synth\nhip-hop, cinematic, traditional\nhip-hop, cinematic, traditional Asian\nhip-hop, cinematic, traditional Chinese\nhip-hop, cinematic, traditional East Asian\nhip-hop, cinematic, traditional Korean\nhip-hop, cinematic, trap\nhip-hop, cinematic, tribal\nhip-hop, cinematic, underground\nhip-hop, cinematic, vaporwave\nhip-hop, cinematic, video game\nhip-hop, cinematic, vocal\nhip-hop, cinematic, world fusion\nhip-hop, cinematic, world music\nhip-hop, cinematic, wuxia\nhip-hop, circus, brass\nhip-hop, city pop\nhip-hop, city pop, 90s R&B\nhip-hop, city pop, R&B\nhip-hop, city pop, neo-soul\nhip-hop, city pop, nu-disco\nhip-hop, city pop, retro funk\nhip-hop, city pop, vaporwave\nhip-hop, city-pop\nhip-hop, city-pop, ambient\nhip-hop, city-pop, boom-bap\nhip-hop, classic rock\nhip-hop, classical crossover\nhip-hop, classical fusion\nhip-hop, classical guitar, Spanish influence\nhip-hop, classical, C-pop\nhip-hop, classical, Chinese rap\nhip-hop, classical, Dutch rap\nhip-hop, classical, Latin\nhip-hop, classical, Latin rap\nhip-hop, classical, Mediterranean\nhip-hop, classical, Punjabi\nhip-hop, classical, Spanish\nhip-hop, classical, ambient\nhip-hop, classical, bilingual\nhip-hop, classical, boom-bap\nhip-hop, classical, cinematic\nhip-hop, classical, dramatic\nhip-hop, classical, electronic\nhip-hop, classical, experimental\nhip-hop, classical, lo-fi\nhip-hop, classical, melancholic\nhip-hop, classical, nu-metal\nhip-hop, classical, rock\nhip-hop, classical, urban\nhip-hop, cloud rap\nhip-hop, cloud rap, lo-fi\nhip-hop, cloud rap, trap\nhip-hop, club, Sundanese\nhip-hop, club, bilingual\nhip-hop, club, dance\nhip-hop, club, early 2000s\nhip-hop, club, electronic\nhip-hop, club, hyperpop\nhip-hop, comedic, Indian\nhip-hop, comedic, Indonesian\nhip-hop, comedic, theatrical\nhip-hop, comedy, boom-bap\nhip-hop, comedy, experimental\nhip-hop, comedy, festive\nhip-hop, comedy, funk\nhip-hop, comedy, hardstyle\nhip-hop, comedy, punk\nhip-hop, comedy, satire\nhip-hop, complextro, dubstep\nhip-hop, conscious rap\nhip-hop, conscious rap, lo-fi\nhip-hop, cool jazz\nhip-hop, country-western, blues-rock\nhip-hop, crunk\nhip-hop, crunk, R&B\nhip-hop, crunk, chiptune\nhip-hop, crunk, dancehall\nhip-hop, crunk, snap\nhip-hop, cumbia\nhip-hop, cumbia, Latin\nhip-hop, cumbia, ambient\nhip-hop, cumbia, cinematic\nhip-hop, cumbia, lo-fi\nhip-hop, cumbia, polka\nhip-hop, cumbia, regional Mexican\nhip-hop, cumbia, synth pop\nhip-hop, cyber-noir\nhip-hop, cyberpunk, future bass\nhip-hop, cyberpunk, trap\nhip-hop, dance, Turkish\nhip-hop, dance, ethnic fusion\nhip-hop, dance-pop\nhip-hop, dance-pop, South Indian film music\nhip-hop, dance-pop, South Indian, Vietnamese\nhip-hop, dance-pop, Southeast Asian fusion\nhip-hop, dance-pop, children's\nhip-hop, dance-pop, early 2000s\nhip-hop, dance-pop, flamenco\nhip-hop, dancehall\nhip-hop, dancehall, 90s new jack swing\nhip-hop, dancehall, Arabic pop\nhip-hop, dancehall, C-pop\nhip-hop, dancehall, East African\nhip-hop, dancehall, Italian rap\nhip-hop, dancehall, Middle Eastern fusion\nhip-hop, dancehall, Punjabi\nhip-hop, dancehall, R&B\nhip-hop, dancehall, South Indian\nhip-hop, dancehall, South Indian film music\nhip-hop, dancehall, afro-trap\nhip-hop, dancehall, afrobeat\nhip-hop, dancehall, afrobeats\nhip-hop, dancehall, chiptune\nhip-hop, dancehall, cinematic\nhip-hop, dancehall, electronic\nhip-hop, dancehall, grime\nhip-hop, dancehall, hyperpop\nhip-hop, dancehall, lo-fi\nhip-hop, dancehall, moombahton\nhip-hop, dancehall, pop\nhip-hop, dancehall, pop-rap\nhip-hop, dancehall, reggae\nhip-hop, dancehall, reggaeton\nhip-hop, dancehall, trap\nhip-hop, dark ambient\nhip-hop, dark cinematic\nhip-hop, dark electronic\nhip-hop, dark pop\nhip-hop, dark pop, industrial\nhip-hop, dark soul, experimental\nhip-hop, dark trap\nhip-hop, deep house\nhip-hop, dembow, Arabic pop\nhip-hop, dembow, Balkan fusion\nhip-hop, dembow, Latin club\nhip-hop, dembow, lo-fi\nhip-hop, devotional, Indian fusion\nhip-hop, devotional, ambient\nhip-hop, devotional, pop\nhip-hop, disco, funk\nhip-hop, disco-funk, new jack swing\nhip-hop, dream pop\nhip-hop, dream pop, C-pop\nhip-hop, dream pop, Latin\nhip-hop, dream pop, R&B\nhip-hop, dream pop, Russian pop\nhip-hop, dream pop, ambient\nhip-hop, dream pop, electronic\nhip-hop, dream pop, trap\nhip-hop, dream-pop\nhip-hop, dream-pop, deep house\nhip-hop, dreamy R&B\nhip-hop, dreamy synth\nhip-hop, dreamy synth, ambient\nhip-hop, dreamy synth, cinematic\nhip-hop, dreamy, ambient\nhip-hop, dreamy, atmospheric\nhip-hop, dreamy, bilingual\nhip-hop, dreamy, boom-bap\nhip-hop, dreamy, cinematic\nhip-hop, dreamy, electronic\nhip-hop, dreamy, jazzy\nhip-hop, dreamy, lo-fi\nhip-hop, dreamy, melodic\nhip-hop, dreamy, modern\nhip-hop, dreamy, neo-soul\nhip-hop, dreamy, oriental\nhip-hop, dreamy, soulful\nhip-hop, drill\nhip-hop, drill, cinematic\nhip-hop, drill, lo-fi boom-bap\nhip-hop, drum and bass\nhip-hop, drum and bass, R&B\nhip-hop, drum and bass, cinematic\nhip-hop, drum and bass, electronic\nhip-hop, drum and bass, lo-fi\nhip-hop, drum and bass, soul\nhip-hop, dub, dancehall\nhip-hop, dub, reggae\nhip-hop, dubstep\nhip-hop, dubstep, C-pop\nhip-hop, dubstep, K-pop\nhip-hop, dubstep, Middle Eastern\nhip-hop, dubstep, ambient\nhip-hop, dubstep, bass\nhip-hop, dubstep, bass house\nhip-hop, dubstep, bass music\nhip-hop, dubstep, chiptune\nhip-hop, dubstep, cinematic\nhip-hop, dubstep, electronic\nhip-hop, dubstep, emotional\nhip-hop, dubstep, glitch\nhip-hop, dubstep, hardstyle\nhip-hop, dubstep, industrial\nhip-hop, dubstep, jazz lounge\nhip-hop, dubstep, lo-fi\nhip-hop, dubstep, metalcore\nhip-hop, dubstep, nu-metal\nhip-hop, dubstep, trap\nhip-hop, dubstep, trap metal\nhip-hop, dubstep, world music\nhip-hop, duduk, Arabic rap\nhip-hop, duduk, cinematic\nhip-hop, duduk, epic\nhip-hop, duduk, fusion\nhip-hop, duduk, soul\nhip-hop, early 2000s R&B\nhip-hop, early 2000s club\nhip-hop, educational, children's\nhip-hop, educational, funk\nhip-hop, educational, pop\nhip-hop, educational, retro electronic\nhip-hop, electro\nhip-hop, electro, EBM\nhip-hop, electro-funk\nhip-hop, electro-funk, new jack swing\nhip-hop, electro-funk, new wave\nhip-hop, electro-funk, retro\nhip-hop, electro-funk, retro-futuristic\nhip-hop, electro-funk, soul\nhip-hop, electro-house, R&B\nhip-hop, electro-house, ambient\nhip-hop, electro-house, dance-pop\nhip-hop, electro-house, pop\nhip-hop, electro-rock, dance-rock\nhip-hop, electronic\nhip-hop, electronic dance music\nhip-hop, electronic dance, Central Asian folk\nhip-hop, electronic dance, Indian folk\nhip-hop, electronic dance, Javanese fusion\nhip-hop, electronic dance, Malayalam rap\nhip-hop, electronic dance, South Asian folk\nhip-hop, electronic dance, South Asian fusion\nhip-hop, electronic dance, South Indian folk\nhip-hop, electronic funk, Indian classical\nhip-hop, electronic rock\nhip-hop, electronic, Afrobeat\nhip-hop, electronic, Arabic\nhip-hop, electronic, Arabic pop\nhip-hop, electronic, Asian fusion\nhip-hop, electronic, C-pop\nhip-hop, electronic, Chinese\nhip-hop, electronic, Dutch rap\nhip-hop, electronic, EBM\nhip-hop, electronic, Eastern\nhip-hop, electronic, Eastern fusion\nhip-hop, electronic, French pop\nhip-hop, electronic, French rap\nhip-hop, electronic, German rap\nhip-hop, electronic, Greek rap\nhip-hop, electronic, Hebrew rap\nhip-hop, electronic, Indian fusion\nhip-hop, electronic, Indian hip-hop\nhip-hop, electronic, J-pop\nhip-hop, electronic, K-pop\nhip-hop, electronic, Latin\nhip-hop, electronic, Middle Eastern\nhip-hop, electronic, Mongolian rap\nhip-hop, electronic, Māori hip-hop\nhip-hop, electronic, North African\nhip-hop, electronic, Polish rap\nhip-hop, electronic, R&B\nhip-hop, electronic, Russian rap\nhip-hop, electronic, South Asian\nhip-hop, electronic, South Asian fusion\nhip-hop, electronic, South Indian film music\nhip-hop, electronic, South Indian folk\nhip-hop, electronic, South Indian fusion\nhip-hop, electronic, Spanish-style\nhip-hop, electronic, Tamil folk\nhip-hop, electronic, Tamil fusion\nhip-hop, electronic, ambient\nhip-hop, electronic, anime\nhip-hop, electronic, big band\nhip-hop, electronic, bilingual\nhip-hop, electronic, blues-rock\nhip-hop, electronic, boom-bap\nhip-hop, electronic, chiptune\nhip-hop, electronic, cinematic\nhip-hop, electronic, club\nhip-hop, electronic, cyberpunk\nhip-hop, electronic, dance\nhip-hop, electronic, dancehall\nhip-hop, electronic, dark ambient\nhip-hop, electronic, digital hardcore\nhip-hop, electronic, dubstep\nhip-hop, electronic, dystopian\nhip-hop, electronic, emotional\nhip-hop, electronic, experimental\nhip-hop, electronic, folk fusion\nhip-hop, electronic, fusion\nhip-hop, electronic, futuristic\nhip-hop, electronic, glitch\nhip-hop, electronic, gospel\nhip-hop, electronic, horror\nhip-hop, electronic, live performance\nhip-hop, electronic, lo-fi\nhip-hop, electronic, melodic rap\nhip-hop, electronic, novelty\nhip-hop, electronic, pop\nhip-hop, electronic, pop-punk\nhip-hop, electronic, rock\nhip-hop, electronic, soul\nhip-hop, electronic, synthwave\nhip-hop, electronic, traditional percussion\nhip-hop, electronic, trance\nhip-hop, electronic, trap\nhip-hop, electronic, workout\nhip-hop, electronic, world fusion\nhip-hop, emo-rap, atmospheric\nhip-hop, emo-rap, dubstep\nhip-hop, emo-rock, chiptune\nhip-hop, emotional acoustic\nhip-hop, emotional ballad\nhip-hop, emotional pop, ambient\nhip-hop, emotional pop, cinematic\nhip-hop, emotional rap, synth-driven\nhip-hop, emotional, C-pop\nhip-hop, emotional, Chinese\nhip-hop, emotional, Tatar\nhip-hop, emotional, acoustic\nhip-hop, emotional, ambient\nhip-hop, emotional, bilingual\nhip-hop, emotional, cinematic\nhip-hop, emotional, modern\nhip-hop, emotional, trap\nhip-hop, epic pop-rock\nhip-hop, epic soundtrack\nhip-hop, epic, Malay rap\nhip-hop, epic, Russian\nhip-hop, epic, ancient style\nhip-hop, epic, choral\nhip-hop, epic, cinematic\nhip-hop, epic, duduk\nhip-hop, epic, operatic\nhip-hop, epic, spiritual\nhip-hop, epic, synth-driven\nhip-hop, erhu, introspective\nhip-hop, ethereal\nhip-hop, ethereal pop\nhip-hop, ethereal, Afrofusion\nhip-hop, ethereal, Arabic pop\nhip-hop, ethereal, C-pop\nhip-hop, ethereal, Greek hip-hop\nhip-hop, ethereal, Greek rap\nhip-hop, ethereal, Middle Eastern\nhip-hop, ethereal, ambient\nhip-hop, ethereal, boom-bap\nhip-hop, ethereal, cinematic\nhip-hop, ethereal, dark pop\nhip-hop, ethereal, dark soul\nhip-hop, ethereal, hopeful\nhip-hop, ethereal, introspective\nhip-hop, ethereal, lo-fi\nhip-hop, ethereal, melancholic\nhip-hop, ethereal, vocal\nhip-hop, ethereal, world fusion\nhip-hop, ethnic fusion\nhip-hop, ethnic fusion, cinematic\nhip-hop, ethnic fusion, lo-fi\nhip-hop, ethnic, trap\nhip-hop, eurodance\nhip-hop, eurodance, 2000s\nhip-hop, eurodance, rock\nhip-hop, eurodance, trance\nhip-hop, experimental electronic\nhip-hop, experimental trap\nhip-hop, experimental, Indian hip-hop\nhip-hop, experimental, K-pop\nhip-hop, experimental, R&B\nhip-hop, experimental, ambient\nhip-hop, experimental, cinematic\nhip-hop, experimental, electronic\nhip-hop, experimental, lo-fi\nhip-hop, experimental, spoken word\nhip-hop, festive, Christmas\nhip-hop, festive, South African\nhip-hop, festive, boom-bap\nhip-hop, festive, chiptune\nhip-hop, festive, cinematic\nhip-hop, festive, early 2000s\nhip-hop, festive, funk\nhip-hop, festive, melodic\nhip-hop, festive, multi-lingual\nhip-hop, festive, ragtime\nhip-hop, festive, retro\nhip-hop, festive, satirical\nhip-hop, festive, trap\nhip-hop, film noir, boom-bap\nhip-hop, flamenco\nhip-hop, flamenco fusion\nhip-hop, flamenco hip-hop\nhip-hop, flamenco, Afrobeat\nhip-hop, flamenco, Andalusian\nhip-hop, flamenco, Arabic\nhip-hop, flamenco, Arabic rap\nhip-hop, flamenco, C-pop\nhip-hop, flamenco, French pop\nhip-hop, flamenco, Latin\nhip-hop, flamenco, Latin pop\nhip-hop, flamenco, Mediterranean\nhip-hop, flamenco, Persian\nhip-hop, flamenco, Portuguese\nhip-hop, flamenco, R&B\nhip-hop, flamenco, Spanish\nhip-hop, flamenco, Thai rap\nhip-hop, flamenco, ambient\nhip-hop, flamenco, bilingual\nhip-hop, flamenco, blues\nhip-hop, flamenco, boom-bap\nhip-hop, flamenco, choral\nhip-hop, flamenco, cinematic\nhip-hop, flamenco, downtempo\nhip-hop, flamenco, electronic\nhip-hop, flamenco, folk\nhip-hop, flamenco, lo-fi\nhip-hop, flamenco, melancholic\nhip-hop, flamenco, pop\nhip-hop, flamenco, pop-rock\nhip-hop, flamenco, quirky\nhip-hop, flamenco, reggae\nhip-hop, flamenco, revolutionary\nhip-hop, flamenco, soul\nhip-hop, flamenco, trap\nhip-hop, folk fusion\nhip-hop, folk fusion, Anatolian\nhip-hop, folk fusion, Central Asian\nhip-hop, folk fusion, Middle Eastern\nhip-hop, folk fusion, Russian\nhip-hop, folk fusion, South Asian\nhip-hop, folk fusion, Southeast Asian\nhip-hop, folk fusion, cinematic\nhip-hop, folk fusion, trap\nhip-hop, folk, Balkan\nhip-hop, folk, C-pop\nhip-hop, folk, Cajun\nhip-hop, folk, Central Asian\nhip-hop, folk, Eastern European\nhip-hop, folk, German\nhip-hop, folk, Hebrew rap\nhip-hop, folk, Klezmer\nhip-hop, folk, Latin\nhip-hop, folk, Middle Eastern\nhip-hop, folk, Nepali\nhip-hop, folk, Slavic\nhip-hop, folk, South Asian\nhip-hop, folk, South Asian fusion\nhip-hop, folk, Southeast Asian\nhip-hop, folk, accordion\nhip-hop, folk, ambient\nhip-hop, folk, atmospheric\nhip-hop, folk, boom-bap\nhip-hop, folk, cabaret\nhip-hop, folk, choral\nhip-hop, folk, cinematic\nhip-hop, folk, classical\nhip-hop, folk, duduk\nhip-hop, folk, electronic\nhip-hop, folk, electronic dance\nhip-hop, folk, emotional\nhip-hop, folk, epic\nhip-hop, folk, experimental\nhip-hop, folk, fusion\nhip-hop, folk, lo-fi\nhip-hop, folk, melancholic\nhip-hop, folk, operatic\nhip-hop, folk, patriotic\nhip-hop, folk, polka\nhip-hop, folk, sea shanty\nhip-hop, folk, soul\nhip-hop, folk, tango\nhip-hop, folk, trap\nhip-hop, folk, tribal\nhip-hop, folk, world music\nhip-hop, folk-dance, lo-fi\nhip-hop, folk-infused, boom-bap\nhip-hop, folk-pop, festive\nhip-hop, folk-pop, world music\nhip-hop, folk-rock, cinematic\nhip-hop, football chant\nhip-hop, free jazz\nhip-hop, freestyle, underground\nhip-hop, funk, 90s new jack swing\nhip-hop, funk, Afrobeat\nhip-hop, funk, Estonian\nhip-hop, funk, G-funk\nhip-hop, funk, Javanese rap\nhip-hop, funk, Jewish hip-hop\nhip-hop, funk, K-hip-hop\nhip-hop, funk, Latin\nhip-hop, funk, Middle Eastern\nhip-hop, funk, Russian\nhip-hop, funk, South Asian\nhip-hop, funk, bilingual\nhip-hop, funk, boom-bap\nhip-hop, funk, chiptune\nhip-hop, funk, city pop\nhip-hop, funk, disco\nhip-hop, funk, educational\nhip-hop, funk, electro\nhip-hop, funk, electronic\nhip-hop, funk, horrorcore\nhip-hop, funk, house\nhip-hop, funk, jazz\nhip-hop, funk, live band\nhip-hop, funk, lo-fi\nhip-hop, funk, motivational\nhip-hop, funk, multi-lingual\nhip-hop, funk, neo-soul\nhip-hop, funk, new jack swing\nhip-hop, funk, novelty\nhip-hop, funk, orchestral\nhip-hop, funk, pop\nhip-hop, funk, retro\nhip-hop, funk, satirical\nhip-hop, funk, soul\nhip-hop, funk, trap\nhip-hop, funk, world music\nhip-hop, funk-metal\nhip-hop, funk-rap\nhip-hop, funk-rap, new jack swing\nhip-hop, funk-rock\nhip-hop, funk-rock, ambient\nhip-hop, funk-rock, klezmer\nhip-hop, funk-rock, nu-metal\nhip-hop, funk-rock, spoken word\nhip-hop, funk-soul, gospel\nhip-hop, fusion, Indian\nhip-hop, fusion, South Asian\nhip-hop, fusion, Telugu\nhip-hop, fusion, cinematic\nhip-hop, fusion, electronic\nhip-hop, fusion, world\nhip-hop, fusion, world beat\nhip-hop, future bass\nhip-hop, future bass, R&B\nhip-hop, future bass, ambient\nhip-hop, future bass, cinematic\nhip-hop, future bass, electronic pop\nhip-hop, future bass, hyperpop\nhip-hop, future bass, jazz\nhip-hop, future bass, lo-fi\nhip-hop, future bass, pop\nhip-hop, future bass, pop-R&B\nhip-hop, future bass, rock\nhip-hop, future bass, soul\nhip-hop, future bass, trap\nhip-hop, futuristic, boom-bap\nhip-hop, futuristic, cinematic\nhip-hop, futuristic, sci-fi\nhip-hop, g-funk, chiptune\nhip-hop, gamelan, Javanese\nhip-hop, gamelan, world fusion\nhip-hop, gangsta rap\nhip-hop, gangsta, party\nhip-hop, ghazal, ambient\nhip-hop, glitch\nhip-hop, glitch hop, dubstep\nhip-hop, glitch, Italian rap\nhip-hop, glitch, ambient\nhip-hop, glitch, dark pop\nhip-hop, glitch, electronic\nhip-hop, glitch, experimental\nhip-hop, glitch, lo-fi\nhip-hop, glitch, nu-metal\nhip-hop, glitch, ragtime\nhip-hop, glitch, trap\nhip-hop, glitch-hop\nhip-hop, glitch-hop, R&B\nhip-hop, glitch-hop, breakcore\nhip-hop, glitch-hop, cinematic\nhip-hop, glitch-hop, lo-fi\nhip-hop, global fusion\nhip-hop, global, boom-bap\nhip-hop, gospel, Afrobeat\nhip-hop, gospel, C-pop\nhip-hop, gospel, Chinese rap\nhip-hop, gospel, Latin\nhip-hop, gospel, Latin rap\nhip-hop, gospel, R&B\nhip-hop, gospel, Zulu\nhip-hop, gospel, ambient\nhip-hop, gospel, blues\nhip-hop, gospel, boom-bap\nhip-hop, gospel, chiptune\nhip-hop, gospel, cinematic\nhip-hop, gospel, dark soul\nhip-hop, gospel, electronic\nhip-hop, gospel, industrial\nhip-hop, gospel, introspective\nhip-hop, gospel, lo-fi\nhip-hop, gospel, operatic\nhip-hop, gospel, pop\nhip-hop, gospel, psychedelic\nhip-hop, gospel, reggae\nhip-hop, gospel, soul\nhip-hop, gospel, trap\nhip-hop, gothic rock, dark synth\nhip-hop, gothic, ambient\nhip-hop, grime\nhip-hop, guzheng, Chinese\nhip-hop, guzheng, boom-bap\nhip-hop, guzheng, cinematic\nhip-hop, gypsy jazz, klezmer\nhip-hop, happy hardcore\nhip-hop, hardcore punk\nhip-hop, hardcore, beatboxing\nhip-hop, hardstyle\nhip-hop, hardstyle, ambient\nhip-hop, hardstyle, big room house\nhip-hop, hardstyle, chiptune\nhip-hop, hardstyle, cinematic\nhip-hop, hardstyle, dubstep\nhip-hop, hardstyle, electronic\nhip-hop, hardstyle, gabber\nhip-hop, hardstyle, industrial techno\nhip-hop, hardstyle, psytrance\nhip-hop, hardstyle, trap\nhip-hop, heartland rock, cinematic\nhip-hop, horror, cinematic\nhip-hop, horror, theatrical\nhip-hop, horrorcore, cinematic\nhip-hop, horrorcore, lo-fi\nhip-hop, house\nhip-hop, house, East Coast\nhip-hop, hyperpop\nhip-hop, hyperpop, R&B\nhip-hop, hyperpop, soul\nhip-hop, indie folk\nhip-hop, indie rock\nhip-hop, indie rock, C-pop\nhip-hop, indie rock, Italian rap\nhip-hop, indie rock, cinematic\nhip-hop, indie rock, conscious hip-hop\nhip-hop, indie rock, punk\nhip-hop, indie, world fusion\nhip-hop, indie-pop\nhip-hop, indie-pop, C-pop\nhip-hop, indie-rock\nhip-hop, industrial metal, cinematic\nhip-hop, industrial rock\nhip-hop, industrial rock, cinematic\nhip-hop, industrial, ambient\nhip-hop, industrial, atmospheric\nhip-hop, industrial, cinematic\nhip-hop, industrial, glitch\nhip-hop, industrial, lo-fi\nhip-hop, industrial, nu-metal\nhip-hop, industrial, psychedelic\nhip-hop, industrial, taiko\nhip-hop, industrial, trap\nhip-hop, inspirational R&B\nhip-hop, inspirational pop-rock\nhip-hop, introspective\nhip-hop, jazz\nhip-hop, jazz fusion\nhip-hop, jazz fusion, cinematic\nhip-hop, jazz fusion, electronic\nhip-hop, jazz fusion, world music\nhip-hop, jazz lounge\nhip-hop, jazz rap\nhip-hop, jazz rap, Cantonese hip-hop\nhip-hop, jazz rap, R&B\nhip-hop, jazz rap, boom-bap\nhip-hop, jazz rap, grime\nhip-hop, jazz rap, lo-fi\nhip-hop, jazz rap, neo-soul\nhip-hop, jazz, Arabic rap\nhip-hop, jazz, C-pop\nhip-hop, jazz, Catalan rap\nhip-hop, jazz, K-pop\nhip-hop, jazz, Kannada rap\nhip-hop, jazz, Latin\nhip-hop, jazz, Mediterranean\nhip-hop, jazz, Middle Eastern\nhip-hop, jazz, Punjabi\nhip-hop, jazz, R&B\nhip-hop, jazz, Sinhala rap\nhip-hop, jazz, ambient\nhip-hop, jazz, avant-garde\nhip-hop, jazz, big band\nhip-hop, jazz, bilingual\nhip-hop, jazz, boom-bap\nhip-hop, jazz, cinematic\nhip-hop, jazz, dreamy\nhip-hop, jazz, electronic\nhip-hop, jazz, emotional\nhip-hop, jazz, ethereal\nhip-hop, jazz, experimental\nhip-hop, jazz, film noir\nhip-hop, jazz, funk\nhip-hop, jazz, funk-rock\nhip-hop, jazz, groove\nhip-hop, jazz, klezmer\nhip-hop, jazz, lo-fi\nhip-hop, jazz, lounge\nhip-hop, jazz, melancholic\nhip-hop, jazz, noir\nhip-hop, jazz, nu-disco\nhip-hop, jazz, operatic\nhip-hop, jazz, pop-R&B\nhip-hop, jazz, psychedelic\nhip-hop, jazz, ragtime\nhip-hop, jazz, reggae\nhip-hop, jazz, sci-fi\nhip-hop, jazz, soul\nhip-hop, jazz, spoken word\nhip-hop, jazz, world music\nhip-hop, jazz-funk, cinematic\nhip-hop, jazz-funk, lo-fi\nhip-hop, jazz-fusion, experimental\nhip-hop, jazz-hop\nhip-hop, jazz-hop, neo-soul\nhip-hop, jazz-rap, soul\nhip-hop, jazzy boom-bap, bilingual\nhip-hop, jazzy boom-bap, experimental\nhip-hop, jazzy hip-hop, South Asian fusion\nhip-hop, jazzy, Afrobeat\nhip-hop, jazzy, Mandarin rap\nhip-hop, jazzy, R&B\nhip-hop, jazzy, bilingual\nhip-hop, jazzy, boom-bap\nhip-hop, jazzy, introspective\nhip-hop, jazzy, lo-fi\nhip-hop, jazzy, melancholic\nhip-hop, jazzy, soulful\nhip-hop, jazzy, trap\nhip-hop, klezmer\nhip-hop, klezmer fusion, electronic\nhip-hop, klezmer, German rap\nhip-hop, klezmer, Polish\nhip-hop, klezmer, R&B\nhip-hop, klezmer, Russian rap\nhip-hop, klezmer, balkan folk\nhip-hop, klezmer, boom-bap\nhip-hop, klezmer, cinematic\nhip-hop, klezmer, electronic\nhip-hop, klezmer, emotional\nhip-hop, klezmer, folk\nhip-hop, klezmer, fusion\nhip-hop, klezmer, gospel\nhip-hop, klezmer, party\nhip-hop, klezmer, playful\nhip-hop, klezmer, polka\nhip-hop, klezmer, soul\nhip-hop, klezmer, spoken word\nhip-hop, klezmer, swing\nhip-hop, klezmer, trap\nhip-hop, kuthu, fusion\nhip-hop, liturgical, blues-rock\nhip-hop, liturgical, electronic\nhip-hop, liturgical, rock\nhip-hop, lo-fi\nhip-hop, lo-fi boom-bap\nhip-hop, lo-fi hip hop\nhip-hop, lo-fi hip hop, dream-pop\nhip-hop, lo-fi hip hop, trap\nhip-hop, lo-fi hip-hop\nhip-hop, lo-fi, 90s vibe\nhip-hop, lo-fi, Afrobeat\nhip-hop, lo-fi, Arabic\nhip-hop, lo-fi, Arabic fusion\nhip-hop, lo-fi, Arabic hip-hop\nhip-hop, lo-fi, C-pop\nhip-hop, lo-fi, Cantonese rap\nhip-hop, lo-fi, Catalan rap\nhip-hop, lo-fi, Chinese\nhip-hop, lo-fi, Chinese fusion\nhip-hop, lo-fi, Chinese hip-hop\nhip-hop, lo-fi, Chinese pop\nhip-hop, lo-fi, Chinese rap\nhip-hop, lo-fi, Chinese traditional\nhip-hop, lo-fi, Dutch rap\nhip-hop, lo-fi, East Asian\nhip-hop, lo-fi, East Asian fusion\nhip-hop, lo-fi, Eastern\nhip-hop, lo-fi, Eastern European\nhip-hop, lo-fi, Eastern influence\nhip-hop, lo-fi, French rap\nhip-hop, lo-fi, G-funk\nhip-hop, lo-fi, Greek folk\nhip-hop, lo-fi, Hebrew\nhip-hop, lo-fi, Indian\nhip-hop, lo-fi, Indian classical\nhip-hop, lo-fi, Indian fusion\nhip-hop, lo-fi, Indian hip-hop\nhip-hop, lo-fi, Italian hip-hop\nhip-hop, lo-fi, Japanese\nhip-hop, lo-fi, K-pop\nhip-hop, lo-fi, Kazakh rap\nhip-hop, lo-fi, Latin\nhip-hop, lo-fi, Latin folk\nhip-hop, lo-fi, Latin pop\nhip-hop, lo-fi, Polish rap\nhip-hop, lo-fi, Punjabi\nhip-hop, lo-fi, R&B\nhip-hop, lo-fi, Romanian\nhip-hop, lo-fi, Sinhala\nhip-hop, lo-fi, South Asian\nhip-hop, lo-fi, Spanish\nhip-hop, lo-fi, Spanish bolero\nhip-hop, lo-fi, Spanish flavor\nhip-hop, lo-fi, Spanish rap\nhip-hop, lo-fi, afrobeat\nhip-hop, lo-fi, ambient\nhip-hop, lo-fi, ancient style\nhip-hop, lo-fi, anime\nhip-hop, lo-fi, atmospheric\nhip-hop, lo-fi, bedroom pop\nhip-hop, lo-fi, bilingual\nhip-hop, lo-fi, boom-bap\nhip-hop, lo-fi, cartoon\nhip-hop, lo-fi, chiptune\nhip-hop, lo-fi, cinematic\nhip-hop, lo-fi, cloud rap\nhip-hop, lo-fi, contemporary\nhip-hop, lo-fi, dark trap\nhip-hop, lo-fi, dream-pop\nhip-hop, lo-fi, electronic\nhip-hop, lo-fi, emotional\nhip-hop, lo-fi, ethereal\nhip-hop, lo-fi, ethnic fusion\nhip-hop, lo-fi, experimental\nhip-hop, lo-fi, funk\nhip-hop, lo-fi, gangsta rap\nhip-hop, lo-fi, hyperpop\nhip-hop, lo-fi, indie\nhip-hop, lo-fi, indie pop\nhip-hop, lo-fi, indie-pop\nhip-hop, lo-fi, introspective\nhip-hop, lo-fi, jazz\nhip-hop, lo-fi, jazz rap\nhip-hop, lo-fi, jazzy\nhip-hop, lo-fi, koto\nhip-hop, lo-fi, lounge\nhip-hop, lo-fi, medieval\nhip-hop, lo-fi, melancholic\nhip-hop, lo-fi, moombahton\nhip-hop, lo-fi, motivational\nhip-hop, lo-fi, party\nhip-hop, lo-fi, pop-R&B\nhip-hop, lo-fi, pop-infused\nhip-hop, lo-fi, pop-rap\nhip-hop, lo-fi, psychedelic\nhip-hop, lo-fi, punk rap\nhip-hop, lo-fi, quirky\nhip-hop, lo-fi, reggae\nhip-hop, lo-fi, rock\nhip-hop, lo-fi, romantic\nhip-hop, lo-fi, soul\nhip-hop, lo-fi, soulful R&B\nhip-hop, lo-fi, spoken word\nhip-hop, lo-fi, stoner\nhip-hop, lo-fi, synth pop\nhip-hop, lo-fi, synthwave\nhip-hop, lo-fi, trap\nhip-hop, lo-fi, underground\nhip-hop, lo-fi, vaporwave\nhip-hop, lo-fi, world fusion\nhip-hop, lo-fi, world music\nhip-hop, lounge\nhip-hop, luk thung, blues-rock\nhip-hop, mariachi\nhip-hop, mariachi, Latin\nhip-hop, mariachi, party\nhip-hop, medieval, lo-fi\nhip-hop, melancholic, C-pop\nhip-hop, melancholic, Central Asian\nhip-hop, melancholic, Chinese\nhip-hop, melancholic, Chinese MC\nhip-hop, melancholic, Indian\nhip-hop, melancholic, Italian\nhip-hop, melancholic, bilingual\nhip-hop, melancholic, cinematic\nhip-hop, melancholic, classical\nhip-hop, melancholic, trap\nhip-hop, melodic hip-hop\nhip-hop, melodic hip-hop, C-pop\nhip-hop, melodic hip-hop, bilingual\nhip-hop, melodic pop, Spanish flavor\nhip-hop, melodic rap, Middle Eastern fusion\nhip-hop, melodic, boom-bap\nhip-hop, melodic, multi-lingual\nhip-hop, meme, trap\nhip-hop, metalcore\nhip-hop, metalcore, chiptune\nhip-hop, microtonal, Arabic\nhip-hop, microtonal, Balkan\nhip-hop, microtonal, Eastern European\nhip-hop, microtonal, Middle Eastern\nhip-hop, microtonal, cinematic\nhip-hop, microtonal, soul\nhip-hop, minimal electronic\nhip-hop, modern, South Asian\nhip-hop, moombahton\nhip-hop, moombahton, latin\nhip-hop, multi-lingual\nhip-hop, musical theater\nhip-hop, mystical, cinematic\nhip-hop, neo-soul\nhip-hop, neo-soul, French chanson\nhip-hop, neo-soul, G-funk\nhip-hop, neo-soul, Latin\nhip-hop, neo-soul, Latin rap\nhip-hop, neo-soul, Middle Eastern\nhip-hop, neo-soul, R&B\nhip-hop, neo-soul, Swedish hip-hop\nhip-hop, neo-soul, UK garage\nhip-hop, neo-soul, acid jazz\nhip-hop, neo-soul, ambient\nhip-hop, neo-soul, boom-bap\nhip-hop, neo-soul, chillhop\nhip-hop, neo-soul, cinematic\nhip-hop, neo-soul, city pop\nhip-hop, neo-soul, classical\nhip-hop, neo-soul, dreamy\nhip-hop, neo-soul, dreamy R&B\nhip-hop, neo-soul, experimental\nhip-hop, neo-soul, funk\nhip-hop, neo-soul, gospel\nhip-hop, neo-soul, jazz\nhip-hop, neo-soul, jazz fusion\nhip-hop, neo-soul, jazz rap\nhip-hop, neo-soul, jazz-funk\nhip-hop, neo-soul, jazz-rap\nhip-hop, neo-soul, lo-fi\nhip-hop, neo-soul, lo-fi hip-hop\nhip-hop, neo-soul, lounge\nhip-hop, neo-soul, psychedelic\nhip-hop, neo-soul, psychedelic rock\nhip-hop, neo-soul, reggae\nhip-hop, neo-soul, trip-hop\nhip-hop, neo-soul, vaporwave\nhip-hop, nerdcore, electronic\nhip-hop, neurofunk drum & bass\nhip-hop, neurofunk, drum and bass\nhip-hop, new jack swing\nhip-hop, new jack swing, 90s style\nhip-hop, new jack swing, Christmas\nhip-hop, new jack swing, French rap\nhip-hop, new jack swing, Miami funk\nhip-hop, new jack swing, R&B\nhip-hop, new jack swing, breakbeat\nhip-hop, new jack swing, city pop\nhip-hop, new jack swing, comedic\nhip-hop, new jack swing, dance\nhip-hop, new jack swing, educational\nhip-hop, new jack swing, funk\nhip-hop, new jack swing, g-funk\nhip-hop, new jack swing, hip-house\nhip-hop, new jack swing, pop-rap\nhip-hop, new jack swing, retro\nhip-hop, new jack swing, synthwave\nhip-hop, new jack swing, upbeat\nhip-hop, new wave\nhip-hop, ney flute, Turkish\nhip-hop, ney flute, Turkish poetry\nhip-hop, ney flute, boom-bap\nhip-hop, ney, Arabic\nhip-hop, noir, cinematic\nhip-hop, noir, lo-fi\nhip-hop, noir-jazz\nhip-hop, noir-jazz, boom-bap\nhip-hop, noise rock, psychedelic rock\nhip-hop, norteño\nhip-hop, norteño, polka\nhip-hop, novelty rap\nhip-hop, novelty, theatrical\nhip-hop, nu-jazz, boom-bap\nhip-hop, nu-metal\nhip-hop, nu-metal, C-pop\nhip-hop, nu-metal, Christian rock\nhip-hop, nu-metal, German rap\nhip-hop, nu-metal, Mediterranean\nhip-hop, nu-metal, Māori protest\nhip-hop, nu-metal, R&B\nhip-hop, nu-metal, alternative\nhip-hop, nu-metal, alternative rock\nhip-hop, nu-metal, ambient\nhip-hop, nu-metal, atmospheric\nhip-hop, nu-metal, boom-bap\nhip-hop, nu-metal, chiptune\nhip-hop, nu-metal, cinematic\nhip-hop, nu-metal, classical\nhip-hop, nu-metal, electronic\nhip-hop, nu-metal, electronic rock\nhip-hop, nu-metal, electronic, experimental\nhip-hop, nu-metal, emotional\nhip-hop, nu-metal, experimental\nhip-hop, nu-metal, funk\nhip-hop, nu-metal, hard rock\nhip-hop, nu-metal, industrial\nhip-hop, nu-metal, industrial rock\nhip-hop, nu-metal, lo-fi\nhip-hop, nu-metal, orchestral\nhip-hop, nu-metal, pop-punk\nhip-hop, nu-metal, rap-metal\nhip-hop, nu-metal, rap-rock\nhip-hop, nu-metal, rock\nhip-hop, nu-metal, symphonic rock\nhip-hop, nu-metal, synthwave\nhip-hop, nu-metal, vaporwave\nhip-hop, old-school, G-funk\nhip-hop, old-school, bilingual\nhip-hop, old-school, educational\nhip-hop, old-school, new jack swing\nhip-hop, oompah, Balkan brass\nhip-hop, oompah, electronic\nhip-hop, operatic\nhip-hop, operatic, boom-bap\nhip-hop, operatic, cinematic\nhip-hop, operatic, rock\nhip-hop, orchestral\nhip-hop, orchestral, Arabic\nhip-hop, orchestral, C-pop\nhip-hop, orchestral, French rap\nhip-hop, orchestral, Latin\nhip-hop, orchestral, Middle Eastern\nhip-hop, orchestral, R&B\nhip-hop, orchestral, anime\nhip-hop, orchestral, battle rap\nhip-hop, orchestral, boom-bap\nhip-hop, orchestral, cinematic\nhip-hop, orchestral, dubstep\nhip-hop, orchestral, emotional\nhip-hop, orchestral, industrial\nhip-hop, orchestral, lo-fi\nhip-hop, orchestral, music box\nhip-hop, orchestral, pop-R&B\nhip-hop, orchestral, protest\nhip-hop, orchestral, rock\nhip-hop, orchestral, soul\nhip-hop, orchestral, trap\nhip-hop, orchestral, underground\nhip-hop, orchestral, urban\nhip-hop, oud fusion, Middle Eastern\nhip-hop, oud fusion, electronic\nhip-hop, oud, Balkan\nhip-hop, oud, Mediterranean\nhip-hop, oud, Middle Eastern\nhip-hop, oud, North African\nhip-hop, oud, Russian\nhip-hop, oud, Turkish\nhip-hop, oud, ambient\nhip-hop, oud, atmospheric\nhip-hop, oud, boom-bap\nhip-hop, oud, cinematic\nhip-hop, oud, dark ambient\nhip-hop, oud, fusion\nhip-hop, oud, soul\nhip-hop, oud, spiritual\nhip-hop, oud, taqsim\nhip-hop, oud, trap\nhip-hop, oud, urban\nhip-hop, oud, world fusion\nhip-hop, party rap, R&B\nhip-hop, party rock\nhip-hop, party, Latin R&B\nhip-hop, party, bilingual\nhip-hop, party, electronic\nhip-hop, party, funk\nhip-hop, patriotic, cinematic\nhip-hop, patriotic, melodic\nhip-hop, piano ballad\nhip-hop, pirate rap\nhip-hop, playful\nhip-hop, playful, cinematic\nhip-hop, playful, quirky\nhip-hop, political hip-hop\nhip-hop, political hip-hop, boom-bap\nhip-hop, political rap, Arabic hip-hop\nhip-hop, political rap, boom-bap\nhip-hop, polka, Mandarin rap\nhip-hop, polka, Schlager\nhip-hop, polka, tango\nhip-hop, pop\nhip-hop, pop ballad\nhip-hop, pop, C-pop\nhip-hop, pop, Chinese urban\nhip-hop, pop, EDM\nhip-hop, pop, Filipino\nhip-hop, pop, Hebrew rap\nhip-hop, pop, Indian classical\nhip-hop, pop, Indian fusion\nhip-hop, pop, Mandarin rap\nhip-hop, pop, Middle Eastern\nhip-hop, pop, North African\nhip-hop, pop, Punjabi\nhip-hop, pop, R&B\nhip-hop, pop, South Asian fusion\nhip-hop, pop, South Indian film music\nhip-hop, pop, Tibetan\nhip-hop, pop, afrobeat\nhip-hop, pop, ambient\nhip-hop, pop, bilingual\nhip-hop, pop, cartoon\nhip-hop, pop, chiptune\nhip-hop, pop, cinematic\nhip-hop, pop, devotional\nhip-hop, pop, electronic\nhip-hop, pop, emotional\nhip-hop, pop, folk\nhip-hop, pop, gospel\nhip-hop, pop, kuthu\nhip-hop, pop, lo-fi\nhip-hop, pop, synthwave\nhip-hop, pop, trance\nhip-hop, pop, trap\nhip-hop, pop, world music\nhip-hop, pop-R&B\nhip-hop, pop-R&B, Chinese\nhip-hop, pop-R&B, Middle Eastern\nhip-hop, pop-R&B, Spanish style\nhip-hop, pop-R&B, a cappella\nhip-hop, pop-R&B, ambient\nhip-hop, pop-R&B, atmospheric\nhip-hop, pop-R&B, bilingual\nhip-hop, pop-R&B, chiptune\nhip-hop, pop-R&B, cinematic\nhip-hop, pop-R&B, classical\nhip-hop, pop-R&B, dream-pop\nhip-hop, pop-R&B, future bass\nhip-hop, pop-R&B, lo-fi\nhip-hop, pop-R&B, pop-rock\nhip-hop, pop-R&B, trap\nhip-hop, pop-R&B, vaporwave\nhip-hop, pop-ballad, cinematic\nhip-hop, pop-ballad, emo\nhip-hop, pop-punk\nhip-hop, pop-punk, alternative rock\nhip-hop, pop-punk, ambient\nhip-hop, pop-punk, chiptune\nhip-hop, pop-punk, cinematic\nhip-hop, pop-punk, emo-rap\nhip-hop, pop-punk, emo-rock\nhip-hop, pop-punk, nu-metal\nhip-hop, pop-punk, rock opera\nhip-hop, pop-punk, satirical\nhip-hop, pop-punk, trap metal\nhip-hop, pop-r&b\nhip-hop, pop-rap\nhip-hop, pop-rap, East Asian fusion\nhip-hop, pop-rap, Nepali\nhip-hop, pop-rap, R&B\nhip-hop, pop-rap, atmospheric\nhip-hop, pop-rap, atmospheric rock\nhip-hop, pop-rap, cinematic\nhip-hop, pop-rap, cinematic rock\nhip-hop, pop-rap, early 2000s\nhip-hop, pop-rap, early 2000s Israeli\nhip-hop, pop-rap, educational\nhip-hop, pop-rap, ethereal\nhip-hop, pop-rap, future bass\nhip-hop, pop-rap, psychedelic\nhip-hop, pop-rock\nhip-hop, pop-rock, C-pop\nhip-hop, pop-rock, EDM\nhip-hop, pop-rock, Eastern European\nhip-hop, pop-rock, K-pop\nhip-hop, pop-rock, Latin\nhip-hop, pop-rock, R&B\nhip-hop, pop-rock, Russian pop\nhip-hop, pop-rock, Russian rap\nhip-hop, pop-rock, Vocaloid\nhip-hop, pop-rock, acoustic\nhip-hop, pop-rock, ambient\nhip-hop, pop-rock, atmospheric\nhip-hop, pop-rock, ballad\nhip-hop, pop-rock, blues-rock\nhip-hop, pop-rock, cinematic\nhip-hop, pop-rock, dream pop\nhip-hop, pop-rock, dubstep\nhip-hop, pop-rock, educational\nhip-hop, pop-rock, electronic\nhip-hop, pop-rock, emotional\nhip-hop, pop-rock, emotional ballad\nhip-hop, pop-rock, flamenco\nhip-hop, pop-rock, future bass\nhip-hop, pop-rock, glitch\nhip-hop, pop-rock, gospel\nhip-hop, pop-rock, hyperpop\nhip-hop, pop-rock, lo-fi\nhip-hop, pop-rock, melancholic\nhip-hop, pop-rock, nu-metal\nhip-hop, pop-rock, soul\nhip-hop, pop-rock, spoken word\nhip-hop, pop-rock, trap\nhip-hop, pop-rock, vaporwave\nhip-hop, pop/R&B\nhip-hop, pop/R&B, C-pop\nhip-hop, pop/R&B, Chinese\nhip-hop, post-rock, metal\nhip-hop, power ballad, cinematic\nhip-hop, power ballad, funk pop\nhip-hop, protest music\nhip-hop, protest, Arabic rap\nhip-hop, protest, Middle Eastern\nhip-hop, protest, ambient\nhip-hop, protest, boom-bap\nhip-hop, protest, cinematic\nhip-hop, protest, classical fusion\nhip-hop, protest, folkloric\nhip-hop, psychedelic\nhip-hop, psychedelic R&B\nhip-hop, psychedelic funk, French rap\nhip-hop, psychedelic rock\nhip-hop, psychedelic rock, R&B\nhip-hop, psychedelic rock, nu-metal\nhip-hop, psychedelic soul\nhip-hop, psychedelic, Greek rap\nhip-hop, psychedelic, K-pop\nhip-hop, psychedelic, Latin\nhip-hop, psychedelic, Middle Eastern\nhip-hop, psychedelic, R&B\nhip-hop, psychedelic, Tamil rap\nhip-hop, psychedelic, ambient\nhip-hop, psychedelic, ancient style\nhip-hop, psychedelic, blues\nhip-hop, psychedelic, boom-bap\nhip-hop, psychedelic, cinematic\nhip-hop, psychedelic, classical\nhip-hop, psychedelic, emotional\nhip-hop, psychedelic, experimental\nhip-hop, psychedelic, funk\nhip-hop, psychedelic, jazz\nhip-hop, psychedelic, lo-fi\nhip-hop, psychedelic, rock\nhip-hop, psychedelic, sci-fi\nhip-hop, psychedelic, shoegaze\nhip-hop, psychedelic, soul\nhip-hop, psychedelic, soulful\nhip-hop, psychedelic, trap\nhip-hop, punk rock\nhip-hop, quirky pop\nhip-hop, quirky, Chinese dialect\nhip-hop, quirky, J-pop\nhip-hop, ragtime\nhip-hop, ragtime, C-pop\nhip-hop, ragtime, Indian hip-hop\nhip-hop, ragtime, Russian hip-hop\nhip-hop, ragtime, Russian rap\nhip-hop, ragtime, educational\nhip-hop, ragtime, electronic\nhip-hop, ragtime, experimental\nhip-hop, ragtime, gothic\nhip-hop, ragtime, jazz\nhip-hop, ragtime, lo-fi\nhip-hop, ragtime, playful\nhip-hop, ragtime, theatrical\nhip-hop, ragtime, trap\nhip-hop, ragtime, video game\nhip-hop, rap-rock\nhip-hop, rap-rock, French\nhip-hop, rap-rock, Latin\nhip-hop, rap-rock, atmospheric\nhip-hop, rap-rock, cinematic\nhip-hop, rap-rock, electronic\nhip-hop, rap-rock, lo-fi\nhip-hop, rap-rock, nu-metal\nhip-hop, rap-rock, underground\nhip-hop, raï, French rap\nhip-hop, raï, electronic\nhip-hop, reggae\nhip-hop, reggae fusion\nhip-hop, reggae fusion, global beat\nhip-hop, reggae, Latin\nhip-hop, reggae, Portuguese hip-hop\nhip-hop, reggae, boom-bap\nhip-hop, reggae, cinematic\nhip-hop, reggae, dancehall\nhip-hop, reggae, dub\nhip-hop, reggae, electronic\nhip-hop, reggae, folk\nhip-hop, reggae, hip-house\nhip-hop, reggae, lo-fi\nhip-hop, reggae, spoken word\nhip-hop, reggaeton\nhip-hop, reggaeton, Latin\nhip-hop, reggaeton, Middle Eastern\nhip-hop, reggaeton, North African\nhip-hop, reggaeton, Swedish\nhip-hop, reggaeton, chiptune\nhip-hop, reggaeton, cinematic\nhip-hop, reggaeton, club\nhip-hop, reggaeton, comedic\nhip-hop, reggaeton, dancehall\nhip-hop, reggaeton, electronic\nhip-hop, reggaeton, soul\nhip-hop, reggaeton, vaporwave\nhip-hop, regional Mexican\nhip-hop, regional Mexican, ranchera\nhip-hop, retro electro\nhip-hop, retro electronic\nhip-hop, retro funk, new jack swing\nhip-hop, retro synth, Afrobeat\nhip-hop, retro synth, Chinese rap\nhip-hop, retro synth, bilingual\nhip-hop, retro synth, boom-bap\nhip-hop, retro synth, trap\nhip-hop, retro, Cantonese\nhip-hop, retro, South African\nhip-hop, retro, brass\nhip-hop, retro, chiptune\nhip-hop, retro, cinematic\nhip-hop, retro, dance-pop\nhip-hop, retro, electronic\nhip-hop, retro, funk\nhip-hop, retro, motivational\nhip-hop, retro, new jack swing\nhip-hop, retro, party\nhip-hop, retro, pop\nhip-hop, retro, synth\nhip-hop, retro, video game\nhip-hop, retro-funk, chiptune\nhip-hop, retro-funk, empowering\nhip-hop, retro-futuristic, bilingual\nhip-hop, retro-rave\nhip-hop, ritual ambient\nhip-hop, rock\nhip-hop, rock opera\nhip-hop, rock, C-pop\nhip-hop, rock, Greek\nhip-hop, rock, Hebrew vocal\nhip-hop, rock, Italian rap\nhip-hop, rock, Mediterranean\nhip-hop, rock, Middle Eastern\nhip-hop, rock, Swedish rap\nhip-hop, rock, Swiss-German\nhip-hop, rock, Turkish fusion\nhip-hop, rock, ambient\nhip-hop, rock, ballad\nhip-hop, rock, cinematic\nhip-hop, rock, classical\nhip-hop, rock, dubstep\nhip-hop, rock, electronic\nhip-hop, rock, emotional\nhip-hop, rock, lo-fi\nhip-hop, rock, protest\nhip-hop, rock, psychedelic\nhip-hop, rock, traditional East Asian\nhip-hop, rock, traditional Southeast Asian\nhip-hop, rock, world fusion\nhip-hop, rock-opera, baroque\nhip-hop, sacred, cinematic\nhip-hop, salsa, lo-fi\nhip-hop, samba, cinematic\nhip-hop, satirical, Christmas\nhip-hop, sci-fi\nhip-hop, sci-fi horror\nhip-hop, sci-fi, ambient\nhip-hop, sci-fi, atmospheric\nhip-hop, sci-fi, boom-bap\nhip-hop, sci-fi, chiptune\nhip-hop, sci-fi, cinematic\nhip-hop, sci-fi, conspiratorial\nhip-hop, sci-fi, electronic\nhip-hop, sci-fi, experimental\nhip-hop, sci-fi, lo-fi\nhip-hop, sea shanty, fusion\nhip-hop, sea shanty, violin\nhip-hop, second-line, brass\nhip-hop, second-line, funk\nhip-hop, sentimental, Chinese\nhip-hop, sentimental, Chinese MC\nhip-hop, shoegaze\nhip-hop, shoegaze, electronic\nhip-hop, shoegaze, lo-fi\nhip-hop, shoegaze, pop-R&B\nhip-hop, sitar, fusion\nhip-hop, slap house, electronic\nhip-hop, soul\nhip-hop, soul, 90s boom-bap\nhip-hop, soul, Afro-Latin\nhip-hop, soul, Afro-Portuguese\nhip-hop, soul, Afro-hip-hop\nhip-hop, soul, Afrobeat\nhip-hop, soul, Arabic hip-hop\nhip-hop, soul, Balkan\nhip-hop, soul, Brazilian\nhip-hop, soul, C-pop\nhip-hop, soul, Christmas\nhip-hop, soul, Czech rap\nhip-hop, soul, Eastern European\nhip-hop, soul, Filipino\nhip-hop, soul, French rap\nhip-hop, soul, Haitian Creole\nhip-hop, soul, Italian rap\nhip-hop, soul, K-rap\nhip-hop, soul, Latin pop\nhip-hop, soul, Latin rap\nhip-hop, soul, Middle Eastern\nhip-hop, soul, Moroccan Arabic\nhip-hop, soul, R&B\nhip-hop, soul, Spanish\nhip-hop, soul, Zulu rap\nhip-hop, soul, acoustic\nhip-hop, soul, ambient\nhip-hop, soul, atmospheric\nhip-hop, soul, ballad\nhip-hop, soul, bilingual\nhip-hop, soul, blues-rock\nhip-hop, soul, boom-bap\nhip-hop, soul, cinematic\nhip-hop, soul, classic rock\nhip-hop, soul, classical\nhip-hop, soul, classical fusion\nhip-hop, soul, comedy\nhip-hop, soul, doo-wop\nhip-hop, soul, dreamy\nhip-hop, soul, electronic\nhip-hop, soul, experimental\nhip-hop, soul, flamenco\nhip-hop, soul, folk\nhip-hop, soul, funk\nhip-hop, soul, gospel\nhip-hop, soul, indie-pop\nhip-hop, soul, jazz\nhip-hop, soul, jazzy\nhip-hop, soul, lo-fi\nhip-hop, soul, noir\nhip-hop, soul, orchestral\nhip-hop, soul, pop\nhip-hop, soul, power ballad\nhip-hop, soul, psychedelic\nhip-hop, soul, psychedelic jazz\nhip-hop, soul, rock\nhip-hop, soul, spiritual\nhip-hop, soul, trap\nhip-hop, soul, urban\nhip-hop, soul, world fusion\nhip-hop, soul, world music\nhip-hop, soul-jazz, French rap\nhip-hop, soulful\nhip-hop, soulful R&B\nhip-hop, soulful R&B, lo-fi\nhip-hop, soulful R&B, world music\nhip-hop, soulful pop\nhip-hop, soulful pop, cinematic\nhip-hop, soulful, bilingual\nhip-hop, soulful, cinematic\nhip-hop, soulful, hyperpop\nhip-hop, soulful, introspective\nhip-hop, soulful, trap\nhip-hop, southern rock\nhip-hop, spacey, cinematic\nhip-hop, spiritual, ambient\nhip-hop, spiritual, choral\nhip-hop, spiritual, folk\nhip-hop, spiritual, lo-fi\nhip-hop, spiritual, trap\nhip-hop, spiritual, world fusion\nhip-hop, spoken word, soul\nhip-hop, sports anthem\nhip-hop, spy theme\nhip-hop, spy theme, lo-fi\nhip-hop, stadium rock\nhip-hop, surf-rock, bilingual\nhip-hop, swing, French rap\nhip-hop, swing, pop\nhip-hop, symphonic metal\nhip-hop, symphonic rock, cinematic\nhip-hop, synth pop, urban\nhip-hop, synth rock, ambient\nhip-hop, synth, German rap\nhip-hop, synth-funk, new jack swing\nhip-hop, synth-pop\nhip-hop, synth-pop, 80s\nhip-hop, synth-pop, 90s\nhip-hop, synth-pop, C-pop\nhip-hop, synth-pop, J-pop\nhip-hop, synth-pop, K-pop\nhip-hop, synth-pop, chiptune\nhip-hop, synth-pop, cyber-pop\nhip-hop, synth-pop, electronic\nhip-hop, synth-pop, glitch\nhip-hop, synth-pop, lo-fi\nhip-hop, synth-pop, mashup\nhip-hop, synth-pop, pop-rock\nhip-hop, synth-pop, trap\nhip-hop, synth-pop, vaporwave\nhip-hop, synthwave\nhip-hop, synthwave, Polish rap\nhip-hop, synthwave, R&B\nhip-hop, synthwave, West Coast\nhip-hop, synthwave, boom-bap\nhip-hop, synthwave, chiptune\nhip-hop, synthwave, cinematic\nhip-hop, synthwave, electronic\nhip-hop, synthwave, experimental\nhip-hop, synthwave, lo-fi\nhip-hop, synthwave, pop-rap\nhip-hop, tango, C-pop\nhip-hop, tango, Latin\nhip-hop, tech-house\nhip-hop, techno, ambient\nhip-hop, theatrical, Christmas\nhip-hop, theatrical, circus\nhip-hop, theatrical, melancholic\nhip-hop, theatrical, soul\nhip-hop, theatrical, video game\nhip-hop, traditional Arabic, cinematic\nhip-hop, traditional Central Asian\nhip-hop, traditional Central Asian, ambient\nhip-hop, traditional Central Asian, atmospheric\nhip-hop, traditional Central Asian, emotional\nhip-hop, traditional Central Asian, melancholic\nhip-hop, traditional Chinese folk\nhip-hop, traditional Chinese, Eastern Asian\nhip-hop, traditional Chinese, boom-bap\nhip-hop, traditional Chinese, cinematic\nhip-hop, traditional Chinese, instrumental\nhip-hop, traditional Chinese, lo-fi\nhip-hop, traditional Chinese, theatrical\nhip-hop, traditional East Asian\nhip-hop, traditional East Asian, boom-bap\nhip-hop, traditional East Asian, fusion\nhip-hop, traditional East Asian, trap\nhip-hop, traditional Indonesian\nhip-hop, traditional Japanese, boom-bap\nhip-hop, traditional Japanese, lo-fi\nhip-hop, traditional Japanese, theatrical\nhip-hop, traditional South Asian\nhip-hop, traditional South Asian, lament\nhip-hop, traditional South Asian, melodic\nhip-hop, traditional Southeast Asian\nhip-hop, traditional Southeast Asian, electronic\nhip-hop, traditional Southeast Asian, fusion\nhip-hop, traditional Turkish\nhip-hop, traditional folk\nhip-hop, traditional fusion\nhip-hop, traditional fusion, Anatolian\nhip-hop, traditional fusion, Central Asian\nhip-hop, traditional, electronic\nhip-hop, traditional, melancholic\nhip-hop, trance, Middle Eastern\nhip-hop, trance, synth-pop\nhip-hop, trap\nhip-hop, trap R&B\nhip-hop, trap metal\nhip-hop, trap metal, Australian outback\nhip-hop, trap metal, breakcore\nhip-hop, trap metal, cinematic\nhip-hop, trap, Afro-hip-hop\nhip-hop, trap, Afrobeat\nhip-hop, trap, Afrofusion\nhip-hop, trap, Arabic fusion\nhip-hop, trap, Asian fusion\nhip-hop, trap, Balkan brass\nhip-hop, trap, Bay Area\nhip-hop, trap, Bollywood\nhip-hop, trap, C-pop\nhip-hop, trap, Cantopop\nhip-hop, trap, Caribbean hip-hop\nhip-hop, trap, Central Asian\nhip-hop, trap, Chinese\nhip-hop, trap, Chinese fusion\nhip-hop, trap, Chinese hip-hop\nhip-hop, trap, Chinese pop\nhip-hop, trap, Chinese rap\nhip-hop, trap, Chinese traditional\nhip-hop, trap, EDM\nhip-hop, trap, East Asian\nhip-hop, trap, Eastern fusion\nhip-hop, trap, G-funk\nhip-hop, trap, Gujarati\nhip-hop, trap, Hindi rap\nhip-hop, trap, Indian folk\nhip-hop, trap, Indian fusion\nhip-hop, trap, Indian hip-hop\nhip-hop, trap, Indian pop\nhip-hop, trap, J-pop\nhip-hop, trap, J-rap\nhip-hop, trap, Japanese-inspired\nhip-hop, trap, K-pop\nhip-hop, trap, Latin\nhip-hop, trap, Latin hip-hop\nhip-hop, trap, Malay pop\nhip-hop, trap, Malay rap\nhip-hop, trap, Mediterranean\nhip-hop, trap, Middle Eastern\nhip-hop, trap, Middle Eastern fusion\nhip-hop, trap, North African\nhip-hop, trap, Portuguese rap\nhip-hop, trap, Punjabi\nhip-hop, trap, Punjabi rap\nhip-hop, trap, R&B\nhip-hop, trap, Rai\nhip-hop, trap, Russian hip-hop\nhip-hop, trap, Sinhala\nhip-hop, trap, Sinhala rap\nhip-hop, trap, South Asian\nhip-hop, trap, South Asian folk\nhip-hop, trap, South Asian fusion\nhip-hop, trap, South Indian\nhip-hop, trap, South Indian fusion\nhip-hop, trap, Southeast Asian\nhip-hop, trap, Southeast Asian fusion\nhip-hop, trap, Spanish-influenced\nhip-hop, trap, Vietnamese bolero\nhip-hop, trap, afro-trap\nhip-hop, trap, afrobeat\nhip-hop, trap, ambient\nhip-hop, trap, ancient style\nhip-hop, trap, anthemic\nhip-hop, trap, atmospheric\nhip-hop, trap, ballad\nhip-hop, trap, baroque\nhip-hop, trap, bhangra\nhip-hop, trap, bilingual\nhip-hop, trap, boom-bap\nhip-hop, trap, boom-bap, R&B\nhip-hop, trap, celebratory\nhip-hop, trap, chiptune\nhip-hop, trap, cinematic\nhip-hop, trap, classical\nhip-hop, trap, classical-inspired\nhip-hop, trap, cloud rap\nhip-hop, trap, cloud-rap, J-rap\nhip-hop, trap, club\nhip-hop, trap, comedic\nhip-hop, trap, dancehall\nhip-hop, trap, dreamy\nhip-hop, trap, drill\nhip-hop, trap, dubstep\nhip-hop, trap, educational\nhip-hop, trap, electronic\nhip-hop, trap, emotional\nhip-hop, trap, empowering\nhip-hop, trap, experimental\nhip-hop, trap, festive\nhip-hop, trap, flamenco\nhip-hop, trap, funk\nhip-hop, trap, global\nhip-hop, trap, global hip-hop\nhip-hop, trap, gospel\nhip-hop, trap, hardstyle\nhip-hop, trap, hip-house\nhip-hop, trap, hyperpop\nhip-hop, trap, jazz\nhip-hop, trap, klezmer\nhip-hop, trap, lo-fi\nhip-hop, trap, melodic\nhip-hop, trap, melodic hip-hop\nhip-hop, trap, modern\nhip-hop, trap, moombahton\nhip-hop, trap, motivational\nhip-hop, trap, multi-lingual\nhip-hop, trap, multilingual\nhip-hop, trap, noir\nhip-hop, trap, orchestral\nhip-hop, trap, oud\nhip-hop, trap, playful\nhip-hop, trap, political\nhip-hop, trap, pop\nhip-hop, trap, pop-r&b, salsa\nhip-hop, trap, psychedelic\nhip-hop, trap, ragtime\nhip-hop, trap, rap-rock\nhip-hop, trap, reggae\nhip-hop, trap, reggaeton\nhip-hop, trap, soul\nhip-hop, trap, sports anthem\nhip-hop, trap, synth\nhip-hop, trap, synth-pop\nhip-hop, trap, trance\nhip-hop, trap, upbeat\nhip-hop, trap, world beat\nhip-hop, trap, world fusion\nhip-hop, trap, world music\nhip-hop, trap-metal, ambient\nhip-hop, trap-soul\nhip-hop, tribal, Afrobeat\nhip-hop, tribal, Indonesian\nhip-hop, tribal, aggressive\nhip-hop, tribal, cinematic\nhip-hop, tribal, electronic\nhip-hop, trip-hop\nhip-hop, trip-hop, boom-bap\nhip-hop, trip-hop, chiptune\nhip-hop, trip-hop, lo-fi\nhip-hop, tropical, Polynesian\nhip-hop, tropical, lo-fi\nhip-hop, turntablism, big beat\nhip-hop, turntablism, boom-bap\nhip-hop, ukulele pop\nhip-hop, underground, Punjabi hip-hop\nhip-hop, underground, boom-bap\nhip-hop, underground, cinematic\nhip-hop, underground, dark\nhip-hop, underground, ethereal\nhip-hop, vaporwave\nhip-hop, vaporwave, 90s R&B\nhip-hop, vaporwave, Afrobeat\nhip-hop, vaporwave, Arabic rap\nhip-hop, vaporwave, C-pop\nhip-hop, vaporwave, Chinese\nhip-hop, vaporwave, G-funk\nhip-hop, vaporwave, Indian hip-hop\nhip-hop, vaporwave, K-pop\nhip-hop, vaporwave, Moroccan Arabic\nhip-hop, vaporwave, R&B\nhip-hop, vaporwave, Russian rap\nhip-hop, vaporwave, ambient\nhip-hop, vaporwave, chiptune\nhip-hop, vaporwave, cinematic\nhip-hop, vaporwave, cyberpunk\nhip-hop, vaporwave, emotional\nhip-hop, vaporwave, experimental\nhip-hop, vaporwave, hyperpop\nhip-hop, vaporwave, lo-fi\nhip-hop, vaporwave, melodic hip-hop\nhip-hop, vaporwave, pop\nhip-hop, vaporwave, psychedelic\nhip-hop, vaporwave, rock\nhip-hop, vaporwave, soul\nhip-hop, vaporwave, synthwave\nhip-hop, vaporwave, trap\nhip-hop, video game\nhip-hop, video game horror\nhip-hop, video game, cartoon\nhip-hop, video game, electronic\nhip-hop, video game, funk\nhip-hop, video game, lo-fi\nhip-hop, video game, playful\nhip-hop, video game, quirky\nhip-hop, video game, synth\nhip-hop, video game, trap\nhip-hop, world beat, multilingual\nhip-hop, world fusion\nhip-hop, world fusion, Tamil rap\nhip-hop, world fusion, cinematic\nhip-hop, world fusion, lo-fi\nhip-hop, world fusion, trap\nhip-hop, world music\nhip-hop, world music fusion\nhip-hop, world music, Arabic\nhip-hop, world music, Arabic rap\nhip-hop, world music, C-pop\nhip-hop, world music, Mandarin rap\nhip-hop, world music, R&B\nhip-hop, world music, Thai pop\nhip-hop, world music, Turkish\nhip-hop, world music, ambient\nhip-hop, world music, blues-rock\nhip-hop, world music, boom-bap\nhip-hop, world music, choral\nhip-hop, world music, cinematic\nhip-hop, world music, contemplative\nhip-hop, world music, experimental\nhip-hop, world music, industrial\nhip-hop, world music, inspirational\nhip-hop, world music, lo-fi\nhip-hop, world music, pop\nhip-hop, world music, psychedelic\nhip-hop, world music, reggae\nhip-hop, world music, soul\nhip-hop, world music, tech house\nhip-hop, world music, trap\nhip-hop, wuxia, Chinese opera\nhip-hop, wuxia, ambient\nhip-hop, wuxia, lo-fi\nhip-hop, zouk, Caribbean\nhip-hop, zouk, R&B\nhip-hop, zouk, kizomba\nhip-hop, 喊麦, 古风\nhip-house\nhip-house breakbeat\nhip-house dance-pop\nhip-house dancehall\nhip-house eurodance\nhip-house funk\nhip-house latin pop\nhip-house trip-hop\nhip-house, Bollywood dance-pop\nhip-house, Brazilian funk, ambient\nhip-house, Latin, club\nhip-house, New Jack Swing\nhip-house, eurodance, trance-pop\nhip-house, hard dance\nhip-house, show tune\nhip-pop\nhistorical rap\nhoempapa\nholiday\nholiday R&B\nholiday a cappella\nholiday acoustic\nholiday ambient\nholiday anthem\nholiday ballad\nholiday big band\nholiday blues\nholiday boogie-woogie\nholiday bossa nova\nholiday brass\nholiday chiptune\nholiday choir\nholiday choral\nholiday cinematic\nholiday country rock\nholiday crooner\nholiday cumbia\nholiday electronic\nholiday folk\nholiday funk\nholiday hip-hop\nholiday instrumental\nholiday jazz\nholiday jingle\nholiday klezmer\nholiday lullaby\nholiday music\nholiday orchestral\nholiday piano\nholiday polka\nholiday pop\nholiday pop R&B\nholiday pop bossa nova\nholiday pop classical crossover\nholiday pop country-folk\nholiday pop future bass\nholiday pop jazz\nholiday pop lovers rock reggae\nholiday pop reggae\nholiday pop reggae-ska\nholiday pop reggaeton\nholiday pop schlager\nholiday pop soul\nholiday pop, J-pop\nholiday pop, Latin cumbia\nholiday pop, Latin pop, tropical house\nholiday pop, R&B, funk\nholiday pop, bossa nova, jazz\nholiday pop, estrada, Eastern European\nholiday pop, estrada, polka\nholiday pop, new jack swing\nholiday pop-R&B\nholiday pop-country\nholiday pop-folk\nholiday pop-funk\nholiday pop-r&b\nholiday pop-rap\nholiday pop-rock\nholiday ragtime\nholiday rock\nholiday rock and roll\nholiday show tune\nholiday soul\nholiday swing\nholiday synth\nholiday trap\nholiday ukulele\nholiday waltz\nholiday, acoustic, choral\nholiday, cinematic, ambient\nholiday, cinematic, theatrical\nholiday, classical, choral\nholiday, folk, electronic\nholiday, honky-tonk, ukulele\nholiday, orchestral, baritone\nholiday, playful, eerie\nholiday, ragtime, choir\nholiday, ragtime, musical theater\nholiday, synth pop, steel pan\nholiday, synthpop, children's choir\nholiday, synthwave, RPG\nhonky-tonk\nhonky-tonk blues\nhonky-tonk blues rock\nhonky-tonk country\nhonky-tonk country cumbia\nhonky-tonk country rock\nhonky-tonk country-rock\nhonky-tonk novelty\nhonky-tonk piano\nhonky-tonk rock\nhonky-tonk rockabilly\nhopeful pop\nhorn-driven rock\nhorror\nhorror ambient\nhorror cabaret\nhorror cumbia\nhorror hip hop\nhorror hip-hop\nhorror pop\nhorror punk\nhorror rap\nhorror reggaeton\nhorror rock\nhorror surf rock\nhorror trap\nhorror-comedy\nhorror-cumbia\nhorror-disco\nhorror-funk\nhorror-pop\nhorror-pop lo-fi hip-hop\nhorror-punk\nhorror-punk metalcore\nhorror-punk surf-punk\nhorror-punk thrash metal\nhorror-ska\nhorror-ska-punk\nhorror-swing\nhorror-swing rock\nhorror-trap\nhorrorcore\nhorrorcore Latin trap\nhorrorcore Memphis rap\nhorrorcore boom-bap\nhorrorcore chiptune\nhorrorcore chiptune g-funk\nhorrorcore chiptune trap\nhorrorcore dancehall\nhorrorcore dembow\nhorrorcore electro-swing\nhorrorcore experimental hip-hop\nhorrorcore g-funk\nhorrorcore g-funk boom-bap\nhorrorcore g-funk gangsta rap\nhorrorcore g-funk west coast hip-hop\nhorrorcore hip hop\nhorrorcore hip-hop\nhorrorcore hip-hop gothic rock\nhorrorcore hip-hop, boom-bap\nhorrorcore industrial\nhorrorcore industrial hip-hop\nhorrorcore lo-fi\nhorrorcore lo-fi hip hop\nhorrorcore lo-fi hip-hop\nhorrorcore lo-fi trap\nhorrorcore metal\nhorrorcore metalcore\nhorrorcore nu-metal\nhorrorcore nu-metal industrial rock\nhorrorcore nu-metal rap-rock\nhorrorcore phonk\nhorrorcore rap\nhorrorcore rap, hardstyle, dark trap\nhorrorcore rap-rock\nhorrorcore trap\nhorrorcore trap chiptune\nhorrorcore trap metal\nhorrorcore trap phonk\nhorrorcore, Brazilian funk, trap\nhorrorcore, G-funk, gangsta rap\nhorrorcore, German hip-hop, boom-bap\nhorrorcore, Southern hip-hop, trap\nhorrorcore, UK grime, boom-bap\nhorrorcore, boom-bap, German rap\nhorrorcore, boom-bap, bilingual\nhorrorcore, boom-bap, cinematic hip-hop\nhorrorcore, boom-bap, classical hip hop\nhorrorcore, boom-bap, gothic hip hop\nhorrorcore, boom-bap, lo-fi hip hop\nhorrorcore, boom-bap, orchestral\nhorrorcore, boom-bap, trap\nhorrorcore, boom-bap, underground hip-hop\nhorrorcore, carnival rap\nhorrorcore, chiptune, dark trap\nhorrorcore, chiptune, electronic\nhorrorcore, chiptune, industrial\nhorrorcore, chiptune, industrial hip-hop\nhorrorcore, chiptune, nu-metal\nhorrorcore, chiptune, trap\nhorrorcore, cinematic hip-hop, boom-bap\nhorrorcore, cinematic, boom-bap\nhorrorcore, conscious hip-hop\nhorrorcore, dark hip-hop\nhorrorcore, dark trap\nhorrorcore, electronic, German rap\nhorrorcore, electronic, cinematic\nhorrorcore, gothic rap, cinematic hip hop\nhorrorcore, industrial metal, rap-metal\nhorrorcore, industrial metal, trap\nhorrorcore, industrial rock, nu-metal\nhorrorcore, industrial, nu-metal\nhorrorcore, industrial, trap metal\nhorrorcore, lo-fi hip hop, Spanish rap\nhorrorcore, lo-fi hip hop, cinematic\nhorrorcore, lo-fi hip hop, conscious hip-hop\nhorrorcore, lo-fi hip hop, dark synth\nhorrorcore, lo-fi hip hop, glitch\nhorrorcore, lo-fi, trap\nhorrorcore, nu-metal, dark trap\nhorrorcore, nu-metal, rap-rock\nhorrorcore, orchestral trap, cinematic hip hop\nhorrorcore, trap\nhorrorcore, trap metal, cinematic\nhorrorcore, trap metal, dark hip-hop\nhorrorcore, trap, German hip hop\nhorrorcore, trap, German rap\nhorrorcore, trap, chiptune\nhorrorcore, trap, cinematic\nhorrorcore, trap, deathcore\nhorrorcore, trap, orchestral\nhot jazz\nhouse\nhouse Afrobeat\nhouse R&B\nhouse acapella\nhouse afro-latin\nhouse afrobeat\nhouse afrobeat dancehall\nhouse ballad\nhouse ballroom\nhouse breakbeat\nhouse chiptune\nhouse dance-pop\nhouse disco\nhouse disco funk\nhouse disco pop\nhouse disco-funk\nhouse disco-pop\nhouse dubstep\nhouse electro\nhouse electro breakbeat\nhouse electro-funk\nhouse flamenco\nhouse funk\nhouse funk breakbeat\nhouse funk disco\nhouse funk hip-house\nhouse future bass\nhouse future bass R&B\nhouse garage\nhouse gospel\nhouse gospel disco\nhouse gospel soul\nhouse hip-hop\nhouse hip-hop R&B\nhouse hip-hop electronic\nhouse hip-hop electronic pop\nhouse hip-hop trap\nhouse hip-house\nhouse j-pop\nhouse jazz\nhouse jazz fusion\nhouse lounge\nhouse music\nhouse nu-disco\nhouse nu-disco funk\nhouse nu-disco techno\nhouse pop\nhouse pop R&B\nhouse pop future bass\nhouse pop-rap\nhouse reggae dancehall\nhouse reggaeton\nhouse rock\nhouse soulful house\nhouse techno\nhouse techno breakbeat\nhouse techno electro\nhouse techno electro-pop\nhouse techno hip-hop\nhouse techno latin\nhouse techno pop\nhouse trance\nhouse trap\nhouse uk garage\nhouse world music\nhouse world music fusion\nhouse worldbeat\nhouse, 90s R&B, UK garage\nhouse, 90s breakbeat\nhouse, 90s dance-pop\nhouse, 90s garage, diva house\nhouse, Afro-Cuban, deep house\nhouse, Balkan, Middle Eastern\nhouse, Bollywood, electronic\nhouse, Brazilian bass\nhouse, Brazilian funk\nhouse, C-pop\nhouse, EDM, big room\nhouse, French rap, Spanish vocal\nhouse, Italian hip-hop\nhouse, Italo disco\nhouse, Italo disco, 90s dance\nhouse, Italo disco, Eurodance\nhouse, Italo disco, Hi-NRG\nhouse, Italo disco, electronic\nhouse, Italo disco, nu-disco\nhouse, Italo disco, retro\nhouse, Italo disco, retro dance\nhouse, Italo disco, retro electronic\nhouse, Italo disco, retro-futuristic\nhouse, Italo disco, synth-pop\nhouse, Italo disco, synthwave\nhouse, Italo-disco, early house\nhouse, Italo-disco, retro electronic\nhouse, Italo-disco, trance\nhouse, J-core, UK garage\nhouse, J-pop, UK garage\nhouse, K-pop, retro dance\nhouse, Latin house\nhouse, Latin, Afro-Cuban\nhouse, Latin, Afro-house\nhouse, Latin, Middle Eastern\nhouse, Latin, R&B\nhouse, Latin, bilingual\nhouse, Latin, dancehall\nhouse, Latin, electronic\nhouse, Middle Eastern\nhouse, Middle Eastern fusion\nhouse, Middle Eastern, Bollywood\nhouse, Middle Eastern, Turkish\nhouse, Middle Eastern, electronic\nhouse, Middle Eastern, flamenco\nhouse, R&B\nhouse, Rai, electronic\nhouse, Russian pop, electronic\nhouse, South Asian fusion\nhouse, Turkish, Middle Eastern\nhouse, UK garage\nhouse, UK garage, 90s\nhouse, UK garage, R&B\nhouse, UK garage, breakbeat\nhouse, UK garage, soulful\nhouse, Vietnamese dance\nhouse, acid house, retro electronic\nhouse, afro-latin\nhouse, afrobeat\nhouse, afrobeat, latin house\nhouse, afrobeat, soulful\nhouse, ambient, techno\nhouse, arabic, jazz\nhouse, bass house, pop\nhouse, big room, electro\nhouse, big room, electronic\nhouse, big room, emotional\nhouse, big room, rap\nhouse, bilingual, club\nhouse, bilingual, electronic\nhouse, breakbeat, lo-fi\nhouse, chillwave\nhouse, chiptune, UK garage\nhouse, chiptune, eurodance\nhouse, city pop, synthwave\nhouse, complextro\nhouse, complextro, emotional\nhouse, complextro, melodic\nhouse, dance-pop\nhouse, dance-pop, gospel\nhouse, dancehall, moombahton\nhouse, deep house\nhouse, deep house, 90s\nhouse, deep house, 90s house\nhouse, dembow, electronic\nhouse, disco, Latin\nhouse, disco, Latin house\nhouse, disco, funk\nhouse, disco, gospel\nhouse, diva house\nhouse, diva house, 90s R&B\nhouse, diva house, classic house\nhouse, diva house, eurodance\nhouse, diva house, gospel house\nhouse, dream-pop, hip hop\nhouse, electro house\nhouse, electro, big beat\nhouse, electro, big room\nhouse, electronic, Portuguese pop\nhouse, eurodance\nhouse, eurodance, 90s\nhouse, eurodance, 90s club\nhouse, eurodance, 90s dancehall\nhouse, eurodance, Turkish pop\nhouse, eurodance, ambient\nhouse, eurodance, dance\nhouse, eurodance, disco\nhouse, eurodance, energetic\nhouse, eurodance, gospel\nhouse, eurodance, happy hardcore\nhouse, eurodance, italo disco\nhouse, eurodance, italo house\nhouse, eurodance, latin house\nhouse, eurodance, retro electronic\nhouse, eurodance, trance\nhouse, flamenco, jazz\nhouse, freestyle\nhouse, freestyle hip-hop\nhouse, freestyle, electronic\nhouse, funk, new jack swing\nhouse, future bass\nhouse, future bass, Latin pop\nhouse, future bass, R&B\nhouse, future bass, cinematic pop\nhouse, future bass, emotional\nhouse, future bass, lo-fi\nhouse, future bass, pop\nhouse, gospel house, diva house\nhouse, gospel, big beat\nhouse, gospel, big room\nhouse, gospel, soul\nhouse, gospel, theatrical\nhouse, hardstyle\nhouse, hardstyle, R&B\nhouse, hardstyle, pop\nhouse, hardstyle, pop-R&B\nhouse, hip-hop, future bass\nhouse, hip-house\nhouse, hip-house, South African\nhouse, hip-house, afro-house\nhouse, hip-house, dance\nhouse, hip-house, new jack swing\nhouse, hip-house, retro\nhouse, hyperpop\nhouse, industrial techno, ambient\nhouse, italo disco, electronic\nhouse, jungle, breakbeat\nhouse, latin house\nhouse, latin house, soulful\nhouse, latin house, synth funk\nhouse, latin, ambient\nhouse, latin, dance\nhouse, latin, eurodance\nhouse, latin, retro-futuristic\nhouse, latin, soul\nhouse, latin, tribal\nhouse, new beat, retro electronic\nhouse, new jack swing\nhouse, new jack swing, 80s electronic\nhouse, new jack swing, 80s funk\nhouse, new jack swing, 90s dance-pop\nhouse, new jack swing, Afro house\nhouse, new jack swing, Hi-NRG\nhouse, new jack swing, Latin\nhouse, new jack swing, Latin house\nhouse, new jack swing, R&B\nhouse, new jack swing, afro house\nhouse, new jack swing, chiptune\nhouse, new jack swing, dancehall\nhouse, new jack swing, early hip-hop\nhouse, new jack swing, early house\nhouse, new jack swing, freestyle\nhouse, new jack swing, funk\nhouse, new jack swing, gospel\nhouse, new jack swing, pop\nhouse, new jack swing, soulful\nhouse, nu-disco\nhouse, nu-disco, French house\nhouse, nu-disco, ethereal\nhouse, nu-disco, funk\nhouse, nu-disco, future house\nhouse, nu-disco, sax house\nhouse, nu-disco, soulful\nhouse, nu-disco, soulful house\nhouse, pop, EDM\nhouse, pop, future bass\nhouse, pop, rap\nhouse, punk, rap\nhouse, rap, UK garage\nhouse, rap, ambient\nhouse, rap, electronic\nhouse, soulful, new jack swing\nhouse, tech house\nhouse, tech house, afrobeat\nhouse, techno, Latin\nhouse, techno, Latin house\nhouse, trance, techno\nhouse, trap\nhouse, trap, psychedelic\nhouse, tribal house\nhouse, uk garage\nhouse, uk garage, 2-step\nhouse, uk garage, deep house\nhouse, uk garage, future funk\nhouse, uk garage, hyperpop\nhouse, uk garage, pop-dance\nhouse, uk garage, r&b\nhouse, uk garage, sample-based\nhouse, vaporwave, Latin hip hop\nhouse, vaporwave, Latin house\nhouse, vaporwave, R&B\nhouse, worldbeat, new age\nhouse-pop\nhouse-rap\nhumpapa\nhumppa\nhumppa lo-fi\nhumppa polka\nhumppa rock\nhumppa schlager\nhumppa ska\nhumppa, polka, Finnish\nhumppa, polka, theatrical\nhumppa-punk rock\nhumppa-rock\nhumppa-rock chiptune schlager\nhumppa-rock power metal\nhumppa-swing\nhybrid electronic\nhybrid hip-hop\nhybrid orchestral\nhybrid rap, electronic, dubstep\nhybrid rock\nhybrid trap\nhybrid trap C-pop\nhybrid trap ambient\nhybrid trap dubstep\nhybrid trap future bass\nhybrid trap hardstyle\nhybrid trap, ambient oud, cinematic dubstep\nhybrid trap, brostep, cinematic\nhybrid trap, brostep, hardstyle\nhybrid trap, cinematic orchestral\nhybrid trap, emo-rap, hardstyle\nhybrid trap, future bass\nhybrid trap, future bass, dubstep\nhybrid trap, future bass, hardstyle\nhybrid trap, hardstyle\nhybrid trap, hardstyle, Mandarin rap\nhybrid trap, hardstyle, cinematic\nhybrid trap, hardstyle, cinematic electronic\nhybrid trap, hardwave, cinematic\nhybrid trap, lo-fi hip hop, ambient\nhybrid-orchestral\nhymn\nhymn-like\nhymn-like ballad\nhymn-like, Celtic folk, cinematic\nhymn-like, acoustic, neo-classical\nhymn-like, cinematic, folk\nhymnal\nhymnal ambient\nhymnal electronic\nhymnal folk\nhymnal organ\nhyper C-pop\nhyper J-pop\nhyper J-pop chiptune\nhyper J-pop denpa\nhyper J-pop denpa-kei\nhyper dance\nhyper ragtime\nhyper-J-pop\nhyper-J-pop breakcore\nhyper-J-pop denpa\nhyper-J-pop denpa-kei\nhyper-dance-pop\nhyper-dancehall\nhyper-digital dance\nhyper-disco\nhyper-electronic dance\nhyper-electronic fusion\nhyper-electronic, South Indian folk\nhyper-funk\nhyper-funk breakbeat\nhyper-funk, J-core\nhyper-funk, chiptune, breakbeat\nhyper-funk, chiptune, electronic\nhyper-funky Latin pop\nhyper-pop\nhyper-pop C-pop\nhyper-pop J-rock\nhyper-pop K-Pop\nhyper-pop R&B\nhyper-pop children's\nhyper-pop children's music\nhyper-pop chiptune\nhyper-pop chiptune J-pop\nhyper-pop industrial\nhyper-pop j-pop\nhyper-pop kawaii future bass\nhyper-pop punk\nhyper-pop show tune\nhyper-pop world fusion\nhyper-pop, Brazilian funk\nhyper-pop, C-pop, J-pop\nhyper-pop, C-pop, anime\nhyper-pop, C-pop, dance\nhyper-pop, C-pop, kawaii\nhyper-pop, J-core\nhyper-pop, J-core, electronic\nhyper-pop, J-core, happy hardcore\nhyper-pop, J-pop\nhyper-pop, J-pop, C-pop\nhyper-pop, J-pop, Chinese New Year\nhyper-pop, J-pop, anime\nhyper-pop, J-pop, children's music\nhyper-pop, J-pop, chiptune\nhyper-pop, J-pop, dance-pop\nhyper-pop, J-pop, electronic\nhyper-pop, J-pop, happy hardcore\nhyper-pop, J-pop, video game\nhyper-pop, J-pop, video game music\nhyper-pop, J-rock\nhyper-pop, K-pop\nhyper-pop, K-pop, children's music\nhyper-pop, K-pop, hardstyle\nhyper-pop, anime, cinematic\nhyper-pop, cartoon soundtrack\nhyper-pop, children's music\nhyper-pop, chiptune\nhyper-pop, chiptune, C-pop\nhyper-pop, chiptune, J-core\nhyper-pop, chiptune, J-pop\nhyper-pop, chiptune, dream pop\nhyper-pop, chiptune, nightcore\nhyper-pop, cinematic, C-pop\nhyper-pop, dance-pop, chiptune\nhyper-pop, electronic, folk\nhyper-pop, happy hardcore\nhyper-pop, happy hardcore, J-pop\nhyper-pop, lo-fi hip hop, rock\nhyper-pop, nightcore\nhyper-pop, nightcore, J-pop\nhyper-pop-punk\nhyper-pop-punk metalcore\nhyper-pop-punk, Nintendocore\nhyper-punk mathcore\nhyper-punk nintendocore\nhyper-rap\nhyper-rap trap\nhyper-reggaeton\nhyper-rock\nhyper-ska cumbia\nhyper-speed C-pop\nhyper-speed cumbia\nhyper-trance\nhyper-trance, chiptune, hardstyle\nhyper-trap\nhyper-trap chiptune\nhyper-trap glitch-hop\nhyper-trap glitchcore\nhyper-trap lo-fi\nhyper-trap meme rap\nhyper-trap pluggnb\nhyper-trap vaporwave\nhyper-trap, C-pop, J-pop\nhyper-trap, Chinese hip hop\nhyper-trap, Christmas, Korean rap\nhyper-trap, K-pop, chiptune\nhyper-trap, R&B\nhyper-trap, Turkish rap, hyperpop\nhyper-trap, breakcore, gabber\nhyper-trap, chiptune, cloud rap\nhyper-trap, chiptune, hyperpop\nhyper-trap, chiptune, trap\nhyper-trap, cloud rap\nhyper-trap, cloud rap, anime-core\nhyper-trap, cloud rap, chiptune\nhyper-trap, cloud rap, hyperpop\nhyper-trap, cloud rap, metal\nhyper-trap, cloud rap, pluggnb\nhyper-trap, cloud rap, rage music\nhyper-trap, cloud-rap\nhyper-trap, glitchcore, cloud rap\nhyper-trap, glitchcore, video game music\nhyper-trap, hardstyle\nhyper-trap, hyperpop\nhyper-trap, hyperpop, chiptune\nhyper-trap, pop, rap\nhyper-trap, rage music, hyperpop\nhyper-trap, rage, hyperpop\nhyper-trap, rage, lo-fi\nhyper-trap, rage, pluggnb\nhyperactive C-pop\nhyperpop\nhyperpop C-pop\nhyperpop C-pop EDM\nhyperpop C-pop J-pop\nhyperpop C-pop J-rock\nhyperpop C-pop anime\nhyperpop C-pop chiptune\nhyperpop C-pop trap\nhyperpop C-pop trap-R&B\nhyperpop J-pop\nhyperpop J-rock\nhyperpop K-pop\nhyperpop R&B\nhyperpop R&B acoustic\nhyperpop R&B cloud rap\nhyperpop R&B trap\nhyperpop T-pop\nhyperpop a cappella\nhyperpop afrobeat\nhyperpop afrobeats\nhyperpop afrobeats chiptune\nhyperpop alternative R&B\nhyperpop alternative pop\nhyperpop alternative rock\nhyperpop alternative rock trap\nhyperpop ambient\nhyperpop ambient pop\nhyperpop arabic\nhyperpop art pop\nhyperpop art-pop\nhyperpop artcore\nhyperpop artcore future bass\nhyperpop artcore lo-fi\nhyperpop artcore trance\nhyperpop baile funk\nhyperpop baile funk chiptune\nhyperpop ballroom house\nhyperpop bhangra edm\nhyperpop bitpop\nhyperpop bollywood\nhyperpop breakbeat\nhyperpop breakcore\nhyperpop breakcore J-rock\nhyperpop breakcore art pop\nhyperpop breakcore chiptune\nhyperpop breakcore glitchcore\nhyperpop breakcore jazz\nhyperpop breakcore shoegaze\nhyperpop bubblegum pop\nhyperpop cantopop\nhyperpop children's\nhyperpop children's music\nhyperpop chiptune\nhyperpop chiptune Bollywood\nhyperpop chiptune Brazilian funk\nhyperpop chiptune J-core\nhyperpop chiptune J-pop\nhyperpop chiptune J-rock\nhyperpop chiptune artcore\nhyperpop chiptune big band\nhyperpop chiptune breakbeat\nhyperpop chiptune breakcore\nhyperpop chiptune children's pop\nhyperpop chiptune cloud rap\nhyperpop chiptune cumbia\nhyperpop chiptune digital hardcore\nhyperpop chiptune drum and bass\nhyperpop chiptune electro-pop\nhyperpop chiptune electronic rock\nhyperpop chiptune emo rap\nhyperpop chiptune emo-pop\nhyperpop chiptune emo-rap\nhyperpop chiptune future bass\nhyperpop chiptune glitch\nhyperpop chiptune glitch-hop\nhyperpop chiptune glitch-pop\nhyperpop chiptune happy hardcore\nhyperpop chiptune hard rock\nhyperpop chiptune hardcore\nhyperpop chiptune hardcore techno\nhyperpop chiptune hardstyle\nhyperpop chiptune indie pop\nhyperpop chiptune j-core\nhyperpop chiptune j-pop\nhyperpop chiptune j-rock\nhyperpop chiptune k-pop\nhyperpop chiptune latin pop\nhyperpop chiptune latin trap\nhyperpop chiptune lo-fi\nhyperpop chiptune meme-rap\nhyperpop chiptune metalcore\nhyperpop chiptune pop-punk\nhyperpop chiptune rap\nhyperpop chiptune rapcore\nhyperpop chiptune reggaeton\nhyperpop chiptune rock\nhyperpop chiptune speedcore\nhyperpop chiptune synth-pop\nhyperpop chiptune trance\nhyperpop chiptune trap\nhyperpop chiptune uk garage\nhyperpop chiptune-punk\nhyperpop chiptune-rap\nhyperpop cinematic\nhyperpop city pop\nhyperpop cloud rap\nhyperpop cloud rap ambient\nhyperpop cloud rap chiptune\nhyperpop cloud rap emo-rock\nhyperpop cloud rap lo-fi hip hop\nhyperpop cloud rap pluggnb\nhyperpop cloud rap vaporwave\nhyperpop cumbia\nhyperpop cumbia reggaeton\nhyperpop dance-pop\nhyperpop dancehall\nhyperpop dappan koothu\nhyperpop dark pop\nhyperpop dark trap\nhyperpop darkwave\nhyperpop denpa\nhyperpop denpa J-core\nhyperpop denpa chiptune\nhyperpop denpa hardcore techno\nhyperpop denpa j-core\nhyperpop denpa j-pop\nhyperpop denpa-kei\nhyperpop digicore\nhyperpop digicore chiptune\nhyperpop digicore emo rap\nhyperpop digicore emo-rap\nhyperpop digicore emo-trap\nhyperpop digicore lo-fi\nhyperpop digicore melodic trap\nhyperpop digicore rage\nhyperpop digital hardcore\nhyperpop dream pop\nhyperpop drill\nhyperpop drum and bass\nhyperpop drum and bass art pop\nhyperpop drum and bass art rock\nhyperpop drum and bass dubstep\nhyperpop dubstep\nhyperpop electro\nhyperpop electro-country chiptune\nhyperpop electro-pop\nhyperpop electro-rock\nhyperpop electroclash\nhyperpop electroclash dance-pop\nhyperpop electronic\nhyperpop electronic R&B\nhyperpop electronic dance\nhyperpop electronic hip-hop\nhyperpop electronic punk\nhyperpop electronic rap\nhyperpop electronic rock\nhyperpop electronic rock J-rock\nhyperpop electronic rock K-pop\nhyperpop electronic rock chiptune\nhyperpop electronic rock digital hardcore\nhyperpop electronic rock emo-rap\nhyperpop electronic rock metalcore\nhyperpop electronic rock nu-metal\nhyperpop electronic rock pop-punk\nhyperpop electronic rock trap metal\nhyperpop electronic trap\nhyperpop electronicore\nhyperpop electronicore emo-rap\nhyperpop electronicore glitchcore\nhyperpop electronicore metalcore\nhyperpop electronicore pop-punk\nhyperpop electronicore post-hardcore\nhyperpop electronicore trancecore\nhyperpop electronicore trap metal\nhyperpop electropop\nhyperpop electropop dance-pop\nhyperpop emo\nhyperpop emo electronic rock\nhyperpop emo hardcore\nhyperpop emo rap\nhyperpop emo rap J-rock\nhyperpop emo rap alternative R&B\nhyperpop emo rap alternative rock\nhyperpop emo rap ambient\nhyperpop emo rap chiptune\nhyperpop emo rap cloud rap\nhyperpop emo rap dark trap\nhyperpop emo rap dream pop\nhyperpop emo rap drum and bass\nhyperpop emo rap electronic punk\nhyperpop emo rap electronic rock\nhyperpop emo rap glitchcore\nhyperpop emo rap metalcore\nhyperpop emo rap pop-punk\nhyperpop emo rap trap metal\nhyperpop emo rock\nhyperpop emo rock glitchcore\nhyperpop emo trap\nhyperpop emo-core\nhyperpop emo-pop\nhyperpop emo-pop chiptune\nhyperpop emo-pop trap metal\nhyperpop emo-punk\nhyperpop emo-punk trap\nhyperpop emo-rap\nhyperpop emo-rap lo-fi\nhyperpop emo-revival\nhyperpop emo-rock\nhyperpop emo-rock trap\nhyperpop emo-trap\nhyperpop emo-trap lo-fi\nhyperpop emo-trap metalcore\nhyperpop emo-trap rock\nhyperpop emo-trap vaporwave\nhyperpop emotional trap\nhyperpop eurodance\nhyperpop experimental\nhyperpop experimental club\nhyperpop experimental hip-hop\nhyperpop experimental pop\nhyperpop flamenco trap\nhyperpop funk\nhyperpop funk alternative R&B\nhyperpop funk big band\nhyperpop funk carioca\nhyperpop funk carioca digital hardcore\nhyperpop funk jazz fusion\nhyperpop funk-rock\nhyperpop fusion\nhyperpop future bass\nhyperpop future bass drum and bass\nhyperpop future funk\nhyperpop gabber\nhyperpop gabber breakcore\nhyperpop gabber experimental club\nhyperpop glitch\nhyperpop glitch breakcore\nhyperpop glitch-hop\nhyperpop glitch-hop chiptune\nhyperpop glitch-hop electronic\nhyperpop glitch-hop experimental R&B\nhyperpop glitch-pop\nhyperpop glitchcore\nhyperpop glitchcore breakcore\nhyperpop glitchcore chiptune\nhyperpop glitchcore digicore\nhyperpop glitchcore drum and bass\nhyperpop glitchcore electronic rock\nhyperpop glitchcore emo rap\nhyperpop glitchcore emo-punk\nhyperpop glitchcore emo-rap\nhyperpop glitchcore experimental\nhyperpop glitchcore experimental R&B\nhyperpop glitchcore experimental hip-hop\nhyperpop glitchcore hardstyle\nhyperpop glitchcore nightcore\nhyperpop glitchcore pluggnb\nhyperpop glitchcore trap\nhyperpop glitchcore trap metal\nhyperpop happy hardcore\nhyperpop hardcore\nhyperpop hardcore electronic\nhyperpop hardcore techno\nhyperpop hardstyle\nhyperpop hardstyle dubstep\nhyperpop hardstyle metalcore\nhyperpop hardstyle trance\nhyperpop hip-hop\nhyperpop hip-hop electronic\nhyperpop house\nhyperpop indie pop\nhyperpop indie pop bedroom pop\nhyperpop indie rock\nhyperpop industrial\nhyperpop industrial J-rock\nhyperpop industrial electro-house\nhyperpop industrial electronic rock\nhyperpop industrial metal\nhyperpop industrial rock\nhyperpop j-core\nhyperpop j-pop\nhyperpop j-pop anime\nhyperpop j-pop anime-core\nhyperpop j-pop breakcore\nhyperpop j-pop chiptune\nhyperpop j-pop rock\nhyperpop j-pop trance\nhyperpop j-rap\nhyperpop j-rock\nhyperpop j-rock anime\nhyperpop jazz\nhyperpop jungle\nhyperpop k-pop\nhyperpop kawaii cloud rap\nhyperpop kawaii future bass\nhyperpop kawaii trap\nhyperpop kuthu\nhyperpop latin dance-pop\nhyperpop lo-fi\nhyperpop lo-fi hip hop\nhyperpop lo-fi hip-hop\nhyperpop lo-fi hip-hop C-pop\nhyperpop manele\nhyperpop math rock\nhyperpop math rock noise rock\nhyperpop math rock shoegaze\nhyperpop meme-rap\nhyperpop meme-rap chiptune\nhyperpop metalcore\nhyperpop metalcore nintendocore\nhyperpop neurofunk\nhyperpop nightcore\nhyperpop nintendocore\nhyperpop noise rock\nhyperpop nu-metal\nhyperpop nu-metal chiptune\nhyperpop nu-metal industrial\nhyperpop orchestral\nhyperpop phonk\nhyperpop pirate\nhyperpop pluggnb\nhyperpop pluggnb Afrobeat\nhyperpop pluggnb chiptune\nhyperpop pluggnb lo-fi\nhyperpop pluggnb trap\nhyperpop pop-punk\nhyperpop power-pop\nhyperpop power-pop musical theater\nhyperpop punk\nhyperpop punk chiptune\nhyperpop punk gabber\nhyperpop punk rock\nhyperpop punk-rap\nhyperpop rage\nhyperpop rage pluggnb\nhyperpop rage trap\nhyperpop rage-trap\nhyperpop rap\nhyperpop rap-rock\nhyperpop rapcore\nhyperpop reggaeton\nhyperpop reggaeton chiptune\nhyperpop reggaeton nightcore\nhyperpop reggaeton trap\nhyperpop rock\nhyperpop samba funk\nhyperpop shoegaze\nhyperpop speedcore\nhyperpop speedcore chiptune\nhyperpop surf-rock\nhyperpop synth-pop\nhyperpop synth-pop breakbeat\nhyperpop synth-punk\nhyperpop tamil folk\nhyperpop techno\nhyperpop trance\nhyperpop trap\nhyperpop trap C-pop\nhyperpop trap EDM\nhyperpop trap J-pop\nhyperpop trap J-rock\nhyperpop trap Latin pop\nhyperpop trap R&B\nhyperpop trap alternative R&B\nhyperpop trap ambient\nhyperpop trap chiptune\nhyperpop trap dancehall\nhyperpop trap experimental\nhyperpop trap glitchcore\nhyperpop trap hardstyle\nhyperpop trap horrorcore\nhyperpop trap industrial\nhyperpop trap metal\nhyperpop trap metal chiptune\nhyperpop trap metal dubstep\nhyperpop trap metal electronic rock\nhyperpop trap metal electronicore\nhyperpop trap metal glitchcore\nhyperpop trap progressive rock\nhyperpop trap rock\nhyperpop trap southern rock\nhyperpop trap synth-pop\nhyperpop trap world music\nhyperpop trap, cloud rap\nhyperpop trap-R&B\nhyperpop trap-metal\nhyperpop trap-pop\nhyperpop trap-rap\nhyperpop uk garage\nhyperpop vaporwave\nhyperpop vaporwave trap\nhyperpop witch house\nhyperpop, Balkan rap\nhyperpop, Bhojpuri folk\nhyperpop, Bhojpuri folk, electronic dance\nhyperpop, Bollywood\nhyperpop, Bollywood trap\nhyperpop, Bollywood, chiptune\nhyperpop, Brazilian Funk\nhyperpop, Brazilian funk\nhyperpop, Brazilian funk carioca\nhyperpop, Brazilian funk, cinematic pop\nhyperpop, Brazilian funk, electronic\nhyperpop, Brazilian funk, lo-fi\nhyperpop, Brazilian funk, rave\nhyperpop, Brazilian funk, synthwave\nhyperpop, Brazilian funk, trap\nhyperpop, Brazilian trap, chopped and screwed\nhyperpop, Brazilian, electronic\nhyperpop, Brazilian, futuristic\nhyperpop, Brazilian, hardstyle\nhyperpop, Brazilian, trap\nhyperpop, C-pop\nhyperpop, C-pop, Eurodance\nhyperpop, C-pop, J-pop\nhyperpop, C-pop, R&B\nhyperpop, C-pop, anime\nhyperpop, C-pop, anime theme\nhyperpop, C-pop, children's music\nhyperpop, C-pop, chiptune\nhyperpop, C-pop, dream pop\nhyperpop, C-pop, electronic\nhyperpop, C-pop, emo rap\nhyperpop, C-pop, future bass\nhyperpop, C-pop, glitch\nhyperpop, C-pop, hip-hop\nhyperpop, C-pop, kawaii bass\nhyperpop, C-pop, kawaii future bass\nhyperpop, C-pop, lo-fi hip hop\nhyperpop, C-pop, trance\nhyperpop, C-pop, trap\nhyperpop, C-pop, trap-R&B\nhyperpop, C-pop, video game\nhyperpop, C-pop, video game music\nhyperpop, Chinese folk, electronic\nhyperpop, Chinese hip-hop\nhyperpop, EBM\nhyperpop, EDM\nhyperpop, EDM, C-pop\nhyperpop, EDM, Italian rap\nhyperpop, EDM, J-pop\nhyperpop, EDM, J-rock\nhyperpop, EDM, cyberpunk\nhyperpop, EDM, dance-pop\nhyperpop, EDM, rap\nhyperpop, EDM, trap\nhyperpop, French pop, chiptune\nhyperpop, Greek pop\nhyperpop, IDM\nhyperpop, Indian electronic\nhyperpop, Indian film music\nhyperpop, Indian folk\nhyperpop, Indian folk, electronic\nhyperpop, Indian folk-pop, chiptune\nhyperpop, Indian hip-hop, electronic dance\nhyperpop, Indian pop\nhyperpop, Indian pop, chiptune\nhyperpop, Indian regional\nhyperpop, Indonesian pop\nhyperpop, Italian indie rock\nhyperpop, Italian pop-rap\nhyperpop, J-Rock, chiptune\nhyperpop, J-core\nhyperpop, J-core, C-pop\nhyperpop, J-core, K-pop\nhyperpop, J-core, ambient\nhyperpop, J-core, anime\nhyperpop, J-core, anime theme\nhyperpop, J-core, artcore\nhyperpop, J-core, breakbeat\nhyperpop, J-core, breakcore\nhyperpop, J-core, chiptune\nhyperpop, J-core, cinematic\nhyperpop, J-core, denpa\nhyperpop, J-core, electronic\nhyperpop, J-core, electronic pop\nhyperpop, J-core, electronic rock\nhyperpop, J-core, gabber\nhyperpop, J-core, happy hardcore\nhyperpop, J-core, hardstyle\nhyperpop, J-core, kawaii bass\nhyperpop, J-core, nightcore\nhyperpop, J-core, rap\nhyperpop, J-core, speedcore\nhyperpop, J-core, trance\nhyperpop, J-core, trap\nhyperpop, J-core, video game music\nhyperpop, J-pop\nhyperpop, J-pop, Brazilian funk\nhyperpop, J-pop, C-pop\nhyperpop, J-pop, Christmas pop\nhyperpop, J-pop, EDM\nhyperpop, J-pop, J-core\nhyperpop, J-pop, K-pop\nhyperpop, J-pop, Latin pop\nhyperpop, J-pop, Russian\nhyperpop, J-pop, T-pop\nhyperpop, J-pop, V-pop\nhyperpop, J-pop, ambient\nhyperpop, J-pop, anime\nhyperpop, J-pop, art-pop\nhyperpop, J-pop, artcore\nhyperpop, J-pop, baroque\nhyperpop, J-pop, big band jazz\nhyperpop, J-pop, breakbeat\nhyperpop, J-pop, breakcore\nhyperpop, J-pop, bubblegum pop\nhyperpop, J-pop, chiptune\nhyperpop, J-pop, cinematic\nhyperpop, J-pop, city pop\nhyperpop, J-pop, cloud rap\nhyperpop, J-pop, dance-pop\nhyperpop, J-pop, dark electronic\nhyperpop, J-pop, dark fantasy\nhyperpop, J-pop, denpa\nhyperpop, J-pop, denpa-kei\nhyperpop, J-pop, digital hardcore\nhyperpop, J-pop, disco\nhyperpop, J-pop, electro-pop\nhyperpop, J-pop, electronic\nhyperpop, J-pop, electronic dance\nhyperpop, J-pop, electronic pop\nhyperpop, J-pop, electronic rock\nhyperpop, J-pop, emo-rap\nhyperpop, J-pop, experimental electronic\nhyperpop, J-pop, funk-rap\nhyperpop, J-pop, funk-rock\nhyperpop, J-pop, future bass\nhyperpop, J-pop, glitch-hop\nhyperpop, J-pop, glitch-pop\nhyperpop, J-pop, glitchcore\nhyperpop, J-pop, happy hardcore\nhyperpop, J-pop, hardcore electronic\nhyperpop, J-pop, hardstyle\nhyperpop, J-pop, hip-hop\nhyperpop, J-pop, idol\nhyperpop, J-pop, kawaii\nhyperpop, J-pop, kawaii bass\nhyperpop, J-pop, kawaii future bass\nhyperpop, J-pop, kids' pop\nhyperpop, J-pop, lo-fi\nhyperpop, J-pop, lo-fi hip-hop\nhyperpop, J-pop, meme music\nhyperpop, J-pop, metalcore\nhyperpop, J-pop, modern pop\nhyperpop, J-pop, nightcore\nhyperpop, J-pop, rock\nhyperpop, J-pop, synth-pop\nhyperpop, J-pop, trap\nhyperpop, J-pop, trap metal\nhyperpop, J-pop, vaporwave\nhyperpop, J-pop, video game\nhyperpop, J-pop, video game music\nhyperpop, J-rap\nhyperpop, J-rap, breakcore\nhyperpop, J-rap, chiptune\nhyperpop, J-rap, trap\nhyperpop, J-rock\nhyperpop, J-rock, C-pop\nhyperpop, J-rock, EDM\nhyperpop, J-rock, anime\nhyperpop, J-rock, art-pop\nhyperpop, J-rock, chiptune\nhyperpop, J-rock, cinematic\nhyperpop, J-rock, digital hardcore\nhyperpop, J-rock, drum and bass\nhyperpop, J-rock, electronic\nhyperpop, J-rock, electronic rock\nhyperpop, J-rock, electronicore\nhyperpop, J-rock, emo-rap\nhyperpop, J-rock, glitch-hop\nhyperpop, J-rock, happy hardcore\nhyperpop, J-rock, lo-fi\nhyperpop, J-rock, rap\nhyperpop, J-rock, speedcore\nhyperpop, J-rock, trap\nhyperpop, J-rock, trap metal\nhyperpop, J-rock, video game\nhyperpop, J-rock, video game music\nhyperpop, J-trap\nhyperpop, Japanese artcore\nhyperpop, Japanese hip hop\nhyperpop, Javanese fusion\nhyperpop, Jersey club\nhyperpop, K-R&B, boom-bap hip-hop\nhyperpop, K-pop\nhyperpop, K-pop, EDM\nhyperpop, K-pop, UK garage\nhyperpop, K-pop, anime\nhyperpop, K-pop, bubblegum pop\nhyperpop, K-pop, children's music\nhyperpop, K-pop, chiptune\nhyperpop, K-pop, dance-pop\nhyperpop, K-pop, electro-pop\nhyperpop, K-pop, electronic\nhyperpop, K-pop, electronic rock\nhyperpop, K-pop, electropop\nhyperpop, K-pop, experimental dance\nhyperpop, K-pop, future bass\nhyperpop, K-pop, glitchcore\nhyperpop, K-pop, happy hardcore\nhyperpop, K-pop, hardstyle\nhyperpop, K-pop, industrial\nhyperpop, K-pop, trap\nhyperpop, K-pop, video game music\nhyperpop, Korean hip-hop, trap\nhyperpop, Latin dance\nhyperpop, Latin dance, cumbia\nhyperpop, Latin electronic\nhyperpop, Latin electronic, dembow\nhyperpop, Latin pop, cinematic\nhyperpop, Latin pop, reggaeton\nhyperpop, Latin trap\nhyperpop, Latin trap, R&B\nhyperpop, Latin trap, rage\nhyperpop, Mandarin pop-rap\nhyperpop, Mandopop, R&B\nhyperpop, Mandopop, electronic dance\nhyperpop, Mandopop, lo-fi hip hop\nhyperpop, Nintendocore\nhyperpop, R&B\nhyperpop, R&B, Latin pop\nhyperpop, R&B, ambient\nhyperpop, R&B, chiptune\nhyperpop, R&B, electronic\nhyperpop, R&B, emo-rap\nhyperpop, R&B, hip-hop\nhyperpop, R&B, metalcore\nhyperpop, R&B, trap\nhyperpop, R&B, trap-soul\nhyperpop, Russian hip-hop, ambient\nhyperpop, Shibuya-kei\nhyperpop, South Asian club\nhyperpop, T-pop\nhyperpop, T-pop, video game music\nhyperpop, Thai pop, video game music\nhyperpop, UK garage\nhyperpop, UK garage, UK drill\nhyperpop, UK garage, breakbeat\nhyperpop, UK garage, chiptune\nhyperpop, UK garage, club\nhyperpop, UK garage, drum and bass\nhyperpop, UK garage, electronic\nhyperpop, UK garage, future bass\nhyperpop, UK garage, glitch\nhyperpop, UK garage, trap\nhyperpop, UK hardcore\nhyperpop, Vietnamese pop\nhyperpop, Vocaloid, electronic\nhyperpop, Vocaloid, trap\nhyperpop, alternative R&B\nhyperpop, alternative R&B, chiptune\nhyperpop, alternative R&B, global pop\nhyperpop, alternative rock, metalcore\nhyperpop, ambient\nhyperpop, ambient pop\nhyperpop, ambient trap\nhyperpop, ambient trap, electronic\nhyperpop, ambient, C-pop\nhyperpop, ambient, chiptune\nhyperpop, ambient, choral\nhyperpop, ambient, cinematic\nhyperpop, ambient, cloud rap\nhyperpop, ambient, dream pop\nhyperpop, ambient, drum and bass\nhyperpop, ambient, electronic\nhyperpop, ambient, emotional\nhyperpop, ambient, future bass\nhyperpop, ambient, lo-fi\nhyperpop, ambient, lo-fi hip hop\nhyperpop, ambient, trap\nhyperpop, anime theme\nhyperpop, anison, J-pop\nhyperpop, arabic pop, chiptune\nhyperpop, art pop\nhyperpop, art pop, C-pop\nhyperpop, art pop, drum and bass\nhyperpop, art pop, electronic\nhyperpop, art pop, experimental electronic\nhyperpop, art-pop, J-pop\nhyperpop, art-pop, digital hardcore\nhyperpop, art-pop, experimental electronic\nhyperpop, art-pop, experimental hip-hop\nhyperpop, art-pop, glitch\nhyperpop, art-pop, video game soundtrack\nhyperpop, artcore\nhyperpop, artcore, J-pop\nhyperpop, artcore, Japanese\nhyperpop, artcore, ambient\nhyperpop, artcore, cinematic\nhyperpop, artcore, denpa-kei\nhyperpop, artcore, glitch\nhyperpop, artcore, lo-fi\nhyperpop, baile funk\nhyperpop, baile funk, ambient\nhyperpop, baile funk, chiptune\nhyperpop, baile funk, electronic\nhyperpop, baile funk, funk carioca\nhyperpop, baile funk, futuristic\nhyperpop, baile funk, hardstyle\nhyperpop, baile funk, lo-fi\nhyperpop, ballad, cinematic\nhyperpop, baroque pop\nhyperpop, bedroom pop\nhyperpop, bedroom pop, lo-fi\nhyperpop, bedroom pop, lo-fi trap\nhyperpop, bhangra, Bollywood\nhyperpop, bhangra, electronic dance\nhyperpop, big beat\nhyperpop, big beat, breakbeat\nhyperpop, bitpop\nhyperpop, bitpop, electronic punk\nhyperpop, bitpop, hardstyle\nhyperpop, bitpop, shoegaze\nhyperpop, breakbeat\nhyperpop, breakbeat, artcore\nhyperpop, breakbeat, chiptune\nhyperpop, breakbeat, drum and bass\nhyperpop, breakbeat, electronic\nhyperpop, breakbeat, glitch\nhyperpop, breakbeat, shoegaze\nhyperpop, breakcore\nhyperpop, breakcore, J-core\nhyperpop, breakcore, J-pop\nhyperpop, breakcore, J-rock\nhyperpop, breakcore, Japanese\nhyperpop, breakcore, ambient\nhyperpop, breakcore, art pop\nhyperpop, breakcore, art-pop\nhyperpop, breakcore, chiptune\nhyperpop, breakcore, denpa-kei\nhyperpop, breakcore, drum and bass\nhyperpop, breakcore, electronic\nhyperpop, breakcore, experimental\nhyperpop, breakcore, experimental electronic\nhyperpop, breakcore, funkot\nhyperpop, breakcore, future bass\nhyperpop, breakcore, futuristic electronic\nhyperpop, breakcore, gabber\nhyperpop, breakcore, glitch\nhyperpop, breakcore, glitch-hop\nhyperpop, breakcore, glitch-pop\nhyperpop, breakcore, glitchcore\nhyperpop, breakcore, hardstyle\nhyperpop, breakcore, indie-pop\nhyperpop, breakcore, industrial\nhyperpop, breakcore, kawaii metal\nhyperpop, breakcore, lo-fi\nhyperpop, breakcore, math rock\nhyperpop, breakcore, meme music\nhyperpop, breakcore, nightcore\nhyperpop, breakcore, rap-metal\nhyperpop, breakcore, reggaeton\nhyperpop, breakcore, synth-pop\nhyperpop, breakcore, trap\nhyperpop, bubblegum bass\nhyperpop, bubblegum bass, C-pop\nhyperpop, bubblegum dance\nhyperpop, bubblegum dance, C-pop\nhyperpop, bubblegum pop\nhyperpop, bubblegum pop, C-pop\nhyperpop, bubblegum pop, J-pop\nhyperpop, bubblegum pop, K-pop\nhyperpop, bubblegum pop, T-pop\nhyperpop, bubblegum pop, V-pop\nhyperpop, bubblegum, C-pop\nhyperpop, chip-hop\nhyperpop, chiptune\nhyperpop, chiptune, Arabic children's\nhyperpop, chiptune, Bollywood\nhyperpop, chiptune, Brazilian funk\nhyperpop, chiptune, C-pop\nhyperpop, chiptune, Indian pop\nhyperpop, chiptune, Indonesian pop\nhyperpop, chiptune, J-core\nhyperpop, chiptune, J-pop\nhyperpop, chiptune, Japanese\nhyperpop, chiptune, K-pop\nhyperpop, chiptune, Middle Eastern electronic\nhyperpop, chiptune, Nintendocore\nhyperpop, chiptune, Russian\nhyperpop, chiptune, Russian pop\nhyperpop, chiptune, T-pop\nhyperpop, chiptune, Thai pop\nhyperpop, chiptune, V-pop\nhyperpop, chiptune, Vocaloid\nhyperpop, chiptune, ambient\nhyperpop, chiptune, anime\nhyperpop, chiptune, art pop\nhyperpop, chiptune, artcore\nhyperpop, chiptune, bitpop\nhyperpop, chiptune, breakbeat\nhyperpop, chiptune, breakcore\nhyperpop, chiptune, bubblegum pop\nhyperpop, chiptune, carioca\nhyperpop, chiptune, children's C-pop\nhyperpop, chiptune, children's pop\nhyperpop, chiptune, christmas\nhyperpop, chiptune, cloud rap\nhyperpop, chiptune, cumbia\nhyperpop, chiptune, dance-pop\nhyperpop, chiptune, denpa\nhyperpop, chiptune, denpa-kei\nhyperpop, chiptune, digicore\nhyperpop, chiptune, digital hardcore\nhyperpop, chiptune, drum and bass\nhyperpop, chiptune, dubstep\nhyperpop, chiptune, electro-pop\nhyperpop, chiptune, electroclash\nhyperpop, chiptune, electronic\nhyperpop, chiptune, electronic pop\nhyperpop, chiptune, emo rap\nhyperpop, chiptune, emo-rap\nhyperpop, chiptune, emo-trap\nhyperpop, chiptune, emotional pop\nhyperpop, chiptune, future bass\nhyperpop, chiptune, gabber\nhyperpop, chiptune, glitch\nhyperpop, chiptune, glitch-hop\nhyperpop, chiptune, glitch-pop\nhyperpop, chiptune, glitchcore\nhyperpop, chiptune, gospel\nhyperpop, chiptune, happy hardcore\nhyperpop, chiptune, hardcore\nhyperpop, chiptune, hardstyle\nhyperpop, chiptune, hip-hop\nhyperpop, chiptune, indie rock\nhyperpop, chiptune, industrial\nhyperpop, chiptune, kawaii\nhyperpop, chiptune, kawaii bass\nhyperpop, chiptune, kawaii future bass\nhyperpop, chiptune, kuthu\nhyperpop, chiptune, lo-fi\nhyperpop, chiptune, lo-fi hip hop\nhyperpop, chiptune, lo-fi hip-hop\nhyperpop, chiptune, lo-fi indie rock\nhyperpop, chiptune, math rock\nhyperpop, chiptune, meme music\nhyperpop, chiptune, metalcore\nhyperpop, chiptune, nightcore\nhyperpop, chiptune, pluggnb\nhyperpop, chiptune, pop-punk\nhyperpop, chiptune, pop-rap\nhyperpop, chiptune, pop-rock\nhyperpop, chiptune, rap\nhyperpop, chiptune, rap-rock\nhyperpop, chiptune, reggaeton\nhyperpop, chiptune, speedcore\nhyperpop, chiptune, synth-pop\nhyperpop, chiptune, trap\nhyperpop, chiptune, video game\nhyperpop, cinematic EDM\nhyperpop, cinematic electronic, trap\nhyperpop, cinematic synth\nhyperpop, cinematic trap\nhyperpop, cinematic, C-pop\nhyperpop, cinematic, Christmas\nhyperpop, cinematic, Mandopop\nhyperpop, cinematic, ambient\nhyperpop, cinematic, art pop\nhyperpop, cinematic, chiptune\nhyperpop, cinematic, dream pop\nhyperpop, cinematic, dreamy\nhyperpop, cinematic, electronic\nhyperpop, cinematic, glitch\nhyperpop, cinematic, indie-pop\nhyperpop, cinematic, lo-fi\nhyperpop, cinematic, pop-punk\nhyperpop, cinematic, rock\nhyperpop, cinematic, trap\nhyperpop, city pop, C-pop\nhyperpop, cloud rap\nhyperpop, cloud rap, C-pop\nhyperpop, cloud rap, Chinese electronic\nhyperpop, cloud rap, Chinese trap\nhyperpop, cloud rap, German cloud rap\nhyperpop, cloud rap, J-core\nhyperpop, cloud rap, J-pop\nhyperpop, cloud rap, K-pop\nhyperpop, cloud rap, Mandarin pop\nhyperpop, cloud rap, Mandopop\nhyperpop, cloud rap, alternative R&B\nhyperpop, cloud rap, ambient\nhyperpop, cloud rap, ambient trap\nhyperpop, cloud rap, anime\nhyperpop, cloud rap, atmospheric R&B\nhyperpop, cloud rap, chiptune\nhyperpop, cloud rap, chopped and screwed\nhyperpop, cloud rap, cinematic electronic\nhyperpop, cloud rap, cinematic trap\nhyperpop, cloud rap, dance-pop\nhyperpop, cloud rap, digicore\nhyperpop, cloud rap, dream pop\nhyperpop, cloud rap, dreamy\nhyperpop, cloud rap, electronic\nhyperpop, cloud rap, emo rap\nhyperpop, cloud rap, emo trap\nhyperpop, cloud rap, emo-trap\nhyperpop, cloud rap, funk\nhyperpop, cloud rap, future bass\nhyperpop, cloud rap, futuristic trap\nhyperpop, cloud rap, kawaii future bass\nhyperpop, cloud rap, lo-fi\nhyperpop, cloud rap, lo-fi hip hop\nhyperpop, cloud rap, synth pop\nhyperpop, cloud rap, synth-pop, future bass, ambient\nhyperpop, cloud rap, synthwave\nhyperpop, cloud rap, trap\nhyperpop, cloud rap, vaporwave\nhyperpop, cloud-rap, chiptune\nhyperpop, club\nhyperpop, club, dance-pop\nhyperpop, color bass, dubstep\nhyperpop, color bass, hardstyle\nhyperpop, comedy rock\nhyperpop, comedy, collage\nhyperpop, complextro, electro-pop\nhyperpop, complextro, kawaii future bass\nhyperpop, cumbia, chiptune\nhyperpop, cyberpunk, electronic\nhyperpop, dance-pop\nhyperpop, dance-pop, C-pop\nhyperpop, dance-pop, EDM\nhyperpop, dance-pop, J-pop\nhyperpop, dance-pop, K-pop\nhyperpop, dance-pop, South Indian film music\nhyperpop, dance-pop, T-pop\nhyperpop, dance-pop, children's music\nhyperpop, dance-pop, electro-pop\nhyperpop, dance-pop, electronic\nhyperpop, dance-pop, eurodance\nhyperpop, dance-pop, lo-fi\nhyperpop, dance-pop, vaporwave\nhyperpop, dancehall, UK garage\nhyperpop, dancehall, electronic\nhyperpop, dangdut koplo, novelty\nhyperpop, dark electro-pop\nhyperpop, dark pop, trap\nhyperpop, dark synth-pop, Russian vocal\nhyperpop, dark trap, kawaii pop\nhyperpop, deconstructed club\nhyperpop, denpa\nhyperpop, denpa, C-pop\nhyperpop, denpa, J-pop\nhyperpop, denpa, chiptune\nhyperpop, denpa-kei\nhyperpop, denpa-kei, J-pop\nhyperpop, denpa-kei, Japanese\nhyperpop, denpa-kei, breakcore\nhyperpop, denpa-kei, happy hardcore\nhyperpop, denpa-kei, piano ballad\nhyperpop, digicore\nhyperpop, digicore, Latin trap\nhyperpop, digicore, Mandopop\nhyperpop, digicore, anime soundtrack\nhyperpop, digicore, bitpop\nhyperpop, digicore, chiptune\nhyperpop, digicore, cloud rap\nhyperpop, digicore, emo rap\nhyperpop, digicore, emo-rap\nhyperpop, digicore, futuristic trap\nhyperpop, digicore, glitch\nhyperpop, digicore, glitchcore\nhyperpop, digicore, industrial\nhyperpop, digicore, lo-fi\nhyperpop, digicore, rage\nhyperpop, digicore, rage music\nhyperpop, digicore, reggaeton\nhyperpop, digicore, trap\nhyperpop, digital cumbia\nhyperpop, digital hardcore\nhyperpop, digital hardcore, J-core\nhyperpop, digital hardcore, breakcore\nhyperpop, digital hardcore, chiptune\nhyperpop, digital hardcore, metalcore\nhyperpop, digital hardcore, speedcore\nhyperpop, digital-punk\nhyperpop, dream pop\nhyperpop, dream pop, breakcore\nhyperpop, dream pop, lo-fi\nhyperpop, dream-pop\nhyperpop, dream-pop, C-pop\nhyperpop, dream-pop, cinematic\nhyperpop, dream-pop, lo-fi\nhyperpop, drill, Japanese rap\nhyperpop, drum and bass\nhyperpop, drum and bass, J-core\nhyperpop, drum and bass, J-pop\nhyperpop, drum and bass, J-rock\nhyperpop, drum and bass, K-pop\nhyperpop, drum and bass, ambient\nhyperpop, drum and bass, art pop\nhyperpop, drum and bass, artcore\nhyperpop, drum and bass, breakbeat\nhyperpop, drum and bass, breakcore\nhyperpop, drum and bass, chiptune\nhyperpop, drum and bass, futuristic electronic\nhyperpop, drum and bass, lo-fi\nhyperpop, drum and bass, rap\nhyperpop, dubstep, brostep\nhyperpop, dubstep, chiptune\nhyperpop, electro-house, funk-pop\nhyperpop, electro-pop\nhyperpop, electro-pop, 90s dance\nhyperpop, electro-pop, Bollywood\nhyperpop, electro-pop, C-pop\nhyperpop, electro-pop, J-pop\nhyperpop, electro-pop, K-pop\nhyperpop, electro-pop, Latin-infused\nhyperpop, electro-pop, baile funk\nhyperpop, electro-pop, chiptune\nhyperpop, electro-pop, cinematic\nhyperpop, electro-pop, club\nhyperpop, electro-pop, collage\nhyperpop, electro-pop, dubstep\nhyperpop, electro-pop, funk\nhyperpop, electro-pop, glitch\nhyperpop, electro-pop, hard dance\nhyperpop, electro-pop, nightcore\nhyperpop, electro-pop, pop\nhyperpop, electro-pop, quirky\nhyperpop, electro-pop, theatrical\nhyperpop, electro-pop, trap\nhyperpop, electro-pop, video game music\nhyperpop, electro-pop, vogue ballroom\nhyperpop, electro-punk, experimental electronic\nhyperpop, electro-rock, chiptune\nhyperpop, electro-swing, Japanese\nhyperpop, electroclash\nhyperpop, electronic\nhyperpop, electronic acapella\nhyperpop, electronic dance\nhyperpop, electronic dance music, J-pop\nhyperpop, electronic dance, Bollywood dance\nhyperpop, electronic dance, C-pop\nhyperpop, electronic dance, Indian film music\nhyperpop, electronic dance, Indian folk\nhyperpop, electronic dance, Italian pop\nhyperpop, electronic dance, Japanese\nhyperpop, electronic dance, Khmer pop\nhyperpop, electronic dance, Mandopop\nhyperpop, electronic dance, T-pop\nhyperpop, electronic dance, Thai pop\nhyperpop, electronic dance, Turkish pop\nhyperpop, electronic dance, V-pop\nhyperpop, electronic dance, cinematic\nhyperpop, electronic dance, trap\nhyperpop, electronic hip-hop\nhyperpop, electronic pop, chiptune\nhyperpop, electronic pop, contemporary R&B\nhyperpop, electronic pop, hip-hop\nhyperpop, electronic rock\nhyperpop, electronic rock, C-pop\nhyperpop, electronic rock, J-pop\nhyperpop, electronic rock, J-rock\nhyperpop, electronic rock, K-pop\nhyperpop, electronic rock, breakbeat\nhyperpop, electronic rock, chiptune\nhyperpop, electronic rock, emo\nhyperpop, electronic rock, glitch\nhyperpop, electronic rock, glitchcore\nhyperpop, electronic rock, industrial\nhyperpop, electronic rock, lo-fi\nhyperpop, electronic rock, metalcore\nhyperpop, electronic rock, nu-metal\nhyperpop, electronic rock, pop-punk\nhyperpop, electronic trap\nhyperpop, electronic trap, chiptune\nhyperpop, electronic trap, cinematic\nhyperpop, electronic trap, glitch-pop\nhyperpop, electronic trap, synth-pop\nhyperpop, electronic, C-pop\nhyperpop, electronic, Cantopop\nhyperpop, electronic, Christmas\nhyperpop, electronic, Hebrew vocal\nhyperpop, electronic, Indian folk\nhyperpop, electronic, Italian rap\nhyperpop, electronic, K-pop\nhyperpop, electronic, Latin pop\nhyperpop, electronic, North African\nhyperpop, electronic, Polish pop\nhyperpop, electronic, R&B\nhyperpop, electronic, Russian vocal\nhyperpop, electronic, Vocaloid\nhyperpop, electronic, ambient\nhyperpop, electronic, bilingual\nhyperpop, electronic, chiptune\nhyperpop, electronic, cinematic\nhyperpop, electronic, dream pop\nhyperpop, electronic, future bass\nhyperpop, electronic, glitch\nhyperpop, electronic, hardstyle\nhyperpop, electronic, hip-hop\nhyperpop, electronic, lo-fi\nhyperpop, electronic, pop\nhyperpop, electronic, trap\nhyperpop, electronic, world music\nhyperpop, electropop, J-pop\nhyperpop, electropop, bubblegum pop\nhyperpop, electropop, trap\nhyperpop, emo rap\nhyperpop, emo rap, Chinese trap\nhyperpop, emo rap, alternative R&B\nhyperpop, emo rap, ambient\nhyperpop, emo rap, atmospheric electronic\nhyperpop, emo rap, chiptune\nhyperpop, emo rap, cloud rap\nhyperpop, emo rap, digicore\nhyperpop, emo rap, dubstep\nhyperpop, emo rap, electronic\nhyperpop, emo rap, electronic rock\nhyperpop, emo rap, glitch\nhyperpop, emo rap, glitchcore\nhyperpop, emo rap, indie rock\nhyperpop, emo rap, lo-fi\nhyperpop, emo rap, synth-pop\nhyperpop, emo rap, synthwave\nhyperpop, emo rap, trap\nhyperpop, emo rap, vaporwave\nhyperpop, emo trap, C-pop\nhyperpop, emo trap, cloud rap\nhyperpop, emo, electronic rock\nhyperpop, emo-pop, chiptune\nhyperpop, emo-pop, indie rock\nhyperpop, emo-rap\nhyperpop, emo-rap, C-pop\nhyperpop, emo-rap, R&B\nhyperpop, emo-rap, ambient\nhyperpop, emo-rap, breakcore\nhyperpop, emo-rap, chiptune\nhyperpop, emo-rap, cloud-rap\nhyperpop, emo-rap, lo-fi\nhyperpop, emo-rap, pop-rap\nhyperpop, emo-rap, trap\nhyperpop, emo-trap\nhyperpop, emo-trap, ambient\nhyperpop, emo-trap, breakcore\nhyperpop, emo-trap, lo-fi\nhyperpop, emo-trap, reggaeton\nhyperpop, emo-trap, vaporwave\nhyperpop, eurodance, bubblegum pop\nhyperpop, eurodance, chiptune\nhyperpop, eurodance, happy hardcore\nhyperpop, experimental\nhyperpop, experimental R&B\nhyperpop, experimental bass\nhyperpop, experimental electronic\nhyperpop, experimental electronic, art pop\nhyperpop, experimental electronic, breakbeat\nhyperpop, experimental electronic, chiptune\nhyperpop, experimental electronic, glitch\nhyperpop, experimental electronic, operatic\nhyperpop, experimental hip-hop\nhyperpop, experimental hip-hop, glitch-hop\nhyperpop, experimental pop, breakbeat\nhyperpop, experimental pop, trap\nhyperpop, experimental reggaeton\nhyperpop, experimental reggaeton, glitch\nhyperpop, experimental, breakcore\nhyperpop, experimental, chiptune\nhyperpop, folk fusion\nhyperpop, footwork, UK garage\nhyperpop, funk carioca\nhyperpop, funk carioca, chiptune\nhyperpop, funk, Vocaloid\nhyperpop, funk, chiptune\nhyperpop, funk, electronic\nhyperpop, funk, glitch\nhyperpop, funk, vaporwave\nhyperpop, funk-rock, chiptune\nhyperpop, funkot, electronic dance\nhyperpop, future bass\nhyperpop, future bass, C-pop\nhyperpop, future bass, J-pop\nhyperpop, future bass, Japanese\nhyperpop, future bass, K-pop\nhyperpop, future bass, R&B\nhyperpop, future bass, ambient\nhyperpop, future bass, breakcore\nhyperpop, future bass, cloud rap\nhyperpop, future bass, electro-pop\nhyperpop, future bass, kawaii\nhyperpop, future bass, lo-fi\nhyperpop, future bass, lo-fi hip hop\nhyperpop, future bass, trap\nhyperpop, future bass, vaporwave\nhyperpop, future funk\nhyperpop, future funk, Japanese\nhyperpop, future funk, chiptune\nhyperpop, future trap, ambient\nhyperpop, futuristic R&B\nhyperpop, gabber, J-core\nhyperpop, gabber, J-pop\nhyperpop, gabber, chiptune\nhyperpop, gabber, denpa-kei\nhyperpop, gabber, electronic\nhyperpop, gabber, electropop\nhyperpop, gabber, glitch\nhyperpop, gabber, hardcore\nhyperpop, gabber, hardcore electronic\nhyperpop, gabber, hardstyle\nhyperpop, gabber, lo-fi\nhyperpop, gabber, nightcore\nhyperpop, gabber, speedcore\nhyperpop, glitch hop, cyberpunk\nhyperpop, glitch, ambient\nhyperpop, glitch, breakcore\nhyperpop, glitch, chiptune\nhyperpop, glitch, metalcore\nhyperpop, glitch-hop, Latin pop\nhyperpop, glitch-hop, breakbeat\nhyperpop, glitch-hop, electronic\nhyperpop, glitch-hop, trap\nhyperpop, glitch-pop, chiptune\nhyperpop, glitch-pop, electro-pop\nhyperpop, glitch-pop, electronic\nhyperpop, glitch-pop, electropop\nhyperpop, glitch-pop, lo-fi\nhyperpop, glitchcore, Japanese\nhyperpop, glitchcore, Latin urban\nhyperpop, glitchcore, chiptune\nhyperpop, glitchcore, digicore\nhyperpop, glitchcore, electronic trap\nhyperpop, glitchcore, emo trap\nhyperpop, glitchcore, hardstyle\nhyperpop, glitchcore, rage music\nhyperpop, glitchcore, trap\nhyperpop, glitchcore, trap metal\nhyperpop, happy hardcore\nhyperpop, happy hardcore, C-pop\nhyperpop, happy hardcore, Christian\nhyperpop, happy hardcore, J-core\nhyperpop, happy hardcore, J-pop\nhyperpop, happy hardcore, Japanese\nhyperpop, happy hardcore, K-pop\nhyperpop, happy hardcore, V-pop\nhyperpop, happy hardcore, breakcore\nhyperpop, happy hardcore, bubblegum C-pop\nhyperpop, happy hardcore, children's dance-pop\nhyperpop, happy hardcore, chiptune\nhyperpop, happy hardcore, electronic\nhyperpop, happy hardcore, gabber\nhyperpop, happy hardcore, hardstyle\nhyperpop, happy hardcore, lo-fi\nhyperpop, happy hardcore, metalcore\nhyperpop, happy hardcore, trance\nhyperpop, hard dance\nhyperpop, hard dance, J-pop\nhyperpop, hard dance, Russian electronic\nhyperpop, hard dance, electronic\nhyperpop, hardbass\nhyperpop, hardcore electronic, gabber\nhyperpop, hardcore hip-hop\nhyperpop, hardcore techno\nhyperpop, hardcore techno, J-pop\nhyperpop, hardcore techno, Japanese\nhyperpop, hardcore techno, chiptune\nhyperpop, hardcore techno, denpa-kei\nhyperpop, hardcore techno, gabber\nhyperpop, hardcore techno, hardstyle\nhyperpop, hardcore, gabber\nhyperpop, hardstyle\nhyperpop, hardstyle, Brazilian\nhyperpop, hardstyle, C-pop\nhyperpop, hardstyle, Chinese theatrical\nhyperpop, hardstyle, EDM\nhyperpop, hardstyle, J-core\nhyperpop, hardstyle, J-pop\nhyperpop, hardstyle, K-pop\nhyperpop, hardstyle, Russian\nhyperpop, hardstyle, Russian pop\nhyperpop, hardstyle, Thai pop\nhyperpop, hardstyle, V-pop\nhyperpop, hardstyle, ambient\nhyperpop, hardstyle, breakcore\nhyperpop, hardstyle, chiptune\nhyperpop, hardstyle, cinematic\nhyperpop, hardstyle, dubstep\nhyperpop, hardstyle, electro-pop\nhyperpop, hardstyle, electronic\nhyperpop, hardstyle, electronic rock\nhyperpop, hardstyle, experimental electronic\nhyperpop, hardstyle, future bass\nhyperpop, hardstyle, gabber\nhyperpop, hardstyle, glitch\nhyperpop, hardstyle, glitchcore\nhyperpop, hardstyle, lo-fi\nhyperpop, hardstyle, nightcore\nhyperpop, hardstyle, rapcore\nhyperpop, hardstyle, rave\nhyperpop, hardstyle, synth-pop\nhyperpop, hardstyle, trance\nhyperpop, hardstyle, trap\nhyperpop, hardstyle, vaporwave\nhyperpop, hip-hop\nhyperpop, hip-hop, V-pop\nhyperpop, hip-hop, cinematic\nhyperpop, hip-hop, electronic\nhyperpop, hip-hop, funk\nhyperpop, hip-hop, synth funk\nhyperpop, idol music, C-pop\nhyperpop, idol-pop, C-pop\nhyperpop, indie dance\nhyperpop, indie pop, breakbeat\nhyperpop, indie pop, electronic rock\nhyperpop, indie pop, math rock\nhyperpop, indie pop, post-rock\nhyperpop, indie rock, alternative rock\nhyperpop, indie-pop, chiptune\nhyperpop, industrial\nhyperpop, industrial dance\nhyperpop, industrial hip-hop, art-pop\nhyperpop, industrial metalcore, dubstep\nhyperpop, industrial trap\nhyperpop, industrial, EDM\nhyperpop, industrial, J-rock\nhyperpop, industrial, K-pop\nhyperpop, industrial, digital hardcore\nhyperpop, industrial, electronic\nhyperpop, industrial, electronic hip-hop\nhyperpop, industrial, electronic rock\nhyperpop, industrial, experimental electronic\nhyperpop, industrial, glitch\nhyperpop, industrial, lo-fi\nhyperpop, industrial, nu-metal\nhyperpop, industrial, trap\nhyperpop, j-pop, chiptune\nhyperpop, j-pop, math rock\nhyperpop, jazz-fusion, Japanese art-pop\nhyperpop, jazz-fusion, progressive rock\nhyperpop, jersey club\nhyperpop, jungle\nhyperpop, kawaii\nhyperpop, kawaii bass, C-pop\nhyperpop, kawaii future bass\nhyperpop, kawaii future bass, C-pop\nhyperpop, kawaii future bass, V-pop\nhyperpop, kawaii, C-pop\nhyperpop, kawaii, chiptune\nhyperpop, kuthu, EDM\nhyperpop, kuthu, gaana\nhyperpop, latin pop, chiptune\nhyperpop, latin trap\nhyperpop, latin, chiptune\nhyperpop, laïko\nhyperpop, liquid drum and bass\nhyperpop, lo-fi R&B\nhyperpop, lo-fi R&B, dream-pop\nhyperpop, lo-fi bedroom pop\nhyperpop, lo-fi emo-rap\nhyperpop, lo-fi hip hop\nhyperpop, lo-fi hip hop, J-pop\nhyperpop, lo-fi hip hop, K-rap\nhyperpop, lo-fi hip hop, Mandopop\nhyperpop, lo-fi hip hop, chiptune\nhyperpop, lo-fi hip hop, digicore\nhyperpop, lo-fi hip hop, emo rap\nhyperpop, lo-fi hip hop, k-pop\nhyperpop, lo-fi hip-hop, cinematic\nhyperpop, lo-fi indie pop\nhyperpop, lo-fi indie rock\nhyperpop, lo-fi trap, nightcore\nhyperpop, lo-fi, Chinese trap\nhyperpop, lo-fi, French rap\nhyperpop, lo-fi, K-pop\nhyperpop, lo-fi, ambient\nhyperpop, lo-fi, bitpop\nhyperpop, lo-fi, chiptune\nhyperpop, lo-fi, cinematic\nhyperpop, lo-fi, digicore\nhyperpop, lo-fi, emo-rap\nhyperpop, lo-fi, experimental\nhyperpop, lo-fi, glitchcore\nhyperpop, lo-fi, pluggnb\nhyperpop, lo-fi, trap\nhyperpop, lo-fi, trap metal\nhyperpop, lo-fi, vaporwave\nhyperpop, mandopop, lo-fi R&B\nhyperpop, mashup, experimental\nhyperpop, math rock, cinematic\nhyperpop, melodic trap\nhyperpop, melodic trap, C-pop\nhyperpop, meme rap\nhyperpop, meme-core, chiptune\nhyperpop, meme-rap, phonk\nhyperpop, metalcore\nhyperpop, metalcore, J-pop\nhyperpop, metalcore, chiptune\nhyperpop, metalcore, trap\nhyperpop, moombahton, trap\nhyperpop, musical theater\nhyperpop, neo-soul\nhyperpop, neo-soul, chiptune\nhyperpop, neo-soul, lo-fi\nhyperpop, neurofunk\nhyperpop, new wave\nhyperpop, nightcore\nhyperpop, nightcore, C-pop\nhyperpop, nightcore, J-core\nhyperpop, nightcore, J-pop\nhyperpop, nightcore, Latin dance\nhyperpop, nightcore, Russian\nhyperpop, nightcore, Russian bubblegum pop\nhyperpop, nightcore, Spanish-style\nhyperpop, nightcore, T-pop\nhyperpop, nightcore, Thai pop\nhyperpop, nightcore, V-pop\nhyperpop, nightcore, ambient\nhyperpop, nightcore, baile funk\nhyperpop, nightcore, bubblegum bass\nhyperpop, nightcore, bubblegum dance-pop\nhyperpop, nightcore, chiptune\nhyperpop, nightcore, cloud rap\nhyperpop, nightcore, dance-pop\nhyperpop, nightcore, digicore\nhyperpop, nightcore, digital hardcore\nhyperpop, nightcore, electronic\nhyperpop, nightcore, electronic dance\nhyperpop, nightcore, electronic pop\nhyperpop, nightcore, electropop\nhyperpop, nightcore, gabber\nhyperpop, nightcore, happy hardcore\nhyperpop, nightcore, hard dance\nhyperpop, nightcore, hardstyle\nhyperpop, nightcore, reggaeton\nhyperpop, nightcore, speedcore\nhyperpop, nightcore, trap\nhyperpop, nintendocore\nhyperpop, nintendocore, ambient\nhyperpop, nintendocore, industrial metal\nhyperpop, nintendocore, metalcore\nhyperpop, noise rock\nhyperpop, novelty, meme culture\nhyperpop, nu-metal, chiptune\nhyperpop, piseiro\nhyperpop, pluggnb\nhyperpop, pluggnb, Brazilian funk\nhyperpop, pluggnb, Latin pop\nhyperpop, pluggnb, ambient\nhyperpop, pluggnb, ambient trap\nhyperpop, pluggnb, chiptune\nhyperpop, pluggnb, cloud rap\nhyperpop, pluggnb, cloud-rap\nhyperpop, pluggnb, lo-fi\nhyperpop, pluggnb, minimalist synth\nhyperpop, pluggnb, reggaeton\nhyperpop, pluggnb, trap\nhyperpop, pluggnb, vaporwave\nhyperpop, pop-R&B, cinematic\nhyperpop, pop-punk\nhyperpop, pop-punk, Christian\nhyperpop, pop-punk, K-pop\nhyperpop, pop-punk, Mandopop\nhyperpop, pop-punk, alternative rock\nhyperpop, pop-punk, chiptune\nhyperpop, pop-punk, cinematic\nhyperpop, pop-punk, easycore\nhyperpop, pop-punk, electronic\nhyperpop, pop-punk, electronic rock\nhyperpop, pop-punk, electronicore\nhyperpop, pop-punk, emo-rock\nhyperpop, pop-punk, indie rock\nhyperpop, pop-punk, metalcore\nhyperpop, pop-punk, trap metal\nhyperpop, pop-rock\nhyperpop, pop-rock, emotional synth\nhyperpop, pop-rock, lo-fi\nhyperpop, pop-trap\nhyperpop, rage\nhyperpop, rage beat, lo-fi\nhyperpop, rage music\nhyperpop, rage music, digicore\nhyperpop, rage music, lo-fi\nhyperpop, rage music, trap\nhyperpop, rage trap\nhyperpop, rage, chiptune\nhyperpop, rage, cinematic\nhyperpop, rage, pluggnb\nhyperpop, rage, trap\nhyperpop, rage-trap, electronic\nhyperpop, rap-rock, chiptune\nhyperpop, rave, ambient\nhyperpop, reggae, chiptune\nhyperpop, reggaeton\nhyperpop, reggaeton, J-pop\nhyperpop, reggaeton, Latin pop\nhyperpop, reggaeton, Latin trap\nhyperpop, reggaeton, R&B\nhyperpop, reggaeton, ambient\nhyperpop, reggaeton, chiptune\nhyperpop, reggaeton, electro-pop\nhyperpop, reggaeton, electronic\nhyperpop, reggaeton, moombahton\nhyperpop, reggaeton, nightcore\nhyperpop, reggaeton, trap\nhyperpop, reggaeton, vaporwave\nhyperpop, regional Mexican\nhyperpop, rock, lo-fi hip hop\nhyperpop, shoegaze, emo-rap\nhyperpop, speedcore, J-pop\nhyperpop, speedcore, Japanese\nhyperpop, speedcore, chiptune\nhyperpop, speedcore, gabber\nhyperpop, speedcore, glitchcore\nhyperpop, speedcore, metalcore\nhyperpop, surf rock, Hawaiian\nhyperpop, synth-funk, Japanese\nhyperpop, synth-funk, R&B\nhyperpop, synth-pop\nhyperpop, synth-pop, breakbeat\nhyperpop, synth-pop, chiptune\nhyperpop, synth-pop, cinematic\nhyperpop, synth-pop, comedy\nhyperpop, synth-pop, dream pop\nhyperpop, synth-pop, electronic dance\nhyperpop, synth-pop, electronic rock\nhyperpop, synth-pop, future bass\nhyperpop, synth-pop, glitch\nhyperpop, synth-pop, industrial\nhyperpop, synth-pop, shoegaze\nhyperpop, synth-pop, trap\nhyperpop, synth-pop, world music\nhyperpop, synth-rock, chiptune\nhyperpop, synthpop, lo-fi\nhyperpop, trance, C-pop\nhyperpop, trance, EDM\nhyperpop, trance, J-pop\nhyperpop, trance, J-rock\nhyperpop, trance, chiptune\nhyperpop, trance, cinematic\nhyperpop, trance, drum and bass\nhyperpop, trance, hard dance\nhyperpop, trance, nightcore\nhyperpop, trance, world music\nhyperpop, trancecore\nhyperpop, trap\nhyperpop, trap R&B\nhyperpop, trap R&B, Chinese electronic\nhyperpop, trap R&B, lo-fi\nhyperpop, trap metal\nhyperpop, trap metal, J-rock\nhyperpop, trap metal, ambient\nhyperpop, trap metal, chiptune\nhyperpop, trap metal, dubstep\nhyperpop, trap metal, electronic rock\nhyperpop, trap metal, emo rap\nhyperpop, trap metal, emo-rap\nhyperpop, trap metal, gabber\nhyperpop, trap metal, glitch\nhyperpop, trap metal, glitchcore\nhyperpop, trap metal, lo-fi\nhyperpop, trap metal, lo-fi indie rock\nhyperpop, trap metal, theatrical rock\nhyperpop, trap, Brazilian funk\nhyperpop, trap, C-Rap\nhyperpop, trap, C-pop\nhyperpop, trap, Cantopop\nhyperpop, trap, Chinese electronic\nhyperpop, trap, Chinese pop\nhyperpop, trap, Chinese rap\nhyperpop, trap, Christmas\nhyperpop, trap, EDM\nhyperpop, trap, German\nhyperpop, trap, J-pop\nhyperpop, trap, J-rap\nhyperpop, trap, K-pop\nhyperpop, trap, Latin pop\nhyperpop, trap, Latin trap\nhyperpop, trap, Mandarin rap\nhyperpop, trap, Mandopop\nhyperpop, trap, Middle Eastern\nhyperpop, trap, Polish rap\nhyperpop, trap, R&B\nhyperpop, trap, Russian pop\nhyperpop, trap, Russian rap\nhyperpop, trap, UK drill\nhyperpop, trap, UK garage\nhyperpop, trap, acoustic\nhyperpop, trap, alternative R&B\nhyperpop, trap, alternative pop\nhyperpop, trap, ambient\nhyperpop, trap, ancient style\nhyperpop, trap, anime\nhyperpop, trap, art pop\nhyperpop, trap, baroque\nhyperpop, trap, baroque pop\nhyperpop, trap, bilingual\nhyperpop, trap, bilingual pop\nhyperpop, trap, chiptune\nhyperpop, trap, cinematic\nhyperpop, trap, cloud rap\nhyperpop, trap, club\nhyperpop, trap, comedic\nhyperpop, trap, cyberpunk\nhyperpop, trap, dancehall\nhyperpop, trap, dark electro-pop\nhyperpop, trap, deathcore\nhyperpop, trap, digicore\nhyperpop, trap, electro-pop\nhyperpop, trap, electronic\nhyperpop, trap, electronic pop\nhyperpop, trap, electronic rock\nhyperpop, trap, emo\nhyperpop, trap, emo rap\nhyperpop, trap, emo-rap\nhyperpop, trap, emotional pop\nhyperpop, trap, ethereal pop\nhyperpop, trap, experimental\nhyperpop, trap, experimental R&B\nhyperpop, trap, experimental bass\nhyperpop, trap, experimental electronic\nhyperpop, trap, folk\nhyperpop, trap, future bass\nhyperpop, trap, gaming music\nhyperpop, trap, glitch\nhyperpop, trap, glitch-hop\nhyperpop, trap, glitch-pop\nhyperpop, trap, glitchcore\nhyperpop, trap, hardstyle\nhyperpop, trap, hardwave\nhyperpop, trap, hip-hop\nhyperpop, trap, indie rock\nhyperpop, trap, industrial\nhyperpop, trap, k-pop\nhyperpop, trap, kawaii\nhyperpop, trap, lo-fi\nhyperpop, trap, lo-fi hip hop\nhyperpop, trap, lo-fi jazz\nhyperpop, trap, melancholic\nhyperpop, trap, nightcore\nhyperpop, trap, nu-metal\nhyperpop, trap, pluggnb\nhyperpop, trap, pop-rock\nhyperpop, trap, psychedelic hip-hop\nhyperpop, trap, rage\nhyperpop, trap, rage music\nhyperpop, trap, reggaeton\nhyperpop, trap, rock\nhyperpop, trap, synth-pop\nhyperpop, trap, synthwave\nhyperpop, trap, techno\nhyperpop, trap, vaporwave\nhyperpop, trap, video game\nhyperpop, trap, video game music\nhyperpop, trap-R&B\nhyperpop, trap-R&B, jazz\nhyperpop, trap-pop, pop-rock\nhyperpop, turbo-folk\nhyperpop, vaporwave, baile funk\nhyperpop, vaporwave, chiptune\nhyperpop, vaporwave, cloud rap\nhyperpop, vaporwave, digicore\nhyperpop, vaporwave, drum and bass\nhyperpop, vaporwave, glitch\nhyperpop, vaporwave, pluggnb\nhyperpop, vaporwave, trap\nhyperpop, video game\nhyperpop, video game music\nhyperpop, witch house, trap\nhyperpop, world music, ambient\nhyperpop, world music, electronic\nhyperpop-punk\nhyperpop-punk chiptune rock\nhyperpop-punk digital hardcore\nhyperpop-punk easycore\nhyperpop-punk electronic rock\nhyperpop-punk electronicore\nhyperpop-punk emo-rap\nhyperpop-punk emo-rock\nhyperpop-punk metalcore\nhyperpop-punk nintendocore\nhyperpop-punk, J-rock\nhyperpop-punk, Nintendocore\nhyperpop-punk, Nintendocore, metalcore\nhyperpop-punk, easycore\nhyperpop-punk, electronic rock\nhyperpop-punk, kawaii metal\nhyperpop-punk, pop-punk\nhyperpop-punk, theatrical cabaret, electronic\nhypnotic Indian folk\nhypnotic R&B\nhypnotic acapella\nhypnotic ambient\nhypnotic deep house\nhypnotic electronic\nhypnotic electronica\nhypnotic folk\nhypnotic groove\nhypnotic hip-hop\nhypnotic house\nhypnotic percussion\nhypnotic pop\nhypnotic techno\nhypnotic trap\nhǎnmài\nhǎnmài EDM\nhǎnmài electronic\nhǎnmài hardstyle\nhǎnmài hip hop\nhǎnmài, Eurodance\nhǎnmài, Eurodance, electronic\nhǎnmài, Eurodance, hip hop\nhǎnmài, Eurodance, hip-hop\nhǎnmài, Eurodance, trap\nhǎnmài, dance, electronic\nhǎnmài, electronic, Chinese hip hop\nhǎnmài, electronic, Eurodance\nhǎnmài, electronic, dance\nhǎnmài, electronic, hip hop\nhǎnmài, electronic, rap\nhǎnmài, electronic, synth-pop\nhǎnmài, hard dance, electronic\nhǎnmài, hard dance, synth-pop\nhǎnmài, hardstyle\nhǎnmài, hardstyle, Chinese rap\nhǎnmài, hardstyle, electronic\nhǎnmài, hardstyle, synth-pop\nhǎnmài, hardstyle, trance\nical Beremusiek\nidol pop\nidol pop, C-pop\nidol pop, anime theme, C-pop\nidol pop, chiptune, denpa-kei\nidol pop, electronic\nidol-pop\nimpressionist classical jazz\nimpressionist jazz\nimpressionist piano\nimpressionistic classical\nimpressionistic jazz\nimpressionistic piano\nimprovisational jazz\nimprovisational piano\nindian folk rock\nindian metal\nindie\nindie C-pop\nindie C-pop emo rap\nindie C-pop lo-fi\nindie Christian\nindie J-pop\nindie J-rock\nindie Latin pop\nindie MPB\nindie R&B\nindie R&B bedroom pop\nindie R&B hip-hop\nindie R&B lo-fi\nindie R&B lo-fi hip hop\nindie R&B lo-fi hip-hop\nindie R&B neo-soul\nindie R&B trap\nindie R&B, emo rap, lo-fi hip-hop\nindie R&B, hyperpop\nindie a cappella\nindie ambient\nindie art-pop\nindie ballad\nindie ballad jazz\nindie ballad post-rock\nindie ballad, alternative rock\nindie ballad, future bass\nindie ballad, indie rock\nindie ballad, jazz, melancholic\nindie ballad, lounge jazz, vintage\nindie ballad, post-rock\nindie ballad, rock, cinematic\nindie ballad, shoegaze, post-hardcore\nindie ballad, shoegaze, post-rock\nindie blues\nindie blues-rock\nindie chanson\nindie classical\nindie dance\nindie dance Afro-Latin\nindie dance French\nindie dance Latin\nindie dance chillwave\nindie dance chiptune\nindie dance cumbia surf rock\nindie dance electro\nindie dance electro-house\nindie dance electro-pop\nindie dance electropop\nindie dance funk\nindie dance funk disco\nindie dance funk nu-disco\nindie dance funk-rock\nindie dance funk-rock nu-disco\nindie dance future bass\nindie dance lo-fi\nindie dance nu-disco\nindie dance post-punk\nindie dance progressive house\nindie dance synth-pop\nindie dance synth-pop chiptune\nindie dance synth-pop dream pop\nindie dance synth-pop dream-pop\nindie dance synth-pop funk\nindie dance synth-pop noise rock\nindie dance trap\nindie dance tropical house\nindie dance, 80s new wave\nindie dance, Italo disco, synth-pop\nindie dance, Italo-disco\nindie dance, Latin, psychedelic\nindie dance, alternative R&B\nindie dance, chiptune, bitpop\nindie dance, chiptune, hyperpop\nindie dance, chiptune, synth-pop\nindie dance, hyperpop\nindie dance, new wave, post-punk\nindie dance, nu-disco, synth-pop\nindie dance, psychedelic pop\nindie dance, psychedelic, Latin fusion\nindie dance, synth pop, Latin pop\nindie dance, synth-pop\nindie dance, synth-pop, French touch\nindie dance, synth-pop, Italo disco\nindie dance, synth-pop, electroclash\nindie dance, synth-pop, nu-disco\nindie dance, synth-pop, reggaeton\nindie dance, trap, chiptune\nindie dance, world music, hypnotic\nindie dance-pop\nindie dance-punk\nindie dance-rock\nindie deep house\nindie dream pop\nindie dream pop, alternative rock\nindie dream-pop\nindie dream-pop shoegaze\nindie electronic\nindie electronic Latin\nindie electronic alternative rock\nindie electronic chiptune\nindie electronic chiptune synth-pop\nindie electronic dream pop\nindie electronic future bass\nindie electronic glitch-hop\nindie electronic lo-fi\nindie electronic pop\nindie electronic pop-punk\nindie electronic synth-pop\nindie electronic trip-hop\nindie electronic, chiptune, bedroom pop\nindie electronic, chiptune, bitpop\nindie electronic, chiptune, hyperpop\nindie electronic, hyperpop\nindie electronica\nindie film score\nindie folk\nindie folk Latin\nindie folk R&B\nindie folk acoustic pop\nindie folk acoustic rock\nindie folk alt-rock\nindie folk alternative rock\nindie folk ambient\nindie folk ambient pop\nindie folk ambient rock\nindie folk art rock\nindie folk art-rock\nindie folk blues\nindie folk bossa nova\nindie folk breakcore\nindie folk chamber pop\nindie folk chillwave\nindie folk country\nindie folk country-pop\nindie folk dream pop\nindie folk dream pop post-rock\nindie folk dream-pop\nindie folk dream-pop shoegaze\nindie folk emo\nindie folk emo rock\nindie folk emo-folk\nindie folk emo-rap\nindie folk emo-rock\nindie folk fusion\nindie folk future bass\nindie folk garage rock\nindie folk hip hop\nindie folk hip-hop\nindie folk jazz\nindie folk jazz cabaret\nindie folk jazz lounge\nindie folk lo-fi\nindie folk lo-fi R&B\nindie folk lo-fi hip hop\nindie folk lo-fi hip-hop\nindie folk lounge jazz\nindie folk mariachi\nindie folk noise rock\nindie folk noise-rock\nindie folk pop\nindie folk pop-punk\nindie folk pop-rock\nindie folk post-hardcore\nindie folk post-rock\nindie folk power-pop\nindie folk progressive rock\nindie folk psychedelic\nindie folk psychedelic folk-rock\nindie folk psychedelic rock\nindie folk punk\nindie folk punk jazz\nindie folk rap\nindie folk reggae\nindie folk rock\nindie folk shoegaze\nindie folk soul\nindie folk tango\nindie folk techno\nindie folk trap\nindie folk trip-hop synth-pop\nindie folk tropical\nindie folk waltz\nindie folk world music\nindie folk worldbeat\nindie folk worship\nindie folk, Christian rock\nindie folk, Christmas pop, Celtic\nindie folk, European cabaret\nindie folk, Latin acoustic pop\nindie folk, Latin pop\nindie folk, Latin rock, lo-fi\nindie folk, MPB\nindie folk, MPB, alternative rock\nindie folk, alt-rock\nindie folk, alt-rock, blues-rock\nindie folk, alt-rock, cinematic\nindie folk, alt-rock, noise rock\nindie folk, alt-rock, post-hardcore\nindie folk, alt-rock, post-rock\nindie folk, alt-rock, shoegaze\nindie folk, alternative rock\nindie folk, alternative rock, blues-rock\nindie folk, alternative rock, garage rock\nindie folk, alternative rock, metalcore\nindie folk, alternative rock, noise rock\nindie folk, alternative rock, post-rock\nindie folk, alternative rock, punk rock\nindie folk, alternative rock, shoegaze\nindie folk, ambient pop\nindie folk, ambient, Chinese experimental\nindie folk, ambient, electronic\nindie folk, art rock\nindie folk, art-pop\nindie folk, blues-rock\nindie folk, breakcore\nindie folk, cabaret, chanson\nindie folk, chamber pop\nindie folk, chiptune, South Indian\nindie folk, cinematic\nindie folk, cinematic pop, Chinese traditional\nindie folk, cinematic pop, Indonesian pop\nindie folk, cinematic rock\nindie folk, cinematic rock, Mandarin ballad\nindie folk, cinematic rock, symphonic rock\nindie folk, cinematic rock, synth-pop\nindie folk, cinematic, Indian classical\nindie folk, cinematic, ambient\nindie folk, cinematic, big band\nindie folk, cinematic, garage rock\nindie folk, cinematic, power ballad\nindie folk, cinematic, world music\nindie folk, conscious hip-hop, choral art song\nindie folk, dark indie rock\nindie folk, dream pop, electronic\nindie folk, dream-pop, indie rock\nindie folk, dream-pop, lo-fi hip-hop\nindie folk, dream-pop, shoegaze\nindie folk, electronic\nindie folk, electronic pop\nindie folk, electronic rock\nindie folk, electronic, Chinese lo-fi\nindie folk, electronic, Swiss hip hop\nindie folk, electronic, ambient\nindie folk, electronic, experimental\nindie folk, electronic, hip-hop\nindie folk, electronic, trap\nindie folk, electronic, world music\nindie folk, electronicore, post-hardcore\nindie folk, emo rock\nindie folk, emotional rock\nindie folk, ethereal wave\nindie folk, experimental indie pop\nindie folk, experimental, ambient\nindie folk, folk-punk\nindie folk, folk-punk, comedy rock\nindie folk, folk-rock, indie rock\nindie folk, funk pop\nindie folk, funk rock\nindie folk, future bass\nindie folk, garage punk, psychedelic rock\nindie folk, garage punk, punk rock\nindie folk, garage rock\nindie folk, garage rock, psychedelic\nindie folk, garage rock, punk\nindie folk, gospel rock\nindie folk, grunge\nindie folk, grunge, alternative rock\nindie folk, hard rock\nindie folk, hip-hop\nindie folk, hip-hop, ambient\nindie folk, holiday pop\nindie folk, hyperpop\nindie folk, indie electronic\nindie folk, indie pop\nindie folk, indie rock\nindie folk, indie rock, German rap\nindie folk, indie rock, alternative rock\nindie folk, indie rock, free jazz\nindie folk, indie rock, funk\nindie folk, indie rock, funk pop\nindie folk, indie rock, garage rock\nindie folk, indie rock, noise rock\nindie folk, indie rock, nu-disco\nindie folk, indie rock, pop-punk\nindie folk, indie rock, post-hardcore\nindie folk, indie rock, post-rock\nindie folk, indie rock, psychedelic rock\nindie folk, indie rock, shoegaze\nindie folk, industrial hip-hop\nindie folk, industrial rock\nindie folk, lo-fi chiptune\nindie folk, lo-fi electronic\nindie folk, lo-fi folk-punk\nindie folk, lo-fi garage rock\nindie folk, lo-fi hip hop\nindie folk, lo-fi hip hop, indie R&B\nindie folk, lo-fi hip-hop\nindie folk, lo-fi hip-hop, rock\nindie folk, lo-fi, alternative rock\nindie folk, lo-fi, hyperpop\nindie folk, noise rock\nindie folk, orchestral rock\nindie folk, orchestral rock, synth-pop\nindie folk, pop, R&B, rap\nindie folk, pop-punk\nindie folk, pop-punk, emo\nindie folk, pop-punk, glitch\nindie folk, pop-rock\nindie folk, post-hardcore\nindie folk, post-hardcore, shoegaze\nindie folk, post-punk\nindie folk, post-punk, lo-fi\nindie folk, post-rock\nindie folk, post-rock, C-pop\nindie folk, post-rock, Mandarin indie\nindie folk, post-rock, ambient\nindie folk, post-rock, indie rock\nindie folk, post-rock, post-punk\nindie folk, post-rock, shoegaze\nindie folk, power-pop\nindie folk, progressive house\nindie folk, psychedelic indie rock\nindie folk, psychedelic rock\nindie folk, psychedelic rock, anthemic rock\nindie folk, psychedelic rock, funk rock\nindie folk, psychedelic rock, noise rock\nindie folk, psychedelic rock, theatrical rock\nindie folk, punk rock\nindie folk, raw blues\nindie folk, reggaeton, ambient\nindie folk, rock\nindie folk, rock, Korean ballad\nindie folk, rock, Swedish\nindie folk, shoegaze\nindie folk, shoegaze, alternative rock\nindie folk, shoegaze, experimental\nindie folk, shoegaze, indie rock\nindie folk, shoegaze, noise rock\nindie folk, shoegaze, post-hardcore\nindie folk, shoegaze, post-rock\nindie folk, spoken word, hip hop\nindie folk, synth-pop\nindie folk, trap, ambient\nindie folk, trap, ghazal\nindie folk, trip-hop\nindie folk, trip-hop, world music\nindie folk, world fusion\nindie folk, world music, smooth jazz\nindie folk-jazz\nindie folk-pop\nindie folk-punk\nindie folk-rap\nindie folk-rock\nindie folk-rock post-rock\nindie folk-rock progressive rock\nindie folk-rock rap-rock\nindie folk-rock shoegaze\nindie funk\nindie funk neo-soul\nindie funk rock\nindie funk soul\nindie funk, hip-hop\nindie funk, soulful indie rock\nindie funk-pop\nindie funk-rock\nindie fusion\nindie future bass\nindie game music\nindie game soundtrack\nindie gospel\nindie guitar\nindie hip hop\nindie hip-hop\nindie house\nindie instrumental\nindie jazz\nindie jazz bossa nova\nindie jazz-pop\nindie jazz-rock\nindie lo-fi\nindie lo-fi hip hop\nindie pop\nindie pop 80s\nindie pop 80s Southeast Asian\nindie pop 90s R&B\nindie pop 90s alternative\nindie pop Afro-Caribbean\nindie pop Afro-Latin\nindie pop Afro-pop Latin\nindie pop Afrobeat\nindie pop Americana\nindie pop Bollywood\nindie pop C-pop\nindie pop C-pop emo rap\nindie pop C-pop lo-fi\nindie pop Christian\nindie pop French chanson\nindie pop French hip-hop\nindie pop French pop\nindie pop J-pop\nindie pop J-rock\nindie pop K-pop\nindie pop K-pop ballad\nindie pop Latin\nindie pop MPB\nindie pop Mandopop\nindie pop Nordic folk\nindie pop R&B\nindie pop R&B Afrobeats\nindie pop R&B dancehall\nindie pop R&B hip-hop\nindie pop R&B lo-fi\nindie pop R&B lo-fi hip-hop\nindie pop R&B neo-soul\nindie pop R&B trap\nindie pop UK hip-hop\nindie pop a cappella\nindie pop acoustic\nindie pop acoustic folk\nindie pop acoustic pop\nindie pop afrobeat\nindie pop alt-country\nindie pop alt-pop\nindie pop alt-rock\nindie pop alternative R&B\nindie pop alternative hip-hop\nindie pop alternative rock\nindie pop ambient\nindie pop ambient pop\nindie pop americana\nindie pop art pop\nindie pop art pop bossa nova\nindie pop art pop world music\nindie pop art rock\nindie pop art rock experimental\nindie pop art-pop\nindie pop baroque pop\nindie pop bedroom pop\nindie pop blues\nindie pop blues jazz\nindie pop blues lounge jazz\nindie pop blues-rock\nindie pop blues-rock lounge\nindie pop bossa nova\nindie pop bossa nova MPB\nindie pop bossa nova city pop\nindie pop bossa nova cool jazz\nindie pop bossa nova funk\nindie pop bossa nova lo-fi\nindie pop bossa nova lounge\nindie pop bossa nova lounge jazz\nindie pop bossa nova mpb\nindie pop bossa nova neo-soul\nindie pop bossa nova reggae\nindie pop cabaret\nindie pop cabaret jazz\nindie pop cabaret lounge\nindie pop cabaret lounge jazz\nindie pop cabaret swing\nindie pop cabaret tango\nindie pop chamber pop\nindie pop chanson\nindie pop chill R&B\nindie pop chillwave\nindie pop chiptune\nindie pop chiptune J-pop\nindie pop chiptune art-pop\nindie pop chiptune bedroom pop\nindie pop chiptune cumbia\nindie pop chiptune electropop\nindie pop chiptune funk\nindie pop chiptune hip-hop\nindie pop chiptune hyperpop\nindie pop chiptune j-pop\nindie pop chiptune j-rock\nindie pop chiptune jangle pop\nindie pop chiptune musical theater\nindie pop chiptune pop-punk\nindie pop chiptune ska\nindie pop chiptune surf rock\nindie pop chiptune synth-pop\nindie pop cinematic\nindie pop city pop\nindie pop city pop R&B\nindie pop city pop bossa nova\nindie pop city pop dream pop\nindie pop city pop folk\nindie pop city pop funk\nindie pop city pop jazz\nindie pop city pop jazz fusion\nindie pop city pop jazz-funk\nindie pop city pop jazz-fusion\nindie pop city pop lounge\nindie pop city pop lounge jazz\nindie pop city pop math rock\nindie pop city pop neo-soul\nindie pop city pop psychedelic\nindie pop city pop surf rock\nindie pop city-pop\nindie pop country\nindie pop country swing\nindie pop country-folk\nindie pop country-pop\nindie pop country-rock\nindie pop cumbia\nindie pop cumbia-reggaeton\nindie pop cumbia-rock\nindie pop dance-pop\nindie pop dance-punk\nindie pop deep house\nindie pop disco\nindie pop disco funk\nindie pop doo-wop\nindie pop downtempo\nindie pop dream pop\nindie pop dream pop bossa nova\nindie pop dream pop emo rap\nindie pop dream pop hyperpop\nindie pop dream pop shoegaze\nindie pop dream-pop\nindie pop electro-funk\nindie pop electro-pop\nindie pop electronic\nindie pop electronic R&B\nindie pop electronic rock\nindie pop electronic soul\nindie pop electronic world fusion\nindie pop electropop\nindie pop electropop alternative R&B\nindie pop electropop hyperpop\nindie pop emo\nindie pop emo alternative R&B\nindie pop emo alternative rock\nindie pop emo chiptune\nindie pop emo electronic\nindie pop emo hyperpop\nindie pop emo pop\nindie pop emo pop-punk\nindie pop emo rap\nindie pop emo rap C-pop\nindie pop emo rap alternative R&B\nindie pop emo rap alternative rock\nindie pop emo rap bedroom pop\nindie pop emo rap hyperpop\nindie pop emo rap lo-fi hip-hop\nindie pop emo rock\nindie pop emo-pop\nindie pop emo-pop future bass\nindie pop emo-rap\nindie pop emo-rap hyperpop\nindie pop emo-rap lo-fi hip-hop\nindie pop emo-rock\nindie pop emo-trap\nindie pop experimental\nindie pop flamenco\nindie pop folk\nindie pop folk blues\nindie pop folk jazz\nindie pop folk-dance\nindie pop folk-pop\nindie pop folk-rock\nindie pop funk\nindie pop funk J-pop\nindie pop funk Latin\nindie pop funk MPB\nindie pop funk R&B\nindie pop funk art-pop\nindie pop funk big band\nindie pop funk bossa nova\nindie pop funk chiptune\nindie pop funk city pop\nindie pop funk disco\nindie pop funk dream pop\nindie pop funk electronic\nindie pop funk emo rap\nindie pop funk hip-hop\nindie pop funk jazz\nindie pop funk jazz fusion\nindie pop funk lounge\nindie pop funk neo-soul\nindie pop funk psychedelic\nindie pop funk psychedelic rock\nindie pop funk r&b\nindie pop funk reggae\nindie pop funk rock\nindie pop funk ska\nindie pop funk soul\nindie pop funk surf rock\nindie pop funk synth-pop\nindie pop funk trip-hop\nindie pop funk tropical\nindie pop funk world music\nindie pop funk-pop\nindie pop funk-pop C-pop\nindie pop funk-rock\nindie pop funk-rock hip-hop\nindie pop future bass\nindie pop future bass chillwave\nindie pop garage punk\nindie pop garage rock\nindie pop glitch-pop\nindie pop gospel\nindie pop grunge\nindie pop gypsy jazz\nindie pop gypsy-folk\nindie pop hip-hop\nindie pop hip-hop R&B\nindie pop hip-hop ballad\nindie pop hip-hop chiptune\nindie pop hip-hop funk\nindie pop hip-hop lounge\nindie pop hip-hop pop-punk\nindie pop house\nindie pop hyperpop\nindie pop hyperpop chiptune\nindie pop j-pop\nindie pop j-rock\nindie pop jangle pop\nindie pop jangle-pop\nindie pop jazz\nindie pop jazz R&B\nindie pop jazz art pop\nindie pop jazz bossa nova\nindie pop jazz dream pop\nindie pop jazz funk\nindie pop jazz fusion\nindie pop jazz lounge\nindie pop jazz neo-soul\nindie pop jazz psychedelic\nindie pop jazz trip-hop\nindie pop jazz-funk\nindie pop jazz-fusion\nindie pop jazz-pop\nindie pop kawaii\nindie pop latin\nindie pop latin pop\nindie pop lo-fi\nindie pop lo-fi R&B\nindie pop lo-fi bedroom pop\nindie pop lo-fi bossa nova\nindie pop lo-fi chiptune\nindie pop lo-fi city pop\nindie pop lo-fi dream pop\nindie pop lo-fi electronic\nindie pop lo-fi garage rock\nindie pop lo-fi hip hop\nindie pop lo-fi hip-hop\nindie pop lo-fi hip-hop MPB\nindie pop lo-fi hip-hop R&B\nindie pop lo-fi hip-hop bedroom pop\nindie pop lo-fi hip-hop jazz\nindie pop lo-fi hip-hop neo-soul\nindie pop lo-fi hip-hop romantic R&B\nindie pop lo-fi hip-hop shoegaze\nindie pop lo-fi hip-hop soul\nindie pop lo-fi house\nindie pop lo-fi jazz\nindie pop lo-fi neo-soul\nindie pop lo-fi pop\nindie pop lo-fi psychedelic\nindie pop lo-fi reggaeton\nindie pop lo-fi rock\nindie pop lo-fi synth-pop\nindie pop lofi\nindie pop lounge\nindie pop lounge big band\nindie pop lounge bossa nova\nindie pop lounge cabaret\nindie pop lounge chiptune\nindie pop lounge city pop\nindie pop lounge exotica\nindie pop lounge jazz\nindie pop lounge neo-soul\nindie pop lounge psychedelic\nindie pop lounge rock\nindie pop lounge swing\nindie pop lounge trip-hop\nindie pop lounge-jazz\nindie pop math-rock\nindie pop neo-funk\nindie pop neo-psychedelic\nindie pop neo-soul\nindie pop neo-soul MPB\nindie pop neo-soul bossa nova\nindie pop neo-soul chiptune\nindie pop neo-soul city pop\nindie pop neo-soul funk\nindie pop neo-soul hip-hop\nindie pop neo-soul jazz\nindie pop neo-soul jazz fusion\nindie pop neo-soul latin\nindie pop neo-soul lo-fi\nindie pop neo-soul lo-fi hip-hop\nindie pop neo-soul lounge\nindie pop neo-soul lounge jazz\nindie pop neo-soul psychedelic\nindie pop neo-soul reggae\nindie pop neo-soul surf rock\nindie pop neo-soul surf-rock\nindie pop neo-soul trip-hop\nindie pop noir\nindie pop noise rock\nindie pop nu-disco\nindie pop nu-disco French pop\nindie pop nu-disco French touch\nindie pop nu-disco chiptune\nindie pop nu-disco city pop\nindie pop nu-disco electro-pop\nindie pop nu-disco funk\nindie pop nu-disco lounge\nindie pop nu-disco synth-pop\nindie pop nu-jazz lounge\nindie pop pop-punk\nindie pop post-punk\nindie pop post-rock\nindie pop power pop\nindie pop power-pop\nindie pop progressive house\nindie pop progressive rock\nindie pop psychedelic\nindie pop psychedelic lounge\nindie pop psychedelic rock\nindie pop punk\nindie pop ragtime\nindie pop rap\nindie pop reggae\nindie pop reggae R&B\nindie pop reggae bossa nova\nindie pop reggae dancehall\nindie pop reggae dub\nindie pop reggae funk\nindie pop reggae fusion\nindie pop reggae hip-hop\nindie pop reggae jazz fusion\nindie pop reggae ska\nindie pop reggae soul\nindie pop reggae surf rock\nindie pop reggae tropical\nindie pop reggae-funk\nindie pop reggae-ska\nindie pop reggaeton\nindie pop retro\nindie pop retro Bollywood\nindie pop retro Italian pop-rock\nindie pop retro chanson\nindie pop retro funk\nindie pop retro funk disco\nindie pop retro garage rock\nindie pop retro lounge\nindie pop retro lounge jazz\nindie pop retro rock\nindie pop retro soul\nindie pop retro soul funk\nindie pop retro surf-rock\nindie pop retro swing\nindie pop retro-funk\nindie pop retro-futuristic\nindie pop retro-soul\nindie pop retrowave\nindie pop rock\nindie pop rockabilly\nindie pop samba-rock\nindie pop shoegaze\nindie pop ska\nindie pop ska Latin\nindie pop ska big band\nindie pop ska reggae\nindie pop ska swing\nindie pop soft rock\nindie pop soul\nindie pop soul R&B\nindie pop soul blues\nindie pop soul-jazz\nindie pop soulful R&B\nindie pop sunshine pop\nindie pop surf rock\nindie pop surf rock MPB\nindie pop surf rock exotica\nindie pop surf rock jazz\nindie pop surf rock neo-soul\nindie pop surf-pop\nindie pop surf-rock\nindie pop swing revival\nindie pop synth-funk\nindie pop synth-pop\nindie pop synth-pop R&B\nindie pop synth-pop alternative rock\nindie pop synth-pop chiptune\nindie pop synth-pop electropop\nindie pop synth-pop funk\nindie pop synth-pop hip-hop\nindie pop synth-pop pop-punk\nindie pop synth-pop power-pop\nindie pop synthwave\nindie pop tango\nindie pop trap\nindie pop trap-R&B\nindie pop trap-pop\nindie pop trip-hop\nindie pop tropical\nindie pop tropical house\nindie pop tropical house afrobeat\nindie pop tropical lounge\nindie pop tropical rock\nindie pop ukulele hip-hop\nindie pop vaporwave\nindie pop vaporwave chillwave\nindie pop vaporwave lo-fi\nindie pop world\nindie pop world music\nindie pop world-folk\nindie pop worldbeat\nindie pop worldbeat tropical\nindie pop, 8-bit chiptune\nindie pop, 80s Bollywood\nindie pop, 80s French pop\nindie pop, 80s Italian new wave\nindie pop, 80s jangle pop\nindie pop, 80s new wave\nindie pop, 80s new wave, atmospheric\nindie pop, 80s synth\nindie pop, 80s synth-pop\nindie pop, 80s synth-pop, dream pop\nindie pop, Americana, country\nindie pop, Bollywood\nindie pop, Brazilian MPB\nindie pop, Brazilian alternative\nindie pop, Brazilian funk\nindie pop, Brazilian funk, bossa nova\nindie pop, Brazilian pop\nindie pop, C-pop\nindie pop, C-pop, anime soundtrack\nindie pop, C-pop, kawaii\nindie pop, C-pop, lo-fi\nindie pop, Canto-pop, chiptune\nindie pop, Chinese hip hop\nindie pop, Chinese hip-hop\nindie pop, Chinese pop, emotional rock\nindie pop, Chinese rap\nindie pop, EDM\nindie pop, EDM, cinematic\nindie pop, EDM, dance-pop\nindie pop, Eastern European folk\nindie pop, Eastern European, lo-fi\nindie pop, European cabaret\nindie pop, European chanson\nindie pop, European folk\nindie pop, European folk, cinematic\nindie pop, European folk, klezmer\nindie pop, European folk, theatrical\nindie pop, Filipino pop-rock\nindie pop, French chanson\nindie pop, French chanson, big band\nindie pop, French chanson, jazz\nindie pop, French chanson, lounge jazz\nindie pop, French chanson, retro\nindie pop, French chanson, trip-hop\nindie pop, French coldwave\nindie pop, French disco\nindie pop, French dream pop\nindie pop, French funk\nindie pop, French new wave\nindie pop, French pop\nindie pop, French pop, dream pop\nindie pop, German art-pop\nindie pop, German cloud rap\nindie pop, German hip-hop\nindie pop, German new wave\nindie pop, Hindi pop\nindie pop, Indian fusion\nindie pop, Israeli rock\nindie pop, Italo disco, synth-pop\nindie pop, Italo-disco\nindie pop, Italo-disco, new wave\nindie pop, Italo-disco, synth-pop\nindie pop, J-pop\nindie pop, J-pop, Shibuya-kei\nindie pop, J-pop, big band\nindie pop, J-pop, video game music\nindie pop, J-pop, video game soundtrack\nindie pop, J-rock\nindie pop, J-rock, chiptune\nindie pop, J-rock, pop-rock\nindie pop, Javanese folk, cinematic\nindie pop, K-indie, neo-soul\nindie pop, Korean R&B\nindie pop, Latin cumbia\nindie pop, Latin dance\nindie pop, Latin folk\nindie pop, Latin funk\nindie pop, Latin funk, bedroom pop\nindie pop, Latin funk, jazzy pop\nindie pop, Latin groove\nindie pop, Latin jazz fusion\nindie pop, Latin jazz-rock, chiptune\nindie pop, Latin pop\nindie pop, Latin pop, R&B\nindie pop, Latin pop, alternative R&B\nindie pop, Latin pop, alternative rock\nindie pop, Latin pop, dance pop\nindie pop, Latin pop, dream pop\nindie pop, Latin pop, house\nindie pop, Latin pop, lo-fi\nindie pop, Latin pop, psychedelic rock\nindie pop, Latin pop, reggaeton\nindie pop, Latin pop, retro\nindie pop, Latin pop, salsa\nindie pop, Latin pop, smooth jazz\nindie pop, Latin pop, surf rock\nindie pop, Latin pop, theatrical\nindie pop, Latin pop, trap\nindie pop, Latin pop, tropical\nindie pop, Latin pop, world music\nindie pop, Latin pop-rock\nindie pop, Latin pop-rock, theatrical\nindie pop, Latin rock\nindie pop, Latin rock, funk\nindie pop, Latin, R&B\nindie pop, Latin, big band\nindie pop, Latin, boogie-woogie\nindie pop, Latin, chiptune\nindie pop, Latin, flamenco\nindie pop, Latin, jazz\nindie pop, Latin, psychedelic\nindie pop, Latin, surf-rock\nindie pop, Latin, world music\nindie pop, MPB\nindie pop, MPB, bossa nova\nindie pop, MPB, chiptune\nindie pop, MPB, dream pop\nindie pop, MPB, funk\nindie pop, MPB, lo-fi\nindie pop, MPB, neo-soul\nindie pop, MPB, retro\nindie pop, MPB, samba-rock\nindie pop, MPB, surf rock\nindie pop, Mandarin ballad\nindie pop, Mandarin rock\nindie pop, Mandopop\nindie pop, Middle Eastern\nindie pop, Middle Eastern fusion\nindie pop, Middle Eastern, funk\nindie pop, Middle Eastern, melancholic\nindie pop, Neue Deutsche Welle\nindie pop, North African\nindie pop, Punjabi folk\nindie pop, R&B\nindie pop, R&B, Chinese hip hop\nindie pop, R&B, ambient\nindie pop, R&B, chillwave\nindie pop, R&B, dream pop\nindie pop, R&B, funk\nindie pop, R&B, future bass\nindie pop, R&B, hip-hop\nindie pop, R&B, hyperpop\nindie pop, R&B, jazz\nindie pop, R&B, lo-fi\nindie pop, R&B, lo-fi hip hop\nindie pop, R&B, lo-fi hip-hop\nindie pop, R&B, neo-soul\nindie pop, R&B, synth-pop\nindie pop, R&B, trap\nindie pop, Schlager\nindie pop, Shibuya-kei, lo-fi\nindie pop, South Asian fusion\nindie pop, South Asian, upbeat\nindie pop, South Indian\nindie pop, Spanish rock\nindie pop, Thai rock\nindie pop, Turkish alternative rock\nindie pop, UK garage\nindie pop, UK hip-hop, electronic\nindie pop, Vocaloid\nindie pop, Vocaloid style\nindie pop, acoustic ballad, pop-rock\nindie pop, alt-rock\nindie pop, alt-rock, blues-rock\nindie pop, alt-rock, folk-rock\nindie pop, alt-rock, future bass\nindie pop, alternative R&B\nindie pop, alternative R&B, emotional ballad\nindie pop, alternative R&B, funk\nindie pop, alternative R&B, lo-fi\nindie pop, alternative R&B, synth-pop\nindie pop, alternative dance\nindie pop, alternative hip-hop\nindie pop, alternative metal\nindie pop, alternative rock\nindie pop, alternative rock, chiptune\nindie pop, alternative rock, electronic\nindie pop, alternative rock, emo\nindie pop, alternative rock, experimental\nindie pop, alternative rock, noise rock\nindie pop, alternative rock, shoegaze\nindie pop, alternative rock, world music\nindie pop, ambient pop\nindie pop, ambient, ancient style\nindie pop, ambient, electronic\nindie pop, ambient, shoegaze\nindie pop, arena rock, neo-soul\nindie pop, atmospheric, world music\nindie pop, baroque pop\nindie pop, bedroom pop\nindie pop, bedroom pop, C-pop\nindie pop, bedroom pop, Latin R&B\nindie pop, bedroom pop, lo-fi\nindie pop, bedroom pop, lo-fi hip-hop\nindie pop, big band swing\nindie pop, big band, theatrical\nindie pop, blues rock\nindie pop, boogie-woogie, cabaret\nindie pop, bossa nova\nindie pop, bossa nova, Latin\nindie pop, bossa nova, Latin pop\nindie pop, bossa nova, bedroom pop\nindie pop, bossa nova, chiptune\nindie pop, bossa nova, city pop\nindie pop, bossa nova, dream pop\nindie pop, bossa nova, jazz\nindie pop, bossa nova, latin\nindie pop, bossa nova, latin pop\nindie pop, bossa nova, lo-fi\nindie pop, bossa nova, lounge\nindie pop, bossa nova, lounge jazz\nindie pop, bossa nova, psychedelic\nindie pop, bossa nova, psychedelic funk\nindie pop, breakbeat\nindie pop, breakbeat, hyperpop\nindie pop, breakcore\nindie pop, cabaret, European\nindie pop, cabaret, chanson\nindie pop, cabaret, circus music\nindie pop, cabaret, dream pop\nindie pop, cabaret, folk\nindie pop, cabaret, jazz\nindie pop, chanson\nindie pop, chanson, European\nindie pop, chanson, anime\nindie pop, chanson, cinematic\nindie pop, chanson, jazzy\nindie pop, chillwave\nindie pop, chillwave, bedroom pop\nindie pop, chillwave, electronic\nindie pop, chillwave, jazzy pop\nindie pop, chillwave, lo-fi\nindie pop, chiptune\nindie pop, chiptune, J-pop\nindie pop, chiptune, Latin pop\nindie pop, chiptune, bedroom pop\nindie pop, chiptune, conscious hip-hop\nindie pop, chiptune, dream pop\nindie pop, chiptune, electropop\nindie pop, chiptune, gospel\nindie pop, chiptune, hyperpop\nindie pop, chiptune, lo-fi\nindie pop, chiptune, psychedelic\nindie pop, chiptune, retro\nindie pop, chiptune, rock\nindie pop, chiptune, synth-pop\nindie pop, cinematic folk, ambient\nindie pop, cinematic pop\nindie pop, cinematic rock\nindie pop, cinematic, C-pop\nindie pop, cinematic, Chinese folk\nindie pop, cinematic, Indonesian\nindie pop, cinematic, Javanese\nindie pop, cinematic, electronic\nindie pop, cinematic, soulful R&B\nindie pop, city pop\nindie pop, city pop, J-pop\nindie pop, city pop, K-pop\nindie pop, city pop, R&B\nindie pop, city pop, Shibuya-kei\nindie pop, city pop, big band\nindie pop, city pop, dream pop\nindie pop, city pop, funk\nindie pop, city pop, jazz\nindie pop, city pop, jazz fusion\nindie pop, city pop, lo-fi\nindie pop, city pop, lo-fi hip-hop\nindie pop, city pop, lounge jazz\nindie pop, city pop, neo-soul\nindie pop, city pop, psychedelic\nindie pop, city pop, retro-funk\nindie pop, city pop, surf rock\nindie pop, city-pop\nindie pop, city-pop, chiptune\nindie pop, city-pop, jazz\nindie pop, city-pop, lo-fi\nindie pop, classic rock\nindie pop, classic rock en español\nindie pop, cloud rap\nindie pop, complextro, electro house\nindie pop, conscious hip-hop\nindie pop, contemporary Christian\nindie pop, contemporary R&B\nindie pop, contemporary R&B, Latin pop\nindie pop, cumbia\nindie pop, cumbia, Latin pop\nindie pop, cumbia, ambient\nindie pop, cumbia, chiptune\nindie pop, cumbia, surf rock\nindie pop, dance-pop\nindie pop, deep house\nindie pop, disco, funk\nindie pop, disco-funk\nindie pop, dream pop\nindie pop, dream pop, 80s new wave\nindie pop, dream pop, Chinese ambient\nindie pop, dream pop, Italo-disco\nindie pop, dream pop, Latin rhythms\nindie pop, dream pop, Latin-infused\nindie pop, dream pop, R&B\nindie pop, dream pop, ambient\nindie pop, dream pop, atmospheric\nindie pop, dream pop, city pop\nindie pop, dream pop, electronic\nindie pop, dream pop, hyperpop\nindie pop, dream pop, industrial rock\nindie pop, dream pop, jazz\nindie pop, dream pop, lo-fi\nindie pop, dream pop, lo-fi hip-hop\nindie pop, dream pop, lounge\nindie pop, dream pop, psychedelic\nindie pop, dream pop, shoegaze\nindie pop, dream pop, synth-pop\nindie pop, dream-pop\nindie pop, dream-pop, Filipino indie\nindie pop, dream-pop, shoegaze\nindie pop, dream-pop, synth-pop\nindie pop, drum and bass\nindie pop, dubstep\nindie pop, dubstep, glitch-hop\nindie pop, electro-rock\nindie pop, electronic\nindie pop, electronic dance\nindie pop, electronic rock, future bass\nindie pop, electronic rock, hyperpop\nindie pop, electronic, Hebrew hip-hop\nindie pop, electronic, Hebrew pop\nindie pop, electronic, Indian classical\nindie pop, electronic, Indian folk\nindie pop, electronic, Indian fusion\nindie pop, electronic, Latin\nindie pop, electronic, dream pop\nindie pop, electronic, glitch\nindie pop, electronic, hip-hop\nindie pop, electronic, industrial\nindie pop, electronic, lo-fi\nindie pop, electronic, trap\nindie pop, electronic, world fusion\nindie pop, electronica, lo-fi\nindie pop, emo rap\nindie pop, emo rap, cloud rap\nindie pop, emo rap, lo-fi hip-hop\nindie pop, emo rock\nindie pop, emo, hyperpop\nindie pop, emo-rap, alternative rock\nindie pop, emo-rap, trap\nindie pop, emotional ballad\nindie pop, eurodance\nindie pop, eurodance, trance\nindie pop, experimental electronic\nindie pop, folk, lo-fi\nindie pop, folk-rock\nindie pop, free jazz, experimental\nindie pop, funk rock\nindie pop, funk, city pop\nindie pop, funk, city-pop\nindie pop, funk, electronic\nindie pop, funk, lo-fi\nindie pop, funk, pop-rock\nindie pop, funk, synth-pop\nindie pop, funk-pop, K-indie\nindie pop, funk-rock, reggae-pop, surf-rock, power-pop\nindie pop, future bass\nindie pop, future bass, folk rock\nindie pop, future bass, hyperpop\nindie pop, future bass, lo-fi\nindie pop, future bass, synth-pop\nindie pop, ghazal, ambient\nindie pop, glitch, hyperpop\nindie pop, glitch-hop, hyperpop\nindie pop, hard rock\nindie pop, hardstyle\nindie pop, hip hop\nindie pop, hip-hop\nindie pop, hip-hop, C-pop\nindie pop, hip-hop, Khmer pop\nindie pop, hip-hop, R&B\nindie pop, hip-hop, ambient\nindie pop, hip-hop, chiptune\nindie pop, hip-hop, cinematic\nindie pop, hip-hop, emotional rock\nindie pop, hip-hop, funk\nindie pop, hip-hop, hyperpop\nindie pop, hip-hop, pop-rock\nindie pop, hip-hop, world music\nindie pop, hyperpop\nindie pop, hyperpop, art-pop\nindie pop, hyperpop, chiptune\nindie pop, hyperpop, cinematic\nindie pop, hyperpop, drum and bass\nindie pop, hyperpop, electronic\nindie pop, hyperpop, electronic rock\nindie pop, hyperpop, electropop\nindie pop, hyperpop, emo\nindie pop, hyperpop, emo-rap\nindie pop, hyperpop, experimental electronic\nindie pop, hyperpop, future bass\nindie pop, hyperpop, glitch-pop\nindie pop, hyperpop, indie rock\nindie pop, hyperpop, pop-punk\nindie pop, hyperpop, trap\nindie pop, indie rock\nindie pop, indie rock, J-rock\nindie pop, indie rock, alternative metal\nindie pop, indie rock, bossa nova\nindie pop, indie rock, hip-hop\nindie pop, indie rock, noise rock\nindie pop, indie rock, nu-disco\nindie pop, indie rock, post-hardcore\nindie pop, indie rock, post-rock\nindie pop, indie rock, synth-pop\nindie pop, industrial rock\nindie pop, jazz lounge\nindie pop, jazz, dream pop\nindie pop, jazz, lounge\nindie pop, jazz, retro\nindie pop, jazz, theatrical\nindie pop, jazz, vintage swing\nindie pop, jazzy rock, Chinese pop\nindie pop, jazzy, dream-pop\nindie pop, jazzy, lo-fi\nindie pop, latin pop\nindie pop, latin pop, R&B\nindie pop, latin-pop, funk\nindie pop, light funk\nindie pop, lo-fi\nindie pop, lo-fi electronic, trip-hop\nindie pop, lo-fi hip hop\nindie pop, lo-fi hip hop, alternative rock\nindie pop, lo-fi hip hop, ambient\nindie pop, lo-fi hip hop, atmospheric\nindie pop, lo-fi hip hop, jazz\nindie pop, lo-fi hip hop, trip-hop\nindie pop, lo-fi hip-hop\nindie pop, lo-fi hip-hop, C-pop\nindie pop, lo-fi hip-hop, city-pop\nindie pop, lo-fi hip-hop, dream rock\nindie pop, lo-fi hip-hop, emo-rock\nindie pop, lo-fi hip-hop, pop-rock\nindie pop, lo-fi hip-hop, rock\nindie pop, lo-fi hip-hop, shoegaze\nindie pop, lo-fi pop, R&B\nindie pop, lo-fi, Brazilian pop\nindie pop, lo-fi, French pop\nindie pop, lo-fi, Hindi pop\nindie pop, lo-fi, Korean\nindie pop, lo-fi, Latin\nindie pop, lo-fi, Mandarin pop\nindie pop, lo-fi, ambient\nindie pop, lo-fi, bedroom pop\nindie pop, lo-fi, chiptune\nindie pop, lo-fi, dream pop\nindie pop, lo-fi, dreamy\nindie pop, lo-fi, hyperpop\nindie pop, lo-fi, melancholic\nindie pop, lo-fi, soulful\nindie pop, lo-fi, theatrical rock\nindie pop, lo-fi, vaporwave\nindie pop, lounge, Indian classical\nindie pop, lounge-pop, jazzy\nindie pop, math rock, C-pop\nindie pop, math rock, noise rock\nindie pop, melodic hip-hop\nindie pop, melodic trap\nindie pop, modern Punjabi pop\nindie pop, narrative hip-hop\nindie pop, neo-funk, chiptune\nindie pop, neo-soul\nindie pop, neo-soul, R&B\nindie pop, neo-soul, bedroom pop\nindie pop, neo-soul, bossa nova\nindie pop, neo-soul, chill-hop\nindie pop, neo-soul, city pop\nindie pop, neo-soul, dream pop\nindie pop, neo-soul, funk\nindie pop, neo-soul, lo-fi hip-hop\nindie pop, new wave\nindie pop, new wave, art-pop\nindie pop, new wave, chiptune\nindie pop, new wave, dream pop\nindie pop, new wave, funk\nindie pop, new wave, post-punk\nindie pop, new wave, surf rock\nindie pop, new wave, synth-pop\nindie pop, noise rock\nindie pop, noise rock, chiptune\nindie pop, noise rock, shoegaze\nindie pop, nu-disco\nindie pop, nu-disco, city pop\nindie pop, polka, French pop\nindie pop, polka, quirky\nindie pop, pop rap\nindie pop, pop-punk\nindie pop, pop-punk, J-rock\nindie pop, pop-punk, alternative rock\nindie pop, pop-punk, barbershop\nindie pop, pop-punk, blues-rock\nindie pop, pop-punk, emo rock\nindie pop, pop-punk, emo-pop\nindie pop, pop-punk, emotional rock\nindie pop, pop-punk, experimental\nindie pop, pop-punk, hip hop\nindie pop, pop-punk, hyperpop\nindie pop, pop-punk, lo-fi\nindie pop, pop-punk, metalcore\nindie pop, pop-punk, rock\nindie pop, pop-rock\nindie pop, pop-rock, future bass\nindie pop, post-hardcore\nindie pop, post-punk\nindie pop, post-punk, emo rap\nindie pop, post-punk, lo-fi\nindie pop, post-punk, lounge\nindie pop, post-punk, new wave\nindie pop, post-punk, synth-pop\nindie pop, post-rock\nindie pop, post-rock, ambient\nindie pop, post-rock, dream pop\nindie pop, post-rock, lo-fi\nindie pop, post-rock, lo-fi hip-hop\nindie pop, post-rock, shoegaze\nindie pop, power pop\nindie pop, power-pop, chiptune\nindie pop, power-pop, emo\nindie pop, progressive house\nindie pop, progressive metal\nindie pop, psychedelic\nindie pop, psychedelic funk-rock\nindie pop, psychedelic rock\nindie pop, psychedelic soul\nindie pop, psychedelic, Latin\nindie pop, psychedelic, exotica\nindie pop, psychedelic, lo-fi\nindie pop, psychedelic, shoegaze\nindie pop, psychedelic, trap\nindie pop, psychedelic, trip-hop\nindie pop, psychedelic, world music\nindie pop, quirky, polka\nindie pop, ragtime, theatrical\nindie pop, rap rock\nindie pop, rap, rock\nindie pop, reggae, ska\nindie pop, retro\nindie pop, retro Brazilian\nindie pop, retro Italian pop-rock\nindie pop, retro funk, disco\nindie pop, retro lounge\nindie pop, retro lounge, jazz\nindie pop, retro lounge, theatrical\nindie pop, retro new wave\nindie pop, retro pop\nindie pop, retro soul\nindie pop, retro surf rock\nindie pop, retro surf-rock\nindie pop, retro synth, C-pop\nindie pop, retro synth-pop\nindie pop, retro, 60s rock\nindie pop, retro, Bollywood\nindie pop, retro, K-pop\nindie pop, retro, Latin\nindie pop, retro, Latin pop\nindie pop, retro, Neue Deutsche Welle\nindie pop, retro, Soviet-era estrada\nindie pop, retro, Turkish\nindie pop, retro, doo-wop\nindie pop, retro, exotica\nindie pop, retro, lo-fi\nindie pop, retro, surf-rock\nindie pop, retro-funk, city pop\nindie pop, rock\nindie pop, rock, Mandarin\nindie pop, rockabilly\nindie pop, rockabilly, retro\nindie pop, satirical hip-hop\nindie pop, schlager\nindie pop, shoegaze\nindie pop, shoegaze, alternative rock\nindie pop, shoegaze, ambient\nindie pop, shoegaze, chiptune\nindie pop, shoegaze, dream pop\nindie pop, shoegaze, experimental\nindie pop, shoegaze, lo-fi\nindie pop, shoegaze, noise rock\nindie pop, shoegaze, post-rock\nindie pop, ska, swing\nindie pop, ska, vintage\nindie pop, soft rock\nindie pop, soft rock, South Asian\nindie pop, sunshine pop\nindie pop, sunshine pop, vintage\nindie pop, surf rock\nindie pop, surf rock, city pop\nindie pop, surf rock, dream pop\nindie pop, surf rock, theatrical\nindie pop, surf-rock, C-pop\nindie pop, synth rock, rock\nindie pop, synth-pop\nindie pop, synth-pop, C-pop\nindie pop, synth-pop, French chanson\nindie pop, synth-pop, Italo-disco\nindie pop, synth-pop, bedroom pop\nindie pop, synth-pop, chiptune\nindie pop, synth-pop, dance-pop\nindie pop, synth-pop, dream pop\nindie pop, synth-pop, dream-pop\nindie pop, synth-pop, electronic\nindie pop, synth-pop, electropop\nindie pop, synth-pop, emotional ballad\nindie pop, synth-pop, future bass\nindie pop, synth-pop, hyperpop\nindie pop, synth-pop, new wave\nindie pop, synth-pop, nu-disco\nindie pop, synth-pop, vaporwave\nindie pop, synthwave\nindie pop, synthwave, dream pop\nindie pop, theatrical pop\nindie pop, theatrical rock, cinematic\nindie pop, theatrical, dark pop\nindie pop, theatrical, rock\nindie pop, trap\nindie pop, trap metal\nindie pop, trap, Hindi pop\nindie pop, trap, R&B\nindie pop, trap, ambient\nindie pop, trap, hip-hop\nindie pop, trap, lo-fi\nindie pop, trap, lo-fi hip hop\nindie pop, trap, psychedelic\nindie pop, trip-hop\nindie pop, trip-hop, ambient\nindie pop, trip-hop, art pop\nindie pop, trip-hop, atmospheric\nindie pop, trip-hop, downtempo\nindie pop, trip-hop, dream pop\nindie pop, trip-hop, lo-fi\nindie pop, trip-hop, lo-fi hip hop\nindie pop, trip-hop, lo-fi hip-hop\nindie pop, tropical, Latin\nindie pop, ukulele pop, retro surf\nindie pop, vaporwave\nindie pop, vaporwave, city pop\nindie pop, vaporwave, dream pop\nindie pop, vaporwave, lo-fi\nindie pop, vintage jazz\nindie pop, vintage, show tune\nindie pop, vintage, show-tune\nindie pop, world fusion\nindie pop, world fusion, Indian classical\nindie pop, world fusion, cinematic\nindie pop, world music\nindie pop, world music, Latin\nindie pop, world music, ghazal\nindie pop-punk\nindie pop-rap\nindie pop-rock\nindie pop-rock C-pop\nindie pop-rock Mandopop\nindie pop-rock alternative rock\nindie pop-rock bossa nova\nindie pop-rock chiptune\nindie pop-rock city pop\nindie pop-rock country\nindie pop-rock country-folk\nindie pop-rock country-pop\nindie pop-rock emo-pop\nindie pop-rock emo-rap\nindie pop-rock folk\nindie pop-rock funk\nindie pop-rock funk soul\nindie pop-rock future bass\nindie pop-rock hip-hop\nindie pop-rock neo-soul\nindie pop-rock reggae\nindie pop-rock ska\nindie pop-rock, J-rock, lo-fi\nindie pop-rock, complextro, dubstep\nindie pop-rock, dangdut, rock\nindie pop-rock, future bass, chiptune\nindie pop-rock, hip-hop, alternative rock\nindie pop-rock, hip-hop, emotional ballad\nindie pop-rock, lo-fi acoustic\nindie pop-rock, melodic dubstep\nindie pop-rock, pop-punk, hyperpop\nindie pop-rock, power ballad, theatrical\nindie pop-rock, synth-pop, electro-funk\nindie pop-rock, trap, EDM\nindie post-rock\nindie punk\nindie punk rock\nindie rap\nindie reggae\nindie rock\nindie rock 80s\nindie rock 90s Chinese rock\nindie rock 90s alternative\nindie rock Afro-pop\nindie rock Anatolian rock\nindie rock Bollywood\nindie rock C-pop\nindie rock C-rock\nindie rock Christian rock\nindie rock Christmas\nindie rock French pop\nindie rock J-rock\nindie rock Latin\nindie rock Latin alt-rock\nindie rock Latin alternative\nindie rock Latin pop\nindie rock Latin pop-rock\nindie rock Latin rock\nindie rock MPB\nindie rock MPB bossa nova\nindie rock Mandopop\nindie rock R&B\nindie rock alt-country\nindie rock alt-country americana\nindie rock alt-country folk-punk\nindie rock alt-rock\nindie rock alternative\nindie rock alternative R&B\nindie rock alternative grunge\nindie rock alternative hip-hop\nindie rock alternative metal\nindie rock alternative pop\nindie rock alternative post-hardcore\nindie rock alternative punk\nindie rock alternative reggae\nindie rock alternative rock\nindie rock alternative rock emo\nindie rock alternative rock noise rock\nindie rock alternative rock pop-punk\nindie rock alternative rock post-hardcore\nindie rock alternative rock post-rock\nindie rock alternative rock psychedelic rock\nindie rock alternative rock shoegaze\nindie rock ambient\nindie rock americana\nindie rock arena rock\nindie rock art rock\nindie rock art-pop\nindie rock art-rock\nindie rock balkan rock\nindie rock ballad\nindie rock baroque pop\nindie rock baroque pop psychedelic\nindie rock bedroom pop\nindie rock big band\nindie rock big band swing\nindie rock bluegrass\nindie rock blues\nindie rock blues americana\nindie rock blues country\nindie rock blues country-rock\nindie rock blues garage rock\nindie rock blues gospel\nindie rock blues jazz\nindie rock blues psychedelic rock\nindie rock blues rock\nindie rock blues soul\nindie rock blues-rock\nindie rock bluesy americana\nindie rock boogie-woogie\nindie rock bossa nova\nindie rock bossa nova MPB\nindie rock bossa nova jazz\nindie rock bossa nova lounge\nindie rock bossa nova lounge jazz\nindie rock brass\nindie rock britpop\nindie rock cabaret\nindie rock cabaret art-rock\nindie rock cabaret punk\nindie rock cabaret surf rock\nindie rock cabaret swing\nindie rock cantopop\nindie rock chamber folk\nindie rock chamber pop\nindie rock chamber pop neo-classical\nindie rock chanson\nindie rock chillhop\nindie rock chillwave\nindie rock chiptune\nindie rock chiptune cabaret\nindie rock chiptune dream pop\nindie rock chiptune emo\nindie rock chiptune funk\nindie rock chiptune j-rock\nindie rock chiptune jangle pop\nindie rock chiptune math rock\nindie rock chiptune new wave\nindie rock chiptune noise rock\nindie rock chiptune pop-punk\nindie rock chiptune post-punk\nindie rock chiptune power pop\nindie rock chiptune power-pop\nindie rock chiptune psychedelic\nindie rock chiptune punk\nindie rock chiptune ska\nindie rock chiptune ska-punk\nindie rock chiptune space rock\nindie rock chiptune surf rock\nindie rock chiptune synth-pop\nindie rock cinematic\nindie rock city pop\nindie rock city pop funk\nindie rock city pop math rock\nindie rock city pop surf rock\nindie rock city-pop\nindie rock classic rock\nindie rock classic rock blues-rock\nindie rock conscious hip-hop\nindie rock country\nindie rock country blues-rock\nindie rock country folk\nindie rock country psychedelic\nindie rock country rock\nindie rock country-folk\nindie rock country-pop\nindie rock country-rock\nindie rock country-western\nindie rock crossover thrash\nindie rock cumbia\nindie rock cumbia ska\nindie rock cumbia surf rock\nindie rock dance-punk\nindie rock dance-punk disco\nindie rock dance-rock\nindie rock desert rock\nindie rock doo-wop\nindie rock dream pop\nindie rock dream pop alternative rock\nindie rock dream pop bossa nova\nindie rock dream pop emo rap\nindie rock dream pop fado\nindie rock dream pop hip-hop\nindie rock dream pop jangle pop\nindie rock dream pop jazz\nindie rock dream pop lo-fi hip-hop\nindie rock dream pop lounge jazz\nindie rock dream pop math rock\nindie rock dream pop neo-soul\nindie rock dream pop post-hardcore\nindie rock dream pop post-punk\nindie rock dream pop psychedelic\nindie rock dream pop shoegaze\nindie rock dream pop surf rock\nindie rock dream-pop\nindie rock dream-pop shoegaze\nindie rock drum and bass\nindie rock dubstep\nindie rock electro\nindie rock electro house\nindie rock electronic\nindie rock electronic funk\nindie rock electronic rock\nindie rock electronicore\nindie rock emo\nindie rock emo alternative\nindie rock emo cloud rap\nindie rock emo hip-hop\nindie rock emo hyperpop\nindie rock emo math rock\nindie rock emo pop\nindie rock emo pop-punk\nindie rock emo post-hardcore\nindie rock emo post-rock\nindie rock emo power-pop\nindie rock emo punk\nindie rock emo rap\nindie rock emo rap dream pop\nindie rock emo rap hyperpop\nindie rock emo rap pop-punk\nindie rock emo rap shoegaze\nindie rock emo rock k-pop\nindie rock emo shoegaze\nindie rock emo-pop\nindie rock emo-pop alternative rock\nindie rock emo-punk\nindie rock emo-rap\nindie rock emo-rap alternative\nindie rock emo-rap hyperpop\nindie rock emo-rap lo-fi hip-hop\nindie rock emo-rap pop-punk\nindie rock emo-rap shoegaze\nindie rock emo-rock\nindie rock fado\nindie rock flamenco\nindie rock flamenco Latin\nindie rock folk\nindie rock folk Latin\nindie rock folk americana\nindie rock folk country-rock\nindie rock folk emo\nindie rock folk surf rock\nindie rock folk world music\nindie rock folk-pop\nindie rock folk-punk\nindie rock folk-punk Celtic\nindie rock folk-punk ska\nindie rock folk-rock\nindie rock french pop\nindie rock funk\nindie rock funk Brazilian MPB\nindie rock funk J-rock\nindie rock funk Latin\nindie rock funk Latin rock\nindie rock funk MPB\nindie rock funk R&B\nindie rock funk art rock\nindie rock funk big band\nindie rock funk blues\nindie rock funk blues-rock\nindie rock funk chiptune\nindie rock funk city pop\nindie rock funk dance-punk\nindie rock funk disco\nindie rock funk dream pop\nindie rock funk electronic\nindie rock funk garage rock\nindie rock funk glam\nindie rock funk hip-hop\nindie rock funk jazz\nindie rock funk jazz fusion\nindie rock funk math rock\nindie rock funk new wave\nindie rock funk party-rock\nindie rock funk pop\nindie rock funk pop-punk\nindie rock funk pop-rock\nindie rock funk post-punk\nindie rock funk power pop\nindie rock funk power-pop\nindie rock funk psychedelic\nindie rock funk punk\nindie rock funk reggae\nindie rock funk rock\nindie rock funk rockabilly\nindie rock funk ska\nindie rock funk soul\nindie rock funk surf rock\nindie rock funk synth-pop\nindie rock funk trip-hop\nindie rock funk-rock\nindie rock funk-rock alternative rock\nindie rock funk-rock blues-rock\nindie rock funk-rock psychedelic\nindie rock future bass\nindie rock garage punk\nindie rock garage rock\nindie rock garage rock blues rock\nindie rock garage rock blues-rock\nindie rock garage rock noise rock\nindie rock garage rock psychedelic\nindie rock garage rock psychedelic rock\nindie rock garage rock revival\nindie rock garage rock surf rock\nindie rock glam rock\nindie rock glitch-pop\nindie rock gospel\nindie rock gospel soul\nindie rock grunge\nindie rock grunge alternative metal\nindie rock grunge alternative rock\nindie rock grunge noise rock\nindie rock grunge psychedelic\nindie rock grunge punk\nindie rock gypsy jazz\nindie rock gypsy jazz bluegrass\nindie rock gypsy jazz cabaret\nindie rock gypsy jazz klezmer\nindie rock gypsy jazz latin\nindie rock gypsy-jazz\nindie rock hardcore punk\nindie rock hardcore punk thrash metal\nindie rock heartland rock\nindie rock hip hop\nindie rock hip-hop\nindie rock hip-hop breakcore\nindie rock hip-hop chiptune\nindie rock hip-hop dubstep\nindie rock hip-hop fusion\nindie rock hip-hop garage rock\nindie rock hip-hop pop\nindie rock hip-hop pop-rock\nindie rock hip-hop shoegaze\nindie rock hyperpop\nindie rock hyperpop chiptune\nindie rock hyperpop trap\nindie rock industrial\nindie rock industrial rock\nindie rock j-rock\nindie rock jangle pop\nindie rock jangle-pop\nindie rock jazz\nindie rock jazz MPB\nindie rock jazz big band\nindie rock jazz blues\nindie rock jazz boogie-woogie\nindie rock jazz bossa nova\nindie rock jazz cabaret\nindie rock jazz chiptune\nindie rock jazz funk\nindie rock jazz fusion\nindie rock jazz fusion funk\nindie rock jazz fusion math rock\nindie rock jazz latin\nindie rock jazz lounge\nindie rock jazz neo-soul\nindie rock jazz noir\nindie rock jazz prog\nindie rock jazz psychedelic\nindie rock jazz soul\nindie rock jazz surf rock\nindie rock jazz-funk\nindie rock jazz-funk Latin\nindie rock jazz-fusion\nindie rock jazz-pop\nindie rock jazz-rock\nindie rock jazz-rock thrash metal\nindie rock jazzy\nindie rock jazzy folk\nindie rock klezmer\nindie rock latin\nindie rock latin alternative\nindie rock latin groove\nindie rock latin pop\nindie rock latin rock\nindie rock latin-pop\nindie rock lo-fi\nindie rock lo-fi C-pop\nindie rock lo-fi bedroom pop\nindie rock lo-fi chiptune\nindie rock lo-fi dream pop\nindie rock lo-fi dream-pop\nindie rock lo-fi garage\nindie rock lo-fi garage rock\nindie rock lo-fi hip hop\nindie rock lo-fi hip-hop\nindie rock lo-fi neo-soul\nindie rock lo-fi psychedelic\nindie rock lo-fi shoegaze\nindie rock lo-fi surf rock\nindie rock lounge\nindie rock lounge jazz\nindie rock lounge trip-hop\nindie rock lounge-pop\nindie rock mandopop\nindie rock math rock\nindie rock math rock J-rock\nindie rock math rock chiptune\nindie rock math rock funk\nindie rock math rock jangle pop\nindie rock math rock jazz fusion\nindie rock math rock pop-punk\nindie rock math rock post-punk\nindie rock math-rock\nindie rock mathcore\nindie rock metal\nindie rock metal fusion\nindie rock metalcore\nindie rock metalcore chiptune\nindie rock metalcore post-rock\nindie rock neo-psychedelic\nindie rock neo-soul\nindie rock neo-soul R&B\nindie rock neo-soul city pop\nindie rock neo-soul funk\nindie rock neo-soul hip-hop\nindie rock neo-soul jazz\nindie rock neo-soul jazz fusion\nindie rock neo-soul lounge\nindie rock neo-soul math rock\nindie rock neo-soul psychedelic\nindie rock neo-soul psychedelic rock\nindie rock nerdcore pop-punk\nindie rock new wave\nindie rock noir\nindie rock noir-jazz\nindie rock noise rock\nindie rock noise rock post-punk\nindie rock noise rock post-rock\nindie rock noise rock psychedelic\nindie rock noise rock punk\nindie rock noise rock shoegaze\nindie rock nu-disco\nindie rock nu-disco funk\nindie rock nu-metal\nindie rock nu-metal rap-rock\nindie rock orchestral rock\nindie rock polka\nindie rock pop\nindie rock pop-punk\nindie rock pop-punk J-rock\nindie rock pop-punk alternative rock\nindie rock pop-punk bluegrass\nindie rock pop-punk chiptune\nindie rock pop-punk easycore\nindie rock pop-punk electronic\nindie rock pop-punk emo\nindie rock pop-punk emo-rap\nindie rock pop-punk hip-hop\nindie rock pop-punk metalcore\nindie rock pop-punk noise rock\nindie rock pop-punk noise-rock\nindie rock pop-punk nu-metal\nindie rock pop-punk rap-rock\nindie rock pop-punk ska\nindie rock pop-rap\nindie rock pop-rock\nindie rock post-grunge\nindie rock post-grunge emo\nindie rock post-hardcore\nindie rock post-hardcore metal\nindie rock post-hardcore metalcore\nindie rock post-hardcore punk\nindie rock post-hardcore rap-rock\nindie rock post-punk\nindie rock post-punk dream pop\nindie rock post-punk new wave\nindie rock post-punk noise rock\nindie rock post-punk psychedelic\nindie rock post-punk revival\nindie rock post-punk shoegaze\nindie rock post-rock\nindie rock post-rock alternative rock\nindie rock post-rock punk\nindie rock post-rock shoegaze\nindie rock power pop\nindie rock power-pop\nindie rock power-pop chiptune\nindie rock power-pop country-rock\nindie rock power-pop garage rock\nindie rock power-pop new wave\nindie rock progressive metal\nindie rock progressive rock\nindie rock protest\nindie rock psychedelic\nindie rock psychedelic Latin\nindie rock psychedelic funk\nindie rock psychedelic garage rock\nindie rock psychedelic latin\nindie rock psychedelic pop\nindie rock psychedelic rock\nindie rock psychedelic rock post-rock\nindie rock psychedelic surf rock\nindie rock psychedelic world music\nindie rock pub rock\nindie rock punk\nindie rock punk blues\nindie rock punk blues rock\nindie rock punk chiptune\nindie rock punk electronic\nindie rock punk funk\nindie rock punk garage rock\nindie rock punk metal\nindie rock punk psychedelic\nindie rock punk rap\nindie rock punk rock\nindie rock punk rock noise rock\nindie rock punk rock rap rock\nindie rock punk ska\nindie rock punk ska-punk\nindie rock rap\nindie rock rap-rock\nindie rock rap-rock alternative metal\nindie rock rap-rock hard rock\nindie rock reggae\nindie rock reggae Latin\nindie rock reggae MPB\nindie rock reggae dub\nindie rock reggae funk\nindie rock reggae psychedelic\nindie rock reggae ska\nindie rock reggae soul\nindie rock reggae surf rock\nindie rock reggae-punk\nindie rock reggae-ska\nindie rock reggaeton\nindie rock retro\nindie rock retro funk\nindie rock retro soul\nindie rock retro-pop\nindie rock rockabilly\nindie rock rockabilly boogie-woogie\nindie rock rockabilly surf rock\nindie rock rockabilly theatrical\nindie rock samba\nindie rock samba-rock\nindie rock sea shanty\nindie rock shoegaze\nindie rock shoegaze J-rock\nindie rock shoegaze alt-country\nindie rock shoegaze alternative\nindie rock shoegaze chiptune\nindie rock shoegaze dream pop\nindie rock shoegaze emo\nindie rock shoegaze jangle pop\nindie rock shoegaze math rock\nindie rock shoegaze neo-soul\nindie rock shoegaze noise pop\nindie rock shoegaze noise rock\nindie rock shoegaze post-hardcore\nindie rock shoegaze post-punk\nindie rock shoegaze post-rock\nindie rock shoegaze punk\nindie rock shoegaze rap-rock\nindie rock ska\nindie rock ska Latin\nindie rock ska Latin rock\nindie rock ska big band\nindie rock ska funk\nindie rock ska jazz\nindie rock ska punk\nindie rock ska reggae\nindie rock ska rock and roll\nindie rock ska soul\nindie rock ska surf rock\nindie rock ska swing\nindie rock ska-punk\nindie rock ska-punk pop-punk\nindie rock ska-punk power-pop\nindie rock ska-punk surf-rock\nindie rock skate punk\nindie rock slacker rock\nindie rock soul\nindie rock soul R&B\nindie rock soul blues\nindie rock soul funk\nindie rock soul gospel\nindie rock soul jazz\nindie rock soul lounge\nindie rock soul rockabilly\nindie rock soul-rock\nindie rock soulful pop\nindie rock southern rock\nindie rock southern rock alt-country\nindie rock space rock\nindie rock space-rock\nindie rock spaghetti western\nindie rock surf\nindie rock surf punk\nindie rock surf rock\nindie rock surf rock Latin\nindie rock surf rock big band\nindie rock surf rock exotica\nindie rock surf rock garage rock\nindie rock surf rock jazz\nindie rock surf rock latin\nindie rock surf rock lounge\nindie rock surf rock psychedelic\nindie rock surf rock reggae\nindie rock surf rock rockabilly\nindie rock surf-pop\nindie rock surf-punk\nindie rock surf-rock\nindie rock surf-rock Latin\nindie rock surf-rock balkan pop\nindie rock surf-rock garage rock\nindie rock surf-rock latin\nindie rock surf-rock rockabilly\nindie rock synth-pop\nindie rock synth-pop chiptune\nindie rock synth-pop emo\nindie rock synth-pop jangle pop\nindie rock synth-pop math rock\nindie rock synth-pop new wave\nindie rock synth-pop party-rock\nindie rock synth-pop pop-punk\nindie rock synth-pop post-punk\nindie rock synth-pop power-pop\nindie rock synth-pop psychedelic\nindie rock synth-pop rap-rock\nindie rock synth-pop shoegaze\nindie rock synth-rock\nindie rock tango\nindie rock tango cinematic\nindie rock tango experimental\nindie rock tango jazz\nindie rock trap\nindie rock trap metal\nindie rock trip-hop\nindie rock vaporwave\nindie rock world fusion\nindie rock world music\nindie rock worldbeat\nindie rock worship\nindie rock, 60s Italian pop-rock\nindie rock, 60s beach pop\nindie rock, 80s new wave\nindie rock, 80s new wave, C-pop\nindie rock, 80s new wave, cinematic\nindie rock, 80s new wave, melancholic\nindie rock, 80s new wave, shoegaze\nindie rock, Americana, Dixieland jazz\nindie rock, Americana, alt-country\nindie rock, Americana, chanson\nindie rock, Americana, country-pop\nindie rock, Americana, country-rock\nindie rock, Americana, folk-rock\nindie rock, Americana, heartland rock\nindie rock, Americana, roots rock\nindie rock, Americana, show tune\nindie rock, Balkan folk-rock\nindie rock, Balkan, Klezmer\nindie rock, Brazilian funk\nindie rock, Brazilian pop-rock\nindie rock, Brazilian rock\nindie rock, Brazilian, Latin-jazz\nindie rock, C-pop\nindie rock, C-pop, ambient\nindie rock, C-pop, cinematic\nindie rock, C-pop, ethnic fusion\nindie rock, C-pop, experimental\nindie rock, C-pop, lo-fi hip hop\nindie rock, C-pop, surf rock\nindie rock, Celtic punk\nindie rock, Chinese folk\nindie rock, Chinese fusion\nindie rock, Christian pop\nindie rock, Christian rock\nindie rock, Deutschrock\nindie rock, EBM, industrial rock\nindie rock, Eastern European folk\nindie rock, Eastern European new wave\nindie rock, Eastern European punk\nindie rock, European folk, theatrical\nindie rock, French chanson\nindie rock, French cold wave\nindie rock, French hip-hop\nindie rock, French new wave\nindie rock, French pop\nindie rock, French pop-rock\nindie rock, French rap, jazz fusion\nindie rock, French rock\nindie rock, G-funk, experimental\nindie rock, German art-rock\nindie rock, German cabaret\nindie rock, German cabaret, theatrical\nindie rock, German cloud rap\nindie rock, German hip-hop\nindie rock, German new wave\nindie rock, German pop-rock\nindie rock, German post-punk\nindie rock, German punk\nindie rock, Greek folk\nindie rock, Greek folk, shoegaze\nindie rock, Greek influence\nindie rock, Greek rock\nindie rock, Hindi rock\nindie rock, Indian classical, cinematic\nindie rock, Indian folk\nindie rock, Indian fusion\nindie rock, Indian rock\nindie rock, Israeli folk\nindie rock, Israeli folk-rock\nindie rock, Italian post-punk\nindie rock, Italo-disco\nindie rock, J-rock\nindie rock, J-rock, alternative rock\nindie rock, J-rock, anime\nindie rock, J-rock, chiptune\nindie rock, J-rock, city pop\nindie rock, J-rock, dream pop\nindie rock, J-rock, emo\nindie rock, J-rock, experimental\nindie rock, J-rock, hyperpop\nindie rock, J-rock, math rock\nindie rock, J-rock, metalcore\nindie rock, J-rock, pop-punk\nindie rock, J-rock, pop-rock\nindie rock, J-rock, power pop\nindie rock, J-rock, punk rock\nindie rock, J-rock, rap-rock\nindie rock, J-rock, shoegaze\nindie rock, J-rock, synth-pop\nindie rock, Japanese punk\nindie rock, K-pop, R&B\nindie rock, K-pop, experimental\nindie rock, K-pop, hip hop\nindie rock, K-rock\nindie rock, Latin alt-rock\nindie rock, Latin alternative\nindie rock, Latin alternative, dance-rock\nindie rock, Latin folk\nindie rock, Latin fusion\nindie rock, Latin hip-hop\nindie rock, Latin indie\nindie rock, Latin indie, dream pop\nindie rock, Latin pop\nindie rock, Latin pop, dance rock\nindie rock, Latin pop, hip hop\nindie rock, Latin pop, world music\nindie rock, Latin pop-rock\nindie rock, Latin punk\nindie rock, Latin rock\nindie rock, Latin rock, dream pop\nindie rock, Latin rock, garage rock\nindie rock, Latin rock, jazz fusion\nindie rock, Latin rock, lo-fi\nindie rock, Latin rock, psychedelic\nindie rock, Latin rock, psychedelic rock\nindie rock, Latin rock, shoegaze\nindie rock, Latin rock, ska\nindie rock, Latin rock, surf rock\nindie rock, Latin rock, tango\nindie rock, Latin trap\nindie rock, Latin, funk\nindie rock, Latin, gypsy-jazz\nindie rock, Latin, jazzy\nindie rock, Latin, quirky\nindie rock, Latin, theatrical\nindie rock, Latin, world music\nindie rock, MPB\nindie rock, MPB, dream pop\nindie rock, MPB, lo-fi\nindie rock, MPB, psychedelic\nindie rock, MPB, soul\nindie rock, Mandarin hip hop, Latin-tinged\nindie rock, Middle Eastern fusion\nindie rock, Middle Eastern, world music\nindie rock, Mizrahi, Middle Eastern\nindie rock, Neue Deutsche Welle\nindie rock, Neue Deutsche Welle, chiptune\nindie rock, Neue Deutsche Welle, electro-funk\nindie rock, North African folk\nindie rock, R&B\nindie rock, R&B, alt-pop\nindie rock, R&B, dream pop\nindie rock, Russian rock\nindie rock, South Asian folk\nindie rock, Southern rock\nindie rock, Spanish rock\nindie rock, UK hardcore, chiptune\nindie rock, UK hip-hop\nindie rock, Vocaloid\nindie rock, Vocaloid, Balkan folk\nindie rock, Vocaloid, electronic folk\nindie rock, Vocaloid, quirky\nindie rock, acoustic ballad\nindie rock, acoustic, melancholic\nindie rock, alt-country\nindie rock, alt-country, Americana\nindie rock, alt-country, lo-fi hip hop\nindie rock, alt-rock\nindie rock, alt-rock, Latin-influenced\nindie rock, alt-rock, cinematic\nindie rock, alt-rock, hip-hop\nindie rock, alt-rock, metal\nindie rock, alt-rock, metalcore\nindie rock, alt-rock, nu-metal\nindie rock, alt-rock, punk rock\nindie rock, alt-rock, rap rock\nindie rock, alt-rock, thrash metal\nindie rock, alternative R&B\nindie rock, alternative hip-hop\nindie rock, alternative metal\nindie rock, alternative metal, ambient\nindie rock, alternative metal, chiptune\nindie rock, alternative rock\nindie rock, alternative rock, German rap\nindie rock, alternative rock, K-pop\nindie rock, alternative rock, Portuguese punk\nindie rock, alternative rock, R&B\nindie rock, alternative rock, dream pop\nindie rock, alternative rock, emo\nindie rock, alternative rock, grunge\nindie rock, alternative rock, hip-hop\nindie rock, alternative rock, lo-fi hip-hop\nindie rock, alternative rock, math rock\nindie rock, alternative rock, pop-punk\nindie rock, alternative rock, post-grunge\nindie rock, alternative rock, post-rock\nindie rock, alternative rock, punk\nindie rock, alternative rock, rap rock\nindie rock, alternative rock, shoegaze\nindie rock, ambient, C-pop\nindie rock, ambient, dream pop\nindie rock, ambient, electronic\nindie rock, ambient, lo-fi hip hop\nindie rock, ambient, metal\nindie rock, ambient, synth-pop\nindie rock, ambient, trap\nindie rock, americana, alt-country\nindie rock, americana, blues-rock\nindie rock, americana, folk-rock\nindie rock, americana, slowcore\nindie rock, arena rock\nindie rock, art rock, cinematic\nindie rock, art rock, lo-fi\nindie rock, baroque pop\nindie rock, baroque pop, experimental\nindie rock, bedroom pop\nindie rock, bedroom pop, emo-rap\nindie rock, bedroom pop, hyperpop\nindie rock, bedroom pop, lo-fi hip hop\nindie rock, big band jazz\nindie rock, big band jazz, experimental\nindie rock, big band, theatrical\nindie rock, big beat\nindie rock, blues rock, cinematic\nindie rock, blues rock, jazz fusion\nindie rock, blues rock, metal\nindie rock, blues-rock\nindie rock, blues-rock, boogie-woogie\nindie rock, blues-rock, metal\nindie rock, bossa nova\nindie rock, bossa nova, MPB\nindie rock, bossa nova, lounge jazz\nindie rock, bossa nova, noise rock\nindie rock, bossa nova, shoegaze\nindie rock, breakcore\nindie rock, cabaret, Latin\nindie rock, cabaret, cinematic\nindie rock, chamber folk, C-pop\nindie rock, chanson, folk\nindie rock, chanson, theatrical\nindie rock, chiptune, C-pop\nindie rock, chiptune, French pop\nindie rock, chiptune, Indonesian pop\nindie rock, chiptune, J-rock\nindie rock, chiptune, a cappella\nindie rock, chiptune, ambient\nindie rock, chiptune, bitpop\nindie rock, chiptune, cinematic\nindie rock, chiptune, dream pop\nindie rock, chiptune, experimental\nindie rock, chiptune, hyperpop\nindie rock, chiptune, jangle pop\nindie rock, chiptune, jazzy punk\nindie rock, chiptune, new wave\nindie rock, chiptune, noise rock\nindie rock, chiptune, pop-punk\nindie rock, chiptune, post-punk\nindie rock, chiptune, power pop\nindie rock, chiptune, psychedelic\nindie rock, chiptune, punk\nindie rock, chiptune, shoegaze\nindie rock, chiptune, synth-pop\nindie rock, chiptune, synthwave\nindie rock, chiptune, theatrical rock\nindie rock, cinematic pop\nindie rock, cinematic rap, emotional synth\nindie rock, cinematic, Hebrew rock\nindie rock, cinematic, J-rock\nindie rock, cinematic, ambient\nindie rock, cinematic, ethereal\nindie rock, cinematic, experimental\nindie rock, cinematic, folk-rock\nindie rock, cinematic, lo-fi\nindie rock, cinematic, lo-fi hip hop\nindie rock, cinematic, orchestral\nindie rock, cinematic, progressive\nindie rock, cinematic, rap\nindie rock, cinematic, world fusion\nindie rock, city pop\nindie rock, city pop, Latin pop\nindie rock, city pop, dream pop\nindie rock, city pop, funk\nindie rock, city pop, jazz\nindie rock, city pop, jazz-funk\nindie rock, city pop, jazz-fusion\nindie rock, city pop, lo-fi\nindie rock, city pop, math rock\nindie rock, city pop, surf rock\nindie rock, city-pop\nindie rock, cloud rap\nindie rock, color bass, hardwave\nindie rock, complextro\nindie rock, complextro, chiptune\nindie rock, complextro, dubstep\nindie rock, complextro, electro-rock\nindie rock, conscious hip-hop\nindie rock, cumbia, Latin pop\nindie rock, cumbia, blues rock\nindie rock, cumbia, folk\nindie rock, cumbia, surf rock\nindie rock, cyberpunk, metalcore\nindie rock, dance rock, house\nindie rock, dance-punk\nindie rock, dance-rock, synth-pop\nindie rock, dangdut koplo\nindie rock, dark Americana\nindie rock, deep house\nindie rock, desert rock\nindie rock, disco-rock, punk rock\nindie rock, doom metal\nindie rock, dream pop\nindie rock, dream pop, C-pop\nindie rock, dream pop, K-pop\nindie rock, dream pop, Latin hip-hop\nindie rock, dream pop, Latin indie\nindie rock, dream pop, Mandarin hip hop\nindie rock, dream pop, alternative rock\nindie rock, dream pop, ambient\nindie rock, dream pop, breakcore\nindie rock, dream pop, electronic\nindie rock, dream pop, emo-pop\nindie rock, dream pop, hard rock\nindie rock, dream pop, hip-hop\nindie rock, dream pop, hyperpop\nindie rock, dream pop, jazz\nindie rock, dream pop, lo-fi\nindie rock, dream pop, lo-fi hip hop\nindie rock, dream pop, math rock\nindie rock, dream pop, noise rock\nindie rock, dream pop, post-punk\nindie rock, dream pop, post-rock\nindie rock, dream pop, psychedelic\nindie rock, dream pop, shoegaze\nindie rock, dream pop, synth-pop\nindie rock, dream pop, trap\nindie rock, dream-pop\nindie rock, dream-pop, Latin indie\nindie rock, dream-pop, art-rock\nindie rock, dream-pop, metalcore\nindie rock, dream-pop, noise rock\nindie rock, dream-pop, noise-rock\nindie rock, dream-pop, pop-punk\nindie rock, dream-pop, post-rock\nindie rock, dream-pop, shoegaze\nindie rock, dream-pop, surf-rock\nindie rock, dreamy, post-rock\nindie rock, drum and bass\nindie rock, drum and bass, alternative\nindie rock, drum and bass, neurofunk\nindie rock, drum and bass, pop-punk\nindie rock, dubstep\nindie rock, dubstep, C-pop\nindie rock, dubstep, bass house\nindie rock, electro house\nindie rock, electro-rock\nindie rock, electronic\nindie rock, electronic rock\nindie rock, electronic rock, dance-punk\nindie rock, electronic rock, dubstep\nindie rock, electronic rock, hyperpop\nindie rock, electronic rock, nu-metal\nindie rock, electronic, C-pop\nindie rock, electronic, French rap\nindie rock, electronic, Mandarin pop\nindie rock, electronic, chiptune\nindie rock, electronic, cinematic\nindie rock, electronic, dubstep\nindie rock, electronic, glitch\nindie rock, electronic, gospel\nindie rock, electronic, hardstyle\nindie rock, electronic, hip-hop\nindie rock, electronic, noise rock\nindie rock, electronic, pop\nindie rock, electronic, pop-punk\nindie rock, electronic, shoegaze\nindie rock, electronic, trap\nindie rock, electronic, world music\nindie rock, emo\nindie rock, emo, C-pop\nindie rock, emo, alternative rock\nindie rock, emo, garage rock\nindie rock, emo, hip hop\nindie rock, emo, hip-hop\nindie rock, emo, hyperpop\nindie rock, emo, lo-fi\nindie rock, emo, lo-fi hip hop\nindie rock, emo, metalcore\nindie rock, emo, pop-R&B\nindie rock, emo, pop-punk\nindie rock, emo, post-hardcore\nindie rock, emo, shoegaze\nindie rock, emo, trap\nindie rock, emo-pop, R&B\nindie rock, emo-pop, hyperpop\nindie rock, emo-pop, lo-fi\nindie rock, emo-rap, electronic\nindie rock, ethereal, Persian folk\nindie rock, eurodance, trance\nindie rock, experimental electronic\nindie rock, experimental hip-hop\nindie rock, experimental, psychedelic rock\nindie rock, flamenco fusion, cinematic rock\nindie rock, flamenco, cinematic\nindie rock, folk\nindie rock, folk, Arabic\nindie rock, folk, C-pop\nindie rock, folk, ambient\nindie rock, folk-punk, French rock\nindie rock, folk-punk, dream-pop\nindie rock, free jazz\nindie rock, funk rock\nindie rock, funk, Hebrew rock\nindie rock, future bass\nindie rock, future bass, C-pop\nindie rock, future bass, EDM\nindie rock, future bass, dream pop\nindie rock, future bass, electronic\nindie rock, future bass, hyperpop\nindie rock, future bass, lo-fi\nindie rock, future bass, melodic dubstep\nindie rock, future bass, progressive house\nindie rock, future bass, rap\nindie rock, garage punk, emo\nindie rock, garage punk, psychedelic\nindie rock, garage rock\nindie rock, garage rock, Latin rock\nindie rock, garage rock, Mandarin rap\nindie rock, garage rock, noise rock\nindie rock, garage rock, post-punk\nindie rock, garage rock, power pop\nindie rock, garage rock, punk\nindie rock, garage rock, punk rock\nindie rock, glitch hop, ambient\nindie rock, glitch, breakcore\nindie rock, glitch, lo-fi\nindie rock, glitch-hop\nindie rock, glitch-hop, breakcore\nindie rock, glitch-hop, dubstep\nindie rock, gospel, Americana\nindie rock, gospel, industrial rock\nindie rock, gospel, jazz\nindie rock, grunge, alternative rock\nindie rock, grunge, ambient\nindie rock, grunge, hard rock\nindie rock, gypsy jazz, French chanson\nindie rock, hard rock\nindie rock, hard rock, Chinese rock\nindie rock, hard rock, Italian pop\nindie rock, hard rock, Vietnamese folk rock\nindie rock, hard rock, atmospheric\nindie rock, hard rock, blues rock\nindie rock, hard rock, blues-rock\nindie rock, hard rock, cinematic\nindie rock, hard rock, dream pop\nindie rock, hard rock, experimental\nindie rock, hard rock, grunge\nindie rock, hard rock, melodic guitar\nindie rock, hard rock, melodic rock\nindie rock, hard rock, metal\nindie rock, hard rock, metalcore\nindie rock, hard rock, punk rock\nindie rock, hardcore punk\nindie rock, hardcore trance\nindie rock, hardstyle\nindie rock, hardstyle, fusion\nindie rock, hardstyle, pop-punk\nindie rock, hardstyle, trap\nindie rock, hardstyle, trap metal\nindie rock, heavy metal\nindie rock, hip hop\nindie rock, hip hop, soul\nindie rock, hip-hop\nindie rock, hip-hop, C-pop\nindie rock, hip-hop, Mandarin pop\nindie rock, hip-hop, R&B\nindie rock, hip-hop, alternative rock\nindie rock, hip-hop, ambient\nindie rock, hip-hop, bilingual\nindie rock, hip-hop, cinematic\nindie rock, hip-hop, cinematic rock\nindie rock, hip-hop, electronic\nindie rock, hip-hop, emo\nindie rock, hip-hop, emotional\nindie rock, hip-hop, funk\nindie rock, hip-hop, hyperpop\nindie rock, hip-hop, lo-fi\nindie rock, hip-hop, nu-metal\nindie rock, hip-hop, pop-punk\nindie rock, hip-hop, post-hardcore\nindie rock, hip-hop, post-rock\nindie rock, hip-hop, shoegaze\nindie rock, hip-hop, synth pop\nindie rock, hip-hop, synth-pop\nindie rock, hip-hop, trap\nindie rock, house, electronic\nindie rock, hyperpop\nindie rock, hyperpop, cinematic\nindie rock, hyperpop, drum and bass\nindie rock, hyperpop, electronic\nindie rock, hyperpop, emo\nindie rock, hyperpop, emo-rap\nindie rock, hyperpop, lo-fi\nindie rock, hyperpop, nightcore\nindie rock, hyperpop, pop-punk\nindie rock, hyperpop, shoegaze\nindie rock, hyperpop, synth-pop\nindie rock, hyperpop, trap metal\nindie rock, indie pop\nindie rock, indie-pop\nindie rock, industrial hip-hop, breakcore\nindie rock, industrial metalcore\nindie rock, industrial metalcore, cyberpunk\nindie rock, industrial pop\nindie rock, industrial rock, math rock\nindie rock, industrial trap\nindie rock, industrial, Chinese pop\nindie rock, industrial, German rock\nindie rock, industrial, lo-fi hip hop\nindie rock, j-pop, jazz\nindie rock, jangle pop\nindie rock, jangle pop, Bengali pop\nindie rock, jangle pop, French indie\nindie rock, jangle pop, rock en español\nindie rock, jazz fusion, cinematic\nindie rock, jazz fusion, lo-fi hip hop\nindie rock, jazz fusion, psychedelic\nindie rock, jazz, noise rock\nindie rock, jazz, punk rock\nindie rock, jazz, soul\nindie rock, jazz-rock, alt-rock\nindie rock, klezmer, folk\nindie rock, klezmer, lo-fi\nindie rock, lo-fi acoustic\nindie rock, lo-fi garage rock\nindie rock, lo-fi hip hop\nindie rock, lo-fi hip hop, C-pop\nindie rock, lo-fi hip hop, Chinese pop\nindie rock, lo-fi hip hop, Chinese rap\nindie rock, lo-fi hip hop, R&B\nindie rock, lo-fi hip hop, ambient\nindie rock, lo-fi hip hop, dream pop\nindie rock, lo-fi hip hop, trap\nindie rock, lo-fi hip-hop, blues\nindie rock, lo-fi hip-hop, post-rock\nindie rock, lo-fi jazz, psychedelic\nindie rock, lo-fi, ambient\nindie rock, lo-fi, bedroom pop\nindie rock, lo-fi, cinematic\nindie rock, lo-fi, dream pop\nindie rock, lo-fi, glitch\nindie rock, lo-fi, industrial\nindie rock, lo-fi, pop, pop-punk\nindie rock, lo-fi, psychedelic\nindie rock, lo-fi, trap\nindie rock, mariachi, Balkan brass\nindie rock, math rock\nindie rock, math rock, C-pop\nindie rock, math rock, Chinese hip hop\nindie rock, math rock, J-rock\nindie rock, math rock, Mandarin rap\nindie rock, math rock, Vocaloid\nindie rock, math rock, ambient\nindie rock, math rock, chiptune\nindie rock, math rock, cinematic\nindie rock, math rock, city pop\nindie rock, math rock, dream pop\nindie rock, math rock, dream-pop\nindie rock, math rock, dubstep\nindie rock, math rock, emo\nindie rock, math rock, emo-pop\nindie rock, math rock, jazz fusion\nindie rock, math rock, lo-fi\nindie rock, math rock, lo-fi hip hop\nindie rock, math rock, pop-punk\nindie rock, math rock, progressive metal\nindie rock, math rock, progressive rock\nindie rock, math rock, punk rock\nindie rock, math rock, shoegaze\nindie rock, melancholic, post-rock\nindie rock, melodic hardcore\nindie rock, melodic rap, pop\nindie rock, metalcore\nindie rock, metalcore, djent\nindie rock, metalcore, electronic\nindie rock, metalcore, pop-punk\nindie rock, metalcore, post-hardcore\nindie rock, metalcore, rap-rock\nindie rock, metalcore, synthpop\nindie rock, modern rock, nu-metal\nindie rock, neurofunk\nindie rock, new wave\nindie rock, new wave, Eastern European\nindie rock, new wave, Spanish rock\nindie rock, new wave, boogie-woogie\nindie rock, new wave, chiptune\nindie rock, new wave, garage rock\nindie rock, new wave, lo-fi\nindie rock, new wave, lounge-rock\nindie rock, new wave, post-punk\nindie rock, new wave, power pop\nindie rock, new wave, ska\nindie rock, new wave, surf rock\nindie rock, new wave, synth rock\nindie rock, new wave, synth-pop\nindie rock, noir jazz, C-pop\nindie rock, noise rock\nindie rock, noise rock, French pop\nindie rock, noise rock, Japanese lo-fi\nindie rock, noise rock, Latin percussion\nindie rock, noise rock, Portuguese folk\nindie rock, noise rock, anthemic\nindie rock, noise rock, cinematic\nindie rock, noise rock, dream pop\nindie rock, noise rock, drum and bass\nindie rock, noise rock, garage rock\nindie rock, noise rock, hard rock\nindie rock, noise rock, lo-fi\nindie rock, noise rock, post-hardcore\nindie rock, noise rock, post-rock\nindie rock, noise rock, shoegaze\nindie rock, noise rock, thrash metal\nindie rock, nu-disco\nindie rock, nu-disco, orchestral\nindie rock, nu-metal\nindie rock, nu-metal, cinematic\nindie rock, nu-metal, industrial rock\nindie rock, nu-metal, rap rock\nindie rock, nu-metal, rap-rock\nindie rock, nu-metal, trap\nindie rock, orchestral, electronic\nindie rock, phonk, trap metal\nindie rock, polka, Latin\nindie rock, pop\nindie rock, pop, rap-rock\nindie rock, pop-punk\nindie rock, pop-punk, C-pop\nindie rock, pop-punk, Chinese rock\nindie rock, pop-punk, J-rock\nindie rock, pop-punk, Mandarin rap\nindie rock, pop-punk, R&B\nindie rock, pop-punk, alternative rock\nindie rock, pop-punk, chiptune\nindie rock, pop-punk, emo\nindie rock, pop-punk, emo revival\nindie rock, pop-punk, emo rock\nindie rock, pop-punk, emo-pop\nindie rock, pop-punk, emo-rap\nindie rock, pop-punk, emo-rock\nindie rock, pop-punk, hardcore punk\nindie rock, pop-punk, hip-hop\nindie rock, pop-punk, hyperpop\nindie rock, pop-punk, lo-fi\nindie rock, pop-punk, lo-fi chiptune\nindie rock, pop-punk, lo-fi hip hop\nindie rock, pop-punk, math rock\nindie rock, pop-punk, metalcore\nindie rock, pop-punk, neo-soul\nindie rock, pop-punk, post-hardcore\nindie rock, pop-punk, rap-rock\nindie rock, pop-punk, synth-pop\nindie rock, pop-punk, trap\nindie rock, pop-rock\nindie rock, pop-rock, Chinese hip-hop\nindie rock, pop-rock, acoustic\nindie rock, pop-rock, hard rock\nindie rock, pop-rock, hip-hop\nindie rock, pop-rock, nu-metal\nindie rock, pop-rock, post-hardcore\nindie rock, pop-rock, synthwave\nindie rock, post-grunge, emo\nindie rock, post-hardcore\nindie rock, post-hardcore, Chinese folk rock\nindie rock, post-hardcore, Mandarin rock\nindie rock, post-hardcore, acoustic ballad\nindie rock, post-hardcore, alternative metal\nindie rock, post-hardcore, chiptune\nindie rock, post-hardcore, cinematic\nindie rock, post-hardcore, emo\nindie rock, post-hardcore, lo-fi\nindie rock, post-hardcore, math rock\nindie rock, post-hardcore, metalcore\nindie rock, post-hardcore, noise rock\nindie rock, post-hardcore, shoegaze\nindie rock, post-metal, shoegaze\nindie rock, post-punk\nindie rock, post-punk revival\nindie rock, post-punk, Brazilian rock\nindie rock, post-punk, C-pop\nindie rock, post-punk, Eastern European\nindie rock, post-punk, Latin rock\nindie rock, post-punk, Spanish rock\nindie rock, post-punk, alternative\nindie rock, post-punk, ambient\nindie rock, post-punk, cinematic\nindie rock, post-punk, darkwave\nindie rock, post-punk, dream pop\nindie rock, post-punk, dream-pop\nindie rock, post-punk, electronic\nindie rock, post-punk, lo-fi\nindie rock, post-punk, lo-fi hip hop\nindie rock, post-punk, new wave\nindie rock, post-punk, noise rock\nindie rock, post-punk, psychedelic\nindie rock, post-punk, psychedelic rock\nindie rock, post-punk, shoegaze\nindie rock, post-punk, synth-pop\nindie rock, post-rock\nindie rock, post-rock, C-pop\nindie rock, post-rock, Chinese folk\nindie rock, post-rock, Chinese indie\nindie rock, post-rock, Chinese rock\nindie rock, post-rock, Hebrew vocal\nindie rock, post-rock, Italian folk\nindie rock, post-rock, K-indie\nindie rock, post-rock, Korean indie\nindie rock, post-rock, Latin\nindie rock, post-rock, Spanish folk\nindie rock, post-rock, Spanish indie\nindie rock, post-rock, Spanish vocal\nindie rock, post-rock, Turkish rock\nindie rock, post-rock, acoustic\nindie rock, post-rock, alternative metal\nindie rock, post-rock, alternative rock\nindie rock, post-rock, ambient\nindie rock, post-rock, atmospheric\nindie rock, post-rock, baroque pop\nindie rock, post-rock, chiptune\nindie rock, post-rock, cinematic\nindie rock, post-rock, dream pop\nindie rock, post-rock, dream-pop\nindie rock, post-rock, dreamy\nindie rock, post-rock, drum and bass\nindie rock, post-rock, electronic\nindie rock, post-rock, emo\nindie rock, post-rock, folk\nindie rock, post-rock, folk ballad\nindie rock, post-rock, funk rock\nindie rock, post-rock, lo-fi\nindie rock, post-rock, math rock\nindie rock, post-rock, math-rock\nindie rock, post-rock, metalcore\nindie rock, post-rock, noise rock\nindie rock, post-rock, pop-rock\nindie rock, post-rock, psychedelic\nindie rock, post-rock, punk rock\nindie rock, post-rock, rap-rock\nindie rock, post-rock, shoegaze\nindie rock, power pop\nindie rock, power pop, alternative rock\nindie rock, power pop, chiptune\nindie rock, power pop, lo-fi\nindie rock, power pop, new wave\nindie rock, power-pop\nindie rock, power-pop, Latin percussion\nindie rock, power-pop, chiptune\nindie rock, power-pop, cinematic\nindie rock, power-pop, funk-rock\nindie rock, power-pop, lo-fi\nindie rock, power-pop, musical theater\nindie rock, power-pop, new wave\nindie rock, power-pop, noise rock\nindie rock, power-pop, psychedelic\nindie rock, power-pop, rap-rock\nindie rock, power-pop, ska\nindie rock, progressive house\nindie rock, progressive house, EDM\nindie rock, progressive house, big room\nindie rock, progressive house, trance\nindie rock, progressive metal\nindie rock, psychedelic\nindie rock, psychedelic metal\nindie rock, psychedelic pop\nindie rock, psychedelic rock\nindie rock, psychedelic rock, Latin rock\nindie rock, psychedelic rock, ballad\nindie rock, psychedelic rock, desert rock\nindie rock, psychedelic rock, garage rock\nindie rock, psychedelic rock, hard rock\nindie rock, psychedelic rock, noise rock\nindie rock, psychedelic rock, post-punk\nindie rock, psychedelic rock, space rock\nindie rock, psychedelic rock, surf rock\nindie rock, psychedelic, cyberpunk\nindie rock, psychedelic, dream pop\nindie rock, psychedelic, electronic\nindie rock, psychedelic, lo-fi\nindie rock, psychedelic, satirical\nindie rock, psychedelic, surf rock\nindie rock, psychedelic, world music\nindie rock, punk rock\nindie rock, punk rock, Latin rock\nindie rock, punk rock, chiptune\nindie rock, punk rock, lo-fi\nindie rock, punk rock, noise rock\nindie rock, punk rock, rap rock\nindie rock, punk rock, retro-funk\nindie rock, punk rock, ska-punk\nindie rock, punk rock, thrash metal\nindie rock, punk, Mandarin rock\nindie rock, punk, Russian rock\nindie rock, punk, blues-rock\nindie rock, punk, electronic\nindie rock, punk, hip-hop\nindie rock, punk, noise rock\nindie rock, punk, rap-rock\nindie rock, ragtime, noise rock\nindie rock, ragtime, punk rock\nindie rock, rap, Finnish\nindie rock, rap, electronic\nindie rock, rap, nu-metal\nindie rock, rap-rock\nindie rock, rap-rock, Mandarin rock\nindie rock, rap-rock, alternative\nindie rock, rap-rock, ambient\nindie rock, rap-rock, atmospheric\nindie rock, rap-rock, electronic\nindie rock, rap-rock, jazz fusion\nindie rock, rap-rock, vaporwave\nindie rock, rockabilly\nindie rock, rockabilly, surf rock\nindie rock, rockabilly, theatrical\nindie rock, samba-reggae\nindie rock, shoegaze\nindie rock, shoegaze, 90s alternative\nindie rock, shoegaze, C-pop\nindie rock, shoegaze, Chinese pop\nindie rock, shoegaze, J-rock\nindie rock, shoegaze, K-indie\nindie rock, shoegaze, Latin pop\nindie rock, shoegaze, Mandarin pop\nindie rock, shoegaze, Spanish rock\nindie rock, shoegaze, alternative\nindie rock, shoegaze, alternative rock\nindie rock, shoegaze, ambient\nindie rock, shoegaze, chiptune\nindie rock, shoegaze, cinematic\nindie rock, shoegaze, dream pop\nindie rock, shoegaze, drum and bass\nindie rock, shoegaze, garage rock\nindie rock, shoegaze, hyperpop\nindie rock, shoegaze, lo-fi\nindie rock, shoegaze, lo-fi hip hop\nindie rock, shoegaze, lo-fi hip-hop\nindie rock, shoegaze, math-rock\nindie rock, shoegaze, minimalist\nindie rock, shoegaze, noise pop\nindie rock, shoegaze, noise rock\nindie rock, shoegaze, nu-metal\nindie rock, shoegaze, post-hardcore\nindie rock, shoegaze, post-rock\nindie rock, shoegaze, psychedelic\nindie rock, shoegaze, vocaloid\nindie rock, skate punk\nindie rock, slowcore\nindie rock, southern rock\nindie rock, space rock, power pop\nindie rock, stoner rock, ambient\nindie rock, sunshine pop\nindie rock, surf rock\nindie rock, surf rock, French pop\nindie rock, surf rock, Italian rock\nindie rock, surf rock, Latin rock\nindie rock, surf rock, Spanish indie\nindie rock, surf rock, cinematic\nindie rock, surf rock, exotica\nindie rock, surf rock, garage rock\nindie rock, surf rock, psychedelic\nindie rock, surf rock, samba-rock\nindie rock, surf-pop\nindie rock, surf-punk\nindie rock, surf-rock, pop-punk\nindie rock, surf-rock, ska\nindie rock, synth pop\nindie rock, synth pop, Spanish\nindie rock, synth pop, Vocaloid\nindie rock, synth rock, Russian rock\nindie rock, synth-pop\nindie rock, synth-pop, C-pop\nindie rock, synth-pop, Latin rock\nindie rock, synth-pop, Neue Deutsche Welle\nindie rock, synth-pop, chiptune\nindie rock, synth-pop, city pop\nindie rock, synth-pop, classical\nindie rock, synth-pop, dance-rock\nindie rock, synth-pop, dream pop\nindie rock, synth-pop, funk\nindie rock, synth-pop, garage rock\nindie rock, synth-pop, lounge jazz\nindie rock, synth-pop, new wave\nindie rock, synth-pop, post-punk\nindie rock, synth-pop, power-pop\nindie rock, synth-pop, rap rock\nindie rock, synth-pop, rap-rock\nindie rock, synth-rock, atmospheric\nindie rock, tech house\nindie rock, tech house, electronic\nindie rock, theatrical rock, punk rock\nindie rock, thrash metal\nindie rock, thrash-punk\nindie rock, traditional East Asian, folk rock\nindie rock, trance\nindie rock, trap\nindie rock, trap R&B\nindie rock, trap metal, hyperpop\nindie rock, trap metal, metalcore\nindie rock, trap, C-pop\nindie rock, trap, J-pop\nindie rock, trap, K-pop\nindie rock, trap, R&B\nindie rock, trap, Vietnamese pop\nindie rock, trap, ambient\nindie rock, trap, atmospheric\nindie rock, trap, breakcore\nindie rock, trap, dream pop\nindie rock, trap, electronic\nindie rock, trap, emo\nindie rock, trap, gospel\nindie rock, trap, hyperpop\nindie rock, trap, lo-fi\nindie rock, trip-hop\nindie rock, trip-hop, ambient\nindie rock, trip-hop, art rock\nindie rock, trip-hop, atmospheric\nindie rock, trip-hop, lo-fi\nindie rock, upbeat, California vibe\nindie rock, vaporwave, emo\nindie rock, vaporwave, hip hop\nindie rock, world fusion\nindie rock, world music\nindie rock, world music, Spanish pop\nindie rock, world music, cinematic\nindie rock, world music, emotional rock\nindie rock, world music, garage rock\nindie rock, world music, hip-hop\nindie rock, world music, piano ballad\nindie rock, world music, post-rock\nindie rock, world music, shoegaze\nindie rock, world music, spiritual\nindie rock, world music, synth pop\nindie shoegaze\nindie singer-songwriter\nindie soul\nindie soul bossa nova\nindie soul funk-rock\nindie soul jazz\nindie soul neo-soul\nindie soul psychedelic folk\nindie surf rock\nindie surf-pop\nindie surf-rock\nindie synth\nindie synth-pop\nindie synth-pop chiptune\nindie synthwave\nindie trap\nindie waltz\nindie worship\nindie, lo-fi, atmospheric\nindie-R&B trap\nindie-dance\nindie-dance funk\nindie-dance lo-fi\nindie-electro\nindie-electronic\nindie-electronic ballad\nindie-electronic chiptune\nindie-electronic funk\nindie-electronic future bass\nindie-electronic hyperpop\nindie-electronic lo-fi\nindie-electronic lo-fi hip-hop\nindie-electronic pop\nindie-electronic shoegaze\nindie-electronic synth-pop\nindie-folk\nindie-folk Celtic\nindie-folk Christian rock\nindie-folk Latin\nindie-folk R&B\nindie-folk alt-country\nindie-folk alt-country bar-room rock\nindie-folk alt-rock\nindie-folk alt-rock post-hardcore\nindie-folk alternative rock\nindie-folk alternative rock trip-hop\nindie-folk ambient\nindie-folk americana\nindie-folk blues\nindie-folk blues-rock\nindie-folk bossa nova\nindie-folk chanson\nindie-folk chiptune\nindie-folk cinematic\nindie-folk cinematic rock\nindie-folk country bluegrass\nindie-folk country swing\nindie-folk dance-pop\nindie-folk dark pop\nindie-folk dream pop\nindie-folk dream pop psychedelic rock\nindie-folk dream-pop\nindie-folk electronic\nindie-folk electronic-pop\nindie-folk emo\nindie-folk emo rock\nindie-folk emo-rap\nindie-folk emo-rap pop-punk\nindie-folk emo-rock\nindie-folk funk-rock\nindie-folk future bass\nindie-folk garage punk\nindie-folk garage rock\nindie-folk grunge\nindie-folk hip hop\nindie-folk hip-hop\nindie-folk hip-hop pop-rock\nindie-folk hip-hop rock\nindie-folk hyperpop\nindie-folk indie-pop\nindie-folk jazz\nindie-folk jazz lounge\nindie-folk lo-fi\nindie-folk lo-fi hip hop\nindie-folk lo-fi hip-hop\nindie-folk lo-fi indie rock\nindie-folk lounge-jazz\nindie-folk math-rock\nindie-folk metalcore\nindie-folk neo-soul\nindie-folk noise rock\nindie-folk noise-pop\nindie-folk noise-rock\nindie-folk pop\nindie-folk pop-punk\nindie-folk pop-rock\nindie-folk post-hardcore\nindie-folk post-hardcore math-rock\nindie-folk post-punk\nindie-folk post-rock\nindie-folk power-pop\nindie-folk psychedelic rock\nindie-folk punk\nindie-folk punk rock\nindie-folk ragtime\nindie-folk rap-rock\nindie-folk reggae\nindie-folk rock\nindie-folk rumba\nindie-folk shoegaze\nindie-folk ska-punk\nindie-folk synth-pop\nindie-folk trap\nindie-folk trap R&B\nindie-folk trap-pop\nindie-folk tropical\nindie-folk worship\nindie-folk, J-rock\nindie-folk, Latin pop, cinematic\nindie-folk, Latin rock\nindie-folk, Latin, world music\nindie-folk, Middle Eastern fusion\nindie-folk, South Asian folk\nindie-folk, alt-rock\nindie-folk, alt-rock, psychedelic rock\nindie-folk, alternative rock\nindie-folk, alternative rock, conscious hip-hop\nindie-folk, alternative rock, metalcore\nindie-folk, alternative rock, post-grunge\nindie-folk, alternative rock, post-hardcore\nindie-folk, alternative rock, post-rock\nindie-folk, alternative rock, shoegaze\nindie-folk, ambient, dark electronic\nindie-folk, americana, roots rock\nindie-folk, anti-folk, lo-fi\nindie-folk, art-rock, psychedelic\nindie-folk, bluegrass\nindie-folk, bossa nova, latin\nindie-folk, breakcore\nindie-folk, christian rock\nindie-folk, cinematic pop, electronic\nindie-folk, cinematic rock\nindie-folk, cinematic, hip-hop\nindie-folk, cinematic, rock\nindie-folk, dance-pop\nindie-folk, deep house\nindie-folk, drum and bass, ambient\nindie-folk, drum and bass, neurofunk\nindie-folk, dubstep\nindie-folk, electronic rock\nindie-folk, electronic rock, future bass\nindie-folk, electronic, ambient\nindie-folk, electronic, trap\nindie-folk, emo, pop-punk\nindie-folk, emo-rock\nindie-folk, emo-rock, post-hardcore\nindie-folk, experimental, electronic\nindie-folk, experimental, lo-fi hip-hop\nindie-folk, folk-punk\nindie-folk, folk-rock\nindie-folk, folk-rock, garage rock\nindie-folk, future bass\nindie-folk, future bass, trap\nindie-folk, garage rock\nindie-folk, garage rock, bluegrass punk\nindie-folk, garage rock, noise rock\nindie-folk, happy hardcore, Dutch rap\nindie-folk, hard rock\nindie-folk, hardstyle\nindie-folk, hip-hop, anthemic\nindie-folk, hyperpop, glitchcore\nindie-folk, indie-pop\nindie-folk, industrial electronic\nindie-folk, industrial rock, noise-rock\nindie-folk, industrial trap\nindie-folk, lo-fi hip hop, trap\nindie-folk, lo-fi hip-hop, industrial rock\nindie-folk, lo-fi, experimental\nindie-folk, noise-rock\nindie-folk, nu-disco\nindie-folk, polka\nindie-folk, pop-punk\nindie-folk, pop-punk, alt-rock\nindie-folk, pop-punk, post-hardcore\nindie-folk, pop-rock, cabaret\nindie-folk, pop-rock, emo-pop\nindie-folk, post-hardcore\nindie-folk, post-rock\nindie-folk, post-rock, glitch\nindie-folk, post-rock, shoegaze\nindie-folk, progressive house\nindie-folk, psychedelic rock\nindie-folk, psychedelic rock, rockabilly\nindie-folk, psychedelic rock, surf-rock\nindie-folk, psychedelic rock, theatrical rock\nindie-folk, shoegaze\nindie-folk, shoegaze, alternative rock\nindie-folk, shoegaze, electronic\nindie-folk, shoegaze, noise-rock\nindie-folk, shoegaze, post-rock\nindie-folk, synth-pop, cinematic\nindie-folk, synth-pop, indie-electronic\nindie-folk, theatrical, cinematic\nindie-folk, trap R&B\nindie-funk\nindie-funk lo-fi\nindie-funk lo-fi hip hop\nindie-funk neo-soul\nindie-funk pop-punk\nindie-funk rock\nindie-funk tropical\nindie-gospel\nindie-jazz\nindie-pop\nindie-pop 80s new wave\nindie-pop Afrobeats\nindie-pop Balkan folk\nindie-pop Balkan jazz\nindie-pop Bollywood\nindie-pop C-pop\nindie-pop C-pop acoustic pop-rap\nindie-pop Christmas\nindie-pop EDM\nindie-pop European chanson\nindie-pop European folk\nindie-pop French chanson\nindie-pop French hip-hop\nindie-pop French-pop\nindie-pop German rock\nindie-pop Indian fusion\nindie-pop J-pop\nindie-pop J-rock\nindie-pop K-pop synth-pop\nindie-pop Latin\nindie-pop Latin Bollywood\nindie-pop Latin jazz\nindie-pop Latin pop\nindie-pop R&B\nindie-pop R&B jazz fusion\nindie-pop R&B lo-fi\nindie-pop R&B metalcore\nindie-pop alt-rock\nindie-pop alternative R&B\nindie-pop alternative rock\nindie-pop ambient\nindie-pop art-rock\nindie-pop art-rock funk-rock\nindie-pop bedroom pop\nindie-pop bedroom-pop\nindie-pop blues country\nindie-pop blues swing\nindie-pop blues-rock\nindie-pop bossa nova\nindie-pop bossa nova cabaret\nindie-pop bossa nova lounge\nindie-pop bossa nova lounge jazz\nindie-pop cabaret\nindie-pop cabaret jazz\nindie-pop cabaret swing\nindie-pop chamber pop\nindie-pop chanson\nindie-pop children's\nindie-pop children's music\nindie-pop chillwave\nindie-pop chiptune\nindie-pop chiptune Bollywood\nindie-pop chiptune J-pop\nindie-pop chiptune city-pop\nindie-pop chiptune exotica\nindie-pop chiptune lo-fi\nindie-pop chiptune lounge\nindie-pop cinematic\nindie-pop city-pop\nindie-pop cloud rap\nindie-pop complextro\nindie-pop country-folk\nindie-pop cumbia lo-fi\nindie-pop cyber-folk\nindie-pop dance\nindie-pop dance-pop\nindie-pop dance-rock\nindie-pop deep house\nindie-pop disco-funk\nindie-pop disco-rock\nindie-pop downtempo\nindie-pop dream pop\nindie-pop dream pop noise rock\nindie-pop dream-pop\nindie-pop drum and bass\nindie-pop dubstep\nindie-pop electro\nindie-pop electro house\nindie-pop electro-funk\nindie-pop electro-house\nindie-pop electro-pop\nindie-pop electro-rock\nindie-pop electronic\nindie-pop electronic rock\nindie-pop electronic world music\nindie-pop electronic-rock\nindie-pop electronicore\nindie-pop electropop\nindie-pop emo rap\nindie-pop emo-pop\nindie-pop emo-pop hip-hop\nindie-pop emo-rap\nindie-pop emo-rock\nindie-pop experimental hip-hop\nindie-pop folk\nindie-pop folk-pop\nindie-pop folk-rock\nindie-pop french chanson\nindie-pop funk\nindie-pop funk Bollywood\nindie-pop funk disco\nindie-pop funk neo-soul\nindie-pop funk-pop\nindie-pop funk-pop industrial rock\nindie-pop funk-rock\nindie-pop funky\nindie-pop future bass\nindie-pop future-bass\nindie-pop garage punk\nindie-pop garage rock\nindie-pop ghazal\nindie-pop glitch-hop\nindie-pop glitch-pop\nindie-pop gypsy jazz\nindie-pop gypsy-jazz\nindie-pop hip-hop\nindie-pop hip-hop rock\nindie-pop house\nindie-pop hyperpop\nindie-pop hyperpop emo rap\nindie-pop indie rock\nindie-pop industrial rock\nindie-pop industrial-trap\nindie-pop j-pop\nindie-pop jazz\nindie-pop jazz R&B\nindie-pop jazz lo-fi hip-hop\nindie-pop jazz lounge\nindie-pop jazz noir\nindie-pop jazz soul\nindie-pop jazz swing\nindie-pop jazz-fusion math-rock\nindie-pop jazz-pop\nindie-pop jazzy\nindie-pop jazzy bossa nova\nindie-pop latin\nindie-pop latin-pop\nindie-pop lo-fi\nindie-pop lo-fi R&B\nindie-pop lo-fi accordion\nindie-pop lo-fi bedroom pop\nindie-pop lo-fi chiptune\nindie-pop lo-fi cinematic\nindie-pop lo-fi hip hop\nindie-pop lo-fi hip-hop\nindie-pop lo-fi pop\nindie-pop lo-fi rap rock\nindie-pop lo-fi synth-pop\nindie-pop lo-fi vaporwave\nindie-pop lounge\nindie-pop lounge bossa nova\nindie-pop lounge jazz\nindie-pop lounge-jazz\nindie-pop math rock\nindie-pop math-rock\nindie-pop mediterranean\nindie-pop metalcore\nindie-pop neo-soul\nindie-pop neo-soul bossa nova\nindie-pop noise-rock\nindie-pop novelty\nindie-pop nu-disco\nindie-pop nu-disco deep house\nindie-pop nu-disco funk\nindie-pop nu-disco funk-pop\nindie-pop nu-disco synth-pop\nindie-pop nu-metal\nindie-pop pop-punk\nindie-pop post-hardcore\nindie-pop post-rock\nindie-pop power-pop\nindie-pop power-pop noise-rock\nindie-pop progressive house\nindie-pop psychedelic\nindie-pop psychedelic rock\nindie-pop punk\nindie-pop punk electronic\nindie-pop punk rock\nindie-pop rap\nindie-pop rap-rock\nindie-pop reggae\nindie-pop reggae-fusion\nindie-pop reggae-ska\nindie-pop reggaeton\nindie-pop retro\nindie-pop retro funk\nindie-pop rock\nindie-pop rumba flamenco\nindie-pop shoegaze\nindie-pop shoegaze electronicore\nindie-pop ska-punk\nindie-pop ska-punk punk-rock\nindie-pop soul\nindie-pop surf-rock\nindie-pop swing\nindie-pop swing chanson\nindie-pop swing revival\nindie-pop synth-pop\nindie-pop synth-pop chiptune\nindie-pop synth-pop glitch-hop\nindie-pop synth-pop nu-disco\nindie-pop synth-rock\nindie-pop synthwave\nindie-pop tango\nindie-pop techno\nindie-pop trance\nindie-pop trap\nindie-pop trap-metal\nindie-pop trap-pop\nindie-pop trip-hop\nindie-pop tropical\nindie-pop tropical house\nindie-pop vaporwave\nindie-pop vintage jazz\nindie-pop world fusion\nindie-pop world music\nindie-pop world-music\nindie-pop world-pop\nindie-pop worldbeat\nindie-pop, 80s synth-pop\nindie-pop, Balkan, Klezmer\nindie-pop, Bollywood dance-pop\nindie-pop, Bollywood, funk\nindie-pop, EDM, dance-pop\nindie-pop, Eastern European folk\nindie-pop, European, soulful\nindie-pop, French chanson, jazz\nindie-pop, French trap\nindie-pop, German art-pop\nindie-pop, German folk\nindie-pop, German new wave\nindie-pop, German rap\nindie-pop, Indian folk\nindie-pop, J-rock\nindie-pop, J-rock, anime rock\nindie-pop, J-rock, hyperpop\nindie-pop, J-rock, lo-fi\nindie-pop, J-rock, math-rock\nindie-pop, J-rock, pop-punk\nindie-pop, J-rock, ska-punk\nindie-pop, Latin pop\nindie-pop, Latin pop, hip-hop\nindie-pop, Latin salsa\nindie-pop, Latin, Bollywood\nindie-pop, Latin, flamenco\nindie-pop, Latin, tropical\nindie-pop, Middle Eastern, cinematic\nindie-pop, Neue Deutsche Welle\nindie-pop, R&B, trap\nindie-pop, Russian estrada\nindie-pop, South Asian folk\nindie-pop, South Asian, atmospheric\nindie-pop, South Asian, folk\nindie-pop, South Indian\nindie-pop, Vocaloid\nindie-pop, alt-rock\nindie-pop, alt-rock, lo-fi hip hop\nindie-pop, alt-rock, nu-metal\nindie-pop, alt-rock, punk\nindie-pop, alternative R&B, trap-soul\nindie-pop, alternative rock\nindie-pop, alternative rock, ambient\nindie-pop, alternative rock, dream pop\nindie-pop, alternative rock, lo-fi hip hop\nindie-pop, alternative rock, pop-punk\nindie-pop, alternative rock, shoegaze\nindie-pop, bedroom pop, C-pop\nindie-pop, brostep\nindie-pop, chillwave, Indian influence\nindie-pop, chiptune, experimental\nindie-pop, chiptune, happy hardcore\nindie-pop, chiptune, rock\nindie-pop, cinematic rock\nindie-pop, cinematic, C-pop\nindie-pop, cinematic, R&B\nindie-pop, cinematic, ambient\nindie-pop, cinematic, experimental\nindie-pop, cloud rap\nindie-pop, dance-pop, moombahton\nindie-pop, dark electronic\nindie-pop, dream-pop, trap\nindie-pop, drum and bass\nindie-pop, dubstep, trap\nindie-pop, dubstep, trap-metal\nindie-pop, electro-rock, lo-fi\nindie-pop, electronic\nindie-pop, electronic rock, dream-pop\nindie-pop, electronic rock, hyperpop\nindie-pop, electronic, Bollywood\nindie-pop, electronic, bilingual\nindie-pop, electronic, lo-fi\nindie-pop, emo rock\nindie-pop, experimental, industrial hip-hop\nindie-pop, flamenco\nindie-pop, folk fusion\nindie-pop, folk-pop, Latin pop-rock\nindie-pop, funk, Bollywood\nindie-pop, funk, lo-fi hip hop\nindie-pop, future bass\nindie-pop, future bass, cinematic rock\nindie-pop, glitch-hop, future bass\nindie-pop, glitch-pop, hyperpop\nindie-pop, happy hardcore\nindie-pop, hard rock\nindie-pop, hip-hop, electronic\nindie-pop, hyperpop\nindie-pop, hyperpop, ambient\nindie-pop, hyperpop, breakcore\nindie-pop, hyperpop, electro-rock\nindie-pop, hyperpop, electronic rock\nindie-pop, hyperpop, emo-rap\nindie-pop, hyperpop, emo-trap\nindie-pop, hyperpop, experimental\nindie-pop, hyperpop, experimental hip-hop\nindie-pop, hyperpop, glitchcore\nindie-pop, hyperpop, lo-fi\nindie-pop, hyperpop, shoegaze\nindie-pop, indie rock\nindie-pop, industrial rock\nindie-pop, industrial rock, emo-rap\nindie-pop, industrial rock, lo-fi\nindie-pop, industrial rock, nu-metal\nindie-pop, industrial, ambient\nindie-pop, industrial, lo-fi\nindie-pop, lo-fi hip hop, electronic\nindie-pop, lo-fi hip hop, experimental\nindie-pop, lo-fi hip-hop, alternative R&B\nindie-pop, lo-fi hip-hop, pop-rock\nindie-pop, lo-fi, South Asian\nindie-pop, lo-fi, trap\nindie-pop, math rock, shoegaze\nindie-pop, neo-soul, glitch\nindie-pop, noise-rock\nindie-pop, nu-metal, atmospheric\nindie-pop, pop-punk\nindie-pop, pop-punk, C-pop\nindie-pop, pop-punk, alternative\nindie-pop, pop-punk, alternative rock\nindie-pop, pop-punk, chiptune\nindie-pop, pop-punk, dream pop\nindie-pop, pop-punk, easycore\nindie-pop, pop-punk, electronic rock\nindie-pop, pop-punk, future bass\nindie-pop, pop-punk, hip-hop\nindie-pop, pop-punk, hyperpop\nindie-pop, pop-punk, lo-fi\nindie-pop, pop-punk, metalcore\nindie-pop, pop-punk, pop-rock\nindie-pop, pop-punk, rap-rock\nindie-pop, pop-punk, rock\nindie-pop, pop-punk, ska\nindie-pop, pop-punk, spoken word\nindie-pop, pop-punk, trap\nindie-pop, pop-rock\nindie-pop, pop-rock, Chinese rock\nindie-pop, pop-rock, dream pop\nindie-pop, pop-rock, future bass\nindie-pop, pop-rock, hip-hop\nindie-pop, pop-rock, industrial\nindie-pop, pop-rock, post-rock\nindie-pop, pop-rock, reggae\nindie-pop, pop-rock, trap\nindie-pop, post-hardcore\nindie-pop, post-hardcore, emo-rap\nindie-pop, post-rock, ambient\nindie-pop, post-rock, pop-rock\nindie-pop, progressive house\nindie-pop, progressive house, big room\nindie-pop, progressive metal\nindie-pop, psychedelic rock\nindie-pop, psychedelic rock, experimental\nindie-pop, psychedelic rock, lo-fi\nindie-pop, psychedelic rock, shoegaze\nindie-pop, rap, Latin\nindie-pop, rap, glitch-hop\nindie-pop, rock, hyperpop\nindie-pop, rock, industrial-electronic\nindie-pop, rock, piano ballad\nindie-pop, schlager\nindie-pop, shoegaze, alternative rock\nindie-pop, shoegaze, chiptune\nindie-pop, shoegaze, post-rock\nindie-pop, surf-rock, cinematic\nindie-pop, synth-pop\nindie-pop, synth-pop, electronic rock\nindie-pop, synth-pop, lo-fi\nindie-pop, synth-pop, new wave\nindie-pop, theatrical rock\nindie-pop, theatrical rock, metalcore\nindie-pop, trap, R&B\nindie-pop, trap, emo-rap\nindie-pop, trap, hyperpop\nindie-pop, trap, psychedelic\nindie-pop, world fusion\nindie-pop, world music, cinematic\nindie-punk\nindie-rap\nindie-rock\nindie-rock J-rock\nindie-rock alt-rock\nindie-rock alternative rock\nindie-rock electro house\nindie-rock future bass\nindie-rock pop-punk\nindie-rock pop-punk electronic\nindie-rock pop-punk metalcore\nindie-rock pop-punk post-hardcore\nindie-rock post-hardcore\nindie-rock power-pop\nindie-rock reggae\nindie-rock, drum and bass\nindie-rock, hard rock, blues-rock\nindie-rock, industrial trap, lo-fi\nindie-rock, metalcore, electronic\nindie-rock, pop-punk, shoegaze\nindie-soul\nindonesian rock\nindustrial\nindustrial Americana\nindustrial Arabic\nindustrial C-pop\nindustrial D&B\nindustrial EBM\nindustrial EBM darkwave\nindustrial EBM punk\nindustrial EBM, hyperpop\nindustrial EDM\nindustrial K-pop\nindustrial Latin rock\nindustrial R&B\nindustrial alt-rock\nindustrial alternative\nindustrial alternative metal\nindustrial alternative rock\nindustrial ambient\nindustrial bass\nindustrial beat\nindustrial big beat\nindustrial blues\nindustrial blues-rock\nindustrial bollywood\nindustrial boom-bap\nindustrial breakbeat\nindustrial breakbeat chiptune\nindustrial breakbeat psytrance\nindustrial breakcore\nindustrial breakcore chiptune\nindustrial breakcore glitch\nindustrial breakcore metalcore\nindustrial brostep\nindustrial chiptune\nindustrial choral\nindustrial cinematic\nindustrial cumbia\nindustrial cyberpunk\nindustrial dance\nindustrial dance EBM\nindustrial dance, hard rock\nindustrial dance-pop\nindustrial dance-punk\nindustrial dance-rock\nindustrial dancehall\nindustrial darksynth\nindustrial darksynth cyberpunk\nindustrial darkwave\nindustrial darkwave trance\nindustrial desert rock\nindustrial devotional\nindustrial dream pop\nindustrial dream-pop\nindustrial drone\nindustrial drum\nindustrial drum & bass\nindustrial drum and bass\nindustrial drum loop\nindustrial drum machine\nindustrial drumming\nindustrial dub\nindustrial dubstep\nindustrial dubstep, neurofunk\nindustrial dubstep, rap, electronic\nindustrial electro\nindustrial electro house\nindustrial electro-pop\nindustrial electro-punk\nindustrial electro-rock\nindustrial electronic\nindustrial electronic pop\nindustrial electronic rock\nindustrial electronic trap\nindustrial electronic, Indian film music\nindustrial electronic, synthwave\nindustrial electronica\nindustrial experimental\nindustrial folk\nindustrial folk rock\nindustrial folk-metal\nindustrial folk-punk\nindustrial funk\nindustrial funk metal\nindustrial funk-rock\nindustrial fusion\nindustrial gabber\nindustrial glitch\nindustrial glitch hop\nindustrial glitch-hop\nindustrial gospel\nindustrial grime\nindustrial hard rock\nindustrial hardcore\nindustrial hardcore glitch-hop\nindustrial hardcore techno\nindustrial hardcore, speedcore\nindustrial hardstyle\nindustrial hardstyle breakcore\nindustrial hardstyle gabber\nindustrial hip hop\nindustrial hip hop, C-pop, cinematic rock\nindustrial hip-hop\nindustrial hip-hop alternative metal\nindustrial hip-hop alternative rock\nindustrial hip-hop alternative rock nu-metal\nindustrial hip-hop chiptune\nindustrial hip-hop darkwave\nindustrial hip-hop digital hardcore\nindustrial hip-hop electronic rock\nindustrial hip-hop emo-rap\nindustrial hip-hop glitch\nindustrial hip-hop glitch hop\nindustrial hip-hop hyperpop breakcore\nindustrial hip-hop hyperpop chiptune\nindustrial hip-hop hyperpop synthwave\nindustrial hip-hop metalcore\nindustrial hip-hop noise rock\nindustrial hip-hop nu-metal\nindustrial hip-hop nu-metal alternative rock\nindustrial hip-hop nu-metal electronic rock\nindustrial hip-hop punk\nindustrial hip-hop stadium rock\nindustrial hip-hop synth-pop\nindustrial hip-hop trap\nindustrial hip-hop trap metal\nindustrial hip-hop trap metal chiptune\nindustrial hip-hop, J-pop\nindustrial hip-hop, K-rock, dubstep\nindustrial hip-hop, alternative R&B, UK rap\nindustrial hip-hop, alternative rock\nindustrial hip-hop, anthemic rock\nindustrial hip-hop, art-pop, futuristic electronic\nindustrial hip-hop, big beat\nindustrial hip-hop, cinematic rock\nindustrial hip-hop, cyberpunk, electronic\nindustrial hip-hop, darkwave, EBM\nindustrial hip-hop, digital hardcore\nindustrial hip-hop, dubstep, breakcore\nindustrial hip-hop, electronic dance\nindustrial hip-hop, epic rock\nindustrial hip-hop, hardstyle, dubstep\nindustrial hip-hop, lo-fi hip-hop\nindustrial hip-hop, lo-fi hip-hop, nu-metal\nindustrial hip-hop, neurofunk, cinematic\nindustrial hip-hop, neurofunk, drum and bass\nindustrial hip-hop, psychedelic dream-pop\nindustrial hip-hop, rap-rock\nindustrial hip-hop, synth-pop\nindustrial hip-hop, synth-pop, cinematic\nindustrial house\nindustrial hyperpop\nindustrial jazz\nindustrial lo-fi\nindustrial metal\nindustrial metal EBM\nindustrial metal breakbeat\nindustrial metal breakcore\nindustrial metal breakcore cybergrind\nindustrial metal chiptune\nindustrial metal chiptune synthwave\nindustrial metal cybergrind\nindustrial metal digital hardcore\nindustrial metal djent\nindustrial metal djent cybergrind\nindustrial metal drum and bass\nindustrial metal electronic rock\nindustrial metal electronicore\nindustrial metal folk metal\nindustrial metal funk metal\nindustrial metal hardstyle\nindustrial metal mathcore cybergrind\nindustrial metal melodic death metal\nindustrial metal nu-metal\nindustrial metal phonk\nindustrial metal power metal\nindustrial metal punk\nindustrial metal rap-metal\nindustrial metal rap-rock\nindustrial metal rapcore\nindustrial metal rave\nindustrial metal speedcore\nindustrial metal symphonic rock\nindustrial metal synth-pop\nindustrial metal synth-rock\nindustrial metal synthwave\nindustrial metal synthwave chiptune\nindustrial metal trance\nindustrial metal trancecore\nindustrial metal trap\nindustrial metal trap chiptune\nindustrial metal trap metal\nindustrial metal, EBM\nindustrial metal, EBM, cinematic\nindustrial metal, EBM, electronic\nindustrial metal, Indian folk\nindustrial metal, J-rock\nindustrial metal, J-rock, chiptune\nindustrial metal, J-rock, nu-metal\nindustrial metal, Latin merengue\nindustrial metal, Neue Deutsche Härte\nindustrial metal, South Indian film music\nindustrial metal, Tamil pop\nindustrial metal, Tamil rap\nindustrial metal, Tamil rock\nindustrial metal, Tamil rock, electronic\nindustrial metal, ambient, folk\nindustrial metal, big beat\nindustrial metal, big beat, nu-metal\nindustrial metal, breakbeat\nindustrial metal, chiptune, electro house\nindustrial metal, chiptune, electronic rock\nindustrial metal, chiptune, electronicore\nindustrial metal, chiptune, hardcore techno\nindustrial metal, cinematic electronic\nindustrial metal, cybergrind\nindustrial metal, cybergrind, chiptune\nindustrial metal, cybergrind, electronicore\nindustrial metal, cybergrind, experimental electronic\nindustrial metal, cyberpunk electronica\nindustrial metal, cyberpunk rock\nindustrial metal, dark synthwave\nindustrial metal, deathstep, brostep\nindustrial metal, digital hardcore\nindustrial metal, digital hardcore, chiptune\nindustrial metal, drum and bass\nindustrial metal, drum and bass, neurofunk\nindustrial metal, dubstep\nindustrial metal, electronic breakbeat\nindustrial metal, electronic dance music\nindustrial metal, electronic dance, Tamil rap\nindustrial metal, electronic rock\nindustrial metal, electronic rock, trance\nindustrial metal, electronica\nindustrial metal, electronicore\nindustrial metal, electronicore, chiptune\nindustrial metal, epic electronic\nindustrial metal, eurodance\nindustrial metal, happy hardcore\nindustrial metal, hard techno\nindustrial metal, hard trance\nindustrial metal, hard trance, cyberpunk\nindustrial metal, hardcore electronic\nindustrial metal, hardcore techno\nindustrial metal, hardstyle\nindustrial metal, hardstyle, acid techno\nindustrial metal, hardstyle, big room\nindustrial metal, hardstyle, electronic\nindustrial metal, hardstyle, electronic rock\nindustrial metal, hardstyle, electronicore\nindustrial metal, hardstyle, gabber\nindustrial metal, hardstyle, techno\nindustrial metal, hardstyle, trance\nindustrial metal, hardstyle, trancecore\nindustrial metal, hardstyle, video game music\nindustrial metal, hyperpop\nindustrial metal, hyperpop, electronicore\nindustrial metal, hyperpop, emo\nindustrial metal, kuthu\nindustrial metal, melodic metalcore\nindustrial metal, metalcore\nindustrial metal, neurofunk\nindustrial metal, neurofunk drum and bass\nindustrial metal, neurofunk, drum and bass\nindustrial metal, nu-metal, deathcore\nindustrial metal, polka-schlager\nindustrial metal, rap-metal, South Indian\nindustrial metal, rap-rock\nindustrial metal, rap-rock, nu-metal\nindustrial metal, symphonic power metal\nindustrial metal, symphonic rap-metal\nindustrial metal, symphonic rock\nindustrial metal, symphonic thrash\nindustrial metal, synth-rock\nindustrial metal, synth-rock, chiptune\nindustrial metal, synthwave\nindustrial metal, synthwave, cinematic\nindustrial metal, trance\nindustrial metal, trancecore\nindustrial metal, trap metal\nindustrial metal, trap metal, Bengali rock\nindustrial metal, trap, electronic\nindustrial metal, tribal, hardstyle\nindustrial metal, video game music\nindustrial metalcore\nindustrial metalcore chiptune\nindustrial metalcore chiptune synthwave\nindustrial metalcore cybergrind\nindustrial metalcore cyberpunk rock\nindustrial metalcore electronicore\nindustrial metalcore glitch-hop\nindustrial metalcore hardstyle\nindustrial metalcore hyperpop\nindustrial metalcore synthwave\nindustrial metalcore, J-rock\nindustrial metalcore, cybergrind\nindustrial metalcore, nu-disco, funk-rock\nindustrial metalcore, rap-metal\nindustrial metalcore, synthwave\nindustrial neo-soul\nindustrial noise\nindustrial noise-rock\nindustrial nu-metal\nindustrial nu-metal trap metal\nindustrial pop\nindustrial pop EBM\nindustrial pop rock\nindustrial pop-rock\nindustrial post-punk\nindustrial post-rock\nindustrial psytrance\nindustrial punk\nindustrial rap\nindustrial rap-rock\nindustrial reggae\nindustrial reggaeton\nindustrial rock\nindustrial rock alternative metal\nindustrial rock ambient\nindustrial rock big beat\nindustrial rock breakcore\nindustrial rock chiptune\nindustrial rock chiptune progressive metal\nindustrial rock chiptune synth-pop\nindustrial rock chiptune trap\nindustrial rock cyberpunk\nindustrial rock dance-pop\nindustrial rock dance-punk\nindustrial rock dark pop\nindustrial rock darkwave\nindustrial rock digital hardcore\nindustrial rock dubstep\nindustrial rock electroclash\nindustrial rock electronicore\nindustrial rock emo-rap\nindustrial rock experimental hip-hop\nindustrial rock experimental pop\nindustrial rock funk\nindustrial rock funk breakbeat\nindustrial rock funk metal\nindustrial rock funk metal progressive\nindustrial rock gothic rock\nindustrial rock hip-hop\nindustrial rock hip-hop K-pop\nindustrial rock hyperpop\nindustrial rock hyperpop nu-metal\nindustrial rock hyperpop rap\nindustrial rock metalcore\nindustrial rock nu-metal\nindustrial rock nu-metal breakbeat\nindustrial rock nu-metal electronic\nindustrial rock nu-metal metalcore\nindustrial rock nu-metal rap-rock\nindustrial rock nu-metal spiritual\nindustrial rock post-punk\nindustrial rock psychedelic rock\nindustrial rock rap-metal\nindustrial rock rap-rock\nindustrial rock symphonic metal\nindustrial rock synth-pop\nindustrial rock synth-punk\nindustrial rock synth-rock\nindustrial rock synthwave\nindustrial rock techno\nindustrial rock trap\nindustrial rock trap metal\nindustrial rock trip-hop\nindustrial rock, Anatolian rock\nindustrial rock, Arabic fusion\nindustrial rock, Balkan electronic\nindustrial rock, Bollywood dance\nindustrial rock, Bollywood dance-pop\nindustrial rock, Bollywood, cinematic\nindustrial rock, C-pop, cinematic\nindustrial rock, C-pop, experimental\nindustrial rock, EBM\nindustrial rock, EBM, Neue Deutsche Härte\nindustrial rock, EBM, cyberpunk\nindustrial rock, EBM, darkwave\nindustrial rock, EBM, synth-pop\nindustrial rock, EBM, synth-punk\nindustrial rock, German rap\nindustrial rock, German rap, vaporwave\nindustrial rock, Indian film music\nindustrial rock, Indian folk\nindustrial rock, J-rock\nindustrial rock, J-rock, chiptune\nindustrial rock, J-rock, synth-pop\nindustrial rock, K-pop\nindustrial rock, K-pop, rap\nindustrial rock, Latin funk\nindustrial rock, Middle Eastern electronic\nindustrial rock, Middle Eastern fusion\nindustrial rock, Neue Deutsche Härte\nindustrial rock, Neue Deutsche Härte, hip-hop\nindustrial rock, R&B\nindustrial rock, South Indian folk\nindustrial rock, South Indian hip-hop\nindustrial rock, Turkish electronic\nindustrial rock, UK hip-hop, nu-metal\nindustrial rock, alternative R&B, neo-soul\nindustrial rock, big beat\nindustrial rock, breakbeat\nindustrial rock, breakbeat, glitch\nindustrial rock, brostep, metalcore\nindustrial rock, chiptune, electronic\nindustrial rock, chiptune, funk\nindustrial rock, cinematic electronica\nindustrial rock, cinematic synth-pop\nindustrial rock, cinematic trailer\nindustrial rock, cinematic, ballad\nindustrial rock, cinematic, nu-metal\nindustrial rock, cinematic, protest anthem\nindustrial rock, cyberpunk electronica\nindustrial rock, cyberpunk, J-rock\nindustrial rock, dance-pop, Latin\nindustrial rock, digital hardcore\nindustrial rock, drum and bass, cinematic\nindustrial rock, drum and bass, rapcore\nindustrial rock, electronic dance music\nindustrial rock, electronic dance, dubstep\nindustrial rock, electronic punk\nindustrial rock, electronic, K-hip hop\nindustrial rock, electronic, Middle Eastern fusion\nindustrial rock, electronic, nu-metal\nindustrial rock, electronic, trap\nindustrial rock, hardstyle\nindustrial rock, hip-hop, cinematic electronic\nindustrial rock, hip-hop, post-hardcore\nindustrial rock, hyperpop\nindustrial rock, hyperpop, electronic\nindustrial rock, hyperpop, trap metal\nindustrial rock, lo-fi orchestral, Bollywood\nindustrial rock, metalcore, ambient\nindustrial rock, metalcore, nu-metal\nindustrial rock, metalcore, progressive metal\nindustrial rock, nu-disco, synth-pop\nindustrial rock, nu-metal, Indian classical\nindustrial rock, nu-metal, ambient\nindustrial rock, nu-metal, electronic\nindustrial rock, nu-metal, reggae\nindustrial rock, rap-metal\nindustrial rock, rap-metal, future bass\nindustrial rock, rap-rock\nindustrial rock, synth-pop\nindustrial rock, synth-pop, J-rock\nindustrial rock, synth-pop, cinematic\nindustrial rock, synth-punk\nindustrial rock, synth-punk, chiptune\nindustrial rock, trap metal\nindustrial rock, trip-hop\nindustrial rock, world music\nindustrial shoegaze\nindustrial soul\nindustrial spoken word\nindustrial symphonic\nindustrial symphonic metal\nindustrial symphonic rock\nindustrial synth\nindustrial synth-pop\nindustrial synth-punk\nindustrial synth-rock\nindustrial synthpop\nindustrial synthwave\nindustrial techno\nindustrial techno EBM\nindustrial techno chiptune\nindustrial techno darkwave\nindustrial techno, Balkan folk\nindustrial techno, art-pop\nindustrial techno, hardstyle\nindustrial techno, hardstyle, ambient\nindustrial trance\nindustrial trap\nindustrial trap hyperpop\nindustrial trap hyperpop metalcore\nindustrial trap metal\nindustrial trap metal hyperpop\nindustrial trap nu-metal\nindustrial trap, anthemic pop\nindustrial trap, cinematic pop, dark electronic\nindustrial trap, hyperpop, digital hardcore\nindustrial trap, melodic pop, atmospheric R&B\nindustrial trap, metalcore, acoustic folk\nindustrial trap, theatrical rock\nindustrial tribal\nindustrial trip-hop\nindustrial world\nindustrial world fusion\nindustrial, EBM, cinematic\nindustrial, EBM, dark electro-pop\nindustrial, EBM, dark electronic\nindustrial, EBM, darkwave\nindustrial, EBM, digital hardcore\nindustrial, EBM, protest\nindustrial, Middle Eastern, flamenco\nindustrial, cinematic, electronic\nindustrial, darksynth\nindustrial, devotional, electronic\nindustrial, electronic, K-pop\nindustrial, hyperpop, Russian chanted\nindustrial, neurofunk, glitch\nindustrial, tribal, experimental\nindustrial, trip-hop, dark pop\nindustrial-electronic\nindustrial-pop\ninspirational\ninspirational Afro-pop\ninspirational Brazilian trap\ninspirational C-pop\ninspirational Christian\ninspirational Christmas\ninspirational Christmas ballad\ninspirational R&B\ninspirational a cappella\ninspirational acapella\ninspirational acoustic\ninspirational adult contemporary\ninspirational ambient\ninspirational anthem\ninspirational ballad\ninspirational choir\ninspirational choral\ninspirational classical\ninspirational corporate\ninspirational electronic\ninspirational electronic pop\ninspirational folk\ninspirational folk rock\ninspirational folk-pop\ninspirational gospel\ninspirational hip-hop\ninspirational house\ninspirational hymn\ninspirational instrumental\ninspirational jazz\ninspirational lo-fi\ninspirational music\ninspirational music world music\ninspirational new age\ninspirational orchestral\ninspirational piano\ninspirational piano ballad\ninspirational pop\ninspirational pop R&B\ninspirational pop ballad\ninspirational pop ballad, reggaeton-pop\ninspirational pop gospel\ninspirational pop reggaeton\ninspirational pop world music\ninspirational pop worship\ninspirational pop, world music\ninspirational pop-ballad\ninspirational pop-chanson\ninspirational pop-gospel\ninspirational pop-rap\ninspirational pop-rock\ninspirational power ballad\ninspirational reggaeton\ninspirational rock\ninspirational soul\ninspirational soundtrack\ninspirational spoken word\ninspirational synth\ninspirational trap\ninspirational world music\ninspirational worship\ninstructional folk\ninstructional groove\ninstrumental\ninstrumental acoustic\ninstrumental ambient\ninstrumental ballad\ninstrumental bass\ninstrumental blues\ninstrumental breakbeat\ninstrumental country rock\ninstrumental cumbia\ninstrumental drum\ninstrumental drum loop\ninstrumental dub\ninstrumental electronic\ninstrumental fantasy\ninstrumental fingerstyle\ninstrumental flamenco\ninstrumental flute\ninstrumental folk\ninstrumental folk rock\ninstrumental funk\ninstrumental funk acid jazz\ninstrumental funk big beat\ninstrumental funk chiptune\ninstrumental funk fusion\ninstrumental funk jazz-fusion\ninstrumental funk lo-fi hip-hop\ninstrumental funk neo-soul\ninstrumental funk retro indie pop\ninstrumental funk rock\ninstrumental funk-rock\ninstrumental fusion\ninstrumental groove\ninstrumental guitar\ninstrumental hip hop\ninstrumental hip-hop\ninstrumental hip-hop chillwave\ninstrumental hip-hop chiptune\ninstrumental hip-hop downtempo\ninstrumental hip-hop electronic funk\ninstrumental hip-hop funk\ninstrumental hip-hop funk lounge\ninstrumental hip-hop vaporwave chillwave\ninstrumental jazz\ninstrumental jingle\ninstrumental lo-fi\ninstrumental lounge\ninstrumental mandolin\ninstrumental math rock\ninstrumental melancholic\ninstrumental melancholy\ninstrumental metal\ninstrumental oud\ninstrumental percussion\ninstrumental piano\ninstrumental pop\ninstrumental pop chillwave\ninstrumental pop-rock\ninstrumental post-rock\ninstrumental power ballad\ninstrumental progressive\ninstrumental rock\ninstrumental rock blues rock\ninstrumental rock funk\ninstrumental rock world music\ninstrumental shred metal\ninstrumental soul\ninstrumental suite\ninstrumental suspense\ninstrumental techno\ninstrumental trap\ninstrumental trap lo-fi hip-hop\ninstrumental trap phonk\ninstrumental ukulele\ninstrumental waltz\ninstrumental whimsy\ninstrumental, Asian fusion\ninstrumental, Asian fusion, traditional electric\ninstrumental, Balkan folk, cinematic\ninstrumental, East Asian, ambient\ninstrumental, European, cinematic\ninstrumental, Latin fusion, classical crossover\ninstrumental, Latin groove, ambient\ninstrumental, Latin groove, ambient piano\ninstrumental, Latin groove, cinematic\ninstrumental, Latin jazz, acoustic\ninstrumental, Latin jazz, piano virtuoso\ninstrumental, Latin jazz, vibraphone\ninstrumental, Latin percussion\ninstrumental, Latin pop, cheerful\ninstrumental, Latin pop, lo-fi\ninstrumental, Latin, ambient\ninstrumental, Latin, cinematic\ninstrumental, Latin, quirky\ninstrumental, Latin, trap\ninstrumental, Middle Eastern, electronic\ninstrumental, Middle Eastern, indie-folk rock\ninstrumental, South Asian fusion, experimental\ninstrumental, acoustic, Latin\ninstrumental, acoustic, ambient\ninstrumental, acoustic, cello\ninstrumental, acoustic, cinematic\ninstrumental, acoustic, fantasy\ninstrumental, acoustic, melancholic\ninstrumental, acoustic, playful\ninstrumental, acoustic, uplifting\ninstrumental, acoustic, whimsical\ninstrumental, ambient pop, Mediterranean\ninstrumental, ambient pop, cinematic\ninstrumental, ambient rock\ninstrumental, ambient rock, cinematic\ninstrumental, ambient rock, flute\ninstrumental, ambient, East Asian\ninstrumental, ambient, JRPG\ninstrumental, ambient, Latin fusion\ninstrumental, ambient, Latin guitar\ninstrumental, ambient, Spanish-influenced\ninstrumental, ambient, acoustic\ninstrumental, ambient, anime\ninstrumental, ambient, chill\ninstrumental, ambient, cinematic\ninstrumental, ambient, classical\ninstrumental, ambient, classical fusion\ninstrumental, ambient, classical guitar\ninstrumental, ambient, fantasy\ninstrumental, ambient, flamenco\ninstrumental, ambient, hopeful\ninstrumental, ambient, inspirational\ninstrumental, ambient, lo-fi\ninstrumental, ambient, melodic\ninstrumental, ambient, music box\ninstrumental, ambient, neo-classical\ninstrumental, ambient, piano\ninstrumental, ambient, playful\ninstrumental, ambient, quirky\ninstrumental, ambient, uplifting\ninstrumental, ambient, world\ninstrumental, ambient, world fusion\ninstrumental, ambient, world music\ninstrumental, ambient, world percussion\ninstrumental, baroque pop\ninstrumental, baroque, Latin\ninstrumental, baroque, ambient\ninstrumental, baroque, synth\ninstrumental, beachy, jazzy\ninstrumental, big band, ambient\ninstrumental, boogie-woogie, piano rock\ninstrumental, boogie-woogie, piano-driven\ninstrumental, boogie-woogie, ragtime\ninstrumental, bossa nova, ambient\ninstrumental, bossa nova, cinematic\ninstrumental, bossa nova, playful\ninstrumental, brass, classic TV theme\ninstrumental, brass, dance\ninstrumental, breakbeat, electronic\ninstrumental, bright, hopeful\ninstrumental, bright, playful\ninstrumental, cafe music, playful\ninstrumental, cartoon, spy\ninstrumental, cartoon, whimsical\ninstrumental, chamber, ambient\ninstrumental, cheerful, children's\ninstrumental, cheerful, music box\ninstrumental, cheerful, whimsical\ninstrumental, cheerful, whimsy\ninstrumental, chiptune, orchestral\ninstrumental, chiptune, post-rock\ninstrumental, chiptune, virtuosic piano\ninstrumental, cinematic, Chinese fusion\ninstrumental, cinematic, European street fair\ninstrumental, cinematic, J-RPG\ninstrumental, cinematic, J-rock\ninstrumental, cinematic, RPG\ninstrumental, cinematic, acoustic\ninstrumental, cinematic, ambient\ninstrumental, cinematic, baroque\ninstrumental, cinematic, classical\ninstrumental, cinematic, classical guitar\ninstrumental, cinematic, electronic\ninstrumental, cinematic, emotional\ninstrumental, cinematic, fairytale\ninstrumental, cinematic, fingerstyle\ninstrumental, cinematic, lo-fi\ninstrumental, cinematic, lullaby\ninstrumental, cinematic, neoclassical\ninstrumental, cinematic, piano\ninstrumental, cinematic, playful\ninstrumental, cinematic, polyrhythmic\ninstrumental, cinematic, quirky\ninstrumental, cinematic, spy score\ninstrumental, cinematic, video game\ninstrumental, cinematic, waltz\ninstrumental, cinematic, whimsical\ninstrumental, cinematic, world fusion\ninstrumental, circus, cartoon\ninstrumental, circus, cumbia\ninstrumental, classical fusion\ninstrumental, classical fusion, ragtime\ninstrumental, classical fusion, virtuosic\ninstrumental, classical guitar, ambient\ninstrumental, classical guitar, cinematic\ninstrumental, classical guitar, piano\ninstrumental, classical, Ghibli-style\ninstrumental, classical, Middle Eastern\ninstrumental, classical, acoustic\ninstrumental, classical, ambient\ninstrumental, classical, cinematic\ninstrumental, classical, emotional\ninstrumental, classical, lo-fi\ninstrumental, classical, melancholic\ninstrumental, classical, ragtime\ninstrumental, classical, soft rock\ninstrumental, classical, video game\ninstrumental, classical, whimsical\ninstrumental, easy-listening, uplifting\ninstrumental, electronic, Middle Eastern\ninstrumental, electronic, aggressive\ninstrumental, electronic, ambient\ninstrumental, electronic, breakbeat\ninstrumental, electronic, breakcore\ninstrumental, electronic, cinematic\ninstrumental, electronic, classical fusion\ninstrumental, electronic, world fusion\ninstrumental, emotional, ambient\ninstrumental, emotional, world music\ninstrumental, energetic, classical\ninstrumental, fairytale\ninstrumental, fairytale, cinematic\ninstrumental, fairytale, lo-fi\ninstrumental, fairytale, orchestral\ninstrumental, fantasy, RPG\ninstrumental, fantasy, ambient\ninstrumental, fantasy, harp\ninstrumental, fantasy, lo-fi\ninstrumental, fantasy, music box\ninstrumental, festive, marching band\ninstrumental, fingerpicked, ambient\ninstrumental, fingerstyle guitar, cinematic\ninstrumental, fingerstyle, Latin\ninstrumental, fingerstyle, ambient\ninstrumental, fingerstyle, cinematic\ninstrumental, fingerstyle, classical\ninstrumental, fingerstyle, classical guitar\ninstrumental, fingerstyle, melancholic\ninstrumental, fingerstyle, world fusion\ninstrumental, flamenco, ambient\ninstrumental, flamenco, latin\ninstrumental, flamenco, neoclassical\ninstrumental, flamenco, whimsical\ninstrumental, flamenco, world fusion\ninstrumental, folk rock\ninstrumental, folk rock, cinematic\ninstrumental, folk rock, electronic\ninstrumental, folk, cello\ninstrumental, folkloric, cinematic\ninstrumental, funk, ambient\ninstrumental, funk, cinematic\ninstrumental, glockenspiel, flamenco\ninstrumental, gospel, ambient\ninstrumental, gospel, cinematic\ninstrumental, groove, ambient\ninstrumental, guzheng, cinematic\ninstrumental, guzheng, world fusion\ninstrumental, harp, Latin\ninstrumental, harp, cello\ninstrumental, harp, fairytale\ninstrumental, hypnotic, energetic\ninstrumental, jazz fusion, cinematic\ninstrumental, jazz, acoustic\ninstrumental, jazz, cinematic\ninstrumental, jazz, fantasy\ninstrumental, jazz, romantic\ninstrumental, jazz, video game\ninstrumental, jazzy, guzheng\ninstrumental, kalimba, ambient\ninstrumental, klezmer, drum and bass\ninstrumental, klezmer, folk rock\ninstrumental, klezmer, virtuosic\ninstrumental, latin, ambient\ninstrumental, latin, hypnotic\ninstrumental, light classical, soundtrack\ninstrumental, light jazz, whimsical\ninstrumental, light piano, whimsical\ninstrumental, light pop, classical\ninstrumental, lo-fi, ambient\ninstrumental, lo-fi, cinematic\ninstrumental, lo-fi, energetic\ninstrumental, lo-fi, music box\ninstrumental, lo-fi, noir\ninstrumental, lo-fi, whimsical\ninstrumental, lounge-jazz, ambient\ninstrumental, mallet percussion, ambient\ninstrumental, mallet, playful\ninstrumental, marimba, ambient\ninstrumental, marimba, playful\ninstrumental, marimba, polyrhythmic\ninstrumental, marimba, whimsical\ninstrumental, melancholic, acoustic\ninstrumental, melancholic, ambient\ninstrumental, melancholic, cinematic\ninstrumental, melancholic, classical\ninstrumental, melancholic, flute\ninstrumental, melancholic, harp\ninstrumental, melancholic, piano\ninstrumental, melancholic, waltz\ninstrumental, modern classical, Latin guitar\ninstrumental, music box, cinematic\ninstrumental, music box, lullaby\ninstrumental, music box, playful\ninstrumental, music box, ragtime\ninstrumental, music box, whimsical\ninstrumental, nostalgic, vintage\ninstrumental, nylon-string guitar, ambient\ninstrumental, orchestral, minimalist\ninstrumental, orchestral, whimsical\ninstrumental, oud, cinematic\ninstrumental, pastoral, melancholic\ninstrumental, percussion, cinematic\ninstrumental, percussive, experimental\ninstrumental, piano, acoustic guitar\ninstrumental, piano, cinematic\ninstrumental, piano, flute\ninstrumental, piano, harmonica\ninstrumental, piano, light jazz\ninstrumental, piano, melancholic\ninstrumental, pizzicato, cinematic\ninstrumental, playful, Latin-influenced\ninstrumental, playful, acoustic\ninstrumental, playful, ambient\ninstrumental, playful, bright\ninstrumental, playful, cartoon\ninstrumental, playful, children's\ninstrumental, playful, children's music\ninstrumental, playful, children's theme\ninstrumental, playful, cinematic\ninstrumental, playful, classical fusion\ninstrumental, playful, jazzy\ninstrumental, playful, klezmer-inspired\ninstrumental, playful, light\ninstrumental, playful, marimba\ninstrumental, playful, melodic\ninstrumental, playful, minimalist\ninstrumental, playful, music box\ninstrumental, playful, mysterious\ninstrumental, playful, puzzle game\ninstrumental, playful, spy theme\ninstrumental, playful, upbeat\ninstrumental, playful, whimsical\ninstrumental, playful, world fusion\ninstrumental, polyrhythmic, Latin-inspired\ninstrumental, polyrhythmic, ambient\ninstrumental, polyrhythmic, ambient techno\ninstrumental, polyrhythmic, electronic\ninstrumental, polyrhythmic, marimba\ninstrumental, polyrhythmic, minimal\ninstrumental, polyrhythmic, playful\ninstrumental, polyrhythmic, tropical\ninstrumental, polyrhythmic, world beat\ninstrumental, polyrhythmic, world fusion\ninstrumental, progressive, cinematic\ninstrumental, qanun, ambient\ninstrumental, quirky, Latin jazz\ninstrumental, quirky, blues\ninstrumental, quirky, boogie-woogie\ninstrumental, quirky, cartoon\ninstrumental, quirky, cinematic\ninstrumental, quirky, marching\ninstrumental, quirky, piano\ninstrumental, quirky, playful\ninstrumental, quirky, ragtime\ninstrumental, quirky, spy theme\ninstrumental, quirky, suspense\ninstrumental, ragtime, big band\ninstrumental, ragtime, boogie-woogie\ninstrumental, ragtime, cinematic\ninstrumental, ragtime, classical\ninstrumental, ragtime, fantasy\ninstrumental, ragtime, jazz fusion\ninstrumental, ragtime, klezmer\ninstrumental, ragtime, music box\ninstrumental, ragtime, piano\ninstrumental, ragtime, playful\ninstrumental, ragtime, quirky\ninstrumental, ragtime, spy theme\ninstrumental, ragtime, video game music\ninstrumental, ragtime, whimsical\ninstrumental, retro, cinematic\ninstrumental, ritualistic, deep house\ninstrumental, spy theme, polyrhythmic\ninstrumental, string ensemble, folk-inspired\ninstrumental, synthwave, cinematic\ninstrumental, tango, classical guitar\ninstrumental, tribal, cinematic\ninstrumental, tribal, world fusion\ninstrumental, ukulele, cheerful\ninstrumental, upbeat, playful\ninstrumental, upbeat, world beat\ninstrumental, uplifting, acoustic\ninstrumental, uplifting, piano\ninstrumental, uplifting, world fusion\ninstrumental, vibraphone, ambient\ninstrumental, vibraphone, energetic\ninstrumental, vibraphone, playful\ninstrumental, vibraphone, upbeat\ninstrumental, vibraphone, video game score\ninstrumental, virtuosic, Eastern European folk\ninstrumental, virtuosic, Middle Eastern fusion\ninstrumental, virtuosic, percussive\ninstrumental, virtuosic, whimsical\ninstrumental, waltz, ambient\ninstrumental, waltz, melancholic\ninstrumental, waltz, music box\ninstrumental, whimsical, European cafe\ninstrumental, whimsical, RPG\ninstrumental, whimsical, acoustic\ninstrumental, whimsical, ambient\ninstrumental, whimsical, baroque pop\ninstrumental, whimsical, children's music\ninstrumental, whimsical, children's theme\ninstrumental, whimsical, cinematic\ninstrumental, whimsical, classical\ninstrumental, whimsical, digital piano\ninstrumental, whimsical, fairytale\ninstrumental, whimsical, fantasy\ninstrumental, whimsical, jazz\ninstrumental, whimsical, lo-fi\ninstrumental, whimsical, melodic\ninstrumental, whimsical, music box\ninstrumental, whimsical, nostalgic\ninstrumental, whimsical, piano\ninstrumental, whimsical, ragtime\ninstrumental, whimsical, staccato\ninstrumental, whimsical, vintage\ninstrumental, whimsical, waltz\ninstrumental, whimsical, woodwind\ninstrumental, woodwind, RPG\ninstrumental, world beat, electronic\ninstrumental, world beat, polyrhythmic\ninstrumental, world fusion\ninstrumental, world fusion, acoustic\ninstrumental, world fusion, ambient\ninstrumental, world fusion, cinematic\ninstrumental, world fusion, classical\ninstrumental, world fusion, upbeat\ninstrumental, world music, lo-fi\ninstrumental, world music, video game\nintellectual hip hop\nintellectual hip-hop\nintelligent dance music\nintelligent drum & bass\nintelligent drum and bass\nintelligent electronic\nintelligent techno\nintense\nintense R&B\nintense electronic\nintimate folk\nintimate pop\nintimate pop ballad\nintimate pop-rock\nintrospective hip-hop\nintrospective pop\nisicathamiya\nisicathamiya kolo\nisicathamiya soukous\niskelmä\nisland acoustic\nisland country\nisland folk\nisland funk\nisland gospel\nisland hip-hop\nisland music\nisland pop\nisland pop 80s synth-pop\nisland pop R&B\nisland pop afrobeats dancehall\nisland pop bossa nova\nisland pop calypso\nisland pop dancehall\nisland pop dancehall afrobeats\nisland pop hip-hop\nisland pop reggae\nisland pop reggae Latin\nisland pop reggae afrobeat\nisland pop reggae dancehall\nisland pop reggae fusion\nisland pop reggae hawaiian\nisland pop reggae world music\nisland pop reggae-dancehall\nisland pop reggaeton\nisland pop worldbeat\nisland pop, soca, gospel\nisland pop, synth-pop\nisland pop, ukulele pop, pop-rap\nisland pop, worldbeat\nisland pop-rock\nisland reggae\nisland reggae dancehall\nisland reggae pop\nisland rock\nisland rock reggae\nisland soul\nisland style\nisland-folk\nisland-pop\nisland-pop reggae\nisland-pop reggae dancehall\nisland-pop reggaeton\nisland-reggae chiptune\nj-core\nj-core breakcore\nj-core breakcore chiptune\nj-core chiptune\nj-core speedcore\nj-core speedcore chiptune\nj-core, breakcore, chiptune\nj-pop\nj-pop breakbeat\nj-pop speedcore chiptune\nj-rock jazz fusion\njam band\njam session\njangle pop\njangle pop alt-country\njangle pop dream pop\njangle pop folk-rock\njangle pop heartland rock\njangle pop indie rock\njangle pop indie rock shoegaze\njangle pop rock\njangle pop rock en español\njangle pop rockabilly country-rock\njangle pop rockabilly gospel\njangle pop shoegaze\njangle pop surf rock\njangle pop, alternative rock\njangle pop, alternative rock, 80s-inspired\njangle pop, heartland rock\njangle pop, indie rock, 80s-inspired\njangle pop, psychedelic folk\njangle-pop\njangle-pop 80s indie rock\njangle-pop 80s new wave\njangle-pop alt-country\njangle-pop college rock\njangle-pop indie rock\njangle-pop post-punk\njangle-pop power-pop\njangle-pop roots-rock\njangle-pop shoegaze\njangle-pop, 80s new wave\njapanese arcade\njapanese ballad\njapanese big band swing\njapanese children's\njapanese children's music\njapanese children's ska\njapanese children's swing\njapanese children's, big band swing\njapanese children's, big band, disco\njapanese children's, big-band jazz\njapanese children's, chiptune, upbeat\njapanese children's, funk, disco\njapanese comedy rap\njapanese dance\njapanese electronic\njapanese festival metal\njapanese festival rock\njapanese fusion\njapanese fusion jazz\njapanese hip hop\njapanese hip-hop\njapanese hip-hop chiptune\njapanese jingle\njapanese jingle punk rock\njapanese pop\njapanese rhythm game\njapanese rock\njapanese rock jazz fusion\njapanese rpg\njapanese show tune\njapanese video game\njapanese video game funk\njapanese video game music\njapanese video game music city pop jazz fusion\njapanese video game music funk\njapanese video game music funk breakbeat\njapanese video game music funk fusion\njapanese video game music funk jazz fusion\njapanese video game music funk jazz-rock\njapanese video game music funk rock jazz fusion\njapanese video game music happy hardcore\njapanese video game music jazz fusion progressive rock\njapanese video game music progressive rock jazz fusion\njapanese video game music uk garage\njapanese video game music, big band jazz fusion\njapanese video game music, big band jazz fusion, funk-rock\njapanese video game music, eurobeat, synthwave\njapanese video game music, happy hardcore\njapanese video game music, jazz fusion, drum and bass\njapanese video game music, jazz fusion, electronic breakbeat\njapanese video game music, jazz fusion, funk\njapanese video game music, jazz fusion, progressive house\njapanese video game music, jazz fusion, synth-pop\njapanese video game music, progressive rock, jazz fusion\njapanese video game music, uk garage, instrumental\njapanese video game soundtrack\njaripeo\njazz\njazz C-pop\njazz C-pop lo-fi hip-hop\njazz C-pop lounge\njazz Christmas\njazz J-pop\njazz Mandopop\njazz R&B\njazz R&B Christmas\njazz R&B, industrial hip-hop\njazz a cappella\njazz acoustic\njazz afrobeats\njazz ambient\njazz anime\njazz arabic ballad\njazz art song\njazz art-pop\njazz ballad\njazz ballad MPB\njazz ballad Mandopop\njazz ballad bolero\njazz ballad bossa nova\njazz ballad cabaret tango\njazz ballad chanson\njazz ballad fado\njazz ballad lounge\njazz ballad pop-rock\njazz ballad rockabilly\njazz ballad swing\njazz ballad world music\njazz ballad, Anatolian, melancholic\njazz ballad, Brazilian pop-rock\njazz ballad, C-pop, cinematic\njazz ballad, Chinese classical, lounge\njazz ballad, Dixieland\njazz ballad, Eastern European folk, Turkish folk\njazz ballad, European cabaret, klezmer\njazz ballad, European chanson\njazz ballad, French chanson, cinematic\njazz ballad, French chanson, melancholic\njazz ballad, Kayōkyoku\njazz ballad, Kayōkyoku, cinematic\njazz ballad, Kayōkyoku, melancholic\njazz ballad, Korean trot\njazz ballad, Latin jazz\njazz ballad, Latin jazz, exotica\njazz ballad, Latin pop-rock\njazz ballad, Latin soul\njazz ballad, Mandopop\njazz ballad, Norteño\njazz ballad, Turkish classical\njazz ballad, Turkish classical, world music\njazz ballad, bebop\njazz ballad, bebop, free jazz\njazz ballad, big band\njazz ballad, big band swing\njazz ballad, big band, bebop\njazz ballad, big band, cinematic\njazz ballad, big band, classical\njazz ballad, big band, free jazz\njazz ballad, big band, jazz\njazz ballad, big band, soulful\njazz ballad, big band, spoken word\njazz ballad, big band, theatrical jazz\njazz ballad, blues-rock\njazz ballad, boogie-woogie, swing\njazz ballad, bossa nova\njazz ballad, bossa nova, Christmas\njazz ballad, bossa nova, Vietnamese\njazz ballad, bossa nova, smooth jazz\njazz ballad, bossa nova, theatrical rock\njazz ballad, cinematic, Indonesian pop-jazz\njazz ballad, cinematic, orchestral\njazz ballad, cinematic, torch song\njazz ballad, city pop\njazz ballad, city pop, lounge\njazz ballad, doo-wop, jump blues\njazz ballad, experimental funk, lo-fi hip hop\njazz ballad, funk jazz, jazz-pop\njazz ballad, funk soul\njazz ballad, funk, disco\njazz ballad, funk-jazz\njazz ballad, gospel, soul\njazz ballad, gypsy jazz\njazz ballad, hard rock\njazz ballad, heavy metal\njazz ballad, jazz fusion, free jazz\njazz ballad, lo-fi hip hop\njazz ballad, lo-fi hip-hop\njazz ballad, lo-fi, R&B\njazz ballad, lounge jazz, Cantopop\njazz ballad, pop-rock, blues rock\njazz ballad, pop-rock, funk\njazz ballad, post-rock, bossa nova\njazz ballad, rap, blues\njazz ballad, samba-rock, blues-rock\njazz ballad, soft rock, Polish\njazz ballad, soul blues, city pop\njazz ballad, soul, lo-fi\njazz ballad, soul, rock\njazz ballad, soulful R&B\njazz ballad, soulful pop, cinematic\njazz ballad, soulful, South Asian classical\njazz ballad, spoken word, blues\njazz ballad, swing\njazz ballad, swing jazz\njazz ballad, theatrical pop\njazz ballad, theatrical pop, cinematic\njazz ballad, trip-hop, downtempo\njazz ballad, trot\njazz bebop\njazz big band\njazz big band, skate punk\njazz blues\njazz blues gospel\njazz blues rock\njazz blues world music\njazz bolero\njazz bolero, hip-hop\njazz boogie-woogie\njazz bossa nova\njazz breakbeat\njazz cabaret\njazz cabaret children's music\njazz chanson\njazz chanson, latin salsa\njazz children's\njazz children's Christmas\njazz children's music\njazz chiptune bossa nova\njazz cinematic\njazz classical\njazz crooner\njazz doo-wop\njazz drum and bass\njazz drum solo\njazz drumming\njazz electronica\njazz etude\njazz exotica\njazz fanfare\njazz folk\njazz folk pop\njazz folk rock\njazz folk-pop\njazz folk-rock\njazz funk\njazz funk disco\njazz funk lounge\njazz funk neo-soul\njazz funk pop\njazz funk progressive metal\njazz funk rock\njazz funk soul\njazz funk, Brazilian funk, soul\njazz fusion\njazz fusion R&B\njazz fusion bossa nova\njazz fusion chiptune\njazz fusion city pop\njazz fusion drum and bass\njazz fusion funk\njazz fusion funk chiptune\njazz fusion funk electronic\njazz fusion funk lounge\njazz fusion funk progressive rock\njazz fusion funk rock\njazz fusion funk soul\njazz fusion funk video game music\njazz fusion funk world music\njazz fusion garage rock\njazz fusion hip-hop\njazz fusion indie rock\njazz fusion latin rumba\njazz fusion lo-fi\njazz fusion lounge\njazz fusion lounge world music\njazz fusion metal\njazz fusion neo-soul\njazz fusion orchestral pop\njazz fusion pop-rock\njazz fusion progressive metal\njazz fusion progressive rock\njazz fusion progressive rock video game music\njazz fusion rock\njazz fusion salsa\njazz fusion samba\njazz fusion samba rock\njazz fusion soul\njazz fusion world music\njazz fusion, 16-bit video game\njazz fusion, Arabic music, flamenco\njazz fusion, Chinese folk, atmospheric\njazz fusion, J-pop\njazz fusion, J-pop, drum and bass\njazz fusion, J-rock, anime soundtrack\njazz fusion, J-rock, boogie-woogie\njazz fusion, J-rock, bossa nova\njazz fusion, J-rock, progressive rock\njazz fusion, Latin jazz, cinematic\njazz fusion, Latin jazz, city pop\njazz fusion, Latin, cinematic\njazz fusion, MPB, classical piano\njazz fusion, Turkish folk\njazz fusion, Turkish pop-rock\njazz fusion, blues rock, hard rock\njazz fusion, bossa nova, video game music\njazz fusion, breakbeat, art pop\njazz fusion, breakbeat, electronic\njazz fusion, breakbeat, video game music\njazz fusion, breakcore\njazz fusion, breakcore, drum and bass\njazz fusion, chiptune, Japanese video game music\njazz fusion, chiptune, electronic\njazz fusion, cinematic orchestral\njazz fusion, cinematic soul\njazz fusion, cinematic, big band\njazz fusion, cinematic, neo-classical\njazz fusion, city pop\njazz fusion, city pop, anime soundtrack\njazz fusion, city pop, big band\njazz fusion, city pop, video game music\njazz fusion, city pop, video game soundtrack\njazz fusion, drum and bass, video game music\njazz fusion, electronic breakbeat, video game music\njazz fusion, electronic funk, video game music\njazz fusion, forró\njazz fusion, funk rock, progressive metal\njazz fusion, funk, Indian film music\njazz fusion, funk, chiptune\njazz fusion, funk, progressive rock\njazz fusion, funk, traditional East Asian\njazz fusion, funk, video game music\njazz fusion, future bass\njazz fusion, house, video game music\njazz fusion, math rock\njazz fusion, neo-soul, UK garage\njazz fusion, progressive electronic, video game music\njazz fusion, progressive house\njazz fusion, progressive house, video game music\njazz fusion, progressive metal\njazz fusion, progressive metal, video game music\njazz fusion, progressive rock\njazz fusion, progressive rock, Japanese RPG\njazz fusion, progressive rock, ambient\njazz fusion, progressive rock, chiptune\njazz fusion, progressive rock, cinematic\njazz fusion, progressive rock, game music\njazz fusion, progressive rock, math rock\njazz fusion, progressive rock, video game music\njazz fusion, progressive rock, video game soundtrack\njazz fusion, psychedelic rock\njazz fusion, reggae-dancehall\njazz fusion, samba rock\njazz fusion, synth-pop\njazz fusion, theatrical swing, world music\njazz fusion, turntablism, electronic funk\njazz fusion, video game music\njazz fusion, video game music, Japanese\njazz fusion, video game music, big band\njazz fusion, video game music, breakbeat\njazz fusion, video game music, funk\njazz fusion, video game music, piano virtuosity\njazz fusion, video game music, world percussion\njazz fusion, video game soundtrack, artcore\njazz fusion, world fusion, lo-fi\njazz fusion, world music\njazz fusion, world music, Turkish folk\njazz fusion, world music, vocal jazz\njazz future bass\njazz ghazal\njazz gospel\njazz gospel latin ballad\njazz guitar\njazz hip hop\njazz hip hop boom-bap\njazz hip hop, soulful house\njazz hip-hop\njazz hip-hop alternative rock\njazz hip-hop boom-bap\njazz hip-hop city pop\njazz hip-hop city-pop\njazz hip-hop drum and bass\njazz hip-hop funk\njazz hip-hop funk rock\njazz hip-hop funk-hop\njazz hip-hop funk-rock\njazz hip-hop fusion\njazz hip-hop indie-pop\njazz hip-hop lo-fi\njazz hip-hop neo-soul\njazz hip-hop post-hardcore\njazz hip-hop salsa\njazz hip-hop samba-rock\njazz hip-hop soul\njazz hip-hop trap\njazz hip-hop, Afro-Cuban salsa\njazz hip-hop, French rap, Jamaican Patois\njazz hip-hop, R&B, cinematic\njazz hip-hop, UK rap\njazz hip-hop, drum and bass\njazz hip-hop, dubstep\njazz hip-hop, funk\njazz hip-hop, lo-fi hip-hop\njazz hip-hop, lo-fi hip-hop, electronic\njazz hip-hop, lo-fi, experimental\njazz hip-hop, neo-soul, cinematic\njazz hip-hop, neo-soul, reggae\njazz hip-hop, rap-rock\njazz hip-hop, rock, neo-soul\njazz hip-hop, trap\njazz hip-hop, trap, neo-soul\njazz hip-hop, vaporwave\njazz holiday\njazz hop\njazz hop dark trap\njazz house\njazz impressionism\njazz improvisation\njazz indie\njazz indie pop\njazz indie rock\njazz indie-folk\njazz indie-pop\njazz instrumental\njazz jingle\njazz lounge\njazz lounge alt-rock\njazz lounge alternative rock\njazz lounge ambient\njazz lounge art-pop\njazz lounge blues-rock\njazz lounge disco house\njazz lounge funk\njazz lounge funk rock\njazz lounge garage rock\njazz lounge hip-hop\njazz lounge indie rock\njazz lounge indie rock psychedelic rock\njazz lounge indie-folk\njazz lounge k-pop\njazz lounge lo-fi hip hop\njazz lounge nu-disco\njazz lounge pop\njazz lounge pop-rock\njazz lounge post-rock\njazz lounge progressive rock\njazz lounge psychedelic rock\njazz lounge rock\njazz lounge salsa\njazz lounge swing rock\njazz lounge, Dutch party, electronic\njazz lounge, Latin jazz, rock\njazz lounge, alternative rock, C-pop\njazz lounge, breakcore, glitch\njazz lounge, hyperpop\njazz lounge, latin funk, cinematic\njazz lounge, latin jazz\njazz lounge, noise rock, ambient\njazz lounge, nu-disco, deep house\njazz lounge, psychedelic rock\njazz lounge, psychedelic rock, experimental\njazz lounge, swing, boogie-woogie\njazz lounge, theatrical rock, cabaret\njazz lullaby\njazz mambo\njazz manouche\njazz metal\njazz musical theater\njazz noir\njazz noir cabaret\njazz noir funk rock\njazz noir rock\njazz nursery rhyme\njazz opera\njazz orchestral\njazz piano\njazz piano trio\njazz piano, breakcore, electronic\njazz poetry\njazz pop\njazz pop R&B\njazz pop anime\njazz pop anime soundtrack\njazz pop ballad\njazz pop bossa nova\njazz pop cabaret\njazz pop chanson\njazz pop city pop\njazz pop city-pop\njazz pop estrada\njazz pop funk\njazz pop funk soul\njazz pop latin\njazz pop lo-fi\njazz pop lounge\njazz pop rap\njazz pop reggae\njazz pop rock\njazz pop soul\njazz pop swing\njazz pop tango\njazz pop world music\njazz pop, Bollywood, ragtime\njazz pop, J-rock\njazz pop, Javanese pop\njazz pop, Latin pop, bossa nova\njazz pop, Latin pop, upbeat\njazz pop, Latin, big band\njazz pop, South Indian film music\njazz pop, cinematic rock, bossa nova\njazz pop, estrada, Eastern European\njazz pop, neo-soul, city pop\njazz pop-rock\njazz pop-rock, German hip-hop\njazz post-rock\njazz punk\njazz punk gypsy\njazz ragtime\njazz rap\njazz rap blues rock\njazz rap emo rap\njazz rap funk\njazz rap lo-fi\njazz rap lo-fi hip hop\njazz rap lo-fi hip-hop\njazz rap neo-soul\njazz rap, K-hip-hop, bossa nova\njazz rap, Korean hip-hop\njazz rap, MPB\njazz rap, Mandopop, lo-fi hip-hop\njazz rap, UK drill\njazz rap, chillhop\njazz rap, conscious hip-hop\njazz rap, conscious hip-hop, North African\njazz rap, conscious hip-hop, lo-fi hip hop\njazz rap, conscious hip-hop, lo-fi hip-hop\njazz rap, lo-fi hip hop\njazz rap, lo-fi hip hop, UK hip-hop\njazz rap, lo-fi hip hop, conscious hip-hop\njazz rap, lo-fi hip-hop, C-pop\njazz rap, lo-fi hip-hop, R&B\njazz rap, neo-soul, lo-fi hip-hop\njazz reggae\njazz reggaeton\njazz reinterpretation\njazz rock\njazz rock hip-hop\njazz rock progressive metal\njazz rock punk\njazz rock, J-rock, city-pop\njazz rockabilly\njazz romance\njazz salsa\njazz samba\njazz samba rock\njazz shanty\njazz show tune\njazz singer-songwriter\njazz soft rock\njazz soul\njazz soul Afrobeat\njazz soul R&B\njazz soul funk\njazz soul funk rock\njazz soul, Latin hip-hop\njazz soul, funk hip-hop, drum and bass\njazz spoken word\njazz spy theme\njazz standard\njazz stride\njazz stride ragtime\njazz swing\njazz swing cabaret\njazz swing children's music\njazz swing show tune\njazz tango\njazz tango Russian chanson\njazz trap\njazz trap C-pop\njazz trio\njazz trip-hop\njazz ukulele\njazz video game\njazz vocal\njazz waltz\njazz world music\njazz, Arabic fusion\njazz, Arabic jazz\njazz, Arabic soul\njazz, Arabic swing\njazz, Balkan folk, Turkish pop\njazz, Balkan folk, tango\njazz, Balkan, ambient\njazz, Brazilian, theatrical\njazz, Broadway\njazz, Broadway, boogie-woogie\njazz, Broadway, theatrical\njazz, Caribbean\njazz, Caribbean, Afro-Latin\njazz, Caribbean, upbeat\njazz, Christmas\njazz, Christmas, Hebrew ballad\njazz, Christmas, ballad\njazz, Christmas, boogie-woogie\njazz, Christmas, ragtime\njazz, Christmas, retro\njazz, Christmas, swing\njazz, French chanson\njazz, French chanson, big band\njazz, French chanson, cool jazz\njazz, Italian pop\njazz, Kayōkyoku\njazz, Latin jazz\njazz, Latin jazz, Bossa Nova\njazz, Latin jazz, klezmer\njazz, Latin, Christmas\njazz, Latin, bolero\njazz, Latin, cabaret\njazz, Latin, flamenco\njazz, Latin, theatrical\njazz, Latin, world music\njazz, Persian vocal, swing\njazz, R&B\njazz, R&B, Christmas\njazz, R&B, blues\njazz, Turkish jazz\njazz, acoustic, Christmas\njazz, adult contemporary\njazz, avant-garde, theatrical\njazz, ballad\njazz, ballad, Javanese\njazz, ballad, big band\njazz, ballad, swing\njazz, ballad, theatrical\njazz, bebop, African jazz\njazz, bebop, Greek jazz\njazz, bebop, Mandarin vocal jazz\njazz, bebop, Persian jazz\njazz, bebop, choral\njazz, bebop, swing\njazz, big band\njazz, big band, Christmas\njazz, big band, Greek vocal\njazz, big band, Latin jazz\njazz, big band, ballad\njazz, big band, cinematic\njazz, big band, classical\njazz, big band, crooner\njazz, big band, free jazz\njazz, big band, funk\njazz, big band, hip hop\njazz, big band, holiday\njazz, big band, piano ballad\njazz, big band, ragtime\njazz, big band, retro Christmas\njazz, big band, show tune\njazz, big band, showtune\njazz, big band, soul\njazz, big band, spoken word\njazz, blues, Latin\njazz, blues, ghazal\njazz, blues, lounge\njazz, blues-rock, big band\njazz, boogie-woogie, Christmas\njazz, boogie-woogie, Portuguese pop\njazz, boogie-woogie, educational\njazz, boogie-woogie, jump blues\njazz, boogie-woogie, soul\njazz, boogie-woogie, swing\njazz, bossa nova\njazz, bossa nova, French chanson\njazz, bossa nova, Italian singer-songwriter\njazz, bossa nova, Polish pub\njazz, bossa nova, Russian romance\njazz, bossa nova, Turkish folk\njazz, bossa nova, acoustic\njazz, bossa nova, cabaret\njazz, bossa nova, holiday\njazz, bossa nova, latin jazz\njazz, bossa nova, lounge\njazz, bossa nova, theatrical\njazz, bossa nova, torch song\njazz, bossa nova, vocal\njazz, bossa nova, vocal jazz\njazz, cabaret, free jazz\njazz, cabaret, lo-fi\njazz, chanson\njazz, chanson, big band\njazz, chanson, boogie-woogie\njazz, chanson, classical\njazz, chanson, piano ballad\njazz, children's music\njazz, children's music, Christmas\njazz, children's music, big band\njazz, children's music, retro\njazz, children's music, show tune\njazz, children's music, swing\njazz, christmas, big band\njazz, christmas, musical theater\njazz, christmas, soul\njazz, cinematic\njazz, cinematic, European cafe\njazz, cinematic, French chanson\njazz, cinematic, Italian\njazz, cinematic, Latin\njazz, cinematic, ambient\njazz, cinematic, ballad\njazz, cinematic, chanson\njazz, cinematic, christmas\njazz, cinematic, folk\njazz, cinematic, lo-fi hip hop\njazz, cinematic, orchestral\njazz, cinematic, post-rock\njazz, cinematic, theatrical\njazz, cinematic, torch song\njazz, circus, playful\njazz, classical, Christmas\njazz, classical, French pop\njazz, classical, ballad\njazz, classical, cabaret\njazz, classical, christmas\njazz, classical, fado\njazz, classical, folk\njazz, classical, theatrical\njazz, contemporary classical\njazz, drum and bass, glitch\njazz, educational, ragtime\njazz, enka, soul\njazz, film noir, big band\njazz, folk, musette\njazz, gospel, theatrical\njazz, gypsy jazz, Persian vocal\njazz, holiday, festive\njazz, honky-tonk\njazz, jump blues\njazz, klezmer\njazz, klezmer, accordion\njazz, klezmer, lounge\njazz, latin, piano ballad\njazz, melancholic, Hindi\njazz, neo-soul, chill-out\njazz, novelty Christmas, swing\njazz, novelty, Christmas\njazz, operatic, cinematic\njazz, piano ballad, Latin jazz\njazz, piano ballad, tango\njazz, ragtime, Christmas\njazz, ragtime, Dutch pop\njazz, ragtime, stride\njazz, rockabilly, holiday\njazz, salsa\njazz, samba, bossa nova\njazz, samba-rock\njazz, show tune, children's music\njazz, ska, reggae\njazz, smoky jazz, Mandarin ballad\njazz, soul, Christmas\njazz, soul, R&B\njazz, soul, big band\njazz, soul, boogie-woogie\njazz, soul, lounge\njazz, spiritual, C-pop\njazz, spoken word, French chanson\njazz, spy music, cinematic\njazz, spy theme, cartoon\njazz, stride, ragtime\njazz, swing\njazz, swing, Christmas\njazz, swing, vocal jazz\njazz, synth-pop\njazz, theatrical pop\njazz, theatrical pop, rock\njazz, theatrical, Japanese\njazz, theatrical, big band\njazz, theatrical, children's music\njazz, theatrical, cinematic\njazz, theatrical, film noir\njazz, theatrical, noir\njazz, theatrical, punk-jazz\njazz, tropical, Christmas\njazz, trot\njazz, video game, upbeat\njazz, vocal jazz, boogie-woogie\njazz, world music, inspirational anthem\njazz-blues\njazz-blues bossa nova\njazz-blues lounge\njazz-blues, Latin jazz\njazz-blues, pub rock\njazz-folk\njazz-funk\njazz-funk C-pop\njazz-funk J-pop\njazz-funk Latin\njazz-funk Latin fusion\njazz-funk Latin jazz\njazz-funk R&B\njazz-funk acid jazz\njazz-funk acid jazz lounge\njazz-funk anime\njazz-funk anime theme\njazz-funk big band\njazz-funk blues-rock\njazz-funk bossa nova\njazz-funk cabaret\njazz-funk chiptune\njazz-funk city pop\njazz-funk city pop anime\njazz-funk city-pop\njazz-funk disco\njazz-funk disco-house\njazz-funk fusion\njazz-funk fusion, progressive metal, djent\njazz-funk gospel\njazz-funk hip-hop\njazz-funk house\njazz-funk indie rock\njazz-funk j-rock\njazz-funk lo-fi\njazz-funk lounge\njazz-funk neo-soul\njazz-funk neo-soul city pop\njazz-funk noir\njazz-funk nu-jazz\njazz-funk pop-rock\njazz-funk progressive rock\njazz-funk psychedelic\njazz-funk rock\njazz-funk soul\njazz-funk soul-jazz\njazz-funk soul-pop\njazz-funk soul-rock\njazz-funk tango\njazz-funk, Indian classical\njazz-funk, J-pop, anime theme\njazz-funk, J-rap, funk\njazz-funk, J-rock\njazz-funk, J-rock, instrumental rock\njazz-funk, Latin jazz\njazz-funk, Latin jazz, groove\njazz-funk, Latin, upbeat\njazz-funk, MPB, Brazilian\njazz-funk, Soviet estrada, funk\njazz-funk, breakbeat, drum and bass\njazz-funk, cinematic soul\njazz-funk, cinematic, orchestral\njazz-funk, cinematic, psychedelic rock\njazz-funk, city pop, synth jazz\njazz-funk, city pop, video game music\njazz-funk, city pop, video game soundtrack\njazz-funk, psychedelic rock\njazz-funk, retro video game music\njazz-funk, video game music\njazz-funk, video game music, retro lounge\njazz-funk, video game music, synth funk\njazz-funk, video game soundtrack\njazz-funk, video game, retro-futuristic\njazz-fusion\njazz-fusion J-pop\njazz-fusion J-rock\njazz-fusion MPB\njazz-fusion R&B\njazz-fusion anime\njazz-fusion anime soundtrack\njazz-fusion bossa nova\njazz-fusion chiptune\njazz-fusion city pop\njazz-fusion city pop Shibuya-kei\njazz-fusion city pop anime\njazz-fusion city pop funk\njazz-fusion city pop latin\njazz-fusion city pop video game music\njazz-fusion city-pop\njazz-fusion drum and bass\njazz-fusion funk\njazz-fusion funk pop\njazz-fusion funk pop-rock\njazz-fusion funk progressive pop\njazz-fusion funk psychedelic rock\njazz-fusion funk rock\njazz-fusion funk soul\njazz-fusion funk-pop\njazz-fusion funk-rock\njazz-fusion hip-hop\njazz-fusion j-pop\njazz-fusion lounge\njazz-fusion neo-soul\njazz-fusion neo-soul city pop\njazz-fusion orchestral\njazz-fusion pop\njazz-fusion pop-rock\njazz-fusion progressive metal\njazz-fusion progressive rock\njazz-fusion rock\njazz-fusion soul\njazz-fusion, J-pop\njazz-fusion, J-pop, chiptune\njazz-fusion, J-pop, video game music\njazz-fusion, J-rock\njazz-fusion, J-rock, anime\njazz-fusion, J-rock, anime theme\njazz-fusion, J-rock, video game music\njazz-fusion, Latin, city pop\njazz-fusion, Shibuya-kei, funk\njazz-fusion, cinematic, J-pop\njazz-fusion, cinematic, anime\njazz-fusion, city pop, Japanese\njazz-fusion, city pop, Japanese video game music\njazz-fusion, city pop, anime\njazz-fusion, city pop, video game music\njazz-fusion, city pop, video game soundtrack\njazz-fusion, hip-hop, J-pop\njazz-fusion, hyper-pop\njazz-fusion, hyper-pop, C-pop\njazz-fusion, progressive house, chiptune\njazz-fusion, progressive metal, Indian rock\njazz-fusion, progressive rock\njazz-gospel\njazz-hop\njazz-hop big band\njazz-hop boom-bap\njazz-hop funk\njazz-hop lo-fi\njazz-hop lo-fi hip hop\njazz-hop lo-fi hip-hop\njazz-hop lounge\njazz-hop neo-soul\njazz-hop retro-swing\njazz-hop trap\njazz-hop, K-hip-hop, trap\njazz-hop, drum and bass, Latin jazz\njazz-inflected C-pop\njazz-inflected Cantopop\njazz-inflected K-ballad\njazz-inflected Mandopop\njazz-inflected R&B\njazz-inflected pop-rock\njazz-influenced singer-songwriter\njazz-infused C-pop\njazz-infused J-pop\njazz-infused R&B\njazz-infused electronic\njazz-infused pop-rock\njazz-noir\njazz-pop\njazz-pop Bollywood\njazz-pop C-pop\njazz-pop Celtic\njazz-pop K-pop\njazz-pop R&B\njazz-pop acoustic pop\njazz-pop anime\njazz-pop anime soundtrack\njazz-pop art rock\njazz-pop ballad\njazz-pop big band\njazz-pop boogie-woogie\njazz-pop bossa nova\njazz-pop cabaret\njazz-pop cabaret tango\njazz-pop chanson\njazz-pop chiptune\njazz-pop cinematic rock\njazz-pop city pop\njazz-pop city pop bossa nova\njazz-pop city pop neo-soul\njazz-pop city-pop\njazz-pop city-pop anime\njazz-pop city-pop bossa nova\njazz-pop cumbia\njazz-pop doo-wop\njazz-pop exotica\njazz-pop flamenco\njazz-pop funk\njazz-pop funk-pop\njazz-pop funk-rock\njazz-pop fusion\njazz-pop gospel\njazz-pop gypsy jazz cabaret\njazz-pop lo-fi\njazz-pop lo-fi hip-hop\njazz-pop lounge\njazz-pop lounge-pop\njazz-pop mandopop\njazz-pop neo-soul\njazz-pop neo-soul funk\njazz-pop noir\njazz-pop pop-rock\njazz-pop ragtime\njazz-pop rap\njazz-pop rock\njazz-pop samba\njazz-pop soul\njazz-pop tango\njazz-pop tango gypsy jazz\njazz-pop, J-rock\njazz-pop, city-pop, Latin jazz\njazz-pop, hardstyle, chiptune\njazz-pop, pop-rock, hip-hop\njazz-pop, rap, rock\njazz-punk fusion\njazz-rap\njazz-rap C-pop ballad\njazz-rap acid jazz\njazz-rap alternative rock\njazz-rap big band funk\njazz-rap blues-rock\njazz-rap boom-bap\njazz-rap funk\njazz-rap funk-rap\njazz-rap funk-rock\njazz-rap lo-fi\njazz-rap lo-fi hip hop\njazz-rap lo-fi hip-hop\njazz-rap neo-soul\njazz-rap samba-rock\njazz-rap, Brazilian funk\njazz-rap, lo-fi hip hop, ambient\njazz-reggae\njazz-rock\njazz-rock anime\njazz-rock art-pop\njazz-rock big band\njazz-rock blues-rock\njazz-rock cabaret\njazz-rock fusion\njazz-rock lounge\njazz-rock piano-rock\njazz-rock progressive math-rock\njazz-rock progressive metal\njazz-rock progressive rock\njazz-rock punk\njazz-rock, J-pop\njazz-rock, J-pop, progressive rock\njazz-rock, J-rock\njazz-rock, Latin rock\njazz-rock, acoustic pop, theatrical\njazz-rock, anime theme, j-rock\njazz-rock, chiptune, drum and bass\njazz-rock, denpa-kei, Vocaloid\njazz-rock, hyper-pop, anime\njazz-rock, lo-fi, Hindi pop\njazz-rock, post-punk, Eastern European\njazz-rock, punk, cinematic\njazz-rock, surf rock, big band\njazz-samba\njazz-schlager\njazz-ska\njazz-soul\njazz-soul funk-rock\njazz-swing\njazz-swing gypsy jazz\njazz-swing noir\njazz-trap\njazz-trap lo-fi hip hop\njazzy C-pop\njazzy R&B\njazzy boom-bap\njazzy electronic\njazzy folk\njazzy hip-hop\njazzy hip-hop lo-fi\njazzy hip-hop neo-soul\njazzy holiday\njazzy house\njazzy indie pop\njazzy indie rock\njazzy indie-pop\njazzy lo-fi\njazzy lo-fi hip hop\njazzy lo-fi hip-hop\njazzy pop\njazzy pop anime\njazzy pop, UK garage, drum and bass\njazzy pop-rock\njazzy reggae\njazzy rock\njazzy trap\njedag jedug\njedag jedug haryanvi\njimeshai, haryanvi, electronic dance\njingle\njingle pop\njingle, chiptune, upbeat\njingle, pop, folk\njingle, synth pop, multilingual\njoropo\njoropo candombe\njoropo cumbia\njoropo salsa\njphonya\njtedag jtedug\njump blues\njump blues boogie-woogie\njump blues cabaret\njump blues country-blues\njump blues country-western\njump blues funk\njump blues gospel\njump blues gypsy jazz\njump blues lounge jazz\njump blues mambo\njump blues ragtime\njump blues rock and roll\njump blues rockabilly\njump blues rockabilly big band\njump blues rockabilly boogie-woogie\njump blues rockabilly swing\njump blues soul\njump blues swing\njump blues swing cabaret\njump blues swing jazz\njump blues western swing\njump blues, Southern rock\njump blues, big band\njump blues, big band jazz\njump blues, big band swing\njump blues, big band, piano ballad\njump blues, big band, ragtime\njump blues, big band, soul\njump blues, big band, swing\njump blues, boogie-woogie\njump blues, boogie-woogie, blues-rock\njump blues, boogie-woogie, free jazz\njump blues, boogie-woogie, rock and roll\njump blues, early rock and roll\njump blues, early rock and roll, novelty\njump blues, rock and roll\njump blues, rock and roll, Christmas\njump blues, rock and roll, rockabilly\njump blues, rockabilly\njump blues, swing\njump blues, swing rock\njump blues, swing, big band\njump blues, swing, novelty\njump blues, swing, soul\njump blues, swing, theatrical\njump blues, western swing\njump jive\njumpstyle\njumpstyle gabber\njungle\njungle acid jazz\njungle big beat\njungle big beat latin\njungle big beat world music\njungle breakbeat\njungle breakbeat big beat\njungle breakbeat chiptune\njungle breakbeat dancehall\njungle breakbeat hyperpop\njungle breakbeat video game\njungle breakcore\njungle breakcore IDM\njungle chiptune\njungle cumbia\njungle dance-pop\njungle dancehall\njungle drum and bass\njungle drum and bass breakcore\njungle drum and bass chiptune\njungle drum and bass hip-hop\njungle drum and bass trip-hop\njungle drum and bass vaporwave\njungle drum and bass video game music\njungle dubstep\njungle experimental hip-hop\njungle funk\njungle funk soul\njungle future bass glitch-hop\njungle gabber\njungle glitch-hop\njungle grime\njungle happy hardcore\njungle hip-hop\njungle house\njungle hyperpop\njungle metalcore\njungle neurofunk\njungle pop\njungle rap-rock\njungle rapcore\njungle rave\njungle reggae dancehall\njungle ska-punk\njungle speedcore\njungle techno\njungle trance\njungle, Bollywood, breakbeat\njungle, IDM, breakbeat\njungle, J-pop, video game\njungle, Japanese rap, breakbeat\njungle, Punjabi folk, electronic\njungle, R&B, gospel\njungle, Turkish pop\njungle, big beat\njungle, big beat, breakbeat\njungle, big beat, drum and bass\njungle, breakbeat, Middle Eastern\njungle, breakbeat, ambient\njungle, breakbeat, chiptune\njungle, chiptune\njungle, chiptune, artcore\njungle, chiptune, breakbeat\njungle, chiptune, lo-fi\njungle, chiptune, video game music\njungle, drum and bass, chiptune\njungle, drum and bass, experimental electronic\njungle, flamenco, Latin\njungle, free jazz\njungle, happy hardcore, chiptune\njungle, hyperpop\njungle, schlager\njungle, synthwave, video game\njíbaro salsa\nk-pop\nk-pop j-pop\nk-pop, lo-fi hip hop\nk-pop, trot-pop, children's music\nkalimba music\nkalypso\nkaraoke pop\nkawaii\nkawaii C-pop\nkawaii C-pop, hyperpop, chiptune\nkawaii J-pop\nkawaii R&B\nkawaii bass\nkawaii bass, chiptune, J-core\nkawaii chiptune\nkawaii chiptune-pop\nkawaii dubstep\nkawaii electronic\nkawaii future bass\nkawaii future bass, chiptune, C-pop\nkawaii future bass, hyperpop, C-pop\nkawaii future jazz-pop\nkawaii hip-hop\nkawaii metal, J-rock\nkawaii metal, J-rock, metalcore\nkawaii metal, chiptune, J-rock\nkawaii metal, melodic metalcore\nkawaii metalcore\nkawaii metalcore, J-rock\nkawaii pop\nkawaii pop chiptune\nkawaii pop, hyperpop, C-pop\nkawaii rap\nkawaii synth-pop\nkawaii trap\nkawaii-core\nkawaii-pop\nkawaii-pop chiptune\nkawaii-pop chiptune hip-hop\nkawaii-pop lo-fi hip-hop\nkawaii-pop trap\nkawaii-pop, J-pop, chiptune\nkayōkyoku\nkazoe\nkeroncong\nkeroncong jazz\nkeroncong, cinematic ballad\nkeroncong, gamelan, romantic pop\nkids hip-hop\nkids pop\nkids' pop\nkinderlied\nkirtan\nkizomba\nkizomba synth-pop\nkizomba zouk\nkizomba, angolan folk\nklezmer\nklezmer bossa nova\nklezmer cabaret\nklezmer cabaret children's\nklezmer children's music\nklezmer circus\nklezmer classical\nklezmer dance-pop\nklezmer folk\nklezmer folk rock\nklezmer folk-rock\nklezmer funk\nklezmer funk-rock\nklezmer fusion\nklezmer hardstyle\nklezmer hip hop\nklezmer hip-hop\nklezmer hip-hop fusion\nklezmer jazz\nklezmer jazz orchestral\nklezmer metal\nklezmer novelty\nklezmer opera\nklezmer polka\nklezmer polka children's music\nklezmer polka novelty\nklezmer pop\nklezmer pop-rock\nklezmer punk\nklezmer punk rock\nklezmer punk ska\nklezmer rock\nklezmer rock, rockabilly, gospel rock\nklezmer rock, surf rock, rockabilly\nklezmer rock, trap\nklezmer rockabilly\nklezmer rockabilly surf\nklezmer ska\nklezmer ska-punk\nklezmer ska-punk big band\nklezmer ska-punk chiptune\nklezmer ska-punk rock\nklezmer surf rock\nklezmer surf rock big band\nklezmer surf rock pop-rock\nklezmer surf rock psychedelic rock\nklezmer surf rock theatrical pop\nklezmer swing\nklezmer synth-pop\nklezmer tango folk\nklezmer tango ragtime\nklezmer trap\nklezmer, Balkan brass, theatrical rock\nklezmer, Balkan folk, big band\nklezmer, Balkan folk, cinematic\nklezmer, Balkan folk, instrumental\nklezmer, Balkan folk, tango\nklezmer, Balkan folk, theatrical\nklezmer, Balkan, instrumental\nklezmer, Eastern European folk, cinematic\nklezmer, Yiddish folk, theatrical\nklezmer, ambient, Persian folk\nklezmer, ambient, experimental\nklezmer, art song, tango\nklezmer, balkan folk\nklezmer, balkan folk, big band jazz\nklezmer, balkan folk, brazilian percussion\nklezmer, balkan folk, folk-rock\nklezmer, balkan folk, lounge\nklezmer, big band, children's music\nklezmer, boogie-woogie, rock and roll\nklezmer, cabaret, folk\nklezmer, children's music\nklezmer, children's music, polka\nklezmer, cinematic, avant-garde\nklezmer, cinematic, folk\nklezmer, cinematic, jazz\nklezmer, cinematic, orchestral\nklezmer, cinematic, playful\nklezmer, circus music, classical chamber\nklezmer, circus music, musette\nklezmer, circus, instrumental\nklezmer, circus, lo-fi\nklezmer, circus, upbeat\nklezmer, classical, ambient\nklezmer, classical, folk\nklezmer, electronic, Balkan folk\nklezmer, electronic, dance\nklezmer, electronic, theatrical\nklezmer, folk rock, cinematic\nklezmer, folk, cinematic\nklezmer, folk, instrumental\nklezmer, folk, theatrical\nklezmer, folk, virtuosic\nklezmer, folk, waltz\nklezmer, gypsy jazz, theatrical rock\nklezmer, gypsy punk, Balkan folk\nklezmer, jazz, Armenian folk\nklezmer, jazz, European street\nklezmer, jazz, big band\nklezmer, jazz, cinematic\nklezmer, jazz, quirky\nklezmer, liturgical, folk\nklezmer, musette, violin\nklezmer, operatic folk, cinematic\nklezmer, polka, Eastern European folk\nklezmer, polka, avant-garde\nklezmer, polka, cabaret\nklezmer, polka, circus\nklezmer, polka, jazz\nklezmer, polka, theatrical\nklezmer, ragtime, boogie-woogie\nklezmer, soul, theatrical\nklezmer, theatrical pop, piano ballad\nklezmer, theatrical, accordion\nklezmer, theatrical, christmas\nklezmer, theatrical, circus\nklezmer, theatrical, folk\nklezmer, theatrical, folk rock\nklezmer, theatrical, quirky\nklezmer, theatrical, vintage\nklezmer, upbeat, playful\nklezmer, vintage, dramatic\nklezmer, waltz, instrumental\nklezmer-pop\nklezmer-punk\nklezmer-punk surf rock\nklezmer-rock\nklezmer-ska\nkorean narrative\nkroncong bossa nova\nkuduro\nkuthak dance\nkuthu\nkuthu funk\nkuthu gaana\nkuthu gana\nkuthu hip-hop electronic\nkuthu hip-hop hardstyle\nkuthu rock\nkuthu, electronic dance\nkuthu, gaana, electronic dance\nkuthu-core\nkuthuosi\nkuthuosi haryanvi\nlaid-back jazz\nlanguage learning\nlate '80s R&B\nlate '90s R&B\nlate 90s R&B\nlate Romantic\nlate Romantic classical\nlate romantic classical\nlate-80s R&B\nlate-80s R&B soul\nlate-90s R&B\nlate-90s R&B, Latin pop\nlate-90s hip-hop\nlate-90s house\nlate-Romantic\nlate-Romantic classical\nlate-Romantic orchestral\nlate-Romantic piano\nlate-night R&B\nlatin R&B\nlatin alternative\nlatin ballad\nlatin big band, big band jazz, latin rock\nlatin dance-pop\nlatin folk-pop\nlatin funk\nlatin hip-hop\nlatin house\nlatin jazz\nlatin jazz bossa nova\nlatin jazz pop\nlatin jazz pop-funk\nlatin jazz-funk\nlatin jazz-pop\nlatin pop\nlatin pop bossa nova\nlatin pop chiptune\nlatin pop deep house\nlatin pop flamenco\nlatin pop lo-fi hip hop\nlatin pop punk\nlatin pop reggaeton\nlatin pop rock\nlatin pop, R&B, lo-fi hip-hop\nlatin pop, deep house\nlatin pop, latin house\nlatin pop, lo-fi hip hop\nlatin pop, lo-fi hip hop, R&B\nlatin pop, lo-fi hip hop, bedroom pop\nlatin pop, lo-fi hip-hop\nlatin pop, lo-fi hip-hop, R&B\nlatin pop-folk\nlatin pop-rap\nlatin pop-rock\nlatin pop-rock ska-punk\nlatin rock\nlatin rock funk\nlatin rock punk\nlatin rock salsa\nlatin rock, big band jazz\nlatin rock, big band, jazz fusion\nlatin rock, big band, swing\nlatin tech house\nlatin trap\nlatin trap, R&B, ambient\nlatin trap, alternative R&B\nlatin trap, experimental pop\nlatin trap, moombahton, industrial\nlatin trip-hop\nlatin urban pop\nlatin-funk\nlatin-pop\nlatin-pop bossa nova\nlatin-pop salsa\nlaïko\nlaïko chiptune\nlevenslied\nlevenslied big band\nlevenslied bossa nova\nlevenslied chiptune\nlevenslied cumbia\nlevenslied indie\nlevenslied latin pop\nlevenslied pop-rock\nlevenslied, Dutch folk, theatrical\nlevenslied, Latin, theatrical\nlevenslied, bağlama, melancholic\nlevenslied, big band swing\nlevenslied, boogie-woogie, musical theatre\nlevenslied, cabaret, folk\nlevenslied, happy hardcore, Eurodance\nlevenslied, polka, carnival\nlevenslied, polka, schlager\nlevenslied, polka, theatrical\nlibrary music\nlight acoustic\nlight classical\nlight folk\nlight instrumental\nlight jazz\nlight piano\nlight pop\nliquid D&B chiptune\nliquid dnb\nliquid dnb afrobeat\nliquid dnb city pop\nliquid dnb jazz fusion\nliquid drum & bass\nliquid drum and bass\nliquid drum and bass K-pop\nliquid drum and bass chillwave\nliquid drum and bass funk\nliquid drum and bass future bass\nliquid drum and bass future garage\nliquid drum and bass hip-hop\nliquid drum and bass indie pop\nliquid drum and bass jazz\nliquid drum and bass jazz fusion\nliquid drum and bass jazz-funk\nliquid drum and bass neo-soul\nliquid drum and bass pop\nliquid drum and bass post-rock\nliquid drum and bass, neurofunk\nliquid funk\nliquid funk, drum and bass\nliturgical\nliturgical a cappella\nliturgical ambient\nliturgical chant\nliturgical chant, Indian film music, electronic\nliturgical choral\nliturgical folk\nliturgical music\nliturgical organ\nliturgical rock\nliturgical synth-pop\nlive acoustic\nlive audience\nlive ballad\nlive concert band\nlive drum\nlive folk\nlive house\nlive pagode\nlive performance\nlive piano\nlive piano rock\nlive pop\nlive pop-worship\nlive recording\nlive rock\nlive rock worship\nlive samba\nlive soul\nlive worship\nlo-fi\nlo-fi African folk\nlo-fi African gospel\nlo-fi Afro-Brazilian funk\nlo-fi Afro-fusion\nlo-fi Afro-gospel\nlo-fi Afrobeat\nlo-fi Afrobeats\nlo-fi Americana\nlo-fi Arabic\nlo-fi Arabic electronica\nlo-fi Arabic folk\nlo-fi Arabic fusion\nlo-fi Arabic hip-hop\nlo-fi Arabic pop\nlo-fi Arabic soul\nlo-fi Arabic spoken word\nlo-fi Bengali\nlo-fi Bollywood\nlo-fi Bossa Nova\nlo-fi Brazilian Funk\nlo-fi Brazilian R&B\nlo-fi Brazilian electronic\nlo-fi Brazilian funk\nlo-fi Brazilian funk, hyperpop, R&B\nlo-fi Brazilian fusion\nlo-fi Brazilian jazz\nlo-fi Brazilian pop\nlo-fi Brazilian trap\nlo-fi C-pop\nlo-fi C-pop R&B\nlo-fi C-pop bossa nova\nlo-fi C-pop city pop\nlo-fi C-pop emo rap\nlo-fi C-pop future bass\nlo-fi C-pop hip-hop\nlo-fi C-pop neo-soul\nlo-fi C-pop rap\nlo-fi C-pop trap\nlo-fi C-pop trap-R&B\nlo-fi Canto-pop\nlo-fi Chinese New Year\nlo-fi Chinese pop\nlo-fi Chinese trap\nlo-fi Christian\nlo-fi Christian hip-hop\nlo-fi Christian rock\nlo-fi Christmas\nlo-fi Christmas pop\nlo-fi Cumbia\nlo-fi EBM\nlo-fi EBM industrial\nlo-fi EDM\nlo-fi EDM-pop\nlo-fi Filipino pop-rock\nlo-fi French\nlo-fi French cloud rap\nlo-fi French cloud rap, drill trap\nlo-fi French indie\nlo-fi French pop\nlo-fi French pop funk-rock\nlo-fi French rap\nlo-fi French synth\nlo-fi French trap\nlo-fi G-funk\nlo-fi German pop\nlo-fi German trap\nlo-fi Greek folk\nlo-fi Hindi\nlo-fi IDM\nlo-fi Indian classical\nlo-fi Indian folk\nlo-fi Indian fusion\nlo-fi Indian pop\nlo-fi Italian ballad\nlo-fi J-Pop\nlo-fi J-R&B\nlo-fi J-pop\nlo-fi J-pop artcore\nlo-fi J-pop future bass\nlo-fi J-rock\nlo-fi K-R&B\nlo-fi K-ballad\nlo-fi K-pop\nlo-fi K-pop ballad\nlo-fi K-pop neo-soul\nlo-fi Latin\nlo-fi Latin R&B\nlo-fi Latin bolero\nlo-fi Latin dance\nlo-fi Latin folk\nlo-fi Latin funk\nlo-fi Latin fusion\nlo-fi Latin groove\nlo-fi Latin hip-hop\nlo-fi Latin indie\nlo-fi Latin indie-pop\nlo-fi Latin pop\nlo-fi Latin pop reggaeton\nlo-fi Latin pop, trap\nlo-fi Latin pop-rock\nlo-fi Latin rock\nlo-fi Latin salsa\nlo-fi Latin trap\nlo-fi MPB\nlo-fi Mandopop\nlo-fi Mandopop R&B\nlo-fi Memphis rap\nlo-fi Neue Deutsche Welle\nlo-fi Persian\nlo-fi Persian hip hop\nlo-fi Persian pop\nlo-fi Persian rap\nlo-fi Punjabi\nlo-fi Punjabi pop\nlo-fi R&B\nlo-fi R&B Afrobeats\nlo-fi R&B Bollywood fusion\nlo-fi R&B Bossa Nova\nlo-fi R&B C-pop\nlo-fi R&B French hip-hop\nlo-fi R&B Indian pop\nlo-fi R&B Mandopop\nlo-fi R&B Punjabi pop\nlo-fi R&B afrobeat\nlo-fi R&B bedroom pop\nlo-fi R&B chillhop\nlo-fi R&B chillwave\nlo-fi R&B chiptune\nlo-fi R&B city pop\nlo-fi R&B dream pop\nlo-fi R&B emo rap\nlo-fi R&B emo-rap\nlo-fi R&B funk-pop\nlo-fi R&B future bass\nlo-fi R&B glitch-hop\nlo-fi R&B hip-hop\nlo-fi R&B indie pop\nlo-fi R&B indie rock\nlo-fi R&B indie-folk\nlo-fi R&B indie-pop\nlo-fi R&B jazz-hop\nlo-fi R&B neo-soul\nlo-fi R&B pop\nlo-fi R&B pop-rock\nlo-fi R&B reggaeton\nlo-fi R&B trap\nlo-fi R&B trap-soul\nlo-fi R&B vaporwave\nlo-fi R&B, Brazilian funk\nlo-fi R&B, Brazilian pop\nlo-fi R&B, Brazilian trap\nlo-fi R&B, C-pop\nlo-fi R&B, C-pop, trap\nlo-fi R&B, Cantopop, 90s vibe\nlo-fi R&B, Chinese hip-hop, cinematic pop\nlo-fi R&B, Christmas pop\nlo-fi R&B, Indian pop\nlo-fi R&B, K-hip-hop\nlo-fi R&B, K-pop\nlo-fi R&B, K-pop ballad\nlo-fi R&B, Latin R&B, pop-reggaeton\nlo-fi R&B, Latin pop\nlo-fi R&B, Latin pop, flamenco\nlo-fi R&B, Latin pop, reggaeton\nlo-fi R&B, Latin trap\nlo-fi R&B, Mandopop\nlo-fi R&B, Mandopop, trap\nlo-fi R&B, Thai pop\nlo-fi R&B, UK garage\nlo-fi R&B, V-Pop\nlo-fi R&B, V-Pop, hip-hop\nlo-fi R&B, ambient hip-hop\nlo-fi R&B, ambient, neo-classical\nlo-fi R&B, bedroom pop\nlo-fi R&B, bedroom pop, C-pop\nlo-fi R&B, bedroom pop, V-Pop\nlo-fi R&B, bilingual hip-hop\nlo-fi R&B, boom-bap hip-hop\nlo-fi R&B, breakcore\nlo-fi R&B, chill pop\nlo-fi R&B, chillhop, Mandopop\nlo-fi R&B, chillwave\nlo-fi R&B, chillwave, Mandopop\nlo-fi R&B, chillwave, V-Pop\nlo-fi R&B, chillwave, alternative R&B\nlo-fi R&B, chillwave, reggaeton\nlo-fi R&B, chillwave, vaporwave\nlo-fi R&B, chiptune, Mandopop\nlo-fi R&B, cinematic hip-hop\nlo-fi R&B, city pop, Indonesian pop\nlo-fi R&B, city pop, Mandopop\nlo-fi R&B, cloud rap, emo trap\nlo-fi R&B, cloud rap, vaporwave\nlo-fi R&B, dancehall, afrobeat\nlo-fi R&B, deep house, Brazilian pop\nlo-fi R&B, deep house, dream pop\nlo-fi R&B, dream pop, reggaeton\nlo-fi R&B, dream-pop\nlo-fi R&B, emo-rap\nlo-fi R&B, emotional pop, trap\nlo-fi R&B, future bass\nlo-fi R&B, future bass, hip-hop\nlo-fi R&B, future bass, kawaii bass\nlo-fi R&B, future bass, pop-R&B\nlo-fi R&B, gospel hip-hop\nlo-fi R&B, hip-hop\nlo-fi R&B, hip-hop, C-pop\nlo-fi R&B, hip-hop, bedroom-pop\nlo-fi R&B, hyperpop\nlo-fi R&B, hyperpop, Thai pop\nlo-fi R&B, hyperpop, cinematic\nlo-fi R&B, indie rock\nlo-fi R&B, indie-pop\nlo-fi R&B, industrial, K-pop\nlo-fi R&B, jazz, Thai pop\nlo-fi R&B, lo-fi hip-hop\nlo-fi R&B, math-rock\nlo-fi R&B, mathcore\nlo-fi R&B, modern trap\nlo-fi R&B, neo-soul\nlo-fi R&B, neo-soul, K-R&B\nlo-fi R&B, neo-soul, V-Pop\nlo-fi R&B, neurofunk\nlo-fi R&B, pop-rock\nlo-fi R&B, pop-rock, hip-hop\nlo-fi R&B, reggaeton\nlo-fi R&B, reggaeton, trap\nlo-fi R&B, sad trap\nlo-fi R&B, shoegaze rock\nlo-fi R&B, synth-pop, K-pop\nlo-fi R&B, trap\nlo-fi R&B, trap R&B\nlo-fi R&B, trap R&B, pop-reggaeton\nlo-fi R&B, trap soul, Mandopop\nlo-fi R&B, trap, Hindi hip-hop\nlo-fi R&B, trap, Latin hip-hop\nlo-fi R&B, trap, Mandopop\nlo-fi R&B, trap, Mongolian hip hop\nlo-fi R&B, trap, Vietnamese soul\nlo-fi R&B, trap, bilingual hip-hop\nlo-fi R&B, trap, future bass\nlo-fi R&B, trap, pop\nlo-fi R&B, trap, pop-rap\nlo-fi R&B, trap-soul\nlo-fi R&B, trap-soul, C-pop\nlo-fi R&B, vaporwave\nlo-fi R&B, vaporwave, Brazilian pop\nlo-fi R&B-pop\nlo-fi RPG\nlo-fi Southern hip-hop\nlo-fi Tamil pop\nlo-fi Thai pop\nlo-fi Turkish pop\nlo-fi Turkish pop-rock\nlo-fi Turkish pop-trap\nlo-fi UK drill\nlo-fi UK garage\nlo-fi UK hip hop\nlo-fi UK hip-hop\nlo-fi UK rap\nlo-fi V-Pop\nlo-fi V-pop\nlo-fi Vietnamese ballad\nlo-fi Vietnamese pop\nlo-fi Vietnamese pop-R&B\nlo-fi Vietnamese pop-rap\nlo-fi a cappella\nlo-fi acapella\nlo-fi acoustic\nlo-fi acoustic R&B\nlo-fi acoustic ballad\nlo-fi acoustic blues\nlo-fi acoustic comedy\nlo-fi acoustic emo-rock\nlo-fi acoustic folk\nlo-fi acoustic hip-hop\nlo-fi acoustic pop\nlo-fi acoustic pop emo rap\nlo-fi acoustic pop-punk\nlo-fi acoustic punk\nlo-fi acoustic rap\nlo-fi acoustic rock\nlo-fi acoustic, boogie-woogie, jazz rock\nlo-fi acoustic, future bass, trap\nlo-fi afro-fusion\nlo-fi afro-trap\nlo-fi afrobeat\nlo-fi afrobeat-pop\nlo-fi afrobeats\nlo-fi afrobeats pop\nlo-fi alt-country\nlo-fi alt-pop\nlo-fi alt-rock\nlo-fi alternative R&B\nlo-fi alternative rock\nlo-fi ambient\nlo-fi ambient pop\nlo-fi ambient trap\nlo-fi anime\nlo-fi anime rock\nlo-fi anthem\nlo-fi anti-folk\nlo-fi anti-folk punk rock\nlo-fi arabic\nlo-fi arabic pop\nlo-fi arabic soul\nlo-fi art rock\nlo-fi art-pop\nlo-fi art-rock\nlo-fi art-rock punk\nlo-fi baile funk\nlo-fi ballad\nlo-fi ballad, Filipino pop, blues-rock\nlo-fi ballad, Latin pop-rock\nlo-fi ballad, Latin rock\nlo-fi ballad, reggaeton, latin pop\nlo-fi bass\nlo-fi beach\nlo-fi beat\nlo-fi beat, Brazilian percussion\nlo-fi beatbox\nlo-fi bedroom R&B\nlo-fi bedroom pop\nlo-fi bedroom pop, future bass\nlo-fi bedroom pop, hyperpop, ambient\nlo-fi bedroom pop, hyperpop, emo-rap\nlo-fi bedroom pop, shoegaze, dream pop\nlo-fi bedroom pop, synth-pop\nlo-fi bedroom pop, trap R&B\nlo-fi bhajan\nlo-fi big band\nlo-fi blues\nlo-fi blues rock\nlo-fi blues-folk\nlo-fi blues-rock\nlo-fi blues-rock trap\nlo-fi bolero\nlo-fi boogie-woogie\nlo-fi boom bap\nlo-fi boom-bap\nlo-fi boom-bap, C-pop\nlo-fi boom-bap, Latin jazz\nlo-fi boom-bap, Latin soul\nlo-fi boom-bap, R&B\nlo-fi boom-bap, Russian hip hop\nlo-fi boom-bap, cinematic hip hop\nlo-fi boom-bap, cloud rap\nlo-fi boom-bap, emo-rap\nlo-fi boom-bap, industrial rock\nlo-fi boom-bap, neo-soul\nlo-fi boom-bap, rap-rock\nlo-fi boom-bap, trap\nlo-fi boom-bap, trap R&B\nlo-fi boom-bap, trap-soul\nlo-fi bossa nova\nlo-fi bossa nova reggaeton\nlo-fi bossa nova, samba-pop, trap-rap, dreamy R&B\nlo-fi bossa nova, trap\nlo-fi brass\nlo-fi breakbeat\nlo-fi breakcore\nlo-fi brega funk\nlo-fi cabaret\nlo-fi cafe music\nlo-fi cartoon\nlo-fi chamber\nlo-fi chamber music\nlo-fi chanson\nlo-fi chanson, cabaret pop\nlo-fi chant\nlo-fi children's\nlo-fi children's music\nlo-fi children's music, eurodance\nlo-fi children's pop\nlo-fi chill\nlo-fi chill house\nlo-fi chill trap\nlo-fi chill-out\nlo-fi chill-pop\nlo-fi chillhop\nlo-fi chillhop future bass\nlo-fi chillhop, J-core\nlo-fi chillhop, R&B, future bass\nlo-fi chillhop, synthwave\nlo-fi chillout\nlo-fi chillwave\nlo-fi chillwave K-R&B\nlo-fi chillwave future bass\nlo-fi chillwave reggaeton\nlo-fi chillwave trap\nlo-fi chillwave, baile funk\nlo-fi chillwave, cloud rap, emo rap\nlo-fi chillwave, pop-R&B\nlo-fi chillwave, pop-rock\nlo-fi chime\nlo-fi chiptune\nlo-fi chiptune C-pop\nlo-fi chiptune J-pop\nlo-fi chiptune Mandopop\nlo-fi chiptune R&B\nlo-fi chiptune V-pop\nlo-fi chiptune alternative rock\nlo-fi chiptune breakcore\nlo-fi chiptune dembow\nlo-fi chiptune drill\nlo-fi chiptune funk\nlo-fi chiptune fusion\nlo-fi chiptune future bass\nlo-fi chiptune hip hop\nlo-fi chiptune hip-hop\nlo-fi chiptune indie electronic\nlo-fi chiptune indie rock\nlo-fi chiptune neo-soul\nlo-fi chiptune pop\nlo-fi chiptune pop-punk\nlo-fi chiptune pop-rock\nlo-fi chiptune protest\nlo-fi chiptune punk rock\nlo-fi chiptune rap\nlo-fi chiptune reggae\nlo-fi chiptune reggaeton\nlo-fi chiptune synth-pop\nlo-fi chiptune techno\nlo-fi chiptune trap\nlo-fi chiptune trap-R&B\nlo-fi chiptune trip-hop\nlo-fi chiptune, 8-bit punk, Neue Deutsche Welle\nlo-fi chiptune, 90s hip-hop\nlo-fi chiptune, Brazilian funk carioca\nlo-fi chiptune, Brazilian trap\nlo-fi chiptune, C-pop, hip-hop\nlo-fi chiptune, G-funk, hip-hop\nlo-fi chiptune, Hindi pop, electronic rock\nlo-fi chiptune, J-rock\nlo-fi chiptune, J-rock, anime rock\nlo-fi chiptune, J-rock, funk\nlo-fi chiptune, Latin pop, dream pop\nlo-fi chiptune, Latin pop, reggaeton\nlo-fi chiptune, Latin pop-rock, cinematic\nlo-fi chiptune, alternative rock, J-rock\nlo-fi chiptune, breakcore, drum and bass\nlo-fi chiptune, dubstep, ambient\nlo-fi chiptune, electro-rock\nlo-fi chiptune, flamenco rock\nlo-fi chiptune, future bass, R&B\nlo-fi chiptune, neo-soul, French pop\nlo-fi chiptune, neo-soul, hip-hop\nlo-fi chiptune, noise rock\nlo-fi chiptune, pop-punk, indie-pop\nlo-fi chiptune, progressive metalcore\nlo-fi chiptune, reggaeton, hyperpop\nlo-fi chiptune, thrash metal\nlo-fi chiptune, trap metal, hyperpop\nlo-fi chiptune, trap, pop-trap\nlo-fi chiptune, trap, reggaeton\nlo-fi chiptune-punk\nlo-fi chiptune-trap\nlo-fi choral\nlo-fi christmas\nlo-fi cinematic\nlo-fi circus\nlo-fi city pop\nlo-fi city pop trap\nlo-fi city pop, trap, cloud rap\nlo-fi city-pop\nlo-fi classical\nlo-fi classical trap\nlo-fi cloud rap\nlo-fi comedy\nlo-fi comedy rap\nlo-fi comedy rock\nlo-fi complextro\nlo-fi country\nlo-fi country blues\nlo-fi country folk\nlo-fi country rock\nlo-fi country-blues\nlo-fi country-folk\nlo-fi country-pop\nlo-fi cumbia\nlo-fi cumbia future bass\nlo-fi cumbia hip-hop\nlo-fi cumbia rap\nlo-fi cumbia ska\nlo-fi cumbia trap\nlo-fi cumbia villera\nlo-fi cumbia-pop\nlo-fi cumbia-rap\nlo-fi cumbia-reggaeton\nlo-fi cumbia-trap\nlo-fi dance\nlo-fi dance pop\nlo-fi dance-pop\nlo-fi dancehall\nlo-fi dancehall-pop\nlo-fi dark pop\nlo-fi deep house\nlo-fi dembow\nlo-fi devotional\nlo-fi devotional Indian\nlo-fi digital cumbia\nlo-fi digital cumbia trap\nlo-fi digital metal\nlo-fi digital noise\nlo-fi digital punk\nlo-fi digital rock\nlo-fi dnb\nlo-fi doo-wop\nlo-fi downtempo\nlo-fi dream pop\nlo-fi dream-pop\nlo-fi drill\nlo-fi drum\nlo-fi drum & bass\nlo-fi drum and bass\nlo-fi drum break\nlo-fi drum loop\nlo-fi drum machine\nlo-fi dub\nlo-fi dub reggae\nlo-fi dubstep\nlo-fi educational\nlo-fi electro\nlo-fi electro house\nlo-fi electro-funk\nlo-fi electro-pop\nlo-fi electro-punk\nlo-fi electro-punk indie-pop psychedelic rock\nlo-fi electro-rap\nlo-fi electro-swing\nlo-fi electroclash\nlo-fi electronic\nlo-fi electronic R&B\nlo-fi electronic alternative rock\nlo-fi electronic bossa nova\nlo-fi electronic chiptune\nlo-fi electronic cumbia\nlo-fi electronic future bass\nlo-fi electronic pop\nlo-fi electronic rock\nlo-fi electronic, Indian classical, ambient\nlo-fi electronic, Indian devotional, Carnatic fusion\nlo-fi electronic, Indian devotional, ambient\nlo-fi electronic, Indian folk, melancholic\nlo-fi electronic, Korean folk\nlo-fi electronic, South Asian folk\nlo-fi electronic, ambient, Persian pop\nlo-fi electronic, breakcore, gabber\nlo-fi electronic, chillwave, synth-pop\nlo-fi electronic, chiptune, hyperpop\nlo-fi electronic, hyperpop, ambient\nlo-fi electronic, hyperpop, chiptune\nlo-fi electronic, hyperpop, gabber\nlo-fi electronic, industrial hip hop\nlo-fi electronic, world music, Angolan\nlo-fi electronica\nlo-fi electropop\nlo-fi emo\nlo-fi emo R&B\nlo-fi emo rap\nlo-fi emo rap, hyperpop, trap\nlo-fi emo rock\nlo-fi emo trap\nlo-fi emo-pop\nlo-fi emo-punk\nlo-fi emo-rap\nlo-fi emo-rap, mathcore\nlo-fi emo-rock\nlo-fi emo-trap\nlo-fi emotional trap\nlo-fi epic\nlo-fi ethereal\nlo-fi eurodance\nlo-fi experimental\nlo-fi experimental hip-hop\nlo-fi experimental pop\nlo-fi fairytale\nlo-fi fanfare\nlo-fi fantasy\nlo-fi field recording\nlo-fi filmi\nlo-fi fingerstyle\nlo-fi flamenco\nlo-fi flute\nlo-fi folk\nlo-fi folk comedy\nlo-fi folk fusion\nlo-fi folk garage rock\nlo-fi folk gospel\nlo-fi folk indie rock\nlo-fi folk metal\nlo-fi folk pop\nlo-fi folk protest\nlo-fi folk punk\nlo-fi folk rock\nlo-fi folk rumba\nlo-fi folk trap\nlo-fi folk trap-r&b\nlo-fi folk, eurodance\nlo-fi folk, novelty rock\nlo-fi folk, post-rock\nlo-fi folk, shoegaze, noise rock\nlo-fi folk, thrash metal\nlo-fi folk-blues\nlo-fi folk-pop\nlo-fi folk-punk\nlo-fi folk-punk garage rock\nlo-fi folk-rock\nlo-fi folk-rock, industrial electronic\nlo-fi funk\nlo-fi funk carioca\nlo-fi funk experimental hip-hop\nlo-fi funk fusion\nlo-fi funk future bass\nlo-fi funk garage punk\nlo-fi funk indie rock\nlo-fi funk jazz\nlo-fi funk rap\nlo-fi funk rock\nlo-fi funk samba-rock\nlo-fi funk soul\nlo-fi funk-hop\nlo-fi funk-pop\nlo-fi funk-rap\nlo-fi funk-rock\nlo-fi funk-rock punk\nlo-fi fusion\nlo-fi future bass\nlo-fi future funk\nlo-fi future garage\nlo-fi game music\nlo-fi gangsta rap\nlo-fi garage punk\nlo-fi garage rock\nlo-fi garage rock, new wave\nlo-fi ghazal\nlo-fi glitch\nlo-fi glitch-hop\nlo-fi gospel\nlo-fi gospel rap\nlo-fi gothic Americana\nlo-fi grime\nlo-fi groove\nlo-fi grunge\nlo-fi guitar\nlo-fi guzheng\nlo-fi harp\nlo-fi harp, neo-soul, indie pop\nlo-fi harpsichord\nlo-fi hip hop\nlo-fi hip hop Afro-fusion\nlo-fi hip hop Bollywood\nlo-fi hip hop C-R&B\nlo-fi hip hop C-pop\nlo-fi hip hop Indian\nlo-fi hip hop Indian classical\nlo-fi hip hop Indian film music\nlo-fi hip hop Indian folk\nlo-fi hip hop Indian pop\nlo-fi hip hop J-pop\nlo-fi hip hop MPB\nlo-fi hip hop R&B\nlo-fi hip hop acid jazz\nlo-fi hip hop acoustic pop\nlo-fi hip hop afro-fusion\nlo-fi hip hop afrobeat\nlo-fi hip hop afrobeats\nlo-fi hip hop alternative hip hop\nlo-fi hip hop alternative rock\nlo-fi hip hop ambient\nlo-fi hip hop ambient R&B\nlo-fi hip hop ambient pop\nlo-fi hip hop anime\nlo-fi hip hop boom-bap\nlo-fi hip hop bossa nova\nlo-fi hip hop chill R&B\nlo-fi hip hop chillhop\nlo-fi hip hop chillwave\nlo-fi hip hop chiptune\nlo-fi hip hop cinematic\nlo-fi hip hop country-rap\nlo-fi hip hop cumbia\nlo-fi hip hop deep house\nlo-fi hip hop dembow\nlo-fi hip hop dream pop\nlo-fi hip hop dream-pop\nlo-fi hip hop electro-swing\nlo-fi hip hop emo\nlo-fi hip hop emo rap\nlo-fi hip hop emo-rap\nlo-fi hip hop emo-rock\nlo-fi hip hop emotional trap\nlo-fi hip hop experimental\nlo-fi hip hop funk\nlo-fi hip hop funk rock\nlo-fi hip hop funk soul\nlo-fi hip hop future bass\nlo-fi hip hop glitch hop\nlo-fi hip hop glitch-hop\nlo-fi hip hop gospel\nlo-fi hip hop grime\nlo-fi hip hop horrorcore\nlo-fi hip hop indie pop\nlo-fi hip hop indie rock\nlo-fi hip hop indie-pop\nlo-fi hip hop industrial\nlo-fi hip hop industrial techno\nlo-fi hip hop industrial trap\nlo-fi hip hop jazz\nlo-fi hip hop jazz rap\nlo-fi hip hop jazz-hop\nlo-fi hip hop jazz-rap\nlo-fi hip hop math-rock\nlo-fi hip hop neo-soul\nlo-fi hip hop noir\nlo-fi hip hop nu-disco\nlo-fi hip hop nu-jazz\nlo-fi hip hop nu-metal\nlo-fi hip hop orchestral\nlo-fi hip hop pop\nlo-fi hip hop pop-punk\nlo-fi hip hop pop-rap\nlo-fi hip hop pop-rock\nlo-fi hip hop protest\nlo-fi hip hop punk\nlo-fi hip hop reggae\nlo-fi hip hop reggaeton\nlo-fi hip hop rock\nlo-fi hip hop samba\nlo-fi hip hop sentimental\nlo-fi hip hop shoegaze\nlo-fi hip hop soul\nlo-fi hip hop synthwave\nlo-fi hip hop tango\nlo-fi hip hop trap\nlo-fi hip hop trap C-pop\nlo-fi hip hop trap dream pop\nlo-fi hip hop trap-pop\nlo-fi hip hop vaporwave\nlo-fi hip hop world music\nlo-fi hip hop, 90s R&B\nlo-fi hip hop, 90s R&B, K-pop\nlo-fi hip hop, Afro-soul, R&B\nlo-fi hip hop, Afro-trap\nlo-fi hip hop, Anatolian folk\nlo-fi hip hop, Anatolian folk, downtempo\nlo-fi hip hop, Andalusian rap\nlo-fi hip hop, Arabic ambient\nlo-fi hip hop, Arabic drill\nlo-fi hip hop, Arabic folk, Balkan folk\nlo-fi hip hop, Arabic fusion\nlo-fi hip hop, Arabic fusion, boom-bap\nlo-fi hip hop, Arabic hip hop\nlo-fi hip hop, Arabic hip hop, cinematic\nlo-fi hip hop, Arabic hip-hop\nlo-fi hip hop, Arabic jazz\nlo-fi hip hop, Arabic melodic\nlo-fi hip hop, Arabic pop\nlo-fi hip hop, Arabic pop, French rap\nlo-fi hip hop, Arabic pop, indie pop\nlo-fi hip hop, Arabic pop, sad rap\nlo-fi hip hop, Arabic rap\nlo-fi hip hop, Arabic rap, boom-bap\nlo-fi hip hop, Arabic rap, cinematic\nlo-fi hip hop, Arabic rap, psychedelic rock\nlo-fi hip hop, Arabic rap, rock\nlo-fi hip hop, Arabic rap, soulful\nlo-fi hip hop, Arabic rock\nlo-fi hip hop, Arabic soul\nlo-fi hip hop, Arabic trap\nlo-fi hip hop, Azerbaijani rap\nlo-fi hip hop, Balkan brass\nlo-fi hip hop, Balkan trap\nlo-fi hip hop, Bengali rap\nlo-fi hip hop, Bhangra, Desi hip-hop\nlo-fi hip hop, Bollywood\nlo-fi hip hop, Bollywood fusion\nlo-fi hip hop, Bollywood, ambient\nlo-fi hip hop, Bollywood, chillwave\nlo-fi hip hop, Bossa Nova\nlo-fi hip hop, Bossa Nova, trap\nlo-fi hip hop, Brazilian\nlo-fi hip hop, Brazilian Funk\nlo-fi hip hop, Brazilian R&B\nlo-fi hip hop, Brazilian conscious hip-hop\nlo-fi hip hop, Brazilian funk\nlo-fi hip hop, Brazilian funk, auto-tune pop\nlo-fi hip hop, Brazilian funk, hardstyle\nlo-fi hip hop, Brazilian funk, hyperpop\nlo-fi hip hop, Brazilian funk, pop\nlo-fi hip hop, Brazilian funk, trap\nlo-fi hip hop, Brazilian funk, vaporwave\nlo-fi hip hop, Brazilian funk-trap\nlo-fi hip hop, Brazilian fusion, ambient\nlo-fi hip hop, Brazilian gangsta rap\nlo-fi hip hop, Brazilian hip hop\nlo-fi hip hop, Brazilian hip-hop\nlo-fi hip hop, Brazilian jazz\nlo-fi hip hop, Brazilian jazz rap\nlo-fi hip hop, Brazilian pop\nlo-fi hip hop, Brazilian pop, R&B\nlo-fi hip hop, Brazilian pop, acoustic\nlo-fi hip hop, Brazilian pop, acoustic singer-songwriter\nlo-fi hip hop, Brazilian pop-rap\nlo-fi hip hop, Brazilian rap\nlo-fi hip hop, Brazilian samba\nlo-fi hip hop, Brazilian trap\nlo-fi hip hop, Brazilian trap, boom-bap\nlo-fi hip hop, C-pop\nlo-fi hip hop, C-pop ballad\nlo-fi hip hop, C-pop rap\nlo-fi hip hop, C-pop, 90s hip hop\nlo-fi hip hop, C-pop, J-rock\nlo-fi hip hop, C-pop, R&B\nlo-fi hip hop, C-pop, ambient\nlo-fi hip hop, C-pop, anime\nlo-fi hip hop, C-pop, bedroom pop\nlo-fi hip hop, C-pop, boom-bap\nlo-fi hip hop, C-pop, chill R&B\nlo-fi hip hop, C-pop, cinematic\nlo-fi hip hop, C-pop, dream pop\nlo-fi hip hop, C-pop, dream trap\nlo-fi hip hop, C-pop, dreamy\nlo-fi hip hop, C-pop, electronic\nlo-fi hip hop, C-pop, ethereal R&B\nlo-fi hip hop, C-pop, experimental\nlo-fi hip hop, C-pop, gospel\nlo-fi hip hop, C-pop, indie rock\nlo-fi hip hop, C-pop, jazz\nlo-fi hip hop, C-pop, kawaii\nlo-fi hip hop, C-pop, melancholic\nlo-fi hip hop, C-pop, pop-rock\nlo-fi hip hop, C-pop, rock\nlo-fi hip hop, C-pop, soul\nlo-fi hip hop, C-pop, trap\nlo-fi hip hop, C-pop, video game music\nlo-fi hip hop, Cantopop\nlo-fi hip hop, Cantopop, pop-rock\nlo-fi hip hop, Central Asian folk\nlo-fi hip hop, Central Asian, melancholic\nlo-fi hip hop, Chinese R&B\nlo-fi hip hop, Chinese ambient\nlo-fi hip hop, Chinese ambient, electronic\nlo-fi hip hop, Chinese ambient, melancholic pop\nlo-fi hip hop, Chinese boom-bap\nlo-fi hip hop, Chinese cinematic\nlo-fi hip hop, Chinese diss track\nlo-fi hip hop, Chinese electronic\nlo-fi hip hop, Chinese folk\nlo-fi hip hop, Chinese folk, jazz hop\nlo-fi hip hop, Chinese fusion\nlo-fi hip hop, Chinese fusion, trap\nlo-fi hip hop, Chinese hip hop\nlo-fi hip hop, Chinese indie\nlo-fi hip hop, Chinese jazz\nlo-fi hip hop, Chinese narrative rap\nlo-fi hip hop, Chinese opera\nlo-fi hip hop, Chinese opera, boom-bap\nlo-fi hip hop, Chinese opera, dream pop\nlo-fi hip hop, Chinese opera, synth-pop\nlo-fi hip hop, Chinese opera, trap\nlo-fi hip hop, Chinese pop\nlo-fi hip hop, Chinese rap\nlo-fi hip hop, Chinese rap, R&B\nlo-fi hip hop, Chinese rap, ambient\nlo-fi hip hop, Chinese rap, anime sample\nlo-fi hip hop, Chinese rap, boom-bap\nlo-fi hip hop, Chinese rap, experimental\nlo-fi hip hop, Chinese rap, folk fusion\nlo-fi hip hop, Chinese rap, jazz hop\nlo-fi hip hop, Chinese rap, melancholic\nlo-fi hip hop, Chinese rap, techno\nlo-fi hip hop, Chinese soul\nlo-fi hip hop, Chinese storytelling\nlo-fi hip hop, Chinese traditional\nlo-fi hip hop, Chinese traditional, West Coast\nlo-fi hip hop, Chinese traditional, ambient\nlo-fi hip hop, Chinese traditional, cinematic\nlo-fi hip hop, Chinese traditional, downtempo\nlo-fi hip hop, Chinese traditional, melancholic\nlo-fi hip hop, Chinese trap\nlo-fi hip hop, Chinese trap, R&B\nlo-fi hip hop, Chinese trap, cinematic C-pop\nlo-fi hip hop, Chinese underground\nlo-fi hip hop, Chinese-style pop\nlo-fi hip hop, Christian rap\nlo-fi hip hop, Christmas R&B\nlo-fi hip hop, Christmas pop\nlo-fi hip hop, Cuban folk\nlo-fi hip hop, Czech rap\nlo-fi hip hop, Desi hip-hop\nlo-fi hip hop, Dutch R&B\nlo-fi hip hop, Dutch hip-hop, cinematic\nlo-fi hip hop, Dutch rap\nlo-fi hip hop, Dutch rap, trap\nlo-fi hip hop, EDM\nlo-fi hip hop, EDM, Chinese hip-hop\nlo-fi hip hop, EDM, Tamil pop\nlo-fi hip hop, EDM, trap\nlo-fi hip hop, Fado\nlo-fi hip hop, Filipino R&B\nlo-fi hip hop, Filipino folk\nlo-fi hip hop, Filipino hip-hop\nlo-fi hip hop, Filipino indie\nlo-fi hip hop, Filipino pop\nlo-fi hip hop, Filipino pop-rap\nlo-fi hip hop, Filipino soul, blues rock\nlo-fi hip hop, Filipino trap\nlo-fi hip hop, French R&B, jazz hop\nlo-fi hip hop, French R&B, neo-soul\nlo-fi hip hop, French chanson\nlo-fi hip hop, French cloud rap\nlo-fi hip hop, French cloud rap, chillwave\nlo-fi hip hop, French conscious rap\nlo-fi hip hop, French drill\nlo-fi hip hop, French hip-hop\nlo-fi hip hop, French pop-rap\nlo-fi hip hop, French pop-rap, dream pop\nlo-fi hip hop, French rap\nlo-fi hip hop, French rap, R&B\nlo-fi hip hop, French rap, Spanish guitar\nlo-fi hip hop, French rap, acoustic\nlo-fi hip hop, French rap, afro-trap\nlo-fi hip hop, French rap, boom-bap\nlo-fi hip hop, French rap, cinematic\nlo-fi hip hop, French rap, ethereal pop\nlo-fi hip hop, French rap, indie pop\nlo-fi hip hop, French rap, industrial trap\nlo-fi hip hop, French rap, jazz hop\nlo-fi hip hop, French rap, rock fusion\nlo-fi hip hop, French rap, soul jazz\nlo-fi hip hop, French rap, trap\nlo-fi hip hop, French rap, trap R&B\nlo-fi hip hop, French rap, world fusion\nlo-fi hip hop, French rap, zouk\nlo-fi hip hop, French trap\nlo-fi hip hop, French trap, cyberpunk\nlo-fi hip hop, G-funk\nlo-fi hip hop, G-funk, cinematic\nlo-fi hip hop, G-funk, soul\nlo-fi hip hop, G-funk, trap\nlo-fi hip hop, G-funk, vaporwave\nlo-fi hip hop, Galician rap\nlo-fi hip hop, Galician rap, Basque hip hop\nlo-fi hip hop, German R&B\nlo-fi hip hop, German cloud rap\nlo-fi hip hop, German conscious hip-hop\nlo-fi hip hop, German party-rap\nlo-fi hip hop, German rap\nlo-fi hip hop, German rap, cinematic\nlo-fi hip hop, German rap, world music\nlo-fi hip hop, German trap\nlo-fi hip hop, German trap, ethereal pop\nlo-fi hip hop, Greek rap\nlo-fi hip hop, Greek trap\nlo-fi hip hop, Haitian Creole rap\nlo-fi hip hop, Hebrew rap\nlo-fi hip hop, Hebrew rap, rock fusion\nlo-fi hip hop, Hebrew soul\nlo-fi hip hop, Hindi R&B, trap\nlo-fi hip hop, Hindi pop, romantic\nlo-fi hip hop, Hungarian hip hop\nlo-fi hip hop, IDM, ambient\nlo-fi hip hop, Indian ambient\nlo-fi hip hop, Indian cinematic\nlo-fi hip hop, Indian classical\nlo-fi hip hop, Indian classical, emotional pop\nlo-fi hip hop, Indian classical, melancholic\nlo-fi hip hop, Indian classical, trap\nlo-fi hip hop, Indian cloud rap\nlo-fi hip hop, Indian devotional\nlo-fi hip hop, Indian film music\nlo-fi hip hop, Indian folk\nlo-fi hip hop, Indian folk, cinematic\nlo-fi hip hop, Indian fusion\nlo-fi hip hop, Indian ghazal\nlo-fi hip hop, Indian hip hop\nlo-fi hip hop, Indian pop\nlo-fi hip hop, Indian pop, R&B\nlo-fi hip hop, Indian pop, melancholic\nlo-fi hip hop, Indian pop, trap\nlo-fi hip hop, Indian vocal, atmospheric\nlo-fi hip hop, Indonesian pop\nlo-fi hip hop, Indonesian rap, vaporwave\nlo-fi hip hop, Italian folk\nlo-fi hip hop, Italian indie\nlo-fi hip hop, Italian pop\nlo-fi hip hop, Italian pop-rap\nlo-fi hip hop, Italian rap\nlo-fi hip hop, J-R&B\nlo-fi hip hop, J-Rap\nlo-fi hip hop, J-Rock\nlo-fi hip hop, J-hip-hop\nlo-fi hip hop, J-pop\nlo-fi hip hop, J-pop, K-pop\nlo-fi hip hop, J-pop, R&B\nlo-fi hip hop, J-pop, chiptune\nlo-fi hip hop, J-pop, cinematic\nlo-fi hip hop, J-pop, rock\nlo-fi hip hop, J-pop, vaporwave\nlo-fi hip hop, J-rap\nlo-fi hip hop, J-rock\nlo-fi hip hop, J-rock, cinematic\nlo-fi hip hop, J-rock, electronic\nlo-fi hip hop, Japanese R&B\nlo-fi hip hop, Japanese rap\nlo-fi hip hop, Japanese rock\nlo-fi hip hop, Javanese fusion\nlo-fi hip hop, K-R&B\nlo-fi hip hop, K-R&B, chiptune\nlo-fi hip hop, K-R&B, city pop\nlo-fi hip hop, K-R&B, neo-soul\nlo-fi hip hop, K-R&B, trap\nlo-fi hip hop, K-hip-hop\nlo-fi hip hop, K-hip-hop, indie pop\nlo-fi hip hop, K-indie, bedroom pop\nlo-fi hip hop, K-pop\nlo-fi hip hop, K-pop ballad\nlo-fi hip hop, K-pop, Chinese rap\nlo-fi hip hop, K-pop, Eurodance\nlo-fi hip hop, K-pop, J-pop\nlo-fi hip hop, K-pop, R&B\nlo-fi hip hop, K-pop, electronic\nlo-fi hip hop, K-pop, funk\nlo-fi hip hop, K-pop, trap\nlo-fi hip hop, K-pop, vaporwave\nlo-fi hip hop, K-rap, boom-bap\nlo-fi hip hop, Kazakh rap\nlo-fi hip hop, Khmer rap\nlo-fi hip hop, Korean R&B\nlo-fi hip hop, Korean R&B, dream pop\nlo-fi hip hop, Korean hip hop, cinematic\nlo-fi hip hop, Korean rap\nlo-fi hip hop, Korean rap, melodic rap\nlo-fi hip hop, Korean trap\nlo-fi hip hop, Latin R&B\nlo-fi hip hop, Latin R&B, bedroom pop\nlo-fi hip hop, Latin R&B, dancehall\nlo-fi hip hop, Latin R&B, reggaeton\nlo-fi hip hop, Latin R&B, sad trap\nlo-fi hip hop, Latin alternative pop\nlo-fi hip hop, Latin bolero\nlo-fi hip hop, Latin drill\nlo-fi hip hop, Latin electronic, moombahton\nlo-fi hip hop, Latin folk, psychedelic\nlo-fi hip hop, Latin funk\nlo-fi hip hop, Latin hip hop\nlo-fi hip hop, Latin hip-hop\nlo-fi hip hop, Latin hip-hop, pop-rap\nlo-fi hip hop, Latin house\nlo-fi hip hop, Latin jazz\nlo-fi hip hop, Latin pop\nlo-fi hip hop, Latin pop, R&B\nlo-fi hip hop, Latin pop, ambient\nlo-fi hip hop, Latin pop, reggaeton\nlo-fi hip hop, Latin pop, vaporwave\nlo-fi hip hop, Latin pop-rap\nlo-fi hip hop, Latin rap\nlo-fi hip hop, Latin rap, electronic\nlo-fi hip hop, Latin singer-songwriter\nlo-fi hip hop, Latin soul\nlo-fi hip hop, Latin trap\nlo-fi hip hop, Latin trap, R&B\nlo-fi hip hop, Latin trap, sad rap\nlo-fi hip hop, Latin trap-soul\nlo-fi hip hop, Latin urban, bedroom pop\nlo-fi hip hop, MPB\nlo-fi hip hop, MPB, bossa nova\nlo-fi hip hop, MPB, neo-soul\nlo-fi hip hop, Malayalam rap\nlo-fi hip hop, Mandarin R&B\nlo-fi hip hop, Mandarin hip hop\nlo-fi hip hop, Mandarin pop\nlo-fi hip hop, Mandarin pop-rap\nlo-fi hip hop, Mandarin rap\nlo-fi hip hop, Mandarin soul\nlo-fi hip hop, Mandarin trap\nlo-fi hip hop, Mandopop\nlo-fi hip hop, Mandopop R&B\nlo-fi hip hop, Mandopop, R&B\nlo-fi hip hop, Mandopop, chillhop\nlo-fi hip hop, Mandopop, chillwave\nlo-fi hip hop, Mandopop, cinematic\nlo-fi hip hop, Mandopop, dream pop\nlo-fi hip hop, Mandopop, emo rap\nlo-fi hip hop, Mandopop, melancholic R&B\nlo-fi hip hop, Mandopop, trap\nlo-fi hip hop, Memphis rap\nlo-fi hip hop, Memphis rap, pop\nlo-fi hip hop, Middle Eastern\nlo-fi hip hop, Middle Eastern fusion\nlo-fi hip hop, Middle Eastern, cinematic\nlo-fi hip hop, Mongolian folk\nlo-fi hip hop, Mongolian rap\nlo-fi hip hop, Moroccan rap\nlo-fi hip hop, Nederhop\nlo-fi hip hop, Nepali folk, boom-bap\nlo-fi hip hop, Nepali pop\nlo-fi hip hop, Nepali pop-rap\nlo-fi hip hop, Nepali rap\nlo-fi hip hop, North African fusion\nlo-fi hip hop, Persian ambient\nlo-fi hip hop, Persian cinematic\nlo-fi hip hop, Persian fusion\nlo-fi hip hop, Persian hip-hop, Latin fusion\nlo-fi hip hop, Persian indie, experimental rock\nlo-fi hip hop, Persian pop\nlo-fi hip hop, Persian rap\nlo-fi hip hop, Persian rap, cinematic\nlo-fi hip hop, Persian soul\nlo-fi hip hop, Polish conscious rap\nlo-fi hip hop, Polish rap\nlo-fi hip hop, Portuguese R&B\nlo-fi hip hop, Portuguese rap, emotional piano\nlo-fi hip hop, Punjabi boom-bap\nlo-fi hip hop, Punjabi folk\nlo-fi hip hop, Punjabi fusion\nlo-fi hip hop, Punjabi hip-hop\nlo-fi hip hop, Punjabi pop\nlo-fi hip hop, Punjabi pop, boom-bap\nlo-fi hip hop, Punjabi pop, indie\nlo-fi hip hop, Punjabi rap\nlo-fi hip hop, Punjabi soul\nlo-fi hip hop, Punjabi trap\nlo-fi hip hop, R&B\nlo-fi hip hop, R&B, Afro-hip hop\nlo-fi hip hop, R&B, Arabic ambient\nlo-fi hip hop, R&B, Brazilian\nlo-fi hip hop, R&B, Brazilian pop\nlo-fi hip hop, R&B, C-pop\nlo-fi hip hop, R&B, Chinese ambient\nlo-fi hip hop, R&B, Chinese hip hop\nlo-fi hip hop, R&B, Chinese hip-hop\nlo-fi hip hop, R&B, Chinese indie\nlo-fi hip hop, R&B, Chinese pop\nlo-fi hip hop, R&B, Chinese rap\nlo-fi hip hop, R&B, Chinese soul\nlo-fi hip hop, R&B, Chinese trap\nlo-fi hip hop, R&B, Chinese underground rap\nlo-fi hip hop, R&B, East Asian hip-hop\nlo-fi hip hop, R&B, Filipino pop\nlo-fi hip hop, R&B, Filipino pop-rap\nlo-fi hip hop, R&B, Filipino rap\nlo-fi hip hop, R&B, Indian ambient\nlo-fi hip hop, R&B, Indian folk\nlo-fi hip hop, R&B, Indian pop\nlo-fi hip hop, R&B, Indonesian pop\nlo-fi hip hop, R&B, Indonesian rap\nlo-fi hip hop, R&B, J-pop\nlo-fi hip hop, R&B, K-pop\nlo-fi hip hop, R&B, Kazakh pop\nlo-fi hip hop, R&B, Korean\nlo-fi hip hop, R&B, Korean rap\nlo-fi hip hop, R&B, Latin\nlo-fi hip hop, R&B, Latin groove\nlo-fi hip hop, R&B, Latin hip-hop\nlo-fi hip hop, R&B, Latin pop\nlo-fi hip hop, R&B, Mandarin pop\nlo-fi hip hop, R&B, Mandarin rap\nlo-fi hip hop, R&B, Mandopop\nlo-fi hip hop, R&B, North African pop\nlo-fi hip hop, R&B, Polish rap\nlo-fi hip hop, R&B, Punjabi pop\nlo-fi hip hop, R&B, Spanish ballad\nlo-fi hip hop, R&B, Tagalog rap\nlo-fi hip hop, R&B, Thai pop\nlo-fi hip hop, R&B, Uyghur rap\nlo-fi hip hop, R&B, V-Pop\nlo-fi hip hop, R&B, Vietnamese pop\nlo-fi hip hop, R&B, Vietnamese pop-rap\nlo-fi hip hop, R&B, Vietnamese soul\nlo-fi hip hop, R&B, acoustic pop\nlo-fi hip hop, R&B, ambient\nlo-fi hip hop, R&B, atmospheric\nlo-fi hip hop, R&B, bilingual hip hop\nlo-fi hip hop, R&B, boom-bap\nlo-fi hip hop, R&B, chill trap\nlo-fi hip hop, R&B, chillhop\nlo-fi hip hop, R&B, chillwave\nlo-fi hip hop, R&B, chiptune\nlo-fi hip hop, R&B, chopped and screwed\nlo-fi hip hop, R&B, cinematic\nlo-fi hip hop, R&B, dream pop\nlo-fi hip hop, R&B, dreamy\nlo-fi hip hop, R&B, electronic\nlo-fi hip hop, R&B, experimental\nlo-fi hip hop, R&B, future bass\nlo-fi hip hop, R&B, gospel\nlo-fi hip hop, R&B, hip hop\nlo-fi hip hop, R&B, hyperpop\nlo-fi hip hop, R&B, indie pop\nlo-fi hip hop, R&B, jazz\nlo-fi hip hop, R&B, melodic rap\nlo-fi hip hop, R&B, neo-soul\nlo-fi hip hop, R&B, pop\nlo-fi hip hop, R&B, psychedelic\nlo-fi hip hop, R&B, reggaeton\nlo-fi hip hop, R&B, rock, Arabic pop\nlo-fi hip hop, R&B, sad pop\nlo-fi hip hop, R&B, sad trap\nlo-fi hip hop, R&B, soul\nlo-fi hip hop, R&B, trap\nlo-fi hip hop, R&B, trap-soul\nlo-fi hip hop, R&B, vaporwave\nlo-fi hip hop, R&B, world music\nlo-fi hip hop, Romanian rap\nlo-fi hip hop, Russian R&B\nlo-fi hip hop, Russian choral\nlo-fi hip hop, Russian emo-rap\nlo-fi hip hop, Russian folk rap\nlo-fi hip hop, Russian hip hop\nlo-fi hip hop, Russian hip hop, Spanish hip hop\nlo-fi hip hop, Russian opera, cinematic\nlo-fi hip hop, Russian pop\nlo-fi hip hop, Russian pop-rap\nlo-fi hip hop, Russian rap\nlo-fi hip hop, Russian rap, Latin guitar\nlo-fi hip hop, Russian rap, ambient\nlo-fi hip hop, Russian rap, cinematic\nlo-fi hip hop, Russian rap, cinematic trap\nlo-fi hip hop, Russian rap, dark ambient\nlo-fi hip hop, Russian rap, experimental\nlo-fi hip hop, Russian rap, soul\nlo-fi hip hop, Russian rap, video game synth\nlo-fi hip hop, Russian underground rap\nlo-fi hip hop, Sichuanese rap\nlo-fi hip hop, Sinhala rap\nlo-fi hip hop, South Asian folk\nlo-fi hip hop, South Asian fusion\nlo-fi hip hop, South Asian fusion, romantic\nlo-fi hip hop, South Asian pop\nlo-fi hip hop, South Asian, ambient\nlo-fi hip hop, South Asian, devotional\nlo-fi hip hop, South Asian, melancholic\nlo-fi hip hop, South Indian folk\nlo-fi hip hop, South Indian, chill\nlo-fi hip hop, Southeast Asian pop\nlo-fi hip hop, Spanish R&B, indie pop\nlo-fi hip hop, Spanish ambient\nlo-fi hip hop, Spanish folk, ambient\nlo-fi hip hop, Spanish folk, boom-bap\nlo-fi hip hop, Spanish guitar, Russian rap\nlo-fi hip hop, Spanish guitar, boom-bap\nlo-fi hip hop, Spanish rap\nlo-fi hip hop, Spanish rap, cinematic\nlo-fi hip hop, Spanish rap, classical guitar\nlo-fi hip hop, Spanish rap, jazz hip hop\nlo-fi hip hop, Spanish rap, melancholic piano\nlo-fi hip hop, Spanish spoken word\nlo-fi hip hop, Swedish pop\nlo-fi hip hop, Tamil R&B\nlo-fi hip hop, Tamil hip-hop\nlo-fi hip hop, Tamil pop, acoustic\nlo-fi hip hop, Tamil pop, ambient\nlo-fi hip hop, Telugu pop\nlo-fi hip hop, Thai R&B\nlo-fi hip hop, Thai pop\nlo-fi hip hop, Turkish folk\nlo-fi hip hop, Turkish folk, ambient\nlo-fi hip hop, Turkish hip-hop\nlo-fi hip hop, Turkish pop\nlo-fi hip hop, Turkish pop, ambient\nlo-fi hip hop, Turkish rap\nlo-fi hip hop, Turkish rap, chillhop\nlo-fi hip hop, Turkish rap, cinematic\nlo-fi hip hop, Turkish rap, dreamy\nlo-fi hip hop, Turkish saz, boom-bap\nlo-fi hip hop, Turkish trap\nlo-fi hip hop, UK R&B, melodic rap\nlo-fi hip hop, UK drill\nlo-fi hip hop, UK drill, grime\nlo-fi hip hop, UK drill, jazz\nlo-fi hip hop, UK drill, vaporwave\nlo-fi hip hop, UK garage\nlo-fi hip hop, UK garage, R&B\nlo-fi hip hop, UK garage, bedroom pop\nlo-fi hip hop, UK garage, breakcore\nlo-fi hip hop, UK garage, deep house\nlo-fi hip hop, UK garage, dream pop\nlo-fi hip hop, UK garage, grime\nlo-fi hip hop, UK garage, jazz rap\nlo-fi hip hop, UK garage, vaporwave\nlo-fi hip hop, UK grime\nlo-fi hip hop, UK hardcore\nlo-fi hip hop, UK hip hop\nlo-fi hip hop, UK hip hop, soul\nlo-fi hip hop, UK hip-hop\nlo-fi hip hop, UK hip-hop, R&B\nlo-fi hip hop, UK hip-hop, atmospheric R&B\nlo-fi hip hop, UK rap\nlo-fi hip hop, UK rap, acoustic\nlo-fi hip hop, UK rap, alternative R&B\nlo-fi hip hop, UK rap, funk\nlo-fi hip hop, UK rap, jazz\nlo-fi hip hop, UK rap, soul\nlo-fi hip hop, Uyghur rap\nlo-fi hip hop, Uzbek soul\nlo-fi hip hop, V-Pop\nlo-fi hip hop, V-Pop, R&B\nlo-fi hip hop, V-Pop, chillhop\nlo-fi hip hop, V-Pop, melancholic\nlo-fi hip hop, V-pop\nlo-fi hip hop, Vietnamese R&B\nlo-fi hip hop, Vietnamese ballad\nlo-fi hip hop, Vietnamese folk\nlo-fi hip hop, Vietnamese hip-hop\nlo-fi hip hop, Vietnamese pop\nlo-fi hip hop, Vietnamese pop, rap\nlo-fi hip hop, Vietnamese rap\nlo-fi hip hop, Vietnamese soul\nlo-fi hip hop, Vocaloid, C-pop\nlo-fi hip hop, West Coast rap\nlo-fi hip hop, Wuxia, boom-bap\nlo-fi hip hop, acid jazz\nlo-fi hip hop, acoustic Mandopop\nlo-fi hip hop, acoustic ballad\nlo-fi hip hop, acoustic ballad, Indian folk\nlo-fi hip hop, acoustic pop, C-pop\nlo-fi hip hop, acoustic singer-songwriter\nlo-fi hip hop, acoustic, C-pop\nlo-fi hip hop, acoustic, bilingual\nlo-fi hip hop, acoustic, romantic\nlo-fi hip hop, afrobeat\nlo-fi hip hop, afrobeats, French pop\nlo-fi hip hop, aggressive hip hop\nlo-fi hip hop, aggressive rap, cinematic\nlo-fi hip hop, alt-rock, Italian pop\nlo-fi hip hop, alternative R&B\nlo-fi hip hop, alternative R&B, Afrobeats\nlo-fi hip hop, alternative R&B, Turkish pop\nlo-fi hip hop, alternative R&B, chillhop\nlo-fi hip hop, alternative R&B, chillwave\nlo-fi hip hop, alternative R&B, cinematic\nlo-fi hip hop, alternative R&B, cinematic trap\nlo-fi hip hop, alternative R&B, cloud rap\nlo-fi hip hop, alternative R&B, dark pop\nlo-fi hip hop, alternative R&B, glitch\nlo-fi hip hop, alternative R&B, sad pop\nlo-fi hip hop, alternative R&B, sad rap\nlo-fi hip hop, alternative R&B, trap-soul\nlo-fi hip hop, alternative hip hop, cinematic soul\nlo-fi hip hop, alternative hip-hop\nlo-fi hip hop, alternative rock\nlo-fi hip hop, alternative rock, C-pop\nlo-fi hip hop, alternative rock, chiptune\nlo-fi hip hop, alternative rock, dream pop\nlo-fi hip hop, alternative rock, neo-soul\nlo-fi hip hop, alternative rock, nu-metal\nlo-fi hip hop, alternative rock, psychedelic rock\nlo-fi hip hop, alternative rock, trap\nlo-fi hip hop, ambient\nlo-fi hip hop, ambient C-pop\nlo-fi hip hop, ambient R&B\nlo-fi hip hop, ambient drone, Spanish rap\nlo-fi hip hop, ambient electronic\nlo-fi hip hop, ambient pop\nlo-fi hip hop, ambient pop, Indian indie\nlo-fi hip hop, ambient pop, chillwave\nlo-fi hip hop, ambient pop, trip-hop\nlo-fi hip hop, ambient soul\nlo-fi hip hop, ambient techno, Portuguese ethereal\nlo-fi hip hop, ambient trap\nlo-fi hip hop, ambient, Arabic rap\nlo-fi hip hop, ambient, Arabic soul\nlo-fi hip hop, ambient, Arabic vocal\nlo-fi hip hop, ambient, C-pop\nlo-fi hip hop, ambient, Chinese ballad\nlo-fi hip hop, ambient, Chinese electronic\nlo-fi hip hop, ambient, Chinese folk\nlo-fi hip hop, ambient, Chinese indie\nlo-fi hip hop, ambient, Chinese pop\nlo-fi hip hop, ambient, Chinese rap\nlo-fi hip hop, ambient, Chinese trap\nlo-fi hip hop, ambient, German pop\nlo-fi hip hop, ambient, Indian chill\nlo-fi hip hop, ambient, Indian classical\nlo-fi hip hop, ambient, Indian melancholic\nlo-fi hip hop, ambient, Indian pop\nlo-fi hip hop, ambient, K-pop\nlo-fi hip hop, ambient, Latin pop\nlo-fi hip hop, ambient, Nordic soul\nlo-fi hip hop, ambient, R&B\nlo-fi hip hop, ambient, R&B trap\nlo-fi hip hop, ambient, Romanian rap\nlo-fi hip hop, ambient, Russian rap\nlo-fi hip hop, ambient, South Asian\nlo-fi hip hop, ambient, South Asian fusion\nlo-fi hip hop, ambient, Spanish rap\nlo-fi hip hop, ambient, bilingual\nlo-fi hip hop, ambient, cinematic\nlo-fi hip hop, ambient, dream pop\nlo-fi hip hop, ambient, electronic\nlo-fi hip hop, ambient, emo-rap\nlo-fi hip hop, ambient, emotional\nlo-fi hip hop, ambient, emotional C-pop\nlo-fi hip hop, ambient, emotional rap\nlo-fi hip hop, ambient, ethereal\nlo-fi hip hop, ambient, experimental\nlo-fi hip hop, ambient, experimental rock\nlo-fi hip hop, ambient, glitch\nlo-fi hip hop, ambient, hyperpop\nlo-fi hip hop, ambient, industrial\nlo-fi hip hop, ambient, jazz\nlo-fi hip hop, ambient, melancholic\nlo-fi hip hop, ambient, sad pop\nlo-fi hip hop, ambient, shoegaze\nlo-fi hip hop, ambient, traditional East Asian\nlo-fi hip hop, ambient, traditional South Asian\nlo-fi hip hop, ambient, trance\nlo-fi hip hop, ambient, trap\nlo-fi hip hop, ambient, world music\nlo-fi hip hop, ancient style\nlo-fi hip hop, anime rock\nlo-fi hip hop, anime, J-pop\nlo-fi hip hop, art pop\nlo-fi hip hop, art-pop, experimental hip-hop\nlo-fi hip hop, atmospheric R&B\nlo-fi hip hop, atmospheric pop\nlo-fi hip hop, auto-tune rap\nlo-fi hip hop, baile funk\nlo-fi hip hop, ballad\nlo-fi hip hop, ballad, C-pop\nlo-fi hip hop, baroque pop\nlo-fi hip hop, bebop jazz, conscious rap\nlo-fi hip hop, bedroom pop\nlo-fi hip hop, bedroom pop, Chinese rap\nlo-fi hip hop, bedroom pop, Mandopop\nlo-fi hip hop, big band swing\nlo-fi hip hop, big beat, trip-hop\nlo-fi hip hop, bilingual\nlo-fi hip hop, bilingual R&B\nlo-fi hip hop, bilingual pop\nlo-fi hip hop, bilingual rap\nlo-fi hip hop, blues rock\nlo-fi hip hop, blues-rock\nlo-fi hip hop, bolero\nlo-fi hip hop, boom-bap\nlo-fi hip hop, boom-bap, 90s East Coast\nlo-fi hip hop, boom-bap, C-pop\nlo-fi hip hop, boom-bap, Cantonese rap\nlo-fi hip hop, boom-bap, Cantopop\nlo-fi hip hop, boom-bap, Chinese hip hop\nlo-fi hip hop, boom-bap, Chinese pop\nlo-fi hip hop, boom-bap, Chinese rap\nlo-fi hip hop, boom-bap, Chinese wuxia\nlo-fi hip hop, boom-bap, East Coast hip-hop\nlo-fi hip hop, boom-bap, French rap\nlo-fi hip hop, boom-bap, Hindi rap\nlo-fi hip hop, boom-bap, Indian hip hop\nlo-fi hip hop, boom-bap, Italian rap\nlo-fi hip hop, boom-bap, Japanese vocal\nlo-fi hip hop, boom-bap, Latin hip hop\nlo-fi hip hop, boom-bap, Latin jazz\nlo-fi hip hop, boom-bap, Latin rap\nlo-fi hip hop, boom-bap, Lithuanian rap\nlo-fi hip hop, boom-bap, Nigerian Pidgin\nlo-fi hip hop, boom-bap, Russian rap\nlo-fi hip hop, boom-bap, Spanish rap\nlo-fi hip hop, boom-bap, alternative R&B\nlo-fi hip hop, boom-bap, bilingual hip hop\nlo-fi hip hop, boom-bap, breakbeat\nlo-fi hip hop, boom-bap, cinematic\nlo-fi hip hop, boom-bap, cinematic rap\nlo-fi hip hop, boom-bap, cloud rap\nlo-fi hip hop, boom-bap, cyberpunk\nlo-fi hip hop, boom-bap, dystopian\nlo-fi hip hop, boom-bap, ethereal\nlo-fi hip hop, boom-bap, experimental\nlo-fi hip hop, boom-bap, funk\nlo-fi hip hop, boom-bap, funk hip hop\nlo-fi hip hop, boom-bap, happy hardcore\nlo-fi hip hop, boom-bap, industrial hip hop\nlo-fi hip hop, boom-bap, melancholic piano\nlo-fi hip hop, boom-bap, noir\nlo-fi hip hop, boom-bap, psychedelic\nlo-fi hip hop, boom-bap, psychedelic folk\nlo-fi hip hop, boom-bap, psychedelic hip hop\nlo-fi hip hop, boom-bap, soul\nlo-fi hip hop, boom-bap, trap\nlo-fi hip hop, boom-bap, underground rap\nlo-fi hip hop, boom-bap, vaporwave\nlo-fi hip hop, bossa nova\nlo-fi hip hop, bossa nova, Brazilian pop\nlo-fi hip hop, bossa nova, French rap\nlo-fi hip hop, bossa nova, Latin rap\nlo-fi hip hop, bossa nova, R&B\nlo-fi hip hop, bossa nova, experimental\nlo-fi hip hop, breakbeat\nlo-fi hip hop, breakbeat, electronic\nlo-fi hip hop, breakbeat, experimental\nlo-fi hip hop, breakcore\nlo-fi hip hop, breakcore, J-core\nlo-fi hip hop, breakcore, R&B\nlo-fi hip hop, breakcore, ambient\nlo-fi hip hop, breakcore, chiptune\nlo-fi hip hop, breakcore, experimental\nlo-fi hip hop, breakcore, neo-soul\nlo-fi hip hop, breakcore, old-school hip hop\nlo-fi hip hop, brostep\nlo-fi hip hop, cabaret\nlo-fi hip hop, chanson, C-pop\nlo-fi hip hop, chanson, jazz\nlo-fi hip hop, chill R&B\nlo-fi hip hop, chill R&B, C-pop\nlo-fi hip hop, chill trap\nlo-fi hip hop, chill trap, C-pop\nlo-fi hip hop, chill trap, R&B\nlo-fi hip hop, chill trap, cloud rap\nlo-fi hip hop, chill-pop\nlo-fi hip hop, chill-pop, Chinese ambient\nlo-fi hip hop, chill-pop, R&B\nlo-fi hip hop, chillhop\nlo-fi hip hop, chillhop, Brazilian\nlo-fi hip hop, chillhop, Brazilian R&B\nlo-fi hip hop, chillhop, C-Pop R&B\nlo-fi hip hop, chillhop, C-pop\nlo-fi hip hop, chillhop, C-pop rap\nlo-fi hip hop, chillhop, East Asian hip-hop\nlo-fi hip hop, chillhop, Filipino R&B\nlo-fi hip hop, chillhop, Filipino hip-hop\nlo-fi hip hop, chillhop, Filipino pop\nlo-fi hip hop, chillhop, French rap\nlo-fi hip hop, chillhop, German cloud rap\nlo-fi hip hop, chillhop, German conscious hip-hop\nlo-fi hip hop, chillhop, German pop\nlo-fi hip hop, chillhop, Indian classical\nlo-fi hip hop, chillhop, Indonesian pop-R&B\nlo-fi hip hop, chillhop, Italian hip-hop\nlo-fi hip hop, chillhop, Italian pop-rap\nlo-fi hip hop, chillhop, J-hip-hop\nlo-fi hip hop, chillhop, J-pop\nlo-fi hip hop, chillhop, Japanese hip-hop\nlo-fi hip hop, chillhop, Korean R&B\nlo-fi hip hop, chillhop, Latin R&B\nlo-fi hip hop, chillhop, Latin alternative\nlo-fi hip hop, chillhop, Latin rap\nlo-fi hip hop, chillhop, Latin trap\nlo-fi hip hop, chillhop, Mandopop\nlo-fi hip hop, chillhop, R&B\nlo-fi hip hop, chillhop, Thai pop\nlo-fi hip hop, chillhop, alternative R&B\nlo-fi hip hop, chillhop, bilingual R&B\nlo-fi hip hop, chillhop, cloud rap\nlo-fi hip hop, chillhop, conscious hip-hop\nlo-fi hip hop, chillhop, conscious rap\nlo-fi hip hop, chillhop, contemporary R&B\nlo-fi hip hop, chillhop, emo rap\nlo-fi hip hop, chillhop, emotional C-pop\nlo-fi hip hop, chillhop, emotional R&B\nlo-fi hip hop, chillhop, emotional rap\nlo-fi hip hop, chillhop, explicit R&B\nlo-fi hip hop, chillhop, lo-fi R&B\nlo-fi hip hop, chillhop, melodic rap\nlo-fi hip hop, chillhop, narrative rap\nlo-fi hip hop, chillhop, neo-soul\nlo-fi hip hop, chillhop, pop-rap\nlo-fi hip hop, chillhop, romantic C-pop\nlo-fi hip hop, chillhop, romantic R&B\nlo-fi hip hop, chillhop, vaporwave\nlo-fi hip hop, chillwave\nlo-fi hip hop, chillwave, Arabic R&B\nlo-fi hip hop, chillwave, Bollywood\nlo-fi hip hop, chillwave, Brazilian funk\nlo-fi hip hop, chillwave, Brazilian hip-hop\nlo-fi hip hop, chillwave, Brazilian pop\nlo-fi hip hop, chillwave, C-pop\nlo-fi hip hop, chillwave, Filipino R&B\nlo-fi hip hop, chillwave, French pop\nlo-fi hip hop, chillwave, German hip-hop\nlo-fi hip hop, chillwave, Indian classical\nlo-fi hip hop, chillwave, Indian fusion\nlo-fi hip hop, chillwave, Indian pop\nlo-fi hip hop, chillwave, J-pop\nlo-fi hip hop, chillwave, K-R&B\nlo-fi hip hop, chillwave, Latin R&B\nlo-fi hip hop, chillwave, Latin hip-hop\nlo-fi hip hop, chillwave, Mandopop\nlo-fi hip hop, chillwave, Punjabi soul\nlo-fi hip hop, chillwave, R&B\nlo-fi hip hop, chillwave, Russian pop\nlo-fi hip hop, chillwave, Russian pop-rap\nlo-fi hip hop, chillwave, Spanish rap\nlo-fi hip hop, chillwave, V-Pop\nlo-fi hip hop, chillwave, Vietnamese folk\nlo-fi hip hop, chillwave, alternative R&B\nlo-fi hip hop, chillwave, ambient\nlo-fi hip hop, chillwave, bedroom pop\nlo-fi hip hop, chillwave, cloud rap\nlo-fi hip hop, chillwave, dream pop\nlo-fi hip hop, chillwave, dreamy R&B\nlo-fi hip hop, chillwave, dubstep\nlo-fi hip hop, chillwave, emo rap\nlo-fi hip hop, chillwave, experimental electronic\nlo-fi hip hop, chillwave, future bass\nlo-fi hip hop, chillwave, future garage\nlo-fi hip hop, chillwave, holiday\nlo-fi hip hop, chillwave, neo-soul\nlo-fi hip hop, chillwave, pop-R&B\nlo-fi hip hop, chillwave, synth-pop\nlo-fi hip hop, chillwave, trap\nlo-fi hip hop, chillwave, vaporwave\nlo-fi hip hop, chiptune\nlo-fi hip hop, chiptune hip hop\nlo-fi hip hop, chiptune, Afrobeat\nlo-fi hip hop, chiptune, C-pop\nlo-fi hip hop, chiptune, Chinese rap\nlo-fi hip hop, chiptune, Filipino hip-hop\nlo-fi hip hop, chiptune, Finnish hip-hop\nlo-fi hip hop, chiptune, Greek rap\nlo-fi hip hop, chiptune, Haitian Creole\nlo-fi hip hop, chiptune, Italian rap\nlo-fi hip hop, chiptune, J-hip-hop\nlo-fi hip hop, chiptune, J-pop\nlo-fi hip hop, chiptune, J-rock\nlo-fi hip hop, chiptune, K-hip-hop\nlo-fi hip hop, chiptune, K-pop\nlo-fi hip hop, chiptune, Latin hip-hop\nlo-fi hip hop, chiptune, Latin pop\nlo-fi hip hop, chiptune, Mandopop\nlo-fi hip hop, chiptune, Moroccan rap\nlo-fi hip hop, chiptune, Persian spoken word\nlo-fi hip hop, chiptune, Polish rap\nlo-fi hip hop, chiptune, Russian pop\nlo-fi hip hop, chiptune, Sichuanese hip-hop\nlo-fi hip hop, chiptune, Taiwanese hip hop\nlo-fi hip hop, chiptune, Tamil rap\nlo-fi hip hop, chiptune, Tamil soul\nlo-fi hip hop, chiptune, Thai hip hop\nlo-fi hip hop, chiptune, Turkish hip-hop\nlo-fi hip hop, chiptune, ambient\nlo-fi hip hop, chiptune, boom-bap\nlo-fi hip hop, chiptune, cabaret\nlo-fi hip hop, chiptune, cinematic\nlo-fi hip hop, chiptune, cloud rap\nlo-fi hip hop, chiptune, conscious hip hop\nlo-fi hip hop, chiptune, dream pop\nlo-fi hip hop, chiptune, electronic\nlo-fi hip hop, chiptune, emo-rap\nlo-fi hip hop, chiptune, ethereal\nlo-fi hip hop, chiptune, experimental\nlo-fi hip hop, chiptune, experimental hip hop\nlo-fi hip hop, chiptune, experimental trap\nlo-fi hip hop, chiptune, future bass\nlo-fi hip hop, chiptune, futuristic\nlo-fi hip hop, chiptune, gangsta rap\nlo-fi hip hop, chiptune, glitch\nlo-fi hip hop, chiptune, hyperpop\nlo-fi hip hop, chiptune, indie pop\nlo-fi hip hop, chiptune, industrial\nlo-fi hip hop, chiptune, industrial dubstep\nlo-fi hip hop, chiptune, pop-rap\nlo-fi hip hop, chiptune, progressive house\nlo-fi hip hop, chiptune, reggae\nlo-fi hip hop, chiptune, regional Mexican\nlo-fi hip hop, chiptune, sad rap\nlo-fi hip hop, chiptune, trap\nlo-fi hip hop, chiptune, trap, cinematic pop\nlo-fi hip hop, chopped and screwed\nlo-fi hip hop, choral\nlo-fi hip hop, choral, Swiss German rap\nlo-fi hip hop, choral, electronic\nlo-fi hip hop, cinematic\nlo-fi hip hop, cinematic Arabic\nlo-fi hip hop, cinematic C-pop\nlo-fi hip hop, cinematic R&B\nlo-fi hip hop, cinematic ambient\nlo-fi hip hop, cinematic ambient, experimental\nlo-fi hip hop, cinematic ballad\nlo-fi hip hop, cinematic downtempo\nlo-fi hip hop, cinematic dubstep\nlo-fi hip hop, cinematic dubstep, trap\nlo-fi hip hop, cinematic electronic\nlo-fi hip hop, cinematic future bass\nlo-fi hip hop, cinematic hip hop\nlo-fi hip hop, cinematic orchestral\nlo-fi hip hop, cinematic pop\nlo-fi hip hop, cinematic pop-rock\nlo-fi hip hop, cinematic rap\nlo-fi hip hop, cinematic rock\nlo-fi hip hop, cinematic soul\nlo-fi hip hop, cinematic synth, C-pop\nlo-fi hip hop, cinematic trap\nlo-fi hip hop, cinematic trap, Chinese fusion\nlo-fi hip hop, cinematic trap, Chinese rap\nlo-fi hip hop, cinematic, Arabic\nlo-fi hip hop, cinematic, Arabic ambient\nlo-fi hip hop, cinematic, Arabic hip hop\nlo-fi hip hop, cinematic, Arabic storytelling\nlo-fi hip hop, cinematic, Arabic vocal\nlo-fi hip hop, cinematic, Balkan\nlo-fi hip hop, cinematic, Bengali folk\nlo-fi hip hop, cinematic, C-pop\nlo-fi hip hop, cinematic, Cantonese rap\nlo-fi hip hop, cinematic, Chinese\nlo-fi hip hop, cinematic, Chinese ambient\nlo-fi hip hop, cinematic, Chinese battle rap\nlo-fi hip hop, cinematic, Chinese folk\nlo-fi hip hop, cinematic, Chinese noir\nlo-fi hip hop, cinematic, Chinese pop\nlo-fi hip hop, cinematic, Chinese rap\nlo-fi hip hop, cinematic, Chinese rock\nlo-fi hip hop, cinematic, Chinese spoken word\nlo-fi hip hop, cinematic, Chinese traditional\nlo-fi hip hop, cinematic, East Coast hip hop\nlo-fi hip hop, cinematic, French rap\nlo-fi hip hop, cinematic, German rap\nlo-fi hip hop, cinematic, Greek rap\nlo-fi hip hop, cinematic, Hebrew rap\nlo-fi hip hop, cinematic, Indian ambient\nlo-fi hip hop, cinematic, Indian fusion\nlo-fi hip hop, cinematic, J-pop\nlo-fi hip hop, cinematic, J-rock\nlo-fi hip hop, cinematic, K-pop\nlo-fi hip hop, cinematic, Latin\nlo-fi hip hop, cinematic, Mandarin pop\nlo-fi hip hop, cinematic, Mandarin rap\nlo-fi hip hop, cinematic, Mandarin spoken word\nlo-fi hip hop, cinematic, Mandopop\nlo-fi hip hop, cinematic, Middle Eastern\nlo-fi hip hop, cinematic, Persian\nlo-fi hip hop, cinematic, Persian rap\nlo-fi hip hop, cinematic, Persian soul\nlo-fi hip hop, cinematic, Punjabi soul\nlo-fi hip hop, cinematic, R&B\nlo-fi hip hop, cinematic, Russian hip-hop\nlo-fi hip hop, cinematic, Russian rap\nlo-fi hip hop, cinematic, South Asian fusion\nlo-fi hip hop, cinematic, Spanish hip hop\nlo-fi hip hop, cinematic, Spanish pop\nlo-fi hip hop, cinematic, Spanish rap\nlo-fi hip hop, cinematic, Spanish soul\nlo-fi hip hop, cinematic, Spanish spoken word\nlo-fi hip hop, cinematic, Spanish vocal\nlo-fi hip hop, cinematic, Tamil hip hop\nlo-fi hip hop, cinematic, Turkish folk\nlo-fi hip hop, cinematic, Turkish indie\nlo-fi hip hop, cinematic, Turkish rap\nlo-fi hip hop, cinematic, UK rap\nlo-fi hip hop, cinematic, ambient\nlo-fi hip hop, cinematic, ancient style\nlo-fi hip hop, cinematic, blues\nlo-fi hip hop, cinematic, boom-bap\nlo-fi hip hop, cinematic, chiptune\nlo-fi hip hop, cinematic, cloud rap\nlo-fi hip hop, cinematic, conscious hip-hop\nlo-fi hip hop, cinematic, doo-wop\nlo-fi hip hop, cinematic, drum and bass\nlo-fi hip hop, cinematic, dubstep\nlo-fi hip hop, cinematic, duet\nlo-fi hip hop, cinematic, electronic\nlo-fi hip hop, cinematic, emo rap\nlo-fi hip hop, cinematic, emotional\nlo-fi hip hop, cinematic, emotional rap\nlo-fi hip hop, cinematic, ethereal\nlo-fi hip hop, cinematic, experimental\nlo-fi hip hop, cinematic, future bass\nlo-fi hip hop, cinematic, glitch\nlo-fi hip hop, cinematic, gospel\nlo-fi hip hop, cinematic, hardstyle\nlo-fi hip hop, cinematic, hyperpop\nlo-fi hip hop, cinematic, industrial\nlo-fi hip hop, cinematic, industrial rock\nlo-fi hip hop, cinematic, jazz-rap\nlo-fi hip hop, cinematic, melancholic\nlo-fi hip hop, cinematic, noir\nlo-fi hip hop, cinematic, pop-rock\nlo-fi hip hop, cinematic, psychedelic\nlo-fi hip hop, cinematic, reggaeton\nlo-fi hip hop, cinematic, rock\nlo-fi hip hop, cinematic, shoegaze\nlo-fi hip hop, cinematic, soul\nlo-fi hip hop, cinematic, trap\nlo-fi hip hop, cinematic, underground rap\nlo-fi hip hop, city pop\nlo-fi hip hop, city pop, K-pop\nlo-fi hip hop, city pop, R&B\nlo-fi hip hop, city pop, nu-disco\nlo-fi hip hop, city-pop, ambient\nlo-fi hip hop, city-pop, chillwave\nlo-fi hip hop, city-pop, dream pop\nlo-fi hip hop, classic hip hop, cloud rap\nlo-fi hip hop, classical\nlo-fi hip hop, classical fusion\nlo-fi hip hop, classical, Arabic hip hop\nlo-fi hip hop, classical, Chinese rap\nlo-fi hip hop, classical, Latin hip hop\nlo-fi hip hop, classical, Russian rap\nlo-fi hip hop, classical, Turkish rap\nlo-fi hip hop, classical, trap\nlo-fi hip hop, cloud rap\nlo-fi hip hop, cloud rap, French cloud rap\nlo-fi hip hop, cloud rap, French pop-rap\nlo-fi hip hop, cloud rap, French rap\nlo-fi hip hop, cloud rap, German hip-hop\nlo-fi hip hop, cloud rap, Korean hip-hop\nlo-fi hip hop, cloud rap, Latin trap\nlo-fi hip hop, cloud rap, Mandopop\nlo-fi hip hop, cloud rap, R&B\nlo-fi hip hop, cloud rap, ambient\nlo-fi hip hop, cloud rap, ambient R&B\nlo-fi hip hop, cloud rap, ambient pop\nlo-fi hip hop, cloud rap, chillwave\nlo-fi hip hop, cloud rap, chiptune\nlo-fi hip hop, cloud rap, cinematic\nlo-fi hip hop, cloud rap, dream pop\nlo-fi hip hop, cloud rap, emo rap\nlo-fi hip hop, cloud rap, emo trap\nlo-fi hip hop, cloud rap, emo-rap\nlo-fi hip hop, cloud rap, hyperpop\nlo-fi hip hop, cloud rap, psychedelic\nlo-fi hip hop, cloud rap, psychedelic hip hop\nlo-fi hip hop, cloud rap, psychedelic hip-hop\nlo-fi hip hop, cloud rap, synth-pop\nlo-fi hip hop, cloud rap, trap\nlo-fi hip hop, cloud rap, trap soul\nlo-fi hip hop, cloud rap, vaporwave\nlo-fi hip hop, coldwave\nlo-fi hip hop, color bass, ambient\nlo-fi hip hop, complextro, pop-punk\nlo-fi hip hop, complextro, vaporwave\nlo-fi hip hop, conscious J-hip-hop, jazz rap\nlo-fi hip hop, conscious hip hop\nlo-fi hip hop, conscious hip hop, Latin hip hop\nlo-fi hip hop, conscious hip hop, Latin-influenced\nlo-fi hip hop, conscious hip hop, Spanish rap\nlo-fi hip hop, conscious hip hop, gospel\nlo-fi hip hop, conscious hip-hop\nlo-fi hip hop, conscious hip-hop, C-pop\nlo-fi hip hop, conscious hip-hop, neo-soul\nlo-fi hip hop, conscious hip-hop, singer-songwriter\nlo-fi hip hop, conscious hip-hop, soulful R&B\nlo-fi hip hop, conscious rap\nlo-fi hip hop, conscious rap, Latin rap\nlo-fi hip hop, conscious rap, jazz hop\nlo-fi hip hop, contemporary R&B\nlo-fi hip hop, corrido\nlo-fi hip hop, country-rap\nlo-fi hip hop, country-trap\nlo-fi hip hop, crunk\nlo-fi hip hop, crunk, Memphis rap\nlo-fi hip hop, cumbia\nlo-fi hip hop, cumbia villera\nlo-fi hip hop, cumbia, boom-bap\nlo-fi hip hop, cumbia, salsa\nlo-fi hip hop, cumbia-reggaeton\nlo-fi hip hop, cyberpunk pop\nlo-fi hip hop, dance-pop\nlo-fi hip hop, dance-pop, Russian electronic\nlo-fi hip hop, dancehall\nlo-fi hip hop, dancehall, soul\nlo-fi hip hop, dark ambient\nlo-fi hip hop, dark ambient, electronic\nlo-fi hip hop, dark hip hop\nlo-fi hip hop, dark pop\nlo-fi hip hop, dark trap\nlo-fi hip hop, dark trap, atmospheric pop\nlo-fi hip hop, deep house\nlo-fi hip hop, deep house, Brazilian bass\nlo-fi hip hop, deep house, German hip-hop\nlo-fi hip hop, deep house, ambient\nlo-fi hip hop, deep house, soul\nlo-fi hip hop, dembow\nlo-fi hip hop, devotional, South Asian fusion\nlo-fi hip hop, digital hardcore, dream pop\nlo-fi hip hop, downtempo, East Asian\nlo-fi hip hop, downtempo, Italian pop\nlo-fi hip hop, downtempo, ambient\nlo-fi hip hop, dramatic ballad\nlo-fi hip hop, dream pop\nlo-fi hip hop, dream pop, C-pop\nlo-fi hip hop, dream pop, Chinese indie\nlo-fi hip hop, dream pop, Chinese rap\nlo-fi hip hop, dream pop, Chinese trap\nlo-fi hip hop, dream pop, French cloud rap\nlo-fi hip hop, dream pop, Indonesian indie\nlo-fi hip hop, dream pop, K-pop\nlo-fi hip hop, dream pop, R&B\nlo-fi hip hop, dream pop, Romanian vocal\nlo-fi hip hop, dream pop, Turkish alternative rap\nlo-fi hip hop, dream pop, ambient\nlo-fi hip hop, dream pop, ambient trap\nlo-fi hip hop, dream pop, bilingual R&B\nlo-fi hip hop, dream pop, bilingual pop\nlo-fi hip hop, dream pop, chillwave\nlo-fi hip hop, dream pop, chiptune\nlo-fi hip hop, dream pop, chopped and screwed\nlo-fi hip hop, dream pop, cinematic\nlo-fi hip hop, dream pop, cloud rap\nlo-fi hip hop, dream pop, emo rap\nlo-fi hip hop, dream pop, future bass\nlo-fi hip hop, dream pop, hyperpop\nlo-fi hip hop, dream pop, indie pop\nlo-fi hip hop, dream pop, indie rock\nlo-fi hip hop, dream pop, psychedelic\nlo-fi hip hop, dream pop, trap\nlo-fi hip hop, dream pop, vaporwave\nlo-fi hip hop, dream rap\nlo-fi hip hop, dream trap\nlo-fi hip hop, dream-pop, experimental\nlo-fi hip hop, dream-pop, synthwave\nlo-fi hip hop, dream-pop, trap\nlo-fi hip hop, dreamy R&B\nlo-fi hip hop, dreamy indie pop\nlo-fi hip hop, dreamy pop\nlo-fi hip hop, dreamy, future bass\nlo-fi hip hop, drill\nlo-fi hip hop, drill trap\nlo-fi hip hop, drill, ambient\nlo-fi hip hop, drill, trap\nlo-fi hip hop, drum and bass\nlo-fi hip hop, drum and bass, Russian rap\nlo-fi hip hop, drum and bass, ambient\nlo-fi hip hop, drum and bass, cinematic\nlo-fi hip hop, drum and bass, electronic\nlo-fi hip hop, drum and bass, emotional rap\nlo-fi hip hop, drum and bass, hyperpop\nlo-fi hip hop, drum and bass, neurofunk\nlo-fi hip hop, drum and bass, soul\nlo-fi hip hop, dubstep\nlo-fi hip hop, dubstep, C-pop\nlo-fi hip hop, dubstep, German rap\nlo-fi hip hop, dubstep, Malayalam rap\nlo-fi hip hop, dubstep, a cappella\nlo-fi hip hop, dubstep, atmospheric\nlo-fi hip hop, dubstep, cinematic\nlo-fi hip hop, dubstep, electronic\nlo-fi hip hop, dubstep, electronic rap\nlo-fi hip hop, dubstep, glitch-hop\nlo-fi hip hop, dubstep, nu-metal\nlo-fi hip hop, dubstep, rap-rock\nlo-fi hip hop, dubstep, trap\nlo-fi hip hop, dubstep, trap metal\nlo-fi hip hop, duduk, melancholic\nlo-fi hip hop, early 2000s K-pop\nlo-fi hip hop, eclectic, experimental\nlo-fi hip hop, educational, Latin\nlo-fi hip hop, electro house, complextro\nlo-fi hip hop, electro-industrial\nlo-fi hip hop, electro-swing, ambient\nlo-fi hip hop, electronic pop\nlo-fi hip hop, electronic, C-pop\nlo-fi hip hop, electronic, Chinese fusion\nlo-fi hip hop, electronic, Indian fusion\nlo-fi hip hop, electronic, Italian pop\nlo-fi hip hop, electronic, Russian rap\nlo-fi hip hop, electronic, Russian vocal\nlo-fi hip hop, electronic, Swiss German rap\nlo-fi hip hop, electronic, cinematic\nlo-fi hip hop, electronic, experimental\nlo-fi hip hop, electronic, trap\nlo-fi hip hop, emo rap\nlo-fi hip hop, emo rap, C-pop\nlo-fi hip hop, emo rap, French cloud rap\nlo-fi hip hop, emo rap, Korean R&B\nlo-fi hip hop, emo rap, Korean hip-hop\nlo-fi hip hop, emo rap, Latin fusion\nlo-fi hip hop, emo rap, Latin pop\nlo-fi hip hop, emo rap, Latin trap\nlo-fi hip hop, emo rap, Mandopop\nlo-fi hip hop, emo rap, R&B\nlo-fi hip hop, emo rap, Turkish alternative pop\nlo-fi hip hop, emo rap, acoustic pop\nlo-fi hip hop, emo rap, acoustic singer-songwriter\nlo-fi hip hop, emo rap, atmospheric pop\nlo-fi hip hop, emo rap, bedroom pop\nlo-fi hip hop, emo rap, cinematic\nlo-fi hip hop, emo rap, cloud rap\nlo-fi hip hop, emo rap, dream pop\nlo-fi hip hop, emo rap, hyperpop\nlo-fi hip hop, emo rap, indie pop\nlo-fi hip hop, emo rap, trap\nlo-fi hip hop, emo rap, vaporwave\nlo-fi hip hop, emo rock\nlo-fi hip hop, emo trap\nlo-fi hip hop, emo-rap\nlo-fi hip hop, emo-rap, Latin rap\nlo-fi hip hop, emo-rap, Mandopop\nlo-fi hip hop, emo-rap, R&B\nlo-fi hip hop, emo-rap, ambient\nlo-fi hip hop, emo-rap, cinematic\nlo-fi hip hop, emo-rap, cloud rap\nlo-fi hip hop, emo-rap, hyperpop\nlo-fi hip hop, emo-rap, synthwave\nlo-fi hip hop, emo-rap, trap\nlo-fi hip hop, emo-rock\nlo-fi hip hop, emo-trap\nlo-fi hip hop, emotional C-pop\nlo-fi hip hop, emotional J-pop\nlo-fi hip hop, emotional Mandopop\nlo-fi hip hop, emotional R&B\nlo-fi hip hop, emotional R&B, French cloud rap\nlo-fi hip hop, emotional ballad\nlo-fi hip hop, emotional duet\nlo-fi hip hop, emotional pop\nlo-fi hip hop, emotional pop, C-pop\nlo-fi hip hop, emotional pop, hyperpop\nlo-fi hip hop, emotional pop, spoken word\nlo-fi hip hop, emotional pop-R&B\nlo-fi hip hop, emotional pop-rap\nlo-fi hip hop, emotional pop-rock\nlo-fi hip hop, emotional rap\nlo-fi hip hop, emotional rap, cinematic hip hop\nlo-fi hip hop, emotional rock\nlo-fi hip hop, emotional rock, C-pop\nlo-fi hip hop, emotional rock, ambient pop\nlo-fi hip hop, emotional synthpop, dubstep\nlo-fi hip hop, emotional trap\nlo-fi hip hop, epic boom-bap\nlo-fi hip hop, ethereal\nlo-fi hip hop, ethereal R&B\nlo-fi hip hop, ethereal pop\nlo-fi hip hop, ethereal trap\nlo-fi hip hop, ethereal, French pop\nlo-fi hip hop, ethereal, Hebrew rap\nlo-fi hip hop, ethereal, rock\nlo-fi hip hop, ethereal, trap\nlo-fi hip hop, experimental C-pop\nlo-fi hip hop, experimental R&B\nlo-fi hip hop, experimental electronic\nlo-fi hip hop, experimental electronic, Azerbaijani hip hop\nlo-fi hip hop, experimental electronic, ambient\nlo-fi hip hop, experimental hip hop\nlo-fi hip hop, experimental hip hop, hyperpop\nlo-fi hip hop, experimental hip hop, trap\nlo-fi hip hop, experimental hip-hop, industrial\nlo-fi hip hop, experimental pop\nlo-fi hip hop, experimental rap\nlo-fi hip hop, experimental synth-pop\nlo-fi hip hop, experimental trap\nlo-fi hip hop, experimental trap, ambient\nlo-fi hip hop, experimental trap, melancholic\nlo-fi hip hop, experimental trap, rage music\nlo-fi hip hop, experimental, Brazilian hip hop\nlo-fi hip hop, experimental, French rap\nlo-fi hip hop, experimental, Indonesian pop\nlo-fi hip hop, experimental, Israeli hip hop\nlo-fi hip hop, experimental, Spanish rap\nlo-fi hip hop, fado\nlo-fi hip hop, flamenco rap\nlo-fi hip hop, flamenco, C-pop\nlo-fi hip hop, flamenco, Chinese rap\nlo-fi hip hop, flamenco, ambient\nlo-fi hip hop, folk fusion\nlo-fi hip hop, folk soul\nlo-fi hip hop, funk\nlo-fi hip hop, funk pop, indie rock\nlo-fi hip hop, funk soul, R&B\nlo-fi hip hop, funk, Chinese fusion\nlo-fi hip hop, funk, Mandopop\nlo-fi hip hop, funk, Russian rap\nlo-fi hip hop, funk, Sundanese rap\nlo-fi hip hop, funk, classical hip hop\nlo-fi hip hop, funk, disco\nlo-fi hip hop, funk, hyperpop\nlo-fi hip hop, funk, pop\nlo-fi hip hop, funk-jazz\nlo-fi hip hop, funk-pop, R&B\nlo-fi hip hop, funky house\nlo-fi hip hop, future bass\nlo-fi hip hop, future bass, C-pop\nlo-fi hip hop, future bass, Chinese R&B\nlo-fi hip hop, future bass, Chinese ambient\nlo-fi hip hop, future bass, Chinese chill\nlo-fi hip hop, future bass, Chinese pop\nlo-fi hip hop, future bass, Chinese rap\nlo-fi hip hop, future bass, Chinese trap\nlo-fi hip hop, future bass, EDM\nlo-fi hip hop, future bass, Hindi EDM\nlo-fi hip hop, future bass, Indian classical\nlo-fi hip hop, future bass, J-core\nlo-fi hip hop, future bass, J-pop\nlo-fi hip hop, future bass, K-pop\nlo-fi hip hop, future bass, Mandarin rap\nlo-fi hip hop, future bass, Punjabi soul\nlo-fi hip hop, future bass, R&B\nlo-fi hip hop, future bass, UK garage\nlo-fi hip hop, future bass, Vietnamese pop\nlo-fi hip hop, future bass, ambient\nlo-fi hip hop, future bass, ambient R&B\nlo-fi hip hop, future bass, boom-bap\nlo-fi hip hop, future bass, bossa nova\nlo-fi hip hop, future bass, chill trap\nlo-fi hip hop, future bass, chillhop\nlo-fi hip hop, future bass, chillwave\nlo-fi hip hop, future bass, chiptune\nlo-fi hip hop, future bass, cinematic\nlo-fi hip hop, future bass, city-pop\nlo-fi hip hop, future bass, dream pop\nlo-fi hip hop, future bass, dreamy pop\nlo-fi hip hop, future bass, dubstep\nlo-fi hip hop, future bass, electro-house\nlo-fi hip hop, future bass, electronic soul\nlo-fi hip hop, future bass, emotional\nlo-fi hip hop, future bass, emotional pop\nlo-fi hip hop, future bass, emotional rap\nlo-fi hip hop, future bass, ethereal\nlo-fi hip hop, future bass, ethereal pop\nlo-fi hip hop, future bass, glitch hop\nlo-fi hip hop, future bass, glitch-hop\nlo-fi hip hop, future bass, happy hardcore\nlo-fi hip hop, future bass, hardstyle\nlo-fi hip hop, future bass, hyperpop\nlo-fi hip hop, future bass, jazz\nlo-fi hip hop, future bass, melodic dubstep\nlo-fi hip hop, future bass, melodic rap\nlo-fi hip hop, future bass, neo-soul\nlo-fi hip hop, future bass, pop\nlo-fi hip hop, future bass, pop-R&B\nlo-fi hip hop, future bass, rap\nlo-fi hip hop, future bass, reggaeton\nlo-fi hip hop, future bass, soul\nlo-fi hip hop, future bass, soulful rap\nlo-fi hip hop, future bass, synth-pop\nlo-fi hip hop, future bass, trap\nlo-fi hip hop, future bass, vaporwave\nlo-fi hip hop, future garage, experimental electronic\nlo-fi hip hop, future garage, trip-hop\nlo-fi hip hop, gangsta rap\nlo-fi hip hop, gangsta rap, Turkish\nlo-fi hip hop, gangster rap\nlo-fi hip hop, gangster rap, Latin hip-hop\nlo-fi hip hop, ghazal\nlo-fi hip hop, ghazal, ambient\nlo-fi hip hop, ghazal, trap\nlo-fi hip hop, glitch hop\nlo-fi hip hop, glitch hop, Chinese rap\nlo-fi hip hop, glitch hop, Latin pop\nlo-fi hip hop, glitch hop, R&B\nlo-fi hip hop, glitch hop, bilingual rap\nlo-fi hip hop, glitch hop, chiptune\nlo-fi hip hop, glitch hop, cinematic\nlo-fi hip hop, glitch hop, industrial trap\nlo-fi hip hop, glitch, ambient\nlo-fi hip hop, glitch, breakcore\nlo-fi hip hop, glitch, chiptune\nlo-fi hip hop, glitch, drum and bass\nlo-fi hip hop, glitch, electro-industrial\nlo-fi hip hop, glitch, electronic\nlo-fi hip hop, glitch, folk\nlo-fi hip hop, glitch, hyperpop\nlo-fi hip hop, glitch-hop, breakcore\nlo-fi hip hop, glitch-hop, hyperpop\nlo-fi hip hop, gospel\nlo-fi hip hop, gospel rap\nlo-fi hip hop, gospel rock\nlo-fi hip hop, gospel soul\nlo-fi hip hop, gospel, C-pop\nlo-fi hip hop, gospel, R&B\nlo-fi hip hop, gospel, emotional rap\nlo-fi hip hop, gospel, soul\nlo-fi hip hop, gospel, spoken word\nlo-fi hip hop, gothic hip hop\nlo-fi hip hop, grime, dreamy vocal\nlo-fi hip hop, happy hardcore\nlo-fi hip hop, hardstyle\nlo-fi hip hop, hardstyle, C-pop\nlo-fi hip hop, hardstyle, K-pop\nlo-fi hip hop, hardstyle, Mandopop\nlo-fi hip hop, hardstyle, ambient\nlo-fi hip hop, hardstyle, big room house\nlo-fi hip hop, hardstyle, cinematic\nlo-fi hip hop, hardstyle, hybrid trap\nlo-fi hip hop, hardstyle, melodic rap\nlo-fi hip hop, hardstyle, trap\nlo-fi hip hop, hardstyle, trap metal\nlo-fi hip hop, hardstyle, vaporwave\nlo-fi hip hop, hardwave\nlo-fi hip hop, hardwave, cinematic\nlo-fi hip hop, hip-house\nlo-fi hip hop, horrorcore\nlo-fi hip hop, horrorcore, synth pop\nlo-fi hip hop, horrorcore, trap\nlo-fi hip hop, house\nlo-fi hip hop, hybrid trap, ambient\nlo-fi hip hop, hybrid trap, cinematic\nlo-fi hip hop, hyperpop\nlo-fi hip hop, hyperpop, C-pop\nlo-fi hip hop, hyperpop, J-pop\nlo-fi hip hop, hyperpop, Korean R&B\nlo-fi hip hop, hyperpop, Korean rap\nlo-fi hip hop, hyperpop, Latin trap\nlo-fi hip hop, hyperpop, R&B\nlo-fi hip hop, hyperpop, ambient\nlo-fi hip hop, hyperpop, bedroom pop\nlo-fi hip hop, hyperpop, breakcore\nlo-fi hip hop, hyperpop, chiptune\nlo-fi hip hop, hyperpop, cloud rap\nlo-fi hip hop, hyperpop, digicore\nlo-fi hip hop, hyperpop, electro-funk\nlo-fi hip hop, hyperpop, electronic rock\nlo-fi hip hop, hyperpop, emo-rap\nlo-fi hip hop, hyperpop, glitch-hop\nlo-fi hip hop, hyperpop, glitchcore\nlo-fi hip hop, hyperpop, melancholic pop\nlo-fi hip hop, hyperpop, metalcore\nlo-fi hip hop, hyperpop, nightcore\nlo-fi hip hop, hyperpop, pop-punk\nlo-fi hip hop, hyperpop, reggaeton\nlo-fi hip hop, hyperpop, trap\nlo-fi hip hop, hyperpop, trap-metal\nlo-fi hip hop, hyperpop, vaporwave\nlo-fi hip hop, hyperpop, vocaloid\nlo-fi hip hop, indie R&B\nlo-fi hip hop, indie dance, drum and bass\nlo-fi hip hop, indie folk\nlo-fi hip hop, indie folk, Indonesian rap\nlo-fi hip hop, indie folk, choral\nlo-fi hip hop, indie pop\nlo-fi hip hop, indie pop, Bollywood\nlo-fi hip hop, indie pop, C-pop\nlo-fi hip hop, indie pop, Chinese rap\nlo-fi hip hop, indie pop, R&B\nlo-fi hip hop, indie pop, Russian rap\nlo-fi hip hop, indie pop, alternative rock\nlo-fi hip hop, indie pop, ambient\nlo-fi hip hop, indie pop, cinematic\nlo-fi hip hop, indie pop, drum and bass\nlo-fi hip hop, indie pop, soul\nlo-fi hip hop, indie pop, synth-pop\nlo-fi hip hop, indie pop, trip-hop\nlo-fi hip hop, indie rock\nlo-fi hip hop, indie rock, Indian rap\nlo-fi hip hop, indie rock, ambient\nlo-fi hip hop, indie rock, chiptune\nlo-fi hip hop, indie-pop, trap\nlo-fi hip hop, indie-pop, vaporwave\nlo-fi hip hop, industrial breakcore\nlo-fi hip hop, industrial hip hop\nlo-fi hip hop, industrial metalcore\nlo-fi hip hop, industrial pop\nlo-fi hip hop, industrial rock\nlo-fi hip hop, industrial trap\nlo-fi hip hop, industrial trap metal\nlo-fi hip hop, industrial trap, K-pop\nlo-fi hip hop, industrial, Persian spoken word\nlo-fi hip hop, industrial, cinematic\nlo-fi hip hop, industrial, electronic\nlo-fi hip hop, industrial, emotional rap\nlo-fi hip hop, industrial, hyperpop\nlo-fi hip hop, j-rock\nlo-fi hip hop, jazz\nlo-fi hip hop, jazz fusion\nlo-fi hip hop, jazz hip hop\nlo-fi hip hop, jazz hop\nlo-fi hip hop, jazz lounge\nlo-fi hip hop, jazz pop\nlo-fi hip hop, jazz rap\nlo-fi hip hop, jazz rap, Korean hip-hop\nlo-fi hip hop, jazz rap, cinematic\nlo-fi hip hop, jazz rap, soul\nlo-fi hip hop, jazz rap, trap\nlo-fi hip hop, jazz soul\nlo-fi hip hop, jazz, C-pop\nlo-fi hip hop, jazz, Catalan\nlo-fi hip hop, jazz, Cebuano rap\nlo-fi hip hop, jazz, Chinese rap\nlo-fi hip hop, jazz, Latin\nlo-fi hip hop, jazz, R&B\nlo-fi hip hop, jazz, ambient\nlo-fi hip hop, jazz, cinematic\nlo-fi hip hop, jazz, orchestral hip hop\nlo-fi hip hop, jazz, vaporwave\nlo-fi hip hop, jazz-hop\nlo-fi hip hop, jazz-hop, Korean R&B\nlo-fi hip hop, jazz-hop, chillhop\nlo-fi hip hop, jazz-hop, neo-soul\nlo-fi hip hop, jazz-rap\nlo-fi hip hop, jazz-rap, cloud rap\nlo-fi hip hop, jazzy hip hop\nlo-fi hip hop, jazzy, Cantonese rap\nlo-fi hip hop, jungle\nlo-fi hip hop, jungle, ambient\nlo-fi hip hop, jungle, drum and bass\nlo-fi hip hop, kawaii\nlo-fi hip hop, kawaii rap\nlo-fi hip hop, liquid drum and bass\nlo-fi hip hop, lo-fi R&B, Mandopop\nlo-fi hip hop, math rock\nlo-fi hip hop, math rock, C-pop\nlo-fi hip hop, math rock, vaporwave\nlo-fi hip hop, melancholic\nlo-fi hip hop, melancholic ballad\nlo-fi hip hop, melancholic piano\nlo-fi hip hop, melancholic piano, blues rock\nlo-fi hip hop, melancholic pop\nlo-fi hip hop, melancholic pop, C-pop\nlo-fi hip hop, melancholic pop, Indian ballad\nlo-fi hip hop, melancholic pop, Persian ballad\nlo-fi hip hop, melancholic pop, ambient ballad\nlo-fi hip hop, melancholic pop-rap\nlo-fi hip hop, melancholic trap\nlo-fi hip hop, melancholic, Khmer\nlo-fi hip hop, melancholic, Punjabi folk\nlo-fi hip hop, melancholic, bilingual\nlo-fi hip hop, melodic rap\nlo-fi hip hop, melodic trap\nlo-fi hip hop, melodic trap, chillwave\nlo-fi hip hop, melodic trap, soul\nlo-fi hip hop, meme hip hop\nlo-fi hip hop, meme rap, chiptune\nlo-fi hip hop, metalcore\nlo-fi hip hop, metalcore, ambient\nlo-fi hip hop, modern R&B\nlo-fi hip hop, modern hip hop\nlo-fi hip hop, modern trap\nlo-fi hip hop, moombahton\nlo-fi hip hop, moombahton, hardstyle\nlo-fi hip hop, moombahton, trap\nlo-fi hip hop, motivational hip hop\nlo-fi hip hop, motivational trap\nlo-fi hip hop, multilingual pop\nlo-fi hip hop, narrative rap\nlo-fi hip hop, neo-classical\nlo-fi hip hop, neo-noir, experimental rock\nlo-fi hip hop, neo-soul\nlo-fi hip hop, neo-soul jazz\nlo-fi hip hop, neo-soul, Afrobeat\nlo-fi hip hop, neo-soul, C-pop\nlo-fi hip hop, neo-soul, Fado\nlo-fi hip hop, neo-soul, French cloud rap\nlo-fi hip hop, neo-soul, French rap\nlo-fi hip hop, neo-soul, J-pop\nlo-fi hip hop, neo-soul, K-R&B\nlo-fi hip hop, neo-soul, R&B\nlo-fi hip hop, neo-soul, UK garage\nlo-fi hip hop, neo-soul, alternative R&B\nlo-fi hip hop, neo-soul, ambient\nlo-fi hip hop, neo-soul, ambient R&B\nlo-fi hip hop, neo-soul, bedroom pop\nlo-fi hip hop, neo-soul, bilingual ballad\nlo-fi hip hop, neo-soul, boom-bap\nlo-fi hip hop, neo-soul, breakbeat\nlo-fi hip hop, neo-soul, chill R&B\nlo-fi hip hop, neo-soul, chillhop\nlo-fi hip hop, neo-soul, chillwave\nlo-fi hip hop, neo-soul, chiptune\nlo-fi hip hop, neo-soul, cinematic\nlo-fi hip hop, neo-soul, city pop\nlo-fi hip hop, neo-soul, city-pop\nlo-fi hip hop, neo-soul, conscious hip-hop\nlo-fi hip hop, neo-soul, dream pop\nlo-fi hip hop, neo-soul, experimental\nlo-fi hip hop, neo-soul, experimental electronic\nlo-fi hip hop, neo-soul, funk\nlo-fi hip hop, neo-soul, funky house\nlo-fi hip hop, neo-soul, hyperpop\nlo-fi hip hop, neo-soul, indie R&B\nlo-fi hip hop, neo-soul, indie rock\nlo-fi hip hop, neo-soul, jazz\nlo-fi hip hop, neo-soul, jazz-hop\nlo-fi hip hop, neo-soul, psychedelic\nlo-fi hip hop, neo-soul, psychedelic funk\nlo-fi hip hop, neo-soul, psychedelic hip hop\nlo-fi hip hop, neo-soul, synth-funk\nlo-fi hip hop, neo-soul, trap\nlo-fi hip hop, neo-soul, trip-hop\nlo-fi hip hop, neo-soul, vaporwave\nlo-fi hip hop, neo-soul, video game music\nlo-fi hip hop, neurofunk\nlo-fi hip hop, neurofunk, ambient\nlo-fi hip hop, new jack swing\nlo-fi hip hop, new jack swing, Cantopop\nlo-fi hip hop, new jack swing, cinematic R&B\nlo-fi hip hop, nightcore\nlo-fi hip hop, noir jazz\nlo-fi hip hop, noir jazz, experimental trap\nlo-fi hip hop, noir, Russian rap\nlo-fi hip hop, noise rock\nlo-fi hip hop, noise rock, French rap\nlo-fi hip hop, noise rock, chiptune\nlo-fi hip hop, novelty, chiptune\nlo-fi hip hop, nu-disco\nlo-fi hip hop, nu-disco, chillwave\nlo-fi hip hop, nu-disco, future funk\nlo-fi hip hop, nu-disco, vaporwave\nlo-fi hip hop, nu-jazz, acid jazz\nlo-fi hip hop, nu-metal\nlo-fi hip hop, nu-metal, Romanian rap\nlo-fi hip hop, nu-metal, alternative rock\nlo-fi hip hop, nu-metal, ambient\nlo-fi hip hop, nu-metal, chiptune\nlo-fi hip hop, nu-metal, cinematic\nlo-fi hip hop, nu-metal, emo-rap\nlo-fi hip hop, nu-metal, horrorcore\nlo-fi hip hop, nu-metal, pop-punk\nlo-fi hip hop, nu-metal, psychedelic\nlo-fi hip hop, nu-metal, rap\nlo-fi hip hop, nu-metal, rap rock\nlo-fi hip hop, nu-metal, rap-rock\nlo-fi hip hop, nu-metal, trap\nlo-fi hip hop, nu-metal, vaporwave\nlo-fi hip hop, old-school hip hop\nlo-fi hip hop, operatic\nlo-fi hip hop, orchestral electronica\nlo-fi hip hop, orchestral hip hop, cinematic trap\nlo-fi hip hop, orchestral pop\nlo-fi hip hop, oud fusion\nlo-fi hip hop, pagode\nlo-fi hip hop, party hip hop\nlo-fi hip hop, phonk\nlo-fi hip hop, phonk, R&B\nlo-fi hip hop, phonk, Russian rap\nlo-fi hip hop, phonk, cinematic\nlo-fi hip hop, phonk, cinematic trap\nlo-fi hip hop, phonk, trap\nlo-fi hip hop, piano ballad\nlo-fi hip hop, pluggnb\nlo-fi hip hop, political rap\nlo-fi hip hop, political rap, world fusion\nlo-fi hip hop, pop\nlo-fi hip hop, pop ballad\nlo-fi hip hop, pop, C-pop\nlo-fi hip hop, pop, Chinese rap\nlo-fi hip hop, pop, electronic\nlo-fi hip hop, pop-R&B\nlo-fi hip hop, pop-R&B, Indonesian\nlo-fi hip hop, pop-R&B, Turkish jazz\nlo-fi hip hop, pop-R&B, vaporwave\nlo-fi hip hop, pop-punk\nlo-fi hip hop, pop-punk, alternative rock\nlo-fi hip hop, pop-punk, boom-bap\nlo-fi hip hop, pop-punk, chiptune\nlo-fi hip hop, pop-punk, cinematic\nlo-fi hip hop, pop-punk, cloud rap\nlo-fi hip hop, pop-punk, rock\nlo-fi hip hop, pop-punk, trap\nlo-fi hip hop, pop-rap\nlo-fi hip hop, pop-rap, acoustic ballad\nlo-fi hip hop, pop-rap, boom-bap\nlo-fi hip hop, pop-rap, funk\nlo-fi hip hop, pop-rap, trap\nlo-fi hip hop, pop-rap, vaporwave\nlo-fi hip hop, pop-rock\nlo-fi hip hop, pop-rock, C-pop\nlo-fi hip hop, pop-rock, Chinese rap\nlo-fi hip hop, pop-rock, K-pop\nlo-fi hip hop, pop-rock, cinematic\nlo-fi hip hop, pop-rock, indie rock\nlo-fi hip hop, pop-rock, rap\nlo-fi hip hop, pop-rock, vaporwave\nlo-fi hip hop, pop-trap, emotional\nlo-fi hip hop, post-hardcore, emo-rap\nlo-fi hip hop, post-punk\nlo-fi hip hop, post-rock\nlo-fi hip hop, post-rock, ambient\nlo-fi hip hop, progressive house, ambient\nlo-fi hip hop, protest music\nlo-fi hip hop, psychedelic\nlo-fi hip hop, psychedelic R&B\nlo-fi hip hop, psychedelic hip hop\nlo-fi hip hop, psychedelic rap\nlo-fi hip hop, psychedelic reggae\nlo-fi hip hop, psychedelic rock, vaporwave\nlo-fi hip hop, psychedelic soul\nlo-fi hip hop, psychedelic trap\nlo-fi hip hop, psychedelic, Danish rap\nlo-fi hip hop, psychedelic, Turkish rap\nlo-fi hip hop, psychedelic, cinematic\nlo-fi hip hop, psychedelic, cloud rap\nlo-fi hip hop, psychedelic, conscious hip-hop\nlo-fi hip hop, psychedelic, experimental\nlo-fi hip hop, psychedelic, jazz\nlo-fi hip hop, psychedelic, vaporwave\nlo-fi hip hop, punk rock\nlo-fi hip hop, ragtime\nlo-fi hip hop, rap rock\nlo-fi hip hop, rap rock, chiptune\nlo-fi hip hop, rap-rock\nlo-fi hip hop, rap-rock, Balkan rock\nlo-fi hip hop, rave, glitch\nlo-fi hip hop, reggae, Russian rap\nlo-fi hip hop, reggaeton\nlo-fi hip hop, reggaeton, French rap\nlo-fi hip hop, reggaeton, ambient\nlo-fi hip hop, reggaeton, cinematic\nlo-fi hip hop, reggaeton, dream pop\nlo-fi hip hop, reggaeton, hyperpop\nlo-fi hip hop, reggaeton, trap\nlo-fi hip hop, regional Mexican\nlo-fi hip hop, regional Mexican rap\nlo-fi hip hop, retro synth, boom-bap\nlo-fi hip hop, retro-funk, city pop\nlo-fi hip hop, rock\nlo-fi hip hop, rock, C-pop\nlo-fi hip hop, rock, Mandarin rap\nlo-fi hip hop, rock, ambient\nlo-fi hip hop, rock, cinematic\nlo-fi hip hop, rock, jazz\nlo-fi hip hop, rock, rap\nlo-fi hip hop, rockabilly\nlo-fi hip hop, romantic C-pop\nlo-fi hip hop, romantic Latin trap\nlo-fi hip hop, romantic R&B\nlo-fi hip hop, romantic pop\nlo-fi hip hop, romantic pop-rap\nlo-fi hip hop, romantic, Spanish-style\nlo-fi hip hop, sad R&B\nlo-fi hip hop, sad R&B, Indian pop\nlo-fi hip hop, sad hip-hop, atmospheric ballad\nlo-fi hip hop, sad pop\nlo-fi hip hop, sad pop, Indian folk\nlo-fi hip hop, sad pop, emotional rap\nlo-fi hip hop, sad rap\nlo-fi hip hop, sad rap, acoustic singer-songwriter\nlo-fi hip hop, sad rap, indie pop\nlo-fi hip hop, sad trap\nlo-fi hip hop, sad trap, Latin R&B\nlo-fi hip hop, sad trap, Turkish pop\nlo-fi hip hop, sad-pop\nlo-fi hip hop, salsa\nlo-fi hip hop, sentimental Mandopop\nlo-fi hip hop, sentimental pop\nlo-fi hip hop, shoegaze\nlo-fi hip hop, shoegaze, C-pop\nlo-fi hip hop, shoegaze, K-pop\nlo-fi hip hop, shoegaze, cinematic\nlo-fi hip hop, shoegaze, dream pop\nlo-fi hip hop, shoegaze, noise rock\nlo-fi hip hop, shoegaze, trap\nlo-fi hip hop, slap house, latin house\nlo-fi hip hop, slowed + reverb\nlo-fi hip hop, smooth jazz, Indian lounge\nlo-fi hip hop, soul\nlo-fi hip hop, soul funk, trap\nlo-fi hip hop, soul, C-pop\nlo-fi hip hop, soul, Korean hip hop\nlo-fi hip hop, soul, Latin rap\nlo-fi hip hop, soul, R&B\nlo-fi hip hop, soul, ambient\nlo-fi hip hop, soul, boom-bap\nlo-fi hip hop, soul, chiptune\nlo-fi hip hop, soul, cinematic\nlo-fi hip hop, soul, comedy rap\nlo-fi hip hop, soul, experimental rock\nlo-fi hip hop, soul, gospel\nlo-fi hip hop, soul, jazz\nlo-fi hip hop, soul, rock\nlo-fi hip hop, soul, vaporwave\nlo-fi hip hop, soulful R&B\nlo-fi hip hop, soulful R&B, cinematic rap\nlo-fi hip hop, soulful R&B, spoken word\nlo-fi hip hop, soulful R&B, trap\nlo-fi hip hop, soulful jazz, political hip hop\nlo-fi hip hop, soulful rap\nlo-fi hip hop, soulful rap, psychedelic\nlo-fi hip hop, spiritual hip hop\nlo-fi hip hop, spiritual rap\nlo-fi hip hop, spiritual, Indian devotional\nlo-fi hip hop, surf rock\nlo-fi hip hop, surf-rock, trap\nlo-fi hip hop, symphonic rock\nlo-fi hip hop, synth-pop\nlo-fi hip hop, synth-pop, K-pop\nlo-fi hip hop, synth-pop, R&B\nlo-fi hip hop, synth-pop, chiptune\nlo-fi hip hop, synth-pop, emotional\nlo-fi hip hop, synth-pop, future bass\nlo-fi hip hop, synth-pop, glitch-hop\nlo-fi hip hop, synthpop\nlo-fi hip hop, synthwave\nlo-fi hip hop, synthwave, R&B\nlo-fi hip hop, synthwave, ambient\nlo-fi hip hop, techno\nlo-fi hip hop, theatrical art-pop, gothic hip hop\nlo-fi hip hop, traditional folk\nlo-fi hip hop, trap\nlo-fi hip hop, trap R&B\nlo-fi hip hop, trap R&B, Chinese pop\nlo-fi hip hop, trap R&B, blues-rock\nlo-fi hip hop, trap R&B, future bass\nlo-fi hip hop, trap hip hop, ambient instrumental\nlo-fi hip hop, trap melão\nlo-fi hip hop, trap metal\nlo-fi hip hop, trap metal, cinematic\nlo-fi hip hop, trap soul\nlo-fi hip hop, trap soul, R&B\nlo-fi hip hop, trap soul, vaporwave\nlo-fi hip hop, trap, Afro-Caribbean\nlo-fi hip hop, trap, Afro-hip hop\nlo-fi hip hop, trap, Arabic rap\nlo-fi hip hop, trap, Bengali fusion\nlo-fi hip hop, trap, Bollywood\nlo-fi hip hop, trap, Brazilian funk\nlo-fi hip hop, trap, Brazilian hip hop\nlo-fi hip hop, trap, C-pop\nlo-fi hip hop, trap, Chinese folk\nlo-fi hip hop, trap, Chinese hip hop\nlo-fi hip hop, trap, Chinese pop\nlo-fi hip hop, trap, Chinese rap\nlo-fi hip hop, trap, Chinese spoken word\nlo-fi hip hop, trap, Czech rap\nlo-fi hip hop, trap, Dutch pop\nlo-fi hip hop, trap, Dutch rap\nlo-fi hip hop, trap, EDM\nlo-fi hip hop, trap, East Asian fusion\nlo-fi hip hop, trap, Finnish rap\nlo-fi hip hop, trap, French chanson\nlo-fi hip hop, trap, French hip hop\nlo-fi hip hop, trap, French rap\nlo-fi hip hop, trap, German rap\nlo-fi hip hop, trap, Hindi rap\nlo-fi hip hop, trap, Indian ambient\nlo-fi hip hop, trap, Indian fusion\nlo-fi hip hop, trap, Indian hip hop\nlo-fi hip hop, trap, Indian hip-hop\nlo-fi hip hop, trap, Indian pop\nlo-fi hip hop, trap, Indian soul\nlo-fi hip hop, trap, Italian rap\nlo-fi hip hop, trap, J-pop\nlo-fi hip hop, trap, K-hip-hop\nlo-fi hip hop, trap, K-pop\nlo-fi hip hop, trap, Korean rap\nlo-fi hip hop, trap, Latin guitar\nlo-fi hip hop, trap, Latin rap\nlo-fi hip hop, trap, Latin-influenced\nlo-fi hip hop, trap, Mandarin pop\nlo-fi hip hop, trap, Mandarin rap\nlo-fi hip hop, trap, Mandopop\nlo-fi hip hop, trap, Middle Eastern\nlo-fi hip hop, trap, Nordic soul\nlo-fi hip hop, trap, Portuguese hip-hop\nlo-fi hip hop, trap, Portuguese rap\nlo-fi hip hop, trap, Punjabi\nlo-fi hip hop, trap, Punjabi rap\nlo-fi hip hop, trap, Quebecois rap\nlo-fi hip hop, trap, R&B\nlo-fi hip hop, trap, Russian rap\nlo-fi hip hop, trap, South Asian folk\nlo-fi hip hop, trap, Spanish rap\nlo-fi hip hop, trap, Thai pop-rap\nlo-fi hip hop, trap, Turkish pop\nlo-fi hip hop, trap, UK garage\nlo-fi hip hop, trap, Urdu rap\nlo-fi hip hop, trap, V-Pop\nlo-fi hip hop, trap, Vietnamese rap\nlo-fi hip hop, trap, ambient\nlo-fi hip hop, trap, ambient R&B\nlo-fi hip hop, trap, anime\nlo-fi hip hop, trap, atmospheric pop\nlo-fi hip hop, trap, baroque\nlo-fi hip hop, trap, bilingual\nlo-fi hip hop, trap, bilingual hip-hop\nlo-fi hip hop, trap, bilingual rap\nlo-fi hip hop, trap, bitpop\nlo-fi hip hop, trap, boom-bap\nlo-fi hip hop, trap, chillwave\nlo-fi hip hop, trap, chiptune\nlo-fi hip hop, trap, chopped and screwed\nlo-fi hip hop, trap, cinematic\nlo-fi hip hop, trap, cinematic rap\nlo-fi hip hop, trap, city pop\nlo-fi hip hop, trap, cloud rap\nlo-fi hip hop, trap, country-folk\nlo-fi hip hop, trap, cyberpunk\nlo-fi hip hop, trap, dancehall\nlo-fi hip hop, trap, dream pop\nlo-fi hip hop, trap, drill\nlo-fi hip hop, trap, dubstep\nlo-fi hip hop, trap, electronic\nlo-fi hip hop, trap, emo rap\nlo-fi hip hop, trap, emotional\nlo-fi hip hop, trap, emotional R&B\nlo-fi hip hop, trap, emotional pop\nlo-fi hip hop, trap, emotional rap\nlo-fi hip hop, trap, ethereal\nlo-fi hip hop, trap, ethereal R&B\nlo-fi hip hop, trap, experimental\nlo-fi hip hop, trap, free jazz\nlo-fi hip hop, trap, funk\nlo-fi hip hop, trap, glitch\nlo-fi hip hop, trap, glitch hop\nlo-fi hip hop, trap, gospel\nlo-fi hip hop, trap, hardstyle\nlo-fi hip hop, trap, hyperpop\nlo-fi hip hop, trap, hyperpop, rock\nlo-fi hip hop, trap, industrial\nlo-fi hip hop, trap, jazz\nlo-fi hip hop, trap, jazz fusion\nlo-fi hip hop, trap, jazz hip hop\nlo-fi hip hop, trap, jazz rap\nlo-fi hip hop, trap, jazzy boom-bap\nlo-fi hip hop, trap, melodic rap\nlo-fi hip hop, trap, musical comedy\nlo-fi hip hop, trap, neo-soul\nlo-fi hip hop, trap, noir jazz\nlo-fi hip hop, trap, parody\nlo-fi hip hop, trap, phonk\nlo-fi hip hop, trap, pop\nlo-fi hip hop, trap, pop-rap\nlo-fi hip hop, trap, psychedelic\nlo-fi hip hop, trap, reggaeton\nlo-fi hip hop, trap, rock\nlo-fi hip hop, trap, soul\nlo-fi hip hop, trap, spoken word\nlo-fi hip hop, trap, synthwave\nlo-fi hip hop, trap, tango\nlo-fi hip hop, trap, traditional East Asian\nlo-fi hip hop, trap, traditional Southeast Asian\nlo-fi hip hop, trap, vaporwave\nlo-fi hip hop, trap, vintage ballad\nlo-fi hip hop, trap, world music\nlo-fi hip hop, trap-R&B\nlo-fi hip hop, trap-pop\nlo-fi hip hop, trap-soul\nlo-fi hip hop, tribal house\nlo-fi hip hop, trip-hop\nlo-fi hip hop, trip-hop, Arabic soul\nlo-fi hip hop, trip-hop, alternative R&B\nlo-fi hip hop, trip-hop, ambient\nlo-fi hip hop, trip-hop, conscious hip-hop\nlo-fi hip hop, trip-hop, experimental R&B\nlo-fi hip hop, trip-hop, psychedelic\nlo-fi hip hop, trip-hop, sad pop\nlo-fi hip hop, tropical house\nlo-fi hip hop, ukulele pop\nlo-fi hip hop, underground hip hop\nlo-fi hip hop, underground hip-hop\nlo-fi hip hop, underground rap\nlo-fi hip hop, vaporwave\nlo-fi hip hop, vaporwave, Arabic soul\nlo-fi hip hop, vaporwave, C-pop\nlo-fi hip hop, vaporwave, Catalan rap\nlo-fi hip hop, vaporwave, Chinese R&B\nlo-fi hip hop, vaporwave, Chinese ambient\nlo-fi hip hop, vaporwave, Chinese chillhop\nlo-fi hip hop, vaporwave, Chinese folk\nlo-fi hip hop, vaporwave, Chinese hip hop\nlo-fi hip hop, vaporwave, Chinese indie\nlo-fi hip hop, vaporwave, Chinese pop\nlo-fi hip hop, vaporwave, Chinese rap\nlo-fi hip hop, vaporwave, Chinese trap\nlo-fi hip hop, vaporwave, G-funk\nlo-fi hip hop, vaporwave, German rap\nlo-fi hip hop, vaporwave, K-R&B\nlo-fi hip hop, vaporwave, K-pop\nlo-fi hip hop, vaporwave, Latin rap\nlo-fi hip hop, vaporwave, Mongolian hip hop\nlo-fi hip hop, vaporwave, Polish rap\nlo-fi hip hop, vaporwave, R&B\nlo-fi hip hop, vaporwave, Russian rap\nlo-fi hip hop, vaporwave, Russian spoken word\nlo-fi hip hop, vaporwave, Southern hip-hop\nlo-fi hip hop, vaporwave, Turkish rap\nlo-fi hip hop, vaporwave, UK rap\nlo-fi hip hop, vaporwave, alternative rock\nlo-fi hip hop, vaporwave, ambient\nlo-fi hip hop, vaporwave, boom-bap\nlo-fi hip hop, vaporwave, breakbeat\nlo-fi hip hop, vaporwave, breakcore\nlo-fi hip hop, vaporwave, chill trap\nlo-fi hip hop, vaporwave, chiptune\nlo-fi hip hop, vaporwave, cinematic\nlo-fi hip hop, vaporwave, cloud rap\nlo-fi hip hop, vaporwave, conscious hip-hop\nlo-fi hip hop, vaporwave, educational hip hop\nlo-fi hip hop, vaporwave, electronic\nlo-fi hip hop, vaporwave, emo-rap\nlo-fi hip hop, vaporwave, emotional pop\nlo-fi hip hop, vaporwave, experimental\nlo-fi hip hop, vaporwave, experimental trap\nlo-fi hip hop, vaporwave, hybrid trap\nlo-fi hip hop, vaporwave, hyperpop\nlo-fi hip hop, vaporwave, indie rock\nlo-fi hip hop, vaporwave, jazz\nlo-fi hip hop, vaporwave, jazz fusion\nlo-fi hip hop, vaporwave, neo-soul\nlo-fi hip hop, vaporwave, pop-R&B\nlo-fi hip hop, vaporwave, pop-rap\nlo-fi hip hop, vaporwave, psychedelic\nlo-fi hip hop, vaporwave, rap\nlo-fi hip hop, vaporwave, rock\nlo-fi hip hop, vaporwave, synth-pop\nlo-fi hip hop, vaporwave, trap\nlo-fi hip hop, vaporwave, trap R&B\nlo-fi hip hop, vaporwave, trap-pop\nlo-fi hip hop, video game music\nlo-fi hip hop, world fusion\nlo-fi hip hop, world music, Islamic\nlo-fi hip hop, world music, R&B\nlo-fi hip hop, world music, ambient\nlo-fi hip hop, world music, chillhop\nlo-fi hip hop, world-trap\nlo-fi hip hop, wuxia, boom-bap\nlo-fi hip hop, 喊麦\nlo-fi hip-hop\nlo-fi hip-hop Afro-fusion\nlo-fi hip-hop Arabic\nlo-fi hip-hop Arabic R&B\nlo-fi hip-hop Arabic alternative pop\nlo-fi hip-hop Arabic pop\nlo-fi hip-hop Arabic pop German rap\nlo-fi hip-hop C-R&B\nlo-fi hip-hop C-pop\nlo-fi hip-hop C-pop Mandopop\nlo-fi hip-hop C-pop R&B\nlo-fi hip-hop C-pop acoustic\nlo-fi hip-hop C-pop ambient\nlo-fi hip-hop C-pop anime\nlo-fi hip-hop C-pop bossa nova\nlo-fi hip-hop C-pop chillwave\nlo-fi hip-hop C-pop chiptune\nlo-fi hip-hop C-pop cinematic\nlo-fi hip-hop C-pop dream pop\nlo-fi hip-hop C-pop emotional pop\nlo-fi hip-hop C-pop hyperpop\nlo-fi hip-hop C-pop pop-rock\nlo-fi hip-hop C-pop trap\nlo-fi hip-hop C-pop vaporwave\nlo-fi hip-hop Christian rap\nlo-fi hip-hop French R&B\nlo-fi hip-hop French R&B trap\nlo-fi hip-hop French pop\nlo-fi hip-hop French pop R&B\nlo-fi hip-hop French rap\nlo-fi hip-hop Indian\nlo-fi hip-hop Indian R&B\nlo-fi hip-hop Indian R&B trap\nlo-fi hip-hop Indian R&B vaporwave\nlo-fi hip-hop Indian classical\nlo-fi hip-hop Indian devotional\nlo-fi hip-hop Indian film music\nlo-fi hip-hop Indian folk\nlo-fi hip-hop Indian fusion\nlo-fi hip-hop Indian ghazal\nlo-fi hip-hop Indian pop\nlo-fi hip-hop Indian pop R&B\nlo-fi hip-hop Indian pop funk\nlo-fi hip-hop Indian pop trap\nlo-fi hip-hop Indian pop-R&B\nlo-fi hip-hop Indian pop-rap\nlo-fi hip-hop Indian sad pop\nlo-fi hip-hop Indian trap\nlo-fi hip-hop Islamic devotional\nlo-fi hip-hop J-R&B\nlo-fi hip-hop J-Rap\nlo-fi hip-hop J-pop\nlo-fi hip-hop J-pop R&B\nlo-fi hip-hop Japanese R&B\nlo-fi hip-hop K-R&B\nlo-fi hip-hop K-ballad\nlo-fi hip-hop K-pop\nlo-fi hip-hop K-pop R&B\nlo-fi hip-hop Latin\nlo-fi hip-hop Latin R&B\nlo-fi hip-hop Latin ballad\nlo-fi hip-hop Latin jazz\nlo-fi hip-hop Latin pop\nlo-fi hip-hop Mandopop\nlo-fi hip-hop Mandopop R&B\nlo-fi hip-hop Mandopop neo-soul\nlo-fi hip-hop Mediterranean\nlo-fi hip-hop Persian pop\nlo-fi hip-hop Persian pop trap\nlo-fi hip-hop Punjabi R&B\nlo-fi hip-hop Punjabi folk\nlo-fi hip-hop Punjabi pop\nlo-fi hip-hop R&B\nlo-fi hip-hop R&B Afrobeats\nlo-fi hip-hop R&B Caribbean\nlo-fi hip-hop R&B Indian pop\nlo-fi hip-hop R&B Indonesian pop\nlo-fi hip-hop R&B K-pop\nlo-fi hip-hop R&B Latin\nlo-fi hip-hop R&B Mandopop\nlo-fi hip-hop R&B Persian\nlo-fi hip-hop R&B Persian pop\nlo-fi hip-hop R&B acoustic\nlo-fi hip-hop R&B bedroom pop\nlo-fi hip-hop R&B bossa nova\nlo-fi hip-hop R&B chillwave\nlo-fi hip-hop R&B chiptune\nlo-fi hip-hop R&B dream pop\nlo-fi hip-hop R&B gospel\nlo-fi hip-hop R&B indie pop\nlo-fi hip-hop R&B rap\nlo-fi hip-hop R&B soul\nlo-fi hip-hop R&B trap\nlo-fi hip-hop Tamil pop\nlo-fi hip-hop Turkish pop\nlo-fi hip-hop V-Pop\nlo-fi hip-hop V-Pop R&B\nlo-fi hip-hop V-Pop ambient\nlo-fi hip-hop V-pop\nlo-fi hip-hop acid jazz\nlo-fi hip-hop acoustic\nlo-fi hip-hop acoustic C-pop\nlo-fi hip-hop acoustic R&B\nlo-fi hip-hop acoustic pop\nlo-fi hip-hop acoustic pop R&B\nlo-fi hip-hop acoustic pop-rap\nlo-fi hip-hop afro-soul\nlo-fi hip-hop afro-soul dancehall\nlo-fi hip-hop afro-trap\nlo-fi hip-hop afrobeat\nlo-fi hip-hop afrobeat R&B\nlo-fi hip-hop afrobeats\nlo-fi hip-hop afrobeats r&b\nlo-fi hip-hop alternative R&B\nlo-fi hip-hop alternative pop-rock\nlo-fi hip-hop alternative rap\nlo-fi hip-hop alternative rock\nlo-fi hip-hop alternative rock noise rock\nlo-fi hip-hop ambient\nlo-fi hip-hop ambient R&B\nlo-fi hip-hop ambient chillwave\nlo-fi hip-hop ambient chiptune\nlo-fi hip-hop ambient neoclassical\nlo-fi hip-hop ambient pop\nlo-fi hip-hop ambient pop dream pop\nlo-fi hip-hop ambient rock\nlo-fi hip-hop ambient trap\nlo-fi hip-hop bachata\nlo-fi hip-hop bedroom pop\nlo-fi hip-hop bilingual R&B\nlo-fi hip-hop blues rock\nlo-fi hip-hop blues-rock\nlo-fi hip-hop bossa nova\nlo-fi hip-hop bossa nova R&B\nlo-fi hip-hop bossa nova indie pop\nlo-fi hip-hop bossa nova neo-soul\nlo-fi hip-hop bossa nova r&b\nlo-fi hip-hop chill R&B\nlo-fi hip-hop chill trap\nlo-fi hip-hop chill-pop\nlo-fi hip-hop chill-pop future bass\nlo-fi hip-hop chillhop\nlo-fi hip-hop chillwave\nlo-fi hip-hop chillwave ambient\nlo-fi hip-hop chillwave downtempo\nlo-fi hip-hop chillwave future garage\nlo-fi hip-hop chillwave lounge\nlo-fi hip-hop chillwave trap\nlo-fi hip-hop chillwave vaporwave\nlo-fi hip-hop chiptune\nlo-fi hip-hop chiptune J-pop\nlo-fi hip-hop chiptune K-pop\nlo-fi hip-hop chiptune R&B\nlo-fi hip-hop chiptune city pop\nlo-fi hip-hop chiptune dream pop\nlo-fi hip-hop chiptune emo rap\nlo-fi hip-hop chiptune hyperpop\nlo-fi hip-hop chiptune indie pop\nlo-fi hip-hop chiptune kawaii future bass\nlo-fi hip-hop chiptune vaporwave\nlo-fi hip-hop cinematic\nlo-fi hip-hop cinematic ambient\nlo-fi hip-hop cinematic pop-rock\nlo-fi hip-hop cinematic trap\nlo-fi hip-hop city pop\nlo-fi hip-hop city pop R&B\nlo-fi hip-hop city pop chiptune\nlo-fi hip-hop city pop funk\nlo-fi hip-hop city pop j-pop\nlo-fi hip-hop city pop neo-soul\nlo-fi hip-hop city pop vaporwave\nlo-fi hip-hop classical\nlo-fi hip-hop cloud rap\nlo-fi hip-hop cloud rap dream pop\nlo-fi hip-hop conscious rap\nlo-fi hip-hop contemporary R&B\nlo-fi hip-hop cool jazz\nlo-fi hip-hop corridos tumbados\nlo-fi hip-hop country-folk\nlo-fi hip-hop dancehall\nlo-fi hip-hop dancehall afrobeats\nlo-fi hip-hop dark R&B\nlo-fi hip-hop dark pop\nlo-fi hip-hop dark techno\nlo-fi hip-hop dark trap\nlo-fi hip-hop dark trap ambient\nlo-fi hip-hop darkwave\nlo-fi hip-hop deep house\nlo-fi hip-hop dembow\nlo-fi hip-hop dream pop\nlo-fi hip-hop dream pop C-pop\nlo-fi hip-hop dream pop Mandopop\nlo-fi hip-hop dream pop R&B\nlo-fi hip-hop dream pop alternative R&B\nlo-fi hip-hop dream pop ambient\nlo-fi hip-hop dream pop chillwave\nlo-fi hip-hop dream pop cloud rap\nlo-fi hip-hop dream pop emo rap\nlo-fi hip-hop dream pop trap\nlo-fi hip-hop dream-pop\nlo-fi hip-hop dreamy R&B\nlo-fi hip-hop drill\nlo-fi hip-hop drum and bass\nlo-fi hip-hop electro house\nlo-fi hip-hop emo\nlo-fi hip-hop emo pop\nlo-fi hip-hop emo rap\nlo-fi hip-hop emo rap C-pop\nlo-fi hip-hop emo rap Indian pop\nlo-fi hip-hop emo rap J-pop\nlo-fi hip-hop emo rap Latin R&B\nlo-fi hip-hop emo rap Mandopop\nlo-fi hip-hop emo rap R&B\nlo-fi hip-hop emo rap alternative R&B\nlo-fi hip-hop emo rap alternative rock\nlo-fi hip-hop emo rap ambient\nlo-fi hip-hop emo rap bedroom pop\nlo-fi hip-hop emo rap chiptune\nlo-fi hip-hop emo rap cloud rap\nlo-fi hip-hop emo rap dream pop\nlo-fi hip-hop emo rap indie pop\nlo-fi hip-hop emo rap indie rock\nlo-fi hip-hop emo rap multilingual rap\nlo-fi hip-hop emo rock\nlo-fi hip-hop emo trap\nlo-fi hip-hop emo-pop\nlo-fi hip-hop emo-rap\nlo-fi hip-hop emo-rock\nlo-fi hip-hop emotional R&B\nlo-fi hip-hop emotional pop\nlo-fi hip-hop emotional rap\nlo-fi hip-hop emotional trap\nlo-fi hip-hop experimental\nlo-fi hip-hop experimental R&B\nlo-fi hip-hop experimental jazz\nlo-fi hip-hop experimental pop\nlo-fi hip-hop experimental trap\nlo-fi hip-hop fado\nlo-fi hip-hop flamenco\nlo-fi hip-hop flamenco fusion\nlo-fi hip-hop free-jazz\nlo-fi hip-hop funk\nlo-fi hip-hop funk Latin pop\nlo-fi hip-hop funk pop-rap\nlo-fi hip-hop funk rock\nlo-fi hip-hop funk-pop\nlo-fi hip-hop funk-rock\nlo-fi hip-hop future R&B\nlo-fi hip-hop future bass\nlo-fi hip-hop future bass Indian pop\nlo-fi hip-hop future bass R&B\nlo-fi hip-hop future bass neo-soul\nlo-fi hip-hop future bass trap\nlo-fi hip-hop future bass vaporwave\nlo-fi hip-hop future garage\nlo-fi hip-hop future garage chillwave\nlo-fi hip-hop glitch-hop\nlo-fi hip-hop gospel\nlo-fi hip-hop gospel R&B\nlo-fi hip-hop gospel rap\nlo-fi hip-hop gospel trap\nlo-fi hip-hop gospel world music\nlo-fi hip-hop horrorcore\nlo-fi hip-hop hyperpop\nlo-fi hip-hop indie\nlo-fi hip-hop indie R&B\nlo-fi hip-hop indie bedroom pop\nlo-fi hip-hop indie dance\nlo-fi hip-hop indie electronic\nlo-fi hip-hop indie folk\nlo-fi hip-hop indie pop\nlo-fi hip-hop indie pop French rap\nlo-fi hip-hop indie pop R&B\nlo-fi hip-hop indie pop contemporary R&B\nlo-fi hip-hop indie pop post-rock\nlo-fi hip-hop indie pop-rock\nlo-fi hip-hop indie rock\nlo-fi hip-hop indie rock post-rock\nlo-fi hip-hop indie-folk\nlo-fi hip-hop indie-pop\nlo-fi hip-hop indie-pop emo-rap\nlo-fi hip-hop indie-rock\nlo-fi hip-hop industrial indie rock\nlo-fi hip-hop industrial rock\nlo-fi hip-hop inspirational rap\nlo-fi hip-hop instrumental funk\nlo-fi hip-hop j-pop\nlo-fi hip-hop j-pop city pop\nlo-fi hip-hop j-rock\nlo-fi hip-hop jazz\nlo-fi hip-hop jazz fusion\nlo-fi hip-hop jazz fusion chiptune\nlo-fi hip-hop jazz rap\nlo-fi hip-hop jazz-funk\nlo-fi hip-hop jazz-hop\nlo-fi hip-hop jazz-hop chillhop\nlo-fi hip-hop jazz-hop trip-hop\nlo-fi hip-hop jazz-rap\nlo-fi hip-hop jazzy\nlo-fi hip-hop jazzy R&B\nlo-fi hip-hop jazzy lounge\nlo-fi hip-hop kawaii\nlo-fi hip-hop kawaii future bass\nlo-fi hip-hop latin\nlo-fi hip-hop latin jazz\nlo-fi hip-hop liquid drum and bass\nlo-fi hip-hop lounge\nlo-fi hip-hop lounge jazz\nlo-fi hip-hop mandopop\nlo-fi hip-hop mandopop chiptune\nlo-fi hip-hop mandopop emo rap\nlo-fi hip-hop math rock\nlo-fi hip-hop melodic trap\nlo-fi hip-hop metal\nlo-fi hip-hop metalcore\nlo-fi hip-hop neo-classical\nlo-fi hip-hop neo-soul\nlo-fi hip-hop neo-soul Afrobeat\nlo-fi hip-hop neo-soul C-pop\nlo-fi hip-hop neo-soul Cantopop\nlo-fi hip-hop neo-soul J-pop\nlo-fi hip-hop neo-soul K-hip-hop\nlo-fi hip-hop neo-soul alternative rock\nlo-fi hip-hop neo-soul chillwave\nlo-fi hip-hop neo-soul chiptune\nlo-fi hip-hop neo-soul city pop\nlo-fi hip-hop neo-soul experimental R&B\nlo-fi hip-hop neo-soul funk\nlo-fi hip-hop neo-soul jazz\nlo-fi hip-hop neo-soul jazz fusion\nlo-fi hip-hop neo-soul reggae\nlo-fi hip-hop noise rock\nlo-fi hip-hop nu-disco\nlo-fi hip-hop nu-disco funk\nlo-fi hip-hop nu-jazz\nlo-fi hip-hop nu-metal\nlo-fi hip-hop nu-metal punk\nlo-fi hip-hop orchestral\nlo-fi hip-hop orchestral pop\nlo-fi hip-hop phonk\nlo-fi hip-hop pop\nlo-fi hip-hop pop-R&B\nlo-fi hip-hop pop-punk\nlo-fi hip-hop pop-rap\nlo-fi hip-hop pop-rock\nlo-fi hip-hop post-punk\nlo-fi hip-hop post-rock\nlo-fi hip-hop progressive metal\nlo-fi hip-hop psychedelic R&B\nlo-fi hip-hop psychedelic electronica\nlo-fi hip-hop psychedelic funk\nlo-fi hip-hop psychedelic rock\nlo-fi hip-hop punk\nlo-fi hip-hop punk rock\nlo-fi hip-hop rap-rock\nlo-fi hip-hop reggae\nlo-fi hip-hop reggae French rap\nlo-fi hip-hop reggae R&B\nlo-fi hip-hop reggae fusion\nlo-fi hip-hop reggae-pop\nlo-fi hip-hop reggaeton\nlo-fi hip-hop retro pop\nlo-fi hip-hop rock\nlo-fi hip-hop sad rap\nlo-fi hip-hop sad trap\nlo-fi hip-hop sadcore\nlo-fi hip-hop samba\nlo-fi hip-hop sentimental pop\nlo-fi hip-hop sentimental pop-rap\nlo-fi hip-hop shoegaze\nlo-fi hip-hop smooth jazz\nlo-fi hip-hop soul\nlo-fi hip-hop soul-rock\nlo-fi hip-hop spiritual\nlo-fi hip-hop spiritual R&B\nlo-fi hip-hop spiritual pop\nlo-fi hip-hop swing jazz\nlo-fi hip-hop synth-pop\nlo-fi hip-hop synthwave\nlo-fi hip-hop tango\nlo-fi hip-hop trap\nlo-fi hip-hop trap C-pop\nlo-fi hip-hop trap Indian pop\nlo-fi hip-hop trap Mandopop\nlo-fi hip-hop trap R&B\nlo-fi hip-hop trap alternative R&B\nlo-fi hip-hop trap ambient\nlo-fi hip-hop trap ambient R&B\nlo-fi hip-hop trap ambient pop\nlo-fi hip-hop trap cinematic\nlo-fi hip-hop trap dream pop\nlo-fi hip-hop trap experimental pop\nlo-fi hip-hop trap soul\nlo-fi hip-hop trap vaporwave\nlo-fi hip-hop trap world music\nlo-fi hip-hop trap-soul\nlo-fi hip-hop trip-hop\nlo-fi hip-hop trip-hop R&B\nlo-fi hip-hop trip-hop jazz\nlo-fi hip-hop tropical\nlo-fi hip-hop uk garage\nlo-fi hip-hop vaporwave\nlo-fi hip-hop vaporwave city pop\nlo-fi hip-hop world music\nlo-fi hip-hop, 90s R&B\nlo-fi hip-hop, Afrobeats\nlo-fi hip-hop, Arabic pop\nlo-fi hip-hop, Arabic pop, R&B\nlo-fi hip-hop, Arabic pop, rap\nlo-fi hip-hop, Arabic rap\nlo-fi hip-hop, Arabic soul\nlo-fi hip-hop, Arabic vocal\nlo-fi hip-hop, Balkan R&B\nlo-fi hip-hop, Bengali pop\nlo-fi hip-hop, Bollywood\nlo-fi hip-hop, Bollywood pop\nlo-fi hip-hop, Bollywood, ambient\nlo-fi hip-hop, Brazilian\nlo-fi hip-hop, Brazilian MPB\nlo-fi hip-hop, Brazilian R&B\nlo-fi hip-hop, Brazilian R&B, neo-soul\nlo-fi hip-hop, Brazilian R&B, sad trap\nlo-fi hip-hop, Brazilian R&B, trap\nlo-fi hip-hop, Brazilian R&B, trap R&B\nlo-fi hip-hop, Brazilian funk\nlo-fi hip-hop, Brazilian pop\nlo-fi hip-hop, Brazilian pop, R&B\nlo-fi hip-hop, Brazilian pop, funk carioca\nlo-fi hip-hop, Brazilian pop, neo-soul\nlo-fi hip-hop, Brazilian pop-R&B\nlo-fi hip-hop, Brazilian pop-rap\nlo-fi hip-hop, Brazilian rap\nlo-fi hip-hop, Brazilian trap\nlo-fi hip-hop, C-Pop R&B\nlo-fi hip-hop, C-Rap\nlo-fi hip-hop, C-pop\nlo-fi hip-hop, C-pop R&B\nlo-fi hip-hop, C-pop ballad\nlo-fi hip-hop, C-pop rap\nlo-fi hip-hop, C-pop, Ancient Style\nlo-fi hip-hop, C-pop, Guofeng\nlo-fi hip-hop, C-pop, Mandopop\nlo-fi hip-hop, C-pop, R&B\nlo-fi hip-hop, C-pop, ambient\nlo-fi hip-hop, C-pop, ballad\nlo-fi hip-hop, C-pop, bedroom pop\nlo-fi hip-hop, C-pop, chillwave\nlo-fi hip-hop, C-pop, chiptune\nlo-fi hip-hop, C-pop, cinematic\nlo-fi hip-hop, C-pop, dream pop\nlo-fi hip-hop, C-pop, indie folk\nlo-fi hip-hop, C-pop, indie pop\nlo-fi hip-hop, C-pop, introspective\nlo-fi hip-hop, C-pop, melancholic\nlo-fi hip-hop, C-pop, pop-rock\nlo-fi hip-hop, C-pop, rap\nlo-fi hip-hop, C-pop, rock\nlo-fi hip-hop, C-pop, romantic R&B\nlo-fi hip-hop, C-pop, romantic ballad\nlo-fi hip-hop, C-pop, traditional Chinese\nlo-fi hip-hop, C-pop, trap\nlo-fi hip-hop, C-pop, video game music\nlo-fi hip-hop, Central Asian folk\nlo-fi hip-hop, Central Asian pop\nlo-fi hip-hop, Central Asian, melancholic\nlo-fi hip-hop, Chinese folk\nlo-fi hip-hop, Chinese folk, melancholic\nlo-fi hip-hop, Chinese fusion\nlo-fi hip-hop, Chinese hip-hop\nlo-fi hip-hop, Chinese opera, cinematic\nlo-fi hip-hop, Chinese pop\nlo-fi hip-hop, Chinese rap\nlo-fi hip-hop, Chinese traditional\nlo-fi hip-hop, Chinese traditional, melancholic\nlo-fi hip-hop, Christian R&B\nlo-fi hip-hop, Christian rock\nlo-fi hip-hop, Christmas ballad\nlo-fi hip-hop, Christmas pop\nlo-fi hip-hop, Danish R&B\nlo-fi hip-hop, Dutch pop-rap\nlo-fi hip-hop, East African R&B, gospel\nlo-fi hip-hop, East Asian rap\nlo-fi hip-hop, Eastern European folk\nlo-fi hip-hop, Eastern European pop\nlo-fi hip-hop, Filipino R&B\nlo-fi hip-hop, Filipino pop-rap\nlo-fi hip-hop, French R&B\nlo-fi hip-hop, French R&B, trap\nlo-fi hip-hop, French chanson\nlo-fi hip-hop, French cloud rap\nlo-fi hip-hop, French cloud rap, R&B\nlo-fi hip-hop, French indie pop\nlo-fi hip-hop, French pop\nlo-fi hip-hop, French pop, sad R&B\nlo-fi hip-hop, French pop, trap\nlo-fi hip-hop, French pop-rap\nlo-fi hip-hop, French rap\nlo-fi hip-hop, G-funk\nlo-fi hip-hop, German R&B\nlo-fi hip-hop, German cloud rap\nlo-fi hip-hop, German pop-R&B\nlo-fi hip-hop, German pop-rap\nlo-fi hip-hop, German pop-rap, neo-soul\nlo-fi hip-hop, Greek trap\nlo-fi hip-hop, IDM\nlo-fi hip-hop, Indian Pop, R&B\nlo-fi hip-hop, Indian R&B\nlo-fi hip-hop, Indian ambient\nlo-fi hip-hop, Indian classical\nlo-fi hip-hop, Indian classical, R&B\nlo-fi hip-hop, Indian classical, ambient\nlo-fi hip-hop, Indian classical, cinematic\nlo-fi hip-hop, Indian classical, romantic\nlo-fi hip-hop, Indian classical, vaporwave\nlo-fi hip-hop, Indian devotional\nlo-fi hip-hop, Indian film music, chiptune\nlo-fi hip-hop, Indian folk\nlo-fi hip-hop, Indian folk, ambient\nlo-fi hip-hop, Indian folk, world fusion\nlo-fi hip-hop, Indian fusion\nlo-fi hip-hop, Indian indie pop\nlo-fi hip-hop, Indian pop\nlo-fi hip-hop, Indian pop, R&B\nlo-fi hip-hop, Indian pop, UK rap\nlo-fi hip-hop, Indian pop, alternative R&B\nlo-fi hip-hop, Indian pop, blues-rock\nlo-fi hip-hop, Indian pop, chiptune\nlo-fi hip-hop, Indian pop, emo rap\nlo-fi hip-hop, Indian pop, flamenco\nlo-fi hip-hop, Indian pop, indie guitar\nlo-fi hip-hop, Indian pop, trap\nlo-fi hip-hop, Indian pop-rap\nlo-fi hip-hop, Indonesian pop\nlo-fi hip-hop, Islamic devotional\nlo-fi hip-hop, Italian alternative R&B\nlo-fi hip-hop, Italian indie pop\nlo-fi hip-hop, Italian pop\nlo-fi hip-hop, Italian pop-rap\nlo-fi hip-hop, J-hip-hop\nlo-fi hip-hop, J-pop\nlo-fi hip-hop, J-pop, C-pop\nlo-fi hip-hop, J-pop, Chinese rap\nlo-fi hip-hop, J-pop, J-rock\nlo-fi hip-hop, J-pop, R&B\nlo-fi hip-hop, J-pop, alternative rock\nlo-fi hip-hop, J-pop, ambient\nlo-fi hip-hop, J-pop, anime\nlo-fi hip-hop, J-pop, chiptune\nlo-fi hip-hop, J-pop, hip-hop\nlo-fi hip-hop, J-pop, pop-rap\nlo-fi hip-hop, J-pop, pop-rock\nlo-fi hip-hop, J-rock\nlo-fi hip-hop, J-rock, J-pop\nlo-fi hip-hop, J-rock, Japanese rap\nlo-fi hip-hop, J-rock, emotional pop\nlo-fi hip-hop, J-rock, hip-hop fusion\nlo-fi hip-hop, J-rock, shoegaze\nlo-fi hip-hop, Japanese RPG, cinematic\nlo-fi hip-hop, Jersey club\nlo-fi hip-hop, K-R&B\nlo-fi hip-hop, K-R&B, Christmas\nlo-fi hip-hop, K-R&B, chiptune\nlo-fi hip-hop, K-R&B, emo rap\nlo-fi hip-hop, K-R&B, pop-rap\nlo-fi hip-hop, K-hip-hop, Latin pop\nlo-fi hip-hop, K-hip-hop, chill R&B\nlo-fi hip-hop, K-indie, dream pop\nlo-fi hip-hop, K-pop\nlo-fi hip-hop, K-pop ballad, pop-rap\nlo-fi hip-hop, K-pop rap\nlo-fi hip-hop, K-pop, R&B\nlo-fi hip-hop, K-pop, ambient\nlo-fi hip-hop, Korean R&B\nlo-fi hip-hop, Korean rap\nlo-fi hip-hop, Korean rock\nlo-fi hip-hop, Latin R&B\nlo-fi hip-hop, Latin R&B, bedroom pop\nlo-fi hip-hop, Latin R&B, chiptune\nlo-fi hip-hop, Latin R&B, rap\nlo-fi hip-hop, Latin R&B, reggaeton\nlo-fi hip-hop, Latin R&B, sad trap\nlo-fi hip-hop, Latin R&B, trap\nlo-fi hip-hop, Latin alternative\nlo-fi hip-hop, Latin alternative R&B\nlo-fi hip-hop, Latin alternative pop\nlo-fi hip-hop, Latin alternative rock\nlo-fi hip-hop, Latin alternative, indie pop\nlo-fi hip-hop, Latin ballad\nlo-fi hip-hop, Latin folk\nlo-fi hip-hop, Latin house\nlo-fi hip-hop, Latin jazz\nlo-fi hip-hop, Latin jazz, Mandopop\nlo-fi hip-hop, Latin melancholy\nlo-fi hip-hop, Latin pop\nlo-fi hip-hop, Latin pop, R&B\nlo-fi hip-hop, Latin pop, neo-soul\nlo-fi hip-hop, Latin pop-rap\nlo-fi hip-hop, Latin rap\nlo-fi hip-hop, Latin rap, vaporwave\nlo-fi hip-hop, Latin salsa\nlo-fi hip-hop, Latin trap\nlo-fi hip-hop, Latin, East Asian\nlo-fi hip-hop, Latin, acoustic\nlo-fi hip-hop, Latin, melancholic\nlo-fi hip-hop, MPB\nlo-fi hip-hop, MPB, indie rock\nlo-fi hip-hop, MPB, neo-soul\nlo-fi hip-hop, Mandarin pop, dream pop\nlo-fi hip-hop, Mandopop\nlo-fi hip-hop, Mandopop R&B\nlo-fi hip-hop, Mandopop, R&B\nlo-fi hip-hop, Mandopop, Spanish flavor\nlo-fi hip-hop, Mandopop, acoustic\nlo-fi hip-hop, Mandopop, acoustic pop\nlo-fi hip-hop, Mandopop, ambient\nlo-fi hip-hop, Mandopop, chill R&B\nlo-fi hip-hop, Mandopop, chillwave\nlo-fi hip-hop, Mandopop, contemporary R&B\nlo-fi hip-hop, Mandopop, dream pop\nlo-fi hip-hop, Mandopop, emo rap\nlo-fi hip-hop, Mandopop, emotional ballad\nlo-fi hip-hop, Mandopop, pop-rock\nlo-fi hip-hop, Mandopop, romantic R&B\nlo-fi hip-hop, Middle Eastern\nlo-fi hip-hop, Middle Eastern, melancholic\nlo-fi hip-hop, Mongolian folk\nlo-fi hip-hop, Nepali pop\nlo-fi hip-hop, Nepali pop, R&B\nlo-fi hip-hop, Nepali pop-R&B\nlo-fi hip-hop, North African pop, R&B\nlo-fi hip-hop, North African, melancholic\nlo-fi hip-hop, North African, romantic\nlo-fi hip-hop, OPM\nlo-fi hip-hop, Persian music\nlo-fi hip-hop, Persian pop\nlo-fi hip-hop, Persian pop, R&B\nlo-fi hip-hop, Punjabi folk\nlo-fi hip-hop, Punjabi pop\nlo-fi hip-hop, Punjabi pop, R&B\nlo-fi hip-hop, Punjabi pop, emo rap\nlo-fi hip-hop, Punjabi rap\nlo-fi hip-hop, Punjabi, melancholic\nlo-fi hip-hop, R&B\nlo-fi hip-hop, R&B, Afrobeats\nlo-fi hip-hop, R&B, Arabic fusion\nlo-fi hip-hop, R&B, Arabic pop\nlo-fi hip-hop, R&B, Brazilian\nlo-fi hip-hop, R&B, Brazilian funk, pop\nlo-fi hip-hop, R&B, Brazilian pop\nlo-fi hip-hop, R&B, C-Pop\nlo-fi hip-hop, R&B, C-pop\nlo-fi hip-hop, R&B, Cantonese pop\nlo-fi hip-hop, R&B, Cantopop\nlo-fi hip-hop, R&B, Chinese traditional\nlo-fi hip-hop, R&B, Christian hip-hop\nlo-fi hip-hop, R&B, Christmas\nlo-fi hip-hop, R&B, Desi pop\nlo-fi hip-hop, R&B, East African\nlo-fi hip-hop, R&B, French cloud rap\nlo-fi hip-hop, R&B, French rap\nlo-fi hip-hop, R&B, German pop\nlo-fi hip-hop, R&B, Indian Pop\nlo-fi hip-hop, R&B, Indian ambient\nlo-fi hip-hop, R&B, Indian folk\nlo-fi hip-hop, R&B, Indian fusion\nlo-fi hip-hop, R&B, Indian pop\nlo-fi hip-hop, R&B, J-hip-hop\nlo-fi hip-hop, R&B, J-pop\nlo-fi hip-hop, R&B, K-Indie\nlo-fi hip-hop, R&B, K-R&B\nlo-fi hip-hop, R&B, K-hip-hop\nlo-fi hip-hop, R&B, K-pop\nlo-fi hip-hop, R&B, Latin pop\nlo-fi hip-hop, R&B, Latin rap\nlo-fi hip-hop, R&B, MPB\nlo-fi hip-hop, R&B, Mandarin ballad\nlo-fi hip-hop, R&B, Mandarin pop\nlo-fi hip-hop, R&B, Mandopop\nlo-fi hip-hop, R&B, Mongolian rap\nlo-fi hip-hop, R&B, Persian\nlo-fi hip-hop, R&B, Persian classical\nlo-fi hip-hop, R&B, Punjabi pop\nlo-fi hip-hop, R&B, South Asian\nlo-fi hip-hop, R&B, South Asian pop\nlo-fi hip-hop, R&B, T-Pop\nlo-fi hip-hop, R&B, Tamil pop\nlo-fi hip-hop, R&B, Thai pop\nlo-fi hip-hop, R&B, UK rap\nlo-fi hip-hop, R&B, V-Pop\nlo-fi hip-hop, R&B, Vietnamese pop\nlo-fi hip-hop, R&B, acoustic\nlo-fi hip-hop, R&B, acoustic pop\nlo-fi hip-hop, R&B, ambient\nlo-fi hip-hop, R&B, ambient pop\nlo-fi hip-hop, R&B, atmospheric\nlo-fi hip-hop, R&B, bedroom pop\nlo-fi hip-hop, R&B, bossa nova\nlo-fi hip-hop, R&B, breakcore\nlo-fi hip-hop, R&B, chill trap\nlo-fi hip-hop, R&B, chillhop\nlo-fi hip-hop, R&B, chillwave\nlo-fi hip-hop, R&B, chiptune\nlo-fi hip-hop, R&B, cinematic\nlo-fi hip-hop, R&B, cloud rap\nlo-fi hip-hop, R&B, conscious rap\nlo-fi hip-hop, R&B, dream pop\nlo-fi hip-hop, R&B, emo-rap\nlo-fi hip-hop, R&B, emotional pop\nlo-fi hip-hop, R&B, emotional pop-rap\nlo-fi hip-hop, R&B, experimental\nlo-fi hip-hop, R&B, future bass\nlo-fi hip-hop, R&B, hyperpop\nlo-fi hip-hop, R&B, indie pop\nlo-fi hip-hop, R&B, jazz\nlo-fi hip-hop, R&B, jazz-pop\nlo-fi hip-hop, R&B, melancholic pop\nlo-fi hip-hop, R&B, neo-soul\nlo-fi hip-hop, R&B, pop\nlo-fi hip-hop, R&B, pop-R&B\nlo-fi hip-hop, R&B, pop-rap\nlo-fi hip-hop, R&B, pop-rock\nlo-fi hip-hop, R&B, rap\nlo-fi hip-hop, R&B, sad pop\nlo-fi hip-hop, R&B, soul\nlo-fi hip-hop, R&B, spiritual hip-hop\nlo-fi hip-hop, R&B, trap\nlo-fi hip-hop, R&B, trap metal\nlo-fi hip-hop, R&B, trap soul\nlo-fi hip-hop, R&B, trap-soul\nlo-fi hip-hop, R&B, vaporwave\nlo-fi hip-hop, Russian chanson\nlo-fi hip-hop, Russian pop\nlo-fi hip-hop, Russian pop, R&B\nlo-fi hip-hop, Russian pop-rap\nlo-fi hip-hop, Russian post-punk\nlo-fi hip-hop, South African R&B, Afrobeats\nlo-fi hip-hop, South Asian\nlo-fi hip-hop, South Asian folk\nlo-fi hip-hop, South Asian fusion\nlo-fi hip-hop, South Asian pop\nlo-fi hip-hop, South Asian, melancholic\nlo-fi hip-hop, South Asian, romantic\nlo-fi hip-hop, South Indian folk\nlo-fi hip-hop, Southern rock, trap\nlo-fi hip-hop, Spanish indie pop\nlo-fi hip-hop, Spanish neo-soul\nlo-fi hip-hop, Spanish pop\nlo-fi hip-hop, Spanish pop-rap\nlo-fi hip-hop, Spanish-style, melancholic duet\nlo-fi hip-hop, Swedish pop-rap\nlo-fi hip-hop, T-Pop, R&B\nlo-fi hip-hop, Tamil R&B, chillwave\nlo-fi hip-hop, Tamil pop, R&B\nlo-fi hip-hop, Thai R&B\nlo-fi hip-hop, Thai pop\nlo-fi hip-hop, Turkish R&B\nlo-fi hip-hop, Turkish R&B, soul\nlo-fi hip-hop, Turkish alternative R&B\nlo-fi hip-hop, Turkish alternative pop\nlo-fi hip-hop, Turkish alternative rap\nlo-fi hip-hop, Turkish alternative rock\nlo-fi hip-hop, Turkish folk\nlo-fi hip-hop, Turkish pop\nlo-fi hip-hop, Turkish rap\nlo-fi hip-hop, Turkish, melancholic\nlo-fi hip-hop, UK drill\nlo-fi hip-hop, UK drill, Spanish fusion\nlo-fi hip-hop, UK garage\nlo-fi hip-hop, UK garage, future garage\nlo-fi hip-hop, UK rap\nlo-fi hip-hop, UK rap, atmospheric R&B\nlo-fi hip-hop, V-Pop\nlo-fi hip-hop, V-Pop, Christmas music\nlo-fi hip-hop, V-Pop, R&B\nlo-fi hip-hop, V-Pop, chill R&B\nlo-fi hip-hop, V-Pop, contemporary R&B\nlo-fi hip-hop, Vietnamese ballad\nlo-fi hip-hop, Vietnamese pop\nlo-fi hip-hop, Vietnamese pop, R&B\nlo-fi hip-hop, Vietnamese pop, rap\nlo-fi hip-hop, Vietnamese pop-R&B\nlo-fi hip-hop, Vietnamese pop-rap\nlo-fi hip-hop, Vocaloid, kawaii\nlo-fi hip-hop, acid jazz\nlo-fi hip-hop, acoustic J-pop\nlo-fi hip-hop, acoustic R&B\nlo-fi hip-hop, acoustic ballad\nlo-fi hip-hop, acoustic folk\nlo-fi hip-hop, acoustic pop\nlo-fi hip-hop, acoustic pop, K-indie\nlo-fi hip-hop, acoustic pop, Mandopop\nlo-fi hip-hop, acoustic pop, R&B\nlo-fi hip-hop, acoustic pop-rap\nlo-fi hip-hop, acoustic, bilingual\nlo-fi hip-hop, alternative R&B\nlo-fi hip-hop, alternative R&B, Indian classical\nlo-fi hip-hop, alternative R&B, Korean hip-hop\nlo-fi hip-hop, alternative R&B, Latin pop\nlo-fi hip-hop, alternative R&B, chillwave\nlo-fi hip-hop, alternative R&B, cinematic\nlo-fi hip-hop, alternative R&B, dream pop\nlo-fi hip-hop, alternative R&B, emo rap\nlo-fi hip-hop, alternative R&B, indie pop\nlo-fi hip-hop, alternative R&B, neo-soul\nlo-fi hip-hop, alternative R&B, soul\nlo-fi hip-hop, alternative R&B, trap\nlo-fi hip-hop, alternative R&B, vaporwave\nlo-fi hip-hop, alternative pop-rock\nlo-fi hip-hop, alternative rap\nlo-fi hip-hop, alternative rock\nlo-fi hip-hop, alternative rock, C-pop\nlo-fi hip-hop, alternative rock, J-pop\nlo-fi hip-hop, alternative rock, K-R&B\nlo-fi hip-hop, alternative rock, R&B\nlo-fi hip-hop, alternative rock, Russian rap\nlo-fi hip-hop, alternative rock, Russian spoken word\nlo-fi hip-hop, alternative rock, ambient\nlo-fi hip-hop, alternative rock, cinematic\nlo-fi hip-hop, alternative rock, ethereal pop\nlo-fi hip-hop, alternative rock, noise rock\nlo-fi hip-hop, alternative rock, nu-metal\nlo-fi hip-hop, ambient\nlo-fi hip-hop, ambient ballad\nlo-fi hip-hop, ambient piano, indie pop\nlo-fi hip-hop, ambient pop\nlo-fi hip-hop, ambient pop, Indian chillwave\nlo-fi hip-hop, ambient pop, chillwave\nlo-fi hip-hop, ambient pop, emotional rap\nlo-fi hip-hop, ambient techno, industrial rock\nlo-fi hip-hop, ambient, Bengali folk\nlo-fi hip-hop, ambient, C-pop\nlo-fi hip-hop, ambient, Indian indie\nlo-fi hip-hop, ambient, Mandopop\nlo-fi hip-hop, ambient, Nepali pop\nlo-fi hip-hop, ambient, Persian classical\nlo-fi hip-hop, ambient, Spanish rap\nlo-fi hip-hop, ambient, Tibetan folk\nlo-fi hip-hop, ambient, cinematic\nlo-fi hip-hop, ambient, hyperpop\nlo-fi hip-hop, ambient, melancholic\nlo-fi hip-hop, ambient, sad pop\nlo-fi hip-hop, ambient, traditional Chinese\nlo-fi hip-hop, ambient, trap R&B\nlo-fi hip-hop, anime pop\nlo-fi hip-hop, anime-pop, ambient\nlo-fi hip-hop, art-pop\nlo-fi hip-hop, art-pop, J-pop\nlo-fi hip-hop, atmospheric R&B\nlo-fi hip-hop, atmospheric pop\nlo-fi hip-hop, atmospheric pop, C-pop\nlo-fi hip-hop, atmospheric rock\nlo-fi hip-hop, atmospheric synth-pop\nlo-fi hip-hop, ballad\nlo-fi hip-hop, ballad, C-pop\nlo-fi hip-hop, ballad, Vietnamese pop\nlo-fi hip-hop, baroque, choral\nlo-fi hip-hop, bedroom pop\nlo-fi hip-hop, bedroom pop, C-pop\nlo-fi hip-hop, bedroom pop, Latin pop\nlo-fi hip-hop, bedroom pop, chiptune\nlo-fi hip-hop, bedroom pop, emo rap\nlo-fi hip-hop, bedroom pop, experimental\nlo-fi hip-hop, bedroom pop, modern R&B\nlo-fi hip-hop, bedroom pop, shoegaze\nlo-fi hip-hop, big band jazz\nlo-fi hip-hop, bilingual R&B\nlo-fi hip-hop, bilingual hip-hop\nlo-fi hip-hop, bilingual pop\nlo-fi hip-hop, bilingual pop-rap\nlo-fi hip-hop, bilingual trap\nlo-fi hip-hop, blues-rock\nlo-fi hip-hop, boom-bap, ragtime\nlo-fi hip-hop, boom-bap, rock\nlo-fi hip-hop, bossa nova\nlo-fi hip-hop, bossa nova, C-pop\nlo-fi hip-hop, bossa nova, soulful R&B\nlo-fi hip-hop, breakbeat, neurofunk\nlo-fi hip-hop, breakcore, R&B\nlo-fi hip-hop, breakcore, ambient\nlo-fi hip-hop, breakcore, experimental\nlo-fi hip-hop, brostep\nlo-fi hip-hop, children's music, Mandarin pop\nlo-fi hip-hop, chill R&B\nlo-fi hip-hop, chill R&B, C-pop\nlo-fi hip-hop, chill R&B, Mandopop\nlo-fi hip-hop, chill R&B, ambient\nlo-fi hip-hop, chill R&B, dream pop\nlo-fi hip-hop, chill R&B, neo-soul\nlo-fi hip-hop, chill R&B, vaporwave\nlo-fi hip-hop, chill trap\nlo-fi hip-hop, chill trap, ambient\nlo-fi hip-hop, chill-pop\nlo-fi hip-hop, chillhop\nlo-fi hip-hop, chillhop, C-Pop R&B\nlo-fi hip-hop, chillhop, C-R&B\nlo-fi hip-hop, chillhop, C-pop\nlo-fi hip-hop, chillhop, East Asian\nlo-fi hip-hop, chillhop, K-hip-hop\nlo-fi hip-hop, chillhop, Mandopop\nlo-fi hip-hop, chillhop, lo-fi R&B\nlo-fi hip-hop, chillwave\nlo-fi hip-hop, chillwave, Brazilian pop-rap\nlo-fi hip-hop, chillwave, C-pop\nlo-fi hip-hop, chillwave, East Asian pop\nlo-fi hip-hop, chillwave, French pop\nlo-fi hip-hop, chillwave, Indian pop\nlo-fi hip-hop, chillwave, Indian pop-R&B\nlo-fi hip-hop, chillwave, J-pop\nlo-fi hip-hop, chillwave, K-indie\nlo-fi hip-hop, chillwave, Latin R&B\nlo-fi hip-hop, chillwave, Mandopop\nlo-fi hip-hop, chillwave, R&B\nlo-fi hip-hop, chillwave, South Asian pop\nlo-fi hip-hop, chillwave, alternative R&B\nlo-fi hip-hop, chillwave, ambient\nlo-fi hip-hop, chillwave, cinematic rock\nlo-fi hip-hop, chillwave, cloud rap\nlo-fi hip-hop, chillwave, future bass\nlo-fi hip-hop, chillwave, future garage\nlo-fi hip-hop, chillwave, glitch-hop\nlo-fi hip-hop, chillwave, hyperpop\nlo-fi hip-hop, chillwave, indie R&B\nlo-fi hip-hop, chillwave, indie rock\nlo-fi hip-hop, chillwave, liquid drum and bass\nlo-fi hip-hop, chillwave, neo-soul\nlo-fi hip-hop, chillwave, pop-rap\nlo-fi hip-hop, chillwave, romantic pop\nlo-fi hip-hop, chillwave, romantic pop-rap\nlo-fi hip-hop, chillwave, shoegaze\nlo-fi hip-hop, chillwave, synthwave\nlo-fi hip-hop, chiptune\nlo-fi hip-hop, chiptune, C-pop\nlo-fi hip-hop, chiptune, J-pop\nlo-fi hip-hop, chiptune, K-pop\nlo-fi hip-hop, chiptune, Mandopop\nlo-fi hip-hop, chiptune, R&B\nlo-fi hip-hop, chiptune, Russian pop\nlo-fi hip-hop, chiptune, Thai pop\nlo-fi hip-hop, chiptune, bedroom pop\nlo-fi hip-hop, chiptune, electronic\nlo-fi hip-hop, chiptune, emo-rap\nlo-fi hip-hop, chiptune, future bass\nlo-fi hip-hop, chiptune, hyperpop\nlo-fi hip-hop, chiptune, nu-disco\nlo-fi hip-hop, chiptune, pop-punk\nlo-fi hip-hop, chiptune, pop-rap\nlo-fi hip-hop, chiptune, rock\nlo-fi hip-hop, chiptune, trap\nlo-fi hip-hop, choral, blues\nlo-fi hip-hop, cinematic\nlo-fi hip-hop, cinematic R&B, ambient\nlo-fi hip-hop, cinematic ambient\nlo-fi hip-hop, cinematic ambient, jazz\nlo-fi hip-hop, cinematic ballad\nlo-fi hip-hop, cinematic classical, sadcore\nlo-fi hip-hop, cinematic jazz, fusion\nlo-fi hip-hop, cinematic orchestral\nlo-fi hip-hop, cinematic piano, pop-rap\nlo-fi hip-hop, cinematic pop, emotional ballad\nlo-fi hip-hop, cinematic pop-rap\nlo-fi hip-hop, cinematic rock\nlo-fi hip-hop, cinematic rock, Arabic indie\nlo-fi hip-hop, cinematic rock, metalcore\nlo-fi hip-hop, cinematic rock, rap\nlo-fi hip-hop, cinematic, Azerbaijani folk\nlo-fi hip-hop, cinematic, C-pop\nlo-fi hip-hop, cinematic, Chinese traditional\nlo-fi hip-hop, cinematic, East Asian\nlo-fi hip-hop, cinematic, French cloud rap\nlo-fi hip-hop, cinematic, Indian fusion\nlo-fi hip-hop, cinematic, Middle Eastern\nlo-fi hip-hop, cinematic, Spanish ballad\nlo-fi hip-hop, cinematic, ambient\nlo-fi hip-hop, cinematic, chillwave\nlo-fi hip-hop, cinematic, dizi\nlo-fi hip-hop, cinematic, melancholic\nlo-fi hip-hop, cinematic, metalcore\nlo-fi hip-hop, cinematic, orchestral\nlo-fi hip-hop, cinematic, rock\nlo-fi hip-hop, cinematic, trap\nlo-fi hip-hop, city pop\nlo-fi hip-hop, city pop, C-pop\nlo-fi hip-hop, city pop, J-pop\nlo-fi hip-hop, city pop, Mandopop\nlo-fi hip-hop, city pop, indie pop\nlo-fi hip-hop, city pop, kawaii\nlo-fi hip-hop, city pop, lounge\nlo-fi hip-hop, city pop, vaporwave\nlo-fi hip-hop, cloud rap\nlo-fi hip-hop, cloud rap, Brazilian trap\nlo-fi hip-hop, cloud rap, C-pop\nlo-fi hip-hop, cloud rap, Japanese rap\nlo-fi hip-hop, cloud rap, Mandopop\nlo-fi hip-hop, cloud rap, R&B\nlo-fi hip-hop, cloud rap, alternative R&B\nlo-fi hip-hop, cloud rap, art-pop\nlo-fi hip-hop, cloud rap, chillwave\nlo-fi hip-hop, cloud rap, chiptune\nlo-fi hip-hop, cloud rap, dream pop\nlo-fi hip-hop, cloud rap, emo rap\nlo-fi hip-hop, cloud rap, emo trap\nlo-fi hip-hop, cloud rap, emo-rap\nlo-fi hip-hop, cloud rap, emotional R&B\nlo-fi hip-hop, cloud rap, hyperpop\nlo-fi hip-hop, cloud rap, indie guitar\nlo-fi hip-hop, cloud rap, indie pop\nlo-fi hip-hop, cloud rap, jazz\nlo-fi hip-hop, cloud rap, psychedelic\nlo-fi hip-hop, cloud rap, trap\nlo-fi hip-hop, cloud rap, vaporwave\nlo-fi hip-hop, cloud rap, video game music\nlo-fi hip-hop, complextro\nlo-fi hip-hop, conscious R&B\nlo-fi hip-hop, conscious UK rap\nlo-fi hip-hop, conscious hip-hop\nlo-fi hip-hop, conscious hip-hop, R&B\nlo-fi hip-hop, conscious rap\nlo-fi hip-hop, conscious rap, Latin-influenced\nlo-fi hip-hop, conscious reggae\nlo-fi hip-hop, contemporary R&B\nlo-fi hip-hop, contemporary R&B, Afrobeat\nlo-fi hip-hop, contemporary R&B, French rap\nlo-fi hip-hop, contemporary R&B, North African\nlo-fi hip-hop, contemporary R&B, South Asian\nlo-fi hip-hop, contemporary R&B, South Asian pop\nlo-fi hip-hop, contemporary R&B, cloud rap\nlo-fi hip-hop, contemporary R&B, dancehall\nlo-fi hip-hop, contemporary R&B, dream pop\nlo-fi hip-hop, contemporary R&B, gospel\nlo-fi hip-hop, contemporary R&B, pop-rap\nlo-fi hip-hop, contemporary R&B, smooth jazz\nlo-fi hip-hop, dance-pop\nlo-fi hip-hop, dance-pop, EDM\nlo-fi hip-hop, dancehall, R&B\nlo-fi hip-hop, dancehall, trap\nlo-fi hip-hop, dark trap\nlo-fi hip-hop, deep house, pop-R&B\nlo-fi hip-hop, downtempo\nlo-fi hip-hop, downtempo R&B\nlo-fi hip-hop, dream pop\nlo-fi hip-hop, dream pop, C-pop\nlo-fi hip-hop, dream pop, Mandopop\nlo-fi hip-hop, dream pop, R&B\nlo-fi hip-hop, dream pop, alternative R&B\nlo-fi hip-hop, dream pop, ambient\nlo-fi hip-hop, dream pop, ambient rock\nlo-fi hip-hop, dream pop, cloud rap\nlo-fi hip-hop, dream pop, emo rap\nlo-fi hip-hop, dream pop, experimental\nlo-fi hip-hop, dream pop, experimental pop\nlo-fi hip-hop, dream pop, indie rock\nlo-fi hip-hop, dream pop, pop-rock\nlo-fi hip-hop, dream pop, shoegaze\nlo-fi hip-hop, dream pop, trap\nlo-fi hip-hop, dream-pop, future bass\nlo-fi hip-hop, dreamy R&B\nlo-fi hip-hop, dreamy R&B, Mandarin rap\nlo-fi hip-hop, dreamy indie pop\nlo-fi hip-hop, dreamy pop\nlo-fi hip-hop, drill\nlo-fi hip-hop, drum and bass\nlo-fi hip-hop, drum and bass, ambient\nlo-fi hip-hop, drum and bass, breakcore\nlo-fi hip-hop, drum and bass, jazz\nlo-fi hip-hop, drum and bass, neurofunk\nlo-fi hip-hop, dubstep\nlo-fi hip-hop, dubstep, R&B\nlo-fi hip-hop, dubstep, anime\nlo-fi hip-hop, dubstep, brostep\nlo-fi hip-hop, dubstep, chiptune\nlo-fi hip-hop, dubstep, cinematic\nlo-fi hip-hop, dubstep, future bass\nlo-fi hip-hop, dubstep, glitch hop\nlo-fi hip-hop, dubstep, glitch-hop\nlo-fi hip-hop, dubstep, metal\nlo-fi hip-hop, electro-funk\nlo-fi hip-hop, electro-house, Spanish rap\nlo-fi hip-hop, electro-rock\nlo-fi hip-hop, electronic pop\nlo-fi hip-hop, electronic, hyperpop\nlo-fi hip-hop, emo rap\nlo-fi hip-hop, emo rap, C-pop\nlo-fi hip-hop, emo rap, Latin pop\nlo-fi hip-hop, emo rap, Mandopop\nlo-fi hip-hop, emo rap, R&B\nlo-fi hip-hop, emo rap, V-Pop\nlo-fi hip-hop, emo rap, acoustic folk\nlo-fi hip-hop, emo rap, acoustic pop\nlo-fi hip-hop, emo rap, alternative rock\nlo-fi hip-hop, emo rap, ambient pop\nlo-fi hip-hop, emo rap, bedroom pop\nlo-fi hip-hop, emo rap, cloud rap\nlo-fi hip-hop, emo rap, dream pop\nlo-fi hip-hop, emo rap, sad pop\nlo-fi hip-hop, emo rap, synth-pop\nlo-fi hip-hop, emo rock\nlo-fi hip-hop, emo-pop\nlo-fi hip-hop, emo-rap\nlo-fi hip-hop, emo-rap, C-pop\nlo-fi hip-hop, emo-rap, Nepali rap\nlo-fi hip-hop, emo-rap, blues-rock\nlo-fi hip-hop, emo-rap, pop-punk\nlo-fi hip-hop, emo-rock\nlo-fi hip-hop, emotional C-pop\nlo-fi hip-hop, emotional C-pop rap\nlo-fi hip-hop, emotional K-hip-hop\nlo-fi hip-hop, emotional R&B\nlo-fi hip-hop, emotional R&B, trap\nlo-fi hip-hop, emotional hyperpop, ambient rap\nlo-fi hip-hop, emotional indie pop\nlo-fi hip-hop, emotional pop\nlo-fi hip-hop, emotional pop, R&B\nlo-fi hip-hop, emotional pop, rap\nlo-fi hip-hop, emotional pop, trap\nlo-fi hip-hop, emotional pop, world music\nlo-fi hip-hop, emotional pop-R&B\nlo-fi hip-hop, emotional pop-rap\nlo-fi hip-hop, emotional pop-rock\nlo-fi hip-hop, emotional rap\nlo-fi hip-hop, emotional rock\nlo-fi hip-hop, emotional trap\nlo-fi hip-hop, emotional trap, C-pop\nlo-fi hip-hop, emotional trap, R&B\nlo-fi hip-hop, emotional trap, hyperpop\nlo-fi hip-hop, ethereal R&B\nlo-fi hip-hop, ethereal pop\nlo-fi hip-hop, experimental rock, French indie\nlo-fi hip-hop, experimental trap, Arabic ambient\nlo-fi hip-hop, folk\nlo-fi hip-hop, folk, Indian\nlo-fi hip-hop, folk, Punjabi\nlo-fi hip-hop, folk, South Asian\nlo-fi hip-hop, folk, ambient\nlo-fi hip-hop, folk, melancholic\nlo-fi hip-hop, folk, romantic\nlo-fi hip-hop, funk, Chinese pop\nlo-fi hip-hop, funk, alternative rock\nlo-fi hip-hop, funk, soul\nlo-fi hip-hop, future bass\nlo-fi hip-hop, future bass, C-pop\nlo-fi hip-hop, future bass, EDM\nlo-fi hip-hop, future bass, J-core\nlo-fi hip-hop, future bass, J-pop\nlo-fi hip-hop, future bass, Persian ambient\nlo-fi hip-hop, future bass, R&B\nlo-fi hip-hop, future bass, alternative R&B\nlo-fi hip-hop, future bass, ambient\nlo-fi hip-hop, future bass, chillwave\nlo-fi hip-hop, future bass, chiptune\nlo-fi hip-hop, future bass, cinematic\nlo-fi hip-hop, future bass, downtempo\nlo-fi hip-hop, future bass, dream pop\nlo-fi hip-hop, future bass, dubstep\nlo-fi hip-hop, future bass, electronic pop\nlo-fi hip-hop, future bass, electronic rock\nlo-fi hip-hop, future bass, emotional\nlo-fi hip-hop, future bass, emotional ballad\nlo-fi hip-hop, future bass, hardstyle\nlo-fi hip-hop, future bass, hyperpop\nlo-fi hip-hop, future bass, indie folk\nlo-fi hip-hop, future bass, indie soul\nlo-fi hip-hop, future bass, liquid drum and bass\nlo-fi hip-hop, future bass, piano ballad\nlo-fi hip-hop, future bass, pop\nlo-fi hip-hop, future bass, synthwave\nlo-fi hip-hop, future bass, trap\nlo-fi hip-hop, future bass, trap-pop\nlo-fi hip-hop, garage rock, ambient\nlo-fi hip-hop, ghazal\nlo-fi hip-hop, glitch-hop, hyperpop\nlo-fi hip-hop, gospel R&B\nlo-fi hip-hop, gospel rap\nlo-fi hip-hop, gospel rock\nlo-fi hip-hop, gospel, Afro-soul\nlo-fi hip-hop, gospel, R&B\nlo-fi hip-hop, gospel, rock\nlo-fi hip-hop, gospel-rock\nlo-fi hip-hop, hard rock\nlo-fi hip-hop, hardstyle\nlo-fi hip-hop, hardstyle, R&B\nlo-fi hip-hop, heavy metal\nlo-fi hip-hop, hybrid trap, dubstep\nlo-fi hip-hop, hyperpop\nlo-fi hip-hop, hyperpop, C-pop\nlo-fi hip-hop, hyperpop, R&B\nlo-fi hip-hop, hyperpop, Russian pop-rap\nlo-fi hip-hop, hyperpop, acoustic\nlo-fi hip-hop, hyperpop, ambient\nlo-fi hip-hop, hyperpop, chiptune\nlo-fi hip-hop, hyperpop, cloud rap\nlo-fi hip-hop, hyperpop, emo rap\nlo-fi hip-hop, hyperpop, future bass\nlo-fi hip-hop, hyperpop, glitchcore\nlo-fi hip-hop, hyperpop, math rock\nlo-fi hip-hop, hyperpop, trap\nlo-fi hip-hop, hyperpop, trap metal\nlo-fi hip-hop, indie R&B\nlo-fi hip-hop, indie folk, emo-rap\nlo-fi hip-hop, indie pop\nlo-fi hip-hop, indie pop, C-pop\nlo-fi hip-hop, indie pop, Latin\nlo-fi hip-hop, indie pop, Latin alternative\nlo-fi hip-hop, indie pop, R&B\nlo-fi hip-hop, indie pop, Thai pop-rap\nlo-fi hip-hop, indie pop, acoustic ballad\nlo-fi hip-hop, indie pop, bedroom pop\nlo-fi hip-hop, indie pop, bilingual R&B\nlo-fi hip-hop, indie pop, chillwave\nlo-fi hip-hop, indie pop, chiptune\nlo-fi hip-hop, indie pop, emo rap\nlo-fi hip-hop, indie pop, trip-hop\nlo-fi hip-hop, indie rock\nlo-fi hip-hop, indie rock, C-pop\nlo-fi hip-hop, indie rock, Filipino rap\nlo-fi hip-hop, indie rock, Mandopop\nlo-fi hip-hop, indie rock, ambient\nlo-fi hip-hop, indie rock, blues-rock\nlo-fi hip-hop, indie rock, dream pop\nlo-fi hip-hop, indie rock, hyperpop\nlo-fi hip-hop, indie rock, punk\nlo-fi hip-hop, indie rock, synth-pop\nlo-fi hip-hop, indie-folk, hyperpop\nlo-fi hip-hop, indie-pop\nlo-fi hip-hop, indie-pop, R&B\nlo-fi hip-hop, indie-pop, alternative R&B\nlo-fi hip-hop, indie-pop, dance-pop\nlo-fi hip-hop, indie-pop, emo-rap\nlo-fi hip-hop, indie-pop, trap\nlo-fi hip-hop, industrial hip-hop, R&B\nlo-fi hip-hop, industrial rock\nlo-fi hip-hop, industrial trap\nlo-fi hip-hop, industrial, hyperpop\nlo-fi hip-hop, inspirational pop-rap\nlo-fi hip-hop, jazz lounge\nlo-fi hip-hop, jazz rap\nlo-fi hip-hop, jazz, Balkan soul\nlo-fi hip-hop, jazz, C-pop\nlo-fi hip-hop, jazz-hop\nlo-fi hip-hop, jazzy hip-hop, J-pop\nlo-fi hip-hop, jungle, drum and bass\nlo-fi hip-hop, kawaii future bass, C-pop\nlo-fi hip-hop, kawaii future bass, pop\nlo-fi hip-hop, latin pop\nlo-fi hip-hop, liquid drum and bass, ambient\nlo-fi hip-hop, melancholic C-pop\nlo-fi hip-hop, melancholic R&B\nlo-fi hip-hop, melancholic pop-rap\nlo-fi hip-hop, melodic C-pop\nlo-fi hip-hop, melodic C-pop rap\nlo-fi hip-hop, melodic pop-rap\nlo-fi hip-hop, melodic rap\nlo-fi hip-hop, melodic rap, C-pop ballad\nlo-fi hip-hop, melodic rap, R&B\nlo-fi hip-hop, melodic trap\nlo-fi hip-hop, melodic trap, Amapiano\nlo-fi hip-hop, melodic trap, Mandopop\nlo-fi hip-hop, melodic trap, R&B\nlo-fi hip-hop, metalcore\nlo-fi hip-hop, metalcore, C-pop\nlo-fi hip-hop, metalcore, Chinese pop\nlo-fi hip-hop, modern R&B\nlo-fi hip-hop, modern R&B, trap\nlo-fi hip-hop, moody pop-rap\nlo-fi hip-hop, neo-classical\nlo-fi hip-hop, neo-soul\nlo-fi hip-hop, neo-soul, C-pop\nlo-fi hip-hop, neo-soul, Indian fusion\nlo-fi hip-hop, neo-soul, Italian pop-rap\nlo-fi hip-hop, neo-soul, J-pop\nlo-fi hip-hop, neo-soul, K-pop\nlo-fi hip-hop, neo-soul, Korean R&B\nlo-fi hip-hop, neo-soul, Latin rap\nlo-fi hip-hop, neo-soul, R&B\nlo-fi hip-hop, neo-soul, alternative R&B\nlo-fi hip-hop, neo-soul, alternative rock\nlo-fi hip-hop, neo-soul, ambient\nlo-fi hip-hop, neo-soul, art-rock\nlo-fi hip-hop, neo-soul, boom-bap\nlo-fi hip-hop, neo-soul, chillhop\nlo-fi hip-hop, neo-soul, chiptune\nlo-fi hip-hop, neo-soul, city pop\nlo-fi hip-hop, neo-soul, dream pop\nlo-fi hip-hop, neo-soul, experimental R&B\nlo-fi hip-hop, neo-soul, funk\nlo-fi hip-hop, noir-jazz, industrial rock\nlo-fi hip-hop, noise-rock, boom-bap\nlo-fi hip-hop, nu-disco, deep house\nlo-fi hip-hop, nu-metal\nlo-fi hip-hop, nu-metal, Indian fusion\nlo-fi hip-hop, nu-metal, ambient\nlo-fi hip-hop, nu-metal, jazz rap\nlo-fi hip-hop, nu-metal, post-hardcore\nlo-fi hip-hop, nu-metal, rap-rock\nlo-fi hip-hop, orchestral trap, cinematic\nlo-fi hip-hop, phonk\nlo-fi hip-hop, phonk, trap\nlo-fi hip-hop, playful rap\nlo-fi hip-hop, pluggnb\nlo-fi hip-hop, pop\nlo-fi hip-hop, pop ballad\nlo-fi hip-hop, pop ballad, cinematic\nlo-fi hip-hop, pop ballad, sentimental hip-hop\nlo-fi hip-hop, pop, Bengali\nlo-fi hip-hop, pop, J-pop\nlo-fi hip-hop, pop, Latin guitar\nlo-fi hip-hop, pop, trap\nlo-fi hip-hop, pop-R&B\nlo-fi hip-hop, pop-R&B, Indonesian pop\nlo-fi hip-hop, pop-R&B, chiptune\nlo-fi hip-hop, pop-R&B, cinematic\nlo-fi hip-hop, pop-R&B, future bass\nlo-fi hip-hop, pop-punk\nlo-fi hip-hop, pop-punk, K-pop\nlo-fi hip-hop, pop-punk, rap rock\nlo-fi hip-hop, pop-rap\nlo-fi hip-hop, pop-rap, OPM\nlo-fi hip-hop, pop-rap, R&B\nlo-fi hip-hop, pop-rap, chillwave\nlo-fi hip-hop, pop-rap, chiptune\nlo-fi hip-hop, pop-rap, contemporary R&B\nlo-fi hip-hop, pop-rap, dream pop\nlo-fi hip-hop, pop-rap, future bass\nlo-fi hip-hop, pop-rap, jazz\nlo-fi hip-hop, pop-rap, melancholic\nlo-fi hip-hop, pop-rap, sentimental ballad\nlo-fi hip-hop, pop-rap, soulful ballad\nlo-fi hip-hop, pop-rock\nlo-fi hip-hop, pop-rock, C-pop\nlo-fi hip-hop, pop-rock, Chinese rap\nlo-fi hip-hop, pop-rock, Mandarin rap\nlo-fi hip-hop, pop-rock, ambient\nlo-fi hip-hop, pop-rock, cinematic\nlo-fi hip-hop, pop-rock, emotional ballad\nlo-fi hip-hop, pop-rock, emotional rock\nlo-fi hip-hop, pop-rock, power ballad\nlo-fi hip-hop, pop-rock, rap\nlo-fi hip-hop, pop-rock, soul\nlo-fi hip-hop, pop-rock, symphonic metal\nlo-fi hip-hop, pop-rock, trap\nlo-fi hip-hop, pop/R&B, cloud rap\nlo-fi hip-hop, post-hardcore\nlo-fi hip-hop, post-hardcore, ambient\nlo-fi hip-hop, post-punk\nlo-fi hip-hop, post-rock\nlo-fi hip-hop, post-rock, C-pop\nlo-fi hip-hop, post-rock, ambient\nlo-fi hip-hop, post-rock, post-metal\nlo-fi hip-hop, post-rock, shoegaze\nlo-fi hip-hop, progressive house, Arabic rap\nlo-fi hip-hop, progressive house, ambient\nlo-fi hip-hop, progressive metal, Bengali pop\nlo-fi hip-hop, psychedelic R&B\nlo-fi hip-hop, psychedelic R&B, trap\nlo-fi hip-hop, psychedelic funk\nlo-fi hip-hop, psychedelic indie-pop\nlo-fi hip-hop, psychedelic pop\nlo-fi hip-hop, psychedelic rock\nlo-fi hip-hop, psychedelic rock, Indian classical\nlo-fi hip-hop, psychedelic soul\nlo-fi hip-hop, psychedelic trip-hop\nlo-fi hip-hop, punk rock\nlo-fi hip-hop, rap-rock\nlo-fi hip-hop, rap-rock, ambient\nlo-fi hip-hop, rap-rock, cinematic\nlo-fi hip-hop, rap-rock, funk\nlo-fi hip-hop, rap-rock, nu-metal\nlo-fi hip-hop, reggae, funk\nlo-fi hip-hop, reggaeton\nlo-fi hip-hop, reggaeton, Brazilian pop\nlo-fi hip-hop, reggaeton, Latin pop\nlo-fi hip-hop, reggaeton, latin pop\nlo-fi hip-hop, rock\nlo-fi hip-hop, rock, C-pop\nlo-fi hip-hop, rock, Hebrew vocal\nlo-fi hip-hop, rock, R&B\nlo-fi hip-hop, rock, ambient\nlo-fi hip-hop, rock, cinematic\nlo-fi hip-hop, rock, electronic\nlo-fi hip-hop, rock, experimental\nlo-fi hip-hop, rock-rap\nlo-fi hip-hop, romantic C-pop\nlo-fi hip-hop, romantic Latin pop\nlo-fi hip-hop, romantic R&B\nlo-fi hip-hop, romantic R&B, C-pop\nlo-fi hip-hop, romantic pop-rap\nlo-fi hip-hop, sad pop\nlo-fi hip-hop, sad pop-rap\nlo-fi hip-hop, sad rap\nlo-fi hip-hop, sad reggaeton\nlo-fi hip-hop, sad trap\nlo-fi hip-hop, sad trap, R&B\nlo-fi hip-hop, sad trap, cinematic\nlo-fi hip-hop, sadcore\nlo-fi hip-hop, salsa, boom-bap\nlo-fi hip-hop, sentimental C-pop\nlo-fi hip-hop, sentimental Mandopop\nlo-fi hip-hop, sentimental pop-rap\nlo-fi hip-hop, shoegaze, C-pop\nlo-fi hip-hop, shoegaze, alternative rock\nlo-fi hip-hop, shoegaze, ambient\nlo-fi hip-hop, shoegaze, hyperpop\nlo-fi hip-hop, shoegaze, noise-rock\nlo-fi hip-hop, shoegaze, post-rock\nlo-fi hip-hop, smooth jazz\nlo-fi hip-hop, soulful R&B\nlo-fi hip-hop, soulful R&B, conscious rap\nlo-fi hip-hop, soulful R&B, indie pop\nlo-fi hip-hop, soulful pop\nlo-fi hip-hop, spiritual, Indian devotional\nlo-fi hip-hop, spiritual, South Asian\nlo-fi hip-hop, synth-pop\nlo-fi hip-hop, synth-pop, C-pop\nlo-fi hip-hop, synth-pop, Mandopop\nlo-fi hip-hop, synth-pop, R&B\nlo-fi hip-hop, synth-pop, chillwave\nlo-fi hip-hop, synth-pop, chiptune\nlo-fi hip-hop, synth-pop, dream pop\nlo-fi hip-hop, synth-pop, dubstep\nlo-fi hip-hop, synth-pop, electronic hip-hop\nlo-fi hip-hop, synth-pop, vaporwave\nlo-fi hip-hop, synth-rock\nlo-fi hip-hop, synthwave, ambient\nlo-fi hip-hop, synthwave, chiptune\nlo-fi hip-hop, synthwave, electronic\nlo-fi hip-hop, synthwave, trap\nlo-fi hip-hop, tech house\nlo-fi hip-hop, techno, emotional\nlo-fi hip-hop, theatrical rock\nlo-fi hip-hop, trap\nlo-fi hip-hop, trap R&B\nlo-fi hip-hop, trap R&B, Hindi ballad\nlo-fi hip-hop, trap R&B, contemporary R&B\nlo-fi hip-hop, trap metal\nlo-fi hip-hop, trap metal, Indian rap\nlo-fi hip-hop, trap metal, hardstyle\nlo-fi hip-hop, trap metal, nu-metal\nlo-fi hip-hop, trap soul, Mandopop\nlo-fi hip-hop, trap, Afrobeat\nlo-fi hip-hop, trap, Arabic\nlo-fi hip-hop, trap, Bengali pop\nlo-fi hip-hop, trap, C-pop\nlo-fi hip-hop, trap, Chinese traditional\nlo-fi hip-hop, trap, East Asian\nlo-fi hip-hop, trap, French rap\nlo-fi hip-hop, trap, German pop\nlo-fi hip-hop, trap, Indian devotional\nlo-fi hip-hop, trap, Indian hip-hop\nlo-fi hip-hop, trap, J-pop\nlo-fi hip-hop, trap, Latin\nlo-fi hip-hop, trap, Latin pop\nlo-fi hip-hop, trap, Mandopop\nlo-fi hip-hop, trap, OPM\nlo-fi hip-hop, trap, Punjabi folk\nlo-fi hip-hop, trap, Punjabi pop\nlo-fi hip-hop, trap, R&B\nlo-fi hip-hop, trap, Thai pop\nlo-fi hip-hop, trap, V-Pop\nlo-fi hip-hop, trap, V-pop\nlo-fi hip-hop, trap, ambient\nlo-fi hip-hop, trap, ambient R&B\nlo-fi hip-hop, trap, ambient pop\nlo-fi hip-hop, trap, bilingual pop\nlo-fi hip-hop, trap, blues rock\nlo-fi hip-hop, trap, cinematic\nlo-fi hip-hop, trap, devotional\nlo-fi hip-hop, trap, electronic\nlo-fi hip-hop, trap, emotional rap\nlo-fi hip-hop, trap, ethereal\nlo-fi hip-hop, trap, flamenco rock\nlo-fi hip-hop, trap, future bass\nlo-fi hip-hop, trap, hardstyle\nlo-fi hip-hop, trap, hardwave\nlo-fi hip-hop, trap, hyperpop\nlo-fi hip-hop, trap, melancholic\nlo-fi hip-hop, trap, pop-R&B\nlo-fi hip-hop, trap, pop-rap\nlo-fi hip-hop, trap, psychedelic R&B\nlo-fi hip-hop, trap, rock\nlo-fi hip-hop, trap, soul\nlo-fi hip-hop, trap, traditional East Asian\nlo-fi hip-hop, trap, witch house\nlo-fi hip-hop, trap-soul\nlo-fi hip-hop, trap-soul, C-pop\nlo-fi hip-hop, trap-soul, Indian pop\nlo-fi hip-hop, trap-soul, Mandopop\nlo-fi hip-hop, trap-soul, R&B\nlo-fi hip-hop, trap-soul, V-Pop\nlo-fi hip-hop, trap-soul, bedroom-pop\nlo-fi hip-hop, trip-hop\nlo-fi hip-hop, trip-hop, C-pop\nlo-fi hip-hop, trip-hop, Greek art-pop\nlo-fi hip-hop, trip-hop, Turkish pop\nlo-fi hip-hop, trip-hop, art pop\nlo-fi hip-hop, trip-hop, ethereal\nlo-fi hip-hop, trip-hop, jazz\nlo-fi hip-hop, trip-hop, post-rock\nlo-fi hip-hop, ukulele pop\nlo-fi hip-hop, vaporwave, C-pop\nlo-fi hip-hop, vaporwave, R&B\nlo-fi hip-hop, vaporwave, conscious rap\nlo-fi hip-hop, vaporwave, future bass\nlo-fi hip-hop, vaporwave, nu-metal\nlo-fi hip-hop, video game music\nlo-fi hip-hop, vintage Indonesian pop\nlo-fi hip-hop, world music\nlo-fi hip-hop, world trap\nlo-fi hip-hop, 喊麦\nlo-fi holiday\nlo-fi honky-tonk\nlo-fi horror\nlo-fi house\nlo-fi house Indian pop\nlo-fi house V-Pop\nlo-fi house ambient\nlo-fi house chill pop\nlo-fi house chillwave\nlo-fi house chiptune\nlo-fi house dream pop\nlo-fi house future bass\nlo-fi house vaporwave\nlo-fi house, Brazilian funk\nlo-fi house, Indian pop\nlo-fi house, Mandopop\nlo-fi house, R&B\nlo-fi house, UK garage\nlo-fi house, chillwave, French pop\nlo-fi house, chillwave, indie pop\nlo-fi house, chillwave, neo-soul\nlo-fi house, deep house, German cloud rap\nlo-fi house, deep house, chillwave\nlo-fi house, deep house, soulful house\nlo-fi house, drum and bass, neurofunk\nlo-fi house, future bass, chillwave\nlo-fi house, hardstyle\nlo-fi house, lo-fi hip hop\nlo-fi huapango\nlo-fi hymn\nlo-fi hymnal\nlo-fi hyperpop\nlo-fi hyperpop emo-rap\nlo-fi hyperpop, vaporwave\nlo-fi indie\nlo-fi indie J-pop\nlo-fi indie R&B\nlo-fi indie ballad\nlo-fi indie dance\nlo-fi indie electronic\nlo-fi indie emo rap\nlo-fi indie folk\nlo-fi indie folk dream pop\nlo-fi indie folk post-hardcore\nlo-fi indie folk trap\nlo-fi indie folk, emo, shoegaze\nlo-fi indie folk, garage rock, post-rock\nlo-fi indie folk, noise rock, post-rock\nlo-fi indie folk, pop-punk, emo\nlo-fi indie folk, psychedelic rock\nlo-fi indie funk\nlo-fi indie game\nlo-fi indie hip hop\nlo-fi indie hip-hop\nlo-fi indie pop\nlo-fi indie pop alternative rock\nlo-fi indie pop bossa nova\nlo-fi indie pop chiptune\nlo-fi indie pop emo-pop\nlo-fi indie pop experimental hip-hop\nlo-fi indie pop future bass\nlo-fi indie pop garage rock\nlo-fi indie pop hip-hop\nlo-fi indie pop neo-soul\nlo-fi indie pop noise rock\nlo-fi indie pop nu-disco\nlo-fi indie pop reggaeton\nlo-fi indie pop shoegaze\nlo-fi indie pop trap\nlo-fi indie pop, Afrobeat\nlo-fi indie pop, Italian indie rock\nlo-fi indie pop, R&B, rock\nlo-fi indie pop, R&B, shoegaze\nlo-fi indie pop, alt-rock\nlo-fi indie pop, alternative rock, power pop\nlo-fi indie pop, boom-bap hip-hop\nlo-fi indie pop, breakcore, rock\nlo-fi indie pop, chillhop, soulful R&B\nlo-fi indie pop, chiptune\nlo-fi indie pop, dance-pop\nlo-fi indie pop, dream pop, shoegaze\nlo-fi indie pop, dreamy R&B\nlo-fi indie pop, dubstep\nlo-fi indie pop, electro house\nlo-fi indie pop, electronic rock\nlo-fi indie pop, electronic, dark ambient\nlo-fi indie pop, emo-pop, pop-punk\nlo-fi indie pop, experimental electronic\nlo-fi indie pop, experimental electronic, R&B\nlo-fi indie pop, future bass\nlo-fi indie pop, future bass, electro-pop\nlo-fi indie pop, garage punk\nlo-fi indie pop, happy hardcore\nlo-fi indie pop, hard techno\nlo-fi indie pop, hardstyle\nlo-fi indie pop, hyperpop\nlo-fi indie pop, hyperpop, chiptune\nlo-fi indie pop, hyperpop, cinematic\nlo-fi indie pop, hyperpop, electronic rock\nlo-fi indie pop, hyperpop, emo-rap\nlo-fi indie pop, hyperpop, happy hardcore\nlo-fi indie pop, hyperpop, shoegaze\nlo-fi indie pop, indie rock, shoegaze\nlo-fi indie pop, lo-fi hip-hop, indie rock\nlo-fi indie pop, modern R&B\nlo-fi indie pop, neo-soul\nlo-fi indie pop, noise rock\nlo-fi indie pop, pop-punk\nlo-fi indie pop, post-rock\nlo-fi indie pop, post-rock, cinematic\nlo-fi indie pop, shoegaze\nlo-fi indie pop, shoegaze, cinematic rock\nlo-fi indie pop, shoegaze, noise rock\nlo-fi indie pop, soulful R&B, atmospheric pop\nlo-fi indie pop, synth-driven indie rock\nlo-fi indie pop, synth-pop\nlo-fi indie pop, trance\nlo-fi indie pop, trap\nlo-fi indie pop, trap R&B\nlo-fi indie pop, trap, pop-punk\nlo-fi indie pop, trap, rap\nlo-fi indie pop-rock\nlo-fi indie punk\nlo-fi indie rock\nlo-fi indie rock emo\nlo-fi indie rock emo rap\nlo-fi indie rock emo rap trap\nlo-fi indie rock emo-rap\nlo-fi indie rock garage punk\nlo-fi indie rock garage rock\nlo-fi indie rock jazz-hop\nlo-fi indie rock noise rock\nlo-fi indie rock pop-punk\nlo-fi indie rock post-hardcore\nlo-fi indie rock punk\nlo-fi indie rock punk rock\nlo-fi indie rock rap-rock\nlo-fi indie rock shoegaze\nlo-fi indie rock surf rock\nlo-fi indie rock trap\nlo-fi indie rock, J-rock, Vocaloid\nlo-fi indie rock, Latin rock\nlo-fi indie rock, R&B ballad\nlo-fi indie rock, UK drill, experimental\nlo-fi indie rock, UK hip-hop\nlo-fi indie rock, alternative rock\nlo-fi indie rock, boom-bap hip-hop\nlo-fi indie rock, dreamy R&B\nlo-fi indie rock, garage punk\nlo-fi indie rock, garage rock, post-rock\nlo-fi indie rock, hyperpop\nlo-fi indie rock, neo-soul\nlo-fi indie rock, nu-metal, rap rock\nlo-fi indie rock, pop-punk\nlo-fi indie rock, post-punk\nlo-fi indie rock, rap-rock\nlo-fi indie rock, shoegaze, noise rock\nlo-fi indie rock, shoegaze, post-hardcore\nlo-fi indie rock, trap\nlo-fi indie rock, trap, atmospheric\nlo-fi indie rock, trap-R&B\nlo-fi indie rock, trip-hop\nlo-fi indie rock, vaporwave, hyperpop\nlo-fi indie soul\nlo-fi indie trap\nlo-fi indie, alternative R&B, trip-hop\nlo-fi indie, alternative rock, shoegaze\nlo-fi indie, future bass\nlo-fi indie, hyperpop, electronic rock\nlo-fi indie, trap-metal\nlo-fi indie-dance\nlo-fi indie-electronic\nlo-fi indie-folk\nlo-fi indie-folk noise rock\nlo-fi indie-funk\nlo-fi indie-pop\nlo-fi indie-pop, noise-rock\nlo-fi industrial\nlo-fi industrial hip-hop\nlo-fi industrial rock\nlo-fi instrumental\nlo-fi instrumental hip-hop\nlo-fi introspective\nlo-fi j-pop\nlo-fi j-rock\nlo-fi jangle pop\nlo-fi jazz\nlo-fi jazz C-pop\nlo-fi jazz ballad\nlo-fi jazz blues\nlo-fi jazz hip hop\nlo-fi jazz hip-hop\nlo-fi jazz hop\nlo-fi jazz house\nlo-fi jazz indie pop\nlo-fi jazz indie rock\nlo-fi jazz neo-soul\nlo-fi jazz nu-disco\nlo-fi jazz pop\nlo-fi jazz pop-rock\nlo-fi jazz rock\nlo-fi jazz salsa\nlo-fi jazz soul\nlo-fi jazz trap\nlo-fi jazz trap R&B\nlo-fi jazz, IDM\nlo-fi jazz, J-pop\nlo-fi jazz, J-rock\nlo-fi jazz, Latin jazz, chanson\nlo-fi jazz, alternative rock, C-pop\nlo-fi jazz, trap, R&B\nlo-fi jazz, trap, rock\nlo-fi jazz-funk\nlo-fi jazz-hop\nlo-fi jazz-hop trap\nlo-fi jazz-pop\nlo-fi jazz-rap\nlo-fi jazzy\nlo-fi jingle\nlo-fi jungle\nlo-fi k-pop\nlo-fi kalimba\nlo-fi kawaii\nlo-fi keroncong\nlo-fi kizomba\nlo-fi korean\nlo-fi korean ballad\nlo-fi koto\nlo-fi latin R&B\nlo-fi latin funk\nlo-fi latin fusion\nlo-fi latin pop\nlo-fi lounge\nlo-fi lounge pop\nlo-fi lullaby\nlo-fi mambo\nlo-fi mandolin\nlo-fi mandopop\nlo-fi math rock\nlo-fi meditation\nlo-fi melancholic\nlo-fi melancholy\nlo-fi metal\nlo-fi metalcore\nlo-fi milonga\nlo-fi minyō\nlo-fi moombahton\nlo-fi music box\nlo-fi neo-soul\nlo-fi neo-soul city pop\nlo-fi neo-soul funk\nlo-fi neo-soul funk-pop\nlo-fi neo-soul indie pop\nlo-fi neo-soul pop-punk\nlo-fi neo-soul, J-rock, trap\nlo-fi neo-soul, R&B\nlo-fi neo-soul, boom-bap hip-hop\nlo-fi neo-soul, experimental hip-hop\nlo-fi neo-soul, indie pop, dream pop, chillhop\nlo-fi neo-soul, nu-disco, funk house\nlo-fi neo-soul, piano ballad\nlo-fi new wave\nlo-fi noir\nlo-fi noise rock\nlo-fi novelty\nlo-fi nu-disco\nlo-fi nu-metal\nlo-fi nursery rhyme\nlo-fi opera\nlo-fi operatic\nlo-fi orchestral\nlo-fi orchestral trap\nlo-fi organ\nlo-fi oud\nlo-fi patriotic\nlo-fi percussion\nlo-fi phonk\nlo-fi phonk ambient\nlo-fi piano\nlo-fi piano ballad\nlo-fi piano, J-pop ballad\nlo-fi piano, J-pop, R&B\nlo-fi piano, K-pop, R&B\nlo-fi piano, Mandopop, R&B\nlo-fi piano, bluesy pop, boogie-woogie\nlo-fi piano, breakcore, drum and bass\nlo-fi piano, reggaeton\nlo-fi pluggnb\nlo-fi polka\nlo-fi pop\nlo-fi pop C-pop\nlo-fi pop Indian film music\nlo-fi pop R&B\nlo-fi pop T-pop\nlo-fi pop acoustic R&B\nlo-fi pop ambient\nlo-fi pop ballad\nlo-fi pop bossa nova\nlo-fi pop chillwave\nlo-fi pop chiptune\nlo-fi pop city pop\nlo-fi pop city-pop\nlo-fi pop dream pop\nlo-fi pop dream-pop\nlo-fi pop emo rap\nlo-fi pop emo trap\nlo-fi pop fusion\nlo-fi pop future bass\nlo-fi pop gospel\nlo-fi pop hip hop\nlo-fi pop indie R&B\nlo-fi pop indie pop\nlo-fi pop indie rock\nlo-fi pop jazz-pop\nlo-fi pop neo-soul\nlo-fi pop reggaeton\nlo-fi pop rock\nlo-fi pop trap\nlo-fi pop, Balkan folk\nlo-fi pop, Brazilian MPB\nlo-fi pop, Brazilian R&B, bossa nova\nlo-fi pop, Brazilian funk\nlo-fi pop, Brazilian reggae\nlo-fi pop, C-pop\nlo-fi pop, C-pop, dreamy hip-hop\nlo-fi pop, Chinese traditional, cinematic\nlo-fi pop, Christian rock\nlo-fi pop, French chanson, psychedelic electronic\nlo-fi pop, German cloud rap\nlo-fi pop, Indonesian pop\nlo-fi pop, Italian pop, folk-pop\nlo-fi pop, J-rock\nlo-fi pop, Latin R&B\nlo-fi pop, Latin pop\nlo-fi pop, Latin trap\nlo-fi pop, Punjabi indie\nlo-fi pop, Punjabi pop, Bollywood\nlo-fi pop, R&B\nlo-fi pop, R&B, C-pop\nlo-fi pop, R&B, Chinese hip-hop\nlo-fi pop, R&B, K-hip-hop\nlo-fi pop, R&B, Korean indie\nlo-fi pop, R&B, Thai indie\nlo-fi pop, R&B, cinematic\nlo-fi pop, R&B, hip-hop\nlo-fi pop, R&B, trap\nlo-fi pop, Russian pop-trap\nlo-fi pop, Turkish pop, synthwave\nlo-fi pop, UK hardcore\nlo-fi pop, Vietnamese pop, modern trap\nlo-fi pop, Vocaloid, chiptune\nlo-fi pop, alternative rock\nlo-fi pop, bossa nova\nlo-fi pop, chill R&B\nlo-fi pop, chillwave\nlo-fi pop, chillwave, Indian pop\nlo-fi pop, chillwave, dream pop\nlo-fi pop, chiptune\nlo-fi pop, chiptune, bilingual\nlo-fi pop, cinematic pop, anime soundtrack\nlo-fi pop, cinematic trap, Chinese pop\nlo-fi pop, cinematic, K-pop\nlo-fi pop, city pop, Mandarin indie\nlo-fi pop, city pop, chiptune\nlo-fi pop, city pop, dream pop\nlo-fi pop, city pop, neo-soul\nlo-fi pop, city-pop, ambient\nlo-fi pop, contemporary R&B\nlo-fi pop, dangdut koplo\nlo-fi pop, dream pop\nlo-fi pop, dream pop, C-pop\nlo-fi pop, dream pop, emo rap\nlo-fi pop, future bass\nlo-fi pop, future bass, chillwave\nlo-fi pop, future bass, cinematic\nlo-fi pop, future bass, dubstep\nlo-fi pop, happy hardcore\nlo-fi pop, hyperpop\nlo-fi pop, hyperpop, breakcore\nlo-fi pop, hyperpop, cinematic\nlo-fi pop, hyperpop, glitch\nlo-fi pop, indie pop, Bollywood\nlo-fi pop, indie pop, Punjabi romantic\nlo-fi pop, industrial rock\nlo-fi pop, math rock\nlo-fi pop, math rock, dream pop\nlo-fi pop, moombahton, Indian fusion\nlo-fi pop, neo-soul, city pop\nlo-fi pop, nu-disco, funk\nlo-fi pop, pop-punk, indie-pop\nlo-fi pop, pop-punk, metalcore\nlo-fi pop, pop-punk, trap\nlo-fi pop, pop-rock\nlo-fi pop, pop-rock, hip-hop\nlo-fi pop, reggaeton\nlo-fi pop, reggaeton, moombahton\nlo-fi pop, sad reggaeton\nlo-fi pop, sadcore\nlo-fi pop, synth-pop, Chinese pop\nlo-fi pop, trap\nlo-fi pop, trap R&B\nlo-fi pop, trap, Thai hip-hop\nlo-fi pop, trap, emo rap\nlo-fi pop, trap-R&B\nlo-fi pop, tropical house\nlo-fi pop, world music\nlo-fi pop-R&B\nlo-fi pop-country\nlo-fi pop-folk\nlo-fi pop-funk\nlo-fi pop-fusion\nlo-fi pop-punk\nlo-fi pop-punk, trap, reggae\nlo-fi pop-r&b\nlo-fi pop-rap\nlo-fi pop-rock\nlo-fi pop-trap\nlo-fi post-hardcore\nlo-fi post-punk\nlo-fi post-rock\nlo-fi progressive house\nlo-fi protest\nlo-fi psychedelic\nlo-fi psychedelic cumbia\nlo-fi psychedelic folk\nlo-fi psychedelic funk\nlo-fi psychedelic garage rock\nlo-fi psychedelic pop\nlo-fi psychedelic rock\nlo-fi punk\nlo-fi punk rock\nlo-fi punk rock, hard trance\nlo-fi punk-rap\nlo-fi rage\nlo-fi rage trap\nlo-fi ragtime\nlo-fi rap\nlo-fi reggae\nlo-fi reggae-pop\nlo-fi reggaeton\nlo-fi reggaeton pop\nlo-fi reggaeton trap\nlo-fi reggaeton, hyperpop\nlo-fi reggaeton, sad Latin pop\nlo-fi reggaeton-pop\nlo-fi regional Mexican\nlo-fi retro-swing\nlo-fi ringtone\nlo-fi ritual\nlo-fi rock\nlo-fi rock and roll\nlo-fi rock, Brazilian funk, rap\nlo-fi rock, R&B, hip-hop\nlo-fi rockabilly\nlo-fi roots-rock\nlo-fi rumba flamenco\nlo-fi sad pop\nlo-fi sad trap\nlo-fi salsa\nlo-fi samba\nlo-fi samba-rock\nlo-fi shanty\nlo-fi shoegaze\nlo-fi shoegaze trap metal\nlo-fi singer-songwriter\nlo-fi singer-songwriter, trap hip-hop\nlo-fi ska-punk\nlo-fi skiffle\nlo-fi slowcore\nlo-fi soul\nlo-fi soul pop\nlo-fi soul trap\nlo-fi southern hip-hop\nlo-fi spoken word\nlo-fi spy\nlo-fi spy theme\nlo-fi steelpan\nlo-fi storytelling\nlo-fi study beat\nlo-fi study music\nlo-fi surf rock\nlo-fi surf-rock\nlo-fi surf-rock trap\nlo-fi swing\nlo-fi swing-pop\nlo-fi synth\nlo-fi synth funk\nlo-fi synth pop\nlo-fi synth trap\nlo-fi synth, 90s R&B, chiptune\nlo-fi synth, Brazilian funk, trap\nlo-fi synth, Brazilian funk, vaporwave\nlo-fi synth, Brazilian pop-rock\nlo-fi synth, Brazilian trap\nlo-fi synth, C-pop\nlo-fi synth, C-pop, R&B\nlo-fi synth, C-pop, trap\nlo-fi synth, C-pop, trap R&B\nlo-fi synth, G-funk, underground rap\nlo-fi synth, German pop-rap\nlo-fi synth, Greek ballad, cinematic\nlo-fi synth, Indian pop, R&B\nlo-fi synth, J-Pop, R&B\nlo-fi synth, J-pop, hyperpop\nlo-fi synth, J-pop, trap\nlo-fi synth, K-pop R&B\nlo-fi synth, K-pop, vaporwave\nlo-fi synth, Latin R&B, reggaeton\nlo-fi synth, Latin pop, chiptune\nlo-fi synth, Latin pop, reggaeton\nlo-fi synth, Latin trap\nlo-fi synth, Latin trap, reggaeton\nlo-fi synth, R&B, K-pop\nlo-fi synth, R&B, chiptune\nlo-fi synth, UK garage, chillwave\nlo-fi synth, V-Pop, dance-pop\nlo-fi synth, alternative rock, vaporwave\nlo-fi synth, chillwave, R&B\nlo-fi synth, chillwave, city pop\nlo-fi synth, chiptune, Brazilian funk\nlo-fi synth, chiptune, reggaeton\nlo-fi synth, cloud rap, emo trap\nlo-fi synth, cloud rap, pluggnb\nlo-fi synth, cloud rap, pop-trap\nlo-fi synth, cloud rap, vaporwave\nlo-fi synth, emo rap, cloud rap\nlo-fi synth, emo rap, hyperpop\nlo-fi synth, emo-rap, hyperpop\nlo-fi synth, future bass, C-pop\nlo-fi synth, hardstyle, vaporwave\nlo-fi synth, hyperpop, pluggnb\nlo-fi synth, latin pop\nlo-fi synth, latin pop, R&B\nlo-fi synth, latin trap\nlo-fi synth, melodic trap\nlo-fi synth, neo-soul, R&B\nlo-fi synth, neo-soul, chiptune\nlo-fi synth, neo-soul, vaporwave\nlo-fi synth, pluggnb, Brazilian trap\nlo-fi synth, pluggnb, hyperpop\nlo-fi synth, post-hardcore, metalcore\nlo-fi synth, reggaeton\nlo-fi synth, reggaeton, Latin trap\nlo-fi synth, reggaeton, chillwave\nlo-fi synth, reggaeton, hyperpop\nlo-fi synth, reggaeton, pop-R&B\nlo-fi synth, reggaeton, trap\nlo-fi synth, reggaeton, vaporwave\nlo-fi synth, trap R&B, C-pop\nlo-fi synth, trap R&B, vaporwave\nlo-fi synth, trap, C-pop\nlo-fi synth, trap, Mandopop\nlo-fi synth, trap, R&B\nlo-fi synth, trap, vaporwave\nlo-fi synth, trap-R&B, Brazilian funk\nlo-fi synth, trap-R&B, vaporwave\nlo-fi synth, trap-pop, vaporwave\nlo-fi synth, trap-soul, chillwave\nlo-fi synth, trap-soul, vaporwave\nlo-fi synth, vaporwave, C-pop\nlo-fi synth, vaporwave, R&B\nlo-fi synth, vaporwave, cloud rap\nlo-fi synth, vaporwave, reggaeton\nlo-fi synth, vaporwave, trap\nlo-fi synth-funk\nlo-fi synth-pop\nlo-fi synth-pop C-pop\nlo-fi synth-pop alternative rock\nlo-fi synth-pop breakcore\nlo-fi synth-pop dream pop\nlo-fi synth-pop emo rap\nlo-fi synth-pop future bass\nlo-fi synth-pop industrial\nlo-fi synth-pop nu-metal\nlo-fi synth-pop trap-R&B\nlo-fi synth-pop, French chanson\nlo-fi synth-pop, breakcore, experimental\nlo-fi synth-pop, eurodance\nlo-fi synth-pop, happy hardcore, dubstep\nlo-fi synth-pop, hyperpop\nlo-fi synth-pop, jazz-hop, neo-soul\nlo-fi synth-pop, pop-punk\nlo-fi synth-pop, post-hardcore\nlo-fi synth-rock\nlo-fi synthpop\nlo-fi synthwave\nlo-fi tango\nlo-fi tech house\nlo-fi tech-house\nlo-fi techno\nlo-fi theatrical\nlo-fi torch song\nlo-fi trance\nlo-fi trap\nlo-fi trap C-pop\nlo-fi trap J-pop\nlo-fi trap R&B\nlo-fi trap chiptune\nlo-fi trap cumbia\nlo-fi trap dancehall\nlo-fi trap emo rap\nlo-fi trap emo-rap\nlo-fi trap funk\nlo-fi trap gospel\nlo-fi trap hip-hop\nlo-fi trap metal\nlo-fi trap metalcore\nlo-fi trap nu-metal\nlo-fi trap reggaeton\nlo-fi trap rock\nlo-fi trap soul\nlo-fi trap vaporwave\nlo-fi trap, Brazilian hip-hop\nlo-fi trap, C-pop\nlo-fi trap, French cloud rap\nlo-fi trap, Indian pop\nlo-fi trap, Japanese hip-hop\nlo-fi trap, Latin R&B\nlo-fi trap, North African hip-hop, chill trap\nlo-fi trap, R&B\nlo-fi trap, R&B, C-pop\nlo-fi trap, R&B, Chinese pop\nlo-fi trap, R&B, Mandopop\nlo-fi trap, R&B, reggaeton\nlo-fi trap, Turkish emo rap\nlo-fi trap, ambient\nlo-fi trap, ambient C-pop\nlo-fi trap, ambient, cinematic\nlo-fi trap, breakcore\nlo-fi trap, chiptune\nlo-fi trap, chiptune, melodic rap\nlo-fi trap, cinematic hip hop\nlo-fi trap, cinematic, ambient\nlo-fi trap, cloud rap\nlo-fi trap, cloud rap, C-pop\nlo-fi trap, cloud rap, French trap\nlo-fi trap, cloud rap, Italian rap\nlo-fi trap, cloud rap, J-hip-hop\nlo-fi trap, cloud rap, Latin trap\nlo-fi trap, cloud rap, Mandopop\nlo-fi trap, cloud rap, alternative R&B\nlo-fi trap, cloud rap, ambient\nlo-fi trap, cloud rap, emo trap\nlo-fi trap, cloud rap, emotional R&B\nlo-fi trap, cloud rap, experimental\nlo-fi trap, cloud rap, horrorcore\nlo-fi trap, cloud rap, hyperpop\nlo-fi trap, cloud rap, jazz noir\nlo-fi trap, drill, ambient\nlo-fi trap, emo rap\nlo-fi trap, emo rap, C-pop\nlo-fi trap, emo rap, cloud rap\nlo-fi trap, emo trap, cloud rap\nlo-fi trap, emo-rap\nlo-fi trap, emo-rap, ambient\nlo-fi trap, ghazal\nlo-fi trap, ghazal, ambient\nlo-fi trap, horrorcore\nlo-fi trap, hyperpop\nlo-fi trap, hyperpop, Chinese hip hop\nlo-fi trap, hyperpop, chiptune\nlo-fi trap, hyperpop, trap metal\nlo-fi trap, kawaii hip-hop\nlo-fi trap, meme rap\nlo-fi trap, modern R&B\nlo-fi trap, rage rap, pluggnb\nlo-fi trap, rage trap\nlo-fi trap, rage-trap\nlo-fi trap, trap metal\nlo-fi trap, vaporwave\nlo-fi trap, vaporwave, R&B\nlo-fi trap, vaporwave, cloud rap\nlo-fi trap-R&B\nlo-fi trap-pop\nlo-fi trap-soul\nlo-fi trip-hop\nlo-fi trip-hop R&B\nlo-fi trip-hop alternative rock\nlo-fi trip-hop cumbia\nlo-fi trip-hop funk-rock\nlo-fi trip-hop future bass\nlo-fi trip-hop grunge\nlo-fi trip-hop indie rock\nlo-fi trip-hop lounge jazz\nlo-fi trip-hop neo-soul\nlo-fi trip-hop nu-disco\nlo-fi trip-hop shoegaze\nlo-fi trip-hop, Italian alternative rock\nlo-fi trip-hop, J-rock\nlo-fi trip-hop, Latin pop\nlo-fi trip-hop, Mandarin pop-rock, alternative rock\nlo-fi trip-hop, R&B\nlo-fi trip-hop, alternative rock, post-hardcore\nlo-fi trip-hop, deep house\nlo-fi trip-hop, funk-rock\nlo-fi trip-hop, pop-rock\nlo-fi trip-hop, trap\nlo-fi tropical\nlo-fi tropical house\nlo-fi trot\nlo-fi ukulele\nlo-fi ukulele pop\nlo-fi ukulele trap\nlo-fi ukulele, cloud rap, emo rap\nlo-fi ukulele, deep house, chillwave\nlo-fi vaporwave\nlo-fi vaporwave C-pop\nlo-fi vaporwave R&B\nlo-fi vaporwave afrobeats\nlo-fi vaporwave emo rap\nlo-fi vaporwave future bass\nlo-fi vaporwave neo-soul\nlo-fi vaporwave reggaeton\nlo-fi vaporwave trap\nlo-fi vaporwave trap-R&B\nlo-fi vaporwave trip-hop\nlo-fi vaporwave, Brazilian trap\nlo-fi vaporwave, C-pop rock\nlo-fi vaporwave, C-pop, R&B\nlo-fi vaporwave, C-pop, R&B soul\nlo-fi vaporwave, C-pop, hip-hop\nlo-fi vaporwave, C-pop, neo-soul\nlo-fi vaporwave, C-pop, pop-rock\nlo-fi vaporwave, C-pop, trap R&B\nlo-fi vaporwave, G-funk, Latin hip-hop\nlo-fi vaporwave, J-rock, rap-rock\nlo-fi vaporwave, K-R&B\nlo-fi vaporwave, K-hip-hop\nlo-fi vaporwave, K-pop ballad, R&B\nlo-fi vaporwave, Latin trap\nlo-fi vaporwave, R&B\nlo-fi vaporwave, R&B, hip-hop\nlo-fi vaporwave, R&B, trap\nlo-fi vaporwave, cloud rap\nlo-fi vaporwave, cloud rap, Dutch hip-hop\nlo-fi vaporwave, cloud rap, R&B\nlo-fi vaporwave, cloud rap, emo trap\nlo-fi vaporwave, cloud rap, pluggnb\nlo-fi vaporwave, cloud rap, trap\nlo-fi vaporwave, contemporary R&B\nlo-fi vaporwave, dark trap\nlo-fi vaporwave, jungle\nlo-fi vaporwave, latin trap\nlo-fi vaporwave, melodic trap\nlo-fi vaporwave, modern R&B\nlo-fi vaporwave, neo-soul, R&B\nlo-fi vaporwave, phonk, trap\nlo-fi vaporwave, reggaeton, latin trap\nlo-fi vaporwave, reggaeton, trap-soul\nlo-fi vaporwave, trap\nlo-fi vaporwave, trap R&B\nlo-fi vaporwave, trap, C-pop\nlo-fi vaporwave, trap, Chinese hip hop\nlo-fi vaporwave, trap, Dutch rap\nlo-fi vaporwave, trap, hardstyle\nlo-fi video game\nlo-fi video game music\nlo-fi vintage\nlo-fi vocal\nlo-fi vocaloid\nlo-fi waltz\nlo-fi whimsy\nlo-fi world\nlo-fi world beat\nlo-fi world fusion\nlo-fi world music\nlo-fi worldbeat\nlo-fi worship\nlo-fi zoubop\nlo-fi, 8-bit, ambient\nlo-fi, Azerbaijani folk, melancholic pop\nlo-fi, Brazilian Funk, Funk Mandelão\nlo-fi, Brazilian ballad, melancholic\nlo-fi, Brazilian folk\nlo-fi, Brazilian folk, chanson\nlo-fi, Brazilian funk, carioca\nlo-fi, Brazilian funk, chillwave\nlo-fi, Brazilian funk, reggae\nlo-fi, Brazilian funk, synth pop\nlo-fi, Brazilian pop\nlo-fi, Brazilian pop, MPB\nlo-fi, Brazilian popular music\nlo-fi, Brazilian, pagode\nlo-fi, Brazilian, soul\nlo-fi, Brazilian, upbeat\nlo-fi, C-pop, J-pop\nlo-fi, Cantopop, ballad\nlo-fi, Carnatic, trap\nlo-fi, Chinese New Year, vintage\nlo-fi, Chinese ambient, vintage pop\nlo-fi, Chinese folk, ambient\nlo-fi, EDM, dubstep\nlo-fi, French R&B, trap-soul\nlo-fi, French children's, vintage\nlo-fi, IDM, chiptune\nlo-fi, Indian classical, ambient\nlo-fi, Indian classical, bhajan\nlo-fi, Indian devotional\nlo-fi, Indian devotional, ambient\nlo-fi, Indian devotional, bhajan\nlo-fi, Indian film music\nlo-fi, Indian folk, ambient\nlo-fi, Italian children's, marching band\nlo-fi, J-pop, anime\nlo-fi, J-pop, anime ballad\nlo-fi, J-rock\nlo-fi, J-rock, cinematic\nlo-fi, J-rock, cinematic pop\nlo-fi, J-rock, piano ballad\nlo-fi, J-rock, vaporwave\nlo-fi, JRPG, synth\nlo-fi, Japanese ballad, blues\nlo-fi, Japanese ballad, cinematic\nlo-fi, Japanese indie rock\nlo-fi, Javanese pop, ambient\nlo-fi, K-pop R&B, jazzy\nlo-fi, K-pop, R&B\nlo-fi, K-pop, pop-rock\nlo-fi, K-pop, synthwave\nlo-fi, Kayōkyoku, vintage jazz\nlo-fi, Latin American, folk\nlo-fi, Latin R&B, bedroom pop\nlo-fi, Latin alternative rock\nlo-fi, Latin ballad, fado\nlo-fi, Latin folk\nlo-fi, Latin pop, dream pop\nlo-fi, Latin pop, synth-pop\nlo-fi, Latin rock\nlo-fi, Latin, folk\nlo-fi, Mandarin folk\nlo-fi, Mandarin folk, ambient\nlo-fi, Middle Eastern, cinematic\nlo-fi, Norteño\nlo-fi, Persian classical, baroque\nlo-fi, Persian folk, cinematic\nlo-fi, Persian folk, melancholic\nlo-fi, Russian bard\nlo-fi, Russian chanson, bard music\nlo-fi, Shidaiqu, acoustic\nlo-fi, South Asian, ambient\nlo-fi, T-Pop, dream pop\nlo-fi, Thai Luk Thung, Mor Lam\nlo-fi, Thai brass band, luk thung\nlo-fi, Turkish dance-pop\nlo-fi, Turkish folk, intimate\nlo-fi, Vocaloid, chiptune\nlo-fi, Vocaloid, experimental\nlo-fi, accordion, Brazilian folk\nlo-fi, accordion, Creole\nlo-fi, acoustic ballad, sentimental\nlo-fi, acoustic, Brazilian folk\nlo-fi, acoustic, Italian pop\nlo-fi, acoustic, Latin\nlo-fi, acoustic, Punjabi\nlo-fi, acoustic, cinematic\nlo-fi, acoustic, flamenco\nlo-fi, acoustic, folk\nlo-fi, acoustic, indie folk\nlo-fi, acoustic, introspective\nlo-fi, acoustic, melancholic\nlo-fi, alternative metal, cinematic\nlo-fi, alternative rock, C-pop\nlo-fi, alternative rock, ambient\nlo-fi, ambient, Arabic pop\nlo-fi, ambient, C-pop\nlo-fi, ambient, Chinese folk\nlo-fi, ambient, Chinese indie\nlo-fi, ambient, Chinese traditional\nlo-fi, ambient, East Asian\nlo-fi, ambient, Indian folk\nlo-fi, ambient, Russian indie\nlo-fi, ambient, Sinhala folk\nlo-fi, ambient, South Asian\nlo-fi, ambient, South Asian folk\nlo-fi, ambient, bossa nova\nlo-fi, ambient, classical\nlo-fi, ambient, folk\nlo-fi, ambient, indie\nlo-fi, ambient, indie folk\nlo-fi, ambient, traditional Arabic\nlo-fi, ambient, vaporwave\nlo-fi, ambient, video game\nlo-fi, ambient, video game music\nlo-fi, barbershop, acoustic\nlo-fi, baritone, German chanson\nlo-fi, baritone, Italian ballad\nlo-fi, baritone, Latin ballad\nlo-fi, baritone, cinematic\nlo-fi, baritone, operatic\nlo-fi, baritone, theatrical\nlo-fi, baritone, vintage\nlo-fi, bedroom pop, Mandarin folk\nlo-fi, bedroom pop, bossa nova\nlo-fi, bitpop, indie electronic\nlo-fi, blues, French chanson\nlo-fi, blues, Mandarin ballad\nlo-fi, bolero, Latin guitar\nlo-fi, bolero, acoustic\nlo-fi, bolero, folk\nlo-fi, bossa nova, Latin\nlo-fi, bossa nova, indie folk\nlo-fi, bossa nova, nostalgic\nlo-fi, bossa nova, torch song\nlo-fi, breakcore, ethereal\nlo-fi, breakcore, neurofunk\nlo-fi, cabaret, theatrical\nlo-fi, cartoon, game show\nlo-fi, cartoon, vintage\nlo-fi, chanson, vintage\nlo-fi, children's music, German folk\nlo-fi, children's music, chiptune\nlo-fi, children's, Vietnamese\nlo-fi, children's, synth pop\nlo-fi, chillhop, ancient style\nlo-fi, chillwave\nlo-fi, chillwave, ambient\nlo-fi, chillwave, ambient pop\nlo-fi, chillwave, instrumental\nlo-fi, chillwave, retro game\nlo-fi, chillwave, vaporwave\nlo-fi, chiptune, ambient\nlo-fi, chiptune, fanfare\nlo-fi, chiptune, indie pop\nlo-fi, chiptune, synthpop\nlo-fi, chiptune, waltz\nlo-fi, choral, melancholic\nlo-fi, choral, video game\nlo-fi, cinematic, French folk\nlo-fi, cinematic, Indian film music\nlo-fi, cinematic, K-pop\nlo-fi, cinematic, Mandopop\nlo-fi, cinematic, Turkish folk\nlo-fi, cinematic, Vietnamese ballad\nlo-fi, cinematic, ambient\nlo-fi, cinematic, ballad\nlo-fi, cinematic, choral\nlo-fi, cinematic, ethereal\nlo-fi, cinematic, folk\nlo-fi, cinematic, operatic\nlo-fi, cinematic, piano ballad\nlo-fi, cinematic, soul\nlo-fi, cinematic, vintage\nlo-fi, circus, big band\nlo-fi, city pop, J-pop\nlo-fi, city pop, funk\nlo-fi, city pop, jazz hop\nlo-fi, city pop, neo-soul\nlo-fi, city-pop, K-pop\nlo-fi, classical guitar, Mediterranean\nlo-fi, classical, Indian film music\nlo-fi, classical, Indian folk\nlo-fi, classical, ambient\nlo-fi, classical, bolero\nlo-fi, classical, devotional\nlo-fi, classical, folk\nlo-fi, crooner, vintage\nlo-fi, cumbia rock, vaporwave\nlo-fi, dark ambient, Latin groove\nlo-fi, dark ambient, experimental\nlo-fi, downtempo, Indian folk\nlo-fi, dream pop, Russian vocal\nlo-fi, dream pop, ambient\nlo-fi, dream pop, synthwave\nlo-fi, dream pop, video game music\nlo-fi, electronic, ambient\nlo-fi, electronic, playful\nlo-fi, electronic, raï\nlo-fi, emotional, cinematic\nlo-fi, enka, traditional Japanese\nlo-fi, eurodance, vaporwave\nlo-fi, flamenco, Russian romance\nlo-fi, flamenco, ambient\nlo-fi, flamenco, art song\nlo-fi, flamenco, chanson\nlo-fi, folk, Chinese folk\nlo-fi, folk, Greek\nlo-fi, folk, Latin American\nlo-fi, folk, Russian folk\nlo-fi, folk, Russian romance\nlo-fi, folk, Spanish ballad\nlo-fi, folk, ambient\nlo-fi, folk, classical\nlo-fi, folk, party\nlo-fi, folk, ranchera\nlo-fi, folk, tango\nlo-fi, future bass\nlo-fi, future bass, ambient\nlo-fi, hardstyle, ambient\nlo-fi, hyperpop, kawaii future bass\nlo-fi, indie pop, Hebrew vocal\nlo-fi, industrial rock\nlo-fi, industrial rock, Brazilian lo-fi\nlo-fi, industrial, ambient\nlo-fi, industrial, ethereal\nlo-fi, introspective, Thai narrative\nlo-fi, jazz, ambient\nlo-fi, jazzy, ambient\nlo-fi, jungle, drum and bass\nlo-fi, klezmer, instrumental\nlo-fi, klezmer, polka\nlo-fi, luk thung, classical-inspired\nlo-fi, melancholic, Indian film music\nlo-fi, melancholic, Khmer folk\nlo-fi, melancholic, Portuguese soul\nlo-fi, melancholic, Vietnamese indie\nlo-fi, melancholic, acoustic\nlo-fi, melancholic, ambient\nlo-fi, melancholic, atmospheric\nlo-fi, melancholic, cinematic\nlo-fi, metalcore\nlo-fi, minimal, chiptune\nlo-fi, neo-classical\nlo-fi, neo-funk, city pop\nlo-fi, neo-soul, R&B\nlo-fi, neo-soul, chillwave\nlo-fi, neo-soul, city pop\nlo-fi, neo-soul, indie pop\nlo-fi, noise rock, Latin percussion\nlo-fi, noise rock, blues\nlo-fi, operatic, Soviet estrada\nlo-fi, operatic, art song\nlo-fi, piano ballad, Korean indie\nlo-fi, piano, operatic\nlo-fi, playful, children's music\nlo-fi, playful, electronic\nlo-fi, playful, experimental\nlo-fi, playful, instrumental\nlo-fi, playful, tropical\nlo-fi, playful, video game\nlo-fi, pop-funk, city-pop\nlo-fi, post-punk, vaporwave\nlo-fi, post-rock, ambient\nlo-fi, post-rock, cinematic\nlo-fi, psychedelic, ambient\nlo-fi, quirky, Christmas\nlo-fi, quirky, instrumental\nlo-fi, ragtime, West African\nlo-fi, ranchera\nlo-fi, retro, children's music\nlo-fi, retro, chiptune\nlo-fi, retro, waltz\nlo-fi, rock opera, cinematic\nlo-fi, rock, emotional\nlo-fi, samba, bossa nova\nlo-fi, shoegaze, dream pop\nlo-fi, soul, ambient\nlo-fi, spiritual, ambient\nlo-fi, spy theme, cartoon\nlo-fi, steel drum, children's music\nlo-fi, surf rock, indie\nlo-fi, symphonic metal\nlo-fi, synth pop, C-pop\nlo-fi, synth, 90s video game\nlo-fi, synth-funk, city pop\nlo-fi, synthwave, chiptune\nlo-fi, synthwave, post-punk\nlo-fi, synthwave, vintage\nlo-fi, tango, folk\nlo-fi, theatrical, ambient\nlo-fi, theatrical, estrada\nlo-fi, theatrical, operatic\nlo-fi, theatrical, vintage\nlo-fi, torch song, cinematic\nlo-fi, torch song, flamenco\nlo-fi, torch song, operatic\nlo-fi, torch song, vintage\nlo-fi, traditional South Asian, ghazal\nlo-fi, traditional Spanish, children's choir\nlo-fi, traditional Sundanese, folk\nlo-fi, tribal, vocal\nlo-fi, tropical, ambient\nlo-fi, tropical, electronic\nlo-fi, tropical, synth pop\nlo-fi, tropical, video game\nlo-fi, ukulele, melancholic\nlo-fi, vaporwave\nlo-fi, vaporwave, K-pop\nlo-fi, vaporwave, ambient\nlo-fi, vaporwave, chillwave\nlo-fi, vaporwave, city-pop\nlo-fi, vaporwave, electronic\nlo-fi, vaporwave, retro\nlo-fi, vaporwave, sample-based\nlo-fi, video game music\nlo-fi, video game music, ambient\nlo-fi, video game, ambient\nlo-fi, video game, children's music\nlo-fi, video game, folk\nlo-fi, video game, minimalist\nlo-fi, video game, nostalgic\nlo-fi, video game, playful\nlo-fi, video game, tropical\nlo-fi, video game, whimsical\nlo-fi, vintage, Brazilian\nlo-fi, vintage, Nepali film music\nlo-fi, vintage, Persian pop\nlo-fi, vintage, Portuguese folk\nlo-fi, vintage, South Asian film music\nlo-fi, vintage, brass\nlo-fi, vintage, crooner\nlo-fi, vintage, vocal harmony\nlo-fi, waltz, chiptune\nlo-fi, whimsical, children's theme\nlo-fi, whimsical, instrumental\nlo-fi, world music, French folk\nlofi electronica\nlofi hip hop\nlofi hip hop, sad trap\nlofi hip-hop\nlofi hip-hop chillhop\nlofi indie\nlofi pop\nlofi soul\nlofi-pop\nloopcore\nlounge\nlounge Mandopop city pop\nlounge R&B\nlounge a cappella\nlounge acid jazz chillhop\nlounge ambient\nlounge ballad\nlounge blues\nlounge bossa nova\nlounge bossa nova chill-out\nlounge bossa nova chiptune\nlounge bossa nova lo-fi hip-hop\nlounge bossa nova neo-soul\nlounge bossa nova noir-jazz\nlounge bossa nova nu-jazz\nlounge bossa nova smooth jazz\nlounge chillhop\nlounge deep house\nlounge electronic\nlounge electronica\nlounge exotica\nlounge exotica bossa nova\nlounge exotica cinematic\nlounge exotica easy listening\nlounge flamenco\nlounge folk\nlounge funk\nlounge funk bossa nova\nlounge funk exotica\nlounge funk reggae\nlounge funk rock\nlounge funk soul\nlounge funk world music\nlounge fusion\nlounge guitar\nlounge hip hop\nlounge hip-hop\nlounge house\nlounge house, city pop\nlounge indie rock\nlounge jazz\nlounge jazz alt-rock\nlounge jazz alternative rock\nlounge jazz art rock\nlounge jazz bebop\nlounge jazz blues-rock\nlounge jazz blues-rock free jazz\nlounge jazz boogie-woogie\nlounge jazz bossa nova\nlounge jazz cabaret\nlounge jazz cinematic\nlounge jazz cinematic electronica\nlounge jazz cinematic exotica\nlounge jazz city pop\nlounge jazz deep house\nlounge jazz disco\nlounge jazz disco-rock\nlounge jazz exotica\nlounge jazz filmi\nlounge jazz funk\nlounge jazz funk disco\nlounge jazz funk rock\nlounge jazz funk soul\nlounge jazz funk-pop\nlounge jazz funk-rock\nlounge jazz garage rock\nlounge jazz hip-hop\nlounge jazz indie rock\nlounge jazz neo-soul\nlounge jazz noise rock\nlounge jazz orchestral\nlounge jazz pop-rock\nlounge jazz pop-rock funk\nlounge jazz progressive rock\nlounge jazz psychedelic rock\nlounge jazz punk rock\nlounge jazz rock\nlounge jazz salsa\nlounge jazz soul\nlounge jazz surf rock\nlounge jazz trip-hop\nlounge jazz, Bollywood jazz, EDM\nlounge jazz, EDM, trap\nlounge jazz, French chanson\nlounge jazz, French chanson, psychedelic\nlounge jazz, Kayōkyoku\nlounge jazz, Latin jazz\nlounge jazz, Latin rock, spoken word\nlounge jazz, art rock\nlounge jazz, big band\nlounge jazz, big band pop\nlounge jazz, big band swing\nlounge jazz, big band, free jazz\nlounge jazz, big band, punk rock\nlounge jazz, big band, swing\nlounge jazz, boogie-woogie, rock and roll\nlounge jazz, bossa nova, Japanese ballad\nlounge jazz, bossa nova, latin jazz\nlounge jazz, choral, latin big band\nlounge jazz, cinematic orchestral\nlounge jazz, cinematic orchestral, C-pop\nlounge jazz, cinematic rock, ambient noir\nlounge jazz, cinematic, funk soul\nlounge jazz, city pop, Indonesian pop\nlounge jazz, disco-pop\nlounge jazz, dream pop, psychedelic rock\nlounge jazz, free jazz\nlounge jazz, funk rock\nlounge jazz, garage rock\nlounge jazz, glitch, industrial rock\nlounge jazz, hard rock\nlounge jazz, hard trance\nlounge jazz, indie rock, soul\nlounge jazz, indie rock, synth pop\nlounge jazz, jazz-hop\nlounge jazz, jazz-rock, bebop\nlounge jazz, jazz-rock, free jazz\nlounge jazz, neo-soul, disco\nlounge jazz, noise rock\nlounge jazz, pop-punk\nlounge jazz, pop-rock\nlounge jazz, power ballad, gospel\nlounge jazz, psychedelic funk\nlounge jazz, psychedelic hard rock\nlounge jazz, psychedelic rock\nlounge jazz, psychedelic rock, dream pop\nlounge jazz, rap rock\nlounge jazz, rock\nlounge jazz, soul, funk\nlounge jazz, synth-pop\nlounge jazz, theatrical pop\nlounge jazz, theatrical rock\nlounge jazz, theatrical rock, free jazz\nlounge jazz-funk\nlounge jazz-pop\nlounge lo-fi hip-hop\nlounge mambo\nlounge music\nlounge neo-soul\nlounge noir\nlounge nu-disco\nlounge nu-jazz\nlounge nu-jazz chill house\nlounge nu-jazz world music\nlounge orchestra\nlounge orchestral\nlounge pop\nlounge pop bossa nova\nlounge pop doo-wop\nlounge pop exotica\nlounge pop, Soviet estrada\nlounge pop, Soviet-era estrada\nlounge pop, electro house\nlounge pop, retro, Soviet estrada\nlounge pop, retro, estrada\nlounge rap\nlounge reggae\nlounge rock\nlounge rock bossa nova\nlounge rock exotica\nlounge smooth jazz\nlounge soul\nlounge swing\nlounge trip-hop\nlounge trip-hop exotica\nlounge ukulele\nlounge waltz\nlounge world music\nlounge, 80s pop, Eastern European\nlounge, Balkan, Klezmer\nlounge, East Asian, instrumental\nlounge, Latin ballad\nlounge, Latin jazz, bossa nova\nlounge, Latin jazz, smooth soul\nlounge, Latin, European\nlounge, Latin, Mediterranean\nlounge, Latin, ambient\nlounge, Latin, trip-hop\nlounge, Latin, tropical\nlounge, Latin, vintage\nlounge, Latin, world music\nlounge, Soviet-era, cabaret\nlounge, ambient, Indian fusion\nlounge, ambient, Latin\nlounge, big band, cinematic\nlounge, big band, easy listening\nlounge, big band, vibraphone\nlounge, bolero, Latin\nlounge, bossa nova, Latin\nlounge, bossa nova, chill\nlounge, bossa nova, cinematic\nlounge, bossa nova, downtempo\nlounge, bossa nova, jazz\nlounge, bossa nova, latin\nlounge, bossa nova, latin jazz\nlounge, bossa nova, lo-fi hip hop\nlounge, bossa nova, smooth jazz\nlounge, bossa nova, synthwave\nlounge, bossa nova, world music\nlounge, breakcore\nlounge, cha-cha-chá\nlounge, chanson, jazz\nlounge, chillout, world fusion\nlounge, chillwave, downtempo\nlounge, cinematic, Latin\nlounge, cinematic, ambient\nlounge, cinematic, easy-listening\nlounge, cinematic, flamenco\nlounge, cinematic, spy theme\nlounge, cinematic, torch song\nlounge, cinematic, world music\nlounge, city pop, Christmas\nlounge, doo-wop, boogie-woogie\nlounge, east asian fusion, smooth jazz\nlounge, east asian, instrumental\nlounge, easy-listening, East Asian folk\nlounge, easy-listening, traditional East Asian\nlounge, exotica, vintage\nlounge, flamenco, torch song\nlounge, guzheng, pentatonic\nlounge, latin jazz, bossa nova\nlounge, latin, bolero\nlounge, latin, smooth jazz\nlounge, library music, cinematic\nlounge, neo-soul, chillhop\nlounge, new age, world fusion\nlounge, nu-disco, acid jazz\nlounge, oud, world music\nlounge, psychedelic, exotica\nlounge, retro video game, chill\nlounge, rockabilly, vintage\nlounge, smooth jazz, Russian vocal\nlounge, smooth jazz, synth-pop\nlounge, spy theme, cinematic\nlounge, tropical, bossa nova\nlounge, tropical, instrumental\nlounge, vintage, Chinese pop\nlounge, vintage, European\nlounge, world fusion, new age\nlounge, world music, Latin\nlounge, world music, ambient\nlounge, world music, bossa nova\nlounge, world music, instrumental\nlounge, world music, jazz fusion\nlounge, world music, steel pan\nlounge, worldbeat, funk\nlounge-country\nlounge-funk\nlounge-funk, hard rock\nlounge-jazz\nlounge-jazz garage rock\nlounge-jazz hip-hop\nlounge-jazz indie rock\nlounge-jazz noise-rock\nlounge-jazz progressive rock\nlounge-jazz rock\nlounge-jazz soulful art-rock\nlounge-jazz, big band, punk-jazz\nlounge-jazz, eurodance, cinematic\nlounge-jazz, garage rock, flamenco\nlounge-jazz, hard rock, samba-rock\nlounge-jazz, vintage rock\nlounge-pop\nlounge-pop 80s Mandopop\nlounge-pop C-pop\nlounge-pop Latin\nlounge-pop Latin jazz\nlounge-pop Soviet estrada\nlounge-pop acid jazz\nlounge-pop afrobeats\nlounge-pop alt-rock\nlounge-pop big band\nlounge-pop big band jazz\nlounge-pop big beat\nlounge-pop bolero\nlounge-pop bossa nova\nlounge-pop bossa nova swing\nlounge-pop cabaret\nlounge-pop chanson\nlounge-pop chillwave\nlounge-pop chiptune\nlounge-pop cinematic\nlounge-pop city pop\nlounge-pop city pop bossa nova\nlounge-pop city pop jazz fusion\nlounge-pop city pop jazz-funk\nlounge-pop city pop jazz-fusion\nlounge-pop city pop smooth jazz\nlounge-pop city-pop\nlounge-pop city-pop big band jazz\nlounge-pop city-pop bossa nova\nlounge-pop city-pop jazz\nlounge-pop city-pop jazz-funk\nlounge-pop city-pop light jazz\nlounge-pop city-pop neo-soul\nlounge-pop city-pop shibuya-kei\nlounge-pop disco\nlounge-pop doo-wop\nlounge-pop dream pop\nlounge-pop dream-pop\nlounge-pop electro-pop\nlounge-pop exotica\nlounge-pop exotica cinematic\nlounge-pop exotica mambo\nlounge-pop exotica swing\nlounge-pop funk\nlounge-pop funk disco\nlounge-pop funk soul\nlounge-pop funk-hop\nlounge-pop funk-rock\nlounge-pop hip-hop\nlounge-pop indie rock\nlounge-pop indie-pop\nlounge-pop j-rock\nlounge-pop jazz\nlounge-pop jazz-fusion\nlounge-pop jazzy\nlounge-pop latin\nlounge-pop latin jazz\nlounge-pop latin-jazz\nlounge-pop lo-fi hip-hop dream pop\nlounge-pop lo-fi hip-hop multilingual\nlounge-pop neo-soul\nlounge-pop neo-soul jazz\nlounge-pop nu-disco\nlounge-pop orchestral\nlounge-pop psychedelic rock\nlounge-pop ragtime\nlounge-pop retro\nlounge-pop rockabilly\nlounge-pop schlager\nlounge-pop shoegaze\nlounge-pop ska-punk\nlounge-pop smooth jazz\nlounge-pop soul\nlounge-pop swing\nlounge-pop trap\nlounge-pop tropical\nlounge-pop vintage jazz\nlounge-pop world music\nlounge-pop, Latin, theatrical\nlounge-pop, MPB, ballad\nlounge-pop, Soviet-era estrada\nlounge-pop, boom-bap\nlounge-pop, city pop, Japanese\nlounge-pop, city pop, Shibuya-kei\nlounge-pop, city pop, festive\nlounge-pop, city pop, neo-soul\nlounge-pop, city pop, theatrical\nlounge-pop, city-pop\nlounge-pop, hard rock\nlounge-pop, pop-rock\nlounge-pop, pop-rock, Indonesian\nlounge-pop, retro, estrada\nlounge-pop, theatrical, Soviet estrada\nlounge-pop, theatrical, funk-rock\nlounge-pop, theatrical, vintage\nlounge-pop, vintage Italian pop, jazz\nlounge-rock\nlounge-rock hard rock\nlover's rock reggae\nlovers rock\nlovers rock R&B\nlovers rock dancehall\nlovers rock reggae\nlovers rock reggae, R&B\nlovers rock reggae-pop\nlovers rock, city pop\nlovers rock, early house\nlovers rock, new jack swing\nlovers rock, new jack swing, dancehall\nluk thung\nlullaby\nlullaby ambient\nlullaby ballad\nlullaby classical\nlullaby folk\nlullaby jazz\nlullaby orchestral\nlullaby piano\nlullaby pop\nlullaby ukulele\nlullaby, Chinese flute, ambient\nlullaby, Indian classical, ambient\nlullaby, R&B\nlullaby, R&B, trap\nlullaby, acoustic, Christmas\nlullaby, acoustic, Thai folk\nlullaby, acoustic, ambient\nlullaby, acoustic, big band swing\nlullaby, acoustic, bilingual\nlullaby, acoustic, cinematic\nlullaby, acoustic, folk\nlullaby, acoustic, mandolin\nlullaby, acoustic, melancholic\nlullaby, acoustic, vintage\nlullaby, ambient acoustic\nlullaby, ambient, ASMR\nlullaby, ambient, Chinese\nlullaby, ambient, Chinese flute\nlullaby, ambient, Chinese folk\nlullaby, ambient, Chinese traditional\nlullaby, ambient, French chanson\nlullaby, ambient, Indian folk\nlullaby, ambient, Spanish\nlullaby, ambient, Spanish folk\nlullaby, ambient, Swedish folk\nlullaby, ambient, Tamil folk\nlullaby, ambient, Telugu\nlullaby, ambient, Thai ballad\nlullaby, ambient, Thai folk\nlullaby, ambient, Vocaloid\nlullaby, ambient, acoustic\nlullaby, ambient, bilingual\nlullaby, ambient, chill\nlullaby, ambient, chiptune\nlullaby, ambient, cinematic\nlullaby, ambient, classical\nlullaby, ambient, classical crossover\nlullaby, ambient, ethereal\nlullaby, ambient, folk\nlullaby, ambient, jazz\nlullaby, ambient, korean folk\nlullaby, ambient, lo-fi\nlullaby, ambient, music box\nlullaby, ambient, neo-classical\nlullaby, ambient, piano\nlullaby, ambient, soft piano\nlullaby, ambient, soft pop\nlullaby, ambient, synth\nlullaby, ambient, synth pop\nlullaby, ambient, world\nlullaby, children's music, ambient pop\nlullaby, children's music, electronic\nlullaby, cinematic, French pop\nlullaby, cinematic, Spanish folk\nlullaby, cinematic, acoustic\nlullaby, cinematic, ambient\nlullaby, cinematic, children's choir\nlullaby, cinematic, choral\nlullaby, cinematic, ethereal\nlullaby, cinematic, indie folk\nlullaby, cinematic, melancholic\nlullaby, cinematic, operatic\nlullaby, cinematic, orchestral\nlullaby, cinematic, world music\nlullaby, classical guitar, Latin folk\nlullaby, classical guitar, Spanish folk\nlullaby, classical, Mandarin\nlullaby, classical, acoustic\nlullaby, classical, ambient\nlullaby, classical, cinematic\nlullaby, classical, flamenco\nlullaby, classical, operatic\nlullaby, dream pop, ambient\nlullaby, easy listening, bilingual\nlullaby, fingerstyle, cinematic\nlullaby, folk, Latin\nlullaby, folk, ambient\nlullaby, folk, melancholic\nlullaby, guzheng, ambient\nlullaby, harpsichord, ambient\nlullaby, jazz, ambient\nlullaby, mandolin, dreamy\nlullaby, mandolin, gentle\nlullaby, melancholic, French nursery\nlullaby, melancholic, Hebrew folk\nlullaby, melancholic, Turkish\nlullaby, melancholic, accordion\nlullaby, melancholic, acoustic\nlullaby, melancholic, ambient\nlullaby, melancholic, classical\nlullaby, music box, children's music\nlullaby, pop, playful\nlullaby, ragtime, Ukrainian folk\nlullaby, ukulele, dream pop\nluxury hip-hop\nluxury rap\nluxury trap\nlyrical hip-hop\nlyrical trap\nmacabre polka-folk\nmagic pop\nmainstream jazz\nmallet percussion\nmambo\nmambo Afro-Cuban jazz\nmambo Arabic pop\nmambo Latin jazz\nmambo big band\nmambo bolero\nmambo boogaloo\nmambo boogie-woogie\nmambo carnavalero\nmambo cha-cha-cha\nmambo cha-cha-chá\nmambo chacha cha\nmambo chanson\nmambo children's music\nmambo comedy\nmambo cumbia\nmambo descarga\nmambo exotica\nmambo flamenco\nmambo hip hop\nmambo jazz\nmambo merengue\nmambo montuno\nmambo novelty\nmambo pachanga\nmambo pop\nmambo psychedelic rock\nmambo punk\nmambo rap\nmambo revival\nmambo rock\nmambo rock and roll\nmambo rockabilly\nmambo rumba\nmambo rumba flamenca\nmambo salsa\nmambo salsa rockabilly\nmambo samba big band\nmambo ska\nmambo ska latin rock\nmambo ska-punk Latin rock\nmambo swing\nmambo tango\nmambo, French chanson, vintage Latin\nmambo, Halloween, theatrical\nmambo, Italian folk, novelty\nmambo, Italian, theatrical\nmambo, Italian, vintage\nmambo, Latin big band\nmambo, Latin big band, energetic\nmambo, Latin big band, festive\nmambo, Latin jazz\nmambo, Latin jazz, big band\nmambo, Latin jazz, cabaret\nmambo, Latin pop, Mediterranean\nmambo, Latin pop, theatrical pop\nmambo, Latin rock\nmambo, Latin, theatrical\nmambo, barbershop, Latin dance\nmambo, big band\nmambo, big band, Afro-Caribbean\nmambo, big band, Afro-Cuban\nmambo, big band, Kayōkyoku\nmambo, big band, Latin\nmambo, big band, Latin jazz\nmambo, big band, Spanish swing\nmambo, big band, ambient\nmambo, big band, pop-soul\nmambo, big band, psychedelic\nmambo, big band, rock\nmambo, blues, big band\nmambo, bolero, cinematic\nmambo, cha-cha-chá\nmambo, cha-cha-chá, Latin big band\nmambo, cha-cha-chá, Latin jazz\nmambo, cha-cha-chá, Mandopop\nmambo, cha-cha-chá, big band\nmambo, cha-cha-chá, cinematic\nmambo, cha-cha-chá, operatic\nmambo, cha-cha-chá, orchestral\nmambo, cha-cha-chá, theatrical\nmambo, cha-cha-chá, vintage lounge\nmambo, cinematic, Latin jazz\nmambo, cinematic, Latin pop\nmambo, cinematic, ballad\nmambo, cinematic, orchestral\nmambo, corrido, Spanish folk\nmambo, novelty, Christmas\nmambo, novelty, Italian-American\nmambo, novelty, vintage\nmambo, operatic, theatrical\nmambo, retro Italian pop\nmambo, satirical, energetic\nmambo, theatrical, novelty\nmambo, vintage, chanson\nmambo-chcha-chá\nmambo-pop\nmambo-ska\nmambo-swing\nmandolin\nmandolin flourish\nmandolin virtuosity\nmandopop\nmandopop rock\nmanele\nmanele etno\nmanele, Romanian folk, theatrical\nmanele, hyperpop, hardstyle\nmanic hip-hop\nmaracatu funk\nmaracatu samba-reggae\nmarch\nmarch music\nmarch polka\nmarch, orchestral, patriotic\nmarch, orchestral, theatrical\nmarch, patriotic, vintage\nmarch, theatrical, vintage\nmarcha\nmarching anime\nmarching band\nmarching band hip-hop\nmarching band rock\nmarching drum\nmarching drum corps\nmarching drumline\nmarching folk\nmarching percussion\nmarching polka\nmarching rock\nmarchinha\nmarchinha de carimbó\nmarchinha de carnaval\nmarchinha samba-reggae\nmarchinha, samba-rock\nmariachi\nmariachi ballad\nmariachi cumbia\nmariachi electronic\nmariachi gospel\nmariachi klezmer fusion\nmariachi pop\nmariachi punk\nmariachi rock\nmariachi ska\nmariachi, bolero, cinematic\nmariachi, brass band, cinematic\nmariachi, cinematic, orchestral\nmariachi, educational, comedic\nmariachi, orchestral, operatic\nmariachi-pop\nmariachi-punk\nmariachi-rock\nmarimba\nmarimba solo\nmarimba virtuosity\nmaritime folk\nmaritime folk-rock\nmarrab\nmarrab fereng\nmarrab ferin\nmarrab gentle\nmarrab style\nmarrabau\nmarrabenta\nmartial\nmartial Arabic\nmartial C-pop\nmartial Turkish revolutionary\nmartial a cappella\nmartial anthem\nmartial band\nmartial brass\nmartial chant\nmartial choral\nmartial drum\nmartial drumming\nmartial electronic\nmartial fanfare\nmartial folk\nmartial folk-pop\nmartial folk-rock\nmartial hip-hop\nmartial hymn\nmartial industrial\nmartial march\nmartial music\nmartial orchestral\nmartial percussion\nmartial rock\nmartial techno\nmashup, chaotic, internet meme\nmashup, dancehall, hip-house\nmashup, electronic, Indian folk\nmashup, pop, electronic\nmashup, pop, rap, Bollywood\nmashup, rock, synth-pop\nmashup, theatrical, synth-pop\nmath metal\nmath rock\nmath rock alternative rock\nmath rock alternative rock post-hardcore\nmath rock ambient\nmath rock chiptune\nmath rock city pop\nmath rock city pop jazz fusion\nmath rock djent\nmath rock dream pop post-hardcore\nmath rock electronic\nmath rock emo\nmath rock emo post-hardcore\nmath rock emo-pop\nmath rock flamenco\nmath rock funk\nmath rock funk J-rock\nmath rock funk chiptune\nmath rock funk fusion\nmath rock funk indie rock\nmath rock funk metal\nmath rock funk psychedelic\nmath rock funk rock\nmath rock funk rock psychedelic rock\nmath rock funk video game music\nmath rock funk-rock\nmath rock gypsy jazz fusion\nmath rock hardcore punk\nmath rock indie\nmath rock indie pop\nmath rock indie rock\nmath rock indie rock post-hardcore\nmath rock indie rock post-rock\nmath rock indie rock shoegaze\nmath rock indie-pop\nmath rock j-rock\nmath rock jangle pop\nmath rock jazz fusion\nmath rock jazz fusion J-pop\nmath rock jazz fusion ambient funk\nmath rock jazz fusion chiptune\nmath rock jazz fusion funk\nmath rock jazz fusion post-rock\nmath rock jazz fusion progressive electronic\nmath rock jazz fusion progressive metal\nmath rock jazz fusion progressive rock\nmath rock jazz fusion video game music\nmath rock lo-fi\nmath rock lo-fi chiptune\nmath rock metalcore\nmath rock metalcore nintendocore\nmath rock neo-soul\nmath rock noise rock\nmath rock pop-punk\nmath rock post-hardcore\nmath rock post-hardcore alt-rock\nmath rock post-hardcore alternative rock\nmath rock post-hardcore metalcore\nmath rock post-hardcore shoegaze\nmath rock post-punk\nmath rock post-rock\nmath rock progressive J-rock\nmath rock progressive folk\nmath rock progressive funk\nmath rock progressive metal\nmath rock progressive metal J-rock\nmath rock progressive metal funk rock\nmath rock progressive metal jazz fusion\nmath rock progressive rock\nmath rock progressive rock video game music\nmath rock punk\nmath rock punk funk\nmath rock punk rock\nmath rock punk rock metalcore\nmath rock shoegaze\nmath rock skate punk\nmath rock, C-pop\nmath rock, C-pop, electronic\nmath rock, C-pop, indie rock\nmath rock, Chinese traditional, electronic\nmath rock, J-pop\nmath rock, J-pop, jazz fusion\nmath rock, J-pop, video game music\nmath rock, J-rock\nmath rock, J-rock, C-pop\nmath rock, J-rock, Vocaloid\nmath rock, J-rock, alternative\nmath rock, J-rock, alternative rock\nmath rock, J-rock, ambient\nmath rock, J-rock, anime\nmath rock, J-rock, chiptune\nmath rock, J-rock, cinematic\nmath rock, J-rock, electronic\nmath rock, J-rock, emo\nmath rock, J-rock, experimental\nmath rock, J-rock, funk\nmath rock, J-rock, hyperpop\nmath rock, J-rock, indie rock\nmath rock, J-rock, instrumental rock\nmath rock, J-rock, jazz fusion\nmath rock, J-rock, metalcore\nmath rock, J-rock, pop-rock\nmath rock, J-rock, post-hardcore\nmath rock, J-rock, progressive metal\nmath rock, J-rock, progressive rock\nmath rock, J-rock, rock\nmath rock, J-rock, shoegaze\nmath rock, J-rock, video game music\nmath rock, Japanese city pop\nmath rock, Japanese rock, chiptune\nmath rock, Japanese rock, video game music\nmath rock, Latin rock\nmath rock, Latin, tribal house\nmath rock, Nintendocore\nmath rock, Nintendocore, post-hardcore\nmath rock, alt rock\nmath rock, alt rock, noise rock\nmath rock, alt-rock, Hindi rock\nmath rock, alt-rock, atmospheric\nmath rock, alternative rock\nmath rock, alternative rock, C-pop\nmath rock, alternative rock, metalcore\nmath rock, ambient, C-pop\nmath rock, ambient, electronic\nmath rock, ambient, rock\nmath rock, breakcore\nmath rock, chiptune\nmath rock, chiptune, J-rock\nmath rock, chiptune, Japanese video game music\nmath rock, chiptune, progressive electronic\nmath rock, chiptune, progressive rock\nmath rock, chiptune, video game music\nmath rock, city pop\nmath rock, city pop, J-rock\nmath rock, city pop, chiptune\nmath rock, city pop, funk\nmath rock, city pop, jazz fusion\nmath rock, denpa-kei\nmath rock, djent, ambient\nmath rock, dream pop, indie rock\nmath rock, dream pop, post-hardcore\nmath rock, dreamy indie rock\nmath rock, electronic pop\nmath rock, electronic rock, trap-metal\nmath rock, electronic, C-pop\nmath rock, electronic, J-pop\nmath rock, electronic, jazz fusion\nmath rock, electronic, rock\nmath rock, emo, alternative rock\nmath rock, emo, hard rock\nmath rock, emo, indie rock\nmath rock, emo, metalcore\nmath rock, emo, pop-punk\nmath rock, emo, post-hardcore\nmath rock, funk rock, post-rock\nmath rock, funk, Japanese\nmath rock, funk, jazz\nmath rock, funk, post-punk\nmath rock, grunge, alternative rock\nmath rock, hard rock\nmath rock, hard rock, C-pop\nmath rock, hardcore punk, sludge metal\nmath rock, heavy metal\nmath rock, heavy rock\nmath rock, hyperpop\nmath rock, hyperpop, Japanese\nmath rock, indie rock\nmath rock, indie rock, Indian pop\nmath rock, indie rock, Indonesian pop\nmath rock, indie rock, Vocaloid pop\nmath rock, indie rock, alternative\nmath rock, indie rock, blues rock\nmath rock, indie rock, cinematic\nmath rock, indie rock, experimental\nmath rock, indie rock, metalcore\nmath rock, indie rock, pop-punk\nmath rock, indie rock, post-hardcore\nmath rock, indie rock, post-rock\nmath rock, indie rock, shoegaze\nmath rock, jazz fusion\nmath rock, jazz fusion, C-pop\nmath rock, jazz fusion, J-rock\nmath rock, jazz fusion, Japanese\nmath rock, jazz fusion, Japanese rock\nmath rock, jazz fusion, funk\nmath rock, jazz fusion, progressive rock\nmath rock, lo-fi hip hop, C-pop\nmath rock, lo-fi hip hop, metalcore\nmath rock, lo-fi hip hop, trap\nmath rock, lo-fi trip-hop\nmath rock, melodic death metal\nmath rock, metal, Hebrew rock\nmath rock, metal, progressive rock\nmath rock, metalcore\nmath rock, metalcore, ambient\nmath rock, metalcore, chiptune\nmath rock, metalcore, indie rock\nmath rock, metalcore, post-hardcore\nmath rock, metalcore, progressive rock\nmath rock, metalcore, shoegaze\nmath rock, midwest emo, C-pop\nmath rock, midwest emo, pop-R&B\nmath rock, noise rock\nmath rock, nu-metal, C-pop\nmath rock, pop-punk\nmath rock, pop-punk, J-rock\nmath rock, pop-punk, chiptune\nmath rock, pop-punk, emo\nmath rock, pop-punk, metalcore\nmath rock, pop-punk, post-hardcore\nmath rock, pop-rock, C-pop\nmath rock, post-hardcore\nmath rock, post-hardcore, Japanese\nmath rock, post-hardcore, Midwest emo\nmath rock, post-hardcore, ambient\nmath rock, post-hardcore, djent\nmath rock, post-hardcore, emo\nmath rock, post-hardcore, indie rock\nmath rock, post-hardcore, lo-fi\nmath rock, post-hardcore, metalcore\nmath rock, post-hardcore, psychedelic\nmath rock, post-hardcore, shoegaze\nmath rock, post-metal, ethereal pop\nmath rock, post-rock\nmath rock, post-rock, Chinese rock\nmath rock, post-rock, K-pop\nmath rock, post-rock, ambient\nmath rock, post-rock, hip hop\nmath rock, post-rock, indie rock\nmath rock, post-rock, progressive metal\nmath rock, post-rock, shoegaze\nmath rock, progressive funk\nmath rock, progressive metal\nmath rock, progressive metal, K-pop\nmath rock, progressive metal, post-hardcore\nmath rock, progressive metal, symphonic rock\nmath rock, progressive metalcore\nmath rock, progressive rock, chiptune\nmath rock, progressive rock, electronic\nmath rock, progressive rock, jazz fusion\nmath rock, progressive rock, post-rock\nmath rock, progressive rock, symphonic metal\nmath rock, psychedelic funk\nmath rock, psychedelic rock, Portuguese rock\nmath rock, psychedelic rock, noise rock\nmath rock, punk rock, chiptune\nmath rock, punk rock, indie pop\nmath rock, rap rock\nmath rock, shoegaze, J-rock\nmath rock, shoegaze, chiptune\nmath rock, shoegaze, glitch\nmath rock, shoegaze, hyperpop\nmath rock, shoegaze, indie\nmath rock, shoegaze, indie rock\nmath rock, shoegaze, noise rock\nmath rock, shoegaze, post-hardcore\nmath rock, shoegaze, post-rock\nmath rock, speed metal, Japanese\nmath rock, surf rock\nmath rock, synth-pop, industrial\nmath rock, thrash metal\nmath rock, thrash metal, Spanish rock\nmath rock, trap, Mandarin hip hop\nmath rock, trap, R&B, boom-bap\nmath rock, trap, gospel\nmath rock, video game music\nmath-folk\nmath-rock\nmath-rock J-rock\nmath-rock R&B\nmath-rock dream-pop\nmath-rock funk\nmath-rock funk-rock\nmath-rock indie-pop\nmath-rock indie-rock\nmath-rock neo-soul\nmath-rock pop-punk\nmath-rock post-hardcore\nmath-rock post-rock\nmath-rock shoegaze\nmath-rock synth-rock\nmath-rock trap\nmath-rock, J-rock\nmath-rock, J-rock, indie rock\nmath-rock, J-rock, lo-fi hip hop\nmath-rock, J-rock, pop-rock\nmath-rock, alt-rock, indie\nmath-rock, djent, rap-rock\nmath-rock, dubstep, ambient\nmath-rock, funk, noise rock\nmath-rock, hyperpop, emo rap\nmath-rock, pop-punk, post-hardcore\nmath-rock, post-hardcore, metalcore\nmath-rock, post-rock, ambient\nmath-rock, post-rock, female vocal\nmath-rock, shoegaze, indie rock\nmath-rock, trap, hyperpop\nmathcore\nmathcore cybergrind\nmathcore funk-rock\nmathcore metalcore\nmathcore noise rock\nmathcore post-hardcore\nmathcore post-rock\nmathcore progressive metal\nmathcore rap-metal\nmathcore skate punk\nmathcore, J-rock\nmathcore, J-rock, electronic\nmathcore, J-rock, metalcore\nmathcore, J-rock, shred metal\nmathcore, Nintendocore\nmathcore, atmospheric rock\nmathcore, chiptune, progressive rock\nmathcore, cybergrind\nmathcore, noise rock\nmathcore, post-rock, metalcore\nmathcore, punk rock, J-rock\nmathcore, vocaloid, flamenco fusion\nmatsuri\nmatsuri punk\nmatsuri rock\nmatsuri samba\nmbaqanga\nmbaqanga afrobeat\nmedieval\nmedieval ambient\nmedieval fantasy\nmedieval folk\nmedieval folk-pop\nmedieval folk-rock\nmedieval hip hop\nmedieval trap\nmeditation\nmeditative\nmeditative C-pop\nmeditative Chinese\nmeditative Chinese ambient\nmeditative Chinese folk\nmeditative Chinese instrumental\nmeditative Indian ambient\nmeditative Indian classical\nmeditative Indian fusion\nmeditative R&B\nmeditative Vietnamese spiritual\nmeditative a cappella\nmeditative acoustic\nmeditative ambient\nmeditative ambient, blues soul\nmeditative ballad\nmeditative bansuri\nmeditative bossa nova\nmeditative chant\nmeditative cinematic\nmeditative classical\nmeditative devotional\nmeditative electronic\nmeditative flamenco\nmeditative flute\nmeditative folk\nmeditative funk\nmeditative groove\nmeditative guzheng\nmeditative hip hop\nmeditative hip-hop\nmeditative house\nmeditative instrumental\nmeditative kalimba\nmeditative lo-fi\nmeditative lullaby\nmeditative oud\nmeditative percussion\nmeditative piano\nmeditative pop\nmeditative pop-folk\nmeditative rhythm\nmeditative rock\nmeditative soul\nmeditative spoken word\nmeditative techno\nmeditative world\nmeditative world beat\nmeditative world fusion\nmeditative world music\nmeditative, devotional, bansuri\nmeditative, spiritual, ancient style\nmelancholic Arabic indie\nmelancholic Arabic pop\nmelancholic C-pop\nmelancholic C-pop trap\nmelancholic Christmas ballad\nmelancholic EDM\nmelancholic Italo-disco\nmelancholic J-pop\nmelancholic Javanese ballad\nmelancholic R&B\nmelancholic R&B hip-hop\nmelancholic R&B trap\nmelancholic R&B, trap, lo-fi hip-hop\nmelancholic Russian pop\nmelancholic Turkish folk\nmelancholic accordion\nmelancholic acoustic\nmelancholic ambient\nmelancholic ballad\nmelancholic ballad, heavy metal\nmelancholic banda\nmelancholic bolero\nmelancholic bossa nova\nmelancholic cello\nmelancholic children's song\nmelancholic chiptune trap\nmelancholic cinematic\nmelancholic classical\nmelancholic cumbia\nmelancholic dance-pop\nmelancholic drill\nmelancholic duduk\nmelancholic duet\nmelancholic electronic\nmelancholic electronica\nmelancholic eurodance\nmelancholic flamenco\nmelancholic folk\nmelancholic fusion\nmelancholic groove\nmelancholic guzheng\nmelancholic hip hop\nmelancholic hip-hop\nmelancholic house\nmelancholic indie\nmelancholic jazz\nmelancholic jazz trap\nmelancholic lo-fi hip hop\nmelancholic ney\nmelancholic oud\nmelancholic piano\nmelancholic piano ballad\nmelancholic piano ballad, Balkan jazz, Klezmer\nmelancholic piano ballad, German hip-hop\nmelancholic piano ballad, Latin groove, theatrical pop\nmelancholic piano ballad, banda, regional Mexican\nmelancholic piano ballad, hard rock\nmelancholic piano ballad, hardstyle, big room house\nmelancholic piano ballad, hip-hop\nmelancholic piano trap\nmelancholic piano, trap, R&B\nmelancholic piano, trap, auto-tuned vocals\nmelancholic piano, trap, hip-hop\nmelancholic pop\nmelancholic pop R&B\nmelancholic pop ballad\nmelancholic pop ballad, Brazilian brega funk\nmelancholic pop ballad, Brazilian pop-rock\nmelancholic pop future bass\nmelancholic pop hip-hop\nmelancholic pop rock\nmelancholic pop trap\nmelancholic pop tropical house\nmelancholic pop, Azerbaijani folk, Turkish classical\nmelancholic pop, Azerbaijani folk, electronic\nmelancholic pop, Brazilian pop\nmelancholic pop, Central Asian folk\nmelancholic pop, Central Asian, synthwave\nmelancholic pop, Eurodance\nmelancholic pop, Fado, cinematic ballad\nmelancholic pop, Javanese, electronic\nmelancholic pop, Middle Eastern pop, Turkish pop\nmelancholic pop, R&B, lo-fi hip-hop\nmelancholic pop, R&B, trap\nmelancholic pop, South Asian pop\nmelancholic pop, South Asian, electronic\nmelancholic pop, Southeast Asian pop\nmelancholic pop, cinematic ballad\nmelancholic pop, dubstep\nmelancholic pop, dubstep, color bass\nmelancholic pop, dubstep, electronic\nmelancholic pop, electronic, Azerbaijani\nmelancholic pop, funk, electronic\nmelancholic pop, future bass\nmelancholic pop, future bass, trap\nmelancholic pop, happy hardcore\nmelancholic pop, hardstyle\nmelancholic pop, hardstyle, EDM\nmelancholic pop, hip-hop, C-pop\nmelancholic pop, modern trap\nmelancholic pop, nu-metal\nmelancholic pop, progressive house\nmelancholic pop, trap R&B\nmelancholic pop, trap, C-pop\nmelancholic pop, trap, Central Asian\nmelancholic pop, trap, Mandarin hip-hop\nmelancholic pop, trap, chiptune\nmelancholic pop, trap, cinematic\nmelancholic pop, trap, hip-hop\nmelancholic pop, trap, lo-fi hip hop\nmelancholic pop, trap, reggaeton\nmelancholic pop-EDM\nmelancholic pop-R&B\nmelancholic pop-ballad\nmelancholic pop-ballad future bass\nmelancholic pop-ballad hip-hop rock\nmelancholic pop-ballad trap\nmelancholic pop-ballad, pop-rock, hip-hop fusion\nmelancholic pop-dance\nmelancholic pop-folk\nmelancholic pop-hip hop\nmelancholic pop-house\nmelancholic pop-rap\nmelancholic pop-rock\nmelancholic pop-rock cumbia norteña\nmelancholic pop-rock, Latin pop, dance-pop\nmelancholic pop-rock, future bass\nmelancholic pop-trap\nmelancholic rap\nmelancholic reggaeton\nmelancholic rock\nmelancholic rock ballad\nmelancholic rock punk\nmelancholic rock, J-rock, metalcore\nmelancholic rumba\nmelancholic soul\nmelancholic synth\nmelancholic tango\nmelancholic techno\nmelancholic trance\nmelancholic trap\nmelancholic trap R&B\nmelancholic trap ballad\nmelancholic trap soul\nmelancholic trap, ambient hip hop\nmelancholic trap, classic hip-hop\nmelancholic trap, emo rap, pop-R&B\nmelancholic trap, ethereal pluggnb\nmelancholic trap, indie pop-rock\nmelancholic trap, pop-punk, alternative rock\nmelancholic trip-hop\nmelancholic ukulele trap\nmelancholic vaporwave trap\nmelancholic waltz\nmelancholic world\nmelancholic world music\nmelbourne bounce\nmelbourne bounce, big room, cinematic\nmellow R&B\nmellow jazz\nmelodic C-Rap\nmelodic EDM\nmelodic German trap\nmelodic J-trap\nmelodic Latin trap\nmelodic R&B\nmelodic R&B trap\nmelodic R&B, trap, bass music\nmelodic R&B, vaporwave, hip-hop\nmelodic UK drill\nmelodic artcore, brostep, hardcore\nmelodic ballad\nmelodic death metal\nmelodic death metal chiptune\nmelodic death metal chiptune power metal\nmelodic death metal power metal\nmelodic death metal, J-rock\nmelodic death metal, folk, atmospheric\nmelodic death metal, symphonic metalcore\nmelodic drill\nmelodic drum and bass\nmelodic dubstep\nmelodic dubstep future bass\nmelodic dubstep hardstyle\nmelodic dubstep metalcore\nmelodic dubstep, brostep\nmelodic dubstep, brostep, rap\nmelodic dubstep, color bass, hardstyle\nmelodic dubstep, drum and bass, hardstyle\nmelodic dubstep, hardstyle\nmelodic dubstep, hardstyle, complextro\nmelodic dubstep, hardstyle, electronic pop\nmelodic dubstep, hardstyle, pop ballad\nmelodic dubstep, trancecore, hardstyle\nmelodic electronic\nmelodic electronica\nmelodic emo rap\nmelodic emo-rap\nmelodic future bass\nmelodic glitch-hop\nmelodic hard rock\nmelodic hardcore\nmelodic hardcore pirate metal\nmelodic hardcore punk\nmelodic hardstyle\nmelodic heavy metal\nmelodic hip hop\nmelodic hip-hop\nmelodic hip-hop lo-fi\nmelodic hip-hop trap soul\nmelodic hip-hop trap-soul\nmelodic hip-hop, UK drill\nmelodic house\nmelodic indie\nmelodic metal\nmelodic metal punk\nmelodic metal, metalcore, Finnish rock\nmelodic metalcore\nmelodic metalcore chiptune\nmelodic metalcore chiptune synth rock\nmelodic metalcore trance\nmelodic metalcore, J-rock, power metal\nmelodic oud\nmelodic pop\nmelodic pop ballad, dangdut koplo\nmelodic pop, conscious hip-hop\nmelodic pop-ballad\nmelodic pop-rap\nmelodic pop-rock\nmelodic progressive house\nmelodic punk\nmelodic punk rock\nmelodic rap\nmelodic rap emo rap\nmelodic rap emo rap C-pop\nmelodic rap lo-fi hip hop\nmelodic rap lo-fi hip-hop\nmelodic rap trap\nmelodic rap, Brazilian trap\nmelodic rap, C-pop, lo-fi hip-hop\nmelodic rap, French cloud rap\nmelodic rap, Latin pop, ukulele\nmelodic rap, Mandopop\nmelodic rap, Middle Eastern, ambient\nmelodic rap, Turkish pop\nmelodic rap, afrobeat, trap\nmelodic rap, chiptune, trap\nmelodic rap, cloud rap\nmelodic rap, dream pop, C-pop\nmelodic rap, emotional trap\nmelodic rap, future bass, trap\nmelodic rap, lo-fi hip-hop, Mandopop\nmelodic rap, reggaeton, chill hop\nmelodic rap, reggaeton, dancehall\nmelodic rap, reggaeton, ukulele\nmelodic rap, trap, drill\nmelodic reggaeton\nmelodic riddim\nmelodic rock\nmelodic rock metalcore\nmelodic rock, melodic death metal\nmelodic rock, metalcore, djent\nmelodic soul\nmelodic techno\nmelodic techno acid trance\nmelodic techno darkwave\nmelodic techno future bass\nmelodic techno progressive house\nmelodic techno, deep house, lo-fi hip hop\nmelodic techno, tech house, German indie-pop\nmelodic thrash metal\nmelodic trance\nmelodic trance hardcore dubstep\nmelodic trance hardstyle\nmelodic trance, brostep, complextro\nmelodic trance, brostep, hardcore\nmelodic trance, brostep, hardstyle\nmelodic trance, complexro, dubstep\nmelodic trance, complextro, dubstep\nmelodic trance, complextro, hardstyle\nmelodic trance, drum and bass\nmelodic trance, drum and bass, neurofunk\nmelodic trance, dubstep\nmelodic trance, dubstep, complextro\nmelodic trance, dubstep, hardstyle\nmelodic trance, dubstep, trap\nmelodic trance, hardstyle\nmelodic trance, hardstyle, complexro\nmelodic trance, hardstyle, complextro\nmelodic trance, hardstyle, dubstep\nmelodic trance, hardstyle, hip-hop\nmelodic trance, hardstyle, rapcore\nmelodic trance, neurofunk\nmelodic trance, neurofunk, complextro\nmelodic trap\nmelodic trap C-pop\nmelodic trap R&B\nmelodic trap afro-fusion\nmelodic trap afrobeats\nmelodic trap alternative R&B pop-punk\nmelodic trap chiptune\nmelodic trap cloud rap\nmelodic trap emo rap\nmelodic trap lo-fi hip hop\nmelodic trap lo-fi hip-hop\nmelodic trap, C-Rap\nmelodic trap, C-pop\nmelodic trap, C-pop, cloud rap\nmelodic trap, Desi hip-hop\nmelodic trap, K-hip-hop\nmelodic trap, Latin R&B\nmelodic trap, Nederhop\nmelodic trap, R&B\nmelodic trap, Southern trap\nmelodic trap, UK cloud rap\nmelodic trap, boom-bap hip hop\nmelodic trap, boom-bap hip-hop\nmelodic trap, chiptune, C-pop\nmelodic trap, cloud rap\nmelodic trap, cloud rap, C-pop\nmelodic trap, cloud rap, Mandopop\nmelodic trap, cloud rap, emo trap\nmelodic trap, cloud rap, hyperpop\nmelodic trap, cloud rap, lo-fi hip hop\nmelodic trap, contemporary R&B\nmelodic trap, emo rap\nmelodic trap, emo rap, C-pop\nmelodic trap, emo rap, R&B\nmelodic trap, emo rap, lo-fi hip hop\nmelodic trap, hardstyle\nmelodic trap, hardstyle, R&B\nmelodic trap, hyperpop\nmelodic trap, hyperpop, chiptune\nmelodic trap, lo-fi hip hop\nmelodic trap, lo-fi hip-hop\nmelodic trap, pluggnb\nmelodic trap, pop-rap\nmelodic trap, tearout dubstep\nmelodic trap-soul\nmeme hip-hop\nmeme house\nmeme rap\nmeme rap chiptune\nmeme rap dancehall\nmeme rap trap\nmeme rap, chiptune, electronic\nmeme rap, chiptune, trap\nmeme rap, trap\nmeme rap, trap, hyperpop\nmeme rap, trap, pop-punk\nmeme trap\nmeme-core\nmeme-pop\nmeme-pop lo-fi\nmeme-rap\nmeme-rap chiptune-trap\nmeme-rap trap\nmeme-rap trap hyperpop\nmeme-rap, chiptune, hyperpop\nmeme-trap\nmeme-trap phonk\nmerengue\nmerengue axé\nmerengue bachata\nmerengue bomba\nmerengue bopa\nmerengue children's\nmerengue chiptune\nmerengue cinematic\nmerengue cumbia\nmerengue cumbia Latin dance\nmerengue de ritmo\nmerengue dembow\nmerengue electronic\nmerengue electronico\nmerengue funk\nmerengue fusion\nmerengue gospel\nmerengue hip-hop\nmerengue hip-hop fusion\nmerengue house\nmerengue lento\nmerengue novelty\nmerengue pop\nmerengue protest\nmerengue ranchero\nmerengue reggaeton\nmerengue salsa\nmerengue salsa bachata\nmerengue samba-reggae\nmerengue soul\nmerengue tropical\nmerengue, Latin Christmas, festive\nmerengue, Latin Christmas, melancholic\nmerengue, Latin Christmas, novelty\nmerengue, Latin dance\nmerengue, Latin jazz, lo-fi\nmerengue, Latin pop, lo-fi\nmerengue, Latin pop, party\nmerengue, chiptune, Latin dance\nmerengue, cinematic, Latin pop\nmerengue, classical, choral\nmerengue, cumbia, reggaeton\nmerengue, electronic, dance\nmerengue, electronic, party\nmerengue, flamenco, Latin pop\nmerengue, pop, synth\nmerengue, retro, chiptune\nmerengue, retro, synth funk\nmerengue, synth-pop\nmerengue-reggaeton\nmeta-pop\nmeta-pop trap\nmetal\nmetal V-pop\nmetal alternative rock\nmetal ballad\nmetal chiptune\nmetal cumbia\nmetal djent\nmetal folk\nmetal fusion\nmetal kuthu\nmetal merengue\nmetal opera\nmetal polka\nmetal polka norteño\nmetal rap\nmetal reggae\nmetal rock\nmetal schlager\nmetal trap\nmetal trap industrial\nmetal, Balkan folk, chiptune\nmetal, C-pop\nmetal, C-pop, ancient style\nmetal, C-pop, cinematic\nmetal, Chinese folk, cinematic\nmetal, Chinese fusion\nmetal, Chinese fusion, Vocaloid\nmetal, Chinese opera, hard rock\nmetal, Chinese rock\nmetal, East Asian fusion\nmetal, Indian classical, experimental\nmetal, Indian film music\nmetal, J-rock\nmetal, J-rock, Chinese fusion\nmetal, JRPG, cinematic\nmetal, Japanese folk\nmetal, Japanese rock\nmetal, Latin rock\nmetal, Mediterranean, Turkish rock\nmetal, Middle Eastern folk\nmetal, Middle Eastern fusion\nmetal, Middle Eastern, experimental\nmetal, Middle Eastern, fusion\nmetal, Middle Eastern, instrumental\nmetal, Middle Eastern, operatic\nmetal, Middle Eastern, progressive\nmetal, Neue Deutsche Härte, melodic death metal\nmetal, Vietnamese, cinematic\nmetal, acoustic, comedy\nmetal, ambient, rock\nmetal, brass, chiptune\nmetal, chiptune\nmetal, chiptune, Japanese video game music\nmetal, chiptune, electronic\nmetal, chiptune, hyper-speed\nmetal, chiptune, instrumental\nmetal, chiptune, neoclassical\nmetal, chiptune, speed metal\nmetal, chiptune, speedcore\nmetal, chiptune, symphonic\nmetal, chiptune, video game music\nmetal, cinematic, Javanese\nmetal, cinematic, Middle Eastern\nmetal, cinematic, folk\nmetal, cinematic, orchestral\nmetal, cinematic, piano rock\nmetal, cinematic, symphonic\nmetal, cinematic, world music\nmetal, classical, flamenco\nmetal, dance-pop, Tamil\nmetal, dance-pop, hip-hop\nmetal, deathcore, atmospheric\nmetal, deathcore, modern metal\nmetal, devotional, electronic\nmetal, djent, aggressive\nmetal, djent, modern metal\nmetal, electronic rock\nmetal, electronic, J-rock\nmetal, electronic, Sanskrit\nmetal, electronic, industrial\nmetal, electronic, instrumental\nmetal, electronic, symphonic\nmetal, flamenco\nmetal, flamenco, Middle Eastern\nmetal, flamenco, cinematic\nmetal, funk, video game\nmetal, guzheng, cinematic\nmetal, modern metal, Chinese metal\nmetal, ney, cinematic\nmetal, nu-metal, industrial\nmetal, oud, cinematic\nmetal, oud, fusion\nmetal, oud, taqsim\nmetal, punk, Turkish rock\nmetal, rap metal, Indonesian\nmetal, rap-metal, aggressive\nmetal, rap-metal, cinematic\nmetal, traditional Malay, ney flute\nmetal, video game music\nmetal, video game music, Japanese\nmetal, world fusion\nmetal, world music, cinematic\nmetal, world music, electronic\nmetal, world music, progressive\nmetalcore\nmetalcore J-rock\nmetalcore J-rock electronicore\nmetalcore alternative metal\nmetalcore alternative rock\nmetalcore ambient\nmetalcore chiptune\nmetalcore chiptune J-rock\nmetalcore chiptune cinematic\nmetalcore chiptune electronic\nmetalcore chiptune electronic rock\nmetalcore chiptune electronicore\nmetalcore chiptune industrial\nmetalcore chiptune j-rock\nmetalcore chiptune symphonic\nmetalcore chiptune synth-pop\nmetalcore chiptune synth-rock\nmetalcore chiptune synthwave\nmetalcore chiptune trance\nmetalcore cinematic\nmetalcore cumbia\nmetalcore cyber-metal\nmetalcore cybergrind\nmetalcore dance-punk\nmetalcore djent\nmetalcore djent alternative rock\nmetalcore djent cinematic\nmetalcore djent rap-metal\nmetalcore drum & bass\nmetalcore dubstep\nmetalcore electronic\nmetalcore electronic J-rock\nmetalcore electronic chiptune\nmetalcore electronic j-rock\nmetalcore electronic pop-punk\nmetalcore electronic rock\nmetalcore electronic symphonic\nmetalcore electronic trance\nmetalcore electronicore\nmetalcore electronicore J-rock\nmetalcore electronicore hyperpop\nmetalcore electronicore post-hardcore\nmetalcore emo\nmetalcore emo-rap\nmetalcore glitch\nmetalcore groove metal\nmetalcore hard trance\nmetalcore hardstyle\nmetalcore hip hop\nmetalcore hip-hop\nmetalcore hyperpop\nmetalcore hyperpop electronic\nmetalcore industrial\nmetalcore j-rock\nmetalcore j-rock chiptune\nmetalcore nintendocore\nmetalcore nintendocore ska-punk\nmetalcore nu-metal\nmetalcore nu-metal alternative rock\nmetalcore nu-metal anime\nmetalcore nu-metal electronic\nmetalcore nu-metal pop-punk\nmetalcore nu-metal rap-metal\nmetalcore pop-punk\nmetalcore pop-rock\nmetalcore post-grunge\nmetalcore post-hardcore\nmetalcore post-metal\nmetalcore post-rock\nmetalcore power metal\nmetalcore progressive metal\nmetalcore progressive rock\nmetalcore punk rock\nmetalcore punk rock chiptune\nmetalcore rap\nmetalcore rap dubstep\nmetalcore rap electronic\nmetalcore rap-metal\nmetalcore rap-rock\nmetalcore rapcore\nmetalcore reggae\nmetalcore ska-punk\nmetalcore skate punk\nmetalcore sludge metal\nmetalcore symphonic\nmetalcore symphonic power metal\nmetalcore synthwave\nmetalcore thrash\nmetalcore thrash metal\nmetalcore trance\nmetalcore trance j-rock\nmetalcore trancecore\nmetalcore trap\nmetalcore trap hyperpop\nmetalcore trap-metal\nmetalcore vaporwave\nmetalcore, Arabic fusion\nmetalcore, C-pop\nmetalcore, C-pop, ambient\nmetalcore, C-pop, ancient style\nmetalcore, C-pop, anime soundtrack\nmetalcore, C-pop, cinematic\nmetalcore, C-pop, electronic\nmetalcore, C-pop, hip-hop\nmetalcore, C-pop, trap\nmetalcore, C-rock\nmetalcore, Chinese folk, cinematic\nmetalcore, Chinese fusion\nmetalcore, Chinese fusion, chiptune\nmetalcore, Chinese fusion, cinematic\nmetalcore, Chinese pop\nmetalcore, Chinese traditional\nmetalcore, Chinese traditional, cinematic\nmetalcore, Chinese traditional, trap\nmetalcore, East Asian fusion\nmetalcore, French rock, progressive metal\nmetalcore, J-pop\nmetalcore, J-pop, Vocaloid\nmetalcore, J-pop, anime\nmetalcore, J-pop, rap-metal\nmetalcore, J-rock\nmetalcore, J-rock, C-pop\nmetalcore, J-rock, Chinese folk\nmetalcore, J-rock, Chinese fusion\nmetalcore, J-rock, Mandarin rock\nmetalcore, J-rock, Vocaloid\nmetalcore, J-rock, anime\nmetalcore, J-rock, anime rock\nmetalcore, J-rock, anime theme\nmetalcore, J-rock, anison\nmetalcore, J-rock, chiptune\nmetalcore, J-rock, cinematic\nmetalcore, J-rock, electronic\nmetalcore, J-rock, hyperpop\nmetalcore, J-rock, melodic metal\nmetalcore, J-rock, neoclassical synth\nmetalcore, J-rock, nu-metal\nmetalcore, J-rock, pop-punk\nmetalcore, J-rock, post-hardcore\nmetalcore, J-rock, power metal\nmetalcore, J-rock, rap-metal\nmetalcore, J-rock, symphonic metal\nmetalcore, J-rock, traditional Japanese\nmetalcore, J-rock, video game soundtrack\nmetalcore, J-rock, visual kei\nmetalcore, K-pop, R&B\nmetalcore, Mandopop\nmetalcore, Middle Eastern folk\nmetalcore, Middle Eastern folk, electronic\nmetalcore, Middle Eastern, electronic\nmetalcore, Neue Deutsche Härte\nmetalcore, Nintendocore\nmetalcore, Nintendocore, J-rock\nmetalcore, Nintendocore, hyperpop\nmetalcore, Spanish rock, experimental\nmetalcore, Vocaloid, math rock\nmetalcore, alternative metal\nmetalcore, alternative metal, djent\nmetalcore, alternative rock\nmetalcore, alternative rock, ambient\nmetalcore, alternative rock, electronic\nmetalcore, alternative rock, hard rock\nmetalcore, alternative rock, pop-punk\nmetalcore, alternative rock, post-hardcore\nmetalcore, alternative rock, trap\nmetalcore, ambient, chiptune\nmetalcore, ambient, dark fantasy\nmetalcore, ambient, electronic\nmetalcore, ambient, industrial\nmetalcore, ambient, rock\nmetalcore, anime rock, rap-rock\nmetalcore, anime theme\nmetalcore, anime theme, C-pop\nmetalcore, anime, C-pop\nmetalcore, anime, electronic\nmetalcore, breakcore, synthwave\nmetalcore, brostep, cinematic\nmetalcore, brostep, glitch\nmetalcore, chiptune\nmetalcore, chiptune, C-pop\nmetalcore, chiptune, French rap\nmetalcore, chiptune, J-rock\nmetalcore, chiptune, Nintendocore\nmetalcore, chiptune, ambient\nmetalcore, chiptune, djent\nmetalcore, chiptune, electronic\nmetalcore, chiptune, electronic rock\nmetalcore, chiptune, hip hop\nmetalcore, chiptune, operatic\nmetalcore, chiptune, pop-punk\nmetalcore, chiptune, post-rock\nmetalcore, chiptune, rap\nmetalcore, chiptune, rap-metal\nmetalcore, chiptune, synth-pop\nmetalcore, chiptune, theatrical punk\nmetalcore, chiptune, trap\nmetalcore, cinematic electronic\nmetalcore, cinematic rock\nmetalcore, cinematic, C-pop\nmetalcore, cinematic, J-rock\nmetalcore, cinematic, ambient\nmetalcore, cinematic, djent\nmetalcore, cinematic, electronic\nmetalcore, cinematic, ethereal\nmetalcore, cinematic, guzheng\nmetalcore, cinematic, hip-hop\nmetalcore, cinematic, horror\nmetalcore, cinematic, hyperpop\nmetalcore, cinematic, lo-fi\nmetalcore, cinematic, post-hardcore\nmetalcore, cinematic, symphonic\nmetalcore, deathcore\nmetalcore, deathcore, Christmas\nmetalcore, deathcore, alternative rock\nmetalcore, deathcore, ambient\nmetalcore, deathcore, atmospheric rock\nmetalcore, deathcore, chiptune\nmetalcore, deathcore, cinematic\nmetalcore, deathcore, industrial metal\nmetalcore, devotional, ambient\nmetalcore, djent, C-pop fusion\nmetalcore, djent, Chinese metal\nmetalcore, djent, Indonesian rap-metal\nmetalcore, djent, J-rock\nmetalcore, djent, aggressive\nmetalcore, djent, ambient\nmetalcore, djent, atmospheric\nmetalcore, djent, chiptune\nmetalcore, djent, cinematic\nmetalcore, djent, cinematic rock\nmetalcore, djent, deathcore\nmetalcore, djent, dubstep\nmetalcore, djent, electronic\nmetalcore, djent, electronic rock\nmetalcore, djent, flamenco\nmetalcore, djent, nu-metal\nmetalcore, djent, post-hardcore\nmetalcore, djent, post-rock\nmetalcore, djent, rap-metal\nmetalcore, djent, rap-rock\nmetalcore, drum and bass, ambient\nmetalcore, dubstep, ambient\nmetalcore, dubstep, drum & bass\nmetalcore, electronic\nmetalcore, electronic dance music\nmetalcore, electronic rock\nmetalcore, electronic rock, Nintendocore\nmetalcore, electronic rock, djent\nmetalcore, electronic, J-rock\nmetalcore, electronic, Mandarin rock\nmetalcore, electronic, ambient\nmetalcore, electronic, brostep\nmetalcore, electronic, chiptune\nmetalcore, electronic, cinematic\nmetalcore, electronic, cyberpunk\nmetalcore, electronic, djent\nmetalcore, electronic, dubstep\nmetalcore, electronic, hip-hop\nmetalcore, electronic, industrial\nmetalcore, electronic, nu-metal\nmetalcore, electronic, rap\nmetalcore, electronicore, chiptune\nmetalcore, electronicore, cinematic\nmetalcore, electronicore, dubstep\nmetalcore, electronicore, rap-metal\nmetalcore, electronicore, trancecore\nmetalcore, emo, trap\nmetalcore, emo-rap, ambient\nmetalcore, ethereal wave, industrial metal\nmetalcore, flamenco, world fusion\nmetalcore, folk, electronic\nmetalcore, funk rock, psychedelic\nmetalcore, glitch, djent\nmetalcore, glitch, electronic\nmetalcore, glitch, rap-metal\nmetalcore, happy hardcore\nmetalcore, happy hardcore, trance\nmetalcore, hardcore electronic\nmetalcore, hardstyle\nmetalcore, hardstyle, cinematic\nmetalcore, hip-hop, cinematic\nmetalcore, horror punk\nmetalcore, hyperpop, electronic\nmetalcore, hyperpop, electronic rock\nmetalcore, indie rock, post-hardcore\nmetalcore, indie rock, rap-rock\nmetalcore, indie-folk\nmetalcore, indie-pop, French pop\nmetalcore, industrial, Chinese rock\nmetalcore, industrial, electronic\nmetalcore, j-rock, ambient\nmetalcore, jazz noir, post-hardcore\nmetalcore, korean rap, electronic\nmetalcore, lo-fi hip-hop, alternative rock\nmetalcore, lo-fi hip-hop, rap-metal\nmetalcore, lo-fi, dream pop\nmetalcore, lo-fi, post-hardcore\nmetalcore, lo-fi, vaporwave\nmetalcore, math rock, djent\nmetalcore, math rock, emo\nmetalcore, math rock, hip-hop\nmetalcore, mathcore, ambient\nmetalcore, melodic death metal\nmetalcore, melodic rock\nmetalcore, neurofunk, drum and bass\nmetalcore, neurofunk, electronic\nmetalcore, nintendocore\nmetalcore, nintendocore, djent\nmetalcore, nintendocore, j-rock\nmetalcore, nu-disco, cinematic\nmetalcore, nu-metal\nmetalcore, nu-metal, C-pop\nmetalcore, nu-metal, ambient\nmetalcore, nu-metal, atmospheric\nmetalcore, nu-metal, chiptune\nmetalcore, nu-metal, cinematic\nmetalcore, nu-metal, electronic\nmetalcore, nu-metal, pop cover\nmetalcore, nu-metal, post-hardcore\nmetalcore, nu-metal, progressive metal\nmetalcore, nu-metal, rap-rock\nmetalcore, operatic, Indonesian\nmetalcore, oud, cinematic\nmetalcore, pop, C-pop\nmetalcore, pop-punk\nmetalcore, pop-punk, ambient\nmetalcore, pop-punk, country-folk\nmetalcore, pop-punk, nu-metal\nmetalcore, pop-punk, rap-metal\nmetalcore, pop-punk, trap\nmetalcore, pop-rock\nmetalcore, pop-rock, Chinese rock\nmetalcore, pop-rock, electronic\nmetalcore, pop-rock, rap-metal\nmetalcore, post-hardcore\nmetalcore, post-hardcore, Indonesian rock\nmetalcore, post-hardcore, J-rock\nmetalcore, post-hardcore, ambient\nmetalcore, post-hardcore, atmospheric\nmetalcore, post-hardcore, chiptune\nmetalcore, post-hardcore, cinematic rock\nmetalcore, post-hardcore, djent\nmetalcore, post-hardcore, nu-metal\nmetalcore, post-hardcore, rap rock\nmetalcore, post-hardcore, rap-metal\nmetalcore, post-hardcore, symphonic metal\nmetalcore, post-hardcore, vaporwave\nmetalcore, post-rock, C-pop\nmetalcore, post-rock, ambient\nmetalcore, post-rock, dream pop\nmetalcore, post-rock, lo-fi\nmetalcore, post-rock, pop-punk\nmetalcore, power metal, J-rock\nmetalcore, power metal, cinematic\nmetalcore, power metal, electronic\nmetalcore, power metal, pop-rock\nmetalcore, power metal, symphonic metal\nmetalcore, progressive metal, Nintendocore\nmetalcore, progressive rock, chiptune\nmetalcore, progressive rock, math rock\nmetalcore, rap metal\nmetalcore, rap rock\nmetalcore, rap rock, electronic\nmetalcore, rap-metal, C-pop\nmetalcore, rap-metal, ambient\nmetalcore, rap-metal, atmospheric\nmetalcore, rap-metal, ballad\nmetalcore, rap-metal, cinematic\nmetalcore, rap-metal, djent\nmetalcore, rap-metal, electronic\nmetalcore, rap-metal, industrial\nmetalcore, rap-metal, post-hardcore\nmetalcore, rap-rock, cinematic\nmetalcore, rap-rock, hyperpop\nmetalcore, sci-fi, cinematic\nmetalcore, screamo, electronic\nmetalcore, shoegaze, mathcore\nmetalcore, symphonic metal\nmetalcore, synth-pop, J-rock\nmetalcore, synth-pop, art-pop\nmetalcore, synth-rock, dubstep\nmetalcore, synth-rock, electronic\nmetalcore, theatrical rock, ragtime\nmetalcore, theatrical rock, synthwave\nmetalcore, trance, cinematic\nmetalcore, trap, Middle Eastern\nmetalcore, trap, electronic\nmetalcore, trap, rap\nmetalcore, vaporwave, R&B\nmetalcore, vaporwave, chiptune\nmetalcore, vaporwave, emo\nmetalcore, video game music\nmetalcore, video game music, Nintendocore\nmetalcore, video game music, instrumental\nmetallic trap\nmetalstep\nmetalstep djent\nmicrohouse\nmicrohouse techno ambient\nmicrotonal cello, Arabic trap, emotive\nmid-1960s pop\nmid-2000s R&B\nmid-2000s hip-hop\nmid-20th century pop\nmid-20th-century pop\nmid-century holiday\nmid-century pop\nmid-tempo bass\nmid-tempo dubstep\nmidtempo bass\nmidwest emo\nmidwest emo math rock\nmidwest emo post-hardcore\nmidwest hip-hop\nmidwest rock\nmilitant Arabic\nmilitant Arabic anthem\nmilitant Arabic chant\nmilitant Arabic electronic\nmilitant Arabic protest\nmilitant Christian march\nmilitant Indian political anthem\nmilitant a cappella\nmilitant anthem\nmilitant chant\nmilitant corrido\nmilitant devotional\nmilitant electronic\nmilitant folk\nmilitant hip-hop\nmilitant march\nmilitant marching band\nmilitant orchestral\nmilitant reggae\nmilitant rock\nmilitant trap\nmilitaristic anthem\nmilitaristic drum\nmilitaristic drumline\nmilitaristic drumming\nmilitaristic electronic\nmilitaristic hip-hop\nmilitaristic march\nmilitaristic rock\nmilitaristic trap\nmilitary\nmilitary anthem\nmilitary brass\nmilitary bugle\nmilitary choir\nmilitary drill\nmilitary drum\nmilitary drum corps\nmilitary drumline\nmilitary drumming\nmilitary electronic\nmilitary fanfare\nmilitary folk\nmilitary folk-pop\nmilitary hip-hop\nmilitary march\nmilitary march pop\nmilitary march, eurodance\nmilitary march, funk, disco\nmilitary march, orchestral, operatic\nmilitary music\nmilitary percussion\nmilitary pop\nmilitary pop-rock\nmilitary rap\nmilitary rock\nmilitary tango\nmilonga\nmilonga carnavalito\nmilonga cumbia\nmilonga folk-rock\nmilonga forró\nmilonga ranchera\nmilonga sertanejo\nmilonga tango\nmilonga tango waltz\nmilonga vallenato\nminimal\nminimal Afro-Cuban\nminimal Afro-Latin\nminimal Afrobeat\nminimal IDM\nminimal R&B\nminimal a cappella\nminimal acapella\nminimal ambient\nminimal beat\nminimal beatbox\nminimal chiptune\nminimal classical\nminimal dance-pop\nminimal dancehall\nminimal drum\nminimal drum & bass\nminimal drum and bass\nminimal drum loop\nminimal drum machine\nminimal dub\nminimal electro\nminimal electro-pop\nminimal electro-punk\nminimal electronic\nminimal funk\nminimal future bass\nminimal glitch\nminimal groovy\nminimal groovy pop\nminimal hip hop\nminimal hip-hop\nminimal house\nminimal house worldbeat\nminimal house, deep house\nminimal jazz\nminimal jingle\nminimal jungle\nminimal percussion\nminimal piano\nminimal piano ballad\nminimal pop\nminimal reggaeton\nminimal rock\nminimal soul\nminimal synth\nminimal synth electro\nminimal synth, chillwave, lo-fi house\nminimal synth-pop\nminimal synthwave\nminimal tech\nminimal tech house\nminimal tech-house\nminimal techno\nminimal techno ambient\nminimal techno ambient chillwave\nminimal techno darkwave\nminimal techno deep house\nminimal techno electro\nminimal techno lo-fi hip-hop\nminimal techno, IDM\nminimal techno, IDM, ambient\nminimal techno, IDM, math-funk\nminimal techno, ambient, industrial techno\nminimal techno, electro, chiptune\nminimal techno, experimental electronic\nminimal techno, progressive house\nminimal techno, progressive house, ambient\nminimal techno, progressive trance\nminimal techno, tech house, world electronic\nminimal techno, tech-house, ambient\nminimal techno, tech-house, electronic\nminimal trap\nminimal trap funk-rock\nminimal tribal\nminimal vocal\nminimal wave\nminimal wave, chiptune\nminimal wave, dark electro\nminimal wave, dark electro-pop\nminimal wave, lo-fi hip-hop\nminimal wave, synth-pop, deep house\nminimal world\nminimalism\nminimalism electronica world music\nminimalism world fusion\nminimalist\nminimalist Afro-Cuban\nminimalist Afro-Latin\nminimalist Afrobeat\nminimalist Afrobeats\nminimalist C-pop\nminimalist Dutch hip-hop\nminimalist German hip-hop\nminimalist IDM\nminimalist Indian folk\nminimalist Latin\nminimalist Latin dance\nminimalist Latin electronic\nminimalist Latin hip-hop\nminimalist Latin percussion\nminimalist Latin pop\nminimalist MPB\nminimalist R&B\nminimalist a cappella\nminimalist acapella\nminimalist acoustic\nminimalist afrobeat\nminimalist ambient\nminimalist ambient trap\nminimalist art song\nminimalist ballad\nminimalist bass\nminimalist beat\nminimalist blues\nminimalist bossa nova\nminimalist brass\nminimalist breakbeat\nminimalist cello\nminimalist chanson\nminimalist choral\nminimalist cinematic\nminimalist classical\nminimalist dance-pop\nminimalist deep house\nminimalist drum\nminimalist educational\nminimalist electro\nminimalist electro-pop\nminimalist electronic\nminimalist electronic pop\nminimalist electronic, lo-fi hip hop\nminimalist electronica\nminimalist electropop\nminimalist film score\nminimalist flamenco\nminimalist folk\nminimalist funk\nminimalist funk electro-funk\nminimalist funk-rap\nminimalist funk-rock\nminimalist groove\nminimalist groovy\nminimalist guitar\nminimalist guzheng\nminimalist hip hop\nminimalist hip-hop\nminimalist house\nminimalist indie dance\nminimalist indie electronic\nminimalist indie pop\nminimalist indie rock\nminimalist indie-electronic\nminimalist indie-pop\nminimalist industrial\nminimalist instrumental\nminimalist jazz\nminimalist koto\nminimalist lo-fi\nminimalist lullaby\nminimalist noir\nminimalist opera\nminimalist orchestral\nminimalist percussion\nminimalist piano\nminimalist piano ballad\nminimalist pop\nminimalist pop-R&B\nminimalist pop-rap\nminimalist pop-rock\nminimalist post-punk\nminimalist protest\nminimalist punk\nminimalist rap\nminimalist reggae\nminimalist reggaeton\nminimalist rock\nminimalist soul\nminimalist spiritual\nminimalist spoken word\nminimalist synth\nminimalist synth-pop\nminimalist tech house\nminimalist tech-house\nminimalist techno\nminimalist techno industrial rock\nminimalist theater\nminimalist torch song\nminimalist trance\nminimalist trap\nminimalist trap rock\nminimalist tribal electronica\nminimalist video game\nminimalist vocal\nminimalist world beat\nminimalist world music\nminimalist worldbeat\nminimalist, ambient, traditional Chinese folk\nminimalist, cinematic, French chanson\nminimalist, cinematic, world fusion\nminimalist, modern classical, ambient\nminyō\nmod revival\nmodern Americana\nmodern Arabic\nmodern Arabic devotional\nmodern Arabic folk\nmodern Arabic pop\nmodern Bhajan\nmodern Bhangra\nmodern C-pop\nmodern Central Asian folk\nmodern Chinese traditional\nmodern Christian hymn\nmodern Christian rock\nmodern Christmas\nmodern Christmas ballad\nmodern Christmas carol\nmodern Christmas lullaby\nmodern Christmas pop\nmodern Dangdut\nmodern East Asian pop\nmodern Enka\nmodern Greek ballad\nmodern Greek folk\nmodern Greek pop\nmodern Greek pop-rock\nmodern Greek rock\nmodern Haryanvi\nmodern Islamic devotional\nmodern Islamic hymn\nmodern Islamic nasheed\nmodern Luk Thung\nmodern Manele\nmodern Middle Eastern\nmodern Middle Eastern dance\nmodern Middle Eastern folk\nmodern Mor Lam\nmodern Naat\nmodern Norteño\nmodern North African pop\nmodern Pop Sunda\nmodern R&B\nmodern R&B Afro-Caribbean\nmodern R&B Afrobeat\nmodern R&B Afrobeat Latin\nmodern R&B Afrobeats\nmodern R&B Balkan\nmodern R&B C-pop\nmodern R&B G-funk\nmodern R&B Indian pop\nmodern R&B Latin\nmodern R&B Latin pop\nmodern R&B Mandopop\nmodern R&B alternative rock\nmodern R&B chillwave\nmodern R&B chiptune\nmodern R&B city pop\nmodern R&B dance-pop\nmodern R&B dancehall\nmodern R&B deep house\nmodern R&B funk\nmodern R&B funk-pop\nmodern R&B future bass\nmodern R&B future bass trap\nmodern R&B gospel\nmodern R&B gospel hip-hop\nmodern R&B hip-hop\nmodern R&B indie pop\nmodern R&B neo-soul\nmodern R&B pop\nmodern R&B pop-rock\nmodern R&B reggae fusion\nmodern R&B reggaeton\nmodern R&B soul\nmodern R&B trap\nmodern R&B tropical\nmodern R&B tropical house\nmodern R&B world music\nmodern R&B, Central Asian\nmodern R&B, Central Asian pop\nmodern R&B, French cloud rap\nmodern R&B, Latin R&B\nmodern R&B, Latin pop\nmodern R&B, Latin pop, reggaeton\nmodern R&B, South Asian fusion\nmodern R&B, chillwave\nmodern R&B, dancehall\nmodern R&B, dancehall, trap\nmodern R&B, future bass\nmodern R&B, hip-hop\nmodern R&B, hip-hop, Latin-influenced\nmodern R&B, hip-hop, ambient\nmodern R&B, hip-hop, cinematic\nmodern R&B, hip-hop, emotional Mandarin\nmodern R&B, hip-hop, tropical\nmodern R&B, hyperpop\nmodern R&B, hyperpop, lo-fi\nmodern R&B, lo-fi hip hop\nmodern R&B, neo-soul\nmodern R&B, pop, North African\nmodern R&B, pop, cinematic\nmodern R&B, pop-funk\nmodern R&B, psychedelic soul\nmodern R&B, synth-pop\nmodern R&B, trap\nmodern R&B, trap hip-hop\nmodern R&B, trap, Arabic pop\nmodern R&B, trap, C-pop\nmodern R&B, trap, Central Asian\nmodern R&B, trap, Eastern melody\nmodern R&B, trap, French pop\nmodern R&B, trap, K-pop\nmodern R&B, trap, North African\nmodern R&B, trap, Persian fusion\nmodern R&B, trap, Tagalog pop\nmodern R&B, trap, ambient\nmodern R&B, trap, cinematic\nmodern R&B, trap, ethereal\nmodern R&B, trap, ethnic pop\nmodern R&B, trap, hip-hop\nmodern R&B, trap, lo-fi\nmodern Rai\nmodern Raï\nmodern South Asian pop\nmodern Sundanese pop\nmodern alternative metal\nmodern alternative rock\nmodern americana\nmodern anasheed\nmodern anthem\nmodern bachata\nmodern bebop\nmodern belly dance\nmodern bhajan\nmodern bhangra\nmodern big band jazz\nmodern big-band jazz\nmodern bluegrass\nmodern bolero\nmodern chanson\nmodern choral\nmodern cinematic\nmodern classical\nmodern classical ambient\nmodern classical gospel\nmodern classical hip-hop\nmodern classical jazz\nmodern classical jazz fusion\nmodern classical, Latin jazz\nmodern classical, Latin jazz, flamenco\nmodern corrido\nmodern country\nmodern country gospel\nmodern country rock\nmodern country-folk\nmodern country-gospel\nmodern country-rock\nmodern cumbia\nmodern dancehall\nmodern dangdut\nmodern dangdut koplo\nmodern devotional\nmodern disco\nmodern electronic\nmodern flamenco\nmodern folk\nmodern folk dance\nmodern folk rock\nmodern folk worship\nmodern folk-dance\nmodern folk-pop\nmodern folk-rock\nmodern funk\nmodern funk R&B\nmodern funk city pop\nmodern funk city pop j-pop\nmodern funk gospel\nmodern funk neo-soul\nmodern funk soul\nmodern funk, city pop\nmodern funk, city pop, J-pop\nmodern fusion\nmodern ghazal\nmodern gospel\nmodern gospel R&B\nmodern gospel afrobeats\nmodern gospel afropop\nmodern gospel funk\nmodern gospel reggae\nmodern gospel rock\nmodern gospel soca\nmodern gospel soul\nmodern guacharaca\nmodern hard rock\nmodern heavy metal\nmodern hip-hop\nmodern hip-hop, Central Asian\nmodern hip-hop, boom-bap\nmodern house\nmodern hymn\nmodern hymnody\nmodern instrumental\nmodern jazz\nmodern jazz ballad\nmodern jazz fusion\nmodern jazz lounge\nmodern lullaby\nmodern mambo\nmodern manele\nmodern mariachi\nmodern metal\nmodern metal djent\nmodern pagode\nmodern patriotic rock\nmodern polka\nmodern pop\nmodern pop R&B\nmodern pop ballad\nmodern pop dangdut\nmodern pop hip-hop\nmodern pop trap\nmodern pop, Central Asian\nmodern pop, Central Asian folk\nmodern pop, Central Asian pop\nmodern pop, Dangdut\nmodern pop, EDM\nmodern pop, Indonesian, electronic rock\nmodern pop, Malay pop, electronic\nmodern pop, Malay traditional\nmodern pop, Middle Eastern fusion\nmodern pop, Middle Eastern pop\nmodern pop, Middle Eastern pop, Azerbaijani pop\nmodern pop, North African, Middle Eastern\nmodern pop, Pop Melayu, Dangdut\nmodern pop, Pop Sunda\nmodern pop, South Asian, trap\nmodern pop, Southeast Asian pop\nmodern pop, dangdut\nmodern pop, dangdut koplo\nmodern pop, dangdut koplo, eurodance\nmodern pop, dangdut, Melayu\nmodern pop, future bass\nmodern pop, pop-rock, Malay traditional\nmodern pop-R&B\nmodern pop-dance\nmodern pop-rock\nmodern power ballad\nmodern punk rock\nmodern ragtime\nmodern ranchera\nmodern reggae\nmodern reggae gospel\nmodern regional folk\nmodern rock\nmodern rock chiptune\nmodern rock country-rock\nmodern rock funk\nmodern rock hip-hop\nmodern rock metalcore\nmodern rock nu-metal\nmodern rock shoegaze\nmodern rock worship\nmodern rock, Indonesian fusion\nmodern rock, Indonesian traditional\nmodern rock, J-rock\nmodern rock, J-rock, anime\nmodern rock, J-rock, anime rock\nmodern rock, J-rock, metalcore\nmodern rock, J-rock, nu-metal\nmodern rock, J-rock, pop-punk\nmodern rock, J-rock, post-hardcore\nmodern rock, J-rock, power metal\nmodern rock, Javanese fusion\nmodern rock, Malay fusion\nmodern rock, Malay pop\nmodern rock, cinematic, gamelan\nmodern rock, electronic, metalcore\nmodern rock, electronicore, rap rock\nmodern rock, metalcore\nmodern rock, metalcore, ambient\nmodern rock, rap-rock, cinematic\nmodern rock, rap-rock, metalcore\nmodern rock, traditional Malay\nmodern rumba\nmodern sacred\nmodern sacred choral\nmodern sacred hymn\nmodern salsa\nmodern sea shanty\nmodern soca\nmodern soul\nmodern soul R&B\nmodern soul funk\nmodern soul gospel\nmodern swing\nmodern tango\nmodern timba\nmodern trap\nmodern trap R&B\nmodern trap, North African pop\nmodern trot\nmodern trot big band\nmodern trot rock\nmodern trot, stadium rock\nmodern world music\nmodern worship\nmodern worship pop-rock\nmodern worship rock\nmodern zouk\nmontage, global fusion, cinematic\nmoody R&B\nmoody electronic\nmoody hip-hop\nmoody pop\nmoody pop R&B\nmoody trap\nmoombahton\nmoombahton Bhojpuri fusion\nmoombahton Bollywood\nmoombahton Indian dance\nmoombahton Indian electronic\nmoombahton Indian folk\nmoombahton Indian fusion\nmoombahton Latin electronic\nmoombahton Latin house\nmoombahton Latin tech\nmoombahton R&B\nmoombahton Tollywood\nmoombahton afro-house\nmoombahton balkan pop\nmoombahton big room house\nmoombahton chiptune\nmoombahton chiptune Bhojpuri\nmoombahton chiptune latin\nmoombahton dance-pop\nmoombahton dancehall\nmoombahton dancehall hard dance\nmoombahton dancehall trap\nmoombahton dembow\nmoombahton electro house\nmoombahton folk fusion\nmoombahton global bass\nmoombahton hardstyle\nmoombahton hardstyle Tamil pop\nmoombahton hardstyle trap\nmoombahton hip-hop Indian pop\nmoombahton hyperpop\nmoombahton hyperpop bollywood\nmoombahton hyperpop chiptune\nmoombahton indian pop\nmoombahton kuthu bollywood\nmoombahton pop\nmoombahton pop hip-hop\nmoombahton protest\nmoombahton reggaeton\nmoombahton reggaeton EDM\nmoombahton reggaeton balkan\nmoombahton reggaeton-pop\nmoombahton slap house\nmoombahton trap\nmoombahton trap EDM\nmoombahton trap dancehall\nmoombahton trap hardstyle\nmoombahton, Balkan brass, Latin club\nmoombahton, Balkan pop, trap\nmoombahton, Bengali folk, electronic dance\nmoombahton, Bollywood pop\nmoombahton, Bollywood, dancehall\nmoombahton, Bollywood, electronic\nmoombahton, Bollywood, electronic dance\nmoombahton, Bollywood, pop\nmoombahton, Brazilian funk, electronic dance\nmoombahton, Desi dance\nmoombahton, Desi, electronic\nmoombahton, EDM\nmoombahton, EDM, trap\nmoombahton, French rap, Rai\nmoombahton, Indian bhajan\nmoombahton, Indian club, electronic\nmoombahton, Indian devotional, EDM\nmoombahton, Indian devotional, electronic\nmoombahton, Indian devotional, electronic dance\nmoombahton, Indian electronic\nmoombahton, Indian film music\nmoombahton, Indian film music, EDM\nmoombahton, Indian folk, cinematic\nmoombahton, Indian folk, electronic\nmoombahton, Indian folk, electronic dance\nmoombahton, Indian fusion, electronic\nmoombahton, Indian hip hop\nmoombahton, Indian pop\nmoombahton, Latin dance, Middle Eastern\nmoombahton, Latin electronic\nmoombahton, Latin electronic, dance\nmoombahton, Latin electronic, hard dance\nmoombahton, Latin house, electronic\nmoombahton, Latin pop, EDM\nmoombahton, Latin rap, hard dance\nmoombahton, Latin trap\nmoombahton, Latin urban\nmoombahton, Nepali folk, electronic\nmoombahton, South Asian folk, electronic\nmoombahton, South Asian folk, electronic dance\nmoombahton, South Asian fusion\nmoombahton, South Asian fusion, electronic\nmoombahton, South Asian fusion, electronic dance\nmoombahton, South Asian pop\nmoombahton, South Indian pop\nmoombahton, South Indian pop, dance\nmoombahton, Spanish pop-rock\nmoombahton, Tamil electronic, kuthu\nmoombahton, Tamil kuthu, electronic dance\nmoombahton, Tamil pop\nmoombahton, Tamil pop, electronic dance\nmoombahton, Telugu dance, electronic\nmoombahton, Tollywood, Indian dance\nmoombahton, Tollywood, pop-rock\nmoombahton, Turkish electronic, Middle Eastern fusion\nmoombahton, Turkish pop\nmoombahton, Turkish pop, electronic dance\nmoombahton, cinematic, Indian fusion\nmoombahton, cinematic, Latin pop\nmoombahton, dancehall, EDM\nmoombahton, dancehall, French rap\nmoombahton, electronic dance, Indian folk\nmoombahton, electronic, Indian fusion\nmoombahton, electronic, Middle Eastern\nmoombahton, electronic, South Asian fusion\nmoombahton, folk fusion, electronic\nmoombahton, hard dance, Latin electronic\nmoombahton, hardstyle, EDM\nmoombahton, hardstyle, Latin electronic\nmoombahton, hardstyle, big room house\nmoombahton, kuthu, bollywood\nmoombahton, kuthu, electronic\nmoombahton, lo-fi hip hop\nmoombahton, reggaeton, Eastern European party\nmoombahton, reggaeton, Indian pop\nmoombahton, reggaeton, Middle Eastern EDM\nmoombahton, reggaeton, South Asian fusion\nmoombahton, reggaeton, South Indian\nmoombahton, reggaeton, electronic\nmoombahton, reggaeton, world fusion\nmoombahton, trap, Indian pop\nmotivational anthem\nmotivational chant\nmotivational hip-hop\nmotorik electronic\nmurder folk\nmurga\nmurga candombe\nmurga cumbia\nmusette\nmusette cabaret\nmusette chanson\nmusette guinguette\nmusette gypsy jazz\nmusette klezmer\nmusette, chanson, vintage\nmusette, klezmer, quirky instrumental\nmusic box\nmusic box lullaby\nmusic box, indie-pop, lounge-pop\nmusic hall\nmusic hall, pub rock, theatrical pop\nmusical comedy\nmusical rock\nmusical sting\nmusical theater\nmusical theater R&B\nmusical theater R&B soul\nmusical theater cabaret\nmusical theater classical crossover\nmusical theater funk\nmusical theater funk soul\nmusical theater funk-rock\nmusical theater glam rock pop-punk\nmusical theater hip-hop\nmusical theater hip-hop funk\nmusical theater jazz\nmusical theater pop\nmusical theater pop-punk\nmusical theater pop-rock\nmusical theater punk rock\nmusical theater ragtime\nmusical theater rock\nmusical theater rock opera\nmusical theater rockabilly\nmusical theater satirical\nmusical theater swing\nmusical theater tango\nmusical theater world music\nmusical theater, East Asian, whimsical\nmusical theater, J-pop\nmusical theater, J-pop, hyperpop\nmusical theater, Latin big band, cinematic pop\nmusical theater, Latin pop\nmusical theater, Latin, salsa\nmusical theater, Latin-pop\nmusical theater, anime theme\nmusical theater, big band jazz, comedic\nmusical theater, big band, show tune\nmusical theater, children's music\nmusical theater, chiptune, novelty pop\nmusical theater, chiptune, upbeat\nmusical theater, cinematic pop, synth-pop\nmusical theater, conscious hip-hop, gospel\nmusical theater, cumbia, folk rock\nmusical theater, dubstep, hardstyle\nmusical theater, electronic, heavy rock\nmusical theater, funk pop, rap\nmusical theater, novelty, hip-hop\nmusical theater, pop-rap\nmusical theater, pop-rap, funk\nmusical theater, pop-rock, jazz\nmusical theater, pop-soul\nmusical theater, swing, comedy rock\nmusical theater, synth-pop\nmusical theater, video game soundtrack\nmusical theater, video game, villainous\nmusical theatre\nmusical theatre cabaret\nmusical theatre jazz\nmusical theatre pop\nmusical theatre, cabaret, symphonic metal\nmusical theatre, calypso, operatic\nmusical theatre, cinematic, big band\nmusical theatre, comedy, parody\nmusical theatre, cumbia\nmystical R&B\nmystical ambient\nmystical electronic\nmystical folk\nmystical fusion\nmystical hip-hop\nmystical pop\nmystical pop-rock\nmystical trap\nmystical world fusion\nmythological drill\nmythological hip-hop\nmythological trap\nmúsica Gaúcha\nmúsica gaúcha\nmúsica llanera\nmúsica popular\nmúsica popular brasileira\nmúsica tropical\nnarrative ambient\nnarrative ballad\nnarrative folk\nnarrative guitar\nnarrative hip-hop\nnarrative piano\nnarrative piano ballad\nnarrative pop\nnarrative pop, hyperpop, nightcore\nnarrative rock\nnarrative trap\nnasheed\nnasheed hip-hop\nnasheed pop\nnasheed, electronic dancehall\nnasheed, electronic, ambient\nnasheed, world music, South Asian pop\nnashid\nnatural ambience\nnature ambience\nnature sound\nnature sounds\nnature soundscape\nnautical ballad\nnautical corrido\nnautical cumbia\nnautical folk\nnederpop\nnefes\nneo soul\nneo-Romantic\nneo-Romantic classical\nneo-Romantic orchestral\nneo-ambient\nneo-baroque\nneo-baroque chamber folk\nneo-baroque chiptune\nneo-baroque orchestral\nneo-city pop\nneo-classical\nneo-classical Anatolian\nneo-classical C-pop\nneo-classical J-rock\nneo-classical Latin jazz-pop\nneo-classical Latin pop\nneo-classical R&B\nneo-classical Turkish folk\nneo-classical a cappella\nneo-classical acoustic\nneo-classical alt-rock\nneo-classical alternative rock\nneo-classical ambient\nneo-classical art song\nneo-classical ballad\nneo-classical bhajan\nneo-classical cabaret\nneo-classical chamber\nneo-classical chillwave\nneo-classical choral\nneo-classical cinematic\nneo-classical crossover\nneo-classical deep house\nneo-classical downtempo\nneo-classical dream pop\nneo-classical electronic\nneo-classical fantasy\nneo-classical flamenco\nneo-classical folk\nneo-classical folk rock\nneo-classical folk-rock\nneo-classical funk\nneo-classical funk-rock\nneo-classical guitar\nneo-classical hip-hop\nneo-classical indie folk\nneo-classical indie folk-rock\nneo-classical indie rock\nneo-classical industrial rock\nneo-classical jazz\nneo-classical jazz fusion\nneo-classical lo-fi hip-hop\nneo-classical lounge\nneo-classical lounge jazz\nneo-classical lullaby\nneo-classical metal\nneo-classical new wave\nneo-classical opera\nneo-classical orchestral\nneo-classical pop\nneo-classical pop-rock\nneo-classical post-rock\nneo-classical power-pop\nneo-classical progressive rock\nneo-classical progressive trance\nneo-classical punk rock\nneo-classical reggaeton\nneo-classical rock\nneo-classical salsa\nneo-classical soul-rock\nneo-classical spoken word\nneo-classical synth-pop\nneo-classical trap\nneo-classical trip-hop\nneo-classical world fusion\nneo-classical, Bollywood, cinematic\nneo-classical, J-rock\nneo-classical, JRPG soundtrack\nneo-classical, Latin, ambient\nneo-classical, alternative rock, cinematic\nneo-classical, big band, klezmer\nneo-classical, cinematic, Eastern-influenced\nneo-classical, cinematic, Greek folk\nneo-classical, cinematic, JRPG\nneo-classical, cinematic, flamenco\nneo-classical, cinematic, jazz fusion\nneo-classical, cinematic, operatic\nneo-classical, cinematic, trip-hop\nneo-classical, electronic, cinematic\nneo-classical, experimental electronic\nneo-classical, folk, hip-hop\nneo-classical, folk, operatic\nneo-classical, indie rock\nneo-classical, indie rock, French pop\nneo-classical, industrial electronic\nneo-classical, industrial rock, cinematic\nneo-classical, industrial rock, folk\nneo-classical, lo-fi hip-hop, nu-metal\nneo-classical, musical theater\nneo-classical, new age, cinematic\nneo-classical, new age, video game soundtrack\nneo-classical, operatic, digital Schlager\nneo-classical, soft rock, spiritual\nneo-classical, soul, Americana\nneo-classical, symphonic metal\nneo-classical, symphonic rock, cabaret\nneo-classical, world fusion, cinematic\nneo-cumbia\nneo-disco\nneo-ethnic\nneo-ethnic hip hop\nneo-ethnic pop\nneo-ethno\nneo-folk\nneo-folk cinematic\nneo-funk\nneo-funk R&B\nneo-funk acid jazz\nneo-funk city pop\nneo-funk city-pop\nneo-funk disco\nneo-funk electro-funk\nneo-funk lounge\nneo-funk new jack swing\nneo-funk pop\nneo-funk synth-rock\nneo-funk vaporwave\nneo-funk, G-funk\nneo-funk, R&B, new jack swing\nneo-funk, lo-fi hip hop, video game\nneo-funk, new jack swing\nneo-funk, new jack swing, retro-futuristic\nneo-funk, synth-pop, French pop\nneo-ghazal\nneo-noir jazz hip-hop\nneo-oriental\nneo-oriental ballad\nneo-oriental rock\nneo-psychedelia\nneo-raqs\nneo-romantic\nneo-romantic chamber\nneo-romantic classical\nneo-romantic orchestral\nneo-romantic piano\nneo-romantic piano ballad\nneo-sierreño rap\nneo-soul\nneo-soul Afro-Brazilian\nneo-soul Afro-Latin\nneo-soul Afro-fusion\nneo-soul Afro-pop\nneo-soul Afrobeat\nneo-soul Afrobeats\nneo-soul C-pop\nneo-soul C-pop R&B\nneo-soul C-pop city pop\nneo-soul C-pop lo-fi hip-hop\nneo-soul C-pop lounge\nneo-soul C-pop trip-hop\nneo-soul Christmas\nneo-soul French\nneo-soul French R&B\nneo-soul French chanson\nneo-soul French hip-hop\nneo-soul French pop\nneo-soul French pop zouk\nneo-soul G-funk\nneo-soul IDM\nneo-soul J-R&B\nneo-soul J-hip-hop\nneo-soul J-pop\nneo-soul J-pop fusion\nneo-soul J-rock\nneo-soul Japanese hip-hop\nneo-soul K-R&B\nneo-soul K-hip-hop\nneo-soul K-pop\nneo-soul Latin\nneo-soul Latin R&B\nneo-soul Latin funk\nneo-soul Latin groove\nneo-soul Latin hip-hop\nneo-soul Latin house\nneo-soul Latin jazz\nneo-soul Latin lounge\nneo-soul Latin pop\nneo-soul Latin rock\nneo-soul MPB\nneo-soul MPB bossa nova\nneo-soul MPB jazz\nneo-soul MPB lo-fi\nneo-soul Mandopop\nneo-soul Mandopop city pop\nneo-soul R&B\nneo-soul R&B 80s synth-pop\nneo-soul R&B 90s\nneo-soul R&B 90s hip-hop\nneo-soul R&B 90s throwback\nneo-soul R&B Bossa Nova\nneo-soul R&B Brazilian\nneo-soul R&B Caribbean\nneo-soul R&B Christmas\nneo-soul R&B G-funk\nneo-soul R&B J-pop\nneo-soul R&B Japanese pop\nneo-soul R&B K-pop\nneo-soul R&B Latin\nneo-soul R&B Latin jazz\nneo-soul R&B Latin pop\nneo-soul R&B MPB\nneo-soul R&B Mandopop\nneo-soul R&B UK hip-hop\nneo-soul R&B alt-rock\nneo-soul R&B alternative rock\nneo-soul R&B ambient\nneo-soul R&B bossa nova\nneo-soul R&B chanson\nneo-soul R&B chillwave\nneo-soul R&B chiptune\nneo-soul R&B cinematic\nneo-soul R&B city pop\nneo-soul R&B city-pop\nneo-soul R&B conscious hip-hop\nneo-soul R&B flamenco\nneo-soul R&B funk\nneo-soul R&B future bass\nneo-soul R&B gospel\nneo-soul R&B gospel jazz\nneo-soul R&B hip-hop\nneo-soul R&B indie rock\nneo-soul R&B indie-pop\nneo-soul R&B jazz\nneo-soul R&B jazz fusion\nneo-soul R&B jazzy lounge\nneo-soul R&B lo-fi\nneo-soul R&B lo-fi hip-hop\nneo-soul R&B lounge\nneo-soul R&B lounge jazz\nneo-soul R&B lounge-jazz\nneo-soul R&B new jack swing\nneo-soul R&B nu-disco\nneo-soul R&B orchestral\nneo-soul R&B pop\nneo-soul R&B pop-rock\nneo-soul R&B progressive rock\nneo-soul R&B psychedelic indie rock\nneo-soul R&B reggae fusion\nneo-soul R&B rock\nneo-soul R&B singer-songwriter\nneo-soul R&B smooth jazz\nneo-soul R&B trap\nneo-soul R&B vaporwave\nneo-soul UK garage\nneo-soul UK garage gospel\nneo-soul UK hip-hop\nneo-soul a cappella\nneo-soul acid jazz\nneo-soul acid jazz lo-fi\nneo-soul acid jazz lo-fi hip-hop\nneo-soul acid jazz nu-disco\nneo-soul acid jazz progressive rock\nneo-soul acoustic R&B\nneo-soul acoustic folk\nneo-soul afrobeat\nneo-soul afrobeat R&B\nneo-soul afrobeat downtempo\nneo-soul afrobeat tropical\nneo-soul afrobeat world music\nneo-soul afrobeats\nneo-soul alt-rock\nneo-soul alternative R&B\nneo-soul alternative rock\nneo-soul amapiano\nneo-soul ambient\nneo-soul ambient R&B\nneo-soul ambient pop\nneo-soul art rock\nneo-soul ballad\nneo-soul bedroom pop\nneo-soul blues\nneo-soul blues-rock\nneo-soul boom-bap\nneo-soul bossa nova\nneo-soul chamber pop\nneo-soul chill R&B\nneo-soul chill-hop\nneo-soul chill-pop\nneo-soul chillhop\nneo-soul chillout\nneo-soul chillwave\nneo-soul chillwave Afrobeat\nneo-soul chillwave ambient\nneo-soul chillwave lounge\nneo-soul chillwave world music\nneo-soul chiptune\nneo-soul cinematic\nneo-soul city pop\nneo-soul city pop R&B\nneo-soul city pop acid jazz\nneo-soul city pop chiptune\nneo-soul city pop funk\nneo-soul city pop jazz fusion\nneo-soul city pop lo-fi\nneo-soul city pop lo-fi hip-hop\nneo-soul city-pop\nneo-soul classical\nneo-soul conscious hip-hop\nneo-soul conscious hip-hop indie pop\nneo-soul conscious hip-hop reggae\nneo-soul conscious reggae\nneo-soul contemporary gospel\nneo-soul country-rock\nneo-soul dancehall\nneo-soul deep house\nneo-soul downtempo\nneo-soul downtempo R&B\nneo-soul dream pop\nneo-soul dream pop lo-fi hip-hop\nneo-soul dream pop shoegaze\nneo-soul dream-pop\nneo-soul drum and bass\nneo-soul electro-funk\nneo-soul electro-rock\nneo-soul electro-swing dubstep\nneo-soul electronic\nneo-soul electronic funk\nneo-soul electronic rock\nneo-soul experimental art-pop\nneo-soul flamenco\nneo-soul funk\nneo-soul funk Latin\nneo-soul funk MPB\nneo-soul funk R&B\nneo-soul funk UK hip-hop\nneo-soul funk acid jazz\nneo-soul funk city pop\nneo-soul funk city-pop\nneo-soul funk disco\nneo-soul funk disco-pop\nneo-soul funk experimental pop\nneo-soul funk fusion\nneo-soul funk gospel\nneo-soul funk hip-hop\nneo-soul funk jazz\nneo-soul funk jazz fusion\nneo-soul funk jazz-fusion\nneo-soul funk lo-fi\nneo-soul funk lo-fi hip-hop\nneo-soul funk psychedelic rock\nneo-soul funk r&b\nneo-soul funk reggae\nneo-soul funk rock\nneo-soul funk smooth jazz\nneo-soul funk trap R&B\nneo-soul funk tropical\nneo-soul funk, progressive metal\nneo-soul funk-hop\nneo-soul funk-jazz\nneo-soul funk-pop\nneo-soul funk-pop city pop\nneo-soul funk-rap\nneo-soul funk-rock\nneo-soul funk-rock ambient\nneo-soul funk-rock hip-hop\nneo-soul funk-rock math-rock\nneo-soul funk-rock noise-rock\nneo-soul funk-rock progressive metal\nneo-soul funk-rock psychedelic\nneo-soul fusion\nneo-soul future R&B\nneo-soul future bass\nneo-soul future bass uk garage\nneo-soul future funk\nneo-soul future garage\nneo-soul g-funk\nneo-soul g-funk boom-bap\nneo-soul glitch-hop\nneo-soul gospel\nneo-soul gospel R&B\nneo-soul gospel conscious hip-hop\nneo-soul gospel funk\nneo-soul gospel hip-hop\nneo-soul gospel house\nneo-soul gospel jazz fusion\nneo-soul gospel lo-fi hip-hop\nneo-soul gospel-pop\nneo-soul hip hop\nneo-soul hip-hop\nneo-soul hip-hop cabaret\nneo-soul hip-hop cinematic\nneo-soul hip-hop funk-rock\nneo-soul hip-hop fusion\nneo-soul hip-hop gospel\nneo-soul hip-hop lounge\nneo-soul hip-hop orchestral\nneo-soul hip-hop pop\nneo-soul hip-hop pop-R&B\nneo-soul hip-hop reggae\nneo-soul hip-hop vaporwave\nneo-soul hip-hop, rock\nneo-soul house\nneo-soul hyperpop\nneo-soul indie R&B\nneo-soul indie dance\nneo-soul indie funk\nneo-soul indie pop\nneo-soul indie pop garage rock\nneo-soul indie pop hard rock\nneo-soul indie pop lo-fi hip-hop\nneo-soul indie pop-rock\nneo-soul indie rock\nneo-soul indie rock blues-rock\nneo-soul indie rock hip-hop\nneo-soul indie rock shoegaze\nneo-soul indie-folk\nneo-soul indie-pop\nneo-soul industrial\nneo-soul instrumental\nneo-soul j-hip-hop\nneo-soul j-pop\nneo-soul j-pop lo-fi hip-hop\nneo-soul jazz\nneo-soul jazz bossa nova\nneo-soul jazz fusion\nneo-soul jazz fusion lo-fi hip-hop\nneo-soul jazz fusion lounge\nneo-soul jazz lounge\nneo-soul jazz rap\nneo-soul jazz-funk\nneo-soul jazz-funk lo-fi\nneo-soul jazz-funk lo-fi hip-hop\nneo-soul jazz-fusion\nneo-soul jazz-hop\nneo-soul jazz-hop funky soul\nneo-soul jazz-hop lo-fi\nneo-soul jazz-pop\nneo-soul jazz-pop funk-rock\nneo-soul jazz-pop lo-fi\nneo-soul jazz-rap\nneo-soul jazz-rock\nneo-soul jazz-soul\nneo-soul jazzy hip-hop\nneo-soul jazzy house chillwave\nneo-soul jungle\nneo-soul latin\nneo-soul latin fusion\nneo-soul lo-fi\nneo-soul lo-fi MPB\nneo-soul lo-fi R&B\nneo-soul lo-fi bedroom pop\nneo-soul lo-fi chillwave\nneo-soul lo-fi dream-pop\nneo-soul lo-fi experimental\nneo-soul lo-fi funk\nneo-soul lo-fi gospel\nneo-soul lo-fi hip hop\nneo-soul lo-fi hip-hop\nneo-soul lo-fi hip-hop R&B\nneo-soul lo-fi hip-hop alternative rock\nneo-soul lo-fi hip-hop ambient\nneo-soul lo-fi hip-hop chill R&B\nneo-soul lo-fi hip-hop chillwave\nneo-soul lo-fi hip-hop cinematic\nneo-soul lo-fi hip-hop classical\nneo-soul lo-fi hip-hop contemporary R&B\nneo-soul lo-fi hip-hop dancehall\nneo-soul lo-fi hip-hop dream pop\nneo-soul lo-fi hip-hop funk\nneo-soul lo-fi hip-hop future bass\nneo-soul lo-fi hip-hop jazz-hop\nneo-soul lo-fi hip-hop post-rock\nneo-soul lo-fi hip-hop progressive rock\nneo-soul lo-fi hip-hop vaporwave\nneo-soul lo-fi house\nneo-soul lo-fi indie rock\nneo-soul lo-fi jazz\nneo-soul lo-fi jazz-hop\nneo-soul lo-fi jazz-pop\nneo-soul lo-fi pop\nneo-soul lounge\nneo-soul lounge funk-rock\nneo-soul lounge jazz\nneo-soul lounge jazz chillhop\nneo-soul lounge-jazz\nneo-soul lounge-pop\nneo-soul lovers rock\nneo-soul math rock\nneo-soul math-rock\nneo-soul new jack swing\nneo-soul nu-disco\nneo-soul orchestral\nneo-soul piano\nneo-soul pop\nneo-soul pop R&B\nneo-soul pop-R&B\nneo-soul pop-funk\nneo-soul pop-punk\nneo-soul pop-punk nu-metal\nneo-soul pop-rap\nneo-soul pop-rap Indian fusion\nneo-soul pop-rap chillwave\nneo-soul pop-rock\nneo-soul pop-rock MPB\nneo-soul pop-rock R&B\nneo-soul post-rock\nneo-soul progressive metal\nneo-soul progressive rock\nneo-soul psychedelic funk\nneo-soul psychedelic rock\nneo-soul psychedelic soul\nneo-soul punk rock\nneo-soul r&b\nneo-soul reggae\nneo-soul reggae dancehall\nneo-soul reggae fusion\nneo-soul reggae world music\nneo-soul reggae-dancehall\nneo-soul reggae-dub\nneo-soul reggae-funk\nneo-soul reggae-pop\nneo-soul reggaeton\nneo-soul rock\nneo-soul salsa\nneo-soul samba\nneo-soul singer-songwriter\nneo-soul smooth R&B\nneo-soul smooth jazz\nneo-soul smooth jazz lo-fi hip-hop\nneo-soul soul\nneo-soul soul-jazz\nneo-soul synth-funk\nneo-soul synth-pop\nneo-soul tango\nneo-soul trap\nneo-soul trap R&B\nneo-soul trap breakcore\nneo-soul trap-R&B\nneo-soul trap-soul\nneo-soul trip-hop\nneo-soul trip-hop art pop\nneo-soul trip-hop chiptune\nneo-soul trip-hop experimental\nneo-soul trip-hop funk-rock\nneo-soul trip-hop lo-fi\nneo-soul trip-hop psychedelic rock\nneo-soul trip-hop smooth jazz\nneo-soul tropical\nneo-soul vaporwave\nneo-soul world music\nneo-soul worldbeat\nneo-soul, 80s R&B\nneo-soul, 90s R&B\nneo-soul, 90s R&B, lo-fi\nneo-soul, 90s hip-hop\nneo-soul, Afro-Latin, inspirational pop\nneo-soul, Afro-pop, ambient\nneo-soul, Afrobeats, gospel\nneo-soul, Brazilian MPB\nneo-soul, Brazilian pop\nneo-soul, Brazilian pop, lo-fi hip-hop\nneo-soul, Brazilian, smooth jazz\nneo-soul, Christmas, R&B\nneo-soul, East Coast hip-hop\nneo-soul, French R&B, lo-fi hip-hop\nneo-soul, French pop, hip-hop\nneo-soul, G-funk\nneo-soul, G-funk, 90s R&B\nneo-soul, G-funk, R&B\nneo-soul, G-funk, hip-hop\nneo-soul, G-funk, instrumental\nneo-soul, G-funk, jazz rap\nneo-soul, Italian jazz, lo-fi hip hop\nneo-soul, J-rock\nneo-soul, J-rock, C-pop\nneo-soul, J-rock, ambient\nneo-soul, K-R&B\nneo-soul, K-R&B, lo-fi\nneo-soul, K-R&B, pop\nneo-soul, Korean R&B\nneo-soul, Latin R&B\nneo-soul, Latin R&B, trap R&B\nneo-soul, Latin funk-rock\nneo-soul, Latin groove\nneo-soul, Latin hip-hop, jazz\nneo-soul, Latin jazz, funk\nneo-soul, Latin pop\nneo-soul, Latin pop, lo-fi hip-hop\nneo-soul, Latin pop, reggaeton\nneo-soul, Latin salsa\nneo-soul, MPB\nneo-soul, MPB, jazz fusion\nneo-soul, MPB, jazzy\nneo-soul, MPB, lo-fi\nneo-soul, New Jack Swing\nneo-soul, R&B\nneo-soul, R&B, Balkan soul\nneo-soul, R&B, Chinese experimental\nneo-soul, R&B, Chinese hip-hop\nneo-soul, R&B, Christmas\nneo-soul, R&B, Christmas pop\nneo-soul, R&B, G-funk\nneo-soul, R&B, German rap\nneo-soul, R&B, Japanese hip-hop\nneo-soul, R&B, Korean\nneo-soul, R&B, Korean indie\nneo-soul, R&B, Latin\nneo-soul, R&B, West Coast\nneo-soul, R&B, ambient\nneo-soul, R&B, ambient hip-hop\nneo-soul, R&B, bilingual fusion\nneo-soul, R&B, blues-rock\nneo-soul, R&B, boom-bap\nneo-soul, R&B, cinematic\nneo-soul, R&B, city pop\nneo-soul, R&B, city-pop\nneo-soul, R&B, conscious hip-hop\nneo-soul, R&B, dream pop\nneo-soul, R&B, drum and bass\nneo-soul, R&B, early 2000s\nneo-soul, R&B, experimental\nneo-soul, R&B, festive\nneo-soul, R&B, flamenco\nneo-soul, R&B, funk\nneo-soul, R&B, fusion\nneo-soul, R&B, glitch\nneo-soul, R&B, hip-hop\nneo-soul, R&B, house\nneo-soul, R&B, jazz\nneo-soul, R&B, jazz fusion\nneo-soul, R&B, jazzy\nneo-soul, R&B, lo-fi\nneo-soul, R&B, lo-fi hip hop\nneo-soul, R&B, lo-fi hip-hop\nneo-soul, R&B, lounge\nneo-soul, R&B, metalcore\nneo-soul, R&B, new jack swing\nneo-soul, R&B, progressive rock\nneo-soul, R&B, psychedelic\nneo-soul, R&B, rock\nneo-soul, R&B, trap\nneo-soul, R&B, trap-soul\nneo-soul, South African house\nneo-soul, Turkish hip-hop\nneo-soul, UK garage\nneo-soul, UK garage, 2-step\nneo-soul, UK garage, R&B\nneo-soul, UK garage, grime\nneo-soul, UK garage, hip-hop\nneo-soul, acid jazz, Latin pop\nneo-soul, acid jazz, R&B\nneo-soul, acid jazz, lounge\nneo-soul, alt-rock\nneo-soul, alt-rock, dream pop\nneo-soul, alternative R&B, lo-fi\nneo-soul, alternative rock\nneo-soul, alternative rock, C-pop\nneo-soul, alternative rock, Indonesian pop\nneo-soul, alternative rock, lo-fi\nneo-soul, alternative rock, psychedelic\nneo-soul, ambient, East Asian\nneo-soul, ambient, Mongolian\nneo-soul, ambient, electronic\nneo-soul, ambient, industrial\nneo-soul, ambient, jazz\nneo-soul, art-pop\nneo-soul, art-pop, ambient\nneo-soul, blues-rock, French soul\nneo-soul, blues-rock, pop-rock\nneo-soul, boom-bap, ambient\nneo-soul, boom-bap, hip-hop\nneo-soul, boom-bap, jazz rap\nneo-soul, bossa nova, cinematic\nneo-soul, bossa nova, glitch-hop\nneo-soul, breakcore\nneo-soul, breakcore, hyperpop\nneo-soul, breakcore, jazz-funk\nneo-soul, chill hop, jazz rap\nneo-soul, chillhop, ambient\nneo-soul, chillhop, lo-fi hip-hop\nneo-soul, chillwave, R&B\nneo-soul, chillwave, future R&B\nneo-soul, cinematic rock\nneo-soul, cinematic rock, C-pop\nneo-soul, cinematic, Punjabi\nneo-soul, cinematic, ambient\nneo-soul, cinematic, hip hop\nneo-soul, cinematic, hip-hop\nneo-soul, cinematic, lo-fi\nneo-soul, cinematic, lo-fi hip-hop\nneo-soul, cinematic, orchestral\nneo-soul, city pop\nneo-soul, city pop, 90s R&B\nneo-soul, city pop, R&B\nneo-soul, city pop, acid jazz\nneo-soul, city pop, funk\nneo-soul, city pop, retro-funk\nneo-soul, city pop, vaporwave\nneo-soul, city-pop\nneo-soul, city-pop, ambient\nneo-soul, city-pop, chiptune\nneo-soul, city-pop, jazz fusion\nneo-soul, city-pop, lo-fi\nneo-soul, city-pop, mandopop\nneo-soul, complextro, J-core\nneo-soul, conscious hip-hop\nneo-soul, conscious hip-hop, Latin-influenced\nneo-soul, conscious hip-hop, ambient\nneo-soul, conscious hip-hop, atmospheric R&B\nneo-soul, conscious hip-hop, cinematic\nneo-soul, conscious hip-hop, gospel\nneo-soul, conscious hip-hop, jazz rap\nneo-soul, conscious hip-hop, jazzy\nneo-soul, conscious hip-hop, lo-fi\nneo-soul, conscious hip-hop, pop\nneo-soul, conscious hip-hop, psychedelic\nneo-soul, contemporary Mandopop\nneo-soul, contemporary R&B, a cappella\nneo-soul, contemporary gospel\nneo-soul, dancehall, funk\nneo-soul, dancehall, lo-fi hip hop\nneo-soul, deep house, UK garage\nneo-soul, downtempo, cinematic\nneo-soul, downtempo, nu-disco\nneo-soul, dream pop, Mandarin hip hop\nneo-soul, dream pop, Vietnamese indie\nneo-soul, dream pop, conscious hip-hop\nneo-soul, dream pop, rock\nneo-soul, dream-pop, psychedelic\nneo-soul, drum and bass\nneo-soul, drum and bass, Spanish rap\nneo-soul, drum and bass, ambient\nneo-soul, electro-funk, complextro\nneo-soul, electronic rock, trap-metal\nneo-soul, experimental future bass, lo-fi\nneo-soul, experimental hip-hop\nneo-soul, experimental trap, hyperpop\nneo-soul, experimental, cinematic\nneo-soul, experimental, psychedelic\nneo-soul, flamenco, Turkish pop\nneo-soul, flamenco, cinematic\nneo-soul, forró, sertanejo\nneo-soul, funk, R&B\nneo-soul, funk, acid jazz\nneo-soul, funk, city pop\nneo-soul, funk, hip hop\nneo-soul, funk-rock, pop R&B\nneo-soul, future bass, R&B\nneo-soul, future bass, chillwave\nneo-soul, future bass, cinematic\nneo-soul, future bass, hip-hop\nneo-soul, future bass, jazz\nneo-soul, future bass, lo-fi hip-hop\nneo-soul, future bass, spoken word\nneo-soul, future funk, R&B\nneo-soul, future funk, lo-fi\nneo-soul, future soul, trap\nneo-soul, garage rock\nneo-soul, glitch, electronic\nneo-soul, glitch, jazz-hop\nneo-soul, glitch, rock\nneo-soul, glitch-hop\nneo-soul, gospel rock, ambient\nneo-soul, gospel soul, soul-rock\nneo-soul, gospel, Celtic folk\nneo-soul, gospel, Christmas\nneo-soul, gospel, R&B\nneo-soul, gospel, ambient\nneo-soul, gospel, funk\nneo-soul, gospel, hip-hop\nneo-soul, gospel, lo-fi hip hop\nneo-soul, gospel, lounge\nneo-soul, gospel, rock\nneo-soul, hard rock\nneo-soul, hard rock, cinematic rock\nneo-soul, hardstyle, R&B\nneo-soul, heavy metal\nneo-soul, hip hop\nneo-soul, hip hop, R&B\nneo-soul, hip hop, cinematic\nneo-soul, hip-hop, R&B\nneo-soul, hip-hop, Vietnamese spoken word\nneo-soul, hip-hop, a cappella\nneo-soul, hip-hop, ambient\nneo-soul, hip-hop, cinematic\nneo-soul, hip-hop, cinematic pop\nneo-soul, hip-hop, dream-pop\nneo-soul, hip-hop, funk\nneo-soul, hip-hop, future bass\nneo-soul, hip-hop, gospel\nneo-soul, hip-hop, lo-fi\nneo-soul, hip-hop, new jack swing\nneo-soul, hip-hop, pop-rock\nneo-soul, hip-hop, rock\nneo-soul, hyperpop\nneo-soul, hyperpop, ambient\nneo-soul, hyperpop, glitch-hop\nneo-soul, indie pop, industrial rock\nneo-soul, indie rock\nneo-soul, indie rock, blues-rock\nneo-soul, indie rock, cinematic\nneo-soul, industrial hip-hop\nneo-soul, industrial rock\nneo-soul, industrial, glitch-hop\nneo-soul, j-rock\nneo-soul, jazz fusion, Cantopop\nneo-soul, jazz lounge, funk rock\nneo-soul, jazz rap, C-pop\nneo-soul, jazz rap, R&B\nneo-soul, jazz, R&B\nneo-soul, jazz, festive\nneo-soul, jazz, glitch-hop\nneo-soul, jazz, hip hop\nneo-soul, jazz, hip-hop\nneo-soul, jazz, theatrical rock\nneo-soul, jazz-fusion, progressive rock\nneo-soul, jazz-hop, ambient\nneo-soul, jazz-hop, boom-bap\nneo-soul, jazz-soul, R&B\nneo-soul, jazzy, K-R&B\nneo-soul, jungle, future bass\nneo-soul, liquid drum and bass\nneo-soul, liquid drum and bass, neurofunk\nneo-soul, lo-fi R&B\nneo-soul, lo-fi hip hop\nneo-soul, lo-fi hip hop, K-pop\nneo-soul, lo-fi hip hop, R&B\nneo-soul, lo-fi hip hop, ambient\nneo-soul, lo-fi hip hop, atmospheric\nneo-soul, lo-fi hip hop, bossa nova\nneo-soul, lo-fi hip hop, cinematic\nneo-soul, lo-fi hip hop, deconstructed club\nneo-soul, lo-fi hip hop, experimental pop\nneo-soul, lo-fi hip hop, funk\nneo-soul, lo-fi hip hop, glitch-hop\nneo-soul, lo-fi hip hop, jazz\nneo-soul, lo-fi hip hop, jazzy\nneo-soul, lo-fi hip-hop\nneo-soul, lo-fi hip-hop, Christmas\nneo-soul, lo-fi hip-hop, Latin pop\nneo-soul, lo-fi hip-hop, Mandopop\nneo-soul, lo-fi hip-hop, R&B\nneo-soul, lo-fi hip-hop, chill R&B\nneo-soul, lo-fi hip-hop, chillwave\nneo-soul, lo-fi hip-hop, dancehall\nneo-soul, lo-fi hip-hop, future bass\nneo-soul, lo-fi hip-hop, jazzy\nneo-soul, lo-fi hip-hop, vaporwave\nneo-soul, lo-fi, ambient\nneo-soul, lo-fi, future bass\nneo-soul, lo-fi, vaporwave\nneo-soul, math rock, chiptune\nneo-soul, math-rock, electronic\nneo-soul, metalcore, electronicore\nneo-soul, modern R&B\nneo-soul, neurofunk\nneo-soul, new jack swing\nneo-soul, new jack swing, 90s R&B\nneo-soul, new jack swing, R&B\nneo-soul, noise rock, hip hop\nneo-soul, nu-disco, ambient\nneo-soul, nu-disco, funk\nneo-soul, nu-disco, funk house\nneo-soul, nu-disco, lo-fi\nneo-soul, nu-jazz\nneo-soul, pop R&B\nneo-soul, pop-R&B, hip-hop\nneo-soul, pop-funk, R&B\nneo-soul, pop-punk, hard rock\nneo-soul, pop-rock, R&B\nneo-soul, pop-rock, Vietnamese spoken word\nneo-soul, pop-rock, hard rock\nneo-soul, pop-rock, hip-hop\nneo-soul, progressive house\nneo-soul, progressive metal\nneo-soul, progressive rock\nneo-soul, progressive rock, ambient\nneo-soul, psychedelic funk\nneo-soul, psychedelic hard rock\nneo-soul, psychedelic pop\nneo-soul, psychedelic rock\nneo-soul, psychedelic rock, K-pop\nneo-soul, psychedelic rock, ambient\nneo-soul, psychedelic rock, funk-rock\nneo-soul, psychedelic world music\nneo-soul, psychedelic, ambient\nneo-soul, psychedelic, lo-fi\nneo-soul, psychedelic, lo-fi hip hop\nneo-soul, psychedelic, lo-fi hip-hop\nneo-soul, psychedelic, trap\nneo-soul, quiet storm, 90s R&B\nneo-soul, quiet storm, R&B\nneo-soul, rap, free jazz\nneo-soul, reggaeton, blues-rock\nneo-soul, retro-futuristic, R&B\nneo-soul, rock\nneo-soul, shoegaze, Latin pop\nneo-soul, shoegaze, ambient\nneo-soul, shoegaze, post-rock\nneo-soul, slow jam, R&B\nneo-soul, smooth R&B\nneo-soul, smooth jazz\nneo-soul, smooth jazz, R&B\nneo-soul, smooth jazz, ambient\nneo-soul, smooth jazz, chillhop\nneo-soul, smooth jazz, cinematic\nneo-soul, smooth jazz, lo-fi\nneo-soul, soft rock\nneo-soul, soul\nneo-soul, soul-rock\nneo-soul, soul-rock, jazz\nneo-soul, synth-funk, lo-fi\nneo-soul, synth-funk, modern R&B\nneo-soul, synth-pop, lo-fi hip-hop\nneo-soul, synth-pop, progressive house\nneo-soul, synth-pop, vaporwave\nneo-soul, theatrical rock, metalcore\nneo-soul, trap R&B\nneo-soul, trap R&B, ambient\nneo-soul, trap, Southern hip-hop\nneo-soul, trap, chill\nneo-soul, trap, electronic pop\nneo-soul, trap, rap\nneo-soul, trap, soul\nneo-soul, trap-soul\nneo-soul, trap-soul, R&B\nneo-soul, trap-soul, modern R&B\nneo-soul, trap-soul, rock\nneo-soul, trip-hop, R&B\nneo-soul, trip-hop, jazz\nneo-soul, trip-hop, lo-fi\nneo-soul, turntablism, hip-hop\nneo-soul, vaporwave\nneo-soul, vaporwave, R&B\nneo-soul, vaporwave, funk\nneo-soul, vaporwave, lo-fi\nneo-soul, video game music\nneo-soul, video game music, funk\nneo-soul, video game, funk\nneo-soul, world music, Caribbean\nneo-soul, world music, R&B\nneo-soul, world music, conscious hip-hop\nneo-soul, world music, lo-fi\nneo-swing\nneo-swing hip-hop\nneo-tango\nneo-tribal hip hop\nneoclassical\nneoclassical alternative rock\nneoclassical ambient\nneoclassical art song\nneoclassical ballad\nneoclassical chamber\nneoclassical chillwave\nneoclassical chiptune\nneoclassical choral\nneoclassical cinematic\nneoclassical darkwave\nneoclassical downtempo\nneoclassical drum and bass\nneoclassical dubstep\nneoclassical electronic\nneoclassical electronica\nneoclassical film score\nneoclassical flamenco\nneoclassical folk\nneoclassical gothic\nneoclassical guitar\nneoclassical heavy metal\nneoclassical hip hop\nneoclassical hip-hop\nneoclassical indie rock\nneoclassical industrial metal\nneoclassical lo-fi\nneoclassical lo-fi hip hop\nneoclassical metal\nneoclassical metal chiptune\nneoclassical metal forró\nneoclassical metal groove metal\nneoclassical metal power metal\nneoclassical metal progressive metal\nneoclassical metal progressive rock\nneoclassical metal, J-rock\nneoclassical metal, J-rock, metalcore\nneoclassical metal, Latin rock\nneoclassical metal, chiptune\nneoclassical metal, cinematic rock, Latin rock\nneoclassical metal, metalcore\nneoclassical metal, power ballad, C-pop\nneoclassical metal, symphonic metalcore\nneoclassical metal, symphonic power metal\nneoclassical metal, symphonic rock, electronic\nneoclassical metal, thrash metal\nneoclassical metal, video game music\nneoclassical metalcore\nneoclassical minimalism\nneoclassical orchestral\nneoclassical piano\nneoclassical pop\nneoclassical post-rock\nneoclassical power metal\nneoclassical power metal chiptune\nneoclassical progressive house\nneoclassical progressive metal\nneoclassical progressive rock\nneoclassical punk\nneoclassical rock\nneoclassical shoegaze\nneoclassical shred metal\nneoclassical symphonic metal\nneoclassical symphonic rock\nneoclassical synth\nneoclassical synth-pop\nneoclassical synthwave\nneoclassical tango\nneoclassical trance\nneoclassical trap\nneoclassical trip-hop\nneoclassical trip-hop ambient\nneoclassical video game\nneoclassical world music\nneoclassical, art rock\nneoclassical, art song, folk\nneoclassical, art-pop, cinematic\nneoclassical, baroque, cinematic\nneoclassical, cartoon chase\nneoclassical, chiptune, ragtime\nneoclassical, cinematic, ambient\nneoclassical, cinematic, dubstep\nneoclassical, cinematic, epic\nneoclassical, cinematic, folk\nneoclassical, cinematic, folk rock\nneoclassical, cinematic, orchestral\nneoclassical, cinematic, progressive rock\nneoclassical, cinematic, rock\nneoclassical, flamenco, epic\nneoclassical, glitch, ambient\nneoclassical, klezmer, folk dance\nneoclassical, progressive house, cinematic\nneoclassical, spoken word, Turkish folk\nneoclassical, symphonic metal, progressive rock\nneoclassical, symphonic rock, cinematic\nneoclassical, symphonic rock, video game music\nneoclassical, video game music, cinematic\nneoclassical, video game soundtrack\nneoclassical, video game soundtrack, ambient\nneoclassical, video game soundtrack, orchestral\nneoclassical, video game, anime\nneoclassical, world music, cinematic\nneofolk\nneofolk cinematic\nneofolk, ambient, world music\nneofolk, world music\nneomelodic rock\nneon desert\nneoy, ambient, world fusion\nnerd rock\nnerd-pop\nnerd-rap boom-bap\nnerd-rock\nnerdcore\nnerdcore chiptune\nnerdcore chiptune synth-pop\nnerdcore electronic rock\nnerdcore hip hop\nnerdcore hip-hop\nnerdcore hip-hop chiptune\nnerdcore hip-hop, chiptune, electronic\nnerdcore hip-hop, power metal, metalcore\nnerdcore hyperpop trap metal\nnerdcore lo-fi hip hop\nnerdcore metal\nnerdcore rap\nnerdcore rap chiptune\nnerdcore rap lo-fi hip-hop\nnerdcore rap trap\nnerdcore rap trap metal\nnerdcore rap, chiptune\nnerdcore rap, chiptune, anime\nnerdcore rap, chiptune, dubstep\nnerdcore rap, dark trap\nnerdcore rap, electronic, chiptune\nnerdcore rap, electronic, pop-punk\nnerdcore rap, trap, metalcore\nnerdcore rap-rock\nnerdcore rock\nnerdcore trap\nnerdcore trap metal\nnerdcore, boom-bap, funk\nnerdcore, boom-bap, video game hip hop\nnerdcore, chiptune, boom-bap\nnerdcore, chiptune, conscious hip-hop\nnerdcore, chiptune, electro-house\nnerdcore, chiptune, electronic\nnerdcore, chiptune, hip-hop\nnerdcore, chiptune, horrorcore\nnerdcore, chiptune, industrial rock\nnerdcore, chiptune, lo-fi hip hop\nnerdcore, chiptune, trap\nnerdcore, chiptune, trap metal\nnerdcore, cinematic hip hop\nnerdcore, comedy rap, electronic\nnerdcore, dubstep, trap metal\nnerdcore, electronic rap, chiptune\nnerdcore, electronic rap, video game music\nnerdcore, electronic, German hip hop\nnerdcore, electronic, chiptune\nnerdcore, electronic, cinematic\nnerdcore, electronic, dubstep\nnerdcore, electronic, lo-fi hip hop\nnerdcore, electronic, pop\nnerdcore, epic rap\nnerdcore, lo-fi hip hop, German rap\nnerdcore, orchestral, trap\nnerdcore, show tune, video game\nnerdcore, synth-rock, sci-fi\nnerdcore, trap, chiptune\nnerdcore, video game, funk\nnerdy hip-hop\nnerdycore hip-hop\nneue deutsche härte\nneue deutsche welle\nneue deutsche welle chiptune rock\nneue deutsche welle garage punk\nneue deutsche welle punk rock\nneue deutsche welle rock\nneue deutsche welle ska-punk\nneurofunk\nneurofunk Afro-Latin\nneurofunk R&B\nneurofunk alternative rock\nneurofunk ambient\nneurofunk baroque\nneurofunk big beat\nneurofunk breakbeat\nneurofunk breakcore\nneurofunk chiptune\nneurofunk chiptune hardcore\nneurofunk cinematic\nneurofunk complextro\nneurofunk complextro chiptune\nneurofunk dancehall\nneurofunk drum & bass\nneurofunk drum & bass hardcore\nneurofunk drum & bass metalcore\nneurofunk drum & bass, digital hardcore\nneurofunk drum & bass, rapcore\nneurofunk drum and bass\nneurofunk drum and bass metalcore\nneurofunk drum and bass, industrial metalcore\nneurofunk dubstep\nneurofunk dubstep chiptune\nneurofunk dubstep experimental\nneurofunk dubstep glitch hop\nneurofunk dubstep metalcore\nneurofunk electronic rock\nneurofunk glitch\nneurofunk glitch hop\nneurofunk glitch-hop\nneurofunk grime\nneurofunk gypsy fusion\nneurofunk industrial\nneurofunk industrial metal\nneurofunk jungle\nneurofunk lo-fi\nneurofunk metalcore\nneurofunk orchestral\nneurofunk rap\nneurofunk rapcore\nneurofunk reggae\nneurofunk techstep\nneurofunk trance\nneurofunk trap\nneurofunk vaporwave\nneurofunk, Indian classical, electronic\nneurofunk, J-core\nneurofunk, J-core, hardcore\nneurofunk, Middle Eastern\nneurofunk, Middle Eastern fusion\nneurofunk, Russian folk, cinematic\nneurofunk, Russian rap, Turkish vocal\nneurofunk, Russian rap, cinematic\nneurofunk, Russian rock, metalcore\nneurofunk, UK rap, cinematic\nneurofunk, ambient, breakcore\nneurofunk, ambient, electronic\nneurofunk, artcore, drum and bass\nneurofunk, breakbeat, cinematic\nneurofunk, breakcore, chiptune\nneurofunk, breakcore, electronic\nneurofunk, chiptune, ambient\nneurofunk, chiptune, artcore\nneurofunk, chiptune, cinematic\nneurofunk, chiptune, dnb\nneurofunk, chiptune, drum and bass\nneurofunk, chiptune, dubstep\nneurofunk, chiptune, techstep\nneurofunk, cinematic electronic\nneurofunk, cinematic orchestral\nneurofunk, cinematic, C-pop\nneurofunk, cinematic, Middle Eastern\nneurofunk, cinematic, Russian vocal\nneurofunk, cinematic, ambient\nneurofunk, cinematic, chiptune\nneurofunk, cinematic, drum and bass\nneurofunk, cinematic, electronic\nneurofunk, cinematic, folk-electronic\nneurofunk, cinematic, hybrid\nneurofunk, cinematic, metalcore\nneurofunk, cinematic, orchestral\nneurofunk, cinematic, synthwave\nneurofunk, complextro, cinematic\nneurofunk, complextro, hardcore electronic\nneurofunk, complextro, hardstyle\nneurofunk, cyber-industrial, cinematic\nneurofunk, cyberpunk, ambient\nneurofunk, cyberpunk, cinematic\nneurofunk, cyberpunk, drum and bass\nneurofunk, dancehall\nneurofunk, dark drum and bass\nneurofunk, drum & bass, chiptune\nneurofunk, drum and bass\nneurofunk, drum and bass, German rap\nneurofunk, drum and bass, Indian classical\nneurofunk, drum and bass, Polish rap\nneurofunk, drum and bass, Russian hip hop\nneurofunk, drum and bass, Russian rap\nneurofunk, drum and bass, ambient\nneurofunk, drum and bass, chiptune\nneurofunk, drum and bass, cinematic\nneurofunk, drum and bass, complextro\nneurofunk, drum and bass, cyberpunk\nneurofunk, drum and bass, electronic\nneurofunk, drum and bass, grime\nneurofunk, drum and bass, heavy metal\nneurofunk, drum and bass, industrial metal\nneurofunk, drum and bass, trance\nneurofunk, dubstep, chiptune\nneurofunk, dubstep, cyberpunk\nneurofunk, dubstep, dancehall\nneurofunk, dubstep, drum and bass\nneurofunk, dubstep, hardstyle\nneurofunk, dubstep, hybrid trap\nneurofunk, duduk, Middle Eastern\nneurofunk, electronic, Russian rap\nneurofunk, electronic, cyberpunk\nneurofunk, electronic, glitch\nneurofunk, glitch hop, hip-hop\nneurofunk, glitch, cyberpunk\nneurofunk, glitch-hop, jazz-fusion\nneurofunk, grime, electronic\nneurofunk, grime, techstep\nneurofunk, hardbass\nneurofunk, hardcore\nneurofunk, hardcore techno\nneurofunk, hardstyle\nneurofunk, hardstyle, cinematic\nneurofunk, hardstyle, drum and bass\nneurofunk, hybrid trap\nneurofunk, indie rock\nneurofunk, industrial, cinematic electronic\nneurofunk, liquid drum and bass\nneurofunk, liquid funk, drum and bass\nneurofunk, lo-fi hip-hop, drum and bass\nneurofunk, lo-fi, glitch-hop\nneurofunk, orchestral, cinematic\nneurofunk, orchestral, techstep\nneurofunk, psytrance, ambient\nneurofunk, psytrance, cinematic\nneurofunk, tearout dubstep\nneurofunk, tearout dubstep, cinematic electronic\nneurofunk, tearout dubstep, glitch\nneurofunk, techstep\nneurofunk, techstep, cinematic\nneurofunk, techstep, drum and bass\nneurofunk, techstep, glitch\nneurofunk, thrash metal, cyber-metal\nneurofunk, trance, R&B\nneurofunk, trance, ambient\nneurofunk, trance, chiptune\nnew acoustic\nnew age\nnew age acoustic\nnew age acoustic folk\nnew age ambient\nnew age ambient classical\nnew age ambient classical crossover\nnew age ambient folk\nnew age ambient spiritual\nnew age ambient world music\nnew age cinematic\nnew age electronic\nnew age electronic world fusion\nnew age folk\nnew age folk world music\nnew age hip-hop\nnew age jazz\nnew age orchestral pop\nnew age pop\nnew age pop rock\nnew age pop-rock\nnew age progressive rock\nnew age rock\nnew age smooth jazz\nnew age soft rock\nnew age spiritual\nnew age synth-pop\nnew age trance\nnew age trip-hop\nnew age world fusion\nnew age world music\nnew age worldbeat\nnew age worldbeat smooth jazz\nnew age, 16-bit, ambient\nnew age, 80s Christian power ballad\nnew age, Afro-gospel\nnew age, Brazilian MPB\nnew age, Buddhist music\nnew age, C-pop, ambient\nnew age, C-pop, cinematic\nnew age, Celtic folk, orchestral fantasy\nnew age, Chinese folk\nnew age, Chinese folk, ambient\nnew age, Chinese folk, cinematic\nnew age, Chinese traditional, ambient\nnew age, East Asian folk\nnew age, French pop\nnew age, Indian classical\nnew age, Indian devotional\nnew age, Indian devotional, ambient\nnew age, Latin folk\nnew age, Latin folk-rock\nnew age, Latin pop-rock\nnew age, R&B, adult contemporary\nnew age, Thai folk\nnew age, adult contemporary\nnew age, ambient, Chinese flute\nnew age, ambient, Chinese folk\nnew age, ambient, East Asian folk\nnew age, ambient, Indian devotional\nnew age, ambient, spiritual\nnew age, ambient, traditional Chinese\nnew age, ambient, world music\nnew age, chamber music, Brazilian folk\nnew age, chillout\nnew age, choral\nnew age, choral, ambient\nnew age, choral, world music\nnew age, cinematic pop, world music\nnew age, cinematic, 80s soundtrack\nnew age, cinematic, C-pop\nnew age, cinematic, Chinese ambient\nnew age, cinematic, Chinese folk\nnew age, cinematic, Chinese spiritual\nnew age, cinematic, Chinese traditional\nnew age, cinematic, East Asian folk\nnew age, cinematic, Indian classical\nnew age, cinematic, Vietnamese folk\nnew age, cinematic, ambient\nnew age, cinematic, easy-listening\nnew age, cinematic, fantasy\nnew age, cinematic, orchestral pop\nnew age, cinematic, spiritual\nnew age, cinematic, traditional Chinese\nnew age, cinematic, video game soundtrack\nnew age, cinematic, world music\nnew age, city pop, ambient\nnew age, classical crossover\nnew age, devotional, ambient\nnew age, devotional, cinematic\nnew age, electronic pop, world music\nnew age, electronic, ambient\nnew age, electronic, cinematic\nnew age, electronic, funk\nnew age, electronic, synth-pop\nnew age, electronic, video game music\nnew age, electronic, world fusion\nnew age, electronic, world music\nnew age, folk, electronic\nnew age, gospel, world music\nnew age, library music\nnew age, progressive house, worldbeat\nnew age, progressive rock\nnew age, retro synth, spiritual\nnew age, smooth jazz\nnew age, smooth jazz, 80s\nnew age, smooth jazz, 80s synth\nnew age, smooth jazz, cinematic\nnew age, spiritual electronic, world music\nnew age, spiritual, ambient\nnew age, synth-pop\nnew age, synth-pop, cinematic\nnew age, traditional Chinese, ambient\nnew age, traditional Chinese, meditative\nnew age, video game soundtrack\nnew age, world folk, acoustic pop\nnew age, world fusion\nnew age, world fusion, Chinese folk\nnew age, world fusion, Indian classical\nnew age, world fusion, ambient\nnew age, world fusion, cinematic\nnew age, world fusion, devotional\nnew age, world fusion, light jazz\nnew age, world fusion, synthwave\nnew age, world music\nnew age, world music, Chinese traditional\nnew age, world music, Indian classical\nnew age, world music, Indian devotional\nnew age, world music, Latin folk\nnew age, world music, MPB\nnew age, world music, Vietnamese folk\nnew age, world music, acoustic folk\nnew age, world music, ambient\nnew age, world music, ambient folk\nnew age, world music, bhajan\nnew age, world music, choral\nnew age, world music, cinematic\nnew age, world music, cinematic folk\nnew age, world music, contemporary Christian\nnew age, world music, devotional\nnew age, world music, electronic\nnew age, world music, electronic pop\nnew age, world music, folk\nnew age, world music, gospel\nnew age, world music, instrumental\nnew age, world music, jazz fusion\nnew age, world music, lo-fi rock\nnew age, world music, modern classical\nnew age, world music, smooth jazz\nnew age, world music, soft rock\nnew age, world music, spiritual\nnew age, world music, spiritual chant\nnew age, world music, traditional Chinese folk\nnew age, world music, traditional Southeast Asian\nnew age, world music, video game soundtrack\nnew age, worldbeat, ambient\nnew age, worldbeat, cinematic\nnew age, worldbeat, devotional\nnew age, worldbeat, downtempo\nnew age, worldbeat, electronic\nnew age, worldbeat, orchestral pop\nnew age, worldbeat, spiritual\nnew age, worldbeat, synthwave\nnew jack swing\nnew jack swing Latin pop\nnew jack swing R&B\nnew jack swing acid jazz\nnew jack swing breakbeat\nnew jack swing chiptune\nnew jack swing city pop\nnew jack swing dance-pop\nnew jack swing dancehall\nnew jack swing electro-funk\nnew jack swing electro-funk R&B\nnew jack swing funk\nnew jack swing funk R&B\nnew jack swing funk gospel\nnew jack swing funk hip-hop\nnew jack swing funk house\nnew jack swing funk rock\nnew jack swing funk-R&B\nnew jack swing funk-hop\nnew jack swing funk-house\nnew jack swing funk-pop\nnew jack swing funk-rap\nnew jack swing funk-rock\nnew jack swing g-funk\nnew jack swing gospel\nnew jack swing gospel R&B\nnew jack swing gospel funk\nnew jack swing gospel house\nnew jack swing hip hop\nnew jack swing hip-hop\nnew jack swing hip-house\nnew jack swing house\nnew jack swing industrial rock\nnew jack swing j-pop\nnew jack swing pop-funk\nnew jack swing rap-rock\nnew jack swing rock\nnew jack swing smooth jazz\nnew jack swing synth-funk\nnew jack swing synth-pop\nnew jack swing vaporwave\nnew jack swing, 90s R&B\nnew jack swing, Bollywood dance-pop\nnew jack swing, Bollywood pop\nnew jack swing, Brazilian pop-funk\nnew jack swing, C-pop, fusion\nnew jack swing, Christian funk\nnew jack swing, French R&B\nnew jack swing, French hip-hop, retro\nnew jack swing, G-funk\nnew jack swing, G-funk, psychedelic hip-hop\nnew jack swing, J-pop\nnew jack swing, Japanese hip-hop\nnew jack swing, K-pop\nnew jack swing, Latin funk, hip-hop\nnew jack swing, Latin salsa, Middle Eastern pop\nnew jack swing, Persian pop, Latin pop\nnew jack swing, Persian pop, cinematic\nnew jack swing, Polish hip-hop\nnew jack swing, R&B\nnew jack swing, R&B ballad\nnew jack swing, R&B, hip-hop\nnew jack swing, Southeast Asian pop\nnew jack swing, UK garage\nnew jack swing, UK hip-hop\nnew jack swing, boom-bap\nnew jack swing, boom-bap, hip-hop\nnew jack swing, chiptune\nnew jack swing, chiptune, Japanese video game music\nnew jack swing, chiptune, hip-hop\nnew jack swing, chiptune, video game music\nnew jack swing, city pop\nnew jack swing, city pop, chiptune\nnew jack swing, city pop, funk pop\nnew jack swing, city pop, hip-hop\nnew jack swing, city pop, video game music\nnew jack swing, city pop, video game soundtrack\nnew jack swing, conscious hip-hop\nnew jack swing, early hip-hop, Malay fusion\nnew jack swing, funk, soul\nnew jack swing, g-funk\nnew jack swing, g-funk, chiptune\nnew jack swing, gospel R&B\nnew jack swing, gospel funk\nnew jack swing, gospel house\nnew jack swing, gospel pop, chiptune\nnew jack swing, gospel, Christmas\nnew jack swing, hip hop, R&B\nnew jack swing, hip house, pop\nnew jack swing, hip-hop, R&B\nnew jack swing, hip-house\nnew jack swing, horrorcore, electronic\nnew jack swing, smooth jazz\nnew jack swing, synth-funk\nnew jack swing, synth-funk, Cantopop rap\nnew jack swing, synth-funk, chiptune\nnew jack swing, synth-funk, vaporwave\nnew jack swing, synth-funk, worldbeat\nnew jack swing, synth-pop\nnew jack swing, synth-pop, hip-hop\nnew jack swing, video game music\nnew wave\nnew wave alternative rock\nnew wave art-rock\nnew wave chiptune\nnew wave disco-funk\nnew wave dream pop\nnew wave funk\nnew wave funk art-rock\nnew wave funk disco\nnew wave funk rock\nnew wave funk-pop\nnew wave funk-rap\nnew wave funk-rock\nnew wave gospel\nnew wave hip hop\nnew wave indie rock\nnew wave industrial rock\nnew wave jangle pop\nnew wave lo-fi\nnew wave pop\nnew wave pop-punk\nnew wave pop-rock\nnew wave post-punk\nnew wave power pop\nnew wave power-pop\nnew wave punk\nnew wave punk rock\nnew wave revival\nnew wave rock\nnew wave rock en español\nnew wave rock ska\nnew wave rockabilly\nnew wave rockabilly surf rock\nnew wave ska\nnew wave ska Latin\nnew wave ska funk\nnew wave ska rocksteady\nnew wave ska-punk\nnew wave surf rock\nnew wave synth-pop\nnew wave synth-punk\nnew wave synth-rock\nnew wave tropical\nnew wave, 80s Czech pop-rock\nnew wave, 80s Czech rock\nnew wave, 80s Dutch pop\nnew wave, 80s Korean rock\nnew wave, 80s Polish rock\nnew wave, 80s Spanish pop-rock\nnew wave, 80s Spanish rock\nnew wave, 80s pop, Eastern European\nnew wave, 80s pop-rock, Spanish pop\nnew wave, 80s rock, Balkan rock\nnew wave, 80s rock, Czech rock\nnew wave, 80s rock, Danish rock\nnew wave, 80s rock, Eastern European\nnew wave, 80s rock, Polish rock\nnew wave, 80s rock, Spanish rock\nnew wave, Brazilian rock\nnew wave, Dutch rock, 80s\nnew wave, Eastern European pop\nnew wave, Eastern European pop-rock\nnew wave, Eastern European rock\nnew wave, Eastern European rock, synth rock\nnew wave, Eastern European rock, synth-pop\nnew wave, French cold wave, synthpop\nnew wave, French pop, 80s\nnew wave, French pop, exotica\nnew wave, French pop, synth-pop\nnew wave, French pop-rock\nnew wave, French pop-rock, 80s\nnew wave, French rock\nnew wave, French rock, 80s\nnew wave, Italo-disco, dance\nnew wave, J-rock, synthpop\nnew wave, Latin mambo, funk\nnew wave, Latin percussion, synthpop\nnew wave, Latin pop\nnew wave, Latin pop, 80s\nnew wave, Latin rock\nnew wave, Latin rock, surf rock\nnew wave, Latin, chiptune\nnew wave, Latin, dance\nnew wave, Latin, exotica\nnew wave, Middle Eastern, synth pop\nnew wave, Nederpop, 80s\nnew wave, Neue Deutsche Welle\nnew wave, Polish rock\nnew wave, Soviet rock\nnew wave, Soviet rock, post-punk\nnew wave, Soviet rock, synth rock\nnew wave, Soviet-era, surf-rock\nnew wave, Spanish pop-rock\nnew wave, Spanish pop-rock, 80s\nnew wave, Spanish rock\nnew wave, Spanish rock, synth-pop\nnew wave, alternative rock\nnew wave, alternative rock, dream pop\nnew wave, alternative rock, power pop\nnew wave, art-pop, 80s\nnew wave, art-pop, 80s Eastern European\nnew wave, boogie-woogie, 80s\nnew wave, breakbeat, big beat\nnew wave, breakbeat, electronic\nnew wave, chiptune\nnew wave, chiptune, 8-bit\nnew wave, chiptune, jazz fusion\nnew wave, chiptune, punk\nnew wave, chiptune, rock\nnew wave, chiptune, space rock\nnew wave, chiptune, synth pop\nnew wave, chiptune, synth punk\nnew wave, chiptune, synthpop\nnew wave, chiptune, video game\nnew wave, cinematic rock\nnew wave, cinematic, operatic\nnew wave, classic rock, pop-rock\nnew wave, coldwave, post-punk\nnew wave, dark wave\nnew wave, dream pop\nnew wave, electro-funk, early house\nnew wave, funk rock, psychedelic\nnew wave, funk-rock, French pop\nnew wave, funk-rock, cinematic\nnew wave, hard rock, industrial\nnew wave, hard rock, psychedelic\nnew wave, hard rock, synth rock\nnew wave, pop-rock, 80s\nnew wave, pop-rock, 80s Eastern European\nnew wave, pop-rock, Eastern European\nnew wave, pop-rock, musical theater\nnew wave, post-punk\nnew wave, post-punk, 80s\nnew wave, post-punk, 80s Eastern European\nnew wave, post-punk, 80s Spanish\nnew wave, post-punk, Eastern European\nnew wave, post-punk, Eastern European rock\nnew wave, post-punk, German rock\nnew wave, post-punk, Soviet rock\nnew wave, post-punk, Soviet-era\nnew wave, post-punk, chiptune\nnew wave, post-punk, cinematic\nnew wave, post-punk, dream-pop\nnew wave, post-punk, electronic\nnew wave, post-punk, funk\nnew wave, post-punk, horror soundtrack\nnew wave, post-punk, lo-fi\nnew wave, post-punk, synth-pop\nnew wave, post-punk, synthwave\nnew wave, power pop\nnew wave, power pop, rockabilly\nnew wave, power pop, synth rock\nnew wave, power-pop\nnew wave, power-pop, 80s\nnew wave, pub rock\nnew wave, punk, electronic\nnew wave, punk, lo-fi\nnew wave, rock en español\nnew wave, rock en español, 80s\nnew wave, rock, hip-hop\nnew wave, ska, rock and roll\nnew wave, ska, rocksteady\nnew wave, surf rock\nnew wave, surf rock, Balkan\nnew wave, surf rock, chiptune\nnew wave, surf rock, garage rock\nnew wave, surf rock, rockabilly\nnew wave, surf rock, ska\nnew wave, surf rock, synth pop\nnew wave, surf-rock, funk\nnew wave, symphonic metal\nnew wave, synth-pop\nnew wave, synth-pop, 80s\nnew wave, synth-pop, French pop-rock\nnew wave, synth-pop, Italo-disco\nnew wave, synth-pop, Soviet-era\nnew wave, synth-pop, Swedish rock\nnew wave, synth-pop, art rock\nnew wave, synth-pop, art-rock\nnew wave, synth-pop, chiptune\nnew wave, synth-pop, comedy rock\nnew wave, synth-pop, electronic\nnew wave, synth-pop, hard rock\nnew wave, synth-pop, indie rock\nnew wave, synth-pop, post-punk\nnew wave, synth-pop, video game soundtrack\nnew wave, world music\nnew wave, world music, rock\nnew-age\nnew-age C-pop\nnew-age Christian pop-rock\nnew-age Christian rock\nnew-age Indian\nnew-age Indian classical\nnew-age Indian devotional\nnew-age Latin lounge\nnew-age R&B\nnew-age R&B-pop\nnew-age Thai pop\nnew-age acoustic\nnew-age ambient\nnew-age ballad\nnew-age bossa nova\nnew-age choral\nnew-age cinematic\nnew-age cinematic pop\nnew-age classical\nnew-age cumbia\nnew-age devotional\nnew-age electronic\nnew-age folk\nnew-age folk progressive house\nnew-age folk rock\nnew-age funk soul\nnew-age fusion\nnew-age gospel\nnew-age gospel rock\nnew-age hip-hop\nnew-age lounge\nnew-age orchestral\nnew-age orchestral pop\nnew-age pop\nnew-age pop funk-rock\nnew-age pop rock\nnew-age pop-rock\nnew-age progressive rock\nnew-age reggae\nnew-age reggae-gospel\nnew-age rock\nnew-age rock fusion\nnew-age smooth jazz\nnew-age soft rock\nnew-age soul\nnew-age spiritual\nnew-age symphonic rock\nnew-age synth-pop\nnew-age trip-hop\nnew-age world fusion\nnew-age world music\nnew-age worldbeat\nnew-age worship\nnew-age, Brazilian gospel, Axé\nnew-age, Brazilian pop, ambient\nnew-age, Brazilian pop-rock\nnew-age, C-pop, ambient\nnew-age, Chinese ambient\nnew-age, Chinese folk\nnew-age, Chinese folk, ambient\nnew-age, Chinese folk, cinematic\nnew-age, Chinese folk, instrumental\nnew-age, Chinese traditional, ambient\nnew-age, Chinese traditional, spiritual\nnew-age, Chinese, electronic\nnew-age, Christian contemporary, ballad\nnew-age, Christian contemporary, power ballad\nnew-age, Eurodance, Latin pop\nnew-age, Indian classical, cinematic\nnew-age, Latin dance-pop\nnew-age, Latin pop, arena rock\nnew-age, MPB, folk\nnew-age, ambient, C-pop\nnew-age, ambient, Chinese spiritual\nnew-age, ambient, meditative\nnew-age, ambient, traditional Chinese\nnew-age, choral, operatic\nnew-age, cinematic, Andean folk\nnew-age, cinematic, C-pop\nnew-age, cinematic, Chinese\nnew-age, cinematic, Chinese ambient\nnew-age, cinematic, Chinese folk\nnew-age, cinematic, Chinese spiritual\nnew-age, cinematic, Chinese traditional\nnew-age, cinematic, ambient\nnew-age, cinematic, bhajan\nnew-age, cinematic, pop-rock\nnew-age, cinematic, power ballad\nnew-age, cinematic, traditional Chinese\nnew-age, cinematic, video game soundtrack\nnew-age, cinematic, world music\nnew-age, devotional, Indian classical\nnew-age, devotional, electronic\nnew-age, electronic, Chinese traditional\nnew-age, electronic, ambient\nnew-age, electronic, pop\nnew-age, eurodance\nnew-age, eurodance, ambient\nnew-age, folk, spiritual\nnew-age, pop-dangdut, jazz\nnew-age, pop-rock, Vietnamese pop\nnew-age, pop-rock, world music\nnew-age, power ballad, 80s synth\nnew-age, spiritual, Chinese folk\nnew-age, spiritual, Vietnamese folk\nnew-age, synth-pop, Christmas\nnew-age, synth-pop, cinematic\nnew-age, traditional Chinese folk\nnew-age, traditional Chinese, ambient\nnew-age, traditional Chinese, meditative\nnew-age, trip-hop, ambient\nnew-age, video game soundtrack, C-pop\nnew-age, world music, Indian devotional\nnew-age, world music, MPB\nnew-age, world music, Thai folk\nnew-age, world music, ambient\nnew-age, world music, cinematic\nnew-age, world music, devotional\nnew-age, world music, pop-rock\nnew-age, world music, soul\nnew-age, world music, spiritual\nnew-age, world music, spiritual electronic\nnew-age, worldbeat, ambient\nnewgrass\nnightcore\nnightcore EDM\nnightcore dance-pop\nnightcore gabber\nnightcore happy hardcore\nnightcore hardstyle\nnightcore hyperpop\nnightcore lo-fi piano pop\nnightcore trap\nnightcore, UK garage, electronic\nnightcore, breakbeat, experimental\nnightcore, children's music, electronic\nnightcore, happy hardcore\nnightcore, happy hardcore, C-pop\nnightcore, happy hardcore, Indian pop\nnightcore, happy hardcore, J-core\nnightcore, happy hardcore, children's music\nnightcore, happy hardcore, dance-pop\nnightcore, happy hardcore, electronic\nnightcore, happy hardcore, electronic dance\nnightcore, happy hardcore, hardstyle\nnightcore, hardstyle, anime\nnightcore, hyperpop\nnightcore, hyperpop, C-pop\nnightcore, hyperpop, EDM\nnightcore, hyperpop, dance-pop\nnightcore, trap, phonk\nnintendocore\nnintendocore metalcore\nnintendocore pop-punk\nnintendocore speedcore\nnocturnal R&B\nnocturnal jazz\nnocturnal trap\nnoir\nnoir ballad\nnoir film score\nnoir hip-hop\nnoir instrumental\nnoir jazz\nnoir jazz bebop\nnoir jazz cinematic\nnoir jazz punk rock\nnoir jazz swing\nnoir jazz tango\nnoir jazz trip-hop\nnoir jazz, Latin jazz\nnoir jazz, big band\nnoir jazz, big band swing\nnoir jazz, big band, cinematic\nnoir jazz, cinematic orchestral\nnoir jazz, free jazz\nnoir orchestral\nnoir rock\nnoir rock tango\nnoir-funk\nnoir-jazz\nnoir-jazz alternative rock\nnoir-jazz art-rock\nnoir-jazz ballad\nnoir-jazz bebop\nnoir-jazz blues-rock\nnoir-jazz bossa nova\nnoir-jazz cabaret\nnoir-jazz cabaret-ska\nnoir-jazz cinematic\nnoir-jazz cumbia\nnoir-jazz cumbia-ska\nnoir-jazz doom metal\nnoir-jazz dubstep\nnoir-jazz folk\nnoir-jazz folk-rock\nnoir-jazz funk\nnoir-jazz funk soul\nnoir-jazz funk-rock\nnoir-jazz garage rock\nnoir-jazz hip-hop\nnoir-jazz indie rock\nnoir-jazz lo-fi hip hop\nnoir-jazz lo-fi hip-hop\nnoir-jazz lounge\nnoir-jazz lounge funk\nnoir-jazz lounge-pop\nnoir-jazz noise-rock\nnoir-jazz post-rock\nnoir-jazz progressive rock\nnoir-jazz psychedelic rock\nnoir-jazz punk rock\nnoir-jazz punk-jazz klezmer\nnoir-jazz rock\nnoir-jazz soul\nnoir-jazz soul-rock\nnoir-jazz tango\nnoir-jazz tango rock\nnoir-jazz trap\nnoir-jazz trip-hop\nnoir-jazz, Afro-Cuban, free jazz\nnoir-jazz, Latin jazz\nnoir-jazz, Latin rock\nnoir-jazz, Latin rock, blues\nnoir-jazz, alternative rock, experimental\nnoir-jazz, alternative rock, surf rock\nnoir-jazz, art-rock, cinematic\nnoir-jazz, big band swing, cinematic\nnoir-jazz, big band swing, punk rock\nnoir-jazz, big band, cinematic\nnoir-jazz, big band, free jazz\nnoir-jazz, big band, lounge-jazz\nnoir-jazz, big band, swing\nnoir-jazz, big-band jazz-rock, free jazz\nnoir-jazz, big-band swing, theatrical soul\nnoir-jazz, breakbeat, ambient\nnoir-jazz, cabaret, big band\nnoir-jazz, chanson, alternative rock\nnoir-jazz, cinematic, Javanese\nnoir-jazz, classic rock\nnoir-jazz, free-jazz\nnoir-jazz, free-jazz, psychedelic rock\nnoir-jazz, hard rock\nnoir-jazz, hard rock, thrash metal\nnoir-jazz, indie rock, post-rock\nnoir-jazz, industrial hip-hop\nnoir-jazz, industrial rock\nnoir-jazz, industrial rock, cinematic\nnoir-jazz, jump blues\nnoir-jazz, progressive metal\nnoir-jazz, progressive rock, noise rock\nnoir-jazz, psychedelic funk, free-jazz\nnoir-jazz, psychedelic rock\nnoir-jazz, psychedelic rock, ambient\nnoir-jazz, psychedelic rock, blues\nnoir-jazz, psychedelic rock, blues-rock\nnoir-jazz, psychedelic rock, hard rock\nnoir-jazz, psychedelic rock, soul\nnoir-jazz, ska-punk, free-jazz\nnoir-jazz, spy theme, cinematic\nnoir-jazz, synth-funk\nnoir-rock\nnoir-western\nnoise\nnoise music\nnoise pop\nnoise pop shoegaze\nnoise rap\nnoise rock\nnoise rock alternative metal\nnoise rock cabaret punk\nnoise rock funk rock\nnoise rock funk rock dream pop\nnoise rock hip-hop\nnoise rock hyperpop\nnoise rock indie rock\nnoise rock industrial\nnoise rock industrial rock\nnoise rock lo-fi\nnoise rock post-hardcore\nnoise rock psychedelic rock\nnoise rock punk\nnoise rock shoegaze\nnoise rock stoner rock\nnoise rock, Indian film music, experimental fusion\nnoise rock, Indian film music, melancholic ballad\nnoise rock, J-pop, experimental\nnoise rock, Latin rock\nnoise rock, alternative rock\nnoise rock, alternative rock, Latin rock\nnoise rock, ambient, C-pop\nnoise rock, digital hardcore\nnoise rock, dream-pop, indie rock\nnoise rock, experimental, electronic\nnoise rock, heavy metal, punk\nnoise rock, indie rock, shoegaze\nnoise rock, kayōkyoku, cinematic\nnoise rock, lounge pop\nnoise rock, post-rock, psychedelic rock\nnoise rock, psychedelic pop, hard rock\nnoise rock, psychedelic rock\nnoise rock, reggae, blues rock\nnoise rock, shoegaze, indie rock\nnoise rock, shoegaze, post-hardcore\nnoise rock, shoegaze, post-punk\nnoise rock, surf rock, post-rock\nnoise-pop\nnoise-punk\nnoise-punk funk rock\nnoise-rock neo-soul\nnoise-rock, Italo-disco, cinematic pop\nnorteña\nnorteña polka\nnorteño\nnorteño banda\nnorteño chiptune\nnorteño cinematic\nnorteño corrido\nnorteño corrido cinematic\nnorteño corrido tumbado\nnorteño corridos tumbados\nnorteño cumbia\nnorteño electronic\nnorteño folk\nnorteño hip-hop\nnorteño lo-fi\nnorteño metal\nnorteño polka\nnorteño pop\nnorteño protest\nnorteño psychedelic\nnorteño punk\nnorteño ranchera\nnorteño reggaeton\nnorteño rock\nnorteño rock fusion\nnorteño rockabilly\nnorteño sax\nnorteño ska\nnorteño ska-punk\nnorteño swing\nnorteño trap\nnorteño waltz\nnorteño, Latin trap\nnorteño, carnaval, Latin folk\nnorteño, corrido tumbado\nnorteño, corridos tumbados, regional Mexican\nnorteño, electronic dance\nnorteño, flamenco, regional Mexican\nnorteño, urban party, fusion\nnorteño-banda\nnorteño-banda chiptune\nnorteño-cumbia\nnorteño-pop\nnorteño-punk\nnorteño-rock\nnorteño-ska\nnostalgic C-pop\nnostalgic ballad\nnostalgic children's music\nnostalgic electronic\nnostalgic hip-hop\nnostalgic piano\nnostalgic pop\nnostalgic pop, Eastern European, chiptune\nnostalgic waltz\nnovelty\nnovelty Christmas\nnovelty Christmas cabaret\nnovelty Christmas, Australian\nnovelty Christmas, Australian folk\nnovelty Christmas, Hawaiian\nnovelty Christmas, Hawaiian tropical\nnovelty Christmas, Hawaiian, theatrical\nnovelty Christmas, Hawaiian, ukulele\nnovelty Christmas, Italian-American, polka\nnovelty Christmas, Latin, cumbia\nnovelty Christmas, big band\nnovelty Christmas, big band swing\nnovelty Christmas, big band swing, show tune\nnovelty Christmas, boogie-woogie\nnovelty Christmas, boogie-woogie, ragtime\nnovelty Christmas, boogie-woogie, rock and roll\nnovelty Christmas, chiptune, Australian\nnovelty Christmas, dark comedy, polka\nnovelty Christmas, honky-tonk, boogie-woogie\nnovelty Christmas, polka, brass band\nnovelty Christmas, polka, retro synth\nnovelty Christmas, ragtime, boogie-woogie\nnovelty Christmas, ragtime, show tune\nnovelty Christmas, ragtime, vaudeville\nnovelty Christmas, retro rock 'n' roll\nnovelty Christmas, retro rock and roll\nnovelty Christmas, ska, polka\nnovelty Christmas, swing, polka\nnovelty Halloween\nnovelty Italian\nnovelty Latin\nnovelty Latin pop\nnovelty R&B\nnovelty Western\nnovelty a cappella\nnovelty baroque\nnovelty beatbox\nnovelty big band\nnovelty bluegrass\nnovelty blues\nnovelty boogie\nnovelty boogie-woogie\nnovelty cabaret\nnovelty children's\nnovelty chiptune\nnovelty comedy\nnovelty country\nnovelty country rockabilly\nnovelty country-folk\nnovelty country-rock\nnovelty cumbia\nnovelty dance\nnovelty dance, Filipino pop, electronic\nnovelty dance, cumbia, Latin pop\nnovelty dance, polka, electronic\nnovelty dance-pop\nnovelty disco\nnovelty electro\nnovelty electronic\nnovelty folk\nnovelty folk-pop\nnovelty funk\nnovelty funk-rock\nnovelty hip hop\nnovelty hip-hop\nnovelty hip-hop chiptune\nnovelty hip-hop funk\nnovelty house\nnovelty jazz\nnovelty jingle\nnovelty lo-fi\nnovelty music\nnovelty music hall\nnovelty music ragtime\nnovelty music vaudeville\nnovelty piano\nnovelty polka\nnovelty polka chiptune\nnovelty polka disco polo\nnovelty polka disco-funk\nnovelty polka ska\nnovelty polka vaudeville\nnovelty pop\nnovelty pop calypso\nnovelty pop chiptune\nnovelty pop country swing\nnovelty pop disco funk\nnovelty pop doo-wop\nnovelty pop eurodance\nnovelty pop exotica\nnovelty pop funk disco\nnovelty pop funk-rock\nnovelty pop pimba\nnovelty pop polka\nnovelty pop ragtime\nnovelty pop reggae dancehall\nnovelty pop reggae ska\nnovelty pop rock\nnovelty pop rockabilly\nnovelty pop schlager\nnovelty pop show tune\nnovelty pop ska\nnovelty pop surf rock\nnovelty pop surf-rock\nnovelty pop world music\nnovelty pop, 80s Filipino pop\nnovelty pop, 80s Filipino pop, retro pop\nnovelty pop, Italian tarantella\nnovelty pop, Latin pop\nnovelty pop, Latin, cha-cha-chá\nnovelty pop, Russian folk-pop, polka\nnovelty pop, big band, ragtime\nnovelty pop, big band, swing\nnovelty pop, chiptune\nnovelty pop, chiptune, Italian\nnovelty pop, chiptune, electronic\nnovelty pop, chiptune, retro video game\nnovelty pop, eurodance\nnovelty pop, retro Italian pop-rock\nnovelty pop, retro Soviet, theatrical\nnovelty pop, retro disco, funk\nnovelty pop, retro, video game\nnovelty pop, rockabilly, retro swing\nnovelty pop, schlager, latin mambo\nnovelty pop, surf rock\nnovelty pop, theatrical rock\nnovelty pop, theatrical, polka\nnovelty pop, tropical, Latin\nnovelty pop-rap\nnovelty pop-rock\nnovelty punk\nnovelty punk rock\nnovelty ragtime\nnovelty ragtime chiptune\nnovelty ragtime country\nnovelty ragtime vaudeville\nnovelty ranchera\nnovelty rap\nnovelty reggae\nnovelty rock\nnovelty rock and roll\nnovelty rock boogie-woogie country-rock\nnovelty rock exotica\nnovelty rock polka\nnovelty rock ragtime\nnovelty rock show tune\nnovelty rock ska\nnovelty rock surf rock\nnovelty rock surf-rock\nnovelty rock, Latin rock\nnovelty rock, Latin rock, rockabilly\nnovelty rock, big band swing, rock and roll\nnovelty rock, boogie-woogie, jump blues\nnovelty rock, boogie-woogie, theatrical rock\nnovelty rock, children's jingle\nnovelty rock, chiptune, video game music\nnovelty rock, country rock, rockabilly\nnovelty rock, lo-fi, skiffle\nnovelty rock, surf rock\nnovelty rockabilly\nnovelty schlager\nnovelty show tune\nnovelty ska\nnovelty song\nnovelty song ragtime\nnovelty surf rock\nnovelty surf-rock\nnovelty swing\nnovelty swing rockabilly\nnovelty techno\nnovelty ukulele\nnovelty vocal\nnovelty, Caribbean, ukulele\nnovelty, Dixieland, ragtime\nnovelty, Dutch, Latin\nnovelty, Filipino folk, polka\nnovelty, French chanson, vintage\nnovelty, French, folk\nnovelty, French, vintage\nnovelty, Hawaiian, comedy\nnovelty, Hawaiian, vintage\nnovelty, Italian folk, Schlager\nnovelty, Italian folk, polka\nnovelty, Italian folk, theatrical\nnovelty, Italian, mambo\nnovelty, Japanese festival, electronic\nnovelty, Latin cha-cha, theatrical\nnovelty, Latin, Dutch pop\nnovelty, Latin, European folk\nnovelty, Latin, mambo\nnovelty, Latin, theatrical\nnovelty, Latin, tropical\nnovelty, Latin, world music\nnovelty, big band, Dutch\nnovelty, big band, chiptune\nnovelty, big band, mid-century\nnovelty, big band, orchestral\nnovelty, big band, show tune\nnovelty, big band, vintage\nnovelty, boogie-woogie\nnovelty, boogie-woogie, Dutch\nnovelty, boogie-woogie, barbershop\nnovelty, boogie-woogie, cabaret\nnovelty, boogie-woogie, jazz\nnovelty, boogie-woogie, show tune\nnovelty, boogie-woogie, skiffle\nnovelty, boogie-woogie, swing\nnovelty, boogie-woogie, theatrical\nnovelty, cabaret, polka\nnovelty, cha-cha-chá, French\nnovelty, chiptune, retro pop\nnovelty, chiptune, retro video game\nnovelty, circus pop\nnovelty, circus, theatrical\nnovelty, comedy, German\nnovelty, cumbia, merengue\nnovelty, cumbia, norteño\nnovelty, cumbia, polka\nnovelty, doo-wop, R&B\nnovelty, electronic, German\nnovelty, electronic, cumbia\nnovelty, electronic, sci-fi\nnovelty, folk metal, electronic\nnovelty, funk, horror\nnovelty, funk, lo-fi\nnovelty, honky-tonk, ragtime\nnovelty, honky-tonk, theatrical\nnovelty, klezmer, brass band\nnovelty, klezmer, polka\nnovelty, lo-fi, chiptune\nnovelty, lo-fi, electronic\nnovelty, mambo, salsa\nnovelty, mus theatre, accordion\nnovelty, musette, French pop\nnovelty, music hall, ukulele\nnovelty, old-timey, vaudeville\nnovelty, oompah, musical theatre\nnovelty, orchestral, theatrical\nnovelty, polka, cowboy\nnovelty, polka, humppa\nnovelty, polka, schlager\nnovelty, polka, theatrical\nnovelty, ragtime, boogie-woogie\nnovelty, ragtime, cabaret\nnovelty, ragtime, children's music\nnovelty, ragtime, dixieland\nnovelty, ragtime, lo-fi\nnovelty, ragtime, show tune\nnovelty, ragtime, theatrical\nnovelty, ragtime, vaudeville\nnovelty, retro Soviet, big band\nnovelty, retro electronic, Vietnamese pop\nnovelty, retro, children's music\nnovelty, retro, synth pop\nnovelty, schlager, music hall\nnovelty, skiffle, country-folk\nnovelty, swing, vintage\nnovelty, tarantella, Italian folk\nnovelty, theatrical, accordion\nnovelty, theatrical, circus\nnovelty, theatrical, folk-rock\nnovelty, theatrical, orchestral\nnovelty, theatrical, tango\nnovelty, theatrical, vintage\nnovelty, theatrical, waltz\nnovelty, vaudeville, accordion\nnovelty, vaudeville, comedic\nnovelty, vaudeville, polka\nnovelty, vaudeville, ragtime\nnovelty, vaudeville, theatrical\nnovelty, vaudeville, ukulele rock\nnovelty, world music, Afro-pop\nnovelty, world music, polka\nnu funk\nnu jazz\nnu jazz, dubstep\nnu metal\nnu metal, rap rock\nnu-bossa nova\nnu-disco\nnu-disco C-pop\nnu-disco C-pop funk\nnu-disco C-pop house\nnu-disco French House\nnu-disco French chanson\nnu-disco French funk\nnu-disco French hip-hop\nnu-disco French house\nnu-disco French house chiptune\nnu-disco French pop\nnu-disco G-funk\nnu-disco German pop\nnu-disco J-pop\nnu-disco K-pop\nnu-disco K-pop city pop\nnu-disco Latin funk\nnu-disco Latin funk-pop\nnu-disco Latin house\nnu-disco Latin pop\nnu-disco Mandopop\nnu-disco Mandopop funk\nnu-disco R&B\nnu-disco R&B city pop\nnu-disco R&B funk\nnu-disco UK hip-hop\nnu-disco acid jazz\nnu-disco afro-house\nnu-disco alternative R&B\nnu-disco ambient\nnu-disco big beat\nnu-disco bossa nova\nnu-disco bossa nova lounge\nnu-disco cabaret\nnu-disco chill R&B\nnu-disco chill house\nnu-disco chillwave\nnu-disco chiptune\nnu-disco chiptune J-pop\nnu-disco chiptune synth-pop\nnu-disco cinematic\nnu-disco city pop\nnu-disco city pop J-pop\nnu-disco city pop acid jazz\nnu-disco city pop chiptune\nnu-disco city pop funk\nnu-disco city pop jazz-funk\nnu-disco city pop lounge\nnu-disco city pop smooth jazz\nnu-disco city pop video game\nnu-disco city-pop\nnu-disco complextro\nnu-disco dance-pop\nnu-disco deep house\nnu-disco deep house lounge\nnu-disco dream pop\nnu-disco dream-pop\nnu-disco electro funk\nnu-disco electro house\nnu-disco electro-funk\nnu-disco electro-funk chiptune\nnu-disco electro-house\nnu-disco electro-pop\nnu-disco electro-swing\nnu-disco flamenco\nnu-disco funk\nnu-disco funk acid jazz\nnu-disco funk boogie\nnu-disco funk chillwave\nnu-disco funk chiptune\nnu-disco funk city pop\nnu-disco funk electronic R&B\nnu-disco funk gospel\nnu-disco funk house\nnu-disco funk indie pop\nnu-disco funk jazz\nnu-disco funk jazz fusion\nnu-disco funk lounge\nnu-disco funk lounge jazz\nnu-disco funk pop\nnu-disco funk soul\nnu-disco funk synth-pop\nnu-disco funk-house\nnu-disco funk-pop\nnu-disco funk-pop country-trap\nnu-disco funk-pop glitch-hop\nnu-disco funk-rap\nnu-disco funk-rock\nnu-disco funky house\nnu-disco future bass\nnu-disco future funk\nnu-disco future funk chiptune\nnu-disco future funk city pop\nnu-disco future house\nnu-disco hip-hop\nnu-disco hip-house\nnu-disco house\nnu-disco house chiptune\nnu-disco house funk\nnu-disco hyperpop\nnu-disco hyperpop city pop\nnu-disco indie dance\nnu-disco indie pop\nnu-disco indie rock\nnu-disco indie-funk\nnu-disco indie-pop\nnu-disco italo-disco\nnu-disco jazz\nnu-disco jazz fusion\nnu-disco jazz lounge\nnu-disco jazz-funk\nnu-disco jazz-hop\nnu-disco lo-fi\nnu-disco lo-fi funk\nnu-disco lo-fi hip hop\nnu-disco lo-fi house\nnu-disco lo-fi jazz\nnu-disco lo-fi synth\nnu-disco lo-fi vaporwave\nnu-disco lounge\nnu-disco lounge acid jazz\nnu-disco lounge city pop\nnu-disco lounge funk\nnu-disco lounge house\nnu-disco orchestral\nnu-disco pop\nnu-disco pop-R&B\nnu-disco pop-funk\nnu-disco pop-punk\nnu-disco pop-rap\nnu-disco pop-rock\nnu-disco power-pop\nnu-disco rock\nnu-disco soul\nnu-disco soulful house\nnu-disco synth-funk\nnu-disco synth-pop\nnu-disco synth-pop electro-funk\nnu-disco synthwave\nnu-disco trap\nnu-disco tribal house\nnu-disco trip-hop\nnu-disco tropical\nnu-disco tropical house\nnu-disco vaporwave\nnu-disco world music\nnu-disco worldbeat\nnu-disco, Brazilian funk\nnu-disco, Brazilian funk, acid jazz\nnu-disco, Brazilian funk, city pop\nnu-disco, Brazilian funk, house\nnu-disco, Brazilian funk, worldbeat\nnu-disco, Brazilian house\nnu-disco, Brazilian pop\nnu-disco, C-pop\nnu-disco, Chinese fusion\nnu-disco, Dutch House\nnu-disco, EBM\nnu-disco, French House\nnu-disco, French House, Italo house\nnu-disco, French House, cinematic\nnu-disco, French House, drum and bass\nnu-disco, French house\nnu-disco, French house, Italo-disco\nnu-disco, French house, Latin pop\nnu-disco, French house, ambient\nnu-disco, French house, chiptune\nnu-disco, French house, cinematic\nnu-disco, French house, city pop\nnu-disco, French house, retro-futuristic\nnu-disco, French pop\nnu-disco, French pop, Latin pop\nnu-disco, French pop, funk\nnu-disco, French pop, synth-pop\nnu-disco, French synth-pop\nnu-disco, French synth-pop, chiptune\nnu-disco, French touch\nnu-disco, G-funk\nnu-disco, G-funk, new jack swing\nnu-disco, Indonesian pop\nnu-disco, Italian pop-rock, cinematic\nnu-disco, Italo disco\nnu-disco, Italo disco, synth-funk\nnu-disco, Italo-disco\nnu-disco, Italo-disco, indie pop\nnu-disco, Italo-disco, synth-funk\nnu-disco, J-funk\nnu-disco, J-pop\nnu-disco, J-pop, Eurobeat\nnu-disco, J-pop, chiptune\nnu-disco, J-pop, city pop\nnu-disco, J-pop, vaporwave\nnu-disco, K-R&B\nnu-disco, K-R&B, synth pop\nnu-disco, K-pop\nnu-disco, K-pop, R&B\nnu-disco, Latin funk\nnu-disco, Latin house\nnu-disco, Latin house, jazz fusion\nnu-disco, Latin pop\nnu-disco, MPB, neo-soul\nnu-disco, Mandopop\nnu-disco, Mandopop, R&B\nnu-disco, Middle Eastern pop\nnu-disco, Middle Eastern, Azerbaijani pop\nnu-disco, Persian pop\nnu-disco, R&B, city-pop\nnu-disco, R&B, hip-hop\nnu-disco, R&B, synth-pop\nnu-disco, R&B, synthwave\nnu-disco, Russian pop\nnu-disco, Russian pop-rock\nnu-disco, Turkish pop\nnu-disco, UK garage, dance-pop\nnu-disco, Ukrainian folk\nnu-disco, V-pop\nnu-disco, V-pop, city pop\nnu-disco, Vietnamese pop\nnu-disco, acid jazz, Latin\nnu-disco, acid jazz, world fusion\nnu-disco, alternative R&B, deep house\nnu-disco, ambient, cinematic\nnu-disco, ambient, funk\nnu-disco, baroque pop, soul\nnu-disco, bass house\nnu-disco, chillwave, C-pop\nnu-disco, chillwave, deep house\nnu-disco, chillwave, neo-soul\nnu-disco, chillwave, synth-pop\nnu-disco, chiptune\nnu-disco, chiptune, Italo-disco\nnu-disco, chiptune, ambient\nnu-disco, chiptune, funk\nnu-disco, cinematic\nnu-disco, cinematic pop\nnu-disco, cinematic synth\nnu-disco, cinematic, Arabic soul\nnu-disco, cinematic, C-pop\nnu-disco, cinematic, Chinese fusion\nnu-disco, cinematic, Persian fusion\nnu-disco, cinematic, R&B\nnu-disco, cinematic, Turkish pop\nnu-disco, cinematic, chiptune\nnu-disco, cinematic, dream pop\nnu-disco, cinematic, electronic\nnu-disco, cinematic, ethereal\nnu-disco, cinematic, hip-hop\nnu-disco, cinematic, synth-funk\nnu-disco, cinematic, synthwave\nnu-disco, city pop\nnu-disco, city pop, 80s Japanese funk\nnu-disco, city pop, 90s R&B\nnu-disco, city pop, C-pop\nnu-disco, city pop, French house\nnu-disco, city pop, French pop\nnu-disco, city pop, Indonesian pop\nnu-disco, city pop, J-pop\nnu-disco, city pop, K-R&B\nnu-disco, city pop, K-pop\nnu-disco, city pop, Latin funk\nnu-disco, city pop, Mandarin hip hop\nnu-disco, city pop, Mandarin pop\nnu-disco, city pop, Mandopop\nnu-disco, city pop, R&B\nnu-disco, city pop, Shibuya-kei\nnu-disco, city pop, acid jazz\nnu-disco, city pop, anime soundtrack\nnu-disco, city pop, chiptune\nnu-disco, city pop, electronic\nnu-disco, city pop, funk\nnu-disco, city pop, funk-pop\nnu-disco, city pop, future funk\nnu-disco, city pop, hip-hop\nnu-disco, city pop, house\nnu-disco, city pop, jazz-funk\nnu-disco, city pop, lo-fi\nnu-disco, city pop, lo-fi hip hop\nnu-disco, city pop, modern funk\nnu-disco, city pop, new jack swing\nnu-disco, city pop, retro-funk\nnu-disco, city pop, retro-futuristic\nnu-disco, city pop, synth-funk\nnu-disco, city pop, synth-pop\nnu-disco, city pop, synthwave\nnu-disco, city pop, vaporwave\nnu-disco, city pop, video game music\nnu-disco, city-pop\nnu-disco, complextro\nnu-disco, complextro, funk\nnu-disco, dance-pop\nnu-disco, dance-pop, Russian\nnu-disco, dance-pop, vaporwave\nnu-disco, dancehall, funk\nnu-disco, deep house\nnu-disco, deep house, Brazilian pop\nnu-disco, deep house, French pop\nnu-disco, deep house, Russian pop\nnu-disco, deep house, jazzy lounge\nnu-disco, dream pop\nnu-disco, dream pop, K-pop\nnu-disco, dream pop, city pop\nnu-disco, dream pop, electronic\nnu-disco, dream pop, neo-soul\nnu-disco, dream pop, synth-pop\nnu-disco, dream-pop, K-pop\nnu-disco, electro house\nnu-disco, electro house, EDM\nnu-disco, electro-funk\nnu-disco, electro-funk, cinematic\nnu-disco, electronic, French pop\nnu-disco, electronic, Russian vocal\nnu-disco, electronic, ambient\nnu-disco, electronic, cinematic\nnu-disco, electronic, melancholic\nnu-disco, electronic, synthwave\nnu-disco, electronic, world fusion\nnu-disco, flamenco, R&B\nnu-disco, folk fusion\nnu-disco, french house\nnu-disco, french house, chiptune\nnu-disco, funk, 90s G-funk\nnu-disco, funk, Brazilian pop\nnu-disco, funk, C-pop\nnu-disco, funk, Dutch pop\nnu-disco, funk, French pop\nnu-disco, funk, German pop\nnu-disco, funk, Israeli pop\nnu-disco, funk, Italian pop\nnu-disco, funk, Mandarin R&B\nnu-disco, funk, R&B\nnu-disco, funk, Romanian pop\nnu-disco, funk, Russian pop\nnu-disco, funk, city pop\nnu-disco, funk, city-pop\nnu-disco, funk, dubstep\nnu-disco, funk, ethereal\nnu-disco, funk, hip-hop\nnu-disco, funk, hyperpop\nnu-disco, funk, pop\nnu-disco, funk, synth-pop\nnu-disco, funk-pop, K-pop\nnu-disco, future bass, C-pop\nnu-disco, future bass, hyperpop\nnu-disco, future bass, lo-fi\nnu-disco, future funk\nnu-disco, future funk, French house\nnu-disco, future funk, city pop\nnu-disco, future house\nnu-disco, future house, dance-pop\nnu-disco, glitch, UK garage\nnu-disco, hardstyle\nnu-disco, hardstyle, C-pop\nnu-disco, hardstyle, experimental electronic\nnu-disco, hardstyle, happy hardcore\nnu-disco, hip hop\nnu-disco, hip-hop, C-pop\nnu-disco, hip-hop, R&B\nnu-disco, hip-house\nnu-disco, house, French pop\nnu-disco, house, German pop\nnu-disco, hyperpop\nnu-disco, hyperpop, ambient\nnu-disco, indie dance, French pop\nnu-disco, industrial, chiptune\nnu-disco, industrial, glitch\nnu-disco, jazz hip-hop, pop-R&B\nnu-disco, lo-fi hip hop, K-pop\nnu-disco, lo-fi pop\nnu-disco, lo-fi, French house\nnu-disco, lo-fi, big band\nnu-disco, lo-fi, cinematic\nnu-disco, lo-fi, city pop\nnu-disco, lo-fi, pop-R&B\nnu-disco, modern funk\nnu-disco, new jack swing\nnu-disco, pop-R&B\nnu-disco, pop-punk\nnu-disco, pop-rap, funk\nnu-disco, progressive house\nnu-disco, psychedelic rock, post-punk\nnu-disco, retro funk\nnu-disco, retro-funk, chiptune\nnu-disco, retro-funk, city pop\nnu-disco, retro-futuristic, city pop\nnu-disco, salsa house\nnu-disco, soul, R&B\nnu-disco, soulful R&B, cinematic\nnu-disco, synth-funk\nnu-disco, synth-funk, chiptune\nnu-disco, synth-funk, city pop\nnu-disco, synth-funk, modern R&B\nnu-disco, synth-pop\nnu-disco, synth-pop, 80s\nnu-disco, synth-pop, Arabic fusion\nnu-disco, synth-pop, Eastern European\nnu-disco, synth-pop, French pop\nnu-disco, synth-pop, Italo-disco\nnu-disco, synth-pop, Mandopop\nnu-disco, synth-pop, Persian pop\nnu-disco, synth-pop, V-pop\nnu-disco, synth-pop, cinematic\nnu-disco, synth-pop, city pop\nnu-disco, synth-pop, city-pop\nnu-disco, synth-pop, deep house\nnu-disco, synth-pop, electro-funk\nnu-disco, synth-pop, funk\nnu-disco, synth-pop, indie dance\nnu-disco, synth-pop, lounge\nnu-disco, synth-pop, vaporwave\nnu-disco, synth-pop, world music\nnu-disco, synthwave, JRPG\nnu-disco, tech-house\nnu-disco, trap, funk-rock\nnu-disco, trap, neo-soul\nnu-disco, trip-hop, ambient\nnu-disco, vaporwave, hip-hop\nnu-disco, vaporwave, lo-fi\nnu-disco, vaporwave, pop\nnu-disco, vaporwave, synth-funk\nnu-disco, video game music\nnu-disco, world-funk\nnu-funk\nnu-funk acid jazz\nnu-funk big beat\nnu-funk, Latin pop, city pop\nnu-funk, big beat\nnu-jazz\nnu-jazz French lounge\nnu-jazz French pop\nnu-jazz R&B\nnu-jazz acid jazz\nnu-jazz art-pop\nnu-jazz big beat\nnu-jazz boom-bap\nnu-jazz bossa nova\nnu-jazz breakbeat\nnu-jazz breakbeat chiptune\nnu-jazz breakbeat glitch-hop\nnu-jazz breakbeat video game music\nnu-jazz chill house\nnu-jazz chill-out\nnu-jazz chillhop\nnu-jazz chillout\nnu-jazz chillwave\nnu-jazz chiptune\nnu-jazz city pop\nnu-jazz deep house\nnu-jazz downtempo\nnu-jazz drum and bass\nnu-jazz electro-swing\nnu-jazz funk\nnu-jazz funk R&B\nnu-jazz funk breakbeat\nnu-jazz funk chill house\nnu-jazz funk city pop\nnu-jazz funk electronic\nnu-jazz funk electronic lounge\nnu-jazz funk fusion\nnu-jazz funk lounge\nnu-jazz funk rock\nnu-jazz funk-pop\nnu-jazz future bass\nnu-jazz future funk\nnu-jazz hip-hop\nnu-jazz house\nnu-jazz liquid funk\nnu-jazz lo-fi\nnu-jazz lo-fi hip hop\nnu-jazz lo-fi hip-hop\nnu-jazz lo-fi hip-hop chiptune\nnu-jazz lo-fi lounge\nnu-jazz lounge\nnu-jazz lounge bossa nova\nnu-jazz lounge chillhop\nnu-jazz lounge house\nnu-jazz lounge-house\nnu-jazz lounge-pop\nnu-jazz pop\nnu-jazz synth-pop\nnu-jazz trip-hop\nnu-jazz, Latin jazz, lounge\nnu-jazz, breakbeat, lo-fi\nnu-jazz, drum and bass, ambient\nnu-jazz, funk, lo-fi hip hop\nnu-jazz, video game music\nnu-metal\nnu-metal J-rock\nnu-metal J-rock fusion\nnu-metal K-pop fusion\nnu-metal R&B\nnu-metal alt-rock\nnu-metal alternative metal\nnu-metal alternative rock\nnu-metal alternative rock electronic\nnu-metal bhangra\nnu-metal breakbeat\nnu-metal chiptune\nnu-metal chiptune rock\nnu-metal dance-pop\nnu-metal dancehall\nnu-metal dubstep\nnu-metal electronic\nnu-metal electronic breakbeat\nnu-metal electronic rock\nnu-metal electronic rock hip-hop\nnu-metal electronic rock rap\nnu-metal electronicore\nnu-metal emo\nnu-metal emo-rock nintendocore\nnu-metal funk\nnu-metal funk-rock\nnu-metal german rap\nnu-metal groove metal\nnu-metal happy hardcore\nnu-metal hip hop\nnu-metal hip-hop\nnu-metal hip-hop acoustic\nnu-metal hip-hop folk\nnu-metal hip-hop funk\nnu-metal hip-hop fusion\nnu-metal horrorcore\nnu-metal hyperpop\nnu-metal hyperpop rap-rock\nnu-metal industrial\nnu-metal industrial hip-hop\nnu-metal industrial metal\nnu-metal industrial rock\nnu-metal lo-fi\nnu-metal metalcore\nnu-metal pop-punk\nnu-metal pop-rock\nnu-metal post-hardcore\nnu-metal post-punk\nnu-metal post-rock\nnu-metal protest rock\nnu-metal punk rock\nnu-metal rap\nnu-metal rap rock\nnu-metal rap-metal\nnu-metal rap-rock\nnu-metal rap-rock alternative rock\nnu-metal rap-rock electronic\nnu-metal rap-rock pop-punk\nnu-metal rapcore\nnu-metal rapcore pop-punk\nnu-metal reggae rock\nnu-metal reggaeton\nnu-metal rock\nnu-metal trap\nnu-metal trap R&B\nnu-metal trap chiptune\nnu-metal trap hyperpop\nnu-metal trap metal\nnu-metal trap metal experimental\nnu-metal trap metal hyperpop\nnu-metal trip-hop\nnu-metal vaporwave\nnu-metal, Balkan folk\nnu-metal, Bollywood fusion, cinematic\nnu-metal, Bollywood rock\nnu-metal, C-pop\nnu-metal, C-pop, ambient\nnu-metal, C-pop, ancient style\nnu-metal, C-pop, cinematic\nnu-metal, C-pop, cinematic rock\nnu-metal, C-pop, electronic\nnu-metal, C-pop, experimental\nnu-metal, C-pop, lo-fi\nnu-metal, C-pop, lo-fi hip hop\nnu-metal, C-pop, opera\nnu-metal, C-pop, traditional Chinese\nnu-metal, C-pop, trap\nnu-metal, C-pop, video game\nnu-metal, C-pop, world music\nnu-metal, Cantopop-rock, hip-hop\nnu-metal, Chinese folk\nnu-metal, Chinese folk fusion\nnu-metal, Chinese folk rock\nnu-metal, Chinese folk, opera\nnu-metal, Chinese folk, rap-metal\nnu-metal, Chinese folk, wuxia\nnu-metal, Chinese folk-metal\nnu-metal, Chinese fusion\nnu-metal, Chinese fusion, cinematic rock\nnu-metal, Chinese fusion, heavy metal\nnu-metal, Chinese opera\nnu-metal, Chinese opera, experimental\nnu-metal, Chinese opera, rock\nnu-metal, Chinese rap, theatrical\nnu-metal, Chinese rock\nnu-metal, German battle rap\nnu-metal, German hip-hop\nnu-metal, German hip-hop, cinematic\nnu-metal, German hip-hop, electronic\nnu-metal, German rap\nnu-metal, German rap, hard rock\nnu-metal, German rap-rock\nnu-metal, Indian classical\nnu-metal, Indian classical, cinematic\nnu-metal, Indian dance-pop\nnu-metal, Indian folk, cinematic\nnu-metal, Indian pop\nnu-metal, Indian rap-rock\nnu-metal, Indian rock\nnu-metal, J-rock\nnu-metal, J-rock, K-hip-hop\nnu-metal, J-rock, anime\nnu-metal, J-rock, anime theme\nnu-metal, J-rock, cinematic\nnu-metal, J-rock, metalcore\nnu-metal, J-rock, pop-rock\nnu-metal, J-rock, rap-rock\nnu-metal, K-pop\nnu-metal, K-rock\nnu-metal, Mando-C-Rock\nnu-metal, Mandopop rock\nnu-metal, Middle Eastern folk\nnu-metal, Middle Eastern rock\nnu-metal, R&B, hip-hop\nnu-metal, Sanskrit chant\nnu-metal, South Asian folk\nnu-metal, South Indian film music\nnu-metal, Tamil rap\nnu-metal, Tamil rap-rock\nnu-metal, Tamil rock\nnu-metal, Telugu folk\nnu-metal, Telugu folk, dance rock\nnu-metal, alt-rock, rap-rock\nnu-metal, alternative metal\nnu-metal, alternative metal, C-pop\nnu-metal, alternative metal, Chinese hip-hop\nnu-metal, alternative metal, post-apocalyptic\nnu-metal, alternative metal, post-hardcore\nnu-metal, alternative rock, C-pop\nnu-metal, alternative rock, Chinese hip-hop\nnu-metal, alternative rock, chiptune\nnu-metal, alternative rock, electronic pop\nnu-metal, alternative rock, hip-hop\nnu-metal, alternative rock, metalcore\nnu-metal, alternative rock, shoegaze\nnu-metal, ambient, C-pop\nnu-metal, ambient, experimental rock\nnu-metal, ballad, C-pop\nnu-metal, chiptune, C-pop\nnu-metal, chiptune, comedy metal\nnu-metal, chiptune, electronic\nnu-metal, chiptune, emo rock\nnu-metal, chiptune, rap-rock\nnu-metal, chiptune, synth-pop\nnu-metal, cinematic hip-hop, rock\nnu-metal, cinematic pop, lo-fi hip hop\nnu-metal, cinematic rock\nnu-metal, cinematic rock, C-pop\nnu-metal, cinematic rock, Chinese fusion\nnu-metal, cinematic rock, Spanish rap\nnu-metal, cinematic rock, metalcore\nnu-metal, cinematic rock, pop-rock\nnu-metal, cinematic rock, rap-metal\nnu-metal, cinematic rock, rap-rock\nnu-metal, cinematic, C-pop\nnu-metal, cinematic, Chinese fusion\nnu-metal, cinematic, Chinese opera\nnu-metal, cinematic, ballad\nnu-metal, cinematic, electronic\nnu-metal, cinematic, gothic\nnu-metal, comedy rap\nnu-metal, comedy rock, rap-rock\nnu-metal, conscious hip-hop\nnu-metal, devotional rock\nnu-metal, djent, rap-rock\nnu-metal, dubstep, cinematic\nnu-metal, dubstep, hip hop\nnu-metal, dubstep, hip-hop\nnu-metal, electronic breakbeat, chiptune\nnu-metal, electronic dance\nnu-metal, electronic dance music\nnu-metal, electronic rock\nnu-metal, electronic rock, Greek rock\nnu-metal, electronic rock, Mandopop\nnu-metal, electronic rock, Telugu hip hop\nnu-metal, electronic rock, cinematic\nnu-metal, electronic rock, hip-hop\nnu-metal, electronic rock, hyperpop\nnu-metal, electronic rock, rap-rock\nnu-metal, electronic rock, trap metal\nnu-metal, electronic trap\nnu-metal, electronic, Balkan fusion\nnu-metal, electronic, C-pop\nnu-metal, electronic, chiptune\nnu-metal, electronic, horror\nnu-metal, electronic, shred guitar\nnu-metal, electronicore, dubstep\nnu-metal, electronicore, hardstyle\nnu-metal, emo rap, alternative rock\nnu-metal, emo rock, metalcore\nnu-metal, emo-rock\nnu-metal, experimental, electronic\nnu-metal, flamenco rock, rap-rock\nnu-metal, folk-rock, metalcore\nnu-metal, funk, electronic\nnu-metal, funk, rap\nnu-metal, hard rock\nnu-metal, hard rock, German rap\nnu-metal, hard rock, Middle Eastern fusion\nnu-metal, hardstyle, EDM\nnu-metal, hardstyle, experimental\nnu-metal, hip-hop, Indian classical\nnu-metal, hip-hop, ambient\nnu-metal, hip-hop, cinematic\nnu-metal, hip-hop, industrial\nnu-metal, hip-hop, metalcore\nnu-metal, hyperpop\nnu-metal, hyperpop, electronic\nnu-metal, indie rock, hip-hop\nnu-metal, indie-folk, rap-rock\nnu-metal, industrial metal\nnu-metal, industrial metal, metalcore\nnu-metal, industrial rock\nnu-metal, industrial rock, C-pop\nnu-metal, industrial rock, South Asian fusion\nnu-metal, industrial rock, chiptune\nnu-metal, industrial rock, cinematic\nnu-metal, industrial rock, electronic\nnu-metal, industrial rock, funk\nnu-metal, industrial rock, spiritual fusion\nnu-metal, industrial, German rap\nnu-metal, industrial, J-rock\nnu-metal, industrial, metalcore\nnu-metal, industrial, rap\nnu-metal, jazz-funk, blues-rock\nnu-metal, jazz-rock, ambient\nnu-metal, kuthu\nnu-metal, kuthu, electronic\nnu-metal, kuthu, hip-hop\nnu-metal, kuthu, pop\nnu-metal, kuthu, rock\nnu-metal, lo-fi chiptune, cinematic rock\nnu-metal, lo-fi hip hop, Russian rap\nnu-metal, lo-fi hip hop, chiptune\nnu-metal, lo-fi hip hop, emo-rap\nnu-metal, lo-fi hip hop, experimental\nnu-metal, lo-fi hip hop, rock\nnu-metal, lo-fi hip-hop\nnu-metal, lo-fi hip-hop, piano ballad\nnu-metal, lo-fi hip-hop, post-hardcore\nnu-metal, lo-fi, ambient\nnu-metal, lo-fi, horrorcore\nnu-metal, lo-fi, rap-rock\nnu-metal, metalcore\nnu-metal, metalcore, Russian rap\nnu-metal, metalcore, ambient\nnu-metal, metalcore, cinematic\nnu-metal, metalcore, electronic\nnu-metal, metalcore, electronicore\nnu-metal, metalcore, industrial\nnu-metal, metalcore, jazz\nnu-metal, metalcore, rap rock\nnu-metal, metalcore, rap-metal\nnu-metal, metalcore, rap-rock\nnu-metal, operatic rock\nnu-metal, orchestral rock, power metal\nnu-metal, orchestral, cinematic\nnu-metal, orchestral, hip-hop\nnu-metal, pop-R&B, ambient\nnu-metal, pop-R&B, trap\nnu-metal, pop-punk, South Indian\nnu-metal, pop-punk, vaporwave\nnu-metal, pop-rock\nnu-metal, pop-rock, cinematic\nnu-metal, pop-rock, dubstep\nnu-metal, pop-rock, electronic\nnu-metal, pop-rock, metalcore\nnu-metal, pop-rock, world music\nnu-metal, post-hardcore, alternative metalcore\nnu-metal, post-hardcore, hip-hop\nnu-metal, post-hardcore, rap-rock\nnu-metal, post-rock, rap-rock\nnu-metal, protest music\nnu-metal, psychedelic hip-hop\nnu-metal, psychedelic rock\nnu-metal, punk rock, German rap\nnu-metal, rap, Indian fusion\nnu-metal, rap, atmospheric rock\nnu-metal, rap-metal\nnu-metal, rap-metal, alternative rock\nnu-metal, rap-metal, cinematic\nnu-metal, rap-metal, dubstep\nnu-metal, rap-metal, theatrical rock\nnu-metal, rap-rock\nnu-metal, rap-rock, C-pop\nnu-metal, rap-rock, Chinese cinematic\nnu-metal, rap-rock, Chinese fusion\nnu-metal, rap-rock, Indian fusion\nnu-metal, rap-rock, Indian rock\nnu-metal, rap-rock, J-rock\nnu-metal, rap-rock, K-pop\nnu-metal, rap-rock, South Indian\nnu-metal, rap-rock, Thai rock\nnu-metal, rap-rock, alternative rock\nnu-metal, rap-rock, atmospheric\nnu-metal, rap-rock, atmospheric hip-hop\nnu-metal, rap-rock, chiptune\nnu-metal, rap-rock, cinematic\nnu-metal, rap-rock, dubstep\nnu-metal, rap-rock, electronic\nnu-metal, rap-rock, electronic rock\nnu-metal, rap-rock, emotional ballad\nnu-metal, rap-rock, glitch\nnu-metal, rap-rock, indie rock\nnu-metal, rap-rock, industrial rock\nnu-metal, rap-rock, jazz hip-hop\nnu-metal, rap-rock, lo-fi\nnu-metal, rap-rock, melancholic pop\nnu-metal, rap-rock, metalcore\nnu-metal, rap-rock, pop-rock\nnu-metal, rap-rock, post-hardcore\nnu-metal, rap-rock, post-rock\nnu-metal, rap-rock, soulful\nnu-metal, rap-rock, surf-rock\nnu-metal, rap-rock, trap\nnu-metal, rap-rock, trap-metal\nnu-metal, rock, C-pop\nnu-metal, rock, Chinese folk\nnu-metal, rock, Indian classical\nnu-metal, southern rock\nnu-metal, symphonic metal, J-rock\nnu-metal, synth-pop\nnu-metal, synth-rock, electronic\nnu-metal, theatrical pop, swing\nnu-metal, traditional Chinese, cinematic\nnu-metal, trap\nnu-metal, trap metal\nnu-metal, trap metal, ambient\nnu-metal, trap metal, metalcore\nnu-metal, trap metal, modern trap\nnu-metal, trap, C-pop\nnu-metal, trap, Chinese rock\nnu-metal, trap, cinematic\nnu-metal, trap, emo-rap\nnu-metal, trap, hard rock\nnu-metal, trap, lo-fi\nnu-metal, trap, lo-fi hip hop\nnu-metal, trap, pop\nnu-metal, trap, rap rock\nnu-metal, trap, rap-rock\nnu-metal, trap-metal, R&B\nnu-metal, trip-hop, cinematic\nnu-metal, turntablism\nnu-metal, turntablism, J-rock\nnu-metalcore\nnu-metalcore electronicore\nnu-metalcore industrial metal\nnu-metalcore rap-rock\nnueva canción\nnursery rhyme\nnursery rhyme jazz\nnursery rhyme, polka, children's music\nold school hip hop\nold-school Brazilian hip-hop\nold-school Dutch hip-hop\nold-school French hip-hop\nold-school German hip-hop\nold-school Hebrew hip-hop\nold-school Italian hip-hop\nold-school Japanese hip-hop\nold-school K-hip-hop\nold-school Korean hip-hop\nold-school Polish hip-hop\nold-school Romanian hip-hop\nold-school Russian hip-hop\nold-school Spanish hip-hop\nold-school Thai hip-hop\nold-school Turkish hip-hop\nold-school Vietnamese hip-hop\nold-school boom-bap\nold-school breakbeat\nold-school electro\nold-school electro hip hop\nold-school electro hip-hop\nold-school electronic\nold-school funk\nold-school hip hop\nold-school hip-hop\nold-school hip-hop Latin\nold-school hip-hop chiptune\nold-school hip-hop dancehall\nold-school hip-hop electro-funk\nold-school hip-hop funk\nold-school hip-hop reggae\nold-school hip-hop, Latin funk\nold-school hip-hop, Latin hip-hop\nold-school hip-hop, R&B/trap\nold-school hip-hop, classic rock\nold-school hip-hop, new jack swing\nold-school hip-hop, trap\nold-school house\nold-school rave\nold-school reggaeton\nold-school techno\nold-time\nold-time ballad\nold-time bluegrass\nold-time fiddle\nold-time folk\nold-time gospel\nold-timey country\nold-timey folk\noompah\noompah hip-hop\nopera\nopera ballad\nopera baroque\nopera buffa\nopera chiptune\nopera comedy\nopera comique\nopera folk\nopera fusion\nopera jazz\nopera metal\nopera pop\nopera pop, rap rock, Filipino ballad\nopera rock\nopera tango\nopera trap\nopera, Greek, Middle Eastern\nopera, Italian ballad, cinematic\nopera, Italian ballad, theatrical\nopera, Italian folk, mandolin\nopera, Middle Eastern folk, Balkan folk\nopera, art song, flamenco\nopera, balkan folk, world music\nopera, big band, Italian theatrical\nopera, bolero, orchestral\nopera, bolero, tango\nopera, cinematic, French chanson\nopera, cinematic, Italian ballad\nopera, cinematic, Neapolitan\nopera, cinematic, Turkish art music\nopera, cinematic, ballad\nopera, classical, copla\nopera, classical, dramatic\nopera, classical, flamenco\nopera, classical, folk\nopera, flamenco, acoustic\nopera, flamenco, cinematic\nopera, flamenco, classical\nopera, flamenco, classical guitar\nopera, folk, accordion\nopera, folk, cinematic\nopera, mariachi\nopera, mariachi, cinematic\nopera, orchestral, Chinese opera\nopera, oud, cinematic\nopera, piano ballad, Turkish art music\nopera, polka, klezmer\nopera, salsa\nopera, samba, acoustic\nopera, soulful, dramatic\nopera, tango, cinematic\nopera, tango, classical\nopera, tango, orchestral\nopera, theatrical, Italian folk\nopera, theatrical, Turkish art song\nopera, theatrical, copla\nopera, theatrical, flamenco\noperatic\noperatic Arabic\noperatic C-pop\noperatic Christmas\noperatic R&B\noperatic a cappella\noperatic ambient\noperatic anthem\noperatic art song\noperatic ballad\noperatic baritone\noperatic baroque\noperatic bolero\noperatic brass\noperatic cabaret\noperatic chamber\noperatic chanson\noperatic choral\noperatic cinematic\noperatic classical\noperatic comedy\noperatic copla\noperatic cumbia\noperatic drama\noperatic duet\noperatic film score\noperatic flamenco\noperatic folk\noperatic fusion\noperatic ghazal\noperatic gypsy jazz\noperatic hip-hop\noperatic jazz\noperatic lament\noperatic melancholy\noperatic musical\noperatic musical theater\noperatic novelty\noperatic orchestral\noperatic piano\noperatic polka\noperatic pop\noperatic ragtime\noperatic rock\noperatic romance\noperatic salsa\noperatic satire\noperatic show tune\noperatic soul\noperatic swing\noperatic synth\noperatic tango\noperatic theater\noperatic trap\noperatic waltz\noperatic, Brazilian, theatrical\noperatic, cinematic, dramatic\noperatic, dark cabaret, cinematic\noperatic, fado, baroque\noperatic, sea shanty, cinematic\noptimistic pop\norchestral\norchestral Arabic\norchestral Arabic pop\norchestral Axé\norchestral C-pop\norchestral Celtic\norchestral Celtic folk\norchestral Christian\norchestral Christmas\norchestral EDM\norchestral J-RPG\norchestral J-pop\norchestral JRPG\norchestral Latin\norchestral Latin Christian\norchestral Latin ballad\norchestral Latin folk\norchestral R&B\norchestral RPG\norchestral Spanish Christmas\norchestral action\norchestral ambient\norchestral anime\norchestral anime theme\norchestral anthem\norchestral art song\norchestral ballad\norchestral ballad, classical crossover, Chinese melodic\norchestral ballad, enka, cinematic\norchestral baroque\norchestral big band\norchestral blues\norchestral bolero\norchestral brass\norchestral breakcore\norchestral caprice\norchestral cartoon\norchestral cartoon score\norchestral celebration\norchestral chanson\norchestral chiptune\norchestral choral\norchestral cinematic\norchestral circus\norchestral circus march\norchestral classical\norchestral comedy\norchestral copla\norchestral dance\norchestral dance-pop\norchestral dembow\norchestral disco\norchestral disco-funk\norchestral dramatic\norchestral drill\norchestral drum and bass\norchestral dubstep\norchestral easy-listening\norchestral educational\norchestral electronic\norchestral electronic rock\norchestral electronica\norchestral epic\norchestral eurodance\norchestral fado\norchestral fairytale\norchestral fanfare\norchestral fanfare, Russian pop, estrada\norchestral fanfare, dance-pop, 80s synth-pop\norchestral fanfare, synth-pop, rap\norchestral fantasy\norchestral fantasy, electronic pop\norchestral festive\norchestral film score\norchestral flamenco\norchestral folk\norchestral folk cabaret\norchestral folk rock\norchestral folk-pop\norchestral folk-rock\norchestral funk\norchestral funk-rock\norchestral fusion\norchestral gabber\norchestral galop\norchestral gospel\norchestral gospel pop-rock\norchestral hardcore techno\norchestral hardstyle\norchestral heroic\norchestral hip hop\norchestral hip-hop\norchestral hip-hop trap\norchestral hip-hop, old-school hip-hop\norchestral holiday\norchestral horror\norchestral house\norchestral hybrid\norchestral hybrid trap\norchestral hymn\norchestral hype\norchestral hyperpop\norchestral jazz\norchestral jazz fusion\norchestral klezmer\norchestral korean\norchestral korean folk\norchestral lo-fi\norchestral lullaby\norchestral march\norchestral march, cinematic, Kayōkyoku\norchestral martial anthem\norchestral metal\norchestral musical\norchestral neo-classical\norchestral noir\norchestral novelty\norchestral nu-disco\norchestral opera\norchestral pasodoble\norchestral patriotic\norchestral percussion\norchestral polka\norchestral pop\norchestral pop J-pop\norchestral pop anime\norchestral pop anime soundtrack\norchestral pop cabaret\norchestral pop chanson\norchestral pop city pop lounge\norchestral pop hip-hop\norchestral pop lounge jazz\norchestral pop nu-disco\norchestral pop rock\norchestral pop trap\norchestral pop trot\norchestral pop world music\norchestral pop, 1980s Korean trot\norchestral pop, C-pop, electronic rock\norchestral pop, Chinese New Year\norchestral pop, Chinese traditional, rock\norchestral pop, J-pop ballad\norchestral pop, J-rock, anime soundtrack\norchestral pop, Korean trot, big band\norchestral pop, Latin pop, cinematic\norchestral pop, MPB, power ballad\norchestral pop, Persian dance, cinematic\norchestral pop, Persian dance-pop\norchestral pop, Pop Melayu\norchestral pop, Russian estrada\norchestral pop, South Asian film music\norchestral pop, cinematic, Chinese influence\norchestral pop, cinematic, traditional Chinese\norchestral pop, disco-funk, Chinese folk\norchestral pop, epic trap\norchestral pop, estrada, Soviet-era\norchestral pop, estrada, synth ballad\norchestral pop, hard rock\norchestral pop, musical theater\norchestral pop, trap, hip-hop\norchestral pop, trap, rap\norchestral pop, trot\norchestral pop, vintage Mandopop\norchestral pop, vintage Mandopop, big band\norchestral pop-rap\norchestral pop-rock\norchestral power ballad\norchestral progressive house\norchestral ragtime\norchestral reggaeton\norchestral revolution\norchestral revolutionary\norchestral rock\norchestral rock anime\norchestral rock hip-hop\norchestral rock, J-rock, rap-rock\norchestral rock, rap-metal, cinematic\norchestral romance\norchestral romantic\norchestral romantic ballad\norchestral samba\norchestral samba-rock\norchestral sea shanty\norchestral sertanejo\norchestral show tune\norchestral soul\norchestral speedcore\norchestral spy\norchestral steampunk\norchestral suspense\norchestral swing\norchestral synth\norchestral synth-rock\norchestral tango\norchestral techno\norchestral tension\norchestral thriller\norchestral torch song\norchestral trailer\norchestral trance\norchestral trance, hardstyle, cinematic\norchestral trap\norchestral trap metal\norchestral trap, conscious hip-hop\norchestral trap, emotional R&B\norchestral trot\norchestral video game\norchestral video game score\norchestral video game soundtrack\norchestral waltz\norchestral whimsy\norchestral world music\norchestral worship\norchestral, 16-bit, Japanese RPG\norchestral, 16-bit, RPG\norchestral, 16-bit, video game\norchestral, 90s J-RPG, synth\norchestral, 90s J-RPG, synthwave\norchestral, 90s JRPG, cinematic\norchestral, Arabic, cinematic\norchestral, Arabic, epic\norchestral, Azerbaijani, Turkish\norchestral, Balkan, Klezmer\norchestral, Brazilian Axé, cinematic\norchestral, Chinese folk, operatic\norchestral, Chinese opera\norchestral, Christmas, cinematic\norchestral, Christmas, classical\norchestral, Eastern European folk, Middle Eastern folk\norchestral, J-RPG, cinematic\norchestral, J-pop, anime soundtrack\norchestral, JRPG, anime\norchestral, JRPG, baroque\norchestral, JRPG, cinematic\norchestral, JRPG, epic\norchestral, JRPG, folk\norchestral, JRPG, heroic\norchestral, JRPG, rock\norchestral, JRPG, symphonic rock\norchestral, JRPG, synth\norchestral, JRPG, whimsical\norchestral, Japanese RPG\norchestral, Japanese RPG, cinematic\norchestral, Japanese RPG, epic\norchestral, Japanese RPG, heroic\norchestral, Japanese RPG, synth\norchestral, Kayōkyoku, cinematic\norchestral, Korean trot, cinematic\norchestral, Latin, Spanish\norchestral, Latin, big band\norchestral, Latin, cinematic\norchestral, Latin, world music\norchestral, Mexican folk, operatic\norchestral, Middle Eastern, Persian\norchestral, Middle Eastern, choral\norchestral, Middle Eastern, cinematic\norchestral, Middle Eastern, classical\norchestral, RPG, cinematic\norchestral, anime, RPG\norchestral, avant-garde, cinematic\norchestral, baroque, cinematic\norchestral, baroque, classical\norchestral, baroque, whimsical\norchestral, big band, cartoon\norchestral, big band, cartoon score\norchestral, big band, cinematic\norchestral, big band, ragtime\norchestral, cartoon score, J-pop\norchestral, cartoon score, baroque\norchestral, cartoon score, cinematic\norchestral, cartoon score, playful\norchestral, cartoon score, theatrical\norchestral, cartoon score, whimsical\norchestral, cartoon soundtrack\norchestral, cartoon, adventure\norchestral, cartoon, baroque\norchestral, cartoon, big band\norchestral, cartoon, bombastic\norchestral, cartoon, cinematic\norchestral, cartoon, circus\norchestral, cartoon, dramatic\norchestral, cartoon, fantasy\norchestral, cartoon, golden age film\norchestral, cartoon, heroic\norchestral, cartoon, klezmer\norchestral, cartoon, musette\norchestral, cartoon, playful\norchestral, cartoon, ragtime\norchestral, cartoon, slapstick\norchestral, cartoon, spy\norchestral, cartoon, tango\norchestral, cartoon, theatrical\norchestral, cartoon, video game\norchestral, cartoon, whimsical\norchestral, cartoonish\norchestral, cartoonish, playful\norchestral, children's choir, cinematic\norchestral, choral, Christmas\norchestral, choral, cinematic\norchestral, choral, classical\norchestral, choral, epic\norchestral, choral, holiday\norchestral, choral, martial\norchestral, choral, patriotic\norchestral, choral, sacred\norchestral, choral, theatrical\norchestral, cinematic, Arabic fusion\norchestral, cinematic, Balkan folk\norchestral, cinematic, Chinese art song\norchestral, cinematic, Chinese folk opera\norchestral, cinematic, Chinese revolutionary\norchestral, cinematic, Christmas\norchestral, cinematic, East Asian\norchestral, cinematic, French chanson\norchestral, cinematic, Halloween\norchestral, cinematic, Hollywood\norchestral, cinematic, JRPG\norchestral, cinematic, Japanese RPG\norchestral, cinematic, Middle Eastern\norchestral, cinematic, RPG\norchestral, cinematic, Shidaiqu\norchestral, cinematic, animated film score\norchestral, cinematic, anime\norchestral, cinematic, baroque\norchestral, cinematic, big band\norchestral, cinematic, cabaret\norchestral, cinematic, cartoon\norchestral, cinematic, cartoon score\norchestral, cinematic, cartoonish\norchestral, cinematic, children's music\norchestral, cinematic, choral\norchestral, cinematic, dramatic\norchestral, cinematic, fantasy\norchestral, cinematic, folk\norchestral, cinematic, folk dance\norchestral, cinematic, heroic\norchestral, cinematic, holiday\norchestral, cinematic, jazz fusion\norchestral, cinematic, late-Romantic\norchestral, cinematic, medieval folk\norchestral, cinematic, musical\norchestral, cinematic, musical theater\norchestral, cinematic, musical theatre\norchestral, cinematic, neo-classical\norchestral, cinematic, opera\norchestral, cinematic, operatic\norchestral, cinematic, playful\norchestral, cinematic, quirky\norchestral, cinematic, ragtime\norchestral, cinematic, rock\norchestral, cinematic, spy\norchestral, cinematic, spy movie\norchestral, cinematic, theatrical\norchestral, cinematic, video game\norchestral, cinematic, video game soundtrack\norchestral, cinematic, vintage Hollywood\norchestral, cinematic, waltz\norchestral, cinematic, whimsical\norchestral, circus, cartoon\norchestral, circus, cinematic\norchestral, circus, galop\norchestral, circus, musette\norchestral, classical, Christmas\norchestral, classical, Latin\norchestral, classical, Russian romance\norchestral, classical, choral\norchestral, classical, cinematic\norchestral, classical, galop\norchestral, classical, holiday\norchestral, classical, patriotic\norchestral, classical, schlager\norchestral, copla, theatrical\norchestral, dramatic, cinematic\norchestral, epic, JRPG\norchestral, fantasy, video game\norchestral, festive, Christmas\norchestral, festive, children's music\norchestral, festive, choral\norchestral, festive, cinematic\norchestral, festive, classical\norchestral, festive, waltz\norchestral, festive, whimsical\norchestral, folk, cinematic\norchestral, folk, neo-romantic\norchestral, folk, operatic\norchestral, funk, video game\norchestral, gothic, anime soundtrack\norchestral, heroic, JRPG\norchestral, heroic, Japanese RPG\norchestral, heroic, anime\norchestral, heroic, cinematic\norchestral, heroic, video game\norchestral, holiday, choral\norchestral, holiday, cinematic\norchestral, holiday, festive\norchestral, klezmer, cinematic\norchestral, klezmer, eastern european\norchestral, mambo, cartoon\norchestral, musical theater\norchestral, musical theater, cinematic\norchestral, musical theater, epic\norchestral, musical, cinematic\norchestral, neoclassical, film score\norchestral, opera, Italian\norchestral, opera, patriotic\norchestral, operatic, European art song\norchestral, operatic, French chanson\norchestral, operatic, cinematic\norchestral, operatic, devotional\norchestral, operatic, epic\norchestral, operatic, musical theatre\norchestral, operatic, patriotic\norchestral, operatic, revolutionary\norchestral, operatic, theatrical\norchestral, pasodoble, concert march\norchestral, patriotic, Chinese fusion\norchestral, patriotic, Chinese revolutionary opera\norchestral, patriotic, South Asian classical\norchestral, patriotic, choral\norchestral, patriotic, cinematic\norchestral, patriotic, classical\norchestral, patriotic, classical Thai\norchestral, patriotic, operatic\norchestral, patriotic, vintage film score\norchestral, playful, animated film score\norchestral, playful, cartoon\norchestral, playful, cinematic\norchestral, playful, klezmer\norchestral, playful, video game\norchestral, polka, cinematic\norchestral, progressive rock, spy theme\norchestral, ragtime, big band\norchestral, ragtime, cartoon\norchestral, ragtime, circus\norchestral, spiritual, world fusion\norchestral, spy theme, cartoon\norchestral, spy, cartoon\norchestral, steampunk, musical theater\norchestral, symphonic, operatic\norchestral, theatrical, Chinese art song\norchestral, theatrical, Christmas\norchestral, theatrical, Halloween\norchestral, theatrical, Hollywood musical\norchestral, theatrical, animated film score\norchestral, theatrical, cartoon\norchestral, theatrical, choral\norchestral, theatrical, cinematic\norchestral, theatrical, classical\norchestral, theatrical, fairytale\norchestral, theatrical, opera\norchestral, theatrical, operatic\norchestral, theatrical, patriotic\norchestral, theatrical, polka\norchestral, theatrical, romantic\norchestral, traditional Chinese, cinematic\norchestral, traditional, Polish\norchestral, trot, cinematic\norchestral, video game score, J-RPG\norchestral, video game soundtrack\norchestral, video game soundtrack, JRPG\norchestral, video game soundtrack, epic\norchestral, video game, Japanese RPG\norchestral, video game, ambient\norchestral, video game, cartoon\norchestral, video game, cinematic\norchestral, video game, dramatic\norchestral, video game, heroic\norchestral, video game, progressive rock\norchestral, video game, ragtime\norchestral, video game, whimsical\norchestral, vintage cinema, big band\norchestral, vintage, Shidaiqu\norchestral, vintage, cartoon\norchestral, whimsical, Japanese children's\norchestral, whimsical, Vocaloid\norchestral, whimsical, cinematic\norchestral, whimsical, fantasy\norchestral, whimsical, video game\norchestral-electronic\norchestral-pop\norgan music\norganic R&B\norganic beat\norganic groove\norganic hip-hop\norganic house\norganic percussion\norganic pop\noriental dance\noriental deep house\noriental electronica\noriental folk metal\noriental house\noriental metal\noriental metal electronicore\noriental metal industrial rock\noriental metal, technical death metal\noriental metalcore\noriental pop\noriental psytrance\noriental tech house\noriental tech-house\noriental trance\noriental trance dance-pop\noriental trap\noud improvisation\noud instrumental\noud music\noud taqsim\noud taqsim, samba-reggae\noud taqsim, samba-reggae, Brazilian\noud virtuosity\noud, ambient, world fusion\noud, folk, theatrical\noud, melancholic, lo-fi\noud, melancholic, traditional\noutback blues\noutlaw Americana\noutlaw country\noutlaw country rock\noutlaw country rockabilly\noutlaw country sci-fi western\noutlaw country, Norteño\noutlaw country, southern rock\noutlaw country, southern rock, blues rock\noutlaw country-rock\noutlaw rock\noyun havası\npagode\npagode MPB\npagode R&B\npagode axé\npagode forró\npagode funk\npagode gospel\npagode pop\npagode reggae\npagode romântico\npagode samba\npagode samba rock\npagode samba-pop\npagode samba-reggae\npagode samba-rock\npagode samba-romântico\npagode sertanejo\npagode sertanejo samba\npagode trap\npagode, Axé\npagode, axé\npagode, pop-R&B, Brazilian\npagode, pop-samba, romantic pagode\npagode, sertanejo, samba\npagode, smooth jazz, Brazilian pop\npagode, trap, Brazilian hip-hop\npagode-pop\npandango\npansori\nparranda\nparty accordion\nparty anthem\nparty hip-hop\nparty polka\nparty pop\nparty punk\nparty punk rock\nparty rap\nparty rap chiptune\nparty rock\nparty rock schlager\nparty rock ska\nparty rock, country-rock\nparty rock, eurodance, happy hardcore\nparty rock, melbourne bounce, surf rock\nparty rock, schlager, rock\nparty schlager\nparty trap\nparty-funk\nparty-pop\nparty-pop funk\nparty-pop, Manele, electronic\nparty-punk\nparty-punk chiptune\nparty-rap hardstyle\nparty-rap, hardstyle, gabber\nparty-rock\nparty-rock ska-punk\nparty-schlager\nparty-schlager funk disco\nparty-schlager reggaeton\npartyschlager\npasodoble\npasodoble concert march\npasodoble flamenco\npasodoble orchestral\npasodoble, Spanish folk\npasodoble, Spanish theatrical\npasodoble, flamenco, big band\npastoral\npastoral acoustic\npastoral ambient\npastoral chamber music\npastoral classical\npastoral folk\npastoral instrumental\npastoral orchestral\npatriotic\npatriotic C-pop\npatriotic Chinese anthem\npatriotic Indian\npatriotic Indonesian anthem\npatriotic Spanish\npatriotic ambient\npatriotic anthem\npatriotic ballad\npatriotic bolero\npatriotic electronic\npatriotic folk\npatriotic hymn\npatriotic march\npatriotic orchestral\npatriotic pop\npatriotic pop ballad\npatriotic pop, Azerbaijani folk, Turkish folk\npatriotic pop, electronic dance, hardstyle\npatriotic pop, electronic, Central Asian\npatriotic pop, estrada, operatic pop\npatriotic pop, pop-rock\npatriotic pop-dance\npatriotic pop-folk\npatriotic pop-rock\npatriotic rock\npatriotic synth\npatriotic synth anthem\npedal steel\npedal steel, whimsical, instrumental\npercussion\npercussion ensemble\npercussion fusion\npercussion loop\npercussion rock\npercussion virtuosity\npercussion, Middle Eastern, South Asian\npercussion, house, breakbeat\npercussion, world fusion\npercussion, world fusion, electronic\npercussion, world fusion, rock\npercussion, world music, cinematic\npercussive\npercussive ambient\npercussive avant-garde\npercussive chant\npercussive electronic\npercussive experimental\npercussive explosion\npercussive fingerstyle\npercussive folk\npercussive fusion\npercussive instrumental\npercussive loop\npercussive rock\npercussive sting\npercussive world\nphilosophical electronic\nphilosophical folk\nphilosophical hip-hop\nphilosophical pop\nphleng phuea chiwit\nphonk\nphonk ambient\nphonk ambient trap\nphonk chiptune\nphonk dark pop\nphonk dark trap\nphonk dark trap indie rock\nphonk darkwave\nphonk drill\nphonk emo-rock\nphonk hardcore techno\nphonk hardstyle\nphonk hip-hop\nphonk horrorcore\nphonk hyperpop\nphonk lo-fi\nphonk lo-fi hip hop\nphonk lo-fi hip-hop\nphonk metal\nphonk metalcore\nphonk reggaeton\nphonk trap\nphonk trap anime-core\nphonk trap chiptune\nphonk trap emo-rap\nphonk trap experimental\nphonk trap lo-fi\nphonk trap metal\nphonk trap political satire\nphonk trap, hyperpop\nphonk trap-metal\nphonk vaporwave\nphonk wave\nphonk witch house\nphonk, Russian hip hop\nphonk, Russian rap\nphonk, Russian, trap\nphonk, aggressive electronic\nphonk, ambient\nphonk, ambient trap\nphonk, ambient, cinematic\nphonk, ambient, dark electronic\nphonk, ambient, electronic\nphonk, ambient, emotional trap\nphonk, ambient, traditional Chinese\nphonk, ambient, trap\nphonk, breakcore\nphonk, chip-hop, Russian rap\nphonk, chiptune\nphonk, chiptune, ambient\nphonk, chiptune, cyberpunk\nphonk, chiptune, electronic\nphonk, chiptune, lo-fi\nphonk, chiptune, trap\nphonk, cinematic\nphonk, cinematic folk\nphonk, cinematic horror\nphonk, cinematic synth\nphonk, cinematic trap\nphonk, cinematic, Eastern European\nphonk, cinematic, Middle Eastern\nphonk, cinematic, Russian hip hop\nphonk, cinematic, Russian rap\nphonk, cinematic, ambient\nphonk, cinematic, chiptune\nphonk, cinematic, dark\nphonk, cinematic, dark ambient\nphonk, cinematic, dark synth\nphonk, cinematic, drum and bass\nphonk, cinematic, glitch\nphonk, cinematic, lo-fi\nphonk, cinematic, trap\nphonk, cloud rap\nphonk, cloud rap, ambient\nphonk, cloud rap, hyperpop\nphonk, cloud rap, trap\nphonk, cloud rap, vaporwave\nphonk, cyberpunk, chiptune\nphonk, cyberpunk, trap\nphonk, dark ambient\nphonk, dark ambient, trap\nphonk, dark electronic\nphonk, dark electronic pop\nphonk, dark pop\nphonk, dark trap\nphonk, dark trap, Eastern European horror\nphonk, dark trap, breakcore\nphonk, dark trap, chiptune\nphonk, dark trap, cinematic\nphonk, dark trap, cloud rap\nphonk, dark trap, hardstyle\nphonk, darkwave\nphonk, darkwave, electronic hip-hop\nphonk, darkwave, emo rap\nphonk, darkwave, witch house\nphonk, dream pop\nphonk, drift phonk\nphonk, electronic, cinematic\nphonk, electronic, lo-fi hip hop\nphonk, emotional trap\nphonk, folk, electronic\nphonk, glitch\nphonk, hard dance\nphonk, hard dance, dark electronic\nphonk, hard techno\nphonk, hard trap\nphonk, hardbass\nphonk, hardbass, dance\nphonk, hardstyle\nphonk, hardstyle, Eastern European\nphonk, hardstyle, Middle Eastern fusion\nphonk, hardstyle, Slavic folk\nphonk, hardstyle, ambient\nphonk, hardstyle, chiptune\nphonk, hardstyle, dark electronic\nphonk, hardstyle, gabber\nphonk, hardstyle, lo-fi\nphonk, hardstyle, rap\nphonk, hardstyle, trap\nphonk, hardstyle, vaporwave\nphonk, hardwave\nphonk, horrorcore\nphonk, horrorcore, lo-fi\nphonk, horrorcore, trap\nphonk, hyperpop\nphonk, hyperpop, chiptune\nphonk, hyperpop, cloud rap\nphonk, hyperpop, lo-fi\nphonk, hyperpop, rage\nphonk, hyperpop, trap\nphonk, industrial\nphonk, industrial trap\nphonk, lo-fi hip hop\nphonk, lo-fi hip hop, dark hip-hop\nphonk, lo-fi hip hop, ethereal\nphonk, lo-fi hip hop, vaporwave\nphonk, lo-fi hip-hop\nphonk, lo-fi trap\nphonk, lo-fi, Russian\nphonk, lo-fi, Russian hip hop\nphonk, lo-fi, Russian rap\nphonk, lo-fi, aggressive\nphonk, lo-fi, aggro\nphonk, lo-fi, dark trap\nphonk, lo-fi, emotional pop\nphonk, lo-fi, hardstyle\nphonk, lo-fi, horrorcore\nphonk, lo-fi, hyperpop\nphonk, lo-fi, psychedelic rock\nphonk, lo-fi, trap\nphonk, meme rap, lo-fi chiptune\nphonk, orchestral trap\nphonk, rage music\nphonk, sad trap\nphonk, trap\nphonk, trap metal\nphonk, trap metal, cinematic\nphonk, trap metal, dark electronic\nphonk, trap metal, industrial hip-hop\nphonk, trap metal, lo-fi hip hop\nphonk, trap, Balkan\nphonk, trap, Bollywood\nphonk, trap, Chinese ambient\nphonk, trap, Eastern European\nphonk, trap, Eastern European folk\nphonk, trap, Eastern flavor\nphonk, trap, Eastern-influenced\nphonk, trap, Hindi rap\nphonk, trap, Japanese fusion\nphonk, trap, Middle Eastern\nphonk, trap, Middle Eastern fusion\nphonk, trap, Polish rap\nphonk, trap, Russian\nphonk, trap, Russian hip hop\nphonk, trap, Russian rap\nphonk, trap, South Asian\nphonk, trap, Turkish folk\nphonk, trap, Turkish hip hop\nphonk, trap, aggro\nphonk, trap, ambient\nphonk, trap, baroque\nphonk, trap, boom-bap\nphonk, trap, breakcore\nphonk, trap, chiptune\nphonk, trap, cinematic\nphonk, trap, cyberpunk\nphonk, trap, dark\nphonk, trap, dark ambient\nphonk, trap, dark electronic\nphonk, trap, dark pop\nphonk, trap, dark synth\nphonk, trap, deathcore\nphonk, trap, distorted\nphonk, trap, electronic\nphonk, trap, ethereal\nphonk, trap, ethnic\nphonk, trap, experimental\nphonk, trap, folk\nphonk, trap, hardstyle\nphonk, trap, hyperpop\nphonk, trap, industrial\nphonk, trap, lo-fi\nphonk, trap, lo-fi hip hop\nphonk, trap, meme rap\nphonk, trap, rock\nphonk, trap, world fusion\nphonk, trap-metal\nphonk, vaporwave\nphonk, vaporwave, Russian rap\nphonk, vaporwave, ambient\nphonk, vaporwave, lo-fi hip hop\nphonk, vaporwave, trap\nphonk, witch house\nphonk, witch house, dark electronic\nphonk, witch house, dark trap\nphonk-trap\nphoron rock\npiano\npiano ballad\npiano ballad R&B\npiano ballad alternative rock\npiano ballad ambient\npiano ballad art rock\npiano ballad art-rock\npiano ballad blues\npiano ballad bossa nova\npiano ballad downtempo\npiano ballad flamenco\npiano ballad folk\npiano ballad gospel\npiano ballad hip-hop\npiano ballad hip-hop crossover\npiano ballad indie rock\npiano ballad jazz\npiano ballad jazz swing\npiano ballad jazz-funk\npiano ballad jazz-pop\npiano ballad jazz-rock\npiano ballad lo-fi hip-hop\npiano ballad pop-rock\npiano ballad psychedelic rock\npiano ballad rap-rock\npiano ballad reggaeton\npiano ballad rock\npiano ballad rock anthem\npiano ballad rock opera\npiano ballad salsa\npiano ballad samba\npiano ballad soft rock\npiano ballad soul-rock\npiano ballad tango\npiano ballad trip-hop\npiano ballad, Afro-Brazilian samba\npiano ballad, Eurodance\npiano ballad, Forró\npiano ballad, French chanson, dramatic\npiano ballad, French chanson, theatrical\npiano ballad, J-rock\npiano ballad, Latin cumbia\npiano ballad, Latin folk\npiano ballad, Latin jazz\npiano ballad, Latin pop, pop\npiano ballad, Latin pop-rock\npiano ballad, Latin rock\npiano ballad, Latin salsa\npiano ballad, R&B\npiano ballad, R&B hip-hop\npiano ballad, R&B, Thai pop\npiano ballad, R&B, hip-hop\npiano ballad, R&B, lo-fi hip-hop\npiano ballad, acoustic pop-folk\npiano ballad, alternative rock\npiano ballad, ambient, experimental\npiano ballad, anthemic rock\npiano ballad, arena rock\npiano ballad, arena rock, cinematic\npiano ballad, art rock\npiano ballad, art rock, experimental\npiano ballad, atmospheric rock\npiano ballad, big band jazz\npiano ballad, big band swing\npiano ballad, big band, theatrical pop\npiano ballad, boogie-woogie, rock and roll\npiano ballad, boogie-woogie, stride piano\npiano ballad, boogie-woogie, theatrical\npiano ballad, chanson, cinematic\npiano ballad, cinematic pop, show tune\npiano ballad, cinematic rap, ambient\npiano ballad, cinematic rock\npiano ballad, cinematic rock, Hebrew pop\npiano ballad, cinematic, ambient\npiano ballad, cinematic, emotional\npiano ballad, cinematic, hip-hop/trap\npiano ballad, cinematic, jazz\npiano ballad, cinematic, melancholic\npiano ballad, cinematic, traditional Chinese\npiano ballad, classic rock\npiano ballad, conscious hip-hop\npiano ballad, contemporary R&B\npiano ballad, contemporary R&B, lo-fi hip-hop\npiano ballad, contemporary pop\npiano ballad, downtempo, atmospheric\npiano ballad, downtempo, trip-hop\npiano ballad, dramatic rock, emotional\npiano ballad, electronic pop\npiano ballad, electronic pop, atmospheric\npiano ballad, electronic rock\npiano ballad, electronic rock, cinematic\npiano ballad, emotional anthem\npiano ballad, emotional pop\npiano ballad, emotional pop, rap fusion\npiano ballad, emotional rock\npiano ballad, emotional rock, Italian pop\npiano ballad, emotional rock, cinematic\npiano ballad, emotional rock, melancholic\npiano ballad, epic rock\npiano ballad, epic rock, cinematic\npiano ballad, experimental electronic\npiano ballad, experimental pop\npiano ballad, folk\npiano ballad, forró, baião\npiano ballad, free jazz\npiano ballad, funk R&B\npiano ballad, funk pop-rock\npiano ballad, funk rock\npiano ballad, gospel pop, theatrical rock\npiano ballad, gospel rock\npiano ballad, gospel rock, soulful\npiano ballad, gospel soul\npiano ballad, gospel, inspirational\npiano ballad, gospel, soul\npiano ballad, gospel-pop\npiano ballad, hard rock\npiano ballad, hip-hop\npiano ballad, hip-hop crossover\npiano ballad, hip-hop, emotional\npiano ballad, industrial rock\npiano ballad, inspirational rock\npiano ballad, klezmer, choral\npiano ballad, lo-fi indie pop\npiano ballad, mambo, salsa\npiano ballad, melancholic rock\npiano ballad, melancholic, traditional Chinese\npiano ballad, modern R&B\npiano ballad, musical theater\npiano ballad, musical theater, classical crossover\npiano ballad, operatic pop\npiano ballad, operatic pop, 80s style\npiano ballad, orchestral rock\npiano ballad, orchestral rock, cinematic\npiano ballad, orchestral rock, power ballad\npiano ballad, pop\npiano ballad, pop R&B\npiano ballad, pop-punk\npiano ballad, pop-punk, emo-rock\npiano ballad, pop-rap\npiano ballad, pop-rock\npiano ballad, pop-rock, French Creole\npiano ballad, pop-rock, anthem\npiano ballad, pop-rock, cinematic\npiano ballad, pop-rock, emotional\npiano ballad, pop-rock, melancholic\npiano ballad, pop-rock, theatrical\npiano ballad, post-rock\npiano ballad, power rock\npiano ballad, power rock, cinematic\npiano ballad, psychedelic rock\npiano ballad, rap, melancholic\npiano ballad, rap-rock\npiano ballad, reggaeton pop\npiano ballad, rock anthem\npiano ballad, rock anthem, chanson\npiano ballad, rock anthem, cinematic\npiano ballad, rock anthem, emotional\npiano ballad, rock ballad\npiano ballad, rock opera\npiano ballad, rock opera, C-pop\npiano ballad, rock opera, cinematic\npiano ballad, rock opera, dramatic\npiano ballad, rock opera, emotional\npiano ballad, rock, bilingual\npiano ballad, rock, cinematic\npiano ballad, rock, duet\npiano ballad, rock, emotional\npiano ballad, rock, shoegaze\npiano ballad, salsa\npiano ballad, samba, live performance\npiano ballad, samba-rock\npiano ballad, soft rock\npiano ballad, soft rock, atmospheric\npiano ballad, soulful R&B\npiano ballad, swing jazz\npiano ballad, symphonic metal\npiano ballad, synth-pop\npiano ballad, synth-pop, R&B\npiano ballad, tango\npiano ballad, tango, cinematic\npiano ballad, theatrical pop\npiano ballad, theatrical pop, cinematic jazz\npiano ballad, theatrical pop, emotional rock\npiano ballad, theatrical pop, rock\npiano ballad, theatrical rock\npiano ballad, theatrical rock, Italian pop\npiano ballad, theatrical rock, cinematic\npiano ballad, theatrical rock, cinematic pop\npiano ballad, theatrical, duet\npiano ballad, theatrical, jazz\npiano ballad, trap, emotional anthem\npiano bar\npiano bar ballad, gospel rock\npiano blues\npiano drama\npiano duet\npiano etude\npiano fantasy\npiano flourish\npiano fusion\npiano house\npiano instrumental\npiano instrumental, ragtime, boogie-woogie\npiano jazz\npiano jazz fusion\npiano loop\npiano pop\npiano pop R&B\npiano pop-rock\npiano ragtime\npiano rock\npiano rock alternative\npiano rock ballad\npiano rock baroque pop\npiano rock blues\npiano rock blues-rock\npiano rock boogie-woogie\npiano rock cabaret\npiano rock emo\npiano rock folk-rock\npiano rock funk soul\npiano rock fusion\npiano rock garage rock\npiano rock glam rock\npiano rock gospel\npiano rock heartland rock\npiano rock indie rock\npiano rock power-pop\npiano rock progressive rock\npiano rock, hard rock, Hungarian rock\npiano solo\npiano solo, pop-rock\npiano solo, ragtime\npiano solo, ragtime, avant-garde\npiano solo, ragtime, cinematic\npiano sting\npiano trap\npiano virtuosity\npiano virtuoso\npiano virtuoso holiday\npiano vocal\npiano, quirky, ragtime\npiano, quirky, video game\npiano, ragtime\npiano, ragtime, modern classical\npiano, ragtime, whimsical\npiano, vocal, Christmas\npiano-driven\npiano-driven pop-rock\npiano-driven rock\npiano-driven singer-songwriter\npiano-led pop-rock\npiano-pop\npimba\npimba brega\npimba forró\npimba pop\npimba saudade\npimba sertanejo\npimba sertanejo romântico\npimba, ballad\npimba, ballad, Latin pop\npimba, chiptune, Portuguese pop\npimba, fiesta, Portuguese pop\npimba, forró\npimba, synthwave, 80s pop\npimba-pop\npingtan\npirate anthem ska-punk\npirate cumbia\npirate folk\npirate folk hip-hop\npirate folk rock\npirate folk-rock\npirate hip-hop\npirate metal\npirate metal chiptune\npirate metal folk metal\npirate metal folk punk\npirate metal folk rock\npirate metal nintendocore\npirate metal power metal\npirate metal punk rock\npirate metal sea shanty\npirate metal, Nintendocore\npirate metal, chiptune power metal\npirate metal, happy hardcore\npirate metal, nintendocore\npirate metal, power metal, chiptune\npirate metal, sea shanty punk\npirate metal, sea shanty rock\npirate metal, symphonic power metal\npirate polka\npirate punk\npirate punk folk punk\npirate punk rock\npirate rap-rock\npirate rock\npirate rock opera\npirate rock surf rock\npirate shanty polka\npirate shanty, polka, klezmer\npirate ska\npirate trap\npirate-pop\npirate-punk\npirate-punk rock\npirate-schlager\npirate-ska\npiseiro\npiseiro arrocha\npiseiro brega\npiseiro brega funk\npiseiro carimbó\npiseiro chiptune\npiseiro eletrônico\npiseiro forró\npiseiro funk carioca\npiseiro rock\npiseiro sertanejo\npiseiro, electronic dance\npiseiro, forró, electronic\npiseiro, forró, lo-fi\nplastic cumbia\nplayful\nplayful Christmas\nplayful Halloween\nplayful Halloween synth\nplayful acapella\nplayful ambient\nplayful big band\nplayful brass\nplayful chamber music\nplayful cinematic\nplayful circus\nplayful classical\nplayful collage\nplayful electronic\nplayful experimental\nplayful folk\nplayful hip-hop\nplayful instrumental\nplayful jazz\nplayful jingle\nplayful nursery rhyme\nplayful orchestral\nplayful piano\nplayful polka\nplayful pop\nplayful string\nplayful synth\nplayful ukulele\nplayful waltz\nplayful woodwind\nplayful world music\nplayful, bright, instrumental\nplayful, circus, staccato\nplena\npleng phuea chiwit\npluggnb\npluggnb chiptune\npluggnb chiptune trap\npluggnb cloud rap\npluggnb emo rap\npluggnb emo-trap\npluggnb hyper-trap\npluggnb hyperpop\npluggnb lo-fi\npluggnb rage\npluggnb ragenb trap\npluggnb trap\npluggnb, Brazilian trap\npluggnb, Brazilian trap, chiptune\npluggnb, Latin trap\npluggnb, Latin trap, chiptune\npluggnb, chiptune\npluggnb, chiptune, cloud rap\npluggnb, chiptune, hyperpop\npluggnb, chiptune, trap\npluggnb, cloud rap\npluggnb, cloud rap, chiptune\npluggnb, cloud rap, chopped and screwed\npluggnb, cloud rap, emo rap\npluggnb, cloud rap, emo trap\npluggnb, cloud rap, emotional trap\npluggnb, cloud rap, future bass\npluggnb, cloud rap, hyperpop\npluggnb, cloud rap, lo-fi\npluggnb, cloud rap, lo-fi hip hop\npluggnb, cloud rap, trap\npluggnb, cloud rap, vaporwave\npluggnb, emo rap\npluggnb, emo rap, cloud rap\npluggnb, emo trap\npluggnb, hyper-trap\npluggnb, hyperpop\npluggnb, hyperpop, ambient\npluggnb, hyperpop, ambient trap\npluggnb, hyperpop, cloud rap\npluggnb, hyperpop, digicore\npluggnb, hyperpop, rage\npluggnb, hyperpop, trap\npluggnb, lo-fi hip hop\npluggnb, melodic trap\npluggnb, melodic trap, chiptune\npluggnb, rage\npluggnb, rage music\npluggnb, rage music, chiptune\npluggnb, rage trap\npluggnb, rage trap, chiptune\npluggnb, rage, trap\npluggnb, trap\npluggnb, trap, Brazilian\npluggnb, trap, chiptune\npluggnb, trap, synthwave\npluggnb, vaporwave, Brazilian trap\nplunderphonics\npoetry music\npoetry song\npoezja śpiewana\npolitical anthem\npolitical dubstep\npolitical electronic\npolitical folk\npolitical hip hop\npolitical hip-hop\npolitical hip-hop breakbeat hardcore\npolitical hip-hop industrial\npolitical hip-hop nu-metal\npolitical hip-hop trap\npolitical hip-hop, EDM, future bass\npolitical hip-hop, cinematic rock, aggressive electronic\npolitical hip-hop, electronic rock, hardstyle\npolitical hip-hop, pop-rock, atmospheric\npolitical hip-hop, trap, Middle Eastern\npolitical house\npolitical opera\npolitical pop\npolitical protest\npolitical punk\npolitical punk rock\npolitical rap\npolitical rap, breakbeat, ambient\npolitical rock\npolitical rock punk\npolitical satire\npolitical show tune\npolitical techno\npolitical trance\npolitical trap\npolka\npolka Christmas\npolka baião\npolka big band\npolka brass band\npolka cabaret\npolka children's\npolka children's music\npolka chiptune\npolka chiptune novelty\npolka chiptune rock\npolka circus\npolka comedy\npolka comedy rock\npolka country\npolka country novelty\npolka country swing\npolka country-folk\npolka cumbia\npolka dance\npolka dubstep\npolka folk\npolka folk dance\npolka folk march\npolka fusion\npolka gospel\npolka hardcore\npolka hip-hop\npolka humppa\npolka klezmer\npolka klezmer children's\npolka klezmer circus\npolka klezmer novelty\npolka klezmer turbo-folk\npolka march\npolka mariachi\npolka metal\npolka metal cabaret\npolka metal chiptune\npolka metal power metal\npolka metal punk\npolka metal speed metal\npolka metal, extreme metal\npolka metal, theatrical heavy metal\npolka metal, theatrical rock\npolka music hall\npolka norteño\npolka novelty\npolka opera\npolka punk\npolka punk metal\npolka punk surf rock\npolka ranchera\npolka rap-rock\npolka rock\npolka rock folk metal\npolka rock mariachi\npolka rock ska-punk\npolka rock surf rock\npolka rock turbo-folk\npolka rock, surf rock, rockabilly\npolka rockabilly\npolka rockabilly boogie-woogie\npolka rockabilly chiptune\npolka rockabilly country\npolka rockabilly mariachi\npolka rockabilly novelty\npolka schlager\npolka sea shanty\npolka show tune\npolka ska\npolka ska big band\npolka ska cabaret\npolka ska chiptune\npolka ska folk\npolka ska novelty\npolka ska punk\npolka ska rock\npolka ska rockabilly\npolka ska surf rock\npolka ska-punk chiptune\npolka surf rock\npolka surf rock chiptune\npolka surf rock klezmer\npolka swing\npolka synth-pop\npolka trot\npolka turbo-folk\npolka waltz\npolka, Balkan folk, novelty\npolka, German carnival, folk pop\npolka, Neue Deutsche Welle, chiptune\npolka, Norteño, regional Mexican\npolka, Schlager, children's music\npolka, Schlager, novelty\npolka, balkan brass, klezmer\npolka, balkan folk\npolka, balkan, folk\npolka, big band, accordion\npolka, big band, novelty\npolka, brass band, comedic\npolka, cabaret, musical theater\npolka, cabaret, theatrical\npolka, carnival, festive\npolka, cartoon, children's music\npolka, children's music, German folk\npolka, children's music, theatrical\npolka, cinematic, festive\npolka, circus, Greek folk\npolka, circus, ragtime\npolka, country dance\npolka, country-western, novelty\npolka, cumbia, cinematic\npolka, disco-funk, cinematic orchestral, synth-pop\npolka, electronic, folk\npolka, festive, accordion\npolka, folk, Italian\npolka, folk, brass\npolka, folk, cinematic\npolka, folk, circus music\npolka, folk, electronic\npolka, folk, klezmer\npolka, folk, video game music\npolka, happy hardcore, video game music\npolka, klezmer, chiptune\npolka, klezmer, cinematic\npolka, klezmer, folk\npolka, klezmer, novelty\npolka, klezmer, surf rock\npolka, march, German folk\npolka, narrative folk\npolka, novelty, Christmas\npolka, novelty, Dutch\npolka, novelty, French\npolka, novelty, folk\npolka, novelty, levenslied\npolka, satirical march, Eastern European\npolka, schlager, German Christmas\npolka, schlager, electronic dance\npolka, schlager, novelty\npolka, schlager, volksmusik\npolka, sea shanty\npolka, sea shanty, German folk\npolka, sea shanty, novelty\npolka, synth pop, video game music\npolka, tarantella, theatrical folk\npolka, theatrical, cabaret\npolka, theatrical, folk\npolka, theatrical, klezmer\npolka, theatrical, live\npolka, theatrical, quirky\npolka, video game, circus\npolka-country\npolka-country novelty\npolka-cumbia\npolka-folk\npolka-funk\npolka-march\npolka-metal\npolka-pop\npolka-pop cabaret\npolka-pop chiptune\npolka-pop dance\npolka-pop novelty\npolka-punk\npolka-punk Balkan folk\npolka-punk carnival rock\npolka-punk chiptune\npolka-punk chiptune synth-pop\npolka-punk comedy rock\npolka-punk country rock\npolka-punk folk metal\npolka-punk folk rock\npolka-punk folk-punk\npolka-punk folk-rock\npolka-punk garage rock\npolka-punk gypsy punk\npolka-punk hard rock\npolka-punk horror rock\npolka-punk metal\npolka-punk pirate metal\npolka-punk pirate rock\npolka-punk power metal\npolka-punk pub rock\npolka-punk rock\npolka-punk rockabilly\npolka-punk sea shanty\npolka-punk ska\npolka-punk ska-punk\npolka-punk ska-rock\npolka-punk speed metal\npolka-punk surf rock\npolka-punk surf-rock\npolka-punk theatrical rock\npolka-punk turbo-folk\npolka-punk, Balkan folk\npolka-punk, Balkan folk, electronic\npolka-punk, Balkan folk, rock\npolka-punk, Russian folk, surf-rock\npolka-punk, hard rock, mashup\npolka-punk, heavy metal\npolka-punk, sci-fi comedy rock\npolka-punk, theatrical chanson\npolka-punk, theatrical rock\npolka-punk, theatrical rock, ska\npolka-rap\npolka-reggae\npolka-rock\npolka-rock Balkan folk\npolka-rock alternative rock\npolka-rock balkan beat\npolka-rock balkan folk\npolka-rock big band\npolka-rock chiptune\npolka-rock country\npolka-rock cumbia\npolka-rock festival folk\npolka-rock festive folk\npolka-rock folk metal\npolka-rock folk-punk\npolka-rock hard rock\npolka-rock heartland rock\npolka-rock indie pop\npolka-rock jump blues\npolka-rock klezmer\npolka-rock metal\npolka-rock norteño\npolka-rock novelty\npolka-rock punk\npolka-rock schlager\npolka-rock ska-punk\npolka-rock southern rock\npolka-rock surf-punk\npolka-rock surf-rock punk\npolka-rock surf-ska\npolka-rock theatrical folk\npolka-rock turbo-folk\npolka-rock, Balkan folk\npolka-rock, Russian folk\npolka-rock, world music, C-pop\npolka-schlager\npolka-ska\npolka-ska German schlager\npolka-ska funk-rock\npolka-ska, musical theater, rap\npolka-ska, surf rock, doo-wop\npolka-swing\npolka-tango\npolyrhythmic percussion\npop\npop Christmas\npop EDM\npop EDM future bass\npop EDM trap\npop J-pop\npop Jawa\npop Latin\npop Melayu\npop Melayu, cinematic orchestral, Indonesian pop\npop Melayu, dangdut\npop Melayu, dangdut koplo\npop Melayu, dangdut koplo, modern pop\npop Melayu, dangdut, modern pop\npop Melayu, dangdut, pop-rock\npop Melayu, hard rock\npop R&B\npop R&B Afrobeats\npop R&B Bollywood\npop R&B Brazilian pop\npop R&B Christmas\npop R&B Indian pop\npop R&B J-pop\npop R&B Kizomba\npop R&B Latin\npop R&B Latin pop\npop R&B OPM\npop R&B South Asian\npop R&B South Asian fusion\npop R&B atmospheric rock\npop R&B ballad\npop R&B chiptune\npop R&B cinematic\npop R&B dancehall\npop R&B dream pop\npop R&B dubstep\npop R&B electronic\npop R&B funk\npop R&B future bass\npop R&B gospel\npop R&B hip-hop\npop R&B indie guitar\npop R&B indie rock\npop R&B lo-fi\npop R&B lo-fi hip-hop\npop R&B lounge\npop R&B musical theater\npop R&B piano ballad\npop R&B reggae\npop R&B reggaeton\npop R&B rock\npop R&B show tune\npop R&B smooth jazz\npop R&B soul\npop R&B trap\npop R&B tropical house\npop R&B world music\npop R&B, EDM, gospel\npop R&B, Eurodance, late 90s pop\npop R&B, J-pop\npop R&B, J-pop, Latin pop, hip-hop, EDM\npop R&B, K-pop\npop R&B, South Asian pop, hip-hop\npop R&B, early 2000s hip-hop\npop R&B, electronic dance, South Indian\npop R&B, hip-hop\npop R&B, indie rock\npop R&B, synth-pop, melancholic R&B\npop R&B, world fusion\npop Sunda\npop a cappella\npop afrobeat\npop anime soundtrack\npop anthem\npop ballad\npop ballad Indian influence\npop ballad Latin\npop ballad R&B\npop ballad R&B future bass\npop ballad anime soundtrack\npop ballad bossa nova\npop ballad chiptune\npop ballad classical\npop ballad classical crossover\npop ballad dancehall\npop ballad doo-wop\npop ballad fado\npop ballad flamenco\npop ballad folk\npop ballad future bass\npop ballad gospel\npop ballad hip-hop\npop ballad hip-hop rock\npop ballad jazz\npop ballad jazz Latin\npop ballad jazz world music\npop ballad latin pop\npop ballad lo-fi hip-hop\npop ballad lounge orchestral\npop ballad progressive house\npop ballad smooth jazz\npop ballad tango\npop ballad tango balkan\npop ballad trap\npop ballad trap-pop\npop ballad world music\npop ballad, 1960s pop, barbershop\npop ballad, 80s pop, cinematic\npop ballad, 90s Italian, cinematic\npop ballad, 90s R&B\npop ballad, Afrobeats, R&B\npop ballad, Axé\npop ballad, Azerbaijani estrada\npop ballad, Azerbaijani estrada, cinematic pop\npop ballad, Azerbaijani folk\npop ballad, Azerbaijani folk, Turkish folk\npop ballad, Azerbaijani, Turkish\npop ballad, Balkan folk\npop ballad, Balkan folk, melancholic\npop ballad, Balkan pop\npop ballad, Balkan, Eastern European\npop ballad, Balkan, Manele\npop ballad, Balkan, cinematic\npop ballad, Balkan, tango\npop ballad, Balkan, world music\npop ballad, Bollywood\npop ballad, Brazilian Funk\npop ballad, Brazilian dance\npop ballad, Brazilian romantic, pop-rock\npop ballad, Brazilian, celebratory\npop ballad, Central Asian\npop ballad, Central Asian folk\npop ballad, Central Asian folk, cinematic\npop ballad, Central Asian, Latin\npop ballad, Central Asian, Middle Eastern\npop ballad, Central Asian, Turkish\npop ballad, Central Asian, atmospheric\npop ballad, Central Asian, cinematic\npop ballad, Central Asian, electronic\npop ballad, Central Asian, heartfelt\npop ballad, Central Asian, modern\npop ballad, Christian pop, EDM\npop ballad, Christmas, anime\npop ballad, Christmas, orchestral\npop ballad, Christmas, romantic\npop ballad, Dangdut Koplo\npop ballad, Dangdut Koplo, Funkot\npop ballad, EDM\npop ballad, EDM, Afrikaans pop\npop ballad, EDM, bilingual\npop ballad, EDM, cinematic\npop ballad, EDM, dance-pop\npop ballad, EDM, future bass\npop ballad, EDM, hip-hop\npop ballad, EDM, trance\npop ballad, EDM, trap\npop ballad, EDM-pop\npop ballad, EDM-pop, cinematic\npop ballad, EDM-pop, future bass\npop ballad, East Asian pop\npop ballad, East Asian, anime\npop ballad, Eastern European folk\npop ballad, Eastern European folk, accordion\npop ballad, Eastern European folk, cinematic\npop ballad, Eastern European folk, cinematic pop\npop ballad, Eastern European pop, Russian pop\npop ballad, Eastern European, Turkish\npop ballad, Eastern European, dramatic\npop ballad, Eurodance, cinematic\npop ballad, European chanson\npop ballad, European folk, Mandarin pop\npop ballad, European waltz\npop ballad, European, cinematic\npop ballad, Europop, 80s pop\npop ballad, Forró Eletrônico\npop ballad, German hip-hop, chopped and screwed\npop ballad, Greek Laïko, classical\npop ballad, Indian pop, bilingual\npop ballad, Islamic music, world music\npop ballad, J-pop\npop ballad, J-pop, pop-rock\npop ballad, J-rock\npop ballad, Javanese pop, pop-rock\npop ballad, Javanese rock\npop ballad, Javanese, melancholic\npop ballad, K-pop\npop ballad, Latin pop\npop ballad, Malay pop, Indonesian pop\npop ballad, Malay traditional\npop ballad, Mediterranean, cinematic\npop ballad, Middle Eastern pop\npop ballad, Middle Eastern pop, cinematic pop\npop ballad, Middle Eastern, Balkan\npop ballad, Middle Eastern, Kurdish\npop ballad, Middle Eastern, Persian\npop ballad, Middle Eastern, Turkish\npop ballad, Middle Eastern, cinematic\npop ballad, Middle Eastern, dramatic\npop ballad, Middle Eastern, emotional\npop ballad, R&B\npop ballad, R&B, Hindi pop\npop ballad, R&B, Indian pop\npop ballad, R&B, K-pop\npop ballad, R&B, South Asian\npop ballad, R&B, Thai pop\npop ballad, R&B, ambient\npop ballad, R&B, cinematic\npop ballad, R&B, electronic\npop ballad, R&B, emotional\npop ballad, R&B, gospel\npop ballad, R&B, trap\npop ballad, Romanian folk\npop ballad, Romanian folk, cinematic\npop ballad, Russian estrada\npop ballad, Russian estrada, 90s pop\npop ballad, South Asian folk\npop ballad, South Asian fusion\npop ballad, South Asian pop\npop ballad, South Asian pop, cinematic pop\npop ballad, South Asian, electronic\npop ballad, South Asian, melodic\npop ballad, South Asian, romantic\npop ballad, Southeast Asian\npop ballad, Southeast Asian folk\npop ballad, Southeast Asian fusion\npop ballad, Southeast Asian pop\npop ballad, Southeast Asian pop, cinematic\npop ballad, Southeast Asian, Khmer\npop ballad, Southeast Asian, cinematic\npop ballad, Spanish influence\npop ballad, Turkish folk, Eastern European folk\npop ballad, Turkish influence\npop ballad, Turkish pop, Mediterranean\npop ballad, Turkish pop, Middle Eastern\npop ballad, Turkish, Eastern European\npop ballad, Turkish, Middle Eastern\npop ballad, Vietnamese bolero, traditional Asian\npop ballad, Vietnamese, cinematic\npop ballad, anthemic pop, modern rap\npop ballad, anthemic pop-rock\npop ballad, anthemic pop-rock, atmospheric\npop ballad, atmospheric pop, bilingual pop\npop ballad, big band, Latin\npop ballad, big band, soul\npop ballad, big room house, EDM\npop ballad, chanson\npop ballad, chanson, levenslied\npop ballad, chanson, schlager\npop ballad, chiptune\npop ballad, chiptune, video game music\npop ballad, chiptune, video game soundtrack\npop ballad, cinematic pop\npop ballad, cinematic pop, C-pop\npop ballad, cinematic pop, Central Asian folk\npop ballad, cinematic pop, Chinese pop\npop ballad, cinematic pop, Eastern European\npop ballad, cinematic pop, Hindi pop\npop ballad, cinematic pop, J-rock\npop ballad, cinematic pop, Southeast Asian pop\npop ballad, cinematic pop, Turkish folk\npop ballad, cinematic pop, dance-pop\npop ballad, cinematic rock\npop ballad, cinematic rock, C-pop\npop ballad, cinematic rock, Chinese fusion\npop ballad, cinematic rock, folk rock\npop ballad, cinematic, Anatolian\npop ballad, cinematic, Asian pop\npop ballad, cinematic, C-pop\npop ballad, cinematic, Central Asian\npop ballad, cinematic, J-rock\npop ballad, cinematic, Middle Eastern\npop ballad, cinematic, R&B\npop ballad, cinematic, Southeast Asian\npop ballad, cinematic, anime soundtrack\npop ballad, cinematic, anime theme\npop ballad, cinematic, anime-inspired\npop ballad, cinematic, anthemic\npop ballad, cinematic, festive\npop ballad, cinematic, hip-hop\npop ballad, cinematic, orchestral\npop ballad, cinematic, power ballad\npop ballad, cinematic, romantic\npop ballad, cinematic, world music\npop ballad, city pop, J-pop\npop ballad, conscious hip-hop\npop ballad, contemporary R&B\npop ballad, dance-pop\npop ballad, dance-pop, EDM\npop ballad, dance-pop, folk\npop ballad, dancehall\npop ballad, dancehall, electronic\npop ballad, dangdut\npop ballad, dangdut koplo\npop ballad, dangdut koplo, Javanese pop\npop ballad, dangdut, Javanese\npop ballad, doo-wop\npop ballad, dubstep, drum and bass\npop ballad, dubstep, electronic\npop ballad, early 2000s Asian pop\npop ballad, early 2000s R&B\npop ballad, early 2000s Russian estrada\npop ballad, early 2000s Russian pop\npop ballad, electronic\npop ballad, electronic rock, cinematic\npop ballad, electronic, South Asian\npop ballad, electronic, bilingual\npop ballad, electronic, folk\npop ballad, electronic, rap\npop ballad, electronic, traditional Azerbaijani\npop ballad, estrada, 80s synth\npop ballad, estrada, 90s synth\npop ballad, estrada, Eastern European\npop ballad, estrada, cinematic\npop ballad, estrada, folk\npop ballad, estrada, melancholic\npop ballad, estrada, sentimental\npop ballad, estrada, synth pop\npop ballad, estrada, synth-pop\npop ballad, estrada, synthpop\npop ballad, estrada, synthwave\npop ballad, estrada, tango\npop ballad, eurodance\npop ballad, flamenco pop\npop ballad, flamenco pop, R&B\npop ballad, flamenco, Mediterranean\npop ballad, folk fusion\npop ballad, folk pop, cinematic\npop ballad, folk pop, hip-hop\npop ballad, folk, cinematic\npop ballad, folk-tango, cinematic\npop ballad, forró, baião\npop ballad, forró, piseiro\npop ballad, funk pop, C-pop\npop ballad, funk pop, Christmas\npop ballad, funk pop, rap\npop ballad, funk rock\npop ballad, future bass\npop ballad, future bass, EDM\npop ballad, future bass, EDM-pop\npop ballad, future bass, R&B\npop ballad, future bass, cinematic\npop ballad, future bass, electronic\npop ballad, future bass, emotional EDM\npop ballad, future bass, pop-rock\npop ballad, future bass, trap\npop ballad, game show, pop-rap\npop ballad, ghazal, cinematic\npop ballad, gospel, cinematic\npop ballad, hard rock\npop ballad, hardstyle\npop ballad, hardstyle, big room house\npop ballad, hardstyle, trap\npop ballad, hip hop, emotional\npop ballad, hip-hop\npop ballad, hip-hop anthem\npop ballad, hip-hop, C-pop\npop ballad, hip-hop, EDM\npop ballad, hip-hop, R&B\npop ballad, hip-hop, ambient\npop ballad, hip-hop, bilingual\npop ballad, hip-hop, choral\npop ballad, hip-hop, cinematic\npop ballad, hip-hop, emotional\npop ballad, hip-hop, flamenco fusion\npop ballad, hip-hop, future bass\npop ballad, hip-hop, pop-rock\npop ballad, hip-hop, rock\npop ballad, hip-hop, sentimental\npop ballad, jazz fusion, city pop\npop ballad, jazz, big band\npop ballad, late-90s R&B\npop ballad, lo-fi hip hop, R&B\npop ballad, lo-fi hip hop, cinematic\npop ballad, manele, cinematic\npop ballad, melodic rap, cinematic pop\npop ballad, modern R&B\npop ballad, modern R&B, trap\npop ballad, modern pop\npop ballad, modern pop-rap\npop ballad, modern trap, cinematic\npop ballad, musical theater\npop ballad, new age, anime soundtrack\npop ballad, new-age\npop ballad, nostalgic, romantic\npop ballad, nu-disco\npop ballad, nu-disco, funk\npop ballad, nu-metal, cinematic\npop ballad, nu-metal, duet\npop ballad, orchestral rock\npop ballad, pop-punk\npop ballad, pop-rap\npop ballad, pop-rock\npop ballad, pop-rock, C-pop\npop ballad, pop-rock, Cantopop\npop ballad, pop-rock, J-rock\npop ballad, pop-rock, K-pop\npop ballad, pop-rock, Mandarin rap\npop ballad, pop-rock, atmospheric\npop ballad, pop-rock, bilingual\npop ballad, pop-rock, cinematic\npop ballad, pop-rock, dance-pop\npop ballad, pop-rock, dangdut koplo\npop ballad, pop-rock, hip-hop\npop ballad, pop-rock, hip-hop crossover\npop ballad, pop-rock, live concert\npop ballad, pop-rock, pop-dangdut\npop ballad, pop-rock, power ballad\npop ballad, pop-rock, psychedelic rock\npop ballad, pop-rock, salsa\npop ballad, power ballad, pop-rock\npop ballad, power ballad, rock\npop ballad, power-pop, cinematic\npop ballad, progressive house\npop ballad, progressive house, EDM\npop ballad, progressive house, big room\npop ballad, rap, pop-rock\npop ballad, reggaeton\npop ballad, retro Southeast Asian, 80s synth\npop ballad, retro, trot\npop ballad, rock and roll, country-pop\npop ballad, rock anthem\npop ballad, rock, R&B\npop ballad, sertanejo\npop ballad, smooth jazz\npop ballad, smooth jazz, Central Asian\npop ballad, smooth jazz, Eastern European folk\npop ballad, smooth jazz, Mongolian folk\npop ballad, smooth jazz, adult contemporary\npop ballad, synth-pop, cinematic\npop ballad, tango rock, cinematic pop\npop ballad, tango, Eastern European\npop ballad, theatrical pop, 70s pop-rock\npop ballad, theatrical pop, cinematic\npop ballad, theatrical pop, live concert\npop ballad, theatrical pop, pop-rock\npop ballad, theatrical rock\npop ballad, traditional Indonesian, cinematic\npop ballad, traditional Malay\npop ballad, traditional Malay, cinematic\npop ballad, traditional Vietnamese, cinematic\npop ballad, trap\npop ballad, trap, EDM\npop ballad, trap, Middle Eastern\npop ballad, trap, R&B\npop ballad, trap, ambient\npop ballad, trap, cinematic\npop ballad, trap, emotional\npop ballad, trap, modern pop\npop ballad, trap-R&B\npop ballad, trap-pop\npop ballad, waltz, estrada\npop ballad, world music\npop ballad, world music, Anatolian pop\npop ballad, world music, Azerbaijani\npop ballad, world music, Central Asian\npop ballad, world music, Mizrahi\npop ballad, world music, ambient\npop ballad, world music, cinematic\npop ballroom waltz\npop bhangra\npop bossa nova\npop brega\npop cabaret\npop chanson\npop chillwave\npop chiptune\npop chiptune R&B\npop chiptune dangdut\npop chiptune dangdut koplo\npop chiptune world music\npop classical\npop country reggae\npop crooner\npop cumbia\npop dance\npop dancehall\npop dancehall Arabic\npop dancehall Arabic fusion\npop dancehall electronic\npop dancehall world music\npop dancehall worldbeat\npop dangdut\npop dangdut koplo\npop duet\npop edm\npop electronic\npop electronic hip-hop\npop flamenco\npop folk\npop folk big band\npop folk fusion\npop folk-dance\npop funk\npop funk R&B\npop funk disco\npop funk hip-hop\npop funk rock\npop funk soul\npop funk, R&B, synth-pop\npop funk, South Indian fusion\npop fusion\npop future bass\npop gospel\npop gospel afrobeat\npop gospel r&b\npop hardstyle\npop hip hop\npop hip-hop\npop hip-hop Bollywood\npop hip-hop EDM\npop hip-hop Islamic devotional\npop hip-hop R&B\npop hip-hop Rai\npop hip-hop celtic folk\npop hip-hop choral\npop hip-hop dancehall\npop hip-hop electro-funk\npop hip-hop electronic\npop hip-hop fusion\npop hip-hop hardstyle\npop hip-hop rock\npop hip-hop tango\npop hip-hop trap\npop hip-hop world music\npop house\npop jazz\npop jazz world music\npop jazzy\npop jingle\npop keroncong\npop keroncong, city pop, Indonesian pop\npop kizomba\npop lounge\npop lullaby\npop mashup, Arabic pop, Latin pop, hip-hop\npop mashup, trap, R&B\npop medley\npop medley, synth-funk, dance-pop, rock\npop melayu\npop metal\npop metalcore\npop musical\npop musical theater\npop musical theatre\npop nasheed\npop neo-soul\npop piano\npop pop\npop power ballad\npop power ballad, folk-pop\npop punk\npop ragtime\npop rap\npop reggae\npop reggae dancehall\npop reggae ska\npop reggae-ska\npop reggaeton\npop reggaeton dancehall\npop rock\npop rock ballad\npop rock electronic\npop rock funk\npop rock hip-hop\npop rock soul\npop rock, Central Asian folk\npop rock, EDM, C-pop\npop rock, J-rock, cinematic pop\npop rock, Javanese pop, cinematic pop\npop rock, Latin pop, Eurodance\npop rock, MPB\npop rock, Pop Melayu, modern Dangdut\npop rock, ballad, lo-fi, acoustic\npop rock, big band, upbeat\npop rock, cinematic, hip-hop\npop rock, cinematic, lo-fi\npop rock, dance-pop, C-pop\npop rock, dance-pop, lo-fi\npop rock, dangdut koplo, cinematic\npop rock, dangdut rock\npop rock, disco, metal\npop rock, doo-wop, 1960s\npop rock, doo-wop, vintage\npop rock, exotica, doo-wop\npop rock, funk-pop, soul\npop rock, hip-hop, dubstep\npop rock, hip-hop, emotional pop\npop rock, modern dangdut\npop rock, orchestral, hip-hop\npop rock, piano ballad\npop romântico\npop schlager\npop sertanejo\npop smooth jazz world music\npop soul\npop soul funk\npop soul funk-rock\npop soul piano\npop standard\npop sunda\npop sunda chiptune\npop sundan\npop swing\npop tango\npop tango folk\npop theater\npop theatre\npop trap\npop trap R&B\npop trap ambient\npop trap electronic\npop trap hip-hop\npop trot\npop ukulele\npop waltz\npop waltz, Russian estrada, 80s synth\npop world music\npop world music children's music\npop worship\npop zouk gospel\npop, 1960s British Invasion\npop, 80s South Indian film music\npop, 80s Southeast Asian\npop, 80s pop, 90s pop\npop, 80s pop, Central Asian pop\npop, 80s pop, Southeast Asian pop\npop, 80s pop, dangdut\npop, 80s pop, regional pop\npop, 80s pop, worship\npop, 80s synth, accordion\npop, 80s, kizomba\npop, 90s R&B\npop, 90s anime\npop, 90s filmi\npop, 90s video game\npop, Afro-Latin\npop, Afro-pop\npop, Afrobeats, Middle Eastern\npop, Anatolian folk\npop, Arabic fusion\npop, Arabic pop, Afrobeat\npop, Arabic, spiritual\npop, Asian pop, lo-fi\npop, Axé, Forró\npop, Azerbaijani folk\npop, Azerbaijani folk, Turkish folk\npop, Azerbaijani folk, cinematic\npop, Azerbaijani folk, dance\npop, Azerbaijani folk, electronic\npop, Azerbaijani folk, rock\npop, Azerbaijani pop, Turkish pop\npop, Azerbaijani, Turkish\npop, Azerbaijani, electronic\npop, Balkan folk\npop, Balkan folk, Middle Eastern fusion\npop, Balkan folk, electronic\npop, Balkan folk, reggaeton\npop, Balkan pop\npop, Balkan, Eastern European\npop, Balkan, Latin\npop, Balkan, Middle Eastern\npop, Balkan, dancehall\npop, Balkan, oriental\npop, Balkan, reggaeton\npop, Balkan, synth-pop\npop, Bhangra\npop, Bhangra, Latin\npop, Bollywood\npop, Bollywood ballad\npop, Bollywood, EDM\npop, Bollywood, Nepali\npop, Bollywood, Punjabi\npop, Bollywood, doo-wop\npop, Bollywood, dream pop\npop, Bollywood, electronic\npop, Brazilian funk\npop, Brazilian funk, carioca\npop, Brazilian funk, disco\npop, Brazilian funk, lo-fi hip hop\npop, Brazilian hip-hop\npop, Brazilian pop\npop, Brazilian pop, early 2000s\npop, Brazilian, educational\npop, Central Asian\npop, Central Asian folk\npop, Central Asian fusion\npop, Central Asian influence\npop, Central Asian pop\npop, Central Asian, Eastern European\npop, Central Asian, Latin\npop, Central Asian, Middle Eastern\npop, Central Asian, R&B\npop, Central Asian, Turkish\npop, Central Asian, ambient\npop, Central Asian, atmospheric\npop, Central Asian, cinematic\npop, Central Asian, dance\npop, Central Asian, dream pop\npop, Central Asian, duet\npop, Central Asian, electronic\npop, Central Asian, flamenco\npop, Central Asian, melancholic\npop, Central Asian, melodic\npop, Central Asian, modern\npop, Central Asian, nostalgic\npop, Central Asian, soulful jazz\npop, Central Asian, synth-pop\npop, Central Asian, upbeat\npop, Chinese ambient\npop, Chinese traditional\npop, Christmas\npop, Christmas, cinematic\npop, Dangdut Koplo, Funkot\npop, Dangdut, Pop Melayu\npop, Dutch pop\npop, EDM, doo-wop\npop, EDM, emotional\npop, EDM, future bass\npop, EDM, hip-hop\npop, EDM, traditional fusion\npop, EDM, trap\npop, EDM, tropical house\npop, EDM, world music\npop, East African, bebop\npop, East African, mbalax\npop, East Asian folk\npop, East Asian pop\npop, East Asian, ambient\npop, East Asian, cinematic\npop, East Asian, dreamy\npop, East Asian, inspirational\npop, Eastern European\npop, Eastern European folk\npop, Eastern European folk, Turkish folk\npop, Eastern European folk, dance\npop, Eastern European pop\npop, Eastern European pop, Caucasian pop\npop, Eastern European, 80s\npop, Eastern European, Central Asian\npop, Eastern European, Middle Eastern\npop, Eastern European, Turkish\npop, Eastern European, dramatic\npop, Eastern European, folk-pop\npop, Eastern European, romantic\npop, Eurodance\npop, European folk\npop, Halloween, theatrical\npop, Hindi, melancholic\npop, Iban, Sundanese\npop, Indian classical\npop, Indian classical, Tamil\npop, Indian classical, cinematic\npop, Indian film music\npop, Indian folk\npop, Indian folk, Bollywood\npop, Indian fusion\npop, Indian fusion, lo-fi\npop, Indian pop\npop, Indian pop, 80s pop\npop, Indian pop, bilingual\npop, Indian pop, electronic\npop, Indian pop, synth pop\npop, Indian, Middle Eastern\npop, Indonesian fusion\npop, Indonesian pop\npop, Indonesian, cinematic\npop, Indonesian, world music\npop, Islamic chant, traditional Indonesian\npop, Javanese folk\npop, Javanese, Arabic\npop, Javanese, Islamic\npop, Javanese, Latin\npop, Javanese, Sundanese\npop, Javanese, electronic\npop, Javanese, funk\npop, Javanese, lo-fi\npop, Javanese, modern\npop, Javanese, pop-rock\npop, Javanese, quirky\npop, Javanese, synth-pop\npop, Latin pop\npop, Latin pop, Kannada pop\npop, Latin pop, Telugu pop\npop, Latin pop, ballad\npop, Latin pop, blues-rock\npop, Latin pop, pop-rock, dance-pop, hip-hop\npop, Latin pop, trap\npop, Latin, Central Asian\npop, Latin, Eastern European\npop, Latin, Eurodance\npop, Latin, Middle Eastern\npop, Latin, North African\npop, Latin, South Asian\npop, Latin, South Indian film music\npop, Latin, brass\npop, Latin, flamenco\npop, Latin, world music\npop, Malay pop, Indonesian pop\npop, Malay traditional\npop, Malay traditional, dream pop\npop, Malay traditional, electronic\npop, Malay traditional, modern\npop, Malay, EDM\npop, Malayalam pop, hip hop\npop, Malaysian pop\npop, Manele, electronic\npop, Mediterranean\npop, Mediterranean, Latin\npop, Melayu, regional Mexican\npop, Middle Eastern\npop, Middle Eastern dance\npop, Middle Eastern folk\npop, Middle Eastern folk, dance\npop, Middle Eastern fusion\npop, Middle Eastern fusion, South Asian pop\npop, Middle Eastern pop\npop, Middle Eastern pop, R&B\npop, Middle Eastern pop, Turkish pop\npop, Middle Eastern, Anatolian\npop, Middle Eastern, Azerbaijani\npop, Middle Eastern, Azerbaijani folk\npop, Middle Eastern, Balkan\npop, Middle Eastern, Central Asian\npop, Middle Eastern, Eastern European\npop, Middle Eastern, Kurdish\npop, Middle Eastern, Kurdish folk\npop, Middle Eastern, Latin\npop, Middle Eastern, Malay\npop, Middle Eastern, Mediterranean\npop, Middle Eastern, North African\npop, Middle Eastern, Persian\npop, Middle Eastern, South Asian\npop, Middle Eastern, Southeast Asian\npop, Middle Eastern, Turkish\npop, Middle Eastern, acoustic\npop, Middle Eastern, atmospheric\npop, Middle Eastern, cinematic\npop, Middle Eastern, classical\npop, Middle Eastern, dance\npop, Middle Eastern, dramatic\npop, Middle Eastern, electronic\npop, Middle Eastern, electronic dance\npop, Middle Eastern, emotive\npop, Middle Eastern, modern\npop, Middle Eastern, reggaeton\npop, Middle Eastern, synth\npop, Middle Eastern, taqsim\npop, Middle Eastern, trap\npop, Middle Eastern, upbeat\npop, Middle Eastern, world music\npop, Mongolian folk, epic\npop, North African fusion\npop, North African, French\npop, North African, Latin\npop, North African, Middle Eastern\npop, North African, cinematic\npop, North African, dancehall\npop, North African, electronic\npop, North African, modern\npop, Persian, cinematic\npop, Punjabi pop\npop, Punjabi pop, trap\npop, Punjabi, electronic\npop, R&B\npop, R&B, 2000s\npop, R&B, Bengali\npop, R&B, C-pop\npop, R&B, Central Asian\npop, R&B, Indian pop\npop, R&B, J-pop\npop, R&B, Mandopop\npop, R&B, Punjabi pop\npop, R&B, South Indian film music\npop, R&B, Spanish-influenced\npop, R&B, chiptune\npop, R&B, cinematic\npop, R&B, dance-pop\npop, R&B, dancehall\npop, R&B, devotional\npop, R&B, early 2000s\npop, R&B, electronic\npop, R&B, funk\npop, R&B, funk, rock\npop, R&B, future bass\npop, R&B, gospel\npop, R&B, hardstyle trap\npop, R&B, hip-hop\npop, R&B, hyperpop\npop, R&B, new jack swing\npop, R&B, pop-rock\npop, R&B, traditional South Asian\npop, R&B, traditional fusion\npop, R&B, vaporwave\npop, Rai\npop, Rai, dance\npop, Rai, electronic\npop, Rai, reggaeton\npop, Romanian, Latin\npop, Romanian, Manele\npop, Sinhala folk\npop, South Asian\npop, South Asian Christian\npop, South Asian folk\npop, South Asian fusion\npop, South Asian fusion, Middle Eastern pop\npop, South Asian influence\npop, South Asian pop\npop, South Asian pop, Arabic pop\npop, South Asian pop, Middle Eastern pop\npop, South Asian pop, dance\npop, South Asian pop, electronic\npop, South Asian, 2000s Bollywood\npop, South Asian, Latin\npop, South Asian, Middle Eastern\npop, South Asian, R&B\npop, South Asian, Sinhala\npop, South Asian, accordion\npop, South Asian, atmospheric\npop, South Asian, ballad\npop, South Asian, cinematic\npop, South Asian, dance\npop, South Asian, duet\npop, South Asian, electronic\npop, South Asian, film soundtrack\npop, South Asian, instrumental\npop, South Asian, melancholic\npop, South Asian, melodic\npop, South Asian, modern\npop, South Asian, rock\npop, South Asian, romantic\npop, South Asian, upbeat\npop, South Asian, uplifting\npop, South Asian, world music\npop, South Indian\npop, South Indian film music\npop, South Indian film music, Latin\npop, South Indian film music, flamenco\npop, South Indian film music, rock\npop, South Indian fusion\npop, South Indian pop\npop, South Indian, dance\npop, South Indian, electronic\npop, South Indian, melodic\npop, South Indian, multi-lingual\npop, South Indian, upbeat\npop, Southeast Asian festive\npop, Southeast Asian folk\npop, Southeast Asian fusion\npop, Southeast Asian pop\npop, Southeast Asian pop, dance\npop, Southeast Asian, Sinhala\npop, Southeast Asian, ambient\npop, Southeast Asian, cinematic\npop, Southeast Asian, dance\npop, Southeast Asian, devotional\npop, Southeast Asian, dramatic\npop, Southeast Asian, duet\npop, Southeast Asian, educational\npop, Southeast Asian, electronic\npop, Southeast Asian, emotional\npop, Southeast Asian, festive\npop, Southeast Asian, melancholic\npop, Southeast Asian, modern\npop, Southeast Asian, ney flute\npop, Southeast Asian, patriotic\npop, Southeast Asian, retro\npop, Southeast Asian, shehnai\npop, Spanish-style, cinematic\npop, Spanish-style, electronic\npop, Sundanese, electronic\npop, Sundanese, festive\npop, Telugu pop, acoustic\npop, Tibetan fusion\npop, Tibetan influence\npop, Turkish folk, Azerbaijani folk\npop, Turkish folk, Middle Eastern\npop, Turkish folk, ambient\npop, Turkish folk, cinematic\npop, Turkish folk, modern\npop, Turkish pop, Middle Eastern pop\npop, Turkish, Azerbaijani\npop, Turkish, Balkan\npop, Turkish, Latin\npop, Turkish, Middle Eastern\npop, Turkish, electronic\npop, UK hip-hop, electronic\npop, Vietnamese folk\npop, Vietnamese folk, electronic\npop, Vietnamese traditional\npop, Y2K R&B, trap-pop\npop, a cappella, Italian\npop, accordion, Mandarin\npop, accordion, theatrical\npop, acoustic\npop, acoustic folk, hip-hop\npop, acoustic, cinematic\npop, acoustic, electronic\npop, acoustic, lo-fi hip-hop, indie pop, R&B\npop, ambient, North African fusion\npop, ambient, Sinhala\npop, ambient, South Asian\npop, ambient, trap\npop, ambient, world music\npop, atmospheric, multi-lingual\npop, axé\npop, ballad, children's music\npop, bansuri, Southeast Asian\npop, bedroom pop\npop, bhangra, hip-hop\npop, big band, lo-fi\npop, big band, show tune\npop, big band, theatrical\npop, bilingual, cinematic\npop, boom-bap, Mandarin pop\npop, bossa nova\npop, bossa nova, Latin\npop, boy band, gospel\npop, children's music\npop, chiptune\npop, chiptune, K-pop\npop, chiptune, Pop Sunda\npop, chiptune, South Asian\npop, chiptune, Sundanese\npop, chiptune, dangdut koplo\npop, chiptune, electronic\npop, chiptune, future bass\npop, chiptune, modern Central Asian pop\npop, chiptune, traditional Malay\npop, chiptune, trap\npop, chiptune, upbeat\npop, chiptune, video game music\npop, choir, festive\npop, choral, Islamic celebratory\npop, cinematic, 80s pop\npop, cinematic, Burmese\npop, cinematic, Central Asian\npop, cinematic, Chinese fusion\npop, cinematic, EDM\npop, cinematic, Eastern European\npop, cinematic, French pop\npop, cinematic, Hebrew\npop, cinematic, Hebrew vocal\npop, cinematic, Hindi\npop, cinematic, Indian classical\npop, cinematic, J-pop\npop, cinematic, Malay traditional\npop, cinematic, Middle Eastern\npop, cinematic, South Asian\npop, cinematic, South Asian classical\npop, cinematic, South Indian\npop, cinematic, Southeast Asian\npop, cinematic, Tết\npop, cinematic, ambient\npop, cinematic, anthemic\npop, cinematic, ballad\npop, cinematic, duet\npop, cinematic, electronic\npop, cinematic, emotional\npop, cinematic, ethnic fusion\npop, cinematic, hip-hop\npop, cinematic, jazz\npop, cinematic, multi-lingual\npop, cinematic, oriental\npop, cinematic, trap\npop, cinematic, vintage\npop, cinematic, world fusion\npop, classical fusion, C-pop\npop, classical, Central Asian\npop, classical, Middle Eastern\npop, classical, ambient\npop, classical, folk\npop, cumbia, Eastern European folk\npop, dance, Afro-pop\npop, dance, Anatolian\npop, dance, Sinhala\npop, dance, Sundanese\npop, dance, accordion\npop, dance, electronic\npop, dance-pop\npop, dance-pop, Anatolian pop\npop, dance-pop, Eastern European\npop, dance-pop, South Asian pop\npop, dance-pop, Vietnamese New Year\npop, dance-pop, rock\npop, dancehall\npop, dancehall, Azerbaijani\npop, dancehall, South Asian\npop, dancehall, South Asian fusion\npop, dancehall, moombahton\npop, dancehall, reggaeton\npop, dangdut\npop, dangdut koplo\npop, dangdut koplo, 90s dance-pop\npop, dangdut koplo, Javanese\npop, dangdut koplo, chiptune\npop, dangdut koplo, funkot\npop, dangdut koplo, traditional\npop, dangdut, chiptune\npop, dangdut, cinematic\npop, dangdut, melayu\npop, dangdut, pop-latin\npop, disco-funk\npop, dream pop, Punjabi pop\npop, dubstep\npop, duduk, Central Asian\npop, duduk, Central Asian folk\npop, duduk, atmospheric\npop, duduk, cinematic\npop, duduk, electronic\npop, duduk, emotional\npop, duduk, romantic\npop, duduk, soulful\npop, early 2000s Asian pop\npop, early 2000s R&B\npop, early 2000s Russian pop\npop, early 2000s internet\npop, early 2000s, nostalgic\npop, electronic folk\npop, electronic, Azerbaijani\npop, electronic, Azerbaijani folk\npop, electronic, Azerbaijani pop\npop, electronic, Bengali\npop, electronic, C-pop\npop, electronic, Central Asian\npop, electronic, Central Asian folk\npop, electronic, Eastern European\npop, electronic, Hindi pop\npop, electronic, Indian fusion\npop, electronic, Indian pop\npop, electronic, K-pop\npop, electronic, Malay traditional\npop, electronic, Middle Eastern\npop, electronic, Middle Eastern fusion\npop, electronic, Mongolian\npop, electronic, Persian pop\npop, electronic, Punjabi\npop, electronic, Sinhala\npop, electronic, South Asian\npop, electronic, South Asian fusion\npop, electronic, South Indian\npop, electronic, Southeast Asian\npop, electronic, Turkish\npop, electronic, Uzbek\npop, electronic, ambient\npop, electronic, cinematic\npop, electronic, dancehall\npop, electronic, dramatic\npop, electronic, dream pop\npop, electronic, folk\npop, electronic, folk fusion\npop, electronic, ghazal\npop, electronic, hip-hop\npop, electronic, multilingual\npop, electronic, oriental\npop, electronic, oriental fusion\npop, electronic, trap\npop, electronic, world fusion\npop, electronic, world music\npop, electronic, worldbeat\npop, emotional ballad, Central Asian\npop, estrada\npop, estrada, 80s\npop, estrada, 90s\npop, estrada, Turkish\npop, estrada, anthemic\npop, estrada, dance\npop, estrada, electronic\npop, estrada, synth-pop\npop, estrada, synthpop\npop, estrada, synthwave\npop, ethereal, Mongolian\npop, ethno-pop\npop, euro-pop\npop, eurodance\npop, eurodance, blues\npop, eurodance, chiptune\npop, eurodance, cinematic\npop, eurodance, trance\npop, eurovision, dance-pop\npop, fairytale, folk\npop, fairytale, orchestral\npop, festive\npop, festive, C-pop\npop, festive, Malay pop\npop, festive, acoustic\npop, festive, children's\npop, festive, cinematic\npop, festive, electronic\npop, festive, holiday\npop, festive, modern C-pop\npop, festive, multi-vocalist\npop, festive, pop-rock\npop, festive, traditional\npop, festive, traditional fusion\npop, filmi\npop, filmi, late-90s\npop, filmi, world music\npop, flamenco, Balkan\npop, flamenco, Central Asian\npop, flamenco, Eastern European\npop, flamenco, Hebrew\npop, flamenco, Middle Eastern\npop, flamenco, Turkish\npop, flamenco, blues\npop, flamenco, electronic\npop, flamenco, melancholic\npop, flamenco, world music\npop, folk dance\npop, folk fusion, Azerbaijani\npop, folk, Anatolian\npop, folk, Azerbaijani\npop, folk, Central Asian\npop, folk, Eastern European\npop, folk, Middle Eastern\npop, folk, South Asian\npop, folk, Southeast Asian\npop, folk, Sundanese\npop, folk, Turkish\npop, folk, ambient\npop, folk, ballad, acoustic\npop, folk, chiptune\npop, folk, cinematic\npop, folk, dance\npop, folk, dramatic\npop, folk, duduk\npop, folk, electronic\npop, folk, estrada\npop, folk, filmi\npop, folk, ghazal\npop, folk, jazzy\npop, folk, lo-fi\npop, folk, melancholic\npop, folk, modern\npop, folk, nostalgic\npop, folk, oriental\npop, folk, oud\npop, folk, polka\npop, folk, romantic\npop, folk, synth\npop, folk, theatrical\npop, folk, upbeat\npop, folk, waltz\npop, folk-pop\npop, folk-pop, Central Asian\npop, folk-pop, cinematic\npop, folk-pop, electronic\npop, folk-pop, estrada\npop, funk, R&B\npop, funk, disco\npop, funk, hip-hop\npop, funk, synthwave\npop, fusion, South Asian\npop, future bass\npop, future bass, EDM\npop, future bass, Indian pop\npop, future bass, Latin pop\npop, future bass, R&B\npop, future bass, ambient\npop, future bass, brostep\npop, future bass, cinematic\npop, future bass, complextro\npop, future bass, gospel\npop, future bass, hip hop\npop, future bass, hip-hop\npop, future bass, hyperpop\npop, future bass, lo-fi hip hop\npop, future bass, nostalgic\npop, future bass, singer-songwriter\npop, ghazal, Sufi\npop, ghazal, electronic\npop, gospel, R&B\npop, gospel, a cappella\npop, hardstyle\npop, hardstyle, big room house\npop, hardstyle, trap\npop, hip hop, rock, acoustic\npop, hip-hop\npop, hip-hop, EDM\npop, hip-hop, Middle Eastern\npop, hip-hop, South Indian film music\npop, hip-hop, ambient\npop, hip-hop, cinematic\npop, hip-hop, classical\npop, hip-hop, funk\npop, hip-hop, traditional Southeast Asian\npop, hip-hop, trap\npop, holiday\npop, hyperpop\npop, indie pop\npop, industrial rock\npop, island pop, Indonesian pop\npop, j-rock, ambient\npop, kizomba, multilingual\npop, kizomba, reggaeton\npop, klezmer\npop, klezmer, Balkan folk\npop, late 80s, South Asian\npop, late 80s, Southeast Asian\npop, late 90s pop, Central Asian pop\npop, late-90s, early-2000s\npop, light R&B\npop, lo-fi hip hop\npop, lullaby, electronic\npop, march, brass\npop, melancholic, Middle Eastern\npop, melancholic, electronic\npop, microtonal, Central Asian\npop, microtonal, folk\npop, microtonal, traditional\npop, microtonal, traditional Central Asian\npop, modern dangdut\npop, modern dangdut, pop Melayu\npop, moombahton\npop, multilingual\npop, multilingual, cinematic\npop, musical theater\npop, musical theater, electronic\npop, new age, world music\npop, new jack swing\npop, new jack swing, R&B\npop, new jack swing, gospel\npop, ney flute, Central Asian\npop, ney flute, North African\npop, ney flute, Southeast Asian\npop, ney flute, atmospheric\npop, ney flute, cinematic\npop, ney flute, modern C-pop\npop, ney flute, traditional Central Asian\npop, nu-disco, EDM\npop, orchestral, Middle Eastern\npop, oriental fusion\npop, oriental pop\npop, oud, Malay\npop, oud, cinematic\npop, oud, electronic\npop, oud, modern\npop, patriotic, South Asian\npop, polka, Portuguese\npop, progressive house\npop, qanun, Middle Eastern\npop, quirky pop\npop, quirky, cinematic\npop, ragtime, Sinhala pop\npop, rap, synth pop\npop, reggae, Middle Eastern\npop, reggae, ska\npop, reggae, world music\npop, reggaeton\npop, reggaeton, Balkan pop\npop, reggaeton, Central Asian\npop, reggaeton, Eastern European\npop, reggaeton, French pop\npop, reggaeton, Latin\npop, reggaeton, Middle Eastern\npop, reggaeton, North African\npop, reggaeton, R&B\npop, reggaeton, R&B, K-pop\npop, reggaeton, South Asian\npop, reggaeton, South Asian fusion\npop, reggaeton, Southeast Asian\npop, reggaeton, anthemic\npop, reggaeton, atmospheric\npop, reggaeton, cinematic\npop, reggaeton, dancehall\npop, reggaeton, electronic\npop, reggaeton, emotional\npop, reggaeton, flamenco\npop, reggaeton, folk\npop, reggaeton, folk-pop\npop, reggaeton, hip-hop, ballad\npop, reggaeton, lo-fi hip hop\npop, reggaeton, romantic\npop, reggaeton, synth\npop, reggaeton, synth-pop\npop, reggaeton, tropical\npop, reggaeton, world music\npop, reggaeton-lite\npop, reggaeton-lite, Bengali\npop, reggaeton-lite, Dutch House\npop, reggaeton-lite, tropical\npop, regional fusion\npop, regional pop\npop, regional pop, ambient\npop, regional, dance\npop, retro Turkish\npop, retro video game, 80s synth\npop, retro video game, superhero\npop, retro, Eastern European\npop, retro, Filipino\npop, retro, Halloween\npop, retro, chiptune\npop, retro, cinematic\npop, retro, estrada\npop, retro, holiday\npop, rock, R&B\npop, rock, cabaret\npop, rock, dream-pop, lo-fi, indie\npop, rock, soul\npop, romantic, Southeast Asian\npop, romantic, melancholic\npop, romantic, traditional\npop, schlager, euro pop\npop, smooth jazz\npop, smooth jazz, Central Asian\npop, smooth jazz, Tamil pop\npop, smooth jazz, funk\npop, soft rock\npop, soft rock, Christmas\npop, soul, Middle Eastern\npop, spiritual pop, Arabic pop\npop, spiritual, South Asian\npop, synth orchestral, video game\npop, synth pop\npop, synth-pop\npop, synth-pop, Christmas\npop, synth-pop, Portuguese pop\npop, synth-pop, R&B, disco-funk\npop, synth-pop, acoustic, R&B\npop, synthwave, Eastern European\npop, tango, Eastern European\npop, theatrical pop\npop, theatrical pop, experimental pop\npop, theatrical, Halloween\npop, theatrical, dark pop\npop, theatrical, funk\npop, theatrical, ragtime\npop, theatrical, retro\npop, theatrical, show tune\npop, traditional Azerbaijani, Turkish\npop, traditional Central Asian\npop, traditional East Asian, fusion\npop, traditional Malay, Indonesian\npop, traditional Malay, Middle Eastern\npop, traditional Malay, Sundanese\npop, traditional Malay, cinematic\npop, traditional Malay, electronic\npop, traditional Malay, festive\npop, traditional Malay, fusion\npop, traditional Malay, ney flute\npop, traditional Malay, qanun\npop, traditional Malay, world fusion\npop, traditional Southeast Asian\npop, traditional Southeast Asian, instrumental\npop, traditional Southeast Asian, modern\npop, traditional Turkish, Azerbaijani\npop, traditional fusion\npop, traditional, melancholic\npop, trap\npop, trap, Azerbaijani folk\npop, trap, Balkan\npop, trap, Central Asian\npop, trap, EDM\npop, trap, Italian\npop, trap, K-pop\npop, trap, Latin pop\npop, trap, Middle Eastern\npop, trap, R&B\npop, trap, South Asian\npop, trap, South Asian, Arabic\npop, trap, Southeast Asian\npop, trap, acoustic\npop, trap, afrobeat\npop, trap, ambient\npop, trap, atmospheric\npop, trap, bilingual\npop, trap, chiptune\npop, trap, cinematic\npop, trap, dancehall\npop, trap, dark pop\npop, trap, dramatic\npop, trap, dubstep\npop, trap, electronic\npop, trap, emotional\npop, trap, festive\npop, trap, fusion\npop, trap, future bass\npop, trap, lo-fi\npop, trap, melancholic\npop, trap, modern\npop, trap, multi-lingual\npop, trap, multilingual\npop, trap, reggaeton\npop, trap, theatrical, comedy\npop, trap, world music\npop, trap, world percussion\npop, trap-R&B\npop, trap-pop, rock\npop, tribal, dance\npop, tropical house\npop, tropical, reggae-lite\npop, ukulele, J-pop\npop, ukulele, beach party\npop, ukulele, musical theatre\npop, ukulele, theatrical\npop, upbeat, motivational\npop, video game soundtrack\npop, video game, children's music\npop, video game, synthwave\npop, whimsical, acoustic\npop, world fusion\npop, world fusion, R&B\npop, world fusion, electronic\npop, world fusion, emotional\npop, world fusion, lo-fi\npop, world fusion, melancholic\npop, world fusion, ney flute\npop, world music\npop, world music, Middle Eastern\npop, world music, Sinhala\npop, world music, South Asian folk\npop, world music, Southeast Asian\npop, world music, Turkish\npop, world music, cinematic\npop, world music, electronic\npop, world music, festive\npop, world music, gospel\npop, world music, hip-hop\npop, world music, new age\npop, world music, stadium anthem\npop, world music, trap-pop\npop, world music, upbeat\npop, world pop, inspirational\npop, world, Middle Eastern\npop, world, ambient\npop, worldbeat\npop, worldbeat, electronic\npop-EDM\npop-EDM Bhangra\npop-EDM Bollywood\npop-EDM Indian fusion\npop-EDM ballad\npop-EDM big room house\npop-EDM future bass\npop-EDM future bass trap\npop-EDM hardstyle\npop-EDM progressive house\npop-EDM tropical house\npop-EDM world music\npop-EDM, Bollywood, dancehall\npop-EDM, Central Asian folk\npop-EDM, Middle Eastern\npop-EDM, Middle Eastern fusion\npop-EDM, South Asian folk\npop-EDM, South Asian fusion\npop-EDM, dance-pop, progressive house\npop-EDM, future bass\npop-EDM, future bass, reggaeton\npop-EDM, hardstyle, cinematic\npop-R&B\npop-R&B 90s\npop-R&B Afro-Caribbean\npop-R&B Afrobeat\npop-R&B Afrobeat Latin\npop-R&B Afrobeats\npop-R&B Arabic fusion\npop-R&B Bollywood\npop-R&B Desi\npop-R&B Indian\npop-R&B Islamic devotional\npop-R&B J-pop\npop-R&B K-pop\npop-R&B Latin\npop-R&B Latin dancehall\npop-R&B Latin pop\npop-R&B Latin-pop\npop-R&B Mandopop\npop-R&B UK hip-hop\npop-R&B afrobeat\npop-R&B ballad\npop-R&B chiptune\npop-R&B cinematic\npop-R&B city pop\npop-R&B city-pop\npop-R&B classical\npop-R&B dancehall\npop-R&B dancehall-lite\npop-R&B deep house\npop-R&B electro-house\npop-R&B electronic\npop-R&B electronic rock\npop-R&B flamenco\npop-R&B funk\npop-R&B funk disco\npop-R&B fusion\npop-R&B future bass\npop-R&B future bass hip-hop\npop-R&B future bass tropical house\npop-R&B gospel\npop-R&B hip-hop\npop-R&B house\npop-R&B indie pop\npop-R&B jazz fusion\npop-R&B lo-fi\npop-R&B lo-fi hip hop\npop-R&B lo-fi hip-hop\npop-R&B metalcore\npop-R&B neo-soul\npop-R&B nu-disco\npop-R&B nu-disco funk\npop-R&B reggae\npop-R&B reggaeton\npop-R&B slap house\npop-R&B smooth jazz\npop-R&B stadium rock\npop-R&B trap\npop-R&B trap EDM\npop-R&B trap-soul\npop-R&B tropical\npop-R&B tropical house\npop-R&B tropical house future bass\npop-R&B world fusion\npop-R&B world music\npop-R&B, 90s new jack swing\npop-R&B, Afrobeat, atmospheric\npop-R&B, Afrobeats\npop-R&B, Afrobeats, bilingual\npop-R&B, Afrobeats, dream pop\npop-R&B, Afrobeats, lo-fi\npop-R&B, Afrobeats, trap\npop-R&B, Arabic ballad, Turkish folk\npop-R&B, Arabic pop, Rai\npop-R&B, Arabic, Raï\npop-R&B, Bollywood\npop-R&B, Bollywood, Punjabi\npop-R&B, Bollywood, Punjabi pop\npop-R&B, Brazilian\npop-R&B, Brazilian Funk\npop-R&B, Brazilian funk\npop-R&B, Brazilian funk, chill\npop-R&B, Brazilian funk, synthwave\npop-R&B, Brazilian pagode\npop-R&B, Brazilian trap\npop-R&B, Central Asian\npop-R&B, Central Asian folk\npop-R&B, Central Asian, ballad\npop-R&B, Central Asian, modern\npop-R&B, Central Asian, trap\npop-R&B, EDM, C-pop\npop-R&B, EDM, Punjabi pop\npop-R&B, EDM, cinematic\npop-R&B, EDM, future bass\npop-R&B, EDM, pop-rock\npop-R&B, EDM, trap\npop-R&B, EDM-pop\npop-R&B, East Asian fusion\npop-R&B, East Asian, modern\npop-R&B, Eastern European\npop-R&B, Filipino hip-hop\npop-R&B, Filipino pop\npop-R&B, Filipino, modern\npop-R&B, Hindi fusion, cinematic\npop-R&B, Hindi pop, trap\npop-R&B, Indian classical, cinematic\npop-R&B, Indian classical, trap\npop-R&B, Indian fusion\npop-R&B, J-pop, hip-hop\npop-R&B, J-rock\npop-R&B, Japanese hip-hop\npop-R&B, K-pop\npop-R&B, K-pop, C-pop\npop-R&B, K-pop, upbeat\npop-R&B, Kizomba\npop-R&B, Kizomba, bilingual\npop-R&B, Latin dancehall\npop-R&B, Latin jazz\npop-R&B, Latin pop\npop-R&B, Latin pop, rock\npop-R&B, Latin pop, trap\npop-R&B, Latin, Balkan\npop-R&B, Latin, UK rap\npop-R&B, Latin, smooth jazz\npop-R&B, Latin-pop\npop-R&B, Middle Eastern\npop-R&B, Middle Eastern fusion\npop-R&B, Middle Eastern, atmospheric\npop-R&B, Middle Eastern, cinematic\npop-R&B, Middle Eastern, festive\npop-R&B, Middle Eastern, microtonal\npop-R&B, Middle Eastern, trap\npop-R&B, North African\npop-R&B, North African, duet\npop-R&B, North African, modern\npop-R&B, OPM\npop-R&B, OPM, neo-soul\npop-R&B, Punjabi pop, trap\npop-R&B, Punjabi, hip-hop\npop-R&B, Punjabi, trap\npop-R&B, Rai\npop-R&B, Rai, reggaeton\npop-R&B, Raï\npop-R&B, Raï, French rap\npop-R&B, South Asian\npop-R&B, South Asian fusion\npop-R&B, South Asian pop\npop-R&B, South Asian, atmospheric\npop-R&B, South Asian, ballad\npop-R&B, South Asian, trap\npop-R&B, South Indian\npop-R&B, South Indian, lo-fi\npop-R&B, Southeast Asian\npop-R&B, Southeast Asian pop\npop-R&B, Southeast Asian, funky\npop-R&B, Southeast Asian, modern\npop-R&B, Tamil hip hop\npop-R&B, UK garage\npop-R&B, UK hip-hop\npop-R&B, Vietnamese hip-hop\npop-R&B, Vietnamese hip-hop, lo-fi\npop-R&B, Zouk, Afrobeats\npop-R&B, Zouk, Kizomba\npop-R&B, afrobeat, cross-cultural\npop-R&B, afrobeat, dancehall\npop-R&B, afrobeats, bilingual\npop-R&B, afrobeats, dancehall\npop-R&B, ambient, EDM\npop-R&B, atmospheric, Central Asian\npop-R&B, atmospheric, Indian fusion\npop-R&B, atmospheric, trap\npop-R&B, baroque pop\npop-R&B, bilingual pop-rock\npop-R&B, bilingual, cinematic\npop-R&B, bilingual, trap\npop-R&B, bilingual, trap-influenced\npop-R&B, chiptune, 2000s pop\npop-R&B, chiptune, Afrobeats\npop-R&B, chiptune, C-pop\npop-R&B, chiptune, bilingual\npop-R&B, chiptune, electronic\npop-R&B, chiptune, future bass\npop-R&B, chiptune, trap\npop-R&B, cinematic\npop-R&B, cinematic fusion\npop-R&B, cinematic, Afrobeat\npop-R&B, cinematic, Asian fusion\npop-R&B, cinematic, Bollywood fusion\npop-R&B, cinematic, Central Asian\npop-R&B, cinematic, Central Asian folk\npop-R&B, cinematic, Chinese ambient\npop-R&B, cinematic, Indian classical\npop-R&B, cinematic, Indian fusion\npop-R&B, cinematic, Malay\npop-R&B, cinematic, Sinhala\npop-R&B, cinematic, South Indian\npop-R&B, cinematic, Tagalog\npop-R&B, cinematic, Tamil\npop-R&B, cinematic, emotional\npop-R&B, cinematic, future bass\npop-R&B, cinematic, hip-hop\npop-R&B, cinematic, modern\npop-R&B, cinematic, motivational\npop-R&B, cinematic, orchestral\npop-R&B, cinematic, spiritual\npop-R&B, cinematic, trap\npop-R&B, cinematic, world music\npop-R&B, city pop, Filipino\npop-R&B, city-pop\npop-R&B, conscious hip-hop, cinematic\npop-R&B, dance-pop, Latin pop\npop-R&B, dancehall\npop-R&B, dancehall, Arabic pop\npop-R&B, dancehall, afrobeat\npop-R&B, dancehall, afrobeats\npop-R&B, dancehall, bilingual\npop-R&B, dancehall, electronic\npop-R&B, dancehall, moombahton\npop-R&B, dancehall, reggaeton\npop-R&B, deep house\npop-R&B, deep house, Afrobeats\npop-R&B, deep house, UK garage\npop-R&B, deep house, afrobeats\npop-R&B, dreamy trap\npop-R&B, dreamy, trap\npop-R&B, drill, trap\npop-R&B, drum and bass, ambient\npop-R&B, dubstep\npop-R&B, dubstep, EDM\npop-R&B, dubstep, ambient\npop-R&B, early 2000s\npop-R&B, early 2000s hip-hop\npop-R&B, early 2000s, bilingual\npop-R&B, electro-funk\npop-R&B, electro-pop, funk\npop-R&B, electronic, Arabic fusion\npop-R&B, electronic, Arabic pop\npop-R&B, electronic, Mandarin pop\npop-R&B, electronic, cinematic\npop-R&B, ethereal, Hindi fusion\npop-R&B, festive, melancholic\npop-R&B, flamenco, trap\npop-R&B, folk, cinematic\npop-R&B, funk carioca\npop-R&B, funk, modern\npop-R&B, future bass\npop-R&B, future bass, C-pop\npop-R&B, future bass, Hindi pop\npop-R&B, future bass, Hungarian pop\npop-R&B, future bass, ambient\npop-R&B, future bass, bilingual\npop-R&B, future bass, cinematic\npop-R&B, future bass, dream pop\npop-R&B, future bass, electronic\npop-R&B, future bass, hip-hop\npop-R&B, future bass, hyperpop\npop-R&B, future bass, lo-fi\npop-R&B, future bass, reggaeton\npop-R&B, future bass, soulful\npop-R&B, future bass, trap\npop-R&B, future bass, vaporwave\npop-R&B, future bass, world music\npop-R&B, global fusion\npop-R&B, gospel, Afrobeats\npop-R&B, gospel, early 2000s\npop-R&B, gospel, early 2000s K-pop\npop-R&B, gospel, funk\npop-R&B, gospel, hip-hop\npop-R&B, gospel, inspirational hip-hop\npop-R&B, gospel, smooth jazz\npop-R&B, gospel, trap\npop-R&B, hard rock\npop-R&B, hardstyle, big room house\npop-R&B, hardstyle, phonk\npop-R&B, hip-hop\npop-R&B, hip-hop, EDM\npop-R&B, hip-hop, Khmer\npop-R&B, hip-hop, Latin\npop-R&B, hip-hop, Middle Eastern\npop-R&B, hip-hop, Punjabi\npop-R&B, hip-hop, Thai pop\npop-R&B, hip-hop, bilingual\npop-R&B, hip-hop, cinematic\npop-R&B, hip-hop, dance-pop\npop-R&B, hip-hop, late 90s\npop-R&B, hip-hop, pop-rock\npop-R&B, hip-hop, trap\npop-R&B, hyperpop\npop-R&B, hyperpop, ambient\npop-R&B, hyperpop, cinematic\npop-R&B, hyperpop, trap metal\npop-R&B, late-90s pop, Arabic hip-hop\npop-R&B, liquid drum and bass\npop-R&B, lo-fi hip-hop\npop-R&B, lo-fi hip-hop, Burmese pop\npop-R&B, lo-fi hip-hop, Indian pop\npop-R&B, lo-fi hip-hop, Nepali fusion\npop-R&B, lo-fi hip-hop, Thai soul\npop-R&B, lo-fi hip-hop, atmospheric\npop-R&B, lo-fi hip-hop, bilingual\npop-R&B, lo-fi hip-hop, jazz\npop-R&B, lo-fi hip-hop, melancholic\npop-R&B, lo-fi hip-hop, multilingual\npop-R&B, lo-fi, Indian pop\npop-R&B, lo-fi, traditional Azerbaijani\npop-R&B, metalcore\npop-R&B, metalcore, trap\npop-R&B, modern Nepali\npop-R&B, moombahton, trap\npop-R&B, neo-soul\npop-R&B, neo-soul, G-funk\npop-R&B, neo-soul, city pop\npop-R&B, neo-soul, funk\npop-R&B, neo-soul, hip-hop\npop-R&B, new jack swing\npop-R&B, new jack swing, Latin pop\npop-R&B, new-age\npop-R&B, nu-disco, folk\npop-R&B, nu-disco, funk house\npop-R&B, nu-disco, funk-pop\npop-R&B, nu-metal, modern rock\npop-R&B, orchestral, festive\npop-R&B, pop-rock\npop-R&B, progressive house, dream pop\npop-R&B, reggaeton\npop-R&B, reggaeton, European\npop-R&B, reggaeton, Latin\npop-R&B, reggaeton, Latin pop\npop-R&B, reggaeton, UK rap\npop-R&B, reggaeton, ambient\npop-R&B, reggaeton, bilingual\npop-R&B, reggaeton, dreamy\npop-R&B, reggaeton, lo-fi\npop-R&B, reggaeton, trap\npop-R&B, reggaeton, urban\npop-R&B, rock\npop-R&B, rock, electronic\npop-R&B, soul, conscious hip-hop\npop-R&B, spiritual\npop-R&B, spiritual, trap\npop-R&B, summer party, K-pop\npop-R&B, synth-funk\npop-R&B, trap\npop-R&B, trap, Balkan\npop-R&B, trap, C-pop\npop-R&B, trap, Cantopop\npop-R&B, trap, EDM\npop-R&B, trap, Hindi pop\npop-R&B, trap, Indian fusion\npop-R&B, trap, Indonesian pop\npop-R&B, trap, J-pop\npop-R&B, trap, Mandarin hip-hop\npop-R&B, trap, Mandopop\npop-R&B, trap, Middle Eastern\npop-R&B, trap, North African\npop-R&B, trap, Punjabi\npop-R&B, trap, South Asian\npop-R&B, trap, South Asian fusion\npop-R&B, trap, ambient\npop-R&B, trap, atmospheric\npop-R&B, trap, bilingual\npop-R&B, trap, blues-rock\npop-R&B, trap, chiptune\npop-R&B, trap, cinematic\npop-R&B, trap, dancehall\npop-R&B, trap, dreamy\npop-R&B, trap, electronic\npop-R&B, trap, festive\npop-R&B, trap, future bass\npop-R&B, trap, hyperpop\npop-R&B, trap, lo-fi\npop-R&B, trap, modern\npop-R&B, trap, multilingual\npop-R&B, trap, reggaeton\npop-R&B, trap, rock\npop-R&B, trap, world music\npop-R&B, trap-pop, K-pop\npop-R&B, vaporwave, future bass\npop-R&B, vaporwave, pop-rock\npop-R&B, world music\npop-R&B, world music, ambient\npop-Raï\npop-anthem\npop-anthem EDM\npop-anthem EDM Christian\npop-anthem future bass\npop-anthem hip-hop\npop-anthem world music\npop-anthem, EDM, future bass\npop-anthem, bhangra, electronic\npop-axé\npop-ballad\npop-ballad cinematic\npop-ballad eurodance\npop-ballad future bass\npop-ballad hip-hop\npop-ballad progressive house\npop-ballad rock\npop-ballad trap\npop-ballad trap-pop\npop-ballad, EDM, funk\npop-ballad, Eurodance, EDM\npop-ballad, German hip-hop\npop-ballad, J-pop, cinematic\npop-ballad, J-rock, C-pop\npop-ballad, J-rock, atmospheric\npop-ballad, J-rock, cinematic\npop-ballad, Latin pop, cinematic\npop-ballad, big band, cinematic\npop-ballad, cinematic, hip-hop\npop-ballad, cinematic, pop-rock\npop-ballad, dangdut koplo, rock\npop-ballad, duduk, cinematic\npop-ballad, emo-pop, C-pop\npop-ballad, eurodance\npop-ballad, future bass\npop-ballad, happy hardcore\npop-ballad, hardstyle\npop-ballad, hardstyle, big room house\npop-ballad, hip-hop, Armenian rap\npop-ballad, hip-hop, ambient\npop-ballad, hip-hop, blues-rock\npop-ballad, hip-hop, electronic\npop-ballad, hip-hop, hardstyle\npop-ballad, hip-hop, lo-fi\npop-ballad, hip-hop, orchestral\npop-ballad, noise-rock\npop-ballad, pop-rock, C-pop\npop-ballad, pop-rock, Chinese traditional\npop-ballad, pop-rock, Indonesian rap\npop-ballad, pop-rock, ambient\npop-ballad, pop-rock, hip-hop\npop-ballad, power-pop, rock\npop-ballad, progressive house, big room house\npop-ballad, rap, ambient\npop-ballad, rap, rock\npop-ballad, rock, C-pop\npop-ballad, rock, hip-hop\npop-ballad, theatrical pop, live rock\npop-ballad, theatrical, rock\npop-ballad, trap, ambient\npop-ballad, trap, cinematic\npop-ballad, trap, electronic\npop-ballad, trap, indie-pop\npop-bhangra\npop-bollywood\npop-bossa nova\npop-brega\npop-chanson\npop-choir\npop-classical\npop-classical crossover\npop-country\npop-country future bass\npop-country rock\npop-dabke\npop-dance\npop-dance eurodance\npop-dance flamenco\npop-dance funk\npop-dance future bass\npop-dance gospel soul\npop-dance hardstyle\npop-dance nu-disco\npop-dance progressive house\npop-dance reggaeton\npop-dance tropical\npop-dance tropical house\npop-dance tropical house afrobeat\npop-dance, Arabic pop, hip-hop\npop-dance, Azerbaijani folk\npop-dance, Azerbaijani folk, Turkish folk\npop-dance, Azerbaijani pop\npop-dance, Azerbaijani pop, Turkish pop\npop-dance, Azerbaijani, Turkish\npop-dance, Azerbaijani, energetic\npop-dance, Azerbaijani, modern\npop-dance, Balkan folk\npop-dance, Balkan folk, Chalga\npop-dance, Balkan folk, hyperpop\npop-dance, Balkan fusion\npop-dance, Balkan pop\npop-dance, Balkan pop, emotional ballad\npop-dance, Balkan, Middle Eastern\npop-dance, Balkan, dramatic\npop-dance, Balkan, electronic\npop-dance, Balkan, reggaeton\npop-dance, Bhangra, EDM\npop-dance, Bollywood, Balkan\npop-dance, Bollywood, French pop\npop-dance, Bollywood, electronic\npop-dance, Central Asian\npop-dance, Central Asian, Eastern European\npop-dance, Central Asian, Middle Eastern\npop-dance, Central Asian, acoustic\npop-dance, EDM, French pop\npop-dance, EDM, bilingual\npop-dance, EDM, gospel-pop\npop-dance, EDM, hip-hop\npop-dance, EDM, house\npop-dance, EDM, multilingual\npop-dance, EDM, tropical\npop-dance, Eastern European, Azerbaijani\npop-dance, Eastern European, Middle Eastern\npop-dance, Eastern European, Turkish\npop-dance, Eastern European, Turkish folk\npop-dance, Eastern European, oriental\npop-dance, Euro-pop\npop-dance, Eurodance, Central Asian\npop-dance, Eurodance, Eastern European\npop-dance, Eurodance, Turkish pop\npop-dance, Eurodance, early 2000s\npop-dance, Latin pop, Middle Eastern\npop-dance, Latin, Balkan\npop-dance, Latin, Middle Eastern\npop-dance, Malay pop, Iban pop\npop-dance, Middle Eastern fusion\npop-dance, Middle Eastern fusion, electronic\npop-dance, Middle Eastern, Azerbaijani\npop-dance, Middle Eastern, Balkan\npop-dance, Middle Eastern, Caucasian\npop-dance, Middle Eastern, Caucasian folk\npop-dance, Middle Eastern, Eastern European\npop-dance, Middle Eastern, European\npop-dance, Middle Eastern, Turkish\npop-dance, Middle Eastern, bilingual\npop-dance, Middle Eastern, electronic\npop-dance, Middle Eastern, microtonal\npop-dance, Middle Eastern, modern\npop-dance, North African, Arabic\npop-dance, Punjabi, R&B\npop-dance, Rai, French pop\npop-dance, Rai, electronic\npop-dance, South Asian fusion\npop-dance, South Asian, modern\npop-dance, Southeast Asian, Sinhala\npop-dance, arabesque, cinematic\npop-dance, bilingual, electronic\npop-dance, cinematic, Central Asian\npop-dance, deep house, UK garage\npop-dance, electronic, Azerbaijani\npop-dance, electronic, Eastern European\npop-dance, electronic, Middle Eastern\npop-dance, electronic, North African\npop-dance, electronic, Turkish\npop-dance, electronic, Turkish fusion\npop-dance, electronic, world fusion\npop-dance, eurodance, balkan\npop-dance, eurodance, balkan pop\npop-dance, eurodance, chalga\npop-dance, eurodance, early 2000s\npop-dance, eurodance, house\npop-dance, funk-pop, EDM\npop-dance, funk-pop, contemporary Christian\npop-dance, late-90s, early-2000s\npop-dance, microtonal, Central Asian\npop-dance, moombahton, reggaeton\npop-dance, oriental house\npop-dance, oriental pop\npop-dance, reggaeton\npop-dance, reggaeton, EDM\npop-dance, reggaeton, Latin\npop-dance, reggaeton, Romanian\npop-dance, reggaeton, bilingual\npop-dance, reggaeton, cinematic\npop-dance, reggaeton, electronic\npop-dance, reggaeton, ney flute\npop-dancehall\npop-dancehall reggaeton grime\npop-dangdut\npop-disco\npop-electronic\npop-flamenco\npop-folk\npop-folk Balkan\npop-folk Chalga\npop-folk chalga\npop-folk chiptune\npop-folk cinematic\npop-folk dance\npop-folk dance-pop\npop-folk electronic\npop-folk estrada\npop-folk eurodance chalga\npop-folk flamenco\npop-folk fusion\npop-folk future bass\npop-folk hip-hop\npop-folk maneles\npop-folk novelty\npop-folk retro\npop-folk rock\npop-folk schlager\npop-folk trap\npop-folk turbo-folk\npop-folk, Balkan dance\npop-folk, Balkan, Chalga\npop-folk, Balkan, cinematic\npop-folk, Balkan, electronic\npop-folk, Balkan, flamenco\npop-folk, Balkan, high-energy\npop-folk, C-pop, rap\npop-folk, Celtic, hip-hop\npop-folk, Chalga, electronic\npop-folk, Indian fusion, Tamil pop\npop-folk, J-rock, pop-rock\npop-folk, Latin pop\npop-folk, Latin, Eastern European\npop-folk, Latin, South Asian\npop-folk, Latin, flamenco\npop-folk, South Asian, ambient\npop-folk, chalga, electronic\npop-folk, chalga, spanish-style\npop-folk, chalga, synth folk\npop-folk, children's music, Latin funk\npop-folk, cinematic, Bollywood\npop-folk, cinematic, arabesque\npop-folk, cinematic, dance-pop\npop-folk, dance-pop, Balkan pop\npop-folk, electronic dance\npop-folk, electronic dance, Balkan\npop-folk, electronic dance, Balkan fusion\npop-folk, electronic dance, fusion\npop-folk, electronic, Balkan\npop-folk, electronic, dance-pop\npop-folk, electronic, hard rock\npop-folk, estrada, Eastern European\npop-folk, estrada, dance\npop-folk, estrada, synth\npop-folk, estrada, synth-pop\npop-folk, eurodance, balkan folk\npop-folk, eurodance, chalga\npop-folk, eurodance, dance\npop-folk, eurodance, electronic\npop-folk, future bass, electronic\npop-folk, progressive house, EDM\npop-funk\npop-funk 90s\npop-funk Bollywood\npop-funk J-pop\npop-funk R&B\npop-funk bubblegum pop\npop-funk chiptune\npop-funk city pop\npop-funk city pop neo-soul\npop-funk city-pop\npop-funk electro-rock\npop-funk future bass\npop-funk gospel\npop-funk hip-hop\npop-funk hip-hop electronic\npop-funk metalcore\npop-funk neo-soul\npop-funk nu-disco\npop-funk reggae\npop-funk reggae ska\npop-funk rock\npop-funk smooth jazz\npop-funk soul\npop-funk surf rock\npop-funk tropical\npop-funk tropical house\npop-funk world music\npop-funk, 80s retro, bilingual\npop-funk, Bhangra, late-90s pop\npop-funk, Bhangra-pop, hip-hop\npop-funk, Bollywood, 2000s pop\npop-funk, Bollywood, R&B\npop-funk, Bollywood, bilingual\npop-funk, Bollywood, upbeat\npop-funk, Brazilian pop\npop-funk, Brazilian, upbeat\npop-funk, C-pop, R&B\npop-funk, C-pop, hip-hop\npop-funk, C-pop, traditional fusion\npop-funk, Caribbean, modern\npop-funk, Central Asian folk\npop-funk, Christmas, soul\npop-funk, Desi hip-hop\npop-funk, Eastern European, Turkish\npop-funk, Indian classical, electronic\npop-funk, Indian fusion, cinematic\npop-funk, Italian soul, 80s rock\npop-funk, J-pop, Vocaloid\npop-funk, K-pop, early 2000s\npop-funk, Latin pop, dance\npop-funk, Latin pop, electronic\npop-funk, Latin, Caribbean\npop-funk, North African, Arabic\npop-funk, North African, modern\npop-funk, R&B\npop-funk, R&B, 80s rock\npop-funk, R&B, South Asian pop\npop-funk, R&B, cinematic\npop-funk, R&B, city pop\npop-funk, R&B, early 2000s\npop-funk, R&B, funk\npop-funk, R&B, future bass\npop-funk, R&B, hip-hop\npop-funk, R&B, late-90s\npop-funk, R&B, smooth jazz\npop-funk, R&B, soul\npop-funk, R&B, trap\npop-funk, Rai, modern Chaabi\npop-funk, South Asian, upbeat\npop-funk, South Indian film music, chiptune\npop-funk, Southeast Asian folk, electronic\npop-funk, Tamil hip-hop, electronic\npop-funk, Turkish, Middle Eastern\npop-funk, V-Pop\npop-funk, acid jazz, Latin percussion\npop-funk, bhajan, Indian fusion\npop-funk, big band, ska\npop-funk, bilingual, Punjabi pop\npop-funk, bilingual, South Indian\npop-funk, bilingual, dance\npop-funk, blues-rock, cinematic\npop-funk, cinematic, Tamil\npop-funk, cinematic, anthemic\npop-funk, cinematic, duduk\npop-funk, cinematic, lo-fi hip hop\npop-funk, city pop\npop-funk, city pop, 80s\npop-funk, city pop, J-pop\npop-funk, city pop, R&B\npop-funk, city-pop\npop-funk, city-pop, bilingual\npop-funk, classical, Azerbaijani\npop-funk, classical, theatrical\npop-funk, dangdut\npop-funk, disco, Balkan pop\npop-funk, electronic dance music\npop-funk, estrada, Eastern European\npop-funk, filmi, 80s\npop-funk, flamenco, C-pop\npop-funk, global fusion\npop-funk, gospel, R&B\npop-funk, hard rock\npop-funk, hard rock, rap-rock\npop-funk, hip-hop, R&B\npop-funk, hip-hop, electronic\npop-funk, late-90s, early-2000s\npop-funk, lo-fi hip hop, R&B\npop-funk, neo-soul, jazz fusion\npop-funk, new jack swing\npop-funk, new jack swing, 90s hip-hop\npop-funk, new jack swing, educational\npop-funk, new jack swing, theatrical\npop-funk, nu-disco, electro-pop\npop-funk, patriotic, anthemic\npop-funk, pop-punk\npop-funk, pop-rock\npop-funk, pop-rock, children's music\npop-funk, pop-rock, funk metal\npop-funk, progressive house, dance\npop-funk, retro disco, theatrical\npop-funk, retro, city pop\npop-funk, retro, hip-hop\npop-funk, rock\npop-funk, rock, electronic\npop-funk, synth-pop\npop-funk, synth-pop, North African pop\npop-funk, theatrical, big band\npop-funk, theatrical, villainous\npop-funk, vintage swing, big band\npop-funk, world fusion, South Indian\npop-funk, world-pop, 90s R&B\npop-funk, zouk, kompa\npop-fusion\npop-fusion Bollywood\npop-fusion bhajan\npop-fusion, reggae, dancehall\npop-ghazal\npop-gospel\npop-gospel ballad\npop-gospel hip-hop\npop-gospel jazz\npop-gospel rock\npop-gospel trap\npop-gospel world music\npop-gospel, a cappella, nu-metal\npop-hip hop\npop-hip hop future bass\npop-hip hop, R&B, K-pop\npop-hip hop, future bass\npop-hip hop, future bass, hyperpop\npop-hip hop, future bass, sentimental\npop-hip-hop\npop-hip-hop R&B\npop-hip-hop, cinematic, rock\npop-house\npop-house future bass\npop-jazz\npop-jazz ballad\npop-jazz chanson\npop-jazz fusion\npop-jazz, Latin, R&B\npop-jazz, big band, lounge\npop-latin\npop-melayu dangdut\npop-musical\npop-punk\npop-punk Christian rock\npop-punk J-rock\npop-punk R&B\npop-punk alt-rock\npop-punk alternative metal\npop-punk alternative rock\npop-punk alternative rock chiptune\npop-punk alternative rock electronic\npop-punk alternative rock hip-hop\npop-punk alternative rock nu-metal\npop-punk alternative rock post-hardcore\npop-punk alternative rock rap-rock\npop-punk anime\npop-punk anime rock\npop-punk bluegrass\npop-punk blues\npop-punk breakbeat\npop-punk chiptune\npop-punk chiptune electronic rock\npop-punk chiptune hip-hop\npop-punk chiptune rock\npop-punk cinematic\npop-punk comedy rock\npop-punk complextro chiptune\npop-punk cyberpunk\npop-punk dance-pop\npop-punk dangdut koplo\npop-punk drum and bass\npop-punk dubstep\npop-punk easycore\npop-punk electro-pop\npop-punk electro-rock\npop-punk electronic\npop-punk electronic J-rock\npop-punk electronic chiptune\npop-punk electronic hip-hop\npop-punk electronic post-hardcore\npop-punk electronic rock\npop-punk electronic trance\npop-punk electronicore\npop-punk emo\npop-punk emo J-rock\npop-punk emo alternative rock\npop-punk emo chiptune\npop-punk emo electronic\npop-punk emo hip-hop\npop-punk emo hyperpop\npop-punk emo math-rock\npop-punk emo metalcore\npop-punk emo post-hardcore\npop-punk emo rap\npop-punk emo rap-rock\npop-punk emo rock\npop-punk emo trap\npop-punk emo-pop\npop-punk emo-pop chiptune\npop-punk emo-pop rap-rock\npop-punk emo-rap\npop-punk emo-rap hyperpop\npop-punk emo-rock\npop-punk emo-rock rap-rock\npop-punk emo-trap\npop-punk flamenco\npop-punk folk-punk\npop-punk funk rock\npop-punk funk-pop\npop-punk funk-rock\npop-punk future bass\npop-punk garage rock\npop-punk glam rock\npop-punk gospel\npop-punk gothic rock\npop-punk gypsy-punk\npop-punk happy hardcore\npop-punk hardcore\npop-punk hardcore punk\npop-punk hardstyle\npop-punk hip-hop\npop-punk hip-hop electronic\npop-punk hip-hop experimental\npop-punk hip-hop fusion\npop-punk hip-hop grime\npop-punk hip-hop hyperpop\npop-punk hip-hop soul\npop-punk hyperpop\npop-punk hyperpop J-rock\npop-punk hyperpop chiptune\npop-punk hyperpop drum and bass\npop-punk hyperpop emo-rap\npop-punk hyperpop industrial\npop-punk hyperpop trap\npop-punk indie rock\npop-punk lo-fi\npop-punk mariachi\npop-punk math rock\npop-punk math-rock\npop-punk metalcore\npop-punk metalcore chiptune\npop-punk musical theater\npop-punk nintendocore\npop-punk novelty\npop-punk nu-metal\npop-punk parody\npop-punk post-hardcore\npop-punk power metal\npop-punk power-pop\npop-punk rap-rock\npop-punk reggae-ska\npop-punk reggaeton\npop-punk rock\npop-punk rock en español\npop-punk rockabilly\npop-punk samba-rock\npop-punk screamo\npop-punk shoegaze\npop-punk ska\npop-punk ska klezmer\npop-punk ska punk\npop-punk ska-punk\npop-punk skate punk\npop-punk skate-punk\npop-punk southern rock\npop-punk space-rock\npop-punk stadium rock\npop-punk surf rock\npop-punk surf-rock\npop-punk synth-pop\npop-punk synth-rock\npop-punk trap\npop-punk trap R&B\npop-punk trap metal\npop-punk trap-rock\npop-punk vaporwave\npop-punk world fusion\npop-punk worship\npop-punk, 80s arena rock\npop-punk, Brazilian funk carioca\npop-punk, Brazilian rock\npop-punk, C-pop\npop-punk, C-pop, alt-metal\npop-punk, C-pop, electronic\npop-punk, C-pop, indie rock\npop-punk, Celtic punk\npop-punk, Celtic rock\npop-punk, Christian rock\npop-punk, Christmas ballad, cinematic\npop-punk, Christmas, R&B\npop-punk, Christmas, chiptune\npop-punk, EDM\npop-punk, EDM, Russian vocal\npop-punk, EDM, complextro\npop-punk, EDM, lo-fi\npop-punk, German new wave\npop-punk, German rap\npop-punk, Indonesian pop\npop-punk, Italian rock\npop-punk, J-pop, musical theater\npop-punk, J-pop, rap-rock\npop-punk, J-rock\npop-punk, J-rock, C-pop\npop-punk, J-rock, German\npop-punk, J-rock, Taiwanese Hokkien\npop-punk, J-rock, alternative metal\npop-punk, J-rock, ambient\npop-punk, J-rock, anime\npop-punk, J-rock, anime theme\npop-punk, J-rock, atmospheric\npop-punk, J-rock, chiptune\npop-punk, J-rock, cinematic\npop-punk, J-rock, easycore\npop-punk, J-rock, electronic\npop-punk, J-rock, emo\npop-punk, J-rock, emo-rap\npop-punk, J-rock, happy hardcore\npop-punk, J-rock, hardcore\npop-punk, J-rock, hyperpop\npop-punk, J-rock, lo-fi\npop-punk, J-rock, math rock\npop-punk, J-rock, math-rock\npop-punk, J-rock, metalcore\npop-punk, J-rock, nu-metal\npop-punk, J-rock, power metal\npop-punk, J-rock, power-pop\npop-punk, J-rock, rap-rock\npop-punk, J-rock, shred guitar\npop-punk, J-rock, trap\npop-punk, Javanese\npop-punk, Javanese fusion\npop-punk, Javanese, rock\npop-punk, K-pop, R&B\npop-punk, K-rock\npop-punk, Latin pop, trap\npop-punk, Latin rock\npop-punk, Latin rock, cumbia\npop-punk, Latin urban\npop-punk, Mandarin rock\npop-punk, Neue Deutsche Welle\npop-punk, Nintendocore\npop-punk, Nintendocore, J-rock\npop-punk, Nintendocore, chiptune\npop-punk, Nintendocore, emo\npop-punk, Nintendocore, metalcore\npop-punk, R&B, bilingual\npop-punk, R&B, electronic\npop-punk, R&B, hip-hop\npop-punk, R&B, lo-fi\npop-punk, R&B, trap\npop-punk, Russian rock\npop-punk, Schlager\npop-punk, Spanish folk\npop-punk, Spanish rock\npop-punk, Sundanese folk\npop-punk, UK hip-hop\npop-punk, Vocaloid\npop-punk, acoustic ballad\npop-punk, acoustic ballad, rock\npop-punk, acoustic folk, C-pop\npop-punk, acoustic pop, rock\npop-punk, alt-rock\npop-punk, alt-rock, acoustic ballad\npop-punk, alt-rock, vaporwave\npop-punk, alternative R&B, industrial\npop-punk, alternative rock\npop-punk, alternative rock, C-pop\npop-punk, alternative rock, K-rock\npop-punk, alternative rock, acoustic ballad\npop-punk, alternative rock, ambient\npop-punk, alternative rock, atmospheric\npop-punk, alternative rock, chiptune\npop-punk, alternative rock, emo\npop-punk, alternative rock, folk\npop-punk, alternative rock, hip-hop\npop-punk, alternative rock, lo-fi\npop-punk, alternative rock, metalcore\npop-punk, alternative rock, nu-metal\npop-punk, alternative rock, rap\npop-punk, alternative rock, rap-rock\npop-punk, alternative rock, trap\npop-punk, alternative rock, vaporwave\npop-punk, ambient, C-pop\npop-punk, bluegrass, acoustic ballad\npop-punk, bossa nova, ska-punk\npop-punk, breakcore, dubstep\npop-punk, brostep\npop-punk, cabaret, Latin pop\npop-punk, children's music\npop-punk, children's music, Brazilian pop\npop-punk, children's music, Latin pop\npop-punk, chiptune\npop-punk, chiptune metalcore\npop-punk, chiptune, C-pop\npop-punk, chiptune, J-rock\npop-punk, chiptune, Nintendocore\npop-punk, chiptune, Russian pop\npop-punk, chiptune, Spanish pop\npop-punk, chiptune, aggressive\npop-punk, chiptune, cinematic rock\npop-punk, chiptune, easycore\npop-punk, chiptune, electronic\npop-punk, chiptune, emo\npop-punk, chiptune, emo-pop\npop-punk, chiptune, energetic\npop-punk, chiptune, hardcore\npop-punk, chiptune, hip-hop\npop-punk, chiptune, hyperpop\npop-punk, chiptune, indie rock\npop-punk, chiptune, lo-fi\npop-punk, chiptune, metalcore\npop-punk, chiptune, punk rock\npop-punk, chiptune, rap-rock\npop-punk, chiptune, reggae\npop-punk, chiptune, rock\npop-punk, chiptune, ska-punk\npop-punk, chiptune, synth-rock\npop-punk, chiptune, theatrical rock\npop-punk, cinematic\npop-punk, cinematic ballad\npop-punk, cinematic rock\npop-punk, cinematic rock, metalcore\npop-punk, cinematic, Chinese rock\npop-punk, cinematic, J-rock\npop-punk, cinematic, ballad\npop-punk, cinematic, chiptune\npop-punk, cinematic, dark ambient\npop-punk, cinematic, emotional\npop-punk, cinematic, holiday\npop-punk, cinematic, hyperpop\npop-punk, cinematic, indie\npop-punk, cinematic, indie rock\npop-punk, cinematic, lo-fi\npop-punk, cinematic, nu-metal\npop-punk, cinematic, operatic\npop-punk, cinematic, orchestral\npop-punk, cinematic, punk rock\npop-punk, cinematic, rap\npop-punk, cinematic, rap-rock\npop-punk, cinematic, synth\npop-punk, cinematic, theatrical\npop-punk, circus rock\npop-punk, comedic, Christmas\npop-punk, comedy rock\npop-punk, cyberpunk\npop-punk, dance-punk\npop-punk, dangdut\npop-punk, digital hardcore, chiptune\npop-punk, disco-pop\npop-punk, dream pop, emo\npop-punk, dream-pop\npop-punk, drum and bass\npop-punk, dubstep, lo-fi\npop-punk, easycore\npop-punk, easycore, J-rock\npop-punk, easycore, chiptune\npop-punk, easycore, electronic\npop-punk, easycore, hardcore\npop-punk, easycore, high-energy\npop-punk, easycore, hyperpop\npop-punk, easycore, metalcore\npop-punk, easycore, nu-metal\npop-punk, easycore, post-hardcore\npop-punk, easycore, synthwave\npop-punk, easycore, trap\npop-punk, electro house\npop-punk, electro-house, R&B\npop-punk, electro-rock\npop-punk, electronic dance\npop-punk, electronic rock, C-pop\npop-punk, electronic rock, metalcore\npop-punk, electronic, EDM\npop-punk, electronic, Mandarin rock\npop-punk, electronic, alternative rock\npop-punk, electronic, chiptune\npop-punk, electronic, future bass\npop-punk, electronic, hip-hop\npop-punk, electronic, hyperpop\npop-punk, electronic, metalcore\npop-punk, electronic, nu-metal\npop-punk, electronic, trance\npop-punk, electronic, trap\npop-punk, electronicore\npop-punk, electronicore, ambient\npop-punk, electronicore, dream pop\npop-punk, electronicore, dubstep\npop-punk, electronicore, emo\npop-punk, electronicore, metalcore\npop-punk, emo\npop-punk, emo rap\npop-punk, emo rock\npop-punk, emo rock, 8-bit\npop-punk, emo rock, hip-hop\npop-punk, emo rock, post-hardcore\npop-punk, emo rock, trap\npop-punk, emo, C-pop\npop-punk, emo, Chinese hip-hop\npop-punk, emo, Chinese rock\npop-punk, emo, J-rock\npop-punk, emo, aggressive\npop-punk, emo, alternative rock\npop-punk, emo, chiptune\npop-punk, emo, cinematic rock\npop-punk, emo, easycore\npop-punk, emo, electronic\npop-punk, emo, hardcore\npop-punk, emo, hip-hop\npop-punk, emo, hyperpop\npop-punk, emo, indie rock\npop-punk, emo, lo-fi\npop-punk, emo, math rock\npop-punk, emo, metal\npop-punk, emo, metalcore\npop-punk, emo, nu-metal\npop-punk, emo, post-hardcore\npop-punk, emo, post-rock\npop-punk, emo, punk rock\npop-punk, emo, rap-rock\npop-punk, emo, rock\npop-punk, emo-pop\npop-punk, emo-pop, Christmas\npop-punk, emo-pop, Mandarin rock\npop-punk, emo-pop, chiptune\npop-punk, emo-pop, electronicore\npop-punk, emo-pop, hip-hop\npop-punk, emo-pop, lo-fi\npop-punk, emo-pop, rap-rock\npop-punk, emo-pop, synth-punk\npop-punk, emo-pop, trap\npop-punk, emo-punk\npop-punk, emo-rap, electronic\npop-punk, emo-rap, rock\npop-punk, emo-rap, synth-rock\npop-punk, emo-rap, trap\npop-punk, emo-rock\npop-punk, emo-rock, C-pop\npop-punk, emo-rock, K-pop\npop-punk, emo-rock, hip-hop\npop-punk, emo-rock, metalcore\npop-punk, emotional ballad\npop-punk, experimental, electronic\npop-punk, flamenco rock, rap-rock\npop-punk, flamenco, K-pop\npop-punk, folk ballad\npop-punk, folk rock, sci-fi rock\npop-punk, folk, choral\npop-punk, folk, hip-hop\npop-punk, folk-pop\npop-punk, folk-pop, theatrical rock\npop-punk, forró, piseiro\npop-punk, funk, Latin pop\npop-punk, funk, electronic\npop-punk, funk, rock\npop-punk, future bass\npop-punk, future bass, cinematic\npop-punk, future bass, electronic\npop-punk, future bass, hardstyle\npop-punk, future bass, hyperpop\npop-punk, future bass, trap\npop-punk, garage rock\npop-punk, garage rock, ska-punk\npop-punk, garage rock, theatrical rock\npop-punk, geek-rock\npop-punk, gypsy jazz\npop-punk, happy hardcore\npop-punk, happy hardcore, EDM\npop-punk, happy hardcore, chiptune\npop-punk, happy hardcore, complextro\npop-punk, happy hardcore, dubstep\npop-punk, hard rock\npop-punk, hard rock, comedic\npop-punk, hard rock, rap rock\npop-punk, hard rock, surf-rock\npop-punk, hard rock, video game metal\npop-punk, hardcore punk\npop-punk, hardcore punk, pop-rock\npop-punk, hardstyle\npop-punk, heavy metal\npop-punk, hip hop, C-pop\npop-punk, hip hop, metalcore\npop-punk, hip-hop\npop-punk, hip-hop, C-pop\npop-punk, hip-hop, K-pop\npop-punk, hip-hop, Mandarin rock\npop-punk, hip-hop, acoustic ballad\npop-punk, hip-hop, alternative\npop-punk, hip-hop, alternative rock\npop-punk, hip-hop, atmospheric rock\npop-punk, hip-hop, chiptune\npop-punk, hip-hop, cinematic\npop-punk, hip-hop, cinematic rock\npop-punk, hip-hop, dream-pop\npop-punk, hip-hop, electronic\npop-punk, hip-hop, emotional\npop-punk, hip-hop, emotional pop\npop-punk, hip-hop, funk-pop\npop-punk, hip-hop, lo-fi\npop-punk, hip-hop, rock\npop-punk, holiday, experimental\npop-punk, horror punk\npop-punk, horror-carnival, synth\npop-punk, hyperpop\npop-punk, hyperpop, J-rock\npop-punk, hyperpop, chiptune\npop-punk, hyperpop, easycore\npop-punk, hyperpop, electronic\npop-punk, hyperpop, electronic dance\npop-punk, hyperpop, electronicore\npop-punk, hyperpop, emo\npop-punk, hyperpop, emo-rap\npop-punk, hyperpop, emo-rock\npop-punk, hyperpop, emo-trap\npop-punk, hyperpop, math rock\npop-punk, hyperpop, musical theater\npop-punk, hyperpop, nightcore\npop-punk, hyperpop, rap-rock\npop-punk, hyperpop, trap\npop-punk, indie rock\npop-punk, indie rock, K-pop\npop-punk, indie rock, lo-fi hip hop\npop-punk, indie-pop\npop-punk, industrial metalcore\npop-punk, industrial rock\npop-punk, industrial, electronic\npop-punk, island pop, J-pop\npop-punk, jazz lounge, hip hop\npop-punk, lo-fi hip hop, C-pop\npop-punk, lo-fi hip hop, K-pop\npop-punk, lo-fi hip hop, rap rock\npop-punk, lo-fi indie folk\npop-punk, lo-fi, C-pop\npop-punk, lo-fi, Chinese hip hop\npop-punk, lo-fi, EDM\npop-punk, lo-fi, J-rock\npop-punk, lo-fi, K-pop\npop-punk, lo-fi, chiptune\npop-punk, lo-fi, hyperpop\npop-punk, lo-fi, indie rock\npop-punk, lo-fi, metalcore\npop-punk, lo-fi, rock\npop-punk, lo-fi, ska\npop-punk, lo-fi, vaporwave\npop-punk, math rock, Spanish rock\npop-punk, math rock, emo\npop-punk, math rock, hip-hop\npop-punk, math rock, metalcore\npop-punk, math-rock\npop-punk, math-rock, dream pop\npop-punk, melodic hardcore\npop-punk, melodic metalcore\npop-punk, metalcore\npop-punk, metalcore, Broadway\npop-punk, metalcore, C-pop\npop-punk, metalcore, Chinese rock\npop-punk, metalcore, Christmas\npop-punk, metalcore, Christmas ballad\npop-punk, metalcore, German\npop-punk, metalcore, JRPG\npop-punk, metalcore, Latin pop\npop-punk, metalcore, Latin pop-rock, power-ballad\npop-punk, metalcore, Mandarin rock\npop-punk, metalcore, acoustic\npop-punk, metalcore, acoustic ballad\npop-punk, metalcore, alternative\npop-punk, metalcore, alternative rock\npop-punk, metalcore, ambient\npop-punk, metalcore, atmospheric\npop-punk, metalcore, chiptune\npop-punk, metalcore, cinematic\npop-punk, metalcore, cinematic rock\npop-punk, metalcore, dream pop\npop-punk, metalcore, easycore\npop-punk, metalcore, electronic\npop-punk, metalcore, electronicore\npop-punk, metalcore, emo\npop-punk, metalcore, emo-rock\npop-punk, metalcore, emotional rock\npop-punk, metalcore, ethereal\npop-punk, metalcore, flamenco\npop-punk, metalcore, lo-fi\npop-punk, metalcore, math rock\npop-punk, metalcore, post-hardcore\npop-punk, metalcore, rap rock\npop-punk, metalcore, rock\npop-punk, metalcore, screamo\npop-punk, metalcore, shred guitar\npop-punk, metalcore, skate-punk\npop-punk, metalcore, soft rock\npop-punk, metalcore, synth pop\npop-punk, metalcore, synth-pop\npop-punk, metalcore, trap\npop-punk, metalcore, video game soundtrack\npop-punk, musical theater\npop-punk, musical theater, Christmas\npop-punk, musical theater, hip-hop\npop-punk, musical theater, synth-pop\npop-punk, nerdcore, anime theme\npop-punk, nerdcore, chiptune\npop-punk, new wave\npop-punk, nintendocore\npop-punk, nu-metal\npop-punk, nu-metal, C-pop\npop-punk, nu-metal, alt-rock\npop-punk, nu-metal, anthemic\npop-punk, nu-metal, cinematic\npop-punk, nu-metal, electronic\npop-punk, nu-metal, emo-rap\npop-punk, nu-metal, hyperpop\npop-punk, nu-metal, lo-fi\npop-punk, nu-metal, rap-rock\npop-punk, nu-metal, rock\npop-punk, nu-metal, trap\npop-punk, pop-rock, indie rock\npop-punk, post-grunge\npop-punk, post-hardcore\npop-punk, post-hardcore, chiptune\npop-punk, post-hardcore, cinematic\npop-punk, post-hardcore, cinematic rock\npop-punk, post-hardcore, electronic\npop-punk, post-hardcore, electronicore\npop-punk, post-hardcore, emo\npop-punk, post-hardcore, emo-pop\npop-punk, post-hardcore, industrial\npop-punk, post-hardcore, lo-fi\npop-punk, post-hardcore, math rock\npop-punk, post-hardcore, metalcore\npop-punk, post-hardcore, rap-rock\npop-punk, post-hardcore, rock\npop-punk, post-hardcore, shoegaze\npop-punk, post-hardcore, trap\npop-punk, post-rock\npop-punk, post-rock, alternative\npop-punk, post-rock, cinematic\npop-punk, post-rock, hip-hop\npop-punk, post-rock, metalcore\npop-punk, post-rock, spoken word\npop-punk, power ballad\npop-punk, power metal\npop-punk, power-pop\npop-punk, power-pop, indie rock\npop-punk, progressive house\npop-punk, progressive house, lo-fi\npop-punk, progressive rock, chiptune\npop-punk, punk rock, a cappella\npop-punk, punk rock, musical theater\npop-punk, punk rock, ska-punk\npop-punk, rap rock, Russian vocal\npop-punk, rap rock, metalcore\npop-punk, rap, metalcore, soul\npop-punk, rap, punk\npop-punk, rap, vaporwave\npop-punk, rap-metal\npop-punk, rap-rock\npop-punk, rap-rock, C-pop\npop-punk, rap-rock, J-pop\npop-punk, rap-rock, K-pop\npop-punk, rap-rock, Mandarin\npop-punk, rap-rock, R&B\npop-punk, rap-rock, acoustic\npop-punk, rap-rock, alternative\npop-punk, rap-rock, ambient\npop-punk, rap-rock, atmospheric\npop-punk, rap-rock, atmospheric rock\npop-punk, rap-rock, chiptune\npop-punk, rap-rock, cinematic\npop-punk, rap-rock, cinematic rock\npop-punk, rap-rock, dream pop\npop-punk, rap-rock, electronic\npop-punk, rap-rock, emo\npop-punk, rap-rock, emo-rock\npop-punk, rap-rock, emotional rock\npop-punk, rap-rock, glitch\npop-punk, rap-rock, indie\npop-punk, rap-rock, lo-fi\npop-punk, rap-rock, metalcore\npop-punk, rap-rock, nu-metal\npop-punk, rap-rock, punk\npop-punk, rap-rock, synth-pop\npop-punk, rap-rock, synth-punk\npop-punk, rap-rock, theatrical\npop-punk, reggae\npop-punk, reggae, lo-fi acoustic\npop-punk, reggaeton, dream pop\npop-punk, rock opera, cinematic\npop-punk, rock, cinematic\npop-punk, rock, hip-hop\npop-punk, rock, rap-rock\npop-punk, samba, funk rock\npop-punk, samba-rock\npop-punk, satirical, Christmas\npop-punk, shoegaze, indie rock\npop-punk, shoegaze, post-hardcore\npop-punk, ska, German\npop-punk, ska, brass band\npop-punk, ska, funk\npop-punk, ska, hard rock\npop-punk, ska, punk rock\npop-punk, ska, rap rock\npop-punk, ska, rock\npop-punk, ska-punk\npop-punk, ska-punk, Italian pop\npop-punk, ska-punk, emo\npop-punk, ska-punk, epic folk\npop-punk, ska-punk, punk rock\npop-punk, ska-punk, rap-rock\npop-punk, skate punk\npop-punk, skate punk, Christmas\npop-punk, skate punk, cinematic\npop-punk, skate punk, easycore\npop-punk, skate punk, emo\npop-punk, skate punk, holiday\npop-punk, skate punk, indie rock\npop-punk, skate punk, metal\npop-punk, skate punk, metalcore\npop-punk, skate punk, rap-rock\npop-punk, skate punk, ska-punk\npop-punk, skate punk, video game\npop-punk, skate-punk\npop-punk, skate-punk, cabaret\npop-punk, sludge-punk, metalcore\npop-punk, southern rock\npop-punk, surf rock\npop-punk, synth pop, emotional rock\npop-punk, synth, chiptune\npop-punk, synth, comedic\npop-punk, synth-pop\npop-punk, synth-pop, J-pop\npop-punk, synth-pop, J-rock\npop-punk, synth-pop, electronic\npop-punk, synth-pop, emotional rock\npop-punk, synth-punk\npop-punk, synth-punk, bitpop\npop-punk, tango, rock\npop-punk, theatrical pop, synth rock\npop-punk, theatrical rock\npop-punk, theatrical rock, cinematic\npop-punk, theatrical rock, rap-rock\npop-punk, theatrical, cinematic\npop-punk, trap R&B\npop-punk, trap metal\npop-punk, trap metal, dubstep\npop-punk, trap, C-pop\npop-punk, trap, Mandarin rock\npop-punk, trap, acoustic\npop-punk, trap, ambient\npop-punk, trap, emo-rock\npop-punk, trap, future bass\npop-punk, trap, hip hop\npop-punk, trap, hip-hop\npop-punk, trap, hyperpop\npop-punk, trap, melodic rap\npop-punk, trap, operatic\npop-punk, trap, rock\npop-punk, vaporwave, C-pop\npop-punk, vaporwave, hip-hop\npop-punk, video game music\npop-punk, video game rock\npop-punk, video game, Christmas\npop-punk, video game, chiptune\npop-r&b\npop-r&b afrobeat\npop-r&b afrobeats\npop-r&b bollywood bhangra\npop-r&b chiptune\npop-r&b cinematic\npop-r&b dance-pop\npop-r&b dancehall\npop-r&b dubstep\npop-r&b electronic\npop-r&b emo-rap\npop-r&b funk\npop-r&b future bass\npop-r&b hip-hop\npop-r&b hip-hop electronic\npop-r&b hip-hop future bass\npop-r&b hip-hop k-pop\npop-r&b island pop\npop-r&b lo-fi\npop-r&b lo-fi hip hop\npop-r&b lo-fi hip-hop\npop-r&b reggaeton\npop-r&b trap\npop-r&b trap hip-hop\npop-r&b trap-soul\npop-r&b tropical\npop-r&b vaporwave\npop-r&b, bollywood fusion, early 2000s pop\npop-r&b, brazilian funk, trap\npop-r&b, brazilian phonk\npop-r&b, chill, trap\npop-r&b, chinese hip hop\npop-r&b, chiptune, bilingual\npop-r&b, chiptune, electronic\npop-r&b, chiptune, uk garage\npop-r&b, cinematic pop, modern rock\npop-r&b, cinematic, balkan pop\npop-r&b, cinematic, electronic\npop-r&b, cinematic, lo-fi hip hop\npop-r&b, cinematic, oriental fusion\npop-r&b, cinematic, trap\npop-r&b, dance-pop\npop-r&b, dancehall\npop-r&b, dancehall, bilingual\npop-r&b, deep house, uk garage\npop-r&b, dream pop, hip-hop\npop-r&b, dubstep, atmospheric\npop-r&b, dubstep, electronic\npop-r&b, early 2000s\npop-r&b, early 2000s hip-hop\npop-r&b, early 2000s, hip-hop\npop-r&b, edm, trap\npop-r&b, electronic, dance\npop-r&b, electronic, indie rock\npop-r&b, emo-pop, trap\npop-r&b, euro-pop\npop-r&b, future bass\npop-r&b, future bass, South Asian fusion\npop-r&b, future bass, lo-fi\npop-r&b, future bass, trap\npop-r&b, future bass, vaporwave\npop-r&b, future bass, world music\npop-r&b, glitch, electronic\npop-r&b, gospel, hip-hop\npop-r&b, hardstyle, dubstep\npop-r&b, hip hop, atmospheric\npop-r&b, hip-hop\npop-r&b, hip-hop, aggressive\npop-r&b, hip-hop, bilingual\npop-r&b, hip-hop, cinematic\npop-r&b, hip-hop, dream pop\npop-r&b, hip-hop, electronic\npop-r&b, hip-hop, gospel\npop-r&b, hip-hop, jazz\npop-r&b, hip-hop, latin pop\npop-r&b, hip-hop, modern\npop-r&b, hip-hop, soul\npop-r&b, hip-hop, synthwave\npop-r&b, hip-hop, traditional fusion\npop-r&b, hyperpop\npop-r&b, late-90s, early-2000s\npop-r&b, latin pop, trap\npop-r&b, latin-pop, electronic\npop-r&b, lo-fi hip hop\npop-r&b, lo-fi hip hop, Russian rap\npop-r&b, lo-fi hip hop, modern R&B\npop-r&b, lo-fi hip-hop\npop-r&b, lo-fi, future bass\npop-r&b, lo-fi, latin pop\npop-r&b, moombahton\npop-r&b, moombahton, trap\npop-r&b, neo-soul, hip-hop\npop-r&b, new jack swing\npop-r&b, nu-metal, lo-fi\npop-r&b, pop-punk\npop-r&b, pop-rock\npop-r&b, reggaeton\npop-r&b, reggaeton, arabic pop\npop-r&b, retro-funk\npop-r&b, rock, atmospheric\npop-r&b, spanish style, trap\npop-r&b, trap\npop-r&b, trap, North African\npop-r&b, trap, afrobeats\npop-r&b, trap, ambient\npop-r&b, trap, bilingual\npop-r&b, trap, chinese rap\npop-r&b, trap, cinematic\npop-r&b, trap, contemporary\npop-r&b, trap, dreamy\npop-r&b, trap, dreamy synth\npop-r&b, trap, electronic\npop-r&b, trap, emotional ballad\npop-r&b, trap, filipino\npop-r&b, trap, flamenco\npop-r&b, trap, future bass\npop-r&b, trap, futuristic\npop-r&b, trap, hip-hop\npop-r&b, trap, hyperpop\npop-r&b, trap, indian pop\npop-r&b, trap, latin\npop-r&b, trap, latin pop\npop-r&b, trap, lo-fi\npop-r&b, trap, lo-fi hip hop\npop-r&b, trap, mandopop\npop-r&b, trap, modern\npop-r&b, trap, reggaeton\npop-r&b, trap, synth-pop\npop-r&b, trap, synthpop\npop-r&b, trap, vaporwave\npop-r&b, trap, world music\npop-r&b, trap-pop, bilingual\npop-r&b, trap-pop, world music\npop-r&b, uk hip-hop, modern hip-hop\npop-r&b, vaporwave, electronic\npop-r&b, vaporwave, trap\npop-rai\npop-rap\npop-rap 90s R&B\npop-rap 90s throwback\npop-rap C-pop\npop-rap C-pop ballad\npop-rap C-pop bilingual\npop-rap EDM\npop-rap J-pop\npop-rap J-pop anime\npop-rap K-hip-hop\npop-rap Latin\npop-rap Mandopop\npop-rap Nordic\npop-rap R&B\npop-rap R&B cinematic\npop-rap R&B hip-hop\npop-rap R&B lo-fi hip-hop\npop-rap a cappella\npop-rap acoustic\npop-rap acoustic folk\npop-rap afro-trap\npop-rap afrobeat\npop-rap afrobeats trap\npop-rap alternative R&B\npop-rap alternative hip-hop\npop-rap alternative pop\npop-rap alternative rock\npop-rap ambient\npop-rap arena rock\npop-rap ballad\npop-rap boom-bap\npop-rap chiptune\npop-rap chiptune J-pop\npop-rap chiptune J-rock\npop-rap chiptune electro-pop\npop-rap chiptune reggaeton\npop-rap chiptune synth-pop\npop-rap chiptune trap\npop-rap cinematic\npop-rap city pop\npop-rap cloud rap\npop-rap dancehall\npop-rap deep house\npop-rap dembow\npop-rap dream pop\npop-rap dream-pop\npop-rap electro-funk\npop-rap electronic\npop-rap electronic rock\npop-rap emo-rap\npop-rap emo-trap\npop-rap emotional R&B\npop-rap emotional hip-hop\npop-rap emotional pop\npop-rap eurodance\npop-rap flamenco\npop-rap folk\npop-rap funk\npop-rap funk R&B\npop-rap funk ska\npop-rap future bass\npop-rap future bass trap\npop-rap gospel\npop-rap gospel R&B\npop-rap house\npop-rap indie pop\npop-rap indie rock\npop-rap inspirational hip-hop\npop-rap introspective hip-hop\npop-rap lo-fi hip hop\npop-rap lo-fi hip-hop\npop-rap lo-fi hip-hop chiptune\npop-rap mandopop\npop-rap melodic hip-hop\npop-rap narrative hip-hop\npop-rap neo-funk chiptune\npop-rap neo-soul\npop-rap nu-disco funk\npop-rap reggae\npop-rap reggae dancehall\npop-rap reggaeton\npop-rap rock\npop-rap satire\npop-rap sentimental\npop-rap sentimental R&B\npop-rap sentimental ballad\npop-rap sentimental hip-hop\npop-rap sentimental pop\npop-rap smooth jazz\npop-rap synth-pop\npop-rap trap\npop-rap trap R&B\npop-rap tropical\npop-rap tropical house\npop-rap vaporwave\npop-rap world music\npop-rap, 2000s style, Vietnamese pop\npop-rap, 90s R&B, hip-hop\npop-rap, Afro-pop, electronic\npop-rap, Asian folk, electronic\npop-rap, Balkan pop\npop-rap, Balkan, dance\npop-rap, Balkan, hip-hop\npop-rap, Balkan, modern\npop-rap, Balkan, trap\npop-rap, Bollywood pop\npop-rap, Bollywood, electronic\npop-rap, Bollywood, hip-hop\npop-rap, Bollywood, upbeat\npop-rap, Brazilian funk\npop-rap, Brazilian funk, digital piano\npop-rap, Brazilian funk, lo-fi\npop-rap, Brazilian funk, lo-fi hip hop\npop-rap, Brazilian funk, modern pop\npop-rap, C-pop\npop-rap, C-pop, electronic\npop-rap, C-pop, hip-hop\npop-rap, C-pop, modern hip-hop\npop-rap, C-pop, traditional fusion\npop-rap, C-pop, trap\npop-rap, California vibe, upbeat\npop-rap, Cantonese hip-hop, cinematic pop\npop-rap, Central Asian folk\npop-rap, Central Asian, modern\npop-rap, Desi pop, hip-hop\npop-rap, Deutschrap, synth-pop\npop-rap, EDM\npop-rap, EDM, Dutch hip hop\npop-rap, EDM, Indonesian pop\npop-rap, EDM, Norwegian party\npop-rap, EDM, anthemic\npop-rap, EDM, ballad\npop-rap, EDM, dance\npop-rap, EDM, dancehall\npop-rap, EDM, electronic\npop-rap, EDM, future bass\npop-rap, EDM, hip-hop\npop-rap, EDM, progressive house\npop-rap, EDM, sports anthem\npop-rap, EDM, synth-pop\npop-rap, EDM, trap\npop-rap, EDM, upbeat\npop-rap, Eastern European pop\npop-rap, Eastern European, chiptune\npop-rap, Eastern European, cinematic\npop-rap, Euro-pop, early 2000s\npop-rap, Euro-pop, late-90s\npop-rap, Eurodance, Central Asian\npop-rap, European folk, nostalgic\npop-rap, Filipino hip-hop, melodic hip-hop\npop-rap, French pop, indie pop\npop-rap, G-funk, summer pop\npop-rap, Indian fusion, electronic\npop-rap, Indonesian pop\npop-rap, Indonesian pop, R&B\npop-rap, Indonesian, upbeat\npop-rap, J-pop, anime\npop-rap, J-pop, hip-hop\npop-rap, K-ballad, acoustic\npop-rap, K-pop, J-pop\npop-rap, K-pop, Tibetan pop\npop-rap, K-pop, electronic\npop-rap, K-pop, upbeat\npop-rap, Khmer pop\npop-rap, Latin pop\npop-rap, Latin pop, Scandinavian hip-hop\npop-rap, Latin pop, Swedish hip-hop\npop-rap, Latin pop, afrobeat\npop-rap, Latin pop, bilingual\npop-rap, Latin pop, electronic\npop-rap, Latin pop, trap\npop-rap, Latin pop, upbeat\npop-rap, Latin, world music\npop-rap, Malaysian festive\npop-rap, Malaysian pop\npop-rap, Mandarin pop, rock\npop-rap, Mediterranean fusion\npop-rap, Middle Eastern fusion\npop-rap, Middle Eastern, Kurdish\npop-rap, Middle Eastern, Turkish\npop-rap, Middle Eastern, bilingual\npop-rap, Middle Eastern, electronic\npop-rap, Middle Eastern, upbeat\npop-rap, North African fusion\npop-rap, North African, Middle Eastern\npop-rap, North African, football anthem\npop-rap, North African, groove\npop-rap, OPM\npop-rap, OPM, lo-fi hip-hop\npop-rap, R&B\npop-rap, R&B, Afrobeat\npop-rap, R&B, C-pop\npop-rap, R&B, Central Asian\npop-rap, R&B, Chinese pop\npop-rap, R&B, German pop\npop-rap, R&B, Mandarin pop\npop-rap, R&B, Swedish party\npop-rap, R&B, Thai hip-hop\npop-rap, R&B, afrobeat\npop-rap, R&B, ambient\npop-rap, R&B, atmospheric electronic\npop-rap, R&B, bilingual\npop-rap, R&B, cinematic\npop-rap, R&B, club\npop-rap, R&B, early 2000s\npop-rap, R&B, electronic\npop-rap, R&B, hip-hop\npop-rap, R&B, lo-fi hip hop\npop-rap, R&B, lo-fi hip-hop\npop-rap, R&B, melodic rap\npop-rap, R&B, retro synth\npop-rap, R&B, synth-pop\npop-rap, R&B, trap\npop-rap, R&B, tropical house\npop-rap, R&B, video game music\npop-rap, Rai, Spanish indie\npop-rap, Rai, electronic\npop-rap, Rai, reggaeton\npop-rap, Romanian Manele, trap\npop-rap, South Asian fusion\npop-rap, South Indian film music, R&B\npop-rap, South Indian pop, Bollywood\npop-rap, South Indian pop, global R&B\npop-rap, South Indian, multilingual\npop-rap, Southeast Asian fusion, reggae\npop-rap, Southeast Asian pop\npop-rap, Swedish hip-hop, R&B\npop-rap, Thai pop, trap\npop-rap, Turkish, melancholic\npop-rap, UK garage, anthemic\npop-rap, UK grime, electronic\npop-rap, West Coast, anthemic\npop-rap, West Coast, laid-back\npop-rap, Y2K, electronic\npop-rap, acoustic pop, Russian hip-hop\npop-rap, acoustic, trap\npop-rap, afrobeat, multi-lingual\npop-rap, alt-rock\npop-rap, ambient, cinematic\npop-rap, anime style\npop-rap, anime, lo-fi hip-hop\npop-rap, anthemic, C-pop\npop-rap, anthemic, trap\npop-rap, atmospheric R&B\npop-rap, atmospheric pop\npop-rap, atmospheric, EDM\npop-rap, atmospheric, cinematic\npop-rap, atmospheric, emotional\npop-rap, atmospheric, lo-fi\npop-rap, atmospheric, melancholic\npop-rap, ballad, hip-hop\npop-rap, bhangra, trap\npop-rap, bilingual, electronic\npop-rap, bilingual, upbeat\npop-rap, boom-bap, C-pop\npop-rap, boom-bap, cinematic\npop-rap, boom-bap, quirky\npop-rap, chill, summery\npop-rap, chiptune\npop-rap, chiptune, Arabic pop\npop-rap, chiptune, J-pop\npop-rap, chiptune, Tamil pop\npop-rap, chiptune, bilingual\npop-rap, chiptune, electronic\npop-rap, chiptune, funk\npop-rap, chiptune, lo-fi hip-hop\npop-rap, chiptune, synth-pop\npop-rap, chiptune, trap\npop-rap, cinematic pop, emo rock\npop-rap, cinematic pop, female rapper\npop-rap, cinematic soul, French indie\npop-rap, cinematic, Asian fusion\npop-rap, cinematic, Central Asian folk\npop-rap, cinematic, Eastern European\npop-rap, cinematic, French soul\npop-rap, cinematic, K-pop\npop-rap, cinematic, Mandarin hip-hop\npop-rap, cinematic, Vietnamese\npop-rap, cinematic, a cappella\npop-rap, cinematic, ambient\npop-rap, cinematic, anime\npop-rap, cinematic, anthemic\npop-rap, cinematic, ballad\npop-rap, cinematic, bilingual\npop-rap, cinematic, classical\npop-rap, cinematic, emotional\npop-rap, cinematic, futuristic\npop-rap, cinematic, heroic\npop-rap, cinematic, high-energy\npop-rap, cinematic, hip-hop\npop-rap, cinematic, lo-fi\npop-rap, cinematic, melancholic\npop-rap, cinematic, modern\npop-rap, cinematic, multi-lingual\npop-rap, cinematic, nu-metal\npop-rap, cinematic, orchestral\npop-rap, cinematic, rock\npop-rap, cinematic, trap\npop-rap, cinematic, world fusion\npop-rap, city pop, new jack swing\npop-rap, city pop, nu-disco\npop-rap, comedic, cinematic\npop-rap, comedic, klezmer\npop-rap, comedic, satirical\npop-rap, conscious hip-hop\npop-rap, contemporary R&B\npop-rap, contemporary R&B, C-pop\npop-rap, contemporary R&B, trap\npop-rap, cross-cultural, electronic\npop-rap, dance, Sinhala\npop-rap, dance-pop\npop-rap, dance-pop, Bhangra\npop-rap, dance-pop, global hip-hop\npop-rap, dance-pop, trap\npop-rap, dancehall, Italian pop\npop-rap, dancehall, Middle Eastern fusion\npop-rap, dancehall, bilingual\npop-rap, dancehall, reggaeton\npop-rap, dancehall, theatrical\npop-rap, dancehall, trap\npop-rap, doo-wop, funk\npop-rap, dream pop, Indonesian pop\npop-rap, dreamy, cinematic\npop-rap, early 2000s R&B\npop-rap, early 2000s R&B, Cantopop\npop-rap, early 2000s, Indian fusion\npop-rap, early 2000s, Mandarin hip-hop\npop-rap, early 2000s, Southeast Asian\npop-rap, early 2000s, anthemic\npop-rap, early 2000s, bilingual\npop-rap, early 2000s, cinematic\npop-rap, early 2000s, funk\npop-rap, early 2000s, multi-lingual\npop-rap, early 2000s, satirical\npop-rap, early 2000s, upbeat\npop-rap, electronic dance music\npop-rap, electronic dance, K-pop\npop-rap, electronic dance, hip-hop\npop-rap, electronic dance, summer anthem\npop-rap, electronic pop, gospel\npop-rap, electronic, Balkan\npop-rap, electronic, C-pop\npop-rap, electronic, German hip hop\npop-rap, electronic, Indian pop\npop-rap, electronic, K-pop\npop-rap, electronic, Middle Eastern pop\npop-rap, electronic, anthemic\npop-rap, electronic, bilingual\npop-rap, electronic, chiptune\npop-rap, electronic, cinematic\npop-rap, electronic, hip-hop\npop-rap, electronic, multilingual\npop-rap, electronic, trap\npop-rap, emo-rock, cinematic pop\npop-rap, emo-rock, lo-fi\npop-rap, emotional R&B\npop-rap, emotional ballad\npop-rap, emotional ballad, C-pop\npop-rap, emotional ballad, French pop\npop-rap, emotional ballad, bilingual\npop-rap, emotional electronic\npop-rap, emotional rock, cinematic ballad\npop-rap, emotional trap\npop-rap, euro-pop, late-90s\npop-rap, eurodance, early 2000s\npop-rap, feel-good hip-hop\npop-rap, festive, Sundanese\npop-rap, folk pop, polka\npop-rap, funk hip-hop\npop-rap, funk, European pop\npop-rap, funk, R&B\npop-rap, funk, city pop\npop-rap, funk, electronic\npop-rap, funk, musical theater\npop-rap, funk, retro\npop-rap, funk, world music\npop-rap, future bass, big room house\npop-rap, future bass, bilingual\npop-rap, future bass, emotional ballad\npop-rap, future bass, trap\npop-rap, global pop, electronic\npop-rap, gospel, EDM\npop-rap, gospel, K-pop\npop-rap, gospel, modern pop\npop-rap, hardstyle, dubstep\npop-rap, hip-hop, Balkan\npop-rap, hip-hop, G-funk\npop-rap, hip-hop, bilingual\npop-rap, hip-hop, lo-fi\npop-rap, hip-hop, multilingual\npop-rap, hip-hop, rock\npop-rap, house, EDM\npop-rap, hyperpop\npop-rap, industrial metal, ambient\npop-rap, lo-fi hip hop, theatrical\npop-rap, lo-fi hip-hop\npop-rap, lo-fi hip-hop, C-pop\npop-rap, lo-fi hip-hop, R&B\npop-rap, lo-fi hip-hop, bilingual\npop-rap, lo-fi hip-hop, emotional\npop-rap, lo-fi hip-hop, emotional ballad\npop-rap, lo-fi hip-hop, melancholic\npop-rap, lo-fi hip-hop, sentimental\npop-rap, lo-fi hip-hop, sentimental ballad\npop-rap, lo-fi, Italian hip-hop\npop-rap, lo-fi, melancholic\npop-rap, lo-fi, trap\npop-rap, melancholic, Central Asian\npop-rap, melancholic, Eastern-influenced\npop-rap, melancholic, atmospheric\npop-rap, melancholic, ballad\npop-rap, melancholic, bilingual\npop-rap, melancholic, cinematic\npop-rap, modern trap\npop-rap, modern, Southeast Asian\npop-rap, modern, multi-lingual\npop-rap, moombahton, cinematic\npop-rap, musical theater, upbeat\npop-rap, new jack swing\npop-rap, new jack swing, upbeat\npop-rap, oriental synth, bilingual\npop-rap, patriotic, blues-rock\npop-rap, pop-punk\npop-rap, pop-punk, ambient\npop-rap, pop-rock\npop-rap, pop-rock, C-pop\npop-rap, pop-rock, cinematic\npop-rap, pop-rock, funk\npop-rap, pop-rock, shred guitar\npop-rap, quirky, upbeat\npop-rap, ragtime, hip-hop\npop-rap, reggaeton, Czech\npop-rap, reggaeton, French pop\npop-rap, reggaeton, Latin\npop-rap, reggaeton, Latin pop\npop-rap, reggaeton, Middle Eastern\npop-rap, reggaeton, Southeast Asian\npop-rap, reggaeton, bilingual\npop-rap, reggaeton, chiptune\npop-rap, reggaeton, cloud rap\npop-rap, reggaeton, comedic\npop-rap, reggaeton, dancehall\npop-rap, reggaeton, dreamy\npop-rap, reggaeton, electronic\npop-rap, reggaeton, late-90s pop\npop-rap, reggaeton, lo-fi\npop-rap, reggaeton, moombahton\npop-rap, reggaeton, multi-lingual\npop-rap, reggaeton, upbeat\npop-rap, reggaeton-lite, summer pop\npop-rap, retro funk, hip-hop\npop-rap, romantic R&B, German pop\npop-rap, sample-based hip-hop\npop-rap, schlager, comedic\npop-rap, sentimental C-pop\npop-rap, sentimental ballad\npop-rap, smooth jazz, Bengali pop\npop-rap, soul, cinematic\npop-rap, stadium rock\npop-rap, synth-pop\npop-rap, synth-pop, Chinese hip-hop\npop-rap, synth-pop, atmospheric\npop-rap, synth-pop, chiptune\npop-rap, synth-pop, electronic\npop-rap, synth-pop, hip-hop\npop-rap, theatrical, funk\npop-rap, theatrical, piano ballad\npop-rap, theatrical, video game\npop-rap, traditional East Asian, cinematic\npop-rap, trap R&B\npop-rap, trap, Bollywood\npop-rap, trap, Brazilian funk\npop-rap, trap, C-pop\npop-rap, trap, Desi hip-hop\npop-rap, trap, EDM\npop-rap, trap, European\npop-rap, trap, Filipino hip hop\npop-rap, trap, Italian hip hop\npop-rap, trap, K-pop\npop-rap, trap, Mandarin pop\npop-rap, trap, Middle Eastern\npop-rap, trap, North African\npop-rap, trap, Punjabi pop\npop-rap, trap, R&B\npop-rap, trap, South Asian pop\npop-rap, trap, Tamil pop\npop-rap, trap, afrobeat\npop-rap, trap, ambient\npop-rap, trap, anthemic\npop-rap, trap, atmospheric\npop-rap, trap, bilingual\npop-rap, trap, bilingual hip-hop\npop-rap, trap, chiptune\npop-rap, trap, cinematic\npop-rap, trap, comedic\npop-rap, trap, contemporary hip-hop\npop-rap, trap, electronic\npop-rap, trap, emo-rap\npop-rap, trap, future bass\npop-rap, trap, futuristic\npop-rap, trap, hip-hop\npop-rap, trap, hyperpop\npop-rap, trap, lo-fi\npop-rap, trap, lo-fi ambient\npop-rap, trap, party\npop-rap, trap, psychedelic\npop-rap, trap, reggaeton\npop-rap, trap, satirical\npop-rap, trap, soul\npop-rap, trap, summer\npop-rap, trap, summer pop\npop-rap, trap, summer vibe\npop-rap, trap, upbeat\npop-rap, tribal, empowering\npop-rap, tropical house, dancehall\npop-rap, upbeat, EDM\npop-rap, vaporwave, trap\npop-rap, world music\npop-rap, world music, Middle Eastern\npop-rap, world music, chiptune\npop-raï\npop-raï, French hip-hop\npop-reggae\npop-reggae 80s\npop-reggae bossa nova\npop-reggae chiptune\npop-reggae dance-pop\npop-reggae dancehall\npop-reggae funk\npop-reggae hip-hop\npop-reggae jazz\npop-reggae latin pop\npop-reggae lovers rock\npop-reggae rock\npop-reggae ska\npop-reggae, Brazilian, upbeat\npop-reggae, Latin hip-hop\npop-reggae, R&B\npop-reggae, South Asian, romantic\npop-reggae, cinematic, Indian fusion\npop-reggae, hip-hop\npop-reggaeton\npop-reggaeton chiptune\npop-reggaeton future bass\npop-reggaeton, Balkan pop\npop-reggaeton, R&B\npop-reggaeton, future bass, trap\npop-reggaeton, future bass, tropical house\npop-reggaeton, hardstyle\npop-reggaeton, hardstyle, psytrance\npop-rock\npop-rock 70s\npop-rock 8-bit\npop-rock 80s\npop-rock 80s Bollywood\npop-rock 80s European\npop-rock 80s adult contemporary\npop-rock 80s anime\npop-rock 80s nostalgic\npop-rock 80s revival\npop-rock 80s synth\npop-rock 90s\npop-rock 90s R&B\npop-rock 90s alternative\npop-rock Afrikaans rock\npop-rock Afro-Cuban\npop-rock Afro-Latin\npop-rock Afrobeat\npop-rock Afrobeat R&B\npop-rock Anatolian rock\npop-rock Arabic\npop-rock Balkan\npop-rock Balkan chanson\npop-rock Balkan folk\npop-rock Balkan pop\npop-rock Balkan rock\npop-rock Bollywood\npop-rock C-pop\npop-rock C-pop J-rock\npop-rock C-pop anime\npop-rock C-pop folk\npop-rock C-pop upbeat\npop-rock Celtic\npop-rock Christian\npop-rock Christian contemporary\npop-rock Christian worship\npop-rock Christmas\npop-rock EDM\npop-rock European\npop-rock Europop\npop-rock French chanson\npop-rock Indian\npop-rock Indian film music\npop-rock Indian folk\npop-rock Indian fusion\npop-rock Indian influence\npop-rock Islamic\npop-rock Islamic devotional\npop-rock J-Rock\npop-rock J-pop\npop-rock J-pop K-pop\npop-rock J-pop R&B\npop-rock J-pop anime\npop-rock J-pop whimsical\npop-rock J-rock\npop-rock J-rock C-pop\npop-rock J-rock K-rock\npop-rock J-rock anime\npop-rock J-rock rap\npop-rock Javanese\npop-rock Javanese pop\npop-rock K-drama OST\npop-rock K-pop\npop-rock K-pop J-rock\npop-rock K-pop electronic\npop-rock K-pop hip-hop\npop-rock K-rock\npop-rock Kollywood\npop-rock Latin\npop-rock Latin Afrikaans folk\npop-rock Latin Bossa Nova\npop-rock Latin Mediterranean\npop-rock Latin Middle Eastern\npop-rock Latin big band\npop-rock Latin dance\npop-rock Latin flamenco\npop-rock Latin folk\npop-rock Latin fusion\npop-rock Latin lounge\npop-rock Latin pop\npop-rock Latin reggae\npop-rock Latin rock\npop-rock Latin tango\npop-rock Latin tropical\npop-rock MPB\npop-rock Mandopop\npop-rock Mizrahi\npop-rock R&B\npop-rock R&B gospel\npop-rock R&B jazz fusion\npop-rock R&B soul\npop-rock R&B trap\npop-rock Sundanese folk\npop-rock T-pop\npop-rock Tibetan\npop-rock Tollywood\npop-rock V-Pop\npop-rock adult contemporary\npop-rock afrobeats\npop-rock alt-rock\npop-rock alternative\npop-rock alternative electronic\npop-rock alternative emo\npop-rock alternative hip-hop\npop-rock alternative metal\npop-rock alternative rap-rock\npop-rock alternative rock\npop-rock americana\npop-rock anime\npop-rock anime ballad\npop-rock anime soundtrack\npop-rock anime theme\npop-rock arena rock\npop-rock ballad\npop-rock ballad, hard rock\npop-rock ballad, hard rock, power metal\npop-rock ballad, pop-dangdut\npop-rock baroque-pop\npop-rock big band\npop-rock big band schlager\npop-rock blues\npop-rock blues big band\npop-rock blues boogie-woogie\npop-rock blues country\npop-rock blues country-rock\npop-rock blues funk\npop-rock blues jazz\npop-rock blues lounge\npop-rock blues rock\npop-rock blues soul\npop-rock blues swing\npop-rock blues-rock\npop-rock boogie-woogie\npop-rock bossa nova\npop-rock bossa nova lounge\npop-rock cabaret\npop-rock cabaret boogie-woogie\npop-rock cabaret folk\npop-rock cabaret klezmer\npop-rock cabaret latin\npop-rock cabaret schlager\npop-rock cabaret sea shanty\npop-rock cabaret ska\npop-rock cabaret surf-rock\npop-rock cabaret swing\npop-rock cabaret tango\npop-rock calypso\npop-rock calypso exotica\npop-rock calypso lounge\npop-rock chalga\npop-rock chanson\npop-rock children's music\npop-rock chiptune\npop-rock chiptune J-pop\npop-rock chiptune J-rock\npop-rock chiptune Latin\npop-rock chiptune dangdut\npop-rock chiptune folk-dance\npop-rock chiptune klezmer\npop-rock chiptune nasyid\npop-rock chiptune polka\npop-rock chiptune ska\npop-rock cinematic\npop-rock city pop\npop-rock city pop jazz-fusion\npop-rock city-pop\npop-rock classical\npop-rock classical fusion\npop-rock contemporary Christian\npop-rock country\npop-rock country Balkan folk\npop-rock country Latin\npop-rock country bar-band\npop-rock country big band\npop-rock country blues\npop-rock country blues-rock\npop-rock country boogie-woogie\npop-rock country crossover\npop-rock country folk\npop-rock country folk-rock\npop-rock country gospel\npop-rock country heartland rock\npop-rock country novelty\npop-rock country polka\npop-rock country pop\npop-rock country rockabilly\npop-rock country schlager\npop-rock country sertanejo\npop-rock country soul\npop-rock country southern rock\npop-rock country surf rock\npop-rock country world music\npop-rock country-folk\npop-rock country-gospel\npop-rock country-pop\npop-rock country-rock\npop-rock cumbia\npop-rock cumbia folk\npop-rock cumbia folk-rock\npop-rock cumbia polka\npop-rock cumbia retro\npop-rock cumbia ska\npop-rock dance-pop\npop-rock dangdut\npop-rock dangdut koplo\npop-rock dansband\npop-rock devotional\npop-rock disco\npop-rock disco balkan\npop-rock disco funk\npop-rock disco-funk\npop-rock doo-wop\npop-rock doo-wop 1960s\npop-rock doo-wop early rock and roll\npop-rock doo-wop retro\npop-rock drum and bass\npop-rock electro house\npop-rock electro-house\npop-rock electronic\npop-rock electronic hip-hop\npop-rock electronicore\npop-rock emo\npop-rock emo J-rock\npop-rock emo K-rock\npop-rock emo alternative\npop-rock emo electronic\npop-rock emo hip-hop\npop-rock emo hyperpop\npop-rock emo nu-metal\npop-rock emo pop-punk\npop-rock emo rap\npop-rock emo rap-rock\npop-rock emo trap\npop-rock emo-pop\npop-rock emo-rap\npop-rock emo-rap K-pop\npop-rock emo-rap hip-hop\npop-rock emo-rap hyperpop\npop-rock emo-rap pop-punk\npop-rock emo-rap synth-pop\npop-rock emo-rock\npop-rock estrada\npop-rock ethno-pop\npop-rock eurodance\npop-rock eurodance balkan pop\npop-rock exotica\npop-rock exotica lounge\npop-rock fado\npop-rock fiddle\npop-rock flamenco\npop-rock folk\npop-rock folk big band\npop-rock folk country\npop-rock folk fusion\npop-rock folk polka\npop-rock folk ska\npop-rock folk-dance\npop-rock folk-punk\npop-rock folk-rock\npop-rock forró\npop-rock forró eletrônico\npop-rock funk\npop-rock funk J-rock\npop-rock funk Latin\npop-rock funk Middle Eastern\npop-rock funk R&B\npop-rock funk big band\npop-rock funk blues\npop-rock funk city pop\npop-rock funk city-pop\npop-rock funk disco\npop-rock funk fusion\npop-rock funk gospel\npop-rock funk hip-hop\npop-rock funk jazz\npop-rock funk jazz fusion\npop-rock funk klezmer\npop-rock funk punk\npop-rock funk reggae\npop-rock funk ska\npop-rock funk soul\npop-rock funk world music\npop-rock funk-rock\npop-rock fusion\npop-rock future bass\npop-rock future bass chiptune\npop-rock future bass hardstyle\npop-rock future bass reggaeton\npop-rock garage rock\npop-rock garage-rock\npop-rock glam\npop-rock glam metal\npop-rock glam rock\npop-rock glam-rock\npop-rock gospel\npop-rock gospel CCM\npop-rock gospel Latin\npop-rock gospel MPB\npop-rock gospel R&B\npop-rock gospel country\npop-rock gospel country-rock\npop-rock gospel funk\npop-rock gospel hip-hop\npop-rock gospel jazz\npop-rock gospel klezmer\npop-rock gospel reggae\npop-rock gospel ska\npop-rock gospel soul\npop-rock gospel surf rock\npop-rock gospel world music\npop-rock gypsy jazz\npop-rock gypsy rock balkan\npop-rock hard rock\npop-rock heartland rock\npop-rock hip hop\npop-rock hip-hop\npop-rock hip-hop Bollywood\npop-rock hip-hop EDM\npop-rock hip-hop J-rock\npop-rock hip-hop R&B\npop-rock hip-hop chiptune\npop-rock hip-hop electronic\npop-rock hip-hop emo-rap\npop-rock hip-hop folk\npop-rock hip-hop funk\npop-rock indie\npop-rock indie hip-hop\npop-rock indie pop hip-hop\npop-rock indie rock\npop-rock island\npop-rock italo-disco\npop-rock italo-rock\npop-rock j-pop\npop-rock j-pop anime\npop-rock j-pop cinematic\npop-rock j-pop funky\npop-rock j-pop upbeat\npop-rock j-rock\npop-rock j-rock chiptune\npop-rock jangle-pop\npop-rock jazz\npop-rock jazz big band\npop-rock jazz blues\npop-rock jazz boogie-woogie\npop-rock jazz bossa nova\npop-rock jazz chanson\npop-rock jazz funk\npop-rock jazz fusion\npop-rock jazz fusion anime\npop-rock jazz fusion city pop\npop-rock jazz fusion funk\npop-rock jazz lounge\npop-rock jazz musical theater\npop-rock jazz soul\npop-rock jazz swing\npop-rock jazz world music\npop-rock jazz-fusion\npop-rock jazz-rock\npop-rock kayōkyoku\npop-rock klezmer\npop-rock klezmer folk\npop-rock klezmer polka\npop-rock latin\npop-rock latin flamenco\npop-rock latin jazz fusion\npop-rock latin pop\npop-rock latin rock\npop-rock latin tango\npop-rock lo-fi\npop-rock lo-fi chiptune\npop-rock lounge\npop-rock lounge exotica\npop-rock lounge jazz\npop-rock lounge neo-soul\npop-rock lounge show tune\npop-rock mandopop\npop-rock mashup\npop-rock math-rock\npop-rock metalcore\npop-rock musical\npop-rock musical theater\npop-rock musical theatre\npop-rock neo-soul\npop-rock neo-soul MPB\npop-rock neo-soul R&B\npop-rock neo-soul city pop\npop-rock neo-soul funk\npop-rock neo-soul jazz\npop-rock new age\npop-rock new wave\npop-rock novelty\npop-rock nu-disco\npop-rock nu-metal\npop-rock nu-metal electronic\npop-rock nu-metal rap-rock\npop-rock opera\npop-rock orchestral\npop-rock oud\npop-rock pimba\npop-rock pirate\npop-rock polka\npop-rock post-hardcore\npop-rock post-punk\npop-rock power ballad\npop-rock progressive house\npop-rock progressive rock\npop-rock protest\npop-rock psytrance\npop-rock punk\npop-rock ragtime\npop-rock ragtime boogie-woogie\npop-rock rap-rock\npop-rock reggae\npop-rock reggae Latin\npop-rock reggae MPB\npop-rock reggae dancehall\npop-rock reggae funk\npop-rock reggae gospel\npop-rock reggae hip-hop\npop-rock reggae rap-rock\npop-rock reggae samba\npop-rock reggae ska\npop-rock reggae soul\npop-rock reggae surf rock\npop-rock reggae surf-rock\npop-rock reggae world music\npop-rock reggae-pop\npop-rock reggae-rock\npop-rock reggae-ska\npop-rock reggaeton\npop-rock retro\npop-rock retro K-pop\npop-rock retro Soviet\npop-rock retro cartoon\npop-rock retro funk\npop-rock retro soul\npop-rock retro surf-rock\npop-rock retro swing\npop-rock retro synth\npop-rock retro-swing\npop-rock rockabilly\npop-rock rockabilly big band\npop-rock rockabilly ska\npop-rock rockabilly surf rock\npop-rock rockabilly swing\npop-rock rumba\npop-rock salsa\npop-rock samba\npop-rock samba-reggae\npop-rock samba-rock\npop-rock samba-rock live\npop-rock satire\npop-rock schlager\npop-rock schlager folk\npop-rock schlager polka\npop-rock sea shanty\npop-rock sertanejo\npop-rock sertanejo live\npop-rock sertanejo-rock\npop-rock show tune\npop-rock ska\npop-rock ska Javanese pop\npop-rock ska Latin\npop-rock ska Latin rock\npop-rock ska Melayu\npop-rock ska Russian chanson\npop-rock ska big band\npop-rock ska dangdut\npop-rock ska forró\npop-rock ska funk\npop-rock ska jazz\npop-rock ska new wave\npop-rock ska polka\npop-rock ska punk\npop-rock ska reggae\npop-rock ska rockabilly\npop-rock ska soul\npop-rock ska surf rock\npop-rock ska surf-rock\npop-rock ska swing\npop-rock ska-punk\npop-rock smooth jazz\npop-rock smooth jazz Latin\npop-rock smooth jazz adult contemporary\npop-rock smooth jazz funk\npop-rock smooth jazz fusion\npop-rock smooth jazz world music\npop-rock soul\npop-rock soul R&B\npop-rock soul big band\npop-rock soul funk\npop-rock soul gospel\npop-rock soul jazz\npop-rock soul ska\npop-rock southern rock\npop-rock spiritual\npop-rock stadium rock\npop-rock sunshine pop\npop-rock surf reggae\npop-rock surf rock\npop-rock surf rock Javanese pop\npop-rock surf rock rockabilly\npop-rock surf-rock\npop-rock surf-rock klezmer\npop-rock surf-rock rockabilly\npop-rock swing\npop-rock swing revival\npop-rock symphonic\npop-rock symphonic rock\npop-rock synth-pop\npop-rock tango\npop-rock tango theatrical\npop-rock theatrical\npop-rock trance\npop-rock trap\npop-rock trap-rap\npop-rock trip-hop\npop-rock tropical\npop-rock tropical house\npop-rock trot\npop-rock turbo-folk\npop-rock turbo-folk ska\npop-rock world fusion\npop-rock world music\npop-rock worldbeat\npop-rock worldbeat gospel\npop-rock worship\npop-rock zouk\npop-rock, 60s British Invasion\npop-rock, 60s Christmas, rock and roll\npop-rock, 60s pop, chiptune\npop-rock, 70s Israeli pop, theatrical\npop-rock, 80s AOR\npop-rock, 80s Balkan pop\npop-rock, 80s Bollywood, funk\npop-rock, 80s Bollywood, retro\npop-rock, 80s Brazilian, devotional\npop-rock, 80s Cantopop\npop-rock, 80s Cantopop, nostalgic\npop-rock, 80s Chinese rock, folk-pop\npop-rock, 80s Czech rock\npop-rock, 80s Danish rock\npop-rock, 80s East Asian, synth pop\npop-rock, 80s Eastern European\npop-rock, 80s Eastern European rock\npop-rock, 80s Estrada, synth-pop\npop-rock, 80s European, melancholic\npop-rock, 80s Europop, theatrical\npop-rock, 80s Filipino pop, retro\npop-rock, 80s Filipino pop, theatrical\npop-rock, 80s French chanson\npop-rock, 80s French chanson, atmospheric\npop-rock, 80s French chanson, cinematic\npop-rock, 80s French chanson, synth-pop\npop-rock, 80s Israeli pop\npop-rock, 80s Israeli pop, retro\npop-rock, 80s Israeli rock\npop-rock, 80s Israeli rock, anthemic\npop-rock, 80s Israeli rock, retro\npop-rock, 80s Israeli rock, synth rock\npop-rock, 80s Italian pop, theatrical\npop-rock, 80s South Asian, Bengali pop\npop-rock, 80s Southeast Asian\npop-rock, 80s Taiwan Hokkien pop\npop-rock, 80s Taiwanese Hokkien pop\npop-rock, 80s Taiwanese Hokkien pop, retro\npop-rock, 80s V-pop\npop-rock, 80s aesthetic, bilingual\npop-rock, 80s anime\npop-rock, 80s anime, retro synth\npop-rock, 80s anime, synth rock\npop-rock, 80s arena rock\npop-rock, 80s arena rock, synth-pop\npop-rock, 80s disco, Eastern European\npop-rock, 80s disco, retro\npop-rock, 80s estrada, Eastern European\npop-rock, 80s movie soundtrack, theatrical\npop-rock, 80s new wave\npop-rock, 80s new wave, atmospheric\npop-rock, 80s new wave, cinematic\npop-rock, 80s new wave, synth rock\npop-rock, 80s pop, East Asian pop\npop-rock, 80s pop, Estrada\npop-rock, 80s pop, Southeast Asian pop\npop-rock, 80s pop, Taiwanese Hokkien pop\npop-rock, 80s pop, ambient\npop-rock, 80s pop, ballad\npop-rock, 80s pop, estrada\npop-rock, 80s pop, synth-pop\npop-rock, 80s power ballad\npop-rock, 80s revival\npop-rock, 80s revival, Mandarin pop\npop-rock, 80s revival, Southeast Asian pop\npop-rock, 80s revival, Spanish pop\npop-rock, 80s revival, bilingual\npop-rock, 80s revival, theatrical\npop-rock, 80s show tune, theatrical\npop-rock, 80s stadium rock\npop-rock, 80s stadium, anthemic\npop-rock, 80s synth, Eastern European\npop-rock, 80s synth, bilingual\npop-rock, 80s synth, retro\npop-rock, 80s synth, theatrical\npop-rock, 80s synth-pop\npop-rock, 80s synth-pop, rock\npop-rock, 80s, 90s\npop-rock, 80s, Brazilian\npop-rock, 80s, Central Asian\npop-rock, 80s, Estrada\npop-rock, 80s, Portuguese\npop-rock, 80s, South Asian\npop-rock, 80s, Southeast Asian\npop-rock, 80s, city pop\npop-rock, 80s, festive\npop-rock, 80s, theatrical\npop-rock, 80s/90s revival, C-pop\npop-rock, 90s Asian pop\npop-rock, 90s C-pop\npop-rock, 90s East Asian pop\npop-rock, 90s Eastern European pop\npop-rock, 90s Eastern European rock\npop-rock, 90s Estrada\npop-rock, 90s K-pop, J-pop\npop-rock, 90s Mandopop\npop-rock, 90s Taiwanese rock\npop-rock, 90s anime theme\npop-rock, 90s, Balkan\npop-rock, 90s, Eastern European\npop-rock, Afro-pop, Latin funk\npop-rock, Anatolian folk\npop-rock, Anatolian rock\npop-rock, Anatolian rock, Middle Eastern rock\npop-rock, Anatolian rock, cinematic\npop-rock, Anatolian, microtonal\npop-rock, Arabic fusion\npop-rock, Arabic fusion, Indonesian pop\npop-rock, Arabic fusion, cinematic\npop-rock, Arabic pop\npop-rock, Arabic pop, cinematic\npop-rock, Arabic, Indonesian\npop-rock, Axé\npop-rock, Axé, Brazilian\npop-rock, Axé, Forró\npop-rock, Axé, Latin\npop-rock, Axé, cinematic ballad\npop-rock, Axé, dance\npop-rock, Axé, high-energy\npop-rock, Axé, retro\npop-rock, Axé-pop\npop-rock, Azerbaijani estrada\npop-rock, Azerbaijani folk\npop-rock, Azerbaijani folk, Turkish folk\npop-rock, Azerbaijani folk, anthemic\npop-rock, Azerbaijani folk, epic\npop-rock, Azerbaijani folk, epic anthem\npop-rock, Azerbaijani folk, satirical\npop-rock, Azerbaijani fusion\npop-rock, Azerbaijani fusion, cinematic\npop-rock, Azerbaijani, Turkish\npop-rock, Azerbaijani, cinematic\npop-rock, Azerbaijani, orchestral\npop-rock, Balkan brass\npop-rock, Balkan brass, folk-rock\npop-rock, Balkan folk\npop-rock, Balkan folk, C-pop\npop-rock, Balkan folk, Chalga\npop-rock, Balkan folk, Eastern European\npop-rock, Balkan folk, Middle Eastern\npop-rock, Balkan folk, Turkish saz\npop-rock, Balkan folk, a cappella\npop-rock, Balkan folk, anthemic\npop-rock, Balkan folk, blues-rock\npop-rock, Balkan folk, brass-driven\npop-rock, Balkan folk, chiptune\npop-rock, Balkan folk, choral\npop-rock, Balkan folk, cinematic\npop-rock, Balkan folk, dance\npop-rock, Balkan folk, dramatic\npop-rock, Balkan folk, electronic\npop-rock, Balkan folk, energetic\npop-rock, Balkan folk, epic\npop-rock, Balkan folk, flamenco\npop-rock, Balkan folk, hard rock\npop-rock, Balkan folk, live\npop-rock, Balkan folk, live rock\npop-rock, Balkan folk, retro\npop-rock, Balkan folk, retro synth\npop-rock, Balkan folk, rock\npop-rock, Balkan folk, synth pop\npop-rock, Balkan folk, synth-pop\npop-rock, Balkan folk, synthwave\npop-rock, Balkan folk, theatrical\npop-rock, Balkan folk, turbo-folk\npop-rock, Balkan folk, upbeat\npop-rock, Balkan folk, vintage\npop-rock, Balkan folk-rock\npop-rock, Balkan fusion\npop-rock, Balkan fusion, Middle Eastern\npop-rock, Balkan fusion, cinematic\npop-rock, Balkan new wave, retro\npop-rock, Balkan pop\npop-rock, Balkan pop, Euro-pop\npop-rock, Balkan pop, cinematic\npop-rock, Balkan pop, electronic\npop-rock, Balkan pop, retro\npop-rock, Balkan pop, synth brass\npop-rock, Balkan pop, theatrical\npop-rock, Balkan rock\npop-rock, Balkan style\npop-rock, Balkan turbo-folk, cinematic\npop-rock, Balkan, C-pop\npop-rock, Balkan, Chalga\npop-rock, Balkan, Eastern European\npop-rock, Balkan, Euro-pop\npop-rock, Balkan, Eurodance\npop-rock, Balkan, Klezmer\npop-rock, Balkan, Latin\npop-rock, Balkan, Mediterranean\npop-rock, Balkan, Middle Eastern\npop-rock, Balkan, Schlager\npop-rock, Balkan, anthemic\npop-rock, Balkan, ballad\npop-rock, Balkan, big band\npop-rock, Balkan, chiptune\npop-rock, Balkan, cinematic\npop-rock, Balkan, disco\npop-rock, Balkan, disco-funk\npop-rock, Balkan, dramatic\npop-rock, Balkan, electronic\npop-rock, Balkan, energetic\npop-rock, Balkan, ethno-pop\npop-rock, Balkan, flamenco\npop-rock, Balkan, folk\npop-rock, Balkan, hard rock\npop-rock, Balkan, klezmer\npop-rock, Balkan, live\npop-rock, Balkan, melancholic\npop-rock, Balkan, modern\npop-rock, Balkan, new wave\npop-rock, Balkan, nu-metal\npop-rock, Balkan, retro\npop-rock, Balkan, retro-pop\npop-rock, Balkan, rock\npop-rock, Balkan, schlager\npop-rock, Balkan, ska\npop-rock, Balkan, spiritual\npop-rock, Balkan, surf rock\npop-rock, Balkan, surf-rock\npop-rock, Balkan, synth\npop-rock, Balkan, synth-pop\npop-rock, Balkan, tango\npop-rock, Balkan, theatrical\npop-rock, Bollywood, 90s\npop-rock, Bollywood, EDM\npop-rock, Bollywood, anthemic\npop-rock, Bollywood, atmospheric\npop-rock, Bollywood, cinematic\npop-rock, Bollywood, electronic\npop-rock, Bollywood, festive\npop-rock, Bollywood, funk\npop-rock, Bollywood, retro\npop-rock, Bollywood, upbeat\npop-rock, Bollywood, uplifting\npop-rock, Bollywood, worship\npop-rock, Bornean, celebratory\npop-rock, Brazilian carnival, festive\npop-rock, Brazilian carnival, theatrical\npop-rock, Brazilian funk\npop-rock, Brazilian funk, carioca\npop-rock, Brazilian pop\npop-rock, Brazilian pop, Axé\npop-rock, Brazilian pop, folk\npop-rock, Brazilian pop, reggae\npop-rock, Brazilian rock\npop-rock, Brazilian rock, 80s\npop-rock, Brazilian, 80s\npop-rock, Brazilian, Latin\npop-rock, Brazilian, Middle Eastern\npop-rock, Brazilian, blues-rock\npop-rock, Brazilian, cinematic\npop-rock, Brazilian, energetic\npop-rock, Brazilian, gospel\npop-rock, Brazilian, live\npop-rock, Brazilian, reggae\npop-rock, Brazilian, retro\npop-rock, Brazilian, rock\npop-rock, Brazilian, upbeat\npop-rock, Brazilian, uplifting\npop-rock, British Invasion, vintage\npop-rock, Broadway, theatrical\npop-rock, C-pop\npop-rock, C-pop, J-rock\npop-rock, C-pop, K-pop\npop-rock, C-pop, alternative\npop-rock, C-pop, alternative rock\npop-rock, C-pop, anime\npop-rock, C-pop, anime theme\npop-rock, C-pop, ballad\npop-rock, C-pop, big band\npop-rock, C-pop, cinematic\npop-rock, C-pop, dreamy\npop-rock, C-pop, electronic\npop-rock, C-pop, emotional\npop-rock, C-pop, emotional ballad\npop-rock, C-pop, funk\npop-rock, C-pop, fusion\npop-rock, C-pop, hip-hop\npop-rock, C-pop, indie\npop-rock, C-pop, indie ballad\npop-rock, C-pop, jazz fusion\npop-rock, C-pop, lo-fi hip hop\npop-rock, C-pop, power ballad\npop-rock, C-pop, rap\npop-rock, C-pop, rock\npop-rock, C-pop, synthwave\npop-rock, C-pop, theatrical\npop-rock, C-pop, traditional fusion\npop-rock, CCM\npop-rock, Cantonese, Mandarin\npop-rock, Cantopop, 80s\npop-rock, Cantopop, 90s\npop-rock, Cantopop, J-rock\npop-rock, Cantopop, anime theme\npop-rock, Cantopop, musical theater\npop-rock, Cantopop, retro\npop-rock, Carnatic fusion, synth-pop\npop-rock, Celtic folk\npop-rock, Celtic, J-pop\npop-rock, Central Asian\npop-rock, Central Asian folk\npop-rock, Central Asian folk, anthemic\npop-rock, Central Asian folk, chiptune\npop-rock, Central Asian folk, hip-hop\npop-rock, Central Asian fusion\npop-rock, Central Asian pop, cinematic\npop-rock, Central Asian, Eastern European\npop-rock, Central Asian, Middle Eastern\npop-rock, Central Asian, atmospheric\npop-rock, Central Asian, blues-rock\npop-rock, Central Asian, cinematic\npop-rock, Central Asian, dance\npop-rock, Central Asian, dramatic\npop-rock, Central Asian, funk\npop-rock, Central Asian, rock\npop-rock, Central Asian, synth\npop-rock, Central Asian, synth-pop\npop-rock, Central Asian, upbeat\npop-rock, Chinese New Year, cinematic\npop-rock, Chinese New Year, festive\npop-rock, Chinese ballad, cinematic\npop-rock, Chinese classical, cinematic\npop-rock, Chinese folk\npop-rock, Chinese folk, anime rock\npop-rock, Chinese folk, big band\npop-rock, Chinese folk, cinematic\npop-rock, Chinese folk, rock\npop-rock, Chinese folk, theatrical\npop-rock, Chinese fusion\npop-rock, Chinese fusion, hard rock\npop-rock, Chinese influence, cinematic\npop-rock, Chinese opera, anthemic\npop-rock, Chinese opera, cinematic\npop-rock, Chinese opera, hard rock\npop-rock, Chinese pop, ballad\npop-rock, Chinese pop, cinematic\npop-rock, Chinese rock\npop-rock, Chinese rock, C-pop\npop-rock, Chinese rock, cinematic\npop-rock, Chinese rock, early 2000s\npop-rock, Chinese rock, emotional\npop-rock, Chinese rock, rap\npop-rock, Chinese style\npop-rock, Chinese traditional\npop-rock, Chinese traditional, anime soundtrack\npop-rock, Chinese traditional, cinematic\npop-rock, Chinese, cinematic\npop-rock, Chinese-style, theatrical\npop-rock, Christian Contemporary Music\npop-rock, Christian contemporary\npop-rock, Christian contemporary music\npop-rock, Christian contemporary, K-pop\npop-rock, Christian contemporary, anime opening\npop-rock, Christian contemporary, bilingual\npop-rock, Christian hip-hop, inspirational\npop-rock, Christian rock\npop-rock, Christian worship\npop-rock, Christian worship, K-pop\npop-rock, Christian worship, anthemic\npop-rock, Christian worship, electronic\npop-rock, Christian worship, energetic\npop-rock, Christmas, 80s synth\npop-rock, Christmas, C-pop\npop-rock, Christmas, Celtic\npop-rock, Christmas, Christian rock\npop-rock, Christmas, D&D\npop-rock, Christmas, Eastern European\npop-rock, Christmas, J-pop\npop-rock, Christmas, Portuguese\npop-rock, Christmas, anime\npop-rock, Christmas, anthemic\npop-rock, Christmas, bilingual\npop-rock, Christmas, boogie-woogie\npop-rock, Christmas, cinematic\npop-rock, Christmas, country rock\npop-rock, Christmas, festive\npop-rock, Christmas, gospel\npop-rock, Christmas, hip-hop\npop-rock, Christmas, live\npop-rock, Christmas, quirky\npop-rock, Christmas, satirical\npop-rock, Christmas, theatrical\npop-rock, Christmas, upbeat\npop-rock, City Pop, 90s K-pop\npop-rock, Contemporary Christian Music\npop-rock, Dangdut\npop-rock, Dangdut Koplo\npop-rock, Dangdut Koplo, cinematic\npop-rock, Dangdut Koplo, lo-fi\npop-rock, Dangdut, Middle Eastern\npop-rock, Dangdut, Southeast Asian pop\npop-rock, Dangdut, electronic\npop-rock, Dangdut, hard rock\npop-rock, Dangdut, retro\npop-rock, Dangdut, world fusion\npop-rock, Deutschrock\npop-rock, EDM\npop-rock, EDM, Afrikaans pop\npop-rock, EDM, Bhangra\npop-rock, EDM, Brazilian\npop-rock, EDM, Brazilian pop\npop-rock, EDM, C-pop\npop-rock, EDM, French pop\npop-rock, EDM, Hebrew vocal\npop-rock, EDM, Middle Eastern\npop-rock, EDM, Romanian\npop-rock, EDM, Turkish pop\npop-rock, EDM, anthemic\npop-rock, EDM, ballad\npop-rock, EDM, big room\npop-rock, EDM, big room house\npop-rock, EDM, bilingual\npop-rock, EDM, blues rock\npop-rock, EDM, cinematic\npop-rock, EDM, cinematic pop\npop-rock, EDM, dance\npop-rock, EDM, dance-pop\npop-rock, EDM, dubstep\npop-rock, EDM, emotional\npop-rock, EDM, energetic\npop-rock, EDM, flamenco\npop-rock, EDM, future bass\npop-rock, EDM, hip-hop\npop-rock, EDM, piano ballad\npop-rock, EDM, progressive house\npop-rock, EDM, sports anthem\npop-rock, EDM, synth-rock\npop-rock, EDM, trap\npop-rock, EDM, tropical house\npop-rock, EDM, upbeat\npop-rock, EDM, worship\npop-rock, EDM-pop\npop-rock, East African, Sinhala\npop-rock, East African, anthemic\npop-rock, East African, cinematic\npop-rock, East African, dance\npop-rock, East African, melodic\npop-rock, East Asian folk, fusion\npop-rock, East Asian fusion\npop-rock, East Asian pop\npop-rock, East Asian, anime\npop-rock, East Asian, ballad\npop-rock, East Asian, theatrical\npop-rock, East-meets-West fusion\npop-rock, Eastern European folk\npop-rock, Eastern European folk, Latin\npop-rock, Eastern European folk, big band\npop-rock, Eastern European folk, blues-rock\npop-rock, Eastern European folk, cinematic\npop-rock, Eastern European folk, dance\npop-rock, Eastern European folk, synth-pop\npop-rock, Eastern European rock, 80s rock\npop-rock, Eastern European rock, 80s synth rock\npop-rock, Eastern European, 80s\npop-rock, Eastern European, 80s synth\npop-rock, Eastern European, Latin\npop-rock, Eastern European, Middle Eastern\npop-rock, Eastern European, Turkish\npop-rock, Eastern European, accordion\npop-rock, Eastern European, anthemic\npop-rock, Eastern European, ballad\npop-rock, Eastern European, cinematic\npop-rock, Eastern European, dramatic\npop-rock, Eastern European, energetic\npop-rock, Eastern European, flamenco\npop-rock, Eastern European, folk rock\npop-rock, Eastern European, folk-rock\npop-rock, Eastern European, funk\npop-rock, Eastern European, jazz\npop-rock, Eastern European, lo-fi\npop-rock, Eastern European, melancholic\npop-rock, Eastern European, melancholic dance\npop-rock, Eastern European, nostalgic\npop-rock, Eastern European, polka\npop-rock, Eastern European, retro\npop-rock, Eastern European, satirical\npop-rock, Eastern European, synth-pop\npop-rock, Eastern European, theatrical\npop-rock, Eastern European, upbeat\npop-rock, Enka, cinematic\npop-rock, Estrada\npop-rock, Estrada, 80s pop\npop-rock, Estrada, folk-pop\npop-rock, Estrada, synth-pop\npop-rock, Euro-pop\npop-rock, Eurodance\npop-rock, Eurodance, Balkan pop\npop-rock, Eurodance, EDM\npop-rock, Eurodance, German pop\npop-rock, Eurodance, Latin\npop-rock, Eurodance, Portuguese\npop-rock, Eurodance, Schlager\npop-rock, Eurodance, ambient\npop-rock, Eurodance, dance-pop\npop-rock, Eurodance, high-energy\npop-rock, Eurodance, hip-hop\npop-rock, Eurodance, late-90s\npop-rock, Eurodance, ska\npop-rock, Eurodance, turbo-folk\npop-rock, European chanson, theatrical\npop-rock, European folk, Indonesian pop\npop-rock, European folk, chanson\npop-rock, European folk, quirky\npop-rock, European folk, retro\npop-rock, European folk, tango\npop-rock, European folk, theatrical\npop-rock, European, soulful\npop-rock, European, theatrical\npop-rock, Europop\npop-rock, Europop, piano ballad\npop-rock, Filipino Christmas\npop-rock, Filipino rock\npop-rock, Finnish schlager\npop-rock, Forró\npop-rock, Forró, Sertanejo\npop-rock, Forró, acoustic\npop-rock, French chanson\npop-rock, French chanson, cinematic\npop-rock, French chanson, theatrical\npop-rock, French chanson, theatrical rock\npop-rock, French hip-hop\npop-rock, French pop, hard rock\npop-rock, French ska\npop-rock, Greek Laïko\npop-rock, Greek folk\npop-rock, Greek rock\npop-rock, Halloween, campy\npop-rock, Halloween, theatrical\npop-rock, Hebrew pop, cinematic rock\npop-rock, Hokkien, electronic\npop-rock, Indian classical fusion\npop-rock, Indian classical, atmospheric\npop-rock, Indian classical, cinematic\npop-rock, Indian classical, electronic\npop-rock, Indian devotional, modern fusion\npop-rock, Indian devotional, uplifting\npop-rock, Indian film music\npop-rock, Indian film music, Christian devotional\npop-rock, Indian film music, EDM\npop-rock, Indian film music, festive\npop-rock, Indian film music, spiritual\npop-rock, Indian folk\npop-rock, Indian folk fusion, cinematic\npop-rock, Indian folk, anthemic\npop-rock, Indian folk, chiptune\npop-rock, Indian folk, cinematic\npop-rock, Indian folk, electronic\npop-rock, Indian folk, festive\npop-rock, Indian folk, fusion\npop-rock, Indian folk, soul\npop-rock, Indian folk, upbeat\npop-rock, Indian fusion\npop-rock, Indian fusion, cinematic\npop-rock, Indian fusion, devotional\npop-rock, Indian fusion, upbeat\npop-rock, Indian pop, devotional\npop-rock, Indonesian Pop, Malay Pop\npop-rock, Indonesian folk\npop-rock, Indonesian fusion\npop-rock, Indonesian fusion, Javanese rap\npop-rock, Indonesian fusion, eclectic\npop-rock, Indonesian musical theater\npop-rock, Indonesian pop\npop-rock, Indonesian pop, 80s rock\npop-rock, Indonesian pop, 80s synth\npop-rock, Indonesian pop, Southeast Asian\npop-rock, Indonesian pop, Spanish guitar\npop-rock, Indonesian pop, Sunda pop\npop-rock, Indonesian pop, electronic\npop-rock, Indonesian pop, energetic\npop-rock, Indonesian pop-rock\npop-rock, Indonesian rock\npop-rock, Indonesian traditional\npop-rock, Indonesian, Islamic\npop-rock, Indonesian, Melayu\npop-rock, Indonesian, Sundanese\npop-rock, Indonesian, anthemic\npop-rock, Indonesian, ballad\npop-rock, Indonesian, cinematic\npop-rock, Indonesian, energetic\npop-rock, Indonesian, festive\npop-rock, Indonesian, funk\npop-rock, Indonesian, melodic\npop-rock, Indonesian, romantic\npop-rock, Indonesian, sentimental\npop-rock, Indonesian, surf-rock\npop-rock, Indonesian, synth-pop\npop-rock, Indonesian, vibrant\npop-rock, Indonesian, world fusion\npop-rock, Islamic praise, gospel\npop-rock, Israeli folk\npop-rock, Israeli rock\npop-rock, Israeli rock, theatrical\npop-rock, Italian folk\npop-rock, Italian folk, chiptune\npop-rock, Italian pop, theatrical\npop-rock, Italo dance\npop-rock, Italo-disco\npop-rock, Italo-disco, cinematic\npop-rock, Italo-disco, funk\npop-rock, Italo-disco, retro\npop-rock, Italo-disco, retro dance\npop-rock, Italo-disco, theatrical\npop-rock, J-Rock\npop-rock, J-Rock, anime theme\npop-rock, J-Rock, anthemic\npop-rock, J-Rock, chiptune\npop-rock, J-Rock, emotional\npop-rock, J-Rock, power ballad\npop-rock, J-pop\npop-rock, J-pop, Bengali pop\npop-rock, J-pop, C-pop\npop-rock, J-pop, Christmas\npop-rock, J-pop, Indonesian pop\npop-rock, J-pop, K-pop\npop-rock, J-pop, R&B\npop-rock, J-pop, ambient\npop-rock, J-pop, anime\npop-rock, J-pop, anime soundtrack\npop-rock, J-pop, anime theme\npop-rock, J-pop, bilingual\npop-rock, J-pop, cabaret\npop-rock, J-pop, cinematic\npop-rock, J-pop, city pop\npop-rock, J-pop, electronic\npop-rock, J-pop, festive\npop-rock, J-pop, hip-hop\npop-rock, J-pop, power ballad\npop-rock, J-pop, theatrical\npop-rock, J-pop, upbeat\npop-rock, J-pop, uplifting\npop-rock, J-pop, video game music\npop-rock, J-rock\npop-rock, J-rock, C-pop\npop-rock, J-rock, C-rock\npop-rock, J-rock, Canto-pop\npop-rock, J-rock, Canto-rock\npop-rock, J-rock, Christmas\npop-rock, J-rock, Hindi pop\npop-rock, J-rock, K-pop\npop-rock, J-rock, K-rock\npop-rock, J-rock, Latin jazz-funk\npop-rock, J-rock, Latin pop\npop-rock, J-rock, Latin pop-rock\npop-rock, J-rock, Malayalam pop\npop-rock, J-rock, Mandarin ballad\npop-rock, J-rock, Mandarin pop\npop-rock, J-rock, Mandarin rap\npop-rock, J-rock, Mandarin rock\npop-rock, J-rock, R&B\npop-rock, J-rock, Russian pop\npop-rock, J-rock, Thai pop\npop-rock, J-rock, acoustic ballad\npop-rock, J-rock, anime\npop-rock, J-rock, anime rock\npop-rock, J-rock, anime soundtrack\npop-rock, J-rock, anime theme\npop-rock, J-rock, anisong\npop-rock, J-rock, anthemic\npop-rock, J-rock, atmospheric\npop-rock, J-rock, ballad\npop-rock, J-rock, bilingual\npop-rock, J-rock, cantopop\npop-rock, J-rock, chiptune\npop-rock, J-rock, cinematic\npop-rock, J-rock, city pop\npop-rock, J-rock, city-pop\npop-rock, J-rock, dance-pop\npop-rock, J-rock, dangdut\npop-rock, J-rock, dream pop\npop-rock, J-rock, electronic\npop-rock, J-rock, emo\npop-rock, J-rock, emo-pop\npop-rock, J-rock, emo-rap\npop-rock, J-rock, emotional\npop-rock, J-rock, emotional ballad\npop-rock, J-rock, energetic\npop-rock, J-rock, explosive\npop-rock, J-rock, festive\npop-rock, J-rock, folk\npop-rock, J-rock, funk\npop-rock, J-rock, high-energy\npop-rock, J-rock, hip-hop\npop-rock, J-rock, hyperpop\npop-rock, J-rock, instrumental\npop-rock, J-rock, late-90s\npop-rock, J-rock, lo-fi\npop-rock, J-rock, lo-fi hip hop\npop-rock, J-rock, lo-fi hip-hop\npop-rock, J-rock, math-rock\npop-rock, J-rock, melancholic\npop-rock, J-rock, metal\npop-rock, J-rock, metalcore\npop-rock, J-rock, modern C-pop\npop-rock, J-rock, nu-metal\npop-rock, J-rock, piano ballad\npop-rock, J-rock, pop-punk\npop-rock, J-rock, power ballad\npop-rock, J-rock, power metal\npop-rock, J-rock, rap\npop-rock, J-rock, rap-rock\npop-rock, J-rock, rock anthem\npop-rock, J-rock, ska-punk\npop-rock, J-rock, synth-pop\npop-rock, J-rock, synth-rock\npop-rock, J-rock, synthwave\npop-rock, J-rock, theatrical\npop-rock, J-rock, trap\npop-rock, J-rock, uplifting\npop-rock, J-rock, video game\npop-rock, J-rock, video game music\npop-rock, J-rock, worship\npop-rock, JRPG, rap-rock\npop-rock, Javanese Dangdut, cinematic\npop-rock, Javanese folk\npop-rock, Javanese folk, acoustic\npop-rock, Javanese folk, cinematic\npop-rock, Javanese folk, electronic\npop-rock, Javanese folk, indie\npop-rock, Javanese folk, ska-punk\npop-rock, Javanese fusion\npop-rock, Javanese fusion, Sundanese\npop-rock, Javanese pop\npop-rock, Javanese pop, Sunda pop\npop-rock, Javanese pop, anthemic\npop-rock, Javanese pop, cinematic\npop-rock, Javanese pop, dangdut koplo\npop-rock, Javanese pop, lo-fi\npop-rock, Javanese rock\npop-rock, Javanese soul, dance rock\npop-rock, Javanese traditional, indie folk\npop-rock, Javanese, Indonesian\npop-rock, Javanese, Sundanese\npop-rock, Javanese, atmospheric\npop-rock, Javanese, ballad\npop-rock, Javanese, cinematic\npop-rock, Javanese, energetic\npop-rock, Javanese, festive\npop-rock, Javanese, funk\npop-rock, Javanese, hard rock\npop-rock, Javanese, hip-hop\npop-rock, Javanese, melancholic\npop-rock, Javanese, power ballad\npop-rock, Javanese, rock\npop-rock, Javanese, world fusion\npop-rock, K-pop\npop-rock, K-pop, EDM\npop-rock, K-pop, J-pop\npop-rock, K-pop, J-rock\npop-rock, K-pop, anime theme\npop-rock, K-pop, anthemic\npop-rock, K-pop, early 2000s\npop-rock, K-pop, electronic\npop-rock, K-pop, emo\npop-rock, K-pop, emo-rap\npop-rock, K-pop, hip-hop\npop-rock, K-pop, hyperpop\npop-rock, K-pop, industrial\npop-rock, K-pop, live\npop-rock, K-pop, live energy\npop-rock, K-pop, rap\npop-rock, K-rock\npop-rock, K-rock, J-rock\npop-rock, K-rock, anime\npop-rock, K-rock, early 2000s\npop-rock, K-rock, emo\npop-rock, K-rock, pop-punk\npop-rock, K-rock, retro\npop-rock, Klezmer, big band\npop-rock, Klezmer, surf rock\npop-rock, Korean hip-hop\npop-rock, Korean rock, 80s revival\npop-rock, Korean trot, cinematic\npop-rock, Latin big band\npop-rock, Latin brass, big band\npop-rock, Latin cumbia\npop-rock, Latin dance, cinematic\npop-rock, Latin dance, energetic\npop-rock, Latin dance, hard rock\npop-rock, Latin dance, melancholic ballad\npop-rock, Latin folk, Balkan folk\npop-rock, Latin funk\npop-rock, Latin funk, retro\npop-rock, Latin fusion, South Asian\npop-rock, Latin groove\npop-rock, Latin groove, sophisti-pop\npop-rock, Latin jazz\npop-rock, Latin jazz fusion\npop-rock, Latin jazz, big band\npop-rock, Latin jazz, smooth jazz\npop-rock, Latin pop\npop-rock, Latin pop, 80s pop\npop-rock, Latin pop, 80s revival\npop-rock, Latin pop, 80s rock\npop-rock, Latin pop, Brazilian pop\npop-rock, Latin pop, C-pop\npop-rock, Latin pop, French pop\npop-rock, Latin pop, Indonesian pop\npop-rock, Latin pop, J-pop\npop-rock, Latin pop, Malaysian pop\npop-rock, Latin pop, Mandarin pop\npop-rock, Latin pop, Mediterranean\npop-rock, Latin pop, Melayu\npop-rock, Latin pop, Vietnamese pop\npop-rock, Latin pop, acoustic\npop-rock, Latin pop, ambient\npop-rock, Latin pop, animated film\npop-rock, Latin pop, anthemic\npop-rock, Latin pop, anxious energy\npop-rock, Latin pop, ballad\npop-rock, Latin pop, bilingual\npop-rock, Latin pop, blues-rock\npop-rock, Latin pop, chiptune\npop-rock, Latin pop, cinematic\npop-rock, Latin pop, dance rock\npop-rock, Latin pop, dangdut\npop-rock, Latin pop, devotional\npop-rock, Latin pop, educational\npop-rock, Latin pop, energetic\npop-rock, Latin pop, exotica\npop-rock, Latin pop, festive\npop-rock, Latin pop, flamenco\npop-rock, Latin pop, folk rock\npop-rock, Latin pop, funk\npop-rock, Latin pop, funk rock\npop-rock, Latin pop, hard rock\npop-rock, Latin pop, high-energy\npop-rock, Latin pop, indie\npop-rock, Latin pop, indie folk\npop-rock, Latin pop, indie rock\npop-rock, Latin pop, live energy\npop-rock, Latin pop, live performance\npop-rock, Latin pop, melancholic\npop-rock, Latin pop, nu-metal\npop-rock, Latin pop, quirky\npop-rock, Latin pop, reggaeton\npop-rock, Latin pop, retro\npop-rock, Latin pop, rock\npop-rock, Latin pop, ska\npop-rock, Latin pop, soul\npop-rock, Latin pop, spiritual\npop-rock, Latin pop, surf rock\npop-rock, Latin pop, synth-pop\npop-rock, Latin pop, synthwave\npop-rock, Latin pop, theatrical\npop-rock, Latin pop, theatrical rock\npop-rock, Latin pop, tropical\npop-rock, Latin pop, upbeat\npop-rock, Latin pop, vintage\npop-rock, Latin pop, world music\npop-rock, Latin rhythm, satirical\npop-rock, Latin rock\npop-rock, Latin rock, Indonesian folk\npop-rock, Latin rock, flamenco\npop-rock, Latin rock, hard rock\npop-rock, Latin rock, indie folk\npop-rock, Latin rock, retro\npop-rock, Latin rock, surf-rock\npop-rock, Latin soul\npop-rock, Latin trap, cinematic\npop-rock, Latin, 80s\npop-rock, Latin, 80s nostalgia\npop-rock, Latin, Axé\npop-rock, Latin, Balkan\npop-rock, Latin, Bossa Nova\npop-rock, Latin, Brazilian\npop-rock, Latin, Caribbean\npop-rock, Latin, Chinese New Year\npop-rock, Latin, Christmas\npop-rock, Latin, Eastern European\npop-rock, Latin, Fado\npop-rock, Latin, Forró\npop-rock, Latin, Indonesian\npop-rock, Latin, MPB\npop-rock, Latin, Mediterranean\npop-rock, Latin, Middle Eastern\npop-rock, Latin, North African\npop-rock, Latin, Pimba\npop-rock, Latin, Portuguese\npop-rock, Latin, Schlager\npop-rock, Latin, Soviet estrada\npop-rock, Latin, anthemic\npop-rock, Latin, ballad\npop-rock, Latin, big band\npop-rock, Latin, bilingual\npop-rock, Latin, blues\npop-rock, Latin, blues-rock\npop-rock, Latin, boogie-woogie\npop-rock, Latin, cabaret\npop-rock, Latin, cinematic\npop-rock, Latin, country-rock\npop-rock, Latin, disco\npop-rock, Latin, dramatic\npop-rock, Latin, educational\npop-rock, Latin, exotica\npop-rock, Latin, experimental\npop-rock, Latin, festive\npop-rock, Latin, flamenco\npop-rock, Latin, folk\npop-rock, Latin, folkloric\npop-rock, Latin, funk\npop-rock, Latin, gospel\npop-rock, Latin, jazz\npop-rock, Latin, live\npop-rock, Latin, lounge\npop-rock, Latin, melancholic\npop-rock, Latin, noir-jazz\npop-rock, Latin, psychedelic\npop-rock, Latin, reggae\npop-rock, Latin, retro\npop-rock, Latin, rock\npop-rock, Latin, salsa\npop-rock, Latin, schlager\npop-rock, Latin, show tune\npop-rock, Latin, ska\npop-rock, Latin, smooth jazz\npop-rock, Latin, soul\npop-rock, Latin, soulful\npop-rock, Latin, spiritual\npop-rock, Latin, surf-rock\npop-rock, Latin, tango\npop-rock, Latin, theatrical\npop-rock, Latin, trip-hop\npop-rock, Latin, tropical\npop-rock, Latin, vintage\npop-rock, Latin, world music\npop-rock, Latin, worldbeat\npop-rock, Latin-infused, hard rock\npop-rock, Latin-pop\npop-rock, Latin-pop, cumbia\npop-rock, Latin-rock\npop-rock, Luk Thung\npop-rock, MPB\npop-rock, MPB, Brazilian\npop-rock, MPB, acoustic ballad\npop-rock, MPB, blues\npop-rock, MPB, folk\npop-rock, MPB, funk\npop-rock, MPB, gospel\npop-rock, MPB, live\npop-rock, MPB, retro\npop-rock, MPB, samba\npop-rock, MPB, samba-reggae\npop-rock, MPB, samba-rock\npop-rock, MPB, ska\npop-rock, MPB, smooth jazz\npop-rock, MPB, soul\npop-rock, MPB, soulful\npop-rock, MPB, surf rock\npop-rock, MPB, theatrical\npop-rock, MPB, upbeat\npop-rock, Malay classical, festive\npop-rock, Malay folk\npop-rock, Malay folk, Sundanese folk\npop-rock, Malay fusion\npop-rock, Malay pop\npop-rock, Malay pop, Indonesian pop\npop-rock, Malay pop, Middle Eastern fusion\npop-rock, Malay pop, ballad\npop-rock, Malay pop, cinematic\npop-rock, Malay pop, fusion\npop-rock, Malay traditional\npop-rock, Malay traditional, cinematic\npop-rock, Malay traditional, festive\npop-rock, Malay, Dangdut\npop-rock, Malay, Indonesian\npop-rock, Malaysian pop\npop-rock, Malaysian rock\npop-rock, Mandarin ballad, cinematic\npop-rock, Mandarin hip hop\npop-rock, Mandarin hip hop, chiptune\npop-rock, Mandarin rock\npop-rock, Mandarin, Latin flair\npop-rock, Mandarin, emotional\npop-rock, Mandopop\npop-rock, Mandopop, 2000s\npop-rock, Mandopop, early 2000s\npop-rock, Mandopop, electronic\npop-rock, Mandopop, retro\npop-rock, Mandopop, synth-pop\npop-rock, Marathi folk\npop-rock, Mediterranean, Balkan\npop-rock, Mediterranean, Hebrew folk\npop-rock, Mediterranean, Italian\npop-rock, Mediterranean, Latin\npop-rock, Mediterranean, Middle Eastern\npop-rock, Mediterranean, blues\npop-rock, Melbourne bounce, big room house\npop-rock, Middle Eastern\npop-rock, Middle Eastern dance\npop-rock, Middle Eastern folk\npop-rock, Middle Eastern folk, Anatolian\npop-rock, Middle Eastern folk, cinematic\npop-rock, Middle Eastern folk, fusion\npop-rock, Middle Eastern fusion\npop-rock, Middle Eastern fusion, live energy\npop-rock, Middle Eastern influence\npop-rock, Middle Eastern pop, Malay pop\npop-rock, Middle Eastern pop, cinematic\npop-rock, Middle Eastern pop, cinematic ballad\npop-rock, Middle Eastern, 80s power ballad\npop-rock, Middle Eastern, Anatolian\npop-rock, Middle Eastern, Anatolian folk\npop-rock, Middle Eastern, Armenian\npop-rock, Middle Eastern, Balkan\npop-rock, Middle Eastern, Eastern European\npop-rock, Middle Eastern, Hebrew vocal\npop-rock, Middle Eastern, Indonesian\npop-rock, Middle Eastern, Klezmer\npop-rock, Middle Eastern, Latin\npop-rock, Middle Eastern, Malay\npop-rock, Middle Eastern, Malay fusion\npop-rock, Middle Eastern, Malay pop\npop-rock, Middle Eastern, Mediterranean\npop-rock, Middle Eastern, Sinhala\npop-rock, Middle Eastern, South Asian\npop-rock, Middle Eastern, Southeast Asian\npop-rock, Middle Eastern, Turkish\npop-rock, Middle Eastern, Turkish pop\npop-rock, Middle Eastern, anthemic\npop-rock, Middle Eastern, arabesque\npop-rock, Middle Eastern, atmospheric\npop-rock, Middle Eastern, ballad\npop-rock, Middle Eastern, cinematic\npop-rock, Middle Eastern, classical\npop-rock, Middle Eastern, dramatic\npop-rock, Middle Eastern, dream pop\npop-rock, Middle Eastern, electronic\npop-rock, Middle Eastern, emotional\npop-rock, Middle Eastern, emotive\npop-rock, Middle Eastern, energetic\npop-rock, Middle Eastern, epic\npop-rock, Middle Eastern, festive\npop-rock, Middle Eastern, flamenco\npop-rock, Middle Eastern, folk\npop-rock, Middle Eastern, instrumental\npop-rock, Middle Eastern, klezmer\npop-rock, Middle Eastern, live\npop-rock, Middle Eastern, melancholic\npop-rock, Middle Eastern, modern\npop-rock, Middle Eastern, patriotic\npop-rock, Middle Eastern, quirky\npop-rock, Middle Eastern, rap\npop-rock, Middle Eastern, rock\npop-rock, Middle Eastern, spiritual\npop-rock, Middle Eastern, synth\npop-rock, Middle Eastern, traditional\npop-rock, Middle Eastern, upbeat\npop-rock, Middle Eastern, uplifting\npop-rock, Middle Eastern, world music\npop-rock, Mizrahi rock\npop-rock, Mizrahi, 80s\npop-rock, Mizrahi, Mediterranean\npop-rock, Mizrahi, Middle Eastern\npop-rock, Mizrahi, anthemic\npop-rock, Mizrahi, ballad\npop-rock, Mizrahi, cinematic\npop-rock, Mizrahi, dance\npop-rock, Mizrahi, electronic\npop-rock, Mizrahi, high-energy\npop-rock, Mizrahi, retro\npop-rock, Mizrahi, rock\npop-rock, Mongolian folk\npop-rock, Mongolian folk, cinematic\npop-rock, Mongolian folk, electronic\npop-rock, Mongolian folk, epic\npop-rock, Mongolian folk, retro\npop-rock, Mongolian folk, rock\npop-rock, Mongolian, cinematic\npop-rock, Neapolitan, blues rock\npop-rock, Neapolitan, cinematic\npop-rock, Nederpop\npop-rock, Nederpop, Schlager\npop-rock, Nederpop, vintage\npop-rock, Nepali folk\npop-rock, Neue Deutsche Welle\npop-rock, Neue Deutsche Welle, 80s synth\npop-rock, Neue Deutsche Welle, Schlager\npop-rock, Neue Deutsche Welle, dance\npop-rock, Norteño, Cumbia\npop-rock, Norteño, bilingual\npop-rock, North African, Arabic\npop-rock, North African, Middle Eastern\npop-rock, OPM, retro\npop-rock, Persian folk, Middle Eastern fusion\npop-rock, Persian pop, cinematic\npop-rock, Pimba, country\npop-rock, Polish disco, synth-pop\npop-rock, Polish new wave, retro\npop-rock, Pop Indonesian\npop-rock, Pop Melayu\npop-rock, Pop Melayu, Dangdut\npop-rock, Pop Melayu, Dangdut rock\npop-rock, Pop Melayu, atmospheric\npop-rock, Pop Melayu, modern Dangdut\npop-rock, Pop Melayu, reggae pop\npop-rock, Pop Melayu, regional Mexican\npop-rock, Pop Sunda\npop-rock, Pop Sunda, Pop Jawa\npop-rock, Pop Sunda, Pop Melayu\npop-rock, Pop Sunda, festive\npop-rock, Pop Sunda, modern\npop-rock, Portuguese pop, satirical\npop-rock, Punjabi folk\npop-rock, Punjabi, cinematic\npop-rock, R&B\npop-rock, R&B, K-pop\npop-rock, R&B, MPB\npop-rock, R&B, acoustic ballad\npop-rock, R&B, ambient\npop-rock, R&B, bilingual\npop-rock, R&B, cinematic\npop-rock, R&B, electronic\npop-rock, R&B, festive\npop-rock, R&B, gospel\npop-rock, R&B, hip-hop\npop-rock, R&B, soul\npop-rock, R&B, synth-pop\npop-rock, R&B, trap\npop-rock, Romanian Christmas, modern folk\npop-rock, Romanian, funk\npop-rock, Russian bard-rock\npop-rock, Russian estrada\npop-rock, Russian estrada, 80s\npop-rock, Russian estrada, 80s rock\npop-rock, Russian estrada, 80s synth\npop-rock, Russian estrada, 90s pop\npop-rock, Russian estrada, ambient\npop-rock, Russian estrada, cinematic\npop-rock, Russian estrada, live performance\npop-rock, Russian estrada, melancholic\npop-rock, Russian estrada, sentimental\npop-rock, Russian estrada, synth-pop\npop-rock, Russian estrada, theatrical\npop-rock, Russian folk, dance\npop-rock, Russian folk-rock\npop-rock, Russian pop, 90s pop\npop-rock, Russian pop, satirical\npop-rock, Russian rock\npop-rock, Russian rock, 2000s\npop-rock, Russian rock, 80s\npop-rock, Russian rock, 90s rock\npop-rock, Russian rock, chiptune\npop-rock, Russian rock, early 2000s\npop-rock, Schlager\npop-rock, Schlager, Christmas\npop-rock, Schlager, European\npop-rock, Schlager, German\npop-rock, Schlager, German pop\npop-rock, Schlager, Neue Deutsche Welle\npop-rock, Schlager, choral\npop-rock, Schlager, cinematic\npop-rock, Schlager, retro\npop-rock, Schlager, rock 'n' roll\npop-rock, Schlager, sentimental\npop-rock, Schlager, synth-pop\npop-rock, Schlager, theatrical\npop-rock, South Asian film music, retro\npop-rock, South Asian folk\npop-rock, South Asian folk, cinematic\npop-rock, South Asian folk, electronic\npop-rock, South Asian folk, fusion\npop-rock, South Asian folk, modern rock\npop-rock, South Asian folk, patriotic\npop-rock, South Asian folk, romantic\npop-rock, South Asian folk, upbeat\npop-rock, South Asian fusion\npop-rock, South Asian fusion, Middle Eastern\npop-rock, South Asian fusion, cinematic\npop-rock, South Asian fusion, electronic rap\npop-rock, South Asian pop\npop-rock, South Asian, 80s\npop-rock, South Asian, Islamic devotional\npop-rock, South Asian, Middle Eastern\npop-rock, South Asian, anthemic\npop-rock, South Asian, atmospheric\npop-rock, South Asian, devotional\npop-rock, South Asian, live\npop-rock, South Asian, melodic\npop-rock, South Asian, modern\npop-rock, South Asian, patriotic\npop-rock, South Asian, spiritual\npop-rock, South Asian, upbeat\npop-rock, South Indian film music\npop-rock, South Indian, devotional\npop-rock, South Indian, energetic\npop-rock, South Indian, high-energy\npop-rock, South Indian, live\npop-rock, South Indian, uplifting\npop-rock, Southeast Asian ballad\npop-rock, Southeast Asian festive\npop-rock, Southeast Asian flavor\npop-rock, Southeast Asian folk\npop-rock, Southeast Asian folk, chiptune\npop-rock, Southeast Asian folk, electronic\npop-rock, Southeast Asian folk, fusion\npop-rock, Southeast Asian folk, modern fusion\npop-rock, Southeast Asian fusion\npop-rock, Southeast Asian fusion, hip-hop rock\npop-rock, Southeast Asian pop\npop-rock, Southeast Asian pop, live energy\npop-rock, Southeast Asian, Iban\npop-rock, Southeast Asian, Khmer\npop-rock, Southeast Asian, anthemic\npop-rock, Southeast Asian, atmospheric\npop-rock, Southeast Asian, ballad\npop-rock, Southeast Asian, cinematic\npop-rock, Southeast Asian, dramatic\npop-rock, Southeast Asian, electronic\npop-rock, Southeast Asian, energetic\npop-rock, Southeast Asian, indie\npop-rock, Southeast Asian, melancholic\npop-rock, Southeast Asian, modern rock\npop-rock, Southeast Asian, sentimental\npop-rock, Southeast Asian, upbeat\npop-rock, Soviet estrada, 80s\npop-rock, Soviet estrada, live performance\npop-rock, Soviet estrada, theatrical\npop-rock, Soviet-era estrada\npop-rock, Soviet-era estrada, retro\npop-rock, Soviet-era, nostalgic\npop-rock, Sunda pop, dangdut koplo\npop-rock, Sundanese\npop-rock, Sundanese folk-rock\npop-rock, Sundanese fusion\npop-rock, Sundanese rock\npop-rock, Sundanese, anthemic\npop-rock, Sundanese, ballad\npop-rock, Sundanese, blues-rock\npop-rock, Sundanese, chiptune\npop-rock, Sundanese, cinematic\npop-rock, Sundanese, dance\npop-rock, Sundanese, energetic\npop-rock, Sundanese, festive\npop-rock, Sundanese, live\npop-rock, Sundanese, quirky\npop-rock, Sundanese, satirical\npop-rock, Sundanese, sentimental\npop-rock, Sundanese, traditional\npop-rock, Sundanese, upbeat\npop-rock, Taiwanese Hokkien pop\npop-rock, Taiwanese Hokkien, cinematic\npop-rock, Taiwanese Hokkien, hip-hop\npop-rock, Taiwanese Hokkien, jazzy pop\npop-rock, Taiwanese Hokkien, orchestral\npop-rock, Taiwanese Hokkien, theatrical\npop-rock, Tamil fusion, soulful\npop-rock, Tamil pop, Bhangra\npop-rock, Tamil pop, anthemic\npop-rock, Telugu folk, chiptune\npop-rock, Thai Luk Thung\npop-rock, Thai pop, 80s/90s\npop-rock, Tibetan flavor\npop-rock, Tibetan influence\npop-rock, Tibetan style, modern C-pop\npop-rock, Turkish classical, cinematic\npop-rock, Turkish folk\npop-rock, Turkish folk, Balkan\npop-rock, Turkish folk, Middle Eastern\npop-rock, Turkish folk, arabesque\npop-rock, Turkish folk, cinematic\npop-rock, Turkish folk, melancholic\npop-rock, Turkish fusion\npop-rock, Turkish pop, cinematic\npop-rock, Turkish, Middle Eastern\npop-rock, Turkish, cinematic\npop-rock, Turkish, emotional\npop-rock, Turkish, melancholic\npop-rock, UK Hardcore\npop-rock, UK hip-hop\npop-rock, V-Pop, early 2000s\npop-rock, Vietnamese folk\npop-rock, Vietnamese pop, Latin pop, dance-pop\npop-rock, Vocaloid, electronic\npop-rock, Vocaloid, melancholic\npop-rock, Vocaloid, sentimental\npop-rock, a cappella, Christmas\npop-rock, a cappella, country-pop\npop-rock, a cappella, funk\npop-rock, accordion, bilingual\npop-rock, acoustic ballad\npop-rock, acoustic ballad, piano ballad, rock, cinematic\npop-rock, acoustic pop, contemporary pop, piano ballad\npop-rock, acoustic, lo-fi, atmospheric\npop-rock, acoustic, rock\npop-rock, adult contemporary, smooth jazz\npop-rock, adult contemporary, soul\npop-rock, alt-rock, Christmas\npop-rock, alt-rock, cinematic\npop-rock, alt-rock, hip-hop\npop-rock, alternative metal\npop-rock, alternative metal, cinematic\npop-rock, alternative rock\npop-rock, alternative rock, C-pop\npop-rock, alternative rock, French ballad\npop-rock, alternative rock, Italian funk\npop-rock, alternative rock, Mandarin ballad\npop-rock, alternative rock, acoustic ballad\npop-rock, alternative rock, dark pop\npop-rock, alternative rock, pop-punk\npop-rock, alternative rock, post-rock\npop-rock, alternative rock, rap-rock\npop-rock, alternative rock, symphonic rock\npop-rock, alternative, electronic\npop-rock, ambient rock, Indian pop\npop-rock, ambient, C-pop\npop-rock, ambient, cinematic\npop-rock, ambient, trap\npop-rock, americana, folk rock\npop-rock, anime ballad, C-pop\npop-rock, anime opening, Christian\npop-rock, anime opening, cinematic\npop-rock, anime soundtrack, cinematic\npop-rock, anime soundtrack, theatrical\npop-rock, anime theme, 2000s\npop-rock, anime theme, C-pop\npop-rock, anime theme, Mandarin rap\npop-rock, anime theme, cinematic\npop-rock, anime theme, electronic\npop-rock, anime theme, power ballad\npop-rock, anime theme, retro game\npop-rock, anime theme, theatrical\npop-rock, anime theme, upbeat\npop-rock, anime, cinematic\npop-rock, anime, theatrical\npop-rock, anthemic, choral\npop-rock, anthemic, electronic\npop-rock, anthemic, multilingual\npop-rock, anthemic, noise-rock\npop-rock, anthemic, revolutionary\npop-rock, arabesque, Turkish pop\npop-rock, arena rock, 80s rock\npop-rock, arena rock, Brazilian pop-rock\npop-rock, arena rock, cinematic\npop-rock, arena rock, electronic\npop-rock, arena rock, emotional ballad\npop-rock, arena rock, industrial\npop-rock, arena rock, synth-rock\npop-rock, art-pop, cinematic\npop-rock, art-pop, theatrical\npop-rock, atmospheric, Balkan\npop-rock, atmospheric, Southeast Asian\npop-rock, atmospheric, cinematic\npop-rock, atmospheric, dramatic\npop-rock, ballad, C-pop\npop-rock, ballad, J-pop\npop-rock, ballad, Sundanese\npop-rock, ballad, Vietnamese\npop-rock, ballad, flamenco\npop-rock, ballad, orchestral\npop-rock, bansuri, dangdut\npop-rock, baroque pop\npop-rock, baroque-pop, cinematic\npop-rock, baroque-pop, theatrical\npop-rock, bhajan, Indian fusion\npop-rock, big band jazz\npop-rock, big band, Latin\npop-rock, big band, Latin pop\npop-rock, big band, Mizrahi\npop-rock, big band, boogie-woogie\npop-rock, big band, brass\npop-rock, big band, cabaret\npop-rock, big band, chiptune\npop-rock, big band, cinematic\npop-rock, big band, comedic\npop-rock, big band, disco\npop-rock, big band, funk\npop-rock, big band, hip-hop\npop-rock, big band, jazz\npop-rock, big band, klezmer\npop-rock, big band, retro\npop-rock, big band, schlager\npop-rock, big band, show tune\npop-rock, big band, ska\npop-rock, big band, soul\npop-rock, big band, soulful\npop-rock, big band, swing\npop-rock, big band, theatrical\npop-rock, big band, trot\npop-rock, big room EDM\npop-rock, big room house\npop-rock, big-band, art-pop\npop-rock, big-band, swing\npop-rock, big-band, theatrical\npop-rock, bilingual, South Asian\npop-rock, bilingual, Spanish-style\npop-rock, bilingual, anime theme\npop-rock, bilingual, ballad\npop-rock, bilingual, cinematic\npop-rock, bilingual, dance-rock\npop-rock, bilingual, electronic\npop-rock, bilingual, flamenco\npop-rock, bilingual, folk rock\npop-rock, bilingual, funk\npop-rock, bilingual, hip-hop\npop-rock, bilingual, late-90s\npop-rock, bilingual, power ballad\npop-rock, bilingual, synth-pop\npop-rock, bilingual, upbeat\npop-rock, blues rock, C-pop\npop-rock, blues rock, Chinese fusion\npop-rock, blues rock, country rock\npop-rock, blues, city-pop\npop-rock, blues, funk\npop-rock, blues, melancholic\npop-rock, blues, ska\npop-rock, blues, swing\npop-rock, blues-rock\npop-rock, blues-rock, C-pop\npop-rock, blues-rock, Dangdut\npop-rock, blues-rock, Indian classical\npop-rock, blues-rock, Italian rock\npop-rock, blues-rock, Mediterranean\npop-rock, blues-rock, Russian folk\npop-rock, blues-rock, Tibetan fusion\npop-rock, blues-rock, cinematic\npop-rock, blues-rock, psychedelic rock\npop-rock, blues-rock, theatrical\npop-rock, blues-rock, traditional Indonesian\npop-rock, bolero, live\npop-rock, boogie-woogie, Indonesian pop\npop-rock, boogie-woogie, big band\npop-rock, boogie-woogie, blues rock\npop-rock, boogie-woogie, cabaret\npop-rock, boogie-woogie, estrada\npop-rock, boogie-woogie, punk-rock\npop-rock, boogie-woogie, rock and roll\npop-rock, boogie-woogie, satirical\npop-rock, boogie-woogie, theatrical\npop-rock, bossa nova\npop-rock, bossa nova, Brazilian pop\npop-rock, bossa nova, Latin\npop-rock, bossa nova, Latin pop\npop-rock, brass, South Asian\npop-rock, breakbeat, hard rock\npop-rock, breakcore, glitch-hop\npop-rock, brostep\npop-rock, bubblegum pop\npop-rock, cabaret, 70s Israeli pop\npop-rock, cabaret, Balkan\npop-rock, cabaret, Eastern European\npop-rock, cabaret, Eastern European folk\npop-rock, cabaret, European folk\npop-rock, cabaret, J-pop\npop-rock, cabaret, Turkish folk\npop-rock, cabaret, chanson\npop-rock, cabaret, cinematic\npop-rock, cabaret, folk\npop-rock, cabaret, funk\npop-rock, cabaret, orchestral\npop-rock, cabaret, polka\npop-rock, cabaret, psychedelic\npop-rock, cabaret, retro\npop-rock, cabaret, tango\npop-rock, cabaret, theatrical\npop-rock, cabaret, whimsical\npop-rock, cantopop, flamenco rock\npop-rock, chalga, cinematic\npop-rock, chamber, hip-hop\npop-rock, chanson, Eastern European\npop-rock, chanson, European\npop-rock, chanson, French-Canadian\npop-rock, chanson, big band\npop-rock, chanson, cinematic\npop-rock, chanson, folk\npop-rock, chanson, melancholic\npop-rock, chanson, military\npop-rock, chanson, retro\npop-rock, chanson, romantic\npop-rock, chanson, theatrical\npop-rock, chanson, vintage\npop-rock, children's choir, ska-punk\npop-rock, children's music\npop-rock, children's music, Brazilian\npop-rock, children's music, rock\npop-rock, chiptune\npop-rock, chiptune, Balkan\npop-rock, chiptune, C-pop\npop-rock, chiptune, Christmas\npop-rock, chiptune, J-pop\npop-rock, chiptune, J-rock\npop-rock, chiptune, Javanese\npop-rock, chiptune, Khmer rock\npop-rock, chiptune, Latin pop\npop-rock, chiptune, Luk Thung\npop-rock, chiptune, Mandopop\npop-rock, chiptune, Middle Eastern\npop-rock, chiptune, Russian pop\npop-rock, chiptune, ambient\npop-rock, chiptune, anime\npop-rock, chiptune, cinematic\npop-rock, chiptune, dance-pop\npop-rock, chiptune, electronic\npop-rock, chiptune, energetic\npop-rock, chiptune, epic\npop-rock, chiptune, folk\npop-rock, chiptune, hip hop\npop-rock, chiptune, indie rock\npop-rock, chiptune, lo-fi\npop-rock, chiptune, metalcore\npop-rock, chiptune, nu-metal\npop-rock, chiptune, power-pop\npop-rock, chiptune, retro\npop-rock, chiptune, synth-pop\npop-rock, chiptune, theatrical\npop-rock, choral, Balkan folk\npop-rock, cinematic pop, hip-hop\npop-rock, cinematic rock\npop-rock, cinematic rock, Indian fusion\npop-rock, cinematic rock, metal-influenced\npop-rock, cinematic rock, world fusion\npop-rock, cinematic, 2000s Russian pop\npop-rock, cinematic, 60s vibe\npop-rock, cinematic, 80s/90s Southeast Asian pop\npop-rock, cinematic, Afrikaans\npop-rock, cinematic, Arabic fusion\npop-rock, cinematic, Asian fusion\npop-rock, cinematic, Balkan\npop-rock, cinematic, Balkan folk\npop-rock, cinematic, Balkan pop\npop-rock, cinematic, Balkan pop-folk\npop-rock, cinematic, Balkan power ballad\npop-rock, cinematic, Brazilian pop\npop-rock, cinematic, C-pop\npop-rock, cinematic, Central Asian\npop-rock, cinematic, Chinese\npop-rock, cinematic, Chinese classical\npop-rock, cinematic, Chinese flute\npop-rock, cinematic, Chinese folk\npop-rock, cinematic, Chinese fusion\npop-rock, cinematic, Chinese historical drama\npop-rock, cinematic, Chinese opera\npop-rock, cinematic, Chinese pop\npop-rock, cinematic, Chinese traditional\npop-rock, cinematic, EDM\npop-rock, cinematic, East Asian\npop-rock, cinematic, Eastern European\npop-rock, cinematic, Eastern European folk\npop-rock, cinematic, Eastern European pop\npop-rock, cinematic, Eastern-influenced\npop-rock, cinematic, European folk\npop-rock, cinematic, French pop\npop-rock, cinematic, Hebrew\npop-rock, cinematic, Hebrew pop\npop-rock, cinematic, Hebrew vocal\npop-rock, cinematic, Hindi\npop-rock, cinematic, Hindi ballad\npop-rock, cinematic, Indian classical\npop-rock, cinematic, Indian film music\npop-rock, cinematic, Indian folk\npop-rock, cinematic, Indian fusion\npop-rock, cinematic, Indonesian pop\npop-rock, cinematic, Italian\npop-rock, cinematic, Italian ballad\npop-rock, cinematic, Italian folk\npop-rock, cinematic, J-Rock\npop-rock, cinematic, J-rock\npop-rock, cinematic, Javanese\npop-rock, cinematic, Javanese folk\npop-rock, cinematic, Javanese pop\npop-rock, cinematic, Javanese traditional\npop-rock, cinematic, K-ballad\npop-rock, cinematic, K-pop\npop-rock, cinematic, Khmer\npop-rock, cinematic, Latin\npop-rock, cinematic, Latin pop\npop-rock, cinematic, Latin-pop\npop-rock, cinematic, Malay pop\npop-rock, cinematic, Malay traditional\npop-rock, cinematic, Mandarin\npop-rock, cinematic, Mandarin ballad\npop-rock, cinematic, Mandarin pop\npop-rock, cinematic, Mandarin rock\npop-rock, cinematic, Middle Eastern\npop-rock, cinematic, Middle Eastern fusion\npop-rock, cinematic, Mizrahi\npop-rock, cinematic, Neapolitan\npop-rock, cinematic, Persian\npop-rock, cinematic, Russian estrada\npop-rock, cinematic, Russian vocal\npop-rock, cinematic, South Asian\npop-rock, cinematic, South Asian fusion\npop-rock, cinematic, South Indian\npop-rock, cinematic, South Indian film music\npop-rock, cinematic, Southeast Asian\npop-rock, cinematic, Sundanese\npop-rock, cinematic, Taiwanese Hokkien\npop-rock, cinematic, Tamil\npop-rock, cinematic, Tamil hip hop\npop-rock, cinematic, Turkish pop\npop-rock, cinematic, Vietnamese\npop-rock, cinematic, Vietnamese folk\npop-rock, cinematic, Vietnamese pop\npop-rock, cinematic, ambient\npop-rock, cinematic, anime\npop-rock, cinematic, anime soundtrack\npop-rock, cinematic, anime theme\npop-rock, cinematic, anime-inspired\npop-rock, cinematic, anthemic\npop-rock, cinematic, art pop\npop-rock, cinematic, ballad\npop-rock, cinematic, big band\npop-rock, cinematic, bilingual\npop-rock, cinematic, blues-rock\npop-rock, cinematic, cabaret\npop-rock, cinematic, chiptune\npop-rock, cinematic, classical\npop-rock, cinematic, dance-pop\npop-rock, cinematic, dramatic\npop-rock, cinematic, dream pop\npop-rock, cinematic, dubstep\npop-rock, cinematic, electronic\npop-rock, cinematic, emo-rock\npop-rock, cinematic, emotional\npop-rock, cinematic, emotional rock\npop-rock, cinematic, epic\npop-rock, cinematic, estrada\npop-rock, cinematic, festive\npop-rock, cinematic, flamenco\npop-rock, cinematic, folk\npop-rock, cinematic, folk rock\npop-rock, cinematic, folk-rock\npop-rock, cinematic, funk-rock\npop-rock, cinematic, futuristic\npop-rock, cinematic, gospel\npop-rock, cinematic, hard rock\npop-rock, cinematic, hip-hop\npop-rock, cinematic, indie\npop-rock, cinematic, industrial\npop-rock, cinematic, inspirational\npop-rock, cinematic, jazz\npop-rock, cinematic, jazz fusion\npop-rock, cinematic, lo-fi\npop-rock, cinematic, lo-fi hip hop\npop-rock, cinematic, marching band\npop-rock, cinematic, metalcore\npop-rock, cinematic, musical theater\npop-rock, cinematic, neo-classical\npop-rock, cinematic, nu-metal\npop-rock, cinematic, operatic\npop-rock, cinematic, orchestral\npop-rock, cinematic, patriotic\npop-rock, cinematic, power ballad\npop-rock, cinematic, rap\npop-rock, cinematic, rap-rock\npop-rock, cinematic, satirical\npop-rock, cinematic, show tune\npop-rock, cinematic, show-tune\npop-rock, cinematic, spiritual\npop-rock, cinematic, spy-movie\npop-rock, cinematic, symphonic metal\npop-rock, cinematic, symphonic rock\npop-rock, cinematic, synthwave\npop-rock, cinematic, tango\npop-rock, cinematic, theatrical\npop-rock, cinematic, traditional fusion\npop-rock, cinematic, trap\npop-rock, cinematic, urban\npop-rock, cinematic, video game theme\npop-rock, cinematic, vintage\npop-rock, cinematic, world fusion\npop-rock, cinematic, world music\npop-rock, circus, big band\npop-rock, city pop, 90s\npop-rock, city pop, AOR\npop-rock, city pop, J-rock\npop-rock, city pop, aor\npop-rock, city pop, bilingual\npop-rock, city pop, retro\npop-rock, city pop, soul\npop-rock, city-pop, funk\npop-rock, city-pop, hard rock\npop-rock, city-pop, retro\npop-rock, city-pop, upbeat\npop-rock, classic rock\npop-rock, classic rock, blues-rock\npop-rock, classical fusion, hip-hop\npop-rock, classical, C-pop\npop-rock, classical, cinematic\npop-rock, classical, folk\npop-rock, classical, musical theater\npop-rock, classical, theatrical\npop-rock, comedic pop, Pop Sunda\npop-rock, comedic, Christmas\npop-rock, comedic, satirical\npop-rock, comedic, theatrical\npop-rock, complextro, cinematic\npop-rock, conscious hip-hop\npop-rock, contemporary Christian\npop-rock, contemporary Christian music\npop-rock, contemporary Christian, gospel\npop-rock, contemporary gospel\npop-rock, cool jazz, funk-rock\npop-rock, country, blues-rock\npop-rock, country, danseband\npop-rock, country, gospel\npop-rock, country, rockabilly\npop-rock, country, show tune\npop-rock, country-pop\npop-rock, country-pop, college rock\npop-rock, country-rock, blues rock\npop-rock, country-rock, novelty\npop-rock, country-rock, tropical\npop-rock, cumbia, Eastern European\npop-rock, cumbia, Filipino\npop-rock, cumbia, Latin\npop-rock, cyberpunk, electronic\npop-rock, dance, Christian praise\npop-rock, dance-pop\npop-rock, dance-pop, C-pop\npop-rock, dance-pop, EDM\npop-rock, dance-pop, Hebrew vocal\npop-rock, dance-pop, Polish\npop-rock, dance-pop, ballad\npop-rock, dance-pop, cinematic\npop-rock, dance-pop, electronic\npop-rock, dance-pop, klezmer\npop-rock, dance-pop, piano ballad\npop-rock, dancehall, reggae\npop-rock, dangdut\npop-rock, dangdut koplo\npop-rock, dangdut koplo, Javanese\npop-rock, dangdut koplo, Javanese ballad\npop-rock, dangdut koplo, Javanese folk\npop-rock, dangdut koplo, Javanese pop\npop-rock, dangdut koplo, Southeast Asian\npop-rock, dangdut koplo, blues\npop-rock, dangdut koplo, chiptune\npop-rock, dangdut koplo, cinematic\npop-rock, dangdut koplo, cinematic metal\npop-rock, dangdut koplo, cinematic rock\npop-rock, dangdut koplo, classical\npop-rock, dangdut koplo, electronic dance\npop-rock, dangdut koplo, modern pop\npop-rock, dangdut koplo, retro\npop-rock, dangdut koplo, rock\npop-rock, dangdut koplo, sentimental pop\npop-rock, dangdut koplo, slow rock\npop-rock, dangdut koplo, surf rock\npop-rock, dangdut rock\npop-rock, dangdut, Indonesian\npop-rock, dangdut, Indonesian pop\npop-rock, dangdut, Javanese\npop-rock, dangdut, Javanese hip-hop\npop-rock, dangdut, Middle Eastern\npop-rock, dangdut, Southeast Asian\npop-rock, dangdut, Sundanese pop\npop-rock, dangdut, ambient\npop-rock, dangdut, ballad\npop-rock, dangdut, chiptune\npop-rock, dangdut, cinematic\npop-rock, dangdut, comedic\npop-rock, dangdut, comedy rock\npop-rock, dangdut, dance rock\npop-rock, dangdut, electronic\npop-rock, dangdut, energetic\npop-rock, dangdut, funk\npop-rock, dangdut, hard rock\npop-rock, dangdut, indie pop\npop-rock, dangdut, jazzy\npop-rock, dangdut, live\npop-rock, dangdut, live energy\npop-rock, dangdut, melayu\npop-rock, dangdut, modern\npop-rock, dangdut, pop melayu\npop-rock, dangdut, retro\npop-rock, dangdut, rock\npop-rock, dangdut, ska\npop-rock, dangdut, soul\npop-rock, dangdut, sunda\npop-rock, dangdut, surf rock\npop-rock, dangdut, theatrical\npop-rock, dangdut, upbeat\npop-rock, dansband, schlager\npop-rock, devotional, blues-rock\npop-rock, devotional, festive\npop-rock, devotional, world fusion\npop-rock, disco polo\npop-rock, disco polo, novelty\npop-rock, disco, Balkan\npop-rock, disco, big band\npop-rock, disco, theatrical\npop-rock, disco-funk, cinematic\npop-rock, disco-funk, hard rock\npop-rock, disco-funk, theatrical\npop-rock, disco-pop\npop-rock, doo-wop\npop-rock, doo-wop, 1960s\npop-rock, doo-wop, early rock and roll\npop-rock, doo-wop, garage rock\npop-rock, doo-wop, retro\npop-rock, doo-wop, rock and roll\npop-rock, doo-wop, soul\npop-rock, doo-wop, theatrical\npop-rock, doo-wop, vintage\npop-rock, dream pop, dubstep\npop-rock, dream-pop\npop-rock, dreamy, funk-rock\npop-rock, dreamy, nostalgic\npop-rock, drum and bass\npop-rock, drum and bass, cinematic\npop-rock, dubstep\npop-rock, dubstep, C-pop\npop-rock, dubstep, acoustic ballad\npop-rock, dubstep, ambient\npop-rock, dubstep, atmospheric\npop-rock, dubstep, cinematic\npop-rock, dubstep, emotional\npop-rock, dubstep, metalcore\npop-rock, dubstep, rap\npop-rock, dubstep, trap\npop-rock, early 2000s Chinese rock\npop-rock, early 2000s R&B\npop-rock, educational, 80s synth\npop-rock, educational, funk\npop-rock, educational, show tune\npop-rock, educational, world percussion\npop-rock, electro house\npop-rock, electro house, big room\npop-rock, electro-funk\npop-rock, electro-house\npop-rock, electro-pop, EDM\npop-rock, electro-pop, chiptune\npop-rock, electro-pop, hip-hop\npop-rock, electronic dance\npop-rock, electronic dance, Indian folk\npop-rock, electronic dance, cinematic\npop-rock, electronic dance, sports anthem\npop-rock, electronic rock, C-pop\npop-rock, electronic rock, dance-pop\npop-rock, electronic rock, lo-fi hip-hop\npop-rock, electronic rock, trance\npop-rock, electronic, Afrikaans\npop-rock, electronic, Balkan\npop-rock, electronic, C-pop\npop-rock, electronic, Chinese opera\npop-rock, electronic, EDM\npop-rock, electronic, German spoken word\npop-rock, electronic, Indian folk\npop-rock, electronic, Indian fusion\npop-rock, electronic, J-rock\npop-rock, electronic, K-pop\npop-rock, electronic, Latin pop\npop-rock, electronic, Mandarin rap\npop-rock, electronic, Middle Eastern\npop-rock, electronic, Middle Eastern fusion\npop-rock, electronic, Persian\npop-rock, electronic, R&B\npop-rock, electronic, Russian pop\npop-rock, electronic, Sinhala\npop-rock, electronic, South Indian folk\npop-rock, electronic, South Indian fusion\npop-rock, electronic, Sundanese\npop-rock, electronic, Thai pop\npop-rock, electronic, anime\npop-rock, electronic, bilingual\npop-rock, electronic, blues-rock\npop-rock, electronic, chiptune\npop-rock, electronic, cinematic\npop-rock, electronic, dance\npop-rock, electronic, dance-pop\npop-rock, electronic, drum and bass\npop-rock, electronic, emo-pop\npop-rock, electronic, funk\npop-rock, electronic, gospel\npop-rock, electronic, hip hop\npop-rock, electronic, hip-hop\npop-rock, electronic, hyperpop\npop-rock, electronic, industrial\npop-rock, electronic, metalcore\npop-rock, electronic, nu-metal\npop-rock, electronic, protest anthem\npop-rock, electronic, rap\npop-rock, electronic, rock\npop-rock, electronic, theatrical\npop-rock, electronic, trap\npop-rock, electronic, world fusion\npop-rock, electronic, world music\npop-rock, electronic, worship\npop-rock, electronicore, C-pop\npop-rock, electronicore, cinematic\npop-rock, electronicore, dubstep\npop-rock, emo, alternative rock\npop-rock, emo, electronic\npop-rock, emo, hyperpop\npop-rock, emo-pop, indie rock\npop-rock, emo-rock, C-pop\npop-rock, emo-rock, Mandarin ballad\npop-rock, emo-rock, ballad\npop-rock, emotional, Indonesian\npop-rock, emotional, Italian\npop-rock, emotional, bilingual\npop-rock, emotional, cinematic\npop-rock, emotional, hip-hop\npop-rock, emotional, metalcore\npop-rock, emotional, power ballad\npop-rock, epic, Middle Eastern\npop-rock, epic, traditional Central Asian\npop-rock, estrada\npop-rock, estrada, 80s\npop-rock, estrada, 80s Russian\npop-rock, estrada, 80s pop\npop-rock, estrada, 80s rock\npop-rock, estrada, 80s synth\npop-rock, estrada, Eastern European\npop-rock, estrada, Soviet pop\npop-rock, estrada, Soviet-era\npop-rock, estrada, blues\npop-rock, estrada, cinematic\npop-rock, estrada, classic rock\npop-rock, estrada, classical\npop-rock, estrada, dance\npop-rock, estrada, eastern european\npop-rock, estrada, electronic\npop-rock, estrada, festive\npop-rock, estrada, folk rock\npop-rock, estrada, folk-pop\npop-rock, estrada, melancholic\npop-rock, estrada, nostalgic\npop-rock, estrada, patriotic\npop-rock, estrada, retro\npop-rock, estrada, romantic\npop-rock, estrada, ska\npop-rock, estrada, synth ballad\npop-rock, estrada, synth brass\npop-rock, estrada, synth-pop\npop-rock, estrada, synth-rock\npop-rock, estrada, synthwave\npop-rock, estrada, theatrical\npop-rock, estrada, vintage\npop-rock, ethereal, cinematic\npop-rock, ethereal, hyperpop\npop-rock, ethnic fusion, cinematic\npop-rock, ethno-pop, Balkan\npop-rock, euro pop, southeast asian pop\npop-rock, euro-pop, 2000s\npop-rock, euro-pop, 90s\npop-rock, euro-pop, novelty\npop-rock, eurobeat\npop-rock, eurodance\npop-rock, eurodance, 2000s\npop-rock, eurodance, 90s\npop-rock, eurodance, Latin pop\npop-rock, eurodance, Portuguese\npop-rock, eurodance, anthemic\npop-rock, eurodance, ballad\npop-rock, eurodance, chiptune\npop-rock, eurodance, cinematic\npop-rock, eurodance, dance-pop\npop-rock, eurodance, dance-rock\npop-rock, eurodance, electronic\npop-rock, eurodance, german\npop-rock, eurodance, lo-fi\npop-rock, eurodance, pimba\npop-rock, eurodance, retro\npop-rock, eurodance, russian\npop-rock, eurodance, synth-pop\npop-rock, eurodance, synthwave\npop-rock, eurodance, theatrical\npop-rock, eurodance, trance\npop-rock, eurodance, trance-pop\npop-rock, eurodance, turbo-folk\npop-rock, festive, Christmas\npop-rock, festive, Malay\npop-rock, festive, Mongolian\npop-rock, festive, accordion\npop-rock, festive, anthemic\npop-rock, festive, ballad\npop-rock, festive, cinematic\npop-rock, festive, jazz-fusion\npop-rock, festive, mariachi\npop-rock, festive, theatrical\npop-rock, filmi, anthemic\npop-rock, filmi, upbeat\npop-rock, flamenco, Balkan\npop-rock, flamenco, C-pop\npop-rock, flamenco, Central Asian\npop-rock, flamenco, Eastern European\npop-rock, flamenco, Hebrew pop\npop-rock, flamenco, Italian\npop-rock, flamenco, K-rap, R&B\npop-rock, flamenco, Latin\npop-rock, flamenco, Latin-pop\npop-rock, flamenco, Mediterranean\npop-rock, flamenco, Middle Eastern\npop-rock, flamenco, Turkish\npop-rock, flamenco, bilingual\npop-rock, flamenco, cinematic\npop-rock, flamenco, electronic\npop-rock, flamenco, folk\npop-rock, flamenco, industrial rock\npop-rock, flamenco, jazz-fusion\npop-rock, flamenco, melancholic\npop-rock, folk anthem, musical theatre\npop-rock, folk fusion, Azerbaijani\npop-rock, folk fusion, Bengali\npop-rock, folk fusion, South Asian\npop-rock, folk fusion, dangdut\npop-rock, folk rock\npop-rock, folk rock, Azerbaijani\npop-rock, folk rock, Cantonese rock\npop-rock, folk rock, Eastern European\npop-rock, folk rock, Malay pop\npop-rock, folk rock, anthemic\npop-rock, folk rock, rockabilly\npop-rock, folk, Anatolian\npop-rock, folk, Azerbaijani\npop-rock, folk, Central Asian\npop-rock, folk, Chinese folk\npop-rock, folk, EDM\npop-rock, folk, Eastern European\npop-rock, folk, Indonesian\npop-rock, folk, Mongolian\npop-rock, folk, Russian estrada\npop-rock, folk, South Asian\npop-rock, folk, Southeast Asian\npop-rock, folk, atmospheric\npop-rock, folk, big band\npop-rock, folk, blues-rock\npop-rock, folk, chanson\npop-rock, folk, chiptune\npop-rock, folk, cinematic\npop-rock, folk, dangdut\npop-rock, folk, disco\npop-rock, folk, electronic\npop-rock, folk, hip-hop\npop-rock, folk, jazz\npop-rock, folk, klezmer\npop-rock, folk, melancholic\npop-rock, folk, operatic\npop-rock, folk, patriotic\npop-rock, folk, piano ballad\npop-rock, folk, polka\npop-rock, folk, power ballad\npop-rock, folk, rock\npop-rock, folk, sentimental\npop-rock, folk, tango\npop-rock, folk, theatrical\npop-rock, folk-infused, lo-fi\npop-rock, folk-pop\npop-rock, folk-pop, Azerbaijani\npop-rock, folk-pop, Eastern European\npop-rock, folk-pop, cinematic\npop-rock, folk-pop, theatrical\npop-rock, folk-rock, Eastern European\npop-rock, folk-rock, boogie-woogie\npop-rock, folk-rock, festive\npop-rock, folk-rock, klezmer\npop-rock, folk-rock, polka-rock\npop-rock, forró, MPB\npop-rock, forró, ballad\npop-rock, forró, brega\npop-rock, forró, cinematic\npop-rock, forró, electronic\npop-rock, forró, energetic\npop-rock, forró, frevo\npop-rock, forró, live\npop-rock, forró, sertanejo\npop-rock, funk, Indian classical\npop-rock, funk, Indian pop\npop-rock, funk, Italian style\npop-rock, funk, Middle Eastern\npop-rock, funk, R&B\npop-rock, funk, Telugu pop\npop-rock, funk, cinematic\npop-rock, funk, disco\npop-rock, funk, electronic\npop-rock, funk, gospel\npop-rock, funk, hip-hop\npop-rock, funk, indie rock\npop-rock, funk, klezmer\npop-rock, funk, ska\npop-rock, funk, soul\npop-rock, funk, theatrical\npop-rock, funk, worship\npop-rock, funk-pop\npop-rock, funk-rock, Italian\npop-rock, funk-rock, Latin pop\npop-rock, funk-rock, blues-rock\npop-rock, funk-rock, hip-hop\npop-rock, funk-rock, soul\npop-rock, funk-rock, theatrical rock\npop-rock, fusion, Indian electronic\npop-rock, future bass\npop-rock, future bass, C-pop\npop-rock, future bass, EDM\npop-rock, future bass, Hindi pop\npop-rock, future bass, K-pop\npop-rock, future bass, Latin pop\npop-rock, future bass, Mandarin rap\npop-rock, future bass, R&B\npop-rock, future bass, Russian pop\npop-rock, future bass, ambient\npop-rock, future bass, arena rock\npop-rock, future bass, chiptune\npop-rock, future bass, cinematic\npop-rock, future bass, color bass\npop-rock, future bass, complextro\npop-rock, future bass, country-pop\npop-rock, future bass, dream pop\npop-rock, future bass, dubstep\npop-rock, future bass, electronic\npop-rock, future bass, emotional\npop-rock, future bass, emotional piano\npop-rock, future bass, gospel\npop-rock, future bass, hardstyle\npop-rock, future bass, hip-hop\npop-rock, future bass, lo-fi\npop-rock, future bass, melodic dubstep\npop-rock, future bass, piano ballad\npop-rock, future bass, rap\npop-rock, future bass, trap\npop-rock, garage rock, French pop\npop-rock, garage rock, retro\npop-rock, garage rock, vintage\npop-rock, ghazal, South Asian fusion\npop-rock, ghazal, ambient fusion\npop-rock, glam metal\npop-rock, glam metal, J-rock\npop-rock, glam rock\npop-rock, glam rock, 80s\npop-rock, glam rock, 80s rock\npop-rock, glam rock, J-rock\npop-rock, glam rock, art rock\npop-rock, glitch, electronic\npop-rock, gospel rock, Indonesian pop\npop-rock, gospel, CCM\npop-rock, gospel, EDM\npop-rock, gospel, J-rock\npop-rock, gospel, MPB\npop-rock, gospel, R&B\npop-rock, gospel, a cappella\npop-rock, gospel, anthemic\npop-rock, gospel, big band\npop-rock, gospel, chiptune\npop-rock, gospel, cinematic\npop-rock, gospel, electronic\npop-rock, gospel, funk\npop-rock, gospel, hard rock\npop-rock, gospel, hip-hop\npop-rock, gospel, hymn\npop-rock, gospel, klezmer\npop-rock, gospel, musical theater\npop-rock, gospel, psychedelic\npop-rock, gospel, rock\npop-rock, gospel, ska\npop-rock, gospel, soul\npop-rock, gospel, spiritual\npop-rock, gospel, theatrical\npop-rock, gospel, world music\npop-rock, gospel-rock, folk\npop-rock, gothic, anime soundtrack\npop-rock, guzheng fusion, arena rock\npop-rock, gypsy-jazz, theatrical\npop-rock, happy hardcore\npop-rock, hard rock\npop-rock, hard rock, 80s rock\npop-rock, hard rock, C-pop\npop-rock, hard rock, Cantopop\npop-rock, hard rock, Chinese ballad\npop-rock, hard rock, Chinese rock\npop-rock, hard rock, German vocal\npop-rock, hard rock, Indonesian folk\npop-rock, hard rock, Indonesian pop\npop-rock, hard rock, Italian hip-hop\npop-rock, hard rock, J-pop\npop-rock, hard rock, JRPG\npop-rock, hard rock, Javanese\npop-rock, hard rock, Javanese vocal\npop-rock, hard rock, Latin pop\npop-rock, hard rock, Mandarin ballad\npop-rock, hard rock, Mandarin rock\npop-rock, hard rock, Middle Eastern\npop-rock, hard rock, Mongolian folk rock\npop-rock, hard rock, Persian pop\npop-rock, hard rock, R&B\npop-rock, hard rock, Spanish-influenced\npop-rock, hard rock, Sundanese\npop-rock, hard rock, Sundanese folk\npop-rock, hard rock, acoustic\npop-rock, hard rock, acoustic ballad\npop-rock, hard rock, ballad\npop-rock, hard rock, blues-rock\npop-rock, hard rock, chiptune\npop-rock, hard rock, cinematic\npop-rock, hard rock, cinematic rock\npop-rock, hard rock, emotional\npop-rock, hard rock, glam metal\npop-rock, hard rock, lo-fi\npop-rock, hard rock, lo-fi hip-hop\npop-rock, hard rock, metal\npop-rock, hard rock, metalcore\npop-rock, hard rock, piano ballad\npop-rock, hard rock, progressive metal\npop-rock, hard rock, psychedelic\npop-rock, hard rock, rap\npop-rock, hard rock, rap rock\npop-rock, hard rock, rap-rock\npop-rock, hard rock, retro\npop-rock, hard rock, shred guitar\npop-rock, hard rock, traditional Asian\npop-rock, hard rock, world music\npop-rock, hardstyle\npop-rock, hardstyle, C-pop\npop-rock, hardstyle, ambient\npop-rock, hardstyle, big room house\npop-rock, hardstyle, cinematic\npop-rock, hardstyle, complextro\npop-rock, hardstyle, dubstep\npop-rock, hardstyle, electronic\npop-rock, hardstyle, happy hardcore\npop-rock, hardstyle, lo-fi\npop-rock, hardstyle, theatrical\npop-rock, hardstyle, trance\npop-rock, heartland rock\npop-rock, heartland rock, 80s\npop-rock, heavy metal\npop-rock, heavy metal, Indonesian pop\npop-rock, heavy metal, piano ballad\npop-rock, heavy rock, Tamil pop\npop-rock, hip hop, C-pop\npop-rock, hip-hop\npop-rock, hip-hop, C-pop\npop-rock, hip-hop, Cantonese\npop-rock, hip-hop, Cantopop\npop-rock, hip-hop, Chinese opera\npop-rock, hip-hop, Christmas\npop-rock, hip-hop, EDM\npop-rock, hip-hop, German pop\npop-rock, hip-hop, Hebrew pop\npop-rock, hip-hop, Hebrew vocal\npop-rock, hip-hop, Indian fusion\npop-rock, hip-hop, Indonesian pop\npop-rock, hip-hop, Italian folk\npop-rock, hip-hop, Javanese\npop-rock, hip-hop, Javanese ballad\npop-rock, hip-hop, Javanese folk\npop-rock, hip-hop, Latin\npop-rock, hip-hop, Malaysian pop\npop-rock, hip-hop, Mongolian\npop-rock, hip-hop, R&B\npop-rock, hip-hop, Romanian\npop-rock, hip-hop, South Asian pop\npop-rock, hip-hop, Sundanese\npop-rock, hip-hop, Thai pop\npop-rock, hip-hop, acoustic\npop-rock, hip-hop, acoustic ballad\npop-rock, hip-hop, ambient\npop-rock, hip-hop, anthemic\npop-rock, hip-hop, arena rock\npop-rock, hip-hop, atmospheric\npop-rock, hip-hop, ballad\npop-rock, hip-hop, bilingual\npop-rock, hip-hop, chiptune\npop-rock, hip-hop, cinematic\npop-rock, hip-hop, cinematic ballad\npop-rock, hip-hop, dancehall\npop-rock, hip-hop, dubstep\npop-rock, hip-hop, electronic\npop-rock, hip-hop, emotional\npop-rock, hip-hop, emotional ballad\npop-rock, hip-hop, ethereal\npop-rock, hip-hop, folk\npop-rock, hip-hop, funk\npop-rock, hip-hop, future bass\npop-rock, hip-hop, gospel\npop-rock, hip-hop, hard rock\npop-rock, hip-hop, heartland rock\npop-rock, hip-hop, indie pop\npop-rock, hip-hop, inspirational\npop-rock, hip-hop, lo-fi\npop-rock, hip-hop, metalcore\npop-rock, hip-hop, nu-metal\npop-rock, hip-hop, piano ballad\npop-rock, hip-hop, pop-ballad, dance-pop\npop-rock, hip-hop, post-hardcore\npop-rock, hip-hop, rap-rock\npop-rock, hip-hop, rock\npop-rock, hip-hop, rock anthem\npop-rock, hip-hop, salsa\npop-rock, hip-hop, synth\npop-rock, hip-hop, traditional Thai\npop-rock, hip-hop, vaporwave\npop-rock, hip-hop, world music\npop-rock, hip-hop/R&B\npop-rock, holiday, playful\npop-rock, horror-rock, theatrical\npop-rock, hyperpop\npop-rock, hyperpop, Vietnamese pop\npop-rock, hyperpop, chiptune\npop-rock, hyperpop, cinematic\npop-rock, hyperpop, electronic\npop-rock, hyperpop, emo\npop-rock, hyperpop, emotional ballad\npop-rock, hyperpop, lo-fi\npop-rock, hyperpop, metalcore\npop-rock, hyperpop, piano ballad\npop-rock, hyperpop, rap\npop-rock, hyperpop, satirical\npop-rock, indie ballad, Chinese rock\npop-rock, indie folk, cinematic\npop-rock, indie pop, South Asian ballad\npop-rock, indie rock\npop-rock, indie rock, C-pop\npop-rock, indie rock, R&B\npop-rock, indie rock, alt-country\npop-rock, indie rock, hip-hop\npop-rock, indie rock, metalcore\npop-rock, indie-pop\npop-rock, indie-pop, bilingual\npop-rock, industrial rock\npop-rock, inspirational hip-hop\npop-rock, island-rock, tropical\npop-rock, jazz fusion\npop-rock, jazz fusion, city pop\npop-rock, jazz fusion, funk\npop-rock, jazz fusion, progressive rock\npop-rock, jazz fusion, spy theme\npop-rock, jazz, Russian chanson\npop-rock, jazz, ballad\npop-rock, jazz, big band\npop-rock, jazz, cabaret\npop-rock, jazz, cinematic\npop-rock, jazz, funk\npop-rock, jazz, hip-hop\npop-rock, jazz, soul\npop-rock, jazz, theatrical\npop-rock, jazz, upbeat\npop-rock, jazz-fusion, Mandarin\npop-rock, jazz-fusion, cinematic\npop-rock, jazz-rock, Javanese folk\npop-rock, klezmer, Balkan\npop-rock, klezmer, Balkan brass\npop-rock, klezmer, Eastern European folk\npop-rock, klezmer, Hebrew pop\npop-rock, klezmer, balkan brass\npop-rock, klezmer, balkan folk\npop-rock, klezmer, ballad\npop-rock, klezmer, big band\npop-rock, klezmer, electronic\npop-rock, klezmer, festival\npop-rock, klezmer, fusion\npop-rock, klezmer, middle eastern\npop-rock, klezmer, mizrahi\npop-rock, klezmer, novelty\npop-rock, klezmer, ska\npop-rock, klezmer, surf rock\npop-rock, klezmer, theatrical\npop-rock, klezmer, world music\npop-rock, kuthu, gaana\npop-rock, late-90s, Mandarin\npop-rock, laïko, electronic\npop-rock, laïko, theatrical\npop-rock, levenslied\npop-rock, live performance, Asian fusion\npop-rock, live performance, Taiwanese Hokkien\npop-rock, live, Pop Sunda\npop-rock, lo-fi hip hop\npop-rock, lo-fi hip hop, C-pop\npop-rock, lo-fi hip hop, Mandarin pop\npop-rock, lo-fi hip hop, Sundanese\npop-rock, lo-fi hip hop, ambient\npop-rock, lo-fi hip hop, bilingual\npop-rock, lo-fi hip hop, emotional\npop-rock, lo-fi hip hop, indie rock\npop-rock, lo-fi hip hop, rap\npop-rock, lo-fi hip-hop\npop-rock, lo-fi hip-hop, atmospheric\npop-rock, lo-fi hip-hop, cinematic\npop-rock, lo-fi hip-hop, shoegaze\npop-rock, lo-fi, C-pop\npop-rock, lo-fi, K-pop\npop-rock, lo-fi, Southeast Asian\npop-rock, lo-fi, blues-rock\npop-rock, lo-fi, cinematic\npop-rock, lo-fi, hip-hop\npop-rock, lo-fi, hyperpop\npop-rock, lo-fi, rap rock\npop-rock, lo-fi, soulful rock\npop-rock, lo-fi, theatrical\npop-rock, lounge, exotica\npop-rock, math rock, electronic\npop-rock, melancholic, Bengali\npop-rock, melancholic, Chinese rock\npop-rock, melancholic, Eastern European\npop-rock, melancholic, J-rock\npop-rock, melancholic, Javanese\npop-rock, melancholic, Spanish\npop-rock, melancholic, Thai R&B\npop-rock, melancholic, Turkish\npop-rock, melancholic, bilingual\npop-rock, melancholic, cinematic\npop-rock, melancholic, traditional Malay\npop-rock, melodic hard rock, Chinese opera\npop-rock, metal, C-pop\npop-rock, metal, acoustic\npop-rock, metalcore\npop-rock, metalcore, Chinese classical\npop-rock, metalcore, Chinese folk\npop-rock, metalcore, Chinese traditional\npop-rock, metalcore, J-pop\npop-rock, metalcore, acoustic ballad\npop-rock, metalcore, ambient\npop-rock, metalcore, anthemic\npop-rock, metalcore, ballad\npop-rock, metalcore, cinematic\npop-rock, metalcore, cinematic rock\npop-rock, metalcore, electronic\npop-rock, metalcore, folk\npop-rock, metalcore, funk\npop-rock, metalcore, piano ballad\npop-rock, metalcore, post-hardcore\npop-rock, metalcore, rap-metal\npop-rock, modern dangdut\npop-rock, modern dangdut, Melayu\npop-rock, modern dangdut, Southeast Asian\npop-rock, modern, bilingual\npop-rock, moombahton, C-pop\npop-rock, motivational, Chinese fusion\npop-rock, multilingual, electronic\npop-rock, musical theater\npop-rock, musical theater, C-pop\npop-rock, musical theater, Celtic rock\npop-rock, musical theater, animated film\npop-rock, musical theater, anime theme\npop-rock, musical theater, anthemic\npop-rock, musical theater, ballad\npop-rock, musical theater, blues rock\npop-rock, musical theater, cartoon\npop-rock, musical theater, chiptune\npop-rock, musical theater, cinematic\npop-rock, musical theater, comedic\npop-rock, musical theater, dance\npop-rock, musical theater, dramatic\npop-rock, musical theater, electronic\npop-rock, musical theater, energetic\npop-rock, musical theater, female ensemble\npop-rock, musical theater, festive\npop-rock, musical theater, folk\npop-rock, musical theater, folk-dance\npop-rock, musical theater, funk-rock\npop-rock, musical theater, hip-hop\npop-rock, musical theater, klezmer\npop-rock, musical theater, live\npop-rock, musical theater, power ballad\npop-rock, musical theater, ragtime\npop-rock, musical theater, rock\npop-rock, musical theater, rock opera\npop-rock, musical theater, soul\npop-rock, musical theater, synth-pop\npop-rock, musical theater, synth-rock\npop-rock, musical theater, theatrical\npop-rock, musical theater, theatrical pop\npop-rock, musical theater, theatrical rock\npop-rock, musical theater, upbeat\npop-rock, musical theater, uplifting\npop-rock, musical theater, video game\npop-rock, musical theatre\npop-rock, musical theatre, animated theme\npop-rock, musical theatre, cinematic\npop-rock, musical theatre, synth-pop\npop-rock, musical theatre, theatrical pop\npop-rock, nasheed, Islamic devotional\npop-rock, neo-soul\npop-rock, neo-soul, Chinese rock\npop-rock, neo-soul, funk\npop-rock, nerdcore, video game\npop-rock, new age, adult contemporary\npop-rock, new jack swing\npop-rock, new jack swing, 80s revival\npop-rock, new jack swing, 80s synth\npop-rock, new jack swing, cinematic\npop-rock, new jack swing, dance-pop\npop-rock, new jack swing, funk\npop-rock, new jack swing, retro\npop-rock, new jack swing, retro-pop\npop-rock, new wave\npop-rock, new wave, 80s\npop-rock, new wave, 80s synth\npop-rock, new wave, 90s Eastern European\npop-rock, new wave, Balkan\npop-rock, new wave, Eastern European\npop-rock, new wave, French pop\npop-rock, new wave, Latin pop, soulful pop\npop-rock, new wave, Soviet-era\npop-rock, new wave, anthemic\npop-rock, new wave, baroque-pop\npop-rock, new wave, bilingual\npop-rock, new wave, chiptune\npop-rock, new wave, cinematic\npop-rock, new wave, dream pop\npop-rock, new wave, energetic\npop-rock, new wave, funk\npop-rock, new wave, gospel-pop\npop-rock, new wave, late 70s\npop-rock, new wave, lounge-jazz\npop-rock, new wave, punk\npop-rock, new wave, reggae\npop-rock, new wave, retro\npop-rock, new wave, rockabilly\npop-rock, new wave, ska\npop-rock, new wave, surf rock\npop-rock, new wave, synth-pop\npop-rock, new wave, theatrical\npop-rock, new-age, 2000s\npop-rock, new-age, 90s\npop-rock, new-age, early 2000s\npop-rock, new-age, power ballad\npop-rock, new-age, rap\npop-rock, new-age, spiritual\npop-rock, new-age, world music\npop-rock, ney, melancholic\npop-rock, nostalgic, Eastern European\npop-rock, novelty, Christmas\npop-rock, novelty, Filipino\npop-rock, novelty, retro\npop-rock, novelty, theatrical\npop-rock, nu-metal\npop-rock, nu-metal, C-pop\npop-rock, nu-metal, Hebrew vocal\npop-rock, nu-metal, K-pop\npop-rock, nu-metal, Latin rock\npop-rock, nu-metal, Mandarin ballad\npop-rock, nu-metal, Spanish\npop-rock, nu-metal, acoustic\npop-rock, nu-metal, acoustic ballad\npop-rock, nu-metal, alternative\npop-rock, nu-metal, anthemic\npop-rock, nu-metal, atmospheric\npop-rock, nu-metal, ballad\npop-rock, nu-metal, cinematic\npop-rock, nu-metal, electronic\npop-rock, nu-metal, emotional\npop-rock, nu-metal, emotional ballad\npop-rock, nu-metal, funk-rock\npop-rock, nu-metal, gospel\npop-rock, nu-metal, hard rock\npop-rock, nu-metal, live anthem\npop-rock, nu-metal, rap-rock\npop-rock, operatic, baroque pop\npop-rock, operatic, cinematic\npop-rock, operatic, hip-hop\npop-rock, orchestral pop, power ballad\npop-rock, orchestral, children's choir\npop-rock, orchestral, cinematic\npop-rock, orchestral, eurodance\npop-rock, orchestral, gospel\npop-rock, orchestral, patriotic\npop-rock, orchestral, theatrical\npop-rock, oud, cinematic\npop-rock, pansori, cinematic\npop-rock, patriotic, Azerbaijani folk\npop-rock, patriotic, Eastern European\npop-rock, patriotic, South Asian\npop-rock, patriotic, anthemic\npop-rock, patriotic, cinematic\npop-rock, patriotic, folk-inspired\npop-rock, patriotic, orchestral\npop-rock, piano ballad, bilingual\npop-rock, piano ballad, cinematic\npop-rock, piano ballad, hard rock\npop-rock, pimba\npop-rock, pimba, folk\npop-rock, polka, accordion\npop-rock, polka, educational\npop-rock, polka, quirky\npop-rock, polka, theatrical\npop-rock, polka-rock\npop-rock, pop Melayu\npop-rock, pop melayu, Southeast Asian\npop-rock, pop sunda\npop-rock, pop-dangdut\npop-rock, pop-dangdut, Javanese ballad\npop-rock, pop-dangdut, cinematic\npop-rock, pop-punk\npop-rock, pop-punk, C-pop\npop-rock, pop-punk, choral pop\npop-rock, pop-punk, hip-hop\npop-rock, pop-rap, Bollywood\npop-rock, post-hardcore\npop-rock, post-hardcore, C-pop\npop-rock, post-hardcore, Chinese ballad\npop-rock, post-hardcore, Chinese indie\npop-rock, post-hardcore, acoustic ballad\npop-rock, post-hardcore, alternative metal\npop-rock, post-hardcore, cinematic\npop-rock, post-hardcore, rap\npop-rock, post-hardcore, rap-rock\npop-rock, post-rock, C-pop\npop-rock, post-rock, alternative rock\npop-rock, post-rock, anime rock\npop-rock, post-rock, cinematic\npop-rock, post-rock, melancholic\npop-rock, post-rock, piano ballad\npop-rock, post-rock, video game style\npop-rock, power ballad\npop-rock, power ballad, Eastern European\npop-rock, power ballad, Eastern European pop\npop-rock, power ballad, Italian ballad\npop-rock, power ballad, Middle Eastern fusion\npop-rock, power ballad, arena rock\npop-rock, power ballad, bilingual\npop-rock, power ballad, cinematic\npop-rock, power ballad, hard rock\npop-rock, power ballad, synth-pop\npop-rock, power ballad, theatrical\npop-rock, power metal\npop-rock, power metal, J-rock\npop-rock, power metal, Spanish style\npop-rock, power metal, acoustic ballad\npop-rock, power metal, cinematic\npop-rock, power-pop, surf rock\npop-rock, progressive house\npop-rock, progressive house, EDM\npop-rock, progressive house, big room\npop-rock, progressive house, cinematic\npop-rock, progressive house, emotional EDM\npop-rock, progressive house, flamenco\npop-rock, progressive house, trance\npop-rock, progressive house, trance-pop\npop-rock, progressive metal\npop-rock, progressive rock\npop-rock, progressive rock, Indonesian traditional\npop-rock, progressive rock, piano ballad\npop-rock, psychedelic rock\npop-rock, psychedelic rock, Italian ballad\npop-rock, psychedelic, 60s\npop-rock, psychedelic, Southeast Asian\npop-rock, psychedelic, cinematic\npop-rock, pub-rock\npop-rock, punk rock, K-pop\npop-rock, punk rock, cinematic\npop-rock, punk rock, emotional ballad\npop-rock, punk rock, lo-fi\npop-rock, punk rock, metalcore\npop-rock, punk rock, piano ballad\npop-rock, punk-rock, theatrical\npop-rock, quirky, Eastern European\npop-rock, quirky, festive\npop-rock, ragtime, bilingual\npop-rock, ragtime, theatrical\npop-rock, rap rock, metalcore\npop-rock, rap, Mandarin pop\npop-rock, rap, ambient\npop-rock, rap, anthemic\npop-rock, rap, ballad\npop-rock, rap, cinematic\npop-rock, rap, dubstep\npop-rock, rap, electronic\npop-rock, rap, emotional\npop-rock, rap, energetic\npop-rock, rap, nu-metal\npop-rock, rap, rock\npop-rock, rap-rock\npop-rock, rap-rock, C-pop\npop-rock, rap-rock, Chinese ambient\npop-rock, rap-rock, J-rock\npop-rock, rap-rock, Mandarin ballad\npop-rock, rap-rock, Mandarin pop\npop-rock, rap-rock, Tamil ballad\npop-rock, rap-rock, alternative\npop-rock, rap-rock, ambient\npop-rock, rap-rock, anthemic\npop-rock, rap-rock, anthemic rock\npop-rock, rap-rock, atmospheric\npop-rock, rap-rock, ballad\npop-rock, rap-rock, cinematic\npop-rock, rap-rock, dream pop\npop-rock, rap-rock, electronic\npop-rock, rap-rock, emotional\npop-rock, rap-rock, explosive\npop-rock, rap-rock, funk\npop-rock, rap-rock, hip-hop\npop-rock, rap-rock, indie rock\npop-rock, rap-rock, lo-fi hip-hop\npop-rock, rap-rock, melodic\npop-rock, rap-rock, nu-metal\npop-rock, rap-rock, post-hardcore\npop-rock, rap-rock, reggae pop\npop-rock, rap-rock, synthwave\npop-rock, reggae\npop-rock, reggae, classic rock\npop-rock, reggae, hip-hop\npop-rock, reggaeton, ambient\npop-rock, reggaeton, bilingual\npop-rock, reggaeton, cinematic\npop-rock, reggaeton, ethereal pop\npop-rock, reggaeton, tropical\npop-rock, regional pop\npop-rock, regional pop, synth-pop\npop-rock, retro 80s\npop-rock, retro Filipino pop\npop-rock, retro J-pop, anime theme\npop-rock, retro Korean trot\npop-rock, retro Mandopop\npop-rock, retro Mandopop, Taiwanese Hokkien pop\npop-rock, retro Mandopop, theatrical\npop-rock, retro pop, 2000s J-pop\npop-rock, retro rock, 90s J-rock\npop-rock, retro rock, C-rock\npop-rock, retro rock, Soviet-era\npop-rock, retro rock, big band\npop-rock, retro rock, theatrical\npop-rock, retro soul, Christmas\npop-rock, retro soul, R&B\npop-rock, retro soul, big band\npop-rock, retro soul, funk\npop-rock, retro surf-rock\npop-rock, retro video game\npop-rock, retro video game, Halloween\npop-rock, retro, 60s British Invasion\npop-rock, retro, 80s\npop-rock, retro, 80s East Asian\npop-rock, retro, 80s new wave\npop-rock, retro, 90s Indonesian pop\npop-rock, retro, Balkan\npop-rock, retro, Balkan folk\npop-rock, retro, C-pop\npop-rock, retro, Christmas\npop-rock, retro, East African\npop-rock, retro, Eastern European\npop-rock, retro, Eastern European pop\npop-rock, retro, Estrada\npop-rock, retro, European\npop-rock, retro, Indonesian pop\npop-rock, retro, Indonesian rock\npop-rock, retro, Israeli pop\npop-rock, retro, Israeli rock\npop-rock, retro, Italian beat\npop-rock, retro, K-pop\npop-rock, retro, Latin pop\npop-rock, retro, Mandopop\npop-rock, retro, Nederpop\npop-rock, retro, OPM\npop-rock, retro, Polish disco-pop\npop-rock, retro, South Asian\npop-rock, retro, Southeast Asian\npop-rock, retro, Southeast Asian pop\npop-rock, retro, Soviet estrada\npop-rock, retro, Soviet-era\npop-rock, retro, Soviet-era estrada\npop-rock, retro, Sundanese\npop-rock, retro, Taiwanese Hokkien\npop-rock, retro, accordion\npop-rock, retro, anime\npop-rock, retro, anime theme\npop-rock, retro, big band\npop-rock, retro, big-band\npop-rock, retro, chiptune\npop-rock, retro, cinematic\npop-rock, retro, doo-wop\npop-rock, retro, educational\npop-rock, retro, estrada\npop-rock, retro, festive\npop-rock, retro, funk-rock\npop-rock, retro, new wave\npop-rock, retro, novelty\npop-rock, retro, pimba\npop-rock, retro, power pop\npop-rock, retro, schlager\npop-rock, retro, show tune\npop-rock, retro, ska\npop-rock, retro, ska-pop\npop-rock, retro, spy theme\npop-rock, retro, sunshine pop\npop-rock, retro, surf rock\npop-rock, retro, surf-rock\npop-rock, retro, synth-pop\npop-rock, retro, synthwave\npop-rock, retro, theatrical\npop-rock, retro, trot-rock\npop-rock, retro, video game\npop-rock, retro, world music\npop-rock, rock en español, retro\npop-rock, rock, Greek\npop-rock, rockabilly\npop-rock, rockabilly, German pop\npop-rock, rockabilly, Nederpop\npop-rock, rockabilly, Portuguese\npop-rock, rockabilly, big band\npop-rock, rockabilly, cabaret\npop-rock, rockabilly, country\npop-rock, rockabilly, country-pop\npop-rock, rockabilly, levenslied\npop-rock, rockabilly, polka\npop-rock, rockabilly, retro\npop-rock, rockabilly, retro swing\npop-rock, rockabilly, ska\npop-rock, rockabilly, soul\npop-rock, rockabilly, surf rock\npop-rock, rockabilly, swing\npop-rock, rockabilly, theatrical\npop-rock, rockabilly, upbeat\npop-rock, rockabilly, vintage pop\npop-rock, salsa, ballad\npop-rock, salsa, big band\npop-rock, salsa, rock\npop-rock, samba-reggae\npop-rock, samba-rock\npop-rock, satirical, Eastern European\npop-rock, satirical, funk\npop-rock, schlager\npop-rock, schlager, 60s pop\npop-rock, schlager, 80s\npop-rock, schlager, 80s euro\npop-rock, schlager, Balkan\npop-rock, schlager, Christmas\npop-rock, schlager, Eastern European\npop-rock, schlager, Euro-pop\npop-rock, schlager, European\npop-rock, schlager, German\npop-rock, schlager, Portuguese\npop-rock, schlager, Scandinavian\npop-rock, schlager, Swedish\npop-rock, schlager, big band\npop-rock, schlager, christmas\npop-rock, schlager, cinematic\npop-rock, schlager, dansband\npop-rock, schlager, epic\npop-rock, schlager, estrada\npop-rock, schlager, euro-dance\npop-rock, schlager, euro-pop\npop-rock, schlager, polka\npop-rock, schlager, quirky\npop-rock, schlager, retro\npop-rock, schlager, ska\npop-rock, schlager, synth-pop\npop-rock, schlager, theatrical\npop-rock, schlager, vintage European\npop-rock, sea shanty, theatrical\npop-rock, sertanejo\npop-rock, sertanejo, ambient\npop-rock, sertanejo, cinematic\npop-rock, shoegaze\npop-rock, shoegaze, C-pop\npop-rock, shoegaze, cinematic\npop-rock, show tune, big band\npop-rock, show tune, children's music\npop-rock, show tune, quirky\npop-rock, show tune, ragtime\npop-rock, show tune, swing revival\npop-rock, show tune, theatrical\npop-rock, show tune, upbeat\npop-rock, show tune, vintage\npop-rock, shred guitar, Dangdut Koplo\npop-rock, shred guitar, ambient\npop-rock, ska, Balkan\npop-rock, ska, Eastern European folk\npop-rock, ska, Filipino Christmas\npop-rock, ska, Javanese\npop-rock, ska, Javanese pop\npop-rock, ska, Latin\npop-rock, ska, Nederpop\npop-rock, ska, big band\npop-rock, ska, new wave\npop-rock, ska, political\npop-rock, ska, polka\npop-rock, ska, pop Melayu\npop-rock, ska, retro\npop-rock, ska, rock 'n' roll\npop-rock, ska, soul\npop-rock, ska, theatrical\npop-rock, ska, worldbeat\npop-rock, ska-pop, new wave\npop-rock, ska-punk\npop-rock, ska-punk, musical theater\npop-rock, ska-punk, piano ballad\npop-rock, ska-punk, swing-rock\npop-rock, skate-punk, summer\npop-rock, slow rock, Dangdut\npop-rock, smooth jazz\npop-rock, smooth jazz, OPM\npop-rock, smooth jazz, ambient\npop-rock, smooth jazz, synth funk\npop-rock, smooth jazz, world music\npop-rock, smooth jazz, worship\npop-rock, soft rock\npop-rock, soul, 70s\npop-rock, soul, Motown\npop-rock, soul, South Asian\npop-rock, soul, ballad\npop-rock, soul, bilingual\npop-rock, soul, boogie-woogie\npop-rock, soul, cinematic\npop-rock, soul, doo-wop\npop-rock, soul, festive\npop-rock, soul, funk\npop-rock, soul, gospel\npop-rock, soul, hard rock\npop-rock, soul, retro\npop-rock, soul, rockabilly\npop-rock, soul, show tune\npop-rock, soul, ska\npop-rock, soul, theatrical\npop-rock, soul, tropical\npop-rock, soul, vintage\npop-rock, soulful R&B, cinematic\npop-rock, soulful, Hebrew ballad\npop-rock, soulful, Sundanese\npop-rock, soulful, cinematic\npop-rock, soulful, heartland rock\npop-rock, soulful, live\npop-rock, southern rock, rock\npop-rock, spiritual, Arabic pop\npop-rock, spiritual, Hebrew\npop-rock, spiritual, Indian\npop-rock, spiritual, Indonesian hip-hop\npop-rock, spiritual, Middle Eastern\npop-rock, spiritual, South Asian\npop-rock, spiritual, Sundanese\npop-rock, spiritual, ballad\npop-rock, spiritual, choral\npop-rock, spiritual, cinematic\npop-rock, spiritual, new-age\npop-rock, spiritual, world music\npop-rock, sports anthem, cinematic\npop-rock, stadium rock, C-pop\npop-rock, summer pop, Italian pop\npop-rock, sunshine pop\npop-rock, sunshine pop, 60s British Invasion\npop-rock, sunshine pop, doo-wop\npop-rock, sunshine pop, glam rock\npop-rock, sunshine pop, musical theater\npop-rock, sunshine pop, retro\npop-rock, sunshine pop, show tune\npop-rock, sunshine pop, vintage\npop-rock, surf rock\npop-rock, surf rock, Balkan\npop-rock, surf rock, Brazilian pop\npop-rock, surf rock, Jangly\npop-rock, surf rock, Latin\npop-rock, surf rock, MPB\npop-rock, surf rock, Middle Eastern\npop-rock, surf rock, Southeast Asian\npop-rock, surf rock, big band\npop-rock, surf rock, blues\npop-rock, surf rock, klezmer\npop-rock, surf rock, reggae\npop-rock, surf rock, retro\npop-rock, surf rock, rock 'n' roll\npop-rock, surf rock, rockabilly\npop-rock, surf rock, ska\npop-rock, surf-rock\npop-rock, surf-rock, Central Asian\npop-rock, surf-rock, Hebrew pop\npop-rock, surf-rock, Latin\npop-rock, surf-rock, Southeast Asian\npop-rock, surf-rock, cinematic\npop-rock, surf-rock, cumbia\npop-rock, surf-rock, exotica\npop-rock, surf-rock, garage rock\npop-rock, surf-rock, new wave\npop-rock, surf-rock, quirky\npop-rock, surf-rock, retro\npop-rock, surf-rock, rockabilly\npop-rock, surf-rock, ska\npop-rock, surf-rock, theatrical\npop-rock, swing, French pop\npop-rock, swing, theatrical\npop-rock, symphonic hard rock\npop-rock, symphonic metal, C-pop\npop-rock, symphonic metal, ballad\npop-rock, symphonic metal, cinematic\npop-rock, symphonic metal, piano ballad\npop-rock, symphonic power metal\npop-rock, symphonic rock\npop-rock, symphonic rock, C-pop\npop-rock, symphonic rock, Russian ballad\npop-rock, symphonic rock, anime soundtrack\npop-rock, symphonic rock, electronic\npop-rock, symphonic rock, emotional rock\npop-rock, synth pop, Chinese hip hop\npop-rock, synth-pop\npop-rock, synth-pop, 80s\npop-rock, synth-pop, Balkan\npop-rock, synth-pop, Bollywood\npop-rock, synth-pop, Brazilian\npop-rock, synth-pop, Central Asian\npop-rock, synth-pop, Central Asian folk\npop-rock, synth-pop, Central Asian pop\npop-rock, synth-pop, EDM, cinematic\npop-rock, synth-pop, Eastern European\npop-rock, synth-pop, Eastern European rock\npop-rock, synth-pop, Italo-disco\npop-rock, synth-pop, Mandopop\npop-rock, synth-pop, Middle Eastern fusion\npop-rock, synth-pop, Russian\npop-rock, synth-pop, Southeast Asian\npop-rock, synth-pop, alternative rock\npop-rock, synth-pop, bilingual\npop-rock, synth-pop, children's music\npop-rock, synth-pop, cinematic\npop-rock, synth-pop, dream-pop, R&B, dance-pop, Latin pop\npop-rock, synth-pop, funk-rock\npop-rock, synth-pop, multilingual\npop-rock, synth-pop, power ballad\npop-rock, synth-pop, rock\npop-rock, synth-pop, satirical\npop-rock, synth-pop, theatrical rock\npop-rock, synth-pop, video game soundtrack\npop-rock, synth-pop, worship\npop-rock, synth-rock\npop-rock, synth-rock, arena rock\npop-rock, synthwave, Eastern European\npop-rock, tango, Eastern European\npop-rock, tango, Latin\npop-rock, tango, cinematic\npop-rock, tango, theatrical\npop-rock, theatrical pop, Eastern European pop\npop-rock, theatrical rock\npop-rock, theatrical rock, 80s rock\npop-rock, theatrical rock, blues-rock\npop-rock, theatrical rock, brass rock\npop-rock, theatrical, 1970s\npop-rock, theatrical, 60s influence\npop-rock, theatrical, 60s show tune\npop-rock, theatrical, 70s influence\npop-rock, theatrical, 70s show tune\npop-rock, theatrical, 80s\npop-rock, theatrical, 80s Israeli\npop-rock, theatrical, 80s Polish\npop-rock, theatrical, 80s aesthetic\npop-rock, theatrical, 80s children's show\npop-rock, theatrical, 80s movie theme\npop-rock, theatrical, Balkan\npop-rock, theatrical, Balkan folk\npop-rock, theatrical, C-pop\npop-rock, theatrical, Christmas\npop-rock, theatrical, Christmas parody\npop-rock, theatrical, Dutch levenslied\npop-rock, theatrical, Eastern European\npop-rock, theatrical, Eastern European folk\npop-rock, theatrical, Eastern European pop\npop-rock, theatrical, European\npop-rock, theatrical, French pop\npop-rock, theatrical, Halloween\npop-rock, theatrical, Hokkien pop\npop-rock, theatrical, Israeli\npop-rock, theatrical, Latin\npop-rock, theatrical, Middle Eastern\npop-rock, theatrical, New Year\npop-rock, theatrical, Soviet-era\npop-rock, theatrical, Soviet-era estrada\npop-rock, theatrical, a cappella\npop-rock, theatrical, anime\npop-rock, theatrical, anime opening\npop-rock, theatrical, anime theme\npop-rock, theatrical, anthemic\npop-rock, theatrical, ballad\npop-rock, theatrical, baritone\npop-rock, theatrical, baroque pop\npop-rock, theatrical, big band\npop-rock, theatrical, big-band\npop-rock, theatrical, bilingual\npop-rock, theatrical, boogie-woogie\npop-rock, theatrical, brass\npop-rock, theatrical, brass rock\npop-rock, theatrical, brass-driven\npop-rock, theatrical, cabaret\npop-rock, theatrical, cartoon musical\npop-rock, theatrical, cartoonish\npop-rock, theatrical, chiptune\npop-rock, theatrical, choral\npop-rock, theatrical, cinematic\npop-rock, theatrical, circus\npop-rock, theatrical, circus pop\npop-rock, theatrical, classical\npop-rock, theatrical, comedic\npop-rock, theatrical, dancehall\npop-rock, theatrical, dramatic\npop-rock, theatrical, duet\npop-rock, theatrical, educational\npop-rock, theatrical, electronic\npop-rock, theatrical, energetic\npop-rock, theatrical, epic\npop-rock, theatrical, estrada\npop-rock, theatrical, fantasy\npop-rock, theatrical, film score\npop-rock, theatrical, flamenco\npop-rock, theatrical, folk\npop-rock, theatrical, folk-pop\npop-rock, theatrical, folk-rock\npop-rock, theatrical, funk\npop-rock, theatrical, funk-rock\npop-rock, theatrical, glam pop\npop-rock, theatrical, gospel\npop-rock, theatrical, gothic\npop-rock, theatrical, hip-hop\npop-rock, theatrical, honky-tonk\npop-rock, theatrical, jazz-fusion\npop-rock, theatrical, jazz-infused\npop-rock, theatrical, klezmer\npop-rock, theatrical, levenslied\npop-rock, theatrical, live show tune\npop-rock, theatrical, musical theater\npop-rock, theatrical, musical theatre\npop-rock, theatrical, narrative\npop-rock, theatrical, neo-classical\npop-rock, theatrical, operatic\npop-rock, theatrical, orchestral\npop-rock, theatrical, power ballad\npop-rock, theatrical, protest\npop-rock, theatrical, punk\npop-rock, theatrical, punk rock\npop-rock, theatrical, punk-rock\npop-rock, theatrical, ragtime\npop-rock, theatrical, reggae-influenced\npop-rock, theatrical, retro\npop-rock, theatrical, romantic\npop-rock, theatrical, satirical\npop-rock, theatrical, show tune\npop-rock, theatrical, show-tune\npop-rock, theatrical, ska\npop-rock, theatrical, soulful\npop-rock, theatrical, spy theme\npop-rock, theatrical, superhero\npop-rock, theatrical, symphonic\npop-rock, theatrical, symphonic rock\npop-rock, theatrical, tango\npop-rock, theatrical, upbeat\npop-rock, theatrical, video game\npop-rock, theatrical, vintage\npop-rock, theatrical, vintage 60s\npop-rock, theatrical, vintage Italian\npop-rock, theatrical, whimsical\npop-rock, theatrical, world music\npop-rock, traditional Azerbaijani, Turkish\npop-rock, traditional Azerbaijani, Turkish folk\npop-rock, traditional Indonesian, modern fusion\npop-rock, traditional Malay\npop-rock, traditional Malay, Javanese fusion\npop-rock, traditional Malay, Mandarin pop\npop-rock, traditional Malay, Middle Eastern\npop-rock, traditional Malay, cinematic\npop-rock, traditional Malay, festive\npop-rock, traditional Malay, folk fusion\npop-rock, traditional Malay, melodic\npop-rock, traditional Malay, modern fusion\npop-rock, traditional Mongolian, cinematic\npop-rock, traditional Southeast Asian, festive\npop-rock, traditional Southeast Asian, modern\npop-rock, traditional Southeast Asian, mystical\npop-rock, traditional, cinematic\npop-rock, traditional, ney\npop-rock, trance\npop-rock, trance, metalcore\npop-rock, trance-pop, emotional\npop-rock, trap\npop-rock, trap metal, electronic\npop-rock, trap, EDM\npop-rock, trap, K-pop\npop-rock, trap, Mandarin\npop-rock, trap, R&B\npop-rock, trap, ambient\npop-rock, trap, atmospheric\npop-rock, trap, cinematic\npop-rock, trap, electronic\npop-rock, trap, emotional\npop-rock, trap, ethereal\npop-rock, trap, lo-fi\npop-rock, trap, mathcore\npop-rock, trap, rock\npop-rock, trap, spoken word\npop-rock, trap-metal, blues rock\npop-rock, trap-rap, future bass\npop-rock, trip-hop, art-pop\npop-rock, trip-hop, nu-metal\npop-rock, tropical, Central Asian\npop-rock, tropical, Christmas\npop-rock, tropical, Latin\npop-rock, tropical, calypso\npop-rock, tropical, island\npop-rock, tropical, island music\npop-rock, trot\npop-rock, trot, anime\npop-rock, trot, big band\npop-rock, trot, cinematic\npop-rock, trot, electronic\npop-rock, trot, theatrical\npop-rock, turbo-folk\npop-rock, turbo-folk, Balkan\npop-rock, turbo-folk, Eastern European\npop-rock, turbo-folk, chiptune\npop-rock, turbo-folk, electronic\npop-rock, turbo-folk, ska\npop-rock, turbo-folk, synth\npop-rock, turbo-folk, synth-pop\npop-rock, video game music\npop-rock, vintage Indonesian\npop-rock, vintage Indonesian pop\npop-rock, vintage Indonesian, boogie-woogie\npop-rock, vintage Indonesian, rock\npop-rock, vintage Israeli pop, theatrical\npop-rock, vintage Latin rock\npop-rock, vintage anime, theatrical\npop-rock, vintage big band\npop-rock, vintage big band, soulful\npop-rock, vintage rock, show tune\npop-rock, vintage soul, big band\npop-rock, vintage soul, funk\npop-rock, vintage, C-pop\npop-rock, vintage, South Asian film music\npop-rock, vintage, estrada\npop-rock, vintage, psychedelic\npop-rock, vintage, soul\npop-rock, vintage, sunshine pop\npop-rock, vintage, theatrical\npop-rock, world fusion\npop-rock, world fusion, cinematic\npop-rock, world fusion, electronic\npop-rock, world fusion, funk\npop-rock, world music\npop-rock, world music, Arabic\npop-rock, world music, Balkan folk\npop-rock, world music, C-pop\npop-rock, world music, Klezmer\npop-rock, world music, Latin\npop-rock, world music, Mandopop\npop-rock, world music, Middle Eastern\npop-rock, world music, Persian\npop-rock, world music, Russian folk\npop-rock, world music, Sinhala\npop-rock, world music, Sinhala pop\npop-rock, world music, Telugu pop\npop-rock, world music, anthemic\npop-rock, world music, atmospheric\npop-rock, world music, ballad\npop-rock, world music, blues-rock\npop-rock, world music, cinematic\npop-rock, world music, electronic\npop-rock, world music, emotional\npop-rock, world music, emotional ballad\npop-rock, world music, epic\npop-rock, world music, flamenco\npop-rock, world music, klezmer\npop-rock, world music, lo-fi\npop-rock, world music, new age\npop-rock, world music, pap melayu\npop-rock, world music, power ballad\npop-rock, world music, spiritual\npop-rock, world music, theatrical\npop-rock, world music, trap\npop-rock, world music, uplifting\npop-rock, worship, Christian\npop-rock, worship, anthemic\npop-rock, worship, bilingual\npop-rock, worship, dance-rock\npop-rock, worship, energetic\npop-rock, worship, live\npop-romántico\npop-romântico\npop-samba\npop-schlager\npop-sertanejo\npop-ska\npop-ska gospel\npop-soul\npop-soul J-pop\npop-soul bossa nova\npop-soul chiptune\npop-soul funk\npop-soul jazz\npop-soul lounge\npop-soul smooth jazz\npop-soul world music\npop-soul, Latin jazz, lounge\npop-soul, R&B, jazz\npop-swing\npop-tango\npop-trance\npop-trap\npop-trap C-pop R&B\npop-trap Desi\npop-trap Indian\npop-trap R&B\npop-trap R&B Indian pop\npop-trap ballad\npop-trap chiptune\npop-trap cinematic\npop-trap devotional\npop-trap emo rap\npop-trap emo-rap\npop-trap emo-trap\npop-trap future bass\npop-trap hip-hop\npop-trap melancholic\npop-trap vaporwave\npop-trap, Azerbaijani folk\npop-trap, Balkan folk, R&B\npop-trap, Balkan folk, cinematic\npop-trap, Balkan, microtonal\npop-trap, Balkan, modern\npop-trap, Bollywood, Bhangra\npop-trap, Bollywood, Punjabi\npop-trap, Bollywood, electronic\npop-trap, Brazilian funk\npop-trap, C-pop\npop-trap, C-pop, cinematic\npop-trap, Central Asian\npop-trap, Central Asian folk\npop-trap, Central Asian fusion\npop-trap, Central Asian, modern\npop-trap, EDM\npop-trap, EDM, Indonesian pop\npop-trap, East Asian, modern\npop-trap, Hebrew pop, cinematic\npop-trap, Hindi ballad, cinematic\npop-trap, Hindi rap, cinematic\npop-trap, Indian classical, R&B\npop-trap, Indian folk, cinematic\npop-trap, Indian fusion\npop-trap, Indian pop, R&B\npop-trap, Indian pop, electronic\npop-trap, K-pop, R&B\npop-trap, Latin pop\npop-trap, Latin pop, R&B\npop-trap, Latin pop, hyperpop\npop-trap, Latin pop, lo-fi\npop-trap, Latin pop, modern pop\npop-trap, Latin, reggaeton\npop-trap, Middle Eastern\npop-trap, Middle Eastern fusion\npop-trap, Middle Eastern, Eastern European\npop-trap, Middle Eastern, Turkish\npop-trap, Middle Eastern, cinematic\npop-trap, Middle Eastern, dramatic\npop-trap, Middle Eastern, emotional\npop-trap, Middle Eastern, melancholic\npop-trap, Persian pop, atmospheric\npop-trap, Persian, cinematic\npop-trap, Persian, rock\npop-trap, Punjabi, Hindi\npop-trap, R&B\npop-trap, R&B, Bollywood\npop-trap, R&B, Indian pop\npop-trap, R&B, South Indian\npop-trap, R&B, Thai pop\npop-trap, R&B, atmospheric\npop-trap, R&B, cinematic\npop-trap, R&B, cloud rap\npop-trap, R&B, hip-hop\npop-trap, Romanian pop, cinematic\npop-trap, Romanian, Arabic\npop-trap, South Asian fusion\npop-trap, South Asian, cinematic\npop-trap, South Indian, R&B\npop-trap, Sundanese, cinematic\npop-trap, Swedish melodic rap, French R&B\npop-trap, Turkish, cinematic\npop-trap, atmospheric, bilingual\npop-trap, atmospheric, metalcore\npop-trap, bilingual, Eastern tonality\npop-trap, bilingual, R&B\npop-trap, bilingual, South Asian\npop-trap, bilingual, ethereal\npop-trap, bilingual, festive\npop-trap, bilingual, lo-fi\npop-trap, bilingual, upbeat\npop-trap, chillwave\npop-trap, chillwave, Russian pop-rap\npop-trap, chiptune, C-pop\npop-trap, chiptune, Indian pop\npop-trap, chiptune, R&B\npop-trap, chiptune, bilingual\npop-trap, chiptune, festive\npop-trap, chiptune, nostalgic\npop-trap, cinematic pop, rock\npop-trap, cinematic, Central Asian\npop-trap, cinematic, EDM\npop-trap, cinematic, Hebrew vocal\npop-trap, cinematic, Hindi pop\npop-trap, cinematic, Middle Eastern\npop-trap, cinematic, Punjabi\npop-trap, cinematic, Russian\npop-trap, cinematic, bilingual\npop-trap, cinematic, dark pop\npop-trap, cinematic, hardstyle\npop-trap, cinematic, neo-classical\npop-trap, cinematic, oud\npop-trap, cloud rap\npop-trap, cloud rap, C-pop\npop-trap, cloud rap, electronic\npop-trap, cloud rap, emo rap\npop-trap, cloud rap, modern R&B\npop-trap, conscious hip-hop\npop-trap, contemporary R&B\npop-trap, dancehall\npop-trap, dancehall, Dutch House\npop-trap, dream pop\npop-trap, dream pop, cinematic\npop-trap, dreamy, atmospheric\npop-trap, dreamy, bilingual\npop-trap, drill, cinematic\npop-trap, dubstep, ambient\npop-trap, electronic, cinematic\npop-trap, emo rap, C-pop\npop-trap, emo rap, K-pop\npop-trap, emo rap, Latin pop\npop-trap, emo rap, R&B\npop-trap, emo-rap, lo-fi\npop-trap, emo-rap, trap\npop-trap, emo-rock, modern pop\npop-trap, emotional, modern\npop-trap, folk, cinematic\npop-trap, funk, EDM\npop-trap, future bass\npop-trap, future bass, C-pop\npop-trap, future bass, Chinese pop\npop-trap, future bass, EDM\npop-trap, future bass, R&B\npop-trap, future bass, bilingual\npop-trap, future bass, chiptune\npop-trap, future bass, cinematic\npop-trap, future bass, cinematic pop\npop-trap, future bass, emotional trap\npop-trap, future bass, lo-fi\npop-trap, futuristic, bilingual\npop-trap, hardstyle\npop-trap, hardstyle, bilingual\npop-trap, hardstyle, phonk\npop-trap, hip-hop\npop-trap, hip-hop, synthwave\npop-trap, hyperpop\npop-trap, hyperpop, EDM\npop-trap, hyperpop, cinematic\npop-trap, hyperpop, electronic rock\npop-trap, hyperpop, glitch-pop\npop-trap, hyperpop, global pop\npop-trap, hyperpop, pop-rock\npop-trap, introspective hip-hop\npop-trap, lo-fi hip-hop\npop-trap, lo-fi hip-hop, German pop\npop-trap, lo-fi, C-pop\npop-trap, lo-fi, Chinese rap\npop-trap, lo-fi, EDM\npop-trap, lo-fi, J-pop\npop-trap, lo-fi, Persian\npop-trap, melancholic, Kurdish\npop-trap, melancholic, bilingual\npop-trap, melancholic, lo-fi\npop-trap, melancholic, modern\npop-trap, melancholic, multilingual\npop-trap, oud fusion, Balkan\npop-trap, oud, melancholic\npop-trap, piano ballad\npop-trap, pop-punk\npop-trap, reggaeton\npop-trap, reggaeton, C-pop\npop-trap, reggaeton, Middle Eastern\npop-trap, reggaeton, cinematic\npop-trap, sad pop, R&B\npop-trap, shoegaze, Italian pop\npop-trap, world fusion\npop-trot\npop-trot ballad\npop-trot big band\npop-trot big-band\npop/R&B\npopsa\npopsa, eurodance, chiptune\npopsho\npost-Romantic piano\npost-apocalyptic ambient\npost-apocalyptic hip-hop\npost-bop\npost-bop jazz\npost-classical\npost-disco\npost-disco boogie\npost-disco boogie funk\npost-disco boogie gospel\npost-disco boogie-funk\npost-disco funk\npost-disco funk soul\npost-disco funk-pop\npost-disco funk-rock\npost-disco house\npost-disco soul\npost-disco synth-pop\npost-disco, Latin funk\npost-disco, Latin funk, 80s dance\npost-disco, Latin, flamenco\npost-disco, boogie\npost-disco, boogie, 80s\npost-disco, boogie, ambient\npost-disco, boogie, dance-pop\npost-disco, boogie, funk\npost-disco, boogie, gospel\npost-disco, boogie, hip-hop\npost-disco, boogie, synth soul\npost-disco, boogie-funk\npost-disco, boogie-funk, early 80s\npost-disco, city pop, boogie\npost-disco, dance-pop\npost-disco, electro-funk, boogie\npost-disco, funk, Latin dance\npost-disco, funk, Latin pop\npost-disco, funk, Latin-funk\npost-disco, funk, bilingual\npost-disco, funk, boogie\npost-disco, funk, dance-pop\npost-disco, funk, electronic\npost-disco, funk, hip-hop\npost-disco, funk, hip-house\npost-disco, new jack swing, boogie\npost-disco, synth-funk, boogie\npost-disco, synth-pop, boogie\npost-disco, tribal house, 80s dance\npost-grunge\npost-grunge alternative metal\npost-grunge alternative rock\npost-grunge emo\npost-grunge emo rock\npost-grunge emo-rock\npost-grunge metalcore\npost-grunge nu-metal\npost-grunge shoegaze\npost-grunge, alt-rock, metalcore\npost-grunge, cinematic rock, metalcore\npost-grunge, hard rock, alternative rock\npost-hardcore\npost-hardcore C-pop\npost-hardcore J-rock\npost-hardcore J-rock electronic\npost-hardcore a cappella\npost-hardcore alternative metal\npost-hardcore alternative rock\npost-hardcore ambient\npost-hardcore chiptune\npost-hardcore chiptune electronic\npost-hardcore electronic\npost-hardcore electronic chiptune\npost-hardcore electronic rock\npost-hardcore electronicore\npost-hardcore emo\npost-hardcore emo metalcore\npost-hardcore emo nu-metal\npost-hardcore emo rock\npost-hardcore emo-pop\npost-hardcore emo-rap\npost-hardcore emo-rock\npost-hardcore flamenco\npost-hardcore folk\npost-hardcore funk rock\npost-hardcore hip-hop\npost-hardcore hip-hop metalcore\npost-hardcore hyperpop\npost-hardcore hyperpop emo-rap\npost-hardcore indie rock\npost-hardcore j-rock\npost-hardcore lo-fi\npost-hardcore math rock\npost-hardcore math-rock\npost-hardcore mathcore\npost-hardcore metalcore\npost-hardcore metalcore emo\npost-hardcore metalcore shoegaze\npost-hardcore nintendocore\npost-hardcore nu-metal\npost-hardcore punk\npost-hardcore rap-metal shoegaze\npost-hardcore rock\npost-hardcore screamo\npost-hardcore shoegaze\npost-hardcore shoegaze alternative rock\npost-hardcore trance\npost-hardcore trancecore\npost-hardcore, Christian rock\npost-hardcore, J-rock\npost-hardcore, J-rock, cinematic rock\npost-hardcore, J-rock, electronic\npost-hardcore, J-rock, pop-punk\npost-hardcore, Nintendocore\npost-hardcore, alternative metal\npost-hardcore, alternative metal, ballad\npost-hardcore, alternative metal, baroque\npost-hardcore, alternative metal, cinematic\npost-hardcore, alternative metal, cinematic ambient\npost-hardcore, alternative metal, cinematic rock\npost-hardcore, alternative metal, metalcore\npost-hardcore, alternative metal, rap-rock\npost-hardcore, alternative rock, ambient\npost-hardcore, cinematic rock, C-pop\npost-hardcore, cinematic rock, metal\npost-hardcore, cinematic rock, metalcore\npost-hardcore, cinematic rock, nu-metal\npost-hardcore, cinematic, C-pop\npost-hardcore, electronic, hyperpop\npost-hardcore, hip-hop, metalcore\npost-hardcore, hyperpop, electronic\npost-hardcore, indie rock, J-rock\npost-hardcore, indie rock, ambient\npost-hardcore, math rock\npost-hardcore, math rock, emo\npost-hardcore, math rock, metalcore\npost-hardcore, metalcore, acoustic ballad\npost-hardcore, metalcore, alternative rock\npost-hardcore, metalcore, ambient piano\npost-hardcore, metalcore, ambient pop\npost-hardcore, metalcore, atmospheric\npost-hardcore, metalcore, cabaret\npost-hardcore, metalcore, cinematic\npost-hardcore, metalcore, cinematic rock\npost-hardcore, metalcore, electronicore\npost-hardcore, metalcore, emo\npost-hardcore, metalcore, emo-rock\npost-hardcore, metalcore, indie rock\npost-hardcore, metalcore, nu-metal\npost-hardcore, metalcore, post-rock\npost-hardcore, metalcore, power ballad\npost-hardcore, metalcore, rap rock\npost-hardcore, metalcore, rap-rock\npost-hardcore, metalcore, trap\npost-hardcore, nintendocore\npost-hardcore, nu-disco, metalcore\npost-hardcore, nu-metal, alternative metal\npost-hardcore, nu-metal, atmospheric\npost-hardcore, nu-metal, chiptune\npost-hardcore, nu-metal, electronic\npost-hardcore, nu-metal, metalcore\npost-hardcore, nu-metal, post-rock\npost-hardcore, pop-punk\npost-hardcore, pop-punk, metalcore\npost-hardcore, rap-rock, pop-punk\npost-hardcore, screamo, metalcore\npost-hardcore, shoegaze\npost-hardcore, shoegaze, ambient\npost-hardcore, shoegaze, cinematic rock\npost-hardcore, shoegaze, emo\npost-hardcore, shoegaze, emo rap\npost-hardcore, shoegaze, indie rock\npost-hardcore, shoegaze, metalcore\npost-hardcore, trap, ambient\npost-hardcore, trap-rap, ambient\npost-metal\npost-metal alternative metal\npost-metal ambient\npost-metal doom metal\npost-metal doomgaze\npost-metal progressive metalcore\npost-metal screamo\npost-metal shoegaze\npost-metal shoegaze ambient\npost-metal sludge metal\npost-metal, ambient, dream-pop\npost-metal, chiptune, doom metal\npost-metal, cinematic, ambient\npost-metal, doom metal\npost-metal, doom metal, C-pop\npost-metal, doom metal, ambient\npost-metal, doom metal, cinematic\npost-metal, doom metal, cinematic rock\npost-metal, doom metal, metalcore\npost-metal, doom metal, post-rock\npost-metal, doomgaze, cinematic\npost-metal, melodic death metal\npost-metal, metalcore\npost-metal, post-rock, cinematic\npost-metal, rap-metal, heavy\npost-metal, shoegaze, alternative rock\npost-metal, shoegaze, metalcore\npost-metal, symphonic metalcore\npost-punk\npost-punk alternative rock\npost-punk art-rock\npost-punk cabaret\npost-punk chiptune\npost-punk cloud rap\npost-punk coldwave\npost-punk darkwave\npost-punk darkwave chiptune\npost-punk disco-funk\npost-punk dream pop\npost-punk dream pop shoegaze\npost-punk dream-pop\npost-punk dream-pop shoegaze\npost-punk electronic\npost-punk emo\npost-punk emo rap\npost-punk funk\npost-punk funk rock\npost-punk funk-rock\npost-punk garage punk\npost-punk garage rock\npost-punk garage-rock\npost-punk goth rock\npost-punk gothic rock\npost-punk grunge\npost-punk hardcore punk\npost-punk hip hop\npost-punk hip-hop\npost-punk indie rock\npost-punk industrial metal\npost-punk industrial rock\npost-punk jangle-pop\npost-punk lo-fi\npost-punk lo-fi hip-hop\npost-punk metal\npost-punk metalcore\npost-punk new wave\npost-punk noir-jazz\npost-punk nu-metal\npost-punk psychedelic\npost-punk revival\npost-punk rock\npost-punk shoegaze\npost-punk surf rock\npost-punk surf-rock\npost-punk synth-pop\npost-punk synth-pop chiptune\npost-punk synth-pop new wave\npost-punk synth-rock\npost-punk trap\npost-punk trip-hop\npost-punk, 80s Eastern European rock\npost-punk, 80s Italian rock\npost-punk, 80s Japanese new wave\npost-punk, 80s Russian rock\npost-punk, 80s Soviet new wave\npost-punk, 80s alternative rock\npost-punk, 80s alternative rock, new wave\npost-punk, 80s electronic, new wave\npost-punk, 80s new wave\npost-punk, 80s new wave, Eastern European\npost-punk, 80s rock, Eastern European\npost-punk, Brazilian rock\npost-punk, C-pop, lo-fi\npost-punk, EBM, cinematic\npost-punk, Eastern European rock\npost-punk, Eastern European rock, lo-fi\npost-punk, Eastern European rock, new wave\npost-punk, Eastern European rock, synth rock\npost-punk, French cold wave\npost-punk, Italian new wave\npost-punk, Italian rock, 80s\npost-punk, Italo, 80s\npost-punk, Italo-disco\npost-punk, J-rock\npost-punk, Japanese new wave\npost-punk, Latin fusion, flamenco rock\npost-punk, Latin pop-rock\npost-punk, Latin rock\npost-punk, Middle Eastern fusion\npost-punk, Middle Eastern, electronic\npost-punk, Middle Eastern, funk\npost-punk, Neue Deutsche Härte\npost-punk, Neue Deutsche Welle\npost-punk, Neue Deutsche Welle, alternative rock\npost-punk, Neue Deutsche Welle, rock\npost-punk, Neue Deutsche Welle, synth-pop\npost-punk, Russian indie rock\npost-punk, Russian rock\npost-punk, Russian rock, melodic\npost-punk, Russian rock, synthwave\npost-punk, Soviet new wave\npost-punk, Soviet new wave, 80s\npost-punk, Soviet new wave, 80s synth\npost-punk, Soviet new wave, ambient\npost-punk, Soviet new wave, noise rock\npost-punk, Soviet new wave, synth rock\npost-punk, Soviet new wave, synth-driven\npost-punk, Soviet new wave, synthwave\npost-punk, Soviet pop-rock\npost-punk, Soviet rock\npost-punk, Soviet rock, 80s\npost-punk, Soviet rock, 80s rock\npost-punk, Soviet rock, 80s synth\npost-punk, Soviet rock, electronic\npost-punk, Soviet rock, energetic\npost-punk, Soviet rock, funk rock\npost-punk, Soviet rock, garage rock\npost-punk, Soviet rock, heavy rock\npost-punk, Soviet rock, new wave\npost-punk, Soviet rock, noise-rock\npost-punk, Soviet rock, surf-rock\npost-punk, Soviet rock, synth rock\npost-punk, Soviet rock, synth-driven\npost-punk, Soviet, estrada\npost-punk, Spanish rock\npost-punk, Turkish alternative rock\npost-punk, Turkish indie rock\npost-punk, alternative R&B, lo-fi hip-hop\npost-punk, alternative metal\npost-punk, alternative metal, Russian indie\npost-punk, alternative metal, Russian punk\npost-punk, alternative metal, Russian rock\npost-punk, alternative metal, atmospheric\npost-punk, alternative metal, cinematic\npost-punk, alternative metal, cinematic rock\npost-punk, alternative metal, gothic rock\npost-punk, alternative metal, grunge\npost-punk, alternative metal, nu-metal\npost-punk, alternative metal, post-hardcore\npost-punk, alternative metal, shoegaze\npost-punk, alternative rock\npost-punk, alternative rock, 80s\npost-punk, alternative rock, Arabic rock\npost-punk, alternative rock, C-pop\npost-punk, alternative rock, French rock\npost-punk, alternative rock, Hebrew vocal\npost-punk, alternative rock, Latin rock\npost-punk, alternative rock, Latin-tinged\npost-punk, alternative rock, Russian indie\npost-punk, alternative rock, Russian rock\npost-punk, alternative rock, ambient\npost-punk, alternative rock, atmospheric\npost-punk, alternative rock, blues rock\npost-punk, alternative rock, chiptune\npost-punk, alternative rock, cinematic\npost-punk, alternative rock, dark wave\npost-punk, alternative rock, dream pop\npost-punk, alternative rock, dream-pop\npost-punk, alternative rock, electronic\npost-punk, alternative rock, grunge\npost-punk, alternative rock, hard rock\npost-punk, alternative rock, hip-hop\npost-punk, alternative rock, industrial\npost-punk, alternative rock, industrial rock\npost-punk, alternative rock, lo-fi\npost-punk, alternative rock, metalcore\npost-punk, alternative rock, noise\npost-punk, alternative rock, noise rock\npost-punk, alternative rock, nu-metal\npost-punk, alternative rock, post-grunge\npost-punk, alternative rock, post-hardcore\npost-punk, alternative rock, punk\npost-punk, alternative rock, rap-rock\npost-punk, alternative rock, shoegaze\npost-punk, alternative rock, ska-punk\npost-punk, alternative rock, synthwave\npost-punk, alternative rock, thrash metal\npost-punk, ambient, cinematic\npost-punk, ambient, electronic\npost-punk, ambient, ethereal\npost-punk, ambient, funk-rock\npost-punk, ambient, shoegaze\npost-punk, ambient, synthwave\npost-punk, arena rock\npost-punk, art pop, cinematic\npost-punk, art rock, French chanson\npost-punk, art rock, free jazz\npost-punk, art-punk, new wave\npost-punk, art-rock, Latin jazz\npost-punk, art-rock, funk\npost-punk, atmospheric, Eastern European\npost-punk, bard-rock, rock\npost-punk, baroque, French rock\npost-punk, baroque, progressive rock\npost-punk, cabaret rock, punk rock\npost-punk, cabaret, punk\npost-punk, chiptune\npost-punk, chiptune, Russian\npost-punk, chiptune, atmospheric\npost-punk, chiptune, electronic\npost-punk, chiptune, lo-fi\npost-punk, chiptune, noise rock\npost-punk, chiptune, rock\npost-punk, chiptune, synth rock\npost-punk, chiptune, synth-pop\npost-punk, chiptune, synthwave\npost-punk, chiptune, theatrical rock\npost-punk, cinematic rock\npost-punk, cinematic synth, Russian rock\npost-punk, cinematic synth, new wave\npost-punk, cinematic, C-pop\npost-punk, cinematic, German rock\npost-punk, cinematic, Russian rock\npost-punk, cinematic, Spanish rock\npost-punk, cinematic, ambient\npost-punk, cinematic, art rock\npost-punk, cinematic, dark wave\npost-punk, cinematic, experimental\npost-punk, cinematic, gothic rock\npost-punk, cinematic, new wave\npost-punk, cinematic, psychedelic\npost-punk, cinematic, synth rock\npost-punk, cinematic, synthwave\npost-punk, cloud rap, darkwave\npost-punk, cold wave\npost-punk, cold wave, goth rock\npost-punk, cold wave, new wave\npost-punk, cold wave, synth\npost-punk, coldwave\npost-punk, coldwave, 80s\npost-punk, coldwave, EBM\npost-punk, coldwave, Eastern European\npost-punk, coldwave, French chanson\npost-punk, coldwave, Greek rock\npost-punk, coldwave, Russian\npost-punk, coldwave, Russian post-punk\npost-punk, coldwave, Russian rock\npost-punk, coldwave, Soviet new wave\npost-punk, coldwave, atmospheric\npost-punk, coldwave, cinematic\npost-punk, coldwave, dance-punk\npost-punk, coldwave, dark wave\npost-punk, coldwave, darkwave\npost-punk, coldwave, dream-pop\npost-punk, coldwave, electronic\npost-punk, coldwave, goth rock\npost-punk, coldwave, gothic\npost-punk, coldwave, gothic rock\npost-punk, coldwave, indie rock\npost-punk, coldwave, industrial\npost-punk, coldwave, industrial rock\npost-punk, coldwave, lo-fi\npost-punk, coldwave, motorik\npost-punk, coldwave, new wave\npost-punk, coldwave, noise rock\npost-punk, coldwave, psychedelic\npost-punk, coldwave, retro\npost-punk, coldwave, shoegaze\npost-punk, coldwave, synth\npost-punk, coldwave, synth-driven\npost-punk, coldwave, synth-pop\npost-punk, coldwave, synthwave\npost-punk, cumbia, Russian\npost-punk, cumbia, electronic\npost-punk, dance-punk\npost-punk, dance-punk, cinematic\npost-punk, dance-punk, funk\npost-punk, dance-punk, new wave\npost-punk, dance-rock\npost-punk, dance-rock, synth brass\npost-punk, dark synth, cinematic\npost-punk, dark wave\npost-punk, dark wave, 80s new wave\npost-punk, dark wave, cinematic\npost-punk, dark wave, coldwave\npost-punk, dark wave, new wave\npost-punk, darkwave\npost-punk, darkwave, 80s\npost-punk, darkwave, alternative rock\npost-punk, darkwave, ambient\npost-punk, darkwave, coldwave\npost-punk, darkwave, electronic\npost-punk, darkwave, goth rock\npost-punk, darkwave, gothic rock\npost-punk, darkwave, industrial rock\npost-punk, darkwave, lo-fi\npost-punk, darkwave, new wave\npost-punk, darkwave, shoegaze\npost-punk, darkwave, synth-pop\npost-punk, darkwave, synthwave\npost-punk, deep house, Russian\npost-punk, doom metal\npost-punk, doom metal, gothic metal\npost-punk, dream pop\npost-punk, dream pop, ambient\npost-punk, dream pop, indie rock\npost-punk, dream pop, new wave\npost-punk, dream pop, shoegaze\npost-punk, dream pop, synthwave\npost-punk, dream-pop\npost-punk, dream-pop, Italian rock\npost-punk, dream-pop, ambient\npost-punk, dream-pop, cinematic\npost-punk, dream-pop, electronic\npost-punk, dream-pop, indie-pop\npost-punk, dream-pop, lo-fi\npost-punk, dream-pop, noise-rock\npost-punk, dream-pop, rap\npost-punk, dream-pop, shoegaze\npost-punk, dream-pop, synthwave\npost-punk, electro-pop\npost-punk, electronic, Arabic rock\npost-punk, electronic, C-pop\npost-punk, electronic, Eastern European\npost-punk, electronic, Russian rap\npost-punk, electronic, cinematic\npost-punk, electronic, experimental\npost-punk, electronic, industrial rock\npost-punk, electronic, world music\npost-punk, electronicore, hyperpop\npost-punk, emo, shoegaze\npost-punk, emo-rap, rap rock\npost-punk, epic rock, Spanish rock\npost-punk, estrada, retro synth\npost-punk, ethereal, Middle Eastern\npost-punk, experimental, dream-pop\npost-punk, folk, ambient\npost-punk, folk, electronic\npost-punk, folk, new wave\npost-punk, funk, French new wave\npost-punk, funk, cold wave\npost-punk, funk, gypsy-punk\npost-punk, funk, jazz fusion\npost-punk, funk, new wave\npost-punk, funk, synth\npost-punk, garage rock\npost-punk, garage rock, Christmas\npost-punk, garage rock, blues rock\npost-punk, garage rock, dream pop\npost-punk, garage rock, experimental\npost-punk, garage rock, indie rock\npost-punk, garage rock, lo-fi\npost-punk, garage rock, shoegaze\npost-punk, glitch, electronic\npost-punk, goth rock\npost-punk, goth rock, 80s\npost-punk, goth rock, dark wave\npost-punk, goth rock, punk\npost-punk, goth rock, synth rock\npost-punk, goth rock, synthwave\npost-punk, gothic metal, cinematic rock\npost-punk, gothic rock\npost-punk, gothic rock, 80s\npost-punk, gothic rock, 80s Soviet\npost-punk, gothic rock, 80s new wave\npost-punk, gothic rock, 80s synth\npost-punk, gothic rock, Eastern European\npost-punk, gothic rock, Latin rock\npost-punk, gothic rock, alternative metal\npost-punk, gothic rock, cinematic\npost-punk, gothic rock, hard rock\npost-punk, gothic rock, industrial metal\npost-punk, gothic rock, synth-driven\npost-punk, gothic, Eastern European\npost-punk, gothic, dark wave\npost-punk, grunge, alternative metal\npost-punk, grunge, alternative rock\npost-punk, grunge, punk\npost-punk, hard rock\npost-punk, hard rock, Hebrew rock\npost-punk, hard rock, Latin rock\npost-punk, hard rock, Russian metal\npost-punk, hard rock, Russian rock\npost-punk, hard rock, atmospheric\npost-punk, hard rock, blues-rock\npost-punk, hard rock, cinematic\npost-punk, hard rock, electronic\npost-punk, hard rock, gothic rock\npost-punk, hard rock, heavy metal\npost-punk, hard rock, industrial\npost-punk, hard rock, melodic rock\npost-punk, hard rock, theatrical rock\npost-punk, hardcore punk\npost-punk, hardcore punk, new wave\npost-punk, hardstyle\npost-punk, hardstyle, gabber\npost-punk, hardstyle, trap\npost-punk, heavy metal\npost-punk, heavy metal, ambient\npost-punk, heavy metal, power metal\npost-punk, heavy metal, thrash metal\npost-punk, hyperpop, synthwave\npost-punk, indie dance, new wave\npost-punk, indie rock\npost-punk, indie rock, Eastern European\npost-punk, indie rock, Mandarin rock\npost-punk, indie rock, Polish rock\npost-punk, indie rock, Russian hip-hop\npost-punk, indie rock, ambient\npost-punk, indie rock, chiptune\npost-punk, indie rock, cinematic\npost-punk, indie rock, dream pop\npost-punk, indie rock, electronic\npost-punk, indie rock, garage rock\npost-punk, indie rock, new wave\npost-punk, indie rock, noise rock\npost-punk, indie rock, psychedelic\npost-punk, indie rock, shoegaze\npost-punk, indie-pop\npost-punk, industrial metal\npost-punk, industrial rock\npost-punk, industrial rock, dark wave\npost-punk, industrial rock, lo-fi\npost-punk, industrial rock, synthwave\npost-punk, industrial synth, dream pop\npost-punk, industrial, ambient\npost-punk, industrial, noise rock\npost-punk, industrial, rap\npost-punk, industrial, shoegaze\npost-punk, industrial, synth-pop\npost-punk, industrial, theatrical\npost-punk, italo, new wave\npost-punk, klezmer rock\npost-punk, latin funk, new wave\npost-punk, lo-fi indie, Russian post-punk\npost-punk, lo-fi, C-pop\npost-punk, lo-fi, Russian\npost-punk, lo-fi, coldwave\npost-punk, lo-fi, electronic\npost-punk, lo-fi, experimental\npost-punk, lo-fi, garage rock\npost-punk, lo-fi, klezmer-punk\npost-punk, lo-fi, new wave\npost-punk, lo-fi, psychedelic\npost-punk, lo-fi, synth\npost-punk, lo-fi, synthwave\npost-punk, lounge jazz, experimental\npost-punk, math-rock, chiptune\npost-punk, math-rock, metalcore\npost-punk, metal\npost-punk, metal, ambient\npost-punk, metalcore\npost-punk, metalcore, ambient\npost-punk, metalcore, atmospheric rock\npost-punk, metalcore, electronic\npost-punk, metalcore, experimental\npost-punk, metalcore, lo-fi\npost-punk, metalcore, psychedelic\npost-punk, metalcore, shoegaze\npost-punk, minimal, electro-funk\npost-punk, motorik, lo-fi\npost-punk, motorik, new wave\npost-punk, new wave\npost-punk, new wave, 80s\npost-punk, new wave, Brazilian rock\npost-punk, new wave, C-pop\npost-punk, new wave, EBM\npost-punk, new wave, Eastern European\npost-punk, new wave, Eastern European rock\npost-punk, new wave, French rock\npost-punk, new wave, Greek rock\npost-punk, new wave, Hebrew rock\npost-punk, new wave, Italian rock\npost-punk, new wave, Italo disco\npost-punk, new wave, Latin percussion\npost-punk, new wave, Latin rock\npost-punk, new wave, Russian\npost-punk, new wave, Russian pop\npost-punk, new wave, Russian rock\npost-punk, new wave, Soviet era\npost-punk, new wave, Soviet rock\npost-punk, new wave, Soviet wave\npost-punk, new wave, Soviet-era\npost-punk, new wave, Spanish rock\npost-punk, new wave, Turkish synth\npost-punk, new wave, alternative rock\npost-punk, new wave, art pop\npost-punk, new wave, art-pop\npost-punk, new wave, atmospheric\npost-punk, new wave, boogie-woogie\npost-punk, new wave, chiptune\npost-punk, new wave, cinematic\npost-punk, new wave, cinematic synth\npost-punk, new wave, cold wave\npost-punk, new wave, coldwave\npost-punk, new wave, dance\npost-punk, new wave, dance-punk\npost-punk, new wave, dark wave\npost-punk, new wave, disco\npost-punk, new wave, disco-rock\npost-punk, new wave, dream pop\npost-punk, new wave, dream-pop\npost-punk, new wave, electronic\npost-punk, new wave, folk\npost-punk, new wave, folk-punk\npost-punk, new wave, funk\npost-punk, new wave, funk rock\npost-punk, new wave, garage rock\npost-punk, new wave, gospel\npost-punk, new wave, goth rock\npost-punk, new wave, gothic rock\npost-punk, new wave, hard rock\npost-punk, new wave, indie rock\npost-punk, new wave, industrial rock\npost-punk, new wave, jangle pop\npost-punk, new wave, lo-fi\npost-punk, new wave, minimalist\npost-punk, new wave, motorik\npost-punk, new wave, noise rock\npost-punk, new wave, rock\npost-punk, new wave, shoegaze\npost-punk, new wave, surf-rock\npost-punk, new wave, synth\npost-punk, new wave, synth funk\npost-punk, new wave, synth pop\npost-punk, new wave, synth punk\npost-punk, new wave, synth rock\npost-punk, new wave, synth-driven\npost-punk, new wave, synth-pop\npost-punk, new wave, synthwave\npost-punk, new wave, world music\npost-punk, noise rock\npost-punk, noise rock, C-pop\npost-punk, noise rock, Chinese experimental\npost-punk, noise rock, Chinese rock\npost-punk, noise rock, French indie\npost-punk, noise rock, French pop\npost-punk, noise rock, French rock\npost-punk, noise rock, Hebrew rock\npost-punk, noise rock, Russian rock\npost-punk, noise rock, Turkish rock\npost-punk, noise rock, ambient\npost-punk, noise rock, atmospheric\npost-punk, noise rock, cinematic rock\npost-punk, noise rock, dream pop\npost-punk, noise rock, electronic\npost-punk, noise rock, ethereal\npost-punk, noise rock, indie rock\npost-punk, noise rock, industrial\npost-punk, noise rock, instrumental\npost-punk, noise rock, lo-fi\npost-punk, noise rock, metal\npost-punk, noise rock, psychedelic\npost-punk, noise rock, psychedelic rock\npost-punk, noise rock, shoegaze\npost-punk, noise rock, synth pop\npost-punk, noise rock, synthwave\npost-punk, noise rock, theatrical\npost-punk, noise rock, theatrical rock\npost-punk, noise-rock\npost-punk, noise-rock, French indie\npost-punk, noise-rock, Spanish rock\npost-punk, noise-rock, cinematic\npost-punk, noise-rock, electronic\npost-punk, noise-rock, indie rock\npost-punk, noise-rock, shoegaze\npost-punk, noise-rock, theatrical rock\npost-punk, nu-metal\npost-punk, orchestral, cinematic\npost-punk, phonk\npost-punk, pop-punk\npost-punk, pop-punk, alternative rock\npost-punk, post-hardcore\npost-punk, post-hardcore, metalcore\npost-punk, post-hardcore, post-rock\npost-punk, post-metal\npost-punk, post-metal, shoegaze\npost-punk, post-rock, ambient\npost-punk, post-rock, lo-fi\npost-punk, post-rock, punk\npost-punk, power metal\npost-punk, psychedelic rock\npost-punk, psychedelic rock, Italian art rock\npost-punk, psychedelic rock, hard rock\npost-punk, psychedelic rock, tribal\npost-punk, psychedelic, atmospheric\npost-punk, psychedelic, electronic\npost-punk, psychedelic, ritualistic\npost-punk, psychedelic, synthwave\npost-punk, psychedelic, world music\npost-punk, punk rock\npost-punk, punk rock, German rock\npost-punk, punk rock, dream-pop\npost-punk, punk rock, metal\npost-punk, punk rock, thrash metal\npost-punk, punk rock, thrash punk\npost-punk, punk rock, world music\npost-punk, raw punk, Russian rock\npost-punk, retro, estrada pop\npost-punk, rock, French theatrical\npost-punk, rock, Hebrew punk\npost-punk, rock, Russian punk\npost-punk, rock, Russian rock\npost-punk, rock, experimental\npost-punk, shoegaze\npost-punk, shoegaze, C-pop\npost-punk, shoegaze, Chinese rock\npost-punk, shoegaze, EBM\npost-punk, shoegaze, French indie\npost-punk, shoegaze, Hebrew rock\npost-punk, shoegaze, Japanese rock\npost-punk, shoegaze, Portuguese rock\npost-punk, shoegaze, Russian rock\npost-punk, shoegaze, Spanish rock\npost-punk, shoegaze, alternative rock\npost-punk, shoegaze, ambient\npost-punk, shoegaze, ambient rock\npost-punk, shoegaze, atmospheric\npost-punk, shoegaze, chiptune\npost-punk, shoegaze, cinematic\npost-punk, shoegaze, coldwave\npost-punk, shoegaze, dark wave\npost-punk, shoegaze, dream pop\npost-punk, shoegaze, dream-pop\npost-punk, shoegaze, electronic\npost-punk, shoegaze, experimental\npost-punk, shoegaze, experimental rock\npost-punk, shoegaze, glitch\npost-punk, shoegaze, hard rock\npost-punk, shoegaze, indie folk\npost-punk, shoegaze, indie rock\npost-punk, shoegaze, italo\npost-punk, shoegaze, lo-fi\npost-punk, shoegaze, minimalist\npost-punk, shoegaze, motorik\npost-punk, shoegaze, noise rock\npost-punk, shoegaze, noise-rock\npost-punk, shoegaze, post-hardcore\npost-punk, shoegaze, post-rock\npost-punk, shoegaze, rock\npost-punk, shoegaze, synthwave\npost-punk, surf-rock\npost-punk, surf-rock, French theatrical\npost-punk, surf-rock, raw rock\npost-punk, surf-rock, rockabilly\npost-punk, surf-rock, satirical\npost-punk, symphonic metal\npost-punk, synth, chiptune\npost-punk, synth-pop\npost-punk, synth-pop, EBM\npost-punk, synth-pop, Russian\npost-punk, synth-pop, Russian alternative rock\npost-punk, synth-pop, Soviet\npost-punk, synth-pop, alternative rock\npost-punk, synth-pop, chiptune\npost-punk, synth-pop, cinematic\npost-punk, synth-pop, dream pop\npost-punk, synth-pop, new wave\npost-punk, synth-punk, Russian rock\npost-punk, synth-rock\npost-punk, synth-rock, shoegaze\npost-punk, synthwave, Chinese electronic\npost-punk, synthwave, Russian rock\npost-punk, synthwave, Soviet new wave\npost-punk, synthwave, Spanish indie\npost-punk, synthwave, chiptune\npost-punk, synthwave, electronic\npost-punk, synthwave, lo-fi\npost-punk, techno\npost-punk, thrash metal\npost-punk, thrash metal, alternative rock\npost-punk, trap, Russian\npost-punk, trap, ambient\npost-punk, tribal, psychedelic\npost-punk, trip-hop, ambient\npost-punk, world music, experimental rock\npost-punk, world music, rock\npost-rock\npost-rock C-pop\npost-rock Christian rock\npost-rock acoustic\npost-rock alt-rock\npost-rock alternative\npost-rock alternative hip-hop\npost-rock alternative metal\npost-rock alternative rock\npost-rock alternative rock indie rock\npost-rock alternative rock metalcore\npost-rock alternative rock shoegaze\npost-rock alternative shoegaze\npost-rock alternative trap\npost-rock ambient\npost-rock ambient electronica\npost-rock ambient folk\npost-rock ambient lo-fi hip-hop\npost-rock ambient rock\npost-rock arena rock\npost-rock art-rock\npost-rock ballad\npost-rock blues-rock\npost-rock chillwave\npost-rock chiptune\npost-rock christian rock\npost-rock cinematic\npost-rock cloud rap\npost-rock doom metal\npost-rock dream pop\npost-rock dream-pop\npost-rock dubstep\npost-rock electronic\npost-rock electronic rock\npost-rock electronica\npost-rock electronica breakbeat\npost-rock electronica world music\npost-rock emo\npost-rock emo alternative rock\npost-rock emo metalcore\npost-rock emo pop-punk\npost-rock emo rap\npost-rock emo rock\npost-rock emo-rap\npost-rock emo-rock\npost-rock folk\npost-rock folk-rock\npost-rock funk\npost-rock funk-rock\npost-rock funk-rock hard rock\npost-rock future bass\npost-rock garage punk\npost-rock garage rock\npost-rock gospel\npost-rock gospel rock\npost-rock gothic metal\npost-rock groove metal\npost-rock grunge\npost-rock grunge rap\npost-rock hard rock\npost-rock hardcore punk\npost-rock heartland rock\npost-rock hip hop\npost-rock hip-hop\npost-rock indie\npost-rock indie folk\npost-rock indie rock\npost-rock indie rock shoegaze\npost-rock indie-folk\npost-rock industrial\npost-rock industrial metal\npost-rock industrial rock\npost-rock lo-fi\npost-rock lo-fi hip hop\npost-rock lo-fi hip-hop\npost-rock lo-fi indie rock\npost-rock math rock\npost-rock math rock chiptune\npost-rock math rock shoegaze\npost-rock math-rock\npost-rock mathcore\npost-rock melodic death metal\npost-rock melodic metal\npost-rock melodic metalcore\npost-rock metal\npost-rock metalcore\npost-rock neoclassical\npost-rock noise rock\npost-rock noise-rock\npost-rock nu-metal\npost-rock pop-punk\npost-rock pop-rock\npost-rock post-hardcore\npost-rock post-hardcore metalcore\npost-rock post-metal\npost-rock power metal\npost-rock progressive house\npost-rock progressive metal\npost-rock progressive rock\npost-rock progressive trance\npost-rock psychedelic blues\npost-rock psychedelic rock\npost-rock punk\npost-rock rap-rock\npost-rock screamo\npost-rock shoegaze\npost-rock shoegaze alternative rock\npost-rock shoegaze ambient\npost-rock shoegaze cinematic\npost-rock shoegaze electronic\npost-rock shoegaze metalcore\npost-rock shoegaze post-hardcore\npost-rock skate punk\npost-rock symphonic metal\npost-rock synthwave\npost-rock thrash metal\npost-rock trap\npost-rock trap metal\npost-rock trip-hop\npost-rock world fusion\npost-rock world music\npost-rock worship\npost-rock worship rock\npost-rock worship-rock\npost-rock, Americana, instrumental rock\npost-rock, Arabic hip hop\npost-rock, Arabic rock, blues rock\npost-rock, Balkan fusion, rock\npost-rock, C-pop, alternative rock\npost-rock, C-pop, ambient\npost-rock, C-pop, ambient rock\npost-rock, C-pop, emotional\npost-rock, C-pop, indie\npost-rock, C-pop, indie rock\npost-rock, C-pop, lo-fi\npost-rock, C-pop, melancholic\npost-rock, Chinese folk, alternative rock\npost-rock, Chinese folk, ambient\npost-rock, Christian rock\npost-rock, Christian rock, ambient\npost-rock, J-rock\npost-rock, J-rock, cinematic\npost-rock, J-rock, pop-punk\npost-rock, J-rock, trance\npost-rock, Middle Eastern folk, cinematic\npost-rock, Middle Eastern rock\npost-rock, Middle Eastern, ambient\npost-rock, acoustic ballad, C-pop\npost-rock, alt-rock, Americana\npost-rock, alt-rock, C-pop\npost-rock, alternative metal\npost-rock, alternative metal, C-pop\npost-rock, alternative metal, Chinese rock\npost-rock, alternative metal, Hungarian rock\npost-rock, alternative metal, acoustic ballad\npost-rock, alternative metal, cinematic\npost-rock, alternative metal, ethereal\npost-rock, alternative metal, metalcore\npost-rock, alternative metal, post-hardcore\npost-rock, alternative metal, psychedelic rock\npost-rock, alternative metal, shoegaze\npost-rock, alternative metalcore\npost-rock, alternative rap, anthemic rock\npost-rock, alternative rock\npost-rock, alternative rock, C-pop\npost-rock, alternative rock, acoustic ballad\npost-rock, alternative rock, ambient\npost-rock, alternative rock, cinematic\npost-rock, alternative rock, dream-pop\npost-rock, alternative rock, emo\npost-rock, alternative rock, hip-hop\npost-rock, alternative rock, melodic death metal\npost-rock, alternative rock, metalcore\npost-rock, alternative rock, noir-jazz\npost-rock, alternative rock, noise rock\npost-rock, alternative rock, nu-metal\npost-rock, alternative rock, post-hardcore\npost-rock, alternative rock, rap\npost-rock, alternative rock, rap-rock\npost-rock, alternative rock, symphonic rock\npost-rock, alternative rock, world music\npost-rock, ambient, C-pop\npost-rock, ambient, Hindi indie\npost-rock, ambient, Icelandic\npost-rock, ambient, cinematic\npost-rock, ambient, experimental\npost-rock, ambient, hip-hop\npost-rock, ambient, indie\npost-rock, ambient, post-metal\npost-rock, ambient, rock\npost-rock, anime theme, cinematic rock\npost-rock, anthemic rock, C-pop\npost-rock, anthemic rock, Mandarin rock\npost-rock, black metal\npost-rock, blues-rock, rock\npost-rock, cinematic metal, C-pop\npost-rock, cinematic metalcore\npost-rock, cinematic rock, C-pop\npost-rock, cinematic, C-pop\npost-rock, cinematic, Chinese rock\npost-rock, cinematic, Mandarin ballad\npost-rock, cinematic, Turkish lament\npost-rock, cinematic, ambient\npost-rock, cinematic, chanson\npost-rock, cinematic, dream pop\npost-rock, cinematic, electronic\npost-rock, cinematic, indie rock\npost-rock, cinematic, indie-rock\npost-rock, cinematic, jazz-rock\npost-rock, cinematic, lounge\npost-rock, cinematic, metalcore\npost-rock, cinematic, operatic\npost-rock, cinematic, orchestral\npost-rock, cinematic, world music\npost-rock, cinematic, worship\npost-rock, death metal\npost-rock, desert rock, hard rock\npost-rock, djent, ambient\npost-rock, djent, metalcore\npost-rock, doom metal\npost-rock, doom metal, alternative rock\npost-rock, doom metal, ambient\npost-rock, doom metal, atmospheric\npost-rock, doom metal, folk\npost-rock, doomgaze, ambient\npost-rock, doomgaze, cinematic\npost-rock, dream pop, C-pop\npost-rock, dream pop, heavy metal\npost-rock, dream-pop, math-rock\npost-rock, dream-pop, metalcore\npost-rock, dubstep, metalcore\npost-rock, electronic rock, dubstep\npost-rock, electronic, C-pop\npost-rock, electronic, Hindi fusion\npost-rock, electronica, cinematic\npost-rock, emo, alternative rock\npost-rock, emo, noise rock\npost-rock, emo, rock\npost-rock, flamenco rock\npost-rock, folk ballad, Chinese indie\npost-rock, folk, Chinese indie\npost-rock, folk, ambient\npost-rock, folk, cinematic\npost-rock, folk-infused, cinematic\npost-rock, folk-punk, Celtic rock\npost-rock, folk-rock, Chinese rock\npost-rock, folk-rock, ambient electronic\npost-rock, future bass, electronic\npost-rock, glitch, breakcore\npost-rock, glitch-hop, ambient\npost-rock, gospel rock, shoegaze\npost-rock, gothic metal, ethereal\npost-rock, gothic rock, thrash metal\npost-rock, groove metal\npost-rock, grunge, ambient\npost-rock, hard rock\npost-rock, hard rock, C-pop\npost-rock, hard rock, Spanish rock\npost-rock, hard rock, Thai rock\npost-rock, hard rock, blues rock\npost-rock, hard rock, blues-rock\npost-rock, hard rock, indie rock\npost-rock, hard rock, metal\npost-rock, hard rock, metalcore\npost-rock, hard rock, progressive metal\npost-rock, hard rock, psychedelic rock\npost-rock, hard rock, shoegaze\npost-rock, hard rock, thrash metal\npost-rock, hard trance\npost-rock, hard trance, hardstyle\npost-rock, hard trance, psytrance\npost-rock, heavy metal\npost-rock, heavy metal, alternative rock\npost-rock, heavy rock, cinematic\npost-rock, hip-hop, alternative\npost-rock, indie folk, ambient\npost-rock, indie rock, Chinese ballad\npost-rock, indie rock, Chinese rock\npost-rock, indie rock, Hindi rock\npost-rock, indie rock, Indonesian rock\npost-rock, indie rock, ambient\npost-rock, indie rock, chiptune\npost-rock, indie rock, noise rock\npost-rock, indie rock, post-hardcore\npost-rock, indie rock, post-metal\npost-rock, indie rock, punk rock\npost-rock, indie rock, shoegaze\npost-rock, indie-folk, ambient\npost-rock, indie-folk, cinematic\npost-rock, industrial metal, grunge\npost-rock, industrial metal, rock\npost-rock, industrial rock, nu-metal\npost-rock, jazz, cinematic\npost-rock, jazz-rock\npost-rock, lo-fi hip hop, Turkish rap\npost-rock, lo-fi hip hop, emo\npost-rock, lo-fi hip hop, trap\npost-rock, lo-fi, C-pop\npost-rock, lo-fi, ambient\npost-rock, lo-fi, experimental\npost-rock, math rock\npost-rock, math rock, alternative metal\npost-rock, math rock, indie rock\npost-rock, math rock, post-hardcore\npost-rock, math-rock, ambient\npost-rock, math-rock, metalcore\npost-rock, math-rock, progressive metal\npost-rock, melancholic, Turkish folk\npost-rock, melodic death metal\npost-rock, melodic hardcore\npost-rock, melodic metalcore, deathcore\npost-rock, metal, rock\npost-rock, metalcore\npost-rock, metalcore, Christmas\npost-rock, metalcore, Russian indie\npost-rock, metalcore, Russian rock\npost-rock, metalcore, alternative metal\npost-rock, metalcore, alternative rock\npost-rock, metalcore, ambient\npost-rock, metalcore, atmospheric rock\npost-rock, metalcore, cinematic\npost-rock, metalcore, cinematic rock\npost-rock, metalcore, electronic\npost-rock, metalcore, emo\npost-rock, metalcore, emotional\npost-rock, metalcore, emotional rock\npost-rock, metalcore, ethereal\npost-rock, metalcore, indie rock\npost-rock, metalcore, industrial\npost-rock, metalcore, lo-fi hip hop\npost-rock, metalcore, math-rock\npost-rock, metalcore, nu-metal\npost-rock, metalcore, post-hardcore\npost-rock, metalcore, rap-rock\npost-rock, metalcore, rock\npost-rock, modern classical\npost-rock, modern metal\npost-rock, modern rock, C-pop\npost-rock, noise rock\npost-rock, noise rock, Mandarin rock\npost-rock, noise rock, alternative rock\npost-rock, noise rock, cinematic rock\npost-rock, noise-rock\npost-rock, noise-rock, ambient\npost-rock, noise-rock, folk\npost-rock, noise-rock, industrial\npost-rock, noise-rock, neo-classical\npost-rock, noise-rock, shoegaze\npost-rock, nu-metal, alternative rock\npost-rock, nu-metal, ambient\npost-rock, nu-metal, electronicore\npost-rock, pop-punk, Russian rap\npost-rock, pop-punk, alternative rock\npost-rock, pop-punk, emo\npost-rock, pop-punk, metalcore\npost-rock, pop-punk, rap-rock\npost-rock, pop-rock, C-pop\npost-rock, pop-rock, ambient\npost-rock, post-hardcore\npost-rock, post-hardcore, C-pop\npost-rock, post-hardcore, French indie\npost-rock, post-hardcore, Russian rock\npost-rock, post-hardcore, Spanish rock\npost-rock, post-hardcore, alternative rock\npost-rock, post-hardcore, ambient\npost-rock, post-hardcore, cinematic\npost-rock, post-hardcore, deathcore\npost-rock, post-hardcore, emo\npost-rock, post-hardcore, indie\npost-rock, post-hardcore, indie rock\npost-rock, post-hardcore, lo-fi\npost-rock, post-hardcore, math rock\npost-rock, post-hardcore, math-rock\npost-rock, post-hardcore, metalcore\npost-rock, post-hardcore, nu-metal\npost-rock, post-hardcore, pop-punk\npost-rock, post-hardcore, rap-rock\npost-rock, post-hardcore, rock\npost-rock, post-hardcore, shoegaze\npost-rock, post-metal\npost-rock, post-metal, baroque\npost-rock, post-metal, cinematic\npost-rock, post-metal, metalcore\npost-rock, post-punk\npost-rock, post-punk, shoegaze\npost-rock, progressive metal\npost-rock, progressive metal, Chinese opera\npost-rock, progressive metal, Spanish rock\npost-rock, progressive metal, ambient\npost-rock, progressive metalcore\npost-rock, progressive metalcore, djent\npost-rock, progressive rock, hard rock\npost-rock, progressive rock, math rock\npost-rock, psychedelic rock\npost-rock, psychedelic rock, hard rock\npost-rock, punk rock, alternative rock\npost-rock, punk, C-pop\npost-rock, rap-rock, alternative rock\npost-rock, rap-rock, dream pop\npost-rock, rap-rock, emotional rock\npost-rock, rap-rock, metalcore\npost-rock, rock, C-pop\npost-rock, rock, Chinese rock\npost-rock, rock, Latin rock\npost-rock, rock, Mandarin rock\npost-rock, rock, djent\npost-rock, rock, hip hop\npost-rock, rock, hip-hop\npost-rock, rock, lo-fi\npost-rock, rock, rap\npost-rock, screamo\npost-rock, screamo, metalcore\npost-rock, shoegaze, C-pop\npost-rock, shoegaze, alt-rock\npost-rock, shoegaze, alternative rock\npost-rock, shoegaze, ambient\npost-rock, shoegaze, cinematic\npost-rock, shoegaze, emo\npost-rock, shoegaze, heavy metal\npost-rock, shoegaze, indie rock\npost-rock, shoegaze, lo-fi hip hop\npost-rock, shoegaze, metalcore\npost-rock, shoegaze, post-hardcore\npost-rock, shoegaze, post-metal\npost-rock, shoegaze, rock\npost-rock, shoegaze, screamo\npost-rock, stoner rock, metalcore\npost-rock, symphonic J-rock\npost-rock, symphonic metal\npost-rock, symphonic metal, French chanson\npost-rock, symphonic metal, cinematic\npost-rock, thrash metal\npost-rock, thrash metal, shred guitar\npost-rock, trap, emo-rap\npost-rock, trap, rock\npost-rock, tribal, ethereal\npost-rock, world music, ambient\npost-rock, world music, ethereal\npost-romantic\npower ballad\npower ballad 80s\npower ballad 80s pop\npower ballad 80s pop-rock\npower ballad 80s rock\npower ballad 80s synth\npower ballad 90s\npower ballad 90s pop\npower ballad 90s pop-rock\npower ballad Latin\npower ballad Latin rock\npower ballad alternative metal\npower ballad alternative rock\npower ballad arena rock\npower ballad blues-rock\npower ballad chiptune\npower ballad chiptune J-rock\npower ballad classic rock\npower ballad flamenco\npower ballad funk-rock\npower ballad gospel\npower ballad gospel rock\npower ballad gospel soul\npower ballad hard rock\npower ballad latin\npower ballad metal\npower ballad pop-punk\npower ballad pop-rock\npower ballad progressive rock\npower ballad punk rock\npower ballad rock\npower ballad rock metal\npower ballad rock opera\npower ballad smooth jazz pop-rock\npower ballad symphonic metal\npower ballad world music\npower ballad, 1970s rock\npower ballad, 70s rock, cinematic\npower ballad, 70s rock, theatrical\npower ballad, 70s soul, theatrical\npower ballad, 80s Schlager, cinematic\npower ballad, 80s Schlager, cinematic pop\npower ballad, 80s Schlager, cinematic synth\npower ballad, 80s Schlager, synth pop\npower ballad, 80s Schlager, synth-pop\npower ballad, 80s adult contemporary\npower ballad, 80s adult contemporary, theatrical\npower ballad, 80s arena rock\npower ballad, 80s arena rock, Christmas\npower ballad, 80s dance-pop\npower ballad, 80s hard rock, East Asian fusion\npower ballad, 80s hard rock, Vietnamese rock\npower ballad, 80s hard rock, cinematic\npower ballad, 80s hard rock, glam metal\npower ballad, 80s pop, cinematic\npower ballad, 80s pop, theatrical\npower ballad, 80s pop-rock\npower ballad, 80s pop-rock, Southeast Asian pop\npower ballad, 80s pop-rock, bilingual\npower ballad, 80s rock\npower ballad, 80s rock, C-pop\npower ballad, 80s rock, East Asian fusion\npower ballad, 80s rock, Indonesian\npower ballad, 80s rock, Italian pop\npower ballad, 80s rock, Malay pop\npower ballad, 80s rock, Spanish\npower ballad, 80s rock, Spanish rock\npower ballad, 80s rock, Sundanese pop\npower ballad, 80s rock, Taiwanese Hokkien\npower ballad, 80s rock, Vietnamese\npower ballad, 80s rock, cinematic\npower ballad, 80s rock, cinematic rock\npower ballad, 80s rock, stadium rock\npower ballad, 80s rock, theatrical\npower ballad, 80s show tune, theatrical\npower ballad, 80s synth, anthemic\npower ballad, 80s synth, cinematic\npower ballad, 80s synth, cinematic rock\npower ballad, 80s synth, operatic rock\npower ballad, 80s synth, rock\npower ballad, 80s synth, theatrical\npower ballad, 80s synth-pop, anthemic\npower ballad, 80s synth-pop, cinematic\npower ballad, 80s, German\npower ballad, 80s, Middle Eastern\npower ballad, 80s, bilingual\npower ballad, 80s, cinematic\npower ballad, 80s, gospel\npower ballad, 80s, theatrical\npower ballad, 90s Eastern European pop\npower ballad, 90s Southeast Asian pop\npower ballad, 90s pop, Southeast Asian pop\npower ballad, 90s pop-rock, Southeast Asian\npower ballad, 90s rock\npower ballad, Axé\npower ballad, Axé music\npower ballad, Axé, rock\npower ballad, Axé, samba-reggae\npower ballad, Balkan folk, rock\npower ballad, Balkan folk, theatrical rock\npower ballad, Balkan rock, 80s rock\npower ballad, Brazilian romantic pop, cinematic\npower ballad, C-pop, cinematic\npower ballad, C-pop, cinematic rock\npower ballad, C-pop, rock\npower ballad, EDM-pop\npower ballad, East Asian folk, pop-rock\npower ballad, East Asian, rock\npower ballad, Eastern European pop-rock, 80s synth\npower ballad, Eurodance\npower ballad, Eurodance, dance-pop\npower ballad, European pop, 80s synth\npower ballad, Filipino Christmas, chiptune\npower ballad, Forró Eletrônico\npower ballad, Indonesian rock, cinematic rock\npower ballad, Indonesian, classic rock\npower ballad, Italian musical theater, pop-rock\npower ballad, Italian pop, soulful rock\npower ballad, Italian pop, theatrical\npower ballad, Italian style, cinematic rock\npower ballad, Italian, cinematic\npower ballad, J-rock, 80s synth\npower ballad, J-rock, cinematic\npower ballad, Javanese folk, cinematic rock\npower ballad, Javanese fusion, rock\npower ballad, Javanese pop, metal\npower ballad, Javanese, rock\npower ballad, K-pop, 80s rock\npower ballad, Middle Eastern rock\npower ballad, Middle Eastern rock, Turkish folk rock\npower ballad, Middle Eastern, Balkan\npower ballad, Middle Eastern, cinematic\npower ballad, Middle Eastern, rock\npower ballad, Middle Eastern, theatrical\npower ballad, Mongolian folk, rock\npower ballad, R&B, 80s\npower ballad, R&B, cinematic\npower ballad, R&B, classical piano\npower ballad, Russian estrada, cinematic rock\npower ballad, Schlager, orchestral rock\npower ballad, Southeast Asian pop\npower ballad, Vietnamese pop\npower ballad, arena rock, 80s rock\npower ballad, arena rock, Italian\npower ballad, arena rock, bilingual\npower ballad, arena rock, theatrical\npower ballad, big band jazz, theatrical\npower ballad, big band swing, ska\npower ballad, big band, funk\npower ballad, chiptune, C-pop\npower ballad, chiptune, cinematic\npower ballad, cinematic pop\npower ballad, cinematic pop, 80s East Asian pop\npower ballad, cinematic pop, Indonesian pop\npower ballad, cinematic pop, bilingual\npower ballad, cinematic pop, epic choral\npower ballad, cinematic rock\npower ballad, cinematic rock, Chinese fusion\npower ballad, cinematic rock, Javanese folk rock\npower ballad, cinematic rock, Middle Eastern fusion\npower ballad, cinematic rock, Southeast Asian fusion\npower ballad, cinematic rock, anime soundtrack\npower ballad, cinematic rock, musical theater\npower ballad, cinematic rock, operatic rock\npower ballad, cinematic rock, theatrical pop\npower ballad, cinematic, C-pop\npower ballad, cinematic, Central Asian pop\npower ballad, cinematic, EDM\npower ballad, cinematic, Eastern European folk\npower ballad, cinematic, German pop\npower ballad, cinematic, Indonesian pop\npower ballad, cinematic, Italian\npower ballad, cinematic, J-rock\npower ballad, cinematic, Latin\npower ballad, cinematic, Schlager\npower ballad, cinematic, Southeast Asian\npower ballad, cinematic, musical theater\npower ballad, cinematic, operatic\npower ballad, cinematic, orchestral\npower ballad, cinematic, patriotic\npower ballad, cinematic, rock\npower ballad, cinematic, theatrical\npower ballad, classic rock\npower ballad, classic rock, Italian folk\npower ballad, classic rock, Southeast Asian fusion\npower ballad, classic rock, blues\npower ballad, classic rock, gospel\npower ballad, classic rock, soul\npower ballad, classic rock, soulful\npower ballad, classic rock, theatrical pop\npower ballad, dance-pop\npower ballad, dangdut koplo\npower ballad, disco-pop, anthem\npower ballad, estrada, rock\npower ballad, eurodance\npower ballad, eurodance, trance\npower ballad, flamenco rock, Javanese vocal\npower ballad, flamenco, Eurodance\npower ballad, folk rock, operatic\npower ballad, folk-pop, Eastern European\npower ballad, forró, piseiro\npower ballad, forró, rock\npower ballad, funk-pop, Latin pop-rock\npower ballad, glam metal, 80s rock\npower ballad, glam rock, Italian ballad\npower ballad, gospel rock, Indonesian rock\npower ballad, gospel rock, arena rock\npower ballad, gospel rock, cinematic\npower ballad, gospel rock, patriotic\npower ballad, gospel soul, rap\npower ballad, gospel, 80s\npower ballad, gospel, Latin\npower ballad, gospel, anime\npower ballad, gospel, cinematic\npower ballad, gospel, cinematic rock\npower ballad, gospel, classic rock\npower ballad, gospel, inspirational\npower ballad, gospel, musical theater\npower ballad, gospel, soul\npower ballad, gospel, stadium rock\npower ballad, gospel, world music\npower ballad, hair metal, neoclassical\npower ballad, happy hardcore, hardstyle\npower ballad, hard rock\npower ballad, hard rock, C-pop\npower ballad, hard rock, Chinese fusion\npower ballad, hard rock, Hebrew pop\npower ballad, hard rock, Indonesian rock\npower ballad, hard rock, Italian\npower ballad, hard rock, Italian opera\npower ballad, hard rock, JRPG\npower ballad, hard rock, Javanese\npower ballad, hard rock, Javanese folk\npower ballad, hard rock, Latin pop\npower ballad, hard rock, Malay traditional\npower ballad, hard rock, Mandarin piano\npower ballad, hard rock, Mongolian folk rock\npower ballad, hard rock, Southeast Asian\npower ballad, hard rock, Southeast Asian fusion\npower ballad, hard rock, Sundanese rock\npower ballad, hard rock, alternative metal\npower ballad, hard rock, cinematic\npower ballad, hard rock, cinematic rock\npower ballad, hard rock, emotional\npower ballad, hard rock, heavy metal\npower ballad, hard rock, patriotic\npower ballad, hard rock, shred guitar\npower ballad, hard rock, synth-pop\npower ballad, heavy metal\npower ballad, heavy metal, cinematic rock\npower ballad, heavy metal, rock\npower ballad, hip-hop, rock\npower ballad, late-80s adult contemporary\npower ballad, late-90s rock, Southeast Asian rock\npower ballad, levenslied, cinematic rock\npower ballad, melodic rock, synth-pop\npower ballad, merengue, rock\npower ballad, modern rock, Indonesian traditional\npower ballad, new jack swing\npower ballad, new wave funk-rock\npower ballad, nostalgic rock\npower ballad, operatic, Central Asian folk\npower ballad, orchestral rock, operatic pop\npower ballad, orchestral, Middle Eastern\npower ballad, orchestral, cinematic\npower ballad, patriotic rock, classic rock\npower ballad, pop-punk, Javanese folk\npower ballad, pop-rock\npower ballad, pop-rock, 80s synth\npower ballad, pop-rock, 90s\npower ballad, pop-rock, Eastern European\npower ballad, pop-rock, Indonesian\npower ballad, pop-rock, Latin pop\npower ballad, pop-rock, Mandarin rock\npower ballad, pop-rock, Southeast Asian\npower ballad, pop-rock, Sundanese\npower ballad, pop-rock, cinematic\npower ballad, pop-rock, funk\npower ballad, pop-rock, theatrical\npower ballad, power metal\npower ballad, rap-rock\npower ballad, rap-rock, cinematic\npower ballad, rock\npower ballad, rock opera, French chanson\npower ballad, rock opera, Latin pop\npower ballad, rock opera, cinematic\npower ballad, rock opera, cinematic rock\npower ballad, rock opera, theatrical\npower ballad, rock, 80s pop\npower ballad, rock, 80s rock\npower ballad, rock, C-pop\npower ballad, rock, Cantopop\npower ballad, rock, Christmas\npower ballad, rock, East Asian fusion\npower ballad, rock, Indonesian\npower ballad, rock, Italian theatrical\npower ballad, rock, J-rock\npower ballad, rock, Latin pop\npower ballad, rock, Malay pop\npower ballad, rock, Mandarin rap\npower ballad, rock, Mandarin rock\npower ballad, rock, Mongolian folk\npower ballad, rock, Southeast Asian\npower ballad, rock, Southeast Asian fusion\npower ballad, rock, Southeast Asian pop\npower ballad, rock, Sundanese\npower ballad, rock, Sundanese folk\npower ballad, rock, Sundanese pop\npower ballad, rock, Thai folk\npower ballad, rock, Turkish folk\npower ballad, rock, Turkish fusion\npower ballad, rock, Vietnamese pop\npower ballad, rock, anime theme\npower ballad, rock, cinematic\npower ballad, rock, cumbia\npower ballad, rock, dangdut\npower ballad, rock, funk-rock\npower ballad, rock, live\npower ballad, rock, metal\npower ballad, rock, operatic\npower ballad, rock, patriotic\npower ballad, rock, pop-rock\npower ballad, rock, theatrical\npower ballad, rock, traditional East Asian\npower ballad, rock, traditional Southeast Asian\npower ballad, rock, world fusion\npower ballad, schlager, musical theater\npower ballad, show tune, gospel\npower ballad, show tune, theatrical\npower ballad, soul, R&B\npower ballad, soul, rock\npower ballad, symphonic metal\npower ballad, symphonic metal, piano ballad\npower ballad, symphonic rock, cinematic\npower ballad, symphonic rock, dangdut koplo\npower ballad, symphonic rock, flamenco rock\npower ballad, symphonic rock, lo-fi\npower ballad, synth pop, cinematic\npower ballad, synth-pop\npower ballad, synth-pop, 80s\npower ballad, synth-pop, Italo-disco\npower ballad, synth-pop, hard rock\npower ballad, synthwave, Asian pop\npower ballad, theatrical pop, Italian pop\npower ballad, theatrical rock, Italian opera\npower ballad, theatrical rock, Neapolitan\npower ballad, theatrical rock, arena rock\npower ballad, theatrical rock, gospel rock\npower ballad, theatrical rock, operatic pop\npower ballad, theatrical rock, protest music\npower ballad, theatrical, Christmas\npower ballad, theatrical, cinematic\npower ballad, theatrical, folk rock\npower ballad, theatrical, rock\npower ballad, theatrical, show tune\npower ballad, traditional Malay, rock\npower ballad, vintage rock\npower ballad, vintage soul, doo-wop\npower ballad, vintage soul, rock\npower ballad, world music, cinematic\npower ballad, world music, gospel\npower metal\npower metal bluegrass fusion\npower metal chiptune\npower metal chiptune J-rock\npower metal chiptune electronic\npower metal chiptune folk\npower metal chiptune folk-metal\npower metal chiptune folk-rock\npower metal chiptune gospel\npower metal chiptune rock\npower metal chiptune symphonic\npower metal chiptune synth rock\npower metal chiptune synth-rock\npower metal chiptune synthwave\npower metal cumbia\npower metal dangdut\npower metal dangdut koplo\npower metal dansband\npower metal disco-funk\npower metal electronicore\npower metal electronicore J-rock\npower metal eurobeat\npower metal eurodance\npower metal flamenco\npower metal flamenco shred\npower metal folk\npower metal folk fusion\npower metal folk metal\npower metal folk metal chiptune\npower metal folk punk\npower metal folk rock\npower metal folk-punk\npower metal forró\npower metal glam rock\npower metal glam rock synth-pop\npower metal groove metal\npower metal happy hardcore\npower metal hardcore punk\npower metal industrial\npower metal industrial rock\npower metal italo disco\npower metal j-rock\npower metal klezmer\npower metal mariachi\npower metal neoclassical\npower metal nintendocore\npower metal opera\npower metal pirate metal\npower metal polka\npower metal pop-punk\npower metal pop-rock\npower metal progressive metal\npower metal progressive rock\npower metal punk\npower metal punk rock\npower metal schlager\npower metal sea shanty\npower metal speed metal\npower metal surf rock\npower metal symphonic\npower metal symphonic chiptune\npower metal symphonic folk metal\npower metal symphonic metal\npower metal symphonic metalcore\npower metal symphonic rock\npower metal synth-pop\npower metal synth-rock\npower metal synthwave\npower metal thrash metal\npower metal trancecore\npower metal turbo-folk\npower metal viking metal\npower metal, 80s hard rock, glam metal\npower metal, Anatolian rock\npower metal, Andean folk\npower metal, Balkan folk\npower metal, Brazilian folk\npower metal, C-pop\npower metal, C-pop fusion\npower metal, C-pop, cinematic\npower metal, C-pop, cinematic rock\npower metal, C-pop, symphonic metal\npower metal, C-rock\npower metal, C-rock, anime\npower metal, C-rock, cinematic\npower metal, C-rock, cinematic rock\npower metal, C-rock, wuxia\npower metal, Celtic folk\npower metal, Celtic folk metal\npower metal, Celtic punk\npower metal, Chinese folk\npower metal, Chinese folk fusion\npower metal, Chinese folk rock\npower metal, Chinese folk, symphonic metal\npower metal, Chinese fusion\npower metal, Chinese opera\npower metal, Chinese rock\npower metal, Chinese style\npower metal, Chinese style, cinematic\npower metal, Chinese-style\npower metal, Chinese-style, cinematic\npower metal, Chinese-style, hard rock\npower metal, Chinese-style, rock\npower metal, Eurodance, 90s trance\npower metal, German folk, video game\npower metal, Greek Laïko\npower metal, Greek folk\npower metal, Indian folk\npower metal, Indian rock\npower metal, Indonesian pop\npower metal, Indonesian pop-rock\npower metal, Indonesian rock\npower metal, J-rock\npower metal, J-rock, Chinese fusion\npower metal, J-rock, Chinese-style\npower metal, J-rock, Dangdut Koplo\npower metal, J-rock, Thai pop\npower metal, J-rock, anime\npower metal, J-rock, chiptune\npower metal, J-rock, cinematic\npower metal, J-rock, hardstyle\npower metal, J-rock, hyperpop\npower metal, J-rock, melodic death metal\npower metal, J-rock, metalcore\npower metal, J-rock, modern metal\npower metal, J-rock, symphonic\npower metal, J-rock, symphonic metal\npower metal, J-rock, symphonic rock\npower metal, J-rock, traditional Malay\npower metal, J-rock, video game music\npower metal, J-rock, wuxia\npower metal, Japanese rock\npower metal, Javanese fusion\npower metal, Javanese pop-rock\npower metal, Javanese pop-rock, dangdut koplo\npower metal, Javanese rock, neoclassical metal\npower metal, Javanese traditional\npower metal, Latin folk\npower metal, Latin rock\npower metal, Malay pop\npower metal, Malay pop-rock\npower metal, Malay traditional\npower metal, Mandopop rock\npower metal, Mandopop, cinematic\npower metal, Middle Eastern folk\npower metal, Middle Eastern fusion\npower metal, Middle Eastern pop\npower metal, Middle Eastern rock\npower metal, Neue Deutsche Härte\npower metal, Neue Deutsche Welle\npower metal, Nintendocore\npower metal, Russian folk\npower metal, Southeast Asian fusion\npower metal, Southeast Asian rock\npower metal, Sundanese fusion\npower metal, anison\npower metal, chiptune\npower metal, chiptune, J-rock\npower metal, chiptune, Schlager-rock\npower metal, chiptune, anison\npower metal, chiptune, electronic rock\npower metal, chiptune, electronicore\npower metal, chiptune, melodic death metal\npower metal, chiptune, speed metal\npower metal, chiptune, speedcore\npower metal, chiptune, symphonic metal\npower metal, chiptune, symphonic rock\npower metal, chiptune, synth rock\npower metal, chiptune, video game music\npower metal, cinematic folk, orchestral\npower metal, cinematic rock\npower metal, cinematic rock, J-rock\npower metal, cinematic, C-pop\npower metal, cinematic, Chinese\npower metal, cinematic, Chinese folk\npower metal, cinematic, Chinese opera\npower metal, cinematic, Chinese traditional\npower metal, cinematic, Chinese-style\npower metal, cinematic, dangdut koplo\npower metal, dangdut\npower metal, dangdut koplo\npower metal, dangdut rock\npower metal, dangdut, rock\npower metal, doom metal, cinematic rock\npower metal, educational rock, eurodance\npower metal, eurobeat\npower metal, folk metal\npower metal, folk, C-pop\npower metal, forró, piseiro\npower metal, happy hardcore\npower metal, hard rock\npower metal, hard trance, epic electronic\npower metal, melodic death metal\npower metal, melodic hardcore\npower metal, melodic hardcore, folk metal\npower metal, melodic metalcore\npower metal, melodic punk\npower metal, melodic punk rock\npower metal, metalcore, alternative metal\npower metal, metalcore, cinematic\npower metal, metalcore, cinematic rock\npower metal, metalcore, space rock\npower metal, neoclassical\npower metal, neoclassical J-rock\npower metal, neoclassical shred\npower metal, nintendocore\npower metal, pop-punk\npower metal, pop-punk, J-rock\npower metal, pop-rock\npower metal, pop-rock, Eurodance\npower metal, pop-rock, Southeast Asian\npower metal, rock opera\npower metal, schlager\npower metal, schlager, ska-punk\npower metal, symphonic death metal, J-rock\npower metal, symphonic metal\npower metal, symphonic metal, Chinese fusion\npower metal, symphonic metal, Chinese traditional\npower metal, symphonic metal, J-rock\npower metal, symphonic metal, Neue Deutsche Härte\npower metal, symphonic metal, Russian rock\npower metal, symphonic rock\npower metal, symphonic rock, Chinese folk\npower metal, symphonic rock, anime theme\npower metal, symphonic rock, chiptune\npower metal, symphonic rock, gospel\npower metal, synth-pop, Middle Eastern\npower metal, synth-pop, video game music\npower metal, synth-rock\npower metal, synth-rock, J-rock\npower metal, synth-rock, chiptune\npower metal, synth-rock, video game music\npower metal, synthwave\npower metal, thrash metal, cinematic rock\npower metal, thrash metal, groove metal\npower metal, thrash metal, neo-classical\npower metal, traditional Malay\npower metal, turbo-folk\npower metal, video game music\npower metal, video game music, synthwave\npower metal, western rock\npower metal, wuxia, C-pop\npower metal, wuxia, cinematic\npower pop\npower pop ballad\npower pop chiptune\npower pop garage rock\npower pop glam rock\npower pop indie rock\npower pop jangle pop\npower pop punk\npower pop punk rock\npower pop rock\npower pop surf rock\npower pop, 70s rock, theatrical\npower pop, J-pop\npower pop, J-pop, C-pop\npower pop, J-pop, anime\npower pop, J-rock\npower pop, J-rock, anime\npower pop, J-rock, cinematic pop\npower pop, J-rock, electronic\npower pop, adult contemporary\npower pop, alternative metal\npower pop, alternative rock\npower pop, arena rock, glam metal\npower pop, classic rock\npower pop, garage rock\npower pop, math rock, chiptune\npower pop, new wave\npower pop, new wave, 80s\npower pop, new wave, 80s rock\npower pop, new wave, theatrical rock\npower pop, pop-punk\npower pop, power metal, orchestral\npower pop, punk rock, Swedish\npower pop, rock, 80s\npower pop, rock, cinematic\npower pop, theatrical rock, musical\npower pop, vintage rock, theatrical\npower pop-rock\npower rock\npower rock ballad\npower-folk\npower-pop\npower-pop 80s\npower-pop 90s alternative rock\npower-pop Christian rock\npower-pop J-pop\npower-pop J-rock\npower-pop alt-country rockabilly\npower-pop alt-rock\npower-pop alternative rock\npower-pop anime\npower-pop anime rock\npower-pop anime theme\npower-pop anime-rock\npower-pop arena rock\npower-pop baroque-pop\npower-pop chiptune\npower-pop chiptune J-rock\npower-pop chiptune anime\npower-pop chiptune arena rock\npower-pop chiptune indie rock\npower-pop chiptune pop-punk\npower-pop chiptune rock\npower-pop chiptune synth-rock\npower-pop classic rock\npower-pop country-rock\npower-pop folk\npower-pop folk-punk\npower-pop folk-rock\npower-pop funk-rock\npower-pop funk-rock piano ballad\npower-pop garage rock\npower-pop garage-rock\npower-pop glam rock\npower-pop gospel\npower-pop gospel rock\npower-pop heartland rock\npower-pop hyperpop\npower-pop indie rock\npower-pop jangle-pop\npower-pop latin rock\npower-pop new wave\npower-pop new wave chiptune\npower-pop new wave hip-hop\npower-pop new wave revival\npower-pop new wave theatrical rock\npower-pop orchestral\npower-pop pub rock\npower-pop pub-rock\npower-pop punk rock\npower-pop punk rock chiptune\npower-pop retro\npower-pop retro rock\npower-pop rock\npower-pop rock chiptune\npower-pop rock en español\npower-pop rock theater\npower-pop rockabilly\npower-pop rockabilly children's\npower-pop rockabilly country-rock\npower-pop rockabilly doo-wop\npower-pop rockabilly garage rock\npower-pop rockabilly gospel\npower-pop rockabilly surf rock\npower-pop sci-fi comedy rock\npower-pop sci-fi rock\npower-pop show-tune\npower-pop ska musical theater\npower-pop ska-punk\npower-pop soul-rock\npower-pop southern rock\npower-pop space-rock\npower-pop surf rock\npower-pop surf-rock\npower-pop symphonic rock\npower-pop synth-rock\npower-pop theatrical\npower-pop vintage rock\npower-pop world music\npower-pop, 80s arena rock, synth rock\npower-pop, 80s new wave\npower-pop, 80s new wave, synth-pop\npower-pop, British indie rock\npower-pop, Christian contemporary\npower-pop, Christian rock\npower-pop, Finnish rock\npower-pop, J-rock\npower-pop, J-rock, anime\npower-pop, J-rock, anime theme\npower-pop, J-rock, chiptune\npower-pop, J-rock, cinematic\npower-pop, J-rock, musical theater\npower-pop, J-rock, ska-punk\npower-pop, J-rock, video game music\npower-pop, J-rock, video game soundtrack\npower-pop, JRPG soundtrack, theatrical\npower-pop, Spanish rock\npower-pop, alternative rock, chiptune\npower-pop, chiptune, Italian pop-rock\npower-pop, chiptune, electronic\npower-pop, chiptune, pop-punk\npower-pop, cinematic, satirical\npower-pop, cinematic, theatrical\npower-pop, cinematic, video game\npower-pop, classic rock\npower-pop, classic rock, doo-wop\npower-pop, comedy rock\npower-pop, epic rock, folk\npower-pop, funk-rock, Latin\npower-pop, garage rock\npower-pop, hard rock, chiptune\npower-pop, hip-hop\npower-pop, hyperpop\npower-pop, indie rock, Christmas\npower-pop, musical theater\npower-pop, musical theater, rock-opera\npower-pop, musical theater, synth-pop\npower-pop, musical theatre, satirical pop\npower-pop, new wave\npower-pop, new wave, chiptune\npower-pop, new wave, educational\npower-pop, new wave, glam rock\npower-pop, new wave, retro video game\npower-pop, new wave, rock 'n' roll\npower-pop, new wave, rockabilly\npower-pop, new wave, ska-punk\npower-pop, new wave, space rock\npower-pop, piano ballad, choral\npower-pop, pop-punk\npower-pop, pop-punk, chiptune\npower-pop, pop-punk, theatrical\npower-pop, progressive metal\npower-pop, retro rock, energetic\npower-pop, rock-opera, cinematic\npower-pop, sludge metal\npower-pop, surf-rock, Christmas\npower-pop, surf-rock, ska-punk\npower-pop, synth-pop\npower-pop, synth-pop, 80s\npower-pop, synth-pop, disco-pop\npower-pop, synth-rock, 80s\npower-pop, theatrical rock, classic rock\npower-pop, video game music\npower-pop, video game rock\npraise and worship\npraise and worship funk\npraise and worship funk pop-rock\npraise and worship funk soul\npraise and worship funk-rock\npraise and worship pop-rock\npraise and worship rock\npraise and worship, Brazilian pop-rock\npraise and worship, big band, klezmer\npraise and worship, funk, pop-rock\npraise and worship, soft rock, 80s pop\npraise anthem\npraise rock\npraise worship\nprogressive Arabic rock\nprogressive J-rock\nprogressive Latin rock\nprogressive acoustic\nprogressive acoustic rock\nprogressive ambient\nprogressive bluegrass\nprogressive bluegrass gypsy jazz\nprogressive blues-rock\nprogressive classical\nprogressive corrido\nprogressive cumbia\nprogressive deep house\nprogressive electronic\nprogressive electronic big room\nprogressive electronic future bass\nprogressive electronic rock\nprogressive flamenco-rock\nprogressive folk\nprogressive folk ambient\nprogressive folk fusion\nprogressive folk rock\nprogressive folk world music\nprogressive folk, alt-rock\nprogressive folk, progressive metal\nprogressive folk-metal\nprogressive folk-rock\nprogressive funk\nprogressive funk rock\nprogressive funk-metal\nprogressive funk-rock\nprogressive fusion\nprogressive gospel rock\nprogressive guitar\nprogressive hard rock\nprogressive house\nprogressive house 90s\nprogressive house Afro-house\nprogressive house Afrobeat\nprogressive house Bollywood\nprogressive house C-pop\nprogressive house K-pop\nprogressive house K-pop hip-hop\nprogressive house Latin\nprogressive house R&B\nprogressive house ambient\nprogressive house ambient techno\nprogressive house ambient trance\nprogressive house big room\nprogressive house big room hardstyle\nprogressive house big room house\nprogressive house big room trance\nprogressive house chillwave\nprogressive house chiptune\nprogressive house chiptune trance\nprogressive house cinematic\nprogressive house classical fusion\nprogressive house dance-pop\nprogressive house dancehall\nprogressive house drum and bass\nprogressive house dubstep\nprogressive house electro\nprogressive house electro chiptune\nprogressive house electro house\nprogressive house electro-pop\nprogressive house ethnic\nprogressive house ethnic electronica\nprogressive house ethno-electronic\nprogressive house flamenco\nprogressive house future bass\nprogressive house gospel\nprogressive house hardstyle\nprogressive house hip-hop\nprogressive house indie rock\nprogressive house industrial metalcore\nprogressive house j-pop\nprogressive house k-pop\nprogressive house latin\nprogressive house latin house\nprogressive house latin pop\nprogressive house lo-fi\nprogressive house mandopop\nprogressive house melbourne bounce\nprogressive house melodic techno\nprogressive house nu-disco\nprogressive house post-rock\nprogressive house psytrance\nprogressive house reggaeton\nprogressive house rock\nprogressive house synth-pop\nprogressive house synthwave\nprogressive house tech house\nprogressive house tech-house\nprogressive house techno\nprogressive house techno synthwave\nprogressive house trance\nprogressive house trip-hop\nprogressive house tropical\nprogressive house tropical house\nprogressive house tropical pop\nprogressive house tropical trance\nprogressive house world fusion\nprogressive house world music\nprogressive house worldbeat\nprogressive house, Arabic pop\nprogressive house, Bollywood\nprogressive house, Bollywood EDM\nprogressive house, Bollywood, electronic\nprogressive house, C-pop\nprogressive house, Central Asian pop\nprogressive house, Christian EDM\nprogressive house, Christian EDM, hip-hop\nprogressive house, EDM\nprogressive house, EDM, C-pop\nprogressive house, EDM, South Asian pop\nprogressive house, EDM, cinematic\nprogressive house, EDM, pop\nprogressive house, EDM, rap\nprogressive house, Eastern European folk\nprogressive house, Latin house\nprogressive house, Latin pop\nprogressive house, Middle Eastern\nprogressive house, Middle Eastern fusion\nprogressive house, Middle Eastern, atmospheric\nprogressive house, Turkish pop\nprogressive house, big room EDM\nprogressive house, big room EDM, cinematic\nprogressive house, big room EDM, lo-fi\nprogressive house, big room house\nprogressive house, big room house, EDM\nprogressive house, big room house, R&B\nprogressive house, big room house, Russian rap\nprogressive house, big room house, ambient\nprogressive house, big room house, cinematic\nprogressive house, big room house, complextro\nprogressive house, big room house, hardstyle\nprogressive house, big room techno\nprogressive house, big room trance\nprogressive house, big room, Dutch house\nprogressive house, big room, EDM\nprogressive house, big room, ambient\nprogressive house, big room, cinematic\nprogressive house, big room, complextro\nprogressive house, big room, hardstyle\nprogressive house, big room, lo-fi\nprogressive house, big room, orchestral\nprogressive house, brostep\nprogressive house, cinematic, Chinese fusion\nprogressive house, complexro, dubstep\nprogressive house, complextro\nprogressive house, complextro, ambient\nprogressive house, complextro, cinematic\nprogressive house, complextro, dubstep\nprogressive house, complextro, hardstyle\nprogressive house, dance, electronic\nprogressive house, drum and bass\nprogressive house, drum and bass, liquid drum and bass\nprogressive house, drum and bass, neurofunk\nprogressive house, dubstep\nprogressive house, dubstep, cinematic\nprogressive house, electro house\nprogressive house, electro house, R&B\nprogressive house, electro house, hardstyle\nprogressive house, electro-industrial, alternative rock\nprogressive house, ethnic electronica\nprogressive house, ethnic electronica, world music\nprogressive house, ethno-electronic, darkwave\nprogressive house, future bass\nprogressive house, future bass, C-pop\nprogressive house, future bass, EDM\nprogressive house, future bass, ambient\nprogressive house, future bass, cinematic\nprogressive house, future bass, dream pop\nprogressive house, future bass, dubstep\nprogressive house, future bass, electro\nprogressive house, future bass, electro house\nprogressive house, future bass, electronic\nprogressive house, future bass, emotional EDM\nprogressive house, future bass, hardstyle\nprogressive house, future bass, lo-fi\nprogressive house, future bass, rap\nprogressive house, future bass, techno\nprogressive house, future bass, world music\nprogressive house, hard dance\nprogressive house, hardstyle\nprogressive house, hardstyle, C-pop\nprogressive house, hardstyle, EDM\nprogressive house, hardstyle, ambient\nprogressive house, hardstyle, big room\nprogressive house, hardstyle, cinematic\nprogressive house, hardstyle, dubstep\nprogressive house, hardstyle, electronic\nprogressive house, hardstyle, ethereal\nprogressive house, hardstyle, ethnic electronic\nprogressive house, hardstyle, hard trance\nprogressive house, hardstyle, pop ballad\nprogressive house, hardstyle, trance\nprogressive house, hardstyle, world music\nprogressive house, hyperpop\nprogressive house, industrial techno, ambient\nprogressive house, melodic techno\nprogressive house, melodic techno, acid techno\nprogressive house, psytrance, world music\nprogressive house, spiritual EDM, Middle Eastern\nprogressive house, synth-pop, electronic\nprogressive house, tech house\nprogressive house, techno\nprogressive house, techno, EBM\nprogressive house, techno, ambient\nprogressive house, trance\nprogressive house, trance, EDM\nprogressive house, trance, J-pop\nprogressive house, trance, Middle Eastern\nprogressive house, trance, Middle Eastern EDM\nprogressive house, trance, North African pop\nprogressive house, trance, South Indian\nprogressive house, trance, Turkish electronic\nprogressive house, trance, big room\nprogressive house, trance, drum and bass\nprogressive house, trance, electronic\nprogressive house, trance, hardstyle\nprogressive house, trance, neurofunk\nprogressive house, trance, world music\nprogressive house, world electronica, synthwave\nprogressive instrumental\nprogressive jazz\nprogressive jazz fusion\nprogressive jazz-fusion\nprogressive jazz-rock\nprogressive jazz-rock fusion\nprogressive metal\nprogressive metal alternative rock\nprogressive metal ambient\nprogressive metal anison\nprogressive metal chiptune\nprogressive metal chiptune J-rock\nprogressive metal chiptune classical\nprogressive metal chiptune j-rock\nprogressive metal chiptune mathcore\nprogressive metal chiptune synth rock\nprogressive metal chiptune synth-rock\nprogressive metal classical\nprogressive metal classical piano\nprogressive metal djent\nprogressive metal djent mathcore\nprogressive metal electronicore\nprogressive metal flamenco\nprogressive metal flamenco fusion\nprogressive metal folk-metal\nprogressive metal funk\nprogressive metal funk chiptune\nprogressive metal funk jazz fusion\nprogressive metal funk math rock\nprogressive metal funk metal\nprogressive metal funk metal math rock\nprogressive metal funk rock\nprogressive metal funk rock psychedelic blues\nprogressive metal funk-rock\nprogressive metal jazz fusion\nprogressive metal jazz fusion chiptune\nprogressive metal jazz video game\nprogressive metal jazz-fusion electronic\nprogressive metal jazz-rock\nprogressive metal math rock\nprogressive metal math rock jazz fusion\nprogressive metal mathcore\nprogressive metal mathcore chiptune\nprogressive metal symphonic metal\nprogressive metal theatrical rock\nprogressive metal trance\nprogressive metal world fusion\nprogressive metal world music\nprogressive metal, Balkan folk\nprogressive metal, Balkan folk, klezmer\nprogressive metal, C-pop\nprogressive metal, C-pop, ancient style\nprogressive metal, Chinese folk\nprogressive metal, Chinese fusion\nprogressive metal, Chinese opera\nprogressive metal, East Asian folk\nprogressive metal, East Asian fusion\nprogressive metal, Indian classical\nprogressive metal, Indian classical, electronic\nprogressive metal, Indian folk\nprogressive metal, J-rock\nprogressive metal, J-rock, power metal\nprogressive metal, J-rock, symphonic\nprogressive metal, J-rock, video game music\nprogressive metal, Japanese rock\nprogressive metal, Japanese rock, chiptune\nprogressive metal, Japanese rock, video game music\nprogressive metal, Latin jazz fusion, metal fusion\nprogressive metal, Latin rock\nprogressive metal, Middle Eastern folk\nprogressive metal, Middle Eastern pop-rock\nprogressive metal, Middle Eastern, Turkish\nprogressive metal, Nintendocore\nprogressive metal, Persian classical, cinematic\nprogressive metal, Tamil rock\nprogressive metal, ancient style, cinematic\nprogressive metal, big band jazz\nprogressive metal, chiptune\nprogressive metal, chiptune, Baroque\nprogressive metal, chiptune, Japanese rock\nprogressive metal, chiptune, classical\nprogressive metal, chiptune, melodic rock\nprogressive metal, cinematic C-pop, ambient\nprogressive metal, cinematic, art rock\nprogressive metal, cinematic, ney flute\nprogressive metal, electronic\nprogressive metal, electronicore\nprogressive metal, hard rock, folk-metal\nprogressive metal, jazz fusion, chiptune\nprogressive metal, jazz fusion, video game music\nprogressive metal, jazz-funk, ambient\nprogressive metal, jazz-fusion, cinematic\nprogressive metal, math rock, chiptune\nprogressive metal, math rock, jazz fusion\nprogressive metal, math rock, video game music\nprogressive metal, metalcore\nprogressive metal, power metal, Javanese pop-rock\nprogressive metal, power metal, chiptune\nprogressive metal, shred guitar, chiptune\nprogressive metal, shred guitar, video game music\nprogressive metal, symphonic J-rock\nprogressive metal, synth-rock, chiptune\nprogressive metal, video game boss music\nprogressive metal, video game music\nprogressive metal, video game music, J-rock\nprogressive metal, video game music, Nintendocore\nprogressive metalcore\nprogressive metalcore chiptune\nprogressive metalcore chiptune electronic rock\nprogressive metalcore chiptune math rock\nprogressive metalcore electronicore\nprogressive metalcore j-rock\nprogressive metalcore jazz-funk\nprogressive metalcore, J-rock\nprogressive metalcore, J-rock, power metal\nprogressive metalcore, Nintendocore\nprogressive metalcore, chiptune, electronic rock\nprogressive norteño\nprogressive pop\nprogressive pop-rock\nprogressive power metal\nprogressive power metal chiptune\nprogressive psytrance\nprogressive punk\nprogressive rock\nprogressive rock Indian folk\nprogressive rock baroque\nprogressive rock chiptune\nprogressive rock cinematic\nprogressive rock country\nprogressive rock djent\nprogressive rock electronic\nprogressive rock flamenco\nprogressive rock funk\nprogressive rock funk Latin jazz\nprogressive rock funk big band\nprogressive rock funk fusion\nprogressive rock funk jazz fusion\nprogressive rock funk latin\nprogressive rock funk math rock\nprogressive rock funk metal\nprogressive rock funk psychedelic\nprogressive rock funk rock\nprogressive rock funk rock melodic instrumental rock\nprogressive rock funk-metal\nprogressive rock fusion\nprogressive rock glam metal\nprogressive rock gospel\nprogressive rock jazz fusion\nprogressive rock jazz fusion anime\nprogressive rock jazz fusion chiptune\nprogressive rock jazz fusion cinematic\nprogressive rock jazz fusion electronic\nprogressive rock jazz fusion funk\nprogressive rock jazz fusion video game music\nprogressive rock jazz-funk\nprogressive rock jazz-fusion\nprogressive rock jazz-rock\nprogressive rock math rock\nprogressive rock math rock J-rock\nprogressive rock nu-metal\nprogressive rock opera\nprogressive rock orchestral\nprogressive rock power metal\nprogressive rock smooth jazz\nprogressive rock symphonic metal video game music\nprogressive rock tango\nprogressive rock world fusion\nprogressive rock world music\nprogressive rock, Anatolian folk\nprogressive rock, Anatolian folk, classical fusion\nprogressive rock, Anatolian rock\nprogressive rock, Arabic fusion\nprogressive rock, Azerbaijani folk\nprogressive rock, Balkan folk\nprogressive rock, C-pop, cinematic\nprogressive rock, Carnatic fusion\nprogressive rock, Celtic, video game music\nprogressive rock, Chinese fusion\nprogressive rock, Chinese fusion, cinematic\nprogressive rock, Chinese opera, cinematic\nprogressive rock, Chinese traditional, cinematic\nprogressive rock, East Asian fusion\nprogressive rock, Indian classical\nprogressive rock, Indian classical fusion\nprogressive rock, Indian classical, cinematic\nprogressive rock, Indian classical, fusion\nprogressive rock, Indian classical, video game music\nprogressive rock, Indian classical, world fusion\nprogressive rock, Indian folk\nprogressive rock, Indian folk, cinematic\nprogressive rock, Italian pop\nprogressive rock, J-rock\nprogressive rock, J-rock, math rock\nprogressive rock, J-rock, power metal\nprogressive rock, J-rock, video game music\nprogressive rock, J-rock, world fusion\nprogressive rock, JRPG, video game music\nprogressive rock, Latin ballad\nprogressive rock, Latin folk, ambient\nprogressive rock, Latin jazz\nprogressive rock, Latin jazz fusion\nprogressive rock, Latin rock\nprogressive rock, Malay traditional\nprogressive rock, Middle Eastern folk\nprogressive rock, Middle Eastern fusion\nprogressive rock, Middle Eastern, Arabic\nprogressive rock, Middle Eastern, Balkan\nprogressive rock, Middle Eastern, theatrical rock\nprogressive rock, South Asian folk\nprogressive rock, Sundanese fusion\nprogressive rock, Telugu folk\nprogressive rock, Turkish folk\nprogressive rock, Turkish folk-rock, blues-rock\nprogressive rock, Turkish fusion\nprogressive rock, ambient, Indian fusion\nprogressive rock, arabesque, Turkish folk\nprogressive rock, chiptune, Javanese fusion\nprogressive rock, cinematic ballad, Turkish spoken word\nprogressive rock, cinematic, Chinese traditional\nprogressive rock, cinematic, J-rock\nprogressive rock, cinematic, Malay traditional\nprogressive rock, cinematic, video game soundtrack\nprogressive rock, cinematic, world fusion\nprogressive rock, classical crossover, musical theater\nprogressive rock, classical fantasy, Japanese RPG\nprogressive rock, classical piano, Japanese RPG\nprogressive rock, classical, video game music\nprogressive rock, electronic, cinematic\nprogressive rock, fusion, electronic\nprogressive rock, gospel, Celtic folk\nprogressive rock, heavy metal\nprogressive rock, jazz fusion, video game music\nprogressive rock, math rock, jazz fusion\nprogressive rock, math rock, progressive metal\nprogressive rock, neo-classical, psychedelic rock\nprogressive rock, new age\nprogressive rock, power metal, cinematic\nprogressive rock, progressive metal\nprogressive rock, progressive metal, Middle Eastern\nprogressive rock, progressive metal, cinematic\nprogressive rock, psychedelic folk-rock\nprogressive rock, psychedelic rock, Latin rock\nprogressive rock, schlager, classical pop\nprogressive rock, symphonic metal\nprogressive rock, symphonic metal, cinematic\nprogressive rock, symphonic metal, classical rock\nprogressive rock, symphonic rock, video game music\nprogressive rock, synth-pop\nprogressive rock, thrash metal, Bengali rock\nprogressive rock, video game music\nprogressive rock, video game music, Chinese traditional\nprogressive rock, video game music, East Asian fusion\nprogressive rock, world fusion\nprogressive rock, world fusion, electronic\nprogressive rock, world fusion, percussive rock\nprogressive rock, world fusion, symphonic metal\nprogressive rock, world music, Indonesian rock\nprogressive rock, world music, Persian fusion\nprogressive rock, world music, video game music\nprogressive salsa\nprogressive soul\nprogressive surf rock\nprogressive synth\nprogressive tech\nprogressive tech-house\nprogressive techno\nprogressive thrash metal\nprogressive trance\nprogressive trance C-pop\nprogressive trance acid house\nprogressive trance ambient\nprogressive trance big room\nprogressive trance chiptune\nprogressive trance cinematic rock\nprogressive trance complextro\nprogressive trance drum and bass\nprogressive trance electro house\nprogressive trance eurodance\nprogressive trance future bass\nprogressive trance industrial rock\nprogressive trance j-pop\nprogressive trance metal\nprogressive trance metalcore\nprogressive trance psytrance\nprogressive trance rock\nprogressive trance synthwave\nprogressive trance techno\nprogressive trance, Indian devotional\nprogressive trance, South Asian pop\nprogressive trance, big room house\nprogressive trance, big room house, hardstyle\nprogressive trance, brostep\nprogressive trance, dubstep\nprogressive trance, electro-industrial\nprogressive trance, ethereal wave\nprogressive trance, ethnic electronica\nprogressive trance, eurodance\nprogressive trance, hard trance\nprogressive trance, hardstyle\nprogressive trance, hardstyle, ambient\nprogressive trance, hardstyle, cinematic electronic\nprogressive trance, hardstyle, drum and bass\nprogressive trance, indie rock, big room house\nprogressive trance, neurofunk, ambient\nprogressive trance, psytrance\nprogressive trance, punk rock\nprogressive trance, synth-funk, video game music\nprogressive trance, synth-pop, Bollywood\nprogressive trance, synthwave\nprogressive trance, synthwave, J-RPG\nprogressive trance, synthwave, Persian vocal\nprogressive trance, synthwave, UK hip-hop\nprogressive trance, techstep\nprogressive world fusion\nprogressive world music\npropaganda march\npropaganda music\npropaganda pop\nprotest anthem\nprotest anthem flamenco\nprotest cumbia\nprotest electronic\nprotest folk\nprotest folk-rock\nprotest hip hop\nprotest hip-hop\nprotest march\nprotest music\nprotest music cumbia\nprotest music cumbia-ska\nprotest music flamenco\nprotest pop\nprotest rap\nprotest rap, cinematic hip-hop\nprotest rap, electronic\nprotest rock\nprotest rock cabaret\nprotest rock nu-metal\nprotest song\nprotest song cabaret\nprotest song chiptune\nprotest song flamenco\nprotest song polka\nprotest song ragtime\nprotest song, boogie-woogie, choral\nprotest soul\nproto-punk\npsybient\npsych rock\npsychedelic\npsychedelic Afrobeat\npsychedelic Americana\npsychedelic Anatolian rock\npsychedelic Arabic electronic\npsychedelic Arabic fusion\npsychedelic Arabic pop\npsychedelic Bollywood\npsychedelic C-pop\npsychedelic French pop\npsychedelic G-funk\npsychedelic Greek rock\npsychedelic Indian fusion\npsychedelic Latin\npsychedelic Latin R&B\npsychedelic Latin alternative\npsychedelic Latin ballad\npsychedelic Latin electronic\npsychedelic Latin folk\npsychedelic Latin folk-rock\npsychedelic Latin funk\npsychedelic Latin funk-rock\npsychedelic Latin fusion\npsychedelic Latin hip-hop\npsychedelic Latin pop\npsychedelic Latin rock\npsychedelic Latin trap\npsychedelic Latin-folk\npsychedelic Latin-rock\npsychedelic Latin-rock, big band jazz\npsychedelic MPB\npsychedelic Middle Eastern fusion\npsychedelic North African\npsychedelic R&B\npsychedelic R&B reggaeton\npsychedelic R&B trap\npsychedelic R&B, cloud rap\npsychedelic South Asian film score\npsychedelic V-Pop\npsychedelic afro rock\npsychedelic alt-rock\npsychedelic alternative\npsychedelic alternative rock\npsychedelic ambient\npsychedelic arabic fusion\npsychedelic art-pop\npsychedelic art-rock\npsychedelic bachata\npsychedelic ballad\npsychedelic ballad, synth-pop, cinematic\npsychedelic baroque pop\npsychedelic big band\npsychedelic bluegrass\npsychedelic blues\npsychedelic blues rock\npsychedelic blues soul\npsychedelic blues-rock\npsychedelic blues-rock funk-rock\npsychedelic blues-rock, Japanese punk\npsychedelic boom bap\npsychedelic boom-bap\npsychedelic bossa nova\npsychedelic breakbeat\npsychedelic cabaret\npsychedelic chanson\npsychedelic choral\npsychedelic cinematic\npsychedelic country\npsychedelic country rock\npsychedelic country-rock\npsychedelic cumbia\npsychedelic cumbia funk\npsychedelic cumbia garage rock\npsychedelic cumbia rock\npsychedelic cumbia surf rock\npsychedelic cumbia-pop\npsychedelic cumbia-reggae\npsychedelic cumbia-rock\npsychedelic dancehall\npsychedelic deep house\npsychedelic desert rock\npsychedelic desert rock funk-rock\npsychedelic devotional\npsychedelic disco\npsychedelic disco-funk\npsychedelic dream pop\npsychedelic dream-pop\npsychedelic drill\npsychedelic dub\npsychedelic dub rock\npsychedelic dub-funk\npsychedelic dub-pop\npsychedelic dub-reggae\npsychedelic dub-rock\npsychedelic electronic\npsychedelic electronica\npsychedelic emo-rap\npsychedelic exotica\npsychedelic experimental\npsychedelic film score\npsychedelic flamenco\npsychedelic folk\npsychedelic folk alternative rock\npsychedelic folk ambient\npsychedelic folk garage rock\npsychedelic folk indie rock\npsychedelic folk noise rock\npsychedelic folk progressive rock\npsychedelic folk rock\npsychedelic folk worldbeat\npsychedelic folk, Brazilian MPB\npsychedelic folk, Latin folk\npsychedelic folk, Latin rock\npsychedelic folk, hard rock\npsychedelic folk, noise rock, indie rock\npsychedelic folk, polka, ska\npsychedelic folk-pop\npsychedelic folk-rock\npsychedelic folk-rock garage rock\npsychedelic folk-rock glam rock\npsychedelic folk-rock, hard rock\npsychedelic folk-rock, heavy metal\npsychedelic folk-rock, industrial trip-hop\npsychedelic folk-tronica\npsychedelic frevo\npsychedelic funk\npsychedelic funk African pop\npsychedelic funk Latin rock\npsychedelic funk MPB\npsychedelic funk blues rock\npsychedelic funk experimental hip-hop\npsychedelic funk fusion\npsychedelic funk garage rock\npsychedelic funk hip-hop\npsychedelic funk neo-soul\npsychedelic funk progressive rock\npsychedelic funk punk rock\npsychedelic funk rap\npsychedelic funk reggae\npsychedelic funk rock\npsychedelic funk soul\npsychedelic funk soul-jazz\npsychedelic funk trip-hop\npsychedelic funk world music\npsychedelic funk worldbeat\npsychedelic funk, Arabic rock\npsychedelic funk, Bollywood, upbeat\npsychedelic funk, Brazilian folk\npsychedelic funk, Italian pop, operatic\npsychedelic funk, Italo-disco\npsychedelic funk, Latin jazz\npsychedelic funk, Latin jazz fusion\npsychedelic funk, MPB\npsychedelic funk, Middle Eastern fusion\npsychedelic funk, cumbia\npsychedelic funk, experimental pop, Balkan brass\npsychedelic funk, soul-jazz, Latin fusion\npsychedelic funk-hop\npsychedelic funk-house\npsychedelic funk-jazz\npsychedelic funk-pop\npsychedelic funk-rap\npsychedelic funk-reggae\npsychedelic funk-rock\npsychedelic funk-rock Afro-Cuban\npsychedelic funk-rock Arabic\npsychedelic funk-rock cumbia\npsychedelic funk-rock skate punk\npsychedelic funk-rock, Latin rock\npsychedelic fusion\npsychedelic garage rock\npsychedelic gospel\npsychedelic gospel-funk\npsychedelic groove\npsychedelic grunge\npsychedelic guitar\npsychedelic hard rock\npsychedelic hip hop\npsychedelic hip-hop\npsychedelic hip-hop cloud rap\npsychedelic hip-hop funk\npsychedelic hip-hop jazz-funk\npsychedelic hip-hop lo-fi\npsychedelic hip-hop neo-soul\npsychedelic hip-hop, downtempo R&B\npsychedelic hip-hop, neo-soul, jazz-hop\npsychedelic house\npsychedelic indie dance\npsychedelic indie electronic\npsychedelic indie folk\npsychedelic indie pop\npsychedelic indie rock\npsychedelic indie rock, Latin rock\npsychedelic indie rock, lo-fi hip-hop\npsychedelic indie rock, neo-soul\npsychedelic indie-pop\npsychedelic industrial\npsychedelic industrial rock\npsychedelic instrumental\npsychedelic jazz\npsychedelic jazz funk rock\npsychedelic jazz hip-hop\npsychedelic jazz-funk\npsychedelic jazz-pop\npsychedelic jazz-rock\npsychedelic jazz-rock funk-rock\npsychedelic jungle\npsychedelic lo-fi\npsychedelic lo-fi boom-bap\npsychedelic lo-fi hip hop\npsychedelic lo-fi hip-hop\npsychedelic lo-fi punk\npsychedelic lounge\npsychedelic lounge jazz\npsychedelic lounge pop\npsychedelic lounge, free jazz, punk rock\npsychedelic lounge-pop\npsychedelic lullaby\npsychedelic metal\npsychedelic neo-soul\npsychedelic neo-soul funk\npsychedelic neo-soul metalcore\npsychedelic new wave\npsychedelic noise rock\npsychedelic nu-disco\npsychedelic oud\npsychedelic oud funk\npsychedelic pop\npsychedelic pop Indian film\npsychedelic pop Latin\npsychedelic pop Latin ballad\npsychedelic pop UK drill\npsychedelic pop bossa nova\npsychedelic pop exotica\npsychedelic pop exotica lounge\npsychedelic pop funk lounge\npsychedelic pop funk-rock\npsychedelic pop garage rock\npsychedelic pop latin\npsychedelic pop lo-fi\npsychedelic pop lounge exotica\npsychedelic pop lounge-jazz\npsychedelic pop neo-soul\npsychedelic pop noise rock\npsychedelic pop progressive rock\npsychedelic pop rock\npsychedelic pop surf rock\npsychedelic pop world music\npsychedelic pop world-pop lounge\npsychedelic pop worldbeat\npsychedelic pop, Brazilian MPB\npsychedelic pop, Latin pop-rock\npsychedelic pop, MPB\npsychedelic pop, MPB, lounge\npsychedelic pop, folk-rock, polka-rock\npsychedelic pop, vintage Indonesian pop\npsychedelic pop, world music, Vietnamese folk\npsychedelic pop-funk\npsychedelic pop-punk\npsychedelic pop-rock\npsychedelic pop-rock, funky pop-rock\npsychedelic post-punk\npsychedelic post-rock\npsychedelic punk\npsychedelic punk rock\npsychedelic raga\npsychedelic reggae\npsychedelic reggae funk\npsychedelic reggae-dub\npsychedelic reggae-rock\npsychedelic reggaeton\npsychedelic regional Mexican\npsychedelic ritual\npsychedelic rock\npsychedelic rock Afrobeat\npsychedelic rock Anatolian rock\npsychedelic rock Arabic folk\npsychedelic rock Arabic fusion\npsychedelic rock C-pop\npsychedelic rock Indian classical\npsychedelic rock Indian folk\npsychedelic rock Indian fusion\npsychedelic rock Latin\npsychedelic rock Latin rock\npsychedelic rock alternative\npsychedelic rock alternative rock\npsychedelic rock ambient\npsychedelic rock arena rock\npsychedelic rock art-punk\npsychedelic rock avant-garde folk\npsychedelic rock baroque pop\npsychedelic rock bluegrass\npsychedelic rock blues\npsychedelic rock blues rock\npsychedelic rock blues-rock\npsychedelic rock boogie-woogie\npsychedelic rock chanson\npsychedelic rock chiptune\npsychedelic rock classic rock\npsychedelic rock country\npsychedelic rock country-rock\npsychedelic rock cumbia\npsychedelic rock cumbia rock\npsychedelic rock desert rock\npsychedelic rock dream pop\npsychedelic rock exotica\npsychedelic rock flamenco\npsychedelic rock folk-rock\npsychedelic rock funk\npsychedelic rock funk Latin jazz\npsychedelic rock funk jazz fusion\npsychedelic rock funk rock\npsychedelic rock funk soul\npsychedelic rock funk surf rock\npsychedelic rock funk-rock\npsychedelic rock funk-rock MPB\npsychedelic rock funk-rock surf rock\npsychedelic rock garage punk\npsychedelic rock garage rock\npsychedelic rock glam\npsychedelic rock gospel\npsychedelic rock grunge\npsychedelic rock hard rock\npsychedelic rock hip-hop\npsychedelic rock indie pop\npsychedelic rock indie rock\npsychedelic rock jazz fusion\npsychedelic rock jazz-fusion\npsychedelic rock latin\npsychedelic rock latin groove\npsychedelic rock latin jazz\npsychedelic rock latin percussion\npsychedelic rock latin rock\npsychedelic rock lo-fi\npsychedelic rock lo-fi hip hop\npsychedelic rock lounge\npsychedelic rock lounge exotica\npsychedelic rock metal\npsychedelic rock metalcore\npsychedelic rock neo-soul\npsychedelic rock noise rock\npsychedelic rock orchestral\npsychedelic rock pop-rock\npsychedelic rock post-hardcore\npsychedelic rock post-punk\npsychedelic rock post-rock\npsychedelic rock power ballad\npsychedelic rock progressive metal\npsychedelic rock progressive rock\npsychedelic rock punk\npsychedelic rock punk rock\npsychedelic rock reggae\npsychedelic rock reggae dub\npsychedelic rock reggae latin\npsychedelic rock reggae soul\npsychedelic rock reggae-rock\npsychedelic rock shoegaze\npsychedelic rock ska-punk\npsychedelic rock soul\npsychedelic rock southern rock\npsychedelic rock spaghetti western\npsychedelic rock stoner rock\npsychedelic rock surf rock\npsychedelic rock thrash metal\npsychedelic rock trap\npsychedelic rock trip-hop\npsychedelic rock world fusion\npsychedelic rock world music\npsychedelic rock zouk\npsychedelic rock, Arabic hip hop, tribal house\npsychedelic rock, Balkan folk\npsychedelic rock, Bollywood, fusion\npsychedelic rock, Brazilian rock, analog\npsychedelic rock, Greek folk\npsychedelic rock, Indian classical\npsychedelic rock, Indian devotional\npsychedelic rock, Indian folk\npsychedelic rock, Indonesian pop\npsychedelic rock, Indonesian traditional\npsychedelic rock, Italian art-pop\npsychedelic rock, Italian pop-rock\npsychedelic rock, J-rock, shoegaze\npsychedelic rock, Japanese folk\npsychedelic rock, Javanese traditional\npsychedelic rock, Javanese, fusion\npsychedelic rock, Latin groove, Nepali film music\npsychedelic rock, Latin jazz, ambient\npsychedelic rock, Latin pop-rock, worship\npsychedelic rock, Latin rock\npsychedelic rock, Latin rock, Norteño\npsychedelic rock, MPB\npsychedelic rock, MPB, world music\npsychedelic rock, Malay traditional\npsychedelic rock, Middle Eastern folk\npsychedelic rock, Middle Eastern fusion\npsychedelic rock, Middle Eastern, Arabic rock\npsychedelic rock, Middle Eastern, cinematic\npsychedelic rock, Middle Eastern, theatrical\npsychedelic rock, South Asian folk\npsychedelic rock, Turkish folk\npsychedelic rock, UK drill\npsychedelic rock, alternative rock\npsychedelic rock, big band jazz fusion\npsychedelic rock, boom-bap hip-hop, nu-metal\npsychedelic rock, city pop\npsychedelic rock, dangdut\npsychedelic rock, electro-rock\npsychedelic rock, experimental hip-hop\npsychedelic rock, folk fusion\npsychedelic rock, folk, Turkish folk\npsychedelic rock, folk-pop\npsychedelic rock, funk pop, hip-hop\npsychedelic rock, hard rock\npsychedelic rock, heavy metal\npsychedelic rock, hip hop\npsychedelic rock, lo-fi hip hop\npsychedelic rock, metal\npsychedelic rock, neo-soul, city pop\npsychedelic rock, neo-soul, smooth jazz\npsychedelic rock, new wave rock\npsychedelic rock, nu-metal, metalcore\npsychedelic rock, pop rock, Indonesian pop\npsychedelic rock, post-punk\npsychedelic rock, progressive house, big room\npsychedelic rock, progressive house, deep house\npsychedelic rock, progressive rock, operatic rock\npsychedelic rock, psychedelic metal, Middle Eastern\npsychedelic rock, shoegaze, noise rock\npsychedelic rock, soft rock\npsychedelic rock, soft rock, arena rock\npsychedelic rock, synth-pop, heavy metal\npsychedelic rock, thrash metal\npsychedelic rock, traditional Indonesian\npsychedelic roots-rock\npsychedelic salsa\npsychedelic samba\npsychedelic samba-rock\npsychedelic shoegaze\npsychedelic soft rock\npsychedelic soul\npsychedelic soul disco\npsychedelic soul funk\npsychedelic soul funk-rock\npsychedelic soul neo-soul\npsychedelic soul world fusion\npsychedelic soul, Greek art-pop\npsychedelic soul, boom-bap hip-hop\npsychedelic soul-rock\npsychedelic southern rock\npsychedelic surf rock\npsychedelic surf-rock\npsychedelic surf-rock, hard rock\npsychedelic swing\npsychedelic synth\npsychedelic synth-funk\npsychedelic synth-pop\npsychedelic synthwave\npsychedelic tango-rock\npsychedelic techno\npsychedelic thrash metal\npsychedelic trance\npsychedelic trap\npsychedelic trap R&B\npsychedelic trap nu-metal\npsychedelic trap, Indian hip-hop\npsychedelic trap, cloud rap\npsychedelic trap-R&B\npsychedelic tribal\npsychedelic trip-hop\npsychedelic trot\npsychedelic wave\npsychedelic western rock\npsychedelic world\npsychedelic world funk\npsychedelic world fusion\npsychedelic world music\npsychedelic world-pop\npsychedelic worldbeat\npsychedelic, Latin, ambient\npsychedelic, trance, Arabic spoken word\npsytrance\npsytrance Indian fusion\npsytrance acid house\npsytrance ambient\npsytrance ancient style\npsytrance arabesque\npsytrance bhajan\npsytrance big room house\npsytrance big room indian bhajan\npsytrance cinematic\npsytrance cyberpunk\npsytrance darkwave\npsytrance devotional\npsytrance drum and bass\npsytrance drum and bass experimental\npsytrance drum and bass world fusion\npsytrance ethnic electronica\npsytrance fusion\npsytrance hard techno\npsytrance hard trance\npsytrance hardstyle\npsytrance hardstyle cinematic\npsytrance house bollywood\npsytrance indian devotional\npsytrance indian fusion\npsytrance industrial\npsytrance industrial techno\npsytrance lo-fi\npsytrance new-age\npsytrance oud\npsytrance progressive house\npsytrance progressive trance\npsytrance rock\npsytrance techno\npsytrance trap\npsytrance tribal\npsytrance tribal house\npsytrance vaporwave\npsytrance world fusion\npsytrance world music\npsytrance worldbeat\npsytrance, Arabic fusion, reggaeton\npsytrance, Celtic ambient\npsytrance, Hindi rap, ambient\npsytrance, Indian classical, electronic\npsytrance, Indian classical, electronic fusion\npsytrance, Indian devotional\npsytrance, Indian devotional, electronic\npsytrance, Indian devotional, electronic dance\npsytrance, Indian fusion\npsytrance, Indian fusion, electronic\npsytrance, Indian pop, electronic dance\npsytrance, Middle Eastern fusion\npsytrance, Middle Eastern fusion, dance-pop\npsytrance, Middle Eastern fusion, electronic\npsytrance, Middle Eastern fusion, electronic dance\npsytrance, Middle Eastern trance\npsytrance, Middle Eastern, cinematic\npsytrance, Slavic folk\npsytrance, ambient, Chinese traditional\npsytrance, ambient, Italian vocal\npsytrance, ambient, Middle Eastern\npsytrance, ambient, ancient style\npsytrance, ambient, experimental\npsytrance, ambient, hardcore techno\npsytrance, ambient, new-age\npsytrance, ambient, spiritual\npsytrance, big room house, Indian devotional\npsytrance, big room house, Middle Eastern fusion\npsytrance, big room house, cinematic\npsytrance, big room house, devotional\npsytrance, big room, Indian devotional\npsytrance, breakbeat, Middle Eastern electronic\npsytrance, cinematic ambient\npsytrance, cinematic, Middle Eastern fusion\npsytrance, cinematic, ambient\npsytrance, cinematic, dubstep\npsytrance, cinematic, electronic\npsytrance, cinematic, glitch\npsytrance, cinematic, hardstyle\npsytrance, devotional electronic\npsytrance, devotional, Indian electronic\npsytrance, devotional, electronic\npsytrance, electronic, Indian devotional\npsytrance, electronic, Middle Eastern\npsytrance, electronic, Middle Eastern fusion\npsytrance, electronic, South Asian fusion\npsytrance, ethnic electronica\npsytrance, hard dance, Middle Eastern electronic\npsytrance, hard dance, ancient style\npsytrance, hard techno, Arabic electronic\npsytrance, hard trance\npsytrance, hard trance, Turkish folk\npsytrance, hard trance, ambient\npsytrance, hard trance, cinematic\npsytrance, hardstyle\npsytrance, hardstyle, Indian devotional\npsytrance, hardstyle, Indian folk\npsytrance, hardstyle, Indian fusion\npsytrance, hardstyle, Korean traditional\npsytrance, hardstyle, Middle Eastern\npsytrance, hardstyle, Slavic folk\npsytrance, hardstyle, Tamil folk\npsytrance, hardstyle, ambient\npsytrance, hardstyle, bhajan\npsytrance, hardstyle, cinematic\npsytrance, hardstyle, devotional\npsytrance, hardstyle, electronic\npsytrance, hardstyle, ethnic fusion\npsytrance, hardstyle, folk rock\npsytrance, hardstyle, gabber\npsytrance, hardstyle, glitch-hop\npsytrance, hardstyle, spiritual\npsytrance, hardstyle, spiritual electronic\npsytrance, hardstyle, trance\npsytrance, oud, cinematic\npsytrance, progressive house, Arabic fusion\npsytrance, speedcore, gabber\npsytrance, spiritual trance, Arabic fusion\npsytrance, techno\npsytrance, trance, techno\npsytrance, world fusion\npsytrance, world fusion, cinematic\npsytrance, world fusion, drum and bass\npsytrance, world fusion, rock\npub folk\npub punk\npub rock\npub rock blues country\npub rock blues rock\npub rock boogie-woogie\npub rock country boogie-woogie\npub rock country folk-rock\npub rock country-rock\npub rock country-swing\npub rock folk country\npub rock folk-punk\npub rock folk-rock\npub rock garage rock\npub rock glam rock\npub rock heartland rock\npub rock rockabilly\npub rock rockabilly swing\npub rock sea shanty\npub rock, Australian novelty, festive rock\npub rock, Australian punk\npub rock, Balkan rock\npub rock, British folk\npub rock, Celtic punk\npub rock, Celtic rock, folk-punk\npub rock, Irish folk\npub rock, Nederpop, rock 'n' roll\npub rock, accordion, waltz\npub rock, boogie-woogie, blues-rock\npub rock, boogie-woogie, rock\npub rock, boogie-woogie, rock and roll\npub rock, country rock, blues rock\npub rock, country rock, rockabilly\npub rock, country, polka\npub rock, country-blues\npub rock, country-rock\npub rock, music hall\npub rock, music hall, theatrical\npub rock, new wave\npub rock, polka, retro\npub rock, rockabilly\npub rock, rockabilly, boogie-woogie\npub rock, sea shanty, novelty\npub rock, show tune\npub rock, soul revue, rock and roll\npub rock, southern rock\npub-folk\npub-punk\npublic announcement\npublic service announcement\npunk\npunk blues\npunk cabaret\npunk chiptune\npunk cumbia\npunk dub\npunk electronic\npunk folk\npunk folk rock\npunk forró\npunk funk\npunk hip hop\npunk hip-hop\npunk house\npunk jazz\npunk metal\npunk poetry\npunk polka\npunk rap\npunk rap, chiptune, lo-fi\npunk reggae\npunk reggaeton\npunk rock\npunk rock alternative hip-hop\npunk rock alternative metal\npunk rock alternative rock\npunk rock big band\npunk rock bluegrass fusion\npunk rock blues rock\npunk rock blues-rock\npunk rock boogie-woogie\npunk rock cabaret\npunk rock chiptune\npunk rock crossover thrash\npunk rock cumbia\npunk rock cumbia Latin\npunk rock cumbia villera\npunk rock dangdut koplo\npunk rock desert rock\npunk rock drum and bass\npunk rock electronic\npunk rock emo\npunk rock flamenco\npunk rock flamenco fusion\npunk rock folk\npunk rock folk fusion\npunk rock folk metal\npunk rock folk punk\npunk rock folk-punk\npunk rock funk\npunk rock funk crossover\npunk rock funk metal\npunk rock funk rock\npunk rock funk ska\npunk rock funk-rock\npunk rock garage rock\npunk rock glam rock\npunk rock gypsy folk\npunk rock gypsy jazz\npunk rock gypsy punk\npunk rock hardcore\npunk rock hardcore punk\npunk rock hip-hop\npunk rock hip-hop electronic\npunk rock hyperpop\npunk rock indie rock\npunk rock lo-fi\npunk rock metal\npunk rock metalcore\npunk rock new wave\npunk rock new wave polka\npunk rock nintendocore\npunk rock norteño\npunk rock nu-metal\npunk rock polka\npunk rock power metal\npunk rock psychedelic rock\npunk rock pub rock\npunk rock rap metal\npunk rock rap rock\npunk rock rap-metal\npunk rock rap-rock\npunk rock rapcore\npunk rock reggae\npunk rock reggae fusion\npunk rock reggae ska\npunk rock reggaeton\npunk rock rockabilly\npunk rock salsa\npunk rock samba\npunk rock samba-rock\npunk rock sea shanty\npunk rock ska\npunk rock ska big band\npunk rock ska cabaret\npunk rock ska free-jazz\npunk rock ska funk\npunk rock ska-punk\npunk rock skate punk\npunk rock southern rock\npunk rock speed metal\npunk rock surf rock\npunk rock synth-pop\npunk rock tango\npunk rock techno\npunk rock thrash metal\npunk rock trap\npunk rock trap metal\npunk rock turbo-folk\npunk rock world music\npunk rock, 8-bit chiptune\npunk rock, Arabic folk\npunk rock, Balkan brass\npunk rock, Balkan brass, flamenco\npunk rock, Balkan folk\npunk rock, Balkan folk, folk-punk\npunk rock, Balkan, polka\npunk rock, Basque folk\npunk rock, Brazilian funk\npunk rock, Brazilian funk carioca\npunk rock, C-pop, experimental\npunk rock, Celtic folk\npunk rock, Chinese folk, blues\npunk rock, Chinese folk, experimental\npunk rock, Chinese fusion\npunk rock, Chinese traditional\npunk rock, Christian rock\npunk rock, Eastern European folk\npunk rock, German folk\npunk rock, German folk, ska\npunk rock, German hip-hop\npunk rock, German rap\npunk rock, German rap, electronic\npunk rock, Indonesian fusion\npunk rock, Italian folk\npunk rock, Italian folk, experimental\npunk rock, J-rock\npunk rock, Javanese fusion\npunk rock, Javanese, electronic\npunk rock, Javanese, experimental\npunk rock, Javanese, fusion\npunk rock, Javanese, reggae\npunk rock, Javanese, ska\npunk rock, Latin folk\npunk rock, Latin folk, ambient\npunk rock, Latin folk, ska-punk\npunk rock, Latin folk, tango\npunk rock, Latin fusion\npunk rock, Latin percussion\npunk rock, Latin percussion, J-rock\npunk rock, Latin rhythms\npunk rock, Latin rock\npunk rock, Latin rock, fusion\npunk rock, Latin rock, metal\npunk rock, Latin rock, surf rock\npunk rock, Latin salsa\npunk rock, Latin, flamenco\npunk rock, Latin, surf rock\npunk rock, Luk Thung\npunk rock, Middle Eastern folk\npunk rock, Neue Deutsche Welle\npunk rock, Polish folk\npunk rock, Romanian party music\npunk rock, Russian chanson\npunk rock, Russian chanson, folk-punk\npunk rock, Russian folk\npunk rock, Sundanese fusion\npunk rock, Sundanese, fusion\npunk rock, Tamil rap\npunk rock, Turkish folk\npunk rock, Ukrainian folk\npunk rock, alternative hip-hop\npunk rock, alternative metal\npunk rock, alternative metal, hardcore punk\npunk rock, alternative rock, Portuguese rock\npunk rock, alternative rock, post-grunge\npunk rock, big band swing\npunk rock, big band swing, metal\npunk rock, big band, brass-punk\npunk rock, big band, fusion\npunk rock, big band, jazz fusion\npunk rock, big band, ska\npunk rock, big band, swing\npunk rock, big room, electro house\npunk rock, bluegrass\npunk rock, bluegrass, country-punk\npunk rock, bluegrass, folk-punk\npunk rock, bluegrass, hip-hop\npunk rock, bluegrass, sea shanty\npunk rock, bluegrass, synth\npunk rock, boogie-woogie, cinematic\npunk rock, brass band, mariachi\npunk rock, cabaret, Portuguese rock\npunk rock, cabaret, jazz\npunk rock, cabaret, theatrical rock\npunk rock, chanson, Balkan brass\npunk rock, chanson, jazz\npunk rock, children's music\npunk rock, chiptune\npunk rock, chiptune metal\npunk rock, chiptune metalcore\npunk rock, chiptune, C-pop\npunk rock, chiptune, Latin fusion\npunk rock, chiptune, Nintendocore\npunk rock, chiptune, alt-rock\npunk rock, chiptune, ballad\npunk rock, chiptune, dance-punk\npunk rock, chiptune, electronic\npunk rock, chiptune, hyperpop\npunk rock, chiptune, indie rock\npunk rock, chiptune, math rock\npunk rock, chiptune, metalcore\npunk rock, chiptune, progressive metal\npunk rock, chiptune, shred guitar\npunk rock, chiptune, video game music\npunk rock, cinematic orchestral\npunk rock, cinematic, industrial\npunk rock, cinematic, orchestral\npunk rock, classical fusion, German spoken word\npunk rock, conscious hip-hop\npunk rock, cumbia\npunk rock, cumbia, Latin rock\npunk rock, cumbia, ska\npunk rock, cumbia-rock, emotional ballad\npunk rock, dangdut koplo\npunk rock, death metal\npunk rock, digital hardcore\npunk rock, disco, noir\npunk rock, duduk, atmospheric\npunk rock, electronic breakbeat\npunk rock, electronic breakbeat, breakcore\npunk rock, electronic dance music\npunk rock, electronic dance, aggressive\npunk rock, electronic, aggressive\npunk rock, electronic, chiptune\npunk rock, electronic, crossover\npunk rock, electronic, hardcore\npunk rock, electronic, hip-hop\npunk rock, electronic, metalcore\npunk rock, electronic, protest\npunk rock, electronic, rap\npunk rock, electronic, theatrical\npunk rock, electronic, world music\npunk rock, experimental electronic, post-rock\npunk rock, folk ballad, classical\npunk rock, folk metal\npunk rock, folk metal, polka\npunk rock, folk, C-pop\npunk rock, folk, Eastern European\npunk rock, folk, klezmer\npunk rock, folk, operatic\npunk rock, folk-metal\npunk rock, folk-metal, gypsy-punk\npunk rock, folk-punk, electronic\npunk rock, folk-punk, hip-hop\npunk rock, free jazz\npunk rock, funk-pop\npunk rock, garage rock, metalcore\npunk rock, hard rock, alternative\npunk rock, heavy metal\npunk rock, heavy metal, rap-rock\npunk rock, hip-hop\npunk rock, hip-hop, chiptune\npunk rock, hip-hop, experimental\npunk rock, hip-hop, garage rock\npunk rock, hip-hop, indie rock\npunk rock, hymn, operatic\npunk rock, hyperpop, electronic\npunk rock, industrial, synthpop\npunk rock, klezmer, surf rock\npunk rock, klezmer, synth rock\npunk rock, latin, flamenco\npunk rock, lo-fi hip hop, hyperpop\npunk rock, lo-fi, garage rock\npunk rock, melodic metal\npunk rock, metalcore, chiptune\npunk rock, metalcore, surf rock\npunk rock, musical theater\npunk rock, neoclassical metal\npunk rock, new wave\npunk rock, new wave, garage rock\npunk rock, noir jazz, cabaret\npunk rock, noise rock, operatic punk\npunk rock, polka\npunk rock, polka, Russian rock\npunk rock, polka, accordion\npunk rock, polka, electronic\npunk rock, polka, folk-punk\npunk rock, polka, klezmer\npunk rock, polka, rock\npunk rock, polka, surf rock\npunk rock, polka-punk\npunk rock, pop-rock, emotional rock\npunk rock, post-rock\npunk rock, post-rock, surf rock\npunk rock, power metal, chiptune\npunk rock, psychedelic rock, Latin rock\npunk rock, rap rock\npunk rock, rap, a cappella\npunk rock, rap, electronic\npunk rock, rap-metal\npunk rock, rap-rock, hardcore\npunk rock, rap-rock, piano ballad\npunk rock, rockabilly, Neue Deutsche Welle\npunk rock, samba, carnival\npunk rock, samba-reggae\npunk rock, ska, rock en español\npunk rock, ska-punk\npunk rock, ska-punk, German\npunk rock, southern metal\npunk rock, speed metal\npunk rock, speed metal, synth punk\npunk rock, surf rock\npunk rock, surf rock, chiptune\npunk rock, surf rock, cinematic\npunk rock, surf rock, electronic\npunk rock, surf rock, gypsy punk\npunk rock, synth-pop\npunk rock, synth-pop, video game\npunk rock, tarantella\npunk rock, technical metal\npunk rock, techno\npunk rock, theatrical metal\npunk rock, thrash metal, noise rock\npunk rock, traditional Indonesian\npunk rock, trap metal\npunk rock, trap, Latin hip hop\npunk rock, trap, electronic\npunk rock, turbo-folk\npunk rock, turntablism, hip-hop\npunk rock, world music, cinematic\npunk swing\npunk tango\npunk trap\npunk world music\npunk, surf rock, klezmer\npunk-folk\npunk-forró fusion\npunk-funk\npunk-funk rock\npunk-jazz\npunk-polka\npunk-pop\npunk-rap\npunk-reggae\npunk-rock, glitch, chiptune\npunk-ska\npunk-trap\npunkabilly\npuri dance\nqanun, devotional, Middle Eastern\nqawwali\nqawwali folk\nqawwali fusion\nqawwali pop\nquacky pop\nquacky rock\nquiet storm\nquiet storm R&B\nquiet storm, 90s R&B\nquiet storm, R&B, 80s slow jam\nquintessential European pop\nquintessential fusion\nquintessential pirate pop\nquintessential polka\nquintessential quirky pop\nquintessential whimsy\nquirky\nquirky acapella\nquirky acoustic\nquirky ambient\nquirky brass\nquirky children's\nquirky children's music\nquirky cinematic\nquirky classical\nquirky cumbia\nquirky electronic\nquirky fanfare\nquirky film score\nquirky folk\nquirky guitar\nquirky hip-hop\nquirky indie\nquirky instrumental\nquirky jazz\nquirky jingle\nquirky melodic\nquirky nursery rhyme\nquirky orchestral\nquirky organ\nquirky piano\nquirky polka\nquirky pop\nquirky pop, polka, synth pop\nquirky pop-rap\nquirky ragtime\nquirky rock\nquirky sound design\nquirky sound effect\nquirky stinger\nquirky synth\nquirky ukulele\nquirky world music\nquirky, accordion, cartoonish\nquirky, bluesy, ragtime\nquirky, koto, guzheng\nradio\nradio drama\nrage\nrage music\nrage music hyperpop\nrage phonk\nrage rap\nrage rap phonk\nrage rap pluggnb\nrage rap trap\nrage rap trap metal\nrage rap, Latin trap\nrage rap, hard trap\nrage rap, hyper-trap\nrage rap, hyperpop\nrage rap, phonk\nrage rap, trap\nrage trap\nrage trap phonk\nrage trap, cloud rap\nrage trap, hyperpop\nrage trap, pluggnb\nrage, hyper-trap\nrage, hyperpop\nrage, hyperpop, trap\nrage, pluggnb, trap\nrage-rap trap\nrage-trap\nragga\nragga dancehall\nragga drum and bass\nragga dub\nragga hip hop\nragga hip-hop\nragga house\nragga jungle\nragga jungle dancehall\nragga jungle dubstep\nragga jungle, neurofunk, drum & bass\nragga tech\nragtime\nragtime Christmas\nragtime ballad\nragtime big band\nragtime bluegrass\nragtime blues\nragtime boogie-woogie\nragtime boogie-woogie blues rock\nragtime boogie-woogie calypso\nragtime boogie-woogie cartoon\nragtime boogie-woogie show tune\nragtime cabaret\nragtime children's\nragtime children's music\nragtime classical\nragtime classical Brazilian popular\nragtime classical boogie-woogie\nragtime comedy\nragtime country\nragtime country bluegrass\nragtime country-gospel\nragtime dixieland novelty\nragtime folk\nragtime funk-rock\nragtime fusion\nragtime gospel\nragtime jazz\nragtime jazz chiptune\nragtime jazz dixieland\nragtime jazz fusion\nragtime jazz novelty\nragtime jump blues\nragtime klezmer\nragtime klezmer circus\nragtime lounge\nragtime musical\nragtime musical theater\nragtime musical theatre\nragtime novelty\nragtime orchestral\nragtime piano\nragtime pop-rock\nragtime rock\nragtime rockabilly novelty\nragtime show tune\nragtime soul\nragtime stride\nragtime stride modern classical\nragtime swing\nragtime tango\nragtime vaudeville novelty\nragtime video game\nragtime waltz\nragtime, Christmas, musical\nragtime, Latin jazz\nragtime, Latin, instrumental\nragtime, Latin, upbeat\nragtime, Latin, video game\nragtime, Latin, video game music\nragtime, Turkish folk\nragtime, accordion, folk\nragtime, big band, Latin swing\nragtime, big band, cinematic\nragtime, big band, show tune\nragtime, big band, swing\nragtime, big band, theatrical\nragtime, big band, vintage\nragtime, bluegrass, western swing\nragtime, boogie-woogie, cabaret\nragtime, boogie-woogie, children's music\nragtime, boogie-woogie, funk-rock\nragtime, boogie-woogie, musical theater\nragtime, boogie-woogie, progressive rock\nragtime, boogie-woogie, show tune\nragtime, boogie-woogie, video game music\nragtime, breakcore\nragtime, cabaret, Russian chanson\nragtime, cinematic, lounge\nragtime, cinematic, spy\nragtime, cinematic, whimsical\nragtime, circus music, cartoon music\nragtime, denpa-kei, anime\nragtime, gospel, show tune\nragtime, klezmer, cinematic\nragtime, klezmer, jazz\nragtime, modern classical\nragtime, musette, folk\nragtime, music hall, theatrical\nragtime, musical theatre\nragtime, novelty, Western\nragtime, novelty, rock and roll\nragtime, polka, festive\nragtime, rock and roll, novelty\nragtime, show tune, children's music\nragtime, show tune, novelty Christmas\nragtime, show tune, operatic pop\nragtime, show tune, patriotic\nragtime, stride piano, early jazz\nragtime, stride piano, gypsy jazz\nragtime, swing, children's music\nragtime, tango, folk\nragtime, theatrical, choral\nragtime, theatrical, cinematic\nragtime, theatrical, whimsical\nragtime, tropical, exotica\nragtime, vaudeville, music hall\nragtime, vaudeville, theatrical\nragtime, western swing\nragtime, world music, playful instrumental\nragtime-pop\nrai\nranchera\nranchera banda\nranchera big band\nranchera bolero\nranchera cabaret\nranchera corrido\nranchera cumbia\nranchera gospel\nranchera huapango\nranchera lo-fi\nranchera norteño\nranchera orchestral\nranchera rock\nranchera salsa\nranchera ska\nranchera swing\nranchera tango\nranchera waltz\nranchera, bolero, Latin ballad\nranchera, norteño\nranchera, norteño cumbia\nranchera-pop\nrap\nrap battle\nrap battle funk rock\nrap battle, boom-bap, classical hip hop\nrap battle, chiptune\nrap battle, chiptune, electronic\nrap battle, chiptune, lo-fi hip hop\nrap battle, chiptune, synth-rock\nrap battle, chiptune, video game\nrap battle, cinematic, electronic\nrap battle, video game, chiptune\nrap dubstep\nrap metal\nrap metal alternative metal\nrap metal crossover thrash\nrap metal hardcore punk\nrap metal nu-metal\nrap metal nu-metalcore\nrap metal punk rock\nrap metal, J-rock\nrap metal, Nintendocore\nrap metal, dubstep\nrap metal, electronicore, trap metal\nrap metal, hardstyle\nrap metal, horrorcore\nrap metal, metalcore, djent\nrap punk\nrap rock\nrap rock alternative\nrap rock alternative metal\nrap rock alternative rock\nrap rock electronic\nrap rock funk rock\nrap rock nu-metal\nrap rock, cinematic, symphonic metal\nrap rock, hip-hop, punk rock\nrap rock, metalcore, alternative rock\nrap rock, nu-metal, blues rock\nrap rock, nu-metal, electronic rock\nrap rock, nu-metal, lo-fi hip hop\nrap rock, nu-metal, southern rap metal\nrap rock, trap metal\nrap, boom-bap, cinematic, metal, emo-rap\nrap, boom-bap, comedy\nrap, dubstep, electronic\nrap, trap, cinematic\nrap-metal\nrap-metal nu-metal\nrap-metal southern rock\nrap-metal, Brazilian funk\nrap-metal, Tamil, protest\nrap-metal, chiptune, nu-metal\nrap-metal, cinematic, nu-metal\nrap-metal, cinematic, wuxia\nrap-metal, hard rock, chiptune\nrap-metal, nu-metal, cinematic\nrap-metal, nu-metal, trap\nrap-metal, theatrical rock, Neue Deutsche Härte\nrap-rock\nrap-rock alternative\nrap-rock alternative hip-hop\nrap-rock alternative metal\nrap-rock alternative punk\nrap-rock alternative rock\nrap-rock anime\nrap-rock chiptune\nrap-rock cumbia\nrap-rock dance-punk\nrap-rock dubstep\nrap-rock electronic\nrap-rock electronic punk\nrap-rock electronicore\nrap-rock emo\nrap-rock emo post-hardcore\nrap-rock emo-rock\nrap-rock funk\nrap-rock funk-jazz\nrap-rock funk-metal\nrap-rock funk-rock\nrap-rock hard rock\nrap-rock hardcore hip-hop\nrap-rock hardcore punk\nrap-rock industrial\nrap-rock industrial metal\nrap-rock industrial nu-metal\nrap-rock noise rock\nrap-rock noise-rock\nrap-rock nu-metal\nrap-rock nu-metal alternative metal\nrap-rock nu-metal boom-bap\nrap-rock nu-metal chiptune\nrap-rock nu-metal cinematic\nrap-rock nu-metal electronic\nrap-rock nu-metal post-hardcore\nrap-rock nu-metal southern hip-hop\nrap-rock nu-metal trap metal\nrap-rock pop-punk\nrap-rock pop-punk metalcore\nrap-rock post-hardcore\nrap-rock post-rock\nrap-rock protest\nrap-rock punk\nrap-rock punk chiptune\nrap-rock punk nu-metal\nrap-rock stadium rock\nrap-rock trap\nrap-rock, Chinese folk, punk\nrap-rock, J-rock\nrap-rock, J-rock, aggressive\nrap-rock, J-rock, hip-hop\nrap-rock, Javanese rock, power ballad\nrap-rock, Latin fusion, urban\nrap-rock, Middle Eastern fusion\nrap-rock, R&B\nrap-rock, alt-rock, nu-metal\nrap-rock, alternative metal, electronic\nrap-rock, alternative rock\nrap-rock, alternative rock, Indian fusion\nrap-rock, alternative rock, chiptune\nrap-rock, alternative rock, emo-rap\nrap-rock, alternative rock, post-hardcore\nrap-rock, alternative, electronic\nrap-rock, anime theme, trap\nrap-rock, big band swing, funk\nrap-rock, big band, swing\nrap-rock, boom-bap, cinematic\nrap-rock, brass rock\nrap-rock, chiptune, lo-fi hip hop\nrap-rock, cinematic hip-hop, ambient\nrap-rock, cinematic hip-hop, choral\nrap-rock, cinematic rock, Indian rock\nrap-rock, cinematic synth, chiptune\nrap-rock, cinematic, C-pop\nrap-rock, cinematic, Chinese\nrap-rock, cinematic, Chinese fusion\nrap-rock, cinematic, alternative rock\nrap-rock, cinematic, anthemic\nrap-rock, cinematic, big band\nrap-rock, cinematic, indie\nrap-rock, cinematic, industrial\nrap-rock, cinematic, military march\nrap-rock, cinematic, nu-metal\nrap-rock, cinematic, orchestral\nrap-rock, cinematic, theatrical\nrap-rock, cinematic, wuxia\nrap-rock, conscious hip-hop\nrap-rock, electronic dance, J-hip hop\nrap-rock, electronic dance, Japanese hip-hop\nrap-rock, electronic dance, aggressive\nrap-rock, electronic dance, hype\nrap-rock, electronic, hardstyle\nrap-rock, electronic, nu-metal\nrap-rock, electronicore, J-rock\nrap-rock, hard rock, arena rock\nrap-rock, hardcore hip-hop, hard rock\nrap-rock, hip-hop, J-rock\nrap-rock, hip-hop, electronic\nrap-rock, horrorcore, nu-metal\nrap-rock, industrial rock, cinematic\nrap-rock, industrial rock, electronic\nrap-rock, industrial rock, nu-metal\nrap-rock, industrial, chiptune\nrap-rock, industrial, lo-fi hip-hop\nrap-rock, jazzy hip-hop, soulful\nrap-rock, melodic rock, classic rock\nrap-rock, new jack swing, hard rock\nrap-rock, nu-metal, C-pop\nrap-rock, nu-metal, Chinese rock\nrap-rock, nu-metal, French rock\nrap-rock, nu-metal, German\nrap-rock, nu-metal, J-rap\nrap-rock, nu-metal, J-rock\nrap-rock, nu-metal, Japanese hip hop\nrap-rock, nu-metal, K-hip-hop\nrap-rock, nu-metal, Middle Eastern fusion\nrap-rock, nu-metal, aggressive\nrap-rock, nu-metal, alt-rock\nrap-rock, nu-metal, alternative\nrap-rock, nu-metal, ambient\nrap-rock, nu-metal, boom-bap\nrap-rock, nu-metal, chiptune\nrap-rock, nu-metal, cinematic\nrap-rock, nu-metal, comedy\nrap-rock, nu-metal, conscious hip-hop\nrap-rock, nu-metal, electronic\nrap-rock, nu-metal, electronic hip-hop\nrap-rock, nu-metal, funk\nrap-rock, nu-metal, funk hip-hop\nrap-rock, nu-metal, funk metal\nrap-rock, nu-metal, funk rock\nrap-rock, nu-metal, hip-hop\nrap-rock, nu-metal, indie-rock\nrap-rock, nu-metal, industrial\nrap-rock, nu-metal, industrial hip-hop\nrap-rock, nu-metal, industrial rock\nrap-rock, nu-metal, orchestral\nrap-rock, nu-metal, psychedelic rock\nrap-rock, nu-metal, punk rock\nrap-rock, nu-metal, synth-pop\nrap-rock, nu-metal, trap\nrap-rock, nu-metal, trap metal\nrap-rock, nu-metal, video game\nrap-rock, old-school hip-hop, nu-metal\nrap-rock, orchestral, cinematic\nrap-rock, political hip-hop, nu-metal\nrap-rock, pop-punk, J-rock\nrap-rock, pop-punk, alternative rock\nrap-rock, pop-punk, cinematic\nrap-rock, pop-punk, nu-metal\nrap-rock, pop-punk, punk-rock\nrap-rock, pop-rap, cinematic\nrap-rock, pop-rock\nrap-rock, post-hardcore, alternative metal\nrap-rock, protest, Arabic\nrap-rock, punk rock, chiptune\nrap-rock, punk rock, multilingual hip hop\nrap-rock, synth-pop, German rock\nrap-rock, synthwave, chiptune\nrap-rock, trap metal\nrap-rock, trap, EDM\nrap-rock, trap, cinematic\nrap-rock, trap, electronic\nrap-rock, trap, nu-metal\nrap-rock, trap-metal, protest\nrapcore\nrapcore electronic\nrapcore punk rock\nrapcore, hardcore hip-hop\nrave\nrave house\nrave rap\nrave techno\nrave, happy hardcore\nrave, happy hardcore, breakbeat\nrave, happy hardcore, chiptune\nrave-pop\nrave-rap\nrave-trap\nraw electro\nraw hip-hop\nraw house\nraw punk\nraw rap\nraw rock\nraï\nraï cumbia\nraï electronic\nraï pop\nrebetiko\nreflective trap\nreggae\nreggae Christmas\nreggae Latin Pop\nreggae Latin pop\nreggae MPB\nreggae R&B\nreggae R&B world music\nreggae a cappella\nreggae acoustic\nreggae afro-latin\nreggae afro-pop\nreggae afrobeat\nreggae afrobeat French pop\nreggae afrobeat brazilian\nreggae afrobeat fusion\nreggae afrobeat highlife\nreggae afrobeat pop\nreggae afrobeats\nreggae afrobeats amapiano\nreggae afropop island\nreggae ambient\nreggae axé\nreggae ballad\nreggae ballad, dancehall\nreggae ballad, reggaeton\nreggae banda\nreggae big room\nreggae blues\nreggae blues-rock\nreggae boogie\nreggae boogie funk\nreggae bossa nova\nreggae brasileiro\nreggae calypso\nreggae calypso world music\nreggae celtic\nreggae chanson\nreggae children's\nreggae chillwave\nreggae chiptune\nreggae chiptune latin\nreggae chiptune world music\nreggae city pop\nreggae conscious\nreggae conscious hip-hop\nreggae cumbia\nreggae cumbia Eastern European\nreggae dance-pop\nreggae dancehall\nreggae dancehall Arabic pop\nreggae dancehall Latin\nreggae dancehall afrobeat\nreggae dancehall chiptune\nreggae dancehall dubstep\nreggae dancehall gospel\nreggae dancehall hip-hop\nreggae dancehall orchestral\nreggae dancehall pop\nreggae dancehall soca\nreggae dancehall trap\nreggae dancehall world music\nreggae dancehall worldbeat\nreggae dancehall, R&B ballad\nreggae dancehall, South Asian pop\nreggae dancehall, conscious hip-hop\nreggae dancehall, drum and bass\nreggae dancehall, hardstyle, dubstep\nreggae dancehall, hardstyle, gabber\nreggae dancehall, neurofunk\nreggae dancehall, neurofunk, techstep\nreggae dembow\nreggae disco funk\nreggae drum and bass\nreggae dub\nreggae dub acid jazz\nreggae dub ambient\nreggae dub electronic\nreggae dub hip-hop\nreggae dub world music\nreggae dub, grime, electronic\nreggae electronic\nreggae electronica\nreggae flamenco\nreggae folk\nreggae folk pop\nreggae folk rock\nreggae funk\nreggae funk Middle Eastern pop\nreggae funk R&B\nreggae funk dancehall\nreggae funk disco\nreggae funk dub\nreggae funk hip-hop\nreggae funk latin\nreggae funk latin pop\nreggae funk pop\nreggae funk pop-rap\nreggae funk rock\nreggae funk soul\nreggae funk world\nreggae funk world music\nreggae funk-rock\nreggae fusion\nreggae fusion trap\nreggae fusion, hardstyle, big room\nreggae gaucho\nreggae gospel\nreggae gospel afrobeat\nreggae gospel calypso\nreggae gospel dancehall\nreggae gospel highlife\nreggae gospel lo-fi hip-hop\nreggae gospel r&b\nreggae gospel world music\nreggae hip hop\nreggae hip-hop\nreggae hip-hop Brazilian funk\nreggae hip-hop Latin pop\nreggae hip-hop chiptune\nreggae hip-hop dancehall\nreggae hip-hop dub\nreggae hip-hop funk\nreggae hip-hop funk-rock\nreggae hip-hop fusion\nreggae hip-hop rock\nreggae hip-hop ska\nreggae hip-hop world music\nreggae indie pop\nreggae indie rock\nreggae jazz\nreggae jazz fusion\nreggae jungle\nreggae latin\nreggae latin jazz\nreggae latin pop\nreggae latino\nreggae lo-fi\nreggae lover's rock\nreggae lovers rock\nreggae lovers rock city pop\nreggae lovers rock dancehall\nreggae lovers rock gospel\nreggae lovers rock soul\nreggae lullaby\nreggae metal\nreggae mexicano\nreggae mpb\nreggae neo-soul\nreggae novelty\nreggae parody\nreggae pop\nreggae pop bossa nova\nreggae pop chiptune\nreggae pop dancehall\nreggae pop gospel\nreggae pop hip-hop\nreggae pop rock\nreggae pop soul\nreggae pop world music\nreggae pop, lo-fi, psychedelic rock\nreggae pop-funk dancehall\nreggae pop-punk\nreggae pop-rap\nreggae pop-rock\nreggae protest\nreggae punk\nreggae rap\nreggae rap, cloud rap, Latin hip hop\nreggae rap-metal\nreggae remix\nreggae revolutionary\nreggae riddim\nreggae riddim, Latin hip-hop\nreggae rock\nreggae rock ska-punk\nreggae rock surf rock\nreggae rock, Latin rock, rap rock\nreggae rocksteady\nreggae rocksteady doo-wop\nreggae rocksteady ska\nreggae rocksteady soul\nreggae roots\nreggae rumba\nreggae salsa\nreggae samba\nreggae schlager\nreggae ska\nreggae ska Israeli rock\nreggae ska Latin\nreggae ska Latin jazz\nreggae ska Latin rock\nreggae ska calypso\nreggae ska children's music\nreggae ska dancehall\nreggae ska hip-hop\nreggae ska punk\nreggae ska rock\nreggae ska rocksteady\nreggae ska thrash metal\nreggae ska-rock\nreggae soca\nreggae soul\nreggae soul funk\nreggae soul gospel\nreggae soul hip-hop\nreggae spiritual\nreggae surf rock\nreggae synth-pop\nreggae techno-pop\nreggae trap\nreggae trip-hop\nreggae world music\nreggae worldbeat\nreggae zouk\nreggae, Brazilian\nreggae, Chinese folk, hip hop\nreggae, Dutch schlager\nreggae, East Asian fusion\nreggae, Eastern European, estrada\nreggae, French chanson, world music\nreggae, Islamic devotional\nreggae, Latin rock\nreggae, MPB\nreggae, MPB, funk\nreggae, MPB, soul\nreggae, Middle Eastern\nreggae, Middle Eastern, cinematic\nreggae, Middle Eastern, dub\nreggae, Southeast Asian, synth\nreggae, Thai pop\nreggae, Turkish folk\nreggae, afrobeat, ska\nreggae, calypso, upbeat\nreggae, chanson, dancehall\nreggae, conscious reggae\nreggae, dancehall, Balkan pop\nreggae, dancehall, Brazilian pop\nreggae, dancehall, C-pop\nreggae, dancehall, East Asian fusion\nreggae, dancehall, hip hop\nreggae, drum and bass, soul\nreggae, eurodance\nreggae, festive, Christmas\nreggae, folk, Azerbaijani hip hop\nreggae, folk, Punjabi\nreggae, folk, holiday\nreggae, future bass, Latin pop\nreggae, happy hardcore\nreggae, hardstyle\nreggae, hardstyle, big room house\nreggae, ska, children's music\nreggae, soft rock, world music\nreggae, soul, ska\nreggae, spiritual, South Asian\nreggae, trap, dubstep\nreggae-cumbia\nreggae-dancehall\nreggae-dancehall alternative rock\nreggae-dancehall chiptune\nreggae-dancehall protest\nreggae-dancehall, Latin reggaeton\nreggae-dub\nreggae-dub breakcore\nreggae-dub chillhop\nreggae-dub drum & bass\nreggae-dub electronic\nreggae-dub fusion\nreggae-dub hip-hop\nreggae-dub lo-fi\nreggae-dub soul\nreggae-dub wobble bass\nreggae-dub, lo-fi hip hop\nreggae-folk\nreggae-funk\nreggae-funk, cinematic, Indonesian\nreggae-gospel\nreggae-infused Brazilian pop\nreggae-infused Filipino protest\nreggae-infused drum and bass\nreggae-pop\nreggae-pop Afro-pop\nreggae-pop Afrobeat\nreggae-pop Balkan\nreggae-pop Balkan folk\nreggae-pop French pop\nreggae-pop J-pop\nreggae-pop J-reggae\nreggae-pop J-rock\nreggae-pop Latin\nreggae-pop Latin rock\nreggae-pop MPB\nreggae-pop Mandopop\nreggae-pop afrobeat\nreggae-pop afrobeats\nreggae-pop afrobeats dancehall\nreggae-pop alt-rock\nreggae-pop bossa nova\nreggae-pop calypso\nreggae-pop children's\nreggae-pop chiptune\nreggae-pop city pop\nreggae-pop dancehall\nreggae-pop electro-rock\nreggae-pop funk\nreggae-pop funk ska\nreggae-pop funk-rock\nreggae-pop gospel\nreggae-pop hip-hop\nreggae-pop latin rock\nreggae-pop lo-fi\nreggae-pop lo-fi hip-hop\nreggae-pop lovers rock\nreggae-pop neo-soul\nreggae-pop rock funk ballad\nreggae-pop salsa\nreggae-pop schlager\nreggae-pop sertanejo\nreggae-pop ska\nreggae-pop ska-punk\nreggae-pop smooth jazz\nreggae-pop southern rock\nreggae-pop surf rock\nreggae-pop surf-rock\nreggae-pop tropical house\nreggae-pop tropical pop\nreggae-pop tropical rock\nreggae-pop world music\nreggae-pop worldbeat\nreggae-pop zouk\nreggae-pop, Brazilian funk\nreggae-pop, Latin rock\nreggae-pop, MPB\nreggae-pop, Schlager\nreggae-pop, big room house\nreggae-pop, funk\nreggae-punk\nreggae-rap\nreggae-rock\nreggae-rock dub\nreggae-rock funk\nreggae-rock fusion\nreggae-rock gospel\nreggae-rock gospel-soul\nreggae-rock hip-hop\nreggae-rock metalcore\nreggae-rock punk\nreggae-rock ska\nreggae-rock ska-punk\nreggae-ska\nreggae-ska children's\nreggae-ska fusion\nreggae-ska lo-fi\nreggae-ska punk\nreggae-ska punk rock\nreggae-ska soul\nreggae-ska world music\nreggae-ska, Latin pop, psychedelic norteño\nreggae-ska, folk fusion, hip-hop\nreggae-soca\nreggae-trap\nreggaeton\nreggaeton 90s hip-hop\nreggaeton Afro-fusion\nreggaeton Afrobeat\nreggaeton Arabic fusion\nreggaeton Arabic pop\nreggaeton Balkan\nreggaeton Balkan fusion\nreggaeton Balkan pop\nreggaeton Bollywood\nreggaeton C-pop\nreggaeton Christian pop\nreggaeton EDM\nreggaeton French pop\nreggaeton German rap\nreggaeton J-pop\nreggaeton J-pop fusion\nreggaeton K-hip-hop\nreggaeton Latin R&B\nreggaeton Latin pop\nreggaeton Latin pop Italian rap\nreggaeton Latin pop Romanian rap\nreggaeton Latin trap\nreggaeton Punjabi pop\nreggaeton R&B\nreggaeton R&B ambient\nreggaeton R&B atmospheric pop\nreggaeton R&B chiptune\nreggaeton R&B cloud rap\nreggaeton R&B dancehall\nreggaeton R&B dream pop\nreggaeton R&B gospel\nreggaeton R&B hip-hop\nreggaeton R&B lo-fi\nreggaeton R&B neo-soul\nreggaeton R&B pop\nreggaeton R&B synth-pop\nreggaeton R&B trap\nreggaeton Tibetan\nreggaeton UK rap\nreggaeton a cappella\nreggaeton afro-trap\nreggaeton afrobeat\nreggaeton afrobeat dancehall\nreggaeton afrobeat french rap\nreggaeton afrobeat oud\nreggaeton afrobeat pop\nreggaeton afrobeats\nreggaeton afrobeats R&B\nreggaeton afrobeats Scandinavian pop\nreggaeton afrobeats chiptune\nreggaeton afrobeats dancehall\nreggaeton afrobeats latin pop\nreggaeton afrobeats pop\nreggaeton afrobeats tropical pop\nreggaeton alternative R&B\nreggaeton ambient\nreggaeton anime\nreggaeton arab pop\nreggaeton bachata\nreggaeton baile funk\nreggaeton baile funk dancehall\nreggaeton balkan\nreggaeton balkan folk\nreggaeton balkan pop\nreggaeton ballad\nreggaeton ballad, trap R&B\nreggaeton bolero\nreggaeton bollywood dance-pop\nreggaeton boom-bap\nreggaeton bossa nova\nreggaeton brostep\nreggaeton cello\nreggaeton children's\nreggaeton chill\nreggaeton chill R&B\nreggaeton chill trap\nreggaeton chillwave\nreggaeton chillwave R&B\nreggaeton chillwave lo-fi\nreggaeton chillwave trap\nreggaeton chillwave vaporwave\nreggaeton chiptune\nreggaeton chiptune dembow\nreggaeton chiptune electronic\nreggaeton chiptune electropop\nreggaeton chiptune horrorcore\nreggaeton chiptune latin pop\nreggaeton chiptune synth-pop\nreggaeton chiptune trap\nreggaeton chiptune tropical\nreggaeton chiptune vaporwave\nreggaeton cinematic\nreggaeton classical\nreggaeton cloud rap\nreggaeton cloud rap vaporwave\nreggaeton conscious\nreggaeton corrido\nreggaeton cumbia\nreggaeton cumbia French pop\nreggaeton cumbia Latin dance\nreggaeton cumbia R&B\nreggaeton cumbia bachata\nreggaeton cumbia chiptune\nreggaeton cumbia dembow\nreggaeton cumbia fusion\nreggaeton cumbia latin rock\nreggaeton cumbia lo-fi\nreggaeton cumbia merengue\nreggaeton cumbia norteño\nreggaeton cumbia pop\nreggaeton cumbia rock\nreggaeton cumbia salsa\nreggaeton cumbia sci-fi\nreggaeton cumbia techno\nreggaeton cumbia trap\nreggaeton cumbia tropical pop\nreggaeton cumbia urban\nreggaeton cumbia villera\nreggaeton cumbia villera trap\nreggaeton dance-pop\nreggaeton dancehall\nreggaeton dancehall afrobeat\nreggaeton dancehall bilingual\nreggaeton dancehall dembow\nreggaeton dancehall moombahton\nreggaeton dancehall pop\nreggaeton dancehall pop-rap\nreggaeton dancehall summer pop\nreggaeton dancehall vaporwave\nreggaeton dark R&B\nreggaeton dark pop\nreggaeton dark trap\nreggaeton deep house\nreggaeton deep house trap\nreggaeton dembow\nreggaeton devotional\nreggaeton dream pop\nreggaeton dream-pop\nreggaeton dreamy\nreggaeton drill\nreggaeton dubstep\nreggaeton electro-house\nreggaeton electro-pop\nreggaeton electronic\nreggaeton electronic pop\nreggaeton electronic rock\nreggaeton eurodance\nreggaeton flamenco\nreggaeton flamenco Latin pop\nreggaeton flamenco fusion\nreggaeton flamenco latin pop\nreggaeton flamenco pop\nreggaeton folk fusion\nreggaeton funk\nreggaeton funk R&B\nreggaeton funk cumbia\nreggaeton funk disco\nreggaeton funk world music\nreggaeton fusion\nreggaeton future bass\nreggaeton gospel\nreggaeton hardcore hip-hop\nreggaeton hardstyle\nreggaeton hardstyle electro house\nreggaeton hardstyle gabber\nreggaeton hardstyle psytrance\nreggaeton hip hop\nreggaeton hip-hop\nreggaeton hip-hop bollywood\nreggaeton house\nreggaeton hyperpop\nreggaeton hyperpop J-pop\nreggaeton hyperpop K-pop\nreggaeton hyperpop chiptune\nreggaeton hyperpop dream pop\nreggaeton hyperpop glitch-pop\nreggaeton hyperpop glitchcore\nreggaeton hyperpop hardstyle\nreggaeton hyperpop kawaii\nreggaeton hyperpop latin trap\nreggaeton hyperpop moombahton\nreggaeton hyperpop trap\nreggaeton hyperpop vaporwave\nreggaeton indie pop\nreggaeton indie-pop\nreggaeton industrial\nreggaeton italiano\nreggaeton italo-dance\nreggaeton j-pop\nreggaeton jazz\nreggaeton jazzy\nreggaeton kids\nreggaeton latin jazz\nreggaeton latin pop\nreggaeton latin trap\nreggaeton lento\nreggaeton lento, ambient, trap-R&B\nreggaeton lento, trap, drill\nreggaeton lo-fi\nreggaeton lo-fi R&B\nreggaeton lo-fi hip hop\nreggaeton lo-fi hip-hop\nreggaeton lo-fi pop\nreggaeton lo-fi vaporwave\nreggaeton lofi\nreggaeton lovers rock\nreggaeton mambo\nreggaeton mandopop\nreggaeton mariachi\nreggaeton melancholic\nreggaeton merengue\nreggaeton merengue dance\nreggaeton moombahton\nreggaeton moombahton Bollywood\nreggaeton moombahton chiptune\nreggaeton moombahton dance-pop\nreggaeton moombahton electro house\nreggaeton moombahton electro-pop\nreggaeton moombahton latin pop\nreggaeton moombahton trap\nreggaeton nerdcore\nreggaeton novelty\nreggaeton orchestral\nreggaeton parody\nreggaeton polka\nreggaeton pop\nreggaeton pop R&B\nreggaeton pop afrobeat\nreggaeton pop bollywood\nreggaeton pop chiptune\nreggaeton pop gospel\nreggaeton pop hip-hop\nreggaeton pop rap\nreggaeton pop, Russian R&B, modern trap\nreggaeton pop, chiptune, ambient\nreggaeton pop, chiptune, shoegaze\nreggaeton pop-R&B\nreggaeton pop-dance\nreggaeton pop-punk\nreggaeton pop-rap\nreggaeton pop-rock\nreggaeton pop-trap\nreggaeton protest\nreggaeton punk\nreggaeton punk rock\nreggaeton ragtime\nreggaeton rap\nreggaeton rap battle\nreggaeton riddim\nreggaeton rock\nreggaeton romantic\nreggaeton salsa\nreggaeton salsa cumbia\nreggaeton salsa fusion\nreggaeton salsa merengue\nreggaeton satirical\nreggaeton sertanejo\nreggaeton smooth jazz\nreggaeton soul\nreggaeton spiritual\nreggaeton synth-pop\nreggaeton synth-pop chiptune\nreggaeton synth-pop deep house\nreggaeton synth-pop vaporwave\nreggaeton tango\nreggaeton tango fusion\nreggaeton techno\nreggaeton timba\nreggaeton trap\nreggaeton trap R&B\nreggaeton trap bilingual pop\nreggaeton trap dancehall\nreggaeton trap electronic\nreggaeton trap hyperpop\nreggaeton trap pop\nreggaeton trap soul\nreggaeton trap vaporwave\nreggaeton trap-pop\nreggaeton trap-soul\nreggaeton trapeton\nreggaeton tropical\nreggaeton tropical house\nreggaeton tropical pop\nreggaeton ukulele\nreggaeton ukulele pop\nreggaeton urban\nreggaeton vallenato\nreggaeton vaporwave\nreggaeton vaporwave cloud rap\nreggaeton vaporwave lo-fi\nreggaeton vaporwave synth-pop\nreggaeton world fusion\nreggaeton world music\nreggaeton worship\nreggaeton, 8-bit, urban\nreggaeton, 90s Latin pop\nreggaeton, Afro-Caribbean, electronic\nreggaeton, Arabic fusion\nreggaeton, Arabic fusion, dance\nreggaeton, Arabic pop\nreggaeton, Arabic pop, Albanian pop\nreggaeton, Arabic pop, Middle Eastern\nreggaeton, Arabic pop, cinematic pop\nreggaeton, Balkan brass, Italian rap\nreggaeton, Balkan dance\nreggaeton, Balkan folk\nreggaeton, Balkan hip-hop\nreggaeton, Balkan party\nreggaeton, Balkan pop\nreggaeton, Balkan pop, Latin pop\nreggaeton, Balkan pop, bilingual pop\nreggaeton, Balkan pop, dancehall\nreggaeton, Balkan pop, electronic\nreggaeton, Balkan pop, lo-fi\nreggaeton, Balkan pop, pop-dance\nreggaeton, Balkan trap\nreggaeton, Balkan, Latin\nreggaeton, Balkan, Middle Eastern\nreggaeton, Balkan, dance\nreggaeton, Balkan, lo-fi\nreggaeton, Bollywood\nreggaeton, Bollywood pop\nreggaeton, Bollywood pop, Latin pop\nreggaeton, Bollywood, French fusion\nreggaeton, Bollywood, electronic\nreggaeton, Bollywood, pop fusion\nreggaeton, Brazilian\nreggaeton, Brazilian funk\nreggaeton, Brazilian funk, trap\nreggaeton, Brazilian hip-hop\nreggaeton, Brazilian, dance\nreggaeton, C-pop, electronic\nreggaeton, Central Asian\nreggaeton, Central Asian folk, fusion\nreggaeton, Central Asian fusion\nreggaeton, Central Asian, synth groove\nreggaeton, Chinese hip hop, Mongolian fusion\nreggaeton, Christian pop\nreggaeton, Christian rap\nreggaeton, Christian, bilingual\nreggaeton, Cuban son, Latin urban\nreggaeton, Dutch House, cinematic\nreggaeton, Dutch hip-hop\nreggaeton, EDM, moombahton\nreggaeton, EDM, trap\nreggaeton, Eastern European pop\nreggaeton, Eastern European, melancholic\nreggaeton, French hip-hop\nreggaeton, French pop\nreggaeton, French pop, Middle Eastern\nreggaeton, French pop, Romanian pop\nreggaeton, French pop, afrobeat\nreggaeton, French pop, world fusion\nreggaeton, French rap\nreggaeton, French rap, Latin pop\nreggaeton, French rap, dembow\nreggaeton, German hip-hop\nreggaeton, German pop\nreggaeton, German pop-rap\nreggaeton, German rap\nreggaeton, Indian fusion\nreggaeton, Italian folk\nreggaeton, Italian pop\nreggaeton, Italian pop, world fusion\nreggaeton, J-pop, electronic\nreggaeton, J-rock, lo-fi\nreggaeton, Japanese hip-hop\nreggaeton, K-pop\nreggaeton, Kizomba, pop\nreggaeton, Latin Christmas, upbeat\nreggaeton, Latin Pop\nreggaeton, Latin R&B\nreggaeton, Latin R&B, ambient\nreggaeton, Latin R&B, chillwave\nreggaeton, Latin ballad, dream pop\nreggaeton, Latin club\nreggaeton, Latin dance, Andean fusion\nreggaeton, Latin dance, satire\nreggaeton, Latin dance-pop\nreggaeton, Latin electronic, experimental club\nreggaeton, Latin folk, C-pop\nreggaeton, Latin folk, dancehall, R&B\nreggaeton, Latin hip-hop\nreggaeton, Latin hip-hop, chiptune\nreggaeton, Latin hip-hop, cinematic\nreggaeton, Latin house\nreggaeton, Latin house, dance\nreggaeton, Latin house, dancehall\nreggaeton, Latin house, minimal electronic\nreggaeton, Latin party, cumbia\nreggaeton, Latin pop\nreggaeton, Latin pop, Andean fusion\nreggaeton, Latin pop, Brazilian pop\nreggaeton, Latin pop, Christian\nreggaeton, Latin pop, Christian contemporary\nreggaeton, Latin pop, EDM\nreggaeton, Latin pop, East Asian fusion\nreggaeton, Latin pop, East Asian rap\nreggaeton, Latin pop, Eastern European pop\nreggaeton, Latin pop, Eurodance\nreggaeton, Latin pop, European hip-hop\nreggaeton, Latin pop, European rap\nreggaeton, Latin pop, Europop\nreggaeton, Latin pop, Europop-rap\nreggaeton, Latin pop, French hip-hop\nreggaeton, Latin pop, French rap\nreggaeton, Latin pop, Italian hip-hop\nreggaeton, Latin pop, Italian trap\nreggaeton, Latin pop, Mediterranean\nreggaeton, Latin pop, Mediterranean hip-hop\nreggaeton, Latin pop, Middle Eastern\nreggaeton, Latin pop, Middle Eastern fusion\nreggaeton, Latin pop, Middle Eastern pop\nreggaeton, Latin pop, Polish rap\nreggaeton, Latin pop, R&B\nreggaeton, Latin pop, Scandinavian hip-hop\nreggaeton, Latin pop, acoustic\nreggaeton, Latin pop, afrobeats\nreggaeton, Latin pop, ambient\nreggaeton, Latin pop, bachata\nreggaeton, Latin pop, chiptune\nreggaeton, Latin pop, cinematic\nreggaeton, Latin pop, cloud rap\nreggaeton, Latin pop, club\nreggaeton, Latin pop, cumbia\nreggaeton, Latin pop, dance-pop\nreggaeton, Latin pop, dancehall\nreggaeton, Latin pop, dream pop\nreggaeton, Latin pop, dreamy\nreggaeton, Latin pop, electronic\nreggaeton, Latin pop, electronic dance\nreggaeton, Latin pop, emotional\nreggaeton, Latin pop, experimental\nreggaeton, Latin pop, flamenco\nreggaeton, Latin pop, flamenco fusion\nreggaeton, Latin pop, hip-hop\nreggaeton, Latin pop, hyperpop\nreggaeton, Latin pop, industrial\nreggaeton, Latin pop, lo-fi\nreggaeton, Latin pop, mambo\nreggaeton, Latin pop, merengue\nreggaeton, Latin pop, moombahton\nreggaeton, Latin pop, piano ballad\nreggaeton, Latin pop, pop-punk\nreggaeton, Latin pop, quirky synth\nreggaeton, Latin pop, retro electronic\nreggaeton, Latin pop, salsa\nreggaeton, Latin pop, trap\nreggaeton, Latin pop, tropical house\nreggaeton, Latin pop, vaporwave\nreggaeton, Latin pop, world music\nreggaeton, Latin protest, salsa\nreggaeton, Latin rock\nreggaeton, Latin rock, nu-metal\nreggaeton, Latin trap\nreggaeton, Latin trap, Dutch hip-hop\nreggaeton, Latin trap, R&B\nreggaeton, Latin trap, Scandinavian\nreggaeton, Latin trap, chiptune\nreggaeton, Latin trap, dembow\nreggaeton, Latin trap, flamenco\nreggaeton, Latin trap, future bass\nreggaeton, Latin trap, jungle\nreggaeton, Latin trap, melodic\nreggaeton, Latin trap, pop\nreggaeton, Latin trap, vaporwave\nreggaeton, Latin urban\nreggaeton, Latin urban, Cuban son\nreggaeton, Latin urban, Puerto Rican folk\nreggaeton, Latin urban, melodic\nreggaeton, Latin urban, trap\nreggaeton, Latin, South Asian\nreggaeton, Latin, South Indian fusion\nreggaeton, Latin-pop\nreggaeton, Latin-pop, Balkan fusion\nreggaeton, Mandopop, Latin pop\nreggaeton, Middle Eastern\nreggaeton, Middle Eastern fusion\nreggaeton, Middle Eastern pop\nreggaeton, Middle Eastern pop, Balkan pop\nreggaeton, Middle Eastern, Balkan\nreggaeton, Middle Eastern, Latin\nreggaeton, Middle Eastern, Latin pop\nreggaeton, Middle Eastern, North African\nreggaeton, Middle Eastern, R&B\nreggaeton, Middle Eastern, South Asian\nreggaeton, Middle Eastern, Turkish\nreggaeton, Middle Eastern, ambient\nreggaeton, Middle Eastern, club\nreggaeton, Middle Eastern, dance\nreggaeton, Middle Eastern, electronic\nreggaeton, Middle Eastern, instrumental\nreggaeton, Middle Eastern, melodic\nreggaeton, North African pop\nreggaeton, Polish hip-hop\nreggaeton, Portuguese folk\nreggaeton, Punjabi pop\nreggaeton, Punjabi pop, R&B\nreggaeton, Punjabi, electronic\nreggaeton, R&B\nreggaeton, R&B, Latin pop\nreggaeton, R&B, cloud rap\nreggaeton, R&B, cumbia-pop\nreggaeton, R&B, dark pop\nreggaeton, R&B, electronic\nreggaeton, R&B, hip-hop\nreggaeton, R&B, pop\nreggaeton, R&B, reggae\nreggaeton, R&B, synth-pop\nreggaeton, R&B, trap\nreggaeton, R&B, trap soul\nreggaeton, R&B, trap-soul\nreggaeton, R&B, vaporwave\nreggaeton, Rai, Latin\nreggaeton, Romanian hip-hop, Latin pop\nreggaeton, Romanian party, dance\nreggaeton, Russian folk\nreggaeton, Russian pop\nreggaeton, Russian rap\nreggaeton, South Asian fusion\nreggaeton, South Asian pop\nreggaeton, South Asian, upbeat\nreggaeton, South Indian pop\nreggaeton, Spanish folk, Latin pop\nreggaeton, Tamil pop, Latin fusion\nreggaeton, Turkish dance-pop\nreggaeton, Turkish pop\nreggaeton, UK drill\nreggaeton, UK drill, hardstyle\nreggaeton, UK garage, ambient\nreggaeton, UK hip-hop\nreggaeton, UK rap, chiptune\nreggaeton, UK rap, hard techno\nreggaeton, acoustic, melancholic\nreggaeton, afrobeat\nreggaeton, alternative R&B\nreggaeton, alternative R&B, atmospheric pop\nreggaeton, alternative rock, conscious hip-hop\nreggaeton, alternative rock, hyperpop\nreggaeton, ambient\nreggaeton, ambient, Latin R&B\nreggaeton, ambient, Latin pop\nreggaeton, ambient, R&B\nreggaeton, ambient, bilingual\nreggaeton, ambient, cinematic\nreggaeton, ambient, dreamy\nreggaeton, ambient, electronic\nreggaeton, ambient, emotional\nreggaeton, ambient, emotional pop\nreggaeton, ambient, hyperpop\nreggaeton, ambient, latin pop\nreggaeton, ambient, lo-fi\nreggaeton, ambient, rock\nreggaeton, ambient, trap\nreggaeton, ambient, world fusion\nreggaeton, anime, nerdcore\nreggaeton, atmospheric R&B\nreggaeton, atmospheric R&B, Latin pop\nreggaeton, atmospheric pop\nreggaeton, atmospheric pop, latin R&B\nreggaeton, atmospheric, latin pop\nreggaeton, bachata, cinematic\nreggaeton, bachata, merengue\nreggaeton, baile funk\nreggaeton, baile funk, Latin house\nreggaeton, baile funk, hyperpop\nreggaeton, baile funk, tech house\nreggaeton, baroque, flamenco\nreggaeton, bhajan, electronic\nreggaeton, big room house\nreggaeton, big room, ambient\nreggaeton, bilingual pop\nreggaeton, bitcrush, chiptune\nreggaeton, bolero, chiptune\nreggaeton, boom-bap, cinematic\nreggaeton, breakcore, ambient\nreggaeton, children's music\nreggaeton, children's pop\nreggaeton, chill trap, modern R&B\nreggaeton, chillwave\nreggaeton, chillwave, German pop\nreggaeton, chillwave, Latin R&B\nreggaeton, chillwave, latin pop\nreggaeton, chillwave, tropical house\nreggaeton, chillwave, vaporwave\nreggaeton, chiptune\nreggaeton, chiptune, Italian pop\nreggaeton, chiptune, Latin dance\nreggaeton, chiptune, Latin house\nreggaeton, chiptune, Latin pop\nreggaeton, chiptune, Latin trap\nreggaeton, chiptune, Latin urban\nreggaeton, chiptune, ambient\nreggaeton, chiptune, cinematic\nreggaeton, chiptune, club\nreggaeton, chiptune, dark ambient\nreggaeton, chiptune, dembow\nreggaeton, chiptune, dreamy\nreggaeton, chiptune, electronic\nreggaeton, chiptune, emo-rap\nreggaeton, chiptune, future bass\nreggaeton, chiptune, future pop\nreggaeton, chiptune, hardstyle\nreggaeton, chiptune, hip hop\nreggaeton, chiptune, hyperpop\nreggaeton, chiptune, latin pop\nreggaeton, chiptune, lo-fi\nreggaeton, chiptune, melancholic\nreggaeton, chiptune, moombahton\nreggaeton, chiptune, pop\nreggaeton, chiptune, romantic\nreggaeton, chiptune, synth-pop\nreggaeton, chiptune, synthwave\nreggaeton, chiptune, trap\nreggaeton, chiptune, urban\nreggaeton, chiptune, vaporwave\nreggaeton, chiptune, video game\nreggaeton, cinematic\nreggaeton, cinematic orchestral\nreggaeton, cinematic pop\nreggaeton, cinematic synth, chiptune\nreggaeton, cinematic, Balkan\nreggaeton, cinematic, Balkan folk\nreggaeton, cinematic, Balkan fusion\nreggaeton, cinematic, C-pop\nreggaeton, cinematic, Eastern European\nreggaeton, cinematic, French chanson\nreggaeton, cinematic, French hip hop\nreggaeton, cinematic, Hindi pop\nreggaeton, cinematic, Latin\nreggaeton, cinematic, Latin dance\nreggaeton, cinematic, Latin pop\nreggaeton, cinematic, Latin urban\nreggaeton, cinematic, Middle Eastern\nreggaeton, cinematic, R&B\nreggaeton, cinematic, aggressive\nreggaeton, cinematic, ambient\nreggaeton, cinematic, chiptune\nreggaeton, cinematic, dance-pop\nreggaeton, cinematic, dark\nreggaeton, cinematic, dark orchestral\nreggaeton, cinematic, dembow\nreggaeton, cinematic, electronic\nreggaeton, cinematic, emotional\nreggaeton, cinematic, epic\nreggaeton, cinematic, ethereal\nreggaeton, cinematic, ethnic fusion\nreggaeton, cinematic, flamenco\nreggaeton, cinematic, folk\nreggaeton, cinematic, fusion\nreggaeton, cinematic, future bass\nreggaeton, cinematic, futuristic\nreggaeton, cinematic, glitch\nreggaeton, cinematic, gospel\nreggaeton, cinematic, hip-hop\nreggaeton, cinematic, hyperpop\nreggaeton, cinematic, industrial hip-hop\nreggaeton, cinematic, klezmer\nreggaeton, cinematic, lo-fi\nreggaeton, cinematic, melancholic\nreggaeton, cinematic, operatic\nreggaeton, cinematic, orchestral\nreggaeton, cinematic, pop\nreggaeton, cinematic, protest\nreggaeton, cinematic, rock\nreggaeton, cinematic, sci-fi\nreggaeton, cinematic, synth brass\nreggaeton, cinematic, synthwave\nreggaeton, cinematic, trap\nreggaeton, cinematic, world fusion\nreggaeton, classical fusion\nreggaeton, classical, cinematic\nreggaeton, classical, romantic\nreggaeton, cloud pop\nreggaeton, cloud rap\nreggaeton, cloud rap, alternative R&B\nreggaeton, cloud rap, cinematic\nreggaeton, cloud rap, trap\nreggaeton, cloud rap, vaporwave\nreggaeton, cloud-pop\nreggaeton, club, multilingual\nreggaeton, conscious Latin urban\nreggaeton, conscious hip-hop\nreggaeton, conscious hip-hop, R&B\nreggaeton, contemporary Christian\nreggaeton, contemporary R&B\nreggaeton, corrido sierreño\nreggaeton, cumbia villera, Latin pop\nreggaeton, cumbia, Latin urban\nreggaeton, cumbia, cinematic\nreggaeton, cumbia, dance-pop\nreggaeton, cumbia, electronic\nreggaeton, cumbia, trap\nreggaeton, cyberpunk, future bass\nreggaeton, cyberpunk, rock\nreggaeton, dance, bilingual\nreggaeton, dance, electronic\nreggaeton, dance-pop\nreggaeton, dance-pop, Latin\nreggaeton, dance-pop, dembow\nreggaeton, dance-pop, trap\nreggaeton, dancehall, European pop\nreggaeton, dancehall, French rap\nreggaeton, dancehall, Latin\nreggaeton, dancehall, Latin house\nreggaeton, dancehall, Latin pop\nreggaeton, dancehall, R&B-pop\nreggaeton, dancehall, chiptune\nreggaeton, dancehall, dark ambient\nreggaeton, dancehall, early 2000s\nreggaeton, dancehall, electronic\nreggaeton, dancehall, electronic pop\nreggaeton, dancehall, moombahton\nreggaeton, dancehall, moombahton, R&B\nreggaeton, dancehall, political hip hop\nreggaeton, dark R&B, sad trap\nreggaeton, dark ambient\nreggaeton, dark pop\nreggaeton, dark wave, chiptune\nreggaeton, deep house\nreggaeton, deep house, melodic techno\nreggaeton, deep house, tech house\nreggaeton, dembow\nreggaeton, dembow, Latin club\nreggaeton, dembow, Latin house\nreggaeton, dembow, electronic\nreggaeton, downtempo, ambient\nreggaeton, dream pop\nreggaeton, dream pop, Latin pop\nreggaeton, dream pop, R&B\nreggaeton, dream pop, ambient\nreggaeton, dream pop, hyperpop\nreggaeton, dream pop, lo-fi hip hop\nreggaeton, dream pop, synthwave\nreggaeton, dreamy synth\nreggaeton, dreamy synth-pop\nreggaeton, dreamy, atmospheric\nreggaeton, dreamy, hyperpop\nreggaeton, dreamy, melancholic\nreggaeton, drum and bass, cinematic\nreggaeton, drum and bass, lo-fi\nreggaeton, electro-house\nreggaeton, electro-pop\nreggaeton, electronic dance, Latin\nreggaeton, electronic dance, Latin pop\nreggaeton, electronic, Bengali pop\nreggaeton, electronic, Finnish hip hop\nreggaeton, electronic, Indian fusion\nreggaeton, electronic, Latin\nreggaeton, electronic, Middle Eastern\nreggaeton, electronic, Middle Eastern fusion\nreggaeton, electronic, North African\nreggaeton, electronic, Romanian party\nreggaeton, electronic, Russian rap\nreggaeton, electronic, South Asian\nreggaeton, electronic, South Asian fusion\nreggaeton, electronic, Turkish fusion\nreggaeton, electronic, bansuri\nreggaeton, electronic, bilingual\nreggaeton, electronic, dance\nreggaeton, electronic, global fusion\nreggaeton, electronic, latin pop\nreggaeton, electronic, multilingual\nreggaeton, electronic, pop\nreggaeton, electronic, psychedelic\nreggaeton, electronic, ritualistic\nreggaeton, electronic, techno\nreggaeton, electronic, urban\nreggaeton, electronic, world fusion\nreggaeton, emo-rap, hyperpop\nreggaeton, emotional pop\nreggaeton, ethereal, melancholic\nreggaeton, ethnic fusion\nreggaeton, ethno-electronic\nreggaeton, euro-dance\nreggaeton, eurodance, 2000s video game\nreggaeton, eurodance, chiptune\nreggaeton, experimental, lo-fi\nreggaeton, festive\nreggaeton, festive, melancholic\nreggaeton, festive, modern\nreggaeton, festive, upbeat\nreggaeton, flamenco fusion\nreggaeton, flamenco pop\nreggaeton, flamenco pop, synthwave\nreggaeton, flamenco, Latin pop\nreggaeton, flamenco, Latin trap\nreggaeton, flamenco, R&B\nreggaeton, flamenco, Russian rap\nreggaeton, flamenco, ambient\nreggaeton, flamenco, ballad\nreggaeton, flamenco, cinematic\nreggaeton, flamenco, emotional\nreggaeton, flamenco, hip-hop\nreggaeton, flamenco, latin trap\nreggaeton, flamenco, lo-fi\nreggaeton, flamenco, pop\nreggaeton, flamenco, pop-R&B\nreggaeton, flamenco, rap\nreggaeton, flamenco, urban\nreggaeton, folk pop\nreggaeton, folk, French rap\nreggaeton, folk, bilingual\nreggaeton, folk, lo-fi\nreggaeton, folk, summer party\nreggaeton, fusion, Indian pop\nreggaeton, fusion, R&B\nreggaeton, fusion, South Asian\nreggaeton, future bass\nreggaeton, future bass, ambient\nreggaeton, future bass, chiptune\nreggaeton, future bass, hardstyle\nreggaeton, future reggaeton, chiptune\nreggaeton, futuristic\nreggaeton, futuristic, chiptune\nreggaeton, futuristic, electronic\nreggaeton, glitch hop\nreggaeton, glitch, electronic\nreggaeton, glitch, lo-fi\nreggaeton, glitch, synthwave\nreggaeton, global pop, fusion\nreggaeton, gospel, Latin pop\nreggaeton, gospel, Latin urban\nreggaeton, gospel, ambient\nreggaeton, gothic horror, cinematic\nreggaeton, gothic trap\nreggaeton, guaracha, hard dance\nreggaeton, hard dance\nreggaeton, hardstyle\nreggaeton, hardstyle, R&B\nreggaeton, hardstyle, ambient\nreggaeton, hardstyle, big room house\nreggaeton, hardstyle, chiptune\nreggaeton, hardstyle, cinematic pop\nreggaeton, hardstyle, dembow\nreggaeton, hardstyle, dream pop\nreggaeton, hardstyle, electronic\nreggaeton, hardstyle, emotional\nreggaeton, hardstyle, happy hardcore\nreggaeton, hardstyle, hybrid trap\nreggaeton, hardstyle, lo-fi\nreggaeton, hardstyle, moombahton\nreggaeton, hardstyle, phonk\nreggaeton, hardstyle, psytrance\nreggaeton, hardstyle, tropical\nreggaeton, hardstyle, vaporwave\nreggaeton, hip hop\nreggaeton, hip hop, emotional pop\nreggaeton, hip-hop\nreggaeton, hip-hop, Indian pop\nreggaeton, hip-hop, electronic\nreggaeton, hip-hop, pop-R&B\nreggaeton, horror, spooky\nreggaeton, house, Latin house\nreggaeton, hyperpop\nreggaeton, hyperpop, Brazilian funk\nreggaeton, hyperpop, Latin pop\nreggaeton, hyperpop, R&B\nreggaeton, hyperpop, ambient\nreggaeton, hyperpop, breakcore\nreggaeton, hyperpop, chiptune\nreggaeton, hyperpop, cinematic\nreggaeton, hyperpop, electronic\nreggaeton, hyperpop, emo trap\nreggaeton, hyperpop, future bass\nreggaeton, hyperpop, glitch-pop\nreggaeton, hyperpop, hardstyle\nreggaeton, hyperpop, synth-pop\nreggaeton, hyperpop, trap\nreggaeton, hyperpop, vaporwave\nreggaeton, industrial trap, electronic\nreggaeton, industrial, cinematic\nreggaeton, jersey club\nreggaeton, latin R&B, ambient\nreggaeton, latin house, dream pop\nreggaeton, latin pop\nreggaeton, latin pop, R&B\nreggaeton, latin pop, ambient\nreggaeton, latin pop, chillwave\nreggaeton, latin pop, cinematic\nreggaeton, latin pop, contemporary Christian\nreggaeton, latin pop, contemporary R&B\nreggaeton, latin pop, cumbia\nreggaeton, latin pop, dream pop\nreggaeton, latin pop, dreamy\nreggaeton, latin pop, electronic\nreggaeton, latin pop, emotional\nreggaeton, latin pop, hyperpop\nreggaeton, latin pop, lo-fi\nreggaeton, latin pop, lo-fi synth\nreggaeton, latin pop, modern R&B\nreggaeton, latin trap\nreggaeton, latin trap, ambient\nreggaeton, latin trap, atmospheric\nreggaeton, latin trap, cinematic\nreggaeton, latin trap, dream pop\nreggaeton, latin trap, electronic\nreggaeton, latin trap, lo-fi\nreggaeton, latin trap, moombahton\nreggaeton, latin trap, pop\nreggaeton, latin urban, R&B\nreggaeton, lo-fi hip hop\nreggaeton, lo-fi hip hop, sample-based\nreggaeton, lo-fi pop\nreggaeton, lo-fi pop, R&B\nreggaeton, lo-fi trap\nreggaeton, lo-fi trap, cloud rap\nreggaeton, lo-fi, Arabic ambient\nreggaeton, lo-fi, Arabic pop\nreggaeton, lo-fi, Brazilian funk\nreggaeton, lo-fi, Latin pop\nreggaeton, lo-fi, Middle Eastern\nreggaeton, lo-fi, R&B\nreggaeton, lo-fi, ambient\nreggaeton, lo-fi, chiptune\nreggaeton, lo-fi, cinematic\nreggaeton, lo-fi, dark\nreggaeton, lo-fi, dream pop\nreggaeton, lo-fi, electronic\nreggaeton, lo-fi, emotional\nreggaeton, lo-fi, emotional trap\nreggaeton, lo-fi, experimental\nreggaeton, lo-fi, future bass\nreggaeton, lo-fi, glitch\nreggaeton, lo-fi, global pop\nreggaeton, lo-fi, hyperpop\nreggaeton, lo-fi, latin pop\nreggaeton, lo-fi, melancholic\nreggaeton, lo-fi, pop\nreggaeton, lo-fi, romantic pop\nreggaeton, lo-fi, synthwave\nreggaeton, lo-fi, vaporwave\nreggaeton, melancholic, Eastern European\nreggaeton, melancholic, Latin pop\nreggaeton, melancholic, R&B\nreggaeton, melancholic, chiptune\nreggaeton, melbourne bounce, latin pop\nreggaeton, merengue, Latin pop\nreggaeton, merengue, bachata\nreggaeton, minimal house\nreggaeton, minimalist synth\nreggaeton, minimalist, chiptune\nreggaeton, moombahton\nreggaeton, moombahton, Balkan pop\nreggaeton, moombahton, EDM\nreggaeton, moombahton, Latin dance-pop\nreggaeton, moombahton, Latin house\nreggaeton, moombahton, R&B\nreggaeton, moombahton, big room house\nreggaeton, moombahton, chiptune\nreggaeton, moombahton, cinematic\nreggaeton, moombahton, cinematic pop\nreggaeton, moombahton, dancehall\nreggaeton, moombahton, electronic\nreggaeton, moombahton, electronic dance\nreggaeton, moombahton, future bass\nreggaeton, moombahton, hard electronic\nreggaeton, moombahton, hardstyle\nreggaeton, moombahton, hyperpop\nreggaeton, moombahton, lo-fi\nreggaeton, moombahton, pop\nreggaeton, moombahton, pop-rap\nreggaeton, moombahton, trap\nreggaeton, neo-soul, R&B\nreggaeton, neo-soul, cinematic\nreggaeton, new age, world music\nreggaeton, nightcore\nreggaeton, nightcore, hyperpop\nreggaeton, nu-metal, dream pop\nreggaeton, orchestral, Latin pop\nreggaeton, orchestral, Latin trap\nreggaeton, orchestral, cinematic\nreggaeton, party anthem\nreggaeton, party rap\nreggaeton, party, electronic\nreggaeton, party, global dance\nreggaeton, phonk, lo-fi\nreggaeton, pop\nreggaeton, pop, Latin dance\nreggaeton, pop, Middle Eastern\nreggaeton, pop, North African\nreggaeton, pop, R&B\nreggaeton, pop, South Asian pop\nreggaeton, pop, chiptune\nreggaeton, pop, hyperpop\nreggaeton, pop, lo-fi\nreggaeton, pop-R&B, Middle Eastern\nreggaeton, pop-dancehall, electronic\nreggaeton, pop-punk, R&B\nreggaeton, pop-rap, cumbia\nreggaeton, pop-reggaeton\nreggaeton, pop-reggaeton, R&B-reggaeton\nreggaeton, psychedelic, hyperpop\nreggaeton, rap\nreggaeton, reggae-pop\nreggaeton, regional Mexican\nreggaeton, retrowave\nreggaeton, romantic, Spanish\nreggaeton, romantic, melancholic\nreggaeton, sad trap\nreggaeton, sad trap, Latin R&B\nreggaeton, sad-pop\nreggaeton, salsa, chiptune\nreggaeton, salsa, lo-fi hip hop\nreggaeton, salsa, rap\nreggaeton, satirical, electronic\nreggaeton, sci-fi, cinematic\nreggaeton, sci-fi, cosmic\nreggaeton, sentimental Latin pop\nreggaeton, ska-punk, chiptune\nreggaeton, slap house, Brazilian bass\nreggaeton, slap house, Latin urban\nreggaeton, spooky, trap\nreggaeton, synth pop\nreggaeton, synth, chiptune\nreggaeton, synth-pop\nreggaeton, synth-pop, Latin pop\nreggaeton, synth-pop, R&B\nreggaeton, synth-pop, chiptune\nreggaeton, synth-pop, future bass, R&B\nreggaeton, synth-pop, vaporwave\nreggaeton, synthpop, auto-tune\nreggaeton, synthwave\nreggaeton, synthwave, chiptune\nreggaeton, tango, folk fusion\nreggaeton, tech house\nreggaeton, tech house, Latin\nreggaeton, tech-house, moombahton\nreggaeton, techno, ambient\nreggaeton, theatrical pop\nreggaeton, trap\nreggaeton, trap R&B\nreggaeton, trap, Latin R&B\nreggaeton, trap, R&B\nreggaeton, trap, ambient\nreggaeton, trap, ballad\nreggaeton, trap, chiptune\nreggaeton, trap, cloud rap\nreggaeton, trap, dancehall\nreggaeton, trap, dark\nreggaeton, trap, dark ambient\nreggaeton, trap, future bass\nreggaeton, trap, hardstyle\nreggaeton, trap, hyperpop\nreggaeton, trap, melancholic\nreggaeton, trap, moombahton\nreggaeton, trap, pop\nreggaeton, trap, vaporwave\nreggaeton, tropical pop, Southeast Asian pop\nreggaeton, urban Latin pop\nreggaeton, urban pop\nreggaeton, vaporwave\nreggaeton, vaporwave, Latin pop\nreggaeton, vaporwave, Latin urban\nreggaeton, vaporwave, R&B\nreggaeton, vaporwave, ambient\nreggaeton, vaporwave, atmospheric R&B\nreggaeton, vaporwave, electronic\nreggaeton, vaporwave, hardstyle\nreggaeton, vaporwave, latin pop\nreggaeton, vaporwave, lo-fi\nreggaeton, vaporwave, metalcore\nreggaeton, vaporwave, pop\nreggaeton, vaporwave, psychedelic\nreggaeton, vaporwave, trap\nreggaeton, vaporwave, urban pop\nreggaeton, world fusion, cinematic\nreggaeton, world music\nreggaeton-house, neo-soul, ambient\nreggaeton-lite\nreggaeton-pop\nreggaeton-pop dream pop\nreggaeton-pop future bass\nreggaeton-pop lo-fi\nreggaeton-pop tropical house\nreggaeton-pop, R&B\nreggaeton-rock\nreggaeton-trap\nregional Chinese hip-hop\nregional Mexican\nregional Mexican ballad\nregional Mexican bolero\nregional Mexican chiptune\nregional Mexican corrido\nregional Mexican cumbia\nregional Mexican cumbia hip-hop\nregional Mexican cumbia, electronic dance music\nregional Mexican dembow\nregional Mexican folk\nregional Mexican funk\nregional Mexican fusion\nregional Mexican gangsta rap\nregional Mexican hip-hop\nregional Mexican lo-fi hip-hop\nregional Mexican polka\nregional Mexican pop\nregional Mexican pop-country\nregional Mexican pop-rock\nregional Mexican rap\nregional Mexican rock\nregional Mexican ska\nregional Mexican surf rock\nregional Mexican surf-rock\nregional Mexican swing jazz\nregional Mexican trap\nregional Mexican tumbado\nregional Mexican waltz\nregional Mexican, Balkan brass\nregional Mexican, Christian hip-hop\nregional Mexican, Latin pop\nregional Mexican, acoustic hip-hop\nregional Mexican, banda, norteño\nregional Mexican, big band jazz\nregional Mexican, bluegrass\nregional Mexican, chiptune\nregional Mexican, cinematic, melancholic\nregional Mexican, comedy, norteño parody\nregional Mexican, corrido, hip-hop\nregional Mexican, flamenco\nregional Mexican, hip-hop\nregional Mexican, hyperpop\nregional Mexican, lo-fi hip hop\nregional Mexican, ska, acoustic\nregional Mexican, theatrical\nregional Mexican, trap\nregional Mexican, urban pop\nregional anthem\nregional club\nregional hip-hop\nregional house\nregional mexican\nregional pop\nregional pop ballad\nregional pop-rock\nreligious\nreligious pop\nreligious rock\nrelyinga\nrepinera\nretro\nretro 80s\nretro Bollywood\nretro Bollywood pop\nretro C-pop\nretro C-pop V-pop\nretro C-pop chiptune\nretro C-pop surf rock\nretro C-pop world music\nretro Cantopop\nretro Chinese children's\nretro Chinese dance-pop\nretro Chinese pop\nretro Christian cumbia\nretro Christian worship\nretro Christmas\nretro Christmas pop\nretro Christmas pop, hard rock\nretro Christmas pop, heavy metal\nretro Christmas pop-rock\nretro Christmas rock\nretro Christmas rock and roll\nretro European\nretro European pop\nretro German pop\nretro Indian film\nretro Indian film score\nretro Indian pop\nretro Indian rock\nretro Israeli pop\nretro Italian disco-pop\nretro Italian pop\nretro Italian swing\nretro J-rock\nretro K-pop\nretro K-pop, Eurodance\nretro K-pop, trot, theatrical pop\nretro Korean funk, new jack swing\nretro Korean rock\nretro Korean synth-pop\nretro Korean trot\nretro Korean trot-pop\nretro Mandopop\nretro Mandopop exotica\nretro Mandopop rock\nretro Mandopop, Chinese folk, theatrical\nretro Mandopop, Latin disco\nretro Nepali pop\nretro R&B\nretro R&B K-pop\nretro R&B chiptune\nretro R&B hip-hop\nretro R&B pop\nretro Romanian pop\nretro Russian pop\nretro South Asian film music\nretro South Asian pop\nretro Soviet estrada\nretro Soviet pop\nretro Soviet pop-rock\nretro Soviet swing\nretro TV theme\nretro V-Pop\nretro V-pop\nretro Vietnamese children's\nretro Vietnamese pop\nretro Zouk\nretro animation\nretro ballad\nretro big band\nretro brass\nretro breakbeat\nretro cartoon\nretro chanson\nretro children's\nretro children's music\nretro children's pop\nretro chiptune\nretro cumbia\nretro dance\nretro dance-pop\nretro devotional\nretro devotional dance\nretro digital\nretro digital hymn\nretro digital pop\nretro digital, South Asian, Bengali pop\nretro doo-wop\nretro easy-listening\nretro educational\nretro electro\nretro electronic\nretro electronic pop\nretro electronic, Middle Eastern folk\nretro electronic, Middle Eastern fusion\nretro electronic, Middle Eastern pop\nretro electronic, Middle Eastern, South Asian\nretro electronic, Southeast Asian fusion\nretro electronic, chiptune, Southeast Asian fusion\nretro electronica\nretro fitness\nretro funk\nretro funk disco\nretro funk pop\nretro funk, big band, children's music\nretro funk, disco, Tamil film score\nretro funk, disco, children's music\nretro funk, ska, children's music\nretro funk, synth-pop, children's music\nretro funk-pop\nretro game\nretro game music\nretro game show\nretro garage rock\nretro hip hop\nretro hip-hop\nretro hip-hop reggae\nretro holiday\nretro house\nretro instrumental\nretro jazz\nretro jingle\nretro jive\nretro lounge\nretro lounge pop\nretro lounge-pop\nretro mambo\nretro mambo salsa\nretro new wave\nretro novelty\nretro orchestral\nretro pop\nretro pop chiptune\nretro pop cumbia\nretro pop doo-wop\nretro pop exotica\nretro pop lounge\nretro pop lounge jazz\nretro pop neo-soul\nretro pop surf rock\nretro pop, 80s South Asian film\nretro pop, Central Asian folk\nretro pop, G-funk, North African pop\nretro pop, Halloween, cartoon\nretro pop, Latin pop\nretro pop, Latin, Eastern European\nretro pop, Middle Eastern, Eastern European\nretro pop, OPM, surf rock\nretro pop, South Asian pop\nretro pop, South Asian, 80s film\nretro pop, South Indian pop\nretro pop, Southeast Asian pop\nretro pop, Sundanese pop\nretro pop, chanson, levenslied\nretro pop, chiptune, Brazilian pop\nretro pop, chiptune, South Asian film music\nretro pop, estrada\nretro pop, estrada, Central Asian\nretro pop, estrada, folk\nretro pop, estrada, theatrical\nretro pop, funk, Turkish pop\nretro pop, hyperpop\nretro pop, rock and roll, Hawaiian\nretro pop, schlager\nretro pop, surf rock, novelty\nretro pop, surf rock, rockabilly\nretro pop, theatrical pop\nretro pop, theatrical pop, estrada\nretro pop, world music\nretro pop-funk\nretro pop-rock\nretro pop-schlager\nretro pop-ska\nretro pop-soul\nretro pop-swing\nretro reggae\nretro reggaeton\nretro rock\nretro rock 'n' roll\nretro rock 'n' roll, schlager, novelty Christmas\nretro rock 'n' roll, swing, children's music\nretro rock and roll\nretro rock and roll boogie-woogie\nretro rock and roll soul\nretro rock and roll, Schlager, children's music\nretro rock and roll, big band, novelty\nretro rock and roll, doo-wop, children's music\nretro rock doo-wop\nretro rock soul\nretro rock, Bollywood, South Asian\nretro rock, French pop\nretro rock, Italian pop-rock, surf rock\nretro rock, big band, swing\nretro rock, estrada\nretro rock, rockabilly, soul\nretro rock, soul, rockabilly\nretro rock, surf rock, Chinese New Year\nretro rock, surf rock, novelty\nretro salsa\nretro ska\nretro soca\nretro soul\nretro soul Latin jazz\nretro soul a cappella\nretro soul funk\nretro soul jazz-pop\nretro soul power ballad\nretro sports anthem\nretro spy\nretro surf rock\nretro swing\nretro swing Mandopop\nretro swing jazz\nretro swing jingle\nretro swing lounge\nretro swing pop\nretro swing trot\nretro synth\nretro synth Christmas\nretro synth pop\nretro synth, Bollywood, video game\nretro synth, devotional, festive\nretro synth-pop\nretro synthwave\nretro techno\nretro trot\nretro video game\nretro video game music\nretro video game, Middle Eastern folk\nretro video game, Middle Eastern fusion\nretro wave\nretro-dance Indian pop\nretro-digital\nretro-disco C-pop\nretro-electro\nretro-electronic\nretro-electronic chiptune\nretro-funk\nretro-funk Bollywood\nretro-funk Bollywood disco\nretro-funk C-pop\nretro-funk French hip-hop\nretro-funk G-funk\nretro-funk Indian film\nretro-funk Indian film music\nretro-funk K-pop\nretro-funk Mandopop\nretro-funk R&B\nretro-funk chiptune\nretro-funk city pop\nretro-funk city pop neo-soul\nretro-funk city-pop\nretro-funk dance-pop\nretro-funk disco\nretro-funk disco-pop\nretro-funk hip-hop\nretro-funk indie pop\nretro-funk lo-fi\nretro-funk lounge\nretro-funk neo-soul\nretro-funk new jack swing\nretro-funk nu-disco\nretro-funk pop\nretro-funk pop-rock\nretro-funk rock\nretro-funk schlager\nretro-funk smooth jazz\nretro-funk soul\nretro-funk space disco\nretro-funk synth-pop\nretro-funk, 80s Indian film music\nretro-funk, Arabic pop\nretro-funk, Arabic, dance\nretro-funk, Bollywood disco, 80s\nretro-funk, Bollywood disco, lo-fi synth\nretro-funk, Bollywood pop, old-school hip-hop\nretro-funk, Bollywood, Indian folk\nretro-funk, Bollywood, Latin\nretro-funk, Bollywood, dance\nretro-funk, Bollywood, disco\nretro-funk, City Pop, Mandopop\nretro-funk, French house\nretro-funk, G-funk\nretro-funk, Indian film music, electronic\nretro-funk, Indian pop\nretro-funk, Indipop\nretro-funk, Italo-disco, Persian pop\nretro-funk, Italo-disco, synth-pop\nretro-funk, K-pop\nretro-funk, K-pop, J-pop\nretro-funk, K-pop, new jack swing\nretro-funk, K-pop, trot\nretro-funk, Korean trot\nretro-funk, North African pop, 80s synth\nretro-funk, R&B, lo-fi hip hop\nretro-funk, Schlager, theatrical pop\nretro-funk, South Asian film music, disco\nretro-funk, South Asian, upbeat\nretro-funk, South Indian film music\nretro-funk, South Indian film music, 80s pop\nretro-funk, South Indian pop, hip-hop\nretro-funk, South Indian, upbeat\nretro-funk, chiptune, 80s Korean synth-pop\nretro-funk, chiptune, Mandopop\nretro-funk, cinematic, Hindi pop\nretro-funk, cinematic, Indian fusion\nretro-funk, cinematic, Vietnamese pop\nretro-funk, cinematic, chiptune\nretro-funk, city pop\nretro-funk, city pop, 90s funk\nretro-funk, city pop, K-pop\nretro-funk, city pop, afrobeat\nretro-funk, city pop, disco-funk\nretro-funk, city pop, new jack swing\nretro-funk, city pop, nu-disco\nretro-funk, city pop, trot\nretro-funk, city pop, trot-funk\nretro-funk, city pop, vaporwave\nretro-funk, city-pop\nretro-funk, dance-pop, Bollywood\nretro-funk, dance-pop, Latin-infused\nretro-funk, electro-funk, G-funk\nretro-funk, electro-funk, chiptune\nretro-funk, electro-funk, nu-disco\nretro-funk, filmi, dance\nretro-funk, hip-hop, G-funk\nretro-funk, hip-hop, electronic\nretro-funk, hip-hop, soul\nretro-funk, hip-house, new jack swing\nretro-funk, neo-soul, hip-hop\nretro-funk, new jack swing\nretro-funk, new jack swing, G-funk\nretro-funk, new jack swing, K-pop\nretro-funk, new jack swing, city pop\nretro-funk, new jack swing, dance-pop\nretro-funk, new jack swing, synth-funk\nretro-funk, new jack swing, synth-pop\nretro-funk, new jack swing, synthwave\nretro-funk, pop, South Asian\nretro-funk, soul, Vietnamese fusion\nretro-funk, soul, Vietnamese pop\nretro-funk, synth-pop\nretro-funk, synth-pop, Bollywood\nretro-funk, synth-pop, Neue Deutsche Welle\nretro-funk, synth-pop, disco-funk\nretro-funk, trot, brass\nretro-funk, video game soundtrack\nretro-funk, worldbeat, South Indian film music\nretro-futuristic\nretro-futuristic C-pop\nretro-futuristic Christmas\nretro-futuristic Indian film score\nretro-futuristic R&B\nretro-futuristic South Asian pop\nretro-futuristic chiptune\nretro-futuristic cumbia\nretro-futuristic dance\nretro-futuristic dance-pop\nretro-futuristic electro-funk\nretro-futuristic electronic\nretro-futuristic hip-hop\nretro-futuristic house\nretro-futuristic lounge\nretro-futuristic swing\nretro-futuristic synth\nretro-futuristic synth-pop\nretro-futuristic synthwave\nretro-futuristic techno\nretro-pop\nretro-pop Balkan\nretro-pop Balkan disco\nretro-pop Bollywood\nretro-pop C-pop\nretro-pop French chanson\nretro-pop Indian film\nretro-pop Indian film music\nretro-pop Indian filmi\nretro-pop J-pop\nretro-pop K-pop\nretro-pop Kannada film music\nretro-pop Kollywood\nretro-pop Latin\nretro-pop Latin exotica\nretro-pop MPB\nretro-pop Soviet estrada\nretro-pop V-pop\nretro-pop anime\nretro-pop big band\nretro-pop bossa nova\nretro-pop cabaret\nretro-pop cantopop\nretro-pop chanson\nretro-pop children's music\nretro-pop chiptune\nretro-pop cumbia\nretro-pop cumbia ska\nretro-pop devotional\nretro-pop disco-funk\nretro-pop doo-wop\nretro-pop doo-wop swing\nretro-pop estrada\nretro-pop exotica\nretro-pop exotica lounge\nretro-pop funk\nretro-pop funk disco\nretro-pop korean trot\nretro-pop latin\nretro-pop lounge\nretro-pop lounge exotica\nretro-pop mambo\nretro-pop neo-soul\nretro-pop new jack swing\nretro-pop reggae\nretro-pop rockabilly\nretro-pop rockabilly swing\nretro-pop romanian rock\nretro-pop schlager\nretro-pop soul\nretro-pop surf rock\nretro-pop surf-rock\nretro-pop swing lounge\nretro-pop trot\nretro-pop trot disco\nretro-pop worldbeat\nretro-pop, 80s soul, funk\nretro-pop, 80s, South Asian film music\nretro-pop, 90s K-pop, City Pop\nretro-pop, 90s K-pop, anime OST\nretro-pop, Bollywood, disco\nretro-pop, Brazilian, upbeat\nretro-pop, City Pop, K-pop\nretro-pop, Eastern European folk\nretro-pop, Indian film music, 80s pop\nretro-pop, K-pop, City Pop\nretro-pop, Korean trot\nretro-pop, Korean trot, 80s\nretro-pop, Latin-pop, Tamil pop\nretro-pop, Mandopop, Taiwanese Hokkien pop\nretro-pop, Neue Deutsche Welle\nretro-pop, R&B, Christmas\nretro-pop, Schlager\nretro-pop, South Asian film music\nretro-pop, South Indian film music\nretro-pop, Soviet estrada, big band\nretro-pop, Soviet-era estrada\nretro-pop, Vietnamese bolero, chiptune\nretro-pop, big band, swing\nretro-pop, boogie-woogie, big band\nretro-pop, chanson, schlager\nretro-pop, chiptune, Arabic pop\nretro-pop, chiptune, Indian film music\nretro-pop, cinematic, Eastern European\nretro-pop, cinematic, South Asian pop\nretro-pop, cinematic, tropical\nretro-pop, doo-wop, rock and roll\nretro-pop, estrada, Central Asian\nretro-pop, estrada, Soviet\nretro-pop, estrada, Soviet-era\nretro-pop, estrada, cinematic\nretro-pop, estrada, synth-pop\nretro-pop, estrada, theatrical\nretro-pop, euro-pop, italo-disco\nretro-pop, filmi, 80s\nretro-pop, filmi, synthwave\nretro-pop, funk, Korean trot\nretro-pop, hyper-pop\nretro-pop, new wave\nretro-pop, new wave, Eastern European\nretro-pop, schlager, exotica\nretro-pop, synth-funk, Indian film music\nretro-pop, synth-funk, city pop\nretro-pop, synth-pop, lo-fi\nretro-pop, synth-pop, trot\nretro-pop, theatrical pop, Balkan pop\nretro-pop, theatrical, Soviet-era estrada\nretro-pop-rock\nretro-rock\nretro-rock disco-pop\nretro-samba\nretro-samba pop\nretro-samba rock\nretro-samba-pop\nretro-schlager\nretro-ska\nretro-soul\nretro-soul German pop\nretro-soul chiptune\nretro-soul doo-wop\nretro-soul funk\nretro-soul funk-pop\nretro-soul lounge\nretro-soul lounge-jazz\nretro-soul pop\nretro-soul rock\nretro-swing\nretro-swing Mandopop\nretro-swing Soviet\nretro-swing Soviet-era estrada\nretro-swing cabaret\nretro-swing estrada\nretro-swing exotica\nretro-swing jazz-pop\nretro-swing klezmer\nretro-swing lounge\nretro-swing pop\nretro-swing rock\nretro-swing tango\nretro-swing trot\nretro-swing, Soviet-era estrada\nretro-swing, hard rock\nretro-wave\nretrowave\nretrowave synth-pop\nretrowave synthwave\nretrowave, synth-pop\nretrowave, synth-pop, 80s\nretrowave, synth-pop, Italo-disco\nrevolutionary Arabic\nrevolutionary C-pop\nrevolutionary Chinese\nrevolutionary Chinese opera\nrevolutionary Middle Eastern\nrevolutionary anthem\nrevolutionary anthem electronic\nrevolutionary choral\nrevolutionary electronic\nrevolutionary folk\nrevolutionary folk rock\nrevolutionary folk-pop\nrevolutionary fusion\nrevolutionary hip-hop\nrevolutionary march\nrevolutionary pop\nrevolutionary rock\nrevolutionary song\nrevolutionary-era Chinese folk\nrevolutionary-style C-pop\nrhythm and blues\nrhythm and blues country-soul\nrhythmic\nriddim\nriddim dubstep\nriddim dubstep trap\nringtone\nritual ambient\nritual chant\nritual choral\nritual drumming\nritual electronic\nritual folk\nritual fusion\nritual hip-hop\nritual house\nritual music\nritual percussion\nritual techno\nritual trance\nritual trap\nritualistic ambient\nritualistic chant\nritualistic electronic\nritualistic folk\nritualistic hip-hop\nritualistic techno\nritualistic trap\nritualistic tribal\nrock\nrock 'n' roll\nrock 'n' roll boogie-woogie\nrock 'n' roll, Nederpop\nrock 'n' roll, Neue Deutsche Welle\nrock 'n' roll, big band, show tune\nrock 'n' roll, boogie-woogie, German rock\nrock 'n' roll, boogie-woogie, Latin rock\nrock 'n' roll, boogie-woogie, blues rock\nrock 'n' roll, boogie-woogie, danseband\nrock 'n' roll, boogie-woogie, rockabilly\nrock 'n' roll, reggae, salsa, disco-funk\nrock 'n' roll, rockabilly, German rock\nrock 'n' roll, yé-yé\nrock Christmas\nrock Kapak\nrock R&B\nrock a cappella\nrock accordion\nrock and roll\nrock and roll a cappella\nrock and roll big band\nrock and roll big band mambo\nrock and roll big band swing\nrock and roll blues shuffle\nrock and roll boogie-woogie\nrock and roll boogie-woogie swing\nrock and roll chiptune\nrock and roll country\nrock and roll country boogie-woogie\nrock and roll country rockabilly\nrock and roll country-pop\nrock and roll doo-wop\nrock and roll exotica\nrock and roll exotica latin\nrock and roll exotica lounge\nrock and roll glam rock\nrock and roll gospel\nrock and roll gospel country\nrock and roll klezmer\nrock and roll latin\nrock and roll outlaw country\nrock and roll punk\nrock and roll rockabilly\nrock and roll rockabilly blues\nrock and roll rockabilly boogie-woogie\nrock and roll rockabilly country\nrock and roll rockabilly doo-wop\nrock and roll rockabilly novelty\nrock and roll schlager\nrock and roll show tune\nrock and roll ska\nrock and roll ska big band\nrock and roll ska boogie-woogie\nrock and roll ska rockabilly\nrock and roll ska sea shanty\nrock and roll ska-punk cumbia\nrock and roll soul\nrock and roll soul R&B\nrock and roll soul big band\nrock and roll soul gospel\nrock and roll surf rock\nrock and roll surf rock mambo\nrock and roll swing\nrock and roll trot\nrock and roll, 60s pop, South Asian pop\nrock and roll, 80s new wave, Christmas\nrock and roll, Balkan folk\nrock and roll, French pop, vintage Christmas\nrock and roll, Latin rock\nrock and roll, Latin rock, 60s garage\nrock and roll, Latin rock, boogie-woogie\nrock and roll, Latin rock, rockabilly\nrock and roll, Latin, boogie-woogie\nrock and roll, Latin, early rock\nrock and roll, Latin, exotica\nrock and roll, Latin, vintage\nrock and roll, Nederpop\nrock and roll, New Orleans R&B, boogie-woogie\nrock and roll, R&B, doo-wop\nrock and roll, R&B, jump blues\nrock and roll, Schlager\nrock and roll, ambient, acoustic\nrock and roll, ballad, children's music\nrock and roll, beat music, Latin rock\nrock and roll, big band swing, theatrical\nrock and roll, big band swing, vintage\nrock and roll, big band, Christmas\nrock and roll, big band, Latin\nrock and roll, big band, Soviet estrada\nrock and roll, big band, boogie-woogie\nrock and roll, big band, brass rock\nrock and roll, big band, jump blues\nrock and roll, big band, mambo\nrock and roll, big band, rockabilly\nrock and roll, big band, ska\nrock and roll, big band, soul\nrock and roll, big band, soul revue\nrock and roll, big band, swing\nrock and roll, big band, theatrical\nrock and roll, big-band swing, retro\nrock and roll, blues, rockabilly\nrock and roll, boogie-woogie\nrock and roll, boogie-woogie, Latin\nrock and roll, boogie-woogie, Latin rock\nrock and roll, boogie-woogie, New Orleans\nrock and roll, boogie-woogie, R&B\nrock and roll, boogie-woogie, big band\nrock and roll, boogie-woogie, bilingual\nrock and roll, boogie-woogie, blues\nrock and roll, boogie-woogie, country rock\nrock and roll, boogie-woogie, jump blues\nrock and roll, boogie-woogie, novelty\nrock and roll, boogie-woogie, pub rock\nrock and roll, boogie-woogie, punk\nrock and roll, boogie-woogie, rockabilly\nrock and roll, boogie-woogie, sax-driven\nrock and roll, boogie-woogie, ska\nrock and roll, boogie-woogie, soul\nrock and roll, boogie-woogie, soul revue\nrock and roll, boogie-woogie, surf rock\nrock and roll, boogie-woogie, swing\nrock and roll, boogie-woogie, theatrical\nrock and roll, boogie-woogie, vintage\nrock and roll, calypso, novelty\nrock and roll, classical, choral\nrock and roll, country, rockabilly\nrock and roll, cumbia, Latin\nrock and roll, cumbia, Latin rock\nrock and roll, cumbia, rockabilly\nrock and roll, doo-wop, blues\nrock and roll, doo-wop, early soul\nrock and roll, doo-wop, honky-tonk\nrock and roll, doo-wop, jump blues\nrock and roll, doo-wop, novelty\nrock and roll, doo-wop, retro\nrock and roll, doo-wop, retro Christmas\nrock and roll, doo-wop, rockabilly\nrock and roll, doo-wop, soul\nrock and roll, doo-wop, vintage\nrock and roll, doo-wop, vintage ballad\nrock and roll, doo-wop, vintage pop\nrock and roll, exotica, Latin\nrock and roll, exotica, mambo\nrock and roll, gospel, rockabilly\nrock and roll, jump blues\nrock and roll, jump blues, big band\nrock and roll, jump blues, boogie-woogie\nrock and roll, jump blues, rockabilly\nrock and roll, jump blues, swing\nrock and roll, mambo, big band\nrock and roll, new wave\nrock and roll, novelty, big band\nrock and roll, pub rock, rockabilly\nrock and roll, rockabilly\nrock and roll, rockabilly, 60s\nrock and roll, rockabilly, 60s Danish\nrock and roll, rockabilly, 60s rock\nrock and roll, rockabilly, Christmas\nrock and roll, rockabilly, Danish\nrock and roll, rockabilly, Italian\nrock and roll, rockabilly, Italian rock\nrock and roll, rockabilly, Latin\nrock and roll, rockabilly, Latin rock\nrock and roll, rockabilly, Nederpop\nrock and roll, rockabilly, R&B\nrock and roll, rockabilly, Romanian pop\nrock and roll, rockabilly, Spanish rock\nrock and roll, rockabilly, big band\nrock and roll, rockabilly, big band, boogie-woogie\nrock and roll, rockabilly, blues\nrock and roll, rockabilly, blues rock\nrock and roll, rockabilly, bolero\nrock and roll, rockabilly, boogie-woogie\nrock and roll, rockabilly, children's music\nrock and roll, rockabilly, cinematic\nrock and roll, rockabilly, country\nrock and roll, rockabilly, country rock\nrock and roll, rockabilly, country-rock\nrock and roll, rockabilly, doo-wop\nrock and roll, rockabilly, early rock\nrock and roll, rockabilly, honky-tonk\nrock and roll, rockabilly, jump blues\nrock and roll, rockabilly, musical theater\nrock and roll, rockabilly, norteño\nrock and roll, rockabilly, pub rock\nrock and roll, rockabilly, punk\nrock and roll, rockabilly, punk rock\nrock and roll, rockabilly, retro\nrock and roll, rockabilly, retro swing\nrock and roll, rockabilly, schlager\nrock and roll, rockabilly, ska\nrock and roll, rockabilly, soul\nrock and roll, rockabilly, surf rock\nrock and roll, rockabilly, swing\nrock and roll, rockabilly, theatrical\nrock and roll, rockabilly, vintage\nrock and roll, rockabilly, vintage pop\nrock and roll, rockabilly, vintage swing\nrock and roll, schlager\nrock and roll, schlager, polka\nrock and roll, schlager, rockabilly\nrock and roll, show tune, rockabilly\nrock and roll, ska, Latin rock\nrock and roll, ska, swing\nrock and roll, soul, R&B\nrock and roll, soul, rockabilly\nrock and roll, surf rock, big band\nrock and roll, surf rock, exotica\nrock and roll, surf rock, rockabilly\nrock and roll, swing blues, boogie-woogie\nrock and roll, swing, novelty\nrock and roll, theatrical rock\nrock and roll, theatrical, boogie-woogie\nrock and roll, theatrical, vintage\nrock and roll, vintage Italian swing, big band\nrock and roll, vintage, big band\nrock and roll, vintage, novelty\nrock and roll, vintage, show tune\nrock ballad\nrock ballad cumbia\nrock ballad world music\nrock ballad, Dangdut Koplo, Funkot\nrock ballad, Indonesian pop\nrock ballad, Indonesian pop, Dangdut\nrock ballad, Javanese pop\nrock ballad, Malay pop\nrock ballad, Malay pop, Indonesian pop\nrock ballad, Middle Eastern, cinematic\nrock ballad, Middle Eastern, pop-rock\nrock ballad, Pop Melayu\nrock ballad, Pop Melayu, Dangdut\nrock ballad, Southeast Asian pop-rock\nrock ballad, boogie-woogie, blues rock\nrock ballad, campursari, theatrical rock\nrock ballad, cinematic rock, rap-rock\nrock ballad, classic rock, dangdut koplo\nrock ballad, dangdut\nrock ballad, dangdut koplo\nrock ballad, dangdut koplo, blues rock\nrock ballad, dangdut, Javanese\nrock ballad, dangdut, cinematic\nrock ballad, dangdut, symphonic metal\nrock ballad, disco-pop\nrock ballad, estrada, Eastern European\nrock ballad, flamenco rock, hard rock\nrock ballad, happy hardcore, hardstyle\nrock ballad, hard rock\nrock ballad, hard rock, thrash metal\nrock ballad, hip-hop\nrock ballad, metalcore\nrock ballad, metalcore, theatrical rock\nrock ballad, pop melayu\nrock ballad, rap-rock, cinematic\nrock ballad, rap-rock, shred guitar\nrock ballad, ska-punk\nrock ballad, trot\nrock ballad, trot, cinematic rock\nrock ballad, world music fusion\nrock blues\nrock boeremusiek\nrock boogie\nrock boogie-woogie\nrock chiptune\nrock cumbia\nrock dangdut\nrock dangdut koplo\nrock dangdut surf rock\nrock drum\nrock drum and bass\nrock drum solo\nrock drumming\nrock dubstep\nrock edm\nrock electronicore\nrock en español\nrock en español punk\nrock en español punk rock\nrock en español punk ska\nrock en español ska\nrock en español ska rockabilly\nrock en español surf rock\nrock en español, country-rock\nrock en español, new wave\nrock en español, new wave, psychedelic cumbia\nrock en español, rockabilly\nrock en español, rockabilly, surf rock\nrock en español, surf rock\nrock epic\nrock español\nrock fiddle\nrock funk\nrock funk blues\nrock funk hip-hop\nrock fusion\nrock gospel\nrock gospel blues\nrock hip hop\nrock hip-hop\nrock hip-hop cinematic\nrock hip-hop fusion\nrock italiano\nrock jangle-pop\nrock kapak\nrock latino\nrock mambo\nrock mariachi\nrock melayu\nrock metal\nrock n' roll\nrock norteño\nrock opera\nrock opera funk\nrock opera, cinematic, Brazilian rock\nrock opera, hard rock, metal\nrock opera, symphonic metal\nrock opera, theatrical rock, cinematic rock\nrock piano\nrock polka cumbia\nrock pop funk\nrock power ballad\nrock punk\nrock rap\nrock reggae\nrock reggae ska\nrock reggaeton\nrock soul\nrock steady\nrock swing\nrock tango\nrock theater\nrock trance\nrock trap\nrock trot\nrock trot-rock\nrock violin\nrock world fusion\nrock worship\nrock'n'roll\nrock, Anatolian folk\nrock, Anatolian, cinematic\nrock, Anatolian, duduk\nrock, Anatolian, emotional\nrock, Arabic rock\nrock, Arabic, cinematic\nrock, Arabic, flamenco\nrock, Arabic, ney\nrock, Azerbaijani, power ballad\nrock, Balkan folk\nrock, Balkan folk, Middle Eastern\nrock, Balkan folk, cinematic\nrock, Balkan folk, emotional\nrock, Balkan, polka\nrock, Bengali folk, surf-rock\nrock, Brazilian percussion\nrock, Brazilian pop-rock, Axé\nrock, Brazilian rock\nrock, C-pop\nrock, C-pop, Ancient Style\nrock, C-pop, Asian fusion\nrock, C-pop, ancient style\nrock, C-pop, chiptune\nrock, C-pop, cinematic\nrock, C-pop, electronic\nrock, C-pop, experimental\nrock, C-pop, flamenco\nrock, C-pop, folk fusion\nrock, C-pop, fusion\nrock, C-pop, metalcore\nrock, C-pop, traditional Chinese\nrock, C-pop, traditional fusion\nrock, C-pop, wuxia\nrock, Chinese folk\nrock, Chinese folk, cinematic\nrock, Chinese folk, electronic\nrock, Chinese folk, epic\nrock, Chinese folk, fusion\nrock, Chinese folk, hard rock\nrock, Chinese folk, instrumental\nrock, Chinese fusion\nrock, Chinese fusion, cinematic\nrock, Chinese fusion, dubstep\nrock, Chinese fusion, wuxia\nrock, Chinese opera, blues\nrock, Chinese opera, cinematic\nrock, Chinese opera, fusion\nrock, Chinese rock\nrock, Chinese traditional\nrock, Chinese traditional, blues-rock\nrock, Chinese traditional, cinematic\nrock, Chinese traditional, hard rock\nrock, Chinese traditional, instrumental\nrock, Chinese, anthem\nrock, Chinese, electric\nrock, Chinese, epic\nrock, Christian rock, Hindi rock\nrock, East Asian fusion\nrock, East Asian fusion, cinematic\nrock, East Asian, cinematic\nrock, East Asian, instrumental\nrock, Eastern European folk\nrock, French rap, pop\nrock, Gaúcho folk, surf rock\nrock, Gaúcho, Brazilian\nrock, Greek folk\nrock, Greek style, cinematic\nrock, Greek, bouzouki\nrock, Halloween, theatrical\nrock, Indian classical\nrock, Indian classical fusion\nrock, Indian classical, acoustic\nrock, Indian classical, alternative\nrock, Indian classical, ambient\nrock, Indian classical, blues rock\nrock, Indian classical, cinematic\nrock, Indian classical, devotional\nrock, Indian classical, electronic\nrock, Indian classical, funk rock\nrock, Indian classical, fusion\nrock, Indian classical, spiritual\nrock, Indian devotional\nrock, Indian devotional, fusion\nrock, Indian devotional, heavy metal\nrock, Indian devotional, pop-rock\nrock, Indian devotional, ritualistic\nrock, Indian film score\nrock, Indian folk\nrock, Indian folk, cinematic\nrock, Indian folk, emotional\nrock, Indian folk, emotive\nrock, Indian folk, patriotic\nrock, Indian fusion\nrock, Indian fusion, blues-rock\nrock, Indian fusion, cinematic\nrock, Indian fusion, hip-hop\nrock, Indian rock\nrock, Indian rock, psychedelic rock\nrock, Indonesian fusion\nrock, Indonesian pop\nrock, Indonesian pop, world fusion\nrock, Indonesian traditional\nrock, J-rock, Christmas\nrock, JRPG, Bengali\nrock, Japanese festival, energetic\nrock, Javanese folk\nrock, Javanese folk, cinematic\nrock, Javanese fusion\nrock, Javanese pop\nrock, Javanese, ballad\nrock, Javanese, cinematic\nrock, Javanese, fusion\nrock, Javanese, melodic\nrock, Javanese, power ballad\nrock, Latin percussion\nrock, Latin pop, theatrical\nrock, Latin rock\nrock, Latin rock, boogie-woogie\nrock, Latin rock, surf rock\nrock, Latin rock, tribal rock\nrock, Latin rock, world music\nrock, Latin trap, R&B\nrock, Latin, South Asian\nrock, Latin, percussion\nrock, Latin, psychedelic\nrock, Latin, world music\nrock, Luk Thung\nrock, Luk Thung, Thai folk\nrock, Luk Thung, dance-rock\nrock, Luk Thung, traditional fusion\nrock, MPB, bossa nova\nrock, MPB, flamenco\nrock, Malay fusion, pop-rock\nrock, Malay pop\nrock, Malay pop, Dangdut\nrock, Malay pop-rock\nrock, Malay traditional\nrock, Mandarin ballad\nrock, Mandarin, cinematic\nrock, Mediterranean fusion\nrock, Melayu pop, fusion\nrock, Middle Eastern folk\nrock, Middle Eastern folk, blues-rock\nrock, Middle Eastern folk, fusion\nrock, Middle Eastern folk, live performance\nrock, Middle Eastern fusion\nrock, Middle Eastern fusion, chiptune\nrock, Middle Eastern fusion, electronic\nrock, Middle Eastern pop, Malay pop\nrock, Middle Eastern rock\nrock, Middle Eastern, Arabic\nrock, Middle Eastern, Balkan\nrock, Middle Eastern, Hebrew\nrock, Middle Eastern, Indonesian\nrock, Middle Eastern, Malay\nrock, Middle Eastern, Malay pop\nrock, Middle Eastern, Malay pop-rock\nrock, Middle Eastern, Turkish\nrock, Middle Eastern, ambient\nrock, Middle Eastern, ballad\nrock, Middle Eastern, blues\nrock, Middle Eastern, blues-rock\nrock, Middle Eastern, cinematic\nrock, Middle Eastern, electric\nrock, Middle Eastern, emotional\nrock, Middle Eastern, experimental\nrock, Middle Eastern, folk\nrock, Middle Eastern, fusion\nrock, Middle Eastern, ghazal\nrock, Middle Eastern, instrumental\nrock, Middle Eastern, microtonal\nrock, Middle Eastern, pop\nrock, Middle Eastern, synth\nrock, Mizrahi, spiritual\nrock, Mor Lam\nrock, Mor Lam, Thai fusion\nrock, Māori, cinematic\nrock, Nepali, cinematic\nrock, Neue Deutsche Welle\nrock, North African folk\nrock, North African fusion\nrock, North African pop\nrock, North African, fusion\nrock, North African, melancholic\nrock, Persian pop-rock\nrock, Persian, cinematic\nrock, Pop Melayu, Dangdut rock\nrock, Russian rap, post-punk\nrock, Schlager, Neue Deutsche Welle\nrock, Sinhala, blues\nrock, South Asian folk\nrock, South Asian folk, blues-rock\nrock, South Asian folk, surf rock\nrock, South Asian fusion\nrock, South Asian pop\nrock, South Asian, patriotic\nrock, South Indian folk, Carnatic rock\nrock, South Indian fusion, electronic\nrock, Southeast Asian folk\nrock, Southeast Asian folk, hard rock\nrock, Southeast Asian fusion\nrock, Southeast Asian pop\nrock, Southeast Asian pop-rock\nrock, Southeast Asian rock\nrock, Spanish folk, live performance\nrock, Sundanese fusion\nrock, Sundanese, fusion\nrock, Sundanese, power ballad\nrock, Taiwanese Hokkien, fusion\nrock, Tamil folk\nrock, Tamil rap\nrock, Thai Mor Lam\nrock, Thai folk\nrock, Thai fusion\nrock, Thai traditional, melodic\nrock, Turkish folk\nrock, Turkish folk, cinematic\nrock, Turkish folk, jazz fusion\nrock, Turkish folk, ney\nrock, Turkish folk, theatrical\nrock, Turkish fusion\nrock, Turkish, Balkan\nrock, Turkish, Middle Eastern\nrock, Turkish, atmospheric\nrock, Turkish, cinematic\nrock, Turkish, emotive\nrock, Turkish, oud\nrock, acoustic ballad\nrock, acoustic ballad, Chinese rock\nrock, acoustic ballad, gospel rock\nrock, acoustic, Mandarin\nrock, alternative, cinematic\nrock, ambient, Indian classical\nrock, ambient, world fusion\nrock, ancient style, cinematic\nrock, ancient style, fusion\nrock, ballad, Indian pop\nrock, ballad, Taiwanese Hokkien\nrock, baroque pop\nrock, baroque, synth\nrock, big band\nrock, big band, surf rock\nrock, big band, swing\nrock, big band, theatrical\nrock, blues rock, folk rock\nrock, blues rock, operatic rock\nrock, blues rock, thrash metal\nrock, blues, Middle Eastern\nrock, blues, Southeast Asian pop\nrock, blues, Turkish rock\nrock, blues, folk\nrock, blues-rock, Hebrew rock\nrock, blues-rock, Nepali\nrock, blues-rock, operatic\nrock, boeremusiek\nrock, boogie-woogie, Latin rock\nrock, boogie-woogie, big band\nrock, boogie-woogie, surf rock\nrock, boogie-woogie, swing\nrock, bossa nova, cinematic\nrock, bossa nova, world fusion\nrock, chanson, cabaret\nrock, chanson, theatrical\nrock, chiptune, Brazilian rock\nrock, chiptune, Hindi pop\nrock, chiptune, J-rock\nrock, chiptune, Mandarin power ballad\nrock, chiptune, Middle Eastern\nrock, chiptune, new wave\nrock, chiptune, pop\nrock, chiptune, punk\nrock, chiptune, synth rock\nrock, chiptune, theatrical\nrock, choral, Mandarin\nrock, choral, blues\nrock, christmas, theatrical\nrock, cinematic, Chinese\nrock, cinematic, Chinese fusion\nrock, cinematic, Hindi ballad\nrock, cinematic, Hindi rock\nrock, cinematic, Indonesian pop-rock\nrock, cinematic, Malay fusion\nrock, cinematic, Malay traditional\nrock, cinematic, Mandarin\nrock, cinematic, Mandarin ballad\nrock, cinematic, Mandarin rock\nrock, cinematic, Middle Eastern\nrock, cinematic, Taiwanese Hokkien\nrock, cinematic, Turkish\nrock, cinematic, ancient style\nrock, cinematic, folk\nrock, cinematic, folk rock\nrock, cinematic, rap-rock\nrock, cinematic, theatrical\nrock, cinematic, traditional Malay\nrock, classical, blues\nrock, classical, cinematic\nrock, complextro, hardstyle\nrock, cumbia, spoken word\nrock, dancehall, R&B\nrock, dangdut\nrock, dangdut koplo\nrock, dangdut koplo, Indonesian pop\nrock, dangdut koplo, Javanese\nrock, dangdut koplo, Javanese folk\nrock, dangdut koplo, Javanese pop\nrock, dangdut, cinematic\nrock, dangdut, pop\nrock, dangdut, surf rock\nrock, dangdut, theatrical\nrock, dangdut, traditional Indonesian\nrock, dangdut, traditional Malay\nrock, devotional, South Asian\nrock, devotional, Telugu\nrock, devotional, ambient\nrock, devotional, fusion\nrock, drum and bass, ambient\nrock, dubstep\nrock, dubstep, Bengali\nrock, dubstep, ambient\nrock, dubstep, electronic\nrock, dubstep, emotional\nrock, dubstep, rap\nrock, dubstep, trap metal\nrock, duduk, cinematic\nrock, electronic dance music\nrock, electronic, Chinese fusion\nrock, electronic, Chinese traditional\nrock, electronic, East Asian fusion\nrock, electronic, Indian devotional\nrock, electronic, Indian fusion\nrock, electronic, Middle Eastern fusion\nrock, electronic, Russian\nrock, electronic, South Asian fusion\nrock, electronic, Sundanese fusion\nrock, electronic, chiptune\nrock, electronic, experimental\nrock, electronic, sacred chant\nrock, electronic, spiritual\nrock, electronic, traditional East Asian\nrock, electronic, world music\nrock, enka, festival\nrock, enka, traditional Japanese\nrock, epic, world fusion\nrock, erhu, cinematic\nrock, ethnic fusion, Hebrew rap\nrock, eurodance, italo disco\nrock, experimental, Latin\nrock, festive, melancholic\nrock, filmi-pop, cinematic\nrock, flamenco rock\nrock, flamenco, Greek\nrock, flamenco, Latin\nrock, flamenco, Latin rock\nrock, flamenco, Turkish\nrock, flamenco, acoustic\nrock, flamenco, acoustic ballad\nrock, flamenco, ambient\nrock, flamenco, blues\nrock, flamenco, cinematic\nrock, flamenco, hip-hop\nrock, flamenco, jazz fusion\nrock, flamenco, theatrical\nrock, folk fusion, Central Asian\nrock, folk fusion, East Asian\nrock, folk fusion, Southeast Asian\nrock, folk rock, Chinese rock\nrock, folk rock, Eastern European\nrock, folk rock, cinematic\nrock, folk, C-pop\nrock, folk, Central Asian\nrock, folk, Chinese\nrock, folk, Eastern European\nrock, folk, Hebrew\nrock, folk, Javanese\nrock, folk, Mandarin rock\nrock, folk, Middle Eastern\nrock, folk, South Asian\nrock, folk, Southeast Asian\nrock, folk, Southeast Asian fusion\nrock, folk, Thai\nrock, folk, accordion\nrock, folk, chiptune\nrock, folk, cinematic\nrock, folk, electronic\nrock, folk, fusion\nrock, folk, hard rock\nrock, folk, klezmer\nrock, folk, traditional\nrock, folk, world\nrock, forró\nrock, forró, cinematic\nrock, funk-rock, hard rock, glam metal\nrock, fusion, Middle Eastern\nrock, fusion, Telugu rock\nrock, fusion, traditional Chinese\nrock, future bass\nrock, ghazal\nrock, ghazal, fusion\nrock, glam rock, boogie-woogie\nrock, gospel, cinematic\nrock, gospel, klezmer\nrock, guzheng, cinematic\nrock, guzheng, instrumental\nrock, guzheng, wuxia\nrock, hardstyle, ambient\nrock, hardstyle, psytrance\nrock, heavy metal\nrock, hip hop\nrock, hip hop, Indian classical\nrock, hip hop, cinematic\nrock, hip hop, flamenco\nrock, hip hop, reggae\nrock, hip-hop, Chinese opera\nrock, hip-hop, anthemic\nrock, hip-hop, cinematic\nrock, hyperpop, C-pop\nrock, jazz fusion, theatrical\nrock, jazz, Hebrew vocal\nrock, jazz-fusion, emotional ballad\nrock, klezmer, Eastern European\nrock, klezmer, fusion\nrock, klezmer, progressive rock\nrock, klezmer, theatrical\nrock, klezmer, world music\nrock, kuthu, folk\nrock, laiko, cinematic\nrock, laïko, electronic\nrock, laïko, ney flute\nrock, liturgical, Hebrew\nrock, lo-fi, Chinese opera\nrock, melancholic, Southeast Asian\nrock, metal, cinematic\nrock, metal, emotional\nrock, metal, pop\nrock, metalcore, C-pop\nrock, metalcore, baroque\nrock, metalcore, cinematic\nrock, metalcore, emotional\nrock, musical theater, comedy rock\nrock, new wave\nrock, new wave, Eastern European\nrock, ney flute, instrumental\nrock, nu-metal, rap-rock\nrock, nu-metal, tribal rock\nrock, orchestral, South Asian\nrock, oud, Hebrew vocal\nrock, oud, Middle Eastern\nrock, oud, Turkish\nrock, oud, cinematic\nrock, oud, fusion\nrock, oud, ritualistic\nrock, oud, theatrical\nrock, patriotic, Azerbaijani folk\nrock, patriotic, Indian folk\nrock, patriotic, traditional Chinese\nrock, piano ballad\nrock, piano ballad, punk rock\nrock, polka, accordion\nrock, polka, cumbia\nrock, polka, theatrical rock\nrock, polka-rock\nrock, pop Melayu\nrock, pop melayu, dangdut\nrock, pop sunda, ney flute\nrock, pop, theatrical\nrock, pop-rock\nrock, pop-rock, Southeast Asian\nrock, pop-rock, punk\nrock, post-hardcore\nrock, post-rock, Spanish\nrock, post-rock, Spanish rock\nrock, power ballad\nrock, power ballad, Mandarin rock\nrock, progressive house, EDM\nrock, progressive rock, Italian rock\nrock, protest music, North African\nrock, protest, acoustic\nrock, psychedelic rock, J-rock\nrock, psychedelic, Latin\nrock, psychedelic, Spanish indie\nrock, psychedelic, big-band\nrock, psychedelic, cinematic\nrock, punk rock\nrock, punk, French pop\nrock, punk, boogie-woogie\nrock, qawwali\nrock, rap rock\nrock, rap, Chinese traditional\nrock, rap, Mandarin pop\nrock, rap, Southeast Asian fusion\nrock, rap, cinematic\nrock, rap, folk\nrock, rap-rock, Portuguese rock\nrock, rap-rock, atmospheric\nrock, rap-rock, cinematic\nrock, rap-rock, nu-metal\nrock, regional Mexican, norteño\nrock, retro, big-band\nrock, rockabilly, Dutch rock\nrock, salsa\nrock, samba-reggae\nrock, schlager\nrock, schlager, comedic\nrock, schlager, humppa\nrock, schlager, latin\nrock, schlager-rock\nrock, shehnai, cinematic\nrock, sitar rock, cinematic\nrock, ska-punk, rap-rock\nrock, soul, Latin rock\nrock, soul, live performance\nrock, surf rock, mariachi rock\nrock, surf rock, rockabilly\nrock, synthwave, cinematic\nrock, tango, acoustic\nrock, tango, carnival\nrock, theatrical pop, dream-pop\nrock, theatrical rock\nrock, theatrical, anthemic\nrock, theatrical, cinematic\nrock, thrash metal\nrock, traditional Central Asian, cinematic\nrock, traditional Central Asian, fusion\nrock, traditional East Asian\nrock, traditional Indonesian\nrock, traditional Indonesian, fusion\nrock, traditional Indonesian, surf rock\nrock, traditional Javanese, fusion\nrock, traditional Malay, cinematic\nrock, traditional Malay, fusion\nrock, traditional Malay, hard rock\nrock, traditional Southeast Asian\nrock, traditional Southeast Asian folk\nrock, traditional Southeast Asian, folk fusion\nrock, traditional Southeast Asian, fusion\nrock, traditional Southeast Asian, pop sunda\nrock, traditional Turkish, cinematic\nrock, traditional fusion\nrock, traditional, Central Asian\nrock, traditional, cinematic\nrock, traditional, ney\nrock, trap, K-pop\nrock, trap, chiptune\nrock, trap, world fusion\nrock, tribal, Thai\nrock, trot, ska\nrock, turbo-folk\nrock, world fusion, Turkish rock\nrock, world fusion, theatrical\nrock, world music\nrock, world music, C-pop\nrock, world music, Hindi rock\nrock, world music, Turkish folk\nrock, world music, cinematic\nrock, world music, jazz fusion\nrock, wuxia, cinematic\nrock-funk\nrock-fusion\nrock-gospel\nrock-infused hip-hop\nrock-opera\nrock-pop\nrock-rap\nrock-rap fusion\nrock-reggae\nrock-trap\nrock-trot\nrockabilly\nrockabilly C-pop\nrockabilly Christmas\nrockabilly Latin\nrockabilly Mandopop\nrockabilly a cappella\nrockabilly big band\nrockabilly bluegrass\nrockabilly blues\nrockabilly blues rock\nrockabilly blues shuffle\nrockabilly blues-rock\nrockabilly boeremusiek\nrockabilly boogie-woogie\nrockabilly boogie-woogie children's\nrockabilly boogie-woogie cumbia\nrockabilly boogie-woogie jump blues\nrockabilly boogie-woogie novelty\nrockabilly cabaret\nrockabilly chanson\nrockabilly children's\nrockabilly children's music\nrockabilly chiptune\nrockabilly comedy folk\nrockabilly comedy rock\nrockabilly country\nrockabilly country Cajun\nrockabilly country bluegrass\nrockabilly country blues\nrockabilly country boogie-woogie\nrockabilly country cajun\nrockabilly country folk-rock\nrockabilly country gospel\nrockabilly country honky-tonk\nrockabilly country latin\nrockabilly country norteño\nrockabilly country novelty\nrockabilly country polka\nrockabilly country rock\nrockabilly country rock bluegrass\nrockabilly country rock blues rock\nrockabilly country rock western swing\nrockabilly country sea shanty\nrockabilly country swamp rock\nrockabilly country swing\nrockabilly country waltz\nrockabilly country western\nrockabilly country-blues\nrockabilly country-folk\nrockabilly country-gospel\nrockabilly country-pop\nrockabilly country-rock\nrockabilly country-swing\nrockabilly country-western\nrockabilly cumbia\nrockabilly cumbia latin\nrockabilly dansband\nrockabilly doo-wop\nrockabilly doo-wop holiday\nrockabilly doo-wop novelty\nrockabilly doo-wop retro-futuristic\nrockabilly doo-wop vintage\nrockabilly doo-wop vintage rock\nrockabilly estrada\nrockabilly folk\nrockabilly folk-punk\nrockabilly folk-rock\nrockabilly forró\nrockabilly fusion\nrockabilly garage rock\nrockabilly gospel\nrockabilly gospel country\nrockabilly gospel rock\nrockabilly gospel soul\nrockabilly gypsy jazz\nrockabilly gypsy punk\nrockabilly honky-tonk\nrockabilly humppa\nrockabilly indie rock\nrockabilly jazz\nrockabilly jump blues\nrockabilly lo-fi\nrockabilly mandopop\nrockabilly nederpop\nrockabilly new wave\nrockabilly novelty\nrockabilly novelty rock\nrockabilly polka\nrockabilly pop\nrockabilly pop-rock\nrockabilly post-punk\nrockabilly psychedelic\nrockabilly pub rock\nrockabilly punk\nrockabilly punk rock\nrockabilly revival\nrockabilly rock\nrockabilly rock 'n' roll\nrockabilly rock and roll\nrockabilly schlager\nrockabilly sertanejo\nrockabilly show tune\nrockabilly ska\nrockabilly skiffle\nrockabilly soul\nrockabilly spaghetti western\nrockabilly surf\nrockabilly surf rock\nrockabilly surf rock big band\nrockabilly surf rock bluegrass\nrockabilly surf rock gypsy jazz\nrockabilly swing\nrockabilly swing big band\nrockabilly swing cabaret\nrockabilly swing jump blues\nrockabilly swing levenslied\nrockabilly swing novelty\nrockabilly swing rock\nrockabilly swing rock and roll\nrockabilly tango\nrockabilly thrash metal\nrockabilly waltz\nrockabilly western swing\nrockabilly, 60s rock, Dutch rock\nrockabilly, 60s rock, big band\nrockabilly, Brazilian rock\nrockabilly, Cajun, boogie-woogie\nrockabilly, Christmas novelty, early rock 'n' roll\nrockabilly, Christmas rock\nrockabilly, Christmas, novelty\nrockabilly, Czech folk, country\nrockabilly, Dutch rock\nrockabilly, Dutch rock, levenslied\nrockabilly, Dutch, polka\nrockabilly, French chanson\nrockabilly, French rock\nrockabilly, Halloween, cinematic\nrockabilly, Italian folk\nrockabilly, Italian folk, surf rock\nrockabilly, Italian pop-rock\nrockabilly, Italian swing, theatrical rock\nrockabilly, Italian, early rock and roll\nrockabilly, Italian, novelty\nrockabilly, Latin rock\nrockabilly, Latin rock, French rock\nrockabilly, Latin rock, vintage rock\nrockabilly, Latin, Tex-Mex\nrockabilly, Latin, energetic\nrockabilly, Latin, vintage\nrockabilly, Middle Eastern folk, surf rock\nrockabilly, Nederpop\nrockabilly, Neue Deutsche Welle\nrockabilly, New Orleans, second-line\nrockabilly, Polish folk\nrockabilly, R&B, boogie-woogie\nrockabilly, R&B, vintage rock\nrockabilly, Schlager\nrockabilly, Schlager, German\nrockabilly, Schlager, German rock\nrockabilly, Schlager, novelty\nrockabilly, Schlager, pub rock\nrockabilly, Schlager, retro rock\nrockabilly, Southern rock\nrockabilly, Soviet rock\nrockabilly, Western Swing, lo-fi\nrockabilly, Western swing, Christmas\nrockabilly, Western swing, novelty Christmas\nrockabilly, acoustic ballad\nrockabilly, anti-folk\nrockabilly, ballad\nrockabilly, big band\nrockabilly, big band, Christmas rock\nrockabilly, big band, Dutch rock\nrockabilly, big band, boogie-woogie\nrockabilly, big band, children's\nrockabilly, big band, children's party\nrockabilly, big band, comedic\nrockabilly, big band, early rock and roll\nrockabilly, big band, gospel\nrockabilly, big band, lounge\nrockabilly, big band, novelty\nrockabilly, big band, novelty Christmas\nrockabilly, big band, novelty rock\nrockabilly, big band, retro rock\nrockabilly, big band, show tune\nrockabilly, big band, surf rock\nrockabilly, big band, swing\nrockabilly, big band, theatrical\nrockabilly, big band, theatrical rock\nrockabilly, big band, vintage\nrockabilly, big band, vintage rock\nrockabilly, big band, vintage rock and roll\nrockabilly, bluegrass, electric guitar\nrockabilly, blues rock\nrockabilly, blues rock, Russian rock\nrockabilly, blues rock, novelty\nrockabilly, blues, Christmas rock\nrockabilly, blues-rock, Christmas rock\nrockabilly, blues-rock, Spanish-style\nrockabilly, blues-rock, holiday\nrockabilly, boogie-woogie, Christmas rock\nrockabilly, boogie-woogie, Czech rock\nrockabilly, boogie-woogie, Danish rock\nrockabilly, boogie-woogie, Dutch rock\nrockabilly, boogie-woogie, Finnish rock\nrockabilly, boogie-woogie, French rock\nrockabilly, boogie-woogie, German rock\nrockabilly, boogie-woogie, Japanese rock\nrockabilly, boogie-woogie, New Orleans\nrockabilly, boogie-woogie, Spanish rock\nrockabilly, boogie-woogie, children's music\nrockabilly, boogie-woogie, comedy rock\nrockabilly, boogie-woogie, early rock and roll\nrockabilly, boogie-woogie, live rock\nrockabilly, boogie-woogie, narrative rock\nrockabilly, boogie-woogie, novelty\nrockabilly, boogie-woogie, novelty Christmas\nrockabilly, boogie-woogie, novelty rock\nrockabilly, boogie-woogie, retro rock\nrockabilly, boogie-woogie, rock\nrockabilly, boogie-woogie, rock 'n' roll\nrockabilly, boogie-woogie, rock and roll\nrockabilly, boogie-woogie, roots-rock\nrockabilly, boogie-woogie, swing\nrockabilly, boogie-woogie, theatrical rock\nrockabilly, boogie-woogie, vintage rock\nrockabilly, cabaret, Russian chanson\nrockabilly, cabaret, theatrical rock\nrockabilly, calypso, rock and roll\nrockabilly, children's music, French\nrockabilly, children's music, early rock and roll\nrockabilly, children's music, retro\nrockabilly, children's music, swing\nrockabilly, cinematic ballad\nrockabilly, cinematic rock\nrockabilly, cinematic, brass rock\nrockabilly, classic rock\nrockabilly, comedic, anti-Christmas\nrockabilly, comedy rock, live\nrockabilly, comedy rock, live rock\nrockabilly, country\nrockabilly, country ballad, early rock and roll\nrockabilly, country rock, French rock\nrockabilly, country rock, novelty\nrockabilly, country, Christmas\nrockabilly, country, Christmas rock\nrockabilly, country, Spanish rock\nrockabilly, country, Thai\nrockabilly, country, children's music\nrockabilly, country, children's novelty\nrockabilly, country, novelty\nrockabilly, country, novelty Christmas\nrockabilly, country, vintage rock\nrockabilly, country-folk, Quebecois\nrockabilly, country-rock\nrockabilly, country-rock, Christmas\nrockabilly, country-rock, Christmas pop\nrockabilly, country-rock, Christmas rock\nrockabilly, country-rock, Czech rock\nrockabilly, country-rock, Finnish rock\nrockabilly, country-rock, German rock\nrockabilly, country-rock, Italian rock\nrockabilly, country-rock, Swedish rock\nrockabilly, country-rock, boogie-woogie\nrockabilly, country-rock, novelty\nrockabilly, country-schlager\nrockabilly, country-western\nrockabilly, country-western, French chanson\nrockabilly, country-western, Mandopop\nrockabilly, country-western, children's\nrockabilly, country-western, children's music\nrockabilly, country-western, children's novelty\nrockabilly, country-western, novelty\nrockabilly, country-western, novelty rock\nrockabilly, cumbia\nrockabilly, dansband\nrockabilly, dansband, Swedish rock\nrockabilly, doo-wop\nrockabilly, doo-wop, 1950s rock\nrockabilly, doo-wop, Christmas\nrockabilly, doo-wop, Christmas rock\nrockabilly, doo-wop, early rock and roll\nrockabilly, doo-wop, novelty\nrockabilly, doo-wop, novelty Christmas\nrockabilly, doo-wop, novelty rock\nrockabilly, doo-wop, retro rock\nrockabilly, doo-wop, rock and roll\nrockabilly, doo-wop, theatrical rock\nrockabilly, doo-wop, vintage rock\nrockabilly, doo-wop, vintage rock and roll\nrockabilly, dream pop\nrockabilly, early R&B, vintage rock\nrockabilly, early country\nrockabilly, early country-blues\nrockabilly, early rock 'n' roll\nrockabilly, early rock and roll\nrockabilly, early rock and roll, Christmas\nrockabilly, early rock and roll, Kayōkyoku\nrockabilly, early rock and roll, ballad\nrockabilly, early rock and roll, cinematic\nrockabilly, early rock and roll, country\nrockabilly, early rock and roll, country blues\nrockabilly, early rock and roll, country-swing\nrockabilly, early rock and roll, doo-wop\nrockabilly, early rock and roll, pop-funk\nrockabilly, early rock and roll, retro rock\nrockabilly, early rock and roll, rock and roll\nrockabilly, early rock and roll, trot\nrockabilly, early rock, vintage rock\nrockabilly, estrada, Soviet pop\nrockabilly, flamenco, surf rock\nrockabilly, folk, gospel\nrockabilly, folk, traditional Southeast Asian\nrockabilly, forró rock\nrockabilly, forró-rock\nrockabilly, funk rock\nrockabilly, garage rock\nrockabilly, gospel, Christmas rock\nrockabilly, gospel, country\nrockabilly, gospel, country rock\nrockabilly, gospel, novelty rock\nrockabilly, gothic rock, rap-metal\nrockabilly, humppa, Finnish rock\nrockabilly, iskelmä, schlager\nrockabilly, jump blues\nrockabilly, jump blues, New Orleans\nrockabilly, jump blues, a cappella\nrockabilly, jump blues, early rock and roll\nrockabilly, jump blues, lo-fi\nrockabilly, jump blues, novelty\nrockabilly, jump blues, novelty Christmas\nrockabilly, jump blues, raw rock\nrockabilly, jump blues, rock and roll\nrockabilly, jump blues, swing\nrockabilly, jump blues, vintage rock\nrockabilly, levenslied\nrockabilly, nederpop\nrockabilly, nederpop, vintage rock\nrockabilly, novelty rock\nrockabilly, novelty rock, Danish\nrockabilly, novelty rock, early rock and roll\nrockabilly, novelty rock, show tune\nrockabilly, novelty, Christmas\nrockabilly, novelty, boogie-woogie\nrockabilly, novelty, cartoon\nrockabilly, novelty, swing\nrockabilly, novelty, vintage Christmas\nrockabilly, outlaw country, jump blues\nrockabilly, piano ballad\nrockabilly, piano ballad, theatrical\nrockabilly, polka rock\nrockabilly, polka, Dutch\nrockabilly, psychedelic rock, blues-rock\nrockabilly, pub rock\nrockabilly, pub rock, Czech rock\nrockabilly, pub rock, Finnish rock\nrockabilly, pub rock, Polish rock\nrockabilly, ranchera, rock and roll\nrockabilly, retro rock, soul\nrockabilly, retro rock, swing\nrockabilly, retro swing, Hebrew spoken word\nrockabilly, retro, dance\nrockabilly, rhythm and blues, vintage rock\nrockabilly, rock 'n' roll, French rock\nrockabilly, rock en español, rock and roll\nrockabilly, schlager\nrockabilly, schlager, Danish rock\nrockabilly, schlager, Finnish\nrockabilly, schlager, Finnish rock\nrockabilly, schlager, Swedish rock\nrockabilly, schlager, children's music\nrockabilly, schlager, cinematic\nrockabilly, schlager, comedic rock\nrockabilly, schlager, neue deutsche welle\nrockabilly, schlager, retro rock\nrockabilly, schlager, rock 'n' roll\nrockabilly, schlager, rock and roll\nrockabilly, show tune\nrockabilly, show tune, children's music\nrockabilly, show tune, novelty\nrockabilly, skiffle, French novelty\nrockabilly, skiffle, vintage rock\nrockabilly, soul, vintage rock\nrockabilly, southern rock\nrockabilly, southern rock, christmas\nrockabilly, surf rock\nrockabilly, surf rock, Christmas\nrockabilly, surf rock, Christmas pop\nrockabilly, surf rock, Christmas rock\nrockabilly, surf rock, Czech rock\nrockabilly, surf rock, Dutch\nrockabilly, surf rock, Dutch rock\nrockabilly, surf rock, Finnish rock\nrockabilly, surf rock, French rock\nrockabilly, surf rock, Greek rock\nrockabilly, surf rock, Halloween\nrockabilly, surf rock, Italian rock\nrockabilly, surf rock, Mandopop\nrockabilly, surf rock, Polish rock\nrockabilly, surf rock, Russian chanson\nrockabilly, surf rock, Russian rock\nrockabilly, surf rock, Spanish rock\nrockabilly, surf rock, Swedish rock\nrockabilly, surf rock, Vietnamese pop\nrockabilly, surf rock, children's music\nrockabilly, surf rock, children's worship\nrockabilly, surf rock, folk\nrockabilly, surf rock, indie rock\nrockabilly, surf rock, iskelmä\nrockabilly, surf rock, live rock\nrockabilly, surf rock, novelty\nrockabilly, surf rock, novelty rock\nrockabilly, surf rock, rock and roll\nrockabilly, surf rock, show tune\nrockabilly, surf rock, ska\nrockabilly, surf rock, theatrical rock\nrockabilly, swamp rock, lo-fi\nrockabilly, swing revival, surf rock\nrockabilly, swing, Brazilian country\nrockabilly, swing, Christmas pop\nrockabilly, swing, Christmas rock\nrockabilly, swing, French pop\nrockabilly, swing, Indonesian pop\nrockabilly, swing, Latin rock\nrockabilly, swing, Russian pop\nrockabilly, swing, Taiwanese pop\nrockabilly, swing, boogie-woogie\nrockabilly, swing, children's music\nrockabilly, swing, children's novelty\nrockabilly, swing, early rock and roll\nrockabilly, swing, holiday\nrockabilly, swing, jazz\nrockabilly, swing, novelty\nrockabilly, swing, novelty Christmas\nrockabilly, swing, rock and roll\nrockabilly, swing, theatrical\nrockabilly, swing, theatrical rock\nrockabilly, theatrical rock\nrockabilly, theatrical rock, comedic rock\nrockabilly, theatrical rock, country-pop\nrockabilly, theatrical rock, satirical\nrockabilly, theatrical rock, surf rock\nrockabilly, theatrical rock, villainous rock\nrockabilly, theatrical, Christmas\nrockabilly, theatrical, holiday\nrockabilly, theatrical, live\nrockabilly, theatrical, novelty\nrockabilly, theatrical, sea shanty\nrockabilly, theatrical, surf rock\nrockabilly, thrash metal\nrockabilly, twist, garage rock\nrockabilly, vintage pop, Vietnamese pop\nrockabilly, vintage rock and roll\nrockabilly, western swing\nrockabilly, western swing, Christmas\nrockabilly, western swing, Dutch rock\nrockabilly, western swing, bluegrass\nrockabilly, western swing, country\nrockabilly, western swing, early rock and roll\nrockabilly, western swing, novelty\nrockabilly, western swing, soul\nrockabilly, western swing, vintage\nrockabilly-punk\nrocksteady\nrocksteady reggae\nrocksteady ska\nromantic C-pop\nromantic C-pop trap\nromantic Indian fusion\nromantic Latin pop\nromantic R&B\nromantic acoustic\nromantic ballad\nromantic ballad merengue\nromantic ballad, Chinese folk opera, cinematic\nromantic ballad, Chinese folk, cinematic\nromantic ballad, Latin pop\nromantic ballad, pop\nromantic ballad, world music\nromantic ballroom\nromantic ballroom waltz\nromantic bolero\nromantic bossa nova\nromantic brega\nromantic classical\nromantic classical jazz\nromantic cumbia\nromantic drill\nromantic duet\nromantic fantasy ballad\nromantic flamenco pop\nromantic folk\nromantic funk\nromantic hip-hop\nromantic hip-hop chiptune\nromantic instrumental\nromantic jazz\nromantic melancholic\nromantic orchestral\nromantic pagode\nromantic piano\nromantic piano ballad\nromantic pop\nromantic pop R&B\nromantic pop ballad\nromantic pop bossa nova\nromantic pop folk\nromantic pop gospel\nromantic pop hip-hop\nromantic pop reggaeton\nromantic pop soul\nromantic pop trap\nromantic pop waltz\nromantic pop world music\nromantic pop, Azerbaijani folk\nromantic pop, Azerbaijani folk, Turkish folk\nromantic pop, Bollywood\nromantic pop, Bollywood, trap\nromantic pop, Central Asian\nromantic pop, Central Asian folk\nromantic pop, Central Asian, Middle Eastern\nromantic pop, Central Asian, modern production\nromantic pop, Eastern European folk, cinematic\nromantic pop, Eastern European, Middle Eastern\nromantic pop, Eastern European, pop-rock\nromantic pop, Indian pop\nromantic pop, Javanese pop\nromantic pop, Middle Eastern, Turkish\nromantic pop, Romanian folk\nromantic pop, South Asian fusion\nromantic pop, South Asian pop\nromantic pop, South Asian, cinematic\nromantic pop, South Indian film music\nromantic pop, Southeast Asian pop\nromantic pop, electronic, Central Asian\nromantic pop, filmi\nromantic pop, flamenco, pop-rock\nromantic pop, future bass\nromantic pop, modern hip-hop\nromantic pop, reggaeton, electronic\nromantic pop, smooth jazz\nromantic pop-fusion\nromantic pop-rap\nromantic reggaeton\nromantic slow-dance\nromantic theatrical\nromantic trap\nromantic trap ballad\nromantic waltz\nromantic winter R&B\nromantic, melancholic, Spanish-influenced\nromantic, melancholic, Tamil folk\nromantic, theatrical, acoustic\nromantic-era\nromantic-era piano, Arabic folk\nromântico\nroots folk\nroots gospel\nroots reggae\nroots reggae conscious hip-hop\nroots reggae dancehall\nroots reggae dub\nroots reggae gospel\nroots reggae hip-hop\nroots reggae rock\nroots reggae ska\nroots reggae ska-punk\nroots reggae, dancehall\nroots reggae, early dancehall\nroots reggae, hard rock\nroots reggae, heavy rock\nroots reggae, trap, future bass\nroots rock\nroots rock alt-country\nroots rock blues americana\nroots rock blues country\nroots rock country\nroots rock country-blues\nroots rock country-rock\nroots rock funk\nroots rock funk soul\nroots rock garage rock\nroots rock gospel\nroots rock gospel blues\nroots rock gospel country\nroots rock psychedelic\nroots rock psychedelic rock\nroots rock reggae\nroots rock soul exotica\nroots rock world music\nroots rock, Americana\nroots rock, Celtic punk\nroots rock, americana, pub rock\nroots rock, country, Americana\nroots rock, country-rock, Americana\nroots rock, gospel, Americana\nroots rock, gospel, americana\nroots rock, honky-tonk, country-rock\nroots rock, rockabilly\nroots rock, rockabilly, Americana\nroots rock, southern rock\nroots-rock\nroots-rock alt-country\nroots-rock alt-country bar-room blues\nroots-rock blues-rock\nroots-rock country boogie-woogie\nroots-rock country pub-rock\nroots-rock gospel\nroots-rock honky-tonk\nroots-rock soul\nroots-rock, country, rockabilly\nrumba\nrumba bellowera\nrumba big band\nrumba chiptune\nrumba cumbia\nrumba electronica\nrumba flamenca\nrumba flamenco\nrumba flamenco rock\nrumba funk-rock\nrumba pop\nrumba punk\nrumba rock\nrumba salsa\nrumba ska big band\nrumba ska-punk\nrumba, cinematic, folk\nrumba-pop\nrumba-punk\nrumba-rock\nrumba-ska\nrumba-ska-punk\nrumba-trap\nrussemusikk\nrussemusikk EDM\nrussemusikk big room\nrussemusikk big room house\nrussemusikk dance-pop\nrussemusikk danseband\nrussemusikk hardstyle\nrussemusikk hardstyle big room\nrussemusikk trap\nrussemusikk, EDM, hyperpop\nrussemusikk, hardstyle, big room house\nsacred a cappella\nsacred ambient\nsacred ballad\nsacred choral\nsacred choral, chiptune\nsacred choral, salsa\nsacred classical\nsacred folk\nsacred hymn\nsacred music\nsacred music, forró\nsacred orchestral\nsacred piano\nsad Afrobeats\nsad Arabic hip-hop\nsad Bollywood ballad\nsad C-pop hip-hop\nsad Latin hip-hop\nsad Latin pop\nsad Latin trap\nsad R&B\nsad R&B emo trap\nsad R&B trap-soul\nsad R&B, Latin trap\nsad R&B, Latin trap-soul\nsad R&B, lo-fi hip hop, Latin pop\nsad acoustic hip-hop\nsad ballad\nsad boy reggaeton\nsad boy trap\nsad funk\nsad funk carioca\nsad hip-hop\nsad hip-hop, Latin R&B\nsad hip-hop, Turkish rap\nsad piano ballad\nsad pop\nsad pop R&B\nsad pop R&B hip-hop\nsad pop ambient lo-fi hip-hop\nsad pop ballad\nsad pop chillwave\nsad pop emo rap\nsad pop emo rap lo-fi hip-hop\nsad pop emo-trap\nsad pop funk carioca\nsad pop lo-fi hip hop\nsad pop lo-fi hip-hop\nsad pop lo-fi hip-hop emo rap\nsad pop reggaeton\nsad pop trap\nsad pop, Brazilian funk, trap\nsad pop, German cloud rap\nsad pop, R&B, UK drill\nsad pop, R&B, lo-fi hip-hop\nsad pop, R&B, trap\nsad pop, contemporary R&B, trap\nsad pop, emotional hip-hop\nsad pop, emotional trap\nsad pop, hip-hop\nsad pop, lo-fi hip hop\nsad pop, lo-fi hip hop, atmospheric\nsad pop, lo-fi hip-hop, ambient\nsad pop, lo-fi hip-hop, cinematic piano\nsad pop, modern trap\nsad pop, narrative hip-hop\nsad pop, reggaeton\nsad pop, slap house\nsad pop, trap, R&B\nsad pop, trap, Turkish ambient\nsad pop, trap, ambient\nsad pop, trap, emotional hip-hop\nsad pop, trap, traditional South Asian\nsad pop-R&B\nsad pop-rap\nsad pop-trap\nsad rap\nsad rap ambient\nsad rap ambient pop\nsad rap ballad\nsad rap chillwave\nsad rap, Turkish hip-hop, lo-fi\nsad rap, alternative R&B, atmospheric pop\nsad rap, cinematic pop\nsad rap, conscious hip-hop\nsad rap, contemporary R&B\nsad rap, emotional pop, lo-fi hip-hop\nsad rap, lo-fi hip hop, North African pop-rap\nsad rap, lo-fi hip-hop\nsad reggaeton\nsad reggaeton Arabic\nsad reggaeton cloud rap\nsad reggaeton, Latin R&B\nsad reggaeton, hyperpop, orchestral synth\nsad reggaeton, latin pop\nsad sierreño\nsad trap\nsad trap R&B\nsad trap R&B Turkish pop\nsad trap alternative rock\nsad trap ambient\nsad trap ambient pop\nsad trap classical\nsad trap emo rap\nsad trap emo-rap\nsad trap lo-fi hip hop\nsad trap lo-fi hip-hop\nsad trap phonk\nsad trap pluggnb\nsad trap, Arabic R&B\nsad trap, Brazilian R&B\nsad trap, Brazilian funk\nsad trap, Desi pop\nsad trap, Indian pop\nsad trap, Indian pop-rap\nsad trap, Latin R&B\nsad trap, Latin R&B, atmospheric pop\nsad trap, Latin cloud rap\nsad trap, Latin emo rap\nsad trap, Latin hip-hop\nsad trap, Latin pop\nsad trap, Latin, ambient\nsad trap, North African hip-hop\nsad trap, North African pop\nsad trap, North African pop-rap\nsad trap, Punjabi pop\nsad trap, R&B\nsad trap, R&B, Brazilian\nsad trap, R&B, Indian pop\nsad trap, R&B, Latin guitar\nsad trap, R&B, North African\nsad trap, R&B, conscious hip-hop\nsad trap, R&B, pop\nsad trap, Russian pop-rap\nsad trap, alternative R&B\nsad trap, alternative R&B, Brazilian pop\nsad trap, alternative R&B, cinematic\nsad trap, alternative R&B, lo-fi hip-hop\nsad trap, cloud rap\nsad trap, cloud rap, J-pop\nsad trap, cloud rap, dancehall\nsad trap, conscious hip-hop\nsad trap, contemporary R&B\nsad trap, contemporary R&B, North African\nsad trap, dark pop\nsad trap, emo rap\nsad trap, emo rap, Latin\nsad trap, emo rap, Latin pop\nsad trap, emo rap, Latin urban\nsad trap, emo rap, R&B\nsad trap, emo rap, ambient C-pop\nsad trap, emo rap, atmospheric pop\nsad trap, emo rap, cinematic\nsad trap, emo rap, contemporary R&B\nsad trap, emo rap, lo-fi\nsad trap, emo rap, lo-fi hip hop\nsad trap, emo rap, lo-fi hip-hop\nsad trap, emo rap, lo-fi pop\nsad trap, emo rap, modern trap\nsad trap, emotional R&B\nsad trap, emotional R&B, Middle Eastern\nsad trap, emotional R&B, Punjabi hip hop\nsad trap, emotional hip-hop\nsad trap, emotional pop\nsad trap, emotional pop-rap\nsad trap, latin pop\nsad trap, latin trap\nsad trap, lo-fi hip hop\nsad trap, lo-fi hip hop, anime-inspired\nsad trap, lo-fi hip hop, atmospheric pop\nsad trap, lo-fi hip hop, emo rap\nsad trap, lo-fi hip hop, emotional ballad\nsad trap, lo-fi hip-hop\nsad trap, lo-fi hip-hop, Spanish ballad\nsad trap, melodic hip-hop\nsad trap, melodic rap\nsad trap, pluggnb\nsad trap, pop-rap, North African\nsad trap-soul\nsad-dance-pop\nsad-pop\nsad-pop trap\nsad-pop, trap, Chinese hip-hop\nsad-trap\nsadcore\nsadcore hip hop\nsadcore indie rock\nsadcore lo-fi hip hop\nsadcore post-rock\nsaloon rock\nsalsa\nsalsa Christian\nsalsa R&B\nsalsa R&B hip-hop\nsalsa arabic gospel\nsalsa arabic pop\nsalsa bachata fusion\nsalsa ballad\nsalsa big band\nsalsa big band j-pop\nsalsa bolero\nsalsa bomba\nsalsa boogaloo\nsalsa boogie-woogie\nsalsa candombe\nsalsa children's\nsalsa children's music\nsalsa chiptune\nsalsa cinematic\nsalsa compas\nsalsa cristiana\nsalsa cumbia\nsalsa cumbia Latin house\nsalsa cumbia metal\nsalsa cumbia reggaeton\nsalsa dancehall\nsalsa disco\nsalsa disco-funk\nsalsa drum and bass\nsalsa dura\nsalsa dura punk rock\nsalsa education\nsalsa flamenca\nsalsa flamenco\nsalsa flamenco rock\nsalsa funk\nsalsa funk gospel\nsalsa funk rock\nsalsa fusion\nsalsa gospel\nsalsa hip hop\nsalsa hip-hop\nsalsa hip-hop fusion\nsalsa jazz\nsalsa jíbaro\nsalsa lo-fi\nsalsa mambo\nsalsa mambo cabaret\nsalsa mambo cumbia\nsalsa mariachi\nsalsa merengue\nsalsa merengue cumbia\nsalsa merengue fusion\nsalsa merengue reggaeton\nsalsa metal\nsalsa opera\nsalsa orchestral\nsalsa plena\nsalsa pop\nsalsa pop-rock\nsalsa protest\nsalsa punk\nsalsa rap\nsalsa reggaeton\nsalsa rock\nsalsa rock ballad\nsalsa romántica\nsalsa romântico\nsalsa rumba\nsalsa rumba flamenca\nsalsa samba Latin\nsalsa samba Latin house\nsalsa samba breakbeat\nsalsa samba reggaeton\nsalsa soca\nsalsa son cubano\nsalsa son montuno\nsalsa soul\nsalsa tango\nsalsa timba\nsalsa trap\nsalsa zouk\nsalsa, Latin funk\nsalsa, Latin gospel\nsalsa, Latin hip hop, Afro-Latin\nsalsa, Latin house\nsalsa, Latin jazz\nsalsa, Latin jazz, big band\nsalsa, Latin jazz, piano ballad\nsalsa, Latin pop\nsalsa, Latin pop, Christmas\nsalsa, Latin rock, gospel\nsalsa, South Asian pop\nsalsa, ballad, Latin\nsalsa, ballad, Latin pop\nsalsa, ballad, cinematic\nsalsa, big band jazz, Indonesian pop\nsalsa, big band, Latin jazz\nsalsa, big band, Latin rock\nsalsa, big band, cinematic\nsalsa, bolero\nsalsa, bolero, merengue, ballad\nsalsa, chanson, classical\nsalsa, children's music, Brazilian\nsalsa, cinematic, Latin ballad\nsalsa, cinematic, ballad\nsalsa, cinematic, operatic pop\nsalsa, cumbia, protest\nsalsa, disco-house\nsalsa, festive, Christmas\nsalsa, folk fusion\nsalsa, mambo, big band\nsalsa, mambo, comedy\nsalsa, merengue\nsalsa, merengue, Latin\nsalsa, merengue, Latin Christmas\nsalsa, merengue, Latin dance\nsalsa, operatic ballad\nsalsa, operatic, cinematic\nsalsa, protest, urban\nsalsa, son cubano\nsalsa, tango, cinematic\nsalsa, theatrical, cinematic\nsalsa-funk\nsalsa-gospel\nsalsa-metal\nsalsa-pop\nsalsa-reggae\nsalsa-reggaeton\nsalsa-rock\nsalsa-rock fusion\nsamba\nsamba MPB\nsamba axé\nsamba ballad\nsamba batucada\nsamba big band\nsamba blues\nsamba boogie\nsamba boogie-woogie\nsamba bossa nova\nsamba brass\nsamba cabaret\nsamba carnival\nsamba children's\nsamba children's music\nsamba chiptune\nsamba choro\nsamba cinematic\nsamba de boi\nsamba de cabasa\nsamba de calypso\nsamba de carioca\nsamba de carnaval\nsamba de partido alto\nsamba de protesto\nsamba de raiz\nsamba de roda\nsamba de viola\nsamba drum and bass\nsamba enredo\nsamba flamenco\nsamba folk\nsamba football\nsamba forró\nsamba forró choro\nsamba frevo\nsamba funk\nsamba funk lounge\nsamba funk rock\nsamba fusion\nsamba gospel\nsamba hip-hop\nsamba hip-hop Afro-Brazilian\nsamba hip-hop fusion\nsamba house\nsamba jazz\nsamba jazz fusion\nsamba lo-fi\nsamba mpb\nsamba orchestral\nsamba pagode\nsamba pop\nsamba pop-rock\nsamba protest\nsamba reggae\nsamba rock\nsamba rock funk rock\nsamba rock, big band jazz\nsamba salsa\nsamba soul\nsamba tango\nsamba vintage big band\nsamba, Brazilian carnival\nsamba, Brazilian folk, festa Junina\nsamba, Brazilian pop\nsamba, Brazilian pop, hip-hop\nsamba, Italian-Brazilian, novelty\nsamba, Latin jazz\nsamba, MPB\nsamba, MPB, Brazilian\nsamba, MPB, Brazilian Christmas\nsamba, MPB, Brazilian folk\nsamba, MPB, Christmas\nsamba, MPB, big band\nsamba, MPB, children's music\nsamba, MPB, live\nsamba, axé, romantic rock\nsamba, baião, Brazilian folk\nsamba, ballad\nsamba, big band, children's music\nsamba, big band, cinematic\nsamba, big band, jazz\nsamba, bossa nova, Afro-Latin\nsamba, bossa nova, Latin house\nsamba, bossa nova, breakbeat\nsamba, bossa nova, children's music\nsamba, brass band, carnival\nsamba, brass band, children's music\nsamba, brass, big band\nsamba, carnival, football chant\nsamba, children's music, carnival\nsamba, children's music, marchinha\nsamba, cinematic, Latin pop\nsamba, cinematic, MPB\nsamba, cinematic, choral\nsamba, cinematic, orchestral\nsamba, forró, Brazilian\nsamba, frevo, Brazilian carnival\nsamba, funk, punk-funk\nsamba, live, Brazilian\nsamba, marching band, Brazilian anthem\nsamba, marchinha, Brazilian Christmas\nsamba, marchinha, Brazilian carnival\nsamba, marchinha, children's music\nsamba, modern, Brazilian\nsamba, música popular brasileira\nsamba, novelty, Brazilian\nsamba, orchestral, cinematic\nsamba, pagode\nsamba, pagode, Brazilian\nsamba, pop, axé\nsamba, salsa, gospel\nsamba, sci-fi, upbeat\nsamba, soul, ambient\nsamba, tango, musette\nsamba, world music, theatrical\nsamba, worldbeat, Brazilian\nsamba-blues\nsamba-bolero\nsamba-bossa nova\nsamba-canção\nsamba-electronic\nsamba-enredo\nsamba-funk\nsamba-funk MPB\nsamba-funk hip-hop\nsamba-fusion\nsamba-gospel\nsamba-gospel, rock, classical guitar\nsamba-house\nsamba-jazz\nsamba-jazz MPB\nsamba-jazz bossa nova\nsamba-jazz funk-rap\nsamba-jazz fusion\nsamba-jazz lo-fi\nsamba-jazz, samba-reggae\nsamba-jazz, surf-rock, dream-pop\nsamba-mambo\nsamba-pagode\nsamba-pop\nsamba-pop bossa nova\nsamba-pop funk\nsamba-pop rockabilly Latin rock\nsamba-rap\nsamba-reggae\nsamba-reggae MPB\nsamba-reggae axé\nsamba-reggae big beat\nsamba-reggae frevo\nsamba-reggae funk\nsamba-reggae funk rock\nsamba-reggae gospel\nsamba-reggae hip-hop\nsamba-reggae lo-fi\nsamba-reggae metal\nsamba-reggae pop-funk\nsamba-reggae pop-rock\nsamba-reggae psychedelic rock\nsamba-reggae punk\nsamba-reggae rock\nsamba-reggae ska\nsamba-reggae surf rock\nsamba-reggae, Brazilian\nsamba-reggae, Latin rock\nsamba-rock\nsamba-rock MPB\nsamba-rock axé\nsamba-rock big band\nsamba-rock big band jazz\nsamba-rock blues\nsamba-rock boogie-woogie\nsamba-rock bossa nova\nsamba-rock cabaret\nsamba-rock carnival pop\nsamba-rock chiptune\nsamba-rock city pop\nsamba-rock exotica\nsamba-rock forró\nsamba-rock freestyle\nsamba-rock frevo\nsamba-rock funk\nsamba-rock funk reggae\nsamba-rock funk soul\nsamba-rock funk-metal\nsamba-rock funk-pop\nsamba-rock funk-rock\nsamba-rock gospel\nsamba-rock gospel rock\nsamba-rock hip-hop\nsamba-rock indie rock\nsamba-rock j-rock\nsamba-rock jazz fusion\nsamba-rock jump blues\nsamba-rock mambo\nsamba-rock pop-funk\nsamba-rock pop-reggae\nsamba-rock pop-rock\nsamba-rock psychedelic rock\nsamba-rock punk\nsamba-rock reggae\nsamba-rock reggae-rock\nsamba-rock show tune\nsamba-rock ska\nsamba-rock ska-punk\nsamba-rock soul\nsamba-rock surf rock\nsamba-rock, Latin funk\nsamba-rock, Latin jazz\nsamba-rock, Latin jazz, free jazz\nsamba-rock, MPB, Brazilian pop\nsamba-rock, MPB, big band jazz\nsamba-rock, Thai rock, blues-rock\nsamba-rock, art-pop\nsamba-rock, big band funk\nsamba-rock, big band jazz\nsamba-rock, big band swing\nsamba-rock, big band, boogie-woogie\nsamba-rock, big band, children's music\nsamba-rock, big band, funk\nsamba-rock, carnival pop\nsamba-rock, classic rock, funk\nsamba-rock, pop-soul, bossa nova\nsamba-rock, psychedelic rock, funk\nsamba-romântico\nsambalexical\nsample house\nsample-based electronic\nsample-based hip-hop\nsatirical R&B\nsatirical brass rock\nsatirical chanson\nsatirical choral\nsatirical country\nsatirical country rock\nsatirical electronic\nsatirical folk\nsatirical hip-hop\nsatirical lullaby\nsatirical march\nsatirical pop\nsatirical protest\nsatirical protest hip-hop\nsatirical protest rock\nsatirical punk\nsatirical rap\nsatirical rock\nsatirical rock, retrowave\nsaxophone house\nscat jazz\nschlager\nschlager ballad\nschlager big band\nschlager bossa nova\nschlager cabaret\nschlager chanson\nschlager children's music\nschlager country\nschlager country-rock\nschlager cumbia\nschlager dansband\nschlager danseband\nschlager dansktop\nschlager disco funk\nschlager euro-pop\nschlager exotica\nschlager folk\nschlager folk-pop\nschlager folk-rock\nschlager football chant\nschlager humppa\nschlager jazz\nschlager jazz waltz\nschlager latin\nschlager levenslied\nschlager lounge jazz\nschlager polka\nschlager polka children's music\nschlager polka novelty\nschlager pop\nschlager pop-rock\nschlager psychedelic pop\nschlager reggae\nschlager reggae-ska\nschlager rock\nschlager rock 'n' roll\nschlager rock and roll\nschlager rock polka\nschlager rockabilly\nschlager rockabilly country\nschlager rockabilly dansband\nschlager rockabilly latin\nschlager rockabilly swing\nschlager rockabilly twist\nschlager rockabilly western swing\nschlager salsa\nschlager samba\nschlager sea shanty\nschlager show tune\nschlager ska\nschlager ska polka\nschlager soft rock\nschlager synth-pop\nschlager tango\nschlager tango orchestral\nschlager waltz\nschlager, 80s pop, novelty\nschlager, 80s synth-pop\nschlager, Dutch pop, levenslied\nschlager, Euro-pop\nschlager, Eurodance\nschlager, European pop, cinematic\nschlager, Hawaiian exotica\nschlager, Italian folk, orchestral\nschlager, Italo-disco\nschlager, Latin mambo, dance\nschlager, Latin pop\nschlager, Latin pop-rock\nschlager, Latin, Neue Deutsche Welle\nschlager, Latin, ballad\nschlager, Latin, dance\nschlager, Latin, theatrical\nschlager, Latin, vintage\nschlager, Neue Deutsche Welle\nschlager, Neue Deutsche Welle, tango\nschlager, Spanish cabaret, big band\nschlager, Volksmusik\nschlager, big band\nschlager, big band, Danish pop\nschlager, big band, polka\nschlager, big band, rockabilly\nschlager, big band, ska-punk\nschlager, big band, swing\nschlager, blues-rock\nschlager, brass band\nschlager, cabaret, Danish\nschlager, cabaret, Swedish\nschlager, cabaret, tango\nschlager, carnaval, Dutch pop\nschlager, carnival, Dutch children's music\nschlager, carnival, German\nschlager, carnival, dance\nschlager, chanson, cinematic\nschlager, chanson, levenslied\nschlager, chanson, orchestral\nschlager, children's music, Christmas\nschlager, children's music, festive\nschlager, chiptune, Volksmusik\nschlager, chiptune, polka\nschlager, cinematic, European ballad\nschlager, cinematic, jazz\nschlager, cinematic, operatic\nschlager, cinematic, pop\nschlager, country, rockabilly\nschlager, dansband, 80s pop\nschlager, dansband, Latin pop\nschlager, dansband, Swedish pop\nschlager, dansband, boogie-woogie\nschlager, dansband, country-swing\nschlager, dansband, folk-pop\nschlager, dansband, pop\nschlager, eurodance\nschlager, eurodance, cajun\nschlager, eurodance, novelty\nschlager, exotica\nschlager, exotica, mambo\nschlager, exotica, vintage German\nschlager, folk, vintage\nschlager, folk-pop\nschlager, folk-pop, children's music\nschlager, gypsy jazz, balkan\nschlager, gypsy jazz, dance\nschlager, latin, Neue Deutsche Welle\nschlager, latin, big band\nschlager, latin, pop\nschlager, latin, salsa\nschlager, levenslied, Dutch pop\nschlager, levenslied, dance\nschlager, levenslied, pop-rock\nschlager, mambo\nschlager, novelty, Dutch\nschlager, party, electronic\nschlager, polka, Christmas\nschlager, polka, Danish Christmas\nschlager, polka, German\nschlager, polka, Swedish\nschlager, polka, Swedish Christmas\nschlager, polka, children's music\nschlager, polka, educational\nschlager, polka, novelty\nschlager, polka, ska\nschlager, pop, Swedish\nschlager, pop, vintage\nschlager, retro, Latin\nschlager, rock 'n' roll\nschlager, rock 'n' roll, doo-wop\nschlager, rock, polka\nschlager, sea shanty\nschlager, sea shanty, German folk\nschlager, spaghetti western, retro\nschlager, surf rock\nschlager, synth-pop\nschlager, synth-pop, Christmas novelty\nschlager, tango, bolero\nschlager, theatrical pop, levenslied\nschlager, theatrical pop, orchestral pop\nschlager, tropical, pop\nschlager, waltz\nschlager, waltz, choral\nschlager, waltz, cinematic\nschlager, western swing, novelty\nschlager, western swing, polka\nschlager-pop\nschlager-pop ska-punk\nschlager-pop, 80s synth-pop\nschlager-rock\nschlager-rock, heavy metal, vibraphone\nsci-fi\nsci-fi country\nsci-fi country rock\nsci-fi dub\nsci-fi electro-funk\nsci-fi electronic\nsci-fi folk\nsci-fi funk\nsci-fi hip hop\nsci-fi hip-hop\nsci-fi merengue\nsci-fi metal\nsci-fi pop\nsci-fi pop-rap\nsci-fi punk rock\nsci-fi rock\nsci-fi rock cabaret\nsci-fi rock opera\nsci-fi ska reggae\nsci-fi soca\nsci-fi sound design\nsci-fi swing\nsci-fi trance\nsci-fi trap\nsci-fi western swing\nscreamo\nsea shanty\nsea shanty Celtic folk\nsea shanty big band\nsea shanty bluegrass\nsea shanty bluegrass celtic folk\nsea shanty bluegrass folk\nsea shanty bluegrass folk-rock\nsea shanty blues rock\nsea shanty boogie-woogie\nsea shanty brass\nsea shanty cabaret swing\nsea shanty chiptune\nsea shanty cinematic\nsea shanty comedy\nsea shanty country folk\nsea shanty country folk-rock\nsea shanty country-folk\nsea shanty cumbia\nsea shanty dark cabaret\nsea shanty fantasy folk\nsea shanty folk\nsea shanty folk bluegrass\nsea shanty folk dance\nsea shanty folk polka\nsea shanty folk waltz\nsea shanty folk-pop\nsea shanty folk-punk\nsea shanty folk-rock\nsea shanty folk-rock polka\nsea shanty gypsy jazz\nsea shanty gypsy jazz folk\nsea shanty klezmer\nsea shanty marching band\nsea shanty metal\nsea shanty orchestral\nsea shanty polka\nsea shanty polka folk\nsea shanty polka klezmer\nsea shanty polka ska\nsea shanty power metal\nsea shanty pub folk\nsea shanty punk\nsea shanty ragtime\nsea shanty rock\nsea shanty schlager\nsea shanty show tune\nsea shanty ska\nsea shanty ska punk\nsea shanty waltz\nsea shanty, Balkan folk, Eastern European\nsea shanty, Celtic folk\nsea shanty, Celtic folk, anthemic\nsea shanty, Celtic folk, comedic\nsea shanty, Celtic folk, folk rock\nsea shanty, Celtic folk, modern folk\nsea shanty, Celtic folk-rock\nsea shanty, Christmas, folk\nsea shanty, Irish folk\nsea shanty, Latin folk\nsea shanty, Latin folk, Caribbean\nsea shanty, Polish folk\nsea shanty, Polish folk, folk rock\nsea shanty, Russian folk, upbeat\nsea shanty, celtic folk\nsea shanty, children's music, synth pop\nsea shanty, festive, folk\nsea shanty, festive, lo-fi\nsea shanty, festive, theatrical\nsea shanty, folk pop, comedic\nsea shanty, folk, choral\nsea shanty, folk, singer-songwriter\nsea shanty, folk, waltz\nsea shanty, maritime folk, upbeat\nsea shanty, pirate metal, folk rock\nsea shanty, polka, folk\nsea shanty, polka, ska\nsea shanty, polka, video game music\nsea shanty, pop, electronic\nsea shanty, pub rock, theatrical\nsea shanty, synth pop, comedic\nsea shanty, theatrical, folk rock\nsea shanty, theatrical, waltz\nsea shanty, video game music, upbeat\nsea shanty, waltz, polka\nsea shanty-pop\nsea shanty-punk\nsecond-line\nsecond-line brass\nsecond-line jazz\nsensual R&B\nsensual pop\nsentimental C-pop\nsentimental Christmas ballad\nsentimental ballad\nsentimental ballad, Forró, anthemic pop\nsentimental ballad, hip-hop, piano\nsentimental duet\nsentimental folk\nsentimental hip-hop\nsentimental piano\nsentimental piano ballad\nsentimental piano ballad hip-hop\nsentimental piano, electronic, Chinese MC\nsentimental pop\nsentimental pop R&B\nsentimental pop ballad\nsentimental pop ballad, EDM\nsentimental pop ballad, EDM, hip-hop\nsentimental pop ballad, Eurodance\nsentimental pop chanson\nsentimental pop gospel\nsentimental pop jazz\nsentimental pop, Brazilian pop\nsentimental pop, Central Asian\nsentimental pop, Central Asian folk\nsentimental pop, Central Asian pop\nsentimental pop, East Asian influence\nsentimental pop, East Asian pop\nsentimental pop, Eastern European folk\nsentimental pop, Javanese influence\nsentimental pop, Romanian folk\nsentimental pop, South Asian pop\nsentimental pop, Southeast Asian folk\nsentimental pop, Southeast Asian pop\nsentimental pop, Vietnamese folk\nsentimental pop, Vietnamese influence\nsentimental pop, Vietnamese pop\nsentimental pop, chiptune, J-pop\nsentimental pop, cinematic, traditional Indonesian\nsentimental pop, cumbia\nsentimental pop, musical theater\nsentimental pop, smooth jazz\nsentimental pop, traditional Chinese, ballad\nsentimental pop, traditional Chinese, pop-rock\nsentimental pop-ballad\nsentimental pop-rap\nsentimental pop-rock\nsentimental trap\nsentimental waltz\nseresta\nsertanejo\nsertanejo MPB\nsertanejo acústico\nsertanejo baião\nsertanejo big band\nsertanejo blues-rock\nsertanejo bolero\nsertanejo bossa nova\nsertanejo brega\nsertanejo brega pop-rock\nsertanejo chiptune\nsertanejo choro\nsertanejo country\nsertanejo country-rock\nsertanejo de baião\nsertanejo de boi\nsertanejo de bumbá\nsertanejo de fado\nsertanejo de favela\nsertanejo de raiz\nsertanejo de sofrência\nsertanejo de v-choro\nsertanejo de vaquejada\nsertanejo electro\nsertanejo electronic\nsertanejo eletrônico\nsertanejo fado\nsertanejo flamenco\nsertanejo forró\nsertanejo forró brega\nsertanejo funk\nsertanejo fusion\nsertanejo futurista\nsertanejo gospel\nsertanejo hip-hop\nsertanejo lo-fi\nsertanejo piseiro\nsertanejo pop\nsertanejo pop rock\nsertanejo pop trap\nsertanejo pop, Brazilian funk, trap\nsertanejo pop-rock\nsertanejo power\nsertanejo power ballad\nsertanejo punk\nsertanejo rock\nsertanejo rockabilly\nsertanejo romântico\nsertanejo sofrência\nsertanejo tango\nsertanejo trap\nsertanejo universitário\nsertanejo, Brazilian romantic, acoustic\nsertanejo, MPB\nsertanejo, acoustic pop-rock\nsertanejo, axé\nsertanejo, big band, samba-rock\nsertanejo, bolero\nsertanejo, country-folk\nsertanejo, electronic dance\nsertanejo, electronic dance, big room\nsertanejo, forró\nsertanejo, forró eletrônico\nsertanejo, forró eletrônico, R&B\nsertanejo, forró, Brazilian folk\nsertanejo, forró, baião\nsertanejo, forró, chiptune\nsertanejo, forró, cinematic\nsertanejo, forró, gospel\nsertanejo, forró, lo-fi\nsertanejo, forró, piseiro\nsertanejo, pagode, arrocha\nsertanejo, pagode, ballad\nsertanejo, pagode, pop-rock\nsertanejo, pop-rock\nsertanejo, pop-rock, forró\nsertanejo, pop-rock, pagode\nsertanejo, romantic pop, forró\nsertanejo-rock\nshakuhachi\nshamanic folk\nshamanic rock\nshamanic tribal\nshamisen rock\nshanson\nshanson, electronic, folk\nshibuya-kei, breakcore, chiptune\nshimmer pop\nshimmer rock\nshoegaze\nshoegaze C-pop\nshoegaze J-rock\nshoegaze R&B\nshoegaze alt-rock\nshoegaze alternative\nshoegaze alternative metal\nshoegaze alternative rock\nshoegaze alternative rock post-hardcore\nshoegaze ambient\nshoegaze arena rock\nshoegaze ballad\nshoegaze bossa nova\nshoegaze chiptune\nshoegaze cinematic\nshoegaze cloud rap\nshoegaze darkwave\nshoegaze dream pop\nshoegaze dream pop alternative rock\nshoegaze dream pop ambient\nshoegaze dream pop indie rock\nshoegaze dream pop lo-fi hip-hop\nshoegaze dream pop noise rock\nshoegaze dream pop post-hardcore\nshoegaze dream pop post-rock\nshoegaze dream-pop\nshoegaze drone\nshoegaze drone metal\nshoegaze electronic\nshoegaze electronic rock\nshoegaze emo\nshoegaze emo rap\nshoegaze emo rap alternative rock\nshoegaze emo rock\nshoegaze emo-rock\nshoegaze folk\nshoegaze funk\nshoegaze funk-rock\nshoegaze future bass\nshoegaze garage rock\nshoegaze grunge\nshoegaze grunge alt-rock\nshoegaze grunge alternative rock\nshoegaze hip hop\nshoegaze hip-hop\nshoegaze hyperpop\nshoegaze indie\nshoegaze indie dance\nshoegaze indie pop\nshoegaze indie pop-rock\nshoegaze indie rock\nshoegaze indie rock dream-pop\nshoegaze indie rock lo-fi\nshoegaze indie rock post-hardcore\nshoegaze indie-folk\nshoegaze indie-pop\nshoegaze industrial\nshoegaze industrial rock\nshoegaze j-rock\nshoegaze jazz\nshoegaze lo-fi\nshoegaze lo-fi hip hop\nshoegaze lo-fi hip-hop\nshoegaze lounge jazz\nshoegaze metal\nshoegaze metalcore\nshoegaze noise pop\nshoegaze noise rock\nshoegaze noise rock J-rock\nshoegaze noise-pop\nshoegaze pop\nshoegaze pop rock\nshoegaze pop-punk\nshoegaze pop-punk post-hardcore\nshoegaze pop-rock\nshoegaze post-grunge\nshoegaze post-hardcore\nshoegaze post-hardcore emo\nshoegaze post-metal\nshoegaze post-punk\nshoegaze post-rock\nshoegaze post-rock alternative rock\nshoegaze post-rock post-hardcore\nshoegaze psychedelic rock\nshoegaze punk\nshoegaze punk rock\nshoegaze rap\nshoegaze reggaeton\nshoegaze rock\nshoegaze surf-punk noise-rock\nshoegaze synth-pop\nshoegaze synth-pop chiptune\nshoegaze trance\nshoegaze trap\nshoegaze trap R&B\nshoegaze trap emo-rap\nshoegaze trap metal\nshoegaze trap nu-metal\nshoegaze trip-hop\nshoegaze vaporwave\nshoegaze, C-pop, cinematic\nshoegaze, C-pop, dream pop\nshoegaze, C-pop, indie rock\nshoegaze, C-pop, post-rock\nshoegaze, EBM, ambient\nshoegaze, French pop, cinematic\nshoegaze, Italian rock, melancholic\nshoegaze, J-rock\nshoegaze, J-rock, alternative rock\nshoegaze, J-rock, ambient\nshoegaze, J-rock, dream pop\nshoegaze, J-rock, electronic\nshoegaze, J-rock, emotional\nshoegaze, J-rock, funk rock\nshoegaze, J-rock, indie rock\nshoegaze, J-rock, post-rock\nshoegaze, K-pop, electronic\nshoegaze, Latin pop, ambient\nshoegaze, acoustic ballad, Mandarin rock\nshoegaze, alt-rock, experimental\nshoegaze, alternative R&B, hyperpop\nshoegaze, alternative rock\nshoegaze, alternative rock, C-pop\nshoegaze, alternative rock, Filipino indie\nshoegaze, alternative rock, Filipino rock\nshoegaze, alternative rock, French indie\nshoegaze, alternative rock, Japanese pop\nshoegaze, alternative rock, Japanese rock\nshoegaze, alternative rock, Spanish rock\nshoegaze, alternative rock, ambient\nshoegaze, alternative rock, ambient pop\nshoegaze, alternative rock, chiptune\nshoegaze, alternative rock, dream pop\nshoegaze, alternative rock, gothic rock\nshoegaze, alternative rock, indie\nshoegaze, alternative rock, indie rock\nshoegaze, alternative rock, industrial\nshoegaze, alternative rock, lo-fi\nshoegaze, alternative rock, noise rock\nshoegaze, alternative rock, post-hardcore\nshoegaze, alternative rock, post-rock\nshoegaze, alternative rock, psychedelic rock\nshoegaze, alternative rock, punk rock\nshoegaze, ambient pop, Chinese indie\nshoegaze, ambient, C-pop\nshoegaze, ambient, Chinese electronic\nshoegaze, ambient, Italian pop\nshoegaze, ambient, K-pop\nshoegaze, ambient, Turkish pop\nshoegaze, ambient, alternative rock\nshoegaze, ambient, chiptune\nshoegaze, ambient, cinematic\nshoegaze, ambient, electronic\nshoegaze, ambient, funk rock\nshoegaze, ambient, noise rock\nshoegaze, ambient, piano ballad\nshoegaze, arena rock\nshoegaze, arena rock, ambient\nshoegaze, bossa nova, dream pop\nshoegaze, chiptune, alternative rock\nshoegaze, chiptune, electronic\nshoegaze, chiptune, glitch\nshoegaze, cinematic rock\nshoegaze, cinematic rock, ambient\nshoegaze, cinematic rock, progressive rock\nshoegaze, cinematic, dark ambient\nshoegaze, cinematic, dream pop\nshoegaze, cinematic, gamelan\nshoegaze, cloud rap, ambient\nshoegaze, dark pop, industrial rock\nshoegaze, doom metal, ambient\nshoegaze, dream pop, C-pop\nshoegaze, dream pop, Chinese indie\nshoegaze, dream pop, Chinese rock\nshoegaze, dream pop, French pop\nshoegaze, dream pop, K-pop\nshoegaze, dream pop, alternative rock\nshoegaze, dream pop, indie pop\nshoegaze, dream pop, indie rock\nshoegaze, dream pop, lo-fi hip hop\nshoegaze, dream-pop, alternative rock\nshoegaze, dream-pop, post-rock\nshoegaze, dream-pop, psychedelic funk\nshoegaze, electronic, C-pop\nshoegaze, electronic, Mandarin pop\nshoegaze, electronic, Russian pop\nshoegaze, electronic, ambient\nshoegaze, emo, alternative rock\nshoegaze, emo, metalcore\nshoegaze, emo-rap, hyperpop\nshoegaze, emo-rap, nu-metal\nshoegaze, emo-rap, post-rock\nshoegaze, eurodance, trance\nshoegaze, future bass, ambient\nshoegaze, hyperpop\nshoegaze, hyperpop, ambient\nshoegaze, hyperpop, electronic\nshoegaze, hyperpop, emo-rap\nshoegaze, indie rock, Mandarin pop\nshoegaze, indie rock, Vietnamese pop\nshoegaze, indie rock, alternative rock\nshoegaze, indie rock, ambient\nshoegaze, indie rock, chiptune\nshoegaze, indie rock, cinematic\nshoegaze, indie rock, noise rock\nshoegaze, indie rock, psychedelic rock\nshoegaze, industrial, ambient\nshoegaze, lo-fi R&B, hip-hop\nshoegaze, lo-fi hip hop\nshoegaze, lo-fi hip hop, ambient\nshoegaze, lo-fi hip hop, indie rock\nshoegaze, lo-fi, C-pop\nshoegaze, lo-fi, Thai indie\nshoegaze, lo-fi, ambient\nshoegaze, lo-fi, electronic\nshoegaze, lo-fi, hip-hop\nshoegaze, math rock, C-pop\nshoegaze, math rock, emo\nshoegaze, math rock, indie rock\nshoegaze, noise rock\nshoegaze, noise rock, alternative rock\nshoegaze, noise rock, ambient\nshoegaze, noise rock, chiptune\nshoegaze, noise rock, cinematic\nshoegaze, noise rock, dream pop\nshoegaze, noise rock, experimental C-pop\nshoegaze, noise rock, indie rock\nshoegaze, noise rock, lo-fi\nshoegaze, noise rock, lo-fi indie pop\nshoegaze, noise rock, metalcore\nshoegaze, noise rock, post-punk\nshoegaze, noise rock, psychedelic funk\nshoegaze, noise-pop, lo-fi\nshoegaze, post-hardcore, chiptune\nshoegaze, post-hardcore, emo\nshoegaze, post-hardcore, indie rock\nshoegaze, post-hardcore, noise rock\nshoegaze, post-metal, doomgaze\nshoegaze, post-punk, electronic\nshoegaze, post-rock, C-pop\nshoegaze, post-rock, Chinese experimental\nshoegaze, post-rock, Chinese indie\nshoegaze, post-rock, Chinese rock\nshoegaze, post-rock, Finnish indie\nshoegaze, post-rock, Japanese indie\nshoegaze, post-rock, Japanese rock\nshoegaze, post-rock, acoustic\nshoegaze, post-rock, acoustic ballad\nshoegaze, post-rock, alt-rock\nshoegaze, post-rock, alternative rock\nshoegaze, post-rock, ambient\nshoegaze, post-rock, blues-rock\nshoegaze, post-rock, chiptune\nshoegaze, post-rock, cinematic\nshoegaze, post-rock, cinematic rock\nshoegaze, post-rock, dream pop\nshoegaze, post-rock, dream-pop\nshoegaze, post-rock, dreamy indie\nshoegaze, post-rock, emo\nshoegaze, post-rock, experimental\nshoegaze, post-rock, folk\nshoegaze, post-rock, hard rock\nshoegaze, post-rock, indie rock\nshoegaze, post-rock, lo-fi\nshoegaze, post-rock, lo-fi indie\nshoegaze, post-rock, math rock\nshoegaze, post-rock, noise rock\nshoegaze, post-rock, noise-rock\nshoegaze, post-rock, post-hardcore\nshoegaze, psychedelic rock\nshoegaze, rock, C-pop\nshoegaze, rock, Mandarin indie\nshoegaze, surf rock\nshoegaze, surf-rock, noise-pop\nshoegaze, synth-rock, electro-rock\nshoegaze, trap, Mandopop\nshoegaze, trap, rock\nsholof, turbo-folk\nshow tune\nshow tune a cappella\nshow tune big band\nshow tune big band jazz\nshow tune blues-rock\nshow tune boogie-woogie\nshow tune boogie-woogie ragtime\nshow tune cabaret\nshow tune calypso big band\nshow tune calypso exotica\nshow tune chiptune\nshow tune exotica big band\nshow tune gospel\nshow tune gospel big band\nshow tune hip-hop\nshow tune jazz\nshow tune lounge jazz\nshow tune novelty\nshow tune polka\nshow tune pop\nshow tune pop-rock\nshow tune pop-rock world music\nshow tune punk rock\nshow tune ragtime\nshow tune ragtime big band\nshow tune ragtime swing\nshow tune rock\nshow tune rockabilly\nshow tune rockabilly classic rock power ballad\nshow tune rockabilly novelty\nshow tune rockabilly swing\nshow tune salsa\nshow tune samba big band\nshow tune sea shanty\nshow tune swing\nshow tune swing jazz\nshow tune tropical\nshow tune, Eurodance\nshow tune, Latin cumbia, theatrical pop\nshow tune, Latin exotica, theatrical\nshow tune, Latin pop, theatrical\nshow tune, Latin, big band\nshow tune, Latin, exotica\nshow tune, Latin, samba\nshow tune, Latin, theatrical\nshow tune, Latin, upbeat\nshow tune, Latin, world music\nshow tune, big band jazz\nshow tune, big band jazz, novelty\nshow tune, big band swing, children's music\nshow tune, big band, French chanson\nshow tune, big band, Halloween\nshow tune, big band, cartoon\nshow tune, big band, holiday\nshow tune, big band, novelty\nshow tune, big band, retro\nshow tune, big band, retro swing\nshow tune, big band, rock and roll\nshow tune, big band, salsa\nshow tune, big band, satirical\nshow tune, big band, swing\nshow tune, big band, theatrical\nshow tune, big band, vintage\nshow tune, big band, vintage swing\nshow tune, boogie-woogie, R&B\nshow tune, boogie-woogie, big band\nshow tune, boogie-woogie, jazz\nshow tune, boogie-woogie, swing\nshow tune, boogie-woogie, theatrical rock\nshow tune, chiptune, theatrical pop\nshow tune, cinematic ballad\nshow tune, circus, polka\nshow tune, emotional ballad, C-pop\nshow tune, gospel, big band\nshow tune, honky-tonk, musical comedy\nshow tune, jump blues, swing\nshow tune, klezmer, big band\nshow tune, klezmer, polka\nshow tune, novelty, dark comedy\nshow tune, novelty, theatrical\nshow tune, orchestral, festive\nshow tune, polka, levenslied\nshow tune, polka, theatrical\nshow tune, polka, theatrical pop\nshow tune, pop-rock, Christmas\nshow tune, pop-rock, big band\nshow tune, pop-rock, theatrical\nshow tune, ragtime, Christmas\nshow tune, ragtime, big band\nshow tune, ragtime, circus\nshow tune, ragtime, comedic\nshow tune, ragtime, gospel\nshow tune, ragtime, jazz\nshow tune, ragtime, satirical pop\nshow tune, ragtime, swing\nshow tune, ragtime, swing rock\nshow tune, ragtime, theatrical\nshow tune, ragtime, vaudeville\nshow tune, retro-soul, big band\nshow tune, rock and roll, R&B\nshow tune, rock and roll, big band\nshow tune, rock and roll, doo-wop\nshow tune, rockabilly, big band\nshow tune, rockabilly, swing\nshow tune, sea shanty, theatrical\nshow tune, surf rock, punk rock\nshow tune, swing, big band\nshow tune, swing, theatrical\nshow tune, synth big band, Latin pop\nshow tune, theatrical, Christmas\nshow tune, theatrical, vintage cartoon\nshow tune, video game music, whimsical\nshow tune, video game, synth pop\nshow tune, vintage pop, doo-wop\nshow tune, vintage rock and roll, big band\nshow tune, vintage soul, big band\nshow tune, vintage swing, big band\nshow tune, vintage, swing\nshowa-era pop\nshowtime\nshowtune\nshowtune pop-rock\nshowtune, electronic, theatrical\nshowtune, theatrical, synth pop\nshred funk\nshred guitar\nshred guitar, city pop, video game music\nshred metal\nshred metal chiptune\nshred metal chiptune synthwave\nshred metal funk-rock\nshred metal progressive metal\nshred metal, video game music, chiptune\nshred rock\nsierreño\nsierreño chiptune\nsierreño corrido\nsierreño corrido tumbado\nsierreño corridos tumbados\nsierreño flamenco\nsierreño hardstyle\nsierreño hip-hop\nsierreño lo-fi hip hop\nsierreño lo-fi hip-hop\nsierreño pop\nsierreño pop-rap\nsierreño pop-rock\nsierreño psychedelic rock\nsierreño punk\nsierreño ranchera\nsierreño rock\nsierreño trap\nsierreño, Latin folk, psychedelic\nsierreño, Latin trap\nsierreño, urban pop, regional Mexican\nsilent film score\nsinger-songwriter\nsinger-songwriter MPB\nsinger-songwriter acoustic blues\nsinger-songwriter acoustic pop\nsinger-songwriter acoustic pop contemporary R&B\nsinger-songwriter alt-country\nsinger-songwriter alt-rock\nsinger-songwriter alternative rock\nsinger-songwriter ballad\nsinger-songwriter blues\nsinger-songwriter blues jazz\nsinger-songwriter blues soul\nsinger-songwriter blues-rock\nsinger-songwriter cinematic\nsinger-songwriter classic rock\nsinger-songwriter country gospel\nsinger-songwriter dansband\nsinger-songwriter emo-acoustic\nsinger-songwriter fado\nsinger-songwriter flamenco\nsinger-songwriter folk\nsinger-songwriter folk blues\nsinger-songwriter folk gospel\nsinger-songwriter folk rock\nsinger-songwriter folk-rock\nsinger-songwriter gospel\nsinger-songwriter heartland rock\nsinger-songwriter hip-hop\nsinger-songwriter indie pop R&B\nsinger-songwriter indie rock\nsinger-songwriter jazz\nsinger-songwriter jazz cabaret\nsinger-songwriter jazz-rock\nsinger-songwriter jazzy soft-rock\nsinger-songwriter lo-fi hip hop\nsinger-songwriter lo-fi hip-hop\nsinger-songwriter pop\nsinger-songwriter pop R&B\nsinger-songwriter pop-rock\nsinger-songwriter post-rock\nsinger-songwriter protest\nsinger-songwriter psychedelic pop\nsinger-songwriter reggae\nsinger-songwriter rock\nsinger-songwriter rumba flamenco\nsinger-songwriter soft rock\nsinger-songwriter world music\nsinger-songwriter, Americana\nsinger-songwriter, Brazilian MPB\nsinger-songwriter, Christian contemporary\nsinger-songwriter, Latin folk\nsinger-songwriter, Latin pop\nsinger-songwriter, Latin pop, classical\nsinger-songwriter, MPB\nsinger-songwriter, alt-country\nsinger-songwriter, alt-rock\nsinger-songwriter, alternative rock\nsinger-songwriter, arena rock\nsinger-songwriter, blues, chamber pop\nsinger-songwriter, boogie-woogie rock\nsinger-songwriter, bossa nova, holiday\nsinger-songwriter, bossa nova, latin folk\nsinger-songwriter, classic rock, indie rock\nsinger-songwriter, contemporary Christian\nsinger-songwriter, gypsy jazz, klezmer\nsinger-songwriter, indie folk\nsinger-songwriter, indie pop\nsinger-songwriter, indie pop, lo-fi hip hop\nsinger-songwriter, jazz, big band\nsinger-songwriter, piano rock, theatrical\nsinger-songwriter, pop-rock, cinematic\nsinger-songwriter, post-rock, acoustic\nsinger-songwriter, rock, cantautore\nsinger-songwriter, sad sierreño\nsinger-songwriter, soft rock\nsinger-songwriter, spoken word\nska\nska Latin jazz world music\nska Latin rock\nska big band\nska boogaloo\nska brass\nska calypso\nska children's music\nska cumbia\nska cumbia rock\nska dancehall\nska funk\nska funk Latin rock\nska funk Neue Deutsche Welle\nska funk big band\nska funk pop\nska gospel\nska mariachi\nska metal\nska new wave Eastern European rock\nska novelty\nska polka\nska polka Latin dance\nska polka folk\nska polka schlager\nska pop\nska pop rock\nska pop-rock\nska power pop\nska punk\nska punk funk rock\nska punk, Latin rock\nska reggae\nska reggae Latin\nska reggae balkan brass\nska reggae chiptune\nska reggae dancehall\nska reggae funk\nska reggae fusion\nska reggae rock\nska revival\nska rock\nska rock boogie-woogie\nska rock pub rock\nska rock reggae\nska rockabilly\nska rocksteady\nska soul\nska swing\nska swing big band\nska worship\nska, German polka, brass band\nska, Indonesian pop\nska, Javanese fusion\nska, Latin jazz\nska, Latin rock\nska, Latin rock, cumbia\nska, Latin rock, merengue\nska, Latin, French\nska, Latin, funk\nska, Latin, party\nska, North African pop\nska, Russian chanson\nska, big band, Italian folk\nska, big band, children's music\nska, big band, jazz\nska, big band, rock and roll\nska, breakcore, big band\nska, cabaret, protest\nska, children's music, Japanese\nska, mariachi\nska, polka, Dutch party\nska-cumbia\nska-funk\nska-funk, psychedelic rock, experimental\nska-gospel\nska-jazz\nska-polka\nska-polo\nska-pop\nska-pop Latin rock\nska-pop reggae\nska-pop, French chanson, funk\nska-punk\nska-punk Christian rock\nska-punk French rock\nska-punk J-rock\nska-punk Latin rock\nska-punk Latin rock jazz fusion\nska-punk Neue Deutsche Härte\nska-punk Neue Deutsche Welle\nska-punk alternative rock\nska-punk big band\nska-punk big band rock\nska-punk big beat\nska-punk boogie-woogie\nska-punk boogie-woogie rock\nska-punk cabaret\nska-punk chiptune\nska-punk chiptune rock\nska-punk circus\nska-punk comedy rock\nska-punk crossover rock\nska-punk crossover thrash\nska-punk cumbia\nska-punk cumbia folk\nska-punk cumbia rock\nska-punk dancehall\nska-punk disco-funk\nska-punk flamenco\nska-punk folk punk\nska-punk folk-punk\nska-punk folk-rock\nska-punk forró\nska-punk funk\nska-punk funk-rock\nska-punk funk-rock metalcore\nska-punk gospel rock\nska-punk gypsy punk\nska-punk gypsy-punk\nska-punk happy hardcore\nska-punk hard rock\nska-punk hardcore punk\nska-punk hip-hop\nska-punk horror punk\nska-punk indie rock\nska-punk klezmer rock\nska-punk latin rock\nska-punk lo-fi\nska-punk mariachi\nska-punk merengue rock\nska-punk metal\nska-punk metalcore\nska-punk narrative punk\nska-punk new wave\nska-punk nintendocore\nska-punk norteño cumbia\nska-punk party rock\nska-punk pirate rock\nska-punk political punk\nska-punk political rock\nska-punk polka\nska-punk polka-punk\nska-punk polka-rock\nska-punk pop-punk\nska-punk pop-rock\nska-punk post-hardcore\nska-punk power metal\nska-punk power pop\nska-punk power-pop\nska-punk progressive metal\nska-punk protest\nska-punk protest punk\nska-punk protest rock\nska-punk punk rock\nska-punk rap-rock\nska-punk reggae\nska-punk reggae dub\nska-punk reggae rock\nska-punk reggae-rock\nska-punk rock\nska-punk rock and roll\nska-punk rock en español\nska-punk rockabilly\nska-punk show tune\nska-punk speed metal\nska-punk street punk\nska-punk surf rock\nska-punk surf-punk\nska-punk swing revival\nska-punk swing rock\nska-punk theatrical rock\nska-punk thrash metal\nska-punk turbo-folk\nska-punk video game rock\nska-punk, Balkan beat\nska-punk, Balkan brass\nska-punk, Balkan brass rock\nska-punk, Balkan brass, cabaret\nska-punk, Balkan brass, gypsy punk\nska-punk, Balkan brass, political rap\nska-punk, Balkan brass, polka\nska-punk, Balkan brass, punk rock\nska-punk, Balkan folk\nska-punk, Balkan folk, Latin rock\nska-punk, Balkan folk, punk rock\nska-punk, Balkan folk-punk\nska-punk, Balkan punk\nska-punk, Balkan rock\nska-punk, Deutschpunk\nska-punk, Deutschpunk, punk rock\nska-punk, Eastern European folk\nska-punk, Eurodance\nska-punk, French chanson, gypsy-punk\nska-punk, French rock\nska-punk, German Schlager\nska-punk, German fun-punk\nska-punk, German rock\nska-punk, Greek folk\nska-punk, Italian rock, punk rock\nska-punk, J-rock\nska-punk, Japanese rock\nska-punk, Latin brass, samba-rock\nska-punk, Latin carnival, Japanese rock\nska-punk, Latin folk, Andean\nska-punk, Latin jazz, instrumental\nska-punk, Latin percussion\nska-punk, Latin percussion, punk rock\nska-punk, Latin pop-rock, Italian\nska-punk, Latin rock\nska-punk, Latin rock, cinematic\nska-punk, Latin rock, cumbia\nska-punk, Latin rock, electronic\nska-punk, Latin rock, funk\nska-punk, Latin rock, metal\nska-punk, Latin rock, punk\nska-punk, Latin, funk\nska-punk, Latin-funk\nska-punk, Neue Deutsche Härte\nska-punk, Neue Deutsche Welle\nska-punk, Nintendocore\nska-punk, Polish folk\nska-punk, Russian bard, theatrical rock\nska-punk, Russian chanson\nska-punk, Russian folk\nska-punk, Russian folk, fusion\nska-punk, Russian folk-punk\nska-punk, Russian folk-rock\nska-punk, Russian rock\nska-punk, Sundanese pop-rock\nska-punk, Turkish rock, chiptune\nska-punk, Ukrainian folk\nska-punk, balkan beat\nska-punk, balkan folk\nska-punk, big band\nska-punk, big band jazz\nska-punk, big band rock\nska-punk, big band swing\nska-punk, big band, Japanese rock\nska-punk, big band, chiptune\nska-punk, big band, free jazz\nska-punk, big band, funk\nska-punk, big band, fusion\nska-punk, big band, jazz\nska-punk, big band, jazz fusion\nska-punk, big band, punk\nska-punk, big band, punk rock\nska-punk, big band, rock\nska-punk, big band, surf rock\nska-punk, big band, swing\nska-punk, big band, theatrical pop\nska-punk, big band, theatrical rock\nska-punk, brass band, theatrical rock\nska-punk, cabaret punk\nska-punk, cabaret rock\nska-punk, cabaret, Russian spoken word\nska-punk, cabaret, theatrical rock\nska-punk, carnival rock\nska-punk, choral, indie folk\nska-punk, cinematic, ballad\nska-punk, cinematic, emotional\nska-punk, circus, theatrical\nska-punk, comedy rock\nska-punk, electronic, breakbeat\nska-punk, eurodance\nska-punk, folk rock\nska-punk, folk rock, electronic\nska-punk, folk-punk, Eastern European\nska-punk, folk-punk, Russian\nska-punk, folk-rock, festive\nska-punk, folk-rock, theatrical\nska-punk, happy hardcore\nska-punk, hard rock\nska-punk, hard rock, atmospheric\nska-punk, heavy metal\nska-punk, heavy metal, polka\nska-punk, hip-hop, folk fusion\nska-punk, hyperpop, electronic\nska-punk, jazz, Portuguese pop\nska-punk, jazz, cinematic\nska-punk, jazz, theatrical\nska-punk, klezmer, punk rock\nska-punk, lo-fi hip-hop, punk rock\nska-punk, marching band, video game music\nska-punk, melodic hardcore\nska-punk, political punk, punk rock\nska-punk, political reggae\nska-punk, polka\nska-punk, polka, Neue Deutsche Welle\nska-punk, polka, brass rock\nska-punk, polka, experimental\nska-punk, polka, party\nska-punk, polka, punk\nska-punk, polka, punk rock\nska-punk, polka, surf rock\nska-punk, polka-punk, punk rock\nska-punk, pop-rock\nska-punk, power ballad, Indonesian spoken word\nska-punk, punk rock\nska-punk, punk rock, jazz fusion\nska-punk, regional Mexican\nska-punk, regional Mexican, fusion\nska-punk, revolutionary rock\nska-punk, rock, hard rock\nska-punk, rockabilly\nska-punk, schlager, garmonik\nska-punk, second-line brass\nska-punk, speed metal\nska-punk, tarantella, punk rock\nska-punk, theatrical cabaret\nska-punk, theatrical rock\nska-punk, theatrical rock, punk\nska-punk, theatrical, show tune\nska-punk, video game music\nska-punk, video game soundtrack\nska-punk, video game, chiptune\nska-rap\nska-reggae\nska-reggae metal\nska-reggae, Latin rock, brass\nska-reggae, ambient\nska-reggae, hardcore punk\nska-rock\nska-salsa\nska-swing\nskate punk\nskate punk chiptune\nskate punk comedy rock\nskate punk crossover thrash\nskate punk metalcore\nskate punk post-rock\nskate punk power metal\nskate punk rap-rock\nskate punk thrash metal\nskate punk, J-rock\nskate punk, chiptune\nskate punk, chiptune metalcore\nskate punk, melodic hardcore\nskate punk, pop-punk, post-rock\nskate punk, thrash metal\nskate-punk\nskate-punk pop-punk\nskiffle\nskiffle country-folk\nskiffle folk\nskiffle ragtime\nskiffle rock\nskiffle, early rock and roll\nslap house\nslap house chiptune\nslap house dance-pop\nslap house dark pop\nslap house funk carioca\nslap house future bass\nslap house tech house\nslap house vaporwave\nslap house, Brazilian bass\nslap house, Brazilian bass, EDM\nslap house, Brazilian bass, cinematic\nslap house, Brazilian bass, electronic\nslap house, Brazilian funk\nslap house, EDM, Russian pop\nslap house, R&B\nslap house, Russian bass house\nslap house, Russian pop\nslap house, Russian pop, dark electronic\nslap house, Russian pop-rap, deep house\nslap house, Russian pop-rap, trap\nslap house, Ukrainian folk\nslap house, darkwave\nslap house, deep house\nslap house, deep house, Russian pop-rap\nslap house, eurodance, EDM\nslap house, rap, art rock\nslow R&B\nslow ballad\nslow blues jazz\nslow drill\nslow jam\nslow jam R&B\nslow jam soul\nslow jam, dream pop, ambient soul\nslow jam, synth soul, R&B\nslow piano ballad\nslow pop\nslow rock\nslow rock ballad\nslow rock ballad, Dangdut Koplo\nslow rock blues\nslow rock, Southeast Asian pop\nslow rock, hard rock, emotional ballad\nslow rock, pop-dangdut, classic rock\nslow rock, pop-rock, dangdut koplo\nslow soul\nslow-burn ballad\nslow-burn rock\nslow-jam\nslow-jam R&B\nslow-jam ballad\nslow-jam, soul, ambient\nslow-tempo hip-hop\nslowcore\nslowcore ambient\nslowcore ambient folk\nslowcore indie rock\nslowcore indie rock post-rock\nslowcore jazz\nslowcore noise rock\nslowcore noise-rock\nslowcore post-rock\nslowcore post-rock shoegaze\nslowcore shoegaze\nslowcore, americana, indie rock\nslowcore, noise rock, shoegaze\nslowcore, post-rock, shoegaze\nsludge funk rock\nsludge metal\nsludge metal folk fusion\nsludge metal punk\nsludge metal thrash\nsludge metal, hard rock, doom metal\nsludge metal, post-rock, ambient\nsludge rock\nsludge rock, Bollywood fusion, Latin rock\nsmooth R&B\nsmooth R&B deep house\nsmooth R&B, smooth jazz\nsmooth ballad\nsmooth funk\nsmooth hip-hop\nsmooth jazz\nsmooth jazz MPB\nsmooth jazz R&B\nsmooth jazz R&B conscious hip-hop\nsmooth jazz R&B gospel\nsmooth jazz R&B lounge\nsmooth jazz acoustic pop\nsmooth jazz adult contemporary\nsmooth jazz blues\nsmooth jazz blues-rock\nsmooth jazz bossa nova\nsmooth jazz chillout\nsmooth jazz chillwave lounge\nsmooth jazz chiptune\nsmooth jazz city pop\nsmooth jazz city pop lounge\nsmooth jazz deep house\nsmooth jazz dream pop\nsmooth jazz funk\nsmooth jazz funk Latin\nsmooth jazz funk bossa nova\nsmooth jazz funk city pop\nsmooth jazz funk fusion\nsmooth jazz funk lounge\nsmooth jazz funk progressive rock\nsmooth jazz funk soul\nsmooth jazz funk soul-jazz\nsmooth jazz funk world music\nsmooth jazz fusion\nsmooth jazz gospel\nsmooth jazz gospel-pop\nsmooth jazz hip-hop\nsmooth jazz hop\nsmooth jazz lo-fi hip hop\nsmooth jazz lo-fi hip-hop\nsmooth jazz lounge\nsmooth jazz lounge bossa nova\nsmooth jazz lounge neo-soul\nsmooth jazz lounge pop\nsmooth jazz lounge world music\nsmooth jazz neo-soul\nsmooth jazz new age\nsmooth jazz orchestral pop\nsmooth jazz pop\nsmooth jazz pop ballad\nsmooth jazz pop-ballad\nsmooth jazz pop-funk\nsmooth jazz pop-rock\nsmooth jazz pop-soul\nsmooth jazz progressive rock\nsmooth jazz rap\nsmooth jazz reggae\nsmooth jazz rock\nsmooth jazz soul\nsmooth jazz synth-pop\nsmooth jazz world fusion\nsmooth jazz world fusion ambient\nsmooth jazz world music\nsmooth jazz, French pop\nsmooth jazz, Latin funk, Bossa Nova\nsmooth jazz, Latin fusion\nsmooth jazz, Latin fusion, Bossa Nova\nsmooth jazz, Latin pop\nsmooth jazz, MPB, Christian ballad\nsmooth jazz, MPB, pop ballad\nsmooth jazz, R&B\nsmooth jazz, R&B, Christmas\nsmooth jazz, R&B, Eastern European pop\nsmooth jazz, R&B, gospel\nsmooth jazz, Vietnamese pop\nsmooth jazz, adult contemporary\nsmooth jazz, adult contemporary, power ballad\nsmooth jazz, bossa nova\nsmooth jazz, cinematic, East Asian pop\nsmooth jazz, city pop\nsmooth jazz, city pop, adult contemporary\nsmooth jazz, deep house, lounge\nsmooth jazz, new age\nsmooth jazz, new age, cinematic\nsmooth jazz, new age, progressive rock\nsmooth jazz, new jack swing\nsmooth jazz, pop-R&B\nsmooth jazz, pop-rock\nsmooth jazz, pop-rock, Eastern European\nsmooth jazz, synth-funk\nsmooth jazz, synth-pop\nsmooth jazz, synth-pop, new age\nsmooth jazz, world fusion\nsmooth jazz, world fusion, East Asian\nsmooth jazz, world fusion, lounge\nsmooth jazz, world music\nsmooth jazz, world music, pop ballad\nsmooth jazz, world music, soul\nsmooth jazz-funk\nsmooth jazz-hop\nsmooth jazz-pop\nsmooth jazz-pop city pop\nsmooth jazz-rap\nsmooth jazz-rock\nsmooth pop\nsmooth soul\nsnap, crunk\nsoca\nsoca afrobeat\nsoca calypso\nsoca christmas\nsoca dance\nsoca dance-pop\nsoca dancehall\nsoca edm\nsoca funk\nsoca funk reggae-pop\nsoca fusion\nsoca gospel\nsoca house\nsoca indie pop\nsoca merengue calypso\nsoca metal\nsoca pop\nsoca pop-funk\nsoca pop-rap\nsoca pop-rock\nsoca reggae\nsoca salsa\nsoca salsa fusion\nsoca samba\nsoca, calypso, Caribbean\nsoca, holiday, Caribbean\nsoca-pop\nsocial hip hop\nsofrência\nsoft R&B\nsoft ballad\nsoft indie pop\nsoft jazz\nsoft jazz ballad\nsoft piano\nsoft piano ballad\nsoft pop\nsoft pop acoustic ballad\nsoft pop ballad\nsoft pop world music\nsoft pop, Indian folk, ambient\nsoft pop, Indian folk, ambient ballad\nsoft pop, smooth jazz, ambient\nsoft pop, world music\nsoft pop, world music, devotional\nsoft pop-ballad\nsoft pop-rock\nsoft rock\nsoft rock ballad\nsoft rock ballad, classic rock, live performance\nsoft rock ballad, hard rock\nsoft rock blues\nsoft rock blues world music\nsoft rock bossa nova\nsoft rock city pop\nsoft rock country gospel\nsoft rock country-pop\nsoft rock folk\nsoft rock gospel\nsoft rock jazz\nsoft rock jazz fusion\nsoft rock jazz-fusion\nsoft rock lounge\nsoft rock lounge bossa nova\nsoft rock lounge jazz\nsoft rock progressive rock\nsoft rock reggae\nsoft rock soul\nsoft rock soul jazz\nsoft rock tropical\nsoft rock world music\nsoft rock worship\nsoft rock, 80s Danish pop\nsoft rock, Latin pop\nsoft rock, Turkish folk\nsoft rock, adult contemporary\nsoft rock, bossa nova, Turkish\nsoft rock, city pop\nsoft rock, city pop, Korean\nsoft rock, classic rock\nsoft rock, funk rock\nsoft rock, hard rock\nsoft rock, hard rock, acoustic ballad\nsoft rock, hard rock, blues rock\nsoft rock, new age\nsoft rock, smooth jazz\nsoft rock, theatrical pop\nsoft rock, theatrical rock, cinematic\nsoft rock, world music\nsoft soul\nsoft-pop\nsokkie\nsokkie boeremusiek\nsokkie folk\nsokkie folk-pop\nsokkie, chiptune\nsokkie, cinematic ballad\nsokkie, novelty country-rock\nsolemn brass\nsolitary piano\nsolo acoustic\nsolo folk\nsolo piano\nsolo piano ballad\nsolo singer-songwriter\nsolopiano\nson cubano\nson cubano cumbia\nson cubano mambo\nson cubano salsa\nson jarocho cumbia\nson montuno\nson montuno cumbia\nsonero\nsonidero cumbia\nsophisti-pop\nsophisti-pop R&B\nsophisti-pop city pop\nsophisti-pop dream pop\nsophisti-pop funk\nsophisti-pop jazz\nsophisti-pop smooth jazz\nsophisti-pop, city pop, R&B\nsophisticated jazz\nsophisticated pop\nsoukous\nsoukous afro-latin\nsoukous afrobeat\nsoukous gospel\nsoukous highlife\nsoul\nsoul Christmas\nsoul Latin\nsoul MPB\nsoul R&B\nsoul R&B Broadway\nsoul R&B Latin\nsoul R&B Latin jazz\nsoul R&B New Orleans jazz\nsoul R&B big band\nsoul R&B blues\nsoul R&B blues rock\nsoul R&B blues-rock\nsoul R&B cinematic\nsoul R&B country\nsoul R&B country gospel\nsoul R&B country-rock\nsoul R&B disco\nsoul R&B doo-wop\nsoul R&B funk\nsoul R&B gospel\nsoul R&B jazz\nsoul R&B jazz ballad\nsoul R&B jazz fusion\nsoul R&B jazz-funk\nsoul R&B lounge\nsoul R&B lounge jazz\nsoul R&B lounge-jazz\nsoul R&B orchestral\nsoul R&B psychedelic\nsoul R&B rock\nsoul R&B smooth jazz\nsoul R&B theatrical\nsoul a cappella\nsoul acoustic\nsoul ballad\nsoul ballad doo-wop\nsoul ballad, 70s R&B, cinematic\nsoul ballad, R&B\nsoul ballad, early rock and roll\nsoul ballad, vintage R&B, psychedelic\nsoul big band\nsoul blues\nsoul blues lounge\nsoul blues psychedelic rock\nsoul blues rock\nsoul blues-rock\nsoul bolero\nsoul boogie\nsoul boogie-woogie\nsoul bossa nova\nsoul cabaret\nsoul chanson\nsoul country\nsoul country-pop\nsoul country-rock\nsoul disco\nsoul disco funk\nsoul doo-wop\nsoul duet\nsoul exotica\nsoul folk\nsoul folk cinematic\nsoul folk gospel\nsoul funk\nsoul funk big band\nsoul funk blues\nsoul funk city-pop\nsoul funk disco\nsoul funk gospel\nsoul funk hip-hop\nsoul funk latin\nsoul funk latin jazz\nsoul funk pop\nsoul funk psychedelic\nsoul funk r&b\nsoul funk reggae\nsoul funk rock\nsoul funk theatrical\nsoul funk world music\nsoul fusion\nsoul gospel\nsoul gospel disco\nsoul gospel hip-hop\nsoul groove\nsoul groovy\nsoul guitar\nsoul hip hop\nsoul hip-hop\nsoul house\nsoul indie rock\nsoul jazz\nsoul jazz R&B\nsoul jazz ballad\nsoul jazz funk\nsoul jazz funk rock\nsoul jazz lounge\nsoul jazz pop\nsoul jazz pop-rock\nsoul jazz salsa\nsoul jazz-funk\nsoul jazz-pop\nsoul latin\nsoul lounge\nsoul lounge jazz\nsoul orchestral\nsoul piano\nsoul piano ballad\nsoul pop\nsoul pop gospel\nsoul pop rock\nsoul pop world music\nsoul pop-rock\nsoul pop-rock Latin\nsoul pop-rock jazz\nsoul power ballad\nsoul psychedelic rock\nsoul reggae\nsoul revue\nsoul rock\nsoul rock ballad\nsoul rock funk\nsoul rock gospel\nsoul rock samba\nsoul rock zouk\nsoul rockabilly\nsoul rocksteady\nsoul slow-jam\nsoul soft rock\nsoul spiritual\nsoul swamp rock\nsoul trap\nsoul ukulele\nsoul waltz\nsoul worship\nsoul, Afro-soul\nsoul, Caribbean folk\nsoul, Christmas\nsoul, Christmas, ambient\nsoul, Christmas, power ballad\nsoul, Christmas, vintage\nsoul, French chanson, acoustic\nsoul, French rap, gospel\nsoul, Japanese pop\nsoul, Latin groove\nsoul, Latin jazz, doo-wop\nsoul, Latin jazz, gospel\nsoul, Latin pop, fusion\nsoul, Latin soul\nsoul, Latin, funk\nsoul, Latin, gospel\nsoul, Latin, vintage\nsoul, MPB\nsoul, Motown\nsoul, Motown, R&B\nsoul, Motown, live\nsoul, New Orleans, festive\nsoul, R&B\nsoul, R&B, Broadway\nsoul, R&B, Christmas\nsoul, R&B, French ballad\nsoul, R&B, Latin\nsoul, R&B, ambient\nsoul, R&B, big band\nsoul, R&B, big band jazz\nsoul, R&B, blues\nsoul, R&B, boogie-woogie\nsoul, R&B, cinematic\nsoul, R&B, doo-wop\nsoul, R&B, dreamy synth-pop\nsoul, R&B, funk\nsoul, R&B, gospel\nsoul, R&B, groove\nsoul, R&B, hip-hop\nsoul, R&B, holiday\nsoul, R&B, jazz\nsoul, R&B, live\nsoul, R&B, live acoustic\nsoul, R&B, lounge\nsoul, R&B, novelty\nsoul, R&B, power ballad\nsoul, R&B, rock\nsoul, R&B, rock and roll\nsoul, R&B, theatrical\nsoul, R&B, vintage\nsoul, acoustic, Latin-influenced\nsoul, adult contemporary, cinematic\nsoul, afrobeats, gospel\nsoul, ambient\nsoul, ambient, Christmas\nsoul, art rock, singer-songwriter\nsoul, axé\nsoul, axé, samba-reggae\nsoul, big band\nsoul, big band jazz\nsoul, big band, Christmas\nsoul, big band, R&B\nsoul, big band, a cappella\nsoul, big band, funk\nsoul, big band, gospel\nsoul, big band, jazz\nsoul, big band, ragtime\nsoul, big band, theatrical\nsoul, big band, vintage\nsoul, blues, Christmas\nsoul, blues, cinematic\nsoul, blues, gospel\nsoul, blues, honky-tonk\nsoul, blues, vintage\nsoul, blues, vintage jazz\nsoul, boogie-woogie, gospel\nsoul, boogie-woogie, gospel rock\nsoul, boogie-woogie, jump blues\nsoul, boogie-woogie, live\nsoul, bossa nova\nsoul, bossa nova, Afro-Latin\nsoul, bossa nova, smooth jazz\nsoul, cinematic\nsoul, cinematic, Latin\nsoul, cinematic, R&B\nsoul, cinematic, big band\nsoul, cinematic, christmas\nsoul, cinematic, doo-wop\nsoul, cinematic, funk\nsoul, cinematic, gospel\nsoul, disco, funk\nsoul, disco-funk\nsoul, doo-wop, slow-jam\nsoul, drum and bass\nsoul, dub, cinematic\nsoul, easy-listening\nsoul, funk, Chinese indie\nsoul, funk, Latin jazz\nsoul, funk, Middle Eastern\nsoul, funk, boom-bap\nsoul, funk, country\nsoul, funk, gospel\nsoul, funk, live jam\nsoul, funk, piano ballad\nsoul, gospel\nsoul, gospel, Afro-soul\nsoul, gospel, Caribbean\nsoul, gospel, Christmas\nsoul, gospel, Latin\nsoul, gospel, Latin hip hop\nsoul, gospel, R&B\nsoul, gospel, a cappella\nsoul, gospel, acoustic\nsoul, gospel, ambient\nsoul, gospel, anthemic\nsoul, gospel, atmospheric\nsoul, gospel, ballad\nsoul, gospel, big band\nsoul, gospel, blues\nsoul, gospel, blues-rock\nsoul, gospel, boogie-woogie\nsoul, gospel, cinematic\nsoul, gospel, classical\nsoul, gospel, conscious hip-hop\nsoul, gospel, electronic\nsoul, gospel, folk\nsoul, gospel, funk\nsoul, gospel, hip-hop\nsoul, gospel, jazz\nsoul, gospel, jazzy pop\nsoul, gospel, live band\nsoul, gospel, live performance\nsoul, gospel, live piano\nsoul, gospel, lo-fi\nsoul, gospel, lo-fi hip hop\nsoul, gospel, lo-fi hip-hop\nsoul, gospel, modern Christmas\nsoul, gospel, musical theater\nsoul, gospel, neo-soul\nsoul, gospel, new jack swing\nsoul, gospel, piano ballad\nsoul, gospel, power ballad\nsoul, gospel, psychedelic\nsoul, gospel, ritualistic\nsoul, gospel, theatrical\nsoul, gospel, vintage\nsoul, gospel, vintage analog\nsoul, gospel, world music\nsoul, hip hop, experimental\nsoul, hip-hop, gospel\nsoul, jazz, Afro-fusion\nsoul, jazz, Brazilian popular music\nsoul, jazz, Christmas\nsoul, jazz, Haitian Creole\nsoul, jazz, R&B\nsoul, jazz, christmas\nsoul, jazz, gospel\nsoul, jazz, reggae\nsoul, jazz, spiritual\nsoul, jazz, vintage\nsoul, jazz, world music\nsoul, latin, bossa nova\nsoul, minimalist\nsoul, musical theater\nsoul, new jack swing\nsoul, orchestral pop\nsoul, orchestral, gospel\nsoul, orchestral, theatrical\nsoul, pop, theatrical\nsoul, punk rock\nsoul, quiet storm, cinematic\nsoul, reggae, gospel\nsoul, retro, Christmas\nsoul, retro, funk\nsoul, romantic, acoustic\nsoul, roots rock, gospel\nsoul, salsa, a cappella\nsoul, smooth jazz, Latin pop\nsoul, soft rock\nsoul, soft rock, 70s\nsoul, spiritual jazz\nsoul, spiritual, acoustic\nsoul, spiritual, lo-fi\nsoul, surf rock, gospel\nsoul, synth-funk, gospel\nsoul, synth-pop\nsoul, theatrical, crooner\nsoul, theatrical, duet\nsoul, theatrical, experimental\nsoul, theatrical, folk\nsoul, theatrical, gospel\nsoul, theatrical, piano ballad\nsoul, trap, jazz\nsoul, tribal, cinematic\nsoul, vintage, cinematic\nsoul, vintage, duet\nsoul, vintage, live band\nsoul, world fusion\nsoul, world music\nsoul, world music, blues\nsoul, world music, gospel\nsoul, worldbeat, R&B\nsoul-R&B\nsoul-blues\nsoul-folk\nsoul-funk\nsoul-funk bossa nova\nsoul-funk hip-hop\nsoul-funk jazz\nsoul-funk, Thai folk, fusion\nsoul-gospel\nsoul-gospel jazz\nsoul-jazz\nsoul-jazz blues-rock\nsoul-jazz funk\nsoul-jazz funk-rock\nsoul-jazz hip-hop\nsoul-jazz lounge\nsoul-jazz rock\nsoul-jazz, K-pop\nsoul-pop\nsoul-pop bossa nova\nsoul-pop funk\nsoul-pop gospel\nsoul-pop jazz\nsoul-pop latin jazz\nsoul-pop lounge jazz\nsoul-pop retro\nsoul-pop, gospel, cinematic\nsoul-pop, neo-soul\nsoul-pop, theatrical, funk\nsoul-reggae\nsoul-rock\nsoul-rock funk-rock\nsoul-trap\nsoulful Afro-pop\nsoulful Afro-soul\nsoulful Afrobeat\nsoulful Arabic fusion\nsoulful Brazilian\nsoulful C-pop\nsoulful Caribbean\nsoulful Christmas\nsoulful Christmas ballad\nsoulful Christmas rock\nsoulful French pop\nsoulful French rap\nsoulful Haitian Creole\nsoulful Indian folk\nsoulful Indian fusion\nsoulful Latin\nsoulful Latin acoustic\nsoulful Latin folk\nsoulful Latin fusion\nsoulful Latin groove\nsoulful Latin jazz\nsoulful Latin pop\nsoulful Portuguese\nsoulful Portuguese ballad\nsoulful R&B\nsoulful R&B ballad\nsoulful R&B funk\nsoulful R&B jazz\nsoulful R&B, French hip-hop, jazz-infused\nsoulful R&B, conscious hip-hop\nsoulful R&B, conscious hip-hop, UK rap\nsoulful Spanish ballad\nsoulful a cappella\nsoulful acapella\nsoulful acoustic\nsoulful acoustic ballad\nsoulful ambient\nsoulful ambient rock\nsoulful anthem\nsoulful anthemic\nsoulful ballad\nsoulful ballad merengue\nsoulful ballad, 80s synth-pop\nsoulful ballad, Latin groove\nsoulful ballad, conscious hip-hop\nsoulful ballad, funk-rock\nsoulful ballad, hard rock\nsoulful ballad, new jack swing\nsoulful ballad, psychedelic rock\nsoulful ballad, salsa, Haitian Creole\nsoulful big band\nsoulful blues\nsoulful blues hip-hop\nsoulful blues-rock\nsoulful bossa nova\nsoulful brass\nsoulful breakbeat\nsoulful cabaret\nsoulful carol\nsoulful cavaquinho\nsoulful cello\nsoulful choir\nsoulful cinematic\nsoulful clarinet\nsoulful classical\nsoulful country\nsoulful country ballad\nsoulful country blues\nsoulful deep house\nsoulful devotional\nsoulful disco\nsoulful duet\nsoulful electronic\nsoulful electropop\nsoulful empowerment\nsoulful fingerstyle\nsoulful folk\nsoulful folk rock\nsoulful funk\nsoulful funk-rock\nsoulful fusion\nsoulful ghazal\nsoulful gospel\nsoulful gospel ballad\nsoulful gospel rock\nsoulful groove\nsoulful guitar\nsoulful highlife\nsoulful hip hop\nsoulful hip-hop\nsoulful holiday\nsoulful holiday ballad\nsoulful house\nsoulful hymn\nsoulful indie\nsoulful indie folk\nsoulful instrumental\nsoulful jazz\nsoulful jazz ballad\nsoulful jazz fusion\nsoulful jazz-gospel\nsoulful live\nsoulful lo-fi\nsoulful lounge\nsoulful lounge-jazz\nsoulful lullaby\nsoulful minimalism\nsoulful orchestral\nsoulful organ\nsoulful pagode\nsoulful piano\nsoulful piano ballad\nsoulful piano ballad, 80s post-disco\nsoulful piano pop\nsoulful piano rap\nsoulful piano rock\nsoulful piano-vocal\nsoulful pop\nsoulful pop R&B\nsoulful pop ballad\nsoulful pop jazz\nsoulful pop nu-disco\nsoulful pop reggae\nsoulful pop world music\nsoulful pop, world music, Gujarati folk\nsoulful pop-R&B\nsoulful pop-gospel\nsoulful pop-rap\nsoulful pop-rock\nsoulful post-disco\nsoulful power ballad\nsoulful power ballad, Axé, samba-reggae\nsoulful protest\nsoulful protest pop\nsoulful rap\nsoulful reggae\nsoulful rock\nsoulful rock and roll\nsoulful rock ballad\nsoulful rock funk\nsoulful rock hip-hop\nsoulful samba\nsoulful singer-songwriter\nsoulful slow-jam\nsoulful soft rock\nsoulful spiritual\nsoulful storytelling\nsoulful swing\nsoulful synth\nsoulful tango\nsoulful trap\nsoulful ukulele\nsoulful vocal\nsoulful world\nsoulful world fusion\nsoulful world music\nsoulful world pop\nsoulful worship\nsoulful, spiritual, Middle Eastern\nsound clash\nsound design\nsound effect\nsoundtrack\nsouthern R&B\nsouthern alt-rock\nsouthern folk\nsouthern gospel\nsouthern gospel country\nsouthern gospel rock\nsouthern gothic\nsouthern gothic ballad\nsouthern gothic blues\nsouthern gothic blues rock\nsouthern gothic blues-rock\nsouthern gothic country\nsouthern gothic country-rock\nsouthern gothic folk\nsouthern gothic folk-rock\nsouthern gothic hip-hop\nsouthern gothic rock\nsouthern gothic trap\nsouthern hard rock\nsouthern hip hop\nsouthern hip hop gospel\nsouthern hip-hop\nsouthern hip-hop chiptune\nsouthern hip-hop crunk\nsouthern hip-hop lo-fi\nsouthern hip-hop neo-soul\nsouthern hip-hop trap\nsouthern hip-hop, stadium rock, hard rock\nsouthern italian ballad\nsouthern metal\nsouthern punk rock\nsouthern rock\nsouthern rock a cappella\nsouthern rock alt-country\nsouthern rock bluegrass\nsouthern rock blues\nsouthern rock blues rock\nsouthern rock blues-rock\nsouthern rock boogie-woogie\nsouthern rock country\nsouthern rock country blues\nsouthern rock country rap\nsouthern rock country rock\nsouthern rock country-blues\nsouthern rock country-gospel\nsouthern rock country-rap\nsouthern rock country-rock\nsouthern rock funk\nsouthern rock funk soul\nsouthern rock garage rock\nsouthern rock gospel\nsouthern rock gospel blues\nsouthern rock hard rock\nsouthern rock hip hop\nsouthern rock hip-hop\nsouthern rock hip-hop pop-rock\nsouthern rock indie rock\nsouthern rock metal\nsouthern rock nu-metal\nsouthern rock outlaw country\nsouthern rock pop-punk\nsouthern rock punk\nsouthern rock punk metal\nsouthern rock rap\nsouthern rock rap-rock\nsouthern rock rockabilly\nsouthern rock soul\nsouthern rock trap\nsouthern rock trap chiptune\nsouthern rock, alt-country\nsouthern rock, bluegrass\nsouthern rock, blues rock, Christmas rock\nsouthern rock, boogie-woogie, rock and roll\nsouthern rock, country\nsouthern rock, country blues\nsouthern rock, country gospel\nsouthern rock, country rap\nsouthern rock, country rap, cinematic\nsouthern rock, country rock, Christmas rock\nsouthern rock, country, christmas\nsouthern rock, country-blues\nsouthern rock, country-rap, hip-hop\nsouthern rock, electronic, dubstep\nsouthern rock, gospel revival\nsouthern rock, gospel, blues rock\nsouthern rock, gospel, boogie-woogie\nsouthern rock, hard rock, glam metal\nsouthern rock, heavy metal\nsouthern rock, latin ballad\nsouthern rock, nu-metal\nsouthern rock, outlaw country\nsouthern rock, rap-metal\nsouthern rock, rap-rock\nsouthern rock, trap, rock\nsouthern soul\nsouthern soul funk\nsouthern soul funk-rock\nsouthern trap\nsouthern trap, cloud rap\nspace cumbia\nspace disco\nspace funk\nspace hip hop\nspace hip-hop synthwave\nspace punk rock\nspace rock\nspace rock indie rock\nspace rock metalcore\nspace rock, drum and bass, neurofunk\nspace trap\nspace-funk\nspace-trap\nspace-trap hip-hop\nspaghetti western\nspaghetti western rock\nspaghetti western, surf rock\nspaghetti-western metal\nspanish folk\nspanish guitar\nsparse folk\nspeed metal\nspeed metal J-rock\nspeed metal anison\nspeed metal chiptune\nspeed metal chiptune electronicore\nspeed metal chiptune symphonic\nspeed metal chiptune synthwave\nspeed metal chiptune trance\nspeed metal electronicore\nspeed metal flamenco\nspeed metal flamenco fusion\nspeed metal folk punk\nspeed metal polka\nspeed metal power metal\nspeed metal punk\nspeed metal punk rock\nspeed metal ska-punk\nspeed metal surf rock\nspeed metal thrash metal\nspeed metal turbo-folk\nspeed metal, Celtic punk\nspeed metal, Chinese fusion\nspeed metal, J-rock\nspeed metal, J-rock, Vocaloid\nspeed metal, J-rock, power metal\nspeed metal, J-rock, rap-metal\nspeed metal, J-rock, traditional Japanese\nspeed metal, Japanese folk\nspeed metal, Japanese fusion\nspeed metal, Middle Eastern fusion\nspeed metal, Nintendocore\nspeed metal, big band swing\nspeed metal, big band, jazz fusion\nspeed metal, chiptune\nspeed metal, chiptune power metal\nspeed metal, chiptune rock\nspeed metal, chiptune, Japanese video game music\nspeed metal, chiptune, VGM\nspeed metal, chiptune, anison\nspeed metal, chiptune, electronic\nspeed metal, dangdut koplo\nspeed metal, denpa-kei\nspeed metal, electronic rock, video game music\nspeed metal, flamenco, J-rock\nspeed metal, happy hardcore, chiptune\nspeed metal, happy hardcore, video game music\nspeed metal, hardcore techno\nspeed metal, hardcore techno, chiptune\nspeed metal, industrial metal, Neue Deutsche Härte\nspeed metal, jazz fusion, chiptune\nspeed metal, jazz fusion, video game music\nspeed metal, klezmer, video game music\nspeed metal, power metal, chiptune\nspeed metal, ska-punk\nspeed metal, video game music\nspeedcore\nspeedcore J-core\nspeedcore acid trance\nspeedcore artcore\nspeedcore breakcore\nspeedcore breakcore chiptune\nspeedcore breakcore gabber\nspeedcore breakcore metal\nspeedcore brostep\nspeedcore chiptune\nspeedcore chiptune J-core\nspeedcore chiptune J-rock\nspeedcore chiptune artcore\nspeedcore chiptune breakcore\nspeedcore chiptune gabber\nspeedcore chiptune hardcore\nspeedcore chiptune industrial metal\nspeedcore chiptune metal\nspeedcore chiptune metalcore\nspeedcore chiptune symphonic metal\nspeedcore complextro\nspeedcore complextro chiptune\nspeedcore cybergrind\nspeedcore denpa-kei\nspeedcore digital hardcore\nspeedcore digitalgrind\nspeedcore dubstep metalcore\nspeedcore gabber\nspeedcore gabber breakcore\nspeedcore gabber chiptune\nspeedcore gabber hardcore\nspeedcore gabber hardcore techno\nspeedcore gabber industrial hardcore\nspeedcore glitch\nspeedcore glitch artcore\nspeedcore glitch hop\nspeedcore glitch hop dubstep\nspeedcore glitchcore\nspeedcore happy hardcore\nspeedcore happy hardcore chiptune\nspeedcore happy hardcore metalcore\nspeedcore hardcore glitch\nspeedcore hardcore techno\nspeedcore hardstyle\nspeedcore hyperpop\nspeedcore hyperpop metalcore\nspeedcore industrial hardcore\nspeedcore industrial hip-hop\nspeedcore industrial metal\nspeedcore j-core\nspeedcore j-core artcore\nspeedcore j-core chiptune\nspeedcore j-core hardcore\nspeedcore j-rock\nspeedcore j-rock chiptune\nspeedcore jazz chiptune\nspeedcore jungle\nspeedcore metal chiptune\nspeedcore metalcore\nspeedcore metalcore J-rock\nspeedcore metalcore chiptune\nspeedcore metalcore k-pop\nspeedcore neurofunk\nspeedcore neurofunk drum & bass\nspeedcore neurofunk glitchcore\nspeedcore neurofunk hardcore techno\nspeedcore nintendocore\nspeedcore polka\nspeedcore power metal\nspeedcore splittercore\nspeedcore symphonic metal breakcore\nspeedcore, Chinese fusion\nspeedcore, Chinese fusion, electronic\nspeedcore, J-core\nspeedcore, J-core, artcore\nspeedcore, J-core, chiptune\nspeedcore, J-core, gabber\nspeedcore, J-rock, chiptune\nspeedcore, J-rock, denpa-kei\nspeedcore, Japanese fusion\nspeedcore, Japanese traditional\nspeedcore, Russian folk, gabber\nspeedcore, artcore, Vocaloid\nspeedcore, artcore, chiptune\nspeedcore, breakcore, chiptune\nspeedcore, chiptune, J-core\nspeedcore, chiptune, gabber\nspeedcore, classical, cinematic\nspeedcore, digital noise\nspeedcore, electronic, dark ambient\nspeedcore, gabber, breakcore\nspeedcore, gabber, djent\nspeedcore, gabber, happy hardcore\nspeedcore, gabber, hardcore techno\nspeedcore, glitch, gabber\nspeedcore, happy hardcore\nspeedcore, happy hardcore, chiptune\nspeedcore, happy hardcore, metalcore\nspeedcore, happy hardcore, theatrical metalcore\nspeedcore, hardcore techno, Chinese fusion\nspeedcore, hardcore techno, Middle Eastern fusion\nspeedcore, hardcore techno, chiptune\nspeedcore, min'yō\nspeedcore, neurofunk\nspeedcore, nintendocore, chiptune\nspeedcore, trancecore, ambient\nspiritual\nspiritual Afro-Latin\nspiritual Afro-folk\nspiritual Afrobeat\nspiritual Arabic\nspiritual Arabic ballad\nspiritual Arabic chant\nspiritual Arabic classical\nspiritual Arabic electronica\nspiritual Arabic fusion\nspiritual Arabic music\nspiritual Arabic pop\nspiritual Arabic synth\nspiritual Bhangra\nspiritual Brazilian\nspiritual C-pop\nspiritual Christmas\nspiritual EDM\nspiritual Greek chant\nspiritual Indian\nspiritual Indian a cappella\nspiritual Indian bhajan\nspiritual Indian chant\nspiritual Indian chanting\nspiritual Indian classical\nspiritual Indian devotional\nspiritual Indian folk\nspiritual Indian fusion\nspiritual Indian music\nspiritual Javanese\nspiritual Latin\nspiritual Latin ballad\nspiritual Latin hip-hop\nspiritual Latin pop\nspiritual MPB\nspiritual Middle Eastern\nspiritual North African\nspiritual Persian\nspiritual R&B\nspiritual R&B trap\nspiritual South Asian\nspiritual Southeast Asian\nspiritual Sufi\nspiritual Tamil\nspiritual Tamil folk\nspiritual Turkish\nspiritual Turkish music\nspiritual Zouk\nspiritual a cappella\nspiritual acapella\nspiritual acoustic\nspiritual afro\nspiritual afrobeat\nspiritual afrobeats\nspiritual ambient\nspiritual anasheed\nspiritual anthem\nspiritual baile funk\nspiritual ballad\nspiritual bhajan\nspiritual blues\nspiritual bossa nova\nspiritual chanson\nspiritual chant\nspiritual children's\nspiritual chillout\nspiritual chillwave\nspiritual chiptune\nspiritual choir\nspiritual choral\nspiritual cinematic\nspiritual classical\nspiritual cumbia\nspiritual dance\nspiritual deep house\nspiritual devotional\nspiritual downtempo\nspiritual duduk\nspiritual electronic\nspiritual electronic fusion\nspiritual electronic pop\nspiritual electronica\nspiritual flamenco\nspiritual folk\nspiritual folk fusion\nspiritual folk rock\nspiritual folk-pop\nspiritual folk-rock\nspiritual funk\nspiritual funk-rock\nspiritual fusion\nspiritual gamelan\nspiritual ghazal\nspiritual gospel\nspiritual hip hop\nspiritual hip-hop\nspiritual hip-hop afrobeats\nspiritual hip-hop, lo-fi hip-hop\nspiritual house\nspiritual house afro-house\nspiritual hymn\nspiritual jazz\nspiritual jazz bossa nova\nspiritual kirtan\nspiritual klezmer\nspiritual lament\nspiritual lo-fi\nspiritual lullaby\nspiritual metal\nspiritual music\nspiritual music world music soft rock\nspiritual new age\nspiritual ney\nspiritual orchestral\nspiritual oud\nspiritual percussion\nspiritual phonk\nspiritual piano\nspiritual pop\nspiritual pop afrobeat\nspiritual pop chiptune\nspiritual pop fusion\nspiritual pop reggaeton\nspiritual pop rock\nspiritual pop world music\nspiritual pop worldbeat\nspiritual pop, Middle Eastern, dance-pop\nspiritual pop, Romanian folk, electronic ballad\nspiritual pop, eurodance, 2000s pop\nspiritual pop-R&B\nspiritual pop-ballad\nspiritual pop-folk\nspiritual pop-fusion\nspiritual pop-gospel\nspiritual pop-rap\nspiritual pop-rock\nspiritual power ballad\nspiritual progressive house\nspiritual psytrance\nspiritual qanun\nspiritual qawwali\nspiritual reggae\nspiritual reggae fusion\nspiritual reggaeton\nspiritual ritual\nspiritual rock\nspiritual rock fusion\nspiritual sitar\nspiritual soft rock\nspiritual soul\nspiritual spoken word\nspiritual synth\nspiritual synth-pop\nspiritual techno\nspiritual trance\nspiritual trance worldbeat\nspiritual trap\nspiritual tribal\nspiritual vocal\nspiritual world\nspiritual world beat\nspiritual world fusion\nspiritual world music\nspiritual world-beat\nspiritual worldbeat\nspiritual worship\nspiritual, Arabic, epic\nspiritual, Hawaiian, acoustic\nspiritual, Middle Eastern, Klezmer\nspiritual, Middle Eastern, ambient\nspiritual, Middle Eastern, devotional\nspiritual, Middle Eastern, vocal\nspiritual, South Asian devotional, melodic\nspiritual, South Asian, devotional\nspiritual, baritone, Hawaiian hymn\nspiritual, celebratory, Eid\nspiritual, choral, devotional\nspiritual, choral, guzheng\nspiritual, choral, world fusion\nspiritual, cinematic, Indian devotional\nspiritual, cinematic, Middle Eastern\nspiritual, cinematic, Vietnamese Buddhist\nspiritual, cinematic, Vietnamese folk\nspiritual, classical, cinematic\nspiritual, devotional, world music\nspiritual, duduk, oud\nspiritual, oud, ambient\nspiritual, oud, choral\nspiritual, oud, cinematic\nspiritual, traditional, Middle Eastern\nspiritual-chillout\nspirituals\nspoken word\nspoken word ambient\nspoken word blues\nspoken word comedy\nspoken word folk\nspoken word funk\nspoken word hip hop\nspoken word hip-hop\nspoken word jazz\nspoken word lo-fi\nspoken word lounge\nspoken word piano ballad\nspoken word rap\nspoken word satire\nspoken word soul\nspoken word worship\nspoken word, R&B, cinematic\nspoken word, ambient soul\nspoken word, ballad, cinematic\nspoken word, cinematic, indie rock\nspoken word, comedic, theatrical\nspoken word, flamenco, theatrical\nspoken word, folk, choral\nspoken word, gospel, soul\nspoken word, piano ballad, boogie-woogie\nspoken word, synth pop, cinematic\nspoken word, ukulele, whimsical\nspooky a cappella\nspooky cabaret\nspooky children's music\nspooky cumbia\nspooky cumbia rock\nspooky folk\nspooky hip-hop\nspooky polka\nspooky pop\nspooky swing\nspooky synth\nspooky trap\nspooky waltz\nspooky-folk\nspooky-folk-pop\nspooky-pop\nspooky-ska\nspooky-swing\nspooky-western folk\nsports anthem\nsports anthem cumbia\nsports chant, electronic, Turkish\nsports commentary\nsports pop\nsports rock\nspy cabaret\nspy electronica\nspy film score\nspy funk\nspy jazz\nspy lounge\nspy lounge exotica\nspy movie\nspy movie funk\nspy music\nspy orchestral\nspy pop\nspy rock\nspy score\nspy soundtrack\nspy theme\nspy theme chiptune\nspy theme lounge funk\nspy theme, big band, progressive rock\nspy theme, cartoon jazz, orchestral chaos\nspy theme, circus, quirky instrumental\nspy theme, jazz, retro\nspy thriller\nspy-caper\nspy-funk\nspy-funk, lounge-jazz, progressive rock\nspy-jazz\nspy-jazz bossa nova\nspy-jazz noir\nspy-pop cabaret\nspy-rock\nspy-rock surf-rock\nspy-swing\nspy-swing gypsy jazz\nspy-thriller surf-rock\nspy-thriller, surf-rock, theatrical pop\nstadium anthem\nstadium ballad\nstadium chant\nstadium folk\nstadium hip hop\nstadium hip-hop\nstadium house\nstadium pop\nstadium rock\nstadium rock J-rock\nstadium rock big room EDM\nstadium rock electronic pop\nstadium rock folk-punk\nstadium rock hip-hop\nstadium rock post-hardcore\nstadium rock post-rock\nstadium rock power metal\nstadium rock punk\nstadium rock synth-pop\nstadium rock, Chinese folk, fusion\nstadium rock, Eurodance, Latin pop, surf rock, Bambemba rock\nstadium rock, Middle Eastern folk\nstadium rock, Middle Eastern fusion\nstadium rock, eurodance\nstadium rock, world music, fusion\nstand-up comedy\nstate anthem\nsteampunk\nsteampunk cabaret\nsteampunk rock\nsteampunk swing\nsteel pan\nsteelpan\nstinger\nstoner blues\nstoner hip hop\nstoner hip-hop\nstoner metal\nstoner rap\nstoner rock\nstoner rock alternative\nstoner rock doom metal\nstoner rock reggae dub\nstoner rock, doom metal\nstoner rock, lo-fi, psychedelic\nstoner rock, sludge metal\nstoner trap\nstory song\nstorytelling ambient\nstorytelling folk\nstorytelling hip-hop\nstorytelling piano\nstorytelling trap\nstraight-ahead jazz\nstreet hip-hop\nstreet music\nstreet punk\nstreet rap\nstreet rock\nstride jazz\nstride jazz ragtime\nstride piano\nstride piano blues\nstride piano ragtime\nstride piano, big band swing\nstride piano, big band, ragtime\nstring orchestra\nstudio break\nstudio drum\nstudio drum break\nstudio sound effect\nsummer R&B\nsummer hip-hop\nsummer pop\nsummer pop reggaeton\nsummer pop, 90s R&B\nsummer pop, Latin pop\nsummer pop, Latin, schlager\nsummer pop-R&B\nsummer pop-dance\nsummer pop-rap\nsummer pop-rock\nsummer rock\nsung poetry\nsunshine pop\nsunshine pop bossa nova\nsunshine pop doo-wop\nsunshine pop exotica\nsunshine pop lounge\nsunshine pop psychedelic pop\nsunshine pop rock\nsunshine pop rockabilly\nsunshine pop, garage rock\nsunshine pop, garage rock, vintage pop-rock\nsunshine pop, novelty pop, show tune\nsurf punk\nsurf punk chiptune\nsurf punk folk rock\nsurf punk garage rock\nsurf punk math rock\nsurf punk rockabilly\nsurf punk ska\nsurf punk ska-punk\nsurf punk skate punk\nsurf punk tropical rock\nsurf punk, Balkan brass rock\nsurf punk, Balkan folk\nsurf punk, Christian rock\nsurf punk, Latin rock\nsurf punk, Ukrainian folk\nsurf punk, chiptune rock, Nintendocore\nsurf punk, digital hardcore\nsurf punk, folk-punk, Russian\nsurf punk, garage rock\nsurf punk, horror punk\nsurf punk, polka rock\nsurf punk, turbo-folk\nsurf rock\nsurf rock Arabic fusion\nsurf rock Latin rock\nsurf rock afro-pop\nsurf rock afrobeat\nsurf rock alternative rock\nsurf rock anime\nsurf rock arabic fusion\nsurf rock arabic pop\nsurf rock art-punk\nsurf rock big band\nsurf rock bluegrass\nsurf rock blues rock\nsurf rock boogie-woogie\nsurf rock bossa nova\nsurf rock cabaret\nsurf rock cabaret punk\nsurf rock chiptune\nsurf rock chiptune French chanson\nsurf rock chiptune J-pop\nsurf rock chiptune Latin\nsurf rock chiptune breakbeat\nsurf rock chiptune math rock\nsurf rock chiptune power pop\nsurf rock chiptune psychedelic\nsurf rock chiptune punk\nsurf rock chiptune spy soundtrack\nsurf rock city pop\nsurf rock city pop exotica\nsurf rock country\nsurf rock country rock\nsurf rock country-rock\nsurf rock cumbia\nsurf rock cumbia chiptune\nsurf rock cumbia exotica\nsurf rock cumbia theatrical\nsurf rock dance-pop\nsurf rock desert rock\nsurf rock doo-wop\nsurf rock doo-wop novelty\nsurf rock dream pop\nsurf rock electro-swing\nsurf rock electro-swing big beat\nsurf rock electronic\nsurf rock electronic world music\nsurf rock exotica\nsurf rock exotica lounge\nsurf rock exotica novelty\nsurf rock exotica ska\nsurf rock flamenco\nsurf rock flamenco rock\nsurf rock flamenco-punk\nsurf rock folk metal\nsurf rock folk metal video game music\nsurf rock folk punk\nsurf rock forró\nsurf rock forró fusion\nsurf rock funk\nsurf rock funk Latin\nsurf rock funk chiptune\nsurf rock funk cumbia\nsurf rock funk latin\nsurf rock funk lounge\nsurf rock funk progressive metal\nsurf rock funk psychedelic\nsurf rock funk psychedelic rock\nsurf rock funk rock\nsurf rock funk rock spy movie\nsurf rock funk video game\nsurf rock funk world music\nsurf rock funk-rock\nsurf rock fusion\nsurf rock garage punk\nsurf rock garage rock\nsurf rock gospel rock\nsurf rock gothic horror\nsurf rock gypsy jazz\nsurf rock gypsy jazz flamenco\nsurf rock gypsy punk\nsurf rock hardcore punk\nsurf rock hardstyle\nsurf rock hip-hop\nsurf rock hyperpop\nsurf rock indie\nsurf rock indie dance\nsurf rock indie pop\nsurf rock indie rock\nsurf rock industrial dance-punk\nsurf rock j-pop\nsurf rock jazz fusion\nsurf rock jazz fusion progressive rock\nsurf rock jazz fusion video game music\nsurf rock jazz-funk\nsurf rock klezmer\nsurf rock klezmer balkan\nsurf rock klezmer big band\nsurf rock klezmer chiptune\nsurf rock klezmer punk\nsurf rock klezmer spy movie\nsurf rock klezmer-punk\nsurf rock latin\nsurf rock latin rock\nsurf rock lounge\nsurf rock lounge jazz\nsurf rock math rock\nsurf rock math rock video game music\nsurf rock metal\nsurf rock metal punk\nsurf rock noir jazz\nsurf rock noise rock\nsurf rock novelty\nsurf rock novelty rock\nsurf rock polka\nsurf rock polka chiptune\nsurf rock polka klezmer\nsurf rock pop\nsurf rock pop-punk\nsurf rock power metal\nsurf rock power pop\nsurf rock progressive math rock\nsurf rock progressive metal\nsurf rock progressive metal big band jazz\nsurf rock progressive metal video game music\nsurf rock progressive rock video game music\nsurf rock psychedelic\nsurf rock psychedelic blues rock\nsurf rock psychedelic funk\nsurf rock psychedelic pop\nsurf rock psychedelic rock\nsurf rock psychedelic rock Middle Eastern\nsurf rock punk\nsurf rock punk Middle Eastern\nsurf rock punk chiptune\nsurf rock punk electronic\nsurf rock punk funk rock\nsurf rock punk metal\nsurf rock punk noise rock\nsurf rock punk rock\nsurf rock punk rockabilly\nsurf rock punk ska-punk\nsurf rock punk video game\nsurf rock rap-rock\nsurf rock reggae\nsurf rock rockabilly\nsurf rock rockabilly Balkan\nsurf rock rockabilly Balkan folk\nsurf rock rockabilly Eastern European\nsurf rock rockabilly French pop-rock\nsurf rock rockabilly Italian folk\nsurf rock rockabilly J-rock\nsurf rock rockabilly Latin\nsurf rock rockabilly Mandopop\nsurf rock rockabilly alternative rock\nsurf rock rockabilly blues rock\nsurf rock rockabilly boogie-woogie\nsurf rock rockabilly cabaret\nsurf rock rockabilly chiptune\nsurf rock rockabilly country rock\nsurf rock rockabilly folk\nsurf rock rockabilly polka\nsurf rock rockabilly punk rock\nsurf rock rockabilly sea shanty\nsurf rock rockabilly surf jazz\nsurf rock rockabilly swing\nsurf rock rockabilly swing revival\nsurf rock rockabilly theatrical rock\nsurf rock rockabilly tropical\nsurf rock rockabilly video game music\nsurf rock rockabilly world music\nsurf rock salsa\nsurf rock samba-rock\nsurf rock sci-fi\nsurf rock ska\nsurf rock ska-punk\nsurf rock ska-punk big band\nsurf rock ska-punk surf metal\nsurf rock soul\nsurf rock spaghetti western\nsurf rock swing\nsurf rock swing revival\nsurf rock synth-pop\nsurf rock tango klezmer\nsurf rock tango psychedelic rock\nsurf rock theatrical rock\nsurf rock thrash metal\nsurf rock trot\nsurf rock turbo-folk\nsurf rock world music\nsurf rock, 60s pop-rock\nsurf rock, Anatolian rock\nsurf rock, Arabic punk\nsurf rock, Axé\nsurf rock, Balkan brass\nsurf rock, Balkan brass, cumbia\nsurf rock, Balkan brass, video game music\nsurf rock, Balkan dance-pop\nsurf rock, Balkan folk\nsurf rock, Balkan folk, cinematic\nsurf rock, Balkan folk, dance rock\nsurf rock, Balkan folk, drum and bass\nsurf rock, Balkan folk, electronic\nsurf rock, Balkan folk, energetic fusion\nsurf rock, Balkan folk, funk\nsurf rock, Balkan folk, gypsy punk\nsurf rock, Balkan folk, gypsy-punk\nsurf rock, Balkan folk, klezmer\nsurf rock, Balkan folk, rock\nsurf rock, Balkan fusion\nsurf rock, Balkan fusion, novelty\nsurf rock, Balkan jazz, gypsy jazz\nsurf rock, Balkan pop-rock\nsurf rock, Balkan punk\nsurf rock, Balkan rock, rock\nsurf rock, Balkan rock, rock and roll\nsurf rock, Balkan, Klezmer\nsurf rock, Balkan, Latin\nsurf rock, Balkan, Middle Eastern\nsurf rock, Balkan, Yiddish folk\nsurf rock, Balkan, energetic\nsurf rock, Balkan, klezmer\nsurf rock, Basque folk, rockabilly\nsurf rock, Bollywood\nsurf rock, Bollywood punk\nsurf rock, Bollywood rock\nsurf rock, Bollywood, pop\nsurf rock, Brazilian Bamba\nsurf rock, Brazilian carnival\nsurf rock, Brazilian funk\nsurf rock, Brazilian garage rock\nsurf rock, Brazilian pop-punk\nsurf rock, Brazilian pop-rock\nsurf rock, Brazilian rock\nsurf rock, Brazilian, MPB\nsurf rock, Brazilian, funk\nsurf rock, C-pop, lo-fi\nsurf rock, Celtic punk\nsurf rock, Chinese New Year, retro\nsurf rock, Chinese folk, wuxia\nsurf rock, Eastern European, lo-fi\nsurf rock, French indie pop\nsurf rock, French pop\nsurf rock, Greek folk\nsurf rock, Indian classical\nsurf rock, Indian classical, fusion\nsurf rock, Indian folk\nsurf rock, Indian folk, fusion\nsurf rock, Indian folk, psychedelic rock\nsurf rock, Indian folk, rockabilly\nsurf rock, Indian fusion, quirky pop\nsurf rock, Indonesian pop\nsurf rock, Israeli rock\nsurf rock, Italian folk\nsurf rock, Italian pop\nsurf rock, J-pop\nsurf rock, J-rock\nsurf rock, J-rock, pop\nsurf rock, J-rock, synth-pop\nsurf rock, Japanese festival music\nsurf rock, Japanese punk\nsurf rock, Javanese fusion\nsurf rock, Javanese fusion, eclectic\nsurf rock, Javanese music\nsurf rock, Javanese pop\nsurf rock, Javanese, garage rock\nsurf rock, Latin big band\nsurf rock, Latin brass, eclectic\nsurf rock, Latin dance\nsurf rock, Latin jazz, psychedelic rock\nsurf rock, Latin jazz, rockabilly\nsurf rock, Latin jazz, theatrical rock\nsurf rock, Latin mambo\nsurf rock, Latin percussion\nsurf rock, Latin percussion, C-pop\nsurf rock, Latin percussion, big band jazz\nsurf rock, Latin percussion, high-energy\nsurf rock, Latin percussion, psychedelic rock\nsurf rock, Latin percussion, theatrical rock\nsurf rock, Latin pop\nsurf rock, Latin pop, cinematic\nsurf rock, Latin pop, indie rock\nsurf rock, Latin punk, chiptune\nsurf rock, Latin rhythm\nsurf rock, Latin rock\nsurf rock, Latin rock, big band jazz\nsurf rock, Latin rock, bolero\nsurf rock, Latin rock, boogie-woogie\nsurf rock, Latin rock, chiptune\nsurf rock, Latin rock, cinematic\nsurf rock, Latin rock, dance-punk\nsurf rock, Latin rock, high-energy rock\nsurf rock, Latin rock, live rock\nsurf rock, Latin rock, lo-fi hip hop\nsurf rock, Latin rock, metal\nsurf rock, Latin rock, party anthem\nsurf rock, Latin rock, power pop\nsurf rock, Latin rock, progressive metal\nsurf rock, Latin rock, psychedelic\nsurf rock, Latin rock, psychedelic funk\nsurf rock, Latin rock, punk\nsurf rock, Latin rock, punk rock\nsurf rock, Latin rock, rap-rock\nsurf rock, Latin rock, retro rock\nsurf rock, Latin rock, rock\nsurf rock, Latin rock, rock and roll\nsurf rock, Latin rock, spaghetti western\nsurf rock, Latin rock, spy theme\nsurf rock, Latin rock, theatrical\nsurf rock, Latin rock, theatrical rock\nsurf rock, Latin rock, world music\nsurf rock, Latin rockabilly\nsurf rock, Latin rumba\nsurf rock, Latin ska\nsurf rock, Latin ska, big band swing\nsurf rock, Latin, Persian pop\nsurf rock, Latin, choral pop\nsurf rock, Latin, cinematic\nsurf rock, Latin, gypsy jazz\nsurf rock, Latin, instrumental\nsurf rock, Latin, rock\nsurf rock, Latin, theatrical\nsurf rock, Latin, upbeat\nsurf rock, Latin, video game\nsurf rock, Latin, video game music\nsurf rock, MPB\nsurf rock, MPB, samba-rock\nsurf rock, Mandopop\nsurf rock, Mandopop, classic rock\nsurf rock, Middle Eastern folk\nsurf rock, Middle Eastern folk, instrumental fusion\nsurf rock, Middle Eastern fusion\nsurf rock, Middle Eastern pop\nsurf rock, Middle Eastern pop-rock\nsurf rock, Middle Eastern rock\nsurf rock, Middle Eastern, Balkan\nsurf rock, Middle Eastern, energetic\nsurf rock, Middle Eastern, theatrical\nsurf rock, Mizrahi pop\nsurf rock, Neue Deutsche Welle\nsurf rock, North African pop\nsurf rock, Russian chanson\nsurf rock, Russian folk\nsurf rock, South Asian pop\nsurf rock, South Indian folk\nsurf rock, Southeast Asian pop\nsurf rock, Soviet pop, post-punk\nsurf rock, Taiwanese Hokkien pop\nsurf rock, Thai pop\nsurf rock, Turkish folk\nsurf rock, Turkish folk, fusion\nsurf rock, Turkish pop-rock\nsurf rock, big band\nsurf rock, big band jazz\nsurf rock, big band jazz, cinematic\nsurf rock, big band jazz, cinematic orchestral\nsurf rock, big band jazz, progressive metal\nsurf rock, big band jazz, progressive rock\nsurf rock, big band jazz, psychedelic rock\nsurf rock, big band jazz, spy soundtrack\nsurf rock, big band jazz, video game music\nsurf rock, big band ska\nsurf rock, big band ska-punk\nsurf rock, big band swing\nsurf rock, big band swing, French chanson\nsurf rock, big band swing, cartoon soundtrack\nsurf rock, big band swing, electronic dance\nsurf rock, big band swing, punk-ska\nsurf rock, big band swing, rockabilly\nsurf rock, big band swing, theatrical rock\nsurf rock, big band, Latin fusion\nsurf rock, big band, Vietnamese rock\nsurf rock, big band, boogie-woogie\nsurf rock, big band, cartoonish\nsurf rock, big band, children's music\nsurf rock, big band, chiptune\nsurf rock, big band, cinematic\nsurf rock, big band, dance\nsurf rock, big band, electronic\nsurf rock, big band, heavy metal\nsurf rock, big band, instrumental\nsurf rock, big band, instrumental rock\nsurf rock, big band, jazz\nsurf rock, big band, klezmer\nsurf rock, big band, psychedelic rock\nsurf rock, big band, punk\nsurf rock, big band, punk rock\nsurf rock, big band, rock\nsurf rock, big band, rock and roll\nsurf rock, big band, rockabilly\nsurf rock, big band, sci-fi\nsurf rock, big band, ska-punk\nsurf rock, big band, spy soundtrack\nsurf rock, big band, spy theme\nsurf rock, big band, swing\nsurf rock, big band, theatrical rock\nsurf rock, big band, trap\nsurf rock, big band, video game music\nsurf rock, big beat\nsurf rock, big beat, electronic\nsurf rock, bluegrass\nsurf rock, bluegrass, country\nsurf rock, blues rock, Hammond organ\nsurf rock, boogie-woogie, hard rock\nsurf rock, boogie-woogie, instrumental\nsurf rock, boogie-woogie, rock and roll\nsurf rock, cabaret jazz\nsurf rock, cabaret, boogie-woogie\nsurf rock, cabaret, electronic\nsurf rock, carnival music\nsurf rock, carnival rock, psychedelic\nsurf rock, children's music\nsurf rock, chiptune\nsurf rock, chiptune, Nintendocore\nsurf rock, chiptune, electronic\nsurf rock, chiptune, indie rock\nsurf rock, chiptune, industrial\nsurf rock, chiptune, lo-fi\nsurf rock, chiptune, power pop\nsurf rock, chiptune, punk rock\nsurf rock, chiptune, video game music\nsurf rock, cinematic orchestral\nsurf rock, cinematic, Balkan\nsurf rock, cinematic, folk rock\nsurf rock, cinematic, klezmer\nsurf rock, cinematic, orchestral\nsurf rock, cinematic, spy movie\nsurf rock, country, children's music\nsurf rock, cumbia\nsurf rock, cumbia, big band\nsurf rock, cumbia, chanson\nsurf rock, cumbia, chiptune\nsurf rock, cumbia, ska\nsurf rock, dangdut\nsurf rock, dangdut koplo\nsurf rock, desert rock\nsurf rock, disco funk, theatrical\nsurf rock, doo-wop, rock and roll\nsurf rock, doo-wop, theatrical rock\nsurf rock, electronic dance\nsurf rock, electronic dance music\nsurf rock, exotica, Czech pop\nsurf rock, exotica, Hawaiian Christmas\nsurf rock, exotica, Indonesian pop\nsurf rock, exotica, holiday\nsurf rock, exotica, pop-rock\nsurf rock, exotica, spy theme\nsurf rock, exotica, vintage pop-rock\nsurf rock, flamenco, progressive rock\nsurf rock, flamenco-punk\nsurf rock, folk fusion\nsurf rock, folk punk, pirate rock\nsurf rock, folk, Eastern European\nsurf rock, folk, chiptune\nsurf rock, folk, klezmer\nsurf rock, free rock\nsurf rock, garage punk\nsurf rock, garage rock\nsurf rock, garage rock, Brazilian\nsurf rock, garage rock, Brazilian rock\nsurf rock, garage rock, Christmas rock\nsurf rock, garage rock, Italian rock\nsurf rock, garage rock, Latin percussion\nsurf rock, garage rock, Latin rock\nsurf rock, garage rock, lo-fi\nsurf rock, gypsy punk, Balkan fusion\nsurf rock, happy hardcore\nsurf rock, hard rock, Middle Eastern\nsurf rock, heavy metal\nsurf rock, heavy metal, Middle Eastern\nsurf rock, heavy metal, cinematic\nsurf rock, heavy metal, video game music\nsurf rock, heavy rock, psychedelic rock\nsurf rock, hip hop, electronic\nsurf rock, indie rock, glitch\nsurf rock, j-rock, noir-jazz\nsurf rock, klezmer punk\nsurf rock, klezmer punk, hard rock\nsurf rock, klezmer rock\nsurf rock, klezmer rock, chiptune\nsurf rock, klezmer, Eastern European folk\nsurf rock, klezmer, Latin\nsurf rock, klezmer, Middle Eastern\nsurf rock, klezmer, balkan\nsurf rock, klezmer, big band\nsurf rock, klezmer, big band jazz\nsurf rock, klezmer, cartoon\nsurf rock, klezmer, cartoon soundtrack\nsurf rock, klezmer, chiptune\nsurf rock, klezmer, cinematic\nsurf rock, klezmer, live energy\nsurf rock, klezmer, progressive rock\nsurf rock, klezmer, punk rock\nsurf rock, klezmer, rock\nsurf rock, klezmer, rock and roll\nsurf rock, klezmer, spy movie\nsurf rock, klezmer, spy soundtrack\nsurf rock, klezmer, theatrical rock\nsurf rock, klezmer, video game music\nsurf rock, laïko, chiptune\nsurf rock, lo-fi hip hop\nsurf rock, mambo, Balkan brass\nsurf rock, mambo, cartoon soundtrack\nsurf rock, mambo, exotica\nsurf rock, mariachi, brass band\nsurf rock, new wave, orchestral rock\nsurf rock, novelty, spy theme\nsurf rock, pansori, korean fusion\nsurf rock, polka, Balkan\nsurf rock, polka, Balkan folk\nsurf rock, polka, Latin\nsurf rock, polka, accordion rock\nsurf rock, polka, chiptune\nsurf rock, polka, cinematic\nsurf rock, polka, rock\nsurf rock, polka, rockabilly\nsurf rock, polka, ska\nsurf rock, polka, spy movie\nsurf rock, polka, video game music\nsurf rock, polka-punk\nsurf rock, polka-punk, folk punk\nsurf rock, pop-rock, C-pop\nsurf rock, pop-rock, blues rock\nsurf rock, power ballad, rock\nsurf rock, power pop\nsurf rock, progressive metal\nsurf rock, progressive metal, free jazz\nsurf rock, progressive metal, video game music\nsurf rock, psychedelic blues\nsurf rock, psychedelic funk\nsurf rock, psychedelic garage rock\nsurf rock, psychedelic rock\nsurf rock, psychedelic rock, Middle Eastern\nsurf rock, psychedelic rock, progressive rock\nsurf rock, psychedelic, Latin\nsurf rock, punk rock, big band\nsurf rock, punk, Balkan folk\nsurf rock, punk, experimental\nsurf rock, rap, pop-rock\nsurf rock, retro rock, Latin rock\nsurf rock, rock and roll, Balkan\nsurf rock, rock and roll, Latin rock\nsurf rock, rock and roll, big band\nsurf rock, rock and roll, novelty\nsurf rock, rock, Middle Eastern\nsurf rock, rockabilly\nsurf rock, rockabilly, Balkan brass\nsurf rock, rockabilly, Brazilian rock\nsurf rock, rockabilly, Greek rock\nsurf rock, rockabilly, Indian film music\nsurf rock, rockabilly, Italian rock\nsurf rock, rockabilly, Latin rock\nsurf rock, rockabilly, Middle Eastern\nsurf rock, rockabilly, Sinhala pop\nsurf rock, rockabilly, South Indian pop-rock\nsurf rock, rockabilly, big band\nsurf rock, rockabilly, boogie-woogie\nsurf rock, rockabilly, cabaret\nsurf rock, rockabilly, cinematic\nsurf rock, rockabilly, klezmer\nsurf rock, rockabilly, novelty\nsurf rock, rockabilly, polka\nsurf rock, rockabilly, retro rock\nsurf rock, rockabilly, rock 'n' roll\nsurf rock, rockabilly, rock and roll\nsurf rock, rockabilly, surf metal\nsurf rock, samba-rock\nsurf rock, schlager, retro rock\nsurf rock, ska, fingerstyle\nsurf rock, ska, rock\nsurf rock, ska, rock and roll\nsurf rock, ska-punk\nsurf rock, ska-punk, big band\nsurf rock, soul, rock and roll\nsurf rock, spaghetti western\nsurf rock, speed metal\nsurf rock, spy electronica, funk\nsurf rock, spy metal, C-pop\nsurf rock, spy movie\nsurf rock, spy movie soundtrack\nsurf rock, spy movie, alternative rock\nsurf rock, spy movie, big band\nsurf rock, spy movie, cinematic\nsurf rock, spy movie, instrumental\nsurf rock, spy movie, modern rock\nsurf rock, spy movie, quirky\nsurf rock, spy movie, retro-funk\nsurf rock, spy movie, theatrical new wave\nsurf rock, spy movie, video game\nsurf rock, spy movie, video game soundtrack\nsurf rock, spy rock\nsurf rock, spy soundtrack\nsurf rock, spy theme\nsurf rock, spy theme, big band\nsurf rock, spy theme, funk\nsurf rock, spy theme, video game music\nsurf rock, spy thriller, electronic\nsurf rock, surf punk, spy theme\nsurf rock, symphonic metal, spy movie\nsurf rock, synth-pop\nsurf rock, synth-pop, revolutionary anthem\nsurf rock, theatrical cabaret\nsurf rock, theatrical pop, Halloween\nsurf rock, theatrical rock, show tune\nsurf rock, theatrical, spy movie\nsurf rock, video game boss music\nsurf rock, video game music\nsurf rock, video game music, progressive metal\nsurf rock, video game music, spy movie\nsurf rock, video game music, spy theme\nsurf rock, video game music, synthwave\nsurf rock, video game soundtrack\nsurf rock, vintage Turkish rock\nsurf rock, vintage rock and roll, big band\nsurf rock, western swing\nsurf rock, world fusion\nsurf rock, world fusion, Middle Eastern\nsurf rock, world music, dance\nsurf rock, world music, psychedelic\nsurf-funk\nsurf-hop\nsurf-pop\nsurf-pop chiptune\nsurf-pop city pop\nsurf-pop doo-wop\nsurf-pop indie rock\nsurf-pop latin\nsurf-pop lo-fi\nsurf-pop reggae\nsurf-punk\nsurf-punk anime\nsurf-punk art-rock\nsurf-punk blues-rock\nsurf-punk chiptune\nsurf-punk cinematic\nsurf-punk cumbia\nsurf-punk funk-rock\nsurf-punk fusion\nsurf-punk garage rock\nsurf-punk indie rock\nsurf-punk lo-fi\nsurf-punk pop-punk\nsurf-punk reggae-rock\nsurf-punk rock\nsurf-punk rockabilly\nsurf-punk ska\nsurf-punk, Russian rock\nsurf-punk, cinematic rock, post-rock\nsurf-punk, dream pop, punk rock\nsurf-punk, hard rock, theatrical rock\nsurf-punk, indie rock, chiptune\nsurf-punk, math rock\nsurf-punk, new wave, punk rock\nsurf-punk, power ballad\nsurf-punk, power-pop, psychedelic\nsurf-punk, psychedelic rock\nsurf-punk, psychedelic rock, indie rock\nsurf-punk, samba-rock, bossa nova\nsurf-reggae\nsurf-rock\nsurf-rock alternative rock\nsurf-rock big band\nsurf-rock big-band fusion\nsurf-rock blues-rock\nsurf-rock children's\nsurf-rock children's music\nsurf-rock chiptune\nsurf-rock city-pop\nsurf-rock cumbia\nsurf-rock disco-funk\nsurf-rock doo-wop pop-rock\nsurf-rock electronic\nsurf-rock exotica\nsurf-rock folk-rock\nsurf-rock funk\nsurf-rock funk-rock\nsurf-rock funk-rock indie pop\nsurf-rock fusion\nsurf-rock garage\nsurf-rock garage rock\nsurf-rock garage-rock\nsurf-rock gothic\nsurf-rock hip hop\nsurf-rock hip-hop\nsurf-rock horror\nsurf-rock indie\nsurf-rock indie pop\nsurf-rock indie-pop\nsurf-rock indie-rock\nsurf-rock j-rock\nsurf-rock klezmer rock\nsurf-rock latin\nsurf-rock latin rock\nsurf-rock lo-fi\nsurf-rock lounge pop\nsurf-rock math-rock\nsurf-rock metal\nsurf-rock new wave\nsurf-rock noir-western\nsurf-rock pop\nsurf-rock pop-punk\nsurf-rock pop-rock\nsurf-rock psychedelic\nsurf-rock psychedelic rock\nsurf-rock pub-rock\nsurf-rock punk\nsurf-rock reggae\nsurf-rock reggae fusion\nsurf-rock reggae rock\nsurf-rock reggae-rock fusion\nsurf-rock rock\nsurf-rock rockabilly\nsurf-rock rockabilly folk\nsurf-rock ska\nsurf-rock ska fusion\nsurf-rock ska-punk\nsurf-rock spaghetti western\nsurf-rock spaghetti-western\nsurf-rock tango\nsurf-rock thrash metal\nsurf-rock trap\nsurf-rock world music\nsurf-rock, Balkan brass, theatrical rock\nsurf-rock, Brazilian pop-rock\nsurf-rock, Eastern European rock\nsurf-rock, French pop\nsurf-rock, Hawaiian music, festive\nsurf-rock, J-rock, rock\nsurf-rock, Latin rock\nsurf-rock, Latin, instrumental\nsurf-rock, Middle Eastern, folk-rock\nsurf-rock, Soviet rock\nsurf-rock, Turkish pop, cinematic\nsurf-rock, acoustic ballad\nsurf-rock, art-pop, anthemic rock\nsurf-rock, big band, children's music\nsurf-rock, big band, novelty\nsurf-rock, chiptune, C-pop\nsurf-rock, chiptune, rock\nsurf-rock, cinematic, cabaret\nsurf-rock, cinematic, experimental\nsurf-rock, dance-pop, theatrical\nsurf-rock, electronic, hip hop\nsurf-rock, flamenco, Hebrew rock\nsurf-rock, flamenco, Latin\nsurf-rock, folk, electronic\nsurf-rock, garage rock, children's music\nsurf-rock, garage-rock, Filipino Christmas\nsurf-rock, heavy metal\nsurf-rock, hip-hop, garage rock\nsurf-rock, indie rock, psychedelic\nsurf-rock, klezmer, rock\nsurf-rock, lo-fi hip hop, electronic\nsurf-rock, lo-fi, jazz\nsurf-rock, mambo, Halloween\nsurf-rock, metalcore, theatrical rock\nsurf-rock, new wave\nsurf-rock, new wave, theatrical rock\nsurf-rock, noise rock, lo-fi\nsurf-rock, polka, comedy\nsurf-rock, pop-rock, rock\nsurf-rock, psychedelic rock, funk\nsurf-rock, psychedelic, energetic\nsurf-rock, psychedelic, garage rock\nsurf-rock, punk-rock, metal\nsurf-rock, rockabilly, Brazilian pop\nsurf-rock, rockabilly, Halloween\nsurf-rock, rockabilly, cartoon rock\nsurf-rock, rockabilly, hip-hop\nsurf-rock, rockabilly, satire\nsurf-rock, sci-fi, Christmas\nsurf-rock, ska, children's music\nsurf-rock, ska-punk, Latin rock\nsurf-rock, spaghetti-western, hard rock\nsurf-rock, spy movie, cinematic\nsurf-rock, spy theme, theatrical\nsurf-rock, spy-thriller, cinematic\nsurf-rock, surf-metal\nsurf-rock, tango, Russian chanson\nsurf-rock, theatrical rock\nsurf-rock, theatrical rock, genre-bending\nsurf-rock, theatrical rock, spy movie\nsurf-rock, theatrical, Halloween\nsurf-rock, theatrical, quirky\nsurf-rock, western, cinematic rock\nsurf-ska\nsurf-ska, tropical pop, rock\nsurf-ska-punk\nsurreal folk\nsurreal folk-rock\nsurreal hip-hop\nsurreal piano\nsurreal pop\nswamp blues\nswamp folk\nswamp funk\nswamp jazz\nswamp rock\nswamp rock boogie-woogie\nswamp rock cajun\nswamp rock country rap\nswamp rock country rockabilly\nswamp rock country-blues\nswamp rock cumbia latin\nswamp rock funk\nswamp rock garage rock\nswamp rock hip-hop\nswamp rock rockabilly\nswamp rock, Cajun\nswamp rock, Cajun, rock\nswamp soul\nswamp trap\nswamp-folk\nswamp-funk\nswamp-gothic\nswamp-hop\nswamp-hop trap\nswamp-jazz\nswamp-rock\nswamp-trap\nsweet pop\nswing\nswing a cappella\nswing blues\nswing boogie-woogie\nswing cabaret\nswing cabaret boogie-woogie\nswing chanson\nswing comedy\nswing drum and bass\nswing folk\nswing funk\nswing funk hip-hop\nswing funk jazz\nswing funk pop-rock\nswing gypsy jazz\nswing hip-hop\nswing house\nswing jazz\nswing jazz Arabic fusion\nswing jazz Celtic folk\nswing jazz cabaret\nswing jazz city pop\nswing jazz exotica\nswing jazz hip-hop\nswing jazz j-pop\nswing jazz lounge\nswing jazz mandopop\nswing jazz novelty\nswing jazz punk rock\nswing jazz rockabilly\nswing jazz world music\nswing jazz, Japanese rap\nswing jazz, Shidaiqu\nswing jazz, Tamil pop, hard rock\nswing jazz, musical theater\nswing jazz, vintage Shidaiqu\nswing klezmer\nswing klezmer fusion\nswing lounge\nswing novelty\nswing pop\nswing pop rock\nswing punk\nswing punk rock chiptune\nswing ragtime\nswing rap\nswing revival\nswing revival rockabilly\nswing revival ska Latin rock\nswing revival theatrical rock\nswing rock\nswing rock cabaret\nswing rock jump blues\nswing rock rockabilly\nswing rockabilly\nswing rockabilly French chanson\nswing rockabilly big band\nswing rockabilly blues\nswing rockabilly cabaret\nswing rockabilly chanson\nswing rockabilly chiptune\nswing rockabilly country-western\nswing rockabilly jazz\nswing rockabilly jump blues\nswing rockabilly novelty\nswing rockabilly punk\nswing rockabilly show tune\nswing show tune\nswing ska\nswing ska latin\nswing ska rockabilly\nswing ska-punk\nswing surf cumbia\nswing villain\nswing, C-pop, festive\nswing, Christmas, vintage\nswing, Halloween, theatrical\nswing, Latin jazz\nswing, big band, schlager\nswing, blues, jump blues\nswing, blues, vintage\nswing, boogie-woogie, Italian folk\nswing, cinematic, quirky\nswing, dream-pop, experimental\nswing, folk, Italian-American\nswing, humppa, schlager\nswing, jump blues, big band\nswing, klezmer, cartoon soundtrack\nswing, klezmer, jazz\nswing, klezmer, theatrical\nswing, mambo, big band\nswing, novelty, Christmas\nswing, novelty, lounge jazz\nswing, retro, blues-rock\nswing, rockabilly, surf rock\nswing, theatrical, Middle Eastern\nswing, theatrical, boogie-woogie\nswing, theatrical, cinematic\nswing, theatrical, festive\nswing, theatrical, film noir\nswing, theatrical, folk\nswing, theatrical, klezmer\nswing, theatrical, piano ballad\nswing-blues\nswing-folk\nswing-funk\nswing-gypsy jazz\nswing-hop\nswing-jazz\nswing-jazz cabaret\nswing-jazz novelty\nswing-jazz, gypsy jazz, boogie-woogie\nswing-polka\nswing-pop\nswing-pop cabaret\nswing-pop doo-wop\nswing-pop funk\nswing-pop gypsy jazz\nswing-pop jazz\nswing-pop klezmer\nswing-pop lo-fi\nswing-pop lounge jazz\nswing-pop mambo\nswing-pop rockabilly\nswing-pop tango\nswing-punk\nswing-rap\nswing-rock\nswing-rock big band\nswing-rock cabaret musical theater\nswing-rock punk\nswing-rockabilly\nswing-ska\nsymphonic\nsymphonic EDM\nsymphonic EDM baroque pop\nsymphonic J-Rock\nsymphonic J-pop\nsymphonic J-rock\nsymphonic J-rock artcore\nsymphonic J-rock chiptune\nsymphonic J-rock electronicore\nsymphonic J-rock metalcore\nsymphonic J-rock power metal\nsymphonic J-rock speed metal\nsymphonic J-rock trancecore\nsymphonic Middle Eastern rock\nsymphonic alternative metal\nsymphonic alternative rock\nsymphonic anthem\nsymphonic band\nsymphonic black metal\nsymphonic chiptune\nsymphonic dance-pop\nsymphonic death metal\nsymphonic deathcore\nsymphonic doom metal\nsymphonic electronic\nsymphonic eurodance\nsymphonic folk\nsymphonic folk metal\nsymphonic folk rock\nsymphonic folk-metal\nsymphonic folk-rock\nsymphonic funk-rock\nsymphonic fusion\nsymphonic gothic rock\nsymphonic hard rock\nsymphonic hardcore\nsymphonic hardstyle\nsymphonic heavy metal\nsymphonic hip-hop\nsymphonic industrial\nsymphonic industrial metal\nsymphonic industrial rock\nsymphonic march\nsymphonic melodic metalcore\nsymphonic metal\nsymphonic metal C-pop\nsymphonic metal cabaret\nsymphonic metal chiptune\nsymphonic metal chiptune j-rock\nsymphonic metal cyberpunk\nsymphonic metal electronicore\nsymphonic metal folk\nsymphonic metal folk metal\nsymphonic metal hip-hop\nsymphonic metal industrial\nsymphonic metal industrial rock\nsymphonic metal opera\nsymphonic metal pirate metal\nsymphonic metal power metal\nsymphonic metal progressive metal\nsymphonic metal progressive rock\nsymphonic metal thrash\nsymphonic metal, C-pop\nsymphonic metal, C-pop, ancient style\nsymphonic metal, C-pop, rock\nsymphonic metal, C-rock\nsymphonic metal, Chinese folk\nsymphonic metal, Chinese folk, chiptune\nsymphonic metal, Chinese folk, cinematic rock\nsymphonic metal, Chinese folk, epic rock\nsymphonic metal, Chinese folk, power metal\nsymphonic metal, Chinese folk, rock\nsymphonic metal, Chinese folk-pop, cinematic\nsymphonic metal, Chinese fusion\nsymphonic metal, Chinese opera\nsymphonic metal, Chinese opera, chiptune\nsymphonic metal, Chinese opera, cinematic rock\nsymphonic metal, Chinese opera, modern rock\nsymphonic metal, Chinese rock\nsymphonic metal, Chinese rock, cinematic\nsymphonic metal, Chinese traditional\nsymphonic metal, J-core\nsymphonic metal, J-metal\nsymphonic metal, J-pop\nsymphonic metal, J-rock\nsymphonic metal, J-rock, C-pop\nsymphonic metal, J-rock, Chinese melodic\nsymphonic metal, J-rock, Chinese traditional\nsymphonic metal, J-rock, anison\nsymphonic metal, J-rock, chiptune\nsymphonic metal, J-rock, metalcore\nsymphonic metal, J-rock, power metal\nsymphonic metal, J-rock, traditional Japanese\nsymphonic metal, Japanese traditional\nsymphonic metal, Middle Eastern rock\nsymphonic metal, Middle Eastern rock, pop\nsymphonic metal, breakbeat, drum and bass\nsymphonic metal, chiptune\nsymphonic metal, chiptune, Japanese video game music\nsymphonic metal, deathcore, ambient\nsymphonic metal, electronic\nsymphonic metal, electronic rock\nsymphonic metal, electronicore, trance\nsymphonic metal, industrial, chiptune\nsymphonic metal, melodic death metal\nsymphonic metal, metalcore, C-pop\nsymphonic metal, neoclassical shred\nsymphonic metal, nu-metal, C-pop\nsymphonic metal, power metal\nsymphonic metal, rap metal\nsymphonic metal, rap-metal, Chinese opera\nsymphonic metal, theatrical rock\nsymphonic metal, video game music\nsymphonic metalcore\nsymphonic metalcore J-rock\nsymphonic metalcore chiptune\nsymphonic metalcore electronic rock\nsymphonic metalcore electronicore\nsymphonic metalcore j-rock\nsymphonic metalcore trance\nsymphonic metalcore, J-rock\nsymphonic metalcore, J-rock power metal\nsymphonic metalcore, hyperpop, chiptune\nsymphonic orchestral\nsymphonic patriotic\nsymphonic pop\nsymphonic pop-rock\nsymphonic post-hardcore\nsymphonic power ballad\nsymphonic power metal\nsymphonic power metal chiptune\nsymphonic power metal electronicore\nsymphonic power metal folk metal\nsymphonic power metal, Chinese folk\nsymphonic power metal, J-rock\nsymphonic power metal, chiptune rock\nsymphonic power rock\nsymphonic power-pop\nsymphonic progressive house\nsymphonic progressive metal\nsymphonic progressive rock\nsymphonic punk\nsymphonic revolutionary\nsymphonic rock\nsymphonic rock C-pop\nsymphonic rock alternative metal\nsymphonic rock anime\nsymphonic rock chiptune\nsymphonic rock emo-pop\nsymphonic rock funk\nsymphonic rock industrial metal\nsymphonic rock jazz fusion\nsymphonic rock kayōkyoku\nsymphonic rock metalcore\nsymphonic rock neoclassical metal\nsymphonic rock opera\nsymphonic rock power metal\nsymphonic rock progressive\nsymphonic rock progressive metal\nsymphonic rock world music\nsymphonic rock wuxia\nsymphonic rock, Anatolian rock\nsymphonic rock, C-pop\nsymphonic rock, C-pop, cinematic\nsymphonic rock, C-pop, pop/R&B\nsymphonic rock, Chinese fusion\nsymphonic rock, Chinese opera, cinematic\nsymphonic rock, J-pop, cinematic\nsymphonic rock, J-rock\nsymphonic rock, J-rock, Chinese fusion\nsymphonic rock, J-rock, Chinese traditional\nsymphonic rock, J-rock, anime\nsymphonic rock, J-rock, cinematic\nsymphonic rock, J-rock, power metal\nsymphonic rock, Turkish folk\nsymphonic rock, chiptune, cinematic\nsymphonic rock, chiptune, progressive metal\nsymphonic rock, cinematic, C-pop\nsymphonic rock, cinematic, Chinese opera\nsymphonic rock, conscious hip-hop\nsymphonic rock, dangdut koplo\nsymphonic rock, happy hardcore, trance\nsymphonic rock, hardcore electronic, chiptune\nsymphonic rock, hardstyle, cinematic\nsymphonic rock, heavy metal, Chinese opera\nsymphonic rock, hip-hop, cinematic\nsymphonic rock, metalcore\nsymphonic rock, modern metal, Chinese fusion\nsymphonic rock, pop-punk\nsymphonic rock, progressive metal, video game music\nsymphonic rock, rap-rock, nu-metal\nsymphonic rock, video game music\nsymphonic trance\nsymphonic trance pop-rock\nsymphonic trancecore\nsymphonic video game\nsynth\nsynth Christmas\nsynth R&B\nsynth accordion\nsynth ambient\nsynth anthem\nsynth arpeggio\nsynth ballad\nsynth baroque\nsynth baroque funk\nsynth bass\nsynth bass hip-hop\nsynth big band\nsynth brass\nsynth brass fanfare\nsynth chamber\nsynth chanson\nsynth choir\nsynth choral\nsynth classical\nsynth cumbia\nsynth etude\nsynth fairytale\nsynth fanfare\nsynth fanfare, Brazilian funk, trap\nsynth fantasy\nsynth folk\nsynth folk-pop\nsynth funk\nsynth funk, Brazilian funk, worldbeat\nsynth fusion\nsynth harp\nsynth hip hop\nsynth hip-hop\nsynth holiday\nsynth horror\nsynth house\nsynth hymn\nsynth instrumental\nsynth jazz\nsynth jingle\nsynth lullaby\nsynth mallet\nsynth metal\nsynth metalcore\nsynth music\nsynth music box\nsynth nursery rhyme\nsynth orchestra\nsynth orchestral\nsynth orchestral chiptune\nsynth organ\nsynth piano\nsynth pluck\nsynth polka\nsynth pop\nsynth pop Latin R&B\nsynth pop R&B nu-metal\nsynth pop children's music\nsynth pop chiptune\nsynth pop fairytale\nsynth pop future bass\nsynth pop hip-hop\nsynth pop reggaeton\nsynth pop rock\nsynth pop trap R&B\nsynth pop world music\nsynth pop, Azerbaijani pop, Turkish pop\nsynth pop, Brazilian funk\nsynth pop, C-pop, video game music\nsynth pop, Central Asian pop\nsynth pop, Dangdut, Vocaloid\nsynth pop, East African, Sinhala\nsynth pop, Halloween, theatrical\nsynth pop, Javanese influence\nsynth pop, South Asian pop\nsynth pop, Southeast Asian pop\nsynth pop, ambient, lo-fi\nsynth pop, big band, anime\nsynth pop, children's music\nsynth pop, chiptune, dark ambient\nsynth pop, cinematic, hyperpop\nsynth pop, dark ambient\nsynth pop, emotional ballad\nsynth pop, experimental, electronic\nsynth pop, hip hop, funk\nsynth pop, hip-hop, R&B\nsynth pop, jazz fusion\nsynth pop, lo-fi hip hop\nsynth pop, music box\nsynth pop, musical theater, nostalgic\nsynth pop, pop-rock\nsynth pop, pop-rock, C-pop\nsynth pop, theatrical pop\nsynth pop, trap\nsynth pop, trap, ambient\nsynth pop, trap, experimental\nsynth pop, trap, oriental\nsynth pop, video game music\nsynth pop, world music, lo-fi\nsynth pop, worldbeat, dancehall\nsynth punk\nsynth rock\nsynth sax\nsynth soul\nsynth steelpan\nsynth stinger\nsynth stings\nsynth trap\nsynth trot\nsynth voice\nsynth waltz\nsynth whimsy\nsynth world music\nsynth worship\nsynth-driven C-pop\nsynth-driven alternative rock\nsynth-driven hip-hop\nsynth-folk\nsynth-folk chiptune\nsynth-funk\nsynth-funk 80s\nsynth-funk 80s R&B\nsynth-funk 80s anime\nsynth-funk 80s new wave\nsynth-funk C-pop\nsynth-funk G-funk\nsynth-funk J-pop\nsynth-funk K-pop\nsynth-funk R&B\nsynth-funk R&B, pop-rock\nsynth-funk ambient\nsynth-funk big beat\nsynth-funk boogie\nsynth-funk boogie chiptune\nsynth-funk breakbeat\nsynth-funk children's\nsynth-funk chillwave\nsynth-funk chiptune\nsynth-funk chiptune J-pop\nsynth-funk chiptune city pop\nsynth-funk chiptune vaporwave\nsynth-funk city pop\nsynth-funk city pop R&B\nsynth-funk city pop chiptune\nsynth-funk city pop j-pop\nsynth-funk city pop neo-soul\nsynth-funk city pop nu-disco\nsynth-funk city pop vaporwave\nsynth-funk city-pop\nsynth-funk city-pop vaporwave\nsynth-funk comedy\nsynth-funk cyberpunk\nsynth-funk dance-pop\nsynth-funk disco\nsynth-funk disco-pop\nsynth-funk electro\nsynth-funk electro ambient\nsynth-funk electro-funk\nsynth-funk electro-funk novelty pop\nsynth-funk electro-pop\nsynth-funk electro-rock\nsynth-funk freestyle\nsynth-funk g-funk\nsynth-funk gospel\nsynth-funk gospel pop\nsynth-funk gospel-pop\nsynth-funk hip-hop\nsynth-funk horror-disco\nsynth-funk horror-pop\nsynth-funk house\nsynth-funk indie pop\nsynth-funk indie-pop\nsynth-funk industrial rock\nsynth-funk j-pop\nsynth-funk j-pop video game\nsynth-funk j-rock\nsynth-funk jazz fusion\nsynth-funk lo-fi\nsynth-funk new jack swing\nsynth-funk new wave\nsynth-funk nu-disco\nsynth-funk nu-disco city pop\nsynth-funk pop-rock\nsynth-funk post-disco\nsynth-funk post-punk\nsynth-funk progressive rock\nsynth-funk punk rock\nsynth-funk rock\nsynth-funk soul\nsynth-funk space-pop\nsynth-funk theatrical\nsynth-funk trap\nsynth-funk vaporwave\nsynth-funk vaporwave chiptune\nsynth-funk world music\nsynth-funk zouk\nsynth-funk, 80s boogie, Italo-disco\nsynth-funk, 80s new wave\nsynth-funk, 80s new wave, dance\nsynth-funk, Arabic pop\nsynth-funk, Bollywood-pop, Indian fusion\nsynth-funk, Brazilian funk, lo-fi\nsynth-funk, Brazilian pop\nsynth-funk, Brazilian pop-rock\nsynth-funk, Christian hip-hop\nsynth-funk, City Pop, retro\nsynth-funk, French pop, new jack swing\nsynth-funk, French pop, retro\nsynth-funk, G-funk, retro-futuristic\nsynth-funk, Italo disco\nsynth-funk, Italo disco, 80s\nsynth-funk, Italo disco, 80s dance\nsynth-funk, J-pop, video game\nsynth-funk, K-pop, city pop\nsynth-funk, Middle Eastern pop, 80s fusion\nsynth-funk, Neue Deutsche Welle\nsynth-funk, North African pop\nsynth-funk, R&B\nsynth-funk, R&B, 80s\nsynth-funk, R&B, cinematic\nsynth-funk, Russian electronic, quirky\nsynth-funk, Russian pop-rock\nsynth-funk, Russian rock\nsynth-funk, Soviet new wave\nsynth-funk, Soviet new wave, funk\nsynth-funk, Tamil pop, 80s/90s pop\nsynth-funk, Turkish pop\nsynth-funk, Turkish, 80s\nsynth-funk, boogie, 80s\nsynth-funk, boogie, 80s disco\nsynth-funk, boogie, city pop\nsynth-funk, chiptune, Japanese video game\nsynth-funk, chiptune, Japanese video game music\nsynth-funk, chiptune, R&B\nsynth-funk, chiptune, retro-futuristic\nsynth-funk, cinematic, C-pop\nsynth-funk, cinematic, Chinese pop\nsynth-funk, cinematic, electronic\nsynth-funk, cinematic, hip-hop\nsynth-funk, city pop\nsynth-funk, city pop, 80s\nsynth-funk, city pop, Italo-disco\nsynth-funk, city pop, K-pop\nsynth-funk, city pop, R&B\nsynth-funk, city pop, anime\nsynth-funk, city pop, anime theme\nsynth-funk, city pop, boogie\nsynth-funk, city pop, chiptune\nsynth-funk, city pop, disco\nsynth-funk, city pop, electro-funk\nsynth-funk, city pop, hip-hop\nsynth-funk, city pop, lo-fi hip hop\nsynth-funk, city pop, neo-soul\nsynth-funk, city pop, new jack swing\nsynth-funk, city pop, new wave\nsynth-funk, city pop, nu-disco\nsynth-funk, city pop, retro\nsynth-funk, city pop, retro-futuristic\nsynth-funk, city pop, vaporwave\nsynth-funk, city pop, video game\nsynth-funk, city pop, video game music\nsynth-funk, city pop, video game soundtrack\nsynth-funk, city-pop\nsynth-funk, city-pop, Mandarin pop\nsynth-funk, city-pop, pop-rap\nsynth-funk, city-pop, retro\nsynth-funk, city-pop, retro-futuristic\nsynth-funk, cyberpunk, vaporwave\nsynth-funk, electro-funk, hip-house\nsynth-funk, electro-funk, new jack swing\nsynth-funk, folk-pop\nsynth-funk, hard rock\nsynth-funk, hip-hop, Afrofusion\nsynth-funk, hip-hop, V-Pop\nsynth-funk, horror-disco\nsynth-funk, lo-fi hip hop, C-pop\nsynth-funk, new jack swing\nsynth-funk, new jack swing, 80s\nsynth-funk, new jack swing, 80s funk\nsynth-funk, new jack swing, 80s-inspired\nsynth-funk, new jack swing, C-pop\nsynth-funk, new jack swing, R&B\nsynth-funk, new jack swing, Russian\nsynth-funk, new jack swing, chiptune\nsynth-funk, new jack swing, city pop\nsynth-funk, new jack swing, comedic\nsynth-funk, new jack swing, comedy\nsynth-funk, new jack swing, dance-pop\nsynth-funk, new jack swing, electro\nsynth-funk, new jack swing, electronic\nsynth-funk, new jack swing, festive\nsynth-funk, new jack swing, funk\nsynth-funk, new jack swing, funk-pop\nsynth-funk, new jack swing, gospel\nsynth-funk, new jack swing, hip-hop\nsynth-funk, new jack swing, novelty\nsynth-funk, new jack swing, retro-futuristic\nsynth-funk, new jack swing, trap\nsynth-funk, new jack swing, upbeat\nsynth-funk, new jack swing, video game music\nsynth-funk, new jack swing, zouk\nsynth-funk, new wave\nsynth-funk, new wave, 80s\nsynth-funk, new wave, French cold wave\nsynth-funk, new wave, Italo disco\nsynth-funk, new wave, funk rock\nsynth-funk, new wave, rock\nsynth-funk, novelty pop\nsynth-funk, nu-disco, city pop\nsynth-funk, nu-metal, hip-hop\nsynth-funk, orchestral, Japanese RPG\nsynth-funk, pop-rock, 80s\nsynth-funk, post-disco, R&B\nsynth-funk, retro video game, city pop\nsynth-funk, retro, city pop\nsynth-funk, retro-funk, theatrical pop\nsynth-funk, retro-futuristic, C-pop\nsynth-funk, smooth jazz\nsynth-funk, trot\nsynth-funk, video game music, 80s Japanese\nsynth-funk, video game music, fusion\nsynth-funk, video game music, retro-futuristic\nsynth-fusion\nsynth-gospel\nsynth-hop\nsynth-hop funk\nsynth-metal\nsynth-orchestral\nsynth-orchestral cumbia\nsynth-polka\nsynth-pop\nsynth-pop 16-bit\nsynth-pop 1980s\nsynth-pop 8-bit\nsynth-pop 8-bit chiptune\nsynth-pop 80s\nsynth-pop 80s Asian pop\nsynth-pop 80s Bollywood\nsynth-pop 80s C-pop\nsynth-pop 80s Cantopop\nsynth-pop 80s Cantopop anime\nsynth-pop 80s Chinese New Year\nsynth-pop 80s Chinese pop\nsynth-pop 80s Chinese pop-rock\nsynth-pop 80s Christmas\nsynth-pop 80s Christmas rock\nsynth-pop 80s City Pop\nsynth-pop 80s Czech pop-rock\nsynth-pop 80s East Asian\nsynth-pop 80s East Asian pop\nsynth-pop 80s Eastern European\nsynth-pop 80s Eastern European new wave\nsynth-pop 80s Euro-pop\nsynth-pop 80s Eurodance\nsynth-pop 80s European\nsynth-pop 80s Europop\nsynth-pop 80s Europop chiptune\nsynth-pop 80s French pop\nsynth-pop 80s Israeli rock\nsynth-pop 80s J-pop\nsynth-pop 80s Mandopop\nsynth-pop 80s Mandopop chiptune\nsynth-pop 80s Mandopop cinematic\nsynth-pop 80s Mandopop disco\nsynth-pop 80s R&B\nsynth-pop 80s Schlager\nsynth-pop 80s South Asian\nsynth-pop 80s South Asian film\nsynth-pop 80s South Asian new wave\nsynth-pop 80s South Asian pop\nsynth-pop 80s Southeast Asian\nsynth-pop 80s Southeast Asian new wave\nsynth-pop 80s Soviet new wave\nsynth-pop 80s Thai pop\nsynth-pop 80s V-Pop\nsynth-pop 80s anime\nsynth-pop 80s cartoon\nsynth-pop 80s chiptune\nsynth-pop 80s cinematic\nsynth-pop 80s city pop\nsynth-pop 80s city pop Cantopop\nsynth-pop 80s city pop Mandopop\nsynth-pop 80s city pop R&B\nsynth-pop 80s city pop anime\nsynth-pop 80s city pop chiptune\nsynth-pop 80s city pop funk\nsynth-pop 80s city pop synthwave\nsynth-pop 80s coastal\nsynth-pop 80s corporate jingle\nsynth-pop 80s dance\nsynth-pop 80s dance-pop\nsynth-pop 80s dancehall\nsynth-pop 80s disco\nsynth-pop 80s electro\nsynth-pop 80s electro-pop\nsynth-pop 80s eurodance\nsynth-pop 80s filmi\nsynth-pop 80s fitness\nsynth-pop 80s funk\nsynth-pop 80s gospel\nsynth-pop 80s horror\nsynth-pop 80s horror-comedy\nsynth-pop 80s lounge\nsynth-pop 80s new age\nsynth-pop 80s new wave\nsynth-pop 80s new wave EBM\nsynth-pop 80s new wave chiptune\nsynth-pop 80s new wave cinematic\nsynth-pop 80s new wave city pop\nsynth-pop 80s new wave funk\nsynth-pop 80s new wave post-punk\nsynth-pop 80s new wave space rock\nsynth-pop 80s new-age\nsynth-pop 80s nostalgic\nsynth-pop 80s pop\nsynth-pop 80s pop-funk\nsynth-pop 80s pop-rock\nsynth-pop 80s power-pop\nsynth-pop 80s retro\nsynth-pop 80s retro K-pop\nsynth-pop 80s retro-funk\nsynth-pop 80s retro-futuristic\nsynth-pop 80s retro-futuristic J-pop\nsynth-pop 80s revival\nsynth-pop 80s rock\nsynth-pop 80s schlager\nsynth-pop 80s smooth jazz\nsynth-pop 80s soundtrack\nsynth-pop 80s tropical\nsynth-pop 80s video game\nsynth-pop 80s world music\nsynth-pop 80s worldbeat\nsynth-pop 80s/90s\nsynth-pop 90s\nsynth-pop 90s Asian pop\nsynth-pop 90s J-pop\nsynth-pop 90s J-pop K-pop\nsynth-pop 90s K-pop\nsynth-pop 90s Mandopop\nsynth-pop 90s R&B\nsynth-pop 90s alternative dance\nsynth-pop 90s anime\nsynth-pop 90s dance\nsynth-pop 90s dance-pop\nsynth-pop 90s electronic\nsynth-pop 90s eurodance\nsynth-pop 90s hip-hop\nsynth-pop 90s house\nsynth-pop 90s retro-futuristic\nsynth-pop 90s trance\nsynth-pop 90s video game\nsynth-pop AOR\nsynth-pop African fusion\nsynth-pop African gospel\nsynth-pop Afrikaans pop\nsynth-pop Afrikaans pop-rock\nsynth-pop Afro-Latin\nsynth-pop Afro-pop\nsynth-pop Afro-pop worldbeat\nsynth-pop Afrobeat\nsynth-pop Anatolian rock\nsynth-pop Arabic\nsynth-pop Arabic children's\nsynth-pop Arabic pop\nsynth-pop Axé\nsynth-pop Balkan\nsynth-pop Balkan folk\nsynth-pop Balkan new wave\nsynth-pop Balkan pop\nsynth-pop Balkan pop-rock\nsynth-pop Balkan rock\nsynth-pop Bollywood\nsynth-pop Bollywood-pop\nsynth-pop C-pop\nsynth-pop C-pop Cantopop\nsynth-pop C-pop Christian contemporary\nsynth-pop C-pop EDM\nsynth-pop C-pop Eurodance\nsynth-pop C-pop J-pop\nsynth-pop C-pop J-rock\nsynth-pop C-pop K-pop\nsynth-pop C-pop R&B\nsynth-pop C-pop V-pop\nsynth-pop C-pop anime\nsynth-pop C-pop anime soundtrack\nsynth-pop C-pop bedroom pop\nsynth-pop C-pop chillwave\nsynth-pop C-pop chiptune\nsynth-pop C-pop city pop\nsynth-pop C-pop city-pop\nsynth-pop C-pop dream pop\nsynth-pop C-pop dreamy\nsynth-pop C-pop electronic\nsynth-pop C-pop electronic dance\nsynth-pop C-pop electronic rock\nsynth-pop C-pop funk-rock\nsynth-pop C-pop future bass\nsynth-pop C-pop futuristic\nsynth-pop C-pop hip-hop\nsynth-pop C-pop hyperpop\nsynth-pop C-pop new age\nsynth-pop C-pop retro\nsynth-pop C-pop retro game\nsynth-pop C-pop retro video game\nsynth-pop C-pop retro-futuristic\nsynth-pop C-pop retro-wave\nsynth-pop C-pop synthwave\nsynth-pop C-pop trance\nsynth-pop C-pop trap\nsynth-pop C-pop vaporwave\nsynth-pop C-pop video game\nsynth-pop C-pop video game music\nsynth-pop C-pop world music\nsynth-pop C-pop wuxia\nsynth-pop CCM\nsynth-pop Cantopop\nsynth-pop Cantopop anime\nsynth-pop Celtic\nsynth-pop Celtic folk\nsynth-pop Central Asian\nsynth-pop Christian\nsynth-pop Christian Latin\nsynth-pop Christian contemporary\nsynth-pop Christian electronic\nsynth-pop Christian pop\nsynth-pop Christian pop hip-hop\nsynth-pop Christian pop-rock\nsynth-pop Christian rock\nsynth-pop Christian worship\nsynth-pop Christmas\nsynth-pop City Pop\nsynth-pop EBM\nsynth-pop EBM Italo disco\nsynth-pop EBM Italo-disco\nsynth-pop EBM Neue Deutsche Welle\nsynth-pop EBM ambient\nsynth-pop EBM chiptune\nsynth-pop EBM cinematic\nsynth-pop EBM darkwave\nsynth-pop EBM futurepop\nsynth-pop EBM hip-hop\nsynth-pop EBM industrial\nsynth-pop EBM industrial dance\nsynth-pop EBM industrial rock\nsynth-pop EBM new wave\nsynth-pop EBM post-punk\nsynth-pop EBM retro-futuristic\nsynth-pop EBM synthwave\nsynth-pop EBM techno\nsynth-pop EBM trance\nsynth-pop EDM\nsynth-pop EDM Bollywood\nsynth-pop EDM C-pop\nsynth-pop EDM Mandopop\nsynth-pop EDM V-pop\nsynth-pop EDM dance-pop\nsynth-pop EDM future bass\nsynth-pop EDM trance\nsynth-pop Eastern European\nsynth-pop Eastern European new wave\nsynth-pop Eurodance\nsynth-pop European\nsynth-pop European folk\nsynth-pop Finnish hip-hop\nsynth-pop Finnish house\nsynth-pop Finnish schlager\nsynth-pop French\nsynth-pop French R&B\nsynth-pop French chanson\nsynth-pop French cloud rap\nsynth-pop French cold wave\nsynth-pop French coldwave\nsynth-pop French hip-hop\nsynth-pop French house\nsynth-pop French house zouk\nsynth-pop French indie\nsynth-pop French new wave\nsynth-pop French pop\nsynth-pop French pop-rap\nsynth-pop French pop-rock\nsynth-pop French rap\nsynth-pop French touch\nsynth-pop French-pop\nsynth-pop German cloud rap\nsynth-pop German hip-hop\nsynth-pop German indie-pop\nsynth-pop German pop-rap\nsynth-pop German pop-rock\nsynth-pop Greek\nsynth-pop Greek folk\nsynth-pop Halloween\nsynth-pop Indian\nsynth-pop Indian Christian\nsynth-pop Indian devotional\nsynth-pop Indian film\nsynth-pop Indian film music\nsynth-pop Indian filmi\nsynth-pop Indian folk\nsynth-pop Indian fusion\nsynth-pop Indian influence\nsynth-pop Indian pop\nsynth-pop Indian pop rock\nsynth-pop Islamic devotional\nsynth-pop Italo disco\nsynth-pop Italo-disco\nsynth-pop J-Pop\nsynth-pop J-Pop anime\nsynth-pop J-pop\nsynth-pop J-pop C-pop\nsynth-pop J-pop EDM\nsynth-pop J-pop Eurobeat\nsynth-pop J-pop Eurodance\nsynth-pop J-pop K-pop\nsynth-pop J-pop anime\nsynth-pop J-pop children's\nsynth-pop J-pop chiptune\nsynth-pop J-pop cinematic\nsynth-pop J-pop city pop\nsynth-pop J-pop future bass\nsynth-pop J-pop hip-hop\nsynth-pop J-pop hyperpop\nsynth-pop J-pop trance\nsynth-pop J-pop video game\nsynth-pop J-rock\nsynth-pop J-rock anime\nsynth-pop J-rock chiptune\nsynth-pop J-rock cinematic\nsynth-pop JRPG\nsynth-pop Javanese Dangdut Koplo\nsynth-pop Javanese pop\nsynth-pop K-Pop\nsynth-pop K-R&B\nsynth-pop K-hip-hop\nsynth-pop K-pop\nsynth-pop K-pop C-pop\nsynth-pop K-pop EDM\nsynth-pop K-pop Eurodance\nsynth-pop K-pop J-pop\nsynth-pop K-pop J-rock\nsynth-pop K-pop R&B\nsynth-pop K-pop alternative rock\nsynth-pop K-pop ballad\nsynth-pop K-pop chiptune\nsynth-pop K-pop city pop\nsynth-pop K-pop city-pop\nsynth-pop K-pop electronic rock\nsynth-pop K-pop funk\nsynth-pop K-pop future bass\nsynth-pop K-pop hip-hop\nsynth-pop K-pop nu-disco\nsynth-pop K-pop rock\nsynth-pop K-pop trance\nsynth-pop K-pop trot\nsynth-pop K-trot\nsynth-pop Latin\nsynth-pop Latin 80s\nsynth-pop Latin Christian\nsynth-pop Latin Christian children's music\nsynth-pop Latin Christian worship\nsynth-pop Latin Christmas\nsynth-pop Latin R&B\nsynth-pop Latin R&B reggaeton\nsynth-pop Latin R&B trap\nsynth-pop Latin alternative\nsynth-pop Latin ballad\nsynth-pop Latin dance\nsynth-pop Latin dancehall\nsynth-pop Latin disco\nsynth-pop Latin groove\nsynth-pop Latin new wave\nsynth-pop Latin novelty\nsynth-pop Latin pop\nsynth-pop Latin pop EDM\nsynth-pop Latin pop R&B\nsynth-pop Latin pop children's music\nsynth-pop Latin pop funk\nsynth-pop Latin pop hip-hop\nsynth-pop Latin pop reggaeton\nsynth-pop Latin pop trap\nsynth-pop Latin rock\nsynth-pop Latin tropical\nsynth-pop Latin urban\nsynth-pop Latin-pop\nsynth-pop MPB\nsynth-pop Mandopop\nsynth-pop Mandopop EDM\nsynth-pop Mandopop Eurodance\nsynth-pop Mandopop J-pop\nsynth-pop Mandopop R&B\nsynth-pop Mandopop dance-pop\nsynth-pop Mandopop dream pop\nsynth-pop Mandopop electronic rock\nsynth-pop Mandopop hip-hop\nsynth-pop Mandopop rock\nsynth-pop Mediterranean\nsynth-pop Mongolian folk\nsynth-pop Mongolian pop\nsynth-pop Nederpop\nsynth-pop Neue Deutsche Welle\nsynth-pop OPM\nsynth-pop Persian\nsynth-pop Persian pop\nsynth-pop Punjabi pop\nsynth-pop R&B\nsynth-pop R&B 80s\nsynth-pop R&B Afrobeat\nsynth-pop R&B Asian fusion\nsynth-pop R&B Brazilian pop\nsynth-pop R&B C-pop\nsynth-pop R&B Christmas\nsynth-pop R&B EDM\nsynth-pop R&B Indian film music\nsynth-pop R&B Kizomba\nsynth-pop R&B Latin pop\nsynth-pop R&B Mandopop\nsynth-pop R&B ballad\nsynth-pop R&B chillwave\nsynth-pop R&B chiptune\nsynth-pop R&B cinematic\nsynth-pop R&B city pop\nsynth-pop R&B cloud rap\nsynth-pop R&B dance-pop\nsynth-pop R&B dancehall\nsynth-pop R&B dream pop\nsynth-pop R&B dreamy\nsynth-pop R&B early 2000s\nsynth-pop R&B funk\nsynth-pop R&B future bass\nsynth-pop R&B gospel\nsynth-pop R&B hip-hop\nsynth-pop R&B jazz fusion\nsynth-pop R&B lo-fi\nsynth-pop R&B lo-fi hip-hop\nsynth-pop R&B new jack swing\nsynth-pop R&B nu-disco\nsynth-pop R&B parody\nsynth-pop R&B power ballad\nsynth-pop R&B retro-futuristic\nsynth-pop R&B smooth jazz\nsynth-pop R&B soul\nsynth-pop R&B synthwave\nsynth-pop R&B trap\nsynth-pop R&B tropical house\nsynth-pop R&B vaporwave\nsynth-pop R&B world music\nsynth-pop Russian chanson\nsynth-pop Russian estrada\nsynth-pop Russian new wave\nsynth-pop Russian pop\nsynth-pop Russian post-punk\nsynth-pop Scandinavian\nsynth-pop Soviet\nsynth-pop Soviet new wave\nsynth-pop Soviet-era\nsynth-pop Soviet-wave\nsynth-pop Sovietwave\nsynth-pop Sovietwave Italo-disco\nsynth-pop T-Pop city pop\nsynth-pop T-pop\nsynth-pop T-pop J-pop\nsynth-pop T-pop city pop\nsynth-pop Tamil film\nsynth-pop Tamil pop\nsynth-pop Tibetan influence\nsynth-pop Turkish pop\nsynth-pop UK hip-hop\nsynth-pop V-Pop\nsynth-pop V-Pop chiptune\nsynth-pop V-Pop city pop\nsynth-pop V-Pop future bass\nsynth-pop V-Pop hip-hop\nsynth-pop V-Pop vaporwave\nsynth-pop V-pop\nsynth-pop V-pop EDM\nsynth-pop V-pop Eurodance\nsynth-pop V-pop Latin house\nsynth-pop V-pop R&B\nsynth-pop V-pop chiptune\nsynth-pop V-pop city pop\nsynth-pop V-pop electro-pop\nsynth-pop V-pop future bass\nsynth-pop V-pop synthwave\nsynth-pop adult contemporary\nsynth-pop afro\nsynth-pop afro-choral\nsynth-pop afrobeat\nsynth-pop afrobeat dancehall\nsynth-pop afrobeats\nsynth-pop afrobeats dancehall\nsynth-pop afrobeats r&b\nsynth-pop afrobeats tropical house\nsynth-pop afropop\nsynth-pop alt-rock\nsynth-pop alternative R&B\nsynth-pop alternative dance\nsynth-pop alternative electronic\nsynth-pop alternative hip-hop\nsynth-pop alternative metal\nsynth-pop alternative pop\nsynth-pop alternative pop-rock\nsynth-pop alternative rock\nsynth-pop alternative rock ambient\nsynth-pop alternative rock chiptune\nsynth-pop alternative rock dream pop\nsynth-pop alternative rock funk\nsynth-pop alternative rock hip-hop\nsynth-pop alternative rock metalcore\nsynth-pop alternative rock shoegaze\nsynth-pop ambient\nsynth-pop ambient R&B\nsynth-pop ambient pop\nsynth-pop anime\nsynth-pop anime C-pop\nsynth-pop anime opening\nsynth-pop anime rock\nsynth-pop anime soundtrack\nsynth-pop anime theme\nsynth-pop arena rock\nsynth-pop art pop\nsynth-pop art pop funk\nsynth-pop art rock\nsynth-pop art-pop lounge\nsynth-pop art-pop new wave\nsynth-pop art-rock\nsynth-pop baile funk\nsynth-pop ballad\nsynth-pop baroque\nsynth-pop bedroom pop\nsynth-pop bedroom pop chiptune\nsynth-pop bhajan\nsynth-pop bhangra\nsynth-pop big band\nsynth-pop big beat\nsynth-pop bitpop\nsynth-pop bluegrass\nsynth-pop bolero\nsynth-pop boogie\nsynth-pop bossa nova\nsynth-pop breakbeat\nsynth-pop breakcore\nsynth-pop brega\nsynth-pop brostep\nsynth-pop bubblegum\nsynth-pop bubblegum dance\nsynth-pop bubblegum pop\nsynth-pop cabaret\nsynth-pop cantopop\nsynth-pop cantopop city pop\nsynth-pop cantopop hip-hop\nsynth-pop cantopop j-pop\nsynth-pop cantopop j-rock\nsynth-pop cantopop mandopop\nsynth-pop cantopop rock\nsynth-pop celtic folk\nsynth-pop chanson\nsynth-pop children's\nsynth-pop children's 80s\nsynth-pop children's C-pop\nsynth-pop children's Christian\nsynth-pop children's Eurodance\nsynth-pop children's Halloween\nsynth-pop children's J-pop\nsynth-pop children's K-pop\nsynth-pop children's disco\nsynth-pop children's education\nsynth-pop children's game music\nsynth-pop children's holiday\nsynth-pop children's hymn\nsynth-pop children's music\nsynth-pop children's novelty\nsynth-pop children's pop\nsynth-pop children's praise\nsynth-pop children's worship\nsynth-pop chillwave\nsynth-pop chillwave C-pop\nsynth-pop chillwave Cantopop\nsynth-pop chillwave R&B\nsynth-pop chillwave ambient\nsynth-pop chillwave lo-fi hip-hop\nsynth-pop chillwave vaporwave\nsynth-pop chiptune\nsynth-pop chiptune 2000s dance-pop\nsynth-pop chiptune 8-bit\nsynth-pop chiptune 80s\nsynth-pop chiptune 80s anime\nsynth-pop chiptune 80s new wave\nsynth-pop chiptune 80s retro-futuristic\nsynth-pop chiptune 90s dance-pop\nsynth-pop chiptune Afropop\nsynth-pop chiptune Arabic\nsynth-pop chiptune Arabic children's\nsynth-pop chiptune Arabic pop\nsynth-pop chiptune Bollywood\nsynth-pop chiptune Brazilian\nsynth-pop chiptune Brazilian funk\nsynth-pop chiptune Brazilian pop\nsynth-pop chiptune C-pop\nsynth-pop chiptune Cantopop\nsynth-pop chiptune Central Asian\nsynth-pop chiptune Central Asian pop\nsynth-pop chiptune Christian\nsynth-pop chiptune Christian contemporary\nsynth-pop chiptune Christian pop\nsynth-pop chiptune Christmas\nsynth-pop chiptune EBM\nsynth-pop chiptune East African\nsynth-pop chiptune Eastern European\nsynth-pop chiptune Eastern European folk\nsynth-pop chiptune Eastern European new wave\nsynth-pop chiptune Eastern European pop\nsynth-pop chiptune Filipino pop\nsynth-pop chiptune French\nsynth-pop chiptune French pop\nsynth-pop chiptune German cloud rap\nsynth-pop chiptune Indian\nsynth-pop chiptune Indian devotional\nsynth-pop chiptune Indian film music\nsynth-pop chiptune Indian folk\nsynth-pop chiptune Indian folk-pop\nsynth-pop chiptune Indian pop\nsynth-pop chiptune Indonesian pop\nsynth-pop chiptune Italo disco\nsynth-pop chiptune Italo-disco\nsynth-pop chiptune J-RPG\nsynth-pop chiptune J-core\nsynth-pop chiptune J-pop\nsynth-pop chiptune J-rock\nsynth-pop chiptune JRPG\nsynth-pop chiptune K-pop\nsynth-pop chiptune Latin\nsynth-pop chiptune Latin Christian\nsynth-pop chiptune Latin pop\nsynth-pop chiptune MPB\nsynth-pop chiptune Mandopop\nsynth-pop chiptune Middle Eastern\nsynth-pop chiptune NDW\nsynth-pop chiptune Nederpop\nsynth-pop chiptune Neue Deutsche Welle\nsynth-pop chiptune North African\nsynth-pop chiptune North African pop\nsynth-pop chiptune Persian pop\nsynth-pop chiptune Punjabi pop\nsynth-pop chiptune R&B\nsynth-pop chiptune Russian estrada\nsynth-pop chiptune Russian folk\nsynth-pop chiptune Russian post-punk\nsynth-pop chiptune Scandinavian\nsynth-pop chiptune Soviet\nsynth-pop chiptune Soviet new wave\nsynth-pop chiptune Soviet pop\nsynth-pop chiptune Tamil children's\nsynth-pop chiptune Tamil pop\nsynth-pop chiptune Thai pop\nsynth-pop chiptune Turkish\nsynth-pop chiptune Turkish new wave\nsynth-pop chiptune Turkish pop\nsynth-pop chiptune V-pop\nsynth-pop chiptune afrobeats\nsynth-pop chiptune ambient\nsynth-pop chiptune anime\nsynth-pop chiptune art rock\nsynth-pop chiptune art-pop\nsynth-pop chiptune baroque\nsynth-pop chiptune bedroom pop\nsynth-pop chiptune bitpop\nsynth-pop chiptune breakcore\nsynth-pop chiptune brega\nsynth-pop chiptune bubblegum pop\nsynth-pop chiptune cabaret\nsynth-pop chiptune children's\nsynth-pop chiptune children's music\nsynth-pop chiptune children's pop\nsynth-pop chiptune cinematic\nsynth-pop chiptune circus\nsynth-pop chiptune city pop\nsynth-pop chiptune city-pop\nsynth-pop chiptune classical\nsynth-pop chiptune comedy rock\nsynth-pop chiptune complextro\nsynth-pop chiptune cumbia\nsynth-pop chiptune cyberpunk\nsynth-pop chiptune dance-pop\nsynth-pop chiptune dance-rock\nsynth-pop chiptune dancehall\nsynth-pop chiptune darkwave\nsynth-pop chiptune disco\nsynth-pop chiptune disco polo\nsynth-pop chiptune dramatic rock\nsynth-pop chiptune dream pop\nsynth-pop chiptune dream-pop\nsynth-pop chiptune drum and bass\nsynth-pop chiptune early 2000s\nsynth-pop chiptune eastern european new wave\nsynth-pop chiptune educational\nsynth-pop chiptune educational pop\nsynth-pop chiptune electro\nsynth-pop chiptune electro-funk\nsynth-pop chiptune electro-house\nsynth-pop chiptune electro-pop\nsynth-pop chiptune electro-rock\nsynth-pop chiptune electroclash\nsynth-pop chiptune electropop\nsynth-pop chiptune emo\nsynth-pop chiptune emo-pop\nsynth-pop chiptune emo-rap\nsynth-pop chiptune eurodance\nsynth-pop chiptune experimental\nsynth-pop chiptune fairytale\nsynth-pop chiptune fantasy\nsynth-pop chiptune festive\nsynth-pop chiptune finnish schlager\nsynth-pop chiptune folk\nsynth-pop chiptune forró\nsynth-pop chiptune french house\nsynth-pop chiptune french new wave\nsynth-pop chiptune funk\nsynth-pop chiptune future bass\nsynth-pop chiptune gaming\nsynth-pop chiptune glitch\nsynth-pop chiptune gospel\nsynth-pop chiptune gufeng\nsynth-pop chiptune happy hardcore\nsynth-pop chiptune hardbass\nsynth-pop chiptune hip-hop\nsynth-pop chiptune horror\nsynth-pop chiptune hyper-pop\nsynth-pop chiptune hyperpop\nsynth-pop chiptune indie dance\nsynth-pop chiptune indie pop\nsynth-pop chiptune indie rock\nsynth-pop chiptune indie-pop\nsynth-pop chiptune industrial\nsynth-pop chiptune industrial rock\nsynth-pop chiptune italo disco\nsynth-pop chiptune italo-disco\nsynth-pop chiptune j-core\nsynth-pop chiptune j-pop\nsynth-pop chiptune j-rock\nsynth-pop chiptune k-pop\nsynth-pop chiptune kawaii\nsynth-pop chiptune kids\nsynth-pop chiptune klezmer\nsynth-pop chiptune latin pop\nsynth-pop chiptune lo-fi\nsynth-pop chiptune lo-fi C-pop\nsynth-pop chiptune lounge\nsynth-pop chiptune melancholic\nsynth-pop chiptune meme\nsynth-pop chiptune metalcore\nsynth-pop chiptune musical theater\nsynth-pop chiptune new jack swing\nsynth-pop chiptune new wave\nsynth-pop chiptune nintendocore\nsynth-pop chiptune nostalgic\nsynth-pop chiptune novelty\nsynth-pop chiptune nu-disco\nsynth-pop chiptune orchestral\nsynth-pop chiptune polka\nsynth-pop chiptune pop-punk\nsynth-pop chiptune pop-rock\nsynth-pop chiptune post-punk\nsynth-pop chiptune post-rock\nsynth-pop chiptune power metal\nsynth-pop chiptune power-pop\nsynth-pop chiptune protest\nsynth-pop chiptune psychedelic\nsynth-pop chiptune rap\nsynth-pop chiptune reggae\nsynth-pop chiptune reggaeton\nsynth-pop chiptune retro\nsynth-pop chiptune retro-futuristic\nsynth-pop chiptune retro-wave\nsynth-pop chiptune retrowave\nsynth-pop chiptune rock\nsynth-pop chiptune schlager\nsynth-pop chiptune ska\nsynth-pop chiptune soviet pop\nsynth-pop chiptune soviet-wave\nsynth-pop chiptune synthwave\nsynth-pop chiptune techno\nsynth-pop chiptune theatrical\nsynth-pop chiptune trance\nsynth-pop chiptune trap\nsynth-pop chiptune tropical\nsynth-pop chiptune uk garage\nsynth-pop chiptune vaporwave\nsynth-pop chiptune video game\nsynth-pop chiptune video game music\nsynth-pop chiptune world music\nsynth-pop chiptune worldbeat\nsynth-pop chiptune worship\nsynth-pop chiptune zouk\nsynth-pop christian pop-rock\nsynth-pop christian rock\nsynth-pop cinematic\nsynth-pop cinematic electronic\nsynth-pop cinematic pop\nsynth-pop cinematic rock\nsynth-pop cinematic sci-fi\nsynth-pop city pop\nsynth-pop city pop 80s retro-futuristic\nsynth-pop city pop C-pop\nsynth-pop city pop J-pop\nsynth-pop city pop K-pop\nsynth-pop city pop Mandopop\nsynth-pop city pop R&B\nsynth-pop city pop anime\nsynth-pop city pop cantopop\nsynth-pop city pop chiptune\nsynth-pop city pop disco\nsynth-pop city pop eurobeat\nsynth-pop city pop funk\nsynth-pop city pop future funk\nsynth-pop city pop hip-hop\nsynth-pop city pop hyperpop\nsynth-pop city pop j-pop\nsynth-pop city pop jazz fusion\nsynth-pop city pop k-pop\nsynth-pop city pop lo-fi hip-hop\nsynth-pop city pop lounge\nsynth-pop city pop mandopop\nsynth-pop city pop neo-soul\nsynth-pop city pop new jack swing\nsynth-pop city pop nu-disco\nsynth-pop city pop smooth jazz\nsynth-pop city pop synth-funk\nsynth-pop city pop synthwave\nsynth-pop city pop v-pop\nsynth-pop city pop vaporwave\nsynth-pop city-pop\nsynth-pop city-pop EDM\nsynth-pop city-pop J-pop\nsynth-pop city-pop K-pop\nsynth-pop city-pop R&B\nsynth-pop city-pop anime\nsynth-pop city-pop chiptune\nsynth-pop city-pop future funk\nsynth-pop city-pop vaporwave\nsynth-pop classical\nsynth-pop classical J-pop\nsynth-pop classical fusion\nsynth-pop cloud rap\nsynth-pop cloud rap R&B\nsynth-pop cloud rap emo rap\nsynth-pop cloud rap hyperpop\nsynth-pop cloud rap vaporwave\nsynth-pop coldwave\nsynth-pop coldwave EBM\nsynth-pop coldwave dream pop\nsynth-pop coldwave hyperpop\nsynth-pop coldwave post-punk\nsynth-pop coldwave trance\nsynth-pop colindă\nsynth-pop comedy\nsynth-pop complextro\nsynth-pop complextro chiptune\nsynth-pop conscious hip-hop\nsynth-pop cosmic\nsynth-pop country\nsynth-pop country-folk\nsynth-pop country-pop\nsynth-pop country-rock\nsynth-pop cumbia\nsynth-pop cumbia Latin\nsynth-pop cumbia children's\nsynth-pop cumbia chiptune\nsynth-pop cumbia latin\nsynth-pop cumbia salsa\nsynth-pop cumbia tropical\nsynth-pop cumbia-pop\nsynth-pop cyber-pop\nsynth-pop cyberpunk\nsynth-pop cyberpunk J-pop\nsynth-pop cyberpunk chiptune\nsynth-pop cyberpunk city-pop\nsynth-pop cyberpunk darkwave\nsynth-pop cyberpunk dream-pop\nsynth-pop cyberpunk glitch-hop\nsynth-pop cyberpunk j-rock\nsynth-pop cyberpunk trance\nsynth-pop dance\nsynth-pop dance-pop\nsynth-pop dance-pop R&B\nsynth-pop dance-rock\nsynth-pop dancehall\nsynth-pop dancehall reggae\nsynth-pop dancehall reggaeton\nsynth-pop dancehall-reggae\nsynth-pop dangdut koplo\nsynth-pop dark\nsynth-pop dark pop\nsynth-pop dark pop electro-rock\nsynth-pop dark wave\nsynth-pop dark wave EBM\nsynth-pop darkwave\nsynth-pop darkwave 80s new wave\nsynth-pop darkwave 80s retro\nsynth-pop darkwave 80s retro-futuristic\nsynth-pop darkwave EBM\nsynth-pop darkwave French coldwave\nsynth-pop darkwave French rap\nsynth-pop darkwave German rock\nsynth-pop darkwave Russian pop\nsynth-pop darkwave Russian post-punk\nsynth-pop darkwave Turkish hip-hop\nsynth-pop darkwave Turkish pop\nsynth-pop darkwave ambient\nsynth-pop darkwave balkan pop\nsynth-pop darkwave chanson\nsynth-pop darkwave chiptune\nsynth-pop darkwave coldwave\nsynth-pop darkwave cyberpunk\nsynth-pop darkwave dance-pop\nsynth-pop darkwave dream pop\nsynth-pop darkwave electro-punk\nsynth-pop darkwave electro-rock\nsynth-pop darkwave electroclash\nsynth-pop darkwave electronic rock\nsynth-pop darkwave eurodance\nsynth-pop darkwave gothic\nsynth-pop darkwave gothic rock\nsynth-pop darkwave hyperpop\nsynth-pop darkwave industrial\nsynth-pop darkwave industrial rock\nsynth-pop darkwave italo-disco\nsynth-pop darkwave new wave\nsynth-pop darkwave nu-disco\nsynth-pop darkwave post-punk\nsynth-pop darkwave rap\nsynth-pop darkwave retro-wave\nsynth-pop darkwave retrowave\nsynth-pop darkwave russian post-punk\nsynth-pop darkwave shoegaze\nsynth-pop darkwave synth-rock\nsynth-pop darkwave synthwave\nsynth-pop darkwave trance\nsynth-pop darkwave trap\nsynth-pop darkwave trip-hop\nsynth-pop deep house\nsynth-pop devotional\nsynth-pop disco\nsynth-pop disco funk\nsynth-pop disco polo\nsynth-pop disco-funk\nsynth-pop downtempo\nsynth-pop dream pop\nsynth-pop dream pop C-pop\nsynth-pop dream pop alternative rock\nsynth-pop dream pop chillwave\nsynth-pop dream pop hyperpop\nsynth-pop dream pop indie rock\nsynth-pop dream pop lo-fi hip-hop\nsynth-pop dream pop post-rock\nsynth-pop dream pop psychedelic rock\nsynth-pop dream pop shoegaze\nsynth-pop dream pop synthwave\nsynth-pop dream pop vaporwave\nsynth-pop dream-pop\nsynth-pop dream-pop chillwave\nsynth-pop dream-pop chiptune\nsynth-pop dream-pop cinematic\nsynth-pop dream-pop darkwave\nsynth-pop dream-pop italo-disco\nsynth-pop dream-pop new wave\nsynth-pop dream-pop post-punk\nsynth-pop dream-pop shoegaze\nsynth-pop dream-pop synthwave\nsynth-pop dream-pop vaporwave\nsynth-pop dreamwave\nsynth-pop dreamy\nsynth-pop drum and bass\nsynth-pop drum and bass electronic rock\nsynth-pop dubstep\nsynth-pop dystopian\nsynth-pop ebm\nsynth-pop ebm chiptune\nsynth-pop ebm industrial\nsynth-pop ebm new wave\nsynth-pop education\nsynth-pop electro\nsynth-pop electro 80s\nsynth-pop electro chiptune\nsynth-pop electro dance-pop\nsynth-pop electro darkwave\nsynth-pop electro future bass\nsynth-pop electro hip-hop\nsynth-pop electro house\nsynth-pop electro hyperpop\nsynth-pop electro synthwave\nsynth-pop electro trance\nsynth-pop electro-funk\nsynth-pop electro-funk future bass\nsynth-pop electro-house\nsynth-pop electro-house chiptune\nsynth-pop electro-industrial\nsynth-pop electro-pop\nsynth-pop electro-pop C-pop\nsynth-pop electro-pop EBM\nsynth-pop electro-pop chiptune\nsynth-pop electro-pop dance\nsynth-pop electro-pop dance-pop\nsynth-pop electro-pop hyperpop\nsynth-pop electro-pop nu-disco\nsynth-pop electro-pop vaporwave\nsynth-pop electro-pop video game music\nsynth-pop electro-punk\nsynth-pop electro-rock\nsynth-pop electro-rock hip-hop\nsynth-pop electro-rock hyperpop\nsynth-pop electro-rock synthwave\nsynth-pop electroclash\nsynth-pop electroclash dance-punk\nsynth-pop electronic\nsynth-pop electronic R&B\nsynth-pop electronic hip-hop\nsynth-pop electronic pop\nsynth-pop electronic rock\nsynth-pop electronic rock chiptune\nsynth-pop electronic rock future bass\nsynth-pop electronic rock trance\nsynth-pop electronic soul\nsynth-pop electronica chiptune\nsynth-pop electronicore\nsynth-pop electropop\nsynth-pop electropop C-pop\nsynth-pop electropop R&B\nsynth-pop electropop chiptune\nsynth-pop electropop cinematic\nsynth-pop electropop dance\nsynth-pop electropop dance-pop\nsynth-pop electropop hyperpop\nsynth-pop electropop indie pop\nsynth-pop electropop pop-punk\nsynth-pop electropop power pop\nsynth-pop electropop power-pop\nsynth-pop electropop vaporwave\nsynth-pop emo\nsynth-pop emo electronic rock\nsynth-pop emo hyperpop\nsynth-pop emo indie rock\nsynth-pop emo pop\nsynth-pop emo pop-punk\nsynth-pop emo rap\nsynth-pop emo rap atmospheric electronic\nsynth-pop emo-pop\nsynth-pop emo-pop chiptune\nsynth-pop emo-pop hip-hop\nsynth-pop emo-pop hyperpop\nsynth-pop emo-pop pop-punk\nsynth-pop emo-rap\nsynth-pop emo-rap C-pop\nsynth-pop emo-rap alternative rock\nsynth-pop emo-rap chiptune\nsynth-pop emo-rap cloud rap\nsynth-pop emo-rap hyperpop\nsynth-pop emo-rap trap\nsynth-pop emo-rock\nsynth-pop emotional dance\nsynth-pop emotional electronic\nsynth-pop emotional pop electronic\nsynth-pop epic\nsynth-pop epic ballad\nsynth-pop epic rock\nsynth-pop estrada\nsynth-pop ethereal\nsynth-pop euro\nsynth-pop euro folk\nsynth-pop euro-disco\nsynth-pop euro-pop\nsynth-pop eurobeat\nsynth-pop eurobeat 90s k-pop\nsynth-pop eurobeat italo-disco\nsynth-pop eurobeat j-pop\nsynth-pop eurodance\nsynth-pop eurodance 90s dance-pop\nsynth-pop eurodance C-pop\nsynth-pop eurodance EBM\nsynth-pop eurodance balkan\nsynth-pop eurodance balkan pop\nsynth-pop eurodance c-pop\nsynth-pop eurodance cantopop\nsynth-pop eurodance chiptune\nsynth-pop eurodance christian pop\nsynth-pop eurodance city pop\nsynth-pop eurodance cumbia\nsynth-pop eurodance darkwave\nsynth-pop eurodance ebm\nsynth-pop eurodance funk\nsynth-pop eurodance happy hardcore\nsynth-pop eurodance hi-nrg\nsynth-pop eurodance hip-hop\nsynth-pop eurodance hyperpop\nsynth-pop eurodance italo disco\nsynth-pop eurodance italo-disco\nsynth-pop eurodance j-pop\nsynth-pop eurodance klezmer\nsynth-pop eurodance latin pop\nsynth-pop eurodance power metal\nsynth-pop eurodance power-pop\nsynth-pop eurodance rock\nsynth-pop eurodance schlager\nsynth-pop eurodance slap house\nsynth-pop eurodance trance\nsynth-pop eurodance turkish pop\nsynth-pop eurodance v-pop\nsynth-pop eurodance worldbeat\nsynth-pop europop\nsynth-pop experimental\nsynth-pop experimental art-pop\nsynth-pop experimental electronic\nsynth-pop fado\nsynth-pop fairytale\nsynth-pop fantasy\nsynth-pop filmi\nsynth-pop finnish schlager\nsynth-pop folk\nsynth-pop folk fusion\nsynth-pop folk-dance\nsynth-pop folk-pop\nsynth-pop forró\nsynth-pop forró eletrônico\nsynth-pop freestyle\nsynth-pop french\nsynth-pop french chanson\nsynth-pop french disco\nsynth-pop french electro\nsynth-pop french hip-hop\nsynth-pop french house\nsynth-pop french new wave\nsynth-pop french pop\nsynth-pop french pop zouk\nsynth-pop french pop-rock\nsynth-pop french rap\nsynth-pop french reggae\nsynth-pop french-pop\nsynth-pop funk\nsynth-pop funk J-pop\nsynth-pop funk R&B\nsynth-pop funk carioca\nsynth-pop funk chiptune\nsynth-pop funk city pop\nsynth-pop funk disco\nsynth-pop funk dream pop\nsynth-pop funk electro-rock\nsynth-pop funk experimental hip-hop\nsynth-pop funk fusion\nsynth-pop funk hip-hop\nsynth-pop funk indie pop\nsynth-pop funk jazz fusion\nsynth-pop funk rock\nsynth-pop funk soul\nsynth-pop funk world music\nsynth-pop funk-pop\nsynth-pop funk-rock\nsynth-pop fusion jazz\nsynth-pop future R&B\nsynth-pop future bass\nsynth-pop future bass C-pop\nsynth-pop future bass EDM\nsynth-pop future bass J-pop\nsynth-pop future bass K-pop\nsynth-pop future bass R&B\nsynth-pop future bass V-pop\nsynth-pop future bass chillwave\nsynth-pop future bass chiptune\nsynth-pop future bass city pop\nsynth-pop future bass deep house\nsynth-pop future bass dream pop\nsynth-pop future bass electro house\nsynth-pop future bass electro-pop\nsynth-pop future bass hardstyle\nsynth-pop future bass hyperpop\nsynth-pop future bass j-pop\nsynth-pop future bass synthwave\nsynth-pop future bass trance\nsynth-pop future bass trap\nsynth-pop future bass vaporwave\nsynth-pop future funk\nsynth-pop future funk city pop\nsynth-pop future funk nu-disco\nsynth-pop future funk vaporwave\nsynth-pop future pop\nsynth-pop future-bass\nsynth-pop future-pop\nsynth-pop futurepop\nsynth-pop futurepop EBM\nsynth-pop futurepop J-pop\nsynth-pop g-funk\nsynth-pop gaming\nsynth-pop garage punk\nsynth-pop german indie rock\nsynth-pop glam metal\nsynth-pop glam rock\nsynth-pop glitch\nsynth-pop glitch-hop\nsynth-pop glitch-pop\nsynth-pop glitch-pop future bass\nsynth-pop gospel\nsynth-pop gospel CCM\nsynth-pop gospel J-pop\nsynth-pop gospel Latin\nsynth-pop gospel R&B\nsynth-pop gospel chiptune\nsynth-pop gospel funk\nsynth-pop gospel rock\nsynth-pop gospel soul\nsynth-pop gospel world music\nsynth-pop gospel-pop\nsynth-pop gothic\nsynth-pop gothic 80s\nsynth-pop gothic baroque\nsynth-pop gothic chiptune\nsynth-pop gothic cinematic\nsynth-pop gothic dream-pop\nsynth-pop gothic rock\nsynth-pop hard rock\nsynth-pop hard trance\nsynth-pop hardstyle\nsynth-pop hardstyle trance\nsynth-pop hi-nrg\nsynth-pop hip-hop\nsynth-pop hip-hop Christian contemporary\nsynth-pop hip-hop EDM\nsynth-pop hip-hop J-pop\nsynth-pop hip-hop R&B\nsynth-pop hip-hop alternative rock\nsynth-pop hip-hop anime\nsynth-pop hip-hop chiptune\nsynth-pop hip-hop cinematic\nsynth-pop hip-hop city pop\nsynth-pop hip-hop electro-pop\nsynth-pop hip-hop electronic rock\nsynth-pop hip-hop hyperpop\nsynth-pop hip-hop industrial\nsynth-pop hip-hop musical theater\nsynth-pop hip-hop pop-punk\nsynth-pop hip-hop rock\nsynth-pop hip-hop synthwave\nsynth-pop hip-hop trap\nsynth-pop hip-hop vaporwave\nsynth-pop hip-hop world music\nsynth-pop holiday\nsynth-pop horror\nsynth-pop horror-dance\nsynth-pop horror-disco\nsynth-pop horror-pop\nsynth-pop house\nsynth-pop house Italo-disco\nsynth-pop house afrobeats\nsynth-pop house chiptune\nsynth-pop hyperpop\nsynth-pop hyperpop C-pop\nsynth-pop hyperpop EBM\nsynth-pop hyperpop J-pop\nsynth-pop hyperpop J-rock\nsynth-pop hyperpop K-pop\nsynth-pop hyperpop art-pop\nsynth-pop hyperpop chiptune\nsynth-pop hyperpop cloud rap\nsynth-pop hyperpop dance-pop\nsynth-pop hyperpop dream pop\nsynth-pop hyperpop drum and bass\nsynth-pop hyperpop electronic rock\nsynth-pop hyperpop emo\nsynth-pop hyperpop emo-pop\nsynth-pop hyperpop emo-rap\nsynth-pop hyperpop eurodance\nsynth-pop hyperpop glitch-pop\nsynth-pop hyperpop hardstyle\nsynth-pop hyperpop j-pop\nsynth-pop hyperpop j-rock\nsynth-pop hyperpop nightcore\nsynth-pop hyperpop pop-punk\nsynth-pop hyperpop shoegaze\nsynth-pop hyperpop trance\nsynth-pop hyperpop trap\nsynth-pop hyperpop uk garage\nsynth-pop idol\nsynth-pop indie\nsynth-pop indie dance\nsynth-pop indie electronic\nsynth-pop indie electronic rock\nsynth-pop indie hyperpop\nsynth-pop indie pop\nsynth-pop indie pop-rock\nsynth-pop indie rock\nsynth-pop indie rock chiptune\nsynth-pop indie rock hyperpop\nsynth-pop indie rock shoegaze\nsynth-pop indie-dance\nsynth-pop indie-electronic\nsynth-pop indie-pop\nsynth-pop indie-rock\nsynth-pop indipop\nsynth-pop industrial\nsynth-pop industrial EBM\nsynth-pop industrial cyberpunk\nsynth-pop industrial darkwave\nsynth-pop industrial dream-pop\nsynth-pop industrial dubstep\nsynth-pop industrial electronic rock\nsynth-pop industrial hyperpop\nsynth-pop industrial metal\nsynth-pop industrial new wave\nsynth-pop industrial noise-rock\nsynth-pop industrial post-punk\nsynth-pop industrial rock\nsynth-pop industrial shoegaze\nsynth-pop industrial synthwave\nsynth-pop industrial trap\nsynth-pop inspirational pop\nsynth-pop instrumental\nsynth-pop instrumental house\nsynth-pop iskelmä\nsynth-pop italo\nsynth-pop italo disco\nsynth-pop italo disco 80s new wave\nsynth-pop italo disco balkan pop\nsynth-pop italo disco bollywood\nsynth-pop italo disco chiptune\nsynth-pop italo disco eastern european pop\nsynth-pop italo disco ebm\nsynth-pop italo disco electro-pop\nsynth-pop italo disco eurobeat\nsynth-pop italo disco eurodance\nsynth-pop italo disco hi-nrg\nsynth-pop italo disco hip-hop\nsynth-pop italo disco new wave\nsynth-pop italo disco nu-disco\nsynth-pop italo disco synthwave\nsynth-pop italo pop\nsynth-pop italo-disco\nsynth-pop italo-disco 80s new wave\nsynth-pop italo-disco 80s retro-futuristic\nsynth-pop italo-disco EBM\nsynth-pop italo-disco afro-pop\nsynth-pop italo-disco afrobeat\nsynth-pop italo-disco arabic pop\nsynth-pop italo-disco balkan pop\nsynth-pop italo-disco bollywood\nsynth-pop italo-disco chiptune\nsynth-pop italo-disco darkwave\nsynth-pop italo-disco dream-pop\nsynth-pop italo-disco ebm\nsynth-pop italo-disco electro-funk\nsynth-pop italo-disco electro-pop\nsynth-pop italo-disco euro-pop\nsynth-pop italo-disco eurobeat\nsynth-pop italo-disco eurodance\nsynth-pop italo-disco french pop\nsynth-pop italo-disco french synth-pop\nsynth-pop italo-disco funk\nsynth-pop italo-disco hi-nrg\nsynth-pop italo-disco hip-hop\nsynth-pop italo-disco house\nsynth-pop italo-disco hyperpop\nsynth-pop italo-disco korean trot\nsynth-pop italo-disco latin pop\nsynth-pop italo-disco ndw\nsynth-pop italo-disco new wave\nsynth-pop italo-disco nu-disco\nsynth-pop italo-disco operatic\nsynth-pop italo-disco power ballad\nsynth-pop italo-disco progressive house\nsynth-pop italo-disco progressive rock\nsynth-pop italo-disco r&b\nsynth-pop italo-disco rap\nsynth-pop italo-disco reggae\nsynth-pop italo-disco schlager\nsynth-pop italo-disco ska\nsynth-pop italo-disco soviet-wave\nsynth-pop italo-disco spanish rock\nsynth-pop italo-disco synthwave\nsynth-pop italo-disco turkish new wave\nsynth-pop j-pop\nsynth-pop j-pop anime\nsynth-pop j-pop artcore\nsynth-pop j-pop c-pop\nsynth-pop j-pop children's\nsynth-pop j-pop chiptune\nsynth-pop j-pop christmas\nsynth-pop j-pop cinematic\nsynth-pop j-pop city pop\nsynth-pop j-pop city-pop\nsynth-pop j-pop electronic rock\nsynth-pop j-pop eurobeat\nsynth-pop j-pop eurodance\nsynth-pop j-pop funk\nsynth-pop j-pop future bass\nsynth-pop j-pop futuristic\nsynth-pop j-pop gospel\nsynth-pop j-pop happy hardcore\nsynth-pop j-pop hip-hop\nsynth-pop j-pop hyperpop\nsynth-pop j-pop k-pop\nsynth-pop j-pop lo-fi\nsynth-pop j-pop musical theater\nsynth-pop j-pop retro-futuristic\nsynth-pop j-pop synthwave\nsynth-pop j-pop trance\nsynth-pop j-pop video game\nsynth-pop j-rock\nsynth-pop j-rock anime\nsynth-pop j-rock chiptune\nsynth-pop j-rock eurodance\nsynth-pop j-rock video game\nsynth-pop jazz\nsynth-pop jazz fusion\nsynth-pop k-pop\nsynth-pop k-pop children's\nsynth-pop k-pop city pop\nsynth-pop k-pop trot\nsynth-pop kawaii\nsynth-pop kawaii J-pop\nsynth-pop kawaii anime\nsynth-pop kawaii chiptune\nsynth-pop kawaii future bass\nsynth-pop kawaii future bass chiptune\nsynth-pop kids\nsynth-pop kids' fitness\nsynth-pop kizomba\nsynth-pop korean trot\nsynth-pop latin\nsynth-pop latin alternative\nsynth-pop latin dance\nsynth-pop latin dance-pop\nsynth-pop latin disco\nsynth-pop latin freestyle\nsynth-pop latin mambo\nsynth-pop latin new wave\nsynth-pop latin pop\nsynth-pop latin pop chiptune\nsynth-pop latin pop eurodance\nsynth-pop latin pop hip-hop\nsynth-pop latin pop new wave\nsynth-pop latin pop nu-disco\nsynth-pop latin pop r&b\nsynth-pop latin pop reggaeton\nsynth-pop latin pop rock\nsynth-pop latin pop vaporwave\nsynth-pop latin pop-rock\nsynth-pop latin r&b\nsynth-pop latin rock\nsynth-pop latin trap r&b\nsynth-pop latin trap vaporwave\nsynth-pop latin-pop\nsynth-pop laïko\nsynth-pop lo-fi\nsynth-pop lo-fi C-pop\nsynth-pop lo-fi J-pop\nsynth-pop lo-fi R&B\nsynth-pop lo-fi bedroom pop\nsynth-pop lo-fi chillwave\nsynth-pop lo-fi chiptune\nsynth-pop lo-fi city pop\nsynth-pop lo-fi dream pop\nsynth-pop lo-fi dreamy\nsynth-pop lo-fi future bass\nsynth-pop lo-fi hip hop\nsynth-pop lo-fi hip-hop\nsynth-pop lo-fi hip-hop C-pop\nsynth-pop lo-fi hip-hop R&B\nsynth-pop lo-fi hip-hop bedroom pop\nsynth-pop lo-fi hip-hop chillwave\nsynth-pop lo-fi hip-hop city pop\nsynth-pop lo-fi hip-hop vaporwave\nsynth-pop lo-fi k-pop\nsynth-pop lo-fi pop\nsynth-pop lo-fi shoegaze\nsynth-pop lo-fi trap\nsynth-pop lo-fi vaporwave\nsynth-pop lounge\nsynth-pop lounge exotica\nsynth-pop lovers rock\nsynth-pop lullaby\nsynth-pop mandopop\nsynth-pop mandopop chiptune\nsynth-pop mandopop dream pop\nsynth-pop mandopop edm\nsynth-pop mandopop hip-hop\nsynth-pop mandopop j-pop\nsynth-pop mandopop r&b\nsynth-pop mandopop trap\nsynth-pop mandopop world music\nsynth-pop melancholic\nsynth-pop meme\nsynth-pop metal\nsynth-pop metalcore\nsynth-pop moombahton dancehall\nsynth-pop musical theater\nsynth-pop neo-classical\nsynth-pop neo-soul\nsynth-pop neo-soul chillwave\nsynth-pop neo-soul lounge\nsynth-pop neoclassical\nsynth-pop new age\nsynth-pop new age world music\nsynth-pop new jack swing\nsynth-pop new jack swing Christian pop\nsynth-pop new jack swing K-pop\nsynth-pop new jack swing R&B\nsynth-pop new jack swing city pop\nsynth-pop new jack swing dancehall\nsynth-pop new jack swing freestyle\nsynth-pop new jack swing gospel\nsynth-pop new jack swing hip-house\nsynth-pop new jack swing k-pop\nsynth-pop new jack swing latin pop\nsynth-pop new wave\nsynth-pop new wave afro-pop\nsynth-pop new wave alternative rock\nsynth-pop new wave art rock\nsynth-pop new wave art-pop\nsynth-pop new wave cabaret\nsynth-pop new wave chiptune\nsynth-pop new wave cinematic\nsynth-pop new wave city pop\nsynth-pop new wave cumbia\nsynth-pop new wave disco\nsynth-pop new wave dream pop\nsynth-pop new wave funk\nsynth-pop new wave funk-rock\nsynth-pop new wave hip-hop\nsynth-pop new wave house\nsynth-pop new wave indie dance\nsynth-pop new wave indie rock\nsynth-pop new wave italo-disco\nsynth-pop new wave latin rock\nsynth-pop new wave pop-punk\nsynth-pop new wave post-punk\nsynth-pop new wave power pop\nsynth-pop new wave power-pop\nsynth-pop new wave punk\nsynth-pop new wave punk rock\nsynth-pop new wave rock\nsynth-pop new wave rockabilly\nsynth-pop new wave ska\nsynth-pop new wave surf rock\nsynth-pop new wave synth-funk\nsynth-pop new wave synthwave\nsynth-pop new wave theatrical\nsynth-pop new wave tropical\nsynth-pop new wave vaporwave\nsynth-pop new wave worldbeat\nsynth-pop new-age\nsynth-pop new-age world music\nsynth-pop noir\nsynth-pop noise rock\nsynth-pop noise-rock\nsynth-pop novelty\nsynth-pop novelty hip-hop\nsynth-pop nu-disco\nsynth-pop nu-disco 80s retro\nsynth-pop nu-disco 80s retro-futuristic\nsynth-pop nu-disco 80s revival\nsynth-pop nu-disco French house\nsynth-pop nu-disco Italo-disco\nsynth-pop nu-disco Latin\nsynth-pop nu-disco R&B\nsynth-pop nu-disco Russian post-punk\nsynth-pop nu-disco Turkish pop\nsynth-pop nu-disco V-pop\nsynth-pop nu-disco chillwave\nsynth-pop nu-disco chiptune\nsynth-pop nu-disco city pop\nsynth-pop nu-disco city-pop\nsynth-pop nu-disco darkwave\nsynth-pop nu-disco deep house\nsynth-pop nu-disco dream pop\nsynth-pop nu-disco electro-funk\nsynth-pop nu-disco electropop\nsynth-pop nu-disco funk\nsynth-pop nu-disco gospel\nsynth-pop nu-disco house\nsynth-pop nu-disco indie dance\nsynth-pop nu-disco italo-disco\nsynth-pop nu-disco lounge\nsynth-pop nu-disco retro-futuristic\nsynth-pop nu-disco synth-funk\nsynth-pop nu-disco synthwave\nsynth-pop nu-disco tropical house\nsynth-pop nu-disco vaporwave\nsynth-pop nu-metal\nsynth-pop nu-metal rap-rock\nsynth-pop opera\nsynth-pop orchestral\nsynth-pop piano ballad\nsynth-pop pimba\nsynth-pop pirate\nsynth-pop polka\nsynth-pop polka surf rock\nsynth-pop pop-punk\nsynth-pop pop-punk J-rock\nsynth-pop pop-punk metalcore\nsynth-pop pop-rock\nsynth-pop post-disco\nsynth-pop post-hardcore\nsynth-pop post-punk\nsynth-pop post-punk alternative rock\nsynth-pop post-punk chiptune\nsynth-pop post-punk coldwave\nsynth-pop post-punk darkwave\nsynth-pop post-punk dream pop\nsynth-pop post-punk new wave\nsynth-pop post-punk revival\nsynth-pop post-punk shoegaze\nsynth-pop post-rock\nsynth-pop power ballad\nsynth-pop power metal\nsynth-pop power pop\nsynth-pop power-pop\nsynth-pop power-pop arena rock\nsynth-pop power-pop chiptune\nsynth-pop power-pop pop-punk\nsynth-pop power-pop pop-rock\nsynth-pop power-pop rock\nsynth-pop power-rock\nsynth-pop praise\nsynth-pop progressive house\nsynth-pop progressive house dream pop\nsynth-pop progressive house trance\nsynth-pop progressive house trap\nsynth-pop progressive rock\nsynth-pop progressive trance\nsynth-pop protest\nsynth-pop psychedelic\nsynth-pop psychedelic funk\nsynth-pop psychedelic rock\nsynth-pop punk\nsynth-pop punk rock\nsynth-pop r&b chillwave\nsynth-pop rap\nsynth-pop reggae\nsynth-pop reggae dancehall\nsynth-pop reggae fusion\nsynth-pop reggae new wave\nsynth-pop reggae ska\nsynth-pop reggae-dancehall\nsynth-pop reggaeton\nsynth-pop reggaeton Latin pop\nsynth-pop reggaeton chiptune\nsynth-pop reggaeton dancehall\nsynth-pop reggaeton latin pop\nsynth-pop retro\nsynth-pop retro 80s\nsynth-pop retro C-pop chiptune\nsynth-pop retro Soviet\nsynth-pop retro dance-pop\nsynth-pop retro disco\nsynth-pop retro funk\nsynth-pop retro summer\nsynth-pop retro tropical\nsynth-pop retro video game\nsynth-pop retro-funk\nsynth-pop retro-funk trot\nsynth-pop retro-futuristic\nsynth-pop retro-futuristic worldbeat\nsynth-pop retro-wave\nsynth-pop retro-wave chiptune\nsynth-pop retrowave\nsynth-pop retrowave 80s\nsynth-pop retrowave J-pop\nsynth-pop retrowave chiptune\nsynth-pop retrowave cyberpunk\nsynth-pop retrowave dream pop\nsynth-pop retrowave synthwave\nsynth-pop retrowave vaporwave\nsynth-pop rock\nsynth-pop rock ballad\nsynth-pop rock chiptune\nsynth-pop rock fusion\nsynth-pop rock hip-hop\nsynth-pop rock opera\nsynth-pop romantic C-pop\nsynth-pop satire\nsynth-pop schlager\nsynth-pop sci-fi\nsynth-pop sea shanty\nsynth-pop shoegaze\nsynth-pop shoegaze alternative rock\nsynth-pop shoegaze ambient\nsynth-pop shoegaze dream pop\nsynth-pop shoegaze funk\nsynth-pop showtune\nsynth-pop ska\nsynth-pop smooth jazz\nsynth-pop sophisti-pop\nsynth-pop soul\nsynth-pop soul ballad\nsynth-pop sovietwave\nsynth-pop space rock\nsynth-pop space-rock\nsynth-pop stadium rock\nsynth-pop surf-rock\nsynth-pop swedish schlager\nsynth-pop synthwave\nsynth-pop tango\nsynth-pop tango retro-futuristic\nsynth-pop tech-house\nsynth-pop techno\nsynth-pop theatrical\nsynth-pop trance\nsynth-pop trance C-pop\nsynth-pop trance EBM\nsynth-pop trance EDM\nsynth-pop trance J-pop\nsynth-pop trance J-rock\nsynth-pop trance chiptune\nsynth-pop trance cyberpunk\nsynth-pop trance darkwave\nsynth-pop trance dream pop\nsynth-pop trance electro-pop\nsynth-pop trance electronic rock\nsynth-pop trance eurodance\nsynth-pop trance hip-hop\nsynth-pop trance hyperpop\nsynth-pop trance progressive house\nsynth-pop trance techno\nsynth-pop trap\nsynth-pop trap C-pop\nsynth-pop trap EDM\nsynth-pop trap J-rock\nsynth-pop trap R&B\nsynth-pop trap chiptune\nsynth-pop trap cloud rap\nsynth-pop trap electronic rock\nsynth-pop trap future bass\nsynth-pop trap hip-hop\nsynth-pop trap hyperpop\nsynth-pop trap phonk\nsynth-pop trap vaporwave\nsynth-pop trap-R&B\nsynth-pop trap-pop\nsynth-pop trap-soul\nsynth-pop tribal\nsynth-pop tribal house\nsynth-pop trip-hop\nsynth-pop trip-hop electronica\nsynth-pop tropical\nsynth-pop tropical 80s\nsynth-pop tropical chiptune\nsynth-pop tropical dancehall\nsynth-pop tropical future bass\nsynth-pop tropical house\nsynth-pop tropical lounge\nsynth-pop trot\nsynth-pop turbo-folk\nsynth-pop uk garage\nsynth-pop uk garage 90s house\nsynth-pop uk hip-hop\nsynth-pop vaporwave\nsynth-pop vaporwave 80s\nsynth-pop vaporwave 80s R&B\nsynth-pop vaporwave 90s R&B\nsynth-pop vaporwave Arabic pop\nsynth-pop vaporwave C-pop\nsynth-pop vaporwave R&B\nsynth-pop vaporwave V-Pop\nsynth-pop vaporwave chillwave\nsynth-pop vaporwave chiptune\nsynth-pop vaporwave city pop\nsynth-pop vaporwave cloud rap\nsynth-pop vaporwave dream pop\nsynth-pop vaporwave dream-pop\nsynth-pop vaporwave experimental\nsynth-pop vaporwave future bass\nsynth-pop vaporwave future funk\nsynth-pop vaporwave hip-hop\nsynth-pop vaporwave lo-fi\nsynth-pop vaporwave lounge\nsynth-pop vaporwave synthwave\nsynth-pop vaporwave trap\nsynth-pop video game\nsynth-pop video game music\nsynth-pop villancico\nsynth-pop world fusion\nsynth-pop world music\nsynth-pop world music funk\nsynth-pop worldbeat\nsynth-pop worldbeat gospel\nsynth-pop worldbeat new age\nsynth-pop worldbeat reggae\nsynth-pop worldbeat zouk\nsynth-pop worship\nsynth-pop zouk\nsynth-pop zouk 80s\nsynth-pop zouk afropop\nsynth-pop zouk caribbean\nsynth-pop zouk cinematic\nsynth-pop zouk french pop\nsynth-pop zouk kizomba\nsynth-pop 中东风情\nsynth-pop, 8-bit, chiptune\nsynth-pop, 80s Asian pop\nsynth-pop, 80s Bollywood\nsynth-pop, 80s Bollywood, cinematic\nsynth-pop, 80s Brazilian\nsynth-pop, 80s Brazilian pop\nsynth-pop, 80s C-pop, City Pop\nsynth-pop, 80s Cantopop, anime theme\nsynth-pop, 80s Cantopop, cinematic\nsynth-pop, 80s Cantopop, new wave\nsynth-pop, 80s Chinese pop, cinematic\nsynth-pop, 80s Chinese rock\nsynth-pop, 80s Christian contemporary\nsynth-pop, 80s City Pop\nsynth-pop, 80s City Pop, anime theme\nsynth-pop, 80s East Asian pop, children's music\nsynth-pop, 80s Eastern European pop\nsynth-pop, 80s Eastern European pop-rock\nsynth-pop, 80s Eastern European, melancholic\nsynth-pop, 80s Estrada\nsynth-pop, 80s Eurodance\nsynth-pop, 80s Eurodance, Russian\nsynth-pop, 80s Eurodance, Russian estrada\nsynth-pop, 80s Eurodance, Turkish\nsynth-pop, 80s Eurodance, cinematic\nsynth-pop, 80s Filipino pop, retro\nsynth-pop, 80s French cold wave\nsynth-pop, 80s French pop\nsynth-pop, 80s French pop, cinematic\nsynth-pop, 80s German Schlager\nsynth-pop, 80s German Schlager, cinematic\nsynth-pop, 80s German new wave\nsynth-pop, 80s Indian film music\nsynth-pop, 80s Indonesian pop\nsynth-pop, 80s Israeli pop\nsynth-pop, 80s Israeli pop, retro\nsynth-pop, 80s Israeli pop-rock\nsynth-pop, 80s Italian new wave\nsynth-pop, 80s Italian new wave, cinematic\nsynth-pop, 80s Italian pop, cinematic\nsynth-pop, 80s Italian pop, theatrical\nsynth-pop, 80s Italian pop-rock\nsynth-pop, 80s J-pop, anime\nsynth-pop, 80s J-pop, cinematic\nsynth-pop, 80s Japanese new wave\nsynth-pop, 80s K-pop\nsynth-pop, 80s K-pop, nostalgic\nsynth-pop, 80s Kollywood, cinematic\nsynth-pop, 80s Korean trot\nsynth-pop, 80s Latin pop\nsynth-pop, 80s Mandopop, C-pop\nsynth-pop, 80s Mandopop, anime theme\nsynth-pop, 80s Mandopop, chiptune\nsynth-pop, 80s Mandopop, cinematic\nsynth-pop, 80s Mandopop, retro\nsynth-pop, 80s Mandopop, theatrical\nsynth-pop, 80s Persian, chiptune\nsynth-pop, 80s Polish new wave\nsynth-pop, 80s Polish new wave, theatrical\nsynth-pop, 80s Polish rock\nsynth-pop, 80s Romanian new wave\nsynth-pop, 80s Romanian pop, festive\nsynth-pop, 80s Russian estrada\nsynth-pop, 80s Russian new wave\nsynth-pop, 80s Russian pop\nsynth-pop, 80s South Indian film music\nsynth-pop, 80s Soviet disco\nsynth-pop, 80s Soviet estrada\nsynth-pop, 80s Soviet estrada, cinematic\nsynth-pop, 80s Soviet new wave\nsynth-pop, 80s Soviet new wave, Russian estrada\nsynth-pop, 80s Soviet rock, chiptune\nsynth-pop, 80s Soviet, electronic\nsynth-pop, 80s Soviet, nostalgic\nsynth-pop, 80s Thai pop\nsynth-pop, 80s Thai pop, psychedelic\nsynth-pop, 80s Thai rock\nsynth-pop, 80s Turkish new wave\nsynth-pop, 80s Turkish pop\nsynth-pop, 80s Turkish pop, melancholic\nsynth-pop, 80s Turkish pop-rock\nsynth-pop, 80s Vietnamese pop\nsynth-pop, 80s anime, theatrical\nsynth-pop, 80s arena rock, bilingual\nsynth-pop, 80s disco, Christmas\nsynth-pop, 80s disco, Eastern European\nsynth-pop, 80s disco, Polish\nsynth-pop, 80s eurodance\nsynth-pop, 80s eurodance, Turkish\nsynth-pop, 80s filmi\nsynth-pop, 80s filmi, Bengali\nsynth-pop, 80s filmi, Bengali pop\nsynth-pop, 80s filmi, South Asian\nsynth-pop, 80s filmi, retro\nsynth-pop, 80s glam rock, cinematic\nsynth-pop, 80s horror\nsynth-pop, 80s horror-pop\nsynth-pop, 80s new age, anime soundtrack\nsynth-pop, 80s new age, cinematic\nsynth-pop, 80s new age, city pop\nsynth-pop, 80s new wave\nsynth-pop, 80s new wave, Arabic pop\nsynth-pop, 80s new wave, C-pop\nsynth-pop, 80s new wave, Cantopop\nsynth-pop, 80s new wave, Christmas\nsynth-pop, 80s new wave, Dutch\nsynth-pop, 80s new wave, EBM\nsynth-pop, 80s new wave, Eastern European\nsynth-pop, 80s new wave, French cold wave\nsynth-pop, 80s new wave, French synthwave\nsynth-pop, 80s new wave, Italian pop-rock\nsynth-pop, 80s new wave, Italo disco\nsynth-pop, 80s new wave, Italo-disco\nsynth-pop, 80s new wave, J-rock\nsynth-pop, 80s new wave, Neue Deutsche Welle\nsynth-pop, 80s new wave, Persian pop\nsynth-pop, 80s new wave, Portuguese pop\nsynth-pop, 80s new wave, Romanian\nsynth-pop, 80s new wave, Soviet pop\nsynth-pop, 80s new wave, Soviet-era\nsynth-pop, 80s new wave, Soviet-wave\nsynth-pop, 80s new wave, Spanish pop\nsynth-pop, 80s new wave, anthemic\nsynth-pop, 80s new wave, atmospheric\nsynth-pop, 80s new wave, bilingual\nsynth-pop, 80s new wave, campy\nsynth-pop, 80s new wave, children's music\nsynth-pop, 80s new wave, chiptune\nsynth-pop, 80s new wave, cinematic\nsynth-pop, 80s new wave, city pop\nsynth-pop, 80s new wave, dance-punk\nsynth-pop, 80s new wave, dark wave\nsynth-pop, 80s new wave, darkwave\nsynth-pop, 80s new wave, dream pop\nsynth-pop, 80s new wave, electronic\nsynth-pop, 80s new wave, funk\nsynth-pop, 80s new wave, glitch\nsynth-pop, 80s new wave, post-punk\nsynth-pop, 80s new wave, retro-futuristic\nsynth-pop, 80s new wave, satirical\nsynth-pop, 80s new wave, shoegaze\nsynth-pop, 80s new wave, show tune\nsynth-pop, 80s new wave, theatrical\nsynth-pop, 80s new wave, video game soundtrack\nsynth-pop, 80s pop, Asian pop\nsynth-pop, 80s pop, Estrada\nsynth-pop, 80s pop-rock\nsynth-pop, 80s pop-rock, Eastern European\nsynth-pop, 80s retro, Halloween\nsynth-pop, 80s retro, festive\nsynth-pop, 80s retro-futuristic\nsynth-pop, 80s retro-futuristic, K-pop\nsynth-pop, 80s retro-futuristic, anime\nsynth-pop, 80s retro-futuristic, chiptune\nsynth-pop, 80s rock\nsynth-pop, 80s rock, Israeli\nsynth-pop, 80s rock, K-rock\nsynth-pop, 80s rock, Russian rock\nsynth-pop, 80s rock, Turkish\nsynth-pop, 80s rock, Turkish rock\nsynth-pop, 80s schlager, cinematic\nsynth-pop, 80s synthwave, city pop\nsynth-pop, 80s synthwave, post-punk\nsynth-pop, 80s, Bengali film music\nsynth-pop, 80s, Bollywood\nsynth-pop, 80s, Brazilian\nsynth-pop, 80s, C-pop\nsynth-pop, 80s, Central Asian pop\nsynth-pop, 80s, Christmas\nsynth-pop, 80s, Czech rock\nsynth-pop, 80s, Eastern European\nsynth-pop, 80s, Eastern European disco\nsynth-pop, 80s, Eastern European new wave\nsynth-pop, 80s, Estrada\nsynth-pop, 80s, German Schlager\nsynth-pop, 80s, Indian fusion\nsynth-pop, 80s, Israeli new wave\nsynth-pop, 80s, Korean\nsynth-pop, 80s, Middle Eastern fusion\nsynth-pop, 80s, Persian\nsynth-pop, 80s, Schlager\nsynth-pop, 80s, South Asian\nsynth-pop, 80s, South Asian film\nsynth-pop, 80s, South Asian film music\nsynth-pop, 80s, South Asian new wave\nsynth-pop, 80s, South Asian pop\nsynth-pop, 80s, South Indian film music\nsynth-pop, 80s, Southeast Asian pop\nsynth-pop, 80s, Turkish\nsynth-pop, 80s, Vietnamese\nsynth-pop, 80s, disco\nsynth-pop, 80s, filmi\nsynth-pop, 80s, quirky\nsynth-pop, 80s, tropical\nsynth-pop, 90s C-pop, city pop\nsynth-pop, 90s Eurodance, Arabic pop\nsynth-pop, 90s Eurodance, South Asian pop\nsynth-pop, 90s Indonesian pop, cinematic\nsynth-pop, 90s J-pop, city pop\nsynth-pop, 90s K-pop, anime theme\nsynth-pop, 90s K-pop, city pop\nsynth-pop, 90s Mandopop, cinematic\nsynth-pop, 90s R&B, city pop\nsynth-pop, 90s anime OST, ballad\nsynth-pop, African gospel\nsynth-pop, Afro-pop\nsynth-pop, Afrobeat\nsynth-pop, Anatolian rock\nsynth-pop, Anatolian rock, Italo-disco\nsynth-pop, Anatolian rock, Middle Eastern\nsynth-pop, Anatolian, cinematic\nsynth-pop, Anatolian, retro\nsynth-pop, Arabic fusion\nsynth-pop, Arabic pop, 80s retro\nsynth-pop, Arabic pop, Italo disco\nsynth-pop, Arabic, retro\nsynth-pop, Axé, Forró Eletrônico\nsynth-pop, Axé, Italo-disco\nsynth-pop, Azerbaijani pop\nsynth-pop, Balkan dance-pop\nsynth-pop, Balkan folk\nsynth-pop, Balkan new wave\nsynth-pop, Balkan pop\nsynth-pop, Balkan pop, trap\nsynth-pop, Balkan rock\nsynth-pop, Balkan, 80s dance-pop\nsynth-pop, Balkan, Latin\nsynth-pop, Balkan, Middle Eastern\nsynth-pop, Balkan, retro\nsynth-pop, Bengali folk\nsynth-pop, Bengali fusion, 80s\nsynth-pop, Bengali pop, retro\nsynth-pop, Bengali, upbeat\nsynth-pop, Bollywood\nsynth-pop, Bollywood disco, 80s\nsynth-pop, Bollywood filmi, Christian devotional\nsynth-pop, Bollywood pop\nsynth-pop, Bollywood, 80s\nsynth-pop, Bollywood, Christian devotional\nsynth-pop, Bollywood, EDM\nsynth-pop, Bollywood, Italo-disco\nsynth-pop, Bollywood, children's\nsynth-pop, Bollywood, chiptune\nsynth-pop, Bollywood, heavy metal\nsynth-pop, Bollywood, hip-hop\nsynth-pop, Bollywood, new wave\nsynth-pop, Bollywood, pop\nsynth-pop, Bollywood, retro-futuristic\nsynth-pop, Bollywood, smooth jazz\nsynth-pop, Bollywood, trance\nsynth-pop, Brazilian\nsynth-pop, Brazilian Funk\nsynth-pop, Brazilian MPB\nsynth-pop, Brazilian bass\nsynth-pop, Brazilian bass, slap house\nsynth-pop, Brazilian electronic\nsynth-pop, Brazilian funk\nsynth-pop, Brazilian funk carioca\nsynth-pop, Brazilian funk, R&B\nsynth-pop, Brazilian funk, retro\nsynth-pop, Brazilian funk, retro-futuristic\nsynth-pop, Brazilian new wave\nsynth-pop, Brazilian pop\nsynth-pop, Brazilian pop, 80s\nsynth-pop, Brazilian pop, retro\nsynth-pop, Brazilian pop-rock\nsynth-pop, Brazilian pop-rock, 80s new wave\nsynth-pop, Brazilian rock\nsynth-pop, Brazilian trap\nsynth-pop, Brazilian, 80s\nsynth-pop, Brazilian, 80s new wave\nsynth-pop, Brazilian, Latin\nsynth-pop, Brazilian, psychedelic\nsynth-pop, Brazilian, reggaeton\nsynth-pop, Brazilian, retro\nsynth-pop, Brazilian, retro-futuristic\nsynth-pop, Brazilian, world music\nsynth-pop, C-pop\nsynth-pop, C-pop, Eurodance\nsynth-pop, C-pop, French pop\nsynth-pop, C-pop, J-pop\nsynth-pop, C-pop, R&B, disco-funk, Mandopop, hip-hop\nsynth-pop, C-pop, anime\nsynth-pop, C-pop, chiptune\nsynth-pop, C-pop, cinematic\nsynth-pop, C-pop, electro-funk\nsynth-pop, C-pop, electronic\nsynth-pop, C-pop, hyperpop\nsynth-pop, C-pop, kawaii\nsynth-pop, C-pop, lo-fi\nsynth-pop, C-pop, retro\nsynth-pop, C-pop, rock\nsynth-pop, C-pop, traditional Chinese\nsynth-pop, Cantopop, City Pop\nsynth-pop, Cantopop, Eurobeat\nsynth-pop, Cantopop, anime\nsynth-pop, Cantopop, cinematic\nsynth-pop, Caribbean, 80s\nsynth-pop, Celtic rock\nsynth-pop, Central Asian\nsynth-pop, Central Asian folk\nsynth-pop, Central Asian pop\nsynth-pop, Central Asian, 80s\nsynth-pop, Central Asian, chiptune\nsynth-pop, Central Asian, dance\nsynth-pop, Central Asian, dramatic\nsynth-pop, Central Asian, upbeat\nsynth-pop, Chinese New Year, 80s Mandopop\nsynth-pop, Chinese New Year, chiptune\nsynth-pop, Chinese New Year, dance\nsynth-pop, Chinese New Year, electronic\nsynth-pop, Chinese New Year, festive\nsynth-pop, Chinese New Year, retro\nsynth-pop, Chinese New Year, upbeat\nsynth-pop, Chinese folk\nsynth-pop, Chinese folk, 80s\nsynth-pop, Chinese folk, disco\nsynth-pop, Chinese folk, retro\nsynth-pop, Chinese fusion\nsynth-pop, Chinese hip hop\nsynth-pop, Chinese hip hop, cinematic\nsynth-pop, Chinese traditional\nsynth-pop, Chinese traditional, theatrical\nsynth-pop, Chinese-style, cinematic\nsynth-pop, Christian Contemporary Music\nsynth-pop, Christian contemporary\nsynth-pop, Christian hymn\nsynth-pop, Christian pop-rock\nsynth-pop, Christian rock\nsynth-pop, Christian, 80s\nsynth-pop, Christian, 80s Eurobeat\nsynth-pop, Christian, 80s Italo-disco\nsynth-pop, Christian, 80s arena rock\nsynth-pop, Christian, 80s dance-pop\nsynth-pop, Christian, Bollywood\nsynth-pop, Christian, Eurodance\nsynth-pop, Christian, Latin\nsynth-pop, Christian, world music\nsynth-pop, Christmas pop, 80s pop\nsynth-pop, Christmas, 80s\nsynth-pop, Christmas, 80s pop\nsynth-pop, Christmas, Schlager\nsynth-pop, Christmas, South Indian\nsynth-pop, Christmas, festive\nsynth-pop, Christmas, theatrical\nsynth-pop, City Pop\nsynth-pop, City Pop, 80s\nsynth-pop, City Pop, 80s J-pop\nsynth-pop, City Pop, 80s Japanese\nsynth-pop, City Pop, 80s anime\nsynth-pop, City Pop, C-pop\nsynth-pop, City Pop, Cantopop\nsynth-pop, City Pop, Eurobeat\nsynth-pop, City Pop, Italo-disco\nsynth-pop, City Pop, J-pop\nsynth-pop, City Pop, Japanese\nsynth-pop, City Pop, K-pop\nsynth-pop, City Pop, Mandopop\nsynth-pop, City Pop, Taiwanese Hokkien pop\nsynth-pop, City Pop, anime\nsynth-pop, City Pop, anime theme\nsynth-pop, City Pop, chiptune\nsynth-pop, City Pop, disco\nsynth-pop, City Pop, festive\nsynth-pop, City Pop, lo-fi\nsynth-pop, City Pop, retro\nsynth-pop, City Pop, retro-futuristic\nsynth-pop, City Pop, video game\nsynth-pop, City Pop, video game music\nsynth-pop, City Pop, video game soundtrack\nsynth-pop, Deutschpop\nsynth-pop, Deutschrap\nsynth-pop, EBM\nsynth-pop, EBM, 80s\nsynth-pop, EBM, 80s new wave\nsynth-pop, EBM, Italian pop\nsynth-pop, EBM, Italo disco\nsynth-pop, EBM, Italo-disco\nsynth-pop, EBM, Neue Deutsche Welle\nsynth-pop, EBM, ambient\nsynth-pop, EBM, atmospheric\nsynth-pop, EBM, chiptune\nsynth-pop, EBM, cinematic\nsynth-pop, EBM, coldwave\nsynth-pop, EBM, cyberpunk\nsynth-pop, EBM, dark wave\nsynth-pop, EBM, darkwave\nsynth-pop, EBM, early techno\nsynth-pop, EBM, electro\nsynth-pop, EBM, electro-pop\nsynth-pop, EBM, electro-punk\nsynth-pop, EBM, electro-rap\nsynth-pop, EBM, electro-rock\nsynth-pop, EBM, electroclash\nsynth-pop, EBM, futurepop\nsynth-pop, EBM, hip-hop\nsynth-pop, EBM, hyperpop\nsynth-pop, EBM, industrial\nsynth-pop, EBM, industrial dance\nsynth-pop, EBM, industrial rock\nsynth-pop, EBM, industrial techno\nsynth-pop, EBM, lo-fi\nsynth-pop, EBM, new wave\nsynth-pop, EBM, retro wave\nsynth-pop, EBM, retro-electronic\nsynth-pop, EBM, retro-futuristic\nsynth-pop, EBM, synthwave\nsynth-pop, EBM, techno\nsynth-pop, EBM, trance\nsynth-pop, EDM\nsynth-pop, EDM, C-pop\nsynth-pop, EDM, Chinese electronic\nsynth-pop, EDM, Chinese pop\nsynth-pop, EDM, Chinese rap\nsynth-pop, EDM, Christian\nsynth-pop, EDM, Hindi pop\nsynth-pop, EDM, Italo-disco\nsynth-pop, EDM, K-pop\nsynth-pop, EDM, Latin pop\nsynth-pop, EDM, Mandarin pop\nsynth-pop, EDM, Mandopop\nsynth-pop, EDM, Nepali pop\nsynth-pop, EDM, Portuguese pop\nsynth-pop, EDM, R&B\nsynth-pop, EDM, Russian pop\nsynth-pop, EDM, Tamil pop\nsynth-pop, EDM, V-Pop\nsynth-pop, EDM, Vietnamese pop\nsynth-pop, EDM, ambient\nsynth-pop, EDM, anime soundtrack\nsynth-pop, EDM, anthemic\nsynth-pop, EDM, atmospheric\nsynth-pop, EDM, ballad\nsynth-pop, EDM, big room house\nsynth-pop, EDM, chiptune\nsynth-pop, EDM, cinematic\nsynth-pop, EDM, cyberpunk\nsynth-pop, EDM, dance\nsynth-pop, EDM, dance-pop\nsynth-pop, EDM, electro-pop\nsynth-pop, EDM, electronic\nsynth-pop, EDM, future bass\nsynth-pop, EDM, futuristic\nsynth-pop, EDM, hip-hop\nsynth-pop, EDM, hyperpop\nsynth-pop, EDM, lo-fi\nsynth-pop, EDM, nostalgic\nsynth-pop, EDM, pop\nsynth-pop, EDM, progressive house\nsynth-pop, EDM, retro\nsynth-pop, EDM, rock\nsynth-pop, EDM, slap house\nsynth-pop, EDM, theatrical\nsynth-pop, EDM, trance\nsynth-pop, EDM, trap\nsynth-pop, EDM, tropical house\nsynth-pop, EDM-pop\nsynth-pop, East African pop\nsynth-pop, East Asian pop\nsynth-pop, East Asian, 90s video game\nsynth-pop, East Asian, retro\nsynth-pop, Eastern European\nsynth-pop, Eastern European dance-pop\nsynth-pop, Eastern European disco\nsynth-pop, Eastern European folk\nsynth-pop, Eastern European folk, chiptune\nsynth-pop, Eastern European new wave\nsynth-pop, Eastern European pop, Turkish pop\nsynth-pop, Eastern European pop-rock\nsynth-pop, Eastern European rock\nsynth-pop, Eastern European rock, 80s\nsynth-pop, Eastern European, Central Asian\nsynth-pop, Eastern European, folk-pop\nsynth-pop, Eastern European, kitsch\nsynth-pop, Eastern European, lo-fi\nsynth-pop, Eastern European, quirky\nsynth-pop, Estrada, 80s Russian pop\nsynth-pop, Eurobeat, Hi-NRG\nsynth-pop, Eurodance\nsynth-pop, Eurodance, Arabic pop\nsynth-pop, Eurodance, Bollywood\nsynth-pop, Eurodance, Central Asian\nsynth-pop, Eurodance, City Pop\nsynth-pop, Eurodance, EDM\nsynth-pop, Eurodance, Eastern European\nsynth-pop, Eurodance, Hi-NRG\nsynth-pop, Eurodance, Italo disco\nsynth-pop, Eurodance, Italo-disco\nsynth-pop, Eurodance, J-pop\nsynth-pop, Eurodance, Middle Eastern\nsynth-pop, Eurodance, Russian pop\nsynth-pop, Eurodance, South Asian\nsynth-pop, Eurodance, Turkish\nsynth-pop, Eurodance, Turkish pop-rock\nsynth-pop, Eurodance, Uzbek pop\nsynth-pop, Eurodance, Vietnamese pop\nsynth-pop, Eurodance, children's music\nsynth-pop, Eurodance, children's pop\nsynth-pop, Eurodance, hyperpop\nsynth-pop, Eurodance, retro-futuristic\nsynth-pop, Eurodance, shoegaze\nsynth-pop, Eurodance, trance\nsynth-pop, Finnish schlager\nsynth-pop, French cloud rap\nsynth-pop, French cold wave\nsynth-pop, French cold wave, 80s\nsynth-pop, French coldwave\nsynth-pop, French coldwave, nu-disco\nsynth-pop, French hip-hop, retro-futuristic\nsynth-pop, French house\nsynth-pop, French house, Italo disco\nsynth-pop, French new wave\nsynth-pop, French new wave, 80s\nsynth-pop, French pop, Italo disco\nsynth-pop, French pop, cinematic\nsynth-pop, French pop-rock\nsynth-pop, French rap\nsynth-pop, French rap, alternative rock\nsynth-pop, French rap, electronic\nsynth-pop, German Schlager\nsynth-pop, German Schlager, cinematic\nsynth-pop, German cloud rap\nsynth-pop, German electro-pop\nsynth-pop, German hip-hop\nsynth-pop, German hip-hop, chiptune\nsynth-pop, German indie-dance\nsynth-pop, German indie-pop\nsynth-pop, German new wave\nsynth-pop, German new wave, 80s\nsynth-pop, German rap, retro-futuristic\nsynth-pop, German rock\nsynth-pop, German techno\nsynth-pop, German, Christmas\nsynth-pop, Greek new wave, retro\nsynth-pop, Greek rock\nsynth-pop, Halloween, campy\nsynth-pop, Halloween, chiptune\nsynth-pop, Halloween, retro\nsynth-pop, Hi-NRG\nsynth-pop, Hi-NRG, Italo disco\nsynth-pop, Hi-NRG, Italo-disco\nsynth-pop, Hi-NRG, dance-pop\nsynth-pop, Indian classical, ambient\nsynth-pop, Indian film music\nsynth-pop, Indian film music, 80s\nsynth-pop, Indian film music, retro\nsynth-pop, Indian film music, retro-futuristic\nsynth-pop, Indian filmi, retro-futuristic\nsynth-pop, Indian folk, retro-futuristic\nsynth-pop, Indian fusion\nsynth-pop, Indian fusion, retro-futuristic\nsynth-pop, Indian pop\nsynth-pop, Indian pop, dance-pop\nsynth-pop, Indonesian pop\nsynth-pop, Israeli new wave\nsynth-pop, Israeli rock\nsynth-pop, Italian folk, operatic\nsynth-pop, Italian folk, retro\nsynth-pop, Italian hip-hop\nsynth-pop, Italian pop, light rock\nsynth-pop, Italian pop-rap\nsynth-pop, Italian pop-rock\nsynth-pop, Italo disco\nsynth-pop, Italo disco, 80s\nsynth-pop, Italo disco, Arabic pop\nsynth-pop, Italo disco, Brazilian synth-pop\nsynth-pop, Italo disco, Christmas\nsynth-pop, Italo disco, Czech disco\nsynth-pop, Italo disco, Eastern European disco\nsynth-pop, Italo disco, Eastern European pop\nsynth-pop, Italo disco, Eurobeat\nsynth-pop, Italo disco, Eurodance\nsynth-pop, Italo disco, Finnish\nsynth-pop, Italo disco, French synth-pop\nsynth-pop, Italo disco, Halloween\nsynth-pop, Italo disco, Hi-NRG\nsynth-pop, Italo disco, Polish new wave\nsynth-pop, Italo disco, Russian estrada\nsynth-pop, Italo disco, South Asian pop\nsynth-pop, Italo disco, Soviet pop\nsynth-pop, Italo disco, children's music\nsynth-pop, Italo disco, chiptune\nsynth-pop, Italo disco, disco polo\nsynth-pop, Italo disco, electro-funk\nsynth-pop, Italo disco, electro-pop\nsynth-pop, Italo disco, house\nsynth-pop, Italo disco, hyperpop\nsynth-pop, Italo disco, new wave\nsynth-pop, Italo disco, retro\nsynth-pop, Italo disco, retro-futuristic\nsynth-pop, Italo disco, synth-rock\nsynth-pop, Italo disco, synthwave\nsynth-pop, Italo-disco\nsynth-pop, Italo-disco, 80s\nsynth-pop, Italo-disco, 80s Czech\nsynth-pop, Italo-disco, 80s Japanese\nsynth-pop, Italo-disco, 80s dance\nsynth-pop, Italo-disco, 80s electro\nsynth-pop, Italo-disco, 80s new wave\nsynth-pop, Italo-disco, 80s pop\nsynth-pop, Italo-disco, 80s pop-rock\nsynth-pop, Italo-disco, Arabic pop\nsynth-pop, Italo-disco, Bengali pop\nsynth-pop, Italo-disco, Bollywood\nsynth-pop, Italo-disco, Bollywood pop\nsynth-pop, Italo-disco, Brazilian pop\nsynth-pop, Italo-disco, Canto-pop\nsynth-pop, Italo-disco, Cantopop\nsynth-pop, Italo-disco, Christmas\nsynth-pop, Italo-disco, Czech new wave\nsynth-pop, Italo-disco, EBM\nsynth-pop, Italo-disco, Estrada\nsynth-pop, Italo-disco, Euro-pop\nsynth-pop, Italo-disco, Eurobeat\nsynth-pop, Italo-disco, Eurodance\nsynth-pop, Italo-disco, European pop\nsynth-pop, Italo-disco, Finnish schlager\nsynth-pop, Italo-disco, French\nsynth-pop, Italo-disco, French novelty\nsynth-pop, Italo-disco, French pop\nsynth-pop, Italo-disco, German\nsynth-pop, Italo-disco, German Schlager\nsynth-pop, Italo-disco, German synth-pop\nsynth-pop, Italo-disco, Greek pop\nsynth-pop, Italo-disco, Greek pop-rock\nsynth-pop, Italo-disco, Halloween\nsynth-pop, Italo-disco, Hi-NRG\nsynth-pop, Italo-disco, Hungarian\nsynth-pop, Italo-disco, Hungarian new wave\nsynth-pop, Italo-disco, K-pop\nsynth-pop, Italo-disco, Korean trot\nsynth-pop, Italo-disco, Latin\nsynth-pop, Italo-disco, Latin pop\nsynth-pop, Italo-disco, Lusophone\nsynth-pop, Italo-disco, Mandopop\nsynth-pop, Italo-disco, Middle Eastern\nsynth-pop, Italo-disco, Middle Eastern pop\nsynth-pop, Italo-disco, Neapolitan\nsynth-pop, Italo-disco, Neue Deutsche Welle\nsynth-pop, Italo-disco, Persian pop\nsynth-pop, Italo-disco, Polish new wave\nsynth-pop, Italo-disco, Romanian\nsynth-pop, Italo-disco, Russian\nsynth-pop, Italo-disco, Russian folk\nsynth-pop, Italo-disco, Russian new wave\nsynth-pop, Italo-disco, Russian pop\nsynth-pop, Italo-disco, Soviet new wave\nsynth-pop, Italo-disco, Soviet pop\nsynth-pop, Italo-disco, Soviet-era\nsynth-pop, Italo-disco, Soviet-wave\nsynth-pop, Italo-disco, Spanish pop\nsynth-pop, Italo-disco, Spanish pop-rock\nsynth-pop, Italo-disco, Swedish pop\nsynth-pop, Italo-disco, Turkish\nsynth-pop, Italo-disco, Turkish pop\nsynth-pop, Italo-disco, V-Pop\nsynth-pop, Italo-disco, V-pop\nsynth-pop, Italo-disco, Vocaloid\nsynth-pop, Italo-disco, ambient\nsynth-pop, Italo-disco, anthemic\nsynth-pop, Italo-disco, ballad\nsynth-pop, Italo-disco, baroque\nsynth-pop, Italo-disco, bilingual\nsynth-pop, Italo-disco, children's music\nsynth-pop, Italo-disco, chiptune\nsynth-pop, Italo-disco, cinematic\nsynth-pop, Italo-disco, city pop\nsynth-pop, Italo-disco, cyberpunk\nsynth-pop, Italo-disco, darkwave\nsynth-pop, Italo-disco, digital reggae\nsynth-pop, Italo-disco, dream pop\nsynth-pop, Italo-disco, electric guitar\nsynth-pop, Italo-disco, electro\nsynth-pop, Italo-disco, electronic\nsynth-pop, Italo-disco, epic\nsynth-pop, Italo-disco, estrada\nsynth-pop, Italo-disco, euro-pop\nsynth-pop, Italo-disco, festive\nsynth-pop, Italo-disco, freestyle\nsynth-pop, Italo-disco, horror\nsynth-pop, Italo-disco, house\nsynth-pop, Italo-disco, iskelmä\nsynth-pop, Italo-disco, new wave\nsynth-pop, Italo-disco, novelty\nsynth-pop, Italo-disco, post-punk\nsynth-pop, Italo-disco, power metal\nsynth-pop, Italo-disco, power pop\nsynth-pop, Italo-disco, power-pop\nsynth-pop, Italo-disco, punk\nsynth-pop, Italo-disco, retro\nsynth-pop, Italo-disco, retro-electronic\nsynth-pop, Italo-disco, retro-futuristic\nsynth-pop, Italo-disco, rock\nsynth-pop, Italo-disco, rock-opera\nsynth-pop, Italo-disco, schlager\nsynth-pop, Italo-disco, stadium pop\nsynth-pop, Italo-disco, synth-rock\nsynth-pop, Italo-disco, synthwave\nsynth-pop, Italo-disco, theatrical\nsynth-pop, Italo-disco, upbeat\nsynth-pop, Italo-disco, video game music\nsynth-pop, Italo-disco, world music\nsynth-pop, J-core\nsynth-pop, J-core, happy hardcore\nsynth-pop, J-core, hyperpop\nsynth-pop, J-core, trance\nsynth-pop, J-pop\nsynth-pop, J-pop, C-pop\nsynth-pop, J-pop, Christian\nsynth-pop, J-pop, City Pop\nsynth-pop, J-pop, Dutch\nsynth-pop, J-pop, K-pop\nsynth-pop, J-pop, Romanian\nsynth-pop, J-pop, Vietnamese pop\nsynth-pop, J-pop, anime\nsynth-pop, J-pop, anime theme\nsynth-pop, J-pop, children's\nsynth-pop, J-pop, children's music\nsynth-pop, J-pop, chillwave\nsynth-pop, J-pop, chiptune\nsynth-pop, J-pop, cinematic\nsynth-pop, J-pop, city pop\nsynth-pop, J-pop, happy hardcore\nsynth-pop, J-pop, hyperpop\nsynth-pop, J-pop, kawaii\nsynth-pop, J-pop, kawaii future bass\nsynth-pop, J-pop, trance\nsynth-pop, J-pop, video game music\nsynth-pop, J-rock\nsynth-pop, J-rock, C-pop\nsynth-pop, J-rock, K-pop\nsynth-pop, J-rock, ambient\nsynth-pop, J-rock, anime\nsynth-pop, J-rock, anime soundtrack\nsynth-pop, J-rock, chiptune\nsynth-pop, J-rock, cinematic\nsynth-pop, J-rock, city pop\nsynth-pop, J-rock, electronic\nsynth-pop, J-rock, hip-hop\nsynth-pop, J-rock, hyperpop\nsynth-pop, J-rock, power metal\nsynth-pop, JRPG, ambient\nsynth-pop, Japanese rock, video game music\nsynth-pop, Javanese, retro-futuristic\nsynth-pop, K-Pop, R&B\nsynth-pop, K-pop ballad, cinematic\nsynth-pop, K-pop, 80s\nsynth-pop, K-pop, 80s rock\nsynth-pop, K-pop, EDM\nsynth-pop, K-pop, J-pop\nsynth-pop, K-pop, J-rock\nsynth-pop, K-pop, Mandopop\nsynth-pop, K-pop, anime\nsynth-pop, K-pop, anthemic\nsynth-pop, K-pop, children's\nsynth-pop, K-pop, chiptune\nsynth-pop, K-pop, city pop\nsynth-pop, K-pop, cyberpunk\nsynth-pop, K-pop, electro-pop\nsynth-pop, K-pop, electronic rock\nsynth-pop, K-pop, future bass\nsynth-pop, K-pop, hyperpop\nsynth-pop, K-pop, retro\nsynth-pop, K-pop, retro-futuristic\nsynth-pop, K-pop, trot\nsynth-pop, K-pop-rock, theatrical\nsynth-pop, Korean trot\nsynth-pop, Latin cumbia, Christian\nsynth-pop, Latin dance\nsynth-pop, Latin dance, retro-futuristic\nsynth-pop, Latin dance-pop, Christian worship\nsynth-pop, Latin disco, 80s\nsynth-pop, Latin disco, Vietnamese pop\nsynth-pop, Latin hip-hop, R&B\nsynth-pop, Latin hyperpop, reggaeton\nsynth-pop, Latin new wave\nsynth-pop, Latin pop\nsynth-pop, Latin pop, 80s\nsynth-pop, Latin pop, Christian\nsynth-pop, Latin pop, Christian praise\nsynth-pop, Latin pop, Italo-disco\nsynth-pop, Latin pop, children's music\nsynth-pop, Latin pop, chiptune\nsynth-pop, Latin pop, hip-hop\nsynth-pop, Latin pop, hyperpop\nsynth-pop, Latin pop, nu-disco\nsynth-pop, Latin pop, reggaeton\nsynth-pop, Latin pop, retro\nsynth-pop, Latin pop-rock\nsynth-pop, Latin trap\nsynth-pop, Latin urban\nsynth-pop, Latin urban, R&B\nsynth-pop, Latin, 80s\nsynth-pop, Latin, Christian\nsynth-pop, Latin, children's\nsynth-pop, Latin, retro\nsynth-pop, Latin, retro-futuristic\nsynth-pop, Latin-inspired, upbeat\nsynth-pop, Laïko\nsynth-pop, Luk Thung\nsynth-pop, Luk Thung, Mor Lam\nsynth-pop, MPB\nsynth-pop, MPB, 80s video game\nsynth-pop, MPB, dream pop\nsynth-pop, MPB, vaporwave\nsynth-pop, Mandopop, Eurodance\nsynth-pop, Mandopop, festive\nsynth-pop, Mandopop, glitch\nsynth-pop, Mandopop, robotic pop\nsynth-pop, Mandopop, rock\nsynth-pop, Middle Eastern\nsynth-pop, Middle Eastern dance\nsynth-pop, Middle Eastern folk\nsynth-pop, Middle Eastern folk, Eastern European folk\nsynth-pop, Middle Eastern fusion\nsynth-pop, Middle Eastern influence\nsynth-pop, Middle Eastern pop\nsynth-pop, Middle Eastern, 80s\nsynth-pop, Middle Eastern, 80s dance-pop\nsynth-pop, Middle Eastern, Anatolian\nsynth-pop, Middle Eastern, Kurdish\nsynth-pop, Middle Eastern, North African\nsynth-pop, Middle Eastern, Persian\nsynth-pop, Middle Eastern, Turkish\nsynth-pop, Middle Eastern, atmospheric\nsynth-pop, Middle Eastern, cinematic\nsynth-pop, Middle Eastern, dance\nsynth-pop, Middle Eastern, educational\nsynth-pop, Middle Eastern, electronic\nsynth-pop, Middle Eastern, energetic\nsynth-pop, Middle Eastern, new wave\nsynth-pop, Middle Eastern, quirky\nsynth-pop, Middle Eastern, reggaeton\nsynth-pop, Mizrahi, chiptune\nsynth-pop, Mongolian folk\nsynth-pop, Neue Deutsche Härte\nsynth-pop, Neue Deutsche Welle\nsynth-pop, Neue Deutsche Welle, 80s\nsynth-pop, Neue Deutsche Welle, Italo-disco\nsynth-pop, Neue Deutsche Welle, ambient\nsynth-pop, Neue Deutsche Welle, anthemic\nsynth-pop, Neue Deutsche Welle, hard rock\nsynth-pop, Neue Deutsche Welle, pop-rock\nsynth-pop, Neue Deutsche Welle, retro-futuristic\nsynth-pop, Neue Deutsche Welle, theatrical\nsynth-pop, North African\nsynth-pop, North African folk\nsynth-pop, North African fusion\nsynth-pop, North African pop\nsynth-pop, North African, dance\nsynth-pop, North African, retro\nsynth-pop, North African, retro electronic\nsynth-pop, Persian pop\nsynth-pop, Persian pop, dance\nsynth-pop, Persian, Italo-disco\nsynth-pop, Persian, atmospheric\nsynth-pop, Persian, cinematic\nsynth-pop, Persian, electronic\nsynth-pop, Persian, retro\nsynth-pop, Polish disco\nsynth-pop, Polish hip-hop\nsynth-pop, Polish new wave\nsynth-pop, Punjabi pop\nsynth-pop, R&B\nsynth-pop, R&B, Brazilian\nsynth-pop, R&B, City Pop\nsynth-pop, R&B, Middle Eastern\nsynth-pop, R&B, Nederpop\nsynth-pop, R&B, Persian\nsynth-pop, R&B, adult contemporary\nsynth-pop, R&B, city pop\nsynth-pop, R&B, future bass\nsynth-pop, R&B, gospel\nsynth-pop, R&B, hip-hop\nsynth-pop, R&B, industrial rock\nsynth-pop, R&B, lo-fi\nsynth-pop, R&B, new jack swing\nsynth-pop, R&B, nu-disco\nsynth-pop, R&B, power ballad\nsynth-pop, R&B, trap\nsynth-pop, R&B, vaporwave\nsynth-pop, Romanian folk, video game\nsynth-pop, Romanian pop\nsynth-pop, Romanian, Manele\nsynth-pop, Russian chanson\nsynth-pop, Russian estrada\nsynth-pop, Russian estrada, 80s\nsynth-pop, Russian estrada, 80s dance\nsynth-pop, Russian estrada, 80s pop\nsynth-pop, Russian estrada, chiptune\nsynth-pop, Russian estrada, cinematic\nsynth-pop, Russian estrada, nostalgic\nsynth-pop, Russian estrada, retro\nsynth-pop, Russian estrada, retro-futuristic\nsynth-pop, Russian estrada, theatrical\nsynth-pop, Russian folk\nsynth-pop, Russian hip-hop\nsynth-pop, Russian new wave\nsynth-pop, Russian new wave, 80s\nsynth-pop, Russian new wave, cinematic\nsynth-pop, Russian new wave, retro-futuristic\nsynth-pop, Russian pop\nsynth-pop, Russian pop, EDM\nsynth-pop, Russian pop, Eurodance\nsynth-pop, Russian pop, big beat\nsynth-pop, Russian pop-rock\nsynth-pop, Russian pop-rock, 2000s\nsynth-pop, Russian pop-rock, 80s\nsynth-pop, Russian pop-rock, cinematic\nsynth-pop, Russian pop-rock, theatrical\nsynth-pop, Russian rock\nsynth-pop, Russian rock, theatrical\nsynth-pop, Russian shanson\nsynth-pop, Russian, 80s\nsynth-pop, Russian, bubblegum pop\nsynth-pop, Russian, folk\nsynth-pop, Russian, retro\nsynth-pop, Russian, theatrical\nsynth-pop, Schlager\nsynth-pop, Schlager, 80s\nsynth-pop, Schlager, 80s German\nsynth-pop, Schlager, Christmas\nsynth-pop, Schlager, German\nsynth-pop, Schlager, children's music\nsynth-pop, Schlager, cinematic\nsynth-pop, Slavic folk\nsynth-pop, South African house\nsynth-pop, South Asian\nsynth-pop, South Asian film music\nsynth-pop, South Asian folk\nsynth-pop, South Asian funk\nsynth-pop, South Asian fusion\nsynth-pop, South Asian influence\nsynth-pop, South Asian rock\nsynth-pop, South Asian, Middle Eastern\nsynth-pop, South Asian, dance\nsynth-pop, South Asian, electronic\nsynth-pop, South Asian, nostalgic\nsynth-pop, South Asian, romantic\nsynth-pop, South Asian, upbeat\nsynth-pop, South Asian, video game\nsynth-pop, South Indian\nsynth-pop, South Indian film music\nsynth-pop, Southeast Asian pop\nsynth-pop, Soviet disco\nsynth-pop, Soviet estrada, dance\nsynth-pop, Soviet estrada, theatrical\nsynth-pop, Soviet new wave\nsynth-pop, Soviet new wave, 80s\nsynth-pop, Soviet new wave, 80s synthwave\nsynth-pop, Soviet new wave, Italo-disco\nsynth-pop, Soviet new wave, darkwave\nsynth-pop, Soviet new wave, quirky\nsynth-pop, Soviet new wave, retro-futuristic\nsynth-pop, Soviet wave, retro-futuristic\nsynth-pop, Soviet-era new wave\nsynth-pop, Soviet-era, Italo-disco\nsynth-pop, Soviet-era, estrada\nsynth-pop, Soviet-era, folk-dance\nsynth-pop, Soviet-era, folk-pop\nsynth-pop, Soviet-era, nostalgic\nsynth-pop, Soviet-era, satirical\nsynth-pop, Soviet-wave\nsynth-pop, Soviet-wave, Italo-disco\nsynth-pop, Soviet-wave, chiptune\nsynth-pop, Soviet-wave, post-punk\nsynth-pop, Soviet-wave, retro-futuristic\nsynth-pop, Sovietwave\nsynth-pop, T-pop, hyperpop\nsynth-pop, Tamil film music\nsynth-pop, Tamil pop, hip hop\nsynth-pop, Tamil pop, retro-futuristic\nsynth-pop, Thai R&B, lo-fi hip-hop\nsynth-pop, Thai pop\nsynth-pop, Thai pop, cinematic\nsynth-pop, Thai-pop\nsynth-pop, Thai-pop, retro\nsynth-pop, Tollywood\nsynth-pop, Turkish alternative rock\nsynth-pop, Turkish folk\nsynth-pop, Turkish influence\nsynth-pop, Turkish new wave\nsynth-pop, Turkish novelty\nsynth-pop, Turkish pop\nsynth-pop, Turkish pop, atmospheric\nsynth-pop, Turkish pop, chiptune\nsynth-pop, Turkish pop, cinematic\nsynth-pop, Turkish pop-rock\nsynth-pop, Turkish rock\nsynth-pop, Turkish, 80s\nsynth-pop, Turkish, 80s Euro-disco\nsynth-pop, Turkish, 80s Eurodance\nsynth-pop, Turkish, 80s electro\nsynth-pop, Turkish, Eurodance\nsynth-pop, Turkish, Middle Eastern\nsynth-pop, Turkish, chiptune\nsynth-pop, Turkish, melancholic\nsynth-pop, Turkish, vaporwave\nsynth-pop, UK garage, R&B\nsynth-pop, UK garage, future garage\nsynth-pop, UK garage, hyperpop\nsynth-pop, UK hip-hop\nsynth-pop, Ukrainian folk\nsynth-pop, V-Pop, Eurobeat\nsynth-pop, V-Pop, Eurodance\nsynth-pop, V-pop, 80s\nsynth-pop, V-pop, Eurodance\nsynth-pop, V-pop, city pop\nsynth-pop, V-pop, theatrical pop\nsynth-pop, Vietnamese ballad\nsynth-pop, Vietnamese folk\nsynth-pop, Vietnamese pop\nsynth-pop, Vietnamese pop, French pop\nsynth-pop, Vocaloid, chiptune\nsynth-pop, Zouk, Afropop\nsynth-pop, adult contemporary\nsynth-pop, afro-electronic\nsynth-pop, afro-pop, gospel\nsynth-pop, alt-rock, dream pop\nsynth-pop, alt-rock, lo-fi\nsynth-pop, alternative R&B\nsynth-pop, alternative R&B, Arabic electronic\nsynth-pop, alternative R&B, chiptune\nsynth-pop, alternative hip-hop\nsynth-pop, alternative rock\nsynth-pop, alternative rock, Chinese electronic\nsynth-pop, alternative rock, South Asian\nsynth-pop, alternative rock, cinematic\nsynth-pop, alternative rock, electronic\nsynth-pop, alternative rock, glitch\nsynth-pop, alternative rock, lo-fi\nsynth-pop, alternative rock, post-hardcore\nsynth-pop, alternative rock, shoegaze\nsynth-pop, alternative rock, synth-rock\nsynth-pop, ambient\nsynth-pop, ambient, C-pop\nsynth-pop, ambient, dubstep\nsynth-pop, ambient, glitch-hop\nsynth-pop, ambient, hip-hop\nsynth-pop, ambient, hyperpop\nsynth-pop, ambient, shoegaze\nsynth-pop, ambient, trance\nsynth-pop, anime theme\nsynth-pop, anthemic, patriotic\nsynth-pop, arena rock\nsynth-pop, arena rock, 80s\nsynth-pop, arena rock, 80s style\nsynth-pop, arena rock, Hungarian\nsynth-pop, arena rock, cinematic\nsynth-pop, arena rock, emotional ballad\nsynth-pop, art rock, 80s new wave\nsynth-pop, art-rock, cinematic\nsynth-pop, art-rock, noise-pop\nsynth-pop, axé, 80s Brazilian\nsynth-pop, ballad\nsynth-pop, ballad, C-pop\nsynth-pop, baroque, Italo-disco\nsynth-pop, bhangra, Bollywood\nsynth-pop, big band jazz\nsynth-pop, big room house\nsynth-pop, big room house, hardstyle\nsynth-pop, big-room EDM\nsynth-pop, blues-rock, cinematic\nsynth-pop, bolero, children's music, salsa\nsynth-pop, breakbeat, chiptune\nsynth-pop, breakbeat, drum and bass\nsynth-pop, breakbeat, electronic\nsynth-pop, breakcore, cinematic rock\nsynth-pop, brega-pop\nsynth-pop, brostep, dubstep\nsynth-pop, brostep, hip-hop\nsynth-pop, cabaret rock\nsynth-pop, cartoon, retro\nsynth-pop, chanson, Eastern European\nsynth-pop, chanson, cinematic\nsynth-pop, children's Christian\nsynth-pop, children's music\nsynth-pop, children's music, 8-bit\nsynth-pop, children's music, 80s\nsynth-pop, children's music, 80s East Asian\nsynth-pop, children's music, 80s video game\nsynth-pop, children's music, Brazilian\nsynth-pop, children's music, C-pop\nsynth-pop, children's music, K-pop\nsynth-pop, children's music, Neue Deutsche Welle\nsynth-pop, children's music, V-pop\nsynth-pop, children's music, eurodance\nsynth-pop, children's music, retro\nsynth-pop, children's music, retro Chinese\nsynth-pop, children's music, retro East Asian\nsynth-pop, children's music, retro Soviet\nsynth-pop, children's music, tropical pop\nsynth-pop, chillwave, C-pop\nsynth-pop, chiptune\nsynth-pop, chiptune, 8-bit\nsynth-pop, chiptune, 80s new wave\nsynth-pop, chiptune, 80s video game\nsynth-pop, chiptune, Afro-electro\nsynth-pop, chiptune, Brazilian\nsynth-pop, chiptune, C-pop\nsynth-pop, chiptune, Central Asian pop\nsynth-pop, chiptune, Chinese New Year\nsynth-pop, chiptune, Christian\nsynth-pop, chiptune, Christian praise\nsynth-pop, chiptune, Christian worship\nsynth-pop, chiptune, EDM\nsynth-pop, chiptune, Filipino Pop\nsynth-pop, chiptune, French\nsynth-pop, chiptune, French pop\nsynth-pop, chiptune, German novelty\nsynth-pop, chiptune, Indian film music\nsynth-pop, chiptune, Indian folk\nsynth-pop, chiptune, J-pop\nsynth-pop, chiptune, J-rock\nsynth-pop, chiptune, Japanese\nsynth-pop, chiptune, K-pop\nsynth-pop, chiptune, Kannada romantic\nsynth-pop, chiptune, Nepali pop\nsynth-pop, chiptune, North African hip-hop\nsynth-pop, chiptune, Persian pop\nsynth-pop, chiptune, R&B\nsynth-pop, chiptune, Russian\nsynth-pop, chiptune, Shibuya-kei\nsynth-pop, chiptune, South Asian\nsynth-pop, chiptune, South Asian pop\nsynth-pop, chiptune, Soviet-era\nsynth-pop, chiptune, Tamil Christian\nsynth-pop, chiptune, Thai\nsynth-pop, chiptune, Thai pop\nsynth-pop, chiptune, Vietnamese pop\nsynth-pop, chiptune, Vocaloid\nsynth-pop, chiptune, ambient techno\nsynth-pop, chiptune, anime\nsynth-pop, chiptune, arena rock\nsynth-pop, chiptune, bhajan\nsynth-pop, chiptune, cartoon\nsynth-pop, chiptune, children's music\nsynth-pop, chiptune, conscious hip-hop\nsynth-pop, chiptune, dark wave\nsynth-pop, chiptune, dystopian\nsynth-pop, chiptune, electro-house\nsynth-pop, chiptune, electro-pop\nsynth-pop, chiptune, electronic\nsynth-pop, chiptune, eurodance\nsynth-pop, chiptune, filmi\nsynth-pop, chiptune, folk-dance\nsynth-pop, chiptune, funk\nsynth-pop, chiptune, happy hardcore\nsynth-pop, chiptune, hyperpop\nsynth-pop, chiptune, indie dance\nsynth-pop, chiptune, industrial\nsynth-pop, chiptune, industrial rock\nsynth-pop, chiptune, lo-fi\nsynth-pop, chiptune, lo-fi hip hop\nsynth-pop, chiptune, new wave\nsynth-pop, chiptune, novelty\nsynth-pop, chiptune, pop-rap\nsynth-pop, chiptune, progressive rock\nsynth-pop, chiptune, retro\nsynth-pop, chiptune, retro-futuristic\nsynth-pop, chiptune, techno\nsynth-pop, chiptune, theatrical\nsynth-pop, chiptune, theatrical rock\nsynth-pop, chiptune, trap\nsynth-pop, chiptune, trot\nsynth-pop, chiptune, video game music\nsynth-pop, choral, 80s\nsynth-pop, choral, cinematic\nsynth-pop, cinematic\nsynth-pop, cinematic ambient, Chinese rap\nsynth-pop, cinematic electronic\nsynth-pop, cinematic orchestral\nsynth-pop, cinematic pop\nsynth-pop, cinematic pop, K-pop, R&B\nsynth-pop, cinematic rock\nsynth-pop, cinematic rock, ambient\nsynth-pop, cinematic, 8-bit\nsynth-pop, cinematic, 80s\nsynth-pop, cinematic, 80s Eastern European\nsynth-pop, cinematic, 80s Eurodance\nsynth-pop, cinematic, 80s German Schlager\nsynth-pop, cinematic, 80s Soviet new wave\nsynth-pop, cinematic, 80s arena rock\nsynth-pop, cinematic, 80s electro\nsynth-pop, cinematic, 80s new wave\nsynth-pop, cinematic, 80s power ballad\nsynth-pop, cinematic, 80s rock\nsynth-pop, cinematic, 90s Eurodance\nsynth-pop, cinematic, Balkan pop\nsynth-pop, cinematic, C-pop\nsynth-pop, cinematic, Central Asian\nsynth-pop, cinematic, Central Asian folk\nsynth-pop, cinematic, Chinese fusion\nsynth-pop, cinematic, Christian contemporary\nsynth-pop, cinematic, Christian rock\nsynth-pop, cinematic, EBM\nsynth-pop, cinematic, EDM\nsynth-pop, cinematic, East Asian\nsynth-pop, cinematic, Eastern European folk\nsynth-pop, cinematic, Eurodance\nsynth-pop, cinematic, Finnish\nsynth-pop, cinematic, Finnish schlager\nsynth-pop, cinematic, German Schlager\nsynth-pop, cinematic, Greek folk\nsynth-pop, cinematic, Indian film music\nsynth-pop, cinematic, Indonesian pop\nsynth-pop, cinematic, Italian\nsynth-pop, cinematic, Italo-disco\nsynth-pop, cinematic, Latin\nsynth-pop, cinematic, Middle Eastern\nsynth-pop, cinematic, Mongolian\nsynth-pop, cinematic, Mongolian folk\nsynth-pop, cinematic, Persian\nsynth-pop, cinematic, Russian\nsynth-pop, cinematic, Russian chanson\nsynth-pop, cinematic, Russian estrada\nsynth-pop, cinematic, South Asian\nsynth-pop, cinematic, Soviet era\nsynth-pop, cinematic, Soviet estrada\nsynth-pop, cinematic, Tamil film music\nsynth-pop, cinematic, Tibetan opera\nsynth-pop, cinematic, Turkish\nsynth-pop, cinematic, Turkish pop\nsynth-pop, cinematic, Vocaloid\nsynth-pop, cinematic, action\nsynth-pop, cinematic, ambient\nsynth-pop, cinematic, ballad\nsynth-pop, cinematic, baroque\nsynth-pop, cinematic, big beat\nsynth-pop, cinematic, chiptune\nsynth-pop, cinematic, complextro\nsynth-pop, cinematic, cosmic\nsynth-pop, cinematic, cyberpunk\nsynth-pop, cinematic, dance-pop\nsynth-pop, cinematic, dark ambient\nsynth-pop, cinematic, dark wave\nsynth-pop, cinematic, devotional\nsynth-pop, cinematic, dream pop\nsynth-pop, cinematic, dream-pop\nsynth-pop, cinematic, dreamy\nsynth-pop, cinematic, dubstep\nsynth-pop, cinematic, electro-house\nsynth-pop, cinematic, electronic\nsynth-pop, cinematic, emotional\nsynth-pop, cinematic, epic\nsynth-pop, cinematic, estrada\nsynth-pop, cinematic, ethereal\nsynth-pop, cinematic, experimental\nsynth-pop, cinematic, folk\nsynth-pop, cinematic, future bass\nsynth-pop, cinematic, glam rock\nsynth-pop, cinematic, glitch\nsynth-pop, cinematic, gothic\nsynth-pop, cinematic, hardstyle\nsynth-pop, cinematic, hip-hop\nsynth-pop, cinematic, hyperpop\nsynth-pop, cinematic, industrial\nsynth-pop, cinematic, industrial rock\nsynth-pop, cinematic, lo-fi\nsynth-pop, cinematic, musical theater\nsynth-pop, cinematic, nu-disco\nsynth-pop, cinematic, operatic\nsynth-pop, cinematic, orchestral\nsynth-pop, cinematic, pop-rock\nsynth-pop, cinematic, power ballad\nsynth-pop, cinematic, power metal\nsynth-pop, cinematic, progressive house\nsynth-pop, cinematic, progressive rock\nsynth-pop, cinematic, retro\nsynth-pop, cinematic, retro-futuristic\nsynth-pop, cinematic, rock\nsynth-pop, cinematic, shoegaze\nsynth-pop, cinematic, stadium rock\nsynth-pop, cinematic, theatrical\nsynth-pop, cinematic, traditional Southeast Asian\nsynth-pop, cinematic, trance\nsynth-pop, cinematic, trot\nsynth-pop, cinematic, world fusion\nsynth-pop, cinematic, world music\nsynth-pop, city pop\nsynth-pop, city pop, 80s\nsynth-pop, city pop, 80s J-pop\nsynth-pop, city pop, 80s Japanese\nsynth-pop, city pop, 80s K-pop\nsynth-pop, city pop, 80s anime\nsynth-pop, city pop, 80s k-pop\nsynth-pop, city pop, 80s new age\nsynth-pop, city pop, 80s new wave\nsynth-pop, city pop, 80s retro-futuristic\nsynth-pop, city pop, 90s Mandopop\nsynth-pop, city pop, 90s lounge\nsynth-pop, city pop, Bollywood\nsynth-pop, city pop, C-pop\nsynth-pop, city pop, Cantopop\nsynth-pop, city pop, French pop\nsynth-pop, city pop, Italo disco\nsynth-pop, city pop, Italo-disco\nsynth-pop, city pop, J-pop\nsynth-pop, city pop, Japanese fusion\nsynth-pop, city pop, K-pop\nsynth-pop, city pop, Korean trot\nsynth-pop, city pop, Mandopop\nsynth-pop, city pop, R&B\nsynth-pop, city pop, Shibuya-kei\nsynth-pop, city pop, Southeast Asian\nsynth-pop, city pop, Vietnamese\nsynth-pop, city pop, Vocaloid\nsynth-pop, city pop, anime\nsynth-pop, city pop, anime soundtrack\nsynth-pop, city pop, anime theme\nsynth-pop, city pop, children's\nsynth-pop, city pop, chiptune\nsynth-pop, city pop, cinematic\nsynth-pop, city pop, dance-pop\nsynth-pop, city pop, dream pop\nsynth-pop, city pop, eurobeat\nsynth-pop, city pop, funk\nsynth-pop, city pop, gospel\nsynth-pop, city pop, latin pop\nsynth-pop, city pop, lo-fi R&B\nsynth-pop, city pop, new age\nsynth-pop, city pop, new jack swing\nsynth-pop, city pop, new wave\nsynth-pop, city pop, nu-disco\nsynth-pop, city pop, orchestral\nsynth-pop, city pop, retro\nsynth-pop, city pop, retro video game\nsynth-pop, city pop, retro-funk\nsynth-pop, city pop, retro-futuristic\nsynth-pop, city pop, synthwave\nsynth-pop, city pop, trance\nsynth-pop, city pop, vaporwave\nsynth-pop, city pop, video game\nsynth-pop, city pop, video game music\nsynth-pop, city pop, video game soundtrack\nsynth-pop, city pop, worldbeat\nsynth-pop, city-pop\nsynth-pop, city-pop, 80s\nsynth-pop, city-pop, Christmas\nsynth-pop, city-pop, K-pop\nsynth-pop, city-pop, chiptune\nsynth-pop, city-pop, dream-pop\nsynth-pop, city-pop, retro-futuristic\nsynth-pop, classical, retro\nsynth-pop, cloud rap\nsynth-pop, cloud rap, trap\nsynth-pop, cold wave\nsynth-pop, cold wave, French\nsynth-pop, cold wave, French new wave\nsynth-pop, cold wave, Italo-disco\nsynth-pop, cold wave, new wave\nsynth-pop, cold wave, retro-futuristic\nsynth-pop, coldwave\nsynth-pop, coldwave, 80s\nsynth-pop, coldwave, EBM\nsynth-pop, coldwave, French\nsynth-pop, coldwave, Italo\nsynth-pop, coldwave, Neue Deutsche Welle\nsynth-pop, coldwave, Russian post-punk\nsynth-pop, coldwave, Soviet-era\nsynth-pop, coldwave, Soviet-wave\nsynth-pop, coldwave, chiptune\nsynth-pop, coldwave, darkwave\nsynth-pop, coldwave, dream pop\nsynth-pop, coldwave, new wave\nsynth-pop, coldwave, post-punk\nsynth-pop, complextro\nsynth-pop, complextro, chiptune\nsynth-pop, complextro, cinematic\nsynth-pop, complextro, dubstep\nsynth-pop, complextro, hardstyle\nsynth-pop, complextro, lo-fi\nsynth-pop, contemporary Christian\nsynth-pop, contemporary R&B\nsynth-pop, cumbia, children's music\nsynth-pop, cumbia, eurodance\nsynth-pop, cyberpunk, C-pop\nsynth-pop, cyberpunk, EDM\nsynth-pop, cyberpunk, electronic\nsynth-pop, cyberpunk, hyperpop\nsynth-pop, cyberpunk, industrial\nsynth-pop, dance, C-pop\nsynth-pop, dance, EDM\nsynth-pop, dance-pop\nsynth-pop, dance-pop, C-pop\nsynth-pop, dance-pop, EDM\nsynth-pop, dance-pop, Eastern European\nsynth-pop, dance-pop, Eurodance\nsynth-pop, dance-pop, bilingual\nsynth-pop, dance-pop, cinematic\nsynth-pop, dance-pop, eurodance\nsynth-pop, dance-pop, progressive house\nsynth-pop, dance-pop, synthwave\nsynth-pop, dangdut\nsynth-pop, dark cabaret\nsynth-pop, dark pop, minimalist electronic\nsynth-pop, dark pop, trap\nsynth-pop, dark wave, 80s new wave\nsynth-pop, dark wave, EBM\nsynth-pop, dark wave, Neue Deutsche Welle\nsynth-pop, dark wave, hyperpop\nsynth-pop, darkwave\nsynth-pop, darkwave, 80s new wave\nsynth-pop, darkwave, EBM\nsynth-pop, darkwave, Italo-disco\nsynth-pop, darkwave, Neue Deutsche Welle\nsynth-pop, darkwave, Russian post-punk\nsynth-pop, darkwave, ambient\nsynth-pop, darkwave, cinematic\nsynth-pop, darkwave, coldwave\nsynth-pop, darkwave, electronic rock\nsynth-pop, darkwave, new wave\nsynth-pop, darkwave, post-punk\nsynth-pop, darkwave, retro-futuristic\nsynth-pop, deep house\nsynth-pop, deep house, Persian ambient\nsynth-pop, deep house, Russian\nsynth-pop, desert wave, Middle Eastern\nsynth-pop, devotional, 80s Bollywood\nsynth-pop, devotional, retro-futuristic\nsynth-pop, disco, Bengali film music\nsynth-pop, disco, C-pop\nsynth-pop, disco, Chinese New Year\nsynth-pop, disco, Christian pop\nsynth-pop, disco, Christmas pop\nsynth-pop, disco, Indian film music\nsynth-pop, disco, Indian folk\nsynth-pop, disco, Indian political\nsynth-pop, disco, Italian cartoon\nsynth-pop, disco, K-pop\nsynth-pop, disco, Mandopop\nsynth-pop, disco, Russian chanson\nsynth-pop, disco, South Asian film music\nsynth-pop, disco, South Asian pop\nsynth-pop, disco, Taiwanese pop\nsynth-pop, disco, Vietnamese pop\nsynth-pop, disco, children's gospel\nsynth-pop, disco, children's music\nsynth-pop, disco, funk\nsynth-pop, disco, novelty\nsynth-pop, disco, traditional Southeast Asian\nsynth-pop, disco-funk, C-pop\nsynth-pop, disco-funk, patriotic\nsynth-pop, disco-funk, pop\nsynth-pop, disco-funk, rock opera\nsynth-pop, downtempo electronica\nsynth-pop, dramatic pop-rock\nsynth-pop, dream pop\nsynth-pop, dream pop, 80s new wave\nsynth-pop, dream pop, Brazilian\nsynth-pop, dream pop, EBM\nsynth-pop, dream pop, Turkish\nsynth-pop, dream pop, city pop\nsynth-pop, dream pop, electronic rap\nsynth-pop, dream pop, electronic rock\nsynth-pop, dream pop, hyperpop\nsynth-pop, dream pop, industrial\nsynth-pop, dream pop, lo-fi\nsynth-pop, dream pop, new age\nsynth-pop, dream pop, new wave\nsynth-pop, dream pop, trance\nsynth-pop, dream pop, vaporwave\nsynth-pop, dreamy, JRPG\nsynth-pop, dreamy, electronic\nsynth-pop, dreamy, industrial\nsynth-pop, drum and bass\nsynth-pop, drum and bass, R&B\nsynth-pop, drum and bass, ambient\nsynth-pop, drum and bass, cinematic\nsynth-pop, drum and bass, emotional\nsynth-pop, drum and bass, neurofunk\nsynth-pop, dubstep\nsynth-pop, dubstep, C-pop\nsynth-pop, dubstep, EDM\nsynth-pop, dubstep, breakbeat\nsynth-pop, dubstep, chiptune\nsynth-pop, dubstep, cinematic\nsynth-pop, dubstep, electronic\nsynth-pop, dubstep, hardstyle\nsynth-pop, dubstep, trap\nsynth-pop, early house\nsynth-pop, educational\nsynth-pop, educational, children's\nsynth-pop, educational, chiptune\nsynth-pop, educational, pop\nsynth-pop, electro house, EDM\nsynth-pop, electro-funk, Kollywood\nsynth-pop, electro-house, K-pop\nsynth-pop, electro-house, cinematic\nsynth-pop, electro-house, cyberpunk\nsynth-pop, electro-industrial\nsynth-pop, electro-pop, EBM\nsynth-pop, electro-pop, Italo-disco\nsynth-pop, electro-pop, Russian hip-hop\nsynth-pop, electro-pop, chiptune\nsynth-pop, electro-pop, meme music\nsynth-pop, electronic C-pop\nsynth-pop, electronic dance music\nsynth-pop, electronic dance, C-pop\nsynth-pop, electronic dance, Middle Eastern\nsynth-pop, electronic dance, North African Arabic\nsynth-pop, electronic dance, South Asian fusion\nsynth-pop, electronic dance, emotional\nsynth-pop, electronic rock\nsynth-pop, electronic rock, C-pop\nsynth-pop, electronic rock, ambient\nsynth-pop, electronic rock, chiptune\nsynth-pop, electronic rock, hyperpop\nsynth-pop, electronic rock, industrial\nsynth-pop, electronic rock, melancholic\nsynth-pop, electronic rock, nu-metal\nsynth-pop, electronic rock, symphonic metal\nsynth-pop, electronic, Latin pop\nsynth-pop, electronic, Mandarin pop\nsynth-pop, electronic, Mandopop\nsynth-pop, electronic, Middle Eastern\nsynth-pop, electronic, Middle Eastern dance\nsynth-pop, electronic, Persian pop\nsynth-pop, electronic, Russian pop\nsynth-pop, electronic, ambient\nsynth-pop, electronic, dream pop\nsynth-pop, electronic, futuristic\nsynth-pop, electronic, hardstyle\nsynth-pop, electronic, hyperpop\nsynth-pop, electronic, lo-fi hip hop\nsynth-pop, electronic, pop-rock\nsynth-pop, electronic, quirky\nsynth-pop, electronic, reggaeton\nsynth-pop, electronic, trap\nsynth-pop, electronicore\nsynth-pop, electronicore, French rap\nsynth-pop, electronicore, hyperpop\nsynth-pop, emotional electronica\nsynth-pop, epic, Middle Eastern\nsynth-pop, estrada\nsynth-pop, estrada, 80s\nsynth-pop, estrada, 80s Russian\nsynth-pop, estrada, 80s pop\nsynth-pop, estrada, Eastern European\nsynth-pop, estrada, ballad\nsynth-pop, estrada, chiptune\nsynth-pop, estrada, cinematic\nsynth-pop, estrada, eurodance\nsynth-pop, estrada, industrial\nsynth-pop, estrada, lo-fi\nsynth-pop, estrada, nostalgic\nsynth-pop, estrada, power ballad\nsynth-pop, estrada, retro\nsynth-pop, estrada, retro-futuristic\nsynth-pop, estrada, theatrical\nsynth-pop, ethereal, glitch\nsynth-pop, ethereal, new-age\nsynth-pop, euro-pop, romanian pop\nsynth-pop, eurobeat\nsynth-pop, eurobeat, 80s\nsynth-pop, eurobeat, chiptune\nsynth-pop, eurobeat, italo-disco\nsynth-pop, eurodance\nsynth-pop, eurodance, 80s\nsynth-pop, eurodance, Christmas\nsynth-pop, eurodance, EBM\nsynth-pop, eurodance, Russian\nsynth-pop, eurodance, Russian pop\nsynth-pop, eurodance, Turkish\nsynth-pop, eurodance, children's music\nsynth-pop, eurodance, chiptune\nsynth-pop, eurodance, cinematic\nsynth-pop, eurodance, comedic\nsynth-pop, eurodance, cyberpunk\nsynth-pop, eurodance, folk\nsynth-pop, eurodance, happy hardcore\nsynth-pop, eurodance, hardstyle\nsynth-pop, eurodance, hip-hop\nsynth-pop, eurodance, hyperpop\nsynth-pop, eurodance, italo disco\nsynth-pop, eurodance, italo-disco\nsynth-pop, eurodance, j-pop\nsynth-pop, eurodance, maneles\nsynth-pop, eurodance, power metal\nsynth-pop, eurodance, retro-futuristic\nsynth-pop, eurodance, russian\nsynth-pop, eurodance, schlager\nsynth-pop, eurodance, theatrical\nsynth-pop, eurodance, trance\nsynth-pop, experimental, lo-fi hip hop\nsynth-pop, experimental, synthwave\nsynth-pop, fairytale, lullaby\nsynth-pop, festive, 80s\nsynth-pop, filmi, 80s\nsynth-pop, filmi, ambient\nsynth-pop, filmi, children's music\nsynth-pop, filmi, chiptune\nsynth-pop, filmi, lo-fi\nsynth-pop, filmi, nostalgic\nsynth-pop, filmi, retro\nsynth-pop, filmi, retro-futuristic\nsynth-pop, filmi, vaporwave\nsynth-pop, folk fusion, electronic dance\nsynth-pop, folk, Central Asian\nsynth-pop, folk, Eastern European\nsynth-pop, folk, ambient\nsynth-pop, folk, ballad\nsynth-pop, folk, chiptune\nsynth-pop, folk, melancholic\nsynth-pop, folk, operatic\nsynth-pop, folk, retro\nsynth-pop, folk, romantic\nsynth-pop, folk, shamanic\nsynth-pop, folk-pop\nsynth-pop, folk-pop, Central Asian\nsynth-pop, folk-pop, musical theatre\nsynth-pop, funk, chiptune\nsynth-pop, funk, country folk\nsynth-pop, funk, video game music\nsynth-pop, funk-pop, hyperpop\nsynth-pop, funk-rock, J-pop\nsynth-pop, funk-rock, chiptune\nsynth-pop, future bass\nsynth-pop, future bass, C-pop\nsynth-pop, future bass, Christmas\nsynth-pop, future bass, ambient\nsynth-pop, future bass, chiptune\nsynth-pop, future bass, cinematic\nsynth-pop, future bass, electronic\nsynth-pop, future bass, experimental\nsynth-pop, future bass, melodic EDM\nsynth-pop, future bass, pop-punk\nsynth-pop, future bass, rock\nsynth-pop, future pop, reggaeton\nsynth-pop, glam rock, new wave\nsynth-pop, glam rock, nu-disco\nsynth-pop, glitch, electronic\nsynth-pop, glitch, experimental\nsynth-pop, glitch, hyperpop\nsynth-pop, glitch, industrial\nsynth-pop, gospel, Italo-disco\nsynth-pop, gospel, chiptune\nsynth-pop, gospel, world music\nsynth-pop, gothic rock, 80s new wave\nsynth-pop, happy hardcore\nsynth-pop, happy hardcore, French pop\nsynth-pop, happy hardcore, chiptune\nsynth-pop, hard rock\nsynth-pop, hard rock, cinematic pop\nsynth-pop, hard trance\nsynth-pop, hardstyle\nsynth-pop, hardstyle, C-pop\nsynth-pop, hardstyle, EDM\nsynth-pop, hardstyle, Russian rap\nsynth-pop, hardstyle, ambient\nsynth-pop, hardstyle, cinematic\nsynth-pop, hardstyle, festive\nsynth-pop, hardstyle, gabber\nsynth-pop, hardstyle, happy hardcore\nsynth-pop, hardstyle, hardcore techno\nsynth-pop, hardstyle, industrial techno\nsynth-pop, hardstyle, trancecore\nsynth-pop, hardstyle, trap\nsynth-pop, heavy metal\nsynth-pop, hip hop\nsynth-pop, hip-hop\nsynth-pop, hip-hop, C-pop\nsynth-pop, hip-hop, Eurodance\nsynth-pop, hip-hop, Finnish pop\nsynth-pop, hip-hop, Mongolian pop\nsynth-pop, hip-hop, North African\nsynth-pop, hip-hop, Sinhala pop\nsynth-pop, hip-hop, ambient\nsynth-pop, hip-hop, chiptune\nsynth-pop, hip-hop, cinematic\nsynth-pop, hip-hop, electronic\nsynth-pop, hip-hop, orchestral rock\nsynth-pop, hip-hop, rock\nsynth-pop, hip-hop, vaporwave\nsynth-pop, horror soundtrack, 80s\nsynth-pop, horror, new wave\nsynth-pop, horror-cabaret, video game\nsynth-pop, horror-comedy, retro-futuristic\nsynth-pop, house, 80s\nsynth-pop, house, cinematic\nsynth-pop, house, retro\nsynth-pop, house, retro electronic\nsynth-pop, house, retro-electronic\nsynth-pop, house, retro-futuristic\nsynth-pop, humppa, 80s Finnish\nsynth-pop, hyperpop\nsynth-pop, hyperpop, C-pop\nsynth-pop, hyperpop, Eurodance\nsynth-pop, hyperpop, German electronic\nsynth-pop, hyperpop, Italo disco\nsynth-pop, hyperpop, J-core\nsynth-pop, hyperpop, J-pop\nsynth-pop, hyperpop, Latin percussion\nsynth-pop, hyperpop, Russian soul\nsynth-pop, hyperpop, Vietnamese pop\nsynth-pop, hyperpop, ambient\nsynth-pop, hyperpop, avant-garde\nsynth-pop, hyperpop, cinematic\nsynth-pop, hyperpop, electro\nsynth-pop, hyperpop, electro-pop\nsynth-pop, hyperpop, electronic\nsynth-pop, hyperpop, emo-rap\nsynth-pop, hyperpop, future bass\nsynth-pop, hyperpop, futuristic\nsynth-pop, hyperpop, hardstyle\nsynth-pop, hyperpop, industrial\nsynth-pop, hyperpop, lo-fi\nsynth-pop, hyperpop, metalcore\nsynth-pop, hyperpop, nightcore\nsynth-pop, hyperpop, rap\nsynth-pop, hyperpop, rock\nsynth-pop, hyperpop, theatrical\nsynth-pop, hyperpop, trance\nsynth-pop, hyperpop, vaporwave\nsynth-pop, indie pop, hyperpop\nsynth-pop, indie rock\nsynth-pop, indie rock, hyperpop, shoegaze\nsynth-pop, industrial metal\nsynth-pop, industrial metal, cinematic\nsynth-pop, industrial metalcore\nsynth-pop, industrial rock\nsynth-pop, industrial rock, EBM\nsynth-pop, industrial rock, ambient\nsynth-pop, industrial rock, cinematic\nsynth-pop, industrial rock, cyberpunk\nsynth-pop, industrial rock, dystopian\nsynth-pop, industrial, 80s retro-futuristic\nsynth-pop, industrial, Chinese pop\nsynth-pop, industrial, EBM\nsynth-pop, industrial, Middle Eastern\nsynth-pop, industrial, Russian\nsynth-pop, industrial, ambient\nsynth-pop, industrial, cinematic\nsynth-pop, industrial, emotional\nsynth-pop, industrial, hyperpop\nsynth-pop, italo-disco, coldwave\nsynth-pop, jazz, Arabic\nsynth-pop, klezmer, chiptune\nsynth-pop, laïko\nsynth-pop, lo-fi hip hop\nsynth-pop, lo-fi hip-hop\nsynth-pop, lo-fi, Central Asian\nsynth-pop, lo-fi, EBM\nsynth-pop, lo-fi, Hebrew pop\nsynth-pop, lo-fi, chiptune\nsynth-pop, lo-fi, cinematic\nsynth-pop, lo-fi, dream pop\nsynth-pop, lullaby\nsynth-pop, lullaby, piano ballad\nsynth-pop, melancholic, hyperpop\nsynth-pop, melodic cloud rap\nsynth-pop, melodic riddim\nsynth-pop, melodic techno\nsynth-pop, metalcore\nsynth-pop, metalcore, chiptune\nsynth-pop, metalcore, vaporwave\nsynth-pop, modern hip-hop\nsynth-pop, musical theater\nsynth-pop, musical theater, 80s\nsynth-pop, musical theater, Christmas pop\nsynth-pop, musical theater, German Schlager\nsynth-pop, musical theater, chiptune\nsynth-pop, musical theater, electronic\nsynth-pop, musical theater, novelty\nsynth-pop, musical theater, operatic\nsynth-pop, neo-soul\nsynth-pop, neurofunk\nsynth-pop, neurofunk, drum and bass\nsynth-pop, new age\nsynth-pop, new age, Chinese traditional\nsynth-pop, new age, chillout\nsynth-pop, new age, operatic\nsynth-pop, new age, video game soundtrack\nsynth-pop, new age, world music\nsynth-pop, new jack swing\nsynth-pop, new jack swing, 80s dance-pop\nsynth-pop, new jack swing, 80s funk\nsynth-pop, new jack swing, Christmas\nsynth-pop, new jack swing, Christmas pop\nsynth-pop, new jack swing, G-funk\nsynth-pop, new jack swing, Indian fusion\nsynth-pop, new jack swing, K-pop\nsynth-pop, new jack swing, R&B\nsynth-pop, new jack swing, Russian\nsynth-pop, new jack swing, children's music\nsynth-pop, new jack swing, city pop\nsynth-pop, new jack swing, dance-pop\nsynth-pop, new jack swing, funk\nsynth-pop, new jack swing, gospel\nsynth-pop, new jack swing, hip-house\nsynth-pop, new jack swing, kizomba\nsynth-pop, new jack swing, retro\nsynth-pop, new jack swing, vaporwave\nsynth-pop, new wave\nsynth-pop, new wave, 80s\nsynth-pop, new wave, 80s Soviet\nsynth-pop, new wave, 80s pop\nsynth-pop, new wave, Bengali pop\nsynth-pop, new wave, Brazilian pop\nsynth-pop, new wave, Chinese dialect\nsynth-pop, new wave, EBM\nsynth-pop, new wave, Eastern European\nsynth-pop, new wave, French pop\nsynth-pop, new wave, French pop-rock\nsynth-pop, new wave, Indonesian pop\nsynth-pop, new wave, Italian\nsynth-pop, new wave, Italo disco\nsynth-pop, new wave, Italo-disco\nsynth-pop, new wave, Latin pop\nsynth-pop, new wave, Latin pop-rock\nsynth-pop, new wave, Mandopop\nsynth-pop, new wave, Persian pop\nsynth-pop, new wave, Russian pop\nsynth-pop, new wave, South Asian fusion\nsynth-pop, new wave, South Asian pop\nsynth-pop, new wave, Soviet-era\nsynth-pop, new wave, aggressive\nsynth-pop, new wave, ambient\nsynth-pop, new wave, anthemic\nsynth-pop, new wave, arena pop\nsynth-pop, new wave, arena rock\nsynth-pop, new wave, art-pop\nsynth-pop, new wave, cabaret\nsynth-pop, new wave, chiptune\nsynth-pop, new wave, cinematic\nsynth-pop, new wave, city pop\nsynth-pop, new wave, cold wave\nsynth-pop, new wave, coldwave\nsynth-pop, new wave, comedy rock\nsynth-pop, new wave, dance-punk\nsynth-pop, new wave, dark wave\nsynth-pop, new wave, darkwave\nsynth-pop, new wave, disco\nsynth-pop, new wave, electro-rock\nsynth-pop, new wave, funk\nsynth-pop, new wave, gothic rock\nsynth-pop, new wave, hard rock\nsynth-pop, new wave, indie rock\nsynth-pop, new wave, industrial\nsynth-pop, new wave, industrial rock\nsynth-pop, new wave, post-punk\nsynth-pop, new wave, power metal\nsynth-pop, new wave, punk rock\nsynth-pop, new wave, rap-rock\nsynth-pop, new wave, retro\nsynth-pop, new wave, retro-futuristic\nsynth-pop, new wave, robotic\nsynth-pop, new wave, rock\nsynth-pop, new wave, rock en español\nsynth-pop, new wave, satirical\nsynth-pop, new wave, sophisti-pop\nsynth-pop, new wave, synth-rock\nsynth-pop, new wave, theatrical\nsynth-pop, new wave, worldbeat\nsynth-pop, new-age, cinematic\nsynth-pop, noise-rock, shoegaze\nsynth-pop, novelty music\nsynth-pop, novelty, children's music\nsynth-pop, novelty, lo-fi\nsynth-pop, novelty, power metal\nsynth-pop, nu-disco, French house\nsynth-pop, nu-disco, Italo disco\nsynth-pop, nu-disco, Latin pop\nsynth-pop, nu-disco, city pop\nsynth-pop, nu-disco, electro-funk\nsynth-pop, nu-metal\nsynth-pop, operatic, Indian fusion\nsynth-pop, orchestral\nsynth-pop, orchestral, Italo-disco\nsynth-pop, orchestral, anthemic\nsynth-pop, orchestral, chiptune\nsynth-pop, orchestral, patriotic\nsynth-pop, orchestral, power metal\nsynth-pop, piano ballad, theatrical pop\nsynth-pop, polka-pop, cabaret, rap-rock, pop-rock\nsynth-pop, pop ballad, Latin pop\nsynth-pop, pop, Punjabi\nsynth-pop, pop, children's music\nsynth-pop, pop-funk, lullaby\nsynth-pop, pop-punk\nsynth-pop, pop-punk, alternative rock\nsynth-pop, pop-punk, cartoon theme\nsynth-pop, pop-punk, chiptune\nsynth-pop, pop-punk, hardstyle\nsynth-pop, pop-punk, hyperpop\nsynth-pop, pop-punk, lo-fi hip hop\nsynth-pop, pop-punk, rap-rock\nsynth-pop, pop-punk, rock\nsynth-pop, pop-rap\nsynth-pop, pop-rap, atmospheric\nsynth-pop, pop-rap, vaporwave\nsynth-pop, pop-rock\nsynth-pop, pop-rock, 80s\nsynth-pop, pop-rock, 80s South Asian\nsynth-pop, pop-rock, 80s hard rock\nsynth-pop, pop-rock, C-pop\nsynth-pop, pop-rock, Chinese pop\nsynth-pop, pop-rock, Chinese rock\nsynth-pop, pop-rock, EDM\nsynth-pop, pop-rock, Filipino\nsynth-pop, pop-rock, K-pop\nsynth-pop, pop-rock, South Asian\nsynth-pop, pop-rock, Spanish\nsynth-pop, pop-rock, ambient\nsynth-pop, pop-rock, arena rock\nsynth-pop, pop-rock, ballad\nsynth-pop, pop-rock, children's music\nsynth-pop, pop-rock, cinematic\nsynth-pop, pop-rock, comedic\nsynth-pop, pop-rock, festive\nsynth-pop, pop-rock, hard rock\nsynth-pop, pop-rock, polka\nsynth-pop, pop-rock, worship\nsynth-pop, post-disco, funk\nsynth-pop, post-hardcore\nsynth-pop, post-hardcore, chiptune\nsynth-pop, post-hardcore, metalcore\nsynth-pop, post-punk\nsynth-pop, post-punk, Eastern European rock\nsynth-pop, post-punk, Russian\nsynth-pop, post-punk, Soviet new wave\nsynth-pop, post-punk, cinematic\nsynth-pop, post-punk, coldwave\nsynth-pop, post-punk, dark wave\nsynth-pop, post-punk, darkwave\nsynth-pop, post-punk, lo-fi\nsynth-pop, post-punk, retro-futuristic\nsynth-pop, post-punk, shoegaze\nsynth-pop, post-rock, shoegaze\nsynth-pop, power ballad, 80s\nsynth-pop, power ballad, 80s arena rock\nsynth-pop, power ballad, 80s rock\nsynth-pop, power ballad, cinematic\nsynth-pop, power ballad, theatrical rock\nsynth-pop, power metal\nsynth-pop, power metal, chiptune\nsynth-pop, power rock\nsynth-pop, power-pop\nsynth-pop, power-pop, 80s\nsynth-pop, power-pop, chiptune\nsynth-pop, power-pop, funk\nsynth-pop, progressive house\nsynth-pop, progressive house, Icelandic\nsynth-pop, progressive house, ambient\nsynth-pop, progressive house, chiptune\nsynth-pop, progressive house, cinematic\nsynth-pop, progressive house, experimental\nsynth-pop, progressive house, techno\nsynth-pop, progressive house, trance\nsynth-pop, progressive house, vaporwave\nsynth-pop, progressive metal\nsynth-pop, progressive trance\nsynth-pop, progressive trance, Arabic ambient\nsynth-pop, protest rock, electronic\nsynth-pop, psychedelic rock, world fusion\nsynth-pop, psychedelic, Middle Eastern\nsynth-pop, quiet storm, R&B\nsynth-pop, ragtime, Russian pop-rock\nsynth-pop, ragtime, ambient\nsynth-pop, rap, cinematic\nsynth-pop, rap, soul\nsynth-pop, rap-rock\nsynth-pop, reggae, Nepali pop\nsynth-pop, reggaeton, Latin pop\nsynth-pop, reggaeton, dancehall\nsynth-pop, reggaeton, dream pop\nsynth-pop, retro 80s, Taiwanese Hokkien pop\nsynth-pop, retro C-pop\nsynth-pop, retro K-pop\nsynth-pop, retro Korean trot\nsynth-pop, retro Nepali pop\nsynth-pop, retro Russian pop\nsynth-pop, retro Soviet, Italo-disco\nsynth-pop, retro pop, Bengali pop\nsynth-pop, retro video game, Chinese New Year\nsynth-pop, retro video game, Christmas\nsynth-pop, retro video game, children's music\nsynth-pop, retro video game, eurodance\nsynth-pop, retro wave, Soviet new wave\nsynth-pop, retro, 80s South Asian film music\nsynth-pop, retro, Arabic pop\nsynth-pop, retro, Bengali\nsynth-pop, retro, Bengali pop\nsynth-pop, retro, Central Asian\nsynth-pop, retro, Central Asian folk\nsynth-pop, retro, Central Asian pop\nsynth-pop, retro, Chinese\nsynth-pop, retro, City Pop\nsynth-pop, retro, Eastern European\nsynth-pop, retro, Eastern European folk\nsynth-pop, retro, Eurodance\nsynth-pop, retro, Gujarati\nsynth-pop, retro, Gujarati pop\nsynth-pop, retro, Halloween\nsynth-pop, retro, Indian fusion\nsynth-pop, retro, Italo-disco\nsynth-pop, retro, Middle Eastern\nsynth-pop, retro, Persian pop\nsynth-pop, retro, Russian\nsynth-pop, retro, South Asian\nsynth-pop, retro, South Asian film music\nsynth-pop, retro, South Asian pop\nsynth-pop, retro, South Indian\nsynth-pop, retro, South Indian film music\nsynth-pop, retro, Southeast Asian pop\nsynth-pop, retro, Soviet disco\nsynth-pop, retro, Soviet new wave\nsynth-pop, retro, Soviet wave\nsynth-pop, retro, Soviet-era\nsynth-pop, retro, Turkish\nsynth-pop, retro, children's music\nsynth-pop, retro, chiptune\nsynth-pop, retro, comedic\nsynth-pop, retro, dance\nsynth-pop, retro, estrada\nsynth-pop, retro, filmi\nsynth-pop, retro, lo-fi\nsynth-pop, retro, new wave\nsynth-pop, retro, novelty\nsynth-pop, retro, pop-rock\nsynth-pop, retro-funk, 80s\nsynth-pop, retro-funk, pop-rock\nsynth-pop, retro-futuristic\nsynth-pop, retro-futuristic, 80s\nsynth-pop, retro-futuristic, 80s Soviet\nsynth-pop, retro-futuristic, 80s synthwave\nsynth-pop, retro-futuristic, Arabic pop\nsynth-pop, retro-futuristic, Bengali film music\nsynth-pop, retro-futuristic, Bengali pop\nsynth-pop, retro-futuristic, Bollywood\nsynth-pop, retro-futuristic, Brazilian\nsynth-pop, retro-futuristic, C-pop\nsynth-pop, retro-futuristic, Central Asian folk\nsynth-pop, retro-futuristic, City Pop\nsynth-pop, retro-futuristic, EBM\nsynth-pop, retro-futuristic, Indian film music\nsynth-pop, retro-futuristic, Italo disco\nsynth-pop, retro-futuristic, Italo-disco\nsynth-pop, retro-futuristic, Latin-electro\nsynth-pop, retro-futuristic, Middle Eastern\nsynth-pop, retro-futuristic, Persian pop\nsynth-pop, retro-futuristic, Russian estrada\nsynth-pop, retro-futuristic, South Asian\nsynth-pop, retro-futuristic, South Asian film music\nsynth-pop, retro-futuristic, South Asian fusion\nsynth-pop, retro-futuristic, South Indian film music\nsynth-pop, retro-futuristic, Soviet new wave\nsynth-pop, retro-futuristic, Soviet pop\nsynth-pop, retro-futuristic, Soviet-era\nsynth-pop, retro-futuristic, Soviet-wave\nsynth-pop, retro-futuristic, Turkish\nsynth-pop, retro-futuristic, chiptune\nsynth-pop, retro-futuristic, city pop\nsynth-pop, retro-futuristic, darkwave\nsynth-pop, retro-futuristic, electro\nsynth-pop, retro-futuristic, electronic\nsynth-pop, retro-futuristic, estrada\nsynth-pop, retro-futuristic, eurodance\nsynth-pop, retro-futuristic, filmi\nsynth-pop, retro-futuristic, hardstyle\nsynth-pop, retro-futuristic, hyperpop\nsynth-pop, retro-futuristic, new wave\nsynth-pop, retro-futuristic, nu-disco\nsynth-pop, retro-futuristic, trot\nsynth-pop, retro-futuristic, video game\nsynth-pop, retro-futuristic, world music\nsynth-pop, retro-futuristic, worldbeat\nsynth-pop, retro-pop, world music\nsynth-pop, retro-rock, Vietnamese pop\nsynth-pop, retro-wave\nsynth-pop, retrowave, 80s\nsynth-pop, retrowave, atmospheric\nsynth-pop, retrowave, cinematic\nsynth-pop, retrowave, electronic\nsynth-pop, rock ballad\nsynth-pop, rock, 80s\nsynth-pop, rock, Eastern European\nsynth-pop, rock, Middle Eastern\nsynth-pop, rock, Persian pop\nsynth-pop, rock, South Asian pop\nsynth-pop, rock, hardstyle\nsynth-pop, rock, hip hop\nsynth-pop, romantic Russian pop\nsynth-pop, salsa\nsynth-pop, schlager\nsynth-pop, schlager, 80s\nsynth-pop, schlager, 80s euro pop\nsynth-pop, schlager, Eastern European\nsynth-pop, schlager, Finnish\nsynth-pop, schlager, novelty\nsynth-pop, schlager, theatrical\nsynth-pop, schlager-rock\nsynth-pop, sci-fi, lo-fi\nsynth-pop, sea shanty, novelty\nsynth-pop, shoegaze\nsynth-pop, shoegaze, Chinese ambient\nsynth-pop, shoegaze, alternative rock\nsynth-pop, shoegaze, chiptune\nsynth-pop, shoegaze, cinematic\nsynth-pop, shoegaze, dream pop\nsynth-pop, shoegaze, noise rock\nsynth-pop, shoegaze, noise-rock\nsynth-pop, shoegaze, post-rock\nsynth-pop, shoegaze, synth-rock\nsynth-pop, singer-songwriter, adult contemporary\nsynth-pop, ska, Russian chanson\nsynth-pop, smooth jazz, 80s\nsynth-pop, soft rock\nsynth-pop, soulful pop\nsynth-pop, sovietwave\nsynth-pop, space rock\nsynth-pop, spiritual, South Asian\nsynth-pop, spiritual, electronic\nsynth-pop, symphonic metal\nsynth-pop, symphonic metal, cinematic\nsynth-pop, symphonic rock\nsynth-pop, symphonic rock, ambient\nsynth-pop, symphonic rock, metalcore\nsynth-pop, synth-rock\nsynth-pop, synth-rock, experimental\nsynth-pop, synth-rock, industrial metal\nsynth-pop, synthwave\nsynth-pop, synthwave, Italo-disco\nsynth-pop, synthwave, K-pop\nsynth-pop, synthwave, Russian pop\nsynth-pop, synthwave, dream pop\nsynth-pop, synthwave, emo-pop\nsynth-pop, synthwave, eurodance\nsynth-pop, synthwave, new wave\nsynth-pop, synthwave, post-rock\nsynth-pop, synthwave, progressive house\nsynth-pop, synthwave, retrowave\nsynth-pop, synthwave, trance\nsynth-pop, techno\nsynth-pop, techno, dark wave\nsynth-pop, theatrical art pop, synthwave\nsynth-pop, theatrical pop\nsynth-pop, theatrical pop, cinematic\nsynth-pop, theatrical rock\nsynth-pop, theatrical rock, ambient ballad\nsynth-pop, theatrical rock, heavy metal\nsynth-pop, theatrical rock, lo-fi\nsynth-pop, theatrical, 80s\nsynth-pop, theatrical, 80s Eastern European\nsynth-pop, theatrical, 80s Russian estrada\nsynth-pop, theatrical, 80s Soviet\nsynth-pop, theatrical, 80s dance-pop\nsynth-pop, theatrical, 80s new wave\nsynth-pop, theatrical, 80s power ballad\nsynth-pop, theatrical, Central Asian\nsynth-pop, theatrical, Eastern European\nsynth-pop, theatrical, Halloween\nsynth-pop, theatrical, Middle Eastern\nsynth-pop, theatrical, Russian estrada\nsynth-pop, theatrical, Soviet-era\nsynth-pop, theatrical, campy\nsynth-pop, theatrical, cinematic\nsynth-pop, theatrical, comedic\nsynth-pop, theatrical, dark pop\nsynth-pop, theatrical, epic\nsynth-pop, theatrical, horror-themed\nsynth-pop, theatrical, operatic\nsynth-pop, theatrical, orchestral\nsynth-pop, theatrical, surf rock\nsynth-pop, theatrical, video game\nsynth-pop, trance\nsynth-pop, trance, Bollywood\nsynth-pop, trance, C-pop\nsynth-pop, trance, EBM\nsynth-pop, trance, EDM\nsynth-pop, trance, German rap\nsynth-pop, trance, Russian\nsynth-pop, trance, ambient\nsynth-pop, trance, chiptune\nsynth-pop, trance, electronic\nsynth-pop, trance, electronic pop\nsynth-pop, trance, electronic rock\nsynth-pop, trance, futurepop\nsynth-pop, trance, futuristic\nsynth-pop, trance, gothic rock\nsynth-pop, trance, hardstyle\nsynth-pop, trance, hyperpop\nsynth-pop, trance, progressive house\nsynth-pop, trance, techno\nsynth-pop, trap\nsynth-pop, trap, EDM\nsynth-pop, trap, French pop\nsynth-pop, trap, K-hip-hop\nsynth-pop, trap, ambient\nsynth-pop, trap, anime\nsynth-pop, trap, bilingual pop\nsynth-pop, trap, chiptune\nsynth-pop, trap, cinematic\nsynth-pop, trap, cloud rap\nsynth-pop, trap, emotional\nsynth-pop, trap, hyperpop\nsynth-pop, tribal house, chiptune\nsynth-pop, tropical house, electronic dance\nsynth-pop, trot\nsynth-pop, trot, 80s\nsynth-pop, trot, cinematic\nsynth-pop, trot, korean folk\nsynth-pop, turbo-folk\nsynth-pop, turbo-folk, chiptune\nsynth-pop, vaporwave, French\nsynth-pop, vaporwave, city pop\nsynth-pop, vaporwave, dream pop\nsynth-pop, vaporwave, electronic rock\nsynth-pop, vaporwave, hyperpop\nsynth-pop, vaporwave, lo-fi\nsynth-pop, video game music\nsynth-pop, video game music, 80s\nsynth-pop, video game music, cinematic\nsynth-pop, video game music, kawaii\nsynth-pop, video game, 80s\nsynth-pop, video game, 80s Japanese\nsynth-pop, world electronic\nsynth-pop, world fusion, video game music\nsynth-pop, world music\nsynth-pop, world music, Turkish pop\nsynth-pop, world music, new age\nsynth-pop, world music, retro\nsynth-pop, world music, rock\nsynth-pop, worldbeat, R&B\nsynth-pop, worldbeat, chiptune\nsynth-pop, worldbeat, cinematic\nsynth-pop, worldbeat, new jack swing\nsynth-pop, worldbeat, retro-futuristic\nsynth-pop, worship, 80s dance-pop\nsynth-pop, zouk, kompa\nsynth-punk\nsynth-punk EBM\nsynth-punk EBM darkwave\nsynth-punk alternative rock\nsynth-punk bitpop\nsynth-punk breakbeat\nsynth-punk chiptune\nsynth-punk chiptune digital hardcore\nsynth-punk coldwave\nsynth-punk cyberpunk\nsynth-punk dance-punk\nsynth-punk dance-rock\nsynth-punk electro-punk\nsynth-punk electro-punk funk-rock\nsynth-punk electro-rock\nsynth-punk electronic rock\nsynth-punk happy hardcore\nsynth-punk hyperpop\nsynth-punk indie rock\nsynth-punk industrial\nsynth-punk industrial rock\nsynth-punk lo-fi\nsynth-punk metalcore\nsynth-punk new wave\nsynth-punk noise rock\nsynth-punk pop-punk\nsynth-punk post-hardcore\nsynth-punk post-punk\nsynth-punk power-pop\nsynth-punk, Balkan brass\nsynth-punk, EBM, chiptune\nsynth-punk, EBM, darkwave\nsynth-punk, EBM, retro-futuristic\nsynth-punk, Neue Deutsche Welle\nsynth-punk, Neue Deutsche Welle, chiptune\nsynth-punk, chiptune, Neue Deutsche Welle\nsynth-punk, dream-pop\nsynth-punk, dream-pop, lo-fi\nsynth-punk, electro, hardcore hip-hop\nsynth-punk, electro-punk, hyperpop\nsynth-punk, hyperpop\nsynth-punk, new wave, punk rock\nsynth-punk, pop-punk, indie rock\nsynth-punk, vaporwave, industrial rock\nsynth-rap\nsynth-reggae\nsynth-rock\nsynth-rock 80s\nsynth-rock 80s anime\nsynth-rock 80s new wave\nsynth-rock 80s power metal\nsynth-rock 80s retro\nsynth-rock 80s retro-futuristic\nsynth-rock 80s video game\nsynth-rock C-pop\nsynth-rock Christian rock\nsynth-rock EBM\nsynth-rock EBM industrial\nsynth-rock J-pop\nsynth-rock J-rock\nsynth-rock J-rock anime\nsynth-rock Neue Deutsche Welle\nsynth-rock alternative metal\nsynth-rock alternative rock\nsynth-rock anime\nsynth-rock anime opening\nsynth-rock anime soundtrack\nsynth-rock anime theme\nsynth-rock arena rock\nsynth-rock baroque\nsynth-rock big beat\nsynth-rock cabaret\nsynth-rock chiptune\nsynth-rock chiptune Chinese opera\nsynth-rock chiptune J-rock\nsynth-rock chiptune anime\nsynth-rock chiptune cinematic\nsynth-rock chiptune dream pop\nsynth-rock chiptune industrial\nsynth-rock chiptune metal\nsynth-rock chiptune new wave\nsynth-rock chiptune post-punk\nsynth-rock chiptune power metal\nsynth-rock cinematic\nsynth-rock city pop\nsynth-rock coldwave post-punk\nsynth-rock cyberpunk\nsynth-rock cyberpunk chiptune\nsynth-rock cyberpunk j-rock\nsynth-rock cyberpunk metalcore\nsynth-rock dance-punk\nsynth-rock dark wave\nsynth-rock darkwave\nsynth-rock darkwave EBM\nsynth-rock darkwave chiptune\nsynth-rock darkwave coldwave\nsynth-rock darkwave goth rock\nsynth-rock darkwave industrial\nsynth-rock darkwave industrial metal\nsynth-rock dream pop\nsynth-rock ebm industrial\nsynth-rock electro-industrial\nsynth-rock electro-pop\nsynth-rock electro-punk\nsynth-rock electro-rock\nsynth-rock electronic worship\nsynth-rock electronicore\nsynth-rock electronicore cyberpunk\nsynth-rock emo\nsynth-rock emo pop-punk\nsynth-rock eurobeat\nsynth-rock eurodance\nsynth-rock funk\nsynth-rock funk disco\nsynth-rock funk-rock\nsynth-rock glam metal\nsynth-rock glam metal J-rock\nsynth-rock gothic rock\nsynth-rock hip-hop\nsynth-rock horror\nsynth-rock hyperpop\nsynth-rock hyperpop J-rock\nsynth-rock hyperpop chiptune\nsynth-rock hyperpop electronic rock\nsynth-rock hyperpop j-rock\nsynth-rock industrial\nsynth-rock industrial EBM\nsynth-rock industrial J-rock\nsynth-rock industrial chiptune\nsynth-rock industrial cyberpunk\nsynth-rock industrial darkwave\nsynth-rock industrial metal\nsynth-rock industrial post-punk\nsynth-rock industrial rap-rock\nsynth-rock industrial rock\nsynth-rock j-pop\nsynth-rock j-pop anime\nsynth-rock j-rock\nsynth-rock j-rock anime\nsynth-rock j-rock chiptune\nsynth-rock j-rock eurobeat\nsynth-rock j-rock video game\nsynth-rock jazz fusion\nsynth-rock metal\nsynth-rock metalcore\nsynth-rock new wave\nsynth-rock nu-metal\nsynth-rock opera\nsynth-rock pop-punk\nsynth-rock pop-rock\nsynth-rock post-hardcore\nsynth-rock post-punk\nsynth-rock post-punk coldwave\nsynth-rock post-punk darkwave\nsynth-rock post-punk new wave\nsynth-rock power metal\nsynth-rock power-pop\nsynth-rock progressive metal\nsynth-rock protest\nsynth-rock rap-rock\nsynth-rock retro new wave\nsynth-rock retrowave\nsynth-rock retrowave cyberpunk\nsynth-rock sci-fi\nsynth-rock space-rock\nsynth-rock trance\nsynth-rock trot\nsynth-rock turbo-folk\nsynth-rock vaporwave\nsynth-rock worship\nsynth-rock, 80s Cantopop, cinematic\nsynth-rock, 80s new wave, chiptune\nsynth-rock, EBM, cyberpunk\nsynth-rock, EBM, industrial\nsynth-rock, EBM, industrial rock\nsynth-rock, Italo-disco\nsynth-rock, J-pop, hyperpop\nsynth-rock, J-rock, anime\nsynth-rock, J-rock, chiptune\nsynth-rock, J-rock, cyberpunk\nsynth-rock, J-rock, industrial\nsynth-rock, J-rock, video game music\nsynth-rock, J-rock, video game soundtrack\nsynth-rock, chiptune, J-rock\nsynth-rock, chiptune, cinematic\nsynth-rock, chiptune, cyberpunk\nsynth-rock, city pop, 80s\nsynth-rock, cyberpunk, J-rock\nsynth-rock, cyberpunk, electronic\nsynth-rock, cyberpunk, industrial\nsynth-rock, darkwave, EBM\nsynth-rock, electro-metal, brostep\nsynth-rock, happy hardcore, video game music\nsynth-rock, hardstyle, dubstep\nsynth-rock, industrial dubstep, cinematic\nsynth-rock, industrial rock, J-rock\nsynth-rock, industrial, EBM\nsynth-rock, new wave, Eastern European\nsynth-rock, progressive metal, JRPG\nsynth-rock, trap, Neapolitan rap\nsynth-trap\nsynth-trot\nsynthesized cumbia\nsynthesized folk-pop\nsynthetic a cappella\nsynthetic cumbia-reggaeton\nsynthetic hip-hop\nsynthpop\nsynthpop cabaret\nsynthpop chiptune\nsynthpop eurodance trance\nsynthpop hardstyle trance\nsynthpop hip-hop\nsynthpop hyperpop glitchcore\nsynthpop lo-fi\nsynthpop lo-fi hip hop\nsynthpop rock\nsynthpop theatrical\nsynthpop vaporwave\nsynthpop, Latin pop\nsynthpop, Vocaloid, JRPG\nsynthpop, ambient, electronic\nsynthpop, anime, baroque pop\nsynthpop, big band, operatic\nsynthpop, children's music\nsynthpop, chiptune, pop-rock\nsynthpop, cinematic rock\nsynthpop, cinematic, hyperpop\nsynthpop, eurodance, trance\nsynthpop, funk, video game\nsynthpop, pop-rock, chiptune\nsynthpop, pop-rock, cinematic\nsynthpop, pop-rock, electronic\nsynthpop, video game soundtrack\nsynthrock\nsynthwave\nsynthwave C-pop\nsynthwave C-pop trance\nsynthwave Christmas\nsynthwave EBM\nsynthwave EBM chiptune\nsynthwave EBM dark synthpop\nsynthwave EBM darkwave\nsynthwave Islamic devotional\nsynthwave J-pop\nsynthwave R&B\nsynthwave R&B pop\nsynthwave R&B trap\nsynthwave alternative metal\nsynthwave alternative rock\nsynthwave ambient\nsynthwave ambient techno\nsynthwave ambient trap\nsynthwave ballad\nsynthwave cabaret\nsynthwave chillwave\nsynthwave chillwave vaporwave\nsynthwave chiptune\nsynthwave chiptune J-pop\nsynthwave chiptune JRPG\nsynthwave chiptune ambient\nsynthwave chiptune breakbeat\nsynthwave chiptune cinematic\nsynthwave chiptune demoscene\nsynthwave chiptune dream pop\nsynthwave chiptune electro\nsynthwave chiptune electro-funk\nsynthwave chiptune electro-rock\nsynthwave chiptune electronic rock\nsynthwave chiptune eurodance\nsynthwave chiptune industrial\nsynthwave chiptune power metal\nsynthwave chiptune trance\nsynthwave chiptune vaporwave\nsynthwave cinematic\nsynthwave city pop\nsynthwave complextro\nsynthwave country-rock\nsynthwave cumbia\nsynthwave cyberpunk\nsynthwave cyberpunk rock\nsynthwave darksynth\nsynthwave darksynth chiptune\nsynthwave darksynth retrowave\nsynthwave darkwave\nsynthwave darkwave EBM\nsynthwave darkwave chiptune\nsynthwave darkwave coldwave\nsynthwave darkwave cyberpunk\nsynthwave darkwave dream pop\nsynthwave darkwave gothic\nsynthwave darkwave gothic rock\nsynthwave darkwave industrial\nsynthwave darkwave post-punk\nsynthwave darkwave shoegaze\nsynthwave darkwave vaporwave\nsynthwave deep house\nsynthwave devotional\nsynthwave downtempo\nsynthwave dream pop\nsynthwave dream pop ambient\nsynthwave dream pop industrial\nsynthwave dream pop progressive rock\nsynthwave dream-pop\nsynthwave drum and bass\nsynthwave drum and bass hardstyle\nsynthwave dubstep\nsynthwave ebm chiptune\nsynthwave ebm darkwave\nsynthwave electro\nsynthwave electro ambient\nsynthwave electro chiptune\nsynthwave electro darkwave\nsynthwave electro house\nsynthwave electro minimal techno\nsynthwave electro trance\nsynthwave electro-funk\nsynthwave electro-industrial\nsynthwave electro-pop\nsynthwave electro-rock\nsynthwave electronic rock\nsynthwave electronicore\nsynthwave electropop\nsynthwave emo\nsynthwave emo-rap\nsynthwave epic\nsynthwave epic trailer\nsynthwave fairytale\nsynthwave fantasy\nsynthwave french rap\nsynthwave funk\nsynthwave funk rock\nsynthwave funk-rock\nsynthwave fusion\nsynthwave future bass\nsynthwave garage rock\nsynthwave glitch\nsynthwave gothic rock\nsynthwave hard rock\nsynthwave hardstyle\nsynthwave hip hop\nsynthwave hip-hop\nsynthwave horror\nsynthwave house\nsynthwave indie pop\nsynthwave indie rock\nsynthwave industrial\nsynthwave industrial EBM\nsynthwave industrial chiptune\nsynthwave industrial darksynth\nsynthwave industrial drum and bass\nsynthwave industrial electro-rock\nsynthwave industrial electronic rock\nsynthwave industrial hard trance\nsynthwave industrial metal\nsynthwave industrial metalcore\nsynthwave industrial power metal\nsynthwave industrial rock\nsynthwave industrial techno\nsynthwave instrumental rock\nsynthwave italo-disco\nsynthwave italo-disco chiptune\nsynthwave italo-disco ebm\nsynthwave j-pop\nsynthwave j-pop anime\nsynthwave j-pop video game\nsynthwave jazz fusion\nsynthwave lo-fi\nsynthwave lo-fi chiptune\nsynthwave lo-fi electronica\nsynthwave lo-fi hip hop\nsynthwave lo-fi hip-hop\nsynthwave lo-fi vaporwave\nsynthwave lounge\nsynthwave metal\nsynthwave metal chiptune\nsynthwave metalcore\nsynthwave metalcore dubstep\nsynthwave minimal techno\nsynthwave neo-soul\nsynthwave neurofunk\nsynthwave new age\nsynthwave noir\nsynthwave nu-disco\nsynthwave orchestral\nsynthwave pop\nsynthwave pop-punk\nsynthwave pop-rock\nsynthwave post-hardcore\nsynthwave post-punk\nsynthwave post-rock\nsynthwave power ballad\nsynthwave power metal\nsynthwave power metal chiptune\nsynthwave progressive electronic\nsynthwave progressive house\nsynthwave progressive rock\nsynthwave progressive trance\nsynthwave protest\nsynthwave rap\nsynthwave reggaeton\nsynthwave retrowave\nsynthwave retrowave ambient\nsynthwave retrowave chiptune\nsynthwave retrowave cinematic\nsynthwave retrowave synth-pop\nsynthwave rock\nsynthwave shoegaze\nsynthwave soul\nsynthwave speed metal\nsynthwave theatrical\nsynthwave trance\nsynthwave trance chiptune\nsynthwave trance eurodance\nsynthwave trap\nsynthwave trap EDM\nsynthwave trap chiptune\nsynthwave trap cinematic\nsynthwave trap dream pop\nsynthwave trap experimental\nsynthwave trap hardstyle\nsynthwave trap rock\nsynthwave tribal house\nsynthwave trip-hop\nsynthwave vaporwave\nsynthwave vaporwave ambient\nsynthwave vaporwave chillwave\nsynthwave vaporwave chiptune\nsynthwave vaporwave lo-fi hip-hop\nsynthwave vaporwave trap\nsynthwave worldbeat\nsynthwave, Arabic electronic\nsynthwave, Brazilian funk\nsynthwave, Brazilian pop-rock\nsynthwave, C-pop\nsynthwave, C-pop, dream pop\nsynthwave, C-pop, electronic\nsynthwave, Chinese hip-hop\nsynthwave, EBM\nsynthwave, EBM, ambient\nsynthwave, EBM, chiptune\nsynthwave, EBM, cinematic\nsynthwave, EBM, cinematic electronic\nsynthwave, EBM, cyberpunk\nsynthwave, EBM, dark techno\nsynthwave, EBM, darkwave\nsynthwave, EBM, electronic\nsynthwave, EBM, hard trance\nsynthwave, EBM, industrial\nsynthwave, EBM, industrial metal\nsynthwave, EBM, industrial rock\nsynthwave, EBM, retro-futuristic\nsynthwave, EBM, techno\nsynthwave, EBM, trance\nsynthwave, French rap\nsynthwave, Indian pop\nsynthwave, Italo disco\nsynthwave, Italo disco, vaporwave\nsynthwave, Italo-disco\nsynthwave, Italo-disco, 80s synth-pop\nsynthwave, Italo-disco, EBM\nsynthwave, Italo-disco, cinematic pop\nsynthwave, Italo-disco, electronic\nsynthwave, Italo-disco, neo-classical\nsynthwave, Italo-disco, retro-futuristic\nsynthwave, Italo-disco, synth-pop\nsynthwave, JRPG, electronic\nsynthwave, K-pop, lo-fi\nsynthwave, Mandopop, electronic\nsynthwave, Middle Eastern electronic\nsynthwave, Middle Eastern, Balkan\nsynthwave, Russian hip hop\nsynthwave, Soviet synth-pop\nsynthwave, V-Pop, trap\nsynthwave, Vocaloid, chiptune\nsynthwave, alternative rock\nsynthwave, alternative rock, nu-metal\nsynthwave, ambient, industrial\nsynthwave, atmospheric electronic\nsynthwave, carioca funk\nsynthwave, chanson, industrial rock\nsynthwave, children's chant, electronic\nsynthwave, chipbeat\nsynthwave, chiptune\nsynthwave, chiptune, EBM\nsynthwave, chiptune, Italo disco\nsynthwave, chiptune, Italo-disco\nsynthwave, chiptune, J-pop\nsynthwave, chiptune, J-rock\nsynthwave, chiptune, Vocaloid\nsynthwave, chiptune, ambient\nsynthwave, chiptune, cinematic\nsynthwave, chiptune, coldwave\nsynthwave, chiptune, cyberpunk\nsynthwave, chiptune, darkwave\nsynthwave, chiptune, electro\nsynthwave, chiptune, electronic\nsynthwave, chiptune, eurobeat\nsynthwave, chiptune, industrial\nsynthwave, chiptune, industrial rock\nsynthwave, chiptune, lo-fi\nsynthwave, chiptune, operatic pop\nsynthwave, chiptune, power metal\nsynthwave, chiptune, progressive house\nsynthwave, chiptune, retro-futuristic\nsynthwave, chiptune, synth-pop\nsynthwave, chiptune, trance\nsynthwave, chiptune, video game music\nsynthwave, cinematic\nsynthwave, cinematic ambient, Russian pop\nsynthwave, cinematic electronic\nsynthwave, cinematic, Arabic\nsynthwave, cinematic, JRPG\nsynthwave, cinematic, ambient\nsynthwave, cinematic, dark pop\nsynthwave, cinematic, darkwave\nsynthwave, cinematic, electro house\nsynthwave, cinematic, funk\nsynthwave, cinematic, industrial metal\nsynthwave, cinematic, operatic\nsynthwave, cinematic, rock\nsynthwave, city pop\nsynthwave, coldwave\nsynthwave, complextro\nsynthwave, complextro, EDM\nsynthwave, complextro, chiptune\nsynthwave, complextro, cinematic\nsynthwave, complextro, dubstep\nsynthwave, complextro, electronic\nsynthwave, complextro, hardstyle\nsynthwave, cumbia, lo-fi hip hop\nsynthwave, cyber-metal\nsynthwave, cyberpunk\nsynthwave, cyberpunk, EBM\nsynthwave, cyberpunk, J-rock\nsynthwave, cyberpunk, cinematic\nsynthwave, cyberpunk, darkwave\nsynthwave, cyberpunk, electronic\nsynthwave, cyberpunk, ethereal\nsynthwave, cyberpunk, hardstyle\nsynthwave, cyberpunk, hip-hop\nsynthwave, cyberpunk, industrial\nsynthwave, cyberpunk, industrial metal\nsynthwave, cyberpunk, rap\nsynthwave, cyberpunk, retrowave\nsynthwave, cyberpunk, symphonic metal\nsynthwave, cyberpunk, synth-pop\nsynthwave, cyberpunk, trance\nsynthwave, dark ambient\nsynthwave, dark pop\nsynthwave, darksynth\nsynthwave, darksynth, EBM\nsynthwave, darksynth, chiptune\nsynthwave, darksynth, cinematic\nsynthwave, darksynth, cyberpunk\nsynthwave, darksynth, industrial\nsynthwave, darkwave\nsynthwave, darkwave, 80s\nsynthwave, darkwave, EBM\nsynthwave, darkwave, ambient\nsynthwave, darkwave, chiptune\nsynthwave, darkwave, cinematic\nsynthwave, darkwave, coldwave\nsynthwave, darkwave, cyberpunk\nsynthwave, darkwave, dream pop\nsynthwave, darkwave, dreamwave\nsynthwave, darkwave, electronic\nsynthwave, darkwave, post-punk\nsynthwave, darkwave, retro-futuristic\nsynthwave, darkwave, retrowave\nsynthwave, drum and bass\nsynthwave, drum and bass, ambient\nsynthwave, drum and bass, chiptune\nsynthwave, drum and bass, cinematic\nsynthwave, drum and bass, ethereal\nsynthwave, drum and bass, trance\nsynthwave, dubstep\nsynthwave, dubstep, C-pop\nsynthwave, dubstep, ambient\nsynthwave, dubstep, cinematic\nsynthwave, dubstep, emotional synth\nsynthwave, electro house\nsynthwave, electro house, retrowave\nsynthwave, electro, 8-bit\nsynthwave, electro, retro-futuristic\nsynthwave, electro-industrial, ambient\nsynthwave, electro-pop\nsynthwave, electro-rock\nsynthwave, electronic rock\nsynthwave, electronic rock, dubstep\nsynthwave, electronic rock, future bass\nsynthwave, electronic rock, retrowave\nsynthwave, electronic, hip hop\nsynthwave, electronic, hip-hop\nsynthwave, electronic, lo-fi hip hop\nsynthwave, electronicore, dubstep\nsynthwave, eurobeat, chiptune\nsynthwave, eurodance\nsynthwave, eurodance, j-pop\nsynthwave, eurodance, medieval fantasy\nsynthwave, eurodance, retro-futuristic\nsynthwave, eurodance, trance\nsynthwave, experimental\nsynthwave, glitch hop\nsynthwave, grime\nsynthwave, happy hardcore\nsynthwave, happy hardcore, trance\nsynthwave, hard rock\nsynthwave, hard trance\nsynthwave, hard trance, industrial\nsynthwave, hardstyle\nsynthwave, hardstyle, cyberpunk\nsynthwave, hardstyle, trance\nsynthwave, hardwave\nsynthwave, hip hop\nsynthwave, hip-hop, C-pop\nsynthwave, horror soundtrack, 80s\nsynthwave, horror-cyberpunk\nsynthwave, hyperpop\nsynthwave, hyperpop, Mandopop\nsynthwave, hyperpop, chiptune\nsynthwave, hyperpop, metalcore\nsynthwave, industrial\nsynthwave, industrial metal\nsynthwave, industrial metalcore\nsynthwave, industrial rock\nsynthwave, industrial rock, cyber metal\nsynthwave, industrial, EBM\nsynthwave, industrial, chiptune\nsynthwave, industrial, cinematic\nsynthwave, industrial, cyberpunk\nsynthwave, industrial, electronic\nsynthwave, industrial, electronic rock\nsynthwave, industrial, video game music\nsynthwave, jazz-fusion\nsynthwave, jazz-fusion, lo-fi\nsynthwave, lo-fi hip hop\nsynthwave, metalcore\nsynthwave, neo-soul, vaporwave\nsynthwave, new wave\nsynthwave, new wave rock, eurodance\nsynthwave, orchestral electronic, electro\nsynthwave, orchestral metal\nsynthwave, orchestral, rock\nsynthwave, post-punk\nsynthwave, post-punk, Russian\nsynthwave, post-punk, Soviet era\nsynthwave, progressive electronic\nsynthwave, progressive metal\nsynthwave, progressive trance\nsynthwave, quirky pop\nsynthwave, retrowave, chiptune\nsynthwave, retrowave, cinematic\nsynthwave, retrowave, cyberpunk\nsynthwave, retrowave, darkwave\nsynthwave, retrowave, instrumental synth-pop\nsynthwave, retrowave, synth-pop\nsynthwave, shoegaze, hardstyle\nsynthwave, symphonic metal\nsynthwave, symphonic metal, Vocaloid\nsynthwave, symphonic metal, chiptune\nsynthwave, synth-pop, lo-fi\nsynthwave, trance\nsynthwave, trance, C-pop\nsynthwave, trance, chiptune\nsynthwave, trance, electronic pop\nsynthwave, trance, eurodance\nsynthwave, trance, hardstyle\nsynthwave, trance, industrial\nsynthwave, trance, video game music\nsynthwave, trance-pop\nsynthwave, trap\nsynthwave, trap, EDM\nsynthwave, trap, Mandopop\nsynthwave, trap, chillwave\nsynthwave, trap, chiptune\nsynthwave, trap, lo-fi hip hop\nsynthwave, uplifting trance\nsynthwave, video game music\nsynthwave, world fusion, psychedelic funk\nsynthwave, world music\ntabla\ntabla loop\ntaiko\ntaiko drum\ntaiko drumming\ntaiko rock\ntango\ntango Arabic pop\ntango J-pop\ntango J-pop fusion\ntango Latin pop\ntango Mandopop\ntango art song\ntango ballad\ntango ballad cumbia\ntango ballad, Latin rock, cumbia-ska\ntango ballad, cumbia, salsa\ntango ballad, korean trot\ntango ballad, salsa\ntango big band\ntango blues\ntango blues-rock\ntango bolero\ntango bolero cumbia\ntango bolero flamenco\ntango bolero mambo\ntango bolero salsa\ntango bossa nova\ntango cabaret\ntango carnaval fusion\ntango chanson\ntango chiptune\ntango classical\ntango classical klezmer\ntango comedy\ntango copla\ntango corrido\ntango cumbia\ntango cumbia bolero\ntango cumbia folk\ntango cumbia fusion\ntango cumbia salsa\ntango cumbia ska\ntango electronic\ntango electronica\ntango fado\ntango flamenco\ntango flamenco Latin folk\ntango flamenco eastern folk\ntango flamenco world music\ntango folk\ntango folk rock\ntango folk-rock\ntango funk\ntango funk jazz fusion\ntango funk-rock\ntango fusion\ntango gospel\ntango gypsy jazz\ntango hip-hop\ntango hip-hop fusion\ntango house\ntango jazz\ntango jazz MPB\ntango jazz classical\ntango jazz folk\ntango jazz orchestral pop\ntango jazz pop\ntango jazz world music\ntango jazz-pop\ntango klezmer\ntango klezmer big band\ntango klezmer cabaret\ntango klezmer video game\ntango lo-fi\ntango lounge\ntango mambo\ntango mambo big band\ntango merengue\ntango metal\ntango milonga\ntango musette\ntango noir\ntango noir, rock, Kayōkyoku\ntango nuevo\ntango nuevo, Latin ballad, danceable Latin\ntango nuevo, klezmer, orchestral\ntango opera\ntango orchestral\ntango polka\ntango pop\ntango pop rock\ntango pop-rock\ntango protest\ntango punk\ntango punk rock\ntango ragtime\ntango ranchera\ntango reggaeton\ntango rock\ntango rock klezmer\ntango rock opera\ntango rockabilly surf rock\ntango rumba flamenco\ntango salsa\ntango salsa protest\ntango samba\ntango samba-bolero\ntango schlager\ntango surf rock\ntango swing\ntango synth-pop\ntango synth-pop world music\ntango trap\ntango trap Latin pop\ntango waltz\ntango waltz flamenco\ntango waltz, disco-pop, theatrical\ntango world music\ntango zamba\ntango, Andean folk\ntango, Balkan folk, cabaret\ntango, Balkan folk, gypsy jazz\ntango, Balkan folk, pop-rock\ntango, Balkan folk, theatrical\ntango, Balkan folk, world music\ntango, Balkan, accordion\ntango, Balkan, cinematic\ntango, Balkan, theatrical\ntango, Christmas, operatic\ntango, European folk, cinematic\ntango, European folk, instrumental\ntango, European, instrumental\ntango, French chanson, Portuguese folk\ntango, French chanson, acoustic\ntango, Italian ballad, vintage\ntango, Kayōkyoku\ntango, Kayōkyoku, melancholic ballad\ntango, Korean trot\ntango, Latin art song\ntango, Latin ballad\ntango, Latin ballad, acoustic guitar\ntango, Latin folk\ntango, Latin folk, theatrical\ntango, Latin jazz\ntango, Latin jazz, Russian bard\ntango, Latin jazz, folk fusion\ntango, Latin jazz, vocal\ntango, Latin pop, cumbia\ntango, Latin ska, cumbia\ntango, Latin, ambient\ntango, Latin, ballad\ntango, Latin, choral\ntango, Latin, folk\ntango, Latin, orchestral\ntango, Latin, theatrical\ntango, MPB, European folk\ntango, MPB, classical guitar\ntango, MPB, folk\ntango, Middle Eastern, world music\ntango, Persian, cinematic\ntango, Spanish folk\ntango, Turkish art music, cinematic\ntango, Turkish folk, Arabesque\ntango, acoustic, flamenco\ntango, acoustic, folk\ntango, art pop, world music\ntango, art song, classical\ntango, balkan, theatrical\ntango, big band, Brazilian\ntango, big band, cabaret\ntango, big band, children's music\ntango, big band, cinematic\ntango, big band, mambo\ntango, big band, operatic\ntango, big band, theatrical\ntango, big band, vintage\ntango, blues, Latin\ntango, bolero\ntango, bolero, Brazilian\ntango, bolero, European folk\ntango, bolero, Latin\ntango, bolero, Latin ballad\ntango, bolero, cinematic\ntango, bolero, cumbia\ntango, bolero, holiday\ntango, bolero, mambo\ntango, bolero, orchestral\ntango, bossa nova, Brazilian\ntango, bossa nova, acoustic\ntango, brass band, ranchera\ntango, brass band, upbeat\ntango, breakbeat, ambient\ntango, cabaret, art song\ntango, canto-pop\ntango, carnavalito, folk\ntango, chanson, melancholic\ntango, chanson, theatrical\ntango, chanson, vintage\ntango, cinematic, Chinese fusion\ntango, cinematic, Japanese vocal\ntango, cinematic, Latin\ntango, cinematic, Latin narrative\ntango, cinematic, ambient\ntango, cinematic, big band\ntango, cinematic, classical\ntango, cinematic, dramatic\ntango, cinematic, emotional\ntango, cinematic, flamenco\ntango, cinematic, folk\ntango, cinematic, melancholic\ntango, cinematic, opera\ntango, cinematic, operatic\ntango, cinematic, orchestral\ntango, cinematic, power ballad\ntango, cinematic, theatrical\ntango, classical crossover\ntango, classical, Arabic pop\ntango, classical, choral\ntango, classical, cinematic\ntango, classical, dramatic\ntango, classical, dramatic folk\ntango, classical, folk\ntango, classical, operatic\ntango, classical, ragtime\ntango, classical, theatrical\ntango, copla, jazz\ntango, copla, operatic\ntango, copla, orchestral\ntango, corrido, Latin folk\ntango, disco-pop, 80s Polish\ntango, fado, romantic\ntango, flamenco, European folk\ntango, flamenco, acoustic\ntango, flamenco, art song\ntango, flamenco, cabaret\ntango, flamenco, cinematic\ntango, flamenco, classical guitar\ntango, flamenco, latin rock\ntango, flamenco, operatic\ntango, flamenco, theatrical\ntango, folk, Azerbaijani pop\ntango, folk, Eastern European\ntango, folk, Latin\ntango, folk, Latin American\ntango, folk, Turkish\ntango, folk, arabesque\ntango, folk, ballad\ntango, folk, chamber\ntango, folk, cinematic\ntango, folk, comedic\ntango, folk, cumbia\ntango, folk, instrumental\ntango, folk, operatic\ntango, folk, theatrical\ntango, folkloric Latin, melancholic\ntango, forró\ntango, forró, European folk\ntango, forró, cumbia\ntango, gospel\ntango, gypsy jazz, cinematic\ntango, gypsy jazz, classical crossover\ntango, jazz, K-pop\ntango, jazz, cinematic\ntango, klezmer, Eastern European folk\ntango, klezmer, classical fusion\ntango, klezmer, theatrical\ntango, korean opera, acoustic\ntango, lo-fi hip hop\ntango, lo-fi, Brazilian\ntango, lounge jazz\ntango, mambo\ntango, mambo, orchestral\ntango, mambo, theatrical\ntango, mariachi\ntango, melancholic ballad, Eastern European\ntango, merengue, bolero\ntango, milonga, Latin folk\ntango, milonga, acoustic\ntango, milonga, flamenco\ntango, milonga, folk\ntango, milonga, rock fusion\ntango, musical theater, cinematic\ntango, operatic folk\ntango, operatic pop, Latin ballad\ntango, operatic, Latin jazz\ntango, operatic, Soviet estrada\ntango, operatic, cinematic\ntango, operatic, dramatic\ntango, operatic, flamenco\ntango, operatic, orchestral\ntango, operatic, theatrical\ntango, orchestral, cabaret\ntango, orchestral, cinematic\ntango, orchestral, dramatic\ntango, orchestral, operatic\ntango, orchestral, theatrical\ntango, ragtime, Latin\ntango, regional Mexican, accordion\ntango, salsa\ntango, salsa, operatic\ntango, theatrical, acoustic\ntango, theatrical, choral\ntango, theatrical, comedic\ntango, theatrical, folk\ntango, theatrical, klezmer\ntango, theatrical, melancholic\ntango, theatrical, operatic\ntango, theatrical, violin-driven\ntango, trot\ntango, trot, jazz\ntango, world music, Latin\ntango, world music, Persian pop\ntango, world music, cinematic\ntango-ballad\ntango-bolero\ntango-chanson\ntango-cumbia\ntango-cumbia fusion\ntango-folk\ntango-gospel\ntango-jazz\ntango-jazz cabaret\ntango-jazz fusion\ntango-noir\ntango-pop\ntango-pop cabaret\ntango-rock\ntango-rock fusion\ntango-samba\ntango-ska\ntango-swing\ntango-waltz\ntango-waltz fusion\ntaqsim\ntarantella\ntarantella pizzica\ntarantella ska\ntarantella, cabaret, educational\ntarantella, educational, theatrical\ntarantella, operatic, Italian folk\ntarantella, orchestral, operatic\ntavern folk\ntearout dubstep\ntearout dubstep glitchcore\ntearout dubstep hardstyle\ntearout dubstep, hardstyle\ntech house\ntech house afro house\ntech house afro-house\ntech house bass house\ntech house chiptune\ntech house dancehall\ntech house darkwave\ntech house electro\ntech house electro-pop\ntech house flamenco\ntech house future bass\ntech house hip-hop\ntech house hip-house\ntech house latin\ntech house latin house\ntech house latin pop\ntech house minimal house\ntech house minimal techno\ntech house minimal techno hip-hop\ntech house oriental\ntech house progressive electronica\ntech house progressive house\ntech house protest\ntech house reggaeton\ntech house soulful house\ntech house trap\ntech house, French rap\ntech house, Latin house\ntech house, Latin urban\ntech house, Russian rap\ntech house, bass house\ntech house, cinematic progressive house\ntech house, dark electro\ntech house, dark electro-pop\ntech house, electro house\ntech house, electro, gabber\ntech house, ethnic electronica\ntech house, future bass, dream pop\ntech house, hard rock\ntech house, hardstyle\ntech house, hip-hop, Persian pop\ntech house, minimal electro\ntech house, minimal house\ntech house, minimal techno, lo-fi hip hop\ntech house, minimal wave\ntech house, neurofunk\ntech house, progressive house, hard dance\ntech house, progressive techno\ntech house, progressive trance\ntech house, reggaeton, Latin house\ntech house, reggaeton, Latin tech\ntech trance\ntech-funk\ntech-house\ntech-house Afro-house\ntech-house afro-house\ntech-house ambient\ntech-house bass house\ntech-house cinematic\ntech-house dancehall\ntech-house deep house\ntech-house electro-funk\ntech-house electro-pop\ntech-house flamenco\ntech-house gospel\ntech-house hip-hop\ntech-house j-pop\ntech-house latin\ntech-house latin house electro-rock\ntech-house latin pop\ntech-house latin urban\ntech-house mandopop\ntech-house mariachi\ntech-house minimal techno\ntech-house oud\ntech-house progressive house electro house\ntech-house progressive trance\ntech-house reggaeton\ntech-house trap\ntech-house tribal house\ntech-house vaporwave\ntech-house world music\ntech-house, Afropop, Amapiano\ntech-house, EBM, ambient\ntech-house, ambient, Middle Eastern\ntech-house, breakcore, ambient\ntech-house, cinematic, oud\ntech-house, cloud rap\ntech-house, cloud-rap, emo-trap\ntech-house, downtempo\ntech-house, drum and bass\ntech-house, electro-industrial\ntech-house, electro-techno\ntech-house, ethnic, psytrance\ntech-house, hard house\ntech-house, hard techno\ntech-house, hardstyle\ntech-house, hardstyle, big room\ntech-house, hardstyle, progressive trance\ntech-house, industrial techno\ntech-house, melodic techno\ntech-house, progressive house\ntech-house, progressive house, electronic\ntech-house, synth-pop\ntech-swing\ntech-trance\ntech-trance IDM\ntech-trance darkwave\ntech-trance progressive house\ntechnical death metal\ntechnical death metal chiptune\ntechnical death metal power metal\ntechnical death metal, symphonic power metal\ntechnical metal\ntechnical metal djent\ntechnical metal, J-rock\ntechnical rap\ntechnical thrash metal\ntechno\ntechno 90s\ntechno C-pop\ntechno EBM\ntechno EBM cinematic\ntechno EBM industrial\ntechno acid\ntechno acid house\ntechno ambient\ntechno big beat\ntechno breakbeat experimental\ntechno brega\ntechno cello\ntechno chiptune\ntechno chiptune trance\ntechno cinematic\ntechno dark electro\ntechno darkwave\ntechno darkwave EBM\ntechno darkwave electro-pop\ntechno darkwave post-punk\ntechno darkwave synth-pop\ntechno deep house\ntechno dubstep\ntechno duduk\ntechno ebm\ntechno ebm experimental\ntechno ebm industrial\ntechno ebm synth-pop\ntechno ebm trance\ntechno electro\ntechno electro house\ntechno electro industrial\ntechno electro-funk\ntechno electro-house\ntechno electro-pop\ntechno electro-punk\ntechno eurodance\ntechno future bass\ntechno gabber\ntechno garage rock\ntechno hard house\ntechno hard trance\ntechno hardstyle\ntechno hip-hop\ntechno hip-house\ntechno house\ntechno house breakbeat\ntechno house electro\ntechno house electro-pop\ntechno house hip-hop\ntechno industrial\ntechno industrial metal\ntechno industrial rock\ntechno j-core\ntechno jazz fusion\ntechno jungle tribal house\ntechno klezmer\ntechno lo-fi\ntechno lo-fi chiptune\ntechno novelty\ntechno orchestral\ntechno partyschlager\ntechno polka\ntechno pop\ntechno pop-rap\ntechno progressive house\ntechno progressive trance\ntechno protest\ntechno psytrance\ntechno punk rap\ntechno rap\ntechno rap battle\ntechno rave\ntechno rock\ntechno synthwave\ntechno synthwave ambient\ntechno synthwave dream pop\ntechno synthwave post-rock\ntechno tech house\ntechno tech-house\ntechno tech-trance\ntechno trance\ntechno trance chiptune\ntechno trance synthwave\ntechno trap\ntechno tribal house\ntechno world fusion\ntechno, 90s rave, drum and bass\ntechno, 90s trance\ntechno, Afrikaans rap\ntechno, Afro-Latin house\ntechno, Balkan, retro\ntechno, C-pop, electronic\ntechno, Chinese folk, rap\ntechno, Chinese hip hop\ntechno, EBM\ntechno, EBM, German\ntechno, EBM, J-pop\ntechno, EBM, acid\ntechno, EBM, ambient\ntechno, EBM, chiptune\ntechno, EBM, darkwave\ntechno, EBM, electronic\ntechno, EBM, ethereal\ntechno, EBM, industrial\ntechno, EBM, narrative electronic\ntechno, EBM, retro-futuristic\ntechno, EBM, synthwave\ntechno, EBM, tech-house\ntechno, EDM, Portuguese vocal\ntechno, EDM, theatrical\ntechno, French rap\ntechno, German rap\ntechno, IDM, ambient\ntechno, Italian rap\ntechno, Italo-disco, EBM\ntechno, Latin house\ntechno, Latin rap\ntechno, Middle Eastern\ntechno, Middle Eastern synth\ntechno, Middle Eastern, electronic\ntechno, Middle Eastern, ethereal\ntechno, Turkish folk\ntechno, Turkish rap\ntechno, Turkish vocal, electronic\ntechno, acid house\ntechno, acid house, breakcore\ntechno, acid house, electronic\ntechno, acid house, minimal techno\ntechno, acid house, trance\ntechno, acid techno\ntechno, acid techno, trance\ntechno, acid, trance\ntechno, ambient\ntechno, ambient drone, EBM\ntechno, ambient, Arabic vocal\ntechno, ambient, C-pop\ntechno, ambient, Chinese electronic\ntechno, ambient, Chinese spoken word\ntechno, ambient, Chinese vocal\ntechno, ambient, Russian vocal\ntechno, ambient, acid\ntechno, ambient, chiptune\ntechno, ambient, choral\ntechno, ambient, cinematic\ntechno, ambient, electronic\ntechno, ambient, emotional\ntechno, ambient, ethereal\ntechno, ambient, glitch\ntechno, ambient, industrial\ntechno, ambient, sci-fi\ntechno, ancient style\ntechno, arabic electronic\ntechno, baroque, electronic\ntechno, big room, ambient\ntechno, breakbeat, electronic\ntechno, breakcore\ntechno, breakcore, ambient\ntechno, breakcore, trance\ntechno, chiptune, German electronic\ntechno, chiptune, Italian vocal\ntechno, chiptune, J-pop\ntechno, chiptune, Middle Eastern\ntechno, chiptune, dystopian\ntechno, chiptune, electronic\ntechno, chiptune, rap\ntechno, chiptune, trance\ntechno, choral, electronic\ntechno, cinematic\ntechno, cinematic ambient, electronic\ntechno, cinematic, C-pop\ntechno, cinematic, Indian electronic\ntechno, cinematic, Italian vocal\ntechno, cinematic, ambient\ntechno, cinematic, chiptune\ntechno, cinematic, dark ambient\ntechno, cinematic, dark pop\ntechno, cinematic, dark wave\ntechno, cinematic, electronic\ntechno, cinematic, experimental\ntechno, cinematic, folk\ntechno, cinematic, folk-electronic\ntechno, cinematic, future dance\ntechno, cinematic, hardstyle\ntechno, cinematic, industrial\ntechno, cinematic, italo\ntechno, cinematic, lo-fi\ntechno, cinematic, operatic\ntechno, cinematic, progressive\ntechno, cinematic, psytrance\ntechno, cinematic, trance\ntechno, classical fusion\ntechno, classical, ballad\ntechno, cloud rap, dark electronic\ntechno, cloud rap, emo-trap\ntechno, cloud rap, vaporwave\ntechno, coldwave, Eastern European\ntechno, comedy, novelty\ntechno, complextro, dubstep\ntechno, conscious hip-hop\ntechno, cyberpunk, electronic\ntechno, cyberpunk, ethereal\ntechno, cyberpunk, trance\ntechno, dark electronic\ntechno, dark wave, Brazilian electronic\ntechno, dark wave, electronic\ntechno, darkwave\ntechno, darkwave, EBM\ntechno, darkwave, hyperpop\ntechno, darkwave, progressive techno\ntechno, darkwave, tech house\ntechno, dystopian, chiptune\ntechno, electro, EBM\ntechno, electro-house\ntechno, electronic dance, Telugu film music\ntechno, electronic, Czech rap\ntechno, electronic, Mandarin rap\ntechno, electronic, Middle Eastern\ntechno, electronic, Mongolian rap\ntechno, electronic, Turkish rap\ntechno, electronic, ambient\ntechno, electronic, chiptune\ntechno, electronic, dark wave\ntechno, electronic, sarcastic pop\ntechno, electronica, indie electronic\ntechno, emo-rap, cloud rap\ntechno, ethereal, Russian vocal\ntechno, ethereal, Ukrainian vocal\ntechno, ethereal, cinematic\ntechno, ethnic fusion\ntechno, ethnic fusion, industrial\ntechno, ethnic, Middle Eastern\ntechno, ethno-electronic\ntechno, eurodance\ntechno, eurodance, 90s\ntechno, folk, electronic\ntechno, folk, klezmer\ntechno, french, melancholic\ntechno, futuristic, electronic\ntechno, gabber, EDM\ntechno, gabber, ambient\ntechno, glitch, demoscene\ntechno, glitch, shoegaze\ntechno, hard house\ntechno, hard house, tribal electronic\ntechno, hard trance\ntechno, hard trance, EBM\ntechno, hard trance, gabber\ntechno, hardstyle\ntechno, hardstyle, C-pop\ntechno, hardstyle, R&B\ntechno, hardstyle, ambient\ntechno, hardstyle, cinematic\ntechno, hardstyle, electronic\ntechno, hardstyle, gabber\ntechno, hardstyle, rap\ntechno, hardstyle, trance\ntechno, hip-hop, electronic\ntechno, house, ambient\ntechno, hyperpop\ntechno, hyperpop, cinematic\ntechno, hǎnmài\ntechno, indie rock\ntechno, industrial, EBM\ntechno, industrial, ambient\ntechno, industrial, electronic\ntechno, latin percussion\ntechno, lo-fi hip hop\ntechno, lo-fi indie folk\ntechno, mashup\ntechno, nightcore, happy hardcore\ntechno, novelty, eurodance\ntechno, nu-disco\ntechno, nu-disco, ambient\ntechno, operatic, French\ntechno, orchestral trance, hardstyle\ntechno, pop-rock, happy hardcore\ntechno, post-hardcore, cinematic\ntechno, post-punk, EBM\ntechno, progressive house\ntechno, progressive house, dark ambient\ntechno, progressive house, darkwave\ntechno, progressive house, pop\ntechno, progressive house, tech-house\ntechno, progressive house, trance\ntechno, progressive trance\ntechno, progressive trance, cyberpunk\ntechno, progressive trance, electronic\ntechno, progressive trance, futurepop\ntechno, psychedelic, ambient\ntechno, psytrance, ambient\ntechno, psytrance, cinematic\ntechno, psytrance, hardstyle\ntechno, ragtime, French spoken word\ntechno, rap, electronic\ntechno, rap, synth-funk\ntechno, rave, EBM\ntechno, retro-futuristic, cyberpunk\ntechno, ritualistic, electronic\ntechno, spiritual, ambient\ntechno, synth-pop\ntechno, synth-pop, EBM\ntechno, synth-pop, ambient\ntechno, synth-pop, chiptune\ntechno, synth-pop, progressive house\ntechno, synthwave\ntechno, tech house\ntechno, tech house, minimal techno\ntechno, tech-house\ntechno, tech-house, ambient\ntechno, tech-house, cinematic\ntechno, tech-trance\ntechno, tech-trance, cinematic\ntechno, trance, Chinese electronic\ntechno, trance, EBM\ntechno, trance, K-pop\ntechno, trance, K-techno\ntechno, trance, Latin pop\ntechno, trance, ambient\ntechno, trance, chiptune\ntechno, trance, cinematic\ntechno, trance, electronic\ntechno, trance, hard house\ntechno, trance, hard techno\ntechno, trance, hardstyle\ntechno, trance, industrial\ntechno, trance, progressive house\ntechno, trance, world music\ntechno, trap\ntechno, trap, chiptune\ntechno, trap, electronic\ntechno, trap, experimental\ntechno, tribal house\ntechno, tribal house, ethnic\ntechno, tribal, ethnic\ntechno, trip-hop\ntechno, world fusion\ntechno, world fusion, electronic\ntechno, wuxia, electronic\ntechno-banda\ntechno-brega\ntechno-cumbia\ntechno-cumbia rock\ntechno-house\ntechno-pop\ntechno-punk\ntechno-rap\ntechno-reggaeton\ntechno-rock\ntechno-trance\ntechno-trap\ntechstep\ntechstep drum and bass\ntechstep jungle\nteddy\nteen pop\nteen pop-rock\ntejano\ntejano cumbia\ntender pop\ntender pop ballad\ntense pop\ntext-mex ballad\ntext-to-speech\ntextural ambient\ntextural percussion\ntextural sound design\nthe gaana\ntheater jazz\ntheatrical\ntheatrical Americana\ntheatrical Arabic\ntheatrical Arabic choral\ntheatrical Brazilian\ntheatrical Brazilian ballad\ntheatrical C-pop\ntheatrical C-pop, Brazilian folk\ntheatrical C-pop, forró\ntheatrical Chinese\ntheatrical Chinese folk\ntheatrical Chinese narrative\ntheatrical Chinese rock\ntheatrical Christian\ntheatrical Christian ballad\ntheatrical Christian rock\ntheatrical Christmas\ntheatrical Dutch\ntheatrical Dutch ballad\ntheatrical Dutch levenslied\ntheatrical Dutch narrative\ntheatrical Dutch rock\ntheatrical Fado\ntheatrical French carol\ntheatrical French pop\ntheatrical German\ntheatrical German Christmas\ntheatrical German comedy\ntheatrical Greek\ntheatrical Greek art song\ntheatrical Greek ballad\ntheatrical Greek children's\ntheatrical Greek children's music\ntheatrical Greek pop\ntheatrical Greek, Latin, Balkan\ntheatrical Italian\ntheatrical Italian art song\ntheatrical Italian ballad\ntheatrical Italian children's music\ntheatrical Italian march\ntheatrical Italian narrative\ntheatrical J-pop\ntheatrical J-rock\ntheatrical K-ballad\ntheatrical Latin\ntheatrical Latin Christian\ntheatrical Latin ballad\ntheatrical Latin folk\ntheatrical Latin jazz\ntheatrical Latin pop\ntheatrical Latin rock\ntheatrical MPB\ntheatrical Mandopop\ntheatrical R&B\ntheatrical Russian ballad\ntheatrical Russian romance\ntheatrical Spanish\ntheatrical Spanish anthem\ntheatrical Spanish ballad\ntheatrical Turkish pop\ntheatrical Turkish waltz\ntheatrical Western\ntheatrical a cappella\ntheatrical acapella\ntheatrical accordion\ntheatrical acoustic\ntheatrical acoustic ballad\ntheatrical acoustic pop\ntheatrical acoustic rock\ntheatrical alt-rock\ntheatrical alternative rock\ntheatrical ambient\ntheatrical anime\ntheatrical anthem\ntheatrical arabic jazz\ntheatrical art song\ntheatrical art song, cinematic, big band\ntheatrical art song, experimental jazz, big band\ntheatrical art-pop\ntheatrical art-pop cabaret\ntheatrical art-rock\ntheatrical art-rock, soul, funk\ntheatrical art-song\ntheatrical art-song jazz\ntheatrical audio drama\ntheatrical ballad\ntheatrical ballad salsa\ntheatrical ballad tango\ntheatrical ballad, Brazilian gospel samba\ntheatrical ballad, German Schlager, polka\ntheatrical ballad, Latin jazz\ntheatrical ballad, Latin jazz, mambo\ntheatrical ballad, Latin, tango\ntheatrical ballad, big band\ntheatrical ballad, big band jazz\ntheatrical ballad, big band mambo\ntheatrical ballad, big band swing\ntheatrical ballad, big band swing, funk\ntheatrical ballad, big band, choral\ntheatrical ballad, big band, cinematic pop\ntheatrical ballad, big band, operatic\ntheatrical ballad, cabaret-pop\ntheatrical ballad, cinematic, dystopian\ntheatrical ballad, flamenco, cinematic\ntheatrical ballad, mambo, big band\ntheatrical ballad, mambo, salsa\ntheatrical ballad, polka, ska\ntheatrical ballad, rockabilly, swing\ntheatrical ballad, salsa\ntheatrical ballad, salsa, cinematic\ntheatrical ballad, samba\ntheatrical ballad, samba-rock\ntheatrical baritone\ntheatrical baroque\ntheatrical big band\ntheatrical blues\ntheatrical blues ballad\ntheatrical blues gospel\ntheatrical blues jazz\ntheatrical blues rock\ntheatrical blues swing\ntheatrical bolero\ntheatrical boogie-woogie\ntheatrical bossa nova\ntheatrical brass\ntheatrical c-pop\ntheatrical cabaret\ntheatrical cabaret rock\ntheatrical cabaret swing\ntheatrical cabaret, Latin pop, flamenco\ntheatrical cartoon\ntheatrical cello\ntheatrical cello, Balkan folk, cabaret\ntheatrical chamber\ntheatrical chamber folk\ntheatrical chamber music\ntheatrical chanson\ntheatrical chanson tango\ntheatrical children's\ntheatrical children's music\ntheatrical children's musical\ntheatrical choir\ntheatrical choral\ntheatrical christmas\ntheatrical cinema\ntheatrical cinematic\ntheatrical circus\ntheatrical classical\ntheatrical comedy\ntheatrical copla\ntheatrical country\ntheatrical crooner\ntheatrical cumbia\ntheatrical cumbia rock\ntheatrical cumbia ska\ntheatrical cumbia-ska\ntheatrical dark ambient\ntheatrical dark pop\ntheatrical dark rock\ntheatrical educational\ntheatrical electro-pop\ntheatrical electronic\ntheatrical electronic, Chinese-style\ntheatrical enka\ntheatrical epic\ntheatrical fairytale\ntheatrical fanfare\ntheatrical fantasy\ntheatrical film score\ntheatrical flamenco\ntheatrical folk\ntheatrical folk blues\ntheatrical folk cabaret\ntheatrical folk cumbia\ntheatrical folk fusion\ntheatrical folk jazz\ntheatrical folk klezmer\ntheatrical folk opera\ntheatrical folk pop\ntheatrical folk protest\ntheatrical folk rock\ntheatrical folk rockabilly\ntheatrical folk tango\ntheatrical folk-blues\ntheatrical folk-country\ntheatrical folk-fusion\ntheatrical folk-gospel\ntheatrical folk-jazz\ntheatrical folk-pop\ntheatrical folk-punk\ntheatrical folk-rock\ntheatrical funk\ntheatrical funk soul\ntheatrical funk-rock\ntheatrical fusion\ntheatrical gospel\ntheatrical gothic\ntheatrical guzheng\ntheatrical hard rock\ntheatrical hard rock boogie-woogie\ntheatrical harp\ntheatrical heavy metal\ntheatrical hip hop\ntheatrical hip-hop\ntheatrical hip-hop folk\ntheatrical hip-hop orchestral pop\ntheatrical holiday\ntheatrical horror\ntheatrical horror-comedy\ntheatrical house\ntheatrical indie\ntheatrical indie folk\ntheatrical indie pop\ntheatrical indie pop jazz\ntheatrical indie rock\ntheatrical industrial\ntheatrical instrumental\ntheatrical jazz\ntheatrical jazz blues\ntheatrical jazz cabaret\ntheatrical jazz gospel\ntheatrical jazz hop\ntheatrical jazz lounge\ntheatrical jazz soul\ntheatrical jazz-hop\ntheatrical jazz-pop\ntheatrical jazz-rap\ntheatrical jazz-rock\ntheatrical jazz-soul\ntheatrical jingle\ntheatrical klezmer\ntheatrical lo-fi\ntheatrical lounge\ntheatrical lounge funk\ntheatrical lounge jazz\ntheatrical lullaby\ntheatrical mambo\ntheatrical march\ntheatrical melancholy\ntheatrical metal\ntheatrical metal polka\ntheatrical metalcore symphonic rock\ntheatrical minimalism\ntheatrical music\ntheatrical musical\ntheatrical narrative\ntheatrical new wave\ntheatrical noir\ntheatrical novelty\ntheatrical nursery rhyme\ntheatrical opera\ntheatrical orchestral\ntheatrical orchestral cabaret\ntheatrical orchestral novelty\ntheatrical organ\ntheatrical organ rock\ntheatrical organ, classical, Thai traditional\ntheatrical oud\ntheatrical parody\ntheatrical percussion\ntheatrical piano\ntheatrical piano ballad\ntheatrical piano ballad swing jazz\ntheatrical piano ballad, big band jazz\ntheatrical piano ballad, lounge jazz\ntheatrical piano ballad, pub rock, cinematic rock\ntheatrical piano ballad, samba-bossa nova\ntheatrical piano ballad, vocal jazz\ntheatrical piano rock\ntheatrical piano, big band swing\ntheatrical piano, lounge jazz, cabaret\ntheatrical piano, operatic vocal, enka\ntheatrical piano, samba, ragtime\ntheatrical piano, samba-jazz\ntheatrical polka\ntheatrical polka-rock\ntheatrical polka-swing\ntheatrical pop\ntheatrical pop 90s R&B\ntheatrical pop blues\ntheatrical pop cabaret\ntheatrical pop cabaret tango\ntheatrical pop calypso\ntheatrical pop chanson\ntheatrical pop chiptune\ntheatrical pop darkwave\ntheatrical pop funk\ntheatrical pop gospel\ntheatrical pop gypsy jazz swing\ntheatrical pop industrial\ntheatrical pop jazz\ntheatrical pop jazz lounge\ntheatrical pop latin\ntheatrical pop lounge\ntheatrical pop lounge jazz\ntheatrical pop neo-soul\ntheatrical pop rock\ntheatrical pop soul\ntheatrical pop tango\ntheatrical pop waltz\ntheatrical pop world music\ntheatrical pop, East Asian fusion\ntheatrical pop, Eastern European folk, dance\ntheatrical pop, European chanson\ntheatrical pop, European folk, C-pop\ntheatrical pop, European folk, cinematic\ntheatrical pop, European folk, cinematic pop\ntheatrical pop, European folk, orchestral pop-rock\ntheatrical pop, French hip-hop, soulful R&B\ntheatrical pop, Javanese folk, comedic music\ntheatrical pop, Latin big band\ntheatrical pop, Latin pop\ntheatrical pop, Latin pop, Eastern European pop\ntheatrical pop, Latin pop, ska\ntheatrical pop, Latin pop, world music\ntheatrical pop, Latin-pop, cinematic\ntheatrical pop, R&B\ntheatrical pop, Russian estrada\ntheatrical pop, Soviet estrada, orchestral pop\ntheatrical pop, big band jazz\ntheatrical pop, big band swing\ntheatrical pop, big band, cinematic\ntheatrical pop, big band, mambo\ntheatrical pop, cabaret, polka\ntheatrical pop, chiptune, video game soundtrack\ntheatrical pop, cinematic rock\ntheatrical pop, cinematic, cabaret\ntheatrical pop, circus music, avant-garde\ntheatrical pop, electro-funk\ntheatrical pop, electro-pop, EDM\ntheatrical pop, estrada\ntheatrical pop, estrada, 80s Eastern European\ntheatrical pop, estrada, Eastern European\ntheatrical pop, estrada, chiptune\ntheatrical pop, estrada, cinematic\ntheatrical pop, estrada, cinematic pop\ntheatrical pop, estrada, operatic\ntheatrical pop, estrada, orchestral\ntheatrical pop, estrada, pop-rock\ntheatrical pop, estrada, synth ballad\ntheatrical pop, future bass\ntheatrical pop, genre-bending, Christmas\ntheatrical pop, happy hardcore, eurodance\ntheatrical pop, hip-hop\ntheatrical pop, industrial rock, synth-pop, gothic rock\ntheatrical pop, mambo\ntheatrical pop, mariachi, free jazz\ntheatrical pop, nu-disco\ntheatrical pop, psychedelic pop, exotica\ntheatrical pop, psychedelic rock\ntheatrical pop, retro pop, estrada\ntheatrical pop, rock medley, funk\ntheatrical pop, rock opera, C-pop\ntheatrical pop, rockabilly, swing\ntheatrical pop, salsa, Latin ballad\ntheatrical pop, schlager\ntheatrical pop, tango, Eastern European\ntheatrical pop, tango, cinematic\ntheatrical pop, vaporwave, lo-fi hip-hop\ntheatrical pop-R&B\ntheatrical pop-funk\ntheatrical pop-punk\ntheatrical pop-punk cabaret rock\ntheatrical pop-rap\ntheatrical pop-rock\ntheatrical pop-rock cabaret\ntheatrical pop-rock funk\ntheatrical pop-rock jazz\ntheatrical pop-soul\ntheatrical power ballad\ntheatrical power pop\ntheatrical power-pop\ntheatrical protest\ntheatrical protest folk-rock\ntheatrical protest hip-hop\ntheatrical protest rock\ntheatrical psychedelic\ntheatrical psychedelic rock\ntheatrical punk\ntheatrical punk rock\ntheatrical punk rock surf rock\ntheatrical punk rock, big band swing\ntheatrical ragtime\ntheatrical retro\ntheatrical ritual\ntheatrical rock\ntheatrical rock blues\ntheatrical rock boogie-woogie\ntheatrical rock cabaret\ntheatrical rock cabaret blues\ntheatrical rock cabaret punk\ntheatrical rock cabaret ska\ntheatrical rock cabaret tango\ntheatrical rock chanson\ntheatrical rock chiptune\ntheatrical rock circus-punk\ntheatrical rock flamenco\ntheatrical rock flamenco cabaret\ntheatrical rock folk\ntheatrical rock funk-rock\ntheatrical rock gypsy punk\ntheatrical rock klezmer\ntheatrical rock novelty\ntheatrical rock opera\ntheatrical rock pop-punk\ntheatrical rock power metal\ntheatrical rock salsa\ntheatrical rock swing\ntheatrical rock tango\ntheatrical rock tango cabaret\ntheatrical rock world music\ntheatrical rock, Chinese rock, big band\ntheatrical rock, Latin rock\ntheatrical rock, Latin rock, world music\ntheatrical rock, Middle Eastern folk\ntheatrical rock, Middle Eastern fusion\ntheatrical rock, Schlager\ntheatrical rock, cabaret rock, boogie-woogie\ntheatrical rock, cabaret, boogie-woogie\ntheatrical rock, chiptune, power metal\ntheatrical rock, dangdut\ntheatrical rock, heavy metal, cabaret\ntheatrical rock, hyperpop, C-pop\ntheatrical rock, polka, rock\ntheatrical rock, rockabilly, doo-wop\ntheatrical rockabilly\ntheatrical rumba\ntheatrical salsa\ntheatrical samba\ntheatrical sci-fi\ntheatrical sci-fi rock\ntheatrical score\ntheatrical sea shanty\ntheatrical shanty\ntheatrical show tune\ntheatrical show tune world music\ntheatrical show tune, big band swing\ntheatrical show tune, video game music, honky-tonk\ntheatrical showtune\ntheatrical singer-songwriter\ntheatrical soul\ntheatrical soul funk\ntheatrical soul jazz\ntheatrical spoken word\ntheatrical spoken-word\ntheatrical string\ntheatrical swing\ntheatrical swing jazz\ntheatrical swing pop\ntheatrical swing-pop\ntheatrical synth\ntheatrical synth-pop\ntheatrical tango\ntheatrical tango ballad\ntheatrical tango cabaret\ntheatrical tango-waltz\ntheatrical torch song\ntheatrical trap\ntheatrical trap-pop\ntheatrical tribal\ntheatrical trip-hop\ntheatrical trot\ntheatrical ukulele\ntheatrical violin\ntheatrical violin, gypsy jazz, tango\ntheatrical vocal\ntheatrical voice\ntheatrical waltz\ntheatrical western\ntheatrical western, schlager\ntheatrical whimsy\ntheatrical world\ntheatrical world fusion\ntheatrical world music\ntheatrical worship\ntheatrical, Balkan, cinematic\ntheatrical, German, Christmas\ntheatrical, melancholic, cabaret\ntheatrical, melancholic, orchestral\nthird-wave ska\nthrash metal\nthrash metal J-rock\nthrash metal alternative rock\nthrash metal bluegrass fusion\nthrash metal chiptune\nthrash metal cumbia\nthrash metal cumbia rock\nthrash metal death metal\nthrash metal folk metal\nthrash metal folk-punk\nthrash metal funk rock\nthrash metal funk-metal\nthrash metal funk-rock\nthrash metal gothic metal\nthrash metal groove metal\nthrash metal nintendocore\nthrash metal polka\nthrash metal pop-punk\nthrash metal power metal\nthrash metal punk\nthrash metal punk rock\nthrash metal reggae\nthrash metal reggae-metal\nthrash metal ska-punk\nthrash metal, Chinese folk\nthrash metal, Javanese traditional\nthrash metal, Latin ballad\nthrash metal, Latin rock\nthrash metal, Neue Deutsche Härte\nthrash metal, Nintendocore\nthrash metal, alt-rock, dream-pop\nthrash metal, alternative rock\nthrash metal, electronic trance\nthrash metal, flamenco fusion\nthrash metal, flamenco, theatrical\nthrash metal, groove metal, chiptune\nthrash metal, hard rock, flamenco\nthrash metal, indie folk\nthrash metal, post-rock, alternative metal, punk rock\nthrash metal, progressive metalcore\nthrash metal, psychedelic rock\nthrash metal, punk, polka\nthrash metal, rap-metal, power metal\nthrash metal, ska-punk, Arabic fusion\nthrash metal, video game music\nthrash punk\ntimba\ntimba reggaeton\ntimba salsa\ntiraera hip hop\ntorch ballad\ntorch song\ntorch song blues\ntorch song jazz\ntorch song lounge jazz\ntorch song, big band\ntorch song, big band jazz\ntorch song, big band jazz, vintage\ntorch song, big band, cinematic\ntorch song, big band, jazz\ntorch song, big band, lounge\ntorch song, blues, jazz\ntorch song, cabaret, cinematic\ntorch song, cabaret, jazz\ntorch song, cinematic, film noir\ntorch song, cinematic, lo-fi\ntorch song, film noir, big band\ntorch song, film noir, cinematic\ntorch song, film noir, jazz\ntorch song, film noir, lounge\ntorch song, film noir, orchestral\ntorch song, film noir, vintage\ntorch song, jazz, cinematic\ntorch song, jazz, film noir\ntorch song, jazz, lo-fi\ntorch song, jazz, noir\ntorch song, lo-fi, vintage\ntorch song, swing jazz, bebop\ntoy music\ntoy piano\ntoy pop\ntraditional\ntraditional African\ntraditional African chant\ntraditional African choral\ntraditional African folk\ntraditional African percussion\ntraditional Arabic\ntraditional Arabic choral\ntraditional Arabic devotional\ntraditional Arabic folk\ntraditional Arabic music\ntraditional Armenian\ntraditional Asian\ntraditional Azerbaijani\ntraditional Brazilian\ntraditional Celtic\ntraditional Central Asian\ntraditional Central Asian folk\ntraditional Chinese\ntraditional Chinese ballad\ntraditional Chinese classical\ntraditional Chinese folk\ntraditional Chinese instrumental\ntraditional Chinese music\ntraditional Chinese opera\ntraditional Chinese orchestral\ntraditional Chinese storytelling\ntraditional Chinese zither\ntraditional Christmas\ntraditional Danish\ntraditional East Asian\ntraditional East Asian folk\ntraditional French hymn\ntraditional German Christmas\ntraditional German anthem\ntraditional German carol\ntraditional German march\ntraditional Greek\ntraditional Indian\ntraditional Indian percussion\ntraditional Indian rhythm\ntraditional Indonesian\ntraditional Indonesian folk\ntraditional Irish ballad\ntraditional Italian\ntraditional Japanese\ntraditional Japanese ballad\ntraditional Japanese folk\ntraditional Javanese\ntraditional Khmer folk\ntraditional Korean folk\ntraditional Kurdish folk\ntraditional Latin folk\ntraditional Malay\ntraditional Mexican hymn\ntraditional Middle Eastern\ntraditional Middle Eastern percussion\ntraditional North African\ntraditional North African folk\ntraditional Persian\ntraditional Scottish\ntraditional South Asian\ntraditional Southeast Asian\ntraditional Southeast Asian folk\ntraditional Spanish\ntraditional Spanish Christmas\ntraditional Spanish carol\ntraditional Spanish folk\ntraditional Spanish hymn\ntraditional Sundanese\ntraditional Tamil\ntraditional Turkish music\ntraditional West African\ntraditional acoustic\ntraditional ambient\ntraditional bagpipe\ntraditional ballad\ntraditional carol\ntraditional ceremonial\ntraditional chant\ntraditional choir\ntraditional choral\ntraditional country\ntraditional crooner\ntraditional devotional\ntraditional flute\ntraditional folk\ntraditional fusion\ntraditional guacharaca\ntraditional guzheng\ntraditional hand percussion\ntraditional hymn\ntraditional instrumental\ntraditional lament\ntraditional lullaby\ntraditional oud\ntraditional percussion\ntraditional pop\ntraditional pop ballad\ntraditional pop, rockabilly\ntraditional quartet\ntraditional ritual\ntraditional waltz\ntraditional world\ntraditional world music\ntrailer\ntrailer music\ntrailer music industrial hardstyle\ntrallpunk\ntrampská muzika\ntrance\ntrance C-pop\ntrance C-pop EDM\ntrance C-pop Eurodance\ntrance C-pop J-core\ntrance EBM\ntrance EDM\ntrance J-pop\ntrance ambient\ntrance artcore\ntrance ballad\ntrance bhajan\ntrance big band\ntrance big room\ntrance big room hardstyle\ntrance big room house\ntrance breakbeat\ntrance breakcore\ntrance chiptune\ntrance chiptune eurodance\ntrance dance-pop\ntrance darkwave\ntrance deep house\ntrance drum and bass\ntrance drum and bass progressive metal\ntrance dubstep\ntrance electro\ntrance electro house\ntrance electro-industrial\ntrance eurodance\ntrance folk\ntrance fusion\ntrance future bass\ntrance gabber\ntrance gospel\ntrance hands-up\ntrance happy hardcore\ntrance hardcore\ntrance hardstyle\ntrance hardstyle C-pop\ntrance hardstyle ambient\ntrance hardstyle artcore\ntrance hardstyle chiptune\ntrance hardstyle eurodance\ntrance hardstyle psytrance\ntrance hardstyle uk hardcore\ntrance hip hop\ntrance hip-hop\ntrance house\ntrance j-pop\ntrance j-pop anime\ntrance lo-fi\ntrance metal\ntrance metalcore\ntrance orchestral\ntrance pop\ntrance pop-rock\ntrance power metal\ntrance progressive house\ntrance progressive techno\ntrance psytrance\ntrance psytrance Indian classical\ntrance rap\ntrance ritual\ntrance rock\ntrance sitar\ntrance synth-pop\ntrance synthwave\ntrance synthwave chiptune\ntrance tech-house\ntrance techno\ntrance techno chiptune\ntrance techno hardstyle\ntrance vaporwave\ntrance world music\ntrance worldbeat\ntrance worship\ntrance, Arabic electronic\ntrance, Arabic pop\ntrance, Bollywood dance, spiritual electronic\ntrance, C-pop, cinematic\ntrance, C-pop, electronic\ntrance, C-pop, hardstyle\ntrance, Chinese folk, electronic\ntrance, Chinese fusion, electronic\ntrance, EBM\ntrance, EBM, chiptune\ntrance, EBM, electronic\ntrance, EBM, industrial\ntrance, EBM, synth-pop\ntrance, EDM, C-pop\ntrance, Eurodance\ntrance, Eurodance, Central Asian folk\ntrance, Eurodance, V-Pop\ntrance, Eurodance, hip-hop\ntrance, Indian bhajan, Eurodance\ntrance, Indian devotional, EDM\ntrance, Indian electronic\ntrance, Indian fusion\ntrance, Indian fusion, electronic\ntrance, Indian fusion, lo-fi\ntrance, J-RPG, cinematic\ntrance, J-core\ntrance, J-core, EDM\ntrance, J-core, Eurodance\ntrance, J-core, ambient\ntrance, J-core, anime\ntrance, J-core, artcore\ntrance, J-core, chiptune\ntrance, J-core, electronic\ntrance, J-core, happy hardcore\ntrance, J-core, hardstyle\ntrance, J-core, hyperpop\ntrance, J-core, video game\ntrance, J-core, video game music\ntrance, J-core, video game soundtrack\ntrance, J-pop\ntrance, J-pop, Eurobeat\ntrance, J-pop, Eurodance\ntrance, J-pop, Vocaloid\ntrance, J-pop, anime\ntrance, J-pop, artcore\ntrance, J-pop, cinematic\ntrance, J-pop, eurodance\ntrance, J-pop, happy hardcore\ntrance, J-pop, hardstyle\ntrance, J-pop, hyperpop\ntrance, J-pop, video game soundtrack\ntrance, J-rock\ntrance, J-rock, electronic\ntrance, Japanese RPG, cinematic\ntrance, K-pop\ntrance, Latin urban\ntrance, Latin, world music\ntrance, Mandarin rap, pop\ntrance, Middle Eastern\ntrance, Middle Eastern electronic\ntrance, Middle Eastern fusion\ntrance, Middle Eastern fusion, electronic\ntrance, Middle Eastern fusion, electronic dance\ntrance, Middle Eastern, Arabic\ntrance, Middle Eastern, Balkan\ntrance, Middle Eastern, South Asian\ntrance, Middle Eastern, ambient\ntrance, Middle Eastern, electronic\ntrance, Middle Eastern, epic\ntrance, Middle Eastern, ethereal\ntrance, Middle Eastern, psytrance\ntrance, Nepali folk\ntrance, Turkish folk, ambient\ntrance, Turkish pop, Eurodance\ntrance, Turkish pop, electronic\ntrance, UK hardcore\ntrance, Vocaloid\ntrance, Vocaloid, Chinese fusion\ntrance, Vocaloid, East Asian fusion\ntrance, ambient techno\ntrance, ambient, Arabic electronic\ntrance, ambient, C-pop\ntrance, ambient, Indian electronic\ntrance, ambient, Middle Eastern electronic\ntrance, ambient, Russian ethereal\ntrance, ambient, cinematic\ntrance, ambient, electronic\ntrance, ambient, ethereal\ntrance, ambient, hardstyle\ntrance, ambient, operatic\ntrance, ambient, tribal electronic\ntrance, anime, hardstyle\ntrance, baroque, electronic\ntrance, big room\ntrance, breakbeat, ethereal\ntrance, brostep\ntrance, chiptune\ntrance, chiptune, EDM\ntrance, chiptune, J-core\ntrance, chiptune, cinematic\ntrance, chiptune, electronic\ntrance, chiptune, eurodance\ntrance, chiptune, hands-up\ntrance, chiptune, happy hardcore\ntrance, chiptune, hardstyle\ntrance, chiptune, synthwave\ntrance, chiptune, video game music\ntrance, cinematic\ntrance, cinematic synth\ntrance, cinematic, Arabic folk\ntrance, cinematic, Arabic pop\ntrance, cinematic, C-pop\ntrance, cinematic, Hebrew vocal\ntrance, cinematic, Middle Eastern\ntrance, cinematic, Turkish pop\ntrance, cinematic, electronic\ntrance, cinematic, epic\ntrance, cinematic, hardstyle\ntrance, cinematic, industrial\ntrance, cinematic, neo-classical\ntrance, cinematic, operatic\ntrance, cinematic, orchestral\ntrance, cinematic, trap\ntrance, classical fusion, electronic\ntrance, classical, video game\ntrance, complextro\ntrance, complextro, EDM\ntrance, complextro, cinematic\ntrance, complextro, dubstep\ntrance, complextro, nu-disco\ntrance, complextro, pop\ntrance, cyberpunk, electronic\ntrance, cyberpunk, video game\ntrance, dark synthwave\ntrance, devotional dance, Indian bhajan\ntrance, devotional electronic\ntrance, dholak, melismatic chant\ntrance, drum and bass\ntrance, drum and bass, acid\ntrance, drum and bass, ambient\ntrance, drum and bass, chiptune\ntrance, drum and bass, cinematic\ntrance, drum and bass, neurofunk\ntrance, dubstep\ntrance, dubstep, ambient\ntrance, dubstep, chiptune\ntrance, dubstep, future bass\ntrance, dubstep, hardstyle\ntrance, electro house, cinematic\ntrance, electronic\ntrance, electronic pop, world music\ntrance, electronic, Arabic\ntrance, electronic, Arabic fusion\ntrance, electronic, C-pop\ntrance, electronic, Indian folk fusion\ntrance, electronic, Middle Eastern\ntrance, electronic, Middle Eastern fusion\ntrance, electronic, Polish hip hop\ntrance, electronic, Telugu\ntrance, electronic, ambient\ntrance, electronic, baroque\ntrance, electronic, cinematic\ntrance, electronic, cyberpunk\ntrance, electronic, hip hop\ntrance, electronic, world fusion\ntrance, ethnic electronica\ntrance, ethnic fusion, electronic\ntrance, eurobeat, ambient\ntrance, eurodance\ntrance, eurodance, 90s\ntrance, eurodance, J-core\ntrance, eurodance, Middle Eastern\ntrance, eurodance, chiptune\ntrance, eurodance, cinematic\ntrance, eurodance, classical\ntrance, eurodance, classical fusion\ntrance, eurodance, electronic\ntrance, eurodance, ethereal\ntrance, eurodance, happy hardcore\ntrance, eurodance, hard trance\ntrance, eurodance, hardstyle\ntrance, eurodance, j-core\ntrance, eurodance, mandopop\ntrance, eurodance, pop\ntrance, eurodance, psytrance\ntrance, eurodance, rock\ntrance, eurodance, world fusion\ntrance, folk electronica\ntrance, future bass, anime\ntrance, glitch, breakcore\ntrance, guzheng, electronic\ntrance, halftime trap\ntrance, hands-up\ntrance, hands-up EDM\ntrance, happy hardcore\ntrance, happy hardcore, J-RPG\ntrance, happy hardcore, J-core\ntrance, happy hardcore, J-pop\ntrance, happy hardcore, Javanese fusion\ntrance, happy hardcore, chiptune\ntrance, happy hardcore, cinematic\ntrance, happy hardcore, drum and bass\ntrance, happy hardcore, electronic\ntrance, happy hardcore, hardstyle\ntrance, happy hardcore, hyperpop\ntrance, happy hardcore, industrial\ntrance, happy hardcore, metalcore\ntrance, happy hardcore, video game music\ntrance, hard dance, Middle Eastern electronic\ntrance, hard techno\ntrance, hard trance, J-core\ntrance, hardcore techno, ambient\ntrance, hardstyle\ntrance, hardstyle, C-pop\ntrance, hardstyle, EDM\ntrance, hardstyle, J-core\ntrance, hardstyle, South Asian\ntrance, hardstyle, UK hardcore\ntrance, hardstyle, ambient\ntrance, hardstyle, big room house\ntrance, hardstyle, chiptune\ntrance, hardstyle, cinematic\ntrance, hardstyle, cinematic ambient\ntrance, hardstyle, complextro\ntrance, hardstyle, dream pop\ntrance, hardstyle, drum and bass\ntrance, hardstyle, dubstep\ntrance, hardstyle, electronic\ntrance, hardstyle, eurodance\ntrance, hardstyle, hands-up\ntrance, hardstyle, happy hardcore\ntrance, hardstyle, lo-fi\ntrance, hardstyle, metal-infused\ntrance, hardstyle, psytrance\ntrance, hardstyle, techno\ntrance, hardstyle, video game\ntrance, hip hop\ntrance, hip-hop, ambient\ntrance, hyperpop\ntrance, hyperpop, hardstyle\ntrance, industrial metal\ntrance, industrial, cinematic\ntrance, lo-fi hip hop\ntrance, melodic dubstep\ntrance, musical theater, cinematic\ntrance, mystical electronic\ntrance, neurofunk, drum and bass\ntrance, nightcore\ntrance, operatic, cinematic\ntrance, orchestral\ntrance, orchestral, cinematic\ntrance, oud, Middle Eastern\ntrance, progressive house\ntrance, progressive house, C-pop\ntrance, progressive house, Middle Eastern fusion\ntrance, progressive house, ambient\ntrance, progressive house, chiptune\ntrance, progressive house, cinematic\ntrance, progressive house, cinematic world music\ntrance, progressive house, drum and bass\ntrance, progressive house, electronic\ntrance, progressive house, metal\ntrance, progressive house, psytrance\ntrance, progressive trance\ntrance, progressive trance, C-pop\ntrance, psychedelic, electronic\ntrance, psytrance\ntrance, psytrance, Greek folk\ntrance, psytrance, Middle Eastern\ntrance, psytrance, ambient\ntrance, psytrance, spiritual ambient\ntrance, ritual electronic\ntrance, ritual electronic, psychedelic\ntrance, spiritual house\ntrance, spiritual, world fusion\ntrance, synth-pop\ntrance, synthwave\ntrance, synthwave, chiptune\ntrance, synthwave, cyberpunk\ntrance, techno, ambient\ntrance, trip-hop, ambient\ntrance, vaporwave, drum and bass\ntrance, video game music\ntrance, video game music, 90s synth\ntrance, video game, synthwave\ntrance, world fusion\ntrance, world fusion, ambient\ntrance, world fusion, deep house\ntrance, world fusion, electronic\ntrance, world music\ntrance, world music, Indian folk\ntrance, world music, dance\ntrance, world music, electronic\ntrance, world music, electronic dance\ntrance, world music, lo-fi\ntrance, worldbeat\ntrance-gate\ntrance-pop\ntrance-pop J-pop\ntrance-pop J-pop anime\ntrance-pop K-pop\ntrance-pop drum and bass\ntrance-pop hardstyle\ntrance-pop, dubstep, electronic\ntrance-pop, happy hardcore\ntrance-pop, happy hardcore, hardstyle\ntrance-pop, hardstyle\ntrance-pop, hardstyle, cinematic\ntrancecore\ntrancecore chiptune\ntrancecore electronicore\ntrancecore happy hardcore\ntrancecore industrial metal\ntrancecore metal\ntrancecore metalcore\ntrancecore post-hardcore\ntrancecore, J-core\ntrancecore, J-core, cinematic\ntrancecore, happy hardcore\ntrancecore, happy hardcore, Japanese electronic\ntrancecore, happy hardcore, Middle Eastern\ntrancecore, hardstyle, cinematic\ntrap\ntrap Afrobeats\ntrap C-pop\ntrap C-pop R&B\ntrap EBM\ntrap EDM\ntrap EDM C-pop\ntrap EDM J-rap\ntrap EDM K-hip-hop\ntrap EDM K-pop\ntrap EDM dancehall\ntrap EDM dark pop\ntrap EDM gospel\ntrap EDM pop\ntrap EDM pop-punk\ntrap EDM pop-rap\ntrap EDM rap\ntrap J-pop\ntrap Manele\ntrap Punjabi hip-hop\ntrap R&B\ntrap R&B Afro-fusion\ntrap R&B Afrobeat\ntrap R&B Afrobeats\ntrap R&B Arabic pop\ntrap R&B Armenian fusion\ntrap R&B Balkan\ntrap R&B Brazilian funk\ntrap R&B C-pop\ntrap R&B Eastern European\ntrap R&B French rap\ntrap R&B Hausa\ntrap R&B Indian\ntrap R&B Indian pop\ntrap R&B J-pop\ntrap R&B K-pop\ntrap R&B Latin\ntrap R&B Latin pop\ntrap R&B Mandopop\ntrap R&B Middle Eastern\ntrap R&B North African\ntrap R&B North African pop-rap\ntrap R&B Punjabi\ntrap R&B Punjabi folk\ntrap R&B Punjabi pop\ntrap R&B South Asian\ntrap R&B South Asian pop\ntrap R&B Turkish pop\ntrap R&B UK rap\ntrap R&B afro-fusion\ntrap R&B afrobeat\ntrap R&B alternative pop\ntrap R&B alternative rock\ntrap R&B ambient\ntrap R&B ambient pop\ntrap R&B art pop\ntrap R&B atmospheric\ntrap R&B atmospheric pop\ntrap R&B baile funk\ntrap R&B bilingual rap\ntrap R&B chillwave\ntrap R&B chiptune\ntrap R&B cinematic\ntrap R&B cinematic pop\ntrap R&B cloud rap\ntrap R&B dancehall\ntrap R&B dream pop\ntrap R&B electronic\ntrap R&B electronic pop\ntrap R&B emo-rap\ntrap R&B experimental electronic\ntrap R&B experimental pop\ntrap R&B fusion\ntrap R&B future bass\ntrap R&B glitch-hop\ntrap R&B gospel\ntrap R&B gospel dancehall\ntrap R&B hip-hop\ntrap R&B hyperpop\ntrap R&B indie pop\ntrap R&B jazz\ntrap R&B lo-fi\ntrap R&B lo-fi hip-hop\ntrap R&B lo-fi pop\ntrap R&B multilingual hip-hop\ntrap R&B multilingual pop\ntrap R&B phonk\ntrap R&B pop\ntrap R&B pop-rap\ntrap R&B protest\ntrap R&B rock\ntrap R&B soul\ntrap R&B synth-pop\ntrap R&B vaporwave\ntrap R&B world music\ntrap R&B, Central Asian\ntrap R&B, Central Asian, ambient\ntrap R&B, Guofeng\ntrap R&B, North African\ntrap R&B, South Asian\ntrap R&B, South Asian fusion\ntrap R&B, South Asian fusion, Middle Eastern\ntrap R&B, South Asian pop\ntrap R&B, Turkish folk\ntrap R&B, UK drill, Hindi pop\ntrap R&B, aggressive hip-hop\ntrap R&B, ambient R&B\ntrap R&B, boom-bap hip-hop\ntrap R&B, classic hip-hop\ntrap R&B, cloud rap\ntrap R&B, cloud rap, alternative R&B\ntrap R&B, emo rap, cloud rap\ntrap R&B, hardstyle\ntrap R&B, hyperpop\ntrap R&B, indie-pop\ntrap R&B, lo-fi hip hop\ntrap R&B, lo-fi, cloud rap\ntrap R&B, metalcore\ntrap R&B, pop-punk\ntrap R&B, psychedelic indie-pop\ntrap R&B, soulful R&B\ntrap afro-fusion\ntrap afrobeat\ntrap afrobeat chiptune\ntrap afrobeat psychedelic\ntrap afrobeat world music\ntrap afrobeats\ntrap afrobeats chiptune\ntrap afrobeats dancehall\ntrap alternative rock experimental\ntrap ambient\ntrap ambient alternative R&B\ntrap ambient chillwave\ntrap ambient experimental\ntrap ambient lo-fi\ntrap anime-core\ntrap ballad\ntrap ballad, R&B, Southeast Asian pop\ntrap ballad, cinematic, Turkish pop\ntrap ballad, cloud rap, emotional R&B\ntrap ballad, emo rap, C-pop\ntrap ballad, emo rap, R&B\ntrap ballad, lo-fi hip-hop, C-pop\ntrap ballad, melancholic, hyperpop\ntrap ballad, reggaeton\ntrap bass\ntrap bass house\ntrap bhajan\ntrap bhangra\ntrap blues\ntrap blues rock\ntrap bolero\ntrap bollywood\ntrap boom-bap\ntrap bossa nova\ntrap bounce\ntrap brass\ntrap breakbeat\ntrap carioca\ntrap cello\ntrap children's\ntrap chillwave\ntrap chiptune\ntrap chiptune Indian\ntrap chiptune bengali folk\ntrap classical\ntrap club\ntrap corrido\ntrap corrido tumbado\ntrap corridos\ntrap corridos tumbados\ntrap country\ntrap crunk\ntrap cumbia\ntrap cypher\ntrap dancehall\ntrap dancehall afro-fusion\ntrap dancehall afrobeats\ntrap dancehall chiptune\ntrap dancehall pop\ntrap dancehall reggaeton\ntrap drill\ntrap drill chiptune\ntrap drill dancehall\ntrap drill gangsta rap\ntrap drill hip-hop\ntrap drill lo-fi\ntrap drill vaporwave\ntrap drill, Middle Eastern fusion\ntrap drill, Middle Eastern fusion, South Asian fusion\ntrap drill, South Asian fusion\ntrap drum and bass\ntrap dubstep\ntrap dubstep vaporwave\ntrap electro chiptune\ntrap electronic\ntrap electronic pop\ntrap electronic rock\ntrap electronic rock C-pop\ntrap emo rap\ntrap emo rap vaporwave\ntrap emo-rap\ntrap en español\ntrap ethnic\ntrap experimental electronic\ntrap experimental hip-hop\ntrap experimental pop\ntrap fado\ntrap flamenco\ntrap folk\ntrap folk fusion\ntrap forró\ntrap funk\ntrap funk carioca\ntrap funk carioca pop\ntrap fusion\ntrap fusion, boom-bap hip-hop\ntrap future bass\ntrap future bass ambient\ntrap future bass chiptune\ntrap future bass cinematic\ntrap future bass hardwave\ntrap ghazal\ntrap ghazal fusion\ntrap gospel\ntrap gospel R&B\ntrap gospel rock\ntrap grime\ntrap hardstyle\ntrap hardstyle cinematic\ntrap hardstyle gabber\ntrap hardstyle psytrance\ntrap hip hop\ntrap hip-hop\ntrap hip-hop C-pop\ntrap hip-hop Indian\ntrap hip-hop Indian devotional\ntrap hip-hop Indian fusion\ntrap hip-hop afrobeat\ntrap hip-hop ambient\ntrap hip-hop chillwave\ntrap hip-hop chiptune\ntrap hip-hop drill\ntrap hip-hop electronic\ntrap hip-hop electronic pop\ntrap hip-hop flamenco\ntrap hip-hop hyperpop\ntrap hip-hop kuthu\ntrap hip-hop lo-fi\ntrap hip-hop pop\ntrap hip-hop pop-R&B\ntrap hip-hop pop-rap\ntrap hip-hop pop-rock\ntrap hip-hop synth-pop\ntrap hip-hop world music\ntrap hip-hop, Bollywood fusion\ntrap hip-hop, C-pop\ntrap hip-hop, Carnatic fusion\ntrap hip-hop, Celtic folk\ntrap hip-hop, Chinese fusion\ntrap hip-hop, EDM, K-pop\ntrap hip-hop, Indian fusion\ntrap hip-hop, J-pop\ntrap hip-hop, Korean Pansori\ntrap hip-hop, Middle Eastern fusion\ntrap hip-hop, North Indian folk, fusion\ntrap hip-hop, Punjabi pop\ntrap hip-hop, R&B\ntrap hip-hop, R&B, Desi hip-hop\ntrap hip-hop, R&B, classical piano\ntrap hip-hop, South Asian folk\ntrap hip-hop, South Asian fusion\ntrap hip-hop, South Indian\ntrap hip-hop, South Indian fusion\ntrap hip-hop, Southeast Asian pop\ntrap hip-hop, alternative R&B\ntrap hip-hop, boom-bap\ntrap hip-hop, cinematic C-pop\ntrap hip-hop, cinematic pop-R&B\ntrap hip-hop, cinematic, South Asian\ntrap hip-hop, cinematic, South Asian fusion\ntrap hip-hop, electronic, C-pop\ntrap hip-hop, emotional ballad\ntrap hip-hop, folk, ambient\ntrap hip-hop, future bass\ntrap hip-hop, hardstyle, psychedelic rap\ntrap hip-hop, hyperpop\ntrap hip-hop, nu-metal, EDM\ntrap hip-hop, nu-metal, emo-rap\ntrap hip-hop, pansori, korean fusion\ntrap hip-hop, pop-punk\ntrap hip-hop, pop-rap\ntrap hip-hop, progressive house, EDM\ntrap hip-hop, synth-pop\ntrap hip-hop, vaporwave\ntrap hip-house\ntrap house\ntrap hyperpop\ntrap hyperpop chiptune\ntrap hyperpop industrial\ntrap industrial\ntrap jazz\ntrap lo-fi\ntrap lo-fi hip-hop\ntrap lounge\ntrap manele\ntrap maneles\ntrap metal\ntrap metal alternative rap\ntrap metal alternative rock\ntrap metal chiptune\ntrap metal dubstep\ntrap metal electronic rock\ntrap metal electronicore\ntrap metal emo rap\ntrap metal emo rap alternative rock\ntrap metal experimental hip-hop\ntrap metal funk carioca\ntrap metal glitchcore\ntrap metal hardcore punk\ntrap metal hardstyle\ntrap metal horrorcore\ntrap metal hyperpop\ntrap metal industrial hip-hop\ntrap metal industrial rock\ntrap metal nu-metal\ntrap metal nu-metal metalcore\ntrap metal nu-metalcore\ntrap metal phonk\ntrap metal phonk horrorcore\ntrap metal punk rock\ntrap metal rap rock\ntrap metal witch house\ntrap metal, Chinese traditional\ntrap metal, Christian rap-rock\ntrap metal, Indian devotional\ntrap metal, Indian fusion\ntrap metal, J-rock\ntrap metal, Middle Eastern fusion\ntrap metal, Middle Eastern rock\ntrap metal, UK rap\ntrap metal, ambient, Indian devotional\ntrap metal, chiptune, cantopop\ntrap metal, cinematic anime\ntrap metal, conscious hip-hop, cinematic\ntrap metal, digital hardcore\ntrap metal, dubstep\ntrap metal, electronic\ntrap metal, electronic hip-hop\ntrap metal, electronic rock\ntrap metal, emo-rap, Chinese hip hop\ntrap metal, epic rock, rap\ntrap metal, hardstyle\ntrap metal, hardstyle, Chinese trap\ntrap metal, hardstyle, electronic\ntrap metal, horrorcore\ntrap metal, hyperpop\ntrap metal, hyperpop, J-pop\ntrap metal, hyperpop, J-rock\ntrap metal, hyperpop, alternative R&B\ntrap metal, hyperpop, electronicore\ntrap metal, hyperpop, glitchcore\ntrap metal, hyperpop, lo-fi\ntrap metal, industrial hardcore, cinematic\ntrap metal, industrial hip-hop, cinematic\ntrap metal, industrial rock\ntrap metal, lo-fi hip hop, ambient\ntrap metal, meme rap\ntrap metal, metalcore, electronic\ntrap metal, nu-metal\ntrap metal, nu-metal, ambient\ntrap metal, nu-metalcore\ntrap metal, nu-metalcore, cinematic ambient\ntrap metal, phonk, Russian rap\ntrap metal, phonk, lo-fi\ntrap metal, political hip-hop\ntrap metal, pop-rock\ntrap metal, post-hardcore\ntrap metal, post-rock, C-pop\ntrap metal, rap-rock\ntrap metal, rap-rock, nu-metal\ntrap metalcore\ntrap moombahton\ntrap neo-soul\ntrap nu-metal\ntrap opera\ntrap orchestral\ntrap oud\ntrap parody\ntrap parody, Malayalam ballad\ntrap phonk\ntrap phonk ambient\ntrap phonk chiptune\ntrap phonk dark electronic\ntrap phonk dark synthwave\ntrap phonk experimental\ntrap phonk hardstyle\ntrap phonk synthwave\ntrap phonk wave\ntrap pop\ntrap pop R&B\ntrap pop ambient\ntrap pop electronic\ntrap pop rap\ntrap pop rock\ntrap pop world music\ntrap pop-punk\ntrap pop-r&b\ntrap pop-rap\ntrap pop-rap dancehall\ntrap pop-rap rock\ntrap pop-rock\ntrap pop-rock electronic\ntrap psytrance\ntrap punk\ntrap rage\ntrap ragtime\ntrap rai\ntrap rap\ntrap rap chiptune\ntrap rap rock\ntrap rap, R&B, ambient\ntrap rap, R&B, jazz\ntrap rap, chiptune\ntrap rap, cinematic rock, hybrid\ntrap rap, nu-metal, alternative rock\ntrap rap, nu-metal, cinematic\ntrap rap, nu-metal, hip-hop\ntrap rap, nu-metal, metalcore\ntrap rap, nu-metal, rap-rock\ntrap reggae\ntrap reggaeton\ntrap rock\ntrap rock chiptune\ntrap rock gospel\ntrap rock world\ntrap salsa\ntrap soul\ntrap soul afrobeats\ntrap soul ambient R&B\ntrap soul ambient pop\ntrap soul emo rap\ntrap soul emo-rap\ntrap soul lo-fi\ntrap soul lo-fi hip-hop\ntrap soul vaporwave\ntrap soul, Mandopop\ntrap soul, R&B\ntrap soul, UK hip-hop\ntrap soul, alternative R&B\ntrap soul, ambient dream-pop\ntrap soul, ambient, hyperpop\ntrap soul, cinematic hip hop\ntrap soul, cinematic hip-hop\ntrap soul, cloud rap\ntrap soul, contemporary R&B\ntrap soul, dream pop\ntrap soul, drill trap\ntrap soul, hip-hop\ntrap soul, hyper-trap\ntrap soul, hyperpop\ntrap soul, liquid drum and bass\ntrap soul, lo-fi hip hop\ntrap soul, pop-rap\ntrap soul, reggaeton\ntrap soul, southern hip hop\ntrap soul, synth-funk\ntrap spiritual\ntrap swing\ntrap synth-pop\ntrap synthwave\ntrap synthwave chiptune\ntrap synthwave vaporwave\ntrap tango\ntrap techno\ntrap twerk\ntrap ukulele\ntrap vaporwave\ntrap vaporwave ambient\ntrap vaporwave world music\ntrap world music\ntrap, 8-bit\ntrap, 8-bit, Chinese hip hop\ntrap, 8-bit, Hungarian hip hop\ntrap, 8-bit, Italian rap\ntrap, 8-bit, Polish rap\ntrap, 8-bit, Southern hip hop\ntrap, 8-bit, aggressive\ntrap, 8-bit, chiptune\ntrap, 8-bit, dark\ntrap, 8-bit, electronic\ntrap, 8-bit, futuristic\ntrap, 8-bit, hardcore\ntrap, 8-bit, hip hop\ntrap, 8-bit, hip-hop\ntrap, 8-bit, lo-fi\ntrap, 8-bit, lo-fi hip hop\ntrap, 8-bit, minimalist\ntrap, 8-bit, nu-metal\ntrap, 8-bit, raw\ntrap, 8-bit, underground\ntrap, African chant\ntrap, African folk, cinematic\ntrap, African fusion\ntrap, African hip hop\ntrap, African hip-hop\ntrap, African vocal, spiritual\ntrap, Afrikaans hip hop\ntrap, Afrikaans rap\ntrap, Afro fusion\ntrap, Afro hip hop\ntrap, Afro trap\ntrap, Afro-Asian fusion\ntrap, Afro-Beat\ntrap, Afro-Caribbean\ntrap, Afro-Caribbean, ambient\ntrap, Afro-Caribbean, lo-fi\ntrap, Afro-Creole\ntrap, Afro-French\ntrap, Afro-French, Middle Eastern\ntrap, Afro-Latin\ntrap, Afro-Portuguese\ntrap, Afro-Portuguese, ambient\ntrap, Afro-Swahili\ntrap, Afro-Swahili hip hop\ntrap, Afro-Trap\ntrap, Afro-fusion\ntrap, Afro-fusion, ambient\ntrap, Afro-fusion, emo rap\ntrap, Afro-hip hop\ntrap, Afro-hip hop, Spanish-influenced\ntrap, Afro-hop\ntrap, Afro-pop\ntrap, Afro-trap\ntrap, Afro-urban\ntrap, Afro-urban, lo-fi hip hop\ntrap, Afro-urban, retro synth\ntrap, Afrobeat\ntrap, Afrobeat, Latin hip hop\ntrap, Afrobeat, cinematic\ntrap, Afrobeat, lo-fi hip hop\ntrap, Afrobeat, melodic trap\ntrap, Afrobeats\ntrap, Afrobeats, dancehall\ntrap, Afrobeats, hip-hop\ntrap, Afrobeats, lo-fi\ntrap, Afrofusion\ntrap, Afroswing\ntrap, Albanian hip hop\ntrap, Albanian pop\ntrap, Albanian rap\ntrap, Amapiano, Afrobeats\ntrap, Americana, blues\ntrap, Anatolian folk\ntrap, Anatolian folk, lo-fi hip hop\ntrap, Anatolian fusion\ntrap, Anatolian, cinematic\ntrap, Anatolian, dark hip-hop\ntrap, Anatolian, electronic\ntrap, Anatolian, hip-hop\ntrap, Anatolian, melodic\ntrap, Anatolian, traditional\ntrap, Andean folk\ntrap, Andean fusion\ntrap, Andean style, lo-fi hip hop\ntrap, Arabic Mawwal\ntrap, Arabic R&B, North African\ntrap, Arabic R&B, cinematic ambient\ntrap, Arabic R&B, lo-fi hip hop\ntrap, Arabic ambient\ntrap, Arabic drill, lo-fi\ntrap, Arabic emo\ntrap, Arabic fusion\ntrap, Arabic fusion, French rap\ntrap, Arabic fusion, Italian rap\ntrap, Arabic fusion, ambient\ntrap, Arabic fusion, cinematic\ntrap, Arabic fusion, electronic\ntrap, Arabic fusion, flamenco\ntrap, Arabic fusion, lo-fi\ntrap, Arabic fusion, lo-fi hip hop\ntrap, Arabic fusion, melodic rap\ntrap, Arabic fusion, pop\ntrap, Arabic fusion, pop-rap\ntrap, Arabic fusion, psychedelic\ntrap, Arabic hip hop\ntrap, Arabic hip hop, Dutch rap\ntrap, Arabic hip hop, French rap\ntrap, Arabic hip hop, Latin trap\ntrap, Arabic hip hop, Middle Eastern\ntrap, Arabic hip hop, Middle Eastern fusion\ntrap, Arabic hip hop, North African\ntrap, Arabic hip hop, Spanish rap\ntrap, Arabic hip hop, acoustic\ntrap, Arabic hip hop, ambient\ntrap, Arabic hip hop, atmospheric\ntrap, Arabic hip hop, cinematic\ntrap, Arabic hip hop, cinematic fusion\ntrap, Arabic hip hop, dark ambient\ntrap, Arabic hip hop, electronic\ntrap, Arabic hip hop, flamenco fusion\ntrap, Arabic hip hop, folk fusion\ntrap, Arabic hip hop, industrial\ntrap, Arabic hip hop, lo-fi\ntrap, Arabic hip hop, melancholic\ntrap, Arabic hip hop, melodic trap\ntrap, Arabic hip hop, oud\ntrap, Arabic hip hop, retro synth\ntrap, Arabic hip hop, soul\ntrap, Arabic hip hop, synth rock\ntrap, Arabic hip hop, synthwave\ntrap, Arabic hip hop, video game\ntrap, Arabic hip-hop\ntrap, Arabic hip-hop, North African\ntrap, Arabic hip-hop, North African fusion\ntrap, Arabic hip-hop, ambient\ntrap, Arabic hip-hop, ambient fusion\ntrap, Arabic hip-hop, atmospheric\ntrap, Arabic hip-hop, cinematic\ntrap, Arabic hip-hop, cross-cultural\ntrap, Arabic hip-hop, duduk\ntrap, Arabic hip-hop, jazzy\ntrap, Arabic hip-hop, oriental fusion\ntrap, Arabic hip-hop, traditional fusion\ntrap, Arabic influence\ntrap, Arabic mawwal, cinematic\ntrap, Arabic melodic\ntrap, Arabic melodic rap\ntrap, Arabic melodic rap, acoustic fusion\ntrap, Arabic melodic rap, ambient\ntrap, Arabic melodic, atmospheric\ntrap, Arabic pop\ntrap, Arabic pop, Albanian hip-hop\ntrap, Arabic pop, French hip-hop\ntrap, Arabic pop, French pop\ntrap, Arabic pop, German hip hop\ntrap, Arabic pop, Latin hip hop\ntrap, Arabic pop, Middle Eastern\ntrap, Arabic pop, R&B\ntrap, Arabic pop, ambient\ntrap, Arabic pop, atmospheric\ntrap, Arabic pop, cinematic\ntrap, Arabic pop, electronic\ntrap, Arabic pop, flamenco fusion\ntrap, Arabic pop, lo-fi\ntrap, Arabic pop, melodic\ntrap, Arabic pop, rock\ntrap, Arabic rap\ntrap, Arabic rap, French rap\ntrap, Arabic rap, ambient\ntrap, Arabic rap, cinematic\ntrap, Arabic rap, lo-fi\ntrap, Arabic rap, melodic trap\ntrap, Arabic soul\ntrap, Arabic trap\ntrap, Arabic, ambient\ntrap, Arabic, atmospheric\ntrap, Arabic, cinematic\ntrap, Arabic, dark ambient\ntrap, Arabic, dubstep\ntrap, Arabic, electronic\ntrap, Arabic, emotional\ntrap, Arabic, hip hop\ntrap, Arabic, lo-fi\ntrap, Arabic, melancholic\ntrap, Arabic, melodic\ntrap, Arabic, modern\ntrap, Arabic, oriental\ntrap, Arabic, psychedelic\ntrap, Arabic, spiritual\ntrap, Armenian folk\ntrap, Armenian pop\ntrap, Armenian, melancholic\ntrap, Asian ambient\ntrap, Asian fusion\ntrap, Asian fusion, lo-fi hip hop\ntrap, Asian hip hop\ntrap, Asian hip hop, J-pop\ntrap, Asian hip-hop\ntrap, Asian pop\ntrap, Asian tonality\ntrap, Asian trap\ntrap, Asian zither, hip-hop\ntrap, Asian-inspired, modern\ntrap, Australian hip hop\ntrap, Australian hip-hop\ntrap, Australian, cinematic\ntrap, Azerbaijani folk\ntrap, Azerbaijani fusion\ntrap, Azerbaijani hip hop\ntrap, Azerbaijani hip hop, German rap\ntrap, Azerbaijani pop\ntrap, Azerbaijani rap\ntrap, Azerbaijani, ambient\ntrap, Azerbaijani, atmospheric\ntrap, Azerbaijani, cinematic\ntrap, Azerbaijani, emotional\ntrap, Azerbaijani, lo-fi\ntrap, Azerbaijani, melancholic\ntrap, Balkan\ntrap, Balkan brass\ntrap, Balkan brass, French rap\ntrap, Balkan brass, Kazakh hip hop\ntrap, Balkan brass, comedy\ntrap, Balkan brass, hip hop\ntrap, Balkan electronic\ntrap, Balkan folk\ntrap, Balkan folk, Hindi pop\ntrap, Balkan folk, Middle Eastern\ntrap, Balkan folk, Romanian rap\ntrap, Balkan folk, cinematic\ntrap, Balkan folk, electronic\ntrap, Balkan folk, rap\ntrap, Balkan fusion\ntrap, Balkan fusion, Klezmer\ntrap, Balkan fusion, Middle Eastern\ntrap, Balkan fusion, electronic\ntrap, Balkan hip hop\ntrap, Balkan hip-hop\ntrap, Balkan hip-hop, Eastern European\ntrap, Balkan hip-hop, Eastern European hip-hop\ntrap, Balkan hip-hop, German hip-hop\ntrap, Balkan hip-hop, Middle Eastern fusion\ntrap, Balkan hip-hop, cinematic\ntrap, Balkan pop\ntrap, Balkan pop, R&B\ntrap, Balkan pop, dancehall\ntrap, Balkan pop, world fusion\ntrap, Balkan rap\ntrap, Balkan trap\ntrap, Balkan, Arabic fusion\ntrap, Balkan, C-pop\ntrap, Balkan, Chinese hip hop\ntrap, Balkan, Eastern European\ntrap, Balkan, German rap\ntrap, Balkan, Italian hip hop\ntrap, Balkan, Klezmer\ntrap, Balkan, Lithuanian hip hop\ntrap, Balkan, Middle Eastern\ntrap, Balkan, R&B\ntrap, Balkan, Romanian hip hop\ntrap, Balkan, Russian pop\ntrap, Balkan, acoustic\ntrap, Balkan, ambient\ntrap, Balkan, atmospheric\ntrap, Balkan, bilingual\ntrap, Balkan, cinematic\ntrap, Balkan, dancehall\ntrap, Balkan, dark hip hop\ntrap, Balkan, electronic\ntrap, Balkan, emotional\ntrap, Balkan, ethnic\ntrap, Balkan, hip hop\ntrap, Balkan, lo-fi\ntrap, Balkan, modern\ntrap, Balkan, moody\ntrap, Balkan, multi-lingual\ntrap, Balkan, oud\ntrap, Balkan, pop\ntrap, Balkan, vocal\ntrap, Balkan-infused\ntrap, Balkan-trap\ntrap, Bengali hip hop\ntrap, Bengali hip hop, Hindi hip hop\ntrap, Bengali pop\ntrap, Bengali pop, electronic\ntrap, Bengali, melancholic\ntrap, Bhangra, Punjabi folk\ntrap, Bhojpuri, electronic\ntrap, Bollywood\ntrap, Bollywood EDM\ntrap, Bollywood fusion\ntrap, Bollywood pop\ntrap, Bollywood pop, world music\ntrap, Bollywood, Indian hip-hop\ntrap, Bollywood, Middle Eastern\ntrap, Bollywood, Punjabi hip hop\ntrap, Bollywood, R&B\ntrap, Bollywood, South Asian fusion\ntrap, Bollywood, ambient\ntrap, Bollywood, cinematic\ntrap, Bollywood, electronic\ntrap, Bollywood, fusion\ntrap, Bollywood, high-fashion\ntrap, Bollywood, hip hop\ntrap, Bollywood, lo-fi hip hop\ntrap, Brazilian\ntrap, Brazilian Portuguese trap\ntrap, Brazilian R&B\ntrap, Brazilian funk\ntrap, Brazilian funk, R&B\ntrap, Brazilian funk, cloud rap\ntrap, Brazilian funk, lo-fi\ntrap, Brazilian funk, lo-fi hip hop\ntrap, Brazilian funk, melodic trap\ntrap, Brazilian funk, synthwave\ntrap, Brazilian funk, video game\ntrap, Brazilian gangsta rap\ntrap, Brazilian gangsta rap, cinematic\ntrap, Brazilian gospel, world music\ntrap, Brazilian hip hop\ntrap, Brazilian hip-hop\ntrap, Brazilian hip-hop, world music\ntrap, Brazilian pop\ntrap, Brazilian trap\ntrap, Brazilian trap, world music\ntrap, Brazilian, ambient\ntrap, Brazilian, cinematic\ntrap, Brazilian, kalimba\ntrap, Brazilian, lo-fi\ntrap, Brazilian, lo-fi hip hop\ntrap, Brazilian, melancholic\ntrap, British hip hop\ntrap, British hip hop, anime-inspired\ntrap, Bulgarian hip hop\ntrap, C-Rap\ntrap, C-Rap, chiptune\ntrap, C-Rap, electronic\ntrap, C-pop\ntrap, C-pop fusion\ntrap, C-pop, Ancient Style\ntrap, C-pop, Asian fusion\ntrap, C-pop, Chinese opera\ntrap, C-pop, Eastern-influenced\ntrap, C-pop, Latin\ntrap, C-pop, Malay pop\ntrap, C-pop, Middle Eastern fusion\ntrap, C-pop, R&B\ntrap, C-pop, ambient\ntrap, C-pop, ancient style\ntrap, C-pop, anime\ntrap, C-pop, atmospheric\ntrap, C-pop, atmospheric R&B\ntrap, C-pop, chiptune\ntrap, C-pop, cinematic\ntrap, C-pop, classical guitar\ntrap, C-pop, cloud rap\ntrap, C-pop, dark R&B\ntrap, C-pop, electronic\ntrap, C-pop, emotional\ntrap, C-pop, ethereal\ntrap, C-pop, ethnic\ntrap, C-pop, ethnic fusion\ntrap, C-pop, experimental\ntrap, C-pop, festive\ntrap, C-pop, flamenco\ntrap, C-pop, folk fusion\ntrap, C-pop, futuristic\ntrap, C-pop, guzheng\ntrap, C-pop, hardstyle\ntrap, C-pop, hip-hop\ntrap, C-pop, hyperpop\ntrap, C-pop, lo-fi\ntrap, C-pop, lo-fi hip hop\ntrap, C-pop, lo-fi hip-hop\ntrap, C-pop, melodic rap\ntrap, C-pop, phonk\ntrap, C-pop, psychedelic\ntrap, C-pop, soul\ntrap, C-pop, synth-pop\ntrap, C-pop, synthwave\ntrap, C-pop, theatrical\ntrap, C-pop, traditional Chinese\ntrap, C-pop, traditional East Asian\ntrap, C-pop, traditional South Asian\ntrap, C-pop, traditional fusion\ntrap, C-pop, vaporwave\ntrap, C-pop, video game\ntrap, C-pop, world fusion\ntrap, C-pop, world music\ntrap, Cantonese hip hop\ntrap, Cantonese hip hop, Mandarin rap\ntrap, Cantonese opera, electronic\ntrap, Cantonese pop\ntrap, Cantonese rap\ntrap, Cantonese rap, Mandarin rap\ntrap, Cantonese rap, atmospheric\ntrap, Cantonese rap, modern hip hop\ntrap, Cantopop\ntrap, Cantopop, electronic\ntrap, Cantopop, synthwave\ntrap, Caribbean\ntrap, Caribbean hip hop\ntrap, Caribbean hip-hop\ntrap, Caribbean, atmospheric\ntrap, Caribbean, hip hop\ntrap, Caribbean, lo-fi\ntrap, Caribbean, modern\ntrap, Carnatic fusion\ntrap, Carnatic, Tamil hip hop\ntrap, Carnatic, Tamil rap\ntrap, Carnatic, ambient\ntrap, Carnatic, hip hop\ntrap, Carnatic, hip-hop\ntrap, Catalan hip hop\ntrap, Catalan hip hop, cinematic\ntrap, Cebuano hip hop\ntrap, Celtic folk\ntrap, Celtic fusion\ntrap, Celtic fusion, rock\ntrap, Celtic hip-hop\ntrap, Celtic, hip hop\ntrap, Celtic, instrumental\ntrap, Celtic, lo-fi hip hop\ntrap, Central Asian folk\ntrap, Central Asian fusion\ntrap, Central Asian hip hop\ntrap, Central Asian, ambient\ntrap, Central Asian, emotional\ntrap, Central Asian, hip hop\ntrap, Central Asian, hip-hop\ntrap, Central Asian, melancholic\ntrap, Chicago hip-hop\ntrap, Chinese\ntrap, Chinese New Year\ntrap, Chinese New Year, hip-hop\ntrap, Chinese aesthetics\ntrap, Chinese aesthetics, cinematic\ntrap, Chinese ambient\ntrap, Chinese ambient, hyperpop\ntrap, Chinese ambient, melodic hip-hop\ntrap, Chinese blues\ntrap, Chinese cinematic\ntrap, Chinese electronic\ntrap, Chinese experimental\ntrap, Chinese flute, anime hip-hop\ntrap, Chinese flute, atmospheric\ntrap, Chinese flute, electronic\ntrap, Chinese flute, lo-fi\ntrap, Chinese flute, lo-fi hip hop\ntrap, Chinese flute, melancholic\ntrap, Chinese flute, modern hip hop\ntrap, Chinese folk\ntrap, Chinese folk, experimental\ntrap, Chinese folk, lo-fi\ntrap, Chinese folk, lo-fi hip hop\ntrap, Chinese folk, nu-metal\ntrap, Chinese folk, punk\ntrap, Chinese fusion\ntrap, Chinese fusion, ambient\ntrap, Chinese fusion, cinematic\ntrap, Chinese fusion, cinematic hip-hop\ntrap, Chinese fusion, epic\ntrap, Chinese fusion, rock\ntrap, Chinese guzheng\ntrap, Chinese hip hop\ntrap, Chinese hip hop, Japanese rap\ntrap, Chinese hip hop, K-pop fusion\ntrap, Chinese hip hop, Korean hip hop\ntrap, Chinese hip hop, Uyghur rap\ntrap, Chinese hip hop, Uyghur rap, Arabic rap\ntrap, Chinese hip hop, ambient\ntrap, Chinese hip hop, anime\ntrap, Chinese hip hop, atmospheric\ntrap, Chinese hip hop, blues rock\ntrap, Chinese hip hop, cinematic\ntrap, Chinese hip hop, cyberpunk\ntrap, Chinese hip hop, dark ambient\ntrap, Chinese hip hop, electronic\ntrap, Chinese hip hop, emotional\ntrap, Chinese hip hop, ethereal\ntrap, Chinese hip hop, experimental\ntrap, Chinese hip hop, future bass\ntrap, Chinese hip hop, futuristic\ntrap, Chinese hip hop, industrial\ntrap, Chinese hip hop, jazz fusion\ntrap, Chinese hip hop, lo-fi\ntrap, Chinese hip hop, lo-fi jazz\ntrap, Chinese hip hop, lo-fi soul\ntrap, Chinese hip hop, melodic rap\ntrap, Chinese hip hop, multilingual\ntrap, Chinese hip hop, psychedelic\ntrap, Chinese hip hop, sci-fi\ntrap, Chinese hip hop, synth pop\ntrap, Chinese hip hop, synthwave\ntrap, Chinese hip hop, video game\ntrap, Chinese hip hop, video game synth\ntrap, Chinese hip-hop\ntrap, Chinese hip-hop, Wuxia\ntrap, Chinese hip-hop, ambient\ntrap, Chinese hip-hop, atmospheric\ntrap, Chinese hip-hop, cinematic\ntrap, Chinese hip-hop, cyberpunk\ntrap, Chinese hip-hop, lo-fi\ntrap, Chinese hip-hop, synth flute\ntrap, Chinese hip-hop, video game\ntrap, Chinese horror, electronic\ntrap, Chinese instrumentation\ntrap, Chinese melodic, atmospheric\ntrap, Chinese mythology, electronic\ntrap, Chinese opera\ntrap, Chinese opera, ambient\ntrap, Chinese opera, bilingual rap\ntrap, Chinese opera, cinematic\ntrap, Chinese opera, electronic\ntrap, Chinese opera, experimental\ntrap, Chinese opera, fusion\ntrap, Chinese opera, hip hop\ntrap, Chinese opera, lo-fi\ntrap, Chinese pop\ntrap, Chinese pop, R&B\ntrap, Chinese pop, ambient\ntrap, Chinese pop, cinematic\ntrap, Chinese pop, electronic\ntrap, Chinese pop, futuristic\ntrap, Chinese pop, hyperpop\ntrap, Chinese pop, lo-fi\ntrap, Chinese pop, lo-fi hip hop\ntrap, Chinese punk\ntrap, Chinese rap\ntrap, Chinese rap, atmospheric\ntrap, Chinese rap, brass loop\ntrap, Chinese rap, cinematic\ntrap, Chinese rap, lo-fi\ntrap, Chinese rap, lo-fi hip hop\ntrap, Chinese traditional\ntrap, Chinese traditional, atmospheric\ntrap, Chinese traditional, cinematic\ntrap, Chinese traditional, electronic\ntrap, Chinese traditional, hip-hop\ntrap, Chinese traditional, lo-fi\ntrap, Chinese trap\ntrap, Chinese underground\ntrap, Chinese zither\ntrap, Chinese zither, aggressive\ntrap, Chinese zither, dark atmosphere\ntrap, Chinese zither, dark hip hop\ntrap, Chinese zither, electronic\ntrap, Chinese zither, hip hop\ntrap, Chinese zither, hip-hop\ntrap, Chinese zither, lo-fi\ntrap, Chinese zither, lo-fi hip hop\ntrap, Chinese zither, modern C-pop\ntrap, Chinese zither, modern hip hop\ntrap, Chinese, Eastern tonality\ntrap, Chinese, aggressive\ntrap, Chinese, ambient\ntrap, Chinese, anthemic\ntrap, Chinese, atmospheric\ntrap, Chinese, cinematic\ntrap, Chinese, dark\ntrap, Chinese, electronic\ntrap, Chinese, esports\ntrap, Chinese, ethnic\ntrap, Chinese, guzheng\ntrap, Chinese, hip-hop\ntrap, Chinese, lo-fi\ntrap, Chinese, melancholic\ntrap, Chinese, modern\ntrap, Chinese, modern hip-hop\ntrap, Chinese, mystical\ntrap, Chinese, wuxia\ntrap, Chinese-style\ntrap, Christian hip-hop\ntrap, Christmas\ntrap, Christmas hip-hop\ntrap, Christmas pop\ntrap, Christmas, comedic\ntrap, Christmas, dark hip hop\ntrap, Christmas, funk\ntrap, Christmas, hip hop\ntrap, Christmas, modern\ntrap, Christmas, pop\ntrap, Christmas, sinister\ntrap, Czech\ntrap, Czech hip hop\ntrap, Czech hip-hop\ntrap, Czech pop\ntrap, Czech rap\ntrap, Czech, Balkan\ntrap, Czech, Eastern\ntrap, Czech, hyperpop\ntrap, Czech, modern\ntrap, Danish hip hop\ntrap, Danish hip-hop\ntrap, Danish, Christmas\ntrap, Desi fusion\ntrap, Desi hip-hop\ntrap, Desi, cinematic\ntrap, Deutschrap\ntrap, Deutschrap, Latin trap\ntrap, Deutschrap, Middle Eastern\ntrap, Deutschrap, Middle Eastern synth\ntrap, Deutschrap, cloud rap\ntrap, Dutch House\ntrap, Dutch House, Melbourne Bounce\ntrap, Dutch club\ntrap, Dutch drill\ntrap, Dutch drill, lo-fi\ntrap, Dutch gangsta rap\ntrap, Dutch hip hop\ntrap, Dutch hip hop, Arabic rap\ntrap, Dutch hip hop, Jamaican patois\ntrap, Dutch hip hop, cinematic\ntrap, Dutch hip hop, dreamy synth\ntrap, Dutch hip hop, lo-fi\ntrap, Dutch hip hop, melodic trap\ntrap, Dutch hip hop, video game synth\ntrap, Dutch hip-hop\ntrap, Dutch hip-hop, Latin guitar\ntrap, Dutch hip-hop, R&B\ntrap, Dutch hip-hop, dancehall\ntrap, Dutch hip-hop, synthwave\ntrap, Dutch rap\ntrap, Dutch rap, Arabic rap\ntrap, Dutch rap, German rap\ntrap, Dutch rap, melodic trap\ntrap, Dutch rap, synthwave\ntrap, EBM, industrial\ntrap, EDM\ntrap, EDM, Balkan\ntrap, EDM, C-pop\ntrap, EDM, Chinese rap\ntrap, EDM, East Asian\ntrap, EDM, East Asian fusion\ntrap, EDM, German rap\ntrap, EDM, Hindi hip hop\ntrap, EDM, Indian devotional\ntrap, EDM, Indian film music\ntrap, EDM, Indian folk\ntrap, EDM, Indian folk fusion\ntrap, EDM, Indian fusion\ntrap, EDM, Indian pop\ntrap, EDM, Kuthu\ntrap, EDM, Latin pop\ntrap, EDM, Mandarin hip-hop\ntrap, EDM, Mandarin rap\ntrap, EDM, Middle Eastern\ntrap, EDM, Middle Eastern fusion\ntrap, EDM, R&B\ntrap, EDM, Russian hip hop\ntrap, EDM, South Asian fusion\ntrap, EDM, South Asian pop\ntrap, EDM, South Indian film music\ntrap, EDM, South Indian folk\ntrap, EDM, Spanish hip hop\ntrap, EDM, Tamil rap\ntrap, EDM, Vietnamese traditional\ntrap, EDM, bass house\ntrap, EDM, chiptune\ntrap, EDM, cinematic\ntrap, EDM, cinematic pop\ntrap, EDM, dark pop\ntrap, EDM, desi hip hop\ntrap, EDM, devotional\ntrap, EDM, electronic\ntrap, EDM, ethnic fusion\ntrap, EDM, fusion\ntrap, EDM, hip-hop\ntrap, EDM, hyperpop\ntrap, EDM, kuthu\ntrap, EDM, lo-fi\ntrap, EDM, lo-fi hip hop\ntrap, EDM, moombahton\ntrap, EDM, party rap\ntrap, EDM, pop-rap\ntrap, EDM, rap-rock\ntrap, EDM, tech-house\ntrap, EDM, traditional East Asian\ntrap, EDM, trance\ntrap, EDM, world fusion\ntrap, EDM, world music\ntrap, EDM-trap, R&B\ntrap, East African\ntrap, East African hip-hop\ntrap, East Asian\ntrap, East Asian ambient\ntrap, East Asian fusion\ntrap, East Asian hip hop\ntrap, East Asian hip-hop\ntrap, East Asian tonality\ntrap, East Asian, Mandarin hip hop\ntrap, East Asian, Mandarin rap\ntrap, East Asian, aggressive\ntrap, East Asian, ambient\ntrap, East Asian, atmospheric\ntrap, East Asian, cinematic\ntrap, East Asian, dark\ntrap, East Asian, electronic\ntrap, East Asian, hip hop\ntrap, East Asian, hip-hop\ntrap, East Asian, instrumental\ntrap, East Asian, lo-fi\ntrap, East Asian, lo-fi hip hop\ntrap, East Asian, melancholic\ntrap, East Asian, melodic\ntrap, East Asian, melodic rap\ntrap, East Asian, modern\ntrap, East Asian, underground\ntrap, East Asian-inspired\ntrap, Eastern Asian, gritty\ntrap, Eastern European\ntrap, Eastern European hip hop\ntrap, Eastern European hip-hop\ntrap, Eastern European pop\ntrap, Eastern European, Balkan\ntrap, Eastern European, German rap\ntrap, Eastern European, Hungarian rap\ntrap, Eastern European, Klezmer\ntrap, Eastern European, Latvian rap\ntrap, Eastern European, Middle Eastern\ntrap, Eastern European, Polish rap\ntrap, Eastern European, Russian hip hop\ntrap, Eastern European, Russian rap\ntrap, Eastern European, Swedish rap\ntrap, Eastern European, Turkish pop\ntrap, Eastern European, aggressive\ntrap, Eastern European, ambient\ntrap, Eastern European, atmospheric\ntrap, Eastern European, cinematic\ntrap, Eastern European, classical\ntrap, Eastern European, dark\ntrap, Eastern European, dombra\ntrap, Eastern European, lo-fi\ntrap, Eastern European, melancholic\ntrap, Eastern European, melodic rap\ntrap, Eastern European, underground\ntrap, Eastern ambient\ntrap, Eastern classical\ntrap, Eastern flavor\ntrap, Eastern flavor, melodic rap\ntrap, Eastern fusion\ntrap, Eastern fusion, hip hop\ntrap, Eastern influence\ntrap, Eastern melisma\ntrap, Eastern melodic\ntrap, Eastern synth\ntrap, Eastern tonality\ntrap, Eastern tonality, Mandarin rap\ntrap, Eastern tonality, lo-fi\ntrap, Eastern, emotional\ntrap, Eastern, lo-fi\ntrap, Eastern, melancholic\ntrap, Eastern-influenced\ntrap, Eastern-influenced, aggressive\ntrap, Eastern-inspired\ntrap, Egyptian Mahraganat\ntrap, Egyptian hip hop\ntrap, Egyptian trap\ntrap, Egyptian, atmospheric\ntrap, Estonian rap\ntrap, European hip-hop\ntrap, European hip-hop, North African hip-hop\ntrap, European rap\ntrap, European trap\ntrap, European trap, Latin trap\ntrap, European, Middle Eastern\ntrap, European, atmospheric\ntrap, European, melodic\ntrap, Filipino gangsta rap\ntrap, Filipino hip hop\ntrap, Filipino hip-hop\ntrap, Filipino hip-hop, dreamy\ntrap, Filipino hip-hop, video game music\ntrap, Filipino pop\ntrap, Finnish hip hop\ntrap, Finnish hip-hop\ntrap, Finnish rap\ntrap, Finnish rap, atmospheric\ntrap, Finnish rap, cinematic\ntrap, Finnish rap, electronic\ntrap, Finnish rap, ethnic synth\ntrap, French Creole hip hop\ntrap, French Creole, Middle Eastern fusion\ntrap, French Creole, aggressive\ntrap, French cloud rap\ntrap, French drill\ntrap, French drill, cinematic\ntrap, French hip hop\ntrap, French hip hop, Arabic rap\ntrap, French hip hop, Haitian Creole\ntrap, French hip hop, Haitian Creole rap\ntrap, French hip hop, Latin pop\ntrap, French hip hop, Lingala rap\ntrap, French hip hop, Mediterranean\ntrap, French hip hop, Papiamento rap\ntrap, French hip hop, Russian rap\ntrap, French hip hop, Swahili rap\ntrap, French hip hop, acoustic\ntrap, French hip hop, acoustic fusion\ntrap, French hip hop, ambient\ntrap, French hip hop, atmospheric\ntrap, French hip hop, cinematic\ntrap, French hip hop, electronic\ntrap, French hip hop, lo-fi\ntrap, French hip hop, melancholic\ntrap, French hip hop, psychedelic\ntrap, French hip hop, retro synth\ntrap, French hip hop, shoegaze\ntrap, French hip hop, synth pop\ntrap, French hip hop, synthwave\ntrap, French hip-hop\ntrap, French hip-hop, Jamaican dancehall\ntrap, French hip-hop, North African\ntrap, French hip-hop, atmospheric R&B\ntrap, French hip-hop, protest music\ntrap, French pop\ntrap, French pop, afrobeat\ntrap, French pop, electronic\ntrap, French pop, world music\ntrap, French pop-rap\ntrap, French rap\ntrap, French rap, Afro-Latin\ntrap, French rap, Afro-soul\ntrap, French rap, American rap\ntrap, French rap, Arabic fusion\ntrap, French rap, Arabic hip hop\ntrap, French rap, Arabic rap\ntrap, French rap, Balkan fusion\ntrap, French rap, Dutch hip hop\ntrap, French rap, Eastern fusion\ntrap, French rap, Islamic devotional\ntrap, French rap, Latin fusion\ntrap, French rap, Latin pop\ntrap, French rap, Lingala\ntrap, French rap, Middle Eastern fusion\ntrap, French rap, Nigerian hip hop\ntrap, French rap, North African\ntrap, French rap, North African pop\ntrap, French rap, Patois\ntrap, French rap, R&B\ntrap, French rap, acoustic\ntrap, French rap, acoustic fusion\ntrap, French rap, ambient\ntrap, French rap, atmospheric\ntrap, French rap, bilingual\ntrap, French rap, chiptune\ntrap, French rap, cinematic\ntrap, French rap, club\ntrap, French rap, dark ambient\ntrap, French rap, dark wave\ntrap, French rap, electronic\ntrap, French rap, emotional\ntrap, French rap, ethereal\ntrap, French rap, flamenco\ntrap, French rap, flamenco fusion\ntrap, French rap, hip-hop\ntrap, French rap, indie pop\ntrap, French rap, jazz fusion\ntrap, French rap, lo-fi\ntrap, French rap, lo-fi synth\ntrap, French rap, melancholic\ntrap, French rap, melodic\ntrap, French rap, melodic hip hop\ntrap, French rap, melodic rap\ntrap, French rap, melodic trap\ntrap, French rap, playful synth\ntrap, French rap, pop\ntrap, French rap, psychedelic\ntrap, French rap, quirky\ntrap, French rap, quirky pop\ntrap, French rap, retro synth\ntrap, French rap, soul\ntrap, French rap, synth pop\ntrap, French rap, synthwave\ntrap, French rap, video game\ntrap, French rap, video game synth\ntrap, French trap\ntrap, French, Arabic\ntrap, French, Jamaican Patois\ntrap, G-funk\ntrap, G-funk, R&B\ntrap, G-funk, West Coast\ntrap, G-funk, West Coast hip-hop\ntrap, G-funk, atmospheric\ntrap, G-funk, cinematic\ntrap, G-funk, cinematic hip hop\ntrap, G-funk, gangsta rap\ntrap, G-funk, hip hop\ntrap, G-funk, hip-hop\ntrap, G-funk, lo-fi hip hop\ntrap, Galician fusion\ntrap, German gangsta rap\ntrap, German hip hop\ntrap, German hip hop, Christmas\ntrap, German hip hop, Danish rap\ntrap, German hip hop, French rap\ntrap, German hip hop, Latin trap\ntrap, German hip hop, Portuguese rap\ntrap, German hip hop, R&B\ntrap, German hip hop, Turkish rap\ntrap, German hip hop, UK rap\ntrap, German hip hop, ambient\ntrap, German hip hop, chopped and screwed\ntrap, German hip hop, cinematic\ntrap, German hip hop, dark ambient\ntrap, German hip hop, electronic\ntrap, German hip hop, lo-fi\ntrap, German hip hop, melancholic\ntrap, German hip hop, melodic rap\ntrap, German hip hop, melodic trap\ntrap, German hip hop, rock\ntrap, German hip-hop\ntrap, German hip-hop, lo-fi hip-hop\ntrap, German pop\ntrap, German rap\ntrap, German rap, Latin pop\ntrap, German rap, Turkish fusion\ntrap, German rap, Turkish hip hop\ntrap, German rap, Turkish pop\ntrap, German rap, Turkish rap\ntrap, German rap, ambient\ntrap, German rap, atmospheric\ntrap, German rap, bilingual\ntrap, German rap, chiptune\ntrap, German rap, cinematic\ntrap, German rap, dark ambient\ntrap, German rap, dark electronic\ntrap, German rap, dreamy\ntrap, German rap, dystopian\ntrap, German rap, electronic\ntrap, German rap, ethereal\ntrap, German rap, flamenco\ntrap, German rap, lo-fi\ntrap, German rap, melancholic\ntrap, German rap, melodic rap\ntrap, German rap, oriental synth\ntrap, German rap, psychedelic\ntrap, German trap\ntrap, German trap, Arabic trap\ntrap, German trap, Turkish trap\ntrap, German, Turkish\ntrap, Greek folk\ntrap, Greek fusion\ntrap, Greek hip hop\ntrap, Greek hip-hop\ntrap, Greek pop\ntrap, Greek rap\ntrap, Greek rap, Spanish melody\ntrap, Greek rap, Spanish rap\ntrap, Greek rap, ambient\ntrap, Greek rap, atmospheric\ntrap, Greek rap, cinematic\ntrap, Greek rap, electronic\ntrap, Greek, atmospheric\ntrap, Greek, electronic\ntrap, Gujarati folk\ntrap, Gujarati hip hop\ntrap, Gujarati pop\ntrap, Haitian Creole\ntrap, Haitian Creole hip hop\ntrap, Haitian Creole rap\ntrap, Haitian Creole, French rap\ntrap, Haitian Creole, atmospheric\ntrap, Haitian Creole, cinematic\ntrap, Haitian Creole, dark ambient\ntrap, Haitian Creole, dark atmosphere\ntrap, Haitian Creole, dreamy\ntrap, Haitian Creole, electronic\ntrap, Haitian Creole, emotional\ntrap, Haitian Creole, ethereal\ntrap, Haitian Creole, lo-fi\ntrap, Haitian Creole, melancholic\ntrap, Haitian Creole, melodic\ntrap, Haitian Creole, melodic rap\ntrap, Haitian Creole, tropical\ntrap, Haitian hip hop\ntrap, Halloween, Mandarin hip hop\ntrap, Halloween, atmospheric\ntrap, Halloween, electronic\ntrap, Haryanvi\ntrap, Haryanvi fusion\ntrap, Haryanvi hip hop\ntrap, Haryanvi hip hop, lo-fi\ntrap, Haryanvi rap\ntrap, Haryanvi rap, folk fusion\ntrap, Haryanvi, cinematic\ntrap, Hausa hip hop\ntrap, Hausa hip-hop\ntrap, Hausa rap\ntrap, Hebrew hip hop\ntrap, Hebrew hip hop, cinematic\ntrap, Hebrew rap\ntrap, Hebrew rap, ambient\ntrap, Hebrew rap, cinematic\ntrap, Hebrew rap, electronic\ntrap, Hebrew vocal, cinematic\ntrap, Hindi fusion\ntrap, Hindi hip hop\ntrap, Hindi hip hop, Punjabi hip hop\ntrap, Hindi hip hop, ambient\ntrap, Hindi hip hop, cinematic\ntrap, Hindi hip hop, dreamy\ntrap, Hindi hip hop, electronic\ntrap, Hindi hip hop, ethereal\ntrap, Hindi hip-hop\ntrap, Hindi hip-hop, melodic pop\ntrap, Hindi pop\ntrap, Hindi pop, ambient\ntrap, Hindi pop, cinematic\ntrap, Hindi pop, dreamy\ntrap, Hindi pop, electronic\ntrap, Hindi pop, lo-fi\ntrap, Hindi rap\ntrap, Hindi rap, ambient\ntrap, Hindi rap, cinematic\ntrap, Hindi rap, mythological\ntrap, Hindi rap, synthwave\ntrap, Hindi, atmospheric\ntrap, Hindi, cinematic\ntrap, Hindi, lo-fi\ntrap, Hindu, hip-hop\ntrap, Hindustani\ntrap, Hindustani hip hop\ntrap, Hindustani pop\ntrap, Hindustani, cinematic\ntrap, Hmong hip-hop\ntrap, Hungarian hip hop\ntrap, Hungarian hip hop, cinematic\ntrap, Hungarian hip hop, synthwave\ntrap, Hungarian pop\ntrap, Hungarian rap\ntrap, Hungarian rap, cinematic\ntrap, Hungarian rap, lo-fi\ntrap, Icelandic hip hop\ntrap, Indian ambient\ntrap, Indian bhajan\ntrap, Indian cinematic\ntrap, Indian classical\ntrap, Indian classical fusion\ntrap, Indian classical, Punjabi folk\ntrap, Indian classical, Tamil hip hop\ntrap, Indian classical, Tamil rap\ntrap, Indian classical, ambient\ntrap, Indian classical, atmospheric\ntrap, Indian classical, bilingual hip hop\ntrap, Indian classical, cinematic\ntrap, Indian classical, dark ambient\ntrap, Indian classical, downtempo\ntrap, Indian classical, electronic\ntrap, Indian classical, experimental\ntrap, Indian classical, folk fusion\ntrap, Indian classical, hip hop\ntrap, Indian classical, hip-hop\ntrap, Indian classical, lo-fi\ntrap, Indian classical, lo-fi hip hop\ntrap, Indian classical, pop\ntrap, Indian classical, romantic\ntrap, Indian classical, spiritual\ntrap, Indian devotional\ntrap, Indian devotional, chiptune\ntrap, Indian devotional, electronic\ntrap, Indian devotional, fusion\ntrap, Indian devotional, hardstyle\ntrap, Indian devotional, hip hop\ntrap, Indian devotional, hip-hop\ntrap, Indian devotional, mystical\ntrap, Indian electronic\ntrap, Indian film music\ntrap, Indian film score\ntrap, Indian flute, ambient\ntrap, Indian flute, cinematic\ntrap, Indian folk\ntrap, Indian folk fusion\ntrap, Indian folk, Bhojpuri\ntrap, Indian folk, Haryanvi\ntrap, Indian folk, ambient\ntrap, Indian folk, chiptune\ntrap, Indian folk, cinematic\ntrap, Indian folk, electronic\ntrap, Indian folk, electronic dance\ntrap, Indian folk, fusion\ntrap, Indian folk, hardstyle\ntrap, Indian folk, hip hop\ntrap, Indian folk, hip-hop\ntrap, Indian folk, hyperpop\ntrap, Indian folk, political\ntrap, Indian folk, spiritual\ntrap, Indian fusion\ntrap, Indian fusion, M bombs\ntrap, Indian fusion, Malayalam hip hop\ntrap, Indian fusion, ambient\ntrap, Indian fusion, cinematic\ntrap, Indian fusion, cinematic hip-hop\ntrap, Indian fusion, dark hip-hop\ntrap, Indian fusion, devotional\ntrap, Indian fusion, electronic\ntrap, Indian fusion, experimental\ntrap, Indian fusion, experimental electronic\ntrap, Indian fusion, glitch\ntrap, Indian fusion, lo-fi hip hop\ntrap, Indian fusion, melodic hip hop\ntrap, Indian fusion, soulful\ntrap, Indian fusion, spiritual\ntrap, Indian hip hop\ntrap, Indian hip hop, cinematic\ntrap, Indian hip hop, electronic\ntrap, Indian hip hop, psychedelic\ntrap, Indian hip hop, retro synth\ntrap, Indian hip-hop\ntrap, Indian hip-hop, cinematic\ntrap, Indian pop\ntrap, Indian pop, R&B\ntrap, Indian pop, ambient\ntrap, Indian pop, atmospheric electronic\ntrap, Indian pop, lo-fi\ntrap, Indian pop, lo-fi hip hop\ntrap, Indian soul\ntrap, Indian vocal, ambient\ntrap, Indian, melancholic\ntrap, Indonesian hip hop\ntrap, Indonesian hip-hop\ntrap, Irish fiddle\ntrap, Irish folk\ntrap, Irish folk, hip-hop\ntrap, Islamic devotional\ntrap, Islamic devotional, Javanese fusion\ntrap, Islamic devotional, fusion\ntrap, Islamic, cinematic\ntrap, Italian R&B\ntrap, Italian ballad\ntrap, Italian drill\ntrap, Italian folk\ntrap, Italian folk, lo-fi\ntrap, Italian gangsta rap\ntrap, Italian hip hop\ntrap, Italian hip hop, French rap\ntrap, Italian hip hop, Spanish rap\ntrap, Italian hip hop, aggressive\ntrap, Italian hip hop, ambient\ntrap, Italian hip hop, chiptune\ntrap, Italian hip hop, cinematic\ntrap, Italian hip hop, classical fusion\ntrap, Italian hip hop, experimental\ntrap, Italian hip hop, folk trap\ntrap, Italian hip hop, lo-fi\ntrap, Italian hip hop, psychedelic\ntrap, Italian hip-hop\ntrap, Italian hip-hop, cinematic\ntrap, Italian hip-hop, folk opera\ntrap, Italian hip-hop, melodic rap\ntrap, Italian melodic rap\ntrap, Italian pop\ntrap, Italian rap\ntrap, Italian rap, Arabic melodic\ntrap, Italian rap, Arabic melody\ntrap, Italian rap, English rap\ntrap, Italian rap, Japanese sample\ntrap, Italian rap, Latin pop\ntrap, Italian rap, Middle Eastern fusion\ntrap, Italian rap, Spanish pop\ntrap, Italian rap, Spanish rap\ntrap, Italian rap, cinematic\ntrap, Italian rap, dark\ntrap, Italian rap, dark hip hop\ntrap, Italian rap, dreamy synth\ntrap, Italian rap, electronic\ntrap, Italian rap, emotional\ntrap, Italian rap, flamenco\ntrap, Italian rap, lo-fi\ntrap, Italian rap, melancholic piano\ntrap, Italian rap, melodic rap\ntrap, Italian rap, melodic trap\ntrap, Italian rap, psychedelic\ntrap, Italian rap, synth\ntrap, Italian, cinematic\ntrap, Italian, melancholic\ntrap, J-core, lo-fi\ntrap, J-hip hop\ntrap, J-hip-hop\ntrap, J-hiphop\ntrap, J-hope\ntrap, J-hope, ambient\ntrap, J-pop\ntrap, J-pop, R&B\ntrap, J-pop, ambient\ntrap, J-pop, cinematic\ntrap, J-pop, cloud rap\ntrap, J-pop, electronic\ntrap, J-pop, electronic dance\ntrap, J-pop, hip hop\ntrap, J-pop, hip-hop\ntrap, J-pop, lo-fi\ntrap, J-pop, lo-fi hip hop\ntrap, J-pop, synthwave\ntrap, J-pop, video game\ntrap, J-rap\ntrap, J-rap, dark electronic\ntrap, J-rap, hip-hop\ntrap, J-rap, world fusion\ntrap, J-rock\ntrap, J-rock, C-pop\ntrap, J-rock, anime rap\ntrap, J-rock, cinematic\ntrap, J-rock, orchestral\ntrap, Jamaican Patois\ntrap, Jamaican Patois rap\ntrap, Jamaican Patois, atmospheric\ntrap, Jamaican Patois, chiptune\ntrap, Jamaican Patois, choral synth\ntrap, Jamaican Patois, cinematic\ntrap, Jamaican Patois, dark atmosphere\ntrap, Jamaican Patois, dark synth\ntrap, Jamaican Patois, lo-fi\ntrap, Jamaican Patois, melodic rap\ntrap, Jamaican Patois, modern hip hop\ntrap, Jamaican Patois, psychedelic\ntrap, Japanese aesthetic\ntrap, Japanese ambient\ntrap, Japanese city pop\ntrap, Japanese folk\ntrap, Japanese fusion\ntrap, Japanese hip hop\ntrap, Japanese hip-hop\ntrap, Japanese influence\ntrap, Japanese koto, cinematic hip-hop\ntrap, Japanese rap\ntrap, Japanese rap, Middle Eastern fusion\ntrap, Japanese warrior, epic\ntrap, Japanese, cinematic\ntrap, Japanese-inspired\ntrap, Japanese-inspired, hip-hop\ntrap, Javanese fusion\ntrap, Javanese hip hop\ntrap, Javanese hip-hop, cinematic\ntrap, Jersey club, R&B\ntrap, K-Rap\ntrap, K-hip-hop\ntrap, K-hip-hop, chiptune\ntrap, K-pop\ntrap, K-pop, Arabic hip hop\ntrap, K-pop, R&B\ntrap, K-pop, ambient\ntrap, K-pop, cinematic\ntrap, K-pop, electronic\ntrap, K-pop, experimental\ntrap, K-pop, hard dance\ntrap, K-pop, hip hop\ntrap, K-pop, lo-fi\ntrap, K-pop, psychedelic\ntrap, K-pop, synth-pop\ntrap, Kannada hip hop\ntrap, Kannada pop\ntrap, Kannada rap\ntrap, Kazakh hip hop\ntrap, Khmer hip hop\ntrap, Khmer hip hop, ambient\ntrap, Khmer hip-hop\ntrap, Kinyarwanda hip hop, ambient\ntrap, Kollywood, electronic\ntrap, Korean hip hop\ntrap, Korean hip hop, Chinese hip hop\ntrap, Korean hip hop, Eastern synth\ntrap, Korean hip hop, atmospheric\ntrap, Korean hip hop, electronic\ntrap, Korean hip-hop\ntrap, Kurdish hip hop\ntrap, Kurdish pop, ambient\ntrap, Latin\ntrap, Latin R&B\ntrap, Latin R&B, global fusion\ntrap, Latin R&B, lo-fi\ntrap, Latin folk\ntrap, Latin folk, lo-fi\ntrap, Latin guitar, ambient\ntrap, Latin hip hop\ntrap, Latin hip hop, cinematic\ntrap, Latin hip hop, electronic\ntrap, Latin hip hop, melodic trap\ntrap, Latin hip-hop\ntrap, Latin hip-hop, EDM\ntrap, Latin hip-hop, vaporwave\ntrap, Latin jazz\ntrap, Latin pop\ntrap, Latin pop, Hebrew rap\ntrap, Latin pop, alternative R&B\ntrap, Latin pop, electronic\ntrap, Latin pop, hyperpop\ntrap, Latin pop, melodic trap\ntrap, Latin trap\ntrap, Latin trap, R&B\ntrap, Latin trap, chiptune\ntrap, Latin urban\ntrap, Latin, Afro-Caribbean\ntrap, Latin, Balkan\ntrap, Latin, Brazilian funk\ntrap, Latin, C-pop\ntrap, Latin, Dutch hip hop\ntrap, Latin, European\ntrap, Latin, Haitian Creole\ntrap, Latin, Mandarin\ntrap, Latin, Middle Eastern\ntrap, Latin, Norwegian hip hop\ntrap, Latin, Polish rap\ntrap, Latin, Russian rap\ntrap, Latin, Turkish pop\ntrap, Latin, UK rap\ntrap, Latin, acoustic\ntrap, Latin, ambient\ntrap, Latin, atmospheric\ntrap, Latin, bossa nova\ntrap, Latin, cinematic\ntrap, Latin, electronic\ntrap, Latin, hip hop\ntrap, Latin, instrumental\ntrap, Latin, jazz\ntrap, Latin, lo-fi\ntrap, Latin, lo-fi hip hop\ntrap, Latin, melancholic\ntrap, Latin, moody\ntrap, Latin-folk\ntrap, Latvian hip hop\ntrap, Lithuanian hip hop\ntrap, Lithuanian rap\ntrap, Mahraganat\ntrap, Malay hip hop\ntrap, Malay hip hop, cinematic\ntrap, Malay hip hop, ethereal\ntrap, Malay hip hop, retro synth\ntrap, Malay hip-hop\ntrap, Malay pop, lo-fi hip hop\ntrap, Malay rap\ntrap, Malayalam hip hop\ntrap, Malayalam hip hop, cinematic\ntrap, Malayalam hip-hop\ntrap, Malayalam pop\ntrap, Malayalam rap\ntrap, Malayalam, ambient\ntrap, Malayalam, atmospheric\ntrap, Mandarin ballad\ntrap, Mandarin hip hop\ntrap, Mandarin hip hop, Cantonese rap\ntrap, Mandarin hip hop, R&B\ntrap, Mandarin hip hop, Vietnamese pop\ntrap, Mandarin hip hop, ambient\ntrap, Mandarin hip hop, atmospheric\ntrap, Mandarin hip hop, cinematic\ntrap, Mandarin hip hop, dreamy trap\ntrap, Mandarin hip hop, electronic\ntrap, Mandarin hip hop, emotional\ntrap, Mandarin hip hop, ethereal\ntrap, Mandarin hip hop, futuristic\ntrap, Mandarin hip hop, jazz fusion\ntrap, Mandarin hip hop, lo-fi\ntrap, Mandarin hip hop, melodic trap\ntrap, Mandarin hip hop, rock\ntrap, Mandarin hip hop, video game\ntrap, Mandarin hip hop, video game synth\ntrap, Mandarin hip-hop\ntrap, Mandarin melodic rap, anime\ntrap, Mandarin pop\ntrap, Mandarin pop, ambient\ntrap, Mandarin pop, atmospheric\ntrap, Mandarin pop, cinematic\ntrap, Mandarin pop, electronic\ntrap, Mandarin pop, ethereal\ntrap, Mandarin rap\ntrap, Mandarin rap, Cantonese rap\ntrap, Mandarin rap, English rap\ntrap, Mandarin rap, Latin percussion\ntrap, Mandarin rap, Mongolian rap\ntrap, Mandarin rap, R&B\ntrap, Mandarin rap, Spanish-influenced\ntrap, Mandarin rap, Turkish pop\ntrap, Mandarin rap, Uyghur hip hop\ntrap, Mandarin rap, acoustic\ntrap, Mandarin rap, ambient\ntrap, Mandarin rap, atmospheric\ntrap, Mandarin rap, chiptune\ntrap, Mandarin rap, cinematic\ntrap, Mandarin rap, dark ambient\ntrap, Mandarin rap, dark pop\ntrap, Mandarin rap, dark synth\ntrap, Mandarin rap, electronic\ntrap, Mandarin rap, emotional\ntrap, Mandarin rap, emotional trap\ntrap, Mandarin rap, ethereal\ntrap, Mandarin rap, experimental\ntrap, Mandarin rap, lo-fi\ntrap, Mandarin rap, lo-fi ambient\ntrap, Mandarin rap, lo-fi synth\ntrap, Mandarin rap, melodic trap\ntrap, Mandarin rap, modern hip hop\ntrap, Mandarin rap, pop\ntrap, Mandarin rap, pop-inflected\ntrap, Mandarin rap, synth\ntrap, Mandarin rap, synthwave\ntrap, Mandarin rap, vaporwave\ntrap, Mandarin rap, video game\ntrap, Mandopop\ntrap, Mandopop, R&B\ntrap, Mandopop, minimalist\ntrap, Manele\ntrap, Manele, Middle Eastern\ntrap, Marathi hip hop\ntrap, Mediterranean\ntrap, Mediterranean fusion\ntrap, Mediterranean hip hop\ntrap, Mediterranean hip-hop\ntrap, Mediterranean, French rap\ntrap, Mediterranean, Greek rap\ntrap, Mediterranean, Italian rap\ntrap, Mediterranean, Middle Eastern\ntrap, Mediterranean, R&B\ntrap, Mediterranean, electronic\ntrap, Mediterranean, lo-fi\ntrap, Mediterranean, lo-fi hip hop\ntrap, Mediterranean, modern\ntrap, Mediterranean, mythological hip-hop\ntrap, Memphis rap\ntrap, Mexican rock\ntrap, Miami bass\ntrap, Middle Eastern\ntrap, Middle Eastern dance\ntrap, Middle Eastern devotional\ntrap, Middle Eastern electronic\ntrap, Middle Eastern folk\ntrap, Middle Eastern fusion\ntrap, Middle Eastern fusion, Balkan electronica\ntrap, Middle Eastern fusion, South Asian\ntrap, Middle Eastern fusion, electronic\ntrap, Middle Eastern fusion, hip-hop\ntrap, Middle Eastern fusion, melodic hip hop\ntrap, Middle Eastern fusion, nu-metal\ntrap, Middle Eastern hip hop\ntrap, Middle Eastern hip-hop\ntrap, Middle Eastern hip-hop, North African\ntrap, Middle Eastern pop\ntrap, Middle Eastern synth\ntrap, Middle Eastern synth, Italian rap\ntrap, Middle Eastern synth, R&B\ntrap, Middle Eastern synth, Spanish rap\ntrap, Middle Eastern synth, hip hop\ntrap, Middle Eastern trap\ntrap, Middle Eastern, Afrobeat\ntrap, Middle Eastern, Anatolian\ntrap, Middle Eastern, Arabic\ntrap, Middle Eastern, Arabic hip hop\ntrap, Middle Eastern, Balkan\ntrap, Middle Eastern, Bollywood\ntrap, Middle Eastern, Brazilian\ntrap, Middle Eastern, C-pop\ntrap, Middle Eastern, Caribbean\ntrap, Middle Eastern, Chinese hip hop\ntrap, Middle Eastern, Danish hip hop\ntrap, Middle Eastern, Danish rap\ntrap, Middle Eastern, Dutch hip hop\ntrap, Middle Eastern, Dutch rap\ntrap, Middle Eastern, Eastern European\ntrap, Middle Eastern, Filipino hip hop\ntrap, Middle Eastern, French hip hop\ntrap, Middle Eastern, French hip-hop\ntrap, Middle Eastern, French rap\ntrap, Middle Eastern, German hip hop\ntrap, Middle Eastern, German rap\ntrap, Middle Eastern, Haitian Creole\ntrap, Middle Eastern, Hebrew hip hop\ntrap, Middle Eastern, Hebrew rap\ntrap, Middle Eastern, Hungarian hip hop\ntrap, Middle Eastern, Hungarian rap\ntrap, Middle Eastern, Indian\ntrap, Middle Eastern, Indonesian hip hop\ntrap, Middle Eastern, Italian hip hop\ntrap, Middle Eastern, Italian hip-hop\ntrap, Middle Eastern, Italian rap\ntrap, Middle Eastern, J-pop\ntrap, Middle Eastern, Japanese hip hop\ntrap, Middle Eastern, Kazakh hip hop\ntrap, Middle Eastern, Latin\ntrap, Middle Eastern, Malay hip hop\ntrap, Middle Eastern, Malayalam hip hop\ntrap, Middle Eastern, Mandarin hip hop\ntrap, Middle Eastern, Mandarin rap\ntrap, Middle Eastern, Nigerian Pidgin\ntrap, Middle Eastern, North African\ntrap, Middle Eastern, Norwegian hip hop\ntrap, Middle Eastern, Persian hip hop\ntrap, Middle Eastern, Phrygian\ntrap, Middle Eastern, Portuguese hip hop\ntrap, Middle Eastern, Portuguese rap\ntrap, Middle Eastern, Punjabi\ntrap, Middle Eastern, R&B\ntrap, Middle Eastern, Romanian hip hop\ntrap, Middle Eastern, Russian hip hop\ntrap, Middle Eastern, Russian rap\ntrap, Middle Eastern, Russian vocal\ntrap, Middle Eastern, South Asian\ntrap, Middle Eastern, Spanish\ntrap, Middle Eastern, Spanish hip hop\ntrap, Middle Eastern, Swahili rap\ntrap, Middle Eastern, Swedish rap\ntrap, Middle Eastern, Swiss hip hop\ntrap, Middle Eastern, Turkish\ntrap, Middle Eastern, Turkish hip hop\ntrap, Middle Eastern, Turkish rap\ntrap, Middle Eastern, acoustic\ntrap, Middle Eastern, aggressive\ntrap, Middle Eastern, ambient\ntrap, Middle Eastern, anthemic\ntrap, Middle Eastern, atmospheric\ntrap, Middle Eastern, auto-tune\ntrap, Middle Eastern, bilingual\ntrap, Middle Eastern, bilingual rap\ntrap, Middle Eastern, boom-bap\ntrap, Middle Eastern, carnival\ntrap, Middle Eastern, chiptune\ntrap, Middle Eastern, choral\ntrap, Middle Eastern, cinematic\ntrap, Middle Eastern, comedic\ntrap, Middle Eastern, conscious hip-hop\ntrap, Middle Eastern, dark\ntrap, Middle Eastern, dark ambient\ntrap, Middle Eastern, dark hip hop\ntrap, Middle Eastern, dark hip-hop\ntrap, Middle Eastern, dark synth\ntrap, Middle Eastern, diss track\ntrap, Middle Eastern, electronic\ntrap, Middle Eastern, emotional\ntrap, Middle Eastern, emotional rap\ntrap, Middle Eastern, emotive\ntrap, Middle Eastern, ethereal\ntrap, Middle Eastern, ethnic\ntrap, Middle Eastern, experimental\ntrap, Middle Eastern, hard-hitting\ntrap, Middle Eastern, hip hop\ntrap, Middle Eastern, hip-hop\ntrap, Middle Eastern, hypnotic\ntrap, Middle Eastern, instrumental\ntrap, Middle Eastern, instrumental hip-hop\ntrap, Middle Eastern, lo-fi\ntrap, Middle Eastern, lo-fi hip hop\ntrap, Middle Eastern, melancholic\ntrap, Middle Eastern, melodic\ntrap, Middle Eastern, melodic rap\ntrap, Middle Eastern, microtonal\ntrap, Middle Eastern, modern\ntrap, Middle Eastern, modern hip hop\ntrap, Middle Eastern, multilingual\ntrap, Middle Eastern, mystical\ntrap, Middle Eastern, phonk\ntrap, Middle Eastern, political\ntrap, Middle Eastern, pop\ntrap, Middle Eastern, pop-R&B\ntrap, Middle Eastern, rap\ntrap, Middle Eastern, reggae\ntrap, Middle Eastern, ritual\ntrap, Middle Eastern, rock\ntrap, Middle Eastern, sensual\ntrap, Middle Eastern, soul\ntrap, Middle Eastern, spiritual\ntrap, Middle Eastern, underground\ntrap, Middle Eastern, urban\ntrap, Middle Eastern, vocal\ntrap, Middle Eastern, world fusion\ntrap, Middle Eastern, world music\ntrap, Mongolian folk\ntrap, Mongolian fusion\ntrap, Mongolian hip hop\ntrap, Mongolian hip hop, Chinese rap\ntrap, Mongolian hip hop, R&B\ntrap, Mongolian hip hop, ambient\ntrap, Mongolian hip hop, retro synth\ntrap, Mongolian hip-hop\ntrap, Mongolian rap\ntrap, Moroccan Arabic\ntrap, Moroccan Arabic hip hop\ntrap, Moroccan Arabic rap\ntrap, Moroccan Arabic, ambient\ntrap, Moroccan Arabic, atmospheric\ntrap, Moroccan Arabic, dark\ntrap, Moroccan Arabic, dark ambient\ntrap, Moroccan Arabic, lo-fi\ntrap, Moroccan Arabic, melodic\ntrap, Moroccan fusion\ntrap, Moroccan hip hop\ntrap, Moroccan hip-hop\ntrap, Māori fusion\ntrap, Neapolitan\ntrap, Neapolitan pop, cinematic\ntrap, Nepali hip hop\ntrap, Nepali hip hop, atmospheric\ntrap, Nepali hip-hop\ntrap, Nepali, lo-fi\ntrap, Nigerian Pidgin\ntrap, Nigerian Pidgin hip hop\ntrap, Nigerian Pidgin rap\ntrap, Nigerian Pidgin, Yoruba\ntrap, Nigerian Pidgin, aggressive\ntrap, Nigerian Pidgin, atmospheric\ntrap, Nigerian Pidgin, dark ambient\ntrap, Nigerian Pidgin, dark atmosphere\ntrap, Nigerian Pidgin, electronic\ntrap, Nigerian Pidgin, hard-hitting\ntrap, Nigerian Pidgin, lo-fi\ntrap, Nigerian Pidgin, soul\ntrap, Nigerian Pidgin, video game\ntrap, Nigerian hip hop\ntrap, Nordic fusion\ntrap, Nordic hip hop\ntrap, Nordic, ambient\ntrap, Nordic, emotional\ntrap, North African\ntrap, North African folk\ntrap, North African fusion\ntrap, North African hip hop\ntrap, North African hip-hop\ntrap, North African pop\ntrap, North African pop, R&B\ntrap, North African pop, ambient\ntrap, North African pop-rap\ntrap, North African rap\ntrap, North African trap\ntrap, North African, Arabic hip hop\ntrap, North African, Arabic hip-hop\ntrap, North African, French\ntrap, North African, French rap\ntrap, North African, Middle Eastern\ntrap, North African, UK rap\ntrap, North African, ambient\ntrap, North African, atmospheric\ntrap, North African, cinematic\ntrap, North African, dark\ntrap, North African, electronic\ntrap, North African, emotional\ntrap, North African, hip hop\ntrap, North African, hip-hop\ntrap, North African, lo-fi\ntrap, North African, lo-fi hip hop\ntrap, North African, melancholic\ntrap, North African, melodic\ntrap, North African, melodic rap\ntrap, North African, modern\ntrap, North African, modern hip-hop\ntrap, North African, multilingual\ntrap, North African, oud\ntrap, Norwegian hip hop\ntrap, Norwegian rap\ntrap, Peking Opera, lo-fi\ntrap, Persian emo, atmospheric\ntrap, Persian folk, electronic\ntrap, Persian fusion\ntrap, Persian hip hop\ntrap, Persian hip hop, Arabic rap\ntrap, Persian hip hop, ambient\ntrap, Persian hip hop, cinematic\ntrap, Persian hip hop, lo-fi\ntrap, Persian hip-hop\ntrap, Persian hip-hop, ambient\ntrap, Persian hip-hop, lo-fi\ntrap, Persian pop\ntrap, Persian pop, R&B\ntrap, Persian pop, acoustic\ntrap, Persian pop, ambient\ntrap, Persian pop, cinematic\ntrap, Persian rap\ntrap, Persian rap, ambient\ntrap, Persian rap, atmospheric\ntrap, Persian rap, cinematic\ntrap, Persian rap, lo-fi\ntrap, Persian rap, lo-fi hip hop\ntrap, Persian rap, synthwave\ntrap, Persian soul\ntrap, Persian, ambient\ntrap, Persian, atmospheric\ntrap, Persian, cinematic\ntrap, Persian, melancholic\ntrap, Polish folk\ntrap, Polish gangsta rap\ntrap, Polish hip hop\ntrap, Polish hip-hop\ntrap, Polish rap\ntrap, Polish rap, R&B\ntrap, Polish rap, cinematic\ntrap, Polish rap, dark pop\ntrap, Polish rap, melodic\ntrap, Polish rap, synthwave\ntrap, Polish street rap\ntrap, Portuguese hip hop\ntrap, Portuguese hip-hop\ntrap, Portuguese rap\ntrap, Punjabi\ntrap, Punjabi R&B\ntrap, Punjabi folk\ntrap, Punjabi folk, R&B\ntrap, Punjabi folk, ambient\ntrap, Punjabi folk, cinematic\ntrap, Punjabi folk, electronic\ntrap, Punjabi folk, fusion\ntrap, Punjabi folk, hip-hop\ntrap, Punjabi folk, jazz\ntrap, Punjabi folk, lo-fi\ntrap, Punjabi fusion\ntrap, Punjabi hip hop\ntrap, Punjabi hip hop, R&B\ntrap, Punjabi hip hop, UK drill\ntrap, Punjabi hip hop, acoustic\ntrap, Punjabi hip hop, ambient\ntrap, Punjabi hip hop, cinematic\ntrap, Punjabi hip hop, flamenco fusion\ntrap, Punjabi hip hop, futuristic\ntrap, Punjabi hip hop, lo-fi\ntrap, Punjabi hip hop, retro synth\ntrap, Punjabi hip-hop\ntrap, Punjabi hip-hop, UK drill\ntrap, Punjabi hip-hop, cinematic\ntrap, Punjabi hip-hop, dreamy\ntrap, Punjabi hip-hop, lo-fi\ntrap, Punjabi hip-hop, vaporwave\ntrap, Punjabi pop\ntrap, Punjabi pop, ambient\ntrap, Punjabi pop, cinematic\ntrap, Punjabi pop, electronic\ntrap, Punjabi pop, hip hop\ntrap, Punjabi pop, lo-fi\ntrap, Punjabi pop, lo-fi hip hop\ntrap, Punjabi pop, moombahton\ntrap, Punjabi pop, synthwave\ntrap, Punjabi rap\ntrap, Punjabi rap, atmospheric\ntrap, Punjabi rap, chiptune\ntrap, Punjabi rap, electronic\ntrap, Punjabi rap, lo-fi\ntrap, Punjabi, Caribbean\ntrap, Punjabi, German hip hop\ntrap, Punjabi, Hindi\ntrap, Punjabi, Indian classical\ntrap, Punjabi, Latin\ntrap, Punjabi, Middle Eastern\ntrap, Punjabi, R&B\ntrap, Punjabi, Spanish\ntrap, Punjabi, acoustic\ntrap, Punjabi, ambient\ntrap, Punjabi, atmospheric\ntrap, Punjabi, blues-rock\ntrap, Punjabi, cinematic\ntrap, Punjabi, classical fusion\ntrap, Punjabi, electric guitar\ntrap, Punjabi, electronic\ntrap, Punjabi, emo-rap\ntrap, Punjabi, ethereal\ntrap, Punjabi, folk fusion\ntrap, Punjabi, fusion\ntrap, Punjabi, hard-hitting\ntrap, Punjabi, hip hop\ntrap, Punjabi, lo-fi\ntrap, Punjabi, lo-fi hip hop\ntrap, Punjabi, mariachi\ntrap, Punjabi, melancholic\ntrap, Punjabi, melodic\ntrap, Punjabi, melodic rap\ntrap, Punjabi, oud\ntrap, Punjabi, romantic\ntrap, Punjabi, soul\ntrap, Punjabi, synth\ntrap, Punjabi, synthwave\ntrap, Punjabi, vaporwave\ntrap, Quebecois hip hop\ntrap, R&B\ntrap, R&B, Afro-English\ntrap, R&B, Afro-Spanish\ntrap, R&B, Afro-Trap\ntrap, R&B, Afro-hip hop\ntrap, R&B, Afro-pop\ntrap, R&B, Afrobeat\ntrap, R&B, Afrobeats\ntrap, R&B, Arabic\ntrap, R&B, Arabic fusion\ntrap, R&B, Arabic hip hop\ntrap, R&B, Arabic hip-hop\ntrap, R&B, Arabic pop\ntrap, R&B, Balkan\ntrap, R&B, Balkan fusion\ntrap, R&B, Brazilian\ntrap, R&B, Brazilian pop\ntrap, R&B, Brazilian trap\ntrap, R&B, British hip hop\ntrap, R&B, Bulgarian\ntrap, R&B, C-pop\ntrap, R&B, Caribbean pop\ntrap, R&B, Chinese\ntrap, R&B, Chinese ambient\ntrap, R&B, Chinese electronic\ntrap, R&B, Chinese hip hop\ntrap, R&B, Chinese hip-hop\ntrap, R&B, Chinese pop\ntrap, R&B, Chinese traditional\ntrap, R&B, Christmas\ntrap, R&B, Christmas parody\ntrap, R&B, Czech hip hop\ntrap, R&B, Danish hip hop\ntrap, R&B, Dutch hip hop\ntrap, R&B, Dutch hip-hop\ntrap, R&B, East Asian fusion\ntrap, R&B, Eastern flavor\ntrap, R&B, Eastern fusion\ntrap, R&B, Filipino hip hop\ntrap, R&B, Finnish hip hop\ntrap, R&B, French hip hop\ntrap, R&B, French rap\ntrap, R&B, G-funk\ntrap, R&B, German hip hop\ntrap, R&B, German rap\ntrap, R&B, Greek\ntrap, R&B, Hindi hip hop\ntrap, R&B, Indian classical\ntrap, R&B, Indian fusion\ntrap, R&B, Indian hip hop\ntrap, R&B, Indian hip-hop\ntrap, R&B, Indian pop\ntrap, R&B, Italian chant\ntrap, R&B, Italian hip hop\ntrap, R&B, J-pop\ntrap, R&B, K-pop\ntrap, R&B, Khmer hip hop\ntrap, R&B, Latin\ntrap, R&B, Latin hip hop\ntrap, R&B, Latin hip-hop\ntrap, R&B, Latin pop\ntrap, R&B, Malay hip hop\ntrap, R&B, Mandarin hip hop\ntrap, R&B, Mandarin hip-hop\ntrap, R&B, Mandopop\ntrap, R&B, Middle Eastern\ntrap, R&B, Middle Eastern fusion\ntrap, R&B, Moroccan hip hop\ntrap, R&B, Ney flute\ntrap, R&B, North African\ntrap, R&B, Persian pop\ntrap, R&B, Polish hip hop\ntrap, R&B, Portuguese hip hop\ntrap, R&B, Punjabi\ntrap, R&B, Punjabi hip-hop\ntrap, R&B, Punjabi pop\ntrap, R&B, Quebecois hip hop\ntrap, R&B, Romanian hip hop\ntrap, R&B, Russian hip-hop\ntrap, R&B, Scandinavian hip-hop\ntrap, R&B, South Asian\ntrap, R&B, South Asian fusion\ntrap, R&B, South Asian pop\ntrap, R&B, Southern hip hop\ntrap, R&B, Spanish\ntrap, R&B, Spanish flavor\ntrap, R&B, Spanish-influenced\ntrap, R&B, Tamil hip hop\ntrap, R&B, Telugu\ntrap, R&B, Thai pop\ntrap, R&B, Turkish folk\ntrap, R&B, Turkish hip hop\ntrap, R&B, Turkish hip-hop\ntrap, R&B, Turkish pop\ntrap, R&B, UK rap\ntrap, R&B, Vietnamese hip hop\ntrap, R&B, acoustic fusion\ntrap, R&B, ambient\ntrap, R&B, ambient pop\ntrap, R&B, anime\ntrap, R&B, atmospheric\ntrap, R&B, atmospheric hip-hop\ntrap, R&B, atmospheric pop\ntrap, R&B, bilingual\ntrap, R&B, bilingual hip hop\ntrap, R&B, bilingual hip-hop\ntrap, R&B, blues\ntrap, R&B, boom-bap\ntrap, R&B, chillwave\ntrap, R&B, chiptune\ntrap, R&B, chopped and screwed\ntrap, R&B, choral\ntrap, R&B, cinematic\ntrap, R&B, cinematic hip hop\ntrap, R&B, cinematic hip-hop\ntrap, R&B, cloud rap\ntrap, R&B, conscious hip-hop\ntrap, R&B, contemporary Christian\ntrap, R&B, dance-pop\ntrap, R&B, dancehall\ntrap, R&B, dark ambient\ntrap, R&B, dream pop\ntrap, R&B, dreamy\ntrap, R&B, dubstep\ntrap, R&B, electronic\ntrap, R&B, emo rap\ntrap, R&B, emotional hip hop\ntrap, R&B, emotional hip-hop\ntrap, R&B, emotional rap\ntrap, R&B, ethereal\ntrap, R&B, ethnic fusion\ntrap, R&B, experimental\ntrap, R&B, flamenco\ntrap, R&B, fusion\ntrap, R&B, future bass\ntrap, R&B, ghazal\ntrap, R&B, glitch\ntrap, R&B, gospel\ntrap, R&B, hardstyle\ntrap, R&B, hip hop\ntrap, R&B, hip-hop\ntrap, R&B, hyperpop\ntrap, R&B, industrial\ntrap, R&B, industrial hip hop\ntrap, R&B, jazz\ntrap, R&B, live performance\ntrap, R&B, lo-fi\ntrap, R&B, lo-fi hip hop\ntrap, R&B, lo-fi hip-hop\ntrap, R&B, melodic hip hop\ntrap, R&B, melodic rap\ntrap, R&B, modern hip hop\ntrap, R&B, multilingual hip-hop\ntrap, R&B, multilingual rap\ntrap, R&B, neo-soul\ntrap, R&B, ney flute\ntrap, R&B, operatic\ntrap, R&B, oud\ntrap, R&B, parody\ntrap, R&B, political hip hop\ntrap, R&B, pop\ntrap, R&B, pop-rap\ntrap, R&B, post-rock\ntrap, R&B, psychedelic\ntrap, R&B, psychedelic hip hop\ntrap, R&B, reggaeton\ntrap, R&B, soul\ntrap, R&B, spoken word\ntrap, R&B, synth-pop\ntrap, R&B, synthwave\ntrap, R&B, traditional Central Asian\ntrap, R&B, traditional fusion\ntrap, R&B, vaporwave\ntrap, R&B, world fusion\ntrap, R&B, world music\ntrap, Rai\ntrap, Rai music\ntrap, Rai, North African fusion\ntrap, Rai, ambient\ntrap, Rai, atmospheric\ntrap, Rai, electronic\ntrap, Rai, lo-fi\ntrap, Rai, modern hip-hop\ntrap, Rajasthani folk\ntrap, Romani music\ntrap, Romanian Manele, cinematic\ntrap, Romanian hip hop\ntrap, Romanian hip hop, Spanish hip hop\ntrap, Romanian hip hop, Spanish rap\ntrap, Romanian hip hop, dark ambient\ntrap, Romanian hip hop, retro synth\ntrap, Romanian hip-hop\ntrap, Romanian pop\ntrap, Romanian pop, manele\ntrap, Romanian rap\ntrap, Romanian rap, chiptune\ntrap, Romanian rap, jazz fusion\ntrap, Romanian trap\ntrap, Russian emo\ntrap, Russian emo, acoustic\ntrap, Russian folk\ntrap, Russian hip hop\ntrap, Russian hip hop, Caribbean hip hop\ntrap, Russian hip hop, cinematic\ntrap, Russian hip hop, dark ambient\ntrap, Russian hip hop, melodic trap\ntrap, Russian hip hop, synthwave\ntrap, Russian hip-hop\ntrap, Russian hip-hop, festive\ntrap, Russian hip-hop, lo-fi\ntrap, Russian influence\ntrap, Russian pop\ntrap, Russian pop, hip-hop\ntrap, Russian pop-rap\ntrap, Russian rap\ntrap, Russian rap, Azerbaijani pop\ntrap, Russian rap, Eastern flavor\ntrap, Russian rap, German rap\ntrap, Russian rap, Jamaican Patois\ntrap, Russian rap, Kazakh rap\ntrap, Russian rap, Latin fusion\ntrap, Russian rap, R&B\ntrap, Russian rap, Spanish rap\ntrap, Russian rap, acoustic\ntrap, Russian rap, aggressive\ntrap, Russian rap, ambient\ntrap, Russian rap, atmospheric\ntrap, Russian rap, bilingual\ntrap, Russian rap, chopper\ntrap, Russian rap, cinematic\ntrap, Russian rap, dark ambient\ntrap, Russian rap, dark club\ntrap, Russian rap, dark electronic\ntrap, Russian rap, electronic\ntrap, Russian rap, ethnic fusion\ntrap, Russian rap, flamenco\ntrap, Russian rap, folk fusion\ntrap, Russian rap, futuristic\ntrap, Russian rap, industrial\ntrap, Russian rap, international\ntrap, Russian rap, lo-fi\ntrap, Russian rap, melodic rap\ntrap, Russian rap, melodic trap\ntrap, Russian rap, psychedelic\ntrap, Russian rap, retro game\ntrap, Russian rap, synthwave\ntrap, Russian rap, video game style\ntrap, Russian romance\ntrap, Russian vocal\ntrap, Russian, melancholic\ntrap, Scandinavian, atmospheric\ntrap, Shona hip hop\ntrap, Sichuanese hip hop\ntrap, Sichuanese rap\ntrap, Sinhala folk\ntrap, Sinhala folk, electronic\ntrap, Sinhala folk, modern fusion\ntrap, Sinhala hip hop\ntrap, Sinhala hip hop, atmospheric\ntrap, Sinhala pop, ambient\ntrap, Sinhala rap\ntrap, Slavic folk\ntrap, Slavic folk, choral\ntrap, Slavic folk, cinematic\ntrap, Slavic folk, dark ambient\ntrap, Slavic folk, electronic\ntrap, Slavic, atmospheric\ntrap, Slavic, modern\ntrap, Slovak\ntrap, Slovak hip hop\ntrap, Slovak hip-hop\ntrap, Slovak rap\ntrap, Slovak, Balkan\ntrap, SoundCloud rap\ntrap, South African hip-hop\ntrap, South Asian\ntrap, South Asian classical\ntrap, South Asian classical, Bengali pop\ntrap, South Asian classical, cinematic\ntrap, South Asian classical, reggae\ntrap, South Asian devotional, electronic\ntrap, South Asian film score\ntrap, South Asian folk\ntrap, South Asian folk, electronic\ntrap, South Asian folk, fusion\ntrap, South Asian fusion\ntrap, South Asian fusion, R&B\ntrap, South Asian fusion, cinematic\ntrap, South Asian fusion, hyperpop\ntrap, South Asian fusion, metal\ntrap, South Asian fusion, urban pop\ntrap, South Asian hip hop\ntrap, South Asian hip-hop\ntrap, South Asian pop\ntrap, South Asian, French\ntrap, South Asian, Middle Eastern\ntrap, South Asian, Punjabi\ntrap, South Asian, R&B\ntrap, South Asian, ambient\ntrap, South Asian, atmospheric\ntrap, South Asian, ballad\ntrap, South Asian, cinematic\ntrap, South Asian, electronic\ntrap, South Asian, emotional\ntrap, South Asian, emotive\ntrap, South Asian, hip hop\ntrap, South Asian, lo-fi\ntrap, South Asian, melancholic\ntrap, South Asian, modern\ntrap, South Indian film music\ntrap, South Indian film music, electronic\ntrap, South Indian folk\ntrap, South Indian folk, electronic\ntrap, South Indian fusion\ntrap, South Indian hip-hop\ntrap, South Indian hip-hop, cinematic\ntrap, South Indian, ambient\ntrap, South Indian, fusion\ntrap, South Indian, mystical\ntrap, Southeast Asian folk\ntrap, Southeast Asian folk, jazz fusion\ntrap, Southeast Asian fusion\ntrap, Southeast Asian pop\ntrap, Southeast Asian, atmospheric\ntrap, Southeast Asian, modern\ntrap, Southern Gothic\ntrap, Southern gangsta rap\ntrap, Southern gothic\ntrap, Southern hip hop\ntrap, Southern hip-hop\ntrap, Southern hip-hop, R&B\ntrap, Southern hip-hop, blues\ntrap, Southern hip-hop, cinematic\ntrap, Southern hip-hop, crunk\ntrap, Southern hip-hop, lo-fi\ntrap, Southern rap\ntrap, Spanish\ntrap, Spanish acoustic\ntrap, Spanish classical\ntrap, Spanish flair, Russian rap\ntrap, Spanish flavor\ntrap, Spanish flavor, Dutch rap\ntrap, Spanish flavor, lo-fi\ntrap, Spanish flavor, lo-fi hip hop\ntrap, Spanish flavor, melodic rap\ntrap, Spanish folk\ntrap, Spanish fusion\ntrap, Spanish guitar\ntrap, Spanish guitar, Malay rap\ntrap, Spanish guitar, aggressive\ntrap, Spanish guitar, anime hip-hop\ntrap, Spanish hip hop\ntrap, Spanish hip-hop\ntrap, Spanish indie\ntrap, Spanish influence\ntrap, Spanish pop\ntrap, Spanish rap\ntrap, Spanish rap, acoustic\ntrap, Spanish rap, anthemic\ntrap, Spanish rap, atmospheric\ntrap, Spanish rap, cinematic\ntrap, Spanish rap, dark ambient\ntrap, Spanish rap, lo-fi\ntrap, Spanish rap, melodic hip hop\ntrap, Spanish street rap\ntrap, Spanish, Russian rap\ntrap, Spanish, bilingual\ntrap, Spanish, lo-fi\ntrap, Spanish, melancholic\ntrap, Spanish-influenced, lo-fi\ntrap, Spanish-style\ntrap, Spanish-style acoustic\ntrap, Spanish-style, Russian vocal\ntrap, Spanish-style, Southern hip hop\ntrap, Spanish-style, aggressive\ntrap, Spanish-style, bilingual\ntrap, Spanish-style, cinematic\ntrap, Spanish-style, gangsta rap\ntrap, Spanish-style, gritty\ntrap, Spanish-style, hip-hop\ntrap, Spanish-style, lo-fi\ntrap, Spanish-style, lo-fi hip hop\ntrap, Spanish-style, melancholic\ntrap, Spanish-style, melodic\ntrap, Spanish-style, melodic rap\ntrap, Sufi devotional\ntrap, Sufi, Arabic\ntrap, Sundanese hip hop\ntrap, Sundanese hip-hop\ntrap, Swahili hip hop\ntrap, Swahili hip-hop\ntrap, Swahili rap\ntrap, Swedish R&B\ntrap, Swedish drill, lo-fi\ntrap, Swedish hip hop\ntrap, Swedish hip-hop\ntrap, Swedish melodic rap\ntrap, Swedish pop, cinematic\ntrap, Swedish rap\ntrap, Swedish rap, ambient\ntrap, Swedish rap, atmospheric\ntrap, Swedish rap, bilingual\ntrap, Swedish rap, lo-fi\ntrap, Swedish rap, oriental fusion\ntrap, Swedish rap, video game\ntrap, Swiss German hip hop\ntrap, Swiss hip hop\ntrap, Swiss-German\ntrap, Tagalog rap\ntrap, Taiwanese Hokkien hip hop\ntrap, Taiwanese Hokkien, electronic\ntrap, Taiwanese hip hop\ntrap, Tamil\ntrap, Tamil folk\ntrap, Tamil folk, Carnatic\ntrap, Tamil folk, cinematic\ntrap, Tamil fusion\ntrap, Tamil fusion, cinematic\ntrap, Tamil fusion, electronic\ntrap, Tamil hip hop\ntrap, Tamil hip hop, Hindi rap\ntrap, Tamil hip hop, R&B\ntrap, Tamil hip hop, ambient\ntrap, Tamil hip-hop\ntrap, Tamil hip-hop, cinematic\ntrap, Tamil pop, ambient\ntrap, Tamil pop, cinematic\ntrap, Tamil pop, electronic\ntrap, Tamil pop, lo-fi\ntrap, Tamil pop, melodic rap\ntrap, Tamil rap\ntrap, Tamil soul\ntrap, Tamil storytelling, cinematic\ntrap, Tamil, ambient\ntrap, Tamil, cinematic\ntrap, Tamil, electronic\ntrap, Tatar folk\ntrap, Tatar hip hop\ntrap, Telugu hip hop\ntrap, Telugu pop\ntrap, Thai folk\ntrap, Thai folk, Luk Thung\ntrap, Thai hip hop\ntrap, Thai hip hop, ambient\ntrap, Thai hip-hop\ntrap, Thai pop\ntrap, Tibetan folk\ntrap, Tibetan fusion\ntrap, Tibetan hip hop\ntrap, Tibetan pop\ntrap, Tibetan pop, lo-fi hip hop\ntrap, Tibetan style, hip-hop\ntrap, Turkish arabesque\ntrap, Turkish classical\ntrap, Turkish folk\ntrap, Turkish folk, German rap\ntrap, Turkish folk, R&B\ntrap, Turkish folk, Russian rap\ntrap, Turkish folk, ambient\ntrap, Turkish folk, atmospheric\ntrap, Turkish folk, cinematic\ntrap, Turkish folk, hip hop\ntrap, Turkish folk, lo-fi\ntrap, Turkish folk, oud\ntrap, Turkish fusion\ntrap, Turkish fusion, cinematic\ntrap, Turkish gangsta rap\ntrap, Turkish hip hop\ntrap, Turkish hip hop, Balkan rap\ntrap, Turkish hip hop, Dutch rap\ntrap, Turkish hip hop, Persian pop\ntrap, Turkish hip hop, Russian rap\ntrap, Turkish hip hop, acoustic\ntrap, Turkish hip hop, ambient\ntrap, Turkish hip hop, cinematic\ntrap, Turkish hip hop, dark electronic\ntrap, Turkish hip hop, dark synth\ntrap, Turkish hip hop, lo-fi\ntrap, Turkish hip hop, synthwave\ntrap, Turkish hip-hop\ntrap, Turkish hip-hop, German hip-hop\ntrap, Turkish melodic\ntrap, Turkish pop\ntrap, Turkish pop, German rap\ntrap, Turkish pop, Russian rap\ntrap, Turkish pop, acoustic\ntrap, Turkish pop, cinematic\ntrap, Turkish pop, electronic\ntrap, Turkish pop, ethereal\ntrap, Turkish pop, lo-fi\ntrap, Turkish pop, lo-fi hip hop\ntrap, Turkish pop, melancholic\ntrap, Turkish pop, world fusion\ntrap, Turkish rap\ntrap, Turkish rap, German rap\ntrap, Turkish rap, Middle Eastern fusion\ntrap, Turkish rap, ambient\ntrap, Turkish rap, chopper\ntrap, Turkish rap, cinematic\ntrap, Turkish rap, dark ambient\ntrap, Turkish rap, electronic\ntrap, Turkish saz\ntrap, Turkish saz, dark electronic\ntrap, Turkish saz, electronic\ntrap, Turkish saz, lo-fi hip hop\ntrap, Turkish trap\ntrap, Turkish, Hindi\ntrap, Turkish, atmospheric\ntrap, Turkish, cinematic\ntrap, Turkish, electronic\ntrap, Turkish, lo-fi\ntrap, Turkish, melancholic\ntrap, Turkish, melodic rap\ntrap, Turkish, sports anthem\ntrap, UK drill\ntrap, UK drill, C-pop\ntrap, UK drill, Hindi pop\ntrap, UK drill, R&B\ntrap, UK drill, Turkish hip hop\ntrap, UK drill, atmospheric\ntrap, UK drill, chiptune\ntrap, UK drill, cinematic\ntrap, UK drill, dancehall\ntrap, UK drill, grime\ntrap, UK drill, hip-hop\ntrap, UK drill, lo-fi hip hop\ntrap, UK garage\ntrap, UK garage, emotional rap\ntrap, UK garage, melodic rap\ntrap, UK hip-hop, electronic\ntrap, UK rap\ntrap, UK rap, Afrobeats\ntrap, UK rap, R&B\ntrap, UK rap, chopped and screwed\ntrap, UK rap, cinematic\ntrap, UK rap, melodic rap\ntrap, UK rap, psychedelic\ntrap, Ukrainian folk\ntrap, Ukrainian hip hop\ntrap, Ukrainian hip-hop\ntrap, Ukrainian pop\ntrap, Ukrainian rap\ntrap, Urdu hip hop\ntrap, Urdu, cinematic\ntrap, Uyghur hip hop\ntrap, V-Pop\ntrap, V-Rap\ntrap, Venezuelan hip hop\ntrap, Vietnamese folk\ntrap, Vietnamese fusion\ntrap, Vietnamese hip hop\ntrap, Vietnamese hip hop, ambient\ntrap, Vietnamese hip hop, cinematic\ntrap, Vietnamese hip hop, lo-fi\ntrap, Vietnamese pop\ntrap, Vietnamese pop, melodic rap\ntrap, Vietnamese rap\ntrap, Vietnamese, guzheng\ntrap, Vocaloid, ambient\ntrap, Vocaloid, lo-fi hip hop\ntrap, West African hip hop\ntrap, West African, cinematic\ntrap, West African, electronic\ntrap, West Coast\ntrap, West Coast gangsta rap\ntrap, West Coast hip hop\ntrap, West Coast hip-hop\ntrap, West Coast, ambient\ntrap, West Coast, dreamy\ntrap, Zulu hip hop\ntrap, accordion\ntrap, acid house, cloud rap\ntrap, acoustic\ntrap, acoustic ballad\ntrap, acoustic ballad, bilingual\ntrap, acoustic, Dutch hip hop\ntrap, acoustic, Dutch rap\ntrap, acoustic, German pop\ntrap, acoustic, Kazakh hip-hop\ntrap, acoustic, Russian rock\ntrap, acoustic, Swedish hip-hop\ntrap, acoustic, Turkish spoken word\ntrap, acoustic, emotional\ntrap, acoustic, ethereal\ntrap, afrikaans hip hop\ntrap, afro-fusion\ntrap, afro-fusion, alternative R&B\ntrap, afro-trap\ntrap, afro-trap, Middle Eastern\ntrap, afro-trap, R&B\ntrap, afro-trap, afrobeat\ntrap, afro-trap, bilingual\ntrap, afro-trap, chiptune\ntrap, afro-trap, cloud rap\ntrap, afro-trap, dancehall\ntrap, afro-trap, gospel\ntrap, afro-trap, lo-fi\ntrap, afrobeat\ntrap, afrobeat, Balkan pop\ntrap, afrobeat, Middle Eastern\ntrap, afrobeat, R&B\ntrap, afrobeat, UK drill\ntrap, afrobeat, ambient\ntrap, afrobeat, cloud rap\ntrap, afrobeat, dancehall\ntrap, afrobeat, hip-hop\ntrap, afrobeat, lo-fi\ntrap, afrobeat, pop\ntrap, afrobeat, pop-rap\ntrap, afrobeat, world music\ntrap, afrobeats\ntrap, afrobeats, R&B\ntrap, afrobeats, ambient\ntrap, afrobeats, dancehall\ntrap, afrobeats, ethnic fusion\ntrap, afrobeats, glitch\ntrap, afrobeats, lo-fi\ntrap, afrobeats, pop-rap\ntrap, aggressive hip-hop\ntrap, aggressive rap\ntrap, aggressive, Mandarin hip hop\ntrap, aggressive, cinematic\ntrap, aggressive, dark\ntrap, aggressive, electronic\ntrap, aggressive, violin\ntrap, aggro, Latin hip hop\ntrap, aggro, Middle Eastern fusion\ntrap, aggro, Middle Eastern trap\ntrap, aggro, South Asian fusion\ntrap, aggro, desi\ntrap, aggro, ethnic fusion\ntrap, agressive, Tagalog hip hop\ntrap, alaap, melancholic\ntrap, alpine, fusion\ntrap, alternative R&B\ntrap, alternative R&B, Chinese hip hop\ntrap, alternative R&B, ambient\ntrap, alternative R&B, ambient pop\ntrap, alternative R&B, atmospheric pop\ntrap, alternative R&B, cinematic\ntrap, alternative R&B, cloud rap\ntrap, alternative R&B, dream pop\ntrap, alternative R&B, electronic\ntrap, alternative R&B, emotional hip-hop\ntrap, alternative R&B, experimental hip-hop\ntrap, alternative R&B, indie rock\ntrap, alternative R&B, lo-fi hip-hop\ntrap, alternative R&B, psychedelic\ntrap, alternative R&B, vaporwave\ntrap, alternative hip-hop\ntrap, alternative hip-hop, dramatic pop-rock\ntrap, alternative pop\ntrap, alternative rock\ntrap, alternative rock, cinematic\ntrap, alternative rock, hyperpop\ntrap, ambient\ntrap, ambient R&B\ntrap, ambient R&B, cinematic\ntrap, ambient R&B, cloud rap\ntrap, ambient drone\ntrap, ambient electronic, Turkish pop\ntrap, ambient hip-hop\ntrap, ambient hip-hop, East Asian fusion\ntrap, ambient jazz\ntrap, ambient piano\ntrap, ambient pop\ntrap, ambient pop, R&B\ntrap, ambient rap\ntrap, ambient synth\ntrap, ambient, ASMR\ntrap, ambient, African fusion\ntrap, ambient, African hip hop\ntrap, ambient, Afro trap\ntrap, ambient, Afro-fusion\ntrap, ambient, Afro-hip hop\ntrap, ambient, Afro-trap\ntrap, ambient, Afro-urban\ntrap, ambient, Afrobeat\ntrap, ambient, Afrofusion\ntrap, ambient, Albanian hip hop\ntrap, ambient, Arabic\ntrap, ambient, Arabic electronic\ntrap, ambient, Arabic fusion\ntrap, ambient, Arabic hip hop\ntrap, ambient, Arabic melodic rap\ntrap, ambient, Arabic music\ntrap, ambient, Arabic pop\ntrap, ambient, Arabic soul\ntrap, ambient, Asian folk\ntrap, ambient, Asian fusion\ntrap, ambient, Australian\ntrap, ambient, Azerbaijani\ntrap, ambient, Azerbaijani hip hop\ntrap, ambient, Azerbaijani pop\ntrap, ambient, Balkan\ntrap, ambient, Bantu hip hop\ntrap, ambient, Bengali\ntrap, ambient, Bengali hip hop\ntrap, ambient, Brazilian hip hop\ntrap, ambient, Brazilian pop\ntrap, ambient, C-pop\ntrap, ambient, Cantonese hip hop\ntrap, ambient, Cantopop\ntrap, ambient, Central Asian\ntrap, ambient, Chinese\ntrap, ambient, Chinese cinematic\ntrap, ambient, Chinese electronic\ntrap, ambient, Chinese epic\ntrap, ambient, Chinese experimental\ntrap, ambient, Chinese flute\ntrap, ambient, Chinese folk\ntrap, ambient, Chinese fusion\ntrap, ambient, Chinese guzheng\ntrap, ambient, Chinese hip hop\ntrap, ambient, Chinese hip-hop\ntrap, ambient, Chinese indie\ntrap, ambient, Chinese lo-fi\ntrap, ambient, Chinese pop\ntrap, ambient, Chinese rap\ntrap, ambient, Chinese traditional\ntrap, ambient, Chinese zither\ntrap, ambient, Czech hip hop\ntrap, ambient, Czech rap\ntrap, ambient, Dutch hip hop\ntrap, ambient, Dutch hip-hop\ntrap, ambient, Dutch indie\ntrap, ambient, Dutch pop\ntrap, ambient, Dutch rap\ntrap, ambient, East Asian\ntrap, ambient, Eastern\ntrap, ambient, Eastern fusion\ntrap, ambient, Eastern-influenced\ntrap, ambient, Eastern-inspired\ntrap, ambient, Estonian hip-hop\ntrap, ambient, Finnish hip hop\ntrap, ambient, Finnish rap\ntrap, ambient, French hip hop\ntrap, ambient, French pop\ntrap, ambient, French rap\ntrap, ambient, French rap, Swahili rap\ntrap, ambient, French vocal\ntrap, ambient, German hip hop\ntrap, ambient, German hip-hop\ntrap, ambient, German pop\ntrap, ambient, German rap\ntrap, ambient, Greek hip hop\ntrap, ambient, Greek rap\ntrap, ambient, Haitian Creole\ntrap, ambient, Haitian Creole rap\ntrap, ambient, Hausa\ntrap, ambient, Hausa hip hop\ntrap, ambient, Hebrew hip hop\ntrap, ambient, Hebrew rap\ntrap, ambient, Hindi hip hop\ntrap, ambient, Hindi pop\ntrap, ambient, Hindi soul\ntrap, ambient, Hungarian hip hop\ntrap, ambient, Hungarian pop\ntrap, ambient, Hungarian rap\ntrap, ambient, Indian\ntrap, ambient, Indian classical\ntrap, ambient, Indian experimental\ntrap, ambient, Indian fusion\ntrap, ambient, Indian hip hop\ntrap, ambient, Indian pop\ntrap, ambient, Indonesian vocal\ntrap, ambient, Italian\ntrap, ambient, Italian hip hop\ntrap, ambient, Italian pop\ntrap, ambient, Italian rap\ntrap, ambient, Italian vocal\ntrap, ambient, J-hope\ntrap, ambient, J-pop\ntrap, ambient, J-rap\ntrap, ambient, Japanese electronic\ntrap, ambient, Japanese hip hop\ntrap, ambient, K-pop\ntrap, ambient, Kazakh hip hop\ntrap, ambient, Kinyarwanda rap\ntrap, ambient, Latin\ntrap, ambient, Latin hip hop\ntrap, ambient, Latin pop\ntrap, ambient, Lithuanian\ntrap, ambient, Malay hip hop\ntrap, ambient, Malayalam hip hop\ntrap, ambient, Mandarin hip hop\ntrap, ambient, Mandarin hip-hop\ntrap, ambient, Mandarin pop\ntrap, ambient, Mandarin rap\ntrap, ambient, Mandopop\ntrap, ambient, Mediterranean\ntrap, ambient, Middle Eastern\ntrap, ambient, Mongolian\ntrap, ambient, Mongolian hip hop\ntrap, ambient, Mongolian pop\ntrap, ambient, Moroccan Arabic\ntrap, ambient, Moroccan hip hop\ntrap, ambient, Moroccan hip-hop\ntrap, ambient, Moroccan pop\ntrap, ambient, Nepali hip hop\ntrap, ambient, Nigerian Pidgin\ntrap, ambient, Nordic\ntrap, ambient, North African\ntrap, ambient, Persian\ntrap, ambient, Persian hip hop\ntrap, ambient, Persian pop\ntrap, ambient, Persian vocal\ntrap, ambient, Polish hip hop\ntrap, ambient, Polish hip-hop\ntrap, ambient, Polish rap\ntrap, ambient, Polish vocal\ntrap, ambient, Portuguese rap\ntrap, ambient, Punjabi\ntrap, ambient, Punjabi hip hop\ntrap, ambient, Punjabi hip-hop\ntrap, ambient, Punjabi pop\ntrap, ambient, Punjabi rap\ntrap, ambient, R&B\ntrap, ambient, Russian\ntrap, ambient, Russian hip hop\ntrap, ambient, Russian pop\ntrap, ambient, Russian rap\ntrap, ambient, Russian vocal\ntrap, ambient, Sinhala hip hop\ntrap, ambient, South Asian\ntrap, ambient, South Asian folk\ntrap, ambient, South Asian fusion\ntrap, ambient, South Indian fusion\ntrap, ambient, Southeast Asian\ntrap, ambient, Southern hip hop\ntrap, ambient, Spanish guitar\ntrap, ambient, Spanish hip hop\ntrap, ambient, Spanish rap\ntrap, ambient, Spanish spoken word\ntrap, ambient, Swedish hip hop\ntrap, ambient, Swedish rap\ntrap, ambient, Swiss hip hop\ntrap, ambient, Tamil\ntrap, ambient, Tamil devotional\ntrap, ambient, Tamil hip hop\ntrap, ambient, Tamil pop\ntrap, ambient, Thai melodic rap\ntrap, ambient, Thai pop\ntrap, ambient, Thai rap\ntrap, ambient, Tibetan hip hop\ntrap, ambient, Turkish\ntrap, ambient, Turkish ethereal\ntrap, ambient, Turkish hip hop\ntrap, ambient, Turkish pop\ntrap, ambient, UK rap\ntrap, ambient, Ukrainian\ntrap, ambient, Ukrainian folk\ntrap, ambient, Urdu hip hop\ntrap, ambient, Vietnamese hip hop\ntrap, ambient, acoustic\ntrap, ambient, afrobeat\ntrap, ambient, afrobeats\ntrap, ambient, alternative R&B\ntrap, ambient, alternative rock\ntrap, ambient, ancient style\ntrap, ambient, anime\ntrap, ambient, auto-tune\ntrap, ambient, autotune\ntrap, ambient, baroque\ntrap, ambient, bilingual\ntrap, ambient, bilingual hip hop\ntrap, ambient, blues\ntrap, ambient, breakcore\ntrap, ambient, chillwave\ntrap, ambient, chiptune\ntrap, ambient, chopped and screwed\ntrap, ambient, choral\ntrap, ambient, cinematic\ntrap, ambient, classical\ntrap, ambient, classical Indian\ntrap, ambient, cloud rap\ntrap, ambient, cyberpunk\ntrap, ambient, dancehall\ntrap, ambient, danish rap\ntrap, ambient, dark electronic\ntrap, ambient, dream pop\ntrap, ambient, dreamy\ntrap, ambient, duduk\ntrap, ambient, electronic\ntrap, ambient, emo-rap\ntrap, ambient, emotional\ntrap, ambient, emotional rap\ntrap, ambient, ethereal\ntrap, ambient, ethnic\ntrap, ambient, experimental\ntrap, ambient, flamenco\ntrap, ambient, folkloric\ntrap, ambient, future bass\ntrap, ambient, future pop\ntrap, ambient, future soul\ntrap, ambient, futuristic\ntrap, ambient, glitch\ntrap, ambient, gospel\ntrap, ambient, grime\ntrap, ambient, guzheng\ntrap, ambient, hip hop\ntrap, ambient, hip-hop\ntrap, ambient, horrorcore\ntrap, ambient, hyperpop\ntrap, ambient, indie\ntrap, ambient, industrial\ntrap, ambient, inspirational\ntrap, ambient, jazz\ntrap, ambient, jazz hip-hop\ntrap, ambient, lo-fi\ntrap, ambient, lo-fi hip hop\ntrap, ambient, melancholic\ntrap, ambient, melodic\ntrap, ambient, melodic rap\ntrap, ambient, melodic trap\ntrap, ambient, multilingual\ntrap, ambient, multilingual hip hop\ntrap, ambient, mystical\ntrap, ambient, neurofunk\ntrap, ambient, ney flute\ntrap, ambient, nightcore\ntrap, ambient, orchestral\ntrap, ambient, oriental\ntrap, ambient, oud\ntrap, ambient, philosophical\ntrap, ambient, phonk\ntrap, ambient, piano\ntrap, ambient, pluggnb\ntrap, ambient, pop\ntrap, ambient, pop-R&B\ntrap, ambient, psychedelic\ntrap, ambient, rap\ntrap, ambient, reggae\ntrap, ambient, ritual\ntrap, ambient, ritualistic\ntrap, ambient, rock\ntrap, ambient, romantic\ntrap, ambient, sad pop\ntrap, ambient, soul\ntrap, ambient, spiritual\ntrap, ambient, spoken word\ntrap, ambient, synth\ntrap, ambient, synthwave\ntrap, ambient, traditional Chinese\ntrap, ambient, traditional East Asian\ntrap, ambient, traditional Indian\ntrap, ambient, traditional South Asian\ntrap, ambient, traditional fusion\ntrap, ambient, vaporwave\ntrap, ambient, vocal\ntrap, ambient, vocal choir\ntrap, ambient, vocal harmony\ntrap, ambient, vocal house\ntrap, ambient, vocal processing\ntrap, ambient, vocal soul\ntrap, ambient, vocaloid\ntrap, ambient, world\ntrap, ambient, world fusion\ntrap, ambient, world music\ntrap, ancient style\ntrap, ancient style, Middle Eastern\ntrap, ancient style, Turkish\ntrap, ancient style, cinematic\ntrap, ancient style, cinematic hip-hop\ntrap, ancient style, electronic\ntrap, ancient style, ethereal\ntrap, ancient style, fusion\ntrap, ancient style, hip-hop\ntrap, anime\ntrap, anime battle rap\ntrap, anime epic\ntrap, anime hip hop\ntrap, anime pop\ntrap, anime rap\ntrap, anime rap, cinematic hip hop\ntrap, anime, Chinese hip hop\ntrap, anime, French rap\ntrap, anime, German hip hop\ntrap, anime, Hindi hip hop\ntrap, anime, J-pop\ntrap, anime, Japanese-inspired\ntrap, anime, Mandarin hip hop\ntrap, anime, Portuguese rap\ntrap, anime, Russian rap\ntrap, anime, Spanish-style\ntrap, anime, aggressive\ntrap, anime, battle rap\ntrap, anime, bilingual\ntrap, anime, chiptune\ntrap, anime, cinematic\ntrap, anime, cypher\ntrap, anime, dark\ntrap, anime, dark electronic\ntrap, anime, dramatic\ntrap, anime, drill\ntrap, anime, electronic\ntrap, anime, gamer\ntrap, anime, hip hop\ntrap, anime, lo-fi\ntrap, anime, lo-fi hip hop\ntrap, anime, melancholic\ntrap, anime, metalcore\ntrap, anime, nerdcore\ntrap, anime, ninja\ntrap, anime, orchestral\ntrap, anime, rap battle\ntrap, anime, sensual\ntrap, anime, video game\ntrap, anime-core\ntrap, anime-trap\ntrap, animecore, pluggnb\ntrap, anthemic, Mandarin hip hop\ntrap, anthemic, chiptune\ntrap, anthemic, electronic\ntrap, anthemic, regional pride\ntrap, arabesque\ntrap, arabesque rap, ney\ntrap, arabesque, Turkish\ntrap, arabesque, Turkish pop\ntrap, arabesque, ambient\ntrap, arabesque, cinematic\ntrap, arabesque, lo-fi\ntrap, arabesque, melancholic\ntrap, arabic hip hop\ntrap, arabic hip hop, atmospheric\ntrap, arabic hip hop, dutch rap\ntrap, arabic hip hop, lo-fi\ntrap, arabic hip hop, synthwave\ntrap, arabic pop\ntrap, arabic pop, ambient\ntrap, arabic rap, synthwave\ntrap, arabic, lo-fi\ntrap, art pop\ntrap, art pop, experimental\ntrap, art pop, world music\ntrap, atmospheric\ntrap, atmospheric R&B\ntrap, atmospheric R&B, Arabic hip-hop\ntrap, atmospheric R&B, Turkish pop\ntrap, atmospheric R&B, hip-hop\ntrap, atmospheric electronic\ntrap, atmospheric electronic, hip-hop\ntrap, atmospheric hip hop\ntrap, atmospheric hip-hop\ntrap, atmospheric pop\ntrap, atmospheric pop, C-pop\ntrap, atmospheric pop, Moroccan hip-hop\ntrap, atmospheric rock\ntrap, atmospheric rock, conscious hip-hop\ntrap, atmospheric synth-pop\ntrap, atmospheric, Arabic\ntrap, atmospheric, Arabic hip hop\ntrap, atmospheric, Arabic hip-hop\ntrap, atmospheric, Arabic melodic\ntrap, atmospheric, Arabic melodic rap\ntrap, atmospheric, Arabic rap\ntrap, atmospheric, C-pop\ntrap, atmospheric, Cantonese hip hop\ntrap, atmospheric, Caribbean\ntrap, atmospheric, Chinese\ntrap, atmospheric, Chinese emo\ntrap, atmospheric, Chinese hip hop\ntrap, atmospheric, Chinese hip-hop\ntrap, atmospheric, Chinese pop\ntrap, atmospheric, Chinese rap\ntrap, atmospheric, Dutch hip hop\ntrap, atmospheric, East Asian\ntrap, atmospheric, Eastern-influenced\ntrap, atmospheric, Finnish hip hop\ntrap, atmospheric, French hip hop\ntrap, atmospheric, French hip-hop\ntrap, atmospheric, French pop\ntrap, atmospheric, French rap\ntrap, atmospheric, French vocal\ntrap, atmospheric, German hip-hop\ntrap, atmospheric, Greek\ntrap, atmospheric, Greek vocal\ntrap, atmospheric, Haitian Creole rap\ntrap, atmospheric, Hebrew hip hop\ntrap, atmospheric, Hindi hip hop\ntrap, atmospheric, Hungarian\ntrap, atmospheric, Italian hip hop\ntrap, atmospheric, Italian pop\ntrap, atmospheric, Italian rap\ntrap, atmospheric, Jamaican Patois\ntrap, atmospheric, Japanese hip hop\ntrap, atmospheric, K-pop\ntrap, atmospheric, Khmer hip hop\ntrap, atmospheric, Korean hip hop\ntrap, atmospheric, Malay hip hop\ntrap, atmospheric, Mandarin\ntrap, atmospheric, Mandarin hip hop\ntrap, atmospheric, Mandarin rap\ntrap, atmospheric, Middle Eastern\ntrap, atmospheric, Mongolian hip hop\ntrap, atmospheric, Moroccan Arabic\ntrap, atmospheric, Moroccan hip hop\ntrap, atmospheric, Nepali\ntrap, atmospheric, Nepali hip hop\ntrap, atmospheric, Nigerian Pidgin\ntrap, atmospheric, Nigerian hip hop\ntrap, atmospheric, North African\ntrap, atmospheric, Persian\ntrap, atmospheric, Persian hip hop\ntrap, atmospheric, Persian pop\ntrap, atmospheric, Polish\ntrap, atmospheric, Polish hip hop\ntrap, atmospheric, Polish rap\ntrap, atmospheric, R&B\ntrap, atmospheric, Russian\ntrap, atmospheric, Russian hip hop\ntrap, atmospheric, Russian pop\ntrap, atmospheric, Russian rap\ntrap, atmospheric, Russian spoken word\ntrap, atmospheric, Sinhala hip hop\ntrap, atmospheric, Tatar hip hop\ntrap, atmospheric, Thai hip hop\ntrap, atmospheric, Turkish\ntrap, atmospheric, Turkish hip hop\ntrap, atmospheric, Turkish pop\ntrap, atmospheric, Turkish vocal\ntrap, atmospheric, Ukrainian rap\ntrap, atmospheric, Uzbek hip hop\ntrap, atmospheric, auto-tune\ntrap, atmospheric, autumnal\ntrap, atmospheric, bilingual\ntrap, atmospheric, bilingual rap\ntrap, atmospheric, chopped and screwed\ntrap, atmospheric, cinematic\ntrap, atmospheric, classical\ntrap, atmospheric, cyberpunk\ntrap, atmospheric, dark\ntrap, atmospheric, dark hip hop\ntrap, atmospheric, dreamy\ntrap, atmospheric, electronic\ntrap, atmospheric, emo\ntrap, atmospheric, emotional\ntrap, atmospheric, ethereal\ntrap, atmospheric, ethnic\ntrap, atmospheric, hyperpop\ntrap, atmospheric, introspective\ntrap, atmospheric, lo-fi\ntrap, atmospheric, melancholic\ntrap, atmospheric, melodic\ntrap, atmospheric, melodic rap\ntrap, atmospheric, melodic trap\ntrap, atmospheric, moody\ntrap, atmospheric, mystic\ntrap, atmospheric, psychedelic\ntrap, atmospheric, romantic\ntrap, atmospheric, social commentary\ntrap, atmospheric, soulful\ntrap, atmospheric, vaporwave\ntrap, atmospheric, world music\ntrap, auto-tune rap\ntrap, auto-tune, French hip hop\ntrap, auto-tune, ambient\ntrap, auto-tune, cinematic\ntrap, auto-tune, electronic\ntrap, auto-tune, ethereal\ntrap, auto-tune, melancholic\ntrap, auto-tune, psychedelic\ntrap, autotune rap\ntrap, baile funk\ntrap, baile funk, bilingual club\ntrap, baile funk, chiptune\ntrap, baile funk, club\ntrap, baile funk, electronic\ntrap, baile funk, hip-hop\ntrap, balkan brass, electronic\ntrap, ballad\ntrap, ballad, Khmer pop\ntrap, ballad, bilingual\ntrap, bansuri, Punjabi\ntrap, bansuri, cinematic\ntrap, bansuri, emotional\ntrap, barbershop\ntrap, barbershop, lo-fi\ntrap, baroque\ntrap, baroque hip hop\ntrap, baroque pop\ntrap, baroque pop, synth\ntrap, baroque synth\ntrap, baroque synth, cinematic\ntrap, baroque trap\ntrap, baroque, Arabic\ntrap, baroque, C-pop\ntrap, baroque, Chinese hip hop\ntrap, baroque, Chinese hip-hop\ntrap, baroque, Czech hip hop\ntrap, baroque, French hip hop\ntrap, baroque, French rap\ntrap, baroque, German rap\ntrap, baroque, Latin hip hop\ntrap, baroque, Latin trap\ntrap, baroque, Mandarin hip hop\ntrap, baroque, Mandarin rap\ntrap, baroque, Middle Eastern fusion\ntrap, baroque, Polish hip hop\ntrap, baroque, R&B\ntrap, baroque, Russian rap\ntrap, baroque, Southern hip hop\ntrap, baroque, Spanish hip hop\ntrap, baroque, Sundanese hip-hop\ntrap, baroque, ambient\ntrap, baroque, chiptune\ntrap, baroque, cinematic\ntrap, baroque, danish hip hop\ntrap, baroque, dark pop\ntrap, baroque, electronic\ntrap, baroque, gangsta rap\ntrap, baroque, gangster rap\ntrap, baroque, hip hop\ntrap, baroque, hip-hop\ntrap, baroque, hyperpop\ntrap, baroque, lo-fi\ntrap, baroque, lo-fi hip hop\ntrap, baroque, melodic rap\ntrap, baroque, synth\ntrap, baroque-trap\ntrap, bass\ntrap, bass house\ntrap, bass house, EDM\ntrap, bass house, cinematic\ntrap, bass, UK drill\ntrap, bass, electronic\ntrap, battle rap\ntrap, battle rap, chiptune\ntrap, bengali rap, hardstyle\ntrap, bhajan\ntrap, bhajan, ambient\ntrap, bhajan, electronic\ntrap, bhangra\ntrap, bhangra, Indian folk\ntrap, bhangra, Punjabi hip hop\ntrap, big band\ntrap, big band jazz, experimental\ntrap, big band swing\ntrap, big band, cinematic\ntrap, big band, hip hop\ntrap, big room house\ntrap, big room, hip-hop\ntrap, bilingual\ntrap, bilingual hip hop\ntrap, bilingual hip hop, dreamy soul\ntrap, bilingual hip-hop\ntrap, bilingual pop\ntrap, bilingual rap\ntrap, bilingual rap, dreamy\ntrap, bilingual rap, lo-fi\ntrap, bilingual, Arabic hip hop\ntrap, bilingual, Asian fusion\ntrap, bilingual, Caribbean\ntrap, bilingual, Chinese hip hop\ntrap, bilingual, East Asian\ntrap, bilingual, East Asian fusion\ntrap, bilingual, Eastern European\ntrap, bilingual, Eastern flavor\ntrap, bilingual, Eastern melodic\ntrap, bilingual, Eastern tonality\ntrap, bilingual, Eastern-influenced\ntrap, bilingual, Greek rap\ntrap, bilingual, Haitian Creole\ntrap, bilingual, Italian hip hop\ntrap, bilingual, Jamaican Patois\ntrap, bilingual, Latin\ntrap, bilingual, Malay hip hop\ntrap, bilingual, Malay-English\ntrap, bilingual, Malayalam\ntrap, bilingual, Middle Eastern\ntrap, bilingual, Middle Eastern fusion\ntrap, bilingual, Middle Eastern influence\ntrap, bilingual, Middle Eastern trap\ntrap, bilingual, Mongolian hip hop\ntrap, bilingual, Moroccan Arabic\ntrap, bilingual, Nigerian\ntrap, bilingual, Nigerian Pidgin\ntrap, bilingual, North African\ntrap, bilingual, Punjabi hip hop\ntrap, bilingual, R&B\ntrap, bilingual, Romanian hip hop\ntrap, bilingual, Russian rap\ntrap, bilingual, Slavic hip hop\ntrap, bilingual, Soviet era\ntrap, bilingual, Swahili hip hop\ntrap, bilingual, Ukrainian\ntrap, bilingual, Ukrainian hip hop\ntrap, bilingual, afrobeats\ntrap, bilingual, aggressive\ntrap, bilingual, agressive\ntrap, bilingual, ambient\ntrap, bilingual, anime\ntrap, bilingual, anime trap\ntrap, bilingual, atmospheric\ntrap, bilingual, auto-tune\ntrap, bilingual, bluegrass trap\ntrap, bilingual, chill\ntrap, bilingual, chiptune\ntrap, bilingual, chopped and screwed\ntrap, bilingual, cinematic\ntrap, bilingual, cloud rap\ntrap, bilingual, dark\ntrap, bilingual, dreamy\ntrap, bilingual, drill\ntrap, bilingual, electronic\ntrap, bilingual, emo-rap\ntrap, bilingual, epic\ntrap, bilingual, ethereal\ntrap, bilingual, female rap\ntrap, bilingual, female vocal\ntrap, bilingual, folk-infused\ntrap, bilingual, futuristic\ntrap, bilingual, gangsta rap\ntrap, bilingual, gangster\ntrap, bilingual, gangster rap\ntrap, bilingual, glitch\ntrap, bilingual, global hip hop\ntrap, bilingual, hard-hitting\ntrap, bilingual, hardstyle\ntrap, bilingual, hip hop\ntrap, bilingual, hip-hop\ntrap, bilingual, hypnotic\ntrap, bilingual, industrial\ntrap, bilingual, koto-inspired\ntrap, bilingual, latin trap\ntrap, bilingual, lo-fi\ntrap, bilingual, melancholic\ntrap, bilingual, melodic\ntrap, bilingual, melodic rap\ntrap, bilingual, melodic trap\ntrap, bilingual, modern\ntrap, bilingual, moody\ntrap, bilingual, neurofunk\ntrap, bilingual, orchestral\ntrap, bilingual, orchestral trap\ntrap, bilingual, oriental flavor\ntrap, bilingual, psychedelic\ntrap, bilingual, retro\ntrap, bilingual, retro synth\ntrap, bilingual, retro trap\ntrap, bilingual, soul-infused\ntrap, bilingual, street\ntrap, bilingual, synthwave\ntrap, bilingual, tropical\ntrap, bilingual, underground\ntrap, bilingual, urban\ntrap, bilingual, video game\ntrap, bilingual, violin\ntrap, bilingual, world fusion\ntrap, bluegrass trap\ntrap, blues, Chinese hip hop\ntrap, blues, French rap\ntrap, blues, Mandarin hip hop\ntrap, blues, Middle Eastern\ntrap, blues, Romanian hip hop\ntrap, blues, afrobeats\ntrap, blues, atmospheric\ntrap, blues, bilingual hip hop\ntrap, blues, cinematic\ntrap, blues, hip hop\ntrap, blues-rock\ntrap, blues-rock, cinematic\ntrap, blues-rock, electronic\ntrap, blues-rock, melodic hip hop\ntrap, bluesy, atmospheric\ntrap, bolero\ntrap, bolero, ambient\ntrap, bolero, hip-hop\ntrap, boom-bap\ntrap, boom-bap hip-hop\ntrap, boom-bap, C-pop\ntrap, boom-bap, Chinese fusion\ntrap, boom-bap, Chinese hip hop\ntrap, boom-bap, Chinese hip-hop\ntrap, boom-bap, French hip hop\ntrap, boom-bap, German rap\ntrap, boom-bap, Russian hip-hop\ntrap, boom-bap, ambient\ntrap, boom-bap, ambient hip-hop\ntrap, boom-bap, chiptune\ntrap, boom-bap, cinematic\ntrap, boom-bap, cinematic hip hop\ntrap, boom-bap, hip hop\ntrap, boom-bap, hip-hop\ntrap, boom-bap, jazz hip hop\ntrap, boom-bap, lo-fi\ntrap, boom-bap, lo-fi hip hop\ntrap, boom-bap, melodic rap\ntrap, boom-bap, melodic trap\ntrap, boom-bap, rap cypher\ntrap, boom-bap, soulful\ntrap, boom-bap, soulful hip-hop\ntrap, boom-bap, traditional hip-hop\ntrap, boom-bap, vaporwave\ntrap, bossa nova\ntrap, bossa nova, R&B\ntrap, bossa nova, Thai hip hop\ntrap, bounce\ntrap, bounce, twerk\ntrap, brass band, hip-hop\ntrap, brass, Balkan\ntrap, brass, hip hop\ntrap, brass, lo-fi\ntrap, brassy synth, Middle Eastern\ntrap, breakbeat\ntrap, breakbeat, chiptune\ntrap, breakbeat, cinematic\ntrap, breakbeat, electronic\ntrap, breakbeat, world fusion\ntrap, breakcore\ntrap, breakcore, cinematic\ntrap, breakcore, electronic\ntrap, breakcore, glitch-hop\ntrap, brostep\ntrap, brostep, dubstep\ntrap, cantonese hip hop\ntrap, cantopop\ntrap, cantopop, ambient\ntrap, cantopop, cinematic\ntrap, cantopop, electronic\ntrap, cantopop, experimental\ntrap, cantopop, lo-fi\ntrap, cartoon\ntrap, cello, Middle Eastern\ntrap, cello, emotional hip-hop\ntrap, celtic folk\ntrap, ceremonial hip-hop\ntrap, ceremonial, fusion\ntrap, chalga\ntrap, chanson\ntrap, chanson, Punjabi hip hop\ntrap, chanson, cinematic hip-hop\ntrap, chanson, electronic\ntrap, child vocals, modern\ntrap, children's music\ntrap, children's protest\ntrap, chill trap, future bass\ntrap, chillwave\ntrap, chillwave, C-pop\ntrap, chillwave, Filipino hip-hop\ntrap, chillwave, Middle Eastern\ntrap, chillwave, cloud rap\ntrap, chillwave, future bass\ntrap, chillwave, synthwave\ntrap, chillwave, vaporwave\ntrap, chipbeat, hyperpop\ntrap, chiptune\ntrap, chiptune hip hop\ntrap, chiptune, 8-bit\ntrap, chiptune, Afro trap\ntrap, chiptune, Afro-hip hop\ntrap, chiptune, Afro-urban\ntrap, chiptune, Afrobeat\ntrap, chiptune, Afrobeats\ntrap, chiptune, Albanian rap\ntrap, chiptune, Arabic hip hop\ntrap, chiptune, Arabic melodic rap\ntrap, chiptune, Arabic pop\ntrap, chiptune, Arabic rap\ntrap, chiptune, Azerbaijani hip hop\ntrap, chiptune, Bengali hip hop\ntrap, chiptune, Bollywood\ntrap, chiptune, Brazilian\ntrap, chiptune, Brazilian funk\ntrap, chiptune, Brazilian hip hop\ntrap, chiptune, Brazilian hip-hop\ntrap, chiptune, C-pop\ntrap, chiptune, Cantonese hip hop\ntrap, chiptune, Cantopop\ntrap, chiptune, Caribbean hip hop\ntrap, chiptune, Chinese hip hop\ntrap, chiptune, Chinese opera\ntrap, chiptune, Chinese punk\ntrap, chiptune, Chinese rap\ntrap, chiptune, Czech rap\ntrap, chiptune, Dutch hip hop\ntrap, chiptune, Dutch hip-hop\ntrap, chiptune, Eastern European\ntrap, chiptune, Eastern scale\ntrap, chiptune, Eastern tonality\ntrap, chiptune, Eastern-inflected\ntrap, chiptune, Eastern-influenced\ntrap, chiptune, European rap\ntrap, chiptune, Filipino hip hop\ntrap, chiptune, Finnish rap\ntrap, chiptune, French Creole rap\ntrap, chiptune, French hip hop\ntrap, chiptune, French pop\ntrap, chiptune, French rap\ntrap, chiptune, G-funk\ntrap, chiptune, German gangsta rap\ntrap, chiptune, German hip hop\ntrap, chiptune, German hip-hop\ntrap, chiptune, German rap\ntrap, chiptune, Greek hip hop\ntrap, chiptune, Greek rap\ntrap, chiptune, Gujarati hip hop\ntrap, chiptune, Haitian Creole rap\ntrap, chiptune, Hebrew hip hop\ntrap, chiptune, Hindi hip hop\ntrap, chiptune, Hungarian hip hop\ntrap, chiptune, Indian hip hop\ntrap, chiptune, Indian pop\ntrap, chiptune, Italian hip hop\ntrap, chiptune, Italian rap\ntrap, chiptune, Italian spoken word\ntrap, chiptune, J-hope\ntrap, chiptune, J-hype\ntrap, chiptune, J-pop\ntrap, chiptune, J-rap\ntrap, chiptune, Japanese hip hop\ntrap, chiptune, Japanese rap\ntrap, chiptune, K-hip hop\ntrap, chiptune, K-hip-hop\ntrap, chiptune, K-pop\ntrap, chiptune, Khmer hip hop\ntrap, chiptune, Korean hip hop\ntrap, chiptune, Latin\ntrap, chiptune, Latin hip hop\ntrap, chiptune, Latin pop\ntrap, chiptune, Latin trap\ntrap, chiptune, Latvian hip hop\ntrap, chiptune, Malay hip hop\ntrap, chiptune, Malay rap\ntrap, chiptune, Mandarin hip hop\ntrap, chiptune, Mandarin hip-hop\ntrap, chiptune, Mandarin pop\ntrap, chiptune, Mandarin rap\ntrap, chiptune, Mandopop\ntrap, chiptune, Middle Eastern\ntrap, chiptune, Middle Eastern electronic\ntrap, chiptune, Middle Eastern fusion\ntrap, chiptune, Mongolian hip hop\ntrap, chiptune, Moroccan hip hop\ntrap, chiptune, North African rap\ntrap, chiptune, Norwegian hip hop\ntrap, chiptune, Persian hip hop\ntrap, chiptune, Persian rap\ntrap, chiptune, Polish hip hop\ntrap, chiptune, Polish rap\ntrap, chiptune, Punjabi\ntrap, chiptune, Punjabi hip hop\ntrap, chiptune, Punjabi hip-hop\ntrap, chiptune, Punjabi pop\ntrap, chiptune, R&B\ntrap, chiptune, Romanian hip hop\ntrap, chiptune, Romanian rap\ntrap, chiptune, Russian\ntrap, chiptune, Russian hip hop\ntrap, chiptune, Russian hip-hop\ntrap, chiptune, Russian rap\ntrap, chiptune, Russian spoken word\ntrap, chiptune, Sinhala hip hop\ntrap, chiptune, Slovak hip hop\ntrap, chiptune, Slovak rap\ntrap, chiptune, South Asian\ntrap, chiptune, Southern hip hop\ntrap, chiptune, Southern hip-hop\ntrap, chiptune, Spanish hip hop\ntrap, chiptune, Spanish rap\ntrap, chiptune, Taiwanese hip hop\ntrap, chiptune, Thai hip hop\ntrap, chiptune, Thai hip-hop\ntrap, chiptune, Turkish hip hop\ntrap, chiptune, Turkish hip-hop\ntrap, chiptune, Turkish pop\ntrap, chiptune, V-pop\ntrap, chiptune, West Coast hip hop\ntrap, chiptune, afro-trap\ntrap, chiptune, aggressive\ntrap, chiptune, ambient\ntrap, chiptune, anime\ntrap, chiptune, atmospheric\ntrap, chiptune, autotune rap\ntrap, chiptune, baroque\ntrap, chiptune, battle rap\ntrap, chiptune, bilingual\ntrap, chiptune, bilingual hip hop\ntrap, chiptune, bilingual hip-hop\ntrap, chiptune, bilingual rap\ntrap, chiptune, blues-rock\ntrap, chiptune, boom-bap\ntrap, chiptune, chopped and screwed\ntrap, chiptune, cinematic\ntrap, chiptune, cinematic hip-hop\ntrap, chiptune, cinematic rap\ntrap, chiptune, cloud rap\ntrap, chiptune, comedic\ntrap, chiptune, comedy rap\ntrap, chiptune, country rap\ntrap, chiptune, creole hip hop\ntrap, chiptune, crunk\ntrap, chiptune, cyberpunk\ntrap, chiptune, dancehall\ntrap, chiptune, dark\ntrap, chiptune, dark ambient\ntrap, chiptune, dark electronic\ntrap, chiptune, dark hip hop\ntrap, chiptune, devotional\ntrap, chiptune, digital hardcore\ntrap, chiptune, dystopian\ntrap, chiptune, dystopian electronic\ntrap, chiptune, electro-pop\ntrap, chiptune, electronic\ntrap, chiptune, electronic hip-hop\ntrap, chiptune, electronic pop\ntrap, chiptune, emo rap\ntrap, chiptune, emo-rap\ntrap, chiptune, emotional\ntrap, chiptune, emotional rap\ntrap, chiptune, ethereal\ntrap, chiptune, ethnic\ntrap, chiptune, experimental\ntrap, chiptune, funk ostentação\ntrap, chiptune, future R&B\ntrap, chiptune, future bass\ntrap, chiptune, future rap\ntrap, chiptune, futuristic\ntrap, chiptune, gangsta rap\ntrap, chiptune, gangster rap\ntrap, chiptune, glitch\ntrap, chiptune, gospel\ntrap, chiptune, hardcore\ntrap, chiptune, hardcore hip-hop\ntrap, chiptune, hardcore techno\ntrap, chiptune, hardstyle\ntrap, chiptune, heroic\ntrap, chiptune, hip hop\ntrap, chiptune, hip-hop\ntrap, chiptune, holiday hip hop\ntrap, chiptune, horror game\ntrap, chiptune, horrorcore\ntrap, chiptune, hype\ntrap, chiptune, hyperpop\ntrap, chiptune, industrial\ntrap, chiptune, industrial hip hop\ntrap, chiptune, instrumental hip-hop\ntrap, chiptune, jazz hip hop\ntrap, chiptune, k-pop\ntrap, chiptune, kawaii\ntrap, chiptune, lo-fi\ntrap, chiptune, lo-fi hip hop\ntrap, chiptune, lo-fi hip-hop\ntrap, chiptune, mariachi\ntrap, chiptune, melodic hip hop\ntrap, chiptune, melodic rap\ntrap, chiptune, melodic trap\ntrap, chiptune, meme rap\ntrap, chiptune, metalcore\ntrap, chiptune, minimalist\ntrap, chiptune, multi-lingual\ntrap, chiptune, multilingual\ntrap, chiptune, multilingual hip-hop\ntrap, chiptune, mumble rap\ntrap, chiptune, nerdcore\ntrap, chiptune, nihilistic\ntrap, chiptune, orchestral\ntrap, chiptune, party\ntrap, chiptune, phonk\ntrap, chiptune, pluggnb\ntrap, chiptune, political hip hop\ntrap, chiptune, pop\ntrap, chiptune, pop rap\ntrap, chiptune, pop-R&B\ntrap, chiptune, pop-rap\ntrap, chiptune, psychedelic\ntrap, chiptune, psychedelic hip hop\ntrap, chiptune, punk\ntrap, chiptune, rage\ntrap, chiptune, rage rap\ntrap, chiptune, rap\ntrap, chiptune, rap battle\ntrap, chiptune, rap cypher\ntrap, chiptune, regional Mexican\ntrap, chiptune, retro-futuristic\ntrap, chiptune, rock\ntrap, chiptune, satirical\ntrap, chiptune, slowed + reverb\ntrap, chiptune, soul\ntrap, chiptune, southern hip-hop\ntrap, chiptune, spiritual hip hop\ntrap, chiptune, stoner rap\ntrap, chiptune, synth-pop\ntrap, chiptune, synthwave\ntrap, chiptune, theatrical hip-hop\ntrap, chiptune, underground\ntrap, chiptune, underground hip hop\ntrap, chiptune, underground hip-hop\ntrap, chiptune, urban\ntrap, chiptune, vaporwave\ntrap, chiptune, video game\ntrap, chiptune, video game music\ntrap, choir, electronic\ntrap, chopped and screwed\ntrap, chopped and screwed, emotional rap\ntrap, chopped and screwed, lo-fi hip hop\ntrap, chopper rap\ntrap, choral\ntrap, choral hip-hop\ntrap, choral synth\ntrap, choral synth, Afro trap\ntrap, choral synth, Chinese hip hop\ntrap, choral synth, Russian rap\ntrap, choral, Afrobeat\ntrap, choral, Arabic hip hop\ntrap, choral, Chinese hip hop\ntrap, choral, Eastern European\ntrap, choral, French rap\ntrap, choral, German hip hop\ntrap, choral, Greek\ntrap, choral, Greek hip hop\ntrap, choral, Hungarian hip hop\ntrap, choral, Mandarin rap\ntrap, choral, Russian hip hop\ntrap, choral, Russian rap\ntrap, choral, Turkish\ntrap, choral, afrobeats\ntrap, choral, ambient\ntrap, choral, ancient style\ntrap, choral, bilingual\ntrap, choral, cinematic\ntrap, choral, conscious hip-hop\ntrap, choral, cross-cultural\ntrap, choral, dark pop\ntrap, choral, electronic\ntrap, choral, hip hop\ntrap, choral, hip-hop\ntrap, choral, lo-fi\ntrap, choral, synth soul\ntrap, cinematic\ntrap, cinematic EDM\ntrap, cinematic ambient\ntrap, cinematic electronic\ntrap, cinematic electronic, French rap\ntrap, cinematic hip hop\ntrap, cinematic hip-hop\ntrap, cinematic hip-hop, Middle Eastern fusion\ntrap, cinematic hip-hop, R&B\ntrap, cinematic hip-hop, boom-bap\ntrap, cinematic hip-hop, electro\ntrap, cinematic hip-hop, pop-rock\ntrap, cinematic hip-hop, world music\ntrap, cinematic horror\ntrap, cinematic orchestral\ntrap, cinematic piano\ntrap, cinematic pop\ntrap, cinematic pop, C-pop\ntrap, cinematic pop-rock\ntrap, cinematic rap\ntrap, cinematic rap, video game\ntrap, cinematic synth\ntrap, cinematic synth, German rap\ntrap, cinematic synth, Italian rap\ntrap, cinematic synth, Turkish hip-hop\ntrap, cinematic synth, chiptune\ntrap, cinematic synth, retro game\ntrap, cinematic synth, retro-futuristic\ntrap, cinematic, African fusion\ntrap, cinematic, African hip hop\ntrap, cinematic, Afrikaans hip hop\ntrap, cinematic, Afro trap\ntrap, cinematic, Afro-French\ntrap, cinematic, Afro-Trap\ntrap, cinematic, Afro-hip hop\ntrap, cinematic, Afro-pop\ntrap, cinematic, Afro-trap\ntrap, cinematic, Afro-urban\ntrap, cinematic, Afrobeat\ntrap, cinematic, Afrofusion\ntrap, cinematic, Albanian hip hop\ntrap, cinematic, Albanian pop\ntrap, cinematic, Albanian rap\ntrap, cinematic, Anatolian\ntrap, cinematic, Arabic\ntrap, cinematic, Arabic drill\ntrap, cinematic, Arabic fusion\ntrap, cinematic, Arabic hip hop\ntrap, cinematic, Arabic hip-hop\ntrap, cinematic, Arabic pop\ntrap, cinematic, Arabic rap\ntrap, cinematic, Armenian hip hop\ntrap, cinematic, Asian fusion\ntrap, cinematic, Asian hip hop\ntrap, cinematic, Asian pop\ntrap, cinematic, Asian-inspired\ntrap, cinematic, Australian hip hop\ntrap, cinematic, Azerbaijani\ntrap, cinematic, Azerbaijani hip hop\ntrap, cinematic, Azerbaijani hip-hop\ntrap, cinematic, Azerbaijani rap\ntrap, cinematic, Balkan\ntrap, cinematic, Balkan folk\ntrap, cinematic, Balkan fusion\ntrap, cinematic, Balkan hip hop\ntrap, cinematic, Balkan pop\ntrap, cinematic, Bantu hip hop\ntrap, cinematic, Bengali hip hop\ntrap, cinematic, Bollywood\ntrap, cinematic, Brazilian\ntrap, cinematic, Brazilian hip hop\ntrap, cinematic, British hip hop\ntrap, cinematic, C-pop\ntrap, cinematic, Cantonese hip hop\ntrap, cinematic, Cantonese hip-hop\ntrap, cinematic, Cantonese rap\ntrap, cinematic, Cantopop\ntrap, cinematic, Caribbean\ntrap, cinematic, Carnatic\ntrap, cinematic, Catalan rap\ntrap, cinematic, Central Asian\ntrap, cinematic, Chinese\ntrap, cinematic, Chinese ambient\ntrap, cinematic, Chinese baroque\ntrap, cinematic, Chinese classical\ntrap, cinematic, Chinese electronic\ntrap, cinematic, Chinese flute\ntrap, cinematic, Chinese folk\ntrap, cinematic, Chinese fusion\ntrap, cinematic, Chinese gangster rap\ntrap, cinematic, Chinese hip hop\ntrap, cinematic, Chinese hip-hop\ntrap, cinematic, Chinese martial arts\ntrap, cinematic, Chinese mythology\ntrap, cinematic, Chinese opera\ntrap, cinematic, Chinese pop\ntrap, cinematic, Chinese rap\ntrap, cinematic, Chinese thematic\ntrap, cinematic, Chinese traditional\ntrap, cinematic, Chinese underground\ntrap, cinematic, Czech hip hop\ntrap, cinematic, Czech rap\ntrap, cinematic, Danish hip hop\ntrap, cinematic, Dutch hip hop\ntrap, cinematic, Dutch hip-hop\ntrap, cinematic, Dutch pop\ntrap, cinematic, Dutch rap\ntrap, cinematic, E-Latin\ntrap, cinematic, EDM\ntrap, cinematic, East African\ntrap, cinematic, East Asian\ntrap, cinematic, East Asian fusion\ntrap, cinematic, East Asian hip hop\ntrap, cinematic, Eastern\ntrap, cinematic, Eastern European\ntrap, cinematic, Eastern flavor\ntrap, cinematic, Eastern fusion\ntrap, cinematic, Eastern tonality\ntrap, cinematic, Eastern-influenced\ntrap, cinematic, Eastern-inspired\ntrap, cinematic, European\ntrap, cinematic, Filipino hip hop\ntrap, cinematic, Finnish hip hop\ntrap, cinematic, Finnish rap\ntrap, cinematic, French\ntrap, cinematic, French Creole\ntrap, cinematic, French ballad\ntrap, cinematic, French electronic\ntrap, cinematic, French hip hop\ntrap, cinematic, French hip-hop\ntrap, cinematic, French noir\ntrap, cinematic, French pop\ntrap, cinematic, French rap\ntrap, cinematic, French rap, German rap\ntrap, cinematic, French rap, Portuguese rap\ntrap, cinematic, French spoken word\ntrap, cinematic, G-funk\ntrap, cinematic, Georgian hip hop\ntrap, cinematic, German gamer-rap\ntrap, cinematic, German hip hop\ntrap, cinematic, German hip-hop\ntrap, cinematic, German pop\ntrap, cinematic, German rap\ntrap, cinematic, German rap, Turkish rap\ntrap, cinematic, Greek\ntrap, cinematic, Greek hip hop\ntrap, cinematic, Greek rap\ntrap, cinematic, Gujarati hip hop\ntrap, cinematic, Haitian Creole\ntrap, cinematic, Haitian Creole hip hop\ntrap, cinematic, Haryanvi hip hop\ntrap, cinematic, Hausa hip hop\ntrap, cinematic, Hausa hip-hop\ntrap, cinematic, Hebrew ballad\ntrap, cinematic, Hebrew hip hop\ntrap, cinematic, Hebrew rap\ntrap, cinematic, Hebrew vocal\ntrap, cinematic, Hindi\ntrap, cinematic, Hindi fusion\ntrap, cinematic, Hindi hip hop\ntrap, cinematic, Hindi hip-hop\ntrap, cinematic, Hindi pop\ntrap, cinematic, Hindi rap\ntrap, cinematic, Hindustani\ntrap, cinematic, Hmong hip hop\ntrap, cinematic, Hong Kong hip hop\ntrap, cinematic, Hungarian hip hop\ntrap, cinematic, Hungarian rap\ntrap, cinematic, Icelandic hip hop\ntrap, cinematic, Indian\ntrap, cinematic, Indian classical\ntrap, cinematic, Indian fusion\ntrap, cinematic, Indian gangster film\ntrap, cinematic, Indian hip hop\ntrap, cinematic, Indian hip-hop\ntrap, cinematic, Indian pop\ntrap, cinematic, Indonesian\ntrap, cinematic, Indonesian fusion\ntrap, cinematic, Indonesian hip hop\ntrap, cinematic, Italian\ntrap, cinematic, Italian hip hop\ntrap, cinematic, Italian hip-hop\ntrap, cinematic, Italian pop\ntrap, cinematic, Italian rap\ntrap, cinematic, Italian soul\ntrap, cinematic, Italian spoken word\ntrap, cinematic, J-hiphop\ntrap, cinematic, J-hope\ntrap, cinematic, J-pop\ntrap, cinematic, Jamaican Patois\ntrap, cinematic, Japanese\ntrap, cinematic, Japanese ambient\ntrap, cinematic, Japanese anime\ntrap, cinematic, Japanese hip hop\ntrap, cinematic, Japanese myth\ntrap, cinematic, Japanese rap\ntrap, cinematic, Japanese samurai\ntrap, cinematic, K-pop\ntrap, cinematic, Kazakh hip hop\ntrap, cinematic, Kazakh pop\ntrap, cinematic, Khmer hip hop\ntrap, cinematic, Khmer hip-hop\ntrap, cinematic, Korean hip hop\ntrap, cinematic, Latin\ntrap, cinematic, Latin hip hop\ntrap, cinematic, Latin pop\ntrap, cinematic, Latvian rap\ntrap, cinematic, Lithuanian hip hop\ntrap, cinematic, Malay hip hop\ntrap, cinematic, Malay rap\ntrap, cinematic, Malayalam hip hop\ntrap, cinematic, Malayalam hip-hop\ntrap, cinematic, Malayalam rap\ntrap, cinematic, Mandarin hip hop\ntrap, cinematic, Mandarin hip-hop\ntrap, cinematic, Mandarin pop\ntrap, cinematic, Mandarin rap\ntrap, cinematic, Marathi hip hop\ntrap, cinematic, Memphis rap\ntrap, cinematic, Middle Eastern\ntrap, cinematic, Middle Eastern fusion\ntrap, cinematic, Mongolian\ntrap, cinematic, Mongolian folk\ntrap, cinematic, Mongolian hip hop\ntrap, cinematic, Mongolian rap\ntrap, cinematic, Moroccan Arabic\ntrap, cinematic, Moroccan hip hop\ntrap, cinematic, Neapolitan\ntrap, cinematic, Neapolitan hip hop\ntrap, cinematic, Neapolitan rap\ntrap, cinematic, Nepali hip hop\ntrap, cinematic, Nigerian Pidgin\ntrap, cinematic, Nordic\ntrap, cinematic, Nordic hip hop\ntrap, cinematic, North African\ntrap, cinematic, North African hip hop\ntrap, cinematic, Norwegian hip hop\ntrap, cinematic, Papiamento hip hop\ntrap, cinematic, Persian\ntrap, cinematic, Persian hip hop\ntrap, cinematic, Persian rap\ntrap, cinematic, Polish\ntrap, cinematic, Polish hip hop\ntrap, cinematic, Polish hip-hop\ntrap, cinematic, Polish rap\ntrap, cinematic, Polish vocal\ntrap, cinematic, Portuguese\ntrap, cinematic, Portuguese hip hop\ntrap, cinematic, Portuguese hip-hop\ntrap, cinematic, Portuguese rap\ntrap, cinematic, Punjabi\ntrap, cinematic, Punjabi folk\ntrap, cinematic, Punjabi hip hop\ntrap, cinematic, Punjabi hip-hop\ntrap, cinematic, Punjabi rap\ntrap, cinematic, R&B\ntrap, cinematic, Romanian\ntrap, cinematic, Romanian hip hop\ntrap, cinematic, Romanian hip-hop\ntrap, cinematic, Romanian rap\ntrap, cinematic, Russian\ntrap, cinematic, Russian hip hop\ntrap, cinematic, Russian hip-hop\ntrap, cinematic, Russian pop\ntrap, cinematic, Russian rap\ntrap, cinematic, Russian spoken word\ntrap, cinematic, Russian vocal\ntrap, cinematic, Sinhala\ntrap, cinematic, Sinhala hip hop\ntrap, cinematic, Slovak hip hop\ntrap, cinematic, Slovak pop\ntrap, cinematic, Slovak rap\ntrap, cinematic, South Asian\ntrap, cinematic, South Asian folk\ntrap, cinematic, South Asian fusion\ntrap, cinematic, South Indian fusion\ntrap, cinematic, South Indian hip-hop\ntrap, cinematic, Southern hip hop\ntrap, cinematic, Soviet style\ntrap, cinematic, Spanish\ntrap, cinematic, Spanish guitar\ntrap, cinematic, Spanish hip hop\ntrap, cinematic, Spanish rap\ntrap, cinematic, Spanish spoken word\ntrap, cinematic, Spanish-influenced\ntrap, cinematic, Spanish-style\ntrap, cinematic, Swahili hip hop\ntrap, cinematic, Swahili rap\ntrap, cinematic, Swedish\ntrap, cinematic, Swedish hip hop\ntrap, cinematic, Swedish rap\ntrap, cinematic, Swiss German hip hop\ntrap, cinematic, Swiss hip hop\ntrap, cinematic, Tagalog hip hop\ntrap, cinematic, Tagalog rap\ntrap, cinematic, Tamil\ntrap, cinematic, Tamil electronic\ntrap, cinematic, Tamil hip hop\ntrap, cinematic, Tamil pop\ntrap, cinematic, Telugu hip hop\ntrap, cinematic, Thai hip hop\ntrap, cinematic, Thai pop\ntrap, cinematic, Thai rap\ntrap, cinematic, Turkish\ntrap, cinematic, Turkish battle rap\ntrap, cinematic, Turkish folk\ntrap, cinematic, Turkish fusion\ntrap, cinematic, Turkish hip hop\ntrap, cinematic, Turkish hip-hop\ntrap, cinematic, Turkish pop\ntrap, cinematic, Turkish rap\ntrap, cinematic, UK hip hop\ntrap, cinematic, UK rap\ntrap, cinematic, Ukrainian\ntrap, cinematic, Ukrainian hip hop\ntrap, cinematic, Ukrainian rap\ntrap, cinematic, Urdu hip hop\ntrap, cinematic, Uyghur hip hop\ntrap, cinematic, Vietnamese\ntrap, cinematic, Vietnamese fusion\ntrap, cinematic, Vietnamese hip hop\ntrap, cinematic, Vietnamese pop\ntrap, cinematic, Vietnamese rap\ntrap, cinematic, West African\ntrap, cinematic, afrobeats\ntrap, cinematic, aggressive\ntrap, cinematic, ambient\ntrap, cinematic, ancient style\ntrap, cinematic, anime\ntrap, cinematic, anthemic\ntrap, cinematic, atmospheric\ntrap, cinematic, auto-tune\ntrap, cinematic, baroque\ntrap, cinematic, baroque trap\ntrap, cinematic, battle rap\ntrap, cinematic, bilingual\ntrap, cinematic, bilingual hip hop\ntrap, cinematic, bilingual rap\ntrap, cinematic, boom-bap\ntrap, cinematic, brass\ntrap, cinematic, chiptune\ntrap, cinematic, choir\ntrap, cinematic, chopped and screwed\ntrap, cinematic, choral\ntrap, cinematic, classical\ntrap, cinematic, classical fusion\ntrap, cinematic, classical-inspired\ntrap, cinematic, cloud rap\ntrap, cinematic, comedy rap\ntrap, cinematic, conscious hip-hop\ntrap, cinematic, cross-cultural\ntrap, cinematic, cyberpunk\ntrap, cinematic, dancehall\ntrap, cinematic, dark\ntrap, cinematic, dark ambient\ntrap, cinematic, dark classical\ntrap, cinematic, dark electronic\ntrap, cinematic, dark future\ntrap, cinematic, dark hip hop\ntrap, cinematic, dark hip-hop\ntrap, cinematic, dark pop\ntrap, cinematic, dark rap\ntrap, cinematic, dark synth\ntrap, cinematic, dark video game\ntrap, cinematic, dark wave\ntrap, cinematic, dream pop\ntrap, cinematic, dream-pop\ntrap, cinematic, dreamy\ntrap, cinematic, drill\ntrap, cinematic, dubstep\ntrap, cinematic, duduk\ntrap, cinematic, dystopian\ntrap, cinematic, electronic\ntrap, cinematic, emo\ntrap, cinematic, emo rap\ntrap, cinematic, emo-rap\ntrap, cinematic, emotional\ntrap, cinematic, emotional rap\ntrap, cinematic, epic\ntrap, cinematic, ethereal\ntrap, cinematic, ethnic\ntrap, cinematic, ethnic fusion\ntrap, cinematic, exotic\ntrap, cinematic, experimental\ntrap, cinematic, fantasy\ntrap, cinematic, female rap\ntrap, cinematic, female vocal\ntrap, cinematic, festive\ntrap, cinematic, folk\ntrap, cinematic, folk fusion\ntrap, cinematic, fusion\ntrap, cinematic, future Chinese\ntrap, cinematic, future bass\ntrap, cinematic, future pop\ntrap, cinematic, futuristic\ntrap, cinematic, gaming\ntrap, cinematic, gangsta rap\ntrap, cinematic, gangster rap\ntrap, cinematic, glitch\ntrap, cinematic, glitch-hop\ntrap, cinematic, global hip hop\ntrap, cinematic, global hip-hop\ntrap, cinematic, gospel\ntrap, cinematic, gothic\ntrap, cinematic, gothic horror\ntrap, cinematic, hard-hitting\ntrap, cinematic, hardstyle\ntrap, cinematic, harp\ntrap, cinematic, hip hop\ntrap, cinematic, hip-hop\ntrap, cinematic, horror\ntrap, cinematic, horrorcore\ntrap, cinematic, hybrid\ntrap, cinematic, hype\ntrap, cinematic, hyperpop\ntrap, cinematic, indie\ntrap, cinematic, industrial\ntrap, cinematic, inspirational\ntrap, cinematic, introspective\ntrap, cinematic, jazz\ntrap, cinematic, lo-fi\ntrap, cinematic, lo-fi hip hop\ntrap, cinematic, male rap\ntrap, cinematic, medieval\ntrap, cinematic, melancholic\ntrap, cinematic, melodic\ntrap, cinematic, melodic hip hop\ntrap, cinematic, melodic rap\ntrap, cinematic, metalcore\ntrap, cinematic, microtonal\ntrap, cinematic, militaristic\ntrap, cinematic, modern hip hop\ntrap, cinematic, moody\ntrap, cinematic, motivational\ntrap, cinematic, multi-lingual\ntrap, cinematic, multilingual\ntrap, cinematic, multilingual hip hop\ntrap, cinematic, mumble rap\ntrap, cinematic, mystical\ntrap, cinematic, mythological\ntrap, cinematic, mythological hip-hop\ntrap, cinematic, neo-soul\ntrap, cinematic, noir\ntrap, cinematic, noise rock\ntrap, cinematic, nu-metal\ntrap, cinematic, operatic\ntrap, cinematic, orchestral\ntrap, cinematic, orchestral hip hop\ntrap, cinematic, orchestral hip-hop\ntrap, cinematic, oriental\ntrap, cinematic, oud\ntrap, cinematic, party\ntrap, cinematic, phonk\ntrap, cinematic, piano\ntrap, cinematic, political\ntrap, cinematic, political hip hop\ntrap, cinematic, pop\ntrap, cinematic, pop-punk\ntrap, cinematic, pop-rap\ntrap, cinematic, posse cut\ntrap, cinematic, protest\ntrap, cinematic, psychedelic\ntrap, cinematic, psychedelic pop\ntrap, cinematic, rap battle\ntrap, cinematic, rap cypher\ntrap, cinematic, reggae\ntrap, cinematic, regional Mexican\ntrap, cinematic, retro\ntrap, cinematic, retro game\ntrap, cinematic, retro synth\ntrap, cinematic, retro video game\ntrap, cinematic, retro-futuristic\ntrap, cinematic, rock\ntrap, cinematic, rock-influenced\ntrap, cinematic, sci-fi\ntrap, cinematic, soul\ntrap, cinematic, soulful\ntrap, cinematic, southern hip-hop\ntrap, cinematic, space\ntrap, cinematic, spiritual\ntrap, cinematic, spoken word\ntrap, cinematic, sports anthem\ntrap, cinematic, street\ntrap, cinematic, street hip hop\ntrap, cinematic, synth\ntrap, cinematic, synth brass\ntrap, cinematic, synthwave\ntrap, cinematic, taiko\ntrap, cinematic, techno\ntrap, cinematic, underground\ntrap, cinematic, urban\ntrap, cinematic, vaporwave\ntrap, cinematic, video game\ntrap, cinematic, villainous\ntrap, cinematic, vocal\ntrap, cinematic, vocal harmony\ntrap, cinematic, world fusion\ntrap, cinematic, world music\ntrap, city pop\ntrap, city pop, vaporwave\ntrap, classical\ntrap, classical crossover\ntrap, classical fusion\ntrap, classical fusion, K-pop\ntrap, classical guitar\ntrap, classical hip-hop\ntrap, classical horror\ntrap, classical synth\ntrap, classical trap\ntrap, classical, Albanian hip hop\ntrap, classical, Arabic fusion\ntrap, classical, Balkan\ntrap, classical, Brazilian hip hop\ntrap, classical, C-pop\ntrap, classical, Chinese\ntrap, classical, Chinese hip hop\ntrap, classical, Chinese hip-hop\ntrap, classical, Dutch hip hop\ntrap, classical, French hip hop\ntrap, classical, French hip-hop\ntrap, classical, French rap\ntrap, classical, German hip hop\ntrap, classical, German rap\ntrap, classical, Haitian Creole rap\ntrap, classical, Italian hip hop\ntrap, classical, Italian rap\ntrap, classical, Jamaican Patois\ntrap, classical, Latin\ntrap, classical, Latin hip hop\ntrap, classical, Mandarin hip hop\ntrap, classical, Mandarin rap\ntrap, classical, Middle Eastern\ntrap, classical, Moroccan hip hop\ntrap, classical, Nordic\ntrap, classical, Polish hip hop\ntrap, classical, Portuguese hip hop\ntrap, classical, Russian\ntrap, classical, Russian hip hop\ntrap, classical, Russian hip-hop\ntrap, classical, Swiss German rap\ntrap, classical, Thai hip hop\ntrap, classical, Turkish hip hop\ntrap, classical, aggressive\ntrap, classical, anime\ntrap, classical, baroque\ntrap, classical, bilingual\ntrap, classical, bilingual rap\ntrap, classical, cinematic\ntrap, classical, comedy\ntrap, classical, dancehall\ntrap, classical, danish hip hop\ntrap, classical, dark\ntrap, classical, electronic\ntrap, classical, epic\ntrap, classical, fantasy\ntrap, classical, flamenco\ntrap, classical, gangster rap\ntrap, classical, gothic\ntrap, classical, hip hop\ntrap, classical, hip-hop\ntrap, classical, industrial\ntrap, classical, lo-fi\ntrap, classical, lo-fi hip hop\ntrap, classical, medieval\ntrap, classical, melancholic\ntrap, classical, minimalist\ntrap, classical, phonk\ntrap, classical, rap\ntrap, classical, soul\ntrap, classical, tango\ntrap, classical, urban\ntrap, classical, world music\ntrap, classical-inspired, Mandarin rap\ntrap, cloud rap\ntrap, cloud rap, Arabic hip hop\ntrap, cloud rap, Arabic pop\ntrap, cloud rap, Balkan folk\ntrap, cloud rap, Brazilian\ntrap, cloud rap, Brazilian funk\ntrap, cloud rap, Brazilian trap\ntrap, cloud rap, C-pop\ntrap, cloud rap, Chinese hip hop\ntrap, cloud rap, Danish hip-hop\ntrap, cloud rap, Deutschrap\ntrap, cloud rap, Dutch hip-hop\ntrap, cloud rap, Eastern fusion\ntrap, cloud rap, Eastern tonality\ntrap, cloud rap, French\ntrap, cloud rap, French hip hop\ntrap, cloud rap, French hip-hop\ntrap, cloud rap, French indie\ntrap, cloud rap, French rap\ntrap, cloud rap, French trap\ntrap, cloud rap, German hip hop\ntrap, cloud rap, Greek pop\ntrap, cloud rap, Greek trap\ntrap, cloud rap, Indian hip hop\ntrap, cloud rap, Indonesian hip-hop\ntrap, cloud rap, Italian hip hop\ntrap, cloud rap, Italian pop\ntrap, cloud rap, J-pop\ntrap, cloud rap, J-rap\ntrap, cloud rap, Jersey club\ntrap, cloud rap, K-hip-hop\ntrap, cloud rap, Korean hip-hop\ntrap, cloud rap, Latin hip hop\ntrap, cloud rap, Latin pop\ntrap, cloud rap, Latin trap\ntrap, cloud rap, Mandarin hip hop\ntrap, cloud rap, Mandopop\ntrap, cloud rap, Middle Eastern fusion\ntrap, cloud rap, Mongolian hip hop\ntrap, cloud rap, Mongolian hip-hop\ntrap, cloud rap, North African\ntrap, cloud rap, North African hip-hop\ntrap, cloud rap, North African pop\ntrap, cloud rap, Polish hip-hop\ntrap, cloud rap, Portuguese\ntrap, cloud rap, Punjabi hip hop\ntrap, cloud rap, R&B\ntrap, cloud rap, Russian\ntrap, cloud rap, Russian hip hop\ntrap, cloud rap, Scandinavian trap\ntrap, cloud rap, Spanish fusion\ntrap, cloud rap, Spanish guitar\ntrap, cloud rap, Spanish hip hop\ntrap, cloud rap, Turkish folk\ntrap, cloud rap, Turkish hip hop\ntrap, cloud rap, UK drill\ntrap, cloud rap, UK rap\ntrap, cloud rap, afro trap\ntrap, cloud rap, afro-trap\ntrap, cloud rap, alternative R&B\ntrap, cloud rap, ambient\ntrap, cloud rap, ambient R&B\ntrap, cloud rap, ambient hip-hop\ntrap, cloud rap, ambient pop\ntrap, cloud rap, atmospheric\ntrap, cloud rap, atmospheric R&B\ntrap, cloud rap, atmospheric electronic\ntrap, cloud rap, atmospheric pop\ntrap, cloud rap, bilingual hip-hop\ntrap, cloud rap, boom-bap\ntrap, cloud rap, chillwave\ntrap, cloud rap, chiptune\ntrap, cloud rap, cinematic\ntrap, cloud rap, cinematic ambient\ntrap, cloud rap, cinematic hip hop\ntrap, cloud rap, cinematic synth\ntrap, cloud rap, cyberpunk\ntrap, cloud rap, dark R&B\ntrap, cloud rap, dark ambient\ntrap, cloud rap, dark pop\ntrap, cloud rap, darkwave\ntrap, cloud rap, dream pop\ntrap, cloud rap, drill\ntrap, cloud rap, electronic\ntrap, cloud rap, emo rap\ntrap, cloud rap, emo trap\ntrap, cloud rap, emo-rap\ntrap, cloud rap, emo-trap\ntrap, cloud rap, emotional R&B\ntrap, cloud rap, emotional hip-hop\ntrap, cloud rap, emotional rap\ntrap, cloud rap, experimental\ntrap, cloud rap, experimental electronic\ntrap, cloud rap, experimental hip-hop\ntrap, cloud rap, funk\ntrap, cloud rap, future bass\ntrap, cloud rap, futuristic\ntrap, cloud rap, glitch\ntrap, cloud rap, glitch-hop\ntrap, cloud rap, gospel\ntrap, cloud rap, hip hop\ntrap, cloud rap, hip-hop\ntrap, cloud rap, horrorcore\ntrap, cloud rap, hyperpop\ntrap, cloud rap, industrial hip hop\ntrap, cloud rap, international\ntrap, cloud rap, lo-fi\ntrap, cloud rap, lo-fi hip hop\ntrap, cloud rap, lo-fi hip-hop\ntrap, cloud rap, melodic hip-hop\ntrap, cloud rap, melodic rap\ntrap, cloud rap, melodic trap\ntrap, cloud rap, modern R&B\ntrap, cloud rap, modern hip-hop\ntrap, cloud rap, phonk\ntrap, cloud rap, pluggnb\ntrap, cloud rap, pop\ntrap, cloud rap, pop-R&B\ntrap, cloud rap, pop-rap\ntrap, cloud rap, psychedelic\ntrap, cloud rap, psychedelic trap\ntrap, cloud rap, rage music\ntrap, cloud rap, reggaeton\ntrap, cloud rap, retro synth\ntrap, cloud rap, sci-fi\ntrap, cloud rap, synth-pop\ntrap, cloud rap, synthwave\ntrap, cloud rap, vaporwave\ntrap, cloud rap, video game\ntrap, cloud rap, video game music\ntrap, cloud rap, video game synth\ntrap, cloud rap, witch house\ntrap, cloud rap, world music\ntrap, club\ntrap, club hip-hop\ntrap, club, R&B\ntrap, club, chiptune\ntrap, club, hip-hop\ntrap, club, hyperpop\ntrap, club, multilingual\ntrap, coldwave\ntrap, comedic rap\ntrap, comedic, Chinese hip hop\ntrap, comedic, Christmas\ntrap, comedic, Czech hip hop\ntrap, comedic, Russian hip hop\ntrap, comedic, aggressive\ntrap, comedic, anti-Christmas\ntrap, comedic, electronic\ntrap, comedic, lo-fi\ntrap, comedic, meta\ntrap, comedic, surreal\ntrap, comedy\ntrap, comedy hip hop\ntrap, comedy hip-hop\ntrap, comedy rap\ntrap, comedy rap, theatrical\ntrap, comedy, Christmas\ntrap, conscious hip hop\ntrap, conscious hip-hop\ntrap, conscious hip-hop, Punjabi\ntrap, conscious hip-hop, ambient\ntrap, conscious hip-hop, atmospheric R&B\ntrap, conscious hip-hop, cinematic\ntrap, conscious hip-hop, dark ambient\ntrap, conscious hip-hop, pop\ntrap, conscious rap\ntrap, conscious rap, ambient\ntrap, contemporary R&B\ntrap, corrido tumbado\ntrap, corrido, lo-fi hip hop\ntrap, corridos tumbados\ntrap, corridos, lo-fi\ntrap, country\ntrap, country, bluegrass\ntrap, country, hardstyle\ntrap, country, lo-fi\ntrap, country-folk, hip-hop\ntrap, country-folk, pop\ntrap, country-rap\ntrap, country-rap, chiptune\ntrap, country-trap\ntrap, country-western, C-pop\ntrap, crunk\ntrap, crunk, Memphis rap\ntrap, crunk, Southern hip-hop\ntrap, crunk, chiptune\ntrap, crunk, club\ntrap, crunk, dirty south\ntrap, crunk, gangsta rap\ntrap, crunk, lo-fi hip hop\ntrap, crunk, southern hip-hop\ntrap, crunk, underground hip-hop\ntrap, crypto, hype\ntrap, cumbia\ntrap, cumbia villera\ntrap, cumbia, ambient\ntrap, cumbia, balkan\ntrap, cumbia, electronic\ntrap, cumbia, hip hop\ntrap, cyber, Chinese hip hop\ntrap, cyber-noir\ntrap, cyberpunk\ntrap, cyberpunk hip-hop\ntrap, cyberpunk, C-pop\ntrap, cyberpunk, Chinese hip hop\ntrap, cyberpunk, Hindi pop\ntrap, cyberpunk, Italian hip-hop\ntrap, cyberpunk, J-hiphop\ntrap, cyberpunk, Japanese hip-hop\ntrap, cyberpunk, Latin hip hop\ntrap, cyberpunk, Mandarin hip hop\ntrap, cyberpunk, Mandarin rap\ntrap, cyberpunk, Polish hip hop\ntrap, cyberpunk, R&B\ntrap, cyberpunk, Spanish hip hop\ntrap, cyberpunk, ambient\ntrap, cyberpunk, atmospheric\ntrap, cyberpunk, chiptune\ntrap, cyberpunk, conscious hip-hop\ntrap, cyberpunk, dark\ntrap, cyberpunk, electronic\ntrap, cyberpunk, ethereal\ntrap, cyberpunk, experimental electronic\ntrap, cyberpunk, future bass\ntrap, cyberpunk, future hip-hop\ntrap, cyberpunk, futuristic\ntrap, cyberpunk, glitch\ntrap, cyberpunk, hip hop\ntrap, cyberpunk, hip-hop\ntrap, cyberpunk, industrial\ntrap, cyberpunk, lo-fi\ntrap, cyberpunk, lo-fi hip hop\ntrap, cyberpunk, synthwave\ntrap, cyberpunk, vaporwave\ntrap, cyberpunk, vocal pop\ntrap, dance, electronic\ntrap, dance-pop, hip-hop\ntrap, dancehall\ntrap, dancehall, Balkan fusion\ntrap, dancehall, Balkan pop\ntrap, dancehall, C-pop\ntrap, dancehall, Dutch hip hop\ntrap, dancehall, French rap\ntrap, dancehall, Greek rap\ntrap, dancehall, J-hip hop\ntrap, dancehall, Latin\ntrap, dancehall, Middle Eastern hip-hop\ntrap, dancehall, Punjabi hip-hop\ntrap, dancehall, R&B\ntrap, dancehall, afro-fusion\ntrap, dancehall, afro-trap\ntrap, dancehall, afrobeat\ntrap, dancehall, afrobeats\ntrap, dancehall, ambient\ntrap, dancehall, atmospheric R&B\ntrap, dancehall, bilingual\ntrap, dancehall, boom-bap\ntrap, dancehall, chiptune\ntrap, dancehall, cinematic\ntrap, dancehall, club\ntrap, dancehall, conscious hip-hop\ntrap, dancehall, drill\ntrap, dancehall, ethnic\ntrap, dancehall, hip hop\ntrap, dancehall, hip-hop\ntrap, dancehall, industrial\ntrap, dancehall, lo-fi\ntrap, dancehall, lo-fi R&B\ntrap, dancehall, lo-fi hip hop\ntrap, dancehall, moody hip-hop\ntrap, dancehall, moombahton\ntrap, dancehall, pop\ntrap, dancehall, reggae fusion\ntrap, dancehall, video game\ntrap, danish hip hop\ntrap, danish rap\ntrap, danish rap, cinematic\ntrap, danish rap, lo-fi\ntrap, danish rap, lo-fi hip hop\ntrap, dark Arabic, cinematic\ntrap, dark R&B\ntrap, dark ambient\ntrap, dark ambient, Arabic hip hop\ntrap, dark ambient, Arabic rap\ntrap, dark ambient, Arabic trap\ntrap, dark ambient, Chinese hip hop\ntrap, dark ambient, Eastern flavor\ntrap, dark ambient, Eastern fusion\ntrap, dark ambient, French hip hop\ntrap, dark ambient, German rap\ntrap, dark ambient, Hindi\ntrap, dark ambient, Hungarian hip hop\ntrap, dark ambient, Italian hip-hop\ntrap, dark ambient, Italian rap\ntrap, dark ambient, Jamaican Patois rap\ntrap, dark ambient, Latin trap\ntrap, dark ambient, Middle Eastern\ntrap, dark ambient, Middle Eastern fusion\ntrap, dark ambient, North African\ntrap, dark ambient, Russian hip-hop\ntrap, dark ambient, Russian melodic rap\ntrap, dark ambient, Southern hip hop\ntrap, dark ambient, Turkish hip hop\ntrap, dark ambient, ancient style\ntrap, dark ambient, chiptune\ntrap, dark ambient, cinematic\ntrap, dark ambient, hardcore techno\ntrap, dark ambient, lo-fi\ntrap, dark ambient, melodic rap\ntrap, dark ambient, melodic trap\ntrap, dark ambient, rock\ntrap, dark choral\ntrap, dark cinematic\ntrap, dark classical\ntrap, dark dancehall\ntrap, dark electronic\ntrap, dark electronic, Latin trap\ntrap, dark electronic, Russian chant\ntrap, dark hip hop\ntrap, dark hip hop, psychedelic rap\ntrap, dark hip-hop\ntrap, dark hip-hop, cinematic\ntrap, dark house, deep tech house\ntrap, dark pop\ntrap, dark pop, Chinese horror\ntrap, dark pop, Eastern European\ntrap, dark pop, German cloud rap\ntrap, dark pop, Italian hip hop\ntrap, dark pop, Persian hip-hop\ntrap, dark pop, R&B\ntrap, dark pop, Turkish hip-hop\ntrap, dark pop, cinematic\ntrap, dark pop, electronic\ntrap, dark pop, electronic dance music\ntrap, dark pop, hip-hop\ntrap, dark rap\ntrap, dark rock\ntrap, dark synth\ntrap, dark synth, Chinese hip hop\ntrap, dark synth, Czech rap\ntrap, dark synth, French rap\ntrap, dark synth, German rap\ntrap, dark synth, Italian rap\ntrap, dark synth, Latin hip hop\ntrap, dark synth, Polish hip hop\ntrap, dark synth, Russian vocal\ntrap, dark synth, Turkish rap\ntrap, dark synth, cinematic\ntrap, dark synth, gothic hip hop\ntrap, dark synth, hip hop\ntrap, dark trap\ntrap, dark trap, Chinese hip hop\ntrap, dark trap, Chinese hip-hop\ntrap, dark trap, Hindi hip hop\ntrap, dark trap, Jamaican Patois rap\ntrap, dark trap, Persian rap\ntrap, dark trap, Russian hip hop\ntrap, dark trap, lo-fi\ntrap, dark wave\ntrap, dark wave, Russian hip hop\ntrap, dark wave, cinematic\ntrap, dark, African hip hop\ntrap, dark, Arabic hip hop\ntrap, dark, Chinese\ntrap, dark, Chinese hip hop\ntrap, dark, Chinese hip-hop\ntrap, dark, Czech hip hop\ntrap, dark, Czech rap\ntrap, dark, Dutch hip hop\ntrap, dark, Dutch hip-hop\ntrap, dark, Eastern\ntrap, dark, Eastern flavor\ntrap, dark, Eastern tonality\ntrap, dark, Eastern-influenced\ntrap, dark, Filipino\ntrap, dark, Filipino hip hop\ntrap, dark, Greek hip hop\ntrap, dark, Greek rap\ntrap, dark, Hebrew rap\ntrap, dark, Hindi hip hop\ntrap, dark, Italian hip hop\ntrap, dark, Italian hip-hop\ntrap, dark, Italian rap\ntrap, dark, Jamaican Patois\ntrap, dark, Japanese hip hop\ntrap, dark, Kazakh hip hop\ntrap, dark, Mandarin hip hop\ntrap, dark, Mandarin hip-hop\ntrap, dark, Mandarin rap\ntrap, dark, Middle Eastern\ntrap, dark, Mongolian\ntrap, dark, Moroccan hip hop\ntrap, dark, Nepali hip hop\ntrap, dark, Nordic\ntrap, dark, Norwegian hip hop\ntrap, dark, Polish hip hop\ntrap, dark, Polish rap\ntrap, dark, Portuguese hip hop\ntrap, dark, Romanian rap\ntrap, dark, Russian hip hop\ntrap, dark, Russian hip-hop\ntrap, dark, Russian rap\ntrap, dark, Spanish hip hop\ntrap, dark, Spanish rap\ntrap, dark, Swiss hip hop\ntrap, dark, Tagalog rap\ntrap, dark, Turkish hip hop\ntrap, dark, Turkish rap\ntrap, dark, aggressive\ntrap, dark, atmospheric\ntrap, dark, baroque\ntrap, dark, bilingual\ntrap, dark, chiptune\ntrap, dark, chopped and screwed\ntrap, dark, cinematic\ntrap, dark, classical\ntrap, dark, electronic\ntrap, dark, ethnic\ntrap, dark, exotic\ntrap, dark, festive\ntrap, dark, gothic\ntrap, dark, hip hop\ntrap, dark, hip-hop\ntrap, dark, jazzy\ntrap, dark, lo-fi\ntrap, dark, multilingual\ntrap, dark, mythological\ntrap, dark, oud\ntrap, dark, psychedelic\ntrap, dark, satirical\ntrap, dark, underground\ntrap, darkwave, electronic\ntrap, darkwave, phonk\ntrap, darkwave, synth-pop\ntrap, deep house\ntrap, dembow, electronic\ntrap, dembow, industrial\ntrap, demonic trap\ntrap, desi hip hop\ntrap, desi hip-hop\ntrap, desihop\ntrap, deutschrap, turkish trap\ntrap, devotional\ntrap, devotional hip-hop\ntrap, devotional, Hindi hip-hop\ntrap, devotional, Hindu\ntrap, devotional, Indian bhajan\ntrap, devotional, Indian fusion\ntrap, devotional, Indian hip hop\ntrap, devotional, Indian hip-hop\ntrap, devotional, South Asian\ntrap, devotional, South Asian fusion\ntrap, devotional, ambient\ntrap, devotional, big room house\ntrap, devotional, chiptune\ntrap, devotional, cinematic\ntrap, devotional, electronic\ntrap, devotional, epic\ntrap, devotional, hip-hop\ntrap, distorted, aggressive\ntrap, distorted, chopped and screwed\ntrap, dream pop\ntrap, dream pop, Arabic hip hop\ntrap, dream pop, Brazilian funk\ntrap, dream pop, C-pop\ntrap, dream pop, Chinese hip hop\ntrap, dream pop, Chinese pop\ntrap, dream pop, Chinese rap\ntrap, dream pop, French rap\ntrap, dream pop, Italian soul\ntrap, dream pop, J-pop\ntrap, dream pop, K-pop\ntrap, dream pop, Latin hip hop\ntrap, dream pop, Latin pop\ntrap, dream pop, Mandarin hip hop\ntrap, dream pop, Mandarin rap\ntrap, dream pop, Persian hip hop\ntrap, dream pop, R&B\ntrap, dream pop, Thai hip hop\ntrap, dream pop, Turkish pop\ntrap, dream pop, atmospheric rock\ntrap, dream pop, bilingual\ntrap, dream pop, electronic\ntrap, dream pop, experimental hip hop\ntrap, dream pop, hip-hop\ntrap, dream pop, hyperpop\ntrap, dream pop, lo-fi\ntrap, dream pop, lo-fi hip hop\ntrap, dream pop, post-rock\ntrap, dream pop, psychedelic\ntrap, dream pop, soul\ntrap, dream pop, synth pop\ntrap, dream pop, synth-pop\ntrap, dream rap, psychedelic\ntrap, dream-pop\ntrap, dream-pop, ambient\ntrap, dream-pop, cinematic\ntrap, dream-pop, spoken word\ntrap, dreamy\ntrap, dreamy R&B\ntrap, dreamy electronic\ntrap, dreamy hip hop\ntrap, dreamy rap\ntrap, dreamy synth\ntrap, dreamy synth, Arabic hip hop\ntrap, dreamy synth, Chinese hip hop\ntrap, dreamy synth, Dutch hip hop\ntrap, dreamy synth, German rap\ntrap, dreamy synth, Italian hip hop\ntrap, dreamy synth, Mandarin hip hop\ntrap, dreamy synth, Mandarin rap\ntrap, dreamy synth, Nepali hip hop\ntrap, dreamy synth, Turkish pop\ntrap, dreamy synth, auto-tune rap\ntrap, dreamy synth, psychedelic\ntrap, dreamy, Arabic hip hop\ntrap, dreamy, British hip hop\ntrap, dreamy, C-pop\ntrap, dreamy, Cantonese hip hop\ntrap, dreamy, Caribbean\ntrap, dreamy, Chinese hip hop\ntrap, dreamy, French rap\ntrap, dreamy, German pop\ntrap, dreamy, German rap\ntrap, dreamy, Japanese pop\ntrap, dreamy, Mandarin hip hop\ntrap, dreamy, Mandarin pop\ntrap, dreamy, Mandarin rap\ntrap, dreamy, Punjabi hip hop\ntrap, dreamy, R&B\ntrap, dreamy, Russian rap\ntrap, dreamy, ambient\ntrap, dreamy, aquatic\ntrap, dreamy, atmospheric\ntrap, dreamy, auto-tune\ntrap, dreamy, bilingual\ntrap, dreamy, chiptune\ntrap, dreamy, cinematic\ntrap, dreamy, cross-cultural\ntrap, dreamy, dancehall\ntrap, dreamy, dark pop\ntrap, dreamy, electronic\ntrap, dreamy, emotional\ntrap, dreamy, ethereal\ntrap, dreamy, hyperpop\ntrap, dreamy, lo-fi\ntrap, dreamy, lo-fi hip hop\ntrap, dreamy, melancholic\ntrap, dreamy, melodic\ntrap, dreamy, melodic rap\ntrap, dreamy, psychedelic\ntrap, dreamy, soul\ntrap, dreamy, soulful\ntrap, dreamy, vocaloid\ntrap, drill\ntrap, drill, Arabic hip hop\ntrap, drill, Asian hip hop\ntrap, drill, Balkan hip-hop\ntrap, drill, C-pop\ntrap, drill, Chinese hip hop\ntrap, drill, Chinese traditional\ntrap, drill, Desi hip-hop\ntrap, drill, Dutch hip hop\ntrap, drill, Eastern tonality\ntrap, drill, French hip hop\ntrap, drill, French rap\ntrap, drill, Greek hip hop\ntrap, drill, Haitian Creole hip hop\ntrap, drill, Haitian Creole rap\ntrap, drill, Hindi hip hop\ntrap, drill, Indonesian hip hop\ntrap, drill, Italian hip hop\ntrap, drill, Italian rap\ntrap, drill, J-hope\ntrap, drill, J-pop\ntrap, drill, Khmer hip hop\ntrap, drill, Latin hip hop\ntrap, drill, Latin trap\ntrap, drill, Mandarin hip hop\ntrap, drill, Middle Eastern\ntrap, drill, Middle Eastern fusion\ntrap, drill, Middle Eastern synth\ntrap, drill, Mongolian hip hop\ntrap, drill, Moroccan hip hop\ntrap, drill, North African\ntrap, drill, Persian hip hop\ntrap, drill, Portuguese hip hop\ntrap, drill, Portuguese hip-hop\ntrap, drill, Punjabi\ntrap, drill, Punjabi hip hop\ntrap, drill, R&B\ntrap, drill, Russian hip hop\ntrap, drill, South Asian\ntrap, drill, Southern hip-hop\ntrap, drill, Swahili hip hop\ntrap, drill, Swedish rap\ntrap, drill, Turkish saz\ntrap, drill, afro-phonk\ntrap, drill, aggressive\ntrap, drill, ambient\ntrap, drill, anime\ntrap, drill, atmospheric\ntrap, drill, bilingual\ntrap, drill, bilingual hip hop\ntrap, drill, boom-bap\ntrap, drill, chiptune\ntrap, drill, choral\ntrap, drill, cinematic\ntrap, drill, cinematic hip-hop\ntrap, drill, cinematic horror\ntrap, drill, classical-inspired\ntrap, drill, dancehall\ntrap, drill, dark\ntrap, drill, dark ambient\ntrap, drill, dark electronic\ntrap, drill, dark hip hop\ntrap, drill, dark trap\ntrap, drill, electronic\ntrap, drill, emo rap\ntrap, drill, ethereal\ntrap, drill, ethnic\ntrap, drill, flamenco\ntrap, drill, future bass\ntrap, drill, future hip hop\ntrap, drill, gangsta rap\ntrap, drill, global hip hop\ntrap, drill, gospel rap\ntrap, drill, grime\ntrap, drill, hip hop\ntrap, drill, hip-hop\ntrap, drill, lo-fi\ntrap, drill, lo-fi hip hop\ntrap, drill, melodic rap\ntrap, drill, multilingual\ntrap, drill, orchestral\ntrap, drill, orchestral hip hop\ntrap, drill, phonk\ntrap, drill, pluggnb\ntrap, drill, rage\ntrap, drill, rage trap\ntrap, drill, reggaeton\ntrap, drill, street rap\ntrap, drill, techno\ntrap, drill, vaporwave\ntrap, drum and bass\ntrap, drum and bass, R&B\ntrap, drum and bass, lo-fi hip hop\ntrap, drum and bass, trip-hop\ntrap, dubstep\ntrap, dubstep, C-pop\ntrap, dubstep, Chinese electronic\ntrap, dubstep, Chinese hip hop\ntrap, dubstep, EDM\ntrap, dubstep, German rap\ntrap, dubstep, Japanese hip-hop\ntrap, dubstep, R&B\ntrap, dubstep, Russian chant\ntrap, dubstep, Russian pop\ntrap, dubstep, ambient\ntrap, dubstep, chiptune\ntrap, dubstep, cinematic\ntrap, dubstep, cinematic hip-hop\ntrap, dubstep, deathstep\ntrap, dubstep, drum and bass\ntrap, dubstep, electronic\ntrap, dubstep, emotional hip-hop\ntrap, dubstep, experimental bass\ntrap, dubstep, festival\ntrap, dubstep, glitch hop\ntrap, dubstep, glitch-pop\ntrap, dubstep, hard trap\ntrap, dubstep, hardstyle\ntrap, dubstep, hardwave\ntrap, dubstep, hip hop\ntrap, dubstep, hip-hop\ntrap, dubstep, horrorcore\ntrap, dubstep, hybrid\ntrap, dubstep, hyperpop\ntrap, dubstep, lo-fi\ntrap, dubstep, lo-fi hip hop\ntrap, dubstep, neurofunk\ntrap, dubstep, pop\ntrap, dubstep, power metal\ntrap, duduk fusion, cinematic\ntrap, duduk, Anatolian\ntrap, duduk, Anatolian hip-hop\ntrap, duduk, Azerbaijani\ntrap, duduk, Middle Eastern\ntrap, duduk, Russian rap\ntrap, duduk, Turkish hip hop\ntrap, duduk, cinematic\ntrap, dystopian hip-hop\ntrap, dystopian hip-hop, cinematic\ntrap, dystopian, agressive\ntrap, dystopian, chiptune\ntrap, east coast hip hop\ntrap, eastern tonality\ntrap, edm, cinematic\ntrap, edm, russian\ntrap, educational hip hop\ntrap, educational, Chinese hip-hop\ntrap, educational, Chinese pop\ntrap, electro, bass house\ntrap, electro, hip-hop\ntrap, electro-house\ntrap, electro-pop\ntrap, electronic\ntrap, electronic dance\ntrap, electronic dance music\ntrap, electronic dance music, Indian folk\ntrap, electronic hip-hop\ntrap, electronic pop\ntrap, electronic pop, hyperpop\ntrap, electronic pop, world music\ntrap, electronic rock, motivational hip-hop\ntrap, electronic, Afro-urban\ntrap, electronic, Afrobeat\ntrap, electronic, Afroswing\ntrap, electronic, Albanian hip hop\ntrap, electronic, Arabic fusion\ntrap, electronic, Arabic hip hop\ntrap, electronic, Arabic pop\ntrap, electronic, Asian fusion\ntrap, electronic, Asian hip hop\ntrap, electronic, Australian\ntrap, electronic, Australian hip hop\ntrap, electronic, Australian outback\ntrap, electronic, Azerbaijani\ntrap, electronic, Balkan fusion\ntrap, electronic, Balkan hip hop\ntrap, electronic, Bollywood\ntrap, electronic, Brazilian hip hop\ntrap, electronic, British hip hop\ntrap, electronic, Bulgarian hip hop\ntrap, electronic, C-pop\ntrap, electronic, Cantopop\ntrap, electronic, Catalan hip hop\ntrap, electronic, Central Asian\ntrap, electronic, Central Asian folk\ntrap, electronic, Chinese experimental\ntrap, electronic, Chinese fusion\ntrap, electronic, Chinese future bass\ntrap, electronic, Chinese hip hop\ntrap, electronic, Chinese pop\ntrap, electronic, Czech\ntrap, electronic, Czech hip hop\ntrap, electronic, Czech pop\ntrap, electronic, Czech rap\ntrap, electronic, Dutch hip hop\ntrap, electronic, East Asian\ntrap, electronic, Eastern European\ntrap, electronic, Eastern flavor\ntrap, electronic, Eastern fusion\ntrap, electronic, Eastern-influenced\ntrap, electronic, Filipino hip hop\ntrap, electronic, French hip hop\ntrap, electronic, French hip-hop\ntrap, electronic, French pop\ntrap, electronic, French rap\ntrap, electronic, French-Spanish hip hop\ntrap, electronic, German hip hop\ntrap, electronic, German hip-hop\ntrap, electronic, German pop\ntrap, electronic, German rap\ntrap, electronic, Greek hip hop\ntrap, electronic, Greek pop\ntrap, electronic, Halloween\ntrap, electronic, Hebrew hip hop\ntrap, electronic, Hebrew pop\ntrap, electronic, Hebrew rap\ntrap, electronic, Hebrew vocal\ntrap, electronic, Hindi pop\ntrap, electronic, Hungarian\ntrap, electronic, Hungarian hip hop\ntrap, electronic, Hungarian pop\ntrap, electronic, Indian fusion\ntrap, electronic, Indian hip hop\ntrap, electronic, Indian pop\ntrap, electronic, Indonesian hip hop\ntrap, electronic, Italian hip hop\ntrap, electronic, Italian hip-hop\ntrap, electronic, Italian pop\ntrap, electronic, Italian rap\ntrap, electronic, J-core\ntrap, electronic, J-hiphop\ntrap, electronic, J-pop\ntrap, electronic, J-rap\ntrap, electronic, Japanese hip hop\ntrap, electronic, K-hip hop\ntrap, electronic, K-pop\ntrap, electronic, Kannada hip hop\ntrap, electronic, Khmer hip hop\ntrap, electronic, Latin\ntrap, electronic, Latin hip hop\ntrap, electronic, Latin pop\ntrap, electronic, Latin urban\ntrap, electronic, Latvian rap\ntrap, electronic, Malaysian\ntrap, electronic, Mandarin hip hop\ntrap, electronic, Mandarin pop\ntrap, electronic, Mandarin rap\ntrap, electronic, Mandopop\ntrap, electronic, Middle Eastern\ntrap, electronic, Middle Eastern fusion\ntrap, electronic, Mongolian hip hop\ntrap, electronic, Moroccan hip hop\ntrap, electronic, Nordic hip hop\ntrap, electronic, North African\ntrap, electronic, North African fusion\ntrap, electronic, Norwegian hip hop\ntrap, electronic, Persian\ntrap, electronic, Persian hip hop\ntrap, electronic, Persian vocal\ntrap, electronic, Polish\ntrap, electronic, Polish hip hop\ntrap, electronic, Polish hip-hop\ntrap, electronic, Polish rap\ntrap, electronic, Portuguese\ntrap, electronic, Punjabi\ntrap, electronic, R&B\ntrap, electronic, Romanian\ntrap, electronic, Romanian hip hop\ntrap, electronic, Russian\ntrap, electronic, Russian hip hop\ntrap, electronic, Russian pop\ntrap, electronic, Russian rap\ntrap, electronic, Russian spoken word\ntrap, electronic, Russian vocal\ntrap, electronic, Sinhala hip hop\ntrap, electronic, Slavic hip hop\ntrap, electronic, Slovak hip hop\ntrap, electronic, South Asian\ntrap, electronic, South Asian fusion\ntrap, electronic, South Asian pop\ntrap, electronic, South Indian folk\ntrap, electronic, Spanish hip hop\ntrap, electronic, Swedish hip hop\ntrap, electronic, Swedish pop\ntrap, electronic, Swedish rap\ntrap, electronic, Swiss hip hop\ntrap, electronic, Tamil hip hop\ntrap, electronic, Telugu hip hop\ntrap, electronic, Thai fusion\ntrap, electronic, Thai hip hop\ntrap, electronic, Thai pop\ntrap, electronic, Turkish fusion\ntrap, electronic, Turkish hip hop\ntrap, electronic, Turkish pop\ntrap, electronic, UK rap\ntrap, electronic, Ukrainian\ntrap, electronic, Ukrainian hip hop\ntrap, electronic, Ukrainian pop\ntrap, electronic, Ukrainian vocal\ntrap, electronic, Uyghur hip hop\ntrap, electronic, Vietnamese hip hop\ntrap, electronic, aggressive\ntrap, electronic, aggro\ntrap, electronic, ambient\ntrap, electronic, ancient style\ntrap, electronic, anime\ntrap, electronic, bilingual\ntrap, electronic, bilingual hip hop\ntrap, electronic, blues-rock\ntrap, electronic, breakcore\ntrap, electronic, chiptune\ntrap, electronic, choral\ntrap, electronic, cinematic\ntrap, electronic, club\ntrap, electronic, conscious hip-hop\ntrap, electronic, crypto\ntrap, electronic, cyberpunk\ntrap, electronic, dance\ntrap, electronic, danish rap\ntrap, electronic, dark\ntrap, electronic, dark ambient\ntrap, electronic, dark pop\ntrap, electronic, devotional\ntrap, electronic, dream pop\ntrap, electronic, dubstep\ntrap, electronic, dystopian\ntrap, electronic, emotional\ntrap, electronic, experimental\ntrap, electronic, fantasy\ntrap, electronic, feminist\ntrap, electronic, folk\ntrap, electronic, folk-pop\ntrap, electronic, future bass\ntrap, electronic, futuristic\ntrap, electronic, glitch\ntrap, electronic, global hip hop\ntrap, electronic, global pop\ntrap, electronic, hip hop\ntrap, electronic, hip-hop\ntrap, electronic, horrorcore\ntrap, electronic, hyperpop\ntrap, electronic, industrial\ntrap, electronic, instrumental\ntrap, electronic, jazz-infused\ntrap, electronic, k-pop\ntrap, electronic, kuthu\ntrap, electronic, lo-fi\ntrap, electronic, lo-fi hip hop\ntrap, electronic, melodic rap\ntrap, electronic, minimalist\ntrap, electronic, multilingual\ntrap, electronic, mythological\ntrap, electronic, nerdcore\ntrap, electronic, ney\ntrap, electronic, nu-metal\ntrap, electronic, oriental\ntrap, electronic, political\ntrap, electronic, pop\ntrap, electronic, protest\ntrap, electronic, psychedelic\ntrap, electronic, quirky\ntrap, electronic, reggaeton\ntrap, electronic, rock\ntrap, electronic, sci-fi\ntrap, electronic, space pop\ntrap, electronic, spoken word\ntrap, electronic, steel pan\ntrap, electronic, synth-pop\ntrap, electronic, traditional East Asian\ntrap, electronic, underground hip-hop\ntrap, electronic, video game\ntrap, electronic, vocal glitch\ntrap, electronic, vocal house\ntrap, electronic, workout\ntrap, electronic, world fusion\ntrap, electronic, world music\ntrap, emo rap\ntrap, emo rap, Brazilian\ntrap, emo rap, C-pop\ntrap, emo rap, J-pop\ntrap, emo rap, K-pop\ntrap, emo rap, R&B\ntrap, emo rap, alternative R&B\ntrap, emo rap, ambient\ntrap, emo rap, atmospheric\ntrap, emo rap, atmospheric R&B\ntrap, emo rap, atmospheric electronic\ntrap, emo rap, atmospheric pop\ntrap, emo rap, chiptune\ntrap, emo rap, cinematic\ntrap, emo rap, cinematic hip-hop\ntrap, emo rap, cloud rap\ntrap, emo rap, dark pop\ntrap, emo rap, dream pop\ntrap, emo rap, electronic\ntrap, emo rap, hardstyle\ntrap, emo rap, hyperpop\ntrap, emo rap, lo-fi\ntrap, emo rap, lo-fi hip-hop\ntrap, emo rap, quirky pop\ntrap, emo rap, rock\ntrap, emo rap, synth-pop\ntrap, emo rap, world music\ntrap, emo trap\ntrap, emo, Chinese hip hop\ntrap, emo, Russian hip hop\ntrap, emo, acoustic\ntrap, emo-rap\ntrap, emo-rap, Arabic\ntrap, emo-rap, Asian fusion\ntrap, emo-rap, ambient\ntrap, emo-rap, atmospheric\ntrap, emo-rap, chiptune\ntrap, emo-rap, chopped and screwed\ntrap, emo-rap, cinematic\ntrap, emo-rap, cloud rap\ntrap, emo-rap, cloud-rap\ntrap, emo-rap, dark ambient\ntrap, emo-rap, drill\ntrap, emo-rap, dubstep\ntrap, emo-rap, experimental\ntrap, emo-rap, hyperpop\ntrap, emo-rap, indie rock\ntrap, emo-rap, lo-fi\ntrap, emo-rap, nu-metal\ntrap, emo-rap, psychedelic\ntrap, emo-rap, rock\ntrap, emo-rap, synth pop\ntrap, emo-rap, synthwave\ntrap, emo-rap, vaporwave\ntrap, emo-rock\ntrap, emo-trap\ntrap, emo-trap, R&B\ntrap, emotional C-pop\ntrap, emotional R&B\ntrap, emotional R&B, Chinese pop\ntrap, emotional R&B, cloud rap\ntrap, emotional ballad\ntrap, emotional electronic\ntrap, emotional hip hop\ntrap, emotional hip-hop\ntrap, emotional hip-hop, R&B\ntrap, emotional hip-hop, atmospheric R&B\ntrap, emotional hip-hop, contemporary R&B\ntrap, emotional hip-hop, pop\ntrap, emotional piano\ntrap, emotional pop\ntrap, emotional pop, Eastern influence\ntrap, emotional rap\ntrap, emotional rap, Albanian\ntrap, emotional rap, C-pop\ntrap, emotional rap, Chinese hip hop\ntrap, emotional rap, Chinese pop\ntrap, emotional rap, French\ntrap, emotional rap, ambient\ntrap, emotional rap, cinematic\ntrap, emotional rap, lo-fi\ntrap, emotional rap, modern C-pop\ntrap, emotional, C-pop\ntrap, emotional, Hebrew vocal\ntrap, emotional, Hungarian\ntrap, emotional, Indonesian hip hop\ntrap, emotional, Kazakh\ntrap, emotional, Mandarin\ntrap, emotional, Mandarin hip hop\ntrap, emotional, Mandarin pop\ntrap, emotional, Mandarin rap\ntrap, emotional, Romanian\ntrap, emotional, Russian\ntrap, emotional, Russian hip hop\ntrap, emotional, Russian pop\ntrap, emotional, Turkish hip hop\ntrap, emotional, ambient\ntrap, emotional, atmospheric\ntrap, emotional, bilingual\ntrap, emotional, cinematic\ntrap, emotional, dark\ntrap, emotional, futuristic\ntrap, emotional, hyperpop\ntrap, emotional, lo-fi\ntrap, emotional, rock-infused\ntrap, epic, German rap\ntrap, epic, Middle Eastern\ntrap, epic, R&B\ntrap, epic, ancient style\ntrap, epic, bilingual\ntrap, epic, choir\ntrap, epic, choral\ntrap, epic, cinematic\ntrap, epic, mythological\ntrap, epic, world music\ntrap, ethereal\ntrap, ethereal R&B\ntrap, ethereal R&B, Afrobeats\ntrap, ethereal hip hop\ntrap, ethereal hip-hop\ntrap, ethereal pop\ntrap, ethereal pop, Asian hip hop\ntrap, ethereal pop, C-pop\ntrap, ethereal pop, Chinese hip hop\ntrap, ethereal pop, Chinese pop\ntrap, ethereal pop, cinematic\ntrap, ethereal rap\ntrap, ethereal synth\ntrap, ethereal, Afro-Asian fusion\ntrap, ethereal, Albanian hip-hop\ntrap, ethereal, Arabic\ntrap, ethereal, Arabic fusion\ntrap, ethereal, Arabic hip hop\ntrap, ethereal, Arabic pop\ntrap, ethereal, Armenian\ntrap, ethereal, Azerbaijani\ntrap, ethereal, Balkan\ntrap, ethereal, British rap\ntrap, ethereal, C-pop\ntrap, ethereal, Central Asian\ntrap, ethereal, Chinese hip hop\ntrap, ethereal, Chinese hip-hop\ntrap, ethereal, Chinese pop\ntrap, ethereal, Chinese rap\ntrap, ethereal, Czech hip hop\ntrap, ethereal, Czech rap\ntrap, ethereal, Dutch\ntrap, ethereal, Dutch hip hop\ntrap, ethereal, Eastern\ntrap, ethereal, Eastern fusion\ntrap, ethereal, Finnish hip hop\ntrap, ethereal, French rap\ntrap, ethereal, German hip hop\ntrap, ethereal, German rap\ntrap, ethereal, Greek\ntrap, ethereal, Hebrew hip hop\ntrap, ethereal, Hebrew rap\ntrap, ethereal, Hindi pop\ntrap, ethereal, Hindustani\ntrap, ethereal, Hungarian\ntrap, ethereal, Hungarian hip hop\ntrap, ethereal, Hungarian pop\ntrap, ethereal, Icelandic\ntrap, ethereal, Icelandic pop\ntrap, ethereal, Indonesian hip hop\ntrap, ethereal, J-pop\ntrap, ethereal, Kazakh hip hop\ntrap, ethereal, Kazakh pop\ntrap, ethereal, Khmer rap\ntrap, ethereal, Kurdish\ntrap, ethereal, Latin pop\ntrap, ethereal, Malayalam\ntrap, ethereal, Mandarin hip hop\ntrap, ethereal, Mandarin rap\ntrap, ethereal, Middle Eastern\ntrap, ethereal, Mongolian hip hop\ntrap, ethereal, Persian\ntrap, ethereal, Persian hip hop\ntrap, ethereal, Portuguese\ntrap, ethereal, Punjabi hip hop\ntrap, ethereal, R&B\ntrap, ethereal, Russian pop\ntrap, ethereal, Russian rap\ntrap, ethereal, Russian vocal\ntrap, ethereal, Sinhala pop\ntrap, ethereal, Slovak\ntrap, ethereal, Slovak hip hop\ntrap, ethereal, Slovak rap\ntrap, ethereal, South Asian fusion\ntrap, ethereal, Swahili hip hop\ntrap, ethereal, Swiss German rap\ntrap, ethereal, Tamil\ntrap, ethereal, Tamil pop\ntrap, ethereal, Thai hip hop\ntrap, ethereal, Tibetan hip hop\ntrap, ethereal, Tigrinya hip hop\ntrap, ethereal, Turkish\ntrap, ethereal, Turkish fusion\ntrap, ethereal, Turkish pop\ntrap, ethereal, Turkish rap\ntrap, ethereal, Ukrainian\ntrap, ethereal, Ukrainian pop\ntrap, ethereal, Uyghur hip hop\ntrap, ethereal, ambient\ntrap, ethereal, bilingual\ntrap, ethereal, bilingual hip-hop\ntrap, ethereal, chopped and screwed\ntrap, ethereal, cinematic\ntrap, ethereal, cross-cultural\ntrap, ethereal, dark ambient\ntrap, ethereal, dark pop\ntrap, ethereal, electronic\ntrap, ethereal, emo-rap\ntrap, ethereal, emotional\ntrap, ethereal, empowerment\ntrap, ethereal, experimental\ntrap, ethereal, glitch\ntrap, ethereal, hardstyle\ntrap, ethereal, hip hop\ntrap, ethereal, hyperpop\ntrap, ethereal, industrial\ntrap, ethereal, jazz fusion\ntrap, ethereal, lo-fi\ntrap, ethereal, lo-fi hip hop\ntrap, ethereal, melodic\ntrap, ethereal, melodic rap\ntrap, ethereal, minimalist\ntrap, ethereal, modern\ntrap, ethereal, modern R&B\ntrap, ethereal, modern hip hop\ntrap, ethereal, mystical\ntrap, ethereal, ritual\ntrap, ethereal, rock\ntrap, ethereal, soulful\ntrap, ethereal, spoken word\ntrap, ethnic\ntrap, ethnic ambient\ntrap, ethnic fusion\ntrap, ethnic fusion, Mandarin rap\ntrap, ethnic fusion, Russian hip hop\ntrap, ethnic fusion, ambient\ntrap, ethnic fusion, cinematic\ntrap, ethnic fusion, hardstyle\ntrap, ethnic fusion, lo-fi\ntrap, ethnic percussion\ntrap, ethnic pop\ntrap, ethnic synth, Azerbaijani hip hop\ntrap, ethnic synth, Balkan\ntrap, ethnic synth, pop-R&B\ntrap, ethnic trap\ntrap, ethnic world music\ntrap, ethnic, French rap\ntrap, ethnic, Middle Eastern\ntrap, ethnic, ambient\ntrap, ethnic, atmospheric\ntrap, ethnic, cinematic\ntrap, ethnic, dark\ntrap, ethnic, emotional\ntrap, ethnic, hard-hitting\ntrap, ethnic, hip hop\ntrap, ethnic, lo-fi\ntrap, ethnic, melancholic\ntrap, ethno-electronic\ntrap, ethno-pop\ntrap, exotic synth\ntrap, exotic, aggressive\ntrap, exotic, chiptune\ntrap, exotic, cinematic\ntrap, experimental\ntrap, experimental club\ntrap, experimental electronic\ntrap, experimental electronic, hip-hop\ntrap, experimental hip hop\ntrap, experimental hip-hop\ntrap, experimental hip-hop, electronic\ntrap, experimental pop, Brazilian funk\ntrap, experimental pop, hip-hop\ntrap, experimental reggaeton\ntrap, experimental, Azerbaijani hip hop\ntrap, experimental, C-pop\ntrap, experimental, Chinese fusion\ntrap, experimental, Chinese hip hop\ntrap, experimental, Eastern fusion\ntrap, experimental, French rap\ntrap, experimental, German hip hop\ntrap, experimental, Middle Eastern\ntrap, experimental, Persian\ntrap, experimental, Polish rap\ntrap, experimental, Russian hip hop\ntrap, experimental, South Asian fusion\ntrap, experimental, Tamil hip hop\ntrap, experimental, ambient\ntrap, experimental, bilingual rap\ntrap, experimental, chiptune\ntrap, experimental, cinematic\ntrap, experimental, cloud rap\ntrap, experimental, dark ambient\ntrap, experimental, dark pop\ntrap, experimental, electronic\ntrap, experimental, emo rap\ntrap, experimental, ethnic fusion\ntrap, experimental, female rap\ntrap, experimental, glitch\ntrap, experimental, hyperpop\ntrap, experimental, jazzy hip-hop\ntrap, experimental, lo-fi\ntrap, experimental, melodic rap\ntrap, experimental, pop\ntrap, experimental, psychedelic\ntrap, experimental, rock\ntrap, experimental, spoken word\ntrap, fado\ntrap, fado, electronic\ntrap, falsetto, atmospheric\ntrap, female rap, twerk\ntrap, festival, Chinese hip hop\ntrap, festival, Dutch House\ntrap, festival, Dutch house\ntrap, festival, Middle Eastern\ntrap, festival, Middle Eastern fusion\ntrap, festival, Middle Eastern synth\ntrap, festival, electronic\ntrap, festival, hardstyle\ntrap, festive\ntrap, festive hip-hop\ntrap, festive, Chinese hip hop\ntrap, festive, Mandarin hip hop\ntrap, festive, R&B\ntrap, festive, Southern hip-hop\ntrap, festive, Swedish rap\ntrap, festive, aggressive\ntrap, festive, ambient\ntrap, festive, anime\ntrap, festive, braggadocious\ntrap, festive, cinematic\ntrap, festive, dark pop\ntrap, festive, electronic\ntrap, festive, gritty\ntrap, festive, hip hop\ntrap, festive, hip-hop\ntrap, festive, hyperpop\ntrap, festive, lo-fi\ntrap, festive, melancholic\ntrap, festive, modern\ntrap, festive, multilingual\ntrap, festive, pop\ntrap, festive, satirical\ntrap, festive, soulful\ntrap, fiddle, electronic\ntrap, flamenco\ntrap, flamenco fusion\ntrap, flamenco hip hop\ntrap, flamenco hip-hop\ntrap, flamenco rap\ntrap, flamenco, Afrobeat\ntrap, flamenco, Arabic hip hop\ntrap, flamenco, C-pop\ntrap, flamenco, Chinese hip hop\ntrap, flamenco, Chinese hip-hop\ntrap, flamenco, Dutch hip hop\ntrap, flamenco, French hip hop\ntrap, flamenco, French rap\ntrap, flamenco, Italian hip-hop\ntrap, flamenco, Italian rap\ntrap, flamenco, Italian soul\ntrap, flamenco, Latin\ntrap, flamenco, Latin hip hop\ntrap, flamenco, Middle Eastern\ntrap, flamenco, Portuguese rap\ntrap, flamenco, Romanian\ntrap, flamenco, Russian hip hop\ntrap, flamenco, Russian pop\ntrap, flamenco, Russian rap\ntrap, flamenco, Turkish hip hop\ntrap, flamenco, ambient\ntrap, flamenco, bilingual hip hop\ntrap, flamenco, cinematic\ntrap, flamenco, drill\ntrap, flamenco, emotional\ntrap, flamenco, emotional rap\ntrap, flamenco, ethereal\ntrap, flamenco, hip hop\ntrap, flamenco, hip-hop\ntrap, flamenco, instrumental\ntrap, flamenco, jazz\ntrap, flamenco, lo-fi\ntrap, flamenco, lo-fi hip hop\ntrap, flamenco, melodic rap\ntrap, flamenco, political hip-hop\ntrap, flamenco, pop\ntrap, flamenco, protest hip-hop\ntrap, flamenco, rap\ntrap, flamenco, rock\ntrap, flamenco, urban\ntrap, folk\ntrap, folk fusion\ntrap, folk fusion, Anatolian\ntrap, folk fusion, Central Asian\ntrap, folk fusion, Italian hip-hop\ntrap, folk fusion, South Asian\ntrap, folk fusion, ambient\ntrap, folk fusion, electronic\ntrap, folk, Anatolian\ntrap, folk, C-pop\ntrap, folk, Central Asian\ntrap, folk, Chinese hip hop\ntrap, folk, EDM\ntrap, folk, Eastern European\ntrap, folk, French rap\ntrap, folk, Hungarian hip hop\ntrap, folk, Indian\ntrap, folk, Japanese hip hop\ntrap, folk, Latin\ntrap, folk, Latin rap\ntrap, folk, Punjabi\ntrap, folk, Russian\ntrap, folk, Slavic\ntrap, folk, South Asian\ntrap, folk, Southeast Asian\ntrap, folk, Ukrainian\ntrap, folk, alpine\ntrap, folk, ambient\ntrap, folk, bilingual\ntrap, folk, chiptune\ntrap, folk, choral\ntrap, folk, cinematic\ntrap, folk, duduk\ntrap, folk, electronic\ntrap, folk, emotional rap\ntrap, folk, epic\ntrap, folk, ethereal\ntrap, folk, hip hop\ntrap, folk, hip-hop\ntrap, folk, lo-fi\ntrap, folk, lo-fi hip hop\ntrap, folk, melancholic\ntrap, folk, pop\ntrap, folk, rock\ntrap, folk, sea shanty\ntrap, folk, spiritual\ntrap, folk, world music\ntrap, folk-infused pop\ntrap, folk-rap, Punjabi\ntrap, folk-trap\ntrap, folkloric fusion\ntrap, free jazz\ntrap, freestyle rap\ntrap, funk\ntrap, funk carioca\ntrap, funk, R&B\ntrap, funk, ambient\ntrap, funk, electronic\ntrap, funk, soul\ntrap, funk-rap\ntrap, funk-rock\ntrap, fusion, Hindi pop\ntrap, fusion, Indian\ntrap, fusion, Indian hip hop\ntrap, fusion, Middle Eastern\ntrap, fusion, Punjabi hip-hop\ntrap, fusion, South Asian\ntrap, fusion, ambient\ntrap, fusion, cinematic\ntrap, fusion, lo-fi hip hop\ntrap, fusion, pop-R&B\ntrap, fusion, world hip hop\ntrap, fusion, world music\ntrap, future bass\ntrap, future bass, Afro trap\ntrap, future bass, Bollywood\ntrap, future bass, C-pop\ntrap, future bass, Chinese hip hop\ntrap, future bass, Christmas\ntrap, future bass, EDM\ntrap, future bass, French rap\ntrap, future bass, Indian folk\ntrap, future bass, Middle Eastern pop\ntrap, future bass, R&B\ntrap, future bass, Russian rap\ntrap, future bass, South Asian\ntrap, future bass, Tamil electronic\ntrap, future bass, Thai hip hop\ntrap, future bass, Vietnamese hip hop\ntrap, future bass, alternative rock\ntrap, future bass, ambient\ntrap, future bass, ambient electronic\ntrap, future bass, chiptune\ntrap, future bass, cinematic\ntrap, future bass, cyberpunk\ntrap, future bass, dancehall\ntrap, future bass, dark electronic\ntrap, future bass, dubstep\ntrap, future bass, electronic\ntrap, future bass, emotional\ntrap, future bass, emotional R&B\ntrap, future bass, ethereal pop\ntrap, future bass, experimental electronic\ntrap, future bass, glitch\ntrap, future bass, glitch pop\ntrap, future bass, glitch-hop\ntrap, future bass, glitch-pop\ntrap, future bass, hardstyle\ntrap, future bass, hardwave\ntrap, future bass, hip hop\ntrap, future bass, hyperpop\ntrap, future bass, lo-fi\ntrap, future bass, lo-fi hip hop\ntrap, future bass, melodic rap\ntrap, future bass, phonk\ntrap, future bass, pop\ntrap, future bass, pop-R&B\ntrap, future bass, pop-punk\ntrap, future bass, pop-rock\ntrap, future bass, vaporwave\ntrap, future bass, world music\ntrap, future garage\ntrap, future garage, cinematic\ntrap, future pop\ntrap, future rap\ntrap, future soul\ntrap, future trap, Turkish rap\ntrap, future, Jamaican Patois\ntrap, future, chiptune\ntrap, futuristic\ntrap, futuristic pop\ntrap, futuristic, Afrikaans hip hop\ntrap, futuristic, Arabic hip hop\ntrap, futuristic, Chinese hip hop\ntrap, futuristic, Haitian Creole rap\ntrap, futuristic, Indian hip hop\ntrap, futuristic, Mandarin hip hop\ntrap, futuristic, Mandarin rap\ntrap, futuristic, Middle Eastern fusion\ntrap, futuristic, Middle Eastern synth\ntrap, futuristic, Norwegian hip hop\ntrap, futuristic, Polish rap\ntrap, futuristic, Romanian rap\ntrap, futuristic, Russian hip hop\ntrap, futuristic, Russian rap\ntrap, futuristic, Spanish hip hop\ntrap, futuristic, Spanish rap\ntrap, futuristic, Thai hip hop\ntrap, futuristic, Turkish hip hop\ntrap, futuristic, Zulu rap\ntrap, futuristic, aggressive\ntrap, futuristic, agressive\ntrap, futuristic, atmospheric\ntrap, futuristic, chiptune\ntrap, futuristic, chopped and screwed\ntrap, futuristic, cinematic\ntrap, futuristic, cloud rap\ntrap, futuristic, cyberpunk\ntrap, futuristic, dark\ntrap, futuristic, electronic\ntrap, futuristic, hip hop\ntrap, futuristic, hyperpop\ntrap, futuristic, industrial\ntrap, futuristic, psychedelic\ntrap, futuristic, sci-fi\ntrap, futuristic, synth\ntrap, futuristic, synth-flute\ntrap, futuristic, vaporwave\ntrap, g-funk, hip hop\ntrap, gabber, Dutch hip-hop\ntrap, gamelan, hip-hop\ntrap, gamelan, lo-fi hip hop\ntrap, gaming music\ntrap, gaming, Mandarin hip hop\ntrap, gaming, cinematic\ntrap, gaming, electronic\ntrap, gangsta rap\ntrap, gangsta rap, Dutch hip hop\ntrap, gangsta rap, Eastern European\ntrap, gangsta rap, Southern hip-hop\ntrap, gangsta rap, chiptune\ntrap, gangsta rap, cinematic\ntrap, gangsta rap, crunk\ntrap, gangsta rap, drill\ntrap, gangsta rap, lo-fi\ntrap, gangsta rap, orchestral\ntrap, gangsta rap, regional Mexican\ntrap, gangsta rap, retro synth\ntrap, gangsta rap, southern hip-hop\ntrap, gangster rap\ntrap, gangster rap, cinematic\ntrap, gangster rap, cinematic hip-hop\ntrap, gangster rap, lo-fi\ntrap, gangster rap, microtonal\ntrap, gangster rap, orchestral\ntrap, gangster rap, regional Mexican\ntrap, gangster rap, synth brass\ntrap, german hip hop\ntrap, german rap\ntrap, german rap, ambient\ntrap, ghazal\ntrap, ghazal, EDM\ntrap, ghazal, Indian folk\ntrap, ghazal, ambient\ntrap, ghazal, cinematic\ntrap, ghazal, folk\ntrap, ghazal, fusion\ntrap, ghazal, qawwali\ntrap, glitch\ntrap, glitch hop\ntrap, glitch hop, K-pop\ntrap, glitch hop, anime pop\ntrap, glitch hop, lo-fi\ntrap, glitch, Afrofuture\ntrap, glitch, Cantonese hip hop\ntrap, glitch, Chinese hip hop\ntrap, glitch, Hungarian hip hop\ntrap, glitch, J-pop\ntrap, glitch, Latin rap\ntrap, glitch, Mongolian hip hop\ntrap, glitch, Nepali hip hop\ntrap, glitch, Polish hip hop\ntrap, glitch, Polish rap\ntrap, glitch, Romanian hip hop\ntrap, glitch, ambient\ntrap, glitch, bilingual\ntrap, glitch, chip-hop\ntrap, glitch, chip-tune\ntrap, glitch, chiptune\ntrap, glitch, chopped and screwed\ntrap, glitch, cinematic\ntrap, glitch, cyberpunk\ntrap, glitch, dark ambient\ntrap, glitch, dark electronic\ntrap, glitch, deathcore\ntrap, glitch, electronic\ntrap, glitch, emotional rap\ntrap, glitch, ethereal\ntrap, glitch, experimental\ntrap, glitch, experimental hip hop\ntrap, glitch, future bass\ntrap, glitch, hyperpop\ntrap, glitch, industrial\ntrap, glitch, lo-fi\ntrap, glitch, lo-fi hip hop\ntrap, glitch, melodic rap\ntrap, glitch, minimalist\ntrap, glitch, psychedelic\ntrap, glitch, video game\ntrap, glitch, world music\ntrap, glitch-hop\ntrap, glitch-hop, Cantopop\ntrap, glitch-hop, Indian fusion\ntrap, glitch-hop, breakcore\ntrap, glitch-hop, cinematic\ntrap, glitch-hop, dark pop\ntrap, glitch-hop, dubstep\ntrap, glitch-hop, electronic\ntrap, glitch-hop, experimental electronic\ntrap, glitch-hop, experimental hip-hop\ntrap, glitch-hop, hip-hop\ntrap, glitch-hop, phonk\ntrap, global bass\ntrap, global fusion\ntrap, global hip hop\ntrap, global hip-hop\ntrap, global pop, Punjabi\ntrap, global pop, hip-hop\ntrap, global, melodic rap\ntrap, gospel\ntrap, gospel hip-hop\ntrap, gospel rap\ntrap, gospel rap, cloud rap\ntrap, gospel, Afro-soul\ntrap, gospel, Afro-spiritual\ntrap, gospel, British hip hop\ntrap, gospel, C-pop\ntrap, gospel, Chinese hip hop\ntrap, gospel, French rap\ntrap, gospel, German hip hop\ntrap, gospel, Haitian Creole\ntrap, gospel, K-pop\ntrap, gospel, Latin hip hop\ntrap, gospel, Mandarin hip hop\ntrap, gospel, Mandarin rap\ntrap, gospel, R&B\ntrap, gospel, Southern hip hop\ntrap, gospel, Southern rap\ntrap, gospel, ambient\ntrap, gospel, cinematic\ntrap, gospel, dark hip hop\ntrap, gospel, electronic\ntrap, gospel, emotional hip hop\ntrap, gospel, ethereal\ntrap, gospel, experimental\ntrap, gospel, experimental hip-hop\ntrap, gospel, female vocal\ntrap, gospel, future soul\ntrap, gospel, hip hop\ntrap, gospel, hip-hop\ntrap, gospel, lo-fi\ntrap, gospel, lo-fi hip hop\ntrap, gospel, psychedelic\ntrap, gospel, reggae\ntrap, gospel, soul\ntrap, gospel, vaporwave\ntrap, gospel, video game score\ntrap, gothic\ntrap, gothic classical\ntrap, gothic hip hop\ntrap, gothic hip-hop\ntrap, gothic hip-hop, dark ambient\ntrap, gothic horror\ntrap, gothic rap\ntrap, gothic synth\ntrap, gothic synth, chiptune\ntrap, gothic, Caribbean\ntrap, gothic, Chinese hip hop\ntrap, gothic, German hip hop\ntrap, gothic, Polish rap\ntrap, gothic, Russian rap\ntrap, gothic, ambient\ntrap, gothic, cinematic\ntrap, gothic, classical\ntrap, gothic, dark hip hop\ntrap, gothic, horrorcore\ntrap, grime\ntrap, grime, afrobeats\ntrap, grime, ambient\ntrap, grime, cinematic\ntrap, grime, cinematic R&B\ntrap, grime, electronic\ntrap, grime, hip-hop\ntrap, grime, lo-fi hip hop\ntrap, gufeng, lo-fi\ntrap, guzheng\ntrap, guzheng fusion, Japanese rap\ntrap, guzheng, East Asian\ntrap, guzheng, ambient\ntrap, guzheng, atmospheric\ntrap, guzheng, cinematic\ntrap, guzheng, cross-cultural\ntrap, guzheng, electronic\ntrap, guzheng, fusion\ntrap, guzheng, hardstyle\ntrap, guzheng, lo-fi\ntrap, guzheng, lo-fi hip hop\ntrap, guzheng, melancholic\ntrap, guzheng, melodic\ntrap, guzheng, modern\ntrap, gypsy, hip-hop\ntrap, happy hardcore\ntrap, hard dance\ntrap, hard dance, Chinese hip hop\ntrap, hard dance, electronic\ntrap, hard dance, hardstyle\ntrap, hard trap\ntrap, hard trap, EDM-trap\ntrap, hard-hitting\ntrap, hard-hitting, Mandarin rap\ntrap, hard-hitting, bilingual\ntrap, hard-hitting, cinematic\ntrap, hardcore hip-hop\ntrap, hardcore punk\ntrap, hardcore punk, French rap\ntrap, hardcore punk, electronic\ntrap, hardcore punk, hip hop\ntrap, hardstyle\ntrap, hardstyle, Arabic fusion\ntrap, hardstyle, Arabic hip hop\ntrap, hardstyle, Arabic pop\ntrap, hardstyle, C-pop\ntrap, hardstyle, Chinese hip hop\ntrap, hardstyle, Dutch hip-hop\ntrap, hardstyle, Dutch house\ntrap, hardstyle, EDM\ntrap, hardstyle, French rap\ntrap, hardstyle, German rap\ntrap, hardstyle, Indian classical\ntrap, hardstyle, Indian fusion\ntrap, hardstyle, Indonesian hip-hop\ntrap, hardstyle, J-pop\ntrap, hardstyle, K-pop\ntrap, hardstyle, K-rap\ntrap, hardstyle, Latin\ntrap, hardstyle, Latin hip hop\ntrap, hardstyle, Mandarin hip hop\ntrap, hardstyle, Mandarin rap\ntrap, hardstyle, Middle Eastern\ntrap, hardstyle, Middle Eastern electronic\ntrap, hardstyle, Middle Eastern fusion\ntrap, hardstyle, Mongolian hip hop\ntrap, hardstyle, Nepali rap\ntrap, hardstyle, R&B\ntrap, hardstyle, Romanian rap\ntrap, hardstyle, Russian hip hop\ntrap, hardstyle, Tamil electronic\ntrap, hardstyle, Tamil fusion\ntrap, hardstyle, Tamil pop\ntrap, hardstyle, Turkish hip hop\ntrap, hardstyle, Vietnamese rap\ntrap, hardstyle, ambient\ntrap, hardstyle, auto-tune\ntrap, hardstyle, big room\ntrap, hardstyle, big room house\ntrap, hardstyle, bilingual\ntrap, hardstyle, chiptune\ntrap, hardstyle, cinematic\ntrap, hardstyle, cinematic hip-hop\ntrap, hardstyle, cloud rap\ntrap, hardstyle, dancehall\ntrap, hardstyle, dark electronic\ntrap, hardstyle, dubstep\ntrap, hardstyle, electronic\ntrap, hardstyle, electronic dance music\ntrap, hardstyle, electronic hip-hop\ntrap, hardstyle, ethereal\ntrap, hardstyle, ethnic fusion\ntrap, hardstyle, experimental bass\ntrap, hardstyle, festival\ntrap, hardstyle, festival EDM\ntrap, hardstyle, future bass\ntrap, hardstyle, future pop\ntrap, hardstyle, gabber\ntrap, hardstyle, glitch\ntrap, hardstyle, glitch-hop\ntrap, hardstyle, hardcore\ntrap, hardstyle, hardcore techno\ntrap, hardstyle, hip hop\ntrap, hardstyle, hip-hop\ntrap, hardstyle, hybrid trap\ntrap, hardstyle, hyperpop\ntrap, hardstyle, industrial\ntrap, hardstyle, industrial hip hop\ntrap, hardstyle, jazz\ntrap, hardstyle, jazzy ambient\ntrap, hardstyle, lo-fi\ntrap, hardstyle, lo-fi hip hop\ntrap, hardstyle, melodic rap\ntrap, hardstyle, melodic techno\ntrap, hardstyle, moombahton\ntrap, hardstyle, phonk\ntrap, hardstyle, pop-R&B\ntrap, hardstyle, pop-rap\ntrap, hardstyle, psytrance\ntrap, hardstyle, synth-pop\ntrap, hardstyle, vaporwave\ntrap, hardstyle, world music\ntrap, hardwave\ntrap, hardwave, phonk\ntrap, hardwave, rage\ntrap, harpsichord synth, Mandarin rap\ntrap, harpsichord, Mandarin rap\ntrap, haunted, lo-fi\ntrap, haunted, synthwave\ntrap, hazy, atmospheric\ntrap, hick-hop\ntrap, hindi rap\ntrap, hip hop\ntrap, hip hop, Afro-Latin\ntrap, hip hop, Afrobeat\ntrap, hip hop, Balkan rap\ntrap, hip hop, C-pop\ntrap, hip hop, Chinese hip hop\ntrap, hip hop, Chinese rap\ntrap, hip hop, East Asian fusion\ntrap, hip hop, Gujarati\ntrap, hip hop, Hebrew rap\ntrap, hip hop, Indian\ntrap, hip hop, Indian fusion\ntrap, hip hop, Indian hip hop\ntrap, hip hop, J-pop\ntrap, hip hop, K-pop\ntrap, hip hop, Latin trap\ntrap, hip hop, Mandarin rap\ntrap, hip hop, Middle Eastern\ntrap, hip hop, Punjabi\ntrap, hip hop, R&B\ntrap, hip hop, South Asian\ntrap, hip hop, Spanish\ntrap, hip hop, Spanish-influenced\ntrap, hip hop, Tamil\ntrap, hip hop, Thai fusion\ntrap, hip hop, Turkish\ntrap, hip hop, aggressive\ntrap, hip hop, ambient\ntrap, hip hop, anime\ntrap, hip hop, ballad\ntrap, hip hop, bilingual\ntrap, hip hop, chiptune\ntrap, hip hop, cinematic\ntrap, hip hop, club\ntrap, hip hop, conscious\ntrap, hip hop, dancehall\ntrap, hip hop, dark ambient\ntrap, hip hop, desi\ntrap, hip hop, electronic\ntrap, hip hop, experimental\ntrap, hip hop, future bass\ntrap, hip hop, global fusion\ntrap, hip hop, industrial\ntrap, hip hop, jazz\ntrap, hip hop, jazzy\ntrap, hip hop, live acoustic\ntrap, hip hop, lo-fi\ntrap, hip hop, melodic rap\ntrap, hip hop, multilingual\ntrap, hip hop, orchestral\ntrap, hip hop, political rap\ntrap, hip hop, psychedelic\ntrap, hip hop, reggae\ntrap, hip hop, rock\ntrap, hip hop, soul\ntrap, hip hop, southern rock\ntrap, hip hop, urban\ntrap, hip hop, video game\ntrap, hip hop, world fusion\ntrap, hip-hop\ntrap, hip-hop, Anatolian\ntrap, hip-hop, Anatolian folk\ntrap, hip-hop, Arabic\ntrap, hip-hop, Azerbaijani folk\ntrap, hip-hop, Balkan\ntrap, hip-hop, Balkan fusion\ntrap, hip-hop, C-pop\ntrap, hip-hop, Carnatic\ntrap, hip-hop, Central Asian\ntrap, hip-hop, Central Asian folk\ntrap, hip-hop, Chinese\ntrap, hip-hop, Chinese fusion\ntrap, hip-hop, Chinese hip-hop\ntrap, hip-hop, Chinese opera\ntrap, hip-hop, Chinese rap\ntrap, hip-hop, East Asian\ntrap, hip-hop, East Asian fusion\ntrap, hip-hop, Eastern fusion\ntrap, hip-hop, French Creole\ntrap, hip-hop, G-funk\ntrap, hip-hop, Hebrew rap\ntrap, hip-hop, Indian devotional\ntrap, hip-hop, Indian hip-hop\ntrap, hip-hop, Indian pop\ntrap, hip-hop, Irish mythology\ntrap, hip-hop, Japanese traditional\ntrap, hip-hop, Japanese-inspired\ntrap, hip-hop, Korean rap\ntrap, hip-hop, Latin\ntrap, hip-hop, Latin pop\ntrap, hip-hop, Mandarin rap\ntrap, hip-hop, Middle Eastern\ntrap, hip-hop, Middle Eastern fusion\ntrap, hip-hop, Māori\ntrap, hip-hop, North African\ntrap, hip-hop, Punjabi\ntrap, hip-hop, Punjabi hip-hop\ntrap, hip-hop, R&B\ntrap, hip-hop, Rai\ntrap, hip-hop, South Asian\ntrap, hip-hop, South Asian fusion\ntrap, hip-hop, South Asian pop\ntrap, hip-hop, South Indian\ntrap, hip-hop, Tamil folk\ntrap, hip-hop, Tamil rap\ntrap, hip-hop, Turkish folk\ntrap, hip-hop, West African\ntrap, hip-hop, afro-fusion\ntrap, hip-hop, ambient\ntrap, hip-hop, ancient style\ntrap, hip-hop, atmospheric\ntrap, hip-hop, atmospheric electronic\ntrap, hip-hop, atmospheric pop\ntrap, hip-hop, atmospheric world music\ntrap, hip-hop, ballroom\ntrap, hip-hop, chiptune\ntrap, hip-hop, choral\ntrap, hip-hop, cinematic\ntrap, hip-hop, classical\ntrap, hip-hop, dancehall\ntrap, hip-hop, dark electronic\ntrap, hip-hop, electronic\ntrap, hip-hop, electronic pop\ntrap, hip-hop, experimental electronic\ntrap, hip-hop, fusion\ntrap, hip-hop, futuristic\ntrap, hip-hop, gospel\ntrap, hip-hop, hard dance\ntrap, hip-hop, hyperpop\ntrap, hip-hop, industrial\ntrap, hip-hop, jazz rap\ntrap, hip-hop, lo-fi\ntrap, hip-hop, melodic\ntrap, hip-hop, melodic trap\ntrap, hip-hop, multilingual\ntrap, hip-hop, neo-soul\ntrap, hip-hop, political\ntrap, hip-hop, pop\ntrap, hip-hop, pop-R&B\ntrap, hip-hop, psychedelic\ntrap, hip-hop, reggaeton\ntrap, hip-hop, regional Mexican\ntrap, hip-hop, rock\ntrap, hip-hop, soul\ntrap, hip-hop, spiritual\ntrap, hip-hop, surf-rock\ntrap, hip-hop, synth pop\ntrap, hip-hop, synthwave\ntrap, hip-hop, traditional Central Asian\ntrap, hip-hop, traditional East Asian\ntrap, hip-hop, traditional fusion\ntrap, hip-hop, vaporwave\ntrap, hip-hop, witch house\ntrap, hip-hop, world fusion\ntrap, hip-hop, world music\ntrap, hip-hop, world percussion\ntrap, hip-house\ntrap, hip-house, funk carioca\ntrap, holiday hip-hop\ntrap, holiday, electronic\ntrap, holiday, hip hop\ntrap, horror ambient\ntrap, horror game\ntrap, horror game, synthwave\ntrap, horror synth\ntrap, horror, cinematic\ntrap, horror, electronic\ntrap, horrorcore\ntrap, horrorcore, Arabic hip hop\ntrap, horrorcore, Chinese hip hop\ntrap, horrorcore, German gangsta rap\ntrap, horrorcore, German party-rap\ntrap, horrorcore, R&B\ntrap, horrorcore, UK drill\ntrap, horrorcore, ambient\ntrap, horrorcore, ambient hip-hop\ntrap, horrorcore, chiptune\ntrap, horrorcore, cinematic\ntrap, horrorcore, cinematic hip hop\ntrap, horrorcore, cinematic hip-hop\ntrap, horrorcore, dark wave\ntrap, horrorcore, experimental hip-hop\ntrap, horrorcore, gangsta rap\ntrap, horrorcore, industrial\ntrap, horrorcore, lo-fi\ntrap, horrorcore, orchestral\ntrap, horrorcore, phonk\ntrap, horrorcore, psychedelic\ntrap, horrorcore, synthwave\ntrap, horrorcore, underground hip-hop\ntrap, horrorcore, vaporwave\ntrap, hyper-trap\ntrap, hyper-trap, Middle Eastern\ntrap, hyper-trap, lo-fi hip hop\ntrap, hyperpop\ntrap, hyperpop, Arabic\ntrap, hyperpop, Balkan pop\ntrap, hyperpop, Balkan rap\ntrap, hyperpop, Brazilian funk\ntrap, hyperpop, C-pop\ntrap, hyperpop, Chinese hip hop\ntrap, hyperpop, Chinese hip-hop\ntrap, hyperpop, Chinese pop\ntrap, hyperpop, EDM\ntrap, hyperpop, East Asian fusion\ntrap, hyperpop, French rap\ntrap, hyperpop, Italian trap\ntrap, hyperpop, J-pop\ntrap, hyperpop, Japanese hip-hop\ntrap, hyperpop, K-hip-hop\ntrap, hyperpop, K-pop\ntrap, hyperpop, Latin\ntrap, hyperpop, Latin rap\ntrap, hyperpop, Mandarin rap\ntrap, hyperpop, Portuguese rap\ntrap, hyperpop, R&B\ntrap, hyperpop, Russian folk\ntrap, hyperpop, Spanish rap\ntrap, hyperpop, Turkish pop\ntrap, hyperpop, UK rap\ntrap, hyperpop, alternative R&B\ntrap, hyperpop, alternative pop\ntrap, hyperpop, ambient\ntrap, hyperpop, baroque\ntrap, hyperpop, bilingual\ntrap, hyperpop, bilingual rap\ntrap, hyperpop, chiptune\ntrap, hyperpop, chopped and screwed\ntrap, hyperpop, cinematic\ntrap, hyperpop, cinematic, hip-hop\ntrap, hyperpop, circuscore\ntrap, hyperpop, cloud rap\ntrap, hyperpop, dancehall\ntrap, hyperpop, dark pop\ntrap, hyperpop, dreamy\ntrap, hyperpop, electronic\ntrap, hyperpop, electronic pop\ntrap, hyperpop, electronic rock\ntrap, hyperpop, electronicore\ntrap, hyperpop, emo rap\ntrap, hyperpop, emo-rap\ntrap, hyperpop, experimental\ntrap, hyperpop, experimental R&B\ntrap, hyperpop, experimental electronic\ntrap, hyperpop, festive\ntrap, hyperpop, glitch-hop\ntrap, hyperpop, glitch-pop\ntrap, hyperpop, glitchcore\ntrap, hyperpop, global bass\ntrap, hyperpop, gospel\ntrap, hyperpop, hardstyle\ntrap, hyperpop, industrial\ntrap, hyperpop, lo-fi\ntrap, hyperpop, lo-fi hip hop\ntrap, hyperpop, medieval\ntrap, hyperpop, melodic\ntrap, hyperpop, melodic rap\ntrap, hyperpop, meme music\ntrap, hyperpop, metalcore\ntrap, hyperpop, nerdcore\ntrap, hyperpop, nightcore\ntrap, hyperpop, pluggnb\ntrap, hyperpop, pop-rap\ntrap, hyperpop, psychedelic\ntrap, hyperpop, rage\ntrap, hyperpop, rage music\ntrap, hyperpop, rap-rock\ntrap, hyperpop, reggaeton\ntrap, hyperpop, ritualistic\ntrap, hyperpop, synth-pop\ntrap, hyperpop, synthwave\ntrap, hyperpop, video game music\ntrap, hyperpop, witch house\ntrap, hypnotic, Middle Eastern\ntrap, indie folk\ntrap, indie folk, Hebrew vocal\ntrap, indie folk, Hindi hip hop\ntrap, indie pop\ntrap, indie pop, Indian hip hop\ntrap, indie rock\ntrap, indie rock, Middle Eastern\ntrap, indie rock, lo-fi\ntrap, indie rock, lo-fi hip hop\ntrap, indie, Hindi\ntrap, indie-pop\ntrap, indie-pop, experimental\ntrap, industrial\ntrap, industrial hip hop\ntrap, industrial hip-hop\ntrap, industrial hip-hop, cyberpunk\ntrap, industrial hip-hop, electronic\ntrap, industrial hip-hop, vaporwave\ntrap, industrial metal\ntrap, industrial pop\ntrap, industrial rock\ntrap, industrial rock, emotional\ntrap, industrial rock, lo-fi\ntrap, industrial, Bollywood\ntrap, industrial, C-pop\ntrap, industrial, Chinese hip hop\ntrap, industrial, Czech hip hop\ntrap, industrial, French rap\ntrap, industrial, Italian rap\ntrap, industrial, K-pop\ntrap, industrial, R&B\ntrap, industrial, Russian hip hop\ntrap, industrial, Russian rap\ntrap, industrial, Spanish rap\ntrap, industrial, Turkish hip hop\ntrap, industrial, ambient\ntrap, industrial, cinematic\ntrap, industrial, cyberpunk\ntrap, industrial, dark\ntrap, industrial, dystopian\ntrap, industrial, electronic\ntrap, industrial, experimental\ntrap, industrial, experimental electronic\ntrap, industrial, experimental hip-hop\ntrap, industrial, experimental pop\ntrap, industrial, glitch\ntrap, industrial, glitch-hop\ntrap, industrial, gospel R&B\ntrap, industrial, hardcore techno\ntrap, industrial, hardstyle\ntrap, industrial, lo-fi\ntrap, industrial, rock\ntrap, instrumental\ntrap, instrumental, Middle Eastern\ntrap, instrumental, cinematic\ntrap, instrumental, ethnic fusion\ntrap, instrumental, oud\ntrap, instrumental, world fusion\ntrap, internet culture, lo-fi\ntrap, island, lo-fi\ntrap, jazz fusion\ntrap, jazz hip hop\ntrap, jazz hip-hop\ntrap, jazz hip-hop, ambient\ntrap, jazz hop\ntrap, jazz noir\ntrap, jazz noir, Chinese hip hop\ntrap, jazz rap\ntrap, jazz, Brazilian\ntrap, jazz, C-pop\ntrap, jazz, Chinese hip hop\ntrap, jazz, Chinese opera\ntrap, jazz, Dutch hip hop\ntrap, jazz, French hip hop\ntrap, jazz, Hebrew rap\ntrap, jazz, Italian hip hop\ntrap, jazz, Khmer hip hop\ntrap, jazz, Latin\ntrap, jazz, Mediterranean\ntrap, jazz, R&B\ntrap, jazz, Romanian hip hop\ntrap, jazz, Russian hip hop\ntrap, jazz, Vietnamese hip hop\ntrap, jazz, blues\ntrap, jazz, cinematic\ntrap, jazz, educational\ntrap, jazz, electronic\ntrap, jazz, hip hop\ntrap, jazz, hip-hop\ntrap, jazz, k-pop\ntrap, jazz, lo-fi\ntrap, jazz, lo-fi hip hop\ntrap, jazz, melancholic\ntrap, jazz, noir\ntrap, jazz, psychedelic\ntrap, jazz, soul\ntrap, jazz-funk, hip-hop\ntrap, jazz-trap\ntrap, jazzy hip hop\ntrap, jazzy hip-hop\ntrap, jazzy hip-hop, cinematic rock\ntrap, jazzy trap\ntrap, jazzy, Chinese hip hop\ntrap, jazzy, Mandarin rap\ntrap, jazzy, atmospheric\ntrap, jazzy, confident\ntrap, jazzy, electronic\ntrap, jazzy, lo-fi\ntrap, jazzy, melancholic\ntrap, jazzy, modern\ntrap, jazzy, pluggnb\ntrap, jersey club\ntrap, k-pop\ntrap, k-pop, chiptune\ntrap, k-pop, cinematic\ntrap, k-pop, electronic\ntrap, k-pop, experimental\ntrap, k-pop, hip hop\ntrap, kalimba, hip hop\ntrap, kawaii\ntrap, kawaii-core\ntrap, klezmer\ntrap, klezmer, Arabic hip hop\ntrap, klezmer, C-pop\ntrap, klezmer, Finnish hip hop\ntrap, klezmer, French hip hop\ntrap, klezmer, Latin hip hop\ntrap, klezmer, Polish hip hop\ntrap, klezmer, Swahili rap\ntrap, klezmer, cinematic\ntrap, klezmer, electronic\ntrap, klezmer, hip hop\ntrap, klezmer, hip-hop\ntrap, klezmer, jazz\ntrap, klezmer, lo-fi\ntrap, klezmer, lo-fi hip hop\ntrap, klezmer, soul\ntrap, koplo, pop\ntrap, korean hip hop\ntrap, korean traditional\ntrap, koto, Russian rap\ntrap, koto, cinematic hip-hop\ntrap, koto, exotic\ntrap, koto, hip-hop\ntrap, koto-influenced\ntrap, kuthu, electronic\ntrap, kuthu, fusion\ntrap, kuthu, gaana\ntrap, kuthu, indian fusion\ntrap, latin hip hop\ntrap, latin trap\ntrap, lo-fi\ntrap, lo-fi R&B\ntrap, lo-fi R&B, C-pop\ntrap, lo-fi R&B, Chinese hip hop\ntrap, lo-fi R&B, atmospheric hip-hop\ntrap, lo-fi chiptune\ntrap, lo-fi hip hop\ntrap, lo-fi hip hop, Afro-trap\ntrap, lo-fi hip hop, Arabic pop\ntrap, lo-fi hip hop, Arabic rap\ntrap, lo-fi hip hop, Asian fusion\ntrap, lo-fi hip hop, Bengali folk\ntrap, lo-fi hip hop, Brazilian\ntrap, lo-fi hip hop, Brazilian funk\ntrap, lo-fi hip hop, Brazilian trap\ntrap, lo-fi hip hop, C-pop\ntrap, lo-fi hip hop, Chinese\ntrap, lo-fi hip hop, Chinese R&B\ntrap, lo-fi hip hop, Chinese ambient\ntrap, lo-fi hip hop, Chinese cinematic\ntrap, lo-fi hip hop, Chinese electronic\ntrap, lo-fi hip hop, Chinese folk\ntrap, lo-fi hip hop, Chinese fusion\ntrap, lo-fi hip hop, Chinese gangster\ntrap, lo-fi hip hop, Chinese hip hop\ntrap, lo-fi hip hop, Chinese indie\ntrap, lo-fi hip hop, Chinese opera\ntrap, lo-fi hip hop, Chinese pop\ntrap, lo-fi hip hop, Chinese rap\ntrap, lo-fi hip hop, Chinese soul\ntrap, lo-fi hip hop, Chinese underground\ntrap, lo-fi hip hop, Chinese vaporwave\ntrap, lo-fi hip hop, Czech rap\ntrap, lo-fi hip hop, Deutschrap\ntrap, lo-fi hip hop, Dutch drill\ntrap, lo-fi hip hop, Dutch rap\ntrap, lo-fi hip hop, Dutch trap\ntrap, lo-fi hip hop, Eastern European\ntrap, lo-fi hip hop, Eastern fusion\ntrap, lo-fi hip hop, Filipino rap\ntrap, lo-fi hip hop, French rap\ntrap, lo-fi hip hop, German rap\ntrap, lo-fi hip hop, Greek rap\ntrap, lo-fi hip hop, Hebrew rap\ntrap, lo-fi hip hop, Hungarian rap\ntrap, lo-fi hip hop, Indian fusion\ntrap, lo-fi hip hop, Indian hip hop\ntrap, lo-fi hip hop, Indian pop\ntrap, lo-fi hip hop, Indonesian rap\ntrap, lo-fi hip hop, Italian\ntrap, lo-fi hip hop, Italian rap\ntrap, lo-fi hip hop, K-pop\ntrap, lo-fi hip hop, K-rap\ntrap, lo-fi hip hop, Korean rap\ntrap, lo-fi hip hop, Latin pop\ntrap, lo-fi hip hop, Latin rap\ntrap, lo-fi hip hop, Mandarin rap\ntrap, lo-fi hip hop, Middle Eastern\ntrap, lo-fi hip hop, Middle Eastern fusion\ntrap, lo-fi hip hop, Moroccan Arabic\ntrap, lo-fi hip hop, Moroccan Arabic rap\ntrap, lo-fi hip hop, Nepali rap\ntrap, lo-fi hip hop, Nordic\ntrap, lo-fi hip hop, North African hip-hop\ntrap, lo-fi hip hop, Persian rap\ntrap, lo-fi hip hop, Polish rap\ntrap, lo-fi hip hop, Portuguese rap\ntrap, lo-fi hip hop, Punjabi\ntrap, lo-fi hip hop, Punjabi fusion\ntrap, lo-fi hip hop, Punjabi hip hop\ntrap, lo-fi hip hop, Punjabi hip-hop\ntrap, lo-fi hip hop, Punjabi rap\ntrap, lo-fi hip hop, R&B\ntrap, lo-fi hip hop, Russian pop\ntrap, lo-fi hip hop, Russian rap\ntrap, lo-fi hip hop, South Asian\ntrap, lo-fi hip hop, South Asian fusion\ntrap, lo-fi hip hop, Southeast Asian\ntrap, lo-fi hip hop, Southern rap\ntrap, lo-fi hip hop, Spanish flavor\ntrap, lo-fi hip hop, Spanish-flavored\ntrap, lo-fi hip hop, Turkish folk\ntrap, lo-fi hip hop, Turkish rap\ntrap, lo-fi hip hop, UK drill\ntrap, lo-fi hip hop, Vietnamese fusion\ntrap, lo-fi hip hop, ambient\ntrap, lo-fi hip hop, ambient pop\ntrap, lo-fi hip hop, anime\ntrap, lo-fi hip hop, atmospheric\ntrap, lo-fi hip hop, big band\ntrap, lo-fi hip hop, bilingual\ntrap, lo-fi hip hop, bilingual rap\ntrap, lo-fi hip hop, blues\ntrap, lo-fi hip hop, blues rock\ntrap, lo-fi hip hop, boom-bap\ntrap, lo-fi hip hop, chillwave\ntrap, lo-fi hip hop, chiptune\ntrap, lo-fi hip hop, cinematic\ntrap, lo-fi hip hop, cinematic ambient\ntrap, lo-fi hip hop, cinematic rap\ntrap, lo-fi hip hop, city pop\ntrap, lo-fi hip hop, cloud rap\ntrap, lo-fi hip hop, dancehall\ntrap, lo-fi hip hop, dark ambient\ntrap, lo-fi hip hop, dream pop\ntrap, lo-fi hip hop, drill\ntrap, lo-fi hip hop, electronic\ntrap, lo-fi hip hop, emo rap\ntrap, lo-fi hip hop, emotional\ntrap, lo-fi hip hop, emotional rap\ntrap, lo-fi hip hop, ethereal\ntrap, lo-fi hip hop, ethnic\ntrap, lo-fi hip hop, experimental\ntrap, lo-fi hip hop, folk\ntrap, lo-fi hip hop, global pop\ntrap, lo-fi hip hop, gospel\ntrap, lo-fi hip hop, hyperpop\ntrap, lo-fi hip hop, introspective\ntrap, lo-fi hip hop, jazz\ntrap, lo-fi hip hop, jazz rap\ntrap, lo-fi hip hop, melancholic\ntrap, lo-fi hip hop, melodic rap\ntrap, lo-fi hip hop, mumble rap\ntrap, lo-fi hip hop, mystical\ntrap, lo-fi hip hop, pluggnb\ntrap, lo-fi hip hop, political rap\ntrap, lo-fi hip hop, pop\ntrap, lo-fi hip hop, psychedelic\ntrap, lo-fi hip hop, reggaeton\ntrap, lo-fi hip hop, retro video game\ntrap, lo-fi hip hop, soul\ntrap, lo-fi hip hop, spoken word\ntrap, lo-fi hip hop, synthwave\ntrap, lo-fi hip hop, underground hip hop\ntrap, lo-fi hip hop, vaporwave\ntrap, lo-fi hip hop, video game\ntrap, lo-fi hip hop, world music\ntrap, lo-fi hip-hop\ntrap, lo-fi hip-hop, Punjabi devotional\ntrap, lo-fi hip-hop, R&B\ntrap, lo-fi hip-hop, ambient\ntrap, lo-fi hip-hop, ambient rock\ntrap, lo-fi hip-hop, cloud rap\ntrap, lo-fi hip-hop, emo rap\ntrap, lo-fi hip-hop, gospel rap\ntrap, lo-fi jazz, Chinese hip hop\ntrap, lo-fi jazz, Russian rap\ntrap, lo-fi orchestral\ntrap, lo-fi piano\ntrap, lo-fi soul\ntrap, lo-fi synth\ntrap, lo-fi, 8-bit\ntrap, lo-fi, African choral\ntrap, lo-fi, African hip hop\ntrap, lo-fi, Afrikaans hip hop\ntrap, lo-fi, Afro trap\ntrap, lo-fi, Afro-hip hop\ntrap, lo-fi, Afro-trap\ntrap, lo-fi, Afrobeat\ntrap, lo-fi, Anatolian hip hop\ntrap, lo-fi, Arabic\ntrap, lo-fi, Arabic fusion\ntrap, lo-fi, Arabic hip hop\ntrap, lo-fi, Arabic melodic rap\ntrap, lo-fi, Arabic rap\ntrap, lo-fi, Arabic soul\ntrap, lo-fi, Arabic vocal\ntrap, lo-fi, Asian ambient\ntrap, lo-fi, Asian fusion\ntrap, lo-fi, Australian\ntrap, lo-fi, Balkan\ntrap, lo-fi, Bantu hip hop\ntrap, lo-fi, Bengali hip hop\ntrap, lo-fi, Brazilian\ntrap, lo-fi, Brazilian hip hop\ntrap, lo-fi, Bulgarian hip hop\ntrap, lo-fi, C-pop\ntrap, lo-fi, Cantonese hip hop\ntrap, lo-fi, Chinese\ntrap, lo-fi, Chinese ambient\ntrap, lo-fi, Chinese electronic\ntrap, lo-fi, Chinese experimental\ntrap, lo-fi, Chinese fusion\ntrap, lo-fi, Chinese hip hop\ntrap, lo-fi, Chinese hip-hop\ntrap, lo-fi, Chinese pop\ntrap, lo-fi, Chinese rap\ntrap, lo-fi, Chinese traditional\ntrap, lo-fi, Chinese zither\ntrap, lo-fi, Czech hip hop\ntrap, lo-fi, Czech rap\ntrap, lo-fi, Danish hip hop\ntrap, lo-fi, Dutch hip hop\ntrap, lo-fi, Dutch rap\ntrap, lo-fi, East Asian\ntrap, lo-fi, East Asian fusion\ntrap, lo-fi, Eastern European\ntrap, lo-fi, Eastern ambient\ntrap, lo-fi, Eastern fusion\ntrap, lo-fi, Eastern influence\ntrap, lo-fi, Eastern tonality\ntrap, lo-fi, Estonian hip hop\ntrap, lo-fi, Filipino hip hop\ntrap, lo-fi, Finnish\ntrap, lo-fi, Finnish hip hop\ntrap, lo-fi, Finnish rap\ntrap, lo-fi, French Creole\ntrap, lo-fi, French Creole hip hop\ntrap, lo-fi, French hip hop\ntrap, lo-fi, French rap\ntrap, lo-fi, G-funk\ntrap, lo-fi, German hip hop\ntrap, lo-fi, German pop\ntrap, lo-fi, German rap\ntrap, lo-fi, Greek\ntrap, lo-fi, Greek hip hop\ntrap, lo-fi, Greek melodic rap\ntrap, lo-fi, Greek rap\ntrap, lo-fi, Greek soul\ntrap, lo-fi, Haitian Creole\ntrap, lo-fi, Haitian Creole rap\ntrap, lo-fi, Haryanvi hip hop\ntrap, lo-fi, Hausa rap\ntrap, lo-fi, Hebrew rap\ntrap, lo-fi, Hindi hip hop\ntrap, lo-fi, Hungarian hip hop\ntrap, lo-fi, Hungarian rap\ntrap, lo-fi, Indian fusion\ntrap, lo-fi, Indian hip hop\ntrap, lo-fi, Indonesian hip hop\ntrap, lo-fi, Indonesian pop\ntrap, lo-fi, Italian\ntrap, lo-fi, Italian hip hop\ntrap, lo-fi, Italian rap\ntrap, lo-fi, J-pop\ntrap, lo-fi, Jamaican Patois\ntrap, lo-fi, Jamaican Patois rap\ntrap, lo-fi, Japanese cinematic\ntrap, lo-fi, Japanese hip hop\ntrap, lo-fi, Japanese vocal\ntrap, lo-fi, K-pop\ntrap, lo-fi, Kazakh hip hop\ntrap, lo-fi, Khmer hip hop\ntrap, lo-fi, Korean hip hop\ntrap, lo-fi, Latin\ntrap, lo-fi, Latin hip hop\ntrap, lo-fi, Latvian rap\ntrap, lo-fi, Malay hip hop\ntrap, lo-fi, Malayalam hip hop\ntrap, lo-fi, Mandarin\ntrap, lo-fi, Mandarin emo\ntrap, lo-fi, Mandarin hip hop\ntrap, lo-fi, Mandarin hip-hop\ntrap, lo-fi, Mandarin pop\ntrap, lo-fi, Mandarin rap\ntrap, lo-fi, Marathi hip hop\ntrap, lo-fi, Middle Eastern\ntrap, lo-fi, Middle Eastern fusion\ntrap, lo-fi, Mongolian\ntrap, lo-fi, Mongolian hip hop\ntrap, lo-fi, Moroccan Arabic\ntrap, lo-fi, Moroccan hip hop\ntrap, lo-fi, Nepali hip hop\ntrap, lo-fi, Nigerian Pidgin\ntrap, lo-fi, Nigerian Pidgin rap\ntrap, lo-fi, Nordic\ntrap, lo-fi, Nordic hip hop\ntrap, lo-fi, North African\ntrap, lo-fi, North African fusion\ntrap, lo-fi, Papiamento hip hop\ntrap, lo-fi, Persian\ntrap, lo-fi, Persian hip hop\ntrap, lo-fi, Persian rap\ntrap, lo-fi, Pinoy hip hop\ntrap, lo-fi, Polish\ntrap, lo-fi, Polish hip hop\ntrap, lo-fi, Polish pop\ntrap, lo-fi, Polish rap\ntrap, lo-fi, Portuguese\ntrap, lo-fi, Portuguese folk\ntrap, lo-fi, Portuguese hip hop\ntrap, lo-fi, Portuguese rap\ntrap, lo-fi, Punjabi\ntrap, lo-fi, Punjabi hip hop\ntrap, lo-fi, Punjabi hip-hop\ntrap, lo-fi, Punjabi pop\ntrap, lo-fi, R&B\ntrap, lo-fi, Romanian\ntrap, lo-fi, Romanian hip hop\ntrap, lo-fi, Romanian rap\ntrap, lo-fi, Russian\ntrap, lo-fi, Russian hip hop\ntrap, lo-fi, Russian hip-hop\ntrap, lo-fi, Russian pop\ntrap, lo-fi, Russian rap\ntrap, lo-fi, Russian vocal\ntrap, lo-fi, Sinhala pop\ntrap, lo-fi, Slovak hip hop\ntrap, lo-fi, Slovak rap\ntrap, lo-fi, South Asian\ntrap, lo-fi, South Asian fusion\ntrap, lo-fi, Southern hip hop\ntrap, lo-fi, Spanish\ntrap, lo-fi, Spanish flavor\ntrap, lo-fi, Spanish guitar\ntrap, lo-fi, Spanish hip hop\ntrap, lo-fi, Spanish rap\ntrap, lo-fi, Spanish-style\ntrap, lo-fi, Swedish hip hop\ntrap, lo-fi, Swedish melodic rap\ntrap, lo-fi, Swedish pop\ntrap, lo-fi, Swedish rap\ntrap, lo-fi, Tamil hip hop\ntrap, lo-fi, Tamil pop\ntrap, lo-fi, Thai hip hop\ntrap, lo-fi, Turkish\ntrap, lo-fi, Turkish classical\ntrap, lo-fi, Turkish hip hop\ntrap, lo-fi, Turkish pop\ntrap, lo-fi, Turkish rap\ntrap, lo-fi, UK drill\ntrap, lo-fi, UK rap\ntrap, lo-fi, Ukrainian\ntrap, lo-fi, Ukrainian hip hop\ntrap, lo-fi, Ukrainian rap\ntrap, lo-fi, Vietnamese hip hop\ntrap, lo-fi, Vietnamese hip-hop\ntrap, lo-fi, West Coast\ntrap, lo-fi, abrasive\ntrap, lo-fi, afrobeats\ntrap, lo-fi, aggressive\ntrap, lo-fi, ambient\ntrap, lo-fi, ancient style\ntrap, lo-fi, anime\ntrap, lo-fi, atmospheric\ntrap, lo-fi, auto-tune\ntrap, lo-fi, baroque\ntrap, lo-fi, bilingual\ntrap, lo-fi, bilingual hip hop\ntrap, lo-fi, bilingual rap\ntrap, lo-fi, boom-bap\ntrap, lo-fi, brass\ntrap, lo-fi, charango\ntrap, lo-fi, chillwave\ntrap, lo-fi, chiptune\ntrap, lo-fi, chopped and screwed\ntrap, lo-fi, choral\ntrap, lo-fi, cinematic\ntrap, lo-fi, classical\ntrap, lo-fi, cloud rap\ntrap, lo-fi, comedic hip hop\ntrap, lo-fi, cyberpunk\ntrap, lo-fi, dancehall\ntrap, lo-fi, danish rap\ntrap, lo-fi, dark\ntrap, lo-fi, dark ambient\ntrap, lo-fi, dark hip hop\ntrap, lo-fi, dark pop\ntrap, lo-fi, dark synth\ntrap, lo-fi, dark trap\ntrap, lo-fi, distorted\ntrap, lo-fi, dream pop\ntrap, lo-fi, dreamy\ntrap, lo-fi, drill\ntrap, lo-fi, drum and bass\ntrap, lo-fi, dubstep\ntrap, lo-fi, dystopian\ntrap, lo-fi, electronic\ntrap, lo-fi, emo rap\ntrap, lo-fi, emo-rap\ntrap, lo-fi, emotional\ntrap, lo-fi, emotional rap\ntrap, lo-fi, ethereal\ntrap, lo-fi, ethnic fusion\ntrap, lo-fi, experimental\ntrap, lo-fi, festive\ntrap, lo-fi, flamenco\ntrap, lo-fi, folk\ntrap, lo-fi, gaming\ntrap, lo-fi, glitch\ntrap, lo-fi, gospel\ntrap, lo-fi, gothic\ntrap, lo-fi, hazy\ntrap, lo-fi, hip hop\ntrap, lo-fi, horrorcore\ntrap, lo-fi, hyper-trap\ntrap, lo-fi, hyperpop\ntrap, lo-fi, industrial\ntrap, lo-fi, international\ntrap, lo-fi, introspective\ntrap, lo-fi, jazz\ntrap, lo-fi, jazz hop\ntrap, lo-fi, jazzy\ntrap, lo-fi, k-pop\ntrap, lo-fi, medieval\ntrap, lo-fi, melancholic\ntrap, lo-fi, melodic\ntrap, lo-fi, melodic rap\ntrap, lo-fi, melodic trap\ntrap, lo-fi, meme\ntrap, lo-fi, meme rap\ntrap, lo-fi, minimalist\ntrap, lo-fi, modern\ntrap, lo-fi, multi-lingual\ntrap, lo-fi, multilingual hip hop\ntrap, lo-fi, noise rock\ntrap, lo-fi, nostalgic\ntrap, lo-fi, novelty\ntrap, lo-fi, orchestral\ntrap, lo-fi, oriental\ntrap, lo-fi, pluggnb\ntrap, lo-fi, pop\ntrap, lo-fi, pop-punk\ntrap, lo-fi, psychedelic\ntrap, lo-fi, ragtime\ntrap, lo-fi, reggae\ntrap, lo-fi, reggaeton\ntrap, lo-fi, regional Mexican\ntrap, lo-fi, retro\ntrap, lo-fi, rock\ntrap, lo-fi, romantic\ntrap, lo-fi, slowed + reverb\ntrap, lo-fi, soul\ntrap, lo-fi, soulful\ntrap, lo-fi, spiritual\ntrap, lo-fi, spoken word\ntrap, lo-fi, summer\ntrap, lo-fi, synth\ntrap, lo-fi, synthwave\ntrap, lo-fi, traditional East Asian\ntrap, lo-fi, traditional fusion\ntrap, lo-fi, tropical\ntrap, lo-fi, underground\ntrap, lo-fi, vaporwave\ntrap, lo-fi, video game\ntrap, lo-fi, whimsical\ntrap, lo-fi, world fusion\ntrap, lo-fi, world music\ntrap, luxury rap\ntrap, mahraganat\ntrap, mandarin hip-hop, ambient\ntrap, mandarin rap, atmospheric\ntrap, mandolin, Balkan\ntrap, mandolin, Chinese\ntrap, mandolin, Chinese hip hop\ntrap, mandolin, medieval\ntrap, mandopop\ntrap, mandopop, lo-fi\ntrap, mandopop, r&b\ntrap, manele\ntrap, manele, electronic\ntrap, mariachi, hip hop\ntrap, medieval\ntrap, medieval folk, fantasy\ntrap, medieval hip hop\ntrap, medieval synth\ntrap, medieval, Chinese hip hop\ntrap, medieval, Dutch hip hop\ntrap, medieval, French rap\ntrap, medieval, Middle Eastern\ntrap, medieval, bilingual\ntrap, medieval, hip hop\ntrap, medieval, lo-fi\ntrap, melancholic\ntrap, melancholic hip-hop\ntrap, melancholic piano\ntrap, melancholic rap\ntrap, melancholic synth\ntrap, melancholic, Anatolian\ntrap, melancholic, Arabic\ntrap, melancholic, Arabic hip hop\ntrap, melancholic, Arabic hip-hop\ntrap, melancholic, Arabic melodic rap\ntrap, melancholic, Arabic rap\ntrap, melancholic, Arabic soul\ntrap, melancholic, Arabic vocal\ntrap, melancholic, Asian ambient\ntrap, melancholic, Balkan\ntrap, melancholic, Balkan folk\ntrap, melancholic, Bengali\ntrap, melancholic, C-pop\ntrap, melancholic, Central Asian\ntrap, melancholic, Chinese\ntrap, melancholic, Chinese ambient\ntrap, melancholic, Chinese hip hop\ntrap, melancholic, Chinese hip-hop\ntrap, melancholic, Chinese rap\ntrap, melancholic, Chinese traditional\ntrap, melancholic, Dutch hip hop\ntrap, melancholic, Dutch rap\ntrap, melancholic, East Asian\ntrap, melancholic, Eastern European\ntrap, melancholic, Eastern flavor\ntrap, melancholic, Eastern-influenced\ntrap, melancholic, French rap\ntrap, melancholic, German hip hop\ntrap, melancholic, German rap\ntrap, melancholic, Haitian Creole\ntrap, melancholic, Hindi\ntrap, melancholic, Hindi hip hop\ntrap, melancholic, Hindi hip-hop\ntrap, melancholic, Hindi rap\ntrap, melancholic, Hindi soul\ntrap, melancholic, Hungarian rap\ntrap, melancholic, Indian hip hop\ntrap, melancholic, Italian\ntrap, melancholic, Italian hip hop\ntrap, melancholic, Italian hip-hop\ntrap, melancholic, Italian rap\ntrap, melancholic, Mandarin hip hop\ntrap, melancholic, Mandarin hip-hop\ntrap, melancholic, Mandarin rap\ntrap, melancholic, Middle Eastern\ntrap, melancholic, Middle Eastern fusion\ntrap, melancholic, Moroccan Arabic\ntrap, melancholic, Neapolitan\ntrap, melancholic, Neapolitan rap\ntrap, melancholic, North African\ntrap, melancholic, Persian\ntrap, melancholic, Persian soul\ntrap, melancholic, Polish hip hop\ntrap, melancholic, Punjabi\ntrap, melancholic, Punjabi hip hop\ntrap, melancholic, Punjabi hip-hop\ntrap, melancholic, Punjabi pop\ntrap, melancholic, Punjabi rap\ntrap, melancholic, R&B\ntrap, melancholic, Russian\ntrap, melancholic, Russian rap\ntrap, melancholic, Sichuanese hip hop\ntrap, melancholic, Sinhala\ntrap, melancholic, Sinhala vocal\ntrap, melancholic, Slovak rap\ntrap, melancholic, South Asian\ntrap, melancholic, Spanish\ntrap, melancholic, Swedish hip hop\ntrap, melancholic, Thai hip hop\ntrap, melancholic, Turkish\ntrap, melancholic, Turkish folk\ntrap, melancholic, Turkish hip hop\ntrap, melancholic, Turkish pop\ntrap, melancholic, Turkish rap\ntrap, melancholic, Urdu rap\ntrap, melancholic, ambient\ntrap, melancholic, atmospheric\ntrap, melancholic, auto-tuned rap\ntrap, melancholic, bilingual\ntrap, melancholic, cello\ntrap, melancholic, chiptune\ntrap, melancholic, cinematic\ntrap, melancholic, electronic\ntrap, melancholic, erhu\ntrap, melancholic, ethnic\ntrap, melancholic, folk\ntrap, melancholic, hip hop\ntrap, melancholic, jazzy\ntrap, melancholic, lo-fi\ntrap, melancholic, medieval\ntrap, melancholic, modern\ntrap, melancholic, multilingual\ntrap, melancholic, phonk\ntrap, melancholic, soulful\ntrap, melancholic, world music\ntrap, melodic R&B\ntrap, melodic R&B, hip-hop\ntrap, melodic hip hop\ntrap, melodic hip hop, emotional pop\ntrap, melodic hip-hop\ntrap, melodic rap\ntrap, melodic rap, Arabic electronic\ntrap, melodic rap, Balkan fusion\ntrap, melodic rap, Balkan hip hop\ntrap, melodic rap, Bollywood fusion\ntrap, melodic rap, C-pop\ntrap, melodic rap, Chinese\ntrap, melodic rap, Chinese hip hop\ntrap, melodic rap, Chinese pop\ntrap, melodic rap, Dutch\ntrap, melodic rap, Dutch hip hop\ntrap, melodic rap, Eastern influence\ntrap, melodic rap, French\ntrap, melodic rap, French hip hop\ntrap, melodic rap, German hip hop\ntrap, melodic rap, Hebrew hip hop\ntrap, melodic rap, Indian hip hop\ntrap, melodic rap, Italian\ntrap, melodic rap, Latin\ntrap, melodic rap, Latin pop\ntrap, melodic rap, Latin trap\ntrap, melodic rap, Middle Eastern\ntrap, melodic rap, Middle Eastern fusion\ntrap, melodic rap, North African\ntrap, melodic rap, Punjabi\ntrap, melodic rap, R&B\ntrap, melodic rap, Romanian\ntrap, melodic rap, Russian\ntrap, melodic rap, Russian hip hop\ntrap, melodic rap, Spanish guitar\ntrap, melodic rap, Swedish\ntrap, melodic rap, Thai pop\ntrap, melodic rap, Turkish\ntrap, melodic rap, Turkish pop\ntrap, melodic rap, UK garage\ntrap, melodic rap, Venezuelan hip hop\ntrap, melodic rap, alternative rock\ntrap, melodic rap, ambient\ntrap, melodic rap, anime pop\ntrap, melodic rap, atmospheric\ntrap, melodic rap, bilingual\ntrap, melodic rap, cinematic\ntrap, melodic rap, cloud rap\ntrap, melodic rap, dark ambient\ntrap, melodic rap, electronic\ntrap, melodic rap, emotional\ntrap, melodic rap, emotional pop\ntrap, melodic rap, ethnic fusion\ntrap, melodic rap, experimental\ntrap, melodic rap, experimental hip hop\ntrap, melodic rap, gospel\ntrap, melodic rap, hyperpop\ntrap, melodic rap, jazz fusion\ntrap, melodic rap, lo-fi\ntrap, melodic rap, medieval\ntrap, melodic rap, psy-trap\ntrap, melodic rap, psychedelic\ntrap, melodic rap, reggae-infused\ntrap, melodic rap, reggaeton\ntrap, melodic trap\ntrap, melodic trap, Chinese hip hop\ntrap, melodic trap, East Asian fusion\ntrap, melodic trap, Eastern fusion\ntrap, melodic trap, Indonesian hip hop\ntrap, melodic trap, R&B\ntrap, melodic trap, Russian hip hop\ntrap, melodic trap, atmospheric\ntrap, melodic trap, boom-bap\ntrap, melodic trap, cinematic\ntrap, melodic trap, experimental\ntrap, melodic trap, lo-fi hip hop\ntrap, melodic trap, reggaeton\ntrap, melodic, Chinese hip hop\ntrap, melodic, Dutch hip hop\ntrap, melodic, Thai pop\ntrap, meme electronic\ntrap, meme music\ntrap, meme rap\ntrap, meme rap, video game\ntrap, meme, aggressive\ntrap, meme, anime\ntrap, meme, chiptune\ntrap, meme, lo-fi\ntrap, meme, pop\ntrap, meme-rap\ntrap, meme-rap, Russian hip hop\ntrap, metalcore\ntrap, metalcore, C-pop\ntrap, metalcore, hyperpop\ntrap, microtonal\ntrap, microtonal folk\ntrap, microtonal oud\ntrap, microtonal, Arabic hip hop\ntrap, microtonal, Azerbaijani hip hop\ntrap, microtonal, Eastern\ntrap, microtonal, Eastern European\ntrap, microtonal, Middle Eastern\ntrap, microtonal, Turkish folk\ntrap, microtonal, Turkish traditional\ntrap, microtonal, cinematic\ntrap, microtonal, experimental\ntrap, microtonal, folk\ntrap, microtonal, lo-fi hip hop\ntrap, middle-eastern fusion\ntrap, militant\ntrap, militant hip-hop\ntrap, minimalist\ntrap, minimalist, Arabic hip hop\ntrap, minimalist, Chinese hip hop\ntrap, minimalist, Chinese hip-hop\ntrap, minimalist, Chinese pop\ntrap, minimalist, Filipino hip hop\ntrap, minimalist, German hip hop\ntrap, minimalist, Italian rap\ntrap, minimalist, Japanese hip hop\ntrap, minimalist, Russian hip hop\ntrap, minimalist, Russian rap\ntrap, minimalist, Southern hip hop\ntrap, minimalist, Swahili hip hop\ntrap, minimalist, bass-heavy\ntrap, minimalist, chiptune\ntrap, minimalist, cyberpunk\ntrap, minimalist, dark\ntrap, minimalist, electronic\ntrap, minimalist, hip hop\ntrap, minimalist, hip-hop\ntrap, minimalist, lo-fi\ntrap, minimalist, underground\ntrap, modern Chinese hip hop\ntrap, modern R&B\ntrap, modern hip hop\ntrap, modern hip-hop\ntrap, modern, African hip hop\ntrap, modern, C-pop\ntrap, modern, Chinese hip hop\ntrap, modern, East Asian\ntrap, modern, Eastern flavor\ntrap, modern, Eastern tonality\ntrap, modern, Eastern-influenced\ntrap, modern, Khmer hip hop\ntrap, modern, Mandarin hip hop\ntrap, modern, Mandarin rap\ntrap, modern, Middle Eastern fusion\ntrap, modern, Mongolian hip hop\ntrap, modern, North African\ntrap, modern, Thai hip hop\ntrap, modern, bilingual\ntrap, modern, bouncy\ntrap, modern, ethnic fusion\ntrap, modern, exotic\ntrap, modern, melancholic\ntrap, modern, melodic rap\ntrap, moody R&B\ntrap, moody R&B, dancehall\ntrap, moody synth\ntrap, moody, Chinese hip hop\ntrap, moody, Czech rap\ntrap, moody, Dutch hip hop\ntrap, moody, Hindi\ntrap, moody, Mandarin hip hop\ntrap, moody, Mandarin pop\ntrap, moody, Punjabi\ntrap, moody, atmospheric\ntrap, moody, bilingual\ntrap, moody, cinematic\ntrap, moombahton\ntrap, moombahton, C-pop\ntrap, moombahton, Indian electronic\ntrap, moombahton, Latin electronic\ntrap, moombahton, Malayalam hip hop\ntrap, moombahton, R&B\ntrap, moombahton, South Asian fusion\ntrap, moombahton, South Asian pop\ntrap, moombahton, Tollywood\ntrap, moombahton, ambient\ntrap, moombahton, electronic\ntrap, moombahton, experimental pop\ntrap, moombahton, hardstyle\ntrap, moombahton, pop\ntrap, moombahton, world music\ntrap, motivational, R&B\ntrap, motivational, cinematic\ntrap, multi-lingual\ntrap, multi-lingual hip hop\ntrap, multi-lingual, Bantu hip hop\ntrap, multi-lingual, Eastern flavor\ntrap, multi-lingual, Eastern-influenced\ntrap, multi-lingual, aggressive\ntrap, multi-lingual, banger\ntrap, multi-lingual, chiptune\ntrap, multi-lingual, cyberpunk\ntrap, multi-lingual, cypher\ntrap, multi-lingual, electronic\ntrap, multi-lingual, hip hop\ntrap, multilingual\ntrap, multilingual hip hop\ntrap, multilingual hip-hop\ntrap, multilingual rap\ntrap, multilingual, Chinese hip hop\ntrap, multilingual, Middle Eastern trap\ntrap, multilingual, aggressive\ntrap, multilingual, chiptune\ntrap, multilingual, chopped and screwed\ntrap, multilingual, cinematic\ntrap, multilingual, dark\ntrap, multilingual, electronic\ntrap, multilingual, global\ntrap, multilingual, gritty\ntrap, multilingual, high-energy\ntrap, multilingual, hip hop\ntrap, multilingual, hypnotic\ntrap, multilingual, lo-fi\ntrap, multilingual, melodic\ntrap, multilingual, street rap\ntrap, mumble rap\ntrap, mystical, Arabic\ntrap, mystical, ambient\ntrap, mystical, atmospheric\ntrap, mythic fusion, electronic\ntrap, mythological\ntrap, mythological hip hop\ntrap, mythological, Greek fusion\ntrap, mythological, Hindi hip hop\ntrap, mythological, atmospheric\ntrap, mythological, cinematic\ntrap, mythological, drill\ntrap, mythological, fusion\ntrap, nasyid\ntrap, neapolitan rap\ntrap, neo-classical\ntrap, neo-classical, hybrid\ntrap, neo-noir, cinematic\ntrap, neo-psychedelic, Arabic fusion\ntrap, neo-psychedelic, North African fusion\ntrap, neo-soul\ntrap, neo-soul, Middle Eastern\ntrap, neo-soul, R&B\ntrap, neo-soul, South Asian fusion\ntrap, neo-soul, ambient\ntrap, neo-soul, cinematic\ntrap, neo-soul, jazz-hop\ntrap, neo-soul, psychedelic\ntrap, neoclassical, Turkish hip-hop\ntrap, nerdcore\ntrap, nerdcore, atmospheric\ntrap, nerdcore, chiptune\ntrap, neurofunk\ntrap, neurofunk, grime\ntrap, ney flute\ntrap, ney flute, Arabic\ntrap, ney flute, Eastern fusion\ntrap, ney flute, Middle Eastern\ntrap, ney flute, Middle Eastern hip-hop\ntrap, ney flute, North African\ntrap, ney flute, ambient\ntrap, ney flute, atmospheric\ntrap, ney flute, cinematic\ntrap, ney flute, dark ambient\ntrap, ney, Middle Eastern\ntrap, nightcore\ntrap, noir jazz\ntrap, noir, lo-fi\ntrap, noir-jazz\ntrap, noise rock, melodic hip hop\ntrap, norteño, cumbia\ntrap, norteño, regional Mexican\ntrap, nostalgic, video game\ntrap, novelty\ntrap, novelty, Christmas\ntrap, nu-disco\ntrap, nu-disco, ambient\ntrap, nu-metal\ntrap, nu-metal, C-pop\ntrap, nu-metal, French rap\ntrap, nu-metal, Spanish rap\ntrap, nu-metal, ambient\ntrap, nu-metal, ambient hip-hop\ntrap, nu-metal, cinematic\ntrap, nu-metal, electronic\ntrap, nu-metal, emo-rap\ntrap, nu-metal, experimental\ntrap, nu-metal, hardcore punk\ntrap, nu-metal, hip-hop\ntrap, nu-metal, industrial\ntrap, nu-metal, industrial rock\ntrap, nu-metal, lo-fi hip hop\ntrap, nu-metal, psychedelic\ntrap, nu-metal, rap-rock\ntrap, nu-metal, rock-trap\ntrap, nu-metal, screamo\ntrap, nu-metal, synth pop\ntrap, operatic\ntrap, operatic hip hop\ntrap, operatic hip-hop\ntrap, operatic, Brazilian hip hop\ntrap, operatic, Chinese\ntrap, operatic, Chinese fusion\ntrap, operatic, French rap\ntrap, operatic, German hip hop\ntrap, operatic, German rap\ntrap, operatic, Haitian Creole\ntrap, operatic, K-pop\ntrap, operatic, Khmer hip hop\ntrap, operatic, Latin hip hop\ntrap, operatic, Russian rap\ntrap, operatic, Spanish hip hop\ntrap, operatic, ambient\ntrap, operatic, bilingual\ntrap, operatic, cinematic\ntrap, operatic, electronic\ntrap, operatic, experimental\ntrap, operatic, gothic\ntrap, operatic, hip hop\ntrap, operatic, hip-hop\ntrap, operatic, lo-fi\ntrap, operatic, lo-fi hip hop\ntrap, operatic, melancholic\ntrap, operatic, rap\ntrap, orchestral\ntrap, orchestral hip hop\ntrap, orchestral hip-hop\ntrap, orchestral synth\ntrap, orchestral synth, C-pop\ntrap, orchestral synth, Chinese hip hop\ntrap, orchestral synth, Dutch hip hop\ntrap, orchestral synth, Middle Eastern\ntrap, orchestral synth, chiptune\ntrap, orchestral synth, cinematic\ntrap, orchestral trap\ntrap, orchestral, Afrobeat\ntrap, orchestral, Arabic hip hop\ntrap, orchestral, Brazilian funk\ntrap, orchestral, Brazilian hip hop\ntrap, orchestral, C-pop\ntrap, orchestral, Cantonese hip hop\ntrap, orchestral, Chinese hip hop\ntrap, orchestral, Chinese rap\ntrap, orchestral, Christian rap\ntrap, orchestral, Dutch hip hop\ntrap, orchestral, French hip hop\ntrap, orchestral, French rap\ntrap, orchestral, German hip hop\ntrap, orchestral, German hip-hop\ntrap, orchestral, German rap\ntrap, orchestral, Greek hip hop\ntrap, orchestral, Hindi hip hop\ntrap, orchestral, Hungarian hip hop\ntrap, orchestral, Icelandic hip hop\ntrap, orchestral, Italian hip hop\ntrap, orchestral, Italian rap\ntrap, orchestral, Jamaican Patois\ntrap, orchestral, K-hip hop\ntrap, orchestral, K-pop\ntrap, orchestral, Korean hip hop\ntrap, orchestral, Latin hip hop\ntrap, orchestral, Malay hip hop\ntrap, orchestral, Mandarin rap\ntrap, orchestral, Middle Eastern\ntrap, orchestral, Polish hip hop\ntrap, orchestral, Polish hip-hop\ntrap, orchestral, Polish rap\ntrap, orchestral, Portuguese rap\ntrap, orchestral, Punjabi hip hop\ntrap, orchestral, Punjabi hip-hop\ntrap, orchestral, R&B\ntrap, orchestral, Romanian rap\ntrap, orchestral, Russian\ntrap, orchestral, Russian gangsta rap\ntrap, orchestral, Russian hip hop\ntrap, orchestral, Russian rap\ntrap, orchestral, Sinhala hip hop\ntrap, orchestral, Swedish hip hop\ntrap, orchestral, Thai hip hop\ntrap, orchestral, Turkish hip hop\ntrap, orchestral, Turkish pop\ntrap, orchestral, aggressive\ntrap, orchestral, anime\ntrap, orchestral, baroque\ntrap, orchestral, battle rap\ntrap, orchestral, bilingual hip hop\ntrap, orchestral, boom-bap\ntrap, orchestral, cinematic\ntrap, orchestral, dance-pop\ntrap, orchestral, dancehall\ntrap, orchestral, danish hip hop\ntrap, orchestral, dark\ntrap, orchestral, electronic\ntrap, orchestral, epic\ntrap, orchestral, epic rap\ntrap, orchestral, experimental\ntrap, orchestral, gangsta rap\ntrap, orchestral, gangster rap\ntrap, orchestral, gothic\ntrap, orchestral, hardstyle\ntrap, orchestral, hip hop\ntrap, orchestral, hip-hop\ntrap, orchestral, horror\ntrap, orchestral, hyperpop\ntrap, orchestral, lo-fi\ntrap, orchestral, melancholic\ntrap, orchestral, pop-R&B\ntrap, orchestral, reggae\ntrap, orchestral, synth\ntrap, orchestral, synthwave\ntrap, orchestral, urban\ntrap, oriental\ntrap, oriental flavor\ntrap, oriental fusion\ntrap, oriental hip hop\ntrap, oriental hip-hop\ntrap, oriental pop\ntrap, oriental style\ntrap, oriental style, lo-fi\ntrap, oriental synth\ntrap, oriental synth, hip-hop\ntrap, oriental trap\ntrap, oriental, Mandarin hip hop\ntrap, oriental, cinematic\ntrap, oriental, electronic\ntrap, oriental, german rap\ntrap, oriental, lo-fi\ntrap, oriental, melancholic\ntrap, oud fusion\ntrap, oud fusion, Moroccan hip-hop\ntrap, oud fusion, North African hip-hop\ntrap, oud fusion, cinematic\ntrap, oud fusion, electronic\ntrap, oud, Arabic fusion\ntrap, oud, Arabic hip hop\ntrap, oud, C-pop\ntrap, oud, Eastern European\ntrap, oud, French hip-hop\ntrap, oud, French rap\ntrap, oud, Middle Eastern\ntrap, oud, North African\ntrap, oud, Persian\ntrap, oud, Turkish fusion\ntrap, oud, Turkish hip-hop\ntrap, oud, ambient\ntrap, oud, atmospheric\ntrap, oud, cinematic\ntrap, oud, cinematic hip-hop\ntrap, oud, classical\ntrap, oud, dark ambient\ntrap, oud, electronic\ntrap, oud, hip-hop\ntrap, oud, hyperpop\ntrap, oud, hypnotic\ntrap, oud, lo-fi\ntrap, oud, melancholic\ntrap, oud, ney\ntrap, oud, vaporwave\ntrap, oud, violin\ntrap, oud, world fusion\ntrap, philosophical, Hindi spoken word\ntrap, phonk\ntrap, phonk, East Asian fusion\ntrap, phonk, Italian hip-hop\ntrap, phonk, J-rap\ntrap, phonk, Polish hip-hop\ntrap, phonk, Russian hip hop\ntrap, phonk, Russian rap\ntrap, phonk, aggressive hip-hop\ntrap, phonk, ambient\ntrap, phonk, chiptune\ntrap, phonk, cinematic\ntrap, phonk, cyberpunk\ntrap, phonk, dark ambient\ntrap, phonk, dark electronic\ntrap, phonk, dark trap\ntrap, phonk, darkwave\ntrap, phonk, drill\ntrap, phonk, electronic\ntrap, phonk, electronic dance music\ntrap, phonk, experimental hip-hop\ntrap, phonk, gangsta rap\ntrap, phonk, hard trap\ntrap, phonk, hardstyle\ntrap, phonk, hardwave\ntrap, phonk, hip-hop\ntrap, phonk, instrumental\ntrap, phonk, instrumental hip-hop\ntrap, phonk, lo-fi hip hop\ntrap, phonk, rage\ntrap, phonk, rage rap\ntrap, phonk, witch house\ntrap, piano ballad\ntrap, piano, Mandarin rap\ntrap, pirate rap\ntrap, pirate, cinematic\ntrap, playful, Mandarin rap\ntrap, playful, cartoon\ntrap, pluggnb\ntrap, pluggnb, Brazilian\ntrap, pluggnb, Brazilian trap\ntrap, pluggnb, Chinese hip-hop\ntrap, pluggnb, Spanish\ntrap, pluggnb, Spanish flavor\ntrap, pluggnb, ambient\ntrap, pluggnb, baroque\ntrap, pluggnb, chiptune\ntrap, pluggnb, cloud rap\ntrap, pluggnb, future bass\ntrap, pluggnb, hyperpop\ntrap, pluggnb, lo-fi\ntrap, pluggnb, lo-fi hip hop\ntrap, pluggnb, minimalist\ntrap, pluggnb, pop-rap\ntrap, pluggnb, rage\ntrap, pluggnb, rage music\ntrap, pluggnb, video game\ntrap, pluggnb, world music\ntrap, political hip hop\ntrap, polka, bilingual\ntrap, polka, electronic\ntrap, pop\ntrap, pop R&B\ntrap, pop R&B, EDM\ntrap, pop rap\ntrap, pop, Anatolian fusion\ntrap, pop, Azerbaijani\ntrap, pop, Balkan\ntrap, pop, Brazilian hip hop\ntrap, pop, Brazilian hip-hop\ntrap, pop, C-pop\ntrap, pop, Chinese pop\ntrap, pop, Dutch hip-hop\ntrap, pop, Finnish hip hop\ntrap, pop, French hip hop\ntrap, pop, French rap\ntrap, pop, Indian folk\ntrap, pop, Indian fusion\ntrap, pop, Indonesian\ntrap, pop, Javanese\ntrap, pop, Khmer\ntrap, pop, Latin\ntrap, pop, Malayalam hip hop\ntrap, pop, Mandarin hip hop\ntrap, pop, Middle Eastern\ntrap, pop, Punjabi hip hop\ntrap, pop, R&B\ntrap, pop, Russian rap\ntrap, pop, South Asian\ntrap, pop, South Asian fusion\ntrap, pop, Swedish hip hop\ntrap, pop, Turkish hip hop\ntrap, pop, Turkish pop\ntrap, pop, bilingual\ntrap, pop, cinematic\ntrap, pop, danish\ntrap, pop, electronic\ntrap, pop, emotional\ntrap, pop, ethnic\ntrap, pop, hip hop\ntrap, pop, hip-hop\ntrap, pop, lo-fi\ntrap, pop, rock\ntrap, pop, vaporwave\ntrap, pop-R&B\ntrap, pop-R&B, Balkan\ntrap, pop-R&B, C-pop\ntrap, pop-R&B, Chinese hip hop\ntrap, pop-R&B, Chinese pop\ntrap, pop-R&B, Chinese rap\ntrap, pop-R&B, Indian fusion\ntrap, pop-R&B, Indonesian hip hop\ntrap, pop-R&B, Mandarin hip hop\ntrap, pop-R&B, Middle Eastern\ntrap, pop-R&B, Middle Eastern fusion\ntrap, pop-R&B, Punjabi\ntrap, pop-R&B, Russian\ntrap, pop-R&B, Russian rap\ntrap, pop-R&B, Turkish\ntrap, pop-R&B, ambient\ntrap, pop-R&B, cinematic\ntrap, pop-R&B, dancehall\ntrap, pop-R&B, hip-hop\ntrap, pop-R&B, lo-fi hip hop\ntrap, pop-R&B, spoken word\ntrap, pop-R&B, vaporwave\ntrap, pop-gospel, cinematic\ntrap, pop-punk\ntrap, pop-punk, C-pop\ntrap, pop-punk, alternative rock\ntrap, pop-punk, ambient\ntrap, pop-punk, cinematic\ntrap, pop-rap\ntrap, pop-rap, C-pop\ntrap, pop-rap, Kazakh\ntrap, pop-rap, Mediterranean\ntrap, pop-rap, R&B\ntrap, pop-rap, Russian hip hop\ntrap, pop-rap, atmospheric R&B\ntrap, pop-rap, contemporary R&B\ntrap, pop-rap, electronic\ntrap, pop-rap, folk fusion\ntrap, pop-rap, hip-hop\ntrap, pop-rap, hyperpop\ntrap, pop-rap, lo-fi hip-hop\ntrap, pop-rap, synth-pop\ntrap, pop-rap, vaporwave\ntrap, pop-rap, world music\ntrap, pop-rock, K-pop\ntrap, pop-rock, reggaeton\ntrap, pop-trap\ntrap, post-rock\ntrap, post-rock, C-pop\ntrap, post-rock, Chinese hip hop\ntrap, post-rock, emo rap\ntrap, post-rock, industrial\ntrap, post-rock, lo-fi hip hop\ntrap, post-rock, screamo\ntrap, power ballad, cinematic\ntrap, progressive house\ntrap, progressive trance\ntrap, protest anthem, cinematic\ntrap, protest hip hop\ntrap, protest music\ntrap, protest rap\ntrap, protest, dark\ntrap, protest, pop\ntrap, psychedelic\ntrap, psychedelic R&B\ntrap, psychedelic R&B, cinematic\ntrap, psychedelic ambient, K-pop\ntrap, psychedelic folk-rock\ntrap, psychedelic hip hop\ntrap, psychedelic hip-hop\ntrap, psychedelic hip-hop, Middle Eastern\ntrap, psychedelic lo-fi\ntrap, psychedelic lo-fi, experimental hip hop\ntrap, psychedelic pop, hip-hop\ntrap, psychedelic rap\ntrap, psychedelic rap, lo-fi\ntrap, psychedelic rock\ntrap, psychedelic rock, Arabic hip hop\ntrap, psychedelic rock, North African\ntrap, psychedelic soul\ntrap, psychedelic trap\ntrap, psychedelic world music\ntrap, psychedelic, Afro-hip hop\ntrap, psychedelic, Afro-trap\ntrap, psychedelic, Arabic\ntrap, psychedelic, Arabic fusion\ntrap, psychedelic, Arabic hip hop\ntrap, psychedelic, Brazilian\ntrap, psychedelic, Brazilian hip hop\ntrap, psychedelic, C-pop\ntrap, psychedelic, Chinese hip hop\ntrap, psychedelic, Chinese traditional\ntrap, psychedelic, Dutch hip hop\ntrap, psychedelic, EDM\ntrap, psychedelic, Eastern\ntrap, psychedelic, Eastern fusion\ntrap, psychedelic, Eastern-influenced\ntrap, psychedelic, Finnish hip hop\ntrap, psychedelic, French rap\ntrap, psychedelic, German hip hop\ntrap, psychedelic, German rap\ntrap, psychedelic, Greek hip hop\ntrap, psychedelic, Hebrew rap\ntrap, psychedelic, Hindi hip hop\ntrap, psychedelic, Indian fusion\ntrap, psychedelic, Indian hip hop\ntrap, psychedelic, Italian\ntrap, psychedelic, Italian hip hop\ntrap, psychedelic, Italian rap\ntrap, psychedelic, Jersey club\ntrap, psychedelic, Korean hip hop\ntrap, psychedelic, Latin\ntrap, psychedelic, Latin hip hop\ntrap, psychedelic, Mandarin hip hop\ntrap, psychedelic, Mandarin rap\ntrap, psychedelic, Middle Eastern\ntrap, psychedelic, Mongolian fusion\ntrap, psychedelic, Mongolian hip hop\ntrap, psychedelic, Moroccan Arabic\ntrap, psychedelic, Moroccan hip hop\ntrap, psychedelic, North African\ntrap, psychedelic, Persian rap\ntrap, psychedelic, Polish rap\ntrap, psychedelic, R&B\ntrap, psychedelic, Romanian\ntrap, psychedelic, Romanian hip hop\ntrap, psychedelic, Russian gangster rap\ntrap, psychedelic, Russian hip hop\ntrap, psychedelic, Sinhala hip hop\ntrap, psychedelic, Southern hip hop\ntrap, psychedelic, Spanish hip hop\ntrap, psychedelic, Spanish rap\ntrap, psychedelic, Swedish rap\ntrap, psychedelic, Thai hip hop\ntrap, psychedelic, Turkish hip hop\ntrap, psychedelic, UK drill\ntrap, psychedelic, UK rap\ntrap, psychedelic, ambient\ntrap, psychedelic, atmospheric\ntrap, psychedelic, auto-tune\ntrap, psychedelic, auto-tune rap\ntrap, psychedelic, bilingual rap\ntrap, psychedelic, breakcore\ntrap, psychedelic, chopped and screwed\ntrap, psychedelic, choral\ntrap, psychedelic, cinematic\ntrap, psychedelic, cloud rap\ntrap, psychedelic, dancehall\ntrap, psychedelic, dark\ntrap, psychedelic, dark ambient\ntrap, psychedelic, dark hip hop\ntrap, psychedelic, dream rap\ntrap, psychedelic, electronic\ntrap, psychedelic, emo rap\ntrap, psychedelic, emotional rap\ntrap, psychedelic, ethereal\ntrap, psychedelic, experimental\ntrap, psychedelic, festive\ntrap, psychedelic, future bass\ntrap, psychedelic, futuristic\ntrap, psychedelic, glitch\ntrap, psychedelic, hip hop\ntrap, psychedelic, hip-hop\ntrap, psychedelic, hyperpop\ntrap, psychedelic, industrial\ntrap, psychedelic, introspective\ntrap, psychedelic, jazz\ntrap, psychedelic, lo-fi\ntrap, psychedelic, lo-fi hip hop\ntrap, psychedelic, luxury\ntrap, psychedelic, melodic\ntrap, psychedelic, melodic hip hop\ntrap, psychedelic, melodic rap\ntrap, psychedelic, motivational\ntrap, psychedelic, orchestral\ntrap, psychedelic, pop\ntrap, psychedelic, rap\ntrap, psychedelic, regional Mexican\ntrap, psychedelic, retro\ntrap, psychedelic, shoegaze\ntrap, psychedelic, soul\ntrap, psychedelic, underground hip hop\ntrap, psychedelic, world music\ntrap, psytrance, Indian fusion\ntrap, psytrance, ambient\ntrap, psytrance, cinematic\ntrap, psytrance, ritual ambient\ntrap, punk, Southeast Asian\ntrap, punk, electronic\ntrap, punk, experimental\ntrap, qawwali\ntrap, quirky, classical fusion\ntrap, rage\ntrap, rage music\ntrap, rage music, Korean hip-hop\ntrap, rage music, cinematic hip hop\ntrap, rage rap\ntrap, rage rap, cinematic\ntrap, rage rap, cloud rap\ntrap, rage rap, dark melodic\ntrap, rage rap, hyperpop\ntrap, rage rap, phonk\ntrap, rage trap\ntrap, rage, Chinese hip hop\ntrap, rage, Hindi hip hop\ntrap, rage, Korean hip hop\ntrap, rage, Latin trap\ntrap, rage, Middle Eastern trap\ntrap, rage, anime trap\ntrap, rage, bilingual\ntrap, rage, cinematic\ntrap, rage, dark trap\ntrap, rage, drill\ntrap, rage, futuristic\ntrap, rage, hyperpop\ntrap, rage, lo-fi\ntrap, rage, multi-lingual\ntrap, rage, phonk\ntrap, rage, pluggnb\ntrap, rage-trap\ntrap, rage-trap, Latin hip hop\ntrap, ragtime\ntrap, ragtime hip hop\ntrap, ragtime, C-pop\ntrap, ragtime, Caribbean hip hop\ntrap, ragtime, Chinese hip hop\ntrap, ragtime, Indian fusion\ntrap, ragtime, Mandarin hip hop\ntrap, ragtime, Mandarin rap\ntrap, ragtime, aggressive\ntrap, ragtime, ambient\ntrap, ragtime, hip hop\ntrap, ragtime, lo-fi\ntrap, ragtime, lo-fi hip hop\ntrap, rai\ntrap, rai, sad pop\ntrap, rai-trap\ntrap, rap\ntrap, rap, Brazilian\ntrap, rap, Chinese hip hop\ntrap, rap, East Asian fusion\ntrap, rap, R&B\ntrap, rap, Romanian\ntrap, rap, anime hip hop\ntrap, rap, chiptune\ntrap, rap, cinematic\ntrap, rap, cypher\ntrap, rap, electronic\ntrap, rap, experimental R&B\ntrap, rap, melancholic\ntrap, rap-rock, nu-metal\ntrap, raï\ntrap, raï, cinematic\ntrap, raï, oud\ntrap, reggae\ntrap, reggae fusion\ntrap, reggae, dancehall\ntrap, reggae, electronic\ntrap, reggae, lo-fi\ntrap, reggae, soulful\ntrap, reggaeton\ntrap, reggaeton, Hindi rap\ntrap, reggaeton, Indian hip hop\ntrap, reggaeton, Italian\ntrap, reggaeton, Latin\ntrap, reggaeton, Latin hip hop\ntrap, reggaeton, Middle Eastern fusion\ntrap, reggaeton, Russian hip hop\ntrap, reggaeton, ambient\ntrap, reggaeton, bilingual\ntrap, reggaeton, boom-bap\ntrap, reggaeton, chiptune\ntrap, reggaeton, cinematic\ntrap, reggaeton, cloud rap\ntrap, reggaeton, dancehall\ntrap, reggaeton, dark electronic\ntrap, reggaeton, electronic\ntrap, reggaeton, experimental electronic\ntrap, reggaeton, hip hop\ntrap, reggaeton, hip-hop\ntrap, reggaeton, hyperpop\ntrap, reggaeton, introspective hip hop\ntrap, reggaeton, lo-fi\ntrap, reggaeton, lo-fi hip hop\ntrap, reggaeton, moombahton\ntrap, reggaeton, pop\ntrap, reggaeton, worldbeat\ntrap, regional Indian hip-hop\ntrap, regional Mexican\ntrap, regional Mexican hip-hop\ntrap, regional Mexican, ambient\ntrap, regional Mexican, electronic\ntrap, regional Mexican, hip-hop\ntrap, regional Mexican, hyperpop\ntrap, regional Mexican, lo-fi\ntrap, regional Mexican, lo-fi hip hop\ntrap, regional hip hop\ntrap, regional hip-hop\ntrap, retro electronic\ntrap, retro gaming\ntrap, retro synth\ntrap, retro synth, Chinese hip hop\ntrap, retro synth, nostalgic hip hop\ntrap, retro, electronic\ntrap, retro-futuristic, Czech hip hop\ntrap, retro-futuristic, chiptune\ntrap, revolutionary anthem\ntrap, ritual ambient\ntrap, ritual chant\ntrap, ritual electronic\ntrap, ritualistic hip hop\ntrap, ritualistic, Afro-urban\ntrap, ritualistic, Malayalam\ntrap, ritualistic, Thai hip hop\ntrap, ritualistic, aggressive\ntrap, ritualistic, ambient\ntrap, ritualistic, choral\ntrap, ritualistic, psychedelic\ntrap, rock\ntrap, rock, Arabic hip hop\ntrap, rock, Italian rap\ntrap, rock, Latin hip-hop\ntrap, rock, Malayalam hip hop\ntrap, rock, Middle Eastern\ntrap, rock, Portuguese hip hop\ntrap, rock, Sinhala\ntrap, rock, Tamil rap\ntrap, rock, afrobeats\ntrap, rock, ambient\ntrap, rock, cinematic\ntrap, rock, doo-wop\ntrap, rock, electronic\ntrap, rock, emotional ballad\ntrap, rock, experimental\ntrap, rock, hip-hop\ntrap, rock-influenced\ntrap, rock-rap\ntrap, romantic hip-hop\ntrap, russian hip hop\ntrap, russian rap\ntrap, samba, Brazilian hip hop\ntrap, satirical hip hop\ntrap, satirical, British hip hop\ntrap, satirical, Eastern flavor\ntrap, satirical, Mandarin rap\ntrap, saxophone, Swahili rap\ntrap, sci-fi\ntrap, sci-fi hip hop\ntrap, sci-fi horror\ntrap, sci-fi horror, electronic\ntrap, sci-fi, Arabic hip hop\ntrap, sci-fi, Latin hip hop\ntrap, sci-fi, Thai hip hop\ntrap, sci-fi, Ukrainian hip hop\ntrap, sci-fi, ambient\ntrap, sci-fi, atmospheric\ntrap, sci-fi, bilingual rap\ntrap, sci-fi, cinematic\ntrap, sci-fi, electronic\ntrap, sci-fi, futuristic\ntrap, sci-fi, hip hop\ntrap, sci-fi, horror\ntrap, sci-fi, pirate\ntrap, sci-fi, video game\ntrap, sea shanty\ntrap, sea shanty, cinematic\ntrap, shehnai\ntrap, shoegaze\ntrap, shoegaze, C-pop\ntrap, shoegaze, Chinese hip hop\ntrap, shoegaze, Italian rap\ntrap, shoegaze, K-pop\ntrap, shoegaze, Mandopop\ntrap, shoegaze, R&B\ntrap, shoegaze, ambient\ntrap, shoegaze, electronic\ntrap, shoegaze, emo\ntrap, shoegaze, emo rap\ntrap, shoegaze, hip hop\ntrap, shoegaze, hyperpop\ntrap, shoegaze, lo-fi\ntrap, shoegaze, lo-fi hip hop\ntrap, sinister, electronic\ntrap, sitar fusion\ntrap, sitar loop\ntrap, sitar synth, Middle Eastern\ntrap, sitar, Eastern\ntrap, sitar, French rap\ntrap, sitar, Middle Eastern\ntrap, sitar, lo-fi hip hop\ntrap, sitar, multilingual\ntrap, slap house, tech house\ntrap, slowed + reverb\ntrap, social commentary\ntrap, soul\ntrap, soul, Afro-hip hop\ntrap, soul, Arabic fusion\ntrap, soul, Arabic hip hop\ntrap, soul, Azerbaijani pop\ntrap, soul, Brazilian\ntrap, soul, C-pop\ntrap, soul, Chinese hip hop\ntrap, soul, Hungarian hip hop\ntrap, soul, Indian\ntrap, soul, Italian hip hop\ntrap, soul, Lithuanian hip hop\ntrap, soul, Mandarin hip hop\ntrap, soul, Middle Eastern\ntrap, soul, Moroccan hip hop\ntrap, soul, R&B\ntrap, soul, South Asian\ntrap, soul, Southern hip hop\ntrap, soul, UK rap\ntrap, soul, Ukrainian\ntrap, soul, ambient\ntrap, soul, atmospheric\ntrap, soul, boom-bap\ntrap, soul, chopped and screwed\ntrap, soul, cinematic\ntrap, soul, classic rock\ntrap, soul, cloud rap\ntrap, soul, danish hip hop\ntrap, soul, electronic\ntrap, soul, experimental\ntrap, soul, experimental hip hop\ntrap, soul, funk\ntrap, soul, gospel\ntrap, soul, hip hop\ntrap, soul, jazz\ntrap, soul, lo-fi\ntrap, soul, lo-fi hip hop\ntrap, soul, melancholic\ntrap, soul, melodic rap\ntrap, soul, piano ballad\ntrap, soul, pop\ntrap, soul, spoken word\ntrap, soul, tribal\ntrap, soul, vaporwave\ntrap, soul-rock, lo-fi\ntrap, soulful\ntrap, soulful R&B\ntrap, soulful R&B, world music\ntrap, soulful ballad\ntrap, soulful hip hop\ntrap, soulful hip-hop\ntrap, soulful rap\ntrap, soulful rock, Turkish hip-hop\ntrap, soulful, Hebrew hip hop\ntrap, soulful, Thai hip hop\ntrap, soulful, atmospheric\ntrap, soulful, auto-tuned\ntrap, soulful, cinematic\ntrap, soulful, lo-fi\ntrap, soulful, melodic\ntrap, south african hip hop\ntrap, southern gothic\ntrap, southern gothic, swamp rap\ntrap, southern hip hop\ntrap, southern hip hop, atmospheric\ntrap, southern hip-hop\ntrap, southern hip-hop, cinematic\ntrap, southern hip-hop, crunk\ntrap, southern hip-hop, gospel\ntrap, southern rock\ntrap, southern rock, country\ntrap, spanish hip hop\ntrap, spiritual chant\ntrap, spiritual chant, Indian fusion\ntrap, spiritual fusion\ntrap, spiritual hip hop\ntrap, spiritual hip-hop\ntrap, spiritual, Arabic\ntrap, spiritual, Hebrew\ntrap, spiritual, Hindi hip hop\ntrap, spiritual, Indian fusion\ntrap, spiritual, Indian hip hop\ntrap, spiritual, Middle Eastern\ntrap, spiritual, North African\ntrap, spiritual, South Asian\ntrap, spiritual, ambient\ntrap, spiritual, ancient style\ntrap, spiritual, anthemic\ntrap, spiritual, cinematic\ntrap, spiritual, conscious\ntrap, spiritual, devotional\ntrap, spiritual, electronic\ntrap, spiritual, experimental\ntrap, spoken word, Latin hip hop\ntrap, spoken word, gospel\ntrap, spooky, Chinese hip hop\ntrap, sports anthem\ntrap, street rap\ntrap, sufi, fusion\ntrap, summer, lo-fi\ntrap, surf-rock, garage rock\ntrap, surf-rock, lo-fi\ntrap, synth\ntrap, synth arpeggio\ntrap, synth arpeggio, classical-inspired\ntrap, synth brass, Eastern European\ntrap, synth brass, Eastern flavor\ntrap, synth brass, Southern hip hop\ntrap, synth brass, anthemic\ntrap, synth brass, cinematic\ntrap, synth brass, hip hop\ntrap, synth hip-hop\ntrap, synth horn, hip hop\ntrap, synth melody\ntrap, synth pop\ntrap, synth pop, Chinese hip hop\ntrap, synth pop, French rap\ntrap, synth pop, R&B\ntrap, synth pop, lo-fi hip hop\ntrap, synth pop, video game\ntrap, synth trap\ntrap, synth trap, cloud rap\ntrap, synth wave\ntrap, synth, Mandarin hip hop\ntrap, synth, R&B\ntrap, synth, aggressive\ntrap, synth, chiptune\ntrap, synth, electronic\ntrap, synth, lo-fi\ntrap, synth-funk, lo-fi hip hop\ntrap, synth-funk, vaporwave\ntrap, synth-pop\ntrap, synth-pop, C-pop\ntrap, synth-pop, EDM\ntrap, synth-pop, German hip hop\ntrap, synth-pop, German pop-rap\ntrap, synth-pop, Italo disco\ntrap, synth-pop, R&B\ntrap, synth-pop, chiptune\ntrap, synth-pop, cloud rap\ntrap, synth-pop, darkwave\ntrap, synth-pop, electronic\ntrap, synth-pop, emo rap\ntrap, synth-pop, future bass\ntrap, synth-pop, gamer-rap\ntrap, synth-pop, hip-hop\ntrap, synth-pop, hyperpop\ntrap, synth-pop, melodic rap\ntrap, synth-rock, chiptune\ntrap, synthpop\ntrap, synthpop, R&B\ntrap, synthwave\ntrap, synthwave, Afro-hip hop\ntrap, synthwave, Arabic hip hop\ntrap, synthwave, C-pop\ntrap, synthwave, Cantopop\ntrap, synthwave, Chinese hip hop\ntrap, synthwave, Chinese opera\ntrap, synthwave, Chinese pop\ntrap, synthwave, Czech hip hop\ntrap, synthwave, Dutch hip hop\ntrap, synthwave, Filipino hip hop\ntrap, synthwave, Finnish hip hop\ntrap, synthwave, French hip hop\ntrap, synthwave, French pop\ntrap, synthwave, French rap\ntrap, synthwave, German hip hop\ntrap, synthwave, German hip-hop\ntrap, synthwave, German pop\ntrap, synthwave, German rap\ntrap, synthwave, Hebrew rap\ntrap, synthwave, Hungarian pop\ntrap, synthwave, J-pop\ntrap, synthwave, K-pop\ntrap, synthwave, Kazakh hip hop\ntrap, synthwave, Latin hip hop\ntrap, synthwave, Mandarin hip hop\ntrap, synthwave, Mandarin rap\ntrap, synthwave, Polish hip hop\ntrap, synthwave, Punjabi hip hop\ntrap, synthwave, R&B\ntrap, synthwave, Russian hip hop\ntrap, synthwave, Russian rap\ntrap, synthwave, Russian vocal\ntrap, synthwave, Southern hip hop\ntrap, synthwave, Southern hip-hop\ntrap, synthwave, Swedish rap\ntrap, synthwave, Turkish hip hop\ntrap, synthwave, Vocaloid\ntrap, synthwave, ambient\ntrap, synthwave, anime\ntrap, synthwave, chiptune\ntrap, synthwave, cinematic\ntrap, synthwave, cinematic hip hop\ntrap, synthwave, cloud rap\ntrap, synthwave, cyberpunk\ntrap, synthwave, dark electronic\ntrap, synthwave, darkwave\ntrap, synthwave, electronic\ntrap, synthwave, future bass\ntrap, synthwave, hip hop\ntrap, synthwave, hip-hop\ntrap, synthwave, hyperpop\ntrap, synthwave, lo-fi hip hop\ntrap, synthwave, nu-metal\ntrap, synthwave, pop\ntrap, synthwave, vaporwave\ntrap, synthwave, vocal electronic\ntrap, tango, Italian hip hop\ntrap, tango, K-pop\ntrap, tango, lo-fi hip hop\ntrap, techno\ntrap, techno, Italian rap\ntrap, techno, industrial hip hop\ntrap, theatrical hip hop\ntrap, theatrical rap, comedic\ntrap, theatrical, British hip hop\ntrap, theatrical, Chinese pop\ntrap, traditional Azerbaijani, melancholic\ntrap, traditional Central Asian\ntrap, traditional Central Asian, atmospheric\ntrap, traditional Central Asian, cinematic\ntrap, traditional Central Asian, emotional\ntrap, traditional Chinese, hip hop\ntrap, traditional East Asian\ntrap, traditional East Asian, cinematic\ntrap, traditional Indonesian, choral\ntrap, traditional South Asian\ntrap, traditional Southeast Asian\ntrap, traditional Southeast Asian folk\ntrap, traditional Southeast Asian, Khmer hip hop\ntrap, traditional Turkish\ntrap, traditional Turkish, emotional\ntrap, traditional Turkish, emotional pop\ntrap, traditional Vietnamese, cinematic\ntrap, traditional chant\ntrap, traditional fusion\ntrap, traditional fusion, Kurdish hip-hop\ntrap, traditional, C-pop\ntrap, traditional, Persian\ntrap, tribal, hip hop\ntrap, tribal, jungle\ntrap, trip-hop, experimental jazz\ntrap, tropical\ntrap, tropical house\ntrap, tropical house, Italian rap\ntrap, tropical house, R&B\ntrap, tropical, chiptune\ntrap, tropical, dancehall\ntrap, tropical, hip hop\ntrap, tropical, mystical\ntrap, twerk\ntrap, twerk, Southern hip-hop\ntrap, twerk, club\ntrap, twerk, crunk\ntrap, uk garage\ntrap, ukulele pop\ntrap, ukulele, meme hip-hop\ntrap, ukulele, playful\ntrap, underground\ntrap, underground hip hop\ntrap, underground hip-hop\ntrap, underground, Czech hip hop\ntrap, underground, ambient\ntrap, underground, atmospheric\ntrap, underground, dark\ntrap, underground, lo-fi\ntrap, urban\ntrap, urban noir, folk fusion\ntrap, urban, Latin\ntrap, urban, cinematic\ntrap, vaporwave\ntrap, vaporwave, Afrobeat\ntrap, vaporwave, Arabic hip hop\ntrap, vaporwave, Arabic hip-hop\ntrap, vaporwave, Arabic melodic rap\ntrap, vaporwave, Arabic pop\ntrap, vaporwave, Brazilian funk\ntrap, vaporwave, Brazilian hip hop\ntrap, vaporwave, Brazilian trap\ntrap, vaporwave, C-pop\ntrap, vaporwave, Cantopop\ntrap, vaporwave, Catalan hip hop\ntrap, vaporwave, Chinese R&B\ntrap, vaporwave, Chinese ambient\ntrap, vaporwave, Chinese electronic\ntrap, vaporwave, Chinese hip hop\ntrap, vaporwave, Chinese hip-hop\ntrap, vaporwave, Chinese opera\ntrap, vaporwave, Chinese pop\ntrap, vaporwave, Chinese underground\ntrap, vaporwave, Czech hip hop\ntrap, vaporwave, Czech rap\ntrap, vaporwave, Dutch hip hop\ntrap, vaporwave, Dutch hip-hop\ntrap, vaporwave, European\ntrap, vaporwave, Filipino hip hop\ntrap, vaporwave, Finnish hip hop\ntrap, vaporwave, Finnish rap\ntrap, vaporwave, French hip hop\ntrap, vaporwave, French pop\ntrap, vaporwave, French rap\ntrap, vaporwave, German hip hop\ntrap, vaporwave, German hip-hop\ntrap, vaporwave, German rap\ntrap, vaporwave, Greek hip hop\ntrap, vaporwave, Hindi pop\ntrap, vaporwave, Indian fusion\ntrap, vaporwave, Indian hip hop\ntrap, vaporwave, Italian hip hop\ntrap, vaporwave, Italian hip-hop\ntrap, vaporwave, Italian rap\ntrap, vaporwave, J-pop\ntrap, vaporwave, K-pop\ntrap, vaporwave, Latin hip hop\ntrap, vaporwave, Latin pop\ntrap, vaporwave, Latin trap\ntrap, vaporwave, Latvian hip hop\ntrap, vaporwave, Malay hip hop\ntrap, vaporwave, Mandarin hip hop\ntrap, vaporwave, Mandarin pop\ntrap, vaporwave, Mandarin rap\ntrap, vaporwave, Mandopop\ntrap, vaporwave, Mongolian hip hop\ntrap, vaporwave, Moroccan hip hop\ntrap, vaporwave, Nepali hip hop\ntrap, vaporwave, North African hip-hop\ntrap, vaporwave, Persian hip hop\ntrap, vaporwave, Polish hip hop\ntrap, vaporwave, Polish rap\ntrap, vaporwave, Punjabi hip hop\ntrap, vaporwave, Punjabi pop\ntrap, vaporwave, R&B\ntrap, vaporwave, Russian\ntrap, vaporwave, Russian emo\ntrap, vaporwave, Russian hip hop\ntrap, vaporwave, Russian hip-hop\ntrap, vaporwave, Russian pop\ntrap, vaporwave, Russian rap\ntrap, vaporwave, Sinhala hip hop\ntrap, vaporwave, Slovak hip hop\ntrap, vaporwave, Spanish rap\ntrap, vaporwave, Swedish hip hop\ntrap, vaporwave, Swedish hip-hop\ntrap, vaporwave, Thai hip hop\ntrap, vaporwave, Turkish hip hop\ntrap, vaporwave, Turkish pop\ntrap, vaporwave, Ukrainian hip hop\ntrap, vaporwave, afrobeats\ntrap, vaporwave, ambient\ntrap, vaporwave, auto-tune\ntrap, vaporwave, bilingual hip hop\ntrap, vaporwave, blues rock\ntrap, vaporwave, boom-bap\ntrap, vaporwave, chillwave\ntrap, vaporwave, chipmunk soul\ntrap, vaporwave, chiptune\ntrap, vaporwave, chopped and screwed\ntrap, vaporwave, choral\ntrap, vaporwave, cinematic\ntrap, vaporwave, cinematic hip hop\ntrap, vaporwave, cloud rap\ntrap, vaporwave, conscious hip-hop\ntrap, vaporwave, dancehall\ntrap, vaporwave, dark hip hop\ntrap, vaporwave, dark pop\ntrap, vaporwave, deep house\ntrap, vaporwave, dream pop\ntrap, vaporwave, dreamy\ntrap, vaporwave, drill\ntrap, vaporwave, electronic\ntrap, vaporwave, emo rap\ntrap, vaporwave, emotional\ntrap, vaporwave, emotional R&B\ntrap, vaporwave, emotional hip-hop\ntrap, vaporwave, emotional rap\ntrap, vaporwave, ethereal\ntrap, vaporwave, experimental\ntrap, vaporwave, experimental hip hop\ntrap, vaporwave, future bass\ntrap, vaporwave, future pop\ntrap, vaporwave, glitch\ntrap, vaporwave, gospel\ntrap, vaporwave, grime\ntrap, vaporwave, hardstyle\ntrap, vaporwave, hip hop\ntrap, vaporwave, hip-hop\ntrap, vaporwave, house\ntrap, vaporwave, hyperpop\ntrap, vaporwave, industrial\ntrap, vaporwave, jazz rap\ntrap, vaporwave, lo-fi\ntrap, vaporwave, lo-fi hip hop\ntrap, vaporwave, melancholic\ntrap, vaporwave, melodic hip hop\ntrap, vaporwave, melodic hip-hop\ntrap, vaporwave, melodic rap\ntrap, vaporwave, nu-metal\ntrap, vaporwave, orchestral\ntrap, vaporwave, pluggnb\ntrap, vaporwave, pop\ntrap, vaporwave, pop-R&B\ntrap, vaporwave, pop-trap\ntrap, vaporwave, pop/R&B\ntrap, vaporwave, psychedelic\ntrap, vaporwave, psychedelic R&B\ntrap, vaporwave, psychedelic rock\ntrap, vaporwave, punk\ntrap, vaporwave, punk rock\ntrap, vaporwave, rage\ntrap, vaporwave, rage rap\ntrap, vaporwave, reggae\ntrap, vaporwave, regional Mexican\ntrap, vaporwave, rock\ntrap, vaporwave, soul\ntrap, vaporwave, synthwave\ntrap, vaporwave, world music\ntrap, video game\ntrap, video game aesthetic\ntrap, video game music\ntrap, video game synth\ntrap, video game, Arabic hip hop\ntrap, video game, Chinese hip hop\ntrap, video game, Mandarin rap\ntrap, video game, Russian rap\ntrap, video game, aggressive\ntrap, video game, chiptune\ntrap, video game, cinematic\ntrap, video game, dark synth\ntrap, video game, hip hop\ntrap, video game, lo-fi\ntrap, video game, lo-fi hip hop\ntrap, video game, melodic rap\ntrap, video game, playful\ntrap, video game, quirky\ntrap, video game, soulful hip hop\ntrap, video game, southern hip hop\ntrap, video game, synth\ntrap, video game, synth pop\ntrap, villain theme\ntrap, violin fusion\ntrap, violin, Japanese hip hop\ntrap, vocalise, Middle Eastern\ntrap, vocaloid, ethereal\ntrap, west coast\ntrap, west coast hip hop\ntrap, west coast hip hop, melodic rap\ntrap, west coast hip-hop\ntrap, witch house\ntrap, witch house, experimental electronic\ntrap, witch house, hyperpop\ntrap, world drill\ntrap, world fusion\ntrap, world fusion, Italian hip hop\ntrap, world fusion, Middle Eastern\ntrap, world fusion, Moroccan hip-hop\ntrap, world fusion, Nigerian Pidgin\ntrap, world fusion, Turkish hip-hop\ntrap, world fusion, ambient\ntrap, world fusion, cinematic\ntrap, world fusion, cinematic hip-hop\ntrap, world fusion, experimental\ntrap, world fusion, hip-hop\ntrap, world fusion, instrumental\ntrap, world fusion, instrumental hip-hop\ntrap, world fusion, lo-fi hip hop\ntrap, world fusion, melodic rap\ntrap, world hip hop\ntrap, world music\ntrap, world music, C-pop\ntrap, world music, Chinese hip hop\ntrap, world music, Dutch rap\ntrap, world music, French rap\ntrap, world music, Hebrew rap\ntrap, world music, K-pop\ntrap, world music, Malay hip hop\ntrap, world music, Mandarin hip-hop\ntrap, world music, Middle Eastern\ntrap, world music, R&B\ntrap, world music, Russian hip hop\ntrap, world music, Turkish\ntrap, world music, afrobeats\ntrap, world music, ambient\ntrap, world music, cinematic\ntrap, world music, electronic\ntrap, world music, epic\ntrap, world music, ethereal\ntrap, world music, experimental\ntrap, world music, experimental hip-hop\ntrap, world music, hip hop\ntrap, world music, hip-hop\ntrap, world music, instrumental\ntrap, world music, lo-fi\ntrap, world music, lo-fi hip hop\ntrap, world music, melodic rap\ntrap, world music, melodic trap\ntrap, world music, pop\ntrap, world music, psychedelic\ntrap, world music, soul\ntrap, world percussion\ntrap, world pop\ntrap, world-trap\ntrap, worship, electronic\ntrap, wuxia, Chinese hip-hop\ntrap, wuxia, cinematic\ntrap, zouk, R&B\ntrap-EDM\ntrap-R&B\ntrap-R&B Balkan pop\ntrap-R&B Indian fusion\ntrap-R&B Mandopop\ntrap-R&B ambient pop\ntrap-R&B chillwave\ntrap-R&B chiptune\ntrap-R&B future bass\ntrap-R&B lo-fi\ntrap-R&B lo-fi hip-hop\ntrap-R&B pop-rock\ntrap-R&B vaporwave\ntrap-R&B, Afrobeats, cinematic\ntrap-R&B, Afrobeats, lo-fi\ntrap-R&B, Arabic pop, French rap\ntrap-R&B, C-pop\ntrap-R&B, Central Asian\ntrap-R&B, Chinese fusion\ntrap-R&B, Chinese pop\ntrap-R&B, EDM, cinematic\ntrap-R&B, East Asian fusion\ntrap-R&B, J-pop, lo-fi hip hop\ntrap-R&B, Latin pop\ntrap-R&B, Punjabi folk\ntrap-R&B, South Asian fusion\ntrap-R&B, South Indian film music\ntrap-R&B, alternative rock, nu-metal\ntrap-R&B, chillwave\ntrap-R&B, chillwave, global pop\ntrap-R&B, chillwave, lo-fi\ntrap-R&B, cinematic\ntrap-R&B, cinematic Arabic\ntrap-R&B, cinematic pop, hard rock\ntrap-R&B, cinematic, Chinese aesthetics\ntrap-R&B, cloud rap\ntrap-R&B, cloud rap, C-Pop\ntrap-R&B, cloud rap, C-pop\ntrap-R&B, cloud rap, Mandopop\ntrap-R&B, cloud rap, atmospheric R&B\ntrap-R&B, cloud rap, contemporary R&B\ntrap-R&B, cloud rap, emo rap\ntrap-R&B, cloud rap, lo-fi\ntrap-R&B, dance-pop, Middle Eastern\ntrap-R&B, dark pop\ntrap-R&B, deep house, ambient\ntrap-R&B, emo-rock\ntrap-R&B, ethereal pop\ntrap-R&B, future bass, ambient\ntrap-R&B, future bass, hyperpop\ntrap-R&B, future bass, rock\ntrap-R&B, hyperpop, cloud rap\ntrap-R&B, hyperpop, lo-fi\ntrap-R&B, lo-fi R&B, Indian classical\ntrap-R&B, lo-fi, glitch-hop\ntrap-R&B, neo-soul\ntrap-R&B, nu-metal, cinematic\ntrap-R&B, pop-punk, emo-rock\ntrap-R&B, rock, hip-hop\ntrap-R&B, synth-pop, Korean R&B\ntrap-corrido\ntrap-dancehall\ntrap-folk\ntrap-funk\ntrap-gospel\ntrap-hop\ntrap-hop, Chinese fusion\ntrap-manele\ntrap-metal\ntrap-metal, Chinese fusion, cinematic\ntrap-metal, nu-metal, metalcore\ntrap-pop\ntrap-pop Balkan fusion\ntrap-pop Bhojpuri folk\ntrap-pop C-pop\ntrap-pop C-pop R&B\ntrap-pop C-pop anime\ntrap-pop C-pop cloud rap\ntrap-pop Indian folk\ntrap-pop R&B cinematic\ntrap-pop alternative rock\ntrap-pop baroque\ntrap-pop chiptune\ntrap-pop emo rap\ntrap-pop future bass\ntrap-pop garage rock\ntrap-pop hyperpop\ntrap-pop kuthu\ntrap-pop lo-fi\ntrap-pop rock\ntrap-pop vaporwave\ntrap-pop, Azerbaijani, emotional\ntrap-pop, Balkan folk\ntrap-pop, Balkan fusion\ntrap-pop, C-pop\ntrap-pop, C-pop, R&B\ntrap-pop, C-pop, cinematic\ntrap-pop, C-pop, hyperpop\ntrap-pop, C-pop, lo-fi hip-hop\ntrap-pop, C-pop, traditional Chinese\ntrap-pop, Central Asian fusion\ntrap-pop, Chinese folk\ntrap-pop, Chinese fusion\ntrap-pop, Chinese fusion, cinematic\ntrap-pop, Chinese fusion, rock\ntrap-pop, Chinese traditional, cinematic\ntrap-pop, Indian fusion\ntrap-pop, Latin acoustic, Russian vocal\ntrap-pop, Middle Eastern\ntrap-pop, Middle Eastern fusion\ntrap-pop, Middle Eastern fusion, Balkan\ntrap-pop, R&B, Romanian pop\ntrap-pop, R&B, ambient\ntrap-pop, South Asian folk\ntrap-pop, South Asian fusion\ntrap-pop, South Indian film music\ntrap-pop, Thai R&B\ntrap-pop, Turkish fusion\ntrap-pop, Vietnamese fusion\ntrap-pop, chiptune\ntrap-pop, cinematic\ntrap-pop, cinematic, Chinese aesthetic\ntrap-pop, cinematic, Chinese aesthetics\ntrap-pop, cinematic, East Asian\ntrap-pop, cinematic, world fusion\ntrap-pop, cloud rap, C-pop\ntrap-pop, cloud rap, emo rap\ntrap-pop, cloud rap, lo-fi\ntrap-pop, dark pop, C-pop\ntrap-pop, emo rap, R&B\ntrap-pop, emo rap, hyperpop\ntrap-pop, emo-pop, hyperpop\ntrap-pop, future bass, J-pop\ntrap-pop, future bass, cinematic\ntrap-pop, future bass, hyperpop\ntrap-pop, future bass, lo-fi\ntrap-pop, hyperpop\ntrap-pop, hyperpop, ambient\ntrap-pop, hyperpop, anime soundtrack\ntrap-pop, hyperpop, chiptune\ntrap-pop, hyperpop, cinematic\ntrap-pop, hyperpop, lo-fi\ntrap-pop, hyperpop, video game music\ntrap-pop, lo-fi hip hop\ntrap-pop, lo-fi hip-hop, C-pop\ntrap-pop, pop-rock, EDM\ntrap-pop, pop-rock, K-pop\ntrap-pop, power-ballad, pop-rock\ntrap-pop, reggaeton, ethnic fusion\ntrap-pop, reggaeton, moombahton\ntrap-pop, vaporwave, dream pop\ntrap-pop, world fusion\ntrap-punk\ntrap-r&b emo-rap\ntrap-rap\ntrap-rap alternative rock\ntrap-rap hardstyle\ntrap-rap, Celtic folk\ntrap-rap, Chinese fusion\ntrap-rap, German folk, electronic\ntrap-rap, J-rock\ntrap-rap, hyperpop, anime\ntrap-rap, piano ballad\ntrap-reggaeton\ntrap-reggaeton, hyperpop, rage\ntrap-rock\ntrap-rock nu-metal\ntrap-rock, Chinese fusion, cinematic\ntrap-rock, cinematic, anime\ntrap-soul\ntrap-soul C-pop\ntrap-soul C-pop R&B\ntrap-soul C-pop lo-fi\ntrap-soul Mandopop\ntrap-soul R&B\ntrap-soul alternative R&B\ntrap-soul ambient R&B\ntrap-soul ambient pop\ntrap-soul cloud rap\ntrap-soul emo rap\ntrap-soul emo-rap\ntrap-soul future bass\ntrap-soul lo-fi\ntrap-soul lo-fi R&B\ntrap-soul lo-fi hip-hop\ntrap-soul mandopop\ntrap-soul neo-soul\ntrap-soul reggae\ntrap-soul reggaeton\ntrap-soul vaporwave\ntrap-soul, Afrobeats, R&B\ntrap-soul, Filipino hip-hop\ntrap-soul, G-funk\ntrap-soul, R&B, Filipino pop\ntrap-soul, R&B, atmospheric\ntrap-soul, afrobeats\ntrap-soul, alternative R&B, atmospheric\ntrap-soul, chillwave, Filipino pop\ntrap-soul, dark R&B\ntrap-soul, dark pop, alternative R&B\ntrap-soul, downtempo R&B\ntrap-soul, drill, Punjabi\ntrap-soul, indie-pop\ntrap-soul, lo-fi hip-hop, French pop\ntrap-soul, lo-fi hip-hop, modern R&B\ntrap-soul, reggaeton\ntrap-soul, synth-pop\ntrapeton\ntribal\ntribal ambient\ntribal anthem\ntribal beat\ntribal blues\ntribal breakbeat\ntribal ceremonial\ntribal chant\ntribal chiptune\ntribal cinematic\ntribal cumbia\ntribal dance\ntribal dance-pop\ntribal dark ambient\ntribal devotional\ntribal drum\ntribal drum & bass\ntribal drum, hip hop, electronic\ntribal drumming\ntribal drumming industrial\ntribal drumming, hip hop, ambient\ntribal electronic\ntribal electronica\ntribal epic\ntribal folk\ntribal folk rock\ntribal folk-metal\ntribal folk-rock\ntribal funk\ntribal funk rock\ntribal fusion\ntribal gospel\ntribal groove\ntribal groove worldbeat\ntribal hip hop\ntribal hip-hop\ntribal house\ntribal house afro-house\ntribal house afrobeat\ntribal house ambient\ntribal house breakbeat\ntribal house cinematic\ntribal house ethnic electronica\ntribal house future bass\ntribal house gospel\ntribal house hip-hop\ntribal house industrial techno\ntribal house moombahton\ntribal house oud\ntribal house progressive trance\ntribal house reggaeton\ntribal house stadium rock\ntribal house techno\ntribal house world fusion\ntribal house world music\ntribal house worldbeat\ntribal house, Indian electronic\ntribal house, Indian folk\ntribal house, J-pop, electronic\ntribal house, Latin house, electronic\ntribal house, Middle Eastern\ntribal house, acid techno\ntribal house, bass house, dubstep\ntribal house, breakbeat, ambient\ntribal house, cinematic, Middle Eastern\ntribal house, cinematic, deep house\ntribal house, deep house\ntribal house, deep house, Latin American\ntribal house, deep house, Latin house\ntribal house, deep house, world music\ntribal house, deep tech house\ntribal house, electro house\ntribal house, electronic pop, world music\ntribal house, ethnic electronica\ntribal house, ethnic electronica, worldbeat\ntribal house, experimental electronic\ntribal house, experimental electronic, Brazilian folk\ntribal house, experimental electronic, Latin\ntribal house, hard techno, breakbeat\ntribal house, hard techno, psytrance\ntribal house, hardstyle\ntribal house, hardstyle, psytrance\ntribal house, industrial techno\ntribal house, melodic techno\ntribal house, minimal techno\ntribal house, progressive house\ntribal house, progressive house, ambient\ntribal house, progressive house, hardstyle\ntribal house, progressive psytrance, ambient\ntribal house, psychedelic trance\ntribal house, psytrance\ntribal house, psytrance, ambient\ntribal house, psytrance, hard trance\ntribal house, psytrance, hardstyle\ntribal house, tech house\ntribal house, tech-house, cinematic\ntribal house, worldbeat, electronic\ntribal house, worldbeat, pop-rap\ntribal industrial\ntribal metal\ntribal music\ntribal norteño\ntribal percussion\ntribal pop\ntribal pop-rock\ntribal psychedelic rock\ntribal psytrance\ntribal punk\ntribal reggaeton\ntribal ritual\ntribal rock\ntribal soul\ntribal tech house\ntribal techno\ntribal techno, hardstyle\ntribal techno, hardstyle, blues\ntribal trance\ntribal trap\ntribal trap world music\ntribal trap worldbeat\ntribal vocal\ntribal world\ntribal world music\ntribal-industrial\ntribal-pop\ntribal-pop, rap, electronic\ntrip hop\ntrip-hop\ntrip-hop Bollywood\ntrip-hop C-pop\ntrip-hop C-pop art pop\ntrip-hop French pop\ntrip-hop Indian classical\ntrip-hop Indian film music\ntrip-hop Indian folk\ntrip-hop Indian fusion\ntrip-hop Indian pop\ntrip-hop Latin\ntrip-hop Latin rock\ntrip-hop R&B\ntrip-hop Russian chanson\ntrip-hop acid jazz\ntrip-hop alt-rock\ntrip-hop alt-rock rap\ntrip-hop alternative R&B\ntrip-hop alternative hip-hop\ntrip-hop alternative metal\ntrip-hop alternative pop\ntrip-hop alternative rock\ntrip-hop alternative rock experimental\ntrip-hop ambient\ntrip-hop ambient R&B\ntrip-hop ambient alternative R&B\ntrip-hop ambient art pop\ntrip-hop ambient cinematic\ntrip-hop ambient jazz\ntrip-hop ambient lo-fi\ntrip-hop ambient pop\ntrip-hop arabesque\ntrip-hop art pop\ntrip-hop art pop breakbeat\ntrip-hop art pop flamenco\ntrip-hop art rock\ntrip-hop art-pop\ntrip-hop ballad\ntrip-hop ballad, pop-rock, blues-rock\ntrip-hop big beat\ntrip-hop big beat funk\ntrip-hop boom-bap\ntrip-hop bossa nova\ntrip-hop breakbeat\ntrip-hop breakcore\ntrip-hop cabaret\ntrip-hop chillwave\ntrip-hop chiptune\ntrip-hop cinematic\ntrip-hop cinematic ambient\ntrip-hop cinematic electronica\ntrip-hop cinematic pop\ntrip-hop classical\ntrip-hop dark R&B\ntrip-hop dark ambient\ntrip-hop dark ambient industrial\ntrip-hop dark pop\ntrip-hop dark pop alternative R&B\ntrip-hop darkwave\ntrip-hop deep house\ntrip-hop disco-funk\ntrip-hop downtempo\ntrip-hop downtempo art pop\ntrip-hop downtempo electronic\ntrip-hop downtempo electronica\ntrip-hop downtempo world music\ntrip-hop dream pop\ntrip-hop dream pop alternative R&B\ntrip-hop dream pop shoegaze\ntrip-hop dream-pop\ntrip-hop dream-pop post-rock\ntrip-hop drum and bass\ntrip-hop dubstep\ntrip-hop electro-pop\ntrip-hop electronic experimental hip-hop\ntrip-hop electronic world music\ntrip-hop electronica\ntrip-hop electronica experimental pop\ntrip-hop experimental\ntrip-hop experimental R&B\ntrip-hop experimental electronic\ntrip-hop experimental folk\ntrip-hop experimental hip-hop\ntrip-hop experimental pop\ntrip-hop experimental techno\ntrip-hop fado\ntrip-hop flamenco\ntrip-hop folk\ntrip-hop french pop\ntrip-hop funk\ntrip-hop funk rock\ntrip-hop funk-hop\ntrip-hop funk-rock\ntrip-hop future bass\ntrip-hop future garage\ntrip-hop future garage ambient pop\ntrip-hop future garage experimental R&B\ntrip-hop glitch\ntrip-hop glitch-hop\ntrip-hop glitch-hop neo-soul\ntrip-hop glitch-pop\ntrip-hop gospel\ntrip-hop gothic rock\ntrip-hop grime\ntrip-hop grunge\ntrip-hop hip-hop\ntrip-hop hip-hop experimental\ntrip-hop indie electronic\ntrip-hop indie pop\ntrip-hop indie pop dream-pop\ntrip-hop indie rock\ntrip-hop industrial\ntrip-hop industrial metal\ntrip-hop industrial rock\ntrip-hop industrial rock jazz-fusion\ntrip-hop industrial rock psychedelic rock\ntrip-hop instrumental\ntrip-hop jazz\ntrip-hop jazz fusion\ntrip-hop jazz noir\ntrip-hop jazz-funk\ntrip-hop jungle\ntrip-hop latin\ntrip-hop lo-fi\ntrip-hop lo-fi ambient\ntrip-hop lo-fi hip hop\ntrip-hop lo-fi hip-hop\ntrip-hop lo-fi house\ntrip-hop lo-fi house ambient\ntrip-hop lo-fi indie\ntrip-hop lo-fi pop\ntrip-hop lounge\ntrip-hop lounge hip-hop\ntrip-hop lounge-jazz\ntrip-hop mandopop\ntrip-hop mandopop pop-rock\ntrip-hop metalcore\ntrip-hop neo-soul\ntrip-hop neo-soul acid jazz\ntrip-hop noir\ntrip-hop noir jazz\ntrip-hop noir-jazz\ntrip-hop noise rock\ntrip-hop noise-rock\ntrip-hop nu-disco\ntrip-hop nu-jazz\ntrip-hop nu-metal\ntrip-hop orchestral\ntrip-hop pop\ntrip-hop pop ballad\ntrip-hop pop-rock\ntrip-hop post-hardcore\ntrip-hop post-metal\ntrip-hop post-rock\ntrip-hop progressive rock\ntrip-hop psychedelic\ntrip-hop psychedelic funk\ntrip-hop psychedelic rock\ntrip-hop psychedelic soul\ntrip-hop punk rock\ntrip-hop rock\ntrip-hop rock fusion\ntrip-hop shoegaze\ntrip-hop shoegaze alternative rock\ntrip-hop soul\ntrip-hop soul jazz\ntrip-hop soul world music\ntrip-hop synth-pop\ntrip-hop techno\ntrip-hop trap\ntrip-hop vaporwave\ntrip-hop world fusion\ntrip-hop world music\ntrip-hop world music alternative rock\ntrip-hop worldbeat\ntrip-hop worship\ntrip-hop, Anatolian rock, lo-fi hip-hop\ntrip-hop, Anatolian, downtempo\ntrip-hop, Arabic devotional, ambient\ntrip-hop, Arabic electronica, ambient\ntrip-hop, Arabic fusion, ambient\ntrip-hop, Arabic fusion, ambient rock\ntrip-hop, Arabic fusion, cinematic\ntrip-hop, Arabic pop, ambient\ntrip-hop, Arabic, atmospheric\ntrip-hop, Azerbaijani fusion, electronic\ntrip-hop, Balkan, ney flute\ntrip-hop, Bollywood, ambient\ntrip-hop, Brazilian electronica\ntrip-hop, Brazilian funk\ntrip-hop, Brazilian hip-hop\ntrip-hop, Brazilian, lo-fi\ntrip-hop, C-pop\ntrip-hop, C-pop, ambient\ntrip-hop, C-pop, electronic\ntrip-hop, Chinese ambient, cinematic\ntrip-hop, Chinese electronic\ntrip-hop, European cabaret\ntrip-hop, French indie pop\ntrip-hop, IDM, ambient\ntrip-hop, Indian classical, ambient\ntrip-hop, Indian classical, atmospheric\ntrip-hop, Indian classical, cinematic\ntrip-hop, Indian classical, funk\ntrip-hop, Indian electronic, industrial trap\ntrip-hop, Indian film music, downtempo\ntrip-hop, Indian folk, downtempo\ntrip-hop, Indian fusion, ambient rock\ntrip-hop, Indian pop, downtempo\ntrip-hop, J-rock, ambient\ntrip-hop, J-rock, cinematic\ntrip-hop, Latin jazz, flamenco fusion\ntrip-hop, Latin jazz, soulful sax\ntrip-hop, Latin, ambient\ntrip-hop, Latin, deep house\ntrip-hop, Latin, psychedelic\ntrip-hop, Middle Eastern fusion\ntrip-hop, Middle Eastern fusion, cinematic\ntrip-hop, Middle Eastern, ambient\ntrip-hop, Middle Eastern, cinematic\ntrip-hop, Middle Eastern, downtempo\ntrip-hop, Middle Eastern, electronic\ntrip-hop, Mongolian folk, ambient\ntrip-hop, Persian, industrial trap\ntrip-hop, R&B\ntrip-hop, R&B, Indian classical\ntrip-hop, R&B, cinematic\ntrip-hop, R&B, electronic\ntrip-hop, R&B, electronic pop\ntrip-hop, R&B, experimental pop\ntrip-hop, R&B, house\ntrip-hop, R&B, lo-fi\ntrip-hop, Russian chanson, downtempo\ntrip-hop, Slavic folk, ambient\ntrip-hop, South Asian pop\ntrip-hop, Turkish alternative pop, ambient\ntrip-hop, Turkish alternative pop, downtempo\ntrip-hop, Turkish alternative rock\ntrip-hop, Turkish ambient, electronic\ntrip-hop, Turkish folk\ntrip-hop, Turkish folk, ambient\ntrip-hop, Turkish folk, atmospheric\ntrip-hop, Turkish folk, cinematic\ntrip-hop, Turkish folk, deep groove\ntrip-hop, Turkish folk, downtempo\ntrip-hop, Turkish fusion\ntrip-hop, Turkish fusion, cinematic\ntrip-hop, Turkish fusion, electronic\ntrip-hop, Turkish pop\ntrip-hop, Turkish pop, cinematic\ntrip-hop, Turkish, cinematic\ntrip-hop, UK hip-hop\ntrip-hop, acid jazz, Turkish rap\ntrip-hop, acid jazz, boom-bap\ntrip-hop, acid jazz, cinematic lounge\ntrip-hop, acid jazz, instrumental hip-hop\ntrip-hop, acid jazz, lo-fi hip hop\ntrip-hop, acid jazz, lounge\ntrip-hop, alternative R&B\ntrip-hop, alternative R&B, UK hip-hop\ntrip-hop, alternative R&B, cinematic\ntrip-hop, alternative R&B, psychedelic\ntrip-hop, alternative pop, electronic\ntrip-hop, alternative pop-rock\ntrip-hop, alternative rock\ntrip-hop, alternative rock, C-pop\ntrip-hop, alternative rock, K-pop\ntrip-hop, alternative rock, blues-rock\ntrip-hop, alternative rock, cinematic\ntrip-hop, alternative rock, lo-fi hip hop\ntrip-hop, alternative rock, metalcore\ntrip-hop, alternative rock, noise rock\ntrip-hop, alternative rock, psychedelic\ntrip-hop, alternative rock, rap\ntrip-hop, ambient electronic, future pop\ntrip-hop, ambient pop, C-pop\ntrip-hop, ambient techno\ntrip-hop, ambient techno, emotional electronic\ntrip-hop, ambient, Ancient Style\ntrip-hop, ambient, Bengali ethereal\ntrip-hop, ambient, C-pop\ntrip-hop, ambient, Central Asian folk\ntrip-hop, ambient, Chinese electronic\ntrip-hop, ambient, Chinese ethereal\ntrip-hop, ambient, Chinese experimental\ntrip-hop, ambient, Chinese indie\ntrip-hop, ambient, Chinese lo-fi\ntrip-hop, ambient, Chinese pop\ntrip-hop, ambient, Chinese spiritual\ntrip-hop, ambient, Chinese traditional\ntrip-hop, ambient, Hindi soul\ntrip-hop, ambient, Indian classical\ntrip-hop, ambient, Indian devotional\ntrip-hop, ambient, Indian electronic\ntrip-hop, ambient, Indian electronica\ntrip-hop, ambient, Indian fusion\ntrip-hop, ambient, K-pop\ntrip-hop, ambient, Middle Eastern\ntrip-hop, ambient, Mongolian folk\ntrip-hop, ambient, Persian\ntrip-hop, ambient, South Asian classical\ntrip-hop, ambient, South Asian fusion\ntrip-hop, ambient, Turkish folk\ntrip-hop, ambient, chiptune\ntrip-hop, ambient, cinematic\ntrip-hop, ambient, downtempo\ntrip-hop, ambient, drum and bass\ntrip-hop, ambient, electronic\ntrip-hop, ambient, ethereal\ntrip-hop, ambient, ethnic fusion\ntrip-hop, ambient, future garage\ntrip-hop, ambient, hardstyle\ntrip-hop, ambient, industrial\ntrip-hop, ambient, industrial rock\ntrip-hop, ambient, jazz fusion\ntrip-hop, ambient, lo-fi\ntrip-hop, ambient, melodic techno\ntrip-hop, ambient, mystical\ntrip-hop, ambient, ney flute\ntrip-hop, ambient, spiritual\ntrip-hop, ambient, synth-pop\ntrip-hop, ambient, world fusion\ntrip-hop, arabesque, cinematic\ntrip-hop, art pop\ntrip-hop, art pop, C-pop\ntrip-hop, art pop, ambient\ntrip-hop, art pop, experimental electronic\ntrip-hop, art pop, glitch\ntrip-hop, art pop, lo-fi\ntrip-hop, art-pop, ambient\ntrip-hop, art-pop, cinematic\ntrip-hop, art-pop, lo-fi hip-hop\ntrip-hop, art-rock, cinematic\ntrip-hop, art-rock, psychedelic\ntrip-hop, big beat, R&B\ntrip-hop, big beat, breakbeat\ntrip-hop, big beat, cinematic\ntrip-hop, big beat, electronic pop\ntrip-hop, boom-bap\ntrip-hop, breakbeat, ambient\ntrip-hop, breakbeat, ambient electronic\ntrip-hop, breakcore, ambient\ntrip-hop, breakcore, experimental\ntrip-hop, breakcore, hardstyle\ntrip-hop, breakcore, psychedelic\ntrip-hop, breakcore, rap-metal\ntrip-hop, cabaret, nu-disco\ntrip-hop, chanson, lo-fi\ntrip-hop, chiptune, ambient\ntrip-hop, chiptune, industrial techno\ntrip-hop, cinematic folk\ntrip-hop, cinematic hip-hop, melancholic\ntrip-hop, cinematic pop, neo-soul\ntrip-hop, cinematic rock\ntrip-hop, cinematic rock, ambient\ntrip-hop, cinematic rock, gospel\ntrip-hop, cinematic, Arabic ambient\ntrip-hop, cinematic, Arabic fusion\ntrip-hop, cinematic, Arabic opera\ntrip-hop, cinematic, Balkan\ntrip-hop, cinematic, C-pop\ntrip-hop, cinematic, Chinese ambient\ntrip-hop, cinematic, Eastern fusion\ntrip-hop, cinematic, Gregorian\ntrip-hop, cinematic, Hebrew pop\ntrip-hop, cinematic, Hindi electronic\ntrip-hop, cinematic, Indian classical\ntrip-hop, cinematic, Indian fusion\ntrip-hop, cinematic, Javanese folk\ntrip-hop, cinematic, K-pop\ntrip-hop, cinematic, Latin fusion\ntrip-hop, cinematic, Middle Eastern\ntrip-hop, cinematic, Persian\ntrip-hop, cinematic, Persian ambient\ntrip-hop, cinematic, Persian folk\ntrip-hop, cinematic, Tamil folk\ntrip-hop, cinematic, Turkish ambient\ntrip-hop, cinematic, Turkish folk\ntrip-hop, cinematic, Turkish fusion\ntrip-hop, cinematic, Turkish pop\ntrip-hop, cinematic, Vietnamese ballad\ntrip-hop, cinematic, a cappella\ntrip-hop, cinematic, ambient\ntrip-hop, cinematic, choral\ntrip-hop, cinematic, dark ambient\ntrip-hop, cinematic, downtempo\ntrip-hop, cinematic, drum and bass\ntrip-hop, cinematic, electronic\ntrip-hop, cinematic, epic\ntrip-hop, cinematic, ethereal\ntrip-hop, cinematic, experimental\ntrip-hop, cinematic, folk\ntrip-hop, cinematic, ghazal\ntrip-hop, cinematic, industrial\ntrip-hop, cinematic, jazz\ntrip-hop, cinematic, jazz-fusion\ntrip-hop, cinematic, klezmer\ntrip-hop, cinematic, lo-fi\ntrip-hop, cinematic, lo-fi hip hop\ntrip-hop, cinematic, neo-soul\ntrip-hop, cinematic, operatic\ntrip-hop, cinematic, orchestral\ntrip-hop, cinematic, oud\ntrip-hop, cinematic, progressive house\ntrip-hop, cinematic, rock\ntrip-hop, cinematic, rock opera\ntrip-hop, cinematic, soul\ntrip-hop, cinematic, spiritual\ntrip-hop, cinematic, world fusion\ntrip-hop, cinematic, world music\ntrip-hop, city pop\ntrip-hop, city pop, ambient\ntrip-hop, classical Turkish, emotive\ntrip-hop, classical fusion, Turkish folk\ntrip-hop, classical, Latin\ntrip-hop, cloud rap\ntrip-hop, conscious hip-hop\ntrip-hop, conscious hip-hop, electronic\ntrip-hop, conscious hip-hop, ethereal\ntrip-hop, cumbia, norteño\ntrip-hop, cyberpunk, ambient\ntrip-hop, dark ambient\ntrip-hop, dark ambient, R&B\ntrip-hop, dark ambient, industrial\ntrip-hop, dark ambient, industrial rock\ntrip-hop, dark ambient, ritual electronic\ntrip-hop, dark pop\ntrip-hop, dark pop, electronic rock\ntrip-hop, dark pop, industrial\ntrip-hop, dark techno, hardstyle\ntrip-hop, darkwave, industrial rock\ntrip-hop, deep house, UK garage\ntrip-hop, deep house, ambient\ntrip-hop, deep house, cinematic\ntrip-hop, deep house, psychedelic\ntrip-hop, devotional, electronic\ntrip-hop, downtempo\ntrip-hop, downtempo, Azerbaijani folk\ntrip-hop, downtempo, Brazilian pop\ntrip-hop, downtempo, C-pop\ntrip-hop, downtempo, Greek\ntrip-hop, downtempo, Middle Eastern\ntrip-hop, downtempo, Persian ambient\ntrip-hop, downtempo, Turkish folk\ntrip-hop, downtempo, Turkish pop\ntrip-hop, downtempo, alternative rock\ntrip-hop, downtempo, cinematic\ntrip-hop, downtempo, dark pop\ntrip-hop, downtempo, experimental electronic\ntrip-hop, downtempo, indie pop\ntrip-hop, downtempo, psychedelic rock\ntrip-hop, downtempo, world fusion\ntrip-hop, dream pop, J-rock\ntrip-hop, dream pop, ambient\ntrip-hop, dream pop, lo-fi hip hop\ntrip-hop, dream-pop, French electronic\ntrip-hop, dream-pop, ambient\ntrip-hop, dream-pop, cinematic\ntrip-hop, dream-pop, electronic\ntrip-hop, dream-pop, lo-fi hip hop\ntrip-hop, dreamy, downtempo\ntrip-hop, drum and bass\ntrip-hop, drum and bass, ambient\ntrip-hop, drum and bass, cinematic\ntrip-hop, drum and bass, lo-fi\ntrip-hop, drum and bass, neurofunk\ntrip-hop, drum and bass, old-school hip-hop\ntrip-hop, drum and bass, world music\ntrip-hop, dubstep, C-pop\ntrip-hop, dubstep, ambient\ntrip-hop, dubstep, lo-fi\ntrip-hop, duduk, Turkish folk\ntrip-hop, electro-pop, folk-electronic\ntrip-hop, electronic folk, ambient\ntrip-hop, electronic pop, ambient\ntrip-hop, electronic pop, melancholic\ntrip-hop, electronic rock, ambient\ntrip-hop, electronic rock, cinematic\ntrip-hop, electronic rock, future bass\ntrip-hop, electronic, Chinese hip hop\ntrip-hop, electronic, K-pop\ntrip-hop, electronic, Russian folk\ntrip-hop, electronic, Russian vocal\ntrip-hop, electronic, ambient\ntrip-hop, electronic, cinematic\ntrip-hop, electronic, dark pop\ntrip-hop, electronic, experimental\ntrip-hop, electronic, glitch\ntrip-hop, electronic, gospel\ntrip-hop, electronic, world music\ntrip-hop, ethereal wave\ntrip-hop, ethereal, Arabic electronic\ntrip-hop, ethereal, Arabic vocal\ntrip-hop, ethereal, C-pop\ntrip-hop, ethereal, Middle Eastern fusion\ntrip-hop, ethereal, Persian ambient\ntrip-hop, ethereal, Russian vocal\ntrip-hop, ethereal, ambient\ntrip-hop, ethereal, cinematic\ntrip-hop, ethereal, world music\ntrip-hop, ethnic trap, dark ambient\ntrip-hop, eurodance, cinematic\ntrip-hop, experimental electronic\ntrip-hop, experimental electronic, C-pop\ntrip-hop, experimental electronic, ambient\ntrip-hop, experimental hip-hop, lo-fi\ntrip-hop, experimental pop\ntrip-hop, experimental pop, world music\ntrip-hop, experimental, Indian classical\ntrip-hop, experimental, ambient\ntrip-hop, experimental, electronic\ntrip-hop, experimental, lo-fi\ntrip-hop, experimental, lo-fi hip hop\ntrip-hop, experimental, trap\ntrip-hop, flamenco, lo-fi hip hop\ntrip-hop, flamenco, operatic\ntrip-hop, folk rock, microtonal\ntrip-hop, folk, ambient\ntrip-hop, folk, electronic\ntrip-hop, funk fusion, Thai electronic\ntrip-hop, funk-rock, dub\ntrip-hop, future bass\ntrip-hop, future bass, C-pop\ntrip-hop, future bass, Korean pop\ntrip-hop, future bass, R&B\ntrip-hop, future bass, South Asian\ntrip-hop, future bass, ambient\ntrip-hop, future bass, chiptune\ntrip-hop, future bass, cinematic\ntrip-hop, future bass, cinematic pop\ntrip-hop, future bass, dream pop\ntrip-hop, future bass, glitch-hop\ntrip-hop, future bass, gospel\ntrip-hop, future bass, hyperpop\ntrip-hop, future bass, lo-fi\ntrip-hop, future bass, lo-fi hip hop\ntrip-hop, future bass, soulful\ntrip-hop, future garage, ambient\ntrip-hop, ghazal, ambient\ntrip-hop, ghazal, electronic\ntrip-hop, ghazal, lo-fi\ntrip-hop, glitch, ambient\ntrip-hop, glitch, cinematic\ntrip-hop, glitch, industrial\ntrip-hop, glitch-hop, C-pop\ntrip-hop, glitch-hop, ambient\ntrip-hop, glitch-hop, cinematic\ntrip-hop, glitch-hop, lo-fi\ntrip-hop, glitch-hop, neo-soul\ntrip-hop, gospel, rock\ntrip-hop, hardstyle\ntrip-hop, hardstyle, ambient\ntrip-hop, hardstyle, chiptune\ntrip-hop, hardwave\ntrip-hop, hip hop, nu-metal\ntrip-hop, hip hop, trap\ntrip-hop, hip-hop\ntrip-hop, hip-hop, Chinese ambient\ntrip-hop, hip-hop, ambient\ntrip-hop, hip-hop, blues\ntrip-hop, hybrid trap, dubstep\ntrip-hop, hyperpop\ntrip-hop, indie electronic\ntrip-hop, indie folk\ntrip-hop, industrial drum and bass, cinematic\ntrip-hop, industrial electronic, C-pop\ntrip-hop, industrial electronic, hip-hop\ntrip-hop, industrial hip-hop\ntrip-hop, industrial rock\ntrip-hop, industrial rock, Lithuanian vocal\ntrip-hop, industrial rock, ambient\ntrip-hop, industrial rock, cinematic\ntrip-hop, industrial rock, electronic\ntrip-hop, industrial rock, ethereal\ntrip-hop, industrial rock, lo-fi\ntrip-hop, industrial rock, nu-metal\ntrip-hop, industrial rock, psychedelic\ntrip-hop, industrial techno, ambient\ntrip-hop, industrial, ambient\ntrip-hop, industrial, cinematic\ntrip-hop, industrial, electronic rock\ntrip-hop, industrial, lo-fi\ntrip-hop, jazz, C-pop\ntrip-hop, jungle, drum and bass\ntrip-hop, latin, psychedelic\ntrip-hop, liquid drum and bass, ambient\ntrip-hop, lo-fi hip hop\ntrip-hop, lo-fi hip hop, Arabic fusion\ntrip-hop, lo-fi hip hop, Chinese ambient\ntrip-hop, lo-fi hip hop, Korean pop\ntrip-hop, lo-fi hip hop, Latin\ntrip-hop, lo-fi hip hop, Latin alternative\ntrip-hop, lo-fi hip hop, Middle Eastern\ntrip-hop, lo-fi hip hop, Russian hip hop\ntrip-hop, lo-fi hip hop, Russian rap\ntrip-hop, lo-fi hip hop, Turkish pop\ntrip-hop, lo-fi hip hop, ambient\ntrip-hop, lo-fi hip hop, art-pop\ntrip-hop, lo-fi hip hop, atmospheric\ntrip-hop, lo-fi hip hop, bilingual\ntrip-hop, lo-fi hip hop, cinematic\ntrip-hop, lo-fi hip hop, experimental\ntrip-hop, lo-fi hip hop, jazz lounge\ntrip-hop, lo-fi hip hop, neo-soul\ntrip-hop, lo-fi hip hop, psychedelic\ntrip-hop, lo-fi hip-hop, Latin pop\ntrip-hop, lo-fi hip-hop, ambient\ntrip-hop, lo-fi hip-hop, cinematic\ntrip-hop, lo-fi hip-hop, dream pop\ntrip-hop, lo-fi hip-hop, industrial rock\ntrip-hop, lo-fi indie pop\ntrip-hop, lo-fi, Balkan jazz\ntrip-hop, lo-fi, C-pop\ntrip-hop, lo-fi, Chinese hip hop\ntrip-hop, lo-fi, R&B\ntrip-hop, lo-fi, UK garage\ntrip-hop, lo-fi, ambient\ntrip-hop, lo-fi, cinematic\ntrip-hop, lo-fi, dark ambient\ntrip-hop, lo-fi, dream-pop\ntrip-hop, lo-fi, dubstep\ntrip-hop, lo-fi, experimental\ntrip-hop, lo-fi, hard rock\ntrip-hop, lo-fi, indie rock\ntrip-hop, lo-fi, psychedelic\ntrip-hop, lo-fi, techno\ntrip-hop, lo-fi, trap\ntrip-hop, lo-fi, world fusion\ntrip-hop, lounge, nu-disco\ntrip-hop, lounge, oud\ntrip-hop, minimal techno, ambient\ntrip-hop, neo-classical, cinematic\ntrip-hop, neo-soul, French hip-hop\ntrip-hop, neo-soul, Spanish\ntrip-hop, neo-soul, alternative hip-hop\ntrip-hop, neo-soul, ambient\ntrip-hop, neo-soul, noise rock\ntrip-hop, neurofunk\ntrip-hop, neurofunk, ambient\ntrip-hop, neurofunk, drum and bass\ntrip-hop, new age, world music\ntrip-hop, noir, ambient\ntrip-hop, noise rock\ntrip-hop, noise rock, lo-fi\ntrip-hop, noise-rock\ntrip-hop, nu-disco\ntrip-hop, nu-disco, ambient\ntrip-hop, nu-disco, dream pop\ntrip-hop, nu-disco, experimental\ntrip-hop, nu-disco, psychedelic\ntrip-hop, nu-metal, cinematic\ntrip-hop, nu-metal, emotional pop\ntrip-hop, orchestral, gospel\ntrip-hop, oud, Russian vocal\ntrip-hop, oud, cinematic\ntrip-hop, oud, downtempo\ntrip-hop, phonk, hardstyle\ntrip-hop, pop, Turkish\ntrip-hop, pop, electronic\ntrip-hop, pop-rock, C-pop\ntrip-hop, pop-rock, Latin\ntrip-hop, pop-rock, R&B\ntrip-hop, pop-rock, ambient\ntrip-hop, pop-rock, blues-rock\ntrip-hop, pop-rock, cinematic\ntrip-hop, pop-rock, electronic\ntrip-hop, pop-rock, hip-hop\ntrip-hop, pop-rock, industrial rock\ntrip-hop, pop-rock, nu-metal\ntrip-hop, pop-rock, psychedelic\ntrip-hop, pop-rock, symphonic rock\ntrip-hop, post-rock, C-pop\ntrip-hop, post-rock, French indie\ntrip-hop, post-rock, ambient\ntrip-hop, post-rock, cinematic\ntrip-hop, post-rock, dream-pop\ntrip-hop, progressive house, ambient\ntrip-hop, progressive house, cinematic\ntrip-hop, progressive house, lo-fi\ntrip-hop, progressive house, trance\ntrip-hop, psychedelic cumbia\ntrip-hop, psychedelic folk\ntrip-hop, psychedelic rock\ntrip-hop, psychedelic rock, Arabic pop\ntrip-hop, psychedelic rock, Turkish folk\ntrip-hop, psychedelic rock, cinematic\ntrip-hop, psychedelic rock, industrial rock\ntrip-hop, psychedelic soul, boom-bap\ntrip-hop, psychedelic, Middle Eastern fusion\ntrip-hop, psychedelic, ambient\ntrip-hop, psychedelic, conscious hip-hop\ntrip-hop, psychedelic, dream-pop\ntrip-hop, psychedelic, operatic\ntrip-hop, psychedelic, world fusion\ntrip-hop, psytrance, soulful\ntrip-hop, reggae-dub, multilingual\ntrip-hop, reggaeton, dream pop\ntrip-hop, reggaeton, lo-fi\ntrip-hop, reggaeton, spiritual\ntrip-hop, rock, R&B\ntrip-hop, rock, ambient\ntrip-hop, rock, orchestral\ntrip-hop, sad Turkish pop, lo-fi hip hop\ntrip-hop, shoegaze, C-pop\ntrip-hop, shoegaze, K-pop\ntrip-hop, shoegaze, Vietnamese pop\ntrip-hop, shoegaze, ambient\ntrip-hop, shoegaze, electronic\ntrip-hop, shoegaze, lo-fi\ntrip-hop, shoegaze, post-rock\ntrip-hop, soul, cinematic\ntrip-hop, soulful hip-hop, cinematic\ntrip-hop, spiritual electronic\ntrip-hop, spiritual, Indian devotional\ntrip-hop, spiritual, ambient\ntrip-hop, symphonic metal\ntrip-hop, symphonic metal, C-pop\ntrip-hop, symphonic rock\ntrip-hop, symphonic rock, ambient\ntrip-hop, synth-pop, C-pop\ntrip-hop, synth-pop, Cantopop\ntrip-hop, synth-pop, ambient\ntrip-hop, synth-pop, classical\ntrip-hop, synth-pop, dream pop\ntrip-hop, synthwave, cinematic\ntrip-hop, trap, ambient\ntrip-hop, trap, cinematic\ntrip-hop, trap, experimental\ntrip-hop, trap, glitch-hop\ntrip-hop, trap, lo-fi\ntrip-hop, vaporwave, hip-hop\ntrip-hop, vaporwave, lo-fi\ntrip-hop, world fusion, ambient\ntrip-hop, world fusion, electronic\ntrip-hop, world fusion, lo-fi hip hop\ntrip-hop, world fusion, progressive techno\ntrip-hop, world music\ntrip-hop, world music, ambient\ntrip-hop, world music, atmospheric pop\ntrip-hop, world music, cinematic\ntrip-hop, world music, lo-fi\ntrip-hop, world music, lo-fi hip hop\ntrip-hop, world music, new age\ntrip-hop, world music, pop-rock\ntrip-hop, world music, smooth jazz\ntriumphant house\ntropical\ntropical C-pop\ntropical Christmas\ntropical French pop\ntropical K-pop\ntropical Latin\ntropical Latin pop\ntropical Mandopop\ntropical R&B\ntropical R&B afrobeats\ntropical R&B future bass\ntropical V-pop\ntropical acoustic\ntropical acoustic pop\ntropical ambient\ntropical bachata\ntropical blues\ntropical blues-rock\ntropical bossa nova\ntropical calypso\ntropical chiptune\ntropical country\ntropical country rock\ntropical country-pop\ntropical country-rock\ntropical cumbia\ntropical cumbia-pop\ntropical dance\ntropical dance-pop\ntropical dance-pop Afrobeat\ntropical dance-pop chiptune\ntropical dance-pop reggaeton\ntropical dancehall\ntropical disco-pop\ntropical folk\ntropical folk-pop\ntropical funk\ntropical funk-pop\ntropical fusion\ntropical future bass\ntropical gospel\ntropical hip hop\ntropical hip-hop\ntropical house\ntropical house C-pop\ntropical house K-pop\ntropical house Mandopop\ntropical house OPM\ntropical house R&B\ntropical house V-pop\ntropical house afrobeat\ntropical house afrobeat pop\ntropical house afrobeats\ntropical house afrobeats conscious hip-hop\ntropical house afrobeats dance-pop\ntropical house afrobeats pop\ntropical house ambient pop\ntropical house bhangra dance-pop\ntropical house chillwave\ntropical house chiptune\ntropical house city pop\ntropical house dance-pop\ntropical house dancehall\ntropical house deep house\ntropical house funk\ntropical house future bass\ntropical house future bass dance-pop\ntropical house german pop-rap\ntropical house indie pop\ntropical house j-pop\ntropical house latin pop\ntropical house lo-fi hip-hop\ntropical house lounge\ntropical house moombahton\ntropical house nu-disco\ntropical house pop\ntropical house pop-rap\ntropical house pop-reggae\ntropical house pop-soul\ntropical house reggaeton\ntropical house synth-pop\ntropical house ukulele pop\ntropical house world music\ntropical house worldbeat\ntropical house, C-pop\ntropical house, EDM, dance-pop\ntropical house, Filipino pop\ntropical house, Latin dance\ntropical house, Latin house\ntropical house, Latin pop\ntropical house, Mandopop\ntropical house, Middle Eastern electronic\ntropical house, V-pop\ntropical house, afrobeat, French pop\ntropical house, afrobeat, future bass\ntropical house, big room house\ntropical house, chiptune, electronic\ntropical house, dance-pop\ntropical house, dance-pop, V-Pop\ntropical house, deep house, ambient\ntropical house, future bass\ntropical house, future bass, cinematic pop\ntropical house, melbourne bounce\ntropical house, moombahton\ntropical house, moombahton, Bollywood pop\ntropical house, moombahton, EDM\ntropical house, moombahton, Middle Eastern\ntropical house, moombahton, electronic dance\ntropical house, moombahton, pop-rap\ntropical house, nu-disco, funk\ntropical house, reggaeton, dance-pop\ntropical house, slap house\ntropical house, synth-pop\ntropical house, world fusion, electronic\ntropical indie-pop\ntropical instrumental\ntropical kids\ntropical kizomba\ntropical lo-fi\ntropical lounge\ntropical lounge jazz\ntropical lullaby\ntropical mambo\ntropical new wave\ntropical novelty\ntropical pop\ntropical pop Afrobeat\ntropical pop R&B\ntropical pop afrobeat\ntropical pop afrobeats\ntropical pop afrobeats R&B\ntropical pop afrobeats dancehall\ntropical pop afrobeats zouk\ntropical pop afropop dancehall\ntropical pop bossa nova\ntropical pop city pop\ntropical pop country-funk\ntropical pop cumbia\ntropical pop dancehall\ntropical pop exotica\ntropical pop future bass\ntropical pop gospel\ntropical pop kizomba\ntropical pop novelty\ntropical pop reggae\ntropical pop reggae fusion\ntropical pop reggaeton\ntropical pop salsa\ntropical pop smooth jazz\ntropical pop soca\ntropical pop surf rock\ntropical pop worldbeat\ntropical pop zouk\ntropical pop, Afrobeat\ntropical pop, Afrobeats, French pop\ntropical pop, Afrobeats, dancehall\ntropical pop, Latin pop\ntropical pop, pop-rock\ntropical pop, reggaeton\ntropical pop-R&B\ntropical pop-funk\ntropical pop-rap\ntropical pop-reggae\ntropical pop-reggaeton\ntropical pop-rock\ntropical pop-trap\ntropical punk rock\ntropical reggae\ntropical reggae-pop\ntropical reggaeton\ntropical rock\ntropical rock country-pop\ntropical salsa\ntropical show tune\ntropical soca\ntropical soul\ntropical swing\ntropical synth\ntropical synth-pop\ntropical trap\ntropical ukulele\ntropical video game\ntropical world music\ntropical world-pop\ntropical worldbeat\ntropical zouk\ntropical zouk afrobeats\ntropical zouk afropop\ntropical zouk kompa\ntropical zouk soca\ntropical zouk, kompa, chiptune\ntrot\ntrot Latin\ntrot ballad\ntrot big band\ntrot blues-rock\ntrot chiptune\ntrot city pop\ntrot dance-pop\ntrot disco\ntrot disco funk\ntrot electronic\ntrot eurobeat\ntrot eurodance\ntrot folk\ntrot funk pop\ntrot funk soul\ntrot funk-rock\ntrot fusion\ntrot music\ntrot orchestral\ntrot pop\ntrot pop-rock\ntrot rock\ntrot rockabilly\ntrot surf rock\ntrot swing\ntrot synth-pop\ntrot, Latin, dance\ntrot, Latin, world folk\ntrot, big band, cinematic\ntrot, big band, dance\ntrot, big band, rock\ntrot, big band, swing\ntrot, big band, theatrical\ntrot, blues, rockabilly\ntrot, chanson\ntrot, chanson, cinematic\ntrot, chiptune\ntrot, chiptune, electronic\ntrot, chiptune, rock\ntrot, cinematic, melancholic\ntrot, disco, synth\ntrot, disco-funk\ntrot, eurodance\ntrot, happy hardcore\ntrot, latin, disco\ntrot, orchestral, cinematic\ntrot, pop ballad\ntrot, pop-rock, 80s-inspired\ntrot, retro dance-pop\ntrot, retro disco\ntrot, retro, chiptune\ntrot, retro, electronic\ntrot, synth-pop\ntrot, synth-pop, disco\ntrot-cha-cha\ntrot-disco\ntrot-pop\ntrot-pop, dance, electronic\ntrot-rock\ntrot-rock big band\ntrot-rock dance-pop\ntrot-rock fusion\ntrot-ska\ntrot-soul\ntrot-swing\ntrot-tango\ntumbados\nturbo-folk\nturbo-folk chalga\nturbo-folk chiptune\nturbo-folk dance-pop\nturbo-folk disco\nturbo-folk electronic\nturbo-folk electronic rock\nturbo-folk ethno-folk\nturbo-folk eurodance\nturbo-folk happy hardcore\nturbo-folk hardstyle\nturbo-folk industrial rock\nturbo-folk metal\nturbo-folk polka\nturbo-folk pop-rock\nturbo-folk power metal\nturbo-folk punk\nturbo-folk punk rock\nturbo-folk rap-rock\nturbo-folk rock\nturbo-folk rockabilly\nturbo-folk ska-punk\nturbo-folk speed metal\nturbo-folk surf rock\nturbo-folk synth-pop\nturbo-folk synth-rock\nturbo-folk trap\nturbo-folk turbo-fusion\nturbo-folk, Eurodance\nturbo-folk, Latin dance-pop\nturbo-folk, chiptune, electronic\nturbo-folk, chiptune, eurodance\nturbo-folk, electronic dance\nturbo-folk, electronic dance music\nturbo-folk, eurodance\nturbo-folk, eurodance, happy hardcore\nturbo-folk, happy hardcore\nturbo-folk, hard dance\nturbo-folk, trap, Balkan pop\nturntablism\nturntablism hip hop\nturntablism hip-hop\ntwerk bounce\ntwist\ntwist dance\ntwist dance rock\ntwist rock\ntwist rock and roll\nukulele\nukulele ballad\nukulele blues\nukulele ensemble\nukulele folk\nukulele instrumental\nukulele jazz\nukulele jingle\nukulele loop\nukulele lullaby\nukulele music gypsy jazz\nukulele orchestral\nukulele pop\nukulele pop reggae funk\nukulele pop, South Indian folk, cinematic\nukulele pop, trap\nukulele pop-rap\nukulele pop-rock\nukulele ska\nukulele ska, baile funk\nukulele solo\nukulele trap\nukulele virtuosity\nukulele virtuoso\nukulele, bossa nova, whimsical\nukulele, glockenspiel, cheerful\nukulele, glockenspiel, whimsical\nukulele-pop\nukulele-trap\nunderground Desi hip-hop\nunderground German battle rap\nunderground Latin hip-hop\nunderground Russian hip-hop\nunderground Turkish hip-hop\nunderground boom-bap\nunderground hip hop\nunderground hip-hop\nunderground hip-hop chiptune\nunderground hip-hop, trap\nunderground hip-hop, trap, orchestral hip-hop\nunderground rap\nunderground techno\nunderground trap\nupbeat\nupbeat Afro-pop\nupbeat C-pop\nupbeat Christmas\nupbeat EDM\nupbeat Latin pop\nupbeat R&B\nupbeat acoustic\nupbeat anthem\nupbeat brass\nupbeat brass pop\nupbeat corporate\nupbeat dance\nupbeat electronic\nupbeat festive\nupbeat flute\nupbeat folk\nupbeat folk pop\nupbeat folk synth\nupbeat funk\nupbeat gospel\nupbeat groove\nupbeat house\nupbeat indie\nupbeat instrumental\nupbeat jazz\nupbeat jazz funk\nupbeat jingle\nupbeat library music\nupbeat lo-fi\nupbeat lounge\nupbeat march\nupbeat orchestral\nupbeat pagode\nupbeat piano\nupbeat piano funk\nupbeat piano rock\nupbeat pop\nupbeat pop gospel\nupbeat pop kizomba\nupbeat pop world music\nupbeat pop, Balkan pop\nupbeat pop, Balkan pop, synth pop\nupbeat pop, Central Asian, retro\nupbeat pop, Eastern European, Turkish\nupbeat pop, Eastern European, accordion\nupbeat pop, Middle Eastern, Eastern European\nupbeat pop, Southeast Asian pop\nupbeat pop, Southeast Asian, nostalgic\nupbeat pop, electronic dance, patriotic\nupbeat pop, worldbeat, empowering\nupbeat pop-rock\nupbeat ragtime\nupbeat rock\nupbeat synth\nupbeat synth pop\nupbeat synth-brass\nupbeat synthpop\nupbeat tropical\nupbeat ukulele\nupbeat ukulele pop\nupbeat video game\nupbeat video game music\nupbeat world music\nupbeat, festive, steel pan\nupbeat, festive, synth\nupbeat, festive, synthpop\nupbeat, hypnotic, instrumental\nupbeat, instrumental, Asian fusion\nupbeat, instrumental, steel drum\nupbeat, quirky, cinematic\nupbeat, quirky, retro\nuplifting\nuplifting EDM\nuplifting R&B\nuplifting acoustic\nuplifting ambient\nuplifting background\nuplifting cinematic\nuplifting corporate\nuplifting devotional\nuplifting electronic\nuplifting folk\nuplifting hip-hop\nuplifting house\nuplifting indie\nuplifting indie rock\nuplifting indie-pop\nuplifting instrumental\nuplifting jazz\nuplifting jingle\nuplifting piano\nuplifting pop\nuplifting pop R&B\nuplifting pop ballad\nuplifting pop world music\nuplifting pop, Middle Eastern pop\nuplifting pop-anthem\nuplifting pop-rock\nuplifting rock\nuplifting synth\nuplifting synth pop\nuplifting trance\nuplifting trance hands-up\nuplifting trance, chiptune\nuplifting ukulele\nupright piano\nupright piano, cheerful, birthday\nupright piano, cheerful, jingle\nupright piano, lounge, upbeat\nupright piano, ragtime, cinematic\nupright piano, ragtime, playful\nupright piano, ragtime, video game music\nurban C-pop\nurban Latin\nurban Latin pop\nurban Mandopop\nurban R&B\nurban alt-rock\nurban anthem\nurban beat\nurban beatbox\nurban cumbia\nurban electronic\nurban flamenco\nurban folk\nurban funk\nurban fusion\nurban hip hop\nurban hip-hop\nurban hip-hop, Indian fusion\nurban pop\nurban pop flamenco\nurban pop hip-hop\nurban pop reggaeton\nurban pop-R&B\nurban pop-rap\nurban pop-trap\nurban reggae\nurban rock\nurban trap\nurban world music\nurban, dembow, hyperpop\nurban, glitch, electronic\nvallenato\nvallenato cumbia\nvallenato lo-fi\nvaneira\nvapor trap\nvapor-trap\nvaporwave\nvaporwave C-pop\nvaporwave C-pop R&B\nvaporwave C-pop trap\nvaporwave J-pop\nvaporwave R&B\nvaporwave R&B hip-hop\nvaporwave R&B lo-fi hip-hop\nvaporwave R&B trap\nvaporwave afro-trap\nvaporwave afrobeat\nvaporwave afrobeats\nvaporwave alternative rock\nvaporwave ambient\nvaporwave baile funk\nvaporwave boom-bap\nvaporwave breakcore\nvaporwave chillhop\nvaporwave chillwave\nvaporwave chiptune\nvaporwave city pop\nvaporwave darkwave\nvaporwave deep house\nvaporwave dembow\nvaporwave dream-pop\nvaporwave drill\nvaporwave electro-funk\nvaporwave electropop\nvaporwave emo rap\nvaporwave emo-rap\nvaporwave funk\nvaporwave future R&B\nvaporwave future bass\nvaporwave future funk\nvaporwave future garage\nvaporwave g-funk\nvaporwave glitch-hop\nvaporwave hip hop\nvaporwave hip-hop\nvaporwave hip-hop indie rock\nvaporwave hip-hop nu-metal\nvaporwave hip-hop synth-pop\nvaporwave house\nvaporwave indie dance\nvaporwave indie pop\nvaporwave indie rock\nvaporwave indie-pop\nvaporwave j-pop\nvaporwave jungle\nvaporwave lo-fi\nvaporwave lo-fi ambient\nvaporwave lo-fi hip hop\nvaporwave lo-fi hip-hop\nvaporwave lo-fi house chiptune\nvaporwave lo-fi trap\nvaporwave lounge\nvaporwave metalcore\nvaporwave neo-soul\nvaporwave nu-disco\nvaporwave nu-funk\nvaporwave nu-jazz\nvaporwave phonk\nvaporwave plunderphonics\nvaporwave pop\nvaporwave pop-r&b\nvaporwave pop-rap\nvaporwave pop-rock\nvaporwave reggaeton\nvaporwave reggaeton lo-fi\nvaporwave rock\nvaporwave rock hip-hop\nvaporwave soul\nvaporwave synth-funk\nvaporwave synth-pop\nvaporwave synthwave\nvaporwave techno\nvaporwave trap\nvaporwave trap R&B\nvaporwave trap hardcore techno\nvaporwave trap metal\nvaporwave trap soul\nvaporwave trap-R&B\nvaporwave trap-pop\nvaporwave trap-r&b\nvaporwave trap-soul\nvaporwave trip-hop\nvaporwave, 2000s R&B, hip-hop\nvaporwave, 90s R&B, new jack swing\nvaporwave, 90s R&B, synth-pop\nvaporwave, 90s hip-hop\nvaporwave, Brazilian funk\nvaporwave, Brazilian funk, electropop\nvaporwave, Brazilian funk, lo-fi hip hop\nvaporwave, Brazilian funk, melodic rap\nvaporwave, Brazilian funk, trap\nvaporwave, Brazilian funk, trap-metal\nvaporwave, Brazilian hip-hop\nvaporwave, Brazilian trap\nvaporwave, Brazilian trap, cloud rap\nvaporwave, Brazilian trap, lo-fi\nvaporwave, Brazilian trap, lo-fi hip hop\nvaporwave, C-pop\nvaporwave, C-pop, R&B\nvaporwave, C-pop, lo-fi hip-hop\nvaporwave, C-pop, trap\nvaporwave, C-pop, trap-pop\nvaporwave, EDM, Tamil pop\nvaporwave, EDM, synthwave\nvaporwave, French drill\nvaporwave, French hip-hop\nvaporwave, French hip-hop, electronic rock\nvaporwave, French hip-hop, lo-fi\nvaporwave, French rap\nvaporwave, French rap, electronic\nvaporwave, French trap\nvaporwave, French trap, R&B\nvaporwave, French trap, lo-fi hip hop\nvaporwave, G-funk\nvaporwave, G-funk, lo-fi hip hop\nvaporwave, German rap, synth-pop\nvaporwave, German trap\nvaporwave, Italian pop-rock\nvaporwave, Italo disco, synth-pop\nvaporwave, J-Pop, R&B\nvaporwave, J-hip-hop\nvaporwave, J-pop\nvaporwave, J-pop, hip-hop\nvaporwave, J-pop, hyperpop\nvaporwave, J-pop, lo-fi\nvaporwave, J-pop, trap\nvaporwave, J-rock\nvaporwave, K-R&B\nvaporwave, K-R&B, lo-fi\nvaporwave, Latin R&B, chiptune\nvaporwave, Latin R&B, lo-fi\nvaporwave, Latin R&B, reggaeton\nvaporwave, Latin R&B, trap\nvaporwave, Latin trap\nvaporwave, Latin trap, cinematic hip hop\nvaporwave, Latin trap, cloud rap\nvaporwave, Latin trap, lo-fi\nvaporwave, Latin trap, reggaeton\nvaporwave, Mandopop\nvaporwave, Mandopop, R&B\nvaporwave, R&B\nvaporwave, R&B, Brazilian funk\nvaporwave, R&B, C-pop\nvaporwave, R&B, Latin pop\nvaporwave, R&B, UK garage\nvaporwave, R&B, ambient\nvaporwave, R&B, baile funk\nvaporwave, R&B, cinematic\nvaporwave, R&B, downtempo\nvaporwave, R&B, dubstep\nvaporwave, R&B, electronic\nvaporwave, R&B, future bass\nvaporwave, R&B, hip-hop\nvaporwave, R&B, hyperpop\nvaporwave, R&B, lo-fi\nvaporwave, R&B, lo-fi hip hop\nvaporwave, R&B, pop\nvaporwave, R&B, synth-pop\nvaporwave, R&B, synthwave\nvaporwave, R&B, trap\nvaporwave, R&B, trap-soul\nvaporwave, Romanian trap\nvaporwave, Russian hip-hop\nvaporwave, Russian pop-rap\nvaporwave, Russian trap\nvaporwave, Southern hip-hop\nvaporwave, Southern hip-hop, dreamy R&B\nvaporwave, Turkish trap\nvaporwave, UK drill\nvaporwave, UK drill, cloud rap\nvaporwave, UK drill, lo-fi hip hop\nvaporwave, UK drill, trap\nvaporwave, UK garage\nvaporwave, UK garage, lo-fi\nvaporwave, UK garage, lo-fi hip hop\nvaporwave, UK hip-hop\nvaporwave, V-Pop, trap-R&B\nvaporwave, afro-trap\nvaporwave, afrobeats, dream pop\nvaporwave, afrobeats, lo-fi hip hop\nvaporwave, alternative R&B, lo-fi hip hop\nvaporwave, ambient\nvaporwave, ambient electronic\nvaporwave, ambient pop, Chinese electronic\nvaporwave, ambient pop, Latin trap\nvaporwave, ambient pop, trap R&B\nvaporwave, ambient trap\nvaporwave, ambient trap, melodic rap\nvaporwave, ambient, C-pop\nvaporwave, ambient, Chinese pop\nvaporwave, ambient, Indian melancholy\nvaporwave, ambient, chiptune\nvaporwave, ambient, electronic\nvaporwave, ambient, experimental\nvaporwave, ambient, industrial\nvaporwave, ambient, lo-fi\nvaporwave, ambient, synthwave\nvaporwave, art pop, electronic\nvaporwave, baile funk\nvaporwave, baile funk, dream pop\nvaporwave, bass house, R&B\nvaporwave, bedroom pop, alternative R&B\nvaporwave, blues-rock, lo-fi hip hop\nvaporwave, boom-bap\nvaporwave, boom-bap hip-hop\nvaporwave, boom-bap, Chinese hip hop\nvaporwave, boom-bap, Chinese hip-hop\nvaporwave, boom-bap, Chinese rap\nvaporwave, boom-bap, French rap\nvaporwave, boom-bap, German hip hop\nvaporwave, boom-bap, Italian hip hop\nvaporwave, boom-bap, Latin hip hop\nvaporwave, boom-bap, R&B\nvaporwave, boom-bap, Spanish rap\nvaporwave, boom-bap, ambient\nvaporwave, boom-bap, chill hop\nvaporwave, boom-bap, future rap\nvaporwave, boom-bap, hip hop\nvaporwave, boom-bap, lo-fi hip hop\nvaporwave, boom-bap, synthwave\nvaporwave, boom-bap, trap\nvaporwave, breakbeat\nvaporwave, breakbeat, ambient\nvaporwave, breakbeat, house\nvaporwave, breakcore, nightcore\nvaporwave, chill trap\nvaporwave, chill trap, cloud rap\nvaporwave, chillwave, alternative R&B\nvaporwave, chillwave, city pop\nvaporwave, chillwave, trap\nvaporwave, chiptune\nvaporwave, chiptune, progressive house\nvaporwave, chiptune, synthpop\nvaporwave, chopped and screwed, R&B\nvaporwave, cinematic\nvaporwave, cinematic hip hop, K-pop\nvaporwave, cinematic, ambient\nvaporwave, city pop\nvaporwave, city pop, R&B\nvaporwave, city pop, funk\nvaporwave, city pop, indie pop\nvaporwave, city pop, lo-fi R&B\nvaporwave, city pop, lo-fi hip hop\nvaporwave, city pop, nu-disco\nvaporwave, city pop, synth-pop\nvaporwave, cloud rap\nvaporwave, cloud rap, Brazilian trap\nvaporwave, cloud rap, C-pop\nvaporwave, cloud rap, Dutch hip-hop\nvaporwave, cloud rap, French cloud rap\nvaporwave, cloud rap, French trap\nvaporwave, cloud rap, German emo-rap\nvaporwave, cloud rap, German hip-hop\nvaporwave, cloud rap, J-pop\nvaporwave, cloud rap, Latin trap\nvaporwave, cloud rap, R&B\nvaporwave, cloud rap, alternative R&B\nvaporwave, cloud rap, ambient R&B\nvaporwave, cloud rap, ambient trap\nvaporwave, cloud rap, anime\nvaporwave, cloud rap, atmospheric trap\nvaporwave, cloud rap, chillwave\nvaporwave, cloud rap, darkwave\nvaporwave, cloud rap, emo rap\nvaporwave, cloud rap, emo trap\nvaporwave, cloud rap, hip-hop\nvaporwave, cloud rap, hyperpop\nvaporwave, cloud rap, lo-fi hip hop\nvaporwave, cloud rap, lo-fi hip-hop\nvaporwave, cloud rap, lo-fi trap\nvaporwave, cloud rap, melodic trap\nvaporwave, cloud rap, pluggnb\nvaporwave, cloud rap, trap\nvaporwave, color bass, melodic riddim\nvaporwave, complextro, dubstep\nvaporwave, complextro, soulful electronic\nvaporwave, conscious hip-hop\nvaporwave, dance-pop\nvaporwave, dance-pop, C-pop\nvaporwave, dance-pop, R&B\nvaporwave, dancehall, afro-fusion\nvaporwave, dancehall, lo-fi\nvaporwave, dark ambient\nvaporwave, deep house\nvaporwave, deep house, R&B\nvaporwave, deep house, UK garage\nvaporwave, deep house, ambient\nvaporwave, dembow, lo-fi hip hop\nvaporwave, downtempo, lo-fi hip hop\nvaporwave, dream pop, C-pop\nvaporwave, dream pop, Italo-disco\nvaporwave, dream pop, electropop\nvaporwave, dream pop, indie pop\nvaporwave, dream pop, lo-fi\nvaporwave, dream pop, neo-soul\nvaporwave, dream pop, synth-pop\nvaporwave, dream pop, trap\nvaporwave, drum and bass\nvaporwave, drum and bass, R&B\nvaporwave, drum and bass, ambient\nvaporwave, drum and bass, hyperpop\nvaporwave, drum and bass, lo-fi\nvaporwave, drum and bass, neurofunk\nvaporwave, drum and bass, synth-pop\nvaporwave, electro house\nvaporwave, electro-funk\nvaporwave, electro-funk, jazz-fusion\nvaporwave, electronic\nvaporwave, electronic pop, hip hop\nvaporwave, electronic pop, hip-hop\nvaporwave, electronic, Arabic hip hop\nvaporwave, electronic, Arabic pop\nvaporwave, electronic, C-pop\nvaporwave, electronic, German rap\nvaporwave, electronic, Greek pop\nvaporwave, electronic, K-pop\nvaporwave, electronic, Khmer pop\nvaporwave, electronic, Latin pop\nvaporwave, electronic, Mandopop\nvaporwave, electronic, Polish rap\nvaporwave, electronic, R&B\nvaporwave, electronic, Russian hip hop\nvaporwave, electronic, ambient\nvaporwave, electronic, dream pop\nvaporwave, electronic, experimental\nvaporwave, electronic, hip hop\nvaporwave, electronic, industrial\nvaporwave, electronic, lo-fi\nvaporwave, electronic, lo-fi hip hop\nvaporwave, electronic, pop\nvaporwave, electronic, trap\nvaporwave, electropop\nvaporwave, emo rap, cloud rap\nvaporwave, emo rap, hyperpop\nvaporwave, emo rap, pop-trap\nvaporwave, emo-pop, lo-fi\nvaporwave, experimental electronic\nvaporwave, folk-pop\nvaporwave, french house, synth-pop\nvaporwave, funk carioca\nvaporwave, funk carioca, hyperpop\nvaporwave, funk carioca, lo-fi R&B\nvaporwave, funk carioca, lo-fi hip hop\nvaporwave, funk carioca, pop-R&B\nvaporwave, funk soul\nvaporwave, funk, R&B\nvaporwave, funk, experimental electronic\nvaporwave, funk, hip-hop\nvaporwave, funk, lo-fi\nvaporwave, funk, synthpop\nvaporwave, funk-pop, city pop\nvaporwave, future bass\nvaporwave, future bass, C-pop\nvaporwave, future bass, Mandopop\nvaporwave, future bass, R&B\nvaporwave, future bass, ambient\nvaporwave, future bass, atmospheric pop\nvaporwave, future bass, cinematic pop\nvaporwave, future bass, dream pop\nvaporwave, future bass, dubstep\nvaporwave, future bass, electronic\nvaporwave, future bass, emotional synth-pop\nvaporwave, future bass, glitch-hop\nvaporwave, future bass, hard dance\nvaporwave, future bass, hyperpop\nvaporwave, future bass, kawaii\nvaporwave, future bass, liquid dnb\nvaporwave, future bass, lo-fi\nvaporwave, future bass, lo-fi hip hop\nvaporwave, future bass, lo-fi hip-hop\nvaporwave, future bass, pop\nvaporwave, future bass, pop-R&B\nvaporwave, future bass, pop-hip hop\nvaporwave, future bass, pop-rock\nvaporwave, future bass, progressive house\nvaporwave, future bass, synth-pop\nvaporwave, future funk\nvaporwave, future funk, chiptune\nvaporwave, g-funk, lo-fi hip hop\nvaporwave, glitch, ambient\nvaporwave, glitch, cinematic\nvaporwave, glitch-hop, dubstep\nvaporwave, hardstyle\nvaporwave, hardstyle, R&B\nvaporwave, hardstyle, big room house\nvaporwave, hardstyle, happy hardcore\nvaporwave, hardstyle, hip-hop\nvaporwave, hardstyle, lo-fi hip hop\nvaporwave, hardstyle, trance\nvaporwave, hip hop\nvaporwave, hip hop, dream pop\nvaporwave, hip hop, electronic\nvaporwave, hip-hop\nvaporwave, hip-hop, French rap\nvaporwave, hip-hop, J-pop\nvaporwave, hip-hop, K-pop\nvaporwave, hip-hop, R&B\nvaporwave, hip-hop, alternative rock\nvaporwave, hip-hop, ambient\nvaporwave, hip-hop, cinematic\nvaporwave, hip-hop, industrial metal\nvaporwave, hip-hop, lo-fi\nvaporwave, hip-hop, neo-soul\nvaporwave, hip-hop, pop-R&B\nvaporwave, hip-hop, synth-pop\nvaporwave, house, R&B\nvaporwave, house, lo-fi\nvaporwave, house, trance\nvaporwave, hyperpop\nvaporwave, hyperpop, C-pop\nvaporwave, hyperpop, cloud rap\nvaporwave, hyperpop, dubstep\nvaporwave, hyperpop, future bass\nvaporwave, hyperpop, hardstyle\nvaporwave, hyperpop, lo-fi hip hop\nvaporwave, hyperpop, trap\nvaporwave, indie R&B, hip hop\nvaporwave, indie dance, lo-fi\nvaporwave, indie dance, lo-fi hip hop\nvaporwave, indie pop\nvaporwave, indie-pop, shoegaze\nvaporwave, indie-pop, synth-pop\nvaporwave, industrial hip hop\nvaporwave, industrial rock\nvaporwave, industrial, hip hop\nvaporwave, jazz fusion\nvaporwave, jungle, breakcore\nvaporwave, jungle, electronic\nvaporwave, latin trap\nvaporwave, latin trap, dream pop\nvaporwave, lo-fi\nvaporwave, lo-fi R&B\nvaporwave, lo-fi electronic\nvaporwave, lo-fi electronic, synthwave\nvaporwave, lo-fi hip hop\nvaporwave, lo-fi hip hop, Arabic trap\nvaporwave, lo-fi hip hop, Brazilian funk\nvaporwave, lo-fi hip hop, Brazilian hip hop\nvaporwave, lo-fi hip hop, Brazilian rap\nvaporwave, lo-fi hip hop, C-pop\nvaporwave, lo-fi hip hop, Chinese electronic\nvaporwave, lo-fi hip hop, Chinese pop\nvaporwave, lo-fi hip hop, Chinese rap\nvaporwave, lo-fi hip hop, Chinese trap\nvaporwave, lo-fi hip hop, Czech rap\nvaporwave, lo-fi hip hop, French R&B\nvaporwave, lo-fi hip hop, French rap\nvaporwave, lo-fi hip hop, French trap\nvaporwave, lo-fi hip hop, German rap\nvaporwave, lo-fi hip hop, J-rap\nvaporwave, lo-fi hip hop, Japanese R&B\nvaporwave, lo-fi hip hop, Latin rap\nvaporwave, lo-fi hip hop, Persian trap\nvaporwave, lo-fi hip hop, R&B\nvaporwave, lo-fi hip hop, Russian rap\nvaporwave, lo-fi hip hop, Spanish rap\nvaporwave, lo-fi hip hop, Swedish rap\nvaporwave, lo-fi hip hop, Tagalog rap\nvaporwave, lo-fi hip hop, ambient\nvaporwave, lo-fi hip hop, ambient trap\nvaporwave, lo-fi hip hop, chiptune\nvaporwave, lo-fi hip hop, chopped and screwed\nvaporwave, lo-fi hip hop, cinematic\nvaporwave, lo-fi hip hop, cloud rap\nvaporwave, lo-fi hip hop, dark trap\nvaporwave, lo-fi hip hop, dream pop\nvaporwave, lo-fi hip hop, electronic\nvaporwave, lo-fi hip hop, ethereal rap\nvaporwave, lo-fi hip hop, future bass\nvaporwave, lo-fi hip hop, hyperpop\nvaporwave, lo-fi hip hop, jazz\nvaporwave, lo-fi hip hop, jazz rap\nvaporwave, lo-fi hip hop, jazzy\nvaporwave, lo-fi hip hop, trap\nvaporwave, lo-fi hip hop, world fusion\nvaporwave, lo-fi hip-hop\nvaporwave, lo-fi hip-hop, J-rock\nvaporwave, lo-fi hip-hop, ambient pop\nvaporwave, lo-fi hip-hop, cloud rap\nvaporwave, lo-fi hip-hop, conscious boom-bap\nvaporwave, lo-fi hip-hop, dream pop\nvaporwave, lo-fi hip-hop, synth-pop\nvaporwave, lo-fi house\nvaporwave, lo-fi house, soulful synth\nvaporwave, lo-fi pop\nvaporwave, lo-fi synth pop\nvaporwave, lo-fi synth, C-pop\nvaporwave, lo-fi trap\nvaporwave, lo-fi trap, Arabic hip hop\nvaporwave, lo-fi trap, R&B\nvaporwave, lo-fi, C-pop\nvaporwave, lo-fi, Chinese electronic\nvaporwave, lo-fi, Chinese pop\nvaporwave, lo-fi, French hip hop\nvaporwave, lo-fi, Mandopop\nvaporwave, lo-fi, R&B\nvaporwave, lo-fi, ambient\nvaporwave, lo-fi, chiptune\nvaporwave, lo-fi, cinematic\nvaporwave, lo-fi, cloud rap\nvaporwave, lo-fi, dancehall\nvaporwave, lo-fi, electronic\nvaporwave, lo-fi, indie dance\nvaporwave, lo-fi, progressive house\nvaporwave, lo-fi, rock\nvaporwave, lo-fi, synth pop\nvaporwave, lo-fi, synth-pop\nvaporwave, lo-fi, synthwave\nvaporwave, lo-fi, trap\nvaporwave, melodic trap\nvaporwave, melodic trap, Chinese hip hop\nvaporwave, melodic trap, K-hip-hop\nvaporwave, metalcore, electronic pop\nvaporwave, modern R&B, trap\nvaporwave, neo-soul\nvaporwave, neo-soul, R&B\nvaporwave, neo-soul, acid jazz\nvaporwave, neo-soul, funk\nvaporwave, neo-soul, future bass\nvaporwave, neo-soul, future funk\nvaporwave, neo-soul, lo-fi hip hop\nvaporwave, neo-soul, trap\nvaporwave, neurofunk, lo-fi\nvaporwave, new jack swing, R&B\nvaporwave, nu-disco\nvaporwave, nu-disco, dream pop\nvaporwave, nu-disco, house\nvaporwave, nu-disco, lo-fi\nvaporwave, nu-disco, techno\nvaporwave, nu-metal, R&B\nvaporwave, nu-metal, hip-hop\nvaporwave, orchestral, trap\nvaporwave, phonk, trap\nvaporwave, pluggnb, trap\nvaporwave, pop, R&B\nvaporwave, pop, lo-fi hip hop\nvaporwave, pop, synthwave\nvaporwave, pop-R&B\nvaporwave, pop-R&B, electronic\nvaporwave, pop-R&B, hip-hop\nvaporwave, pop-R&B, trap\nvaporwave, pop-punk, hip-hop\nvaporwave, pop-rock, cinematic\nvaporwave, pop-rock, dubstep\nvaporwave, pop-rock, lo-fi hip hop\nvaporwave, pop-trap\nvaporwave, pop-trap, lo-fi\nvaporwave, progressive house\nvaporwave, progressive house, drum and bass\nvaporwave, progressive house, future bass\nvaporwave, psytrance, rap\nvaporwave, reggaeton\nvaporwave, reggaeton, Latin R&B\nvaporwave, reggaeton, R&B\nvaporwave, reggaeton, ambient\nvaporwave, reggaeton, cinematic\nvaporwave, reggaeton, dream pop\nvaporwave, reggaeton, electronic\nvaporwave, reggaeton, hyperpop\nvaporwave, reggaeton, lo-fi\nvaporwave, reggaeton, lo-fi hip hop\nvaporwave, reggaeton, lo-fi pop\nvaporwave, reggaeton, pop\nvaporwave, reggaeton, synth-pop\nvaporwave, reggaeton, trap\nvaporwave, reggaeton-trap, future bass\nvaporwave, retro-futuristic, electronic\nvaporwave, shoegaze, electronic\nvaporwave, shoegaze, lo-fi\nvaporwave, shoegaze, post-rock\nvaporwave, slap house, deep house\nvaporwave, symphonic rock\nvaporwave, synth pop, R&B\nvaporwave, synth-funk\nvaporwave, synth-funk, French R&B\nvaporwave, synth-funk, electro-funk\nvaporwave, synth-pop\nvaporwave, synth-pop, C-pop\nvaporwave, synth-pop, EDM\nvaporwave, synth-pop, Hindi pop\nvaporwave, synth-pop, R&B\nvaporwave, synth-pop, Russian rap\nvaporwave, synth-pop, Turkish pop\nvaporwave, synth-pop, ambient\nvaporwave, synth-pop, cloud rap\nvaporwave, synth-pop, electronic dance\nvaporwave, synth-pop, future bass\nvaporwave, synth-pop, hyperpop\nvaporwave, synth-pop, lo-fi\nvaporwave, synth-pop, lo-fi hip hop\nvaporwave, synth-pop, nu-disco\nvaporwave, synth-pop, retro-funk\nvaporwave, synthpop\nvaporwave, synthwave, French pop\nvaporwave, synthwave, ambient\nvaporwave, synthwave, electronic\nvaporwave, synthwave, emotional electronic\nvaporwave, synthwave, emotional synth\nvaporwave, synthwave, funk\nvaporwave, synthwave, hip-hop\nvaporwave, synthwave, lo-fi hip hop\nvaporwave, synthwave, psychedelic pop\nvaporwave, techno\nvaporwave, trance, electronic\nvaporwave, trap\nvaporwave, trap R&B\nvaporwave, trap metal, nu-metal\nvaporwave, trap soul\nvaporwave, trap soul, R&B\nvaporwave, trap, Afrobeat\nvaporwave, trap, Arabic hip hop\nvaporwave, trap, Arabic hip-hop\nvaporwave, trap, Arabic melodic rap\nvaporwave, trap, Arabic pop\nvaporwave, trap, Arabic rap\nvaporwave, trap, Brazilian funk\nvaporwave, trap, C-pop\nvaporwave, trap, Chinese hip hop\nvaporwave, trap, Chinese hip-hop\nvaporwave, trap, Chinese house\nvaporwave, trap, Chinese pop\nvaporwave, trap, Czech hip hop\nvaporwave, trap, Dutch pop\nvaporwave, trap, Filipino hip hop\nvaporwave, trap, Finnish rap\nvaporwave, trap, French melodic rap\nvaporwave, trap, French pop\nvaporwave, trap, French rap\nvaporwave, trap, German hip hop\nvaporwave, trap, German hip-hop\nvaporwave, trap, German pop\nvaporwave, trap, German rap\nvaporwave, trap, Greek hip hop\nvaporwave, trap, Italian rap\nvaporwave, trap, J-pop\nvaporwave, trap, J-rock\nvaporwave, trap, K-pop\nvaporwave, trap, K-rap\nvaporwave, trap, Latin hip hop\nvaporwave, trap, Latin pop\nvaporwave, trap, Latin trap\nvaporwave, trap, Mandarin pop\nvaporwave, trap, Mandarin rap\nvaporwave, trap, Mandopop\nvaporwave, trap, Mongolian hip-hop\nvaporwave, trap, Moroccan hip hop\nvaporwave, trap, North African hip-hop\nvaporwave, trap, Pinoy hip hop\nvaporwave, trap, Polish electronic\nvaporwave, trap, Polish hip hop\nvaporwave, trap, R&B\nvaporwave, trap, Russian chanson-rap\nvaporwave, trap, Russian hip hop\nvaporwave, trap, Russian rap\nvaporwave, trap, Thai pop\nvaporwave, trap, Turkish\nvaporwave, trap, alternative R&B\nvaporwave, trap, ambient\nvaporwave, trap, anime\nvaporwave, trap, bilingual\nvaporwave, trap, bilingual pop\nvaporwave, trap, boom-bap\nvaporwave, trap, chiptune\nvaporwave, trap, cinematic\nvaporwave, trap, cinematic hip hop\nvaporwave, trap, cloud rap\nvaporwave, trap, conscious hip-hop\nvaporwave, trap, dream pop\nvaporwave, trap, drum and bass\nvaporwave, trap, electronic\nvaporwave, trap, electronic pop\nvaporwave, trap, emo rap\nvaporwave, trap, emo-rap\nvaporwave, trap, emotional\nvaporwave, trap, emotional R&B\nvaporwave, trap, emotional pop\nvaporwave, trap, emotional rap\nvaporwave, trap, ethereal pop\nvaporwave, trap, experimental\nvaporwave, trap, future bass\nvaporwave, trap, future pop\nvaporwave, trap, gospel\nvaporwave, trap, hardstyle\nvaporwave, trap, hyperpop\nvaporwave, trap, lo-fi\nvaporwave, trap, lo-fi hip hop\nvaporwave, trap, mandopop\nvaporwave, trap, melodic rap\nvaporwave, trap, neo-soul\nvaporwave, trap, nightcore\nvaporwave, trap, phonk\nvaporwave, trap, pop\nvaporwave, trap, pop R&B\nvaporwave, trap, pop-punk\nvaporwave, trap, pop-rock\nvaporwave, trap, psychedelic rap\nvaporwave, trap, reggaeton\nvaporwave, trap, soul\nvaporwave, trap, synth-pop\nvaporwave, trap, synthpop\nvaporwave, trap, synthwave\nvaporwave, trap-R&B\nvaporwave, trap-R&B, J-pop\nvaporwave, trap-R&B, Thai pop\nvaporwave, trap-R&B, electronic pop\nvaporwave, trap-R&B, hyperpop\nvaporwave, trap-R&B, synth-pop\nvaporwave, trap-soul\nvaporwave, trap-soul, Dutch R&B\nvaporwave, trap-soul, R&B\nvaporwave, trap-soul, atmospheric R&B\nvaporwave, trap-soul, cloud rap\nvaporwave, trap-soul, lo-fi R&B\nvaporwave, trip-hop, C-pop\nvaporwave, trip-hop, German rap\nvaporwave, trip-hop, ambient\nvaporwave, trip-hop, dream pop\nvaporwave, trip-hop, lo-fi\nvaporwave, uk garage\nvaporwave, world fusion, electronic\nvaudeville\nvaudeville jazz\nvaudeville music hall\nvaudeville novelty\nvaudeville ragtime\nvaudeville rock\nvaudeville show tune\nvaudeville swing\nvaudeville, ragtime, boogie-woogie\nvaudeville, ragtime, musical theater\nvaudeville, ragtime, theatrical\nvaudevillian\nvaudevillian novelty\nvaudevillian show tune\nvibraphone\nvibraphone waltz\nvideo game\nvideo game OST\nvideo game ambient\nvideo game anthem\nvideo game boss battle\nvideo game boss music\nvideo game boss theme\nvideo game chime\nvideo game chiptune\nvideo game folk\nvideo game funk\nvideo game fusion\nvideo game hip-hop\nvideo game horror\nvideo game jingle\nvideo game lo-fi hip hop\nvideo game metal\nvideo game music\nvideo game music big band jazz\nvideo game music chiptune\nvideo game music cumbia\nvideo game music funk\nvideo game music funk breakbeat\nvideo game music funk disco\nvideo game music funk electronic\nvideo game music funk electronic breakbeat\nvideo game music funk electronic rock\nvideo game music funk fusion\nvideo game music funk fusion progressive rock\nvideo game music funk jazz fusion\nvideo game music funk orchestral pop\nvideo game music funk orchestral rock\nvideo game music funk rock\nvideo game music funk rock electronic\nvideo game music funk synth-pop\nvideo game music funk world fusion\nvideo game music funk-rock electronic\nvideo game music funk-rock fusion\nvideo game music funk-rock synth-pop\nvideo game music fusion jazz synth-pop\nvideo game music happy hardcore\nvideo game music jazz fusion artcore\nvideo game music jazz fusion progressive rock\nvideo game music lounge jazz\nvideo game music power metal\nvideo game music progressive rock\nvideo game music salsa\nvideo game music speed metal\nvideo game music speed metal drum and bass\nvideo game music, Latin jazz fusion, progressive house\nvideo game music, Latin jazz, electronic\nvideo game music, Latin jazz, funk\nvideo game music, Latin jazz, fusion\nvideo game music, Latin jazz, synth funk\nvideo game music, Latin jazz, synth fusion\nvideo game music, Latin jazz, synthpop\nvideo game music, artcore, symphonic rock\nvideo game music, artcore, trance\nvideo game music, breakbeat, synthwave\nvideo game music, early trance\nvideo game music, electronic rock\nvideo game music, electronic rock, chiptune\nvideo game music, eurobeat, happy hardcore\nvideo game music, funk fusion, electronic breakbeat\nvideo game music, funk fusion, electronic rock\nvideo game music, funk, electronic dance\nvideo game music, happy hardcore\nvideo game music, happy hardcore, Latin jazz\nvideo game music, happy hardcore, artcore\nvideo game music, happy hardcore, breakbeat\nvideo game music, happy hardcore, symphonic rock\nvideo game music, happy hardcore, trance\nvideo game music, hard rock, electronic\nvideo game music, hard rock, electronic dance music\nvideo game music, hard rock, synth-pop\nvideo game music, jazz fusion, progressive rock\nvideo game music, math rock, progressive metal\nvideo game music, new age, progressive electronic\nvideo game music, power metal, symphonic rock\nvideo game music, progressive metal, jazz fusion\nvideo game music, progressive rock, classical piano\nvideo game music, progressive rock, fusion\nvideo game music, progressive rock, jazz fusion\nvideo game music, speed metal, happy hardcore\nvideo game music, synth-pop, progressive rock\nvideo game music, synth-pop, trance\nvideo game music, trance, 90s Japanese\nvideo game music, trance, eurobeat\nvideo game music, trance, happy hardcore\nvideo game music, world fusion, funk\nvideo game orchestral\nvideo game pop\nvideo game rock\nvideo game score\nvideo game sound\nvideo game soundtrack\nvideo game soundtrack lounge jazz\nvideo game theme\nvillain laugh\nvillain show tune\nvillain tone\nvillancico\nvillancico chiptune\nvillancico cumbia\nvillancico flamenco\nvillancico lo-fi\nvillancico rumba\nvillancico, chiptune, festive\nvillancico, cumbia, Andean\nvillancico, electronic, festive\nvillancico, flamenco, festive\nvillancico, folk, Christmas\nvillancico, folk, Spanish Christmas\nvillancico, folk, cinematic\nvillancico, pop-rock, festive\nvillancico, rumba, flamenco\nvintage African funk\nvintage African rock\nvintage African rumba\nvintage Arabic pop\nvintage Bhangra\nvintage Bollywood\nvintage Brazilian\nvintage Brazilian rock\nvintage C-pop\nvintage Canto-pop\nvintage Cantopop\nvintage Chinese folk\nvintage Chinese swing\nvintage Christmas\nvintage Christmas ballad\nvintage Christmas jazz\nvintage Christmas pop\nvintage Christmas swing\nvintage Dutch pop\nvintage Dutch tango\nvintage European\nvintage European ballad\nvintage European cafe\nvintage European pop\nvintage Filipino pop\nvintage French pop\nvintage French rock\nvintage German rock 'n' roll\nvintage Greek rock\nvintage Hebrew children's\nvintage Indian film\nvintage Indian film music\nvintage Indian film score\nvintage Indonesian pop\nvintage Israeli children's\nvintage Israeli pop\nvintage Italian ballad\nvintage Italian children's\nvintage Italian children's music\nvintage Italian film score\nvintage Italian march\nvintage Italian pop\nvintage Italian pop, Latin, theatrical\nvintage Italian pop, rock and roll\nvintage Italian pop-rock\nvintage Italian rock\nvintage Italian swing\nvintage Japanese\nvintage Japanese rock\nvintage Japanese swing\nvintage Korean trot\nvintage Latin\nvintage Latin Christmas\nvintage Latin Cumbia\nvintage Latin cumbia\nvintage Latin folk\nvintage Latin pop\nvintage Latin rock\nvintage Mandopop\nvintage Mandopop Latin\nvintage Mandopop bossa nova\nvintage Mandopop exotica\nvintage Mandopop funk soul\nvintage Mandopop garage rock\nvintage Mandopop rock\nvintage Mandopop surf rock\nvintage Mandopop surf-rock\nvintage Mandopop, Latin pop\nvintage Mandopop, Latin rock\nvintage Mandopop, Latin salsa\nvintage Nepali pop\nvintage Persian pop\nvintage Pop Sunda\nvintage R&B\nvintage R&B boogie-woogie\nvintage R&B jump blues\nvintage Sinhala pop-rock\nvintage South Asian film music\nvintage South Asian film score\nvintage South Asian pop\nvintage South Indian film music\nvintage Southeast Asian pop\nvintage Southeast Asian rock\nvintage Soviet swing\nvintage Spanish\nvintage Spanish copla\nvintage Spanish pop\nvintage Spanish pop-rock\nvintage Spanish rock\nvintage Taiwanese pop\nvintage Taiwanese pop-rock\nvintage Tamil film score\nvintage Tamil funk\nvintage Telugu film music\nvintage V-pop\nvintage V-pop funk\nvintage Vietnamese Christian hymn\nvintage Vietnamese pop\nvintage Vietnamese pop-rock\nvintage a cappella\nvintage acoustic\nvintage animation\nvintage ballad\nvintage ballad, Southeast Asian, crooner\nvintage ballad, early rock and roll, doo-wop\nvintage ballroom\nvintage ballroom waltz\nvintage big band\nvintage big-band\nvintage blues\nvintage brass\nvintage brass band\nvintage brass fanfare\nvintage brass waltz\nvintage cartoon\nvintage chanson\nvintage children's\nvintage children's choir\nvintage children's music\nvintage children's pop\nvintage choral\nvintage cinematic\nvintage circus\nvintage comedy\nvintage country\nvintage country-folk\nvintage country-pop\nvintage crooner\nvintage cumbia\nvintage devotional\nvintage digital cumbia\nvintage electronic\nvintage fanfare\nvintage film music\nvintage film score\nvintage filmi\nvintage folk\nvintage folk-pop\nvintage funk\nvintage funk R&B\nvintage funk disco\nvintage funk-pop\nvintage gospel\nvintage gospel folk\nvintage hip hop\nvintage hip-hop\nvintage holiday\nvintage holiday ballad\nvintage house\nvintage hymn\nvintage instrumental\nvintage jazz\nvintage jingle\nvintage library music\nvintage lo-fi\nvintage lounge\nvintage lounge exotica\nvintage lounge jazz\nvintage lounge pop\nvintage lounge-pop\nvintage lullaby\nvintage mambo\nvintage march\nvintage melancholic\nvintage merengue\nvintage noir\nvintage novelty\nvintage orchestral\nvintage organ\nvintage organ, Southeast Asian soul, analog soul\nvintage organ, bluesy Americana, retro film score\nvintage patriotic ballad\nvintage polka\nvintage pop\nvintage pop ballad\nvintage pop boogie-woogie\nvintage pop cabaret\nvintage pop exotica\nvintage pop exotica lounge\nvintage pop funk soul\nvintage pop lounge\nvintage pop rock\nvintage pop show tune\nvintage pop soul\nvintage pop waltz\nvintage pop, Latin jazz\nvintage pop, Latin pop\nvintage pop, South Asian pop\nvintage pop, big band, Latin\nvintage pop, brass band, Indonesian pop\nvintage pop-rock\nvintage pop-soul\nvintage pop-swing\nvintage ragtime\nvintage reggae\nvintage rock\nvintage rock and roll\nvintage rock and roll exotica\nvintage rock and roll soul\nvintage rock and roll, Latin rock\nvintage rock and roll, doo-wop\nvintage rock and roll, doo-wop, Christmas\nvintage rock and roll, mambo\nvintage rock ballad\nvintage rock en español\nvintage rock funk soul\nvintage salsa\nvintage samba\nvintage sci-fi\nvintage show tune\nvintage soul\nvintage soul R&B\nvintage soul doo-wop\nvintage soul funk\nvintage soul lounge\nvintage soul rock\nvintage soul-funk\nvintage soul-pop\nvintage soul-rock\nvintage swing\nvintage synth\nvintage tango\nvintage torch song\nvintage trap\nvintage video game\nvintage vocal\nvintage waltz\nvintage whimsy\nvintage world music\nvirtuosic piano\nvocal\nvocal ambient\nvocal art\nvocal ballad\nvocal beat\nvocal beatbox\nvocal beatboxing\nvocal beatboxing hip-hop\nvocal beatboxing, world fusion, minimalist hip hop\nvocal choir\nvocal drama\nvocal electronic\nvocal ensemble\nvocal epic\nvocal experimental\nvocal funk\nvocal glitch\nvocal gospel\nvocal group\nvocal group, orchestral pop, show tune\nvocal harmony\nvocal hip hop\nvocal hip-hop\nvocal house\nvocal hymn\nvocal jazz\nvocal jazz ballad\nvocal jazz bebop\nvocal jazz blues\nvocal jazz blues cabaret\nvocal jazz blues lounge\nvocal jazz blues soul\nvocal jazz bolero\nvocal jazz bossa nova\nvocal jazz cabaret\nvocal jazz cabaret tango\nvocal jazz chanson\nvocal jazz city pop\nvocal jazz doo-wop\nvocal jazz exotica\nvocal jazz gypsy jazz\nvocal jazz hip-hop\nvocal jazz lo-fi\nvocal jazz lounge\nvocal jazz soul\nvocal jazz swing\nvocal jazz tango\nvocal jazz, Broadway\nvocal jazz, Christmas lounge\nvocal jazz, Eastern European cabaret\nvocal jazz, French chanson\nvocal jazz, French chanson, bebop\nvocal jazz, French chanson, cool jazz\nvocal jazz, French chanson, lounge\nvocal jazz, French chanson, melancholic\nvocal jazz, Greek blues, Balkan jazz\nvocal jazz, Greek folk\nvocal jazz, Hawaiian exotica\nvocal jazz, Latin jazz\nvocal jazz, Latin jazz, exotica\nvocal jazz, Parisian cabaret\nvocal jazz, big band\nvocal jazz, big band swing\nvocal jazz, big band, blues\nvocal jazz, big band, cinematic\nvocal jazz, big band, jazz ballad\nvocal jazz, blues, noir\nvocal jazz, blues, soul\nvocal jazz, bolero\nvocal jazz, bossa nova\nvocal jazz, bossa nova, Latin jazz\nvocal jazz, bossa nova, exotica\nvocal jazz, bossa nova, latin jazz\nvocal jazz, cabaret, European\nvocal jazz, cabaret, French chanson\nvocal jazz, chanson\nvocal jazz, chanson, European\nvocal jazz, chanson, accordion\nvocal jazz, cinematic, French chanson\nvocal jazz, cinematic, lounge jazz\nvocal jazz, city pop\nvocal jazz, doo-wop\nvocal jazz, doo-wop, Christmas\nvocal jazz, doo-wop, classic pop\nvocal jazz, doo-wop, pop ballad\nvocal jazz, exotica, bossa nova\nvocal jazz, free jazz\nvocal jazz, gospel, swing\nvocal jazz, gypsy jazz\nvocal jazz, latin bolero\nvocal jazz, show tune\nvocal jazz, theatrical rock\nvocal percussion\nvocal percussion, R&B, beatboxing\nvocal pop\nvocal pop ballad\nvocal pop doo-wop\nvocal pop exotica\nvocal pop, doo-wop, early rock and roll\nvocal pop, doo-wop, vintage\nvocal rock\nvocal sample\nvocal snippet\nvocal soul\nvocal trance\nvocal, Spanish, choral\nvocalise\nvocaloid\nvogue house\nvogue house, ballroom, electronic\nvoice-over\nvoiceover\nwaltz\nwaltz pop-rock\nwaltz, Mandarin folk, nostalgic\nwaltz, accordion, Spanish folk\nwaltz, accordion, barbershop\nwaltz, accordion, fairytale\nwaltz, chanson, music hall\nwaltz, child vocal, Parisian\nwaltz, cinematic, romantic\nwaltz, classical, sentimental\nwaltz, folk, Russian\nwaltz, folk, accordion\nwaltz, folk, chanson\nwaltz, orchestral, cinematic\nwaltz, romantic, European\nwaltz, romantic, cinematic\nwaltz, synth pop, fairytale\nwedding ballad\nwestern\nwestern ballad, chanson\nwestern blues\nwestern rock\nwestern swing\nwestern swing bebop\nwestern swing bluegrass\nwestern swing blues\nwestern swing boogie-woogie\nwestern swing gypsy jazz\nwestern swing rockabilly\nwestern swing rockabilly country\nwestern swing rockabilly country blues\nwestern swing, schlager, theatrical\nwhimsical\nwhimsical C-pop\nwhimsical Christmas\nwhimsical acapella\nwhimsical acoustic\nwhimsical ambient\nwhimsical ballad\nwhimsical children's\nwhimsical clarinet\nwhimsical educational\nwhimsical electronic\nwhimsical fantasy\nwhimsical flute\nwhimsical folk\nwhimsical harp\nwhimsical hip-hop\nwhimsical holiday\nwhimsical indie\nwhimsical instrumental\nwhimsical jazz\nwhimsical jingle\nwhimsical lullaby\nwhimsical narrative\nwhimsical nursery rhyme\nwhimsical orchestral\nwhimsical piano\nwhimsical piano ballad\nwhimsical piano pop\nwhimsical piano waltz\nwhimsical pop\nwhimsical sci-fi sea shanty\nwhimsical swing\nwhimsical synth\nwhimsical theater\nwhimsical ukulele\nwhimsical waltz\nwhimsical, nostalgic, Bengali folk\nwhistle folk\nwhistle jazz\nwhistle music\nwhistle pop\nwinter R&B\nwinter ballad\nwinter pop\nwinter trap\nwitch house\nwitch house dark trap\nwitch house darkwave\nwitch house dream pop\nwitch house experimental trap\nwitch house future bass\nwitch house future garage\nwitch house phonk\nwitch house trap\nwitch house, ambient, Slavic folk\nwitch house, cloud rap\nwitch house, cloud rap, dark electronic\nwitch house, dark electronic, industrial\nwitch house, dark pop\nwitch house, dark pop, electronic\nwitch house, dark pop, hardstyle\nwitch house, dark trap\nwitch house, dark trap, ambient electronic\nwitch house, darkwave, electronic\nwitch house, darkwave, trap\nwitch house, future bass, ethereal trap\nwitch house, hardstyle, dark electronic\nwitch house, trap\nwitch house, trap, cloud rap\nwitch house, trap, dark pop\nwitch house, trap, hyperpop\nwitch house, witch trap\nwitch-trap\nwobble house\nwoodwind ensemble\nwork song\nwork song, gospel, hip-hop\nworld R&B\nworld ambient\nworld ballad\nworld bass, trap, cinematic\nworld bass, trap, traditional East Asian\nworld beat\nworld beat hip-hop\nworld chanson\nworld chant\nworld dance\nworld drum\nworld electronic\nworld electronic chiptune\nworld electronic pop\nworld electronica\nworld flute\nworld folk\nworld folk ambient\nworld folk ballad\nworld folk fusion\nworld folk pop\nworld folk rock\nworld folk waltz\nworld folk worship\nworld folk, cinematic, klezmer\nworld folk-rock\nworld funk\nworld funk soul\nworld fusion\nworld fusion Christian rock\nworld fusion EDM\nworld fusion R&B\nworld fusion alternative rock\nworld fusion ambient\nworld fusion ballad\nworld fusion blues-rock\nworld fusion cabaret\nworld fusion chillout\nworld fusion cinematic\nworld fusion cumbia\nworld fusion electro-pop\nworld fusion electronic\nworld fusion electronic rock\nworld fusion flamenco\nworld fusion folk\nworld fusion folk-rock\nworld fusion funk\nworld fusion funk jazz\nworld fusion funk rock\nworld fusion funk-jazz\nworld fusion funk-rock\nworld fusion hip hop\nworld fusion hip-hop\nworld fusion house\nworld fusion indie rock\nworld fusion jazz\nworld fusion jazz funk\nworld fusion jazz lounge\nworld fusion lounge\nworld fusion metal\nworld fusion new age\nworld fusion pop\nworld fusion pop rock\nworld fusion pop-funk\nworld fusion pop-rock\nworld fusion progressive rock\nworld fusion psychedelic rock\nworld fusion psytrance\nworld fusion reggaeton\nworld fusion rock\nworld fusion salsa\nworld fusion smooth jazz\nworld fusion synth-pop flamenco\nworld fusion tango\nworld fusion tango balkan\nworld fusion tango jazz\nworld fusion tango middle eastern\nworld fusion trance\nworld fusion trap\nworld fusion trip-hop\nworld fusion, Latin rock\nworld fusion, ambient, electronic\nworld fusion, cinematic hip-hop, global pop\nworld fusion, electronic, cinematic\nworld fusion, folk-rock, Latin, Middle Eastern\nworld fusion, new age, Indian devotional\nworld fusion, new age, ambient\nworld fusion, new age, cinematic\nworld fusion, new age, devotional\nworld fusion, new age, synth-pop\nworld fusion, pop, hip-hop\nworld fusion, psychedelic rock, Arabic\nworld fusion, rock, Persian\nworld gospel\nworld gospel hip-hop\nworld hip hop\nworld hip-hop\nworld hip-hop pop\nworld house\nworld instrumental\nworld jazz\nworld jazz fusion\nworld lounge\nworld lullaby\nworld meditation\nworld music\nworld music Afro-Latin\nworld music Afrobeat\nworld music C-pop\nworld music Christmas\nworld music Javanese\nworld music R&B\nworld music acoustic folk\nworld music acoustic pop spiritual new age\nworld music adult contemporary\nworld music afro-latin\nworld music afrobeat\nworld music afropop\nworld music alternative rock\nworld music ambient\nworld music ballad\nworld music big band jazz\nworld music bossa nova\nworld music cabaret\nworld music chillout\nworld music chiptune\nworld music choral\nworld music cinematic\nworld music cinematic ballad\nworld music cinematic pop\nworld music cinematic pop-rock\nworld music classical crossover\nworld music conscious hip-hop\nworld music devotional\nworld music downtempo\nworld music easy listening\nworld music electronic\nworld music electronica\nworld music fado\nworld music fantasy\nworld music flamenco\nworld music folk\nworld music folk jazz fusion\nworld music folk-fusion\nworld music folk-pop\nworld music folk-rock\nworld music funk\nworld music fusion\nworld music gospel\nworld music gospel african pop\nworld music gospel afropop\nworld music gospel bossa nova\nworld music gospel jazz\nworld music gospel pop-rock\nworld music gospel reggae\nworld music gospel soft rock\nworld music gospel-pop\nworld music gothic\nworld music hip hop\nworld music hip-hop\nworld music indie rock\nworld music jazz fusion\nworld music kirtan\nworld music kizomba\nworld music latin\nworld music latin pop\nworld music lo-fi\nworld music lounge\nworld music lounge jazz\nworld music lullaby\nworld music neo-classical\nworld music new age\nworld music pop\nworld music pop ballad\nworld music pop rock\nworld music pop-rock\nworld music power ballad\nworld music power rock\nworld music progressive rock\nworld music protest\nworld music psychedelic\nworld music psychedelic folk\nworld music psychedelic rock\nworld music reggae\nworld music reggaeton\nworld music ritual\nworld music rock\nworld music rumba flamenco\nworld music salsa\nworld music samba\nworld music smooth jazz\nworld music soft pop ghazal\nworld music soft pop-rock\nworld music soft rock\nworld music soul\nworld music spiritual\nworld music spiritual pop\nworld music surf rock\nworld music tango\nworld music tango folk\nworld music trap\nworld music trap r&b\nworld music tribal fusion\nworld music tribal house\nworld music trip-hop\nworld music worship\nworld music zouk\nworld music, Anatolian rock, emotional pop\nworld music, Arabic pop, Mandarin pop\nworld music, French hip-hop, soul\nworld music, Indian folk, ambient\nworld music, Indian folk, romantic duet\nworld music, Islamic children's, upbeat\nworld music, Latin pop-rock\nworld music, Latin, funk\nworld music, Latin, upbeat\nworld music, Middle Eastern, Armenian\nworld music, Middle Eastern, Persian\nworld music, Sufi, microtonal\nworld music, cabaret, tango\nworld music, cinematic rock\nworld music, cinematic, electronic\nworld music, cinematic, emotional ballad\nworld music, classical crossover, epic film score\nworld music, dance, J-pop\nworld music, dance-pop\nworld music, dance-pop, Romanian\nworld music, dark electronic, ambient\nworld music, devotional, ambient\nworld music, downtempo, lo-fi hip hop\nworld music, electronic pop\nworld music, electronic, Armenian\nworld music, electronic, Middle Eastern\nworld music, electronic, Turkish\nworld music, electronic, hip hop\nworld music, fantasy soundtrack, upbeat\nworld music, festive, cinematic\nworld music, folk, spiritual\nworld music, hard rock\nworld music, hyperpop, ambient\nworld music, industrial rock, ambient\nworld music, minimalism, Latin rhythms\nworld music, minimalist hip-hop\nworld music, moombahton, Latin EDM\nworld music, moombahton, reggaeton\nworld music, musical theater, Latin pop\nworld music, new age\nworld music, new age, ambient\nworld music, new age, ambient pop\nworld music, new age, cinematic\nworld music, new age, electronic\nworld music, new age, hyperpop\nworld music, new age, soft rock\nworld music, new age, soul\nworld music, new age, synth pop\nworld music, new-age, ambient\nworld music, pop-rock, French pop\nworld music, pop-rock, Turkish\nworld music, pop-trap, Azerbaijani\nworld music, power metal, rock ballad\nworld music, progressive house, French pop\nworld music, psychedelic rock\nworld music, psychedelic rock, cabaret\nworld music, retro electronic, funk\nworld music, salsa, Arabic pop\nworld music, synth-pop, flamenco\nworld music, trap, hardstyle\nworld music, tribal, anthemic\nworld music, video game soundtrack\nworld music, video game soundtrack, ambient\nworld music, video game soundtrack, cinematic\nworld music, video game soundtrack, epic\nworld music, video game soundtrack, folk dance\nworld music, video game soundtrack, folk pop\nworld music, video game soundtrack, instrumental\nworld music, video game soundtrack, orchestral\nworld music, video game soundtrack, playful\nworld music, video game soundtrack, pop-rock\nworld music, video game soundtrack, synthpop\nworld music, video game soundtrack, upbeat\nworld music, video game soundtrack, uplifting\nworld music, video game, ambient\nworld music, worship\nworld music-pop\nworld narrative\nworld percussion\nworld poetry\nworld pop\nworld pop rock\nworld pop trap\nworld pop, Sinhala pop\nworld protest\nworld punk\nworld rock\nworld soul\nworld trance\nworld trap\nworld vocal\nworld worship\nworld-electronic\nworld-folk\nworld-folk alt-rock\nworld-folk cinematic\nworld-folk cumbia\nworld-folk flamenco\nworld-folk fusion\nworld-folk future bass\nworld-folk pop\nworld-folk pop-rock\nworld-folk rock\nworld-folk, conscious reggae, organic groove\nworld-folk-pop\nworld-folk-rock\nworld-funk\nworld-infused electronic\nworld-music electronica\nworld-music trap\nworld-pop\nworld-pop Afrobeat\nworld-pop R&B\nworld-pop afrobeat\nworld-pop afrobeats\nworld-pop cinematic\nworld-pop cumbia\nworld-pop dance-pop\nworld-pop dancehall\nworld-pop devotional\nworld-pop funk\nworld-pop gospel\nworld-pop gospel african\nworld-pop gospel afro-pop\nworld-pop reggae\nworld-pop reggae Latin\nworld-pop reggae island\nworld-pop reggaeton\nworld-pop rock\nworld-pop salsa\nworld-pop ska-pop\nworld-pop smooth jazz\nworld-pop trap\nworld-pop tribal house\nworld-pop tropical house hip-hop\nworld-pop, Latin pop, C-pop\nworld-pop, experimental, hyperpop\nworld-rock\nworld-techno\nworld-trap\nworldbeat\nworldbeat African pop\nworldbeat Afro-Latin\nworldbeat Afro-pop\nworldbeat Afro-pop Tibetan pop\nworldbeat Arabic pop\nworldbeat Bollywood\nworldbeat C-pop\nworldbeat Celtic folk\nworldbeat Christian pop\nworldbeat Christmas\nworldbeat EDM\nworldbeat French pop\nworldbeat Latin pop\nworldbeat Mandopop\nworldbeat R&B\nworldbeat R&B gospel\nworldbeat adult contemporary\nworldbeat afro-house\nworldbeat afro-tech\nworldbeat afrobeat gospel\nworldbeat afrobeats\nworldbeat afrobeats gospel\nworldbeat afropop gospel\nworldbeat alternative rock\nworldbeat ambient\nworldbeat arabic pop\nworldbeat big band\nworldbeat blues\nworldbeat blues-rock\nworldbeat cabaret\nworldbeat chanson\nworldbeat chillout\nworldbeat chillwave\nworldbeat chiptune\nworldbeat cinematic\nworldbeat cinematic pop\nworldbeat conscious hip-hop\nworldbeat corporate pop\nworldbeat cumbia\nworldbeat cumbia anime\nworldbeat cumbia latin\nworldbeat dance\nworldbeat dance pop\nworldbeat dance-pop\nworldbeat dancehall\nworldbeat deep house\nworldbeat devotional\nworldbeat downtempo\nworldbeat electronic\nworldbeat electronic lounge\nworldbeat electronic pop\nworldbeat electronic rock\nworldbeat electronica\nworldbeat epic\nworldbeat epic pop\nworldbeat ethnic fusion\nworldbeat ethno-pop\nworldbeat filmi\nworldbeat flamenco\nworldbeat flamenco latin\nworldbeat folk pop\nworldbeat folk-dance\nworldbeat folk-fusion\nworldbeat folk-pop\nworldbeat folk-rock\nworldbeat folk-rock big band\nworldbeat freestyle\nworldbeat funk\nworldbeat funk acid jazz\nworldbeat funk disco\nworldbeat funk pop\nworldbeat funk pop-rock\nworldbeat funk reggae\nworldbeat funk rock electronic\nworldbeat funk soul\nworldbeat funk-pop\nworldbeat funk-rock\nworldbeat fusion\nworldbeat future bass\nworldbeat gospel\nworldbeat gospel R&B\nworldbeat gospel afro-pop\nworldbeat gospel afrobeat\nworldbeat gospel afropop\nworldbeat gospel latin\nworldbeat gospel new age\nworldbeat gospel pop\nworldbeat gospel reggae\nworldbeat gospel zouk\nworldbeat gospel-pop\nworldbeat gypsy jazz swing\nworldbeat highlife\nworldbeat hip-hop\nworldbeat hip-hop funk\nworldbeat house\nworldbeat indie pop\nworldbeat indie rock\nworldbeat island pop\nworldbeat jazz\nworldbeat jazz fusion\nworldbeat kizomba\nworldbeat kizomba zouk\nworldbeat lo-fi\nworldbeat lounge\nworldbeat neo-soul\nworldbeat new age\nworldbeat new age gospel\nworldbeat new age pop\nworldbeat new wave\nworldbeat new-age\nworldbeat pop\nworldbeat pop gospel\nworldbeat pop hip-hop\nworldbeat pop rock\nworldbeat pop-dance\nworldbeat pop-folk\nworldbeat pop-funk\nworldbeat pop-gospel\nworldbeat pop-r&b\nworldbeat pop-rock\nworldbeat progressive house\nworldbeat progressive rock\nworldbeat protest\nworldbeat psychedelic funk\nworldbeat psychedelic rock\nworldbeat psytrance\nworldbeat ragtime\nworldbeat reggae\nworldbeat reggae dancehall\nworldbeat reggae fusion\nworldbeat reggae gospel\nworldbeat reggae highlife\nworldbeat reggae island pop\nworldbeat reggae latin\nworldbeat reggae pop\nworldbeat reggae pop-rock\nworldbeat reggaeton\nworldbeat retro\nworldbeat retro synth\nworldbeat rock\nworldbeat rock fusion\nworldbeat rock-pop\nworldbeat smooth jazz\nworldbeat soul\nworldbeat spiritual\nworldbeat surf rock\nworldbeat synth-pop\nworldbeat synth-pop chiptune\nworldbeat tango\nworldbeat techno\nworldbeat theatrical pop\nworldbeat trap\nworldbeat trap-pop\nworldbeat tribal house\nworldbeat trip-hop\nworldbeat tropical house\nworldbeat world fusion\nworldbeat zouk\nworldbeat zouk afro-caribbean\nworldbeat zouk afropop\nworldbeat zouk caribbean\nworldbeat zouk french pop\nworldbeat, 80s French pop, synth rock\nworldbeat, African pop, anthem\nworldbeat, Anatolian rock, Middle Eastern\nworldbeat, Anatolian rock, Middle Eastern rock\nworldbeat, Arabic pop, cinematic\nworldbeat, Bollywood, pop\nworldbeat, Bollywood, upbeat\nworldbeat, Brazilian, Latin\nworldbeat, Brazilian, new age\nworldbeat, Chinese folk, upbeat\nworldbeat, EDM, Latin\nworldbeat, EDM, Middle Eastern\nworldbeat, Latin house\nworldbeat, Latin pop\nworldbeat, Latin pop, French pop\nworldbeat, Latin pop, deep house\nworldbeat, Latin pop, gospel\nworldbeat, Latin pop, theatrical folk\nworldbeat, Latin, Andean\nworldbeat, Latin, South Asian fusion\nworldbeat, Latin, Zouk\nworldbeat, Latin, boogie-woogie\nworldbeat, Latin, ceremonial\nworldbeat, Latin, funk\nworldbeat, Latin, klezmer\nworldbeat, Latin, new age\nworldbeat, Latin, surf-rock\nworldbeat, Persian pop, dance\nworldbeat, South African pop, anthemic\nworldbeat, South Asian pop\nworldbeat, South Asian pop, electronic\nworldbeat, South Asian pop, upbeat\nworldbeat, South Asian, upbeat\nworldbeat, South Indian folk, cinematic\nworldbeat, afrobeats, chiptune\nworldbeat, ambient, cinematic\nworldbeat, ambient, downtempo\nworldbeat, ambient, electronic\nworldbeat, ambient, pop-funk\nworldbeat, ambient, spiritual\nworldbeat, children's music, South Indian folk\nworldbeat, choral, electronic\nworldbeat, cinematic, Greek folk\nworldbeat, cinematic, ethereal\nworldbeat, cinematic, soul\nworldbeat, classical fusion, Persian opera\nworldbeat, devotional, electronic\nworldbeat, electronic dance\nworldbeat, electronic dance music\nworldbeat, electronic dance, Central Asian folk\nworldbeat, electronic dance, Indian fusion\nworldbeat, electronic dance, Middle Eastern\nworldbeat, electronic dance, Middle Eastern fusion\nworldbeat, electronic dance, South Asian fusion\nworldbeat, electronic dance, folk\nworldbeat, electronic dance-pop, Central Asian\nworldbeat, electronic pop, Middle Eastern\nworldbeat, electronic, Indian classical\nworldbeat, electronic, Indian fusion\nworldbeat, electronic, Indian pop\nworldbeat, electronic, Middle Eastern\nworldbeat, electronic, South Asian\nworldbeat, electronic, cinematic\nworldbeat, electronic, dance-pop\nworldbeat, electronic, devotional\nworldbeat, electronic, folk fusion\nworldbeat, electronic, melodic\nworldbeat, ethereal, electronic\nworldbeat, ethnic electronica\nworldbeat, eurodance, pop\nworldbeat, folk-pop, Sinhala\nworldbeat, folk-pop, South Asian\nworldbeat, funk, retro Persian pop\nworldbeat, hardstyle, psytrance\nworldbeat, island pop, Polynesian\nworldbeat, new age\nworldbeat, new age pop\nworldbeat, new age, electronic\nworldbeat, pop, Southeast Asian\nworldbeat, pop, electronic\nworldbeat, psychedelic, Sufi\nworldbeat, retro electronic, South Asian\nworldbeat, retro pop, Sinhala pop\nworldbeat, soul, electronic\nworldbeat, synth-pop, Afropop\nworldbeat, synth-pop, Persian pop\nworldbeat, synth-pop, chiptune\nworldbeat, trance, industrial\nworldbeat, tribal house, Latin\nworldbeat, tribal, J-pop\nworldbeat, trip-hop, Azerbaijani\nworldbeat, video game music\nworldbeat-pop\nworship\nworship Cumbia\nworship Latin\nworship ambient\nworship anthem\nworship ballad\nworship ballad funk-rock\nworship ballad pop-rock\nworship ballad, Christian rock\nworship ballad, Latin pop-rock\nworship ballad, gospel rock\nworship ballad, pop-rock, cinematic\nworship electronic\nworship folk\nworship folk-rock\nworship funk soul\nworship funk-rock\nworship indie rock\nworship jazz\nworship music\nworship piano\nworship piano ballad\nworship pop\nworship pop gospel\nworship pop rock\nworship pop-rock\nworship power ballad\nworship rock\nworship ukulele\nworship, Hawaiian, acoustic\nworship, Latin pop\nworship, Latin pop-rock, gospel\nworship, Latin rumba, gospel\nworship, Latin, world music\nworship, acoustic, bilingual\nworship, ambient pop\nworship, ambient, acoustic\nworship, ambient, post-rock\nworship, anthemic, bilingual\nworship, bossa nova\nworship, cinematic, multilingual\nworship, cinematic, spiritual\nworship, contemporary Christian, hip-hop\nworship, epic, Middle Eastern\nworship, eurodance, synth-pop\nworship, multi-lingual, folk rock\nworship, pop-rock, ambient\nworship, rock, bilingual\nworship, soft rock\nworship, synth-pop, cinematic\nworship, world music, cinematic\nworshipful pop-rock\nworshipful rock\nwuxia\nwuxia cinematic\nwuxia film score\nwuxia metal\nwuxia rock\nwuxia rock opera\nwuxia, cinematic, traditional Chinese\nyé-yé\nyé-yé, French pop, 60s rock\nyé-yé, garage rock, French pop\nyé-yé, surf-rock, French pop\nzouk\nzouk chiptune\nzouk hip-hop\nzouk kompa\nzouk reggae\nzouk soca chiptune\nzydeco\nzydeco cajun\nzydeco rock\n古风\n古风 C-pop\n古风 pop\n古风 pop, cinematic, electronic\n古风 rock\n古风, ambient pop, electronic\n古风, ambient, electronic\n古风, chillwave, C-pop\n古风, cinematic orchestral\n古风, cinematic pop, ambient\n古风, cinematic pop, emotional ballad\n古风, cinematic pop, epic rock\n古风, cinematic pop, lo-fi\n古风, cinematic pop, modern Chinese\n古风, cinematic pop, pop-rock\n古风, cinematic pop, power ballad\n古风, cinematic pop, rock\n古风, cinematic rock\n古风, cinematic rock, electronic\n古风, cinematic, ambient\n古风, cinematic, ambient pop\n古风, cinematic, electronic\n古风, cinematic, orchestral\n古风, cinematic, rock\n古风, electronic, ambient\n古风, electronic, cinematic\n古风, electronic, jazz fusion\n古风, lo-fi, ambient\n古风, pop, cinematic\n古风, pop-rock, cinematic\n古风, symphonic rock, cinematic pop\n喊麦\n喊麦, Eurodance\n喊麦, Eurodance, Chinese club\n喊麦, Eurodance, Trance"
  },
  {
    "path": "acestep/gpu_config.py",
    "content": "\"\"\"\nGPU Configuration Module\nCentralized GPU memory detection and adaptive configuration management\n\n    Debug Mode:\n        Set environment variable MAX_CUDA_VRAM to simulate different GPU memory sizes.\n        Example: MAX_CUDA_VRAM=8 python acestep  # Simulates 8GB GPU\n\n        For MPS testing, use MAX_MPS_VRAM to simulate MPS memory.\n        Example: MAX_MPS_VRAM=16 python acestep  # Simulates 16GB MPS\n\n    This is useful for testing GPU tier configurations on high-end hardware.\n\"\"\"\n\nimport os\nimport sys\nfrom dataclasses import dataclass\nfrom typing import Optional, List, Dict, Tuple\nfrom loguru import logger\n\n\n# Environment variable for debugging/testing different GPU memory configurations\nDEBUG_MAX_CUDA_VRAM_ENV = \"MAX_CUDA_VRAM\"\nDEBUG_MAX_MPS_VRAM_ENV = \"MAX_MPS_VRAM\"\nDEBUG_MAX_XPU_VRAM_ENV = \"MAX_XPU_VRAM\"\n\n# Tolerance for 16GB detection: reported VRAM like 15.5GB is effectively 16GB hardware\n# Real-world 16GB GPUs often report 15.7-15.9GB due to system/driver reservations\nVRAM_16GB_TOLERANCE_GB = 0.5\nVRAM_16GB_MIN_GB = 16.0 - VRAM_16GB_TOLERANCE_GB  # treat as 16GB class if >= this\n\n# Threshold below which auto_offload is enabled.\n# 16GB GPUs cannot hold DiT + VAE + text_encoder + LM simultaneously without offloading.\nVRAM_AUTO_OFFLOAD_THRESHOLD_GB = 20.0\n\n# PyTorch installation URLs for diagnostics\nPYTORCH_CUDA_INSTALL_URL = \"https://download.pytorch.org/whl/cu121\"\nPYTORCH_ROCM_INSTALL_URL = \"https://download.pytorch.org/whl/rocm6.0\"\n\n\ndef is_mps_platform() -> bool:\n    \"\"\"Check if running on macOS with MPS (Apple Silicon) available.\n\n    This is the canonical check used across the codebase to apply\n    Mac-specific configuration overrides (no compile, no quantization,\n    mlx backend, no offload, etc.).\n    \"\"\"\n    if sys.platform != \"darwin\":\n        return False\n    try:\n        import torch\n\n        return hasattr(torch.backends, \"mps\") and torch.backends.mps.is_available()\n    except Exception:\n        return False\n\n\ndef is_cuda_available() -> bool:\n    \"\"\"Return whether CUDA runtime is available.\"\"\"\n    try:\n        import torch\n\n        return torch.cuda.is_available()\n    except Exception:\n        return False\n\n\ndef is_mps_available() -> bool:\n    \"\"\"Return whether MPS runtime is available.\"\"\"\n    try:\n        import torch\n\n        return hasattr(torch.backends, \"mps\") and torch.backends.mps.is_available()\n    except Exception:\n        return False\n\n\ndef is_xpu_available() -> bool:\n    \"\"\"Return whether XPU runtime is available.\"\"\"\n    try:\n        import torch\n\n        return hasattr(torch, \"xpu\") and torch.xpu.is_available()\n    except Exception:\n        return False\n\n\ndef is_rocm_available() -> bool:\n    \"\"\"Return whether the active CUDA device is an AMD ROCm/HIP device.\n\n    On ROCm, PyTorch exposes the GPU as a CUDA device but also sets\n    ``torch.version.hip``.  This function returns ``True`` only when\n    *both* conditions hold: a CUDA device is present **and** the build\n    is a ROCm/HIP build.\n    \"\"\"\n    try:\n        import torch\n\n        return (\n            torch.cuda.is_available()\n            and hasattr(torch.version, \"hip\")\n            and torch.version.hip is not None\n        )\n    except Exception:\n        return False\n\n\ndef cuda_supports_bfloat16(device_index: int | None = None) -> bool:\n    \"\"\"Return whether a CUDA device supports native bfloat16 kernels.\"\"\"\n    try:\n        import torch\n\n        if not torch.cuda.is_available():\n            return False\n        major, _ = torch.cuda.get_device_capability(device_index)\n        return major >= 8\n    except Exception:\n        return False\n\n\n# ===========================================================================\n# Empirical VRAM measurements (GB) -- model weights only, bf16 precision\n# These values should be calibrated using scripts/profile_vram.py\n# ===========================================================================\n\n# Base model weights (loaded once at startup)\nMODEL_VRAM = {\n    \"dit_turbo\": 4.7,  # DiT turbo model weights (bf16)\n    \"dit_base\": 4.7,  # DiT base model weights (bf16)\n    \"vae\": 0.33,  # VAE (AutoencoderOobleck) weights (fp16)\n    \"text_encoder\": 1.2,  # Qwen3-Embedding-0.6B text encoder (bf16)\n    \"silence_latent\": 0.01,  # Silence latent tensor\n    \"cuda_context\": 0.5,  # CUDA context + driver overhead\n}\n\n# LM model weights (bf16) + KV cache estimates\nLM_VRAM = {\n    \"0.6B\": {\"weights\": 1.2, \"kv_cache_2k\": 0.3, \"kv_cache_4k\": 0.6},\n    \"1.7B\": {\"weights\": 3.4, \"kv_cache_2k\": 0.5, \"kv_cache_4k\": 1.0},\n    \"4B\": {\"weights\": 8.0, \"kv_cache_2k\": 0.8, \"kv_cache_4k\": 1.6},\n}\n\n# DiT inference peak VRAM per batch item (approximate, depends on duration)\n# These are additional activations/intermediates on top of model weights.\n#\n# Profiling on A800 (flash attention) shows only ~0.001-0.004 GB per batch item.\n# Consumer GPUs without flash attention will be higher due to materialised\n# attention matrices.  We use conservative estimates that cover the worst case\n# (no flash attention, long sequences).\nDIT_INFERENCE_VRAM_PER_BATCH = {\n    \"turbo\": 0.3,  # GB per batch item (no CFG)\n    \"base\": 0.6,  # GB per batch item (with CFG, 2x forward)\n}\n\n# Safety margin to keep free for OS/driver/fragmentation (GB)\nVRAM_SAFETY_MARGIN_GB = 0.5\n\n\n@dataclass\nclass GPUConfig:\n    \"\"\"GPU configuration based on available memory\"\"\"\n\n    tier: str  # \"tier1\", \"tier2\", etc. or \"unlimited\"\n    gpu_memory_gb: float\n\n    # Duration limits (in seconds)\n    max_duration_with_lm: int  # When LM is initialized\n    max_duration_without_lm: int  # When LM is not initialized\n\n    # Batch size limits\n    max_batch_size_with_lm: int\n    max_batch_size_without_lm: int\n\n    # LM configuration\n    init_lm_default: bool  # Whether to initialize LM by default\n    available_lm_models: List[str]  # Available LM models for this tier\n    recommended_lm_model: (\n        str  # Recommended default LM model path (empty if LM not available)\n    )\n\n    # LM backend restriction\n    # \"all\" = any backend, \"pt_mlx_only\" = only pt/mlx (no vllm), used for MPS (vllm requires CUDA)\n    lm_backend_restriction: str  # \"all\" or \"pt_mlx_only\"\n    recommended_backend: str  # Recommended default backend: \"vllm\", \"pt\", or \"mlx\"\n\n    # Offload defaults\n    offload_to_cpu_default: bool  # Whether offload_to_cpu should be enabled by default\n    offload_dit_to_cpu_default: (\n        bool  # Whether offload_dit_to_cpu should be enabled by default\n    )\n\n    # Quantization / compile defaults\n    quantization_default: bool  # Whether INT8 quantization should be enabled by default\n    compile_model_default: bool  # Whether torch.compile should be enabled by default\n\n    # LM memory allocation (GB) for each model size\n    lm_memory_gb: Dict[str, float]  # e.g., {\"0.6B\": 3, \"1.7B\": 8, \"4B\": 12}\n\n\n# GPU tier configurations\n# tier6 has been split into tier6a (16-20GB) and tier6b (20-24GB) to fix the\n# 16GB regression. 16GB GPUs cannot hold all models simultaneously with the\n# same batch sizes as 24GB GPUs.\nGPU_TIER_CONFIGS = {\n    \"tier1\": {  # <= 4GB\n        # Offload mode required.  DiT(4.46) barely fits with CUDA context(0.5).\n        # VAE decode falls back to CPU.  Keep durations moderate.\n        \"max_duration_with_lm\": 240,  # 4 minutes\n        \"max_duration_without_lm\": 360,  # 6 minutes\n        \"max_batch_size_with_lm\": 1,\n        \"max_batch_size_without_lm\": 1,\n        \"init_lm_default\": False,\n        \"available_lm_models\": [],\n        \"recommended_lm_model\": \"\",\n        \"lm_backend_restriction\": \"all\",\n        \"recommended_backend\": \"vllm\",\n        \"offload_to_cpu_default\": True,\n        \"offload_dit_to_cpu_default\": True,\n        \"quantization_default\": True,  # INT8 essential to fit DiT in ~4GB\n        \"compile_model_default\": True,\n        \"lm_memory_gb\": {},\n    },\n    \"tier2\": {  # 4-6GB\n        # Offload mode.  DiT(4.46) + context(0.5) + activations ≈ 5.0GB.\n        # ~1GB headroom.  Tiled VAE decode fits with chunk=256 (~0.8GB peak).\n        # Duration barely affects peak VRAM (latent tensor is <2MB even at 10min).\n        \"max_duration_with_lm\": 480,  # 8 minutes\n        \"max_duration_without_lm\": 600,  # 10 minutes (max supported)\n        \"max_batch_size_with_lm\": 1,\n        \"max_batch_size_without_lm\": 1,\n        \"init_lm_default\": False,\n        \"available_lm_models\": [],\n        \"recommended_lm_model\": \"\",\n        \"lm_backend_restriction\": \"all\",\n        \"recommended_backend\": \"vllm\",\n        \"offload_to_cpu_default\": True,\n        \"offload_dit_to_cpu_default\": True,\n        \"quantization_default\": True,\n        \"compile_model_default\": True,\n        \"lm_memory_gb\": {},\n    },\n    \"tier3\": {  # 6-8GB\n        # Offload mode.  DiT(4.46) + context(0.5) ≈ 5.0GB.\n        # ~1.5-3GB headroom allows LM 0.6B (1.2+0.6=1.8GB) and batch=2.\n        # With CPU offload, DiT is offloaded before LM runs → vllm can use freed VRAM.\n        \"max_duration_with_lm\": 480,  # 8 minutes\n        \"max_duration_without_lm\": 600,  # 10 minutes (max supported)\n        \"max_batch_size_with_lm\": 2,\n        \"max_batch_size_without_lm\": 2,\n        \"init_lm_default\": True,\n        \"available_lm_models\": [\"acestep-5Hz-lm-0.6B\"],\n        \"recommended_lm_model\": \"acestep-5Hz-lm-0.6B\",\n        \"lm_backend_restriction\": \"all\",\n        \"recommended_backend\": \"vllm\",\n        \"offload_to_cpu_default\": True,\n        \"offload_dit_to_cpu_default\": True,\n        \"quantization_default\": True,\n        \"compile_model_default\": True,\n        \"lm_memory_gb\": {\"0.6B\": 3},\n    },\n    \"tier4\": {  # 8-12GB\n        # Can keep DiT + 0.6B LM simultaneously on GPU (4.46+1.2+0.6=6.26GB).\n        # Offload VAE/TextEnc.  Plenty of room for inference activations.\n        \"max_duration_with_lm\": 480,  # 8 minutes\n        \"max_duration_without_lm\": 600,  # 10 minutes (max supported)\n        \"max_batch_size_with_lm\": 2,\n        \"max_batch_size_without_lm\": 4,\n        \"init_lm_default\": True,\n        \"available_lm_models\": [\"acestep-5Hz-lm-0.6B\"],\n        \"recommended_lm_model\": \"acestep-5Hz-lm-0.6B\",\n        \"lm_backend_restriction\": \"all\",  # vllm fits with 0.6B\n        \"recommended_backend\": \"vllm\",\n        \"offload_to_cpu_default\": True,\n        \"offload_dit_to_cpu_default\": True,\n        \"quantization_default\": True,\n        \"compile_model_default\": True,\n        \"lm_memory_gb\": {\"0.6B\": 3},\n    },\n    \"tier5\": {  # 12-16GB\n        # DiT + 1.7B LM (4.46+3.45+0.44=8.35GB) fits comfortably.\n        # VAE decode is batch-sequential so batch size doesn't affect VAE VRAM.\n        \"max_duration_with_lm\": 480,  # 8 minutes\n        \"max_duration_without_lm\": 600,  # 10 minutes (max supported)\n        \"max_batch_size_with_lm\": 4,\n        \"max_batch_size_without_lm\": 4,\n        \"init_lm_default\": True,\n        \"available_lm_models\": [\"acestep-5Hz-lm-0.6B\", \"acestep-5Hz-lm-1.7B\"],\n        \"recommended_lm_model\": \"acestep-5Hz-lm-1.7B\",\n        \"lm_backend_restriction\": \"all\",\n        \"recommended_backend\": \"vllm\",\n        \"offload_to_cpu_default\": True,\n        \"offload_dit_to_cpu_default\": False,  # 12-16GB can keep DiT on GPU\n        \"quantization_default\": True,\n        \"compile_model_default\": True,\n        \"lm_memory_gb\": {\"0.6B\": 3, \"1.7B\": 8},\n    },\n    \"tier6a\": {  # 16-20GB (e.g., RTX 4060 Ti 16GB, RTX 3080 16GB)\n        # On 16GB GPUs: DiT(INT8, ~2.4GB) + LM 1.7B(~7.6GB peak with offload) = ~10GB peak\n        # Empirical batch tests (60s, turbo): noLM-4→13.3GB, LM-2→11.9GB, LM-4→~13.5GB\n        # With CPU offload, LM is offloaded after inference → DiT batch has full 16GB budget.\n        \"max_duration_with_lm\": 480,  # 8 minutes\n        \"max_duration_without_lm\": 600,  # 10 minutes (max supported)\n        \"max_batch_size_with_lm\": 4,\n        \"max_batch_size_without_lm\": 8,\n        \"init_lm_default\": True,\n        \"available_lm_models\": [\"acestep-5Hz-lm-0.6B\", \"acestep-5Hz-lm-1.7B\"],\n        \"recommended_lm_model\": \"acestep-5Hz-lm-1.7B\",\n        \"lm_backend_restriction\": \"all\",\n        \"recommended_backend\": \"vllm\",\n        \"offload_to_cpu_default\": True,  # Still offload VAE/TextEnc to save VRAM for LM\n        \"offload_dit_to_cpu_default\": False,\n        \"quantization_default\": True,\n        \"compile_model_default\": True,\n        \"lm_memory_gb\": {\"0.6B\": 3, \"1.7B\": 8},\n    },\n    \"tier6b\": {  # 20-24GB (e.g., RTX 3090, RTX 4090)\n        # 20-24GB: no offload, no quantization. DiT(bf16, ~4.7GB) + LM 1.7B(~3.4GB) = ~8.1GB\n        # Remaining ~12-16GB easily fits batch=8. VAE decode is batch-sequential.\n        \"max_duration_with_lm\": 480,  # 8 minutes\n        \"max_duration_without_lm\": 480,  # 8 minutes\n        \"max_batch_size_with_lm\": 8,\n        \"max_batch_size_without_lm\": 8,\n        \"init_lm_default\": True,\n        \"available_lm_models\": [\n            \"acestep-5Hz-lm-0.6B\",\n            \"acestep-5Hz-lm-1.7B\",\n            \"acestep-5Hz-lm-4B\",\n        ],\n        \"recommended_lm_model\": \"acestep-5Hz-lm-1.7B\",\n        \"lm_backend_restriction\": \"all\",\n        \"recommended_backend\": \"vllm\",\n        \"offload_to_cpu_default\": False,  # 20-24GB can hold all models\n        \"offload_dit_to_cpu_default\": False,\n        \"quantization_default\": False,  # Enough VRAM, quantization optional\n        \"compile_model_default\": True,\n        \"lm_memory_gb\": {\"0.6B\": 3, \"1.7B\": 8, \"4B\": 12},\n    },\n    \"unlimited\": {  # >= 24GB\n        \"max_duration_with_lm\": 600,  # 10 minutes (max supported)\n        \"max_duration_without_lm\": 600,  # 10 minutes\n        \"max_batch_size_with_lm\": 8,\n        \"max_batch_size_without_lm\": 8,\n        \"init_lm_default\": True,\n        \"available_lm_models\": [\n            \"acestep-5Hz-lm-0.6B\",\n            \"acestep-5Hz-lm-1.7B\",\n            \"acestep-5Hz-lm-4B\",\n        ],\n        \"recommended_lm_model\": \"acestep-5Hz-lm-4B\",\n        \"lm_backend_restriction\": \"all\",\n        \"recommended_backend\": \"vllm\",\n        \"offload_to_cpu_default\": False,\n        \"offload_dit_to_cpu_default\": False,\n        \"quantization_default\": False,  # Plenty of VRAM\n        \"compile_model_default\": True,\n        \"lm_memory_gb\": {\"0.6B\": 3, \"1.7B\": 8, \"4B\": 12},\n    },\n}\n\n# Backward compatibility alias: code that references \"tier6\" gets tier6b behavior\nGPU_TIER_CONFIGS[\"tier6\"] = GPU_TIER_CONFIGS[\"tier6b\"]\n\n\ndef get_gpu_memory_gb() -> float:\n    \"\"\"\n    Get GPU memory in GB. Returns 0 if no GPU is available.\n\n    Debug Mode:\n        Set environment variable MAX_CUDA_VRAM to override the detected GPU memory.\n        Example: MAX_CUDA_VRAM=8 python acestep  # Simulates 8GB GPU\n\n        For MPS testing, set MAX_MPS_VRAM to override MPS memory detection.\n        Example: MAX_MPS_VRAM=16 python acestep  # Simulates 16GB MPS\n\n        This allows testing different GPU tier configurations on high-end hardware.\n    \"\"\"\n    # Check for debug override first\n    debug_vram = os.environ.get(DEBUG_MAX_CUDA_VRAM_ENV)\n    if debug_vram is not None:\n        try:\n            simulated_gb = float(debug_vram)\n            logger.warning(\n                f\"⚠️ DEBUG MODE: Simulating GPU memory as {simulated_gb:.1f}GB (set via {DEBUG_MAX_CUDA_VRAM_ENV} environment variable)\"\n            )\n            # Also enforce a hard VRAM cap via PyTorch so that the allocator\n            # cannot use more than the simulated amount.  This makes the\n            # simulation realistic — without it, models still load into the\n            # real (larger) GPU memory and nvitop shows much higher usage.\n            try:\n                import torch\n\n                if torch.cuda.is_available():\n                    total_bytes = torch.cuda.get_device_properties(0).total_memory\n                    total_gb = total_bytes / (1024**3)\n                    if simulated_gb < total_gb:\n                        # When simulating a smaller GPU on a larger one, the host\n                        # GPU's CUDA context is typically much bigger (e.g. A100\n                        # ~1.4GB vs GTX 1060 ~0.3GB).  Using the host context\n                        # would over-penalise the allocator budget.\n                        #\n                        # Instead we use a *reference* context size that matches\n                        # what the target-class GPU would actually have.  Consumer\n                        # GPUs (≤24GB) typically have 0.3-0.5GB context overhead.\n                        REFERENCE_CONTEXT_GB = MODEL_VRAM.get(\"cuda_context\", 0.5)\n                        allocator_budget_gb = max(\n                            0.5, simulated_gb - REFERENCE_CONTEXT_GB\n                        )\n                        fraction = allocator_budget_gb / total_gb\n                        # Clamp to [0.01, 1.0] to satisfy PyTorch constraints\n                        fraction = max(0.01, min(1.0, fraction))\n                        torch.cuda.set_per_process_memory_fraction(fraction)\n                        logger.warning(\n                            f\"⚠️ DEBUG MODE: Set CUDA memory fraction to {fraction:.4f} \"\n                            f\"(allocator_budget={allocator_budget_gb:.2f}GB, \"\n                            f\"ref_context={REFERENCE_CONTEXT_GB:.2f}GB, target={simulated_gb:.1f}GB, \"\n                            f\"total={total_gb:.1f}GB) to enforce hard VRAM cap\"\n                        )\n            except Exception as e:\n                logger.warning(f\"⚠️ DEBUG MODE: Could not enforce CUDA memory cap: {e}\")\n            return simulated_gb\n        except ValueError:\n            logger.warning(\n                f\"Invalid {DEBUG_MAX_CUDA_VRAM_ENV} value: {debug_vram}, ignoring\"\n            )\n    debug_mps_vram = os.environ.get(DEBUG_MAX_MPS_VRAM_ENV)\n    if debug_mps_vram is not None:\n        try:\n            simulated_gb = float(debug_mps_vram)\n            logger.warning(\n                f\"⚠️ DEBUG MODE: Simulating MPS memory as {simulated_gb:.1f}GB (set via {DEBUG_MAX_MPS_VRAM_ENV} environment variable)\"\n            )\n            return simulated_gb\n        except ValueError:\n            logger.warning(\n                f\"Invalid {DEBUG_MAX_MPS_VRAM_ENV} value: {debug_mps_vram}, ignoring\"\n            )\n\n    # XPU debug override\n    debug_xpu_vram = os.environ.get(DEBUG_MAX_XPU_VRAM_ENV)\n    if debug_xpu_vram is not None:\n        try:\n            simulated_gb = float(debug_xpu_vram)\n            logger.warning(\n                f\"⚠️ DEBUG MODE: Simulating XPU memory as {simulated_gb:.1f}GB (set via {DEBUG_MAX_XPU_VRAM_ENV} environment variable)\"\n            )\n            return simulated_gb\n        except ValueError:\n            logger.warning(\n                f\"Invalid {DEBUG_MAX_XPU_VRAM_ENV} value: {debug_xpu_vram}, ignoring\"\n            )\n\n    try:\n        import torch\n\n        if torch.cuda.is_available():\n            # Get total memory of the first GPU in GB\n            total_memory = torch.cuda.get_device_properties(0).total_memory\n            memory_gb = total_memory / (1024**3)  # Convert bytes to GB\n            device_name = torch.cuda.get_device_name(0)\n            is_rocm = hasattr(torch.version, \"hip\") and torch.version.hip is not None\n            if is_rocm:\n                logger.info(\n                    f\"ROCm GPU detected: {device_name} ({memory_gb:.1f} GB, HIP {torch.version.hip})\"\n                )\n            else:\n                logger.info(f\"CUDA GPU detected: {device_name} ({memory_gb:.1f} GB)\")\n            return memory_gb\n        elif hasattr(torch, \"xpu\") and torch.xpu.is_available():\n            # Get total memory of the first XPU in GB\n            total_memory = torch.xpu.get_device_properties(0).total_memory\n            memory_gb = total_memory / (1024**3)  # Convert bytes to GB\n            device_name = getattr(\n                torch.xpu.get_device_properties(0), \"name\", \"Intel XPU\"\n            )\n            logger.info(f\"Intel XPU detected: {device_name} ({memory_gb:.1f} GB)\")\n            return memory_gb\n        elif hasattr(torch.backends, \"mps\") and torch.backends.mps.is_available():\n            mps_module = getattr(torch, \"mps\", None)\n            try:\n                if mps_module is not None and hasattr(\n                    mps_module, \"recommended_max_memory\"\n                ):\n                    total_memory = mps_module.recommended_max_memory()\n                    memory_gb = total_memory / (1024**3)  # Convert bytes to GB\n                    return memory_gb\n                if mps_module is not None and hasattr(\n                    mps_module, \"get_device_properties\"\n                ):\n                    props = mps_module.get_device_properties(0)\n                    total_memory = getattr(props, \"total_memory\", None)\n                    if total_memory:\n                        memory_gb = total_memory / (1024**3)\n                        return memory_gb\n            except Exception as e:\n                logger.warning(f\"Failed to detect MPS memory: {e}\")\n\n            # Fallback: estimate from system unified memory (Apple Silicon shares CPU/GPU RAM)\n            try:\n                import subprocess\n\n                result = subprocess.run(\n                    [\"sysctl\", \"-n\", \"hw.memsize\"],\n                    capture_output=True,\n                    text=True,\n                    timeout=5,\n                )\n                total_system_bytes = int(result.stdout.strip())\n                # MPS can use up to ~75% of unified memory for GPU workloads\n                memory_gb = (total_system_bytes / (1024**3)) * 0.75\n                return memory_gb\n            except Exception:\n                logger.warning(\n                    f\"MPS available but total memory not exposed. Set {DEBUG_MAX_MPS_VRAM_ENV} to enable tiering.\"\n                )\n                # Conservative fallback for M1/M2\n                return 8.0\n        else:\n            # No GPU detected - provide diagnostic information\n            _log_gpu_diagnostic_info(torch)\n            return 0\n    except Exception as e:\n        logger.warning(f\"Failed to detect GPU memory: {e}\")\n        return 0\n\n\ndef _log_gpu_diagnostic_info(torch_module):\n    \"\"\"\n    Log diagnostic information when GPU is not detected to help users troubleshoot.\n\n    Args:\n        torch_module: The torch module to inspect for build information\n    \"\"\"\n    logger.warning(\"=\" * 80)\n    logger.warning(\"⚠️ GPU NOT DETECTED - DIAGNOSTIC INFORMATION\")\n    logger.warning(\"=\" * 80)\n\n    # Check PyTorch build type\n    is_rocm_build = (\n        hasattr(torch_module.version, \"hip\") and torch_module.version.hip is not None\n    )\n    is_cuda_build = (\n        hasattr(torch_module.version, \"cuda\") and torch_module.version.cuda is not None\n    )\n\n    if is_rocm_build:\n        logger.warning(\"✓ PyTorch ROCm build detected\")\n        logger.warning(f\"  HIP version: {torch_module.version.hip}\")\n        logger.warning(\"\")\n        logger.warning(\"❌ torch.cuda.is_available() returned False\")\n        logger.warning(\"\")\n        logger.warning(\"Common causes for AMD/ROCm GPUs:\")\n        logger.warning(\"  1. ROCm drivers not installed or not properly configured\")\n        logger.warning(\"  2. GPU not supported by installed ROCm version\")\n        logger.warning(\n            \"  3. Missing or incorrect HSA_OVERRIDE_GFX_VERSION environment variable\"\n        )\n        logger.warning(\"  4. ROCm runtime libraries not in system path\")\n        logger.warning(\"\")\n\n        # Check for common environment variables\n        hsa_override = os.environ.get(\"HSA_OVERRIDE_GFX_VERSION\")\n        if hsa_override:\n            logger.warning(f\"  HSA_OVERRIDE_GFX_VERSION is set to: {hsa_override}\")\n        else:\n            logger.warning(\"  ⚠️ HSA_OVERRIDE_GFX_VERSION is not set\")\n            logger.warning(\"     For RDNA3 GPUs (RX 7000 series, RX 9000 series):\")\n            logger.warning(\n                \"       - RX 7900 XT/XTX, RX 9070 XT: set HSA_OVERRIDE_GFX_VERSION=11.0.0\"\n            )\n            logger.warning(\n                \"       - RX 7800 XT, RX 7700 XT: set HSA_OVERRIDE_GFX_VERSION=11.0.1\"\n            )\n            logger.warning(\"       - RX 7600: set HSA_OVERRIDE_GFX_VERSION=11.0.2\")\n\n        logger.warning(\"\")\n        logger.warning(\"Troubleshooting steps:\")\n        logger.warning(\"  1. Verify ROCm installation:\")\n        logger.warning(\"     rocm-smi  # Should list your GPU\")\n        logger.warning(\"  2. Check PyTorch ROCm build:\")\n        logger.warning(\n            \"     python -c \\\"import torch; print(f'ROCm: {torch.version.hip}')\\\"\"\n        )\n        logger.warning(\"  3. Set HSA_OVERRIDE_GFX_VERSION for your GPU (see above)\")\n        logger.warning(\n            \"  4. On Windows: Use start_gradio_ui_rocm.bat which sets required env vars\"\n        )\n        logger.warning(\n            \"  5. See docs/en/ACE-Step1.5-Rocm-Manual-Linux.md for Linux setup\"\n        )\n        logger.warning(\n            \"  6. See requirements-rocm.txt for Windows ROCm setup instructions\"\n        )\n\n    elif is_cuda_build:\n        logger.warning(\"✓ PyTorch CUDA build detected\")\n        logger.warning(f\"  CUDA version: {torch_module.version.cuda}\")\n        logger.warning(\"\")\n        logger.warning(\"❌ torch.cuda.is_available() returned False\")\n        logger.warning(\"\")\n        logger.warning(\"Common causes for NVIDIA GPUs:\")\n        logger.warning(\"  1. NVIDIA drivers not installed\")\n        logger.warning(\"  2. CUDA runtime not installed or version mismatch\")\n        logger.warning(\"  3. GPU not supported by installed CUDA version\")\n        logger.warning(\"\")\n        logger.warning(\"Troubleshooting steps:\")\n        logger.warning(\"  1. Verify NVIDIA driver installation:\")\n        logger.warning(\"     nvidia-smi  # Should list your GPU\")\n        logger.warning(\"  2. Check CUDA version compatibility\")\n        logger.warning(\"  3. Reinstall PyTorch with CUDA support:\")\n        logger.warning(f\"     pip install torch --index-url {PYTORCH_CUDA_INSTALL_URL}\")\n\n    else:\n        logger.warning(\"⚠️ PyTorch build type: CPU-only\")\n        logger.warning(\"\")\n        logger.warning(\"You have installed a CPU-only version of PyTorch!\")\n        logger.warning(\"\")\n        logger.warning(\"For NVIDIA GPUs:\")\n        logger.warning(f\"  pip install torch --index-url {PYTORCH_CUDA_INSTALL_URL}\")\n        logger.warning(\"\")\n        logger.warning(\"For AMD GPUs with ROCm:\")\n        logger.warning(\"  Windows: See requirements-rocm.txt for detailed instructions\")\n        logger.warning(\n            f\"  Linux: pip install torch --index-url {PYTORCH_ROCM_INSTALL_URL}\"\n        )\n        logger.warning(\"\")\n        logger.warning(\"For more information, see README.md section 'AMD / ROCm GPUs'\")\n\n    logger.warning(\"=\" * 80)\n\n\ndef get_gpu_tier(gpu_memory_gb: float) -> str:\n    \"\"\"\n    Determine GPU tier based on available memory.\n\n    Args:\n        gpu_memory_gb: GPU memory in GB\n\n    Returns:\n        Tier string: \"tier1\", \"tier2\", \"tier3\", \"tier4\", \"tier5\", \"tier6a\", \"tier6b\", or \"unlimited\"\n    \"\"\"\n    if gpu_memory_gb <= 0:\n        # CPU mode - use tier1 limits\n        return \"tier1\"\n    elif gpu_memory_gb <= 4:\n        return \"tier1\"\n    elif gpu_memory_gb <= 6:\n        return \"tier2\"\n    elif gpu_memory_gb <= 8:\n        return \"tier3\"\n    elif gpu_memory_gb <= 12:\n        return \"tier4\"\n    elif gpu_memory_gb < VRAM_16GB_MIN_GB:\n        return \"tier5\"\n    elif gpu_memory_gb < VRAM_AUTO_OFFLOAD_THRESHOLD_GB:\n        # 16-20GB range: tier6a (constrained, needs offload)\n        if gpu_memory_gb < 16.0:\n            logger.info(\n                f\"Detected {gpu_memory_gb:.2f}GB VRAM — treating as 16GB class GPU\"\n            )\n        return \"tier6a\"\n    elif gpu_memory_gb <= 24:\n        return \"tier6b\"\n    else:\n        return \"unlimited\"\n\n\ndef get_gpu_config(gpu_memory_gb: Optional[float] = None) -> GPUConfig:\n    \"\"\"\n    Get GPU configuration based on detected or provided GPU memory.\n\n    On macOS with MPS (Apple Silicon), several overrides are applied\n    automatically regardless of the tier selected by memory size:\n\n    - ``compile_model_default = False`` — ``torch.compile`` is not supported\n      on MPS and would error or silently fall back to eager mode.\n    - ``quantization_default = False`` — torchao INT8 quantization is\n      incompatible with MPS / macOS.\n    - ``recommended_backend = \"mlx\"`` — MLX provides native Apple Silicon\n      acceleration for the 5Hz LM; vllm requires CUDA.\n    - ``lm_backend_restriction = \"pt_mlx_only\"`` — vllm cannot run on MPS.\n    - ``offload_to_cpu_default = False`` — Apple Silicon uses unified memory;\n      offloading to CPU provides no benefit and adds overhead.\n    - ``offload_dit_to_cpu_default = False`` — same reason.\n\n    Args:\n        gpu_memory_gb: GPU memory in GB. If None, will be auto-detected.\n\n    Returns:\n        GPUConfig object with all configuration parameters\n    \"\"\"\n    if gpu_memory_gb is None:\n        gpu_memory_gb = get_gpu_memory_gb()\n\n    tier = get_gpu_tier(gpu_memory_gb)\n    config = GPU_TIER_CONFIGS[tier]\n\n    # --- MPS (Apple Silicon) overrides ---\n    _mps = is_mps_platform()\n    if _mps:\n        logger.info(\n            f\"macOS MPS detected ({gpu_memory_gb:.1f} GB unified memory, tier={tier}). \"\n            \"Applying Apple Silicon optimizations: no compile, no quantization, \"\n            \"mlx backend, no CPU offload.\"\n        )\n\n    return GPUConfig(\n        tier=tier,\n        gpu_memory_gb=gpu_memory_gb,\n        max_duration_with_lm=config[\"max_duration_with_lm\"],\n        max_duration_without_lm=config[\"max_duration_without_lm\"],\n        max_batch_size_with_lm=config[\"max_batch_size_with_lm\"],\n        max_batch_size_without_lm=config[\"max_batch_size_without_lm\"],\n        init_lm_default=config[\"init_lm_default\"],\n        available_lm_models=config[\"available_lm_models\"],\n        recommended_lm_model=config.get(\"recommended_lm_model\", \"\"),\n        # MPS: vllm requires CUDA, restrict to pt/mlx; prefer mlx for native acceleration\n        lm_backend_restriction=\"pt_mlx_only\"\n        if _mps\n        else config.get(\"lm_backend_restriction\", \"all\"),\n        recommended_backend=\"mlx\"\n        if _mps\n        else config.get(\"recommended_backend\", \"vllm\"),\n        # MPS: unified memory — offloading to CPU is pointless overhead\n        offload_to_cpu_default=False\n        if _mps\n        else config.get(\"offload_to_cpu_default\", True),\n        offload_dit_to_cpu_default=False\n        if _mps\n        else config.get(\"offload_dit_to_cpu_default\", True),\n        # MPS: torchao quantization is not supported\n        quantization_default=False\n        if _mps\n        else config.get(\"quantization_default\", True),\n        # MPS: torch.compile unsupported (redirected to mx.compile at runtime);\n        # default to False — user can opt in via the UI checkbox.\n        compile_model_default=False\n        if _mps\n        else config.get(\"compile_model_default\", True),\n        lm_memory_gb=config[\"lm_memory_gb\"],\n    )\n\n\ndef get_lm_model_size(model_path: str) -> str:\n    \"\"\"\n    Extract LM model size from model path.\n\n    Args:\n        model_path: Model path string (e.g., \"acestep-5Hz-lm-0.6B\", \"acestep-5Hz-lm-0.6B-v4-fix\")\n\n    Returns:\n        Model size string: \"0.6B\", \"1.7B\", or \"4B\"\n    \"\"\"\n    if \"0.6B\" in model_path:\n        return \"0.6B\"\n    elif \"1.7B\" in model_path:\n        return \"1.7B\"\n    elif \"4B\" in model_path:\n        return \"4B\"\n    else:\n        # Default to smallest model assumption\n        return \"0.6B\"\n\n\ndef is_lm_model_size_allowed(\n    disk_model_name: str, tier_available_models: List[str]\n) -> bool:\n    \"\"\"\n    Check if a disk LM model is allowed by the tier's available models list.\n\n    Uses size-based matching so that variants like \"acestep-5Hz-lm-0.6B-v4-fix\"\n    are correctly matched against \"acestep-5Hz-lm-0.6B\" in the tier config.\n\n    Args:\n        disk_model_name: Actual model directory name on disk (e.g., \"acestep-5Hz-lm-0.6B-v4-fix\")\n        tier_available_models: List of tier-allowed model base names (e.g., [\"acestep-5Hz-lm-0.6B\"])\n\n    Returns:\n        True if the model's size class is allowed by the tier\n    \"\"\"\n    if not tier_available_models:\n        return False\n    model_size = get_lm_model_size(disk_model_name)\n    for tier_model in tier_available_models:\n        if model_size == get_lm_model_size(tier_model):\n            return True\n    return False\n\n\ndef find_best_lm_model_on_disk(\n    recommended_model: str, disk_models: List[str]\n) -> Optional[str]:\n    \"\"\"\n    Find the best matching disk model for a recommended tier model.\n\n    If the exact recommended model exists on disk, return it.\n    Otherwise, find a disk model with the same size class (e.g., \"0.6B\").\n    Prefers models with version suffixes (e.g., \"-v4-fix\") as they are likely newer.\n\n    Args:\n        recommended_model: Tier-recommended model name (e.g., \"acestep-5Hz-lm-0.6B\")\n        disk_models: List of model names actually on disk\n\n    Returns:\n        Best matching disk model name, or None if no match\n    \"\"\"\n    if not recommended_model or not disk_models:\n        return disk_models[0] if disk_models else None\n\n    # Exact match first\n    if recommended_model in disk_models:\n        return recommended_model\n\n    # Size-based match: find all disk models with same size\n    target_size = get_lm_model_size(recommended_model)\n    candidates = [m for m in disk_models if get_lm_model_size(m) == target_size]\n\n    if candidates:\n        # Prefer the one with the longest name (likely has version suffix = newer)\n        return max(candidates, key=len)\n\n    # No match for recommended size; return first available disk model\n    return disk_models[0] if disk_models else None\n\n\ndef get_lm_gpu_memory_ratio(\n    model_path: str, total_gpu_memory_gb: float\n) -> Tuple[float, float]:\n    \"\"\"\n    Calculate GPU memory utilization ratio for LM model.\n\n    This function now uses *actually free* VRAM (via torch.cuda.mem_get_info)\n    when available, instead of computing the ratio purely from total VRAM.\n    This is critical because DiT, VAE, and text encoder are already loaded\n    when the LM initializes, so the \"available\" memory is much less than total.\n\n    Args:\n        model_path: LM model path (e.g., \"acestep-5Hz-lm-0.6B\")\n        total_gpu_memory_gb: Total GPU memory in GB (used as fallback)\n\n    Returns:\n        Tuple of (gpu_memory_utilization_ratio, target_memory_gb)\n    \"\"\"\n    model_size = get_lm_model_size(model_path)\n\n    # Use empirical LM VRAM measurements for target memory\n    lm_info = LM_VRAM.get(model_size, LM_VRAM[\"0.6B\"])\n    lm_weights_gb = lm_info[\"weights\"]\n    lm_kv_cache_gb = lm_info[\"kv_cache_4k\"]\n\n    # Total target = model weights + KV cache + small overhead\n    target_gb = lm_weights_gb\n    total_target_gb = lm_weights_gb + lm_kv_cache_gb + 0.3  # 0.3 GB overhead\n\n    # Try to use actual free memory for a more accurate ratio\n    free_gb = None\n    try:\n        import torch\n\n        if torch.cuda.is_available():\n            free_bytes, total_bytes = torch.cuda.mem_get_info()\n            free_gb = free_bytes / (1024**3)\n            actual_total_gb = total_bytes / (1024**3)\n\n            # If MAX_CUDA_VRAM is set, use the simulated values instead\n            # because set_per_process_memory_fraction limits actual allocation\n            debug_vram = os.environ.get(DEBUG_MAX_CUDA_VRAM_ENV)\n            if debug_vram is not None:\n                try:\n                    simulated_gb = float(debug_vram)\n                    if simulated_gb < actual_total_gb:\n                        # Use reference context (matching set_per_process_memory_fraction)\n                        ref_context_gb = MODEL_VRAM.get(\"cuda_context\", 0.5)\n                        allocator_budget_gb = max(0.5, simulated_gb - ref_context_gb)\n                        reserved_gb = torch.cuda.memory_reserved() / (1024**3)\n                        free_gb = max(0, allocator_budget_gb - reserved_gb)\n                        actual_total_gb = simulated_gb\n                except (ValueError, TypeError):\n                    pass\n\n            # The ratio is relative to total GPU memory (nano-vllm convention),\n            # but we compute it so that the LM only claims what's actually free\n            # minus a safety margin for DiT inference activations.\n            # Reserve at least 1.5 GB for DiT inference activations\n            dit_reserve_gb = 1.5\n            usable_for_lm = max(0, free_gb - dit_reserve_gb - VRAM_SAFETY_MARGIN_GB)\n\n            # Cap to what the LM actually needs\n            usable_for_lm = min(usable_for_lm, total_target_gb)\n\n            # Convert to ratio of total GPU memory\n            # nano-vllm uses: target_total_usage = total * gpu_memory_utilization\n            # We want: (total * ratio) = current_usage + usable_for_lm\n            current_usage_gb = actual_total_gb - free_gb\n            desired_total_usage = current_usage_gb + usable_for_lm\n            ratio = desired_total_usage / actual_total_gb\n\n            ratio = min(0.9, max(0.1, ratio))\n\n            logger.info(\n                f\"[get_lm_gpu_memory_ratio] model={model_size}, free={free_gb:.2f}GB, \"\n                f\"current_usage={current_usage_gb:.2f}GB, lm_target={total_target_gb:.2f}GB, \"\n                f\"usable_for_lm={usable_for_lm:.2f}GB, ratio={ratio:.3f}\"\n            )\n            return ratio, target_gb\n    except Exception as e:\n        logger.warning(\n            f\"[get_lm_gpu_memory_ratio] Failed to query free VRAM: {e}, using fallback\"\n        )\n\n    # Fallback: compute ratio from total VRAM (less accurate)\n    if total_gpu_memory_gb >= 24:\n        ratio = min(0.9, max(0.2, total_target_gb / total_gpu_memory_gb))\n    else:\n        ratio = min(0.9, max(0.1, total_target_gb / total_gpu_memory_gb))\n\n    return ratio, target_gb\n\n\ndef compute_adaptive_config(total_vram_gb: float, dit_type: str = \"turbo\") -> GPUConfig:\n    \"\"\"\n    Compute GPU configuration based on what actually fits in VRAM.\n\n    This is a VRAM-budget-based approach: instead of hard-coded tier boundaries,\n    we calculate how much memory each component needs and determine what fits.\n\n    Args:\n        total_vram_gb: Total GPU VRAM in GB\n        dit_type: \"turbo\" or \"base\" (affects inference VRAM due to CFG)\n\n    Returns:\n        GPUConfig with parameters that fit within the VRAM budget\n    \"\"\"\n    # Calculate base VRAM usage (always loaded)\n    dit_key = f\"dit_{dit_type}\" if f\"dit_{dit_type}\" in MODEL_VRAM else \"dit_turbo\"\n    base_usage = (\n        MODEL_VRAM[dit_key]\n        + MODEL_VRAM[\"vae\"]\n        + MODEL_VRAM[\"text_encoder\"]\n        + MODEL_VRAM[\"cuda_context\"]\n        + MODEL_VRAM[\"silence_latent\"]\n        + VRAM_SAFETY_MARGIN_GB\n    )\n\n    available = total_vram_gb - base_usage\n\n    if available <= 0:\n        # Not enough for even base models - CPU offload required\n        return get_gpu_config(total_vram_gb)\n\n    # Determine which LM models fit\n    available_lm_models = []\n    lm_memory_gb = {}\n\n    for size_key in [\"0.6B\", \"1.7B\", \"4B\"]:\n        lm_info = LM_VRAM[size_key]\n        lm_total = lm_info[\"weights\"] + lm_info[\"kv_cache_4k\"]\n        # LM needs to fit with some room left for inference activations\n        inference_per_batch = DIT_INFERENCE_VRAM_PER_BATCH.get(dit_type, 0.8)\n        if lm_total + inference_per_batch <= available:\n            model_name = f\"acestep-5Hz-lm-{size_key}\"\n            available_lm_models.append(model_name)\n            lm_memory_gb[size_key] = lm_info[\"weights\"] + lm_info[\"kv_cache_4k\"]\n\n    # Determine max batch sizes\n    inference_per_batch = DIT_INFERENCE_VRAM_PER_BATCH.get(dit_type, 0.8)\n\n    # Without LM: all available VRAM goes to inference\n    max_batch_no_lm = max(1, int(available / inference_per_batch))\n    max_batch_no_lm = min(max_batch_no_lm, 8)  # Cap at 8\n\n    # With LM: subtract the largest available LM from available\n    if available_lm_models:\n        largest_lm_size = list(lm_memory_gb.keys())[-1]\n        lm_usage = lm_memory_gb[largest_lm_size]\n        remaining_for_inference = available - lm_usage\n        max_batch_with_lm = max(1, int(remaining_for_inference / inference_per_batch))\n        max_batch_with_lm = min(max_batch_with_lm, 8)\n    else:\n        max_batch_with_lm = max_batch_no_lm\n\n    # Determine duration limits based on available VRAM\n    # Longer durations need more VRAM for latents\n    if total_vram_gb >= 24:\n        max_dur_lm = 600\n        max_dur_no_lm = 600\n    elif total_vram_gb >= 20:\n        max_dur_lm = 480\n        max_dur_no_lm = 480\n    elif total_vram_gb >= 16:\n        max_dur_lm = 360\n        max_dur_no_lm = 480\n    elif total_vram_gb >= 12:\n        max_dur_lm = 240\n        max_dur_no_lm = 360\n    elif total_vram_gb >= 8:\n        max_dur_lm = 240\n        max_dur_no_lm = 360\n    else:\n        max_dur_lm = 180\n        max_dur_no_lm = 180\n\n    tier = get_gpu_tier(total_vram_gb)\n    tier_config = GPU_TIER_CONFIGS.get(tier, {})\n\n    return GPUConfig(\n        tier=tier,\n        gpu_memory_gb=total_vram_gb,\n        max_duration_with_lm=max_dur_lm,\n        max_duration_without_lm=max_dur_no_lm,\n        max_batch_size_with_lm=max_batch_with_lm,\n        max_batch_size_without_lm=max_batch_no_lm,\n        init_lm_default=bool(available_lm_models),\n        available_lm_models=available_lm_models,\n        recommended_lm_model=tier_config.get(\n            \"recommended_lm_model\",\n            available_lm_models[0] if available_lm_models else \"\",\n        ),\n        lm_backend_restriction=tier_config.get(\"lm_backend_restriction\", \"all\"),\n        recommended_backend=tier_config.get(\"recommended_backend\", \"vllm\"),\n        offload_to_cpu_default=tier_config.get(\"offload_to_cpu_default\", True),\n        offload_dit_to_cpu_default=tier_config.get(\"offload_dit_to_cpu_default\", True),\n        quantization_default=tier_config.get(\"quantization_default\", True),\n        compile_model_default=tier_config.get(\"compile_model_default\", True),\n        lm_memory_gb=lm_memory_gb,\n    )\n\n\ndef get_effective_free_vram_gb(device_index: int = 0) -> float:\n    \"\"\"\n    Get the effective free VRAM in GB, accounting for PyTorch allocator cache and\n    per-process memory fraction.\n\n    torch.cuda.mem_get_info() reports *device-level* free memory.  After models\n    are loaded, the PyTorch caching allocator may have reserved nearly all VRAM\n    from the OS perspective, making device_free_bytes appear near zero even though\n    the allocator can freely reuse its cached (reserved-but-not-allocated) blocks\n    for new tensors without going back to the OS.\n\n    This function computes:\n        effective_free = device_free_bytes + pytorch_cache_free_bytes\n\n    where pytorch_cache_free_bytes = memory_reserved - memory_allocated.\n\n    When the MAX_CUDA_VRAM debug cap is active it additionally clamps to the\n    simulated allocator budget:\n        effective_free = min(effective_free, allocator_budget - memory_allocated)\n\n    Returns 0 if no GPU is available or on error.\n    \"\"\"\n    try:\n        import torch\n\n        if hasattr(torch, \"cuda\") and torch.cuda.is_available():\n            device_free_bytes, total_bytes = torch.cuda.mem_get_info(device_index)\n\n            # Memory reserved by the PyTorch caching allocator from the OS but not\n            # actively used by live tensors.  This can be reused without a new OS\n            # allocation, so it counts as \"available\" from our perspective.\n            reserved_bytes = torch.cuda.memory_reserved(device_index)\n            allocated_bytes = torch.cuda.memory_allocated(device_index)\n            pytorch_cache_free_bytes = max(0, reserved_bytes - allocated_bytes)\n            effective_free_bytes = device_free_bytes + pytorch_cache_free_bytes\n\n            # Check if a per-process memory fraction has been set\n            # We detect this by checking MAX_CUDA_VRAM env var (our simulation mechanism)\n            debug_vram = os.environ.get(DEBUG_MAX_CUDA_VRAM_ENV)\n            if debug_vram is not None:\n                try:\n                    simulated_gb = float(debug_vram)\n                    total_gb = total_bytes / (1024**3)\n                    if simulated_gb < total_gb:\n                        # Per-process cap is active.\n                        # Use the same reference context as set_per_process_memory_fraction.\n                        ref_context_gb = MODEL_VRAM.get(\"cuda_context\", 0.5)\n                        allocator_budget_gb = max(0.5, simulated_gb - ref_context_gb)\n                        allocator_budget_bytes = allocator_budget_gb * (1024**3)\n                        # Free = what the allocator is allowed minus what it has allocated\n                        process_free = allocator_budget_bytes - allocated_bytes\n                        effective_free_bytes = min(effective_free_bytes, process_free)\n                        return max(0.0, effective_free_bytes / (1024**3))\n                except (ValueError, TypeError):\n                    pass\n\n            return max(0.0, effective_free_bytes / (1024**3))\n\n        elif hasattr(torch, \"xpu\") and torch.xpu.is_available():\n            # Support for Intel XPU (IPEX)\n            # Try mem_get_info first (available in newer IPEX versions)\n            if hasattr(torch.xpu, \"mem_get_info\"):\n                try:\n                    device_free_bytes, _ = torch.xpu.mem_get_info(device_index)\n                    return device_free_bytes / (1024**3)\n                except Exception:\n                    pass\n\n            # Fallback for older IPEX or if mem_get_info fails: total - reserved\n            try:\n                total_bytes = torch.xpu.get_device_properties(device_index).total_memory\n                reserved_bytes = torch.xpu.memory_reserved(device_index)\n                return max(0.0, (total_bytes - reserved_bytes) / (1024**3))\n            except Exception:\n                return 0.0\n\n        return 0.0\n    except Exception:\n        return 0.0\n\n\ndef get_available_vram_gb() -> float:\n    \"\"\"\n    Get currently available (free) GPU VRAM in GB.\n    Returns 0 if no GPU is available or on error.\n\n    This is an alias for get_effective_free_vram_gb() that accounts for\n    per-process memory fraction caps.\n    \"\"\"\n    return get_effective_free_vram_gb()\n\n\ndef estimate_inference_vram(\n    batch_size: int,\n    duration_s: float,\n    dit_type: str = \"turbo\",\n    with_lm: bool = False,\n    lm_size: str = \"0.6B\",\n) -> float:\n    \"\"\"\n    Estimate total VRAM needed for a generation request.\n\n    Args:\n        batch_size: Number of samples to generate\n        duration_s: Audio duration in seconds\n        dit_type: \"turbo\" or \"base\"\n        with_lm: Whether LM is loaded\n        lm_size: LM model size if with_lm is True\n\n    Returns:\n        Estimated VRAM in GB\n    \"\"\"\n    # Base model weights\n    dit_key = f\"dit_{dit_type}\" if f\"dit_{dit_type}\" in MODEL_VRAM else \"dit_turbo\"\n    base = (\n        MODEL_VRAM[dit_key]\n        + MODEL_VRAM[\"vae\"]\n        + MODEL_VRAM[\"text_encoder\"]\n        + MODEL_VRAM[\"cuda_context\"]\n    )\n\n    # DiT inference activations (scales with batch size and duration)\n    per_batch = DIT_INFERENCE_VRAM_PER_BATCH.get(dit_type, 0.8)\n    # Duration scaling: longer audio = more latent frames = more memory\n    duration_factor = max(1.0, duration_s / 60.0)  # Normalize to 60s baseline\n    inference = per_batch * batch_size * duration_factor\n\n    # LM memory\n    lm_mem = 0.0\n    if with_lm and lm_size in LM_VRAM:\n        lm_info = LM_VRAM[lm_size]\n        lm_mem = lm_info[\"weights\"] + lm_info[\"kv_cache_4k\"]\n\n    return base + inference + lm_mem + VRAM_SAFETY_MARGIN_GB\n\n\ndef check_duration_limit(\n    duration: float, gpu_config: GPUConfig, lm_initialized: bool\n) -> Tuple[bool, str]:\n    \"\"\"\n    Check if requested duration is within limits for current GPU configuration.\n\n    Args:\n        duration: Requested duration in seconds\n        gpu_config: Current GPU configuration\n        lm_initialized: Whether LM is initialized\n\n    Returns:\n        Tuple of (is_valid, warning_message)\n    \"\"\"\n    max_duration = (\n        gpu_config.max_duration_with_lm\n        if lm_initialized\n        else gpu_config.max_duration_without_lm\n    )\n\n    if duration > max_duration:\n        warning_msg = (\n            f\"⚠️ Requested duration ({duration:.0f}s) exceeds the limit for your GPU \"\n            f\"({gpu_config.gpu_memory_gb:.1f}GB). Maximum allowed: {max_duration}s \"\n            f\"({'with' if lm_initialized else 'without'} LM). \"\n            f\"Duration will be clamped to {max_duration}s.\"\n        )\n        return False, warning_msg\n\n    return True, \"\"\n\n\ndef check_batch_size_limit(\n    batch_size: int, gpu_config: GPUConfig, lm_initialized: bool\n) -> Tuple[bool, str]:\n    \"\"\"\n    Check if requested batch size is within limits for current GPU configuration.\n\n    Args:\n        batch_size: Requested batch size\n        gpu_config: Current GPU configuration\n        lm_initialized: Whether LM is initialized\n\n    Returns:\n        Tuple of (is_valid, warning_message)\n    \"\"\"\n    max_batch_size = (\n        gpu_config.max_batch_size_with_lm\n        if lm_initialized\n        else gpu_config.max_batch_size_without_lm\n    )\n\n    if batch_size > max_batch_size:\n        warning_msg = (\n            f\"⚠️ Requested batch size ({batch_size}) exceeds the limit for your GPU \"\n            f\"({gpu_config.gpu_memory_gb:.1f}GB). Maximum allowed: {max_batch_size} \"\n            f\"({'with' if lm_initialized else 'without'} LM). \"\n            f\"Batch size will be clamped to {max_batch_size}.\"\n        )\n        return False, warning_msg\n\n    return True, \"\"\n\n\ndef is_lm_model_supported(model_path: str, gpu_config: GPUConfig) -> Tuple[bool, str]:\n    \"\"\"\n    Check if the specified LM model is supported for current GPU configuration.\n\n    Args:\n        model_path: LM model path\n        gpu_config: Current GPU configuration\n\n    Returns:\n        Tuple of (is_supported, warning_message)\n    \"\"\"\n    if not gpu_config.available_lm_models:\n        return False, (\n            f\"⚠️ Your GPU ({gpu_config.gpu_memory_gb:.1f}GB) does not have enough memory \"\n            f\"to run any LM model. Please disable LM initialization.\"\n        )\n\n    model_size = get_lm_model_size(model_path)\n\n    # Check if model size is in available models\n    for available_model in gpu_config.available_lm_models:\n        if model_size in available_model:\n            return True, \"\"\n\n    return False, (\n        f\"⚠️ LM model {model_path} ({model_size}) is not supported for your GPU \"\n        f\"({gpu_config.gpu_memory_gb:.1f}GB). Available models: {', '.join(gpu_config.available_lm_models)}\"\n    )\n\n\ndef get_recommended_lm_model(gpu_config: GPUConfig) -> Optional[str]:\n    \"\"\"\n    Get recommended LM model for current GPU configuration.\n\n    Args:\n        gpu_config: Current GPU configuration\n\n    Returns:\n        Recommended LM model path, or None if LM is not supported\n    \"\"\"\n    if not gpu_config.available_lm_models:\n        return None\n\n    # Return the largest available model (last in the list)\n    return gpu_config.available_lm_models[-1]\n\n\ndef print_gpu_config_info(gpu_config: GPUConfig):\n    \"\"\"Print GPU configuration information for debugging.\"\"\"\n    logger.info(f\"GPU Configuration:\")\n    logger.info(f\"  - GPU Memory: {gpu_config.gpu_memory_gb:.1f} GB\")\n    logger.info(f\"  - Tier: {gpu_config.tier}\")\n    logger.info(\n        f\"  - Max Duration (with LM): {gpu_config.max_duration_with_lm}s ({gpu_config.max_duration_with_lm // 60} min)\"\n    )\n    logger.info(\n        f\"  - Max Duration (without LM): {gpu_config.max_duration_without_lm}s ({gpu_config.max_duration_without_lm // 60} min)\"\n    )\n    logger.info(f\"  - Max Batch Size (with LM): {gpu_config.max_batch_size_with_lm}\")\n    logger.info(\n        f\"  - Max Batch Size (without LM): {gpu_config.max_batch_size_without_lm}\"\n    )\n    logger.info(f\"  - Init LM by Default: {gpu_config.init_lm_default}\")\n    logger.info(f\"  - Available LM Models: {gpu_config.available_lm_models or 'None'}\")\n\n\n# Human-readable tier labels for UI display\nGPU_TIER_LABELS = {\n    \"tier1\": \"tier1 (≤4GB)\",\n    \"tier2\": \"tier2 (4-6GB)\",\n    \"tier3\": \"tier3 (6-8GB)\",\n    \"tier4\": \"tier4 (8-12GB)\",\n    \"tier5\": \"tier5 (12-16GB)\",\n    \"tier6a\": \"tier6a (16-20GB)\",\n    \"tier6b\": \"tier6b (20-24GB)\",\n    \"unlimited\": \"unlimited (≥24GB)\",\n}\n\n# Ordered list of tier keys for dropdown\nGPU_TIER_CHOICES = list(GPU_TIER_LABELS.items())  # [(value, label), ...]\n\n\ndef get_gpu_device_name() -> str:\n    \"\"\"\n    Get the GPU device name string.\n\n    Returns:\n        Human-readable GPU name, e.g. \"NVIDIA GeForce RTX 4060 Ti\",\n        \"Apple M2 Pro (MPS)\", \"CPU only\", etc.\n    \"\"\"\n    try:\n        import torch\n\n        if torch.cuda.is_available():\n            return torch.cuda.get_device_name(0)\n        elif hasattr(torch, \"xpu\") and torch.xpu.is_available():\n            props = torch.xpu.get_device_properties(0)\n            return getattr(props, \"name\", \"Intel XPU\")\n        elif hasattr(torch.backends, \"mps\") and torch.backends.mps.is_available():\n            # MPS doesn't expose a device name; use platform info\n            try:\n                import platform\n\n                chip = platform.processor() or \"Apple Silicon\"\n                return f\"{chip} (MPS)\"\n            except Exception:\n                return \"Apple Silicon (MPS)\"\n        else:\n            return \"CPU only\"\n    except ImportError:\n        return \"Unknown (PyTorch not available)\"\n\n\ndef get_gpu_config_for_tier(tier: str) -> GPUConfig:\n    \"\"\"\n    Create a GPUConfig for a specific tier, applying platform overrides.\n\n    This is used when the user manually selects a different tier in the UI.\n    The actual gpu_memory_gb is preserved from the real hardware detection,\n    but all tier-based settings come from the selected tier's config.\n\n    Args:\n        tier: Tier key, e.g. \"tier3\", \"tier6a\", \"unlimited\"\n\n    Returns:\n        GPUConfig with the selected tier's settings\n    \"\"\"\n    if tier not in GPU_TIER_CONFIGS:\n        logger.warning(f\"Unknown tier '{tier}', falling back to auto-detected config\")\n        return get_gpu_config()\n\n    # Keep the real GPU memory for informational purposes\n    real_gpu_memory = get_gpu_memory_gb()\n    config = GPU_TIER_CONFIGS[tier]\n\n    _mps = is_mps_platform()\n    if _mps:\n        logger.info(\n            f\"Manual tier override to {tier} on macOS MPS — applying Apple Silicon overrides\"\n        )\n\n    return GPUConfig(\n        tier=tier,\n        gpu_memory_gb=real_gpu_memory,\n        max_duration_with_lm=config[\"max_duration_with_lm\"],\n        max_duration_without_lm=config[\"max_duration_without_lm\"],\n        max_batch_size_with_lm=config[\"max_batch_size_with_lm\"],\n        max_batch_size_without_lm=config[\"max_batch_size_without_lm\"],\n        init_lm_default=config[\"init_lm_default\"],\n        available_lm_models=config[\"available_lm_models\"],\n        recommended_lm_model=config.get(\"recommended_lm_model\", \"\"),\n        lm_backend_restriction=\"pt_mlx_only\"\n        if _mps\n        else config.get(\"lm_backend_restriction\", \"all\"),\n        recommended_backend=\"mlx\"\n        if _mps\n        else config.get(\"recommended_backend\", \"vllm\"),\n        offload_to_cpu_default=False\n        if _mps\n        else config.get(\"offload_to_cpu_default\", True),\n        offload_dit_to_cpu_default=False\n        if _mps\n        else config.get(\"offload_dit_to_cpu_default\", True),\n        quantization_default=False\n        if _mps\n        else config.get(\"quantization_default\", True),\n        compile_model_default=False\n        if _mps\n        else config.get(\"compile_model_default\", True),\n        lm_memory_gb=config[\"lm_memory_gb\"],\n    )\n\n\n# Global GPU config instance (initialized lazily)\n_global_gpu_config: Optional[GPUConfig] = None\n\n\ndef get_global_gpu_config() -> GPUConfig:\n    \"\"\"Get the global GPU configuration, initializing if necessary.\"\"\"\n    global _global_gpu_config\n    if _global_gpu_config is None:\n        _global_gpu_config = get_gpu_config()\n    return _global_gpu_config\n\n\ndef set_global_gpu_config(config: GPUConfig):\n    \"\"\"Set the global GPU configuration.\"\"\"\n    global _global_gpu_config\n    _global_gpu_config = config\n"
  },
  {
    "path": "acestep/gpu_config_effective_free_vram_test.py",
    "content": "\"\"\"Tests for ``get_effective_free_vram_gb`` in ``gpu_config``.\n\nValidates that the function correctly accounts for the PyTorch caching\nallocator's reserved-but-unused memory so that VRAM checks do not\nincorrectly report 0 GB free on machines where all VRAM appears reserved\nfrom the OS perspective but is still internally reusable.\n\"\"\"\n\nimport os\nimport sys\nimport unittest\nfrom unittest.mock import MagicMock, patch\n\nimport acestep.gpu_config as _GPU_CONFIG_MOD\nfrom acestep.gpu_config import get_effective_free_vram_gb\n\n\ndef _make_torch_cuda_mock(\n    device_free_bytes: int,\n    total_bytes: int,\n    reserved_bytes: int,\n    allocated_bytes: int,\n) -> MagicMock:\n    \"\"\"Build a ``torch`` mock whose ``.cuda`` reports deterministic memory stats.\n\n    Args:\n        device_free_bytes: Bytes free at the CUDA-driver level.\n        total_bytes: Total GPU memory in bytes.\n        reserved_bytes: Bytes reserved by the PyTorch caching allocator.\n        allocated_bytes: Bytes actively allocated to live tensors.\n\n    Returns:\n        A ``MagicMock`` that stands in for the ``torch`` module.\n    \"\"\"\n    mock_cuda = MagicMock()\n    mock_cuda.is_available.return_value = True\n    mock_cuda.mem_get_info.return_value = (device_free_bytes, total_bytes)\n    mock_cuda.memory_reserved.return_value = reserved_bytes\n    mock_cuda.memory_allocated.return_value = allocated_bytes\n\n    mock_torch = MagicMock()\n    mock_torch.cuda = mock_cuda\n    # xpu should appear unavailable so the CUDA branch is taken\n    mock_torch.xpu.is_available.return_value = False\n    return mock_torch\n\n\nclass GetEffectiveFreeVramGbTests(unittest.TestCase):\n    \"\"\"Unit tests for ``get_effective_free_vram_gb``.\"\"\"\n\n    def _run_with_mock(\n        self,\n        mock_torch: MagicMock,\n        debug_vram_env: str | None = None,\n    ) -> float:\n        \"\"\"Invoke ``get_effective_free_vram_gb`` with ``torch`` injected via sys.modules.\n\n        The function does ``import torch`` locally, so we inject our mock into\n        ``sys.modules[\"torch\"]`` for the duration of the call.\n\n        Args:\n            mock_torch: Replacement ``torch`` module mock.\n            debug_vram_env: Value for the ``MAX_CUDA_VRAM`` environment variable,\n                or ``None`` to leave it unset.\n\n        Returns:\n            The float returned by ``get_effective_free_vram_gb()``.\n        \"\"\"\n        env_overrides = {}\n        if debug_vram_env is not None:\n            env_overrides[\"MAX_CUDA_VRAM\"] = debug_vram_env\n\n        original_torch = sys.modules.get(\"torch\")\n        sys.modules[\"torch\"] = mock_torch\n        # Remove MAX_CUDA_VRAM from the environment so the non-debug path is\n        # exercised unless the caller explicitly provides a value.\n        saved_env = os.environ.pop(\"MAX_CUDA_VRAM\", None)\n        try:\n            with patch.dict(\"os.environ\", env_overrides, clear=False):\n                return get_effective_free_vram_gb()\n        finally:\n            if original_torch is None:\n                sys.modules.pop(\"torch\", None)\n            else:\n                sys.modules[\"torch\"] = original_torch\n            if saved_env is not None:\n                os.environ[\"MAX_CUDA_VRAM\"] = saved_env\n\n    def test_includes_pytorch_cache_when_device_free_is_zero(self):\n        \"\"\"Returns non-zero free VRAM when device-level free is 0 but allocator cache exists.\n\n        This is the primary regression: models fully occupy VRAM from the OS\n        perspective (device_free == 0), but PyTorch's caching allocator holds\n        reserved-but-not-allocated memory that can be reused for inference.\n        \"\"\"\n        GB = 1024 ** 3\n        # Simulate 24 GB card: all reserved by PyTorch, 20 GB actively used\n        mock_torch = _make_torch_cuda_mock(\n            device_free_bytes=0,\n            total_bytes=24 * GB,\n            reserved_bytes=24 * GB,\n            allocated_bytes=20 * GB,\n        )\n        result = self._run_with_mock(mock_torch)\n\n        # Expected: 0 (device free) + (24 - 20) GB allocator cache = 4 GB\n        self.assertAlmostEqual(result, 4.0, places=2)\n\n    def test_sums_device_free_and_allocator_cache(self):\n        \"\"\"Returns device_free + allocator_cache when both are non-zero.\"\"\"\n        GB = 1024 ** 3\n        mock_torch = _make_torch_cuda_mock(\n            device_free_bytes=2 * GB,\n            total_bytes=24 * GB,\n            reserved_bytes=18 * GB,\n            allocated_bytes=16 * GB,\n        )\n        result = self._run_with_mock(mock_torch)\n\n        # Expected: 2 (device free) + (18 - 16) allocator cache = 4 GB\n        self.assertAlmostEqual(result, 4.0, places=2)\n\n    def test_returns_zero_when_fully_allocated_no_cache(self):\n        \"\"\"Returns 0 when device free is 0 and all reserved memory is allocated.\"\"\"\n        GB = 1024 ** 3\n        mock_torch = _make_torch_cuda_mock(\n            device_free_bytes=0,\n            total_bytes=8 * GB,\n            reserved_bytes=8 * GB,\n            allocated_bytes=8 * GB,\n        )\n        result = self._run_with_mock(mock_torch)\n\n        self.assertAlmostEqual(result, 0.0, places=2)\n\n    def test_returns_zero_when_cuda_unavailable(self):\n        \"\"\"Returns 0 when no CUDA device is present.\"\"\"\n        mock_torch = MagicMock()\n        mock_torch.cuda.is_available.return_value = False\n        mock_torch.xpu.is_available.return_value = False\n\n        result = self._run_with_mock(mock_torch)\n\n        self.assertEqual(result, 0.0)\n\n    def test_debug_cap_clamps_effective_free(self):\n        \"\"\"Debug MAX_CUDA_VRAM cap limits reported free to the simulated budget.\"\"\"\n        GB = 1024 ** 3\n        # Real card: 80 GB; simulating 8 GB; 5 GB allocated, 7 GB reserved\n        mock_torch = _make_torch_cuda_mock(\n            device_free_bytes=0,\n            total_bytes=80 * GB,\n            reserved_bytes=7 * GB,\n            allocated_bytes=5 * GB,\n        )\n        result = self._run_with_mock(mock_torch, debug_vram_env=\"8\")\n\n        # Allocator budget = 8 - 0.5 (context) = 7.5 GB\n        # process_free = 7.5 - 5 (allocated) = 2.5 GB\n        # effective without cap = device_free (0) + pytorch_cache (7 reserved - 5 allocated) = 2 GB\n        # clamped = min(2, 2.5) = 2 GB\n        self.assertAlmostEqual(result, 2.0, places=1)\n\n\nif __name__ == \"__main__\":\n    unittest.main()\n"
  },
  {
    "path": "acestep/handler.py",
    "content": "\"\"\"\nBusiness Logic Handler\nEncapsulates all data processing and business logic as a bridge between model and UI\n\"\"\"\nimport os\nimport sys\n\n# Disable tokenizers parallelism to avoid fork warning\nos.environ[\"TOKENIZERS_PARALLELISM\"] = \"false\"\n\nimport threading\nfrom typing import Optional\n\nimport torch\nimport warnings\n\nfrom acestep.core.generation.handler import (\n    AudioCodesMixin,\n    BatchPrepMixin,\n    ConditioningBatchMixin,\n    ConditioningEmbedMixin,\n    ConditioningMaskMixin,\n    ConditioningTargetMixin,\n    ConditioningTextMixin,\n    DiffusionMixin,\n    GenerateMusicDecodeMixin,\n    GenerateMusicExecuteMixin,\n    GenerateMusicMixin,\n    GenerateMusicPayloadMixin,\n    GenerateMusicRequestMixin,\n    InitServiceMixin,\n    IoAudioMixin,\n    LyricScoreMixin,\n    LyricTimestampMixin,\n    LoraManagerMixin,\n    MemoryUtilsMixin,\n    MetadataMixin,\n    MlxDitInitMixin,\n    MlxVaeDecodeNativeMixin,\n    MlxVaeEncodeNativeMixin,\n    MlxVaeInitMixin,\n    PaddingMixin,\n    ProgressMixin,\n    PromptMixin,\n    ServiceGenerateMixin,\n    TrainingPresetMixin,\n    TaskUtilsMixin,\n    VaeDecodeChunksMixin,\n    VaeDecodeMixin,\n    VaeEncodeChunksMixin,\n    VaeEncodeMixin,\n    ServiceGenerateRequestMixin,\n    ServiceGenerateExecuteMixin,\n    ServiceGenerateOutputsMixin,\n)\n\n\nwarnings.filterwarnings(\"ignore\")\n\n\nclass AceStepHandler(\n    DiffusionMixin,\n    GenerateMusicMixin,\n    GenerateMusicDecodeMixin,\n    GenerateMusicPayloadMixin,\n    GenerateMusicExecuteMixin,\n    GenerateMusicRequestMixin,\n    AudioCodesMixin,\n    BatchPrepMixin,\n    ConditioningBatchMixin,\n    ConditioningEmbedMixin,\n    ConditioningMaskMixin,\n    ConditioningTargetMixin,\n    ConditioningTextMixin,\n    IoAudioMixin,\n    InitServiceMixin,\n    LyricScoreMixin,\n    LyricTimestampMixin,\n    LoraManagerMixin,\n    MemoryUtilsMixin,\n    MetadataMixin,\n    MlxDitInitMixin,\n    MlxVaeDecodeNativeMixin,\n    MlxVaeEncodeNativeMixin,\n    MlxVaeInitMixin,\n    PaddingMixin,\n    ProgressMixin,\n    PromptMixin,\n    ServiceGenerateMixin,\n    TrainingPresetMixin,\n    TaskUtilsMixin,\n    VaeDecodeChunksMixin,\n    VaeDecodeMixin,\n    VaeEncodeChunksMixin,\n    VaeEncodeMixin,\n    ServiceGenerateRequestMixin,\n    ServiceGenerateExecuteMixin,\n    ServiceGenerateOutputsMixin,\n):\n    \"\"\"ACE-Step Business Logic Handler\"\"\"\n    \n    def __init__(self):\n        \"\"\"Initialize runtime model handles, feature flags, and generation state.\"\"\"\n        self.model = None\n        self.config = None\n        self.device = \"cpu\"\n        self.dtype = torch.float32  # Will be set based on device in initialize_service\n\n        # VAE for audio encoding/decoding\n        self.vae = None\n        \n        # Text encoder and tokenizer\n        self.text_encoder = None\n        self.text_tokenizer = None\n        \n        # Silence latent for initialization\n        self.silence_latent = None\n        \n        # Sample rate\n        self.sample_rate = 48000\n        \n        # Reward model (temporarily disabled)\n        self.reward_model = None\n        \n        # Batch size\n        self.batch_size = 2\n        \n        # Custom layers config\n        self.custom_layers_config = {2: [6], 3: [10, 11], 4: [3], 5: [8, 9], 6: [8]}\n        self.offload_to_cpu = False\n        self.offload_dit_to_cpu = False\n        self.compiled = False\n        self.current_offload_cost = 0.0\n        self.disable_tqdm = os.environ.get(\"ACESTEP_DISABLE_TQDM\", \"\").lower() in (\"1\", \"true\", \"yes\") or not getattr(sys.stderr, 'isatty', lambda: False)()\n        self.debug_stats = os.environ.get(\"ACESTEP_DEBUG_STATS\", \"\").lower() in (\"1\", \"true\", \"yes\")\n        self._last_diffusion_per_step_sec: Optional[float] = None\n        self._progress_estimates_lock = threading.Lock()\n        self._progress_estimates = {\"records\": []}\n        self._progress_estimates_path = os.path.join(\n            self._get_project_root(),\n            \".cache\",\n            \"acestep\",\n            \"progress_estimates.json\",\n        )\n        self._load_progress_estimates()\n        self.last_init_params = None\n        \n        # Quantization state - tracks if model is quantized (int8_weight_only, fp8_weight_only, or w8a8_dynamic)\n        # Populated during initialize_service, remains None if quantization is disabled\n        self.quantization = None\n        \n        # LoRA state\n        self.lora_loaded = False\n        self.use_lora = False\n        self.lora_scale = 1.0  # LoRA influence scale (0-1), mirrors active adapter's scale\n        self._base_decoder = None  # Backup of original decoder state_dict (CPU) for memory efficiency\n        self._active_loras = {}  # adapter_name -> scale (per-adapter)\n        self._lora_adapter_registry = {}  # adapter_name -> explicit scaling targets\n        self._lora_active_adapter = None\n\n        # MLX DiT acceleration (macOS Apple Silicon only)\n        self.mlx_decoder = None\n        self.use_mlx_dit = False\n        self.mlx_dit_compiled = False\n\n        # MLX VAE acceleration (macOS Apple Silicon only)\n        self.mlx_vae = None\n        self.use_mlx_vae = False\n\n"
  },
  {
    "path": "acestep/inference.py",
    "content": "\"\"\"\nACE-Step Inference API Module\n\nThis module provides a standardized inference interface for music generation,\ndesigned for third-party integration. It offers both a simplified API and\nbackward-compatible Gradio UI support.\n\"\"\"\n\nimport math\nimport os\nimport tempfile\nfrom typing import Optional, Union, List, Dict, Any, Tuple\nfrom dataclasses import dataclass, field, asdict\nfrom loguru import logger\nimport torch\n\n\nfrom acestep.audio_utils import AudioSaver, apply_fade, generate_uuid_from_params, normalize_audio, get_lora_weights_hash\n\n# HuggingFace Space environment detection\nIS_HUGGINGFACE_SPACE = os.environ.get(\"SPACE_ID\") is not None\n\ndef _get_spaces_gpu_decorator(duration=180):\n    \"\"\"\n    Get the @spaces.GPU decorator if running in HuggingFace Space environment.\n    Returns identity decorator if not in Space environment.\n    \"\"\"\n    if IS_HUGGINGFACE_SPACE:\n        try:\n            import spaces\n            return spaces.GPU(duration=duration)\n        except ImportError:\n            logger.warning(\"spaces package not found, GPU decorator disabled\")\n            return lambda func: func\n    return lambda func: func\n\n\n@dataclass\nclass GenerationParams:\n    \"\"\"Configuration for music generation parameters.\n    \n    Attributes:\n        # Text Inputs\n        caption: A short text prompt describing the desired music (main prompt). < 512 characters\n        lyrics: Lyrics for the music. Use \"[Instrumental]\" for instrumental songs. < 4096 characters\n        instrumental: If True, generate instrumental music regardless of lyrics.\n        \n        # Music Metadata\n        bpm: BPM (beats per minute), e.g., 120. Set to None for automatic estimation. 30 ~ 300\n        keyscale: Musical key (e.g., \"C Major\", \"Am\"). Leave empty for auto-detection. A-G, #/♭, major/minor\n        timesignature: Time signature (2 for '2/4', 3 for '3/4', 4 for '4/4', 6 for '6/8'). Leave empty for auto-detection.\n        vocal_language: Language code for vocals, e.g., \"en\", \"zh\", \"ja\", or \"unknown\". see acestep/constants.py:VALID_LANGUAGES\n        duration: Target audio length in seconds. If <0 or None, model chooses automatically. 10 ~ 600\n        \n        # Audio Post-Processing\n        enable_normalization: Whether to apply loudness normalization to the output audio.\n        normalization_db: Target loudness in dB for normalization (e.g., -1.0 for -1 dBFS peak).\n        latent_shift: Additive shift applied to DiT latents before VAE decode (default 0, no shift).\n        latent_rescale: Multiplicative rescale applied to DiT latents before VAE decode (default 1.0, no rescale).\n        \n        # Generation Parameters\n        inference_steps: Number of diffusion steps (e.g., 8 for turbo, 32–100 for base model).\n        guidance_scale: CFG (classifier-free guidance) strength. Higher means following the prompt more strictly. Only support for non-turbo model.\n        seed: Integer seed for reproducibility. -1 means use random seed each time.\n        \n        # Advanced DiT Parameters\n        use_adg: Whether to use Adaptive Dual Guidance (only works for base model).\n        cfg_interval_start: Start ratio (0.0–1.0) to apply CFG.\n        cfg_interval_end: End ratio (0.0–1.0) to apply CFG.\n        shift: Timestep shift factor (default 1.0). When != 1.0, applies t = shift * t / (1 + (shift - 1) * t) to timesteps.\n        \n        # Task-Specific Parameters\n        task_type: Type of generation task. One of: \"text2music\", \"cover\", \"repaint\", \"lego\", \"extract\", \"complete\".\n        reference_audio: Path to a reference audio file for style transfer or cover tasks.\n        src_audio: Path to a source audio file for audio-to-audio tasks.\n        audio_codes: Audio semantic codes as a string (advanced use, for code-control generation).\n        repainting_start: For repaint/lego tasks: start time in seconds for region to repaint.\n        repainting_end: For repaint/lego tasks: end time in seconds for region to repaint (-1 for until end).\n        audio_cover_strength: Strength of reference audio/codes influence (range 0.0–1.0). set smaller (0.2) for style transfer tasks.\n        instruction: Optional task instruction prompt. If empty, auto-generated by system.\n        \n        # 5Hz Language Model Parameters for CoT reasoning\n        thinking: If True, enable 5Hz Language Model \"Chain-of-Thought\" reasoning for semantic/music metadata and codes.\n        lm_temperature: Sampling temperature for the LLM (0.0–2.0). Higher = more creative/varied results.\n        lm_cfg_scale: Classifier-free guidance scale for the LLM.\n        lm_top_k: LLM top-k sampling (0 = disabled).\n        lm_top_p: LLM top-p nucleus sampling (1.0 = disabled).\n        lm_negative_prompt: Negative prompt to use for LLM (for control).\n        use_cot_metas: Whether to let LLM generate music metadata via CoT reasoning.\n        use_cot_caption: Whether to let LLM rewrite or format the input caption via CoT reasoning.\n        use_cot_language: Whether to let LLM detect vocal language via CoT.\n    \"\"\"\n    # Required Inputs\n    task_type: str = \"text2music\"\n    instruction: str = \"Fill the audio semantic mask based on the given conditions:\"\n\n    # Audio Uploads\n    reference_audio: Optional[str] = None\n    src_audio: Optional[str] = None\n\n    # LM Codes Hints\n    audio_codes: str = \"\"\n\n    # Text Inputs\n    caption: str = \"\"\n    global_caption: str = \"\"  # Global/song-level caption for SFT-stems lego tasks\n    lyrics: str = \"\"\n    instrumental: bool = False\n\n    # Metadata\n    vocal_language: str = \"unknown\"\n    bpm: Optional[int] = None\n    keyscale: str = \"\"\n    timesignature: str = \"\"\n    duration: float = -1.0\n\n    # Audio Post-Processing\n    enable_normalization: bool = True\n    normalization_db: float = -1.0\n    fade_in_duration: float = 0.0   # Fade in duration in seconds. 0 = no fade in.\n    fade_out_duration: float = 0.0  # Fade out duration in seconds. 0 = no fade out.\n\n    # Latent Post-Processing (before VAE decode)\n    latent_shift: float = 0.0       # Additive shift on DiT latents. Default 0 = no shift.\n    latent_rescale: float = 1.0     # Multiplicative rescale on DiT latents. Default 1.0 = no rescale.\n\n    # Advanced Settings\n    inference_steps: int = 8\n    seed: int = -1\n    guidance_scale: float = 7.0\n    use_adg: bool = False\n    cfg_interval_start: float = 0.0\n    cfg_interval_end: float = 1.0\n    shift: float = 1.0\n    infer_method: str = \"ode\"  # \"ode\" or \"sde\" - diffusion inference method\n    # Custom timesteps (parsed from string like \"0.97,0.76,0.615,0.5,0.395,0.28,0.18,0.085,0\")\n    # If provided, overrides inference_steps and shift\n    timesteps: Optional[List[float]] = None\n\n    repainting_start: float = 0.0\n    repainting_end: float = -1\n    chunk_mask_mode: str = \"auto\"  # \"explicit\" = 0/1 mask from repaint range; \"auto\" = all 2.0 (model decides)\n    repaint_latent_crossfade_frames: int = 10  # latent-level boundary blend width (25Hz frames, 10≈0.4s)\n    repaint_wav_crossfade_sec: float = 0.0  # waveform-level splice crossfade (seconds, 0=hard cut)\n    repaint_mode: str = \"balanced\"  # \"conservative\", \"balanced\", or \"aggressive\"\n    repaint_strength: float = 0.5  # 0.0=aggressive, 1.0=conservative (balanced mode only)\n    audio_cover_strength: float = 1.0\n    cover_noise_strength: float = 0.0  # 0=pure noise (no cover), 1=closest to src audio\n\n    # 5Hz Language Model Parameters\n    thinking: bool = True\n    lm_temperature: float = 0.85\n    lm_cfg_scale: float = 2.0\n    lm_top_k: int = 0\n    lm_top_p: float = 0.9\n    lm_negative_prompt: str = \"NO USER INPUT\"\n    use_cot_metas: bool = True\n    use_cot_caption: bool = True\n    use_cot_lyrics: bool = False  # TODO: not used yet\n    use_cot_language: bool = True\n    use_constrained_decoding: bool = True\n\n    cot_bpm: Optional[int] = None\n    cot_keyscale: str = \"\"\n    cot_timesignature: str = \"\"\n    cot_duration: Optional[float] = None\n    cot_vocal_language: str = \"unknown\"\n    cot_caption: str = \"\"\n    cot_lyrics: str = \"\"\n\n    def to_dict(self) -> Dict[str, Any]:\n        \"\"\"Convert config to dictionary for JSON serialization.\"\"\"\n        return asdict(self)\n\n\n@dataclass\nclass GenerationConfig:\n    \"\"\"Configuration for music generation.\n    \n    Attributes:\n        batch_size: Number of audio samples to generate\n        allow_lm_batch: Whether to allow batch processing in LM\n        use_random_seed: Whether to use random seed\n        seeds: Seed(s) for batch generation. Can be:\n            - None: Use random seeds (when use_random_seed=True) or params.seed (when use_random_seed=False)\n            - List[int]: List of seeds, will be padded with random seeds if fewer than batch_size\n            - int: Single seed value (will be converted to list and padded)\n        lm_batch_chunk_size: Batch chunk size for LM processing\n        constrained_decoding_debug: Whether to enable constrained decoding debug\n        audio_format: Output audio format, one of \"mp3\", \"wav\", \"flac\", \"wav32\", \"opus\", \"aac\". Default: \"flac\"\n    \"\"\"\n    batch_size: int = 2\n    allow_lm_batch: bool = False\n    use_random_seed: bool = True\n    seeds: Optional[List[int]] = None\n    lm_batch_chunk_size: int = 8\n    constrained_decoding_debug: bool = False\n    audio_format: str = \"flac\"  # Default to FLAC for fast saving\n\n    def to_dict(self) -> Dict[str, Any]:\n        \"\"\"Convert config to dictionary for JSON serialization.\"\"\"\n        return asdict(self)\n\n\n@dataclass\nclass GenerationResult:\n    \"\"\"Result of music generation.\n    \n    Attributes:\n        # Audio Outputs\n        audios: List of audio dictionaries with paths, keys, params\n        status_message: Status message from generation\n        extra_outputs: Extra outputs from generation\n        success: Whether generation completed successfully\n        error: Error message if generation failed\n    \"\"\"\n\n    # Audio Outputs\n    audios: List[Dict[str, Any]] = field(default_factory=list)\n    # Generation Information\n    status_message: str = \"\"\n    extra_outputs: Dict[str, Any] = field(default_factory=dict)\n    # Success Status\n    success: bool = True\n    error: Optional[str] = None\n\n    def to_dict(self) -> Dict[str, Any]:\n        \"\"\"Convert result to dictionary for JSON serialization.\"\"\"\n        return asdict(self)\n\n\n@dataclass\nclass UnderstandResult:\n    \"\"\"Result of music understanding from audio codes.\n    \n    Attributes:\n        # Metadata Fields\n        caption: Generated caption describing the music\n        lyrics: Generated or extracted lyrics\n        bpm: Beats per minute (None if not detected)\n        duration: Duration in seconds (None if not detected)\n        keyscale: Musical key (e.g., \"C Major\")\n        language: Vocal language code (e.g., \"en\", \"zh\")\n        timesignature: Time signature (e.g., \"4/4\")\n        \n        # Status\n        status_message: Status message from understanding\n        success: Whether understanding completed successfully\n        error: Error message if understanding failed\n    \"\"\"\n    # Metadata Fields\n    caption: str = \"\"\n    lyrics: str = \"\"\n    bpm: Optional[int] = None\n    duration: Optional[float] = None\n    keyscale: str = \"\"\n    language: str = \"\"\n    timesignature: str = \"\"\n    \n    # Status\n    status_message: str = \"\"\n    success: bool = True\n    error: Optional[str] = None\n\n    def to_dict(self) -> Dict[str, Any]:\n        \"\"\"Convert result to dictionary for JSON serialization.\"\"\"\n        return asdict(self)\n\n\ndef _update_metadata_from_lm(\n    metadata: Dict[str, Any],\n    bpm: Optional[int],\n    key_scale: str,\n    time_signature: str,\n    audio_duration: Optional[float],\n    vocal_language: str,\n    caption: str,\n    lyrics: str,\n) -> Tuple[Optional[int], str, str, Optional[float], str, str, str]:\n    \"\"\"Update metadata fields from LM output if not provided by user.\"\"\"\n\n    if bpm is None and metadata.get('bpm'):\n        bpm_value = metadata.get('bpm')\n        if bpm_value not in [\"N/A\", \"\"]:\n            try:\n                bpm = int(bpm_value)\n            except (ValueError, TypeError):\n                pass\n\n    if not key_scale and metadata.get('keyscale'):\n        key_scale_value = metadata.get('keyscale', metadata.get('key_scale', \"\"))\n        if key_scale_value != \"N/A\":\n            key_scale = key_scale_value\n\n    if not time_signature and metadata.get('timesignature'):\n        time_signature_value = metadata.get('timesignature', metadata.get('time_signature', \"\"))\n        if time_signature_value != \"N/A\":\n            time_signature = time_signature_value\n\n    if audio_duration is None or audio_duration <= 0:\n        audio_duration_value = metadata.get('duration', -1)\n        if audio_duration_value not in [\"N/A\", \"\"]:\n            try:\n                audio_duration = float(audio_duration_value)\n            except (ValueError, TypeError):\n                pass\n\n    if not vocal_language and metadata.get('vocal_language'):\n        vocal_language = metadata.get('vocal_language')\n    if not caption and metadata.get('caption'):\n        caption = metadata.get('caption')\n    if not lyrics and metadata.get('lyrics'):\n        lyrics = metadata.get('lyrics')\n    return bpm, key_scale, time_signature, audio_duration, vocal_language, caption, lyrics\n\n\n@_get_spaces_gpu_decorator(duration=180)\ndef generate_music(\n    dit_handler,\n    llm_handler,\n    params: GenerationParams,\n    config: GenerationConfig,\n    save_dir: Optional[str] = None,\n    progress=None,\n) -> GenerationResult:\n    \"\"\"Generate music using ACE-Step model with optional LM reasoning.\n    \n    Args:\n        dit_handler: Initialized DiT model handler (AceStepHandler instance)\n        llm_handler: Initialized LLM handler (LLMHandler instance)\n        params: Generation parameters (GenerationParams instance)\n        config: Generation configuration (GenerationConfig instance)\n        \n    Returns:\n        GenerationResult with generated audio files and metadata\n    \"\"\"\n    try:\n        # Phase 1: LM-based metadata and code generation (if enabled)\n        audio_code_string_to_use = params.audio_codes\n        lm_generated_metadata = None\n        lm_generated_audio_codes_list = []\n        lm_total_time_costs = {\n            \"phase1_time\": 0.0,\n            \"phase2_time\": 0.0,\n            \"total_time\": 0.0,\n        }\n\n        # Extract mutable copies of metadata (will be updated by LM if needed)\n        bpm = params.bpm\n        key_scale = params.keyscale\n        time_signature = params.timesignature\n        audio_duration = params.duration\n        dit_input_caption = params.caption\n        dit_input_vocal_language = params.vocal_language\n        dit_input_lyrics = params.lyrics\n        # Determine if we need to generate audio codes\n        # If user has provided audio_codes, we don't need to generate them\n        # Otherwise, check if we need audio codes (lm_dit mode) or just metas (dit mode)\n        user_provided_audio_codes = bool(params.audio_codes and str(params.audio_codes).strip())\n\n        # Determine infer_type: use \"llm_dit\" if we need audio codes, \"dit\" if only metas needed\n        # For now, we use \"llm_dit\" if batch mode or if user hasn't provided codes\n        # Use \"dit\" if user has provided codes (only need metas) or if explicitly only need metas\n        # Note: This logic can be refined based on specific requirements\n        need_audio_codes = not user_provided_audio_codes\n\n        # Determine if we should use chunk-based LM generation (always use chunks for consistency)\n        # Determine actual batch size for chunk processing\n        actual_batch_size = config.batch_size if config.batch_size is not None else 1\n\n        # Prepare seeds for batch generation\n        # Use config.seed if provided, otherwise fallback to params.seed\n        # Convert config.seed (None, int, or List[int]) to format that prepare_seeds accepts\n        seed_for_generation = \"\"\n        # Original code (commented out because it crashes on int seeds):\n        # if config.seeds is not None and len(config.seeds) > 0:\n        #     if isinstance(config.seeds, list):\n        #         # Convert List[int] to comma-separated string\n        #         seed_for_generation = \",\".join(str(s) for s in config.seeds)\n\n        if config.seeds is not None:\n            if isinstance(config.seeds, list) and len(config.seeds) > 0:\n                # Convert List[int] to comma-separated string\n                seed_for_generation = \",\".join(str(s) for s in config.seeds)\n            elif isinstance(config.seeds, int):\n                # Fix: Explicitly handle single integer seeds by converting to string.\n                # Previously, this would crash because 'len()' was called on an int.\n                seed_for_generation = str(config.seeds)\n\n        # Use dit_handler.prepare_seeds to handle seed list generation and padding\n        # This will handle all the logic: padding with random seeds if needed, etc.\n        actual_seed_list, _ = dit_handler.prepare_seeds(actual_batch_size, seed_for_generation, config.use_random_seed)\n\n        # LM-based Chain-of-Thought reasoning\n        # Skip LM for cover/repaint/extract tasks - these tasks use reference/src audio directly\n        # and don't need LM to generate audio codes or metadata.\n        # For extract tasks, LLM-generated captions can conflict with the extract instruction\n        # and cause the DiT model to reconstruct input audio instead of extracting stems.\n        skip_lm_tasks = {\"cover\", \"repaint\", \"extract\"}\n        \n        # Determine if we should use LLM\n        # LLM is needed for:\n        # 1. thinking=True: generate audio codes via LM\n        # 2. use_cot_caption=True: enhance/generate caption via CoT\n        # 3. use_cot_language=True: detect vocal language via CoT\n        # 4. use_cot_metas=True: fill missing metadata via CoT\n        need_lm_for_cot = params.use_cot_caption or params.use_cot_language or params.use_cot_metas\n        use_lm = (params.thinking or need_lm_for_cot) and llm_handler is not None and llm_handler.llm_initialized and params.task_type not in skip_lm_tasks\n        lm_status = []\n        \n        if params.task_type in skip_lm_tasks:\n            logger.info(f\"Skipping LM for task_type='{params.task_type}' - using DiT directly\")\n        \n        logger.info(f\"[generate_music] LLM usage decision: thinking={params.thinking}, \"\n                   f\"use_cot_caption={params.use_cot_caption}, use_cot_language={params.use_cot_language}, \"\n                   f\"use_cot_metas={params.use_cot_metas}, need_lm_for_cot={need_lm_for_cot}, \"\n                   f\"llm_initialized={llm_handler.llm_initialized if llm_handler else False}, use_lm={use_lm}\")\n        \n        if use_lm:\n            # Convert sampling parameters - handle None values safely\n            top_k_value = None if not params.lm_top_k or params.lm_top_k == 0 else int(params.lm_top_k)\n            top_p_value = None if not params.lm_top_p or params.lm_top_p >= 1.0 else params.lm_top_p\n\n            # Build user_metadata from user-provided values\n            user_metadata = {}\n            if bpm is not None:\n                try:\n                    bpm_value = float(bpm)\n                    if bpm_value > 0:\n                        user_metadata['bpm'] = int(bpm_value)\n                except (ValueError, TypeError):\n                    pass\n\n            if key_scale and key_scale.strip():\n                key_scale_clean = key_scale.strip()\n                if key_scale_clean.lower() not in [\"n/a\", \"\"]:\n                    user_metadata['keyscale'] = key_scale_clean\n\n            if time_signature and time_signature.strip():\n                time_sig_clean = time_signature.strip()\n                if time_sig_clean.lower() not in [\"n/a\", \"\"]:\n                    user_metadata['timesignature'] = time_sig_clean\n\n            if audio_duration is not None:\n                try:\n                    duration_value = float(audio_duration)\n                    if duration_value > 0:\n                        user_metadata['duration'] = int(duration_value)\n                except (ValueError, TypeError):\n                    pass\n\n            user_metadata_to_pass = user_metadata if user_metadata else None\n\n            # Determine infer_type based on whether we need audio codes\n            # - \"llm_dit\": generates both metas and audio codes (two-phase internally)\n            # - \"dit\": generates only metas (single phase)\n            infer_type = \"llm_dit\" if need_audio_codes and params.thinking else \"dit\"\n\n            # Use chunk size from config, or default to batch_size if not set\n            max_inference_batch_size = int(config.lm_batch_chunk_size) if config.lm_batch_chunk_size > 0 else actual_batch_size\n            num_chunks = math.ceil(actual_batch_size / max_inference_batch_size)\n\n            all_metadata_list = []\n            all_audio_codes_list = []\n\n            for chunk_idx in range(num_chunks):\n                chunk_start = chunk_idx * max_inference_batch_size\n                chunk_end = min(chunk_start + max_inference_batch_size, actual_batch_size)\n                chunk_size = chunk_end - chunk_start\n                chunk_seeds = actual_seed_list[chunk_start:chunk_end] if chunk_start < len(actual_seed_list) else None\n\n                logger.info(f\"LM chunk {chunk_idx+1}/{num_chunks} (infer_type={infer_type}) \"\n                            f\"(size: {chunk_size}, seeds: {chunk_seeds})\")\n\n                # Use the determined infer_type\n                # - \"llm_dit\" will internally run two phases (metas + codes)\n                # - \"dit\" will only run phase 1 (metas only)\n                result = llm_handler.generate_with_stop_condition(\n                    caption=params.caption or \"\",\n                    lyrics=params.lyrics or \"\",\n                    infer_type=infer_type,\n                    temperature=params.lm_temperature,\n                    cfg_scale=params.lm_cfg_scale,\n                    negative_prompt=params.lm_negative_prompt,\n                    top_k=top_k_value,\n                    top_p=top_p_value,\n                    target_duration=audio_duration,  # Pass duration to limit audio codes generation\n                    user_metadata=user_metadata_to_pass,\n                    use_cot_caption=params.use_cot_caption,\n                    use_cot_language=params.use_cot_language,\n                    use_cot_metas=params.use_cot_metas,\n                    use_constrained_decoding=params.use_constrained_decoding,\n                    constrained_decoding_debug=config.constrained_decoding_debug,\n                    batch_size=chunk_size,\n                    seeds=chunk_seeds,\n                    progress=progress,\n                )\n\n                # Check if LM generation failed\n                if not result.get(\"success\", False):\n                    error_msg = result.get(\"error\", \"Unknown LM error\")\n                    lm_status.append(f\"❌ LM Error: {error_msg}\")\n                    # Return early with error\n                    return GenerationResult(\n                        audios=[],\n                        status_message=f\"❌ LM generation failed: {error_msg}\",\n                        extra_outputs={},\n                        success=False,\n                        error=error_msg,\n                    )\n\n                # Extract metadata and audio_codes from result dict\n                if chunk_size > 1:\n                    metadata_list = result.get(\"metadata\", [])\n                    audio_codes_list = result.get(\"audio_codes\", [])\n                    all_metadata_list.extend(metadata_list)\n                    all_audio_codes_list.extend(audio_codes_list)\n                else:\n                    metadata = result.get(\"metadata\", {})\n                    audio_codes = result.get(\"audio_codes\", \"\")\n                    all_metadata_list.append(metadata)\n                    all_audio_codes_list.append(audio_codes)\n\n                # Collect time costs from LM extra_outputs\n                lm_extra = result.get(\"extra_outputs\", {})\n                lm_chunk_time_costs = lm_extra.get(\"time_costs\", {})\n                if lm_chunk_time_costs:\n                    # Accumulate time costs from all chunks\n                    for key in [\"phase1_time\", \"phase2_time\", \"total_time\"]:\n                        if key in lm_chunk_time_costs:\n                            lm_total_time_costs[key] += lm_chunk_time_costs[key]\n\n                    time_str = \", \".join([f\"{k}: {v:.2f}s\" for k, v in lm_chunk_time_costs.items()])\n                    lm_status.append(f\"✅ LM chunk {chunk_idx+1}: {time_str}\")\n\n            lm_generated_metadata = all_metadata_list[0] if all_metadata_list else None\n            lm_generated_audio_codes_list = all_audio_codes_list\n\n            # Set audio_code_string_to_use based on infer_type\n            if infer_type == \"llm_dit\":\n                # If batch mode, use list; otherwise use single string\n                if actual_batch_size > 1:\n                    audio_code_string_to_use = all_audio_codes_list\n                else:\n                    audio_code_string_to_use = all_audio_codes_list[0] if all_audio_codes_list else \"\"\n            else:\n                # For \"dit\" mode, keep user-provided codes or empty\n                audio_code_string_to_use = params.audio_codes\n\n            # Update metadata from LM if not provided by user\n            if lm_generated_metadata:\n                bpm, key_scale, time_signature, audio_duration, vocal_language, caption, lyrics = _update_metadata_from_lm(\n                    metadata=lm_generated_metadata,\n                    bpm=bpm,\n                    key_scale=key_scale,\n                    time_signature=time_signature,\n                    audio_duration=audio_duration,\n                    vocal_language=dit_input_vocal_language,\n                    caption=dit_input_caption,\n                    lyrics=dit_input_lyrics)\n                if not params.bpm:\n                    params.cot_bpm = bpm\n                if not params.keyscale:\n                    params.cot_keyscale = key_scale\n                if not params.timesignature:\n                    params.cot_timesignature = time_signature\n                if not params.duration:\n                    params.cot_duration = audio_duration\n                if not params.vocal_language:\n                    params.cot_vocal_language = vocal_language\n                if not params.caption:\n                    params.cot_caption = caption\n                if not params.lyrics:\n                    params.cot_lyrics = lyrics\n\n            # set cot caption and language if needed\n            if params.use_cot_caption:\n                dit_input_caption = lm_generated_metadata.get(\"caption\", dit_input_caption)\n            if params.use_cot_language:\n                dit_input_vocal_language = lm_generated_metadata.get(\"vocal_language\", dit_input_vocal_language)\n\n        # Repaint/cover/extract: no LM run, so conditioning must come from params (caption + lyrics from GUI).\n        if params.task_type in (\"repaint\", \"cover\", \"extract\"):\n            dit_input_caption = params.caption or dit_input_caption\n            dit_input_lyrics = params.lyrics if params.lyrics is not None else dit_input_lyrics\n            logger.info(f\"[generate_music] {params.task_type} task: using params.caption='{params.caption}', params.lyrics='{params.lyrics}'\")\n            logger.info(f\"[generate_music] Final inputs: dit_input_caption='{dit_input_caption}', dit_input_lyrics='{dit_input_lyrics}'\")\n\n        # Phase 2: DiT music generation\n        # Use seed_for_generation (from config.seed or params.seed) instead of params.seed for actual generation\n        result = dit_handler.generate_music(\n            captions=dit_input_caption,\n            global_caption=params.global_caption,\n            lyrics=dit_input_lyrics,\n            bpm=bpm,\n            key_scale=key_scale,\n            time_signature=time_signature,\n            vocal_language=dit_input_vocal_language,\n            inference_steps=params.inference_steps,\n            guidance_scale=params.guidance_scale,\n            use_random_seed=config.use_random_seed,\n            seed=seed_for_generation,  # Use config.seed (or params.seed fallback) instead of params.seed directly\n            reference_audio=params.reference_audio,\n            audio_duration=audio_duration,\n            batch_size=config.batch_size if config.batch_size is not None else 1,\n            # text2music (Custom mode) never uses src_audio; force None to\n            # prevent stale UI values from leaking into generation.\n            src_audio=None if params.task_type == \"text2music\" else params.src_audio,\n            audio_code_string=audio_code_string_to_use,\n            repainting_start=params.repainting_start,\n            repainting_end=params.repainting_end,\n            instruction=params.instruction,\n            audio_cover_strength=params.audio_cover_strength,\n            cover_noise_strength=params.cover_noise_strength,\n            task_type=params.task_type,\n            use_adg=params.use_adg,\n            cfg_interval_start=params.cfg_interval_start,\n            cfg_interval_end=params.cfg_interval_end,\n            shift=params.shift,\n            infer_method=params.infer_method,\n            timesteps=params.timesteps,\n            latent_shift=params.latent_shift,\n            latent_rescale=params.latent_rescale,\n            chunk_mask_mode=getattr(params, \"chunk_mask_mode\", \"auto\"),\n            repaint_latent_crossfade_frames=getattr(\n                params, \"repaint_latent_crossfade_frames\", 10,\n            ),\n            repaint_wav_crossfade_sec=getattr(\n                params, \"repaint_wav_crossfade_sec\", 0.0,\n            ),\n            repaint_mode=getattr(params, \"repaint_mode\", \"balanced\"),\n            repaint_strength=getattr(params, \"repaint_strength\", 0.5),\n            progress=progress,\n        )\n\n        # Check if generation failed\n        if not result.get(\"success\", False):\n            return GenerationResult(\n                audios=[],\n                status_message=result.get(\"status_message\", \"\"),\n                extra_outputs={},\n                success=False,\n                error=result.get(\"error\"),\n            )\n\n        # Extract results from dit_handler.generate_music dict\n        dit_audios = result.get(\"audios\", [])\n        status_message = result.get(\"status_message\", \"\")\n        dit_extra_outputs = result.get(\"extra_outputs\", {})\n\n        # Use the seed list already prepared above (from config.seed or params.seed fallback)\n        # actual_seed_list was computed earlier using dit_handler.prepare_seeds\n        seed_list = actual_seed_list\n\n        # Get base params dictionary\n        base_params_dict = params.to_dict()\n\n        # Save audio files using AudioSaver (format from config)\n        audio_format = config.audio_format if config.audio_format else \"flac\"\n        audio_saver = AudioSaver(default_format=audio_format)\n\n        # Use handler's temp_dir for saving files\n        if save_dir is not None:\n            os.makedirs(save_dir, exist_ok=True)\n\n        # Build audios list for GenerationResult with params and save files\n        # Audio saving and UUID generation handled here, outside of handler\n        audios = []\n        for idx, dit_audio in enumerate(dit_audios):\n            # Create a copy of params dict for this audio\n            audio_params = base_params_dict.copy()\n\n            # Update audio-specific values\n            audio_params[\"seed\"] = seed_list[idx] if idx < len(seed_list) else None\n\n            # Add LM-generated audio codes (only if non-empty, to preserve\n            # user-provided codes when LM was used only for CoT metas)\n            if lm_generated_audio_codes_list and idx < len(lm_generated_audio_codes_list):\n                lm_code = lm_generated_audio_codes_list[idx]\n                if lm_code and str(lm_code).strip():\n                    audio_params[\"audio_codes\"] = lm_code\n\n            # Add LoRA state to params for UUID generation (ensures different UUIDs when only LoRA state changes)\n            audio_params[\"lora_loaded\"] = dit_handler.lora_loaded\n            audio_params[\"use_lora\"] = dit_handler.use_lora\n            audio_params[\"lora_scale\"] = dit_handler.lora_scale\n            audio_params[\"lora_weights_hash\"] = get_lora_weights_hash(dit_handler)\n\n            # Get audio tensor and metadata\n            audio_tensor = dit_audio.get(\"tensor\")\n            sample_rate = dit_audio.get(\"sample_rate\", 48000)\n\n            # --- NORMALIZATION & LOGGING ---\n            if params.enable_normalization and params.normalization_db <= 0.0:\n                 try:\n                     peak_before = torch.max(torch.abs(audio_tensor)).item()\n                     logger.info(f\"[Normalization] Audio {idx} BEFORE: Peak={peak_before:.4f}, Target={params.normalization_db}dB\")\n                     \n                     audio_tensor = normalize_audio(audio_tensor, params.normalization_db)\n                     \n                     peak_after = torch.max(torch.abs(audio_tensor)).item()\n                     logger.info(f\"[Normalization] Audio {idx} AFTER: Peak={peak_after:.4f}\")\n                     \n                     # Update the tensor in the dict so downstream uses the normalized version ??\n                     # Actually we use audio_tensor variable below, so it's fine.\n                 except Exception as e:\n                     logger.error(f\"Normalization failed: {e}\")\n            # -------------------------------\n\n            # --- FADE IN / FADE OUT ---\n            if params.fade_in_duration > 0.0 or params.fade_out_duration > 0.0:\n                try:\n                    fade_in_samples = round(params.fade_in_duration * sample_rate)\n                    fade_out_samples = round(params.fade_out_duration * sample_rate)\n                    audio_tensor = apply_fade(audio_tensor, fade_in_samples, fade_out_samples)\n                    logger.info(\n                        f\"[Fade] Audio {idx}: fade_in={params.fade_in_duration:.2f}s \"\n                        f\"({fade_in_samples} samples), fade_out={params.fade_out_duration:.2f}s \"\n                        f\"({fade_out_samples} samples)\"\n                    )\n                except Exception as e:\n                    logger.error(f\"Fade application failed: {e}\")\n            # --------------------------\n\n            # Generate UUID for this audio (moved from handler)\n            batch_seed = seed_list[idx] if idx < len(seed_list) else seed_list[0] if seed_list else -1\n\n            audio_code_str = lm_generated_audio_codes_list[idx] if (\n                lm_generated_audio_codes_list and idx < len(lm_generated_audio_codes_list)) else audio_code_string_to_use\n            if isinstance(audio_code_str, list):\n                audio_code_str = audio_code_str[idx] if idx < len(audio_code_str) else \"\"\n\n            audio_key = generate_uuid_from_params(audio_params)\n\n            # Save audio file (handled outside handler)\n            audio_path = None\n            if audio_tensor is not None and save_dir is not None:\n\n                try:\n                    # Handle wav32 special case for extension\n                    file_ext = \"wav\" if audio_format == \"wav32\" else audio_format\n                    audio_file = os.path.join(save_dir, f\"{audio_key}.{file_ext}\")\n                    \n                    audio_path = audio_saver.save_audio(audio_tensor,\n                                                        audio_file,\n                                                        sample_rate=sample_rate,\n                                                        format=audio_format,\n                                                        channels_first=True)\n                except Exception as e:\n                    logger.error(f\"[generate_music] Failed to save audio file: {e}\")\n                    audio_path = \"\"  # Fallback to empty path\n\n            audio_dict = {\n                \"path\": audio_path or \"\",  # File path (saved here, not in handler)\n                \"tensor\": audio_tensor,  # Audio tensor [channels, samples], CPU, float32\n                \"key\": audio_key,\n                \"sample_rate\": sample_rate,\n                \"params\": audio_params,\n            }\n\n            audios.append(audio_dict)\n\n        # Merge extra_outputs: include dit_extra_outputs (latents, masks) and add LM metadata\n        extra_outputs = dit_extra_outputs.copy()\n        extra_outputs[\"lm_metadata\"] = lm_generated_metadata\n\n        # Merge time_costs from both LM and DiT into a unified dictionary\n        unified_time_costs = {}\n\n        # Add LM time costs (if LM was used)\n        if use_lm and lm_total_time_costs:\n            for key, value in lm_total_time_costs.items():\n                unified_time_costs[f\"lm_{key}\"] = value\n\n        # Add DiT time costs (if available)\n        dit_time_costs = dit_extra_outputs.get(\"time_costs\", {})\n        if dit_time_costs:\n            for key, value in dit_time_costs.items():\n                unified_time_costs[f\"dit_{key}\"] = value\n\n        # Calculate total pipeline time\n        if unified_time_costs:\n            lm_total = unified_time_costs.get(\"lm_total_time\", 0.0)\n            dit_total = unified_time_costs.get(\"dit_total_time_cost\", 0.0)\n            unified_time_costs[\"pipeline_total_time\"] = lm_total + dit_total\n\n        # Update extra_outputs with unified time_costs\n        extra_outputs[\"time_costs\"] = unified_time_costs\n\n        if lm_status:\n            status_message = \"\\n\".join(lm_status) + \"\\n\" + status_message\n        else:\n            status_message = status_message\n        # Create and return GenerationResult\n        return GenerationResult(\n            audios=audios,\n            status_message=status_message,\n            extra_outputs=extra_outputs,\n            success=True,\n            error=None,\n        )\n\n    except Exception as e:\n        logger.exception(\"Music generation failed\")\n        return GenerationResult(\n            audios=[],\n            status_message=f\"Error: {str(e)}\",\n            extra_outputs={},\n            success=False,\n            error=str(e),\n        )\n\n\ndef understand_music(\n    llm_handler,\n    audio_codes: str,\n    temperature: float = 0.85,\n    top_k: Optional[int] = None,\n    top_p: Optional[float] = None,\n    repetition_penalty: float = 1.0,\n    use_constrained_decoding: bool = True,\n    constrained_decoding_debug: bool = False,\n) -> UnderstandResult:\n    \"\"\"Understand music from audio codes using the 5Hz Language Model.\n    \n    This function analyzes audio semantic codes and generates metadata about the music,\n    including caption, lyrics, BPM, duration, key scale, language, and time signature.\n    \n    If audio_codes is empty or \"NO USER INPUT\", the LM will generate a sample example\n    instead of analyzing existing codes.\n    \n    Note: cfg_scale and negative_prompt are not supported in understand mode.\n    \n    Args:\n        llm_handler: Initialized LLM handler (LLMHandler instance)\n        audio_codes: String of audio code tokens (e.g., \"<|audio_code_123|><|audio_code_456|>...\")\n                     Use empty string or \"NO USER INPUT\" to generate a sample example.\n        temperature: Sampling temperature for generation (0.0-2.0). Higher = more creative.\n        top_k: Top-K sampling (None or 0 = disabled)\n        top_p: Top-P (nucleus) sampling (None or 1.0 = disabled)\n        repetition_penalty: Repetition penalty (1.0 = no penalty)\n        use_constrained_decoding: Whether to use FSM-based constrained decoding for metadata\n        constrained_decoding_debug: Whether to enable debug logging for constrained decoding\n        \n    Returns:\n        UnderstandResult with parsed metadata fields and status\n        \n    Example:\n        >>> result = understand_music(llm_handler, audio_codes=\"<|audio_code_123|>...\")\n        >>> if result.success:\n        ...     print(f\"Caption: {result.caption}\")\n        ...     print(f\"BPM: {result.bpm}\")\n        ...     print(f\"Lyrics: {result.lyrics}\")\n    \"\"\"\n    # Check if LLM is initialized\n    if not llm_handler.llm_initialized:\n        return UnderstandResult(\n            status_message=\"5Hz LM not initialized. Please initialize it first.\",\n            success=False,\n            error=\"LLM not initialized\",\n        )\n    \n    # If codes are empty, use \"NO USER INPUT\" to generate a sample example\n    if not audio_codes or not audio_codes.strip():\n        audio_codes = \"NO USER INPUT\"\n    \n    try:\n        # Call LLM understanding\n        metadata, status = llm_handler.understand_audio_from_codes(\n            audio_codes=audio_codes,\n            temperature=temperature,\n            top_k=top_k,\n            top_p=top_p,\n            repetition_penalty=repetition_penalty,\n            use_constrained_decoding=use_constrained_decoding,\n            constrained_decoding_debug=constrained_decoding_debug,\n        )\n        \n        # Check if LLM returned empty metadata (error case)\n        if not metadata:\n            return UnderstandResult(\n                status_message=status or \"Failed to understand audio codes\",\n                success=False,\n                error=status or \"Empty metadata returned\",\n            )\n        \n        # Extract and convert fields\n        caption = metadata.get('caption', '')\n        lyrics = metadata.get('lyrics', '')\n        keyscale = metadata.get('keyscale', '')\n        language = metadata.get('language', metadata.get('vocal_language', ''))\n        timesignature = metadata.get('timesignature', '')\n        \n        # Convert BPM to int\n        bpm = None\n        bpm_value = metadata.get('bpm')\n        if bpm_value is not None and bpm_value != 'N/A' and bpm_value != '':\n            try:\n                bpm = int(bpm_value)\n            except (ValueError, TypeError):\n                pass\n        \n        # Convert duration to float\n        duration = None\n        duration_value = metadata.get('duration')\n        if duration_value is not None and duration_value != 'N/A' and duration_value != '':\n            try:\n                duration = float(duration_value)\n            except (ValueError, TypeError):\n                pass\n        \n        # Clean up N/A values\n        if keyscale == 'N/A':\n            keyscale = ''\n        if language == 'N/A':\n            language = ''\n        if timesignature == 'N/A':\n            timesignature = ''\n        \n        return UnderstandResult(\n            caption=caption,\n            lyrics=lyrics,\n            bpm=bpm,\n            duration=duration,\n            keyscale=keyscale,\n            language=language,\n            timesignature=timesignature,\n            status_message=status,\n            success=True,\n            error=None,\n        )\n        \n    except Exception as e:\n        logger.exception(\"Music understanding failed\")\n        return UnderstandResult(\n            status_message=f\"Error: {str(e)}\",\n            success=False,\n            error=str(e),\n        )\n\n\n@dataclass\nclass CreateSampleResult:\n    \"\"\"Result of creating a music sample from a natural language query.\n    \n    This is used by the \"Simple Mode\" / \"Inspiration Mode\" feature where users\n    provide a natural language description and the LLM generates a complete\n    sample with caption, lyrics, and metadata.\n    \n    Attributes:\n        # Metadata Fields\n        caption: Generated detailed music description/caption\n        lyrics: Generated lyrics (or \"[Instrumental]\" for instrumental music)\n        bpm: Beats per minute (None if not generated)\n        duration: Duration in seconds (None if not generated)\n        keyscale: Musical key (e.g., \"C Major\")\n        language: Vocal language code (e.g., \"en\", \"zh\")\n        timesignature: Time signature (e.g., \"4\")\n        instrumental: Whether this is an instrumental piece\n        \n        # Status\n        status_message: Status message from sample creation\n        success: Whether sample creation completed successfully\n        error: Error message if sample creation failed\n    \"\"\"\n    # Metadata Fields\n    caption: str = \"\"\n    lyrics: str = \"\"\n    bpm: Optional[int] = None\n    duration: Optional[float] = None\n    keyscale: str = \"\"\n    language: str = \"\"\n    timesignature: str = \"\"\n    instrumental: bool = False\n    \n    # Status\n    status_message: str = \"\"\n    success: bool = True\n    error: Optional[str] = None\n\n    def to_dict(self) -> Dict[str, Any]:\n        \"\"\"Convert result to dictionary for JSON serialization.\"\"\"\n        return asdict(self)\n\n\ndef create_sample(\n    llm_handler,\n    query: str,\n    instrumental: bool = False,\n    vocal_language: Optional[str] = None,\n    temperature: float = 0.85,\n    top_k: Optional[int] = None,\n    top_p: Optional[float] = None,\n    repetition_penalty: float = 1.0,\n    use_constrained_decoding: bool = True,\n    constrained_decoding_debug: bool = False,\n) -> CreateSampleResult:\n    \"\"\"Create a music sample from a natural language query using the 5Hz Language Model.\n    \n    This is the \"Simple Mode\" / \"Inspiration Mode\" feature that takes a user's natural\n    language description of music and generates a complete sample including:\n    - Detailed caption/description\n    - Lyrics (unless instrumental)\n    - Metadata (BPM, duration, key, language, time signature)\n    \n    Note: cfg_scale and negative_prompt are not supported in create_sample mode.\n    \n    Args:\n        llm_handler: Initialized LLM handler (LLMHandler instance)\n        query: User's natural language music description (e.g., \"a soft Bengali love song\")\n        instrumental: Whether to generate instrumental music (no vocals)\n        vocal_language: Allowed vocal language for constrained decoding (e.g., \"en\", \"zh\").\n                       If provided, the model will be constrained to generate lyrics in this language.\n                       If None or \"unknown\", no language constraint is applied.\n        temperature: Sampling temperature for generation (0.0-2.0). Higher = more creative.\n        top_k: Top-K sampling (None or 0 = disabled)\n        top_p: Top-P (nucleus) sampling (None or 1.0 = disabled)\n        repetition_penalty: Repetition penalty (1.0 = no penalty)\n        use_constrained_decoding: Whether to use FSM-based constrained decoding\n        constrained_decoding_debug: Whether to enable debug logging\n        \n    Returns:\n        CreateSampleResult with generated sample fields and status\n        \n    Example:\n        >>> result = create_sample(llm_handler, \"a soft Bengali love song for a quiet evening\", vocal_language=\"bn\")\n        >>> if result.success:\n        ...     print(f\"Caption: {result.caption}\")\n        ...     print(f\"Lyrics: {result.lyrics}\")\n        ...     print(f\"BPM: {result.bpm}\")\n    \"\"\"\n    # Check if LLM is initialized\n    if not llm_handler.llm_initialized:\n        return CreateSampleResult(\n            status_message=\"5Hz LM not initialized. Please initialize it first.\",\n            success=False,\n            error=\"LLM not initialized\",\n        )\n    \n    try:\n        # Call LLM to create sample\n        metadata, status = llm_handler.create_sample_from_query(\n            query=query,\n            instrumental=instrumental,\n            vocal_language=vocal_language,\n            temperature=temperature,\n            top_k=top_k,\n            top_p=top_p,\n            repetition_penalty=repetition_penalty,\n            use_constrained_decoding=use_constrained_decoding,\n            constrained_decoding_debug=constrained_decoding_debug,\n        )\n        \n        # Check if LLM returned empty metadata (error case)\n        if not metadata:\n            return CreateSampleResult(\n                status_message=status or \"Failed to create sample\",\n                success=False,\n                error=status or \"Empty metadata returned\",\n            )\n        \n        # Extract and convert fields\n        caption = metadata.get('caption', '')\n        lyrics = metadata.get('lyrics', '')\n        keyscale = metadata.get('keyscale', '')\n        language = metadata.get('language', metadata.get('vocal_language', ''))\n        timesignature = metadata.get('timesignature', '')\n        is_instrumental = metadata.get('instrumental', instrumental)\n        \n        # Convert BPM to int\n        bpm = None\n        bpm_value = metadata.get('bpm')\n        if bpm_value is not None and bpm_value != 'N/A' and bpm_value != '':\n            try:\n                bpm = int(bpm_value)\n            except (ValueError, TypeError):\n                pass\n        \n        # Convert duration to float\n        duration = None\n        duration_value = metadata.get('duration')\n        if duration_value is not None and duration_value != 'N/A' and duration_value != '':\n            try:\n                duration = float(duration_value)\n            except (ValueError, TypeError):\n                pass\n        \n        # Clean up N/A values\n        if keyscale == 'N/A':\n            keyscale = ''\n        if language == 'N/A':\n            language = ''\n        if timesignature == 'N/A':\n            timesignature = ''\n        \n        return CreateSampleResult(\n            caption=caption,\n            lyrics=lyrics,\n            bpm=bpm,\n            duration=duration,\n            keyscale=keyscale,\n            language=language,\n            timesignature=timesignature,\n            instrumental=is_instrumental,\n            status_message=status,\n            success=True,\n            error=None,\n        )\n        \n    except Exception as e:\n        logger.exception(\"Sample creation failed\")\n        return CreateSampleResult(\n            status_message=f\"Error: {str(e)}\",\n            success=False,\n            error=str(e),\n        )\n\n\n@dataclass\nclass FormatSampleResult:\n    \"\"\"Result of formatting user-provided caption and lyrics.\n    \n    This is used by the \"Format\" feature where users provide caption and lyrics,\n    and the LLM formats them into structured music metadata and an enhanced description.\n    \n    Attributes:\n        # Metadata Fields\n        caption: Enhanced/formatted music description/caption\n        lyrics: Formatted lyrics (may be same as input or reformatted)\n        bpm: Beats per minute (None if not detected)\n        duration: Duration in seconds (None if not detected)\n        keyscale: Musical key (e.g., \"C Major\")\n        language: Vocal language code (e.g., \"en\", \"zh\")\n        timesignature: Time signature (e.g., \"4\")\n        \n        # Status\n        status_message: Status message from formatting\n        success: Whether formatting completed successfully\n        error: Error message if formatting failed\n    \"\"\"\n    # Metadata Fields\n    caption: str = \"\"\n    lyrics: str = \"\"\n    bpm: Optional[int] = None\n    duration: Optional[float] = None\n    keyscale: str = \"\"\n    language: str = \"\"\n    timesignature: str = \"\"\n    \n    # Status\n    status_message: str = \"\"\n    success: bool = True\n    error: Optional[str] = None\n\n    def to_dict(self) -> Dict[str, Any]:\n        \"\"\"Convert result to dictionary for JSON serialization.\"\"\"\n        return asdict(self)\n\n\ndef format_sample(\n    llm_handler,\n    caption: str,\n    lyrics: str,\n    user_metadata: Optional[Dict[str, Any]] = None,\n    temperature: float = 0.85,\n    top_k: Optional[int] = None,\n    top_p: Optional[float] = None,\n    repetition_penalty: float = 1.0,\n    use_constrained_decoding: bool = True,\n    constrained_decoding_debug: bool = False,\n) -> FormatSampleResult:\n    \"\"\"Format user-provided caption and lyrics using the 5Hz Language Model.\n    \n    This function takes user input (caption and lyrics) and generates structured\n    music metadata including an enhanced caption, BPM, duration, key, language,\n    and time signature.\n    \n    If user_metadata is provided, those values will be used to constrain the\n    decoding, ensuring the output matches user-specified values.\n    \n    Note: cfg_scale and negative_prompt are not supported in format mode.\n    \n    Args:\n        llm_handler: Initialized LLM handler (LLMHandler instance)\n        caption: User's caption/description (e.g., \"Latin pop, reggaeton\")\n        lyrics: User's lyrics with structure tags\n        user_metadata: Optional dict with user-provided metadata to constrain decoding.\n                      Supported keys: bpm, duration, keyscale, timesignature, language\n        temperature: Sampling temperature for generation (0.0-2.0). Higher = more creative.\n        top_k: Top-K sampling (None or 0 = disabled)\n        top_p: Top-P (nucleus) sampling (None or 1.0 = disabled)\n        repetition_penalty: Repetition penalty (1.0 = no penalty)\n        use_constrained_decoding: Whether to use FSM-based constrained decoding for metadata\n        constrained_decoding_debug: Whether to enable debug logging for constrained decoding\n        \n    Returns:\n        FormatSampleResult with formatted metadata fields and status\n        \n    Example:\n        >>> result = format_sample(llm_handler, \"Latin pop, reggaeton\", \"[Verse 1]\\\\nHola mundo...\")\n        >>> if result.success:\n        ...     print(f\"Caption: {result.caption}\")\n        ...     print(f\"BPM: {result.bpm}\")\n        ...     print(f\"Lyrics: {result.lyrics}\")\n    \"\"\"\n    # Check if LLM is initialized\n    if not llm_handler.llm_initialized:\n        return FormatSampleResult(\n            status_message=\"5Hz LM not initialized. Please initialize it first.\",\n            success=False,\n            error=\"LLM not initialized\",\n        )\n    \n    try:\n        # Call LLM formatting\n        metadata, status = llm_handler.format_sample_from_input(\n            caption=caption,\n            lyrics=lyrics,\n            user_metadata=user_metadata,\n            temperature=temperature,\n            top_k=top_k,\n            top_p=top_p,\n            repetition_penalty=repetition_penalty,\n            use_constrained_decoding=use_constrained_decoding,\n            constrained_decoding_debug=constrained_decoding_debug,\n        )\n        \n        # Check if LLM returned empty metadata (error case)\n        if not metadata:\n            return FormatSampleResult(\n                status_message=status or \"Failed to format input\",\n                success=False,\n                error=status or \"Empty metadata returned\",\n            )\n        \n        # Extract and convert fields\n        result_caption = metadata.get('caption', '')\n        result_lyrics = metadata.get('lyrics', lyrics)  # Fall back to input lyrics\n        keyscale = metadata.get('keyscale', '')\n        language = metadata.get('language', metadata.get('vocal_language', ''))\n        timesignature = metadata.get('timesignature', '')\n        \n        # Convert BPM to int\n        bpm = None\n        bpm_value = metadata.get('bpm')\n        if bpm_value is not None and bpm_value != 'N/A' and bpm_value != '':\n            try:\n                bpm = int(bpm_value)\n            except (ValueError, TypeError):\n                pass\n        \n        # Convert duration to float\n        duration = None\n        duration_value = metadata.get('duration')\n        if duration_value is not None and duration_value != 'N/A' and duration_value != '':\n            try:\n                duration = float(duration_value)\n            except (ValueError, TypeError):\n                pass\n        \n        # Clean up N/A values\n        if keyscale == 'N/A':\n            keyscale = ''\n        if language == 'N/A':\n            language = ''\n        if timesignature == 'N/A':\n            timesignature = ''\n        \n        return FormatSampleResult(\n            caption=result_caption,\n            lyrics=result_lyrics,\n            bpm=bpm,\n            duration=duration,\n            keyscale=keyscale,\n            language=language,\n            timesignature=timesignature,\n            status_message=status,\n            success=True,\n            error=None,\n        )\n        \n    except Exception as e:\n        logger.exception(\"Format sample failed\")\n        return FormatSampleResult(\n            status_message=f\"Error: {str(e)}\",\n            success=False,\n            error=str(e),\n        )\n"
  },
  {
    "path": "acestep/launcher_compat.py",
    "content": "\"\"\"Launcher compatibility helpers for hardware-specific startup fixes.\"\"\"\n\nfrom __future__ import annotations\n\nfrom dataclasses import dataclass\nfrom typing import Any\n\n\nLEGACY_TORCH_FIX_EXIT_CODE = 42\n\n\n@dataclass(frozen=True)\nclass LegacyTorchFixDecision:\n    \"\"\"Decision payload for whether launcher should apply legacy torch fix.\n\n    Attributes:\n        should_apply: Whether compatibility fix should be applied.\n        reason: Short machine-readable reason for decision.\n        device_arch: CUDA architecture string (for example, ``sm_61``) when available.\n    \"\"\"\n\n    should_apply: bool\n    reason: str\n    device_arch: str | None = None\n\n\ndef evaluate_legacy_torch_fix(torch_module: Any) -> LegacyTorchFixDecision:\n    \"\"\"Evaluate legacy GPU compatibility using an injected torch-like module.\n\n    Args:\n        torch_module: Imported ``torch`` module or a test double exposing\n            ``cuda.is_available()``, ``cuda.get_device_capability()``, and\n            ``cuda.get_arch_list()``.\n\n    Returns:\n        Compatibility decision indicating whether to apply legacy torch wheels.\n    \"\"\"\n    cuda = getattr(torch_module, \"cuda\", None)\n    if cuda is None or not cuda.is_available():\n        return LegacyTorchFixDecision(False, \"cuda_unavailable\")\n\n    major, minor = cuda.get_device_capability(0)\n    device_arch = f\"sm_{major}{minor}\"\n    supported_arches = set(cuda.get_arch_list() or [])\n\n    if major < 7 and device_arch not in supported_arches:\n        return LegacyTorchFixDecision(True, \"legacy_arch_missing\", device_arch=device_arch)\n\n    return LegacyTorchFixDecision(False, \"compatible_arch\", device_arch=device_arch)\n\n\ndef determine_legacy_torch_fix(torch_module: Any | None = None) -> LegacyTorchFixDecision:\n    \"\"\"Determine whether legacy torch compatibility patch is required.\n\n    Args:\n        torch_module: Optional injected ``torch`` module for tests.\n\n    Returns:\n        Compatibility decision payload.\n    \"\"\"\n    if torch_module is None:\n        try:\n            import torch as imported_torch\n        except Exception:\n            return LegacyTorchFixDecision(False, \"torch_unavailable\")\n        torch_module = imported_torch\n\n    try:\n        return evaluate_legacy_torch_fix(torch_module)\n    except Exception:\n        return LegacyTorchFixDecision(False, \"probe_failed\")\n\n\ndef legacy_torch_fix_probe_exit_code(torch_module: Any | None = None) -> int:\n    \"\"\"Return launcher probe exit code for legacy torch compatibility check.\n\n    Args:\n        torch_module: Optional injected ``torch`` module for tests.\n\n    Returns:\n        ``LEGACY_TORCH_FIX_EXIT_CODE`` when fix should be applied or the probe\n        itself fails, otherwise ``0``.\n    \"\"\"\n    decision = determine_legacy_torch_fix(torch_module=torch_module)\n    if decision.should_apply or decision.reason == \"probe_failed\":\n        return LEGACY_TORCH_FIX_EXIT_CODE\n    return 0\n"
  },
  {
    "path": "acestep/launcher_compat_test.py",
    "content": "\"\"\"Unit tests for launcher compatibility decision logic.\"\"\"\n\nfrom __future__ import annotations\n\nimport types\nimport unittest\n\nfrom acestep.launcher_compat import (\n    LEGACY_TORCH_FIX_EXIT_CODE,\n    determine_legacy_torch_fix,\n    evaluate_legacy_torch_fix,\n    legacy_torch_fix_probe_exit_code,\n)\n\n\ndef _make_torch(\n    *,\n    cuda_available: bool,\n    capability: tuple[int, int] = (6, 1),\n    arch_list: list[str] | None = None,\n) -> types.SimpleNamespace:\n    \"\"\"Create a minimal torch test double for compatibility checks.\"\"\"\n    cuda = types.SimpleNamespace(\n        is_available=lambda: cuda_available,\n        get_device_capability=lambda _idx=0: capability,\n        get_arch_list=lambda: arch_list or [],\n    )\n    return types.SimpleNamespace(cuda=cuda)\n\n\nclass LauncherCompatDecisionTests(unittest.TestCase):\n    \"\"\"Validate decision logic for legacy torch compatibility fixes.\"\"\"\n\n    def test_legacy_arch_missing_requires_fix(self) -> None:\n        \"\"\"It requests fix when legacy GPU arch is missing from torch wheel.\"\"\"\n        torch_module = _make_torch(cuda_available=True, capability=(6, 1), arch_list=[\"sm_70\"])\n        decision = evaluate_legacy_torch_fix(torch_module)\n        self.assertTrue(decision.should_apply)\n        self.assertEqual(\"legacy_arch_missing\", decision.reason)\n        self.assertEqual(\"sm_61\", decision.device_arch)\n\n    def test_legacy_arch_present_skips_fix(self) -> None:\n        \"\"\"It skips fix when legacy arch is already supported.\"\"\"\n        torch_module = _make_torch(cuda_available=True, capability=(6, 1), arch_list=[\"sm_61\", \"sm_70\"])\n        decision = evaluate_legacy_torch_fix(torch_module)\n        self.assertFalse(decision.should_apply)\n        self.assertEqual(\"compatible_arch\", decision.reason)\n        self.assertEqual(\"sm_61\", decision.device_arch)\n\n    def test_modern_gpu_skips_fix_even_if_arch_not_listed(self) -> None:\n        \"\"\"It does not apply legacy fix for modern GPUs.\"\"\"\n        torch_module = _make_torch(cuda_available=True, capability=(8, 6), arch_list=[\"sm_70\"])\n        decision = evaluate_legacy_torch_fix(torch_module)\n        self.assertFalse(decision.should_apply)\n        self.assertEqual(\"compatible_arch\", decision.reason)\n        self.assertEqual(\"sm_86\", decision.device_arch)\n\n    def test_no_cuda_skips_fix(self) -> None:\n        \"\"\"It skips fix when CUDA is unavailable.\"\"\"\n        torch_module = _make_torch(cuda_available=False)\n        decision = evaluate_legacy_torch_fix(torch_module)\n        self.assertFalse(decision.should_apply)\n        self.assertEqual(\"cuda_unavailable\", decision.reason)\n        self.assertIsNone(decision.device_arch)\n\n    def test_determine_returns_probe_failed_on_exception(self) -> None:\n        \"\"\"It returns a safe no-fix decision when probing raises.\"\"\"\n        broken_cuda = types.SimpleNamespace(\n            is_available=lambda: True,\n            get_device_capability=lambda _idx=0: (_ for _ in ()).throw(RuntimeError(\"boom\")),\n            get_arch_list=lambda: [],\n        )\n        decision = determine_legacy_torch_fix(types.SimpleNamespace(cuda=broken_cuda))\n        self.assertFalse(decision.should_apply)\n        self.assertEqual(\"probe_failed\", decision.reason)\n\n    def test_probe_exit_code_maps_to_decision(self) -> None:\n        \"\"\"Probe exit code is 42 for required-fix and probe-failure cases, else 0.\"\"\"\n        needs_fix = _make_torch(cuda_available=True, capability=(6, 1), arch_list=[\"sm_70\"])\n        ok = _make_torch(cuda_available=True, capability=(8, 0), arch_list=[\"sm_80\"])\n        broken_cuda = types.SimpleNamespace(\n            is_available=lambda: True,\n            get_device_capability=lambda _idx=0: (_ for _ in ()).throw(RuntimeError(\"boom\")),\n            get_arch_list=lambda: [],\n        )\n        self.assertEqual(LEGACY_TORCH_FIX_EXIT_CODE, legacy_torch_fix_probe_exit_code(needs_fix))\n        self.assertEqual(0, legacy_torch_fix_probe_exit_code(ok))\n        failed_exit = legacy_torch_fix_probe_exit_code(types.SimpleNamespace(cuda=broken_cuda))\n        self.assertNotEqual(0, failed_exit)\n        self.assertEqual(LEGACY_TORCH_FIX_EXIT_CODE, failed_exit)\n\n\nif __name__ == \"__main__\":\n    unittest.main()\n"
  },
  {
    "path": "acestep/launcher_legacy_torch_fix_test.py",
    "content": "\"\"\"Tests for legacy NVIDIA torch compatibility launcher guards.\"\"\"\n\nfrom __future__ import annotations\n\nfrom pathlib import Path\nimport unittest\n\n\nPROJECT_ROOT = Path(__file__).resolve().parents[1]\n\n\nclass LauncherLegacyTorchFixTests(unittest.TestCase):\n    \"\"\"Ensure launcher compatibility fixes are narrowly scoped and opt-out capable.\"\"\"\n\n    def _read(self, rel_path: str) -> str:\n        \"\"\"Read a launcher script from the project root.\"\"\"\n        return (PROJECT_ROOT / rel_path).read_text(encoding=\"utf-8\")\n\n    def test_linux_gradio_launcher_calls_shared_probe(self) -> None:\n        \"\"\"Linux Gradio launcher should call shared Python compatibility probe.\"\"\"\n        content = self._read(\"start_gradio_ui.sh\")\n        self.assertIn(\"ACESTEP_SKIP_LEGACY_TORCH_FIX\", content)\n        self.assertIn(\"legacy_torch_fix_probe_exit_code\", content)\n        self.assertIn(\"legacy NVIDIA compatibility probe failed with exit code $compat_status\", content)\n        self.assertIn(\"return 1\", content)\n        self.assertIn(\"torch==2.5.1+cu121\", content)\n\n    def test_linux_api_launcher_calls_shared_probe(self) -> None:\n        \"\"\"Linux API launcher should call shared Python compatibility probe.\"\"\"\n        content = self._read(\"start_api_server.sh\")\n        self.assertIn(\"ACESTEP_SKIP_LEGACY_TORCH_FIX\", content)\n        self.assertIn(\"legacy_torch_fix_probe_exit_code\", content)\n        self.assertIn(\"legacy NVIDIA compatibility probe failed with exit code $compat_status\", content)\n        self.assertIn(\"return 1\", content)\n        self.assertIn(\"torch==2.5.1+cu121\", content)\n\n    def test_windows_gradio_launcher_calls_shared_probe(self) -> None:\n        \"\"\"Windows Gradio launcher should call shared Python compatibility probe.\"\"\"\n        content = self._read(\"start_gradio_ui.bat\")\n        self.assertIn('if /i \"%ACESTEP_SKIP_LEGACY_TORCH_FIX%\"==\"true\"', content)\n        self.assertIn(\"legacy_torch_fix_probe_exit_code\", content)\n        self.assertIn(\"torch==2.5.1+cu121\", content)\n        self.assertGreaterEqual(content.count(\"call :EnsureLegacyNvidiaTorchCompat\"), 1)\n        self.assertGreaterEqual(content.count(\"if !ERRORLEVEL! NEQ 0 exit /b !ERRORLEVEL!\"), 1)\n        self.assertRegex(\n            content,\n            r\"call :EnsureLegacyNvidiaTorchCompat\\s+if !ERRORLEVEL! NEQ 0 exit /b !ERRORLEVEL!\",\n        )\n        self.assertIn('if \"!LEGACY_CHECK_EXIT!\"==\"0\" (', content)\n        self.assertIn(\"exit /b !LEGACY_CHECK_EXIT!\", content)\n\n    def test_windows_api_launcher_calls_shared_probe(self) -> None:\n        \"\"\"Windows API launcher should call shared Python compatibility probe.\"\"\"\n        content = self._read(\"start_api_server.bat\")\n        self.assertIn('if /i \"%ACESTEP_SKIP_LEGACY_TORCH_FIX%\"==\"true\"', content)\n        self.assertIn(\"legacy_torch_fix_probe_exit_code\", content)\n        self.assertIn(\"torch==2.5.1+cu121\", content)\n        self.assertIn(\"uv run --no-sync !ACESTEP_ARGS!\", content)\n        self.assertIn(\"uv run --offline --no-sync !ACESTEP_ARGS!\", content)\n        self.assertGreaterEqual(content.count(\"call :EnsureLegacyNvidiaTorchCompat\"), 1)\n        self.assertGreaterEqual(content.count(\"if !ERRORLEVEL! NEQ 0 exit /b !ERRORLEVEL!\"), 1)\n        self.assertRegex(\n            content,\n            r\"call :EnsureLegacyNvidiaTorchCompat\\s+if !ERRORLEVEL! NEQ 0 exit /b !ERRORLEVEL!\",\n        )\n        self.assertIn('if \"!LEGACY_CHECK_EXIT!\"==\"0\" (', content)\n        self.assertIn(\"exit /b !LEGACY_CHECK_EXIT!\", content)\n\n\nif __name__ == \"__main__\":\n    unittest.main()\n"
  },
  {
    "path": "acestep/llm_backend_compat.py",
    "content": "\"\"\"Compatibility helpers for optional 5Hz LM backends.\"\"\"\n\nimport importlib\nimport sys\n\n\ndef _has_working_triton_installation() -> bool:\n    \"\"\"Return whether the Triton modules required by nano-vllm import cleanly.\"\"\"\n    try:\n        importlib.import_module(\"triton\")\n        importlib.import_module(\"triton.language\")\n        return True\n    except (ImportError, ModuleNotFoundError):\n        return False\n\n\ndef get_vllm_preflight_warning(*, device: str, platform: str | None = None) -> str | None:\n    \"\"\"Return a user-facing warning when vLLM should be skipped before initialization.\n\n    Args:\n        device: The resolved device string for LM initialization.\n        platform: Optional platform override for tests. Defaults to ``sys.platform``.\n\n    Returns:\n        A warning string when vLLM should fall back to PyTorch, otherwise ``None``.\n    \"\"\"\n    active_platform = sys.platform if platform is None else platform\n    if device != \"cuda\" or active_platform != \"win32\":\n        return None\n    if _has_working_triton_installation():\n        return None\n    return (\n        \"vLLM backend is unavailable on Windows because Triton is not installed \"\n        \"or is incompatible. Falling back to the PyTorch backend. \"\n        \"Use --backend pt to suppress this warning.\"\n    )"
  },
  {
    "path": "acestep/llm_backend_compat_test.py",
    "content": "\"\"\"Unit tests for optional 5Hz LM backend compatibility helpers.\"\"\"\n\nfrom __future__ import annotations\n\nimport unittest\nfrom types import SimpleNamespace\nfrom unittest.mock import MagicMock, patch\n\nfrom acestep.llm_backend_compat import get_vllm_preflight_warning\n\ntry:\n    from acestep.llm_inference import LLMHandler\n\n    _IMPORT_ERROR = None\nexcept ImportError as exc:  # pragma: no cover - dependency guard\n    missing_name = getattr(exc, \"name\", None)\n    if missing_name is None:\n        missing_name = str(exc)\n    if \"acestep\" in missing_name:\n        raise\n    LLMHandler = None\n    _IMPORT_ERROR = exc\n\n\nclass VllmBackendCompatTests(unittest.TestCase):\n    \"\"\"Verify backend preflight guards for optional Triton-dependent paths.\"\"\"\n\n    def test_get_vllm_preflight_warning_returns_message_on_windows_without_triton(self) -> None:\n        \"\"\"Windows CUDA should skip vLLM when Triton imports are unavailable.\"\"\"\n        with patch(\n            \"acestep.llm_backend_compat._has_working_triton_installation\",\n            return_value=False,\n        ):\n            warning = get_vllm_preflight_warning(device=\"cuda\", platform=\"win32\")\n\n        self.assertIsNotNone(warning)\n        self.assertIn(\"Windows\", warning)\n        self.assertIn(\"Triton\", warning)\n        self.assertIn(\"Falling back to the PyTorch backend\", warning)\n\n    def test_get_vllm_preflight_warning_returns_none_outside_windows_cuda(self) -> None:\n        \"\"\"Non-Windows or non-CUDA setups should not be blocked by the Triton preflight.\"\"\"\n        with patch(\n            \"acestep.llm_backend_compat._has_working_triton_installation\",\n            return_value=False,\n        ):\n            warning = get_vllm_preflight_warning(device=\"cpu\", platform=\"win32\")\n            linux_warning = get_vllm_preflight_warning(device=\"cuda\", platform=\"linux\")\n\n        self.assertIsNone(warning)\n        self.assertIsNone(linux_warning)\n\n\n@unittest.skipIf(LLMHandler is None, f\"llm_inference import unavailable: {_IMPORT_ERROR}\")\nclass LlmInitializeBackendCompatTests(unittest.TestCase):\n    \"\"\"Verify ``LLMHandler.initialize`` uses the Windows Triton preflight cleanly.\"\"\"\n\n    @patch(\"torch.cuda.synchronize\")\n    @patch(\"torch.cuda.empty_cache\")\n    @patch(\"torch.cuda.is_available\", return_value=True)\n    @patch(\"acestep.llm_inference.MetadataConstrainedLogitsProcessor\")\n    @patch(\"acestep.llm_inference.get_global_gpu_config\")\n    @patch(\"acestep.llm_inference.AutoTokenizer.from_pretrained\")\n    @patch(\"acestep.llm_inference.get_vllm_preflight_warning\")\n    def test_initialize_skips_vllm_when_windows_triton_is_unavailable(\n        self,\n        mock_preflight_warning: MagicMock,\n        mock_tokenizer: MagicMock,\n        mock_gpu_config: MagicMock,\n        _mock_processor: MagicMock,\n        _mock_cuda_available: MagicMock,\n        _mock_empty_cache: MagicMock,\n        _mock_synchronize: MagicMock,\n    ) -> None:\n        \"\"\"Initialization should avoid nano-vllm when the Windows Triton preflight fails.\"\"\"\n        handler = LLMHandler()\n        mock_tokenizer.return_value = MagicMock()\n        mock_gpu_config.return_value = SimpleNamespace(max_duration_with_lm=600, tier=\"tier6\")\n        mock_preflight_warning.return_value = (\n            \"vLLM backend is unavailable on Windows because Triton is not installed \"\n            \"or is incompatible. Falling back to the PyTorch backend. \"\n            \"Use --backend pt to suppress this warning.\"\n        )\n\n        with patch(\"acestep.llm_inference.os.path.exists\", return_value=True), patch.object(\n            handler,\n            \"_load_pytorch_model\",\n            return_value=(\n                True,\n                \"ok\\nBackend: PyTorch\\nDevice: cuda\",\n            ),\n        ) as load_pytorch_model, patch.object(\n            handler,\n            \"_initialize_5hz_lm_vllm\",\n        ) as init_vllm:\n            status, ok = handler.initialize(\n                checkpoint_dir=\"C:/repo/checkpoints\",\n                lm_model_path=\"acestep-5Hz-lm-0.6B\",\n                backend=\"vllm\",\n                device=\"cuda\",\n            )\n\n        self.assertTrue(ok)\n        load_pytorch_model.assert_called_once()\n        init_vllm.assert_not_called()\n        self.assertIn(\"Backend: PyTorch\", status)\n        self.assertIn(\"vLLM backend is unavailable on Windows\", status)\n\n    @patch(\"torch.cuda.synchronize\")\n    @patch(\"torch.cuda.empty_cache\")\n    @patch(\"torch.cuda.is_available\", return_value=True)\n    @patch(\"acestep.llm_inference.MetadataConstrainedLogitsProcessor\")\n    @patch(\"acestep.llm_inference.get_global_gpu_config\")\n    @patch(\"acestep.llm_inference.AutoTokenizer.from_pretrained\")\n    @patch(\"acestep.llm_inference.get_gpu_memory_gb\", return_value=24.0)\n    @patch(\"torch.cuda.mem_get_info\", return_value=(8 * 1024**3, 24 * 1024**3))\n    def test_initialize_falls_back_when_vllm_returns_triton_error(\n        self,\n        _mock_mem_get_info: MagicMock,\n        _mock_gpu_memory_gb: MagicMock,\n        mock_tokenizer: MagicMock,\n        mock_gpu_config: MagicMock,\n        _mock_processor: MagicMock,\n        _mock_cuda_available: MagicMock,\n        _mock_empty_cache: MagicMock,\n        _mock_synchronize: MagicMock,\n    ) -> None:\n        \"\"\"Initialization should still fall back when vLLM returns a Triton-specific error string.\"\"\"\n        handler = LLMHandler()\n        mock_tokenizer.return_value = MagicMock()\n        mock_gpu_config.return_value = SimpleNamespace(max_duration_with_lm=600, tier=\"tier6\")\n\n        with patch(\"acestep.llm_inference.os.path.exists\", return_value=True), patch(\n            \"acestep.llm_inference.get_vllm_preflight_warning\",\n            return_value=None,\n        ), patch.object(\n            handler,\n            \"_initialize_5hz_lm_vllm\",\n            return_value=(\n                \"❌ vLLM backend requires a working Triton installation. \"\n                \"Falling back to PyTorch is recommended on Windows. \"\n                \"Use --backend pt to avoid this warning.\"\n            ),\n        ) as init_vllm, patch.object(\n            handler,\n            \"_load_pytorch_model\",\n            return_value=(\n                True,\n                \"✅ 5Hz LM initialized successfully\\nModel: C:/repo/checkpoints/acestep-5Hz-lm-0.6B\\nBackend: PyTorch\\nDevice: cuda\",\n            ),\n        ) as load_pytorch_model:\n            status, ok = handler.initialize(\n                checkpoint_dir=\"C:/repo/checkpoints\",\n                lm_model_path=\"acestep-5Hz-lm-0.6B\",\n                backend=\"vllm\",\n                device=\"cuda\",\n            )\n\n        self.assertTrue(ok)\n        init_vllm.assert_called_once()\n        load_pytorch_model.assert_called_once()\n        self.assertIn(\"Backend: PyTorch\", status)\n        self.assertIn(\"PyTorch fallback\", status)\n        self.assertIn(\"working Triton installation\", status)\n        self.assertNotIn(\"Traceback\", status)\n\n\nif __name__ == \"__main__\":\n    unittest.main()\n"
  },
  {
    "path": "acestep/llm_inference.py",
    "content": "\"\"\"\n5Hz LM (Language Model) Handler\nHandles all LM-related operations including initialization and generation\n\"\"\"\nimport gc\nimport os\nimport sys\nimport traceback\nimport time\nimport random\nimport warnings\nfrom typing import Optional, Dict, Any, Tuple, List, Union\nfrom contextlib import contextmanager\n\nimport yaml\nimport torch\nfrom loguru import logger\nfrom tqdm import tqdm\nfrom transformers import AutoTokenizer, AutoModelForCausalLM\nfrom transformers.generation.streamers import BaseStreamer\nfrom transformers.generation.logits_process import (\n    LogitsProcessorList,\n    RepetitionPenaltyLogitsProcessor,\n)\nfrom acestep.llm_backend_compat import get_vllm_preflight_warning\nfrom acestep.constrained_logits_processor import MetadataConstrainedLogitsProcessor\nfrom acestep.constants import DEFAULT_LM_INSTRUCTION, DEFAULT_LM_UNDERSTAND_INSTRUCTION, DEFAULT_LM_INSPIRED_INSTRUCTION, DEFAULT_LM_REWRITE_INSTRUCTION, DURATION_MIN, DURATION_MAX\nfrom acestep.gpu_config import get_lm_gpu_memory_ratio, get_gpu_memory_gb, get_lm_model_size, get_global_gpu_config\n\n# Minimum free VRAM (GB) required to attempt vLLM initialization.\n# vLLM's KV cache allocator adapts to available memory, so we only need a\n# basic sanity check — not a hard total-VRAM gate.\nVRAM_SAFE_FREE_GB = 2.0\n\n\ndef _warn_if_prerelease_python():\n    v = sys.version_info\n    if getattr(v, \"releaselevel\", \"final\") != \"final\" and sys.platform.startswith(\"linux\"):\n        warnings.warn(\n            f\"Detected pre-release Python {sys.version.split()[0]} ({getattr(v, 'releaselevel', '')}). \"\n            \"This is known to cause segmentation faults with vLLM/nano-vllm on Linux. \"\n            \"Please install a stable Python release (e.g. 3.11.12+), or use --backend pt as a workaround.\",\n            RuntimeWarning,\n            stacklevel=2,\n        )\n\n\nclass LLMHandler:\n    \"\"\"5Hz LM Handler for audio code generation\"\"\"\n\n    STOP_REASONING_TAG = \"</think>\"\n\n    # HuggingFace Space environment detection\n    IS_HUGGINGFACE_SPACE = os.environ.get(\"SPACE_ID\") is not None\n\n    def __init__(self, persistent_storage_path: Optional[str] = None):\n        \"\"\"Initialize LLMHandler with default values\"\"\"\n        self.llm = None\n        self.llm_tokenizer = None\n        self.llm_initialized = False\n        self.llm_backend = None\n        self.max_model_len = 4096\n        self.device = \"cpu\"\n        self.dtype = torch.float32\n        self.offload_to_cpu = False\n        self.disable_tqdm = os.environ.get(\"ACESTEP_DISABLE_TQDM\", \"\").lower() in (\"1\", \"true\", \"yes\") or not (hasattr(sys.stderr, 'isatty') and sys.stderr.isatty())\n\n        # HuggingFace Space persistent storage support\n        if persistent_storage_path is None and self.IS_HUGGINGFACE_SPACE:\n            persistent_storage_path = \"/data\"\n        self.persistent_storage_path = persistent_storage_path\n\n        # Shared constrained decoding processor\n        self.constrained_processor: Optional[MetadataConstrainedLogitsProcessor] = None\n\n        # Shared HuggingFace model for perplexity calculation\n        self._hf_model_for_scoring = None\n\n        # MLX model reference (used when llm_backend == \"mlx\")\n        self._mlx_model = None\n        self._mlx_model_path = None\n\n    def _clear_accelerator_cache(self) -> None:\n        \"\"\"Release freed accelerator memory back to the driver.\n\n        Synchronises the device *before* releasing cached blocks so that\n        every in-flight async write has landed and the freed blocks are\n        actually reclaimable.  Supports CUDA, XPU (Intel), and MPS\n        (Apple Silicon) backends.\n        \"\"\"\n        try:\n            active_device = str(getattr(self, \"device\", \"cpu\")).split(\":\")[0]\n        except (TypeError, AttributeError):\n            active_device = None\n\n        # Fallback: if device is unset/None, detect by availability\n        if not active_device or active_device in (\"cpu\", \"None\"):\n            if torch.cuda.is_available():\n                active_device = \"cuda\"\n            elif hasattr(torch, \"xpu\") and torch.xpu.is_available():\n                active_device = \"xpu\"\n            elif hasattr(torch.backends, \"mps\") and torch.backends.mps.is_available():\n                active_device = \"mps\"\n\n        if active_device == \"cuda\" and torch.cuda.is_available():\n            torch.cuda.synchronize()\n            torch.cuda.empty_cache()\n        elif active_device == \"xpu\" and hasattr(torch, \"xpu\") and torch.xpu.is_available():\n            torch.xpu.synchronize()\n            torch.xpu.empty_cache()\n        elif active_device == \"mps\" and hasattr(torch.backends, \"mps\") and torch.backends.mps.is_available():\n            if hasattr(torch.mps, \"synchronize\"):\n                torch.mps.synchronize()\n            if hasattr(torch.mps, \"empty_cache\"):\n                torch.mps.empty_cache()\n\n    def unload(self) -> None:\n        \"\"\"Release LM weights/tokenizer and clear caches to free memory.\"\"\"\n        try:\n            if self.llm_backend == \"vllm\":\n                try:\n                    if hasattr(self.llm, \"reset\"):\n                        self.llm.reset()\n                except Exception:\n                    pass\n                self._cleanup_torch_distributed_state()\n            self.llm = None\n            self.llm_tokenizer = None\n            self.constrained_processor = None\n            self.llm_initialized = False\n            self.llm_backend = None\n            self._mlx_model = None\n            self._mlx_model_path = None\n            gc.collect()\n            if torch.cuda.is_available():\n                torch.cuda.empty_cache()\n                torch.cuda.synchronize()\n            elif hasattr(torch, \"mps\") and torch.backends.mps.is_available():\n                if hasattr(torch.mps, \"synchronize\"):\n                    torch.mps.synchronize()\n                if hasattr(torch.mps, \"empty_cache\"):\n                    torch.mps.empty_cache()\n            elif hasattr(torch, \"xpu\") and torch.xpu.is_available():\n                torch.xpu.empty_cache()\n                torch.xpu.synchronize()\n        except Exception:\n            pass\n\n    def _cleanup_torch_distributed_state(self) -> None:\n        \"\"\"Destroy default torch distributed process group when already initialized.\"\"\"\n        try:\n            import torch.distributed as dist\n            if dist.is_available() and dist.is_initialized():\n                logger.warning(\"[LLM vLLM] Destroying stale default process group before/after vLLM lifecycle\")\n                dist.destroy_process_group()\n        except Exception as exc:\n            logger.warning(f\"[LLM vLLM] Failed to clean torch distributed state: {exc}\")\n\n    def _get_checkpoint_dir(self) -> str:\n        \"\"\"Get checkpoint directory, prioritizing persistent storage\"\"\"\n        if self.persistent_storage_path:\n            return os.path.join(self.persistent_storage_path, \"checkpoints\")\n        current_file = os.path.abspath(__file__)\n        project_root = os.path.dirname(os.path.dirname(current_file))\n        return os.path.join(project_root, \"checkpoints\")\n\n    def get_available_5hz_lm_models(self) -> List[str]:\n        \"\"\"Scan and return all model directory names starting with 'acestep-5Hz-lm-'\"\"\"\n        checkpoint_dir = self._get_checkpoint_dir()\n\n        models = []\n        if os.path.exists(checkpoint_dir):\n            for item in os.listdir(checkpoint_dir):\n                item_path = os.path.join(checkpoint_dir, item)\n                if os.path.isdir(item_path) and item.startswith(\"acestep-5Hz-lm-\"):\n                    models.append(item)\n\n        models.sort()\n        return models\n\n    def get_gpu_memory_utilization(self, model_path: str = None, minimal_gpu: float = 8, min_ratio: float = 0.2, max_ratio: float = 0.9) -> Tuple[float, bool]:\n        \"\"\"\n        Get GPU memory utilization ratio based on LM model size and available GPU memory.\n\n        Args:\n            model_path: LM model path (e.g., \"acestep-5Hz-lm-0.6B\"). Used to determine target memory.\n            minimal_gpu: Minimum GPU memory requirement in GB (fallback)\n            min_ratio: Minimum memory utilization ratio\n            max_ratio: Maximum memory utilization ratio\n\n        Returns:\n            Tuple of (gpu_memory_utilization_ratio, low_gpu_memory_mode)\n        \"\"\"\n        try:\n            device = torch.device(\"cuda:0\")\n            total_gpu_mem_bytes = torch.cuda.get_device_properties(device).total_memory\n            total_gpu = total_gpu_mem_bytes / 1024**3\n\n            low_gpu_memory_mode = False\n\n            # Use adaptive GPU memory ratio based on model size\n            if model_path:\n                ratio, target_memory_gb = get_lm_gpu_memory_ratio(model_path, total_gpu)\n                logger.info(f\"Adaptive LM memory allocation: model={model_path}, target={target_memory_gb}GB, ratio={ratio:.3f}, total_gpu={total_gpu:.1f}GB\")\n\n                # Enable low memory mode for small GPUs\n                if total_gpu < 8:\n                    low_gpu_memory_mode = True\n\n                return ratio, low_gpu_memory_mode\n\n            # Fallback to original logic if no model_path provided\n            reserved_mem_bytes = torch.cuda.memory_reserved(device)\n            reserved_gpu = reserved_mem_bytes / 1024**3\n            available_gpu = total_gpu - reserved_gpu\n\n            if total_gpu < minimal_gpu:\n                minimal_gpu = 0.5 * total_gpu\n                low_gpu_memory_mode = True\n\n            if available_gpu >= minimal_gpu:\n                ratio = min(max_ratio, max(min_ratio, minimal_gpu / total_gpu))\n            else:\n                ratio = min(max_ratio, max(min_ratio, (available_gpu * 0.8) / total_gpu))\n\n            return ratio, low_gpu_memory_mode\n        except Exception as e:\n            logger.warning(f\"Failed to calculate GPU memory utilization: {e}\")\n            return 0.9, False\n\n    def _compute_max_new_tokens(\n        self,\n        target_duration: Optional[float],\n        generation_phase: str,\n        fallback_max: Optional[int] = None,\n    ) -> int:\n        \"\"\"\n        Compute max_new_tokens based on target duration and generation phase.\n\n        In the two-phase architecture:\n        - CoT phase: generates metadata (~50-200 tokens) + needs buffer for safety.\n        - Codes phase: CoT is already in the prompt; only audio codes are generated.\n          The constrained decoder forces EOS at exactly target_codes, so only a\n          small buffer (10 tokens) is needed to avoid a misleading progress bar.\n\n        Duration is clamped to ``[DURATION_MIN, max_dur]`` where *max_dur* is the\n        GPU-config-dependent maximum (from ``get_global_gpu_config()``) capped at\n        ``DURATION_MAX``.  This keeps the progress-bar total aligned with what the\n        constrained decoder actually enforces.\n\n        Args:\n            target_duration: Target duration in seconds (5 codes = 1 second).\n            generation_phase: \"cot\" or \"codes\".\n            fallback_max: Fallback value when target_duration is not set.\n\n        Returns:\n            Computed max_new_tokens value, capped at model's max length.\n        \"\"\"\n        if target_duration is not None and target_duration > 0:\n            # Determine the effective upper bound from GPU config (if available)\n            # so that max_new_tokens does not exceed what the constrained decoder\n            # will actually enforce on lower-tier GPUs.\n            gpu_max_dur = DURATION_MAX\n            try:\n                gpu_cfg = get_global_gpu_config()\n                gpu_max_dur = min(gpu_cfg.max_duration_with_lm, DURATION_MAX)\n            except Exception:\n                pass  # Fallback to DURATION_MAX if GPU config unavailable\n\n            effective_duration = max(DURATION_MIN, min(gpu_max_dur, target_duration))\n            target_codes = int(effective_duration * 5)\n            if generation_phase == \"codes\":\n                # Codes phase: CoT already in prompt, only audio codes generated.\n                # Constrained decoder forces EOS at target_codes, so small buffer suffices.\n                max_new_tokens = target_codes + 10\n            else:\n                # CoT phase or mixed: add larger buffer for metadata overhead.\n                max_new_tokens = target_codes + 500\n        else:\n            # When no target_duration is set, cap the fallback to a safe\n            # upper bound derived from DURATION_MAX so that generation cannot\n            # produce more audio codes than the downstream DiT can handle.\n            duration_cap = DURATION_MAX * 5 + 500  # codes + metadata buffer\n            if fallback_max is not None:\n                max_new_tokens = min(fallback_max, duration_cap)\n            else:\n                max_new_tokens = min(\n                    getattr(self, \"max_model_len\", 4096) - 64,\n                    duration_cap,\n                )\n\n        # Cap at model's max length\n        if hasattr(self, \"max_model_len\"):\n            max_new_tokens = min(max_new_tokens, self.max_model_len - 64)\n\n        return max_new_tokens\n\n    def _has_meaningful_negative_prompt(self, negative_prompt: str) -> bool:\n        \"\"\"Check if negative prompt is meaningful (not default/empty)\"\"\"\n        return negative_prompt and negative_prompt.strip() and negative_prompt.strip() != \"NO USER INPUT\"\n\n    def _build_logits_processor(self, repetition_penalty: float) -> LogitsProcessorList:\n        \"\"\"Build logits processor list with repetition penalty if needed\"\"\"\n        logits_processor = LogitsProcessorList()\n        if repetition_penalty != 1.0:\n            logits_processor.append(RepetitionPenaltyLogitsProcessor(penalty=repetition_penalty))\n        return logits_processor\n\n    def _setup_constrained_processor(\n        self,\n        use_constrained_decoding: bool,\n        constrained_decoding_debug: bool,\n        target_duration: Optional[float],\n        user_metadata: Optional[Dict[str, Optional[str]]],\n        stop_at_reasoning: bool,\n        skip_genres: bool,\n        skip_caption: bool,\n        skip_language: bool,\n        generation_phase: str,\n        is_batch: bool = False,\n        metadata_temperature: Optional[float] = None,\n        codes_temperature: Optional[float] = None,\n    ) -> Optional[MetadataConstrainedLogitsProcessor]:\n        \"\"\"Setup and configure constrained processor for generation\"\"\"\n        use_phase_temperatures = not is_batch and (metadata_temperature is not None or codes_temperature is not None)\n\n        if not use_constrained_decoding and not use_phase_temperatures:\n            return None\n\n        # Reset processor state for new generation\n        self.constrained_processor.reset()\n\n        # Use shared processor, just update settings\n        self.constrained_processor.enabled = use_constrained_decoding\n        self.constrained_processor.debug = constrained_decoding_debug\n\n        # Phase temperatures only supported in single mode\n        if use_phase_temperatures:\n            self.constrained_processor.metadata_temperature = metadata_temperature\n            self.constrained_processor.codes_temperature = codes_temperature\n        else:\n            self.constrained_processor.metadata_temperature = None\n            self.constrained_processor.codes_temperature = None\n\n        self.constrained_processor.set_target_duration(target_duration)\n\n        # Batch mode uses default/disabled settings for these options\n        if is_batch:\n            self.constrained_processor.set_user_metadata(None)\n            self.constrained_processor.set_stop_at_reasoning(False)\n            self.constrained_processor.set_skip_genres(True)\n            self.constrained_processor.set_skip_caption(True)\n            self.constrained_processor.set_skip_language(True)\n        else:\n            # Single mode uses provided settings\n            self.constrained_processor.set_user_metadata(user_metadata)\n            self.constrained_processor.set_stop_at_reasoning(stop_at_reasoning)\n            self.constrained_processor.set_skip_genres(skip_genres)\n            self.constrained_processor.set_skip_caption(skip_caption)\n            self.constrained_processor.set_skip_language(skip_language)\n\n        # Set generation phase for phase-aware processing\n        self.constrained_processor.set_generation_phase(generation_phase)\n\n        return self.constrained_processor\n\n    def _build_unconditional_prompt(\n        self,\n        caption: str,\n        lyrics: str,\n        cot_text: str,\n        negative_prompt: str,\n        generation_phase: str,\n        is_batch: bool = False,\n    ) -> str:\n        \"\"\"Build unconditional prompt for CFG based on generation phase and batch mode\"\"\"\n        if is_batch or generation_phase == \"codes\":\n            # Codes phase or batch mode: use empty CoT in unconditional prompt\n            return self.build_formatted_prompt_with_cot(\n                caption, lyrics, cot_text, is_negative_prompt=True, negative_prompt=negative_prompt\n            )\n        else:\n            # CoT phase (single mode only): unconditional prompt\n            # If negative_prompt is provided, use it as caption; otherwise remove caption and keep only lyrics\n            return self.build_formatted_prompt(\n                caption, lyrics, is_negative_prompt=True, generation_phase=\"cot\", negative_prompt=negative_prompt\n            )\n\n    def _load_pytorch_model(self, model_path: str, device: str) -> Tuple[bool, str]:\n        \"\"\"Load PyTorch model from path and return (success, status_message)\"\"\"\n        try:\n            self.llm = AutoModelForCausalLM.from_pretrained(model_path, trust_remote_code=True)\n            if not self.offload_to_cpu:\n                self.llm = self.llm.to(device).to(self.dtype)\n            else:\n                self.llm = self.llm.to(\"cpu\").to(self.dtype)\n            self.llm.eval()\n            self.llm_backend = \"pt\"\n            self.llm_initialized = True\n            logger.info(f\"5Hz LM initialized successfully using PyTorch backend on {device}\")\n            status_msg = f\"✅ 5Hz LM initialized successfully\\nModel: {model_path}\\nBackend: PyTorch\\nDevice: {device}\"\n            return True, status_msg\n        except Exception as e:\n            return False, f\"❌ Error initializing 5Hz LM: {str(e)}\\n\\nTraceback:\\n{traceback.format_exc()}\"\n\n    def _apply_top_k_filter(self, logits: torch.Tensor, top_k: Optional[int]) -> torch.Tensor:\n        \"\"\"Apply top-k filtering to logits\"\"\"\n        if top_k is not None and top_k > 0:\n            indices_to_remove = logits < torch.topk(logits, top_k)[0][..., -1, None]\n            logits[indices_to_remove] = float('-inf')\n        return logits\n\n    def _apply_top_p_filter(self, logits: torch.Tensor, top_p: Optional[float]) -> torch.Tensor:\n        \"\"\"Apply top-p (nucleus) filtering to logits\"\"\"\n        if top_p is not None and 0.0 < top_p < 1.0:\n            sorted_logits, sorted_indices = torch.sort(logits, descending=True)\n            # Upcast to float32 for stable softmax/cumsum (critical for float16/MPS)\n            cumulative_probs = torch.cumsum(torch.softmax(sorted_logits.float(), dim=-1), dim=-1)\n            sorted_indices_to_remove = cumulative_probs > top_p\n            sorted_indices_to_remove[..., 1:] = sorted_indices_to_remove[..., :-1].clone()\n            sorted_indices_to_remove[..., 0] = 0\n            indices_to_remove = sorted_indices_to_remove.scatter(1, sorted_indices, sorted_indices_to_remove)\n            logits[indices_to_remove] = float('-inf')\n        return logits\n\n    def _sample_tokens(self, logits: torch.Tensor, temperature: float) -> torch.Tensor:\n        \"\"\"Sample tokens from logits with temperature.\n\n        Upcasts to float32 for numerical stability (float16 logits can overflow\n        during softmax, especially after CFG scaling).\n        \"\"\"\n        if temperature > 0:\n            # Upcast to float32 for stable softmax (critical for float16/MPS)\n            logits = logits.float() / temperature\n            probs = torch.softmax(logits, dim=-1)\n            return torch.multinomial(probs, num_samples=1).squeeze(1)\n        else:\n            return torch.argmax(logits, dim=-1)\n\n    def _check_eos_token(self, tokens: torch.Tensor, eos_token_id: int, pad_token_id: Optional[int]) -> bool:\n        \"\"\"Check if any token in the batch is EOS or pad token\"\"\"\n        if torch.any(tokens == eos_token_id):\n            return True\n        if pad_token_id is not None and pad_token_id != eos_token_id:\n            if torch.any(tokens == pad_token_id):\n                return True\n        return False\n\n    def _update_constrained_processor_state(self, constrained_processor: Optional[MetadataConstrainedLogitsProcessor], tokens: torch.Tensor):\n        \"\"\"Update constrained processor state with generated tokens\"\"\"\n        if constrained_processor is not None:\n            for b in range(tokens.shape[0]):\n                constrained_processor.update_state(tokens[b].item())\n\n    def _forward_pass(\n        self,\n        model: Any,\n        generated_ids: torch.Tensor,\n        model_kwargs: Dict[str, Any],\n        past_key_values: Optional[Any],\n        use_cache: bool,\n    ) -> Any:\n        \"\"\"Perform forward pass with KV cache support\"\"\"\n        if past_key_values is None:\n            outputs = model(\n                input_ids=generated_ids,\n                **model_kwargs,\n                use_cache=use_cache,\n            )\n        else:\n            outputs = model(\n                input_ids=generated_ids[:, -1:],\n                past_key_values=past_key_values,\n                **model_kwargs,\n                use_cache=use_cache,\n            )\n        return outputs\n\n    def _normalize_batch_input(self, formatted_prompts: Union[str, List[str]]) -> Tuple[List[str], bool]:\n        \"\"\"Normalize batch input: convert single string to list and return (list, is_batch)\"\"\"\n        is_batch = isinstance(formatted_prompts, list)\n        if is_batch:\n            return formatted_prompts, is_batch\n        else:\n            return [formatted_prompts], is_batch\n\n    def initialize(\n        self,\n        checkpoint_dir: str,\n        lm_model_path: str,\n        backend: str = \"vllm\",\n        device: str = \"auto\",\n        offload_to_cpu: bool = False,\n        dtype: Optional[torch.dtype] = None,\n    ) -> Tuple[str, bool]:\n        \"\"\"\n        Initialize 5Hz LM model\n\n        Args:\n            checkpoint_dir: Checkpoint directory path\n            lm_model_path: LM model path (relative to checkpoint_dir)\n            backend: Backend type (\"vllm\" or \"pt\")\n            device: Device type (\"auto\", \"cuda\", \"mps\", \"xpu\", or \"cpu\")\n            offload_to_cpu: Whether to offload to CPU\n            dtype: Data type (if None, auto-detect based on device)\n\n        Returns:\n            (status_message, success)\n        \"\"\"\n        try:\n            if device == \"auto\":\n                if torch.cuda.is_available():\n                    device = \"cuda\"\n                elif hasattr(torch.backends, \"mps\") and torch.backends.mps.is_available():\n                    device = \"mps\"\n                elif hasattr(torch, 'xpu') and torch.xpu.is_available():\n                    device = \"xpu\"\n                else:\n                    device = \"cpu\"\n            elif device == \"cuda\" and not torch.cuda.is_available():\n                if hasattr(torch.backends, \"mps\") and torch.backends.mps.is_available():\n                    logger.warning(\"[initialize] CUDA requested but unavailable. Falling back to MPS.\")\n                    device = \"mps\"\n                elif hasattr(torch, 'xpu') and torch.xpu.is_available():\n                    logger.warning(\"[initialize] CUDA requested but unavailable. Falling back to XPU.\")\n                    device = \"xpu\"\n                else:\n                    logger.warning(\"[initialize] CUDA requested but unavailable. Falling back to CPU.\")\n                    device = \"cpu\"\n            elif device == \"mps\" and not (hasattr(torch.backends, \"mps\") and torch.backends.mps.is_available()):\n                if torch.cuda.is_available():\n                    logger.warning(\"[initialize] MPS requested but unavailable. Falling back to CUDA.\")\n                    device = \"cuda\"\n                elif hasattr(torch, 'xpu') and torch.xpu.is_available():\n                    logger.warning(\"[initialize] MPS requested but unavailable. Falling back to XPU.\")\n                    device = \"xpu\"\n                else:\n                    logger.warning(\"[initialize] MPS requested but unavailable. Falling back to CPU.\")\n                    device = \"cpu\"\n            elif device == \"xpu\" and not (hasattr(torch, 'xpu') and torch.xpu.is_available()):\n                if torch.cuda.is_available():\n                    logger.warning(\"[initialize] XPU requested but unavailable. Falling back to CUDA.\")\n                    device = \"cuda\"\n                elif hasattr(torch.backends, \"mps\") and torch.backends.mps.is_available():\n                    logger.warning(\"[initialize] XPU requested but unavailable. Falling back to MPS.\")\n                    device = \"mps\"\n                else:\n                    logger.warning(\"[initialize] XPU requested but unavailable. Falling back to CPU.\")\n                    device = \"cpu\"\n\n            self.device = device\n            self.offload_to_cpu = offload_to_cpu\n\n            # Set dtype based on device: bfloat16 for cuda/xpu, float32 for mps/cpu\n            # Note: LLM stays in float32 on MPS because autoregressive generation is\n            # latency-bound (not compute-bound), and many LLM weights trained in bfloat16\n            # produce NaN/inf when naively converted to float16 (different exponent range).\n            # The DiT and VAE use float16 on MPS where it actually helps throughput.\n            if dtype is None:\n                if device in [\"cuda\", \"xpu\"]:\n                    self.dtype = torch.bfloat16\n                else:\n                    self.dtype = torch.float32\n            else:\n                self.dtype = dtype\n                # Keep LM in float32 on MPS for stability.\n                if device == \"mps\" and self.dtype != torch.float32:\n                    logger.warning(\n                        f\"[initialize] Overriding requested dtype {self.dtype} to float32 for LM on MPS.\"\n                    )\n                    self.dtype = torch.float32\n\n            # If lm_model_path is None, use default\n            if lm_model_path is None:\n                lm_model_path = \"acestep-5Hz-lm-1.7B\"\n                logger.info(f\"[initialize] lm_model_path is None, using default: {lm_model_path}\")\n\n            full_lm_model_path = os.path.join(checkpoint_dir, lm_model_path)\n            if not os.path.exists(full_lm_model_path):\n                return f\"❌ 5Hz LM model not found at {full_lm_model_path}\", False\n\n            # Proactive CUDA cleanup before LM load to reduce fragmentation on mode/model switch\n            if device == \"cuda\" and torch.cuda.is_available():\n                gc.collect()\n                torch.cuda.empty_cache()\n                torch.cuda.synchronize()\n\n            logger.info(\"loading 5Hz LM tokenizer... it may take 80~90s\")\n            start_time = time.time()\n            # TODO: load tokenizer too slow, not found solution yet\n            llm_tokenizer = AutoTokenizer.from_pretrained(full_lm_model_path, use_fast=True)\n            logger.info(f\"5Hz LM tokenizer loaded successfully in {time.time() - start_time:.2f} seconds\")\n            self.llm_tokenizer = llm_tokenizer\n\n            # Initialize shared constrained decoding processor (one-time initialization)\n            # Use GPU-based max_duration to limit duration values in constrained decoding\n            logger.info(\"Initializing constrained decoding processor...\")\n            processor_start = time.time()\n\n            gpu_config = get_global_gpu_config()\n            # Use max_duration_with_lm since LM is being initialized\n            max_duration_for_constraint = gpu_config.max_duration_with_lm\n            logger.info(f\"Setting constrained decoding max_duration to {max_duration_for_constraint}s based on GPU config (tier: {gpu_config.tier})\")\n\n            self.constrained_processor = MetadataConstrainedLogitsProcessor(\n                tokenizer=self.llm_tokenizer,\n                enabled=True,\n                debug=False,\n                max_duration=max_duration_for_constraint,\n            )\n            logger.info(f\"Constrained processor initialized in {time.time() - processor_start:.2f} seconds\")\n\n            # Disable CUDA/HIP graph capture on ROCm (unverified on RDNA3 Windows),\n            # on Jetson (SDPA paged-cache decode calls .item() during capture),\n            # and when flash_attn is not installed (same .item() incompatibility on all CUDA hardware).\n            # When flash_attn is unavailable, nano-vllm falls back to _sdpa_decode_with_paged_cache\n            # which contains a Python loop with .item() calls.  These force CPU-GPU\n            # synchronisation that is forbidden inside torch.cuda.CUDAGraph capture,\n            # corrupting the CUDA context and causing downstream errors such as:\n            #   RuntimeError: Offset increment outside graph capture encountered unexpectedly\n            is_rocm = hasattr(torch.version, 'hip') and torch.version.hip is not None\n            is_jetson = False\n            if device == \"cuda\" and torch.cuda.is_available():\n                try:\n                    dev_name = torch.cuda.get_device_name(0).lower()\n                    is_jetson = any(k in dev_name for k in (\"orin\", \"xavier\", \"tegra\"))\n                    if is_jetson:\n                        logger.info(f\"Jetson GPU detected ({dev_name}): disabling CUDA graph capture for nano-vllm\")\n                except Exception:\n                    pass\n            _has_flash_attn = False\n            try:\n                import importlib.util\n                _has_flash_attn = importlib.util.find_spec(\"flash_attn\") is not None\n            except Exception:\n                pass\n            if not _has_flash_attn:\n                logger.info(\n                    \"flash_attn not installed: disabling CUDA graph capture for nano-vllm \"\n                    \"(SDPA fallback uses .item() calls in paged-cache decode that are \"\n                    \"incompatible with CUDA graph capture)\"\n                )\n            _has_triton = False\n            try:\n                import triton  # noqa: F401\n                _has_triton = True\n            except ImportError:\n                pass\n            if not _has_triton:\n                logger.info(\n                    \"Triton not available: disabling CUDA graph capture for nano-vllm \"\n                    \"(CUDA graphs require torch.compile which depends on Triton)\"\n                )\n            enforce_eager_for_vllm = bool(is_rocm or is_jetson or not _has_flash_attn or not _has_triton)\n\n            # Auto-detect best backend on Apple Silicon\n            if backend == \"mlx\" or (backend == \"vllm\" and device == \"mps\"):\n                # On Apple Silicon, prefer MLX (native acceleration) over PyTorch MPS\n                if self._is_mlx_available():\n                    logger.info(\"Attempting MLX backend for Apple Silicon acceleration...\")\n                    mlx_success, mlx_status = self._load_mlx_model(full_lm_model_path)\n                    if mlx_success:\n                        return mlx_status, True\n                    else:\n                        logger.warning(f\"MLX backend failed: {mlx_status}\")\n                        if backend == \"mlx\":\n                            # User explicitly requested MLX, fall back to PyTorch\n                            logger.warning(\"MLX explicitly requested but failed, falling back to PyTorch backend\")\n                            success, status_msg = self._load_pytorch_model(full_lm_model_path, device)\n                            if not success:\n                                return status_msg, False\n                            status_msg = f\"✅ 5Hz LM initialized (PyTorch fallback from MLX)\\nModel: {full_lm_model_path}\\nBackend: PyTorch\"\n                            return status_msg, True\n                        # else: backend was \"vllm\" on MPS, continue to vllm attempt below\n                elif backend == \"mlx\":\n                    logger.warning(\"MLX not available (requires Apple Silicon + mlx-lm package)\")\n                    # Fall back to PyTorch\n                    success, status_msg = self._load_pytorch_model(full_lm_model_path, device)\n                    if not success:\n                        return status_msg, False\n                    status_msg = f\"✅ 5Hz LM initialized (PyTorch fallback, MLX not available)\\nModel: {full_lm_model_path}\\nBackend: PyTorch\"\n                    return status_msg, True\n\n            if backend == \"vllm\" and device != \"cuda\":\n                logger.info(\n                    f\"[initialize] vllm backend requires CUDA, using PyTorch backend for device={device}.\"\n                )\n                backend = \"pt\"\n\n            vllm_preflight_warning = None\n            if backend == \"vllm\":\n                vllm_preflight_warning = get_vllm_preflight_warning(device=device)\n                if vllm_preflight_warning is not None:\n                    logger.warning(f\"[initialize] {vllm_preflight_warning}\")\n                    backend = \"pt\"\n\n            vllm_fallback_note = None\n\n            # Initialize based on user-selected backend\n            if backend == \"vllm\":\n                _warn_if_prerelease_python()\n                total_gb = get_gpu_memory_gb() if device == \"cuda\" else 0.0\n                free_gb = 0.0\n                if device == \"cuda\" and torch.cuda.is_available():\n                    try:\n                        if hasattr(torch.cuda, \"mem_get_info\"):\n                            free_bytes, _ = torch.cuda.mem_get_info()\n                            free_gb = free_bytes / (1024**3)\n                        else:\n                            total_bytes = torch.cuda.get_device_properties(0).total_memory\n                            free_gb = (total_bytes - torch.cuda.memory_reserved(0)) / (1024**3)\n                    except Exception:\n                        free_gb = 0.0\n                if device == \"cuda\" and free_gb < VRAM_SAFE_FREE_GB:\n                    logger.warning(\n                        f\"vLLM disabled due to insufficient free VRAM (total={total_gb:.2f}GB, free={free_gb:.2f}GB, need>={VRAM_SAFE_FREE_GB}GB free) — falling back to PyTorch backend\"\n                    )\n                    success, status_msg = self._load_pytorch_model(full_lm_model_path, device)\n                    if not success:\n                        return status_msg, False\n                    status_msg = f\"✅ 5Hz LM initialized successfully (PyTorch fallback)\\nModel: {full_lm_model_path}\\nBackend: PyTorch\"\n                else:\n                    status_msg = self._initialize_5hz_lm_vllm(\n                        full_lm_model_path,\n                        enforce_eager=enforce_eager_for_vllm,\n                        has_triton=_has_triton,\n                    )\n                    logger.info(f\"5Hz LM status message: {status_msg}\")\n                    if status_msg.startswith(\"❌\"):\n                        logger.warning(f\"vLLM initialization failed before PyTorch fallback: {status_msg}\")\n                        vllm_fallback_note = status_msg.splitlines()[0]\n                        if not self.llm_initialized:\n                            if device == \"mps\" and self._is_mlx_available():\n                                logger.warning(\"vllm failed on MPS, trying MLX backend...\")\n                                mlx_success, mlx_status = self._load_mlx_model(full_lm_model_path)\n                                if mlx_success:\n                                    return mlx_status, True\n                                logger.warning(f\"MLX also failed: {mlx_status}, falling back to PyTorch\")\n                            logger.warning(\"Falling back to PyTorch backend\")\n                            success, status_msg = self._load_pytorch_model(full_lm_model_path, device)\n                            if not success:\n                                return status_msg, False\n                            status_msg = f\"✅ 5Hz LM initialized successfully (PyTorch fallback)\\nModel: {full_lm_model_path}\\nBackend: PyTorch\"\n                            if vllm_fallback_note is not None:\n                                status_msg += f\"\\nNote: {vllm_fallback_note}\"\n            elif backend != \"mlx\":\n                success, status_msg = self._load_pytorch_model(full_lm_model_path, device)\n                if not success:\n                    return status_msg, False\n                if vllm_preflight_warning is not None:\n                    status_msg += f\"\\nNote: {vllm_preflight_warning}\"\n\n            return status_msg, True\n\n        except Exception as e:\n            return f\"❌ Error initializing 5Hz LM: {str(e)}\\n\\nTraceback:\\n{traceback.format_exc()}\", False\n\n    def _initialize_5hz_lm_vllm(self, model_path: str, enforce_eager: bool = False, has_triton: bool = True) -> str:\n        \"\"\"Initialize 5Hz LM model using vllm backend.\n\n        Args:\n            model_path: Path to the 5Hz LM model checkpoint.\n            enforce_eager: Disable CUDA graph capture.  Set to ``True`` when\n                Triton is unavailable so vLLM does not attempt graph capture\n                that depends on compiled kernels.\n            has_triton: Whether the Triton compiler is available.  When\n                ``False``, ``torch._dynamo`` diagnostics are temporarily\n                suppressed during initialization to avoid verbose fallback\n                warnings, then restored afterwards.\n        \"\"\"\n        if not torch.cuda.is_available():\n            self.llm_initialized = False\n            logger.error(\"CUDA/ROCm is not available. Please check your GPU setup.\")\n            return \"❌ CUDA/ROCm is not available. Please check your GPU setup.\"\n        try:\n            from nanovllm import LLM, SamplingParams\n        except ImportError:\n            self.llm_initialized = False\n            logger.error(\"nano-vllm is not installed. Please install it using 'cd acestep/third_parts/nano-vllm && pip install .'\")\n            return \"❌ nano-vllm is not installed. Please install it using 'cd acestep/third_parts/nano-vllm && pip install .'\"\n\n        try:\n            current_device = torch.cuda.current_device()\n            device_name = torch.cuda.get_device_name(current_device)\n\n            gc.collect()\n            torch.cuda.empty_cache()\n            self._cleanup_torch_distributed_state()\n\n            # Use adaptive GPU memory utilization based on model size\n            gpu_memory_utilization, low_gpu_memory_mode = self.get_gpu_memory_utilization(\n                model_path=model_path,\n                minimal_gpu=3,\n                min_ratio=0.1,\n                max_ratio=0.9\n            )\n\n            if low_gpu_memory_mode:\n                self.max_model_len = 2048\n            else:\n                self.max_model_len = 4096\n\n            logger.info(f\"Initializing 5Hz LM with model: {model_path}, enforce_eager: {enforce_eager}, tensor_parallel_size: 1, max_model_len: {self.max_model_len}, gpu_memory_utilization: {gpu_memory_utilization:.3f}\")\n\n            # When Triton is unavailable, torch._dynamo still attempts to\n            # compile functions decorated with @torch.compile and emits\n            # verbose \"WON'T CONVERT\" warnings with full tracebacks.\n            # suppress_errors makes it fall back silently to eager mode,\n            # and raising the log level hides the noisy warning output.\n            # State is restored after init to avoid masking diagnostics\n            # from other components.\n            _dynamo_state_saved = False\n            if not has_triton:\n                import torch._dynamo as _dynamo\n                import logging as _logging\n                _dynamo_logger = _logging.getLogger(\"torch._dynamo\")\n                _prev_suppress = _dynamo.config.suppress_errors\n                _prev_log_level = _dynamo_logger.level\n                _dynamo.config.suppress_errors = True\n                _dynamo_logger.setLevel(_logging.ERROR)\n                _dynamo_state_saved = True\n\n            try:\n                start_time = time.time()\n                self.llm = LLM(\n                    model=model_path,\n                    enforce_eager=enforce_eager,\n                    tensor_parallel_size=1,\n                    max_model_len=self.max_model_len,\n                    gpu_memory_utilization=gpu_memory_utilization,\n                    tokenizer=self.llm_tokenizer,\n                )\n                logger.info(f\"5Hz LM initialized successfully in {time.time() - start_time:.2f} seconds\")\n                self.llm_initialized = True\n                self.llm_backend = \"vllm\"\n                return f\"✅ 5Hz LM initialized successfully\\nModel: {model_path}\\nDevice: {device_name}\\nGPU Memory Utilization: {gpu_memory_utilization:.3f}\\nLow GPU Memory Mode: {low_gpu_memory_mode}\"\n            finally:\n                if _dynamo_state_saved:\n                    _dynamo.config.suppress_errors = _prev_suppress\n                    _dynamo_logger.setLevel(_prev_log_level)\n        except Exception as e:\n            self.llm_initialized = False\n            if \"Cannot find a working triton installation\" in str(e):\n                status_msg = \"❌ vLLM backend requires a working Triton installation.\"\n                if sys.platform == \"win32\":\n                    status_msg += (\n                        \" Falling back to PyTorch is recommended on Windows. \"\n                        \"Use --backend pt to avoid this warning.\"\n                    )\n                return status_msg\n            return f\"❌ Error initializing 5Hz LM: {str(e)}\\n\\nTraceback:\\n{traceback.format_exc()}\"\n\n    def _run_vllm(\n        self,\n        formatted_prompts: Union[str, List[str]],\n        temperature: float,\n        cfg_scale: float,\n        negative_prompt: str,\n        top_k: Optional[int],\n        top_p: Optional[float],\n        repetition_penalty: float,\n        use_constrained_decoding: bool = True,\n        constrained_decoding_debug: bool = False,\n        metadata_temperature: Optional[float] = None,\n        codes_temperature: Optional[float] = None,\n        target_duration: Optional[float] = None,\n        user_metadata: Optional[Dict[str, Optional[str]]] = None,\n        stop_at_reasoning: bool = False,\n        skip_genres: bool = True,\n        skip_caption: bool = False,\n        skip_language: bool = False,\n        generation_phase: str = \"cot\",\n        caption: str = \"\",\n        lyrics: str = \"\",\n        cot_text: str = \"\",\n        seeds: Optional[List[int]] = None,\n    ) -> Union[str, List[str]]:\n        \"\"\"\n        Unified vllm generation function supporting both single and batch modes.\n        Accepts either a single formatted prompt (str) or a list of formatted prompts (List[str]).\n        Returns a single string for single mode, or a list of strings for batch mode.\n        \"\"\"\n        from nanovllm import SamplingParams\n\n        # Determine if batch mode\n        formatted_prompt_list, is_batch = self._normalize_batch_input(formatted_prompts)\n        batch_size = len(formatted_prompt_list)\n\n        # Determine effective temperature for sampler\n        # Batch mode doesn't support phase temperatures, so use simple temperature\n        # Single mode supports phase temperatures\n        use_phase_temperatures = not is_batch and (metadata_temperature is not None or codes_temperature is not None)\n        effective_sampler_temp = 1.0 if use_phase_temperatures else temperature\n\n        # Setup constrained processor\n        constrained_processor = self._setup_constrained_processor(\n            use_constrained_decoding=use_constrained_decoding or use_phase_temperatures,\n            constrained_decoding_debug=constrained_decoding_debug,\n            target_duration=target_duration,\n            user_metadata=user_metadata,\n            stop_at_reasoning=stop_at_reasoning,\n            skip_genres=skip_genres,\n            skip_caption=skip_caption,\n            skip_language=skip_language,\n            generation_phase=generation_phase,\n            is_batch=is_batch,\n            metadata_temperature=metadata_temperature,\n            codes_temperature=codes_temperature,\n        )\n\n        # Calculate max_tokens based on target_duration and generation phase\n        max_tokens = self._compute_max_new_tokens(\n            target_duration=target_duration,\n            generation_phase=generation_phase,\n            fallback_max=self.max_model_len - 64,\n        )\n\n        sampling_params = SamplingParams(\n            max_tokens=max_tokens,\n            temperature=effective_sampler_temp,\n            cfg_scale=cfg_scale,\n            top_k=top_k,\n            top_p=top_p,\n            repetition_penalty=repetition_penalty,\n            logits_processor=constrained_processor,\n            logits_processor_update_state=constrained_processor.update_state if constrained_processor else None,\n        )\n\n        if cfg_scale > 1.0:\n            # Build unconditional prompt based on generation phase\n            formatted_unconditional_prompt = self._build_unconditional_prompt(\n                caption=caption,\n                lyrics=lyrics,\n                cot_text=cot_text,\n                negative_prompt=negative_prompt,\n                generation_phase=generation_phase,\n                is_batch=is_batch,\n            )\n            unconditional_prompts = [formatted_unconditional_prompt] * batch_size\n\n            outputs = self.llm.generate(\n                formatted_prompt_list,\n                sampling_params,\n                unconditional_prompts=unconditional_prompts,\n            )\n        else:\n            outputs = self.llm.generate(formatted_prompt_list, sampling_params)\n\n        # Extract text from outputs\n        output_texts = []\n        for output in outputs:\n            if hasattr(output, \"outputs\") and len(output.outputs) > 0:\n                output_texts.append(output.outputs[0].text)\n            elif hasattr(output, \"text\"):\n                output_texts.append(output.text)\n            elif isinstance(output, dict) and \"text\" in output:\n                output_texts.append(output[\"text\"])\n            else:\n                output_texts.append(str(output))\n\n        # Return single string for single mode, list for batch mode\n        return output_texts[0] if not is_batch else output_texts\n\n    def _run_pt_single(\n        self,\n        formatted_prompt: str,\n        temperature: float,\n        cfg_scale: float,\n        negative_prompt: str,\n        top_k: Optional[int],\n        top_p: Optional[float],\n        repetition_penalty: float,\n        use_constrained_decoding: bool,\n        constrained_decoding_debug: bool,\n        target_duration: Optional[float],\n        user_metadata: Optional[Dict[str, Optional[str]]],\n        stop_at_reasoning: bool,\n        skip_genres: bool,\n        skip_caption: bool,\n        skip_language: bool,\n        generation_phase: str,\n        caption: str,\n        lyrics: str,\n        cot_text: str,\n    ) -> str:\n        \"\"\"Internal helper function for single-item PyTorch generation.\"\"\"\n        inputs = self.llm_tokenizer(\n            formatted_prompt,\n            return_tensors=\"pt\",\n            padding=False,\n            truncation=True,\n        )\n\n        # Setup constrained processor\n        constrained_processor = self._setup_constrained_processor(\n            use_constrained_decoding=use_constrained_decoding,\n            constrained_decoding_debug=constrained_decoding_debug,\n            target_duration=target_duration,\n            user_metadata=user_metadata,\n            stop_at_reasoning=stop_at_reasoning,\n            skip_genres=skip_genres,\n            skip_caption=skip_caption,\n            skip_language=skip_language,\n            generation_phase=generation_phase,\n            is_batch=False,\n        )\n\n        with self._load_model_context():\n            inputs = {k: v.to(self.device) for k, v in inputs.items()}\n\n            # Calculate max_new_tokens based on target_duration and generation phase\n            max_new_tokens = self._compute_max_new_tokens(\n                target_duration=target_duration,\n                generation_phase=generation_phase,\n                fallback_max=getattr(self.llm.config, \"max_new_tokens\", 4096),\n            )\n\n            # Build logits processor list (only for CFG and repetition penalty)\n            logits_processor = self._build_logits_processor(repetition_penalty)\n\n            if cfg_scale > 1.0:\n                # Build unconditional prompt based on generation phase\n                formatted_unconditional_prompt = self._build_unconditional_prompt(\n                    caption=caption,\n                    lyrics=lyrics,\n                    cot_text=cot_text,\n                    negative_prompt=negative_prompt,\n                    generation_phase=generation_phase,\n                    is_batch=False,\n                )\n\n                # Tokenize both prompts together to ensure same length (with left padding)\n                # Left padding is important for generation tasks\n                batch_texts = [formatted_prompt, formatted_unconditional_prompt]\n                original_padding_side = self.llm_tokenizer.padding_side\n                self.llm_tokenizer.padding_side = 'left'\n                batch_inputs_tokenized = self.llm_tokenizer(\n                    batch_texts,\n                    return_tensors=\"pt\",\n                    padding=True,\n                    truncation=True,\n                )\n                self.llm_tokenizer.padding_side = original_padding_side\n                batch_inputs_tokenized = {k: v.to(self.device) for k, v in batch_inputs_tokenized.items()}\n\n                # Extract batch inputs\n                batch_input_ids = batch_inputs_tokenized['input_ids']\n                batch_attention_mask = batch_inputs_tokenized.get('attention_mask', None)\n\n                # Use custom CFG generation loop with constrained decoding\n                outputs = self._generate_with_cfg_custom(\n                    batch_input_ids=batch_input_ids,\n                    batch_attention_mask=batch_attention_mask,\n                    max_new_tokens=max_new_tokens,\n                    temperature=temperature,\n                    cfg_scale=cfg_scale,\n                    top_k=top_k,\n                    top_p=top_p,\n                    repetition_penalty=repetition_penalty,\n                    pad_token_id=self.llm_tokenizer.pad_token_id or self.llm_tokenizer.eos_token_id,\n                    streamer=None,\n                    constrained_processor=constrained_processor,\n                )\n\n                # Extract only the conditional output (first in batch)\n                outputs = outputs[0:1]  # Keep only conditional output\n            elif use_constrained_decoding:\n                # Use custom constrained decoding loop for non-CFG\n                outputs = self._generate_with_constrained_decoding(\n                    input_ids=inputs[\"input_ids\"],\n                    attention_mask=inputs.get(\"attention_mask\"),\n                    max_new_tokens=max_new_tokens,\n                    temperature=temperature,\n                    top_k=top_k,\n                    top_p=top_p,\n                    repetition_penalty=repetition_penalty,\n                    pad_token_id=self.llm_tokenizer.pad_token_id or self.llm_tokenizer.eos_token_id,\n                    streamer=None,\n                    constrained_processor=constrained_processor,\n                )\n            else:\n                # Generate without CFG using native generate() parameters\n                with torch.inference_mode():\n                    outputs = self.llm.generate(\n                        **inputs,\n                        max_new_tokens=max_new_tokens,\n                        temperature=temperature if temperature > 0 else 1.0,\n                        do_sample=True if temperature > 0 else False,\n                        top_k=top_k if top_k is not None and top_k > 0 else None,\n                        top_p=top_p if top_p is not None and 0.0 < top_p < 1.0 else None,\n                        logits_processor=logits_processor if len(logits_processor) > 0 else None,\n                        pad_token_id=self.llm_tokenizer.pad_token_id or self.llm_tokenizer.eos_token_id,\n                        streamer=None,\n                    )\n\n        # Decode the generated tokens\n        # outputs is a tensor with shape [batch_size, seq_len], extract first sequence\n        if isinstance(outputs, torch.Tensor):\n            if outputs.dim() == 2:\n                generated_ids = outputs[0]\n            else:\n                generated_ids = outputs\n        else:\n            generated_ids = outputs[0]\n\n        # Only decode the newly generated tokens (skip the input prompt)\n        # Use the original input length (before batch processing for CFG)\n        if cfg_scale > 1.0:\n            # In CFG case, we need to use the conditional input length from batch_inputs_tokenized\n            # Both sequences have the same length due to padding\n            input_length = batch_inputs_tokenized['input_ids'].shape[1]\n        else:\n            input_length = inputs[\"input_ids\"].shape[1]\n\n        generated_ids = generated_ids[input_length:]\n\n        # Move to CPU for decoding (tokenizer needs CPU tensors)\n        if generated_ids.device.type != \"cpu\":\n            generated_ids = generated_ids.cpu()\n\n        output_text = self.llm_tokenizer.decode(generated_ids, skip_special_tokens=False)\n        return output_text\n\n    def _run_pt(\n        self,\n        formatted_prompts: Union[str, List[str]],\n        temperature: float,\n        cfg_scale: float,\n        negative_prompt: str,\n        top_k: Optional[int],\n        top_p: Optional[float],\n        repetition_penalty: float,\n        use_constrained_decoding: bool = True,\n        constrained_decoding_debug: bool = False,\n        target_duration: Optional[float] = None,\n        user_metadata: Optional[Dict[str, Optional[str]]] = None,\n        stop_at_reasoning: bool = False,\n        skip_genres: bool = True,\n        skip_caption: bool = False,\n        skip_language: bool = False,\n        generation_phase: str = \"cot\",\n        caption: str = \"\",\n        lyrics: str = \"\",\n        cot_text: str = \"\",\n        seeds: Optional[List[int]] = None,\n    ) -> Union[str, List[str]]:\n        \"\"\"\n        Unified PyTorch generation function supporting both single and batch modes.\n        Accepts either a single formatted prompt (str) or a list of formatted prompts (List[str]).\n        Returns a single string for single mode, or a list of strings for batch mode.\n        Note: PyTorch backend processes batch items sequentially (doesn't support true batching efficiently).\n        \"\"\"\n        # Determine if batch mode\n        formatted_prompt_list, is_batch = self._normalize_batch_input(formatted_prompts)\n\n        # For batch mode, process each item sequentially with different seeds.\n        # Wrap the entire loop in a single _load_model_context() so the model\n        # loads to GPU once and offloads once, instead of per-item.\n        if is_batch:\n            output_texts = []\n\n            with self._load_model_context():\n                for i, formatted_prompt in enumerate(formatted_prompt_list):\n                    # Set seed for this item if provided\n                    if seeds and i < len(seeds):\n                        torch.manual_seed(seeds[i])\n                        if torch.cuda.is_available():\n                            torch.cuda.manual_seed_all(seeds[i])\n                        elif hasattr(torch.backends, \"mps\") and torch.backends.mps.is_available():\n                            torch.mps.manual_seed(seeds[i])\n\n                    # Generate using single-item method with batch-mode defaults\n                    output_text = self._run_pt_single(\n                        formatted_prompt=formatted_prompt,\n                        temperature=temperature,\n                        cfg_scale=cfg_scale,\n                        negative_prompt=negative_prompt,\n                        top_k=top_k,\n                        top_p=top_p,\n                        repetition_penalty=repetition_penalty,\n                        use_constrained_decoding=use_constrained_decoding,\n                        constrained_decoding_debug=constrained_decoding_debug,\n                        target_duration=target_duration,\n                        user_metadata=None,\n                        stop_at_reasoning=False,\n                        skip_genres=True,\n                        skip_caption=True,\n                        skip_language=True,\n                        generation_phase=generation_phase,\n                        caption=caption,\n                        lyrics=lyrics,\n                        cot_text=cot_text,\n                    )\n\n                    output_texts.append(output_text)\n\n            return output_texts\n\n        # Single mode: process the formatted prompt\n        formatted_prompt = formatted_prompt_list[0]\n\n        return self._run_pt_single(\n            formatted_prompt=formatted_prompt,\n            temperature=temperature,\n            cfg_scale=cfg_scale,\n            negative_prompt=negative_prompt,\n            top_k=top_k,\n            top_p=top_p,\n            repetition_penalty=repetition_penalty,\n            use_constrained_decoding=use_constrained_decoding,\n            constrained_decoding_debug=constrained_decoding_debug,\n            target_duration=target_duration,\n            user_metadata=user_metadata,\n            stop_at_reasoning=stop_at_reasoning,\n            skip_genres=skip_genres,\n            skip_caption=skip_caption,\n            skip_language=skip_language,\n            generation_phase=generation_phase,\n            caption=caption,\n            lyrics=lyrics,\n            cot_text=cot_text,\n        )\n\n    def has_all_metas(self, user_metadata: Optional[Dict[str, Optional[str]]]) -> bool:\n        \"\"\"Check if all required metadata are present.\"\"\"\n        if user_metadata is None:\n            return False\n        if 'bpm' in user_metadata and 'keyscale' in user_metadata and 'timesignature' in user_metadata and 'duration' in user_metadata:\n            return True\n        return False\n\n    def _format_metadata_as_cot(self, metadata: Dict[str, Any]) -> str:\n        \"\"\"\n        Format parsed metadata as CoT text using YAML format (matching training format).\n\n        Args:\n            metadata: Dictionary with keys: bpm, caption, duration, keyscale, language, timesignature\n\n        Returns:\n            Formatted CoT text: \"<think>\\n{yaml_content}\\n</think>\"\n        \"\"\"\n        # Build cot_items dict with only non-None values\n        cot_items = {}\n        for key in ['bpm', 'caption', 'duration', 'keyscale', 'language', 'timesignature']:\n            if key in metadata and metadata[key] is not None:\n                value = metadata[key]\n                if key == \"timesignature\" and value.endswith(\"/4\"):\n                    value = value.split(\"/\")[0]\n                if isinstance(value, str) and value.isdigit():\n                    value = int(value)\n                cot_items[key] = value\n\n        # Format as YAML (sorted keys, unicode support)\n        if len(cot_items) > 0:\n            cot_yaml = yaml.dump(cot_items, allow_unicode=True, sort_keys=True).strip()\n        else:\n            cot_yaml = \"\"\n\n        return f\"<think>\\n{cot_yaml}\\n</think>\"\n\n    def generate_with_stop_condition(\n        self,\n        caption: str,\n        lyrics: str,\n        infer_type: str,\n        temperature: float = 0.85,\n        cfg_scale: float = 1.0,\n        negative_prompt: str = \"NO USER INPUT\",\n        top_k: Optional[int] = None,\n        top_p: Optional[float] = None,\n        repetition_penalty: float = 1.0,\n        use_constrained_decoding: bool = True,\n        constrained_decoding_debug: bool = False,\n        target_duration: Optional[float] = None,\n        user_metadata: Optional[Dict[str, Optional[str]]] = None,\n        use_cot_metas: bool = True,\n        use_cot_caption: bool = True,\n        use_cot_language: bool = True,\n        batch_size: Optional[int] = None,\n        seeds: Optional[List[int]] = None,\n        progress=None,\n    ) -> Dict[str, Any]:\n        \"\"\"Two-phase LM generation: CoT generation followed by audio codes generation.\n\n        - infer_type='dit': Phase 1 only - generate CoT and return metas (no audio codes)\n        - infer_type='llm_dit': Phase 1 + Phase 2 - generate CoT then audio codes\n\n        Args:\n            target_duration: Target duration in seconds for codes generation constraint.\n                            5 codes = 1 second. If specified, blocks EOS until target reached.\n            user_metadata: User-provided metadata fields (e.g. bpm/duration/keyscale/timesignature).\n                           If specified, constrained decoding will inject these values directly.\n            use_cot_caption: Whether to generate caption in CoT (default True).\n            use_cot_language: Whether to generate language in CoT (default True).\n            batch_size: Optional batch size for batch generation. If None or 1, returns single result.\n                       If > 1, returns batch results (lists).\n            seeds: Optional list of seeds for batch generation (for reproducibility).\n                  Only used when batch_size > 1. TODO: not used yet\n\n        Returns:\n            Dictionary containing:\n                - metadata: Dict or List[Dict] - Generated metadata\n                - audio_codes: str or List[str] - Generated audio codes\n                - success: bool - Whether generation succeeded\n                - error: Optional[str] - Error message if failed\n                - extra_outputs: Dict with time_costs and other info\n        \"\"\"\n        if progress is None:\n            def progress(*args, **kwargs):\n                pass\n\n        infer_type = (infer_type or \"\").strip().lower()\n        if infer_type not in {\"dit\", \"llm_dit\"}:\n            error_msg = f\"invalid infer_type: {infer_type!r} (expected 'dit' or 'llm_dit')\"\n            return {\n                \"metadata\": [] if (batch_size and batch_size > 1) else {},\n                \"audio_codes\": [] if (batch_size and batch_size > 1) else \"\",\n                \"success\": False,\n                \"error\": error_msg,\n                \"extra_outputs\": {\"time_costs\": {}},\n            }\n\n        # Determine if batch mode\n        is_batch = batch_size and batch_size > 1\n        actual_batch_size = batch_size if is_batch else 1\n\n        # Initialize variables\n        metadata = {}\n        audio_codes = \"\"\n        has_all_metas = self.has_all_metas(user_metadata)\n        phase1_time = 0.0\n        phase2_time = 0.0\n\n        # Handle seeds for batch mode\n        if is_batch:\n            if seeds is None:\n                seeds = [random.randint(0, 2**32 - 1) for _ in range(actual_batch_size)]\n            elif len(seeds) < actual_batch_size:\n                seeds = list(seeds) + [random.randint(0, 2**32 - 1) for _ in range(actual_batch_size - len(seeds))]\n            else:\n                seeds = seeds[:actual_batch_size]\n\n        # ========== PHASE 1: CoT Generation ==========\n        # Skip CoT if all metadata are user-provided OR caption is already formatted\n        progress(0.1, f\"Phase 1: Generating CoT metadata (once for all items)...\")\n        if not has_all_metas and use_cot_metas:\n            if is_batch:\n                logger.info(\"Batch Phase 1: Generating CoT metadata (once for all items)...\")\n            else:\n                logger.info(\"Phase 1: Generating CoT metadata...\")\n            phase1_start = time.time()\n\n            # Build formatted prompt for CoT phase\n            formatted_prompt = self.build_formatted_prompt(caption, lyrics, generation_phase=\"cot\")\n\n            logger.info(f\"generate_with_stop_condition: formatted_prompt={formatted_prompt}\")\n            # Generate CoT (stop at </think>)\n            cot_output_text, status = self.generate_from_formatted_prompt(\n                formatted_prompt=formatted_prompt,\n                cfg={\n                    \"temperature\": temperature,\n                    # CFG must not be applied during CoT (text generation) phase.\n                    # cfg_scale > 1 distorts text logits during reasoning, causing\n                    # premature newlines and truncated captions.\n                    \"cfg_scale\": 1.0,\n                    \"negative_prompt\": negative_prompt,\n                    \"top_k\": top_k,\n                    \"top_p\": top_p,\n                    \"repetition_penalty\": repetition_penalty,\n                    \"target_duration\": None,  # No duration constraint for CoT phase\n                    \"user_metadata\": user_metadata,\n                    \"skip_caption\": not use_cot_caption,\n                    \"skip_language\": not use_cot_language,\n                    \"skip_genres\": True,  # Generate genres\n                    \"generation_phase\": \"cot\",\n                    # Pass context for building unconditional prompt in CoT phase\n                    \"caption\": caption,\n                    \"lyrics\": lyrics,\n                },\n                use_constrained_decoding=use_constrained_decoding,\n                constrained_decoding_debug=constrained_decoding_debug,\n                stop_at_reasoning=True,  # Always stop at </think> in Phase 1\n            )\n\n            phase1_time = time.time() - phase1_start\n\n            if not cot_output_text:\n                return {\n                    \"metadata\": [] if is_batch else {},\n                    \"audio_codes\": [] if is_batch else \"\",\n                    \"success\": False,\n                    \"error\": status,\n                    \"extra_outputs\": {\"time_costs\": {\"phase1_time\": phase1_time}},\n                }\n\n            # Parse metadata from CoT output\n            metadata, _ = self.parse_lm_output(cot_output_text)\n            if is_batch:\n                logger.info(f\"Batch Phase 1 completed in {phase1_time:.2f}s. Generated metadata: {list(metadata.keys())}\")\n            else:\n                logger.info(f\"Phase 1 completed in {phase1_time:.2f}s. Generated metadata: {list(metadata.keys())}\")\n        else:\n            # Use user-provided metadata\n            if is_batch:\n                logger.info(\"Batch Phase 1: Using user-provided metadata (skipping generation)\")\n            else:\n                logger.info(\"Phase 1: Using user-provided metadata (skipping generation)\")\n            metadata = {k: v for k, v in user_metadata.items() if v is not None}\n\n        # When the caller did not supply an explicit target_duration, use the\n        # duration that Phase 1 (CoT) produced so that Phase 2 code generation\n        # is properly constrained.  Without this, a null API duration lets\n        # Phase 2 run unconstrained, potentially producing more audio codes\n        # than the downstream DiT expects and causing a tensor-size mismatch.\n        if (target_duration is None or target_duration <= 0) and metadata.get(\"duration\"):\n            try:\n                cot_duration = float(metadata[\"duration\"])\n                if cot_duration > 0:\n                    target_duration = cot_duration\n                    logger.info(\n                        f\"Using CoT-generated duration ({cot_duration}s) as \"\n                        f\"Phase 2 target_duration (original was None/unset)\"\n                    )\n            except (ValueError, TypeError):\n                pass\n\n        # If infer_type is 'dit', stop here and return only metadata\n        if infer_type == \"dit\":\n            if is_batch:\n                metadata_list = [metadata.copy() for _ in range(actual_batch_size)]\n                return {\n                    \"metadata\": metadata_list,\n                    \"audio_codes\": [\"\"] * actual_batch_size,\n                    \"success\": True,\n                    \"error\": None,\n                    \"extra_outputs\": {\n                        \"time_costs\": {\n                            \"phase1_time\": phase1_time,\n                            \"total_time\": phase1_time,\n                        }\n                    },\n                }\n            else:\n                return {\n                    \"metadata\": metadata,\n                    \"audio_codes\": \"\",\n                    \"success\": True,\n                    \"error\": None,\n                    \"extra_outputs\": {\n                        \"time_costs\": {\n                            \"phase1_time\": phase1_time,\n                            \"total_time\": phase1_time,\n                        }\n                    },\n                }\n\n        # ========== PHASE 2: Audio Codes Generation ==========\n        if is_batch:\n            logger.info(f\"Batch Phase 2: Generating audio codes for {actual_batch_size} items...\")\n        else:\n            logger.info(\"Phase 2: Generating audio codes...\")\n        phase2_start = time.time()\n\n        # Format metadata as CoT using YAML (matching training format)\n        cot_text = self._format_metadata_as_cot(metadata)\n\n        # Build formatted prompt with CoT for codes generation phase\n        formatted_prompt_with_cot = self.build_formatted_prompt_with_cot(caption, lyrics, cot_text)\n        logger.info(f\"generate_with_stop_condition: formatted_prompt_with_cot={formatted_prompt_with_cot}\")\n\n        progress(0.5, f\"Phase 2: Generating audio codes for {actual_batch_size} items...\")\n        if is_batch:\n            # Batch mode: generate codes for all items\n            formatted_prompts = [formatted_prompt_with_cot] * actual_batch_size\n\n            # Call backend-specific batch generation\n            try:\n                if self.llm_backend == \"vllm\":\n                    codes_outputs = self._run_vllm(\n                        formatted_prompts=formatted_prompts,\n                        temperature=temperature,\n                        cfg_scale=cfg_scale,\n                        negative_prompt=negative_prompt,\n                        top_k=top_k,\n                        top_p=top_p,\n                        repetition_penalty=repetition_penalty,\n                        use_constrained_decoding=use_constrained_decoding,\n                        constrained_decoding_debug=constrained_decoding_debug,\n                        target_duration=target_duration,\n                        generation_phase=\"codes\",\n                        caption=caption,\n                        lyrics=lyrics,\n                        cot_text=cot_text,\n                        seeds=seeds,\n                    )\n                elif self.llm_backend == \"mlx\":\n                    codes_outputs = self._run_mlx(\n                        formatted_prompts=formatted_prompts,\n                        temperature=temperature,\n                        cfg_scale=cfg_scale,\n                        negative_prompt=negative_prompt,\n                        top_k=top_k,\n                        top_p=top_p,\n                        repetition_penalty=repetition_penalty,\n                        use_constrained_decoding=use_constrained_decoding,\n                        constrained_decoding_debug=constrained_decoding_debug,\n                        target_duration=target_duration,\n                        generation_phase=\"codes\",\n                        caption=caption,\n                        lyrics=lyrics,\n                        cot_text=cot_text,\n                        seeds=seeds,\n                    )\n                else:  # pt backend\n                    codes_outputs = self._run_pt(\n                        formatted_prompts=formatted_prompts,\n                        temperature=temperature,\n                        cfg_scale=cfg_scale,\n                        negative_prompt=negative_prompt,\n                        top_k=top_k,\n                        top_p=top_p,\n                        repetition_penalty=repetition_penalty,\n                        use_constrained_decoding=use_constrained_decoding,\n                        constrained_decoding_debug=constrained_decoding_debug,\n                        target_duration=target_duration,\n                        generation_phase=\"codes\",\n                        caption=caption,\n                        lyrics=lyrics,\n                        cot_text=cot_text,\n                        seeds=seeds,\n                    )\n            except Exception as e:\n                error_msg = f\"Error in batch codes generation: {str(e)}\"\n                logger.error(error_msg)\n                return {\n                    \"metadata\": [],\n                    \"audio_codes\": [],\n                    \"success\": False,\n                    \"error\": error_msg,\n                    \"extra_outputs\": {\n                        \"time_costs\": {\n                            \"phase1_time\": phase1_time,\n                            \"phase2_time\": 0.0,\n                            \"total_time\": phase1_time,\n                        }\n                    },\n                }\n            finally:\n                self._clear_accelerator_cache()\n\n            # Parse audio codes from each output\n            audio_codes_list = []\n            metadata_list = []\n            for output_text in codes_outputs:\n                _, audio_codes_item = self.parse_lm_output(output_text)\n                audio_codes_list.append(audio_codes_item)\n                metadata_list.append(metadata.copy())  # Same metadata for all\n\n            phase2_time = time.time() - phase2_start\n\n            # Log results\n            codes_counts = [len(codes.split('<|audio_code_')) - 1 if codes else 0 for codes in audio_codes_list]\n            logger.info(f\"Batch Phase 2 completed in {phase2_time:.2f}s. Generated codes: {codes_counts}\")\n\n            total_time = phase1_time + phase2_time\n            return {\n                \"metadata\": metadata_list,\n                \"audio_codes\": audio_codes_list,\n                \"success\": True,\n                \"error\": None,\n                \"extra_outputs\": {\n                    \"time_costs\": {\n                        \"phase1_time\": phase1_time,\n                        \"phase2_time\": phase2_time,\n                        \"total_time\": total_time,\n                    },\n                    \"codes_counts\": codes_counts,\n                    \"total_codes\": sum(codes_counts),\n                },\n            }\n        else:\n            # Single mode: generate codes for one item\n            codes_output_text, status = self.generate_from_formatted_prompt(\n                formatted_prompt=formatted_prompt_with_cot,\n                cfg={\n                    \"temperature\": temperature,\n                    \"cfg_scale\": cfg_scale,\n                    \"negative_prompt\": negative_prompt,\n                    \"top_k\": top_k,\n                    \"top_p\": top_p,\n                    \"repetition_penalty\": repetition_penalty,\n                    \"target_duration\": target_duration,\n                    \"user_metadata\": None,  # No user metadata injection in Phase 2\n                    \"skip_caption\": True,  # Skip caption since CoT is already included\n                    \"skip_language\": True,  # Skip language since CoT is already included\n                    \"generation_phase\": \"codes\",\n                    # Pass context for building unconditional prompt in codes phase\n                    \"caption\": caption,\n                    \"lyrics\": lyrics,\n                    \"cot_text\": cot_text,\n                },\n                use_constrained_decoding=use_constrained_decoding,\n                constrained_decoding_debug=constrained_decoding_debug,\n                stop_at_reasoning=False,  # Generate codes until EOS\n            )\n\n            if not codes_output_text:\n                total_time = phase1_time + phase2_time\n                return {\n                    \"metadata\": metadata,\n                    \"audio_codes\": \"\",\n                    \"success\": False,\n                    \"error\": status,\n                    \"extra_outputs\": {\n                        \"time_costs\": {\n                            \"phase1_time\": phase1_time,\n                            \"phase2_time\": phase2_time,\n                            \"total_time\": total_time,\n                        }\n                    },\n                }\n\n            phase2_time = time.time() - phase2_start\n\n            # Parse audio codes from output (metadata should be same as Phase 1)\n            _, audio_codes = self.parse_lm_output(codes_output_text)\n\n            codes_count = len(audio_codes.split('<|audio_code_')) - 1 if audio_codes else 0\n            logger.info(f\"Phase 2 completed in {phase2_time:.2f}s. Generated {codes_count} audio codes\")\n\n            total_time = phase1_time + phase2_time\n            return {\n                \"metadata\": metadata,\n                \"audio_codes\": audio_codes,\n                \"success\": True,\n                \"error\": None,\n                \"extra_outputs\": {\n                    \"time_costs\": {\n                        \"phase1_time\": phase1_time,\n                        \"phase2_time\": phase2_time,\n                        \"total_time\": total_time,\n                    },\n                    \"codes_count\": codes_count,\n                },\n            }\n\n    def build_formatted_prompt(self, caption: str, lyrics: str = \"\", is_negative_prompt: bool = False, generation_phase: str = \"cot\", negative_prompt: str = \"NO USER INPUT\") -> str:\n        \"\"\"\n        Build the chat-formatted prompt for 5Hz LM from caption/lyrics.\n        Raises a ValueError if the tokenizer is not initialized.\n\n        Args:\n            caption: Caption text\n            lyrics: Lyrics text\n            is_negative_prompt: If True, builds unconditional prompt for CFG\n            generation_phase: \"cot\" or \"codes\" - affects unconditional prompt format\n            negative_prompt: Negative prompt for CFG (used when is_negative_prompt=True)\n\n        Example:\n            prompt = handler.build_formatted_prompt(\"calm piano\", \"hello world\")\n        \"\"\"\n        if self.llm_tokenizer is None:\n            raise ValueError(\"LLM tokenizer is not initialized. Call initialize() first.\")\n\n        if is_negative_prompt:\n            # Unconditional prompt for CFG\n            # Check if user provided a meaningful negative prompt (not the default)\n            has_negative_prompt = self._has_meaningful_negative_prompt(negative_prompt)\n\n            if generation_phase == \"cot\":\n                # CoT phase unconditional prompt\n                if has_negative_prompt:\n                    # If negative prompt provided, use it as caption\n                    prompt = f\"# Caption\\n{negative_prompt}\\n\\n# Lyric\\n{lyrics}\\n\"\n                else:\n                    # No negative prompt: remove caption, keep only lyrics\n                    prompt = f\"# Lyric\\n{lyrics}\\n\"\n            else:\n                # Codes phase: will be handled by build_formatted_prompt_with_cot\n                # For backward compatibility, use simple caption as before\n                prompt = caption\n        else:\n            # Conditional prompt: include both caption and lyrics\n            prompt = f\"# Caption\\n{caption}\\n\\n# Lyric\\n{lyrics}\\n\"\n\n        return self.llm_tokenizer.apply_chat_template(\n            [\n                {\"role\": \"system\", \"content\": f\"# Instruction\\n{DEFAULT_LM_INSTRUCTION}\\n\\n\"},\n                {\"role\": \"user\", \"content\": prompt},\n            ],\n            tokenize=False,\n            add_generation_prompt=True,\n        )\n\n    def build_formatted_prompt_with_cot(self, caption: str, lyrics: str, cot_text: str, is_negative_prompt: bool = False, negative_prompt: str = \"NO USER INPUT\") -> str:\n        \"\"\"\n        Build the chat-formatted prompt for codes generation phase with pre-generated CoT.\n\n        Args:\n            caption: Caption text\n            lyrics: Lyrics text\n            cot_text: Pre-generated CoT text (e.g., \"<think>\\\\nbpm: 120\\\\n...\\\\n</think>\")\n            is_negative_prompt: If True, uses empty CoT for CFG unconditional prompt\n            negative_prompt: Negative prompt for CFG (used when is_negative_prompt=True)\n\n        Returns:\n            Formatted prompt string\n\n        Example:\n            cot = \"<think>\\\\nbpm: 120\\\\ncaption: calm piano\\\\n...\\\\n</think>\"\n            prompt = handler.build_formatted_prompt_with_cot(\"calm piano\", \"hello\", cot)\n        \"\"\"\n        if self.llm_tokenizer is None:\n            raise ValueError(\"LLM tokenizer is not initialized. Call initialize() first.\")\n\n        if is_negative_prompt:\n            # Unconditional prompt for codes phase\n            # Check if user provided a meaningful negative prompt\n            has_negative_prompt = self._has_meaningful_negative_prompt(negative_prompt)\n\n            # Use empty CoT for unconditional\n            cot_for_prompt = \"<think>\\n</think>\"\n\n            if has_negative_prompt:\n                # If negative prompt provided, use it as caption\n                caption_for_prompt = negative_prompt\n            else:\n                # No negative prompt: use original caption\n                caption_for_prompt = caption\n        else:\n            # Conditional prompt: use the full CoT and original caption\n            cot_for_prompt = cot_text\n            caption_for_prompt = caption\n\n        # Build user prompt with caption and lyrics ONLY (no COT)\n        # COT should be in the assistant's message, not user's\n        user_prompt = f\"# Caption\\n{caption_for_prompt}\\n\\n# Lyric\\n{lyrics}\\n\"\n\n        # Build the chat with assistant message containing the COT\n        # The model will continue generation after the COT\n        formatted = self.llm_tokenizer.apply_chat_template(\n            [\n                {\"role\": \"system\", \"content\": f\"# Instruction\\n{DEFAULT_LM_INSTRUCTION}\\n\\n\"},\n                {\"role\": \"user\", \"content\": user_prompt},\n                {\"role\": \"assistant\", \"content\": cot_for_prompt},\n            ],\n            tokenize=False,\n            add_generation_prompt=False,  # Don't add generation prompt, COT is already in assistant\n        )\n\n        # Add a newline after </think> so model generates audio codes on next line\n        if not formatted.endswith('\\n'):\n            formatted += '\\n'\n\n        return formatted\n\n    def build_formatted_prompt_for_understanding(\n        self,\n        audio_codes: str,\n        is_negative_prompt: bool = False,\n        negative_prompt: str = \"NO USER INPUT\"\n    ) -> str:\n        \"\"\"\n        Build the chat-formatted prompt for audio understanding from codes.\n\n        This is the reverse of generation: given audio codes, generate metadata and lyrics.\n\n        Args:\n            audio_codes: Audio code string (e.g., \"<|audio_code_123|><|audio_code_456|>...\")\n            is_negative_prompt: If True, builds unconditional prompt for CFG\n            negative_prompt: Negative prompt for CFG (used when is_negative_prompt=True)\n\n        Returns:\n            Formatted prompt string\n\n        Example:\n            codes = \"<|audio_code_18953|><|audio_code_13833|>...\"\n            prompt = handler.build_formatted_prompt_for_understanding(codes)\n        \"\"\"\n        if self.llm_tokenizer is None:\n            raise ValueError(\"LLM tokenizer is not initialized. Call initialize() first.\")\n\n        # For understanding task, user provides audio codes\n        # Unconditional prompt uses negative_prompt or empty string\n        if is_negative_prompt:\n            user_content = negative_prompt if negative_prompt and negative_prompt.strip() else \"\"\n        else:\n            user_content = audio_codes\n\n        return self.llm_tokenizer.apply_chat_template(\n            [\n                {\n                    \"role\": \"system\",\n                    \"content\": f\"# Instruction\\n{DEFAULT_LM_UNDERSTAND_INSTRUCTION}\\n\\n\"\n                },\n                {\n                    \"role\": \"user\",\n                    \"content\": user_content\n                },\n            ],\n            tokenize=False,\n            add_generation_prompt=True,\n        )\n\n    def understand_audio_from_codes(\n        self,\n        audio_codes: str,\n        temperature: float = 0.3,\n        top_k: Optional[int] = None,\n        top_p: Optional[float] = None,\n        repetition_penalty: float = 1.0,\n        use_constrained_decoding: bool = True,\n        constrained_decoding_debug: bool = False,\n    ) -> Tuple[Dict[str, Any], str]:\n        \"\"\"\n        Understand audio codes and generate metadata + lyrics.\n\n        This is the reverse of the normal generation flow:\n        - Input: Audio codes\n        - Output: Metadata (bpm, caption, duration, etc.) + Lyrics\n\n        Note: cfg_scale and negative_prompt are not supported in understand mode.\n\n        Args:\n            audio_codes: String of audio code tokens (e.g., \"<|audio_code_123|><|audio_code_456|>...\")\n            temperature: Sampling temperature for generation\n            top_k: Top-K sampling (None = disabled)\n            top_p: Top-P (nucleus) sampling (None = disabled)\n            repetition_penalty: Repetition penalty (1.0 = no penalty)\n            use_constrained_decoding: Whether to use FSM-based constrained decoding for metadata\n            constrained_decoding_debug: Whether to enable debug logging for constrained decoding\n\n        Returns:\n            Tuple of (metadata_dict, status_message)\n            metadata_dict contains:\n                - bpm: int or str\n                - caption: str\n                - duration: int or str\n                - keyscale: str\n                - language: str\n                - timesignature: str\n                - lyrics: str (extracted from output after </think>)\n\n        Example:\n            codes = \"<|audio_code_18953|><|audio_code_13833|>...\"\n            metadata, status = handler.understand_audio_from_codes(codes)\n            print(metadata['caption'])  # \"A cinematic orchestral piece...\"\n            print(metadata['lyrics'])   # \"[Intro: ...]\\\\n...\"\n        \"\"\"\n        if not getattr(self, \"llm_initialized\", False):\n            return {}, \"❌ 5Hz LM not initialized. Please initialize it first.\"\n\n        if not audio_codes or not audio_codes.strip():\n            return {}, \"❌ No audio codes provided. Please paste audio codes first.\"\n\n        logger.info(f\"Understanding audio codes (length: {len(audio_codes)} chars)\")\n\n        # Build formatted prompt for understanding\n        formatted_prompt = self.build_formatted_prompt_for_understanding(audio_codes)\n        print(f\"formatted_prompt: {formatted_prompt}\")\n        # Generate using constrained decoding (understand phase)\n        # We want to generate metadata first (CoT), then lyrics (natural text)\n        # Note: cfg_scale and negative_prompt are not used in understand mode\n        output_text, status = self.generate_from_formatted_prompt(\n            formatted_prompt=formatted_prompt,\n            cfg={\n                \"temperature\": temperature,\n                \"top_k\": top_k,\n                \"top_p\": top_p,\n                \"repetition_penalty\": repetition_penalty,\n                \"target_duration\": None,  # No duration constraint for understanding\n                \"user_metadata\": None,  # No user metadata injection\n                \"skip_caption\": False,  # Generate caption\n                \"skip_language\": False,  # Generate language\n                \"skip_genres\": False,  # Generate genres\n                \"generation_phase\": \"understand\",  # Understanding phase: generate CoT metadata, then free-form lyrics\n                # Context for building unconditional prompt\n                \"caption\": \"\",\n                \"lyrics\": \"\",\n            },\n            use_constrained_decoding=use_constrained_decoding,\n            constrained_decoding_debug=constrained_decoding_debug,\n            stop_at_reasoning=False,  # Continue after </think> to generate lyrics\n        )\n\n        if not output_text:\n            return {}, status\n\n        # Parse metadata and extract lyrics\n        metadata, _ = self.parse_lm_output(output_text)\n\n        # Extract lyrics section (everything after </think>)\n        lyrics = self._extract_lyrics_from_output(output_text)\n        if lyrics:\n            metadata['lyrics'] = lyrics\n\n        logger.info(f\"Understanding completed. Generated {len(metadata)} metadata fields\")\n        if constrained_decoding_debug:\n            logger.debug(f\"Generated metadata: {list(metadata.keys())}\")\n            logger.debug(f\"Output text preview: {output_text[:200]}...\")\n\n        status_msg = f\"✅ Understanding completed successfully\\nGenerated fields: {', '.join(metadata.keys())}\"\n        return metadata, status_msg\n\n    def _extract_lyrics_from_output(self, output_text: str) -> str:\n        \"\"\"\n        Extract lyrics section from LLM output.\n\n        The lyrics appear after the </think> tag and typically start with \"# Lyric\"\n        or directly with lyric content.\n\n        Args:\n            output_text: Full LLM output text\n\n        Returns:\n            Extracted lyrics string, or empty string if no lyrics found\n        \"\"\"\n        import re\n\n        # Find the </think> tag\n        think_end_pattern = r'</think>'\n        match = re.search(think_end_pattern, output_text)\n\n        if not match:\n            # No </think> tag found, no lyrics\n            return \"\"\n\n        # Extract everything after </think>\n        after_think = output_text[match.end():].strip()\n\n        if not after_think:\n            return \"\"\n\n        # Remove \"# Lyric\" header if present\n        lyric_header_pattern = r'^#\\s*Lyri[c|cs]?\\s*\\n'\n        after_think = re.sub(lyric_header_pattern, '', after_think, flags=re.IGNORECASE)\n\n        # Remove <|im_end|> tag at the end if present\n        after_think = re.sub(r'<\\|im_end\\|>\\s*$', '', after_think)\n\n        return after_think.strip()\n\n    def build_formatted_prompt_for_inspiration(\n        self,\n        query: str,\n        instrumental: bool = False,\n        is_negative_prompt: bool = False,\n        negative_prompt: str = \"NO USER INPUT\"\n    ) -> str:\n        \"\"\"\n        Build the chat-formatted prompt for inspiration/simple mode.\n\n        This generates a complete sample (caption, lyrics, metadata) from a user's\n        natural language music description query.\n\n        Args:\n            query: User's natural language music description\n            instrumental: Whether to generate instrumental music (no vocals)\n            is_negative_prompt: If True, builds unconditional prompt for CFG\n            negative_prompt: Negative prompt for CFG (used when is_negative_prompt=True)\n\n        Returns:\n            Formatted prompt string\n\n        Example:\n            query = \"a soft Bengali love song for a quiet evening\"\n            prompt = handler.build_formatted_prompt_for_inspiration(query, instrumental=False)\n        \"\"\"\n        if self.llm_tokenizer is None:\n            raise ValueError(\"LLM tokenizer is not initialized. Call initialize() first.\")\n\n        # Build user content with query and instrumental flag\n        instrumental_str = \"true\" if instrumental else \"false\"\n\n        if is_negative_prompt:\n            # For CFG unconditional prompt\n            user_content = negative_prompt if negative_prompt and negative_prompt.strip() else \"\"\n        else:\n            # Normal prompt: query + instrumental flag\n            user_content = f\"{query}\\n\\ninstrumental: {instrumental_str}\"\n\n        return self.llm_tokenizer.apply_chat_template(\n            [\n                {\n                    \"role\": \"system\",\n                    \"content\": f\"# Instruction\\n{DEFAULT_LM_INSPIRED_INSTRUCTION}\\n\\n\"\n                },\n                {\n                    \"role\": \"user\",\n                    \"content\": user_content\n                },\n            ],\n            tokenize=False,\n            add_generation_prompt=True,\n        )\n\n    def create_sample_from_query(\n        self,\n        query: str,\n        instrumental: bool = False,\n        vocal_language: Optional[str] = None,\n        temperature: float = 0.85,\n        top_k: Optional[int] = None,\n        top_p: Optional[float] = None,\n        repetition_penalty: float = 1.0,\n        use_constrained_decoding: bool = True,\n        constrained_decoding_debug: bool = False,\n    ) -> Tuple[Dict[str, Any], str]:\n        \"\"\"\n        Create a complete music sample from a user's natural language query.\n\n        This is the \"Simple Mode\" / \"Inspiration Mode\" feature that generates:\n        - Metadata (bpm, caption, duration, keyscale, language, timesignature)\n        - Lyrics (unless instrumental=True)\n\n        Args:\n            query: User's natural language music description\n            instrumental: Whether to generate instrumental music (no vocals)\n            vocal_language: Allowed vocal language for constrained decoding (e.g., \"en\", \"zh\").\n                           If provided and not \"unknown\", it will be used.\n            temperature: Sampling temperature for generation (0.0-2.0)\n            top_k: Top-K sampling (None = disabled)\n            top_p: Top-P (nucleus) sampling (None = disabled)\n            repetition_penalty: Repetition penalty (1.0 = no penalty)\n            use_constrained_decoding: Whether to use FSM-based constrained decoding\n            constrained_decoding_debug: Whether to enable debug logging\n\n        Returns:\n            Tuple of (metadata_dict, status_message)\n            metadata_dict contains:\n                - bpm: int or str\n                - caption: str\n                - duration: int or str\n                - keyscale: str\n                - language: str\n                - timesignature: str\n                - lyrics: str (extracted from output after </think>)\n                - instrumental: bool (echoed back)\n\n        Example:\n            query = \"a soft Bengali love song for a quiet evening\"\n            metadata, status = handler.create_sample_from_query(query, instrumental=False, vocal_language=\"bn\")\n            print(metadata['caption'])  # \"A gentle romantic acoustic pop ballad...\"\n            print(metadata['lyrics'])   # \"[Intro: ...]\\\\n...\"\n        \"\"\"\n        if not getattr(self, \"llm_initialized\", False):\n            return {}, \"❌ 5Hz LM not initialized. Please initialize it first.\"\n\n        if not query or not query.strip():\n            query = \"NO USER INPUT\"\n\n        logger.info(f\"Creating sample from query: {query[:100]}... (instrumental={instrumental}, vocal_language={vocal_language})\")\n\n        # Build formatted prompt for inspiration\n        formatted_prompt = self.build_formatted_prompt_for_inspiration(\n            query=query,\n            instrumental=instrumental,\n        )\n        logger.debug(f\"Formatted prompt for inspiration: {formatted_prompt}\")\n\n        # Build user_metadata if vocal_language is specified and is not \"unknown\"\n        user_metadata = None\n        skip_language = False\n        if vocal_language and vocal_language.strip() and vocal_language.strip().lower() != \"unknown\":\n            # Use the specified language for constrained decoding\n            user_metadata = {\"language\": vocal_language.strip()}\n            # skip_language = True  # Skip language generation since we're injecting it\n            logger.info(f\"Using user-specified language: {vocal_language.strip()}\")\n\n        # Generate using constrained decoding (inspiration phase)\n        # Similar to understand mode - generate metadata first (CoT), then lyrics\n        # Note: cfg_scale and negative_prompt are not used in create_sample mode\n        output_text, status = self.generate_from_formatted_prompt(\n            formatted_prompt=formatted_prompt,\n            cfg={\n                \"temperature\": temperature,\n                \"top_k\": top_k,\n                \"top_p\": top_p,\n                \"repetition_penalty\": repetition_penalty,\n                \"target_duration\": None,  # No duration constraint\n                \"user_metadata\": user_metadata,  # Inject language if specified\n                \"skip_caption\": False,  # Generate caption\n                \"skip_language\": False,\n                \"skip_genres\": False,  # Generate genres\n                \"generation_phase\": \"understand\",  # Use understand phase for metadata + free-form lyrics\n                \"caption\": \"\",\n                \"lyrics\": \"\",\n            },\n            use_constrained_decoding=use_constrained_decoding,\n            constrained_decoding_debug=constrained_decoding_debug,\n            stop_at_reasoning=False,  # Continue after </think> to generate lyrics\n        )\n\n        if not output_text:\n            return {}, status\n\n        # Parse metadata and extract lyrics\n        metadata, _ = self.parse_lm_output(output_text)\n\n        # Extract lyrics section (everything after </think>)\n        lyrics = self._extract_lyrics_from_output(output_text)\n        if lyrics:\n            metadata['lyrics'] = lyrics\n        elif instrumental:\n            # For instrumental, set empty lyrics or placeholder\n            metadata['lyrics'] = \"[Instrumental]\"\n\n        # Echo back the instrumental flag\n        metadata['instrumental'] = instrumental\n\n        logger.info(f\"Sample created successfully. Generated {metadata} fields\")\n        if constrained_decoding_debug:\n            logger.debug(f\"Generated metadata: {list(metadata.keys())}\")\n            logger.debug(f\"Output text preview: {output_text[:300]}...\")\n\n        status_msg = f\"✅ Sample created successfully\\nGenerated fields: {metadata}\"\n        return metadata, status_msg\n\n    def build_formatted_prompt_for_format(\n        self,\n        caption: str,\n        lyrics: str,\n        is_negative_prompt: bool = False,\n        negative_prompt: str = \"NO USER INPUT\"\n    ) -> str:\n        \"\"\"\n        Build the chat-formatted prompt for format/rewrite mode.\n\n        This formats user-provided caption and lyrics into a more detailed and specific\n        musical description with metadata.\n\n        Args:\n            caption: User's caption/description of the music\n            lyrics: User's lyrics\n            is_negative_prompt: If True, builds unconditional prompt for CFG\n            negative_prompt: Negative prompt for CFG (used when is_negative_prompt=True)\n\n        Returns:\n            Formatted prompt string\n\n        Example:\n            caption = \"Latin pop, reggaeton, flamenco-pop\"\n            lyrics = \"[Verse 1]\\\\nTengo un nudo...\"\n            prompt = handler.build_formatted_prompt_for_format(caption, lyrics)\n        \"\"\"\n        if self.llm_tokenizer is None:\n            raise ValueError(\"LLM tokenizer is not initialized. Call initialize() first.\")\n\n        if is_negative_prompt:\n            # For CFG unconditional prompt\n            user_content = negative_prompt if negative_prompt and negative_prompt.strip() else \"\"\n        else:\n            # Normal prompt: caption + lyrics\n            user_content = f\"# Caption\\n{caption}\\n\\n# Lyric\\n{lyrics}\"\n\n        return self.llm_tokenizer.apply_chat_template(\n            [\n                {\n                    \"role\": \"system\",\n                    \"content\": f\"# Instruction\\n{DEFAULT_LM_REWRITE_INSTRUCTION}\\n\\n\"\n                },\n                {\n                    \"role\": \"user\",\n                    \"content\": user_content\n                },\n            ],\n            tokenize=False,\n            add_generation_prompt=True,\n        )\n\n    def format_sample_from_input(\n        self,\n        caption: str,\n        lyrics: str,\n        user_metadata: Optional[Dict[str, Any]] = None,\n        temperature: float = 0.85,\n        top_k: Optional[int] = None,\n        top_p: Optional[float] = None,\n        repetition_penalty: float = 1.0,\n        use_constrained_decoding: bool = True,\n        constrained_decoding_debug: bool = False,\n    ) -> Tuple[Dict[str, Any], str]:\n        \"\"\"\n        Format user-provided caption and lyrics into structured music metadata.\n\n        This is the \"Format\" feature that takes user input and generates:\n        - Enhanced caption with detailed music description\n        - Metadata (bpm, duration, keyscale, language, timesignature)\n        - Formatted lyrics (preserved from input)\n\n        Note: cfg_scale and negative_prompt are not supported in format mode.\n\n        Args:\n            caption: User's caption/description (e.g., \"Latin pop, reggaeton\")\n            lyrics: User's lyrics with structure tags\n            user_metadata: Optional dict with user-provided metadata to constrain decoding.\n                          Supported keys: bpm, duration, keyscale, timesignature, language\n            temperature: Sampling temperature for generation (0.0-2.0)\n            top_k: Top-K sampling (None = disabled)\n            top_p: Top-P (nucleus) sampling (None = disabled)\n            repetition_penalty: Repetition penalty (1.0 = no penalty)\n            use_constrained_decoding: Whether to use FSM-based constrained decoding\n            constrained_decoding_debug: Whether to enable debug logging\n\n        Returns:\n            Tuple of (metadata_dict, status_message)\n            metadata_dict contains:\n                - bpm: int or str\n                - caption: str (enhanced)\n                - duration: int or str\n                - keyscale: str\n                - language: str\n                - timesignature: str\n                - lyrics: str (from input, possibly formatted)\n\n        Example:\n            caption = \"Latin pop, reggaeton, flamenco-pop\"\n            lyrics = \"[Verse 1]\\\\nTengo un nudo en la garganta...\"\n            metadata, status = handler.format_sample_from_input(caption, lyrics)\n            print(metadata['caption'])  # \"A dramatic and powerful Latin pop track...\"\n            print(metadata['bpm'])      # 100\n        \"\"\"\n        if not getattr(self, \"llm_initialized\", False):\n            return {}, \"❌ 5Hz LM not initialized. Please initialize it first.\"\n\n        if not caption or not caption.strip():\n            caption = \"NO USER INPUT\"\n        if not lyrics or not lyrics.strip():\n            lyrics = \"[Instrumental]\"\n\n        logger.info(f\"Formatting sample from input: caption={caption[:50]}..., lyrics length={len(lyrics)}\")\n\n        # Build formatted prompt for format task\n        formatted_prompt = self.build_formatted_prompt_for_format(\n            caption=caption,\n            lyrics=lyrics,\n        )\n        logger.debug(f\"Formatted prompt for format: {formatted_prompt}\")\n\n        # Build constrained decoding metadata from user_metadata\n        constrained_metadata = None\n        if user_metadata:\n            constrained_metadata = {}\n            if user_metadata.get('bpm') is not None:\n                try:\n                    bpm_val = int(user_metadata['bpm'])\n                    if bpm_val > 0:\n                        constrained_metadata['bpm'] = bpm_val\n                except (ValueError, TypeError):\n                    pass\n            if user_metadata.get('duration') is not None:\n                try:\n                    dur_val = int(user_metadata['duration'])\n                    if dur_val > 0:\n                        constrained_metadata['duration'] = dur_val\n                except (ValueError, TypeError):\n                    pass\n            if user_metadata.get('keyscale'):\n                constrained_metadata['keyscale'] = user_metadata['keyscale']\n            if user_metadata.get('timesignature'):\n                constrained_metadata['timesignature'] = user_metadata['timesignature']\n            if user_metadata.get('language'):\n                constrained_metadata['language'] = user_metadata['language']\n\n            # Only use if we have at least one field\n            if not constrained_metadata:\n                constrained_metadata = None\n            else:\n                logger.info(f\"Using user-provided metadata constraints: {constrained_metadata}\")\n\n        # Generate using constrained decoding (format phase)\n        # Similar to understand/inspiration mode - generate metadata first (CoT), then formatted lyrics\n        # Note: cfg_scale and negative_prompt are not used in format mode\n        output_text, status = self.generate_from_formatted_prompt(\n            formatted_prompt=formatted_prompt,\n            cfg={\n                \"temperature\": temperature,\n                \"top_k\": top_k,\n                \"top_p\": top_p,\n                \"repetition_penalty\": repetition_penalty,\n                \"target_duration\": None,  # No duration constraint for generation length\n                \"user_metadata\": constrained_metadata,  # Inject user-provided metadata\n                \"skip_caption\": False,  # Generate caption\n                \"skip_language\": constrained_metadata.get('language') is not None if constrained_metadata else False,\n                \"skip_genres\": False,  # Generate genres\n                \"generation_phase\": \"understand\",  # Use understand phase for metadata + free-form lyrics\n                \"caption\": \"\",\n                \"lyrics\": \"\",\n            },\n            use_constrained_decoding=use_constrained_decoding,\n            constrained_decoding_debug=constrained_decoding_debug,\n            stop_at_reasoning=False,  # Continue after </think> to get formatted lyrics\n        )\n\n        if not output_text:\n            return {}, status\n\n        # Parse metadata and extract lyrics\n        metadata, _ = self.parse_lm_output(output_text)\n\n        # Extract formatted lyrics section (everything after </think>)\n        formatted_lyrics = self._extract_lyrics_from_output(output_text)\n        if formatted_lyrics:\n            metadata['lyrics'] = formatted_lyrics\n        else:\n            # If no lyrics generated, keep original input\n            metadata['lyrics'] = lyrics\n\n        logger.info(f\"Format completed successfully. Generated {metadata} fields\")\n        if constrained_decoding_debug:\n            logger.debug(f\"Generated metadata: {list(metadata.keys())}\")\n            logger.debug(f\"Output text preview: {output_text[:300]}...\")\n\n        status_msg = f\"✅ Format completed successfully\\nGenerated fields: {', '.join(metadata.keys())}\"\n        return metadata, status_msg\n\n    def generate_from_formatted_prompt(\n        self,\n        formatted_prompt: str,\n        cfg: Optional[Dict[str, Any]] = None,\n        use_constrained_decoding: bool = True,\n        constrained_decoding_debug: bool = False,\n        stop_at_reasoning: bool = False,\n    ) -> Tuple[str, str]:\n        \"\"\"\n        Generate raw LM text output from a pre-built formatted prompt.\n\n        Args:\n            formatted_prompt: Prompt that is already formatted by `build_formatted_prompt`.\n            cfg: Optional dict supporting keys:\n                - temperature (float)\n                - cfg_scale (float)\n                - negative_prompt (str) used when cfg_scale > 1\n                - top_k (int), top_p (float), repetition_penalty (float)\n                - target_duration (float): Target duration in seconds for codes generation\n                - generation_phase (str): \"cot\" or \"codes\" for phase-aware CFG\n            use_constrained_decoding: Whether to use FSM-based constrained decoding\n            constrained_decoding_debug: Whether to enable debug logging for constrained decoding\n            stop_at_reasoning: If True, stop generation immediately after </think> tag (no audio codes)\n\n        Returns:\n            (output_text, status_message)\n\n        Example:\n            prompt = handler.build_formatted_prompt(caption, lyric)\n            text, status = handler.generate_from_formatted_prompt(prompt, {\"temperature\": 0.7})\n        \"\"\"\n        if not getattr(self, \"llm_initialized\", False):\n            return \"\", \"❌ 5Hz LM not initialized. Please initialize it first.\"\n        # Check that the appropriate model is loaded for the active backend\n        if self.llm_backend == \"mlx\":\n            if self._mlx_model is None or self.llm_tokenizer is None:\n                return \"\", \"❌ 5Hz LM is missing MLX model or tokenizer.\"\n        elif self.llm is None or self.llm_tokenizer is None:\n            return \"\", \"❌ 5Hz LM is missing model or tokenizer.\"\n\n        cfg = cfg or {}\n        temperature = cfg.get(\"temperature\", 0.6)\n        cfg_scale = cfg.get(\"cfg_scale\", 1.0)\n        negative_prompt = cfg.get(\"negative_prompt\", \"NO USER INPUT\")\n        top_k = cfg.get(\"top_k\")\n        top_p = cfg.get(\"top_p\")\n        repetition_penalty = cfg.get(\"repetition_penalty\", 1.0)\n        target_duration = cfg.get(\"target_duration\")\n        user_metadata = cfg.get(\"user_metadata\")  # User-provided metadata fields\n        skip_caption = cfg.get(\"skip_caption\", False)  # Skip caption generation in CoT\n        skip_language = cfg.get(\"skip_language\", False)  # Skip language generation in CoT\n        skip_genres = cfg.get(\"skip_genres\", False)  # Skip genres generation in CoT\n        generation_phase = cfg.get(\"generation_phase\", \"cot\")  # \"cot\" or \"codes\"\n        # Additional context for codes phase unconditional prompt building\n        caption = cfg.get(\"caption\", \"\")\n        lyrics = cfg.get(\"lyrics\", \"\")\n        cot_text = cfg.get(\"cot_text\", \"\")\n\n        try:\n            if self.llm_backend == \"vllm\":\n                output_text = self._run_vllm(\n                    formatted_prompts=formatted_prompt,\n                    temperature=temperature,\n                    cfg_scale=cfg_scale,\n                    negative_prompt=negative_prompt,\n                    top_k=top_k,\n                    top_p=top_p,\n                    repetition_penalty=repetition_penalty,\n                    use_constrained_decoding=use_constrained_decoding,\n                    constrained_decoding_debug=constrained_decoding_debug,\n                    target_duration=target_duration,\n                    user_metadata=user_metadata,\n                    stop_at_reasoning=stop_at_reasoning,\n                    skip_genres=skip_genres,\n                    skip_caption=skip_caption,\n                    skip_language=skip_language,\n                    generation_phase=generation_phase,\n                    caption=caption,\n                    lyrics=lyrics,\n                    cot_text=cot_text,\n                )\n                self._clear_accelerator_cache()\n                return output_text, f\"✅ Generated successfully (vllm) | length={len(output_text)}\"\n\n            elif self.llm_backend == \"mlx\":\n                # MLX backend (Apple Silicon native)\n                output_text = self._run_mlx(\n                    formatted_prompts=formatted_prompt,\n                    temperature=temperature,\n                    cfg_scale=cfg_scale,\n                    negative_prompt=negative_prompt,\n                    top_k=top_k,\n                    top_p=top_p,\n                    repetition_penalty=repetition_penalty,\n                    use_constrained_decoding=use_constrained_decoding,\n                    constrained_decoding_debug=constrained_decoding_debug,\n                    target_duration=target_duration,\n                    user_metadata=user_metadata,\n                    stop_at_reasoning=stop_at_reasoning,\n                    skip_genres=skip_genres,\n                    skip_caption=skip_caption,\n                    skip_language=skip_language,\n                    generation_phase=generation_phase,\n                    caption=caption,\n                    lyrics=lyrics,\n                    cot_text=cot_text,\n                )\n                self._clear_accelerator_cache()\n                return output_text, f\"✅ Generated successfully (mlx) | length={len(output_text)}\"\n\n            # PyTorch backend (fallback)\n            output_text = self._run_pt(\n                formatted_prompts=formatted_prompt,\n                temperature=temperature,\n                cfg_scale=cfg_scale,\n                negative_prompt=negative_prompt,\n                top_k=top_k,\n                top_p=top_p,\n                repetition_penalty=repetition_penalty,\n                use_constrained_decoding=use_constrained_decoding,\n                constrained_decoding_debug=constrained_decoding_debug,\n                target_duration=target_duration,\n                user_metadata=user_metadata,\n                stop_at_reasoning=stop_at_reasoning,\n                skip_genres=skip_genres,\n                skip_caption=skip_caption,\n                skip_language=skip_language,\n                generation_phase=generation_phase,\n                caption=caption,\n                lyrics=lyrics,\n                cot_text=cot_text,\n            )\n            self._clear_accelerator_cache()\n            return output_text, f\"✅ Generated successfully (pt) | length={len(output_text)}\"\n\n        except Exception as e:\n            # Log full traceback for debugging\n            import traceback\n            error_detail = traceback.format_exc()\n            logger.error(f\"Error in generate_from_formatted_prompt: {type(e).__name__}: {e}\\n{error_detail}\")\n            # Reset nano-vllm state on error to prevent stale context from causing\n            # subsequent CUDA illegal memory access errors\n            if self.llm_backend == \"vllm\":\n                try:\n                    from nanovllm.utils.context import reset_context\n                    reset_context()\n                except ImportError:\n                    pass\n                # Also reset the LLM scheduler to release allocated KV cache blocks\n                # This prevents 'deque index out of range' errors from block leaks\n                try:\n                    if hasattr(self.llm, 'reset'):\n                        self.llm.reset()\n                except Exception:\n                    pass  # Ignore errors during cleanup\n            # Clear accelerator cache to release any corrupted memory\n            gc.collect()\n            self._clear_accelerator_cache()\n            return \"\", f\"❌ Error generating from formatted prompt: {type(e).__name__}: {e or error_detail.splitlines()[-1]}\"\n\n    def _generate_with_constrained_decoding(\n        self,\n        input_ids: torch.Tensor,\n        attention_mask: Optional[torch.Tensor],\n        max_new_tokens: int,\n        temperature: float,\n        top_k: Optional[int],\n        top_p: Optional[float],\n        repetition_penalty: float,\n        pad_token_id: int,\n        streamer: Optional[BaseStreamer],\n        constrained_processor: Optional[MetadataConstrainedLogitsProcessor] = None,\n    ) -> torch.Tensor:\n        \"\"\"\n        Custom generation loop with constrained decoding support (non-CFG).\n        This allows us to call update_state() after each token generation.\n        \"\"\"\n        model = self.llm\n        device = self.device\n\n        # Initialize generated sequences\n        generated_ids = input_ids.clone()\n        if attention_mask is not None:\n            attn_mask = attention_mask.clone()\n        else:\n            attn_mask = torch.ones_like(input_ids)\n\n        # Prepare model inputs\n        model_kwargs = {'attention_mask': attn_mask}\n\n        # Past key values for KV cache\n        past_key_values = None\n        use_cache = hasattr(model, 'generation_config') and getattr(model.generation_config, 'use_cache', True)\n\n        # Get EOS token ID\n        eos_token_id = self.llm_tokenizer.eos_token_id\n        if eos_token_id is None:\n            eos_token_id = pad_token_id\n\n        # Build logits processor for repetition penalty\n        logits_processor = self._build_logits_processor(repetition_penalty)\n\n        with torch.inference_mode():\n            for step in tqdm(range(max_new_tokens), desc=\"LLM Constrained Decoding\", unit=\"token\", disable=self.disable_tqdm):\n                # Forward pass\n                outputs = self._forward_pass(model, generated_ids, model_kwargs, past_key_values, use_cache)\n\n                # Get logits for the last position\n                next_token_logits = outputs.logits[:, -1, :]  # [batch_size, vocab_size]\n\n                # Apply constrained processor FIRST (modifies logits based on FSM state)\n                if constrained_processor is not None:\n                    next_token_logits = constrained_processor(generated_ids, next_token_logits)\n\n                # Apply other logits processors (repetition penalty)\n                for processor in logits_processor:\n                    next_token_logits = processor(generated_ids, next_token_logits)\n\n                # Apply top-k and top-p filtering\n                next_token_logits = self._apply_top_k_filter(next_token_logits, top_k)\n                next_token_logits = self._apply_top_p_filter(next_token_logits, top_p)\n\n                # Apply temperature and sample\n                next_tokens = self._sample_tokens(next_token_logits, temperature)\n\n                # Update constrained processor state\n                self._update_constrained_processor_state(constrained_processor, next_tokens)\n\n                # Check for EOS token\n                should_stop = self._check_eos_token(next_tokens, eos_token_id, pad_token_id)\n\n                # Append token to sequence\n                next_tokens_unsqueezed = next_tokens.unsqueeze(1)\n                generated_ids = torch.cat([generated_ids, next_tokens_unsqueezed], dim=1)\n                attn_mask = torch.cat([attn_mask, torch.ones((input_ids.shape[0], 1), device=device, dtype=attn_mask.dtype)], dim=1)\n                model_kwargs['attention_mask'] = attn_mask\n\n                # Update KV cache\n                if use_cache and hasattr(outputs, 'past_key_values'):\n                    past_key_values = outputs.past_key_values\n\n                # Update streamer\n                if streamer is not None:\n                    streamer.put(next_tokens_unsqueezed)\n\n                if should_stop:\n                    break\n\n        if streamer is not None:\n            streamer.end()\n\n        # Explicitly free KV cache to reduce memory fragmentation\n        del past_key_values\n\n        return generated_ids\n\n    def _generate_with_cfg_custom(\n        self,\n        batch_input_ids: torch.Tensor,\n        batch_attention_mask: Optional[torch.Tensor],\n        max_new_tokens: int,\n        temperature: float,\n        cfg_scale: float,\n        top_k: Optional[int],\n        top_p: Optional[float],\n        repetition_penalty: float,\n        pad_token_id: int,\n        streamer: Optional[BaseStreamer],\n        constrained_processor: Optional[MetadataConstrainedLogitsProcessor] = None,\n    ) -> torch.Tensor:\n        \"\"\"\n        Custom CFG generation loop that:\n        1. Processes both conditional and unconditional sequences in parallel\n        2. Applies CFG formula to logits, restricted to valid tokens when in CODES_GENERATION\n        3. Samples tokens only for conditional sequences\n        4. Applies the same sampled tokens to both conditional and unconditional sequences\n        5. Optionally applies constrained decoding via FSM-based logits processor\n        6. Tracks per-sequence EOS state; stops only when all sequences have finished\n\n        Batch format: [cond_0..cond_n, uncond_0..uncond_n]\n        \"\"\"\n        from acestep.constrained_logits_processor import FSMState\n\n        model = self.llm\n        device = self.device\n        batch_size = batch_input_ids.shape[0] // 2  # Half are conditional, half are unconditional\n        cond_start_idx = 0\n        uncond_start_idx = batch_size\n\n        # Initialize generated sequences\n        generated_ids = batch_input_ids.clone()\n        if batch_attention_mask is not None:\n            attention_mask = batch_attention_mask.clone()\n        else:\n            attention_mask = torch.ones_like(batch_input_ids)\n\n        # Prepare model inputs\n        model_kwargs = {}\n        if batch_attention_mask is not None:\n            model_kwargs['attention_mask'] = attention_mask\n\n        # Past key values for KV cache (if model supports it)\n        past_key_values = None\n        use_cache = hasattr(model, 'generation_config') and getattr(model.generation_config, 'use_cache', True)\n\n        # Get EOS token ID for stopping condition\n        eos_token_id = self.llm_tokenizer.eos_token_id\n        if eos_token_id is None:\n            eos_token_id = pad_token_id\n\n        # Build logits processor for non-CFG operations (repetition penalty, top_k, top_p)\n        logits_processor = self._build_logits_processor(repetition_penalty)\n\n        # Per-sequence finished tracking (Fix 4: batch compaction - stop when ALL done)\n        seq_finished = torch.zeros(batch_size, dtype=torch.bool, device=device)\n\n        with torch.inference_mode():\n            for step in tqdm(range(max_new_tokens), desc=\"LLM CFG Generation\", unit=\"token\", disable=self.disable_tqdm):\n                # Forward pass for the entire batch (conditional + unconditional)\n                outputs = self._forward_pass(model, generated_ids, model_kwargs, past_key_values, use_cache)\n\n                # Get logits for the last position\n                next_token_logits = outputs.logits[:, -1, :]  # [batch_size*2, vocab_size]\n\n                # Split conditional and unconditional logits\n                cond_logits = next_token_logits[cond_start_idx:cond_start_idx+batch_size]\n                uncond_logits = next_token_logits[uncond_start_idx:uncond_start_idx+batch_size]\n\n                # Fixes 2, 3, 5: When in CODES_GENERATION state, apply the non-audio mask\n                # BEFORE CFG to avoid:\n                #  - wasted compute over the full 217k vocab (only ~64k audio tokens are valid)\n                #  - probability mass leakage from text tokens into the softmax denominator\n                # Extract valid token indices and compute CFG only on those to avoid\n                # NaN from (-inf - -inf) when both cond and uncond are masked.\n                if (\n                    constrained_processor is not None\n                    and constrained_processor.state == FSMState.CODES_GENERATION\n                    and constrained_processor.non_audio_code_mask is not None\n                ):\n                    non_audio_mask = constrained_processor.non_audio_code_mask\n                    if non_audio_mask.device != device or non_audio_mask.dtype != torch.float32:\n                        non_audio_mask = non_audio_mask.to(device=device, dtype=torch.float32)\n                    # valid_mask is True where tokens are allowed (mask value == 0)\n                    valid_mask = (non_audio_mask[0] == 0)  # [vocab_size]\n                    valid_indices = valid_mask.nonzero(as_tuple=False).squeeze(1)  # [num_valid]\n\n                    # CFG on valid tokens only; all others get -inf\n                    cond_valid = cond_logits[:, valid_indices].float()\n                    uncond_valid = uncond_logits[:, valid_indices].float()\n                    cfg_valid = uncond_valid + cfg_scale * (cond_valid - uncond_valid)\n\n                    cfg_logits = torch.full(\n                        (batch_size, cond_logits.shape[1]),\n                        float('-inf'),\n                        device=device,\n                        dtype=torch.float32,\n                    )\n                    cfg_logits[:, valid_indices] = cfg_valid\n                else:\n                    # Apply CFG formula: cfg_logits = uncond + cfg_scale * (cond - uncond)\n                    # Upcast to float32 to prevent overflow in float16 (CFG scaling can exceed fp16 range)\n                    cfg_logits = uncond_logits.float() + cfg_scale * (cond_logits.float() - uncond_logits.float())\n                    # Guard against NaN from (-inf) + scale * ((-inf) - (-inf)).\n                    # This can happen when repetition penalty drives a token to -inf in both\n                    # cond and uncond branches simultaneously.  Replace NaN with -inf so those\n                    # tokens are simply excluded from sampling.\n                    cfg_logits = torch.nan_to_num(cfg_logits, nan=float('-inf'))\n\n                # Apply constrained processor (modifies logits based on FSM state, e.g. duration constraint)\n                if constrained_processor is not None:\n                    current_input_ids = generated_ids[cond_start_idx:cond_start_idx+batch_size]\n                    cfg_logits = constrained_processor(current_input_ids, cfg_logits)\n\n                # Apply logits processors (repetition penalty, top-k, top-p)\n                # Get current input_ids for repetition penalty (only conditional part)\n                current_input_ids = generated_ids[cond_start_idx:cond_start_idx+batch_size]\n                for processor in logits_processor:\n                    cfg_logits = processor(current_input_ids, cfg_logits)\n\n                # Apply top-k and top-p filtering\n                cfg_logits = self._apply_top_k_filter(cfg_logits, top_k)\n                cfg_logits = self._apply_top_p_filter(cfg_logits, top_p)\n\n                # Force EOS for already-finished sequences so they don't alter constrained state\n                if seq_finished.any():\n                    for b in range(batch_size):\n                        if seq_finished[b]:\n                            cfg_logits[b, :] = float('-inf')\n                            cfg_logits[b, eos_token_id] = 0.0\n\n                # Apply temperature and sample\n                next_tokens = self._sample_tokens(cfg_logits, temperature)\n\n                # Update constrained processor state AFTER sampling\n                self._update_constrained_processor_state(constrained_processor, next_tokens)\n\n                # Per-sequence EOS tracking (Fix 4: stop when ALL sequences are done)\n                is_eos = next_tokens == eos_token_id\n                if pad_token_id is not None and pad_token_id != eos_token_id:\n                    is_eos = is_eos | (next_tokens == pad_token_id)\n                seq_finished = seq_finished | is_eos\n\n                # Apply the same sampled tokens to both conditional and unconditional sequences\n                next_tokens_unsqueezed = next_tokens.unsqueeze(1)\n                generated_ids = torch.cat([generated_ids, next_tokens_unsqueezed.repeat(2, 1)], dim=1)\n                attention_mask = torch.cat([attention_mask, torch.ones((batch_size*2, 1), device=device, dtype=attention_mask.dtype)], dim=1)\n                model_kwargs['attention_mask'] = attention_mask\n\n                # Update past_key_values for next iteration\n                if use_cache and hasattr(outputs, 'past_key_values'):\n                    past_key_values = outputs.past_key_values\n\n                # Update streamer\n                if streamer is not None:\n                    streamer.put(next_tokens_unsqueezed)  # Stream conditional tokens\n\n                # Stop generation only when ALL sequences have finished\n                if seq_finished.all():\n                    break\n\n        if streamer is not None:\n            streamer.end()\n\n        # Explicitly free KV cache to reduce memory fragmentation\n        del past_key_values\n\n        # Return the full batch (both conditional and unconditional)\n        # The caller will extract only the conditional output\n        return generated_ids\n\n    def parse_lm_output(self, output_text: str) -> Tuple[Dict[str, Any], str]:\n        \"\"\"\n        Parse LM output to extract metadata and audio codes.\n\n        Expected format:\n        <think>\n        bpm: 73\n        caption: A calm piano melody\n        duration: 273\n        genres: Chinese folk\n        keyscale: G major\n        language: en\n        timesignature: 4\n        </think>\n\n        <|audio_code_56535|><|audio_code_62918|>...\n\n        Returns:\n            Tuple of (metadata_dict, audio_codes_string)\n        \"\"\"\n        debug_output_text = output_text.split(\"</think>\")[0]\n        logger.debug(f\"Debug output text: {debug_output_text}\")\n        metadata = {}\n        audio_codes = \"\"\n\n        import re\n\n        # Extract audio codes - find all <|audio_code_XXX|> patterns\n        code_pattern = r'<\\|audio_code_\\d+\\|>'\n        code_matches = re.findall(code_pattern, output_text)\n        if code_matches:\n            audio_codes = \"\".join(code_matches)\n\n        # Extract metadata from reasoning section\n        # Try different reasoning tag patterns\n        reasoning_patterns = [\n            r'<think>(.*?)</think>',\n            r'<think>(.*?)</think>',\n            r'<reasoning>(.*?)</reasoning>',\n        ]\n\n        reasoning_text = None\n        for pattern in reasoning_patterns:\n            match = re.search(pattern, output_text, re.DOTALL)\n            if match:\n                reasoning_text = match.group(1).strip()\n                break\n\n        # If no reasoning tags found, try to parse metadata from the beginning of output\n        if not reasoning_text:\n            # Look for metadata lines before audio codes\n            lines_before_codes = output_text.split('<|audio_code_')[0] if '<|audio_code_' in output_text else output_text\n            reasoning_text = lines_before_codes.strip()\n\n        # Parse metadata fields with YAML multi-line value support\n        if reasoning_text:\n            lines = reasoning_text.split('\\n')\n            current_key = None\n            current_value_lines = []\n\n            def save_current_field():\n                \"\"\"Save the accumulated field value\"\"\"\n                nonlocal current_key, current_value_lines\n                if current_key and current_value_lines:\n                    # Join multi-line value\n                    value = '\\n'.join(current_value_lines)\n\n                    if current_key == 'bpm':\n                        try:\n                            metadata['bpm'] = int(value.strip())\n                        except:\n                            metadata['bpm'] = value.strip()\n                    elif current_key == 'caption':\n                        # Post-process caption to remove YAML multi-line formatting\n                        metadata['caption'] = MetadataConstrainedLogitsProcessor.postprocess_caption(value)\n                    elif current_key == 'duration':\n                        try:\n                            metadata['duration'] = int(value.strip())\n                        except:\n                            metadata['duration'] = value.strip()\n                    elif current_key == 'genres':\n                        metadata['genres'] = value.strip()\n                    elif current_key == 'keyscale':\n                        metadata['keyscale'] = value.strip()\n                    elif current_key == 'language':\n                        metadata['language'] = value.strip()\n                    elif current_key == 'timesignature':\n                        metadata['timesignature'] = value.strip()\n\n                current_key = None\n                current_value_lines = []\n\n            for line in lines:\n                # Skip lines starting with '<' (tags)\n                if line.strip().startswith('<'):\n                    continue\n\n                # Check if this is a new field (no leading spaces and contains ':')\n                if line and not line[0].isspace() and ':' in line:\n                    # Save previous field if any\n                    save_current_field()\n\n                    # Parse new field\n                    parts = line.split(':', 1)\n                    if len(parts) == 2:\n                        current_key = parts[0].strip().lower()\n                        # First line of value (after colon)\n                        first_value = parts[1]\n                        if first_value.strip():\n                            current_value_lines.append(first_value)\n                elif line.startswith(' ') or line.startswith('\\t'):\n                    # Continuation line (YAML multi-line value)\n                    if current_key:\n                        current_value_lines.append(line)\n\n            # Don't forget to save the last field\n            save_current_field()\n\n        return metadata, audio_codes\n\n    # =========================================================================\n    # MLX Backend Methods (Apple Silicon native acceleration)\n    # =========================================================================\n\n    @staticmethod\n    def _is_mlx_available() -> bool:\n        \"\"\"Check if MLX framework is available (Apple Silicon).\n\n        Delegates to the cached ``mlx_available()`` helper to avoid\n        re-importing ``mlx.core`` when the native extension failed on\n        first load (which causes a fatal nanobind duplicate-enum crash).\n        \"\"\"\n        try:\n            from acestep.models.mlx import mlx_available\n            if not mlx_available():\n                return False\n            import mlx_lm\n            return True\n        except Exception:\n            return False\n\n    def _load_mlx_model(self, model_path: str) -> Tuple[bool, str]:\n        \"\"\"\n        Load the 5Hz LM model using mlx-lm for native Apple Silicon acceleration.\n\n        Args:\n            model_path: Path to the HuggingFace model directory\n\n        Returns:\n            Tuple of (success, status_message)\n        \"\"\"\n        try:\n            import mlx.core as mx\n            from mlx_lm.utils import load as mlx_load\n\n            logger.info(f\"Loading MLX model from {model_path}\")\n            start_time = time.time()\n\n            # Try standard mlx-lm load first\n            try:\n                self._mlx_model, _ = mlx_load(model_path)\n            except Exception as first_err:\n                # The ACE-Step 5Hz LM checkpoints store safetensors keys without\n                # the \"model.\" prefix (e.g. \"layers.0.xxx\" instead of\n                # \"model.layers.0.xxx\") which is what mlx-lm's Qwen3 model\n                # expects.  When the standard load fails we retry with the\n                # prefix remapped.\n                logger.info(\n                    f\"Standard MLX load failed ({first_err}), \"\n                    \"retrying with 'model.' prefix remapping...\"\n                )\n                import glob as _glob\n                from pathlib import Path\n                from mlx_lm.utils import load_model, load_config, load_tokenizer, _get_classes\n\n                _model_path = Path(model_path)\n                config = load_config(_model_path)\n\n                # Load raw weights from safetensors\n                weight_files = _glob.glob(str(_model_path / \"model*.safetensors\"))\n                if not weight_files:\n                    raise FileNotFoundError(f\"No safetensors found in {model_path}\") from first_err\n\n                weights = {}\n                for wf in weight_files:\n                    weights.update(mx.load(wf))\n\n                # Check if keys need \"model.\" prefix by inspecting first key\n                sample_key = next(iter(weights))\n                if not sample_key.startswith(\"model.\"):\n                    logger.info(\"Adding 'model.' prefix to weight keys for MLX compatibility\")\n                    weights = {f\"model.{k}\": v for k, v in weights.items()}\n\n                # Build model from config\n                model_class, model_args_class = _get_classes(config=config)\n                model_args = model_args_class.from_dict(config)\n                model = model_class(model_args)\n\n                if hasattr(model, \"sanitize\"):\n                    weights = model.sanitize(weights)\n\n                model.load_weights(list(weights.items()), strict=True)\n                mx.eval(model.parameters())\n                model.eval()\n                self._mlx_model = model\n\n            mx.eval(self._mlx_model.parameters())\n            # Store model path for get_hf_model_for_scoring\n            self._mlx_model_path = model_path\n\n            load_time = time.time() - start_time\n            logger.info(f\"MLX model loaded successfully in {load_time:.2f}s\")\n\n            self.llm_backend = \"mlx\"\n            self.llm_initialized = True\n            status_msg = (\n                f\"✅ 5Hz LM initialized successfully\\n\"\n                f\"Model: {model_path}\\n\"\n                f\"Backend: MLX (Apple Silicon native)\\n\"\n                f\"Device: Apple Silicon GPU\"\n            )\n            return True, status_msg\n\n        except Exception as e:\n            import traceback\n            error_detail = traceback.format_exc()\n            logger.warning(f\"Failed to load MLX model: {e}\\n{error_detail}\")\n            return False, f\"❌ MLX load failed: {str(e)}\"\n\n    def _make_mlx_cache(self):\n        \"\"\"Create a KV cache for the MLX model.\"\"\"\n        import mlx.core as mx\n        try:\n            from mlx_lm.models.cache import make_prompt_cache\n            return make_prompt_cache(self._mlx_model)\n        except (ImportError, AttributeError):\n            # Fallback: try model's own cache creation\n            try:\n                return self._mlx_model.make_cache()\n            except AttributeError:\n                raise RuntimeError(\n                    \"Cannot create MLX KV cache. Ensure mlx-lm version >= 0.20.0\"\n                )\n\n    def _run_mlx_batch_native(\n        self,\n        formatted_prompt: str,\n        batch_size: int,\n        temperature: float,\n        cfg_scale: float,\n        negative_prompt: str,\n        top_k: Optional[int],\n        top_p: Optional[float],\n        repetition_penalty: float,\n        use_constrained_decoding: bool,\n        constrained_decoding_debug: bool,\n        target_duration: Optional[float],\n        caption: str,\n        lyrics: str,\n        cot_text: str,\n        seeds: Optional[List[int]] = None,\n    ) -> List[str]:\n        \"\"\"\n        Optimized native MLX batch generation for codes phase.\n\n        Strategy: shared prefill + clone cache + interleaved B=1 decode.\n\n        On Apple Silicon, LLM decode is memory-bandwidth-bound. Batching the\n        forward pass (B>1) doubles the KV cache reads per step and actually\n        *slows down* throughput for 1.7B-class models. Instead, we:\n\n        1. Prefill ONCE with B=1, then clone the KV caches for each item.\n           This saves ~50% of prefill time vs sequential generation.\n        2. Interleave B=1 forward passes across items within each step.\n           Each item gets its own cache, constrained state, and seed.\n\n        This achieves ~1.25x speedup over fully sequential generation while\n        maintaining the full ~44 tok/s per-item decode speed.\n\n        Only used for codes generation phase where all prompts are identical.\n        Raises on failure so the caller can fall back to sequential mode.\n        \"\"\"\n        import mlx.core as mx\n        import numpy as np\n        from mlx_lm.models.cache import make_prompt_cache, KVCache\n        from mlx_lm.sample_utils import make_sampler\n\n        # ---- Tokenize (single prompt, shared by all items) ----\n        inputs = self.llm_tokenizer(\n            formatted_prompt,\n            return_tensors=\"np\",\n            padding=False,\n            truncation=True,\n        )\n        input_ids_np = inputs[\"input_ids\"]  # [1, seq_len]\n        prompt_length = input_ids_np.shape[1]\n        prompt = mx.array(input_ids_np[0])  # 1D [seq_len]\n\n        # ---- Calculate max_new_tokens ----\n        # Batch native is always codes phase\n        max_new_tokens = self._compute_max_new_tokens(\n            target_duration=target_duration,\n            generation_phase=\"codes\",\n        )\n\n        # ---- EOS tokens ----\n        eos_token_id = self.llm_tokenizer.eos_token_id\n        pad_token_id = self.llm_tokenizer.pad_token_id or eos_token_id\n\n        # ---- Native MLX sampler ----\n        sampler = make_sampler(\n            temp=temperature if temperature > 0 else 0.0,\n            top_p=top_p if top_p is not None and 0.0 < top_p < 1.0 else 1.0,\n            top_k=top_k if top_k is not None and top_k > 0 else 0,\n        )\n\n        # ---- Repetition penalty config ----\n        use_rep_penalty = repetition_penalty != 1.0\n        rep_penalty_val = float(repetition_penalty)\n\n        use_cfg = cfg_scale > 1.0\n        cfg_label = \"CFG \" if use_cfg else \"\"\n        prefill_step_size = 2048\n\n        # ---- Pre-convert constrained masks to MLX (shared by all items) ----\n        from acestep.constrained_logits_processor import FSMState\n        _mlx_non_audio_mask = None\n        _mlx_eos_id = None\n        _target_codes = None\n\n        # Setup a temporary constrained processor to get masks\n        constrained_processor = self._setup_constrained_processor(\n            use_constrained_decoding=use_constrained_decoding,\n            constrained_decoding_debug=constrained_decoding_debug,\n            target_duration=target_duration,\n            user_metadata=None,\n            stop_at_reasoning=False,\n            skip_genres=True,\n            skip_caption=True,\n            skip_language=True,\n            generation_phase=\"codes\",\n            is_batch=True,\n        )\n\n        if constrained_processor is not None:\n            if hasattr(constrained_processor, 'non_audio_code_mask') and constrained_processor.non_audio_code_mask is not None:\n                _mlx_non_audio_mask = mx.array(constrained_processor.non_audio_code_mask.float().numpy())\n            if hasattr(constrained_processor, 'eos_token_id') and constrained_processor.eos_token_id is not None:\n                _mlx_eos_id = int(constrained_processor.eos_token_id)\n            if hasattr(constrained_processor, 'target_codes'):\n                _target_codes = constrained_processor.target_codes\n\n            # Pre-transition FSM to CODES_GENERATION\n            if constrained_processor.state == FSMState.THINK_TAG:\n                if \"</think>\" in formatted_prompt:\n                    constrained_processor.state = FSMState.CODES_GENERATION\n                    constrained_processor.codes_count = 0\n\n        # ===== SHARED PREFILL PHASE (done ONCE for all batch items) =====\n        prefill_start = time.time()\n        logger.info(f\"MLX batch native: prefilling once for {batch_size} items (shared prompt)\")\n\n        def _clone_cache_list(cache_list):\n            \"\"\"Deep-copy a list of KVCache objects so each batch item gets independent state.\"\"\"\n            cloned = []\n            for c in cache_list:\n                new_c = KVCache()\n                if c.keys is not None:\n                    # mx.array(...) on an existing array creates a copy\n                    new_c.keys = mx.array(c.keys)\n                    new_c.values = mx.array(c.values)\n                    new_c.offset = c.offset\n                cloned.append(new_c)\n            return cloned\n\n        if use_cfg:\n            # Build unconditional prompt\n            uncond_text = self._build_unconditional_prompt(\n                caption=caption, lyrics=lyrics, cot_text=cot_text,\n                negative_prompt=negative_prompt, generation_phase=\"codes\", is_batch=True,\n            )\n            uncond_inputs = self.llm_tokenizer(\n                uncond_text, return_tensors=\"np\", padding=False, truncation=True,\n            )\n            uncond_prompt = mx.array(uncond_inputs[\"input_ids\"][0])\n            uncond_length = len(uncond_prompt)\n\n            # Create single KV caches and prefill once\n            base_cond_cache = make_prompt_cache(self._mlx_model)\n            base_uncond_cache = make_prompt_cache(self._mlx_model)\n\n            # Chunked prefill for conditional prompt\n            cond_remaining = prompt\n            while len(cond_remaining) > 1:\n                chunk_size = min(prefill_step_size, len(cond_remaining) - 1)\n                self._mlx_model(cond_remaining[:chunk_size][None], cache=base_cond_cache)\n                mx.eval([c.state for c in base_cond_cache])\n                cond_remaining = cond_remaining[chunk_size:]\n                mx.clear_cache()\n\n            # Chunked prefill for unconditional prompt\n            uncond_remaining = uncond_prompt\n            while len(uncond_remaining) > 1:\n                chunk_size = min(prefill_step_size, len(uncond_remaining) - 1)\n                self._mlx_model(uncond_remaining[:chunk_size][None], cache=base_uncond_cache)\n                mx.eval([c.state for c in base_uncond_cache])\n                uncond_remaining = uncond_remaining[chunk_size:]\n                mx.clear_cache()\n\n            # Process last tokens of both prompts to get initial logits\n            base_cond_logits = self._mlx_model(cond_remaining[None], cache=base_cond_cache)\n            base_uncond_logits = self._mlx_model(uncond_remaining[None], cache=base_uncond_cache)\n            mx.eval(base_cond_logits, base_uncond_logits)\n\n            # Clone caches for each batch item (item 0 reuses the base cache)\n            item_cond_caches = [base_cond_cache]\n            item_uncond_caches = [base_uncond_cache]\n            for i in range(1, batch_size):\n                item_cond_caches.append(_clone_cache_list(base_cond_cache))\n                item_uncond_caches.append(_clone_cache_list(base_uncond_cache))\n            # Eval cloned caches\n            for i in range(1, batch_size):\n                mx.eval(*[c.keys for c in item_cond_caches[i] if c.keys is not None])\n                mx.eval(*[c.keys for c in item_uncond_caches[i] if c.keys is not None])\n\n            # Initial logits for each item (same values, but we need separate references)\n            item_last_cond = [base_cond_logits[:, -1:, :]] * batch_size\n            item_last_uncond = [base_uncond_logits[:, -1:, :]] * batch_size\n\n            prefill_time = time.time() - prefill_start\n            total_prefill_tokens = prompt_length + uncond_length\n            prefill_tps = total_prefill_tokens / prefill_time if prefill_time > 0 else 0\n            logger.info(\n                f\"MLX batch native prefill: {total_prefill_tokens} tokens \"\n                f\"(cond={prompt_length}, uncond={uncond_length}) \"\n                f\"in {prefill_time:.2f}s ({prefill_tps:.1f} tok/s) \"\n                f\"[shared across {batch_size} items, saved {(batch_size-1)*total_prefill_tokens} redundant tokens]\"\n            )\n        else:\n            # Non-CFG mode\n            base_cache = make_prompt_cache(self._mlx_model)\n            remaining = prompt\n            while len(remaining) > 1:\n                chunk_size = min(prefill_step_size, len(remaining) - 1)\n                self._mlx_model(remaining[:chunk_size][None], cache=base_cache)\n                mx.eval([c.state for c in base_cache])\n                remaining = remaining[chunk_size:]\n                mx.clear_cache()\n\n            base_logits = self._mlx_model(remaining[None], cache=base_cache)\n            mx.eval(base_logits)\n\n            item_caches = [base_cache]\n            for i in range(1, batch_size):\n                item_caches.append(_clone_cache_list(base_cache))\n            for i in range(1, batch_size):\n                mx.eval(*[c.keys for c in item_caches[i] if c.keys is not None])\n\n            item_last_logits = [base_logits[:, -1:, :]] * batch_size\n\n            prefill_time = time.time() - prefill_start\n            prefill_tps = prompt_length / prefill_time if prefill_time > 0 else 0\n            logger.info(\n                f\"MLX batch native prefill: {prompt_length} tokens \"\n                f\"in {prefill_time:.2f}s ({prefill_tps:.1f} tok/s) \"\n                f\"[shared across {batch_size} items]\"\n            )\n\n        # ===== INTERLEAVED AUTOREGRESSIVE GENERATION LOOP =====\n        # Each item has independent: tokens, codes_count, finished flag, KV cache, random key\n        # But they share: model weights, masks, sampler\n        #\n        # Why interleaved B=1 instead of true batch B=N?\n        # On Apple Silicon, LLM decode is memory-bandwidth-bound.\n        # B=2 doubles KV cache reads per step, causing ~3x slowdown per step\n        # for 1.7B models. Interleaved B=1 keeps the full ~44 tok/s speed\n        # while still sharing the prefill computation.\n        base_token_ids = list(input_ids_np[0])\n        item_all_token_ids = [list(base_token_ids) for _ in range(batch_size)]\n        item_new_tokens = [[] for _ in range(batch_size)]\n        item_codes_count = [0] * batch_size\n        item_finished = [False] * batch_size\n\n        # Pre-compute per-item seed bases (large primes to avoid correlation)\n        item_seed_bases = []\n        for i in range(batch_size):\n            if seeds and i < len(seeds):\n                item_seed_bases.append(seeds[i])\n            else:\n                item_seed_bases.append(42 + i * 1000003)\n\n        decode_start = time.time()\n        pbar = tqdm(total=max_new_tokens, desc=f\"MLX {cfg_label}Batch Gen (native, n={batch_size})\", unit=\"tok\")\n\n        for step in range(max_new_tokens):\n            # Check if all items are done\n            if all(item_finished):\n                break\n\n            # Process each active item (interleaved B=1 forward passes)\n            for i in range(batch_size):\n                if item_finished[i]:\n                    continue\n\n                # ---- Set deterministic per-item seed for this step ----\n                # This ensures reproducibility: item i at step s always uses the same seed\n                mx.random.seed(item_seed_bases[i] + step * 1000003)\n\n                # ---- Combine logits (CFG) ----\n                if use_cfg:\n                    step_logits = item_last_uncond[i] + cfg_scale * (item_last_cond[i] - item_last_uncond[i])\n                else:\n                    step_logits = item_last_logits[i]\n\n                step_logits = step_logits.reshape(1, -1)  # [1, vocab_size]\n\n                # ---- Repetition penalty ----\n                if use_rep_penalty and len(item_all_token_ids[i]) > 0:\n                    token_indices = mx.array(item_all_token_ids[i])\n                    selected = step_logits[:, token_indices]\n                    modified = mx.where(\n                        selected > 0,\n                        selected / rep_penalty_val,\n                        selected * rep_penalty_val,\n                    )\n                    step_logits[:, token_indices] = modified\n\n                # ---- Constrained decoding (native MLX fast path) ----\n                if _mlx_non_audio_mask is not None:\n                    step_logits = step_logits + _mlx_non_audio_mask\n                if _target_codes is not None and _mlx_eos_id is not None:\n                    if item_codes_count[i] < _target_codes:\n                        step_logits = mx.concatenate([\n                            step_logits[:, :_mlx_eos_id],\n                            mx.array([[float('-inf')]]),\n                            step_logits[:, _mlx_eos_id + 1:],\n                        ], axis=1)\n                    else:\n                        eos_val = step_logits[:, _mlx_eos_id:_mlx_eos_id + 1]\n                        step_logits = mx.full(step_logits.shape, float('-inf'))\n                        step_logits = mx.concatenate([\n                            step_logits[:, :_mlx_eos_id],\n                            eos_val,\n                            step_logits[:, _mlx_eos_id + 1:],\n                        ], axis=1)\n\n                # ---- Sample ----\n                logprobs = step_logits - mx.logsumexp(step_logits, keepdims=True)\n                token_arr = sampler(logprobs)\n                mx.eval(token_arr)\n                token_id = token_arr.item()\n\n                item_new_tokens[i].append(token_id)\n                item_all_token_ids[i].append(token_id)\n\n                # Update codes count\n                item_codes_count[i] += 1\n\n                # Check EOS\n                if token_id == eos_token_id:\n                    item_finished[i] = True\n                    continue\n                if pad_token_id is not None and pad_token_id != eos_token_id and token_id == pad_token_id:\n                    item_finished[i] = True\n                    continue\n\n                # ---- Next forward step (B=1 per item) ----\n                next_input = mx.array([[token_id]])\n                if use_cfg:\n                    cond_logits = self._mlx_model(next_input, cache=item_cond_caches[i])\n                    uncond_logits = self._mlx_model(next_input, cache=item_uncond_caches[i])\n                    item_last_cond[i] = cond_logits[:, -1:, :]\n                    item_last_uncond[i] = uncond_logits[:, -1:, :]\n                else:\n                    logits_out = self._mlx_model(next_input, cache=item_caches[i])\n                    item_last_logits[i] = logits_out[:, -1:, :]\n\n            pbar.update(1)\n\n            # Periodic memory cleanup\n            if step % 256 == 0 and step > 0:\n                mx.clear_cache()\n\n        pbar.close()\n\n        # ---- Log generation summary ----\n        decode_time = time.time() - decode_start\n        total_tokens = sum(len(t) for t in item_new_tokens)\n        avg_tokens = total_tokens / batch_size if batch_size > 0 else 0\n        decode_tps = total_tokens / decode_time if decode_time > 0 else 0\n        total_time = prefill_time + decode_time\n        logger.info(\n            f\"MLX batch native generation complete: {batch_size} items, \"\n            f\"{total_tokens} total tokens ({avg_tokens:.0f} avg) in {decode_time:.2f}s \"\n            f\"({decode_tps:.1f} tok/s) | prefill {prefill_time:.2f}s + decode {decode_time:.2f}s = {total_time:.2f}s total\"\n        )\n\n        # Decode each item's tokens\n        output_texts = []\n        for i in range(batch_size):\n            output_text = self.llm_tokenizer.decode(item_new_tokens[i], skip_special_tokens=False)\n            output_texts.append(output_text)\n\n        return output_texts\n\n    def _run_mlx_single_native(\n        self,\n        formatted_prompt: str,\n        temperature: float,\n        cfg_scale: float,\n        negative_prompt: str,\n        top_k: Optional[int],\n        top_p: Optional[float],\n        repetition_penalty: float,\n        use_constrained_decoding: bool,\n        constrained_decoding_debug: bool,\n        target_duration: Optional[float],\n        user_metadata: Optional[Dict[str, Optional[str]]],\n        stop_at_reasoning: bool,\n        skip_genres: bool,\n        skip_caption: bool,\n        skip_language: bool,\n        generation_phase: str,\n        caption: str,\n        lyrics: str,\n        cot_text: str,\n    ) -> str:\n        \"\"\"\n        Optimized native MLX generation using mlx-lm infrastructure.\n\n        Key improvements over the hybrid approach:\n        1. Native MLX sampling (temperature, top-k, top-p) via mlx-lm make_sampler\n           - Eliminates numpy/PyTorch round-trip for EVERY generated token\n        2. Native MLX repetition penalty (no per-step PyTorch conversion)\n        3. Chunked prefill for memory-efficient long prompt processing\n        4. Periodic memory cleanup (mx.clear_cache) matching mlx-lm patterns\n        5. Bridges to PyTorch ONLY for constrained decoding FSM when active\n\n        Raises on failure so the caller can fall back to the legacy hybrid method.\n        \"\"\"\n        import mlx.core as mx\n        import numpy as np\n        from mlx_lm.models.cache import make_prompt_cache\n        from mlx_lm.sample_utils import make_sampler\n\n        # ---- Tokenize ----\n        inputs = self.llm_tokenizer(\n            formatted_prompt,\n            return_tensors=\"np\",\n            padding=False,\n            truncation=True,\n        )\n        input_ids_np = inputs[\"input_ids\"]  # [1, seq_len]\n        prompt_length = input_ids_np.shape[1]\n        prompt = mx.array(input_ids_np[0])  # 1D [seq_len]\n\n        # ---- Setup constrained processor ----\n        constrained_processor = self._setup_constrained_processor(\n            use_constrained_decoding=use_constrained_decoding,\n            constrained_decoding_debug=constrained_decoding_debug,\n            target_duration=target_duration,\n            user_metadata=user_metadata,\n            stop_at_reasoning=stop_at_reasoning,\n            skip_genres=skip_genres,\n            skip_caption=skip_caption,\n            skip_language=skip_language,\n            generation_phase=generation_phase,\n            is_batch=False,\n        )\n\n        # ---- Calculate max_new_tokens ----\n        max_new_tokens = self._compute_max_new_tokens(\n            target_duration=target_duration,\n            generation_phase=generation_phase,\n        )\n\n        # ---- EOS tokens ----\n        eos_token_id = self.llm_tokenizer.eos_token_id\n        pad_token_id = self.llm_tokenizer.pad_token_id or eos_token_id\n\n        # ---- Native MLX sampler (replaces PyTorch top-k/top-p/temperature) ----\n        sampler = make_sampler(\n            temp=temperature if temperature > 0 else 0.0,\n            top_p=top_p if top_p is not None and 0.0 < top_p < 1.0 else 1.0,\n            top_k=top_k if top_k is not None and top_k > 0 else 0,\n        )\n\n        # ---- Repetition penalty config ----\n        use_rep_penalty = repetition_penalty != 1.0\n        rep_penalty_val = float(repetition_penalty)\n\n        use_cfg = cfg_scale > 1.0\n        cfg_label = \"CFG \" if use_cfg else \"\"\n        tqdm_desc = f\"MLX {cfg_label}Gen (native)\"\n        prefill_step_size = 2048\n\n        # ---- Pre-convert constrained processor masks to MLX (one-time) ----\n        # This enables native MLX fast-path for CODES_GENERATION state,\n        # eliminating the PyTorch bridge for 99%+ of Phase 2 tokens.\n        from acestep.constrained_logits_processor import FSMState\n        _mlx_non_audio_mask = None\n        _mlx_eos_id = None\n        _target_codes = None\n        _use_native_codes_path = False\n\n        if constrained_processor is not None:\n            # Pre-convert the non-audio-code mask to MLX (blocks everything except audio codes + EOS)\n            if hasattr(constrained_processor, 'non_audio_code_mask') and constrained_processor.non_audio_code_mask is not None:\n                _mlx_non_audio_mask = mx.array(constrained_processor.non_audio_code_mask.float().numpy())\n            if hasattr(constrained_processor, 'eos_token_id') and constrained_processor.eos_token_id is not None:\n                _mlx_eos_id = int(constrained_processor.eos_token_id)\n            if hasattr(constrained_processor, 'target_codes'):\n                _target_codes = constrained_processor.target_codes\n\n            # For codes phase, the prompt already contains </think>.\n            # Pre-transition FSM to CODES_GENERATION so the native fast path\n            # activates from the very first generated token.\n            if generation_phase == \"codes\" and constrained_processor.state == FSMState.THINK_TAG:\n                if \"</think>\" in formatted_prompt:\n                    constrained_processor.state = FSMState.CODES_GENERATION\n                    constrained_processor.codes_count = 0\n                    _use_native_codes_path = True\n                    logger.info(\"MLX native: pre-transitioned FSM to CODES_GENERATION (native fast path)\")\n\n        # ===== PREFILL PHASE =====\n        prefill_start = time.time()\n\n        if use_cfg:\n            # Build unconditional prompt\n            uncond_text = self._build_unconditional_prompt(\n                caption=caption,\n                lyrics=lyrics,\n                cot_text=cot_text,\n                negative_prompt=negative_prompt,\n                generation_phase=generation_phase,\n                is_batch=False,\n            )\n            uncond_inputs = self.llm_tokenizer(\n                uncond_text,\n                return_tensors=\"np\",\n                padding=False,\n                truncation=True,\n            )\n            uncond_prompt = mx.array(uncond_inputs[\"input_ids\"][0])\n            uncond_length = len(uncond_prompt)\n\n            # Create KV caches via mlx-lm infrastructure\n            cond_cache = make_prompt_cache(self._mlx_model)\n            uncond_cache = make_prompt_cache(self._mlx_model)\n\n            # Chunked prefill for conditional prompt\n            cond_remaining = prompt\n            while len(cond_remaining) > 1:\n                chunk_size = min(prefill_step_size, len(cond_remaining) - 1)\n                self._mlx_model(cond_remaining[:chunk_size][None], cache=cond_cache)\n                mx.eval([c.state for c in cond_cache])\n                cond_remaining = cond_remaining[chunk_size:]\n                mx.clear_cache()\n\n            # Chunked prefill for unconditional prompt\n            uncond_remaining = uncond_prompt\n            while len(uncond_remaining) > 1:\n                chunk_size = min(prefill_step_size, len(uncond_remaining) - 1)\n                self._mlx_model(uncond_remaining[:chunk_size][None], cache=uncond_cache)\n                mx.eval([c.state for c in uncond_cache])\n                uncond_remaining = uncond_remaining[chunk_size:]\n                mx.clear_cache()\n\n            # Process last tokens of both prompts\n            cond_logits = self._mlx_model(cond_remaining[None], cache=cond_cache)\n            uncond_logits = self._mlx_model(uncond_remaining[None], cache=uncond_cache)\n            mx.eval(cond_logits, uncond_logits)\n\n            last_cond = cond_logits[:, -1:, :]\n            last_uncond = uncond_logits[:, -1:, :]\n\n            prefill_time = time.time() - prefill_start\n            total_prefill_tokens = prompt_length + uncond_length\n            prefill_tps = total_prefill_tokens / prefill_time if prefill_time > 0 else 0\n            logger.info(\n                f\"MLX native prefill: {total_prefill_tokens} tokens \"\n                f\"(cond={prompt_length}, uncond={uncond_length}) \"\n                f\"in {prefill_time:.2f}s ({prefill_tps:.1f} tok/s)\"\n            )\n        else:\n            # Non-CFG: single cache\n            cache = make_prompt_cache(self._mlx_model)\n\n            # Chunked prefill\n            remaining = prompt\n            while len(remaining) > 1:\n                chunk_size = min(prefill_step_size, len(remaining) - 1)\n                self._mlx_model(remaining[:chunk_size][None], cache=cache)\n                mx.eval([c.state for c in cache])\n                remaining = remaining[chunk_size:]\n                mx.clear_cache()\n\n            logits_out = self._mlx_model(remaining[None], cache=cache)\n            mx.eval(logits_out)\n            last_logits = logits_out[:, -1:, :]\n\n            prefill_time = time.time() - prefill_start\n            prefill_tps = prompt_length / prefill_time if prefill_time > 0 else 0\n            logger.info(\n                f\"MLX native prefill: {prompt_length} tokens \"\n                f\"in {prefill_time:.2f}s ({prefill_tps:.1f} tok/s)\"\n            )\n\n        # ===== AUTOREGRESSIVE GENERATION LOOP =====\n        all_token_ids = list(input_ids_np[0])\n        new_tokens = []\n        decode_start = time.time()\n\n        pbar = tqdm(total=max_new_tokens, desc=tqdm_desc, unit=\"tok\")\n        for step in range(max_new_tokens):\n            # ---- Combine logits (CFG formula in MLX, lazy) ----\n            if use_cfg:\n                step_logits = last_uncond + cfg_scale * (last_cond - last_uncond)\n            else:\n                step_logits = last_logits\n\n            step_logits = step_logits.reshape(1, -1)  # [1, vocab_size]\n\n            # ---- Native MLX repetition penalty (lazy) ----\n            if use_rep_penalty and len(all_token_ids) > 0:\n                token_indices = mx.array(all_token_ids)\n                selected = step_logits[:, token_indices]\n                modified = mx.where(\n                    selected > 0,\n                    selected / rep_penalty_val,\n                    selected * rep_penalty_val,\n                )\n                step_logits[:, token_indices] = modified\n\n            # ---- Constrained decoding: native MLX fast path vs PyTorch bridge ----\n            if constrained_processor is not None:\n                _cp_state = constrained_processor.state\n\n                if _cp_state == FSMState.CODES_GENERATION:\n                    # === NATIVE MLX FAST PATH (no PyTorch bridge!) ===\n                    # Apply non-audio-code mask (blocks everything except audio codes + EOS)\n                    if _mlx_non_audio_mask is not None:\n                        step_logits = step_logits + _mlx_non_audio_mask\n                    # Duration constraint: block or force EOS\n                    if _target_codes is not None and _mlx_eos_id is not None:\n                        if constrained_processor.codes_count < _target_codes:\n                            # Block EOS until target codes reached\n                            step_logits = mx.concatenate([\n                                step_logits[:, :_mlx_eos_id],\n                                mx.array([[float('-inf')]]),\n                                step_logits[:, _mlx_eos_id + 1:],\n                            ], axis=1)\n                        else:\n                            # Force EOS when target reached\n                            eos_val = step_logits[:, _mlx_eos_id:_mlx_eos_id + 1]\n                            step_logits = mx.full(step_logits.shape, float('-inf'))\n                            step_logits = mx.concatenate([\n                                step_logits[:, :_mlx_eos_id],\n                                eos_val,\n                                step_logits[:, _mlx_eos_id + 1:],\n                            ], axis=1)\n\n                elif _cp_state == FSMState.COMPLETED:\n                    # No-op: COMPLETED state in codes/cot phase is passthrough\n                    pass\n\n                else:\n                    # === PYTORCH BRIDGE (metadata states during CoT phase) ===\n                    step_logits_f32 = step_logits.astype(mx.float32)\n                    np_logits = np.array(step_logits_f32, copy=True)\n                    t_logits = torch.from_numpy(np_logits)\n                    t_ids = torch.tensor([all_token_ids], dtype=torch.long)\n                    t_logits = constrained_processor(t_ids, t_logits)\n                    step_logits = mx.array(t_logits.numpy())\n\n            # ---- Native MLX sampling (temperature + top-k + top-p) ----\n            logprobs = step_logits - mx.logsumexp(step_logits, keepdims=True)\n            token_arr = sampler(logprobs)\n            mx.eval(token_arr)  # SINGLE sync point per token\n            token_id = token_arr.item()\n\n            new_tokens.append(token_id)\n            all_token_ids.append(token_id)\n            pbar.update(1)\n\n            # Update constrained processor FSM state\n            if constrained_processor is not None:\n                constrained_processor.update_state(token_id)\n\n            # Check EOS\n            if token_id == eos_token_id:\n                break\n            if pad_token_id is not None and pad_token_id != eos_token_id and token_id == pad_token_id:\n                break\n\n            # ---- Next forward step in MLX (LAZY - no eval!) ----\n            # By deferring evaluation, the entire pipeline (forward + CFG + mask + sample)\n            # executes as one fused graph when mx.eval(token_arr) is called next iteration.\n            next_input = mx.array([[token_id]])\n            if use_cfg:\n                cond_logits = self._mlx_model(next_input, cache=cond_cache)\n                uncond_logits = self._mlx_model(next_input, cache=uncond_cache)\n                last_cond = cond_logits[:, -1:, :]\n                last_uncond = uncond_logits[:, -1:, :]\n            else:\n                logits_out = self._mlx_model(next_input, cache=cache)\n                last_logits = logits_out[:, -1:, :]\n\n            # Periodic memory cleanup (every 256 tokens, matching mlx-lm pattern)\n            if step % 256 == 0 and step > 0:\n                mx.clear_cache()\n\n        pbar.close()\n\n        # ---- Log generation summary ----\n        decode_time = time.time() - decode_start\n        num_generated = len(new_tokens)\n        decode_tps = num_generated / decode_time if decode_time > 0 else 0\n        total_time = prefill_time + decode_time\n        logger.info(\n            f\"MLX native generation complete: {num_generated} tokens in {decode_time:.2f}s \"\n            f\"({decode_tps:.1f} tok/s) | prefill {prefill_time:.2f}s + decode {decode_time:.2f}s = {total_time:.2f}s total\"\n        )\n\n        # Decode new tokens only\n        output_text = self.llm_tokenizer.decode(new_tokens, skip_special_tokens=False)\n        return output_text\n\n    def _run_mlx_single(\n        self,\n        formatted_prompt: str,\n        temperature: float,\n        cfg_scale: float,\n        negative_prompt: str,\n        top_k: Optional[int],\n        top_p: Optional[float],\n        repetition_penalty: float,\n        use_constrained_decoding: bool,\n        constrained_decoding_debug: bool,\n        target_duration: Optional[float],\n        user_metadata: Optional[Dict[str, Optional[str]]],\n        stop_at_reasoning: bool,\n        skip_genres: bool,\n        skip_caption: bool,\n        skip_language: bool,\n        generation_phase: str,\n        caption: str,\n        lyrics: str,\n        cot_text: str,\n    ) -> str:\n        \"\"\"\n        MLX-accelerated single-item generation.\n\n        Tries optimized native MLX generation first (using mlx-lm infrastructure\n        for sampling, repetition penalty, and chunked prefill). Falls back to\n        hybrid MLX/PyTorch approach if native generation fails.\n        \"\"\"\n        # ---- Try optimized native MLX generation ----\n        try:\n            return self._run_mlx_single_native(\n                formatted_prompt=formatted_prompt,\n                temperature=temperature,\n                cfg_scale=cfg_scale,\n                negative_prompt=negative_prompt,\n                top_k=top_k,\n                top_p=top_p,\n                repetition_penalty=repetition_penalty,\n                use_constrained_decoding=use_constrained_decoding,\n                constrained_decoding_debug=constrained_decoding_debug,\n                target_duration=target_duration,\n                user_metadata=user_metadata,\n                stop_at_reasoning=stop_at_reasoning,\n                skip_genres=skip_genres,\n                skip_caption=skip_caption,\n                skip_language=skip_language,\n                generation_phase=generation_phase,\n                caption=caption,\n                lyrics=lyrics,\n                cot_text=cot_text,\n            )\n        except Exception as _native_err:\n            logger.warning(\n                f\"Native MLX generation failed ({type(_native_err).__name__}: {_native_err}), \"\n                f\"falling back to hybrid mode\"\n            )\n\n        # ---- Fallback: Legacy hybrid MLX/PyTorch generation ----\n        import mlx.core as mx\n        import numpy as np\n\n        # Tokenize prompt\n        inputs = self.llm_tokenizer(\n            formatted_prompt,\n            return_tensors=\"np\",\n            padding=False,\n            truncation=True,\n        )\n        input_ids_np = inputs[\"input_ids\"]  # [1, seq_len]\n        prompt_length = input_ids_np.shape[1]\n        prompt = mx.array(input_ids_np)\n\n        # Setup constrained processor\n        constrained_processor = self._setup_constrained_processor(\n            use_constrained_decoding=use_constrained_decoding,\n            constrained_decoding_debug=constrained_decoding_debug,\n            target_duration=target_duration,\n            user_metadata=user_metadata,\n            stop_at_reasoning=stop_at_reasoning,\n            skip_genres=skip_genres,\n            skip_caption=skip_caption,\n            skip_language=skip_language,\n            generation_phase=generation_phase,\n            is_batch=False,\n        )\n\n        # Calculate max_new_tokens\n        max_new_tokens = self._compute_max_new_tokens(\n            target_duration=target_duration,\n            generation_phase=generation_phase,\n        )\n\n        # EOS token\n        eos_token_id = self.llm_tokenizer.eos_token_id\n        pad_token_id = self.llm_tokenizer.pad_token_id or eos_token_id\n\n        use_cfg = cfg_scale > 1.0\n        cfg_label = \"CFG \" if use_cfg else \"\"\n        tqdm_desc = f\"MLX {cfg_label}Generation\"\n\n        # ---- Prefill phase ----\n        prefill_start = time.time()\n        if use_cfg:\n            # Build unconditional prompt\n            uncond_text = self._build_unconditional_prompt(\n                caption=caption,\n                lyrics=lyrics,\n                cot_text=cot_text,\n                negative_prompt=negative_prompt,\n                generation_phase=generation_phase,\n                is_batch=False,\n            )\n            uncond_inputs = self.llm_tokenizer(\n                uncond_text,\n                return_tensors=\"np\",\n                padding=False,\n                truncation=True,\n            )\n            uncond_prompt = mx.array(uncond_inputs[\"input_ids\"])\n            uncond_length = uncond_prompt.shape[1]\n\n            # Create separate caches for conditional and unconditional\n            cond_cache = self._make_mlx_cache()\n            uncond_cache = self._make_mlx_cache()\n\n            # Prefill both prompts\n            cond_logits = self._mlx_model(prompt, cache=cond_cache)\n            uncond_logits = self._mlx_model(uncond_prompt, cache=uncond_cache)\n            mx.eval(cond_logits, uncond_logits)\n\n            last_cond = cond_logits[:, -1:, :]\n            last_uncond = uncond_logits[:, -1:, :]\n\n            prefill_time = time.time() - prefill_start\n            total_prefill_tokens = prompt_length + uncond_length\n            prefill_tps = total_prefill_tokens / prefill_time if prefill_time > 0 else 0\n            logger.info(\n                f\"MLX prefill: {total_prefill_tokens} tokens \"\n                f\"(cond={prompt_length}, uncond={uncond_length}) \"\n                f\"in {prefill_time:.2f}s ({prefill_tps:.1f} tok/s)\"\n            )\n        else:\n            cache = self._make_mlx_cache()\n            logits_out = self._mlx_model(prompt, cache=cache)\n            mx.eval(logits_out)\n            last_logits = logits_out[:, -1:, :]\n\n            prefill_time = time.time() - prefill_start\n            prefill_tps = prompt_length / prefill_time if prefill_time > 0 else 0\n            logger.info(\n                f\"MLX prefill: {prompt_length} tokens \"\n                f\"in {prefill_time:.2f}s ({prefill_tps:.1f} tok/s)\"\n            )\n\n        # ---- Autoregressive generation loop ----\n        # Track all token IDs for constrained processor context\n        all_token_ids = list(input_ids_np[0])\n        new_tokens = []\n        decode_start = time.time()\n\n        pbar = tqdm(total=max_new_tokens, desc=tqdm_desc, unit=\"tok\")\n        for step in range(max_new_tokens):\n            # Apply CFG formula in MLX\n            if use_cfg:\n                step_logits = last_uncond + cfg_scale * (last_cond - last_uncond)\n            else:\n                step_logits = last_logits\n\n            step_logits = step_logits.reshape(1, -1)  # [1, vocab_size]\n\n            # Bridge to PyTorch for logits processing and sampling\n            # This reuses all existing tested code (constrained decoding, top-k/p, etc.)\n            # Cast to float32 in MLX first: numpy doesn't support bfloat16\n            step_logits_f32 = step_logits.astype(mx.float32)\n            np_logits = np.array(step_logits_f32, copy=True)\n            t_logits = torch.from_numpy(np_logits)\n            t_ids = torch.tensor([all_token_ids], dtype=torch.long)\n\n            # Apply constrained processor\n            if constrained_processor is not None:\n                t_logits = constrained_processor(t_ids, t_logits)\n\n            # Apply repetition penalty\n            if repetition_penalty != 1.0:\n                from transformers.generation.logits_process import RepetitionPenaltyLogitsProcessor\n                rep_proc = RepetitionPenaltyLogitsProcessor(penalty=repetition_penalty)\n                t_logits = rep_proc(t_ids, t_logits)\n\n            # Apply top-k and top-p filtering (reuse existing methods)\n            t_logits = self._apply_top_k_filter(t_logits, top_k)\n            t_logits = self._apply_top_p_filter(t_logits, top_p)\n\n            # Sample token (reuse existing method)\n            t_token = self._sample_tokens(t_logits, temperature)\n            token_id = t_token.item()\n\n            new_tokens.append(token_id)\n            all_token_ids.append(token_id)\n            pbar.update(1)\n\n            # Update constrained processor state\n            if constrained_processor is not None:\n                constrained_processor.update_state(token_id)\n\n            # Check EOS\n            if token_id == eos_token_id:\n                break\n            if pad_token_id is not None and pad_token_id != eos_token_id and token_id == pad_token_id:\n                break\n\n            # Next forward step in MLX (fast)\n            next_input = mx.array([[token_id]])\n            if use_cfg:\n                cond_logits = self._mlx_model(next_input, cache=cond_cache)\n                uncond_logits = self._mlx_model(next_input, cache=uncond_cache)\n                mx.eval(cond_logits, uncond_logits)\n                last_cond = cond_logits[:, -1:, :]\n                last_uncond = uncond_logits[:, -1:, :]\n            else:\n                logits_out = self._mlx_model(next_input, cache=cache)\n                mx.eval(logits_out)\n                last_logits = logits_out[:, -1:, :]\n\n        pbar.close()\n\n        # Log generation summary\n        decode_time = time.time() - decode_start\n        num_generated = len(new_tokens)\n        decode_tps = num_generated / decode_time if decode_time > 0 else 0\n        total_time = prefill_time + decode_time\n        logger.info(\n            f\"MLX generation complete: {num_generated} tokens in {decode_time:.2f}s \"\n            f\"({decode_tps:.1f} tok/s) | prefill {prefill_time:.2f}s + decode {decode_time:.2f}s = {total_time:.2f}s total\"\n        )\n\n        # Decode new tokens only\n        output_text = self.llm_tokenizer.decode(new_tokens, skip_special_tokens=False)\n        return output_text\n\n    def _run_mlx(\n        self,\n        formatted_prompts: Union[str, List[str]],\n        temperature: float,\n        cfg_scale: float,\n        negative_prompt: str,\n        top_k: Optional[int],\n        top_p: Optional[float],\n        repetition_penalty: float,\n        use_constrained_decoding: bool = True,\n        constrained_decoding_debug: bool = False,\n        target_duration: Optional[float] = None,\n        user_metadata: Optional[Dict[str, Optional[str]]] = None,\n        stop_at_reasoning: bool = False,\n        skip_genres: bool = True,\n        skip_caption: bool = False,\n        skip_language: bool = False,\n        generation_phase: str = \"cot\",\n        caption: str = \"\",\n        lyrics: str = \"\",\n        cot_text: str = \"\",\n        seeds: Optional[List[int]] = None,\n    ) -> Union[str, List[str]]:\n        \"\"\"\n        Unified MLX generation function supporting both single and batch modes.\n\n        For batch mode in codes generation phase, uses optimized batch native path\n        that shares prefill across all items (saving ~50% prefill time).\n        Falls back to sequential processing if batch native fails.\n        \"\"\"\n        import mlx.core as mx\n\n        # Normalize input\n        formatted_prompt_list, is_batch = self._normalize_batch_input(formatted_prompts)\n\n        if is_batch:\n            batch_size = len(formatted_prompt_list)\n\n            # ---- Try optimized batch native path ----\n            # Conditions: codes generation phase + all prompts identical (which they are in batch codes phase)\n            all_prompts_identical = len(set(formatted_prompt_list)) == 1\n            can_use_batch_native = (\n                generation_phase == \"codes\"\n                and all_prompts_identical\n                and batch_size > 1\n                and hasattr(self, '_mlx_model')\n                and self._mlx_model is not None\n            )\n\n            if can_use_batch_native:\n                try:\n                    logger.info(\n                        f\"MLX batch: using optimized batch native path \"\n                        f\"(batch_size={batch_size}, shared prefill)\"\n                    )\n                    return self._run_mlx_batch_native(\n                        formatted_prompt=formatted_prompt_list[0],\n                        batch_size=batch_size,\n                        temperature=temperature,\n                        cfg_scale=cfg_scale,\n                        negative_prompt=negative_prompt,\n                        top_k=top_k,\n                        top_p=top_p,\n                        repetition_penalty=repetition_penalty,\n                        use_constrained_decoding=use_constrained_decoding,\n                        constrained_decoding_debug=constrained_decoding_debug,\n                        target_duration=target_duration,\n                        caption=caption,\n                        lyrics=lyrics,\n                        cot_text=cot_text,\n                        seeds=seeds,\n                    )\n                except Exception as e:\n                    logger.warning(\n                        f\"MLX batch native failed ({type(e).__name__}: {e}), \"\n                        f\"falling back to sequential mode\"\n                    )\n\n            # ---- Fallback: sequential processing ----\n            logger.info(f\"MLX batch: using sequential mode (batch_size={batch_size})\")\n            output_texts = []\n            for i, formatted_prompt in enumerate(formatted_prompt_list):\n                # Set MLX seed for reproducibility\n                if seeds and i < len(seeds):\n                    mx.random.seed(seeds[i])\n\n                output_text = self._run_mlx_single(\n                    formatted_prompt=formatted_prompt,\n                    temperature=temperature,\n                    cfg_scale=cfg_scale,\n                    negative_prompt=negative_prompt,\n                    top_k=top_k,\n                    top_p=top_p,\n                    repetition_penalty=repetition_penalty,\n                    use_constrained_decoding=use_constrained_decoding,\n                    constrained_decoding_debug=constrained_decoding_debug,\n                    target_duration=target_duration,\n                    user_metadata=None,\n                    stop_at_reasoning=False,\n                    skip_genres=True,\n                    skip_caption=True,\n                    skip_language=True,\n                    generation_phase=generation_phase,\n                    caption=caption,\n                    lyrics=lyrics,\n                    cot_text=cot_text,\n                )\n                output_texts.append(output_text)\n            return output_texts\n\n        # Single mode\n        formatted_prompt = formatted_prompt_list[0]\n        return self._run_mlx_single(\n            formatted_prompt=formatted_prompt,\n            temperature=temperature,\n            cfg_scale=cfg_scale,\n            negative_prompt=negative_prompt,\n            top_k=top_k,\n            top_p=top_p,\n            repetition_penalty=repetition_penalty,\n            use_constrained_decoding=use_constrained_decoding,\n            constrained_decoding_debug=constrained_decoding_debug,\n            target_duration=target_duration,\n            user_metadata=user_metadata,\n            stop_at_reasoning=stop_at_reasoning,\n            skip_genres=skip_genres,\n            skip_caption=skip_caption,\n            skip_language=skip_language,\n            generation_phase=generation_phase,\n            caption=caption,\n            lyrics=lyrics,\n            cot_text=cot_text,\n        )\n\n    # =========================================================================\n    # End of MLX Backend Methods\n    # =========================================================================\n\n    @contextmanager\n    def _load_model_context(self):\n        \"\"\"\n        Context manager to load a model to GPU and offload it back to CPU after use.\n        Only used for PyTorch backend when offload_to_cpu is True.\n        \"\"\"\n        if not self.offload_to_cpu:\n            yield\n            return\n\n        # If using nanovllm or MLX, do not offload (managed differently)\n        if self.llm_backend in (\"vllm\", \"mlx\"):\n            yield\n            return\n\n        model = self.llm\n        if model is None:\n            yield\n            return\n\n        # Reentrancy guard: if an outer context already loaded the model\n        # to the target device, skip the inner load/offload to avoid\n        # redundant CPU↔GPU transfers during batch processing.\n        try:\n            current_device = next(model.parameters()).device.type\n        except StopIteration:\n            current_device = None\n        target_device = str(self.device).split(\":\")[0]\n        if current_device == target_device:\n            yield\n            return\n\n        # Load to GPU\n        logger.info(f\"Loading LLM to {self.device}\")\n        start_time = time.time()\n        if hasattr(model, \"to\"):\n            model.to(self.device).to(self.dtype)\n        load_time = time.time() - start_time\n        logger.info(f\"Loaded LLM to {self.device} in {load_time:.4f}s\")\n\n        try:\n            yield\n        finally:\n            # Offload to CPU\n            logger.info(f\"Offloading LLM to CPU\")\n            start_time = time.time()\n            if hasattr(model, \"to\"):\n                model.to(\"cpu\")\n            # Clear accelerator cache after offloading\n            gc.collect()\n            if torch.cuda.is_available():\n                torch.cuda.empty_cache()\n            elif hasattr(torch, 'xpu') and torch.xpu.is_available():\n                torch.xpu.empty_cache()\n            elif hasattr(torch.backends, \"mps\") and torch.backends.mps.is_available() and hasattr(torch, \"mps\") and hasattr(torch.mps, \"empty_cache\"):\n                torch.mps.empty_cache()\n            offload_time = time.time() - start_time\n            logger.info(f\"Offloaded LLM to CPU in {offload_time:.4f}s\")\n\n    def get_hf_model_for_scoring(self):\n        \"\"\"\n        Get HuggingFace model for perplexity scoring.\n\n        For vllm backend, loads HuggingFace model from disk (weights are cached by transformers).\n        For pt backend, returns the existing model.\n        For mlx backend, loads HuggingFace model from disk (MLX model can't be used for torch scoring).\n\n        Returns:\n            HuggingFace model instance\n        \"\"\"\n        if self.llm_backend == \"pt\":\n            # For PyTorch backend, directly return the model\n            return self.llm\n\n        elif self.llm_backend == \"vllm\":\n            # For vllm backend, load HuggingFace model from disk\n            # Note: transformers caches model weights, so this doesn't duplicate disk I/O\n            if self._hf_model_for_scoring is None:\n                logger.info(\"Loading HuggingFace model for scoring (from checkpoint)\")\n\n                # Get model path from vllm config\n                model_runner = self.llm.model_runner\n                model_path = model_runner.config.model\n\n                # Load HuggingFace model from the same checkpoint\n                # This will load the original unfused weights\n                import time\n                start_time = time.time()\n                self._hf_model_for_scoring = AutoModelForCausalLM.from_pretrained(\n                    model_path,\n                    trust_remote_code=True,\n                    torch_dtype=self.dtype\n                )\n                load_time = time.time() - start_time\n                logger.info(f\"HuggingFace model loaded in {load_time:.2f}s\")\n\n                # When offload_to_cpu is enabled, keep the model on CPU to save\n                # VRAM.  The caller (_load_scoring_model_context in\n                # core/scoring/lm_score.py) will move it to the accelerator only\n                # for the duration of the forward pass.\n                if self.offload_to_cpu:\n                    self._hf_model_for_scoring.eval()\n                    logger.info(\"HuggingFace model for scoring kept on CPU (offload_to_cpu=True)\")\n                else:\n                    device = next(model_runner.model.parameters()).device\n                    self._hf_model_for_scoring = self._hf_model_for_scoring.to(device)\n                    self._hf_model_for_scoring.eval()\n                    logger.info(f\"HuggingFace model for scoring ready on {device}\")\n\n            return self._hf_model_for_scoring\n\n        elif self.llm_backend == \"mlx\":\n            # For MLX backend, load HuggingFace model from disk for PyTorch scoring\n            if self._hf_model_for_scoring is None:\n                logger.info(\"Loading HuggingFace model for scoring (MLX backend, need PyTorch model)\")\n\n                # Get model path from stored path\n                model_path = getattr(self, '_mlx_model_path', None)\n                if model_path is None:\n                    raise ValueError(\"MLX model path not stored. Cannot load HuggingFace model for scoring.\")\n\n                import time\n                start_time = time.time()\n                self._hf_model_for_scoring = AutoModelForCausalLM.from_pretrained(\n                    model_path,\n                    trust_remote_code=True,\n                    torch_dtype=self.dtype\n                )\n                load_time = time.time() - start_time\n                logger.info(f\"HuggingFace model loaded in {load_time:.2f}s\")\n\n                # When offload_to_cpu is enabled, keep on CPU; the scoring\n                # context manager will move it to the accelerator as needed.\n                if self.offload_to_cpu:\n                    self._hf_model_for_scoring.eval()\n                    logger.info(\"HuggingFace model for scoring kept on CPU (offload_to_cpu=True)\")\n                else:\n                    device = \"mps\" if hasattr(torch.backends, \"mps\") and torch.backends.mps.is_available() else \"cpu\"\n                    self._hf_model_for_scoring = self._hf_model_for_scoring.to(device)\n                    self._hf_model_for_scoring.eval()\n                    logger.info(f\"HuggingFace model for scoring ready on {device}\")\n\n            return self._hf_model_for_scoring\n\n        else:\n            raise ValueError(f\"Unknown backend: {self.llm_backend}\")\n"
  },
  {
    "path": "acestep/llm_inference_cache_cleanup_test.py",
    "content": "\"\"\"Unit tests for accelerator cache cleanup in ``LLMHandler``.\"\"\"\n\nimport unittest\nfrom types import SimpleNamespace\nfrom unittest.mock import MagicMock, patch\n\nimport torch\n\ntry:\n    from acestep.llm_inference import LLMHandler\n    _IMPORT_ERROR = None\nexcept ImportError as exc:\n    LLMHandler = None\n    _IMPORT_ERROR = exc\n\n\n@unittest.skipIf(LLMHandler is None, f\"llm_inference import unavailable: {_IMPORT_ERROR}\")\nclass LlmAcceleratorCacheCleanupTests(unittest.TestCase):\n    \"\"\"Verify _clear_accelerator_cache syncs then clears the correct backend.\"\"\"\n\n    def test_syncs_then_clears_cuda(self):\n        \"\"\"CUDA: synchronize() must fire before empty_cache().\"\"\"\n        handler = LLMHandler()\n        handler.device = \"cuda\"\n        call_order = []\n        with patch(\"torch.cuda.is_available\", return_value=True), \\\n             patch(\"torch.cuda.synchronize\",\n                   side_effect=lambda: call_order.append(\"sync\")), \\\n             patch(\"torch.cuda.empty_cache\",\n                   side_effect=lambda: call_order.append(\"clear\")):\n            handler._clear_accelerator_cache()\n        self.assertEqual(call_order, [\"sync\", \"clear\"])\n\n    def test_syncs_then_clears_xpu(self):\n        \"\"\"XPU: synchronize() must fire before empty_cache().\"\"\"\n        handler = LLMHandler()\n        handler.device = \"xpu\"\n        call_order = []\n        fake_xpu = SimpleNamespace(\n            is_available=lambda: True,\n            synchronize=MagicMock(\n                side_effect=lambda: call_order.append(\"sync\")),\n            empty_cache=MagicMock(\n                side_effect=lambda: call_order.append(\"clear\")),\n        )\n        with patch.object(torch, \"xpu\", fake_xpu, create=True):\n            handler._clear_accelerator_cache()\n        self.assertEqual(call_order, [\"sync\", \"clear\"])\n\n    def test_syncs_then_clears_mps(self):\n        \"\"\"MPS: synchronize() must fire before empty_cache().\"\"\"\n        handler = LLMHandler()\n        handler.device = \"mps\"\n        call_order = []\n        fake_mps_backend = SimpleNamespace(is_available=lambda: True)\n        fake_mps = SimpleNamespace(\n            synchronize=MagicMock(\n                side_effect=lambda: call_order.append(\"sync\")),\n            empty_cache=MagicMock(\n                side_effect=lambda: call_order.append(\"clear\")),\n        )\n        with patch.object(\n                torch.backends, \"mps\", fake_mps_backend), \\\n             patch.object(\n                torch, \"mps\", fake_mps, create=True):\n            handler._clear_accelerator_cache()\n        self.assertEqual(call_order, [\"sync\", \"clear\"])\n\n    def test_falls_back_to_cuda_when_device_unset(self):\n        \"\"\"When self.device is None, fall back to CUDA if available.\"\"\"\n        handler = LLMHandler()\n        handler.device = None\n        call_order = []\n        with patch(\"torch.cuda.is_available\", return_value=True), \\\n             patch(\"torch.cuda.synchronize\",\n                   side_effect=lambda: call_order.append(\"sync\")), \\\n             patch(\"torch.cuda.empty_cache\",\n                   side_effect=lambda: call_order.append(\"clear\")):\n            handler._clear_accelerator_cache()\n        self.assertEqual(call_order, [\"sync\", \"clear\"])\n\n    def test_noop_when_device_is_cpu(self):\n        \"\"\"Safe no-op when device is CPU and no GPU available.\"\"\"\n        handler = LLMHandler()\n        handler.device = \"cpu\"\n        with patch(\"torch.cuda.is_available\", return_value=False), \\\n             patch(\"torch.cuda.empty_cache\") as cuda_mock:\n            handler._clear_accelerator_cache()\n        cuda_mock.assert_not_called()\n\n\nif __name__ == \"__main__\":\n    unittest.main()\n"
  },
  {
    "path": "acestep/llm_inference_cfg_fixes_test.py",
    "content": "\"\"\"Unit tests for CFG-related bug fixes in ``LLMHandler``.\n\nCovers:\n  - Fix 1: cfg_scale forced to 1.0 during CoT phase so text logits are not distorted.\n  - Fixes 2/3/5: non_audio_code_mask applied *before* CFG to avoid wasted compute\n    over the full 217k vocab and probability mass leakage.\n  - Fix 4: per-sequence EOS tracking – generation stops only when *all* sequences\n    have finished, not at the first EOS token.\n\"\"\"\n\nimport unittest\nfrom types import SimpleNamespace\nfrom unittest.mock import MagicMock, patch, call\n\ntry:\n    import torch\n    from acestep.llm_inference import LLMHandler\n    from acestep.constrained_logits_processor import FSMState\n\n    _IMPORT_ERROR = None\nexcept ImportError as exc:  # pragma: no cover – dependency guard\n    torch = None  # type: ignore[assignment]\n    LLMHandler = None\n    FSMState = None\n    _IMPORT_ERROR = exc\n\n\n# ---------------------------------------------------------------------------\n# Helpers\n# ---------------------------------------------------------------------------\n\ndef _make_handler() -> \"LLMHandler\":\n    \"\"\"Return a minimal LLMHandler without any loaded models.\"\"\"\n    handler = LLMHandler()\n    # Provide just enough tokenizer state for the tests\n    tokenizer = MagicMock()\n    tokenizer.eos_token_id = 1\n    tokenizer.pad_token_id = 1\n    handler.llm_tokenizer = tokenizer\n    handler.disable_tqdm = True\n    return handler\n\n\ndef _make_constrained_processor(state: \"FSMState\", vocab_size: int = 10) -> MagicMock:\n    \"\"\"Return a mock constrained processor pinned to *state*.\"\"\"\n    proc = MagicMock()\n    proc.state = state\n    # Build a mask that allows only tokens 2 and 3 (audio codes) plus token 1 (EOS)\n    non_audio_mask = torch.full((1, vocab_size), float(\"-inf\"))\n    non_audio_mask[0, 1] = 0.0  # EOS\n    non_audio_mask[0, 2] = 0.0  # audio code\n    non_audio_mask[0, 3] = 0.0  # audio code\n    proc.non_audio_code_mask = non_audio_mask\n    # Make __call__ return scores unchanged by default\n    proc.side_effect = lambda input_ids, scores: scores\n    return proc\n\n\ndef _make_fake_model(batch_size: int, vocab_size: int = 10, logit_val: float = 1.0):\n    \"\"\"Return a fake model that outputs constant logits of shape [batch_size, 1, vocab_size].\"\"\"\n    model = MagicMock()\n    logits = torch.full((batch_size, 1, vocab_size), logit_val)\n    outputs = SimpleNamespace(logits=logits, past_key_values=None)\n    model.return_value = outputs\n    model.generation_config = MagicMock()\n    model.generation_config.use_cache = False\n    return model\n\n\n# ---------------------------------------------------------------------------\n# Fix 1: CoT phase must use cfg_scale=1.0\n# ---------------------------------------------------------------------------\n\n@unittest.skipIf(LLMHandler is None, f\"llm_inference import unavailable: {_IMPORT_ERROR}\")\nclass TestCotCfgScaleFixed(unittest.TestCase):\n    \"\"\"cfg_scale must be forced to 1.0 for the CoT phase (Fix 1).\"\"\"\n\n    def test_cot_phase_uses_cfg_scale_1(self):\n        \"\"\"generate_from_formatted_prompt called during CoT must receive cfg_scale=1.0.\"\"\"\n        handler = LLMHandler()\n        handler.llm_initialized = True\n        handler.llm_backend = \"pt\"\n\n        captured_cfg = {}\n\n        def fake_run_pt(formatted_prompts, temperature, cfg_scale, **kwargs):\n            captured_cfg[\"cfg_scale\"] = cfg_scale\n            return \"<think>metadata</think>\"\n\n        with patch.object(handler, \"_run_pt\", side_effect=fake_run_pt):\n            with patch.object(handler, \"build_formatted_prompt\", return_value=\"PROMPT\"):\n                with patch.object(\n                    handler,\n                    \"_format_metadata_as_cot\",\n                    return_value=\"\",\n                ):\n                    with patch.object(\n                        handler,\n                        \"build_formatted_prompt_with_cot\",\n                        return_value=\"PROMPT_WITH_COT\",\n                    ):\n                        # Simulate Phase 1 CoT call via generate_from_formatted_prompt\n                        # by calling the internal helper directly\n                        handler.generate_from_formatted_prompt(\n                            formatted_prompt=\"PROMPT\",\n                            cfg={\n                                \"temperature\": 0.6,\n                                \"cfg_scale\": 1.0,  # already 1.0 for CoT\n                                \"negative_prompt\": \"NO USER INPUT\",\n                                \"top_k\": None,\n                                \"top_p\": None,\n                                \"repetition_penalty\": 1.0,\n                                \"target_duration\": None,\n                                \"generation_phase\": \"cot\",\n                                \"caption\": \"test\",\n                                \"lyrics\": \"test\",\n                            },\n                        )\n        # cfg_scale must be 1.0 for CoT – captured during _run_pt call\n        self.assertEqual(captured_cfg.get(\"cfg_scale\"), 1.0)\n\n    def test_generate_with_stop_condition_forces_cot_cfg_1(self):\n        \"\"\"generate_with_stop_condition must pass cfg_scale=1.0 to the CoT phase\n        regardless of the user-supplied cfg_scale value.\"\"\"\n        handler = LLMHandler()\n        handler.llm_initialized = True\n        handler.llm_backend = \"pt\"\n\n        # Capture cfg passed to generate_from_formatted_prompt\n        captured_cfgs = []\n\n        def capturing_gen(formatted_prompt, cfg=None, **kwargs):\n            captured_cfgs.append(cfg or {})\n            # Return a minimal CoT response so Phase 1 succeeds\n            return \"<think>metadata</think>\", \"ok\"\n\n        with patch.object(handler, \"generate_from_formatted_prompt\", side_effect=capturing_gen):\n            with patch.object(handler, \"build_formatted_prompt\", return_value=\"P\"):\n                with patch.object(handler, \"_parse_metadata_from_cot\", return_value={}):\n                    with patch.object(handler, \"_format_metadata_as_cot\", return_value=\"\"):\n                        with patch.object(\n                            handler, \"build_formatted_prompt_with_cot\", return_value=\"P2\"\n                        ):\n                            # Invoke with cfg_scale=2.0 (typical UI default)\n                            handler.generate_with_stop_condition(\n                                caption=\"test caption\",\n                                lyrics=\"test lyrics\",\n                                cfg_scale=2.0,\n                                temperature=0.6,\n                                negative_prompt=\"\",\n                                top_k=None,\n                                top_p=None,\n                                repetition_penalty=1.0,\n                                infer_type=\"dit\",  # Phase 1 only – avoids Phase 2 setup\n                                progress=lambda *a, **kw: None,\n                            )\n\n        # At least one generate_from_formatted_prompt call must exist\n        self.assertTrue(len(captured_cfgs) >= 1, \"generate_from_formatted_prompt was not called\")\n\n        # The first call is always the CoT phase – cfg_scale must be 1.0\n        cot_cfg = captured_cfgs[0]\n        self.assertEqual(\n            cot_cfg.get(\"cfg_scale\"),\n            1.0,\n            f\"Expected cfg_scale=1.0 for CoT phase, got {cot_cfg.get('cfg_scale')}\",\n        )\n\n\n# ---------------------------------------------------------------------------\n# Fixes 2/3/5: mask applied before CFG in CODES_GENERATION state\n# ---------------------------------------------------------------------------\n\n@unittest.skipIf(LLMHandler is None, f\"llm_inference import unavailable: {_IMPORT_ERROR}\")\nclass TestCfgMaskBeforeCFG(unittest.TestCase):\n    \"\"\"When in CODES_GENERATION state, invalid tokens must be -inf BEFORE CFG (Fixes 2/3/5).\"\"\"\n\n    VOCAB_SIZE = 10\n    BATCH_SIZE = 1\n\n    def _run_single_step(\n        self,\n        constrained_processor_state: \"FSMState\",\n        cond_logit_val: float = 2.0,\n        uncond_logit_val: float = 1.0,\n        cfg_scale: float = 2.0,\n    ) -> \"torch.Tensor\":\n        \"\"\"Run _generate_with_cfg_custom for one step and return the sampled token.\"\"\"\n        handler = _make_handler()\n        vocab_size = self.VOCAB_SIZE\n        total_batch = self.BATCH_SIZE * 2  # cond + uncond\n\n        # Fake model – different logit values for cond vs uncond\n        model = MagicMock()\n        cond_logits = torch.full((self.BATCH_SIZE, 1, vocab_size), cond_logit_val)\n        uncond_logits = torch.full((self.BATCH_SIZE, 1, vocab_size), uncond_logit_val)\n        # Stack [cond, uncond]\n        combined_logits = torch.cat([cond_logits, uncond_logits], dim=0)\n        outputs = SimpleNamespace(logits=combined_logits, past_key_values=None)\n        model.return_value = outputs\n        model.generation_config = MagicMock()\n        model.generation_config.use_cache = False\n        handler.llm = model\n\n        constrained_proc = _make_constrained_processor(\n            constrained_processor_state, vocab_size\n        )\n\n        input_ids = torch.zeros((total_batch, 5), dtype=torch.long)\n        attn_mask = torch.ones((total_batch, 5), dtype=torch.long)\n\n        result = handler._generate_with_cfg_custom(\n            batch_input_ids=input_ids,\n            batch_attention_mask=attn_mask,\n            max_new_tokens=1,\n            temperature=1.0,\n            cfg_scale=cfg_scale,\n            top_k=None,\n            top_p=None,\n            repetition_penalty=1.0,\n            pad_token_id=1,\n            streamer=None,\n            constrained_processor=constrained_proc,\n        )\n        # result shape: [total_batch, seq_len+1]; return the generated token for cond seq 0\n        return result[0, -1]\n\n    def test_codes_generation_only_samples_valid_tokens(self):\n        \"\"\"In CODES_GENERATION state, only audio codes (2, 3) or EOS (1) may be sampled.\"\"\"\n        for _ in range(20):  # repeat to reduce flakiness from sampling\n            token = self._run_single_step(FSMState.CODES_GENERATION)\n            self.assertIn(\n                token.item(),\n                {1, 2, 3},\n                f\"Sampled invalid token {token.item()} during CODES_GENERATION\",\n            )\n\n    def test_non_codes_state_samples_from_full_vocab(self):\n        \"\"\"Outside CODES_GENERATION, all vocab tokens are valid candidates.\"\"\"\n        # With uniform logits and no masking, token 0 should sometimes be sampled\n        seen_tokens = set()\n        for _ in range(30):\n            token = self._run_single_step(FSMState.THINK_TAG, cfg_scale=1.0)\n            seen_tokens.add(token.item())\n        # Should see some variation across vocab (token 0 or others)\n        self.assertGreater(len(seen_tokens), 1, \"Expected sampling from full vocab\")\n\n    def test_codes_generation_cfg_applied_to_valid_indices_only(self):\n        \"\"\"CFG scaling must only affect valid token positions during CODES_GENERATION.\n\n        With cond_logit=2.0, uncond_logit=1.0, cfg_scale=2.0 the CFG formula gives:\n          cfg = 1.0 + 2.0 * (2.0 - 1.0) = 3.0 for valid tokens, -inf elsewhere.\n        We verify that invalid tokens remain -inf after the CFG path.\n        \"\"\"\n        handler = _make_handler()\n        vocab_size = self.VOCAB_SIZE\n        total_batch = self.BATCH_SIZE * 2\n\n        # Build a model where cond logits are 2.0 and uncond logits are 1.0\n        cond_logits = torch.full((self.BATCH_SIZE, 1, vocab_size), 2.0)\n        uncond_logits = torch.full((self.BATCH_SIZE, 1, vocab_size), 1.0)\n        combined = torch.cat([cond_logits, uncond_logits], dim=0)\n        outputs = SimpleNamespace(logits=combined, past_key_values=None)\n        model = MagicMock(return_value=outputs)\n        model.generation_config = MagicMock()\n        model.generation_config.use_cache = False\n        handler.llm = model\n\n        constrained_proc = _make_constrained_processor(FSMState.CODES_GENERATION, vocab_size)\n\n        # Patch _sample_tokens to capture the logits passed to it\n        captured_logits = []\n\n        def fake_sample(logits, temperature):\n            captured_logits.append(logits.clone())\n            # Always return valid token 2\n            return torch.tensor([2])\n\n        with patch.object(handler, \"_sample_tokens\", side_effect=fake_sample):\n            input_ids = torch.zeros((total_batch, 3), dtype=torch.long)\n            handler._generate_with_cfg_custom(\n                batch_input_ids=input_ids,\n                batch_attention_mask=None,\n                max_new_tokens=1,\n                temperature=1.0,\n                cfg_scale=2.0,\n                top_k=None,\n                top_p=None,\n                repetition_penalty=1.0,\n                pad_token_id=1,\n                streamer=None,\n                constrained_processor=constrained_proc,\n            )\n\n        self.assertEqual(len(captured_logits), 1)\n        logits = captured_logits[0][0]  # [vocab_size] for seq 0\n\n        # Invalid tokens (not 1, 2, or 3) must be -inf\n        for idx in range(vocab_size):\n            if idx not in {1, 2, 3}:\n                self.assertEqual(\n                    logits[idx].item(),\n                    float(\"-inf\"),\n                    f\"Token {idx} should be -inf (invalid), got {logits[idx].item()}\",\n                )\n\n\n# ---------------------------------------------------------------------------\n# NaN guard: aggressive repetition penalty edge case\n# ---------------------------------------------------------------------------\n\n@unittest.skipIf(LLMHandler is None, f\"llm_inference import unavailable: {_IMPORT_ERROR}\")\nclass TestCfgNanGuard(unittest.TestCase):\n    \"\"\"CFG result must not contain NaN when repetition penalty drives a token to -inf\n    in both conditional and unconditional branches simultaneously (edge case).\n\n    (-inf) + scale * ((-inf) - (-inf))  =>  NaN in IEEE 754 arithmetic\n    The nan_to_num guard must replace NaN with -inf so those tokens are safely\n    excluded from sampling rather than causing undefined behaviour.\n    \"\"\"\n\n    VOCAB_SIZE = 10\n\n    def test_cfg_nan_replaced_with_neg_inf(self):\n        \"\"\"NaN entries in cfg_logits (outside CODES_GENERATION) are replaced with -inf.\"\"\"\n        handler = _make_handler()\n        vocab_size = self.VOCAB_SIZE\n        total_batch = 2  # batch_size=1: [cond, uncond]\n\n        # Both cond and uncond logits are -inf for token 4 → CFG produces NaN for that token\n        cond = torch.full((1, 1, vocab_size), 0.0)\n        uncond = torch.full((1, 1, vocab_size), 0.0)\n        cond[0, 0, 4] = float('-inf')\n        uncond[0, 0, 4] = float('-inf')\n        # Token 7 (EOS substitute) stays finite so sampling always has a valid candidate\n        cond[0, 0, 7] = 100.0\n        uncond[0, 0, 7] = 100.0\n        combined = torch.cat([cond, uncond], dim=0)\n        outputs = SimpleNamespace(logits=combined, past_key_values=None)\n        model = MagicMock(return_value=outputs)\n        model.generation_config = MagicMock()\n        model.generation_config.use_cache = False\n        handler.llm = model\n        handler.llm_tokenizer.eos_token_id = 7\n\n        captured_logits = []\n\n        def fake_sample(logits, temperature):\n            captured_logits.append(logits.clone())\n            return torch.tensor([7])\n\n        with patch.object(handler, \"_sample_tokens\", side_effect=fake_sample):\n            input_ids = torch.zeros((total_batch, 3), dtype=torch.long)\n            # Use a THINK_TAG processor so the full-vocab CFG else-branch is taken\n            constrained_proc = _make_constrained_processor(FSMState.THINK_TAG, vocab_size)\n            handler._generate_with_cfg_custom(\n                batch_input_ids=input_ids,\n                batch_attention_mask=None,\n                max_new_tokens=1,\n                temperature=1.0,\n                cfg_scale=2.0,\n                top_k=None,\n                top_p=None,\n                repetition_penalty=1.0,\n                pad_token_id=7,\n                streamer=None,\n                constrained_processor=constrained_proc,\n            )\n\n        self.assertEqual(len(captured_logits), 1)\n        logits = captured_logits[0][0]  # [vocab_size] for seq 0\n\n        # No NaN values in the logits passed to the sampler\n        self.assertFalse(\n            torch.isnan(logits).any().item(),\n            f\"NaN found in cfg_logits: {logits}\",\n        )\n        # Token 4 (was NaN before guard) must be -inf after the guard\n        self.assertEqual(\n            logits[4].item(),\n            float('-inf'),\n            f\"Expected -inf for NaN token, got {logits[4].item()}\",\n        )\n\n\n# ---------------------------------------------------------------------------\n# Fix 4: Per-sequence EOS tracking (batch compaction)\n# ---------------------------------------------------------------------------\n\n@unittest.skipIf(LLMHandler is None, f\"llm_inference import unavailable: {_IMPORT_ERROR}\")\nclass TestPerSequenceEosTracking(unittest.TestCase):\n    \"\"\"Generation must continue until ALL sequences in the batch have hit EOS (Fix 4).\"\"\"\n\n    VOCAB_SIZE = 10\n\n    def test_generation_stops_when_all_sequences_finish(self):\n        \"\"\"With batch_size=1, generation must stop immediately at EOS (unchanged behaviour).\"\"\"\n        eos_id = 1\n        vocab_size = self.VOCAB_SIZE\n        handler = _make_handler()\n        handler.llm_tokenizer.eos_token_id = eos_id\n\n        # Model always outputs EOS\n        logits = torch.full((2, 1, vocab_size), -100.0)  # [cond+uncond, 1, V]\n        logits[:, :, eos_id] = 100.0\n        outputs = SimpleNamespace(logits=logits, past_key_values=None)\n        model = MagicMock(return_value=outputs)\n        model.generation_config = MagicMock()\n        model.generation_config.use_cache = False\n        handler.llm = model\n\n        input_ids = torch.zeros((2, 3), dtype=torch.long)\n        result = handler._generate_with_cfg_custom(\n            batch_input_ids=input_ids,\n            batch_attention_mask=None,\n            max_new_tokens=10,\n            temperature=1.0,\n            cfg_scale=1.0,\n            top_k=None,\n            top_p=None,\n            repetition_penalty=1.0,\n            pad_token_id=eos_id,\n            streamer=None,\n        )\n        # Should have stopped after 1 step (EOS immediately)\n        generated_len = result.shape[1] - input_ids.shape[1]\n        self.assertEqual(generated_len, 1, f\"Expected 1 generated token, got {generated_len}\")\n        # The generated token must be EOS\n        self.assertEqual(result[0, -1].item(), eos_id)\n\n    def test_finished_sequences_are_forced_to_eos(self):\n        \"\"\"After a sequence hits EOS, subsequent tokens must also be EOS (no new tokens).\"\"\"\n        eos_id = 1\n        vocab_size = self.VOCAB_SIZE\n        handler = _make_handler()\n        handler.llm_tokenizer.eos_token_id = eos_id\n\n        # Step 0: output EOS; step 1+: output token 5\n        step = [0]\n\n        def fake_call(input_ids, **kwargs):\n            logits = torch.full((input_ids.shape[0], 1, vocab_size), -100.0)\n            if step[0] == 0:\n                logits[:, :, eos_id] = 100.0  # EOS on step 0\n            else:\n                logits[:, :, 5] = 100.0  # token 5 on step 1+\n            step[0] += 1\n            return SimpleNamespace(logits=logits, past_key_values=None)\n\n        model = MagicMock(side_effect=fake_call)\n        model.generation_config = MagicMock()\n        model.generation_config.use_cache = False\n        handler.llm = model\n\n        input_ids = torch.zeros((2, 3), dtype=torch.long)\n        result = handler._generate_with_cfg_custom(\n            batch_input_ids=input_ids,\n            batch_attention_mask=None,\n            max_new_tokens=5,\n            temperature=1.0,\n            cfg_scale=1.0,\n            top_k=None,\n            top_p=None,\n            repetition_penalty=1.0,\n            pad_token_id=eos_id,\n            streamer=None,\n        )\n        # With batch_size=1, EOS on step 0 means all done → stops immediately\n        generated_len = result.shape[1] - input_ids.shape[1]\n        self.assertEqual(generated_len, 1)\n        self.assertEqual(result[0, -1].item(), eos_id)\n\n\nif __name__ == \"__main__\":\n    unittest.main()\n"
  },
  {
    "path": "acestep/llm_inference_dist_cleanup_test.py",
    "content": "\"\"\"Unit tests for torch.distributed cleanup in ``LLMHandler``.\"\"\"\n\nimport unittest\nfrom unittest.mock import patch\n\ntry:\n    from acestep.llm_inference import LLMHandler\n    _IMPORT_ERROR = None\nexcept ImportError as exc:  # pragma: no cover - dependency guard\n    LLMHandler = None\n    _IMPORT_ERROR = exc\n\n\n@unittest.skipIf(LLMHandler is None, f\"llm_inference import unavailable: {_IMPORT_ERROR}\")\nclass LlmDistributedCleanupTests(unittest.TestCase):\n    \"\"\"Verify process-group cleanup helper avoids double initialization issues.\"\"\"\n\n    def test_cleanup_destroys_initialized_process_group(self):\n        \"\"\"Cleanup should call destroy when torch.distributed is initialized.\"\"\"\n        handler = LLMHandler()\n        with patch(\"torch.distributed.is_available\", return_value=True), patch(\n            \"torch.distributed.is_initialized\", return_value=True\n        ), patch(\"torch.distributed.destroy_process_group\") as destroy_mock:\n            handler._cleanup_torch_distributed_state()\n        destroy_mock.assert_called_once()\n\n    def test_cleanup_is_noop_when_not_initialized(self):\n        \"\"\"Cleanup should not destroy when process group is not initialized.\"\"\"\n        handler = LLMHandler()\n        with patch(\"torch.distributed.is_available\", return_value=True), patch(\n            \"torch.distributed.is_initialized\", return_value=False\n        ), patch(\"torch.distributed.destroy_process_group\") as destroy_mock:\n            handler._cleanup_torch_distributed_state()\n        destroy_mock.assert_not_called()\n\n\nif __name__ == \"__main__\":\n    unittest.main()\n"
  },
  {
    "path": "acestep/llm_inference_enforce_eager_test.py",
    "content": "\"\"\"Unit tests for enforce_eager logic when flash_attn is unavailable.\n\nRegression test for the bug where CUDA graph capture would fail when\n``flash_attn`` is not installed because the SDPA paged-cache decode path\ncalls ``.item()`` inside the capture region (a forbidden CPU-GPU sync).\n\nWhen flash_attn is absent, nano-vllm must run in ``enforce_eager=True``\n(eager mode, no CUDA graph capture) to avoid corrupting the CUDA context.\n\"\"\"\n\nimport unittest\nfrom unittest.mock import MagicMock, patch\n\ntry:\n    from acestep.llm_inference import LLMHandler\n    _IMPORT_ERROR = None\nexcept ImportError as exc:  # pragma: no cover - dependency guard\n    LLMHandler = None\n    _IMPORT_ERROR = exc\n\n\ndef _make_handler() -> \"LLMHandler\":\n    \"\"\"Return a bare LLMHandler with no models loaded.\"\"\"\n    return LLMHandler()\n\n\ndef _mock_gpu_config():\n    \"\"\"Return a minimal GPU config mock.\"\"\"\n    cfg = MagicMock()\n    cfg.tier = \"high\"\n    cfg.max_duration_with_lm = 60.0\n    return cfg\n\n\n@unittest.skipIf(LLMHandler is None, f\"llm_inference import unavailable: {_IMPORT_ERROR}\")\nclass TestEnforceEagerWhenFlashAttnMissing(unittest.TestCase):\n    \"\"\"Verify that enforce_eager=True is set when flash_attn is not installed.\"\"\"\n\n    def _run_initialize_with_mocks(self, flash_attn_available: bool, device_name: str = \"NVIDIA GeForce RTX 4090\"):\n        \"\"\"Call handler.initialize() with all heavy operations mocked.\n\n        Args:\n            flash_attn_available: Whether flash_attn should appear detectable\n                via ``importlib.util.find_spec``.\n            device_name: Simulated CUDA device name.\n\n        Returns:\n            The ``enforce_eager`` value that was passed to ``_initialize_5hz_lm_vllm``.\n        \"\"\"\n        handler = _make_handler()\n\n        # find_spec returns None when the module is not found, non-None when found.\n        find_spec_return = MagicMock() if flash_attn_available else None\n\n        captured = {}\n\n        def fake_init_vllm(model_path: str, enforce_eager: bool = False) -> str:\n            captured[\"enforce_eager\"] = enforce_eager\n            return \"✅ ok\"\n\n        with patch(\"importlib.util.find_spec\", return_value=find_spec_return), \\\n             patch(\"os.path.exists\", return_value=True), \\\n             patch(\"acestep.llm_inference.AutoTokenizer\") as mock_tok, \\\n             patch(\"acestep.llm_inference.get_global_gpu_config\", return_value=_mock_gpu_config()), \\\n             patch(\"acestep.llm_inference.MetadataConstrainedLogitsProcessor\"), \\\n             patch(\"torch.cuda.is_available\", return_value=True), \\\n             patch(\"torch.cuda.empty_cache\"), \\\n             patch(\"torch.cuda.synchronize\"), \\\n             patch(\"torch.cuda.get_device_name\", return_value=device_name), \\\n             patch.object(handler, \"_initialize_5hz_lm_vllm\", side_effect=fake_init_vllm):\n\n            mock_tok.from_pretrained.return_value = MagicMock()\n            handler.initialize(\n                checkpoint_dir=\"/tmp/fake_ckpt\",\n                lm_model_path=\"model\",\n                backend=\"vllm\",\n                device=\"cuda\",\n            )\n\n        return captured.get(\"enforce_eager\")\n\n    def test_enforce_eager_true_when_flash_attn_missing(self):\n        \"\"\"enforce_eager must be True when flash_attn cannot be found.\"\"\"\n        enforce_eager = self._run_initialize_with_mocks(flash_attn_available=False)\n        self.assertTrue(\n            enforce_eager,\n            \"enforce_eager must be True when flash_attn is not installed to prevent \"\n            \"CUDA graph capture from corrupting the CUDA context via SDPA .item() calls\",\n        )\n\n    def test_enforce_eager_false_when_flash_attn_present(self):\n        \"\"\"enforce_eager must be False when flash_attn is detectable (standard GPU, non-ROCm).\"\"\"\n        enforce_eager = self._run_initialize_with_mocks(flash_attn_available=True)\n        self.assertFalse(\n            enforce_eager,\n            \"enforce_eager should be False on standard CUDA hardware with flash_attn present\",\n        )\n\n    def test_enforce_eager_still_true_for_jetson_even_with_flash_attn(self):\n        \"\"\"Jetson GPUs must still use enforce_eager=True even if flash_attn is detectable.\"\"\"\n        # Jetson is identified by keywords in the device name\n        enforce_eager = self._run_initialize_with_mocks(\n            flash_attn_available=True,\n            device_name=\"Jetson Orin NX 16GB\",\n        )\n        self.assertTrue(\n            enforce_eager,\n            \"enforce_eager must be True on Jetson regardless of flash_attn availability\",\n        )\n\n\nif __name__ == \"__main__\":\n    unittest.main()\n"
  },
  {
    "path": "acestep/local_cache.py",
    "content": "\"\"\"Local cache module to replace Redis\n\nUses diskcache as backend, provides Redis-compatible API.\nSupports persistent storage and TTL expiration.\n\"\"\"\n\nimport json\nimport os\nfrom typing import Any, Optional\nfrom threading import Lock\n\ntry:\n    from diskcache import Cache\n    HAS_DISKCACHE = True\nexcept ImportError:\n    HAS_DISKCACHE = False\n\n\nclass LocalCache:\n    \"\"\"\n    Local cache implementation with Redis-compatible API.\n    Uses diskcache as backend, supports persistence and TTL.\n    \"\"\"\n\n    _instance = None\n    _lock = Lock()\n\n    def __new__(cls, cache_dir: Optional[str] = None):\n        \"\"\"Singleton pattern\"\"\"\n        if cls._instance is None:\n            with cls._lock:\n                if cls._instance is None:\n                    cls._instance = super().__new__(cls)\n                    cls._instance._initialized = False\n        return cls._instance\n\n    def __init__(self, cache_dir: Optional[str] = None):\n        if getattr(self, '_initialized', False):\n            return\n\n        if not HAS_DISKCACHE:\n            raise ImportError(\n                \"diskcache not installed. Run: pip install diskcache\"\n            )\n\n        if cache_dir is None:\n            cache_dir = os.path.join(\n                os.path.dirname(os.path.dirname(__file__)),\n                \".cache\",\n                \"local_redis\"\n            )\n\n        os.makedirs(cache_dir, exist_ok=True)\n        self._cache = Cache(cache_dir)\n        self._initialized = True\n\n    def set(self, name: str, value: Any, ex: Optional[int] = None) -> bool:\n        \"\"\"\n        Set key-value pair\n\n        Args:\n            name: Key name\n            value: Value (auto-serialize dict/list)\n            ex: Expiration time (seconds)\n\n        Returns:\n            bool: Success status\n        \"\"\"\n        if isinstance(value, (dict, list)):\n            value = json.dumps(value, ensure_ascii=False)\n        self._cache.set(name, value, expire=ex)\n        return True\n\n    def get(self, name: str) -> Optional[str]:\n        \"\"\"Get value\"\"\"\n        return self._cache.get(name)\n\n    def delete(self, name: str) -> int:\n        \"\"\"Delete key, returns number of deleted items\"\"\"\n        return 1 if self._cache.delete(name) else 0\n\n    def exists(self, name: str) -> bool:\n        \"\"\"Check if key exists\"\"\"\n        return name in self._cache\n\n    def keys(self, pattern: str = \"*\") -> list:\n        \"\"\"\n        Get list of matching keys\n        Note: Simplified implementation, only supports prefix and full matching\n        \"\"\"\n        if pattern == \"*\":\n            return list(self._cache.iterkeys())\n\n        prefix = pattern.rstrip(\"*\")\n        return [k for k in self._cache.iterkeys() if k.startswith(prefix)]\n\n    def expire(self, name: str, seconds: int) -> bool:\n        \"\"\"Set key expiration time\"\"\"\n        value = self._cache.get(name)\n        if value is not None:\n            self._cache.set(name, value, expire=seconds)\n            return True\n        return False\n\n    def ttl(self, name: str) -> int:\n        \"\"\"\n        Get remaining time to live (seconds)\n        Note: diskcache does not directly support TTL queries\n        \"\"\"\n        if name in self._cache:\n            return -1  # Exists but TTL unknown\n        return -2  # Key does not exist\n\n    def close(self):\n        \"\"\"Close cache connection\"\"\"\n        if hasattr(self, '_cache'):\n            self._cache.close()\n\n\ndef get_local_cache(cache_dir: Optional[str] = None) -> LocalCache:\n    \"\"\"Get or create the global :class:`LocalCache` singleton.\n\n    Thread safety is handled by ``LocalCache.__new__`` which uses\n    double-checked locking via ``cls._lock``, so no additional\n    module-level lock is needed here.\n\n    Note:\n        The ``cache_dir`` is only used on first initialization.  Subsequent\n        calls return the existing singleton regardless of the ``cache_dir``\n        argument.\n    \"\"\"\n    return LocalCache(cache_dir)\n"
  },
  {
    "path": "acestep/local_cache_thread_safety_test.py",
    "content": "\"\"\"Thread safety tests for the local_cache singleton.\"\"\"\n\nimport threading\nimport unittest\n\nfrom acestep.local_cache import LocalCache\n\n\nclass LocalCacheLockTests(unittest.TestCase):\n    \"\"\"Verify LocalCache.__new__ has proper double-checked locking.\"\"\"\n\n    def test_class_level_lock_exists(self):\n        \"\"\"LocalCache._lock must be present for singleton thread safety.\"\"\"\n        self.assertIsInstance(LocalCache._lock, type(threading.Lock()))\n\n\nif __name__ == \"__main__\":\n    unittest.main()\n"
  },
  {
    "path": "acestep/model_downloader.py",
    "content": "\"\"\"\nACE-Step Model Downloader\n\nThis module provides functionality to download models from HuggingFace Hub or ModelScope.\nIt supports automatic downloading when models are not found locally,\nwith intelligent fallback between download sources.\n\"\"\"\n\nimport os\nimport sys\nimport hashlib\nimport shutil\nimport argparse\nfrom typing import Optional, List, Dict, Tuple\nfrom pathlib import Path\n\nfrom loguru import logger\n\n\n# =============================================================================\n# Model Code File Sync (GitHub repo -> checkpoint directories)\n# =============================================================================\n\n# Mapping from checkpoint directory name to source model variant in acestep/models/\n_CHECKPOINT_TO_VARIANT: Dict[str, str] = {\n    \"acestep-v15-turbo\": \"turbo\",\n    \"acestep-v15-sft\": \"sft\",\n    \"acestep-v15-base\": \"base\",\n    # SFT variants (base-SFT uses the same model code as SFT)\n    \"acestep-v15-base-sft-fix-inst\": \"sft\",\n    # Turbo variants all share the turbo model code\n    \"acestep-v15-turbo-shift1\": \"turbo\",\n    \"acestep-v15-turbo-shift3\": \"turbo\",\n    \"acestep-v15-turbo-continuous\": \"turbo\",\n    \"acestep-v15-turbo-fix-inst-shift3\": \"turbo\",\n    \"acestep-v15-turbo-fix-inst-shift-continuous\": \"turbo\",\n    \"acestep-v15-turbo-fix-inst-shift-dynamic\": \"turbo\",\n    \"acestep-v15-turbo-rl\": \"turbo\",\n}\n\n\ndef _get_models_source_dir() -> Path:\n    \"\"\"Get the acestep/models/ directory (authoritative source for model code).\"\"\"\n    return Path(__file__).resolve().parent / \"models\"\n\n\ndef _file_hash(filepath: Path) -> str:\n    \"\"\"Compute SHA-256 hash of a file's contents.\"\"\"\n    h = hashlib.sha256()\n    with open(filepath, \"rb\") as f:\n        for chunk in iter(lambda: f.read(8192), b\"\"):\n            h.update(chunk)\n    return h.hexdigest()\n\n\ndef _check_code_mismatch(model_name: str, checkpoints_dir) -> List[str]:\n    \"\"\"\n    Compare .py files in acestep/models/{variant}/ with those in the checkpoint directory.\n\n    Args:\n        model_name: Checkpoint directory name (e.g. \"acestep-v15-turbo\")\n        checkpoints_dir: Path to the checkpoints root directory\n\n    Returns:\n        List of filenames that differ (empty list if all match or model_name is unknown)\n    \"\"\"\n    variant = _CHECKPOINT_TO_VARIANT.get(model_name)\n    if variant is None:\n        return []\n\n    source_dir = _get_models_source_dir() / variant\n    if not source_dir.exists():\n        return []\n\n    if isinstance(checkpoints_dir, str):\n        checkpoints_dir = Path(checkpoints_dir)\n    target_dir = checkpoints_dir / model_name\n\n    mismatched = []\n    for src_file in source_dir.glob(\"*.py\"):\n        if src_file.name == \"__init__.py\":\n            continue\n        dst_file = target_dir / src_file.name\n        if not dst_file.exists():\n            mismatched.append(src_file.name)\n        elif _file_hash(src_file) != _file_hash(dst_file):\n            mismatched.append(src_file.name)\n\n    return mismatched\n\n\ndef _sync_model_code_files(model_name: str, checkpoints_dir) -> List[str]:\n    \"\"\"\n    Copy .py files from acestep/models/{variant}/ into the checkpoint directory,\n    overwriting the HuggingFace-downloaded versions.\n\n    Args:\n        model_name: Checkpoint directory name (e.g. \"acestep-v15-turbo\")\n        checkpoints_dir: Path to the checkpoints root directory\n\n    Returns:\n        List of filenames that were synced (empty if model_name is unknown or no source)\n    \"\"\"\n    variant = _CHECKPOINT_TO_VARIANT.get(model_name)\n    if variant is None:\n        return []\n\n    source_dir = _get_models_source_dir() / variant\n    if not source_dir.exists():\n        logger.warning(f\"[Model Sync] Source directory not found: {source_dir}\")\n        return []\n\n    if isinstance(checkpoints_dir, str):\n        checkpoints_dir = Path(checkpoints_dir)\n    target_dir = checkpoints_dir / model_name\n    if not target_dir.exists():\n        logger.warning(f\"[Model Sync] Target directory not found: {target_dir}\")\n        return []\n\n    synced = []\n    for src_file in source_dir.glob(\"*.py\"):\n        if src_file.name == \"__init__.py\":\n            continue\n        dst_file = target_dir / src_file.name\n        shutil.copy2(src_file, dst_file)\n        synced.append(src_file.name)\n        logger.debug(f\"[Model Sync] Synced {src_file.name} -> {dst_file}\")\n\n    return synced\n\n\n# =============================================================================\n# Network Detection & Smart Download\n# =============================================================================\n\ndef _can_access_google(timeout: float = 3.0) -> bool:\n    \"\"\"\n    Check if Google is accessible (to determine HuggingFace vs ModelScope).\n\n    Args:\n        timeout: Connection timeout in seconds\n\n    Returns:\n        True if Google is accessible, False otherwise\n    \"\"\"\n    import socket\n    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)\n    try:\n        sock.settimeout(timeout)\n        sock.connect((\"www.google.com\", 443))\n        return True\n    except (socket.timeout, socket.error, OSError):\n        return False\n    finally:\n        sock.close()\n\n\ndef _download_from_huggingface_internal(\n    repo_id: str,\n    local_dir: Path,\n    token: Optional[str] = None,\n) -> None:\n    \"\"\"\n    Internal function to download from HuggingFace Hub.\n\n    Args:\n        repo_id: HuggingFace repository ID (e.g., \"ACE-Step/Ace-Step1.5\")\n        local_dir: Local directory to save the model\n        token: HuggingFace token for private repos (optional)\n\n    Raises:\n        Exception: If download fails\n    \"\"\"\n    from huggingface_hub import snapshot_download\n\n    logger.info(f\"[Model Download] Downloading from HuggingFace: {repo_id} -> {local_dir}\")\n\n    snapshot_download(\n        repo_id=repo_id,\n        local_dir=str(local_dir),\n        local_dir_use_symlinks=False,\n        token=token,\n    )\n\n\ndef _download_from_modelscope_internal(\n    repo_id: str,\n    local_dir: Path,\n) -> None:\n    \"\"\"\n    Internal function to download from ModelScope.\n\n    Args:\n        repo_id: ModelScope repository ID (e.g., \"ACE-Step/Ace-Step1.5\")\n        local_dir: Local directory to save the model\n\n    Raises:\n        Exception: If download fails\n    \"\"\"\n    from modelscope import snapshot_download\n\n    logger.info(f\"[Model Download] Downloading from ModelScope: {repo_id} -> {local_dir}\")\n\n    snapshot_download(\n        model_id=repo_id,\n        local_dir=str(local_dir),\n    )\n\n\ndef _smart_download(\n    repo_id: str,\n    local_dir: Path,\n    token: Optional[str] = None,\n    prefer_source: Optional[str] = None,\n) -> Tuple[bool, str]:\n    \"\"\"\n    Smart download with automatic fallback between HuggingFace and ModelScope.\n\n    Automatically detects network environment and chooses the best download source.\n    If the primary source fails, automatically falls back to the alternative.\n\n    Args:\n        repo_id: Repository ID (same format for both HF and ModelScope)\n        local_dir: Local directory to save the model\n        token: HuggingFace token for private repos (optional)\n        prefer_source: Preferred download source (\"huggingface\", \"modelscope\", or None for auto-detect)\n\n    Returns:\n        Tuple of (success, message)\n    \"\"\"\n    # Ensure directory exists\n    local_dir.mkdir(parents=True, exist_ok=True)\n\n    # Determine primary source\n    if prefer_source == \"huggingface\":\n        use_huggingface_first = True\n        logger.info(\"[Model Download] User preference: HuggingFace Hub\")\n    elif prefer_source == \"modelscope\":\n        use_huggingface_first = False\n        logger.info(\"[Model Download] User preference: ModelScope\")\n    else:\n        # Auto-detect network environment\n        can_access_google = _can_access_google()\n        use_huggingface_first = can_access_google\n        logger.info(f\"[Model Download] Auto-detected: {'HuggingFace Hub' if can_access_google else 'ModelScope'}\")\n\n    if use_huggingface_first:\n        logger.info(\"[Model Download] Using HuggingFace Hub...\")\n        try:\n            _download_from_huggingface_internal(repo_id, local_dir, token)\n            return True, f\"Successfully downloaded from HuggingFace: {repo_id}\"\n        except Exception as e:\n            logger.warning(f\"[Model Download] HuggingFace download failed: {e}\")\n            logger.info(\"[Model Download] Falling back to ModelScope...\")\n            try:\n                _download_from_modelscope_internal(repo_id, local_dir)\n                return True, f\"Successfully downloaded from ModelScope: {repo_id}\"\n            except Exception as e2:\n                error_msg = f\"Both HuggingFace and ModelScope downloads failed. HF: {e}, MS: {e2}\"\n                logger.error(error_msg)\n                return False, error_msg\n    else:\n        logger.info(\"[Model Download] Using ModelScope...\")\n        try:\n            _download_from_modelscope_internal(repo_id, local_dir)\n            return True, f\"Successfully downloaded from ModelScope: {repo_id}\"\n        except Exception as e:\n            logger.warning(f\"[Model Download] ModelScope download failed: {e}\")\n            logger.info(\"[Model Download] Falling back to HuggingFace Hub...\")\n            try:\n                _download_from_huggingface_internal(repo_id, local_dir, token)\n                return True, f\"Successfully downloaded from HuggingFace: {repo_id}\"\n            except Exception as e2:\n                error_msg = f\"Both ModelScope and HuggingFace downloads failed. MS: {e}, HF: {e2}\"\n                logger.error(error_msg)\n                return False, error_msg\n\n\n# =============================================================================\n# Model Registry\n# =============================================================================\n# Main model contains core components (vae, text_encoder, default DiT)\nMAIN_MODEL_REPO = \"ACE-Step/Ace-Step1.5\"\n\n# Sub-models that can be downloaded separately into the checkpoints directory\nSUBMODEL_REGISTRY: Dict[str, str] = {\n    # LM models\n    \"acestep-5Hz-lm-0.6B\": \"ACE-Step/acestep-5Hz-lm-0.6B\",\n    \"acestep-5Hz-lm-4B\": \"ACE-Step/acestep-5Hz-lm-4B\",\n    # DiT models\n    \"acestep-v15-turbo-shift3\": \"ACE-Step/acestep-v15-turbo-shift3\",\n    \"acestep-v15-sft\": \"ACE-Step/acestep-v15-sft\",\n    \"acestep-v15-base\": \"ACE-Step/acestep-v15-base\",\n    \"acestep-v15-turbo-shift1\": \"ACE-Step/acestep-v15-turbo-shift1\",\n    \"acestep-v15-turbo-continuous\": \"ACE-Step/acestep-v15-turbo-continuous\",\n}\n\n# Components that come from the main model repo (ACE-Step/Ace-Step1.5)\nMAIN_MODEL_COMPONENTS = [\n    \"acestep-v15-turbo\",      # Default DiT model\n    \"vae\",                     # VAE for audio encoding/decoding\n    \"Qwen3-Embedding-0.6B\",    # Text encoder\n    \"acestep-5Hz-lm-1.7B\",     # Default LM model (1.7B)\n]\n\n# Default LM model (included in main model)\nDEFAULT_LM_MODEL = \"acestep-5Hz-lm-1.7B\"\n\n\ndef get_project_root() -> Path:\n    \"\"\"Get the project root directory.\n\n    Returns the directory set by the ``ACESTEP_PROJECT_ROOT`` environment\n    variable when present, otherwise the current working directory.  Using\n    the working directory (rather than ``__file__``) keeps the checkpoints\n    folder next to where the user launched the process, regardless of whether\n    the package was installed via ``pip install .`` or run from source.\n    \"\"\"\n    env_root = os.environ.get(\"ACESTEP_PROJECT_ROOT\")\n    if env_root:\n        return Path(env_root).resolve()\n    return Path(os.getcwd())\n\n\ndef get_checkpoints_dir(custom_dir: Optional[str] = None) -> Path:\n    \"\"\"Get the checkpoints directory path.\"\"\"\n    if custom_dir:\n        return Path(custom_dir)\n    return get_project_root() / \"checkpoints\"\n\n\ndef _contains_model_weights(model_path: Path) -> bool:\n    \"\"\"Return whether a model directory contains at least one weights artifact.\n\n    Args:\n        model_path: Candidate model directory path.\n\n    Returns:\n        `True` when a known model weights file exists in the directory.\n    \"\"\"\n    weight_filenames = (\n        \"model.safetensors\",\n        \"model.safetensors.index.json\",\n        \"pytorch_model.bin\",\n        \"pytorch_model.bin.index.json\",\n        \"diffusion_pytorch_model.safetensors\",\n        \"diffusion_pytorch_model.safetensors.index.json\",\n        \"diffusion_pytorch_model.bin\",\n        \"diffusion_pytorch_model.bin.index.json\",\n    )\n    if not model_path.is_dir():\n        return False\n    return any((model_path / filename).exists() for filename in weight_filenames)\n\n\ndef check_main_model_exists(checkpoints_dir: Optional[Path] = None) -> bool:\n    \"\"\"\n    Check if the main model components exist in the checkpoints directory.\n\n    Returns:\n        True if all main model components contain weights, False otherwise.\n    \"\"\"\n    if checkpoints_dir is None:\n        checkpoints_dir = get_checkpoints_dir()\n    elif isinstance(checkpoints_dir, str):\n        checkpoints_dir = Path(checkpoints_dir)\n\n    for component in MAIN_MODEL_COMPONENTS:\n        component_path = checkpoints_dir / component\n        if not _contains_model_weights(component_path):\n            return False\n    return True\n\n\ndef check_model_exists(model_name: str, checkpoints_dir: Optional[Path] = None) -> bool:\n    \"\"\"\n    Check if a specific model exists in the checkpoints directory.\n    \n    Args:\n        model_name: Name of the model to check\n        checkpoints_dir: Custom checkpoints directory (optional)\n    \n    Returns:\n        True if the model exists, False otherwise.\n    \"\"\"\n    if not model_name:\n        logger.warning(\"[check_model_exists] Empty model_name; treating as missing.\")\n        return False\n    if checkpoints_dir is None:\n        checkpoints_dir = get_checkpoints_dir()\n    elif isinstance(checkpoints_dir, str):\n        checkpoints_dir = Path(checkpoints_dir)\n\n    model_path = checkpoints_dir / model_name\n    return _contains_model_weights(model_path)\n\n\ndef list_available_models() -> Dict[str, str]:\n    \"\"\"\n    List all available models for download.\n    \n    Returns:\n        Dictionary mapping local names to HuggingFace repo IDs.\n    \"\"\"\n    models = {\n        \"main\": MAIN_MODEL_REPO,\n        **SUBMODEL_REGISTRY\n    }\n    return models\n\n\ndef download_main_model(\n    checkpoints_dir: Optional[Path] = None,\n    force: bool = False,\n    token: Optional[str] = None,\n    prefer_source: Optional[str] = None,\n) -> Tuple[bool, str]:\n    \"\"\"\n    Download the main ACE-Step model from HuggingFace or ModelScope.\n\n    The main model includes:\n    - acestep-v15-turbo (default DiT model)\n    - vae (audio encoder/decoder)\n    - Qwen3-Embedding-0.6B (text encoder)\n    - acestep-5Hz-lm-1.7B (default LM model)\n\n    Args:\n        checkpoints_dir: Custom checkpoints directory (optional)\n        force: Force re-download even if model exists\n        token: HuggingFace token for private repos (optional)\n        prefer_source: Preferred download source (\"huggingface\", \"modelscope\", or None for auto-detect)\n\n    Returns:\n        Tuple of (success, message)\n    \"\"\"\n    if checkpoints_dir is None:\n        checkpoints_dir = get_checkpoints_dir()\n    elif isinstance(checkpoints_dir, str):\n        checkpoints_dir = Path(checkpoints_dir)\n\n    # Ensure checkpoints directory exists\n    checkpoints_dir.mkdir(parents=True, exist_ok=True)\n\n    if not force and check_main_model_exists(checkpoints_dir):\n        return True, f\"Main model already exists at {checkpoints_dir}\"\n\n    print(f\"Downloading main model from {MAIN_MODEL_REPO}...\")\n    print(f\"Destination: {checkpoints_dir}\")\n    print(\"This may take a while depending on your internet connection...\")\n\n    # Use smart download with automatic fallback\n    success, msg = _smart_download(MAIN_MODEL_REPO, checkpoints_dir, token, prefer_source)\n    if success:\n        # Sync model code files for all DiT components in the main model\n        for component in MAIN_MODEL_COMPONENTS:\n            if component in _CHECKPOINT_TO_VARIANT:\n                synced = _sync_model_code_files(component, checkpoints_dir)\n                if synced:\n                    logger.info(f\"[Model Download] Synced code files for {component}: {synced}\")\n    return success, msg\n\n\ndef download_submodel(\n    model_name: str,\n    checkpoints_dir: Optional[Path] = None,\n    force: bool = False,\n    token: Optional[str] = None,\n    prefer_source: Optional[str] = None,\n) -> Tuple[bool, str]:\n    \"\"\"\n    Download a specific sub-model from HuggingFace or ModelScope.\n\n    Args:\n        model_name: Name of the model to download (must be in SUBMODEL_REGISTRY)\n        checkpoints_dir: Custom checkpoints directory (optional)\n        force: Force re-download even if model exists\n        token: HuggingFace token for private repos (optional)\n        prefer_source: Preferred download source (\"huggingface\", \"modelscope\", or None for auto-detect)\n\n    Returns:\n        Tuple of (success, message)\n    \"\"\"\n    if model_name not in SUBMODEL_REGISTRY:\n        available = \", \".join(SUBMODEL_REGISTRY.keys())\n        return False, f\"Unknown model '{model_name}'. Available models: {available}\"\n\n    if checkpoints_dir is None:\n        checkpoints_dir = get_checkpoints_dir()\n    elif isinstance(checkpoints_dir, str):\n        checkpoints_dir = Path(checkpoints_dir)\n\n    # Ensure checkpoints directory exists\n    checkpoints_dir.mkdir(parents=True, exist_ok=True)\n\n    model_path = checkpoints_dir / model_name\n\n    if not force and model_path.exists():\n        return True, f\"Model '{model_name}' already exists at {model_path}\"\n\n    repo_id = SUBMODEL_REGISTRY[model_name]\n\n    print(f\"Downloading {model_name} from {repo_id}...\")\n    print(f\"Destination: {model_path}\")\n\n    # Use smart download with automatic fallback\n    success, msg = _smart_download(repo_id, model_path, token, prefer_source)\n    if success and model_name in _CHECKPOINT_TO_VARIANT:\n        # Sync model code files after successful download\n        synced = _sync_model_code_files(model_name, checkpoints_dir)\n        if synced:\n            logger.info(f\"[Model Download] Synced code files for {model_name}: {synced}\")\n    return success, msg\n\n\ndef download_all_models(\n    checkpoints_dir: Optional[Path] = None,\n    force: bool = False,\n    token: Optional[str] = None,\n) -> Tuple[bool, List[str]]:\n    \"\"\"\n    Download all available models.\n    \n    Args:\n        checkpoints_dir: Custom checkpoints directory (optional)\n        force: Force re-download even if models exist\n        token: HuggingFace token for private repos (optional)\n    \n    Returns:\n        Tuple of (all_success, list of messages)\n    \"\"\"\n    if checkpoints_dir is None:\n        checkpoints_dir = get_checkpoints_dir()\n    elif isinstance(checkpoints_dir, str):\n        checkpoints_dir = Path(checkpoints_dir)\n\n    messages = []\n    all_success = True\n    \n    # Download main model first\n    success, msg = download_main_model(checkpoints_dir, force, token)\n    messages.append(msg)\n    if not success:\n        all_success = False\n    \n    # Download all sub-models\n    for model_name in SUBMODEL_REGISTRY:\n        success, msg = download_submodel(model_name, checkpoints_dir, force, token)\n        messages.append(msg)\n        if not success:\n            all_success = False\n    \n    return all_success, messages\n\n\ndef ensure_main_model(\n    checkpoints_dir: Optional[Path] = None,\n    token: Optional[str] = None,\n    prefer_source: Optional[str] = None,\n) -> Tuple[bool, str]:\n    \"\"\"\n    Ensure the main model is available, downloading if necessary.\n\n    This function is designed to be called during initialization.\n    It will only download if the model doesn't exist.\n\n    Args:\n        checkpoints_dir: Custom checkpoints directory (optional)\n        token: HuggingFace token for private repos (optional)\n        prefer_source: Preferred download source (\"huggingface\", \"modelscope\", or None for auto-detect)\n\n    Returns:\n        Tuple of (success, message)\n    \"\"\"\n    if checkpoints_dir is None:\n        checkpoints_dir = get_checkpoints_dir()\n\n    if check_main_model_exists(checkpoints_dir):\n        return True, \"Main model is available\"\n\n    print(\"\\n\" + \"=\" * 60)\n    print(\"Main model not found. Starting automatic download...\")\n    print(\"=\" * 60 + \"\\n\")\n\n    return download_main_model(checkpoints_dir, token=token, prefer_source=prefer_source)\n\n\ndef ensure_lm_model(\n    model_name: Optional[str] = None,\n    checkpoints_dir: Optional[Path] = None,\n    token: Optional[str] = None,\n    prefer_source: Optional[str] = None,\n) -> Tuple[bool, str]:\n    \"\"\"\n    Ensure an LM model is available, downloading if necessary.\n\n    Args:\n        model_name: Name of the LM model (defaults to DEFAULT_LM_MODEL)\n        checkpoints_dir: Custom checkpoints directory (optional)\n        token: HuggingFace token for private repos (optional)\n        prefer_source: Preferred download source (\"huggingface\", \"modelscope\", or None for auto-detect)\n\n    Returns:\n        Tuple of (success, message)\n    \"\"\"\n    if model_name is None:\n        model_name = DEFAULT_LM_MODEL\n\n    if checkpoints_dir is None:\n        checkpoints_dir = get_checkpoints_dir()\n    elif isinstance(checkpoints_dir, str):\n        checkpoints_dir = Path(checkpoints_dir)\n\n    if check_model_exists(model_name, checkpoints_dir):\n        return True, f\"LM model '{model_name}' is available\"\n\n    # Check if this is a known LM model\n    if model_name not in SUBMODEL_REGISTRY:\n        # Check if it might be a variant name\n        for known_model in SUBMODEL_REGISTRY:\n            if \"lm\" in known_model.lower() and model_name.lower() in known_model.lower():\n                model_name = known_model\n                break\n        else:\n            return False, f\"Unknown LM model: {model_name}\"\n\n    print(\"\\n\" + \"=\" * 60)\n    print(f\"LM model '{model_name}' not found. Starting automatic download...\")\n    print(\"=\" * 60 + \"\\n\")\n\n    return download_submodel(model_name, checkpoints_dir, token=token, prefer_source=prefer_source)\n\n\ndef ensure_dit_model(\n    model_name: str,\n    checkpoints_dir: Optional[Path] = None,\n    token: Optional[str] = None,\n    prefer_source: Optional[str] = None,\n) -> Tuple[bool, str]:\n    \"\"\"\n    Ensure a DiT model is available, downloading if necessary.\n\n    Args:\n        model_name: Name of the DiT model\n        checkpoints_dir: Custom checkpoints directory (optional)\n        token: HuggingFace token for private repos (optional)\n        prefer_source: Preferred download source (\"huggingface\", \"modelscope\", or None for auto-detect)\n\n    Returns:\n        Tuple of (success, message)\n    \"\"\"\n    if checkpoints_dir is None:\n        checkpoints_dir = get_checkpoints_dir()\n    elif isinstance(checkpoints_dir, str):\n        checkpoints_dir = Path(checkpoints_dir)\n\n    if check_model_exists(model_name, checkpoints_dir):\n        return True, f\"DiT model '{model_name}' is available\"\n\n    # Check if this is the default turbo model (part of main)\n    if model_name == \"acestep-v15-turbo\":\n        return ensure_main_model(checkpoints_dir, token, prefer_source)\n\n    # Check if it's a known sub-model\n    if model_name in SUBMODEL_REGISTRY:\n        print(\"\\n\" + \"=\" * 60)\n        print(f\"DiT model '{model_name}' not found. Starting automatic download...\")\n        print(\"=\" * 60 + \"\\n\")\n        return download_submodel(model_name, checkpoints_dir, token=token, prefer_source=prefer_source)\n\n    if not model_name:\n        return False, \"Unknown DiT model: '' (pass None for default or choose a valid model)\"\n    return False, f\"Unknown DiT model: {model_name}\"\n\n\ndef print_model_list():\n    \"\"\"Print formatted list of available models.\"\"\"\n    print(\"\\nAvailable Models for Download:\")\n    print(\"=\" * 60)\n    print(\"\\nSupported Sources: HuggingFace Hub <-> ModelScope (auto-fallback)\")\n\n    print(\"\\n[Main Model]\")\n    print(f\"  main -> {MAIN_MODEL_REPO}\")\n    print(\"  Contains: vae, Qwen3-Embedding-0.6B, acestep-v15-turbo, acestep-5Hz-lm-1.7B\")\n\n    print(\"\\n[Optional LM Models]\")\n    for name, repo in SUBMODEL_REGISTRY.items():\n        if \"lm\" in name.lower():\n            print(f\"  {name} -> {repo}\")\n\n    print(\"\\n[Optional DiT Models]\")\n    for name, repo in SUBMODEL_REGISTRY.items():\n        if \"lm\" not in name.lower():\n            print(f\"  {name} -> {repo}\")\n\n    print(\"\\n\" + \"=\" * 60)\n\n\ndef main():\n    \"\"\"CLI entry point for model downloading.\"\"\"\n    parser = argparse.ArgumentParser(\n        description=\"Download ACE-Step models with automatic fallback (HuggingFace <-> ModelScope)\",\n        formatter_class=argparse.RawDescriptionHelpFormatter,\n        epilog=\"\"\"\nExamples:\n  acestep-download                          # Download main model (includes LM 1.7B)\n  acestep-download --all                    # Download all available models\n  acestep-download --model acestep-v15-sft  # Download a specific model\n  acestep-download --list                   # List all available models\n\nNetwork Detection:\n  Automatically detects network environment and chooses the best download source:\n  - Google accessible -> HuggingFace (fallback to ModelScope)\n  - Google blocked -> ModelScope (fallback to HuggingFace)\n\nAlternative using huggingface-cli:\n  huggingface-cli download ACE-Step/Ace-Step1.5 --local-dir ./checkpoints\n  huggingface-cli download ACE-Step/acestep-5Hz-lm-0.6B --local-dir ./checkpoints/acestep-5Hz-lm-0.6B\n        \"\"\"\n    )\n    \n    parser.add_argument(\n        \"--model\", \"-m\",\n        type=str,\n        help=\"Specific model to download (use --list to see available models)\"\n    )\n    parser.add_argument(\n        \"--all\", \"-a\",\n        action=\"store_true\",\n        help=\"Download all available models\"\n    )\n    parser.add_argument(\n        \"--list\", \"-l\",\n        action=\"store_true\",\n        help=\"List all available models\"\n    )\n    parser.add_argument(\n        \"--dir\", \"-d\",\n        type=str,\n        default=None,\n        help=\"Custom checkpoints directory (default: ./checkpoints)\"\n    )\n    parser.add_argument(\n        \"--force\", \"-f\",\n        action=\"store_true\",\n        help=\"Force re-download even if model exists\"\n    )\n    parser.add_argument(\n        \"--token\", \"-t\",\n        type=str,\n        default=None,\n        help=\"HuggingFace token for private repos\"\n    )\n    parser.add_argument(\n        \"--skip-main\",\n        action=\"store_true\",\n        help=\"Skip downloading the main model (only download specified sub-model)\"\n    )\n    \n    args = parser.parse_args()\n    \n    # Handle --list\n    if args.list:\n        print_model_list()\n        return 0\n    \n    # Get checkpoints directory\n    checkpoints_dir = get_checkpoints_dir(args.dir) if args.dir else get_checkpoints_dir()\n    print(f\"Checkpoints directory: {checkpoints_dir}\")\n    \n    # Handle --all\n    if args.all:\n        success, messages = download_all_models(checkpoints_dir, args.force, args.token)\n        for msg in messages:\n            print(msg)\n        return 0 if success else 1\n    \n    # Handle --model\n    if args.model:\n        if args.model == \"main\":\n            success, msg = download_main_model(checkpoints_dir, args.force, args.token)\n        elif args.model in SUBMODEL_REGISTRY:\n            # Download main model first if needed (unless --skip-main)\n            if not args.skip_main and not check_main_model_exists(checkpoints_dir):\n                print(\"Main model not found. Downloading main model first...\")\n                main_success, main_msg = download_main_model(checkpoints_dir, args.force, args.token)\n                print(main_msg)\n                if not main_success:\n                    return 1\n            \n            success, msg = download_submodel(args.model, checkpoints_dir, args.force, args.token)\n        else:\n            print(f\"Unknown model: {args.model}\")\n            print(\"Use --list to see available models\")\n            return 1\n        \n        print(msg)\n        return 0 if success else 1\n    \n    # Default: download main model (includes default LM 1.7B)\n    print(\"Downloading main model (includes vae, text encoder, DiT, and LM 1.7B)...\")\n    \n    # Download main model\n    success, msg = download_main_model(checkpoints_dir, args.force, args.token)\n    print(msg)\n    \n    if success:\n        print(\"\\nDownload complete!\")\n        print(f\"Models are available at: {checkpoints_dir}\")\n    \n    return 0 if success else 1\n\n\nif __name__ == \"__main__\":\n    sys.exit(main())\n"
  },
  {
    "path": "acestep/model_downloader_test.py",
    "content": "\"\"\"Unit tests for model_downloader.get_project_root and get_checkpoints_dir.\"\"\"\n\nimport importlib.util\nimport os\nimport sys\nimport tempfile\nimport unittest\nfrom pathlib import Path\nfrom unittest.mock import patch\n\n\ndef _load_module():\n    \"\"\"Load model_downloader directly without importing heavy dependencies.\"\"\"\n    spec = importlib.util.spec_from_file_location(\n        \"model_downloader\",\n        os.path.join(os.path.dirname(__file__), \"model_downloader.py\"),\n    )\n    mod = importlib.util.module_from_spec(spec)\n    spec.loader.exec_module(mod)\n    return mod\n\n\nclass TestGetProjectRoot(unittest.TestCase):\n    \"\"\"Tests for model_downloader.get_project_root().\"\"\"\n\n    @classmethod\n    def setUpClass(cls):\n        cls.mod = _load_module()\n\n    def test_returns_cwd_by_default(self):\n        \"\"\"get_project_root returns the current working directory when no env var is set.\"\"\"\n        env = {k: v for k, v in os.environ.items() if k != \"ACESTEP_PROJECT_ROOT\"}\n        with patch.dict(os.environ, env, clear=True):\n            result = self.mod.get_project_root()\n        self.assertEqual(result, Path(os.getcwd()))\n\n    def test_returns_env_var_when_set(self):\n        \"\"\"get_project_root returns the ACESTEP_PROJECT_ROOT path when the env var is set.\"\"\"\n        with tempfile.TemporaryDirectory() as tmp_dir:\n            with patch.dict(os.environ, {\"ACESTEP_PROJECT_ROOT\": tmp_dir}):\n                result = self.mod.get_project_root()\n            self.assertEqual(result, Path(tmp_dir).resolve())\n\n    def test_env_var_takes_precedence_over_cwd(self):\n        \"\"\"ACESTEP_PROJECT_ROOT overrides the current working directory.\"\"\"\n        with tempfile.TemporaryDirectory() as tmp_dir:\n            with patch.dict(os.environ, {\"ACESTEP_PROJECT_ROOT\": tmp_dir}):\n                result = self.mod.get_project_root()\n            self.assertNotEqual(result, Path(os.getcwd()))\n            self.assertEqual(result, Path(tmp_dir).resolve())\n\n    def test_does_not_derive_path_from_package_file(self):\n        \"\"\"get_project_root must not return a __file__-derived path (site-packages fix).\"\"\"\n        env = {k: v for k, v in os.environ.items() if k != \"ACESTEP_PROJECT_ROOT\"}\n        with patch.dict(os.environ, env, clear=True):\n            result = self.mod.get_project_root()\n        # The old __file__-based path would be the parent of the parent of model_downloader.py\n        old_style_path = Path(os.path.abspath(__file__)).parent.parent\n        # The current test is running with CWD == project root, so they happen to be equal\n        # here; what matters is the returned path equals CWD, not the module file ancestor.\n        self.assertEqual(result, Path(os.getcwd()))\n\n\nclass TestGetCheckpointsDir(unittest.TestCase):\n    \"\"\"Tests for model_downloader.get_checkpoints_dir().\"\"\"\n\n    @classmethod\n    def setUpClass(cls):\n        cls.mod = _load_module()\n\n    def test_default_is_checkpoints_under_cwd(self):\n        \"\"\"get_checkpoints_dir returns <cwd>/checkpoints when no custom dir or env var is set.\"\"\"\n        env = {k: v for k, v in os.environ.items() if k != \"ACESTEP_PROJECT_ROOT\"}\n        with patch.dict(os.environ, env, clear=True):\n            result = self.mod.get_checkpoints_dir()\n        self.assertEqual(result, Path(os.getcwd()) / \"checkpoints\")\n\n    def test_custom_dir_overrides_default(self):\n        \"\"\"get_checkpoints_dir returns the custom_dir when explicitly provided.\"\"\"\n        with tempfile.TemporaryDirectory() as tmp_dir:\n            result = self.mod.get_checkpoints_dir(custom_dir=tmp_dir)\n        self.assertEqual(result, Path(tmp_dir))\n\n    def test_env_var_is_honoured_as_root(self):\n        \"\"\"get_checkpoints_dir appends 'checkpoints' to ACESTEP_PROJECT_ROOT when set.\"\"\"\n        with tempfile.TemporaryDirectory() as tmp_dir:\n            with patch.dict(os.environ, {\"ACESTEP_PROJECT_ROOT\": tmp_dir}):\n                result = self.mod.get_checkpoints_dir()\n            self.assertEqual(result, Path(tmp_dir).resolve() / \"checkpoints\")\n\nclass TestCheckMainModelExists(unittest.TestCase):\n    \"\"\"Tests for model_downloader.check_main_model_exists().\"\"\"\n\n    @classmethod\n    def setUpClass(cls):\n        cls.mod = _load_module()\n\n    def test_returns_false_when_any_component_lacks_weights(self):\n        \"\"\"check_main_model_exists rejects partial main-model component directories.\"\"\"\n        with tempfile.TemporaryDirectory() as tmp_dir:\n            checkpoints_dir = Path(tmp_dir)\n            for component in self.mod.MAIN_MODEL_COMPONENTS:\n                component_dir = checkpoints_dir / component\n                component_dir.mkdir()\n                (component_dir / \"configuration.json\").write_text(\"{}\", encoding=\"utf-8\")\n\n            result = self.mod.check_main_model_exists(checkpoints_dir)\n\n        self.assertFalse(result)\n\n    def test_returns_true_when_all_components_have_weights(self):\n        \"\"\"check_main_model_exists accepts main-model components with weights present.\"\"\"\n        with tempfile.TemporaryDirectory() as tmp_dir:\n            checkpoints_dir = Path(tmp_dir)\n            for component in self.mod.MAIN_MODEL_COMPONENTS:\n                component_dir = checkpoints_dir / component\n                component_dir.mkdir()\n                (component_dir / \"model.safetensors\").write_text(\"weights\", encoding=\"utf-8\")\n\n            result = self.mod.check_main_model_exists(checkpoints_dir)\n\n        self.assertTrue(result)\n\n    def test_returns_true_when_vae_uses_diffusers_weight_filename(self):\n        \"\"\"check_main_model_exists accepts the current Diffusers-style VAE checkpoint filename.\"\"\"\n        with tempfile.TemporaryDirectory() as tmp_dir:\n            checkpoints_dir = Path(tmp_dir)\n            for component in self.mod.MAIN_MODEL_COMPONENTS:\n                component_dir = checkpoints_dir / component\n                component_dir.mkdir()\n                weight_filename = \"model.safetensors\"\n                if component == \"vae\":\n                    weight_filename = \"diffusion_pytorch_model.safetensors\"\n                (component_dir / weight_filename).write_text(\"weights\", encoding=\"utf-8\")\n\n            result = self.mod.check_main_model_exists(checkpoints_dir)\n\n        self.assertTrue(result)\n\n\nclass TestCheckModelExists(unittest.TestCase):\n    \"\"\"Tests for model_downloader.check_model_exists().\"\"\"\n\n    @classmethod\n    def setUpClass(cls):\n        cls.mod = _load_module()\n\n    def test_returns_false_for_partial_model_directory_without_weights(self):\n        \"\"\"check_model_exists rejects directories that only contain synced code files.\"\"\"\n        with tempfile.TemporaryDirectory() as tmp_dir:\n            model_dir = Path(tmp_dir) / \"acestep-v15-turbo\"\n            model_dir.mkdir()\n            (model_dir / \"configuration_acestep_v15.py\").write_text(\n                \"# synced code only\\n\",\n                encoding=\"utf-8\",\n            )\n\n            result = self.mod.check_model_exists(\"acestep-v15-turbo\", Path(tmp_dir))\n\n        self.assertFalse(result)\n\n    def test_returns_true_when_model_weights_are_present(self):\n        \"\"\"check_model_exists accepts directories that contain a weights artifact.\"\"\"\n        with tempfile.TemporaryDirectory() as tmp_dir:\n            model_dir = Path(tmp_dir) / \"acestep-v15-turbo\"\n            model_dir.mkdir()\n            (model_dir / \"model.safetensors\").write_text(\"weights\", encoding=\"utf-8\")\n\n            result = self.mod.check_model_exists(\"acestep-v15-turbo\", Path(tmp_dir))\n\n        self.assertTrue(result)\n\n\nif __name__ == \"__main__\":\n    unittest.main()\n"
  },
  {
    "path": "acestep/models/__init__.py",
    "content": "# ACE-Step model definitions\n# These files are the authoritative source for model code.\n# They are auto-synced to checkpoint directories on startup.\n"
  },
  {
    "path": "acestep/models/base/__init__.py",
    "content": ""
  },
  {
    "path": "acestep/models/base/apg_guidance.py",
    "content": "import torch\nimport torch.nn.functional as F\n\n\nclass MomentumBuffer:\n\n    def __init__(self, momentum: float = -0.75):\n        self.momentum = momentum\n        self.running_average = 0\n\n    def update(self, update_value: torch.Tensor):\n        new_average = self.momentum * self.running_average\n        self.running_average = update_value + new_average\n\n\ndef project(\n    v0: torch.Tensor,  # [B, C, T]\n    v1: torch.Tensor,  # [B, C, T]\n    dims=[-1],\n):\n    dtype = v0.dtype\n    device_type = v0.device.type\n    if device_type == \"mps\":\n        v0, v1 = v0.cpu(), v1.cpu()\n\n    v0, v1 = v0.double(), v1.double()\n    v1 = torch.nn.functional.normalize(v1, dim=dims)\n    v0_parallel = (v0 * v1).sum(dim=dims, keepdim=True) * v1\n    v0_orthogonal = v0 - v0_parallel\n    return v0_parallel.to(dtype).to(device_type), v0_orthogonal.to(dtype).to(device_type)\n\n\ndef apg_forward(\n    pred_cond: torch.Tensor,  # [B, C, T]\n    pred_uncond: torch.Tensor,  # [B, C, T]\n    guidance_scale: float,\n    momentum_buffer: MomentumBuffer = None,\n    eta: float = 0.0,\n    norm_threshold: float = 2.5,\n    dims=[-1],\n):\n    diff = pred_cond - pred_uncond\n    if momentum_buffer is not None:\n        momentum_buffer.update(diff)\n        diff = momentum_buffer.running_average\n\n    if norm_threshold > 0:\n        ones = torch.ones_like(diff)\n        diff_norm = diff.norm(p=2, dim=dims, keepdim=True)\n        scale_factor = torch.minimum(ones, norm_threshold / diff_norm)\n        diff = diff * scale_factor\n\n    diff_parallel, diff_orthogonal = project(diff, pred_cond, dims)\n    normalized_update = diff_orthogonal + eta * diff_parallel\n    pred_guided = pred_cond + (guidance_scale - 1) * normalized_update\n    return pred_guided\n\n\ndef cfg_forward(cond_output, uncond_output, cfg_strength):\n    return uncond_output + cfg_strength * (cond_output - uncond_output)\n\n\ndef call_cos_tensor(tensor1, tensor2):\n    \"\"\"\n    Calculate cosine similarity between two normalized tensors.\n\n    Args:\n        tensor1: First tensor [B, ...]\n        tensor2: Second tensor [B, ...]\n\n    Returns:\n        Cosine similarity value [B, 1]\n    \"\"\"\n    tensor1 = tensor1 / torch.linalg.norm(tensor1, dim=1, keepdim=True)\n    tensor2 = tensor2 / torch.linalg.norm(tensor2, dim=1, keepdim=True)\n    cosvalue = torch.sum(tensor1 * tensor2, dim=1, keepdim=True)\n    return cosvalue\n\n\ndef compute_perpendicular_component(latent_diff, latent_hat_uncond):\n    \"\"\"\n    Decompose latent_diff into parallel and perpendicular components relative to latent_hat_uncond.\n\n    Args:\n        latent_diff: Difference tensor [B, C, ...]\n        latent_hat_uncond: Unconditional prediction tensor [B, C, ...]\n\n    Returns:\n        projection: Parallel component\n        perpendicular_component: Perpendicular component\n    \"\"\"\n    n, t, c = latent_diff.shape\n    latent_diff = latent_diff.view(n * t, c).float()\n    latent_hat_uncond = latent_hat_uncond.view(n * t, c).float()\n\n    if latent_diff.size() != latent_hat_uncond.size():\n        raise ValueError(\"latent_diff and latent_hat_uncond must have the same shape [n, d].\")\n\n    dot_product = torch.sum(latent_diff * latent_hat_uncond, dim=1, keepdim=True)  # [n, 1]\n    norm_square = torch.sum(latent_hat_uncond * latent_hat_uncond, dim=1, keepdim=True)  # [n, 1]\n    projection = (dot_product / (norm_square + 1e-8)) * latent_hat_uncond\n    perpendicular_component = latent_diff - projection\n\n    return projection.view(n, t, c), perpendicular_component.reshape(n, t, c)\n\n\ndef adg_forward(\n    latents: torch.Tensor,\n    noise_pred_cond: torch.Tensor,\n    noise_pred_uncond: torch.Tensor,\n    sigma: torch.Tensor,\n    guidance_scale: float,\n    angle_clip: float = 3.14 / 6,  # pi/6 by default\n    apply_norm: bool = False,\n    apply_clip: bool = True,\n):\n    \"\"\"\n    ADG (Angle-based Dynamic Guidance) forward pass for Flow Matching.\n\n    In flow matching (including SD3), sigma represents the current timestep t_curr.\n    The predictions are velocity fields v(x_t, t).\n\n    Args:\n        latents: Current state x_t [N, T, d] where d=64\n        noise_pred_cond: Conditional velocity prediction v_cond [N, T, d]\n        noise_pred_uncond: Unconditional velocity prediction v_uncond [N, T, d]\n        sigma: Current timestep t_curr (not t_prev!)\n        guidance_scale: Guidance strength\n        angle_clip: Maximum angle for clipping (default: pi/6)\n        apply_norm: Whether to normalize the result (ADG_w_norm variant)\n        apply_clip: Whether to clip the angle (ADG_wo_clip when False)\n\n    Returns:\n        Guided velocity prediction [N, T, d]\n    \"\"\"\n    if latents.shape[1] != noise_pred_cond.shape[1]:\n        if noise_pred_cond.shape[1] % latents.shape[1] != 0:\n            raise ValueError(\"noise_pred_cond time dimension must be a whole-number multiple of latents time dimension.\")\n        repeats = noise_pred_cond.shape[1] // latents.shape[1]\n        latents = latents.repeat_interleave(repeats, dim=1)\n\n    # Get batch size\n    n = noise_pred_cond.shape[0]\n    noise_pred_text = noise_pred_cond\n    n, t, c = noise_pred_text.shape\n\n    # Ensure sigma/t has the right shape for broadcasting [N, 1, 1]\n    if isinstance(sigma, (int, float)):\n        sigma = torch.tensor(sigma, device=latents.device, dtype=latents.dtype)\n        sigma = sigma.view(1, 1, 1).expand(n, 1, 1)\n    elif torch.is_tensor(sigma):\n        if sigma.numel() == 1:\n            sigma = sigma.view(1, 1, 1).expand(n, 1, 1)\n        elif sigma.numel() == n:\n            sigma = sigma.view(n, 1, 1)\n        else:\n            raise ValueError(f\"sigma has incompatible shape. Expected scalar or size {n}, got {sigma.shape}\")\n    else:\n        raise TypeError(f\"sigma must be a number or tensor, got {type(sigma)}\")\n\n    # Adjust guidance weight\n    weight = guidance_scale - 1\n    weight = weight * (weight > 0) + 1e-3\n\n    latent_hat_text = latents - sigma * noise_pred_text\n    latent_hat_uncond = latents - sigma * noise_pred_uncond\n    latent_diff = latent_hat_text - latent_hat_uncond\n\n    # Calculate angle between conditional and unconditional predicted data\n    cos_theta = call_cos_tensor(\n        latent_hat_text.view(-1, c).to(float),\n        latent_hat_uncond.reshape(-1, c).contiguous().to(float)\n    ).clamp(-1.0 + 1e-6, 1.0 - 1e-6)\n    latent_theta = torch.acos(cos_theta).view(n, t, 1)\n    latent_theta_new = torch.clip(weight * latent_theta, -angle_clip, angle_clip) if apply_clip else weight * latent_theta\n    proj, perp = compute_perpendicular_component(latent_diff, latent_hat_uncond)\n    latent_v_new = torch.cos(latent_theta_new) * latent_hat_text\n\n    latent_p_new = perp * torch.sin(latent_theta_new) / torch.sin(latent_theta) * (\n        torch.sin(latent_theta) > 1e-3) + perp * weight * (torch.sin(latent_theta) <= 1e-3)\n    latent_new = latent_v_new + latent_p_new\n    if apply_norm:\n        latent_new = latent_new * torch.linalg.norm(latent_hat_text, dim=1, keepdim=True) / torch.linalg.norm(\n            latent_new, dim=1, keepdim=True)\n\n    noise_pred = (latents - latent_new) / sigma\n    noise_pred = noise_pred.reshape(n, t, c).to(latents.dtype)\n    return noise_pred\n\n\ndef adg_w_norm_forward(\n    latents: torch.Tensor,\n    noise_pred_cond: torch.Tensor,\n    noise_pred_uncond: torch.Tensor,\n    sigma: float,\n    guidance_scale: float,\n    angle_clip: float = 3.14 / 3,\n):\n    \"\"\"\n    ADG with normalization - preserves the magnitude of latent predictions.\n\n    This variant normalizes the final latent to maintain the same norm as the\n    conditional prediction, which can help preserve image quality.\n    \"\"\"\n    return adg_forward(latents,\n                       noise_pred_cond,\n                       noise_pred_uncond,\n                       sigma,\n                       guidance_scale,\n                       angle_clip=angle_clip,\n                       apply_norm=True,\n                       apply_clip=True)\n\n\ndef adg_wo_clip_forward(\n    latents: torch.Tensor,\n    noise_pred_cond: torch.Tensor,\n    noise_pred_uncond: torch.Tensor,\n    sigma: float,\n    guidance_scale: float,\n):\n    \"\"\"\n    ADG without angle clipping - allows unbounded angle adjustments.\n\n    This variant doesn't clip the angle, which may result in more aggressive\n    guidance but could be less stable.\n    \"\"\"\n    return adg_forward(latents, noise_pred_cond, noise_pred_uncond, sigma, guidance_scale, apply_norm=False, apply_clip=False)\n"
  },
  {
    "path": "acestep/models/base/configuration_acestep_v15.py",
    "content": "# coding=utf-8\n# Copyright 2024 The Qwen team, Alibaba Group and the HuggingFace Inc. team. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#     http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n\"\"\"AceStep model configuration\"\"\"\n\nfrom transformers.configuration_utils import PretrainedConfig, layer_type_validation\nfrom transformers.modeling_rope_utils import rope_config_validation\nfrom transformers.utils import logging\n\n\nlogger = logging.get_logger(__name__)\n\n\nclass AceStepConfig(PretrainedConfig):\n    r\"\"\"\n    This is the configuration class to store the configuration of a [`AceStepModel`]. It is used to instantiate an\n    AceStep model according to the specified arguments, defining the model architecture.\n\n    Configuration objects inherit from [`PretrainedConfig`] and can be used to control the model outputs. Read the\n    documentation from [`PretrainedConfig`] for more information.\n\n    Args:\n        vocab_size (`int`, *optional*, defaults to 64003):\n            Vocabulary size of the AceStep model. Defines the number of different tokens that can be represented by the\n            `inputs_ids` passed when calling the model.\n        hidden_size (`int`, *optional*, defaults to 4096):\n            Dimension of the hidden representations.\n        intermediate_size (`int`, *optional*, defaults to 22016):\n            Dimension of the MLP representations.\n        num_hidden_layers (`int`, *optional*, defaults to 32):\n            Number of hidden layers in the Transformer encoder.\n        num_attention_heads (`int`, *optional*, defaults to 32):\n            Number of attention heads for each attention layer in the Transformer encoder.\n        num_key_value_heads (`int`, *optional*, defaults to 32):\n            This is the number of key_value heads that should be used to implement Grouped Query Attention. If\n            `num_key_value_heads=num_attention_heads`, the model will use Multi Head Attention (MHA), if\n            `num_key_value_heads=1` the model will use Multi Query Attention (MQA) otherwise GQA is used. When\n            converting a multi-head checkpoint to a GQA checkpoint, each group key and value head should be constructed\n            by meanpooling all the original heads within that group. For more details, check out [this\n            paper](https://huggingface.co/papers/2305.13245). If it is not specified, will default to `32`.\n        head_dim (`int`, *optional*, defaults to 128):\n            The attention head dimension.\n        hidden_act (`str` or `function`, *optional*, defaults to `\"silu\"`):\n            The non-linear activation function (function or string) in the decoder.\n        max_position_embeddings (`int`, *optional*, defaults to 32768):\n            The maximum sequence length that this model might ever be used with.\n        initializer_range (`float`, *optional*, defaults to 0.02):\n            The standard deviation of the truncated_normal_initializer for initializing all weight matrices.\n        rms_norm_eps (`float`, *optional*, defaults to 1e-06):\n            The epsilon used by the rms normalization layers.\n        use_cache (`bool`, *optional*, defaults to `True`):\n            Whether or not the model should return the last key/values attentions (not used by all models). Only\n            relevant if `config.is_decoder=True`.\n        tie_word_embeddings (`bool`, *optional*, defaults to `False`):\n            Whether the model's input and output word embeddings should be tied.\n        rope_theta (`float`, *optional*, defaults to 10000.0):\n            The base period of the RoPE embeddings.\n        rope_scaling (`Dict`, *optional*):\n            Dictionary containing the scaling configuration for the RoPE embeddings. NOTE: if you apply new rope type\n            and you expect the model to work on longer `max_position_embeddings`, we recommend you to update this value\n            accordingly.\n            Expected contents:\n                `rope_type` (`str`):\n                    The sub-variant of RoPE to use. Can be one of ['default', 'linear', 'dynamic', 'yarn', 'longrope',\n                    'llama3'], with 'default' being the original RoPE implementation.\n                `factor` (`float`, *optional*):\n                    Used with all rope types except 'default'. The scaling factor to apply to the RoPE embeddings. In\n                    most scaling types, a `factor` of x will enable the model to handle sequences of length x *\n                    original maximum pre-trained length.\n                `original_max_position_embeddings` (`int`, *optional*):\n                    Used with 'dynamic', 'longrope' and 'llama3'. The original max position embeddings used during\n                    pretraining.\n                `attention_factor` (`float`, *optional*):\n                    Used with 'yarn' and 'longrope'. The scaling factor to be applied on the attention\n                    computation. If unspecified, it defaults to value recommended by the implementation, using the\n                    `factor` field to infer the suggested value.\n                `beta_fast` (`float`, *optional*):\n                    Only used with 'yarn'. Parameter to set the boundary for extrapolation (only) in the linear\n                    ramp function. If unspecified, it defaults to 32.\n                `beta_slow` (`float`, *optional*):\n                    Only used with 'yarn'. Parameter to set the boundary for interpolation (only) in the linear\n                    ramp function. If unspecified, it defaults to 1.\n                `short_factor` (`list[float]`, *optional*):\n                    Only used with 'longrope'. The scaling factor to be applied to short contexts (<\n                    `original_max_position_embeddings`). Must be a list of numbers with the same length as the hidden\n                    size divided by the number of attention heads divided by 2\n                `long_factor` (`list[float]`, *optional*):\n                    Only used with 'longrope'. The scaling factor to be applied to long contexts (<\n                    `original_max_position_embeddings`). Must be a list of numbers with the same length as the hidden\n                    size divided by the number of attention heads divided by 2\n                `low_freq_factor` (`float`, *optional*):\n                    Only used with 'llama3'. Scaling factor applied to low frequency components of the RoPE\n                `high_freq_factor` (`float`, *optional*):\n                    Only used with 'llama3'. Scaling factor applied to high frequency components of the RoPE\n        attention_bias (`bool`, defaults to `False`, *optional*, defaults to `False`):\n            Whether to use a bias in the query, key, value and output projection layers during self-attention.\n        use_sliding_window (`bool`, *optional*, defaults to `False`):\n            Whether to use sliding window attention.\n        sliding_window (`int`, *optional*, defaults to 4096):\n            Sliding window attention (SWA) window size. If not specified, will default to `4096`.\n        layer_types (`list`, *optional*):\n            Attention pattern for each layer.\n        attention_dropout (`float`, *optional*, defaults to 0.0):\n            The dropout ratio for the attention probabilities.\n\n    ```python\n    >>> from acestep.models import AceStepConfig\n\n    >>> # Initializing an AceStep configuration\n    >>> configuration = AceStepConfig()\n\n    >>> # Initializing a model from the configuration\n    >>> model = AceStepConditionGenerationModel(configuration)\n\n    >>> # Accessing the model configuration\n    >>> configuration = model.config\n    ```\"\"\"\n\n    model_type = \"acestep\"\n    keys_to_ignore_at_inference = [\"past_key_values\"]\n    \n    # Default tensor parallel plan for the base model\n    base_model_tp_plan = {\n        \"layers.*.self_attn.q_proj\": \"colwise\",\n        \"layers.*.self_attn.k_proj\": \"colwise\",\n        \"layers.*.self_attn.v_proj\": \"colwise\",\n        \"layers.*.self_attn.o_proj\": \"rowwise\",\n        \"layers.*.mlp.gate_proj\": \"colwise\",\n        \"layers.*.mlp.up_proj\": \"colwise\",\n        \"layers.*.mlp.down_proj\": \"rowwise\",\n    }\n    base_model_pp_plan = {\n        \"embed_tokens\": ([\"input_ids\"], [\"inputs_embeds\"]),\n        \"layers\": ([\"hidden_states\", \"attention_mask\"], [\"hidden_states\"]),\n        \"norm\": ([\"hidden_states\"], [\"hidden_states\"]),\n    }\n    def __init__(\n        self,\n        vocab_size=64003,\n        fsq_dim=2048,\n        fsq_input_levels=[8, 8, 8, 5, 5, 5],\n        fsq_input_num_quantizers=1,\n        hidden_size=2048,\n        intermediate_size=6144,\n        num_hidden_layers=24,\n        num_attention_heads=16,\n        num_key_value_heads=8,\n        head_dim=128,\n        hidden_act=\"silu\",\n        max_position_embeddings=32768,\n        initializer_range=0.02,\n        rms_norm_eps=1e-6,\n        use_cache=True,\n        tie_word_embeddings=True,\n        rope_theta=1000000,\n        rope_scaling=None,\n        attention_bias=False,\n        use_sliding_window=True,\n        sliding_window=128,\n        layer_types=None,\n        attention_dropout=0.0,\n        num_lyric_encoder_hidden_layers=8,\n        audio_acoustic_hidden_dim=64,\n        pool_window_size=5,\n        text_hidden_dim=1024,\n        in_channels=192,\n        data_proportion=0.5,\n        timestep_mu=-0.4,\n        timestep_sigma=1.0,\n        timbre_hidden_dim=64,\n        num_timbre_encoder_hidden_layers=4,\n        timbre_fix_frame=750,\n        patch_size=2,\n        num_attention_pooler_hidden_layers=2,\n        num_audio_decoder_hidden_layers=24,\n        model_version=\"turbo\",\n        **kwargs,\n    ):\n        self.max_position_embeddings = max_position_embeddings\n        self.hidden_size = hidden_size\n        self.intermediate_size = intermediate_size\n        self.num_hidden_layers = num_hidden_layers\n        self.num_attention_heads = num_attention_heads\n        self.use_sliding_window = use_sliding_window\n        self.sliding_window = sliding_window if self.use_sliding_window else None\n        \n        # Text encoder configuration\n        self.text_hidden_dim = text_hidden_dim\n\n        # Lyric encoder configuration\n        self.num_lyric_encoder_hidden_layers = num_lyric_encoder_hidden_layers\n        self.patch_size = patch_size\n\n        # Audio semantic token generation configuration\n        self.audio_acoustic_hidden_dim = audio_acoustic_hidden_dim\n        self.pool_window_size = pool_window_size\n        self.in_channels = in_channels\n        self.data_proportion = data_proportion\n        self.timestep_mu = timestep_mu\n        self.timestep_sigma = timestep_sigma\n        \n        # FSQ (Finite Scalar Quantization) configuration\n        self.fsq_dim = fsq_dim\n        self.fsq_input_levels = fsq_input_levels\n        self.fsq_input_num_quantizers = fsq_input_num_quantizers\n        \n        # Timbre encoder configuration\n        self.timbre_hidden_dim = timbre_hidden_dim\n        self.num_timbre_encoder_hidden_layers = num_timbre_encoder_hidden_layers\n        self.timbre_fix_frame = timbre_fix_frame\n        self.num_attention_pooler_hidden_layers = num_attention_pooler_hidden_layers\n        self.num_audio_decoder_hidden_layers = num_audio_decoder_hidden_layers\n        self.vocab_size = vocab_size\n\n        # Backward compatibility: ensure num_key_value_heads is set\n        if num_key_value_heads is None:\n            num_key_value_heads = num_attention_heads\n\n        self.num_key_value_heads = num_key_value_heads\n        self.head_dim = head_dim\n        self.hidden_act = hidden_act\n        self.initializer_range = initializer_range\n        self.rms_norm_eps = rms_norm_eps\n        self.use_cache = use_cache\n        self.rope_theta = rope_theta\n        self.rope_scaling = rope_scaling\n        self.attention_bias = attention_bias\n        self.attention_dropout = attention_dropout\n        self.model_version = model_version\n        \n        # Validate rotary position embeddings parameters\n        # Backward compatibility: if there is a 'type' field, move it to 'rope_type'\n        if self.rope_scaling is not None and \"type\" in self.rope_scaling:\n            self.rope_scaling[\"rope_type\"] = self.rope_scaling[\"type\"]\n        rope_config_validation(self)\n\n        self.layer_types = layer_types\n\n        # Set default layer types if not specified\n        if self.layer_types is None:\n            self.layer_types = [\n                \"sliding_attention\" if bool((i + 1) % 2) else \"full_attention\" for i in range(self.num_hidden_layers)\n            ]\n        layer_type_validation(self.layer_types)\n\n        super().__init__(\n            tie_word_embeddings=tie_word_embeddings,\n            **kwargs,\n        )\n\n\n__all__ = [\"AceStepConfig\"]\n"
  },
  {
    "path": "acestep/models/base/modeling_acestep_v15_base.py",
    "content": "# Copyright 2025 The ACESTEO Team. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#     http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\nimport math\nimport time\nfrom typing import Callable, List, Optional, Union\n\nimport torch\nimport torch.nn.functional as F\nfrom torch import nn\n\nfrom einops import rearrange\n\n# Transformers imports (sorted by submodule, then alphabetically)\nfrom transformers.cache_utils import Cache, DynamicCache, EncoderDecoderCache\nfrom transformers.modeling_attn_mask_utils import _prepare_4d_causal_attention_mask\nfrom transformers.modeling_flash_attention_utils import FlashAttentionKwargs\nfrom transformers.modeling_layers import GradientCheckpointingLayer\nfrom transformers.modeling_outputs import BaseModelOutput\nfrom transformers.modeling_utils import ALL_ATTENTION_FUNCTIONS, PreTrainedModel\nfrom transformers.processing_utils import Unpack\nfrom transformers.utils import auto_docstring, can_return_tuple, logging\nfrom transformers.models.qwen3.modeling_qwen3 import (\n    Qwen3MLP,\n    Qwen3RMSNorm,\n    Qwen3RotaryEmbedding,\n    apply_rotary_pos_emb,\n    eager_attention_forward,\n)\nfrom tqdm import tqdm\nfrom vector_quantize_pytorch import ResidualFSQ\n\n\n# Local config import with fallback\ntry:\n    from .configuration_acestep_v15 import AceStepConfig\n    from .apg_guidance import adg_forward, apg_forward, MomentumBuffer\nexcept ImportError:\n    from configuration_acestep_v15 import AceStepConfig\n    from apg_guidance import adg_forward, apg_forward, MomentumBuffer\n\n\nlogger = logging.get_logger(__name__)\n\n\ndef create_4d_mask(\n    seq_len: int,\n    dtype: torch.dtype,\n    device: torch.device,\n    attention_mask: Optional[torch.Tensor] = None, # [Batch, Seq_Len]\n    sliding_window: Optional[int] = None,\n    is_sliding_window: bool = False,\n    is_causal: bool = True,\n) -> torch.Tensor:\n    \"\"\"\n    General 4D Attention Mask generator compatible with CPU/Mac/SDPA and Eager mode.\n    Supports use cases:\n    1. Causal Full: is_causal=True, is_sliding_window=False (standard GPT)\n    2. Causal Sliding: is_causal=True, is_sliding_window=True (Mistral/Qwen local window)\n    3. Bidirectional Full: is_causal=False, is_sliding_window=False (BERT/Encoder)\n    4. Bidirectional Sliding: is_causal=False, is_sliding_window=True (Longformer local)\n\n    Returns:\n        [Batch, 1, Seq_Len, Seq_Len] additive mask (0.0 for keep, -inf for mask)\n    \"\"\"\n    # ------------------------------------------------------\n    # 1. Construct basic geometry mask [Seq_Len, Seq_Len]\n    # ------------------------------------------------------\n\n    # Build index matrices\n    # i (Query): [0, 1, ..., L-1]\n    # j (Key):   [0, 1, ..., L-1]\n    indices = torch.arange(seq_len, device=device)\n    # diff = i - j\n    diff = indices.unsqueeze(1) - indices.unsqueeze(0)\n\n    # Initialize all True (all positions visible)\n    valid_mask = torch.ones((seq_len, seq_len), device=device, dtype=torch.bool)\n\n    # (A) Handle causality (Causal)\n    if is_causal:\n        # i >= j  =>  diff >= 0\n        valid_mask = valid_mask & (diff >= 0)\n\n    # (B) Handle sliding window\n    if is_sliding_window and sliding_window is not None:\n        if is_causal:\n            # Causal sliding: only attend to past window steps\n            # i - j <= window  =>  diff <= window\n            # (diff >= 0 already handled above)\n            valid_mask = valid_mask & (diff <= sliding_window)\n        else:\n            # Bidirectional sliding: attend past and future window steps\n            # |i - j| <= window  =>  abs(diff) <= sliding_window\n            valid_mask = valid_mask & (torch.abs(diff) <= sliding_window)\n\n    # Expand dimensions to [1, 1, Seq_Len, Seq_Len] for broadcasting\n    valid_mask = valid_mask.unsqueeze(0).unsqueeze(0)\n\n    # ------------------------------------------------------\n    # 2. Apply padding mask (Key Masking)\n    # ------------------------------------------------------\n    if attention_mask is not None:\n        # attention_mask shape: [Batch, Seq_Len] (1=valid, 0=padding)\n        # We want to mask out invalid keys (columns)\n        # Expand shape: [Batch, 1, 1, Seq_Len]\n        padding_mask_4d = attention_mask.view(attention_mask.shape[0], 1, 1, seq_len).to(torch.bool)\n\n        # Broadcasting: Geometry Mask [1, 1, L, L] & Padding Mask [B, 1, 1, L]\n        # Result shape: [B, 1, L, L]\n        valid_mask = valid_mask & padding_mask_4d\n\n    # ------------------------------------------------------\n    # 3. Convert to additive mask\n    # ------------------------------------------------------\n    # Get the minimal value for current dtype\n    min_dtype = torch.finfo(dtype).min\n\n    # Create result tensor filled with -inf by default\n    mask_tensor = torch.full(valid_mask.shape, min_dtype, dtype=dtype, device=device)\n\n    # Set valid positions to 0.0\n    mask_tensor.masked_fill_(valid_mask, 0.0)\n\n    return mask_tensor\n\n\ndef pack_sequences(hidden1: torch.Tensor, hidden2: torch.Tensor, mask1: torch.Tensor, mask2: torch.Tensor):\n    \"\"\"\n    Pack two sequences by concatenating and sorting them based on mask values.\n\n    Args:\n        hidden1: First hidden states tensor of shape [B, L1, D]\n        hidden2: Second hidden states tensor of shape [B, L2, D]\n        mask1: First mask tensor of shape [B, L1]\n        mask2: Second mask tensor of shape [B, L2]\n\n    Returns:\n        Tuple of (packed_hidden_states, new_mask) where:\n        - packed_hidden_states: Packed hidden states with valid tokens (mask=1) first, shape [B, L1+L2, D]\n        - new_mask: New mask tensor indicating valid positions, shape [B, L1+L2]\n    \"\"\"\n    # Step 1: Concatenate hidden states and masks along sequence dimension\n    hidden_cat = torch.cat([hidden1, hidden2], dim=1)  # [B, L, D]\n    mask_cat = torch.cat([mask1, mask2], dim=1)  # [B, L]\n\n    B, L, D = hidden_cat.shape\n\n    # Step 2: Sort indices so that mask values of 1 come before 0\n    sort_idx = mask_cat.argsort(dim=1, descending=True, stable=True)  # [B, L]\n\n    # Step 3: Reorder hidden states using sorted indices\n    hidden_left = torch.gather(hidden_cat, 1, sort_idx.unsqueeze(-1).expand(B, L, D))\n\n    # Step 4: Create new mask based on valid sequence lengths\n    lengths = mask_cat.sum(dim=1)  # [B]\n    new_mask = (torch.arange(L, dtype=torch.long, device=hidden_cat.device).unsqueeze(0) < lengths.unsqueeze(1))\n\n    return hidden_left, new_mask\n\n\ndef sample_t_r(batch_size, device, dtype, data_proportion=0.0, timestep_mu=-0.4, timestep_sigma=1.0, use_meanflow=True):\n    \"\"\"\n    Sample timestep t and r for flow matching training.\n\n    Args:\n        batch_size: Batch size\n        device: Device to create tensors on\n        dtype: Data type for tensors\n        data_proportion: Proportion of data samples (0.0 to 1.0)\n        timestep_mu: Mean for timestep sampling\n        timestep_sigma: Standard deviation for timestep sampling\n        use_meanflow: Whether to use meanflow (if False, data_proportion is set to 1.0)\n\n    Returns:\n        Tuple of (t, r) tensors, each of shape [batch_size]\n    \"\"\"\n    t = torch.sigmoid(torch.randn((batch_size,), device=device, dtype=dtype) * timestep_sigma + timestep_mu)\n    r = torch.sigmoid(torch.randn((batch_size,), device=device, dtype=dtype) * timestep_sigma + timestep_mu)\n    # Assign t = max, r = min, for each pair\n    t, r = torch.maximum(t, r), torch.minimum(t, r)\n    if not use_meanflow:\n        data_proportion = 1.0\n    data_size = int(batch_size * data_proportion)\n    zero_mask = torch.arange(batch_size, device=device) < data_size\n    r = torch.where(zero_mask, t, r)\n    return t, r\n\n\nclass TimestepEmbedding(nn.Module):\n    \"\"\"\n    Timestep embedding module for diffusion models.\n\n    Converts timestep values into high-dimensional embeddings using sinusoidal\n    positional encoding, followed by MLP layers. Used for conditioning diffusion\n    models on timestep information.\n    \"\"\"\n    def __init__(\n        self,\n        in_channels: int,\n        time_embed_dim: int,\n        scale: float = 1000,\n    ):\n        super().__init__()\n\n        self.linear_1 = nn.Linear(in_channels, time_embed_dim, bias=True)\n        self.act1 = nn.SiLU()\n        self.linear_2 = nn.Linear(time_embed_dim, time_embed_dim, bias=True)\n        self.in_channels = in_channels\n\n        self.act2 = nn.SiLU()\n        self.time_proj = nn.Linear(time_embed_dim, time_embed_dim * 6)\n        self.scale = scale\n\n    def timestep_embedding(self, t, dim, max_period=10000):\n        \"\"\"\n        Create sinusoidal timestep embeddings.\n\n        Args:\n            t: A 1-D tensor of N indices, one per batch element. These may be fractional.\n            dim: The dimension of the output embeddings.\n            max_period: Controls the minimum frequency of the embeddings.\n\n        Returns:\n            An (N, D) tensor of positional embeddings.\n        \"\"\"\n        t = t * self.scale\n        half = dim // 2\n        freqs = torch.exp(\n            -math.log(max_period) * torch.arange(start=0, end=half, dtype=torch.float32) / half\n        ).to(device=t.device)\n        args = t[:, None].float() * freqs[None]\n        embedding = torch.cat([torch.cos(args), torch.sin(args)], dim=-1)\n        if dim % 2:\n            embedding = torch.cat([embedding, torch.zeros_like(embedding[:, :1])], dim=-1)\n        return embedding\n\n    def forward(self, t):\n        t_freq = self.timestep_embedding(t, self.in_channels)\n        temb = self.linear_1(t_freq.to(t.dtype))\n        temb = self.act1(temb)\n        temb = self.linear_2(temb)\n        timestep_proj = self.time_proj(self.act2(temb)).unflatten(1, (6, -1))\n        return temb, timestep_proj\n\nclass AceStepAttention(nn.Module):\n    \"\"\"\n    Multi-headed attention module for AceStep model.\n\n    Implements the attention mechanism from 'Attention Is All You Need' paper,\n    with support for both self-attention and cross-attention modes. Uses RMSNorm\n    for query and key normalization, and supports sliding window attention for\n    efficient long-sequence processing.\n    \"\"\"\n\n    def __init__(self, config: AceStepConfig, layer_idx: int, is_cross_attention: bool = False, is_causal: bool = False):\n        super().__init__()\n        self.config = config\n        self.layer_idx = layer_idx\n        self.head_dim = getattr(config, \"head_dim\", config.hidden_size // config.num_attention_heads)\n        self.num_key_value_groups = config.num_attention_heads // config.num_key_value_heads\n        self.scaling = self.head_dim**-0.5\n        self.attention_dropout = config.attention_dropout\n        if is_cross_attention:\n            is_causal = False\n        self.is_causal = is_causal\n        self.is_cross_attention = is_cross_attention\n\n        self.q_proj = nn.Linear(config.hidden_size, config.num_attention_heads * self.head_dim, bias=config.attention_bias)\n        self.k_proj = nn.Linear(config.hidden_size, config.num_key_value_heads * self.head_dim, bias=config.attention_bias)\n        self.v_proj = nn.Linear(config.hidden_size, config.num_key_value_heads * self.head_dim, bias=config.attention_bias)\n        self.o_proj = nn.Linear(config.num_attention_heads * self.head_dim, config.hidden_size, bias=config.attention_bias)\n        # Apply RMS normalization only on the head dimension (unlike OLMo)\n        self.q_norm = Qwen3RMSNorm(self.head_dim, eps=config.rms_norm_eps)\n        self.k_norm = Qwen3RMSNorm(self.head_dim, eps=config.rms_norm_eps)\n        self.attention_type = config.layer_types[layer_idx]\n        self.sliding_window = config.sliding_window if config.layer_types[layer_idx] == \"sliding_attention\" else None\n\n    def forward(\n        self,\n        hidden_states: torch.Tensor,\n        attention_mask: Optional[torch.Tensor],\n        past_key_value: Optional[Cache] = None,\n        cache_position: Optional[torch.LongTensor] = None,\n        encoder_hidden_states: Optional[torch.Tensor] = None,\n        position_embeddings: tuple[torch.Tensor, torch.Tensor] = None,\n        output_attentions: Optional[bool] = False,\n        **kwargs: Unpack[FlashAttentionKwargs],\n    ) -> tuple[torch.Tensor, Optional[torch.Tensor], Optional[tuple[torch.Tensor]]]:\n        input_shape = hidden_states.shape[:-1]\n        hidden_shape = (*input_shape, -1, self.head_dim)\n\n        # Project and normalize query states\n        query_states = self.q_norm(self.q_proj(hidden_states).view(hidden_shape)).transpose(1, 2)\n\n        # Determine if this is cross-attention (requires encoder_hidden_states)\n        is_cross_attention = self.is_cross_attention and encoder_hidden_states is not None\n\n        # Cross-attention path: attend to encoder hidden states\n        if is_cross_attention:\n            encoder_hidden_shape = (*encoder_hidden_states.shape[:-1], -1, self.head_dim)\n            if past_key_value is not None:\n                is_updated = past_key_value.is_updated.get(self.layer_idx)\n                # After the first generated token, we can reuse all key/value states from cache\n                curr_past_key_value = past_key_value.cross_attention_cache\n\n                # Conditions for calculating key and value states\n                if not is_updated:\n                    # Compute and cache K/V for the first time\n                    key_states = self.k_norm(self.k_proj(encoder_hidden_states).view(encoder_hidden_shape)).transpose(1, 2)\n                    value_states = self.v_proj(encoder_hidden_states).view(encoder_hidden_shape).transpose(1, 2)\n                    # Update cache: save all key/value states to cache for fast auto-regressive generation\n                    key_states, value_states = curr_past_key_value.update(key_states, value_states, self.layer_idx)\n                    # Set flag that this layer's cross-attention cache is updated\n                    past_key_value.is_updated[self.layer_idx] = True\n                else:\n                    # Reuse cached key/value states for subsequent tokens\n                    key_states = curr_past_key_value.layers[self.layer_idx].keys\n                    value_states = curr_past_key_value.layers[self.layer_idx].values\n            else:\n                # No cache used, compute K/V directly\n                key_states = self.k_norm(self.k_proj(encoder_hidden_states).view(encoder_hidden_shape)).transpose(1, 2)\n                value_states = self.v_proj(encoder_hidden_states).view(encoder_hidden_shape).transpose(1, 2)\n\n        # Self-attention path: attend to the same sequence\n        else:\n            # Project and normalize key/value states for self-attention\n            key_states = self.k_norm(self.k_proj(hidden_states).view(hidden_shape)).transpose(1, 2)\n            value_states = self.v_proj(hidden_states).view(hidden_shape).transpose(1, 2)\n            # Apply rotary position embeddings (RoPE) if provided\n            if position_embeddings is not None:\n                cos, sin = position_embeddings\n                query_states, key_states = apply_rotary_pos_emb(query_states, key_states, cos, sin)\n\n            # Update cache for auto-regressive generation\n            if past_key_value is not None:\n                # Sin and cos are specific to RoPE models; cache_position needed for the static cache\n                cache_kwargs = {\"sin\": sin, \"cos\": cos, \"cache_position\": cache_position}\n                key_states, value_states = past_key_value.update(key_states, value_states, self.layer_idx, cache_kwargs)\n\n        attention_interface: Callable = eager_attention_forward\n        if is_cross_attention and output_attentions:\n            attention_interface: Callable = eager_attention_forward\n        elif self.config._attn_implementation != \"eager\":\n            attention_interface = ALL_ATTENTION_FUNCTIONS[self.config._attn_implementation]\n\n        attn_output, attn_weights = attention_interface(\n            self,\n            query_states,\n            key_states,\n            value_states,\n            attention_mask,\n            dropout=self.attention_dropout if self.training else 0.0,\n            scaling=self.scaling,\n            sliding_window=self.sliding_window if not self.is_cross_attention else None,\n            **kwargs,\n        )\n\n        attn_output = attn_output.reshape(*input_shape, -1).contiguous()\n        attn_output = self.o_proj(attn_output)\n        return attn_output, attn_weights\n\n\nclass AceStepEncoderLayer(GradientCheckpointingLayer):\n    \"\"\"\n    Encoder layer for AceStep model.\n\n    Consists of self-attention and MLP (feed-forward) sub-layers with residual connections.\n    \"\"\"\n\n    def __init__(self, config, layer_idx: int):\n        super().__init__()\n        self.hidden_size = config.hidden_size\n        self.config = config\n        self.layer_idx = layer_idx\n\n        # Self-attention sub-layer\n        self.self_attn = AceStepAttention(\n            config=config,\n            layer_idx=layer_idx,\n            is_cross_attention=False,\n            is_causal=False,\n        )\n        self.input_layernorm = Qwen3RMSNorm(config.hidden_size, eps=config.rms_norm_eps)\n        self.post_attention_layernorm = Qwen3RMSNorm(config.hidden_size, eps=config.rms_norm_eps)\n\n        # MLP (feed-forward) sub-layer\n        self.mlp = Qwen3MLP(config)\n        self.attention_type = config.layer_types[layer_idx]\n\n    def forward(\n        self,\n        hidden_states: torch.Tensor,\n        position_embeddings: tuple[torch.Tensor, torch.Tensor],\n        attention_mask: Optional[torch.Tensor] = None,\n        position_ids: Optional[torch.LongTensor] = None,\n        output_attentions: Optional[bool] = False,\n        **kwargs,\n    ) -> tuple[\n        torch.FloatTensor,\n        Optional[tuple[torch.FloatTensor, torch.FloatTensor]],\n    ]:\n        # Self-attention with residual connection\n        residual = hidden_states\n        hidden_states = self.input_layernorm(hidden_states)\n        hidden_states, self_attn_weights = self.self_attn(\n            hidden_states=hidden_states,\n            position_embeddings=position_embeddings,\n            attention_mask=attention_mask,\n            position_ids=position_ids,\n            output_attentions=output_attentions,\n            # Encoders don't use cache\n            use_cache=False,\n            past_key_value=None,\n            **kwargs,\n        )\n        hidden_states = residual + hidden_states\n\n        # MLP with residual connection\n        residual = hidden_states\n        hidden_states = self.post_attention_layernorm(hidden_states)\n        hidden_states = self.mlp(hidden_states)\n        hidden_states = residual + hidden_states\n\n        outputs = (hidden_states,)\n\n        if output_attentions:\n            outputs += (self_attn_weights,)\n\n        return outputs\n\n\nclass AceStepDiTLayer(GradientCheckpointingLayer):\n    \"\"\"\n    DiT (Diffusion Transformer) layer for AceStep model.\n\n    Implements a transformer layer with three main components:\n    1. Self-attention with adaptive layer norm (AdaLN)\n    2. Cross-attention (optional) for conditioning on encoder outputs\n    3. Feed-forward MLP with adaptive layer norm\n\n    Uses scale-shift modulation from timestep embeddings for adaptive normalization.\n    \"\"\"\n    def __init__(self, config: AceStepConfig, layer_idx: int, use_cross_attention: bool = True):\n        super().__init__()\n\n        # 1. Self-attention sub-layer with adaptive normalization\n        self.self_attn_norm = Qwen3RMSNorm(config.hidden_size, eps=config.rms_norm_eps)\n        self.self_attn = AceStepAttention(config=config, layer_idx=layer_idx)\n\n        # 2. Cross-attention sub-layer (optional, for encoder conditioning)\n        self.use_cross_attention = use_cross_attention\n        if self.use_cross_attention:\n            self.cross_attn_norm = Qwen3RMSNorm(config.hidden_size, eps=config.rms_norm_eps)\n            self.cross_attn = AceStepAttention(config=config, layer_idx=layer_idx, is_cross_attention=True)\n\n        # 3. Feed-forward MLP sub-layer with adaptive normalization\n        self.mlp_norm = Qwen3RMSNorm(config.hidden_size, eps=config.rms_norm_eps)\n        self.mlp = Qwen3MLP(config)\n\n        # Scale-shift table for adaptive layer norm modulation (6 values: 3 for self-attn, 3 for MLP)\n        self.scale_shift_table = nn.Parameter(torch.randn(1, 6, config.hidden_size) / config.hidden_size**0.5)\n        self.attention_type = config.layer_types[layer_idx]\n\n    def forward(\n        self,\n        hidden_states: torch.Tensor,\n        position_embeddings: tuple[torch.Tensor, torch.Tensor],\n        temb: torch.Tensor,\n        attention_mask: Optional[torch.Tensor] = None,\n        position_ids: Optional[torch.LongTensor] = None,\n        past_key_value: Optional[EncoderDecoderCache] = None,\n        output_attentions: Optional[bool] = False,\n        use_cache: Optional[bool] = False,\n        cache_position: Optional[torch.LongTensor] = None,\n        encoder_hidden_states: Optional[torch.Tensor] = None,\n        encoder_attention_mask: Optional[torch.Tensor] = None,\n        **kwargs,\n    ) -> torch.Tensor:\n\n        # Extract scale-shift parameters for adaptive layer norm from timestep embeddings\n        # 6 values: (shift_msa, scale_msa, gate_msa, c_shift_msa, c_scale_msa, c_gate_msa)\n        shift_msa, scale_msa, gate_msa, c_shift_msa, c_scale_msa, c_gate_msa = (\n            self.scale_shift_table + temb\n        ).chunk(6, dim=1)\n\n        # Step 1: Self-attention with adaptive layer norm (AdaLN)\n        # Apply adaptive normalization: norm(x) * (1 + scale) + shift\n        norm_hidden_states = (self.self_attn_norm(hidden_states) * (1 + scale_msa) + shift_msa).type_as(hidden_states)\n        attn_output, self_attn_weights = self.self_attn(\n            hidden_states=norm_hidden_states,\n            position_embeddings=position_embeddings,\n            attention_mask=attention_mask,\n            position_ids=position_ids,\n            output_attentions=output_attentions,\n            use_cache=False,\n            past_key_value=None,\n            **kwargs,\n        )\n        # Apply gated residual connection: x = x + attn_output * gate\n        hidden_states = (hidden_states + attn_output * gate_msa).type_as(hidden_states)\n\n        # Step 2: Cross-attention (if enabled) for conditioning on encoder outputs\n        if self.use_cross_attention:\n            norm_hidden_states = self.cross_attn_norm(hidden_states).type_as(hidden_states)\n            attn_output, cross_attn_weights = self.cross_attn(\n                hidden_states=norm_hidden_states,\n                encoder_hidden_states=encoder_hidden_states,\n                attention_mask=encoder_attention_mask,\n                past_key_value=past_key_value,\n                output_attentions=output_attentions,\n                use_cache=use_cache,\n                **kwargs,\n            )\n            # Standard residual connection for cross-attention\n            hidden_states = hidden_states + attn_output\n\n        # Step 3: Feed-forward (MLP) with adaptive layer norm\n        # Apply adaptive normalization for MLP: norm(x) * (1 + scale) + shift\n        norm_hidden_states = (self.mlp_norm(hidden_states) * (1 + c_scale_msa) + c_shift_msa).type_as(hidden_states)\n        ff_output = self.mlp(norm_hidden_states)\n        # Apply gated residual connection: x = x + mlp_output * gate\n        hidden_states = (hidden_states + ff_output * c_gate_msa).type_as(hidden_states)\n\n        outputs = (hidden_states,)\n        if output_attentions:\n            outputs += (self_attn_weights, cross_attn_weights)\n\n        return outputs\n\n\n@auto_docstring\nclass AceStepPreTrainedModel(PreTrainedModel):\n    config_class = AceStepConfig\n    base_model_prefix = \"model\"\n    supports_gradient_checkpointing = True\n    _no_split_modules = [\"AceStepEncoderLayer\", \"AceStepDiTLayer\"]\n    _skip_keys_device_placement = [\"past_key_values\"]\n    _supports_flash_attn_3 = True\n    _supports_flash_attn_2 = True\n    _supports_sdpa = True\n    _supports_flex_attn = True\n    _supports_cache_class = True\n    _supports_quantized_cache = True\n    _supports_static_cache = True\n    _supports_attention_backend = True\n\n    def _init_weights(self, module):\n        \"\"\"\n        Initialize weights for different module types.\n\n        TODO: Support separate initialization for encoders and decoders.\n        \"\"\"\n        std = self.config.initializer_range\n        if isinstance(module, nn.Linear):\n            module.weight.data.normal_(mean=0.0, std=std)\n            if module.bias is not None:\n                module.bias.data.zero_()\n        elif isinstance(module, nn.Embedding):\n            module.weight.data.normal_(mean=0.0, std=std)\n            if module.padding_idx is not None:\n                module.weight.data[module.padding_idx].zero_()\n        elif isinstance(module, Qwen3RMSNorm):\n            module.weight.data.fill_(1.0)\n\n\nclass AceStepLyricEncoder(AceStepPreTrainedModel):\n    \"\"\"\n    Encoder for processing lyric text embeddings.\n\n    Encodes lyric text hidden states using a transformer encoder architecture\n    with bidirectional attention. Projects text embeddings to model hidden size\n    and processes them through multiple encoder layers.\n    \"\"\"\n    def __init__(self, config):\n        super().__init__(config)\n\n        # Project text embeddings to model hidden size\n        self.embed_tokens = nn.Linear(config.text_hidden_dim, config.hidden_size)\n        self.norm = Qwen3RMSNorm(config.hidden_size, eps=config.rms_norm_eps)\n        self.rotary_emb = Qwen3RotaryEmbedding(config=config)\n        self.gradient_checkpointing = False\n\n        # Stack of encoder layers\n        self.layers = nn.ModuleList(\n            [AceStepEncoderLayer(config, layer_idx) for layer_idx in range(config.num_lyric_encoder_hidden_layers)]\n        )\n\n        # Initialize weights and apply final processing\n        self.post_init()\n\n    @can_return_tuple\n    def forward(\n        self,\n        input_ids: Optional[torch.LongTensor] = None,\n        attention_mask: Optional[torch.Tensor] = None,\n        position_ids: Optional[torch.LongTensor] = None,\n        inputs_embeds: Optional[torch.FloatTensor] = None,\n        output_attentions: Optional[bool] = None,\n        output_hidden_states: Optional[bool] = None,\n        **flash_attn_kwargs: Unpack[FlashAttentionKwargs],\n    ) -> BaseModelOutput:\n        output_attentions = output_attentions if output_attentions is not None else self.config.output_attentions\n        output_hidden_states = (\n            output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states\n        )\n\n        assert input_ids is None, \"Only `input_ids` is supported for the lyric encoder.\"\n        assert attention_mask is not None, \"Attention mask must be provided for the lyric encoder.\"\n        assert inputs_embeds is not None, \"Inputs embeddings must be provided for the lyric encoder.\"\n\n        # Project input embeddings: N x T x text_hidden_dim -> N x T x hidden_size\n        inputs_embeds = self.embed_tokens(inputs_embeds)\n        # Cache position: only used for mask construction (not for actual caching)\n        cache_position = torch.arange(0, inputs_embeds.shape[1], device=inputs_embeds.device)\n\n        # Positional IDs\n        if position_ids is None:\n            position_ids = cache_position.unsqueeze(0)\n\n        # Attention masks\n        seq_len = inputs_embeds.shape[1]\n        dtype = inputs_embeds.dtype\n        device = inputs_embeds.device\n\n        # 判断是否使用 Flash Attention 2\n        is_flash_attn = (self.config._attn_implementation == \"flash_attention_2\")\n\n        # 初始化 Mask 变量\n        full_attn_mask = None\n        sliding_attn_mask = None\n\n        if is_flash_attn:\n            # -------------------------------------------------------\n            # 场景 A: Flash Attention 模式\n            # -------------------------------------------------------\n            # FA 不需要 4D Mask。\n            # 如果有 padding mask (attention_mask [B, L])，直接传给它即可。\n            # 如果没有 padding mask，传 None。\n            # 滑动窗口逻辑由 Layer 内部传给 FA kernel 的 sliding_window 参数控制。\n            full_attn_mask = attention_mask\n\n            # 这里的逻辑是：如果配置启用了滑动窗口，FA 模式下我们也只需要传基础的 padding mask\n            # Layer 会自己决定是否调用带 sliding window 的 kernel\n            sliding_attn_mask = attention_mask if self.config.use_sliding_window else None\n\n        else:\n            # -------------------------------------------------------\n            # 场景 B: CPU / Mac / SDPA (Eager 模式)\n            # -------------------------------------------------------\n            # 必须手动生成 4D Mask [B, 1, L, L]\n\n            # 1. Full Attention (Bidirectional, Global)\n            # 对应原来的 create_causal_mask + bidirectional\n            full_attn_mask = create_4d_mask(\n                seq_len=seq_len,\n                dtype=dtype,\n                device=device,\n                attention_mask=attention_mask,     # [B, L]\n                sliding_window=None,\n                is_sliding_window=False,\n                is_causal=False                    # <--- 关键：双向注意力\n            )\n\n            # 2. Sliding Attention (Bidirectional, Local)\n            # 对应原来的 create_sliding_window... + bidirectional\n            if self.config.use_sliding_window:\n                sliding_attn_mask = create_4d_mask(\n                    seq_len=seq_len,\n                    dtype=dtype,\n                    device=device,\n                    attention_mask=attention_mask, # [B, L]\n                    sliding_window=self.config.sliding_window,\n                    is_sliding_window=True,        # <--- 开启滑动窗口\n                    is_causal=False                # <--- 关键：双向注意力\n                )\n\n        # 构建 Mapping\n        self_attn_mask_mapping = {\n            \"full_attention\": full_attn_mask,\n            \"sliding_attention\": sliding_attn_mask,\n        }\n\n        # Initialize hidden states with input embeddings\n        hidden_states = inputs_embeds\n\n        # Create position embeddings to be shared across all layers\n        position_embeddings = self.rotary_emb(hidden_states, position_ids)\n\n        # Pass through transformer layers\n        all_hidden_states = () if output_hidden_states else None\n        all_self_attns = () if output_attentions else None\n\n        for layer_module in self.layers[: self.config.num_hidden_layers]:\n            if output_hidden_states:\n                all_hidden_states += (hidden_states,)\n\n            layer_outputs = layer_module(\n                hidden_states,\n                position_embeddings,\n                self_attn_mask_mapping[layer_module.attention_type],\n                position_ids,\n                output_attentions,\n                **flash_attn_kwargs,\n            )\n\n            hidden_states = layer_outputs[0]\n\n            if output_attentions:\n                all_self_attns += (layer_outputs[1],)\n\n        hidden_states = self.norm(hidden_states)\n\n        if output_hidden_states:\n            all_hidden_states += (hidden_states,)\n\n        return BaseModelOutput(\n            last_hidden_state=hidden_states,\n            hidden_states=all_hidden_states,\n            attentions=all_self_attns,\n        )\n\n\nclass AttentionPooler(AceStepPreTrainedModel):\n    \"\"\"\n    Attention-based pooling module.\n\n    Pools sequences of patches using a special token and attention mechanism.\n    The special token attends to all patches and its output is used as the\n    pooled representation. Used for aggregating patch-level features into\n    sequence-level representations.\n    \"\"\"\n    def __init__(self, config):\n        super().__init__(config)\n        self.config = config\n        self.embed_tokens = nn.Linear(config.hidden_size, config.hidden_size)\n        self.norm = Qwen3RMSNorm(config.hidden_size, eps=config.rms_norm_eps)\n        self.rotary_emb = Qwen3RotaryEmbedding(config=config)\n        self.gradient_checkpointing = False\n        # Special token used for pooling (CLS-like token)\n        self.special_token = nn.Parameter(torch.randn(1, 1, config.hidden_size) * 0.02)\n        self.layers = nn.ModuleList(\n            [AceStepEncoderLayer(config, layer_idx) for layer_idx in range(config.num_attention_pooler_hidden_layers)]\n        )\n\n        # Initialize weights and apply final processing\n        self.post_init()\n\n    @can_return_tuple\n    def forward(self,\n        x,\n        attention_mask: Optional[torch.Tensor] = None,\n        **flash_attn_kwargs: Unpack[FlashAttentionKwargs],\n    ) -> BaseModelOutput:\n        B, T, P, D = x.shape\n        x = self.embed_tokens(x)\n        special_tokens = self.special_token.expand(B, T, 1, -1)\n        x = torch.cat([special_tokens, x], dim=2)\n        x = rearrange(x, \"b t p c -> (b t) p c\")\n\n        # Cache position: only used for mask construction.\n        cache_position = torch.arange(0, x.shape[1], device=x.device)\n        # Postional ids.\n        position_ids = cache_position.unsqueeze(0)\n\n        # embed positions\n        hidden_states = x\n\n        # create position embeddings to be shared across the decoder layers\n        position_embeddings = self.rotary_emb(hidden_states, position_ids)\n\n        seq_len = x.shape[1]\n        dtype = x.dtype\n        device = x.device\n\n        # 判断是否使用 Flash Attention 2\n        is_flash_attn = (self.config._attn_implementation == \"flash_attention_2\")\n\n        # 初始化 Mask 变量\n        full_attn_mask = None\n        sliding_attn_mask = None\n\n        if is_flash_attn:\n            # -------------------------------------------------------\n            # 场景 A: Flash Attention 模式\n            # -------------------------------------------------------\n            # FA 不需要 4D Mask。\n            # 如果有 padding mask (attention_mask [B, L])，直接传给它即可。\n            # 如果没有 padding mask，传 None。\n            # 滑动窗口逻辑由 Layer 内部传给 FA kernel 的 sliding_window 参数控制。\n            full_attn_mask = attention_mask\n\n            # 这里的逻辑是：如果配置启用了滑动窗口，FA 模式下我们也只需要传基础的 padding mask\n            # Layer 会自己决定是否调用带 sliding window 的 kernel\n            sliding_attn_mask = attention_mask if self.config.use_sliding_window else None\n\n        else:\n            # -------------------------------------------------------\n            # 场景 B: CPU / Mac / SDPA (Eager 模式)\n            # -------------------------------------------------------\n            # 必须手动生成 4D Mask [B, 1, L, L]\n\n            # 1. Full Attention (Bidirectional, Global)\n            # 对应原来的 create_causal_mask + bidirectional\n            full_attn_mask = create_4d_mask(\n                seq_len=seq_len,\n                dtype=dtype,\n                device=device,\n                attention_mask=attention_mask,     # [B, L]\n                sliding_window=None,\n                is_sliding_window=False,\n                is_causal=False                    # <--- 关键：双向注意力\n            )\n\n            # 2. Sliding Attention (Bidirectional, Local)\n            # 对应原来的 create_sliding_window... + bidirectional\n            if self.config.use_sliding_window:\n                sliding_attn_mask = create_4d_mask(\n                    seq_len=seq_len,\n                    dtype=dtype,\n                    device=device,\n                    attention_mask=attention_mask, # [B, L]\n                    sliding_window=self.config.sliding_window,\n                    is_sliding_window=True,        # <--- 开启滑动窗口\n                    is_causal=False                # <--- 关键：双向注意力\n                )\n\n        # 构建 Mapping\n        self_attn_mask_mapping = {\n            \"full_attention\": full_attn_mask,\n            \"sliding_attention\": sliding_attn_mask,\n        }\n\n        for layer_module in self.layers:\n            layer_outputs = layer_module(\n                hidden_states,\n                position_embeddings,\n                attention_mask=self_attn_mask_mapping[layer_module.attention_type],\n                **flash_attn_kwargs,\n            )\n\n            hidden_states = layer_outputs[0]\n\n        hidden_states = self.norm(hidden_states)\n\n        # Extract the special token output (first position) as pooled representation\n        cls_output = hidden_states[:, 0, :]\n        cls_output = rearrange(cls_output, \"(b t) c -> b t c\", b=B)\n        return cls_output\n\n\nclass AudioTokenDetokenizer(AceStepPreTrainedModel):\n    \"\"\"\n    Audio token detokenizer module.\n\n    Converts quantized audio tokens back to continuous acoustic representations.\n    Expands each token into multiple patches using special tokens, processes them\n    through encoder layers, and projects to acoustic hidden dimension.\n    \"\"\"\n    def __init__(self, config):\n        super().__init__(config)\n        self.config = config\n        self.embed_tokens = nn.Linear(config.hidden_size, config.hidden_size)\n        self.norm = Qwen3RMSNorm(config.hidden_size, eps=config.rms_norm_eps)\n        self.rotary_emb = Qwen3RotaryEmbedding(config=config)\n        self.gradient_checkpointing = False\n        # Special tokens for expanding each quantized token into patches\n        self.special_tokens = nn.Parameter(torch.randn(1, config.pool_window_size, config.hidden_size) * 0.02)\n        self.layers = nn.ModuleList(\n            [AceStepEncoderLayer(config, layer_idx) for layer_idx in range(config.num_attention_pooler_hidden_layers)]\n        )\n        # Project back to acoustic hidden dimension\n        self.proj_out = nn.Linear(config.hidden_size, config.audio_acoustic_hidden_dim)\n\n        # Initialize weights and apply final processing\n        self.post_init()\n\n    @can_return_tuple\n    def forward(self,\n        x,\n        attention_mask: Optional[torch.Tensor] = None,\n        **flash_attn_kwargs: Unpack[FlashAttentionKwargs],\n    ) -> BaseModelOutput:\n        B, T, D = x.shape\n        x = self.embed_tokens(x)\n        # Expand and add special tokens: N x T x D -> N x T x P x D\n        # Each token is expanded into pool_window_size patches\n        x = x.unsqueeze(2)  # N x T x 1 x D\n        x = x.repeat(1, 1, self.config.pool_window_size, 1)  # N x T x P x D\n        # Add learnable special tokens to each patch\n        special_tokens = self.special_tokens.expand(B, T, -1, -1)\n        x = x + special_tokens\n        # Reshape for processing: (batch * time) x patches x hidden\n        x = rearrange(x, \"b t p c -> (b t) p c\")\n\n        # Cache position: only used for mask construction\n        cache_position = torch.arange(0, x.shape[1], device=x.device)\n        # Positional IDs\n        position_ids = cache_position.unsqueeze(0)\n\n        # Initialize hidden states\n        hidden_states = x\n\n        # Create position embeddings to be shared across all layers\n        position_embeddings = self.rotary_emb(hidden_states, position_ids)\n\n        seq_len = x.shape[1]\n        dtype = x.dtype\n        device = x.device\n\n        # 判断是否使用 Flash Attention 2\n        is_flash_attn = (self.config._attn_implementation == \"flash_attention_2\")\n\n        # 初始化 Mask 变量\n        full_attn_mask = None\n        sliding_attn_mask = None\n\n        if is_flash_attn:\n            # -------------------------------------------------------\n            # 场景 A: Flash Attention 模式\n            # -------------------------------------------------------\n            # FA 不需要 4D Mask。\n            # 如果有 padding mask (attention_mask [B, L])，直接传给它即可。\n            # 如果没有 padding mask，传 None。\n            # 滑动窗口逻辑由 Layer 内部传给 FA kernel 的 sliding_window 参数控制。\n            full_attn_mask = attention_mask\n\n            # 这里的逻辑是：如果配置启用了滑动窗口，FA 模式下我们也只需要传基础的 padding mask\n            # Layer 会自己决定是否调用带 sliding window 的 kernel\n            sliding_attn_mask = attention_mask if self.config.use_sliding_window else None\n\n        else:\n            # -------------------------------------------------------\n            # 场景 B: CPU / Mac / SDPA (Eager 模式)\n            # -------------------------------------------------------\n            # 必须手动生成 4D Mask [B, 1, L, L]\n\n            # 1. Full Attention (Bidirectional, Global)\n            # 对应原来的 create_causal_mask + bidirectional\n            full_attn_mask = create_4d_mask(\n                seq_len=seq_len,\n                dtype=dtype,\n                device=device,\n                attention_mask=attention_mask,     # [B, L]\n                sliding_window=None,\n                is_sliding_window=False,\n                is_causal=False                    # <--- 关键：双向注意力\n            )\n\n            # 2. Sliding Attention (Bidirectional, Local)\n            # 对应原来的 create_sliding_window... + bidirectional\n            if self.config.use_sliding_window:\n                sliding_attn_mask = create_4d_mask(\n                    seq_len=seq_len,\n                    dtype=dtype,\n                    device=device,\n                    attention_mask=attention_mask, # [B, L]\n                    sliding_window=self.config.sliding_window,\n                    is_sliding_window=True,        # <--- 开启滑动窗口\n                    is_causal=False                # <--- 关键：双向注意力\n                )\n\n        # 构建 Mapping\n        self_attn_mask_mapping = {\n            \"full_attention\": full_attn_mask,\n            \"sliding_attention\": sliding_attn_mask,\n        }\n\n        for layer_module in self.layers:\n            layer_outputs = layer_module(\n                hidden_states,\n                position_embeddings,\n                attention_mask=self_attn_mask_mapping[layer_module.attention_type],\n                **flash_attn_kwargs,\n            )\n\n            hidden_states = layer_outputs[0]\n\n        hidden_states = self.norm(hidden_states)\n\n        hidden_states = self.proj_out(hidden_states)\n\n        hidden_states = rearrange(hidden_states, \"(b t) p c -> b (t p) c\", b=B, p=self.config.pool_window_size)\n        return hidden_states\n\n\nclass AceStepTimbreEncoder(AceStepPreTrainedModel):\n    \"\"\"\n    Encoder for extracting timbre embeddings from reference audio.\n\n    Processes packed reference audio acoustic features to extract timbre\n    representations. Uses a special token (CLS-like) to aggregate information\n    from the entire reference audio sequence. Outputs are unpacked back to\n    batch format for use in conditioning.\n    \"\"\"\n    def __init__(self, config):\n        super().__init__(config)\n\n        # Project acoustic features to model hidden size\n        self.embed_tokens = nn.Linear(config.timbre_hidden_dim, config.hidden_size)\n        self.norm = Qwen3RMSNorm(config.hidden_size, eps=config.rms_norm_eps)\n        self.rotary_emb = Qwen3RotaryEmbedding(config=config)\n        self.gradient_checkpointing = False\n        # Special token for aggregating timbre information (prepended to sequence)\n        self.special_token = nn.Parameter(torch.randn(1, 1, config.hidden_size))\n        self.layers = nn.ModuleList(\n            [AceStepEncoderLayer(config, layer_idx) for layer_idx in range(config.num_timbre_encoder_hidden_layers)]\n        )\n\n        # Initialize weights and apply final processing\n        self.post_init()\n\n    def unpack_timbre_embeddings(self, timbre_embs_packed, refer_audio_order_mask):\n        \"\"\"\n        Unpack packed timbre embeddings into batch format.\n\n        Args:\n            timbre_embs_packed: Packed timbre embeddings of shape [N, d]\n            refer_audio_order_mask: Order mask indicating batch assignment for each packed embedding\n\n        Returns:\n            Tuple of (unpacked_embeddings, mask):\n            - unpacked_embeddings: Unpacked embeddings of shape [B, max_count, d]\n            - new_mask: Mask indicating valid positions, shape [B, max_count]\n        \"\"\"\n        N, d = timbre_embs_packed.shape\n        device = timbre_embs_packed.device\n        dtype = timbre_embs_packed.dtype\n\n        # Get batch size\n        B = int(refer_audio_order_mask.max().item() + 1)\n\n        # Calculate element count and positions for each batch\n        counts = torch.bincount(refer_audio_order_mask, minlength=B)\n        max_count = counts.max().item()\n\n        # Calculate positions within batch\n        sorted_indices = torch.argsort(refer_audio_order_mask * N + torch.arange(N, device=device), stable=True)\n        sorted_batch_ids = refer_audio_order_mask[sorted_indices]\n\n        positions = torch.arange(N, device=device)\n        batch_starts = torch.cat([torch.tensor([0], device=device),\n                                torch.cumsum(counts, dim=0)[:-1]])\n        positions_in_sorted = positions - batch_starts[sorted_batch_ids]\n\n        inverse_indices = torch.empty_like(sorted_indices)\n        inverse_indices[sorted_indices] = torch.arange(N, device=device)\n        positions_in_batch = positions_in_sorted[inverse_indices]\n\n        # Use one-hot encoding and matrix multiplication (gradient-friendly approach)\n        # Create one-hot encoding\n        indices_2d = refer_audio_order_mask * max_count + positions_in_batch  # (N,)\n        one_hot = F.one_hot(indices_2d, num_classes=B * max_count).to(dtype)  # (N, B*max_count)\n\n        # Rearrange using matrix multiplication\n        timbre_embs_flat = one_hot.t() @ timbre_embs_packed  # (B*max_count, d)\n        timbre_embs_unpack = timbre_embs_flat.reshape(B, max_count, d)\n\n        # Create mask indicating valid positions\n        mask_flat = (one_hot.sum(dim=0) > 0).long()  # (B*max_count,)\n        new_mask = mask_flat.reshape(B, max_count)\n\n        return timbre_embs_unpack, new_mask\n\n    @can_return_tuple\n    def forward(\n        self,\n        refer_audio_acoustic_hidden_states_packed: Optional[torch.FloatTensor] = None,\n        refer_audio_order_mask: Optional[torch.LongTensor] = None,\n        attention_mask: Optional[torch.Tensor] = None,\n        **flash_attn_kwargs: Unpack[FlashAttentionKwargs],\n    ) -> BaseModelOutput:\n        inputs_embeds = refer_audio_acoustic_hidden_states_packed\n        # Project embeddings: N x T x timbre_hidden_dim -> N x T x hidden_size\n        inputs_embeds = self.embed_tokens(inputs_embeds)\n        # Prepend special token for timbre aggregation (CLS-like token)\n        # inputs_embeds = torch.cat([self.special_token.expand(inputs_embeds.shape[0], 1, -1), inputs_embeds], dim=1)\n        # Cache position: only used for mask construction (not for actual caching)\n        cache_position = torch.arange(0, inputs_embeds.shape[1], device=inputs_embeds.device)\n        # Positional IDs\n        position_ids = cache_position.unsqueeze(0)\n\n        seq_len = inputs_embeds.shape[1]\n        dtype = inputs_embeds.dtype\n        device = inputs_embeds.device\n\n        # 判断是否使用 Flash Attention 2\n        is_flash_attn = (self.config._attn_implementation == \"flash_attention_2\")\n\n        # 初始化 Mask 变量\n        full_attn_mask = None\n        sliding_attn_mask = None\n\n        if is_flash_attn:\n            # -------------------------------------------------------\n            # 场景 A: Flash Attention 模式\n            # -------------------------------------------------------\n            # FA 不需要 4D Mask。\n            # 如果有 padding mask (attention_mask [B, L])，直接传给它即可。\n            # 如果没有 padding mask，传 None。\n            # 滑动窗口逻辑由 Layer 内部传给 FA kernel 的 sliding_window 参数控制。\n            full_attn_mask = attention_mask\n\n            # 这里的逻辑是：如果配置启用了滑动窗口，FA 模式下我们也只需要传基础的 padding mask\n            # Layer 会自己决定是否调用带 sliding window 的 kernel\n            sliding_attn_mask = attention_mask if self.config.use_sliding_window else None\n\n        else:\n            # -------------------------------------------------------\n            # 场景 B: CPU / Mac / SDPA (Eager 模式)\n            # -------------------------------------------------------\n            # 必须手动生成 4D Mask [B, 1, L, L]\n\n            # 1. Full Attention (Bidirectional, Global)\n            # 对应原来的 create_causal_mask + bidirectional\n            full_attn_mask = create_4d_mask(\n                seq_len=seq_len,\n                dtype=dtype,\n                device=device,\n                attention_mask=attention_mask,     # [B, L]\n                sliding_window=None,\n                is_sliding_window=False,\n                is_causal=False                    # <--- 关键：双向注意力\n            )\n\n            # 2. Sliding Attention (Bidirectional, Local)\n            # 对应原来的 create_sliding_window... + bidirectional\n            if self.config.use_sliding_window:\n                sliding_attn_mask = create_4d_mask(\n                    seq_len=seq_len,\n                    dtype=dtype,\n                    device=device,\n                    attention_mask=attention_mask, # [B, L]\n                    sliding_window=self.config.sliding_window,\n                    is_sliding_window=True,        # <--- 开启滑动窗口\n                    is_causal=False                # <--- 关键：双向注意力\n                )\n\n        # 构建 Mapping\n        self_attn_mask_mapping = {\n            \"full_attention\": full_attn_mask,\n            \"sliding_attention\": sliding_attn_mask,\n        }\n\n        # Initialize hidden states\n        hidden_states = inputs_embeds\n\n        # Create position embeddings to be shared across all layers\n        position_embeddings = self.rotary_emb(hidden_states, position_ids)\n\n        # Pass through transformer layers\n        for layer_module in self.layers[: self.config.num_hidden_layers]:\n            layer_outputs = layer_module(\n                hidden_states,\n                position_embeddings,\n                self_attn_mask_mapping[layer_module.attention_type],\n                position_ids,\n                **flash_attn_kwargs,\n            )\n\n            hidden_states = layer_outputs[0]\n\n        hidden_states = self.norm(hidden_states)\n        # Extract special token output (first position) as timbre embedding: N x T x D -> N x D\n        hidden_states = hidden_states[:, 0, :]\n        # Unpack packed embeddings back to batch format\n        timbre_embs_unpack, timbre_embs_mask = self.unpack_timbre_embeddings(hidden_states, refer_audio_order_mask)\n        return timbre_embs_unpack, timbre_embs_mask\n\n\nclass AceStepAudioTokenizer(AceStepPreTrainedModel):\n    \"\"\"\n    Audio tokenizer module.\n\n    Converts continuous acoustic features into discrete quantized tokens.\n    Process: project -> pool patches -> quantize. Used for converting audio\n    representations into discrete tokens for processing by the diffusion model.\n    \"\"\"\n    def __init__(self, config):\n        super().__init__(config)\n        # Project acoustic features to hidden size\n        self.audio_acoustic_proj = nn.Linear(config.audio_acoustic_hidden_dim, config.hidden_size)\n        # Pool patches into sequence-level representations\n        self.attention_pooler = AttentionPooler(config)\n        # Quantize continuous representations into discrete tokens\n        self.quantizer = ResidualFSQ(\n            dim=config.fsq_dim,\n            levels=config.fsq_input_levels,\n            num_quantizers=config.fsq_input_num_quantizers\n        )\n        self.pool_window_size = config.pool_window_size\n        # Initialize weights and apply final processing\n        self.post_init()\n\n    @can_return_tuple\n    def forward(\n        self,\n        hidden_states: Optional[torch.FloatTensor] = None,\n        **flash_attn_kwargs: Unpack[FlashAttentionKwargs],\n    ) -> BaseModelOutput:\n\n        # Project acoustic features to hidden size\n        hidden_states = self.audio_acoustic_proj(hidden_states)\n        # Pool sequences: N x T//pool_window_size x pool_window_size x d -> N x T//pool_window_size x d\n        hidden_states = self.attention_pooler(hidden_states)\n        # Quantize continuous representations into discrete tokens: N x T//pool_window_size x d\n        quantized, indices = self.quantizer(hidden_states)\n        return quantized, indices\n\n    def tokenize(self, x):\n        x = rearrange(x, 'n (t_patch p) d -> n t_patch p d', p=self.pool_window_size)\n        quantized, indices = self.forward(x)\n        return quantized, indices\n\nclass Lambda(nn.Module):\n    \"\"\"\n    Wrapper module for arbitrary lambda functions.\n\n    Allows using lambda functions in nn.Sequential by wrapping them in a Module.\n    Useful for simple transformations like transpose operations.\n    \"\"\"\n    def __init__(self, func):\n        super().__init__()\n        self.func = func\n\n    def forward(self, x):\n        return self.func(x)\n\n\nclass AceStepDiTModel(AceStepPreTrainedModel):\n    \"\"\"\n    DiT (Diffusion Transformer) model for AceStep.\n\n    Main diffusion model that generates audio latents conditioned on text, lyrics,\n    and timbre. Uses patch-based processing with transformer layers, timestep\n    conditioning, and cross-attention to encoder outputs.\n    \"\"\"\n    def __init__(self, config: AceStepConfig):\n        super().__init__(config)\n        # Rotary position embeddings for transformer layers\n        self.rotary_emb = Qwen3RotaryEmbedding(config)\n        # Stack of DiT transformer layers\n        self.layers = nn.ModuleList(\n            [AceStepDiTLayer(config, layer_idx) for layer_idx in range(config.num_hidden_layers)]\n        )\n\n        in_channels = config.in_channels\n        inner_dim = config.hidden_size\n        patch_size = config.patch_size\n        self.patch_size = patch_size\n\n        # Input projection: patch embedding using 1D convolution\n        # Converts sequence into patches for efficient processing\n        self.proj_in = nn.Sequential(\n            Lambda(lambda x: x.transpose(1, 2)),  # [B, T, C] -> [B, C, T]\n            nn.Conv1d(\n                in_channels=in_channels,\n                out_channels=inner_dim,\n                kernel_size=patch_size,\n                stride=patch_size,\n                padding=0,\n            ),\n            Lambda(lambda x: x.transpose(1, 2)),  # [B, C, T//patch_size] -> [B, T//patch_size, C]\n        )\n\n        # Timestep embeddings for diffusion conditioning\n        # Two embeddings: one for timestep t, one for timestep difference (t - r)\n        self.time_embed = TimestepEmbedding(in_channels=256, time_embed_dim=inner_dim)\n        self.time_embed_r = TimestepEmbedding(in_channels=256, time_embed_dim=inner_dim)\n\n        # Project encoder hidden states to model dimension\n        self.condition_embedder = nn.Linear(inner_dim, inner_dim, bias=True)\n\n        # Output normalization and projection\n        # Adaptive layer norm with scale-shift modulation, then de-patchify\n        self.norm_out = Qwen3RMSNorm(inner_dim, eps=config.rms_norm_eps)\n        self.proj_out = nn.Sequential(\n            Lambda(lambda x: x.transpose(1, 2)),  # [B, T//patch_size, inner_dim] -> [B, inner_dim, T//patch_size]\n            nn.ConvTranspose1d(\n                in_channels=inner_dim,\n                out_channels=config.audio_acoustic_hidden_dim,\n                kernel_size=patch_size,\n                stride=patch_size,\n                padding=0,\n            ),\n            Lambda(lambda x: x.transpose(1, 2)),  # [B, out_channels, T] -> [B, T, out_channels]\n        )\n        # Scale-shift table for adaptive output normalization (2 values: shift, scale)\n        self.scale_shift_table = nn.Parameter(torch.randn(1, 2, inner_dim) / inner_dim**0.5)\n\n        self.gradient_checkpointing = False\n\n    def forward(\n        self,\n        hidden_states: torch.Tensor,\n        timestep: torch.Tensor,\n        timestep_r: torch.Tensor,\n        attention_mask: torch.Tensor,\n        encoder_hidden_states: torch.Tensor,\n        encoder_attention_mask: torch.Tensor,\n        context_latents: torch.Tensor,\n        use_cache: Optional[bool] = None,\n        past_key_values: Optional[EncoderDecoderCache] = None,\n        cache_position: Optional[torch.LongTensor] = None,\n        position_ids: Optional[torch.LongTensor] = None,\n        output_attentions: Optional[bool] = False,\n        return_hidden_states: int = None,\n        custom_layers_config: Optional[dict] = None,\n        enable_early_exit: bool = False,\n        **flash_attn_kwargs: Unpack[FlashAttentionKwargs],\n    ):\n\n        use_cache = use_cache if use_cache is not None else self.config.use_cache\n\n        # Disable cache during training or when gradient checkpointing is enabled\n        if self.gradient_checkpointing and self.training and use_cache:\n            logger.warning_once(\n                \"`use_cache=True` is incompatible with gradient checkpointing. Setting `use_cache=False`.\"\n            )\n            use_cache = False\n        if self.training:\n            use_cache = False\n\n        # Initialize cache if needed (only during inference for auto-regressive generation)\n        if not self.training and use_cache and past_key_values is None:\n            past_key_values = EncoderDecoderCache(DynamicCache(), DynamicCache())\n\n        # Compute timestep embeddings for diffusion conditioning\n        # Two embeddings: one for timestep t, one for timestep difference (t - r)\n        temb_t, timestep_proj_t = self.time_embed(timestep)\n        temb_r, timestep_proj_r = self.time_embed_r(timestep - timestep_r)\n        # Combine embeddings\n        temb = temb_t + temb_r\n        timestep_proj = timestep_proj_t + timestep_proj_r\n\n        # Concatenate context latents (source latents + chunk masks) with hidden states\n        hidden_states = torch.cat([context_latents, hidden_states], dim=-1)\n        # Record original sequence length for later restoration after padding\n        original_seq_len = hidden_states.shape[1]\n        # Apply padding if sequence length is not divisible by patch_size\n        # This ensures proper patch extraction\n        pad_length = 0\n        if hidden_states.shape[1] % self.patch_size != 0:\n            pad_length = self.patch_size - (hidden_states.shape[1] % self.patch_size)\n            hidden_states = F.pad(hidden_states, (0, 0, 0, pad_length), mode='constant', value=0)\n\n        # Project input to patches and project encoder states\n        hidden_states = self.proj_in(hidden_states)\n        encoder_hidden_states = self.condition_embedder(encoder_hidden_states)\n\n        # Cache positions\n        if cache_position is None:\n            past_seen_tokens = past_key_values.get_seq_length() if past_key_values is not None else 0\n            cache_position = torch.arange(\n                past_seen_tokens, past_seen_tokens + hidden_states.shape[1], device=hidden_states.device\n            )\n\n        # Position IDs\n        if position_ids is None:\n            position_ids = cache_position.unsqueeze(0)\n\n\n        seq_len = hidden_states.shape[1]\n        encoder_seq_len = encoder_hidden_states.shape[1]\n        dtype = hidden_states.dtype\n        device = hidden_states.device\n\n        # 判断是否使用 Flash Attention 2\n        is_flash_attn = (self.config._attn_implementation == \"flash_attention_2\")\n\n        # 初始化 Mask 变量\n        full_attn_mask = None\n        sliding_attn_mask = None\n        encoder_attention_mask = None\n        attention_mask = None\n        if is_flash_attn:\n            # -------------------------------------------------------\n            # 场景 A: Flash Attention 模式\n            # -------------------------------------------------------\n            # FA 不需要 4D Mask。\n            # 如果有 padding mask (attention_mask [B, L])，直接传给它即可。\n            # 如果没有 padding mask，传 None。\n            # 滑动窗口逻辑由 Layer 内部传给 FA kernel 的 sliding_window 参数控制。\n            full_attn_mask = attention_mask\n\n            # 这里的逻辑是：如果配置启用了滑动窗口，FA 模式下我们也只需要传基础的 padding mask\n            # Layer 会自己决定是否调用带 sliding window 的 kernel\n            sliding_attn_mask = attention_mask if self.config.use_sliding_window else None\n\n        else:\n            # -------------------------------------------------------\n            # 场景 B: CPU / Mac / SDPA (Eager 模式)\n            # -------------------------------------------------------\n            # 必须手动生成 4D Mask [B, 1, L, L]\n\n            # 1. Full Attention (Bidirectional, Global)\n            # 对应原来的 create_causal_mask + bidirectional\n            full_attn_mask = create_4d_mask(\n                seq_len=seq_len,\n                dtype=dtype,\n                device=device,\n                attention_mask=attention_mask,     # [B, L]\n                sliding_window=None,\n                is_sliding_window=False,\n                is_causal=False                    # <--- 关键：双向注意力\n            )\n            max_len = max(seq_len, encoder_seq_len)\n\n            encoder_attention_mask = create_4d_mask(\n                seq_len=max_len,\n                dtype=dtype,\n                device=device,\n                attention_mask=attention_mask,     # [B, L]\n                sliding_window=None,\n                is_sliding_window=False,\n                is_causal=False                    # <--- 关键：双向注意力\n            )\n            encoder_attention_mask = encoder_attention_mask[:, :, :seq_len, :encoder_seq_len]\n            # 2. Sliding Attention (Bidirectional, Local)\n            # 对应原来的 create_sliding_window... + bidirectional\n            if self.config.use_sliding_window:\n                sliding_attn_mask = create_4d_mask(\n                    seq_len=seq_len,\n                    dtype=dtype,\n                    device=device,\n                    attention_mask=attention_mask, # [B, L]\n                    sliding_window=self.config.sliding_window,\n                    is_sliding_window=True,        # <--- 开启滑动窗口\n                    is_causal=False                # <--- 关键：双向注意力\n                )\n\n        # 构建 Mapping\n        self_attn_mask_mapping = {\n            \"full_attention\": full_attn_mask,\n            \"sliding_attention\": sliding_attn_mask,\n            \"encoder_attention_mask\": encoder_attention_mask,\n        }\n\n        # Create position embeddings to be shared across all decoder layers\n        position_embeddings = self.rotary_emb(hidden_states, position_ids)\n        all_cross_attentions = () if output_attentions else None\n\n        # Handle early exit for custom layer configurations\n        max_needed_layer = float('inf')\n        if custom_layers_config is not None and enable_early_exit:\n            max_needed_layer = max(custom_layers_config.keys())\n            # Force output_attentions to True when early exit is enabled for attention extraction\n            output_attentions = True\n            if all_cross_attentions is None:\n                all_cross_attentions = ()\n\n        # Process through transformer layers\n        for index_block, layer_module in enumerate(self.layers):\n\n            layer_outputs = layer_module(\n                hidden_states,\n                position_embeddings,\n                timestep_proj,\n                self_attn_mask_mapping[layer_module.attention_type],\n                position_ids,\n                past_key_values,\n                output_attentions,\n                use_cache,\n                cache_position,\n                encoder_hidden_states,\n                self_attn_mask_mapping[\"encoder_attention_mask\"],\n                **flash_attn_kwargs,\n            )\n            hidden_states = layer_outputs[0]\n\n            if output_attentions and self.layers[index_block].use_cross_attention:\n                # layer_outputs structure: (hidden_states, self_attn_weights, cross_attn_weights)\n                # Extract the last element which is cross_attn_weights\n                if len(layer_outputs) >= 3:\n                    all_cross_attentions += (layer_outputs[2],)\n\n        if return_hidden_states:\n            return hidden_states\n\n        # Extract scale-shift parameters for adaptive output normalization\n        shift, scale = (self.scale_shift_table + temb.unsqueeze(1)).chunk(2, dim=1)\n        shift = shift.to(hidden_states.device)\n        scale = scale.to(hidden_states.device)\n\n        # Apply adaptive layer norm: norm(x) * (1 + scale) + shift\n        hidden_states = (self.norm_out(hidden_states) * (1 + scale) + shift).type_as(hidden_states)\n        # Project output: de-patchify back to original sequence format\n        hidden_states = self.proj_out(hidden_states)\n\n        # Crop back to original sequence length to ensure exact length match (remove padding)\n        hidden_states = hidden_states[:, :original_seq_len, :]\n\n        outputs = (hidden_states, past_key_values)\n\n        if output_attentions:\n            outputs += (all_cross_attentions,)\n        return outputs\n\nclass AceStepConditionEncoder(AceStepPreTrainedModel):\n    \"\"\"\n    Condition encoder for AceStep model.\n\n    Encodes multiple conditioning inputs (text, lyrics, timbre) and packs them\n    into a single sequence for cross-attention in the diffusion model. Handles\n    projection, encoding, and sequence packing.\n    \"\"\"\n    def __init__(self, config: AceStepConfig):\n        super().__init__(config)\n        self.config = config\n        # Project text embeddings to model hidden size\n        self.text_projector = nn.Linear(config.text_hidden_dim, config.hidden_size, bias=False)\n        # Encoder for lyric text\n        self.lyric_encoder = AceStepLyricEncoder(config)\n        # Encoder for timbre from reference audio\n        self.timbre_encoder = AceStepTimbreEncoder(config)\n\n    def forward(\n        self,\n        # Text inputs\n        text_hidden_states: Optional[torch.FloatTensor] = None,\n        text_attention_mask: Optional[torch.Tensor] = None,\n        # Lyric inputs\n        lyric_hidden_states: Optional[torch.LongTensor] = None,\n        lyric_attention_mask: Optional[torch.Tensor] = None,\n        # Reference audio for timbre\n        refer_audio_acoustic_hidden_states_packed: Optional[torch.Tensor] = None,\n        refer_audio_order_mask: Optional[torch.LongTensor] = None,\n    ):\n        # Project and encode text\n        text_hidden_states = self.text_projector(text_hidden_states)\n        # Encode lyrics\n        lyric_encoder_outputs = self.lyric_encoder(\n            inputs_embeds=lyric_hidden_states,\n            attention_mask=lyric_attention_mask,\n        )\n        lyric_hidden_states = lyric_encoder_outputs.last_hidden_state\n        # Encode timbre from reference audio\n        timbre_embs_unpack, timbre_embs_mask = self.timbre_encoder(refer_audio_acoustic_hidden_states_packed, refer_audio_order_mask)\n\n        # Pack sequences: combine lyrics and timbre, then add text\n        # This creates a single sequence with all conditioning information\n        encoder_hidden_states, encoder_attention_mask = pack_sequences(lyric_hidden_states, timbre_embs_unpack, lyric_attention_mask, timbre_embs_mask)\n        encoder_hidden_states, encoder_attention_mask = pack_sequences(encoder_hidden_states, text_hidden_states, encoder_attention_mask, text_attention_mask)\n        return encoder_hidden_states, encoder_attention_mask\n\n\ndef _repaint_step_injection(xt, clean_src, mask, t_next, noise):\n    \"\"\"Replace non-repaint regions of *xt* with noised source latents.\"\"\"\n    zt = t_next * noise + (1.0 - t_next) * clean_src\n    m = mask.unsqueeze(-1).expand_as(xt)\n    return torch.where(m, xt, zt)\n\n\ndef _repaint_boundary_blend(x_gen, clean_src, mask, cf_frames):\n    \"\"\"Blend generated latents with source at repaint boundaries.\"\"\"\n    soft = mask.float().clone()\n    if cf_frames <= 0:\n        m = soft.unsqueeze(-1).expand_as(x_gen)\n        return m * x_gen + (1.0 - m) * clean_src\n    B, T = mask.shape\n    for b in range(B):\n        row = mask[b]\n        if row.all() or not row.any():\n            continue\n        idx = torch.nonzero(row, as_tuple=False).squeeze(-1)\n        if idx.numel() == 0:\n            continue\n        left, right = idx[0].item(), idx[-1].item() + 1\n        fs = max(left - cf_frames, 0)\n        if left - fs > 0:\n            soft[b, fs:left] = torch.linspace(0, 1, left - fs + 2, device=soft.device)[1:-1]\n        fe = min(right + cf_frames, T)\n        if fe - right > 0:\n            soft[b, right:fe] = torch.linspace(1, 0, fe - right + 2, device=soft.device)[1:-1]\n    m = soft.unsqueeze(-1).expand_as(x_gen)\n    return m * x_gen + (1.0 - m) * clean_src\n\n\nclass AceStepConditionGenerationModel(AceStepPreTrainedModel):\n    \"\"\"\n    Main conditional generation model for AceStep.\n\n    End-to-end model for generating audio conditioned on text, lyrics, and timbre.\n    Combines encoder (for conditioning), decoder (diffusion model), tokenizer\n    (for discrete tokenization), and detokenizer (for reconstruction).\n    Supports flow matching training and inference with various sampling methods.\n    \"\"\"\n    def __init__(self, config: AceStepConfig):\n        super().__init__(config)\n        self.config = config\n        # Diffusion model components\n        self.decoder = AceStepDiTModel(config)  # Main diffusion transformer\n        self.encoder = AceStepConditionEncoder(config)  # Condition encoder\n        self.tokenizer = AceStepAudioTokenizer(config)  # Audio tokenizer\n        self.detokenizer = AudioTokenDetokenizer(config)  # Audio detokenizer\n        # Null condition embedding for classifier-free guidance\n        self.null_condition_emb = nn.Parameter(torch.randn(1, 1, config.hidden_size))\n\n        # Initialize weights and apply final processing\n        self.post_init()\n\n    def tokenize(self, x, silence_latent, attention_mask):\n        if x.shape[1] % self.config.pool_window_size != 0:\n            pad_len = self.config.pool_window_size - (x.shape[1] % self.config.pool_window_size)\n            x = torch.cat([x,  silence_latent[:1,:pad_len].repeat(x.shape[0],1,1)], dim=1)\n            attention_mask = F.pad(attention_mask, (0, pad_len), mode='constant', value=0)\n        x = rearrange(x, 'n (t_patch p) d -> n t_patch p d', p=self.config.pool_window_size)\n        seq_len = x.shape[1]\n        chunk = math.ceil(attention_mask.shape[1] / seq_len)\n        attention_mask = attention_mask.to(x.dtype)\n        attention_mask = F.max_pool1d(attention_mask.unsqueeze(1), kernel_size=chunk, stride=chunk, ceil_mode=True).squeeze(1)\n        quantized, indices = self.tokenizer(x)\n        return quantized, indices, attention_mask\n\n    def detokenize(self, quantized):\n        \"\"\"\n        Detokenize quantized audio tokens back to continuous representations.\n\n        Args:\n            quantized: Quantized tokens of shape [N, T//pool_window_size, d]\n\n        Returns:\n            Detokenized hidden states of shape [N, T, d]\n        \"\"\"\n        hidden_states = self.detokenizer(quantized)\n        return hidden_states\n\n    @torch.no_grad()\n    def prepare_condition(\n        self,\n        text_hidden_states: torch.FloatTensor,\n        text_attention_mask: torch.Tensor,\n        lyric_hidden_states: torch.FloatTensor,\n        lyric_attention_mask: torch.Tensor,\n        refer_audio_acoustic_hidden_states_packed: torch.FloatTensor,\n        refer_audio_order_mask: torch.Tensor,\n        hidden_states: torch.FloatTensor,\n        attention_mask: torch.Tensor,\n        silence_latent: torch.FloatTensor,\n        src_latents: torch.FloatTensor,\n        chunk_masks: torch.Tensor,\n        is_covers: torch.Tensor,\n        precomputed_lm_hints_25Hz: Optional[torch.FloatTensor] = None,\n        audio_codes: torch.FloatTensor = None,\n    ):\n\n        dtype = hidden_states.dtype\n        encoder_hidden_states, encoder_attention_mask = self.encoder(\n            text_hidden_states=text_hidden_states,\n            text_attention_mask=text_attention_mask,\n            lyric_hidden_states=lyric_hidden_states,\n            lyric_attention_mask=lyric_attention_mask,\n            refer_audio_acoustic_hidden_states_packed=refer_audio_acoustic_hidden_states_packed,\n            refer_audio_order_mask=refer_audio_order_mask,\n        )\n\n        # N x T x d -> N x T//pool_window_size x pool_window_size x d\n        # tokenize and detokenize to get LM hints for cover songs (when is_covers=True)\n        # Use precomputed hints if provided (e.g., from audio codes), otherwise tokenize hidden_states\n        if precomputed_lm_hints_25Hz is not None:\n            print(\"Using precomputed LM hints\")\n            lm_hints_25Hz = precomputed_lm_hints_25Hz[:, :src_latents.shape[1], :]\n        else:\n            if audio_codes is not None:\n                lm_hints_5Hz = self.tokenize.quantizer.get_output_from_indices(audio_codes)\n            else:\n                lm_hints_5Hz, indices, llm_mask = self.tokenize(hidden_states, silence_latent, attention_mask)\n            lm_hints_25Hz = self.detokenize(lm_hints_5Hz)\n            # Crop lm_hints_25Hz to match src_latents length (tokenize may have added padding)\n            lm_hints_25Hz = lm_hints_25Hz[:, :src_latents.shape[1], :]\n        src_latents = torch.where(is_covers.unsqueeze(-1).unsqueeze(-1) > 0, lm_hints_25Hz, src_latents)\n        # Concatenate source latents with chunk masks as context\n        context_latents = torch.cat([src_latents, chunk_masks.to(dtype)], dim=-1)\n        return encoder_hidden_states, encoder_attention_mask, context_latents\n\n    def forward(\n        self,\n        # Diffusion inputs\n        hidden_states: torch.FloatTensor,\n        attention_mask: torch.Tensor,\n        # Encoder inputs\n        # Text\n        text_hidden_states: Optional[torch.FloatTensor] = None,\n        text_attention_mask: Optional[torch.Tensor] = None,\n        # Lyric\n        lyric_hidden_states: Optional[torch.LongTensor] = None,\n        lyric_attention_mask: Optional[torch.Tensor] = None,\n        # Reference audio for timbre\n        refer_audio_acoustic_hidden_states_packed: Optional[torch.Tensor] = None,\n        refer_audio_order_mask: Optional[torch.LongTensor] = None,\n        src_latents: torch.FloatTensor = None,\n        chunk_masks: torch.FloatTensor = None,\n        is_covers: torch.Tensor = None,\n        silence_latent: torch.FloatTensor = None,\n        cfg_ratio: float = 0.15,\n    ):\n        \"\"\"\n        Forward pass for training (computes training losses).\n        \"\"\"\n        # Prepare conditioning inputs (encoder states, context latents)\n        encoder_hidden_states, encoder_attention_mask, context_latents = self.prepare_condition(\n            text_hidden_states=text_hidden_states,\n            text_attention_mask=text_attention_mask,\n            lyric_hidden_states=lyric_hidden_states,\n            lyric_attention_mask=lyric_attention_mask,\n            refer_audio_acoustic_hidden_states_packed=refer_audio_acoustic_hidden_states_packed,\n            refer_audio_order_mask=refer_audio_order_mask,\n            hidden_states=src_latents,\n            attention_mask=attention_mask,\n            silence_latent=silence_latent,\n            src_latents=src_latents,\n            chunk_masks=chunk_masks,\n            is_covers=is_covers,\n        )\n        bsz, device, dtype = hidden_states.shape[0], hidden_states.device, hidden_states.dtype\n        # Classifier-free guidance: randomly drop conditions with probability cfg_ratio\n        # This helps the model learn to work with and without conditions\n        full_cfg_condition_mask = torch.where(\n            (torch.rand(size=(bsz,), device=device, dtype=dtype) < cfg_ratio),\n            torch.zeros(size=(bsz,), device=device, dtype=dtype),\n            torch.ones(size=(bsz,), device=device, dtype=dtype)\n        ).view(-1, 1, 1)\n        # Replace dropped conditions with null condition embedding\n        encoder_hidden_states = torch.where(full_cfg_condition_mask > 0, encoder_hidden_states, self.null_condition_emb.expand_as(encoder_hidden_states))\n\n        # Flow matching setup: sample noise x1 and interpolate with data x0\n        x1 = torch.randn_like(hidden_states)  # Noise\n        x0 = hidden_states  # Data\n        # Sample timesteps t and r for flow matching\n        t, r = sample_t_r(bsz, device, dtype, self.config.data_proportion, self.config.timestep_mu, self.config.timestep_sigma, use_meanflow=False)\n        t_ = t.unsqueeze(-1).unsqueeze(-1)\n        # Interpolate: x_t = t * x1 + (1 - t) * x0\n        xt = t_ * x1 + (1.0 - t_) * x0\n\n        # Predict flow (velocity) from diffusion model\n        decoder_outputs = self.decoder(\n            hidden_states=xt,\n            timestep=t,\n            timestep_r=t,\n            attention_mask=attention_mask,\n            encoder_hidden_states=encoder_hidden_states,\n            encoder_attention_mask=encoder_attention_mask,\n            context_latents=context_latents,\n        )\n        # Flow matching loss: predict the flow field v = x1 - x0\n        flow = x1 - x0\n        diffusion_loss = F.mse_loss(decoder_outputs[0], flow)\n        return {\n            \"diffusion_loss\": diffusion_loss,\n        }\n\n    def training_losses(self, **kwargs):\n        return self.forward(**kwargs)\n\n    def prepare_noise(self, context_latents: torch.FloatTensor, seed: Union[int, List[int], None] = None):\n        \"\"\"\n        Prepare noise tensor for generation with optional seeding.\n\n        Args:\n            context_latents: Context latents to determine noise shape\n            seed: Can be int, List[int], or None. If None, uses random noise.\n\n        Returns:\n            Noise tensor of appropriate shape\n        \"\"\"\n        bsz = context_latents.shape[0]\n        device = context_latents.device\n        dtype = context_latents.dtype\n        # Handle seed: can be int, List[int], or None\n        src_latents_shape = (context_latents.shape[0], context_latents.shape[1], context_latents.shape[-1] // 2)\n        if seed is None:\n            # No seed provided - use random\n            noise = torch.randn(src_latents_shape, device=device, dtype=dtype)\n        elif isinstance(seed, list):\n            # List of seeds - generate noise for each sample separately\n            noise_list = []\n            for i, s in enumerate(seed):\n                if s is None or s < 0:\n                    # Random seed for this sample\n                    noise_i = torch.randn(1, src_latents_shape[1], src_latents_shape[2], device=device, dtype=dtype)\n                else:\n                    # Use specific seed for this sample\n                    generator = torch.Generator(device=device).manual_seed(int(s))\n                    noise_i = torch.randn(1, src_latents_shape[1], src_latents_shape[2], generator=generator, device=device, dtype=dtype)\n                noise_list.append(noise_i)\n            noise = torch.cat(noise_list, dim=0)\n        else:\n            # Single seed for all samples\n            generator = torch.Generator(device=device).manual_seed(int(seed))\n            noise = torch.randn(src_latents_shape, generator=generator, device=device, dtype=dtype)\n\n        return noise\n\n    def get_x0_from_noise(self, zt, vt, t):\n        if t.shape[0] != zt.shape[0]:\n            raise ValueError(f\"Batch size mismatch: t has {t.shape[0]}, zt has {zt.shape[0]}\")\n\n        return zt - vt * t.unsqueeze(-1).unsqueeze(-1)\n\n    def renoise(self, x, t, noise=None):\n        if noise is None:\n            noise = torch.randn_like(x)\n        if isinstance(t, torch.Tensor) and t.ndim != x.ndim:\n            t = t.unsqueeze(-1).unsqueeze(-1)\n        xt = t * noise + (1 - t) * x\n        return xt\n\n    def generate_audio(\n        self,\n        text_hidden_states: torch.FloatTensor,\n        text_attention_mask: torch.FloatTensor,\n        lyric_hidden_states: torch.FloatTensor,\n        lyric_attention_mask: torch.FloatTensor,\n        refer_audio_acoustic_hidden_states_packed: torch.FloatTensor,\n        refer_audio_order_mask: torch.LongTensor,\n        src_latents: torch.FloatTensor,\n        chunk_masks: torch.FloatTensor,\n        is_covers: torch.Tensor,\n        silence_latent: Optional[torch.FloatTensor] = None,\n        attention_mask: torch.Tensor = None,\n        seed: int = None,\n        infer_method: str = \"ode\",\n        use_cache: bool = True,\n        infer_steps: int = 30,\n        diffusion_guidance_sale: float = 7.0,\n        audio_cover_strength: float = 1.0,\n        non_cover_text_hidden_states: Optional[torch.FloatTensor] = None,\n        non_cover_text_attention_mask: Optional[torch.FloatTensor] = None,\n        cfg_interval_start: float = 0.0,\n        cfg_interval_end: float = 1.0,\n        precomputed_lm_hints_25Hz: Optional[torch.FloatTensor] = None,\n        audio_codes: Optional[torch.FloatTensor] = None,\n        use_progress_bar: bool = True,\n        use_adg: bool = False,\n        shift: float = 1.0,\n        cover_noise_strength: float = 0.0,\n        repaint_mask: Optional[torch.Tensor] = None,\n        clean_src_latents: Optional[torch.FloatTensor] = None,\n        repaint_crossfade_frames: int = 10,\n        repaint_injection_ratio: float = 0.5,\n        **kwargs,\n    ):\n        if attention_mask is None:\n            latent_length = src_latents.shape[1]\n            attention_mask = torch.ones(src_latents.shape[0], latent_length, device=src_latents.device, dtype=src_latents.dtype)\n        time_costs = {}\n        start_time = time.time()\n        total_start_time = start_time\n        encoder_hidden_states, encoder_attention_mask, context_latents = self.prepare_condition(\n            text_hidden_states=text_hidden_states,\n            text_attention_mask=text_attention_mask,\n            lyric_hidden_states=lyric_hidden_states,\n            lyric_attention_mask=lyric_attention_mask,\n            refer_audio_acoustic_hidden_states_packed=refer_audio_acoustic_hidden_states_packed,\n            refer_audio_order_mask=refer_audio_order_mask,\n            hidden_states=src_latents,\n            attention_mask=attention_mask,\n            silence_latent=silence_latent,\n            src_latents=src_latents,\n            chunk_masks=chunk_masks,\n            is_covers=is_covers,\n            precomputed_lm_hints_25Hz=precomputed_lm_hints_25Hz,\n            audio_codes=audio_codes,\n        )\n        encoder_hidden_states_non_cover, encoder_attention_mask_non_cover, context_latents_non_cover = None, None, None\n        if audio_cover_strength < 1.0:\n            non_is_covers = torch.zeros_like(is_covers, device=is_covers.device, dtype=is_covers.dtype)\n            # Use silence_latent for non-cover condition to simulate text2music mode (no reference audio)\n            silence_latent_expanded = silence_latent[:, :src_latents.shape[1], :].expand(src_latents.shape[0], -1, -1)\n            encoder_hidden_states_non_cover, encoder_attention_mask_non_cover, context_latents_non_cover = self.prepare_condition(\n            text_hidden_states=non_cover_text_hidden_states,\n            text_attention_mask=non_cover_text_attention_mask,\n            lyric_hidden_states=lyric_hidden_states,\n            lyric_attention_mask=lyric_attention_mask,\n            refer_audio_acoustic_hidden_states_packed=refer_audio_acoustic_hidden_states_packed,\n            refer_audio_order_mask=refer_audio_order_mask,\n            hidden_states=silence_latent_expanded,\n            attention_mask=attention_mask,\n            silence_latent=silence_latent,\n            src_latents=silence_latent_expanded,\n            chunk_masks=chunk_masks,\n            is_covers=non_is_covers,\n            precomputed_lm_hints_25Hz=None,\n            audio_codes=None,\n        )\n        end_time = time.time()\n        time_costs[\"encoder_time_cost\"] = end_time - start_time\n        start_time = end_time\n\n        # Calculate cover steps based on audio_cover_strength\n        cover_steps = int(infer_steps * audio_cover_strength)\n        device, dtype = context_latents.device, context_latents.dtype\n        t = torch.linspace(1.0, 0.0, infer_steps + 1, device=device, dtype=dtype)\n        # Apply shift transformation to timesteps if shift != 1.0\n        if shift != 1.0:\n            t = shift * t / (1 + (shift - 1) * t)\n        if use_progress_bar:\n            iterator = tqdm(zip(t[:-1], t[1:]), total=infer_steps)\n        else:\n            iterator = zip(t[:-1], t[1:])\n\n        noise = self.prepare_noise(context_latents, seed)\n        bsz, device, dtype = context_latents.shape[0], context_latents.device, context_latents.dtype\n        past_key_values = EncoderDecoderCache(DynamicCache(), DynamicCache())\n        momentum_buffer = MomentumBuffer()\n\n        # Cover noise initialization: blend noise with src_latents\n        if cover_noise_strength > 0.0:\n            # cover_noise_strength=1 means closest to src, so noise_level should be low\n            effective_noise_level = 1.0 - cover_noise_strength\n            # Find nearest timestep in the schedule t[:-1]\n            t_values = t[:-1].tolist()\n            nearest_t = min(t_values, key=lambda x: abs(x - effective_noise_level))\n            start_idx = t_values.index(nearest_t)\n            # xt = nearest_t * noise + (1 - nearest_t) * src_latents\n            xt = self.renoise(src_latents, nearest_t, noise)\n            # Truncate schedule to start from nearest_t\n            t = t[start_idx:]\n            infer_steps = len(t) - 1\n            cover_steps = int(infer_steps * audio_cover_strength)\n            if use_progress_bar:\n                iterator = tqdm(zip(t[:-1], t[1:]), total=infer_steps)\n            else:\n                iterator = zip(t[:-1], t[1:])\n            logger.info(\n                f\"[generate_audio] Cover mode: cover_noise_strength={cover_noise_strength}, \"\n                f\"effective_noise_level={effective_noise_level:.4f}, nearest_t={nearest_t:.4f}, \"\n                f\"remaining_steps={infer_steps}\"\n            )\n        else:\n            xt = noise\n\n        # main task condition\n        do_cfg_guidance = diffusion_guidance_sale > 1.0\n        if do_cfg_guidance:\n            encoder_hidden_states = torch.cat([encoder_hidden_states, self.null_condition_emb.expand_as(encoder_hidden_states)], dim=0)\n            encoder_attention_mask = torch.cat([encoder_attention_mask, encoder_attention_mask], dim=0)\n            # src_latents\n            context_latents = torch.cat([context_latents, context_latents], dim=0)\n            attention_mask = torch.cat([attention_mask, attention_mask], dim=0)\n\n        _switched_to_non_cover = False\n        with torch.no_grad():\n            for step_idx, (t_curr, t_prev) in enumerate(iterator):\n                if step_idx >= cover_steps and not _switched_to_non_cover:\n                    _switched_to_non_cover = True\n                    if do_cfg_guidance:\n                        encoder_hidden_states_non_cover = torch.cat([encoder_hidden_states_non_cover, self.null_condition_emb.expand_as(encoder_hidden_states_non_cover)], dim=0)\n                        encoder_attention_mask_non_cover = torch.cat([encoder_attention_mask_non_cover, encoder_attention_mask_non_cover], dim=0)\n                        # src_latents\n                        context_latents_non_cover = torch.cat([context_latents_non_cover, context_latents_non_cover], dim=0)\n\n                    encoder_hidden_states = encoder_hidden_states_non_cover\n                    encoder_attention_mask = encoder_attention_mask_non_cover\n                    context_latents = context_latents_non_cover\n                    past_key_values = EncoderDecoderCache(DynamicCache(), DynamicCache())\n\n                x = torch.cat([xt, xt], dim=0) if do_cfg_guidance else xt\n                t_curr_tensor = t_curr * torch.ones((x.shape[0],), device=device, dtype=dtype)\n                decoder_outputs = self.decoder(\n                    hidden_states=x,\n                    timestep=t_curr_tensor,\n                    timestep_r=t_curr_tensor,\n                    attention_mask=attention_mask,\n                    encoder_hidden_states=encoder_hidden_states,\n                    encoder_attention_mask=encoder_attention_mask,\n                    context_latents=context_latents,\n                    use_cache=True,\n                    past_key_values=past_key_values,\n                )\n\n                vt = decoder_outputs[0]\n                past_key_values = decoder_outputs[1]\n                apply_cfg_guidance = t_curr >= cfg_interval_start and t_curr <= cfg_interval_end\n                if do_cfg_guidance:\n                    pred_cond, pred_null_cond = vt.chunk(2)\n                    if apply_cfg_guidance:\n                        if not use_adg:\n                            vt = apg_forward(\n                                pred_cond=pred_cond,\n                                pred_uncond=pred_null_cond,\n                                guidance_scale=diffusion_guidance_sale,\n                                momentum_buffer=momentum_buffer,\n                                dims=[1],\n                            )\n                        else:\n                            vt = adg_forward(\n                                latents=xt,\n                                noise_pred_cond=pred_cond,\n                                noise_pred_uncond=pred_null_cond,\n                                sigma=t_curr,\n                                guidance_scale=diffusion_guidance_sale,\n                            )\n                    else:\n                        vt = pred_cond\n                # Update x_t based on inference method\n                if infer_method == \"sde\":\n                    # Stochastic Differential Equation: predict clean, then re-add noise\n                    t_curr_bsz = t_curr * torch.ones((bsz,), device=device, dtype=dtype)\n                    pred_clean = self.get_x0_from_noise(xt, vt, t_curr_bsz)\n                    next_timestep = 1.0 - (float(step_idx + 1) / infer_steps)\n                    xt = self.renoise(pred_clean, next_timestep)\n                    t_after_step = next_timestep\n                elif infer_method == \"ode\":\n                    # Ordinary Differential Equation: Euler method\n                    # dx/dt = -v, so x_{t+1} = x_t - v_t * dt\n                    dt = t_curr - t_prev\n                    dt_tensor = dt * torch.ones((bsz,), device=device, dtype=dtype).unsqueeze(-1).unsqueeze(-1)\n                    xt = xt - vt * dt_tensor\n                    t_after_step = t_prev\n\n                injection_cutoff = round(repaint_injection_ratio * infer_steps)\n                if repaint_mask is not None and clean_src_latents is not None and step_idx < injection_cutoff:\n                    xt = _repaint_step_injection(\n                        xt, clean_src_latents, repaint_mask, t_after_step, noise,\n                    )\n\n        x_gen = xt\n        if repaint_mask is not None and clean_src_latents is not None and repaint_crossfade_frames > 0:\n            x_gen = _repaint_boundary_blend(\n                x_gen, clean_src_latents, repaint_mask, repaint_crossfade_frames,\n            )\n\n        end_time = time.time()\n        time_costs[\"diffusion_time_cost\"] = end_time - start_time\n        time_costs[\"diffusion_per_step_time_cost\"] = time_costs[\"diffusion_time_cost\"] / infer_steps\n        time_costs[\"total_time_cost\"] = end_time - total_start_time\n        return {\n            \"target_latents\": x_gen,\n            \"time_costs\": time_costs,\n        }\n\n\ndef test_forward(model, seed=42):\n    # Fix random seed for reproducibility\n    import random\n    import numpy as np\n    random.seed(seed)\n    np.random.seed(seed)\n    torch.manual_seed(seed)\n    if torch.cuda.is_available():\n        torch.cuda.manual_seed(seed)\n        torch.cuda.manual_seed_all(seed)\n        torch.backends.cudnn.deterministic = True\n        torch.backends.cudnn.benchmark = False\n\n    # Get model dtype and device\n    model_dtype = next(model.parameters()).dtype\n    device = next(model.parameters()).device\n\n    print(f\"Testing with dtype: {model_dtype}, device: {device}, seed: {seed}\")\n\n    # Test data preparation with matching dtype\n    text_hidden_states = torch.randn(2, 77, 1024, dtype=model_dtype, device=device)\n    text_attention_mask = torch.ones(2, 77, dtype=model_dtype, device=device)\n    lyric_hidden_states = torch.randn(2, 123, 1024, dtype=model_dtype, device=device)\n    lyric_attention_mask = torch.ones(2, 123, dtype=model_dtype, device=device)\n    refer_audio_acoustic_hidden_states_packed = torch.randn(3, 750, 64, dtype=model_dtype, device=device)\n    refer_audio_order_mask = torch.LongTensor([0, 0, 1]).to(device)\n\n    # Base config: 25 Hz hidden states → 10 s = 250 frames (round to int)\n    base_seconds = 10\n    frames_per_second = 25\n    base_seq_len = base_seconds * frames_per_second\n\n    hidden_states = torch.randn(2, base_seq_len, 64, dtype=model_dtype, device=device)\n    attention_mask = torch.ones(2, base_seq_len, dtype=model_dtype, device=device)\n    # Add some padding to test mask behavior\n    pad_start = max(base_seq_len // 2, 1)\n    attention_mask[0, pad_start:] = 0\n    chunk_mask = torch.ones(2, base_seq_len, 64, dtype=model_dtype, device=device)\n    chunk_mask[0, pad_start:] = 0\n\n    silence_latent = torch.randn(2, base_seq_len, 64, dtype=model_dtype, device=device)\n    # New required parameters for updated training logic\n    src_latents = torch.randn(2, base_seq_len, 64, dtype=model_dtype, device=device)  # Source latents for context\n    is_covers = torch.tensor([0, 1], dtype=torch.long, device=device)  # Cover song indicators (0=original, 1=cover)\n\n    # Test 1: Flow matching training (using 10s sequence for sanity check by default)\n    print(f\"Testing flow matching training with {base_seconds}s sequence ({base_seq_len} frames @ {frames_per_second}Hz)...\")\n    outputs = model.training_losses(\n        hidden_states=hidden_states,\n        attention_mask=attention_mask,\n        chunk_masks=chunk_mask,\n        text_hidden_states=text_hidden_states,\n        text_attention_mask=text_attention_mask,\n        lyric_hidden_states=lyric_hidden_states,\n        lyric_attention_mask=lyric_attention_mask,\n        refer_audio_acoustic_hidden_states_packed=refer_audio_acoustic_hidden_states_packed,\n        refer_audio_order_mask=refer_audio_order_mask,\n        silence_latent=silence_latent,\n        src_latents=src_latents,\n        is_covers=is_covers,\n        cfg_ratio=0.15,\n    )\n    loss = outputs['diffusion_loss']\n    print(f\"Flow matching loss: {loss.item():.6f}\")\n    print(f\"  Loss stats - min: {loss.min().item():.6f}, max: {loss.max().item():.6f}, mean: {loss.mean().item():.6f}, std: {loss.std().item() if loss.numel() > 1 else 0:.6f}\")\n\n    # Test 2: Generation with flow matching, testing throughput for different sequence lengths\n    lengths_seconds = [10, 30, 60, 120, 180, 240]\n    infer_steps = 2  # Can be increased as needed (e.g., 50/100) to better approximate real inference\n\n    print(\"\\n===== Throughput benchmark (25Hz hidden states) =====\")\n    for seconds in lengths_seconds:\n        seq_len = seconds * frames_per_second\n\n        # Reconstruct inputs for current sequence length\n        cur_hidden_states = torch.randn(2, seq_len, 64, dtype=model_dtype, device=device)\n        cur_attention_mask = torch.ones(2, seq_len, dtype=model_dtype, device=device)\n        cur_chunk_mask = torch.ones(2, seq_len, 64, dtype=model_dtype, device=device)\n        cur_silence_latent = torch.randn(2, seq_len, 64, dtype=model_dtype, device=device)\n        cur_src_latents = torch.randn(2, seq_len, 64, dtype=model_dtype, device=device)\n\n        print(f\"\\n--- {seconds}s input ({seq_len} frames @ {frames_per_second}Hz) ---\")\n        outputs = model.generate_audio(\n            text_hidden_states=text_hidden_states,\n            text_attention_mask=text_attention_mask,\n            lyric_hidden_states=lyric_hidden_states,\n            lyric_attention_mask=lyric_attention_mask,\n            refer_audio_acoustic_hidden_states_packed=refer_audio_acoustic_hidden_states_packed,\n            refer_audio_order_mask=refer_audio_order_mask,\n            src_latents=cur_src_latents,\n            chunk_masks=cur_chunk_mask,\n            silence_latent=cur_silence_latent,\n            infer_steps=infer_steps,\n            is_covers=is_covers,\n            seed=1234,\n        )\n\n        target_latents = outputs[\"target_latents\"]\n        time_costs = outputs.get(\"time_costs\", {})\n\n        total_time = time_costs.get(\"total_time_cost\", None)\n        diffusion_time = time_costs.get(\"diffusion_time_cost\", None)\n\n        # Output shape and statistics\n        print(f\"Generated latents shape: {target_latents.shape}\")\n        print(\n            f\"Stats - min: {target_latents.min().item():.4f}, \"\n            f\"max: {target_latents.max().item():.4f}, \"\n            f\"mean: {target_latents.mean().item():.4f}, \"\n            f\"std: {target_latents.std().item():.4f}\"\n        )\n\n        # Calculate throughput: statistics by frame count and audio seconds\n        bsz, t_len = target_latents.shape[0], target_latents.shape[1]\n        audio_seconds = t_len / frames_per_second\n\n        if total_time is not None:\n            frames_throughput = (bsz * t_len) / total_time\n            seconds_throughput = (bsz * audio_seconds) / total_time\n            print(\n                f\"Time costs: total={total_time:.4f}s, diffusion={diffusion_time:.4f}s \"\n                f\"({infer_steps} steps)\"\n                if diffusion_time is not None\n                else f\"Time costs: total={total_time:.4f}s\"\n            )\n            print(\n                f\"Throughput (based on total_time): \"\n                f\"{frames_throughput:.2f} frames/s, \"\n                f\"{seconds_throughput:.2f} audio-seconds/s (batch={bsz})\"\n            )\n        else:\n            print(\"Time costs not available in outputs['time_costs']; only basic stats printed.\")\n\n\nif __name__ == \"__main__\":\n    from torch.profiler import profile, record_function, ProfilerActivity\n    import os, torch\n    import time\n    from transformers import AutoModel\n    config = AceStepConfig()\n    start = time.time()\n    import os\n    model_dir = os.path.dirname(os.path.abspath(__file__))\n    model = AceStepConditionGenerationModel.from_pretrained(model_dir)\n    end = time.time()\n    # model.config._attn_implementation = \"sdpa\"\n    model.config._attn_implementation = \"flash_attention_2\"\n    model.eval()\n    # model = model.to(\"cpu\")\n    # model = model.float()\n    model = model.to(\"cuda\")\n    model = model.bfloat16()\n    test_forward(model)\n"
  },
  {
    "path": "acestep/models/mlx/__init__.py",
    "content": "# Native MLX implementations of AceStep models for Apple Silicon.\n# Provides pure MLX inference with graceful fallback to PyTorch.\n\nimport logging\nimport platform\n\nlogger = logging.getLogger(__name__)\n\n\ndef is_mlx_available() -> bool:\n    \"\"\"Check if MLX is available on this platform (macOS + Apple Silicon).\"\"\"\n    if platform.system() != \"Darwin\":\n        return False\n    try:\n        import mlx.core as mx\n        import mlx.nn\n        # Verify we can actually create arrays (Metal backend works)\n        _ = mx.array([1.0])\n        mx.eval(_)\n        return True\n    except Exception:\n        return False\n\n\n_MLX_AVAILABLE = None\n\n\ndef mlx_available() -> bool:\n    \"\"\"Cached check for MLX availability.\"\"\"\n    global _MLX_AVAILABLE\n    if _MLX_AVAILABLE is None:\n        _MLX_AVAILABLE = is_mlx_available()\n    return _MLX_AVAILABLE\n"
  },
  {
    "path": "acestep/models/mlx/dit_convert.py",
    "content": "# Weight conversion from PyTorch AceStep DiT decoder to native MLX format.\n\nimport logging\nfrom typing import Dict, List, Tuple\n\nimport numpy as np\n\nlogger = logging.getLogger(__name__)\n\n\ndef convert_decoder_weights(\n    pytorch_model,\n) -> List[Tuple[str, \"mx.array\"]]:\n    \"\"\"Convert PyTorch decoder weights to a list of (name, mx.array) pairs\n    suitable for ``mlx_decoder.load_weights()``.\n\n    The function extracts weights from\n    ``pytorch_model.decoder`` (``AceStepDiTModel``) and converts them to MLX\n    format, handling:\n        - Conv1d weight layout:  PT ``[out, in, K]`` -> MLX ``[out, K, in]``\n        - ConvTranspose1d layout: PT ``[in, out, K]`` -> MLX ``[out, K, in]``\n        - nn.Sequential index remapping (Lambda wrappers removed in MLX)\n        - All other weights are transferred as-is\n\n    Args:\n        pytorch_model: The full ``AceStepConditionGenerationModel`` (PyTorch).\n\n    Returns:\n        List of (param_name, mx.array) pairs ready for ``model.load_weights()``.\n    \"\"\"\n    import mlx.core as mx\n\n    decoder = pytorch_model.decoder\n    state_dict = decoder.state_dict()\n\n    weights: List[Tuple[str, \"mx.array\"]] = []\n\n    for key, value in state_dict.items():\n        np_val = value.detach().cpu().float().numpy()\n        new_key = key\n\n        # PyTorch proj_in is Sequential(Lambda, Conv1d, Lambda)\n        # The Conv1d is at index 1.  In MLX we use a bare Conv1d.\n        if key.startswith(\"proj_in.1.\"):\n            new_key = key.replace(\"proj_in.1.\", \"proj_in.\")\n            if new_key.endswith(\".weight\"):\n                # PT Conv1d weight: [out, in, K] -> MLX: [out, K, in]\n                np_val = np_val.swapaxes(1, 2)\n\n        # PyTorch proj_out is Sequential(Lambda, ConvTranspose1d, Lambda)\n        elif key.startswith(\"proj_out.1.\"):\n            new_key = key.replace(\"proj_out.1.\", \"proj_out.\")\n            if new_key.endswith(\".weight\"):\n                # PT ConvTranspose1d weight: [in, out, K] -> MLX: [out, K, in]\n                np_val = np_val.transpose(1, 2, 0)\n\n        # Skip rotary embedding buffers (recomputed in MLX)\n        elif \"rotary_emb\" in key:\n            continue\n\n        weights.append((new_key, mx.array(np_val)))\n\n    logger.info(\n        \"[MLX-DiT] Converted %d decoder parameters to MLX format.\", len(weights)\n    )\n    return weights\n\n\ndef convert_and_load(\n    pytorch_model,\n    mlx_decoder: \"MLXDiTDecoder\",\n) -> None:\n    \"\"\"Convert PyTorch decoder weights and load them into an MLX decoder.\n\n    Args:\n        pytorch_model: The full AceStepConditionGenerationModel (PyTorch).\n        mlx_decoder: An instance of ``MLXDiTDecoder`` (already constructed).\n    \"\"\"\n    import mlx.core as mx\n\n    weights = convert_decoder_weights(pytorch_model)\n    mlx_decoder.load_weights(weights)\n    mx.eval(mlx_decoder.parameters())\n    logger.info(\"[MLX-DiT] Weights loaded and evaluated successfully.\")\n"
  },
  {
    "path": "acestep/models/mlx/dit_generate.py",
    "content": "# MLX diffusion generation loop for AceStep DiT decoder.\n#\n# Replicates the timestep scheduling and ODE/SDE stepping from\n# ``AceStepConditionGenerationModel.generate_audio`` using pure MLX arrays.\n\nimport logging\nimport time\nfrom typing import Dict, List, Optional, Tuple, Union\n\nimport numpy as np\nfrom tqdm import tqdm\n\nlogger = logging.getLogger(__name__)\n\n# Pre-defined timestep schedules (from modeling_acestep_v15_turbo.py)\nVALID_SHIFTS = [1.0, 2.0, 3.0]\n\nVALID_TIMESTEPS = [\n    1.0, 0.9545454545454546, 0.9333333333333333, 0.9, 0.875,\n    0.8571428571428571, 0.8333333333333334, 0.7692307692307693, 0.75,\n    0.6666666666666666, 0.6428571428571429, 0.625, 0.5454545454545454,\n    0.5, 0.4, 0.375, 0.3, 0.25, 0.2222222222222222, 0.125,\n]\n\nSHIFT_TIMESTEPS = {\n    1.0: [1.0, 0.875, 0.75, 0.625, 0.5, 0.375, 0.25, 0.125],\n    2.0: [1.0, 0.9333333333333333, 0.8571428571428571, 0.7692307692307693,\n          0.6666666666666666, 0.5454545454545454, 0.4, 0.2222222222222222],\n    3.0: [1.0, 0.9545454545454546, 0.9, 0.8333333333333334, 0.75,\n          0.6428571428571429, 0.5, 0.3],\n}\n\n\ndef get_timestep_schedule(\n    shift: float = 3.0,\n    timesteps: Optional[list] = None,\n    infer_steps: Optional[int] = None,\n) -> List[float]:\n    \"\"\"Compute the timestep schedule for diffusion sampling.\n\n    When ``infer_steps`` is provided and ``timesteps`` is None, a continuous\n    linspace schedule is generated (matching the PyTorch base-model behaviour).\n    The legacy lookup-table path (8-step ``SHIFT_TIMESTEPS``) is used only when\n    neither ``timesteps`` nor ``infer_steps`` is supplied.\n\n    Args:\n        shift: Diffusion timestep shift (applied via ``shift*t / (1+(shift-1)*t)``).\n        timesteps: Optional custom list of timesteps.\n        infer_steps: Number of diffusion steps.  When given, overrides the\n            fixed 8-step lookup table.\n\n    Returns:\n        List of timestep values (descending, without trailing 0).\n    \"\"\"\n    t_schedule_list = None\n\n    if timesteps is not None:\n        ts_list = list(timesteps)\n        while ts_list and ts_list[-1] == 0:\n            ts_list.pop()\n        if len(ts_list) < 1:\n            logger.warning(\"timesteps empty after removing zeros; using default shift=%s\", shift)\n        else:\n            if len(ts_list) > 20:\n                logger.warning(\"timesteps length=%d > 20; truncating\", len(ts_list))\n                ts_list = ts_list[:20]\n            mapped = [min(VALID_TIMESTEPS, key=lambda x, t=t: abs(x - t)) for t in ts_list]\n            t_schedule_list = mapped\n\n    if t_schedule_list is None and infer_steps is not None and infer_steps > 0:\n        raw = [1.0 - i / infer_steps for i in range(infer_steps)]\n        if shift != 1.0:\n            raw = [shift * t / (1.0 + (shift - 1.0) * t) for t in raw]\n        t_schedule_list = raw\n\n    if t_schedule_list is None:\n        original_shift = shift\n        shift = min(VALID_SHIFTS, key=lambda x: abs(x - shift))\n        if original_shift != shift:\n            logger.warning(\"shift=%.2f rounded to nearest valid shift=%.1f\", original_shift, shift)\n        t_schedule_list = SHIFT_TIMESTEPS[shift]\n\n    return t_schedule_list\n\n\ndef _mlx_apg_forward(\n    pred_cond,\n    pred_uncond,\n    guidance_scale: float,\n    momentum_state: Optional[Dict] = None,\n    norm_threshold: float = 2.5,\n):\n    \"\"\"APG (Adaptive Projected Guidance) in pure MLX — mirrors the PyTorch ``apg_forward``.\n\n    Projection is performed along axis 1 (the time/sequence dimension) to match\n    the PyTorch implementation which calls ``apg_forward(..., dims=[1])``.\n    \"\"\"\n    import mlx.core as mx\n\n    proj_axis = 1\n\n    diff = pred_cond - pred_uncond\n    if momentum_state is not None:\n        diff = diff + momentum_state.get(\"running\", 0)\n        momentum_state[\"running\"] = diff\n\n    if norm_threshold > 0:\n        diff_norm = mx.sqrt((diff * diff).sum(axis=proj_axis, keepdims=True))\n        scale_factor = mx.minimum(mx.ones_like(diff_norm), norm_threshold / (diff_norm + 1e-8))\n        diff = diff * scale_factor\n\n    v1 = pred_cond / (mx.sqrt((pred_cond * pred_cond).sum(axis=proj_axis, keepdims=True)) + 1e-8)\n    parallel = (diff * v1).sum(axis=proj_axis, keepdims=True) * v1\n    orthogonal = diff - parallel\n\n    return pred_cond + (guidance_scale - 1) * orthogonal\n\n\ndef mlx_generate_diffusion(\n    mlx_decoder,\n    encoder_hidden_states_np: np.ndarray,\n    context_latents_np: np.ndarray,\n    src_latents_shape: Tuple[int, ...],\n    seed: Optional[Union[int, List[int]]] = None,\n    infer_method: str = \"ode\",\n    shift: float = 3.0,\n    timesteps: Optional[list] = None,\n    infer_steps: Optional[int] = None,\n    guidance_scale: float = 1.0,\n    null_condition_emb_np: Optional[np.ndarray] = None,\n    cfg_interval_start: float = 0.0,\n    cfg_interval_end: float = 1.0,\n    audio_cover_strength: float = 1.0,\n    encoder_hidden_states_non_cover_np: Optional[np.ndarray] = None,\n    context_latents_non_cover_np: Optional[np.ndarray] = None,\n    compile_model: bool = False,\n    disable_tqdm: bool = False,\n) -> Dict[str, object]:\n    \"\"\"Run the complete MLX diffusion loop with optional CFG guidance.\n\n    This is the core generation function.  It accepts numpy arrays (converted\n    from PyTorch tensors by the handler) and returns numpy arrays that the\n    handler converts back to PyTorch.\n\n    Args:\n        mlx_decoder: ``MLXDiTDecoder`` instance with loaded weights.\n        encoder_hidden_states_np: [B, enc_L, D] from prepare_condition (numpy).\n        context_latents_np: [B, T, C] from prepare_condition (numpy).\n        src_latents_shape: shape tuple [B, T, 64] for noise generation.\n        seed: random seed (int, list[int], or None).\n        infer_method: \"ode\" or \"sde\".\n        shift: timestep shift factor.\n        timesteps: optional custom timestep list.\n        infer_steps: number of diffusion steps.\n        guidance_scale: CFG guidance strength (>1.0 enables CFG).\n        null_condition_emb_np: [1, 1, D] null condition embedding for CFG.\n        cfg_interval_start: timestep ratio below which CFG is disabled.\n        cfg_interval_end: timestep ratio above which CFG is disabled.\n        audio_cover_strength: cover strength (0-1).\n        encoder_hidden_states_non_cover_np: optional [B, enc_L, D] for non-cover.\n        context_latents_non_cover_np: optional [B, T, C] for non-cover.\n        compile_model: If True, compile the decoder step with ``mx.compile``.\n        disable_tqdm: If True, suppress the diffusion progress bar.\n\n    Returns:\n        Dict with ``\"target_latents\"`` (numpy) and ``\"time_costs\"`` dict.\n    \"\"\"\n    import mlx.core as mx\n    from .dit_model import MLXCrossAttentionCache\n\n    time_costs = {}\n    total_start = time.time()\n\n    enc_hs = mx.array(encoder_hidden_states_np)\n    ctx = mx.array(context_latents_np)\n\n    enc_hs_nc = mx.array(encoder_hidden_states_non_cover_np) if encoder_hidden_states_non_cover_np is not None else None\n    ctx_nc = mx.array(context_latents_non_cover_np) if context_latents_non_cover_np is not None else None\n\n    bsz = src_latents_shape[0]\n    T = src_latents_shape[1]\n    C = src_latents_shape[2]\n\n    # ---- CFG setup ----\n    do_cfg = guidance_scale > 1.0 and null_condition_emb_np is not None\n    null_cond = mx.array(null_condition_emb_np) if do_cfg else None\n    if do_cfg:\n        null_expanded = mx.broadcast_to(null_cond, enc_hs.shape)\n        enc_hs = mx.concatenate([enc_hs, null_expanded], axis=0)\n        ctx = mx.concatenate([ctx, ctx], axis=0)\n        if enc_hs_nc is not None:\n            null_expanded_nc = mx.broadcast_to(null_cond, enc_hs_nc.shape)\n            enc_hs_nc = mx.concatenate([enc_hs_nc, null_expanded_nc], axis=0)\n        if ctx_nc is not None:\n            ctx_nc = mx.concatenate([ctx_nc, ctx_nc], axis=0)\n    momentum_state: Optional[Dict] = {} if do_cfg else None\n\n    # ---- Noise preparation ----\n    if seed is None:\n        noise = mx.random.normal((bsz, T, C))\n    elif isinstance(seed, list):\n        parts = []\n        for s in seed:\n            if s is None or s < 0:\n                parts.append(mx.random.normal((1, T, C)))\n            else:\n                key = mx.random.key(int(s))\n                parts.append(mx.random.normal((1, T, C), key=key))\n        noise = mx.concatenate(parts, axis=0)\n    else:\n        key = mx.random.key(int(seed))\n        noise = mx.random.normal((bsz, T, C), key=key)\n\n    # ---- Timestep schedule ----\n    t_schedule_list = get_timestep_schedule(shift, timesteps, infer_steps=infer_steps)\n    num_steps = len(t_schedule_list)\n\n    cover_steps = int(num_steps * audio_cover_strength)\n\n    # ---- Prepare decoder step (compiled or plain with KV cache) ----\n    _compiled_step = None\n    if compile_model:\n        def _raw_step(xt, t, tr, enc, ctx):\n            vt, _ = mlx_decoder(\n                hidden_states=xt, timestep=t, timestep_r=tr,\n                encoder_hidden_states=enc, context_latents=ctx,\n                cache=None, use_cache=False,\n            )\n            return vt\n\n        try:\n            _compiled_step = mx.compile(_raw_step)\n            logger.info(\"[MLX-DiT] Diffusion step compiled with mx.compile().\")\n        except Exception as exc:\n            logger.warning(\n                \"[MLX-DiT] mx.compile() failed (%s); using uncompiled path.\", exc\n            )\n\n    cache = MLXCrossAttentionCache() if _compiled_step is None else None\n    xt = noise\n\n    diff_start = time.time()\n    _switched_to_non_cover = False\n\n    for step_idx in tqdm(range(num_steps), desc=\"MLX DiT diffusion\", disable=disable_tqdm):\n        current_t = t_schedule_list[step_idx]\n\n        # Switch to non-cover conditions when appropriate\n        if step_idx >= cover_steps and not _switched_to_non_cover:\n            _switched_to_non_cover = True\n            if enc_hs_nc is not None:\n                enc_hs = enc_hs_nc\n                ctx = ctx_nc\n            if cache is not None:\n                cache = MLXCrossAttentionCache()\n\n        # Build input: double batch for CFG\n        x_in = mx.concatenate([xt, xt], axis=0) if do_cfg else xt\n        t_curr = mx.full((x_in.shape[0],), current_t)\n\n        if _compiled_step is not None:\n            vt = _compiled_step(x_in, t_curr, t_curr, enc_hs, ctx)\n        else:\n            vt, cache = mlx_decoder(\n                hidden_states=x_in,\n                timestep=t_curr,\n                timestep_r=t_curr,\n                encoder_hidden_states=enc_hs,\n                context_latents=ctx,\n                cache=cache,\n                use_cache=not do_cfg,\n            )\n\n        mx.eval(vt)\n\n        # Apply CFG guidance\n        if do_cfg:\n            pred_cond = vt[:bsz]\n            pred_uncond = vt[bsz:]\n            apply_cfg = cfg_interval_start <= current_t <= cfg_interval_end\n            if apply_cfg:\n                vt = _mlx_apg_forward(pred_cond, pred_uncond, guidance_scale, momentum_state)\n            else:\n                vt = pred_cond\n\n        # Final step: compute x0\n        if step_idx == num_steps - 1:\n            t_unsq = mx.full((bsz, 1, 1), current_t)\n            xt = xt - vt * t_unsq\n            mx.eval(xt)\n        else:\n            # ODE / SDE update\n            next_t = t_schedule_list[step_idx + 1]\n            if infer_method == \"sde\":\n                t_unsq = mx.full((bsz, 1, 1), current_t)\n                pred_clean = xt - vt * t_unsq\n                new_noise = mx.random.normal(xt.shape)\n                xt = next_t * new_noise + (1.0 - next_t) * pred_clean\n            else:\n                dt = current_t - next_t\n                dt_arr = mx.full((bsz, 1, 1), dt)\n                xt = xt - vt * dt_arr\n\n            mx.eval(xt)\n\n    diff_end = time.time()\n    total_end = time.time()\n\n    time_costs[\"diffusion_time_cost\"] = diff_end - diff_start\n    time_costs[\"diffusion_per_step_time_cost\"] = time_costs[\"diffusion_time_cost\"] / max(num_steps, 1)\n    time_costs[\"total_time_cost\"] = total_end - total_start\n\n    result_np = np.array(xt)\n    return {\n        \"target_latents\": result_np,\n        \"time_costs\": time_costs,\n    }\n"
  },
  {
    "path": "acestep/models/mlx/dit_model.py",
    "content": "# This module re-implements the diffusion transformer decoder from\n# modeling_acestep_v15_turbo.py using pure MLX operations for optimal\n# performance on Apple Silicon.\n\nimport math\nfrom typing import Optional, Tuple\n\nimport mlx.core as mx\nimport mlx.nn as nn\n\n\n# ---------------------------------------------------------------------------\n# Utility helpers\n# ---------------------------------------------------------------------------\n\ndef _rotate_half(x: mx.array) -> mx.array:\n    \"\"\"Rotate the last dimension by splitting in half and swapping with negation.\"\"\"\n    half = x.shape[-1] // 2\n    x1 = x[..., :half]\n    x2 = x[..., half:]\n    return mx.concatenate([-x2, x1], axis=-1)\n\n\ndef _apply_rotary_pos_emb(\n    q: mx.array, k: mx.array, cos: mx.array, sin: mx.array\n) -> Tuple[mx.array, mx.array]:\n    \"\"\"Apply rotary position embeddings to query and key tensors.\n\n    Args:\n        q, k: [B, n_heads, L, head_dim]\n        cos, sin: [1, 1, L, head_dim]\n    \"\"\"\n    q_embed = (q * cos) + (_rotate_half(q) * sin)\n    k_embed = (k * cos) + (_rotate_half(k) * sin)\n    return q_embed, k_embed\n\n\ndef _create_sliding_window_mask(\n    seq_len: int, window_size: int, dtype: mx.Dtype = mx.float32\n) -> mx.array:\n    \"\"\"Create a bidirectional sliding-window additive attention mask.\n\n    Positions within ``window_size`` of each other get ``0``; all others\n    receive a large negative value (``-1e9``).\n\n    Returns:\n        [1, 1, seq_len, seq_len]\n    \"\"\"\n    indices = mx.arange(seq_len)\n    # diff[i, j] = |i - j|\n    diff = mx.abs(indices[:, None] - indices[None, :])\n    zeros = mx.zeros(diff.shape, dtype=dtype)\n    neginf = mx.full(diff.shape, -1e9, dtype=dtype)\n    mask = mx.where(diff <= window_size, zeros, neginf)\n    return mask[None, None, :, :]  # [1, 1, L, L]\n\n\n# ---------------------------------------------------------------------------\n# Rotary Position Embedding\n# ---------------------------------------------------------------------------\n\nclass MLXRotaryEmbedding(nn.Module):\n    \"\"\"Pre-computes and caches cos/sin tables for rotary position embeddings.\"\"\"\n\n    def __init__(self, head_dim: int, max_len: int = 32768, base: float = 1_000_000.0):\n        super().__init__()\n        self.head_dim = head_dim\n        self.max_len = max_len\n        self.base = base\n\n        inv_freq = 1.0 / (\n            base ** (mx.arange(0, head_dim, 2).astype(mx.float32) / head_dim)\n        )\n        positions = mx.arange(max_len).astype(mx.float32)\n        freqs = positions[:, None] * inv_freq[None, :]  # [max_len, head_dim//2]\n        freqs = mx.concatenate([freqs, freqs], axis=-1)  # [max_len, head_dim]\n        self._cos = mx.cos(freqs)  # [max_len, head_dim]\n        self._sin = mx.sin(freqs)  # [max_len, head_dim]\n\n    def __call__(self, seq_len: int) -> Tuple[mx.array, mx.array]:\n        \"\"\"Return (cos, sin) each shaped [1, 1, seq_len, head_dim].\"\"\"\n        cos = self._cos[:seq_len][None, None, :, :]\n        sin = self._sin[:seq_len][None, None, :, :]\n        return cos, sin\n\n\n# ---------------------------------------------------------------------------\n# Cross-Attention KV Cache\n# ---------------------------------------------------------------------------\n\nclass MLXCrossAttentionCache:\n    \"\"\"Simple KV cache for cross-attention layers.\n\n    Cross-attention K/V are computed from encoder hidden states once on the\n    first diffusion step and re-used for all subsequent steps.\n    \"\"\"\n\n    def __init__(self):\n        self._keys: dict[int, mx.array] = {}\n        self._values: dict[int, mx.array] = {}\n        self._updated: set[int] = set()\n\n    def update(self, key: mx.array, value: mx.array, layer_idx: int):\n        self._keys[layer_idx] = key\n        self._values[layer_idx] = value\n        self._updated.add(layer_idx)\n\n    def is_updated(self, layer_idx: int) -> bool:\n        return layer_idx in self._updated\n\n    def get(self, layer_idx: int) -> Tuple[mx.array, mx.array]:\n        return self._keys[layer_idx], self._values[layer_idx]\n\n\n# ---------------------------------------------------------------------------\n# Core Layers\n# ---------------------------------------------------------------------------\n\nclass MLXSwiGLUMLP(nn.Module):\n    \"\"\"SwiGLU MLP (equivalent to Qwen3MLP): gate * silu(gate_proj) * up_proj.\"\"\"\n\n    def __init__(self, hidden_size: int, intermediate_size: int):\n        super().__init__()\n        self.gate_proj = nn.Linear(hidden_size, intermediate_size, bias=False)\n        self.up_proj = nn.Linear(hidden_size, intermediate_size, bias=False)\n        self.down_proj = nn.Linear(intermediate_size, hidden_size, bias=False)\n\n    def __call__(self, x: mx.array) -> mx.array:\n        return self.down_proj(nn.silu(self.gate_proj(x)) * self.up_proj(x))\n\n\nclass MLXAttention(nn.Module):\n    \"\"\"Multi-head attention with QK-RMSNorm for the AceStep DiT.\n\n    Supports both self-attention (with RoPE) and cross-attention (with\n    optional KV caching).\n    \"\"\"\n\n    def __init__(\n        self,\n        hidden_size: int,\n        num_attention_heads: int,\n        num_key_value_heads: int,\n        head_dim: int,\n        rms_norm_eps: float,\n        attention_bias: bool,\n        layer_idx: int,\n        is_cross_attention: bool = False,\n        sliding_window: Optional[int] = None,\n    ):\n        super().__init__()\n        self.hidden_size = hidden_size\n        self.num_heads = num_attention_heads\n        self.num_kv_heads = num_key_value_heads\n        self.head_dim = head_dim\n        self.n_rep = num_attention_heads // num_key_value_heads\n        self.scale = head_dim ** -0.5\n        self.layer_idx = layer_idx\n        self.is_cross_attention = is_cross_attention\n        self.sliding_window = sliding_window\n\n        self.q_proj = nn.Linear(hidden_size, num_attention_heads * head_dim, bias=attention_bias)\n        self.k_proj = nn.Linear(hidden_size, num_key_value_heads * head_dim, bias=attention_bias)\n        self.v_proj = nn.Linear(hidden_size, num_key_value_heads * head_dim, bias=attention_bias)\n        self.o_proj = nn.Linear(num_attention_heads * head_dim, hidden_size, bias=attention_bias)\n\n        self.q_norm = nn.RMSNorm(head_dim, eps=rms_norm_eps)\n        self.k_norm = nn.RMSNorm(head_dim, eps=rms_norm_eps)\n\n    @staticmethod\n    def _repeat_kv(x: mx.array, n_rep: int) -> mx.array:\n        \"\"\"Repeat KV heads for GQA: [B, n_kv, L, D] -> [B, n_kv*n_rep, L, D].\"\"\"\n        if n_rep == 1:\n            return x\n        B, n_kv, L, D = x.shape\n        x = mx.expand_dims(x, axis=2)                  # [B, n_kv, 1, L, D]\n        x = mx.broadcast_to(x, (B, n_kv, n_rep, L, D))\n        return x.reshape(B, n_kv * n_rep, L, D)\n\n    def __call__(\n        self,\n        hidden_states: mx.array,\n        position_cos_sin: Optional[Tuple[mx.array, mx.array]] = None,\n        attention_mask: Optional[mx.array] = None,\n        encoder_hidden_states: Optional[mx.array] = None,\n        cache: Optional[MLXCrossAttentionCache] = None,\n        use_cache: bool = False,\n    ) -> mx.array:\n        B, L, _ = hidden_states.shape\n\n        # Project queries (always from hidden_states)\n        q = self.q_proj(hidden_states)\n        q = self.q_norm(q.reshape(B, L, self.num_heads, self.head_dim))\n        q = q.transpose(0, 2, 1, 3)  # [B, n_heads, L, D]\n\n        if self.is_cross_attention and encoder_hidden_states is not None:\n            # Cross-attention: K,V come from encoder\n            if cache is not None and cache.is_updated(self.layer_idx):\n                k, v = cache.get(self.layer_idx)\n            else:\n                enc_L = encoder_hidden_states.shape[1]\n                k = self.k_proj(encoder_hidden_states)\n                k = self.k_norm(k.reshape(B, enc_L, self.num_kv_heads, self.head_dim))\n                k = k.transpose(0, 2, 1, 3)\n                v = self.v_proj(encoder_hidden_states).reshape(\n                    B, enc_L, self.num_kv_heads, self.head_dim\n                ).transpose(0, 2, 1, 3)\n                if cache is not None and use_cache:\n                    cache.update(k, v, self.layer_idx)\n        else:\n            # Self-attention: K,V come from hidden_states\n            k = self.k_proj(hidden_states)\n            k = self.k_norm(k.reshape(B, L, self.num_kv_heads, self.head_dim))\n            k = k.transpose(0, 2, 1, 3)\n            v = self.v_proj(hidden_states).reshape(\n                B, L, self.num_kv_heads, self.head_dim\n            ).transpose(0, 2, 1, 3)\n\n            # Apply RoPE to self-attention Q,K\n            if position_cos_sin is not None:\n                cos, sin = position_cos_sin\n                q, k = _apply_rotary_pos_emb(q, k, cos, sin)\n\n        # GQA: repeat KV heads to match Q heads\n        k = self._repeat_kv(k, self.n_rep)\n        v = self._repeat_kv(v, self.n_rep)\n\n        # Scaled dot-product attention\n        attn_out = mx.fast.scaled_dot_product_attention(\n            q, k, v, scale=self.scale, mask=attention_mask\n        )\n\n        # Merge heads and project output: [B, n_heads, L, D] -> [B, L, hidden]\n        attn_out = attn_out.transpose(0, 2, 1, 3).reshape(B, L, -1)\n        return self.o_proj(attn_out)\n\n\n# ---------------------------------------------------------------------------\n# DiT Layer\n# ---------------------------------------------------------------------------\n\nclass MLXDiTLayer(nn.Module):\n    \"\"\"A single DiT transformer layer with AdaLN modulation.\n\n    Implements:\n        1. Self-attention with adaptive layer norm (AdaLN)\n        2. Cross-attention to encoder hidden states\n        3. Feed-forward MLP with adaptive layer norm\n    \"\"\"\n\n    def __init__(\n        self,\n        hidden_size: int,\n        intermediate_size: int,\n        num_attention_heads: int,\n        num_key_value_heads: int,\n        head_dim: int,\n        rms_norm_eps: float,\n        attention_bias: bool,\n        layer_idx: int,\n        layer_type: str,\n        sliding_window: Optional[int] = None,\n    ):\n        super().__init__()\n        self.layer_type = layer_type\n        sw = sliding_window if layer_type == \"sliding_attention\" else None\n\n        # 1. Self-attention\n        self.self_attn_norm = nn.RMSNorm(hidden_size, eps=rms_norm_eps)\n        self.self_attn = MLXAttention(\n            hidden_size=hidden_size,\n            num_attention_heads=num_attention_heads,\n            num_key_value_heads=num_key_value_heads,\n            head_dim=head_dim,\n            rms_norm_eps=rms_norm_eps,\n            attention_bias=attention_bias,\n            layer_idx=layer_idx,\n            is_cross_attention=False,\n            sliding_window=sw,\n        )\n\n        # 2. Cross-attention\n        self.cross_attn_norm = nn.RMSNorm(hidden_size, eps=rms_norm_eps)\n        self.cross_attn = MLXAttention(\n            hidden_size=hidden_size,\n            num_attention_heads=num_attention_heads,\n            num_key_value_heads=num_key_value_heads,\n            head_dim=head_dim,\n            rms_norm_eps=rms_norm_eps,\n            attention_bias=attention_bias,\n            layer_idx=layer_idx,\n            is_cross_attention=True,\n        )\n\n        # 3. MLP\n        self.mlp_norm = nn.RMSNorm(hidden_size, eps=rms_norm_eps)\n        self.mlp = MLXSwiGLUMLP(hidden_size, intermediate_size)\n\n        # AdaLN modulation table (6 values: shift/scale/gate for self-attn & MLP)\n        self.scale_shift_table = mx.zeros((1, 6, hidden_size))\n\n    def __call__(\n        self,\n        hidden_states: mx.array,\n        position_cos_sin: Tuple[mx.array, mx.array],\n        temb: mx.array,\n        self_attn_mask: Optional[mx.array],\n        encoder_hidden_states: Optional[mx.array],\n        encoder_attention_mask: Optional[mx.array],\n        cache: Optional[MLXCrossAttentionCache] = None,\n        use_cache: bool = False,\n    ) -> mx.array:\n        # AdaLN modulation from timestep embeddings\n        # scale_shift_table: [1, 6, D], temb: [B, 6, D]\n        modulation = self.scale_shift_table + temb  # [B, 6, D]\n        parts = mx.split(modulation, 6, axis=1)\n        # Each part: [B, 1, D]\n        shift_msa, scale_msa, gate_msa = parts[0], parts[1], parts[2]\n        c_shift_msa, c_scale_msa, c_gate_msa = parts[3], parts[4], parts[5]\n\n        # Step 1: Self-attention with AdaLN\n        normed = self.self_attn_norm(hidden_states)\n        normed = normed * (1.0 + scale_msa) + shift_msa\n        attn_out = self.self_attn(\n            normed,\n            position_cos_sin=position_cos_sin,\n            attention_mask=self_attn_mask,\n        )\n        hidden_states = hidden_states + attn_out * gate_msa\n\n        # Step 2: Cross-attention\n        normed = self.cross_attn_norm(hidden_states)\n        cross_out = self.cross_attn(\n            normed,\n            encoder_hidden_states=encoder_hidden_states,\n            attention_mask=encoder_attention_mask,\n            cache=cache,\n            use_cache=use_cache,\n        )\n        hidden_states = hidden_states + cross_out\n\n        # Step 3: MLP with AdaLN\n        normed = self.mlp_norm(hidden_states)\n        normed = normed * (1.0 + c_scale_msa) + c_shift_msa\n        ff_out = self.mlp(normed)\n        hidden_states = hidden_states + ff_out * c_gate_msa\n\n        return hidden_states\n\n\n# ---------------------------------------------------------------------------\n# Timestep Embedding\n# ---------------------------------------------------------------------------\n\nclass MLXTimestepEmbedding(nn.Module):\n    \"\"\"Sinusoidal timestep embedding followed by MLP.\"\"\"\n\n    def __init__(self, in_channels: int = 256, time_embed_dim: int = 2048, scale: float = 1000.0):\n        super().__init__()\n        self.in_channels = in_channels\n        self.scale = scale\n\n        self.linear_1 = nn.Linear(in_channels, time_embed_dim, bias=True)\n        self.act1 = nn.SiLU()\n        self.linear_2 = nn.Linear(time_embed_dim, time_embed_dim, bias=True)\n        self.act2 = nn.SiLU()\n        self.time_proj = nn.Linear(time_embed_dim, time_embed_dim * 6, bias=True)\n\n    def _sinusoidal_embedding(self, t: mx.array, dim: int, max_period: int = 10000) -> mx.array:\n        \"\"\"Create sinusoidal timestep embeddings.\n\n        Args:\n            t: 1-D array of shape [N]\n            dim: embedding dimension\n        Returns:\n            [N, dim]\n        \"\"\"\n        t = t * self.scale\n        half = dim // 2\n        freqs = mx.exp(\n            -math.log(max_period)\n            * mx.arange(half).astype(mx.float32) / half\n        )\n        args = t[:, None].astype(mx.float32) * freqs[None, :]\n        embedding = mx.concatenate([mx.cos(args), mx.sin(args)], axis=-1)\n        if dim % 2:\n            embedding = mx.concatenate(\n                [embedding, mx.zeros_like(embedding[:, :1])], axis=-1\n            )\n        return embedding\n\n    def __call__(self, t: mx.array) -> Tuple[mx.array, mx.array]:\n        \"\"\"\n        Args:\n            t: [B] timestep values\n        Returns:\n            temb: [B, D]\n            timestep_proj: [B, 6, D]\n        \"\"\"\n        t_freq = self._sinusoidal_embedding(t, self.in_channels)\n        temb = self.linear_1(t_freq.astype(t.dtype))\n        temb = self.act1(temb)\n        temb = self.linear_2(temb)\n        proj = self.time_proj(self.act2(temb))  # [B, D*6]\n        timestep_proj = proj.reshape(proj.shape[0], 6, -1)  # [B, 6, D]\n        return temb, timestep_proj\n\n\n# ---------------------------------------------------------------------------\n# Full DiT Decoder\n# ---------------------------------------------------------------------------\n\nclass MLXDiTDecoder(nn.Module):\n    \"\"\"Native MLX implementation of AceStepDiTModel (the diffusion transformer decoder).\n\n    Mirrors the PyTorch ``AceStepDiTModel`` class exactly:\n        - Patch-based input projection (Conv1d)\n        - Timestep conditioning via dual TimestepEmbedding\n        - N DiT transformer layers with self/cross-attention and AdaLN\n        - Patch-based output projection (ConvTranspose1d)\n        - Adaptive output layer norm\n    \"\"\"\n\n    def __init__(\n        self,\n        hidden_size: int = 2048,\n        intermediate_size: int = 6144,\n        num_hidden_layers: int = 24,\n        num_attention_heads: int = 16,\n        num_key_value_heads: int = 8,\n        head_dim: int = 128,\n        rms_norm_eps: float = 1e-6,\n        attention_bias: bool = False,\n        in_channels: int = 192,\n        audio_acoustic_hidden_dim: int = 64,\n        patch_size: int = 2,\n        sliding_window: int = 128,\n        layer_types: Optional[list] = None,\n        rope_theta: float = 1_000_000.0,\n        max_position_embeddings: int = 32768,\n    ):\n        super().__init__()\n        self.hidden_size = hidden_size\n        self.patch_size = patch_size\n        inner_dim = hidden_size\n\n        if layer_types is None:\n            layer_types = [\n                \"sliding_attention\" if bool((i + 1) % 2) else \"full_attention\"\n                for i in range(num_hidden_layers)\n            ]\n\n        # Rotary position embeddings\n        self.rotary_emb = MLXRotaryEmbedding(\n            head_dim, max_len=max_position_embeddings, base=rope_theta\n        )\n\n        # Input projection: Conv1d patch embedding\n        # MLX Conv1d uses channels-last: [B, L, C] -> [B, L//stride, out_C]\n        self.proj_in = nn.Conv1d(\n            in_channels=in_channels,\n            out_channels=inner_dim,\n            kernel_size=patch_size,\n            stride=patch_size,\n            padding=0,\n        )\n\n        # Timestep embeddings (two: t and t-r)\n        self.time_embed = MLXTimestepEmbedding(in_channels=256, time_embed_dim=inner_dim)\n        self.time_embed_r = MLXTimestepEmbedding(in_channels=256, time_embed_dim=inner_dim)\n\n        # Condition embedder\n        self.condition_embedder = nn.Linear(inner_dim, inner_dim, bias=True)\n\n        # Transformer layers\n        self.layers = [\n            MLXDiTLayer(\n                hidden_size=hidden_size,\n                intermediate_size=intermediate_size,\n                num_attention_heads=num_attention_heads,\n                num_key_value_heads=num_key_value_heads,\n                head_dim=head_dim,\n                rms_norm_eps=rms_norm_eps,\n                attention_bias=attention_bias,\n                layer_idx=i,\n                layer_type=layer_types[i],\n                sliding_window=sliding_window,\n            )\n            for i in range(num_hidden_layers)\n        ]\n\n        # Output\n        self.norm_out = nn.RMSNorm(inner_dim, eps=rms_norm_eps)\n        self.proj_out = nn.ConvTranspose1d(\n            in_channels=inner_dim,\n            out_channels=audio_acoustic_hidden_dim,\n            kernel_size=patch_size,\n            stride=patch_size,\n            padding=0,\n        )\n\n        # Output adaptive layer norm modulation (2 values: shift, scale)\n        self.scale_shift_table = mx.zeros((1, 2, inner_dim))\n\n        # Pre-compute sliding window mask (will be set on first forward)\n        self._sliding_masks: dict[int, mx.array] = {}\n        self._sliding_window = sliding_window\n        self._layer_types = layer_types\n\n    def _get_sliding_mask(self, seq_len: int, dtype: mx.Dtype) -> mx.array:\n        if seq_len not in self._sliding_masks:\n            self._sliding_masks[seq_len] = _create_sliding_window_mask(\n                seq_len, self._sliding_window, dtype\n            )\n        return self._sliding_masks[seq_len]\n\n    def __call__(\n        self,\n        hidden_states: mx.array,\n        timestep: mx.array,\n        timestep_r: mx.array,\n        encoder_hidden_states: mx.array,\n        context_latents: mx.array,\n        cache: Optional[MLXCrossAttentionCache] = None,\n        use_cache: bool = True,\n    ) -> Tuple[mx.array, Optional[MLXCrossAttentionCache]]:\n        \"\"\"\n        Args:\n            hidden_states: noisy latents [B, T, 64]\n            timestep: [B] current timestep\n            timestep_r: [B] reference timestep\n            encoder_hidden_states: [B, enc_L, D] from condition encoder\n            context_latents: [B, T, C_ctx] (src_latents + chunk_masks)\n            cache: cross-attention KV cache\n            use_cache: whether to cache cross-attention KV\n\n        Returns:\n            (output_hidden_states, cache)\n        \"\"\"\n        # Timestep embeddings\n        temb_t, proj_t = self.time_embed(timestep)\n        temb_r, proj_r = self.time_embed_r(timestep - timestep_r)\n        temb = temb_t + temb_r          # [B, D]\n        timestep_proj = proj_t + proj_r  # [B, 6, D]\n\n        # Concatenate context with hidden states: [B, T, C_ctx + 64] -> [B, T, in_channels]\n        hidden_states = mx.concatenate([context_latents, hidden_states], axis=-1)\n\n        original_seq_len = hidden_states.shape[1]\n\n        # Pad to multiple of patch_size\n        pad_length = 0\n        if hidden_states.shape[1] % self.patch_size != 0:\n            pad_length = self.patch_size - (hidden_states.shape[1] % self.patch_size)\n            # Pad along time dimension\n            padding = mx.zeros(\n                (hidden_states.shape[0], pad_length, hidden_states.shape[2]),\n                dtype=hidden_states.dtype,\n            )\n            hidden_states = mx.concatenate([hidden_states, padding], axis=1)\n\n        # Patch embedding: [B, T, in_ch] -> [B, T//patch, D]\n        hidden_states = self.proj_in(hidden_states)\n\n        # Project encoder states\n        encoder_hidden_states = self.condition_embedder(encoder_hidden_states)\n\n        seq_len = hidden_states.shape[1]\n        dtype = hidden_states.dtype\n\n        # Position embeddings (RoPE)\n        cos, sin = self.rotary_emb(seq_len)\n\n        # Attention masks\n        # Self-attention: full layers get None; sliding layers get windowed mask\n        # Cross-attention: always None (no masking)\n        sliding_mask = None\n        has_sliding = any(lt == \"sliding_attention\" for lt in self._layer_types)\n        if has_sliding:\n            sliding_mask = self._get_sliding_mask(seq_len, dtype)\n\n        # Process through transformer layers\n        for layer in self.layers:\n            self_attn_mask = sliding_mask if layer.layer_type == \"sliding_attention\" else None\n            hidden_states = layer(\n                hidden_states,\n                position_cos_sin=(cos, sin),\n                temb=timestep_proj,\n                self_attn_mask=self_attn_mask,\n                encoder_hidden_states=encoder_hidden_states,\n                encoder_attention_mask=None,\n                cache=cache,\n                use_cache=use_cache,\n            )\n\n        # Output adaptive layer norm\n        shift, scale = mx.split(\n            self.scale_shift_table + mx.expand_dims(temb, axis=1), 2, axis=1\n        )\n        hidden_states = self.norm_out(hidden_states) * (1.0 + scale) + shift\n\n        # De-patchify: [B, T//patch, D] -> [B, T, out_channels]\n        hidden_states = self.proj_out(hidden_states)\n\n        # Crop back to original sequence length\n        hidden_states = hidden_states[:, :original_seq_len, :]\n\n        return hidden_states, cache\n\n    @classmethod\n    def from_config(cls, config) -> \"MLXDiTDecoder\":\n        \"\"\"Construct from an AceStepConfig (transformers PretrainedConfig).\"\"\"\n        return cls(\n            hidden_size=config.hidden_size,\n            intermediate_size=config.intermediate_size,\n            num_hidden_layers=config.num_hidden_layers,\n            num_attention_heads=config.num_attention_heads,\n            num_key_value_heads=config.num_key_value_heads,\n            head_dim=getattr(config, \"head_dim\", config.hidden_size // config.num_attention_heads),\n            rms_norm_eps=config.rms_norm_eps,\n            attention_bias=config.attention_bias,\n            in_channels=config.in_channels,\n            audio_acoustic_hidden_dim=config.audio_acoustic_hidden_dim,\n            patch_size=config.patch_size,\n            sliding_window=config.sliding_window if config.sliding_window else 128,\n            layer_types=config.layer_types,\n            rope_theta=config.rope_theta,\n            max_position_embeddings=config.max_position_embeddings,\n        )\n"
  },
  {
    "path": "acestep/models/mlx/vae_convert.py",
    "content": "# Weight conversion from PyTorch AutoencoderOobleck to native MLX format.\n#\n# Handles:\n#   - weight_norm fusion:  weight_g + weight_v  →  fused weight\n#   - Conv1d axis swap:    PT [out, in, K]      →  MLX [out, K, in]\n#   - ConvTranspose1d:     PT [in, out, K]      →  MLX [out, K, in]\n#   - Snake1d parameters:  PT [1, C, 1]         →  MLX [C]\n#   - Bias:                no change\n\nimport logging\nfrom typing import Dict, List, Tuple\n\nimport numpy as np\n\nlogger = logging.getLogger(__name__)\n\n\ndef _fuse_weight_norm(\n    weight_g: np.ndarray,\n    weight_v: np.ndarray,\n    eps: float = 1e-9,\n) -> np.ndarray:\n    \"\"\"Fuse weight_norm parameters into a single weight tensor.\n\n    weight_norm decomposes ``w = g * v / ||v||`` where:\n        weight_g: per-output-channel scale  [out, 1, 1]  (Conv1d)\n                  or [in, 1, 1] for ConvTranspose1d\n        weight_v: direction tensor with same shape as the original weight\n\n    Returns the fused weight in the *original PyTorch shape* (before axis swap).\n    \"\"\"\n    v_flat = weight_v.reshape(weight_v.shape[0], -1)\n    norm = np.linalg.norm(v_flat, axis=1).reshape(weight_g.shape)\n    return weight_g * weight_v / (norm + eps)\n\n\ndef convert_vae_weights(\n    pytorch_vae,\n) -> List[Tuple[str, \"mx.array\"]]:\n    \"\"\"Convert PyTorch AutoencoderOobleck weights to MLX format.\n\n    The function extracts the state dict from ``pytorch_vae`` and converts\n    each parameter to the format expected by ``MLXAutoEncoderOobleck``,\n    handling weight_norm fusion, Conv axis reordering, and Snake1d\n    parameter reshaping.\n\n    Args:\n        pytorch_vae: A ``diffusers.AutoencoderOobleck`` instance.\n\n    Returns:\n        List of ``(param_name, mx.array)`` pairs for ``model.load_weights()``.\n    \"\"\"\n    import mlx.core as mx\n\n    state_dict = pytorch_vae.state_dict()\n    weights: List[Tuple[str, \"mx.array\"]] = []\n    processed: set = set()\n\n    # Sort keys so we process weight_v / weight_g pairs together\n    all_keys = sorted(state_dict.keys())\n\n    for key in all_keys:\n        if key in processed:\n            continue\n\n        # ------------------------------------------------------------------\n        # 1) weight_norm fusion:  *_weight_g + *_weight_v  →  *.weight\n        # ------------------------------------------------------------------\n        if key.endswith(\".weight_g\"):\n            # The companion weight_v key\n            base = key[: -len(\".weight_g\")]\n            v_key = base + \".weight_v\"\n\n            if v_key not in state_dict:\n                logger.warning(\n                    \"[MLX-VAE] weight_g without weight_v: %s — skipping\", key\n                )\n                processed.add(key)\n                continue\n\n            g = state_dict[key].detach().cpu().float().numpy()\n            v = state_dict[v_key].detach().cpu().float().numpy()\n            w = _fuse_weight_norm(g, v)\n\n            # Determine layer type and swap axes\n            if \"conv_t1\" in base:\n                # ConvTranspose1d: PT [in, out, K] → MLX [out, K, in]\n                w = w.transpose(1, 2, 0)\n            else:\n                # Conv1d: PT [out, in, K] → MLX [out, K, in]\n                w = w.swapaxes(1, 2)\n\n            new_key = base + \".weight\"\n            weights.append((new_key, mx.array(w)))\n            processed.add(key)\n            processed.add(v_key)\n            continue\n\n        if key.endswith(\".weight_v\"):\n            # Will be / was handled together with weight_g above\n            continue\n\n        # ------------------------------------------------------------------\n        # 2) Snake1d parameters:  PT [1, C, 1] → MLX [C]\n        # ------------------------------------------------------------------\n        if key.endswith(\".alpha\") or key.endswith(\".beta\"):\n            val = state_dict[key].detach().cpu().float().numpy().squeeze()\n            weights.append((key, mx.array(val)))\n            processed.add(key)\n            continue\n\n        # ------------------------------------------------------------------\n        # 3) Bias:  shape [C] — no transformation needed\n        # ------------------------------------------------------------------\n        if key.endswith(\".bias\"):\n            val = state_dict[key].detach().cpu().float().numpy()\n            weights.append((key, mx.array(val)))\n            processed.add(key)\n            continue\n\n        # ------------------------------------------------------------------\n        # 4) Catch-all for any remaining parameters (unlikely in this model)\n        # ------------------------------------------------------------------\n        val = state_dict[key].detach().cpu().float().numpy()\n        logger.debug(\"[MLX-VAE] Pass-through key: %s  shape=%s\", key, val.shape)\n        weights.append((key, mx.array(val)))\n        processed.add(key)\n\n    logger.info(\n        \"[MLX-VAE] Converted %d parameters to MLX format.\", len(weights)\n    )\n    return weights\n\n\ndef convert_and_load(\n    pytorch_vae,\n    mlx_vae: \"MLXAutoEncoderOobleck\",\n) -> None:\n    \"\"\"Convert PyTorch VAE weights and load them into an MLX VAE.\n\n    Args:\n        pytorch_vae: ``diffusers.AutoencoderOobleck`` instance (PyTorch).\n        mlx_vae: An ``MLXAutoEncoderOobleck`` instance (already constructed).\n    \"\"\"\n    import mlx.core as mx\n\n    weights = convert_vae_weights(pytorch_vae)\n    mlx_vae.load_weights(weights)\n    mx.eval(mlx_vae.parameters())\n    logger.info(\"[MLX-VAE] Weights loaded and evaluated successfully.\")\n"
  },
  {
    "path": "acestep/models/mlx/vae_model.py",
    "content": "# Pure MLX re-implementation of diffusers' AutoencoderOobleck for Apple Silicon.\n#\n# Architecture mirrors the PyTorch version exactly:\n#   Snake1d -> OobleckResidualUnit -> EncoderBlock / DecoderBlock\n#   -> OobleckEncoder / OobleckDecoder -> MLXAutoEncoderOobleck\n#\n# All operations use MLX channels-last (NLC) convention internally.\n# The public encode/decode API accepts and returns NLC arrays.\n\nimport math\nimport logging\nfrom typing import List, Optional, Tuple\n\nimport mlx.core as mx\nimport mlx.nn as nn\n\nlogger = logging.getLogger(__name__)\n\n\n# ---------------------------------------------------------------------------\n# Snake1d Activation\n# ---------------------------------------------------------------------------\n\nclass MLXSnake1d(nn.Module):\n    \"\"\"Snake activation: x + (1/beta) * sin(alpha * x)^2.\n\n    Parameters ``alpha`` and ``beta`` are stored as 1-D vectors of shape [C]\n    and broadcast over (B, L) automatically.  When ``logscale=True`` (default)\n    the actual scale is ``exp(alpha)`` / ``exp(beta)``.\n    \"\"\"\n\n    def __init__(self, hidden_dim: int, logscale: bool = True):\n        super().__init__()\n        self.alpha = mx.zeros(hidden_dim)\n        self.beta = mx.zeros(hidden_dim)\n        self.logscale = logscale\n\n    def __call__(self, x: mx.array) -> mx.array:\n        # x: [B, L, C]  (NLC)\n        # NOTE: Upcast to float32 for exp/sin/power to prevent overflow with float16\n        # weights (exp overflows float16 at alpha > ~11).  This is only a problem\n        # if the weights are in float16.  The surrounding\n        # Conv1d layers still run in the caller's dtype (float16) for speed.\n\n        # This is the original code that works with float16 weights, if we end up needing to\n        # use float16 weights. please use this code instead\n        # alpha = mx.exp(self.alpha.astype(mx.float32)) if self.logscale else self.alpha\n        # beta = mx.exp(self.beta.astype(mx.float32)) if self.logscale else self.beta\n        # x_f32 = x.astype(mx.float32)\n        # result = x_f32 + mx.reciprocal(beta + 1e-9) * mx.power(mx.sin(alpha * x_f32), 2)\n        # return result.astype(x.dtype)\n        alpha = mx.exp(self.alpha) if self.logscale else self.alpha\n        beta = mx.exp(self.beta) if self.logscale else self.beta\n        # All ops broadcast [C] over [B, L, C]\n        return x + mx.reciprocal(beta + 1e-9) * mx.power(mx.sin(alpha * x), 2)\n\n\n# ---------------------------------------------------------------------------\n# Residual Unit\n# ---------------------------------------------------------------------------\n\nclass MLXOobleckResidualUnit(nn.Module):\n    \"\"\"Two weight-normalised Conv1d layers (k=7 dilated + k=1) wrapped with\n    Snake1d activations and a residual skip connection.\"\"\"\n\n    def __init__(self, dimension: int = 16, dilation: int = 1):\n        super().__init__()\n        pad = ((7 - 1) * dilation) // 2\n\n        self.snake1 = MLXSnake1d(dimension)\n        self.conv1 = nn.Conv1d(\n            dimension, dimension, kernel_size=7, dilation=dilation, padding=pad\n        )\n        self.snake2 = MLXSnake1d(dimension)\n        self.conv2 = nn.Conv1d(dimension, dimension, kernel_size=1)\n\n    def __call__(self, hidden_state: mx.array) -> mx.array:\n        # hidden_state: [B, L, C]\n        output = self.conv1(self.snake1(hidden_state))\n        output = self.conv2(self.snake2(output))\n\n        # Safety trim (should be no-op with correct padding)\n        padding = (hidden_state.shape[1] - output.shape[1]) // 2\n        if padding > 0:\n            hidden_state = hidden_state[:, padding:-padding, :]\n\n        return hidden_state + output\n\n\n# ---------------------------------------------------------------------------\n# Encoder / Decoder Blocks\n# ---------------------------------------------------------------------------\n\nclass MLXOobleckEncoderBlock(nn.Module):\n    \"\"\"3 residual units (dilations 1, 3, 9) -> Snake -> strided Conv1d down.\"\"\"\n\n    def __init__(self, input_dim: int, output_dim: int, stride: int = 1):\n        super().__init__()\n        self.res_unit1 = MLXOobleckResidualUnit(input_dim, dilation=1)\n        self.res_unit2 = MLXOobleckResidualUnit(input_dim, dilation=3)\n        self.res_unit3 = MLXOobleckResidualUnit(input_dim, dilation=9)\n        self.snake1 = MLXSnake1d(input_dim)\n        self.conv1 = nn.Conv1d(\n            input_dim,\n            output_dim,\n            kernel_size=2 * stride,\n            stride=stride,\n            padding=math.ceil(stride / 2),\n        )\n\n    def __call__(self, hidden_state: mx.array) -> mx.array:\n        hidden_state = self.res_unit1(hidden_state)\n        hidden_state = self.res_unit2(hidden_state)\n        hidden_state = self.snake1(self.res_unit3(hidden_state))\n        hidden_state = self.conv1(hidden_state)\n        return hidden_state\n\n\nclass MLXOobleckDecoderBlock(nn.Module):\n    \"\"\"Snake -> strided ConvTranspose1d up -> 3 residual units (dilations 1, 3, 9).\"\"\"\n\n    def __init__(self, input_dim: int, output_dim: int, stride: int = 1):\n        super().__init__()\n        self.snake1 = MLXSnake1d(input_dim)\n        self.conv_t1 = nn.ConvTranspose1d(\n            input_dim,\n            output_dim,\n            kernel_size=2 * stride,\n            stride=stride,\n            padding=math.ceil(stride / 2),\n        )\n        self.res_unit1 = MLXOobleckResidualUnit(output_dim, dilation=1)\n        self.res_unit2 = MLXOobleckResidualUnit(output_dim, dilation=3)\n        self.res_unit3 = MLXOobleckResidualUnit(output_dim, dilation=9)\n\n    def __call__(self, hidden_state: mx.array) -> mx.array:\n        hidden_state = self.snake1(hidden_state)\n        hidden_state = self.conv_t1(hidden_state)\n        hidden_state = self.res_unit1(hidden_state)\n        hidden_state = self.res_unit2(hidden_state)\n        hidden_state = self.res_unit3(hidden_state)\n        return hidden_state\n\n\n# ---------------------------------------------------------------------------\n# Encoder / Decoder\n# ---------------------------------------------------------------------------\n\nclass MLXOobleckEncoder(nn.Module):\n    \"\"\"Oobleck Encoder: Conv1d -> N encoder blocks -> Snake -> Conv1d.\"\"\"\n\n    def __init__(\n        self,\n        encoder_hidden_size: int,\n        audio_channels: int,\n        downsampling_ratios: List[int],\n        channel_multiples: List[int],\n    ):\n        super().__init__()\n        strides = downsampling_ratios\n        cm = [1] + list(channel_multiples)\n\n        self.conv1 = nn.Conv1d(\n            audio_channels, encoder_hidden_size, kernel_size=7, padding=3\n        )\n\n        self.block = []\n        for i, stride in enumerate(strides):\n            self.block.append(\n                MLXOobleckEncoderBlock(\n                    input_dim=encoder_hidden_size * cm[i],\n                    output_dim=encoder_hidden_size * cm[i + 1],\n                    stride=stride,\n                )\n            )\n\n        d_model = encoder_hidden_size * cm[-1]\n        self.snake1 = MLXSnake1d(d_model)\n        self.conv2 = nn.Conv1d(d_model, encoder_hidden_size, kernel_size=3, padding=1)\n\n    def __call__(self, hidden_state: mx.array) -> mx.array:\n        hidden_state = self.conv1(hidden_state)\n        for module in self.block:\n            hidden_state = module(hidden_state)\n        hidden_state = self.snake1(hidden_state)\n        hidden_state = self.conv2(hidden_state)\n        return hidden_state\n\n\nclass MLXOobleckDecoder(nn.Module):\n    \"\"\"Oobleck Decoder: Conv1d -> N decoder blocks -> Snake -> Conv1d.\"\"\"\n\n    def __init__(\n        self,\n        channels: int,\n        input_channels: int,\n        audio_channels: int,\n        upsampling_ratios: List[int],\n        channel_multiples: List[int],\n    ):\n        super().__init__()\n        strides = upsampling_ratios\n        cm = [1] + list(channel_multiples)\n\n        self.conv1 = nn.Conv1d(\n            input_channels, channels * cm[-1], kernel_size=7, padding=3\n        )\n\n        self.block = []\n        for i, stride in enumerate(strides):\n            self.block.append(\n                MLXOobleckDecoderBlock(\n                    input_dim=channels * cm[len(strides) - i],\n                    output_dim=channels * cm[len(strides) - i - 1],\n                    stride=stride,\n                )\n            )\n\n        self.snake1 = MLXSnake1d(channels)\n        self.conv2 = nn.Conv1d(\n            channels, audio_channels, kernel_size=7, padding=3, bias=False\n        )\n\n    def __call__(self, hidden_state: mx.array) -> mx.array:\n        hidden_state = self.conv1(hidden_state)\n        for layer in self.block:\n            hidden_state = layer(hidden_state)\n        hidden_state = self.snake1(hidden_state)\n        hidden_state = self.conv2(hidden_state)\n        return hidden_state\n\n\n# ---------------------------------------------------------------------------\n# Full VAE\n# ---------------------------------------------------------------------------\n\nclass MLXAutoEncoderOobleck(nn.Module):\n    \"\"\"Pure-MLX re-implementation of ``diffusers.AutoencoderOobleck``.\n\n    Default configuration matches the Stable Audio / ACE-Step VAE:\n        encoder_hidden_size  = 128\n        downsampling_ratios  = [2, 4, 4, 8, 8]   (hop_length = 2048)\n        channel_multiples    = [1, 2, 4, 8, 16]\n        decoder_channels     = 128\n        decoder_input_channels = 64               (latent dim)\n        audio_channels       = 2                  (stereo)\n\n    Data flows in NLC (batch, length, channels) format throughout.\n    \"\"\"\n\n    def __init__(\n        self,\n        encoder_hidden_size: int = 128,\n        downsampling_ratios: Optional[List[int]] = None,\n        channel_multiples: Optional[List[int]] = None,\n        decoder_channels: int = 128,\n        decoder_input_channels: int = 64,\n        audio_channels: int = 2,\n    ):\n        super().__init__()\n        if downsampling_ratios is None:\n            downsampling_ratios = [2, 4, 4, 8, 8]\n        if channel_multiples is None:\n            channel_multiples = [1, 2, 4, 8, 16]\n\n        self.encoder_hidden_size = encoder_hidden_size\n        self.decoder_input_channels = decoder_input_channels\n\n        self.encoder = MLXOobleckEncoder(\n            encoder_hidden_size=encoder_hidden_size,\n            audio_channels=audio_channels,\n            downsampling_ratios=downsampling_ratios,\n            channel_multiples=channel_multiples,\n        )\n        self.decoder = MLXOobleckDecoder(\n            channels=decoder_channels,\n            input_channels=decoder_input_channels,\n            audio_channels=audio_channels,\n            upsampling_ratios=downsampling_ratios[::-1],\n            channel_multiples=channel_multiples,\n        )\n\n    # -- public API ---------------------------------------------------------\n\n    def encode_and_sample(self, audio_nlc: mx.array) -> mx.array:\n        \"\"\"Encode audio -> sample latent.\n\n        Args:\n            audio_nlc: [B, L_audio, C_audio] in NLC format.\n\n        Returns:\n            z: [B, L_latent, C_latent] sampled latent.\n        \"\"\"\n        h = self.encoder(audio_nlc)  # [B, L', encoder_hidden_size]\n\n        # Diagonal Gaussian: split into mean + log-scale\n        mean, scale = mx.split(h, 2, axis=-1)\n\n        # softplus(scale) + epsilon  (numerically stable)\n        std = mx.where(scale > 20.0, scale, mx.log(1.0 + mx.exp(scale))) + 1e-4\n\n        noise = mx.random.normal(mean.shape)\n        z = mean + std * noise\n        return z\n\n    def encode_mean(self, audio_nlc: mx.array) -> mx.array:\n        \"\"\"Encode audio -> return mean (no sampling noise).\"\"\"\n        h = self.encoder(audio_nlc)\n        mean, _scale = mx.split(h, 2, axis=-1)\n        return mean\n\n    def decode(self, latents_nlc: mx.array) -> mx.array:\n        \"\"\"Decode latents -> audio.\n\n        Args:\n            latents_nlc: [B, L_latent, C_latent] in NLC format.\n\n        Returns:\n            audio: [B, L_audio, C_audio] in NLC format.\n        \"\"\"\n        return self.decoder(latents_nlc)\n\n    # -- construction helpers -----------------------------------------------\n\n    @classmethod\n    def from_pytorch_config(cls, pt_vae) -> \"MLXAutoEncoderOobleck\":\n        \"\"\"Construct from a PyTorch ``AutoencoderOobleck`` instance's config.\"\"\"\n        cfg = pt_vae.config\n        return cls(\n            encoder_hidden_size=cfg.encoder_hidden_size,\n            downsampling_ratios=list(cfg.downsampling_ratios),\n            channel_multiples=list(cfg.channel_multiples),\n            decoder_channels=cfg.decoder_channels,\n            decoder_input_channels=cfg.decoder_input_channels,\n            audio_channels=cfg.audio_channels,\n        )\n"
  },
  {
    "path": "acestep/models/sft/__init__.py",
    "content": ""
  },
  {
    "path": "acestep/models/sft/apg_guidance.py",
    "content": "import torch\nimport torch.nn.functional as F\n\n\nclass MomentumBuffer:\n\n    def __init__(self, momentum: float = -0.75):\n        self.momentum = momentum\n        self.running_average = 0\n\n    def update(self, update_value: torch.Tensor):\n        new_average = self.momentum * self.running_average\n        self.running_average = update_value + new_average\n\n\ndef project(\n    v0: torch.Tensor,  # [B, C, T]\n    v1: torch.Tensor,  # [B, C, T]\n    dims=[-1],\n):\n    dtype = v0.dtype\n    device_type = v0.device.type\n    if device_type == \"mps\":\n        v0, v1 = v0.cpu(), v1.cpu()\n\n    v0, v1 = v0.double(), v1.double()\n    v1 = torch.nn.functional.normalize(v1, dim=dims)\n    v0_parallel = (v0 * v1).sum(dim=dims, keepdim=True) * v1\n    v0_orthogonal = v0 - v0_parallel\n    return v0_parallel.to(dtype).to(device_type), v0_orthogonal.to(dtype).to(device_type)\n\n\ndef apg_forward(\n    pred_cond: torch.Tensor,  # [B, C, T]\n    pred_uncond: torch.Tensor,  # [B, C, T]\n    guidance_scale: float,\n    momentum_buffer: MomentumBuffer = None,\n    eta: float = 0.0,\n    norm_threshold: float = 2.5,\n    dims=[-1],\n):\n    diff = pred_cond - pred_uncond\n    if momentum_buffer is not None:\n        momentum_buffer.update(diff)\n        diff = momentum_buffer.running_average\n\n    if norm_threshold > 0:\n        ones = torch.ones_like(diff)\n        diff_norm = diff.norm(p=2, dim=dims, keepdim=True)\n        scale_factor = torch.minimum(ones, norm_threshold / diff_norm)\n        diff = diff * scale_factor\n\n    diff_parallel, diff_orthogonal = project(diff, pred_cond, dims)\n    normalized_update = diff_orthogonal + eta * diff_parallel\n    pred_guided = pred_cond + (guidance_scale - 1) * normalized_update\n    return pred_guided\n\n\ndef cfg_forward(cond_output, uncond_output, cfg_strength):\n    return uncond_output + cfg_strength * (cond_output - uncond_output)\n\n\ndef call_cos_tensor(tensor1, tensor2):\n    \"\"\"\n    Calculate cosine similarity between two normalized tensors.\n\n    Args:\n        tensor1: First tensor [B, ...]\n        tensor2: Second tensor [B, ...]\n\n    Returns:\n        Cosine similarity value [B, 1]\n    \"\"\"\n    tensor1 = tensor1 / torch.linalg.norm(tensor1, dim=1, keepdim=True)\n    tensor2 = tensor2 / torch.linalg.norm(tensor2, dim=1, keepdim=True)\n    cosvalue = torch.sum(tensor1 * tensor2, dim=1, keepdim=True)\n    return cosvalue\n\n\ndef compute_perpendicular_component(latent_diff, latent_hat_uncond):\n    \"\"\"\n    Decompose latent_diff into parallel and perpendicular components relative to latent_hat_uncond.\n\n    Args:\n        latent_diff: Difference tensor [B, C, ...]\n        latent_hat_uncond: Unconditional prediction tensor [B, C, ...]\n\n    Returns:\n        projection: Parallel component\n        perpendicular_component: Perpendicular component\n    \"\"\"\n    n, t, c = latent_diff.shape\n    latent_diff = latent_diff.view(n * t, c).float()\n    latent_hat_uncond = latent_hat_uncond.view(n * t, c).float()\n\n    if latent_diff.size() != latent_hat_uncond.size():\n        raise ValueError(\"latent_diff and latent_hat_uncond must have the same shape [n, d].\")\n\n    dot_product = torch.sum(latent_diff * latent_hat_uncond, dim=1, keepdim=True)  # [n, 1]\n    norm_square = torch.sum(latent_hat_uncond * latent_hat_uncond, dim=1, keepdim=True)  # [n, 1]\n    projection = (dot_product / (norm_square + 1e-8)) * latent_hat_uncond\n    perpendicular_component = latent_diff - projection\n\n    return projection.view(n, t, c), perpendicular_component.reshape(n, t, c)\n\n\ndef adg_forward(\n    latents: torch.Tensor,\n    noise_pred_cond: torch.Tensor,\n    noise_pred_uncond: torch.Tensor,\n    sigma: torch.Tensor,\n    guidance_scale: float,\n    angle_clip: float = 3.14 / 6,  # pi/6 by default\n    apply_norm: bool = False,\n    apply_clip: bool = True,\n):\n    \"\"\"\n    ADG (Angle-based Dynamic Guidance) forward pass for Flow Matching.\n\n    In flow matching (including SD3), sigma represents the current timestep t_curr.\n    The predictions are velocity fields v(x_t, t).\n\n    Args:\n        latents: Current state x_t [N, T, d] where d=64\n        noise_pred_cond: Conditional velocity prediction v_cond [N, T, d]\n        noise_pred_uncond: Unconditional velocity prediction v_uncond [N, T, d]\n        sigma: Current timestep t_curr (not t_prev!)\n        guidance_scale: Guidance strength\n        angle_clip: Maximum angle for clipping (default: pi/6)\n        apply_norm: Whether to normalize the result (ADG_w_norm variant)\n        apply_clip: Whether to clip the angle (ADG_wo_clip when False)\n\n    Returns:\n        Guided velocity prediction [N, T, d]\n    \"\"\"\n    if latents.shape[1] != noise_pred_cond.shape[1]:\n        if noise_pred_cond.shape[1] % latents.shape[1] != 0:\n            raise ValueError(\"noise_pred_cond time dimension must be a whole-number multiple of latents time dimension.\")\n        repeats = noise_pred_cond.shape[1] // latents.shape[1]\n        latents = latents.repeat_interleave(repeats, dim=1)\n\n    # Get batch size\n    n = noise_pred_cond.shape[0]\n    noise_pred_text = noise_pred_cond\n    n, t, c = noise_pred_text.shape\n\n    # Ensure sigma/t has the right shape for broadcasting [N, 1, 1]\n    if isinstance(sigma, (int, float)):\n        sigma = torch.tensor(sigma, device=latents.device, dtype=latents.dtype)\n        sigma = sigma.view(1, 1, 1).expand(n, 1, 1)\n    elif torch.is_tensor(sigma):\n        if sigma.numel() == 1:\n            sigma = sigma.view(1, 1, 1).expand(n, 1, 1)\n        elif sigma.numel() == n:\n            sigma = sigma.view(n, 1, 1)\n        else:\n            raise ValueError(f\"sigma has incompatible shape. Expected scalar or size {n}, got {sigma.shape}\")\n    else:\n        raise TypeError(f\"sigma must be a number or tensor, got {type(sigma)}\")\n\n    # Adjust guidance weight\n    weight = guidance_scale - 1\n    weight = weight * (weight > 0) + 1e-3\n\n    latent_hat_text = latents - sigma * noise_pred_text\n    latent_hat_uncond = latents - sigma * noise_pred_uncond\n    latent_diff = latent_hat_text - latent_hat_uncond\n\n    # Calculate angle between conditional and unconditional predicted data\n    cos_theta = call_cos_tensor(\n        latent_hat_text.view(-1, c).to(float),\n        latent_hat_uncond.reshape(-1, c).contiguous().to(float)\n    ).clamp(-1.0 + 1e-6, 1.0 - 1e-6)\n    latent_theta = torch.acos(cos_theta).view(n, t, 1)\n    latent_theta_new = torch.clip(weight * latent_theta, -angle_clip, angle_clip) if apply_clip else weight * latent_theta\n    proj, perp = compute_perpendicular_component(latent_diff, latent_hat_uncond)\n    latent_v_new = torch.cos(latent_theta_new) * latent_hat_text\n\n    latent_p_new = perp * torch.sin(latent_theta_new) / torch.sin(latent_theta) * (\n        torch.sin(latent_theta) > 1e-3) + perp * weight * (torch.sin(latent_theta) <= 1e-3)\n    latent_new = latent_v_new + latent_p_new\n    if apply_norm:\n        latent_new = latent_new * torch.linalg.norm(latent_hat_text, dim=1, keepdim=True) / torch.linalg.norm(\n            latent_new, dim=1, keepdim=True)\n\n    noise_pred = (latents - latent_new) / sigma\n    noise_pred = noise_pred.reshape(n, t, c).to(latents.dtype)\n    return noise_pred\n\n\ndef adg_w_norm_forward(\n    latents: torch.Tensor,\n    noise_pred_cond: torch.Tensor,\n    noise_pred_uncond: torch.Tensor,\n    sigma: float,\n    guidance_scale: float,\n    angle_clip: float = 3.14 / 3,\n):\n    \"\"\"\n    ADG with normalization - preserves the magnitude of latent predictions.\n\n    This variant normalizes the final latent to maintain the same norm as the\n    conditional prediction, which can help preserve image quality.\n    \"\"\"\n    return adg_forward(latents,\n                       noise_pred_cond,\n                       noise_pred_uncond,\n                       sigma,\n                       guidance_scale,\n                       angle_clip=angle_clip,\n                       apply_norm=True,\n                       apply_clip=True)\n\n\ndef adg_wo_clip_forward(\n    latents: torch.Tensor,\n    noise_pred_cond: torch.Tensor,\n    noise_pred_uncond: torch.Tensor,\n    sigma: float,\n    guidance_scale: float,\n):\n    \"\"\"\n    ADG without angle clipping - allows unbounded angle adjustments.\n\n    This variant doesn't clip the angle, which may result in more aggressive\n    guidance but could be less stable.\n    \"\"\"\n    return adg_forward(latents, noise_pred_cond, noise_pred_uncond, sigma, guidance_scale, apply_norm=False, apply_clip=False)\n"
  },
  {
    "path": "acestep/models/sft/configuration_acestep_v15.py",
    "content": "# coding=utf-8\n# Copyright 2024 The Qwen team, Alibaba Group and the HuggingFace Inc. team. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#     http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n\"\"\"AceStep model configuration\"\"\"\n\nfrom transformers.configuration_utils import PretrainedConfig, layer_type_validation\nfrom transformers.modeling_rope_utils import rope_config_validation\nfrom transformers.utils import logging\n\n\nlogger = logging.get_logger(__name__)\n\n\nclass AceStepConfig(PretrainedConfig):\n    r\"\"\"\n    This is the configuration class to store the configuration of a [`AceStepModel`]. It is used to instantiate an\n    AceStep model according to the specified arguments, defining the model architecture.\n\n    Configuration objects inherit from [`PretrainedConfig`] and can be used to control the model outputs. Read the\n    documentation from [`PretrainedConfig`] for more information.\n\n    Args:\n        vocab_size (`int`, *optional*, defaults to 64003):\n            Vocabulary size of the AceStep model. Defines the number of different tokens that can be represented by the\n            `inputs_ids` passed when calling the model.\n        hidden_size (`int`, *optional*, defaults to 4096):\n            Dimension of the hidden representations.\n        intermediate_size (`int`, *optional*, defaults to 22016):\n            Dimension of the MLP representations.\n        num_hidden_layers (`int`, *optional*, defaults to 32):\n            Number of hidden layers in the Transformer encoder.\n        num_attention_heads (`int`, *optional*, defaults to 32):\n            Number of attention heads for each attention layer in the Transformer encoder.\n        num_key_value_heads (`int`, *optional*, defaults to 32):\n            This is the number of key_value heads that should be used to implement Grouped Query Attention. If\n            `num_key_value_heads=num_attention_heads`, the model will use Multi Head Attention (MHA), if\n            `num_key_value_heads=1` the model will use Multi Query Attention (MQA) otherwise GQA is used. When\n            converting a multi-head checkpoint to a GQA checkpoint, each group key and value head should be constructed\n            by meanpooling all the original heads within that group. For more details, check out [this\n            paper](https://huggingface.co/papers/2305.13245). If it is not specified, will default to `32`.\n        head_dim (`int`, *optional*, defaults to 128):\n            The attention head dimension.\n        hidden_act (`str` or `function`, *optional*, defaults to `\"silu\"`):\n            The non-linear activation function (function or string) in the decoder.\n        max_position_embeddings (`int`, *optional*, defaults to 32768):\n            The maximum sequence length that this model might ever be used with.\n        initializer_range (`float`, *optional*, defaults to 0.02):\n            The standard deviation of the truncated_normal_initializer for initializing all weight matrices.\n        rms_norm_eps (`float`, *optional*, defaults to 1e-06):\n            The epsilon used by the rms normalization layers.\n        use_cache (`bool`, *optional*, defaults to `True`):\n            Whether or not the model should return the last key/values attentions (not used by all models). Only\n            relevant if `config.is_decoder=True`.\n        tie_word_embeddings (`bool`, *optional*, defaults to `False`):\n            Whether the model's input and output word embeddings should be tied.\n        rope_theta (`float`, *optional*, defaults to 10000.0):\n            The base period of the RoPE embeddings.\n        rope_scaling (`Dict`, *optional*):\n            Dictionary containing the scaling configuration for the RoPE embeddings. NOTE: if you apply new rope type\n            and you expect the model to work on longer `max_position_embeddings`, we recommend you to update this value\n            accordingly.\n            Expected contents:\n                `rope_type` (`str`):\n                    The sub-variant of RoPE to use. Can be one of ['default', 'linear', 'dynamic', 'yarn', 'longrope',\n                    'llama3'], with 'default' being the original RoPE implementation.\n                `factor` (`float`, *optional*):\n                    Used with all rope types except 'default'. The scaling factor to apply to the RoPE embeddings. In\n                    most scaling types, a `factor` of x will enable the model to handle sequences of length x *\n                    original maximum pre-trained length.\n                `original_max_position_embeddings` (`int`, *optional*):\n                    Used with 'dynamic', 'longrope' and 'llama3'. The original max position embeddings used during\n                    pretraining.\n                `attention_factor` (`float`, *optional*):\n                    Used with 'yarn' and 'longrope'. The scaling factor to be applied on the attention\n                    computation. If unspecified, it defaults to value recommended by the implementation, using the\n                    `factor` field to infer the suggested value.\n                `beta_fast` (`float`, *optional*):\n                    Only used with 'yarn'. Parameter to set the boundary for extrapolation (only) in the linear\n                    ramp function. If unspecified, it defaults to 32.\n                `beta_slow` (`float`, *optional*):\n                    Only used with 'yarn'. Parameter to set the boundary for interpolation (only) in the linear\n                    ramp function. If unspecified, it defaults to 1.\n                `short_factor` (`list[float]`, *optional*):\n                    Only used with 'longrope'. The scaling factor to be applied to short contexts (<\n                    `original_max_position_embeddings`). Must be a list of numbers with the same length as the hidden\n                    size divided by the number of attention heads divided by 2\n                `long_factor` (`list[float]`, *optional*):\n                    Only used with 'longrope'. The scaling factor to be applied to long contexts (<\n                    `original_max_position_embeddings`). Must be a list of numbers with the same length as the hidden\n                    size divided by the number of attention heads divided by 2\n                `low_freq_factor` (`float`, *optional*):\n                    Only used with 'llama3'. Scaling factor applied to low frequency components of the RoPE\n                `high_freq_factor` (`float`, *optional*):\n                    Only used with 'llama3'. Scaling factor applied to high frequency components of the RoPE\n        attention_bias (`bool`, defaults to `False`, *optional*, defaults to `False`):\n            Whether to use a bias in the query, key, value and output projection layers during self-attention.\n        use_sliding_window (`bool`, *optional*, defaults to `False`):\n            Whether to use sliding window attention.\n        sliding_window (`int`, *optional*, defaults to 4096):\n            Sliding window attention (SWA) window size. If not specified, will default to `4096`.\n        layer_types (`list`, *optional*):\n            Attention pattern for each layer.\n        attention_dropout (`float`, *optional*, defaults to 0.0):\n            The dropout ratio for the attention probabilities.\n\n    ```python\n    >>> from acestep.models import AceStepConfig\n\n    >>> # Initializing an AceStep configuration\n    >>> configuration = AceStepConfig()\n\n    >>> # Initializing a model from the configuration\n    >>> model = AceStepConditionGenerationModel(configuration)\n\n    >>> # Accessing the model configuration\n    >>> configuration = model.config\n    ```\"\"\"\n\n    model_type = \"acestep\"\n    keys_to_ignore_at_inference = [\"past_key_values\"]\n    \n    # Default tensor parallel plan for the base model\n    base_model_tp_plan = {\n        \"layers.*.self_attn.q_proj\": \"colwise\",\n        \"layers.*.self_attn.k_proj\": \"colwise\",\n        \"layers.*.self_attn.v_proj\": \"colwise\",\n        \"layers.*.self_attn.o_proj\": \"rowwise\",\n        \"layers.*.mlp.gate_proj\": \"colwise\",\n        \"layers.*.mlp.up_proj\": \"colwise\",\n        \"layers.*.mlp.down_proj\": \"rowwise\",\n    }\n    base_model_pp_plan = {\n        \"embed_tokens\": ([\"input_ids\"], [\"inputs_embeds\"]),\n        \"layers\": ([\"hidden_states\", \"attention_mask\"], [\"hidden_states\"]),\n        \"norm\": ([\"hidden_states\"], [\"hidden_states\"]),\n    }\n    def __init__(\n        self,\n        vocab_size=64003,\n        fsq_dim=2048,\n        fsq_input_levels=[8, 8, 8, 5, 5, 5],\n        fsq_input_num_quantizers=1,\n        hidden_size=2048,\n        intermediate_size=6144,\n        num_hidden_layers=24,\n        num_attention_heads=16,\n        num_key_value_heads=8,\n        head_dim=128,\n        hidden_act=\"silu\",\n        max_position_embeddings=32768,\n        initializer_range=0.02,\n        rms_norm_eps=1e-6,\n        use_cache=True,\n        tie_word_embeddings=True,\n        rope_theta=1000000,\n        rope_scaling=None,\n        attention_bias=False,\n        use_sliding_window=True,\n        sliding_window=128,\n        layer_types=None,\n        attention_dropout=0.0,\n        num_lyric_encoder_hidden_layers=8,\n        audio_acoustic_hidden_dim=64,\n        pool_window_size=5,\n        text_hidden_dim=1024,\n        in_channels=192,\n        data_proportion=0.5,\n        timestep_mu=-0.4,\n        timestep_sigma=1.0,\n        timbre_hidden_dim=64,\n        num_timbre_encoder_hidden_layers=4,\n        timbre_fix_frame=750,\n        patch_size=2,\n        num_attention_pooler_hidden_layers=2,\n        num_audio_decoder_hidden_layers=24,\n        model_version=\"turbo\",\n        **kwargs,\n    ):\n        self.max_position_embeddings = max_position_embeddings\n        self.hidden_size = hidden_size\n        self.intermediate_size = intermediate_size\n        self.num_hidden_layers = num_hidden_layers\n        self.num_attention_heads = num_attention_heads\n        self.use_sliding_window = use_sliding_window\n        self.sliding_window = sliding_window if self.use_sliding_window else None\n        \n        # Text encoder configuration\n        self.text_hidden_dim = text_hidden_dim\n\n        # Lyric encoder configuration\n        self.num_lyric_encoder_hidden_layers = num_lyric_encoder_hidden_layers\n        self.patch_size = patch_size\n\n        # Audio semantic token generation configuration\n        self.audio_acoustic_hidden_dim = audio_acoustic_hidden_dim\n        self.pool_window_size = pool_window_size\n        self.in_channels = in_channels\n        self.data_proportion = data_proportion\n        self.timestep_mu = timestep_mu\n        self.timestep_sigma = timestep_sigma\n        \n        # FSQ (Finite Scalar Quantization) configuration\n        self.fsq_dim = fsq_dim\n        self.fsq_input_levels = fsq_input_levels\n        self.fsq_input_num_quantizers = fsq_input_num_quantizers\n        \n        # Timbre encoder configuration\n        self.timbre_hidden_dim = timbre_hidden_dim\n        self.num_timbre_encoder_hidden_layers = num_timbre_encoder_hidden_layers\n        self.timbre_fix_frame = timbre_fix_frame\n        self.num_attention_pooler_hidden_layers = num_attention_pooler_hidden_layers\n        self.num_audio_decoder_hidden_layers = num_audio_decoder_hidden_layers\n        self.vocab_size = vocab_size\n\n        # Backward compatibility: ensure num_key_value_heads is set\n        if num_key_value_heads is None:\n            num_key_value_heads = num_attention_heads\n\n        self.num_key_value_heads = num_key_value_heads\n        self.head_dim = head_dim\n        self.hidden_act = hidden_act\n        self.initializer_range = initializer_range\n        self.rms_norm_eps = rms_norm_eps\n        self.use_cache = use_cache\n        self.rope_theta = rope_theta\n        self.rope_scaling = rope_scaling\n        self.attention_bias = attention_bias\n        self.attention_dropout = attention_dropout\n        self.model_version = model_version\n        \n        # Validate rotary position embeddings parameters\n        # Backward compatibility: if there is a 'type' field, move it to 'rope_type'\n        if self.rope_scaling is not None and \"type\" in self.rope_scaling:\n            self.rope_scaling[\"rope_type\"] = self.rope_scaling[\"type\"]\n        rope_config_validation(self)\n\n        self.layer_types = layer_types\n\n        # Set default layer types if not specified\n        if self.layer_types is None:\n            self.layer_types = [\n                \"sliding_attention\" if bool((i + 1) % 2) else \"full_attention\" for i in range(self.num_hidden_layers)\n            ]\n        layer_type_validation(self.layer_types)\n\n        super().__init__(\n            tie_word_embeddings=tie_word_embeddings,\n            **kwargs,\n        )\n\n\n__all__ = [\"AceStepConfig\"]\n"
  },
  {
    "path": "acestep/models/sft/modeling_acestep_v15_base.py",
    "content": "# Copyright 2025 The ACESTEO Team. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#     http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\nimport math\nimport time\nfrom typing import Callable, List, Optional, Union\n\nimport torch\nimport torch.nn.functional as F\nfrom torch import nn\n\nfrom einops import rearrange\n\n# Transformers imports (sorted by submodule, then alphabetically)\nfrom transformers.cache_utils import Cache, DynamicCache, EncoderDecoderCache\nfrom transformers.modeling_attn_mask_utils import _prepare_4d_causal_attention_mask\nfrom transformers.modeling_flash_attention_utils import FlashAttentionKwargs\nfrom transformers.modeling_layers import GradientCheckpointingLayer\nfrom transformers.modeling_outputs import BaseModelOutput\nfrom transformers.modeling_utils import ALL_ATTENTION_FUNCTIONS, PreTrainedModel\nfrom transformers.processing_utils import Unpack\nfrom transformers.utils import auto_docstring, can_return_tuple, logging\nfrom transformers.models.qwen3.modeling_qwen3 import (\n    Qwen3MLP,\n    Qwen3RMSNorm,\n    Qwen3RotaryEmbedding,\n    apply_rotary_pos_emb,\n    eager_attention_forward,\n)\nfrom tqdm import tqdm\nfrom vector_quantize_pytorch import ResidualFSQ\n\n\n# Local config import with fallback\ntry:\n    from .configuration_acestep_v15 import AceStepConfig\n    from .apg_guidance import adg_forward, apg_forward, MomentumBuffer\nexcept ImportError:\n    from configuration_acestep_v15 import AceStepConfig\n    from apg_guidance import adg_forward, apg_forward, MomentumBuffer\n\n\nlogger = logging.get_logger(__name__)\n\n\ndef create_4d_mask(\n    seq_len: int,\n    dtype: torch.dtype,\n    device: torch.device,\n    attention_mask: Optional[torch.Tensor] = None, # [Batch, Seq_Len]\n    sliding_window: Optional[int] = None,\n    is_sliding_window: bool = False,\n    is_causal: bool = True,\n) -> torch.Tensor:\n    \"\"\"\n    General 4D Attention Mask generator compatible with CPU/Mac/SDPA and Eager mode.\n    Supports use cases:\n    1. Causal Full: is_causal=True, is_sliding_window=False (standard GPT)\n    2. Causal Sliding: is_causal=True, is_sliding_window=True (Mistral/Qwen local window)\n    3. Bidirectional Full: is_causal=False, is_sliding_window=False (BERT/Encoder)\n    4. Bidirectional Sliding: is_causal=False, is_sliding_window=True (Longformer local)\n\n    Returns:\n        [Batch, 1, Seq_Len, Seq_Len] additive mask (0.0 for keep, -inf for mask)\n    \"\"\"\n    # ------------------------------------------------------\n    # 1. Construct basic geometry mask [Seq_Len, Seq_Len]\n    # ------------------------------------------------------\n\n    # Build index matrices\n    # i (Query): [0, 1, ..., L-1]\n    # j (Key):   [0, 1, ..., L-1]\n    indices = torch.arange(seq_len, device=device)\n    # diff = i - j\n    diff = indices.unsqueeze(1) - indices.unsqueeze(0)\n\n    # Initialize all True (all positions visible)\n    valid_mask = torch.ones((seq_len, seq_len), device=device, dtype=torch.bool)\n\n    # (A) Handle causality (Causal)\n    if is_causal:\n        # i >= j  =>  diff >= 0\n        valid_mask = valid_mask & (diff >= 0)\n\n    # (B) Handle sliding window\n    if is_sliding_window and sliding_window is not None:\n        if is_causal:\n            # Causal sliding: only attend to past window steps\n            # i - j <= window  =>  diff <= window\n            # (diff >= 0 already handled above)\n            valid_mask = valid_mask & (diff <= sliding_window)\n        else:\n            # Bidirectional sliding: attend past and future window steps\n            # |i - j| <= window  =>  abs(diff) <= sliding_window\n            valid_mask = valid_mask & (torch.abs(diff) <= sliding_window)\n\n    # Expand dimensions to [1, 1, Seq_Len, Seq_Len] for broadcasting\n    valid_mask = valid_mask.unsqueeze(0).unsqueeze(0)\n\n    # ------------------------------------------------------\n    # 2. Apply padding mask (Key Masking)\n    # ------------------------------------------------------\n    if attention_mask is not None:\n        # attention_mask shape: [Batch, Seq_Len] (1=valid, 0=padding)\n        # We want to mask out invalid keys (columns)\n        # Expand shape: [Batch, 1, 1, Seq_Len]\n        padding_mask_4d = attention_mask.view(attention_mask.shape[0], 1, 1, seq_len).to(torch.bool)\n\n        # Broadcasting: Geometry Mask [1, 1, L, L] & Padding Mask [B, 1, 1, L]\n        # Result shape: [B, 1, L, L]\n        valid_mask = valid_mask & padding_mask_4d\n\n    # ------------------------------------------------------\n    # 3. Convert to additive mask\n    # ------------------------------------------------------\n    # Get the minimal value for current dtype\n    min_dtype = torch.finfo(dtype).min\n\n    # Create result tensor filled with -inf by default\n    mask_tensor = torch.full(valid_mask.shape, min_dtype, dtype=dtype, device=device)\n\n    # Set valid positions to 0.0\n    mask_tensor.masked_fill_(valid_mask, 0.0)\n\n    return mask_tensor\n\n\ndef pack_sequences(hidden1: torch.Tensor, hidden2: torch.Tensor, mask1: torch.Tensor, mask2: torch.Tensor):\n    \"\"\"\n    Pack two sequences by concatenating and sorting them based on mask values.\n\n    Args:\n        hidden1: First hidden states tensor of shape [B, L1, D]\n        hidden2: Second hidden states tensor of shape [B, L2, D]\n        mask1: First mask tensor of shape [B, L1]\n        mask2: Second mask tensor of shape [B, L2]\n\n    Returns:\n        Tuple of (packed_hidden_states, new_mask) where:\n        - packed_hidden_states: Packed hidden states with valid tokens (mask=1) first, shape [B, L1+L2, D]\n        - new_mask: New mask tensor indicating valid positions, shape [B, L1+L2]\n    \"\"\"\n    # Step 1: Concatenate hidden states and masks along sequence dimension\n    hidden_cat = torch.cat([hidden1, hidden2], dim=1)  # [B, L, D]\n    mask_cat = torch.cat([mask1, mask2], dim=1)  # [B, L]\n\n    B, L, D = hidden_cat.shape\n\n    # Step 2: Sort indices so that mask values of 1 come before 0\n    sort_idx = mask_cat.argsort(dim=1, descending=True, stable=True)  # [B, L]\n\n    # Step 3: Reorder hidden states using sorted indices\n    hidden_left = torch.gather(hidden_cat, 1, sort_idx.unsqueeze(-1).expand(B, L, D))\n\n    # Step 4: Create new mask based on valid sequence lengths\n    lengths = mask_cat.sum(dim=1)  # [B]\n    new_mask = (torch.arange(L, dtype=torch.long, device=hidden_cat.device).unsqueeze(0) < lengths.unsqueeze(1))\n\n    return hidden_left, new_mask\n\n\ndef sample_t_r(batch_size, device, dtype, data_proportion=0.0, timestep_mu=-0.4, timestep_sigma=1.0, use_meanflow=True):\n    \"\"\"\n    Sample timestep t and r for flow matching training.\n\n    Args:\n        batch_size: Batch size\n        device: Device to create tensors on\n        dtype: Data type for tensors\n        data_proportion: Proportion of data samples (0.0 to 1.0)\n        timestep_mu: Mean for timestep sampling\n        timestep_sigma: Standard deviation for timestep sampling\n        use_meanflow: Whether to use meanflow (if False, data_proportion is set to 1.0)\n\n    Returns:\n        Tuple of (t, r) tensors, each of shape [batch_size]\n    \"\"\"\n    t = torch.sigmoid(torch.randn((batch_size,), device=device, dtype=dtype) * timestep_sigma + timestep_mu)\n    r = torch.sigmoid(torch.randn((batch_size,), device=device, dtype=dtype) * timestep_sigma + timestep_mu)\n    # Assign t = max, r = min, for each pair\n    t, r = torch.maximum(t, r), torch.minimum(t, r)\n    if not use_meanflow:\n        data_proportion = 1.0\n    data_size = int(batch_size * data_proportion)\n    zero_mask = torch.arange(batch_size, device=device) < data_size\n    r = torch.where(zero_mask, t, r)\n    return t, r\n\n\nclass TimestepEmbedding(nn.Module):\n    \"\"\"\n    Timestep embedding module for diffusion models.\n\n    Converts timestep values into high-dimensional embeddings using sinusoidal\n    positional encoding, followed by MLP layers. Used for conditioning diffusion\n    models on timestep information.\n    \"\"\"\n    def __init__(\n        self,\n        in_channels: int,\n        time_embed_dim: int,\n        scale: float = 1000,\n    ):\n        super().__init__()\n\n        self.linear_1 = nn.Linear(in_channels, time_embed_dim, bias=True)\n        self.act1 = nn.SiLU()\n        self.linear_2 = nn.Linear(time_embed_dim, time_embed_dim, bias=True)\n        self.in_channels = in_channels\n\n        self.act2 = nn.SiLU()\n        self.time_proj = nn.Linear(time_embed_dim, time_embed_dim * 6)\n        self.scale = scale\n\n    def timestep_embedding(self, t, dim, max_period=10000):\n        \"\"\"\n        Create sinusoidal timestep embeddings.\n\n        Args:\n            t: A 1-D tensor of N indices, one per batch element. These may be fractional.\n            dim: The dimension of the output embeddings.\n            max_period: Controls the minimum frequency of the embeddings.\n\n        Returns:\n            An (N, D) tensor of positional embeddings.\n        \"\"\"\n        t = t * self.scale\n        half = dim // 2\n        freqs = torch.exp(\n            -math.log(max_period) * torch.arange(start=0, end=half, dtype=torch.float32) / half\n        ).to(device=t.device)\n        args = t[:, None].float() * freqs[None]\n        embedding = torch.cat([torch.cos(args), torch.sin(args)], dim=-1)\n        if dim % 2:\n            embedding = torch.cat([embedding, torch.zeros_like(embedding[:, :1])], dim=-1)\n        return embedding\n\n    def forward(self, t):\n        t_freq = self.timestep_embedding(t, self.in_channels)\n        temb = self.linear_1(t_freq.to(t.dtype))\n        temb = self.act1(temb)\n        temb = self.linear_2(temb)\n        timestep_proj = self.time_proj(self.act2(temb)).unflatten(1, (6, -1))\n        return temb, timestep_proj\n\nclass AceStepAttention(nn.Module):\n    \"\"\"\n    Multi-headed attention module for AceStep model.\n\n    Implements the attention mechanism from 'Attention Is All You Need' paper,\n    with support for both self-attention and cross-attention modes. Uses RMSNorm\n    for query and key normalization, and supports sliding window attention for\n    efficient long-sequence processing.\n    \"\"\"\n\n    def __init__(self, config: AceStepConfig, layer_idx: int, is_cross_attention: bool = False, is_causal: bool = False):\n        super().__init__()\n        self.config = config\n        self.layer_idx = layer_idx\n        self.head_dim = getattr(config, \"head_dim\", config.hidden_size // config.num_attention_heads)\n        self.num_key_value_groups = config.num_attention_heads // config.num_key_value_heads\n        self.scaling = self.head_dim**-0.5\n        self.attention_dropout = config.attention_dropout\n        if is_cross_attention:\n            is_causal = False\n        self.is_causal = is_causal\n        self.is_cross_attention = is_cross_attention\n\n        self.q_proj = nn.Linear(config.hidden_size, config.num_attention_heads * self.head_dim, bias=config.attention_bias)\n        self.k_proj = nn.Linear(config.hidden_size, config.num_key_value_heads * self.head_dim, bias=config.attention_bias)\n        self.v_proj = nn.Linear(config.hidden_size, config.num_key_value_heads * self.head_dim, bias=config.attention_bias)\n        self.o_proj = nn.Linear(config.num_attention_heads * self.head_dim, config.hidden_size, bias=config.attention_bias)\n        # Apply RMS normalization only on the head dimension (unlike OLMo)\n        self.q_norm = Qwen3RMSNorm(self.head_dim, eps=config.rms_norm_eps)\n        self.k_norm = Qwen3RMSNorm(self.head_dim, eps=config.rms_norm_eps)\n        self.attention_type = config.layer_types[layer_idx]\n        self.sliding_window = config.sliding_window if config.layer_types[layer_idx] == \"sliding_attention\" else None\n\n    def forward(\n        self,\n        hidden_states: torch.Tensor,\n        attention_mask: Optional[torch.Tensor],\n        past_key_value: Optional[Cache] = None,\n        cache_position: Optional[torch.LongTensor] = None,\n        encoder_hidden_states: Optional[torch.Tensor] = None,\n        position_embeddings: tuple[torch.Tensor, torch.Tensor] = None,\n        output_attentions: Optional[bool] = False,\n        **kwargs: Unpack[FlashAttentionKwargs],\n    ) -> tuple[torch.Tensor, Optional[torch.Tensor], Optional[tuple[torch.Tensor]]]:\n        input_shape = hidden_states.shape[:-1]\n        hidden_shape = (*input_shape, -1, self.head_dim)\n\n        # Project and normalize query states\n        query_states = self.q_norm(self.q_proj(hidden_states).view(hidden_shape)).transpose(1, 2)\n\n        # Determine if this is cross-attention (requires encoder_hidden_states)\n        is_cross_attention = self.is_cross_attention and encoder_hidden_states is not None\n\n        # Cross-attention path: attend to encoder hidden states\n        if is_cross_attention:\n            encoder_hidden_shape = (*encoder_hidden_states.shape[:-1], -1, self.head_dim)\n            if past_key_value is not None:\n                is_updated = past_key_value.is_updated.get(self.layer_idx)\n                # After the first generated token, we can reuse all key/value states from cache\n                curr_past_key_value = past_key_value.cross_attention_cache\n\n                # Conditions for calculating key and value states\n                if not is_updated:\n                    # Compute and cache K/V for the first time\n                    key_states = self.k_norm(self.k_proj(encoder_hidden_states).view(encoder_hidden_shape)).transpose(1, 2)\n                    value_states = self.v_proj(encoder_hidden_states).view(encoder_hidden_shape).transpose(1, 2)\n                    # Update cache: save all key/value states to cache for fast auto-regressive generation\n                    key_states, value_states = curr_past_key_value.update(key_states, value_states, self.layer_idx)\n                    # Set flag that this layer's cross-attention cache is updated\n                    past_key_value.is_updated[self.layer_idx] = True\n                else:\n                    # Reuse cached key/value states for subsequent tokens\n                    key_states = curr_past_key_value.layers[self.layer_idx].keys\n                    value_states = curr_past_key_value.layers[self.layer_idx].values\n            else:\n                # No cache used, compute K/V directly\n                key_states = self.k_norm(self.k_proj(encoder_hidden_states).view(encoder_hidden_shape)).transpose(1, 2)\n                value_states = self.v_proj(encoder_hidden_states).view(encoder_hidden_shape).transpose(1, 2)\n\n        # Self-attention path: attend to the same sequence\n        else:\n            # Project and normalize key/value states for self-attention\n            key_states = self.k_norm(self.k_proj(hidden_states).view(hidden_shape)).transpose(1, 2)\n            value_states = self.v_proj(hidden_states).view(hidden_shape).transpose(1, 2)\n            # Apply rotary position embeddings (RoPE) if provided\n            if position_embeddings is not None:\n                cos, sin = position_embeddings\n                query_states, key_states = apply_rotary_pos_emb(query_states, key_states, cos, sin)\n\n            # Update cache for auto-regressive generation\n            if past_key_value is not None:\n                # Sin and cos are specific to RoPE models; cache_position needed for the static cache\n                cache_kwargs = {\"sin\": sin, \"cos\": cos, \"cache_position\": cache_position}\n                key_states, value_states = past_key_value.update(key_states, value_states, self.layer_idx, cache_kwargs)\n\n        attention_interface: Callable = eager_attention_forward\n        if is_cross_attention and output_attentions:\n            attention_interface: Callable = eager_attention_forward\n        elif self.config._attn_implementation != \"eager\":\n            attention_interface = ALL_ATTENTION_FUNCTIONS[self.config._attn_implementation]\n\n        attn_output, attn_weights = attention_interface(\n            self,\n            query_states,\n            key_states,\n            value_states,\n            attention_mask,\n            dropout=self.attention_dropout if self.training else 0.0,\n            scaling=self.scaling,\n            sliding_window=self.sliding_window if not self.is_cross_attention else None,\n            **kwargs,\n        )\n\n        attn_output = attn_output.reshape(*input_shape, -1).contiguous()\n        attn_output = self.o_proj(attn_output)\n        return attn_output, attn_weights\n\n\nclass AceStepEncoderLayer(GradientCheckpointingLayer):\n    \"\"\"\n    Encoder layer for AceStep model.\n\n    Consists of self-attention and MLP (feed-forward) sub-layers with residual connections.\n    \"\"\"\n\n    def __init__(self, config, layer_idx: int):\n        super().__init__()\n        self.hidden_size = config.hidden_size\n        self.config = config\n        self.layer_idx = layer_idx\n\n        # Self-attention sub-layer\n        self.self_attn = AceStepAttention(\n            config=config,\n            layer_idx=layer_idx,\n            is_cross_attention=False,\n            is_causal=False,\n        )\n        self.input_layernorm = Qwen3RMSNorm(config.hidden_size, eps=config.rms_norm_eps)\n        self.post_attention_layernorm = Qwen3RMSNorm(config.hidden_size, eps=config.rms_norm_eps)\n\n        # MLP (feed-forward) sub-layer\n        self.mlp = Qwen3MLP(config)\n        self.attention_type = config.layer_types[layer_idx]\n\n    def forward(\n        self,\n        hidden_states: torch.Tensor,\n        position_embeddings: tuple[torch.Tensor, torch.Tensor],\n        attention_mask: Optional[torch.Tensor] = None,\n        position_ids: Optional[torch.LongTensor] = None,\n        output_attentions: Optional[bool] = False,\n        **kwargs,\n    ) -> tuple[\n        torch.FloatTensor,\n        Optional[tuple[torch.FloatTensor, torch.FloatTensor]],\n    ]:\n        # Self-attention with residual connection\n        residual = hidden_states\n        hidden_states = self.input_layernorm(hidden_states)\n        hidden_states, self_attn_weights = self.self_attn(\n            hidden_states=hidden_states,\n            position_embeddings=position_embeddings,\n            attention_mask=attention_mask,\n            position_ids=position_ids,\n            output_attentions=output_attentions,\n            # Encoders don't use cache\n            use_cache=False,\n            past_key_value=None,\n            **kwargs,\n        )\n        hidden_states = residual + hidden_states\n\n        # MLP with residual connection\n        residual = hidden_states\n        hidden_states = self.post_attention_layernorm(hidden_states)\n        hidden_states = self.mlp(hidden_states)\n        hidden_states = residual + hidden_states\n\n        outputs = (hidden_states,)\n\n        if output_attentions:\n            outputs += (self_attn_weights,)\n\n        return outputs\n\n\nclass AceStepDiTLayer(GradientCheckpointingLayer):\n    \"\"\"\n    DiT (Diffusion Transformer) layer for AceStep model.\n\n    Implements a transformer layer with three main components:\n    1. Self-attention with adaptive layer norm (AdaLN)\n    2. Cross-attention (optional) for conditioning on encoder outputs\n    3. Feed-forward MLP with adaptive layer norm\n\n    Uses scale-shift modulation from timestep embeddings for adaptive normalization.\n    \"\"\"\n    def __init__(self, config: AceStepConfig, layer_idx: int, use_cross_attention: bool = True):\n        super().__init__()\n\n        # 1. Self-attention sub-layer with adaptive normalization\n        self.self_attn_norm = Qwen3RMSNorm(config.hidden_size, eps=config.rms_norm_eps)\n        self.self_attn = AceStepAttention(config=config, layer_idx=layer_idx)\n\n        # 2. Cross-attention sub-layer (optional, for encoder conditioning)\n        self.use_cross_attention = use_cross_attention\n        if self.use_cross_attention:\n            self.cross_attn_norm = Qwen3RMSNorm(config.hidden_size, eps=config.rms_norm_eps)\n            self.cross_attn = AceStepAttention(config=config, layer_idx=layer_idx, is_cross_attention=True)\n\n        # 3. Feed-forward MLP sub-layer with adaptive normalization\n        self.mlp_norm = Qwen3RMSNorm(config.hidden_size, eps=config.rms_norm_eps)\n        self.mlp = Qwen3MLP(config)\n\n        # Scale-shift table for adaptive layer norm modulation (6 values: 3 for self-attn, 3 for MLP)\n        self.scale_shift_table = nn.Parameter(torch.randn(1, 6, config.hidden_size) / config.hidden_size**0.5)\n        self.attention_type = config.layer_types[layer_idx]\n\n    def forward(\n        self,\n        hidden_states: torch.Tensor,\n        position_embeddings: tuple[torch.Tensor, torch.Tensor],\n        temb: torch.Tensor,\n        attention_mask: Optional[torch.Tensor] = None,\n        position_ids: Optional[torch.LongTensor] = None,\n        past_key_value: Optional[EncoderDecoderCache] = None,\n        output_attentions: Optional[bool] = False,\n        use_cache: Optional[bool] = False,\n        cache_position: Optional[torch.LongTensor] = None,\n        encoder_hidden_states: Optional[torch.Tensor] = None,\n        encoder_attention_mask: Optional[torch.Tensor] = None,\n        **kwargs,\n    ) -> torch.Tensor:\n\n        # Extract scale-shift parameters for adaptive layer norm from timestep embeddings\n        # 6 values: (shift_msa, scale_msa, gate_msa, c_shift_msa, c_scale_msa, c_gate_msa)\n        shift_msa, scale_msa, gate_msa, c_shift_msa, c_scale_msa, c_gate_msa = (\n            self.scale_shift_table + temb\n        ).chunk(6, dim=1)\n\n        # Step 1: Self-attention with adaptive layer norm (AdaLN)\n        # Apply adaptive normalization: norm(x) * (1 + scale) + shift\n        norm_hidden_states = (self.self_attn_norm(hidden_states) * (1 + scale_msa) + shift_msa).type_as(hidden_states)\n        attn_output, self_attn_weights = self.self_attn(\n            hidden_states=norm_hidden_states,\n            position_embeddings=position_embeddings,\n            attention_mask=attention_mask,\n            position_ids=position_ids,\n            output_attentions=output_attentions,\n            use_cache=False,\n            past_key_value=None,\n            **kwargs,\n        )\n        # Apply gated residual connection: x = x + attn_output * gate\n        hidden_states = (hidden_states + attn_output * gate_msa).type_as(hidden_states)\n\n        # Step 2: Cross-attention (if enabled) for conditioning on encoder outputs\n        if self.use_cross_attention:\n            norm_hidden_states = self.cross_attn_norm(hidden_states).type_as(hidden_states)\n            attn_output, cross_attn_weights = self.cross_attn(\n                hidden_states=norm_hidden_states,\n                encoder_hidden_states=encoder_hidden_states,\n                attention_mask=encoder_attention_mask,\n                past_key_value=past_key_value,\n                output_attentions=output_attentions,\n                use_cache=use_cache,\n                **kwargs,\n            )\n            # Standard residual connection for cross-attention\n            hidden_states = hidden_states + attn_output\n\n        # Step 3: Feed-forward (MLP) with adaptive layer norm\n        # Apply adaptive normalization for MLP: norm(x) * (1 + scale) + shift\n        norm_hidden_states = (self.mlp_norm(hidden_states) * (1 + c_scale_msa) + c_shift_msa).type_as(hidden_states)\n        ff_output = self.mlp(norm_hidden_states)\n        # Apply gated residual connection: x = x + mlp_output * gate\n        hidden_states = (hidden_states + ff_output * c_gate_msa).type_as(hidden_states)\n\n        outputs = (hidden_states,)\n        if output_attentions:\n            outputs += (self_attn_weights, cross_attn_weights)\n\n        return outputs\n\n\n@auto_docstring\nclass AceStepPreTrainedModel(PreTrainedModel):\n    config_class = AceStepConfig\n    base_model_prefix = \"model\"\n    supports_gradient_checkpointing = True\n    _no_split_modules = [\"AceStepEncoderLayer\", \"AceStepDiTLayer\"]\n    _skip_keys_device_placement = [\"past_key_values\"]\n    _supports_flash_attn_3 = True\n    _supports_flash_attn_2 = True\n    _supports_sdpa = True\n    _supports_flex_attn = True\n    _supports_cache_class = True\n    _supports_quantized_cache = True\n    _supports_static_cache = True\n    _supports_attention_backend = True\n\n    def _init_weights(self, module):\n        \"\"\"\n        Initialize weights for different module types.\n\n        TODO: Support separate initialization for encoders and decoders.\n        \"\"\"\n        std = self.config.initializer_range\n        if isinstance(module, nn.Linear):\n            module.weight.data.normal_(mean=0.0, std=std)\n            if module.bias is not None:\n                module.bias.data.zero_()\n        elif isinstance(module, nn.Embedding):\n            module.weight.data.normal_(mean=0.0, std=std)\n            if module.padding_idx is not None:\n                module.weight.data[module.padding_idx].zero_()\n        elif isinstance(module, Qwen3RMSNorm):\n            module.weight.data.fill_(1.0)\n\n\nclass AceStepLyricEncoder(AceStepPreTrainedModel):\n    \"\"\"\n    Encoder for processing lyric text embeddings.\n\n    Encodes lyric text hidden states using a transformer encoder architecture\n    with bidirectional attention. Projects text embeddings to model hidden size\n    and processes them through multiple encoder layers.\n    \"\"\"\n    def __init__(self, config):\n        super().__init__(config)\n\n        # Project text embeddings to model hidden size\n        self.embed_tokens = nn.Linear(config.text_hidden_dim, config.hidden_size)\n        self.norm = Qwen3RMSNorm(config.hidden_size, eps=config.rms_norm_eps)\n        self.rotary_emb = Qwen3RotaryEmbedding(config=config)\n        self.gradient_checkpointing = False\n\n        # Stack of encoder layers\n        self.layers = nn.ModuleList(\n            [AceStepEncoderLayer(config, layer_idx) for layer_idx in range(config.num_lyric_encoder_hidden_layers)]\n        )\n\n        # Initialize weights and apply final processing\n        self.post_init()\n\n    @can_return_tuple\n    def forward(\n        self,\n        input_ids: Optional[torch.LongTensor] = None,\n        attention_mask: Optional[torch.Tensor] = None,\n        position_ids: Optional[torch.LongTensor] = None,\n        inputs_embeds: Optional[torch.FloatTensor] = None,\n        output_attentions: Optional[bool] = None,\n        output_hidden_states: Optional[bool] = None,\n        **flash_attn_kwargs: Unpack[FlashAttentionKwargs],\n    ) -> BaseModelOutput:\n        output_attentions = output_attentions if output_attentions is not None else self.config.output_attentions\n        output_hidden_states = (\n            output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states\n        )\n\n        assert input_ids is None, \"Only `input_ids` is supported for the lyric encoder.\"\n        assert attention_mask is not None, \"Attention mask must be provided for the lyric encoder.\"\n        assert inputs_embeds is not None, \"Inputs embeddings must be provided for the lyric encoder.\"\n\n        # Project input embeddings: N x T x text_hidden_dim -> N x T x hidden_size\n        inputs_embeds = self.embed_tokens(inputs_embeds)\n        # Cache position: only used for mask construction (not for actual caching)\n        cache_position = torch.arange(0, inputs_embeds.shape[1], device=inputs_embeds.device)\n\n        # Positional IDs\n        if position_ids is None:\n            position_ids = cache_position.unsqueeze(0)\n\n        # Attention masks\n        seq_len = inputs_embeds.shape[1]\n        dtype = inputs_embeds.dtype\n        device = inputs_embeds.device\n\n        # 判断是否使用 Flash Attention 2\n        is_flash_attn = (self.config._attn_implementation == \"flash_attention_2\")\n\n        # 初始化 Mask 变量\n        full_attn_mask = None\n        sliding_attn_mask = None\n\n        if is_flash_attn:\n            # -------------------------------------------------------\n            # 场景 A: Flash Attention 模式\n            # -------------------------------------------------------\n            # FA 不需要 4D Mask。\n            # 如果有 padding mask (attention_mask [B, L])，直接传给它即可。\n            # 如果没有 padding mask，传 None。\n            # 滑动窗口逻辑由 Layer 内部传给 FA kernel 的 sliding_window 参数控制。\n            full_attn_mask = attention_mask\n\n            # 这里的逻辑是：如果配置启用了滑动窗口，FA 模式下我们也只需要传基础的 padding mask\n            # Layer 会自己决定是否调用带 sliding window 的 kernel\n            sliding_attn_mask = attention_mask if self.config.use_sliding_window else None\n\n        else:\n            # -------------------------------------------------------\n            # 场景 B: CPU / Mac / SDPA (Eager 模式)\n            # -------------------------------------------------------\n            # 必须手动生成 4D Mask [B, 1, L, L]\n\n            # 1. Full Attention (Bidirectional, Global)\n            # 对应原来的 create_causal_mask + bidirectional\n            full_attn_mask = create_4d_mask(\n                seq_len=seq_len,\n                dtype=dtype,\n                device=device,\n                attention_mask=attention_mask,     # [B, L]\n                sliding_window=None,\n                is_sliding_window=False,\n                is_causal=False                    # <--- 关键：双向注意力\n            )\n\n            # 2. Sliding Attention (Bidirectional, Local)\n            # 对应原来的 create_sliding_window... + bidirectional\n            if self.config.use_sliding_window:\n                sliding_attn_mask = create_4d_mask(\n                    seq_len=seq_len,\n                    dtype=dtype,\n                    device=device,\n                    attention_mask=attention_mask, # [B, L]\n                    sliding_window=self.config.sliding_window,\n                    is_sliding_window=True,        # <--- 开启滑动窗口\n                    is_causal=False                # <--- 关键：双向注意力\n                )\n\n        # 构建 Mapping\n        self_attn_mask_mapping = {\n            \"full_attention\": full_attn_mask,\n            \"sliding_attention\": sliding_attn_mask,\n        }\n\n        # Initialize hidden states with input embeddings\n        hidden_states = inputs_embeds\n\n        # Create position embeddings to be shared across all layers\n        position_embeddings = self.rotary_emb(hidden_states, position_ids)\n\n        # Pass through transformer layers\n        all_hidden_states = () if output_hidden_states else None\n        all_self_attns = () if output_attentions else None\n\n        for layer_module in self.layers[: self.config.num_hidden_layers]:\n            if output_hidden_states:\n                all_hidden_states += (hidden_states,)\n\n            layer_outputs = layer_module(\n                hidden_states,\n                position_embeddings,\n                self_attn_mask_mapping[layer_module.attention_type],\n                position_ids,\n                output_attentions,\n                **flash_attn_kwargs,\n            )\n\n            hidden_states = layer_outputs[0]\n\n            if output_attentions:\n                all_self_attns += (layer_outputs[1],)\n\n        hidden_states = self.norm(hidden_states)\n\n        if output_hidden_states:\n            all_hidden_states += (hidden_states,)\n\n        return BaseModelOutput(\n            last_hidden_state=hidden_states,\n            hidden_states=all_hidden_states,\n            attentions=all_self_attns,\n        )\n\n\nclass AttentionPooler(AceStepPreTrainedModel):\n    \"\"\"\n    Attention-based pooling module.\n\n    Pools sequences of patches using a special token and attention mechanism.\n    The special token attends to all patches and its output is used as the\n    pooled representation. Used for aggregating patch-level features into\n    sequence-level representations.\n    \"\"\"\n    def __init__(self, config):\n        super().__init__(config)\n        self.config = config\n        self.embed_tokens = nn.Linear(config.hidden_size, config.hidden_size)\n        self.norm = Qwen3RMSNorm(config.hidden_size, eps=config.rms_norm_eps)\n        self.rotary_emb = Qwen3RotaryEmbedding(config=config)\n        self.gradient_checkpointing = False\n        # Special token used for pooling (CLS-like token)\n        self.special_token = nn.Parameter(torch.randn(1, 1, config.hidden_size) * 0.02)\n        self.layers = nn.ModuleList(\n            [AceStepEncoderLayer(config, layer_idx) for layer_idx in range(config.num_attention_pooler_hidden_layers)]\n        )\n\n        # Initialize weights and apply final processing\n        self.post_init()\n\n    @can_return_tuple\n    def forward(self,\n        x,\n        attention_mask: Optional[torch.Tensor] = None,\n        **flash_attn_kwargs: Unpack[FlashAttentionKwargs],\n    ) -> BaseModelOutput:\n        B, T, P, D = x.shape\n        x = self.embed_tokens(x)\n        special_tokens = self.special_token.expand(B, T, 1, -1)\n        x = torch.cat([special_tokens, x], dim=2)\n        x = rearrange(x, \"b t p c -> (b t) p c\")\n\n        # Cache position: only used for mask construction.\n        cache_position = torch.arange(0, x.shape[1], device=x.device)\n        # Postional ids.\n        position_ids = cache_position.unsqueeze(0)\n\n        # embed positions\n        hidden_states = x\n\n        # create position embeddings to be shared across the decoder layers\n        position_embeddings = self.rotary_emb(hidden_states, position_ids)\n\n        seq_len = x.shape[1]\n        dtype = x.dtype\n        device = x.device\n\n        # 判断是否使用 Flash Attention 2\n        is_flash_attn = (self.config._attn_implementation == \"flash_attention_2\")\n\n        # 初始化 Mask 变量\n        full_attn_mask = None\n        sliding_attn_mask = None\n\n        if is_flash_attn:\n            # -------------------------------------------------------\n            # 场景 A: Flash Attention 模式\n            # -------------------------------------------------------\n            # FA 不需要 4D Mask。\n            # 如果有 padding mask (attention_mask [B, L])，直接传给它即可。\n            # 如果没有 padding mask，传 None。\n            # 滑动窗口逻辑由 Layer 内部传给 FA kernel 的 sliding_window 参数控制。\n            full_attn_mask = attention_mask\n\n            # 这里的逻辑是：如果配置启用了滑动窗口，FA 模式下我们也只需要传基础的 padding mask\n            # Layer 会自己决定是否调用带 sliding window 的 kernel\n            sliding_attn_mask = attention_mask if self.config.use_sliding_window else None\n\n        else:\n            # -------------------------------------------------------\n            # 场景 B: CPU / Mac / SDPA (Eager 模式)\n            # -------------------------------------------------------\n            # 必须手动生成 4D Mask [B, 1, L, L]\n\n            # 1. Full Attention (Bidirectional, Global)\n            # 对应原来的 create_causal_mask + bidirectional\n            full_attn_mask = create_4d_mask(\n                seq_len=seq_len,\n                dtype=dtype,\n                device=device,\n                attention_mask=attention_mask,     # [B, L]\n                sliding_window=None,\n                is_sliding_window=False,\n                is_causal=False                    # <--- 关键：双向注意力\n            )\n\n            # 2. Sliding Attention (Bidirectional, Local)\n            # 对应原来的 create_sliding_window... + bidirectional\n            if self.config.use_sliding_window:\n                sliding_attn_mask = create_4d_mask(\n                    seq_len=seq_len,\n                    dtype=dtype,\n                    device=device,\n                    attention_mask=attention_mask, # [B, L]\n                    sliding_window=self.config.sliding_window,\n                    is_sliding_window=True,        # <--- 开启滑动窗口\n                    is_causal=False                # <--- 关键：双向注意力\n                )\n\n        # 构建 Mapping\n        self_attn_mask_mapping = {\n            \"full_attention\": full_attn_mask,\n            \"sliding_attention\": sliding_attn_mask,\n        }\n\n        for layer_module in self.layers:\n            layer_outputs = layer_module(\n                hidden_states,\n                position_embeddings,\n                attention_mask=self_attn_mask_mapping[layer_module.attention_type],\n                **flash_attn_kwargs,\n            )\n\n            hidden_states = layer_outputs[0]\n\n        hidden_states = self.norm(hidden_states)\n\n        # Extract the special token output (first position) as pooled representation\n        cls_output = hidden_states[:, 0, :]\n        cls_output = rearrange(cls_output, \"(b t) c -> b t c\", b=B)\n        return cls_output\n\n\nclass AudioTokenDetokenizer(AceStepPreTrainedModel):\n    \"\"\"\n    Audio token detokenizer module.\n\n    Converts quantized audio tokens back to continuous acoustic representations.\n    Expands each token into multiple patches using special tokens, processes them\n    through encoder layers, and projects to acoustic hidden dimension.\n    \"\"\"\n    def __init__(self, config):\n        super().__init__(config)\n        self.config = config\n        self.embed_tokens = nn.Linear(config.hidden_size, config.hidden_size)\n        self.norm = Qwen3RMSNorm(config.hidden_size, eps=config.rms_norm_eps)\n        self.rotary_emb = Qwen3RotaryEmbedding(config=config)\n        self.gradient_checkpointing = False\n        # Special tokens for expanding each quantized token into patches\n        self.special_tokens = nn.Parameter(torch.randn(1, config.pool_window_size, config.hidden_size) * 0.02)\n        self.layers = nn.ModuleList(\n            [AceStepEncoderLayer(config, layer_idx) for layer_idx in range(config.num_attention_pooler_hidden_layers)]\n        )\n        # Project back to acoustic hidden dimension\n        self.proj_out = nn.Linear(config.hidden_size, config.audio_acoustic_hidden_dim)\n\n        # Initialize weights and apply final processing\n        self.post_init()\n\n    @can_return_tuple\n    def forward(self,\n        x,\n        attention_mask: Optional[torch.Tensor] = None,\n        **flash_attn_kwargs: Unpack[FlashAttentionKwargs],\n    ) -> BaseModelOutput:\n        B, T, D = x.shape\n        x = self.embed_tokens(x)\n        # Expand and add special tokens: N x T x D -> N x T x P x D\n        # Each token is expanded into pool_window_size patches\n        x = x.unsqueeze(2)  # N x T x 1 x D\n        x = x.repeat(1, 1, self.config.pool_window_size, 1)  # N x T x P x D\n        # Add learnable special tokens to each patch\n        special_tokens = self.special_tokens.expand(B, T, -1, -1)\n        x = x + special_tokens\n        # Reshape for processing: (batch * time) x patches x hidden\n        x = rearrange(x, \"b t p c -> (b t) p c\")\n\n        # Cache position: only used for mask construction\n        cache_position = torch.arange(0, x.shape[1], device=x.device)\n        # Positional IDs\n        position_ids = cache_position.unsqueeze(0)\n\n        # Initialize hidden states\n        hidden_states = x\n\n        # Create position embeddings to be shared across all layers\n        position_embeddings = self.rotary_emb(hidden_states, position_ids)\n\n        seq_len = x.shape[1]\n        dtype = x.dtype\n        device = x.device\n\n        # 判断是否使用 Flash Attention 2\n        is_flash_attn = (self.config._attn_implementation == \"flash_attention_2\")\n\n        # 初始化 Mask 变量\n        full_attn_mask = None\n        sliding_attn_mask = None\n\n        if is_flash_attn:\n            # -------------------------------------------------------\n            # 场景 A: Flash Attention 模式\n            # -------------------------------------------------------\n            # FA 不需要 4D Mask。\n            # 如果有 padding mask (attention_mask [B, L])，直接传给它即可。\n            # 如果没有 padding mask，传 None。\n            # 滑动窗口逻辑由 Layer 内部传给 FA kernel 的 sliding_window 参数控制。\n            full_attn_mask = attention_mask\n\n            # 这里的逻辑是：如果配置启用了滑动窗口，FA 模式下我们也只需要传基础的 padding mask\n            # Layer 会自己决定是否调用带 sliding window 的 kernel\n            sliding_attn_mask = attention_mask if self.config.use_sliding_window else None\n\n        else:\n            # -------------------------------------------------------\n            # 场景 B: CPU / Mac / SDPA (Eager 模式)\n            # -------------------------------------------------------\n            # 必须手动生成 4D Mask [B, 1, L, L]\n\n            # 1. Full Attention (Bidirectional, Global)\n            # 对应原来的 create_causal_mask + bidirectional\n            full_attn_mask = create_4d_mask(\n                seq_len=seq_len,\n                dtype=dtype,\n                device=device,\n                attention_mask=attention_mask,     # [B, L]\n                sliding_window=None,\n                is_sliding_window=False,\n                is_causal=False                    # <--- 关键：双向注意力\n            )\n\n            # 2. Sliding Attention (Bidirectional, Local)\n            # 对应原来的 create_sliding_window... + bidirectional\n            if self.config.use_sliding_window:\n                sliding_attn_mask = create_4d_mask(\n                    seq_len=seq_len,\n                    dtype=dtype,\n                    device=device,\n                    attention_mask=attention_mask, # [B, L]\n                    sliding_window=self.config.sliding_window,\n                    is_sliding_window=True,        # <--- 开启滑动窗口\n                    is_causal=False                # <--- 关键：双向注意力\n                )\n\n        # 构建 Mapping\n        self_attn_mask_mapping = {\n            \"full_attention\": full_attn_mask,\n            \"sliding_attention\": sliding_attn_mask,\n        }\n\n        for layer_module in self.layers:\n            layer_outputs = layer_module(\n                hidden_states,\n                position_embeddings,\n                attention_mask=self_attn_mask_mapping[layer_module.attention_type],\n                **flash_attn_kwargs,\n            )\n\n            hidden_states = layer_outputs[0]\n\n        hidden_states = self.norm(hidden_states)\n\n        hidden_states = self.proj_out(hidden_states)\n\n        hidden_states = rearrange(hidden_states, \"(b t) p c -> b (t p) c\", b=B, p=self.config.pool_window_size)\n        return hidden_states\n\n\nclass AceStepTimbreEncoder(AceStepPreTrainedModel):\n    \"\"\"\n    Encoder for extracting timbre embeddings from reference audio.\n\n    Processes packed reference audio acoustic features to extract timbre\n    representations. Uses a special token (CLS-like) to aggregate information\n    from the entire reference audio sequence. Outputs are unpacked back to\n    batch format for use in conditioning.\n    \"\"\"\n    def __init__(self, config):\n        super().__init__(config)\n\n        # Project acoustic features to model hidden size\n        self.embed_tokens = nn.Linear(config.timbre_hidden_dim, config.hidden_size)\n        self.norm = Qwen3RMSNorm(config.hidden_size, eps=config.rms_norm_eps)\n        self.rotary_emb = Qwen3RotaryEmbedding(config=config)\n        self.gradient_checkpointing = False\n        # Special token for aggregating timbre information (prepended to sequence)\n        self.special_token = nn.Parameter(torch.randn(1, 1, config.hidden_size))\n        self.layers = nn.ModuleList(\n            [AceStepEncoderLayer(config, layer_idx) for layer_idx in range(config.num_timbre_encoder_hidden_layers)]\n        )\n\n        # Initialize weights and apply final processing\n        self.post_init()\n\n    def unpack_timbre_embeddings(self, timbre_embs_packed, refer_audio_order_mask):\n        \"\"\"\n        Unpack packed timbre embeddings into batch format.\n\n        Args:\n            timbre_embs_packed: Packed timbre embeddings of shape [N, d]\n            refer_audio_order_mask: Order mask indicating batch assignment for each packed embedding\n\n        Returns:\n            Tuple of (unpacked_embeddings, mask):\n            - unpacked_embeddings: Unpacked embeddings of shape [B, max_count, d]\n            - new_mask: Mask indicating valid positions, shape [B, max_count]\n        \"\"\"\n        N, d = timbre_embs_packed.shape\n        device = timbre_embs_packed.device\n        dtype = timbre_embs_packed.dtype\n\n        # Get batch size\n        B = int(refer_audio_order_mask.max().item() + 1)\n\n        # Calculate element count and positions for each batch\n        counts = torch.bincount(refer_audio_order_mask, minlength=B)\n        max_count = counts.max().item()\n\n        # Calculate positions within batch\n        sorted_indices = torch.argsort(refer_audio_order_mask * N + torch.arange(N, device=device), stable=True)\n        sorted_batch_ids = refer_audio_order_mask[sorted_indices]\n\n        positions = torch.arange(N, device=device)\n        batch_starts = torch.cat([torch.tensor([0], device=device),\n                                torch.cumsum(counts, dim=0)[:-1]])\n        positions_in_sorted = positions - batch_starts[sorted_batch_ids]\n\n        inverse_indices = torch.empty_like(sorted_indices)\n        inverse_indices[sorted_indices] = torch.arange(N, device=device)\n        positions_in_batch = positions_in_sorted[inverse_indices]\n\n        # Use one-hot encoding and matrix multiplication (gradient-friendly approach)\n        # Create one-hot encoding\n        indices_2d = refer_audio_order_mask * max_count + positions_in_batch  # (N,)\n        one_hot = F.one_hot(indices_2d, num_classes=B * max_count).to(dtype)  # (N, B*max_count)\n\n        # Rearrange using matrix multiplication\n        timbre_embs_flat = one_hot.t() @ timbre_embs_packed  # (B*max_count, d)\n        timbre_embs_unpack = timbre_embs_flat.reshape(B, max_count, d)\n\n        # Create mask indicating valid positions\n        mask_flat = (one_hot.sum(dim=0) > 0).long()  # (B*max_count,)\n        new_mask = mask_flat.reshape(B, max_count)\n\n        return timbre_embs_unpack, new_mask\n\n    @can_return_tuple\n    def forward(\n        self,\n        refer_audio_acoustic_hidden_states_packed: Optional[torch.FloatTensor] = None,\n        refer_audio_order_mask: Optional[torch.LongTensor] = None,\n        attention_mask: Optional[torch.Tensor] = None,\n        **flash_attn_kwargs: Unpack[FlashAttentionKwargs],\n    ) -> BaseModelOutput:\n        inputs_embeds = refer_audio_acoustic_hidden_states_packed\n        # Project embeddings: N x T x timbre_hidden_dim -> N x T x hidden_size\n        inputs_embeds = self.embed_tokens(inputs_embeds)\n        # Prepend special token for timbre aggregation (CLS-like token)\n        # inputs_embeds = torch.cat([self.special_token.expand(inputs_embeds.shape[0], 1, -1), inputs_embeds], dim=1)\n        # Cache position: only used for mask construction (not for actual caching)\n        cache_position = torch.arange(0, inputs_embeds.shape[1], device=inputs_embeds.device)\n        # Positional IDs\n        position_ids = cache_position.unsqueeze(0)\n\n        seq_len = inputs_embeds.shape[1]\n        dtype = inputs_embeds.dtype\n        device = inputs_embeds.device\n\n        # 判断是否使用 Flash Attention 2\n        is_flash_attn = (self.config._attn_implementation == \"flash_attention_2\")\n\n        # 初始化 Mask 变量\n        full_attn_mask = None\n        sliding_attn_mask = None\n\n        if is_flash_attn:\n            # -------------------------------------------------------\n            # 场景 A: Flash Attention 模式\n            # -------------------------------------------------------\n            # FA 不需要 4D Mask。\n            # 如果有 padding mask (attention_mask [B, L])，直接传给它即可。\n            # 如果没有 padding mask，传 None。\n            # 滑动窗口逻辑由 Layer 内部传给 FA kernel 的 sliding_window 参数控制。\n            full_attn_mask = attention_mask\n\n            # 这里的逻辑是：如果配置启用了滑动窗口，FA 模式下我们也只需要传基础的 padding mask\n            # Layer 会自己决定是否调用带 sliding window 的 kernel\n            sliding_attn_mask = attention_mask if self.config.use_sliding_window else None\n\n        else:\n            # -------------------------------------------------------\n            # 场景 B: CPU / Mac / SDPA (Eager 模式)\n            # -------------------------------------------------------\n            # 必须手动生成 4D Mask [B, 1, L, L]\n\n            # 1. Full Attention (Bidirectional, Global)\n            # 对应原来的 create_causal_mask + bidirectional\n            full_attn_mask = create_4d_mask(\n                seq_len=seq_len,\n                dtype=dtype,\n                device=device,\n                attention_mask=attention_mask,     # [B, L]\n                sliding_window=None,\n                is_sliding_window=False,\n                is_causal=False                    # <--- 关键：双向注意力\n            )\n\n            # 2. Sliding Attention (Bidirectional, Local)\n            # 对应原来的 create_sliding_window... + bidirectional\n            if self.config.use_sliding_window:\n                sliding_attn_mask = create_4d_mask(\n                    seq_len=seq_len,\n                    dtype=dtype,\n                    device=device,\n                    attention_mask=attention_mask, # [B, L]\n                    sliding_window=self.config.sliding_window,\n                    is_sliding_window=True,        # <--- 开启滑动窗口\n                    is_causal=False                # <--- 关键：双向注意力\n                )\n\n        # 构建 Mapping\n        self_attn_mask_mapping = {\n            \"full_attention\": full_attn_mask,\n            \"sliding_attention\": sliding_attn_mask,\n        }\n\n        # Initialize hidden states\n        hidden_states = inputs_embeds\n\n        # Create position embeddings to be shared across all layers\n        position_embeddings = self.rotary_emb(hidden_states, position_ids)\n\n        # Pass through transformer layers\n        for layer_module in self.layers[: self.config.num_hidden_layers]:\n            layer_outputs = layer_module(\n                hidden_states,\n                position_embeddings,\n                self_attn_mask_mapping[layer_module.attention_type],\n                position_ids,\n                **flash_attn_kwargs,\n            )\n\n            hidden_states = layer_outputs[0]\n\n        hidden_states = self.norm(hidden_states)\n        # Extract special token output (first position) as timbre embedding: N x T x D -> N x D\n        hidden_states = hidden_states[:, 0, :]\n        # Unpack packed embeddings back to batch format\n        timbre_embs_unpack, timbre_embs_mask = self.unpack_timbre_embeddings(hidden_states, refer_audio_order_mask)\n        return timbre_embs_unpack, timbre_embs_mask\n\n\nclass AceStepAudioTokenizer(AceStepPreTrainedModel):\n    \"\"\"\n    Audio tokenizer module.\n\n    Converts continuous acoustic features into discrete quantized tokens.\n    Process: project -> pool patches -> quantize. Used for converting audio\n    representations into discrete tokens for processing by the diffusion model.\n    \"\"\"\n    def __init__(self, config):\n        super().__init__(config)\n        # Project acoustic features to hidden size\n        self.audio_acoustic_proj = nn.Linear(config.audio_acoustic_hidden_dim, config.hidden_size)\n        # Pool patches into sequence-level representations\n        self.attention_pooler = AttentionPooler(config)\n        # Quantize continuous representations into discrete tokens\n        self.quantizer = ResidualFSQ(\n            dim=config.fsq_dim,\n            levels=config.fsq_input_levels,\n            num_quantizers=config.fsq_input_num_quantizers\n        )\n        self.pool_window_size = config.pool_window_size\n        # Initialize weights and apply final processing\n        self.post_init()\n\n    @can_return_tuple\n    def forward(\n        self,\n        hidden_states: Optional[torch.FloatTensor] = None,\n        **flash_attn_kwargs: Unpack[FlashAttentionKwargs],\n    ) -> BaseModelOutput:\n\n        # Project acoustic features to hidden size\n        hidden_states = self.audio_acoustic_proj(hidden_states)\n        # Pool sequences: N x T//pool_window_size x pool_window_size x d -> N x T//pool_window_size x d\n        hidden_states = self.attention_pooler(hidden_states)\n        # Quantize continuous representations into discrete tokens: N x T//pool_window_size x d\n        quantized, indices = self.quantizer(hidden_states)\n        return quantized, indices\n\n    def tokenize(self, x):\n        x = rearrange(x, 'n (t_patch p) d -> n t_patch p d', p=self.pool_window_size)\n        quantized, indices = self.forward(x)\n        return quantized, indices\n\nclass Lambda(nn.Module):\n    \"\"\"\n    Wrapper module for arbitrary lambda functions.\n\n    Allows using lambda functions in nn.Sequential by wrapping them in a Module.\n    Useful for simple transformations like transpose operations.\n    \"\"\"\n    def __init__(self, func):\n        super().__init__()\n        self.func = func\n\n    def forward(self, x):\n        return self.func(x)\n\n\nclass AceStepDiTModel(AceStepPreTrainedModel):\n    \"\"\"\n    DiT (Diffusion Transformer) model for AceStep.\n\n    Main diffusion model that generates audio latents conditioned on text, lyrics,\n    and timbre. Uses patch-based processing with transformer layers, timestep\n    conditioning, and cross-attention to encoder outputs.\n    \"\"\"\n    def __init__(self, config: AceStepConfig):\n        super().__init__(config)\n        # Rotary position embeddings for transformer layers\n        self.rotary_emb = Qwen3RotaryEmbedding(config)\n        # Stack of DiT transformer layers\n        self.layers = nn.ModuleList(\n            [AceStepDiTLayer(config, layer_idx) for layer_idx in range(config.num_hidden_layers)]\n        )\n\n        in_channels = config.in_channels\n        inner_dim = config.hidden_size\n        patch_size = config.patch_size\n        self.patch_size = patch_size\n\n        # Input projection: patch embedding using 1D convolution\n        # Converts sequence into patches for efficient processing\n        self.proj_in = nn.Sequential(\n            Lambda(lambda x: x.transpose(1, 2)),  # [B, T, C] -> [B, C, T]\n            nn.Conv1d(\n                in_channels=in_channels,\n                out_channels=inner_dim,\n                kernel_size=patch_size,\n                stride=patch_size,\n                padding=0,\n            ),\n            Lambda(lambda x: x.transpose(1, 2)),  # [B, C, T//patch_size] -> [B, T//patch_size, C]\n        )\n\n        # Timestep embeddings for diffusion conditioning\n        # Two embeddings: one for timestep t, one for timestep difference (t - r)\n        self.time_embed = TimestepEmbedding(in_channels=256, time_embed_dim=inner_dim)\n        self.time_embed_r = TimestepEmbedding(in_channels=256, time_embed_dim=inner_dim)\n\n        # Project encoder hidden states to model dimension\n        self.condition_embedder = nn.Linear(inner_dim, inner_dim, bias=True)\n\n        # Output normalization and projection\n        # Adaptive layer norm with scale-shift modulation, then de-patchify\n        self.norm_out = Qwen3RMSNorm(inner_dim, eps=config.rms_norm_eps)\n        self.proj_out = nn.Sequential(\n            Lambda(lambda x: x.transpose(1, 2)),  # [B, T//patch_size, inner_dim] -> [B, inner_dim, T//patch_size]\n            nn.ConvTranspose1d(\n                in_channels=inner_dim,\n                out_channels=config.audio_acoustic_hidden_dim,\n                kernel_size=patch_size,\n                stride=patch_size,\n                padding=0,\n            ),\n            Lambda(lambda x: x.transpose(1, 2)),  # [B, out_channels, T] -> [B, T, out_channels]\n        )\n        # Scale-shift table for adaptive output normalization (2 values: shift, scale)\n        self.scale_shift_table = nn.Parameter(torch.randn(1, 2, inner_dim) / inner_dim**0.5)\n\n        self.gradient_checkpointing = False\n\n    def forward(\n        self,\n        hidden_states: torch.Tensor,\n        timestep: torch.Tensor,\n        timestep_r: torch.Tensor,\n        attention_mask: torch.Tensor,\n        encoder_hidden_states: torch.Tensor,\n        encoder_attention_mask: torch.Tensor,\n        context_latents: torch.Tensor,\n        use_cache: Optional[bool] = None,\n        past_key_values: Optional[EncoderDecoderCache] = None,\n        cache_position: Optional[torch.LongTensor] = None,\n        position_ids: Optional[torch.LongTensor] = None,\n        output_attentions: Optional[bool] = False,\n        return_hidden_states: int = None,\n        custom_layers_config: Optional[dict] = None,\n        enable_early_exit: bool = False,\n        **flash_attn_kwargs: Unpack[FlashAttentionKwargs],\n    ):\n\n        use_cache = use_cache if use_cache is not None else self.config.use_cache\n\n        # Disable cache during training or when gradient checkpointing is enabled\n        if self.gradient_checkpointing and self.training and use_cache:\n            logger.warning_once(\n                \"`use_cache=True` is incompatible with gradient checkpointing. Setting `use_cache=False`.\"\n            )\n            use_cache = False\n        if self.training:\n            use_cache = False\n\n        # Initialize cache if needed (only during inference for auto-regressive generation)\n        if not self.training and use_cache and past_key_values is None:\n            past_key_values = EncoderDecoderCache(DynamicCache(), DynamicCache())\n\n        # Compute timestep embeddings for diffusion conditioning\n        # Two embeddings: one for timestep t, one for timestep difference (t - r)\n        temb_t, timestep_proj_t = self.time_embed(timestep)\n        temb_r, timestep_proj_r = self.time_embed_r(timestep - timestep_r)\n        # Combine embeddings\n        temb = temb_t + temb_r\n        timestep_proj = timestep_proj_t + timestep_proj_r\n\n        # Concatenate context latents (source latents + chunk masks) with hidden states\n        hidden_states = torch.cat([context_latents, hidden_states], dim=-1)\n        # Record original sequence length for later restoration after padding\n        original_seq_len = hidden_states.shape[1]\n        # Apply padding if sequence length is not divisible by patch_size\n        # This ensures proper patch extraction\n        pad_length = 0\n        if hidden_states.shape[1] % self.patch_size != 0:\n            pad_length = self.patch_size - (hidden_states.shape[1] % self.patch_size)\n            hidden_states = F.pad(hidden_states, (0, 0, 0, pad_length), mode='constant', value=0)\n\n        # Project input to patches and project encoder states\n        hidden_states = self.proj_in(hidden_states)\n        encoder_hidden_states = self.condition_embedder(encoder_hidden_states)\n\n        # Cache positions\n        if cache_position is None:\n            past_seen_tokens = past_key_values.get_seq_length() if past_key_values is not None else 0\n            cache_position = torch.arange(\n                past_seen_tokens, past_seen_tokens + hidden_states.shape[1], device=hidden_states.device\n            )\n\n        # Position IDs\n        if position_ids is None:\n            position_ids = cache_position.unsqueeze(0)\n\n\n        seq_len = hidden_states.shape[1]\n        encoder_seq_len = encoder_hidden_states.shape[1]\n        dtype = hidden_states.dtype\n        device = hidden_states.device\n\n        # 判断是否使用 Flash Attention 2\n        is_flash_attn = (self.config._attn_implementation == \"flash_attention_2\")\n\n        # 初始化 Mask 变量\n        full_attn_mask = None\n        sliding_attn_mask = None\n        encoder_attention_mask = None\n        attention_mask = None\n        if is_flash_attn:\n            # -------------------------------------------------------\n            # 场景 A: Flash Attention 模式\n            # -------------------------------------------------------\n            # FA 不需要 4D Mask。\n            # 如果有 padding mask (attention_mask [B, L])，直接传给它即可。\n            # 如果没有 padding mask，传 None。\n            # 滑动窗口逻辑由 Layer 内部传给 FA kernel 的 sliding_window 参数控制。\n            full_attn_mask = attention_mask\n\n            # 这里的逻辑是：如果配置启用了滑动窗口，FA 模式下我们也只需要传基础的 padding mask\n            # Layer 会自己决定是否调用带 sliding window 的 kernel\n            sliding_attn_mask = attention_mask if self.config.use_sliding_window else None\n\n        else:\n            # -------------------------------------------------------\n            # 场景 B: CPU / Mac / SDPA (Eager 模式)\n            # -------------------------------------------------------\n            # 必须手动生成 4D Mask [B, 1, L, L]\n\n            # 1. Full Attention (Bidirectional, Global)\n            # 对应原来的 create_causal_mask + bidirectional\n            full_attn_mask = create_4d_mask(\n                seq_len=seq_len,\n                dtype=dtype,\n                device=device,\n                attention_mask=attention_mask,     # [B, L]\n                sliding_window=None,\n                is_sliding_window=False,\n                is_causal=False                    # <--- 关键：双向注意力\n            )\n            max_len = max(seq_len, encoder_seq_len)\n\n            encoder_attention_mask = create_4d_mask(\n                seq_len=max_len,\n                dtype=dtype,\n                device=device,\n                attention_mask=attention_mask,     # [B, L]\n                sliding_window=None,\n                is_sliding_window=False,\n                is_causal=False                    # <--- 关键：双向注意力\n            )\n            encoder_attention_mask = encoder_attention_mask[:, :, :seq_len, :encoder_seq_len]\n            # 2. Sliding Attention (Bidirectional, Local)\n            # 对应原来的 create_sliding_window... + bidirectional\n            if self.config.use_sliding_window:\n                sliding_attn_mask = create_4d_mask(\n                    seq_len=seq_len,\n                    dtype=dtype,\n                    device=device,\n                    attention_mask=attention_mask, # [B, L]\n                    sliding_window=self.config.sliding_window,\n                    is_sliding_window=True,        # <--- 开启滑动窗口\n                    is_causal=False                # <--- 关键：双向注意力\n                )\n\n        # 构建 Mapping\n        self_attn_mask_mapping = {\n            \"full_attention\": full_attn_mask,\n            \"sliding_attention\": sliding_attn_mask,\n            \"encoder_attention_mask\": encoder_attention_mask,\n        }\n\n        # Create position embeddings to be shared across all decoder layers\n        position_embeddings = self.rotary_emb(hidden_states, position_ids)\n        all_cross_attentions = () if output_attentions else None\n\n        # Handle early exit for custom layer configurations\n        max_needed_layer = float('inf')\n        if custom_layers_config is not None and enable_early_exit:\n            max_needed_layer = max(custom_layers_config.keys())\n            # Force output_attentions to True when early exit is enabled for attention extraction\n            output_attentions = True\n            if all_cross_attentions is None:\n                all_cross_attentions = ()\n\n        # Process through transformer layers\n        for index_block, layer_module in enumerate(self.layers):\n\n            layer_outputs = layer_module(\n                hidden_states,\n                position_embeddings,\n                timestep_proj,\n                self_attn_mask_mapping[layer_module.attention_type],\n                position_ids,\n                past_key_values,\n                output_attentions,\n                use_cache,\n                cache_position,\n                encoder_hidden_states,\n                self_attn_mask_mapping[\"encoder_attention_mask\"],\n                **flash_attn_kwargs,\n            )\n            hidden_states = layer_outputs[0]\n\n            if output_attentions and self.layers[index_block].use_cross_attention:\n                # layer_outputs structure: (hidden_states, self_attn_weights, cross_attn_weights)\n                # Extract the last element which is cross_attn_weights\n                if len(layer_outputs) >= 3:\n                    all_cross_attentions += (layer_outputs[2],)\n\n        if return_hidden_states:\n            return hidden_states\n\n        # Extract scale-shift parameters for adaptive output normalization\n        shift, scale = (self.scale_shift_table + temb.unsqueeze(1)).chunk(2, dim=1)\n        shift = shift.to(hidden_states.device)\n        scale = scale.to(hidden_states.device)\n\n        # Apply adaptive layer norm: norm(x) * (1 + scale) + shift\n        hidden_states = (self.norm_out(hidden_states) * (1 + scale) + shift).type_as(hidden_states)\n        # Project output: de-patchify back to original sequence format\n        hidden_states = self.proj_out(hidden_states)\n\n        # Crop back to original sequence length to ensure exact length match (remove padding)\n        hidden_states = hidden_states[:, :original_seq_len, :]\n\n        outputs = (hidden_states, past_key_values)\n\n        if output_attentions:\n            outputs += (all_cross_attentions,)\n        return outputs\n\nclass AceStepConditionEncoder(AceStepPreTrainedModel):\n    \"\"\"\n    Condition encoder for AceStep model.\n\n    Encodes multiple conditioning inputs (text, lyrics, timbre) and packs them\n    into a single sequence for cross-attention in the diffusion model. Handles\n    projection, encoding, and sequence packing.\n    \"\"\"\n    def __init__(self, config: AceStepConfig):\n        super().__init__(config)\n        self.config = config\n        # Project text embeddings to model hidden size\n        self.text_projector = nn.Linear(config.text_hidden_dim, config.hidden_size, bias=False)\n        # Encoder for lyric text\n        self.lyric_encoder = AceStepLyricEncoder(config)\n        # Encoder for timbre from reference audio\n        self.timbre_encoder = AceStepTimbreEncoder(config)\n\n    def forward(\n        self,\n        # Text inputs\n        text_hidden_states: Optional[torch.FloatTensor] = None,\n        text_attention_mask: Optional[torch.Tensor] = None,\n        # Lyric inputs\n        lyric_hidden_states: Optional[torch.LongTensor] = None,\n        lyric_attention_mask: Optional[torch.Tensor] = None,\n        # Reference audio for timbre\n        refer_audio_acoustic_hidden_states_packed: Optional[torch.Tensor] = None,\n        refer_audio_order_mask: Optional[torch.LongTensor] = None,\n    ):\n        # Project and encode text\n        text_hidden_states = self.text_projector(text_hidden_states)\n        # Encode lyrics\n        lyric_encoder_outputs = self.lyric_encoder(\n            inputs_embeds=lyric_hidden_states,\n            attention_mask=lyric_attention_mask,\n        )\n        lyric_hidden_states = lyric_encoder_outputs.last_hidden_state\n        # Encode timbre from reference audio\n        timbre_embs_unpack, timbre_embs_mask = self.timbre_encoder(refer_audio_acoustic_hidden_states_packed, refer_audio_order_mask)\n\n        # Pack sequences: combine lyrics and timbre, then add text\n        # This creates a single sequence with all conditioning information\n        encoder_hidden_states, encoder_attention_mask = pack_sequences(lyric_hidden_states, timbre_embs_unpack, lyric_attention_mask, timbre_embs_mask)\n        encoder_hidden_states, encoder_attention_mask = pack_sequences(encoder_hidden_states, text_hidden_states, encoder_attention_mask, text_attention_mask)\n        return encoder_hidden_states, encoder_attention_mask\n\n\ndef _repaint_step_injection(xt, clean_src, mask, t_next, noise):\n    \"\"\"Replace non-repaint regions of *xt* with noised source latents.\"\"\"\n    zt = t_next * noise + (1.0 - t_next) * clean_src\n    m = mask.unsqueeze(-1).expand_as(xt)\n    return torch.where(m, xt, zt)\n\n\ndef _repaint_boundary_blend(x_gen, clean_src, mask, cf_frames):\n    \"\"\"Blend generated latents with source at repaint boundaries.\"\"\"\n    soft = mask.float().clone()\n    if cf_frames <= 0:\n        m = soft.unsqueeze(-1).expand_as(x_gen)\n        return m * x_gen + (1.0 - m) * clean_src\n    B, T = mask.shape\n    for b in range(B):\n        row = mask[b]\n        if row.all() or not row.any():\n            continue\n        idx = torch.nonzero(row, as_tuple=False).squeeze(-1)\n        if idx.numel() == 0:\n            continue\n        left, right = idx[0].item(), idx[-1].item() + 1\n        fs = max(left - cf_frames, 0)\n        if left - fs > 0:\n            soft[b, fs:left] = torch.linspace(0, 1, left - fs + 2, device=soft.device)[1:-1]\n        fe = min(right + cf_frames, T)\n        if fe - right > 0:\n            soft[b, right:fe] = torch.linspace(1, 0, fe - right + 2, device=soft.device)[1:-1]\n    m = soft.unsqueeze(-1).expand_as(x_gen)\n    return m * x_gen + (1.0 - m) * clean_src\n\n\nclass AceStepConditionGenerationModel(AceStepPreTrainedModel):\n    \"\"\"\n    Main conditional generation model for AceStep.\n\n    End-to-end model for generating audio conditioned on text, lyrics, and timbre.\n    Combines encoder (for conditioning), decoder (diffusion model), tokenizer\n    (for discrete tokenization), and detokenizer (for reconstruction).\n    Supports flow matching training and inference with various sampling methods.\n    \"\"\"\n    def __init__(self, config: AceStepConfig):\n        super().__init__(config)\n        self.config = config\n        # Diffusion model components\n        self.decoder = AceStepDiTModel(config)  # Main diffusion transformer\n        self.encoder = AceStepConditionEncoder(config)  # Condition encoder\n        self.tokenizer = AceStepAudioTokenizer(config)  # Audio tokenizer\n        self.detokenizer = AudioTokenDetokenizer(config)  # Audio detokenizer\n        # Null condition embedding for classifier-free guidance\n        self.null_condition_emb = nn.Parameter(torch.randn(1, 1, config.hidden_size))\n\n        # Initialize weights and apply final processing\n        self.post_init()\n\n    def tokenize(self, x, silence_latent, attention_mask):\n        if x.shape[1] % self.config.pool_window_size != 0:\n            pad_len = self.config.pool_window_size - (x.shape[1] % self.config.pool_window_size)\n            x = torch.cat([x,  silence_latent[:1,:pad_len].repeat(x.shape[0],1,1)], dim=1)\n            attention_mask = F.pad(attention_mask, (0, pad_len), mode='constant', value=0)\n        x = rearrange(x, 'n (t_patch p) d -> n t_patch p d', p=self.config.pool_window_size)\n        seq_len = x.shape[1]\n        chunk = math.ceil(attention_mask.shape[1] / seq_len)\n        attention_mask = attention_mask.to(x.dtype)\n        attention_mask = F.max_pool1d(attention_mask.unsqueeze(1), kernel_size=chunk, stride=chunk, ceil_mode=True).squeeze(1)\n        quantized, indices = self.tokenizer(x)\n        return quantized, indices, attention_mask\n\n    def detokenize(self, quantized):\n        \"\"\"\n        Detokenize quantized audio tokens back to continuous representations.\n\n        Args:\n            quantized: Quantized tokens of shape [N, T//pool_window_size, d]\n\n        Returns:\n            Detokenized hidden states of shape [N, T, d]\n        \"\"\"\n        hidden_states = self.detokenizer(quantized)\n        return hidden_states\n\n    @torch.no_grad()\n    def prepare_condition(\n        self,\n        text_hidden_states: torch.FloatTensor,\n        text_attention_mask: torch.Tensor,\n        lyric_hidden_states: torch.FloatTensor,\n        lyric_attention_mask: torch.Tensor,\n        refer_audio_acoustic_hidden_states_packed: torch.FloatTensor,\n        refer_audio_order_mask: torch.Tensor,\n        hidden_states: torch.FloatTensor,\n        attention_mask: torch.Tensor,\n        silence_latent: torch.FloatTensor,\n        src_latents: torch.FloatTensor,\n        chunk_masks: torch.Tensor,\n        is_covers: torch.Tensor,\n        precomputed_lm_hints_25Hz: Optional[torch.FloatTensor] = None,\n        audio_codes: torch.FloatTensor = None,\n    ):\n\n        dtype = hidden_states.dtype\n        encoder_hidden_states, encoder_attention_mask = self.encoder(\n            text_hidden_states=text_hidden_states,\n            text_attention_mask=text_attention_mask,\n            lyric_hidden_states=lyric_hidden_states,\n            lyric_attention_mask=lyric_attention_mask,\n            refer_audio_acoustic_hidden_states_packed=refer_audio_acoustic_hidden_states_packed,\n            refer_audio_order_mask=refer_audio_order_mask,\n        )\n\n        # N x T x d -> N x T//pool_window_size x pool_window_size x d\n        # tokenize and detokenize to get LM hints for cover songs (when is_covers=True)\n        # Use precomputed hints if provided (e.g., from audio codes), otherwise tokenize hidden_states\n        if precomputed_lm_hints_25Hz is not None:\n            print(\"Using precomputed LM hints\")\n            lm_hints_25Hz = precomputed_lm_hints_25Hz[:, :src_latents.shape[1], :]\n        else:\n            if audio_codes is not None:\n                lm_hints_5Hz = self.tokenize.quantizer.get_output_from_indices(audio_codes)\n            else:\n                lm_hints_5Hz, indices, llm_mask = self.tokenize(hidden_states, silence_latent, attention_mask)\n            lm_hints_25Hz = self.detokenize(lm_hints_5Hz)\n            # Crop lm_hints_25Hz to match src_latents length (tokenize may have added padding)\n            lm_hints_25Hz = lm_hints_25Hz[:, :src_latents.shape[1], :]\n        src_latents = torch.where(is_covers.unsqueeze(-1).unsqueeze(-1) > 0, lm_hints_25Hz, src_latents)\n        # Concatenate source latents with chunk masks as context\n        context_latents = torch.cat([src_latents, chunk_masks.to(dtype)], dim=-1)\n        return encoder_hidden_states, encoder_attention_mask, context_latents\n\n    def forward(\n        self,\n        # Diffusion inputs\n        hidden_states: torch.FloatTensor,\n        attention_mask: torch.Tensor,\n        # Encoder inputs\n        # Text\n        text_hidden_states: Optional[torch.FloatTensor] = None,\n        text_attention_mask: Optional[torch.Tensor] = None,\n        # Lyric\n        lyric_hidden_states: Optional[torch.LongTensor] = None,\n        lyric_attention_mask: Optional[torch.Tensor] = None,\n        # Reference audio for timbre\n        refer_audio_acoustic_hidden_states_packed: Optional[torch.Tensor] = None,\n        refer_audio_order_mask: Optional[torch.LongTensor] = None,\n        src_latents: torch.FloatTensor = None,\n        chunk_masks: torch.FloatTensor = None,\n        is_covers: torch.Tensor = None,\n        silence_latent: torch.FloatTensor = None,\n        cfg_ratio: float = 0.15,\n    ):\n        \"\"\"\n        Forward pass for training (computes training losses).\n        \"\"\"\n        # Prepare conditioning inputs (encoder states, context latents)\n        encoder_hidden_states, encoder_attention_mask, context_latents = self.prepare_condition(\n            text_hidden_states=text_hidden_states,\n            text_attention_mask=text_attention_mask,\n            lyric_hidden_states=lyric_hidden_states,\n            lyric_attention_mask=lyric_attention_mask,\n            refer_audio_acoustic_hidden_states_packed=refer_audio_acoustic_hidden_states_packed,\n            refer_audio_order_mask=refer_audio_order_mask,\n            hidden_states=src_latents,\n            attention_mask=attention_mask,\n            silence_latent=silence_latent,\n            src_latents=src_latents,\n            chunk_masks=chunk_masks,\n            is_covers=is_covers,\n        )\n        bsz, device, dtype = hidden_states.shape[0], hidden_states.device, hidden_states.dtype\n        # Classifier-free guidance: randomly drop conditions with probability cfg_ratio\n        # This helps the model learn to work with and without conditions\n        full_cfg_condition_mask = torch.where(\n            (torch.rand(size=(bsz,), device=device, dtype=dtype) < cfg_ratio),\n            torch.zeros(size=(bsz,), device=device, dtype=dtype),\n            torch.ones(size=(bsz,), device=device, dtype=dtype)\n        ).view(-1, 1, 1)\n        # Replace dropped conditions with null condition embedding\n        encoder_hidden_states = torch.where(full_cfg_condition_mask > 0, encoder_hidden_states, self.null_condition_emb.expand_as(encoder_hidden_states))\n\n        # Flow matching setup: sample noise x1 and interpolate with data x0\n        x1 = torch.randn_like(hidden_states)  # Noise\n        x0 = hidden_states  # Data\n        # Sample timesteps t and r for flow matching\n        t, r = sample_t_r(bsz, device, dtype, self.config.data_proportion, self.config.timestep_mu, self.config.timestep_sigma, use_meanflow=False)\n        t_ = t.unsqueeze(-1).unsqueeze(-1)\n        # Interpolate: x_t = t * x1 + (1 - t) * x0\n        xt = t_ * x1 + (1.0 - t_) * x0\n\n        # Predict flow (velocity) from diffusion model\n        decoder_outputs = self.decoder(\n            hidden_states=xt,\n            timestep=t,\n            timestep_r=t,\n            attention_mask=attention_mask,\n            encoder_hidden_states=encoder_hidden_states,\n            encoder_attention_mask=encoder_attention_mask,\n            context_latents=context_latents,\n        )\n        # Flow matching loss: predict the flow field v = x1 - x0\n        flow = x1 - x0\n        diffusion_loss = F.mse_loss(decoder_outputs[0], flow)\n        return {\n            \"diffusion_loss\": diffusion_loss,\n        }\n\n    def training_losses(self, **kwargs):\n        return self.forward(**kwargs)\n\n    def prepare_noise(self, context_latents: torch.FloatTensor, seed: Union[int, List[int], None] = None):\n        \"\"\"\n        Prepare noise tensor for generation with optional seeding.\n\n        Args:\n            context_latents: Context latents to determine noise shape\n            seed: Can be int, List[int], or None. If None, uses random noise.\n\n        Returns:\n            Noise tensor of appropriate shape\n        \"\"\"\n        bsz = context_latents.shape[0]\n        device = context_latents.device\n        dtype = context_latents.dtype\n        # Handle seed: can be int, List[int], or None\n        src_latents_shape = (context_latents.shape[0], context_latents.shape[1], context_latents.shape[-1] // 2)\n        if seed is None:\n            # No seed provided - use random\n            noise = torch.randn(src_latents_shape, device=device, dtype=dtype)\n        elif isinstance(seed, list):\n            # List of seeds - generate noise for each sample separately\n            noise_list = []\n            for i, s in enumerate(seed):\n                if s is None or s < 0:\n                    # Random seed for this sample\n                    noise_i = torch.randn(1, src_latents_shape[1], src_latents_shape[2], device=device, dtype=dtype)\n                else:\n                    # Use specific seed for this sample\n                    generator = torch.Generator(device=device).manual_seed(int(s))\n                    noise_i = torch.randn(1, src_latents_shape[1], src_latents_shape[2], generator=generator, device=device, dtype=dtype)\n                noise_list.append(noise_i)\n            noise = torch.cat(noise_list, dim=0)\n        else:\n            # Single seed for all samples\n            generator = torch.Generator(device=device).manual_seed(int(seed))\n            noise = torch.randn(src_latents_shape, generator=generator, device=device, dtype=dtype)\n\n        return noise\n\n    def get_x0_from_noise(self, zt, vt, t):\n        if t.shape[0] != zt.shape[0]:\n            raise ValueError(f\"Batch size mismatch: t has {t.shape[0]}, zt has {zt.shape[0]}\")\n\n        return zt - vt * t.unsqueeze(-1).unsqueeze(-1)\n\n    def renoise(self, x, t, noise=None):\n        if noise is None:\n            noise = torch.randn_like(x)\n        if isinstance(t, torch.Tensor) and t.ndim != x.ndim:\n            t = t.unsqueeze(-1).unsqueeze(-1)\n        xt = t * noise + (1 - t) * x\n        return xt\n\n    def generate_audio(\n        self,\n        text_hidden_states: torch.FloatTensor,\n        text_attention_mask: torch.FloatTensor,\n        lyric_hidden_states: torch.FloatTensor,\n        lyric_attention_mask: torch.FloatTensor,\n        refer_audio_acoustic_hidden_states_packed: torch.FloatTensor,\n        refer_audio_order_mask: torch.LongTensor,\n        src_latents: torch.FloatTensor,\n        chunk_masks: torch.FloatTensor,\n        is_covers: torch.Tensor,\n        silence_latent: Optional[torch.FloatTensor] = None,\n        attention_mask: torch.Tensor = None,\n        seed: int = None,\n        infer_method: str = \"ode\",\n        use_cache: bool = True,\n        infer_steps: int = 30,\n        diffusion_guidance_sale: float = 7.0,\n        audio_cover_strength: float = 1.0,\n        non_cover_text_hidden_states: Optional[torch.FloatTensor] = None,\n        non_cover_text_attention_mask: Optional[torch.FloatTensor] = None,\n        cfg_interval_start: float = 0.0,\n        cfg_interval_end: float = 1.0,\n        precomputed_lm_hints_25Hz: Optional[torch.FloatTensor] = None,\n        audio_codes: Optional[torch.FloatTensor] = None,\n        use_progress_bar: bool = True,\n        use_adg: bool = False,\n        shift: float = 1.0,\n        timesteps: Optional[torch.Tensor] = None,\n        cover_noise_strength: float = 0.0,\n        repaint_mask: Optional[torch.Tensor] = None,\n        clean_src_latents: Optional[torch.FloatTensor] = None,\n        repaint_crossfade_frames: int = 10,\n        repaint_injection_ratio: float = 0.5,\n        **kwargs,\n    ):\n        if attention_mask is None:\n            latent_length = src_latents.shape[1]\n            attention_mask = torch.ones(src_latents.shape[0], latent_length, device=src_latents.device, dtype=src_latents.dtype)\n        time_costs = {}\n        start_time = time.time()\n        total_start_time = start_time\n        encoder_hidden_states, encoder_attention_mask, context_latents = self.prepare_condition(\n            text_hidden_states=text_hidden_states,\n            text_attention_mask=text_attention_mask,\n            lyric_hidden_states=lyric_hidden_states,\n            lyric_attention_mask=lyric_attention_mask,\n            refer_audio_acoustic_hidden_states_packed=refer_audio_acoustic_hidden_states_packed,\n            refer_audio_order_mask=refer_audio_order_mask,\n            hidden_states=src_latents,\n            attention_mask=attention_mask,\n            silence_latent=silence_latent,\n            src_latents=src_latents,\n            chunk_masks=chunk_masks,\n            is_covers=is_covers,\n            precomputed_lm_hints_25Hz=precomputed_lm_hints_25Hz,\n            audio_codes=audio_codes,\n        )\n        encoder_hidden_states_non_cover, encoder_attention_mask_non_cover, context_latents_non_cover = None, None, None\n        if audio_cover_strength < 1.0:\n            non_is_covers = torch.zeros_like(is_covers, device=is_covers.device, dtype=is_covers.dtype)\n            # Use silence_latent for non-cover condition to simulate text2music mode (no reference audio)\n            silence_latent_expanded = silence_latent[:, :src_latents.shape[1], :].expand(src_latents.shape[0], -1, -1)\n            encoder_hidden_states_non_cover, encoder_attention_mask_non_cover, context_latents_non_cover = self.prepare_condition(\n            text_hidden_states=non_cover_text_hidden_states,\n            text_attention_mask=non_cover_text_attention_mask,\n            lyric_hidden_states=lyric_hidden_states,\n            lyric_attention_mask=lyric_attention_mask,\n            refer_audio_acoustic_hidden_states_packed=refer_audio_acoustic_hidden_states_packed,\n            refer_audio_order_mask=refer_audio_order_mask,\n            hidden_states=silence_latent_expanded,\n            attention_mask=attention_mask,\n            silence_latent=silence_latent,\n            src_latents=silence_latent_expanded,\n            chunk_masks=chunk_masks,\n            is_covers=non_is_covers,\n            precomputed_lm_hints_25Hz=None,\n            audio_codes=None,\n        )\n        end_time = time.time()\n        time_costs[\"encoder_time_cost\"] = end_time - start_time\n        start_time = end_time\n\n        # Calculate cover steps based on audio_cover_strength\n        device, dtype = context_latents.device, context_latents.dtype\n\n        # Use custom timesteps if provided, otherwise compute from infer_steps and shift\n        if timesteps is not None:\n            t = timesteps.to(device=device, dtype=dtype)\n            infer_steps = len(t) - 1  # Override infer_steps based on timesteps length\n        else:\n            t = torch.linspace(1.0, 0.0, infer_steps + 1, device=device, dtype=dtype)\n            # Apply shift transformation to timesteps if shift != 1.0\n            if shift != 1.0:\n                t = shift * t / (1 + (shift - 1) * t)\n\n        cover_steps = int(infer_steps * audio_cover_strength)\n        if use_progress_bar:\n            iterator = tqdm(zip(t[:-1], t[1:]), total=infer_steps)\n        else:\n            iterator = zip(t[:-1], t[1:])\n\n        noise = self.prepare_noise(context_latents, seed)\n        bsz, device, dtype = context_latents.shape[0], context_latents.device, context_latents.dtype\n        past_key_values = EncoderDecoderCache(DynamicCache(), DynamicCache())\n        momentum_buffer = MomentumBuffer()\n\n        # Cover noise initialization: blend noise with src_latents\n        if cover_noise_strength > 0.0:\n            # cover_noise_strength=1 means closest to src, so noise_level should be low\n            effective_noise_level = 1.0 - cover_noise_strength\n            # Find nearest timestep in the schedule t[:-1]\n            t_values = t[:-1].tolist()\n            nearest_t = min(t_values, key=lambda x: abs(x - effective_noise_level))\n            start_idx = t_values.index(nearest_t)\n            # xt = nearest_t * noise + (1 - nearest_t) * src_latents\n            xt = self.renoise(src_latents, nearest_t, noise)\n            # Truncate schedule to start from nearest_t\n            t = t[start_idx:]\n            infer_steps = len(t) - 1\n            cover_steps = int(infer_steps * audio_cover_strength)\n            if use_progress_bar:\n                iterator = tqdm(zip(t[:-1], t[1:]), total=infer_steps)\n            else:\n                iterator = zip(t[:-1], t[1:])\n            logger.info(\n                f\"[generate_audio] Cover mode: cover_noise_strength={cover_noise_strength}, \"\n                f\"effective_noise_level={effective_noise_level:.4f}, nearest_t={nearest_t:.4f}, \"\n                f\"remaining_steps={infer_steps}\"\n            )\n        else:\n            xt = noise\n\n        # main task condition\n        do_cfg_guidance = diffusion_guidance_sale > 1.0\n        if do_cfg_guidance:\n            encoder_hidden_states = torch.cat([encoder_hidden_states, self.null_condition_emb.expand_as(encoder_hidden_states)], dim=0)\n            encoder_attention_mask = torch.cat([encoder_attention_mask, encoder_attention_mask], dim=0)\n            # src_latents\n            context_latents = torch.cat([context_latents, context_latents], dim=0)\n            attention_mask = torch.cat([attention_mask, attention_mask], dim=0)\n\n        _switched_to_non_cover = False\n        with torch.no_grad():\n            for step_idx, (t_curr, t_prev) in enumerate(iterator):\n                if step_idx >= cover_steps and not _switched_to_non_cover:\n                    _switched_to_non_cover = True\n                    if do_cfg_guidance:\n                        encoder_hidden_states_non_cover = torch.cat([encoder_hidden_states_non_cover, self.null_condition_emb.expand_as(encoder_hidden_states_non_cover)], dim=0)\n                        encoder_attention_mask_non_cover = torch.cat([encoder_attention_mask_non_cover, encoder_attention_mask_non_cover], dim=0)\n                        # src_latents\n                        context_latents_non_cover = torch.cat([context_latents_non_cover, context_latents_non_cover], dim=0)\n\n                    encoder_hidden_states = encoder_hidden_states_non_cover\n                    encoder_attention_mask = encoder_attention_mask_non_cover\n                    context_latents = context_latents_non_cover\n                    past_key_values = EncoderDecoderCache(DynamicCache(), DynamicCache())\n\n                x = torch.cat([xt, xt], dim=0) if do_cfg_guidance else xt\n                t_curr_tensor = t_curr * torch.ones((x.shape[0],), device=device, dtype=dtype)\n                decoder_outputs = self.decoder(\n                    hidden_states=x,\n                    timestep=t_curr_tensor,\n                    timestep_r=t_curr_tensor,\n                    attention_mask=attention_mask,\n                    encoder_hidden_states=encoder_hidden_states,\n                    encoder_attention_mask=encoder_attention_mask,\n                    context_latents=context_latents,\n                    use_cache=True,\n                    past_key_values=past_key_values,\n                )\n\n                vt = decoder_outputs[0]\n                past_key_values = decoder_outputs[1]\n                apply_cfg_guidance = t_curr >= cfg_interval_start and t_curr <= cfg_interval_end\n                if do_cfg_guidance:\n                    pred_cond, pred_null_cond = vt.chunk(2)\n                    if apply_cfg_guidance:\n                        if not use_adg:\n                            vt = apg_forward(\n                                pred_cond=pred_cond,\n                                pred_uncond=pred_null_cond,\n                                guidance_scale=diffusion_guidance_sale,\n                                momentum_buffer=momentum_buffer,\n                                dims=[1],\n                            )\n                        else:\n                            vt = adg_forward(\n                                latents=xt,\n                                noise_pred_cond=pred_cond,\n                                noise_pred_uncond=pred_null_cond,\n                                sigma=t_curr,\n                                guidance_scale=diffusion_guidance_sale,\n                            )\n                    else:\n                        vt = pred_cond\n                # Update x_t based on inference method\n                if infer_method == \"sde\":\n                    # Stochastic Differential Equation: predict clean, then re-add noise\n                    t_curr_bsz = t_curr * torch.ones((bsz,), device=device, dtype=dtype)\n                    pred_clean = self.get_x0_from_noise(xt, vt, t_curr_bsz)\n                    next_timestep = 1.0 - (float(step_idx + 1) / infer_steps)\n                    xt = self.renoise(pred_clean, next_timestep)\n                    t_after_step = next_timestep\n                elif infer_method == \"ode\":\n                    # Ordinary Differential Equation: Euler method\n                    # dx/dt = -v, so x_{t+1} = x_t - v_t * dt\n                    dt = t_curr - t_prev\n                    dt_tensor = dt * torch.ones((bsz,), device=device, dtype=dtype).unsqueeze(-1).unsqueeze(-1)\n                    xt = xt - vt * dt_tensor\n                    t_after_step = t_prev\n\n                injection_cutoff = round(repaint_injection_ratio * infer_steps)\n                if repaint_mask is not None and clean_src_latents is not None and step_idx < injection_cutoff:\n                    xt = _repaint_step_injection(\n                        xt, clean_src_latents, repaint_mask, t_after_step, noise,\n                    )\n\n        x_gen = xt\n        if repaint_mask is not None and clean_src_latents is not None and repaint_crossfade_frames > 0:\n            x_gen = _repaint_boundary_blend(\n                x_gen, clean_src_latents, repaint_mask, repaint_crossfade_frames,\n            )\n        end_time = time.time()\n        time_costs[\"diffusion_time_cost\"] = end_time - start_time\n        time_costs[\"diffusion_per_step_time_cost\"] = time_costs[\"diffusion_time_cost\"] / infer_steps\n        time_costs[\"total_time_cost\"] = end_time - total_start_time\n        return {\n            \"target_latents\": x_gen,\n            \"time_costs\": time_costs,\n        }\n\n\ndef test_forward(model, seed=42):\n    # Fix random seed for reproducibility\n    import random\n    import numpy as np\n    random.seed(seed)\n    np.random.seed(seed)\n    torch.manual_seed(seed)\n    if torch.cuda.is_available():\n        torch.cuda.manual_seed(seed)\n        torch.cuda.manual_seed_all(seed)\n        torch.backends.cudnn.deterministic = True\n        torch.backends.cudnn.benchmark = False\n\n    # Get model dtype and device\n    model_dtype = next(model.parameters()).dtype\n    device = next(model.parameters()).device\n\n    print(f\"Testing with dtype: {model_dtype}, device: {device}, seed: {seed}\")\n\n    # Test data preparation with matching dtype\n    text_hidden_states = torch.randn(2, 77, 1024, dtype=model_dtype, device=device)\n    text_attention_mask = torch.ones(2, 77, dtype=model_dtype, device=device)\n    lyric_hidden_states = torch.randn(2, 123, 1024, dtype=model_dtype, device=device)\n    lyric_attention_mask = torch.ones(2, 123, dtype=model_dtype, device=device)\n    refer_audio_acoustic_hidden_states_packed = torch.randn(3, 750, 64, dtype=model_dtype, device=device)\n    refer_audio_order_mask = torch.LongTensor([0, 0, 1]).to(device)\n\n    # Base config: 25 Hz hidden states → 10 s = 250 frames (round to int)\n    base_seconds = 10\n    frames_per_second = 25\n    base_seq_len = base_seconds * frames_per_second\n\n    hidden_states = torch.randn(2, base_seq_len, 64, dtype=model_dtype, device=device)\n    attention_mask = torch.ones(2, base_seq_len, dtype=model_dtype, device=device)\n    # Add some padding to test mask behavior\n    pad_start = max(base_seq_len // 2, 1)\n    attention_mask[0, pad_start:] = 0\n    chunk_mask = torch.ones(2, base_seq_len, 64, dtype=model_dtype, device=device)\n    chunk_mask[0, pad_start:] = 0\n\n    silence_latent = torch.randn(2, base_seq_len, 64, dtype=model_dtype, device=device)\n    # New required parameters for updated training logic\n    src_latents = torch.randn(2, base_seq_len, 64, dtype=model_dtype, device=device)  # Source latents for context\n    is_covers = torch.tensor([0, 1], dtype=torch.long, device=device)  # Cover song indicators (0=original, 1=cover)\n\n    # Test 1: Flow matching training (using 10s sequence for sanity check by default)\n    print(f\"Testing flow matching training with {base_seconds}s sequence ({base_seq_len} frames @ {frames_per_second}Hz)...\")\n    outputs = model.training_losses(\n        hidden_states=hidden_states,\n        attention_mask=attention_mask,\n        chunk_masks=chunk_mask,\n        text_hidden_states=text_hidden_states,\n        text_attention_mask=text_attention_mask,\n        lyric_hidden_states=lyric_hidden_states,\n        lyric_attention_mask=lyric_attention_mask,\n        refer_audio_acoustic_hidden_states_packed=refer_audio_acoustic_hidden_states_packed,\n        refer_audio_order_mask=refer_audio_order_mask,\n        silence_latent=silence_latent,\n        src_latents=src_latents,\n        is_covers=is_covers,\n        cfg_ratio=0.15,\n    )\n    loss = outputs['diffusion_loss']\n    print(f\"Flow matching loss: {loss.item():.6f}\")\n    print(f\"  Loss stats - min: {loss.min().item():.6f}, max: {loss.max().item():.6f}, mean: {loss.mean().item():.6f}, std: {loss.std().item() if loss.numel() > 1 else 0:.6f}\")\n\n    # Test 2: Generation with flow matching, testing throughput for different sequence lengths\n    lengths_seconds = [10, 30, 60, 120, 180, 240]\n    infer_steps = 2  # Can be increased as needed (e.g., 50/100) to better approximate real inference\n\n    print(\"\\n===== Throughput benchmark (25Hz hidden states) =====\")\n    for seconds in lengths_seconds:\n        seq_len = seconds * frames_per_second\n\n        # Reconstruct inputs for current sequence length\n        cur_hidden_states = torch.randn(2, seq_len, 64, dtype=model_dtype, device=device)\n        cur_attention_mask = torch.ones(2, seq_len, dtype=model_dtype, device=device)\n        cur_chunk_mask = torch.ones(2, seq_len, 64, dtype=model_dtype, device=device)\n        cur_silence_latent = torch.randn(2, seq_len, 64, dtype=model_dtype, device=device)\n        cur_src_latents = torch.randn(2, seq_len, 64, dtype=model_dtype, device=device)\n\n        print(f\"\\n--- {seconds}s input ({seq_len} frames @ {frames_per_second}Hz) ---\")\n        outputs = model.generate_audio(\n            text_hidden_states=text_hidden_states,\n            text_attention_mask=text_attention_mask,\n            lyric_hidden_states=lyric_hidden_states,\n            lyric_attention_mask=lyric_attention_mask,\n            refer_audio_acoustic_hidden_states_packed=refer_audio_acoustic_hidden_states_packed,\n            refer_audio_order_mask=refer_audio_order_mask,\n            src_latents=cur_src_latents,\n            chunk_masks=cur_chunk_mask,\n            silence_latent=cur_silence_latent,\n            infer_steps=infer_steps,\n            is_covers=is_covers,\n            seed=1234,\n        )\n\n        target_latents = outputs[\"target_latents\"]\n        time_costs = outputs.get(\"time_costs\", {})\n\n        total_time = time_costs.get(\"total_time_cost\", None)\n        diffusion_time = time_costs.get(\"diffusion_time_cost\", None)\n\n        # Output shape and statistics\n        print(f\"Generated latents shape: {target_latents.shape}\")\n        print(\n            f\"Stats - min: {target_latents.min().item():.4f}, \"\n            f\"max: {target_latents.max().item():.4f}, \"\n            f\"mean: {target_latents.mean().item():.4f}, \"\n            f\"std: {target_latents.std().item():.4f}\"\n        )\n\n        # Calculate throughput: statistics by frame count and audio seconds\n        bsz, t_len = target_latents.shape[0], target_latents.shape[1]\n        audio_seconds = t_len / frames_per_second\n\n        if total_time is not None:\n            frames_throughput = (bsz * t_len) / total_time\n            seconds_throughput = (bsz * audio_seconds) / total_time\n            print(\n                f\"Time costs: total={total_time:.4f}s, diffusion={diffusion_time:.4f}s \"\n                f\"({infer_steps} steps)\"\n                if diffusion_time is not None\n                else f\"Time costs: total={total_time:.4f}s\"\n            )\n            print(\n                f\"Throughput (based on total_time): \"\n                f\"{frames_throughput:.2f} frames/s, \"\n                f\"{seconds_throughput:.2f} audio-seconds/s (batch={bsz})\"\n            )\n        else:\n            print(\"Time costs not available in outputs['time_costs']; only basic stats printed.\")\n\n\nif __name__ == \"__main__\":\n    from torch.profiler import profile, record_function, ProfilerActivity\n    import os, torch\n    import time\n    from transformers import AutoModel\n    config = AceStepConfig()\n    start = time.time()\n    import os\n    model_dir = os.path.dirname(os.path.abspath(__file__))\n    model = AceStepConditionGenerationModel.from_pretrained(model_dir)\n    end = time.time()\n    # model.config._attn_implementation = \"sdpa\"\n    model.config._attn_implementation = \"flash_attention_2\"\n    model.eval()\n    # model = model.to(\"cpu\")\n    # model = model.float()\n    model = model.to(\"cuda\")\n    model = model.bfloat16()\n    test_forward(model)\n"
  },
  {
    "path": "acestep/models/turbo/__init__.py",
    "content": ""
  },
  {
    "path": "acestep/models/turbo/configuration_acestep_v15.py",
    "content": "# coding=utf-8\n# Copyright 2024 The Qwen team, Alibaba Group and the HuggingFace Inc. team. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#     http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n\"\"\"AceStep model configuration\"\"\"\n\nfrom transformers.configuration_utils import PretrainedConfig, layer_type_validation\nfrom transformers.modeling_rope_utils import rope_config_validation\nfrom transformers.utils import logging\n\n\nlogger = logging.get_logger(__name__)\n\n\nclass AceStepConfig(PretrainedConfig):\n    r\"\"\"\n    This is the configuration class to store the configuration of a [`AceStepModel`]. It is used to instantiate an\n    AceStep model according to the specified arguments, defining the model architecture.\n\n    Configuration objects inherit from [`PretrainedConfig`] and can be used to control the model outputs. Read the\n    documentation from [`PretrainedConfig`] for more information.\n\n    Args:\n        vocab_size (`int`, *optional*, defaults to 64003):\n            Vocabulary size of the AceStep model. Defines the number of different tokens that can be represented by the\n            `inputs_ids` passed when calling the model.\n        hidden_size (`int`, *optional*, defaults to 4096):\n            Dimension of the hidden representations.\n        intermediate_size (`int`, *optional*, defaults to 22016):\n            Dimension of the MLP representations.\n        num_hidden_layers (`int`, *optional*, defaults to 32):\n            Number of hidden layers in the Transformer encoder.\n        num_attention_heads (`int`, *optional*, defaults to 32):\n            Number of attention heads for each attention layer in the Transformer encoder.\n        num_key_value_heads (`int`, *optional*, defaults to 32):\n            This is the number of key_value heads that should be used to implement Grouped Query Attention. If\n            `num_key_value_heads=num_attention_heads`, the model will use Multi Head Attention (MHA), if\n            `num_key_value_heads=1` the model will use Multi Query Attention (MQA) otherwise GQA is used. When\n            converting a multi-head checkpoint to a GQA checkpoint, each group key and value head should be constructed\n            by meanpooling all the original heads within that group. For more details, check out [this\n            paper](https://huggingface.co/papers/2305.13245). If it is not specified, will default to `32`.\n        head_dim (`int`, *optional*, defaults to 128):\n            The attention head dimension.\n        hidden_act (`str` or `function`, *optional*, defaults to `\"silu\"`):\n            The non-linear activation function (function or string) in the decoder.\n        max_position_embeddings (`int`, *optional*, defaults to 32768):\n            The maximum sequence length that this model might ever be used with.\n        initializer_range (`float`, *optional*, defaults to 0.02):\n            The standard deviation of the truncated_normal_initializer for initializing all weight matrices.\n        rms_norm_eps (`float`, *optional*, defaults to 1e-06):\n            The epsilon used by the rms normalization layers.\n        use_cache (`bool`, *optional*, defaults to `True`):\n            Whether or not the model should return the last key/values attentions (not used by all models). Only\n            relevant if `config.is_decoder=True`.\n        tie_word_embeddings (`bool`, *optional*, defaults to `False`):\n            Whether the model's input and output word embeddings should be tied.\n        rope_theta (`float`, *optional*, defaults to 10000.0):\n            The base period of the RoPE embeddings.\n        rope_scaling (`Dict`, *optional*):\n            Dictionary containing the scaling configuration for the RoPE embeddings. NOTE: if you apply new rope type\n            and you expect the model to work on longer `max_position_embeddings`, we recommend you to update this value\n            accordingly.\n            Expected contents:\n                `rope_type` (`str`):\n                    The sub-variant of RoPE to use. Can be one of ['default', 'linear', 'dynamic', 'yarn', 'longrope',\n                    'llama3'], with 'default' being the original RoPE implementation.\n                `factor` (`float`, *optional*):\n                    Used with all rope types except 'default'. The scaling factor to apply to the RoPE embeddings. In\n                    most scaling types, a `factor` of x will enable the model to handle sequences of length x *\n                    original maximum pre-trained length.\n                `original_max_position_embeddings` (`int`, *optional*):\n                    Used with 'dynamic', 'longrope' and 'llama3'. The original max position embeddings used during\n                    pretraining.\n                `attention_factor` (`float`, *optional*):\n                    Used with 'yarn' and 'longrope'. The scaling factor to be applied on the attention\n                    computation. If unspecified, it defaults to value recommended by the implementation, using the\n                    `factor` field to infer the suggested value.\n                `beta_fast` (`float`, *optional*):\n                    Only used with 'yarn'. Parameter to set the boundary for extrapolation (only) in the linear\n                    ramp function. If unspecified, it defaults to 32.\n                `beta_slow` (`float`, *optional*):\n                    Only used with 'yarn'. Parameter to set the boundary for interpolation (only) in the linear\n                    ramp function. If unspecified, it defaults to 1.\n                `short_factor` (`list[float]`, *optional*):\n                    Only used with 'longrope'. The scaling factor to be applied to short contexts (<\n                    `original_max_position_embeddings`). Must be a list of numbers with the same length as the hidden\n                    size divided by the number of attention heads divided by 2\n                `long_factor` (`list[float]`, *optional*):\n                    Only used with 'longrope'. The scaling factor to be applied to long contexts (<\n                    `original_max_position_embeddings`). Must be a list of numbers with the same length as the hidden\n                    size divided by the number of attention heads divided by 2\n                `low_freq_factor` (`float`, *optional*):\n                    Only used with 'llama3'. Scaling factor applied to low frequency components of the RoPE\n                `high_freq_factor` (`float`, *optional*):\n                    Only used with 'llama3'. Scaling factor applied to high frequency components of the RoPE\n        attention_bias (`bool`, defaults to `False`, *optional*, defaults to `False`):\n            Whether to use a bias in the query, key, value and output projection layers during self-attention.\n        use_sliding_window (`bool`, *optional*, defaults to `False`):\n            Whether to use sliding window attention.\n        sliding_window (`int`, *optional*, defaults to 4096):\n            Sliding window attention (SWA) window size. If not specified, will default to `4096`.\n        layer_types (`list`, *optional*):\n            Attention pattern for each layer.\n        attention_dropout (`float`, *optional*, defaults to 0.0):\n            The dropout ratio for the attention probabilities.\n\n    ```python\n    >>> from acestep.models import AceStepConfig\n\n    >>> # Initializing an AceStep configuration\n    >>> configuration = AceStepConfig()\n\n    >>> # Initializing a model from the configuration\n    >>> model = AceStepConditionGenerationModel(configuration)\n\n    >>> # Accessing the model configuration\n    >>> configuration = model.config\n    ```\"\"\"\n\n    model_type = \"acestep\"\n    keys_to_ignore_at_inference = [\"past_key_values\"]\n    \n    # Default tensor parallel plan for the base model\n    base_model_tp_plan = {\n        \"layers.*.self_attn.q_proj\": \"colwise\",\n        \"layers.*.self_attn.k_proj\": \"colwise\",\n        \"layers.*.self_attn.v_proj\": \"colwise\",\n        \"layers.*.self_attn.o_proj\": \"rowwise\",\n        \"layers.*.mlp.gate_proj\": \"colwise\",\n        \"layers.*.mlp.up_proj\": \"colwise\",\n        \"layers.*.mlp.down_proj\": \"rowwise\",\n    }\n    base_model_pp_plan = {\n        \"embed_tokens\": ([\"input_ids\"], [\"inputs_embeds\"]),\n        \"layers\": ([\"hidden_states\", \"attention_mask\"], [\"hidden_states\"]),\n        \"norm\": ([\"hidden_states\"], [\"hidden_states\"]),\n    }\n    def __init__(\n        self,\n        vocab_size=64003,\n        fsq_dim=2048,\n        fsq_input_levels=[8, 8, 8, 5, 5, 5],\n        fsq_input_num_quantizers=1,\n        hidden_size=2048,\n        intermediate_size=6144,\n        num_hidden_layers=24,\n        num_attention_heads=16,\n        num_key_value_heads=8,\n        head_dim=128,\n        hidden_act=\"silu\",\n        max_position_embeddings=32768,\n        initializer_range=0.02,\n        rms_norm_eps=1e-6,\n        use_cache=True,\n        tie_word_embeddings=True,\n        rope_theta=1000000,\n        rope_scaling=None,\n        attention_bias=False,\n        use_sliding_window=True,\n        sliding_window=128,\n        layer_types=None,\n        attention_dropout=0.0,\n        num_lyric_encoder_hidden_layers=8,\n        audio_acoustic_hidden_dim=64,\n        pool_window_size=5,\n        text_hidden_dim=1024,\n        in_channels=192,\n        data_proportion=0.5,\n        timestep_mu=-0.4,\n        timestep_sigma=1.0,\n        timbre_hidden_dim=64,\n        num_timbre_encoder_hidden_layers=4,\n        timbre_fix_frame=750,\n        patch_size=2,\n        num_attention_pooler_hidden_layers=2,\n        num_audio_decoder_hidden_layers=24,\n        model_version=\"turbo\",\n        **kwargs,\n    ):\n        self.max_position_embeddings = max_position_embeddings\n        self.hidden_size = hidden_size\n        self.intermediate_size = intermediate_size\n        self.num_hidden_layers = num_hidden_layers\n        self.num_attention_heads = num_attention_heads\n        self.use_sliding_window = use_sliding_window\n        self.sliding_window = sliding_window if self.use_sliding_window else None\n        \n        # Text encoder configuration\n        self.text_hidden_dim = text_hidden_dim\n\n        # Lyric encoder configuration\n        self.num_lyric_encoder_hidden_layers = num_lyric_encoder_hidden_layers\n        self.patch_size = patch_size\n\n        # Audio semantic token generation configuration\n        self.audio_acoustic_hidden_dim = audio_acoustic_hidden_dim\n        self.pool_window_size = pool_window_size\n        self.in_channels = in_channels\n        self.data_proportion = data_proportion\n        self.timestep_mu = timestep_mu\n        self.timestep_sigma = timestep_sigma\n        \n        # FSQ (Finite Scalar Quantization) configuration\n        self.fsq_dim = fsq_dim\n        self.fsq_input_levels = fsq_input_levels\n        self.fsq_input_num_quantizers = fsq_input_num_quantizers\n        \n        # Timbre encoder configuration\n        self.timbre_hidden_dim = timbre_hidden_dim\n        self.num_timbre_encoder_hidden_layers = num_timbre_encoder_hidden_layers\n        self.timbre_fix_frame = timbre_fix_frame\n        self.num_attention_pooler_hidden_layers = num_attention_pooler_hidden_layers\n        self.num_audio_decoder_hidden_layers = num_audio_decoder_hidden_layers\n        self.vocab_size = vocab_size\n\n        # Backward compatibility: ensure num_key_value_heads is set\n        if num_key_value_heads is None:\n            num_key_value_heads = num_attention_heads\n\n        self.num_key_value_heads = num_key_value_heads\n        self.head_dim = head_dim\n        self.hidden_act = hidden_act\n        self.initializer_range = initializer_range\n        self.rms_norm_eps = rms_norm_eps\n        self.use_cache = use_cache\n        self.rope_theta = rope_theta\n        self.rope_scaling = rope_scaling\n        self.attention_bias = attention_bias\n        self.attention_dropout = attention_dropout\n        self.model_version = model_version\n        \n        # Validate rotary position embeddings parameters\n        # Backward compatibility: if there is a 'type' field, move it to 'rope_type'\n        if self.rope_scaling is not None and \"type\" in self.rope_scaling:\n            self.rope_scaling[\"rope_type\"] = self.rope_scaling[\"type\"]\n        rope_config_validation(self)\n\n        self.layer_types = layer_types\n\n        # Set default layer types if not specified\n        if self.layer_types is None:\n            self.layer_types = [\n                \"sliding_attention\" if bool((i + 1) % 2) else \"full_attention\" for i in range(self.num_hidden_layers)\n            ]\n        layer_type_validation(self.layer_types)\n\n        super().__init__(\n            tie_word_embeddings=tie_word_embeddings,\n            **kwargs,\n        )\n\n\n__all__ = [\"AceStepConfig\"]\n"
  },
  {
    "path": "acestep/models/turbo/modeling_acestep_v15_turbo.py",
    "content": "# Copyright 2025 The ACESTEO Team. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#     http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\nimport math\nimport time\nfrom typing import Callable, List, Optional, Union\n\nimport torch\nimport torch.nn.functional as F\nfrom torch import nn\n\nfrom einops import rearrange\n\n# Transformers imports (sorted by submodule, then alphabetically)\nfrom transformers.cache_utils import Cache, DynamicCache, EncoderDecoderCache\nfrom transformers.modeling_attn_mask_utils import _prepare_4d_causal_attention_mask\nfrom transformers.modeling_flash_attention_utils import FlashAttentionKwargs\nfrom transformers.modeling_layers import GradientCheckpointingLayer\nfrom transformers.modeling_outputs import BaseModelOutput\nfrom transformers.modeling_utils import ALL_ATTENTION_FUNCTIONS, PreTrainedModel\nfrom transformers.processing_utils import Unpack\nfrom transformers.utils import auto_docstring, can_return_tuple, logging\nfrom transformers.models.qwen3.modeling_qwen3 import (\n    Qwen3MLP,\n    Qwen3RMSNorm,\n    Qwen3RotaryEmbedding,\n    apply_rotary_pos_emb,\n    eager_attention_forward,\n)\n\nfrom vector_quantize_pytorch import ResidualFSQ\n\n# Local config import with fallback\ntry:\n    from .configuration_acestep_v15 import AceStepConfig\nexcept ImportError:\n    from configuration_acestep_v15 import AceStepConfig\n\n\nlogger = logging.get_logger(__name__)\n\n\ndef create_4d_mask(\n    seq_len: int,\n    dtype: torch.dtype,\n    device: torch.device,\n    attention_mask: Optional[torch.Tensor] = None, # [Batch, Seq_Len]\n    sliding_window: Optional[int] = None,\n    is_sliding_window: bool = False,\n    is_causal: bool = True,\n) -> torch.Tensor:\n    \"\"\"\n    General 4D Attention Mask generator compatible with CPU/Mac/SDPA and Eager mode.\n    Supports use cases:\n    1. Causal Full: is_causal=True, is_sliding_window=False (standard GPT)\n    2. Causal Sliding: is_causal=True, is_sliding_window=True (Mistral/Qwen local window)\n    3. Bidirectional Full: is_causal=False, is_sliding_window=False (BERT/Encoder)\n    4. Bidirectional Sliding: is_causal=False, is_sliding_window=True (Longformer local)\n\n    Returns:\n        [Batch, 1, Seq_Len, Seq_Len] additive mask (0.0 for keep, -inf for mask)\n    \"\"\"\n    # ------------------------------------------------------\n    # 1. Construct basic geometry mask [Seq_Len, Seq_Len]\n    # ------------------------------------------------------\n\n    # Build index matrices\n    # i (Query): [0, 1, ..., L-1]\n    # j (Key):   [0, 1, ..., L-1]\n    indices = torch.arange(seq_len, device=device)\n    # diff = i - j\n    diff = indices.unsqueeze(1) - indices.unsqueeze(0)\n\n    # Initialize all True (all positions visible)\n    valid_mask = torch.ones((seq_len, seq_len), device=device, dtype=torch.bool)\n\n    # (A) Handle causality (Causal)\n    if is_causal:\n        # i >= j  =>  diff >= 0\n        valid_mask = valid_mask & (diff >= 0)\n\n    # (B) Handle sliding window\n    if is_sliding_window and sliding_window is not None:\n        if is_causal:\n            # Causal sliding: only attend to past window steps\n            # i - j <= window  =>  diff <= window\n            # (diff >= 0 already handled above)\n            valid_mask = valid_mask & (diff <= sliding_window)\n        else:\n            # Bidirectional sliding: attend past and future window steps\n            # |i - j| <= window  =>  abs(diff) <= sliding_window\n            valid_mask = valid_mask & (torch.abs(diff) <= sliding_window)\n\n    # Expand dimensions to [1, 1, Seq_Len, Seq_Len] for broadcasting\n    valid_mask = valid_mask.unsqueeze(0).unsqueeze(0)\n\n    # ------------------------------------------------------\n    # 2. Apply padding mask (Key Masking)\n    # ------------------------------------------------------\n    if attention_mask is not None:\n        # attention_mask shape: [Batch, Seq_Len] (1=valid, 0=padding)\n        # We want to mask out invalid keys (columns)\n        # Expand shape: [Batch, 1, 1, Seq_Len]\n        padding_mask_4d = attention_mask.view(attention_mask.shape[0], 1, 1, seq_len).to(torch.bool)\n        \n        # Broadcasting: Geometry Mask [1, 1, L, L] & Padding Mask [B, 1, 1, L]\n        # Result shape: [B, 1, L, L]\n        valid_mask = valid_mask & padding_mask_4d\n\n    # ------------------------------------------------------\n    # 3. Convert to additive mask\n    # ------------------------------------------------------\n    # Get the minimal value for current dtype\n    min_dtype = torch.finfo(dtype).min\n    \n    # Create result tensor filled with -inf by default\n    mask_tensor = torch.full(valid_mask.shape, min_dtype, dtype=dtype, device=device)\n    \n    # Set valid positions to 0.0\n    mask_tensor.masked_fill_(valid_mask, 0.0)\n    \n    return mask_tensor\n\n\ndef pack_sequences(hidden1: torch.Tensor, hidden2: torch.Tensor, mask1: torch.Tensor, mask2: torch.Tensor):\n    \"\"\"\n    Pack two sequences by concatenating and sorting them based on mask values.\n\n    Args:\n        hidden1: First hidden states tensor of shape [B, L1, D]\n        hidden2: Second hidden states tensor of shape [B, L2, D]\n        mask1: First mask tensor of shape [B, L1]\n        mask2: Second mask tensor of shape [B, L2]\n\n    Returns:\n        Tuple of (packed_hidden_states, new_mask) where:\n        - packed_hidden_states: Packed hidden states with valid tokens (mask=1) first, shape [B, L1+L2, D]\n        - new_mask: New mask tensor indicating valid positions, shape [B, L1+L2]\n    \"\"\"\n    # Step 1: Concatenate hidden states and masks along sequence dimension\n    hidden_cat = torch.cat([hidden1, hidden2], dim=1)  # [B, L, D]\n    mask_cat = torch.cat([mask1, mask2], dim=1)  # [B, L]\n\n    B, L, D = hidden_cat.shape\n\n    # Step 2: Sort indices so that mask values of 1 come before 0\n    sort_idx = mask_cat.argsort(dim=1, descending=True, stable=True)  # [B, L]\n\n    # Step 3: Reorder hidden states using sorted indices\n    hidden_left = torch.gather(hidden_cat, 1, sort_idx.unsqueeze(-1).expand(B, L, D))\n\n    # Step 4: Create new mask based on valid sequence lengths\n    lengths = mask_cat.sum(dim=1)  # [B]\n    new_mask = (torch.arange(L, dtype=torch.long, device=hidden_cat.device).unsqueeze(0) < lengths.unsqueeze(1))\n\n    return hidden_left, new_mask\n\n\ndef sample_t_r(batch_size, device, dtype, data_proportion=0.0, timestep_mu=-0.4, timestep_sigma=1.0, use_meanflow=True):\n    \"\"\"\n    Sample timestep t and r for flow matching training.\n\n    Args:\n        batch_size: Batch size\n        device: Device to create tensors on\n        dtype: Data type for tensors\n        data_proportion: Proportion of data samples (0.0 to 1.0)\n        timestep_mu: Mean for timestep sampling\n        timestep_sigma: Standard deviation for timestep sampling\n        use_meanflow: Whether to use meanflow (if False, data_proportion is set to 1.0)\n\n    Returns:\n        Tuple of (t, r) tensors, each of shape [batch_size]\n    \"\"\"\n    t = torch.sigmoid(torch.randn((batch_size,), device=device, dtype=dtype) * timestep_sigma + timestep_mu)\n    r = torch.sigmoid(torch.randn((batch_size,), device=device, dtype=dtype) * timestep_sigma + timestep_mu)\n    # Assign t = max, r = min, for each pair\n    t, r = torch.maximum(t, r), torch.minimum(t, r)\n    if not use_meanflow:\n        data_proportion = 1.0\n    data_size = int(batch_size * data_proportion)\n    zero_mask = torch.arange(batch_size, device=device) < data_size\n    r = torch.where(zero_mask, t, r)\n    return t, r\n\n\nclass TimestepEmbedding(nn.Module):\n    \"\"\"\n    Timestep embedding module for diffusion models.\n    \n    Converts timestep values into high-dimensional embeddings using sinusoidal\n    positional encoding, followed by MLP layers. Used for conditioning diffusion\n    models on timestep information.\n    \"\"\"\n    def __init__(\n        self,\n        in_channels: int,\n        time_embed_dim: int,\n        scale: float = 1000,\n    ):\n        super().__init__()\n\n        self.linear_1 = nn.Linear(in_channels, time_embed_dim, bias=True)\n        self.act1 = nn.SiLU()\n        self.linear_2 = nn.Linear(time_embed_dim, time_embed_dim, bias=True)\n        self.in_channels = in_channels\n        \n        self.act2 = nn.SiLU()\n        self.time_proj = nn.Linear(time_embed_dim, time_embed_dim * 6)\n        self.scale = scale\n\n    def timestep_embedding(self, t, dim, max_period=10000):\n        \"\"\"\n        Create sinusoidal timestep embeddings.\n\n        Args:\n            t: A 1-D tensor of N indices, one per batch element. These may be fractional.\n            dim: The dimension of the output embeddings.\n            max_period: Controls the minimum frequency of the embeddings.\n\n        Returns:\n            An (N, D) tensor of positional embeddings.\n        \"\"\"\n        t = t * self.scale\n        half = dim // 2\n        freqs = torch.exp(\n            -math.log(max_period) * torch.arange(start=0, end=half, dtype=torch.float32) / half\n        ).to(device=t.device)\n        args = t[:, None].float() * freqs[None]\n        embedding = torch.cat([torch.cos(args), torch.sin(args)], dim=-1)\n        if dim % 2:\n            embedding = torch.cat([embedding, torch.zeros_like(embedding[:, :1])], dim=-1)\n        return embedding\n\n    def forward(self, t):\n        t_freq = self.timestep_embedding(t, self.in_channels)\n        temb = self.linear_1(t_freq.to(t.dtype))\n        temb = self.act1(temb)\n        temb = self.linear_2(temb)\n        timestep_proj = self.time_proj(self.act2(temb)).unflatten(1, (6, -1))\n        return temb, timestep_proj\n\nclass AceStepAttention(nn.Module):\n    \"\"\"\n    Multi-headed attention module for AceStep model.\n\n    Implements the attention mechanism from 'Attention Is All You Need' paper,\n    with support for both self-attention and cross-attention modes. Uses RMSNorm\n    for query and key normalization, and supports sliding window attention for\n    efficient long-sequence processing.\n    \"\"\"\n\n    def __init__(self, config: AceStepConfig, layer_idx: int, is_cross_attention: bool = False, is_causal: bool = False):\n        super().__init__()\n        self.config = config\n        self.layer_idx = layer_idx\n        self.head_dim = getattr(config, \"head_dim\", config.hidden_size // config.num_attention_heads)\n        self.num_key_value_groups = config.num_attention_heads // config.num_key_value_heads\n        self.scaling = self.head_dim**-0.5\n        self.attention_dropout = config.attention_dropout\n        if is_cross_attention:\n            is_causal = False\n        self.is_causal = is_causal\n        self.is_cross_attention = is_cross_attention\n\n        self.q_proj = nn.Linear(config.hidden_size, config.num_attention_heads * self.head_dim, bias=config.attention_bias)\n        self.k_proj = nn.Linear(config.hidden_size, config.num_key_value_heads * self.head_dim, bias=config.attention_bias)\n        self.v_proj = nn.Linear(config.hidden_size, config.num_key_value_heads * self.head_dim, bias=config.attention_bias)\n        self.o_proj = nn.Linear(config.num_attention_heads * self.head_dim, config.hidden_size, bias=config.attention_bias)\n        # Apply RMS normalization only on the head dimension (unlike OLMo)\n        self.q_norm = Qwen3RMSNorm(self.head_dim, eps=config.rms_norm_eps)\n        self.k_norm = Qwen3RMSNorm(self.head_dim, eps=config.rms_norm_eps)\n        self.attention_type = config.layer_types[layer_idx]\n        self.sliding_window = config.sliding_window if config.layer_types[layer_idx] == \"sliding_attention\" else None\n\n    def forward(\n        self,\n        hidden_states: torch.Tensor,\n        attention_mask: Optional[torch.Tensor],\n        past_key_value: Optional[Cache] = None,\n        cache_position: Optional[torch.LongTensor] = None,\n        encoder_hidden_states: Optional[torch.Tensor] = None,\n        position_embeddings: tuple[torch.Tensor, torch.Tensor] = None,\n        output_attentions: Optional[bool] = False,\n        **kwargs: Unpack[FlashAttentionKwargs],\n    ) -> tuple[torch.Tensor, Optional[torch.Tensor], Optional[tuple[torch.Tensor]]]:\n        input_shape = hidden_states.shape[:-1]\n        hidden_shape = (*input_shape, -1, self.head_dim)\n\n        # Project and normalize query states\n        query_states = self.q_norm(self.q_proj(hidden_states).view(hidden_shape)).transpose(1, 2)\n\n        # Determine if this is cross-attention (requires encoder_hidden_states)\n        is_cross_attention = self.is_cross_attention and encoder_hidden_states is not None\n        \n        # Cross-attention path: attend to encoder hidden states\n        if is_cross_attention:\n            encoder_hidden_shape = (*encoder_hidden_states.shape[:-1], -1, self.head_dim)\n            if past_key_value is not None:\n                is_updated = past_key_value.is_updated.get(self.layer_idx)\n                # After the first generated token, we can reuse all key/value states from cache\n                curr_past_key_value = past_key_value.cross_attention_cache\n                \n                # Conditions for calculating key and value states\n                if not is_updated:\n                    # Compute and cache K/V for the first time\n                    key_states = self.k_norm(self.k_proj(encoder_hidden_states).view(encoder_hidden_shape)).transpose(1, 2)\n                    value_states = self.v_proj(encoder_hidden_states).view(encoder_hidden_shape).transpose(1, 2)\n                    # Update cache: save all key/value states to cache for fast auto-regressive generation\n                    key_states, value_states = curr_past_key_value.update(key_states, value_states, self.layer_idx)\n                    # Set flag that this layer's cross-attention cache is updated\n                    past_key_value.is_updated[self.layer_idx] = True\n                else:\n                    # Reuse cached key/value states for subsequent tokens\n                    key_states = curr_past_key_value.layers[self.layer_idx].keys\n                    value_states = curr_past_key_value.layers[self.layer_idx].values\n            else:\n                # No cache used, compute K/V directly\n                key_states = self.k_norm(self.k_proj(encoder_hidden_states).view(encoder_hidden_shape)).transpose(1, 2)\n                value_states = self.v_proj(encoder_hidden_states).view(encoder_hidden_shape).transpose(1, 2)\n        \n        # Self-attention path: attend to the same sequence\n        else:\n            # Project and normalize key/value states for self-attention\n            key_states = self.k_norm(self.k_proj(hidden_states).view(hidden_shape)).transpose(1, 2)\n            value_states = self.v_proj(hidden_states).view(hidden_shape).transpose(1, 2)\n            # Apply rotary position embeddings (RoPE) if provided\n            if position_embeddings is not None:\n                cos, sin = position_embeddings\n                query_states, key_states = apply_rotary_pos_emb(query_states, key_states, cos, sin)\n\n            # Update cache for auto-regressive generation\n            if past_key_value is not None:\n                # Sin and cos are specific to RoPE models; cache_position needed for the static cache\n                cache_kwargs = {\"sin\": sin, \"cos\": cos, \"cache_position\": cache_position}\n                key_states, value_states = past_key_value.update(key_states, value_states, self.layer_idx, cache_kwargs)\n\n        attention_interface: Callable = eager_attention_forward\n        if is_cross_attention and output_attentions:\n            attention_interface: Callable = eager_attention_forward\n        elif self.config._attn_implementation != \"eager\":\n            attention_interface = ALL_ATTENTION_FUNCTIONS[self.config._attn_implementation]\n    \n        attn_output, attn_weights = attention_interface(\n            self,\n            query_states,\n            key_states,\n            value_states,\n            attention_mask,\n            dropout=self.attention_dropout if self.training else 0.0,\n            scaling=self.scaling,\n            sliding_window=self.sliding_window if not self.is_cross_attention else None,\n            **kwargs,\n        )\n\n        attn_output = attn_output.reshape(*input_shape, -1).contiguous()\n        attn_output = self.o_proj(attn_output)\n        return attn_output, attn_weights\n\n\nclass AceStepEncoderLayer(GradientCheckpointingLayer):\n    \"\"\"\n    Encoder layer for AceStep model.\n\n    Consists of self-attention and MLP (feed-forward) sub-layers with residual connections.\n    \"\"\"\n\n    def __init__(self, config, layer_idx: int):\n        super().__init__()\n        self.hidden_size = config.hidden_size\n        self.config = config\n        self.layer_idx = layer_idx\n\n        # Self-attention sub-layer\n        self.self_attn = AceStepAttention(\n            config=config,\n            layer_idx=layer_idx,\n            is_cross_attention=False,\n            is_causal=False,\n        )\n        self.input_layernorm = Qwen3RMSNorm(config.hidden_size, eps=config.rms_norm_eps)\n        self.post_attention_layernorm = Qwen3RMSNorm(config.hidden_size, eps=config.rms_norm_eps)\n\n        # MLP (feed-forward) sub-layer\n        self.mlp = Qwen3MLP(config)\n        self.attention_type = config.layer_types[layer_idx]\n\n    def forward(\n        self,\n        hidden_states: torch.Tensor,\n        position_embeddings: tuple[torch.Tensor, torch.Tensor],\n        attention_mask: Optional[torch.Tensor] = None,\n        position_ids: Optional[torch.LongTensor] = None,\n        output_attentions: Optional[bool] = False,\n        **kwargs,\n    ) -> tuple[\n        torch.FloatTensor,\n        Optional[tuple[torch.FloatTensor, torch.FloatTensor]],\n    ]:\n        # Self-attention with residual connection\n        residual = hidden_states\n        hidden_states = self.input_layernorm(hidden_states)\n        hidden_states, self_attn_weights = self.self_attn(\n            hidden_states=hidden_states,\n            position_embeddings=position_embeddings,\n            attention_mask=attention_mask,\n            position_ids=position_ids,\n            output_attentions=output_attentions,\n            # Encoders don't use cache\n            use_cache=False,\n            past_key_value=None,\n            **kwargs,\n        )\n        hidden_states = residual + hidden_states\n\n        # MLP with residual connection\n        residual = hidden_states\n        hidden_states = self.post_attention_layernorm(hidden_states)\n        hidden_states = self.mlp(hidden_states)\n        hidden_states = residual + hidden_states\n\n        outputs = (hidden_states,)\n\n        if output_attentions:\n            outputs += (self_attn_weights,)\n\n        return outputs\n\n\nclass AceStepDiTLayer(GradientCheckpointingLayer):\n    \"\"\"\n    DiT (Diffusion Transformer) layer for AceStep model.\n    \n    Implements a transformer layer with three main components:\n    1. Self-attention with adaptive layer norm (AdaLN)\n    2. Cross-attention (optional) for conditioning on encoder outputs\n    3. Feed-forward MLP with adaptive layer norm\n    \n    Uses scale-shift modulation from timestep embeddings for adaptive normalization.\n    \"\"\"\n    def __init__(self, config: AceStepConfig, layer_idx: int, use_cross_attention: bool = True):\n        super().__init__()\n\n        # 1. Self-attention sub-layer with adaptive normalization\n        self.self_attn_norm = Qwen3RMSNorm(config.hidden_size, eps=config.rms_norm_eps)\n        self.self_attn = AceStepAttention(config=config, layer_idx=layer_idx)\n\n        # 2. Cross-attention sub-layer (optional, for encoder conditioning)\n        self.use_cross_attention = use_cross_attention\n        if self.use_cross_attention:\n            self.cross_attn_norm = Qwen3RMSNorm(config.hidden_size, eps=config.rms_norm_eps)\n            self.cross_attn = AceStepAttention(config=config, layer_idx=layer_idx, is_cross_attention=True)\n\n        # 3. Feed-forward MLP sub-layer with adaptive normalization\n        self.mlp_norm = Qwen3RMSNorm(config.hidden_size, eps=config.rms_norm_eps)\n        self.mlp = Qwen3MLP(config)\n\n        # Scale-shift table for adaptive layer norm modulation (6 values: 3 for self-attn, 3 for MLP)\n        self.scale_shift_table = nn.Parameter(torch.randn(1, 6, config.hidden_size) / config.hidden_size**0.5)\n        self.attention_type = config.layer_types[layer_idx]\n    \n    def forward(\n        self,\n        hidden_states: torch.Tensor,\n        position_embeddings: tuple[torch.Tensor, torch.Tensor],\n        temb: torch.Tensor,\n        attention_mask: Optional[torch.Tensor] = None,\n        position_ids: Optional[torch.LongTensor] = None,\n        past_key_value: Optional[EncoderDecoderCache] = None,\n        output_attentions: Optional[bool] = False,\n        use_cache: Optional[bool] = False,\n        cache_position: Optional[torch.LongTensor] = None,\n        encoder_hidden_states: Optional[torch.Tensor] = None,\n        encoder_attention_mask: Optional[torch.Tensor] = None,\n        **kwargs,\n    ) -> torch.Tensor:\n\n        # Extract scale-shift parameters for adaptive layer norm from timestep embeddings\n        # 6 values: (shift_msa, scale_msa, gate_msa, c_shift_msa, c_scale_msa, c_gate_msa)\n        shift_msa, scale_msa, gate_msa, c_shift_msa, c_scale_msa, c_gate_msa = (\n            self.scale_shift_table + temb\n        ).chunk(6, dim=1)\n\n        # Step 1: Self-attention with adaptive layer norm (AdaLN)\n        # Apply adaptive normalization: norm(x) * (1 + scale) + shift\n        norm_hidden_states = (self.self_attn_norm(hidden_states) * (1 + scale_msa) + shift_msa).type_as(hidden_states)\n        attn_output, self_attn_weights = self.self_attn(\n            hidden_states=norm_hidden_states,\n            position_embeddings=position_embeddings,\n            attention_mask=attention_mask,\n            position_ids=position_ids,\n            output_attentions=output_attentions,\n            use_cache=False,\n            past_key_value=None,\n            **kwargs,\n        )\n        # Apply gated residual connection: x = x + attn_output * gate\n        hidden_states = (hidden_states + attn_output * gate_msa).type_as(hidden_states)\n\n        # Step 2: Cross-attention (if enabled) for conditioning on encoder outputs\n        if self.use_cross_attention:\n            norm_hidden_states = self.cross_attn_norm(hidden_states).type_as(hidden_states)\n            attn_output, cross_attn_weights = self.cross_attn(\n                hidden_states=norm_hidden_states,\n                encoder_hidden_states=encoder_hidden_states,\n                attention_mask=encoder_attention_mask,\n                past_key_value=past_key_value,\n                output_attentions=output_attentions,\n                use_cache=use_cache,\n                **kwargs,\n            )\n            # Standard residual connection for cross-attention\n            hidden_states = hidden_states + attn_output\n\n        # Step 3: Feed-forward (MLP) with adaptive layer norm\n        # Apply adaptive normalization for MLP: norm(x) * (1 + scale) + shift\n        norm_hidden_states = (self.mlp_norm(hidden_states) * (1 + c_scale_msa) + c_shift_msa).type_as(hidden_states)\n        ff_output = self.mlp(norm_hidden_states)\n        # Apply gated residual connection: x = x + mlp_output * gate\n        hidden_states = (hidden_states + ff_output * c_gate_msa).type_as(hidden_states)\n\n        outputs = (hidden_states,)\n        if output_attentions:\n            outputs += (self_attn_weights, cross_attn_weights)\n\n        return outputs\n\n\n@auto_docstring\nclass AceStepPreTrainedModel(PreTrainedModel):\n    config_class = AceStepConfig\n    base_model_prefix = \"model\"\n    supports_gradient_checkpointing = True\n    _no_split_modules = [\"AceStepEncoderLayer\", \"AceStepDiTLayer\"]\n    _skip_keys_device_placement = [\"past_key_values\"]\n    _supports_flash_attn_3 = True\n    _supports_flash_attn_2 = True\n    _supports_sdpa = True\n    _supports_flex_attn = True\n    _supports_cache_class = True\n    _supports_quantized_cache = True\n    _supports_static_cache = True\n    _supports_attention_backend = True\n\n    def _init_weights(self, module):\n        \"\"\"\n        Initialize weights for different module types.\n\n        TODO: Support separate initialization for encoders and decoders.\n        \"\"\"\n        std = self.config.initializer_range\n        if isinstance(module, nn.Linear):\n            module.weight.data.normal_(mean=0.0, std=std)\n            if module.bias is not None:\n                module.bias.data.zero_()\n        elif isinstance(module, nn.Embedding):\n            module.weight.data.normal_(mean=0.0, std=std)\n            if module.padding_idx is not None:\n                module.weight.data[module.padding_idx].zero_()\n        elif isinstance(module, Qwen3RMSNorm):\n            module.weight.data.fill_(1.0)\n\n\nclass AceStepLyricEncoder(AceStepPreTrainedModel):\n    \"\"\"\n    Encoder for processing lyric text embeddings.\n    \n    Encodes lyric text hidden states using a transformer encoder architecture\n    with bidirectional attention. Projects text embeddings to model hidden size\n    and processes them through multiple encoder layers.\n    \"\"\"\n    def __init__(self, config):\n        super().__init__(config)\n        \n        # Project text embeddings to model hidden size\n        self.embed_tokens = nn.Linear(config.text_hidden_dim, config.hidden_size)\n        self.norm = Qwen3RMSNorm(config.hidden_size, eps=config.rms_norm_eps)\n        self.rotary_emb = Qwen3RotaryEmbedding(config=config)\n        self.gradient_checkpointing = False\n\n        # Stack of encoder layers\n        self.layers = nn.ModuleList(\n            [AceStepEncoderLayer(config, layer_idx) for layer_idx in range(config.num_lyric_encoder_hidden_layers)]\n        )\n\n        # Initialize weights and apply final processing\n        self.post_init()\n\n    @can_return_tuple\n    def forward(\n        self,\n        input_ids: Optional[torch.LongTensor] = None,\n        attention_mask: Optional[torch.Tensor] = None,\n        position_ids: Optional[torch.LongTensor] = None,\n        inputs_embeds: Optional[torch.FloatTensor] = None,\n        output_attentions: Optional[bool] = None,\n        output_hidden_states: Optional[bool] = None,\n        **flash_attn_kwargs: Unpack[FlashAttentionKwargs],\n    ) -> BaseModelOutput:\n        output_attentions = output_attentions if output_attentions is not None else self.config.output_attentions\n        output_hidden_states = (\n            output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states\n        )\n\n        assert input_ids is None, \"Only `input_ids` is supported for the lyric encoder.\"\n        assert attention_mask is not None, \"Attention mask must be provided for the lyric encoder.\"\n        assert inputs_embeds is not None, \"Inputs embeddings must be provided for the lyric encoder.\"\n        \n        # Project input embeddings: N x T x text_hidden_dim -> N x T x hidden_size\n        inputs_embeds = self.embed_tokens(inputs_embeds)\n        # Cache position: only used for mask construction (not for actual caching)\n        cache_position = torch.arange(0, inputs_embeds.shape[1], device=inputs_embeds.device)\n\n        # Positional IDs\n        if position_ids is None:\n            position_ids = cache_position.unsqueeze(0)\n\n        # Attention masks\n        seq_len = inputs_embeds.shape[1]\n        dtype = inputs_embeds.dtype\n        device = inputs_embeds.device\n        \n        # 判断是否使用 Flash Attention 2\n        is_flash_attn = (self.config._attn_implementation == \"flash_attention_2\")\n\n        # 初始化 Mask 变量\n        full_attn_mask = None\n        sliding_attn_mask = None\n\n        if is_flash_attn:\n            # -------------------------------------------------------\n            # 场景 A: Flash Attention 模式\n            # -------------------------------------------------------\n            # FA 不需要 4D Mask。\n            # 如果有 padding mask (attention_mask [B, L])，直接传给它即可。\n            # 如果没有 padding mask，传 None。\n            # 滑动窗口逻辑由 Layer 内部传给 FA kernel 的 sliding_window 参数控制。\n            full_attn_mask = attention_mask\n            \n            # 这里的逻辑是：如果配置启用了滑动窗口，FA 模式下我们也只需要传基础的 padding mask\n            # Layer 会自己决定是否调用带 sliding window 的 kernel\n            sliding_attn_mask = attention_mask if self.config.use_sliding_window else None\n\n        else:\n            # -------------------------------------------------------\n            # 场景 B: CPU / Mac / SDPA (Eager 模式)\n            # -------------------------------------------------------\n            # 必须手动生成 4D Mask [B, 1, L, L]\n            \n            # 1. Full Attention (Bidirectional, Global)\n            # 对应原来的 create_causal_mask + bidirectional\n            full_attn_mask = create_4d_mask(\n                seq_len=seq_len,\n                dtype=dtype,\n                device=device,\n                attention_mask=attention_mask,     # [B, L]\n                sliding_window=None,\n                is_sliding_window=False,\n                is_causal=False                    # <--- 关键：双向注意力\n            )\n\n            # 2. Sliding Attention (Bidirectional, Local)\n            # 对应原来的 create_sliding_window... + bidirectional\n            if self.config.use_sliding_window:\n                sliding_attn_mask = create_4d_mask(\n                    seq_len=seq_len,\n                    dtype=dtype,\n                    device=device,\n                    attention_mask=attention_mask, # [B, L]\n                    sliding_window=self.config.sliding_window,\n                    is_sliding_window=True,        # <--- 开启滑动窗口\n                    is_causal=False                # <--- 关键：双向注意力\n                )\n\n        # 构建 Mapping\n        self_attn_mask_mapping = {\n            \"full_attention\": full_attn_mask,\n            \"sliding_attention\": sliding_attn_mask,\n        }\n\n        # Initialize hidden states with input embeddings\n        hidden_states = inputs_embeds\n\n        # Create position embeddings to be shared across all layers\n        position_embeddings = self.rotary_emb(hidden_states, position_ids)\n\n        # Pass through transformer layers\n        all_hidden_states = () if output_hidden_states else None\n        all_self_attns = () if output_attentions else None\n\n        for layer_module in self.layers[: self.config.num_hidden_layers]:\n            if output_hidden_states:\n                all_hidden_states += (hidden_states,)\n\n            layer_outputs = layer_module(\n                hidden_states,\n                position_embeddings,\n                self_attn_mask_mapping[layer_module.attention_type],\n                position_ids,\n                output_attentions,\n                **flash_attn_kwargs,\n            )\n\n            hidden_states = layer_outputs[0]\n\n            if output_attentions:\n                all_self_attns += (layer_outputs[1],)\n\n        hidden_states = self.norm(hidden_states)\n\n        if output_hidden_states:\n            all_hidden_states += (hidden_states,)\n\n        return BaseModelOutput(\n            last_hidden_state=hidden_states,\n            hidden_states=all_hidden_states,\n            attentions=all_self_attns,\n        )\n\n\nclass AttentionPooler(AceStepPreTrainedModel):\n    \"\"\"\n    Attention-based pooling module.\n    \n    Pools sequences of patches using a special token and attention mechanism.\n    The special token attends to all patches and its output is used as the\n    pooled representation. Used for aggregating patch-level features into\n    sequence-level representations.\n    \"\"\"\n    def __init__(self, config):\n        super().__init__(config)\n        self.config = config\n        self.embed_tokens = nn.Linear(config.hidden_size, config.hidden_size)\n        self.norm = Qwen3RMSNorm(config.hidden_size, eps=config.rms_norm_eps)\n        self.rotary_emb = Qwen3RotaryEmbedding(config=config)\n        self.gradient_checkpointing = False\n        # Special token used for pooling (CLS-like token)\n        self.special_token = nn.Parameter(torch.randn(1, 1, config.hidden_size) * 0.02)\n        self.layers = nn.ModuleList(\n            [AceStepEncoderLayer(config, layer_idx) for layer_idx in range(config.num_attention_pooler_hidden_layers)]\n        )\n\n        # Initialize weights and apply final processing\n        self.post_init()\n\n    @can_return_tuple\n    def forward(self,\n        x,\n        attention_mask: Optional[torch.Tensor] = None,\n        **flash_attn_kwargs: Unpack[FlashAttentionKwargs],\n    ) -> BaseModelOutput:\n        B, T, P, D = x.shape\n        x = self.embed_tokens(x)\n        special_tokens = self.special_token.expand(B, T, 1, -1)\n        x = torch.cat([special_tokens, x], dim=2)\n        x = rearrange(x, \"b t p c -> (b t) p c\")\n\n        # Cache position: only used for mask construction.\n        cache_position = torch.arange(0, x.shape[1], device=x.device)\n        # Postional ids.\n        position_ids = cache_position.unsqueeze(0)\n\n        # embed positions\n        hidden_states = x\n\n        # create position embeddings to be shared across the decoder layers\n        position_embeddings = self.rotary_emb(hidden_states, position_ids)\n\n        seq_len = x.shape[1]\n        dtype = x.dtype\n        device = x.device\n        \n        # 判断是否使用 Flash Attention 2\n        is_flash_attn = (self.config._attn_implementation == \"flash_attention_2\")\n\n        # 初始化 Mask 变量\n        full_attn_mask = None\n        sliding_attn_mask = None\n\n        if is_flash_attn:\n            # -------------------------------------------------------\n            # 场景 A: Flash Attention 模式\n            # -------------------------------------------------------\n            # FA 不需要 4D Mask。\n            # 如果有 padding mask (attention_mask [B, L])，直接传给它即可。\n            # 如果没有 padding mask，传 None。\n            # 滑动窗口逻辑由 Layer 内部传给 FA kernel 的 sliding_window 参数控制。\n            full_attn_mask = attention_mask\n            \n            # 这里的逻辑是：如果配置启用了滑动窗口，FA 模式下我们也只需要传基础的 padding mask\n            # Layer 会自己决定是否调用带 sliding window 的 kernel\n            sliding_attn_mask = attention_mask if self.config.use_sliding_window else None\n\n        else:\n            # -------------------------------------------------------\n            # 场景 B: CPU / Mac / SDPA (Eager 模式)\n            # -------------------------------------------------------\n            # 必须手动生成 4D Mask [B, 1, L, L]\n            \n            # 1. Full Attention (Bidirectional, Global)\n            # 对应原来的 create_causal_mask + bidirectional\n            full_attn_mask = create_4d_mask(\n                seq_len=seq_len,\n                dtype=dtype,\n                device=device,\n                attention_mask=attention_mask,     # [B, L]\n                sliding_window=None,\n                is_sliding_window=False,\n                is_causal=False                    # <--- 关键：双向注意力\n            )\n\n            # 2. Sliding Attention (Bidirectional, Local)\n            # 对应原来的 create_sliding_window... + bidirectional\n            if self.config.use_sliding_window:\n                sliding_attn_mask = create_4d_mask(\n                    seq_len=seq_len,\n                    dtype=dtype,\n                    device=device,\n                    attention_mask=attention_mask, # [B, L]\n                    sliding_window=self.config.sliding_window,\n                    is_sliding_window=True,        # <--- 开启滑动窗口\n                    is_causal=False                # <--- 关键：双向注意力\n                )\n\n        # 构建 Mapping\n        self_attn_mask_mapping = {\n            \"full_attention\": full_attn_mask,\n            \"sliding_attention\": sliding_attn_mask,\n        }\n        \n        for layer_module in self.layers:\n            layer_outputs = layer_module(\n                hidden_states,\n                position_embeddings,\n                attention_mask=self_attn_mask_mapping[layer_module.attention_type],\n                **flash_attn_kwargs,\n            )\n\n            hidden_states = layer_outputs[0]\n\n        hidden_states = self.norm(hidden_states)\n        \n        # Extract the special token output (first position) as pooled representation\n        cls_output = hidden_states[:, 0, :]\n        cls_output = rearrange(cls_output, \"(b t) c -> b t c\", b=B)\n        return cls_output\n\n\nclass AudioTokenDetokenizer(AceStepPreTrainedModel):\n    \"\"\"\n    Audio token detokenizer module.\n    \n    Converts quantized audio tokens back to continuous acoustic representations.\n    Expands each token into multiple patches using special tokens, processes them\n    through encoder layers, and projects to acoustic hidden dimension.\n    \"\"\"\n    def __init__(self, config):\n        super().__init__(config)\n        self.config = config\n        self.embed_tokens = nn.Linear(config.hidden_size, config.hidden_size)\n        self.norm = Qwen3RMSNorm(config.hidden_size, eps=config.rms_norm_eps)\n        self.rotary_emb = Qwen3RotaryEmbedding(config=config)\n        self.gradient_checkpointing = False\n        # Special tokens for expanding each quantized token into patches\n        self.special_tokens = nn.Parameter(torch.randn(1, config.pool_window_size, config.hidden_size) * 0.02)\n        self.layers = nn.ModuleList(\n            [AceStepEncoderLayer(config, layer_idx) for layer_idx in range(config.num_attention_pooler_hidden_layers)]\n        )\n        # Project back to acoustic hidden dimension\n        self.proj_out = nn.Linear(config.hidden_size, config.audio_acoustic_hidden_dim)\n\n        # Initialize weights and apply final processing\n        self.post_init()\n\n    @can_return_tuple\n    def forward(self,\n        x,\n        attention_mask: Optional[torch.Tensor] = None,\n        **flash_attn_kwargs: Unpack[FlashAttentionKwargs],\n    ) -> BaseModelOutput:\n        B, T, D = x.shape\n        x = self.embed_tokens(x)\n        # Expand and add special tokens: N x T x D -> N x T x P x D\n        # Each token is expanded into pool_window_size patches\n        x = x.unsqueeze(2)  # N x T x 1 x D\n        x = x.repeat(1, 1, self.config.pool_window_size, 1)  # N x T x P x D\n        # Add learnable special tokens to each patch\n        special_tokens = self.special_tokens.expand(B, T, -1, -1)\n        x = x + special_tokens\n        # Reshape for processing: (batch * time) x patches x hidden\n        x = rearrange(x, \"b t p c -> (b t) p c\")\n\n        # Cache position: only used for mask construction\n        cache_position = torch.arange(0, x.shape[1], device=x.device)\n        # Positional IDs\n        position_ids = cache_position.unsqueeze(0)\n\n        # Initialize hidden states\n        hidden_states = x\n\n        # Create position embeddings to be shared across all layers\n        position_embeddings = self.rotary_emb(hidden_states, position_ids)\n\n        seq_len = x.shape[1]\n        dtype = x.dtype\n        device = x.device\n        \n        # 判断是否使用 Flash Attention 2\n        is_flash_attn = (self.config._attn_implementation == \"flash_attention_2\")\n\n        # 初始化 Mask 变量\n        full_attn_mask = None\n        sliding_attn_mask = None\n\n        if is_flash_attn:\n            # -------------------------------------------------------\n            # 场景 A: Flash Attention 模式\n            # -------------------------------------------------------\n            # FA 不需要 4D Mask。\n            # 如果有 padding mask (attention_mask [B, L])，直接传给它即可。\n            # 如果没有 padding mask，传 None。\n            # 滑动窗口逻辑由 Layer 内部传给 FA kernel 的 sliding_window 参数控制。\n            full_attn_mask = attention_mask\n            \n            # 这里的逻辑是：如果配置启用了滑动窗口，FA 模式下我们也只需要传基础的 padding mask\n            # Layer 会自己决定是否调用带 sliding window 的 kernel\n            sliding_attn_mask = attention_mask if self.config.use_sliding_window else None\n\n        else:\n            # -------------------------------------------------------\n            # 场景 B: CPU / Mac / SDPA (Eager 模式)\n            # -------------------------------------------------------\n            # 必须手动生成 4D Mask [B, 1, L, L]\n            \n            # 1. Full Attention (Bidirectional, Global)\n            # 对应原来的 create_causal_mask + bidirectional\n            full_attn_mask = create_4d_mask(\n                seq_len=seq_len,\n                dtype=dtype,\n                device=device,\n                attention_mask=attention_mask,     # [B, L]\n                sliding_window=None,\n                is_sliding_window=False,\n                is_causal=False                    # <--- 关键：双向注意力\n            )\n\n            # 2. Sliding Attention (Bidirectional, Local)\n            # 对应原来的 create_sliding_window... + bidirectional\n            if self.config.use_sliding_window:\n                sliding_attn_mask = create_4d_mask(\n                    seq_len=seq_len,\n                    dtype=dtype,\n                    device=device,\n                    attention_mask=attention_mask, # [B, L]\n                    sliding_window=self.config.sliding_window,\n                    is_sliding_window=True,        # <--- 开启滑动窗口\n                    is_causal=False                # <--- 关键：双向注意力\n                )\n\n        # 构建 Mapping\n        self_attn_mask_mapping = {\n            \"full_attention\": full_attn_mask,\n            \"sliding_attention\": sliding_attn_mask,\n        }\n        \n        for layer_module in self.layers:\n            layer_outputs = layer_module(\n                hidden_states,\n                position_embeddings,\n                attention_mask=self_attn_mask_mapping[layer_module.attention_type],\n                **flash_attn_kwargs,\n            )\n\n            hidden_states = layer_outputs[0]\n\n        hidden_states = self.norm(hidden_states)\n        \n        hidden_states = self.proj_out(hidden_states)\n\n        hidden_states = rearrange(hidden_states, \"(b t) p c -> b (t p) c\", b=B, p=self.config.pool_window_size)\n        return hidden_states\n\n\nclass AceStepTimbreEncoder(AceStepPreTrainedModel):\n    \"\"\"\n    Encoder for extracting timbre embeddings from reference audio.\n    \n    Processes packed reference audio acoustic features to extract timbre\n    representations. Uses a special token (CLS-like) to aggregate information\n    from the entire reference audio sequence. Outputs are unpacked back to\n    batch format for use in conditioning.\n    \"\"\"\n    def __init__(self, config):\n        super().__init__(config)\n        \n        # Project acoustic features to model hidden size\n        self.embed_tokens = nn.Linear(config.timbre_hidden_dim, config.hidden_size)\n        self.norm = Qwen3RMSNorm(config.hidden_size, eps=config.rms_norm_eps)\n        self.rotary_emb = Qwen3RotaryEmbedding(config=config)\n        self.gradient_checkpointing = False\n        # Special token for aggregating timbre information (prepended to sequence)\n        self.special_token = nn.Parameter(torch.randn(1, 1, config.hidden_size))\n        self.layers = nn.ModuleList(\n            [AceStepEncoderLayer(config, layer_idx) for layer_idx in range(config.num_timbre_encoder_hidden_layers)]\n        )\n\n        # Initialize weights and apply final processing\n        self.post_init()\n\n    def unpack_timbre_embeddings(self, timbre_embs_packed, refer_audio_order_mask):\n        \"\"\"\n        Unpack packed timbre embeddings into batch format.\n\n        Args:\n            timbre_embs_packed: Packed timbre embeddings of shape [N, d]\n            refer_audio_order_mask: Order mask indicating batch assignment for each packed embedding\n\n        Returns:\n            Tuple of (unpacked_embeddings, mask):\n            - unpacked_embeddings: Unpacked embeddings of shape [B, max_count, d]\n            - new_mask: Mask indicating valid positions, shape [B, max_count]\n        \"\"\"\n        N, d = timbre_embs_packed.shape\n        device = timbre_embs_packed.device\n        dtype = timbre_embs_packed.dtype\n        \n        # Get batch size\n        B = int(refer_audio_order_mask.max().item() + 1)\n        \n        # Calculate element count and positions for each batch\n        counts = torch.bincount(refer_audio_order_mask, minlength=B)\n        max_count = counts.max().item()\n        \n        # Calculate positions within batch\n        sorted_indices = torch.argsort(refer_audio_order_mask * N + torch.arange(N, device=device), stable=True)\n        sorted_batch_ids = refer_audio_order_mask[sorted_indices]\n        \n        positions = torch.arange(N, device=device)\n        batch_starts = torch.cat([torch.tensor([0], device=device), \n                                torch.cumsum(counts, dim=0)[:-1]])\n        positions_in_sorted = positions - batch_starts[sorted_batch_ids]\n        \n        inverse_indices = torch.empty_like(sorted_indices)\n        inverse_indices[sorted_indices] = torch.arange(N, device=device)\n        positions_in_batch = positions_in_sorted[inverse_indices]\n        \n        # Use one-hot encoding and matrix multiplication (gradient-friendly approach)\n        # Create one-hot encoding\n        indices_2d = refer_audio_order_mask * max_count + positions_in_batch  # (N,)\n        one_hot = F.one_hot(indices_2d, num_classes=B * max_count).to(dtype)  # (N, B*max_count)\n        \n        # Rearrange using matrix multiplication\n        timbre_embs_flat = one_hot.t() @ timbre_embs_packed  # (B*max_count, d)\n        timbre_embs_unpack = timbre_embs_flat.reshape(B, max_count, d)\n        \n        # Create mask indicating valid positions\n        mask_flat = (one_hot.sum(dim=0) > 0).long()  # (B*max_count,)\n        new_mask = mask_flat.reshape(B, max_count)\n        \n        return timbre_embs_unpack, new_mask\n\n    @can_return_tuple\n    def forward(\n        self,\n        refer_audio_acoustic_hidden_states_packed: Optional[torch.FloatTensor] = None,\n        refer_audio_order_mask: Optional[torch.LongTensor] = None,\n        attention_mask: Optional[torch.Tensor] = None,\n        **flash_attn_kwargs: Unpack[FlashAttentionKwargs],\n    ) -> BaseModelOutput:\n        inputs_embeds = refer_audio_acoustic_hidden_states_packed\n        # Project embeddings: N x T x timbre_hidden_dim -> N x T x hidden_size\n        inputs_embeds = self.embed_tokens(inputs_embeds)\n        # Prepend special token for timbre aggregation (CLS-like token)\n        # inputs_embeds = torch.cat([self.special_token.expand(inputs_embeds.shape[0], 1, -1), inputs_embeds], dim=1)\n        # Cache position: only used for mask construction (not for actual caching)\n        cache_position = torch.arange(0, inputs_embeds.shape[1], device=inputs_embeds.device)\n        # Positional IDs\n        position_ids = cache_position.unsqueeze(0)\n\n        seq_len = inputs_embeds.shape[1]\n        dtype = inputs_embeds.dtype\n        device = inputs_embeds.device\n        \n        # 判断是否使用 Flash Attention 2\n        is_flash_attn = (self.config._attn_implementation == \"flash_attention_2\")\n\n        # 初始化 Mask 变量\n        full_attn_mask = None\n        sliding_attn_mask = None\n\n        if is_flash_attn:\n            # -------------------------------------------------------\n            # 场景 A: Flash Attention 模式\n            # -------------------------------------------------------\n            # FA 不需要 4D Mask。\n            # 如果有 padding mask (attention_mask [B, L])，直接传给它即可。\n            # 如果没有 padding mask，传 None。\n            # 滑动窗口逻辑由 Layer 内部传给 FA kernel 的 sliding_window 参数控制。\n            full_attn_mask = attention_mask\n            \n            # 这里的逻辑是：如果配置启用了滑动窗口，FA 模式下我们也只需要传基础的 padding mask\n            # Layer 会自己决定是否调用带 sliding window 的 kernel\n            sliding_attn_mask = attention_mask if self.config.use_sliding_window else None\n\n        else:\n            # -------------------------------------------------------\n            # 场景 B: CPU / Mac / SDPA (Eager 模式)\n            # -------------------------------------------------------\n            # 必须手动生成 4D Mask [B, 1, L, L]\n            \n            # 1. Full Attention (Bidirectional, Global)\n            # 对应原来的 create_causal_mask + bidirectional\n            full_attn_mask = create_4d_mask(\n                seq_len=seq_len,\n                dtype=dtype,\n                device=device,\n                attention_mask=attention_mask,     # [B, L]\n                sliding_window=None,\n                is_sliding_window=False,\n                is_causal=False                    # <--- 关键：双向注意力\n            )\n\n            # 2. Sliding Attention (Bidirectional, Local)\n            # 对应原来的 create_sliding_window... + bidirectional\n            if self.config.use_sliding_window:\n                sliding_attn_mask = create_4d_mask(\n                    seq_len=seq_len,\n                    dtype=dtype,\n                    device=device,\n                    attention_mask=attention_mask, # [B, L]\n                    sliding_window=self.config.sliding_window,\n                    is_sliding_window=True,        # <--- 开启滑动窗口\n                    is_causal=False                # <--- 关键：双向注意力\n                )\n\n        # 构建 Mapping\n        self_attn_mask_mapping = {\n            \"full_attention\": full_attn_mask,\n            \"sliding_attention\": sliding_attn_mask,\n        }\n        \n        # Initialize hidden states\n        hidden_states = inputs_embeds\n\n        # Create position embeddings to be shared across all layers\n        position_embeddings = self.rotary_emb(hidden_states, position_ids)\n\n        # Pass through transformer layers\n        for layer_module in self.layers[: self.config.num_hidden_layers]:\n            layer_outputs = layer_module(\n                hidden_states,\n                position_embeddings,\n                self_attn_mask_mapping[layer_module.attention_type],\n                position_ids,\n                **flash_attn_kwargs,\n            )\n\n            hidden_states = layer_outputs[0]\n\n        hidden_states = self.norm(hidden_states)\n        # Extract special token output (first position) as timbre embedding: N x T x D -> N x D\n        hidden_states = hidden_states[:, 0, :]\n        # Unpack packed embeddings back to batch format\n        timbre_embs_unpack, timbre_embs_mask = self.unpack_timbre_embeddings(hidden_states, refer_audio_order_mask)\n        return timbre_embs_unpack, timbre_embs_mask\n\n\nclass AceStepAudioTokenizer(AceStepPreTrainedModel):\n    \"\"\"\n    Audio tokenizer module.\n    \n    Converts continuous acoustic features into discrete quantized tokens.\n    Process: project -> pool patches -> quantize. Used for converting audio\n    representations into discrete tokens for processing by the diffusion model.\n    \"\"\"\n    def __init__(self, config):\n        super().__init__(config)\n        # Project acoustic features to hidden size\n        self.audio_acoustic_proj = nn.Linear(config.audio_acoustic_hidden_dim, config.hidden_size)\n        # Pool patches into sequence-level representations\n        self.attention_pooler = AttentionPooler(config)\n        # Quantize continuous representations into discrete tokens\n        self.quantizer = ResidualFSQ(\n            dim=config.fsq_dim,\n            levels=config.fsq_input_levels,\n            num_quantizers=config.fsq_input_num_quantizers\n        )\n        self.pool_window_size = config.pool_window_size\n        # Initialize weights and apply final processing\n        self.post_init()\n\n    @can_return_tuple\n    def forward(\n        self,\n        hidden_states: Optional[torch.FloatTensor] = None,\n        **flash_attn_kwargs: Unpack[FlashAttentionKwargs],\n    ) -> BaseModelOutput:\n        \n        # Project acoustic features to hidden size\n        hidden_states = self.audio_acoustic_proj(hidden_states)\n        # Pool sequences: N x T//pool_window_size x pool_window_size x d -> N x T//pool_window_size x d\n        hidden_states = self.attention_pooler(hidden_states)\n        # Quantize continuous representations into discrete tokens: N x T//pool_window_size x d\n        quantized, indices = self.quantizer(hidden_states)\n        return quantized, indices\n\n    def tokenize(self, x):\n        x = rearrange(x, 'n (t_patch p) d -> n t_patch p d', p=self.pool_window_size)\n        quantized, indices = self.forward(x)\n        return quantized, indices\n\nclass Lambda(nn.Module):\n    \"\"\"\n    Wrapper module for arbitrary lambda functions.\n    \n    Allows using lambda functions in nn.Sequential by wrapping them in a Module.\n    Useful for simple transformations like transpose operations.\n    \"\"\"\n    def __init__(self, func):\n        super().__init__()\n        self.func = func\n    \n    def forward(self, x):\n        return self.func(x)\n\n\nclass AceStepDiTModel(AceStepPreTrainedModel):\n    \"\"\"\n    DiT (Diffusion Transformer) model for AceStep.\n    \n    Main diffusion model that generates audio latents conditioned on text, lyrics,\n    and timbre. Uses patch-based processing with transformer layers, timestep\n    conditioning, and cross-attention to encoder outputs.\n    \"\"\"\n    def __init__(self, config: AceStepConfig):\n        super().__init__(config)\n        # Rotary position embeddings for transformer layers\n        self.rotary_emb = Qwen3RotaryEmbedding(config)\n        # Stack of DiT transformer layers\n        self.layers = nn.ModuleList(\n            [AceStepDiTLayer(config, layer_idx) for layer_idx in range(config.num_hidden_layers)]\n        )\n\n        in_channels = config.in_channels\n        inner_dim = config.hidden_size\n        patch_size = config.patch_size\n        self.patch_size = patch_size\n        \n        # Input projection: patch embedding using 1D convolution\n        # Converts sequence into patches for efficient processing\n        self.proj_in = nn.Sequential(\n            Lambda(lambda x: x.transpose(1, 2)),  # [B, T, C] -> [B, C, T]\n            nn.Conv1d(\n                in_channels=in_channels,\n                out_channels=inner_dim,\n                kernel_size=patch_size,\n                stride=patch_size,\n                padding=0,\n            ),\n            Lambda(lambda x: x.transpose(1, 2)),  # [B, C, T//patch_size] -> [B, T//patch_size, C]\n        )\n\n        # Timestep embeddings for diffusion conditioning\n        # Two embeddings: one for timestep t, one for timestep difference (t - r)\n        self.time_embed = TimestepEmbedding(in_channels=256, time_embed_dim=inner_dim)\n        self.time_embed_r = TimestepEmbedding(in_channels=256, time_embed_dim=inner_dim)\n        \n        # Project encoder hidden states to model dimension\n        self.condition_embedder = nn.Linear(inner_dim, inner_dim, bias=True)\n\n        # Output normalization and projection\n        # Adaptive layer norm with scale-shift modulation, then de-patchify\n        self.norm_out = Qwen3RMSNorm(inner_dim, eps=config.rms_norm_eps)\n        self.proj_out = nn.Sequential(\n            Lambda(lambda x: x.transpose(1, 2)),  # [B, T//patch_size, inner_dim] -> [B, inner_dim, T//patch_size]\n            nn.ConvTranspose1d(\n                in_channels=inner_dim,\n                out_channels=config.audio_acoustic_hidden_dim,\n                kernel_size=patch_size,\n                stride=patch_size,\n                padding=0,\n            ),\n            Lambda(lambda x: x.transpose(1, 2)),  # [B, out_channels, T] -> [B, T, out_channels]\n        )\n        # Scale-shift table for adaptive output normalization (2 values: shift, scale)\n        self.scale_shift_table = nn.Parameter(torch.randn(1, 2, inner_dim) / inner_dim**0.5)\n\n        self.gradient_checkpointing = False\n\n    def forward(\n        self,\n        hidden_states: torch.Tensor,\n        timestep: torch.Tensor,\n        timestep_r: torch.Tensor,\n        attention_mask: torch.Tensor,\n        encoder_hidden_states: torch.Tensor,\n        encoder_attention_mask: torch.Tensor,\n        context_latents: torch.Tensor,\n        use_cache: Optional[bool] = None,\n        past_key_values: Optional[EncoderDecoderCache] = None,\n        cache_position: Optional[torch.LongTensor] = None,\n        position_ids: Optional[torch.LongTensor] = None,\n        output_attentions: Optional[bool] = False,\n        return_hidden_states: int = None,\n        custom_layers_config: Optional[dict] = None,\n        enable_early_exit: bool = False,\n        **flash_attn_kwargs: Unpack[FlashAttentionKwargs],\n    ):\n\n        use_cache = use_cache if use_cache is not None else self.config.use_cache\n\n        # Disable cache during training or when gradient checkpointing is enabled\n        if self.gradient_checkpointing and self.training and use_cache:\n            logger.warning_once(\n                \"`use_cache=True` is incompatible with gradient checkpointing. Setting `use_cache=False`.\"\n            )\n            use_cache = False\n        if self.training:\n            use_cache = False\n    \n        # Initialize cache if needed (only during inference for auto-regressive generation)\n        if not self.training and use_cache and past_key_values is None:\n            past_key_values = EncoderDecoderCache(DynamicCache(), DynamicCache())\n\n        # Compute timestep embeddings for diffusion conditioning\n        # Two embeddings: one for timestep t, one for timestep difference (t - r)\n        temb_t, timestep_proj_t = self.time_embed(timestep)\n        temb_r, timestep_proj_r = self.time_embed_r(timestep - timestep_r)\n        # Combine embeddings\n        temb = temb_t + temb_r\n        timestep_proj = timestep_proj_t + timestep_proj_r\n\n        # Concatenate context latents (source latents + chunk masks) with hidden states\n        hidden_states = torch.cat([context_latents, hidden_states], dim=-1)\n        # Record original sequence length for later restoration after padding\n        original_seq_len = hidden_states.shape[1]\n        # Apply padding if sequence length is not divisible by patch_size\n        # This ensures proper patch extraction\n        pad_length = 0\n        if hidden_states.shape[1] % self.patch_size != 0:\n            pad_length = self.patch_size - (hidden_states.shape[1] % self.patch_size)\n            hidden_states = F.pad(hidden_states, (0, 0, 0, pad_length), mode='constant', value=0)\n\n        # Project input to patches and project encoder states\n        hidden_states = self.proj_in(hidden_states)\n        encoder_hidden_states = self.condition_embedder(encoder_hidden_states)\n        \n        # Cache positions\n        if cache_position is None:\n            past_seen_tokens = past_key_values.get_seq_length() if past_key_values is not None else 0\n            cache_position = torch.arange(\n                past_seen_tokens, past_seen_tokens + hidden_states.shape[1], device=hidden_states.device\n            )\n        \n        # Position IDs\n        if position_ids is None:\n            position_ids = cache_position.unsqueeze(0)\n\n\n        seq_len = hidden_states.shape[1]\n        encoder_seq_len = encoder_hidden_states.shape[1]\n        dtype = hidden_states.dtype\n        device = hidden_states.device\n        \n        # 判断是否使用 Flash Attention 2\n        is_flash_attn = (self.config._attn_implementation == \"flash_attention_2\")\n\n        # 初始化 Mask 变量\n        full_attn_mask = None\n        sliding_attn_mask = None\n        encoder_attention_mask = None\n        attention_mask = None\n        if is_flash_attn:\n            # -------------------------------------------------------\n            # 场景 A: Flash Attention 模式\n            # -------------------------------------------------------\n            # FA 不需要 4D Mask。\n            # 如果有 padding mask (attention_mask [B, L])，直接传给它即可。\n            # 如果没有 padding mask，传 None。\n            # 滑动窗口逻辑由 Layer 内部传给 FA kernel 的 sliding_window 参数控制。\n            full_attn_mask = attention_mask\n            \n            # 这里的逻辑是：如果配置启用了滑动窗口，FA 模式下我们也只需要传基础的 padding mask\n            # Layer 会自己决定是否调用带 sliding window 的 kernel\n            sliding_attn_mask = attention_mask if self.config.use_sliding_window else None\n\n        else:\n            # -------------------------------------------------------\n            # 场景 B: CPU / Mac / SDPA (Eager 模式)\n            # -------------------------------------------------------\n            # 必须手动生成 4D Mask [B, 1, L, L]\n            \n            # 1. Full Attention (Bidirectional, Global)\n            # 对应原来的 create_causal_mask + bidirectional\n            full_attn_mask = create_4d_mask(\n                seq_len=seq_len,\n                dtype=dtype,\n                device=device,\n                attention_mask=attention_mask,     # [B, L]\n                sliding_window=None,\n                is_sliding_window=False,\n                is_causal=False                    # <--- 关键：双向注意力\n            )\n            max_len = max(seq_len, encoder_seq_len)\n            \n            encoder_attention_mask = create_4d_mask(\n                seq_len=max_len,\n                dtype=dtype,\n                device=device,\n                attention_mask=attention_mask,     # [B, L]\n                sliding_window=None,\n                is_sliding_window=False,\n                is_causal=False                    # <--- 关键：双向注意力\n            )\n            encoder_attention_mask = encoder_attention_mask[:, :, :seq_len, :encoder_seq_len]\n            # 2. Sliding Attention (Bidirectional, Local)\n            # 对应原来的 create_sliding_window... + bidirectional\n            if self.config.use_sliding_window:\n                sliding_attn_mask = create_4d_mask(\n                    seq_len=seq_len,\n                    dtype=dtype,\n                    device=device,\n                    attention_mask=attention_mask, # [B, L]\n                    sliding_window=self.config.sliding_window,\n                    is_sliding_window=True,        # <--- 开启滑动窗口\n                    is_causal=False                # <--- 关键：双向注意力\n                )\n\n        # 构建 Mapping\n        self_attn_mask_mapping = {\n            \"full_attention\": full_attn_mask,\n            \"sliding_attention\": sliding_attn_mask,\n            \"encoder_attention_mask\": encoder_attention_mask,\n        }\n\n        # Create position embeddings to be shared across all decoder layers\n        position_embeddings = self.rotary_emb(hidden_states, position_ids)\n        all_cross_attentions = () if output_attentions else None\n\n        # Handle early exit for custom layer configurations\n        max_needed_layer = float('inf')\n        if custom_layers_config is not None and enable_early_exit:\n            max_needed_layer = max(custom_layers_config.keys())\n            # Force output_attentions to True when early exit is enabled for attention extraction\n            output_attentions = True\n            if all_cross_attentions is None:\n                all_cross_attentions = ()\n\n        # Process through transformer layers\n        for index_block, layer_module in enumerate(self.layers):\n\n            layer_outputs = layer_module(\n                hidden_states,\n                position_embeddings,\n                timestep_proj,\n                self_attn_mask_mapping[layer_module.attention_type],\n                position_ids,\n                past_key_values,\n                output_attentions,\n                use_cache,\n                cache_position,\n                encoder_hidden_states,\n                self_attn_mask_mapping[\"encoder_attention_mask\"],\n                **flash_attn_kwargs,\n            )\n            hidden_states = layer_outputs[0]\n\n            if output_attentions and self.layers[index_block].use_cross_attention:\n                # layer_outputs structure: (hidden_states, self_attn_weights, cross_attn_weights)\n                # Extract the last element which is cross_attn_weights\n                if len(layer_outputs) >= 3:\n                    all_cross_attentions += (layer_outputs[2],)\n        \n        if return_hidden_states:\n            return hidden_states\n\n        # Extract scale-shift parameters for adaptive output normalization\n        shift, scale = (self.scale_shift_table + temb.unsqueeze(1)).chunk(2, dim=1)\n        shift = shift.to(hidden_states.device)\n        scale = scale.to(hidden_states.device)\n\n        # Apply adaptive layer norm: norm(x) * (1 + scale) + shift\n        hidden_states = (self.norm_out(hidden_states) * (1 + scale) + shift).type_as(hidden_states)\n        # Project output: de-patchify back to original sequence format\n        hidden_states = self.proj_out(hidden_states)\n        \n        # Crop back to original sequence length to ensure exact length match (remove padding)\n        hidden_states = hidden_states[:, :original_seq_len, :]\n        \n        outputs = (hidden_states, past_key_values)\n\n        if output_attentions:\n            outputs += (all_cross_attentions,)\n        return outputs\n\nclass AceStepConditionEncoder(AceStepPreTrainedModel):\n    \"\"\"\n    Condition encoder for AceStep model.\n    \n    Encodes multiple conditioning inputs (text, lyrics, timbre) and packs them\n    into a single sequence for cross-attention in the diffusion model. Handles\n    projection, encoding, and sequence packing.\n    \"\"\"\n    def __init__(self, config: AceStepConfig):\n        super().__init__(config)\n        self.config = config\n        # Project text embeddings to model hidden size\n        self.text_projector = nn.Linear(config.text_hidden_dim, config.hidden_size, bias=False)\n        # Encoder for lyric text\n        self.lyric_encoder = AceStepLyricEncoder(config)\n        # Encoder for timbre from reference audio\n        self.timbre_encoder = AceStepTimbreEncoder(config)\n\n    def forward(\n        self,\n        # Text inputs\n        text_hidden_states: Optional[torch.FloatTensor] = None,\n        text_attention_mask: Optional[torch.Tensor] = None,\n        # Lyric inputs\n        lyric_hidden_states: Optional[torch.LongTensor] = None,\n        lyric_attention_mask: Optional[torch.Tensor] = None,\n        # Reference audio for timbre\n        refer_audio_acoustic_hidden_states_packed: Optional[torch.Tensor] = None,\n        refer_audio_order_mask: Optional[torch.LongTensor] = None,\n    ):\n        # Project and encode text\n        text_hidden_states = self.text_projector(text_hidden_states)\n        # Encode lyrics\n        lyric_encoder_outputs = self.lyric_encoder(\n            inputs_embeds=lyric_hidden_states,\n            attention_mask=lyric_attention_mask,\n        )\n        lyric_hidden_states = lyric_encoder_outputs.last_hidden_state\n        # Encode timbre from reference audio\n        timbre_embs_unpack, timbre_embs_mask = self.timbre_encoder(refer_audio_acoustic_hidden_states_packed, refer_audio_order_mask)\n\n        # Pack sequences: combine lyrics and timbre, then add text\n        # This creates a single sequence with all conditioning information\n        encoder_hidden_states, encoder_attention_mask = pack_sequences(lyric_hidden_states, timbre_embs_unpack, lyric_attention_mask, timbre_embs_mask)\n        encoder_hidden_states, encoder_attention_mask = pack_sequences(encoder_hidden_states, text_hidden_states, encoder_attention_mask, text_attention_mask)\n        return encoder_hidden_states, encoder_attention_mask\n\n\ndef _repaint_step_injection(xt, clean_src, mask, t_next, noise):\n    \"\"\"Replace non-repaint regions of *xt* with noised source latents.\"\"\"\n    zt = t_next * noise + (1.0 - t_next) * clean_src\n    m = mask.unsqueeze(-1).expand_as(xt)\n    return torch.where(m, xt, zt)\n\n\ndef _repaint_boundary_blend(x_gen, clean_src, mask, cf_frames):\n    \"\"\"Blend generated latents with source at repaint boundaries.\"\"\"\n    soft = mask.float().clone()\n    if cf_frames <= 0:\n        m = soft.unsqueeze(-1).expand_as(x_gen)\n        return m * x_gen + (1.0 - m) * clean_src\n    B, T = mask.shape\n    for b in range(B):\n        row = mask[b]\n        if row.all() or not row.any():\n            continue\n        idx = torch.nonzero(row, as_tuple=False).squeeze(-1)\n        if idx.numel() == 0:\n            continue\n        left, right = idx[0].item(), idx[-1].item() + 1\n        fs = max(left - cf_frames, 0)\n        if left - fs > 0:\n            soft[b, fs:left] = torch.linspace(0, 1, left - fs + 2, device=soft.device)[1:-1]\n        fe = min(right + cf_frames, T)\n        if fe - right > 0:\n            soft[b, right:fe] = torch.linspace(1, 0, fe - right + 2, device=soft.device)[1:-1]\n    m = soft.unsqueeze(-1).expand_as(x_gen)\n    return m * x_gen + (1.0 - m) * clean_src\n\n\nclass AceStepConditionGenerationModel(AceStepPreTrainedModel):\n    \"\"\"\n    Main conditional generation model for AceStep.\n    \n    End-to-end model for generating audio conditioned on text, lyrics, and timbre.\n    Combines encoder (for conditioning), decoder (diffusion model), tokenizer\n    (for discrete tokenization), and detokenizer (for reconstruction).\n    Supports flow matching training and inference with various sampling methods.\n    \"\"\"\n    def __init__(self, config: AceStepConfig):\n        super().__init__(config)\n        self.config = config\n        # Diffusion model components\n        self.decoder = AceStepDiTModel(config)  # Main diffusion transformer\n        self.encoder = AceStepConditionEncoder(config)  # Condition encoder\n        self.tokenizer = AceStepAudioTokenizer(config)  # Audio tokenizer\n        self.detokenizer = AudioTokenDetokenizer(config)  # Audio detokenizer\n        # Null condition embedding for classifier-free guidance\n        self.null_condition_emb = nn.Parameter(torch.randn(1, 1, config.hidden_size))\n\n        # Initialize weights and apply final processing\n        self.post_init()\n\n    def tokenize(self, x, silence_latent, attention_mask):\n        if x.shape[1] % self.config.pool_window_size != 0:\n            pad_len = self.config.pool_window_size - (x.shape[1] % self.config.pool_window_size)\n            x = torch.cat([x,  silence_latent[:1,:pad_len].repeat(x.shape[0],1,1)], dim=1)\n            attention_mask = F.pad(attention_mask, (0, pad_len), mode='constant', value=0)\n        x = rearrange(x, 'n (t_patch p) d -> n t_patch p d', p=self.config.pool_window_size)\n        seq_len = x.shape[1]\n        chunk = math.ceil(attention_mask.shape[1] / seq_len)\n        attention_mask = attention_mask.to(x.dtype)\n        attention_mask = F.max_pool1d(attention_mask.unsqueeze(1), kernel_size=chunk, stride=chunk, ceil_mode=True).squeeze(1)\n        quantized, indices = self.tokenizer(x)\n        return quantized, indices, attention_mask\n\n    def detokenize(self, quantized):\n        \"\"\"\n        Detokenize quantized audio tokens back to continuous representations.\n\n        Args:\n            quantized: Quantized tokens of shape [N, T//pool_window_size, d]\n\n        Returns:\n            Detokenized hidden states of shape [N, T, d]\n        \"\"\"\n        hidden_states = self.detokenizer(quantized)\n        return hidden_states\n\n    @torch.no_grad()\n    def prepare_condition(\n        self,\n        text_hidden_states: torch.FloatTensor,\n        text_attention_mask: torch.Tensor,\n        lyric_hidden_states: torch.FloatTensor,\n        lyric_attention_mask: torch.Tensor,\n        refer_audio_acoustic_hidden_states_packed: torch.FloatTensor,\n        refer_audio_order_mask: torch.Tensor,\n        hidden_states: torch.FloatTensor,\n        attention_mask: torch.Tensor,\n        silence_latent: torch.FloatTensor,\n        src_latents: torch.FloatTensor,\n        chunk_masks: torch.Tensor,\n        is_covers: torch.Tensor,\n        precomputed_lm_hints_25Hz: Optional[torch.FloatTensor] = None,\n        audio_codes: torch.FloatTensor = None,\n    ):\n        \n        dtype = hidden_states.dtype\n        encoder_hidden_states, encoder_attention_mask = self.encoder(\n            text_hidden_states=text_hidden_states,\n            text_attention_mask=text_attention_mask,\n            lyric_hidden_states=lyric_hidden_states,\n            lyric_attention_mask=lyric_attention_mask,\n            refer_audio_acoustic_hidden_states_packed=refer_audio_acoustic_hidden_states_packed,\n            refer_audio_order_mask=refer_audio_order_mask,\n        )\n\n        # N x T x d -> N x T//pool_window_size x pool_window_size x d\n        # tokenize and detokenize to get LM hints for cover songs (when is_covers=True)\n        # Use precomputed hints if provided (e.g., from audio codes), otherwise tokenize hidden_states\n        if precomputed_lm_hints_25Hz is not None:\n            print(\"Using precomputed LM hints\")\n            lm_hints_25Hz = precomputed_lm_hints_25Hz[:, :src_latents.shape[1], :]\n        else:\n            if audio_codes is not None:\n                lm_hints_5Hz = self.tokenize.quantizer.get_output_from_indices(audio_codes)\n            else:\n                lm_hints_5Hz, indices, llm_mask = self.tokenize(hidden_states, silence_latent, attention_mask)\n            lm_hints_25Hz = self.detokenize(lm_hints_5Hz)\n            # Crop lm_hints_25Hz to match src_latents length (tokenize may have added padding)\n            lm_hints_25Hz = lm_hints_25Hz[:, :src_latents.shape[1], :]\n        src_latents = torch.where(is_covers.unsqueeze(-1).unsqueeze(-1) > 0, lm_hints_25Hz, src_latents)\n        # Concatenate source latents with chunk masks as context\n        context_latents = torch.cat([src_latents, chunk_masks.to(dtype)], dim=-1)\n        return encoder_hidden_states, encoder_attention_mask, context_latents\n\n    def forward(\n        self,\n        # Diffusion inputs\n        hidden_states: torch.FloatTensor,\n        attention_mask: torch.Tensor,\n        # Encoder inputs\n        # Text\n        text_hidden_states: Optional[torch.FloatTensor] = None,\n        text_attention_mask: Optional[torch.Tensor] = None,\n        # Lyric\n        lyric_hidden_states: Optional[torch.LongTensor] = None,\n        lyric_attention_mask: Optional[torch.Tensor] = None,\n        # Reference audio for timbre\n        refer_audio_acoustic_hidden_states_packed: Optional[torch.Tensor] = None,\n        refer_audio_order_mask: Optional[torch.LongTensor] = None,\n        src_latents: torch.FloatTensor = None,\n        chunk_masks: torch.FloatTensor = None,\n        is_covers: torch.Tensor = None,\n        silence_latent: torch.FloatTensor = None,\n        cfg_ratio: float = 0.15,\n    ):\n        \"\"\"\n        Forward pass for training (computes training losses).\n        \"\"\"\n        # Prepare conditioning inputs (encoder states, context latents)\n        encoder_hidden_states, encoder_attention_mask, context_latents = self.prepare_condition(\n            text_hidden_states=text_hidden_states,\n            text_attention_mask=text_attention_mask,\n            lyric_hidden_states=lyric_hidden_states,\n            lyric_attention_mask=lyric_attention_mask,\n            refer_audio_acoustic_hidden_states_packed=refer_audio_acoustic_hidden_states_packed,\n            refer_audio_order_mask=refer_audio_order_mask,\n            hidden_states=src_latents,\n            attention_mask=attention_mask,\n            silence_latent=silence_latent,\n            src_latents=src_latents,\n            chunk_masks=chunk_masks,\n            is_covers=is_covers,\n        )\n        bsz, device, dtype = hidden_states.shape[0], hidden_states.device, hidden_states.dtype\n        # Classifier-free guidance: randomly drop conditions with probability cfg_ratio\n        # This helps the model learn to work with and without conditions\n        full_cfg_condition_mask = torch.where(\n            (torch.rand(size=(bsz,), device=device, dtype=dtype) < cfg_ratio),\n            torch.zeros(size=(bsz,), device=device, dtype=dtype),\n            torch.ones(size=(bsz,), device=device, dtype=dtype)\n        ).view(-1, 1, 1)\n        # Replace dropped conditions with null condition embedding\n        encoder_hidden_states = torch.where(full_cfg_condition_mask > 0, encoder_hidden_states, self.null_condition_emb.expand_as(encoder_hidden_states))\n\n        # Flow matching setup: sample noise x1 and interpolate with data x0\n        x1 = torch.randn_like(hidden_states)  # Noise\n        x0 = hidden_states  # Data\n        # Sample timesteps t and r for flow matching\n        t, r = sample_t_r(bsz, device, dtype, self.config.data_proportion, self.config.timestep_mu, self.config.timestep_sigma, use_meanflow=False)\n        t_ = t.unsqueeze(-1).unsqueeze(-1)\n        # Interpolate: x_t = t * x1 + (1 - t) * x0\n        xt = t_ * x1 + (1.0 - t_) * x0\n        \n        # Predict flow (velocity) from diffusion model\n        decoder_outputs = self.decoder(\n            hidden_states=xt,\n            timestep=t,\n            timestep_r=t,\n            attention_mask=attention_mask,\n            encoder_hidden_states=encoder_hidden_states,\n            encoder_attention_mask=encoder_attention_mask,\n            context_latents=context_latents,\n        )\n        # Flow matching loss: predict the flow field v = x1 - x0\n        flow = x1 - x0\n        diffusion_loss = F.mse_loss(decoder_outputs[0], flow)\n        return {\n            \"diffusion_loss\": diffusion_loss,\n        }\n        \n    def training_losses(self, **kwargs):\n        return self.forward(**kwargs)\n    \n    def prepare_noise(self, context_latents: torch.FloatTensor, seed: Union[int, List[int], None] = None):\n        \"\"\"\n        Prepare noise tensor for generation with optional seeding.\n\n        Args:\n            context_latents: Context latents to determine noise shape\n            seed: Can be int, List[int], or None. If None, uses random noise.\n\n        Returns:\n            Noise tensor of appropriate shape\n        \"\"\"\n        bsz = context_latents.shape[0]\n        device = context_latents.device\n        dtype = context_latents.dtype\n        # Handle seed: can be int, List[int], or None\n        src_latents_shape = (context_latents.shape[0], context_latents.shape[1], context_latents.shape[-1] // 2)\n        if seed is None:\n            # No seed provided - use random\n            noise = torch.randn(src_latents_shape, device=device, dtype=dtype)\n        elif isinstance(seed, list):\n            # List of seeds - generate noise for each sample separately\n            noise_list = []\n            for i, s in enumerate(seed):\n                if s is None or s < 0:\n                    # Random seed for this sample\n                    noise_i = torch.randn(1, src_latents_shape[1], src_latents_shape[2], device=device, dtype=dtype)\n                else:\n                    # Use specific seed for this sample\n                    generator = torch.Generator(device=device).manual_seed(int(s))\n                    noise_i = torch.randn(1, src_latents_shape[1], src_latents_shape[2], generator=generator, device=device, dtype=dtype)\n                noise_list.append(noise_i)\n            noise = torch.cat(noise_list, dim=0)\n        else:\n            # Single seed for all samples\n            generator = torch.Generator(device=device).manual_seed(int(seed))\n            noise = torch.randn(src_latents_shape, generator=generator, device=device, dtype=dtype)\n\n        return noise\n\n    def get_x0_from_noise(self, zt, vt, t):\n        return zt - vt * t.unsqueeze(-1).unsqueeze(-1)\n\n    def renoise(self, x, t, noise=None):\n        if noise is None:\n            noise = torch.randn_like(x)\n        if isinstance(t, torch.Tensor) and t.ndim != x.ndim:\n            t = t.unsqueeze(-1).unsqueeze(-1)\n        xt = t * noise + (1 - t) * x\n        return xt\n    \n    def generate_audio(\n        self,\n        text_hidden_states: torch.FloatTensor,\n        text_attention_mask: torch.FloatTensor,\n        lyric_hidden_states: torch.FloatTensor,\n        lyric_attention_mask: torch.FloatTensor,\n        refer_audio_acoustic_hidden_states_packed: torch.FloatTensor,\n        refer_audio_order_mask: torch.LongTensor,\n        src_latents: torch.FloatTensor,\n        chunk_masks: torch.FloatTensor,\n        is_covers: torch.Tensor,\n        silence_latent: Optional[torch.FloatTensor] = None,\n        attention_mask: torch.Tensor = None,\n        seed: int = None,\n        fix_nfe: int = 8,\n        infer_method: str = \"ode\",\n        use_cache: bool = True,\n        audio_cover_strength: float = 1.0,\n        non_cover_text_hidden_states: Optional[torch.FloatTensor] = None,\n        non_cover_text_attention_mask: Optional[torch.FloatTensor] = None,\n        precomputed_lm_hints_25Hz: Optional[torch.FloatTensor] = None,\n        audio_codes: Optional[torch.FloatTensor] = None,\n        shift: float = 3.0,\n        timesteps: Optional[torch.Tensor] = None,\n        cover_noise_strength: float = 0.0,\n        repaint_mask: Optional[torch.Tensor] = None,\n        clean_src_latents: Optional[torch.FloatTensor] = None,\n        repaint_crossfade_frames: int = 10,\n        repaint_injection_ratio: float = 0.5,\n        **kwargs,\n    ):\n        # Valid shifts: only discrete values 1, 2, 3 are supported\n        VALID_SHIFTS = [1.0, 2.0, 3.0]\n        \n        # Valid timesteps: all unique timesteps from shift=1,2,3 with fix_nfe=8 (total 20 values)\n        VALID_TIMESTEPS = [\n            1.0, 0.9545454545454546, 0.9333333333333333, 0.9, 0.875, \n            0.8571428571428571, 0.8333333333333334, 0.7692307692307693, 0.75, \n            0.6666666666666666, 0.6428571428571429, 0.625, 0.5454545454545454, \n            0.5, 0.4, 0.375, 0.3, 0.25, 0.2222222222222222, 0.125\n        ]\n        \n        # Pre-defined timestep schedules for each valid shift (fix_nfe=8, excluding final 0)\n        SHIFT_TIMESTEPS = {\n            1.0: [1.0, 0.875, 0.75, 0.625, 0.5, 0.375, 0.25, 0.125],\n            2.0: [1.0, 0.9333333333333333, 0.8571428571428571, 0.7692307692307693, 0.6666666666666666, 0.5454545454545454, 0.4, 0.2222222222222222],\n            3.0: [1.0, 0.9545454545454546, 0.9, 0.8333333333333334, 0.75, 0.6428571428571429, 0.5, 0.3],\n        }\n        \n        # Determine the timestep schedule to use\n        t_schedule_list = None\n        \n        if timesteps is not None:\n            # Process custom timesteps: map each value to nearest valid timestep\n            timesteps_list = timesteps.tolist() if isinstance(timesteps, torch.Tensor) else list(timesteps)\n            \n            # Remove trailing zeros\n            while len(timesteps_list) > 0 and timesteps_list[-1] == 0:\n                timesteps_list.pop()\n            \n            # Validate length: 1-20\n            if len(timesteps_list) < 1:\n                logger.warning(f\"timesteps length is too short after removing trailing zeros, using default shift={shift}\")\n            elif len(timesteps_list) > 20:\n                logger.warning(f\"timesteps length={len(timesteps_list)} exceeds maximum 20, truncating to 20\")\n                timesteps_list = timesteps_list[:20]\n                t_schedule_list = timesteps_list\n            else:\n                t_schedule_list = timesteps_list\n            \n            if t_schedule_list is not None:\n                # Map each timestep to nearest valid timestep\n                original_timesteps = t_schedule_list.copy()\n                mapped_timesteps = []\n                for t in t_schedule_list:\n                    nearest = min(VALID_TIMESTEPS, key=lambda x: abs(x - t))\n                    mapped_timesteps.append(nearest)\n                \n                if original_timesteps != mapped_timesteps:\n                    logger.warning(f\"timesteps mapped to nearest valid values: {original_timesteps} -> {mapped_timesteps}\")\n                \n                t_schedule_list = mapped_timesteps\n        \n        if t_schedule_list is None:\n            # Use shift-based schedule: round to nearest valid shift\n            original_shift = shift\n            shift = min(VALID_SHIFTS, key=lambda x: abs(x - shift))\n            if original_shift != shift:\n                logger.warning(f\"shift={original_shift} not supported, rounded to nearest valid shift={shift}\")\n            t_schedule_list = SHIFT_TIMESTEPS[shift]\n        \n        if attention_mask is None:\n            latent_length = src_latents.shape[1]\n            attention_mask = torch.ones(src_latents.shape[0], latent_length, device=src_latents.device, dtype=src_latents.dtype)\n        \n        time_costs = {}\n        start_time = time.time()\n        total_start_time = start_time\n        encoder_hidden_states, encoder_attention_mask, context_latents = self.prepare_condition(\n            text_hidden_states=text_hidden_states,\n            text_attention_mask=text_attention_mask,\n            lyric_hidden_states=lyric_hidden_states,\n            lyric_attention_mask=lyric_attention_mask,\n            refer_audio_acoustic_hidden_states_packed=refer_audio_acoustic_hidden_states_packed,\n            refer_audio_order_mask=refer_audio_order_mask,\n            hidden_states=src_latents,\n            attention_mask=attention_mask,\n            silence_latent=silence_latent,\n            src_latents=src_latents,\n            chunk_masks=chunk_masks,\n            is_covers=is_covers,\n            precomputed_lm_hints_25Hz=precomputed_lm_hints_25Hz,\n            audio_codes=audio_codes,\n        )\n        \n        encoder_hidden_states_non_cover, encoder_attention_mask_non_cover, context_latents_non_cover = None, None, None\n        if audio_cover_strength < 1.0:\n            non_is_covers = torch.zeros_like(is_covers, device=is_covers.device, dtype=is_covers.dtype)\n            # Use silence_latent for non-cover condition to simulate text2music mode (no reference audio)\n            silence_latent_expanded = silence_latent[:, :src_latents.shape[1], :].expand(src_latents.shape[0], -1, -1)\n            encoder_hidden_states_non_cover, encoder_attention_mask_non_cover, context_latents_non_cover = self.prepare_condition(\n            text_hidden_states=non_cover_text_hidden_states,\n            text_attention_mask=non_cover_text_attention_mask,\n            lyric_hidden_states=lyric_hidden_states,\n            lyric_attention_mask=lyric_attention_mask,\n            refer_audio_acoustic_hidden_states_packed=refer_audio_acoustic_hidden_states_packed,\n            refer_audio_order_mask=refer_audio_order_mask,\n            hidden_states=silence_latent_expanded,\n            attention_mask=attention_mask,\n            silence_latent=silence_latent,\n            src_latents=silence_latent_expanded,\n            chunk_masks=chunk_masks,\n            is_covers=non_is_covers,\n            precomputed_lm_hints_25Hz=None,\n            audio_codes=None,\n        )\n        \n        end_time = time.time()\n        time_costs[\"encoder_time_cost\"] = end_time - start_time\n        start_time = end_time\n        \n        noise = self.prepare_noise(context_latents, seed)\n        bsz, device, dtype = context_latents.shape[0], context_latents.device, context_latents.dtype\n        past_key_values = EncoderDecoderCache(DynamicCache(), DynamicCache())\n        \n        # Cover noise initialization: blend noise with src_latents\n        if cover_noise_strength > 0.0:\n            # cover_noise_strength=1 means closest to src, so noise_level should be low\n            effective_noise_level = 1.0 - cover_noise_strength\n            # Find nearest valid timestep from t_schedule\n            nearest_t = min(t_schedule_list, key=lambda x: abs(x - effective_noise_level))\n            # xt = nearest_t * noise + (1 - nearest_t) * src_latents\n            xt = self.renoise(src_latents, nearest_t, noise)\n            # Truncate t_schedule to start from nearest_t\n            start_idx = t_schedule_list.index(nearest_t)\n            t_schedule_list = t_schedule_list[start_idx:]\n            logger.info(\n                f\"[generate_audio] Cover mode: cover_noise_strength={cover_noise_strength}, \"\n                f\"effective_noise_level={effective_noise_level:.4f}, nearest_t={nearest_t:.4f}, \"\n                f\"remaining_steps={len(t_schedule_list)}\"\n            )\n        else:\n            xt = noise\n        \n        # Use pre-computed t_schedule_list (already validated and mapped to valid timesteps)\n        t_schedule = torch.tensor(t_schedule_list, device=device, dtype=dtype)\n        num_steps = len(t_schedule)\n        \n        # Recalculate cover_steps based on actual num_steps\n        cover_steps = int(num_steps * audio_cover_strength)\n        _switched_to_non_cover = False\n        for step_idx in range(num_steps):\n            current_timestep = t_schedule[step_idx].item()\n            t_curr_tensor = current_timestep * torch.ones((bsz,), device=device, dtype=dtype)\n            \n            if step_idx >= cover_steps and not _switched_to_non_cover:\n                _switched_to_non_cover = True\n                encoder_hidden_states = encoder_hidden_states_non_cover\n                encoder_attention_mask = encoder_attention_mask_non_cover\n                context_latents = context_latents_non_cover\n                past_key_values = EncoderDecoderCache(DynamicCache(), DynamicCache())\n            \n            with torch.no_grad():        \n                decoder_outputs = self.decoder(\n                    hidden_states=xt,\n                    timestep=t_curr_tensor,\n                    timestep_r=t_curr_tensor,\n                    attention_mask=attention_mask,\n                    encoder_hidden_states=encoder_hidden_states,\n                    encoder_attention_mask=encoder_attention_mask,\n                    context_latents=context_latents,\n                    use_cache=True,\n                    past_key_values=past_key_values,\n                )\n                \n            vt = decoder_outputs[0]\n            past_key_values = decoder_outputs[1]\n            \n            # On final step, directly compute x0 from noise\n            if step_idx == num_steps - 1:\n                xt = self.get_x0_from_noise(xt, vt, t_curr_tensor)\n                break\n            \n            # Update x_t based on inference method\n            if infer_method == \"sde\":\n                # Stochastic Differential Equation: predict clean, then re-add noise\n                pred_clean = self.get_x0_from_noise(xt, vt, t_curr_tensor)\n                next_timestep = t_schedule[step_idx + 1].item()\n                xt = self.renoise(pred_clean, next_timestep)\n                t_after_step = next_timestep\n            elif infer_method == \"ode\":\n                # Ordinary Differential Equation: Euler method\n                # dx/dt = -v, so x_{t+1} = x_t - v_t * dt\n                next_timestep = t_schedule[step_idx + 1].item()\n                dt = current_timestep - next_timestep\n                dt_tensor = dt * torch.ones((bsz,), device=device, dtype=dtype).unsqueeze(-1).unsqueeze(-1)\n                xt = xt - vt * dt_tensor\n                t_after_step = next_timestep\n\n            injection_cutoff = round(repaint_injection_ratio * num_steps)\n            if repaint_mask is not None and clean_src_latents is not None and step_idx < injection_cutoff:\n                xt = _repaint_step_injection(\n                    xt, clean_src_latents, repaint_mask, t_after_step, noise,\n                )\n        \n        x_gen = xt\n        if repaint_mask is not None and clean_src_latents is not None and repaint_crossfade_frames > 0:\n            x_gen = _repaint_boundary_blend(\n                x_gen, clean_src_latents, repaint_mask, repaint_crossfade_frames,\n            )\n        end_time = time.time()\n        time_costs[\"diffusion_time_cost\"] = end_time - start_time\n        time_costs[\"diffusion_per_step_time_cost\"] = time_costs[\"diffusion_time_cost\"] / num_steps\n        time_costs[\"total_time_cost\"] = end_time - total_start_time\n        return {\n            \"target_latents\": x_gen,\n            \"time_costs\": time_costs,\n        }\n\n\ndef test_forward(model, seed=42):\n    # Fix random seed for reproducibility\n    import random\n    import numpy as np\n    random.seed(seed)\n    np.random.seed(seed)\n    torch.manual_seed(seed)\n    if torch.cuda.is_available():\n        torch.cuda.manual_seed(seed)\n        torch.cuda.manual_seed_all(seed)\n        torch.backends.cudnn.deterministic = True\n        torch.backends.cudnn.benchmark = False\n    \n    # Get model dtype and device\n    model_dtype = next(model.parameters()).dtype\n    device = next(model.parameters()).device\n    \n    print(f\"Testing with dtype: {model_dtype}, device: {device}, seed: {seed}\")\n    \n    # Test data preparation with matching dtype\n    text_hidden_states = torch.randn(2, 77, 1024, dtype=model_dtype, device=device)\n    text_attention_mask = torch.ones(2, 77, dtype=model_dtype, device=device)\n    lyric_hidden_states = torch.randn(2, 123, 1024, dtype=model_dtype, device=device)\n    lyric_attention_mask = torch.ones(2, 123, dtype=model_dtype, device=device)\n    refer_audio_acoustic_hidden_states_packed = torch.randn(3, 750, 64, dtype=model_dtype, device=device)\n    refer_audio_order_mask = torch.LongTensor([0, 0, 1]).to(device)\n\n    # Base config: 25 Hz hidden states → 10 s = 250 frames (round to int)\n    base_seconds = 10\n    frames_per_second = 25\n    base_seq_len = base_seconds * frames_per_second\n\n    hidden_states = torch.randn(2, base_seq_len, 64, dtype=model_dtype, device=device)\n    attention_mask = torch.ones(2, base_seq_len, dtype=model_dtype, device=device)\n    # Add some padding to test mask behavior\n    pad_start = max(base_seq_len // 2, 1)\n    attention_mask[0, pad_start:] = 0\n    chunk_mask = torch.ones(2, base_seq_len, 64, dtype=model_dtype, device=device)\n    chunk_mask[0, pad_start:] = 0\n\n    silence_latent = torch.randn(2, base_seq_len, 64, dtype=model_dtype, device=device)\n    # New required parameters for updated training logic\n    src_latents = torch.randn(2, base_seq_len, 64, dtype=model_dtype, device=device)  # Source latents for context\n    is_covers = torch.tensor([0, 1], dtype=torch.long, device=device)  # Cover song indicators (0=original, 1=cover)\n\n    # Test 1: Flow matching training (using 10s sequence for sanity check by default)\n    print(f\"Testing flow matching training with {base_seconds}s sequence ({base_seq_len} frames @ {frames_per_second}Hz)...\")\n    outputs = model.training_losses(\n        hidden_states=hidden_states,\n        attention_mask=attention_mask,\n        chunk_masks=chunk_mask,\n        text_hidden_states=text_hidden_states,\n        text_attention_mask=text_attention_mask,\n        lyric_hidden_states=lyric_hidden_states,\n        lyric_attention_mask=lyric_attention_mask,\n        refer_audio_acoustic_hidden_states_packed=refer_audio_acoustic_hidden_states_packed,\n        refer_audio_order_mask=refer_audio_order_mask,\n        silence_latent=silence_latent,\n        src_latents=src_latents,\n        is_covers=is_covers,\n        cfg_ratio=0.15,\n    )\n    loss = outputs['diffusion_loss']\n    print(f\"Flow matching loss: {loss.item():.6f}\")\n    print(f\"  Loss stats - min: {loss.min().item():.6f}, max: {loss.max().item():.6f}, mean: {loss.mean().item():.6f}, std: {loss.std().item() if loss.numel() > 1 else 0:.6f}\")\n\n    # Test 2: Generation with flow matching, testing throughput for different sequence lengths\n    lengths_seconds = [10, 30, 60, 120, 180, 240]\n    infer_steps = 2  # Can be increased as needed (e.g., 50/100) to better approximate real inference\n\n    print(\"\\n===== Throughput benchmark (25Hz hidden states) =====\")\n    for seconds in lengths_seconds:\n        seq_len = seconds * frames_per_second\n\n        # Reconstruct inputs for current sequence length\n        cur_hidden_states = torch.randn(2, seq_len, 64, dtype=model_dtype, device=device)\n        cur_attention_mask = torch.ones(2, seq_len, dtype=model_dtype, device=device)\n        cur_chunk_mask = torch.ones(2, seq_len, 64, dtype=model_dtype, device=device)\n        cur_silence_latent = torch.randn(2, seq_len, 64, dtype=model_dtype, device=device)\n        cur_src_latents = torch.randn(2, seq_len, 64, dtype=model_dtype, device=device)\n\n        print(f\"\\n--- {seconds}s input ({seq_len} frames @ {frames_per_second}Hz) ---\")\n        outputs = model.generate_audio(\n            text_hidden_states=text_hidden_states,\n            text_attention_mask=text_attention_mask,\n            lyric_hidden_states=lyric_hidden_states,\n            lyric_attention_mask=lyric_attention_mask,\n            refer_audio_acoustic_hidden_states_packed=refer_audio_acoustic_hidden_states_packed,\n            refer_audio_order_mask=refer_audio_order_mask,\n            src_latents=cur_src_latents,\n            chunk_masks=cur_chunk_mask,\n            silence_latent=cur_silence_latent,\n            infer_steps=infer_steps,\n            is_covers=is_covers,\n            seed=1234,\n        )\n\n        target_latents = outputs[\"target_latents\"]\n        time_costs = outputs.get(\"time_costs\", {})\n\n        total_time = time_costs.get(\"total_time_cost\", None)\n        diffusion_time = time_costs.get(\"diffusion_time_cost\", None)\n\n        # Output shape and statistics\n        print(f\"Generated latents shape: {target_latents.shape}\")\n        print(\n            f\"Stats - min: {target_latents.min().item():.4f}, \"\n            f\"max: {target_latents.max().item():.4f}, \"\n            f\"mean: {target_latents.mean().item():.4f}, \"\n            f\"std: {target_latents.std().item():.4f}\"\n        )\n\n        # Calculate throughput: statistics by frame count and audio seconds\n        bsz, t_len = target_latents.shape[0], target_latents.shape[1]\n        audio_seconds = t_len / frames_per_second\n\n        if total_time is not None:\n            frames_throughput = (bsz * t_len) / total_time\n            seconds_throughput = (bsz * audio_seconds) / total_time\n            print(\n                f\"Time costs: total={total_time:.4f}s, diffusion={diffusion_time:.4f}s \"\n                f\"({infer_steps} steps)\"\n                if diffusion_time is not None\n                else f\"Time costs: total={total_time:.4f}s\"\n            )\n            print(\n                f\"Throughput (based on total_time): \"\n                f\"{frames_throughput:.2f} frames/s, \"\n                f\"{seconds_throughput:.2f} audio-seconds/s (batch={bsz})\"\n            )\n        else:\n            print(\"Time costs not available in outputs['time_costs']; only basic stats printed.\")\n\n\nif __name__ == \"__main__\":\n    from torch.profiler import profile, record_function, ProfilerActivity\n    import os, torch\n    import time\n    from transformers import AutoModel\n    config = AceStepConfig()\n    start = time.time()\n    import os\n    model_dir = os.path.dirname(os.path.abspath(__file__))\n    model = AceStepConditionGenerationModel.from_pretrained(model_dir)\n    end = time.time()\n    # model.config._attn_implementation = \"sdpa\"\n    model.config._attn_implementation = \"flash_attention_2\"\n    model.eval()\n    # model = model.to(\"cpu\")\n    # model = model.float()\n    model = model.to(\"cuda\")\n    model = model.bfloat16()\n    test_forward(model)"
  },
  {
    "path": "acestep/null_duration_fixes_test.py",
    "content": "\"\"\"Tests for null audio_duration crash fixes (issue #797).\n\nCovers:\n  - Fix 1: CoT-generated duration feeds into Phase 2 target_duration.\n  - Fix 2: _compute_max_new_tokens caps fallback at DURATION_MAX.\n  - Fix 3: silence_latent tiling when length exceeds stored tensor.\n  - Fix 4: API-level default duration replaces -1.0 sentinel.\n\"\"\"\n\nimport unittest\nfrom types import SimpleNamespace\n\ntry:\n    import torch\n    from acestep.llm_inference import LLMHandler\n    from acestep.constants import DURATION_MAX\n    from acestep.core.generation.handler.conditioning_target import (\n        ConditioningTargetMixin,\n    )\n    from acestep.api.job_generation_setup import (\n        _API_DEFAULT_DURATION_SECONDS,\n        build_generation_setup,\n    )\n\n    _IMPORT_ERROR = None\nexcept ImportError as exc:  # pragma: no cover\n    torch = None  # type: ignore[assignment]\n    LLMHandler = None\n    ConditioningTargetMixin = None\n    DURATION_MAX = None\n    _API_DEFAULT_DURATION_SECONDS = None\n    build_generation_setup = None\n    _IMPORT_ERROR = exc\n\n\n# ---------------------------------------------------------------------------\n# Fix 2: _compute_max_new_tokens caps\n# ---------------------------------------------------------------------------\n\n@unittest.skipIf(LLMHandler is None, f\"import unavailable: {_IMPORT_ERROR}\")\nclass ComputeMaxNewTokensCapTests(unittest.TestCase):\n    \"\"\"_compute_max_new_tokens must not exceed DURATION_MAX-based cap.\"\"\"\n\n    def _handler(self, max_model_len: int = 16384) -> \"LLMHandler\":\n        h = LLMHandler()\n        h.max_model_len = max_model_len\n        return h\n\n    def test_no_duration_caps_at_duration_max(self):\n        \"\"\"Without target_duration, result must be <= DURATION_MAX*5 + 500.\"\"\"\n        h = self._handler(max_model_len=100_000)\n        tokens = h._compute_max_new_tokens(target_duration=None, generation_phase=\"codes\")\n        cap = DURATION_MAX * 5 + 500\n        self.assertLessEqual(tokens, cap)\n\n    def test_no_duration_with_fallback_caps(self):\n        \"\"\"Explicit fallback_max must also be capped at DURATION_MAX bound.\"\"\"\n        h = self._handler(max_model_len=100_000)\n        huge_fallback = 999_999\n        tokens = h._compute_max_new_tokens(\n            target_duration=None, generation_phase=\"codes\", fallback_max=huge_fallback,\n        )\n        cap = DURATION_MAX * 5 + 500\n        self.assertLessEqual(tokens, cap)\n\n    def test_with_duration_ignores_cap(self):\n        \"\"\"When target_duration is set, normal calculation should apply.\"\"\"\n        h = self._handler()\n        tokens = h._compute_max_new_tokens(target_duration=30.0, generation_phase=\"codes\")\n        # 30s * 5 codes/s + 10 buffer = 160\n        self.assertEqual(tokens, 160)\n\n\n# ---------------------------------------------------------------------------\n# Fix 3: silence_latent tiling\n# ---------------------------------------------------------------------------\n\n@unittest.skipIf(torch is None, f\"import unavailable: {_IMPORT_ERROR}\")\nclass SilenceLatentTilingTests(unittest.TestCase):\n    \"\"\"_get_silence_latent_slice must tile when length > stored tensor.\"\"\"\n\n    def _make_mixin(self, latent_len: int = 64, channels: int = 6):\n        \"\"\"Build a minimal object that satisfies the mixin's interface.\"\"\"\n\n        class _Host(ConditioningTargetMixin):\n            pass\n\n        host = _Host()\n        host.silence_latent = torch.ones(1, latent_len, channels)\n        return host, channels\n\n    def test_slice_within_bounds(self):\n        host, C = self._make_mixin(latent_len=128)\n        result = host._get_silence_latent_slice(64)\n        self.assertEqual(result.shape, (64, C))\n\n    def test_slice_exact_bounds(self):\n        host, C = self._make_mixin(latent_len=128)\n        result = host._get_silence_latent_slice(128)\n        self.assertEqual(result.shape, (128, C))\n\n    def test_slice_exceeds_bounds_tiles(self):\n        host, C = self._make_mixin(latent_len=64)\n        result = host._get_silence_latent_slice(200)\n        self.assertEqual(result.shape, (200, C))\n\n    def test_tiled_values_are_correct(self):\n        \"\"\"Tiled tensor should repeat the original values.\"\"\"\n        host, C = self._make_mixin(latent_len=3, channels=2)\n        host.silence_latent = torch.tensor([[[1.0, 2.0], [3.0, 4.0], [5.0, 6.0]]])\n        result = host._get_silence_latent_slice(7)\n        self.assertEqual(result.shape, (7, 2))\n        # First 3 frames match original\n        self.assertTrue(torch.equal(result[:3], host.silence_latent[0]))\n        # Frames 3-5 repeat\n        self.assertTrue(torch.equal(result[3:6], host.silence_latent[0]))\n\n\n# ---------------------------------------------------------------------------\n# Fix 4: API default duration\n# ---------------------------------------------------------------------------\n\n@unittest.skipIf(build_generation_setup is None, f\"import unavailable: {_IMPORT_ERROR}\")\nclass ApiDefaultDurationTests(unittest.TestCase):\n    \"\"\"build_generation_setup must use a sensible default when duration is null.\"\"\"\n\n    def _base_req(self):\n        return SimpleNamespace(\n            task_type=\"text2music\",\n            instruction=\"default instruction\",\n            reference_audio_path=\"\",\n            src_audio_path=\"\",\n            vocal_language=\"en\",\n            inference_steps=25,\n            seed=None,\n            guidance_scale=4.5,\n            use_adg=False,\n            cfg_interval_start=0.0,\n            cfg_interval_end=1.0,\n            shift=0.0,\n            infer_method=\"euler\",\n            timesteps=\"\",\n            repainting_start=0.0,\n            repainting_end=-1,\n            audio_cover_strength=0.0,\n            cover_noise_strength=0.0,\n            audio_code_string=\"\",\n            lm_temperature=0.85,\n            lm_cfg_scale=2.5,\n            lm_negative_prompt=\"\",\n            batch_size=None,\n            allow_lm_batch=False,\n            use_random_seed=True,\n            audio_format=\"wav\",\n            constrained_decoding_debug=False,\n            track_classes=None,\n            track_name=\"\",\n        )\n\n    def test_null_duration_gets_default(self):\n        \"\"\"When audio_duration is None, params.duration should be the API default.\"\"\"\n        setup = build_generation_setup(\n            req=self._base_req(),\n            caption=\"cap\",\n            lyrics=\"lyr\",\n            bpm=None,\n            key_scale=\"\",\n            time_signature=\"\",\n            audio_duration=None,\n            thinking=False,\n            sample_mode=False,\n            format_has_duration=False,\n            use_cot_caption=False,\n            use_cot_language=False,\n            lm_top_k=0,\n            lm_top_p=0.9,\n            parse_timesteps=lambda _: None,\n            is_instrumental=lambda _: False,\n            default_dit_instruction=\"default instruction\",\n            task_instructions={},\n        )\n        self.assertEqual(setup.params.duration, _API_DEFAULT_DURATION_SECONDS)\n\n    def test_zero_duration_gets_default(self):\n        \"\"\"Zero duration is falsy and should also get the default.\"\"\"\n        setup = build_generation_setup(\n            req=self._base_req(),\n            caption=\"cap\",\n            lyrics=\"lyr\",\n            bpm=None,\n            key_scale=\"\",\n            time_signature=\"\",\n            audio_duration=0,\n            thinking=False,\n            sample_mode=False,\n            format_has_duration=False,\n            use_cot_caption=False,\n            use_cot_language=False,\n            lm_top_k=0,\n            lm_top_p=0.9,\n            parse_timesteps=lambda _: None,\n            is_instrumental=lambda _: False,\n            default_dit_instruction=\"default instruction\",\n            task_instructions={},\n        )\n        self.assertEqual(setup.params.duration, _API_DEFAULT_DURATION_SECONDS)\n\n    def test_explicit_duration_preserved(self):\n        \"\"\"When audio_duration is explicitly set, it should be preserved.\"\"\"\n        setup = build_generation_setup(\n            req=self._base_req(),\n            caption=\"cap\",\n            lyrics=\"lyr\",\n            bpm=None,\n            key_scale=\"\",\n            time_signature=\"\",\n            audio_duration=60.0,\n            thinking=False,\n            sample_mode=False,\n            format_has_duration=False,\n            use_cot_caption=False,\n            use_cot_language=False,\n            lm_top_k=0,\n            lm_top_p=0.9,\n            parse_timesteps=lambda _: None,\n            is_instrumental=lambda _: False,\n            default_dit_instruction=\"default instruction\",\n            task_instructions={},\n        )\n        self.assertEqual(setup.params.duration, 60.0)\n\n\nif __name__ == \"__main__\":\n    unittest.main()\n"
  },
  {
    "path": "acestep/openrouter_adapter.py",
    "content": "\"\"\"OpenRouter API adapter for ACE-Step music generation.\n\nThis module provides OpenRouter-compatible endpoints that wrap the ACE-Step\nmusic generation API, mounted as a sub-router on the main api_server.\n\nAll generation requests go through the shared asyncio.Queue, ensuring unified\nGPU scheduling with release_task.\n\nEndpoints:\n- POST /v1/chat/completions  - Generate music via chat completion format\n- GET  /v1/models            - List available models (OpenRouter format)\n\"\"\"\n\nfrom __future__ import annotations\n\nimport asyncio\nimport base64\nimport json\nimport os\nimport re\nimport tempfile\nimport time\nfrom typing import Any, Dict, List, NamedTuple, Optional, Tuple\n\nfrom fastapi import APIRouter, HTTPException, Request\nfrom fastapi.responses import JSONResponse, StreamingResponse\nfrom loguru import logger\n\nfrom acestep.openrouter_models import (\n    AudioConfig,\n    ChatCompletionRequest,\n    ModelInfo,\n    ModelPricing,\n    ModelsResponse,\n)\n\n\n# =============================================================================\n# Constants\n# =============================================================================\n\nMODEL_PREFIX = \"acestep\"\nDEFAULT_AUDIO_FORMAT = \"mp3\"\n\n# Generation timeout for non-streaming requests (seconds)\nGENERATION_TIMEOUT = int(os.environ.get(\"ACESTEP_GENERATION_TIMEOUT\", \"600\"))\n\n\n# =============================================================================\n# Helper Functions\n# =============================================================================\n\ndef _generate_completion_id() -> str:\n    \"\"\"Generate a unique completion ID.\"\"\"\n    return f\"chatcmpl-{os.urandom(8).hex()}\"\n\n\ndef _get_model_id(model_name: str) -> str:\n    \"\"\"Convert internal model name to OpenRouter model ID.\"\"\"\n    return f\"{MODEL_PREFIX}/{model_name}\"\n\n\ndef _parse_model_name(model_id: str) -> str:\n    \"\"\"Extract internal model name from OpenRouter model ID.\"\"\"\n    if \"/\" in model_id:\n        return model_id.split(\"/\", 1)[1]\n    return model_id\n\n\ndef _audio_to_base64_url(audio_path: str, audio_format: str = \"mp3\") -> str:\n    \"\"\"Convert audio file to base64 data URL.\"\"\"\n    if not audio_path or not os.path.exists(audio_path):\n        return \"\"\n\n    mime_types = {\n        \"mp3\": \"audio/mpeg\",\n        \"wav\": \"audio/wav\",\n        \"flac\": \"audio/flac\",\n        \"ogg\": \"audio/ogg\",\n        \"m4a\": \"audio/mp4\",\n        \"aac\": \"audio/aac\",\n    }\n    mime_type = mime_types.get(audio_format.lower(), \"audio/mpeg\")\n\n    with open(audio_path, \"rb\") as f:\n        audio_data = f.read()\n\n    b64_data = base64.b64encode(audio_data).decode(\"utf-8\")\n    return f\"data:{mime_type};base64,{b64_data}\"\n\n\ndef _format_lm_content(result: Dict[str, Any]) -> str:\n    \"\"\"Format generation result as content string with metadata and lyrics.\"\"\"\n    metas = result.get(\"metas\", {})\n    lyrics = result.get(\"lyrics\", \"\")\n\n    parts = []\n\n    # Add metadata section\n    meta_lines = []\n    caption = metas.get(\"prompt\") or metas.get(\"caption\") or result.get(\"prompt\", \"\")\n    if caption:\n        meta_lines.append(f\"**Caption:** {caption}\")\n    if metas.get(\"bpm\") and metas[\"bpm\"] != \"N/A\":\n        meta_lines.append(f\"**BPM:** {metas['bpm']}\")\n    if metas.get(\"duration\") and metas[\"duration\"] != \"N/A\":\n        meta_lines.append(f\"**Duration:** {metas['duration']}s\")\n    if metas.get(\"keyscale\") and metas[\"keyscale\"] != \"N/A\":\n        meta_lines.append(f\"**Key:** {metas['keyscale']}\")\n    if metas.get(\"timesignature\") and metas[\"timesignature\"] != \"N/A\":\n        meta_lines.append(f\"**Time Signature:** {metas['timesignature']}\")\n\n    if meta_lines:\n        parts.append(\"## Metadata\\n\" + \"\\n\".join(meta_lines))\n\n    # Add lyrics section\n    if lyrics and lyrics.strip() and lyrics.strip().lower() not in (\"[inst]\", \"[instrumental]\"):\n        parts.append(f\"## Lyrics\\n{lyrics}\")\n\n    if parts:\n        return \"\\n\\n\".join(parts)\n    else:\n        return \"Music generated successfully.\"\n\n\ndef _base64_to_temp_file(b64_data: str, audio_format: str = \"mp3\") -> str:\n    \"\"\"Save base64 audio data to temporary file.\"\"\"\n    if \",\" in b64_data:\n        b64_data = b64_data.split(\",\", 1)[1]\n\n    audio_bytes = base64.b64decode(b64_data)\n    suffix = f\".{audio_format}\" if not audio_format.startswith(\".\") else audio_format\n    fd, path = tempfile.mkstemp(suffix=suffix, prefix=\"openrouter_audio_\")\n    os.close(fd)\n\n    with open(path, \"wb\") as f:\n        f.write(audio_bytes)\n\n    return path\n\n\nclass _AudioBlob(NamedTuple):\n    \"\"\"Deferred audio data extracted from a message (not yet on disk).\"\"\"\n\n    data: str\n    format: str\n\n\ndef _materialize_audio_files(\n    blobs: List[_AudioBlob],\n) -> List[str]:\n    \"\"\"Write deferred audio blobs to temporary files.\n\n    Args:\n        blobs: Audio blobs extracted by _parse_messages.\n\n    Returns:\n        List of temp file paths (caller must ensure cleanup).\n    \"\"\"\n    paths: List[str] = []\n    for blob in blobs:\n        try:\n            path = _base64_to_temp_file(blob.data, blob.format)\n            paths.append(path)\n        except Exception:\n            pass\n    return paths\n\n\ndef _cleanup_temp_paths(paths: List[str]) -> None:\n    \"\"\"Remove temporary files, ignoring errors.\"\"\"\n    for p in paths:\n        try:\n            os.remove(p)\n        except Exception:\n            pass\n\n\ndef _extract_tagged_content(text: str) -> Tuple[Optional[str], Optional[str], str]:\n    \"\"\"\n    Extract content from <prompt> and <lyrics> tags.\n\n    Returns:\n        (prompt, lyrics, remaining_text)\n    \"\"\"\n    prompt = None\n    lyrics = None\n    remaining = text\n\n    prompt_match = re.search(r'<prompt>(.*?)</prompt>', text, re.DOTALL | re.IGNORECASE)\n    if prompt_match:\n        prompt = prompt_match.group(1).strip()\n        remaining = remaining.replace(prompt_match.group(0), '').strip()\n\n    lyrics_match = re.search(r'<lyrics>(.*?)</lyrics>', text, re.DOTALL | re.IGNORECASE)\n    if lyrics_match:\n        lyrics = lyrics_match.group(1).strip()\n        remaining = remaining.replace(lyrics_match.group(0), '').strip()\n\n    return prompt, lyrics, remaining\n\n\ndef _looks_like_lyrics(text: str) -> bool:\n    \"\"\"Heuristic to detect if text looks like song lyrics.\"\"\"\n    if not text:\n        return False\n\n    lyrics_markers = [\n        \"[verse\", \"[chorus\", \"[bridge\", \"[intro\", \"[outro\",\n        \"[hook\", \"[pre-chorus\", \"[refrain\", \"[inst\",\n    ]\n    text_lower = text.lower()\n    for marker in lyrics_markers:\n        if marker in text_lower:\n            return True\n\n    lines = [line.strip() for line in text.split(\"\\n\") if line.strip()]\n    if len(lines) >= 4:\n        avg_line_length = sum(len(line) for line in lines) / len(lines)\n        if avg_line_length < 60:\n            return True\n\n    return False\n\n\ndef _is_instrumental(lyrics: str) -> bool:\n    \"\"\"Check if the music should be instrumental based on lyrics.\"\"\"\n    if not lyrics:\n        return True\n    lyrics_clean = lyrics.strip().lower()\n    if not lyrics_clean:\n        return True\n    return lyrics_clean in (\"[inst]\", \"[instrumental]\")\n\n\ndef _parse_messages(\n    messages: List[Any],\n) -> Tuple[str, str, List[_AudioBlob], Optional[str]]:\n    \"\"\"Parse chat messages to extract prompt, lyrics, and audio references.\n\n    Only processes the last user message (consistent with server behavior).\n    Audio data is returned as deferred blobs — no temp files are created.\n    Call _materialize_audio_files to write them to disk.\n\n    Returns:\n        (prompt, lyrics, audio_blobs, sample_query)\n    \"\"\"\n    prompt = \"\"\n    lyrics = \"\"\n    sample_query = None\n    audio_blobs: List[_AudioBlob] = []\n\n    # Process only the last user message\n    for msg in reversed(messages):\n        if msg.role != \"user\" or not msg.content:\n            continue\n\n        content = msg.content\n\n        # Handle multimodal content (list of parts)\n        if isinstance(content, list):\n            text_parts = []\n            for part in content:\n                if isinstance(part, dict):\n                    part_type = part.get(\"type\", \"\")\n                    if part_type == \"text\":\n                        text_parts.append(\n                            part.get(\"text\", \"\").strip()\n                        )\n                    elif part_type == \"input_audio\":\n                        ad = part.get(\"input_audio\", {})\n                        if isinstance(ad, dict):\n                            b64 = ad.get(\"data\", \"\")\n                            fmt = ad.get(\"format\", \"mp3\")\n                            if b64:\n                                audio_blobs.append(\n                                    _AudioBlob(b64, fmt)\n                                )\n                elif hasattr(part, \"type\"):\n                    if part.type == \"text\":\n                        text_parts.append(\n                            getattr(part, \"text\", \"\").strip()\n                        )\n                    elif part.type == \"input_audio\":\n                        ad = getattr(part, \"input_audio\", None)\n                        if ad:\n                            b64 = getattr(ad, \"data\", \"\")\n                            fmt = getattr(ad, \"format\", \"mp3\")\n                            if b64:\n                                audio_blobs.append(\n                                    _AudioBlob(b64, fmt)\n                                )\n            content = \"\\n\".join(text_parts).strip()\n        else:\n            content = content.strip()\n\n        if not content:\n            break\n\n        # Try to extract tagged content first\n        tagged_prompt, tagged_lyrics, remaining = (\n            _extract_tagged_content(content)\n        )\n\n        if tagged_prompt is not None or tagged_lyrics is not None:\n            prompt = tagged_prompt or \"\"\n            lyrics = tagged_lyrics or \"\"\n            if remaining and not prompt:\n                prompt = remaining\n        else:\n            # No tags - use heuristic detection\n            if _looks_like_lyrics(content):\n                lyrics = content\n            else:\n                prompt = content\n        break\n\n    return prompt, lyrics, audio_blobs, sample_query\n\n\ndef _to_generate_music_request(\n    req: ChatCompletionRequest,\n    prompt: str,\n    lyrics: str,\n    sample_query: Optional[str],\n    reference_audio_path: Optional[str],\n    src_audio_path: Optional[str],\n    audio_codes: str = \"\",\n):\n    \"\"\"\n    Convert OpenRouter ChatCompletionRequest to api_server's GenerateMusicRequest.\n\n    Audio routing depends on task_type:\n      text2music:           audio[0] → reference_audio\n      cover/repaint/lego/…: audio[0] → src_audio, audio[1] → reference_audio\n\n    Uses late import to avoid circular dependency with api_server.\n    \"\"\"\n    from acestep.api_server import GenerateMusicRequest\n\n    audio_config = req.audio_config or AudioConfig()\n\n    # Resolve parameters from audio_config only\n    resolved_instrumental = audio_config.instrumental if audio_config.instrumental is not None else False\n\n    # If instrumental, set lyrics to [inst]\n    resolved_lyrics = lyrics\n    if req.lyrics:\n        resolved_lyrics = req.lyrics\n    if resolved_instrumental and not resolved_lyrics:\n        resolved_lyrics = \"[inst]\"\n\n    # Resolve sample_mode: explicit field takes priority, then auto-detect from messages\n    resolved_sample_mode = req.sample_mode\n    resolved_sample_query = sample_query or \"\"\n\n    # Resolve seed: pass through as-is (int or comma-separated string)\n    # handler.prepare_seeds() handles both formats\n    resolved_seed = req.seed if req.seed is not None else -1\n    use_random_seed = req.seed is None\n\n    return GenerateMusicRequest(\n        # Text input\n        prompt=prompt,\n        lyrics=resolved_lyrics,\n        sample_query=resolved_sample_query,\n        sample_mode=resolved_sample_mode,\n\n        # Music metadata\n        bpm=audio_config.bpm,\n        key_scale=audio_config.key_scale or \"\",\n        time_signature=audio_config.time_signature or \"\",\n        audio_duration=audio_config.duration if audio_config.duration else None,\n        vocal_language=audio_config.vocal_language or \"en\",\n\n        # LM parameters\n        lm_temperature=req.temperature if req.temperature is not None else 0.85,\n        lm_top_p=req.top_p if req.top_p is not None else 0.9,\n        lm_top_k=req.top_k if req.top_k is not None else 0,\n        lm_cfg_scale=req.lm_cfg_scale,\n        thinking=req.thinking if req.thinking is not None else False,\n\n        # Generation parameters\n        inference_steps=req.inference_steps,\n        infer_method=req.infer_method,\n        guidance_scale=req.guidance_scale if req.guidance_scale is not None else 7.0,\n        seed=resolved_seed,\n        use_random_seed=use_random_seed,\n        batch_size=req.batch_size if req.batch_size is not None else 1,\n\n        # Task type\n        task_type=req.task_type,\n\n        # Audio paths\n        reference_audio_path=reference_audio_path or None,\n        src_audio_path=src_audio_path or None,\n\n        # Audio editing\n        repainting_start=req.repainting_start,\n        repainting_end=req.repainting_end,\n        audio_cover_strength=req.audio_cover_strength,\n\n        # Format / CoT control\n        use_format=req.use_format,\n        use_cot_caption=req.use_cot_caption,\n        use_cot_language=req.use_cot_language,\n\n        # Model selection\n        model=_parse_model_name(req.model),\n\n        # Audio format\n        audio_format=(audio_config.format or DEFAULT_AUDIO_FORMAT),\n    )\n\n\ndef _build_openrouter_response(\n    rec: Any,\n    model_id: str,\n    audio_format: str,\n) -> JSONResponse:\n    \"\"\"Build OpenRouter non-streaming response from a completed JobRecord.\"\"\"\n    if rec.status != \"succeeded\" or not rec.result:\n        error_msg = rec.error or \"Generation failed\"\n        raise HTTPException(status_code=500, detail=error_msg)\n\n    result = rec.result\n    completion_id = _generate_completion_id()\n    created_timestamp = int(time.time())\n\n    text_content = _format_lm_content(result)\n\n    # Encode audio\n    audio_obj = None\n    raw_audio_paths = result.get(\"raw_audio_paths\", [])\n    if raw_audio_paths:\n        audio_path = raw_audio_paths[0]\n        if audio_path and os.path.exists(audio_path):\n            b64_url = _audio_to_base64_url(audio_path, audio_format)\n            if b64_url:\n                audio_obj = [{\n                    \"type\": \"audio_url\",\n                    \"audio_url\": {\"url\": b64_url},\n                }]\n\n    # Extract audio_codes from result if available\n    audio_codes = result.get(\"audio_codes\") or None\n\n    response_data = {\n        \"id\": completion_id,\n        \"object\": \"chat.completion\",\n        \"created\": created_timestamp,\n        \"model\": model_id,\n        \"choices\": [{\n            \"index\": 0,\n            \"message\": {\n                \"role\": \"assistant\",\n                \"content\": text_content,\n                \"audio\": audio_obj,\n                \"audio_codes\": audio_codes,\n            },\n            \"finish_reason\": \"stop\",\n        }],\n        \"usage\": {\n            \"prompt_tokens\": 0,\n            \"completion_tokens\": 0,\n            \"total_tokens\": 0,\n        },\n    }\n\n    return JSONResponse(content=response_data)\n\n\nasync def _openrouter_stream_generator(\n    rec: Any,\n    model_id: str,\n    audio_format: str,\n):\n    \"\"\"\n    SSE stream generator that reads from rec.progress_queue.\n\n    Yields heartbeat chunks every 2 seconds while waiting for the\n    queue worker to push the generation result.\n    \"\"\"\n    completion_id = _generate_completion_id()\n    created_timestamp = int(time.time())\n\n    def _make_chunk(\n        content: Optional[str] = None,\n        role: Optional[str] = None,\n        audio: Optional[Any] = None,\n        finish_reason: Optional[str] = None,\n    ) -> str:\n        delta = {}\n        if role:\n            delta[\"role\"] = role\n        if content is not None:\n            delta[\"content\"] = content\n        if audio is not None:\n            delta[\"audio\"] = audio\n\n        chunk = {\n            \"id\": completion_id,\n            \"object\": \"chat.completion.chunk\",\n            \"created\": created_timestamp,\n            \"model\": model_id,\n            \"choices\": [{\n                \"index\": 0,\n                \"delta\": delta,\n                \"finish_reason\": finish_reason,\n            }],\n        }\n        return f\"data: {json.dumps(chunk)}\\n\\n\"\n\n    # Initial role chunk\n    yield _make_chunk(role=\"assistant\", content=\"\")\n    await asyncio.sleep(0)\n\n    # Wait for result with periodic heartbeats\n    while True:\n        try:\n            msg = await asyncio.wait_for(rec.progress_queue.get(), timeout=2.0)\n        except asyncio.TimeoutError:\n            yield _make_chunk(content=\".\")\n            await asyncio.sleep(0)\n            continue\n\n        msg_type = msg.get(\"type\")\n\n        if msg_type == \"done\":\n            break\n\n        elif msg_type == \"error\":\n            yield _make_chunk(content=f\"\\n\\nError: {msg.get('content', 'Unknown error')}\")\n            yield _make_chunk(finish_reason=\"error\")\n            yield \"data: [DONE]\\n\\n\"\n            return\n\n        elif msg_type == \"result\":\n            result = msg.get(\"result\", {})\n\n            # Send LM content\n            lm_content = _format_lm_content(result)\n            yield _make_chunk(content=f\"\\n\\n{lm_content}\")\n            await asyncio.sleep(0)\n\n            # Send audio\n            raw_audio_paths = result.get(\"raw_audio_paths\", [])\n            if raw_audio_paths:\n                audio_path = raw_audio_paths[0]\n                if audio_path and os.path.exists(audio_path):\n                    b64_url = _audio_to_base64_url(audio_path, audio_format)\n                    if b64_url:\n                        audio_list = [{\n                            \"type\": \"audio_url\",\n                            \"audio_url\": {\"url\": b64_url},\n                        }]\n                        yield _make_chunk(audio=audio_list)\n                        await asyncio.sleep(0)\n\n            # Send audio_codes if available\n            audio_codes = result.get(\"audio_codes\")\n            if audio_codes:\n                yield _make_chunk(content=f\"\\n\\n[audio_codes]{audio_codes}[/audio_codes]\")\n                await asyncio.sleep(0)\n\n    # Finish\n    yield _make_chunk(finish_reason=\"stop\")\n    yield \"data: [DONE]\\n\\n\"\n\n\n# =============================================================================\n# Router Factory\n# =============================================================================\n\ndef create_openrouter_router(app_state_getter) -> APIRouter:\n    \"\"\"\n    Create OpenRouter-compatible API router.\n\n    Args:\n        app_state_getter: Callable that returns the FastAPI app.state object\n\n    Returns:\n        APIRouter with OpenRouter-compatible endpoints\n    \"\"\"\n    router = APIRouter(tags=[\"OpenRouter Compatible\"])\n\n    def _get_model_name_from_path(config_path: str) -> str:\n        \"\"\"Extract model name from config path.\"\"\"\n        if not config_path:\n            return \"\"\n        normalized = config_path.rstrip(\"/\\\\\")\n        return os.path.basename(normalized)\n\n    @router.get(\"/v1/models\", response_model=ModelsResponse)\n    async def list_models():\n        \"\"\"List available models in OpenRouter format.\"\"\"\n        state = app_state_getter()\n        models = []\n        created_timestamp = int(time.time()) - 86400 * 30\n\n        # Primary model\n        if getattr(state, \"_initialized\", False):\n            model_name = _get_model_name_from_path(state._config_path)\n            if model_name:\n                models.append(ModelInfo(\n                    id=_get_model_id(model_name),\n                    name=f\"ACE-Step {model_name}\",\n                    created=created_timestamp,\n                    input_modalities=[\"text\", \"audio\"],\n                    output_modalities=[\"audio\", \"text\"],\n                    context_length=4096,\n                    max_output_length=300,\n                    pricing=ModelPricing(\n                        prompt=\"0\", completion=\"0\", request=\"0\",\n                    ),\n                    description=\"AI music generation model\",\n                ))\n\n        # Secondary model\n        if getattr(state, \"_initialized2\", False) and getattr(state, \"_config_path2\", \"\"):\n            model_name = _get_model_name_from_path(state._config_path2)\n            if model_name:\n                models.append(ModelInfo(\n                    id=_get_model_id(model_name),\n                    name=f\"ACE-Step {model_name}\",\n                    created=created_timestamp,\n                    input_modalities=[\"text\", \"audio\"],\n                    output_modalities=[\"audio\", \"text\"],\n                    context_length=4096,\n                    max_output_length=300,\n                    pricing=ModelPricing(),\n                    description=\"AI music generation model\",\n                ))\n\n        # Third model\n        if getattr(state, \"_initialized3\", False) and getattr(state, \"_config_path3\", \"\"):\n            model_name = _get_model_name_from_path(state._config_path3)\n            if model_name:\n                models.append(ModelInfo(\n                    id=_get_model_id(model_name),\n                    name=f\"ACE-Step {model_name}\",\n                    created=created_timestamp,\n                    input_modalities=[\"text\", \"audio\"],\n                    output_modalities=[\"audio\", \"text\"],\n                    context_length=4096,\n                    max_output_length=300,\n                    pricing=ModelPricing(),\n                    description=\"AI music generation model\",\n                ))\n\n        return ModelsResponse(data=models)\n\n    @router.post(\"/v1/chat/completions\")\n    async def chat_completions(request: Request):\n        \"\"\"\n        OpenRouter-compatible chat completions endpoint for music generation.\n\n        Submits the request to the shared asyncio.Queue and waits for completion.\n        Supports both streaming (SSE) and non-streaming responses.\n        \"\"\"\n        state = app_state_getter()\n\n        # Check initialization\n        if not getattr(state, \"_initialized\", False):\n            raise HTTPException(\n                status_code=503,\n                detail=f\"Model not initialized. init_error={getattr(state, '_init_error', None)}\"\n            )\n\n        # Parse request\n        try:\n            body = await request.json()\n            req = ChatCompletionRequest(**body)\n        except Exception as e:\n            raise HTTPException(status_code=400, detail=f\"Invalid request format: {str(e)}\")\n\n        # Parse messages — audio is returned as deferred blobs,\n        # no temp files are created yet.\n        prompt, lyrics, audio_blobs, sample_query = (\n            _parse_messages(req.messages)\n        )\n\n        # When lyrics or sample_mode is explicitly provided,\n        # the message text role is already known.\n        if req.lyrics or req.sample_mode:\n            raw_text = prompt or sample_query or \"\"\n            if req.lyrics:\n                prompt = raw_text\n                lyrics = req.lyrics\n                sample_query = None\n            else:\n                prompt = \"\"\n                lyrics = \"\"\n                sample_query = raw_text\n\n        has_audio = bool(audio_blobs)\n        if (not prompt and not lyrics\n                and not sample_query\n                and not req.sample_mode\n                and not has_audio):\n            raise HTTPException(\n                status_code=400,\n                detail=(\n                    \"No valid prompt, lyrics, sample query, \"\n                    \"or input audio found in request\"\n                ),\n            )\n\n        # Check queue capacity — still no temp files on disk.\n        job_queue = state.job_queue\n        if job_queue.full():\n            raise HTTPException(\n                status_code=429,\n                detail=\"Server busy: queue is full\",\n            )\n\n        # Get audio format\n        audio_config = req.audio_config or AudioConfig()\n        audio_format = (\n            audio_config.format or DEFAULT_AUDIO_FORMAT\n        )\n\n        # Create job record first so we have a job_id for\n        # cleanup registration.\n        job_store = state.job_store\n        rec = job_store.create()\n\n        # Materialize audio blobs to temp files and register\n        # them for cleanup in one step — no leak window.\n        audio_paths = _materialize_audio_files(audio_blobs)\n        if audio_paths:\n            async with state.job_temp_files_lock:\n                state.job_temp_files.setdefault(\n                    rec.job_id, []\n                ).extend(audio_paths)\n\n        # Route audio paths based on task_type.\n        reference_audio_path = None\n        src_audio_path = None\n        _SRC_AUDIO_TASK_TYPES = {\n            \"cover\", \"repaint\", \"lego\",\n            \"extract\", \"complete\",\n        }\n        if audio_paths:\n            if req.task_type in _SRC_AUDIO_TASK_TYPES:\n                src_audio_path = audio_paths[0]\n                if len(audio_paths) > 1:\n                    reference_audio_path = audio_paths[1]\n            else:\n                reference_audio_path = audio_paths[0]\n\n        # Auto-convert src_audio to codes for cover mode\n        resolved_audio_codes = req.audio_codes\n        if (src_audio_path\n                and not resolved_audio_codes\n                and req.task_type == \"cover\"):\n            handler = getattr(state, \"handler\", None)\n            if handler and hasattr(\n                handler, \"convert_src_audio_to_codes\"\n            ):\n                try:\n                    codes_str = await asyncio.to_thread(\n                        handler.convert_src_audio_to_codes,\n                        src_audio_path,\n                    )\n                    if codes_str and not codes_str.startswith(\n                        \"❌\"\n                    ):\n                        resolved_audio_codes = codes_str\n                except Exception as exc:\n                    logger.error(\n                        \"Auto-cover audio transcoding failed \"\n                        \"for {}: {}\",\n                        src_audio_path,\n                        exc,\n                    )\n\n        # Convert to GenerateMusicRequest\n        gen_request = _to_generate_music_request(\n            req, prompt, lyrics, sample_query,\n            reference_audio_path, src_audio_path,\n            audio_codes=resolved_audio_codes,\n        )\n\n        if req.stream:\n            # Streaming: use progress_queue\n            rec.progress_queue = asyncio.Queue()\n\n            async with state.pending_lock:\n                state.pending_ids.append(rec.job_id)\n\n            await job_queue.put((rec.job_id, gen_request))\n\n            return StreamingResponse(\n                _openrouter_stream_generator(rec, req.model, audio_format),\n                media_type=\"text/event-stream\",\n            )\n        else:\n            # Non-streaming: use done_event\n            rec.done_event = asyncio.Event()\n\n            async with state.pending_lock:\n                state.pending_ids.append(rec.job_id)\n\n            await job_queue.put((rec.job_id, gen_request))\n\n            # Wait for completion with timeout\n            try:\n                await asyncio.wait_for(rec.done_event.wait(), timeout=GENERATION_TIMEOUT)\n            except asyncio.TimeoutError:\n                raise HTTPException(status_code=504, detail=\"Generation timeout\")\n\n            return _build_openrouter_response(rec, req.model, audio_format)\n\n    return router\n"
  },
  {
    "path": "acestep/openrouter_models.py",
    "content": "\"\"\"OpenRouter API compatible Pydantic models for ACE-Step.\n\nThis module defines request/response models that conform to OpenRouter's\nchat completions API specification for audio generation.\n\"\"\"\n\nfrom __future__ import annotations\n\nfrom typing import Any, Dict, List, Literal, Optional, Union\nfrom pydantic import BaseModel, Field\n\n\n# =============================================================================\n# Request Models\n# =============================================================================\n\nclass AudioInputContent(BaseModel):\n    \"\"\"Audio input content in base64 format.\"\"\"\n    data: str = Field(..., description=\"Base64-encoded audio data\")\n    format: str = Field(default=\"mp3\", description=\"Audio format (mp3, wav, flac, etc.)\")\n\n\nclass TextContent(BaseModel):\n    \"\"\"Text content block.\"\"\"\n    type: Literal[\"text\"] = \"text\"\n    text: str = Field(..., description=\"Text content\")\n\n\nclass AudioContent(BaseModel):\n    \"\"\"Audio input content block.\"\"\"\n    type: Literal[\"input_audio\"] = \"input_audio\"\n    input_audio: AudioInputContent\n\n\n# Union type for message content\nContentPart = Union[TextContent, AudioContent, Dict[str, Any]]\n\n\nclass ChatMessage(BaseModel):\n    \"\"\"A single message in the chat conversation.\"\"\"\n    role: Literal[\"system\", \"user\", \"assistant\"] = Field(..., description=\"Message role\")\n    content: Union[str, List[ContentPart]] = Field(..., description=\"Message content\")\n    name: Optional[str] = Field(default=None, description=\"Optional name for the message author\")\n\n\nclass AudioConfig(BaseModel):\n    \"\"\"Audio generation configuration.\"\"\"\n    duration: Optional[float] = Field(default=None, description=\"Target audio duration in seconds\")\n    format: str = Field(default=\"mp3\", description=\"Output audio format\")\n    # ACE-Step specific parameters\n    bpm: Optional[int] = Field(default=None, description=\"Beats per minute\")\n    key_scale: Optional[str] = Field(default=None, description=\"Musical key and scale\")\n    time_signature: Optional[str] = Field(default=None, description=\"Time signature (e.g., 4/4)\")\n    vocal_language: Optional[str] = Field(default=None, description=\"Vocal language code\")\n    instrumental: Optional[bool] = Field(default=None, description=\"Generate instrumental only\")\n\n\nclass ChatCompletionRequest(BaseModel):\n    \"\"\"OpenRouter-compatible chat completion request.\"\"\"\n    model: str = Field(..., description=\"Model ID to use\")\n    messages: List[ChatMessage] = Field(..., description=\"List of messages\")\n\n    # Modalities\n    modalities: Optional[List[str]] = Field(\n        default=None,\n        description=\"Output modalities (e.g., ['audio', 'text'])\"\n    )\n\n    # Audio configuration\n    audio_config: Optional[AudioConfig] = Field(\n        default=None,\n        description=\"Audio generation configuration\"\n    )\n\n    # Standard OpenAI parameters\n    temperature: Optional[float] = Field(default=None, ge=0, le=2)\n    top_p: Optional[float] = Field(default=None, ge=0, le=1)\n    top_k: Optional[int] = Field(default=None, ge=0)\n    max_tokens: Optional[int] = Field(default=None, ge=1)\n    stream: bool = Field(default=False, description=\"Enable streaming response\")\n    stop: Optional[Union[str, List[str]]] = Field(default=None)\n    seed: Optional[Union[int, str]] = Field(default=None, description=\"Seed(s) for reproducibility. Comma-separated for batch (e.g. '42,123,456')\")\n\n    # ACE-Step specific parameters (extended)\n    thinking: Optional[bool] = Field(default=None, description=\"Use LM for audio code generation\")\n    guidance_scale: Optional[float] = Field(default=None, description=\"Classifier-free guidance scale\")\n    batch_size: Optional[int] = Field(default=None, description=\"Number of audio samples to generate\")\n\n    # ACE-Step direct fields (bypass message parsing / audio_config)\n    lyrics: str = Field(default=\"\", description=\"Direct lyrics input (bypass message parsing)\")\n    sample_mode: bool = Field(default=False, description=\"Auto-generate caption/lyrics/metas via LM; user message becomes the query\")\n    use_format: bool = Field(default=False, description=\"Use format_sample to enhance caption/lyrics\")\n    use_cot_caption: bool = Field(default=True, description=\"Use CoT for caption rewriting\")\n    use_cot_language: bool = Field(default=True, description=\"Use CoT for language detection\")\n\n    # Task type\n    task_type: str = Field(default=\"text2music\", description=\"Task type: text2music, cover, repaint, extract, lego, complete\")\n\n    # Audio editing parameters\n    repainting_start: float = Field(default=0.0, description=\"Repainting region start (seconds)\")\n    repainting_end: Optional[float] = Field(default=None, description=\"Repainting region end (seconds)\")\n    audio_cover_strength: float = Field(default=1.0, description=\"Audio cover strength (0.0~1.0)\")\n\n    # Extended fields for ComfyUI node compatibility\n    audio_codes: str = Field(default=\"\", description=\"Pre-computed audio codes (bypass auto-conversion)\")\n    cover_noise_strength: float = Field(default=0.0, description=\"Cover noise strength (0=pure noise, 1=closest to src)\")\n    inference_steps: int = Field(default=8, description=\"Number of diffusion inference steps\")\n    infer_method: str = Field(default=\"ode\", description=\"Diffusion inference method: 'ode' or 'sde'\")\n    lm_cfg_scale: float = Field(default=2.0, description=\"LM classifier-free guidance scale\")\n    use_cot_metas: Optional[bool] = Field(default=None, description=\"Use CoT for metadata generation (auto if None)\")\n\n    class Config:\n        extra = \"allow\"  # Allow additional fields for forward compatibility\n\n\n# =============================================================================\n# Response Models\n# =============================================================================\n\nclass AudioOutputUrl(BaseModel):\n    \"\"\"Audio output URL (base64 data URL).\"\"\"\n    url: str = Field(..., description=\"Base64 data URL of the audio\")\n\n\nclass AudioOutput(BaseModel):\n    \"\"\"Audio output content block.\"\"\"\n    type: Literal[\"audio_url\"] = \"audio_url\"\n    audio_url: AudioOutputUrl\n\n\nclass AssistantMessage(BaseModel):\n    \"\"\"Assistant response message.\"\"\"\n    role: Literal[\"assistant\"] = \"assistant\"\n    content: Optional[str] = Field(default=None, description=\"Text content\")\n    audio: Optional[List[AudioOutput]] = Field(default=None, description=\"Generated audio files\")\n    audio_codes: Optional[str] = Field(default=None, description=\"Generated audio codes\")\n\n\nclass Choice(BaseModel):\n    \"\"\"A single completion choice.\"\"\"\n    index: int = Field(default=0)\n    message: AssistantMessage\n    finish_reason: Literal[\"stop\", \"length\", \"content_filter\", \"error\"] = \"stop\"\n\n\nclass Usage(BaseModel):\n    \"\"\"Token usage statistics.\"\"\"\n    prompt_tokens: int = 0\n    completion_tokens: int = 0\n    total_tokens: int = 0\n\n\nclass ChatCompletionResponse(BaseModel):\n    \"\"\"OpenRouter-compatible chat completion response.\"\"\"\n    id: str = Field(..., description=\"Unique completion ID\")\n    object: Literal[\"chat.completion\"] = \"chat.completion\"\n    created: int = Field(..., description=\"Unix timestamp\")\n    model: str = Field(..., description=\"Model ID used\")\n    choices: List[Choice] = Field(..., description=\"Completion choices\")\n    usage: Usage = Field(default_factory=Usage)\n\n    # Extended metadata\n    system_fingerprint: Optional[str] = Field(default=None)\n\n\n# =============================================================================\n# Streaming Response Models\n# =============================================================================\n\nclass DeltaContent(BaseModel):\n    \"\"\"Delta content for streaming.\"\"\"\n    role: Optional[Literal[\"assistant\"]] = None\n    content: Optional[str] = None\n    audio: Optional[List[AudioOutput]] = None\n\n\nclass StreamChoice(BaseModel):\n    \"\"\"Streaming choice.\"\"\"\n    index: int = 0\n    delta: DeltaContent\n    finish_reason: Optional[Literal[\"stop\", \"length\", \"content_filter\", \"error\"]] = None\n\n\nclass ChatCompletionChunk(BaseModel):\n    \"\"\"Streaming chunk response.\"\"\"\n    id: str\n    object: Literal[\"chat.completion.chunk\"] = \"chat.completion.chunk\"\n    created: int\n    model: str\n    choices: List[StreamChoice]\n\n\n# =============================================================================\n# Models Endpoint Response\n# =============================================================================\n\nclass ModelPricing(BaseModel):\n    \"\"\"Model pricing information.\"\"\"\n    prompt: str = Field(default=\"0\", description=\"Price per prompt token in USD\")\n    completion: str = Field(default=\"0\", description=\"Price per completion token in USD\")\n    request: str = Field(default=\"0\", description=\"Price per request in USD\")\n    image: str = Field(default=\"0\", description=\"Price per image in USD\")\n\n\nclass ModelInfo(BaseModel):\n    \"\"\"OpenRouter-compatible model information.\"\"\"\n    id: str = Field(..., description=\"Model identifier\")\n    name: str = Field(..., description=\"Display name\")\n    created: int = Field(..., description=\"Unix timestamp of creation\")\n\n    # Modalities\n    input_modalities: List[str] = Field(\n        default_factory=lambda: [\"text\"],\n        description=\"Supported input modalities\"\n    )\n    output_modalities: List[str] = Field(\n        default_factory=lambda: [\"audio\", \"text\"],\n        description=\"Supported output modalities\"\n    )\n\n    # Limits\n    context_length: int = Field(default=4096, description=\"Maximum context length\")\n    max_output_length: int = Field(default=300, description=\"Maximum output length in seconds\")\n\n    # Pricing\n    pricing: ModelPricing = Field(default_factory=ModelPricing)\n\n    # Metadata\n    description: Optional[str] = Field(default=None)\n    architecture: Optional[Dict[str, Any]] = Field(default=None)\n\n\nclass ModelsResponse(BaseModel):\n    \"\"\"Response for /v1/models endpoint.\"\"\"\n    object: Literal[\"list\"] = \"list\"\n    data: List[ModelInfo] = Field(default_factory=list)\n\n\n# =============================================================================\n# Error Response\n# =============================================================================\n\nclass ErrorDetail(BaseModel):\n    \"\"\"Error detail information.\"\"\"\n    message: str\n    type: str = \"invalid_request_error\"\n    param: Optional[str] = None\n    code: Optional[str] = None\n\n\nclass ErrorResponse(BaseModel):\n    \"\"\"OpenRouter-compatible error response.\"\"\"\n    error: ErrorDetail\n"
  },
  {
    "path": "acestep/text2music_src_audio_test.py",
    "content": "\"\"\"Unit tests verifying that text2music (Custom mode) never uses src_audio.\n\nThe Custom / text2music mode operates exclusively on LM-generated audio codes\nor user-provided LM Codes Hints.  Source audio uploaded in Remix / Repaint\nmodes must not leak into text2music generation.\n\nTests cover three defence layers:\n1. ``generate_with_progress`` (Gradio UI layer) — clears src_audio.\n2. ``generate_music`` (inference orchestrator) — passes None to handler.\n3. ``handler.generate_music`` (backend) — skips src_audio processing.\n\"\"\"\n\nimport unittest\nfrom dataclasses import dataclass\nfrom types import SimpleNamespace\nfrom unittest.mock import MagicMock, patch, call\n\nfrom acestep.inference import GenerationParams\n\n\nclass TestGenerationParamsTextToMusicSrcAudio(unittest.TestCase):\n    \"\"\"Verify GenerationParams allows src_audio but the pipeline ignores it.\"\"\"\n\n    def test_text2music_params_accept_src_audio_field(self):\n        \"\"\"GenerationParams should accept src_audio without raising.\"\"\"\n        params = GenerationParams(\n            task_type=\"text2music\",\n            src_audio=\"/tmp/stale_remix_audio.wav\",\n        )\n        self.assertEqual(params.src_audio, \"/tmp/stale_remix_audio.wav\")\n        self.assertEqual(params.task_type, \"text2music\")\n\n    def test_cover_params_preserve_src_audio(self):\n        \"\"\"Non-text2music tasks should preserve src_audio.\"\"\"\n        params = GenerationParams(\n            task_type=\"cover\",\n            src_audio=\"/tmp/cover_source.wav\",\n        )\n        self.assertEqual(params.src_audio, \"/tmp/cover_source.wav\")\n\n\nclass TestInferenceLayerSrcAudioGuard(unittest.TestCase):\n    \"\"\"Verify ``inference.generate_music`` nullifies src_audio for text2music.\"\"\"\n\n    @patch(\"acestep.inference.generate_music\")\n    def test_generate_music_passes_none_src_audio_for_text2music(self, mock_gen):\n        \"\"\"When task_type is text2music, src_audio passed to handler must be None.\n\n        We patch at the module boundary and verify the actual code path\n        by inspecting how the handler's generate_music is called.\n        \"\"\"\n        # Instead of calling the full generate_music (which needs a real\n        # model), we verify the expression used inline:\n        params = GenerationParams(\n            task_type=\"text2music\",\n            src_audio=\"/tmp/stale.wav\",\n        )\n        # The guarded expression: None if task_type == \"text2music\" else src_audio\n        result = None if params.task_type == \"text2music\" else params.src_audio\n        self.assertIsNone(result)\n\n    def test_cover_task_preserves_src_audio(self):\n        \"\"\"For cover tasks, the guard expression should preserve src_audio.\"\"\"\n        params = GenerationParams(\n            task_type=\"cover\",\n            src_audio=\"/tmp/cover.wav\",\n        )\n        result = None if params.task_type == \"text2music\" else params.src_audio\n        self.assertEqual(result, \"/tmp/cover.wav\")\n\n    def test_repaint_task_preserves_src_audio(self):\n        \"\"\"For repaint tasks, the guard expression should preserve src_audio.\"\"\"\n        params = GenerationParams(\n            task_type=\"repaint\",\n            src_audio=\"/tmp/repaint.wav\",\n        )\n        result = None if params.task_type == \"text2music\" else params.src_audio\n        self.assertEqual(result, \"/tmp/repaint.wav\")\n\n\nclass TestHandlerLayerSrcAudioGuard(unittest.TestCase):\n    \"\"\"Verify handler-level defence: text2music skips process_src_audio.\"\"\"\n\n    def _simulate_handler_src_audio_logic(self, task_type, src_audio, audio_code_string=\"\"):\n        \"\"\"Reproduce the handler's src_audio processing logic.\n\n        This mirrors the branching in ``handler.py`` generate_music()\n        without requiring a full model instantiation.\n        \"\"\"\n        def _has_audio_codes(v):\n            if isinstance(v, list):\n                return any((x or \"\").strip() for x in v)\n            return bool(v and str(v).strip())\n\n        processed_src_audio = None\n        process_called = False\n\n        if task_type == \"text2music\":\n            if src_audio is not None:\n                pass  # logged, ignored\n        elif src_audio is not None:\n            if _has_audio_codes(audio_code_string):\n                pass  # codes take precedence\n            else:\n                processed_src_audio = f\"processed:{src_audio}\"\n                process_called = True\n\n        return processed_src_audio, process_called\n\n    def test_text2music_ignores_src_audio(self):\n        \"\"\"text2music must never process src_audio.\"\"\"\n        result, called = self._simulate_handler_src_audio_logic(\n            \"text2music\", \"/tmp/stale.wav\",\n        )\n        self.assertIsNone(result)\n        self.assertFalse(called)\n\n    def test_text2music_ignores_src_audio_even_with_no_codes(self):\n        \"\"\"text2music must ignore src_audio even when audio codes are empty.\"\"\"\n        result, called = self._simulate_handler_src_audio_logic(\n            \"text2music\", \"/tmp/stale.wav\", audio_code_string=\"\",\n        )\n        self.assertIsNone(result)\n        self.assertFalse(called)\n\n    def test_cover_processes_src_audio(self):\n        \"\"\"cover task should process src_audio when no codes provided.\"\"\"\n        result, called = self._simulate_handler_src_audio_logic(\n            \"cover\", \"/tmp/cover.wav\",\n        )\n        self.assertEqual(result, \"processed:/tmp/cover.wav\")\n        self.assertTrue(called)\n\n    def test_cover_ignores_src_audio_when_codes_provided(self):\n        \"\"\"cover task should ignore src_audio when audio codes exist.\"\"\"\n        result, called = self._simulate_handler_src_audio_logic(\n            \"cover\", \"/tmp/cover.wav\", audio_code_string=\"<|audio_code_42|>\",\n        )\n        self.assertIsNone(result)\n        self.assertFalse(called)\n\n    def test_repaint_processes_src_audio(self):\n        \"\"\"repaint task should process src_audio.\"\"\"\n        result, called = self._simulate_handler_src_audio_logic(\n            \"repaint\", \"/tmp/repaint.wav\",\n        )\n        self.assertEqual(result, \"processed:/tmp/repaint.wav\")\n        self.assertTrue(called)\n\n    def test_none_src_audio_is_noop_for_all_tasks(self):\n        \"\"\"When src_audio is None, no processing should occur for any task.\"\"\"\n        for task in (\"text2music\", \"cover\", \"repaint\", \"lego\", \"extract\"):\n            result, called = self._simulate_handler_src_audio_logic(task, None)\n            self.assertIsNone(result, f\"Expected None for task={task}\")\n            self.assertFalse(called, f\"Expected no processing for task={task}\")\n\n\nclass TestGenerateWithProgressSrcAudioClear(unittest.TestCase):\n    \"\"\"Verify the UI-layer guard in generate_with_progress.\"\"\"\n\n    def test_text2music_clears_src_audio_before_params(self):\n        \"\"\"The local variable should be set to None for text2music.\"\"\"\n        # Simulate the guard logic from generate_with_progress\n        task_type = \"text2music\"\n        src_audio = \"/tmp/stale_from_remix.wav\"\n\n        if task_type == \"text2music\":\n            src_audio = None\n\n        self.assertIsNone(src_audio)\n\n    def test_cover_preserves_src_audio(self):\n        \"\"\"Non-text2music tasks should not clear src_audio.\"\"\"\n        task_type = \"cover\"\n        src_audio = \"/tmp/cover_source.wav\"\n\n        if task_type == \"text2music\":\n            src_audio = None\n\n        self.assertEqual(src_audio, \"/tmp/cover_source.wav\")\n\n\nif __name__ == \"__main__\":\n    unittest.main()\n"
  },
  {
    "path": "acestep/third_parts/nano-vllm/LICENSE",
    "content": "MIT License\n\nCopyright (c) 2025 Xingkai Yu\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
  },
  {
    "path": "acestep/third_parts/nano-vllm/README.md",
    "content": "<p align=\"center\">\n<img width=\"300\" src=\"assets/logo.png\">\n</p>\n\n<p align=\"center\">\n<a href=\"https://trendshift.io/repositories/15323\" target=\"_blank\"><img src=\"https://trendshift.io/api/badge/repositories/15323\" alt=\"GeeeekExplorer%2Fnano-vllm | Trendshift\" style=\"width: 250px; height: 55px;\" width=\"250\" height=\"55\"/></a>\n</p>\n\n# Nano-vLLM\n\nA lightweight vLLM implementation built from scratch.\n\n## Key Features\n\n* 🚀 **Fast offline inference** - Comparable inference speeds to vLLM\n* 📖 **Readable codebase** - Clean implementation in ~ 1,200 lines of Python code\n* ⚡ **Optimization Suite** - Prefix caching, Tensor Parallelism, Torch compilation, CUDA graph, etc.\n\n## Installation\n\n```bash\npip install git+https://github.com/GeeeekExplorer/nano-vllm.git\n```\n\n## Model Download\n\nTo download the model weights manually, use the following command:\n```bash\nhuggingface-cli download --resume-download Qwen/Qwen3-0.6B \\\n  --local-dir ~/huggingface/Qwen3-0.6B/ \\\n  --local-dir-use-symlinks False\n```\n\n## Quick Start\n\nSee `example.py` for usage. The API mirrors vLLM's interface with minor differences in the `LLM.generate` method:\n```python\nfrom nanovllm import LLM, SamplingParams\nllm = LLM(\"/YOUR/MODEL/PATH\", enforce_eager=True, tensor_parallel_size=1)\nsampling_params = SamplingParams(temperature=0.6, max_tokens=256)\nprompts = [\"Hello, Nano-vLLM.\"]\noutputs = llm.generate(prompts, sampling_params)\noutputs[0][\"text\"]\n```\n\n## Benchmark\n\nSee `bench.py` for benchmark.\n\n**Test Configuration:**\n- Hardware: RTX 4070 Laptop (8GB)\n- Model: Qwen3-0.6B\n- Total Requests: 256 sequences\n- Input Length: Randomly sampled between 100–1024 tokens\n- Output Length: Randomly sampled between 100–1024 tokens\n\n**Performance Results:**\n| Inference Engine | Output Tokens | Time (s) | Throughput (tokens/s) |\n|----------------|-------------|----------|-----------------------|\n| vLLM           | 133,966     | 98.37    | 1361.84               |\n| Nano-vLLM      | 133,966     | 93.41    | 1434.13               |\n\n\n## Star History\n\n[![Star History Chart](https://api.star-history.com/svg?repos=GeeeekExplorer/nano-vllm&type=Date)](https://www.star-history.com/#GeeeekExplorer/nano-vllm&Date)"
  },
  {
    "path": "acestep/third_parts/nano-vllm/bench.py",
    "content": "import os\nimport time\nfrom random import randint, seed\nfrom nanovllm import LLM, SamplingParams\n# from vllm import LLM, SamplingParams\n\n\ndef main():\n    seed(0)\n    num_seqs = 256\n    max_input_len = 1024\n    max_output_len = 1024\n\n    path = os.path.expanduser(\"~/huggingface/Qwen3-0.6B/\")\n    llm = LLM(path, enforce_eager=False, max_model_len=4096)\n\n    prompt_token_ids = [[randint(0, 10000) for _ in range(randint(100, max_input_len))] for _ in range(num_seqs)]\n    sampling_params = [SamplingParams(temperature=0.6, ignore_eos=True, max_tokens=randint(100, max_output_len)) for _ in range(num_seqs)]\n    # uncomment the following line for vllm\n    # prompt_token_ids = [dict(prompt_token_ids=p) for p in prompt_token_ids]\n\n    llm.generate([\"Benchmark: \"], SamplingParams())\n    t = time.time()\n    llm.generate(prompt_token_ids, sampling_params, use_tqdm=False)\n    t = (time.time() - t)\n    total_tokens = sum(sp.max_tokens for sp in sampling_params)\n    throughput = total_tokens / t\n    print(f\"Total: {total_tokens}tok, Time: {t:.2f}s, Throughput: {throughput:.2f}tok/s\")\n\n\nif __name__ == \"__main__\":\n    main()\n"
  },
  {
    "path": "acestep/third_parts/nano-vllm/example.py",
    "content": "import os\nfrom nanovllm import LLM, SamplingParams\nfrom transformers import AutoTokenizer\n\n\ndef main():\n    path = os.path.expanduser(\"~/huggingface/Qwen3-0.6B/\")\n    tokenizer = AutoTokenizer.from_pretrained(path)\n    llm = LLM(path, enforce_eager=True, tensor_parallel_size=1)\n\n    sampling_params = SamplingParams(temperature=0.6, max_tokens=256)\n    prompts = [\n        \"introduce yourself\",\n        \"list all prime numbers within 100\",\n    ]\n    prompts = [\n        tokenizer.apply_chat_template(\n            [{\"role\": \"user\", \"content\": prompt}],\n            tokenize=False,\n            add_generation_prompt=True,\n        )\n        for prompt in prompts\n    ]\n    outputs = llm.generate(prompts, sampling_params)\n\n    for prompt, output in zip(prompts, outputs):\n        print(\"\\n\")\n        print(f\"Prompt: {prompt!r}\")\n        print(f\"Completion: {output['text']!r}\")\n\n\nif __name__ == \"__main__\":\n    main()\n"
  },
  {
    "path": "acestep/third_parts/nano-vllm/nanovllm/__init__.py",
    "content": "from nanovllm.llm import LLM\nfrom nanovllm.sampling_params import SamplingParams\n"
  },
  {
    "path": "acestep/third_parts/nano-vllm/nanovllm/config.py",
    "content": "import os\nfrom dataclasses import dataclass\nfrom transformers import AutoConfig\n\n\n@dataclass\nclass Config:\n    model: str\n    max_num_batched_tokens: int = 16384\n    max_num_seqs: int = 512\n    max_model_len: int = 4096\n    gpu_memory_utilization: float = 0.9\n    tensor_parallel_size: int = 1\n    enforce_eager: bool = False\n    hf_config: AutoConfig | None = None\n    eos: int = -1\n    kvcache_block_size: int = 256\n    num_kvcache_blocks: int = -1\n\n    def __post_init__(self):\n        assert os.path.isdir(self.model)\n        assert self.kvcache_block_size % 256 == 0\n        assert 1 <= self.tensor_parallel_size <= 8\n        self.hf_config = AutoConfig.from_pretrained(self.model)\n        self.max_model_len = min(self.max_model_len, self.hf_config.max_position_embeddings)\n        assert self.max_num_batched_tokens >= self.max_model_len\n"
  },
  {
    "path": "acestep/third_parts/nano-vllm/nanovllm/distributed.py",
    "content": "\"\"\"\nDistributed utilities for nano-vllm.\n\nThis module provides wrapper functions for torch.distributed that gracefully\nhandle single-GPU mode (world_size == 1) without requiring distributed initialization.\n\"\"\"\n\nimport torch.distributed as dist\n\n\n# Global flag to track if distributed is actually initialized\n_distributed_initialized = False\n\n\ndef initialize_distributed(backend: str, init_method: str, world_size: int, rank: int) -> bool:\n    \"\"\"\n    Initialize distributed process group only if world_size > 1.\n    \n    Args:\n        backend: Distributed backend (e.g., \"nccl\" or \"gloo\")\n        init_method: Initialization method (e.g., \"tcp://127.0.0.1:2333\")\n        world_size: Total number of processes\n        rank: Rank of current process\n        \n    Returns:\n        True if distributed was initialized, False otherwise\n    \"\"\"\n    global _distributed_initialized\n    \n    if world_size == 1:\n        # Single GPU mode - no distributed needed\n        _distributed_initialized = False\n        return False\n    \n    # Multi-GPU mode - initialize distributed\n    dist.init_process_group(backend, init_method, world_size=world_size, rank=rank)\n    _distributed_initialized = True\n    return True\n\n\ndef is_initialized() -> bool:\n    \"\"\"Check if distributed is initialized.\"\"\"\n    return _distributed_initialized\n\n\ndef get_rank() -> int:\n    \"\"\"Get current process rank. Returns 0 if distributed is not initialized.\"\"\"\n    if _distributed_initialized:\n        return dist.get_rank()\n    return 0\n\n\ndef get_world_size() -> int:\n    \"\"\"Get world size. Returns 1 if distributed is not initialized.\"\"\"\n    if _distributed_initialized:\n        return dist.get_world_size()\n    return 1\n\n\ndef barrier():\n    \"\"\"Synchronize all processes. No-op if distributed is not initialized.\"\"\"\n    if _distributed_initialized:\n        dist.barrier()\n\n\ndef all_reduce(tensor, op=None):\n    \"\"\"\n    All-reduce operation. No-op if distributed is not initialized.\n    \n    Args:\n        tensor: Tensor to reduce\n        op: Reduce operation (default: SUM)\n    \"\"\"\n    if _distributed_initialized:\n        if op is None:\n            op = dist.ReduceOp.SUM\n        dist.all_reduce(tensor, op)\n\n\ndef gather(tensor, gather_list=None, dst=0):\n    \"\"\"\n    Gather tensors from all processes. No-op if distributed is not initialized.\n    \n    Args:\n        tensor: Tensor to gather\n        gather_list: List to gather into (only used on dst rank)\n        dst: Destination rank\n    \"\"\"\n    if _distributed_initialized:\n        dist.gather(tensor, gather_list, dst)\n\n\ndef destroy_process_group():\n    \"\"\"Destroy process group. No-op if distributed is not initialized.\"\"\"\n    global _distributed_initialized\n    \n    if _distributed_initialized:\n        dist.destroy_process_group()\n        _distributed_initialized = False\n"
  },
  {
    "path": "acestep/third_parts/nano-vllm/nanovllm/engine/block_manager.py",
    "content": "import os\nfrom collections import deque\nimport xxhash\nimport numpy as np\n\nfrom nanovllm.engine.sequence import Sequence\n\n# Debug logging - enable with NANOVLLM_DEBUG=1\n_DEBUG = os.environ.get(\"NANOVLLM_DEBUG\", \"0\") == \"1\"\n\ndef _debug_log(msg: str):\n    \"\"\"Print debug message if NANOVLLM_DEBUG is enabled\"\"\"\n    if _DEBUG:\n        print(f\"[nanovllm block_mgr DEBUG] {msg}\", flush=True)\n\n\nclass Block:\n\n    def __init__(self, block_id):\n        self.block_id = block_id\n        self.ref_count = 0\n        self.hash = -1\n        self.token_ids = []\n\n    def update(self, hash: int, token_ids: list[int]):\n        self.hash = hash\n        self.token_ids = token_ids\n\n    def reset(self):\n        self.ref_count = 1\n        self.hash = -1\n        self.token_ids = []\n\n\nclass BlockManager:\n\n    def __init__(self, num_blocks: int, block_size: int):\n        self.block_size = block_size\n        self.blocks: list[Block] = [Block(i) for i in range(num_blocks)]\n        self.hash_to_block_id: dict[int, int] = dict()\n        self.free_block_ids: deque[int] = deque(range(num_blocks))\n        self.used_block_ids: set[int] = set()\n\n    @classmethod\n    def compute_hash(cls, token_ids: list[int], prefix: int = -1):\n        h = xxhash.xxh64()\n        if prefix != -1:\n            h.update(prefix.to_bytes(8, \"little\"))\n        h.update(np.array(token_ids).tobytes())\n        return h.intdigest()\n\n    def reset(self):\n        \"\"\"Reset all blocks and clear the prefix cache to prevent unbounded growth.\"\"\"\n        for block_id in list(self.used_block_ids):\n            self.blocks[block_id].ref_count = 0\n            self.blocks[block_id].hash = -1\n            self.blocks[block_id].token_ids = []\n        self.free_block_ids = deque(range(len(self.blocks)))\n        self.used_block_ids.clear()\n        self.hash_to_block_id.clear()\n\n    def _allocate_block(self, block_id: int) -> Block:\n        block = self.blocks[block_id]\n        assert block.ref_count == 0\n        block.reset()\n        self.free_block_ids.remove(block_id)\n        self.used_block_ids.add(block_id)\n        return self.blocks[block_id]\n\n    def _deallocate_block(self, block_id: int) -> Block:\n        assert self.blocks[block_id].ref_count == 0\n        self.used_block_ids.remove(block_id)\n        self.free_block_ids.append(block_id)\n\n    def can_allocate(self, seq: Sequence) -> bool:\n        return len(self.free_block_ids) >= seq.num_blocks\n\n    def allocate(self, seq: Sequence):\n        _debug_log(f\"allocate: seq_id={seq.seq_id}, len={len(seq)}, num_blocks={seq.num_blocks}, \"\n                  f\"free_blocks={len(self.free_block_ids)}\")\n        assert not seq.block_table\n        h = -1\n        cache_miss = False\n        for i in range(seq.num_blocks):\n            token_ids = seq.block(i)\n            h = self.compute_hash(token_ids, h) if len(token_ids) == self.block_size else -1\n            block_id = self.hash_to_block_id.get(h, -1)\n            if block_id == -1 or self.blocks[block_id].token_ids != token_ids:\n                cache_miss = True\n            if cache_miss:\n                if len(self.free_block_ids) == 0:\n                    _debug_log(f\"  ERROR: no free blocks available!\")\n                block_id = self.free_block_ids[0]\n                block = self._allocate_block(block_id)\n            else:\n                seq.num_cached_tokens += self.block_size\n                if block_id in self.used_block_ids:\n                    block = self.blocks[block_id]\n                    block.ref_count += 1\n                else:\n                    block = self._allocate_block(block_id)\n            if h != -1:\n                block.update(h, token_ids)\n                self.hash_to_block_id[h] = block_id\n            seq.block_table.append(block_id)\n        _debug_log(f\"  allocated block_table: {seq.block_table}\")\n\n    def deallocate(self, seq: Sequence):\n        _debug_log(f\"deallocate: seq_id={seq.seq_id}, block_table={seq.block_table}\")\n        for block_id in reversed(seq.block_table):\n            block = self.blocks[block_id]\n            block.ref_count -= 1\n            _debug_log(f\"  block_id={block_id}, ref_count after decrement={block.ref_count}\")\n            if block.ref_count == 0:\n                # Fix: Clean up hash_to_block_id mapping to prevent stale references\n                # This prevents CUDA illegal memory access when prefix cache tries to\n                # reuse a block_id that has already been freed\n                if block.hash != -1:\n                    cached_id = self.hash_to_block_id.get(block.hash)\n                    if cached_id == block_id:\n                        del self.hash_to_block_id[block.hash]\n                self._deallocate_block(block_id)\n        seq.num_cached_tokens = 0\n        seq.block_table.clear()\n        _debug_log(f\"  deallocated, free_blocks={len(self.free_block_ids)}\")\n\n    def can_append(self, seq: Sequence) -> bool:\n        return len(self.free_block_ids) >= (len(seq) % self.block_size == 1)\n\n    def may_append(self, seq: Sequence):\n        block_table = seq.block_table\n        last_block = self.blocks[block_table[-1]]\n        if len(seq) % self.block_size == 1:\n            assert last_block.hash != -1\n            block_id = self.free_block_ids[0]\n            self._allocate_block(block_id)\n            block_table.append(block_id)\n        elif len(seq) % self.block_size == 0:\n            assert last_block.hash == -1\n            token_ids = seq.block(seq.num_blocks-1)\n            prefix = self.blocks[block_table[-2]].hash if len(block_table) > 1 else -1\n            h = self.compute_hash(token_ids, prefix)\n            last_block.update(h, token_ids)\n            self.hash_to_block_id[h] = last_block.block_id\n        else:\n            assert last_block.hash == -1\n"
  },
  {
    "path": "acestep/third_parts/nano-vllm/nanovllm/engine/llm_engine.py",
    "content": "import atexit\nimport threading\nfrom dataclasses import fields\nfrom time import perf_counter\nfrom tqdm.auto import tqdm\nfrom transformers import AutoTokenizer\nimport torch.multiprocessing as mp\n\nfrom nanovllm.config import Config\nfrom nanovllm.sampling_params import SamplingParams\nfrom nanovllm.engine.sequence import Sequence\nfrom nanovllm.engine.scheduler import Scheduler\nfrom nanovllm.engine.model_runner import ModelRunner\n\n\nclass LLMEngine:\n\n    def __init__(self, model, **kwargs):\n        config_fields = {field.name for field in fields(Config)}\n        config_kwargs = {k: v for k, v in kwargs.items() if k in config_fields}\n        config = Config(model, **config_kwargs)\n        self.ps = []\n        self.events = []\n        # Thread-safety lock for generate().\n        # The scheduler, block manager, model runner, and CUDA graph buffers are all\n        # shared mutable state that is NOT thread-safe. In concurrent serving scenarios\n        # (API server with ThreadPoolExecutor, multiple queue workers, Gradio with\n        # concurrent requests), multiple threads can call generate() simultaneously.\n        # Without this lock, concurrent access corrupts scheduler state, block tables,\n        # and CUDA graph input buffers, leading to intermittent CUDA device-side\n        # assertion failures (illegal memory access in KV cache).\n        self._generate_lock = threading.Lock()\n        ctx = mp.get_context(\"spawn\")\n        for i in range(1, config.tensor_parallel_size):\n            event = ctx.Event()\n            process = ctx.Process(target=ModelRunner, args=(config, i, event))\n            process.start()\n            self.ps.append(process)\n            self.events.append(event)\n        self.model_runner = ModelRunner(config, 0, self.events)\n        tokenizer = kwargs.get(\"tokenizer\", None)\n        if tokenizer is not None:\n            self.tokenizer = tokenizer\n        else:\n            self.tokenizer = AutoTokenizer.from_pretrained(config.model, use_fast=True)\n        config.eos = self.tokenizer.eos_token_id\n        self.scheduler = Scheduler(config)\n        atexit.register(self.exit)\n\n    def exit(self):\n        self.model_runner.call(\"exit\")\n        del self.model_runner\n        for p in self.ps:\n            p.join()\n\n    def add_request(self, prompt: str | list[int], sampling_params: SamplingParams, unconditional_prompt: str | list[int] | None = None):\n        if isinstance(prompt, str):\n            prompt = self.tokenizer.encode(prompt)\n        # For CFG: if cfg_scale > 1.0, create both conditional and unconditional sequences\n        if sampling_params.cfg_scale > 1.0:\n            if unconditional_prompt is None:\n                # Try to construct unconditional prompt by replacing user input with \"NO USER INPUT\"\n                # This is a fallback - ideally users should provide unconditional_prompt\n                if isinstance(prompt, list):\n                    # For now, just use the same prompt (user should provide unconditional_prompt)\n                    # TODO: Implement automatic \"NO USER INPUT\" replacement if possible\n                    unconditional_prompt = prompt\n                else:\n                    unconditional_prompt = prompt\n            if isinstance(unconditional_prompt, str):\n                unconditional_prompt = self.tokenizer.encode(unconditional_prompt)\n            # Create unconditional sequence first (so we can reference it from conditional)\n            uncond_seq = Sequence(unconditional_prompt, sampling_params, is_unconditional=True)\n            # Create conditional sequence with reference to unconditional\n            cond_seq = Sequence(prompt, sampling_params, is_unconditional=False, conditional_seq=uncond_seq)\n            uncond_seq.paired_seq = cond_seq  # Link them bidirectionally\n            # Add both sequences to scheduler\n            self.scheduler.add(cond_seq)\n            self.scheduler.add(uncond_seq)\n        else:\n            seq = Sequence(prompt, sampling_params)\n            self.scheduler.add(seq)\n\n    def step(self):\n        seqs, is_prefill = self.scheduler.schedule()\n        token_ids = self.model_runner.call(\"run\", seqs, is_prefill)\n        self.scheduler.postprocess(seqs, token_ids)\n        # Only output conditional sequences (unconditional sequences are just for CFG computation)\n        output_seqs = [seq for seq in seqs if seq.is_finished and (seq.cfg_scale <= 1.0 or not seq.is_unconditional)]\n        outputs = [(seq.seq_id, seq.completion_token_ids) for seq in output_seqs]\n        num_tokens = sum(len(seq) for seq in seqs) if is_prefill else -len([s for s in seqs if not s.is_unconditional])\n        return outputs, num_tokens\n\n    def is_finished(self):\n        return self.scheduler.is_finished()\n\n    def reset(self):\n        \"\"\"\n        Reset the scheduler state and release all allocated blocks.\n        This should be called when an exception occurs during generation to prevent\n        KV cache block leaks that can cause 'deque index out of range' errors.\n        \"\"\"\n        # Deallocate all running sequences\n        while self.scheduler.running:\n            seq = self.scheduler.running.popleft()\n            if seq.block_table:  # Only deallocate if blocks are allocated\n                self.scheduler.block_manager.deallocate(seq)\n\n        # Deallocate all waiting sequences (they might have blocks from preemption)\n        while self.scheduler.waiting:\n            seq = self.scheduler.waiting.popleft()\n            if seq.block_table:\n                self.scheduler.block_manager.deallocate(seq)\n\n        # Clear prefix cache to prevent unbounded hash_to_block_id growth\n        self.scheduler.block_manager.reset()\n\n    def generate(\n        self,\n        prompts: list[str] | list[list[int]],\n        sampling_params: SamplingParams | list[SamplingParams],\n        use_tqdm: bool = True,\n        unconditional_prompts: list[str] | list[list[int]] | None = None,\n    ) -> list[str]:\n        # Serialize access to the engine to prevent concurrent corruption of\n        # scheduler state, block manager, CUDA graph buffers, and KV cache.\n        # This is the primary defense against the intermittent CUDA device-side\n        # assertion error that occurs in concurrent serving scenarios.\n        with self._generate_lock:\n            return self._generate_impl(prompts, sampling_params, use_tqdm, unconditional_prompts)\n\n    def _generate_impl(\n        self,\n        prompts: list[str] | list[list[int]],\n        sampling_params: SamplingParams | list[SamplingParams],\n        use_tqdm: bool = True,\n        unconditional_prompts: list[str] | list[list[int]] | None = None,\n    ) -> list[str]:\n        # Clean up any residual state from previous interrupted generations\n        # This prevents 'deque index out of range' errors from accumulated block leaks\n        if not self.is_finished():\n            self.reset()\n        \n        if use_tqdm:\n            pbar = tqdm(total=len(prompts), desc=\"Generating\", dynamic_ncols=True)\n        if not isinstance(sampling_params, list):\n            sampling_params = [sampling_params] * len(prompts)\n        if unconditional_prompts is None:\n            unconditional_prompts = [None] * len(prompts)\n        for prompt, sp, uncond_prompt in zip(prompts, sampling_params, unconditional_prompts):\n            self.add_request(prompt, sp, uncond_prompt)\n        outputs = {}\n        prefill_throughput = decode_throughput = 0.\n        try:\n            while not self.is_finished():\n                t = perf_counter()\n                output, num_tokens = self.step()\n                if use_tqdm:\n                    if num_tokens > 0:\n                        prefill_throughput = num_tokens / (perf_counter() - t)\n                    else:\n                        decode_throughput = -num_tokens / (perf_counter() - t)\n                    pbar.set_postfix({\n                        \"Prefill\": f\"{int(prefill_throughput)}tok/s\",\n                        \"Decode\": f\"{int(decode_throughput)}tok/s\",\n                    })\n                for seq_id, token_ids in output:\n                    outputs[seq_id] = token_ids\n                    if use_tqdm:\n                        pbar.update(1)\n        except Exception:\n            # Clean up on exception to prevent block leaks\n            self.reset()\n            raise\n        finally:\n            if use_tqdm:\n                pbar.close()\n        \n        outputs = [outputs[seq_id] for seq_id in sorted(outputs.keys())]\n        outputs = [{\"text\": self.tokenizer.decode(token_ids), \"token_ids\": token_ids} for token_ids in outputs]\n        return outputs\n"
  },
  {
    "path": "acestep/third_parts/nano-vllm/nanovllm/engine/model_runner.py",
    "content": "import os\nimport pickle\nimport torch\nimport torch.distributed as dist\nfrom multiprocessing.synchronize import Event\nfrom multiprocessing.shared_memory import SharedMemory\nimport sys\n\nfrom nanovllm.config import Config\nfrom acestep.debug_utils import debug_start, debug_end\nfrom nanovllm import distributed as dist_utils\n\n# Debug logging - enable with NANOVLLM_DEBUG=1\n_DEBUG = os.environ.get(\"NANOVLLM_DEBUG\", \"0\") == \"1\"\n\ndef _debug_log(msg: str):\n    \"\"\"Print debug message if NANOVLLM_DEBUG is enabled\"\"\"\n    if _DEBUG:\n        print(f\"[nanovllm DEBUG] {msg}\", flush=True)\nfrom nanovllm.engine.sequence import Sequence\nfrom nanovllm.models.qwen3 import Qwen3ForCausalLM\nfrom nanovllm.layers.sampler import Sampler\nfrom nanovllm.utils.context import set_context, get_context, reset_context\nfrom nanovllm.utils.loader import load_model\n\nimport socket\n\n\ndef find_available_port(start_port: int = 2333, max_attempts: int = 100) -> int:\n    \"\"\"Find an available port starting from start_port.\n    \n    Args:\n        start_port: The starting port number to check\n        max_attempts: Maximum number of ports to try\n        \n    Returns:\n        An available port number\n        \n    Raises:\n        RuntimeError: If no available port is found within max_attempts\n    \"\"\"\n    for i in range(max_attempts):\n        port = start_port + i\n        try:\n            with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:\n                s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)\n                s.bind(('localhost', port))\n                return port\n        except OSError:\n            # Port is in use, try next one\n            continue\n    raise RuntimeError(f\"Could not find an available port starting from {start_port} after {max_attempts} attempts\")\n\n\nclass ModelRunner:\n\n    def __init__(self, config: Config, rank: int, event: Event | list[Event]):\n        # Enable capturing scalar outputs to avoid graph breaks from Tensor.item() calls\n        torch._dynamo.config.capture_scalar_outputs = True\n        \n        self.config = config\n        hf_config = config.hf_config\n        self.block_size = config.kvcache_block_size\n        self.enforce_eager = config.enforce_eager\n        self.world_size = config.tensor_parallel_size\n        self.rank = rank\n        self.event = event\n        \n        # Only initialize distributed if world_size > 1\n        if self.world_size > 1:\n            dist_port = find_available_port()\n            print(f\"[debug]dist_port: {dist_port}\")\n            # Use gloo backend on Windows, nccl on Linux/other platforms\n            backend = \"gloo\" if sys.platform == \"win32\" else \"nccl\"\n            dist_utils.initialize_distributed(backend, f\"tcp://127.0.0.1:{dist_port}\", world_size=self.world_size, rank=rank)\n        \n        torch.cuda.set_device(rank)\n        default_dtype = torch.get_default_dtype()\n        \n        # Detect GPU compute capability to determine bfloat16 support\n        # Bfloat16 requires Ampere (compute capability >= 8.0) or newer\n        gpu_props = torch.cuda.get_device_properties(rank)\n        # Use tuple comparison to handle compute capability correctly\n        # (e.g., 7.5 < 8.0, 8.0 >= 8.0, 8.6 >= 8.0, etc.)\n        supports_bfloat16 = (gpu_props.major, gpu_props.minor) >= (8, 0)\n        \n        # Use dtype instead of deprecated torch_dtype\n        config_dtype = getattr(hf_config, 'dtype', getattr(hf_config, 'torch_dtype', torch.bfloat16))\n\n        # Validate and convert config_dtype to a valid torch floating-point dtype\n        # Default to bfloat16 for CUDA (required for Flash Attention 2) if GPU supports it\n        if config_dtype is None:\n            config_dtype = torch.bfloat16 if supports_bfloat16 else torch.float16\n        elif isinstance(config_dtype, str):\n            # Convert string dtype to torch dtype\n            dtype_map = {\n                'float32': torch.float32,\n                'float16': torch.float16,\n                'bfloat16': torch.bfloat16,\n                'float64': torch.float64,\n                'torch.float32': torch.float32,\n                'torch.float16': torch.float16,\n                'torch.bfloat16': torch.bfloat16,\n                'torch.float64': torch.float64,\n            }\n            config_dtype = dtype_map.get(config_dtype.lower(), torch.bfloat16 if supports_bfloat16 else torch.float16)\n        elif not isinstance(config_dtype, torch.dtype) or not config_dtype.is_floating_point:\n            # If not a valid floating-point torch dtype, default based on GPU capability\n            config_dtype = torch.bfloat16 if supports_bfloat16 else torch.float16\n        \n        # Override to float16 if config requested bfloat16 but GPU doesn't support it\n        if config_dtype == torch.bfloat16 and not supports_bfloat16:\n            print(f\"[nanovllm] GPU {gpu_props.name} (compute capability {gpu_props.major}.{gpu_props.minor}) does not support bfloat16. Using float16 instead.\", flush=True)\n            config_dtype = torch.float16\n\n        self.dtype = config_dtype  # Save for later use\n        torch.set_default_dtype(config_dtype)\n        torch.set_default_device(\"cuda\")\n        self.model = Qwen3ForCausalLM(hf_config)\n        _t0 = debug_start(\"load_model\", prefix=\"tensor.vllm\")\n        load_model(self.model, config.model)\n        debug_end(\"load_model\", _t0, prefix=\"tensor.vllm\")\n        self.sampler = Sampler()\n        \n        # Pre-allocate buffers for sampling (optimization: avoid repeated tensor creation)\n        # Must be called before warmup_model() since it uses these buffers\n        self._allocate_sample_buffers()\n        \n        self.warmup_model()\n        self.allocate_kv_cache()\n        if not self.enforce_eager:\n            self.capture_cudagraph()\n        \n        torch.set_default_device(\"cpu\")\n        torch.set_default_dtype(default_dtype)\n\n        if self.world_size > 1:\n            if rank == 0:\n                self.shm = SharedMemory(name=\"nanovllm\", create=True, size=2**20)\n                dist_utils.barrier()\n            else:\n                dist_utils.barrier()\n                self.shm = SharedMemory(name=\"nanovllm\")\n                self.loop()\n\n    def _allocate_sample_buffers(self):\n        \"\"\"Pre-allocate reusable buffers for sampling to avoid repeated tensor creation.\"\"\"\n        _t0 = debug_start(\"_allocate_sample_buffers\", prefix=\"tensor.vllm\")\n        max_bs = self.config.max_num_seqs\n        max_tokens = self.config.max_num_batched_tokens\n        max_num_blocks = (self.config.max_model_len + self.block_size - 1) // self.block_size\n        \n        # Pre-allocate pinned memory buffers on CPU for fast transfer\n        # Must explicitly specify device=\"cpu\" since default device may be \"cuda\"\n        self._cpu_temperatures = torch.zeros(max_bs, dtype=torch.float32, device=\"cpu\", pin_memory=True)\n        self._cpu_cfg_scales = torch.zeros(max_bs, dtype=torch.float32, device=\"cpu\", pin_memory=True)\n        self._cpu_top_ks = torch.zeros(max_bs, dtype=torch.int32, device=\"cpu\", pin_memory=True)\n        self._cpu_top_ps = torch.zeros(max_bs, dtype=torch.float32, device=\"cpu\", pin_memory=True)\n        self._cpu_repetition_penalties = torch.zeros(max_bs, dtype=torch.float32, device=\"cpu\", pin_memory=True)\n        \n        # Pre-allocate decode buffers on CPU with pinned memory\n        self._cpu_input_ids = torch.zeros(max_bs, dtype=torch.int64, device=\"cpu\", pin_memory=True)\n        self._cpu_positions = torch.zeros(max_bs, dtype=torch.int64, device=\"cpu\", pin_memory=True)\n        self._cpu_slot_mapping = torch.zeros(max_bs, dtype=torch.int32, device=\"cpu\", pin_memory=True)\n        self._cpu_context_lens = torch.zeros(max_bs, dtype=torch.int32, device=\"cpu\", pin_memory=True)\n        \n        # Pre-allocate prefill buffers on CPU with pinned memory (optimization to avoid repeated tensor creation)\n        self._cpu_prefill_input_ids = torch.zeros(max_tokens, dtype=torch.int64, device=\"cpu\", pin_memory=True)\n        self._cpu_prefill_positions = torch.zeros(max_tokens, dtype=torch.int64, device=\"cpu\", pin_memory=True)\n        self._cpu_prefill_cu_seqlens = torch.zeros(max_bs + 1, dtype=torch.int32, device=\"cpu\", pin_memory=True)\n        self._cpu_prefill_slot_mapping = torch.zeros(max_tokens, dtype=torch.int32, device=\"cpu\", pin_memory=True)\n        \n        # Pre-allocate block tables buffer (shared by both decode and prefill)\n        self._cpu_block_tables = torch.zeros(max_bs, max_num_blocks, dtype=torch.int32, device=\"cpu\", pin_memory=True)\n        \n        # Pre-allocate buffer for sequence token IDs (used in logits processor and sampler)\n        # Max length is max_model_len since sequences can be that long\n        self._seq_token_ids_buffer = torch.zeros(max_bs, self.config.max_model_len, dtype=torch.int64, device=\"cpu\", pin_memory=True)\n        debug_end(\"_allocate_sample_buffers\", _t0, prefix=\"tensor.vllm\")\n\n    def exit(self):\n        if self.world_size > 1:\n            self.shm.close()\n            dist_utils.barrier()\n            if self.rank == 0:\n                self.shm.unlink()\n        if not self.enforce_eager:\n            del self.graphs, self.graph_pool\n        torch.cuda.synchronize()\n        dist_utils.destroy_process_group()\n\n    def loop(self):\n        while True:\n            method_name, args = self.read_shm()\n            self.call(method_name, *args)\n            if method_name == \"exit\":\n                break\n\n    def read_shm(self):\n        assert self.world_size > 1 and self.rank > 0\n        self.event.wait()\n        n = int.from_bytes(self.shm.buf[0:4], \"little\")\n        method_name, *args = pickle.loads(self.shm.buf[4:n+4])\n        self.event.clear()\n        return method_name, args\n\n    def write_shm(self, method_name, *args):\n        assert self.world_size > 1 and self.rank == 0\n        data = pickle.dumps([method_name, *args])\n        n = len(data)\n        self.shm.buf[0:4] = n.to_bytes(4, \"little\")\n        self.shm.buf[4:n+4] = data\n        for event in self.event:\n            event.set()\n\n    def call(self, method_name, *args):\n        if self.world_size > 1 and self.rank == 0:\n            self.write_shm(method_name, *args)\n        method = getattr(self, method_name, None)\n        return method(*args)\n\n    def warmup_model(self):\n        _t0 = debug_start(\"warmup_model\", prefix=\"tensor.vllm\")\n        torch.cuda.empty_cache()\n        torch.cuda.reset_peak_memory_stats()\n        max_num_batched_tokens, max_model_len = self.config.max_num_batched_tokens, self.config.max_model_len\n        num_seqs = min(max_num_batched_tokens // max_model_len, self.config.max_num_seqs)\n        seqs = [Sequence([0] * max_model_len) for _ in range(num_seqs)]\n        self.run(seqs, True)\n        torch.cuda.empty_cache()\n        debug_end(\"warmup_model\", _t0, prefix=\"tensor.vllm\")\n\n    def allocate_kv_cache(self):\n        _t0 = debug_start(\"allocate_kv_cache\", prefix=\"tensor.vllm\")\n        config = self.config\n        hf_config = config.hf_config\n        free, total = torch.cuda.mem_get_info()\n        current = torch.cuda.memory_stats()[\"allocated_bytes.all.current\"]\n        \n        # Account for per-process memory fraction (set via MAX_CUDA_VRAM simulation)\n        import os as _os\n        _debug_vram = _os.environ.get(\"MAX_CUDA_VRAM\")\n        if _debug_vram is not None:\n            try:\n                _simulated_gb = float(_debug_vram)\n                _total_gb = total / (1024 ** 3)\n                if _simulated_gb < _total_gb:\n                    # Effective total and free are capped by simulation\n                    reserved = torch.cuda.memory_reserved()\n                    total = int(_simulated_gb * (1024 ** 3))\n                    free = max(0, total - reserved)\n            except (ValueError, TypeError):\n                pass\n        \n        num_kv_heads = hf_config.num_key_value_heads // self.world_size\n        head_dim = getattr(hf_config, \"head_dim\", hf_config.hidden_size // hf_config.num_attention_heads)\n        block_bytes = 2 * hf_config.num_hidden_layers * self.block_size * num_kv_heads * head_dim * self.dtype.itemsize\n        \n        # Calculate available memory for KV cache\n        # After warmup_model, empty_cache has been called, so current represents model memory only\n        # Use free memory but respect the gpu_memory_utilization limit\n        target_total_usage = total * config.gpu_memory_utilization\n        available_for_kv_cache = min(free * 0.9, target_total_usage - current)\n        \n        # Safety check: ensure we leave at least ~1 GB free for DiT inference\n        # activations that will run after LM generation. Without this, the KV\n        # cache can consume all free VRAM and cause OOM during DiT forward pass.\n        MIN_RESERVE_BYTES = int(1.0 * 1024**3)  # 1 GB reserved for other models\n        max_kv_from_free = max(0, free - MIN_RESERVE_BYTES) * 0.9\n        available_for_kv_cache = min(available_for_kv_cache, max_kv_from_free)\n        \n        # Ensure we have positive memory available\n        if available_for_kv_cache <= 0:\n            available_for_kv_cache = free * 0.5  # Fallback to 50% of free memory\n        \n        config.num_kvcache_blocks = max(1, int(available_for_kv_cache) // block_bytes)\n        if config.num_kvcache_blocks <= 0:\n            raise RuntimeError(\n                f\"Insufficient GPU memory for KV cache. \"\n                f\"Free: {free / 1024**3:.2f} GB, Current: {current / 1024**3:.2f} GB, \"\n                f\"Available for KV: {available_for_kv_cache / 1024**3:.2f} GB, \"\n                f\"Block size: {block_bytes / 1024**2:.2f} MB\"\n            )\n        max_tokens_capacity = config.num_kvcache_blocks * self.block_size\n        kv_cache_size_gb = config.num_kvcache_blocks * block_bytes / 1024**3\n        \n        # If KV cache would leave less than 1 GB free, warn and suggest reducing max_model_len\n        post_kv_free = (free - config.num_kvcache_blocks * block_bytes) / 1024**3\n        if post_kv_free < 1.0:\n            print(\n                f\"[nanovllm] WARNING: After KV cache allocation, only {post_kv_free:.2f} GB free. \"\n                f\"DiT inference may OOM. Consider reducing max_model_len or using CPU offload.\"\n            )\n        \n        print(\n            f\"[nanovllm] KV cache allocated: {config.num_kvcache_blocks} blocks × {self.block_size} tokens = \"\n            f\"{max_tokens_capacity} tokens capacity, {kv_cache_size_gb:.2f} GB \"\n            f\"(free: {free / 1024**3:.2f} GB, used: {current / 1024**3:.2f} GB, \"\n            f\"target: {target_total_usage / 1024**3:.2f} GB, block: {block_bytes / 1024**2:.2f} MB, \"\n            f\"post_kv_free: {post_kv_free:.2f} GB)\"\n        )\n        self.kv_cache = torch.empty(2, hf_config.num_hidden_layers, config.num_kvcache_blocks, self.block_size, num_kv_heads, head_dim)\n        layer_id = 0\n        for module in self.model.modules():\n            if hasattr(module, \"k_cache\") and hasattr(module, \"v_cache\"):\n                module.k_cache = self.kv_cache[0, layer_id]\n                module.v_cache = self.kv_cache[1, layer_id]\n                layer_id += 1\n        debug_end(\"allocate_kv_cache\", _t0, prefix=\"tensor.vllm\")\n\n    def prepare_block_tables(self, seqs: list[Sequence]):\n        _t0 = debug_start(\"prepare_block_tables\", prefix=\"tensor.vllm\")\n        max_len = max(len(seq.block_table) for seq in seqs)\n        block_tables = [seq.block_table + [-1] * (max_len - len(seq.block_table)) for seq in seqs]\n        block_tables = torch.tensor(block_tables, dtype=torch.int32, pin_memory=True).cuda(non_blocking=True)\n        debug_end(\"prepare_block_tables\", _t0, prefix=\"tensor.vllm\")\n        return block_tables\n\n    def prepare_prefill(self, seqs: list[Sequence]):\n        _t0 = debug_start(\"prepare_prefill\", prefix=\"tensor.vllm\")\n        input_ids = []\n        positions = []\n        cu_seqlens_q = [0]\n        cu_seqlens_k = [0]\n        max_seqlen_q = 0\n        max_seqlen_k = 0\n        slot_mapping = []\n        block_tables = None\n        for seq in seqs:\n            seqlen = len(seq)\n            input_ids.extend(seq[seq.num_cached_tokens:])\n            positions.extend(list(range(seq.num_cached_tokens, seqlen)))\n            seqlen_q = seqlen - seq.num_cached_tokens\n            seqlen_k = seqlen\n            cu_seqlens_q.append(cu_seqlens_q[-1] + seqlen_q)\n            cu_seqlens_k.append(cu_seqlens_k[-1] + seqlen_k)\n            max_seqlen_q = max(seqlen_q, max_seqlen_q)\n            max_seqlen_k = max(seqlen_k, max_seqlen_k)\n            if not seq.block_table:    # warmup\n                continue\n            for i in range(seq.num_cached_blocks, seq.num_blocks):\n                start = seq.block_table[i] * self.block_size\n                if i != seq.num_blocks - 1:\n                    end = start + self.block_size\n                else:\n                    end = start + seq.last_block_num_tokens\n                slot_mapping.extend(list(range(start, end)))\n        if cu_seqlens_k[-1] > cu_seqlens_q[-1]:    # prefix cache\n            block_tables = self.prepare_block_tables(seqs)\n        input_ids = torch.tensor(input_ids, dtype=torch.int64, pin_memory=True).cuda(non_blocking=True)\n        positions = torch.tensor(positions, dtype=torch.int64, pin_memory=True).cuda(non_blocking=True)\n        cu_seqlens_q = torch.tensor(cu_seqlens_q, dtype=torch.int32, pin_memory=True).cuda(non_blocking=True)\n        cu_seqlens_k = torch.tensor(cu_seqlens_k, dtype=torch.int32, pin_memory=True).cuda(non_blocking=True)\n        slot_mapping = torch.tensor(slot_mapping, dtype=torch.int32, pin_memory=True).cuda(non_blocking=True)\n        set_context(True, cu_seqlens_q, cu_seqlens_k, max_seqlen_q, max_seqlen_k, slot_mapping, None, block_tables)\n        debug_end(\"prepare_prefill\", _t0, prefix=\"tensor.vllm\")\n        return input_ids, positions\n\n    def prepare_decode(self, seqs: list[Sequence]):\n        \"\"\"Optimized decode preparation using pre-allocated buffers.\"\"\"\n        _t0 = debug_start(\"prepare_decode\", prefix=\"tensor.vllm\")\n        bs = len(seqs)\n        \n        # Use pre-allocated CPU buffers\n        for i, seq in enumerate(seqs):\n            self._cpu_input_ids[i] = seq.last_token\n            self._cpu_positions[i] = len(seq) - 1\n            self._cpu_context_lens[i] = len(seq)\n            self._cpu_slot_mapping[i] = seq.block_table[-1] * self.block_size + seq.last_block_num_tokens - 1\n        \n        # Transfer to GPU using sliced views\n        input_ids = self._cpu_input_ids[:bs].cuda(non_blocking=True)\n        positions = self._cpu_positions[:bs].cuda(non_blocking=True)\n        slot_mapping = self._cpu_slot_mapping[:bs].cuda(non_blocking=True)\n        context_lens = self._cpu_context_lens[:bs].cuda(non_blocking=True)\n        block_tables = self.prepare_block_tables(seqs)\n        set_context(False, slot_mapping=slot_mapping, context_lens=context_lens, block_tables=block_tables)\n        debug_end(\"prepare_decode\", _t0, prefix=\"tensor.vllm\")\n        return input_ids, positions\n\n    def prepare_sample(self, seqs: list[Sequence], is_cfg_batch: bool = False):\n        \"\"\"Optimized sample preparation using pre-allocated buffers.\"\"\"\n        _t0 = debug_start(\"prepare_sample\", prefix=\"tensor.vllm\")\n        if is_cfg_batch:\n            num_seqs = len(seqs) // 2\n            target_seqs = seqs[:num_seqs]\n        else:\n            num_seqs = len(seqs)\n            target_seqs = seqs\n        \n        # Fill pre-allocated CPU buffers\n        top_ks_is_zero = True\n        top_ps_is_one = True\n        repetition_penalties_is_one = True\n        for i, seq in enumerate(target_seqs):\n            self._cpu_temperatures[i] = seq.temperature\n            self._cpu_cfg_scales[i] = seq.cfg_scale\n            self._cpu_top_ks[i] = seq.top_k if seq.top_k is not None else 0\n            if seq.top_k is not None and seq.top_k > 0:\n                top_ks_is_zero = False\n            self._cpu_top_ps[i] = seq.top_p if seq.top_p is not None else 1.0\n            if seq.top_p is not None and seq.top_p == 1.0:\n                top_ps_is_one = False\n            self._cpu_repetition_penalties[i] = seq.repetition_penalty if seq.repetition_penalty is not None else 1.0\n            if seq.repetition_penalty is not None and seq.repetition_penalty == 1.0:\n                repetition_penalties_is_one = False\n        \n        # Transfer to GPU using sliced views (single batched transfer)\n        temperatures = self._cpu_temperatures[:num_seqs].cuda(non_blocking=True)\n        cfg_scales = self._cpu_cfg_scales[:num_seqs].cuda(non_blocking=True)\n        top_ks = self._cpu_top_ks[:num_seqs].cuda(non_blocking=True) if not top_ks_is_zero else None\n        top_ps = self._cpu_top_ps[:num_seqs].cuda(non_blocking=True) if not top_ps_is_one else None\n        repetition_penalties = self._cpu_repetition_penalties[:num_seqs].cuda(non_blocking=True) if not repetition_penalties_is_one else None\n        \n        debug_end(\"prepare_sample\", _t0, prefix=\"tensor.vllm\")\n        return temperatures, cfg_scales, top_ks, top_ps, repetition_penalties\n\n    @torch.inference_mode()\n    def run_model(self, input_ids: torch.Tensor, positions: torch.Tensor, is_prefill: bool):\n        _t0 = debug_start(\"run_model\", prefix=\"tensor.vllm\")\n        if is_prefill or self.enforce_eager or input_ids.size(0) > 512:\n            _debug_log(f\"run_model: eager mode, is_prefill={is_prefill}, bs={input_ids.size(0)}\")\n            out = self.model.compute_logits(self.model(input_ids, positions))\n            debug_end(\"run_model\", _t0, prefix=\"tensor.vllm\")\n            return out\n        else:\n            bs = input_ids.size(0)\n            context = get_context()\n            \n            _debug_log(f\"run_model: decode mode, bs={bs}\")\n            _debug_log(f\"  context.block_tables.shape={context.block_tables.shape}\")\n            _debug_log(f\"  context.slot_mapping.shape={context.slot_mapping.shape}\")\n            _debug_log(f\"  context.context_lens.shape={context.context_lens.shape}\")\n            _debug_log(f\"  context.slot_mapping={context.slot_mapping.tolist()}\")\n            _debug_log(f\"  context.context_lens={context.context_lens.tolist()}\")\n            \n            # Check if block_tables size exceeds pre-allocated buffer size\n            # This can happen when conditional and unconditional sequences have different lengths\n            # in CFG mode, causing block_tables to have more columns than expected\n            max_num_blocks = self.graph_vars[\"block_tables\"].size(1)\n            if context.block_tables.size(1) > max_num_blocks:\n                # Fall back to eager mode when block_tables is too large for CUDA graph\n                _debug_log(f\"  fallback: block_tables cols {context.block_tables.size(1)} > max {max_num_blocks}\")\n                out = self.model.compute_logits(self.model(input_ids, positions))\n                debug_end(\"run_model\", _t0, prefix=\"tensor.vllm\")\n                return out\n            \n            # Fix: Also check if block_tables row count matches batch size\n            # Dimension mismatch can cause CUDA illegal memory access during graph replay\n            if context.block_tables.size(0) != bs:\n                # Fall back to eager mode when block_tables row count doesn't match batch size\n                _debug_log(f\"  fallback: block_tables rows {context.block_tables.size(0)} != bs {bs}\")\n                out = self.model.compute_logits(self.model(input_ids, positions))\n                debug_end(\"run_model\", _t0, prefix=\"tensor.vllm\")\n                return out\n            \n            # Fix: Verify slot_mapping and context_lens dimensions match batch size\n            if context.slot_mapping.size(0) != bs or context.context_lens.size(0) != bs:\n                # Fall back to eager mode when dimensions don't match\n                _debug_log(f\"  fallback: slot_mapping/context_lens size mismatch\")\n                out = self.model.compute_logits(self.model(input_ids, positions))\n                debug_end(\"run_model\", _t0, prefix=\"tensor.vllm\")\n                return out\n            \n            # Validate block_tables values\n            if _DEBUG:\n                max_block_id = context.block_tables.max().item()\n                min_block_id = context.block_tables[context.block_tables >= 0].min().item() if (context.block_tables >= 0).any() else -1\n                _debug_log(f\"  block_tables range: [{min_block_id}, {max_block_id}]\")\n                _debug_log(f\"  num_kvcache_blocks: {self.config.num_kvcache_blocks}\")\n                if max_block_id >= self.config.num_kvcache_blocks:\n                    _debug_log(f\"  WARNING: block_table contains invalid block_id {max_block_id} >= {self.config.num_kvcache_blocks}\")\n            \n            graph = self.graphs[next(x for x in self.graph_bs if x >= bs)]\n            graph_vars = self.graph_vars\n            graph_vars[\"input_ids\"][:bs] = input_ids\n            graph_vars[\"positions\"][:bs] = positions\n            graph_vars[\"slot_mapping\"].fill_(-1)\n            graph_vars[\"slot_mapping\"][:bs] = context.slot_mapping\n            graph_vars[\"context_lens\"].zero_()\n            graph_vars[\"context_lens\"][:bs] = context.context_lens\n            # Clear block_tables first to ensure no stale data from previous runs\n            graph_vars[\"block_tables\"][:bs].fill_(-1)\n            graph_vars[\"block_tables\"][:bs, :context.block_tables.size(1)] = context.block_tables\n            \n            _debug_log(f\"  executing CUDA graph replay for bs={bs}\")\n            graph.replay()\n            out = self.model.compute_logits(graph_vars[\"outputs\"][:bs])\n            debug_end(\"run_model\", _t0, prefix=\"tensor.vllm\")\n            return out\n\n    def run(self, seqs: list[Sequence], is_prefill: bool) -> list[int]:\n        \"\"\"Run model forward and sampling. For CFG sequences, batch is structured as:\n        [cond_seq1, cond_seq2, ..., uncond_seq1, uncond_seq2, ...]\n        where uncond_seqi is the paired unconditional sequence of cond_seqi.\"\"\"\n        _debug_log(f\"run: num_seqs={len(seqs)}, is_prefill={is_prefill}\")\n        for i, seq in enumerate(seqs):\n            _debug_log(f\"  seq[{i}]: len={len(seq)}, num_blocks={seq.num_blocks}, \"\n                      f\"cfg_scale={seq.cfg_scale}, is_uncond={seq.is_unconditional}, \"\n                      f\"block_table={seq.block_table}\")\n        \n        # Check if this is a CFG batch (contains paired conditional and unconditional sequences)\n        is_cfg_batch = seqs[0].cfg_scale > 1.0 and seqs[0].paired_seq is not None\n        _debug_log(f\"  is_cfg_batch={is_cfg_batch}\")\n        if is_cfg_batch:\n            # CFG batch: seqs = [cond_seq1, cond_seq2, ..., uncond_seq1, uncond_seq2, ...]\n            num_cond = len(seqs) // 2\n            cond_seqs = seqs[:num_cond]\n            # uncond_seqs = seqs[num_cond:]\n            \n            # Prepare inputs for both conditional and unconditional (they're already in the batch)\n            input_ids, positions = (self.prepare_prefill(seqs) if is_prefill else self.prepare_decode(seqs))\n            sample_params = self.prepare_sample(seqs, is_cfg_batch=True) if self.rank == 0 else None\n            if sample_params is not None:\n                temperatures, cfg_scales, top_ks, top_ps, repetition_penalties = sample_params\n            else:\n                temperatures = cfg_scales = top_ks = top_ps = repetition_penalties = None\n            \n            # Run model forward (processes entire batch: cond + uncond)\n            logits_all = self.run_model(input_ids, positions, is_prefill)\n            reset_context()\n            \n            if self.rank == 0:\n                # Split logits: first half is conditional, second half is unconditional\n                logits_cond = logits_all[:num_cond]\n                logits_uncond = logits_all[num_cond:]\n                \n                # Apply repetition penalty to conditional logits (before CFG)\n                if repetition_penalties is not None:\n                    for i, seq in enumerate(cond_seqs):\n                        penalty = repetition_penalties[i].item()\n                        if penalty != 1.0:\n                            # Only penalize completion tokens (not prompt tokens)\n                            completion_tokens = torch.tensor(seq.completion_token_ids, device=logits_cond.device)\n                            if len(completion_tokens) > 0:\n                                # Create token mask: mark tokens that appeared in completion\n                                token_mask = torch.zeros(logits_cond.shape[1], dtype=torch.bool, device=logits_cond.device)\n                                token_mask[completion_tokens] = True\n                                \n                                # Apply standard repetition penalty formula (matching transformers implementation):\n                                # For tokens in completion: if score < 0 then score * penalty, else score / penalty\n                                penalty_scores = torch.where(\n                                    logits_cond[i] < 0,\n                                    logits_cond[i] * penalty,\n                                    logits_cond[i] / penalty\n                                )\n                                # Only apply penalty to tokens that appeared in completion\n                                logits_cond[i] = torch.where(token_mask, penalty_scores, logits_cond[i])\n                \n                # Apply CFG formula: logits_cfg = logits_uncond + cfg_scale * (logits_cond - logits_uncond)\n                cfg_scales_tensor = cfg_scales.unsqueeze(1)  # [num_cond, 1]\n                logits_cfg = logits_uncond + cfg_scales_tensor * (logits_cond - logits_uncond)\n                \n                # Apply logits processor for constrained decoding (if any sequence has one)\n                for i, seq in enumerate(cond_seqs):\n                    if seq.logits_processor is not None:\n                        # Create input_ids tensor for this sequence\n                        seq_input_ids = torch.tensor([seq.token_ids], device=logits_cfg.device)\n                        # Apply processor to this sequence's logits\n                        logits_cfg[i:i+1] = seq.logits_processor(seq_input_ids, logits_cfg[i:i+1])\n                \n                # Prepare input_ids for sampler (for repetition penalty, though we already applied it)\n                # cond_input_ids = torch.tensor([seq.token_ids for seq in cond_seqs], device=logits_cfg.device)\n                \n                # Sample from CFG logits\n                token_ids_cfg = self.sampler(\n                    logits_cfg, \n                    temperatures,\n                    top_ks=top_ks if top_ks is not None else None,\n                    top_ps=top_ps if top_ps is not None else None,\n                    repetition_penalties=None,  # Already applied above\n                    # input_ids=cond_input_ids,\n                ).tolist()\n                \n                # Update logits processor state after sampling\n                # NOTE: Only update for the first sequence since all sequences share the same processor\n                # Updating multiple times would cause duplicate state updates (e.g., codes_count += N instead of += 1)\n                if cond_seqs and cond_seqs[0].logits_processor_update_state is not None:\n                    cond_seqs[0].logits_processor_update_state(token_ids_cfg[0])\n                \n                # Return token_ids (will be applied to both conditional and unconditional sequences)\n                return token_ids_cfg\n            else:\n                return None\n        else:\n            # Normal batch (non-CFG)\n            input_ids, positions = (self.prepare_prefill(seqs) if is_prefill \n                                   else self.prepare_decode(seqs))\n            sample_params = self.prepare_sample(seqs, is_cfg_batch=False) if self.rank == 0 else None\n            if sample_params is not None:\n                temperatures, cfg_scales, top_ks, top_ps, repetition_penalties = sample_params\n            else:\n                temperatures = cfg_scales = top_ks = top_ps = repetition_penalties = None\n            logits = self.run_model(input_ids, positions, is_prefill)\n            reset_context()\n            \n            if self.rank == 0:\n                # Apply repetition penalty to logits\n                if repetition_penalties is not None:\n                    for i, seq in enumerate(seqs):\n                        penalty = repetition_penalties[i].item()\n                        if penalty != 1.0:\n                            # Only penalize completion tokens (not prompt tokens)\n                            completion_tokens = torch.tensor(seq.completion_token_ids, device=logits.device)\n                            if len(completion_tokens) > 0:\n                                # Create token mask: mark tokens that appeared in completion\n                                token_mask = torch.zeros(logits.shape[1], dtype=torch.bool, device=logits.device)\n                                token_mask[completion_tokens] = True\n                                \n                                # Apply standard repetition penalty formula (matching transformers implementation):\n                                # For tokens in completion: if score < 0 then score * penalty, else score / penalty\n                                penalty_scores = torch.where(\n                                    logits[i] < 0,\n                                    logits[i] * penalty,\n                                    logits[i] / penalty\n                                )\n                                # Only apply penalty to tokens that appeared in completion\n                                logits[i] = torch.where(token_mask, penalty_scores, logits[i])\n                \n                # Apply logits processor for constrained decoding (if any sequence has one)\n                # Clone logits to avoid in-place update issues in inference mode\n                logits = logits.clone()\n                for i, seq in enumerate(seqs):\n                    if seq.logits_processor is not None:\n                        # Create input_ids tensor for this sequence\n                        seq_input_ids = torch.tensor([seq.token_ids], device=logits.device)\n                        # Apply processor to this sequence's logits (clone to avoid inference mode issues)\n                        processed = seq.logits_processor(seq_input_ids, logits[i:i+1].clone())\n                        logits[i] = processed[0]\n                \n                # Prepare input_ids for sampler\n                # seq_input_ids = torch.tensor([seq.token_ids for seq in seqs], device=logits.device)\n                \n                token_ids = self.sampler(\n                    logits, \n                    temperatures,\n                    top_ks=top_ks if top_ks is not None else None,\n                    top_ps=top_ps if top_ps is not None else None,\n                    repetition_penalties=None,  # Already applied above\n                    # input_ids=seq_input_ids,\n                ).tolist()\n                \n                # Update logits processor state after sampling\n                # NOTE: Only update for the first sequence since all sequences may share the same processor\n                # (when using a single SamplingParams for batch generation)\n                # Updating multiple times would cause duplicate state updates (e.g., codes_count += N instead of += 1)\n                if seqs and seqs[0].logits_processor_update_state is not None:\n                    seqs[0].logits_processor_update_state(token_ids[0])\n                \n                return token_ids\n            else:\n                return None\n\n    @torch.inference_mode()\n    def capture_cudagraph(self):\n        _t0 = debug_start(\"capture_cudagraph\", prefix=\"tensor.vllm\")\n        config = self.config\n        hf_config = config.hf_config\n        max_bs = min(self.config.max_num_seqs, 512)\n        max_num_blocks = (config.max_model_len + self.block_size - 1) // self.block_size\n        input_ids = torch.zeros(max_bs, dtype=torch.int64)\n        positions = torch.zeros(max_bs, dtype=torch.int64)\n        slot_mapping = torch.zeros(max_bs, dtype=torch.int32)\n        context_lens = torch.zeros(max_bs, dtype=torch.int32)\n        block_tables = torch.zeros(max_bs, max_num_blocks, dtype=torch.int32)\n        outputs = torch.zeros(max_bs, hf_config.hidden_size)\n        self.graph_bs = [1, 2, 4, 8] + list(range(16, max_bs + 1, 16))\n        self.graphs = {}\n        self.graph_pool = None\n\n        for bs in reversed(self.graph_bs):\n            graph = torch.cuda.CUDAGraph()\n            set_context(False, slot_mapping=slot_mapping[:bs], context_lens=context_lens[:bs], block_tables=block_tables[:bs])\n            outputs[:bs] = self.model(input_ids[:bs], positions[:bs])    # warmup\n            with torch.cuda.graph(graph, self.graph_pool):\n                outputs[:bs] = self.model(input_ids[:bs], positions[:bs])    # capture\n            if self.graph_pool is None:\n                self.graph_pool = graph.pool()\n            self.graphs[bs] = graph\n            torch.cuda.synchronize()\n            reset_context()\n\n        self.graph_vars = dict(\n            input_ids=input_ids,\n            positions=positions,\n            slot_mapping=slot_mapping,\n            context_lens=context_lens,\n            block_tables=block_tables,\n            outputs=outputs,\n        )\n        debug_end(\"capture_cudagraph\", _t0, prefix=\"tensor.vllm\")\n"
  },
  {
    "path": "acestep/third_parts/nano-vllm/nanovllm/engine/scheduler.py",
    "content": "import os\nfrom collections import deque\n\nfrom nanovllm.config import Config\nfrom nanovllm.engine.sequence import Sequence, SequenceStatus\nfrom nanovllm.engine.block_manager import BlockManager\n\n# Debug logging - enable with NANOVLLM_DEBUG=1\n_DEBUG = os.environ.get(\"NANOVLLM_DEBUG\", \"0\") == \"1\"\n\ndef _debug_log(msg: str):\n    \"\"\"Print debug message if NANOVLLM_DEBUG is enabled\"\"\"\n    if _DEBUG:\n        print(f\"[nanovllm scheduler DEBUG] {msg}\", flush=True)\n\n\nclass Scheduler:\n\n    def __init__(self, config: Config):\n        self.max_num_seqs = config.max_num_seqs\n        self.max_num_batched_tokens = config.max_num_batched_tokens\n        self.eos = config.eos\n        self.block_manager = BlockManager(config.num_kvcache_blocks, config.kvcache_block_size)\n        self.waiting: deque[Sequence] = deque()\n        self.running: deque[Sequence] = deque()\n\n    def is_finished(self):\n        return not self.waiting and not self.running\n\n    def add(self, seq: Sequence):\n        self.waiting.append(seq)\n\n    def schedule(self) -> tuple[list[Sequence], bool]:\n        _debug_log(f\"schedule: waiting={len(self.waiting)}, running={len(self.running)}, \"\n                  f\"free_blocks={len(self.block_manager.free_block_ids)}\")\n        \n        # prefill\n        scheduled_seqs = []\n        num_seqs = 0\n        num_batched_tokens = 0\n        processed_seqs = set()  # Track processed sequences to handle CFG pairs\n        \n        while self.waiting and num_seqs < self.max_num_seqs:\n            seq = self.waiting[0]\n            \n            # For CFG sequences, ensure conditional and unconditional are scheduled together\n            if seq.cfg_scale > 1.0 and seq.paired_seq is not None and not seq.is_unconditional:\n                # This is a conditional sequence, need to schedule its paired unconditional sequence too\n                paired_seq = seq.paired_seq\n                if paired_seq.status != SequenceStatus.WAITING:\n                    # Paired sequence not in waiting, skip this conditional sequence for now\n                    break\n                \n                # Calculate tokens for both sequences\n                total_tokens = (len(seq) - seq.num_cached_tokens) + (len(paired_seq) - paired_seq.num_cached_tokens)\n                \n                # FIX: Check if we have enough blocks for BOTH sequences combined\n                # The old check was wrong: it checked each sequence independently,\n                # but didn't account for the total blocks needed by both\n                total_blocks_needed = seq.num_blocks + paired_seq.num_blocks\n                can_allocate_both = len(self.block_manager.free_block_ids) >= total_blocks_needed\n                \n                if num_batched_tokens + total_tokens > self.max_num_batched_tokens or not can_allocate_both:\n                    break\n                \n                # Schedule both sequences: conditional first, then unconditional\n                for s in [seq, paired_seq]:\n                    num_seqs += 1\n                    self.block_manager.allocate(s)\n                    num_batched_tokens += len(s) - s.num_cached_tokens\n                    s.status = SequenceStatus.RUNNING\n                    self.waiting.remove(s)\n                    self.running.append(s)\n                    scheduled_seqs.append(s)\n                    processed_seqs.add(s.seq_id)\n            else:\n                # Normal sequence or unconditional sequence (already processed with its conditional)\n                if seq.seq_id in processed_seqs:\n                    # Skip if already processed as part of a CFG pair\n                    self.waiting.popleft()\n                    continue\n                    \n                if num_batched_tokens + len(seq) > self.max_num_batched_tokens or not self.block_manager.can_allocate(seq):\n                    break\n                num_seqs += 1\n                self.block_manager.allocate(seq)\n                num_batched_tokens += len(seq) - seq.num_cached_tokens\n                seq.status = SequenceStatus.RUNNING\n                self.waiting.popleft()\n                self.running.append(seq)\n                scheduled_seqs.append(seq)\n                \n        if scheduled_seqs:\n            # For CFG batches, ensure conditional sequences come before their unconditional pairs\n            cfg_cond_seqs = [s for s in scheduled_seqs if s.cfg_scale > 1.0 and not s.is_unconditional]\n            cfg_uncond_seqs = [s for s in scheduled_seqs if s.is_unconditional]\n            non_cfg_seqs = [s for s in scheduled_seqs if s.cfg_scale <= 1.0]\n            \n            # Reorder: non-CFG, then CFG conditional, then CFG unconditional\n            scheduled_seqs = non_cfg_seqs + cfg_cond_seqs + cfg_uncond_seqs\n            return scheduled_seqs, True\n\n        # decode\n        processed_seqs = set()\n        temp_running = list(self.running)  # Work with a copy\n        \n        while temp_running and num_seqs < self.max_num_seqs:\n            seq = temp_running.pop(0)\n            \n            # For CFG sequences, ensure conditional and unconditional are scheduled together\n            if seq.cfg_scale > 1.0 and seq.paired_seq is not None and not seq.is_unconditional:\n                paired_seq = seq.paired_seq\n                if paired_seq not in temp_running:\n                    # Paired sequence not available, skip for now\n                    continue\n                \n                # Remove paired_seq from temp_running\n                temp_running.remove(paired_seq)\n                \n                # FIX: Check if we have enough blocks for BOTH sequences to append\n                # Each sequence needs 1 block when at block boundary (len % block_size == 1)\n                block_size = self.block_manager.block_size\n                blocks_needed_seq = 1 if len(seq) % block_size == 1 else 0\n                blocks_needed_paired = 1 if len(paired_seq) % block_size == 1 else 0\n                total_blocks_needed = blocks_needed_seq + blocks_needed_paired\n                can_append_both = len(self.block_manager.free_block_ids) >= total_blocks_needed\n                \n                if not can_append_both:\n                    # Try preempting other sequences\n                    preempted = False\n                    while not can_append_both and temp_running:\n                        other_seq = temp_running.pop(0)\n                        if other_seq != seq and other_seq != paired_seq:\n                            self.preempt(other_seq)\n                            # Recalculate with the same correct logic\n                            can_append_both = len(self.block_manager.free_block_ids) >= total_blocks_needed\n                            preempted = True\n                        else:\n                            temp_running.append(other_seq)\n                            break\n                    \n                    if not can_append_both:\n                        # Can't schedule this pair right now\n                        temp_running.append(seq)\n                        temp_running.append(paired_seq)\n                        continue\n                \n                # Schedule both sequences\n                for s in [seq, paired_seq]:\n                    num_seqs += 1\n                    self.block_manager.may_append(s)\n                    scheduled_seqs.append(s)\n                    processed_seqs.add(s.seq_id)\n                    # Remove from actual running list if scheduled\n                    if s in self.running:\n                        self.running.remove(s)\n            else:\n                # Normal sequence or unconditional (already processed)\n                if seq.seq_id in processed_seqs:\n                    continue\n                    \n                while not self.block_manager.can_append(seq):\n                    if temp_running:\n                        other_seq = temp_running.pop(0)\n                        if other_seq != seq:\n                            self.preempt(other_seq)\n                        else:\n                            temp_running.append(other_seq)\n                            break\n                    else:\n                        self.preempt(seq)\n                        if seq in self.running:\n                            self.running.remove(seq)\n                        break\n                else:\n                    num_seqs += 1\n                    self.block_manager.may_append(seq)\n                    scheduled_seqs.append(seq)\n                    if seq in self.running:\n                        self.running.remove(seq)\n                    \n        if not scheduled_seqs:\n            # No sequences could be scheduled - provide informative error\n            waiting_count = len(self.waiting)\n            running_count = len(self.running)\n            free_blocks = len(self.block_manager.free_block_ids)\n            total_blocks = len(self.block_manager.blocks)\n\n            if waiting_count > 0:\n                seq = self.waiting[0]\n                blocks_needed = seq.num_blocks\n                prompt_tokens = len(seq)\n                if seq.cfg_scale > 1.0 and seq.paired_seq is not None:\n                    blocks_needed += seq.paired_seq.num_blocks\n                    prompt_tokens = f\"{len(seq)}+{len(seq.paired_seq)}\"\n                raise RuntimeError(\n                    f\"Insufficient KV cache to schedule sequence. \"\n                    f\"Free blocks: {free_blocks}/{total_blocks}, blocks needed: {blocks_needed}, \"\n                    f\"prompt tokens: {prompt_tokens}, block size: {self.block_manager.block_size}. \"\n                    f\"The prompt may be too long for available GPU memory, or gpu_memory_utilization is too low.\"\n                )\n            else:\n                raise RuntimeError(\n                    f\"No schedulable sequences found. \"\n                    f\"Waiting: {waiting_count}, Running: {running_count}, \"\n                    f\"Free blocks: {free_blocks}/{total_blocks}\"\n                )\n\n        # For CFG batches in decode, ensure conditional sequences come before unconditional\n        cfg_cond_seqs = [s for s in scheduled_seqs if s.cfg_scale > 1.0 and not s.is_unconditional]\n        cfg_uncond_seqs = [s for s in scheduled_seqs if s.is_unconditional]\n        non_cfg_seqs = [s for s in scheduled_seqs if s.cfg_scale <= 1.0]\n        scheduled_seqs = non_cfg_seqs + cfg_cond_seqs + cfg_uncond_seqs\n        \n        self.running.extendleft(reversed(scheduled_seqs))\n        return scheduled_seqs, False\n\n    def preempt(self, seq: Sequence):\n        seq.status = SequenceStatus.WAITING\n        self.block_manager.deallocate(seq)\n        self.waiting.appendleft(seq)\n\n    def postprocess(self, seqs: list[Sequence], token_ids: list[int]) -> list[bool]:\n        _debug_log(f\"postprocess: num_seqs={len(seqs)}, num_token_ids={len(token_ids) if token_ids else 0}\")\n        if token_ids:\n            _debug_log(f\"  token_ids: {token_ids[:10]}...\" if len(token_ids) > 10 else f\"  token_ids: {token_ids}\")\n        \n        # Check if this is a CFG batch\n        is_cfg_batch = False\n        if len(seqs) > 0 and seqs[0].cfg_scale > 1.0 and seqs[0].paired_seq is not None:\n            num_cond = len(seqs) // 2\n            is_cfg_batch = (num_cond > 0 and \n                           not seqs[0].is_unconditional and \n                           seqs[num_cond].is_unconditional)\n        _debug_log(f\"  is_cfg_batch={is_cfg_batch}\")\n        \n        if is_cfg_batch:\n            # CFG batch: seqs = [cond_seq1, cond_seq2, ..., uncond_seq1, uncond_seq2, ...]\n            # token_ids correspond to conditional sequences only (sampled from CFG logits)\n            num_cond = len(seqs) // 2\n            cond_seqs = seqs[:num_cond]\n            uncond_seqs = seqs[num_cond:]\n            \n            # Apply the same sampled token to both conditional and unconditional sequences\n            for i, (cond_seq, uncond_seq, token_id) in enumerate(zip(cond_seqs, uncond_seqs, token_ids)):\n                cond_seq.append_token(token_id)\n                uncond_seq.append_token(token_id)  # Same token for unconditional\n                \n                # Check if either sequence is finished\n                cond_finished = ((not cond_seq.ignore_eos and token_id == self.eos) or \n                                cond_seq.num_completion_tokens == cond_seq.max_tokens)\n                uncond_finished = ((not uncond_seq.ignore_eos and token_id == self.eos) or \n                                  uncond_seq.num_completion_tokens == uncond_seq.max_tokens)\n                \n                if cond_finished or uncond_finished:\n                    # Mark both as finished\n                    cond_seq.status = SequenceStatus.FINISHED\n                    uncond_seq.status = SequenceStatus.FINISHED\n                    self.block_manager.deallocate(cond_seq)\n                    self.block_manager.deallocate(uncond_seq)\n                    if cond_seq in self.running:\n                        self.running.remove(cond_seq)\n                    if uncond_seq in self.running:\n                        self.running.remove(uncond_seq)\n        else:\n            # Normal batch\n            for seq, token_id in zip(seqs, token_ids):\n                seq.append_token(token_id)\n                if (not seq.ignore_eos and token_id == self.eos) or seq.num_completion_tokens == seq.max_tokens:\n                    seq.status = SequenceStatus.FINISHED\n                    self.block_manager.deallocate(seq)\n                    self.running.remove(seq)\n"
  },
  {
    "path": "acestep/third_parts/nano-vllm/nanovllm/engine/sequence.py",
    "content": "from copy import copy\nfrom enum import Enum, auto\nfrom itertools import count\nfrom typing import Optional, Callable, Any\n\nfrom nanovllm.sampling_params import SamplingParams\n\n\nclass SequenceStatus(Enum):\n    WAITING = auto()\n    RUNNING = auto()\n    FINISHED = auto()\n\n\nclass Sequence:\n    block_size = 256\n    counter = count()\n\n    def __init__(self, token_ids: list[int], sampling_params = SamplingParams(), is_unconditional: bool = False, conditional_seq = None):\n        self.seq_id = next(Sequence.counter)\n        self.status = SequenceStatus.WAITING\n        self.token_ids = copy(token_ids)\n        self.last_token = token_ids[-1]\n        self.num_tokens = len(self.token_ids)\n        self.num_prompt_tokens = len(token_ids)\n        self.num_cached_tokens = 0\n        self.block_table = []\n        self.temperature = sampling_params.temperature\n        self.max_tokens = sampling_params.max_tokens\n        self.ignore_eos = sampling_params.ignore_eos\n        self.cfg_scale = sampling_params.cfg_scale\n        self.top_k = sampling_params.top_k\n        self.top_p = sampling_params.top_p\n        self.repetition_penalty = sampling_params.repetition_penalty\n        # For CFG: mark if this is an unconditional sequence\n        self.is_unconditional = is_unconditional\n        # For CFG: reference to the corresponding conditional sequence (if this is unconditional)\n        # For conditional sequences, this points to the unconditional sequence\n        self.paired_seq = conditional_seq  # For conditional seq, points to uncond; for uncond seq, points to cond\n        # For constrained decoding: logits processor and state update callback\n        self.logits_processor: Optional[Any] = sampling_params.logits_processor\n        self.logits_processor_update_state: Optional[Callable[[int], None]] = sampling_params.logits_processor_update_state\n\n    def __len__(self):\n        return self.num_tokens\n\n    def __getitem__(self, key):\n        return self.token_ids[key]\n\n    @property\n    def is_finished(self):\n        return self.status == SequenceStatus.FINISHED\n\n    @property\n    def num_completion_tokens(self):\n        return self.num_tokens - self.num_prompt_tokens\n\n    @property\n    def prompt_token_ids(self):\n        return self.token_ids[:self.num_prompt_tokens]\n\n    @property\n    def completion_token_ids(self):\n        return self.token_ids[self.num_prompt_tokens:]\n\n    @property\n    def num_cached_blocks(self):\n        return self.num_cached_tokens // self.block_size\n\n    @property\n    def num_blocks(self):\n        return (self.num_tokens + self.block_size - 1) // self.block_size\n\n    @property\n    def last_block_num_tokens(self):\n        return self.num_tokens - (self.num_blocks - 1) * self.block_size\n\n    def block(self, i):\n        assert 0 <= i < self.num_blocks\n        return self.token_ids[i*self.block_size: (i+1)*self.block_size]\n\n    def append_token(self, token_id: int):\n        self.token_ids.append(token_id)\n        self.last_token = token_id\n        self.num_tokens += 1\n\n    def __getstate__(self):\n        return (self.num_tokens, self.num_prompt_tokens, self.num_cached_tokens, self.block_table,\n                self.token_ids if self.num_completion_tokens == 0 else self.last_token)\n\n    def __setstate__(self, state):\n        self.num_tokens, self.num_prompt_tokens, self.num_cached_tokens, self.block_table = state[:-1]\n        if self.num_completion_tokens == 0:\n            self.token_ids = state[-1]\n        else:\n            self.last_token = state[-1]\n"
  },
  {
    "path": "acestep/third_parts/nano-vllm/nanovllm/layers/activation.py",
    "content": "import torch\nfrom torch import nn\nimport torch.nn.functional as F\n\nfrom nanovllm.utils.compat import maybe_compile\n\n\nclass SiluAndMul(nn.Module):\n\n    def __init__(self):\n        super().__init__()\n\n    @maybe_compile\n    def forward(self, x: torch.Tensor) -> torch.Tensor:\n        x, y = x.chunk(2, -1)\n        return F.silu(x) * y\n"
  },
  {
    "path": "acestep/third_parts/nano-vllm/nanovllm/layers/attention.py",
    "content": "import os\nimport torch\nfrom torch import nn\nimport torch.nn.functional as F\n\nfrom nanovllm.utils.context import get_context\n\n# Debug logging - enable with NANOVLLM_DEBUG=1\n_DEBUG = os.environ.get(\"NANOVLLM_DEBUG\", \"0\") == \"1\"\n\ndef _debug_log(msg: str):\n    \"\"\"Print debug message if NANOVLLM_DEBUG is enabled\"\"\"\n    if _DEBUG:\n        print(f\"[nanovllm attention DEBUG] {msg}\", flush=True)\n\n# Optional dependencies: Triton (for KV cache kernel) and Flash Attention\n_HAS_TRITON = False\n_HAS_FLASH_ATTN = False\n\ntry:\n    import triton\n    import triton.language as tl\n    _HAS_TRITON = True\nexcept ImportError:\n    pass\n\ntry:\n    from flash_attn import flash_attn_varlen_func, flash_attn_with_kvcache\n    _HAS_FLASH_ATTN = True\nexcept ImportError:\n    pass\n\n\n# ============================================================\n# Triton KV cache store kernel (original, used when available)\n# ============================================================\n\nif _HAS_TRITON:\n    @triton.jit\n    def store_kvcache_kernel(\n        key_ptr,\n        key_stride,\n        value_ptr,\n        value_stride,\n        k_cache_ptr,\n        v_cache_ptr,\n        slot_mapping_ptr,\n        D: tl.constexpr,\n    ):\n        idx = tl.program_id(0)\n        slot = tl.load(slot_mapping_ptr + idx)\n        if slot == -1: return\n        key_offsets = idx * key_stride + tl.arange(0, D)\n        value_offsets = idx * value_stride + tl.arange(0, D)\n        key = tl.load(key_ptr + key_offsets)\n        value = tl.load(value_ptr + value_offsets)\n        cache_offsets = slot * D + tl.arange(0, D)\n        tl.store(k_cache_ptr + cache_offsets, key)\n        tl.store(v_cache_ptr + cache_offsets, value)\n\n\n# ============================================================\n# Pure PyTorch KV cache store (fallback when Triton unavailable)\n# ============================================================\n\ndef _store_kvcache_pytorch(\n    key: torch.Tensor,\n    value: torch.Tensor,\n    k_cache: torch.Tensor,\n    v_cache: torch.Tensor,\n    slot_mapping: torch.Tensor,\n):\n    \"\"\"Store key/value into paged KV cache using pure PyTorch ops.\n\n    Args:\n        key: [N, num_kv_heads, head_dim]\n        value: [N, num_kv_heads, head_dim]\n        k_cache: [num_blocks, block_size, num_kv_heads, head_dim] (per-layer view)\n        v_cache: [num_blocks, block_size, num_kv_heads, head_dim]\n        slot_mapping: [N] - flat slot indices into cache\n    \"\"\"\n    N, num_kv_heads, head_dim = key.shape\n    D = num_kv_heads * head_dim\n\n    # View cache as flat [total_slots, D]\n    k_flat = k_cache.reshape(-1, D)\n    v_flat = v_cache.reshape(-1, D)\n\n    # View keys/values as [N, D]\n    key_flat = key.reshape(N, D)\n    value_flat = value.reshape(N, D)\n\n    # Filter out padding slots (slot == -1)\n    valid_mask = slot_mapping != -1\n    valid_slots = slot_mapping[valid_mask]\n    k_flat[valid_slots] = key_flat[valid_mask]\n    v_flat[valid_slots] = value_flat[valid_mask]\n\n\ndef store_kvcache(\n    key: torch.Tensor,\n    value: torch.Tensor,\n    k_cache: torch.Tensor,\n    v_cache: torch.Tensor,\n    slot_mapping: torch.Tensor,\n):\n    \"\"\"Store key/value into paged KV cache. Uses Triton kernel when available.\"\"\"\n    if _HAS_TRITON:\n        N, num_heads, head_dim = key.shape\n        D = num_heads * head_dim\n        assert key.stride(-1) == 1 and value.stride(-1) == 1\n        assert key.stride(1) == head_dim and value.stride(1) == head_dim\n        assert k_cache.stride(1) == D and v_cache.stride(1) == D\n        assert slot_mapping.numel() == N\n        store_kvcache_kernel[(N,)](key, key.stride(0), value, value.stride(0), k_cache, v_cache, slot_mapping, D)\n    else:\n        _store_kvcache_pytorch(key, value, k_cache, v_cache, slot_mapping)\n\n\n# ============================================================\n# SDPA-based attention (fallback when Flash Attention unavailable)\n# ============================================================\n\ndef _sdpa_varlen_prefill(\n    q: torch.Tensor,\n    k: torch.Tensor,\n    v: torch.Tensor,\n    cu_seqlens_q: torch.Tensor,\n    cu_seqlens_k: torch.Tensor,\n    scale: float,\n    num_heads: int,\n    num_kv_heads: int,\n) -> torch.Tensor:\n    \"\"\"SDPA replacement for flash_attn_varlen_func during prefill.\n\n    Splits packed sequences, runs SDPA per sequence with causal masking,\n    then re-packs. Handles GQA via enable_gqa when heads differ.\n\n    Args:\n        q: [total_q_tokens, num_heads, head_dim]\n        k: [total_k_tokens, num_kv_heads, head_dim]\n        v: [total_k_tokens, num_kv_heads, head_dim]\n        cu_seqlens_q: [num_seqs + 1] cumulative sequence lengths for queries\n        cu_seqlens_k: [num_seqs + 1] cumulative sequence lengths for keys\n        scale: attention scale factor\n        num_heads: number of query heads\n        num_kv_heads: number of KV heads\n\n    Returns:\n        output: [total_q_tokens, num_heads, head_dim]\n    \"\"\"\n    num_seqs = cu_seqlens_q.shape[0] - 1\n    outputs = []\n    enable_gqa = num_heads != num_kv_heads\n\n    for i in range(num_seqs):\n        q_start = cu_seqlens_q[i].item()\n        q_end = cu_seqlens_q[i + 1].item()\n        k_start = cu_seqlens_k[i].item()\n        k_end = cu_seqlens_k[i + 1].item()\n\n        # [seq_len, heads, dim] -> [1, heads, seq_len, dim]\n        qi = q[q_start:q_end].unsqueeze(0).transpose(1, 2)\n        ki = k[k_start:k_end].unsqueeze(0).transpose(1, 2)\n        vi = v[k_start:k_end].unsqueeze(0).transpose(1, 2)\n\n        oi = F.scaled_dot_product_attention(\n            qi, ki, vi, scale=scale, is_causal=True, enable_gqa=enable_gqa\n        )\n\n        # [1, heads, seq_len, dim] -> [seq_len, heads, dim]\n        outputs.append(oi.transpose(1, 2).squeeze(0))\n\n    return torch.cat(outputs, dim=0)\n\n\ndef _sdpa_prefill_with_paged_cache(\n    q: torch.Tensor,\n    k_cache: torch.Tensor,\n    v_cache: torch.Tensor,\n    cu_seqlens_q: torch.Tensor,\n    cu_seqlens_k: torch.Tensor,\n    block_tables: torch.Tensor,\n    scale: float,\n    num_heads: int,\n    num_kv_heads: int,\n) -> torch.Tensor:\n    \"\"\"SDPA prefill with paged KV cache (prefix caching case).\n\n    Args:\n        q: [total_q_tokens, num_heads, head_dim]\n        k_cache: [num_blocks, block_size, num_kv_heads, head_dim]\n        v_cache: [num_blocks, block_size, num_kv_heads, head_dim]\n        cu_seqlens_q: [num_seqs + 1]\n        cu_seqlens_k: [num_seqs + 1]\n        block_tables: [num_seqs, max_blocks_per_seq]\n        scale: attention scale factor\n        num_heads: number of query heads\n        num_kv_heads: number of KV heads\n\n    Returns:\n        output: [total_q_tokens, num_heads, head_dim]\n    \"\"\"\n    block_size = k_cache.shape[1]\n    num_seqs = cu_seqlens_q.shape[0] - 1\n    outputs = []\n    enable_gqa = num_heads != num_kv_heads\n\n    for i in range(num_seqs):\n        q_start = cu_seqlens_q[i].item()\n        q_end = cu_seqlens_q[i + 1].item()\n        k_len = cu_seqlens_k[i + 1].item() - cu_seqlens_k[i].item()\n\n        # Gather k/v from paged cache\n        num_blocks_needed = (k_len + block_size - 1) // block_size\n        block_indices = block_tables[i, :num_blocks_needed]\n        ki = k_cache[block_indices].reshape(-1, num_kv_heads, k_cache.shape[-1])[:k_len]\n        vi = v_cache[block_indices].reshape(-1, num_kv_heads, v_cache.shape[-1])[:k_len]\n\n        # [seq, heads, dim] -> [1, heads, seq, dim]\n        qi = q[q_start:q_end].unsqueeze(0).transpose(1, 2)\n        ki = ki.unsqueeze(0).transpose(1, 2)\n        vi = vi.unsqueeze(0).transpose(1, 2)\n\n        oi = F.scaled_dot_product_attention(\n            qi, ki, vi, scale=scale, is_causal=True, enable_gqa=enable_gqa\n        )\n        outputs.append(oi.transpose(1, 2).squeeze(0))\n\n    return torch.cat(outputs, dim=0)\n\n\ndef _sdpa_decode_with_paged_cache(\n    q: torch.Tensor,\n    k_cache: torch.Tensor,\n    v_cache: torch.Tensor,\n    context_lens: torch.Tensor,\n    block_tables: torch.Tensor,\n    scale: float,\n    num_heads: int,\n    num_kv_heads: int,\n) -> torch.Tensor:\n    \"\"\"SDPA replacement for flash_attn_with_kvcache during decode.\n\n    For each sequence, gathers KV from paged cache and runs SDPA\n    for the single new query token against the full context.\n\n    Args:\n        q: [batch, 1, num_heads, head_dim] (already unsqueezed)\n        k_cache: [num_blocks, block_size, num_kv_heads, head_dim]\n        v_cache: [num_blocks, block_size, num_kv_heads, head_dim]\n        context_lens: [batch] - number of tokens in context for each sequence\n        block_tables: [batch, max_blocks_per_seq]\n        scale: attention scale factor\n        num_heads: number of query heads\n        num_kv_heads: number of KV heads\n\n    Returns:\n        output: [batch, 1, num_heads, head_dim]\n    \"\"\"\n    batch_size = q.shape[0]\n    block_size = k_cache.shape[1]\n    outputs = []\n    enable_gqa = num_heads != num_kv_heads\n\n    for i in range(batch_size):\n        ctx_len = context_lens[i].item()\n        num_blocks_needed = (ctx_len + block_size - 1) // block_size\n        block_indices = block_tables[i, :num_blocks_needed]\n\n        # Gather and trim KV: [ctx_len, num_kv_heads, head_dim]\n        ki = k_cache[block_indices].reshape(-1, num_kv_heads, k_cache.shape[-1])[:ctx_len]\n        vi = v_cache[block_indices].reshape(-1, num_kv_heads, v_cache.shape[-1])[:ctx_len]\n\n        # q[i]: [1, num_heads, head_dim] -> [1, num_heads, 1, head_dim]\n        qi = q[i].unsqueeze(0).transpose(1, 2)     # [1, num_heads, 1, head_dim]\n        ki = ki.unsqueeze(0).transpose(1, 2)        # [1, num_kv_heads, ctx_len, head_dim]\n        vi = vi.unsqueeze(0).transpose(1, 2)        # [1, num_kv_heads, ctx_len, head_dim]\n\n        oi = F.scaled_dot_product_attention(\n            qi, ki, vi, scale=scale, is_causal=False, enable_gqa=enable_gqa\n        )\n        outputs.append(oi.transpose(1, 2).squeeze(0))  # [1, num_heads, head_dim]\n\n    return torch.stack(outputs, dim=0)  # [batch, 1, num_heads, head_dim]\n\n\n# ============================================================\n# Attention module\n# ============================================================\n\nclass Attention(nn.Module):\n\n    def __init__(\n        self,\n        num_heads,\n        head_dim,\n        scale,\n        num_kv_heads,\n    ):\n        super().__init__()\n        self.num_heads = num_heads\n        self.head_dim = head_dim\n        self.scale = scale\n        self.num_kv_heads = num_kv_heads\n        self.k_cache = self.v_cache = torch.tensor([])\n\n    def forward(self, q: torch.Tensor, k: torch.Tensor, v: torch.Tensor):\n        context = get_context()\n        k_cache, v_cache = self.k_cache, self.v_cache\n\n        if _DEBUG:\n            _debug_log(f\"forward: q.shape={q.shape}, k.shape={k.shape}, v.shape={v.shape}\")\n            _debug_log(f\"  is_prefill={context.is_prefill}\")\n            _debug_log(f\"  k_cache.shape={k_cache.shape if k_cache.numel() else 'empty'}\")\n            if context.slot_mapping is not None:\n                _debug_log(f\"  slot_mapping.shape={context.slot_mapping.shape}, range=[{context.slot_mapping.min().item()}, {context.slot_mapping.max().item()}]\")\n            if context.block_tables is not None:\n                valid_blocks = context.block_tables[context.block_tables >= 0]\n                _debug_log(f\"  block_tables.shape={context.block_tables.shape}, range=[{valid_blocks.min().item() if valid_blocks.numel() else -1}, {valid_blocks.max().item() if valid_blocks.numel() else -1}]\")\n            if context.context_lens is not None:\n                _debug_log(f\"  context_lens={context.context_lens.tolist()}\")\n\n        if k_cache.numel() and v_cache.numel():\n            store_kvcache(k, v, k_cache, v_cache, context.slot_mapping)\n\n        if _HAS_FLASH_ATTN:\n            return self._forward_flash_attn(q, k, v, k_cache, v_cache, context)\n        else:\n            return self._forward_sdpa(q, k, v, k_cache, v_cache, context)\n\n    def _forward_flash_attn(self, q, k, v, k_cache, v_cache, context):\n        \"\"\"Original flash attention path.\"\"\"\n        if context.is_prefill:\n            if context.block_tables is not None:  # prefix cache\n                k, v = k_cache, v_cache\n            _debug_log(f\"  calling flash_attn_varlen_func\")\n            o = flash_attn_varlen_func(\n                q, k, v,\n                max_seqlen_q=context.max_seqlen_q,\n                cu_seqlens_q=context.cu_seqlens_q,\n                max_seqlen_k=context.max_seqlen_k,\n                cu_seqlens_k=context.cu_seqlens_k,\n                softmax_scale=self.scale,\n                causal=True,\n                block_table=context.block_tables,\n            )\n        else:  # decode\n            _debug_log(f\"  calling flash_attn_with_kvcache\")\n            o = flash_attn_with_kvcache(\n                q.unsqueeze(1), k_cache, v_cache,\n                cache_seqlens=context.context_lens,\n                block_table=context.block_tables,\n                softmax_scale=self.scale,\n                causal=True,\n            )\n        return o\n\n    def _forward_sdpa(self, q, k, v, k_cache, v_cache, context):\n        \"\"\"SDPA fallback path (no flash_attn dependency).\"\"\"\n        if context.is_prefill:\n            if context.block_tables is not None:\n                # Prefix cache: gather from paged cache\n                _debug_log(f\"  calling _sdpa_prefill_with_paged_cache\")\n                o = _sdpa_prefill_with_paged_cache(\n                    q, k_cache, v_cache,\n                    context.cu_seqlens_q, context.cu_seqlens_k,\n                    context.block_tables,\n                    self.scale, self.num_heads, self.num_kv_heads,\n                )\n            else:\n                # Standard prefill: k, v are packed tokens\n                _debug_log(f\"  calling _sdpa_varlen_prefill\")\n                o = _sdpa_varlen_prefill(\n                    q, k, v,\n                    context.cu_seqlens_q, context.cu_seqlens_k,\n                    self.scale, self.num_heads, self.num_kv_heads,\n                )\n        else:\n            # Decode: single token per sequence against full KV cache\n            _debug_log(f\"  calling _sdpa_decode_with_paged_cache\")\n            o = _sdpa_decode_with_paged_cache(\n                q.unsqueeze(1), k_cache, v_cache,\n                context.context_lens, context.block_tables,\n                self.scale, self.num_heads, self.num_kv_heads,\n            )\n        return o\n"
  },
  {
    "path": "acestep/third_parts/nano-vllm/nanovllm/layers/embed_head.py",
    "content": "import torch\nfrom torch import nn\nimport torch.nn.functional as F\nimport torch.distributed as dist\n\nfrom nanovllm.utils.context import get_context\nfrom nanovllm import distributed as dist_utils\n\n\nclass VocabParallelEmbedding(nn.Module):\n\n    def __init__(\n        self,\n        num_embeddings: int,\n        embedding_dim: int,\n    ):\n        super().__init__()\n        self.tp_rank = dist_utils.get_rank()\n        self.tp_size = dist_utils.get_world_size()\n        assert num_embeddings % self.tp_size == 0\n        self.num_embeddings = num_embeddings\n        self.num_embeddings_per_partition = self.num_embeddings // self.tp_size\n        self.vocab_start_idx = self.num_embeddings_per_partition * self.tp_rank\n        self.vocab_end_idx = self.vocab_start_idx + self.num_embeddings_per_partition\n        self.weight = nn.Parameter(torch.empty(self.num_embeddings_per_partition, embedding_dim))\n        self.weight.weight_loader = self.weight_loader\n\n    def weight_loader(self, param: nn.Parameter, loaded_weight: torch.Tensor):\n        param_data = param.data\n        shard_size = param_data.size(0)\n        start_idx = self.tp_rank * shard_size\n        loaded_weight = loaded_weight.narrow(0, start_idx, shard_size)\n        param_data.copy_(loaded_weight)\n\n    def forward(self, x: torch.Tensor):\n        if self.tp_size > 1:\n            mask = (x >= self.vocab_start_idx) & (x < self.vocab_end_idx)\n            x = mask * (x - self.vocab_start_idx)\n        y = F.embedding(x, self.weight)\n        if self.tp_size > 1:\n            y = mask.unsqueeze(1) * y\n            dist_utils.all_reduce(y)\n        return y\n\n\nclass ParallelLMHead(VocabParallelEmbedding):\n\n    def __init__(\n        self,\n        num_embeddings: int,\n        embedding_dim: int,\n        bias: bool = False,\n    ):\n        assert not bias\n        super().__init__(num_embeddings, embedding_dim)\n\n    def forward(self, x: torch.Tensor):\n        context = get_context()\n        if context.is_prefill:\n            last_indices = context.cu_seqlens_q[1:] - 1\n            x = x[last_indices].contiguous()\n        logits = F.linear(x, self.weight)\n        # In multi-GPU mode, gather logits from all ranks and concatenate\n        # In single-GPU mode (tp_size=1), skip gathering and return logits directly\n        if self.tp_size > 1:\n            all_logits = [torch.empty_like(logits) for _ in range(self.tp_size)] if self.tp_rank == 0 else None\n            dist_utils.gather(logits, all_logits, 0)\n            logits = torch.cat(all_logits, -1) if self.tp_rank == 0 else None\n        return logits\n"
  },
  {
    "path": "acestep/third_parts/nano-vllm/nanovllm/layers/layernorm.py",
    "content": "import torch\nfrom torch import nn\n\nfrom nanovllm.utils.compat import maybe_compile\n\n\nclass RMSNorm(nn.Module):\n\n    def __init__(\n        self,\n        hidden_size: int,\n        eps: float = 1e-6,\n    ) -> None:\n        super().__init__()\n        self.eps = eps\n        self.weight = nn.Parameter(torch.ones(hidden_size))\n\n    @maybe_compile\n    def rms_forward(\n        self,\n        x: torch.Tensor,\n    ) -> torch.Tensor:\n        orig_dtype = x.dtype\n        x = x.float()\n        var = x.pow(2).mean(dim=-1, keepdim=True)\n        x.mul_(torch.rsqrt(var + self.eps))\n        x = x.to(orig_dtype).mul_(self.weight)\n        return x\n\n    @maybe_compile\n    def add_rms_forward(\n        self,\n        x: torch.Tensor,\n        residual: torch.Tensor,\n    ) -> tuple[torch.Tensor, torch.Tensor]:\n        orig_dtype = x.dtype\n        x = x.float().add_(residual.float())\n        residual = x.to(orig_dtype)\n        var = x.pow(2).mean(dim=-1, keepdim=True)\n        x.mul_(torch.rsqrt(var + self.eps))\n        x = x.to(orig_dtype).mul_(self.weight)\n        return x, residual\n\n    def forward(\n        self,\n        x: torch.Tensor,\n        residual: torch.Tensor | None = None,\n    ) -> torch.Tensor | tuple[torch.Tensor, torch.Tensor]:\n        if residual is None:\n            return self.rms_forward(x)\n        else:\n            return self.add_rms_forward(x, residual)\n"
  },
  {
    "path": "acestep/third_parts/nano-vllm/nanovllm/layers/linear.py",
    "content": "import torch\nfrom torch import nn\nimport torch.nn.functional as F\nimport torch.distributed as dist\n\nfrom nanovllm import distributed as dist_utils\n\n\ndef divide(numerator, denominator):\n    assert numerator % denominator == 0\n    return numerator // denominator\n\n\nclass LinearBase(nn.Module):\n\n    def __init__(\n        self,\n        input_size: int,\n        output_size: int,\n        bias: bool = False,\n        tp_dim: int | None = None,\n    ):\n        super().__init__()\n        self.tp_dim = tp_dim\n        self.tp_rank = dist_utils.get_rank()\n        self.tp_size = dist_utils.get_world_size()\n        self.weight = nn.Parameter(torch.empty(output_size, input_size))\n        self.weight.weight_loader = self.weight_loader\n        if bias:\n            self.bias = nn.Parameter(torch.empty(output_size))\n            self.bias.weight_loader = self.weight_loader\n        else:\n            self.register_parameter(\"bias\", None)\n\n    def forward(self, x: torch.Tensor) -> torch.Tensor:\n        raise NotImplementedError\n\n\nclass ReplicatedLinear(LinearBase):\n\n    def __init__(\n        self,\n        input_size: int,\n        output_size: int,\n        bias: bool = False,\n    ):\n        super().__init__(input_size, output_size, bias)\n\n    def weight_loader(self, param: nn.Parameter, loaded_weight: torch.Tensor):\n        param.data.copy_(loaded_weight)\n\n    def forward(self, x: torch.Tensor) -> torch.Tensor:\n        return F.linear(x, self.weight, self.bias)\n\n\nclass ColumnParallelLinear(LinearBase):\n\n    def __init__(\n        self,\n        input_size: int,\n        output_size: int,\n        bias: bool = False,\n    ):\n        tp_size = dist_utils.get_world_size()\n        super().__init__(input_size, divide(output_size, tp_size), bias, 0)\n\n    def weight_loader(self, param: nn.Parameter, loaded_weight: torch.Tensor):\n        param_data = param.data\n        shard_size = param_data.size(self.tp_dim)\n        start_idx = self.tp_rank * shard_size\n        loaded_weight = loaded_weight.narrow(self.tp_dim, start_idx, shard_size)\n        param_data.copy_(loaded_weight)\n\n    def forward(self, x: torch.Tensor) -> torch.Tensor:\n        return F.linear(x, self.weight, self.bias)\n\n\nclass MergedColumnParallelLinear(ColumnParallelLinear):\n\n    def __init__(\n        self,\n        input_size: int,\n        output_sizes: list[int],\n        bias: bool = False,\n    ):\n        self.output_sizes = output_sizes\n        super().__init__(input_size, sum(output_sizes), bias)\n\n    def weight_loader(self, param: nn.Parameter, loaded_weight: torch.Tensor, loaded_shard_id: int):\n        param_data = param.data\n        shard_offset = sum(self.output_sizes[:loaded_shard_id]) // self.tp_size\n        shard_size = self.output_sizes[loaded_shard_id] // self.tp_size\n        param_data = param_data.narrow(self.tp_dim, shard_offset, shard_size)\n        loaded_weight = loaded_weight.chunk(self.tp_size, self.tp_dim)[self.tp_rank]\n        param_data.copy_(loaded_weight)\n\n\nclass QKVParallelLinear(ColumnParallelLinear):\n\n    def __init__(\n        self,\n        hidden_size: int,\n        head_size: int,\n        total_num_heads: int,\n        total_num_kv_heads: int | None = None,\n        bias: bool = False,\n    ):\n        tp_size = dist_utils.get_world_size()\n        total_num_kv_heads = total_num_kv_heads or total_num_heads\n        self.head_size = head_size\n        self.num_heads = divide(total_num_heads, tp_size)\n        self.num_kv_heads = divide(total_num_kv_heads, tp_size)\n        output_size = (total_num_heads + 2 * total_num_kv_heads) * self.head_size\n        super().__init__(hidden_size, output_size, bias)\n\n    def weight_loader(self, param: nn.Parameter, loaded_weight: torch.Tensor, loaded_shard_id: str):\n        param_data = param.data\n        assert loaded_shard_id in [\"q\", \"k\", \"v\"]\n        if loaded_shard_id == \"q\":\n            shard_size = self.num_heads * self.head_size\n            shard_offset = 0\n        elif loaded_shard_id == \"k\":\n            shard_size = self.num_kv_heads * self.head_size\n            shard_offset = self.num_heads * self.head_size\n        else:\n            shard_size = self.num_kv_heads * self.head_size\n            shard_offset = self.num_heads * self.head_size + self.num_kv_heads * self.head_size\n        param_data = param_data.narrow(self.tp_dim, shard_offset, shard_size)\n        loaded_weight = loaded_weight.chunk(self.tp_size, self.tp_dim)[self.tp_rank]\n        param_data.copy_(loaded_weight)\n\n\nclass RowParallelLinear(LinearBase):\n\n    def __init__(\n        self,\n        input_size: int,\n        output_size: int,\n        bias: bool = False,\n    ):\n        tp_size = dist_utils.get_world_size()\n        super().__init__(divide(input_size, tp_size), output_size, bias, 1)\n\n    def weight_loader(self, param: nn.Parameter, loaded_weight: torch.Tensor):\n        param_data = param.data\n        shard_size = param_data.size(self.tp_dim)\n        start_idx = self.tp_rank * shard_size\n        loaded_weight = loaded_weight.narrow(self.tp_dim, start_idx, shard_size)\n        param_data.copy_(loaded_weight)\n\n    def forward(self, x: torch.Tensor) -> torch.Tensor:\n        y = F.linear(x, self.weight, self.bias if self.tp_rank == 0 else None)\n        if self.tp_size > 1:\n            dist_utils.all_reduce(y)\n        return y\n"
  },
  {
    "path": "acestep/third_parts/nano-vllm/nanovllm/layers/rotary_embedding.py",
    "content": "from functools import lru_cache\nimport torch\nfrom torch import nn\n\nfrom nanovllm.utils.compat import maybe_compile\n\n\ndef apply_rotary_emb(\n    x: torch.Tensor,\n    cos: torch.Tensor,\n    sin: torch.Tensor,\n) -> torch.Tensor:\n    x1, x2 = torch.chunk(x.float(), 2, dim=-1)\n    y1 = x1 * cos - x2 * sin\n    y2 = x2 * cos + x1 * sin\n    return torch.cat((y1, y2), dim=-1).to(x.dtype)\n\n\nclass RotaryEmbedding(nn.Module):\n\n    def __init__(\n        self,\n        head_size: int,\n        rotary_dim: int,\n        max_position_embeddings: int,\n        base: float,\n    ) -> None:\n        super().__init__()\n        self.head_size = head_size\n        assert rotary_dim == head_size\n        inv_freq = 1.0 / (base**(torch.arange(0, rotary_dim, 2, dtype=torch.float) / rotary_dim))\n        t = torch.arange(max_position_embeddings, dtype=torch.float)\n        freqs = torch.einsum(\"i,j -> ij\", t, inv_freq)\n        cos = freqs.cos()\n        sin = freqs.sin()\n        cache = torch.cat((cos, sin), dim=-1).unsqueeze_(1)\n        self.register_buffer(\"cos_sin_cache\", cache, persistent=False)\n\n    @maybe_compile\n    def forward(\n        self,\n        positions: torch.Tensor,\n        query: torch.Tensor,\n        key: torch.Tensor,\n    ) -> tuple[torch.Tensor, torch.Tensor]:\n        cos_sin = self.cos_sin_cache[positions]\n        cos, sin = cos_sin.chunk(2, dim=-1)\n        query = apply_rotary_emb(query, cos, sin)\n        key = apply_rotary_emb(key, cos, sin)\n        return query, key\n\n\n@lru_cache(1)\ndef get_rope(\n    head_size: int,\n    rotary_dim: int,\n    max_position: int,\n    base: float,\n    rope_scaling: dict | None = None,\n):\n    assert rope_scaling is None\n    rotary_emb = RotaryEmbedding(head_size, rotary_dim, max_position, base)\n    return rotary_emb\n"
  },
  {
    "path": "acestep/third_parts/nano-vllm/nanovllm/layers/sampler.py",
    "content": "import torch\nfrom torch import nn\nfrom typing import Optional\n\nfrom nanovllm.utils.compat import maybe_compile\n\n\ndef apply_top_k_top_p(\n    logits: torch.Tensor,\n    k: Optional[torch.Tensor],\n    p: Optional[torch.Tensor],\n) -> torch.Tensor:\n    \"\"\"Apply top-k and top-p masks to the logits (vLLM style).\n    \n    The logits tensor is updated in-place.\n    \"\"\"\n    if p is None:\n        if k is None:\n            return logits\n        # Avoid sorting vocab for top-k only case\n        return apply_top_k_only(logits, k)\n\n    # Need to sort for top-p\n    logits_sort, logits_idx = logits.sort(dim=-1, descending=False)\n\n    if k is not None:\n        # Apply top-k first\n        vocab_size = logits_sort.size(1)\n        # Clamp k to valid range\n        k_clamped = k.clamp(1, vocab_size).long()\n        top_k_mask_idx = vocab_size - k_clamped  # shape: [B]\n        # Get the threshold value for each batch\n        top_k_thresh = logits_sort.gather(1, top_k_mask_idx.unsqueeze(1))\n        top_k_mask = logits_sort < top_k_thresh\n        logits_sort.masked_fill_(top_k_mask, float('-inf'))\n\n    # Apply top-p\n    probs_sort = logits_sort.softmax(dim=-1)\n    probs_sum = torch.cumsum(probs_sort, dim=-1, out=probs_sort)  # reuse buffer\n    top_p_mask = probs_sum <= (1.0 - p.unsqueeze(1))\n    # Ensure at least one token is kept\n    top_p_mask[:, -1] = False\n    logits_sort.masked_fill_(top_p_mask, float('-inf'))\n\n    # Re-sort back to original positions\n    logits.scatter_(dim=-1, index=logits_idx, src=logits_sort)\n    return logits\n\n\ndef apply_top_k_only(\n    logits: torch.Tensor,\n    k: torch.Tensor,\n) -> torch.Tensor:\n    \"\"\"Apply top-k mask without sorting the entire vocab (vLLM style).\n    \n    This is much faster than sorting for top-k only cases.\n    The logits tensor is updated in-place.\n    \"\"\"\n    vocab_size = logits.shape[1]\n    # Handle cases where k >= vocab_size (no filtering needed)\n    no_top_k_mask = (k <= 0) | (k >= vocab_size)\n    # Set invalid k to 1 so we can still gather\n    k_safe = k.masked_fill(no_top_k_mask, 1).long()\n    # NOTE: This int() causes CPU-GPU sync, but torch.topk requires Python int\n    max_top_k = int(k_safe.max().clamp(max=vocab_size))\n    \n    # Get top-k values for all batches\n    # topk.values has shape [batch_size, max_top_k]\n    topk_values = logits.topk(max_top_k, dim=1).values\n    \n    # Convert k to 0-based index: we want the k-th largest value (index k-1)\n    # Clamp to valid range for gather\n    k_index = (k_safe - 1).clamp(0, max_top_k - 1).unsqueeze(1)  # shape: [B, 1]\n    # Gather the threshold value (the k-th largest)\n    top_k_thresh = topk_values.gather(1, k_index)\n    \n    # For rows with no top-k filtering, set threshold to -inf so nothing gets masked\n    top_k_thresh.masked_fill_(no_top_k_mask.unsqueeze(1), float('-inf'))\n    \n    # Mask all values below the threshold\n    logits.masked_fill_(logits < top_k_thresh, float('-inf'))\n    return logits\n\n\nclass Sampler(nn.Module):\n\n    def __init__(self):\n        super().__init__()\n\n    @maybe_compile\n    def forward(\n        self, \n        logits: torch.Tensor, \n        temperatures: torch.Tensor,\n        top_ks: Optional[torch.Tensor] = None,\n        top_ps: Optional[torch.Tensor] = None,\n        repetition_penalties: Optional[torch.Tensor] = None,\n        input_ids: Optional[torch.Tensor] = None,\n    ):\n        \"\"\"\n        Sample tokens from logits with optional top-k and top-p filtering.\n        \n        Condition checking is done OUTSIDE the compiled function to avoid\n        graph breaks from .any() calls.\n        \"\"\"\n        # Apply temperature\n        logits = logits.float().div_(temperatures.unsqueeze(dim=1))\n\n        logits = apply_top_k_top_p(\n            logits,\n            top_ks,\n            top_ps,\n        )\n        probs = torch.softmax(logits, dim=-1)\n        sample_tokens = probs.div_(torch.empty_like(probs).exponential_(1).clamp_min_(1e-10)).argmax(dim=-1)\n        return sample_tokens"
  },
  {
    "path": "acestep/third_parts/nano-vllm/nanovllm/llm.py",
    "content": "from nanovllm.engine.llm_engine import LLMEngine\n\n\nclass LLM(LLMEngine):\n    pass\n"
  },
  {
    "path": "acestep/third_parts/nano-vllm/nanovllm/models/qwen3.py",
    "content": "import torch\nfrom torch import nn\nimport torch.distributed as dist\nfrom transformers import Qwen3Config\n\nfrom nanovllm.layers.activation import SiluAndMul\nfrom nanovllm.layers.attention import Attention\nfrom nanovllm.layers.layernorm import RMSNorm\nfrom nanovllm.layers.linear import QKVParallelLinear, MergedColumnParallelLinear, RowParallelLinear\nfrom nanovllm.layers.rotary_embedding import get_rope\nfrom nanovllm.layers.embed_head import VocabParallelEmbedding, ParallelLMHead\nfrom nanovllm import distributed as dist_utils\n\n\nclass Qwen3Attention(nn.Module):\n\n    def __init__(\n        self,\n        hidden_size: int,\n        num_heads: int,\n        num_kv_heads: int,\n        max_position: int = 4096 * 32,\n        head_dim: int | None = None,\n        rms_norm_eps: float = 1e-06,\n        qkv_bias: bool = False,\n        rope_theta: float = 10000,\n        rope_scaling: tuple | None = None,\n    ) -> None:\n        super().__init__()\n        tp_size = dist_utils.get_world_size()\n        self.total_num_heads = num_heads\n        assert self.total_num_heads % tp_size == 0\n        self.num_heads = self.total_num_heads // tp_size\n        self.total_num_kv_heads = num_kv_heads\n        assert self.total_num_kv_heads % tp_size == 0\n        self.num_kv_heads = self.total_num_kv_heads // tp_size\n        self.head_dim = head_dim or hidden_size // self.total_num_heads\n        self.q_size = self.num_heads * self.head_dim\n        self.kv_size = self.num_kv_heads * self.head_dim\n        self.scaling = self.head_dim ** -0.5\n        self.qkv_bias = qkv_bias\n\n        self.qkv_proj = QKVParallelLinear(\n            hidden_size,\n            self.head_dim,\n            self.total_num_heads,\n            self.total_num_kv_heads,\n            bias=qkv_bias,\n        )\n        self.o_proj = RowParallelLinear(\n            self.total_num_heads * self.head_dim,\n            hidden_size,\n            bias=False,\n        )\n        self.rotary_emb = get_rope(\n            self.head_dim,\n            rotary_dim=self.head_dim,\n            max_position=max_position,\n            base=rope_theta,\n            rope_scaling=rope_scaling,\n        )\n        self.attn = Attention(\n            self.num_heads,\n            self.head_dim,\n            self.scaling,\n            self.num_kv_heads,\n        )\n        if not self.qkv_bias:\n            self.q_norm = RMSNorm(self.head_dim, eps=rms_norm_eps)\n            self.k_norm = RMSNorm(self.head_dim, eps=rms_norm_eps)\n\n    def forward(\n        self,\n        positions: torch.Tensor,\n        hidden_states: torch.Tensor,\n    ) -> torch.Tensor:\n        qkv = self.qkv_proj(hidden_states)\n        q, k, v = qkv.split([self.q_size, self.kv_size, self.kv_size], dim=-1)\n        q = q.view(-1, self.num_heads, self.head_dim)\n        k = k.view(-1, self.num_kv_heads, self.head_dim)\n        v = v.view(-1, self.num_kv_heads, self.head_dim)\n        if not self.qkv_bias:\n            q = self.q_norm(q)\n            k = self.k_norm(k)\n        q, k = self.rotary_emb(positions, q, k)\n        o = self.attn(q, k, v)\n        output = self.o_proj(o.flatten(1, -1))\n        return output\n\n\nclass Qwen3MLP(nn.Module):\n\n    def __init__(\n        self,\n        hidden_size: int,\n        intermediate_size: int,\n        hidden_act: str,\n    ) -> None:\n        super().__init__()\n        self.gate_up_proj = MergedColumnParallelLinear(\n            hidden_size,\n            [intermediate_size] * 2,\n            bias=False,\n        )\n        self.down_proj = RowParallelLinear(\n            intermediate_size,\n            hidden_size,\n            bias=False,\n        )\n        assert hidden_act == \"silu\"\n        self.act_fn = SiluAndMul()\n\n    def forward(self, x):\n        gate_up = self.gate_up_proj(x)\n        x = self.act_fn(gate_up)\n        x = self.down_proj(x)\n        return x\n\n\nclass Qwen3DecoderLayer(nn.Module):\n\n    def __init__(\n        self,\n        config: Qwen3Config,\n    ) -> None:\n        super().__init__()\n        self.self_attn = Qwen3Attention(\n            hidden_size=config.hidden_size,\n            num_heads=config.num_attention_heads,\n            num_kv_heads=config.num_key_value_heads,\n            max_position=config.max_position_embeddings,\n            rms_norm_eps=config.rms_norm_eps,\n            qkv_bias=getattr(config, 'attention_bias', True),\n            head_dim=getattr(config, 'head_dim', None),\n            rope_theta=getattr(config, \"rope_theta\", 1000000),\n            rope_scaling=getattr(config, \"rope_scaling\", None),\n        )\n        self.mlp = Qwen3MLP(\n            hidden_size=config.hidden_size,\n            intermediate_size=config.intermediate_size,\n            hidden_act=config.hidden_act,\n        )\n        self.input_layernorm = RMSNorm(config.hidden_size, eps=config.rms_norm_eps)\n        self.post_attention_layernorm = RMSNorm(config.hidden_size, eps=config.rms_norm_eps)\n\n    def forward(\n        self,\n        positions: torch.Tensor,\n        hidden_states: torch.Tensor,\n        residual: torch.Tensor | None,\n    ) -> tuple[torch.Tensor, torch.Tensor]:\n        if residual is None:\n            hidden_states, residual = self.input_layernorm(hidden_states), hidden_states\n        else:\n            hidden_states, residual = self.input_layernorm(hidden_states, residual)\n        hidden_states = self.self_attn(positions, hidden_states)\n        hidden_states, residual = self.post_attention_layernorm(hidden_states, residual)\n        hidden_states = self.mlp(hidden_states)\n        return hidden_states, residual\n\n\nclass Qwen3Model(nn.Module):\n\n    def __init__(\n        self,\n        config: Qwen3Config,\n    ) -> None:\n        super().__init__()\n        self.embed_tokens = VocabParallelEmbedding(config.vocab_size, config.hidden_size)\n        self.layers = nn.ModuleList([Qwen3DecoderLayer(config) for _ in range(config.num_hidden_layers)])\n        self.norm = RMSNorm(config.hidden_size, eps=config.rms_norm_eps)\n\n    def forward(\n        self,\n        input_ids: torch.Tensor,\n        positions: torch.Tensor,\n    ) -> torch.Tensor:\n        hidden_states = self.embed_tokens(input_ids)\n        residual = None\n        for layer in self.layers:\n            hidden_states, residual = layer(positions, hidden_states, residual)\n        hidden_states, _ = self.norm(hidden_states, residual)\n        return hidden_states\n\n\nclass Qwen3ForCausalLM(nn.Module):\n    packed_modules_mapping = {\n        \"q_proj\": (\"qkv_proj\", \"q\"),\n        \"k_proj\": (\"qkv_proj\", \"k\"),\n        \"v_proj\": (\"qkv_proj\", \"v\"),\n        \"gate_proj\": (\"gate_up_proj\", 0),\n        \"up_proj\": (\"gate_up_proj\", 1),\n    }\n\n    def __init__(\n        self,\n        config: Qwen3Config\n    ) -> None:\n        super().__init__()\n        self.model = Qwen3Model(config)\n        self.lm_head = ParallelLMHead(config.vocab_size, config.hidden_size)\n        if config.tie_word_embeddings:\n            self.lm_head.weight.data = self.model.embed_tokens.weight.data\n\n    # Proxy attributes for weight loading compatibility\n    # Some model weights use \"embed_tokens\" instead of \"model.embed_tokens\"\n    @property\n    def embed_tokens(self):\n        return self.model.embed_tokens\n\n    @property\n    def layers(self):\n        return self.model.layers\n\n    @property\n    def norm(self):\n        return self.model.norm\n\n    def forward(\n        self,\n        input_ids: torch.Tensor,\n        positions: torch.Tensor,\n    ) -> torch.Tensor:\n        return self.model(input_ids, positions)\n\n    def compute_logits(\n        self,\n        hidden_states: torch.Tensor,\n    ) -> torch.Tensor:\n        return self.lm_head(hidden_states)\n"
  },
  {
    "path": "acestep/third_parts/nano-vllm/nanovllm/sampling_params.py",
    "content": "from dataclasses import dataclass, field\nfrom typing import Optional, Callable, Any\n\n\n@dataclass\nclass SamplingParams:\n    temperature: float = 1.0\n    max_tokens: int = 64\n    ignore_eos: bool = False\n    cfg_scale: float = 1.0  # CFG guidance scale. When > 1.0, applies classifier-free guidance\n    top_k: Optional[int] = None  # Top-k sampling: consider only top k tokens\n    top_p: Optional[float] = None  # Top-p (nucleus) sampling: consider tokens with cumulative probability <= top_p\n    repetition_penalty: float = 1.0  # Repetition penalty: >1.0 reduces repetition, <1.0 increases it\n    # Optional logits processor for constrained decoding\n    # Should be a callable with signature: (input_ids: torch.Tensor, logits: torch.Tensor) -> torch.Tensor\n    logits_processor: Optional[Any] = field(default=None, repr=False)\n    # Optional callback to update processor state after each token\n    # Should be a callable with signature: (token_id: int) -> None\n    logits_processor_update_state: Optional[Callable[[int], None]] = field(default=None, repr=False)\n\n    def __post_init__(self):\n        assert self.temperature > 1e-10, \"greedy sampling is not permitted\"\n        assert self.cfg_scale >= 1.0, \"cfg_scale must be >= 1.0\"\n        if self.top_k is not None:\n            assert self.top_k > 0, \"top_k must be > 0\"\n        if self.top_p is not None:\n            assert 0.0 < self.top_p <= 1.0, \"top_p must be in (0.0, 1.0]\"\n        assert self.repetition_penalty > 0.0, \"repetition_penalty must be > 0.0\"\n"
  },
  {
    "path": "acestep/third_parts/nano-vllm/nanovllm/utils/compat.py",
    "content": "\"\"\"Compatibility utilities for optional dependencies.\n\nProvides graceful fallbacks when torch.compile's backend (Triton) is\nunavailable — e.g. on Windows or on GPU architectures where Triton\nhas not yet added support (Blackwell / SM 120 as of early 2026).\n\"\"\"\n\nfrom typing import Any, Callable, Optional, TypeVar\n\nfrom loguru import logger\n\nF = TypeVar(\"F\", bound=Callable[..., Any])\n\n# Module-level Triton availability check — runs once at import time\n# rather than repeating the import probe at every decoration site.\n_HAS_TRITON = False\ntry:\n    import triton  # noqa: F401\n    _HAS_TRITON = True\nexcept ImportError:\n    pass\n\n\ndef maybe_compile(fn: Optional[F] = None, **compile_kwargs: Any) -> Any:\n    \"\"\"Apply ``torch.compile`` only when its backend (Triton) is available.\n\n    Drop-in replacement for the ``@torch.compile`` decorator.  When Triton\n    is importable the function is compiled as usual; otherwise the original\n    function is returned unmodified so inference still works (just without\n    the kernel-fusion speed-up).\n\n    Args:\n        fn: The function to compile. When used as ``@maybe_compile`` (without\n            parentheses) the decorated function is passed directly.  When used\n            as ``@maybe_compile(...)`` this is ``None`` and a decorator is\n            returned instead.\n        **compile_kwargs: Keyword arguments forwarded to ``torch.compile``\n            (e.g. ``dynamic=True``, ``fullgraph=True``).\n\n    Returns:\n        The compiled function when Triton is available, or the original\n        unmodified function as a fallback.\n\n    Usage::\n\n        @maybe_compile\n        def forward(self, x):\n            ...\n\n        # or with keyword arguments:\n        @maybe_compile(dynamic=True)\n        def forward(self, x):\n            ...\n    \"\"\"\n    def decorator(func: F) -> F:\n        \"\"\"Inner decorator that performs the actual compile-or-skip logic.\"\"\"\n        if _HAS_TRITON:\n            import torch\n            return torch.compile(func, **compile_kwargs)\n        logger.info(\n            \"Triton not available — skipping torch.compile for %s \"\n            \"(inference will use native PyTorch kernels)\",\n            func.__qualname__,\n        )\n        return func\n\n    # Support both @maybe_compile and @maybe_compile(...) syntax\n    if fn is not None:\n        return decorator(fn)\n    return decorator\n"
  },
  {
    "path": "acestep/third_parts/nano-vllm/nanovllm/utils/compat_test.py",
    "content": "\"\"\"Unit tests for the ``maybe_compile`` conditional compilation decorator.\"\"\"\n\nimport unittest\nfrom unittest.mock import patch, MagicMock\n\n\ndef _sample_fn(x):\n    \"\"\"Trivial function used as decoration target in tests.\"\"\"\n    return x + 1\n\n\nclass MaybeCompileTests(unittest.TestCase):\n    \"\"\"Verify maybe_compile compiles or skips based on Triton availability.\"\"\"\n\n    def test_compiles_when_triton_available(self):\n        \"\"\"When Triton is available, the function should be passed to torch.compile.\"\"\"\n        mock_compiled = MagicMock(name=\"compiled_fn\")\n        with patch(\"nanovllm.utils.compat._HAS_TRITON\", True), \\\n             patch(\"torch.compile\", return_value=mock_compiled) as compile_mock:\n            from nanovllm.utils.compat import maybe_compile\n            result = maybe_compile(_sample_fn)\n        compile_mock.assert_called_once_with(_sample_fn)\n        self.assertEqual(result, mock_compiled)\n\n    def test_returns_original_when_triton_absent(self):\n        \"\"\"When Triton is absent, the original function should be returned unmodified.\"\"\"\n        with patch(\"nanovllm.utils.compat._HAS_TRITON\", False):\n            from nanovllm.utils.compat import maybe_compile\n            result = maybe_compile(_sample_fn)\n        self.assertIs(result, _sample_fn)\n\n    def test_kwargs_syntax_forwards_compile_args(self):\n        \"\"\"@maybe_compile(dynamic=True) should forward kwargs to torch.compile.\"\"\"\n        mock_compiled = MagicMock(name=\"compiled_fn\")\n        with patch(\"nanovllm.utils.compat._HAS_TRITON\", True), \\\n             patch(\"torch.compile\", return_value=mock_compiled) as compile_mock:\n            from nanovllm.utils.compat import maybe_compile\n            decorator = maybe_compile(dynamic=True)\n            result = decorator(_sample_fn)\n        compile_mock.assert_called_once_with(_sample_fn, dynamic=True)\n        self.assertEqual(result, mock_compiled)\n\n\nif __name__ == \"__main__\":\n    unittest.main()\n"
  },
  {
    "path": "acestep/third_parts/nano-vllm/nanovllm/utils/context.py",
    "content": "from dataclasses import dataclass\nimport threading\nimport torch\n\n\n@dataclass\nclass Context:\n    is_prefill: bool = False\n    cu_seqlens_q: torch.Tensor | None = None\n    cu_seqlens_k: torch.Tensor | None = None\n    max_seqlen_q: int = 0\n    max_seqlen_k: int = 0\n    slot_mapping: torch.Tensor | None = None\n    context_lens: torch.Tensor | None = None\n    block_tables: torch.Tensor | None = None\n\n\n# Thread-local storage for context.\n# \n# ROOT CAUSE FIX: The original implementation used a plain module-level global\n# `_CONTEXT` variable. In concurrent serving scenarios (API server with\n# ThreadPoolExecutor, multiple queue workers, or Gradio with concurrent requests),\n# multiple threads can call set_context() / get_context() / reset_context()\n# concurrently. This creates a race condition:\n#\n#   Thread A: set_context(...)        # sets slot_mapping, block_tables for request A\n#   Thread B: set_context(...)        # OVERWRITES with request B's data\n#   Thread A: run_model(...)          # reads Thread B's context → WRONG KV cache addresses\n#                                     # → CUDA illegal memory access / device-side assertion\n#\n# By using threading.local(), each thread gets its own independent Context,\n# eliminating the race condition entirely.\n_THREAD_LOCAL = threading.local()\n\n\ndef get_context():\n    ctx = getattr(_THREAD_LOCAL, 'context', None)\n    if ctx is None:\n        ctx = Context()\n        _THREAD_LOCAL.context = ctx\n    return ctx\n\ndef set_context(is_prefill, cu_seqlens_q=None, cu_seqlens_k=None, max_seqlen_q=0, max_seqlen_k=0, slot_mapping=None, context_lens=None, block_tables=None):\n    _THREAD_LOCAL.context = Context(is_prefill, cu_seqlens_q, cu_seqlens_k, max_seqlen_q, max_seqlen_k, slot_mapping, context_lens, block_tables)\n\ndef reset_context():\n    _THREAD_LOCAL.context = Context()\n"
  },
  {
    "path": "acestep/third_parts/nano-vllm/nanovllm/utils/loader.py",
    "content": "import os\nfrom glob import glob\nimport torch\nfrom torch import nn\nfrom safetensors import safe_open\n\n\ndef default_weight_loader(param: nn.Parameter, loaded_weight: torch.Tensor):\n    param.data.copy_(loaded_weight)\n\n\ndef _get_parameter_safe(model: nn.Module, weight_name: str):\n    \"\"\"\n    Try to get parameter from model, handling name mismatches.\n\n    Some models have nested structure (e.g., Qwen3ForCausalLM has model.embed_tokens)\n    but weight files may have flat names (embed_tokens.weight).\n    \"\"\"\n    # Try direct access first\n    try:\n        return model.get_parameter(weight_name)\n    except AttributeError:\n        pass\n\n    # Try with 'model.' prefix (for nested model structure)\n    try:\n        prefixed_name = f\"model.{weight_name}\"\n        return model.get_parameter(prefixed_name)\n    except AttributeError:\n        pass\n\n    # Try removing 'model.' prefix\n    if weight_name.startswith(\"model.\"):\n        try:\n            unprefixed_name = weight_name[6:]  # Remove 'model.' prefix\n            return model.get_parameter(unprefixed_name)\n        except AttributeError:\n            pass\n\n    return None\n\n\ndef load_model(model: nn.Module, path: str):\n    packed_modules_mapping = getattr(model, \"packed_modules_mapping\", {})\n    safetensor_files = glob(os.path.join(path, \"*.safetensors\"))\n\n    if not safetensor_files:\n        raise FileNotFoundError(f\"No .safetensors files found in {path}\")\n\n    for file in safetensor_files:\n        with safe_open(file, \"pt\", \"cpu\") as f:\n            for weight_name in f.keys():\n                for k in packed_modules_mapping:\n                    if k in weight_name:\n                        v, shard_id = packed_modules_mapping[k]\n                        param_name = weight_name.replace(k, v)\n                        param = _get_parameter_safe(model, param_name)\n                        if param is None:\n                            print(f\"[loader] Warning: Parameter not found: {param_name}\")\n                            continue\n                        weight_loader = getattr(param, \"weight_loader\")\n                        weight_loader(param, f.get_tensor(weight_name), shard_id)\n                        break\n                else:\n                    param = _get_parameter_safe(model, weight_name)\n                    if param is None:\n                        print(f\"[loader] Warning: Parameter not found: {weight_name}\")\n                        continue\n                    weight_loader = getattr(param, \"weight_loader\", default_weight_loader)\n                    weight_loader(param, f.get_tensor(weight_name))\n"
  },
  {
    "path": "acestep/third_parts/nano-vllm/pyproject.toml",
    "content": "[build-system]\nrequires = [\"setuptools>=61\"]\nbuild-backend = \"setuptools.build_meta\"\n\n[project]\nname = \"nano-vllm\"\nversion = \"0.2.0\"\nauthors = [{ name = \"Xingkai Yu\" }]\nlicense = {text = \"MIT\"}\nreadme = \"README.md\"\ndescription = \"a lightweight vLLM implementation built from scratch\"\nrequires-python = \">=3.10,<3.13\"\ndependencies = [\n    \"torch>=2.4.0\",\n    # Triton and Flash Attention are optional on ROCm (Python 3.12) - SDPA fallback used instead\n    \"triton-windows>=3.0.0,<3.4; sys_platform == 'win32' and python_version == '3.11'\",\n    \"triton>=3.0.0; sys_platform == 'linux' and python_version == '3.11'\",\n    \"transformers>=4.51.0\",\n    \"flash-attn @ https://github.com/sdbds/flash-attention-for-windows/releases/download/2.8.2/flash_attn-2.8.2+cu128torch2.7.1cxx11abiFALSEfullbackward-cp311-cp311-win_amd64.whl ; sys_platform == 'win32' and sys_platform != 'darwin' and python_version == '3.11' and platform_machine == 'AMD64'\",\n    \"flash-attn @ https://github.com/mjun0812/flash-attention-prebuild-wheels/releases/download/v0.7.12/flash_attn-2.8.3+cu128torch2.10-cp311-cp311-linux_x86_64.whl ; sys_platform == 'linux' and sys_platform != 'darwin' and python_version == '3.11' and platform_machine == 'x86_64'\",\n    \"xxhash\",\n]\n\n[project.urls]\nHomepage=\"https://github.com/GeeeekExplorer/nano-vllm\"\n\n[tool.setuptools.packages.find]\nwhere = [\".\"]\ninclude = [\"nanovllm*\"]\n"
  },
  {
    "path": "acestep/training/__init__.py",
    "content": "\"\"\"\nACE-Step Training Module\n\nThis module provides LoRA training functionality for ACE-Step models,\nincluding dataset building, audio labeling, and training utilities.\n\"\"\"\n\nfrom acestep.training.dataset_builder import DatasetBuilder, AudioSample\nfrom acestep.training.configs import LoRAConfig, LoKRConfig, TrainingConfig\nfrom acestep.training.lora_injection import (\n    inject_lora_into_dit,\n    freeze_non_lora_parameters,\n)\nfrom acestep.training.lora_checkpoint import (\n    save_lora_weights,\n    load_lora_weights,\n    save_training_checkpoint,\n    load_training_checkpoint,\n)\nfrom acestep.training.lora_utils import (\n    merge_lora_weights,\n    check_peft_available,\n)\nfrom acestep.training.lokr_utils import (\n    inject_lokr_into_dit,\n    save_lokr_weights,\n    load_lokr_weights,\n    check_lycoris_available,\n)\nfrom acestep.training.data_module import (\n    # Preprocessed (recommended)\n    PreprocessedTensorDataset,\n    PreprocessedDataModule,\n    collate_preprocessed_batch,\n    # Legacy (raw audio)\n    AceStepTrainingDataset,\n    AceStepDataModule,\n    collate_training_batch,\n    load_dataset_from_json,\n)\nfrom acestep.training.trainer import (\n    LoRATrainer,\n    LoKRTrainer,\n    PreprocessedLoRAModule,\n    PreprocessedLoKRModule,\n    LIGHTNING_AVAILABLE,\n)\n\n\ndef check_lightning_available():\n    \"\"\"Check if Lightning Fabric is available.\"\"\"\n    return LIGHTNING_AVAILABLE\n\n\n__all__ = [\n    # Dataset Builder\n    \"DatasetBuilder\",\n    \"AudioSample\",\n    # Configs\n    \"LoRAConfig\",\n    \"LoKRConfig\",\n    \"TrainingConfig\",\n    # LoRA Injection\n    \"inject_lora_into_dit\",\n    \"freeze_non_lora_parameters\",\n    # LoRA Checkpoint\n    \"save_lora_weights\",\n    \"load_lora_weights\",\n    \"save_training_checkpoint\",\n    \"load_training_checkpoint\",\n    # LoRA Utils\n    \"merge_lora_weights\",\n    \"check_peft_available\",\n    # LoKr Utils\n    \"inject_lokr_into_dit\",\n    \"save_lokr_weights\",\n    \"load_lokr_weights\",\n    \"check_lycoris_available\",\n    # Data Module (Preprocessed - Recommended)\n    \"PreprocessedTensorDataset\",\n    \"PreprocessedDataModule\",\n    \"collate_preprocessed_batch\",\n    # Data Module (Legacy)\n    \"AceStepTrainingDataset\",\n    \"AceStepDataModule\",\n    \"collate_training_batch\",\n    \"load_dataset_from_json\",\n    # Trainer\n    \"LoRATrainer\",\n    \"LoKRTrainer\",\n    \"PreprocessedLoRAModule\",\n    \"PreprocessedLoKRModule\",\n    \"check_lightning_available\",\n    \"LIGHTNING_AVAILABLE\",\n]\n"
  },
  {
    "path": "acestep/training/configs.py",
    "content": "\"\"\"\nTraining Configuration Classes\n\nContains dataclasses for LoRA and training configurations.\n\"\"\"\n\nfrom dataclasses import dataclass, field\nfrom typing import List\n\n\n@dataclass\nclass LoRAConfig:\n    \"\"\"Configuration for LoRA (Low-Rank Adaptation) training.\n    \n    Attributes:\n        r: LoRA rank (dimension of low-rank matrices)\n        alpha: LoRA scaling factor (alpha/r determines the scaling)\n        dropout: Dropout probability for LoRA layers\n        target_modules: List of module names to apply LoRA to\n        bias: Whether to train bias parameters (\"none\", \"all\", or \"lora_only\")\n    \"\"\"\n    r: int = 8\n    alpha: int = 16\n    dropout: float = 0.1\n    target_modules: List[str] = field(default_factory=lambda: [\n        \"q_proj\", \"k_proj\", \"v_proj\", \"o_proj\"\n    ])\n    bias: str = \"none\"\n    \n    def to_dict(self):\n        \"\"\"Convert to dictionary for PEFT config.\"\"\"\n        return {\n            \"r\": self.r,\n            \"lora_alpha\": self.alpha,\n            \"lora_dropout\": self.dropout,\n            \"target_modules\": self.target_modules,\n            \"bias\": self.bias,\n        }\n\n\n@dataclass\nclass LoKRConfig:\n    \"\"\"Configuration for LoKr (Low-Rank Kronecker) training.\"\"\"\n\n    linear_dim: int = 64\n    linear_alpha: int = 128\n    factor: int = -1\n    decompose_both: bool = False\n    use_tucker: bool = False\n    use_scalar: bool = False\n    weight_decompose: bool = False\n    target_modules: List[str] = field(default_factory=lambda: [\n        \"q_proj\", \"k_proj\", \"v_proj\", \"o_proj\"\n    ])\n    full_matrix: bool = False\n    bypass_mode: bool = False\n    rs_lora: bool = False\n    unbalanced_factorization: bool = False\n\n    def to_dict(self):\n        \"\"\"Convert to dictionary for LyCORIS config.\"\"\"\n        return {\n            \"linear_dim\": self.linear_dim,\n            \"linear_alpha\": self.linear_alpha,\n            \"factor\": self.factor,\n            \"decompose_both\": self.decompose_both,\n            \"use_tucker\": self.use_tucker,\n            \"use_scalar\": self.use_scalar,\n            \"weight_decompose\": self.weight_decompose,\n            \"target_modules\": self.target_modules,\n            \"full_matrix\": self.full_matrix,\n            \"bypass_mode\": self.bypass_mode,\n            \"rs_lora\": self.rs_lora,\n            \"unbalanced_factorization\": self.unbalanced_factorization,\n        }\n\n\n@dataclass\nclass TrainingConfig:\n    \"\"\"Configuration for LoRA training process.\n    \n    Training uses:\n    - Device-aware mixed precision (bf16 on CUDA/XPU, fp16 on MPS, fp32 on CPU)\n    - Discrete timesteps from turbo shift=3.0 schedule (8 steps)\n    - Randomly samples one of 8 timesteps per training step:\n      [1.0, 0.9545, 0.9, 0.8333, 0.75, 0.6429, 0.5, 0.3]\n    \n    Attributes:\n        shift: Timestep shift factor (fixed at 3.0 for turbo model)\n        num_inference_steps: Number of inference steps (fixed at 8 for turbo)\n        learning_rate: Initial learning rate\n        batch_size: Training batch size\n        gradient_accumulation_steps: Number of gradient accumulation steps\n        max_epochs: Maximum number of training epochs\n        save_every_n_epochs: Save checkpoint every N epochs\n        warmup_steps: Number of warmup steps for learning rate scheduler\n        weight_decay: Weight decay for optimizer\n        max_grad_norm: Maximum gradient norm for clipping\n        mixed_precision: Preferred precision mode for logging/config tracking\n        seed: Random seed for reproducibility\n        output_dir: Directory to save checkpoints and logs\n    \"\"\"\n    # Fixed for turbo model\n    shift: float = 3.0  # Fixed: turbo uses shift=3.0\n    num_inference_steps: int = 8  # Fixed: turbo uses 8 steps\n    learning_rate: float = 1e-4\n    batch_size: int = 1\n    gradient_accumulation_steps: int = 4\n    max_epochs: int = 100\n    save_every_n_epochs: int = 10\n    warmup_steps: int = 100\n    weight_decay: float = 0.01\n    max_grad_norm: float = 1.0\n    mixed_precision: str = \"bf16\"\n    use_fp8: bool = False\n    gradient_checkpointing: bool = False\n    seed: int = 42\n    output_dir: str = \"./lora_output\"\n    \n    # Data loading\n    num_workers: int = 4\n    pin_memory: bool = True\n    prefetch_factor: int = 2\n    persistent_workers: bool = True\n    pin_memory_device: str = \"\"\n    \n    # Logging\n    log_every_n_steps: int = 10\n\n    # Validation (for loss curve and best-checkpoint tracking)\n    val_split: float = 0.0\n\n    def __post_init__(self) -> None:\n        if not 0.0 <= self.val_split < 1.0:\n            raise ValueError(\"val_split must be in [0.0, 1.0).\")\n\n    def to_dict(self):\n        \"\"\"Convert to dictionary.\"\"\"\n        return {\n            \"shift\": self.shift,\n            \"num_inference_steps\": self.num_inference_steps,\n            \"learning_rate\": self.learning_rate,\n            \"batch_size\": self.batch_size,\n            \"gradient_accumulation_steps\": self.gradient_accumulation_steps,\n            \"max_epochs\": self.max_epochs,\n            \"save_every_n_epochs\": self.save_every_n_epochs,\n            \"warmup_steps\": self.warmup_steps,\n            \"weight_decay\": self.weight_decay,\n            \"max_grad_norm\": self.max_grad_norm,\n            \"mixed_precision\": self.mixed_precision,\n            \"use_fp8\": self.use_fp8,\n            \"gradient_checkpointing\": self.gradient_checkpointing,\n            \"seed\": self.seed,\n            \"output_dir\": self.output_dir,\n            \"num_workers\": self.num_workers,\n            \"pin_memory\": self.pin_memory,\n            \"prefetch_factor\": self.prefetch_factor,\n            \"persistent_workers\": self.persistent_workers,\n            \"pin_memory_device\": self.pin_memory_device,\n            \"log_every_n_steps\": self.log_every_n_steps,\n            \"val_split\": self.val_split,\n        }\n"
  },
  {
    "path": "acestep/training/data_module.py",
    "content": "\"\"\"\nPyTorch Lightning DataModule for LoRA Training\n\nHandles data loading and preprocessing for training ACE-Step LoRA adapters.\nSupports both raw audio loading and preprocessed tensor loading.\n\"\"\"\n\nimport os\nimport json\nimport random\nfrom typing import Optional, List, Dict, Any, Tuple\nfrom loguru import logger\n\nfrom acestep.training.path_safety import safe_path\n\nimport torch\nimport torchaudio\nfrom torch.utils.data import Dataset, DataLoader\n\ntry:\n    from lightning.pytorch import LightningDataModule\n    LIGHTNING_AVAILABLE = True\nexcept ImportError:\n    LIGHTNING_AVAILABLE = False\n    logger.warning(\"Lightning not installed. Training module will not be available.\")\n    # Create a dummy class for type hints\n    class LightningDataModule:\n        pass\n\n\n# ============================================================================\n# Preprocessed Tensor Dataset (Recommended for Training)\n# ============================================================================\n\nclass PreprocessedTensorDataset(Dataset):\n    \"\"\"Dataset that loads preprocessed tensor files.\n    \n    This is the recommended dataset for training as all tensors are pre-computed:\n    - target_latents: VAE-encoded audio [T, 64]\n    - encoder_hidden_states: Condition encoder output [L, D]\n    - encoder_attention_mask: Condition mask [L]\n    - context_latents: Source context [T, 65]\n    - attention_mask: Audio latent mask [T]\n    \n    No VAE/text encoder needed during training - just load tensors directly!\n    \"\"\"\n    \n    def __init__(self, tensor_dir: str):\n        \"\"\"Initialize from a directory of preprocessed .pt files.\n        \n        Args:\n            tensor_dir: Directory containing preprocessed .pt files and manifest.json\n            \n        Raises:\n            ValueError: If tensor_dir is not an existing directory or escapes safe root.\n        \"\"\"\n        validated_dir = safe_path(tensor_dir)\n        if not os.path.isdir(validated_dir):\n            raise ValueError(f\"Not an existing directory: {tensor_dir}\")\n        self.tensor_dir = validated_dir\n        self.sample_paths: List[str] = []\n        \n        # Load manifest if exists\n        manifest_path = safe_path(\"manifest.json\", base=self.tensor_dir)\n        if os.path.exists(manifest_path):\n            with open(manifest_path, 'r') as f:\n                manifest = json.load(f)\n            raw_paths = manifest.get(\"samples\", [])\n            for raw in raw_paths:\n                resolved = self._resolve_manifest_path(raw)\n                if resolved is not None:\n                    self.sample_paths.append(resolved)\n        else:\n            # Fallback: scan directory for .pt files (already inside tensor_dir)\n            for f in os.listdir(self.tensor_dir):\n                if f.endswith('.pt') and f != \"manifest.json\":\n                    self.sample_paths.append(\n                        safe_path(f, base=self.tensor_dir)\n                    )\n        \n        # Validate paths exist on disk\n        self.valid_paths = [p for p in self.sample_paths if os.path.exists(p)]\n        \n        if len(self.valid_paths) != len(self.sample_paths):\n            logger.warning(\n                f\"Some tensor files not found: \"\n                f\"{len(self.sample_paths) - len(self.valid_paths)} missing\"\n            )\n        \n        logger.info(\n            f\"PreprocessedTensorDataset: {len(self.valid_paths)} samples \"\n            f\"from {self.tensor_dir}\"\n        )\n    \n    def _resolve_manifest_path(self, raw: str) -> Optional[str]:\n        \"\"\"Resolve a single manifest sample path to a validated absolute path.\n\n        Tries ``base=tensor_dir`` first (correct for new manifests that store\n        paths relative to the tensor directory).  If the resulting path does\n        not exist on disk, falls back to resolving against the global safe\n        root (backward compat for legacy manifests that stored CWD-relative\n        paths like ``./datasets/…/foo.pt``).\n\n        Returns:\n            Validated absolute path, or ``None`` if the path cannot be\n            resolved safely.\n        \"\"\"\n        # Primary: resolve relative to tensor_dir\n        try:\n            child = safe_path(raw, base=self.tensor_dir)\n            if os.path.exists(child):\n                return child\n        except ValueError:\n            pass\n\n        # Legacy fallback: resolve relative to global safe root (CWD)\n        try:\n            child = safe_path(raw)\n            if os.path.exists(child):\n                logger.debug(\n                    f\"Resolved legacy manifest path via safe root: {raw}\"\n                )\n                return child\n        except ValueError:\n            pass\n\n        logger.warning(f\"Skipping unresolvable manifest path: {raw}\")\n        return None\n\n    def __len__(self) -> int:\n        return len(self.valid_paths)\n    \n    def __getitem__(self, idx: int) -> Dict[str, torch.Tensor]:\n        \"\"\"Load a preprocessed tensor file.\n        \n        Returns:\n            Dictionary containing all pre-computed tensors for training\n        \"\"\"\n        tensor_path = self.valid_paths[idx]\n        data = torch.load(tensor_path, map_location='cpu', weights_only=True)\n        \n        return {\n            \"target_latents\": data[\"target_latents\"],  # [T, 64]\n            \"attention_mask\": data[\"attention_mask\"],  # [T]\n            \"encoder_hidden_states\": data[\"encoder_hidden_states\"],  # [L, D]\n            \"encoder_attention_mask\": data[\"encoder_attention_mask\"],  # [L]\n            \"context_latents\": data[\"context_latents\"],  # [T, 65]\n            \"metadata\": data.get(\"metadata\", {}),\n        }\n\n\ndef collate_preprocessed_batch(batch: List[Dict]) -> Dict[str, torch.Tensor]:\n    \"\"\"Collate function for preprocessed tensor batches.\n    \n    Handles variable-length tensors by padding to the longest in the batch.\n    \n    Args:\n        batch: List of sample dictionaries with pre-computed tensors\n        \n    Returns:\n        Batched dictionary with all tensors stacked\n    \"\"\"\n    # Get max lengths\n    max_latent_len = max(s[\"target_latents\"].shape[0] for s in batch)\n    max_encoder_len = max(s[\"encoder_hidden_states\"].shape[0] for s in batch)\n    \n    # Pad and stack tensors\n    target_latents = []\n    attention_masks = []\n    encoder_hidden_states = []\n    encoder_attention_masks = []\n    context_latents = []\n    \n    for sample in batch:\n        # Pad target_latents [T, 64] -> [max_T, 64]\n        tl = sample[\"target_latents\"]\n        if tl.shape[0] < max_latent_len:\n            pad = tl.new_zeros(max_latent_len - tl.shape[0], tl.shape[1])\n            tl = torch.cat([tl, pad], dim=0)\n        target_latents.append(tl)\n        \n        # Pad attention_mask [T] -> [max_T]\n        am = sample[\"attention_mask\"]\n        if am.shape[0] < max_latent_len:\n            pad = am.new_zeros(max_latent_len - am.shape[0])\n            am = torch.cat([am, pad], dim=0)\n        attention_masks.append(am)\n        \n        # Pad context_latents [T, 65] -> [max_T, 65]\n        cl = sample[\"context_latents\"]\n        if cl.shape[0] < max_latent_len:\n            pad = cl.new_zeros(max_latent_len - cl.shape[0], cl.shape[1])\n            cl = torch.cat([cl, pad], dim=0)\n        context_latents.append(cl)\n        \n        # Pad encoder_hidden_states [L, D] -> [max_L, D]\n        ehs = sample[\"encoder_hidden_states\"]\n        if ehs.shape[0] < max_encoder_len:\n            pad = ehs.new_zeros(max_encoder_len - ehs.shape[0], ehs.shape[1])\n            ehs = torch.cat([ehs, pad], dim=0)\n        encoder_hidden_states.append(ehs)\n        \n        # Pad encoder_attention_mask [L] -> [max_L]\n        eam = sample[\"encoder_attention_mask\"]\n        if eam.shape[0] < max_encoder_len:\n            pad = eam.new_zeros(max_encoder_len - eam.shape[0])\n            eam = torch.cat([eam, pad], dim=0)\n        encoder_attention_masks.append(eam)\n    \n    return {\n        \"target_latents\": torch.stack(target_latents),  # [B, T, 64]\n        \"attention_mask\": torch.stack(attention_masks),  # [B, T]\n        \"encoder_hidden_states\": torch.stack(encoder_hidden_states),  # [B, L, D]\n        \"encoder_attention_mask\": torch.stack(encoder_attention_masks),  # [B, L]\n        \"context_latents\": torch.stack(context_latents),  # [B, T, 65]\n        \"metadata\": [s[\"metadata\"] for s in batch],\n    }\n\n\nclass PreprocessedDataModule(LightningDataModule if LIGHTNING_AVAILABLE else object):\n    \"\"\"DataModule for preprocessed tensor files.\n    \n    This is the recommended DataModule for training. It loads pre-computed tensors\n    directly without needing VAE, text encoder, or condition encoder at training time.\n    \"\"\"\n    \n    def __init__(\n        self,\n        tensor_dir: str,\n        batch_size: int = 1,\n        num_workers: int = 4,\n        pin_memory: bool = True,\n        prefetch_factor: int = 2,\n        persistent_workers: bool = True,\n        pin_memory_device: str = \"\",\n        val_split: float = 0.0,\n    ):\n        \"\"\"Initialize the data module.\n        \n        Args:\n            tensor_dir: Directory containing preprocessed .pt files\n            batch_size: Training batch size\n            num_workers: Number of data loading workers\n            pin_memory: Whether to pin memory for faster GPU transfer\n            val_split: Fraction of data for validation (0 = no validation)\n        \"\"\"\n        if LIGHTNING_AVAILABLE:\n            super().__init__()\n        \n        self.tensor_dir = tensor_dir\n        self.batch_size = batch_size\n        self.num_workers = num_workers\n        self.pin_memory = pin_memory\n        self.prefetch_factor = prefetch_factor\n        self.persistent_workers = persistent_workers\n        self.pin_memory_device = pin_memory_device\n        self.val_split = val_split\n        \n        self.train_dataset = None\n        self.val_dataset = None\n    \n    def setup(self, stage: Optional[str] = None):\n        \"\"\"Setup datasets.\"\"\"\n        if stage == 'fit' or stage is None:\n            # Create full dataset\n            full_dataset = PreprocessedTensorDataset(self.tensor_dir)\n            \n            # Split if validation requested\n            if self.val_split > 0 and len(full_dataset) > 1:\n                n_val = max(1, int(len(full_dataset) * self.val_split))\n                n_train = len(full_dataset) - n_val\n                \n                self.train_dataset, self.val_dataset = torch.utils.data.random_split(\n                    full_dataset, [n_train, n_val]\n                )\n            else:\n                self.train_dataset = full_dataset\n                self.val_dataset = None\n    \n    def train_dataloader(self) -> DataLoader:\n        \"\"\"Create training dataloader.\"\"\"\n        prefetch_factor = None if self.num_workers == 0 else self.prefetch_factor\n        persistent_workers = False if self.num_workers == 0 else self.persistent_workers\n        kwargs = dict(\n            dataset=self.train_dataset,\n            batch_size=self.batch_size,\n            shuffle=True,\n            num_workers=self.num_workers,\n            pin_memory=self.pin_memory,\n            collate_fn=collate_preprocessed_batch,\n            drop_last=False,\n            prefetch_factor=prefetch_factor,\n            persistent_workers=persistent_workers,\n        )\n        if self.pin_memory_device:\n            kwargs[\"pin_memory_device\"] = self.pin_memory_device\n        return DataLoader(**kwargs)\n    \n    def val_dataloader(self) -> Optional[DataLoader]:\n        \"\"\"Create validation dataloader.\"\"\"\n        if self.val_dataset is None:\n            return None\n        prefetch_factor = None if self.num_workers == 0 else self.prefetch_factor\n        persistent_workers = False if self.num_workers == 0 else self.persistent_workers\n        kwargs = dict(\n            dataset=self.val_dataset,\n            batch_size=self.batch_size,\n            shuffle=False,\n            num_workers=self.num_workers,\n            pin_memory=self.pin_memory,\n            collate_fn=collate_preprocessed_batch,\n            prefetch_factor=prefetch_factor,\n            persistent_workers=persistent_workers,\n        )\n        if self.pin_memory_device:\n            kwargs[\"pin_memory_device\"] = self.pin_memory_device\n        return DataLoader(**kwargs)\n\n\n# ============================================================================\n# Raw Audio Dataset (Legacy - for backward compatibility)\n# ============================================================================\n\nclass AceStepTrainingDataset(Dataset):\n    \"\"\"Dataset for ACE-Step LoRA training from raw audio.\n    \n    DEPRECATED: Use PreprocessedTensorDataset instead for better performance.\n    \n    Audio Format Requirements (handled automatically):\n    - Sample rate: 48kHz (resampled if different)\n    - Channels: Stereo (2 channels, mono is duplicated)\n    - Max duration: 240 seconds (4 minutes)\n    - Min duration: 5 seconds (padded if shorter)\n    \"\"\"\n    \n    def __init__(\n        self,\n        samples: List[Dict[str, Any]],\n        dit_handler,\n        max_duration: float = 240.0,\n        target_sample_rate: int = 48000,\n    ):\n        \"\"\"Initialize the dataset.\"\"\"\n        self.samples = samples\n        self.dit_handler = dit_handler\n        self.max_duration = max_duration\n        self.target_sample_rate = target_sample_rate\n        \n        self.valid_samples = self._validate_samples()\n        logger.info(f\"Dataset initialized with {len(self.valid_samples)} valid samples\")\n    \n    def _validate_samples(self) -> List[Dict[str, Any]]:\n        \"\"\"Validate and filter samples, resolving audio paths to safe paths.\"\"\"\n        valid = []\n        for i, sample in enumerate(self.samples):\n            audio_path = sample.get(\"audio_path\", \"\")\n            if not audio_path:\n                logger.warning(f\"Sample {i}: Missing audio_path\")\n                continue\n\n            try:\n                validated = safe_path(audio_path)\n            except ValueError:\n                logger.warning(f\"Sample {i}: Rejected unsafe path: {audio_path}\")\n                continue\n\n            if not os.path.isfile(validated):\n                logger.warning(f\"Sample {i}: Audio file not found: {audio_path}\")\n                continue\n            \n            if not sample.get(\"caption\"):\n                logger.warning(f\"Sample {i}: Missing caption\")\n                continue\n            \n            # Store validated path so downstream code never uses raw user input\n            sample = {**sample, \"audio_path\": validated}\n            valid.append(sample)\n        \n        return valid\n    \n    def __len__(self) -> int:\n        return len(self.valid_samples)\n    \n    def __getitem__(self, idx: int) -> Dict[str, torch.Tensor]:\n        \"\"\"Get a single training sample.\"\"\"\n        sample = self.valid_samples[idx]\n        \n        audio_path = sample[\"audio_path\"]\n        audio, sr = torchaudio.load(audio_path)\n        \n        # Resample to 48kHz\n        if sr != self.target_sample_rate:\n            resampler = torchaudio.transforms.Resample(sr, self.target_sample_rate)\n            audio = resampler(audio)\n        \n        # Convert to stereo\n        if audio.shape[0] == 1:\n            audio = audio.repeat(2, 1)\n        elif audio.shape[0] > 2:\n            audio = audio[:2, :]\n        \n        # Truncate/pad\n        max_samples = int(self.max_duration * self.target_sample_rate)\n        if audio.shape[1] > max_samples:\n            audio = audio[:, :max_samples]\n        \n        min_samples = int(5.0 * self.target_sample_rate)\n        if audio.shape[1] < min_samples:\n            padding = min_samples - audio.shape[1]\n            audio = torch.nn.functional.pad(audio, (0, padding))\n        \n        return {\n            \"audio\": audio,\n            \"caption\": sample.get(\"caption\", \"\"),\n            \"lyrics\": sample.get(\"lyrics\", \"[Instrumental]\"),\n            \"metadata\": {\n                \"caption\": sample.get(\"caption\", \"\"),\n                \"lyrics\": sample.get(\"lyrics\", \"[Instrumental]\"),\n                \"bpm\": sample.get(\"bpm\"),\n                \"keyscale\": sample.get(\"keyscale\", \"\"),\n                \"timesignature\": sample.get(\"timesignature\", \"\"),\n                \"duration\": sample.get(\"duration\", audio.shape[1] / self.target_sample_rate),\n                \"language\": sample.get(\"language\", \"unknown\"),\n                \"is_instrumental\": sample.get(\"is_instrumental\", True),\n            },\n            \"audio_path\": audio_path,\n        }\n\n\ndef collate_training_batch(batch: List[Dict]) -> Dict[str, Any]:\n    \"\"\"Collate function for raw audio batches (legacy).\"\"\"\n    max_len = max(sample[\"audio\"].shape[1] for sample in batch)\n    \n    padded_audio = []\n    attention_masks = []\n    \n    for sample in batch:\n        audio = sample[\"audio\"]\n        audio_len = audio.shape[1]\n        \n        if audio_len < max_len:\n            padding = max_len - audio_len\n            audio = torch.nn.functional.pad(audio, (0, padding))\n        \n        padded_audio.append(audio)\n        \n        mask = torch.ones(max_len)\n        if audio_len < max_len:\n            mask[audio_len:] = 0\n        attention_masks.append(mask)\n    \n    return {\n        \"audio\": torch.stack(padded_audio),\n        \"attention_mask\": torch.stack(attention_masks),\n        \"captions\": [s[\"caption\"] for s in batch],\n        \"lyrics\": [s[\"lyrics\"] for s in batch],\n        \"metadata\": [s[\"metadata\"] for s in batch],\n        \"audio_paths\": [s[\"audio_path\"] for s in batch],\n    }\n\n\nclass AceStepDataModule(LightningDataModule if LIGHTNING_AVAILABLE else object):\n    \"\"\"DataModule for raw audio loading (legacy).\n    \n    DEPRECATED: Use PreprocessedDataModule for better training performance.\n    \"\"\"\n    \n    def __init__(\n        self,\n        samples: List[Dict[str, Any]],\n        dit_handler,\n        batch_size: int = 1,\n        num_workers: int = 4,\n        pin_memory: bool = True,\n        max_duration: float = 240.0,\n        val_split: float = 0.0,\n    ):\n        if LIGHTNING_AVAILABLE:\n            super().__init__()\n        \n        self.samples = samples\n        self.dit_handler = dit_handler\n        self.batch_size = batch_size\n        self.num_workers = num_workers\n        self.pin_memory = pin_memory\n        self.max_duration = max_duration\n        self.val_split = val_split\n        \n        self.train_dataset = None\n        self.val_dataset = None\n    \n    def setup(self, stage: Optional[str] = None):\n        if stage == 'fit' or stage is None:\n            if self.val_split > 0 and len(self.samples) > 1:\n                n_val = max(1, int(len(self.samples) * self.val_split))\n                \n                indices = list(range(len(self.samples)))\n                random.shuffle(indices)\n                \n                val_indices = indices[:n_val]\n                train_indices = indices[n_val:]\n                \n                train_samples = [self.samples[i] for i in train_indices]\n                val_samples = [self.samples[i] for i in val_indices]\n                \n                self.train_dataset = AceStepTrainingDataset(\n                    train_samples, self.dit_handler, self.max_duration\n                )\n                self.val_dataset = AceStepTrainingDataset(\n                    val_samples, self.dit_handler, self.max_duration\n                )\n            else:\n                self.train_dataset = AceStepTrainingDataset(\n                    self.samples, self.dit_handler, self.max_duration\n                )\n                self.val_dataset = None\n    \n    def train_dataloader(self) -> DataLoader:\n        return DataLoader(\n            self.train_dataset,\n            batch_size=self.batch_size,\n            shuffle=True,\n            num_workers=self.num_workers,\n            pin_memory=self.pin_memory,\n            collate_fn=collate_training_batch,\n            drop_last=True,\n        )\n    \n    def val_dataloader(self) -> Optional[DataLoader]:\n        if self.val_dataset is None:\n            return None\n        \n        return DataLoader(\n            self.val_dataset,\n            batch_size=self.batch_size,\n            shuffle=False,\n            num_workers=self.num_workers,\n            pin_memory=self.pin_memory,\n            collate_fn=collate_training_batch,\n        )\n\n\ndef load_dataset_from_json(json_path: str) -> Tuple[List[Dict[str, Any]], Dict[str, Any]]:\n    \"\"\"Load a dataset from JSON file.\n\n    Args:\n        json_path: Path to the JSON dataset file.\n\n    Returns:\n        Tuple of (samples list, metadata dict).\n\n    Raises:\n        ValueError: If json_path does not point to an existing file or escapes safe root.\n    \"\"\"\n    validated = safe_path(json_path)\n    if not os.path.isfile(validated):\n        raise ValueError(f\"Dataset JSON file not found: {json_path}\")\n\n    with open(validated, 'r', encoding='utf-8') as f:\n        data = json.load(f)\n    \n    metadata = data.get(\"metadata\", {})\n    samples = data.get(\"samples\", [])\n    \n    return samples, metadata\n"
  },
  {
    "path": "acestep/training/data_module_test.py",
    "content": "\"\"\"Tests for path-sanitisation in data_module.\n\nCovers the safe_path integration in PreprocessedTensorDataset and\nload_dataset_from_json that guards against path-traversal attacks\n(CodeQL: uncontrolled data used in path expression).\n\"\"\"\n\nimport os\nimport json\nimport tempfile\nimport unittest\n\nfrom acestep.training.path_safety import safe_path, set_safe_root\nfrom acestep.training.data_module import (\n    PreprocessedTensorDataset,\n    load_dataset_from_json,\n)\n\n\nclass SafePathTests(unittest.TestCase):\n    \"\"\"Tests for safe_path from path_safety module.\"\"\"\n\n    def test_valid_directory(self):\n        with tempfile.TemporaryDirectory() as d:\n            parent = os.path.dirname(os.path.realpath(d))\n            set_safe_root(parent)\n            result = safe_path(d)\n            self.assertEqual(result, os.path.realpath(d))\n\n    def test_traversal_raises(self):\n        with tempfile.TemporaryDirectory() as d:\n            set_safe_root(d)\n            with self.assertRaises(ValueError):\n                safe_path(\"../../etc/passwd\", base=d)\n\n    def test_absolute_path_outside_raises(self):\n        with tempfile.TemporaryDirectory() as d:\n            set_safe_root(d)\n            with self.assertRaises(ValueError):\n                safe_path(\"/etc/passwd\", base=d)\n\n    def test_normal_child(self):\n        with tempfile.TemporaryDirectory() as d:\n            base = os.path.realpath(d)\n            result = safe_path(\"foo.pt\", base=base)\n            self.assertEqual(result, os.path.join(base, \"foo.pt\"))\n\n    def test_absolute_path_inside_allowed(self):\n        with tempfile.TemporaryDirectory() as d:\n            base = os.path.realpath(d)\n            child = os.path.join(base, \"sub\", \"file.pt\")\n            result = safe_path(child, base=base)\n            self.assertEqual(result, child)\n\n\nclass PreprocessedTensorDatasetPathSafetyTests(unittest.TestCase):\n    \"\"\"Tests that PreprocessedTensorDataset rejects traversal paths.\"\"\"\n\n    def setUp(self):\n        # Allow /tmp paths during tests\n        set_safe_root(tempfile.gettempdir())\n\n    def test_manifest_traversal_paths_skipped(self):\n        \"\"\"Paths in manifest.json that escape tensor_dir are ignored.\"\"\"\n        with tempfile.TemporaryDirectory() as d:\n            # Create a manifest with one good and one bad path\n            good_pt = os.path.join(d, \"good.pt\")\n            open(good_pt, \"wb\").close()  # touch\n\n            manifest = {\n                \"samples\": [\n                    \"good.pt\",\n                    \"../../etc/passwd\",\n                ]\n            }\n            with open(os.path.join(d, \"manifest.json\"), \"w\") as f:\n                json.dump(manifest, f)\n\n            ds = PreprocessedTensorDataset(d)\n            # Only the safe path should survive\n            self.assertEqual(len(ds.valid_paths), 1)\n            self.assertTrue(ds.valid_paths[0].endswith(\"good.pt\"))\n\n    def test_fallback_scan_only_finds_pt_files(self):\n        \"\"\"Without manifest, only .pt files inside tensor_dir are found.\"\"\"\n        with tempfile.TemporaryDirectory() as d:\n            for name in [\"a.pt\", \"b.pt\", \"c.txt\"]:\n                open(os.path.join(d, name), \"wb\").close()\n\n            ds = PreprocessedTensorDataset(d)\n            self.assertEqual(len(ds.valid_paths), 2)\n\n    def test_nonexistent_dir_raises(self):\n        with self.assertRaises(ValueError):\n            PreprocessedTensorDataset(\"/tmp/nonexistent_xyz_12345\")\n\n    def test_manifest_relative_to_tensor_dir(self):\n        \"\"\"Manifest with paths relative to tensor_dir loads correctly.\"\"\"\n        with tempfile.TemporaryDirectory() as d:\n            for name in [\"a.pt\", \"b.pt\"]:\n                open(os.path.join(d, name), \"wb\").close()\n\n            manifest = {\"samples\": [\"a.pt\", \"b.pt\"]}\n            with open(os.path.join(d, \"manifest.json\"), \"w\") as f:\n                json.dump(manifest, f)\n\n            ds = PreprocessedTensorDataset(d)\n            self.assertEqual(len(ds.valid_paths), 2)\n\n    def test_manifest_legacy_cwd_relative_paths(self):\n        \"\"\"Legacy manifest with CWD-relative paths resolves via fallback.\"\"\"\n        with tempfile.TemporaryDirectory() as root:\n            set_safe_root(root)\n            tensor_dir = os.path.join(root, \"sub\", \"tensors\")\n            os.makedirs(tensor_dir)\n            pt_file = os.path.join(tensor_dir, \"sample.pt\")\n            open(pt_file, \"wb\").close()\n\n            # Legacy manifest stored the full CWD-relative path\n            legacy_rel = os.path.relpath(pt_file, root)\n            manifest = {\"samples\": [legacy_rel]}\n            with open(os.path.join(tensor_dir, \"manifest.json\"), \"w\") as f:\n                json.dump(manifest, f)\n\n            ds = PreprocessedTensorDataset(tensor_dir)\n            self.assertEqual(len(ds.valid_paths), 1)\n            self.assertEqual(\n                os.path.realpath(ds.valid_paths[0]),\n                os.path.realpath(pt_file),\n            )\n\n\nclass SaveManifestTests(unittest.TestCase):\n    \"\"\"Tests for save_manifest path normalisation.\"\"\"\n\n    def test_paths_stored_relative_to_output_dir(self):\n        \"\"\"save_manifest converts absolute/CWD-relative paths to dir-relative.\"\"\"\n        from acestep.training.dataset_builder_modules.preprocess_manifest import (\n            save_manifest,\n        )\n        from types import SimpleNamespace\n\n        with tempfile.TemporaryDirectory() as d:\n            metadata = SimpleNamespace(to_dict=lambda: {\"name\": \"test\"})\n            # Simulate paths that preprocess_to_tensors produces\n            output_paths = [\n                os.path.join(d, \"a.pt\"),\n                os.path.join(d, \"b.pt\"),\n            ]\n            save_manifest(d, metadata, output_paths)\n            with open(os.path.join(d, \"manifest.json\")) as f:\n                manifest = json.load(f)\n            # Paths should be just filenames (relative to d)\n            self.assertEqual(manifest[\"samples\"], [\"a.pt\", \"b.pt\"])\n            self.assertEqual(manifest[\"num_samples\"], 2)\n\n    def test_cwd_relative_input_normalised(self):\n        \"\"\"CWD-relative input paths are normalised to dir-relative.\"\"\"\n        from acestep.training.dataset_builder_modules.preprocess_manifest import (\n            save_manifest,\n        )\n        from types import SimpleNamespace\n\n        with tempfile.TemporaryDirectory() as d:\n            metadata = SimpleNamespace(to_dict=lambda: {\"name\": \"test\"})\n            # Paths like \"./subdir/a.pt\" relative to CWD\n            cwd_rel = os.path.relpath(os.path.join(d, \"x.pt\"))\n            save_manifest(d, metadata, [cwd_rel])\n            with open(os.path.join(d, \"manifest.json\")) as f:\n                manifest = json.load(f)\n            self.assertEqual(manifest[\"samples\"], [\"x.pt\"])\n\n\nclass LoadDatasetFromJsonTests(unittest.TestCase):\n    \"\"\"Tests for load_dataset_from_json path validation.\"\"\"\n\n    def setUp(self):\n        set_safe_root(tempfile.gettempdir())\n\n    def test_nonexistent_file_raises(self):\n        with self.assertRaises(ValueError):\n            load_dataset_from_json(\"/tmp/nonexistent_file.json\")\n\n    def test_valid_json(self):\n        with tempfile.NamedTemporaryFile(mode=\"w\", suffix=\".json\", delete=False) as f:\n            json.dump({\"metadata\": {\"v\": 1}, \"samples\": [{\"a\": 1}]}, f)\n            path = f.name\n        try:\n            samples, meta = load_dataset_from_json(path)\n            self.assertEqual(len(samples), 1)\n            self.assertEqual(meta[\"v\"], 1)\n        finally:\n            os.unlink(path)\n\n\nif __name__ == \"__main__\":\n    unittest.main()\n"
  },
  {
    "path": "acestep/training/dataset_builder.py",
    "content": "\"\"\"\nDataset Builder for LoRA Training (facade).\n\nThis module preserves the public API while delegating to smaller modules.\n\"\"\"\n\nfrom .dataset_builder_modules import AudioSample, DatasetBuilder, DatasetMetadata, SUPPORTED_AUDIO_FORMATS\n\n__all__ = [\n    \"AudioSample\",\n    \"DatasetBuilder\",\n    \"DatasetMetadata\",\n    \"SUPPORTED_AUDIO_FORMATS\",\n]\n"
  },
  {
    "path": "acestep/training/dataset_builder_modules/__init__.py",
    "content": "from .models import AudioSample, DatasetMetadata, SUPPORTED_AUDIO_FORMATS\nfrom .builder import DatasetBuilder\n\n__all__ = [\n    \"AudioSample\",\n    \"DatasetMetadata\",\n    \"DatasetBuilder\",\n    \"SUPPORTED_AUDIO_FORMATS\",\n]\n"
  },
  {
    "path": "acestep/training/dataset_builder_modules/audio_io.py",
    "content": "import json\nimport os\nfrom typing import Dict, Any, Tuple\n\nfrom loguru import logger\n\nfrom acestep.training.path_safety import safe_path\n\n\ndef _read_text_file(path: str) -> Tuple[str, bool]:\n    \"\"\"Read a text file; return (content.strip(), True) if present and non-empty.\n\n    Args:\n        path: Already-validated file path.\n    \"\"\"\n    validated = safe_path(path)\n    if not os.path.exists(validated):\n        return \"\", False\n    try:\n        with open(validated, \"r\", encoding=\"utf-8\") as f:\n            content = f.read().strip()\n        if content:\n            return content, True\n        return \"\", False\n    except Exception as e:\n        logger.warning(f\"Failed to read {validated}: {e}\")\n        return \"\", False\n\n\ndef load_caption_file(audio_path: str) -> Tuple[str, bool]:\n    \"\"\"Load caption from <basename>.caption.txt (explicit convention).\"\"\"\n    validated = safe_path(audio_path)\n    base_path = os.path.splitext(validated)[0]\n    caption_path = base_path + \".caption.txt\"\n    content, ok = _read_text_file(caption_path)\n    if ok:\n        logger.debug(f\"Loaded caption from {caption_path}\")\n    return content, ok\n\n\ndef load_json_metadata(audio_path: str) -> Tuple[Dict[str, Any], bool]:\n    \"\"\"Load metadata from <basename>.json.\n\n    Expected JSON structure:\n        {\n            \"caption\": \"\",\n            \"bpm\": 120,\n            \"keyscale\": \"C major\",\n            \"timesignature\": \"4\",\n            \"language\": \"ja\"\n        }\n\n    All fields are optional.\n    \"\"\"\n    validated = safe_path(audio_path)\n    base_path = os.path.splitext(validated)[0]\n    json_path = base_path + \".json\"\n    if not os.path.exists(json_path):\n        return {}, False\n    try:\n        with open(json_path, \"r\", encoding=\"utf-8\") as f:\n            data = json.load(f)\n        if isinstance(data, dict):\n            logger.debug(f\"Loaded JSON metadata from {json_path}\")\n            return data, True\n        return {}, False\n    except Exception as e:\n        logger.warning(f\"Failed to read {json_path}: {e}\")\n        return {}, False\n\n\ndef load_lyrics_file(audio_path: str) -> Tuple[str, bool]:\n    \"\"\"Load lyrics from <basename>.lyrics.txt, then fallback to <basename>.txt for backward compat.\"\"\"\n    validated = safe_path(audio_path)\n    base_path = os.path.splitext(validated)[0]\n    for suffix in (\".lyrics.txt\", \".txt\"):\n        path = base_path + suffix\n        content, ok = _read_text_file(path)\n        if ok:\n            if suffix == \".lyrics.txt\":\n                logger.debug(f\"Loaded lyrics from {path}\")\n            else:\n                logger.debug(f\"Loaded lyrics from {path} (legacy .txt)\")\n            return content, True\n    return \"\", False\n\n\ndef get_audio_duration(audio_path: str) -> int:\n    \"\"\"Get the duration of an audio file in seconds.\"\"\"\n    validated = safe_path(audio_path)\n    # Primary: torchcodec (ships with torchaudio >=2.9, supports all ffmpeg formats)\n    # Note: torchcodec is optional on ROCM/Intel platforms due to CUDA dependencies\n    try:\n        from torchcodec.decoders import AudioDecoder\n        decoder = AudioDecoder(validated)\n        return int(decoder.metadata.duration_seconds)\n    except ImportError:\n        logger.debug(\"torchcodec not available (expected on ROCM/Intel platforms), using soundfile fallback\")\n    except Exception as e:\n        logger.debug(f\"torchcodec failed for {validated}: {e}, trying soundfile\")\n    # Fallback: soundfile (fast for wav/flac/ogg, works on all platforms)\n    try:\n        import soundfile as sf\n        info = sf.info(validated)\n        return int(info.duration)\n    except Exception as e:\n        logger.warning(f\"Failed to get duration for {validated}: {e}\")\n        return 0\n"
  },
  {
    "path": "acestep/training/dataset_builder_modules/builder.py",
    "content": "from .core import CoreMixin\nfrom .dataframe import DataframeMixin\nfrom .label_all import LabelAllMixin\nfrom .label_single import LabelSingleMixin\nfrom .metadata import MetadataMixin\nfrom .preprocess import PreprocessMixin\nfrom .scan import ScanMixin\nfrom .serialization import SerializationMixin\nfrom .update_sample import UpdateSampleMixin\n\n\nclass DatasetBuilder(\n    CoreMixin,\n    ScanMixin,\n    LabelSingleMixin,\n    LabelAllMixin,\n    UpdateSampleMixin,\n    MetadataMixin,\n    SerializationMixin,\n    DataframeMixin,\n    PreprocessMixin,\n):\n    \"\"\"Builder for creating training datasets from audio files.\"\"\"\n\n    pass\n"
  },
  {
    "path": "acestep/training/dataset_builder_modules/core.py",
    "content": "from typing import List\n\nfrom .models import AudioSample, DatasetMetadata\n\n\nclass CoreMixin:\n    \"\"\"Base state for dataset builder.\"\"\"\n\n    def __init__(self):\n        self.samples: List[AudioSample] = []\n        self.metadata = DatasetMetadata()\n        self._current_dir: str = \"\"\n\n    def get_sample_count(self) -> int:\n        \"\"\"Get the number of samples in the dataset.\"\"\"\n        return len(self.samples)\n\n    def get_labeled_count(self) -> int:\n        \"\"\"Get the number of labeled samples.\"\"\"\n        return sum(1 for s in self.samples if s.labeled)\n"
  },
  {
    "path": "acestep/training/dataset_builder_modules/csv_metadata.py",
    "content": "import os\nimport csv\nfrom typing import Any, Dict\n\nfrom loguru import logger\n\nfrom acestep.training.path_safety import safe_path\n\n\ndef load_csv_metadata(directory: str) -> Dict[str, Dict[str, Any]]:\n    \"\"\"Load metadata from CSV files in the directory.\"\"\"\n    metadata: Dict[str, Dict[str, Any]] = {}\n\n    validated_dir = safe_path(directory)\n    csv_files = []\n    for file in os.listdir(validated_dir):\n        if file.lower().endswith(\".csv\"):\n            csv_files.append(safe_path(file, base=validated_dir))\n\n    if not csv_files:\n        return metadata\n\n    for csv_path in csv_files:\n        try:\n            with open(csv_path, \"r\", encoding=\"utf-8\") as f:\n                sample = f.read(4096)\n                f.seek(0)\n\n                try:\n                    dialect = csv.Sniffer().sniff(sample, delimiters=\",;\\t\")\n                    reader = csv.DictReader(f, dialect=dialect)\n                except csv.Error:\n                    reader = csv.DictReader(f)\n\n                if reader.fieldnames is None:\n                    continue\n\n                header_map = {h.lower(): h for h in reader.fieldnames}\n                if \"file\" not in header_map:\n                    continue\n\n                file_col = header_map[\"file\"]\n                bpm_col = header_map.get(\"bpm\")\n                key_col = header_map.get(\"key\")\n                caption_col = header_map.get(\"caption\")\n\n                for row in reader:\n                    filename = row.get(file_col, \"\").strip()\n                    if not filename:\n                        continue\n\n                    entry: Dict[str, Any] = {}\n\n                    if bpm_col and row.get(bpm_col):\n                        try:\n                            bpm_val = row[bpm_col].strip()\n                            entry[\"bpm\"] = int(float(bpm_val))\n                        except (ValueError, TypeError):\n                            pass\n\n                    if key_col and row.get(key_col):\n                        key_val = row[key_col].strip()\n                        if key_val:\n                            entry[\"key\"] = key_val\n\n                    if caption_col and row.get(caption_col):\n                        caption_val = row[caption_col].strip()\n                        if caption_val:\n                            entry[\"caption\"] = caption_val\n\n                    if entry:\n                        metadata[filename] = entry\n\n            logger.info(f\"Loaded {len(metadata)} entries from CSV: {csv_path}\")\n        except Exception as e:\n            logger.warning(f\"Failed to load CSV {csv_path}: {e}\")\n\n    return metadata\n"
  },
  {
    "path": "acestep/training/dataset_builder_modules/dataframe.py",
    "content": "from typing import Any, Dict, List\n\n\nclass DataframeMixin:\n    \"\"\"Display helpers for UI.\"\"\"\n\n    def get_samples_dataframe_data(self) -> List[List[Any]]:\n        \"\"\"Get samples data in a format suitable for Gradio DataFrame.\"\"\"\n        rows = []\n        for i, sample in enumerate(self.samples):\n            if sample.has_raw_lyrics():\n                lyrics_status = \"📝\"\n            elif sample.is_instrumental:\n                lyrics_status = \"🎵\"\n            else:\n                lyrics_status = \"-\"\n\n            rows.append(\n                [\n                    i,\n                    sample.filename,\n                    f\"{sample.duration:.1f}s\",\n                    lyrics_status,\n                    \"✅\" if sample.labeled else \"❌\",\n                    sample.bpm or \"-\",\n                    sample.keyscale or \"-\",\n                    sample.caption[:50] + \"...\" if len(sample.caption) > 50 else sample.caption or \"-\",\n                ]\n            )\n        return rows\n\n    def to_training_format(self) -> List[Dict[str, Any]]:\n        \"\"\"Convert dataset to format suitable for training.\"\"\"\n        training_samples = []\n\n        for sample in self.samples:\n            if not sample.labeled:\n                continue\n\n            training_sample = {\n                \"audio_path\": sample.audio_path,\n                \"caption\": sample.get_full_caption(self.metadata.tag_position),\n                \"lyrics\": sample.lyrics,\n                \"bpm\": sample.bpm,\n                \"keyscale\": sample.keyscale,\n                \"timesignature\": sample.timesignature,\n                \"duration\": sample.duration,\n                \"language\": sample.language,\n                \"is_instrumental\": sample.is_instrumental,\n            }\n            training_samples.append(training_sample)\n\n        return training_samples\n"
  },
  {
    "path": "acestep/training/dataset_builder_modules/label_all.py",
    "content": "from typing import List, Tuple\n\nfrom .models import AudioSample\n\n\nclass LabelAllMixin:\n    \"\"\"Label all samples in the dataset.\"\"\"\n\n    def label_all_samples(\n        self,\n        dit_handler,\n        llm_handler,\n        format_lyrics: bool = False,\n        transcribe_lyrics: bool = False,\n        skip_metas: bool = False,\n        only_unlabeled: bool = False,\n        progress_callback=None,\n    ) -> Tuple[List[AudioSample], str]:\n        \"\"\"Label all samples in the dataset.\"\"\"\n        if not self.samples:\n            return [], \"❌ No samples to label. Please scan a directory first.\"\n\n        if only_unlabeled:\n            samples_to_label = [\n                (i, s) for i, s in enumerate(self.samples) if not s.labeled or not s.caption\n            ]\n        else:\n            samples_to_label = [(i, s) for i, s in enumerate(self.samples)]\n\n        if not samples_to_label:\n            return self.samples, \"✅ All samples already labeled\"\n\n        success_count = 0\n        fail_count = 0\n        total = len(samples_to_label)\n\n        for idx, (i, sample) in enumerate(samples_to_label):\n            if progress_callback:\n                progress_callback(f\"Labeling {idx+1}/{total}: {sample.filename}\")\n\n            _, status = self.label_sample(\n                i,\n                dit_handler,\n                llm_handler,\n                format_lyrics,\n                transcribe_lyrics,\n                skip_metas,\n                progress_callback,\n            )\n\n            if \"✅\" in status:\n                success_count += 1\n            else:\n                fail_count += 1\n\n        status_msg = f\"✅ Labeled {success_count}/{total} samples\"\n        if fail_count > 0:\n            status_msg += f\" ({fail_count} failed)\"\n        if only_unlabeled:\n            status_msg += f\" (unlabeled only, {len(self.samples)} total)\"\n\n        return self.samples, status_msg\n"
  },
  {
    "path": "acestep/training/dataset_builder_modules/label_single.py",
    "content": "from typing import Optional, Tuple\n\nfrom loguru import logger\n\nfrom .label_utils import get_audio_codes, parse_int\nfrom .models import AudioSample\n\n\nclass LabelSingleMixin:\n    \"\"\"Label a single sample.\"\"\"\n\n    def label_sample(\n        self,\n        sample_idx: int,\n        dit_handler,\n        llm_handler,\n        format_lyrics: bool = False,\n        transcribe_lyrics: bool = False,\n        skip_metas: bool = False,\n        progress_callback=None,\n    ) -> Tuple[AudioSample, str]:\n        \"\"\"Label a single sample using the LLM.\"\"\"\n        if sample_idx < 0 or sample_idx >= len(self.samples):\n            return None, f\"❌ Invalid sample index: {sample_idx}\"\n\n        sample = self.samples[sample_idx]\n\n        has_preloaded_lyrics = sample.has_raw_lyrics() and not sample.is_instrumental\n        has_csv_bpm = sample.bpm is not None\n        has_csv_key = bool(sample.keyscale)\n\n        try:\n            if progress_callback:\n                progress_callback(f\"Processing: {sample.filename}\")\n\n            audio_codes = get_audio_codes(sample.audio_path, dit_handler)\n\n            if not audio_codes:\n                return sample, f\"❌ Failed to encode audio: {sample.filename}\"\n\n            if progress_callback:\n                progress_callback(f\"Generating metadata for: {sample.filename}\")\n\n            if format_lyrics and has_preloaded_lyrics:\n                from acestep.inference import format_sample\n\n                result = format_sample(\n                    llm_handler=llm_handler,\n                    caption=\"\",\n                    lyrics=sample.raw_lyrics,\n                    user_metadata=None,\n                    temperature=0.85,\n                    use_constrained_decoding=True,\n                )\n\n                if not result.success:\n                    return sample, f\"❌ LLM format failed: {result.error}\"\n\n                sample.caption = result.caption or \"\"\n                if not skip_metas:\n                    if not has_csv_bpm:\n                        sample.bpm = result.bpm\n                    if not has_csv_key:\n                        sample.keyscale = result.keyscale or \"\"\n                    sample.timesignature = result.timesignature or \"\"\n                sample.language = result.language or \"unknown\"\n                sample.formatted_lyrics = result.lyrics or \"\"\n                sample.lyrics = sample.formatted_lyrics if sample.formatted_lyrics else sample.raw_lyrics\n\n                status_suffix = \"(lyrics formatted by LM)\"\n\n            else:\n                metadata, status = llm_handler.understand_audio_from_codes(\n                    audio_codes=audio_codes,\n                    temperature=0.7,\n                    use_constrained_decoding=True,\n                )\n\n                if not metadata:\n                    return sample, f\"❌ LLM labeling failed: {status}\"\n\n                sample.caption = metadata.get(\"caption\", \"\")\n                sample.genre = metadata.get(\"genres\", \"\")\n\n                if not skip_metas:\n                    if not has_csv_bpm:\n                        sample.bpm = parse_int(metadata.get(\"bpm\"))\n                    if not has_csv_key:\n                        sample.keyscale = metadata.get(\"keyscale\", \"\")\n                    sample.timesignature = metadata.get(\"timesignature\", \"\")\n\n                sample.language = metadata.get(\"vocal_language\", \"unknown\")\n\n                llm_lyrics = metadata.get(\"lyrics\", \"\")\n\n                if sample.is_instrumental:\n                    sample.lyrics = \"[Instrumental]\"\n                    sample.language = \"unknown\"\n                    sample.formatted_lyrics = \"\"\n                    status_suffix = \"(instrumental)\"\n                elif transcribe_lyrics:\n                    sample.formatted_lyrics = llm_lyrics\n                    sample.lyrics = llm_lyrics\n                    status_suffix = \"(lyrics transcribed by LM)\"\n                elif has_preloaded_lyrics:\n                    sample.lyrics = sample.raw_lyrics\n                    sample.formatted_lyrics = \"\"\n                    status_suffix = \"(using raw lyrics)\"\n                else:\n                    sample.lyrics = llm_lyrics\n                    sample.formatted_lyrics = llm_lyrics\n                    status_suffix = \"\"\n\n            sample.labeled = True\n            self.samples[sample_idx] = sample\n\n            status_msg = f\"✅ Labeled: {sample.filename}\"\n            if skip_metas:\n                status_msg += \" (skip metas)\"\n            if status_suffix:\n                status_msg += f\" {status_suffix}\"\n\n            return sample, status_msg\n\n        except Exception as e:\n            logger.exception(f\"Error labeling sample {sample.filename}\")\n            return sample, f\"❌ Error: {str(e)}\"\n"
  },
  {
    "path": "acestep/training/dataset_builder_modules/label_utils.py",
    "content": "from typing import Any, Optional\n\nfrom loguru import logger\n\n\ndef get_audio_codes(audio_path: str, dit_handler) -> Optional[str]:\n    \"\"\"Encode audio to get semantic codes for LLM understanding.\"\"\"\n    try:\n        if not hasattr(dit_handler, \"convert_src_audio_to_codes\"):\n            logger.error(\"DiT handler missing convert_src_audio_to_codes method\")\n            return None\n\n        codes_string = dit_handler.convert_src_audio_to_codes(audio_path)\n\n        if codes_string and not codes_string.startswith(\"❌\"):\n            return codes_string\n        logger.warning(f\"Failed to convert audio to codes: {codes_string}\")\n        return None\n    except Exception:\n        logger.exception(f\"Error encoding audio {audio_path}\")\n        return None\n\n\ndef parse_int(value: Any) -> Optional[int]:\n    \"\"\"Safely parse an integer value.\"\"\"\n    if value is None or value == \"N/A\" or value == \"\":\n        return None\n    try:\n        return int(value)\n    except (ValueError, TypeError):\n        return None\n"
  },
  {
    "path": "acestep/training/dataset_builder_modules/metadata.py",
    "content": "from .models import AudioSample\n\n\nclass MetadataMixin:\n    \"\"\"Dataset-level metadata helpers.\"\"\"\n\n    def set_custom_tag(self, custom_tag: str, tag_position: str = \"prepend\"):\n        \"\"\"Set the custom tag for all samples.\"\"\"\n        self.metadata.custom_tag = custom_tag\n        self.metadata.tag_position = tag_position\n\n        for sample in self.samples:\n            sample.custom_tag = custom_tag\n\n    def set_all_instrumental(self, is_instrumental: bool):\n        \"\"\"Set instrumental flag for all samples.\"\"\"\n        self.metadata.all_instrumental = is_instrumental\n\n        for sample in self.samples:\n            if sample.has_raw_lyrics():\n                sample.is_instrumental = False\n                if not sample.lyrics or sample.lyrics == \"[Instrumental]\":\n                    sample.lyrics = sample.raw_lyrics\n            else:\n                sample.is_instrumental = is_instrumental\n                if is_instrumental:\n                    sample.lyrics = \"[Instrumental]\"\n                    sample.language = \"unknown\"\n"
  },
  {
    "path": "acestep/training/dataset_builder_modules/models.py",
    "content": "\"\"\"\nData models for dataset builder.\n\"\"\"\n\nfrom dataclasses import dataclass, asdict\nfrom datetime import datetime\nfrom typing import Any, Dict, Optional\nimport uuid\n\n\nSUPPORTED_AUDIO_FORMATS = {\".wav\", \".mp3\", \".flac\", \".ogg\", \".opus\"}\n\n\n@dataclass\nclass AudioSample:\n    \"\"\"Represents a single audio sample with its metadata.\"\"\"\n\n    id: str = \"\"\n    audio_path: str = \"\"\n    filename: str = \"\"\n    caption: str = \"\"\n    genre: str = \"\"  # Genre tags from LLM\n    lyrics: str = \"[Instrumental]\"\n    raw_lyrics: str = \"\"  # Original user-provided lyrics from .txt file\n    formatted_lyrics: str = \"\"  # LM-formatted lyrics\n    bpm: Optional[int] = None\n    keyscale: str = \"\"\n    timesignature: str = \"\"\n    duration: int = 0\n    language: str = \"unknown\"\n    is_instrumental: bool = True\n    custom_tag: str = \"\"\n    labeled: bool = False\n    prompt_override: Optional[str] = None  # None=use global ratio, \"caption\" or \"genre\"\n\n    def __post_init__(self):\n        if not self.id:\n            self.id = str(uuid.uuid4())[:8]\n\n    def to_dict(self) -> Dict[str, Any]:\n        \"\"\"Convert to dictionary.\"\"\"\n        return asdict(self)\n\n    @classmethod\n    def from_dict(cls, data: Dict[str, Any]) -> \"AudioSample\":\n        \"\"\"Create from dictionary.\n\n        Handles backward compatibility for datasets without raw_lyrics/formatted_lyrics/genre.\n        \"\"\"\n        valid_keys = {f.name for f in cls.__dataclass_fields__.values()}\n        filtered_data = {k: v for k, v in data.items() if k in valid_keys}\n        return cls(**filtered_data)\n\n    def get_full_caption(self, tag_position: str = \"prepend\") -> str:\n        \"\"\"Get caption with custom tag applied.\"\"\"\n        if not self.custom_tag:\n            return self.caption\n\n        if tag_position == \"prepend\":\n            return f\"{self.custom_tag}, {self.caption}\" if self.caption else self.custom_tag\n        if tag_position == \"append\":\n            return f\"{self.caption}, {self.custom_tag}\" if self.caption else self.custom_tag\n        if tag_position == \"replace\":\n            return self.custom_tag\n        return self.caption\n\n    def get_full_genre(self, tag_position: str = \"prepend\") -> str:\n        \"\"\"Get genre with custom tag applied.\"\"\"\n        if not self.custom_tag:\n            return self.genre\n\n        if tag_position == \"prepend\":\n            return f\"{self.custom_tag}, {self.genre}\" if self.genre else self.custom_tag\n        if tag_position == \"append\":\n            return f\"{self.genre}, {self.custom_tag}\" if self.genre else self.custom_tag\n        if tag_position == \"replace\":\n            return self.custom_tag\n        return self.genre\n\n    def get_training_prompt(self, tag_position: str = \"prepend\", use_genre: bool = False) -> str:\n        \"\"\"Get the prompt to use for training.\"\"\"\n        if self.prompt_override == \"genre\":\n            return self.get_full_genre(tag_position)\n        if self.prompt_override == \"caption\":\n            return self.get_full_caption(tag_position)\n        if use_genre:\n            return self.get_full_genre(tag_position)\n        return self.get_full_caption(tag_position)\n\n    def has_raw_lyrics(self) -> bool:\n        \"\"\"Check if sample has user-provided raw lyrics from .txt file.\"\"\"\n        return bool(self.raw_lyrics and self.raw_lyrics.strip())\n\n    def has_formatted_lyrics(self) -> bool:\n        \"\"\"Check if sample has LM-formatted lyrics.\"\"\"\n        return bool(self.formatted_lyrics and self.formatted_lyrics.strip())\n\n\n@dataclass\nclass DatasetMetadata:\n    \"\"\"Metadata for the entire dataset.\"\"\"\n\n    name: str = \"untitled_dataset\"\n    custom_tag: str = \"\"\n    tag_position: str = \"prepend\"\n    created_at: str = \"\"\n    num_samples: int = 0\n    all_instrumental: bool = True\n    genre_ratio: int = 0  # 0-100, percentage of samples using genre\n\n    def __post_init__(self):\n        if not self.created_at:\n            self.created_at = datetime.now().isoformat()\n\n    def to_dict(self) -> Dict[str, Any]:\n        \"\"\"Convert to dictionary.\"\"\"\n        return asdict(self)\n"
  },
  {
    "path": "acestep/training/dataset_builder_modules/preprocess.py",
    "content": "\"\"\"Preprocess labeled audio samples to tensor files for LoRA/LoKr training.\n\nOrchestrates VAE encoding, text encoding, lyric encoding, and the DiT\ncondition-encoder pass.  Each model phase is wrapped in the handler's\n``_load_model_context`` so that only the active model resides on the GPU\nwhen CPU offloading is enabled.  VAE encoding uses overlap-discard\ntiling to cap peak VRAM on long audio.\n\"\"\"\n\nimport os\nfrom typing import List, Tuple\n\nimport torch\nfrom loguru import logger\n\nfrom .models import AudioSample\nfrom .preprocess_audio import load_audio_stereo\nfrom .preprocess_context import build_context_latents\nfrom .preprocess_encoder import run_encoder\nfrom .preprocess_lyrics import encode_lyrics\nfrom .preprocess_manifest import save_manifest\nfrom .preprocess_text import build_text_prompt, encode_text\nfrom .preprocess_utils import select_genre_indices\nfrom .preprocess_vae import tiled_vae_encode\nfrom acestep.debug_utils import (\n    debug_log_for,\n    debug_log_verbose_for,\n    debug_start_verbose_for,\n    debug_end_verbose_for,\n)\n\n\ndef _empty_gpu_cache() -> None:\n    \"\"\"Release cached GPU memory (CUDA / MPS / XPU).\"\"\"\n    if torch.cuda.is_available():\n        torch.cuda.empty_cache()\n    if hasattr(torch, \"xpu\") and torch.xpu.is_available():\n        torch.xpu.empty_cache()\n    if hasattr(torch, \"mps\") and hasattr(torch.mps, \"empty_cache\"):\n        try:\n            torch.mps.empty_cache()\n        except Exception:\n            pass\n\n\nclass PreprocessMixin:\n    \"\"\"Preprocess labeled samples to tensor files.\"\"\"\n\n    def preprocess_to_tensors(\n        self,\n        dit_handler,\n        output_dir: str,\n        max_duration: float = 240.0,\n        preprocess_mode: str = \"lora\",\n        progress_callback=None,\n        skip_existing: bool = False,\n    ) -> Tuple[List[str], str]:\n        \"\"\"Preprocess all labeled samples to tensor files for efficient training.\n\n        Each model phase (VAE, text-encoder, DiT encoder) is wrapped in\n        ``dit_handler._load_model_context`` so that only one model is on\n        the GPU at a time when CPU offloading is active.\n\n        Args:\n            dit_handler: Initialised ``AceStepHandler`` with models loaded.\n            output_dir: Directory for output ``.pt`` files.\n            max_duration: Maximum audio duration in seconds.\n            preprocess_mode: ``\"lora\"`` or ``\"lokr\"``.\n            progress_callback: Optional ``(message) -> None`` callback.\n            skip_existing: Skip samples whose tensor file already exists.\n\n        Returns:\n            ``(output_paths, status_message)`` tuple.\n        \"\"\"\n        mode = str(preprocess_mode or \"lora\").strip().lower()\n        if mode not in {\"lora\", \"lokr\"}:\n            mode = \"lora\"\n\n        debug_log_for(\n            \"dataset\",\n            f\"preprocess_to_tensors: output_dir='{output_dir}', max_duration={max_duration}, mode={mode}\",\n        )\n        if not self.samples:\n            return [], \"❌ No samples to preprocess\"\n\n        labeled_samples = [s for s in self.samples if s.labeled]\n        if not labeled_samples:\n            return [], \"❌ No labeled samples to preprocess\"\n\n        if dit_handler is None or dit_handler.model is None:\n            return [], \"❌ Model not initialized. Please initialize the service first.\"\n\n        os.makedirs(output_dir, exist_ok=True)\n\n        output_paths: List[str] = []\n        success_count = 0\n        fail_count = 0\n\n        model = dit_handler.model\n        vae = dit_handler.vae\n        text_encoder = dit_handler.text_encoder\n        text_tokenizer = dit_handler.text_tokenizer\n        silence_latent = dit_handler.silence_latent\n        device = dit_handler.device\n        dtype = dit_handler.dtype\n\n        target_sample_rate = 48000\n\n        genre_indices = select_genre_indices(labeled_samples, self.metadata.genre_ratio)\n        debug_log_verbose_for(\"dataset\", f\"selected genre indices: count={len(genre_indices)}\")\n\n        for i, sample in enumerate(labeled_samples):\n            try:\n                debug_log_verbose_for(\"dataset\", f\"sample[{i}] id={sample.id} file={sample.filename}\")\n\n                if skip_existing:\n                    existing_path = os.path.join(output_dir, f\"{sample.id}.pt\")\n                    if os.path.isfile(existing_path):\n                        output_paths.append(existing_path)\n                        success_count += 1\n                        if progress_callback:\n                            progress_callback(f\"Skipping {i+1}/{len(labeled_samples)}: {sample.filename} (exists)\")\n                        continue\n\n                if progress_callback:\n                    progress_callback(f\"Preprocessing {i+1}/{len(labeled_samples)}: {sample.filename}\")\n\n                use_genre = i in genre_indices\n\n                # -- Load audio ------------------------------------------------\n                t0 = debug_start_verbose_for(\"dataset\", f\"load_audio_stereo[{i}]\")\n                audio, _ = load_audio_stereo(sample.audio_path, target_sample_rate, max_duration)\n                debug_end_verbose_for(\"dataset\", f\"load_audio_stereo[{i}]\", t0)\n                debug_log_verbose_for(\"dataset\", f\"audio shape={tuple(audio.shape)} dtype={audio.dtype}\")\n                audio = audio.unsqueeze(0)\n\n                # -- VAE encode (tiled, with CPU offloading) -------------------\n                with dit_handler._load_model_context(\"vae\"):\n                    vae_device = next(vae.parameters()).device\n                    audio_gpu = audio.to(vae_device).to(vae.dtype)\n                    debug_log_verbose_for(\n                        \"dataset\",\n                        f\"vae device={vae_device} vae dtype={vae.dtype} \"\n                        f\"audio device={audio_gpu.device} audio dtype={audio_gpu.dtype}\",\n                    )\n\n                    with torch.no_grad():\n                        t0 = debug_start_verbose_for(\"dataset\", f\"vae_encode[{i}]\")\n                        target_latents = tiled_vae_encode(vae, audio_gpu, dtype)\n                        debug_end_verbose_for(\"dataset\", f\"vae_encode[{i}]\", t0)\n\n                    del audio_gpu\n\n                _empty_gpu_cache()\n\n                latent_length = target_latents.shape[1]\n                attention_mask = torch.ones(1, latent_length, device=device, dtype=dtype)\n                debug_log_verbose_for(\n                    \"dataset\",\n                    f\"target_latents shape={tuple(target_latents.shape)} latent_length={latent_length}\",\n                )\n\n                # -- Text / lyric encode (with CPU offloading) -----------------\n                caption = sample.get_training_prompt(self.metadata.tag_position, use_genre=use_genre)\n                text_prompt = build_text_prompt(sample, self.metadata.tag_position, use_genre)\n\n                if i == 0:\n                    logger.info(f\"\\n{'='*70}\")\n                    logger.info(\"🔍 [DEBUG] DiT TEXT ENCODER INPUT (Training Preprocess)\")\n                    logger.info(f\"{'='*70}\")\n                    logger.info(f\"text_prompt:\\n{text_prompt}\")\n                    logger.info(f\"{'='*70}\\n\")\n\n                with dit_handler._load_model_context(\"text_encoder\"):\n                    t0 = debug_start_verbose_for(\"dataset\", f\"encode_text[{i}]\")\n                    text_hidden_states, text_attention_mask = encode_text(\n                        text_encoder, text_tokenizer, text_prompt, device, dtype\n                    )\n                    debug_end_verbose_for(\"dataset\", f\"encode_text[{i}]\", t0)\n                    debug_log_verbose_for(\n                        \"dataset\",\n                        f\"text_hidden_states shape={tuple(text_hidden_states.shape)} \"\n                        f\"text_attention_mask shape={tuple(text_attention_mask.shape)}\",\n                    )\n\n                    lyrics = sample.lyrics if sample.lyrics else \"[Instrumental]\"\n                    t0 = debug_start_verbose_for(\"dataset\", f\"encode_lyrics[{i}]\")\n                    lyric_hidden_states, lyric_attention_mask = encode_lyrics(\n                        text_encoder, text_tokenizer, lyrics, device, dtype\n                    )\n                    debug_end_verbose_for(\"dataset\", f\"encode_lyrics[{i}]\", t0)\n                    debug_log_verbose_for(\n                        \"dataset\",\n                        f\"lyric_hidden_states shape={tuple(lyric_hidden_states.shape)} \"\n                        f\"lyric_attention_mask shape={tuple(lyric_attention_mask.shape)}\",\n                    )\n\n                _empty_gpu_cache()\n\n                # -- DiT condition encoder (with CPU offloading) ---------------\n                t0 = debug_start_verbose_for(\"dataset\", f\"run_encoder[{i}]\")\n                # Ensure DiT encoder runs on the active residency device (GPU when loaded via\n                # offload context). This prevents flash-attn CPU backend crashes.\n                with dit_handler._load_model_context(\"model\"):\n                    model_device = next(model.parameters()).device\n                    model_dtype = next(model.parameters()).dtype\n                    if text_hidden_states.device != model_device:\n                        text_hidden_states = text_hidden_states.to(model_device)\n                    if text_attention_mask.device != model_device:\n                        text_attention_mask = text_attention_mask.to(model_device)\n                    if lyric_hidden_states.device != model_device:\n                        lyric_hidden_states = lyric_hidden_states.to(model_device)\n                    if lyric_attention_mask.device != model_device:\n                        lyric_attention_mask = lyric_attention_mask.to(model_device)\n                    if text_hidden_states.dtype != model_dtype:\n                        text_hidden_states = text_hidden_states.to(model_dtype)\n                    if lyric_hidden_states.dtype != model_dtype:\n                        lyric_hidden_states = lyric_hidden_states.to(model_dtype)\n\n                    refer_audio_hidden = None\n                    refer_audio_order_mask_val = None\n                    if mode == \"lokr\":\n                        # LoKr mode uses per-sample audio latents as reference-audio conditioning.\n                        refer_audio_hidden = target_latents.to(device=model_device, dtype=model_dtype)\n                        refer_audio_order_mask_val = torch.zeros(\n                            refer_audio_hidden.shape[0],\n                            device=model_device,\n                            dtype=torch.long,\n                        )\n\n                    encoder_hidden_states, encoder_attention_mask = run_encoder(\n                        model,\n                        text_hidden_states=text_hidden_states,\n                        text_attention_mask=text_attention_mask,\n                        lyric_hidden_states=lyric_hidden_states,\n                        lyric_attention_mask=lyric_attention_mask,\n                        device=model_device,\n                        dtype=model_dtype,\n                        refer_audio_hidden_states_packed=refer_audio_hidden,\n                        refer_audio_order_mask=refer_audio_order_mask_val,\n                    )\n                debug_end_verbose_for(\"dataset\", f\"run_encoder[{i}]\", t0)\n                debug_log_verbose_for(\n                    \"dataset\",\n                    f\"encoder_hidden_states shape={tuple(encoder_hidden_states.shape)} \"\n                    f\"encoder_attention_mask shape={tuple(encoder_attention_mask.shape)}\",\n                )\n\n                _empty_gpu_cache()\n\n                t0 = debug_start_verbose_for(\"dataset\", f\"build_context_latents[{i}]\")\n                context_src = target_latents if mode == \"lokr\" else None\n                context_latents = build_context_latents(\n                    silence_latent,\n                    latent_length,\n                    device,\n                    dtype,\n                    src_latents=context_src,\n                )\n                debug_end_verbose_for(\"dataset\", f\"build_context_latents[{i}]\", t0)\n\n                output_data = {\n                    \"target_latents\": target_latents.squeeze(0).cpu(),\n                    \"attention_mask\": attention_mask.squeeze(0).cpu(),\n                    \"encoder_hidden_states\": encoder_hidden_states.squeeze(0).cpu(),\n                    \"encoder_attention_mask\": encoder_attention_mask.squeeze(0).cpu(),\n                    \"context_latents\": context_latents.squeeze(0).cpu(),\n                    \"metadata\": {\n                        \"audio_path\": sample.audio_path,\n                        \"filename\": sample.filename,\n                        \"caption\": caption,\n                        \"lyrics\": lyrics,\n                        \"duration\": sample.duration,\n                        \"bpm\": sample.bpm,\n                        \"keyscale\": sample.keyscale,\n                        \"timesignature\": sample.timesignature,\n                        \"language\": sample.language,\n                        \"is_instrumental\": sample.is_instrumental,\n                        \"preprocess_mode\": mode,\n                    },\n                }\n\n                output_path = os.path.join(output_dir, f\"{sample.id}.pt\")\n                t0 = debug_start_verbose_for(\"dataset\", f\"torch.save[{i}]\")\n                torch.save(output_data, output_path)\n                debug_end_verbose_for(\"dataset\", f\"torch.save[{i}]\", t0)\n                output_paths.append(output_path)\n                success_count += 1\n\n            except Exception as e:\n                logger.exception(f\"Error preprocessing {sample.filename}\")\n                fail_count += 1\n                if progress_callback:\n                    progress_callback(f\"❌ Failed: {sample.filename}: {str(e)}\")\n\n        t0 = debug_start_verbose_for(\"dataset\", \"save_manifest\")\n        save_manifest(output_dir, self.metadata, output_paths)\n        debug_end_verbose_for(\"dataset\", \"save_manifest\", t0)\n\n        status = f\"✅ Preprocessed {success_count}/{len(labeled_samples)} samples to {output_dir}\"\n        if fail_count > 0:\n            status += f\" ({fail_count} failed)\"\n\n        return output_paths, status\n"
  },
  {
    "path": "acestep/training/dataset_builder_modules/preprocess_audio.py",
    "content": "import torchaudio\n\n\ndef load_audio_stereo(audio_path: str, target_sample_rate: int, max_duration: float):\n    \"\"\"Load audio, resample, convert to stereo, and truncate.\"\"\"\n    audio, sr = torchaudio.load(audio_path)\n\n    if sr != target_sample_rate:\n        resampler = torchaudio.transforms.Resample(sr, target_sample_rate)\n        audio = resampler(audio)\n\n    if audio.shape[0] == 1:\n        audio = audio.repeat(2, 1)\n    elif audio.shape[0] > 2:\n        audio = audio[:2, :]\n\n    max_samples = int(max_duration * target_sample_rate)\n    if audio.shape[1] > max_samples:\n        audio = audio[:, :max_samples]\n\n    return audio, sr\n"
  },
  {
    "path": "acestep/training/dataset_builder_modules/preprocess_context.py",
    "content": "import torch\n\n\ndef build_context_latents(\n    silence_latent,\n    latent_length: int,\n    device,\n    dtype,\n    src_latents: torch.Tensor = None,\n):\n    \"\"\"Build context latents for text2music.\"\"\"\n    if src_latents is None:\n        src_latents = silence_latent[:, :latent_length, :].to(dtype)\n    else:\n        if src_latents.dim() == 2:\n            src_latents = src_latents.unsqueeze(0)\n        src_latents = src_latents.to(device=device, dtype=dtype)\n    if src_latents.shape[0] < 1:\n        src_latents = src_latents.expand(1, -1, -1)\n\n    if src_latents.shape[1] < latent_length:\n        pad_len = latent_length - src_latents.shape[1]\n        src_latents = torch.cat(\n            [\n                src_latents,\n                silence_latent[:, :pad_len, :].expand(1, -1, -1).to(dtype),\n            ],\n            dim=1,\n        )\n    elif src_latents.shape[1] > latent_length:\n        src_latents = src_latents[:, :latent_length, :]\n\n    chunk_masks = torch.ones(1, latent_length, 64, device=device, dtype=dtype)\n    context_latents = torch.cat([src_latents, chunk_masks], dim=-1)\n    return context_latents\n"
  },
  {
    "path": "acestep/training/dataset_builder_modules/preprocess_encoder.py",
    "content": "import torch\n\n\ndef run_encoder(\n    model,\n    text_hidden_states,\n    text_attention_mask,\n    lyric_hidden_states,\n    lyric_attention_mask,\n    device,\n    dtype,\n    refer_audio_hidden_states_packed=None,\n    refer_audio_order_mask=None,\n):\n    \"\"\"Run model encoder to get hidden states and attention mask.\"\"\"\n    if refer_audio_hidden_states_packed is None:\n        refer_audio_hidden = torch.zeros(1, 1, 64, device=device, dtype=dtype)\n    else:\n        refer_audio_hidden = refer_audio_hidden_states_packed\n        if refer_audio_hidden.dim() == 2:\n            refer_audio_hidden = refer_audio_hidden.unsqueeze(0)\n        refer_audio_hidden = refer_audio_hidden.to(device=device, dtype=dtype)\n\n    if refer_audio_order_mask is None:\n        refer_audio_order_mask = torch.zeros(\n            refer_audio_hidden.shape[0],\n            device=device,\n            dtype=torch.long,\n        )\n    else:\n        refer_audio_order_mask = refer_audio_order_mask.to(device=device, dtype=torch.long)\n\n    with torch.no_grad():\n        encoder_hidden_states, encoder_attention_mask = model.encoder(\n            text_hidden_states=text_hidden_states,\n            text_attention_mask=text_attention_mask,\n            lyric_hidden_states=lyric_hidden_states,\n            lyric_attention_mask=lyric_attention_mask,\n            refer_audio_acoustic_hidden_states_packed=refer_audio_hidden,\n            refer_audio_order_mask=refer_audio_order_mask,\n        )\n\n    return encoder_hidden_states, encoder_attention_mask\n"
  },
  {
    "path": "acestep/training/dataset_builder_modules/preprocess_lyrics.py",
    "content": "import torch\n\n\ndef encode_lyrics(text_encoder, text_tokenizer, lyrics: str, device, dtype):\n    \"\"\"Encode lyrics into hidden states.\"\"\"\n    lyric_inputs = text_tokenizer(\n        lyrics,\n        padding=\"max_length\",\n        max_length=512,\n        truncation=True,\n        return_tensors=\"pt\",\n    )\n    lyric_input_ids = lyric_inputs.input_ids.to(device)\n    lyric_attention_mask = lyric_inputs.attention_mask.to(device).to(dtype)\n\n    # Align tensor residency to the actual text encoder device to avoid\n    # CPU/CUDA mismatch in embedding/index_select calls.\n    text_dev = next(text_encoder.parameters()).device\n    if lyric_input_ids.device != text_dev:\n        lyric_input_ids = lyric_input_ids.to(text_dev)\n        lyric_attention_mask = lyric_attention_mask.to(text_dev)\n\n    with torch.no_grad():\n        lyric_hidden_states = text_encoder.embed_tokens(lyric_input_ids).to(dtype)\n\n    return lyric_hidden_states, lyric_attention_mask\n"
  },
  {
    "path": "acestep/training/dataset_builder_modules/preprocess_manifest.py",
    "content": "import json\nimport os\nfrom typing import List\n\n\ndef save_manifest(output_dir: str, metadata, output_paths: List[str]) -> str:\n    \"\"\"Save manifest.json listing all preprocessed samples.\n\n    Paths are stored **relative to output_dir** (typically just filenames)\n    so that ``PreprocessedTensorDataset`` can resolve them correctly via\n    ``safe_path(rel, base=tensor_dir)``.\n\n    Args:\n        output_dir: Directory where the manifest and .pt files live.\n        metadata: Dataset metadata object with a ``to_dict`` method.\n        output_paths: Absolute or CWD-relative paths to .pt files.\n\n    Returns:\n        Path to the written manifest.json.\n    \"\"\"\n    abs_output_dir = os.path.abspath(output_dir)\n    relative_paths = [\n        os.path.relpath(os.path.abspath(p), abs_output_dir)\n        for p in output_paths\n    ]\n    manifest = {\n        \"metadata\": metadata.to_dict(),\n        \"samples\": relative_paths,\n        \"num_samples\": len(relative_paths),\n    }\n    manifest_path = os.path.join(output_dir, \"manifest.json\")\n    with open(manifest_path, \"w\", encoding=\"utf-8\") as f:\n        json.dump(manifest, f, indent=2)\n    return manifest_path\n"
  },
  {
    "path": "acestep/training/dataset_builder_modules/preprocess_text.py",
    "content": "import torch\n\nfrom acestep.constants import DEFAULT_DIT_INSTRUCTION, SFT_GEN_PROMPT\n\nfrom .models import AudioSample\nfrom .preprocess_utils import build_metas_str\n\n\ndef build_text_prompt(sample: AudioSample, tag_position: str, use_genre: bool) -> str:\n    \"\"\"Build the text prompt for the text encoder.\"\"\"\n    caption = sample.get_training_prompt(tag_position, use_genre=use_genre)\n    metas_str = build_metas_str(sample)\n    return SFT_GEN_PROMPT.format(DEFAULT_DIT_INSTRUCTION, caption, metas_str)\n\n\ndef encode_text(text_encoder, text_tokenizer, text_prompt: str, device, dtype):\n    \"\"\"Encode caption/genre prompt into text hidden states.\"\"\"\n    text_inputs = text_tokenizer(\n        text_prompt,\n        padding=\"max_length\",\n        max_length=256,\n        truncation=True,\n        return_tensors=\"pt\",\n    )\n    text_input_ids = text_inputs.input_ids.to(device)\n    text_attention_mask = text_inputs.attention_mask.to(device).to(dtype)\n\n    text_dev = next(text_encoder.parameters()).device\n    if text_input_ids.device != text_dev:\n        text_input_ids = text_input_ids.to(text_dev)\n        text_attention_mask = text_attention_mask.to(text_dev)\n\n    with torch.no_grad():\n        text_outputs = text_encoder(text_input_ids)\n        text_hidden_states = text_outputs.last_hidden_state.to(dtype)\n\n    return text_hidden_states, text_attention_mask\n"
  },
  {
    "path": "acestep/training/dataset_builder_modules/preprocess_utils.py",
    "content": "import random\nfrom typing import List, Set\n\nfrom .models import AudioSample\n\n\ndef select_genre_indices(samples: List[AudioSample], genre_ratio: int) -> Set[int]:\n    \"\"\"Select indices that should use genre, based on ratio.\"\"\"\n    num_genre_samples = int(len(samples) * genre_ratio / 100)\n    random.seed(42)\n    all_indices = list(range(len(samples)))\n    random.shuffle(all_indices)\n    return set(all_indices[:num_genre_samples])\n\n\ndef build_metas_str(sample: AudioSample) -> str:\n    \"\"\"Construct metadata string for text prompt.\"\"\"\n    return (\n        f\"- bpm: {sample.bpm if sample.bpm else 'N/A'}\\n\"\n        f\"- timesignature: {sample.timesignature if sample.timesignature else 'N/A'}\\n\"\n        f\"- keyscale: {sample.keyscale if sample.keyscale else 'N/A'}\\n\"\n        f\"- duration: {sample.duration} seconds\\n\"\n    )\n"
  },
  {
    "path": "acestep/training/dataset_builder_modules/preprocess_vae.py",
    "content": "\"\"\"VAE encoding helpers for training preprocessing.\n\nProvides both a simple one-shot ``vae_encode`` (kept for backward\ncompatibility) and a tiled variant ``tiled_vae_encode`` that processes\nlong audio in overlapping chunks to cap peak VRAM usage.\n\"\"\"\n\nimport math\nfrom typing import Optional\n\nimport torch\n\n\n# Target sample rate for ACE-Step models (used for chunk-size heuristics)\n_TARGET_SR = 48000\n\n\ndef vae_encode(vae, audio, dtype):\n    \"\"\"VAE encode audio to get target latents (one-shot, no tiling).\n\n    For long audio this may OOM on low-VRAM GPUs.  Prefer\n    :func:`tiled_vae_encode` when peak memory is a concern.\n\n    Args:\n        vae: ``AutoencoderOobleck`` model (on device, eval mode).\n        audio: ``[B, C, S]`` audio tensor.\n        dtype: Target dtype for the output latents.\n\n    Returns:\n        Latent tensor ``[B, T, 64]``.\n    \"\"\"\n    model_device = next(vae.parameters()).device\n    if audio.device != model_device:\n        audio = audio.to(model_device)\n\n    latent = vae.encode(audio).latent_dist.sample()\n    target_latents = latent.transpose(1, 2).to(dtype)\n    return target_latents\n\n\ndef tiled_vae_encode(\n    vae,\n    audio: torch.Tensor,\n    dtype: torch.dtype,\n    chunk_size: Optional[int] = None,\n    overlap: int = 96000,\n) -> torch.Tensor:\n    \"\"\"Encode audio through the VAE using overlap-discard tiling.\n\n    Processes long audio in chunks to avoid OOM on the monolithic\n    ``vae.encode()`` call.  Short audio (shorter than *chunk_size*) is\n    encoded directly without tiling overhead.\n\n    Args:\n        vae: ``AutoencoderOobleck`` VAE model (on device, eval mode).\n        audio: Audio tensor ``[B, C, S]`` (batch, channels, samples).\n        dtype: Target dtype for the output latents.\n        chunk_size: Audio samples per chunk.  ``None`` = auto-select\n            based on available GPU memory (30 s for >=8 GB, 15 s\n            otherwise).\n        overlap: Overlap in audio samples between adjacent chunks\n            (default 2 s at 48 kHz = 96 000).\n\n    Returns:\n        Latent tensor ``[B, T, 64]``, cast to *dtype*.\n    \"\"\"\n    vae_device = next(vae.parameters()).device\n    vae_dtype = vae.dtype\n\n    # Auto-select chunk size based on GPU VRAM\n    if chunk_size is None:\n        gpu_mem_gb = 0.0\n        if torch.cuda.is_available():\n            try:\n                props = torch.cuda.get_device_properties(vae_device)\n                gpu_mem_gb = props.total_mem / (1024 ** 3)\n            except Exception:\n                pass\n        chunk_size = _TARGET_SR * 15 if gpu_mem_gb <= 8 else _TARGET_SR * 30\n\n    B, C, S = audio.shape\n\n    # Short audio -- direct encode (no tiling needed)\n    if S <= chunk_size:\n        vae_input = audio.to(vae_device, dtype=vae_dtype)\n        with torch.inference_mode():\n            latents = vae.encode(vae_input).latent_dist.sample()\n        return latents.transpose(1, 2).to(dtype)\n\n    # Calculate stride (core region per chunk, excluding overlap)\n    stride = chunk_size - 2 * overlap\n    if stride <= 0:\n        raise ValueError(\n            f\"chunk_size ({chunk_size}) must be > 2 * overlap ({overlap})\"\n        )\n\n    num_steps = math.ceil(S / stride)\n    downsample_factor: Optional[float] = None\n    latent_write_pos = 0\n    final_latents: Optional[torch.Tensor] = None\n\n    for i in range(num_steps):\n        core_start = i * stride\n        core_end = min(core_start + stride, S)\n\n        # Window with overlap on both sides\n        win_start = max(0, core_start - overlap)\n        win_end = min(S, core_end + overlap)\n\n        chunk = audio[:, :, win_start:win_end].to(vae_device, dtype=vae_dtype)\n\n        with torch.inference_mode():\n            latent_chunk = vae.encode(chunk).latent_dist.sample()\n\n        # Determine downsample factor from the first chunk\n        if downsample_factor is None:\n            downsample_factor = chunk.shape[-1] / latent_chunk.shape[-1]\n            total_latent_len = int(round(S / downsample_factor))\n            final_latents = torch.zeros(\n                B, latent_chunk.shape[1], total_latent_len,\n                dtype=latent_chunk.dtype, device=\"cpu\",\n            )\n\n        # Trim the overlap regions from the latent\n        added_start = core_start - win_start\n        trim_start = int(round(added_start / downsample_factor))\n\n        added_end = win_end - core_end\n        trim_end = int(round(added_end / downsample_factor))\n\n        lat_len = latent_chunk.shape[-1]\n        end_idx = lat_len - trim_end if trim_end > 0 else lat_len\n        latent_core = latent_chunk[:, :, trim_start:end_idx]\n\n        # Copy to pre-allocated CPU tensor\n        core_len = latent_core.shape[-1]\n        assert final_latents is not None\n        final_latents[:, :, latent_write_pos:latent_write_pos + core_len] = (\n            latent_core.cpu()\n        )\n        latent_write_pos += core_len\n\n        del chunk, latent_chunk, latent_core\n\n    # Trim to actual written length\n    assert final_latents is not None\n    final_latents = final_latents[:, :, :latent_write_pos]\n\n    # Transpose to (B, T, 64) and cast -- matches vae_encode output format\n    return final_latents.transpose(1, 2).to(dtype)\n"
  },
  {
    "path": "acestep/training/dataset_builder_modules/scan.py",
    "content": "import os\nfrom typing import List, Tuple\n\nfrom loguru import logger\n\nfrom acestep.training.path_safety import safe_path\nfrom .audio_io import get_audio_duration, load_caption_file, load_json_metadata, load_lyrics_file\nfrom .csv_metadata import load_csv_metadata\nfrom .models import AudioSample, SUPPORTED_AUDIO_FORMATS\n\n\nclass ScanMixin:\n    \"\"\"Directory scanning helpers.\"\"\"\n\n    def scan_directory(self, directory: str) -> Tuple[List[AudioSample], str]:\n        \"\"\"Scan a directory for audio files.\"\"\"\n        try:\n            directory = safe_path(directory)\n        except ValueError:\n            return [], f\"❌ Rejected unsafe directory path: {directory}\"\n\n        if not os.path.exists(directory):\n            return [], f\"❌ Directory not found: {directory}\"\n\n        if not os.path.isdir(directory):\n            return [], f\"❌ Not a directory: {directory}\"\n\n        self._current_dir = directory\n        self.samples = []\n\n        audio_files = []\n        for root, _, files in os.walk(directory):\n            for file in files:\n                ext = os.path.splitext(file)[1].lower()\n                if ext in SUPPORTED_AUDIO_FORMATS:\n                    audio_files.append(os.path.join(root, file))\n\n        if not audio_files:\n            return [], (\n                f\"❌ No audio files found in {directory}\\n\"\n                f\"Supported formats: {', '.join(SUPPORTED_AUDIO_FORMATS)}\"\n            )\n\n        audio_files.sort()\n\n        csv_metadata = load_csv_metadata(directory)\n        csv_count = 0\n        json_count = 0\n        caption_count = 0\n        lyrics_count = 0\n\n        for audio_path in audio_files:\n            try:\n                duration = get_audio_duration(audio_path)\n                caption_content, has_caption_file = load_caption_file(audio_path)\n                lyrics_content, has_lyrics_file = load_lyrics_file(audio_path)\n                json_meta, has_json = load_json_metadata(audio_path)\n\n                if has_caption_file:\n                    caption_count += 1\n                if has_lyrics_file:\n                    lyrics_count += 1\n                if has_json:\n                    json_count += 1\n\n                is_instrumental = self.metadata.all_instrumental\n                if has_lyrics_file:\n                    is_instrumental = False\n\n                sample = AudioSample(\n                    audio_path=audio_path,\n                    filename=os.path.basename(audio_path),\n                    duration=duration,\n                    is_instrumental=is_instrumental,\n                    custom_tag=self.metadata.custom_tag,\n                    caption=caption_content if has_caption_file else \"\",\n                    lyrics=lyrics_content if has_lyrics_file else \"[Instrumental]\",\n                    raw_lyrics=lyrics_content if has_lyrics_file else \"\",\n                )\n                if has_caption_file:\n                    sample.labeled = True\n\n                # Apply JSON metadata (overrides caption file if present)\n                if has_json:\n                    if json_meta.get(\"caption\"):\n                        sample.caption = json_meta[\"caption\"]\n                        sample.labeled = True\n                    if json_meta.get(\"bpm\"):\n                        sample.bpm = json_meta[\"bpm\"]\n                    if json_meta.get(\"keyscale\"):\n                        sample.keyscale = json_meta[\"keyscale\"]\n                    if json_meta.get(\"timesignature\"):\n                        sample.timesignature = json_meta[\"timesignature\"]\n                    if json_meta.get(\"language\"):\n                        sample.language = json_meta[\"language\"]\n                        if sample.language != \"instrumental\":\n                            sample.is_instrumental = False\n\n                if csv_metadata and sample.filename in csv_metadata:\n                    meta = csv_metadata[sample.filename]\n                    if meta.get(\"bpm\"):\n                        sample.bpm = meta[\"bpm\"]\n                    if meta.get(\"key\"):\n                        sample.keyscale = meta[\"key\"]\n                    if meta.get(\"caption\"):\n                        sample.caption = meta[\"caption\"]\n                        sample.labeled = True\n                    csv_count += 1\n\n                self.samples.append(sample)\n            except Exception as e:\n                logger.warning(f\"Failed to process {audio_path}: {e}\")\n\n        self.metadata.num_samples = len(self.samples)\n\n        status = f\"✅ Found {len(self.samples)} audio files in {directory}\"\n        if json_count > 0:\n            status += f\"\\n   📄 Detected {json_count} JSON metadata (.json)\"\n        if caption_count > 0:\n            status += f\"\\n   📋 Detected {caption_count} captions (.caption.txt)\"\n        if lyrics_count > 0:\n            status += f\"\\n   📝 Detected {lyrics_count} lyrics (.lyrics.txt / .txt)\"\n        if csv_count > 0:\n            status += f\"\\n   📊 {csv_count} files have metadata from CSV\"\n\n        return self.samples, status\n"
  },
  {
    "path": "acestep/training/dataset_builder_modules/serialization.py",
    "content": "import json\nimport os\nfrom datetime import datetime\nfrom typing import List, Tuple\n\nfrom loguru import logger\n\nfrom acestep.training.path_safety import safe_path\nfrom .models import AudioSample, DatasetMetadata\n\n\nclass SerializationMixin:\n    \"\"\"Save/load dataset JSON.\"\"\"\n\n    def save_dataset(self, output_path: str, dataset_name: str = None) -> str:\n        \"\"\"Save the dataset to a JSON file.\"\"\"\n        if not self.samples:\n            return \"❌ No samples to save\"\n\n        if dataset_name:\n            self.metadata.name = dataset_name\n\n        self.metadata.num_samples = len(self.samples)\n        self.metadata.created_at = datetime.now().isoformat()\n\n        dataset = {\n            \"metadata\": self.metadata.to_dict(),\n            \"samples\": [sample.to_dict() for sample in self.samples],\n        }\n\n        try:\n            validated_output = safe_path(output_path)\n            parent = os.path.dirname(validated_output)\n            os.makedirs(parent if parent else \".\", exist_ok=True)\n\n            with open(validated_output, \"w\", encoding=\"utf-8\") as f:\n                json.dump(dataset, f, indent=2, ensure_ascii=False)\n\n            return f\"✅ Dataset saved to {validated_output}\\n{len(self.samples)} samples, tag: '{self.metadata.custom_tag}'\"\n        except Exception as e:\n            logger.exception(\"Error saving dataset\")\n            return f\"❌ Failed to save dataset: {str(e)}\"\n\n    def load_dataset(self, dataset_path: str) -> Tuple[List[AudioSample], str]:\n        \"\"\"Load a dataset from a JSON file.\"\"\"\n        try:\n            validated_path = safe_path(dataset_path)\n        except ValueError:\n            return [], f\"❌ Rejected unsafe dataset path: {dataset_path}\"\n\n        if not os.path.exists(validated_path):\n            return [], f\"❌ Dataset not found: {dataset_path}\"\n\n        try:\n            with open(validated_path, \"r\", encoding=\"utf-8\") as f:\n                data = json.load(f)\n\n            if \"metadata\" in data:\n                meta_dict = data[\"metadata\"]\n                self.metadata = DatasetMetadata(\n                    name=meta_dict.get(\"name\", \"untitled\"),\n                    custom_tag=meta_dict.get(\"custom_tag\", \"\"),\n                    tag_position=meta_dict.get(\"tag_position\", \"prepend\"),\n                    created_at=meta_dict.get(\"created_at\", \"\"),\n                    num_samples=meta_dict.get(\"num_samples\", 0),\n                    all_instrumental=meta_dict.get(\"all_instrumental\", True),\n                    genre_ratio=meta_dict.get(\"genre_ratio\", 0),\n                )\n\n            self.samples = []\n            for sample_dict in data.get(\"samples\", []):\n                sample = AudioSample.from_dict(sample_dict)\n                self.samples.append(sample)\n\n            return self.samples, f\"✅ Loaded {len(self.samples)} samples from {dataset_path}\"\n        except Exception as e:\n            logger.exception(\"Error loading dataset\")\n            return [], f\"❌ Failed to load dataset: {str(e)}\"\n"
  },
  {
    "path": "acestep/training/dataset_builder_modules/update_sample.py",
    "content": "from typing import Tuple\n\nfrom .models import AudioSample\n\n\nclass UpdateSampleMixin:\n    \"\"\"Sample update helpers.\"\"\"\n\n    def update_sample(self, sample_idx: int, **kwargs) -> Tuple[AudioSample, str]:\n        \"\"\"Update a sample's metadata.\"\"\"\n        if sample_idx < 0 or sample_idx >= len(self.samples):\n            return None, f\"❌ Invalid sample index: {sample_idx}\"\n\n        sample = self.samples[sample_idx]\n\n        for key, value in kwargs.items():\n            if hasattr(sample, key):\n                setattr(sample, key, value)\n\n        self.samples[sample_idx] = sample\n        return sample, f\"✅ Updated: {sample.filename}\"\n"
  },
  {
    "path": "acestep/training/lokr_utils.py",
    "content": "\"\"\"\nLoKr utilities for ACE-Step training and inference.\n\nThis module integrates LyCORIS LoKr adapters with the ACE-Step decoder.\n\"\"\"\n\nimport json\nimport os\nfrom typing import Any, Dict, Optional, Tuple\n\nimport torch\nfrom loguru import logger\n\nfrom acestep.training.configs import LoKRConfig\nfrom acestep.training.path_safety import safe_path\n\ntry:\n    from lycoris import LycorisNetwork, create_lycoris\n\n    LYCORIS_AVAILABLE = True\nexcept ImportError:\n    LYCORIS_AVAILABLE = False\n    LycorisNetwork = Any  # type: ignore[assignment,misc]\n    logger.warning(\n        \"LyCORIS library not installed. LoKr training/inference unavailable. \"\n        \"Install with: pip install lycoris-lora\"\n    )\n\n\ndef check_lycoris_available() -> bool:\n    \"\"\"Check if LyCORIS is importable.\"\"\"\n    return LYCORIS_AVAILABLE\n\n\ndef _matches_target_module_name(module_name: str, target_modules) -> bool:\n    \"\"\"Return True if a LyCORIS module name maps to one of target module suffixes.\"\"\"\n    if not module_name:\n        return False\n    name = module_name.lower()\n    for target in target_modules or []:\n        t = str(target).strip().lower()\n        if not t:\n            continue\n        if name.endswith(t) or f\"_{t}\" in name or f\".{t}\" in name:\n            return True\n    return False\n\n\ndef inject_lokr_into_dit(\n    model,\n    lokr_config: LoKRConfig,\n    multiplier: float = 1.0,\n) -> Tuple[Any, \"LycorisNetwork\", Dict[str, Any]]:\n    \"\"\"\n    Inject LoKr adapters into the decoder.\n\n    Returns:\n        Tuple: (model, lycoris_network, info_dict)\n    \"\"\"\n    if not LYCORIS_AVAILABLE:\n        raise ImportError(\n            \"LyCORIS library is required for LoKr training. \"\n            \"Install with: pip install lycoris-lora\"\n        )\n\n    decoder = model.decoder\n\n    # Freeze all existing params before creating adapter params.\n    for _, param in model.named_parameters():\n        param.requires_grad = False\n\n    LycorisNetwork.apply_preset(\n        {\n            \"unet_target_name\": lokr_config.target_modules,\n            \"target_name\": lokr_config.target_modules,\n        }\n    )\n\n    lycoris_net = create_lycoris(\n        decoder,\n        multiplier,\n        linear_dim=lokr_config.linear_dim,\n        linear_alpha=lokr_config.linear_alpha,\n        algo=\"lokr\",\n        factor=lokr_config.factor,\n        decompose_both=lokr_config.decompose_both,\n        use_tucker=lokr_config.use_tucker,\n        use_scalar=lokr_config.use_scalar,\n        full_matrix=lokr_config.full_matrix,\n        bypass_mode=lokr_config.bypass_mode,\n        rs_lora=lokr_config.rs_lora,\n        unbalanced_factorization=lokr_config.unbalanced_factorization,\n    )\n\n    if lokr_config.weight_decompose:\n        try:\n            lycoris_net = create_lycoris(\n                decoder,\n                multiplier,\n                linear_dim=lokr_config.linear_dim,\n                linear_alpha=lokr_config.linear_alpha,\n                algo=\"lokr\",\n                factor=lokr_config.factor,\n                decompose_both=lokr_config.decompose_both,\n                use_tucker=lokr_config.use_tucker,\n                use_scalar=lokr_config.use_scalar,\n                full_matrix=lokr_config.full_matrix,\n                bypass_mode=lokr_config.bypass_mode,\n                rs_lora=lokr_config.rs_lora,\n                unbalanced_factorization=lokr_config.unbalanced_factorization,\n                dora_wd=True,\n            )\n        except Exception as exc:\n            logger.warning(f\"DoRA mode not supported in current LyCORIS build: {exc}\")\n\n    lycoris_net.apply_to()\n\n    # Keep a reference on decoder so it stays discoverable after wrappers.\n    # Always refresh this reference to avoid stale nets from earlier runs.\n    decoder._lycoris_net = lycoris_net\n\n    lokr_param_list = []\n    enabled_module_count = 0\n    disabled_module_count = 0\n    disabled_examples = []\n\n    for idx, module in enumerate(getattr(lycoris_net, \"loras\", []) or []):\n        module_name = (\n            getattr(module, \"lora_name\", None)\n            or getattr(module, \"name\", None)\n            or f\"{module.__class__.__name__}#{idx}\"\n        )\n        enabled = _matches_target_module_name(module_name, lokr_config.target_modules)\n\n        if enabled:\n            enabled_module_count += 1\n        else:\n            disabled_module_count += 1\n            if len(disabled_examples) < 8:\n                disabled_examples.append(module_name)\n\n        for param in module.parameters():\n            param.requires_grad = enabled\n            if enabled:\n                lokr_param_list.append(param)\n\n    logger.info(\n        f\"LoKr target filter: enabled {enabled_module_count} LyCORIS modules \"\n        f\"(disabled {disabled_module_count}) for targets={lokr_config.target_modules}\"\n    )\n    if disabled_examples:\n        logger.info(\"LoKr disabled non-target modules (sample): \" + \", \".join(disabled_examples))\n\n    if not lokr_param_list:\n        for param in lycoris_net.parameters():\n            param.requires_grad = True\n            lokr_param_list.append(param)\n\n    # De-duplicate possible shared params.\n    unique_params = {id(p): p for p in lokr_param_list}\n    total_params = sum(p.numel() for p in model.parameters())\n    lokr_params = sum(p.numel() for p in unique_params.values())\n    trainable_params = sum(p.numel() for p in unique_params.values() if p.requires_grad)\n\n    info = {\n        \"total_params\": total_params,\n        \"lokr_params\": lokr_params,\n        \"trainable_params\": trainable_params,\n        \"trainable_ratio\": trainable_params / total_params if total_params > 0 else 0.0,\n        \"linear_dim\": lokr_config.linear_dim,\n        \"linear_alpha\": lokr_config.linear_alpha,\n        \"factor\": lokr_config.factor,\n        \"algo\": \"lokr\",\n        \"target_modules\": lokr_config.target_modules,\n    }\n\n    logger.info(\"LoKr injected into decoder\")\n    logger.info(\n        f\"LoKr trainable params: {trainable_params:,}/{total_params:,} \"\n        f\"({info['trainable_ratio']:.2%})\"\n    )\n    return model, lycoris_net, info\n\n\ndef save_lokr_weights(\n    lycoris_net: \"LycorisNetwork\",\n    output_dir: str,\n    dtype: Optional[torch.dtype] = None,\n    metadata: Optional[Dict[str, str]] = None,\n) -> str:\n    \"\"\"Save LoKr weights to safetensors.\"\"\"\n    output_dir = safe_path(output_dir)\n    os.makedirs(output_dir, exist_ok=True)\n    weights_path = os.path.join(output_dir, \"lokr_weights.safetensors\")\n\n    save_metadata: Dict[str, str] = {\"algo\": \"lokr\", \"format\": \"lycoris\"}\n    if metadata:\n        for key, value in metadata.items():\n            if value is None:\n                continue\n            if isinstance(value, str):\n                save_metadata[key] = value\n            else:\n                save_metadata[key] = json.dumps(value, ensure_ascii=True)\n\n    lycoris_net.save_weights(weights_path, dtype=dtype, metadata=save_metadata)\n    logger.info(f\"LoKr weights saved to {weights_path}\")\n    return weights_path\n\n\ndef load_lokr_weights(lycoris_net: \"LycorisNetwork\", weights_path: str) -> Dict[str, Any]:\n    \"\"\"Load LoKr weights into an injected LyCORIS network.\"\"\"\n    weights_path = safe_path(weights_path)\n    if not os.path.exists(weights_path):\n        raise FileNotFoundError(f\"LoKr weights not found: {weights_path}\")\n    result = lycoris_net.load_weights(weights_path)\n    logger.info(f\"LoKr weights loaded from {weights_path}\")\n    return result\n\n\ndef save_lokr_training_checkpoint(\n    lycoris_net: \"LycorisNetwork\",\n    optimizer,\n    scheduler,\n    epoch: int,\n    global_step: int,\n    output_dir: str,\n    lokr_config: Optional[LoKRConfig] = None,\n    run_metadata: Optional[Dict[str, Any]] = None,\n) -> str:\n    \"\"\"Save LoKr weights plus optimizer/scheduler state.\"\"\"\n    output_dir = safe_path(output_dir)\n    os.makedirs(output_dir, exist_ok=True)\n\n    metadata: Dict[str, Any] = {}\n    if lokr_config is not None:\n        metadata[\"lokr_config\"] = lokr_config.to_dict()\n    if run_metadata is not None:\n        metadata[\"run_metadata\"] = run_metadata\n    metadata = metadata or None\n    save_lokr_weights(lycoris_net, output_dir, metadata=metadata)\n\n    state = {\n        \"epoch\": epoch,\n        \"global_step\": global_step,\n        \"optimizer_state_dict\": optimizer.state_dict(),\n        \"scheduler_state_dict\": scheduler.state_dict(),\n    }\n    if lokr_config is not None:\n        state[\"lokr_config\"] = lokr_config.to_dict()\n    if run_metadata is not None:\n        state[\"run_metadata\"] = run_metadata\n\n    state_path = os.path.join(output_dir, \"training_state.pt\")\n    torch.save(state, state_path)\n    logger.info(f\"LoKr checkpoint saved to {output_dir} (epoch={epoch}, step={global_step})\")\n    return output_dir\n"
  },
  {
    "path": "acestep/training/lora_checkpoint.py",
    "content": "\"\"\"\nLoRA Checkpoint Utilities for ACE-Step\n\nProvides functions for saving and loading LoRA checkpoints.\n\"\"\"\n\nimport os\nfrom typing import Optional, Dict, Any\nfrom loguru import logger\n\nimport torch\nfrom torch.nn import Module\n\nfrom acestep.training.path_safety import safe_path\nfrom acestep.training.configs import LoRAConfig\n\ntry:\n    from peft import PeftModel\n\n    PEFT_AVAILABLE = True\nexcept ImportError:\n    PEFT_AVAILABLE = False\n\n\ndef save_lora_weights(\n    model: Module,\n    output_dir: str,\n    save_full_model: bool = False,\n) -> str:\n    \"\"\"Save LoRA adapter weights.\n\n    Args:\n        model: Model with LoRA adapters\n        output_dir: Directory to save weights\n        save_full_model: Whether to save the full model state dict\n\n    Returns:\n        Path to saved weights\n    \"\"\"\n    output_dir = safe_path(output_dir)\n    os.makedirs(output_dir, exist_ok=True)\n\n    if hasattr(model, \"decoder\") and hasattr(model.decoder, \"save_pretrained\"):\n        adapter_path = os.path.join(output_dir, \"adapter\")\n        model.decoder.save_pretrained(adapter_path)\n        logger.info(f\"LoRA adapter saved to {adapter_path}\")\n        return adapter_path\n    elif save_full_model:\n        model_path = os.path.join(output_dir, \"model.pt\")\n        torch.save(model.state_dict(), model_path)\n        logger.info(f\"Full model state dict saved to {model_path}\")\n        return model_path\n    else:\n        lora_state_dict = {}\n        for name, param in model.named_parameters():\n            if \"lora_\" in name:\n                lora_state_dict[name] = param.data.clone()\n\n        if not lora_state_dict:\n            logger.warning(\"No LoRA parameters found to save!\")\n            return \"\"\n\n        lora_path = os.path.join(output_dir, \"lora_weights.pt\")\n        torch.save(lora_state_dict, lora_path)\n        logger.info(f\"LoRA weights saved to {lora_path}\")\n        return lora_path\n\n\ndef load_lora_weights(\n    model: Module,\n    lora_path: str,\n    _lora_config: Optional[LoRAConfig] = None,\n) -> Module:\n    \"\"\"Load LoRA adapter weights into the model.\n\n    Args:\n        model: The base model (without LoRA)\n        lora_path: Path to saved LoRA adapter directory\n        lora_config: Unused; retained for API compatibility\n\n    Returns:\n        Model with LoRA weights loaded\n    \"\"\"\n    validated = safe_path(lora_path)\n    if not os.path.exists(validated):\n        raise FileNotFoundError(f\"LoRA weights not found: {validated}\")\n\n    if os.path.isdir(validated):\n        if not PEFT_AVAILABLE:\n            raise ImportError(\n                \"PEFT library is required to load adapter. Install with: pip install peft\"\n            )\n\n        model.decoder = PeftModel.from_pretrained(model.decoder, validated)\n        logger.info(f\"LoRA adapter loaded from {validated}\")\n\n    elif validated.endswith(\".pt\"):\n        raise ValueError(\n            \"Loading LoRA weights from .pt files is disabled for security. \"\n            \"Use a PEFT adapter directory instead.\"\n        )\n\n    else:\n        raise ValueError(f\"Unsupported LoRA weight format: {validated}\")\n\n    return model\n\n\ndef save_training_checkpoint(\n    model: Module,\n    optimizer,\n    scheduler,\n    epoch: int,\n    global_step: int,\n    output_dir: str,\n) -> str:\n    \"\"\"Save a training checkpoint including LoRA weights and training state.\n\n    Args:\n        model: Model with LoRA adapters\n        optimizer: Optimizer state\n        scheduler: Scheduler state\n        epoch: Current epoch number\n        global_step: Current global step\n        output_dir: Directory to save checkpoint\n\n    Returns:\n        Path to saved checkpoint directory\n    \"\"\"\n    output_dir = safe_path(output_dir)\n    os.makedirs(output_dir, exist_ok=True)\n\n    save_lora_weights(model, output_dir)\n\n    training_state = {\n        \"epoch\": epoch,\n        \"global_step\": global_step,\n        \"optimizer_state_dict\": optimizer.state_dict(),\n        \"scheduler_state_dict\": scheduler.state_dict(),\n    }\n\n    state_path = os.path.join(output_dir, \"training_state.pt\")\n    torch.save(training_state, state_path)\n\n    logger.info(\n        f\"Training checkpoint saved to {output_dir} (epoch {epoch}, step {global_step})\"\n    )\n    return output_dir\n\n\ndef load_training_checkpoint(\n    checkpoint_dir: str,\n    optimizer=None,\n    scheduler=None,\n    device: torch.device = None,\n) -> Dict[str, Any]:\n    \"\"\"Load training checkpoint.\n\n    Args:\n        checkpoint_dir: Directory containing checkpoint files\n        optimizer: Optimizer instance to load state into (optional).\n            When provided, loads optimizer_state_dict from the checkpoint.\n        scheduler: Scheduler instance to load state into (optional).\n            When provided, loads scheduler_state_dict from the checkpoint.\n        device: Device to load tensors to\n\n    Returns:\n        Dictionary with checkpoint info:\n        - epoch: Saved epoch number\n        - global_step: Saved global step\n        - adapter_path: Path to adapter weights\n        - loaded_optimizer: Whether optimizer state was loaded (True when optimizer param provided and state loaded)\n        - loaded_scheduler: Whether scheduler state was loaded (True when scheduler param provided and state loaded)\n    \"\"\"\n    result = {\n        \"epoch\": 0,\n        \"global_step\": 0,\n        \"adapter_path\": None,\n        \"loaded_optimizer\": False,\n        \"loaded_scheduler\": False,\n    }\n\n    try:\n        safe_dir = safe_path(checkpoint_dir)\n    except ValueError:\n        logger.warning(f\"Rejected unsafe checkpoint directory: {checkpoint_dir!r}\")\n        return result\n\n    adapter_path = os.path.join(safe_dir, \"adapter\")\n    if os.path.isdir(adapter_path):\n        result[\"adapter_path\"] = adapter_path\n    elif os.path.isdir(safe_dir):\n        result[\"adapter_path\"] = safe_dir\n\n    state_path = os.path.join(safe_dir, \"training_state.pt\")\n    if os.path.isfile(state_path):\n        try:\n            training_state = torch.load(\n                state_path, map_location=device, weights_only=True\n            )\n\n            if \"epoch\" in training_state:\n                try:\n                    result[\"epoch\"] = int(training_state[\"epoch\"])\n                except (ValueError, TypeError) as e:\n                    logger.warning(\n                        f\"Failed to parse 'epoch' from training_state.pt: {e}, using default 0\"\n                    )\n            if \"global_step\" in training_state:\n                try:\n                    result[\"global_step\"] = int(training_state[\"global_step\"])\n                except (ValueError, TypeError) as e:\n                    logger.warning(\n                        f\"Failed to parse 'global_step' from training_state.pt: {e}, using default 0\"\n                    )\n\n            if optimizer is not None and \"optimizer_state_dict\" in training_state:\n                try:\n                    optimizer_state = training_state[\"optimizer_state_dict\"]\n                    if device is not None:\n                        for state in optimizer_state.get(\"state\", {}).values():\n                            for k, v in state.items():\n                                if isinstance(v, torch.Tensor):\n                                    state[k] = v.to(device)\n                    optimizer.load_state_dict(optimizer_state)\n                    result[\"loaded_optimizer\"] = True\n                    logger.info(\"Loaded optimizer state from checkpoint\")\n                except (RuntimeError, ValueError, KeyError) as e:\n                    logger.warning(f\"Failed to load optimizer state: {e}\")\n\n            if scheduler is not None and \"scheduler_state_dict\" in training_state:\n                try:\n                    scheduler.load_state_dict(training_state[\"scheduler_state_dict\"])\n                    result[\"loaded_scheduler\"] = True\n                    logger.info(\"Loaded scheduler state from checkpoint\")\n                except (RuntimeError, ValueError, KeyError) as e:\n                    logger.warning(f\"Failed to load scheduler state: {e}\")\n\n            logger.info(\n                f\"Loaded checkpoint metadata from epoch {result['epoch']}, step {result['global_step']}\"\n            )\n        except (OSError, RuntimeError, ValueError) as e:\n            logger.warning(f\"Failed to load training_state.pt: {e}\")\n    else:\n        import re\n\n        match = re.search(r\"epoch_(\\d+)\", safe_dir)\n        if match:\n            result[\"epoch\"] = int(match.group(1))\n            logger.info(\n                f\"No training_state.pt found, extracted epoch {result['epoch']} from path\"\n            )\n\n    return result\n"
  },
  {
    "path": "acestep/training/lora_injection.py",
    "content": "\"\"\"\nLoRA Injection Utilities for ACE-Step\n\nProvides functions for injecting LoRA adapters into the DiT decoder model.\n\"\"\"\n\nfrom typing import List, Tuple, Any, Dict\nfrom loguru import logger\nimport types\n\nimport torch.nn as nn\n\nfrom acestep.training.configs import LoRAConfig\n\n\ndef _safe_enable_input_require_grads(self):\n    \"\"\"Safely call enable_input_require_grads on the decoder.\n\n    This helper wraps the original enable_input_require_grads method,\n    handling NotImplementedError gracefully and tracking whether the hook\n    was successfully enabled.\n\n    Args:\n        self: The decoder module to call enable_input_require_grads on.\n    \"\"\"\n    orig_enable_input_require_grads = getattr(\n        self, \"_acestep_orig_enable_input_require_grads\", None\n    )\n\n    try:\n        if orig_enable_input_require_grads is not None:\n            result = orig_enable_input_require_grads()\n        else:\n            result = None\n        try:\n            self._acestep_input_grads_hook_enabled = True\n        except Exception:\n            logger.debug(\n                \"Failed to set _acestep_input_grads_hook_enabled\", exc_info=True\n            )\n        return result\n    except NotImplementedError:\n        try:\n            self._acestep_input_grads_hook_enabled = False\n        except Exception:\n            logger.debug(\n                \"Failed to set _acestep_input_grads_hook_enabled\", exc_info=True\n            )\n        if not getattr(self, \"_acestep_input_grads_warning_emitted\", False):\n            logger.info(\n                \"Skipping enable_input_require_grads for decoder: \"\n                \"get_input_embeddings is not implemented (expected for DiT)\"\n            )\n            try:\n                self._acestep_input_grads_warning_emitted = True\n            except Exception:\n                logger.debug(\n                    \"Failed to set _acestep_input_grads_warning_emitted\", exc_info=True\n                )\n        return None\n\n\ntry:\n    from peft import (\n        get_peft_model,\n        LoraConfig,\n        TaskType,\n        PeftModel,\n    )\n\n    PEFT_AVAILABLE = True\nexcept ImportError:\n    PEFT_AVAILABLE = False\n    logger.warning(\"PEFT library not installed. LoRA training will not be available.\")\n\n\ndef _unwrap_decoder(module: nn.Module) -> nn.Module:\n    \"\"\"Unwrap PEFT/Fabric wrappers from a model/decoder to retrieve the base DiT module.\n\n    This internal helper walks the wrapper chain and returns the underlying\n    ``nn.Module`` that can be passed to PEFT for adapter injection.\n\n    Args:\n        module: A model or decoder that may have PEFT/Fabric wrappers.\n\n    Returns:\n        The unwrapped base DiT decoder module.\n    \"\"\"\n    decoder = module\n    seen_ids = {id(decoder)}\n    while True:\n        next_decoder = getattr(decoder, \"_forward_module\", None)\n        if next_decoder is None:\n            break\n        next_id = id(next_decoder)\n        if next_id in seen_ids:\n            break\n        seen_ids.add(next_id)\n        decoder = next_decoder\n\n    base_model = getattr(decoder, \"base_model\", None)\n    if base_model is not None:\n        inner_model = getattr(base_model, \"model\", None)\n        if inner_model is not None and isinstance(inner_model, nn.Module):\n            decoder = inner_model\n        else:\n            decoder = base_model\n\n    final_model = getattr(decoder, \"model\", None)\n    if final_model is not None and isinstance(final_model, nn.Module):\n        decoder = final_model\n\n    return decoder\n\n\ndef get_dit_target_modules(model) -> List[str]:\n    \"\"\"Get the list of module names in the DiT decoder that can have LoRA applied.\n\n    Args:\n        model: The AceStepConditionGenerationModel\n\n    Returns:\n        List of module names suitable for LoRA\n    \"\"\"\n    target_modules = []\n\n    if hasattr(model, \"decoder\"):\n        for name, module in model.decoder.named_modules():\n            if any(proj in name for proj in [\"q_proj\", \"k_proj\", \"v_proj\", \"o_proj\"]):\n                if isinstance(module, nn.Linear):\n                    target_modules.append(name)\n\n    return target_modules\n\n\ndef freeze_non_lora_parameters(model, freeze_encoder: bool = True) -> None:\n    \"\"\"Freeze all non-LoRA parameters in the model.\n\n    Args:\n        model: The model to freeze parameters for\n        freeze_encoder: Whether to freeze the encoder (condition encoder)\n    \"\"\"\n    encoder_prefixes = (\"encoder\", \"text_encoder\", \"vision_encoder\", \"model.encoder\")\n\n    for name, param in model.named_parameters():\n        is_lora = \"lora_\" in name\n        is_encoder = name.startswith(encoder_prefixes) or any(\n            name.startswith(f\"{prefix}.\") for prefix in encoder_prefixes\n        )\n\n        if is_lora:\n            param.requires_grad = True\n        elif freeze_encoder or not is_encoder:\n            param.requires_grad = False\n\n    total_params = 0\n    trainable_params = 0\n\n    for _, param in model.named_parameters():\n        total_params += param.numel()\n        if param.requires_grad:\n            trainable_params += param.numel()\n\n    logger.info(f\"Frozen parameters: {total_params - trainable_params:,}\")\n    logger.info(f\"Trainable parameters: {trainable_params:,}\")\n\n\ndef inject_lora_into_dit(\n    model,\n    lora_config: LoRAConfig,\n) -> Tuple[Any, Dict[str, Any]]:\n    \"\"\"Inject LoRA adapters into the DiT decoder of the model.\n\n    Args:\n        model: The AceStepConditionGenerationModel\n        lora_config: LoRA configuration\n\n    Returns:\n        Tuple of (peft_model, info_dict)\n    \"\"\"\n    if not PEFT_AVAILABLE:\n        raise ImportError(\n            \"PEFT library is required for LoRA training. Install with: pip install peft\"\n        )\n\n    decoder = _unwrap_decoder(model.decoder)\n    model.decoder = decoder\n\n    if hasattr(decoder, \"enable_input_require_grads\") and not hasattr(\n        decoder, \"_acestep_orig_enable_input_require_grads\"\n    ):\n        orig = decoder.enable_input_require_grads\n        decoder._acestep_orig_enable_input_require_grads = orig\n        decoder.enable_input_require_grads = types.MethodType(\n            _safe_enable_input_require_grads, decoder\n        )\n\n    if hasattr(decoder, \"is_gradient_checkpointing\"):\n        try:\n            decoder.is_gradient_checkpointing = False\n        except Exception:\n            pass\n\n    peft_lora_config = LoraConfig(\n        r=lora_config.r,\n        lora_alpha=lora_config.alpha,\n        lora_dropout=lora_config.dropout,\n        target_modules=lora_config.target_modules,\n        bias=lora_config.bias,\n        task_type=TaskType.FEATURE_EXTRACTION,\n    )\n\n    peft_decoder = get_peft_model(decoder, peft_lora_config)\n    model.decoder = peft_decoder\n\n    for name, param in model.named_parameters():\n        if \"lora_\" not in name:\n            param.requires_grad = False\n\n    total_params = sum(p.numel() for p in model.parameters())\n    trainable_params = sum(p.numel() for p in model.parameters() if p.requires_grad)\n\n    info = {\n        \"total_params\": total_params,\n        \"trainable_params\": trainable_params,\n        \"trainable_ratio\": trainable_params / total_params if total_params > 0 else 0,\n        \"lora_r\": lora_config.r,\n        \"lora_alpha\": lora_config.alpha,\n        \"target_modules\": lora_config.target_modules,\n    }\n\n    logger.info(\"LoRA injected into DiT decoder:\")\n    logger.info(f\"  Total parameters: {total_params:,}\")\n    logger.info(\n        f\"  Trainable parameters: {trainable_params:,} ({info['trainable_ratio']:.2%})\"\n    )\n    logger.info(f\"  LoRA rank: {lora_config.r}, alpha: {lora_config.alpha}\")\n\n    return model, info\n"
  },
  {
    "path": "acestep/training/lora_utils.py",
    "content": "\"\"\"\nLoRA Utilities for ACE-Step\n\nProvides utilities for inspecting and merging LoRA adapters.\nUses PEFT (Parameter-Efficient Fine-Tuning) library for LoRA implementation.\n\"\"\"\n\nfrom typing import Dict, Any\nfrom loguru import logger\n\ntry:\n    from peft import PeftModel\n\n    PEFT_AVAILABLE = True\nexcept ImportError:\n    PEFT_AVAILABLE = False\n    logger.warning(\"PEFT library not installed. LoRA training will not be available.\")\n\n\ndef check_peft_available() -> bool:\n    \"\"\"Check if PEFT library is available.\"\"\"\n    return PEFT_AVAILABLE\n\n\ndef merge_lora_weights(model) -> Any:\n    \"\"\"Merge LoRA weights into the base model.\n\n    This permanently integrates the LoRA adaptations into the model weights.\n    After merging, the model can be used without PEFT.\n\n    Args:\n        model: Model with LoRA adapters\n\n    Returns:\n        Model with merged weights\n    \"\"\"\n    if hasattr(model, \"decoder\") and hasattr(model.decoder, \"merge_and_unload\"):\n        model.decoder = model.decoder.merge_and_unload()\n        logger.info(\"LoRA weights merged into base model\")\n    else:\n        logger.warning(\"Model does not support LoRA merging\")\n\n    return model\n\n\ndef get_lora_info(model) -> Dict[str, Any]:\n    \"\"\"Get information about LoRA adapters in the model.\n\n    Args:\n        model: Model to inspect\n\n    Returns:\n        Dictionary with LoRA information\n    \"\"\"\n    info = {\n        \"has_lora\": False,\n        \"lora_params\": 0,\n        \"total_params\": 0,\n        \"modules_with_lora\": [],\n    }\n\n    total_params = 0\n    lora_params = 0\n    lora_modules = []\n\n    for name, param in model.named_parameters():\n        total_params += param.numel()\n        if \"lora_\" in name:\n            lora_params += param.numel()\n            module_name = name.rsplit(\".lora_\", 1)[0]\n            if module_name not in lora_modules:\n                lora_modules.append(module_name)\n\n    info[\"total_params\"] = total_params\n    info[\"lora_params\"] = lora_params\n    info[\"has_lora\"] = lora_params > 0\n    info[\"modules_with_lora\"] = lora_modules\n\n    if total_params > 0:\n        info[\"lora_ratio\"] = lora_params / total_params\n\n    return info\n"
  },
  {
    "path": "acestep/training/path_safety.py",
    "content": "\"\"\"Path sanitisation helpers for training modules.\n\nProvides a single ``safe_path`` function that validates user-provided\nfilesystem paths against a known safe root directory.  The validation\nuses ``os.path.realpath`` followed by a ``.startswith`` check — the\nexact pattern that CodeQL recognises as a sanitiser for the\n``py/path-injection`` query.\n\nSymlinks are resolved on both the root and user paths so that paths\nthrough symlinks (e.g. ``/root/data`` → ``/vepfs/.../data``) are\ncompared consistently.\n\nAll training modules that accept user-supplied paths should call\n``safe_path`` (or ``safe_open``) before performing any filesystem I/O.\n\"\"\"\n\nimport os\nfrom typing import Optional\n\nfrom loguru import logger\n\n\ndef _resolve(path: str) -> str:\n    \"\"\"Normalise and resolve symlinks in *path*.\n\n    Uses ``os.path.realpath`` so that symlinked prefixes are resolved\n    to their canonical form before comparison.\n    \"\"\"\n    return os.path.normpath(os.path.realpath(path))\n\n\n# Root directory that all user-provided paths must resolve under.\n# Defaults to the working directory at import time.  Override via\n# ``set_safe_root`` if needed (e.g. in tests).\n_SAFE_ROOT: str = _resolve(os.getcwd())\n\n\ndef set_safe_root(root: str) -> None:\n    \"\"\"Override the safe root directory.\n\n    Args:\n        root: New safe root (will be normalised and symlink-resolved).\n    \"\"\"\n    global _SAFE_ROOT  # noqa: PLW0603\n    _SAFE_ROOT = _resolve(root)\n\n\ndef get_safe_root() -> str:\n    \"\"\"Return the current safe root directory.\"\"\"\n    return _SAFE_ROOT\n\n\ndef safe_path(user_path: str, *, base: Optional[str] = None) -> str:\n    \"\"\"Validate and normalise a user-provided path.\n\n    The returned path is guaranteed to live under *base* (or the\n    global ``_SAFE_ROOT`` when *base* is ``None``).  Symlinks in both\n    the root and user path are resolved so that paths through symlinks\n    compare correctly.\n\n    Args:\n        user_path: Untrusted path string from user input.\n        base: Optional explicit base directory.  When provided it is\n              resolved (symlinks included) and used instead of\n              ``_SAFE_ROOT``.\n\n    Returns:\n        Normalised, symlink-resolved absolute path within the safe root.\n\n    Raises:\n        ValueError: If the resolved path escapes the safe root.\n    \"\"\"\n    if base is not None:\n        root = _resolve(base)\n    else:\n        root = _SAFE_ROOT\n\n    # Resolve the user path.  If relative, join against *root* first.\n    if os.path.isabs(user_path):\n        normalised = _resolve(user_path)\n    else:\n        normalised = _resolve(os.path.join(root, user_path))\n\n    # ── CodeQL-recognised sanitiser barrier ──\n    # ``normpath(…).startswith(safe_prefix)`` is the pattern that\n    # CodeQL's ``py/path-injection`` query treats as a sanitiser.\n    if not normalised.startswith(root + os.sep) and normalised != root:\n        raise ValueError(\n            f\"Path escapes safe root: {user_path!r} \"\n            f\"(resolved to {normalised!r}, root={root!r})\"\n        )\n\n    return normalised\n\n\ndef safe_open(user_path: str, mode: str = \"r\", **kwargs):\n    \"\"\"Open a file after validating its path.\n\n    Convenience wrapper around ``safe_path`` + ``open``.\n\n    Args:\n        user_path: Untrusted path string.\n        mode: File open mode.\n        **kwargs: Extra keyword arguments forwarded to ``open``.\n\n    Returns:\n        File object.\n\n    Raises:\n        ValueError: If the path escapes the safe root.\n    \"\"\"\n    validated = safe_path(user_path)\n    return open(validated, mode, **kwargs)  # noqa: SIM115\n"
  },
  {
    "path": "acestep/training/test_lora_utils.py",
    "content": "\"\"\"Unit tests for acestep.training.lora_injection and acestep.training.lora_utils modules.\"\"\"\n\nimport unittest\nfrom unittest.mock import MagicMock, patch\nimport torch\nimport torch.nn as nn\n\nfrom acestep.training.lora_injection import (\n    _unwrap_decoder,\n    freeze_non_lora_parameters,\n)\nfrom acestep.training.lora_utils import check_peft_available\n\n\nclass TestUnwrapDecoder(unittest.TestCase):\n    \"\"\"Test cases for _unwrap_decoder function.\"\"\"\n\n    def test_returns_module_directly(self):\n        \"\"\"If module has no wrappers, return it unchanged.\"\"\"\n        mock_module = MagicMock(spec=nn.Module)\n        result = _unwrap_decoder(mock_module)\n        self.assertIs(result, mock_module)\n\n    def test_unwraps_forward_module(self):\n        \"\"\"Unwrap _forward_module chain.\"\"\"\n        inner = MagicMock(spec=nn.Module)\n        wrapper = MagicMock(spec_set=[\"_forward_module\"])\n        wrapper._forward_module = inner\n\n        result = _unwrap_decoder(wrapper)\n        self.assertIs(result, inner)\n\n    def test_unwraps_peft_base_model(self):\n        \"\"\"Unwrap PEFT base_model with .model attribute.\"\"\"\n        inner = MagicMock(spec=nn.Module)\n        base = MagicMock(spec_set=[\"model\"])\n        base.model = inner\n\n        result = _unwrap_decoder(base)\n        self.assertIs(result, inner)\n\n    def test_unwraps_peft_base_model_no_inner_model(self):\n        \"\"\"Unwrap PEFT base_model without .model attribute.\"\"\"\n        base = MagicMock(spec=nn.Module)\n\n        result = _unwrap_decoder(base)\n        self.assertIs(result, base)\n\n    def test_unwraps_nested_wrappers(self):\n        \"\"\"Handle multiple wrapper layers.\"\"\"\n        inner = MagicMock(spec=nn.Module)\n        wrapper1 = MagicMock(spec_set=[\"_forward_module\"])\n        wrapper1._forward_module = inner\n        wrapper2 = MagicMock(spec_set=[\"_forward_module\"])\n        wrapper2._forward_module = wrapper1\n\n        result = _unwrap_decoder(wrapper2)\n        self.assertIs(result, inner)\n\n    def test_unwraps_complex_peft_chain(self):\n        \"\"\"Unwrap complex chain: wrapper -> _forward_module -> base_model -> .model.\"\"\"\n        inner = MagicMock(spec=nn.Module)\n        base = MagicMock(spec_set=[\"model\"])\n        base.model = inner\n        mid = MagicMock(spec_set=[\"_forward_module\"])\n        mid._forward_module = base\n        wrapper = MagicMock(spec_set=[\"_forward_module\"])\n        wrapper._forward_module = mid\n\n        result = _unwrap_decoder(wrapper)\n        self.assertIs(result, inner)\n\n\nclass TestCheckPeftAvailable(unittest.TestCase):\n    \"\"\"Test cases for check_peft_available function.\"\"\"\n\n    def test_returns_boolean(self):\n        \"\"\"check_peft_available should return a boolean.\"\"\"\n        result = check_peft_available()\n        self.assertIsInstance(result, bool)\n\n\nclass TestFreezeNonLoraParameters(unittest.TestCase):\n    \"\"\"Test cases for freeze_non_lora_parameters function.\"\"\"\n\n    def _create_mock_model(self, param_names_requires_grad=None):\n        \"\"\"Create a mock model with named parameters.\"\"\"\n        mock_model = MagicMock(spec=nn.Module)\n        params = []\n        for name, requires_grad in param_names_requires_grad or []:\n            mock_param = MagicMock()\n            mock_param.requires_grad = requires_grad\n            mock_param.numel.return_value = 100\n            params.append((name, mock_param))\n        mock_model.named_parameters.return_value = params\n        return mock_model\n\n    def test_lora_params_remain_trainable(self):\n        \"\"\"LoRA parameters should remain trainable regardless of freeze_encoder.\"\"\"\n        mock_model = self._create_mock_model(\n            [\n                (\"decoder.layer.q_proj.lora_A.weight\", True),\n                (\"decoder.layer.k_proj.lora_B.weight\", True),\n            ]\n        )\n        freeze_non_lora_parameters(mock_model, freeze_encoder=True)\n        for name, param in mock_model.named_parameters():\n            if \"lora_\" in name:\n                self.assertTrue(\n                    param.requires_grad, f\"LoRA param {name} should be trainable\"\n                )\n\n    def test_non_lora_non_encoder_frozen_when_freeze_encoder_true(self):\n        \"\"\"Non-LoRA, non-encoder params should be frozen when freeze_encoder=True.\"\"\"\n        mock_model = self._create_mock_model(\n            [\n                (\"decoder.layer.fc.weight\", True),\n            ]\n        )\n        freeze_non_lora_parameters(mock_model, freeze_encoder=True)\n        for name, param in mock_model.named_parameters():\n            self.assertFalse(\n                param.requires_grad, f\"Non-LoRA param {name} should be frozen\"\n            )\n\n    def test_encoder_frozen_when_freeze_encoder_true(self):\n        \"\"\"Encoder parameters should be frozen when freeze_encoder=True.\"\"\"\n        mock_model = self._create_mock_model(\n            [\n                (\"encoder.layer.0.weight\", True),\n                (\"text_encoder.embed.weight\", True),\n                (\"vision_encoder.conv.weight\", True),\n                (\"model.encoder.block.0.weight\", True),\n            ]\n        )\n        freeze_non_lora_parameters(mock_model, freeze_encoder=True)\n        for name, param in mock_model.named_parameters():\n            self.assertFalse(\n                param.requires_grad, f\"Encoder param {name} should be frozen\"\n            )\n\n    def test_encoder_trainable_when_freeze_encoder_false(self):\n        \"\"\"Encoder parameters should remain trainable when freeze_encoder=False.\"\"\"\n        mock_model = self._create_mock_model(\n            [\n                (\"encoder.layer.0.weight\", True),\n                (\"text_encoder.embed.weight\", True),\n                (\"vision_encoder.conv.weight\", True),\n                (\"model.encoder.block.0.weight\", True),\n                (\"decoder.layer.fc.weight\", True),\n            ]\n        )\n        freeze_non_lora_parameters(mock_model, freeze_encoder=False)\n        encoder_params = [\n            \"encoder.layer.0.weight\",\n            \"text_encoder.embed.weight\",\n            \"vision_encoder.conv.weight\",\n            \"model.encoder.block.0.weight\",\n        ]\n        for name, param in mock_model.named_parameters():\n            if name in encoder_params:\n                self.assertTrue(\n                    param.requires_grad, f\"Encoder param {name} should be trainable\"\n                )\n            else:\n                self.assertFalse(\n                    param.requires_grad, f\"Non-encoder param {name} should be frozen\"\n                )\n\n    def test_mixed_params_freeze_encoder_true(self):\n        \"\"\"Test mixed LoRA and encoder params with freeze_encoder=True.\"\"\"\n        mock_model = self._create_mock_model(\n            [\n                (\"encoder.layer.0.weight\", True),\n                (\"decoder.layer.q_proj.lora_A.weight\", True),\n                (\"decoder.layer.fc.weight\", True),\n            ]\n        )\n        freeze_non_lora_parameters(mock_model, freeze_encoder=True)\n        for name, param in mock_model.named_parameters():\n            if \"lora_\" in name:\n                self.assertTrue(\n                    param.requires_grad, f\"LoRA param {name} should be trainable\"\n                )\n            else:\n                self.assertFalse(\n                    param.requires_grad, f\"Non-LoRA param {name} should be frozen\"\n                )\n\n    def test_mixed_params_freeze_encoder_false(self):\n        \"\"\"Test mixed LoRA and encoder params with freeze_encoder=False.\"\"\"\n        mock_model = self._create_mock_model(\n            [\n                (\"encoder.layer.0.weight\", True),\n                (\"decoder.layer.q_proj.lora_A.weight\", True),\n                (\"decoder.layer.fc.weight\", True),\n            ]\n        )\n        freeze_non_lora_parameters(mock_model, freeze_encoder=False)\n        for name, param in mock_model.named_parameters():\n            if \"lora_\" in name:\n                self.assertTrue(\n                    param.requires_grad, f\"LoRA param {name} should be trainable\"\n                )\n            elif (\n                name.startswith(\"encoder\")\n                or name.startswith(\"text_encoder\")\n                or name.startswith(\"vision_encoder\")\n                or name.startswith(\"model.encoder\")\n            ):\n                self.assertTrue(\n                    param.requires_grad, f\"Encoder param {name} should be trainable\"\n                )\n            else:\n                self.assertFalse(\n                    param.requires_grad,\n                    f\"Non-LoRA/non-encoder param {name} should be frozen\",\n                )\n\n\nif __name__ == \"__main__\":\n    unittest.main()\n"
  },
  {
    "path": "acestep/training/trainer.py",
    "content": "\"\"\"\nLoRA Trainer for ACE-Step\n\nLightning Fabric-based trainer for LoRA fine-tuning of ACE-Step DiT decoder.\nSupports training from preprocessed tensor files for optimal performance.\n\"\"\"\n\nimport os\nimport time\nimport random\nimport math\nfrom typing import Optional, List, Dict, Any, Tuple, Generator\nfrom loguru import logger\n\nimport torch\nimport torch.nn as nn\nimport torch.nn.functional as F\nfrom contextlib import nullcontext\nfrom torch.optim import AdamW\nfrom torch.optim.lr_scheduler import CosineAnnealingWarmRestarts, LinearLR, SequentialLR\n\ntry:\n    from lightning.fabric import Fabric\n    from lightning.fabric.loggers import TensorBoardLogger\n\n    LIGHTNING_AVAILABLE = True\nexcept ImportError:\n    LIGHTNING_AVAILABLE = False\n    logger.warning(\n        \"Lightning Fabric not installed. Training will use basic training loop.\"\n    )\n\n# OPTIMIZATION: Use 8-bit Adam to save some VRAM\ntry:\n    import bitsandbytes as bnb\n\n    HAS_BNB = True\nexcept ImportError:\n    HAS_BNB = False\n    logger.warning(\"bitsandbytes not installed. Using standard AdamW.\")\n\nfrom acestep.training.configs import LoRAConfig, LoKRConfig, TrainingConfig\nfrom acestep.training.lora_injection import inject_lora_into_dit\nfrom acestep.training.lora_utils import check_peft_available\nfrom acestep.training.lora_checkpoint import (\n    save_lora_weights,\n    save_training_checkpoint,\n    load_training_checkpoint,\n)\nfrom acestep.training.lokr_utils import (\n    inject_lokr_into_dit,\n    save_lokr_weights,\n    save_lokr_training_checkpoint,\n    check_lycoris_available,\n)\nfrom acestep.training.data_module import PreprocessedDataModule\nfrom acestep.training.path_safety import safe_path\n\n\n# Turbo model shift=3.0 discrete timesteps (8 steps, same as inference)\nTURBO_SHIFT3_TIMESTEPS = [\n    1.0,\n    0.9545454545454546,\n    0.9,\n    0.8333333333333334,\n    0.75,\n    0.6428571428571429,\n    0.5,\n    0.3,\n]\n\n\ndef _normalize_device_type(device: Any) -> str:\n    \"\"\"Normalize torch device or string to canonical device type.\"\"\"\n    if isinstance(device, torch.device):\n        return device.type\n    if isinstance(device, str):\n        return device.split(\":\", 1)[0]\n    return str(device)\n\n\ndef _select_compute_dtype(device_type: str) -> torch.dtype:\n    \"\"\"Pick the compute dtype for each accelerator.\"\"\"\n    if device_type in (\"cuda\", \"xpu\"):\n        return torch.bfloat16\n    if device_type == \"mps\":\n        return torch.float16\n    return torch.float32\n\n\ndef _select_fabric_precision(device_type: str) -> str:\n    \"\"\"Pick Fabric precision plugin setting for each accelerator.\"\"\"\n    if device_type in (\"cuda\", \"xpu\"):\n        return \"bf16-mixed\"\n    if device_type == \"mps\":\n        # Use AMP on MPS for better throughput. Trainable LoRA parameters are\n        # explicitly forced to fp32 before optimizer/Fabric setup.\n        return \"16-mixed\"\n    return \"32-true\"\n\n\ndef _ensure_trainable_params_fp32(module: nn.Module) -> Tuple[int, int]:\n    \"\"\"Force trainable floating-point parameters to fp32.\"\"\"\n    casted = 0\n    total = 0\n    for p in module.parameters():\n        if not p.requires_grad:\n            continue\n        total += 1\n        if p.is_floating_point() and p.dtype != torch.float32:\n            with torch.no_grad():\n                p.data = p.data.float()\n            casted += 1\n    return casted, total\n\n\ndef _count_nonfinite_grads(params: List[torch.nn.Parameter]) -> Tuple[int, int]:\n    \"\"\"Count non-finite gradient tensors among params with gradients.\"\"\"\n    nonfinite = 0\n    total_with_grad = 0\n    for p in params:\n        g = p.grad\n        if g is None:\n            continue\n        total_with_grad += 1\n        if not torch.isfinite(g).all():\n            nonfinite += 1\n    return nonfinite, total_with_grad\n\n\ndef _ensure_optimizer_params_fp32(optimizer: torch.optim.Optimizer) -> Tuple[int, int]:\n    \"\"\"Force optimizer parameter tensors to fp32 when trainable.\"\"\"\n    casted = 0\n    total = 0\n    for group in optimizer.param_groups:\n        for p in group.get(\"params\", []):\n            if p is None:\n                continue\n            total += 1\n            if p.is_floating_point() and p.dtype != torch.float32:\n                with torch.no_grad():\n                    p.data = p.data.float()\n                casted += 1\n    return casted, total\n\n\ndef _build_param_name_lookup(\n    module: nn.Module, extra_module: Optional[nn.Module] = None\n) -> Dict[int, str]:\n    \"\"\"Build a best-effort id(param) -> name lookup for debug logging.\"\"\"\n    lookup: Dict[int, str] = {}\n    for name, p in module.named_parameters():\n        lookup[id(p)] = name\n    if extra_module is not None:\n        for name, p in extra_module.named_parameters():\n            lookup.setdefault(id(p), f\"lycoris_net.{name}\")\n    return lookup\n\n\ndef _count_nonfinite_grads_detailed(\n    params: List[torch.nn.Parameter],\n    param_name_lookup: Dict[int, str],\n    detail_limit: int = 8,\n) -> Tuple[int, int, List[str]]:\n    \"\"\"Count non-finite grads and return up to `detail_limit` offending tensor details.\"\"\"\n    nonfinite = 0\n    total_with_grad = 0\n    details: List[str] = []\n\n    for p in params:\n        g = p.grad\n        if g is None:\n            continue\n        total_with_grad += 1\n        if torch.isfinite(g).all():\n            continue\n\n        nonfinite += 1\n        if len(details) >= detail_limit:\n            continue\n\n        pname = param_name_lookup.get(id(p), f\"<unnamed:{id(p)}>\")\n        g32 = g.detach().float()\n        nan_count = int(torch.isnan(g32).sum().item())\n        inf_count = int(torch.isinf(g32).sum().item())\n        finite_vals = g32[torch.isfinite(g32)]\n        max_abs_finite = (\n            float(finite_vals.abs().max().item())\n            if finite_vals.numel()\n            else float(\"nan\")\n        )\n\n        p32 = p.detach().float()\n        param_nonfinite = int((~torch.isfinite(p32)).sum().item())\n        details.append(\n            f\"{pname} | shape={tuple(p.shape)} grad_dtype={g.dtype} \"\n            f\"nan={nan_count} inf={inf_count} max_abs_finite={max_abs_finite:.3e} \"\n            f\"param_nonfinite={param_nonfinite}\"\n        )\n\n    return nonfinite, total_with_grad, details\n\n\ndef _collect_lokr_trainable_params(\n    module: nn.Module, lycoris_net: Optional[nn.Module]\n) -> List[torch.nn.Parameter]:\n    \"\"\"\n    Collect LoKr trainable params robustly.\n\n    Primary path is model parameter traversal. If that returns empty due to\n    wrapper/registration quirks, fall back to LyCORIS module parameters.\n    \"\"\"\n    params = [p for p in module.parameters() if p.requires_grad]\n    if params:\n        return list({id(p): p for p in params}.values())\n\n    fallback: List[torch.nn.Parameter] = []\n    if lycoris_net is None:\n        return fallback\n\n    for m in getattr(lycoris_net, \"loras\", []) or []:\n        for p in m.parameters():\n            if p.requires_grad:\n                fallback.append(p)\n    if not fallback:\n        for p in lycoris_net.parameters():\n            if p.requires_grad:\n                fallback.append(p)\n    return list({id(p): p for p in fallback}.values())\n\n\ndef _unwrap_stale_fabric_decoder(model: nn.Module) -> bool:\n    \"\"\"\n    Unwrap stale Lightning Fabric wrappers from decoder left by previous runs.\n\n    Returns:\n        True if decoder was unwrapped, else False.\n    \"\"\"\n    if model is None or not hasattr(model, \"decoder\"):\n        return False\n    decoder = model.decoder\n    unwrapped = False\n    while hasattr(decoder, \"_forward_module\") and isinstance(\n        getattr(decoder, \"_forward_module\"), nn.Module\n    ):\n        decoder = decoder._forward_module\n        unwrapped = True\n    if unwrapped:\n        model.decoder = decoder\n    return unwrapped\n\n\ndef _iter_module_wrappers(module: nn.Module) -> List[nn.Module]:\n    \"\"\"Collect wrapper chain modules (Fabric/PEFT/compile/base-model wrappers).\"\"\"\n    modules: List[nn.Module] = []\n    stack = [module]\n    visited = set()\n\n    while stack:\n        current = stack.pop()\n        if not isinstance(current, nn.Module):\n            continue\n        module_id = id(current)\n        if module_id in visited:\n            continue\n        visited.add(module_id)\n        modules.append(current)\n\n        for attr_name in (\n            \"_forward_module\",\n            \"_orig_mod\",\n            \"base_model\",\n            \"model\",\n            \"module\",\n        ):\n            child = getattr(current, attr_name, None)\n            if isinstance(child, nn.Module):\n                stack.append(child)\n\n    return modules\n\n\ndef _configure_training_memory_features(decoder: nn.Module) -> Tuple[bool, bool, bool]:\n    \"\"\"\n    Enable gradient checkpointing and disable use_cache across wrapped decoder modules.\n\n    Returns:\n        Tuple[checkpointing_enabled, cache_disabled, input_grads_enabled]\n    \"\"\"\n    checkpointing_enabled = False\n    cache_disabled = False\n    input_grads_enabled = False\n\n    for mod in _iter_module_wrappers(decoder):\n        if hasattr(mod, \"gradient_checkpointing_enable\"):\n            try:\n                mod.gradient_checkpointing_enable()\n                checkpointing_enabled = True\n            except Exception:\n                pass\n        elif hasattr(mod, \"gradient_checkpointing\"):\n            try:\n                mod.gradient_checkpointing = True\n                checkpointing_enabled = True\n            except Exception:\n                pass\n\n        # PEFT + gradient checkpointing can require input embeddings to have\n        # gradients enabled, otherwise loss may be detached (no grad_fn).\n        if hasattr(mod, \"enable_input_require_grads\"):\n            try:\n                mod.enable_input_require_grads()\n                hook_enabled = bool(\n                    getattr(mod, \"_acestep_input_grads_hook_enabled\", False)\n                )\n                has_require_hook = getattr(mod, \"_require_grads_hook\", None) is not None\n                if hook_enabled or has_require_hook:\n                    input_grads_enabled = True\n            except Exception:\n                pass\n\n        cfg = getattr(mod, \"config\", None)\n        if cfg is not None and hasattr(cfg, \"use_cache\"):\n            try:\n                if getattr(cfg, \"use_cache\", None) is not False:\n                    cfg.use_cache = False\n                    cache_disabled = True\n            except Exception:\n                pass\n\n    return checkpointing_enabled, cache_disabled, input_grads_enabled\n\n\ndef sample_discrete_timestep(bsz, timesteps_tensor):\n    \"\"\"Sample timesteps from discrete turbo shift=3 schedule.\n\n    For each sample in the batch, randomly select one of the 8 discrete timesteps\n    used by the turbo model with shift=3.0.\n\n    Args:\n        bsz: Batch size\n        device: Device\n        dtype: Data type (should be bfloat16)\n\n    Returns:\n        Tuple of (t, r) where both are the same sampled timestep\n    \"\"\"\n    # Randomly select indices for each sample in batch\n    indices = torch.randint(\n        0, timesteps_tensor.shape[0], (bsz,), device=timesteps_tensor.device\n    )\n    t = timesteps_tensor[indices]\n\n    # r = t for this training setup\n    r = t\n\n    return t, r\n\n\nclass PreprocessedLoRAModule(nn.Module):\n    \"\"\"LoRA Training Module using preprocessed tensors.\n\n    This module trains only the DiT decoder with LoRA adapters.\n    All inputs are pre-computed tensors - no VAE or text encoder needed!\n\n    Training flow:\n    1. Load pre-computed tensors (target_latents, encoder_hidden_states, context_latents)\n    2. Sample noise and timestep\n    3. Forward through decoder (with LoRA)\n    4. Compute flow matching loss\n    \"\"\"\n\n    def __init__(\n        self,\n        model: nn.Module,\n        lora_config: LoRAConfig,\n        training_config: TrainingConfig,\n        device: torch.device,\n        dtype: torch.dtype,\n    ):\n        \"\"\"Initialize the training module.\n\n        Args:\n            model: The AceStepConditionGenerationModel\n            lora_config: LoRA configuration\n            training_config: Training configuration\n            device: Device to use\n            dtype: Data type to use\n        \"\"\"\n        super().__init__()\n\n        self.lora_config = lora_config\n        self.training_config = training_config\n        self.device = torch.device(device) if isinstance(device, str) else device\n        self.device_type = _normalize_device_type(self.device)\n        self.dtype = _select_compute_dtype(self.device_type)\n        self.transfer_non_blocking = self.device_type in (\"cuda\", \"xpu\")\n        self.timesteps_tensor = torch.tensor(\n            TURBO_SHIFT3_TIMESTEPS, device=self.device, dtype=self.dtype\n        )\n        # When gradient checkpointing is enabled via wrapper layers that don't expose\n        # enable_input_require_grads(), force at least one forward input to require grad\n        # so checkpointed segments keep a valid autograd graph.\n        self.force_input_grads_for_checkpointing = False\n\n        # Inject LoRA into the decoder only\n        if check_peft_available():\n            # Fix: Force tensors out of inference mode before injection\n            for param in model.parameters():\n                param.data = param.data.clone()\n                if param.is_inference():\n                    with torch.no_grad():\n                        param.data = param.data.clone()\n\n            self.model, self.lora_info = inject_lora_into_dit(model, lora_config)\n            logger.info(\n                f\"LoRA injected: {self.lora_info['trainable_params']:,} trainable params\"\n            )\n        else:\n            self.model = model\n            self.lora_info = {}\n            logger.warning(\"PEFT not available, training without LoRA adapters\")\n\n        # torch.compile: optional perf optimization.\n        # PEFT LoRA wraps the decoder in PeftModelForFeatureExtraction which is\n        # incompatible with torch.compile/inductor on PyTorch 2.7.x\n        # (AssertionError at first forward pass, not at compile time).\n        # Only compile when NOT using PEFT adapters.\n        has_peft = bool(self.lora_info)\n        if hasattr(torch, \"compile\") and self.device_type == \"cuda\" and not has_peft:\n            try:\n                logger.info(\"Compiling DiT decoder...\")\n                self.model.decoder = torch.compile(self.model.decoder, mode=\"default\")\n                logger.info(\"torch.compile successful\")\n            except Exception as e:\n                logger.warning(\n                    f\"torch.compile failed ({e}), continuing without compilation\"\n                )\n        else:\n            if has_peft:\n                logger.info(\n                    \"Skipping torch.compile (incompatible with PEFT LoRA adapters)\"\n                )\n            else:\n                logger.info(\n                    \"torch.compile not available on this device/PyTorch version, skipping\"\n                )\n\n        # Model config for flow matching\n        self.config = model.config\n\n        # Store training losses\n        self.training_losses = []\n\n    def training_step(\n        self,\n        batch: Dict[str, torch.Tensor],\n        record_loss: bool = True,\n    ) -> torch.Tensor:\n        \"\"\"Single training step using preprocessed tensors.\n\n        Note: This is a distilled turbo model, NO CFG is used.\n\n        Args:\n            batch: Dictionary containing pre-computed tensors:\n                - target_latents: [B, T, 64] - VAE encoded audio\n                - attention_mask: [B, T] - Valid audio mask\n                - encoder_hidden_states: [B, L, D] - Condition encoder output\n                - encoder_attention_mask: [B, L] - Condition mask\n                - context_latents: [B, T, 128] - Source context\n            record_loss: If True, append loss to training_losses (set False for validation).\n\n        Returns:\n            Loss tensor (float32 for stable backward)\n        \"\"\"\n        # Use autocast for mixed precision training (bf16 on CUDA/XPU, fp16 on MPS)\n        if self.device_type in (\"cuda\", \"xpu\", \"mps\"):\n            autocast_ctx = torch.autocast(\n                device_type=self.device_type, dtype=self.dtype\n            )\n        else:\n            autocast_ctx = nullcontext()\n        with autocast_ctx:\n            # Get tensors from batch (already on device from Fabric dataloader)\n            target_latents = batch[\"target_latents\"].to(\n                self.device, dtype=self.dtype, non_blocking=self.transfer_non_blocking\n            )  # x0\n            attention_mask = batch[\"attention_mask\"].to(\n                self.device, dtype=self.dtype, non_blocking=self.transfer_non_blocking\n            )\n            encoder_hidden_states = batch[\"encoder_hidden_states\"].to(\n                self.device, dtype=self.dtype, non_blocking=self.transfer_non_blocking\n            )\n            encoder_attention_mask = batch[\"encoder_attention_mask\"].to(\n                self.device, dtype=self.dtype, non_blocking=self.transfer_non_blocking\n            )\n            context_latents = batch[\"context_latents\"].to(\n                self.device, dtype=self.dtype, non_blocking=self.transfer_non_blocking\n            )\n\n            bsz = target_latents.shape[0]\n\n            # Flow matching: sample noise x1 and interpolate with data x0\n            x1 = torch.randn_like(target_latents)  # Noise\n            x0 = target_latents  # Data\n\n            # Sample timesteps from discrete turbo shift=3 schedule (8 steps)\n            t, _ = sample_discrete_timestep(bsz, self.timesteps_tensor)\n            t_ = t.unsqueeze(-1).unsqueeze(-1)\n\n            # Interpolate: x_t = t * x1 + (1 - t) * x0\n            xt = t_ * x1 + (1.0 - t_) * x0\n            if self.force_input_grads_for_checkpointing:\n                xt = xt.requires_grad_(True)\n\n            # Forward through decoder (distilled turbo model, no CFG)\n            decoder_outputs = self.model.decoder(\n                hidden_states=xt,\n                timestep=t,\n                timestep_r=t,\n                attention_mask=attention_mask,\n                encoder_hidden_states=encoder_hidden_states,\n                encoder_attention_mask=encoder_attention_mask,\n                context_latents=context_latents,\n            )\n\n            # Flow matching loss: predict the flow field v = x1 - x0\n            flow = x1 - x0\n            diffusion_loss = F.mse_loss(decoder_outputs[0], flow)\n\n        # Convert loss to float32 for stable backward pass\n        diffusion_loss = diffusion_loss.float()\n\n        if record_loss:\n            self.training_losses.append(diffusion_loss.item())\n\n        return diffusion_loss\n\n\nclass LoRATrainer:\n    \"\"\"High-level trainer for ACE-Step LoRA fine-tuning.\n\n    Uses Lightning Fabric for distributed training and mixed precision.\n    Supports training from preprocessed tensor directories.\n    \"\"\"\n\n    def __init__(\n        self,\n        dit_handler,\n        lora_config: LoRAConfig,\n        training_config: TrainingConfig,\n    ):\n        \"\"\"Initialize the trainer.\n\n        Args:\n            dit_handler: Initialized DiT handler (for model access)\n            lora_config: LoRA configuration\n            training_config: Training configuration\n        \"\"\"\n        self.dit_handler = dit_handler\n        self.lora_config = lora_config\n        # Validate output_dir early so all downstream path operations are safe\n        training_config.output_dir = safe_path(training_config.output_dir)\n        self.training_config = training_config\n\n        self.module = None\n        self.fabric = None\n        self.is_training = False\n\n    def train_from_preprocessed(\n        self,\n        tensor_dir: str,\n        training_state: Optional[Dict] = None,\n        resume_from: Optional[str] = None,\n    ) -> Generator[Tuple[int, float, str], None, None]:\n        \"\"\"Train LoRA adapters from preprocessed tensor files.\n\n        This is the recommended training method for best performance.\n\n        Args:\n            tensor_dir: Directory containing preprocessed .pt files\n            training_state: Optional state dict for stopping control\n            resume_from: Optional path to checkpoint directory to resume from\n\n        Yields:\n            Tuples of (step, loss, status_message)\n        \"\"\"\n        self.is_training = True\n\n        try:\n            # LoRA injection via PEFT is incompatible with torchao-quantized\n            # decoder modules in this runtime. Fail fast with actionable guidance.\n            quantization_mode = getattr(self.dit_handler, \"quantization\", None)\n            if quantization_mode is not None:\n                yield (\n                    0,\n                    0.0,\n                    (\n                        \"❌ LoRA training requires a non-quantized DiT model. \"\n                        f\"Current quantization: {quantization_mode}. \"\n                        \"Re-initialize service with INT8 Quantization disabled, then retry training.\"\n                    ),\n                )\n                return\n\n            # Validate tensor directory\n            try:\n                tensor_dir = safe_path(tensor_dir)\n            except ValueError:\n                yield 0, 0.0, f\"❌ Rejected unsafe tensor directory: {tensor_dir}\"\n                return\n            if not os.path.isdir(tensor_dir):\n                yield 0, 0.0, f\"❌ Tensor directory not found: {tensor_dir}\"\n                return\n\n            # Create training module\n            torch.manual_seed(self.training_config.seed)\n            random.seed(self.training_config.seed)\n            if torch.cuda.is_available():\n                torch.cuda.manual_seed_all(self.training_config.seed)\n            try:\n                import numpy as np\n\n                np.random.seed(self.training_config.seed)\n            except Exception:\n                pass\n\n            self.module = PreprocessedLoRAModule(\n                model=self.dit_handler.model,\n                lora_config=self.lora_config,\n                training_config=self.training_config,\n                device=self.dit_handler.device,\n                dtype=self.dit_handler.dtype,\n            )\n            ckpt_enabled, cache_disabled, input_grads_enabled = (\n                _configure_training_memory_features(self.module.model.decoder)\n            )\n            # DiT decoder does not expose token embeddings like causal LMs.\n            # Force grad-carrying inputs for checkpointed segments to avoid\n            # detached losses regardless of wrapper hook availability.\n            self.module.force_input_grads_for_checkpointing = ckpt_enabled\n            logger.info(\n                f\"Training memory features: gradient_checkpointing={ckpt_enabled}, \"\n                f\"use_cache_disabled={cache_disabled}, input_grads_enabled={input_grads_enabled}\"\n            )\n\n            # Create data module\n            data_module = PreprocessedDataModule(\n                tensor_dir=tensor_dir,\n                batch_size=self.training_config.batch_size,\n                num_workers=self.training_config.num_workers,\n                pin_memory=self.training_config.pin_memory,\n                prefetch_factor=self.training_config.prefetch_factor,\n                persistent_workers=self.training_config.persistent_workers,\n                pin_memory_device=self.training_config.pin_memory_device,\n                val_split=getattr(self.training_config, \"val_split\", 0.0),\n            )\n\n            # Setup data\n            data_module.setup(\"fit\")\n\n            if len(data_module.train_dataset) == 0:\n                yield 0, 0.0, \"❌ No valid samples found in tensor directory\"\n                return\n\n            yield (\n                0,\n                0.0,\n                f\"📂 Loaded {len(data_module.train_dataset)} preprocessed samples\",\n            )\n            if ckpt_enabled:\n                yield 0, 0.0, \"🧠 Gradient checkpointing enabled for decoder\"\n            else:\n                yield (\n                    0,\n                    0.0,\n                    \"⚠️ Gradient checkpointing not enabled (model wrapper did not expose it)\",\n                )\n            if not input_grads_enabled:\n                yield (\n                    0,\n                    0.0,\n                    \"ℹ️ Input-grad hook not available on this DiT; using explicit checkpointing fallback\",\n                )\n\n            if LIGHTNING_AVAILABLE:\n                yield from self._train_with_fabric(\n                    data_module, training_state, resume_from\n                )\n            else:\n                yield from self._train_basic(data_module, training_state)\n\n        except Exception as e:\n            logger.exception(\"Training failed\")\n            yield 0, 0.0, f\"❌ Training failed: {str(e)}\"\n        finally:\n            self.is_training = False\n\n    def _train_with_fabric(\n        self,\n        data_module: PreprocessedDataModule,\n        training_state: Optional[Dict],\n        resume_from: Optional[str] = None,\n    ) -> Generator[Tuple[int, float, str], None, None]:\n        \"\"\"Train using Lightning Fabric.\"\"\"\n        # Create output directory\n        os.makedirs(self.training_config.output_dir, exist_ok=True)\n\n        device_type = self.module.device_type\n        precision = _select_fabric_precision(device_type)\n        accelerator = (\n            device_type if device_type in (\"cuda\", \"xpu\", \"mps\", \"cpu\") else \"auto\"\n        )\n\n        # Create TensorBoard logger when available; continue without it otherwise.\n        tb_logger = None\n        try:\n            tb_logger = TensorBoardLogger(\n                root_dir=self.training_config.output_dir, name=\"logs\"\n            )\n        except ModuleNotFoundError as e:\n            logger.warning(\n                f\"TensorBoard logger unavailable, continuing without logger: {e}\"\n            )\n\n        # Initialize Fabric\n        fabric_kwargs = {\n            \"accelerator\": accelerator,\n            \"devices\": 1,\n            \"precision\": precision,\n        }\n        if tb_logger is not None:\n            fabric_kwargs[\"loggers\"] = [tb_logger]\n        self.fabric = Fabric(**fabric_kwargs)\n        self.fabric.launch()\n\n        yield (\n            0,\n            0.0,\n            f\"🚀 Starting training (device: {device_type}, precision: {precision})...\",\n        )\n\n        # Keep decoder weights in a stable dtype before optimizer/Fabric setup.\n        # MPS stays in fp32 weights for stability; computation still uses fp16\n        # autocast inside training_step.\n        if device_type == \"mps\" or precision.endswith(\"-mixed\"):\n            self.module.model.decoder = self.module.model.decoder.to(\n                dtype=torch.float32\n            )\n        else:\n            self.module.model.decoder = self.module.model.decoder.to(\n                dtype=self.module.dtype\n            )\n        casted_trainable, total_trainable_tensors = _ensure_trainable_params_fp32(\n            self.module.model.decoder\n        )\n        logger.info(\n            f\"Trainable tensor dtype fixup: casted {casted_trainable}/{total_trainable_tensors} to fp32\"\n        )\n\n        # Get dataloader\n        train_loader = data_module.train_dataloader()\n        val_loader = (\n            data_module.val_dataloader()\n            if hasattr(data_module, \"val_dataloader\")\n            else None\n        )\n\n        if training_state is not None:\n            training_state[\"plot_steps\"] = []\n            training_state[\"plot_loss\"] = []\n            training_state[\"plot_ema\"] = []\n            training_state[\"plot_val_steps\"] = []\n            training_state[\"plot_val_loss\"] = []\n            training_state[\"plot_best_step\"] = None\n        ema_loss = None\n        ema_alpha = 0.1\n        best_val_loss = float(\"inf\")\n        best_val_step = None\n\n        # Setup optimizer - only LoRA parameters\n        trainable_params = [\n            p for p in self.module.model.parameters() if p.requires_grad\n        ]\n\n        if not trainable_params:\n            yield 0, 0.0, \"❌ No trainable parameters found!\"\n            return\n\n        yield (\n            0,\n            0.0,\n            f\"🎯 Training {sum(p.numel() for p in trainable_params):,} parameters\",\n        )\n\n        optimizer_kwargs = {\n            \"lr\": self.training_config.learning_rate,\n            \"weight_decay\": self.training_config.weight_decay,\n        }\n\n        # Optimizer selection: AdamW 8-bit vs Standard AdamW\n        if HAS_BNB and device_type == \"cuda\":\n            logger.info(\"train_with_fabric using bitsandbytes 8-bit AdamW optimizer\")\n            optimizer = bnb.optim.AdamW8bit(trainable_params, **optimizer_kwargs)\n        else:\n            if self.module.device.type == \"cuda\":\n                optimizer_kwargs[\"fused\"] = True\n            optimizer = AdamW(trainable_params, **optimizer_kwargs)\n\n        # Calculate total steps\n        steps_per_epoch = max(\n            1,\n            math.ceil(\n                len(train_loader) / self.training_config.gradient_accumulation_steps\n            ),\n        )\n        total_steps = steps_per_epoch * self.training_config.max_epochs\n        warmup_steps = min(self.training_config.warmup_steps, max(1, total_steps // 10))\n\n        # Scheduler\n        warmup_scheduler = LinearLR(\n            optimizer,\n            start_factor=0.1,\n            end_factor=1.0,\n            total_iters=warmup_steps,\n        )\n\n        main_scheduler = CosineAnnealingWarmRestarts(\n            optimizer,\n            T_0=max(1, total_steps - warmup_steps),\n            T_mult=1,\n            eta_min=self.training_config.learning_rate * 0.01,\n        )\n\n        scheduler = SequentialLR(\n            optimizer,\n            schedulers=[warmup_scheduler, main_scheduler],\n            milestones=[warmup_steps],\n        )\n\n        # Setup with Fabric - only the decoder (which has LoRA)\n        self.module.model.decoder, optimizer = self.fabric.setup(\n            self.module.model.decoder, optimizer\n        )\n        casted_opt_params, total_opt_params = _ensure_optimizer_params_fp32(optimizer)\n        logger.info(\n            f\"Optimizer param dtype fixup: casted {casted_opt_params}/{total_opt_params} to fp32\"\n        )\n        train_loader = self.fabric.setup_dataloaders(train_loader)\n\n        # Handle resume from checkpoint (load AFTER Fabric setup)\n        start_epoch = 0\n        global_step = 0\n        checkpoint_info = None\n\n        if resume_from:\n            try:\n                resume_from = safe_path(resume_from)\n            except ValueError:\n                yield (\n                    0,\n                    0.0,\n                    f\"⚠️ Rejected unsafe checkpoint path: {resume_from}, starting fresh\",\n                )\n                resume_from = None\n        if resume_from and os.path.exists(resume_from):\n            try:\n                yield 0, 0.0, f\"🔄 Loading checkpoint from {resume_from}...\"\n\n                # Load checkpoint using utility function\n                checkpoint_info = load_training_checkpoint(\n                    resume_from,\n                    optimizer=optimizer,\n                    scheduler=scheduler,\n                    device=self.module.device,\n                )\n\n                if checkpoint_info[\"adapter_path\"]:\n                    adapter_path = checkpoint_info[\"adapter_path\"]\n                    adapter_weights_path = os.path.join(\n                        adapter_path, \"adapter_model.safetensors\"\n                    )\n                    if not os.path.exists(adapter_weights_path):\n                        adapter_weights_path = os.path.join(\n                            adapter_path, \"adapter_model.bin\"\n                        )\n\n                    if os.path.exists(adapter_weights_path):\n                        # Load adapter weights\n                        from safetensors.torch import load_file\n\n                        if adapter_weights_path.endswith(\".safetensors\"):\n                            state_dict = load_file(adapter_weights_path)\n                        else:\n                            state_dict = torch.load(\n                                adapter_weights_path,\n                                map_location=self.module.device,\n                                weights_only=True,\n                            )\n\n                        # Get the decoder (might be wrapped by Fabric)\n                        decoder = self.module.model.decoder\n                        if hasattr(decoder, \"_forward_module\"):\n                            decoder = decoder._forward_module\n\n                        decoder.load_state_dict(state_dict, strict=False)\n\n                        start_epoch = checkpoint_info[\"epoch\"]\n                        global_step = checkpoint_info[\"global_step\"]\n\n                        status_parts = [\n                            f\"✅ Resumed from epoch {start_epoch}, step {global_step}\"\n                        ]\n                        if checkpoint_info[\"loaded_optimizer\"]:\n                            status_parts.append(\"optimizer ✓\")\n                        if checkpoint_info[\"loaded_scheduler\"]:\n                            status_parts.append(\"scheduler ✓\")\n                        yield 0, 0.0, \", \".join(status_parts)\n                    else:\n                        yield 0, 0.0, f\"⚠️ Adapter weights not found in {adapter_path}\"\n                else:\n                    yield 0, 0.0, f\"⚠️ No valid checkpoint found in {resume_from}\"\n\n            except Exception as e:\n                logger.exception(\"Failed to load checkpoint\")\n                yield 0, 0.0, f\"⚠️ Failed to load checkpoint: {e}, starting fresh\"\n                start_epoch = 0\n                global_step = 0\n        elif resume_from:\n            yield 0, 0.0, f\"⚠️ Checkpoint path not found: {resume_from}, starting fresh\"\n\n        # Training loop\n        accumulation_step = 0\n        accumulated_loss = 0.0\n        optimizer.zero_grad(set_to_none=True)\n\n        self.module.model.decoder.train()\n\n        for epoch in range(start_epoch, self.training_config.max_epochs):\n            epoch_loss = 0.0\n            num_updates = 0\n            epoch_start_time = time.time()\n\n            for _batch_idx, batch in enumerate(train_loader):\n                # Check for stop signal\n                if training_state and training_state.get(\"should_stop\", False):\n                    yield (\n                        global_step,\n                        accumulated_loss / max(accumulation_step, 1),\n                        \"⏹️ Training stopped by user\",\n                    )\n                    return\n\n                # Forward pass\n                loss = self.module.training_step(batch)\n                loss = loss / self.training_config.gradient_accumulation_steps\n\n                # Backward pass\n                self.fabric.backward(loss)\n                accumulated_loss += loss.item()\n                accumulation_step += 1\n\n                # Optimizer step\n                if (\n                    accumulation_step\n                    >= self.training_config.gradient_accumulation_steps\n                ):\n                    nonfinite_grads, grad_tensors = _count_nonfinite_grads(\n                        trainable_params\n                    )\n                    if nonfinite_grads > 0:\n                        optimizer.zero_grad(set_to_none=True)\n                        yield (\n                            global_step,\n                            float(\"nan\"),\n                            (\n                                f\"⚠️ Non-finite gradients ({nonfinite_grads}/{grad_tensors}); \"\n                                \"skipping optimizer step\"\n                            ),\n                        )\n                        accumulated_loss = 0.0\n                        accumulation_step = 0\n                        continue\n\n                    self.fabric.clip_gradients(\n                        self.module.model.decoder,\n                        optimizer,\n                        max_norm=self.training_config.max_grad_norm,\n                        error_if_nonfinite=False,\n                    )\n\n                    optimizer.step()\n                    scheduler.step()\n                    optimizer.zero_grad(set_to_none=True)\n\n                    global_step += 1\n\n                    # Log\n                    avg_loss = accumulated_loss / accumulation_step\n                    if global_step % self.training_config.log_every_n_steps == 0:\n                        if training_state is not None:\n                            if ema_loss is None:\n                                ema_loss = avg_loss\n                            else:\n                                ema_loss = (\n                                    ema_alpha * avg_loss + (1 - ema_alpha) * ema_loss\n                                )\n                            training_state[\"plot_steps\"].append(global_step)\n                            training_state[\"plot_loss\"].append(avg_loss)\n                            training_state[\"plot_ema\"].append(ema_loss)\n                        self.fabric.log(\"train/loss\", avg_loss, step=global_step)\n                        self.fabric.log(\n                            \"train/lr\", scheduler.get_last_lr()[0], step=global_step\n                        )\n                        yield (\n                            global_step,\n                            avg_loss,\n                            f\"Epoch {epoch + 1}/{self.training_config.max_epochs}, Step {global_step}, Loss: {avg_loss:.4f}\",\n                        )\n\n                    epoch_loss += avg_loss\n                    num_updates += 1\n                    accumulated_loss = 0.0\n                    accumulation_step = 0\n\n            # Flush remainder to avoid dropping gradients when epoch length is not\n            # divisible by gradient_accumulation_steps.\n            if accumulation_step > 0:\n                nonfinite_grads, grad_tensors = _count_nonfinite_grads(trainable_params)\n                if nonfinite_grads > 0:\n                    optimizer.zero_grad(set_to_none=True)\n                    yield (\n                        global_step,\n                        float(\"nan\"),\n                        (\n                            f\"⚠️ Non-finite gradients ({nonfinite_grads}/{grad_tensors}); \"\n                            \"skipping optimizer remainder step\"\n                        ),\n                    )\n                    accumulated_loss = 0.0\n                    accumulation_step = 0\n                else:\n                    self.fabric.clip_gradients(\n                        self.module.model.decoder,\n                        optimizer,\n                        max_norm=self.training_config.max_grad_norm,\n                        error_if_nonfinite=False,\n                    )\n\n                    optimizer.step()\n                    scheduler.step()\n                    optimizer.zero_grad(set_to_none=True)\n\n                global_step += 1\n                avg_loss = accumulated_loss / accumulation_step\n                if global_step % self.training_config.log_every_n_steps == 0:\n                    if training_state is not None:\n                        if ema_loss is None:\n                            ema_loss = avg_loss\n                        else:\n                            ema_loss = ema_alpha * avg_loss + (1 - ema_alpha) * ema_loss\n                        training_state[\"plot_steps\"].append(global_step)\n                        training_state[\"plot_loss\"].append(avg_loss)\n                        training_state[\"plot_ema\"].append(ema_loss)\n                    self.fabric.log(\"train/loss\", avg_loss, step=global_step)\n                    self.fabric.log(\n                        \"train/lr\", scheduler.get_last_lr()[0], step=global_step\n                    )\n                    yield (\n                        global_step,\n                        avg_loss,\n                        f\"Epoch {epoch + 1}/{self.training_config.max_epochs}, Step {global_step}, Loss: {avg_loss:.4f}\",\n                    )\n\n                    epoch_loss += avg_loss\n                    num_updates += 1\n                    accumulated_loss = 0.0\n                    accumulation_step = 0\n\n            # End of epoch\n            epoch_time = time.time() - epoch_start_time\n            avg_epoch_loss = epoch_loss / max(num_updates, 1)\n            if training_state is not None:\n                if ema_loss is None:\n                    ema_loss = avg_epoch_loss\n                else:\n                    ema_loss = ema_alpha * avg_epoch_loss + (1 - ema_alpha) * ema_loss\n                # Avoid duplicating the last step if it was already logged in the batch loop\n                plot_steps = training_state[\"plot_steps\"]\n                if not plot_steps or plot_steps[-1] != global_step:\n                    training_state[\"plot_steps\"].append(global_step)\n                    training_state[\"plot_loss\"].append(avg_epoch_loss)\n                    training_state[\"plot_ema\"].append(ema_loss)\n            self.fabric.log(\"train/epoch_loss\", avg_epoch_loss, step=epoch + 1)\n\n            # Validation and best checkpoint (if validation set exists)\n            if val_loader is not None:\n                self.module.model.decoder.eval()\n                total_val_loss = 0.0\n                n_val = 0\n                with torch.no_grad():\n                    for val_batch in val_loader:\n                        v_loss = self.module.training_step(val_batch, record_loss=False)\n                        total_val_loss += v_loss.item()\n                        n_val += 1\n                self.module.model.decoder.train()\n                val_loss = total_val_loss / max(n_val, 1)\n                if training_state is not None:\n                    training_state[\"plot_val_steps\"].append(global_step)\n                    training_state[\"plot_val_loss\"].append(val_loss)\n                if val_loss < best_val_loss:\n                    best_val_loss = val_loss\n                    best_val_step = global_step\n                    if training_state is not None:\n                        training_state[\"plot_best_step\"] = best_val_step\n                    best_dir = os.path.join(\n                        self.training_config.output_dir, \"checkpoints\", \"best\"\n                    )\n                    save_training_checkpoint(\n                        self.module.model,\n                        optimizer,\n                        scheduler,\n                        epoch + 1,\n                        global_step,\n                        best_dir,\n                    )\n\n            # Save checkpoint\n            if (epoch + 1) % self.training_config.save_every_n_epochs == 0:\n                checkpoint_dir = os.path.join(\n                    self.training_config.output_dir, \"checkpoints\", f\"epoch_{epoch + 1}_loss_{avg_epoch_loss:.4f}\"\n                )\n                save_training_checkpoint(\n                    self.module.model,\n                    optimizer,\n                    scheduler,\n                    epoch + 1,\n                    global_step,\n                    checkpoint_dir,\n                )\n                yield (\n                    global_step,\n                    avg_epoch_loss,\n                    f\"💾 Checkpoint saved at epoch {epoch + 1}\",\n                )\n\n        # Save final model\n        final_path = os.path.join(self.training_config.output_dir, \"final\")\n        save_lora_weights(self.module.model, final_path)\n\n        final_loss = (\n            self.module.training_losses[-1] if self.module.training_losses else 0.0\n        )\n        yield (\n            global_step,\n            final_loss,\n            f\"✅ Training complete! LoRA saved to {final_path}\",\n        )\n\n    def _train_basic(\n        self,\n        data_module: PreprocessedDataModule,\n        training_state: Optional[Dict],\n    ) -> Generator[Tuple[int, float, str], None, None]:\n        \"\"\"Basic training loop without Fabric.\"\"\"\n        yield 0, 0.0, \"🚀 Starting basic training loop...\"\n\n        os.makedirs(self.training_config.output_dir, exist_ok=True)\n\n        train_loader = data_module.train_dataloader()\n\n        trainable_params = [\n            p for p in self.module.model.parameters() if p.requires_grad\n        ]\n\n        if not trainable_params:\n            yield 0, 0.0, \"❌ No trainable parameters found!\"\n            return\n\n        if HAS_BNB and self.module.device_type == \"cuda\":\n            optimizer = bnb.optim.AdamW8bit(\n                trainable_params,\n                lr=self.training_config.learning_rate,\n                weight_decay=self.training_config.weight_decay,\n            )\n            logger.info(\"train_basic using bitsandbytes 8-bit AdamW optimizer\")\n        else:\n            optimizer = AdamW(\n                trainable_params,\n                lr=self.training_config.learning_rate,\n                weight_decay=self.training_config.weight_decay,\n            )\n\n        steps_per_epoch = max(\n            1,\n            math.ceil(\n                len(train_loader) / self.training_config.gradient_accumulation_steps\n            ),\n        )\n        total_steps = steps_per_epoch * self.training_config.max_epochs\n        warmup_steps = min(self.training_config.warmup_steps, max(1, total_steps // 10))\n\n        warmup_scheduler = LinearLR(\n            optimizer, start_factor=0.1, end_factor=1.0, total_iters=warmup_steps\n        )\n        main_scheduler = CosineAnnealingWarmRestarts(\n            optimizer,\n            T_0=max(1, total_steps - warmup_steps),\n            T_mult=1,\n            eta_min=self.training_config.learning_rate * 0.01,\n        )\n        scheduler = SequentialLR(\n            optimizer,\n            schedulers=[warmup_scheduler, main_scheduler],\n            milestones=[warmup_steps],\n        )\n\n        global_step = 0\n        accumulation_step = 0\n        accumulated_loss = 0.0\n        optimizer.zero_grad(set_to_none=True)\n\n        self.module.model.decoder.train()\n\n        for epoch in range(self.training_config.max_epochs):\n            epoch_loss = 0.0\n            num_updates = 0\n            epoch_start_time = time.time()\n\n            for batch in train_loader:\n                if training_state and training_state.get(\"should_stop\", False):\n                    yield (\n                        global_step,\n                        accumulated_loss / max(accumulation_step, 1),\n                        \"⏹️ Training stopped\",\n                    )\n                    return\n\n                loss = self.module.training_step(batch)\n                loss = loss / self.training_config.gradient_accumulation_steps\n                loss.backward()\n                accumulated_loss += loss.item()\n                accumulation_step += 1\n\n                if (\n                    accumulation_step\n                    >= self.training_config.gradient_accumulation_steps\n                ):\n                    torch.nn.utils.clip_grad_norm_(\n                        trainable_params, self.training_config.max_grad_norm\n                    )\n                    optimizer.step()\n                    scheduler.step()\n                    optimizer.zero_grad(set_to_none=True)\n                    global_step += 1\n\n                    avg_loss = accumulated_loss / accumulation_step\n                    if global_step % self.training_config.log_every_n_steps == 0:\n                        yield (\n                            global_step,\n                            avg_loss,\n                            f\"Epoch {epoch + 1}, Step {global_step}, Loss: {avg_loss:.4f}\",\n                        )\n\n                    epoch_loss += avg_loss\n                    num_updates += 1\n                    accumulated_loss = 0.0\n                    accumulation_step = 0\n\n            if accumulation_step > 0:\n                torch.nn.utils.clip_grad_norm_(\n                    trainable_params, self.training_config.max_grad_norm\n                )\n                optimizer.step()\n                scheduler.step()\n                optimizer.zero_grad(set_to_none=True)\n                global_step += 1\n\n                avg_loss = accumulated_loss / accumulation_step\n                if global_step % self.training_config.log_every_n_steps == 0:\n                    yield (\n                        global_step,\n                        avg_loss,\n                        f\"Epoch {epoch + 1}, Step {global_step}, Loss: {avg_loss:.4f}\",\n                    )\n\n                epoch_loss += avg_loss\n                num_updates += 1\n                accumulated_loss = 0.0\n                accumulation_step = 0\n\n            epoch_time = time.time() - epoch_start_time\n            avg_epoch_loss = epoch_loss / max(num_updates, 1)\n            yield (\n                global_step,\n                avg_epoch_loss,\n                f\"✅ Epoch {epoch + 1}/{self.training_config.max_epochs} in {epoch_time:.1f}s\",\n            )\n\n            if (epoch + 1) % self.training_config.save_every_n_epochs == 0:\n                checkpoint_dir = os.path.join(\n                    self.training_config.output_dir, \"checkpoints\", f\"epoch_{epoch + 1}_loss_{avg_epoch_loss:.4f}\"\n                )\n                save_lora_weights(self.module.model, checkpoint_dir)\n                yield global_step, avg_epoch_loss, \"💾 Checkpoint saved\"\n\n        final_path = os.path.join(self.training_config.output_dir, \"final\")\n        save_lora_weights(self.module.model, final_path)\n        final_loss = (\n            self.module.training_losses[-1] if self.module.training_losses else 0.0\n        )\n        yield (\n            global_step,\n            final_loss,\n            f\"✅ Training complete! LoRA saved to {final_path}\",\n        )\n\n    def stop(self):\n        \"\"\"Stop training.\"\"\"\n        self.is_training = False\n\n\nclass PreprocessedLoKRModule(nn.Module):\n    \"\"\"LoKr training module using preprocessed tensors.\"\"\"\n\n    def __init__(\n        self,\n        model: nn.Module,\n        lokr_config: LoKRConfig,\n        training_config: TrainingConfig,\n        device: torch.device,\n        dtype: torch.dtype,\n    ):\n        super().__init__()\n\n        self.lokr_config = lokr_config\n        self.training_config = training_config\n        self.device = torch.device(device) if isinstance(device, str) else device\n        self.device_type = _normalize_device_type(self.device)\n        self.dtype = _select_compute_dtype(self.device_type)\n        self.transfer_non_blocking = self.device_type in (\"cuda\", \"xpu\")\n        self.timesteps_tensor = torch.tensor(\n            TURBO_SHIFT3_TIMESTEPS, device=self.device, dtype=self.dtype\n        )\n        self.force_input_grads_for_checkpointing = False\n        self.lycoris_net = None\n\n        if check_lycoris_available():\n            self.model, self.lycoris_net, self.lokr_info = inject_lokr_into_dit(\n                model, lokr_config\n            )\n            logger.info(\n                f\"LoKr injected: {self.lokr_info['trainable_params']:,} trainable params\"\n            )\n        else:\n            self.model = model\n            self.lokr_info = {}\n            logger.warning(\"LyCORIS not available, training without LoKr adapters\")\n\n        self.config = model.config\n        self.training_losses = []\n\n    def training_step(self, batch: Dict[str, torch.Tensor]) -> torch.Tensor:\n        \"\"\"Single LoKr training step.\"\"\"\n        if self.device_type in (\"cuda\", \"xpu\", \"mps\"):\n            autocast_ctx = torch.autocast(\n                device_type=self.device_type, dtype=self.dtype\n            )\n        else:\n            autocast_ctx = nullcontext()\n\n        with autocast_ctx:\n            target_latents = batch[\"target_latents\"].to(\n                self.device, dtype=self.dtype, non_blocking=self.transfer_non_blocking\n            )\n            attention_mask = batch[\"attention_mask\"].to(\n                self.device, dtype=self.dtype, non_blocking=self.transfer_non_blocking\n            )\n            encoder_hidden_states = batch[\"encoder_hidden_states\"].to(\n                self.device, dtype=self.dtype, non_blocking=self.transfer_non_blocking\n            )\n            encoder_attention_mask = batch[\"encoder_attention_mask\"].to(\n                self.device, dtype=self.dtype, non_blocking=self.transfer_non_blocking\n            )\n            context_latents = batch[\"context_latents\"].to(\n                self.device, dtype=self.dtype, non_blocking=self.transfer_non_blocking\n            )\n\n            bsz = target_latents.shape[0]\n            x1 = torch.randn_like(target_latents)\n            x0 = target_latents\n\n            t, _ = sample_discrete_timestep(bsz, self.timesteps_tensor)\n            t_ = t.unsqueeze(-1).unsqueeze(-1)\n            xt = t_ * x1 + (1.0 - t_) * x0\n            if self.force_input_grads_for_checkpointing:\n                xt = xt.requires_grad_(True)\n\n            decoder_outputs = self.model.decoder(\n                hidden_states=xt,\n                timestep=t,\n                timestep_r=t,\n                attention_mask=attention_mask,\n                encoder_hidden_states=encoder_hidden_states,\n                encoder_attention_mask=encoder_attention_mask,\n                context_latents=context_latents,\n            )\n\n            flow = x1 - x0\n            diffusion_loss = F.mse_loss(decoder_outputs[0], flow)\n\n        diffusion_loss = diffusion_loss.float()\n        self.training_losses.append(diffusion_loss.item())\n        return diffusion_loss\n\n\nclass LoKRTrainer:\n    \"\"\"High-level trainer for ACE-Step LoKr fine-tuning.\"\"\"\n\n    def __init__(\n        self,\n        dit_handler,\n        lokr_config: LoKRConfig,\n        training_config: TrainingConfig,\n    ):\n        self.dit_handler = dit_handler\n        self.lokr_config = lokr_config\n        # Validate output_dir early so all downstream path operations are safe\n        training_config.output_dir = safe_path(training_config.output_dir)\n        self.training_config = training_config\n\n        self.module = None\n        self.fabric = None\n        self.is_training = False\n        self.run_metadata: Dict[str, Any] = {}\n\n    def train_from_preprocessed(\n        self,\n        tensor_dir: str,\n        training_state: Optional[Dict] = None,\n    ) -> Generator[Tuple[int, float, str], None, None]:\n        \"\"\"Train LoKr adapters from preprocessed tensors.\"\"\"\n        self.is_training = True\n        try:\n            if _unwrap_stale_fabric_decoder(self.dit_handler.model):\n                logger.info(\n                    \"Unwrapped stale Fabric decoder wrapper before LoKr training\"\n                )\n\n            quantization_mode = getattr(self.dit_handler, \"quantization\", None)\n            if quantization_mode is not None:\n                yield (\n                    0,\n                    0.0,\n                    (\n                        \"❌ LoKr training requires a non-quantized DiT model. \"\n                        f\"Current quantization: {quantization_mode}. \"\n                        \"Re-initialize service with INT8 Quantization disabled, then retry training.\"\n                    ),\n                )\n                return\n\n            try:\n                tensor_dir = safe_path(tensor_dir)\n            except ValueError:\n                yield 0, 0.0, f\"❌ Rejected unsafe tensor directory: {tensor_dir}\"\n                return\n            if not os.path.isdir(tensor_dir):\n                yield 0, 0.0, f\"❌ Tensor directory not found: {tensor_dir}\"\n                return\n\n            if not check_lycoris_available():\n                yield (\n                    0,\n                    0.0,\n                    \"❌ LyCORIS not installed. Install lycoris-lora to train LoKr.\",\n                )\n                return\n\n            torch.manual_seed(self.training_config.seed)\n            random.seed(self.training_config.seed)\n            if torch.cuda.is_available():\n                torch.cuda.manual_seed_all(self.training_config.seed)\n            try:\n                import numpy as np\n\n                np.random.seed(self.training_config.seed)\n            except Exception:\n                pass\n\n            self.module = PreprocessedLoKRModule(\n                model=self.dit_handler.model,\n                lokr_config=self.lokr_config,\n                training_config=self.training_config,\n                device=self.dit_handler.device,\n                dtype=self.dit_handler.dtype,\n            )\n            ckpt_enabled, cache_disabled, input_grads_enabled = (\n                _configure_training_memory_features(self.module.model.decoder)\n            )\n            self.module.force_input_grads_for_checkpointing = ckpt_enabled\n            logger.info(\n                f\"Training memory features: gradient_checkpointing={ckpt_enabled}, \"\n                f\"use_cache_disabled={cache_disabled}, input_grads_enabled={input_grads_enabled}\"\n            )\n\n            data_module = PreprocessedDataModule(\n                tensor_dir=tensor_dir,\n                batch_size=self.training_config.batch_size,\n                num_workers=self.training_config.num_workers,\n                pin_memory=self.training_config.pin_memory,\n                prefetch_factor=self.training_config.prefetch_factor,\n                persistent_workers=self.training_config.persistent_workers,\n                pin_memory_device=self.training_config.pin_memory_device,\n                val_split=self.training_config.val_split,\n            )\n            data_module.setup(\"fit\")\n\n            if len(data_module.train_dataset) == 0:\n                yield 0, 0.0, \"❌ No valid samples found in tensor directory\"\n                return\n\n            self.run_metadata = {\n                \"tensor_dir\": tensor_dir,\n                \"num_samples\": int(len(data_module.train_dataset)),\n                \"training_config\": self.training_config.to_dict(),\n            }\n\n            yield (\n                0,\n                0.0,\n                f\"📂 Loaded {len(data_module.train_dataset)} preprocessed samples\",\n            )\n            if ckpt_enabled:\n                yield 0, 0.0, \"🧠 Gradient checkpointing enabled for decoder\"\n            else:\n                yield (\n                    0,\n                    0.0,\n                    \"⚠️ Gradient checkpointing not enabled (model wrapper did not expose it)\",\n                )\n            if not input_grads_enabled:\n                yield (\n                    0,\n                    0.0,\n                    \"ℹ️ Input-grad hook not available on this DiT; using explicit checkpointing fallback\",\n                )\n\n            if LIGHTNING_AVAILABLE:\n                yield from self._train_with_fabric(data_module, training_state)\n            else:\n                yield from self._train_basic(data_module, training_state)\n\n        except Exception as e:\n            logger.exception(\"LoKr training failed\")\n            yield 0, 0.0, f\"❌ Training failed: {str(e)}\"\n        finally:\n            if self.module is not None and hasattr(self.module, \"model\"):\n                _unwrap_stale_fabric_decoder(self.module.model)\n            if (\n                getattr(self, \"dit_handler\", None) is not None\n                and getattr(self.dit_handler, \"model\", None) is not None\n            ):\n                _unwrap_stale_fabric_decoder(self.dit_handler.model)\n            self.is_training = False\n\n    def _train_with_fabric(\n        self,\n        data_module: PreprocessedDataModule,\n        training_state: Optional[Dict],\n    ) -> Generator[Tuple[int, float, str], None, None]:\n        os.makedirs(self.training_config.output_dir, exist_ok=True)\n\n        device_type = self.module.device_type\n        precision = _select_fabric_precision(device_type)\n        accelerator = (\n            device_type if device_type in (\"cuda\", \"xpu\", \"mps\", \"cpu\") else \"auto\"\n        )\n        manual_nonfinite_check = not precision.endswith(\"-mixed\")\n\n        tb_logger = None\n        try:\n            tb_logger = TensorBoardLogger(\n                root_dir=self.training_config.output_dir,\n                name=\"logs\",\n            )\n        except ModuleNotFoundError as exc:\n            logger.warning(\n                f\"TensorBoard logger unavailable, continuing without logger: {exc}\"\n            )\n\n        fabric_kwargs = {\n            \"accelerator\": accelerator,\n            \"devices\": 1,\n            \"precision\": precision,\n        }\n        if tb_logger is not None:\n            fabric_kwargs[\"loggers\"] = [tb_logger]\n        self.fabric = Fabric(**fabric_kwargs)\n        self.fabric.launch()\n\n        yield (\n            0,\n            0.0,\n            f\"🚀 Starting training (device: {device_type}, precision: {precision})...\",\n        )\n        if not manual_nonfinite_check:\n            logger.info(\n                \"LoKr mixed precision detected: disabling pre-unscale non-finite grad checks; \"\n                \"relying on AMP/GradScaler handling.\"\n            )\n\n        if device_type == \"mps\" or precision.endswith(\"-mixed\"):\n            self.module.model.decoder = self.module.model.decoder.to(\n                dtype=torch.float32\n            )\n        else:\n            self.module.model.decoder = self.module.model.decoder.to(\n                dtype=self.module.dtype\n            )\n        casted_trainable, total_trainable_tensors = _ensure_trainable_params_fp32(\n            self.module.model.decoder\n        )\n        if (\n            total_trainable_tensors == 0\n            and getattr(self.module, \"lycoris_net\", None) is not None\n        ):\n            casted_fallback, total_fallback = _ensure_trainable_params_fp32(\n                self.module.lycoris_net\n            )\n            casted_trainable += casted_fallback\n            total_trainable_tensors += total_fallback\n        logger.info(\n            f\"Trainable tensor dtype fixup: casted {casted_trainable}/{total_trainable_tensors} to fp32\"\n        )\n\n        train_loader = data_module.train_dataloader()\n        trainable_params = _collect_lokr_trainable_params(\n            self.module.model,\n            getattr(self.module, \"lycoris_net\", None),\n        )\n        param_name_lookup = _build_param_name_lookup(\n            self.module.model,\n            getattr(self.module, \"lycoris_net\", None),\n        )\n\n        if not trainable_params:\n            yield 0, 0.0, \"❌ No trainable parameters found!\"\n            return\n        if total_trainable_tensors == 0:\n            logger.warning(\n                \"LoKr trainable params discovered via LyCORIS fallback traversal; \"\n                \"decoder parameter traversal returned 0 trainables.\"\n            )\n\n        yield (\n            0,\n            0.0,\n            f\"🎯 Training {sum(p.numel() for p in trainable_params):,} parameters\",\n        )\n\n        optimizer_kwargs = {\n            \"lr\": self.training_config.learning_rate,\n            \"weight_decay\": self.training_config.weight_decay,\n        }\n        if self.module.device.type == \"cuda\":\n            optimizer_kwargs[\"fused\"] = True\n        optimizer = AdamW(trainable_params, **optimizer_kwargs)\n\n        steps_per_epoch = max(\n            1,\n            math.ceil(\n                len(train_loader) / self.training_config.gradient_accumulation_steps\n            ),\n        )\n        total_steps = steps_per_epoch * self.training_config.max_epochs\n        warmup_steps = min(self.training_config.warmup_steps, max(1, total_steps // 10))\n\n        warmup_scheduler = LinearLR(\n            optimizer,\n            start_factor=0.1,\n            end_factor=1.0,\n            total_iters=warmup_steps,\n        )\n        main_scheduler = CosineAnnealingWarmRestarts(\n            optimizer,\n            T_0=max(1, total_steps - warmup_steps),\n            T_mult=1,\n            eta_min=self.training_config.learning_rate * 0.01,\n        )\n        scheduler = SequentialLR(\n            optimizer,\n            schedulers=[warmup_scheduler, main_scheduler],\n            milestones=[warmup_steps],\n        )\n\n        self.module.model.decoder, optimizer = self.fabric.setup(\n            self.module.model.decoder, optimizer\n        )\n        casted_opt_params, total_opt_params = _ensure_optimizer_params_fp32(optimizer)\n        logger.info(\n            f\"Optimizer param dtype fixup: casted {casted_opt_params}/{total_opt_params} to fp32\"\n        )\n        train_loader = self.fabric.setup_dataloaders(train_loader)\n\n        accumulation_step = 0\n        accumulated_loss = 0.0\n        global_step = 0\n        optimizer.zero_grad(set_to_none=True)\n        self.module.model.decoder.train()\n\n        for epoch in range(self.training_config.max_epochs):\n            epoch_loss = 0.0\n            num_updates = 0\n            epoch_start_time = time.time()\n\n            for batch in train_loader:\n                if training_state and training_state.get(\"should_stop\", False):\n                    yield (\n                        global_step,\n                        accumulated_loss / max(accumulation_step, 1),\n                        \"⏹️ Training stopped by user\",\n                    )\n                    return\n\n                loss = self.module.training_step(batch)\n                loss = loss / self.training_config.gradient_accumulation_steps\n\n                self.fabric.backward(loss)\n                accumulated_loss += loss.item()\n                accumulation_step += 1\n\n                if (\n                    accumulation_step\n                    >= self.training_config.gradient_accumulation_steps\n                ):\n                    if manual_nonfinite_check:\n                        nonfinite_grads, grad_tensors, nonfinite_details = (\n                            _count_nonfinite_grads_detailed(\n                                trainable_params,\n                                param_name_lookup,\n                                detail_limit=10,\n                            )\n                        )\n                        if nonfinite_grads > 0:\n                            if nonfinite_details:\n                                logger.warning(\n                                    f\"LoKr non-finite gradients ({nonfinite_grads}/{grad_tensors}) at epoch \"\n                                    f\"{epoch + 1}, step {global_step}. Top offending tensors:\\n\"\n                                    + \"\\n\".join(f\"  - {d}\" for d in nonfinite_details)\n                                )\n                            optimizer.zero_grad(set_to_none=True)\n                            yield (\n                                global_step,\n                                float(\"nan\"),\n                                (\n                                    f\"⚠️ Non-finite gradients ({nonfinite_grads}/{grad_tensors}); \"\n                                    \"skipping optimizer step (see logs for tensor names)\"\n                                ),\n                            )\n                            accumulated_loss = 0.0\n                            accumulation_step = 0\n                            continue\n\n                    self.fabric.clip_gradients(\n                        self.module.model.decoder,\n                        optimizer,\n                        max_norm=self.training_config.max_grad_norm,\n                        error_if_nonfinite=False,\n                    )\n\n                    optimizer.step()\n                    scheduler.step()\n                    optimizer.zero_grad(set_to_none=True)\n                    global_step += 1\n\n                    avg_loss = accumulated_loss / accumulation_step\n                    if global_step % self.training_config.log_every_n_steps == 0:\n                        self.fabric.log(\"train/loss\", avg_loss, step=global_step)\n                        self.fabric.log(\n                            \"train/lr\", scheduler.get_last_lr()[0], step=global_step\n                        )\n                        yield (\n                            global_step,\n                            avg_loss,\n                            (\n                                f\"Epoch {epoch + 1}/{self.training_config.max_epochs}, \"\n                                f\"Step {global_step}, Loss: {avg_loss:.4f}\"\n                            ),\n                        )\n\n                    epoch_loss += avg_loss\n                    num_updates += 1\n                    accumulated_loss = 0.0\n                    accumulation_step = 0\n\n            if accumulation_step > 0:\n                if manual_nonfinite_check:\n                    nonfinite_grads, grad_tensors, nonfinite_details = (\n                        _count_nonfinite_grads_detailed(\n                            trainable_params,\n                            param_name_lookup,\n                            detail_limit=10,\n                        )\n                    )\n                    if nonfinite_grads > 0:\n                        if nonfinite_details:\n                            logger.warning(\n                                f\"LoKr non-finite remainder gradients ({nonfinite_grads}/{grad_tensors}) at epoch \"\n                                f\"{epoch + 1}, step {global_step}. Top offending tensors:\\n\"\n                                + \"\\n\".join(f\"  - {d}\" for d in nonfinite_details)\n                            )\n                        optimizer.zero_grad(set_to_none=True)\n                        yield (\n                            global_step,\n                            float(\"nan\"),\n                            (\n                                f\"⚠️ Non-finite gradients ({nonfinite_grads}/{grad_tensors}); \"\n                                \"skipping optimizer remainder step (see logs for tensor names)\"\n                            ),\n                        )\n                        accumulated_loss = 0.0\n                        accumulation_step = 0\n                        continue\n\n                self.fabric.clip_gradients(\n                    self.module.model.decoder,\n                    optimizer,\n                    max_norm=self.training_config.max_grad_norm,\n                    error_if_nonfinite=False,\n                )\n\n                optimizer.step()\n                scheduler.step()\n                optimizer.zero_grad(set_to_none=True)\n                global_step += 1\n                avg_loss = accumulated_loss / accumulation_step\n                if global_step % self.training_config.log_every_n_steps == 0:\n                    self.fabric.log(\"train/loss\", avg_loss, step=global_step)\n                    self.fabric.log(\n                        \"train/lr\", scheduler.get_last_lr()[0], step=global_step\n                    )\n                    yield (\n                        global_step,\n                        avg_loss,\n                        (\n                            f\"Epoch {epoch + 1}/{self.training_config.max_epochs}, \"\n                            f\"Step {global_step}, Loss: {avg_loss:.4f}\"\n                        ),\n                    )\n\n                epoch_loss += avg_loss\n                num_updates += 1\n                accumulated_loss = 0.0\n                accumulation_step = 0\n\n            epoch_time = time.time() - epoch_start_time\n            avg_epoch_loss = epoch_loss / max(num_updates, 1)\n\n            self.fabric.log(\"train/epoch_loss\", avg_epoch_loss, step=epoch + 1)\n            yield (\n                global_step,\n                avg_epoch_loss,\n                (\n                    f\"✅ Epoch {epoch + 1}/{self.training_config.max_epochs} \"\n                    f\"in {epoch_time:.1f}s, Loss: {avg_epoch_loss:.4f}\"\n                ),\n            )\n\n            if (epoch + 1) % self.training_config.save_every_n_epochs == 0:\n                checkpoint_dir = os.path.join(\n                    self.training_config.output_dir, \"checkpoints\", f\"epoch_{epoch + 1}_loss_{avg_epoch_loss:.4f}\"\n                )\n                save_lokr_training_checkpoint(\n                    self.module.lycoris_net,\n                    optimizer,\n                    scheduler,\n                    epoch + 1,\n                    global_step,\n                    checkpoint_dir,\n                    lokr_config=self.lokr_config,\n                    run_metadata=self.run_metadata,\n                )\n                yield (\n                    global_step,\n                    avg_epoch_loss,\n                    f\"💾 Checkpoint saved at epoch {epoch + 1}\",\n                )\n\n        final_path = os.path.join(self.training_config.output_dir, \"final\")\n        final_metadata: Dict[str, Any] = {\"lokr_config\": self.lokr_config.to_dict()}\n        if self.run_metadata:\n            final_metadata[\"run_metadata\"] = self.run_metadata\n        save_lokr_weights(\n            self.module.lycoris_net,\n            final_path,\n            metadata=final_metadata,\n        )\n        final_loss = (\n            self.module.training_losses[-1] if self.module.training_losses else 0.0\n        )\n        yield (\n            global_step,\n            final_loss,\n            f\"✅ Training complete! LoKr saved to {final_path}\",\n        )\n\n    def _train_basic(\n        self,\n        data_module: PreprocessedDataModule,\n        training_state: Optional[Dict],\n    ) -> Generator[Tuple[int, float, str], None, None]:\n        yield 0, 0.0, \"🚀 Starting basic training loop...\"\n        os.makedirs(self.training_config.output_dir, exist_ok=True)\n\n        train_loader = data_module.train_dataloader()\n        trainable_params = _collect_lokr_trainable_params(\n            self.module.model,\n            getattr(self.module, \"lycoris_net\", None),\n        )\n        if not trainable_params:\n            yield 0, 0.0, \"❌ No trainable parameters found!\"\n            return\n\n        optimizer = AdamW(\n            trainable_params,\n            lr=self.training_config.learning_rate,\n            weight_decay=self.training_config.weight_decay,\n        )\n        steps_per_epoch = max(\n            1,\n            math.ceil(\n                len(train_loader) / self.training_config.gradient_accumulation_steps\n            ),\n        )\n        total_steps = steps_per_epoch * self.training_config.max_epochs\n        warmup_steps = min(self.training_config.warmup_steps, max(1, total_steps // 10))\n\n        warmup_scheduler = LinearLR(\n            optimizer, start_factor=0.1, end_factor=1.0, total_iters=warmup_steps\n        )\n        main_scheduler = CosineAnnealingWarmRestarts(\n            optimizer,\n            T_0=max(1, total_steps - warmup_steps),\n            T_mult=1,\n            eta_min=self.training_config.learning_rate * 0.01,\n        )\n        scheduler = SequentialLR(\n            optimizer,\n            schedulers=[warmup_scheduler, main_scheduler],\n            milestones=[warmup_steps],\n        )\n\n        global_step = 0\n        accumulation_step = 0\n        accumulated_loss = 0.0\n        optimizer.zero_grad(set_to_none=True)\n        self.module.model.decoder.train()\n\n        for epoch in range(self.training_config.max_epochs):\n            epoch_loss = 0.0\n            num_updates = 0\n            epoch_start_time = time.time()\n\n            for batch in train_loader:\n                if training_state and training_state.get(\"should_stop\", False):\n                    yield (\n                        global_step,\n                        accumulated_loss / max(accumulation_step, 1),\n                        \"⏹️ Training stopped\",\n                    )\n                    return\n\n                loss = self.module.training_step(batch)\n                loss = loss / self.training_config.gradient_accumulation_steps\n                loss.backward()\n                accumulated_loss += loss.item()\n                accumulation_step += 1\n\n                if (\n                    accumulation_step\n                    >= self.training_config.gradient_accumulation_steps\n                ):\n                    torch.nn.utils.clip_grad_norm_(\n                        trainable_params, self.training_config.max_grad_norm\n                    )\n                    optimizer.step()\n                    scheduler.step()\n                    optimizer.zero_grad(set_to_none=True)\n                    global_step += 1\n\n                    avg_loss = accumulated_loss / accumulation_step\n                    if global_step % self.training_config.log_every_n_steps == 0:\n                        yield (\n                            global_step,\n                            avg_loss,\n                            f\"Epoch {epoch + 1}, Step {global_step}, Loss: {avg_loss:.4f}\",\n                        )\n\n                    epoch_loss += avg_loss\n                    num_updates += 1\n                    accumulated_loss = 0.0\n                    accumulation_step = 0\n\n            if accumulation_step > 0:\n                torch.nn.utils.clip_grad_norm_(\n                    trainable_params, self.training_config.max_grad_norm\n                )\n                optimizer.step()\n                scheduler.step()\n                optimizer.zero_grad(set_to_none=True)\n                global_step += 1\n\n                avg_loss = accumulated_loss / accumulation_step\n                if global_step % self.training_config.log_every_n_steps == 0:\n                    yield (\n                        global_step,\n                        avg_loss,\n                        f\"Epoch {epoch + 1}, Step {global_step}, Loss: {avg_loss:.4f}\",\n                    )\n\n                epoch_loss += avg_loss\n                num_updates += 1\n                accumulated_loss = 0.0\n                accumulation_step = 0\n\n            epoch_time = time.time() - epoch_start_time\n            avg_epoch_loss = epoch_loss / max(num_updates, 1)\n            yield (\n                global_step,\n                avg_epoch_loss,\n                f\"✅ Epoch {epoch + 1}/{self.training_config.max_epochs} in {epoch_time:.1f}s\",\n            )\n\n            if (epoch + 1) % self.training_config.save_every_n_epochs == 0:\n                checkpoint_dir = os.path.join(\n                    self.training_config.output_dir, \"checkpoints\", f\"epoch_{epoch + 1}_loss_{avg_epoch_loss:.4f}\"\n                )\n                save_lokr_training_checkpoint(\n                    self.module.lycoris_net,\n                    optimizer,\n                    scheduler,\n                    epoch + 1,\n                    global_step,\n                    checkpoint_dir,\n                    lokr_config=self.lokr_config,\n                    run_metadata=self.run_metadata,\n                )\n                yield global_step, avg_epoch_loss, \"💾 Checkpoint saved\"\n\n        final_path = os.path.join(self.training_config.output_dir, \"final\")\n        final_metadata: Dict[str, Any] = {\"lokr_config\": self.lokr_config.to_dict()}\n        if self.run_metadata:\n            final_metadata[\"run_metadata\"] = self.run_metadata\n        save_lokr_weights(\n            self.module.lycoris_net,\n            final_path,\n            metadata=final_metadata,\n        )\n        final_loss = (\n            self.module.training_losses[-1] if self.module.training_losses else 0.0\n        )\n        yield (\n            global_step,\n            final_loss,\n            f\"✅ Training complete! LoKr saved to {final_path}\",\n        )\n\n    def stop(self):\n        \"\"\"Stop training.\"\"\"\n        self.is_training = False\n"
  },
  {
    "path": "acestep/training_v2/__init__.py",
    "content": "\"\"\"\nACE-Step Training V2 (Side-Step) -- Corrected LoRA Fine-Tuning CLI\n\nNon-destructive parallel module providing corrected training procedures\nthat match each model variant's own forward() training logic.\n\nSubcommands:\n    vanilla   -- Reproduce existing (bugged) training for backward compatibility\n    fixed     -- Corrected training: continuous timesteps + CFG dropout\n    estimate  -- Gradient sensitivity analysis (no training)\n\nNote:\n    This is the upstream-integrated version of Side-Step.\n    For the standalone version with additional features and more\n    frequent updates, visit: https://github.com/koda-dernet/Side-Step\n\"\"\"\n\n__version__ = \"2.0.0\"\n"
  },
  {
    "path": "acestep/training_v2/cli/__init__.py",
    "content": "\"\"\"\nCLI package for ACE-Step Training V2.\n\nProvides shared argparse helpers and per-subcommand entry points.\n\"\"\"\n"
  },
  {
    "path": "acestep/training_v2/cli/args.py",
    "content": "\"\"\"\nArgparse construction for ACE-Step Training V2 CLI.\n\nContains ``build_root_parser`` and all ``_add_*`` argument-group helpers,\nplus shared constants (``_DEFAULT_NUM_WORKERS``, ``VARIANT_DIR_MAP``).\n\"\"\"\n\nfrom __future__ import annotations\n\nimport argparse\nimport sys\n\n# Windows uses spawn-based multiprocessing which breaks DataLoader workers\n_DEFAULT_NUM_WORKERS = 0 if sys.platform == \"win32\" else 4\n\n# Model variant -> checkpoint subdirectory mapping\nVARIANT_DIR_MAP = {\n    \"turbo\": \"acestep-v15-turbo\",\n    \"base\": \"acestep-v15-base\",\n    \"sft\": \"acestep-v15-sft\",\n}\n\n\n# ===========================================================================\n# Root parser\n# ===========================================================================\n\ndef build_root_parser() -> argparse.ArgumentParser:\n    \"\"\"Build the top-level argparse parser with all subcommands.\"\"\"\n\n    formatter_class = argparse.HelpFormatter\n    try:\n        from acestep.training_v2.ui.help_formatter import RichHelpFormatter\n        formatter_class = RichHelpFormatter\n    except ImportError:\n        pass\n\n    root = argparse.ArgumentParser(\n        prog=\"train.py\",\n        description=\"ACE-Step Training V2 -- corrected LoRA fine-tuning CLI\",\n        formatter_class=formatter_class,\n    )\n\n    root.add_argument(\n        \"--plain\",\n        action=\"store_true\",\n        default=False,\n        help=\"Disable Rich output; use plain text (also set automatically when stdout is not a TTY)\",\n    )\n    root.add_argument(\n        \"--yes\",\n        \"-y\",\n        action=\"store_true\",\n        default=False,\n        help=\"Skip the confirmation prompt and start training immediately\",\n    )\n\n    subparsers = root.add_subparsers(dest=\"subcommand\", required=True)\n\n    # -- vanilla -------------------------------------------------------------\n    p_vanilla = subparsers.add_parser(\n        \"vanilla\",\n        help=\"Reproduce existing (bugged) training for backward compatibility\",\n        formatter_class=formatter_class,\n    )\n    _add_common_training_args(p_vanilla)\n\n    # -- fixed ---------------------------------------------------------------\n    p_fixed = subparsers.add_parser(\n        \"fixed\",\n        help=\"Corrected training: continuous timesteps + CFG dropout\",\n        formatter_class=formatter_class,\n    )\n    _add_common_training_args(p_fixed)\n    _add_fixed_args(p_fixed)\n\n    # -- estimate ------------------------------------------------------------\n    p_estimate = subparsers.add_parser(\n        \"estimate\",\n        help=\"Gradient sensitivity analysis (no training)\",\n        formatter_class=formatter_class,\n    )\n    _add_model_args(p_estimate)\n    _add_device_args(p_estimate)\n    _add_estimation_args(p_estimate)\n    p_estimate.add_argument(\n        \"--dataset-dir\",\n        type=str,\n        required=True,\n        help=\"Directory containing preprocessed .pt files\",\n    )\n    p_estimate.add_argument(\n        \"--batch-size\",\n        type=int,\n        default=1,\n        help=\"Batch size for estimation forward passes (default: 1)\",\n    )\n    p_estimate.add_argument(\n        \"--num-workers\",\n        type=int,\n        default=_DEFAULT_NUM_WORKERS,\n        help=f\"DataLoader workers (default: {_DEFAULT_NUM_WORKERS}; 0 on Windows)\",\n    )\n    p_estimate.add_argument(\n        \"--seed\",\n        type=int,\n        default=42,\n        help=\"Random seed (default: 42)\",\n    )\n\n    return root\n\n\n# ===========================================================================\n# Argument groups\n# ===========================================================================\n\ndef _add_model_args(parser: argparse.ArgumentParser) -> None:\n    \"\"\"Add --checkpoint-dir, --model-variant, and --base-model.\"\"\"\n    g = parser.add_argument_group(\"Model / paths\")\n    g.add_argument(\n        \"--checkpoint-dir\",\n        type=str,\n        required=True,\n        help=\"Path to checkpoints root directory\",\n    )\n    g.add_argument(\n        \"--model-variant\",\n        type=str,\n        default=\"turbo\",\n        help=(\n            \"Model variant or subfolder name (default: turbo). \"\n            \"Official: turbo, base, sft. \"\n            \"For fine-tunes: use the exact folder name under checkpoint-dir.\"\n        ),\n    )\n    g.add_argument(\n        \"--base-model\",\n        type=str,\n        default=None,\n        choices=[\"turbo\", \"base\", \"sft\"],\n        help=(\n            \"Base model a fine-tune was trained from (turbo/base/sft). \"\n            \"Used to condition timestep sampling. Auto-detected for official models.\"\n        ),\n    )\n\n\ndef _add_device_args(parser: argparse.ArgumentParser) -> None:\n    \"\"\"Add --device and --precision.\"\"\"\n    g = parser.add_argument_group(\"Device / platform\")\n    g.add_argument(\n        \"--device\",\n        type=str,\n        default=\"auto\",\n        help=\"Device: auto, cuda, cuda:0, mps, xpu, cpu (default: auto)\",\n    )\n    g.add_argument(\n        \"--precision\",\n        type=str,\n        default=\"auto\",\n        choices=[\"auto\", \"bf16\", \"fp16\", \"fp32\"],\n        help=\"Precision: auto, bf16, fp16, fp32 (default: auto)\",\n    )\n\n\ndef _add_common_training_args(parser: argparse.ArgumentParser) -> None:\n    \"\"\"Add arguments shared by vanilla / fixed subcommands.\"\"\"\n    _add_model_args(parser)\n    _add_device_args(parser)\n\n    # -- Data ----------------------------------------------------------------\n    g_data = parser.add_argument_group(\"Data\")\n    g_data.add_argument(\n        \"--dataset-dir\",\n        type=str,\n        required=True,\n        help=\"Directory containing preprocessed .pt files\",\n    )\n    g_data.add_argument(\n        \"--num-workers\",\n        type=int,\n        default=_DEFAULT_NUM_WORKERS,\n        help=f\"DataLoader workers (default: {_DEFAULT_NUM_WORKERS}; 0 on Windows)\",\n    )\n    g_data.add_argument(\n        \"--pin-memory\",\n        action=argparse.BooleanOptionalAction,\n        default=True,\n        help=\"Pin memory for GPU transfer (default: True)\",\n    )\n    g_data.add_argument(\n        \"--prefetch-factor\",\n        type=int,\n        default=2 if _DEFAULT_NUM_WORKERS > 0 else 0,\n        help=\"DataLoader prefetch factor (default: 2; 0 on Windows)\",\n    )\n    g_data.add_argument(\n        \"--persistent-workers\",\n        action=argparse.BooleanOptionalAction,\n        default=_DEFAULT_NUM_WORKERS > 0,\n        help=\"Keep workers alive between epochs (default: True; False on Windows)\",\n    )\n\n    # -- Training hyperparams ------------------------------------------------\n    g_train = parser.add_argument_group(\"Training\")\n    g_train.add_argument(\"--lr\", \"--learning-rate\", type=float, default=1e-4, dest=\"learning_rate\", help=\"Initial learning rate (default: 1e-4)\")\n    g_train.add_argument(\"--batch-size\", type=int, default=1, help=\"Training batch size (default: 1)\")\n    g_train.add_argument(\"--gradient-accumulation\", type=int, default=4, help=\"Gradient accumulation steps (default: 4)\")\n    g_train.add_argument(\"--epochs\", type=int, default=100, help=\"Maximum training epochs (default: 100)\")\n    g_train.add_argument(\"--warmup-steps\", type=int, default=100, help=\"LR warmup steps (default: 100)\")\n    g_train.add_argument(\"--weight-decay\", type=float, default=0.01, help=\"AdamW weight decay (default: 0.01)\")\n    g_train.add_argument(\"--max-grad-norm\", type=float, default=1.0, help=\"Gradient clipping norm (default: 1.0)\")\n    g_train.add_argument(\"--seed\", type=int, default=42, help=\"Random seed (default: 42)\")\n    g_train.add_argument(\"--shift\", type=float, default=3.0, help=\"Noise schedule shift (turbo=3.0, base/sft=1.0)\")\n    g_train.add_argument(\"--num-inference-steps\", type=int, default=8, help=\"Inference steps for timestep schedule (turbo=8, base/sft=50)\")\n    g_train.add_argument(\"--optimizer-type\", type=str, default=\"adamw\", choices=[\"adamw\", \"adamw8bit\", \"adafactor\", \"prodigy\"], help=\"Optimizer (default: adamw)\")\n    g_train.add_argument(\"--scheduler-type\", type=str, default=\"cosine\", choices=[\"cosine\", \"cosine_restarts\", \"linear\", \"constant\", \"constant_with_warmup\"], help=\"LR scheduler (default: cosine)\")\n    g_train.add_argument(\"--gradient-checkpointing\", action=argparse.BooleanOptionalAction, default=True, help=\"Recompute activations to save VRAM (~40-60%% less, ~10-30%% slower). On by default; use --no-gradient-checkpointing to disable\")\n    g_train.add_argument(\"--offload-encoder\", action=argparse.BooleanOptionalAction, default=False, help=\"Move encoder/VAE to CPU after setup (saves ~2-4GB VRAM)\")\n\n    # -- Adapter selection ---------------------------------------------------\n    g_adapter = parser.add_argument_group(\"Adapter\")\n    g_adapter.add_argument(\"--adapter-type\", type=str, default=\"lora\", choices=[\"lora\", \"lokr\"], help=\"Adapter type: lora (PEFT) or lokr (LyCORIS) (default: lora)\")\n\n    # -- LoRA hyperparams ---------------------------------------------------\n    g_lora = parser.add_argument_group(\"LoRA (used when --adapter-type=lora)\")\n    g_lora.add_argument(\"--rank\", \"-r\", type=int, default=64, help=\"LoRA rank (default: 64)\")\n    g_lora.add_argument(\"--alpha\", type=int, default=128, help=\"LoRA alpha (default: 128)\")\n    g_lora.add_argument(\"--dropout\", type=float, default=0.1, help=\"LoRA dropout (default: 0.1)\")\n    g_lora.add_argument(\"--target-modules\", nargs=\"+\", default=[\"q_proj\", \"k_proj\", \"v_proj\", \"o_proj\"], help=\"Modules to apply adapter to\")\n    g_lora.add_argument(\"--bias\", type=str, default=\"none\", choices=[\"none\", \"all\", \"lora_only\"], help=\"Bias training mode (default: none)\")\n    g_lora.add_argument(\"--attention-type\", type=str, default=\"both\", choices=[\"self\", \"cross\", \"both\"], help=\"Attention layers to target (default: both)\")\n\n    # -- LoKR hyperparams ---------------------------------------------------\n    g_lokr = parser.add_argument_group(\"LoKR (used when --adapter-type=lokr)\")\n    g_lokr.add_argument(\"--lokr-linear-dim\", type=int, default=64, help=\"LoKR linear dimension (default: 64)\")\n    g_lokr.add_argument(\"--lokr-linear-alpha\", type=int, default=128, help=\"LoKR linear alpha (default: 128)\")\n    g_lokr.add_argument(\"--lokr-factor\", type=int, default=-1, help=\"LoKR factor; -1 for auto (default: -1)\")\n    g_lokr.add_argument(\"--lokr-decompose-both\", action=\"store_true\", default=False, help=\"Decompose both Kronecker factors\")\n    g_lokr.add_argument(\"--lokr-use-tucker\", action=\"store_true\", default=False, help=\"Use Tucker decomposition\")\n    g_lokr.add_argument(\"--lokr-use-scalar\", action=\"store_true\", default=False, help=\"Use scalar scaling\")\n    g_lokr.add_argument(\"--lokr-weight-decompose\", action=\"store_true\", default=False, help=\"Enable DoRA-style weight decomposition\")\n\n    # -- Checkpointing -------------------------------------------------------\n    g_ckpt = parser.add_argument_group(\"Checkpointing\")\n    g_ckpt.add_argument(\"--output-dir\", type=str, required=True, help=\"Output directory for LoRA weights\")\n    g_ckpt.add_argument(\"--save-every\", type=int, default=10, help=\"Save checkpoint every N epochs (default: 10)\")\n    g_ckpt.add_argument(\"--resume-from\", type=str, default=None, help=\"Path to checkpoint dir to resume from\")\n\n    # -- Logging / TensorBoard -----------------------------------------------\n    g_log = parser.add_argument_group(\"Logging / TensorBoard\")\n    g_log.add_argument(\"--log-dir\", type=str, default=None, help=\"TensorBoard log directory (default: {output-dir}/runs)\")\n    g_log.add_argument(\"--log-every\", type=int, default=10, help=\"Log basic metrics every N steps (default: 10)\")\n    g_log.add_argument(\"--log-heavy-every\", type=int, default=50, help=\"Log per-layer gradient norms every N steps (default: 50)\")\n    g_log.add_argument(\"--sample-every-n-epochs\", type=int, default=0, help=\"Generate audio sample every N epochs; 0=disabled (default: 0)\")\n\n    # -- Preprocessing -------------------------------------------------------\n    g_pre = parser.add_argument_group(\"Preprocessing\")\n    g_pre.add_argument(\"--preprocess\", action=\"store_true\", default=False, help=\"Run preprocessing before training\")\n    g_pre.add_argument(\"--audio-dir\", type=str, default=None, help=\"Source audio directory (preprocessing)\")\n    g_pre.add_argument(\"--dataset-json\", type=str, default=None, help=\"Labeled dataset JSON file (preprocessing)\")\n    g_pre.add_argument(\"--tensor-output\", type=str, default=None, help=\"Output directory for .pt tensor files (preprocessing)\")\n    g_pre.add_argument(\"--max-duration\", type=float, default=240.0, help=\"Max audio duration in seconds (default: 240)\")\n\n\ndef _add_fixed_args(parser: argparse.ArgumentParser) -> None:\n    \"\"\"Add arguments specific to the fixed subcommand.\"\"\"\n    g = parser.add_argument_group(\"Corrected training\")\n    g.add_argument(\"--cfg-ratio\", type=float, default=0.15, help=\"CFG dropout probability (default: 0.15)\")\n\n\n\ndef _add_estimation_args(parser: argparse.ArgumentParser) -> None:\n    \"\"\"Add arguments for the estimate subcommand.\"\"\"\n    g = parser.add_argument_group(\"Estimation\")\n    g.add_argument(\"--estimate-batches\", type=int, default=None, help=\"Number of batches for estimation (default: auto from GPU)\")\n    g.add_argument(\"--top-k\", type=int, default=16, help=\"Number of top modules to select (default: 16)\")\n    g.add_argument(\"--granularity\", type=str, default=\"module\", choices=[\"layer\", \"module\"], help=\"Estimation granularity (default: module)\")\n    g.add_argument(\"--output\", type=str, default=None, dest=\"estimate_output\", help=\"Path to write module config JSON (estimate only)\")\n"
  },
  {
    "path": "acestep/training_v2/cli/common.py",
    "content": "\"\"\"\nBackward-compatible re-exports for ACE-Step Training V2 CLI.\n\nSplit structure:\n    args.py           -- argparse construction (build_root_parser, _add_* helpers)\n    validation.py     -- path validation and target-module resolution\n    config_builder.py -- LoRA/Training config construction from parsed args\n    common.py         -- re-exports for API compatibility (this file)\n\nUsage (unchanged)::\n\n    from acestep.training_v2.cli.common import build_root_parser, build_configs\n    from acestep.training_v2.cli.common import validate_paths, resolve_target_modules\n\"\"\"\n\nfrom acestep.training_v2.cli.args import (  # noqa: F401\n    build_root_parser,\n    VARIANT_DIR_MAP,\n    _DEFAULT_NUM_WORKERS,\n)\nfrom acestep.training_v2.cli.validation import (  # noqa: F401\n    validate_paths,\n    resolve_target_modules,\n)\nfrom acestep.training_v2.cli.config_builder import (  # noqa: F401\n    build_configs,\n)\n"
  },
  {
    "path": "acestep/training_v2/cli/config_builder.py",
    "content": "\"\"\"\nConfig-object construction for ACE-Step Training V2 CLI.\n\nReads model ``config.json`` for timestep parameters, auto-detects GPU,\nand builds adapter config (LoRA or LoKR) + ``TrainingConfigV2`` from CLI args.\n\"\"\"\n\nfrom __future__ import annotations\n\nimport argparse\nimport logging\nfrom pathlib import Path\nfrom typing import Tuple, Union\n\nfrom acestep.training_v2.configs import LoRAConfigV2, LoKRConfigV2, TrainingConfigV2\nfrom acestep.training_v2.gpu_utils import detect_gpu\nfrom acestep.training_v2.cli.args import VARIANT_DIR_MAP\nfrom acestep.training_v2.cli.validation import resolve_target_modules\n\nlogger = logging.getLogger(__name__)\n\nAdapterConfig = Union[LoRAConfigV2, LoKRConfigV2]\n\n\ndef _resolve_model_config_path(ckpt_root: Path, variant: str) -> Path:\n    \"\"\"Find config.json for *variant*, supporting custom folder names.\n\n    Checks the ``VARIANT_DIR_MAP`` alias first, then tries *variant* as\n    a literal subdirectory name.\n    \"\"\"\n    # 1. Known alias\n    mapped = VARIANT_DIR_MAP.get(variant)\n    if mapped:\n        p = ckpt_root / mapped / \"config.json\"\n        if p.is_file():\n            return p\n\n    # 2. Literal folder name (fine-tunes, custom models)\n    p = ckpt_root / variant / \"config.json\"\n    if p.is_file():\n        return p\n\n    # 3. Fallback: return the mapped path (even if missing) so the caller\n    #    gets a meaningful \"not found\" message.\n    return ckpt_root / (mapped or variant) / \"config.json\"\n\n\ndef build_configs(args: argparse.Namespace) -> Tuple[AdapterConfig, TrainingConfigV2]:\n    \"\"\"Construct adapter config and TrainingConfigV2 from parsed CLI args.\n\n    Returns LoRAConfigV2 when ``args.adapter_type == \"lora\"`` and\n    LoKRConfigV2 when ``args.adapter_type == \"lokr\"``.\n\n    Also patches in ``timestep_mu``, ``timestep_sigma``, and\n    ``data_proportion`` from the model's ``config.json`` so the user\n    does not need to pass them manually.\n    \"\"\"\n    import json as _json\n\n    adapter_type = getattr(args, \"adapter_type\", \"lora\")\n\n    # -- Resolve model config path ------------------------------------------\n    ckpt_root = Path(args.checkpoint_dir)\n    model_config_path = _resolve_model_config_path(ckpt_root, args.model_variant)\n\n    timestep_mu = -0.4\n    timestep_sigma = 1.0\n    data_proportion = 0.5\n\n    if model_config_path.is_file():\n        try:\n            mcfg = _json.loads(model_config_path.read_text())\n            timestep_mu = mcfg.get(\"timestep_mu\", timestep_mu)\n            timestep_sigma = mcfg.get(\"timestep_sigma\", timestep_sigma)\n            data_proportion = mcfg.get(\"data_proportion\", data_proportion)\n        except (_json.JSONDecodeError, OSError) as exc:\n            logger.warning(\n                \"[Side-Step] Failed to parse %s: %s -- using default timestep parameters\",\n                model_config_path, exc,\n            )\n\n    # -- Override from --base-model if provided and config lacked params ----\n    base_model = getattr(args, \"base_model\", None)\n    if base_model and not model_config_path.is_file():\n        from acestep.training_v2.model_discovery import get_base_defaults\n        defaults = get_base_defaults(base_model)\n        timestep_mu = defaults.get(\"timestep_mu\", timestep_mu)\n        timestep_sigma = defaults.get(\"timestep_sigma\", timestep_sigma)\n\n    # -- GPU info -----------------------------------------------------------\n    gpu_info = detect_gpu(\n        requested_device=args.device,\n        requested_precision=args.precision,\n    )\n\n    # -- Adapter config (LoRA or LoKR) --------------------------------------\n    attention_type = getattr(args, \"attention_type\", \"both\")\n    resolved_modules = resolve_target_modules(args.target_modules, attention_type)\n\n    adapter_cfg: AdapterConfig\n    if adapter_type == \"lokr\":\n        adapter_cfg = LoKRConfigV2(\n            linear_dim=getattr(args, \"lokr_linear_dim\", 64),\n            linear_alpha=getattr(args, \"lokr_linear_alpha\", 128),\n            factor=getattr(args, \"lokr_factor\", -1),\n            decompose_both=getattr(args, \"lokr_decompose_both\", False),\n            use_tucker=getattr(args, \"lokr_use_tucker\", False),\n            use_scalar=getattr(args, \"lokr_use_scalar\", False),\n            weight_decompose=getattr(args, \"lokr_weight_decompose\", False),\n            target_modules=resolved_modules,\n            attention_type=attention_type,\n        )\n    else:\n        adapter_cfg = LoRAConfigV2(\n            r=args.rank,\n            alpha=args.alpha,\n            dropout=args.dropout,\n            target_modules=resolved_modules,\n            bias=args.bias,\n            attention_type=attention_type,\n        )\n\n    # -- Clamp DataLoader flags when num_workers <= 0 -----------------------\n    num_workers = args.num_workers\n    prefetch_factor = args.prefetch_factor\n    persistent_workers = args.persistent_workers\n\n    if num_workers <= 0:\n        if persistent_workers:\n            logger.info(\"[Side-Step] num_workers=0 -- forcing persistent_workers=False\")\n            persistent_workers = False\n        if prefetch_factor and prefetch_factor > 0:\n            logger.info(\"[Side-Step] num_workers=0 -- forcing prefetch_factor=0\")\n            prefetch_factor = 0\n\n    # -- Training config ----------------------------------------------------\n    train_cfg = TrainingConfigV2(\n        shift=getattr(args, \"shift\", 3.0),\n        num_inference_steps=getattr(args, \"num_inference_steps\", 8),\n        learning_rate=args.learning_rate,\n        batch_size=args.batch_size,\n        gradient_accumulation_steps=args.gradient_accumulation,\n        max_epochs=args.epochs,\n        warmup_steps=args.warmup_steps,\n        weight_decay=args.weight_decay,\n        max_grad_norm=args.max_grad_norm,\n        seed=args.seed,\n        output_dir=args.output_dir,\n        save_every_n_epochs=args.save_every,\n        num_workers=num_workers,\n        pin_memory=args.pin_memory,\n        prefetch_factor=prefetch_factor,\n        persistent_workers=persistent_workers,\n        # V2 extensions\n        adapter_type=adapter_type,\n        optimizer_type=getattr(args, \"optimizer_type\", \"adamw\"),\n        scheduler_type=getattr(args, \"scheduler_type\", \"cosine\"),\n        gradient_checkpointing=getattr(args, \"gradient_checkpointing\", True),\n        offload_encoder=getattr(args, \"offload_encoder\", False),\n        cfg_ratio=getattr(args, \"cfg_ratio\", 0.15),\n        timestep_mu=timestep_mu,\n        timestep_sigma=timestep_sigma,\n        data_proportion=data_proportion,\n        model_variant=args.model_variant,\n        checkpoint_dir=args.checkpoint_dir,\n        dataset_dir=args.dataset_dir,\n        device=gpu_info.device,\n        precision=gpu_info.precision,\n        resume_from=args.resume_from,\n        log_dir=args.log_dir,\n        log_every=args.log_every,\n        log_heavy_every=args.log_heavy_every,\n        sample_every_n_epochs=args.sample_every_n_epochs,\n        # Estimation / selective (may not exist on all subcommands)\n        estimate_batches=getattr(args, \"estimate_batches\", None),\n        top_k=getattr(args, \"top_k\", 16),\n        granularity=getattr(args, \"granularity\", \"module\"),\n        module_config=getattr(args, \"module_config\", None),\n        auto_estimate=getattr(args, \"auto_estimate\", False),\n        estimate_output=getattr(args, \"estimate_output\", None),\n        # Preprocessing\n        preprocess=args.preprocess,\n        audio_dir=args.audio_dir,\n        dataset_json=args.dataset_json,\n        tensor_output=args.tensor_output,\n        max_duration=args.max_duration,\n    )\n\n    return adapter_cfg, train_cfg\n"
  },
  {
    "path": "acestep/training_v2/cli/train_fixed.py",
    "content": "\"\"\"\nfixed subcommand -- Corrected training: continuous timesteps + CFG dropout.\n\nUses ``FixedLoRATrainer`` which matches each model variant's own\n``forward()`` training logic:\n\n    - Continuous logit-normal timestep sampling via ``sample_timesteps()``\n    - CFG dropout (``cfg_ratio=0.15``) using ``model.null_condition_emb``\n    - ``r = t`` (``use_meanflow=False``)\n    - Reads ``timestep_mu``, ``timestep_sigma``, ``data_proportion``\n      from the model's ``config.json``\n\nReuses the same data pipeline (``PreprocessedDataModule``) and LoRA\nutilities (``inject_lora_into_dit``, ``save_lora_weights``, etc.) as\nthe vanilla subcommand.\n\"\"\"\n\nfrom __future__ import annotations\n\nimport argparse\nimport gc\nimport sys\n\nfrom acestep.training_v2.cli.common import build_configs\nfrom acestep.training_v2.model_loader import load_decoder_for_training\nfrom acestep.training_v2.trainer_fixed import FixedLoRATrainer\n\n\ndef _cleanup_gpu() -> None:\n    \"\"\"Release GPU memory so the process can safely reuse it.\"\"\"\n    gc.collect()\n    try:\n        import torch\n        if torch.cuda.is_available():\n            torch.cuda.empty_cache()\n    except ImportError:\n        pass\n\n\ndef run_fixed(args: argparse.Namespace) -> int:\n    \"\"\"Execute the fixed (corrected) training subcommand.\n\n    Returns 0 on success, non-zero on failure.\n    \"\"\"\n    import torch\n\n    # -- UI setup -------------------------------------------------------------\n    from acestep.training_v2.ui import set_plain_mode\n    from acestep.training_v2.ui.banner import show_banner\n    from acestep.training_v2.ui.config_panel import show_config, confirm_start\n    from acestep.training_v2.ui.errors import handle_error, show_info\n    from acestep.training_v2.ui.progress import track_training\n    from acestep.training_v2.ui.summary import show_summary\n\n    if getattr(args, \"plain\", False):\n        set_plain_mode(True)\n\n    # -- Matmul precision (matches handler.initialize_service behaviour) ------\n    torch.set_float32_matmul_precision(\"medium\")\n\n    # -- Build V2 config objects from CLI args --------------------------------\n    adapter_cfg, train_cfg = build_configs(args)\n\n    # -- Banner (skip if wizard already showed one) ---------------------------\n    if not getattr(args, \"_from_wizard\", False):\n        show_banner(\n            subcommand=\"fixed\",\n            device=train_cfg.device,\n            precision=train_cfg.precision,\n        )\n\n    # -- Config summary & confirmation (always shown) -----------------------\n    show_config(adapter_cfg, train_cfg, subcommand=\"fixed\")\n    skip_confirm = getattr(args, \"yes\", False)\n    if not confirm_start(skip=skip_confirm):\n        return 0\n\n    model = None\n    trainer = None\n    try:\n        # -- Load model -------------------------------------------------------\n        try:\n            show_info(f\"Loading model (variant={train_cfg.model_variant}, device={train_cfg.device})\")\n            model = load_decoder_for_training(\n                checkpoint_dir=train_cfg.checkpoint_dir,\n                variant=train_cfg.model_variant,\n                device=train_cfg.device,\n                precision=train_cfg.precision,\n            )\n        except Exception as exc:\n            handle_error(exc, context=\"Model loading\", show_traceback=True)\n            return 1\n\n        # -- Train ------------------------------------------------------------\n        try:\n            trainer = FixedLoRATrainer(model, adapter_cfg, train_cfg)\n\n            stats = track_training(\n                training_iter=trainer.train(),\n                max_epochs=train_cfg.max_epochs,\n                device=train_cfg.device,\n            )\n\n            # -- Summary ------------------------------------------------------\n            show_summary(\n                stats=stats,\n                output_dir=train_cfg.output_dir,\n                log_dir=str(train_cfg.effective_log_dir),\n            )\n        except KeyboardInterrupt:\n            show_info(\"Training interrupted by user (Ctrl+C)\")\n            return 130\n        except Exception as exc:\n            handle_error(exc, context=\"Training\", show_traceback=True)\n            return 1\n\n        return 0\n    finally:\n        # Explicitly release GPU memory so the session loop can reuse it.\n        del trainer\n        del model\n        _cleanup_gpu()\n"
  },
  {
    "path": "acestep/training_v2/cli/train_vanilla.py",
    "content": "\"\"\"\nvanilla subcommand -- Reproduce existing (bugged) training for backward compatibility.\n\nImports the original ``PreprocessedLoRAModule`` and ``LoRATrainer`` (or\n``LoKRTrainer``) from ``acestep/training/``.  Always prints a warning that\nbehaviour differs from the model's own training procedure.\n\nSupports both LoRA (PEFT) and LoKR (LyCORIS) adapters.\n\"\"\"\n\nfrom __future__ import annotations\n\nimport argparse\nimport gc\nimport sys\n\nimport torch\n\n# Vanilla mode requires full ACE-Step installation.\nfrom acestep.training.configs import LoRAConfig, TrainingConfig\nfrom acestep.training.trainer import LoRATrainer\n_VANILLA_AVAILABLE = True\n\n# LoKR may not exist in older ACE-Step installs\ntry:\n    from acestep.training.configs import LoKRConfig\n    from acestep.training.trainer import LoKRTrainer\n    _LOKR_AVAILABLE = True\nexcept ImportError:\n    LoKRConfig = None  # type: ignore[assignment,misc]\n    LoKRTrainer = None  # type: ignore[assignment,misc]\n    _LOKR_AVAILABLE = False\nfrom acestep.training_v2.gpu_utils import detect_gpu\nfrom acestep.training_v2.model_loader import load_decoder_for_training\n\n\ndef _cleanup_gpu() -> None:\n    \"\"\"Release GPU memory so the process can safely reuse it.\"\"\"\n    gc.collect()\n    if torch.cuda.is_available():\n        torch.cuda.empty_cache()\n\n\n# ---------------------------------------------------------------------------\n# Handler shim\n# ---------------------------------------------------------------------------\n\nclass _HandlerShim:\n    \"\"\"Minimal shim satisfying the ``LoRATrainer`` constructor.\n\n    The original trainer expects a ``dit_handler`` with ``.model``,\n    ``.device``, ``.dtype``, and ``.quantization``.\n    \"\"\"\n\n    def __init__(self, model: torch.nn.Module, device: str, dtype: torch.dtype) -> None:\n        self.model = model\n        self.device = device\n        self.dtype = dtype\n        self.quantization = None\n\n\n# ---------------------------------------------------------------------------\n# Public entry point\n# ---------------------------------------------------------------------------\n\ndef run_vanilla(args: argparse.Namespace) -> int:\n    \"\"\"Execute the vanilla training subcommand.\n\n    Returns 0 on success, non-zero on failure.\n    \"\"\"\n    # -- UI setup -------------------------------------------------------------\n    from acestep.training_v2.ui import set_plain_mode\n    from acestep.training_v2.ui.banner import show_banner\n    from acestep.training_v2.ui.errors import handle_error, show_info, show_warning\n    from acestep.training_v2.ui.progress import track_training\n    from acestep.training_v2.ui.summary import show_summary\n\n    if getattr(args, \"plain\", False):\n        set_plain_mode(True)\n\n    if not _VANILLA_AVAILABLE:\n        show_warning(\n            \"Vanilla training requires a full ACE-Step 1.5 installation.\\n\"\n            \"Install it with:  pip install -e /path/to/ACE-Step-1.5\\n\"\n            \"Or use the 'Corrected (fixed)' training mode which is standalone.\"\n        )\n        return 1\n\n    # -- Matmul precision (matches handler.initialize_service behaviour) ------\n    torch.set_float32_matmul_precision(\"medium\")\n\n    # -- GPU detection -------------------------------------------------------\n    gpu = detect_gpu(args.device, args.precision)\n\n    # -- Extra-strong warning for base/sft + vanilla (especially problematic) --\n    if args.model_variant in (\"base\", \"sft\"):\n        from acestep.training_v2.ui.config_panel import confirm_start\n        from acestep.training_v2.ui.errors import show_error\n\n        show_error(\n            title=\"Vanilla + Non-Turbo Model Warning\",\n            message=(\n                f\"You're using vanilla mode with --model-variant {args.model_variant}.\\n\\n\"\n                \"The vanilla trainer uses turbo's 8-step discrete timesteps, which is:\\n\"\n                \"  1. Wrong for training (should use continuous logit-normal sampling)\\n\"\n                \"  2. Extra wrong for base/sft (they use different inference schedules)\\n\\n\"\n                \"This combination will likely produce poor results.\\n\"\n                \"Use 'fixed' mode instead for proper training behavior.\"\n            ),\n            suggestion=f\"python train.py fixed --model-variant {args.model_variant} ...\",\n        )\n        if not getattr(args, \"yes\", False):\n            if not confirm_start(skip=False):\n                show_info(\"Aborted. Use 'fixed' mode for correct training.\")\n                return 0\n\n    # -- Banner (skip if wizard already showed one) ---------------------------\n    if not getattr(args, \"_from_wizard\", False):\n        show_banner(\n            subcommand=\"vanilla\",\n            device=gpu.device,\n            precision=gpu.precision,\n        )\n\n    # -- Vanilla warning (always shown -- important for user awareness) -----\n    show_warning(\n        \"vanilla mode reproduces the EXISTING training behaviour which\\n\"\n        \"         differs from the model's own training procedure:\\n\"\n        \"           - Discrete 8-step turbo timesteps (should be continuous logit-normal)\\n\"\n        \"           - No CFG dropout (should be cfg_ratio=0.15)\\n\"\n        \"         These bugs affect ALL model variants (turbo, base, sft).\\n\"\n        \"         Use 'fixed' for corrected training.\"\n    )\n\n    # -- Determine adapter type -----------------------------------------------\n    adapter_type = getattr(args, \"adapter_type\", \"lora\")\n\n    if adapter_type == \"lokr\" and not _LOKR_AVAILABLE:\n        from acestep.training_v2.ui.errors import show_error\n        show_error(\n            title=\"LoKR Not Available\",\n            message=(\n                \"Your ACE-Step installation does not include LoKR support.\\n\"\n                \"Please update ACE-Step to a version with lokr_utils, or use LoRA instead.\"\n            ),\n        )\n        return 1\n\n    # -- Build original config objects from CLI args -------------------------\n    if adapter_type == \"lokr\":\n        adapter_cfg: object = LoKRConfig(\n            linear_dim=getattr(args, \"lokr_linear_dim\", 64),\n            linear_alpha=getattr(args, \"lokr_linear_alpha\", 128),\n            factor=getattr(args, \"lokr_factor\", -1),\n            decompose_both=getattr(args, \"lokr_decompose_both\", False),\n            use_tucker=getattr(args, \"lokr_use_tucker\", False),\n            use_scalar=getattr(args, \"lokr_use_scalar\", False),\n            weight_decompose=getattr(args, \"lokr_weight_decompose\", False),\n            target_modules=args.target_modules,\n        )\n    else:\n        adapter_cfg = LoRAConfig(\n            r=args.rank,\n            alpha=args.alpha,\n            dropout=args.dropout,\n            target_modules=args.target_modules,\n            bias=args.bias,\n        )\n    # Windows spawn-based multiprocessing breaks DataLoader workers\n    num_workers = args.num_workers\n    if sys.platform == \"win32\" and num_workers > 0:\n        num_workers = 0\n\n    train_cfg = TrainingConfig(\n        learning_rate=args.learning_rate,\n        batch_size=args.batch_size,\n        gradient_accumulation_steps=args.gradient_accumulation,\n        max_epochs=args.epochs,\n        warmup_steps=args.warmup_steps,\n        weight_decay=args.weight_decay,\n        max_grad_norm=args.max_grad_norm,\n        seed=args.seed,\n        output_dir=args.output_dir,\n        save_every_n_epochs=args.save_every,\n        num_workers=num_workers,\n        pin_memory=args.pin_memory,\n        prefetch_factor=args.prefetch_factor,\n        persistent_workers=args.persistent_workers,\n        log_every_n_steps=args.log_every,\n    )\n\n    model = None\n    trainer = None\n    handler = None\n    try:\n        # -- Load model ------------------------------------------------------\n        try:\n            show_info(f\"Loading model (variant={args.model_variant}, device={gpu.device})\")\n            model = load_decoder_for_training(\n                checkpoint_dir=args.checkpoint_dir,\n                variant=args.model_variant,\n                device=gpu.device,\n                precision=gpu.precision,\n            )\n        except Exception as exc:\n            handle_error(exc, context=\"Model loading\", show_traceback=True)\n            return 1\n\n        # -- Build handler shim ----------------------------------------------\n        dtype_map = {\"bf16\": torch.bfloat16, \"fp16\": torch.float16, \"fp32\": torch.float32}\n        handler = _HandlerShim(\n            model=model,\n            device=gpu.device,\n            dtype=dtype_map.get(gpu.precision, torch.bfloat16),\n        )\n\n        # -- Run original trainer --------------------------------------------\n        try:\n            if adapter_type == \"lokr\":\n                trainer = LoKRTrainer(handler, adapter_cfg, train_cfg)\n            else:\n                trainer = LoRATrainer(handler, adapter_cfg, train_cfg)\n\n            stats = track_training(\n                training_iter=trainer.train_from_preprocessed(\n                    tensor_dir=args.dataset_dir,\n                    resume_from=args.resume_from,\n                ),\n                max_epochs=args.epochs,\n                device=gpu.device,\n            )\n\n            # -- Summary ------------------------------------------------------\n            show_summary(\n                stats=stats,\n                output_dir=args.output_dir,\n                log_dir=None,  # vanilla doesn't have configurable log_dir\n            )\n        except KeyboardInterrupt:\n            show_info(\"Training interrupted by user (Ctrl+C)\")\n            return 130\n        except Exception as exc:\n            handle_error(exc, context=\"Training\", show_traceback=True)\n            return 1\n\n        return 0\n    finally:\n        # Explicitly release GPU memory so the session loop can reuse it.\n        del trainer\n        del handler\n        del model\n        _cleanup_gpu()\n"
  },
  {
    "path": "acestep/training_v2/cli/validation.py",
    "content": "\"\"\"\nPath validation and target-module resolution for ACE-Step Training V2 CLI.\n\"\"\"\n\nfrom __future__ import annotations\n\nimport argparse\nimport sys\nfrom pathlib import Path\n\nfrom acestep.training_v2.cli.args import VARIANT_DIR_MAP\n\n\ndef validate_paths(args: argparse.Namespace) -> bool:\n    \"\"\"Validate that required paths exist and attach the resolved model dir.\n\n    On success, sets ``args.model_dir`` to the resolved ``Path`` so that\n    callers can consume it directly.  Returns ``True`` if all OK.\n\n    Prints ``[FAIL]`` messages and returns ``False`` on the first error.\n    \"\"\"\n    # All subcommands need checkpoint-dir\n    ckpt_root = Path(args.checkpoint_dir)\n    if not ckpt_root.is_dir():\n        print(f\"[FAIL] Checkpoint directory not found: {ckpt_root}\", file=sys.stderr)\n        return False\n\n    # Resolve model directory: try known alias first, then literal folder name\n    variant_dir = VARIANT_DIR_MAP.get(args.model_variant)\n    if variant_dir and (ckpt_root / variant_dir).is_dir():\n        model_dir = ckpt_root / variant_dir\n    elif (ckpt_root / args.model_variant).is_dir():\n        model_dir = ckpt_root / args.model_variant\n    else:\n        tried = variant_dir or args.model_variant\n        print(\n            f\"[FAIL] Model directory not found: {ckpt_root / tried}\\n\"\n            f\"       Looked for '{tried}' under {ckpt_root}\",\n            file=sys.stderr,\n        )\n        return False\n\n    # Attach resolved path so callers can use it directly\n    args.model_dir = model_dir\n\n    # Dataset dir\n    ds_dir = getattr(args, \"dataset_dir\", None)\n    if ds_dir is not None and not Path(ds_dir).is_dir():\n        print(f\"[FAIL] Dataset directory not found: {ds_dir}\", file=sys.stderr)\n        return False\n\n    # Resume path\n    resume = getattr(args, \"resume_from\", None)\n    if resume is not None and not Path(resume).exists():\n        print(f\"[WARN] Resume path not found (will train from scratch): {resume}\", file=sys.stderr)\n\n    return True\n\n\ndef resolve_target_modules(target_modules: list, attention_type: str) -> list:\n    \"\"\"Resolve target modules based on attention type selection.\n\n    Args:\n        target_modules: List of module patterns (e.g. [\"q_proj\", \"v_proj\"])\n        attention_type: One of \"self\", \"cross\", or \"both\"\n\n    Returns:\n        Resolved list of module patterns with appropriate prefixes.\n\n    Examples:\n        resolve_target_modules([\"q_proj\", \"v_proj\"], \"both\")\n        -> [\"q_proj\", \"v_proj\"]  # unchanged, PEFT matches all\n\n        resolve_target_modules([\"q_proj\", \"v_proj\"], \"self\")\n        -> [\"self_attn.q_proj\", \"self_attn.v_proj\"]\n\n        resolve_target_modules([\"q_proj\", \"v_proj\"], \"cross\")\n        -> [\"cross_attn.q_proj\", \"cross_attn.v_proj\"]\n    \"\"\"\n    if attention_type == \"both\":\n        return target_modules\n\n    prefix_map = {\n        \"self\": \"self_attn\",\n        \"cross\": \"cross_attn\",\n    }\n    prefix = prefix_map.get(attention_type)\n    if prefix is None:\n        return target_modules\n\n    resolved = []\n    for mod in target_modules:\n        if \".\" in mod:\n            resolved.append(mod)\n        else:\n            resolved.append(f\"{prefix}.{mod}\")\n\n    return resolved\n"
  },
  {
    "path": "acestep/training_v2/configs.py",
    "content": "\"\"\"\nExtended Training Configuration for ACE-Step Training V2\n\nUses base configs from ``acestep.training.configs``.  Extends them with\ncorrected-training-specific fields (CFG dropout,\ncontinuous timestep sampling parameters, estimation, TensorBoard, sample\ngeneration, etc.).\n\"\"\"\n\nfrom __future__ import annotations\n\nimport json\nfrom dataclasses import dataclass, field, asdict\nfrom pathlib import Path\nfrom typing import List, Optional\n\n# Vendored base configs -- no base ACE-Step installation required\nfrom acestep.training.configs import (  # noqa: F401\n    LoRAConfig,\n    LoKRConfig,\n    TrainingConfig,\n)\n\n\n# ---------------------------------------------------------------------------\n# Extended LoRA config (unchanged for now, but available for future extension)\n# ---------------------------------------------------------------------------\n\n@dataclass\nclass LoRAConfigV2(LoRAConfig):\n    \"\"\"Extended LoRA configuration.\n\n    Inherits all fields from the original LoRAConfig and adds:\n    - attention_type: Which attention layers to target (self, cross, or both)\n    \"\"\"\n\n    attention_type: str = \"both\"\n    \"\"\"Which attention layers to target: 'self', 'cross', or 'both'.\"\"\"\n\n    def to_dict(self) -> dict:\n        base = super().to_dict()\n        base[\"attention_type\"] = self.attention_type\n        return base\n\n    # --- Data loading (declared here for compatibility with base packages\n    #     that may not include these fields in TrainingConfig) -----------------\n    num_workers: int = 4\n    \"\"\"Number of DataLoader worker processes.\"\"\"\n\n    pin_memory: bool = True\n    \"\"\"Pin memory in DataLoader for faster host-to-device transfer.\"\"\"\n\n    prefetch_factor: int = 2\n    \"\"\"Number of batches to prefetch per DataLoader worker.\"\"\"\n\n    persistent_workers: bool = True\n    \"\"\"Keep DataLoader workers alive between epochs.\"\"\"\n\n    pin_memory_device: str = \"\"\n    \"\"\"Device for pinned memory (\"\" = default CUDA device).\"\"\"\n\n\n# ---------------------------------------------------------------------------\n# Extended LoKR config\n# ---------------------------------------------------------------------------\n\n@dataclass\nclass LoKRConfigV2(LoKRConfig):\n    \"\"\"Extended LoKR configuration.\n\n    Inherits all fields from the original LoKRConfig and adds:\n    - attention_type: Which attention layers to target (self, cross, or both)\n    \"\"\"\n\n    attention_type: str = \"both\"\n    \"\"\"Which attention layers to target: 'self', 'cross', or 'both'.\"\"\"\n\n    def to_dict(self) -> dict:\n        base = super().to_dict()\n        base[\"attention_type\"] = self.attention_type\n        return base\n\n\n# ---------------------------------------------------------------------------\n# Extended Training config\n# ---------------------------------------------------------------------------\n\n@dataclass\nclass TrainingConfigV2(TrainingConfig):\n    \"\"\"Extended training configuration with corrected-training fields.\n\n    New fields compared to the original TrainingConfig:\n    - CFG dropout (cfg_ratio)\n    - Continuous timestep sampling parameters (timestep_mu, timestep_sigma,\n      data_proportion)\n    - Model variant selection\n    - Device / precision auto-detection\n    - Estimation parameters\n    - Extended TensorBoard logging\n    - Sample generation during training\n    - Checkpoint resume\n    - Preprocessing flags\n    \"\"\"\n\n    # --- Data loading (declared here for compatibility with base packages\n    #     that may not include these fields in TrainingConfig) -----------------\n    num_workers: int = 4\n    \"\"\"Number of DataLoader worker processes.\"\"\"\n\n    pin_memory: bool = True\n    \"\"\"Pin memory in DataLoader for faster host-to-device transfer.\"\"\"\n\n    prefetch_factor: int = 2\n    \"\"\"Number of batches to prefetch per DataLoader worker.\"\"\"\n\n    persistent_workers: bool = True\n    \"\"\"Keep DataLoader workers alive between epochs.\"\"\"\n\n    pin_memory_device: str = \"\"\n    \"\"\"Device for pinned memory (\"\" = default CUDA device).\"\"\"\n\n    # --- Optimizer / Scheduler ------------------------------------------------\n    optimizer_type: str = \"adamw\"\n    \"\"\"Optimizer: 'adamw', 'adamw8bit', 'adafactor', 'prodigy'.\"\"\"\n\n    scheduler_type: str = \"cosine\"\n    \"\"\"LR scheduler: 'cosine', 'cosine_restarts', 'linear', 'constant', 'constant_with_warmup'.\"\"\"\n\n    # --- VRAM management ------------------------------------------------------\n    gradient_checkpointing: bool = True\n    \"\"\"Trade compute for memory by recomputing activations during backward.\n    Enabled by default to match ACE-Step's behaviour and save ~40-60%\n    activation VRAM.  Adds ~10-30% training time overhead.\"\"\"\n\n    offload_encoder: bool = False\n    \"\"\"Move encoder/VAE to CPU after setup to free ~2-4 GB VRAM.\"\"\"\n\n    vram_profile: str = \"auto\"\n    \"\"\"VRAM preset: 'auto', 'comfortable', 'standard', 'tight', 'minimal'.\"\"\"\n\n    # --- Corrected training params ------------------------------------------\n    cfg_ratio: float = 0.15\n    \"\"\"Classifier-free guidance dropout probability.\"\"\"\n\n    timestep_mu: float = -0.4\n    \"\"\"Mean for logit-normal timestep sampling (from model config).\"\"\"\n\n    timestep_sigma: float = 1.0\n    \"\"\"Std for logit-normal timestep sampling (from model config).\"\"\"\n\n    data_proportion: float = 0.5\n    \"\"\"Data proportion for sample_t_r (from model config).\"\"\"\n\n    # --- Adapter selection ----------------------------------------------------\n    adapter_type: str = \"lora\"\n    \"\"\"Adapter type: 'lora' (PEFT) or 'lokr' (LyCORIS).\"\"\"\n\n    # --- Model / paths ------------------------------------------------------\n    model_variant: str = \"turbo\"\n    \"\"\"Model variant: 'turbo', 'base', or 'sft'.\"\"\"\n\n    checkpoint_dir: str = \"./checkpoints\"\n    \"\"\"Path to checkpoints root directory.\"\"\"\n\n    dataset_dir: str = \"\"\n    \"\"\"Directory containing preprocessed .pt tensor files.\"\"\"\n\n    # --- Device / precision -------------------------------------------------\n    device: str = \"auto\"\n    \"\"\"Device selection: 'auto', 'cuda', 'cuda:0', 'mps', 'xpu', 'cpu'.\"\"\"\n\n    precision: str = \"auto\"\n    \"\"\"Precision: 'auto', 'bf16', 'fp16', 'fp32'.\"\"\"\n\n    # --- Checkpointing ------------------------------------------------------\n    resume_from: Optional[str] = None\n    \"\"\"Path to checkpoint directory to resume training from.\"\"\"\n\n    # --- Extended TensorBoard logging ---------------------------------------\n    log_dir: Optional[str] = None\n    \"\"\"TensorBoard log directory.  Defaults to {output_dir}/runs.\"\"\"\n\n    log_every: int = 10\n    \"\"\"Log basic metrics (loss, LR) every N optimiser steps.\"\"\"\n\n    log_heavy_every: int = 50\n    \"\"\"Log per-layer gradient norms every N optimiser steps.\"\"\"\n\n    # --- Sample generation --------------------------------------------------\n    sample_every_n_epochs: int = 0\n    \"\"\"Generate an audio sample every N epochs (0 = disabled).\"\"\"\n\n    # --- Estimation params --------------------------------------------------\n    estimate_batches: Optional[int] = None\n    \"\"\"Number of batches for gradient estimation (None = auto from GPU).\"\"\"\n\n    top_k: int = 16\n    \"\"\"Number of top modules to select during estimation.\"\"\"\n\n    granularity: str = \"module\"\n    \"\"\"Estimation granularity: 'layer' or 'module'.\"\"\"\n\n    module_config: Optional[str] = None\n    \"\"\"Path to JSON module config produced by the estimate subcommand.\"\"\"\n\n    auto_estimate: bool = False\n    \"\"\"Run estimation inline before training.\"\"\"\n\n    estimate_output: Optional[str] = None\n    \"\"\"Path to write module config JSON (estimate subcommand only).\"\"\"\n\n    # --- Preprocessing flags ------------------------------------------------\n    preprocess: bool = False\n    \"\"\"Run preprocessing before training.\"\"\"\n\n    audio_dir: Optional[str] = None\n    \"\"\"Source audio directory for preprocessing.\"\"\"\n\n    dataset_json: Optional[str] = None\n    \"\"\"Labeled dataset JSON for preprocessing.\"\"\"\n\n    tensor_output: Optional[str] = None\n    \"\"\"Output directory for preprocessed .pt tensor files.\"\"\"\n\n    max_duration: float = 240.0\n    \"\"\"Maximum audio duration in seconds (preprocessing).\"\"\"\n\n    # -----------------------------------------------------------------------\n    # Helpers\n    # -----------------------------------------------------------------------\n\n    @property\n    def effective_log_dir(self) -> Path:\n        \"\"\"Return the resolved TensorBoard log directory.\"\"\"\n        if self.log_dir is not None:\n            return Path(self.log_dir)\n        return Path(self.output_dir) / \"runs\"\n\n    def to_dict(self) -> dict:\n        \"\"\"Serialize every field, including new ones.\"\"\"\n        base = super().to_dict()\n        base.update(\n            {\n                \"num_workers\": self.num_workers,\n                \"pin_memory\": self.pin_memory,\n                \"prefetch_factor\": self.prefetch_factor,\n                \"persistent_workers\": self.persistent_workers,\n                \"pin_memory_device\": self.pin_memory_device,\n                \"optimizer_type\": self.optimizer_type,\n                \"scheduler_type\": self.scheduler_type,\n                \"gradient_checkpointing\": self.gradient_checkpointing,\n                \"offload_encoder\": self.offload_encoder,\n                \"vram_profile\": self.vram_profile,\n                \"adapter_type\": self.adapter_type,\n                \"cfg_ratio\": self.cfg_ratio,\n                \"timestep_mu\": self.timestep_mu,\n                \"timestep_sigma\": self.timestep_sigma,\n                \"data_proportion\": self.data_proportion,\n                \"model_variant\": self.model_variant,\n                \"checkpoint_dir\": self.checkpoint_dir,\n                \"dataset_dir\": self.dataset_dir,\n                \"device\": self.device,\n                \"precision\": self.precision,\n                \"resume_from\": self.resume_from,\n                \"log_dir\": self.log_dir,\n                \"log_every\": self.log_every,\n                \"log_heavy_every\": self.log_heavy_every,\n                \"sample_every_n_epochs\": self.sample_every_n_epochs,\n                \"estimate_batches\": self.estimate_batches,\n                \"top_k\": self.top_k,\n                \"granularity\": self.granularity,\n                \"module_config\": self.module_config,\n                \"auto_estimate\": self.auto_estimate,\n                \"estimate_output\": self.estimate_output,\n                \"preprocess\": self.preprocess,\n                \"audio_dir\": self.audio_dir,\n                \"dataset_json\": self.dataset_json,\n                \"tensor_output\": self.tensor_output,\n                \"max_duration\": self.max_duration,\n            }\n        )\n        return base\n\n    def save_json(self, path: Path) -> None:\n        \"\"\"Persist the full config to a JSON file.\"\"\"\n        path = Path(path)\n        path.parent.mkdir(parents=True, exist_ok=True)\n        path.write_text(json.dumps(self.to_dict(), indent=2))\n\n    @classmethod\n    def from_json(cls, path: Path) -> \"TrainingConfigV2\":\n        \"\"\"Load config from a JSON file.\"\"\"\n        data = json.loads(Path(path).read_text())\n        return cls(**{k: v for k, v in data.items() if k in cls.__dataclass_fields__})\n"
  },
  {
    "path": "acestep/training_v2/estimate.py",
    "content": "\"\"\"\nGradient Sensitivity Estimation -- Reusable Module\n\nProvides ``run_estimation()`` for use from both the CLI and the TUI.\nMeasures gradient magnitudes per LoRA-targetable module to rank them\nby importance for a given dataset.\n\nUses the same flow-matching forward pass as ``FixedLoRAModule.training_step``\nso that gradient measurements reflect the real training loss surface.\n\"\"\"\n\nfrom __future__ import annotations\n\nimport json\nimport logging\nfrom pathlib import Path\nfrom typing import Any, Callable, Dict, List, Optional\n\nimport torch\nimport torch.nn as nn\nimport torch.nn.functional as F\n\nlogger = logging.getLogger(__name__)\n\n\ndef run_estimation(\n    checkpoint_dir: str,\n    variant: str,\n    dataset_dir: str,\n    num_batches: int = 10,\n    batch_size: int = 1,\n    top_k: int = 16,\n    granularity: str = \"module\",\n    progress_callback: Optional[Callable] = None,\n    cancel_check: Optional[Callable] = None,\n    cfg_ratio: float = 0.0,\n) -> List[Dict[str, Any]]:\n    \"\"\"Run gradient sensitivity analysis and return ranked modules.\n\n    Args:\n        checkpoint_dir: Path to model checkpoints.\n        variant: Model variant (turbo, base, sft).\n        dataset_dir: Directory with preprocessed .pt files.\n        num_batches: Number of forward/backward passes for estimation.\n        batch_size: Samples per estimation batch.\n        top_k: Number of top modules to return.\n        granularity: ``\"module\"`` or ``\"layer\"``.\n        progress_callback: ``(batch, total, module_name) -> None``.\n        cancel_check: ``() -> bool`` -- return True to cancel.\n        cfg_ratio: CFG dropout ratio (default 0).  When > 0 and the model\n            has a ``null_condition_emb``, CFG dropout is applied to\n            ``encoder_hidden_states`` so sensitivity reflects the same\n            masking used during training.\n\n    Returns:\n        List of dicts ``[{\"module\": name, \"sensitivity\": float}, ...]``\n        sorted descending by sensitivity.\n    \"\"\"\n    from acestep.training_v2.model_loader import (\n        load_decoder_for_training,\n        read_model_config,\n        unload_models,\n    )\n    from acestep.training_v2.gpu_utils import detect_gpu\n    from acestep.training_v2.timestep_sampling import sample_timesteps\n    from acestep.training.data_module import PreprocessedDataModule\n\n    gpu = detect_gpu()\n    device = gpu.device\n    device_type = gpu.device_type\n    dtype_map = {\"bf16\": torch.bfloat16, \"fp16\": torch.float16, \"fp32\": torch.float32}\n    dtype = dtype_map.get(gpu.precision, torch.bfloat16)\n\n    # Read timestep parameters from model config.json\n    try:\n        mcfg = read_model_config(checkpoint_dir, variant)\n    except (FileNotFoundError, json.JSONDecodeError):\n        mcfg = {}\n    timestep_mu = mcfg.get(\"timestep_mu\", -0.4)\n    timestep_sigma = mcfg.get(\"timestep_sigma\", 1.0)\n    data_proportion = mcfg.get(\"data_proportion\", 0.5)\n\n    logger.info(\"[Side-Step] Loading model for estimation (variant=%s)\", variant)\n    model = load_decoder_for_training(\n        checkpoint_dir=checkpoint_dir,\n        variant=variant,\n        device=device,\n        precision=gpu.precision,\n    )\n\n    # Identify targetable attention modules\n    target_modules = _find_attention_modules(model, granularity)\n    logger.info(\"[Side-Step] Found %d targetable modules\", len(target_modules))\n\n    if not target_modules:\n        logger.error(\"[Side-Step] No targetable modules found -- aborting estimation\")\n        unload_models(model)\n        return []\n\n    # Build parameter name -> target module mapping for fast lookup\n    param_to_module: Dict[str, str] = {}\n    for pname, _ in model.named_parameters():\n        for mod_name in target_modules:\n            if mod_name in pname:\n                param_to_module[pname] = mod_name\n                break\n\n    # Load data\n    data_module = PreprocessedDataModule(\n        tensor_dir=dataset_dir,\n        batch_size=batch_size,\n        num_workers=0,\n        pin_memory=False,\n    )\n    data_module.setup(\"fit\")\n    loader = data_module.train_dataloader()\n\n    # Accumulate gradient norms per module\n    grad_accum: Dict[str, float] = {name: 0.0 for name in target_modules}\n\n    batches_done = 0\n    for batch in loader:\n        if batches_done >= num_batches:\n            break\n        if cancel_check and cancel_check():\n            break\n\n        # Enable gradients ONLY on targetable parameters\n        for pname, param in model.named_parameters():\n            param.requires_grad = pname in param_to_module\n\n        try:\n            # Move batch to device\n            target_latents = batch[\"target_latents\"].to(device, dtype=dtype)\n            attention_mask = batch[\"attention_mask\"].to(device, dtype=dtype)\n            encoder_hidden_states = batch[\"encoder_hidden_states\"].to(device, dtype=dtype)\n            encoder_attention_mask = batch[\"encoder_attention_mask\"].to(device, dtype=dtype)\n            context_latents = batch[\"context_latents\"].to(device, dtype=dtype)\n\n            bsz = target_latents.shape[0]\n\n            # Autocast for mixed precision\n            if device_type in (\"cuda\", \"xpu\", \"mps\"):\n                autocast_ctx = torch.autocast(device_type=device_type, dtype=dtype)\n            else:\n                from contextlib import nullcontext\n                autocast_ctx = nullcontext()\n\n            with autocast_ctx:\n                # ---- CFG dropout (match training when cfg_ratio > 0) ----\n                if cfg_ratio > 0.0 and hasattr(model, \"null_condition_emb\"):\n                    from acestep.training_v2.fixed_lora_module import apply_cfg_dropout\n                    encoder_hidden_states = apply_cfg_dropout(\n                        encoder_hidden_states,\n                        model.null_condition_emb,\n                        cfg_ratio=cfg_ratio,\n                    )\n\n                # Flow matching noise\n                x0 = target_latents\n                x1 = torch.randn_like(x0)\n\n                # Continuous timestep sampling (matches trainer_fixed)\n                t, _r = sample_timesteps(\n                    batch_size=bsz,\n                    device=device,\n                    dtype=dtype,\n                    data_proportion=data_proportion,\n                    timestep_mu=timestep_mu,\n                    timestep_sigma=timestep_sigma,\n                    use_meanflow=False,\n                )\n                t_ = t.unsqueeze(-1).unsqueeze(-1)\n\n                # Interpolate\n                xt = t_ * x1 + (1.0 - t_) * x0\n\n                # Real decoder forward pass\n                decoder_outputs = model.decoder(\n                    hidden_states=xt,\n                    timestep=t,\n                    timestep_r=t,\n                    attention_mask=attention_mask,\n                    encoder_hidden_states=encoder_hidden_states,\n                    encoder_attention_mask=encoder_attention_mask,\n                    context_latents=context_latents,\n                )\n\n                # Flow matching loss\n                flow = x1 - x0\n                loss = F.mse_loss(decoder_outputs[0], flow)\n\n            loss.backward()\n\n            # Accumulate gradient norms per module\n            for pname, param in model.named_parameters():\n                if param.grad is not None and pname in param_to_module:\n                    mod_name = param_to_module[pname]\n                    grad_accum[mod_name] += param.grad.norm().item()\n\n        except Exception as e:\n            logger.warning(\"[Side-Step] Estimation batch %d failed: %s\", batches_done, e)\n        finally:\n            model.zero_grad()\n            for param in model.parameters():\n                param.requires_grad = False\n\n        batches_done += 1\n        if progress_callback:\n            progress_callback(batches_done, num_batches, \"\")\n\n    # Normalize and rank\n    if batches_done > 0:\n        for name in grad_accum:\n            grad_accum[name] /= batches_done\n\n    ranked = sorted(grad_accum.items(), key=lambda x: x[1], reverse=True)\n    results = [\n        {\"module\": name, \"sensitivity\": score}\n        for name, score in ranked[:top_k]\n    ]\n\n    logger.info(\n        \"[Side-Step] Estimation complete (%d batches): top module = %s (%.6f)\",\n        batches_done,\n        results[0][\"module\"] if results else \"none\",\n        results[0][\"sensitivity\"] if results else 0.0,\n    )\n\n    # Clean up\n    unload_models(model)\n\n    return results\n\n\ndef _find_attention_modules(model: nn.Module, granularity: str) -> List[str]:\n    \"\"\"Find attention module names in the model.\n\n    ACE-Step uses ``q_proj``, ``k_proj``, ``v_proj``, ``o_proj`` naming.\n    \"\"\"\n    modules = []\n    for name, _ in model.named_modules():\n        if granularity == \"module\":\n            # Individual attention projections (ACE-Step naming)\n            if any(proj in name for proj in (\"q_proj\", \"k_proj\", \"v_proj\", \"o_proj\")):\n                modules.append(name)\n        else:\n            # Layer level -- attention blocks (exclude individual projections)\n            if \"attn\" in name.lower() and not any(\n                proj in name for proj in (\"q_proj\", \"k_proj\", \"v_proj\", \"o_proj\", \"norm\")\n            ):\n                modules.append(name)\n\n    if not modules:\n        # Fallback: any module with 'attention' or 'attn' in the name\n        logger.warning(\"[Side-Step] No standard attention modules found; using fallback search\")\n        for name, _ in model.named_modules():\n            if \"attn\" in name.lower():\n                modules.append(name)\n\n    return modules\n"
  },
  {
    "path": "acestep/training_v2/fixed_lora_module.py",
    "content": "\"\"\"\nFixedLoRAModule -- Corrected adapter training step for ACE-Step V2.\n\nThis module contains the ``FixedLoRAModule`` (nn.Module) responsible for\nthe per-step training logic: CFG dropout, logit-normal timestep sampling,\nflow-matching interpolation, and the decoder forward pass.\n\nAlso includes small device/dtype/precision helpers used by both the\nFabric and basic training loops.\n\"\"\"\n\nfrom __future__ import annotations\n\nimport logging\nfrom contextlib import nullcontext\nfrom typing import Any, Dict, Union\n\nimport torch\nimport torch.nn as nn\nimport torch.nn.functional as F\n\n# ACE-Step utilities\nfrom acestep.training.lora_injection import inject_lora_into_dit\nfrom acestep.training.lora_utils import check_peft_available\nfrom acestep.training.lokr_utils import (\n    check_lycoris_available,\n    inject_lokr_into_dit,\n)\n\n# V2 modules\nfrom acestep.training_v2.configs import LoRAConfigV2, LoKRConfigV2, TrainingConfigV2\nfrom acestep.training_v2.timestep_sampling import apply_cfg_dropout, sample_timesteps\nfrom acestep.training_v2.ui import TrainingUpdate\n\n# Union type for adapter configs\nAdapterConfig = Union[LoRAConfigV2, LoKRConfigV2]\n\n\nclass _LastLossAccessor:\n    \"\"\"Lightweight wrapper that provides ``[-1]`` and bool access.\n\n    Avoids storing an unbounded list of floats while keeping backward\n    compatibility with code that reads ``module.training_losses[-1]``\n    or checks ``if module.training_losses:``.\n    \"\"\"\n\n    def __init__(self, module: \"FixedLoRAModule\") -> None:\n        self._module = module\n        self._has_value = False\n\n    def append(self, value: float) -> None:\n        self._module.last_training_loss = value\n        self._has_value = True\n\n    def __getitem__(self, idx: int) -> float:\n        if idx == -1 or idx == 0:\n            return self._module.last_training_loss\n        raise IndexError(\"only index -1 or 0 is supported\")\n\n    def __bool__(self) -> bool:\n        return self._has_value\n\n    def __len__(self) -> int:\n        return 1 if self._has_value else 0\n\n\nlogger = logging.getLogger(__name__)\n\n\n# ---------------------------------------------------------------------------\n# Helpers\n# ---------------------------------------------------------------------------\n\n\ndef _normalize_device_type(device: Any) -> str:\n    if isinstance(device, torch.device):\n        return device.type\n    if isinstance(device, str):\n        return device.split(\":\", 1)[0]\n    return str(device)\n\n\ndef _select_compute_dtype(device_type: str) -> torch.dtype:\n    if device_type in (\"cuda\", \"xpu\"):\n        return torch.bfloat16\n    if device_type == \"mps\":\n        return torch.float16\n    return torch.float32\n\n\ndef _select_fabric_precision(device_type: str) -> str:\n    if device_type in (\"cuda\", \"xpu\"):\n        return \"bf16-mixed\"\n    if device_type == \"mps\":\n        return \"16-mixed\"\n    return \"32-true\"\n\n\n# ===========================================================================\n# FixedLoRAModule -- corrected training step\n# ===========================================================================\n\n\nclass FixedLoRAModule(nn.Module):\n    \"\"\"Adapter training module with corrected timestep sampling and CFG dropout.\n\n    Supports both LoRA (PEFT) and LoKR (LyCORIS) adapters.  The training\n    step is identical for both -- only the injection and weight format differ.\n\n    Training flow (per step):\n        1. Load pre-computed tensors (from ``PreprocessedDataModule``).\n        2. Apply **CFG dropout** on ``encoder_hidden_states``.\n        3. Sample noise ``x1`` and continuous timestep ``t`` via\n           ``sample_timesteps()`` (logit-normal).\n        4. Interpolate ``x_t = t * x1 + (1 - t) * x0``.\n        5. Forward through decoder, compute flow matching loss.\n    \"\"\"\n\n    def __init__(\n        self,\n        model: nn.Module,\n        adapter_config: AdapterConfig,\n        training_config: TrainingConfigV2,\n        device: torch.device,\n        dtype: torch.dtype,\n    ) -> None:\n        super().__init__()\n\n        self.adapter_config = adapter_config\n        self.adapter_type = training_config.adapter_type\n        self.training_config = training_config\n        self.device = torch.device(device) if isinstance(device, str) else device\n        self.device_type = _normalize_device_type(self.device)\n        self.dtype = _select_compute_dtype(self.device_type)\n        self.transfer_non_blocking = self.device_type in (\"cuda\", \"xpu\")\n\n        # LyCORIS network reference (only set for LoKR)\n        self.lycoris_net: Any = None\n        self.adapter_info: Dict[str, Any] = {}\n\n        # -- Adapter injection -----------------------------------------------\n        if self.adapter_type == \"lokr\":\n            self._inject_lokr(model, adapter_config)  # type: ignore[arg-type]\n        else:\n            self._inject_lora(model, adapter_config)  # type: ignore[arg-type]\n\n        # Backward-compat alias\n        self.lora_info = self.adapter_info\n\n        # Model config (for timestep params read at runtime)\n        self.config = model.config\n\n        # -- Null condition embedding for CFG dropout ------------------------\n        # ``model.null_condition_emb`` is a Parameter on the top-level model\n        # (not the decoder).\n        if hasattr(model, \"null_condition_emb\"):\n            self._null_cond_emb = model.null_condition_emb\n        else:\n            self._null_cond_emb = None\n            logger.warning(\n                \"[WARN] model.null_condition_emb not found -- CFG dropout disabled\"\n            )\n\n        # -- Timestep sampling params ----------------------------------------\n        self._timestep_mu = training_config.timestep_mu\n        self._timestep_sigma = training_config.timestep_sigma\n        self._data_proportion = training_config.data_proportion\n        self._cfg_ratio = training_config.cfg_ratio\n\n        # When gradient checkpointing is enabled via wrapper layers that don't\n        # expose enable_input_require_grads(), force at least one forward input\n        # to require grad so checkpointed segments keep a valid autograd graph.\n        self.force_input_grads_for_checkpointing: bool = False\n\n        # Book-keeping -- store only the most recent loss to avoid\n        # unbounded memory growth over long training runs.\n        self.last_training_loss: float = 0.0\n\n        # Backward-compat: property provides list-like [-1] access\n        # for callers that read ``training_losses[-1]``.\n        self.training_losses = _LastLossAccessor(self)\n\n    # -----------------------------------------------------------------------\n    # Adapter injection helpers\n    # -----------------------------------------------------------------------\n\n    def _inject_lora(self, model: nn.Module, cfg: LoRAConfigV2) -> None:\n        \"\"\"Inject LoRA adapters via PEFT.\n\n        Raises:\n            RuntimeError: If PEFT is not installed.\n        \"\"\"\n        if not check_peft_available():\n            raise RuntimeError(\n                \"PEFT is required for LoRA training but is not installed.\\n\"\n                \"Install it with:  uv pip install peft\"\n            )\n        self.model, self.adapter_info = inject_lora_into_dit(model, cfg)\n        logger.info(\n            \"[OK] LoRA injected: %s trainable params\",\n            f\"{self.adapter_info['trainable_params']:,}\",\n        )\n\n    def _inject_lokr(self, model: nn.Module, cfg: LoKRConfigV2) -> None:\n        \"\"\"Inject LoKR adapters via LyCORIS.\n\n        After injection, explicitly moves the model to the target device\n        so that newly created LoKR parameters (which LyCORIS creates on\n        CPU) end up on GPU before Fabric wraps the model.\n\n        Raises:\n            RuntimeError: If LyCORIS is not installed.\n        \"\"\"\n        if not check_lycoris_available():\n            raise RuntimeError(\n                \"LyCORIS is required for LoKR training but is not installed.\\n\"\n                \"Install it with:  uv pip install lycoris-lora\"\n            )\n        self.model, self.lycoris_net, self.adapter_info = inject_lokr_into_dit(\n            model,\n            cfg,\n        )\n        # LyCORIS creates adapter parameters on CPU.  Move the entire\n        # model to the target device so all parameters (including the\n        # new LoKR ones) are co-located before Fabric setup.\n        self.model = self.model.to(self.device)\n        logger.info(\n            \"[OK] LoKR injected: %s trainable params (moved to %s)\",\n            f\"{self.adapter_info['trainable_params']:,}\",\n            self.device,\n        )\n\n    # -----------------------------------------------------------------------\n    # Training step\n    # -----------------------------------------------------------------------\n\n    def training_step(self, batch: Dict[str, torch.Tensor]) -> torch.Tensor:\n        \"\"\"Single training step with corrected timestep sampling + CFG dropout.\n\n        Args:\n            batch: Dict with keys ``target_latents``, ``attention_mask``,\n                ``encoder_hidden_states``, ``encoder_attention_mask``,\n                ``context_latents``.\n\n        Returns:\n            Scalar loss tensor (``float32`` for stable backward).\n        \"\"\"\n        # Mixed-precision context\n        if self.device_type in (\"cuda\", \"xpu\", \"mps\"):\n            autocast_ctx = torch.autocast(\n                device_type=self.device_type, dtype=self.dtype\n            )\n        else:\n            autocast_ctx = nullcontext()\n\n        with autocast_ctx:\n            nb = self.transfer_non_blocking\n\n            target_latents = batch[\"target_latents\"].to(\n                self.device, dtype=self.dtype, non_blocking=nb\n            )\n            attention_mask = batch[\"attention_mask\"].to(\n                self.device, dtype=self.dtype, non_blocking=nb\n            )\n            encoder_hidden_states = batch[\"encoder_hidden_states\"].to(\n                self.device, dtype=self.dtype, non_blocking=nb\n            )\n            encoder_attention_mask = batch[\"encoder_attention_mask\"].to(\n                self.device, dtype=self.dtype, non_blocking=nb\n            )\n            context_latents = batch[\"context_latents\"].to(\n                self.device, dtype=self.dtype, non_blocking=nb\n            )\n\n            bsz = target_latents.shape[0]\n\n            # ---- CFG dropout (CORRECTED -- missing in original trainer) ----\n            if self._null_cond_emb is not None and self._cfg_ratio > 0.0:\n                encoder_hidden_states = apply_cfg_dropout(\n                    encoder_hidden_states,\n                    self._null_cond_emb,\n                    cfg_ratio=self._cfg_ratio,\n                )\n\n            # ---- Flow matching noise ----------------------------------------\n            x1 = torch.randn_like(target_latents)  # noise\n            x0 = target_latents  # data\n\n            # ---- Continuous timestep sampling (CORRECTED) -------------------\n            t, r = sample_timesteps(\n                batch_size=bsz,\n                device=self.device,\n                dtype=self.dtype,\n                data_proportion=self._data_proportion,\n                timestep_mu=self._timestep_mu,\n                timestep_sigma=self._timestep_sigma,\n                use_meanflow=False,  # r = t for all ACE-Step variants\n            )\n            t_ = t.unsqueeze(-1).unsqueeze(-1)\n\n            # ---- Interpolate x_t -------------------------------------------\n            xt = t_ * x1 + (1.0 - t_) * x0\n            if self.force_input_grads_for_checkpointing:\n                xt = xt.requires_grad_(True)\n\n            # ---- Decoder forward -------------------------------------------\n            decoder_outputs = self.model.decoder(\n                hidden_states=xt,\n                timestep=t,\n                timestep_r=t,  # r = t\n                attention_mask=attention_mask,\n                encoder_hidden_states=encoder_hidden_states,\n                encoder_attention_mask=encoder_attention_mask,\n                context_latents=context_latents,\n            )\n\n            # ---- Flow matching loss ----------------------------------------\n            flow = x1 - x0\n            diffusion_loss = F.mse_loss(decoder_outputs[0], flow)\n\n        # fp32 for stable backward\n        diffusion_loss = diffusion_loss.float()\n        self.training_losses.append(diffusion_loss.item())\n        return diffusion_loss\n"
  },
  {
    "path": "acestep/training_v2/gpu_utils.py",
    "content": "\"\"\"\nGPU Detection, VRAM Query, and Estimation Budget Calculation\n\nProvides:\n    detect_gpu()            -- auto-detect best available accelerator\n    get_available_vram_mb() -- query free VRAM on the selected device\n    estimate_batch_budget() -- compute how many estimation batches fit in VRAM\n\"\"\"\n\nfrom __future__ import annotations\n\nimport logging\nfrom dataclasses import dataclass\nfrom typing import Optional\n\nimport torch\n\nlogger = logging.getLogger(__name__)\n\n# ---------------------------------------------------------------------------\n# GPU detection\n# ---------------------------------------------------------------------------\n\n@dataclass\nclass GPUInfo:\n    \"\"\"Describes the detected accelerator.\"\"\"\n\n    device: str\n    \"\"\"Torch device string, e.g. 'cuda:0', 'mps', 'xpu', 'cpu'.\"\"\"\n\n    device_type: str\n    \"\"\"Canonical type: 'cuda', 'mps', 'xpu', 'cpu'.\"\"\"\n\n    name: str\n    \"\"\"Human-readable device name.\"\"\"\n\n    vram_total_mb: Optional[float] = None\n    \"\"\"Total device memory in MiB (None for CPU / unknown).\"\"\"\n\n    vram_free_mb: Optional[float] = None\n    \"\"\"Free device memory in MiB (None for CPU / unknown).\"\"\"\n\n    precision: str = \"fp32\"\n    \"\"\"Recommended precision for this device.\"\"\"\n\n    def __str__(self) -> str:\n        parts = [f\"device={self.device}\", f\"name={self.name}\"]\n        if self.vram_total_mb is not None:\n            parts.append(f\"vram_total={self.vram_total_mb:.0f}MiB\")\n        if self.vram_free_mb is not None:\n            parts.append(f\"vram_free={self.vram_free_mb:.0f}MiB\")\n        parts.append(f\"precision={self.precision}\")\n        return \"GPUInfo(\" + \", \".join(parts) + \")\"\n\n\ndef detect_gpu(requested_device: str = \"auto\", requested_precision: str = \"auto\") -> GPUInfo:\n    \"\"\"Detect the best available accelerator.\n\n    Priority: CUDA > MPS > XPU > CPU.\n\n    Args:\n        requested_device: 'auto', 'cuda', 'cuda:N', 'mps', 'xpu', 'cpu'.\n        requested_precision: 'auto', 'bf16', 'fp16', 'fp32'.\n\n    Returns:\n        GPUInfo with device string, name, VRAM stats, and recommended precision.\n    \"\"\"\n    device_type: str\n    device_str: str\n    name: str\n    vram_total: Optional[float] = None\n    vram_free: Optional[float] = None\n\n    if requested_device == \"auto\":\n        if torch.cuda.is_available():\n            device_str = \"cuda:0\"\n            device_type = \"cuda\"\n        elif hasattr(torch.backends, \"mps\") and torch.backends.mps.is_available():\n            device_str = \"mps\"\n            device_type = \"mps\"\n        elif hasattr(torch, \"xpu\") and torch.xpu.is_available():\n            device_str = \"xpu:0\"\n            device_type = \"xpu\"\n        else:\n            device_str = \"cpu\"\n            device_type = \"cpu\"\n    else:\n        device_str = requested_device\n        device_type = requested_device.split(\":\")[0]\n\n    # Resolve name + VRAM\n    if device_type == \"cuda\":\n        idx = 0\n        if \":\" in device_str:\n            idx = int(device_str.split(\":\")[1])\n        name = torch.cuda.get_device_name(idx)\n        vram_total = torch.cuda.get_device_properties(idx).total_memory / (1024 ** 2)\n        vram_free = _cuda_free_mb(idx)\n    elif device_type == \"mps\":\n        name = \"Apple MPS\"\n    elif device_type == \"xpu\":\n        idx = 0\n        if \":\" in device_str:\n            idx = int(device_str.split(\":\")[1])\n        name = f\"Intel XPU:{idx}\"\n        if hasattr(torch.xpu, \"get_device_properties\"):\n            props = torch.xpu.get_device_properties(idx)\n            vram_total = getattr(props, \"total_memory\", 0) / (1024 ** 2)\n    else:\n        name = \"CPU\"\n\n    # Resolve precision\n    if requested_precision == \"auto\":\n        if device_type in (\"cuda\", \"xpu\"):\n            precision = \"bf16\"\n        elif device_type == \"mps\":\n            precision = \"fp16\"\n        else:\n            precision = \"fp32\"\n    else:\n        precision = requested_precision\n\n    return GPUInfo(\n        device=device_str,\n        device_type=device_type,\n        name=name,\n        vram_total_mb=vram_total,\n        vram_free_mb=vram_free,\n        precision=precision,\n    )\n\n\n# ---------------------------------------------------------------------------\n# VRAM helpers\n# ---------------------------------------------------------------------------\n\ndef _cuda_free_mb(idx: int = 0) -> float:\n    \"\"\"Return free CUDA memory in MiB for device *idx*.\"\"\"\n    torch.cuda.synchronize(idx)\n    free, _total = torch.cuda.mem_get_info(idx)\n    return free / (1024 ** 2)\n\n\ndef get_available_vram_mb(device: str = \"auto\") -> Optional[float]:\n    \"\"\"Query free VRAM on the given device.\n\n    Returns None when VRAM cannot be determined (CPU / MPS).\n    \"\"\"\n    info = detect_gpu(requested_device=device)\n    return info.vram_free_mb\n\n\n# ---------------------------------------------------------------------------\n# Estimation batch budget\n# ---------------------------------------------------------------------------\n\n# Rough per-batch memory estimate for a single forward+backward pass through\n# the full DiT decoder (24 layers, hidden_size=2048) with all parameters\n# requiring gradients.  This is a *very* conservative upper bound.\n_BYTES_PER_BATCH_ESTIMATE_BF16: float = 1200.0  # ~1.2 GiB per sample\n\n\ndef get_gpu_info(device: str = \"auto\") -> dict:\n    \"\"\"Return GPU info as a flat dict suitable for TUI widgets.\n\n    Keys: name, vram_used_gb, vram_total_gb, utilization, temperature, power.\n    Missing values are returned as 0.\n    \"\"\"\n    try:\n        info = detect_gpu(requested_device=device)\n        total_mb = info.vram_total_mb or 0\n        free_mb = info.vram_free_mb or 0\n        used_mb = max(0, total_mb - free_mb)\n        return {\n            \"name\": info.name,\n            \"vram_used_gb\": used_mb / 1024,\n            \"vram_total_gb\": total_mb / 1024,\n            \"utilization\": 0,  # nvidia-smi would be needed for live util\n            \"temperature\": 0,\n            \"power\": 0,\n        }\n    except Exception:\n        return {\n            \"name\": \"Unknown\",\n            \"vram_used_gb\": 0,\n            \"vram_total_gb\": 0,\n            \"utilization\": 0,\n            \"temperature\": 0,\n            \"power\": 0,\n        }\n\n\ndef estimate_batch_budget(\n    device: str = \"auto\",\n    safety_factor: float = 0.8,\n    min_batches: int = 4,\n    max_batches: int = 64,\n) -> int:\n    \"\"\"Estimate how many estimation batches fit in available VRAM.\n\n    Args:\n        device: Device string or 'auto'.\n        safety_factor: Fraction of free VRAM to use (0-1).\n        min_batches: Floor value.\n        max_batches: Ceiling value.\n\n    Returns:\n        Number of estimation batches (clamped to [min_batches, max_batches]).\n    \"\"\"\n    free_mb = get_available_vram_mb(device)\n    if free_mb is None:\n        logger.info(\"[INFO] VRAM unknown -- using minimum batch budget of %d\", min_batches)\n        return min_batches\n\n    usable_mb = free_mb * safety_factor\n    # Subtract ~4 GiB for the model weights themselves\n    usable_mb = max(0.0, usable_mb - 4096.0)\n    n_batches = int(usable_mb / _BYTES_PER_BATCH_ESTIMATE_BF16)\n    n_batches = max(min_batches, min(n_batches, max_batches))\n\n    logger.info(\n        \"[INFO] Estimation budget: %d batches (%.0f MiB free, %.0f MiB usable)\",\n        n_batches,\n        free_mb,\n        usable_mb,\n    )\n    return n_batches\n"
  },
  {
    "path": "acestep/training_v2/make_test_fixtures.py",
    "content": "#!/usr/bin/env python3\n\"\"\"\nGenerate synthetic preprocessed tensor fixtures for end-to-end testing.\n\nCreates N fake .pt files with correct tensor shapes so the full training\npipeline can be exercised without needing real audio data or the VAE/encoder.\n\nTensor shapes (matching the real preprocessing pipeline):\n    target_latents       : [T, 64]    (audio_acoustic_hidden_dim)\n    attention_mask       : [T]\n    encoder_hidden_states: [L, 2048]  (hidden_size)\n    encoder_attention_mask: [L]\n    context_latents      : [T, 128]   (64 src_latents + 64 chunk_masks)\n\nUsage:\n    python -m acestep.training_v2.make_test_fixtures \\\\\n        --output-dir ./test_fixtures --num-samples 4\n\nOr from another script:\n    from acestep.training_v2.make_test_fixtures import generate_fixtures\n    generate_fixtures(Path(\"./test_fixtures\"), num_samples=4)\n\"\"\"\n\nfrom __future__ import annotations\n\nimport argparse\nimport json\nimport sys\nfrom pathlib import Path\n\nimport torch\n\n\n# Default dimensions matching the turbo model config\n_TARGET_DIM = 64          # audio_acoustic_hidden_dim\n_CONTEXT_DIM = 128        # 64 (src_latents) + 64 (chunk_masks)\n_ENCODER_DIM = 2048       # hidden_size\n_LATENT_LENGTH = 128      # Short sequence for fast testing\n_ENCODER_LENGTH = 64      # Encoder sequence length\n\n\ndef generate_single_sample(\n    sample_id: str,\n    latent_length: int = _LATENT_LENGTH,\n    encoder_length: int = _ENCODER_LENGTH,\n    dtype: torch.dtype = torch.float32,\n) -> dict:\n    \"\"\"Generate a single synthetic preprocessed sample.\n\n    All tensors are random (no semantic meaning), but shapes are correct\n    for the DiT decoder.\n    \"\"\"\n    return {\n        \"target_latents\": torch.randn(latent_length, _TARGET_DIM, dtype=dtype),\n        \"attention_mask\": torch.ones(latent_length, dtype=dtype),\n        \"encoder_hidden_states\": torch.randn(encoder_length, _ENCODER_DIM, dtype=dtype),\n        \"encoder_attention_mask\": torch.ones(encoder_length, dtype=dtype),\n        \"context_latents\": torch.randn(latent_length, _CONTEXT_DIM, dtype=dtype),\n        \"metadata\": {\n            \"sample_id\": sample_id,\n            \"caption\": f\"Test sample {sample_id}\",\n            \"lyrics\": \"[Instrumental]\",\n            \"duration\": latent_length * 0.01,\n            \"is_synthetic\": True,\n        },\n    }\n\n\ndef generate_fixtures(\n    output_dir: Path,\n    num_samples: int = 4,\n    latent_length: int = _LATENT_LENGTH,\n    encoder_length: int = _ENCODER_LENGTH,\n) -> Path:\n    \"\"\"Generate *num_samples* synthetic .pt files + manifest.json.\n\n    Args:\n        output_dir: Directory to write fixtures to.\n        num_samples: Number of samples to generate.\n        latent_length: Latent sequence length (T dimension).\n        encoder_length: Encoder sequence length (L dimension).\n\n    Returns:\n        Path to the output directory.\n    \"\"\"\n    output_dir = Path(output_dir)\n    output_dir.mkdir(parents=True, exist_ok=True)\n\n    sample_paths = []\n    for i in range(num_samples):\n        sample_id = f\"test_{i:04d}\"\n        data = generate_single_sample(\n            sample_id=sample_id,\n            latent_length=latent_length,\n            encoder_length=encoder_length,\n        )\n        pt_path = output_dir / f\"{sample_id}.pt\"\n        torch.save(data, str(pt_path))\n        sample_paths.append(str(pt_path))\n\n    # Write manifest\n    manifest = {\n        \"metadata\": {\n            \"type\": \"synthetic_test_fixtures\",\n            \"num_samples\": num_samples,\n            \"latent_length\": latent_length,\n            \"encoder_length\": encoder_length,\n        },\n        \"samples\": sample_paths,\n        \"num_samples\": num_samples,\n    }\n    manifest_path = output_dir / \"manifest.json\"\n    manifest_path.write_text(json.dumps(manifest, indent=2))\n\n    print(f\"[OK] Generated {num_samples} synthetic fixtures in {output_dir}\")\n    return output_dir\n\n\ndef main() -> int:\n    parser = argparse.ArgumentParser(\n        description=\"Generate synthetic preprocessed tensor fixtures for testing\",\n    )\n    parser.add_argument(\n        \"--output-dir\",\n        type=str,\n        default=\"./test_fixtures\",\n        help=\"Output directory (default: ./test_fixtures)\",\n    )\n    parser.add_argument(\n        \"--num-samples\",\n        type=int,\n        default=4,\n        help=\"Number of samples to generate (default: 4)\",\n    )\n    parser.add_argument(\n        \"--latent-length\",\n        type=int,\n        default=_LATENT_LENGTH,\n        help=f\"Latent sequence length (default: {_LATENT_LENGTH})\",\n    )\n    parser.add_argument(\n        \"--encoder-length\",\n        type=int,\n        default=_ENCODER_LENGTH,\n        help=f\"Encoder sequence length (default: {_ENCODER_LENGTH})\",\n    )\n\n    args = parser.parse_args()\n    generate_fixtures(\n        output_dir=Path(args.output_dir),\n        num_samples=args.num_samples,\n        latent_length=args.latent_length,\n        encoder_length=args.encoder_length,\n    )\n    return 0\n\n\nif __name__ == \"__main__\":\n    sys.exit(main())\n"
  },
  {
    "path": "acestep/training_v2/model_discovery.py",
    "content": "\"\"\"\nModel discovery and selection for Side-Step.\n\nScans a checkpoint directory for model subdirectories (identified by the\npresence of a ``config.json``), classifies them as official or custom\n(fine-tune), and provides an interactive fuzzy-search picker.\n\"\"\"\n\nfrom __future__ import annotations\n\nimport difflib\nimport json\nimport logging\nfrom dataclasses import dataclass, field\nfrom pathlib import Path\nfrom typing import Dict, List, Optional, Tuple\n\nlogger = logging.getLogger(__name__)\n\n# Official ACE-Step model directory name patterns.\n_OFFICIAL_PREFIXES = (\"acestep-v15-\", \"acestep-v1-\")\n\n# Known base-model fingerprints: (is_turbo, timestep_mu approx range).\n_BASE_DEFAULTS: Dict[str, Dict] = {\n    \"turbo\": {\"is_turbo\": True, \"timestep_mu\": -0.4, \"timestep_sigma\": 1.0, \"shift\": 3.0, \"num_inference_steps\": 8},\n    \"base\":  {\"is_turbo\": False, \"timestep_mu\": -0.4, \"timestep_sigma\": 1.0, \"shift\": 1.0, \"num_inference_steps\": 50},\n    \"sft\":   {\"is_turbo\": False, \"timestep_mu\": -0.4, \"timestep_sigma\": 1.0, \"shift\": 1.0, \"num_inference_steps\": 50},\n}\n\n\n@dataclass\nclass ModelInfo:\n    \"\"\"Metadata about a discovered model directory.\"\"\"\n\n    name: str\n    path: Path\n    is_official: bool\n    config: Dict = field(default_factory=dict)\n    base_model: str = \"unknown\"\n\n\n# ---------------------------------------------------------------------------\n# Scanning\n# ---------------------------------------------------------------------------\n\ndef scan_models(checkpoint_dir: str | Path) -> List[ModelInfo]:\n    \"\"\"Scan *checkpoint_dir* for model subdirectories.\n\n    A valid model directory contains a ``config.json`` with either an\n    ``auto_map`` key (HuggingFace custom model) or a ``model_type`` key.\n    Non-model directories (``vae/``, ``Qwen3-*``, ``*.lm-*``) are\n    excluded automatically.\n\n    Returns a sorted list of :class:`ModelInfo` (officials first, then\n    alphabetical).\n    \"\"\"\n    ckpt = Path(checkpoint_dir)\n    if not ckpt.is_dir():\n        return []\n\n    skip_names = {\"vae\", \".git\", \"__pycache__\"}\n    skip_prefixes = (\"Qwen\", \"acestep-5Hz\")\n\n    results: List[ModelInfo] = []\n    for child in sorted(ckpt.iterdir()):\n        if not child.is_dir():\n            continue\n        if child.name in skip_names:\n            continue\n        if any(child.name.startswith(p) for p in skip_prefixes):\n            continue\n\n        cfg_path = child / \"config.json\"\n        if not cfg_path.is_file():\n            continue\n\n        try:\n            cfg = json.loads(cfg_path.read_text(encoding=\"utf-8\"))\n        except (json.JSONDecodeError, OSError):\n            continue\n\n        # Must look like a model config (not just any JSON)\n        if \"auto_map\" not in cfg and \"model_type\" not in cfg:\n            continue\n\n        is_official = any(child.name.startswith(p) for p in _OFFICIAL_PREFIXES)\n        base = detect_base_model(cfg, child.name)\n\n        results.append(ModelInfo(\n            name=child.name,\n            path=child,\n            is_official=is_official,\n            config=cfg,\n            base_model=base,\n        ))\n\n    # Sort: officials first, then alphabetical\n    results.sort(key=lambda m: (not m.is_official, m.name))\n    return results\n\n\n# ---------------------------------------------------------------------------\n# Base-model detection\n# ---------------------------------------------------------------------------\n\ndef detect_base_model(config: Dict, dir_name: str = \"\") -> str:\n    \"\"\"Infer which base variant a model descends from.\n\n    Uses ``is_turbo`` flag and directory name heuristics.  Returns one\n    of ``\"turbo\"``, ``\"base\"``, ``\"sft\"``, or ``\"unknown\"``.\n    \"\"\"\n    # Explicit is_turbo flag\n    if config.get(\"is_turbo\", False):\n        return \"turbo\"\n\n    # Match by directory name for official models\n    name_lower = dir_name.lower()\n    for variant in (\"turbo\", \"base\", \"sft\"):\n        if variant in name_lower:\n            return variant\n\n    return \"unknown\"\n\n\ndef get_base_defaults(base_model: str) -> Dict:\n    \"\"\"Return default timestep params for a known base variant.\"\"\"\n    return dict(_BASE_DEFAULTS.get(base_model, _BASE_DEFAULTS[\"base\"]))\n\n\n# ---------------------------------------------------------------------------\n# Fuzzy search\n# ---------------------------------------------------------------------------\n\ndef fuzzy_search(query: str, models: List[ModelInfo]) -> List[ModelInfo]:\n    \"\"\"Filter models by fuzzy name match.\n\n    Tries substring match first, then ``difflib.get_close_matches``.\n    Returns matching models in relevance order.\n    \"\"\"\n    if not query:\n        return list(models)\n\n    q = query.lower()\n\n    # 1. Substring matches (most intuitive)\n    substring_hits = [m for m in models if q in m.name.lower()]\n    if substring_hits:\n        return substring_hits\n\n    # 2. Fuzzy matches via difflib\n    names = [m.name for m in models]\n    close = difflib.get_close_matches(query, names, n=5, cutoff=0.4)\n    name_set = set(close)\n    return [m for m in models if m.name in name_set]\n\n\n# ---------------------------------------------------------------------------\n# Interactive picker\n# ---------------------------------------------------------------------------\n\ndef pick_model(\n    checkpoint_dir: str | Path,\n) -> Optional[Tuple[str, ModelInfo]]:\n    \"\"\"Interactive model selector with fuzzy search.\n\n    Scans *checkpoint_dir*, lists all discovered models, and lets the\n    user pick by number or type a name to search.\n\n    Returns ``(model_name, ModelInfo)`` or ``None`` if no models found.\n\n    Raises:\n        GoBack: When user types 'b'/'back'.\n    \"\"\"\n    from acestep.training_v2.ui import console, is_rich_active\n    from acestep.training_v2.ui.prompt_helpers import GoBack, menu, ask\n\n    models = scan_models(checkpoint_dir)\n    if not models:\n        return None\n\n    # Build menu options\n    options = []\n    for m in models:\n        tag = \"(official)\" if m.is_official else f\"(custom, base: {m.base_model})\"\n        options.append((m.name, f\"{m.name}  {tag}\"))\n\n    # Add search option at the end\n    options.append((\"__search__\", \"Search by name...\"))\n\n    choice = menu(\n        \"Select a model to train on\",\n        options,\n        default=1,\n        allow_back=True,\n    )\n\n    if choice == \"__search__\":\n        return _search_loop(models)\n\n    # Find the matching model\n    for m in models:\n        if m.name == choice:\n            return (m.name, m)\n\n    return None\n\n\ndef _search_loop(models: List[ModelInfo]) -> Optional[Tuple[str, ModelInfo]]:\n    \"\"\"Fuzzy-search sub-flow for model selection.\"\"\"\n    from acestep.training_v2.ui import console, is_rich_active\n    from acestep.training_v2.ui.prompt_helpers import GoBack, ask, menu\n\n    while True:\n        query = ask(\"Enter model name (or part of it)\", allow_back=True)\n        hits = fuzzy_search(query, models)\n\n        if not hits:\n            _msg = \"  No matches found. Try a different search term.\"\n            if is_rich_active() and console is not None:\n                console.print(f\"  [yellow]{_msg}[/]\")\n            else:\n                print(_msg)\n            continue\n\n        if len(hits) == 1:\n            return (hits[0].name, hits[0])\n\n        options = []\n        for m in hits:\n            tag = \"(official)\" if m.is_official else f\"(custom, base: {m.base_model})\"\n            options.append((m.name, f\"{m.name}  {tag}\"))\n\n        choice = menu(\"Multiple matches -- pick one\", options, default=1, allow_back=True)\n        for m in hits:\n            if m.name == choice:\n                return (m.name, m)\n\n\ndef prompt_base_model(model_name: str) -> str:\n    \"\"\"Ask the user which base model a fine-tune descends from.\n\n    Returns ``\"turbo\"``, ``\"base\"``, or ``\"sft\"``.\n    \"\"\"\n    from acestep.training_v2.ui import console, is_rich_active\n    from acestep.training_v2.ui.prompt_helpers import menu\n\n    from acestep.training_v2.ui.prompt_helpers import _esc\n\n    if is_rich_active() and console is not None:\n        console.print(\n            f\"\\n  [yellow]'{_esc(model_name)}' appears to be a custom fine-tune.[/]\"\n        )\n        console.print(\n            \"  [dim]Knowing the base model helps condition timestep sampling.[/]\\n\"\n        )\n    else:\n        print(f\"\\n  '{model_name}' appears to be a custom fine-tune.\")\n        print(\"  Knowing the base model helps condition timestep sampling.\\n\")\n\n    return menu(\n        \"Which base model was this fine-tune trained from?\",\n        [\n            (\"turbo\", \"Turbo (8-step accelerated)\"),\n            (\"base\", \"Base (full diffusion)\"),\n            (\"sft\", \"SFT (supervised fine-tune)\"),\n        ],\n        default=1,\n        allow_back=True,\n    )\n"
  },
  {
    "path": "acestep/training_v2/model_loader.py",
    "content": "\"\"\"\nLean Per-Phase Model Loading for ACE-Step Training V2\n\nTwo entry points:\n    load_preprocessing_models()  -- VAE + text encoder + condition encoder\n    load_decoder_for_training()  -- Full model with decoder accessible\n\nEach function loads only what is needed for its phase, supports torch.no_grad()\ncontext, and provides proper cleanup helpers.\n\"\"\"\n\nfrom __future__ import annotations\n\nimport gc\nimport json\nimport logging\nfrom pathlib import Path\nfrom typing import Any, Dict, Optional, Tuple\n\nimport torch\n\nlogger = logging.getLogger(__name__)\n\n\ndef _is_flash_attention_available(device: str) -> bool:\n    \"\"\"Check if flash_attn is usable on the target device.\n\n    Requirements (all must be met):\n        1. Device is CUDA.\n        2. GPU compute capability >= 8.0 (Ampere / RTX 30xx or newer).\n        3. ``flash_attn`` package is importable.\n    \"\"\"\n    if not device.startswith(\"cuda\"):\n        return False\n    try:\n        dev_idx = int(device.split(\":\")[1]) if \":\" in device else 0\n        props = torch.cuda.get_device_properties(dev_idx)\n        if props.major < 8:\n            logger.info(\n                \"[INFO] Flash Attention skipped: GPU compute capability %d.%d < 8.0\",\n                props.major, props.minor,\n            )\n            return False\n    except Exception:\n        return False\n    try:\n        import flash_attn  # noqa: F401\n        return True\n    except ImportError:\n        return False\n\n\n# Variant -> subdirectory mapping\n_VARIANT_DIR = {\n    \"turbo\": \"acestep-v15-turbo\",\n    \"base\": \"acestep-v15-base\",\n    \"sft\": \"acestep-v15-sft\",\n}\n\n\ndef _resolve_model_dir(checkpoint_dir: str | Path, variant: str) -> Path:\n    \"\"\"Return the model subdirectory for *variant* under *checkpoint_dir*.\n\n    Checks the known ``_VARIANT_DIR`` mapping first.  If *variant* is not\n    a recognised alias, it is treated as a literal subdirectory name (to\n    support custom fine-tunes with arbitrary folder names).\n    \"\"\"\n    # 1. Known alias (turbo -> acestep-v15-turbo, etc.)\n    subdir = _VARIANT_DIR.get(variant)\n    if subdir is not None:\n        p = Path(checkpoint_dir) / subdir\n        if p.is_dir():\n            return p\n\n    # 2. Literal subdirectory name (e.g. \"my-custom-finetune\")\n    p = Path(checkpoint_dir) / variant\n    if p.is_dir():\n        return p\n\n    # 3. None found\n    raise FileNotFoundError(\n        f\"Model directory not found: tried {_VARIANT_DIR.get(variant, variant)!r} \"\n        f\"and {variant!r} under {checkpoint_dir}\"\n    )\n\n\ndef _resolve_dtype(precision: str) -> torch.dtype:\n    \"\"\"Map precision string to torch dtype.\"\"\"\n    mapping = {\n        \"bf16\": torch.bfloat16,\n        \"fp16\": torch.float16,\n        \"fp32\": torch.float32,\n    }\n    return mapping.get(precision, torch.bfloat16)\n\n\ndef read_model_config(checkpoint_dir: str | Path, variant: str) -> Dict[str, Any]:\n    \"\"\"Read and return the model ``config.json`` as a dict.\n\n    Useful for extracting ``timestep_mu``, ``timestep_sigma``,\n    ``data_proportion``, ``is_turbo``, etc. without loading the model.\n    \"\"\"\n    model_dir = _resolve_model_dir(checkpoint_dir, variant)\n    config_path = model_dir / \"config.json\"\n    if not config_path.is_file():\n        raise FileNotFoundError(f\"config.json not found at {config_path}\")\n    return json.loads(config_path.read_text())\n\n\n# ---------------------------------------------------------------------------\n# Decoder loading (for training / estimation)\n# ---------------------------------------------------------------------------\n\ndef load_decoder_for_training(\n    checkpoint_dir: str | Path,\n    variant: str = \"turbo\",\n    device: str = \"cpu\",\n    precision: str = \"bf16\",\n) -> Any:\n    \"\"\"Load the full ``AceStepConditionGenerationModel`` for training.\n\n    The model is loaded in eval mode with gradients disabled on all\n    parameters (the caller -- the trainer -- will selectively enable\n    gradients on LoRA-injected parameters).\n\n    Args:\n        checkpoint_dir: Root checkpoints directory.\n        variant: 'turbo', 'base', or 'sft'.\n        device: Target device string.\n        precision: 'bf16', 'fp16', or 'fp32'.\n\n    Returns:\n        The loaded ``AceStepConditionGenerationModel`` instance.\n    \"\"\"\n    from transformers import AutoModel\n\n    model_dir = _resolve_model_dir(checkpoint_dir, variant)\n    dtype = _resolve_dtype(precision)\n\n    logger.info(\"[INFO] Loading model from %s (variant=%s, dtype=%s)\", model_dir, variant, dtype)\n    print(f\"[INFO] Loading model from {model_dir} (variant={variant}, dtype={dtype})\")\n\n    # Try attention implementations in preference order.\n    # flash_attention_2 first (matches handler.initialize_service), then sdpa, then eager.\n    attn_candidates = []\n    if _is_flash_attention_available(device):\n        attn_candidates.append(\"flash_attention_2\")\n    attn_candidates.extend([\"sdpa\", \"eager\"])\n\n    model = None\n    last_err: Optional[Exception] = None\n\n    for attn_impl in attn_candidates:\n        try:\n            model = AutoModel.from_pretrained(\n                str(model_dir),\n                trust_remote_code=True,\n                attn_implementation=attn_impl,\n                dtype=dtype,\n            )\n            print(f\"[OK] Model loaded with attn_implementation={attn_impl}\")\n            break\n        except Exception as exc:\n            last_err = exc\n            logger.warning(\"[WARN] Failed with attn_implementation=%s: %s\", attn_impl, exc)\n\n    if model is None:\n        raise RuntimeError(\n            f\"Failed to load model from {model_dir}: {last_err}\"\n        ) from last_err\n\n    # Freeze everything by default -- trainer will unfreeze LoRA params\n    for param in model.parameters():\n        param.requires_grad = False\n\n    model = model.to(device=device, dtype=dtype)\n    model.eval()\n\n    logger.info(\"[OK] Model on %s (%s), all params frozen\", device, dtype)\n    return model\n\n\n# ---------------------------------------------------------------------------\n# Preprocessing models (VAE + text encoder + condition encoder)\n# ---------------------------------------------------------------------------\n\ndef load_preprocessing_models(\n    checkpoint_dir: str | Path,\n    variant: str = \"turbo\",\n    device: str = \"cpu\",\n    precision: str = \"bf16\",\n) -> Dict[str, Any]:\n    \"\"\"Load only models needed for the preprocessing phase.\n\n    Returns a dict with keys:\n        - ``model``: the full ``AceStepConditionGenerationModel``\n        - ``vae``: ``AutoencoderOobleck`` (or None)\n        - ``text_tokenizer``: HuggingFace tokenizer\n        - ``text_encoder``: Qwen3 text encoder\n\n    The caller must call :func:`cleanup_preprocessing_models` when done.\n    \"\"\"\n    from transformers import AutoModel, AutoTokenizer\n    from diffusers.models import AutoencoderOobleck\n\n    ckpt = Path(checkpoint_dir)\n    dtype = _resolve_dtype(precision)\n    result: Dict[str, Any] = {}\n\n    # 1. Full model (needed for condition encoder)\n    model = load_decoder_for_training(checkpoint_dir, variant, device, precision)\n    result[\"model\"] = model\n\n    # 2. VAE\n    vae_path = ckpt / \"vae\"\n    if vae_path.is_dir():\n        vae = AutoencoderOobleck.from_pretrained(str(vae_path))\n        vae = vae.to(device=device, dtype=dtype)\n        vae.eval()\n        result[\"vae\"] = vae\n        logger.info(\"[OK] VAE loaded from %s\", vae_path)\n    else:\n        result[\"vae\"] = None\n        logger.warning(\"[WARN] VAE directory not found: %s\", vae_path)\n\n    # 3. Text encoder + tokenizer\n    text_path = ckpt / \"Qwen3-Embedding-0.6B\"\n    if text_path.is_dir():\n        result[\"text_tokenizer\"] = AutoTokenizer.from_pretrained(str(text_path))\n        text_enc = AutoModel.from_pretrained(str(text_path))\n        text_enc = text_enc.to(device=device, dtype=dtype)\n        text_enc.eval()\n        result[\"text_encoder\"] = text_enc\n        logger.info(\"[OK] Text encoder loaded from %s\", text_path)\n    else:\n        result[\"text_tokenizer\"] = None\n        result[\"text_encoder\"] = None\n        logger.warning(\"[WARN] Text encoder directory not found: %s\", text_path)\n\n    return result\n\n\ndef cleanup_preprocessing_models(models: Dict[str, Any]) -> None:\n    \"\"\"Free memory occupied by preprocessing models.\n\n    Moves tensors to CPU, deletes references, and forces garbage collection.\n    \"\"\"\n    for key in list(models.keys()):\n        obj = models.pop(key, None)\n        if obj is not None and hasattr(obj, \"to\"):\n            try:\n                obj.to(\"cpu\")\n            except Exception:\n                pass\n        del obj\n\n    gc.collect()\n    if torch.cuda.is_available():\n        torch.cuda.empty_cache()\n    logger.info(\"[OK] Preprocessing models cleaned up\")\n\n\n# ---------------------------------------------------------------------------\n# Per-component loaders (for sequential / low-VRAM preprocessing)\n# ---------------------------------------------------------------------------\n\ndef load_vae(\n    checkpoint_dir: str | Path,\n    device: str = \"cpu\",\n    precision: str = \"bf16\",\n) -> Any:\n    \"\"\"Load only the VAE (``AutoencoderOobleck``).\n\n    Returns the VAE model in eval mode, or raises ``FileNotFoundError``\n    if the ``vae/`` directory is missing.\n    \"\"\"\n    from diffusers.models import AutoencoderOobleck\n\n    vae_path = Path(checkpoint_dir) / \"vae\"\n    if not vae_path.is_dir():\n        raise FileNotFoundError(f\"VAE directory not found: {vae_path}\")\n\n    dtype = _resolve_dtype(precision)\n    vae = AutoencoderOobleck.from_pretrained(str(vae_path))\n    vae = vae.to(device=device, dtype=dtype)\n    vae.eval()\n    logger.info(\"[OK] VAE loaded from %s (%s)\", vae_path, dtype)\n    return vae\n\n\ndef load_text_encoder(\n    checkpoint_dir: str | Path,\n    device: str = \"cpu\",\n    precision: str = \"bf16\",\n) -> Tuple[Any, Any]:\n    \"\"\"Load the text tokenizer and encoder (Qwen3-Embedding-0.6B).\n\n    Returns:\n        ``(tokenizer, text_encoder)`` -- both ready for inference.\n\n    Raises ``FileNotFoundError`` if the encoder directory is missing.\n    \"\"\"\n    from transformers import AutoModel, AutoTokenizer\n\n    text_path = Path(checkpoint_dir) / \"Qwen3-Embedding-0.6B\"\n    if not text_path.is_dir():\n        raise FileNotFoundError(f\"Text encoder directory not found: {text_path}\")\n\n    dtype = _resolve_dtype(precision)\n    tokenizer = AutoTokenizer.from_pretrained(str(text_path))\n    encoder = AutoModel.from_pretrained(str(text_path))\n    encoder = encoder.to(device=device, dtype=dtype)\n    encoder.eval()\n    logger.info(\"[OK] Text encoder loaded from %s (%s)\", text_path, dtype)\n    return tokenizer, encoder\n\n\ndef load_silence_latent(\n    checkpoint_dir: str | Path,\n    device: str = \"cpu\",\n    precision: str = \"bf16\",\n    variant: str | None = None,\n) -> torch.Tensor:\n    \"\"\"Load ``silence_latent.pt`` from the checkpoint directory.\n\n    The tensor is transposed to match the handler convention\n    ``(1, T, 64)`` and moved to *device* / *dtype*.\n\n    Search order:\n        1. ``checkpoint_dir/silence_latent.pt`` (root -- custom layouts)\n        2. ``checkpoint_dir/<variant_subdir>/silence_latent.pt`` (upstream)\n        3. Scan all known variant subdirectories as a last-resort fallback\n\n    Raises ``FileNotFoundError`` if the file cannot be found anywhere.\n    \"\"\"\n    ckpt = Path(checkpoint_dir)\n    sl_path: Path | None = None\n\n    # 1. Direct root path\n    candidate = ckpt / \"silence_latent.pt\"\n    if candidate.is_file():\n        sl_path = candidate\n\n    # 2. Variant-specific subdirectory\n    if sl_path is None and variant is not None:\n        subdir = _VARIANT_DIR.get(variant, f\"acestep-v15-{variant}\")\n        candidate = ckpt / subdir / \"silence_latent.pt\"\n        if candidate.is_file():\n            sl_path = candidate\n\n    # 3. Last-resort: scan all known variant subdirectories\n    if sl_path is None:\n        for subdir in _VARIANT_DIR.values():\n            candidate = ckpt / subdir / \"silence_latent.pt\"\n            if candidate.is_file():\n                sl_path = candidate\n                break\n\n    if sl_path is None:\n        raise FileNotFoundError(\n            f\"silence_latent.pt not found under {ckpt} \"\n            f\"(checked root and variant subdirectories)\"\n        )\n\n    dtype = _resolve_dtype(precision)\n    sl = torch.load(str(sl_path), weights_only=True).transpose(1, 2)\n    sl = sl.to(device=device, dtype=dtype)\n    logger.info(\"[OK] silence_latent loaded from %s\", sl_path)\n    return sl\n\n\ndef unload_models(*models: Any) -> None:\n    \"\"\"Move models to CPU, delete references, and free GPU memory.\n\n    Accepts any number of model objects (or ``None`` values, which are\n    silently skipped).\n    \"\"\"\n    for obj in models:\n        if obj is None:\n            continue\n        if hasattr(obj, \"to\"):\n            try:\n                obj.to(\"cpu\")\n            except Exception:\n                pass\n        del obj\n\n    gc.collect()\n    if torch.cuda.is_available():\n        torch.cuda.empty_cache()\n    logger.info(\"[OK] Models unloaded and GPU cache cleared\")\n"
  },
  {
    "path": "acestep/training_v2/optim.py",
    "content": "\"\"\"\nSide-Step Optimizer & Scheduler Factories\n\nProvides ``build_optimizer()`` and ``build_scheduler()`` so that\n``trainer_fixed.py`` doesn't need to hard-code AdamW / CosineAnnealing.\n\nSupported optimizers:\n    adamw       -- torch.optim.AdamW (default, fused on CUDA)\n    adamw8bit   -- bitsandbytes.optim.AdamW8bit (optional dep)\n    adafactor   -- transformers.optimization.Adafactor\n    prodigy     -- prodigyopt.Prodigy (optional dep, auto-tunes LR)\n\nSupported schedulers:\n    cosine              -- warmup + CosineAnnealingLR (single smooth decay)\n    cosine_restarts     -- warmup + CosineAnnealingWarmRestarts (cyclical)\n    linear              -- warmup + LinearLR decay to near-zero\n    constant            -- warmup then flat LR\n    constant_with_warmup -- alias for constant\n\"\"\"\n\nfrom __future__ import annotations\n\nimport logging\nfrom typing import Iterable\n\nimport torch\nfrom torch.optim import AdamW\nfrom torch.optim.lr_scheduler import (\n    CosineAnnealingLR,\n    CosineAnnealingWarmRestarts,\n    ConstantLR,\n    LinearLR,\n    SequentialLR,\n)\n\nlogger = logging.getLogger(__name__)\n\n\n# ---------------------------------------------------------------------------\n# Optimizer factory\n# ---------------------------------------------------------------------------\n\ndef build_optimizer(\n    params: Iterable,\n    optimizer_type: str = \"adamw\",\n    lr: float = 1e-4,\n    weight_decay: float = 0.01,\n    device_type: str = \"cuda\",\n) -> torch.optim.Optimizer:\n    \"\"\"Create an optimizer from a string key.\n\n    Falls back to AdamW when an optional dependency is missing.\n    \"\"\"\n    optimizer_type = optimizer_type.lower().strip()\n\n    if optimizer_type == \"adamw8bit\":\n        try:\n            from bitsandbytes.optim import AdamW8bit\n            logger.info(\"[Side-Step] Using AdamW8bit optimizer (lower VRAM)\")\n            return AdamW8bit(params, lr=lr, weight_decay=weight_decay)\n        except ImportError:\n            logger.warning(\n                \"[Side-Step] bitsandbytes not installed -- falling back to AdamW. \"\n                \"Install with: pip install bitsandbytes>=0.45.0\"\n            )\n            optimizer_type = \"adamw\"\n\n    if optimizer_type == \"adafactor\":\n        try:\n            from transformers.optimization import Adafactor\n            logger.info(\"[Side-Step] Using Adafactor optimizer (minimal state memory)\")\n            return Adafactor(\n                params,\n                lr=lr,\n                weight_decay=weight_decay,\n                scale_parameter=False,\n                relative_step=False,\n            )\n        except ImportError:\n            logger.warning(\n                \"[Side-Step] transformers not installed -- falling back to AdamW\"\n            )\n            optimizer_type = \"adamw\"\n\n    if optimizer_type == \"prodigy\":\n        try:\n            from prodigyopt import Prodigy\n            logger.info(\n                \"[Side-Step] Using Prodigy optimizer (adaptive LR -- set LR=1.0 for best results)\"\n            )\n            return Prodigy(\n                params,\n                lr=lr if lr != 1e-4 else 1.0,  # Default to 1.0 for Prodigy\n                weight_decay=weight_decay,\n            )\n        except ImportError:\n            logger.warning(\n                \"[Side-Step] prodigyopt not installed -- falling back to AdamW. \"\n                \"Install with: pip install prodigyopt>=1.1.2\"\n            )\n            optimizer_type = \"adamw\"\n\n    # Default: AdamW\n    kwargs = {\"lr\": lr, \"weight_decay\": weight_decay}\n    if device_type == \"cuda\":\n        kwargs[\"fused\"] = True\n    logger.info(\"[Side-Step] Using AdamW optimizer\")\n    return AdamW(params, **kwargs)\n\n\n# ---------------------------------------------------------------------------\n# Scheduler factory\n# ---------------------------------------------------------------------------\n\ndef build_scheduler(\n    optimizer: torch.optim.Optimizer,\n    scheduler_type: str = \"cosine\",\n    total_steps: int = 1000,\n    warmup_steps: int = 500,\n    lr: float = 1e-4,\n    optimizer_type: str = \"adamw\",\n    n_restarts: int = 4,\n):\n    \"\"\"Create a learning rate scheduler from a string key.\n\n    Args:\n        n_restarts: Number of cosine restart cycles for the\n            ``cosine_restarts`` scheduler.  Ignored by other types.\n\n    When the optimizer is Prodigy, defaults to constant schedule\n    (Prodigy manages LR internally).\n    \"\"\"\n    scheduler_type = scheduler_type.lower().strip()\n\n    # Prodigy handles its own LR -- force constant\n    if optimizer_type == \"prodigy\" and scheduler_type not in (\"constant\", \"constant_with_warmup\"):\n        logger.info(\n            \"[Side-Step] Prodigy optimizer detected -- overriding scheduler to 'constant' \"\n            \"(Prodigy adapts LR internally)\"\n        )\n        scheduler_type = \"constant\"\n\n    # Clamp warmup to avoid exceeding total\n    warmup_steps = min(warmup_steps, max(1, total_steps // 10))\n\n    warmup_sched = LinearLR(\n        optimizer,\n        start_factor=0.1,\n        end_factor=1.0,\n        total_iters=warmup_steps,\n    )\n\n    remaining = max(1, total_steps - warmup_steps)\n\n    if scheduler_type in (\"constant\", \"constant_with_warmup\"):\n        main_sched = ConstantLR(optimizer, factor=1.0, total_iters=total_steps)\n    elif scheduler_type == \"linear\":\n        main_sched = LinearLR(\n            optimizer,\n            start_factor=1.0,\n            end_factor=0.01,\n            total_iters=remaining,\n        )\n    elif scheduler_type == \"cosine_restarts\":\n        # Cyclical cosine: LR resets to peak multiple times during training.\n        # T_0 = cycle length = remaining / n_restarts.\n        main_sched = CosineAnnealingWarmRestarts(\n            optimizer,\n            T_0=max(1, remaining // max(1, n_restarts)),\n            T_mult=1,\n            eta_min=lr * 0.01,\n        )\n    else:\n        # cosine (default) -- single smooth decay to eta_min, no restarts.\n        main_sched = CosineAnnealingLR(\n            optimizer,\n            T_max=remaining,\n            eta_min=lr * 0.01,\n        )\n\n    return SequentialLR(optimizer, [warmup_sched, main_sched], milestones=[warmup_steps])\n"
  },
  {
    "path": "acestep/training_v2/preprocess.py",
    "content": "\"\"\"\nTwo-Pass CLI Preprocessing for ACE-Step Training V2.\n\nConverts raw audio files into ``.pt`` tensor files compatible with\n``PreprocessedDataModule``.  Uses upstream sub-functions directly and\nloads models **sequentially** to minimise peak VRAM:\n\n    Pass 1 (Light ~3 GB):  VAE + Text Encoder  -> intermediate ``.tmp.pt``\n    Pass 2 (Heavy ~6 GB):  DIT encoder          -> final ``.pt``\n\nInput modes:\n    * With ``--dataset-json``: rich per-sample metadata (lyrics, genre, BPM, …)\n    * Without JSON: scan directory, default to ``[Instrumental]``, filename caption\n\"\"\"\n\nfrom __future__ import annotations\n\nimport logging\nfrom pathlib import Path\nfrom typing import Any, Callable, Dict, List, Optional\n\nimport torch\n\n# Split-out helpers\nfrom acestep.training_v2.preprocess_discovery import (\n    discover_audio_files as _discover_audio_files,\n    load_dataset_metadata as _load_dataset_metadata,\n    load_sample_metadata as _load_sample_metadata,\n    select_genre_indices as _select_genre_indices,\n)\nfrom acestep.training_v2.preprocess_prompt import (\n    build_simple_prompt as _build_simple_prompt,\n)\nfrom acestep.training_v2.preprocess_vae import (\n    TARGET_SR as _TARGET_SR,\n    tiled_vae_encode as _tiled_vae_encode,\n)\n\nlogger = logging.getLogger(__name__)\n\n\n# ---------------------------------------------------------------------------\n# Public API\n# ---------------------------------------------------------------------------\n\n\ndef preprocess_audio_files(\n    audio_dir: Optional[str],\n    output_dir: str,\n    checkpoint_dir: str,\n    variant: str = \"turbo\",\n    max_duration: float = 240.0,\n    dataset_json: Optional[str] = None,\n    device: str = \"auto\",\n    precision: str = \"auto\",\n    progress_callback: Optional[Callable] = None,\n    cancel_check: Optional[Callable] = None,\n) -> Dict[str, Any]:\n    \"\"\"Preprocess audio files into .pt tensor format (two-pass pipeline).\n\n    Audio files are discovered from one of two sources:\n\n    * **Dataset JSON** (preferred): each entry's ``audio_path`` or\n      ``filename`` field locates the audio file directly.\n    * **Audio directory** (fallback): scanned **recursively** for\n      supported audio formats when no JSON is provided.\n\n    The resulting tensors are adapter-agnostic: they work for both LoRA\n    and LoKR training (the adapter type only affects weight injection,\n    not the data pipeline).\n\n    Args:\n        audio_dir: Directory containing audio files (scanned recursively).\n            May be ``None`` when *dataset_json* provides audio paths.\n        output_dir: Directory for output .pt files.\n        checkpoint_dir: Path to ACE-Step model checkpoints.\n        variant: Model variant (turbo, base, sft).\n        max_duration: Maximum audio duration in seconds.\n        dataset_json: Optional JSON file with per-sample metadata and\n            audio paths.\n        device: Target device (``\"auto\"`` to auto-detect).\n        precision: Target precision (``\"auto\"`` to auto-detect).\n        progress_callback: ``(current, total, message) -> None``.\n        cancel_check: ``() -> bool`` -- return True to cancel.\n\n    Returns:\n        Dict with keys: ``processed``, ``failed``, ``total``, ``output_dir``.\n    \"\"\"\n    from acestep.training_v2.gpu_utils import detect_gpu\n\n    gpu = detect_gpu(device, precision)\n    dev = gpu.device\n    prec = gpu.precision\n\n    out_path = Path(output_dir)\n    out_path.mkdir(parents=True, exist_ok=True)\n\n    # -- Discover audio files -----------------------------------------------\n    audio_files = _discover_audio_files(audio_dir, dataset_json)\n    if not audio_files:\n        logger.warning(\"[Side-Step] No audio files found\")\n        return {\"processed\": 0, \"failed\": 0, \"total\": 0, \"output_dir\": str(out_path)}\n\n    total = len(audio_files)\n    logger.info(\"[Side-Step] Found %d audio files to preprocess\", total)\n\n    # -- Load metadata -------------------------------------------------------\n    sample_meta = _load_sample_metadata(dataset_json, audio_files)\n    ds_meta = _load_dataset_metadata(dataset_json)\n\n    # Apply dataset-level custom_tag as fallback for samples without one\n    ds_tag = ds_meta.get(\"custom_tag\", \"\")\n    if ds_tag:\n        for sm in sample_meta.values():\n            if not sm.get(\"custom_tag\"):\n                sm[\"custom_tag\"] = ds_tag\n\n    # -- Pass 1: VAE + Text Encoder -----------------------------------------\n    intermediates, pass1_failed = _pass1_light(\n        audio_files=audio_files,\n        sample_meta=sample_meta,\n        ds_meta=ds_meta,\n        out_path=out_path,\n        checkpoint_dir=checkpoint_dir,\n        variant=variant,\n        device=dev,\n        precision=prec,\n        max_duration=max_duration,\n        progress_callback=progress_callback,\n        cancel_check=cancel_check,\n    )\n\n    # -- Pass 2: DIT Encoder ------------------------------------------------\n    processed, pass2_failed = _pass2_heavy(\n        intermediates=intermediates,\n        out_path=out_path,\n        checkpoint_dir=checkpoint_dir,\n        variant=variant,\n        device=dev,\n        precision=prec,\n        progress_callback=progress_callback,\n        cancel_check=cancel_check,\n    )\n\n    failed = pass1_failed + pass2_failed\n    result = {\n        \"processed\": processed,\n        \"failed\": failed,\n        \"total\": total,\n        \"output_dir\": str(out_path),\n    }\n    logger.info(\n        \"[Side-Step] Preprocessing complete: %d/%d processed, %d failed\",\n        processed,\n        total,\n        failed,\n    )\n    return result\n\n\n# ---------------------------------------------------------------------------\n# Pass 1 -- Light models (VAE + Text Encoder)\n# ---------------------------------------------------------------------------\n\n\ndef _pass1_light(\n    audio_files: List[Path],\n    sample_meta: Dict[str, Dict[str, Any]],\n    ds_meta: Dict[str, Any],\n    out_path: Path,\n    checkpoint_dir: str,\n    variant: str,\n    device: str,\n    precision: str,\n    max_duration: float,\n    progress_callback: Optional[Callable],\n    cancel_check: Optional[Callable],\n) -> tuple[List[Path], int]:\n    \"\"\"Load audio, VAE-encode, text-encode, save intermediates.\n\n    Args:\n        ds_meta: Dataset-level metadata (``tag_position``, ``genre_ratio``,\n            ``custom_tag``) from the JSON's top-level ``metadata`` block.\n\n    Returns ``(list_of_intermediate_paths, fail_count)``.\n    \"\"\"\n    from acestep.training_v2.model_loader import (\n        load_vae,\n        load_text_encoder,\n        load_silence_latent,\n        unload_models,\n        _resolve_dtype,\n    )\n    from acestep.training.dataset_builder_modules.preprocess_audio import (\n        load_audio_stereo,\n    )\n    from acestep.training.dataset_builder_modules.preprocess_text import encode_text\n    from acestep.training.dataset_builder_modules.preprocess_lyrics import encode_lyrics\n\n    dtype = _resolve_dtype(precision)\n\n    logger.info(\"[Side-Step] Pass 1/2: Loading VAE + Text Encoder ...\")\n    vae = load_vae(checkpoint_dir, device, precision)\n    tokenizer, text_enc = load_text_encoder(checkpoint_dir, device, precision)\n    silence_latent = load_silence_latent(\n        checkpoint_dir, device, precision, variant=variant\n    )\n\n    intermediates: List[Path] = []\n    failed = 0\n    total = len(audio_files)\n\n    # Dataset-level prompt settings from ACE-Step's metadata block\n    tag_position = ds_meta.get(\"tag_position\", \"prepend\")\n    genre_ratio = ds_meta.get(\"genre_ratio\", 0)\n    genre_indices = _select_genre_indices(total, genre_ratio)\n    if genre_indices:\n        logger.info(\n            \"[Side-Step] genre_ratio=%d%% -- %d/%d samples will use genre as prompt\",\n            genre_ratio,\n            len(genre_indices),\n            total,\n        )\n    if tag_position != \"prepend\":\n        logger.info(\"[Side-Step] tag_position=%s (from dataset metadata)\", tag_position)\n\n    try:\n        for i, af in enumerate(audio_files):\n            if cancel_check and cancel_check():\n                logger.info(\"[Side-Step] Cancelled at %d/%d\", i, total)\n                break\n\n            if progress_callback:\n                progress_callback(i, total, f\"[Pass 1] {af.name}\")\n\n            # Skip if final .pt already exists (resumable)\n            final_pt = out_path / f\"{af.stem}.pt\"\n            if final_pt.exists():\n                logger.info(\"[Side-Step] Skipping (final exists): %s\", af.name)\n                continue\n\n            try:\n                # 1. Load audio (stereo, 48 kHz)\n                audio, _sr = load_audio_stereo(str(af), _TARGET_SR, max_duration)\n                audio = audio.unsqueeze(0).to(device=device, dtype=vae.dtype)\n\n                # 2. VAE encode (tiled for long audio)\n                with torch.no_grad():\n                    target_latents = _tiled_vae_encode(vae, audio, dtype)\n\n                # Free raw audio immediately -- no longer needed after VAE encode\n                del audio\n\n                latent_length = target_latents.shape[1]\n                attention_mask = torch.ones(\n                    1, latent_length, device=device, dtype=dtype\n                )\n\n                # 3. Text encode\n                sm = sample_meta.get(af.name, {})\n                caption = sm.get(\"caption\", af.stem)\n                lyrics = sm.get(\"lyrics\", \"[Instrumental]\")\n\n                # Build text prompt using dataset-level tag_position and genre_ratio\n                use_genre = i in genre_indices\n                text_prompt = _build_simple_prompt(\n                    sm, tag_position=tag_position, use_genre=use_genre\n                )\n\n                with torch.no_grad():\n                    text_hs, text_mask = encode_text(\n                        text_enc, tokenizer, text_prompt, device, dtype\n                    )\n                    lyric_hs, lyric_mask = encode_lyrics(\n                        text_enc, tokenizer, lyrics, device, dtype\n                    )\n\n                # 4. Save intermediate\n                tmp_path = out_path / f\"{af.stem}.tmp.pt\"\n                torch.save(\n                    {\n                        \"target_latents\": target_latents.squeeze(0).cpu(),\n                        \"attention_mask\": attention_mask.squeeze(0).cpu(),\n                        \"text_hidden_states\": text_hs.cpu(),\n                        \"text_attention_mask\": text_mask.cpu(),\n                        \"lyric_hidden_states\": lyric_hs.cpu(),\n                        \"lyric_attention_mask\": lyric_mask.cpu(),\n                        \"silence_latent\": silence_latent.cpu(),\n                        \"latent_length\": latent_length,\n                        \"metadata\": {\n                            \"audio_path\": str(af),\n                            \"filename\": af.name,\n                            \"caption\": caption,\n                            \"lyrics\": lyrics,\n                            \"duration\": sm.get(\"duration\", 0),\n                            \"bpm\": sm.get(\"bpm\"),\n                            \"keyscale\": sm.get(\"keyscale\", \"\"),\n                            \"timesignature\": sm.get(\"timesignature\", \"\"),\n                            \"genre\": sm.get(\"genre\", \"\"),\n                            \"is_instrumental\": sm.get(\"is_instrumental\", True),\n                            \"custom_tag\": sm.get(\"custom_tag\", \"\"),\n                            \"prompt_override\": sm.get(\"prompt_override\"),\n                        },\n                    },\n                    tmp_path,\n                )\n\n                # Free GPU tensors from this iteration before the next one\n                del target_latents, attention_mask, text_hs, text_mask\n                del lyric_hs, lyric_mask\n                if torch.cuda.is_available():\n                    torch.cuda.empty_cache()\n\n                intermediates.append(tmp_path)\n                logger.info(\"[Side-Step] Pass 1 OK: %s\", af.name)\n\n            except Exception as exc:\n                failed += 1\n                logger.error(\"[Side-Step] Pass 1 FAIL %s: %s\", af.name, exc)\n\n    finally:\n        logger.info(\"[Side-Step] Unloading VAE + Text Encoder ...\")\n        unload_models(vae, text_enc, tokenizer, silence_latent)\n\n    if progress_callback:\n        progress_callback(total, total, \"[Pass 1] Done\")\n\n    return intermediates, failed\n\n\n# ---------------------------------------------------------------------------\n# Pass 2 -- Heavy model (DIT encoder)\n# ---------------------------------------------------------------------------\n\n\ndef _pass2_heavy(\n    intermediates: List[Path],\n    out_path: Path,\n    checkpoint_dir: str,\n    variant: str,\n    device: str,\n    precision: str,\n    progress_callback: Optional[Callable],\n    cancel_check: Optional[Callable],\n) -> tuple[int, int]:\n    \"\"\"Run DIT encoder on intermediates and write final .pt files.\n\n    Returns ``(processed_count, fail_count)``.\n    \"\"\"\n    if not intermediates:\n        return 0, 0\n\n    from acestep.training_v2.model_loader import (\n        load_decoder_for_training,\n        unload_models,\n        _resolve_dtype,\n    )\n    from acestep.training.dataset_builder_modules.preprocess_encoder import run_encoder\n    from acestep.training.dataset_builder_modules.preprocess_context import (\n        build_context_latents,\n    )\n\n    dtype = _resolve_dtype(precision)\n\n    logger.info(\"[Side-Step] Pass 2/2: Loading DIT model (variant=%s) ...\", variant)\n    model = load_decoder_for_training(checkpoint_dir, variant, device, precision)\n\n    processed = 0\n    failed = 0\n    total = len(intermediates)\n\n    try:\n        for i, tmp_path in enumerate(intermediates):\n            if cancel_check and cancel_check():\n                logger.info(\"[Side-Step] Cancelled at %d/%d\", i, total)\n                break\n\n            if progress_callback:\n                progress_callback(i, total, f\"[Pass 2] {tmp_path.stem}\")\n\n            try:\n                data = torch.load(str(tmp_path), weights_only=True)\n\n                # Move tensors directly to model device/dtype (single .to()\n                # avoids creating throwaway intermediate GPU copies).\n                model_device = next(model.parameters()).device\n                model_dtype = next(model.parameters()).dtype\n\n                text_hs = data[\"text_hidden_states\"].to(model_device, dtype=model_dtype)\n                text_mask = data[\"text_attention_mask\"].to(\n                    model_device, dtype=model_dtype\n                )\n                lyric_hs = data[\"lyric_hidden_states\"].to(\n                    model_device, dtype=model_dtype\n                )\n                lyric_mask = data[\"lyric_attention_mask\"].to(\n                    model_device, dtype=model_dtype\n                )\n                silence_latent = data[\"silence_latent\"].to(\n                    model_device, dtype=model_dtype\n                )\n                latent_length = data[\"latent_length\"]\n\n                # DIT encoder pass (adapter-agnostic: same tensors for\n                # LoRA and LoKR -- only the adapter injection differs).\n                encoder_hs, encoder_mask = run_encoder(\n                    model,\n                    text_hidden_states=text_hs,\n                    text_attention_mask=text_mask,\n                    lyric_hidden_states=lyric_hs,\n                    lyric_attention_mask=lyric_mask,\n                    device=str(model_device),\n                    dtype=model_dtype,\n                )\n\n                # Free encoder inputs immediately after use\n                del text_hs, text_mask, lyric_hs, lyric_mask\n\n                # Build context latents (silence-based, standard text2music)\n                if silence_latent.dim() == 2:\n                    silence_latent = silence_latent.unsqueeze(0)\n\n                context_latents = build_context_latents(\n                    silence_latent,\n                    latent_length,\n                    str(model_device),\n                    model_dtype,\n                )\n                del silence_latent\n\n                # Write final .pt  (strip \".tmp\" from \"song.tmp.pt\" -> \"song.pt\")\n                base_name = tmp_path.name.replace(\".tmp.pt\", \".pt\")\n                final_path = out_path / base_name\n                meta = data[\"metadata\"]\n                torch.save(\n                    {\n                        \"target_latents\": data[\"target_latents\"],\n                        \"attention_mask\": data[\"attention_mask\"],\n                        \"encoder_hidden_states\": encoder_hs.squeeze(0).cpu(),\n                        \"encoder_attention_mask\": encoder_mask.squeeze(0).cpu(),\n                        \"context_latents\": context_latents.squeeze(0).cpu(),\n                        \"metadata\": meta,\n                    },\n                    final_path,\n                )\n\n                # Free all GPU tensors and the loaded data dict before next iter\n                del encoder_hs, encoder_mask, context_latents, data\n                if torch.cuda.is_available():\n                    torch.cuda.empty_cache()\n\n                # Remove intermediate\n                tmp_path.unlink(missing_ok=True)\n\n                processed += 1\n                logger.info(\"[Side-Step] Pass 2 OK: %s\", tmp_path.stem)\n\n            except Exception as exc:\n                failed += 1\n                logger.error(\"[Side-Step] Pass 2 FAIL %s: %s\", tmp_path.stem, exc)\n\n    finally:\n        logger.info(\"[Side-Step] Unloading DIT model ...\")\n        unload_models(model)\n\n    if progress_callback:\n        progress_callback(total, total, \"[Pass 2] Done\")\n\n    return processed, failed\n"
  },
  {
    "path": "acestep/training_v2/preprocess_discovery.py",
    "content": "\"\"\"\nAudio file discovery and metadata loading for preprocessing.\n\nReads both per-sample metadata and dataset-level metadata (``tag_position``,\n``genre_ratio``, default ``custom_tag``) from ACE-Step's JSON format.\n\nExtracted from ``preprocess.py`` to keep that module under the LOC limit.\n\"\"\"\n\nfrom __future__ import annotations\n\nimport json\nimport logging\nimport random\nfrom pathlib import Path\nfrom typing import Any, Dict, List, Optional, Set\n\nlogger = logging.getLogger(__name__)\n\n# Supported audio extensions (same as upstream)\nAUDIO_EXTENSIONS = {\".wav\", \".mp3\", \".flac\", \".ogg\", \".opus\", \".m4a\"}\n\n\ndef discover_audio_files(\n    audio_dir: Optional[str],\n    dataset_json: Optional[str],\n) -> List[Path]:\n    \"\"\"Discover audio files from a dataset JSON or by scanning a directory.\n\n    Resolution order:\n\n    1. If *dataset_json* is provided, extract ``audio_path`` (or fall back\n       to ``filename``) from each entry.  Missing files are skipped with a\n       warning.\n    2. Otherwise, recursively scan *audio_dir* for supported audio\n       extensions (``AUDIO_EXTENSIONS``).\n    \"\"\"\n    # -- JSON-driven discovery ----------------------------------------------\n    if dataset_json and Path(dataset_json).is_file():\n        try:\n            raw = json.loads(Path(dataset_json).read_text(encoding=\"utf-8\"))\n            samples = raw if isinstance(raw, list) else raw.get(\"samples\", [])\n        except (json.JSONDecodeError, OSError) as exc:\n            logger.warning(\"[Side-Step] Failed to read dataset JSON: %s\", exc)\n            samples = []\n\n        audio_files: List[Path] = []\n        json_dir = Path(dataset_json).parent  # resolve relative paths vs JSON\n        for entry in samples:\n            ap = entry.get(\"audio_path\") or entry.get(\"filename\", \"\")\n            if not ap:\n                continue\n            p = Path(ap)\n            if not p.is_absolute():\n                p = json_dir / p\n            if p.is_file():\n                audio_files.append(p)\n            else:\n                logger.warning(\"[Side-Step] Audio file from JSON not found: %s\", p)\n\n        if audio_files:\n            logger.info(\n                \"[Side-Step] Resolved %d audio files from dataset JSON\", len(audio_files),\n            )\n            return sorted(audio_files)\n        else:\n            logger.warning(\n                \"[Side-Step] Dataset JSON contained no resolvable audio paths; \"\n                \"falling back to directory scan\"\n            )\n\n    # -- Recursive directory scan -------------------------------------------\n    if not audio_dir:\n        return []\n\n    source_path = Path(audio_dir)\n    if not source_path.is_dir():\n        logger.warning(\"[Side-Step] Audio directory does not exist: %s\", audio_dir)\n        return []\n\n    audio_files = sorted(\n        f for f in source_path.rglob(\"*\")\n        if f.is_file() and f.suffix.lower() in AUDIO_EXTENSIONS\n    )\n    if audio_files:\n        logger.info(\n            \"[Side-Step] Found %d audio files (recursive scan of %s)\",\n            len(audio_files), audio_dir,\n        )\n    return audio_files\n\n\ndef load_sample_metadata(\n    dataset_json: Optional[str],\n    audio_files: List[Path],\n) -> Dict[str, Dict[str, Any]]:\n    \"\"\"Build a filename -> metadata mapping.\n\n    If *dataset_json* is provided, load it and index by filename.\n    Falls back to basename of ``audio_path`` when ``filename`` is missing.\n    Otherwise return defaults for every audio file.\n    \"\"\"\n    meta: Dict[str, Dict[str, Any]] = {}\n\n    if dataset_json and Path(dataset_json).is_file():\n        try:\n            raw = json.loads(Path(dataset_json).read_text(encoding=\"utf-8\"))\n            samples = raw if isinstance(raw, list) else raw.get(\"samples\", [])\n            for s in samples:\n                # Primary key: explicit filename field\n                fname = s.get(\"filename\", \"\")\n                if fname:\n                    meta[fname] = s\n                    # Also index by basename if filename contains a path\n                    basename = Path(fname).name\n                    if basename != fname and basename not in meta:\n                        meta[basename] = s\n                elif s.get(\"audio_path\"):\n                    # Fallback: derive key from audio_path basename\n                    basename = Path(s[\"audio_path\"]).name\n                    if basename and basename not in meta:\n                        meta[basename] = s\n            logger.info(\"[Side-Step] Loaded metadata for %d samples from %s\", len(meta), dataset_json)\n        except (json.JSONDecodeError, OSError) as exc:\n            logger.warning(\"[Side-Step] Failed to load dataset JSON: %s\", exc)\n\n    # Fill defaults for any audio file without metadata\n    for af in audio_files:\n        if af.name not in meta:\n            meta[af.name] = {\n                \"filename\": af.name,\n                \"caption\": af.stem.replace(\"_\", \" \").replace(\"-\", \" \"),\n                \"lyrics\": \"[Instrumental]\",\n                \"genre\": \"\",\n                \"bpm\": None,\n                \"keyscale\": \"\",\n                \"timesignature\": \"\",\n                \"duration\": 0,\n                \"is_instrumental\": True,\n            }\n\n    return meta\n\n\ndef load_dataset_metadata(dataset_json: Optional[str]) -> Dict[str, Any]:\n    \"\"\"Load the top-level ``metadata`` block from an ACE-Step dataset JSON.\n\n    Returns a dict with the dataset-level settings that affect prompt\n    construction:\n\n    - ``tag_position`` (str): ``\"prepend\"``, ``\"append\"``, or ``\"replace\"``.\n    - ``genre_ratio`` (int): 0-100, percentage of samples using genre.\n    - ``custom_tag`` (str): default trigger word applied to all samples.\n\n    Returns safe defaults when the JSON has no metadata block or is absent.\n    \"\"\"\n    defaults: Dict[str, Any] = {\n        \"tag_position\": \"prepend\",\n        \"genre_ratio\": 0,\n        \"custom_tag\": \"\",\n    }\n    if not dataset_json or not Path(dataset_json).is_file():\n        return defaults\n\n    try:\n        raw = json.loads(Path(dataset_json).read_text(encoding=\"utf-8\"))\n    except (json.JSONDecodeError, OSError):\n        return defaults\n\n    if not isinstance(raw, dict) or \"metadata\" not in raw:\n        return defaults\n\n    meta = raw[\"metadata\"]\n    return {\n        \"tag_position\": meta.get(\"tag_position\", \"prepend\"),\n        \"genre_ratio\": meta.get(\"genre_ratio\", 0),\n        \"custom_tag\": meta.get(\"custom_tag\", \"\"),\n    }\n\n\ndef select_genre_indices(num_samples: int, genre_ratio: int) -> Set[int]:\n    \"\"\"Select sample indices that should use genre instead of caption.\n\n    Mirrors upstream ``select_genre_indices()`` from ACE-Step's\n    ``preprocess_utils.py``.  Uses a fixed seed so the selection is\n    deterministic and reproducible across runs.\n\n    Args:\n        num_samples: Total number of samples.\n        genre_ratio: 0-100, percentage of samples that use genre.\n\n    Returns:\n        Set of sample indices that should use genre.\n    \"\"\"\n    if genre_ratio <= 0 or num_samples <= 0:\n        return set()\n    num_genre = int(num_samples * genre_ratio / 100)\n    rng = random.Random(42)\n    indices = list(range(num_samples))\n    rng.shuffle(indices)\n    return set(indices[:num_genre])\n"
  },
  {
    "path": "acestep/training_v2/preprocess_prompt.py",
    "content": "\"\"\"\nPrompt builder for ACE-Step preprocessing.\n\nBuilds the ``SFT_GEN_PROMPT``-formatted text prompt from per-sample\nmetadata, supporting caption, genre, custom trigger tags, and\noptional per-sample ``prompt_override``.\n\nExtracted from ``preprocess.py`` to keep that module under the LOC limit.\n\"\"\"\n\nfrom __future__ import annotations\n\nfrom typing import Any, Dict\n\n\ndef build_simple_prompt(\n    meta: Dict[str, Any],\n    tag_position: str = \"prepend\",\n    use_genre: bool = False,\n) -> str:\n    \"\"\"Build a text prompt from sample metadata.\n\n    Mimics the upstream ``build_text_prompt`` + ``build_metas_str`` +\n    ``AudioSample.get_training_prompt`` without requiring the\n    ``AudioSample`` dataclass or ``DatasetBuilder``.\n\n    Supports the same JSON fields as upstream:\n    - ``caption``, ``genre``: primary text descriptions.\n    - ``custom_tag``: trigger word prepended/appended/replaced.\n    - ``prompt_override``: per-sample ``\"caption\"`` or ``\"genre\"`` override.\n\n    Args:\n        meta: Per-sample metadata dict from the dataset JSON.\n        tag_position: Where to apply ``custom_tag`` (``\"prepend\"``,\n            ``\"append\"``, or ``\"replace\"``).\n        use_genre: If ``True`` and no ``prompt_override``, use the\n            ``genre`` field instead of ``caption``.\n    \"\"\"\n    from acestep.constants import DEFAULT_DIT_INSTRUCTION, SFT_GEN_PROMPT\n\n    caption = meta.get(\"caption\", \"\")\n    genre = meta.get(\"genre\", \"\")\n    override = meta.get(\"prompt_override\")\n    tag = meta.get(\"custom_tag\", \"\")\n\n    # Decide caption vs genre (mirrors AudioSample.get_training_prompt)\n    if override == \"genre\":\n        text = genre\n    elif override == \"caption\" or not use_genre:\n        text = caption\n    else:\n        text = genre or caption\n\n    # Apply custom_tag (mirrors AudioSample.get_full_caption / get_full_genre)\n    if tag:\n        if tag_position == \"prepend\":\n            text = f\"{tag}, {text}\" if text else tag\n        elif tag_position == \"append\":\n            text = f\"{text}, {tag}\" if text else tag\n        elif tag_position == \"replace\":\n            text = tag\n\n    bpm = meta.get(\"bpm\", \"N/A\") or \"N/A\"\n    ts = meta.get(\"timesignature\", \"N/A\") or \"N/A\"\n    ks = meta.get(\"keyscale\", \"N/A\") or \"N/A\"\n    dur = meta.get(\"duration\", 0)\n\n    metas_str = (\n        f\"- bpm: {bpm}\\n\"\n        f\"- timesignature: {ts}\\n\"\n        f\"- keyscale: {ks}\\n\"\n        f\"- duration: {dur} seconds\\n\"\n    )\n    return SFT_GEN_PROMPT.format(DEFAULT_DIT_INSTRUCTION, text, metas_str)\n"
  },
  {
    "path": "acestep/training_v2/preprocess_vae.py",
    "content": "\"\"\"\nTiled VAE encoding for long audio during preprocessing.\n\nProcesses audio in overlapping chunks to avoid OOM on large inputs,\nthen reassembles the latent representation with overlap-discard.\n\nExtracted from ``preprocess.py`` to keep that module under the LOC limit.\n\"\"\"\n\nfrom __future__ import annotations\n\nimport math\nfrom typing import Any, Optional\n\nimport torch\n\n# Target sample rate for ACE-Step models\nTARGET_SR = 48000\n\n\ndef tiled_vae_encode(\n    vae: Any,\n    audio: torch.Tensor,\n    dtype: torch.dtype,\n    chunk_size: Optional[int] = None,\n    overlap: int = 96000,\n) -> torch.Tensor:\n    \"\"\"Encode audio through the VAE using overlap-discard tiling.\n\n    Processes long audio in chunks to avoid OOM on the monolithic\n    ``vae.encode()`` call.  Mirrors the tiling strategy from\n    ``handler.tiled_encode`` but as a standalone function with no\n    ``self`` / handler dependency.\n\n    Args:\n        vae: The ``AutoencoderOobleck`` VAE model (on device, in eval mode).\n        audio: Audio tensor ``[B, C, S]`` (batch, channels, samples).\n        dtype: Target dtype for the output latents.\n        chunk_size: Audio samples per chunk.  ``None`` = auto-select\n            based on available GPU memory (30 s for >=8 GB, 15 s otherwise).\n        overlap: Overlap in audio samples between adjacent chunks\n            (default 2 s at 48 kHz = 96 000).\n\n    Returns:\n        Latent tensor ``[B, T, 64]`` (same format as upstream\n        ``vae_encode``), cast to *dtype*.\n    \"\"\"\n    vae_device = next(vae.parameters()).device\n    vae_dtype = vae.dtype\n\n    # Auto-select chunk size based on GPU VRAM\n    if chunk_size is None:\n        gpu_mem_gb = 0.0\n        if torch.cuda.is_available():\n            try:\n                props = torch.cuda.get_device_properties(vae_device)\n                gpu_mem_gb = props.total_mem / (1024 ** 3)\n            except Exception:\n                pass\n        chunk_size = TARGET_SR * 15 if gpu_mem_gb <= 8 else TARGET_SR * 30\n\n    B, C, S = audio.shape\n\n    # Short audio -- direct encode (no tiling needed)\n    if S <= chunk_size:\n        vae_input = audio.to(vae_device, dtype=vae_dtype)\n        with torch.inference_mode():\n            latents = vae.encode(vae_input).latent_dist.sample()\n        return latents.transpose(1, 2).to(dtype)\n\n    # Calculate stride (core region per chunk, excluding overlap)\n    stride = chunk_size - 2 * overlap\n    if stride <= 0:\n        raise ValueError(\n            f\"chunk_size ({chunk_size}) must be > 2 * overlap ({overlap})\"\n        )\n\n    num_steps = math.ceil(S / stride)\n    downsample_factor: Optional[float] = None\n    latent_write_pos = 0\n    final_latents: Optional[torch.Tensor] = None\n\n    for i in range(num_steps):\n        core_start = i * stride\n        core_end = min(core_start + stride, S)\n\n        # Window with overlap on both sides\n        win_start = max(0, core_start - overlap)\n        win_end = min(S, core_end + overlap)\n\n        chunk = audio[:, :, win_start:win_end].to(vae_device, dtype=vae_dtype)\n\n        with torch.inference_mode():\n            latent_chunk = vae.encode(chunk).latent_dist.sample()\n\n        # Determine downsample factor from the first chunk\n        if downsample_factor is None:\n            downsample_factor = chunk.shape[-1] / latent_chunk.shape[-1]\n            total_latent_len = int(round(S / downsample_factor))\n            final_latents = torch.zeros(\n                B, latent_chunk.shape[1], total_latent_len,\n                dtype=latent_chunk.dtype, device=\"cpu\",\n            )\n\n        # Trim the overlap regions from the latent\n        added_start = core_start - win_start\n        trim_start = int(round(added_start / downsample_factor))\n\n        added_end = win_end - core_end\n        trim_end = int(round(added_end / downsample_factor))\n\n        lat_len = latent_chunk.shape[-1]\n        end_idx = lat_len - trim_end if trim_end > 0 else lat_len\n        latent_core = latent_chunk[:, :, trim_start:end_idx]\n\n        # Copy to pre-allocated CPU tensor\n        core_len = latent_core.shape[-1]\n        assert final_latents is not None\n        final_latents[:, :, latent_write_pos:latent_write_pos + core_len] = latent_core.cpu()\n        latent_write_pos += core_len\n\n        del chunk, latent_chunk, latent_core\n\n    # Trim to actual written length\n    assert final_latents is not None\n    final_latents = final_latents[:, :, :latent_write_pos]\n\n    # Transpose to (B, T, 64) and cast -- matches vae_encode output format\n    return final_latents.transpose(1, 2).to(dtype)\n"
  },
  {
    "path": "acestep/training_v2/presets/high_quality.json",
    "content": "{\n  \"name\": \"high_quality\",\n  \"description\": \"High capacity, long training -- rank 128, 1000 epochs\",\n  \"rank\": 128,\n  \"alpha\": 256,\n  \"dropout\": 0.1,\n  \"target_modules_str\": \"q_proj k_proj v_proj o_proj\",\n  \"attention_type\": \"both\",\n  \"bias\": \"none\",\n  \"learning_rate\": 1e-4,\n  \"batch_size\": 1,\n  \"gradient_accumulation\": 4,\n  \"epochs\": 1000,\n  \"warmup_steps\": 100,\n  \"weight_decay\": 0.01,\n  \"max_grad_norm\": 1.0,\n  \"seed\": 42,\n  \"shift\": 3.0,\n  \"num_inference_steps\": 8,\n  \"optimizer_type\": \"adamw\",\n  \"scheduler_type\": \"cosine\",\n  \"cfg_ratio\": 0.15,\n  \"save_every\": 250,\n  \"log_every\": 10,\n  \"log_heavy_every\": 50,\n  \"gradient_checkpointing\": true,\n  \"offload_encoder\": false,\n  \"sample_every_n_epochs\": 0\n}\n"
  },
  {
    "path": "acestep/training_v2/presets/quick_test.json",
    "content": "{\n  \"name\": \"quick_test\",\n  \"description\": \"Low rank, few epochs -- fast iteration for testing\",\n  \"rank\": 16,\n  \"alpha\": 32,\n  \"dropout\": 0.1,\n  \"target_modules_str\": \"q_proj k_proj v_proj o_proj\",\n  \"attention_type\": \"both\",\n  \"bias\": \"none\",\n  \"learning_rate\": 1e-4,\n  \"batch_size\": 1,\n  \"gradient_accumulation\": 4,\n  \"epochs\": 10,\n  \"warmup_steps\": 10,\n  \"weight_decay\": 0.01,\n  \"max_grad_norm\": 1.0,\n  \"seed\": 42,\n  \"shift\": 3.0,\n  \"num_inference_steps\": 8,\n  \"optimizer_type\": \"adamw\",\n  \"scheduler_type\": \"cosine\",\n  \"cfg_ratio\": 0.15,\n  \"save_every\": 5,\n  \"log_every\": 5,\n  \"log_heavy_every\": 50,\n  \"gradient_checkpointing\": true,\n  \"offload_encoder\": false,\n  \"sample_every_n_epochs\": 0\n}\n"
  },
  {
    "path": "acestep/training_v2/presets/recommended.json",
    "content": "{\n  \"name\": \"recommended\",\n  \"description\": \"Balanced defaults for most LoRA fine-tuning tasks\",\n  \"rank\": 64,\n  \"alpha\": 128,\n  \"dropout\": 0.1,\n  \"target_modules_str\": \"q_proj k_proj v_proj o_proj\",\n  \"attention_type\": \"both\",\n  \"bias\": \"none\",\n  \"learning_rate\": 1e-4,\n  \"batch_size\": 1,\n  \"gradient_accumulation\": 4,\n  \"epochs\": 100,\n  \"warmup_steps\": 100,\n  \"weight_decay\": 0.01,\n  \"max_grad_norm\": 1.0,\n  \"seed\": 42,\n  \"shift\": 3.0,\n  \"num_inference_steps\": 8,\n  \"optimizer_type\": \"adamw\",\n  \"scheduler_type\": \"cosine\",\n  \"cfg_ratio\": 0.15,\n  \"save_every\": 10,\n  \"log_every\": 10,\n  \"log_heavy_every\": 50,\n  \"gradient_checkpointing\": true,\n  \"offload_encoder\": false,\n  \"sample_every_n_epochs\": 0\n}\n"
  },
  {
    "path": "acestep/training_v2/presets/vram_12gb.json",
    "content": "{\n  \"name\": \"vram_12gb\",\n  \"description\": \"Tight (10-16 GB) -- RTX 3060 12GB, 4070, 4060 Ti. 8-bit optimizer + encoder offloading.\",\n  \"rank\": 32,\n  \"alpha\": 64,\n  \"dropout\": 0.1,\n  \"target_modules_str\": \"q_proj k_proj v_proj o_proj\",\n  \"attention_type\": \"both\",\n  \"bias\": \"none\",\n  \"learning_rate\": 1e-4,\n  \"batch_size\": 1,\n  \"gradient_accumulation\": 4,\n  \"epochs\": 100,\n  \"warmup_steps\": 100,\n  \"weight_decay\": 0.01,\n  \"max_grad_norm\": 1.0,\n  \"seed\": 42,\n  \"shift\": 3.0,\n  \"num_inference_steps\": 8,\n  \"optimizer_type\": \"adamw8bit\",\n  \"scheduler_type\": \"cosine\",\n  \"cfg_ratio\": 0.15,\n  \"save_every\": 10,\n  \"log_every\": 10,\n  \"log_heavy_every\": 50,\n  \"gradient_checkpointing\": true,\n  \"offload_encoder\": true,\n  \"sample_every_n_epochs\": 0\n}\n"
  },
  {
    "path": "acestep/training_v2/presets/vram_16gb.json",
    "content": "{\n  \"name\": \"vram_16gb\",\n  \"description\": \"Standard (16-24 GB) -- RTX 4080, 3080 Ti, A5000. Balanced rank and batch size.\",\n  \"rank\": 64,\n  \"alpha\": 128,\n  \"dropout\": 0.1,\n  \"target_modules_str\": \"q_proj k_proj v_proj o_proj\",\n  \"attention_type\": \"both\",\n  \"bias\": \"none\",\n  \"learning_rate\": 1e-4,\n  \"batch_size\": 1,\n  \"gradient_accumulation\": 4,\n  \"epochs\": 100,\n  \"warmup_steps\": 100,\n  \"weight_decay\": 0.01,\n  \"max_grad_norm\": 1.0,\n  \"seed\": 42,\n  \"shift\": 3.0,\n  \"num_inference_steps\": 8,\n  \"optimizer_type\": \"adamw\",\n  \"scheduler_type\": \"cosine\",\n  \"cfg_ratio\": 0.15,\n  \"save_every\": 10,\n  \"log_every\": 10,\n  \"log_heavy_every\": 50,\n  \"gradient_checkpointing\": true,\n  \"offload_encoder\": false,\n  \"sample_every_n_epochs\": 0\n}\n"
  },
  {
    "path": "acestep/training_v2/presets/vram_24gb_plus.json",
    "content": "{\n  \"name\": \"vram_24gb_plus\",\n  \"description\": \"Comfortable (24 GB+) -- RTX 3090, 4090, A100, H100. High rank, batch 2, full speed.\",\n  \"rank\": 128,\n  \"alpha\": 256,\n  \"dropout\": 0.1,\n  \"target_modules_str\": \"q_proj k_proj v_proj o_proj\",\n  \"attention_type\": \"both\",\n  \"bias\": \"none\",\n  \"learning_rate\": 1e-4,\n  \"batch_size\": 2,\n  \"gradient_accumulation\": 2,\n  \"epochs\": 100,\n  \"warmup_steps\": 100,\n  \"weight_decay\": 0.01,\n  \"max_grad_norm\": 1.0,\n  \"seed\": 42,\n  \"shift\": 3.0,\n  \"num_inference_steps\": 8,\n  \"optimizer_type\": \"adamw\",\n  \"scheduler_type\": \"cosine\",\n  \"cfg_ratio\": 0.15,\n  \"save_every\": 10,\n  \"log_every\": 10,\n  \"log_heavy_every\": 50,\n  \"gradient_checkpointing\": true,\n  \"offload_encoder\": false,\n  \"sample_every_n_epochs\": 0\n}\n"
  },
  {
    "path": "acestep/training_v2/presets/vram_8gb.json",
    "content": "{\n  \"name\": \"vram_8gb\",\n  \"description\": \"Minimal (<10 GB) -- RTX 4060 8GB, 3050, GTX 1080. Aggressive savings, low rank.\",\n  \"rank\": 16,\n  \"alpha\": 32,\n  \"dropout\": 0.1,\n  \"target_modules_str\": \"q_proj k_proj v_proj o_proj\",\n  \"attention_type\": \"both\",\n  \"bias\": \"none\",\n  \"learning_rate\": 1e-4,\n  \"batch_size\": 1,\n  \"gradient_accumulation\": 8,\n  \"epochs\": 100,\n  \"warmup_steps\": 100,\n  \"weight_decay\": 0.01,\n  \"max_grad_norm\": 1.0,\n  \"seed\": 42,\n  \"shift\": 3.0,\n  \"num_inference_steps\": 8,\n  \"optimizer_type\": \"adamw8bit\",\n  \"scheduler_type\": \"cosine\",\n  \"cfg_ratio\": 0.15,\n  \"save_every\": 10,\n  \"log_every\": 10,\n  \"log_heavy_every\": 50,\n  \"gradient_checkpointing\": true,\n  \"offload_encoder\": true,\n  \"sample_every_n_epochs\": 0\n}\n"
  },
  {
    "path": "acestep/training_v2/settings.py",
    "content": "\"\"\"\nPersistent user settings for Side-Step.\n\nStored as JSON at a platform-aware location:\n\n    Linux/macOS:  ``~/.config/sidestep/settings.json``\n    Windows:      ``%APPDATA%\\\\sidestep\\\\settings.json``\n\nSettings hold environment paths (checkpoint directory, ACE-Step install\nlocation) and flags (vanilla intent, first-run state).  They are *not*\ntraining hyperparameters -- those live in presets.\n\"\"\"\n\nfrom __future__ import annotations\n\nimport json\nimport logging\nimport os\nimport sys\nfrom pathlib import Path\nfrom typing import Any, Dict, Optional\n\nlogger = logging.getLogger(__name__)\n\n# Current schema version -- bump when adding/renaming keys.\n_SCHEMA_VERSION = 1\n\n\n# ---------------------------------------------------------------------------\n# Paths\n# ---------------------------------------------------------------------------\n\ndef settings_dir() -> Path:\n    \"\"\"Platform-aware root config directory for Side-Step.\"\"\"\n    if sys.platform == \"win32\":\n        base = Path(os.environ.get(\"APPDATA\", Path.home() / \"AppData\" / \"Roaming\"))\n    else:\n        base = Path.home() / \".config\"\n    return base / \"sidestep\"\n\n\ndef settings_path() -> Path:\n    \"\"\"Full path to the settings JSON file.\"\"\"\n    return settings_dir() / \"settings.json\"\n\n\n# ---------------------------------------------------------------------------\n# Load / Save\n# ---------------------------------------------------------------------------\n\ndef _default_settings() -> Dict[str, Any]:\n    \"\"\"Return a blank settings dict with the current schema version.\"\"\"\n    return {\n        \"version\": _SCHEMA_VERSION,\n        \"checkpoint_dir\": None,\n        \"vanilla_enabled\": False,\n        \"first_run_complete\": False,\n    }\n\n\ndef load_settings() -> Optional[Dict[str, Any]]:\n    \"\"\"Load settings from disk.\n\n    Returns ``None`` if the file does not exist or cannot be parsed.\n    Performs lightweight schema migration when the on-disk version is\n    older than ``_SCHEMA_VERSION``.\n    \"\"\"\n    p = settings_path()\n    if not p.is_file():\n        return None\n    try:\n        data = json.loads(p.read_text(encoding=\"utf-8\"))\n    except (json.JSONDecodeError, OSError) as exc:\n        logger.warning(\"Failed to read settings: %s\", exc)\n        return None\n\n    # Schema migration: fill missing keys from defaults\n    defaults = _default_settings()\n    for key, val in defaults.items():\n        data.setdefault(key, val)\n    data[\"version\"] = _SCHEMA_VERSION\n    return data\n\n\ndef save_settings(data: Dict[str, Any]) -> None:\n    \"\"\"Write settings to disk, creating parent directories as needed.\"\"\"\n    data[\"version\"] = _SCHEMA_VERSION\n    p = settings_path()\n    p.parent.mkdir(parents=True, exist_ok=True)\n    p.write_text(json.dumps(data, indent=2) + \"\\n\", encoding=\"utf-8\")\n    logger.debug(\"Settings saved to %s\", p)\n\n\n# ---------------------------------------------------------------------------\n# Convenience helpers\n# ---------------------------------------------------------------------------\n\ndef is_first_run() -> bool:\n    \"\"\"Return ``True`` if settings do not exist or setup was never completed.\"\"\"\n    data = load_settings()\n    if data is None:\n        return True\n    return not data.get(\"first_run_complete\", False)\n\n\ndef get_checkpoint_dir() -> Optional[str]:\n    \"\"\"Return the stored checkpoint directory, or ``None``.\"\"\"\n    data = load_settings()\n    if data is None:\n        return None\n    return data.get(\"checkpoint_dir\")\n\n\n"
  },
  {
    "path": "acestep/training_v2/tensorboard_utils.py",
    "content": "\"\"\"\nExtended TensorBoard Logging for ACE-Step Training V2\n\nProvides helpers for:\n    - Per-layer gradient norms\n    - Learning rate tracking\n    - Loss curves\n    - Estimation score logging\n\"\"\"\n\nfrom __future__ import annotations\n\nimport logging\nfrom pathlib import Path\nfrom typing import Any, Dict, Optional\n\nimport torch\nimport torch.nn as nn\n\nlogger = logging.getLogger(__name__)\n\ntry:\n    from torch.utils.tensorboard import SummaryWriter\n\n    _TB_AVAILABLE = True\nexcept ImportError:\n    _TB_AVAILABLE = False\n    SummaryWriter = None  # type: ignore[misc,assignment]\n\n\ndef is_tensorboard_available() -> bool:\n    \"\"\"Return True if tensorboard is importable.\"\"\"\n    return _TB_AVAILABLE\n\n\nclass TrainingLogger:\n    \"\"\"Wrapper around ``SummaryWriter`` with training-specific helpers.\n\n    If TensorBoard is not installed, all methods are silent no-ops.\n    \"\"\"\n\n    def __init__(self, log_dir: str | Path, enabled: bool = True) -> None:\n        self._writer: Optional[Any] = None\n        self._enabled = enabled and _TB_AVAILABLE\n        if self._enabled:\n            log_dir = Path(log_dir)\n            log_dir.mkdir(parents=True, exist_ok=True)\n            self._writer = SummaryWriter(log_dir=str(log_dir))\n            logger.info(\"[OK] TensorBoard logger initialised at %s\", log_dir)\n        else:\n            if enabled and not _TB_AVAILABLE:\n                logger.warning(\n                    \"[WARN] tensorboard not installed -- logging disabled. \"\n                    \"Install with: pip install tensorboard\"\n                )\n\n    # ------------------------------------------------------------------\n    # Basic scalars\n    # ------------------------------------------------------------------\n\n    def log_scalar(self, tag: str, value: float, step: int) -> None:\n        \"\"\"Log a single scalar value.\"\"\"\n        if self._writer is not None:\n            self._writer.add_scalar(tag, value, global_step=step)\n\n    def log_loss(self, loss: float, step: int) -> None:\n        self.log_scalar(\"train/loss\", loss, step)\n\n    def log_lr(self, lr: float, step: int) -> None:\n        self.log_scalar(\"train/lr\", lr, step)\n\n    def log_epoch_loss(self, loss: float, epoch: int) -> None:\n        self.log_scalar(\"train/epoch_loss\", loss, epoch)\n\n    def log_grad_norm(self, norm: float, step: int) -> None:\n        self.log_scalar(\"train/grad_norm\", norm, step)\n\n    # ------------------------------------------------------------------\n    # Per-layer gradient norms (heavy)\n    # ------------------------------------------------------------------\n\n    def log_per_layer_grad_norms(\n        self,\n        model: nn.Module,\n        step: int,\n        prefix: str = \"grad_norm\",\n    ) -> Dict[str, float]:\n        \"\"\"Compute and log the L2 gradient norm of every named parameter.\n\n        Only parameters with ``requires_grad=True`` and a non-None\n        ``.grad`` are considered (i.e. only LoRA parameters).\n\n        Returns:\n            Dict mapping ``{prefix}/{param_name}`` -> norm value.\n        \"\"\"\n        norms: Dict[str, float] = {}\n        with torch.no_grad():\n            for name, param in model.named_parameters():\n                if param.requires_grad and param.grad is not None:\n                    # Compute norm in native dtype (avoids creating a\n                    # temporary fp32 GPU copy of each gradient tensor).\n                    norm_val = param.grad.data.norm(2).item()\n                    tag = f\"{prefix}/{name}\"\n                    norms[tag] = norm_val\n                    if self._writer is not None:\n                        self._writer.add_scalar(tag, norm_val, global_step=step)\n        return norms\n\n    # ------------------------------------------------------------------\n    # Estimation scores\n    # ------------------------------------------------------------------\n\n    def log_estimation_scores(\n        self,\n        scores: Dict[str, float],\n        step: int = 0,\n        prefix: str = \"estimation\",\n    ) -> None:\n        \"\"\"Log estimation gradient sensitivity scores.\"\"\"\n        for module_name, score in scores.items():\n            tag = f\"{prefix}/{module_name}\"\n            self.log_scalar(tag, score, step)\n\n    # ------------------------------------------------------------------\n    # Histogram helpers\n    # ------------------------------------------------------------------\n\n    def log_param_histogram(\n        self,\n        model: nn.Module,\n        step: int,\n        prefix: str = \"params\",\n    ) -> None:\n        \"\"\"Log weight histograms for trainable parameters.\"\"\"\n        if self._writer is None:\n            return\n        with torch.no_grad():\n            for name, param in model.named_parameters():\n                if param.requires_grad:\n                    # Move to CPU in native dtype first, then upcast\n                    # to float32 on CPU (avoids GPU fp32 intermediate).\n                    cpu_data = param.data.cpu().float()\n                    self._writer.add_histogram(\n                        f\"{prefix}/{name}\", cpu_data, global_step=step,\n                    )\n                    del cpu_data\n\n    # ------------------------------------------------------------------\n    # Lifecycle\n    # ------------------------------------------------------------------\n\n    def flush(self) -> None:\n        if self._writer is not None:\n            self._writer.flush()\n\n    def close(self) -> None:\n        if self._writer is not None:\n            self._writer.close()\n            self._writer = None\n\n    def __enter__(self) -> \"TrainingLogger\":\n        return self\n\n    def __exit__(self, *exc: Any) -> None:\n        self.close()\n"
  },
  {
    "path": "acestep/training_v2/timestep_sampling.py",
    "content": "\"\"\"\nCorrect Timestep Sampling and CFG Dropout for ACE-Step Training V2\n\nReimplements ``sample_t_r()`` exactly as defined in the model's own\n``forward()`` method (``modeling_acestep_v15_turbo.py`` lines 169-194).\n\nAlso provides ``apply_cfg_dropout()`` matching lines 1691-1699 of the\nsame file.\n\"\"\"\n\nfrom __future__ import annotations\n\nimport torch\n\n\n# ---------------------------------------------------------------------------\n# Continuous logit-normal timestep sampling\n# ---------------------------------------------------------------------------\n\ndef sample_timesteps(\n    batch_size: int,\n    device: torch.device | str,\n    dtype: torch.dtype,\n    data_proportion: float = 0.0,\n    timestep_mu: float = -0.4,\n    timestep_sigma: float = 1.0,\n    use_meanflow: bool = False,\n) -> tuple[torch.Tensor, torch.Tensor]:\n    \"\"\"Sample timestep ``t`` and ``r`` for flow matching training.\n\n    This is a faithful reimplementation of ``sample_t_r()`` from\n    ``checkpoints/acestep-v15-turbo/modeling_acestep_v15_turbo.py``\n    lines 169-194.\n\n    All ACE-Step model variants call this with ``use_meanflow=False``\n    during training, which forces ``data_proportion=1.0`` and therefore\n    ``r = t`` for every sample in the batch.\n\n    Args:\n        batch_size: Number of samples.\n        device: Torch device.\n        dtype: Tensor dtype (e.g. ``torch.bfloat16``).\n        data_proportion: Proportion of data samples (from model config).\n        timestep_mu: Mean for logit-normal sampling (from model config).\n        timestep_sigma: Std  for logit-normal sampling (from model config).\n        use_meanflow: Whether to use mean-flow (``False`` for all current\n            ACE-Step variants during training).\n\n    Returns:\n        ``(t, r)`` -- each of shape ``[batch_size]``.\n    \"\"\"\n    # Logit-normal sampling via sigmoid(N(mu, sigma))\n    t = torch.sigmoid(\n        torch.randn((batch_size,), device=device, dtype=dtype) * timestep_sigma + timestep_mu\n    )\n    r = torch.sigmoid(\n        torch.randn((batch_size,), device=device, dtype=dtype) * timestep_sigma + timestep_mu\n    )\n\n    # Assign t = max, r = min for each pair\n    t, r = torch.maximum(t, r), torch.minimum(t, r)\n\n    # When use_meanflow is False the model forces data_proportion = 1.0,\n    # which makes r = t for *every* sample (the zero_mask covers the full\n    # batch).\n    if not use_meanflow:\n        data_proportion = 1.0\n\n    data_size = int(batch_size * data_proportion)\n    zero_mask = torch.arange(batch_size, device=device) < data_size\n    r = torch.where(zero_mask, t, r)\n\n    return t, r\n\n\n# ---------------------------------------------------------------------------\n# CFG dropout\n# ---------------------------------------------------------------------------\n\ndef apply_cfg_dropout(\n    encoder_hidden_states: torch.Tensor,\n    null_condition_emb: torch.Tensor,\n    cfg_ratio: float = 0.15,\n) -> torch.Tensor:\n    \"\"\"Apply classifier-free guidance dropout to condition embeddings.\n\n    Faithful reimplementation of lines 1691-1699 of\n    ``modeling_acestep_v15_turbo.py``:\n\n    .. code-block:: python\n\n        full_cfg_condition_mask = torch.where(\n            (torch.rand(size=(bsz,), device=device, dtype=dtype) < cfg_ratio),\n            torch.zeros(size=(bsz,), device=device, dtype=dtype),\n            torch.ones(size=(bsz,), device=device, dtype=dtype),\n        ).view(-1, 1, 1)\n        encoder_hidden_states = torch.where(\n            full_cfg_condition_mask > 0,\n            encoder_hidden_states,\n            self.null_condition_emb.expand_as(encoder_hidden_states),\n        )\n\n    Args:\n        encoder_hidden_states: Condition embeddings ``[B, L, D]``.\n        null_condition_emb: Null (unconditional) embedding.  Will be\n            ``expand_as``'d to match ``encoder_hidden_states``.\n        cfg_ratio: Probability of replacing a sample's condition with\n            the null embedding (default 0.15).\n\n    Returns:\n        Modified ``encoder_hidden_states`` with some samples replaced.\n    \"\"\"\n    bsz = encoder_hidden_states.shape[0]\n    device = encoder_hidden_states.device\n    dtype = encoder_hidden_states.dtype\n\n    # Per-sample mask: 0 = drop condition (replace with null), 1 = keep\n    full_cfg_condition_mask = torch.where(\n        torch.rand(size=(bsz,), device=device, dtype=dtype) < cfg_ratio,\n        torch.zeros(size=(bsz,), device=device, dtype=dtype),\n        torch.ones(size=(bsz,), device=device, dtype=dtype),\n    ).view(-1, 1, 1)\n\n    encoder_hidden_states = torch.where(\n        full_cfg_condition_mask > 0,\n        encoder_hidden_states,\n        null_condition_emb.expand_as(encoder_hidden_states),\n    )\n\n    return encoder_hidden_states\n"
  },
  {
    "path": "acestep/training_v2/trainer_basic_loop.py",
    "content": "\"\"\"\nBasic (non-Fabric) training loop for FixedLoRATrainer.\n\nExtracted from ``FixedLoRATrainer._train_basic`` to keep\n``trainer_fixed.py`` under the LOC limit.  This module provides a single\ngenerator function that yields ``TrainingUpdate`` objects exactly like\nthe Fabric loop, but uses manual ``loss.backward()`` and\n``torch.nn.utils.clip_grad_norm_`` instead of Fabric wrappers.\n\"\"\"\n\nfrom __future__ import annotations\n\nimport logging\nimport math\nimport time\nfrom pathlib import Path\nfrom typing import Any, Dict, Generator, List, Optional, Tuple\n\nimport torch\n\nfrom acestep.training_v2.optim import build_optimizer, build_scheduler\nfrom acestep.training_v2.tensorboard_utils import TrainingLogger\nfrom acestep.training_v2.trainer_helpers import configure_memory_features, save_checkpoint, save_final\nfrom acestep.training_v2.ui import TrainingUpdate\n\nlogger = logging.getLogger(__name__)\n\n\n# ---------------------------------------------------------------------------\n# Extracted helpers\n# ---------------------------------------------------------------------------\n\ndef _flush_accumulated(\n    trainable_params: list,\n    optimizer: Any,\n    scheduler: Any,\n    accumulated_loss: float,\n    accumulation_step: int,\n    cfg: Any,\n    tb: TrainingLogger,\n    module: Any,\n    epoch: int,\n    global_step: int,\n    steps_per_epoch: int,\n) -> Tuple[int, float, List[TrainingUpdate]]:\n    \"\"\"Clip gradients, step optimizer/scheduler, zero grads, and log.\n\n    Consolidates the duplicated optimizer-step sequence used both inside\n    the accumulation check and the end-of-epoch flush.\n\n    Returns:\n        ``(global_step, avg_loss, updates)`` where *updates* is a list\n        of ``TrainingUpdate`` objects the caller should yield.\n    \"\"\"\n    torch.nn.utils.clip_grad_norm_(trainable_params, cfg.max_grad_norm)\n    optimizer.step()\n    scheduler.step()\n    optimizer.zero_grad(set_to_none=True)\n    global_step += 1\n\n    avg_loss = accumulated_loss * cfg.gradient_accumulation_steps / accumulation_step\n    _lr = scheduler.get_last_lr()[0]\n    updates: List[TrainingUpdate] = []\n\n    if global_step % cfg.log_every == 0:\n        tb.log_loss(avg_loss, global_step)\n        tb.log_lr(_lr, global_step)\n        updates.append(TrainingUpdate(\n            step=global_step, loss=avg_loss,\n            msg=f\"Epoch {epoch + 1}, Step {global_step}, Loss: {avg_loss:.4f}\",\n            kind=\"step\", epoch=epoch + 1, max_epochs=cfg.max_epochs, lr=_lr,\n            steps_per_epoch=steps_per_epoch,\n        ))\n\n    if global_step % cfg.log_heavy_every == 0:\n        tb.log_per_layer_grad_norms(module.model, global_step)\n\n    return global_step, avg_loss, updates\n\n\n# ---------------------------------------------------------------------------\n# Main loop\n# ---------------------------------------------------------------------------\n\ndef run_basic_training_loop(\n    trainer: Any,\n    data_module: Any,\n    training_state: Optional[Dict[str, Any]],\n) -> Generator[TrainingUpdate, None, None]:\n    \"\"\"Execute the basic (non-Fabric) training loop.\n\n    Args:\n        trainer: The ``FixedLoRATrainer`` instance.\n        data_module: ``PreprocessedDataModule`` with training data.\n        training_state: Optional dict with ``should_stop`` flag.\n\n    Yields:\n        ``TrainingUpdate`` tuples for each step/epoch/event.\n    \"\"\"\n    cfg = trainer.training_config\n    module = trainer.module\n    assert module is not None\n\n    output_dir = Path(cfg.output_dir)\n    output_dir.mkdir(parents=True, exist_ok=True)\n\n    yield TrainingUpdate(0, 0.0, \"[INFO] Starting basic training loop (no Fabric)\", kind=\"info\")\n\n    tb = TrainingLogger(cfg.effective_log_dir)\n    train_loader = data_module.train_dataloader()\n\n    trainable_params = [p for p in module.model.parameters() if p.requires_grad]\n    if not trainable_params:\n        yield TrainingUpdate(0, 0.0, \"[FAIL] No trainable parameters found\", kind=\"fail\")\n        tb.close()\n        return\n\n    device_type = module.device_type if hasattr(module, \"device_type\") else str(module.device).split(\":\")[0]\n    optimizer_type = getattr(cfg, \"optimizer_type\", \"adamw\")\n    optimizer = build_optimizer(\n        trainable_params,\n        optimizer_type=optimizer_type,\n        lr=cfg.learning_rate,\n        weight_decay=cfg.weight_decay,\n        device_type=device_type,\n    )\n\n    steps_per_epoch = max(1, math.ceil(len(train_loader) / cfg.gradient_accumulation_steps))\n    total_steps = steps_per_epoch * cfg.max_epochs\n\n    scheduler = build_scheduler(\n        optimizer,\n        scheduler_type=getattr(cfg, \"scheduler_type\", \"cosine\"),\n        total_steps=total_steps,\n        warmup_steps=cfg.warmup_steps,\n        lr=cfg.learning_rate,\n        optimizer_type=optimizer_type,\n    )\n\n    # -- Training memory features (same as Fabric path) ----------------\n    if getattr(cfg, \"gradient_checkpointing\", True):\n        ckpt_ok, cache_off, grads_ok = configure_memory_features(module.model.decoder)\n        module.force_input_grads_for_checkpointing = ckpt_ok\n        if ckpt_ok:\n            yield TrainingUpdate(\n                0, 0.0,\n                f\"[INFO] Gradient checkpointing enabled \"\n                f\"(use_cache={not cache_off}, input_grads={grads_ok})\",\n                kind=\"info\",\n            )\n\n    # -- Resume ---------------------------------------------------------\n    start_epoch = 0\n    global_step = 0\n\n    if cfg.resume_from and Path(cfg.resume_from).exists():\n        try:\n            yield TrainingUpdate(0, 0.0, f\"[INFO] Loading checkpoint from {cfg.resume_from}\", kind=\"info\")\n            from acestep.training_v2.trainer_helpers import resume_checkpoint\n            resumed = yield from resume_checkpoint(trainer, cfg.resume_from, optimizer, scheduler)\n            if resumed is not None:\n                start_epoch, global_step = resumed\n        except Exception as exc:\n            logger.exception(\"Failed to load checkpoint\")\n            yield TrainingUpdate(0, 0.0, f\"[WARN] Checkpoint load failed: {exc} -- starting fresh\", kind=\"warn\")\n\n    accumulation_step = 0\n    accumulated_loss = 0.0\n    optimizer.zero_grad(set_to_none=True)\n    module.model.decoder.train()\n\n    for epoch in range(start_epoch, cfg.max_epochs):\n        epoch_loss = 0.0\n        num_updates = 0\n        epoch_start = time.time()\n\n        for batch in train_loader:\n            if training_state and training_state.get(\"should_stop\", False):\n                _stop_loss = accumulated_loss * cfg.gradient_accumulation_steps / max(accumulation_step, 1)\n                yield TrainingUpdate(global_step, _stop_loss, \"[INFO] Training stopped\", kind=\"complete\")\n                tb.close()\n                return\n\n            loss = module.training_step(batch)\n            loss = loss / cfg.gradient_accumulation_steps\n            loss.backward()\n            accumulated_loss += loss.item()\n            del loss\n            accumulation_step += 1\n\n            if accumulation_step >= cfg.gradient_accumulation_steps:\n                global_step, avg_loss, updates = _flush_accumulated(\n                    trainable_params, optimizer, scheduler,\n                    accumulated_loss, accumulation_step, cfg, tb, module,\n                    epoch, global_step, steps_per_epoch,\n                )\n                yield from updates\n                epoch_loss += avg_loss\n                num_updates += 1\n                accumulated_loss = 0.0\n                accumulation_step = 0\n\n                if torch.cuda.is_available() and global_step % cfg.log_every == 0:\n                    torch.cuda.empty_cache()\n\n        # Flush remainder\n        if accumulation_step > 0:\n            global_step, avg_loss, updates = _flush_accumulated(\n                trainable_params, optimizer, scheduler,\n                accumulated_loss, accumulation_step, cfg, tb, module,\n                epoch, global_step, steps_per_epoch,\n            )\n            yield from updates\n            epoch_loss += avg_loss\n            num_updates += 1\n            accumulated_loss = 0.0\n            accumulation_step = 0\n\n        epoch_time = time.time() - epoch_start\n        avg_epoch_loss = epoch_loss / max(num_updates, 1)\n        tb.log_epoch_loss(avg_epoch_loss, epoch + 1)\n        yield TrainingUpdate(\n            step=global_step, loss=avg_epoch_loss,\n            msg=f\"[OK] Epoch {epoch + 1}/{cfg.max_epochs} in {epoch_time:.1f}s\",\n            kind=\"epoch\", epoch=epoch + 1, max_epochs=cfg.max_epochs, epoch_time=epoch_time,\n        )\n\n        if (epoch + 1) % cfg.save_every_n_epochs == 0:\n            ckpt_dir = str(output_dir / \"checkpoints\" / f\"epoch_{epoch + 1}_loss_{avg_epoch_loss:.4f}\")\n            save_checkpoint(trainer, optimizer, scheduler, epoch + 1, global_step, ckpt_dir)\n            yield TrainingUpdate(\n                step=global_step, loss=avg_epoch_loss,\n                msg=f\"[OK] Checkpoint saved at epoch {epoch + 1}\",\n                kind=\"checkpoint\", epoch=epoch + 1, max_epochs=cfg.max_epochs,\n                checkpoint_path=ckpt_dir,\n            )\n\n        if torch.cuda.is_available():\n            torch.cuda.empty_cache()\n\n    # -- Sanity check: did we actually train? ----------------------------\n    if global_step == 0:\n        tb.close()\n        yield TrainingUpdate(\n            step=0, loss=0.0,\n            msg=(\n                \"[FAIL] Training completed 0 steps -- no batches were processed.\\n\"\n                \"       Possible causes:\\n\"\n                \"         - Dataset directory is empty or contains no valid .pt files\\n\"\n                \"         - DataLoader failed to yield batches (device/platform issue)\\n\"\n                \"       Check the dataset path and try again.\"\n            ),\n            kind=\"fail\",\n        )\n        return\n\n    final_path = str(output_dir / \"final\")\n    save_final(trainer, final_path)\n    final_loss = module.training_losses[-1] if module.training_losses else 0.0\n\n    adapter_label = \"LoKR\" if trainer.adapter_type == \"lokr\" else \"LoRA\"\n    tb.flush()\n    tb.close()\n    yield TrainingUpdate(\n        step=global_step, loss=final_loss,\n        msg=(\n            f\"[OK] Training complete! {adapter_label} saved to {final_path}\\n\"\n            f\"     For inference, set your LoRA path to: {final_path}\"\n        ),\n        kind=\"complete\",\n    )\n"
  },
  {
    "path": "acestep/training_v2/trainer_fixed.py",
    "content": "\"\"\"\nFixedLoRATrainer -- Orchestration for ACE-Step V2 adapter fine-tuning.\n\nThe actual per-step training logic lives in ``fixed_lora_module.py``\n(``FixedLoRAModule``).  The non-Fabric fallback loop lives in\n``trainer_basic_loop.py``.  Checkpoint, memory, and verification helpers\nlive in ``trainer_helpers.py``.\n\nSupports both adapter types:\n    - **LoRA** via PEFT (``inject_lora_into_dit``)\n    - **LoKR** via LyCORIS (``inject_lokr_into_dit``)\n\nUses shared utilities from ``acestep.training``.\n\"\"\"\n\nfrom __future__ import annotations\n\nimport logging\nimport math\nimport random\nimport sys\nimport time\nfrom pathlib import Path\nfrom typing import Any, Dict, Generator, Optional, Tuple\n\nimport torch\nimport torch.nn as nn\nfrom acestep.training_v2.optim import build_optimizer, build_scheduler\nfrom acestep.training.data_module import PreprocessedDataModule\n\n# V2 modules\nfrom acestep.training_v2.configs import TrainingConfigV2\nfrom acestep.training_v2.tensorboard_utils import TrainingLogger\nfrom acestep.training_v2.ui import TrainingUpdate\n\n# Split-out modules\nfrom acestep.training_v2.fixed_lora_module import (\n    AdapterConfig,\n    FixedLoRAModule,\n    _normalize_device_type,\n    _select_compute_dtype,\n    _select_fabric_precision,\n)\nfrom acestep.training_v2.trainer_helpers import (\n    configure_memory_features,\n    offload_non_decoder,\n    resume_checkpoint,\n    save_adapter_flat,\n    save_checkpoint,\n    save_final,\n    verify_saved_adapter,\n)\nfrom acestep.training_v2.trainer_basic_loop import run_basic_training_loop\n\nlogger = logging.getLogger(__name__)\n\n# Try to import Lightning Fabric\ntry:\n    from lightning.fabric import Fabric\n\n    _FABRIC_AVAILABLE = True\nexcept ImportError:\n    _FABRIC_AVAILABLE = False\n    logger.warning(\"[WARN] Lightning Fabric not installed. Training will use basic loop.\")\n\n\n# ===========================================================================\n# FixedLoRATrainer -- orchestration\n# ===========================================================================\n\nclass FixedLoRATrainer:\n    \"\"\"High-level trainer for corrected ACE-Step adapter fine-tuning.\n\n    Supports both LoRA (PEFT) and LoKR (LyCORIS) adapters.\n    Uses Lightning Fabric for mixed precision and gradient scaling.\n    Falls back to a basic PyTorch loop when Fabric is not installed.\n    \"\"\"\n\n    def __init__(\n        self,\n        model: nn.Module,\n        adapter_config: AdapterConfig,\n        training_config: TrainingConfigV2,\n    ) -> None:\n        self.model = model\n        self.adapter_config = adapter_config\n        self.training_config = training_config\n        self.adapter_type = training_config.adapter_type\n\n        # Backward-compat alias\n        self.lora_config = adapter_config\n\n        self.module: Optional[FixedLoRAModule] = None\n        self.fabric: Optional[Any] = None\n        self.is_training = False\n\n    # ------------------------------------------------------------------\n    # Public API\n    # ------------------------------------------------------------------\n\n    def train(\n        self,\n        training_state: Optional[Dict[str, Any]] = None,\n    ) -> Generator[Tuple[int, float, str], None, None]:\n        \"\"\"Run the full training loop.\n\n        Yields ``(global_step, loss, status_message)`` tuples.\n        \"\"\"\n        self.is_training = True\n        cfg = self.training_config\n\n        try:\n            # -- Validate ---------------------------------------------------\n            ds_dir = Path(cfg.dataset_dir)\n            if not ds_dir.is_dir():\n                yield TrainingUpdate(0, 0.0, f\"[FAIL] Dataset directory not found: {ds_dir}\", kind=\"fail\")\n                return\n\n            # -- Seed -------------------------------------------------------\n            torch.manual_seed(cfg.seed)\n            random.seed(cfg.seed)\n            if torch.cuda.is_available():\n                torch.cuda.manual_seed_all(cfg.seed)\n\n            # -- Build module -----------------------------------------------\n            device = torch.device(cfg.device)\n            dtype = _select_compute_dtype(_normalize_device_type(device))\n\n            self.module = FixedLoRAModule(\n                model=self.model,\n                adapter_config=self.adapter_config,\n                training_config=cfg,\n                device=device,\n                dtype=dtype,\n            )\n\n            # -- Data -------------------------------------------------------\n            # Windows uses spawn for multiprocessing; default to 0 workers there\n            num_workers = cfg.num_workers\n            if sys.platform == \"win32\" and num_workers > 0:\n                logger.info(\"[Side-Step] Windows detected -- setting num_workers=0 (spawn incompatible)\")\n                num_workers = 0\n\n            data_module = PreprocessedDataModule(\n                tensor_dir=cfg.dataset_dir,\n                batch_size=cfg.batch_size,\n                num_workers=num_workers,\n                pin_memory=cfg.pin_memory,\n                prefetch_factor=cfg.prefetch_factor if num_workers > 0 else None,\n                persistent_workers=cfg.persistent_workers if num_workers > 0 else False,\n                pin_memory_device=cfg.pin_memory_device,\n            )\n            data_module.setup(\"fit\")\n\n            if len(data_module.train_dataset) == 0:\n                yield TrainingUpdate(0, 0.0, \"[FAIL] No valid samples found in dataset directory\", kind=\"fail\")\n                return\n\n            yield TrainingUpdate(0, 0.0, f\"[OK] Loaded {len(data_module.train_dataset)} preprocessed samples\", kind=\"info\")\n\n            # -- Dispatch to Fabric or basic loop ---------------------------\n            if _FABRIC_AVAILABLE:\n                yield from self._train_fabric(data_module, training_state)\n            else:\n                yield from run_basic_training_loop(self, data_module, training_state)\n\n        except Exception as exc:\n            logger.exception(\"Training failed\")\n            yield TrainingUpdate(0, 0.0, f\"[FAIL] Training failed: {exc}\", kind=\"fail\")\n        finally:\n            self.is_training = False\n\n    def stop(self) -> None:\n        self.is_training = False\n\n    # ------------------------------------------------------------------\n    # Delegate helpers (thin wrappers around trainer_helpers functions)\n    # ------------------------------------------------------------------\n\n    @staticmethod\n    def _iter_module_wrappers(module: nn.Module) -> list:\n        from acestep.training_v2.trainer_helpers import iter_module_wrappers\n        return iter_module_wrappers(module)\n\n    @classmethod\n    def _configure_memory_features(cls, decoder: nn.Module) -> tuple:\n        return configure_memory_features(decoder)\n\n    @staticmethod\n    def _offload_non_decoder(model: nn.Module) -> int:\n        return offload_non_decoder(model)\n\n    def _save_adapter_flat(self, output_dir: str) -> None:\n        save_adapter_flat(self, output_dir)\n\n    def _save_checkpoint(\n        self, optimizer: Any, scheduler: Any, epoch: int, global_step: int, ckpt_dir: str,\n    ) -> None:\n        save_checkpoint(self, optimizer, scheduler, epoch, global_step, ckpt_dir)\n\n    def _save_final(self, output_dir: str) -> None:\n        save_final(self, output_dir)\n\n    @staticmethod\n    def _verify_saved_adapter(output_dir: str) -> None:\n        verify_saved_adapter(output_dir)\n\n    def _resume_checkpoint(\n        self, resume_path: str, optimizer: Any, scheduler: Any,\n    ) -> Generator[TrainingUpdate, None, Optional[Tuple[int, int]]]:\n        return (yield from resume_checkpoint(self, resume_path, optimizer, scheduler))\n\n    # ------------------------------------------------------------------\n    # Fabric training loop\n    # ------------------------------------------------------------------\n\n    def _train_fabric(\n        self,\n        data_module: PreprocessedDataModule,\n        training_state: Optional[Dict[str, Any]],\n    ) -> Generator[TrainingUpdate, None, None]:\n        cfg = self.training_config\n        assert self.module is not None\n\n        output_dir = Path(cfg.output_dir)\n        output_dir.mkdir(parents=True, exist_ok=True)\n\n        device_type = self.module.device_type\n        precision = _select_fabric_precision(device_type)\n        accelerator = device_type if device_type in (\"cuda\", \"xpu\", \"mps\", \"cpu\") else \"auto\"\n\n        # -- Fabric init ----------------------------------------------------\n        # Always use devices=1 (integer).  Passing devices=[index] (a list)\n        # causes Fabric on Windows to create a DistributedSampler wrapper\n        # that yields 0 batches, silently breaking the training loop.\n        # Instead, we set the default CUDA device so Fabric's single-device\n        # mode picks up the correct GPU.\n        if device_type == \"cuda\":\n            device_idx = self.module.device.index or 0\n            torch.cuda.set_device(device_idx)\n\n        self.fabric = Fabric(\n            accelerator=accelerator,\n            devices=1,\n            precision=precision,\n        )\n        self.fabric.launch()\n\n        yield TrainingUpdate(0, 0.0, f\"[INFO] Starting training (device: {device_type}, precision: {precision})\", kind=\"info\")\n\n        # -- TensorBoard logger ---------------------------------------------\n        tb = TrainingLogger(cfg.effective_log_dir)\n\n        # -- Dataloader -----------------------------------------------------\n        train_loader = data_module.train_dataloader()\n\n        # -- Trainable params / optimizer -----------------------------------\n        trainable_params = [p for p in self.module.model.parameters() if p.requires_grad]\n        if not trainable_params:\n            yield TrainingUpdate(0, 0.0, \"[FAIL] No trainable parameters found\", kind=\"fail\")\n            tb.close()\n            return\n\n        yield TrainingUpdate(0, 0.0, f\"[INFO] Training {sum(p.numel() for p in trainable_params):,} parameters\", kind=\"info\")\n\n        optimizer_type = getattr(cfg, \"optimizer_type\", \"adamw\")\n        optimizer = build_optimizer(\n            trainable_params,\n            optimizer_type=optimizer_type,\n            lr=cfg.learning_rate,\n            weight_decay=cfg.weight_decay,\n            device_type=self.module.device.type,\n        )\n        yield TrainingUpdate(0, 0.0, f\"[INFO] Optimizer: {optimizer_type}\", kind=\"info\")\n\n        # -- Scheduler -------------------------------------------------------\n        steps_per_epoch = max(1, math.ceil(len(train_loader) / cfg.gradient_accumulation_steps))\n        total_steps = steps_per_epoch * cfg.max_epochs\n\n        scheduler_type = getattr(cfg, \"scheduler_type\", \"cosine\")\n        scheduler = build_scheduler(\n            optimizer,\n            scheduler_type=scheduler_type,\n            total_steps=total_steps,\n            warmup_steps=cfg.warmup_steps,\n            lr=cfg.learning_rate,\n            optimizer_type=optimizer_type,\n        )\n        yield TrainingUpdate(0, 0.0, f\"[INFO] Scheduler: {scheduler_type}\", kind=\"info\")\n\n        # -- Training memory features ----------------------------------------\n        if getattr(cfg, \"gradient_checkpointing\", True):\n            ckpt_ok, cache_off, grads_ok = configure_memory_features(\n                self.module.model.decoder\n            )\n            self.module.force_input_grads_for_checkpointing = ckpt_ok\n            if ckpt_ok:\n                yield TrainingUpdate(\n                    0, 0.0,\n                    f\"[INFO] Gradient checkpointing enabled \"\n                    f\"(use_cache={not cache_off}, input_grads={grads_ok})\",\n                    kind=\"info\",\n                )\n            else:\n                yield TrainingUpdate(\n                    0, 0.0, \"[WARN] Gradient checkpointing not supported by this model\",\n                    kind=\"warn\",\n                )\n        else:\n            yield TrainingUpdate(\n                0, 0.0,\n                \"[INFO] Gradient checkpointing OFF (faster but uses more VRAM)\",\n                kind=\"info\",\n            )\n\n        # -- Encoder/VAE offloading ------------------------------------------\n        if getattr(cfg, \"offload_encoder\", False):\n            offloaded = offload_non_decoder(self.module.model)\n            if offloaded:\n                yield TrainingUpdate(0, 0.0, f\"[INFO] Offloaded {offloaded} model components to CPU (saves VRAM)\", kind=\"info\")\n                if torch.cuda.is_available():\n                    torch.cuda.empty_cache()\n\n        # -- dtype / Fabric setup -------------------------------------------\n        self.module.model = self.module.model.to(self.module.dtype)\n        self.module.model.decoder, optimizer = self.fabric.setup(self.module.model.decoder, optimizer)\n\n        # -- Resume ---------------------------------------------------------\n        start_epoch = 0\n        global_step = 0\n\n        if cfg.resume_from and Path(cfg.resume_from).exists():\n            try:\n                yield TrainingUpdate(0, 0.0, f\"[INFO] Loading checkpoint from {cfg.resume_from}\", kind=\"info\")\n                resumed = yield from self._resume_checkpoint(\n                    cfg.resume_from, optimizer, scheduler,\n                )\n                if resumed is not None:\n                    start_epoch, global_step = resumed\n            except Exception as exc:\n                logger.exception(\"Failed to load checkpoint\")\n                yield TrainingUpdate(0, 0.0, f\"[WARN] Checkpoint load failed: {exc} -- starting fresh\", kind=\"warn\")\n                start_epoch = 0\n                global_step = 0\n\n        # -- Training loop --------------------------------------------------\n        accumulation_step = 0\n        accumulated_loss = 0.0\n        optimizer.zero_grad(set_to_none=True)\n        self.module.model.decoder.train()\n\n        for epoch in range(start_epoch, cfg.max_epochs):\n            epoch_loss = 0.0\n            num_updates = 0\n            epoch_start = time.time()\n\n            for _batch_idx, batch in enumerate(train_loader):\n                # Stop signal\n                if training_state and training_state.get(\"should_stop\", False):\n                    _stop_loss = (\n                        accumulated_loss * cfg.gradient_accumulation_steps\n                        / max(accumulation_step, 1)\n                    )\n                    yield TrainingUpdate(global_step, _stop_loss, \"[INFO] Training stopped by user\", kind=\"complete\")\n                    tb.close()\n                    return\n\n                loss = self.module.training_step(batch)\n                loss = loss / cfg.gradient_accumulation_steps\n                self.fabric.backward(loss)\n                accumulated_loss += loss.item()\n                del loss  # free scalar tensor immediately\n                accumulation_step += 1\n\n                if accumulation_step >= cfg.gradient_accumulation_steps:\n                    self.fabric.clip_gradients(\n                        self.module.model.decoder, optimizer, max_norm=cfg.max_grad_norm,\n                    )\n                    optimizer.step()\n                    scheduler.step()\n                    global_step += 1\n\n                    avg_loss = accumulated_loss * cfg.gradient_accumulation_steps / accumulation_step\n                    _lr = scheduler.get_last_lr()[0]\n                    if global_step % cfg.log_every == 0:\n                        tb.log_loss(avg_loss, global_step)\n                        tb.log_lr(_lr, global_step)\n                        yield TrainingUpdate(\n                            step=global_step, loss=avg_loss,\n                            msg=f\"Epoch {epoch + 1}/{cfg.max_epochs}, Step {global_step}, Loss: {avg_loss:.4f}\",\n                            kind=\"step\", epoch=epoch + 1, max_epochs=cfg.max_epochs, lr=_lr,\n                            steps_per_epoch=steps_per_epoch,\n                        )\n\n                    if global_step % cfg.log_heavy_every == 0:\n                        tb.log_per_layer_grad_norms(self.module.model, global_step)\n\n                    optimizer.zero_grad(set_to_none=True)\n                    epoch_loss += avg_loss\n                    num_updates += 1\n                    accumulated_loss = 0.0\n                    accumulation_step = 0\n\n                    # Periodic CUDA cache cleanup to prevent intra-epoch\n                    # memory fragmentation on consumer GPUs.\n                    if torch.cuda.is_available() and global_step % cfg.log_every == 0:\n                        torch.cuda.empty_cache()\n\n            # Flush remainder\n            if accumulation_step > 0:\n                self.fabric.clip_gradients(\n                    self.module.model.decoder, optimizer, max_norm=cfg.max_grad_norm,\n                )\n                optimizer.step()\n                scheduler.step()\n                global_step += 1\n\n                avg_loss = accumulated_loss * cfg.gradient_accumulation_steps / accumulation_step\n                _lr = scheduler.get_last_lr()[0]\n                if global_step % cfg.log_every == 0:\n                    tb.log_loss(avg_loss, global_step)\n                    tb.log_lr(_lr, global_step)\n                    yield TrainingUpdate(\n                        step=global_step, loss=avg_loss,\n                        msg=f\"Epoch {epoch + 1}/{cfg.max_epochs}, Step {global_step}, Loss: {avg_loss:.4f}\",\n                        kind=\"step\", epoch=epoch + 1, max_epochs=cfg.max_epochs, lr=_lr,\n                        steps_per_epoch=steps_per_epoch,\n                    )\n\n                optimizer.zero_grad(set_to_none=True)\n                epoch_loss += avg_loss\n                num_updates += 1\n                accumulated_loss = 0.0\n                accumulation_step = 0\n\n            # End of epoch\n            epoch_time = time.time() - epoch_start\n            avg_epoch_loss = epoch_loss / max(num_updates, 1)\n            tb.log_epoch_loss(avg_epoch_loss, epoch + 1)\n            yield TrainingUpdate(\n                step=global_step, loss=avg_epoch_loss,\n                msg=f\"[OK] Epoch {epoch + 1}/{cfg.max_epochs} in {epoch_time:.1f}s, Loss: {avg_epoch_loss:.4f}\",\n                kind=\"epoch\", epoch=epoch + 1, max_epochs=cfg.max_epochs, epoch_time=epoch_time,\n            )\n\n            # Checkpoint\n            if (epoch + 1) % cfg.save_every_n_epochs == 0:\n                ckpt_dir = str(output_dir / \"checkpoints\" / f\"epoch_{epoch + 1}_loss_{avg_epoch_loss:.4f}\")\n                self._save_checkpoint(optimizer, scheduler, epoch + 1, global_step, ckpt_dir)\n                yield TrainingUpdate(\n                    step=global_step, loss=avg_epoch_loss,\n                    msg=f\"[OK] Checkpoint saved at epoch {epoch + 1}\",\n                    kind=\"checkpoint\", epoch=epoch + 1, max_epochs=cfg.max_epochs,\n                    checkpoint_path=ckpt_dir,\n                )\n\n            # Clear CUDA cache AFTER checkpoint save so serialization\n            # temporaries are also freed.\n            if torch.cuda.is_available():\n                torch.cuda.empty_cache()\n\n        # -- Sanity check: did we actually train? ----------------------------\n        if global_step == 0:\n            tb.close()\n            yield TrainingUpdate(\n                step=0, loss=0.0,\n                msg=(\n                    \"[FAIL] Training completed 0 steps -- no batches were processed.\\n\"\n                    \"       Possible causes:\\n\"\n                    \"         - Dataset directory is empty or contains no valid .pt files\\n\"\n                    \"         - DataLoader failed to yield batches (device/platform issue)\\n\"\n                    \"       Check the dataset path and try again.\"\n                ),\n                kind=\"fail\",\n            )\n            return\n\n        # -- Final save -----------------------------------------------------\n        final_path = str(output_dir / \"final\")\n        self._save_final(final_path)\n        final_loss = self.module.training_losses[-1] if self.module.training_losses else 0.0\n\n        adapter_label = \"LoKR\" if self.adapter_type == \"lokr\" else \"LoRA\"\n        tb.flush()\n        tb.close()\n        yield TrainingUpdate(\n            step=global_step, loss=final_loss,\n            msg=(\n                f\"[OK] Training complete! {adapter_label} saved to {final_path}\\n\"\n                f\"     For inference, set your LoRA path to: {final_path}\"\n            ),\n            kind=\"complete\",\n        )\n"
  },
  {
    "path": "acestep/training_v2/trainer_helpers.py",
    "content": "\"\"\"\nTrainer helper functions for FixedLoRATrainer.\n\nContains checkpoint save/resume, adapter verification, memory\nconfiguration, and module wrapper introspection -- extracted from\n``trainer_fixed.py`` to keep it under the LOC limit.\n\"\"\"\n\nfrom __future__ import annotations\n\nimport logging\nimport os\nfrom pathlib import Path\nfrom typing import Any, Generator, Optional, Tuple\n\nimport torch\nimport torch.nn as nn\n\nfrom acestep.training.lora_checkpoint import (\n    load_training_checkpoint,\n    save_lora_weights,\n)\nfrom acestep.training.lokr_utils import (\n    save_lokr_weights,\n    load_lokr_weights,\n)\nfrom acestep.training_v2.ui import TrainingUpdate\n\nlogger = logging.getLogger(__name__)\n\n\n# ---------------------------------------------------------------------------\n# Module introspection\n# ---------------------------------------------------------------------------\n\n\ndef iter_module_wrappers(module: nn.Module) -> list:\n    \"\"\"Collect wrapper-chain modules (Fabric/PEFT/compile wrappers).\n\n    Walks ``_forward_module``, ``_orig_mod``, ``base_model``, ``model``,\n    and ``module`` attributes to find all wrapped layers.  Ported from\n    ACE-Step's ``trainer.py`` to ensure parity.\n    \"\"\"\n    modules: list = []\n    stack = [module]\n    visited: set = set()\n    while stack:\n        current = stack.pop()\n        if not isinstance(current, nn.Module):\n            continue\n        mid = id(current)\n        if mid in visited:\n            continue\n        visited.add(mid)\n        modules.append(current)\n        for attr in (\"_forward_module\", \"_orig_mod\", \"base_model\", \"model\", \"module\"):\n            child = getattr(current, attr, None)\n            if isinstance(child, nn.Module):\n                stack.append(child)\n    return modules\n\n\n# ---------------------------------------------------------------------------\n# Memory configuration\n# ---------------------------------------------------------------------------\n\n\ndef configure_memory_features(decoder: nn.Module) -> tuple:\n    \"\"\"Enable gradient checkpointing, disable use_cache, and enable\n    input_require_grads across all wrapper layers of *decoder*.\n\n    Mirrors ACE-Step's ``_configure_training_memory_features()`` exactly\n    so that VRAM usage is identical.\n\n    Returns:\n        ``(checkpointing_enabled, cache_disabled, input_grads_enabled)``\n    \"\"\"\n    ckpt_enabled = False\n    cache_disabled = False\n    input_grads_enabled = False\n\n    for mod in iter_module_wrappers(decoder):\n        # 1. Gradient checkpointing\n        if hasattr(mod, \"gradient_checkpointing_enable\"):\n            try:\n                mod.gradient_checkpointing_enable()\n                ckpt_enabled = True\n            except Exception:\n                pass\n        elif hasattr(mod, \"gradient_checkpointing\"):\n            try:\n                mod.gradient_checkpointing = True\n                ckpt_enabled = True\n            except Exception:\n                pass\n\n        # 2. PEFT + checkpointing needs input embeddings to carry grads\n        if hasattr(mod, \"enable_input_require_grads\"):\n            try:\n                mod.enable_input_require_grads()\n                hook_ok = bool(getattr(mod, \"_acestep_input_grads_hook_enabled\", False))\n                has_hook = getattr(mod, \"_require_grads_hook\", None) is not None\n                if hook_ok or has_hook:\n                    input_grads_enabled = True\n            except Exception:\n                pass\n\n        # 3. Disable use_cache (frees KV-cache memory)\n        cfg = getattr(mod, \"config\", None)\n        if cfg is not None and hasattr(cfg, \"use_cache\"):\n            try:\n                if getattr(cfg, \"use_cache\", None) is not False:\n                    cfg.use_cache = False\n                    cache_disabled = True\n            except Exception:\n                pass\n\n    return ckpt_enabled, cache_disabled, input_grads_enabled\n\n\ndef offload_non_decoder(model: nn.Module) -> int:\n    \"\"\"Move encoder/VAE/non-decoder submodules to CPU. Returns count offloaded.\"\"\"\n    count = 0\n    for name in (\n        \"music_encoder\",\n        \"lyric_encoder\",\n        \"timbre_encoder\",\n        \"condition_projection\",\n        \"vae\",\n        \"text_encoder\",\n        \"attention_pooler\",\n    ):\n        sub = getattr(model, name, None)\n        if sub is not None and isinstance(sub, nn.Module):\n            sub.to(\"cpu\")\n            count += 1\n    return count\n\n\n# ---------------------------------------------------------------------------\n# Adapter-aware save helpers\n# ---------------------------------------------------------------------------\n\n\ndef save_adapter_flat(trainer: Any, output_dir: str) -> None:\n    \"\"\"Save adapter weights directly into *output_dir* (no nesting).\n\n    Writes ``adapter_config.json`` and ``adapter_model.safetensors``\n    (or LoKR equivalent) directly into *output_dir* so that\n    inference tools can point straight at this directory.\n    \"\"\"\n    module = trainer.module\n    assert module is not None\n    os.makedirs(output_dir, exist_ok=True)\n\n    if trainer.adapter_type == \"lokr\":\n        if module.lycoris_net is None:\n            logger.error(\n                \"[BUG] adapter_type is 'lokr' but lycoris_net is None -- \"\n                \"cannot save LoKR weights.  This indicates a configuration or \"\n                \"injection error.  Refusing to silently save as LoRA.\"\n            )\n            raise RuntimeError(\n                \"LoKR adapter type was requested but no LyCORIS network is \"\n                \"attached to the training module.  Cannot save weights.\"\n            )\n        lokr_meta = {\"lokr_config\": module.adapter_config.to_dict()}\n        save_lokr_weights(module.lycoris_net, output_dir, metadata=lokr_meta)\n    else:\n        # Access the decoder directly (PeftModel after LoRA injection,\n        # possibly wrapped by Fabric's _FabricModule after setup).\n        # Do NOT use _unwrap_decoder here -- that function strips the PEFT\n        # wrapper and returns the base DiT model, causing save_pretrained()\n        # to write the full model instead of the adapter-only files.\n        raw_decoder = module.model.decoder\n        # Strip Fabric wrappers only (_forward_module chain).\n        while hasattr(raw_decoder, \"_forward_module\"):\n            raw_decoder = raw_decoder._forward_module\n        if hasattr(raw_decoder, \"save_pretrained\"):\n            raw_decoder.save_pretrained(output_dir)\n            logger.info(\"[OK] LoRA adapter saved to %s\", output_dir)\n        else:\n            # Fallback for non-PEFT models\n            save_lora_weights(module.model, output_dir)\n\n\ndef save_checkpoint(\n    trainer: Any,\n    optimizer: Any,\n    scheduler: Any,\n    epoch: int,\n    global_step: int,\n    ckpt_dir: str,\n) -> None:\n    \"\"\"Save a resumable checkpoint that is also inference-ready.\n\n    Adapter files (``adapter_config.json``, ``adapter_model.safetensors``)\n    are saved flat in *ckpt_dir* (same layout as ``save_final``), so\n    users can point inference tools directly at any checkpoint.\n    ``training_state.pt`` is saved alongside for resume support.\n    \"\"\"\n    save_adapter_flat(trainer, ckpt_dir)\n\n    # Save optimizer / scheduler / progress for resume\n    training_state = {\n        \"epoch\": epoch,\n        \"global_step\": global_step,\n        \"optimizer_state_dict\": optimizer.state_dict(),\n        \"scheduler_state_dict\": scheduler.state_dict(),\n    }\n    state_path = os.path.join(ckpt_dir, \"training_state.pt\")\n    torch.save(training_state, state_path)\n\n    # Also write a safetensors file with epoch/global_step so that\n    # load_training_checkpoint (which reads .safetensors) can restore\n    # training progress metadata.\n    try:\n        from safetensors.torch import save_file as _save_safetensors\n\n        meta_tensors = {\n            \"epoch\": torch.tensor([epoch], dtype=torch.int64),\n            \"global_step\": torch.tensor([global_step], dtype=torch.int64),\n        }\n        sf_path = os.path.join(ckpt_dir, \"training_state.safetensors\")\n        _save_safetensors(meta_tensors, sf_path)\n    except Exception as exc:\n        logger.debug(\"Could not write training_state.safetensors: %s\", exc)\n\n    logger.info(\n        \"Training checkpoint saved to %s (epoch %d, step %d)\",\n        ckpt_dir,\n        epoch,\n        global_step,\n    )\n\n\ndef save_final(trainer: Any, output_dir: str) -> None:\n    \"\"\"Save final adapter weights (inference-ready, no training state).\"\"\"\n    save_adapter_flat(trainer, output_dir)\n    verify_saved_adapter(output_dir)\n\n\ndef verify_saved_adapter(output_dir: str) -> None:\n    \"\"\"Check saved adapter weights exist and are non-trivial.\n\n    Loads the safetensors file, counts non-zero parameters, and logs\n    a warning if the weights appear to be all zeros (which would mean\n    the LoRA has no effect during inference).\n    \"\"\"\n    safetensors_path = os.path.join(output_dir, \"adapter_model.safetensors\")\n    config_path = os.path.join(output_dir, \"adapter_config.json\")\n\n    # LoKR uses a different file name\n    if not os.path.exists(safetensors_path):\n        lokr_path = os.path.join(output_dir, \"lokr_weights.safetensors\")\n        if os.path.exists(lokr_path):\n            logger.info(\"[OK] LoKR weights saved: %s\", lokr_path)\n            return\n        logger.warning(\n            \"[WARN] No adapter weights found in %s -- check save path\",\n            output_dir,\n        )\n        return\n\n    try:\n        from safetensors.torch import load_file\n\n        weights = load_file(safetensors_path)\n        total_params = 0\n        nonzero_params = 0\n        max_abs = 0.0\n        with torch.no_grad():\n            for tensor in weights.values():\n                total_params += tensor.numel()\n                nonzero_params += int((tensor != 0).sum().item())\n                max_abs = max(max_abs, tensor.abs().max().item())\n\n        if nonzero_params == 0:\n            logger.warning(\n                \"[WARN] All saved LoRA weights are ZERO -- \"\n                \"the adapter will have no effect during inference. \"\n                \"Training may not have converged.\"\n            )\n        else:\n            pct = 100.0 * nonzero_params / max(total_params, 1)\n            logger.info(\n                \"[OK] Adapter verified: %s params, %s non-zero (%.1f%%), max|w|=%.6f\",\n                f\"{total_params:,}\",\n                f\"{nonzero_params:,}\",\n                pct,\n                max_abs,\n            )\n\n        if not os.path.exists(config_path):\n            logger.warning(\n                \"[WARN] adapter_config.json missing in %s -- \"\n                \"inference tools will not be able to load this adapter\",\n                output_dir,\n            )\n    except Exception as exc:\n        logger.warning(\"[WARN] Could not verify adapter: %s\", exc)\n\n\ndef resume_checkpoint(\n    trainer: Any,\n    resume_path: str,\n    optimizer: Any,\n    scheduler: Any,\n) -> Generator[TrainingUpdate, None, Optional[Tuple[int, int]]]:\n    \"\"\"Resume from a checkpoint directory. Returns (start_epoch, global_step) or None.\"\"\"\n    module = trainer.module\n    assert module is not None\n    ckpt_dir = Path(resume_path)\n\n    # Normalize: if user pointed to a file inside the checkpoint dir,\n    # use the containing directory instead.\n    if ckpt_dir.is_file():\n        logger.info(\n            \"resume_from points to a file (%s) -- using parent directory %s\",\n            ckpt_dir.name,\n            ckpt_dir.parent,\n        )\n        ckpt_dir = ckpt_dir.parent\n\n    # -- Detect format: LoKR uses lokr_weights.safetensors ---------------\n    lokr_weights_path = ckpt_dir / \"lokr_weights.safetensors\"\n    state_path = ckpt_dir / \"training_state.pt\"\n\n    if lokr_weights_path.exists() and module.lycoris_net is not None:\n        # LoKR resume\n        if trainer.adapter_type != \"lokr\":\n            logger.warning(\n                \"[WARN] Found lokr_weights.safetensors but adapter_type is '%s' \"\n                \"-- loading as LoKR anyway\",\n                trainer.adapter_type,\n            )\n        load_lokr_weights(module.lycoris_net, str(lokr_weights_path))\n        if state_path.exists():\n            state = torch.load(\n                str(state_path), map_location=module.device, weights_only=False\n            )\n            epoch = state.get(\"epoch\", 0)\n            step = state.get(\"global_step\", 0)\n            if \"optimizer_state_dict\" in state:\n                optimizer.load_state_dict(state[\"optimizer_state_dict\"])\n            if \"scheduler_state_dict\" in state:\n                scheduler.load_state_dict(state[\"scheduler_state_dict\"])\n            yield TrainingUpdate(\n                0,\n                0.0,\n                f\"[OK] Resumed LoKR from epoch {epoch}, step {step}\",\n                kind=\"info\",\n            )\n            return (epoch, step)\n        yield TrainingUpdate(\n            0, 0.0, \"[OK] LoKR weights loaded (no training state)\", kind=\"info\"\n        )\n        return None\n\n    # Warn if LoKR was expected but checkpoint is LoRA-format\n    if trainer.adapter_type == \"lokr\":\n        if not lokr_weights_path.exists():\n            logger.warning(\n                \"[WARN] adapter_type is 'lokr' but no lokr_weights.safetensors \"\n                \"found in %s -- falling back to LoRA resume format\",\n                resume_path,\n            )\n        elif module.lycoris_net is None:\n            logger.warning(\n                \"[WARN] adapter_type is 'lokr' and lokr_weights.safetensors exists \"\n                \"but lycoris_net is None -- cannot load LoKR checkpoint\",\n            )\n\n    # LoRA resume (original logic)\n    ckpt_info = load_training_checkpoint(\n        str(ckpt_dir),\n        optimizer=optimizer,\n        scheduler=scheduler,\n        device=module.device,\n    )\n    if ckpt_info[\"adapter_path\"]:\n        adapter_path = ckpt_info[\"adapter_path\"]\n        aw_path = os.path.join(adapter_path, \"adapter_model.safetensors\")\n        if not os.path.exists(aw_path):\n            aw_path = os.path.join(adapter_path, \"adapter_model.bin\")\n\n        if os.path.exists(aw_path):\n            from safetensors.torch import load_file\n\n            state_dict = (\n                load_file(aw_path)\n                if aw_path.endswith(\".safetensors\")\n                else torch.load(aw_path, map_location=module.device, weights_only=True)\n            )\n            decoder = module.model.decoder\n            if hasattr(decoder, \"_forward_module\"):\n                decoder = decoder._forward_module\n            decoder.load_state_dict(state_dict, strict=False)\n\n            start_epoch = ckpt_info[\"epoch\"]\n            g_step = ckpt_info[\"global_step\"]\n            parts = [f\"[OK] Resumed from epoch {start_epoch}, step {g_step}\"]\n            if ckpt_info[\"loaded_optimizer\"]:\n                parts.append(\"optimizer OK\")\n            if ckpt_info[\"loaded_scheduler\"]:\n                parts.append(\"scheduler OK\")\n            yield TrainingUpdate(0, 0.0, \", \".join(parts), kind=\"info\")\n            return (start_epoch, g_step)\n        yield TrainingUpdate(\n            0, 0.0, f\"[WARN] Adapter weights not found in {adapter_path}\", kind=\"warn\"\n        )\n        return None\n    yield TrainingUpdate(\n        0, 0.0, f\"[WARN] No valid checkpoint in {ckpt_dir}\", kind=\"warn\"\n    )\n    return None\n"
  },
  {
    "path": "acestep/training_v2/trainer_helpers_test.py",
    "content": "\"\"\"Unit tests for acestep.training_v2.trainer_helpers.save_adapter_flat.\n\nThese tests use only stdlib and unittest.mock so that torch is not required.\nThe save_adapter_flat function only needs attribute-level duck-typing, so\nplain MagicMock objects work as stand-ins for nn.Module subclasses.\n\"\"\"\n\nimport unittest\nfrom unittest.mock import MagicMock, patch\n\n\ndef _make_fabric_wrapper(inner: MagicMock) -> MagicMock:\n    \"\"\"Return a mock that looks like a Fabric _FabricModule wrapping *inner*.\"\"\"\n    wrapper = MagicMock(spec_set=[\"_forward_module\"])\n    wrapper._forward_module = inner\n    return wrapper\n\n\ndef _make_peft_decoder() -> MagicMock:\n    \"\"\"Return a mock that looks like a PEFT PeftModel-wrapped decoder.\"\"\"\n    decoder = MagicMock(spec=[\"save_pretrained\"])\n    return decoder\n\n\ndef _make_base_decoder() -> MagicMock:\n    \"\"\"Return a mock with no save_pretrained (raw non-PEFT decoder fallback).\"\"\"\n    return MagicMock(spec=[])  # no save_pretrained attribute\n\n\ndef _make_full_model(decoder: MagicMock) -> MagicMock:\n    \"\"\"Return a mock that looks like AceStepConditionGenerationModel.\n\n    The full model also has save_pretrained (inherits from HF PreTrainedModel)\n    -- that method must NOT be invoked; only the decoder's save_pretrained\n    should be called.\n    \"\"\"\n    model = MagicMock(spec=[\"decoder\", \"save_pretrained\"])\n    model.decoder = decoder\n    model.save_pretrained = MagicMock()\n    return model\n\n\ndef _make_trainer(decoder: MagicMock, adapter_type: str = \"lora\") -> MagicMock:\n    \"\"\"Build a minimal trainer mock with the given decoder embedded.\"\"\"\n    full_model = _make_full_model(decoder)\n    module = MagicMock()\n    module.model = full_model\n    trainer = MagicMock()\n    trainer.adapter_type = adapter_type\n    trainer.module = module\n    return trainer\n\n\nclass TestSaveAdapterFlatLora(unittest.TestCase):\n    \"\"\"save_adapter_flat must write adapter files (not the full model) for LoRA.\"\"\"\n\n    def test_calls_save_pretrained_on_peft_decoder_not_full_model(self):\n        \"\"\"save_pretrained() must be called on the PeftModel decoder, not the full model.\"\"\"\n        peft_decoder = _make_peft_decoder()\n        trainer = _make_trainer(peft_decoder)\n\n        from acestep.training_v2.trainer_helpers import save_adapter_flat\n\n        with patch(\"os.makedirs\"):\n            save_adapter_flat(trainer, \"/tmp/out\")\n\n        # The PeftModel's save_pretrained must have been invoked.\n        peft_decoder.save_pretrained.assert_called_once_with(\"/tmp/out\")\n        # The full model's save_pretrained must NOT have been called.\n        trainer.module.model.save_pretrained.assert_not_called()\n\n    def test_unwraps_fabric_wrapper_before_saving(self):\n        \"\"\"When Fabric wraps the decoder, save_pretrained is still called on the PeftModel.\"\"\"\n        peft_decoder = _make_peft_decoder()\n        fabric_wrapped = _make_fabric_wrapper(peft_decoder)\n        trainer = _make_trainer(fabric_wrapped)\n\n        from acestep.training_v2.trainer_helpers import save_adapter_flat\n\n        with patch(\"os.makedirs\"):\n            save_adapter_flat(trainer, \"/tmp/out\")\n\n        peft_decoder.save_pretrained.assert_called_once_with(\"/tmp/out\")\n        trainer.module.model.save_pretrained.assert_not_called()\n\n    def test_doubly_wrapped_fabric_still_reaches_peft_decoder(self):\n        \"\"\"Handles two layers of Fabric _FabricModule wrapping.\"\"\"\n        peft_decoder = _make_peft_decoder()\n        fabric_inner = _make_fabric_wrapper(peft_decoder)\n        fabric_outer = _make_fabric_wrapper(fabric_inner)\n        trainer = _make_trainer(fabric_outer)\n\n        from acestep.training_v2.trainer_helpers import save_adapter_flat\n\n        with patch(\"os.makedirs\"):\n            save_adapter_flat(trainer, \"/tmp/out\")\n\n        peft_decoder.save_pretrained.assert_called_once_with(\"/tmp/out\")\n\n    def test_fallback_to_save_lora_weights_when_no_save_pretrained(self):\n        \"\"\"If the decoder has no save_pretrained, save_lora_weights is used as fallback.\"\"\"\n        raw_decoder = _make_base_decoder()\n        trainer = _make_trainer(raw_decoder)\n\n        from acestep.training_v2.trainer_helpers import save_adapter_flat\n\n        with (\n            patch(\"os.makedirs\"),\n            patch(\n                \"acestep.training_v2.trainer_helpers.save_lora_weights\"\n            ) as mock_slw,\n        ):\n            save_adapter_flat(trainer, \"/tmp/out\")\n\n        mock_slw.assert_called_once_with(trainer.module.model, \"/tmp/out\")\n\n    def test_regression_full_model_save_pretrained_not_called_for_lora(self):\n        \"\"\"Regression: the full AceStep model's save_pretrained must never be called.\n\n        Previously, _unwrap_decoder(module.model) returned the full\n        AceStepConditionGenerationModel (which also has save_pretrained), causing\n        model.safetensors + config.json to be written instead of adapter files.\n        \"\"\"\n        peft_decoder = _make_peft_decoder()\n        trainer = _make_trainer(peft_decoder)\n\n        from acestep.training_v2.trainer_helpers import save_adapter_flat\n\n        with patch(\"os.makedirs\"):\n            save_adapter_flat(trainer, \"/tmp/out\")\n\n        # Critically, the full model's save_pretrained must not have been called.\n        trainer.module.model.save_pretrained.assert_not_called()\n\n\nif __name__ == \"__main__\":\n    unittest.main()\n"
  },
  {
    "path": "acestep/training_v2/trainer_vanilla.py",
    "content": "\"\"\"\nVanillaTrainer -- Thin adapter wrapping the original LoRATrainer for TUI use.\n\nThe original ``acestep/training/trainer.py`` ``LoRATrainer`` requires a\n``dit_handler`` shim.  This module provides a ``VanillaTrainer`` class with\nthe same interface as ``FixedTrainer`` so both can be used interchangeably\nfrom the TUI training monitor.\n\"\"\"\n\nfrom __future__ import annotations\n\nimport logging\nimport sys\nfrom pathlib import Path\nfrom typing import Any, Callable, Dict, Generator, Optional, Tuple\n\nimport torch\n\ntry:\n    from acestep.training.configs import LoRAConfig, TrainingConfig\n    from acestep.training.trainer import LoRATrainer\n    _VANILLA_AVAILABLE = True\nexcept ImportError:\n    _VANILLA_AVAILABLE = False\n\n    # Stub definitions so the module can be imported for type-checking\n    # even when the real package is missing (avoids a second ImportError).\n    from dataclasses import dataclass as _dataclass\n\n    @_dataclass\n    class LoRAConfig:  # type: ignore[no-redef]\n        \"\"\"Stub for ``acestep.training.configs.LoRAConfig``.\"\"\"\n        r: int = 64\n        alpha: int = 128\n        dropout: float = 0.0\n        target_modules: list = None  # type: ignore[assignment]\n        bias: str = \"none\"\n\n    @_dataclass\n    class TrainingConfig:  # type: ignore[no-redef]\n        \"\"\"Stub for ``acestep.training.configs.TrainingConfig``.\"\"\"\n        learning_rate: float = 1e-4\n        batch_size: int = 1\n        gradient_accumulation_steps: int = 4\n        max_epochs: int = 100\n        warmup_steps: int = 500\n        weight_decay: float = 0.01\n        max_grad_norm: float = 1.0\n        seed: int = 42\n        output_dir: str = \"./lora_output\"\n        save_every_n_epochs: int = 10\n        num_workers: int = 0\n        pin_memory: bool = True\n\n    LoRATrainer = None  # type: ignore[assignment,misc]\nfrom acestep.training_v2.model_loader import load_decoder_for_training\n\nlogger = logging.getLogger(__name__)\n\n\nclass _HandlerShim:\n    \"\"\"Minimal shim satisfying the ``LoRATrainer`` constructor.\n\n    Wraps a decoder model, device string, and dtype so that the upstream\n    ``LoRATrainer`` receives the interface it expects from a full\n    ``dit_handler``.\n\n    Args:\n        model: The decoder ``torch.nn.Module`` to train.\n        device: Target device string (e.g. ``\"cuda\"``, ``\"cpu\"``).\n        dtype: Torch dtype for mixed-precision (e.g. ``torch.bfloat16``).\n    \"\"\"\n\n    def __init__(self, model: torch.nn.Module, device: str, dtype: torch.dtype) -> None:\n        self.model = model\n        self.device = device\n        self.dtype = dtype\n        self.quantization = None\n\n\nclass VanillaTrainer:\n    \"\"\"Adapter that wraps the upstream ``LoRATrainer`` to match FixedTrainer's interface.\n\n    Args:\n        lora_config: LoRA hyper-parameters (rank, alpha, dropout, targets).\n        training_config: Training hyper-parameters (LR, epochs, batch size, ...).\n        progress_callback: Optional callable invoked after each upstream\n            training update.  Signature:\n            ``(epoch: int, step: int, loss: float, lr: float, is_epoch_end: bool) -> Optional[bool]``.\n            Return ``False`` to request early stopping.\n\n    Attributes:\n        lora_config: Stored LoRA configuration.\n        training_config: Stored training configuration.\n        progress_callback: Stored callback (may be ``None``).\n    \"\"\"\n\n    def __init__(\n        self,\n        lora_config: Any,\n        training_config: Any,\n        progress_callback: Optional[Callable[..., Optional[bool]]] = None,\n    ) -> None:\n        self.lora_config = lora_config\n        self.training_config = training_config\n        self.progress_callback = progress_callback\n\n    # -- Private helpers ---------------------------------------------------\n\n    def _build_configs(self) -> Tuple[LoRAConfig, TrainingConfig, int]:\n        \"\"\"Map V2 config objects to base ``LoRAConfig`` / ``TrainingConfig``.\n\n        Returns:\n            A tuple of ``(lora_cfg, train_cfg, num_workers)`` where\n            *num_workers* is clamped to 0 on Windows.\n        \"\"\"\n        cfg = self.training_config\n\n        lora_cfg = LoRAConfig(\n            r=getattr(self.lora_config, \"rank\", 64),\n            alpha=getattr(self.lora_config, \"alpha\", 128),\n            dropout=getattr(self.lora_config, \"dropout\", 0.0),\n            target_modules=getattr(self.lora_config, \"target_modules\", [\"to_q\", \"to_k\", \"to_v\", \"to_out.0\"]),\n            bias=getattr(self.lora_config, \"bias\", \"none\"),\n        )\n\n        # Windows uses spawn-based multiprocessing which breaks DataLoader workers\n        num_workers = getattr(cfg, \"num_workers\", 4)\n        if sys.platform == \"win32\" and num_workers > 0:\n            logger.info(\"[Side-Step] Windows detected -- setting num_workers=0 (spawn incompatible)\")\n            num_workers = 0\n\n        train_cfg = TrainingConfig(\n            learning_rate=getattr(cfg, \"learning_rate\", 1e-4),\n            batch_size=getattr(cfg, \"batch_size\", 1),\n            gradient_accumulation_steps=getattr(cfg, \"gradient_accumulation_steps\", 4),\n            max_epochs=getattr(cfg, \"max_epochs\", getattr(cfg, \"epochs\", 100)),\n            warmup_steps=getattr(cfg, \"warmup_steps\", 500),\n            weight_decay=getattr(cfg, \"weight_decay\", 0.01),\n            max_grad_norm=getattr(cfg, \"max_grad_norm\", 1.0),\n            seed=getattr(cfg, \"seed\", 42),\n            output_dir=getattr(cfg, \"output_dir\", \"./lora_output\"),\n            save_every_n_epochs=getattr(cfg, \"save_every_n_epochs\", 10),\n            num_workers=num_workers,\n            pin_memory=getattr(cfg, \"pin_memory\", True),\n        )\n\n        return lora_cfg, train_cfg, num_workers\n\n    @staticmethod\n    def _setup_device_and_model(\n        cfg: Any,\n    ) -> Tuple[Any, torch.dtype, torch.nn.Module]:\n        \"\"\"Auto-detect GPU and load the decoder model.\n\n        Returns:\n            A tuple of ``(gpu_info, dtype, model)``.\n        \"\"\"\n        from acestep.training_v2.gpu_utils import detect_gpu\n\n        gpu = detect_gpu(\n            requested_device=getattr(cfg, \"device\", \"auto\"),\n            requested_precision=getattr(cfg, \"precision\", \"auto\"),\n        )\n        dtype_map = {\"bf16\": torch.bfloat16, \"fp16\": torch.float16, \"fp32\": torch.float32}\n        dtype = dtype_map.get(gpu.precision, torch.bfloat16)\n\n        model = load_decoder_for_training(\n            checkpoint_dir=getattr(cfg, \"checkpoint_dir\", \"./checkpoints\"),\n            variant=getattr(cfg, \"model_variant\", getattr(cfg, \"variant\", \"turbo\")),\n            device=gpu.device,\n            precision=gpu.precision,\n        )\n\n        return gpu, dtype, model\n\n    @staticmethod\n    def _run_training(\n        model: torch.nn.Module,\n        gpu: Any,\n        dtype: torch.dtype,\n        lora_cfg: LoRAConfig,\n        train_cfg: TrainingConfig,\n        cfg: Any,\n    ) -> Generator:\n        \"\"\"Construct handler + LoRATrainer and yield training updates.\n\n        Yields:\n            Tuples from the upstream ``LoRATrainer.train_from_preprocessed``.\n        \"\"\"\n        handler = _HandlerShim(model=model, device=gpu.device, dtype=dtype)\n        trainer = LoRATrainer(handler, lora_cfg, train_cfg)\n        dataset_dir = getattr(cfg, \"dataset_dir\", \"\")\n        resume_from = getattr(cfg, \"resume_from\", None)\n\n        yield from trainer.train_from_preprocessed(\n            tensor_dir=dataset_dir,\n            resume_from=resume_from,\n        )\n\n    # -- Public API --------------------------------------------------------\n\n    def train(self) -> None:\n        \"\"\"Run vanilla training, calling *progress_callback* for each update.\n\n        Raises:\n            RuntimeError: If base ACE-Step is not installed.\n        \"\"\"\n        if not _VANILLA_AVAILABLE:\n            raise RuntimeError(\n                \"Vanilla training requires a full ACE-Step 1.5 installation.\\n\"\n                \"Install it with:  pip install -e /path/to/ACE-Step-1.5\\n\"\n                \"Or use the 'Corrected (fixed)' training mode which is standalone.\"\n            )\n        cfg = self.training_config\n\n        lora_cfg, train_cfg, _num_workers = self._build_configs()\n        gpu, dtype, model = self._setup_device_and_model(cfg)\n\n        for update in self._run_training(model, gpu, dtype, lora_cfg, train_cfg, cfg):\n            if self.progress_callback:\n                # Upstream yields (step, loss, msg) tuples\n                step, loss, _msg = update if len(update) == 3 else (update[0], update[1], \"\")\n                should_continue = self.progress_callback(\n                    epoch=0, step=step, loss=loss, lr=0.0, is_epoch_end=False,\n                )\n                if should_continue is False:\n                    break\n"
  },
  {
    "path": "acestep/training_v2/ui/__init__.py",
    "content": "\"\"\"\nACE-Step Training V2 -- Rich UI Layer\n\nProvides a shared ``Console`` instance and a ``RICH_AVAILABLE`` flag so that\nevery UI module can degrade gracefully when Rich is not installed.\n\nExports\n-------\nconsole : Console | None\n    Shared Rich console (``None`` when Rich is missing).\nRICH_AVAILABLE : bool\n    ``True`` when ``rich>=13`` is importable.\nplain_mode : bool\n    Module-level flag toggled by ``--plain``.  When ``True`` *or* stdout is\n    not a TTY, all UI helpers fall back to plain ``print()`` output.\n\"\"\"\n\nfrom __future__ import annotations\n\nimport sys\nfrom dataclasses import dataclass\nfrom typing import Iterator, Tuple\n\n# ---- Rich availability check ------------------------------------------------\n\nRICH_AVAILABLE: bool = False\nconsole = None  # type: ignore[assignment]\n\ntry:\n    from rich.console import Console as _Console\n\n    console = _Console(stderr=True)  # UI goes to stderr so stdout stays clean\n    RICH_AVAILABLE = True\nexcept ImportError:\n    pass\n\n# ---- Plain-mode flag (set via --plain CLI arg) ------------------------------\n\nplain_mode: bool = False\n\n\ndef set_plain_mode(value: bool) -> None:\n    \"\"\"Toggle plain-text output globally.\"\"\"\n    global plain_mode\n    plain_mode = value\n\n\ndef is_rich_active() -> bool:\n    \"\"\"Return True when Rich output should be used.\"\"\"\n    if plain_mode or not RICH_AVAILABLE:\n        return False\n    if console is not None and not console.is_terminal:\n        return False\n    return True\n\n\ndef require_rich() -> None:\n    \"\"\"Print an install hint and exit if Rich is missing.\"\"\"\n    if RICH_AVAILABLE:\n        return\n    print(\n        \"[FAIL] Rich is required for the pretty CLI.\\n\"\n        \"       Install it with:  pip install rich\\n\"\n        \"       Or use --plain for basic text output.\",\n        file=sys.stderr,\n    )\n    sys.exit(1)\n\n\n# ---- TrainingUpdate (backward-compatible structured yield) ------------------\n\n@dataclass\nclass TrainingUpdate:\n    \"\"\"Structured object yielded by the trainer, backward-compatible with\n    ``(step, loss, msg)`` tuple unpacking.\n\n    Extra fields give the UI enough context to render a live dashboard\n    without parsing message strings.\n    \"\"\"\n\n    step: int\n    loss: float\n    msg: str\n    kind: str = \"info\"\n    \"\"\"One of: info, step, epoch, checkpoint, complete, warn, fail.\"\"\"\n    epoch: int = 0\n    max_epochs: int = 0\n    lr: float = 0.0\n    epoch_time: float = 0.0\n    samples_per_sec: float = 0.0\n    steps_per_epoch: int = 0\n    \"\"\"Total optimizer steps per epoch (for step-level progress bar).\"\"\"\n    checkpoint_path: str = \"\"\n    \"\"\"Filesystem path emitted with kind='checkpoint'.\"\"\"\n\n    # -- backward compat: ``for step, loss, msg in trainer.train():`` --------\n    def __iter__(self) -> Iterator[Tuple[int, float, str]]:  # type: ignore[override]\n        return iter((self.step, self.loss, self.msg))\n"
  },
  {
    "path": "acestep/training_v2/ui/banner.py",
    "content": "\"\"\"\nStartup banner for Side-Step CLI.\n\nShows a branded header with a random motto (Minecraft-style splash),\nsubcommand, framework versions, and GPU info.\n\"\"\"\n\nfrom __future__ import annotations\n\nimport random\nimport shutil\nimport sys\nimport textwrap\nfrom typing import Optional\n\nfrom acestep.training_v2.ui import console, is_rich_active\n\n# ---- ASCII logos (wide BlurVision + narrow fallback) -------------------------\n\n# Multi-line BlurVision gradient-block art (Unicode shade characters)\n_LOGO_WIDE_LINES = [\n    \" \\u2591\\u2592\\u2593\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2593\\u2592\\u2591\\u2592\\u2593\\u2588\\u2593\\u2592\\u2591\\u2592\\u2593\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2593\\u2592\\u2591\\u2591\\u2592\\u2593\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2593\\u2592\\u2591\\u2591\\u2592\\u2593\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2593\\u2592\\u2591\\u2592\\u2593\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2593\\u2592\\u2591\\u2592\\u2593\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2593\\u2592\\u2591\\u2592\\u2593\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2593\\u2592\\u2591\",\n    \"\\u2591\\u2592\\u2593\\u2588\\u2593\\u2592\\u2591      \\u2591\\u2592\\u2593\\u2588\\u2593\\u2592\\u2591\\u2592\\u2593\\u2588\\u2593\\u2592\\u2591\\u2591\\u2592\\u2593\\u2588\\u2593\\u2592\\u2591\\u2592\\u2593\\u2588\\u2593\\u2592\\u2591      \\u2591\\u2592\\u2593\\u2588\\u2593\\u2592\\u2591         \\u2591\\u2592\\u2593\\u2588\\u2593\\u2592\\u2591   \\u2591\\u2592\\u2593\\u2588\\u2593\\u2592\\u2591      \\u2591\\u2592\\u2593\\u2588\\u2593\\u2592\\u2591\\u2591\\u2592\\u2593\\u2588\\u2593\\u2592\\u2591\",\n    \"\\u2591\\u2592\\u2593\\u2588\\u2593\\u2592\\u2591      \\u2591\\u2592\\u2593\\u2588\\u2593\\u2592\\u2591\\u2592\\u2593\\u2588\\u2593\\u2592\\u2591\\u2591\\u2592\\u2593\\u2588\\u2593\\u2592\\u2591\\u2592\\u2593\\u2588\\u2593\\u2592\\u2591      \\u2591\\u2592\\u2593\\u2588\\u2593\\u2592\\u2591         \\u2591\\u2592\\u2593\\u2588\\u2593\\u2592\\u2591   \\u2591\\u2592\\u2593\\u2588\\u2593\\u2592\\u2591      \\u2591\\u2592\\u2593\\u2588\\u2593\\u2592\\u2591\\u2591\\u2592\\u2593\\u2588\\u2593\\u2592\\u2591\",\n    \" \\u2591\\u2592\\u2593\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2593\\u2592\\u2591\\u2591\\u2592\\u2593\\u2588\\u2593\\u2592\\u2591\\u2592\\u2593\\u2588\\u2593\\u2592\\u2591\\u2591\\u2592\\u2593\\u2588\\u2593\\u2592\\u2591\\u2592\\u2593\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2593\\u2592\\u2591  \\u2591\\u2592\\u2593\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2593\\u2592\\u2591   \\u2591\\u2592\\u2593\\u2588\\u2593\\u2592\\u2591   \\u2591\\u2592\\u2593\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2593\\u2592\\u2591 \\u2591\\u2592\\u2593\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2593\\u2592\\u2591\",\n    \"       \\u2591\\u2592\\u2593\\u2588\\u2593\\u2592\\u2591\\u2592\\u2593\\u2588\\u2593\\u2592\\u2591\\u2592\\u2593\\u2588\\u2593\\u2592\\u2591\\u2591\\u2592\\u2593\\u2588\\u2593\\u2592\\u2591\\u2592\\u2593\\u2588\\u2593\\u2592\\u2591             \\u2591\\u2592\\u2593\\u2588\\u2593\\u2592\\u2591  \\u2591\\u2592\\u2593\\u2588\\u2593\\u2592\\u2591   \\u2591\\u2592\\u2593\\u2588\\u2593\\u2592\\u2591      \\u2591\\u2592\\u2593\\u2588\\u2593\\u2592\\u2591\",\n    \"       \\u2591\\u2592\\u2593\\u2588\\u2593\\u2592\\u2591\\u2592\\u2593\\u2588\\u2593\\u2592\\u2591\\u2592\\u2593\\u2588\\u2593\\u2592\\u2591\\u2591\\u2592\\u2593\\u2588\\u2593\\u2592\\u2591\\u2592\\u2593\\u2588\\u2593\\u2592\\u2591             \\u2591\\u2592\\u2593\\u2588\\u2593\\u2592\\u2591  \\u2591\\u2592\\u2593\\u2588\\u2593\\u2592\\u2591   \\u2591\\u2592\\u2593\\u2588\\u2593\\u2592\\u2591      \\u2591\\u2592\\u2593\\u2588\\u2593\\u2592\\u2591\",\n    \"\\u2591\\u2592\\u2593\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2593\\u2592\\u2591\\u2591\\u2592\\u2593\\u2588\\u2593\\u2592\\u2591\\u2592\\u2593\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2593\\u2592\\u2591\\u2591\\u2592\\u2593\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2593\\u2592\\u2591\\u2592\\u2593\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2593\\u2592\\u2591   \\u2591\\u2592\\u2593\\u2588\\u2593\\u2592\\u2591   \\u2591\\u2592\\u2593\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2593\\u2592\\u2591\\u2592\\u2593\\u2588\\u2593\\u2592\\u2591\",\n]\n\n_LOGO_NARROW = textwrap.dedent(r\"\"\"\n  ███████ ██ ██████  ███████\n  ██      ██ ██   ██ ██\n  ███████ ██ ██   ██ █████\n       ██ ██ ██   ██ ██\n  ███████ ██ ██████  ███████\n\n  ███████ ████████ ███████ ██████\n  ██         ██    ██      ██   ██\n  ███████    ██    █████   ██████\n       ██    ██    ██      ██\n  ███████    ██    ███████ ██\n\"\"\").strip()\n\n_LOGO_MIN_WIDTH = 98  # Minimum terminal width for the wide BlurVision logo\n\n\ndef _pick_logo() -> str:\n    \"\"\"Return the best logo for the current terminal width.\"\"\"\n    try:\n        width = shutil.get_terminal_size((120, 24)).columns\n    except Exception:\n        width = 120\n    if width >= _LOGO_MIN_WIDTH:\n        return \"\\n\".join(_LOGO_WIDE_LINES)\n    return _LOGO_NARROW\n\n# ---- Splash mottos (randomly picked each launch) ----------------------------\n\n_MOTTOS = [\n    \"Because Gradio is the spawn of Satan.\",\n    \"Sidestepping the spaghetti code.\",\n    \"Bypassing the BS, one epoch at a time.\",\n    \"Research grade? No. dernet grade.\",\n    \"Nimrod-tested. Blackwell-approved.\",\n    \"The 5-Euro Heist.\",\n    \"Je suis calibré.\",\n    \"Born in the VRAM trenches.\",\n    \"323k tokens later, we have a snare.\",\n    \"Designed by a Producer. Debugged by a Nimrod.\",\n    \"Because Gradio is the spawn of Satan.\",\n    \"Talk to an LLM for 10h? Hell yeah.\",\n    \"Side-Step: The 17-Hour Speedrun.\",\n    \"Red errors are just decoration.\",\n    \"Importing sanity... ModuleNotFoundError.\",\n    \"One variable, two names, zero documentation.\",\n    \"Because Gradio is the spawn of Satan.\",\n    \"Refactoring the Prometheus experience.\",\n    \"Surgical training for blunt-force code.\",\n    \"2,500 lines of 'Why?'\",\n    \"The browser tab is not the boss of me.\",\n    \"1.5 Terabytes of RAM and still no documentation.\",\n    \"The only way to debug a 2000-line error is to write a 2000-line error.\",\n]\n\n\ndef _pick_motto() -> str:\n    return random.choice(_MOTTOS)\n\n\ndef _get_versions() -> dict:\n    \"\"\"Collect framework version strings (best-effort).\"\"\"\n    info: dict = {}\n    try:\n        import torch\n        info[\"PyTorch\"] = torch.__version__\n        if torch.cuda.is_available():\n            info[\"CUDA\"] = torch.version.cuda or \"n/a\"\n    except ImportError:\n        info[\"PyTorch\"] = \"not installed\"\n    try:\n        info[\"Python\"] = f\"{sys.version_info.major}.{sys.version_info.minor}.{sys.version_info.micro}\"\n    except Exception:\n        pass\n    return info\n\n\ndef _get_gpu_line(device: str = \"\", precision: str = \"\") -> str:\n    \"\"\"One-liner for GPU name + VRAM.\"\"\"\n    try:\n        from acestep.training_v2.gpu_utils import detect_gpu\n        gpu = detect_gpu(requested_device=device or \"auto\", requested_precision=precision or \"auto\")\n        vram_part = \"\"\n        if gpu.vram_total_mb is not None:\n            vram_gb = gpu.vram_total_mb / 1024\n            vram_part = f\"  ({vram_gb:.1f} GiB)\"\n        return f\"{gpu.name}{vram_part}\"\n    except Exception:\n        return \"unknown\"\n\n\n# ---- Public API -------------------------------------------------------------\n\ndef show_banner(\n    subcommand: str,\n    device: str = \"\",\n    precision: str = \"\",\n    extra_lines: Optional[list] = None,\n) -> None:\n    \"\"\"Print the startup banner with a random motto.\"\"\"\n    versions = _get_versions()\n    gpu_line = _get_gpu_line(device, precision)\n    motto = _pick_motto()\n\n    ver_parts = []\n    if \"Python\" in versions:\n        ver_parts.append(f\"Python {versions['Python']}\")\n    if \"PyTorch\" in versions:\n        ver_parts.append(f\"PyTorch {versions['PyTorch']}\")\n    if \"CUDA\" in versions:\n        ver_parts.append(f\"CUDA {versions['CUDA']}\")\n    if precision:\n        ver_parts.append(precision)\n    ver_str = \" | \".join(ver_parts)\n\n    from acestep.training_v2 import __version__ as SIDESTEP_VERSION\n\n    _SUBCOMMAND_DESC = {\n        \"vanilla\": \"vanilla (original behaviour, bugged timesteps)\",\n        \"fixed\": \"fixed (corrected timesteps + CFG dropout)\",\n        \"estimate\": \"estimate (gradient sensitivity analysis)\",\n    }\n    sub_desc = _SUBCOMMAND_DESC.get(subcommand, subcommand)\n\n    if is_rich_active() and console is not None:\n        from rich.panel import Panel\n        from rich.text import Text\n\n        logo = _pick_logo()\n        body = Text()\n        body.append(logo + \"\\n\", style=\"bold cyan\")\n        body.append(f'  \"{motto}\"\\n\\n', style=\"italic yellow\")\n        body.append(f\"  Side-Step v{SIDESTEP_VERSION} -- Adapter Fine-Tuning CLI (LoRA + LoKR)\\n\", style=\"dim\")\n        body.append(\"  Standalone: github.com/koda-dernet/Side-Step\\n\\n\", style=\"dim italic\")\n        body.append(\"  Mode   : \", style=\"dim\")\n        body.append(f\"{sub_desc}\\n\", style=\"bold\")\n        body.append(\"  Stack  : \", style=\"dim\")\n        body.append(f\"{ver_str}\\n\", style=\"\")\n        body.append(\"  GPU    : \", style=\"dim\")\n        body.append(f\"{gpu_line}\\n\", style=\"\")\n\n        if extra_lines:\n            for line in extra_lines:\n                body.append(f\"  {line}\\n\", style=\"dim\")\n\n        console.print(Panel(body, border_style=\"cyan\", padding=(0, 1)))\n    else:\n        # Plain text fallback\n        print(_pick_logo(), file=sys.stderr)\n        print(f'  \"{motto}\"', file=sys.stderr)\n        print(f\"  Side-Step v{SIDESTEP_VERSION} -- Adapter Fine-Tuning CLI (LoRA + LoKR)\", file=sys.stderr)\n        print(\"  Standalone: github.com/koda-dernet/Side-Step\", file=sys.stderr)\n        print(f\"  Mode   : {sub_desc}\", file=sys.stderr)\n        print(f\"  Stack  : {ver_str}\", file=sys.stderr)\n        print(f\"  GPU    : {gpu_line}\", file=sys.stderr)\n        if extra_lines:\n            for line in extra_lines:\n                print(f\"  {line}\", file=sys.stderr)\n        print(file=sys.stderr)\n"
  },
  {
    "path": "acestep/training_v2/ui/config_panel.py",
    "content": "\"\"\"\nPre-training configuration display.\n\nRenders a grouped Rich Table of all training parameters, with non-default\nvalues highlighted so the user instantly sees what they changed.\n\nFalls back to aligned plain text when Rich is unavailable.\n\"\"\"\n\nfrom __future__ import annotations\n\nimport sys\nfrom dataclasses import fields\nfrom typing import Any, Dict, Optional\n\nfrom acestep.training_v2.configs import LoRAConfigV2, TrainingConfigV2\nfrom acestep.training_v2.ui import console, is_rich_active\nfrom acestep.training_v2.ui.prompt_helpers import _esc\n\n# ---- Default values (for highlighting non-default settings) -----------------\n\n# These mirror the argparse defaults in cli/common.py.\n_DEFAULTS: Dict[str, Any] = {\n    # Model\n    \"model_variant\": \"turbo\",\n    \"checkpoint_dir\": \"./checkpoints\",\n    # Device\n    \"device\": \"auto\",\n    \"precision\": \"auto\",\n    # Training\n    \"learning_rate\": 1e-4,\n    \"batch_size\": 1,\n    \"gradient_accumulation_steps\": 4,\n    \"max_epochs\": 100,\n    \"warmup_steps\": 100,\n    \"weight_decay\": 0.01,\n    \"max_grad_norm\": 1.0,\n    \"seed\": 42,\n    # LoRA\n    \"r\": 64,\n    \"alpha\": 128,\n    \"dropout\": 0.1,\n    \"target_modules\": [\"q_proj\", \"k_proj\", \"v_proj\", \"o_proj\"],\n    \"bias\": \"none\",\n    # Checkpointing\n    \"output_dir\": \"\",\n    \"save_every_n_epochs\": 10,\n    \"resume_from\": None,\n    # Logging\n    \"log_dir\": None,\n    \"log_every\": 10,\n    \"log_heavy_every\": 50,\n    # Corrected training\n    \"cfg_ratio\": 0.15,\n    \"timestep_mu\": -0.4,\n    \"timestep_sigma\": 1.0,\n    \"data_proportion\": 0.5,\n}\n\n# Logical grouping for display.\n_GROUPS = [\n    (\n        \"Model\",\n        [\n            (\"model_variant\", \"Model variant\"),\n            (\"checkpoint_dir\", \"Checkpoint dir\"),\n            (\"dataset_dir\", \"Dataset dir\"),\n        ],\n    ),\n    (\n        \"Device\",\n        [\n            (\"device\", \"Device\"),\n            (\"precision\", \"Precision\"),\n        ],\n    ),\n    (\n        \"LoRA\",\n        [\n            (\"r\", \"Rank (r)\"),\n            (\"alpha\", \"Alpha\"),\n            (\"dropout\", \"Dropout\"),\n            (\"target_modules\", \"Target modules\"),\n            (\"bias\", \"Bias\"),\n        ],\n    ),\n    (\n        \"Training\",\n        [\n            (\"learning_rate\", \"Learning rate\"),\n            (\"batch_size\", \"Batch size\"),\n            (\"gradient_accumulation_steps\", \"Grad accumulation\"),\n            (\"_effective_batch\", \"Effective batch\"),\n            (\"max_epochs\", \"Max epochs\"),\n            (\"warmup_steps\", \"Warmup steps\"),\n            (\"weight_decay\", \"Weight decay\"),\n            (\"max_grad_norm\", \"Max grad norm\"),\n            (\"seed\", \"Seed\"),\n        ],\n    ),\n    (\n        \"Corrected Training\",\n        [\n            (\"cfg_ratio\", \"CFG dropout ratio\"),\n            (\"timestep_mu\", \"Timestep mu\"),\n            (\"timestep_sigma\", \"Timestep sigma\"),\n            (\"data_proportion\", \"Data proportion\"),\n        ],\n    ),\n    (\n        \"Checkpointing\",\n        [\n            (\"output_dir\", \"Output dir\"),\n            (\"save_every_n_epochs\", \"Save every N epochs\"),\n            (\"resume_from\", \"Resume from\"),\n        ],\n    ),\n    (\n        \"Logging\",\n        [\n            (\"log_dir\", \"TensorBoard dir\"),\n            (\"log_every\", \"Log every N steps\"),\n            (\"log_heavy_every\", \"Grad norms every N steps\"),\n        ],\n    ),\n]\n\n\ndef _resolve_value(\n    key: str,\n    lora_cfg: LoRAConfigV2,\n    train_cfg: TrainingConfigV2,\n) -> Any:\n    \"\"\"Look up a config key from either config object.\"\"\"\n    if key == \"_effective_batch\":\n        return train_cfg.batch_size * train_cfg.gradient_accumulation_steps\n    # LoRA fields\n    for f in fields(lora_cfg):\n        if f.name == key:\n            return getattr(lora_cfg, key)\n    # Training fields\n    if hasattr(train_cfg, key):\n        return getattr(train_cfg, key)\n    return None\n\n\ndef _is_default(key: str, value: Any) -> bool:\n    \"\"\"Return True when *value* matches the known default for *key*.\"\"\"\n    if key not in _DEFAULTS:\n        return True  # unknown keys are not highlighted\n    default = _DEFAULTS[key]\n    if isinstance(default, list) and isinstance(value, list):\n        return default == value\n    return value == default\n\n\ndef _fmt_value(value: Any) -> str:\n    \"\"\"Format a config value for display.\"\"\"\n    if value is None:\n        return \"(auto)\"\n    if isinstance(value, list):\n        return \", \".join(str(v) for v in value)\n    if isinstance(value, float):\n        # Scientific notation for very small values\n        if 0 < abs(value) < 0.001:\n            return f\"{value:.1e}\"\n        return f\"{value:g}\"\n    return str(value)\n\n\n# ---- Public API -------------------------------------------------------------\n\ndef show_config(\n    lora_cfg: LoRAConfigV2,\n    train_cfg: TrainingConfigV2,\n    subcommand: str = \"fixed\",\n    skip_corrected: bool = False,\n) -> None:\n    \"\"\"Display the full configuration before training starts.\n\n    Args:\n        lora_cfg: LoRA configuration.\n        train_cfg: Training configuration.\n        subcommand: Active subcommand (used to skip irrelevant groups).\n        skip_corrected: If True, hide the 'Corrected Training' group\n                        (e.g. for the vanilla subcommand).\n    \"\"\"\n    if is_rich_active() and console is not None:\n        _show_rich(lora_cfg, train_cfg, subcommand, skip_corrected)\n    else:\n        _show_plain(lora_cfg, train_cfg, subcommand, skip_corrected)\n\n\ndef _show_rich(\n    lora_cfg: LoRAConfigV2,\n    train_cfg: TrainingConfigV2,\n    subcommand: str,\n    skip_corrected: bool,\n) -> None:\n    from rich.panel import Panel\n    from rich.table import Table\n\n    assert console is not None\n\n    table = Table(\n        show_header=True,\n        header_style=\"bold\",\n        border_style=\"dim\",\n        pad_edge=True,\n        expand=False,\n    )\n    table.add_column(\"Parameter\", style=\"dim\", min_width=22)\n    table.add_column(\"Value\", min_width=30)\n\n    for group_name, keys in _GROUPS:\n        if skip_corrected and group_name == \"Corrected Training\":\n            continue\n        # Section header row\n        table.add_row(f\"[bold cyan]{group_name}[/]\", \"\", end_section=False)\n        for key, label in keys:\n            value = _resolve_value(key, lora_cfg, train_cfg)\n            formatted = _fmt_value(value)\n            is_def = _is_default(key, value)\n            if is_def:\n                table.add_row(f\"  {label}\", _esc(formatted))\n            else:\n                table.add_row(f\"  {label}\", f\"[bold yellow]{_esc(formatted)}[/]\")\n\n    console.print(\n        Panel(\n            table,\n            title=\"[bold]Training Configuration[/]\",\n            border_style=\"blue\",\n            padding=(0, 1),\n        )\n    )\n\n\ndef _show_plain(\n    lora_cfg: LoRAConfigV2,\n    train_cfg: TrainingConfigV2,\n    subcommand: str,\n    skip_corrected: bool,\n) -> None:\n    print(\"=\" * 60, file=sys.stderr)\n    print(\"  Training Configuration\", file=sys.stderr)\n    print(\"=\" * 60, file=sys.stderr)\n\n    for group_name, keys in _GROUPS:\n        if skip_corrected and group_name == \"Corrected Training\":\n            continue\n        print(f\"\\n  [{group_name}]\", file=sys.stderr)\n        for key, label in keys:\n            value = _resolve_value(key, lora_cfg, train_cfg)\n            formatted = _fmt_value(value)\n            marker = \" *\" if not _is_default(key, value) else \"\"\n            print(f\"    {label:.<24s} {formatted}{marker}\", file=sys.stderr)\n\n    print(\"\\n\" + \"=\" * 60, file=sys.stderr)\n    print(\"  (* = non-default value)\", file=sys.stderr)\n    print(\"=\" * 60 + \"\\n\", file=sys.stderr)\n\n\n# ---- Confirmation prompt ----------------------------------------------------\n\ndef confirm_start(skip: bool = False) -> bool:\n    \"\"\"Ask the user to confirm before training.  Returns True to proceed.\n\n    Args:\n        skip: If True (``--yes`` flag), skip the prompt and return True.\n    \"\"\"\n    if skip:\n        return True\n\n    if is_rich_active() and console is not None:\n        from rich.prompt import Confirm\n        try:\n            return Confirm.ask(\n                \"[bold]Start training?[/]\",\n                default=True,\n                console=console,\n            )\n        except (EOFError, KeyboardInterrupt):\n            console.print(\"[dim]Aborted.[/]\")\n            return False\n    else:\n        try:\n            answer = input(\"Start training? [Y/n] \").strip().lower()\n            return answer in (\"\", \"y\", \"yes\")\n        except (EOFError, KeyboardInterrupt):\n            print(\"\\nAborted.\", file=sys.stderr)\n            return False\n"
  },
  {
    "path": "acestep/training_v2/ui/errors.py",
    "content": "\"\"\"\nError presentation for the ACE-Step Training V2 CLI.\n\nWraps exceptions in Rich Panels with actionable suggestions.\nFalls back to plain ``[FAIL]`` messages when Rich is unavailable.\n\"\"\"\n\nfrom __future__ import annotations\n\nimport sys\nimport traceback\nfrom typing import Optional\n\nfrom acestep.training_v2.ui import console, is_rich_active\n\n# ---- Suggestion database ----------------------------------------------------\n\n_SUGGESTIONS: dict[str, list[str]] = {\n    # CUDA OOM\n    \"CUDA out of memory\": [\n        \"Reduce --batch-size (try 1)\",\n        \"Reduce --rank (try 32 or 16)\",\n        \"Reduce --gradient-accumulation\",\n        \"Close other GPU-consuming processes\",\n    ],\n    \"OutOfMemoryError\": [\n        \"Reduce --batch-size (try 1)\",\n        \"Reduce --rank (try 32 or 16)\",\n    ],\n    # Model loading\n    \"No such file or directory\": [\n        \"Check --checkpoint-dir points to the correct path\",\n        \"Verify the model variant directory exists (e.g. acestep-v15-turbo/)\",\n    ],\n    \"not found\": [\n        \"Check that all required paths exist\",\n        \"Run preprocessing first if .pt files are missing\",\n    ],\n    # LoRA / PEFT\n    \"peft\": [\n        \"Install PEFT:  pip install peft\",\n    ],\n    \"PeftModel\": [\n        \"Install PEFT:  pip install peft\",\n    ],\n    # Fabric\n    \"lightning\": [\n        \"Install Lightning Fabric:  pip install lightning\",\n        \"Or the trainer will fall back to a basic PyTorch loop\",\n    ],\n    # Flash attention\n    \"flash_attn\": [\n        \"Flash Attention 2 is optional. The model will fall back to SDPA\",\n        \"To install:  pip install flash-attn --no-build-isolation\",\n    ],\n    # Dtype\n    \"bfloat16\": [\n        \"Your GPU may not support bf16.  Try --precision fp16\",\n    ],\n    # Generic\n    \"Permission denied\": [\n        \"Check file/directory permissions on --output-dir\",\n    ],\n    \"No space left on device\": [\n        \"Free up disk space or change --output-dir to a different drive\",\n    ],\n}\n\n\ndef _find_suggestions(error_str: str) -> list[str]:\n    \"\"\"Match error text against known patterns and return suggestions.\"\"\"\n    suggestions: list[str] = []\n    lower = error_str.lower()\n    for pattern, tips in _SUGGESTIONS.items():\n        if pattern.lower() in lower:\n            suggestions.extend(tips)\n    return suggestions\n\n\n# ---- Public API -------------------------------------------------------------\n\ndef handle_error(\n    exc: BaseException,\n    context: str = \"Training\",\n    show_traceback: bool = False,\n) -> None:\n    \"\"\"Display an error with suggestions.\n\n    Args:\n        exc: The exception that occurred.\n        context: Short label (e.g. \"Model loading\", \"Training\").\n        show_traceback: If True, include the full traceback.\n    \"\"\"\n    error_str = str(exc)\n    exc_type = type(exc).__name__\n    suggestions = _find_suggestions(error_str)\n\n    if is_rich_active() and console is not None:\n        _show_rich(exc, exc_type, error_str, context, suggestions, show_traceback)\n    else:\n        _show_plain(exc, exc_type, error_str, context, suggestions, show_traceback)\n\n\ndef show_warning(msg: str) -> None:\n    \"\"\"Display a warning message.\"\"\"\n    if is_rich_active() and console is not None:\n        console.print(f\"[bold yellow][WARN][/] {msg}\")\n    else:\n        print(f\"[WARN] {msg}\", file=sys.stderr)\n\n\ndef show_fail(msg: str) -> None:\n    \"\"\"Display a failure message (non-exception).\"\"\"\n    if is_rich_active() and console is not None:\n        console.print(f\"[bold red][Side-Step][/] {msg}\")\n    else:\n        print(f\"[Side-Step] {msg}\", file=sys.stderr)\n\n\ndef show_info(msg: str) -> None:\n    \"\"\"Display an info message.\"\"\"\n    if is_rich_active() and console is not None:\n        console.print(f\"[bold blue][INFO][/] {msg}\")\n    else:\n        print(f\"[INFO] {msg}\", file=sys.stderr)\n\n\ndef show_error(\n    title: str,\n    message: str,\n    suggestion: Optional[str] = None,\n) -> None:\n    \"\"\"Display a styled error panel (non-exception).\n\n    Args:\n        title: Panel title (e.g. \"Vanilla + Non-Turbo Model Warning\").\n        message: Main error message text (can be multiline).\n        suggestion: Optional suggestion text (e.g. command to run instead).\n    \"\"\"\n    if is_rich_active() and console is not None:\n        from rich.panel import Panel\n        from rich.text import Text\n\n        body = Text()\n        body.append(message, style=\"red\")\n        if suggestion:\n            body.append(\"\\n\\nSuggested fix:\\n\", style=\"bold yellow\")\n            body.append(f\"  {suggestion}\", style=\"yellow\")\n\n        console.print(\n            Panel(\n                body,\n                title=f\"[bold red]{title}[/]\",\n                border_style=\"red\",\n                padding=(0, 1),\n            )\n        )\n    else:\n        print(f\"\\n[Side-Step] {title}\", file=sys.stderr)\n        print(\"-\" * 60, file=sys.stderr)\n        print(message, file=sys.stderr)\n        if suggestion:\n            print(f\"\\nSuggested fix: {suggestion}\", file=sys.stderr)\n        print(\"-\" * 60 + \"\\n\", file=sys.stderr)\n\n\n# ---- Rich rendering --------------------------------------------------------\n\ndef _show_rich(\n    exc: BaseException,\n    exc_type: str,\n    error_str: str,\n    context: str,\n    suggestions: list[str],\n    show_traceback: bool,\n) -> None:\n    from rich.panel import Panel\n    from rich.text import Text\n\n    assert console is not None\n\n    body = Text()\n    body.append(f\"{exc_type}: \", style=\"bold red\")\n    body.append(f\"{error_str}\\n\", style=\"red\")\n\n    if suggestions:\n        body.append(\"\\nSuggested fixes:\\n\", style=\"bold yellow\")\n        for i, tip in enumerate(suggestions, 1):\n            body.append(f\"  {i}. {tip}\\n\", style=\"yellow\")\n\n    if show_traceback:\n        body.append(\"\\nTraceback:\\n\", style=\"dim\")\n        tb_str = \"\".join(traceback.format_exception(type(exc), exc, exc.__traceback__))\n        body.append(tb_str, style=\"dim red\")\n\n    console.print(\n        Panel(\n            body,\n            title=f\"[bold red]{context} Error[/]\",\n            border_style=\"red\",\n            padding=(0, 1),\n        )\n    )\n\n\n# ---- Plain rendering -------------------------------------------------------\n\ndef _show_plain(\n    exc: BaseException,\n    exc_type: str,\n    error_str: str,\n    context: str,\n    suggestions: list[str],\n    show_traceback: bool,\n) -> None:\n    print(f\"\\n[Side-Step] {context} Error: {exc_type}: {error_str}\", file=sys.stderr)\n    if suggestions:\n        print(\"       Suggested fixes:\", file=sys.stderr)\n        for i, tip in enumerate(suggestions, 1):\n            print(f\"         {i}. {tip}\", file=sys.stderr)\n    if show_traceback:\n        traceback.print_exception(type(exc), exc, exc.__traceback__, file=sys.stderr)\n    print(file=sys.stderr)\n"
  },
  {
    "path": "acestep/training_v2/ui/flows.py",
    "content": "\"\"\"\nWizard flow builders -- facade module.\n\nRe-exports ``wizard_train``, ``wizard_preprocess``, and ``wizard_estimate``\nfrom their dedicated modules so existing ``from .flows import ...`` imports\ncontinue to work after the step-based refactor.\n\"\"\"\n\nfrom acestep.training_v2.ui.flows_train import wizard_train\nfrom acestep.training_v2.ui.flows_preprocess import wizard_preprocess\nfrom acestep.training_v2.ui.flows_estimate import wizard_estimate\n\n__all__ = [\"wizard_train\", \"wizard_preprocess\", \"wizard_estimate\"]\n"
  },
  {
    "path": "acestep/training_v2/ui/flows_common.py",
    "content": "\"\"\"\nShared utilities for wizard flow modules.\n\nContains the Namespace builder for training flows, which maps the wizard\n``answers`` dict to the ``argparse.Namespace`` expected by dispatch.\n\"\"\"\n\nfrom __future__ import annotations\n\nimport argparse\n\nfrom acestep.training_v2.ui.prompt_helpers import DEFAULT_NUM_WORKERS\n\n\ndef build_train_namespace(a: dict, mode: str) -> argparse.Namespace:\n    \"\"\"Convert a wizard answers dict into an argparse.Namespace for dispatch.\n\n    Args:\n        a: Wizard answers dict populated by step functions.\n        mode: Training subcommand ('fixed' or 'vanilla').\n\n    Returns:\n        A fully populated ``argparse.Namespace``.\n    \"\"\"\n    target_modules = a.get(\"target_modules_str\", \"q_proj k_proj v_proj o_proj\").split()\n    nw = a.get(\"num_workers\", DEFAULT_NUM_WORKERS)\n    return argparse.Namespace(\n        subcommand=mode,\n        plain=False,\n        yes=False,\n        _from_wizard=True,\n        # Adapter selection\n        adapter_type=a.get(\"adapter_type\", \"lora\"),\n        checkpoint_dir=a[\"checkpoint_dir\"],\n        model_variant=a[\"model_variant\"],\n        base_model=a.get(\"base_model\", a[\"model_variant\"]),\n        device=a.get(\"device\", \"auto\"),\n        precision=a.get(\"precision\", \"auto\"),\n        dataset_dir=a[\"dataset_dir\"],\n        num_workers=nw,\n        pin_memory=a.get(\"pin_memory\", True),\n        prefetch_factor=a.get(\"prefetch_factor\", 2 if nw > 0 else 0),\n        persistent_workers=a.get(\"persistent_workers\", nw > 0),\n        learning_rate=a.get(\"learning_rate\", 1e-4),\n        batch_size=a.get(\"batch_size\", 1),\n        gradient_accumulation=a.get(\"gradient_accumulation\", 4),\n        epochs=a.get(\"epochs\", 100),\n        warmup_steps=a.get(\"warmup_steps\", 100),\n        weight_decay=a.get(\"weight_decay\", 0.01),\n        max_grad_norm=a.get(\"max_grad_norm\", 1.0),\n        seed=a.get(\"seed\", 42),\n        # LoRA args\n        rank=a.get(\"rank\", 64),\n        alpha=a.get(\"alpha\", 128),\n        dropout=a.get(\"dropout\", 0.1),\n        target_modules=target_modules,\n        attention_type=a.get(\"attention_type\", \"both\"),\n        bias=a.get(\"bias\", \"none\"),\n        # LoKR args\n        lokr_linear_dim=a.get(\"lokr_linear_dim\", 64),\n        lokr_linear_alpha=a.get(\"lokr_linear_alpha\", 128),\n        lokr_factor=a.get(\"lokr_factor\", -1),\n        lokr_decompose_both=a.get(\"lokr_decompose_both\", False),\n        lokr_use_tucker=a.get(\"lokr_use_tucker\", False),\n        lokr_use_scalar=a.get(\"lokr_use_scalar\", False),\n        lokr_weight_decompose=a.get(\"lokr_weight_decompose\", False),\n        # Output / checkpoints\n        output_dir=a[\"output_dir\"],\n        save_every=a.get(\"save_every\", 10),\n        resume_from=a.get(\"resume_from\"),\n        log_dir=a.get(\"log_dir\"),\n        log_every=a.get(\"log_every\", 10),\n        log_heavy_every=a.get(\"log_heavy_every\", 50),\n        sample_every_n_epochs=a.get(\"sample_every_n_epochs\", 0),\n        shift=a.get(\"shift\", 3.0),\n        num_inference_steps=a.get(\"num_inference_steps\", 8),\n        optimizer_type=a.get(\"optimizer_type\", \"adamw\"),\n        scheduler_type=a.get(\"scheduler_type\", \"cosine\"),\n        gradient_checkpointing=a.get(\"gradient_checkpointing\", True),\n        offload_encoder=a.get(\"offload_encoder\", False),\n        preprocess=False,\n        audio_dir=None,\n        dataset_json=None,\n        tensor_output=None,\n        max_duration=240.0,\n        cfg_ratio=a.get(\"cfg_ratio\", 0.15),\n        estimate_batches=None,\n        top_k=16,\n        granularity=\"module\",\n        module_config=None,\n        auto_estimate=False,\n        estimate_output=None,\n    )\n"
  },
  {
    "path": "acestep/training_v2/ui/flows_estimate.py",
    "content": "\"\"\"\nWizard flow for gradient sensitivity estimation.\n\nUses a step-list pattern for go-back navigation.\n\"\"\"\n\nfrom __future__ import annotations\n\nimport argparse\nfrom typing import Any, Callable\n\nfrom acestep.training_v2.ui import console, is_rich_active\nfrom acestep.training_v2.ui.prompt_helpers import (\n    DEFAULT_NUM_WORKERS,\n    GoBack,\n    ask,\n    ask_path,\n    native_path,\n    section,\n    step_indicator,\n)\n\n\n# ---- Steps ------------------------------------------------------------------\n\ndef _step_model(a: dict) -> None:\n    \"\"\"Prompt for checkpoint directory, model variant, and dataset path.\n\n    Args:\n        a: Mutable answers dict; mutated with ``checkpoint_dir``,\n            ``model_variant``, and ``dataset_dir``.\n\n    Raises:\n        GoBack: When the user navigates back.\n    \"\"\"\n    section(\"Gradient Sensitivity Estimation\")\n    if is_rich_active() and console is not None:\n        console.print(\n            \"  [dim]Estimates which LoRA layers learn fastest for your dataset.\\n\"\n            \"  Results are saved as JSON and can be used to guide rank selection.[/]\\n\"\n        )\n    else:\n        print(\n            \"  Estimates which LoRA layers learn fastest for your dataset.\\n\"\n            \"  Results are saved as JSON and can be used to guide rank selection.\\n\"\n        )\n\n    a[\"checkpoint_dir\"] = ask_path(\n        \"Checkpoint directory\", default=a.get(\"checkpoint_dir\", native_path(\"./checkpoints\")),\n        must_exist=True, allow_back=True,\n    )\n    a[\"model_variant\"] = ask(\n        \"Model variant\", default=a.get(\"model_variant\", \"base\"),\n        choices=[\"turbo\", \"base\", \"sft\"], allow_back=True,\n    )\n    a[\"dataset_dir\"] = ask_path(\n        \"Dataset directory (preprocessed .pt files)\",\n        default=a.get(\"dataset_dir\"),\n        must_exist=True, allow_back=True,\n    )\n\n\ndef _step_params(a: dict) -> None:\n    \"\"\"Prompt for estimation hyperparameters.\n\n    Args:\n        a: Mutable answers dict; mutated with ``estimate_batches``,\n            ``top_k``, and ``granularity``.\n\n    Raises:\n        GoBack: When the user navigates back.\n    \"\"\"\n    section(\"Estimation Parameters (press Enter for defaults)\")\n    a[\"estimate_batches\"] = ask(\"Number of estimation batches\", default=a.get(\"estimate_batches\", 5), type_fn=int, allow_back=True)\n    a[\"top_k\"] = ask(\"Top-K layers to highlight\", default=a.get(\"top_k\", 16), type_fn=int, allow_back=True)\n    a[\"granularity\"] = ask(\"Granularity\", default=a.get(\"granularity\", \"module\"), choices=[\"module\", \"layer\"], allow_back=True)\n\n\ndef _step_lora(a: dict) -> None:\n    \"\"\"Prompt for LoRA rank, alpha, and dropout used during estimation.\n\n    Args:\n        a: Mutable answers dict; mutated with ``rank``, ``alpha``,\n            and ``dropout``.\n\n    Raises:\n        GoBack: When the user navigates back.\n    \"\"\"\n    section(\"LoRA Settings (press Enter for defaults)\")\n    a[\"rank\"] = ask(\"Rank\", default=a.get(\"rank\", 64), type_fn=int, allow_back=True)\n    a[\"alpha\"] = ask(\"Alpha\", default=a.get(\"alpha\", 128), type_fn=int, allow_back=True)\n    a[\"dropout\"] = ask(\"Dropout\", default=a.get(\"dropout\", 0.1), type_fn=float, allow_back=True)\n\n\ndef _step_output(a: dict) -> None:\n    \"\"\"Prompt for the output JSON path for estimation results.\n\n    Args:\n        a: Mutable answers dict; mutated with ``estimate_output``.\n\n    Raises:\n        GoBack: When the user navigates back.\n    \"\"\"\n    a[\"estimate_output\"] = ask(\n        \"Output JSON path\",\n        default=a.get(\"estimate_output\", native_path(\"./estimate_results.json\")),\n        allow_back=True,\n    )\n\n\n# ---- Step list and runner ---------------------------------------------------\n\n_STEPS: list[tuple[str, Callable[..., Any]]] = [\n    (\"Model & Dataset\", _step_model),\n    (\"Estimation Parameters\", _step_params),\n    (\"LoRA Settings\", _step_lora),\n    (\"Output\", _step_output),\n]\n\n\ndef wizard_estimate() -> argparse.Namespace:\n    \"\"\"Interactive wizard for gradient estimation.\n\n    Returns:\n        A populated ``argparse.Namespace`` for the estimate subcommand.\n\n    Raises:\n        GoBack: If the user backs out of the first step.\n    \"\"\"\n    answers: dict = {}\n    total = len(_STEPS)\n    i = 0\n\n    while i < total:\n        label, step_fn = _STEPS[i]\n        try:\n            step_indicator(i + 1, total, label)\n            step_fn(answers)\n            i += 1\n        except GoBack:\n            if i == 0:\n                raise  # bubble to main menu\n            i -= 1\n\n    return argparse.Namespace(\n        subcommand=\"estimate\",\n        plain=False,\n        yes=True,\n        _from_wizard=True,\n        checkpoint_dir=answers[\"checkpoint_dir\"],\n        model_variant=answers[\"model_variant\"],\n        device=\"auto\",\n        precision=\"auto\",\n        dataset_dir=answers[\"dataset_dir\"],\n        num_workers=DEFAULT_NUM_WORKERS,\n        pin_memory=True,\n        prefetch_factor=2 if DEFAULT_NUM_WORKERS > 0 else 0,\n        persistent_workers=DEFAULT_NUM_WORKERS > 0,\n        learning_rate=1e-4,\n        batch_size=1,\n        gradient_accumulation=4,\n        epochs=1,\n        warmup_steps=0,\n        weight_decay=0.01,\n        max_grad_norm=1.0,\n        seed=42,\n        rank=answers.get(\"rank\", 64),\n        alpha=answers.get(\"alpha\", 128),\n        dropout=answers.get(\"dropout\", 0.1),\n        target_modules=[\"q_proj\", \"k_proj\", \"v_proj\", \"o_proj\"],\n        attention_type=\"both\",\n        bias=\"none\",\n        output_dir=native_path(\"./estimate_output\"),\n        save_every=999,\n        resume_from=None,\n        log_dir=None,\n        log_every=10,\n        log_heavy_every=50,\n        sample_every_n_epochs=0,\n        optimizer_type=\"adamw\",\n        scheduler_type=\"cosine\",\n        gradient_checkpointing=True,\n        offload_encoder=False,\n        preprocess=False,\n        audio_dir=None,\n        dataset_json=None,\n        tensor_output=None,\n        max_duration=240.0,\n        cfg_ratio=0.15,\n        estimate_batches=answers.get(\"estimate_batches\", 5),\n        top_k=answers.get(\"top_k\", 16),\n        granularity=answers.get(\"granularity\", \"module\"),\n        module_config=None,\n        auto_estimate=False,\n        estimate_output=answers.get(\"estimate_output\", native_path(\"./estimate_results.json\")),\n    )\n"
  },
  {
    "path": "acestep/training_v2/ui/flows_preprocess.py",
    "content": "\"\"\"\nWizard flow for preprocessing audio into tensors.\n\nUses a step-list pattern for go-back navigation.\n\"\"\"\n\nfrom __future__ import annotations\n\nimport argparse\nfrom pathlib import Path\nfrom typing import Any, Callable\n\nfrom acestep.training_v2.ui import console, is_rich_active\nfrom acestep.training_v2.ui.prompt_helpers import (\n    DEFAULT_NUM_WORKERS,\n    GoBack,\n    _esc,\n    ask,\n    ask_path,\n    native_path,\n    section,\n    step_indicator,\n)\n\n\n# ---- Steps ------------------------------------------------------------------\n\ndef _step_model(a: dict) -> None:\n    \"\"\"Checkpoint directory and model selection.\"\"\"\n    from acestep.training_v2.settings import get_checkpoint_dir\n    from acestep.training_v2.model_discovery import pick_model, prompt_base_model\n\n    section(\"Preprocessing Settings\")\n\n    ckpt_default = a.get(\"checkpoint_dir\") or get_checkpoint_dir() or native_path(\"./checkpoints\")\n    a[\"checkpoint_dir\"] = ask_path(\n        \"Checkpoint directory\", default=ckpt_default,\n        must_exist=True, allow_back=True,\n    )\n\n    # Model picker (replaces hardcoded turbo/base/sft choices)\n    result = pick_model(a[\"checkpoint_dir\"])\n    if result is None:\n        if is_rich_active() and console is not None:\n            console.print(\"  [yellow]No model directories found. Enter variant name manually.[/]\")\n        else:\n            print(\"  No model directories found. Enter variant name manually.\")\n        a[\"model_variant\"] = ask(\n            \"Model variant or folder name\", default=a.get(\"model_variant\", \"turbo\"),\n            allow_back=True,\n        )\n        a[\"base_model\"] = a[\"model_variant\"]\n    else:\n        name, info = result\n        a[\"model_variant\"] = name\n        a[\"base_model\"] = info.base_model\n        if not info.is_official and info.base_model == \"unknown\":\n            a[\"base_model\"] = prompt_base_model(name)\n\n\ndef _step_source(a: dict) -> None:\n    \"\"\"Dataset JSON or audio directory.\"\"\"\n    if is_rich_active() and console is not None:\n        console.print(\n            \"\\n  [dim]A dataset JSON provides lyrics, genre, BPM, key, and \"\n            \"other metadata for each audio file, plus audio file paths.\\n\"\n            \"  Without it, you will be asked for an audio directory and all \"\n            \"tracks will default to [Instrumental] with no genre/BPM info.[/]\"\n        )\n    else:\n        print(\n            \"\\n  A dataset JSON provides lyrics, genre, BPM, key, and \"\n            \"other metadata for each audio file, plus audio file paths.\\n\"\n            \"  Without it, you will be asked for an audio directory and all \"\n            \"tracks will default to [Instrumental] with no genre/BPM info.\"\n        )\n\n    a[\"dataset_json\"] = _ask_dataset_json(a.get(\"dataset_json\"))\n\n    if not a.get(\"dataset_json\"):\n        if is_rich_active() and console is not None:\n            console.print(\"  [dim]Subdirectories will be scanned recursively.[/]\")\n        else:\n            print(\"  Subdirectories will be scanned recursively.\")\n        a[\"audio_dir\"] = ask_path(\n            \"Audio directory (source audio files)\",\n            default=a.get(\"audio_dir\"),\n            must_exist=True, allow_back=True,\n        )\n    else:\n        a[\"audio_dir\"] = None\n\n\ndef _ask_dataset_json(default: str | None) -> str | None:\n    \"\"\"Prompt for a dataset JSON path with search-nearby fallback.\n\n    When the entered path is not found, searches common sibling\n    directories (``datasets/``, ``data/``) and CWD for a matching\n    filename before giving up.  Lets the user retry instead of\n    silently falling through to audio-directory mode.\n    \"\"\"\n    from acestep.training_v2.ui.prompt_helpers import ask_bool\n\n    while True:\n        dataset_json = ask(\n            \"Dataset JSON file (leave empty to skip)\",\n            default=default, allow_back=True,\n        )\n        if dataset_json in (None, \"None\", \"\"):\n            return None\n\n        resolved = _resolve_dataset_json(dataset_json)\n        if resolved is not None:\n            return str(resolved)\n\n        # Not found -- offer to retry\n        _print_not_found(dataset_json)\n        if ask_bool(\"Try a different path?\", default=True):\n            default = dataset_json  # keep what they typed as the new default\n            continue\n        return None\n\n\ndef _resolve_dataset_json(raw_path: str) -> Path | None:\n    \"\"\"Try to find the dataset JSON, searching nearby if needed.\"\"\"\n    candidate = Path(raw_path).expanduser()\n\n    # 1. Exact path (absolute or relative to CWD)\n    resolved = candidate.resolve()\n    if resolved.is_file():\n        return resolved\n\n    # 2. If they gave just a filename, search common subdirectories\n    search_dirs = [\n        Path.cwd(),\n        Path.cwd() / \"datasets\",\n        Path.cwd() / \"data\",\n    ]\n    name = candidate.name\n    for d in search_dirs:\n        p = (d / name).resolve()\n        if p.is_file():\n            _print_found_nearby(raw_path, p)\n            return p\n\n    # 3. Glob for the filename anywhere one level deep from CWD\n    for match in sorted(Path.cwd().glob(f\"*/{name}\")):\n        if match.is_file():\n            _print_found_nearby(raw_path, match)\n            return match\n\n    return None\n\n\ndef _print_found_nearby(original: str, found: Path) -> None:\n    \"\"\"Tell the user we found their file at a different path.\"\"\"\n    if is_rich_active() and console is not None:\n        console.print(f\"  [yellow]'{_esc(original)}' not at that exact path,[/]\")\n        console.print(f\"  [green]but found it at: {_esc(found)}[/]\")\n    else:\n        print(f\"  '{original}' not at that exact path,\")\n        print(f\"  but found it at: {found}\")\n\n\ndef _print_not_found(path: str) -> None:\n    \"\"\"Tell the user the file was not found anywhere.\"\"\"\n    if is_rich_active() and console is not None:\n        console.print(f\"  [red]Not found: {_esc(path)}[/]\")\n        console.print(\"  [dim]Searched CWD, datasets/, data/, and one level deep.[/]\")\n    else:\n        print(f\"  Not found: {path}\")\n        print(\"  Searched CWD, datasets/, data/, and one level deep.\")\n\n\ndef _step_output(a: dict) -> None:\n    \"\"\"Output directory and max duration.\"\"\"\n    a[\"tensor_output\"] = ask(\n        \"Output directory for .pt tensor files\",\n        default=a.get(\"tensor_output\"),\n        required=True, allow_back=True,\n    )\n    a[\"max_duration\"] = ask(\n        \"Max audio duration in seconds\",\n        default=a.get(\"max_duration\", 240.0),\n        type_fn=float, allow_back=True,\n    )\n\n\n# ---- Step list and runner ---------------------------------------------------\n\n_STEPS: list[tuple[str, Callable[..., Any]]] = [\n    (\"Model & Checkpoint\", _step_model),\n    (\"Audio Source\", _step_source),\n    (\"Output Settings\", _step_output),\n]\n\n\ndef wizard_preprocess() -> argparse.Namespace:\n    \"\"\"Interactive wizard for preprocessing.\n\n    Returns:\n        A populated ``argparse.Namespace`` with ``preprocess=True``.\n\n    Raises:\n        GoBack: If the user backs out of the first step.\n    \"\"\"\n    answers: dict = {}\n    total = len(_STEPS)\n    i = 0\n\n    while i < total:\n        label, step_fn = _STEPS[i]\n        try:\n            step_indicator(i + 1, total, label)\n            step_fn(answers)\n            i += 1\n        except GoBack:\n            if i == 0:\n                raise  # bubble to main menu\n            i -= 1\n\n    return argparse.Namespace(\n        subcommand=\"fixed\",\n        plain=False,\n        yes=True,\n        _from_wizard=True,\n        adapter_type=\"lora\",\n        checkpoint_dir=answers[\"checkpoint_dir\"],\n        model_variant=answers[\"model_variant\"],\n        base_model=answers.get(\"base_model\", answers[\"model_variant\"]),\n        device=\"auto\",\n        precision=\"auto\",\n        dataset_dir=answers.get(\"tensor_output\", \"\"),\n        num_workers=DEFAULT_NUM_WORKERS,\n        pin_memory=True,\n        prefetch_factor=2 if DEFAULT_NUM_WORKERS > 0 else 0,\n        persistent_workers=DEFAULT_NUM_WORKERS > 0,\n        learning_rate=1e-4,\n        batch_size=1,\n        gradient_accumulation=4,\n        epochs=100,\n        warmup_steps=100,\n        weight_decay=0.01,\n        max_grad_norm=1.0,\n        seed=42,\n        rank=64,\n        alpha=128,\n        dropout=0.1,\n        target_modules=[\"q_proj\", \"k_proj\", \"v_proj\", \"o_proj\"],\n        attention_type=\"both\",\n        bias=\"none\",\n        output_dir=native_path(\"./lora_output\"),\n        save_every=10,\n        resume_from=None,\n        log_dir=None,\n        log_every=10,\n        log_heavy_every=50,\n        sample_every_n_epochs=0,\n        optimizer_type=\"adamw\",\n        scheduler_type=\"cosine\",\n        gradient_checkpointing=True,\n        offload_encoder=False,\n        preprocess=True,\n        audio_dir=answers.get(\"audio_dir\"),\n        dataset_json=answers.get(\"dataset_json\"),\n        tensor_output=answers.get(\"tensor_output\"),\n        max_duration=answers.get(\"max_duration\", 240.0),\n        cfg_ratio=0.15,\n        estimate_batches=None,\n        top_k=16,\n        granularity=\"module\",\n        module_config=None,\n        auto_estimate=False,\n        estimate_output=None,\n    )\n"
  },
  {
    "path": "acestep/training_v2/ui/flows_setup.py",
    "content": "\"\"\"\nFirst-run setup wizard and settings editor for Side-Step.\n\nRuns automatically on the first launch.  Collects the checkpoint\ndirectory path and vanilla-mode intent.\nRe-accessible from the main menu under \"Settings\".\n\nNote: This is the upstream-integrated version of Side-Step.\nFor the standalone version with additional features, visit:\nhttps://github.com/koda-dernet/Side-Step\n\"\"\"\n\nfrom __future__ import annotations\n\nimport logging\nfrom pathlib import Path\n\nfrom acestep.training_v2.ui import console, is_rich_active\nfrom acestep.training_v2.ui.prompt_helpers import (\n    _esc,\n    ask_bool,\n    ask_path,\n    native_path,\n    section,\n)\n\nlogger = logging.getLogger(__name__)\n\n\n# ---------------------------------------------------------------------------\n# Helpers\n# ---------------------------------------------------------------------------\n\ndef _print(msg: str) -> None:\n    \"\"\"Print via Rich console if available, else plain print.\"\"\"\n    if is_rich_active() and console is not None:\n        console.print(msg)\n    else:\n        # Strip Rich markup for plain output\n        import re\n        print(re.sub(r\"\\[/?[^\\]]*\\]\", \"\", msg))\n\n\ndef _smart_checkpoint_default() -> str:\n    \"\"\"Pick a sensible default checkpoint path based on context.\"\"\"\n    for rel in (\"./checkpoints\", \"../checkpoints\"):\n        if Path(rel).is_dir():\n            return native_path(rel)\n    return native_path(\"./checkpoints\")\n\n\n# ---------------------------------------------------------------------------\n# First-run wizard\n# ---------------------------------------------------------------------------\n\ndef run_first_setup() -> dict:\n    \"\"\"Walk the user through first-time setup.\n\n    Returns the settings dict ready for ``save_settings()``.\n    \"\"\"\n    from acestep.training_v2.settings import _default_settings\n\n    data = _default_settings()\n\n    # -- Welcome + disclaimer -----------------------------------------------\n    section(\"Welcome to Side-Step\")\n    _print(\"  [bold]Before we begin, a few important notes:[/]\\n\")\n    _print(\"  [yellow]1.[/] You are responsible for downloading the model weights\")\n    _print(\"     you want to train on (e.g. via [bold]acestep-download[/] or manually).\")\n    _print(\"  [yellow]2.[/] If you are training on a fine-tune, you [bold]MUST[/] also have\")\n    _print(\"     the original base model that fine-tune was built from.\")\n    _print(\"  [yellow]3.[/] [bold]Never rename checkpoint folders.[/] The model loader uses\")\n    _print(\"     folder names and config.json files to identify models.\\n\")\n\n    _print(\"  [dim]This is the upstream-integrated version of Side-Step.[/]\")\n    _print(\"  [dim]For the standalone version with more features:[/]\")\n    _print(\"  [dim]https://github.com/koda-dernet/Side-Step[/]\\n\")\n\n    # -- Vanilla intent -----------------------------------------------------\n    section(\"Vanilla Training Mode\")\n    _print(\"  Side-Step's [bold green]corrected (fixed)[/] training is the recommended mode.\")\n    _print(\"  [bold yellow]Vanilla[/] mode reproduces the original ACE-Step training\")\n    _print(\"  behavior (discrete timesteps, no CFG dropout).\\n\")\n\n    data[\"vanilla_enabled\"] = ask_bool(\n        \"Do you plan to use Vanilla training mode?\",\n        default=False,\n    )\n\n    # -- Checkpoint directory -----------------------------------------------\n    section(\"Model Checkpoints\")\n    _print(\"  Where are your model checkpoint folders?\")\n    _print(\"  [dim](Each model variant lives in its own subfolder, e.g.\\n   checkpoints/acestep-v15-turbo/, checkpoints/acestep-v15-base/, etc.)[/]\\n\")\n\n    default_ckpt = _smart_checkpoint_default()\n    while True:\n        ckpt_dir = ask_path(\"Checkpoint directory\", default=default_ckpt)\n        ckpt_path = Path(ckpt_dir)\n        if not ckpt_path.is_dir():\n            _print(f\"  [red]Directory not found: {_esc(ckpt_dir)}[/]\")\n            if not ask_bool(\"Try a different path?\", default=True):\n                break\n            continue\n\n        # Scan for model subdirectories\n        from acestep.training_v2.model_discovery import scan_models\n        models = scan_models(ckpt_dir)\n        if models:\n            _print(f\"\\n  [green]Found {len(models)} model(s):[/]\")\n            for m in models:\n                tag = \"[green](official)[/]\" if m.is_official else \"[yellow](custom)[/]\"\n                _print(f\"    - {m.name}  {tag}\")\n            _print(\"\")\n            break\n        else:\n            _print(\"  [yellow]No model directories found in that location.[/]\")\n            _print(\"  [dim](Looking for subfolders with a config.json file.)[/]\")\n            if not ask_bool(\"Try a different path?\", default=True):\n                break\n\n    data[\"checkpoint_dir\"] = ckpt_dir\n    data[\"first_run_complete\"] = True\n\n    # -- Summary ------------------------------------------------------------\n    section(\"Setup Complete\")\n    _print(f\"  Checkpoint dir : [bold]{_esc(data['checkpoint_dir'])}[/]\")\n    if data[\"vanilla_enabled\"]:\n        _print(\"  Vanilla mode   : [bold green]enabled[/]\")\n    else:\n        _print(\"  Vanilla mode   : [bold yellow]disabled[/] (corrected mode recommended)\")\n    _print(\"\")\n    _print(\"  [dim]You can change these any time from the main menu → Settings.[/]\\n\")\n\n    return data\n\n\n# ---------------------------------------------------------------------------\n# Settings editor (re-run setup from the menu)\n# ---------------------------------------------------------------------------\n\ndef run_settings_editor() -> dict | None:\n    \"\"\"Re-run the setup flow from defaults.\n\n    Returns the updated settings dict, or ``None`` if the user cancels.\n    \"\"\"\n    from acestep.training_v2.settings import load_settings\n\n    _print(\"\\n  [bold]Re-running Side-Step setup...[/]\\n\")\n    try:\n        return run_first_setup()\n    except (KeyboardInterrupt, EOFError):\n        _print(\"  [dim]Cancelled.[/]\")\n        return None\n"
  },
  {
    "path": "acestep/training_v2/ui/flows_train.py",
    "content": "\"\"\"\nWizard flow for training (fixed or vanilla mode).\n\nUses a step-list pattern for go-back navigation.  Step functions are\ndefined in ``flows_train_steps`` to keep this module under the LOC cap.\n\nSupports both LoRA (PEFT) and LoKR (LyCORIS) adapters.\n\"\"\"\n\nfrom __future__ import annotations\n\nimport argparse\n\nfrom acestep.training_v2.ui import console, is_rich_active\nfrom acestep.training_v2.ui.prompt_helpers import GoBack, _esc, menu, step_indicator\nfrom acestep.training_v2.ui.flows_common import build_train_namespace\nfrom acestep.training_v2.ui.flows_train_steps import (\n    step_config_mode,\n    step_required,\n    step_lora,\n    step_lokr,\n    step_training,\n    step_cfg,\n    step_logging,\n    step_advanced_device,\n    step_advanced_optimizer,\n    step_advanced_vram,\n    step_advanced_training,\n    step_advanced_dataloader,\n    step_advanced_logging,\n)\n\n\n# ---- Step list builder ------------------------------------------------------\n\ndef _build_steps(mode: str, config_mode: str, adapter_type: str = \"lora\") -> list[tuple[str, callable]]:\n    \"\"\"Return the ordered list of ``(label, step_fn)`` for this wizard run.\"\"\"\n    adapter_step = step_lokr if adapter_type == \"lokr\" else step_lora\n    adapter_label = \"LoKR Settings\" if adapter_type == \"lokr\" else \"LoRA Settings\"\n\n    steps = [\n        (\"Required Settings\", step_required),\n        (adapter_label, adapter_step),\n        (\"Training Settings\", step_training),\n    ]\n\n    if mode == \"fixed\":\n        steps.append((\"Corrected Training Settings\", step_cfg))\n\n    steps.append((\"Logging & Checkpoints\", step_logging))\n\n    if config_mode == \"advanced\":\n        steps.extend([\n            (\"Device & Precision\", step_advanced_device),\n            (\"Optimizer & Scheduler\", step_advanced_optimizer),\n            (\"VRAM Savings\", step_advanced_vram),\n            (\"Advanced Training\", step_advanced_training),\n            (\"Data Loading\", step_advanced_dataloader),\n            (\"Advanced Logging\", step_advanced_logging),\n        ])\n\n    return steps\n\n\n# ---- Preset helpers ---------------------------------------------------------\n\ndef _offer_load_preset(answers: dict) -> None:\n    \"\"\"Ask user if they want to load a preset; merge values into answers.\"\"\"\n    from acestep.training_v2.ui.presets import list_presets, load_preset\n\n    presets = list_presets()\n    if not presets:\n        return\n\n    options: list[tuple[str, str]] = [(\"fresh\", \"Start fresh (defaults)\")]\n    for p in presets:\n        tag = \" (built-in)\" if p[\"builtin\"] else \"\"\n        desc = f\" -- {p['description']}\" if p[\"description\"] else \"\"\n        options.append((p[\"name\"], f\"{p['name']}{tag}{desc}\"))\n\n    choice = menu(\"Load a preset?\", options, default=1, allow_back=True)\n\n    if choice != \"fresh\":\n        data = load_preset(choice)\n        if data:\n            answers.update(data)\n            if is_rich_active() and console is not None:\n                console.print(f\"  [green]Loaded preset '{choice}'.[/]\\n\")\n            else:\n                print(f\"  Loaded preset '{choice}'.\\n\")\n\n\ndef _offer_save_preset(answers: dict) -> None:\n    \"\"\"After wizard completes, offer to save settings as a preset.\n\n    Errors from file I/O or name validation are caught and displayed\n    so the user gets feedback rather than a silent failure.\n    \"\"\"\n    from acestep.training_v2.ui.presets import save_preset\n    from acestep.training_v2.ui.prompt_helpers import ask_bool, ask as _ask, section\n\n    try:\n        section(\"Save Preset\")\n        if not ask_bool(\"Save these settings as a reusable preset?\", default=True):\n            return\n        name = _ask(\"Preset name\", required=True)\n        desc = _ask(\"Short description\", default=\"\")\n        path = save_preset(name, desc, answers)\n\n        # Verify the file was actually written\n        if path.is_file():\n            size = path.stat().st_size\n            if is_rich_active() and console is not None:\n                console.print(\n                    f\"  [green]Preset '{_esc(name)}' saved ({size} bytes)[/]\\n\"\n                    f\"  [dim]Location: {_esc(path)}[/]\\n\"\n                )\n            else:\n                print(f\"  Preset '{name}' saved ({size} bytes)\")\n                print(f\"  Location: {path}\\n\")\n        else:\n            if is_rich_active() and console is not None:\n                console.print(f\"  [red]Warning: preset file not found after save: {_esc(path)}[/]\\n\")\n            else:\n                print(f\"  Warning: preset file not found after save: {path}\\n\")\n    except (KeyboardInterrupt, EOFError):\n        pass\n    except Exception as exc:\n        # Catch ValueError (bad name), OSError/PermissionError, etc.\n        if is_rich_active() and console is not None:\n            console.print(f\"  [red]Failed to save preset: {_esc(exc)}[/]\\n\")\n        else:\n            print(f\"  Failed to save preset: {exc}\\n\")\n\n\n# ---- Public entry point -----------------------------------------------------\n\ndef wizard_train(\n    mode: str = \"fixed\",\n    adapter_type: str = \"lora\",\n    preset: dict | None = None,\n) -> argparse.Namespace:\n    \"\"\"Interactive wizard for training (fixed or vanilla).\n\n    Args:\n        mode: Training mode ('fixed' or 'vanilla').\n        adapter_type: Adapter type ('lora' or 'lokr').\n        preset: Optional dict of pre-filled answer values (e.g. dataset_dir\n            from the chain flow after preprocessing).  These values are\n            used as defaults but do NOT suppress preset loading.\n\n    Returns:\n        A populated ``argparse.Namespace`` ready for dispatch.\n\n    Raises:\n        GoBack: If the user backs out of the very first step.\n    \"\"\"\n    # Pre-fill any values the caller provided (e.g. dataset_dir from\n    # the preprocess chain flow).  These are saved and restored after\n    # preset loading so they always take priority.\n    prefill: dict = dict(preset) if preset else {}\n    answers: dict = dict(prefill)\n    answers[\"adapter_type\"] = adapter_type\n\n    # Always offer to load a preset.  Pre-filled values (like\n    # dataset_dir) are not in PRESET_FIELDS, so they survive the\n    # update.  adapter_type is guarded below regardless.\n    try:\n        _offer_load_preset(answers)\n    except GoBack:\n        raise\n\n    # Guard: adapter_type always comes from the menu selection, never\n    # from a preset.  Pre-filled values also take priority over preset\n    # values in case of overlap.\n    answers[\"adapter_type\"] = adapter_type\n    answers.update(prefill)\n\n    # Step 0: config depth\n    try:\n        step_config_mode(answers)\n    except GoBack:\n        raise\n\n    config_mode = answers[\"config_mode\"]\n    steps = _build_steps(mode, config_mode, adapter_type)\n    total = len(steps)\n    i = 0\n\n    while i < total:\n        label, step_fn = steps[i]\n        try:\n            step_indicator(i + 1, total, label)\n            step_fn(answers)\n            i += 1\n        except GoBack:\n            if i == 0:\n                try:\n                    step_config_mode(answers)\n                except GoBack:\n                    raise\n                config_mode = answers[\"config_mode\"]\n                steps = _build_steps(mode, config_mode, adapter_type)\n                total = len(steps)\n                i = 0\n            else:\n                i -= 1\n\n    _offer_save_preset(answers)\n\n    return build_train_namespace(answers, mode)\n"
  },
  {
    "path": "acestep/training_v2/ui/flows_train_steps.py",
    "content": "\"\"\"\nIndividual wizard steps for the training flow.\n\nEach step function takes an ``answers`` dict and writes user responses\ninto it.  All prompts support ``allow_back=True`` for go-back navigation.\n\"\"\"\n\nfrom __future__ import annotations\n\nfrom acestep.training_v2.ui import console, is_rich_active\nfrom acestep.training_v2.ui.prompt_helpers import (\n    IS_WINDOWS,\n    DEFAULT_NUM_WORKERS,\n    _esc,\n    menu,\n    ask,\n    ask_path,\n    ask_bool,\n    native_path,\n    section,\n)\n\n\n# ---- Basic steps ------------------------------------------------------------\n\ndef step_config_mode(a: dict) -> None:\n    \"\"\"Choose basic vs advanced configuration depth.\"\"\"\n    a[\"config_mode\"] = menu(\n        \"How much do you want to configure?\",\n        [\n            (\"basic\", \"Basic (recommended defaults, fewer questions)\"),\n            (\"advanced\", \"Advanced (all settings exposed)\"),\n        ],\n        default=1,\n        allow_back=True,\n    )\n\n\ndef step_required(a: dict) -> None:\n    \"\"\"Collect required paths and model selection.\"\"\"\n    from acestep.training_v2.settings import get_checkpoint_dir\n    from acestep.training_v2.model_discovery import (\n        pick_model,\n        prompt_base_model,\n    )\n\n    section(\"Required Settings\")\n\n    # Checkpoint dir: prefer settings default over hardcoded fallback\n    ckpt_default = a.get(\"checkpoint_dir\") or get_checkpoint_dir() or native_path(\"./checkpoints\")\n    a[\"checkpoint_dir\"] = ask_path(\n        \"Checkpoint directory\", default=ckpt_default,\n        must_exist=True, allow_back=True,\n    )\n\n    # Model selection via interactive picker (replaces hardcoded choices)\n    result = pick_model(a[\"checkpoint_dir\"])\n    if result is None:\n        # No models found -- fall back to manual entry\n        if is_rich_active() and console is not None:\n            console.print(\"  [yellow]No model directories found. Enter variant name manually.[/]\")\n        else:\n            print(\"  No model directories found. Enter variant name manually.\")\n        a[\"model_variant\"] = ask(\n            \"Model variant or folder name\", default=a.get(\"model_variant\", \"turbo\"),\n            allow_back=True,\n        )\n        a[\"base_model\"] = a[\"model_variant\"]\n    else:\n        name, info = result\n        a[\"model_variant\"] = name\n        a[\"base_model\"] = info.base_model\n\n        # If fine-tune with unknown base, ask the user\n        if not info.is_official and info.base_model == \"unknown\":\n            a[\"base_model\"] = prompt_base_model(name)\n\n    a[\"dataset_dir\"] = ask_path(\n        \"Dataset directory (preprocessed .pt files)\",\n        default=a.get(\"dataset_dir\"),\n        must_exist=True, allow_back=True,\n    )\n    a[\"output_dir\"] = ask(\n        \"Output directory for adapter weights\",\n        default=a.get(\"output_dir\"),\n        required=True, allow_back=True,\n    )\n\n\ndef step_lora(a: dict) -> None:\n    \"\"\"LoRA hyperparameters.\"\"\"\n    section(\"LoRA Settings (press Enter for defaults)\")\n    a[\"rank\"] = ask(\"Rank\", default=a.get(\"rank\", 64), type_fn=int, allow_back=True)\n    a[\"alpha\"] = ask(\"Alpha\", default=a.get(\"alpha\", 128), type_fn=int, allow_back=True)\n    a[\"dropout\"] = ask(\"Dropout\", default=a.get(\"dropout\", 0.1), type_fn=float, allow_back=True)\n\n    a[\"attention_type\"] = menu(\n        \"Which attention layers to target?\",\n        [\n            (\"both\", \"Both self-attention and cross-attention\"),\n            (\"self\", \"Self-attention only (audio patterns)\"),\n            (\"cross\", \"Cross-attention only (text conditioning)\"),\n        ],\n        default=1,\n        allow_back=True,\n    )\n\n    a[\"target_modules_str\"] = ask(\n        \"Target projections\",\n        default=a.get(\"target_modules_str\", \"q_proj k_proj v_proj o_proj\"),\n        allow_back=True,\n    )\n\n\ndef step_lokr(a: dict) -> None:\n    \"\"\"LoKR hyperparameters (LyCORIS Kronecker adapter).\"\"\"\n    section(\"LoKR Settings (press Enter for defaults)\")\n    a[\"lokr_linear_dim\"] = ask(\"Linear dimension\", default=a.get(\"lokr_linear_dim\", 64), type_fn=int, allow_back=True)\n    a[\"lokr_linear_alpha\"] = ask(\"Linear alpha\", default=a.get(\"lokr_linear_alpha\", 128), type_fn=int, allow_back=True)\n    a[\"lokr_factor\"] = ask(\"Factor (-1 = auto)\", default=a.get(\"lokr_factor\", -1), type_fn=int, allow_back=True)\n\n    a[\"lokr_decompose_both\"] = ask_bool(\n        \"Decompose both Kronecker factors?\",\n        default=a.get(\"lokr_decompose_both\", False),\n        allow_back=True,\n    )\n    a[\"lokr_use_tucker\"] = ask_bool(\n        \"Use Tucker decomposition?\",\n        default=a.get(\"lokr_use_tucker\", False),\n        allow_back=True,\n    )\n    a[\"lokr_use_scalar\"] = ask_bool(\n        \"Use scalar scaling?\",\n        default=a.get(\"lokr_use_scalar\", False),\n        allow_back=True,\n    )\n    a[\"lokr_weight_decompose\"] = ask_bool(\n        \"Enable DoRA-style weight decomposition?\",\n        default=a.get(\"lokr_weight_decompose\", False),\n        allow_back=True,\n    )\n\n    a[\"attention_type\"] = menu(\n        \"Which attention layers to target?\",\n        [\n            (\"both\", \"Both self-attention and cross-attention\"),\n            (\"self\", \"Self-attention only (audio patterns)\"),\n            (\"cross\", \"Cross-attention only (text conditioning)\"),\n        ],\n        default=1,\n        allow_back=True,\n    )\n\n    a[\"target_modules_str\"] = ask(\n        \"Target projections\",\n        default=a.get(\"target_modules_str\", \"q_proj k_proj v_proj o_proj\"),\n        allow_back=True,\n    )\n\n\ndef _default_shift(a: dict) -> float:\n    \"\"\"Return default shift value based on selected model variant.\"\"\"\n    base = a.get(\"base_model\", a.get(\"model_variant\", \"turbo\"))\n    if isinstance(base, str) and \"turbo\" in base.lower():\n        return 3.0\n    return 1.0\n\n\ndef _default_inference_steps(a: dict) -> int:\n    \"\"\"Return default num_inference_steps based on selected model variant.\"\"\"\n    base = a.get(\"base_model\", a.get(\"model_variant\", \"turbo\"))\n    if isinstance(base, str) and \"turbo\" in base.lower():\n        return 8\n    return 50\n\n\ndef step_training(a: dict) -> None:\n    \"\"\"Core training hyperparameters.\"\"\"\n    section(\"Training Settings (press Enter for defaults)\")\n    a[\"learning_rate\"] = ask(\"Learning rate\", default=a.get(\"learning_rate\", 1e-4), type_fn=float, allow_back=True)\n    a[\"batch_size\"] = ask(\"Batch size\", default=a.get(\"batch_size\", 1), type_fn=int, allow_back=True)\n    a[\"gradient_accumulation\"] = ask(\"Gradient accumulation\", default=a.get(\"gradient_accumulation\", 4), type_fn=int, allow_back=True)\n    a[\"epochs\"] = ask(\"Max epochs\", default=a.get(\"epochs\", 100), type_fn=int, allow_back=True)\n    a[\"warmup_steps\"] = ask(\"Warmup steps\", default=a.get(\"warmup_steps\", 100), type_fn=int, allow_back=True)\n    a[\"seed\"] = ask(\"Seed\", default=a.get(\"seed\", 42), type_fn=int, allow_back=True)\n\n    # Shift & inference steps -- auto-default from model variant\n    a[\"shift\"] = ask(\n        \"Shift (turbo=3.0, base/sft=1.0)\",\n        default=a.get(\"shift\", _default_shift(a)),\n        type_fn=float, allow_back=True,\n    )\n    a[\"num_inference_steps\"] = ask(\n        \"Inference steps (turbo=8, base/sft=50)\",\n        default=a.get(\"num_inference_steps\", _default_inference_steps(a)),\n        type_fn=int, allow_back=True,\n    )\n\n\ndef step_cfg(a: dict) -> None:\n    \"\"\"CFG dropout (fixed mode only).\"\"\"\n    section(\"Corrected Training Settings (press Enter for defaults)\")\n    a[\"cfg_ratio\"] = ask(\"CFG dropout ratio\", default=a.get(\"cfg_ratio\", 0.15), type_fn=float, allow_back=True)\n\n\ndef step_logging(a: dict) -> None:\n    \"\"\"Logging and checkpoint settings.\"\"\"\n    import os\n\n    section(\"Logging & Checkpoints (press Enter for defaults)\")\n    a[\"save_every\"] = ask(\"Save checkpoint every N epochs\", default=a.get(\"save_every\", 10), type_fn=int, allow_back=True)\n    a[\"log_every\"] = ask(\"Log metrics every N steps\", default=a.get(\"log_every\", 10), type_fn=int, allow_back=True)\n    resume_raw = ask(\"Resume from checkpoint path (leave empty to skip)\", default=a.get(\"resume_from\"), allow_back=True)\n    if resume_raw in (None, \"None\", \"\"):\n        a[\"resume_from\"] = None\n    else:\n        # Normalize: if user pointed to a file (e.g. adapter_config.json),\n        # use the containing directory instead.\n        if os.path.isfile(resume_raw):\n            parent = os.path.dirname(resume_raw)\n            if is_rich_active() and console is not None:\n                console.print(\n                    f\"  [yellow]That's a file -- using checkpoint directory: {_esc(parent)}[/]\"\n                )\n            else:\n                print(f\"  That's a file -- using checkpoint directory: {parent}\")\n            resume_raw = parent\n        a[\"resume_from\"] = resume_raw\n\n\n# ---- Advanced steps ---------------------------------------------------------\n\ndef step_advanced_device(a: dict) -> None:\n    \"\"\"Advanced: device and precision.\"\"\"\n    section(\"Device & Precision (Advanced, press Enter for defaults)\")\n    a[\"device\"] = ask(\"Device\", default=a.get(\"device\", \"auto\"), choices=[\"auto\", \"cuda\", \"cuda:0\", \"cuda:1\", \"mps\", \"xpu\", \"cpu\"], allow_back=True)\n    a[\"precision\"] = ask(\"Precision\", default=a.get(\"precision\", \"auto\"), choices=[\"auto\", \"bf16\", \"fp16\", \"fp32\"], allow_back=True)\n\n\ndef step_advanced_optimizer(a: dict) -> None:\n    \"\"\"Advanced: optimizer and scheduler.\"\"\"\n    section(\"Optimizer & Scheduler (press Enter for defaults)\")\n    a[\"optimizer_type\"] = menu(\n        \"Which optimizer to use?\",\n        [\n            (\"adamw\", \"AdamW (default, reliable)\"),\n            (\"adamw8bit\", \"AdamW 8-bit (saves ~30% optimizer VRAM, needs bitsandbytes)\"),\n            (\"adafactor\", \"Adafactor (minimal state memory)\"),\n            (\"prodigy\", \"Prodigy (auto-tunes LR -- set LR to 1.0, needs prodigyopt)\"),\n        ],\n        default=1,\n        allow_back=True,\n    )\n    if a[\"optimizer_type\"] == \"prodigy\":\n        a[\"learning_rate\"] = ask(\"Learning rate (Prodigy: use 1.0)\", default=1.0, type_fn=float, allow_back=True)\n\n    a[\"scheduler_type\"] = menu(\n        \"LR scheduler?\",\n        [\n            (\"cosine\", \"Cosine Annealing (smooth decay to near-zero, most popular)\"),\n            (\"cosine_restarts\", \"Cosine with Restarts (cyclical decay, LR resets periodically)\"),\n            (\"linear\", \"Linear (steady decay to near-zero)\"),\n            (\"constant\", \"Constant (flat LR after warmup)\"),\n            (\"constant_with_warmup\", \"Constant with Warmup (explicit warmup then flat)\"),\n        ],\n        default=1,\n        allow_back=True,\n    )\n\n\ndef step_advanced_vram(a: dict) -> None:\n    \"\"\"Advanced: VRAM savings.\"\"\"\n    section(\"VRAM Savings (Advanced, press Enter for defaults)\")\n    a[\"gradient_checkpointing\"] = ask_bool(\n        \"Enable gradient checkpointing? (saves ~40-60% activation VRAM, ~10-30% slower)\",\n        default=a.get(\"gradient_checkpointing\", True),\n        allow_back=True,\n    )\n    a[\"offload_encoder\"] = ask_bool(\n        \"Offload encoder/VAE to CPU? (saves ~2-4GB VRAM after setup)\",\n        default=a.get(\"offload_encoder\", False),\n        allow_back=True,\n    )\n\n\ndef step_advanced_training(a: dict) -> None:\n    \"\"\"Advanced: weight decay, grad norm, bias.\"\"\"\n    section(\"Advanced Training Settings (press Enter for defaults)\")\n    a[\"weight_decay\"] = ask(\"Weight decay\", default=a.get(\"weight_decay\", 0.01), type_fn=float, allow_back=True)\n    a[\"max_grad_norm\"] = ask(\"Max gradient norm\", default=a.get(\"max_grad_norm\", 1.0), type_fn=float, allow_back=True)\n    a[\"bias\"] = ask(\"Bias training mode\", default=a.get(\"bias\", \"none\"), choices=[\"none\", \"all\", \"lora_only\"], allow_back=True)\n\n\ndef step_advanced_dataloader(a: dict) -> None:\n    \"\"\"Advanced: DataLoader tuning.\"\"\"\n    section(\"Data Loading (Advanced, press Enter for defaults)\")\n    a[\"num_workers\"] = ask(\"DataLoader workers\", default=a.get(\"num_workers\", DEFAULT_NUM_WORKERS), type_fn=int, allow_back=True)\n    if IS_WINDOWS and a[\"num_workers\"] > 0:\n        if is_rich_active() and console is not None:\n            console.print(\"  [yellow]Warning: Windows detected -- forcing num_workers=0[/]\")\n        else:\n            print(\"  Warning: Windows detected -- forcing num_workers=0\")\n        a[\"num_workers\"] = 0\n    a[\"pin_memory\"] = ask_bool(\"Pin memory for GPU transfer?\", default=a.get(\"pin_memory\", True), allow_back=True)\n    a[\"prefetch_factor\"] = ask(\"Prefetch factor\", default=a.get(\"prefetch_factor\", 2 if a[\"num_workers\"] > 0 else 0), type_fn=int, allow_back=True)\n    a[\"persistent_workers\"] = ask_bool(\"Keep workers alive between epochs?\", default=a.get(\"persistent_workers\", a[\"num_workers\"] > 0), allow_back=True)\n\n\ndef step_advanced_logging(a: dict) -> None:\n    \"\"\"Advanced: TensorBoard logging.\"\"\"\n    section(\"Advanced Logging (press Enter for defaults)\")\n    log_dir_raw = ask(\"TensorBoard log directory (leave empty for default)\", default=a.get(\"log_dir\"), allow_back=True)\n    a[\"log_dir\"] = None if log_dir_raw in (None, \"None\", \"\") else log_dir_raw\n    a[\"log_heavy_every\"] = ask(\"Log gradient norms every N steps\", default=a.get(\"log_heavy_every\", 50), type_fn=int, allow_back=True)\n    a[\"sample_every_n_epochs\"] = ask(\"Generate sample every N epochs (0=disabled)\", default=a.get(\"sample_every_n_epochs\", 0), type_fn=int, allow_back=True)\n"
  },
  {
    "path": "acestep/training_v2/ui/gpu_monitor.py",
    "content": "\"\"\"\nCached GPU / VRAM monitor for the live training display.\n\nWraps ``gpu_utils`` with a time-based cache to avoid hammering the GPU\ndriver on every render tick.\n\"\"\"\n\nfrom __future__ import annotations\n\nimport time\nfrom dataclasses import dataclass\nfrom typing import Optional\n\n\n@dataclass\nclass VRAMSnapshot:\n    \"\"\"A point-in-time GPU memory reading.\"\"\"\n\n    used_mb: float = 0.0\n    total_mb: float = 0.0\n    name: str = \"unknown\"\n    timestamp: float = 0.0\n\n    @property\n    def used_gb(self) -> float:\n        return self.used_mb / 1024.0\n\n    @property\n    def total_gb(self) -> float:\n        return self.total_mb / 1024.0\n\n    @property\n    def percent(self) -> float:\n        if self.total_mb <= 0:\n            return 0.0\n        return (self.used_mb / self.total_mb) * 100.0\n\n    @property\n    def free_mb(self) -> float:\n        return max(0.0, self.total_mb - self.used_mb)\n\n\nclass GPUMonitor:\n    \"\"\"Cached GPU VRAM monitor.\n\n    Queries the device at most every ``interval`` seconds.  Returns the\n    last snapshot otherwise.\n\n    Args:\n        device: Torch device string (``cuda:0``, ``mps``, ``cpu``, ...).\n        interval: Minimum seconds between actual GPU queries.\n    \"\"\"\n\n    def __init__(self, device: str = \"cuda:0\", interval: float = 5.0) -> None:\n        self._device = device\n        self._device_type = device.split(\":\")[0]\n        self._interval = interval\n        self._last: Optional[VRAMSnapshot] = None\n        self._available = self._device_type == \"cuda\"\n        self._name: str = \"\"\n        self._total_mb: float = 0.0\n        self._init_static()\n\n    # ---- static (one-time) queries -----------------------------------------\n\n    def _init_static(self) -> None:\n        \"\"\"Cache device name and total VRAM (these don't change).\"\"\"\n        if not self._available:\n            return\n        try:\n            import torch\n\n            idx = self._cuda_idx()\n            self._name = torch.cuda.get_device_name(idx)\n            self._total_mb = (\n                torch.cuda.get_device_properties(idx).total_memory / (1024 ** 2)\n            )\n        except Exception:\n            self._available = False\n\n    def _cuda_idx(self) -> int:\n        if \":\" in self._device:\n            return int(self._device.split(\":\")[1])\n        return 0\n\n    # ---- public API ---------------------------------------------------------\n\n    @property\n    def available(self) -> bool:\n        \"\"\"``True`` when VRAM monitoring is possible.\"\"\"\n        return self._available\n\n    def snapshot(self) -> VRAMSnapshot:\n        \"\"\"Return the latest VRAM snapshot, potentially cached.\"\"\"\n        now = time.monotonic()\n\n        if self._last is not None and (now - self._last.timestamp) < self._interval:\n            return self._last\n\n        if not self._available:\n            snap = VRAMSnapshot(timestamp=now)\n            self._last = snap\n            return snap\n\n        try:\n            import torch\n\n            idx = self._cuda_idx()\n            torch.cuda.synchronize(idx)\n            reserved = torch.cuda.memory_reserved(idx) / (1024 ** 2)\n            snap = VRAMSnapshot(\n                used_mb=reserved,\n                total_mb=self._total_mb,\n                name=self._name,\n                timestamp=now,\n            )\n        except Exception:\n            snap = VRAMSnapshot(\n                total_mb=self._total_mb,\n                name=self._name,\n                timestamp=now,\n            )\n\n        self._last = snap\n        return snap\n\n    def peak_mb(self) -> float:\n        \"\"\"Return peak allocated VRAM in MiB (CUDA only).\"\"\"\n        if not self._available:\n            return 0.0\n        try:\n            import torch\n            return torch.cuda.max_memory_allocated(self._cuda_idx()) / (1024 ** 2)\n        except Exception:\n            return 0.0\n"
  },
  {
    "path": "acestep/training_v2/ui/help_formatter.py",
    "content": "\"\"\"\nRich-enhanced argparse help formatter.\n\nReplaces the default ``argparse.HelpFormatter`` with a version that uses\nRich markup for colored, readable ``--help`` output.\n\nThis is a lightweight custom implementation that avoids the need for the\n``rich-argparse`` third-party package.\n\"\"\"\n\nfrom __future__ import annotations\n\nimport argparse\nimport io\nimport sys\nfrom typing import Optional\n\n\nclass RichHelpFormatter(argparse.HelpFormatter):\n    \"\"\"argparse help formatter that uses Rich for styled terminal output.\n\n    Falls back to the default formatter if Rich is not available.\n    \"\"\"\n\n    def __init__(\n        self,\n        prog: str,\n        indent_increment: int = 2,\n        max_help_position: int = 30,\n        width: Optional[int] = None,\n    ) -> None:\n        # Try to get terminal width from Rich\n        if width is None:\n            try:\n                from rich.console import Console\n                width = Console().width\n            except ImportError:\n                width = 80\n        super().__init__(prog, indent_increment, max_help_position, width)\n\n    def format_help(self) -> str:\n        \"\"\"Override to apply Rich styling to the help output.\"\"\"\n        raw_help = super().format_help()\n\n        try:\n            from rich.console import Console\n            from rich.text import Text\n        except ImportError:\n            return raw_help\n\n        # Build styled output\n        console = Console(file=io.StringIO(), force_terminal=True, width=self._width)\n\n        for line in raw_help.split(\"\\n\"):\n            stripped = line.strip()\n\n            # Section headers (e.g. \"positional arguments:\", \"options:\")\n            if stripped.endswith(\":\") and not stripped.startswith(\"-\"):\n                console.print(f\"[bold cyan]{line}[/]\")\n\n            # Argument lines (start with -)\n            elif stripped.startswith(\"-\"):\n                # Split into arg name and help text\n                parts = line.split(\"  \", 1)\n                if len(parts) == 2:\n                    arg_part = parts[0]\n                    help_part = parts[1]\n                    console.print(f\"[bold green]{arg_part}[/]  {help_part}\")\n                else:\n                    console.print(f\"[bold green]{line}[/]\")\n\n            # Subcommand names (indented words before help text)\n            elif stripped and not stripped.startswith(\"{\") and \"  \" in line and line.startswith(\"  \"):\n                parts = line.split(\"  \", 1)\n                # Filter out empty parts\n                parts = [p for p in line.split(\"  \") if p.strip()]\n                if len(parts) >= 2:\n                    cmd = parts[0]\n                    desc = \"  \".join(parts[1:])\n                    indent = line[:len(line) - len(line.lstrip())]\n                    console.print(f\"{indent}[bold yellow]{cmd.strip()}[/]  {desc.strip()}\")\n                else:\n                    console.print(line)\n\n            # Usage line\n            elif stripped.startswith(\"usage:\"):\n                console.print(f\"[bold]{line}[/]\")\n\n            # Everything else\n            else:\n                console.print(line)\n\n        output = console.file.getvalue()\n        return output\n\n\ndef install_rich_help(parser: argparse.ArgumentParser) -> None:\n    \"\"\"Replace the formatter class on an existing parser and all subparsers.\"\"\"\n    parser.formatter_class = RichHelpFormatter\n    # Walk subparsers\n    for action in parser._actions:\n        if isinstance(action, argparse._SubParsersAction):\n            for sub_parser in action.choices.values():\n                sub_parser.formatter_class = RichHelpFormatter\n"
  },
  {
    "path": "acestep/training_v2/ui/presets.py",
    "content": "\"\"\"\nPreset save/load/manage logic for Side-Step wizard.\n\nPresets are named JSON files containing training hyperparameters (but not\npaths, device settings, or model-derived timestep params).  They live in:\n\n    Built-in:  ``<package>/training_v2/presets/``   (shipped, read-only)\n    Local:     ``./presets/``                       (project-local, primary)\n    Global:    ``~/.config/sidestep/presets/``      (user-global, fallback)\n\nNew user presets are saved to the **local** directory (``./presets/`` in\nthe current working directory).  This keeps presets visible, portable,\nand persistent across Docker container restarts.\n\nThe preset schema uses wizard field names for readability.  Unknown keys\nare silently ignored on load; missing keys fall back to defaults.\n\"\"\"\n\nfrom __future__ import annotations\n\nimport json\nimport shutil\nimport sys\nfrom pathlib import Path\nfrom typing import Any, Dict, List, Optional\n\nimport logging\n\nlogger = logging.getLogger(__name__)\n\n\n# ---- Directories ------------------------------------------------------------\n\ndef _find_project_root() -> Optional[Path]:\n    \"\"\"Locate the Side-Step project root directory.\n\n    Searches CWD, the script's own directory (``sys.argv[0]``), and\n    ancestors of CWD for a directory containing both ``pyproject.toml``\n    and the ``acestep/`` package.  This makes preset discovery work\n    regardless of the working directory -- important on Windows where\n    batch files and shortcuts may not set CWD to the project root.\n\n    Returns ``None`` if the project root cannot be determined.\n    \"\"\"\n    import sys as _sys\n\n    def _is_root(p: Path) -> bool:\n        return (p / \"train.py\").is_file() or (\n            (p / \"pyproject.toml\").is_file() and (p / \"acestep\").is_dir()\n        )\n\n    # 1. CWD (most common -- users are told to cd into the project)\n    cwd = Path.cwd()\n    if _is_root(cwd):\n        return cwd\n\n    # 2. Script directory (handles shortcuts, batch files, uv run, etc.)\n    if _sys.argv:\n        try:\n            script_dir = Path(_sys.argv[0]).resolve().parent\n            if _is_root(script_dir):\n                return script_dir\n        except (OSError, ValueError):\n            pass\n\n    # 3. Walk up from CWD (user ran from a subdirectory)\n    for parent in cwd.parents:\n        if _is_root(parent):\n            return parent\n\n    return None\n\n\ndef _local_presets_dir() -> Path:\n    \"\"\"Project-local user presets directory.\n\n    Anchored to the Side-Step project root rather than raw ``Path.cwd()``\n    so that presets are always found regardless of the working directory.\n    Falls back to ``CWD/presets/`` if the project root cannot be located.\n    \"\"\"\n    root = _find_project_root()\n    if root is not None:\n        return root / \"presets\"\n    return Path.cwd() / \"presets\"\n\n\ndef _global_presets_dir() -> Path:\n    \"\"\"Platform-aware global user presets directory (fallback).\n\n    Used as a secondary scan location so that presets saved before the\n    local-directory change are still found.\n    \"\"\"\n    import os\n    if sys.platform == \"win32\":\n        base = Path(os.environ.get(\"APPDATA\", Path.home() / \"AppData\" / \"Roaming\"))\n    else:\n        base = Path.home() / \".config\"\n    return base / \"sidestep\" / \"presets\"\n\n\ndef _builtin_presets_dir() -> Path:\n    \"\"\"Shipped built-in presets directory.\"\"\"\n    return Path(__file__).resolve().parent.parent / \"presets\"\n\n\n# ---- Fields that belong in a preset ----------------------------------------\n\nPRESET_FIELDS = frozenset([\n    # Adapter selection\n    \"adapter_type\",\n    # LoRA settings\n    \"rank\", \"alpha\", \"dropout\", \"target_modules_str\", \"attention_type\", \"bias\",\n    # LoKR settings\n    \"lokr_linear_dim\", \"lokr_linear_alpha\", \"lokr_factor\",\n    \"lokr_decompose_both\", \"lokr_use_tucker\", \"lokr_use_scalar\",\n    \"lokr_weight_decompose\",\n    # Training settings\n    \"learning_rate\", \"batch_size\", \"gradient_accumulation\", \"epochs\",\n    \"warmup_steps\", \"weight_decay\", \"max_grad_norm\", \"seed\",\n    \"shift\", \"num_inference_steps\",\n    \"optimizer_type\", \"scheduler_type\", \"cfg_ratio\",\n    \"save_every\", \"log_every\", \"log_heavy_every\",\n    \"gradient_checkpointing\", \"offload_encoder\",\n    \"sample_every_n_epochs\",\n])\n\n# ---- Max file size for import validation ------------------------------------\n_MAX_PRESET_BYTES = 1_000_000  # 1 MB\n\n# Characters forbidden in preset names (filesystem-safe on all platforms)\n_UNSAFE_CHARS = set('/\\\\:*?\"<>|')\n\n# Windows reserved filenames -- cannot be used even with an extension.\n# See https://learn.microsoft.com/en-us/windows/win32/fileio/naming-a-file\n_WINDOWS_RESERVED = frozenset({\n    \"CON\", \"PRN\", \"AUX\", \"NUL\",\n    *(f\"COM{i}\" for i in range(1, 10)),\n    *(f\"LPT{i}\" for i in range(1, 10)),\n})\n\n\ndef _sanitize_name(name: str) -> str:\n    \"\"\"Sanitize a preset name to be a safe filename stem.\n\n    Strips whitespace, replaces spaces with underscores, removes unsafe\n    characters, rejects path traversal attempts, and blocks Windows\n    reserved filenames (CON, NUL, COM1, etc.).\n    \"\"\"\n    name = name.strip()\n    if not name:\n        raise ValueError(\"Preset name cannot be empty\")\n    # Block path traversal\n    if \"..\" in name or name.startswith(\"/\") or name.startswith(\"\\\\\"):\n        raise ValueError(f\"Invalid preset name: {name!r}\")\n    # Remove unsafe characters and replace spaces\n    cleaned = \"\".join(c if c not in _UNSAFE_CHARS else \"\" for c in name)\n    cleaned = cleaned.replace(\" \", \"_\")\n    if not cleaned:\n        raise ValueError(f\"Preset name contains only special characters: {name!r}\")\n    # Block Windows reserved filenames (case-insensitive)\n    if cleaned.upper() in _WINDOWS_RESERVED:\n        raise ValueError(\n            f\"Preset name {cleaned!r} is a reserved filename on Windows\"\n        )\n    return cleaned\n\n\n# ---- Core operations --------------------------------------------------------\n\ndef list_presets() -> List[Dict[str, Any]]:\n    \"\"\"Return all available presets (built-in, then local, then global).\n\n    Each entry is ``{\"name\", \"description\", \"path\", \"builtin\"}``.\n    User presets (local or global) with the same name as a built-in\n    override the built-in.  Local presets override global ones.\n    Logs scan directories at DEBUG level for troubleshooting.\n    \"\"\"\n    presets: List[Dict[str, Any]] = []\n    seen_names: set[str] = set()\n\n    local_dir = _local_presets_dir()\n    global_dir = _global_presets_dir()\n    builtin_dir = _builtin_presets_dir()\n    logger.debug(\n        \"Scanning presets: local=%s  global=%s  builtin=%s\",\n        local_dir, global_dir, builtin_dir,\n    )\n\n    # Scan in priority order: local > global > built-in.\n    # First-seen name wins, so local overrides global which overrides built-in.\n    scan_order = [\n        (local_dir, False),\n        (global_dir, False),\n        (builtin_dir, True),\n    ]\n\n    for directory, builtin in scan_order:\n        if not directory.is_dir():\n            logger.debug(\"  %s: not found, skipping\", directory)\n            continue\n        found = list(sorted(directory.glob(\"*.json\")))\n        logger.debug(\"  %s: found %d preset(s)\", directory, len(found))\n        for fp in found:\n            name = fp.stem\n            if name in seen_names:\n                continue  # higher-priority version already listed\n            seen_names.add(name)\n            try:\n                data = json.loads(fp.read_text(encoding=\"utf-8\"))\n                desc = data.get(\"description\", \"\")\n            except (json.JSONDecodeError, OSError):\n                desc = \"(unreadable)\"\n            presets.append({\n                \"name\": name,\n                \"description\": desc,\n                \"path\": str(fp),\n                \"builtin\": builtin,\n            })\n\n    return presets\n\n\ndef load_preset(name: str) -> Optional[Dict[str, Any]]:\n    \"\"\"Load a preset by name and return the answers dict.\n\n    Search order: local -> global -> built-in.\n    Returns None if not found or if the name is invalid.\n    \"\"\"\n    try:\n        sanitized = _sanitize_name(name)\n    except ValueError:\n        logger.warning(\"Invalid preset name: %r\", name)\n        return None\n\n    for directory in [_local_presets_dir(), _global_presets_dir(), _builtin_presets_dir()]:\n        fp = directory / f\"{sanitized}.json\"\n        if fp.is_file():\n            try:\n                data = json.loads(fp.read_text(encoding=\"utf-8\"))\n            except (json.JSONDecodeError, OSError) as exc:\n                logger.warning(\"Failed to load preset %s: %s\", fp, exc)\n                return None\n            # Filter to known preset fields only\n            return {k: v for k, v in data.items() if k in PRESET_FIELDS}\n\n    return None\n\n\ndef save_preset(name: str, description: str, answers: Dict[str, Any]) -> Path:\n    \"\"\"Save a preset to the project-local presets directory.\n\n    Presets are saved to ``./presets/`` (relative to the current working\n    directory) so they're visible in the project, portable, and persist\n    across Docker container restarts.\n\n    Args:\n        name: Preset name (used as filename stem, sanitized).\n        description: Human-readable description.\n        answers: Full wizard answers dict (filtered to PRESET_FIELDS).\n\n    Returns:\n        Path to the saved preset file.\n\n    Raises:\n        ValueError: If the name is empty or unsafe.\n    \"\"\"\n    safe_name = _sanitize_name(name)\n    out_dir = _local_presets_dir()\n    out_dir.mkdir(parents=True, exist_ok=True)\n\n    data = {\"name\": safe_name, \"description\": description}\n    data.update({k: v for k, v in answers.items() if k in PRESET_FIELDS})\n\n    fp = out_dir / f\"{safe_name}.json\"\n    fp.write_text(json.dumps(data, indent=2), encoding=\"utf-8\")\n    return fp\n\n\ndef delete_preset(name: str) -> bool:\n    \"\"\"Delete a user preset.  Cannot delete built-ins.\n\n    Checks local directory first, then global.\n    Returns True if deleted, False if not found or built-in.\n    \"\"\"\n    try:\n        safe_name = _sanitize_name(name)\n    except ValueError:\n        return False\n    for directory in [_local_presets_dir(), _global_presets_dir()]:\n        fp = directory / f\"{safe_name}.json\"\n        if fp.is_file():\n            fp.unlink()\n            return True\n    return False\n\n\ndef import_preset(source_path: str) -> Optional[str]:\n    \"\"\"Import a preset from an external JSON file.\n\n    Validates the file before copying.  Returns the preset name on\n    success, or None on failure.\n    \"\"\"\n    src = Path(source_path)\n    if not src.is_file():\n        logger.warning(\"Import source not found: %s\", src)\n        return None\n    if src.stat().st_size > _MAX_PRESET_BYTES:\n        logger.warning(\"Preset file too large (>1MB): %s\", src)\n        return None\n\n    try:\n        data = json.loads(src.read_text(encoding=\"utf-8\"))\n        if not isinstance(data, dict):\n            logger.warning(\"Preset must be a JSON object: %s\", src)\n            return None\n    except (json.JSONDecodeError, OSError) as exc:\n        logger.warning(\"Invalid preset file %s: %s\", src, exc)\n        return None\n\n    raw_name = data.get(\"name\", src.stem)\n    try:\n        name = _sanitize_name(raw_name)\n    except ValueError:\n        logger.warning(\"Invalid preset name in %s: %r\", src, raw_name)\n        return None\n    out_dir = _local_presets_dir()\n    out_dir.mkdir(parents=True, exist_ok=True)\n    dest = out_dir / f\"{name}.json\"\n    shutil.copy2(src, dest)\n    return name\n\n\ndef export_preset(name: str, dest_path: str) -> bool:\n    \"\"\"Export a preset to an arbitrary path.\n\n    Returns True on success.\n    \"\"\"\n    try:\n        safe_name = _sanitize_name(name)\n    except ValueError:\n        return False\n    for directory in [_local_presets_dir(), _global_presets_dir(), _builtin_presets_dir()]:\n        fp = directory / f\"{safe_name}.json\"\n        if fp.is_file():\n            shutil.copy2(fp, dest_path)\n            return True\n    return False\n"
  },
  {
    "path": "acestep/training_v2/ui/progress.py",
    "content": "\"\"\"\nLive training progress display using Rich.\n\nRenders a live-updating dashboard that shows:\n    - Epoch progress bar with ETA\n    - Step-level progress bar within the current epoch\n    - Current metrics (loss, learning rate, speed)\n    - GPU VRAM usage bar\n    - Scrolling log of recent messages\n\nFalls back to plain ``print(msg)`` when Rich is unavailable or stdout\nis not a TTY.\n\"\"\"\n\nfrom __future__ import annotations\n\nimport logging\nimport time\nfrom dataclasses import dataclass, field\nfrom typing import Any, Dict, Iterator, List, Optional, Tuple, Union\n\nfrom acestep.training_v2.ui import TrainingUpdate, console, is_rich_active\nfrom acestep.training_v2.ui.gpu_monitor import GPUMonitor\n\n\n# ---- Logging capture (prevents ghost panels in tmux / web terminals) --------\n\nclass _LiveLogCapture(logging.Handler):\n    \"\"\"Redirects log messages into the panel's scrolling log area.\n\n    During a Rich Live session, any direct writes to stderr (including\n    from Python's ``logging.StreamHandler``) break the ANSI cursor\n    positioning that Live uses to overwrite the panel in-place.  This\n    causes \"ghost panels\" — stale copies of the display that get pushed\n    up.  The problem is especially visible in tmux and web terminals.\n\n    This handler captures log messages into the ``recent_msgs`` list\n    that the panel display reads from, and a ``live`` reference so the\n    display refreshes immediately after the log message is captured.\n    The file handler (``sidestep.log``) is unaffected and keeps logging\n    normally.\n    \"\"\"\n\n    def __init__(self, messages: list, live: object = None) -> None:\n        super().__init__(level=logging.INFO)\n        self._messages = messages\n        self._live = live\n\n    def emit(self, record: logging.LogRecord) -> None:\n        try:\n            msg = record.getMessage()\n            self._messages.append(msg)\n            if len(self._messages) > 20:\n                self._messages.pop(0)\n        except Exception:\n            pass\n\n\n# ---- Training statistics tracker --------------------------------------------\n\n@dataclass\nclass TrainingStats:\n    \"\"\"Accumulates statistics during training for the live display and\n    the post-training summary.\n    \"\"\"\n\n    start_time: float = 0.0\n    first_loss: float = 0.0\n    best_loss: float = float(\"inf\")\n    last_loss: float = 0.0\n    last_lr: float = 0.0\n    _lr_seen: bool = False\n    current_epoch: int = 0\n    max_epochs: int = 0\n    current_step: int = 0\n    total_steps_estimate: int = 0\n    steps_this_session: int = 0\n    peak_vram_mb: float = 0.0\n    last_epoch_time: float = 0.0\n    steps_per_epoch: int = 0\n    \"\"\"Total optimizer steps per epoch (for step-level progress bar).\"\"\"\n    step_in_epoch: int = 0\n    \"\"\"Current step index within the epoch (resets each epoch).\"\"\"\n    _step_times: list = field(default_factory=list)\n    checkpoints: List[Dict[str, object]] = field(default_factory=list)\n    \"\"\"Saved checkpoints: ``[{\"epoch\": int, \"loss\": float, \"path\": str}, ...]``.\"\"\"\n\n    @property\n    def elapsed(self) -> float:\n        if self.start_time <= 0:\n            return 0.0\n        return time.time() - self.start_time\n\n    @property\n    def elapsed_str(self) -> str:\n        return _fmt_duration(self.elapsed)\n\n    @property\n    def samples_per_sec(self) -> float:\n        if not self._step_times or len(self._step_times) < 2:\n            return 0.0\n        dt = self._step_times[-1] - self._step_times[0]\n        if dt <= 0:\n            return 0.0\n        return (len(self._step_times) - 1) / dt\n\n    @property\n    def eta_seconds(self) -> float:\n        if self.max_epochs <= 0 or self.current_epoch <= 0:\n            return 0.0\n        elapsed = self.elapsed\n        if elapsed <= 0:\n            return 0.0\n        progress = self.current_epoch / self.max_epochs\n        if progress <= 0:\n            return 0.0\n        return elapsed * (1.0 / progress - 1.0)\n\n    @property\n    def eta_str(self) -> str:\n        eta = self.eta_seconds\n        if eta <= 0:\n            return \"--\"\n        return _fmt_duration(eta)\n\n    def record_step(self) -> None:\n        now = time.time()\n        self._step_times.append(now)\n        if len(self._step_times) > 50:\n            self._step_times = self._step_times[-50:]\n\n\ndef _fmt_duration(seconds: float) -> str:\n    \"\"\"Format seconds to ``1h 23m 45s`` or ``12m 34s`` or ``45s``.\"\"\"\n    if seconds < 0:\n        return \"--\"\n    s = int(seconds)\n    h, s = divmod(s, 3600)\n    m, s = divmod(s, 60)\n    if h > 0:\n        return f\"{h}h {m:02d}m {s:02d}s\"\n    if m > 0:\n        return f\"{m}m {s:02d}s\"\n    return f\"{s}s\"\n\n\n# ---- Rich live display builder ----------------------------------------------\n\n_LOG_LINES = 5  # Fixed number of log lines for stable panel height\n\n\ndef _build_display(\n    stats: TrainingStats,\n    gpu: GPUMonitor,\n    recent_msgs: list,\n) -> Any:\n    \"\"\"Build the composite Rich renderable for one Live refresh.\"\"\"\n    from rich.console import Group\n    from rich.panel import Panel\n    from rich.progress_bar import ProgressBar\n    from rich.table import Table\n    from rich.text import Text\n\n    # -- Epoch progress -------------------------------------------------------\n    epoch_pct = 0.0\n    if stats.max_epochs > 0:\n        epoch_pct = stats.current_epoch / stats.max_epochs\n    epoch_bar = ProgressBar(total=100, completed=int(epoch_pct * 100), width=40)\n\n    epoch_line = Text()\n    epoch_line.append(\"  Epoch \", style=\"dim\")\n    epoch_line.append(f\"{stats.current_epoch}\", style=\"bold\")\n    epoch_line.append(f\" / {stats.max_epochs}  \", style=\"dim\")\n    epoch_line.append_text(Text.from_markup(f\"  Step {stats.current_step}\"))\n    epoch_line.append(f\"  |  ETA {stats.eta_str}\", style=\"dim\")\n\n    # -- Step-level progress (within epoch) -----------------------------------\n    # Only show the inner step bar when there are enough steps per epoch\n    # to make it meaningful.  For small datasets (e.g. 3 steps/epoch) the\n    # bar just flickers up/down and is more confusing than helpful.\n    _MIN_STEPS_FOR_BAR = 10\n    step_parts: list = []\n    if stats.steps_per_epoch >= _MIN_STEPS_FOR_BAR:\n        shown_step = max(stats.step_in_epoch, 0)\n        step_pct = min(shown_step / stats.steps_per_epoch, 1.0)\n        step_bar = ProgressBar(\n            total=100, completed=int(step_pct * 100), width=30,\n        )\n        step_line = Text()\n        step_line.append(f\"  Step {shown_step}\", style=\"dim\")\n        step_line.append(f\" / {stats.steps_per_epoch}  \", style=\"dim\")\n        step_line.append_text(\n            Text.from_markup(f\"  {step_bar}  [dim]{step_pct * 100:.0f}%[/]\"),\n        )\n        step_parts = [step_line]\n\n    # -- Metrics table --------------------------------------------------------\n    metrics = Table(\n        show_header=False, show_edge=False, pad_edge=False,\n        box=None, expand=True,\n    )\n    metrics.add_column(\"key\", style=\"dim\", ratio=1)\n    metrics.add_column(\"val\", ratio=1)\n    metrics.add_column(\"key2\", style=\"dim\", ratio=1)\n    metrics.add_column(\"val2\", ratio=1)\n\n    loss_str = f\"{stats.last_loss:.4f}\" if stats.last_loss > 0 else \"--\"\n    best_str = f\"{stats.best_loss:.4f}\" if stats.best_loss < float(\"inf\") else \"--\"\n    lr_str = f\"{stats.last_lr:.2e}\" if stats._lr_seen else \"--\"\n    speed_str = (\n        f\"{stats.samples_per_sec:.1f} steps/s\"\n        if stats.samples_per_sec > 0 else \"--\"\n    )\n\n    metrics.add_row(\"Loss\", f\"[bold]{loss_str}[/]\", \"Best\", f\"[green]{best_str}[/]\")\n    metrics.add_row(\"LR\", lr_str, \"Speed\", speed_str)\n    metrics.add_row(\n        \"Elapsed\", stats.elapsed_str,\n        \"Epoch time\",\n        f\"{stats.last_epoch_time:.1f}s\" if stats.last_epoch_time > 0 else \"--\",\n    )\n\n    # -- VRAM bar -------------------------------------------------------------\n    if gpu.available:\n        snap = gpu.snapshot()\n        pct = snap.percent\n        bar_width = 30\n        filled = int(bar_width * pct / 100)\n        bar_color = \"green\" if pct < 70 else (\"yellow\" if pct < 90 else \"red\")\n        bar = f\"[{bar_color}]{'#' * filled}[/][dim]{'-' * (bar_width - filled)}[/]\"\n        vram_line = (\n            f\"  VRAM {bar}  \"\n            f\"{snap.used_gb:.1f} / {snap.total_gb:.1f} GiB  \"\n            f\"[dim]({pct:.0f}%)[/]\"\n        )\n    else:\n        vram_line = \"  [dim]VRAM monitoring not available[/]\"\n\n    # -- Recent log (fixed height for stable panel) ---------------------------\n    log_text = Text()\n    padded = recent_msgs[-_LOG_LINES:]\n    while len(padded) < _LOG_LINES:\n        padded.insert(0, \"\")\n    for msg in padded:\n        if not msg:\n            log_text.append(\"  \\n\")\n        elif msg.startswith(\"[OK]\"):\n            log_text.append(f\"  {msg}\\n\", style=\"green\")\n        elif msg.startswith(\"[WARN]\"):\n            log_text.append(f\"  {msg}\\n\", style=\"yellow\")\n        elif msg.startswith(\"[FAIL]\"):\n            log_text.append(f\"  {msg}\\n\", style=\"red\")\n        elif msg.startswith(\"[INFO]\"):\n            log_text.append(f\"  {msg}\\n\", style=\"blue\")\n        else:\n            log_text.append(f\"  {msg}\\n\", style=\"dim\")\n\n    # -- Assemble panel -------------------------------------------------------\n    parts: list = [\n        epoch_line,\n        Text(\"\"),\n        Text.from_markup(f\"  {epoch_bar}  [dim]{epoch_pct * 100:.0f}%[/]\"),\n    ]\n    parts.extend(step_parts)\n    parts.extend([\n        Text(\"\"),\n        metrics,\n        Text(\"\"),\n        Text.from_markup(vram_line),\n        Text(\"\"),\n        log_text,\n    ])\n\n    return Panel(\n        Group(*parts),\n        title=\"[bold]Side-Step Training Progress[/]\",\n        border_style=\"green\",\n        padding=(0, 1),\n    )\n\n\n# ---- Main entry point -------------------------------------------------------\n\ndef track_training(\n    training_iter: Iterator[Union[Tuple[int, float, str], TrainingUpdate]],\n    max_epochs: int,\n    device: str = \"cuda:0\",\n    refresh_per_second: int = 2,\n) -> TrainingStats:\n    \"\"\"Consume training yields and display live progress.\n\n    Args:\n        training_iter: Generator yielding ``(step, loss, msg)`` or\n            ``TrainingUpdate`` objects.\n        max_epochs: Total number of epochs (for progress bar).\n        device: Device string for GPU monitoring.\n        refresh_per_second: Rich Live refresh rate.\n\n    Returns:\n        Final ``TrainingStats`` for the summary display.\n    \"\"\"\n    stats = TrainingStats(start_time=time.time(), max_epochs=max_epochs)\n    gpu = GPUMonitor(device=device, interval=3.0)\n    recent_msgs: list[str] = []\n\n    if is_rich_active() and console is not None:\n        return _track_rich(training_iter, stats, gpu, recent_msgs, refresh_per_second)\n    return _track_plain(training_iter, stats, gpu, recent_msgs)\n\n\ndef _track_rich(\n    training_iter: Iterator,\n    stats: TrainingStats,\n    gpu: GPUMonitor,\n    recent_msgs: list,\n    refresh_per_second: int,\n) -> TrainingStats:\n    \"\"\"Rich Live display loop.\n\n    Uses ``transient=True`` so each frame cleanly erases the previous one,\n    preventing ghost-panel stacking when external code (e.g. Lightning's\n    SLURM warning) writes to stdout/stderr during the live display.\n\n    During the Live session, Python logging is redirected from stderr into\n    the panel's scrolling log area.  This prevents log output (e.g. from\n    checkpoint saves) from breaking Rich's ANSI cursor positioning, which\n    caused \"ghost panels\" — especially in tmux and web terminals.  The file\n    handler (sidestep.log) is unaffected.\n\n    After the Live context exits, the final dashboard is re-printed as a\n    static renderable so it remains visible in the terminal.\n    \"\"\"\n    import warnings\n    from rich.live import Live\n\n    assert console is not None\n\n    error_msgs: list[str] = []\n\n    # Suppress warnings that print to stderr during Live and disrupt\n    # Rich's cursor positioning (e.g. Lightning SLURM, fork safety).\n    warnings.filterwarnings(\n        \"ignore\", message=\".*srun.*command is available.*\",\n    )\n    warnings.filterwarnings(\n        \"ignore\", message=\".*fork.*\",\n    )\n\n    # -- Redirect logging to prevent ghost panels ---------------------------\n    # Find and temporarily mute stderr StreamHandlers.  Replace them with a\n    # capture handler that feeds messages into the panel's log area.\n    root_logger = logging.getLogger()\n    muted_handlers: list[logging.Handler] = []\n    for h in list(root_logger.handlers):\n        if isinstance(h, logging.StreamHandler) and not isinstance(h, logging.FileHandler):\n            root_logger.removeHandler(h)\n            muted_handlers.append(h)\n\n    capture = _LiveLogCapture(recent_msgs)\n    root_logger.addHandler(capture)\n\n    try:\n        with Live(\n            _build_display(stats, gpu, recent_msgs),\n            console=console,\n            refresh_per_second=refresh_per_second,\n            transient=True,\n        ) as live:\n            for update in training_iter:\n                if isinstance(update, TrainingUpdate):\n                    step, loss, msg = update.step, update.loss, update.msg\n                    _process_structured(update, stats)\n                    if update.kind in (\"fail\", \"warn\"):\n                        error_msgs.append(msg)\n                else:\n                    step, loss, msg = update\n                    _process_tuple(step, loss, msg, stats)\n                    if \"[FAIL]\" in msg or \"[WARN]\" in msg:\n                        error_msgs.append(msg)\n\n                recent_msgs.append(msg)\n                if len(recent_msgs) > 20:\n                    recent_msgs.pop(0)\n\n                live.update(_build_display(stats, gpu, recent_msgs))\n    finally:\n        # Restore original console handlers\n        root_logger.removeHandler(capture)\n        for h in muted_handlers:\n            root_logger.addHandler(h)\n\n    # Print the final dashboard state (transient=True erases it on exit)\n    console.print(_build_display(stats, gpu, recent_msgs))\n\n    # Re-print errors that may have scrolled out of the log window\n    for err in error_msgs:\n        console.print(f\"  {err}\")\n\n    stats.peak_vram_mb = gpu.peak_mb()\n    return stats\n\n\ndef _track_plain(\n    training_iter: Iterator,\n    stats: TrainingStats,\n    gpu: GPUMonitor,\n    recent_msgs: list,\n) -> TrainingStats:\n    \"\"\"Plain-text fallback (no Rich).\"\"\"\n    for update in training_iter:\n        if isinstance(update, TrainingUpdate):\n            step, loss, msg = update.step, update.loss, update.msg\n            _process_structured(update, stats)\n        else:\n            step, loss, msg = update\n            _process_tuple(step, loss, msg, stats)\n\n        print(msg)\n\n    stats.peak_vram_mb = gpu.peak_mb()\n    return stats\n\n\n# ---- Update processing helpers ----------------------------------------------\n\ndef _process_structured(update: TrainingUpdate, stats: TrainingStats) -> None:\n    \"\"\"Extract stats from a TrainingUpdate.\"\"\"\n    stats.current_step = update.step\n    stats.last_loss = update.loss\n    stats.current_epoch = update.epoch\n    if update.max_epochs > 0:\n        stats.max_epochs = update.max_epochs\n    if update.lr >= 0 and update.kind == \"step\":\n        stats.last_lr = update.lr\n        stats._lr_seen = True\n    if update.epoch_time > 0:\n        stats.last_epoch_time = update.epoch_time\n    if update.steps_per_epoch > 0:\n        stats.steps_per_epoch = update.steps_per_epoch\n\n    if stats.first_loss == 0.0 and update.loss > 0:\n        stats.first_loss = update.loss\n    if update.loss > 0 and update.loss < stats.best_loss:\n        stats.best_loss = update.loss\n\n    if update.kind == \"step\":\n        stats.record_step()\n        stats.steps_this_session += 1\n\n    # Track step position within the current epoch.\n    # Derived from global_step so the bar stays correct even when\n    # updates are sparse (log_every > 1).  At epoch boundaries\n    # (kind=\"epoch\") we show the bar as fully complete rather than\n    # resetting to 0, which looked broken (\"Step 0 / 3\").\n    if stats.steps_per_epoch > 0 and stats.current_step > 0:\n        if update.kind == \"epoch\":\n            stats.step_in_epoch = stats.steps_per_epoch  # show as complete\n        else:\n            stats.step_in_epoch = (\n                (stats.current_step - 1) % stats.steps_per_epoch\n            ) + 1\n\n    if update.kind == \"checkpoint\":\n        stats.checkpoints.append({\n            \"epoch\": update.epoch,\n            \"loss\": update.loss,\n            \"path\": update.checkpoint_path,\n        })\n\n\ndef _process_tuple(step: int, loss: float, msg: str, stats: TrainingStats) -> None:\n    \"\"\"Extract stats from a raw ``(step, loss, msg)`` tuple by parsing the msg.\"\"\"\n    stats.current_step = step\n    stats.last_loss = loss\n\n    if stats.first_loss == 0.0 and loss > 0:\n        stats.first_loss = loss\n    if loss > 0 and loss < stats.best_loss:\n        stats.best_loss = loss\n\n    msg_lower = msg.lower()\n    if \"epoch\" in msg_lower:\n        try:\n            idx = msg.lower().index(\"epoch\")\n            rest = msg[idx + 5:].strip()\n            parts = rest.split(\"/\")\n            if len(parts) >= 2:\n                epoch_num = int(parts[0].strip())\n                max_part = parts[1].split(\",\")[0].split(\" \")[0].strip()\n                max_epochs = int(max_part)\n                stats.current_epoch = epoch_num\n                if max_epochs > 0:\n                    stats.max_epochs = max_epochs\n        except (ValueError, IndexError):\n            pass\n\n    if \" in \" in msg and (\"s,\" in msg or msg.rstrip().endswith(\"s\")):\n        try:\n            time_part = msg.split(\" in \")[1].split(\"s\")[0].strip()\n            stats.last_epoch_time = float(time_part)\n        except (IndexError, ValueError):\n            pass\n\n    if msg.startswith(\"Epoch\") and \"Step\" in msg and \"Loss\" in msg:\n        stats.record_step()\n        stats.steps_this_session += 1\n"
  },
  {
    "path": "acestep/training_v2/ui/prompt_helpers.py",
    "content": "\"\"\"\nReusable Rich/fallback prompt helpers for the interactive wizard.\n\nProvides menu selection, typed value prompts, path prompts, boolean prompts,\nsection headers, go-back navigation, and step indicators -- with automatic\nRich fallback to plain ``input()``.\n\"\"\"\n\nfrom __future__ import annotations\n\nimport sys\nfrom pathlib import Path\nfrom typing import Any, Optional\n\nfrom acestep.training_v2.ui import console, is_rich_active\n\n# Windows uses spawn-based multiprocessing which breaks DataLoader workers\nIS_WINDOWS = sys.platform == \"win32\"\nDEFAULT_NUM_WORKERS = 0 if IS_WINDOWS else 4\n\n# Back-navigation keyword recognised by all prompts\n_BACK_KEYWORDS = {\"b\", \"back\"}\n\n\ndef _esc(text: object) -> str:\n    \"\"\"Escape Rich markup characters in user-provided text for safe display.\n\n    Replaces ``[`` with ``\\\\[`` so that paths and other user input containing\n    square brackets (e.g. ``/media/user/[volume]/path``) are not interpreted\n    as Rich markup tags.\n    \"\"\"\n    return str(text).replace(\"[\", \"\\\\[\")\n\n\ndef native_path(path: str) -> str:\n    \"\"\"Convert a path string to use the native OS separator for display.\n\n    On Windows, replaces forward slashes with backslashes so that path\n    defaults shown in wizard prompts look natural to the user\n    (e.g. ``.\\checkpoints`` instead of ``./checkpoints``).\n\n    On Linux/macOS, returns the path unchanged.\n    \"\"\"\n    if IS_WINDOWS:\n        return path.replace(\"/\", \"\\\\\")\n    return path\n\n\n# ---- Go-back exception -----------------------------------------------------\n\nclass GoBack(Exception):\n    \"\"\"Raised when the user types 'b' or 'back' at any prompt.\"\"\"\n\n\ndef _is_back(raw: str) -> bool:\n    \"\"\"Return True if the raw input string is a back-navigation request.\"\"\"\n    return raw.strip().lower() in _BACK_KEYWORDS\n\n\n# ---- Step indicator ---------------------------------------------------------\n\ndef step_indicator(current: int, total: int, label: str) -> None:\n    \"\"\"Print a step progress indicator, e.g. ``[Step 3/8] LoRA Settings``.\"\"\"\n    tag = f\"Step {current}/{total}\"\n    if is_rich_active() and console is not None:\n        # Use \\[ to escape the bracket so Rich doesn't parse it as markup\n        console.print(f\"\\n  [bold green]\\\\[{tag}][/] [bold]{label}[/]\")\n    else:\n        print(f\"\\n  [{tag}] {label}\")\n\n\n# ---- Helpers ----------------------------------------------------------------\n\ndef menu(\n    title: str,\n    options: list[tuple[str, str]],\n    default: int = 1,\n    allow_back: bool = False,\n) -> str:\n    \"\"\"Display a numbered menu and return the chosen key.\n\n    Args:\n        title: Prompt text.\n        options: List of ``(key, label)`` tuples.\n        default: 1-based default index.\n        allow_back: If True, typing 'b'/'back' raises ``GoBack``.\n\n    Returns:\n        The ``key`` of the chosen option.\n\n    Raises:\n        GoBack: When ``allow_back`` is True and user types 'b'/'back'.\n    \"\"\"\n    back_hint = \"  [dim]Type 'b' to go back[/]\" if allow_back else \"\"\n    back_hint_plain = \"  Type 'b' to go back\" if allow_back else \"\"\n\n    if is_rich_active() and console is not None:\n        console.print()\n        console.print(f\"  [bold]{title}[/]\\n\")\n        for i, (key, label) in enumerate(options, 1):\n            marker = \"[bold cyan]>[/]\" if i == default else \" \"\n            tag = \"  [dim](default)[/]\" if i == default else \"\"\n            console.print(f\"    {marker} [bold]{i}[/]. {label}{tag}\")\n        if back_hint:\n            console.print(back_hint)\n        console.print()\n\n        from rich.prompt import IntPrompt\n        while True:\n            raw = console.input(\"  Choice: \") if allow_back else None\n            if allow_back and raw is not None:\n                if _is_back(raw):\n                    raise GoBack()\n                try:\n                    choice = int(raw) if raw.strip() else default\n                except ValueError:\n                    console.print(f\"  [red]Please enter a number between 1 and {len(options)}[/]\")\n                    continue\n            else:\n                choice = IntPrompt.ask(\n                    \"  Choice\",\n                    default=default,\n                    console=console,\n                )\n            if 1 <= choice <= len(options):\n                return options[choice - 1][0]\n            console.print(f\"  [red]Please enter a number between 1 and {len(options)}[/]\")\n    else:\n        print(f\"\\n  {title}\\n\")\n        for i, (key, label) in enumerate(options, 1):\n            tag = \" (default)\" if i == default else \"\"\n            print(f\"    {i}. {label}{tag}\")\n        if back_hint_plain:\n            print(back_hint_plain)\n        print()\n        while True:\n            try:\n                raw = input(f\"  Choice [{default}]: \").strip()\n                if allow_back and _is_back(raw):\n                    raise GoBack()\n                choice = int(raw) if raw else default\n                if 1 <= choice <= len(options):\n                    return options[choice - 1][0]\n                print(f\"  Please enter a number between 1 and {len(options)}\")\n            except ValueError:\n                print(f\"  Please enter a number between 1 and {len(options)}\")\n\n\ndef ask(\n    label: str,\n    default: Any = None,\n    required: bool = False,\n    type_fn: type = str,\n    choices: Optional[list] = None,\n    allow_back: bool = False,\n) -> Any:\n    \"\"\"Ask for a single value with an optional default.\n\n    Args:\n        label: Prompt text.\n        default: Default value (None = required).\n        required: If True, empty input is rejected.\n        type_fn: Cast function (str, int, float).\n        choices: Optional list of valid string values.\n        allow_back: If True, typing 'b'/'back' raises ``GoBack``.\n\n    Returns:\n        The user's input, cast to ``type_fn``.\n\n    Raises:\n        GoBack: When ``allow_back`` is True and user types 'b'/'back'.\n    \"\"\"\n    if choices:\n        choice_str = f\" ({'/'.join(str(c) for c in choices)})\"\n    else:\n        choice_str = \"\"\n\n    if is_rich_active() and console is not None:\n        from rich.prompt import Prompt, IntPrompt, FloatPrompt\n\n        prompt_cls = Prompt\n        if type_fn is int:\n            prompt_cls = IntPrompt\n        elif type_fn is float:\n            prompt_cls = FloatPrompt\n\n        while True:\n            if allow_back:\n                # Use raw console.input so we can intercept 'b'/'back'\n                # Escape default value so paths with brackets aren't\n                # misinterpreted as Rich markup tags.\n                default_str = f\" \\\\[{_esc(default)}]\" if default is not None else \"\"\n                raw = console.input(f\"  {label}{choice_str}{default_str}: \").strip()\n                if _is_back(raw):\n                    raise GoBack()\n                if not raw and default is not None:\n                    return default\n                if not raw and required:\n                    console.print(\"  [red]This field is required[/]\")\n                    continue\n                try:\n                    val = type_fn(raw)\n                except (ValueError, TypeError):\n                    console.print(f\"  [red]Invalid input, expected {type_fn.__name__}[/]\")\n                    continue\n                if choices and str(val) not in [str(c) for c in choices]:\n                    console.print(f\"  [red]Must be one of: {', '.join(str(c) for c in choices)}[/]\")\n                    continue\n                return val\n            else:\n                result = prompt_cls.ask(\n                    f\"  {label}{choice_str}\",\n                    default=default if default is not None else ...,\n                    console=console,\n                )\n                if result is ...:\n                    if required:\n                        console.print(\"  [red]This field is required[/]\")\n                        continue\n                    return None\n                if required and not str(result).strip():\n                    console.print(\"  [red]This field is required[/]\")\n                    continue\n                if choices and str(result) not in [str(c) for c in choices]:\n                    console.print(f\"  [red]Must be one of: {', '.join(str(c) for c in choices)}[/]\")\n                    continue\n                return type_fn(result) if not isinstance(result, type_fn) else result\n    else:\n        default_str = f\" [{default}]\" if default is not None else \"\"\n        while True:\n            raw = input(f\"  {label}{choice_str}{default_str}: \").strip()\n            if allow_back and _is_back(raw):\n                raise GoBack()\n            if not raw and default is not None:\n                return default\n            if not raw and required:\n                print(\"  This field is required\")\n                continue\n            try:\n                val = type_fn(raw)\n                if choices and str(val) not in [str(c) for c in choices]:\n                    print(f\"  Must be one of: {', '.join(str(c) for c in choices)}\")\n                    continue\n                return val\n            except (ValueError, TypeError):\n                print(f\"  Invalid input, expected {type_fn.__name__}\")\n\n\ndef ask_path(\n    label: str,\n    default: Optional[str] = None,\n    must_exist: bool = False,\n    allow_back: bool = False,\n) -> str:\n    \"\"\"Ask for a filesystem path, optionally validating existence.\n\n    Raises:\n        GoBack: When ``allow_back`` is True and user types 'b'/'back'.\n    \"\"\"\n    while True:\n        val = ask(label, default=default, required=True, allow_back=allow_back)\n        if must_exist and not Path(val).exists():\n            if is_rich_active() and console is not None:\n                console.print(f\"  [red]Path not found: {_esc(val)}[/]\")\n            else:\n                print(f\"  Path not found: {val}\")\n            continue\n        return val\n\n\ndef ask_bool(label: str, default: bool = True, allow_back: bool = False) -> bool:\n    \"\"\"Ask for a yes/no boolean value.\n\n    Raises:\n        GoBack: When ``allow_back`` is True and user types 'b'/'back'.\n    \"\"\"\n    choices = [\"yes\", \"no\"]\n    default_str = \"yes\" if default else \"no\"\n    result = ask(label, default=default_str, choices=choices, allow_back=allow_back)\n    return result.lower() in (\"yes\", \"y\", \"true\", \"1\")\n\n\ndef section(title: str) -> None:\n    \"\"\"Print a section header.\"\"\"\n    if is_rich_active() and console is not None:\n        console.print(f\"\\n  [bold cyan]--- {title} ---[/]\\n\")\n    else:\n        print(f\"\\n  --- {title} ---\\n\")\n"
  },
  {
    "path": "acestep/training_v2/ui/summary.py",
    "content": "\"\"\"\nPost-training summary panel.\n\nDisplays final statistics after training completes: total time, loss\ntrajectory, GPU usage, saved checkpoints grid, output paths, and\nnext-steps hints.\n\"\"\"\n\nfrom __future__ import annotations\n\nimport sys\nfrom pathlib import Path\nfrom typing import Any, Optional\n\nfrom acestep.training_v2.ui import console, is_rich_active\nfrom acestep.training_v2.ui.progress import TrainingStats\n\n\ndef _dir_size_str(path: str) -> str:\n    \"\"\"Return human-readable size of a directory.\"\"\"\n    try:\n        total = sum(f.stat().st_size for f in Path(path).rglob(\"*\") if f.is_file())\n        if total > 1024 ** 3:\n            return f\"{total / 1024 ** 3:.2f} GiB\"\n        if total > 1024 ** 2:\n            return f\"{total / 1024 ** 2:.1f} MiB\"\n        if total > 1024:\n            return f\"{total / 1024:.0f} KiB\"\n        return f\"{total} B\"\n    except Exception:\n        return \"unknown\"\n\n\ndef show_summary(\n    stats: TrainingStats,\n    output_dir: str,\n    log_dir: Optional[str] = None,\n) -> None:\n    \"\"\"Display the post-training summary.\n\n    If training completed 0 steps, shows a failure panel with diagnostics\n    instead of a misleading \"Training Complete\" message.\n\n    Args:\n        stats: Accumulated training statistics from the progress tracker.\n        output_dir: Path to the LoRA output directory.\n        log_dir: Path to TensorBoard log directory (for the hint).\n    \"\"\"\n    if stats.current_step == 0 and stats.current_epoch == 0:\n        _show_failure(stats, output_dir)\n        return\n\n    if is_rich_active() and console is not None:\n        _show_rich(stats, output_dir, log_dir)\n    else:\n        _show_plain(stats, output_dir, log_dir)\n\n\ndef _show_failure(stats: TrainingStats, output_dir: str) -> None:\n    \"\"\"Show a clear failure message when training completes with 0 steps.\"\"\"\n    if is_rich_active() and console is not None:\n        from rich.panel import Panel\n\n        console.print(\n            Panel(\n                \"[bold red]Training did not run.[/]\\n\\n\"\n                \"  0 epochs completed, 0 steps executed.\\n\\n\"\n                \"  Common causes:\\n\"\n                \"  1. [bold]Dataset directory is empty[/] -- no .pt files found\\n\"\n                \"  2. [bold]Device mismatch[/] -- wrong GPU index or insufficient VRAM\\n\"\n                \"  3. [bold]Dependency issue[/] -- peft, lightning, or bitsandbytes\\n\\n\"\n                \"  Check [bold]sidestep.log[/] for the full error traceback.\",\n                title=\"[bold red]Training Failed[/]\",\n                border_style=\"red\",\n                padding=(0, 1),\n            )\n        )\n    else:\n        print(\"\\n\" + \"=\" * 60, file=sys.stderr)\n        print(\"  TRAINING FAILED -- 0 steps executed\", file=sys.stderr)\n        print(\"  Check sidestep.log for the full error traceback.\", file=sys.stderr)\n        print(\"=\" * 60 + \"\\n\", file=sys.stderr)\n\n\ndef _show_rich(\n    stats: TrainingStats,\n    output_dir: str,\n    log_dir: Optional[str],\n) -> None:\n    \"\"\"Rich summary panel with 2-column checkpoint grid.\"\"\"\n    from rich.columns import Columns\n    from rich.console import Group\n    from rich.panel import Panel\n    from rich.table import Table\n    from rich.text import Text\n\n    assert console is not None\n\n    # -- Stats table ----------------------------------------------------------\n    table = Table(\n        show_header=False, show_edge=False, box=None,\n        pad_edge=True, expand=False,\n    )\n    table.add_column(\"key\", style=\"dim\", min_width=20)\n    table.add_column(\"val\", min_width=30)\n\n    table.add_row(\"Total time\", f\"[bold]{stats.elapsed_str}[/]\")\n    table.add_row(\"Epochs completed\", f\"{stats.current_epoch} / {stats.max_epochs}\")\n    table.add_row(\"Total steps\", str(stats.current_step))\n\n    if stats.first_loss > 0:\n        direction = \"down\" if stats.last_loss < stats.first_loss else \"up\"\n        color = \"green\" if direction == \"down\" else \"red\"\n        pct = abs(stats.last_loss - stats.first_loss) / stats.first_loss * 100\n        table.add_row(\n            \"Loss\",\n            f\"[bold]{stats.first_loss:.4f}[/] -> [{color}]{stats.last_loss:.4f}[/]  \"\n            f\"[dim]({direction} {pct:.1f}%)[/]\",\n        )\n    if stats.best_loss < float(\"inf\"):\n        table.add_row(\"Best loss\", f\"[green]{stats.best_loss:.4f}[/]\")\n    if stats.peak_vram_mb > 0:\n        table.add_row(\"Peak VRAM\", f\"{stats.peak_vram_mb / 1024:.1f} GiB\")\n    if stats.samples_per_sec > 0:\n        table.add_row(\"Avg speed\", f\"{stats.samples_per_sec:.1f} steps/s\")\n\n    # -- Saved checkpoints grid (2-column) ------------------------------------\n    ckpt_section = _build_checkpoint_grid(stats, output_dir)\n\n    # -- Output paths ---------------------------------------------------------\n    paths = Table(\n        show_header=False, show_edge=False, box=None,\n        pad_edge=True, expand=False,\n    )\n    paths.add_column(\"key\", style=\"dim\", min_width=20)\n    paths.add_column(\"val\", min_width=30)\n\n    final_dir = Path(output_dir) / \"final\"\n    paths.add_row(\"Output dir\", str(output_dir))\n    if final_dir.exists():\n        paths.add_row(\n            \"Final weights\",\n            f\"{final_dir}  [dim]({_dir_size_str(str(final_dir))})[/]\",\n        )\n    if log_dir:\n        paths.add_row(\"TensorBoard\", str(log_dir))\n\n    # -- Next steps -----------------------------------------------------------\n    hints = Text()\n    hints.append(\"\\n  Next steps:\\n\", style=\"bold\")\n    hints.append(\"  1. Use the adapter:  \", style=\"dim\")\n    hints.append(f\"load from {final_dir}\\n\")\n    if log_dir:\n        hints.append(\"  2. View metrics:  \", style=\"dim\")\n        hints.append(f\"tensorboard --logdir {log_dir}\\n\")\n    hints.append(\"  3. Generate music with the adapter via the Gradio UI\\n\", style=\"dim\")\n\n    # -- Assemble panel -------------------------------------------------------\n    parts = [table, Text(\"\")]\n    if ckpt_section is not None:\n        parts.extend([ckpt_section, Text(\"\")])\n    parts.extend([paths, hints])\n\n    console.print(\n        Panel(\n            Group(*parts),\n            title=\"[bold green]Training Complete[/]\",\n            border_style=\"green\",\n            padding=(0, 1),\n        )\n    )\n\n\ndef _build_checkpoint_grid(\n    stats: TrainingStats, output_dir: str,\n) -> Optional[Any]:\n    \"\"\"Build a 2-column grid of saved checkpoints, or None if there are none.\"\"\"\n    from rich.table import Table\n    from rich.text import Text\n\n    if not stats.checkpoints:\n        return None\n\n    header = Text(\"  Saved Checkpoints\", style=\"bold\")\n\n    grid = Table(\n        show_header=True, show_edge=False, box=None,\n        pad_edge=True, expand=True,\n    )\n    grid.add_column(\"Epoch\", style=\"bold cyan\", justify=\"right\", min_width=8)\n    grid.add_column(\"Loss\", min_width=10)\n    grid.add_column(\"Epoch\", style=\"bold cyan\", justify=\"right\", min_width=8)\n    grid.add_column(\"Loss\", min_width=10)\n\n    # Pair checkpoints into rows of 2\n    ckpts = stats.checkpoints\n    for i in range(0, len(ckpts), 2):\n        c1 = ckpts[i]\n        loss1 = f\"{c1['loss']:.4f}\" if c1[\"loss\"] > 0 else \"--\"\n        if i + 1 < len(ckpts):\n            c2 = ckpts[i + 1]\n            loss2 = f\"{c2['loss']:.4f}\" if c2[\"loss\"] > 0 else \"--\"\n            grid.add_row(\n                str(c1[\"epoch\"]), loss1,\n                str(c2[\"epoch\"]), loss2,\n            )\n        else:\n            grid.add_row(str(c1[\"epoch\"]), loss1, \"\", \"\")\n\n    from rich.console import Group\n    return Group(header, grid)\n\n\ndef _show_plain(\n    stats: TrainingStats,\n    output_dir: str,\n    log_dir: Optional[str],\n) -> None:\n    \"\"\"Plain-text fallback summary.\"\"\"\n    print(\"\\n\" + \"=\" * 60, file=sys.stderr)\n    print(\"  Training Complete\", file=sys.stderr)\n    print(\"=\" * 60, file=sys.stderr)\n    print(f\"  Total time .......... {stats.elapsed_str}\", file=sys.stderr)\n    print(f\"  Epochs .............. {stats.current_epoch} / {stats.max_epochs}\", file=sys.stderr)\n    print(f\"  Total steps ......... {stats.current_step}\", file=sys.stderr)\n\n    if stats.first_loss > 0:\n        print(f\"  Loss ................ {stats.first_loss:.4f} -> {stats.last_loss:.4f}\", file=sys.stderr)\n    if stats.best_loss < float(\"inf\"):\n        print(f\"  Best loss ........... {stats.best_loss:.4f}\", file=sys.stderr)\n    if stats.peak_vram_mb > 0:\n        print(f\"  Peak VRAM ........... {stats.peak_vram_mb / 1024:.1f} GiB\", file=sys.stderr)\n\n    # Checkpoints\n    if stats.checkpoints:\n        print(\"\\n  Saved Checkpoints:\", file=sys.stderr)\n        for c in stats.checkpoints:\n            loss_s = f\"{c['loss']:.4f}\" if c[\"loss\"] > 0 else \"--\"\n            print(f\"    Epoch {c['epoch']:>4}  Loss: {loss_s}\", file=sys.stderr)\n\n    print(f\"\\n  Output dir .......... {output_dir}\", file=sys.stderr)\n    final_dir = Path(output_dir) / \"final\"\n    if final_dir.exists():\n        print(f\"  Final weights ....... {final_dir}  ({_dir_size_str(str(final_dir))})\", file=sys.stderr)\n    if log_dir:\n        print(f\"  TensorBoard ......... {log_dir}\", file=sys.stderr)\n\n    print(\"=\" * 60 + \"\\n\", file=sys.stderr)\n"
  },
  {
    "path": "acestep/training_v2/ui/wizard.py",
    "content": "\"\"\"\nInteractive wizard for ACE-Step Training V2.\n\nLaunched when ``python train.py`` is run with no subcommand.  Provides a\nsession loop so the user can preprocess, train, manage presets, and access\nexperimental features without restarting.\n\nSubmenus are in ``wizard_menus.py``; flow builders are in ``flows*.py``.\n\"\"\"\n\nfrom __future__ import annotations\n\nimport argparse\nfrom typing import Generator, Optional\n\nfrom acestep.training_v2.ui import console, is_rich_active\nfrom acestep.training_v2.ui.prompt_helpers import GoBack, menu\nfrom acestep.training_v2.ui.flows import wizard_train, wizard_preprocess\nfrom acestep.training_v2.ui.wizard_menus import experimental_menu, manage_presets_menu, _print_msg\n\n\n# ---- First-run check -------------------------------------------------------\n\ndef _ensure_first_run_done() -> None:\n    \"\"\"Run the first-time setup wizard if settings don't exist yet.\"\"\"\n    from acestep.training_v2.settings import is_first_run, save_settings\n    from acestep.training_v2.ui.flows_setup import run_first_setup\n\n    if not is_first_run():\n        return\n\n    try:\n        data = run_first_setup()\n        save_settings(data)\n    except (KeyboardInterrupt, EOFError):\n        if is_rich_active() and console is not None:\n            console.print(\"\\n  [dim]Setup skipped. You can run it later from Settings.[/]\")\n        else:\n            print(\"\\n  Setup skipped. You can run it later from Settings.\")\n\n\n# ---- Session loop -----------------------------------------------------------\n\ndef run_wizard_session() -> Generator[argparse.Namespace, None, None]:\n    \"\"\"Launch the interactive wizard as a session loop.\n\n    Yields one ``argparse.Namespace`` per action the user selects.\n    The caller (``train.py:main()``) dispatches each, cleans up GPU,\n    and the loop shows the menu again.\n\n    After preprocessing, offers to chain directly into training.\n    \"\"\"\n    from acestep.training_v2.ui.banner import show_banner\n    from acestep.training_v2.ui.prompt_helpers import ask_bool\n\n    show_banner(subcommand=\"interactive\")\n\n    # First-run setup (skippable)\n    _ensure_first_run_done()\n\n    while True:\n        try:\n            ns = _main_menu()\n        except (KeyboardInterrupt, EOFError):\n            _print_abort()\n            return\n\n        if ns is None:\n            return  # user chose Exit\n\n        is_preprocess = getattr(ns, \"preprocess\", False)\n        tensor_output = getattr(ns, \"tensor_output\", None)\n\n        yield ns\n\n        # Flow chaining: after preprocess, offer to train on the output\n        if is_preprocess and tensor_output:\n            try:\n                _print_msg(\"\")\n                if ask_bool(\"Train on these tensors now?\", default=True):\n                    try:\n                        adapter = menu(\n                            \"Which adapter type?\",\n                            [(\"lora\", \"LoRA (PEFT)\"), (\"lokr\", \"LoKR (LyCORIS)\")],\n                            default=1,\n                        )\n                        chain_ns = wizard_train(\n                            mode=\"fixed\",\n                            adapter_type=adapter,\n                            preset={\"dataset_dir\": tensor_output},\n                        )\n                        yield chain_ns\n                    except GoBack:\n                        pass\n            except (KeyboardInterrupt, EOFError):\n                pass\n\n\n# ---- Main menu --------------------------------------------------------------\n\ndef _main_menu() -> Optional[argparse.Namespace]:\n    \"\"\"Show the main menu and return a Namespace, or None to exit.\n\n    Uses a loop instead of recursion to avoid hitting the stack limit\n    when the user navigates back and forth many times.\n    \"\"\"\n    while True:\n        action = menu(\n            \"What would you like to do?\",\n            [\n                (\"train_lora\", \"Train a LoRA (PEFT)\"),\n                (\"train_lokr\", \"Train a LoKR (LyCORIS)\"),\n                (\"preprocess\", \"Preprocess audio into tensors\"),\n                (\"presets\", \"Manage presets\"),\n                (\"settings\", \"Settings (paths, vanilla mode)\"),\n                (\"experimental\", \"Experimental (beta)\"),\n                (\"exit\", \"Exit\"),\n            ],\n            default=1,\n        )\n\n        if action == \"exit\":\n            return None\n\n        if action == \"presets\":\n            manage_presets_menu()\n            continue  # loop back to main menu\n\n        if action == \"settings\":\n            _run_settings_editor()\n            continue  # loop back to main menu\n\n        try:\n            if action == \"experimental\":\n                result = experimental_menu()\n                if result is None:\n                    continue  # user chose \"Back\" -> main menu\n                return result\n\n            if action == \"preprocess\":\n                return wizard_preprocess()\n\n            if action in (\"train_lora\", \"train_lokr\"):\n                adapter = \"lokr\" if action == \"train_lokr\" else \"lora\"\n                mode = _training_mode_submenu()\n                if mode is None:\n                    continue  # user chose \"Back\" -> main menu\n                return wizard_train(mode=mode, adapter_type=adapter)\n        except GoBack:\n            continue  # loop back to main menu\n\n\ndef _training_mode_submenu() -> Optional[str]:\n    \"\"\"Ask which training mode to use. Returns 'fixed' or 'vanilla', or None for back.\"\"\"\n    try:\n        choice = menu(\n            \"Which training mode?\",\n            [\n                (\"fixed\", \"Corrected (recommended -- continuous timesteps + CFG dropout)\"),\n                (\"vanilla\", \"Vanilla (original behavior -- discrete timesteps, no CFG)\"),\n            ],\n            default=1,\n            allow_back=True,\n        )\n        return choice\n    except GoBack:\n        return None\n\n\n# ---- Backward-compat shim --------------------------------------------------\n\ndef run_wizard() -> Optional[argparse.Namespace]:\n    \"\"\"Single-shot wizard (backward compatibility).\n\n    Returns the first Namespace from the session loop, or None.\n    \"\"\"\n    for ns in run_wizard_session():\n        return ns\n    return None\n\n\n# ---- Helpers ----------------------------------------------------------------\n\ndef _run_settings_editor() -> None:\n    \"\"\"Open the settings editor and save any changes.\"\"\"\n    from acestep.training_v2.settings import save_settings\n    from acestep.training_v2.ui.flows_setup import run_settings_editor\n\n    data = run_settings_editor()\n    if data is not None:\n        save_settings(data)\n\n\ndef _print_abort() -> None:\n    if is_rich_active() and console is not None:\n        console.print(\"\\n  [dim]Aborted.[/]\")\n    else:\n        print(\"\\n  Aborted.\")\n"
  },
  {
    "path": "acestep/training_v2/ui/wizard_menus.py",
    "content": "\"\"\"\nSubmenu implementations for the wizard session loop.\n\nExtracted from ``wizard.py`` to keep modules under the LOC cap.\n\"\"\"\n\nfrom __future__ import annotations\n\nimport argparse\nfrom typing import Optional\n\nfrom acestep.training_v2.ui import console, is_rich_active\nfrom acestep.training_v2.ui.prompt_helpers import GoBack, menu, section, ask\n\n\ndef experimental_menu() -> Optional[argparse.Namespace]:\n    \"\"\"Show experimental features and return a Namespace, or None to go back.\n\n    Uses a loop instead of recursion.  Returns None when the user\n    chooses 'Back', which the caller interprets as \"show main menu\".\n    \"\"\"\n    from acestep.training_v2.ui.flows import wizard_estimate\n\n    if is_rich_active() and console is not None:\n        console.print(\n            \"\\n  [dim]These features are functional but under active development.\\n\"\n            \"  Results may vary. Feedback welcome.[/]\"\n        )\n    else:\n        print(\n            \"\\n  These features are functional but under active development.\\n\"\n            \"  Results may vary. Feedback welcome.\"\n        )\n\n    while True:\n        action = menu(\n            \"Experimental Features\",\n            [\n                (\"estimate\", \"Gradient estimation (analyze which layers learn fastest)\"),\n                (\"back\", \"Back\"),\n            ],\n            default=2,\n        )\n\n        if action == \"back\":\n            return None  # caller loops back to main menu\n\n        if action == \"estimate\":\n            try:\n                return wizard_estimate()\n            except GoBack:\n                continue  # stay in experimental menu\n\n\ndef manage_presets_menu() -> None:\n    \"\"\"Submenu for listing, viewing, deleting, importing, and exporting presets.\"\"\"\n    from acestep.training_v2.ui.presets import (\n        list_presets, load_preset, delete_preset, import_preset, export_preset,\n    )\n\n    while True:\n        action = menu(\n            \"Manage Presets\",\n            [\n                (\"list\", \"List all presets\"),\n                (\"view\", \"View preset details\"),\n                (\"delete\", \"Delete a user preset\"),\n                (\"import\", \"Import preset from file\"),\n                (\"export\", \"Export preset to file\"),\n                (\"back\", \"Back\"),\n            ],\n            default=6,\n        )\n\n        if action == \"back\":\n            return\n\n        presets = list_presets()\n\n        if action == \"list\":\n            if not presets:\n                _print_msg(\"  No presets found.\")\n                continue\n            section(\"Available Presets\")\n            for p in presets:\n                tag = \" (built-in)\" if p[\"builtin\"] else \"\"\n                desc = f\" -- {p['description']}\" if p[\"description\"] else \"\"\n                _print_msg(f\"    {p['name']}{tag}{desc}\")\n            _print_msg(\"\")\n\n        elif action == \"view\":\n            if not presets:\n                _print_msg(\"  No presets found.\")\n                continue\n            name = ask(\"Preset name to view\", required=True)\n            data = load_preset(name)\n            if data is None:\n                _print_msg(f\"  Preset '{name}' not found.\")\n            else:\n                section(f\"Preset: {name}\")\n                for k, v in sorted(data.items()):\n                    _print_msg(f\"    {k}: {v}\")\n                _print_msg(\"\")\n\n        elif action == \"delete\":\n            user_presets = [p for p in presets if not p[\"builtin\"]]\n            if not user_presets:\n                _print_msg(\"  No user presets to delete.\")\n                continue\n            name = ask(\"Preset name to delete\", required=True)\n            if delete_preset(name):\n                _print_msg(f\"  Deleted preset '{name}'.\")\n            else:\n                _print_msg(f\"  Preset '{name}' not found (or is built-in).\")\n\n        elif action == \"import\":\n            path = ask(\"Path to preset JSON file\", required=True)\n            imported = import_preset(path)\n            if imported:\n                _print_msg(f\"  Imported preset '{imported}'.\")\n            else:\n                _print_msg(\"  Import failed. Check the file path and format.\")\n\n        elif action == \"export\":\n            name = ask(\"Preset name to export\", required=True)\n            dest = ask(\"Destination path\", required=True)\n            if export_preset(name, dest):\n                _print_msg(f\"  Exported '{name}' to {dest}.\")\n            else:\n                _print_msg(f\"  Preset '{name}' not found.\")\n\n\ndef _print_msg(msg: str) -> None:\n    \"\"\"Print a message using Rich if available, plain otherwise.\"\"\"\n    if is_rich_active() and console is not None:\n        # Strip Rich markup for plain fallback detection\n        console.print(msg)\n    else:\n        # Remove Rich markup tags for plain output\n        import re\n        clean = re.sub(r\"\\[/?[^\\]]*\\]\", \"\", msg)\n        print(clean)\n"
  },
  {
    "path": "acestep/ui/__init__.py",
    "content": "\"\"\"UI package intent: presentation layer and interaction wiring (no core business logic).\"\"\"\n"
  },
  {
    "path": "acestep/ui/gradio/__init__.py",
    "content": "\"\"\"Gradio package: web UI composition for ACE-Step controls and outputs.\"\"\"\nfrom acestep.ui.gradio.interfaces import create_gradio_interface  # noqa: F401\n"
  },
  {
    "path": "acestep/ui/gradio/api/__init__.py",
    "content": "\"\"\"UI API package: UI-facing route adapters and DTO helpers.\"\"\"\nfrom acestep.ui.gradio.api.api_routes import setup_api_routes  # noqa: F401\n"
  },
  {
    "path": "acestep/ui/gradio/api/api_routes.py",
    "content": "\"\"\"\nGradio API Routes Module\nAdd API endpoints compatible with api_server.py and CustomAceStep to Gradio application\n\"\"\"\nimport atexit\nimport json\nimport os\nimport random\nimport time\nfrom threading import Lock\nfrom typing import Any, Dict, List, Optional\nfrom uuid import uuid4\n\nfrom fastapi import APIRouter, HTTPException, Request, Depends, Header\nfrom fastapi.middleware.cors import CORSMiddleware\nfrom fastapi.responses import FileResponse\n\n# Global results directory inside project root\nPROJECT_ROOT = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))\nDEFAULT_RESULTS_DIR = os.path.join(PROJECT_ROOT, \"gradio_outputs\").replace(\"\\\\\", \"/\")\nos.makedirs(DEFAULT_RESULTS_DIR, exist_ok=True)\n\n# API Key storage (set via setup_api_routes)\n_api_key: Optional[str] = None\n_api_key_lock = Lock()\n\n\ndef set_api_key(key: Optional[str]):\n    \"\"\"Set the API key for authentication.\"\"\"\n    global _api_key\n    with _api_key_lock:\n        _api_key = key\n\n\ndef _get_api_key() -> Optional[str]:\n    \"\"\"Read the current API key under lock.\"\"\"\n    with _api_key_lock:\n        return _api_key\n\n\ndef _wrap_response(data: Any, code: int = 200, error: Optional[str] = None) -> Dict[str, Any]:\n    \"\"\"Wrap response data in standard format compatible with CustomAceStep.\"\"\"\n    return {\n        \"data\": data,\n        \"code\": code,\n        \"error\": error,\n        \"timestamp\": int(time.time() * 1000),\n        \"extra\": None,\n    }\n\n\ndef verify_token_from_request(body: dict, authorization: Optional[str] = None) -> Optional[str]:\n    \"\"\"\n    Verify API key from request body (ai_token) or Authorization header.\n    Returns the token if valid, None if no auth required.\n    \"\"\"\n    key = _get_api_key()\n    if key is None:\n        return None  # No auth required\n\n    # Try ai_token from body first\n    ai_token = body.get(\"ai_token\") if body else None\n    if ai_token:\n        if ai_token == key:\n            return ai_token\n        raise HTTPException(status_code=401, detail=\"Invalid ai_token\")\n\n    # Fallback to Authorization header\n    if authorization:\n        if authorization.startswith(\"Bearer \"):\n            token = authorization[7:]\n        else:\n            token = authorization\n        if token == key:\n            return token\n        raise HTTPException(status_code=401, detail=\"Invalid API key\")\n\n    # No token provided but auth is required\n    raise HTTPException(status_code=401, detail=\"Missing ai_token or Authorization header\")\n\n\nasync def verify_api_key(authorization: Optional[str] = Header(None)):\n    \"\"\"Verify API key from Authorization header (legacy, for non-body endpoints).\"\"\"\n    key = _get_api_key()\n    if key is None:\n        return  # No auth required\n\n    if not authorization:\n        raise HTTPException(status_code=401, detail=\"Missing Authorization header\")\n\n    # Support \"Bearer <key>\" format\n    if authorization.startswith(\"Bearer \"):\n        token = authorization[7:]\n    else:\n        token = authorization\n\n    if token != key:\n        raise HTTPException(status_code=401, detail=\"Invalid API key\")\n\n\n# Use diskcache to store results\ntry:\n    import diskcache\n    _cache_dir = os.path.join(os.path.dirname(__file__), \".cache\", \"api_results\")\n    os.makedirs(_cache_dir, exist_ok=True)\n    _result_cache = diskcache.Cache(_cache_dir)\n    DISKCACHE_AVAILABLE = True\nexcept ImportError:\n    _result_cache = {}\n    DISKCACHE_AVAILABLE = False\n\nRESULT_EXPIRE_SECONDS = 7 * 24 * 60 * 60  # 7 days expiration\nRESULT_KEY_PREFIX = \"ace_step_v1.5_\"\n_result_cache_lock = Lock()  # guards the plain-dict fallback when diskcache is unavailable\n\n\ndef _close_result_cache():\n    \"\"\"Close the diskcache backend so pending writes are flushed on shutdown.\"\"\"\n    if DISKCACHE_AVAILABLE and hasattr(_result_cache, \"close\"):\n        _result_cache.close()\n\n\natexit.register(_close_result_cache)\n\n# =============================================================================\n# Example Data for Random Sample\n# =============================================================================\n\ndef _get_project_root() -> str:\n    \"\"\"Get project root directory\"\"\"\n    return os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))\n\n\ndef _load_all_examples(sample_mode: str = \"simple_mode\") -> List[Dict[str, Any]]:\n    \"\"\"Load all example JSON files from examples directory\"\"\"\n    project_root = _get_project_root()\n    if sample_mode == \"simple_mode\":\n        examples_dir = os.path.join(project_root, \"examples\", \"simple_mode\")\n    else:\n        examples_dir = os.path.join(project_root, \"examples\", \"text2music\")\n\n    if not os.path.isdir(examples_dir):\n        return []\n\n    all_examples = []\n    for filename in os.listdir(examples_dir):\n        if filename.endswith(\".json\"):\n            filepath = os.path.join(examples_dir, filename)\n            try:\n                with open(filepath, \"r\", encoding=\"utf-8\") as f:\n                    data = json.load(f)\n                    if isinstance(data, list):\n                        all_examples.extend(data)\n                    elif isinstance(data, dict):\n                        all_examples.append(data)\n            except Exception:\n                pass\n    return all_examples\n\n\n# Pre-load example data\nSIMPLE_EXAMPLE_DATA = _load_all_examples(\"simple_mode\")\nCUSTOM_EXAMPLE_DATA = _load_all_examples(\"custom_mode\")\n\n\ndef store_result(task_id: str, result: dict, status: str = \"succeeded\"):\n    \"\"\"Store generation result keyed by *task_id*.\"\"\"\n    data = {\n        \"result\": result,\n        \"created_at\": time.time(),\n        \"status\": status,\n    }\n    key = f\"{RESULT_KEY_PREFIX}{task_id}\"\n    if DISKCACHE_AVAILABLE:\n        _result_cache.set(key, data, expire=RESULT_EXPIRE_SECONDS)\n    else:\n        with _result_cache_lock:\n            _result_cache[key] = data\n\n\ndef get_result(task_id: str) -> Optional[dict]:\n    \"\"\"Retrieve a stored generation result by *task_id*.\"\"\"\n    key = f\"{RESULT_KEY_PREFIX}{task_id}\"\n    if DISKCACHE_AVAILABLE:\n        return _result_cache.get(key)\n    with _result_cache_lock:\n        return _result_cache.get(key)\n\n\nrouter = APIRouter()\n\n\n@router.get(\"/health\")\nasync def health_check():\n    \"\"\"Health check endpoint\"\"\"\n    return _wrap_response({\n        \"status\": \"ok\",\n        \"service\": \"ACE-Step Gradio API\",\n        \"version\": \"1.0\",\n    })\n\n\n@router.get(\"/v1/models\")\nasync def list_models(request: Request, _: None = Depends(verify_api_key)):\n    \"\"\"List available DiT models\"\"\"\n    dit_handler = request.app.state.dit_handler\n\n    models = []\n    if dit_handler and dit_handler.model is not None:\n        # Get current loaded model name\n        config_path = getattr(dit_handler, 'config_path', '') or ''\n        model_name = os.path.basename(config_path.rstrip(\"/\\\\\")) if config_path else \"unknown\"\n        models.append({\n            \"name\": model_name,\n            \"is_default\": True,\n        })\n\n    return _wrap_response({\n        \"models\": models,\n        \"default_model\": models[0][\"name\"] if models else None,\n    })\n\n\n@router.get(\"/v1/audio\")\nasync def get_audio(path: str, _: None = Depends(verify_api_key)):\n    \"\"\"Download audio file\"\"\"\n    # Security: Validate path is within allowed directory to prevent path traversal\n    resolved_path = os.path.realpath(path)\n    allowed_dir = os.path.realpath(DEFAULT_RESULTS_DIR)\n    if not resolved_path.startswith(allowed_dir + os.sep) and resolved_path != allowed_dir:\n        raise HTTPException(status_code=403, detail=\"Access denied: path outside allowed directory\")\n    if not os.path.exists(resolved_path):\n        raise HTTPException(status_code=404, detail=\"Audio file not found\")\n\n    ext = os.path.splitext(resolved_path)[1].lower()\n    media_types = {\n        \".mp3\": \"audio/mpeg\",\n        \".wav\": \"audio/wav\",\n        \".flac\": \"audio/flac\",\n        \".ogg\": \"audio/ogg\",\n    }\n    media_type = media_types.get(ext, \"audio/mpeg\")\n\n    return FileResponse(resolved_path, media_type=media_type)\n\n\n@router.post(\"/create_random_sample\")\nasync def create_random_sample(request: Request, authorization: Optional[str] = Header(None)):\n    \"\"\"Get random sample parameters from pre-loaded example data\"\"\"\n    content_type = (request.headers.get(\"content-type\") or \"\").lower()\n\n    if \"json\" in content_type:\n        body = await request.json()\n    else:\n        form = await request.form()\n        body = {k: v for k, v in form.items()}\n\n    verify_token_from_request(body, authorization)\n    sample_type = body.get(\"sample_type\", \"simple_mode\") or \"simple_mode\"\n\n    if sample_type == \"simple_mode\":\n        example_data = SIMPLE_EXAMPLE_DATA\n    else:\n        example_data = CUSTOM_EXAMPLE_DATA\n\n    if not example_data:\n        return _wrap_response(None, code=500, error=\"No example data available\")\n\n    random_example = random.choice(example_data)\n    return _wrap_response(random_example)\n\n\n@router.post(\"/query_result\")\nasync def query_result(request: Request, authorization: Optional[str] = Header(None)):\n    \"\"\"Batch query task results\"\"\"\n    content_type = (request.headers.get(\"content-type\") or \"\").lower()\n\n    if \"json\" in content_type:\n        body = await request.json()\n    else:\n        form = await request.form()\n        body = {k: v for k, v in form.items()}\n\n    verify_token_from_request(body, authorization)\n    task_ids = body.get(\"task_id_list\", [])\n\n    if isinstance(task_ids, str):\n        try:\n            task_ids = json.loads(task_ids)\n        except Exception:\n            task_ids = []\n\n    results = []\n    for task_id in task_ids:\n        data = get_result(task_id)\n        if data and data.get(\"status\") == \"succeeded\":\n            results.append({\n                \"task_id\": task_id,\n                \"status\": 1,\n                \"result\": json.dumps(data[\"result\"], ensure_ascii=False)\n            })\n        else:\n            results.append({\n                \"task_id\": task_id,\n                \"status\": 0,\n                \"result\": \"[]\"\n            })\n\n    return _wrap_response(results)\n\n\n@router.post(\"/format_input\")\nasync def format_input(request: Request, authorization: Optional[str] = Header(None)):\n    \"\"\"Format and enhance lyrics/caption via LLM\"\"\"\n    llm_handler = request.app.state.llm_handler\n\n    if not llm_handler or not llm_handler.llm_initialized:\n        return _wrap_response(None, code=500, error=\"LLM not initialized\")\n\n    content_type = (request.headers.get(\"content-type\") or \"\").lower()\n    if \"json\" in content_type:\n        body = await request.json()\n    else:\n        form = await request.form()\n        body = {k: v for k, v in form.items()}\n\n    verify_token_from_request(body, authorization)\n\n    caption = body.get(\"prompt\", \"\") or \"\"\n    lyrics = body.get(\"lyrics\", \"\") or \"\"\n    temperature = float(body.get(\"temperature\", 0.85))\n\n    from acestep.inference import format_sample\n\n    try:\n        result = format_sample(\n            llm_handler=llm_handler,\n            caption=caption,\n            lyrics=lyrics,\n            temperature=temperature,\n            use_constrained_decoding=True,\n        )\n\n        if not result.success:\n            return _wrap_response(None, code=500, error=result.status_message)\n\n        return _wrap_response({\n            \"caption\": result.caption or caption,\n            \"lyrics\": result.lyrics or lyrics,\n            \"bpm\": result.bpm,\n            \"key_scale\": result.keyscale,\n            \"time_signature\": result.timesignature,\n            \"duration\": result.duration,\n            \"vocal_language\": result.language or \"unknown\",\n        })\n    except Exception as e:\n        return _wrap_response(None, code=500, error=str(e))\n\n\n@router.post(\"/release_task\")\nasync def release_task(request: Request, authorization: Optional[str] = Header(None)):\n    \"\"\"Create music generation task\"\"\"\n    dit_handler = request.app.state.dit_handler\n    llm_handler = request.app.state.llm_handler\n\n    if not dit_handler or dit_handler.model is None:\n        raise HTTPException(status_code=500, detail=\"DiT model not initialized\")\n\n    content_type = (request.headers.get(\"content-type\") or \"\").lower()\n    if \"json\" in content_type:\n        body = await request.json()\n    else:\n        form = await request.form()\n        body = {k: v for k, v in form.items()}\n\n    verify_token_from_request(body, authorization)\n    task_id = str(uuid4())\n\n    from acestep.inference import generate_music, GenerationParams, GenerationConfig, create_sample, format_sample\n\n    # Parse param_obj if provided\n    param_obj = body.get(\"param_obj\", {})\n    if isinstance(param_obj, str):\n        try:\n            param_obj = json.loads(param_obj)\n        except Exception:\n            param_obj = {}\n\n    # Helper to get param with aliases\n    def get_param(key, *aliases, default=None):\n        for k in [key] + list(aliases):\n            if k in body and body[k] is not None:\n                return body[k]\n            if k in param_obj and param_obj[k] is not None:\n                return param_obj[k]\n        return default\n\n    def to_bool(val, default=False):\n        if val is None:\n            return default\n        if isinstance(val, bool):\n            return val\n        if isinstance(val, str):\n            return val.lower() in (\"true\", \"1\", \"yes\")\n        return bool(val)\n\n    try:\n        # Get sample_mode and sample_query parameters\n        sample_mode = to_bool(get_param(\"sample_mode\", \"sampleMode\"), False)\n        sample_query = get_param(\"sample_query\", \"sampleQuery\", \"description\", \"desc\", default=\"\") or \"\"\n        use_format = to_bool(get_param(\"use_format\", \"useFormat\"), False)\n        has_sample_query = bool(sample_query and sample_query.strip())\n\n        # Get base parameters\n        caption = get_param(\"prompt\", \"caption\", default=\"\") or \"\"\n        lyrics = get_param(\"lyrics\", default=\"\") or \"\"\n        vocal_language = get_param(\"vocal_language\", \"language\", default=\"en\") or \"en\"\n        lm_temperature = float(get_param(\"lm_temperature\", \"temperature\", default=0.85) or 0.85)\n\n        # Process sample_mode: use LLM to auto-generate caption/lyrics/metas\n        if sample_mode or has_sample_query:\n            if not llm_handler or not llm_handler.llm_initialized:\n                raise HTTPException(status_code=500, detail=\"sample_mode requires LLM to be initialized\")\n\n            query = sample_query if has_sample_query else \"NO USER INPUT\"\n            sample_result = create_sample(\n                llm_handler=llm_handler,\n                query=query,\n                vocal_language=vocal_language if vocal_language not in (\"en\", \"unknown\", \"\") else None,\n                temperature=lm_temperature,\n            )\n\n            if not sample_result.success:\n                raise HTTPException(status_code=500, detail=sample_result.error or sample_result.status_message)\n\n            # Use generated values\n            caption = sample_result.caption or caption\n            lyrics = sample_result.lyrics or lyrics\n            # Override metas from sample result if available\n            sample_bpm = sample_result.bpm\n            sample_duration = sample_result.duration\n            sample_keyscale = sample_result.keyscale\n            sample_timesignature = sample_result.timesignature\n            sample_language = sample_result.language or vocal_language\n        else:\n            sample_bpm = None\n            sample_duration = None\n            sample_keyscale = None\n            sample_timesignature = None\n            sample_language = vocal_language\n\n        # Process use_format: enhance caption/lyrics via LLM\n        if use_format and not sample_mode and not has_sample_query:\n            if llm_handler and llm_handler.llm_initialized:\n                format_result = format_sample(\n                    llm_handler=llm_handler,\n                    caption=caption,\n                    lyrics=lyrics,\n                    temperature=lm_temperature,\n                )\n                if format_result.success:\n                    caption = format_result.caption or caption\n                    lyrics = format_result.lyrics or lyrics\n                    if format_result.bpm:\n                        sample_bpm = format_result.bpm\n                    if format_result.duration:\n                        sample_duration = format_result.duration\n                    if format_result.keyscale:\n                        sample_keyscale = format_result.keyscale\n                    if format_result.timesignature:\n                        sample_timesignature = format_result.timesignature\n                    if format_result.language:\n                        sample_language = format_result.language\n\n        # Build generation params with alias support\n        params = GenerationParams(\n            task_type=get_param(\"task_type\", default=\"text2music\"),\n            caption=caption,\n            lyrics=lyrics,\n            bpm=sample_bpm or get_param(\"bpm\"),\n            keyscale=sample_keyscale or get_param(\"key_scale\", \"keyscale\", \"key\", default=\"\"),\n            timesignature=sample_timesignature or get_param(\"time_signature\", \"timesignature\", default=\"\"),\n            duration=sample_duration or get_param(\"audio_duration\", \"duration\", default=-1),\n            vocal_language=sample_language,\n            inference_steps=get_param(\"inference_steps\", default=8),\n            guidance_scale=float(get_param(\"guidance_scale\", default=7.0) or 7.0),\n            seed=int(get_param(\"seed\", default=-1) or -1),\n            thinking=to_bool(get_param(\"thinking\"), False),\n            lm_temperature=lm_temperature,\n            lm_cfg_scale=float(get_param(\"lm_cfg_scale\", default=2.0) or 2.0),\n            lm_negative_prompt=get_param(\"lm_negative_prompt\", default=\"NO USER INPUT\") or \"NO USER INPUT\",\n            repaint_latent_crossfade_frames=int(\n                get_param(\"repaint_latent_crossfade_frames\", default=10) or 10,\n            ),\n            repaint_wav_crossfade_sec=float(\n                get_param(\"repaint_wav_crossfade_sec\", default=0.0) or 0.0,\n            ),\n            repaint_mode=get_param(\"repaint_mode\", default=\"balanced\") or \"balanced\",\n            repaint_strength=float(\n                get_param(\"repaint_strength\", default=0.5) or 0.5,\n            ),\n        )\n\n        # Resolve seed(s) into List[int] for GenerationConfig.seeds\n        use_random_seed = get_param(\"use_random_seed\", default=True)\n        resolved_seeds = None\n        if not use_random_seed:\n            raw_seed = get_param(\"seed\", default=-1)\n            if isinstance(raw_seed, str) and raw_seed.strip():\n                resolved_seeds = []\n                for s in raw_seed.split(\",\"):\n                    s = s.strip()\n                    if s and s != \"-1\":\n                        try:\n                            resolved_seeds.append(int(float(s)))\n                        except (ValueError, TypeError):\n                            pass\n                if not resolved_seeds:\n                    resolved_seeds = None\n            elif isinstance(raw_seed, (int, float)) and int(raw_seed) >= 0:\n                resolved_seeds = [int(raw_seed)]\n\n        config = GenerationConfig(\n            batch_size=get_param(\"batch_size\", default=2),\n            use_random_seed=use_random_seed,\n            seeds=resolved_seeds,\n            audio_format=get_param(\"audio_format\", default=\"flac\"),\n        )\n\n        # Get output directory\n        save_dir = os.path.join(DEFAULT_RESULTS_DIR, f\"api_{int(time.time())}\").replace(\"\\\\\", \"/\")\n        os.makedirs(save_dir, exist_ok=True)\n\n        # Call generation function\n        result = generate_music(\n            dit_handler=dit_handler,\n            llm_handler=llm_handler if llm_handler and llm_handler.llm_initialized else None,\n            params=params,\n            config=config,\n            save_dir=save_dir,\n        )\n\n        if not result.success:\n            raise HTTPException(status_code=500, detail=result.error or result.status_message)\n\n        # Build result data with download URLs and per-audio metadata.\n        # Each audio in result.audios carries a \"params\" dict from GenerationParams\n        # which includes the actual seed used, caption, bpm, keyscale, etc.\n        from urllib.parse import urlencode\n        result_data = []\n        for audio in result.audios:\n            audio_path = audio.get(\"path\", \"\")\n            if not audio_path:\n                continue\n            audio_params = audio.get(\"params\", {})\n\n            # Prefer CoT-derived metadata (model's actual decision) over input hints\n            item = {\n                \"file\": audio_path,\n                \"url\": f\"/v1/audio?{urlencode({'path': audio_path})}\",\n                \"status\": 1,\n                \"create_time\": int(time.time()),\n                # Per-audio generation metadata\n                \"seed\": audio_params.get(\"seed\"),\n                \"caption\": audio_params.get(\"cot_caption\") or audio_params.get(\"caption\", \"\"),\n                \"lyrics\": audio_params.get(\"cot_lyrics\") or audio_params.get(\"lyrics\", \"\"),\n                \"bpm\": audio_params.get(\"cot_bpm\") or audio_params.get(\"bpm\"),\n                \"duration\": audio_params.get(\"cot_duration\") or audio_params.get(\"duration\"),\n                \"keyscale\": audio_params.get(\"cot_keyscale\") or audio_params.get(\"keyscale\", \"\"),\n                \"timesignature\": audio_params.get(\"cot_timesignature\") or audio_params.get(\"timesignature\", \"\"),\n                \"vocal_language\": audio_params.get(\"cot_vocal_language\") or audio_params.get(\"vocal_language\", \"\"),\n            }\n            result_data.append(item)\n\n        # Store result\n        store_result(task_id, result_data)\n\n        return _wrap_response({\"task_id\": task_id, \"status\": \"succeeded\"})\n\n    except HTTPException:\n        raise\n    except Exception as e:\n        raise HTTPException(status_code=500, detail=str(e))\n\n\n# Origins that are expected to call the API:\n#  - \"null\"                     → studio.html opened via file:// protocol\n#  - http://localhost:*         → local dev servers / Gradio UI\n#  - http://127.0.0.1:*        → same, numeric form\n_CORS_KWARGS = dict(\n    allow_origins=[\"null\", \"http://localhost\", \"http://127.0.0.1\"],\n    allow_origin_regex=r\"^https?://(localhost|127\\.0\\.0\\.1)(:\\d+)?$\",\n    allow_methods=[\"GET\", \"POST\", \"OPTIONS\"],\n    allow_headers=[\"Content-Type\", \"Authorization\"],\n)\n\n\ndef _add_cors_middleware(app):\n    \"\"\"Add CORS middleware so browser-based frontends (e.g. studio.html via file://) can call the API.\"\"\"\n    app.add_middleware(CORSMiddleware, **_CORS_KWARGS)\n\n\ndef _add_cors_middleware_post_launch(app):\n    \"\"\"Wrap an already-started app's middleware stack with CORS.\n\n    ``add_middleware`` raises after Starlette has started, so we patch the\n    compiled middleware stack directly instead.\n    \"\"\"\n    from starlette.middleware.cors import CORSMiddleware as _CORSImpl\n\n    if app.middleware_stack is not None:\n        app.middleware_stack = _CORSImpl(app=app.middleware_stack, **_CORS_KWARGS)\n    else:\n        # App hasn't built its stack yet – safe to use the normal path\n        _add_cors_middleware(app)\n\n\ndef setup_api_routes_to_app(app, dit_handler, llm_handler, api_key: Optional[str] = None):\n    \"\"\"\n    Mount API routes to a FastAPI application (for use with gr.mount_gradio_app)\n\n    Args:\n        app: FastAPI application instance\n        dit_handler: DiT handler\n        llm_handler: LLM handler\n        api_key: Optional API key for authentication\n    \"\"\"\n    set_api_key(api_key)\n    _add_cors_middleware(app)\n    app.state.dit_handler = dit_handler\n    app.state.llm_handler = llm_handler\n    app.include_router(router)\n\n\ndef setup_api_routes(demo, dit_handler, llm_handler, api_key: Optional[str] = None):\n    \"\"\"\n    Mount API routes to Gradio application\n\n    Args:\n        demo: Gradio Blocks instance\n        dit_handler: DiT handler\n        llm_handler: LLM handler\n        api_key: Optional API key for authentication\n    \"\"\"\n    set_api_key(api_key)\n    app = demo.app\n    _add_cors_middleware_post_launch(app)\n    app.state.dit_handler = dit_handler\n    app.state.llm_handler = llm_handler\n    app.include_router(router)\n\n"
  },
  {
    "path": "acestep/ui/gradio/api/api_routes_resource_test.py",
    "content": "\"\"\"Tests for resource cleanup in api_routes module.\"\"\"\n\nimport unittest\nfrom unittest import mock\n\n\nclass ApiRoutesResourceCleanupTests(unittest.TestCase):\n    \"\"\"Verify atexit cleanup for the diskcache result cache.\"\"\"\n\n    def test_close_result_cache_calls_close_when_diskcache_available(self):\n        \"\"\"_close_result_cache should call .close() on the diskcache backend.\"\"\"\n\n        from acestep.ui.gradio.api.api_routes import _close_result_cache\n\n        fake_cache = mock.MagicMock()\n        with mock.patch(\n            \"acestep.ui.gradio.api.api_routes._result_cache\", fake_cache\n        ), mock.patch(\n            \"acestep.ui.gradio.api.api_routes.DISKCACHE_AVAILABLE\", True\n        ):\n            _close_result_cache()\n        fake_cache.close.assert_called_once()\n\n    def test_close_result_cache_skips_when_diskcache_unavailable(self):\n        \"\"\"_close_result_cache should be a no-op when diskcache is not installed.\"\"\"\n\n        from acestep.ui.gradio.api.api_routes import _close_result_cache\n\n        fake_dict = {}\n        with mock.patch(\n            \"acestep.ui.gradio.api.api_routes._result_cache\", fake_dict\n        ), mock.patch(\n            \"acestep.ui.gradio.api.api_routes.DISKCACHE_AVAILABLE\", False\n        ):\n            # Should not raise\n            _close_result_cache()\n\n    def test_atexit_registered(self):\n        \"\"\"_close_result_cache should be registered with atexit.\"\"\"\n\n        import atexit\n\n        from acestep.ui.gradio.api.api_routes import _close_result_cache\n\n        # atexit._run_exitfuncs is CPython internal; instead verify registration\n        # by checking the function is importable and callable (registration happens\n        # at module load time via atexit.register at module level)\n        self.assertTrue(callable(_close_result_cache))\n\n\nif __name__ == \"__main__\":\n    unittest.main()\n"
  },
  {
    "path": "acestep/ui/gradio/api/api_routes_thread_safety_test.py",
    "content": "\"\"\"Thread safety tests for api_routes globals.\"\"\"\n\nimport threading\nimport unittest\n\nfrom acestep.ui.gradio.api.api_routes import (\n    _api_key_lock,\n    _result_cache_lock,\n    set_api_key,\n    _get_api_key,\n    store_result,\n    get_result,\n    DISKCACHE_AVAILABLE,\n)\n\n\nclass ApiKeyLockTests(unittest.TestCase):\n    \"\"\"Verify _api_key reads and writes are synchronized.\"\"\"\n\n    def test_lock_attributes_exist(self):\n        \"\"\"Module-level locks must be present.\"\"\"\n        self.assertIsInstance(_api_key_lock, type(threading.Lock()))\n        self.assertIsInstance(_result_cache_lock, type(threading.Lock()))\n\n    def test_set_and_get_api_key_consistent(self):\n        \"\"\"Concurrent set/get of api_key must not lose updates.\"\"\"\n        set_api_key(None)\n        barrier = threading.Barrier(4)\n        errors: list[str] = []\n\n        def _writer(value: str) -> None:\n            \"\"\"Set api_key after barrier synchronization.\"\"\"\n            try:\n                barrier.wait(timeout=5)\n                set_api_key(value)\n            except Exception as exc:  # noqa: BLE001\n                errors.append(f\"writer failed: {exc!r}\")\n\n        def _reader() -> None:\n            \"\"\"Read api_key after barrier synchronization.\"\"\"\n            try:\n                barrier.wait(timeout=5)\n                key = _get_api_key()\n                if key is not None and key not in (\"key-a\", \"key-b\"):\n                    errors.append(f\"unexpected key value: {key}\")\n            except Exception as exc:  # noqa: BLE001\n                errors.append(f\"reader failed: {exc!r}\")\n\n        threads = [\n            threading.Thread(target=_writer, args=(\"key-a\",)),\n            threading.Thread(target=_writer, args=(\"key-b\",)),\n            threading.Thread(target=_reader),\n            threading.Thread(target=_reader),\n        ]\n        for t in threads:\n            t.start()\n        for t in threads:\n            t.join()\n\n        self.assertEqual(errors, [], f\"Race condition detected: {errors}\")\n        # Final value must be one of the two written keys\n        final = _get_api_key()\n        self.assertIn(final, (\"key-a\", \"key-b\"))\n        # Clean up\n        set_api_key(None)\n\n\nclass ResultCacheFallbackTests(unittest.TestCase):\n    \"\"\"Verify dict-fallback cache path is thread-safe.\"\"\"\n\n    @unittest.skipIf(DISKCACHE_AVAILABLE, \"Test targets dict fallback only\")\n    def test_concurrent_store_and_get(self):\n        \"\"\"Concurrent store/get on dict fallback must not raise.\"\"\"\n        barrier = threading.Barrier(8)\n        errors: list[str] = []\n\n        def _store(idx: int) -> None:\n            \"\"\"Store a result after barrier synchronization.\"\"\"\n            try:\n                barrier.wait(timeout=5)\n                store_result(f\"task-{idx}\", {\"idx\": idx})\n            except Exception as exc:  # noqa: BLE001\n                errors.append(f\"store failed: {exc!r}\")\n\n        def _get(idx: int) -> None:\n            \"\"\"Retrieve a result after barrier synchronization.\"\"\"\n            try:\n                barrier.wait(timeout=5)\n                get_result(f\"task-{idx}\")\n            except Exception as exc:  # noqa: BLE001\n                errors.append(f\"get failed: {exc!r}\")\n\n        threads = []\n        for i in range(4):\n            threads.append(threading.Thread(target=_store, args=(i,)))\n            threads.append(threading.Thread(target=_get, args=(i,)))\n        for t in threads:\n            t.start()\n        for t in threads:\n            t.join()\n\n        self.assertEqual(errors, [])\n\n\nif __name__ == \"__main__\":\n    unittest.main()\n"
  },
  {
    "path": "acestep/ui/gradio/events/__init__.py",
    "content": "\"\"\"\nGradio UI Event Handlers Module\nMain entry point for setting up all event handlers\n\"\"\"\n# Import handler modules\nfrom .wiring import (\n    GenerationWiringContext,\n    TrainingWiringContext,\n    build_mode_ui_outputs,\n    register_generation_batch_navigation_handlers,\n    register_generation_metadata_file_handlers,\n    register_generation_metadata_handlers,\n    register_generation_mode_handlers,\n    register_generation_run_handlers,\n    register_results_aux_handlers,\n    register_results_restore_and_lrc_handlers,\n    register_results_save_button_handlers,\n    register_generation_service_handlers,\n    register_training_dataset_builder_handlers,\n    register_training_dataset_load_handler,\n    register_training_preprocess_handler,\n    register_training_run_handlers,\n)\n\n\ndef setup_event_handlers(demo, dit_handler, llm_handler, dataset_handler, dataset_section, generation_section, results_section):\n    \"\"\"Setup generation/results event wiring for the Gradio UI.\n\n    Args:\n        demo (Any): Root Gradio demo/container used to register events.\n        dit_handler (Any): Inference service used by generation/results callbacks.\n        llm_handler (Any): LLM service used by metadata/text callbacks.\n        dataset_handler (Any): Dataset service used by generation wiring.\n        dataset_section (dict[str, Any]): Dataset UI component map.\n        generation_section (dict[str, Any]): Generation UI component map.\n        results_section (dict[str, Any]): Results UI component map.\n\n    Local wiring values:\n        wiring_context (GenerationWiringContext): Shared typed context for\n            generation/results wiring helper modules.\n        auto_checkbox_inputs (list[Any]): Ordered metadata fields used for\n            auto-checkbox synchronization; forwarded to\n            register_generation_metadata_handlers and\n            register_generation_mode_handlers.\n        auto_checkbox_outputs (list[Any]): Ordered auto toggles plus derived\n            metadata outputs returned by register_generation_service_handlers;\n            forwarded to register_generation_metadata_handlers and\n            register_generation_mode_handlers.\n        mode_ui_outputs (list[Any]): Ordered mode-UI outputs from\n            build_mode_ui_outputs; forwarded to\n            register_generation_mode_handlers and register_results_aux_handlers.\n\n    Returns:\n        None: Registers event handlers in-place on the supplied components.\n    \"\"\"\n    wiring_context = GenerationWiringContext(\n        demo=demo,\n        dit_handler=dit_handler,\n        llm_handler=llm_handler,\n        dataset_handler=dataset_handler,\n        dataset_section=dataset_section,\n        generation_section=generation_section,\n        results_section=results_section,\n    )\n    \n    auto_checkbox_inputs, auto_checkbox_outputs = register_generation_service_handlers(\n        wiring_context\n    )\n    mode_ui_outputs = build_mode_ui_outputs(wiring_context)\n    register_generation_metadata_handlers(\n        wiring_context,\n        auto_checkbox_inputs=auto_checkbox_inputs,\n        auto_checkbox_outputs=auto_checkbox_outputs,\n    )\n\n    register_generation_mode_handlers(\n        wiring_context,\n        mode_ui_outputs=mode_ui_outputs,\n        auto_checkbox_inputs=auto_checkbox_inputs,\n        auto_checkbox_outputs=auto_checkbox_outputs,\n    )\n\n    register_generation_metadata_file_handlers(\n        wiring_context,\n        auto_checkbox_inputs=auto_checkbox_inputs,\n        auto_checkbox_outputs=auto_checkbox_outputs,\n    )\n    register_results_save_button_handlers(wiring_context)\n    register_results_aux_handlers(\n        wiring_context,\n        mode_ui_outputs=mode_ui_outputs,\n    )\n    register_generation_run_handlers(wiring_context)\n    register_generation_batch_navigation_handlers(wiring_context)\n    register_results_restore_and_lrc_handlers(wiring_context)\n\n\ndef setup_training_event_handlers(demo, dit_handler, llm_handler, training_section):\n    \"\"\"Setup event handlers for the training tab (dataset builder and LoRA training)\"\"\"\n    training_context = TrainingWiringContext(\n        demo=demo,\n        dit_handler=dit_handler,\n        llm_handler=llm_handler,\n        training_section=training_section,\n    )\n    \n    # ========== Load Existing Dataset (Top Section) ==========\n\n    # Load existing dataset JSON at the top of Dataset Builder\n    register_training_dataset_load_handler(\n        training_context,\n        button_key=\"load_json_btn\",\n        path_key=\"load_json_path\",\n        status_key=\"load_json_status\",\n    )\n    # ========== Dataset Builder Handlers ==========\n    register_training_dataset_builder_handlers(training_context)\n\n    # ========== Preprocess Handlers ==========\n    \n    # Load existing dataset JSON for preprocessing\n    # This also updates the preview section so users can view/edit samples\n    register_training_dataset_load_handler(\n        training_context,\n        button_key=\"load_existing_dataset_btn\",\n        path_key=\"load_existing_dataset_path\",\n        status_key=\"load_existing_status\",\n    )\n    \n    # Preprocess dataset to tensor files\n    register_training_preprocess_handler(training_context)\n    register_training_run_handlers(training_context)\n"
  },
  {
    "path": "acestep/ui/gradio/events/generation/__init__.py",
    "content": "\"\"\"Generation handlers sub-package.\n\nRe-exports all public symbols so callers can import from\n``acestep.ui.gradio.events.generation`` directly.\n\"\"\"\n\nfrom .validation import (\n    clamp_duration_to_gpu_limit,\n    parse_and_validate_timesteps,\n    _has_reference_audio,\n    _extract_audio_path,\n    validate_uploaded_audio_file,\n    _contains_audio_code_tokens,\n)\nfrom .metadata_loading import (\n    load_metadata,\n    load_random_example,\n    sample_example_smart,\n    load_random_simple_description,\n)\nfrom .service_init import (\n    refresh_checkpoints,\n    init_service_wrapper,\n    on_tier_change,\n)\nfrom .model_config import (\n    is_pure_base_model,\n    is_sft_model,\n    update_model_type_settings,\n    get_ui_control_config,\n    get_model_type_ui_settings,\n    get_generation_mode_choices,\n)\nfrom .mode_ui import (\n    compute_mode_ui_updates,\n    handle_generation_mode_change,\n    handle_extract_track_name_change,\n    handle_extract_src_audio_change,\n)\nfrom .llm_actions import (\n    handle_create_sample,\n    handle_format_sample,\n    handle_format_caption,\n    handle_format_lyrics,\n    transcribe_audio_codes,\n    analyze_src_audio,\n)\nfrom .ui_helpers import (\n    update_negative_prompt_visibility,\n    on_auto_checkbox_change,\n    reset_all_auto,\n    uncheck_auto_for_populated_fields,\n    update_audio_cover_strength_visibility,\n    convert_src_audio_to_codes_wrapper,\n    update_instruction_ui,\n    update_transcribe_button_text,\n    reset_format_caption_flag,\n    update_audio_uploads_accordion,\n    handle_instrumental_checkbox,\n    handle_simple_instrumental_change,\n    update_audio_components_visibility,\n)\n"
  },
  {
    "path": "acestep/ui/gradio/events/generation/llm_action_params.py",
    "content": "\"\"\"Shared parameter-normalization helpers for generation LLM actions.\"\"\"\nfrom typing import Any, Dict, Optional, Tuple, Union\n\n\ndef _parse_positive_duration_seconds(value: Optional[Union[float, int, str]]) -> Optional[int]:\n    \"\"\"Parse optional duration input and return positive whole seconds.\"\"\"\n    if value is None:\n        return None\n    try:\n        duration_value = float(value)\n    except (TypeError, ValueError):\n        return None\n    if duration_value <= 0:\n        return None\n    return int(duration_value)\n\n\ndef build_user_metadata(\n    bpm: Optional[Union[int, float]],\n    audio_duration: Optional[Union[float, int, str]],\n    key_scale: Optional[str],\n    time_signature: Optional[str],\n) -> Optional[Dict[str, Any]]:\n    \"\"\"Build constrained-decoding metadata from optional manual inputs.\"\"\"\n    user_metadata: Dict[str, Any] = {}\n    if bpm is not None and bpm > 0:\n        user_metadata[\"bpm\"] = int(bpm)\n    parsed_duration = _parse_positive_duration_seconds(audio_duration)\n    if parsed_duration is not None:\n        user_metadata[\"duration\"] = parsed_duration\n    if key_scale and key_scale.strip():\n        user_metadata[\"keyscale\"] = key_scale.strip()\n    if time_signature and time_signature.strip():\n        user_metadata[\"timesignature\"] = time_signature.strip()\n    return user_metadata if user_metadata else None\n\n\ndef convert_lm_params(\n    lm_top_k: Optional[Union[int, float]],\n    lm_top_p: Optional[float],\n) -> Tuple[Optional[int], Optional[float]]:\n    \"\"\"Convert UI LM controls to inference-compatible top-k/top-p values.\"\"\"\n    top_k_value = None if lm_top_k is None or lm_top_k == 0 else int(lm_top_k)\n    top_p_value = None if lm_top_p is None or lm_top_p >= 1.0 else float(lm_top_p)\n    return top_k_value, top_p_value\n"
  },
  {
    "path": "acestep/ui/gradio/events/generation/llm_actions.py",
    "content": "\"\"\"LLM generation action facade.\n\nThis module preserves the historical import path while delegating\nimplementation to focused sub-modules.\n\"\"\"\n\nfrom .llm_analysis_actions import analyze_src_audio, transcribe_audio_codes\nfrom .llm_format_actions import (\n    handle_format_caption,\n    handle_format_lyrics,\n    handle_format_sample,\n)\nfrom .llm_sample_actions import handle_create_sample\n\n__all__ = [\n    \"analyze_src_audio\",\n    \"handle_create_sample\",\n    \"handle_format_caption\",\n    \"handle_format_lyrics\",\n    \"handle_format_sample\",\n    \"transcribe_audio_codes\",\n]\n"
  },
  {
    "path": "acestep/ui/gradio/events/generation/llm_analysis_actions.py",
    "content": "\"\"\"Audio-code analysis and transcription actions for generation handlers.\n\nThis module contains source-audio analysis and audio-code transcription\nentry points used by the Gradio generation UI.\n\"\"\"\n\nimport gradio as gr\n\nfrom acestep.inference import understand_music\nfrom acestep.ui.gradio.i18n import t\n\nfrom .validation import _contains_audio_code_tokens, clamp_duration_to_gpu_limit\n\n\ndef analyze_src_audio(\n    dit_handler,\n    llm_handler,\n    src_audio,\n    constrained_decoding_debug: bool = False,\n):\n    \"\"\"Analyze source audio and optionally transcribe generated audio codes.\n\n    Args:\n        dit_handler: DiT handler instance.\n        llm_handler: LLM handler instance.\n        src_audio: Path to source audio file.\n        constrained_decoding_debug: Whether constrained-decoding debug logs are enabled.\n\n    Returns:\n        Tuple of ``(audio_codes, status, caption, lyrics, bpm, duration,\n        keyscale, language, timesignature, is_format_caption)``.\n    \"\"\"\n    error_tuple = (\"\", \"\", \"\", \"\", None, None, \"\", \"\", \"\", False)\n\n    if not src_audio:\n        gr.Warning(t(\"messages.no_source_audio\"))\n        return error_tuple\n\n    if dit_handler.model is None:\n        gr.Warning(t(\"messages.model_not_initialized\"))\n        return error_tuple\n\n    try:\n        codes_string = dit_handler.convert_src_audio_to_codes(src_audio)\n    except Exception as exc:\n        gr.Warning(t(\"messages.audio_conversion_failed\", error=str(exc)))\n        return error_tuple\n\n    if not codes_string or not _contains_audio_code_tokens(codes_string):\n        gr.Warning(t(\"messages.no_audio_codes_generated\"))\n        return (\n            codes_string or \"\",\n            t(\"messages.no_audio_codes_generated\"),\n            \"\",\n            \"\",\n            None,\n            None,\n            \"\",\n            \"\",\n            \"\",\n            False,\n        )\n\n    if not llm_handler.llm_initialized:\n        return (\n            codes_string,\n            t(\"messages.codes_ready_no_lm\"),\n            \"\",\n            \"\",\n            None,\n            None,\n            \"\",\n            \"\",\n            \"\",\n            False,\n        )\n\n    result = understand_music(\n        llm_handler=llm_handler,\n        audio_codes=codes_string,\n        use_constrained_decoding=True,\n        constrained_decoding_debug=constrained_decoding_debug,\n    )\n\n    if not result.success:\n        return (\n            codes_string,\n            result.status_message,\n            \"\",\n            \"\",\n            None,\n            None,\n            \"\",\n            \"\",\n            \"\",\n            False,\n        )\n\n    clamped_duration = clamp_duration_to_gpu_limit(result.duration, llm_handler)\n    return (\n        codes_string,\n        result.status_message,\n        result.caption,\n        result.lyrics,\n        result.bpm,\n        clamped_duration,\n        result.keyscale,\n        result.language,\n        result.timesignature,\n        True,\n    )\n\n\ndef transcribe_audio_codes(llm_handler, audio_code_string, constrained_decoding_debug: bool):\n    \"\"\"Transcribe serialized audio codes into metadata fields via the LLM.\n\n    Args:\n        llm_handler: LLM handler instance.\n        audio_code_string: Serialized audio-code tokens.\n        constrained_decoding_debug: Whether constrained-decoding debug logs are enabled.\n\n    Returns:\n        Tuple of ``(status, caption, lyrics, bpm, duration, keyscale,\n        language, timesignature, is_format_caption)``.\n    \"\"\"\n    result = understand_music(\n        llm_handler=llm_handler,\n        audio_codes=audio_code_string,\n        use_constrained_decoding=True,\n        constrained_decoding_debug=constrained_decoding_debug,\n    )\n\n    if not result.success:\n        if result.error == \"LLM not initialized\":\n            return t(\"messages.lm_not_initialized\"), \"\", \"\", None, None, \"\", \"\", \"\", False\n        return result.status_message, \"\", \"\", None, None, \"\", \"\", \"\", False\n\n    clamped_duration = clamp_duration_to_gpu_limit(result.duration, llm_handler)\n    return (\n        result.status_message,\n        result.caption,\n        result.lyrics,\n        result.bpm,\n        clamped_duration,\n        result.keyscale,\n        result.language,\n        result.timesignature,\n        True,\n    )\n"
  },
  {
    "path": "acestep/ui/gradio/events/generation/llm_format_actions.py",
    "content": "\"\"\"LLM formatting action handlers for generation UI text fields.\"\"\"\nfrom typing import Optional\n\nimport gradio as gr\n\nfrom acestep.inference import format_sample\nfrom acestep.ui.gradio.i18n import t\n\nfrom .llm_action_params import build_user_metadata, convert_lm_params\nfrom .validation import clamp_duration_to_gpu_limit\n\n\ndef _format_failure_response(update_count: int, status_message: str):\n    \"\"\"Build a standardized failure response with update placeholders.\"\"\"\n    return (*([gr.update()] * update_count), status_message)\n\n\ndef _clean_optional_wrapped_quotes(text: Optional[str]) -> Optional[str]:\n    \"\"\"Strip a single layer of leading/trailing quote characters when present.\"\"\"\n    if text is None:\n        return None\n    if len(text) >= 2 and (\n        (text.startswith(\"'\") and text.endswith(\"'\"))\n        or (text.startswith('\"') and text.endswith('\"'))\n    ):\n        return text[1:-1]\n    return text\n\n\ndef _execute_format_sample(\n    llm_handler,\n    caption: str,\n    lyrics: str,\n    bpm,\n    audio_duration,\n    key_scale: str,\n    time_signature: str,\n    lm_temperature: float,\n    lm_top_k: int,\n    lm_top_p: float,\n    constrained_decoding_debug: bool,\n):\n    \"\"\"Run shared format-sample workflow.\n\n    Returns:\n        Tuple of ``(result_or_none, audio_duration_value_or_none, status_message)``.\n    \"\"\"\n    if not llm_handler.llm_initialized:\n        status_message = t(\"messages.lm_not_initialized\")\n        gr.Warning(status_message)\n        return None, None, status_message\n\n    user_metadata = build_user_metadata(bpm, audio_duration, key_scale, time_signature)\n    top_k_value, top_p_value = convert_lm_params(lm_top_k, lm_top_p)\n\n    result = format_sample(\n        llm_handler=llm_handler,\n        caption=caption,\n        lyrics=lyrics,\n        user_metadata=user_metadata,\n        temperature=lm_temperature,\n        top_k=top_k_value,\n        top_p=top_p_value,\n        use_constrained_decoding=True,\n        constrained_decoding_debug=constrained_decoding_debug,\n    )\n\n    if not result.success:\n        status_message = result.status_message or t(\"messages.format_failed\")\n        gr.Warning(status_message)\n        return None, None, status_message\n\n    gr.Info(t(\"messages.format_success\"))\n    clamped_duration = clamp_duration_to_gpu_limit(result.duration, llm_handler)\n    duration_value = clamped_duration if clamped_duration and clamped_duration > 0 else -1\n    return result, duration_value, result.status_message\n\n\ndef handle_format_sample(\n    llm_handler,\n    caption: str,\n    lyrics: str,\n    bpm,\n    audio_duration,\n    key_scale: str,\n    time_signature: str,\n    lm_temperature: float,\n    lm_top_k: int,\n    lm_top_p: float,\n    constrained_decoding_debug: bool = False,\n):\n    \"\"\"Format caption and lyrics together via LLM.\"\"\"\n    result, duration_value, status_message = _execute_format_sample(\n        llm_handler=llm_handler,\n        caption=caption,\n        lyrics=lyrics,\n        bpm=bpm,\n        audio_duration=audio_duration,\n        key_scale=key_scale,\n        time_signature=time_signature,\n        lm_temperature=lm_temperature,\n        lm_top_k=lm_top_k,\n        lm_top_p=lm_top_p,\n        constrained_decoding_debug=constrained_decoding_debug,\n    )\n\n    if result is None:\n        return _format_failure_response(update_count=8, status_message=status_message)\n\n    return (\n        result.caption,\n        result.lyrics,\n        result.bpm,\n        duration_value,\n        result.keyscale,\n        result.language,\n        result.timesignature,\n        True,\n        status_message,\n    )\n\n\ndef handle_format_caption(\n    llm_handler,\n    caption: str,\n    lyrics: str,\n    bpm,\n    audio_duration,\n    key_scale: str,\n    time_signature: str,\n    lm_temperature: float,\n    lm_top_k: int,\n    lm_top_p: float,\n    constrained_decoding_debug: bool = False,\n):\n    \"\"\"Format only caption via LLM while leaving lyrics unchanged in UI wiring.\n\n    Any outer single/double quotes added by the LLM are stripped from the\n    returned caption for cleaner textbox display.\n    \"\"\"\n    result, duration_value, status_message = _execute_format_sample(\n        llm_handler=llm_handler,\n        caption=caption,\n        lyrics=lyrics,\n        bpm=bpm,\n        audio_duration=audio_duration,\n        key_scale=key_scale,\n        time_signature=time_signature,\n        lm_temperature=lm_temperature,\n        lm_top_k=lm_top_k,\n        lm_top_p=lm_top_p,\n        constrained_decoding_debug=constrained_decoding_debug,\n    )\n\n    if result is None:\n        return _format_failure_response(update_count=7, status_message=status_message)\n\n    return (\n        _clean_optional_wrapped_quotes(result.caption),\n        result.bpm,\n        duration_value,\n        result.keyscale,\n        result.language,\n        result.timesignature,\n        True,\n        status_message,\n    )\n\n\ndef handle_format_lyrics(\n    llm_handler,\n    caption: str,\n    lyrics: str,\n    bpm,\n    audio_duration,\n    key_scale: str,\n    time_signature: str,\n    lm_temperature: float,\n    lm_top_k: int,\n    lm_top_p: float,\n    constrained_decoding_debug: bool = False,\n):\n    \"\"\"Format only lyrics via LLM while leaving caption unchanged in UI wiring.\n\n    Any outer single/double quotes added by the LLM are stripped from the\n    returned lyrics for cleaner textbox display.\n    \"\"\"\n    result, duration_value, status_message = _execute_format_sample(\n        llm_handler=llm_handler,\n        caption=caption,\n        lyrics=lyrics,\n        bpm=bpm,\n        audio_duration=audio_duration,\n        key_scale=key_scale,\n        time_signature=time_signature,\n        lm_temperature=lm_temperature,\n        lm_top_k=lm_top_k,\n        lm_top_p=lm_top_p,\n        constrained_decoding_debug=constrained_decoding_debug,\n    )\n\n    if result is None:\n        return _format_failure_response(update_count=7, status_message=status_message)\n\n    return (\n        _clean_optional_wrapped_quotes(result.lyrics),\n        result.bpm,\n        duration_value,\n        result.keyscale,\n        result.language,\n        result.timesignature,\n        True,\n        status_message,\n    )\n"
  },
  {
    "path": "acestep/ui/gradio/events/generation/llm_sample_actions.py",
    "content": "\"\"\"LLM sample-creation action handlers for generation UI.\"\"\"\n\nimport gradio as gr\n\nfrom acestep.inference import create_sample\nfrom acestep.ui.gradio.i18n import t\n\nfrom .llm_action_params import convert_lm_params\nfrom .validation import clamp_duration_to_gpu_limit\n\n\ndef handle_create_sample(\n    llm_handler,\n    query: str,\n    instrumental: bool,\n    vocal_language: str,\n    lm_temperature: float,\n    lm_top_k: int,\n    lm_top_p: float,\n    constrained_decoding_debug: bool = False,\n):\n    \"\"\"Handle Simple-mode sample creation.\n\n    Args:\n        llm_handler: LLM handler instance.\n        query: User natural-language description.\n        instrumental: Whether the sample should be instrumental.\n        vocal_language: Preferred vocal language.\n        lm_temperature: LLM temperature value.\n        lm_top_k: LLM top-k value.\n        lm_top_p: LLM top-p value.\n        constrained_decoding_debug: Whether constrained-decoding debug logs are enabled.\n\n    Returns:\n        Tuple of 15 UI updates for wired Gradio outputs.\n    \"\"\"\n    if not llm_handler.llm_initialized:\n        gr.Warning(t(\"messages.lm_not_initialized\"))\n        return (\n            gr.update(),\n            gr.update(),\n            gr.update(),\n            gr.update(),\n            gr.update(),\n            gr.update(),\n            gr.update(),\n            gr.update(),\n            gr.update(),\n            gr.update(interactive=False),\n            False,\n            gr.update(),\n            gr.update(),\n            t(\"messages.lm_not_initialized\"),\n            gr.update(),\n        )\n\n    top_k_value, top_p_value = convert_lm_params(lm_top_k, lm_top_p)\n    result = create_sample(\n        llm_handler=llm_handler,\n        query=query,\n        instrumental=instrumental,\n        vocal_language=vocal_language,\n        temperature=lm_temperature,\n        top_k=top_k_value,\n        top_p=top_p_value,\n        use_constrained_decoding=True,\n        constrained_decoding_debug=constrained_decoding_debug,\n    )\n\n    if not result.success:\n        gr.Warning(result.status_message or t(\"messages.sample_creation_failed\"))\n        return (\n            gr.update(),\n            gr.update(),\n            gr.update(),\n            gr.update(),\n            gr.update(),\n            gr.update(),\n            gr.update(),\n            gr.update(),\n            gr.update(),\n            gr.update(interactive=False),\n            False,\n            gr.update(),\n            gr.update(),\n            result.status_message or t(\"messages.sample_creation_failed\"),\n            gr.update(),\n        )\n\n    gr.Info(t(\"messages.sample_created\"))\n    clamped_duration = clamp_duration_to_gpu_limit(result.duration, llm_handler)\n    audio_duration_value = clamped_duration if clamped_duration and clamped_duration > 0 else -1\n    return (\n        result.caption,\n        result.lyrics,\n        result.bpm,\n        audio_duration_value,\n        result.keyscale,\n        result.language,\n        result.language,\n        result.timesignature,\n        result.instrumental,\n        gr.update(interactive=True),\n        True,\n        True,\n        True,\n        result.status_message,\n        gr.update(value=\"Custom\"),\n    )\n"
  },
  {
    "path": "acestep/ui/gradio/events/generation/metadata_loading.py",
    "content": "\"\"\"Metadata loading and example sampling for generation handlers.\n\nContains functions for loading generation parameters from JSON files\nand sampling random examples from the examples directory.\n\"\"\"\n\nimport os\nimport json\nimport random\nimport glob\nimport gradio as gr\nfrom typing import Optional\n\nfrom acestep.ui.gradio.i18n import t\nfrom acestep.gpu_config import get_global_gpu_config\nfrom acestep.inference import understand_music\nfrom .validation import clamp_duration_to_gpu_limit\n\n\ndef load_metadata(file_obj, llm_handler=None):\n    \"\"\"Load generation parameters from a JSON file.\n\n    Args:\n        file_obj: Uploaded file object.\n        llm_handler: LLM handler instance (optional, for GPU duration limit check).\n    \"\"\"\n    if file_obj is None:\n        gr.Warning(t(\"messages.no_file_selected\"))\n        return [None] * 37 + [False]\n\n    try:\n        if hasattr(file_obj, 'name'):\n            filepath = file_obj.name\n        else:\n            filepath = file_obj\n\n        with open(filepath, 'r', encoding='utf-8') as f:\n            metadata = json.load(f)\n\n        task_type = metadata.get('task_type', 'text2music')\n        captions = metadata.get('caption', '')\n        lyrics = metadata.get('lyrics', '')\n        vocal_language = metadata.get('vocal_language', 'unknown')\n\n        bpm_value = metadata.get('bpm')\n        if bpm_value is not None and bpm_value != \"N/A\":\n            try:\n                bpm = int(bpm_value) if bpm_value else None\n            except Exception:\n                bpm = None\n        else:\n            bpm = None\n\n        key_scale = metadata.get('keyscale', '')\n        time_signature = metadata.get('timesignature', '')\n\n        duration_value = metadata.get('duration', -1)\n        if duration_value is not None and duration_value != \"N/A\":\n            try:\n                audio_duration = float(duration_value)\n                audio_duration = clamp_duration_to_gpu_limit(audio_duration, llm_handler)\n            except Exception:\n                audio_duration = -1\n        else:\n            audio_duration = -1\n\n        batch_size = metadata.get('batch_size', 2)\n        gpu_config = get_global_gpu_config()\n        lm_initialized = llm_handler.llm_initialized if llm_handler else False\n        max_batch_size = gpu_config.max_batch_size_with_lm if lm_initialized else gpu_config.max_batch_size_without_lm\n        batch_size = min(int(batch_size), max_batch_size)\n        inference_steps = metadata.get('inference_steps', 8)\n        guidance_scale = metadata.get('guidance_scale', 7.0)\n        seed = metadata.get('seed', '-1')\n        random_seed = False\n        use_adg = metadata.get('use_adg', False)\n        cfg_interval_start = metadata.get('cfg_interval_start', 0.0)\n        cfg_interval_end = metadata.get('cfg_interval_end', 1.0)\n        audio_format = metadata.get('audio_format', 'flac')\n        lm_temperature = metadata.get('lm_temperature', 0.85)\n        lm_cfg_scale = metadata.get('lm_cfg_scale', 2.0)\n        lm_top_k = metadata.get('lm_top_k', 0)\n        lm_top_p = metadata.get('lm_top_p', 0.9)\n        lm_negative_prompt = metadata.get('lm_negative_prompt', 'NO USER INPUT')\n        use_cot_metas = metadata.get('use_cot_metas', True)\n        use_cot_caption = metadata.get('use_cot_caption', True)\n        use_cot_language = metadata.get('use_cot_language', True)\n        audio_cover_strength = metadata.get('audio_cover_strength', 1.0)\n        cover_noise_strength = metadata.get('cover_noise_strength', 0.0)\n        think = metadata.get('thinking', True)\n        lm_ok = llm_handler.llm_initialized if llm_handler else False\n        if think and not lm_ok:\n            think = False\n            gr.Warning(t(\"messages.think_requires_lm\"))\n        audio_codes = metadata.get('audio_codes', '')\n        if think and audio_codes and audio_codes.strip():\n            think = False\n        repainting_start = metadata.get('repainting_start', 0.0)\n        repainting_end = metadata.get('repainting_end', -1)\n        track_name = metadata.get('track_name')\n        complete_track_classes = metadata.get('complete_track_classes', [])\n        shift = metadata.get('shift', 3.0)\n        infer_method = metadata.get('infer_method', 'ode')\n        custom_timesteps = metadata.get('timesteps', '')\n        if custom_timesteps is None:\n            custom_timesteps = ''\n        instrumental = metadata.get('instrumental', False)\n\n        gr.Info(t(\"messages.params_loaded\", filename=os.path.basename(filepath)))\n\n        return (\n            task_type, captions, lyrics, vocal_language, bpm, key_scale, time_signature,\n            audio_duration, batch_size, inference_steps, guidance_scale, seed, random_seed,\n            use_adg, cfg_interval_start, cfg_interval_end, shift, infer_method,\n            custom_timesteps,\n            audio_format, lm_temperature, lm_cfg_scale, lm_top_k, lm_top_p, lm_negative_prompt,\n            use_cot_metas, use_cot_caption, use_cot_language, audio_cover_strength,\n            cover_noise_strength, think, audio_codes, repainting_start, repainting_end,\n            track_name, complete_track_classes, instrumental,\n            True  # is_format_caption\n        )\n\n    except json.JSONDecodeError as e:\n        gr.Warning(t(\"messages.invalid_json\", error=str(e)))\n        return [None] * 37 + [False]\n    except Exception as e:\n        gr.Warning(t(\"messages.load_error\", error=str(e)))\n        return [None] * 37 + [False]\n\n\ndef _get_project_root() -> str:\n    \"\"\"Return the project root directory (5 levels up from this file).\"\"\"\n    current_file = os.path.abspath(__file__)\n    # This file is in acestep/ui/gradio/events/generation/\n    return os.path.dirname(os.path.dirname(os.path.dirname(\n        os.path.dirname(os.path.dirname(os.path.dirname(current_file))))))\n\n\ndef load_random_example(task_type: str, llm_handler=None):\n    \"\"\"Load a random example from the task-specific examples directory.\n\n    Args:\n        task_type: The task type (e.g., \"text2music\").\n        llm_handler: LLM handler instance (optional, for GPU duration limit check).\n\n    Returns:\n        Tuple of (caption, lyrics, think, bpm, duration, keyscale, language, timesignature).\n    \"\"\"\n    try:\n        project_root = _get_project_root()\n        examples_dir = os.path.join(project_root, \"examples\", task_type)\n\n        if not os.path.exists(examples_dir):\n            gr.Warning(f\"Examples directory not found: examples/{task_type}/\")\n            return \"\", \"\", True, None, None, \"\", \"\", \"\"\n\n        json_files = glob.glob(os.path.join(examples_dir, \"*.json\"))\n        if not json_files:\n            gr.Warning(f\"No JSON files found in examples/{task_type}/\")\n            return \"\", \"\", True, None, None, \"\", \"\", \"\"\n\n        selected_file = random.choice(json_files)\n\n        try:\n            with open(selected_file, 'r', encoding='utf-8') as f:\n                data = json.load(f)\n\n            caption_value = data.get('caption', data.get('prompt', ''))\n            if not isinstance(caption_value, str):\n                caption_value = str(caption_value) if caption_value else ''\n\n            lyrics_value = data.get('lyrics', '')\n            if not isinstance(lyrics_value, str):\n                lyrics_value = str(lyrics_value) if lyrics_value else ''\n\n            think_value = data.get('think', True)\n            if not isinstance(think_value, bool):\n                think_value = True\n            lm_ok = llm_handler.llm_initialized if llm_handler else False\n            if think_value and not lm_ok:\n                think_value = False\n                gr.Warning(t(\"messages.think_requires_lm\"))\n\n            bpm_value: Optional[int] = None\n            if 'bpm' in data and data['bpm'] not in [None, \"N/A\", \"\"]:\n                try:\n                    bpm_value = int(data['bpm'])\n                except (ValueError, TypeError):\n                    pass\n\n            duration_value = None\n            if 'duration' in data and data['duration'] not in [None, \"N/A\", \"\"]:\n                try:\n                    duration_value = float(data['duration'])\n                    duration_value = clamp_duration_to_gpu_limit(duration_value, llm_handler)\n                except (ValueError, TypeError):\n                    pass\n\n            keyscale_value = data.get('keyscale', '')\n            if keyscale_value in [None, \"N/A\"]:\n                keyscale_value = ''\n\n            language_value = data.get('language', '')\n            if language_value in [None, \"N/A\"]:\n                language_value = ''\n\n            timesignature_value = data.get('timesignature', '')\n            if timesignature_value in [None, \"N/A\"]:\n                timesignature_value = ''\n\n            gr.Info(t(\"messages.example_loaded\", filename=os.path.basename(selected_file)))\n            return (caption_value, lyrics_value, think_value, bpm_value,\n                    duration_value, keyscale_value, language_value, timesignature_value)\n\n        except json.JSONDecodeError as e:\n            gr.Warning(t(\"messages.example_failed\", filename=os.path.basename(selected_file), error=str(e)))\n            return \"\", \"\", True, None, None, \"\", \"\", \"\"\n        except Exception as e:\n            gr.Warning(t(\"messages.example_error\", error=str(e)))\n            return \"\", \"\", True, None, None, \"\", \"\", \"\"\n\n    except Exception as e:\n        gr.Warning(t(\"messages.example_error\", error=str(e)))\n        return \"\", \"\", True, None, None, \"\", \"\", \"\"\n\n\ndef sample_example_smart(llm_handler, task_type: str, constrained_decoding_debug: bool = False):\n    \"\"\"Smart sample: use LM if initialized, else fall back to examples directory.\n\n    Args:\n        llm_handler: LLM handler instance.\n        task_type: The task type (e.g., \"text2music\").\n        constrained_decoding_debug: Whether to enable debug logging.\n\n    Returns:\n        Tuple of (caption, lyrics, think, bpm, duration, keyscale, language, timesignature).\n    \"\"\"\n    if llm_handler.llm_initialized:\n        try:\n            result = understand_music(\n                llm_handler=llm_handler,\n                audio_codes=\"NO USER INPUT\",\n                temperature=0.85,\n                use_constrained_decoding=True,\n                constrained_decoding_debug=constrained_decoding_debug,\n            )\n            if result.success:\n                gr.Info(t(\"messages.lm_generated\"))\n                clamped_duration = clamp_duration_to_gpu_limit(result.duration, llm_handler)\n                return (\n                    result.caption, result.lyrics, True,\n                    result.bpm, clamped_duration, result.keyscale,\n                    result.language, result.timesignature,\n                )\n            else:\n                gr.Warning(t(\"messages.lm_fallback\"))\n                return load_random_example(task_type)\n        except Exception:\n            gr.Warning(t(\"messages.lm_fallback\"))\n            return load_random_example(task_type)\n    else:\n        return load_random_example(task_type)\n\n\ndef load_random_simple_description():\n    \"\"\"Load a random description from the simple_mode examples directory.\n\n    Returns:\n        Tuple of (description, instrumental, vocal_language).\n    \"\"\"\n    try:\n        project_root = _get_project_root()\n        examples_dir = os.path.join(project_root, \"examples\", \"simple_mode\")\n\n        if not os.path.exists(examples_dir):\n            gr.Warning(t(\"messages.simple_examples_not_found\"))\n            return gr.update(), gr.update(), gr.update()\n\n        json_files = glob.glob(os.path.join(examples_dir, \"*.json\"))\n        if not json_files:\n            gr.Warning(t(\"messages.simple_examples_empty\"))\n            return gr.update(), gr.update(), gr.update()\n\n        selected_file = random.choice(json_files)\n\n        try:\n            with open(selected_file, 'r', encoding='utf-8') as f:\n                data = json.load(f)\n\n            description = data.get('description', '')\n            instrumental = data.get('instrumental', False)\n            vocal_language = data.get('vocal_language', 'unknown')\n            if isinstance(vocal_language, list):\n                vocal_language = vocal_language[0] if vocal_language else 'unknown'\n\n            gr.Info(t(\"messages.simple_example_loaded\", filename=os.path.basename(selected_file)))\n            return description, instrumental, vocal_language\n\n        except json.JSONDecodeError as e:\n            gr.Warning(t(\"messages.example_failed\", filename=os.path.basename(selected_file), error=str(e)))\n            return gr.update(), gr.update(), gr.update()\n        except Exception as e:\n            gr.Warning(t(\"messages.example_error\", error=str(e)))\n            return gr.update(), gr.update(), gr.update()\n\n    except Exception as e:\n        gr.Warning(t(\"messages.example_error\", error=str(e)))\n        return gr.update(), gr.update(), gr.update()\n"
  },
  {
    "path": "acestep/ui/gradio/events/generation/mode_ui.py",
    "content": "\"\"\"Generation-mode UI update orchestration for Gradio handlers.\"\"\"\n\nimport gradio as gr\nfrom loguru import logger\n\nfrom acestep.constants import MODE_TO_TASK_TYPE\nfrom acestep.ui.gradio.i18n import t\nfrom .mode_ui_helpers import (\n    _compute_automation_updates,\n    _compute_field_updates_for_mode,\n    _compute_meta_updates_for_mode,\n    _compute_repainting_labels,\n)\n\n\ndef compute_mode_ui_updates(mode: str, llm_handler=None, previous_mode: str = \"Custom\"):\n    \"\"\"Return the 44-output mode-switch update tuple for generation UI.\"\"\"\n    task_type = MODE_TO_TASK_TYPE.get(mode, \"text2music\")\n\n    is_simple = (mode == \"Simple\")\n    is_custom = (mode == \"Custom\")\n    is_cover = (mode == \"Remix\")\n    is_repaint = (mode == \"Repaint\")\n    is_extract = (mode == \"Extract\")\n    is_lego = (mode == \"Lego\")\n    is_complete = (mode == \"Complete\")\n    leaving_extract_or_lego = previous_mode in (\"Extract\", \"Lego\")\n    not_simple = not is_simple\n\n    # --- Visibility rules ---\n    show_simple = is_simple\n    show_custom_group = not_simple and not is_extract\n    show_generate_row = not_simple\n    generate_interactive = not_simple\n    show_src_audio = is_cover or is_repaint or is_extract or is_lego or is_complete\n    show_optional = not_simple and not is_extract and not is_lego\n    show_repainting = is_repaint or is_lego\n    show_audio_codes = is_custom\n    show_track_name = is_lego or is_extract\n    show_complete_classes = is_complete\n\n    # Audio cover strength\n    show_strength = not is_simple and not is_repaint and not is_extract and not is_lego\n    if is_cover:\n        strength_label = t(\"generation.remix_strength_label\")\n        strength_info = t(\"generation.remix_strength_info\")\n    elif is_custom:\n        strength_label = t(\"generation.codes_strength_label\")\n        strength_info = t(\"generation.codes_strength_info\")\n    else:\n        strength_label = t(\"generation.cover_strength_label\")\n        strength_info = t(\"generation.cover_strength_info\")\n    strength_update = gr.update(visible=show_strength, label=strength_label, info=strength_info)\n    cover_noise_update = gr.update(visible=is_cover)\n\n    # Think checkbox\n    lm_initialized = llm_handler.llm_initialized if llm_handler else False\n    if is_extract or is_lego or is_cover or is_repaint:\n        think_update = gr.update(interactive=False, value=False, visible=not (is_extract or is_lego))\n    elif not lm_initialized:\n        think_update = gr.update(interactive=False, value=False, visible=True)\n    else:\n        # Restore thinking to True when entering a mode where it is supported\n        # (e.g. Custom after returning from Remix/Repaint where it was forced off).\n        think_update = gr.update(interactive=True, visible=True, value=True)\n\n    mode_descriptions = {\n        \"Simple\": t(\"generation.mode_info_simple\"),\n        \"Custom\": t(\"generation.mode_info_custom\"),\n        \"Remix\": t(\"generation.mode_info_remix\"),\n        \"Repaint\": t(\"generation.mode_info_repaint\"),\n        \"Extract\": t(\"generation.mode_info_extract\"),\n        \"Lego\": t(\"generation.mode_info_lego\"),\n        \"Complete\": t(\"generation.mode_info_complete\"),\n    }\n    mode_help_text = mode_descriptions.get(mode, \"\")\n    show_results = not_simple\n\n    # Generate button label\n    if is_extract:\n        generate_btn_update = gr.update(interactive=generate_interactive, value=t(\"generation.extract_stem_btn\"))\n    elif is_lego:\n        generate_btn_update = gr.update(interactive=generate_interactive, value=t(\"generation.add_stem_btn\"))\n    else:\n        generate_btn_update = gr.update(interactive=generate_interactive, value=t(\"generation.generate_btn\"))\n\n    # --- Extract/Lego-mode outputs (indices 19-29) ---\n    captions_update, lyrics_update, bpm_update, key_scale_update = _compute_field_updates_for_mode(\n        is_extract, is_lego, not_simple, leaving_extract_or_lego,\n    )\n    time_signature_update, vocal_language_update, audio_duration_update = _compute_meta_updates_for_mode(\n        is_extract, is_lego, not_simple, leaving_extract_or_lego,\n    )\n    auto_score_update, autogen_update, auto_lrc_update, analyze_btn_update = _compute_automation_updates(\n        is_extract, is_lego, not_simple,\n    )\n\n    # --- Dynamic repainting / stem area labels (indices 30-32) ---\n    repainting_header_update, repainting_start_update, repainting_end_update = _compute_repainting_labels(\n        is_lego, is_repaint,\n    )\n\n    # --- Auto checkbox updates (indices 37-41) ---\n    if is_extract or is_lego or leaving_extract_or_lego:\n        auto_bpm_update = gr.update(value=True)\n        auto_key_update = gr.update(value=True)\n        auto_timesig_update = gr.update(value=True)\n        auto_vocal_lang_update = gr.update(value=True)\n        auto_duration_update = gr.update(value=True)\n    else:\n        auto_bpm_update = gr.update()\n        auto_key_update = gr.update()\n        auto_timesig_update = gr.update()\n        auto_vocal_lang_update = gr.update()\n        auto_duration_update = gr.update()\n\n    # Clear stale audio codes when leaving/returning from source-audio modes.\n    _prev_has_src_audio = previous_mode in (\"Remix\", \"Repaint\", \"Extract\", \"Lego\", \"Complete\")\n    if is_custom:\n        if _prev_has_src_audio:\n            audio_codes_update = gr.update(value=\"\", visible=True)\n        else:\n            audio_codes_update = gr.update(visible=True)\n    else:\n        audio_codes_update = gr.update(value=\"\", visible=False)\n\n    # Clear src_audio when entering a mode that doesn't use it\n    # (Custom, Simple) to prevent stale audio from leaking.\n    if show_src_audio:\n        src_audio_update = gr.update()\n    else:\n        src_audio_update = gr.update(value=None)\n\n    return (\n        gr.update(visible=show_simple),                    # 0: simple_mode_group\n        gr.update(visible=show_custom_group),              # 1: custom_mode_group\n        generate_btn_update,                               # 2: generate_btn\n        False,                                             # 3: simple_sample_created\n        gr.update(visible=show_optional, open=False),       # 4: optional_params_accordion\n        gr.update(value=task_type, elem_classes=[\"has-info-container\"]),  # 5: task_type\n        gr.update(visible=show_src_audio),                 # 6: src_audio_row\n        gr.update(visible=show_repainting),                # 7: repainting_group\n        gr.update(visible=show_audio_codes),               # 8: text2music_audio_codes_group\n        gr.update(visible=show_track_name),                # 9: track_name\n        gr.update(visible=show_complete_classes),           # 10: complete_track_classes\n        gr.update(visible=show_generate_row),              # 11: generate_btn_row\n        gr.update(info=mode_help_text, elem_classes=[\"has-info-container\"]),  # 12: generation_mode\n        gr.update(visible=show_results),                   # 13: results_wrapper\n        think_update,                                      # 14: think_checkbox\n        gr.update(visible=not_simple),                     # 15: load_file_col\n        gr.update(visible=not_simple),                     # 16: load_file\n        strength_update,                                   # 17: audio_cover_strength\n        cover_noise_update,                                # 18: cover_noise_strength\n        captions_update,                                   # 19: captions\n        lyrics_update,                                     # 20: lyrics\n        bpm_update,                                        # 21: bpm\n        key_scale_update,                                  # 22: key_scale\n        time_signature_update,                             # 23: time_signature\n        vocal_language_update,                             # 24: vocal_language\n        audio_duration_update,                             # 25: audio_duration\n        auto_score_update,                                 # 26: auto_score\n        autogen_update,                                    # 27: autogen_checkbox\n        auto_lrc_update,                                   # 28: auto_lrc\n        analyze_btn_update,                                # 29: analyze_btn\n        repainting_header_update,                          # 30: repainting_header_html\n        repainting_start_update,                           # 31: repainting_start\n        repainting_end_update,                             # 32: repainting_end\n        gr.skip(),                                         # 33: repaint_mode\n        gr.skip(),                                         # 34: repaint_strength\n        mode,                                              # 35: previous_generation_mode\n        gr.update(visible=is_cover),                       # 34: remix_help_group\n        gr.update(visible=(is_extract or is_lego)),        # 35: extract_help_group\n        gr.update(visible=is_complete),                    # 36: complete_help_group\n        auto_bpm_update,                                   # 37: bpm_auto\n        auto_key_update,                                   # 38: key_auto\n        auto_timesig_update,                               # 39: timesig_auto\n        auto_vocal_lang_update,                            # 40: vocal_lang_auto\n        auto_duration_update,                              # 41: duration_auto\n        audio_codes_update,                                # 42: text2music_audio_code_string\n        src_audio_update,                                  # 43: src_audio\n    )\n\n\ndef handle_generation_mode_change(mode: str, previous_mode: str, llm_handler=None):\n    \"\"\"Delegate generation-mode change handling to compute_mode_ui_updates.\"\"\"\n    return compute_mode_ui_updates(mode, llm_handler, previous_mode=previous_mode)\n\n\ndef handle_extract_track_name_change(track_name_value: str, mode: str):\n    \"\"\"Auto-fill caption with the selected track name in Extract mode.\"\"\"\n    if mode == \"Extract\" and track_name_value:\n        return gr.update(value=track_name_value)\n    return gr.update()\n\n\ndef handle_extract_src_audio_change(src_audio_path, mode: str):\n    \"\"\"Auto-fill audio duration from source audio in Extract/Lego mode.\"\"\"\n    if mode not in (\"Extract\", \"Lego\") or not src_audio_path:\n        return gr.update()\n    try:\n        # Late import avoids loading training audio helpers unless this path is used.\n        from acestep.training.dataset_builder_modules.audio_io import get_audio_duration\n        duration = get_audio_duration(src_audio_path)\n        if duration and duration > 0:\n            return gr.update(value=float(duration))\n    except Exception as e:\n        logger.warning(f\"Failed to get audio duration for {mode} mode: {e}\")\n    return gr.update()\n"
  },
  {
    "path": "acestep/ui/gradio/events/generation/mode_ui_helpers.py",
    "content": "\"\"\"Helper functions for generation mode UI update construction.\"\"\"\n\nimport gradio as gr\n\nfrom acestep.ui.gradio.i18n import t\n\n\ndef _compute_field_updates_for_mode(\n    is_extract: bool,\n    is_lego: bool,\n    not_simple: bool,\n    leaving_extract_or_lego: bool,\n):\n    \"\"\"Compute gr.update() for captions, lyrics, bpm, and key_scale.\"\"\"\n    if is_extract:\n        return (\n            gr.update(value=\"\", visible=False),\n            gr.update(value=\"\", visible=False),\n            gr.update(value=None, interactive=False, visible=False),\n            gr.update(value=\"\", interactive=False, visible=False),\n        )\n    if is_lego:\n        return (\n            gr.update(visible=True, interactive=True),\n            gr.update(visible=True, interactive=True),\n            gr.update(value=None, interactive=False, visible=False),\n            gr.update(value=\"\", interactive=False, visible=False),\n        )\n    if not_simple:\n        if leaving_extract_or_lego:\n            return (\n                gr.update(value=\"\", visible=True, interactive=True),\n                gr.update(value=\"\", visible=True, interactive=True),\n                gr.update(value=None, visible=True, interactive=False),\n                gr.update(value=\"\", visible=True, interactive=False),\n            )\n        return (\n            gr.update(visible=True, interactive=True),\n            gr.update(visible=True, interactive=True),\n            gr.update(visible=True),\n            gr.update(visible=True),\n        )\n    if leaving_extract_or_lego:\n        return (\n            gr.update(value=\"\"),\n            gr.update(value=\"\"),\n            gr.update(value=None),\n            gr.update(value=\"\"),\n        )\n    return gr.update(), gr.update(), gr.update(), gr.update()\n\n\ndef _compute_meta_updates_for_mode(\n    is_extract: bool,\n    is_lego: bool,\n    not_simple: bool,\n    leaving_extract_or_lego: bool,\n):\n    \"\"\"Compute gr.update() for time_signature, vocal_language, audio_duration.\"\"\"\n    if is_extract or is_lego:\n        return (\n            gr.update(value=\"\", interactive=False, visible=False),\n            gr.update(value=\"unknown\", interactive=False, visible=False),\n            gr.update(value=-1, interactive=False, visible=False),\n        )\n    if not_simple:\n        if leaving_extract_or_lego:\n            return (\n                gr.update(value=\"\", visible=True, interactive=False),\n                gr.update(value=\"en\", visible=True, interactive=False),\n                gr.update(value=-1, visible=True, interactive=False),\n            )\n        return (\n            gr.update(visible=True),\n            gr.update(visible=True),\n            gr.update(visible=True),\n        )\n    if leaving_extract_or_lego:\n        return (\n            gr.update(value=\"\"),\n            gr.update(value=\"en\"),\n            gr.update(value=-1),\n        )\n    return gr.update(), gr.update(), gr.update()\n\n\ndef _compute_automation_updates(is_extract: bool, is_lego: bool, not_simple: bool):\n    \"\"\"Compute gr.update() for auto_score, autogen, auto_lrc, and analyze_btn.\"\"\"\n    if is_extract or is_lego:\n        return (\n            gr.update(visible=False, value=False, interactive=False),\n            gr.update(visible=False, value=False, interactive=False),\n            gr.update(visible=False, value=False, interactive=False),\n            gr.update(visible=False),\n        )\n    if not_simple:\n        return (\n            gr.update(visible=True, interactive=True),\n            gr.update(visible=True, interactive=True),\n            gr.update(visible=True, interactive=True),\n            gr.update(visible=True),\n        )\n    return gr.update(), gr.update(), gr.update(), gr.update()\n\n\ndef _compute_repainting_labels(is_lego: bool, is_repaint: bool):\n    \"\"\"Compute gr.update() for repainting header, start, and end labels.\"\"\"\n    if is_lego:\n        return (\n            gr.update(value=f\"<h5>{t('generation.stem_area_controls')}</h5>\"),\n            gr.update(label=t(\"generation.stem_start\")),\n            gr.update(label=t(\"generation.stem_end\")),\n        )\n    if is_repaint:\n        return (\n            gr.update(value=f\"<h5>{t('generation.repainting_controls')}</h5>\"),\n            gr.update(label=t(\"generation.repainting_start\")),\n            gr.update(label=t(\"generation.repainting_end\")),\n        )\n    return gr.update(), gr.update(), gr.update()\n\n"
  },
  {
    "path": "acestep/ui/gradio/events/generation/mode_ui_test.py",
    "content": "\"\"\"Unit tests for mode_ui state-clearing behavior on mode switch.\n\nVerifies that compute_mode_ui_updates correctly clears stale\ntext2music_audio_code_string and src_audio values when switching\nbetween modes, preventing the state-leakage noise bug.\n\nAlso verifies that think_checkbox is restored to True when switching\nback to Custom/Simple modes after Remix/Repaint forced it off.\n\"\"\"\n\nimport unittest\nfrom types import SimpleNamespace\n\ntry:\n    from acestep.ui.gradio.events.generation.mode_ui import compute_mode_ui_updates\n    _IMPORT_ERROR = None\nexcept Exception as exc:  # pragma: no cover - environment dependency guard\n    compute_mode_ui_updates = None\n    _IMPORT_ERROR = exc\n\n# Output indices for the two new state-clearing outputs\n_IDX_AUDIO_CODES = 44\n_IDX_SRC_AUDIO = 45\n_IDX_THINK_CHECKBOX = 14\n_EXPECTED_TUPLE_LENGTH = 46\n_IDX_BPM = 21\n_IDX_KEY = 22\n_IDX_TIMESIG = 23\n_IDX_VOCAL_LANG = 24\n_IDX_DURATION = 25\n\n\n@unittest.skipIf(compute_mode_ui_updates is None,\n                 f\"compute_mode_ui_updates import unavailable: {_IMPORT_ERROR}\")\nclass ModeUiStateClearingTests(unittest.TestCase):\n    \"\"\"Tests that mode switches clear stale UI state to prevent noise.\"\"\"\n\n    def test_tuple_length(self):\n        \"\"\"compute_mode_ui_updates should return exactly 44 elements.\"\"\"\n        result = compute_mode_ui_updates(\"Custom\")\n        self.assertEqual(len(result), _EXPECTED_TUPLE_LENGTH)\n\n    def test_custom_mode_preserves_audio_codes(self):\n        \"\"\"In Custom mode, audio_codes textbox should be visible but not cleared.\"\"\"\n        result = compute_mode_ui_updates(\"Custom\")\n        codes_update = result[_IDX_AUDIO_CODES]\n        # Should only set visibility, not clear the value\n        self.assertTrue(codes_update.get(\"visible\"))\n        self.assertNotIn(\"value\", codes_update)\n\n    def test_remix_mode_clears_audio_codes(self):\n        \"\"\"Switching to Remix should clear the audio_codes textbox value.\"\"\"\n        result = compute_mode_ui_updates(\"Remix\", previous_mode=\"Custom\")\n        codes_update = result[_IDX_AUDIO_CODES]\n        self.assertEqual(codes_update.get(\"value\"), \"\")\n        self.assertFalse(codes_update.get(\"visible\"))\n\n    def test_simple_mode_clears_audio_codes(self):\n        \"\"\"Switching to Simple should clear the audio_codes textbox value.\"\"\"\n        result = compute_mode_ui_updates(\"Simple\", previous_mode=\"Custom\")\n        codes_update = result[_IDX_AUDIO_CODES]\n        self.assertEqual(codes_update.get(\"value\"), \"\")\n\n    def test_repaint_mode_clears_audio_codes(self):\n        \"\"\"Switching to Repaint should clear the audio_codes textbox value.\"\"\"\n        result = compute_mode_ui_updates(\"Repaint\", previous_mode=\"Custom\")\n        codes_update = result[_IDX_AUDIO_CODES]\n        self.assertEqual(codes_update.get(\"value\"), \"\")\n\n    def test_custom_mode_clears_src_audio(self):\n        \"\"\"Switching to Custom should clear src_audio (no source audio needed).\"\"\"\n        result = compute_mode_ui_updates(\"Custom\", previous_mode=\"Remix\")\n        src_update = result[_IDX_SRC_AUDIO]\n        self.assertIsNone(src_update.get(\"value\"))\n\n    def test_simple_mode_clears_src_audio(self):\n        \"\"\"Switching to Simple should clear src_audio.\"\"\"\n        result = compute_mode_ui_updates(\"Simple\", previous_mode=\"Remix\")\n        src_update = result[_IDX_SRC_AUDIO]\n        self.assertIsNone(src_update.get(\"value\"))\n\n    def test_remix_mode_preserves_src_audio(self):\n        \"\"\"In Remix mode, src_audio should not be cleared (it's needed).\"\"\"\n        result = compute_mode_ui_updates(\"Remix\")\n        src_update = result[_IDX_SRC_AUDIO]\n        # Should be a no-op update (no value key)\n        self.assertNotIn(\"value\", src_update)\n\n    def test_repaint_mode_preserves_src_audio(self):\n        \"\"\"In Repaint mode, src_audio should not be cleared (it's needed).\"\"\"\n        result = compute_mode_ui_updates(\"Repaint\")\n        src_update = result[_IDX_SRC_AUDIO]\n        self.assertNotIn(\"value\", src_update)\n\n    def test_round_trip_remix_to_custom_clears_both(self):\n        \"\"\"Switching Remix -> Custom should clear both audio_codes and src_audio.\n\n        analyze_btn in Remix mode writes codes to text2music_audio_code_string.\n        These must be cleared when entering Custom mode so stale codes are not\n        passed to the DiT (the root cause of garbled audio after tab-switching).\n        \"\"\"\n        result = compute_mode_ui_updates(\"Custom\", previous_mode=\"Remix\")\n        codes_update = result[_IDX_AUDIO_CODES]\n        src_update = result[_IDX_SRC_AUDIO]\n        # Codes from analyze_btn in Remix must be cleared\n        self.assertEqual(codes_update.get(\"value\"), \"\")\n        self.assertTrue(codes_update.get(\"visible\"))\n        # src_audio should also be cleared\n        self.assertIsNone(src_update.get(\"value\"))\n\n    def test_repaint_to_custom_clears_audio_codes(self):\n        \"\"\"Switching Repaint -> Custom should clear audio codes (analyze_btn contaminates them).\"\"\"\n        result = compute_mode_ui_updates(\"Custom\", previous_mode=\"Repaint\")\n        codes_update = result[_IDX_AUDIO_CODES]\n        self.assertEqual(codes_update.get(\"value\"), \"\")\n        self.assertTrue(codes_update.get(\"visible\"))\n\n    def test_simple_to_custom_preserves_audio_codes(self):\n        \"\"\"Switching Simple -> Custom should NOT clear audio codes (Simple has no analyze_btn).\"\"\"\n        result = compute_mode_ui_updates(\"Custom\", previous_mode=\"Simple\")\n        codes_update = result[_IDX_AUDIO_CODES]\n        self.assertNotIn(\"value\", codes_update)\n        self.assertTrue(codes_update.get(\"visible\"))\n\n    def test_round_trip_custom_to_remix_clears_codes(self):\n        \"\"\"Switching Custom -> Remix should clear stale audio codes.\"\"\"\n        result = compute_mode_ui_updates(\"Remix\", previous_mode=\"Custom\")\n        codes_update = result[_IDX_AUDIO_CODES]\n        self.assertEqual(codes_update.get(\"value\"), \"\")\n\n    def test_remix_mode_forces_think_checkbox_off(self):\n        \"\"\"Remix mode should force think_checkbox to False and non-interactive.\"\"\"\n        llm_handler = SimpleNamespace(llm_initialized=True)\n        result = compute_mode_ui_updates(\"Remix\", llm_handler=llm_handler, previous_mode=\"Custom\")\n        think_update = result[_IDX_THINK_CHECKBOX]\n        self.assertFalse(think_update.get(\"value\"))\n        self.assertFalse(think_update.get(\"interactive\"))\n\n    def test_repaint_mode_forces_think_checkbox_off(self):\n        \"\"\"Repaint mode should force think_checkbox to False and non-interactive.\"\"\"\n        llm_handler = SimpleNamespace(llm_initialized=True)\n        result = compute_mode_ui_updates(\"Repaint\", llm_handler=llm_handler, previous_mode=\"Custom\")\n        think_update = result[_IDX_THINK_CHECKBOX]\n        self.assertFalse(think_update.get(\"value\"))\n        self.assertFalse(think_update.get(\"interactive\"))\n\n    def test_remix_to_custom_restores_think_checkbox(self):\n        \"\"\"Switching Remix -> Custom should restore think_checkbox to True when LM is initialized.\n\n        This is the core regression test for the tab-switch noise bug:\n        think_checkbox was stuck at False after returning from Remix mode,\n        causing the LLM to be skipped and producing garbled audio.\n        \"\"\"\n        llm_handler = SimpleNamespace(llm_initialized=True)\n        result = compute_mode_ui_updates(\"Custom\", llm_handler=llm_handler, previous_mode=\"Remix\")\n        think_update = result[_IDX_THINK_CHECKBOX]\n        self.assertTrue(think_update.get(\"value\"),\n                        \"think_checkbox must be restored to True when switching back to Custom mode\")\n        self.assertTrue(think_update.get(\"interactive\"))\n\n    def test_repaint_to_custom_restores_think_checkbox(self):\n        \"\"\"Switching Repaint -> Custom should restore think_checkbox to True.\"\"\"\n        llm_handler = SimpleNamespace(llm_initialized=True)\n        result = compute_mode_ui_updates(\"Custom\", llm_handler=llm_handler, previous_mode=\"Repaint\")\n        think_update = result[_IDX_THINK_CHECKBOX]\n        self.assertTrue(think_update.get(\"value\"))\n\n    def test_remix_to_simple_restores_think_checkbox(self):\n        \"\"\"Switching Remix -> Simple should restore think_checkbox to True when LM is initialized.\"\"\"\n        llm_handler = SimpleNamespace(llm_initialized=True)\n        result = compute_mode_ui_updates(\"Simple\", llm_handler=llm_handler, previous_mode=\"Remix\")\n        think_update = result[_IDX_THINK_CHECKBOX]\n        self.assertTrue(think_update.get(\"value\"))\n\n    def test_no_lm_keeps_think_checkbox_off(self):\n        \"\"\"Without LM initialized, think_checkbox should remain False even in Custom mode.\"\"\"\n        llm_handler = SimpleNamespace(llm_initialized=False)\n        result = compute_mode_ui_updates(\"Custom\", llm_handler=llm_handler, previous_mode=\"Remix\")\n        think_update = result[_IDX_THINK_CHECKBOX]\n        self.assertFalse(think_update.get(\"value\"))\n        self.assertFalse(think_update.get(\"interactive\"))\n\n    def test_non_extract_modes_do_not_force_auto_fields_interactive(self):\n        \"\"\"Mode switches should not re-enable auto-managed metadata fields.\"\"\"\n        result = compute_mode_ui_updates(\"Remix\", previous_mode=\"Custom\")\n        for idx in (_IDX_BPM, _IDX_KEY, _IDX_TIMESIG, _IDX_VOCAL_LANG, _IDX_DURATION):\n            self.assertNotIn(\"interactive\", result[idx])\n\n    def test_leaving_extract_sets_auto_fields_non_interactive(self):\n        \"\"\"Leaving Extract should reset optional fields in locked auto state.\"\"\"\n        result = compute_mode_ui_updates(\"Custom\", previous_mode=\"Extract\")\n        for idx in (_IDX_BPM, _IDX_KEY, _IDX_TIMESIG, _IDX_VOCAL_LANG, _IDX_DURATION):\n            self.assertFalse(result[idx].get(\"interactive\"))\n\n\nif __name__ == \"__main__\":\n    unittest.main()\n"
  },
  {
    "path": "acestep/ui/gradio/events/generation/model_config.py",
    "content": "\"\"\"Model configuration and UI control settings for generation handlers.\n\nContains functions for determining model type (turbo/base/pure-base),\nproducing UI control configurations, and computing gr.update() tuples\nfor model-type-dependent controls.\n\"\"\"\n\nimport re\n\nimport gradio as gr\n\nfrom acestep.constants import (\n    TASK_TYPES_TURBO,\n    TASK_TYPES_BASE,\n    GENERATION_MODES_TURBO,\n    GENERATION_MODES_BASE,\n)\n\n\ndef _has_token(token: str, path: str) -> bool:\n    \"\"\"Check if *token* appears as a delimited word in *path*.\n\n    Matches when *token* is bounded by start/end of string or a common\n    path delimiter (``/``, ``\\\\``, ``.``, ``_``, ``-``).\n    \"\"\"\n    return re.search(rf\"(^|[\\\\\\\\/._-]){token}($|[\\\\\\\\/._-])\", path) is not None\n\n\ndef is_pure_base_model(config_path_lower: str) -> bool:\n    \"\"\"Check whether a model path refers to a pure base model.\n\n    Args:\n        config_path_lower: Lowercased model config path string.\n\n    Returns:\n        ``True`` when the path contains ``\"base\"`` and excludes ``\"sft\"`` and ``\"turbo\"``.\n    \"\"\"\n    return (\n        _has_token(\"base\", config_path_lower)\n        and not _has_token(\"sft\", config_path_lower)\n        and not _has_token(\"turbo\", config_path_lower)\n    )\n\n\ndef update_model_type_settings(config_path: str | None, current_mode: str | None = None) -> tuple:\n    \"\"\"Update UI settings based on model type (fallback when handler not initialized yet).\n\n    Args:\n        config_path: Model config path string.\n        current_mode: Current generation mode value to preserve across choices update.\n\n    Returns:\n        Nine-element tuple of ``gr.update()`` dicts for inference_steps,\n        guidance_scale, use_adg, shift, cfg_interval_start, cfg_interval_end,\n        task_type, generation_mode, and init_llm_checkbox.\n    \"\"\"\n    if config_path is None:\n        config_path = \"\"\n    config_path_lower = config_path.lower()\n\n    # Precedence: turbo > SFT > pure base > fallback.\n    # Detection functions enforce mutual exclusivity.\n    is_turbo = _has_token(\"turbo\", config_path_lower)\n    is_pure_base = is_pure_base_model(config_path_lower)\n    is_sft = is_sft_model(config_path_lower)\n\n    return get_model_type_ui_settings(is_turbo, current_mode=current_mode, is_pure_base=is_pure_base, is_sft=is_sft)\n\n\ndef is_sft_model(config_path_lower: str) -> bool:\n    \"\"\"Check whether a model path refers to an SFT (supervised fine-tuned) model.\n\n    Args:\n        config_path_lower: Lowercased model config path string.\n\n    Returns:\n        ``True`` when the path contains ``\"sft\"`` and excludes ``\"turbo\"``.\n    \"\"\"\n    return _has_token(\"sft\", config_path_lower) and not _has_token(\"turbo\", config_path_lower)\n\n\ndef get_ui_control_config(is_turbo: bool, is_pure_base: bool = False, is_sft: bool = False) -> dict:\n    \"\"\"Return UI control configuration (values, limits, visibility) for model type.\n\n    Args:\n        is_turbo: Whether the model is a turbo variant.\n        is_pure_base: Whether the model is a pure base model.\n        is_sft: Whether the model is an SFT (supervised fine-tuned) variant.\n              SFT models are optimized for 50 inference steps, matching the\n              training defaults in model_discovery._BASE_DEFAULTS.\n\n    Used by both interactive init and service-mode startup so controls stay consistent.\n    \"\"\"\n    # Precedence: turbo > SFT > pure base > fallback.\n    if is_pure_base:\n        task_choices = TASK_TYPES_BASE\n        mode_choices = GENERATION_MODES_BASE\n    else:\n        task_choices = TASK_TYPES_TURBO\n        mode_choices = GENERATION_MODES_TURBO\n\n    if is_turbo:\n        return {\n            \"inference_steps_value\": 8,\n            \"inference_steps_maximum\": 20,\n            \"inference_steps_minimum\": 1,\n            \"guidance_scale_visible\": False,\n            \"use_adg_visible\": False,\n            \"shift_value\": 3.0,\n            \"shift_visible\": True,\n            \"cfg_interval_start_visible\": False,\n            \"cfg_interval_end_visible\": False,\n            \"task_type_choices\": task_choices,\n            \"generation_mode_choices\": mode_choices,\n        }\n    else:\n        # SFT models are optimized for 50 steps per training defaults;\n        # pure base / unknown models fall back to 32 steps.\n        steps = 50 if is_sft else 32\n        return {\n            \"inference_steps_value\": steps,\n            \"inference_steps_maximum\": 200,\n            \"inference_steps_minimum\": 1,\n            \"guidance_scale_visible\": True,\n            \"use_adg_visible\": True,\n            \"shift_value\": 3.0,\n            \"shift_visible\": True,\n            \"cfg_interval_start_visible\": True,\n            \"cfg_interval_end_visible\": True,\n            \"task_type_choices\": task_choices,\n            \"generation_mode_choices\": mode_choices,\n        }\n\n\ndef get_model_type_ui_settings(is_turbo: bool, current_mode: str | None = None, is_pure_base: bool = False, is_sft: bool = False):\n    \"\"\"Get gr.update() tuple for model-type controls.\n\n    Args:\n        is_turbo: Whether the model is a turbo variant.\n        current_mode: Current generation mode value to preserve.\n        is_pure_base: Whether the model is a pure base model.\n        is_sft: Whether the model is an SFT variant.\n\n    Returns:\n        Tuple of updates for inference_steps, guidance_scale, use_adg,\n        shift, cfg_interval_start, cfg_interval_end, task_type,\n        generation_mode, init_llm_checkbox.\n    \"\"\"\n    cfg = get_ui_control_config(is_turbo, is_pure_base=is_pure_base, is_sft=is_sft)\n    new_choices = cfg[\"generation_mode_choices\"]\n    if current_mode and current_mode in new_choices:\n        mode_update = gr.update(choices=new_choices, value=current_mode)\n    else:\n        mode_update = gr.update(choices=new_choices)\n    init_llm_update = gr.update(value=False) if is_pure_base else gr.update()\n    return (\n        gr.update(\n            value=cfg[\"inference_steps_value\"],\n            maximum=cfg[\"inference_steps_maximum\"],\n            minimum=cfg[\"inference_steps_minimum\"],\n        ),\n        gr.update(visible=cfg[\"guidance_scale_visible\"]),\n        gr.update(visible=cfg[\"use_adg_visible\"]),\n        gr.update(value=cfg[\"shift_value\"], visible=cfg[\"shift_visible\"]),\n        gr.update(visible=cfg[\"cfg_interval_start_visible\"]),\n        gr.update(visible=cfg[\"cfg_interval_end_visible\"]),\n        gr.update(),  # task_type\n        mode_update,\n        init_llm_update,\n    )\n\n\ndef get_generation_mode_choices(is_pure_base: bool = False) -> list:\n    \"\"\"Get the list of generation mode choices based on model type.\n\n    Args:\n        is_pure_base: Whether the model is a pure base model.\n\n    Returns:\n        List of mode choice strings.\n    \"\"\"\n    if is_pure_base:\n        return GENERATION_MODES_BASE\n    else:\n        return GENERATION_MODES_TURBO\n"
  },
  {
    "path": "acestep/ui/gradio/events/generation/model_config_test.py",
    "content": "\"\"\"Unit tests for model configuration and UI control settings.\"\"\"\n\nimport unittest\n\nfrom acestep.ui.gradio.events.generation.model_config import (\n    _has_token,\n    is_sft_model,\n    is_pure_base_model,\n    get_ui_control_config,\n    update_model_type_settings,\n)\n\n\nclass HasTokenTests(unittest.TestCase):\n    \"\"\"Verify _has_token matches tokens at various delimiter boundaries.\"\"\"\n\n    def test_token_with_hyphens(self):\n        \"\"\"Standard hyphen-delimited path.\"\"\"\n        self.assertTrue(_has_token(\"sft\", \"acestep-sft-1b\"))\n\n    def test_token_at_start(self):\n        \"\"\"Token at the beginning of the string.\"\"\"\n        self.assertTrue(_has_token(\"sft\", \"sft-model\"))\n\n    def test_token_at_end(self):\n        \"\"\"Token at the end of the string.\"\"\"\n        self.assertTrue(_has_token(\"sft\", \"model-sft\"))\n\n    def test_token_alone(self):\n        \"\"\"Token is the entire string.\"\"\"\n        self.assertTrue(_has_token(\"sft\", \"sft\"))\n\n    def test_token_with_dots(self):\n        \"\"\"Dot-delimited path.\"\"\"\n        self.assertTrue(_has_token(\"sft\", \"model.sft.v1\"))\n\n    def test_token_with_underscores(self):\n        \"\"\"Underscore-delimited path.\"\"\"\n        self.assertTrue(_has_token(\"sft\", \"model_sft_v1\"))\n\n    def test_token_embedded_rejected(self):\n        \"\"\"Token inside a larger word is not matched.\"\"\"\n        self.assertFalse(_has_token(\"sft\", \"sftp-server\"))\n        self.assertFalse(_has_token(\"base\", \"database\"))\n\n\nclass IsSftModelTests(unittest.TestCase):\n    \"\"\"Verify is_sft_model correctly identifies SFT model paths.\"\"\"\n\n    def test_sft_model_detected(self):\n        \"\"\"Paths containing 'sft' without 'turbo' should be identified as SFT.\"\"\"\n        self.assertTrue(is_sft_model(\"acestep-sft-1b-v1\"))\n\n    def test_turbo_model_not_sft(self):\n        \"\"\"Turbo models should not be classified as SFT even if path contains 'sft'.\"\"\"\n        self.assertFalse(is_sft_model(\"acestep-sft-turbo-1b\"))\n\n    def test_base_model_not_sft(self):\n        \"\"\"Plain base models should not be classified as SFT.\"\"\"\n        self.assertFalse(is_sft_model(\"acestep-base-1b\"))\n\n    def test_substring_inside_larger_word_rejected(self):\n        \"\"\"Word-boundary matching rejects 'sft' embedded in larger tokens.\n\n        \"sftp-server\" contains \"sft\" but not as a delimited token.\n        \"\"\"\n        self.assertFalse(is_sft_model(\"sftp-server\"))\n\n    def test_unrelated_path_not_sft(self):\n        \"\"\"Paths without any SFT-related substring should not match.\"\"\"\n        self.assertFalse(is_sft_model(\"acestep-v15-1b\"))\n\n\nclass IsPureBaseModelTests(unittest.TestCase):\n    \"\"\"Verify is_pure_base_model correctly identifies pure base model paths.\"\"\"\n\n    def test_base_model_detected(self):\n        \"\"\"Paths containing 'base' without 'sft' or 'turbo' should match.\"\"\"\n        self.assertTrue(is_pure_base_model(\"acestep-base-1b\"))\n\n    def test_sft_model_not_base(self):\n        \"\"\"SFT models should not be classified as pure base.\"\"\"\n        self.assertFalse(is_pure_base_model(\"acestep-base-sft-1b\"))\n\n    def test_turbo_model_not_base(self):\n        \"\"\"Turbo models should not be classified as pure base.\"\"\"\n        self.assertFalse(is_pure_base_model(\"acestep-base-turbo-1b\"))\n\n    def test_substring_inside_larger_word_rejected(self):\n        \"\"\"Word-boundary matching rejects 'base' embedded in larger tokens.\n\n        \"database\" contains \"base\" but not as a delimited token.\n        \"\"\"\n        self.assertFalse(is_pure_base_model(\"database-model\"))\n\n    def test_unrelated_path_not_base(self):\n        \"\"\"Paths without any base-related substring should not match.\"\"\"\n        self.assertFalse(is_pure_base_model(\"acestep-v15-1b\"))\n\n\nclass GetUiControlConfigTests(unittest.TestCase):\n    \"\"\"Verify get_ui_control_config returns correct defaults per model type.\"\"\"\n\n    def test_sft_model_returns_50_steps(self):\n        \"\"\"SFT models should default to 50 inference steps.\"\"\"\n        cfg = get_ui_control_config(is_turbo=False, is_sft=True)\n        self.assertEqual(cfg[\"inference_steps_value\"], 50)\n\n    def test_base_model_returns_32_steps(self):\n        \"\"\"Non-SFT, non-turbo models should default to 32 inference steps.\"\"\"\n        cfg = get_ui_control_config(is_turbo=False, is_sft=False)\n        self.assertEqual(cfg[\"inference_steps_value\"], 32)\n\n    def test_turbo_model_returns_8_steps(self):\n        \"\"\"Turbo models should default to 8 inference steps.\"\"\"\n        cfg = get_ui_control_config(is_turbo=True)\n        self.assertEqual(cfg[\"inference_steps_value\"], 8)\n\n    def test_turbo_takes_precedence_over_sft(self):\n        \"\"\"When both turbo and SFT flags are set, turbo should win.\"\"\"\n        cfg = get_ui_control_config(is_turbo=True, is_sft=True)\n        self.assertEqual(cfg[\"inference_steps_value\"], 8)\n\n\nclass UpdateModelTypeSettingsIntegrationTests(unittest.TestCase):\n    \"\"\"End-to-end tests: config path string in, correct step defaults out.\"\"\"\n\n    def test_sft_path_produces_50_steps(self):\n        \"\"\"Passing an SFT model path should yield 50 inference steps.\"\"\"\n        result = update_model_type_settings(\"acestep-v15-sft\")\n        # First element is the inference_steps gr.update()\n        self.assertEqual(result[0][\"value\"], 50)\n\n    def test_turbo_path_produces_8_steps(self):\n        \"\"\"Passing a turbo model path should yield 8 inference steps.\"\"\"\n        result = update_model_type_settings(\"acestep-v15-turbo\")\n        self.assertEqual(result[0][\"value\"], 8)\n\n    def test_base_path_produces_32_steps(self):\n        \"\"\"Passing a base model path should yield 32 inference steps.\"\"\"\n        result = update_model_type_settings(\"acestep-v15-base\")\n        self.assertEqual(result[0][\"value\"], 32)\n\n    def test_none_path_does_not_crash(self):\n        \"\"\"Passing None as config_path should not raise.\"\"\"\n        result = update_model_type_settings(None)\n        self.assertEqual(result[0][\"value\"], 32)\n\n    def test_substring_no_false_positive_end_to_end(self):\n        \"\"\"Word-boundary matching prevents false positives end-to-end.\n\n        \"sftp-server\" contains \"sft\" but not as a delimited token,\n        so it correctly falls through to the 32-step default.\n        \"\"\"\n        result = update_model_type_settings(\"sftp-server\")\n        self.assertEqual(result[0][\"value\"], 32)\n\n\nif __name__ == \"__main__\":\n    unittest.main()\n"
  },
  {
    "path": "acestep/ui/gradio/events/generation/service_init.py",
    "content": "\"\"\"Service initialization and tier management for generation handlers.\n\nContains functions for initializing the DiT/LLM services, refreshing\ncheckpoints, and handling GPU tier changes.\n\"\"\"\n\nimport os\nimport sys\nimport gradio as gr\nfrom loguru import logger\n\nfrom acestep.ui.gradio.i18n import t\nfrom acestep.gpu_config import (\n    get_global_gpu_config, is_lm_model_size_allowed, find_best_lm_model_on_disk,\n    get_gpu_config_for_tier, set_global_gpu_config, GPU_TIER_LABELS, GPU_TIER_CONFIGS,\n)\nfrom .model_config import is_pure_base_model, is_sft_model, get_model_type_ui_settings\n\n\ndef _select_quantization_value(\n    *,\n    quantization_enabled: bool,\n    device: str,\n) -> str | None:\n    \"\"\"Return the DiT quantization mode selected for the current UI state.\"\"\"\n    quant_value = \"int8_weight_only\" if quantization_enabled else None\n    if not quantization_enabled or device not in {\"auto\", \"cuda\"}:\n        return quant_value\n\n    try:\n        import torch\n    except ImportError:\n        return quant_value\n\n    try:\n        if torch.cuda.is_available():\n            major, _ = torch.cuda.get_device_capability(0)\n            if major < 7:\n                logger.info(\n                    \"Pre-Ampere CUDA detected: using w8a8_dynamic quantization for stability\"\n                )\n                return \"w8a8_dynamic\"\n    except Exception:\n        return quant_value\n    return quant_value\n\n\ndef refresh_checkpoints(dit_handler):\n    \"\"\"Refresh available checkpoints.\"\"\"\n    choices = dit_handler.get_available_checkpoints()\n    return gr.update(choices=choices)\n\n\ndef init_service_wrapper(\n    dit_handler, llm_handler, checkpoint, config_path, device,\n    init_llm, lm_model_path, backend, use_flash_attention,\n    offload_to_cpu, offload_dit_to_cpu, compile_model, quantization,\n    mlx_dit=True, current_mode=None, current_batch_size=None,\n):\n    \"\"\"Wrapper for service initialization.\n\n    Returns status, button state, accordion state, model type settings,\n    and GPU-config-aware UI limits.\n\n    Args:\n        current_batch_size: Current batch size value from UI to preserve\n            after reinitialization (optional).\n    \"\"\"\n    quant_value = _select_quantization_value(\n        quantization_enabled=quantization,\n        device=device,\n    )\n\n    gpu_config = get_global_gpu_config()\n\n    if sys.platform == \"darwin\":\n        if compile_model:\n            logger.info(\n                \"macOS detected: torch.compile not supported; compilation \"\n                \"will use mx.compile via MLX.\"\n            )\n        if quantization:\n            logger.info(\"macOS detected: disabling INT8 quantization (torchao incompatible with MPS)\")\n            quantization = False\n            quant_value = None\n\n    # Compute lm_device only when initializing the LLM to avoid overwriting a\n    # previously-resolved device (e.g. \"cuda\") with the raw UI value (\"auto\").\n    # \"auto\" is resolved to the concrete device inside llm_handler.initialize().\n    if init_llm:\n        if not gpu_config.available_lm_models:\n            logger.warning(\n                f\"⚠️ GPU tier {gpu_config.tier} ({gpu_config.gpu_memory_gb:.1f}GB) does not support LM on GPU. \"\n                \"Falling back to CPU for LM initialization.\"\n            )\n            lm_device = \"cpu\"\n        else:\n            lm_device = device\n\n    if init_llm and lm_model_path and gpu_config.available_lm_models:\n        if not is_lm_model_size_allowed(lm_model_path, gpu_config.available_lm_models):\n            logger.warning(\n                f\"⚠️ LM model {lm_model_path} is not in the recommended list for tier {gpu_config.tier} \"\n                f\"(recommended: {gpu_config.available_lm_models}). Proceeding with user selection — \"\n                f\"this may cause high VRAM usage or OOM.\"\n            )\n\n    if init_llm and gpu_config.lm_backend_restriction == \"pt_mlx_only\" and backend == \"vllm\":\n        backend = gpu_config.recommended_backend\n        logger.warning(\n            f\"⚠️ vllm backend not supported for tier {gpu_config.tier} \"\n            f\"(VRAM too low for KV cache), falling back to {backend}\"\n        )\n\n    # Derive project_root from the checkpoint path (which is the checkpoints\n    # directory itself, e.g. \"<project>/checkpoints\").  Passing it directly as\n    # project_root would cause initialize_service to append \"checkpoints\" again,\n    # resulting in \"<project>/checkpoints/checkpoints\".\n    current_file = os.path.abspath(__file__)\n    # This file is in acestep/ui/gradio/events/generation/\n    project_root = os.path.dirname(os.path.dirname(os.path.dirname(\n        os.path.dirname(os.path.dirname(os.path.dirname(current_file))))))\n\n    status, enable = dit_handler.initialize_service(\n        project_root, config_path, device,\n        use_flash_attention=use_flash_attention, compile_model=compile_model,\n        offload_to_cpu=offload_to_cpu, offload_dit_to_cpu=offload_dit_to_cpu,\n        quantization=quant_value, use_mlx_dit=mlx_dit,\n    )\n\n    if init_llm:\n        checkpoint_dir = os.path.join(project_root, \"checkpoints\")\n\n        lm_status, lm_success = llm_handler.initialize(\n            checkpoint_dir=checkpoint_dir,\n            lm_model_path=lm_model_path,\n            backend=backend,\n            device=lm_device,\n            offload_to_cpu=offload_to_cpu,\n            dtype=None,\n        )\n\n        if lm_success:\n            status += f\"\\n{lm_status}\"\n        else:\n            status += f\"\\n{lm_status}\"\n\n    is_model_initialized = dit_handler.model is not None\n    accordion_state = gr.Accordion(open=not is_model_initialized)\n\n    is_turbo = dit_handler.is_turbo_model()\n    config_path_lower = (config_path or \"\").lower()\n    is_pure_base = is_pure_base_model(config_path_lower)\n    # Match interactive path — SFT models need 50-step default here too.\n    is_sft = is_sft_model(config_path_lower)\n    model_type_settings = get_model_type_ui_settings(\n        is_turbo, current_mode=current_mode, is_pure_base=is_pure_base,\n        is_sft=is_sft,\n    )\n\n    gpu_config = get_global_gpu_config()\n    lm_actually_initialized = llm_handler.llm_initialized if llm_handler else False\n    max_duration = gpu_config.max_duration_with_lm if lm_actually_initialized else gpu_config.max_duration_without_lm\n    max_batch = gpu_config.max_batch_size_with_lm if lm_actually_initialized else gpu_config.max_batch_size_without_lm\n\n    duration_update = gr.update(\n        maximum=float(max_duration),\n        info=f\"Duration in seconds (-1 for auto). Max: {max_duration}s / {max_duration // 60} min.\",\n        elem_classes=[\"has-info-container\"],\n    )\n\n    if current_batch_size is not None:\n        try:\n            batch_value_int = int(current_batch_size)\n            if batch_value_int >= 1:\n                batch_value = min(batch_value_int, max_batch)\n                if batch_value_int > max_batch:\n                    logger.warning(f\"Batch size {batch_value_int} exceeds GPU limit {max_batch}, clamping to {batch_value}\")\n            else:\n                logger.warning(f\"Invalid batch size {batch_value_int} (must be >= 1), using default {min(2, max_batch)}\")\n                batch_value = min(2, max_batch)\n        except ValueError:\n            logger.warning(f\"Cannot convert batch size '{current_batch_size}' to integer, using default {min(2, max_batch)}\")\n            batch_value = min(2, max_batch)\n        except TypeError:\n            logger.warning(f\"Invalid batch size type {type(current_batch_size).__name__}, using default {min(2, max_batch)}\")\n            batch_value = min(2, max_batch)\n    else:\n        batch_value = min(2, max_batch)\n\n    batch_update = gr.update(\n        value=batch_value, maximum=max_batch,\n        info=f\"Number of samples to generate (Max: {max_batch}).\",\n        elem_classes=[\"has-info-container\"],\n    )\n\n    status += f\"\\n📊 GPU Config: tier={gpu_config.tier}, max_duration={max_duration}s, max_batch={max_batch}\"\n    if gpu_config.available_lm_models:\n        status += f\", available_lm={gpu_config.available_lm_models}\"\n    else:\n        status += \", LM not available for this GPU tier\"\n\n    think_interactive = lm_actually_initialized\n\n    return (\n        status,\n        gr.update(interactive=enable),\n        accordion_state,\n        *model_type_settings,\n        duration_update,\n        batch_update,\n        gr.update(interactive=think_interactive, value=think_interactive),\n    )\n\n\ndef on_tier_change(selected_tier, llm_handler=None):\n    \"\"\"Handle manual tier override from the UI dropdown.\n\n    Updates the global GPU config and returns gr.update() for all\n    affected UI components so they reflect the new tier's defaults.\n\n    Returns a tuple of gr.update() objects for:\n        (offload_to_cpu, offload_dit_to_cpu, compile_model, quantization,\n         backend_dropdown, lm_model_path, init_llm, batch_size_input,\n         audio_duration, gpu_info_display)\n    \"\"\"\n    if not selected_tier or selected_tier not in GPU_TIER_CONFIGS:\n        logger.warning(f\"Invalid tier selection: {selected_tier}\")\n        return (gr.update(),) * 10\n\n    new_config = get_gpu_config_for_tier(selected_tier)\n    set_global_gpu_config(new_config)\n    logger.info(f\"🔄 Tier manually changed to {selected_tier} — updating UI defaults\")\n\n    if new_config.lm_backend_restriction == \"pt_mlx_only\":\n        available_backends = [\"pt\", \"mlx\"]\n    else:\n        available_backends = [\"vllm\", \"pt\", \"mlx\"]\n    recommended_backend = new_config.recommended_backend\n    if recommended_backend not in available_backends:\n        recommended_backend = available_backends[0]\n\n    all_disk_models = llm_handler.get_available_5hz_lm_models() if llm_handler else []\n    recommended_lm = new_config.recommended_lm_model\n    default_lm_model = find_best_lm_model_on_disk(recommended_lm, all_disk_models)\n\n    max_duration = new_config.max_duration_without_lm\n    max_batch = new_config.max_batch_size_without_lm\n\n    tier_label = GPU_TIER_LABELS.get(selected_tier, selected_tier)\n    from acestep.gpu_config import get_gpu_device_name\n    _gpu_device_name = get_gpu_device_name()\n    gpu_info_text = (\n        f\"🖥️ **{_gpu_device_name}** — {new_config.gpu_memory_gb:.1f} GB VRAM \"\n        f\"— {t('service.gpu_auto_tier')}: **{tier_label}**\"\n    )\n\n    return (\n        gr.update(\n            value=new_config.offload_to_cpu_default,\n            info=t(\"service.offload_cpu_info\") + (\" (recommended for this tier)\" if new_config.offload_to_cpu_default else \"\"),\n            elem_classes=[\"has-info-container\"],\n        ),\n        gr.update(\n            value=new_config.offload_dit_to_cpu_default,\n            info=t(\"service.offload_dit_cpu_info\") + (\" (recommended for this tier)\" if new_config.offload_dit_to_cpu_default else \"\"),\n            elem_classes=[\"has-info-container\"],\n        ),\n        gr.update(value=new_config.compile_model_default),\n        gr.update(\n            value=new_config.quantization_default,\n            info=t(\"service.quantization_info\") + (\" (recommended for this tier)\" if new_config.quantization_default else \"\"),\n            elem_classes=[\"has-info-container\"],\n        ),\n        gr.update(choices=available_backends, value=recommended_backend, elem_classes=[\"has-info-container\"]),\n        gr.update(\n            choices=all_disk_models, value=default_lm_model,\n            info=t(\"service.lm_model_path_info\") + (f\" (Recommended: {recommended_lm})\" if recommended_lm else \" (LM not available for this GPU tier).\"),\n            elem_classes=[\"has-info-container\"],\n        ),\n        gr.update(value=new_config.init_lm_default, elem_classes=[\"has-info-container\"]),\n        gr.update(\n            value=min(2, max_batch), maximum=max_batch,\n            info=f\"Number of samples to generate (Max: {max_batch}).\",\n            elem_classes=[\"has-info-container\"],\n        ),\n        gr.update(\n            maximum=float(max_duration),\n            info=f\"Duration in seconds (-1 for auto). Max: {max_duration}s / {max_duration // 60} min.\",\n            elem_classes=[\"has-info-container\"],\n        ),\n        gr.update(value=gpu_info_text),\n    )\n"
  },
  {
    "path": "acestep/ui/gradio/events/generation/service_init_test.py",
    "content": "\"\"\"Unit tests for service_init.init_service_wrapper checkpoint path handling.\"\"\"\n\nimport importlib\nimport os\nimport sys\nimport unittest\nfrom unittest.mock import MagicMock, patch\n\n\nclass InitServiceWrapperPathTests(unittest.TestCase):\n    \"\"\"Verify init_service_wrapper passes project_root (not checkpoint dir) to initialize_service.\"\"\"\n\n    def _import_module(self):\n        \"\"\"Import service_init lazily to avoid heavy transitive imports.\"\"\"\n        from acestep.ui.gradio.events.generation import service_init\n        return service_init\n\n    @patch(\"acestep.ui.gradio.events.generation.service_init.get_global_gpu_config\")\n    def test_passes_project_root_not_checkpoint_dir(self, mock_gpu_config):\n        \"\"\"init_service_wrapper must NOT pass the checkpoint dropdown value as project_root.\n\n        The checkpoint dropdown returns the full checkpoints directory path\n        (e.g. ``<project>/checkpoints``).  Passing it directly as ``project_root``\n        causes initialize_service to append ``checkpoints`` again, yielding\n        ``<project>/checkpoints/checkpoints``.\n        \"\"\"\n        module = self._import_module()\n\n        # Stub GPU config\n        mock_gpu_config.return_value = MagicMock(\n            available_lm_models=[\"acestep-5Hz-lm-1.7B\"],\n            lm_backend_restriction=None,\n            tier=\"tier6\",\n            gpu_memory_gb=24.0,\n            max_duration_with_lm=600,\n            max_duration_without_lm=600,\n            max_batch_size_with_lm=4,\n            max_batch_size_without_lm=8,\n        )\n\n        dit_handler = MagicMock()\n        dit_handler.initialize_service.return_value = (\"ok\", True)\n        dit_handler.model = MagicMock()\n        dit_handler.is_turbo_model.return_value = True\n\n        llm_handler = MagicMock()\n        llm_handler.llm_initialized = False\n\n        # Simulate the checkpoint dropdown value: full path to checkpoints dir\n        checkpoint_value = \"/some/project/checkpoints\"\n\n        module.init_service_wrapper(\n            dit_handler,\n            llm_handler,\n            checkpoint_value,\n            \"acestep-v15-turbo\",\n            \"cpu\",\n            False,  # init_llm\n            None,  # lm_model_path\n            \"vllm\",  # backend\n            False,  # use_flash_attention\n            False,  # offload_to_cpu\n            False,  # offload_dit_to_cpu\n            False,  # compile_model\n            False,  # quantization\n        )\n\n        # The first positional arg to initialize_service must be the project root,\n        # NOT the checkpoints directory.\n        call_args = dit_handler.initialize_service.call_args\n        actual_project_root = call_args[0][0]\n\n        # It should be computed from __file__, not from the checkpoint dropdown.\n        # Critically, it must NOT end with \"checkpoints\".\n        self.assertFalse(\n            actual_project_root.rstrip(\"/\").endswith(\"checkpoints\"),\n            f\"project_root must not be the checkpoints dir, got: {actual_project_root}\",\n        )\n\n    @patch(\"acestep.ui.gradio.events.generation.service_init.get_global_gpu_config\")\n    def test_project_root_is_consistent_with_checkpoint_dir(self, mock_gpu_config):\n        \"\"\"The project_root passed to initialize_service should be the parent of checkpoints.\"\"\"\n        module = self._import_module()\n\n        mock_gpu_config.return_value = MagicMock(\n            available_lm_models=[],\n            lm_backend_restriction=None,\n            tier=\"tier6\",\n            gpu_memory_gb=24.0,\n            max_duration_with_lm=600,\n            max_duration_without_lm=600,\n            max_batch_size_with_lm=4,\n            max_batch_size_without_lm=8,\n        )\n\n        dit_handler = MagicMock()\n        dit_handler.initialize_service.return_value = (\"ok\", True)\n        dit_handler.model = MagicMock()\n        dit_handler.is_turbo_model.return_value = True\n\n        llm_handler = MagicMock()\n        llm_handler.llm_initialized = False\n\n        module.init_service_wrapper(\n            dit_handler,\n            llm_handler,\n            \"/any/path/checkpoints\",  # checkpoint dropdown value (unused now)\n            \"acestep-v15-turbo\",\n            \"cpu\",\n            False, None, \"vllm\", False, False, False, False, False,\n        )\n\n        call_args = dit_handler.initialize_service.call_args\n        actual_project_root = call_args[0][0]\n\n        # The project_root + \"checkpoints\" should form a valid checkpoints path\n        expected_checkpoints = os.path.join(actual_project_root, \"checkpoints\")\n        self.assertTrue(\n            os.path.isabs(expected_checkpoints) or actual_project_root,\n            \"project_root should be a meaningful path\",\n        )\n        # It should NOT contain double \"checkpoints\"\n        self.assertNotIn(\n            \"checkpoints/checkpoints\",\n            expected_checkpoints,\n            f\"Double nesting detected: {expected_checkpoints}\",\n        )\n\n\nclass InitServiceWrapperDeviceResolutionTests(unittest.TestCase):\n    \"\"\"Verify that 'auto' device is not written back to llm_handler when init_llm=False.\n\n    Regression test for: Auto-labelling broke after recent update if auto is\n    chosen for device.  When the user re-initialises the service without the\n    'Init LLM' checkbox ticked, the previously-resolved device (e.g. 'cuda')\n    must not be overwritten with the raw UI value 'auto'.\n    \"\"\"\n\n    def _import_module(self):\n        \"\"\"Import service_init lazily to avoid heavy transitive imports.\"\"\"\n        from acestep.ui.gradio.events.generation import service_init\n        return service_init\n\n    @patch(\"acestep.ui.gradio.events.generation.service_init.get_global_gpu_config\")\n    def test_reinit_without_llm_preserves_resolved_device(self, mock_gpu_config):\n        \"\"\"Calling init_service_wrapper with init_llm=False must not overwrite llm_handler.device.\n\n        Scenario: LLM was previously initialized (llm_initialized=True, device='cuda').\n        User re-initialises the service (e.g. to change checkpoint) with init_llm=False\n        and device='auto'.  The LLM handler's resolved device must remain 'cuda'.\n        \"\"\"\n        module = self._import_module()\n\n        mock_gpu_config.return_value = MagicMock(\n            available_lm_models=[\"acestep-5Hz-lm-1.7B\"],\n            lm_backend_restriction=None,\n            tier=\"tier6\",\n            gpu_memory_gb=24.0,\n            max_duration_with_lm=600,\n            max_duration_without_lm=600,\n            max_batch_size_with_lm=4,\n            max_batch_size_without_lm=8,\n        )\n\n        dit_handler = MagicMock()\n        dit_handler.initialize_service.return_value = (\"ok\", True)\n        dit_handler.model = MagicMock()\n        dit_handler.is_turbo_model.return_value = True\n\n        # Simulate LLM previously initialised with resolved device=\"cuda\"\n        llm_handler = MagicMock()\n        llm_handler.llm_initialized = True\n        llm_handler.device = \"cuda\"  # previously resolved from \"auto\" -> \"cuda\"\n\n        module.init_service_wrapper(\n            dit_handler,\n            llm_handler,\n            \"/some/project/checkpoints\",\n            \"acestep-v15-turbo\",\n            \"auto\",   # raw UI value -- must NOT overwrite the resolved \"cuda\"\n            False,    # init_llm=False: do not re-initialize LLM\n            None,     # lm_model_path\n            \"vllm\",   # backend\n            use_flash_attention=False,\n            offload_to_cpu=False,\n            offload_dit_to_cpu=False,\n            compile_model=False,\n            quantization=False,\n        )\n\n        # llm_handler.initialize must NOT have been called (init_llm=False)\n        llm_handler.initialize.assert_not_called()\n        # The previously-resolved device must be preserved\n        self.assertEqual(\n            llm_handler.device,\n            \"cuda\",\n            \"llm_handler.device must remain 'cuda' when init_llm=False, \"\n            f\"got '{llm_handler.device}' instead\",\n        )\n\n    @patch(\"acestep.ui.gradio.events.generation.service_init.get_global_gpu_config\")\n    def test_init_llm_with_auto_device_calls_initialize(self, mock_gpu_config):\n        \"\"\"When init_llm=True and device='auto', initialize() must be called with 'auto' device.\n\n        The 'auto' -> concrete device resolution happens inside initialize(), so we\n        must pass 'auto' through correctly.\n        \"\"\"\n        module = self._import_module()\n\n        mock_gpu_config.return_value = MagicMock(\n            available_lm_models=[\"acestep-5Hz-lm-1.7B\"],\n            lm_backend_restriction=None,\n            tier=\"tier6\",\n            gpu_memory_gb=24.0,\n            max_duration_with_lm=600,\n            max_duration_without_lm=600,\n            max_batch_size_with_lm=4,\n            max_batch_size_without_lm=8,\n        )\n\n        dit_handler = MagicMock()\n        dit_handler.initialize_service.return_value = (\"ok\", True)\n        dit_handler.model = MagicMock()\n        dit_handler.is_turbo_model.return_value = True\n\n        llm_handler = MagicMock()\n        llm_handler.llm_initialized = False\n        llm_handler.initialize.return_value = (\"[OK] LLM initialized\", True)\n\n        module.init_service_wrapper(\n            dit_handler,\n            llm_handler,\n            \"/some/project/checkpoints\",\n            \"acestep-v15-turbo\",\n            \"auto\",   # raw UI value\n            True,     # init_llm=True\n            \"acestep-5Hz-lm-1.7B\",\n            \"pt\",\n            use_flash_attention=False,\n            offload_to_cpu=False,\n            offload_dit_to_cpu=False,\n            compile_model=False,\n            quantization=False,\n        )\n\n        llm_handler.initialize.assert_called_once()\n        _, call_kwargs = llm_handler.initialize.call_args\n        self.assertEqual(\n            call_kwargs.get(\"device\"),\n            \"auto\",\n            \"initialize() must receive 'auto' so it can resolve to the best device\",\n        )\n\n\n\nclass QuantizationSelectionTests(unittest.TestCase):\n    \"\"\"Verify pre-Ampere quantization mode selection.\"\"\"\n\n    def _import_module(self):\n        \"\"\"Import service_init lazily to avoid heavy transitive imports.\"\"\"\n        from acestep.ui.gradio.events.generation import service_init\n        return service_init\n\n    def test_select_quantization_value_uses_dynamic_mode_for_pre_ampere_cuda(self):\n        \"\"\"It selects ``w8a8_dynamic`` for pre-Ampere CUDA devices.\"\"\"\n        module = self._import_module()\n\n        with patch(\"torch.cuda.is_available\", return_value=True), \\\n                patch(\"torch.cuda.get_device_capability\", return_value=(6, 1)):\n            self.assertEqual(\n                module._select_quantization_value(\n                    quantization_enabled=True,\n                    device=\"cuda\",\n                ),\n                \"w8a8_dynamic\",\n            )\n\n    def test_select_quantization_value_keeps_default_when_torch_import_fails(self):\n        \"\"\"It keeps the default quantization when torch cannot be imported.\"\"\"\n        module = importlib.import_module(\n            \"acestep.ui.gradio.events.generation.service_init\"\n        )\n        real_import = __import__\n        removed_torch_module = sys.modules.pop(\"torch\", None)\n        removed_torch_nn_module = sys.modules.pop(\"torch.nn\", None)\n\n        def fake_import(name, globals_=None, locals_=None, fromlist=(), level=0):\n            \"\"\"Raise ImportError only for torch imports from the helper.\"\"\"\n            if name == \"torch\" or name.startswith(\"torch.\"):\n                raise ImportError(\"torch missing\")\n            return real_import(name, globals_, locals_, fromlist, level)\n\n        try:\n            with patch(\"builtins.__import__\", side_effect=fake_import):\n                self.assertEqual(\n                    module._select_quantization_value(\n                        quantization_enabled=True,\n                        device=\"cuda\",\n                    ),\n                    \"int8_weight_only\",\n                )\n        finally:\n            if removed_torch_module is not None:\n                sys.modules[\"torch\"] = removed_torch_module\n            if removed_torch_nn_module is not None:\n                sys.modules[\"torch.nn\"] = removed_torch_nn_module\n\nif __name__ == \"__main__\":\n    unittest.main()\n"
  },
  {
    "path": "acestep/ui/gradio/events/generation/ui_helpers.py",
    "content": "\"\"\"Small UI toggle/helper functions for generation handlers.\n\nContains functions for visibility toggles, auto-checkbox management,\ninstrumental handling, and other lightweight UI helpers.\n\"\"\"\n\nimport gradio as gr\nfrom typing import Optional\n\nfrom acestep.ui.gradio.i18n import t\nfrom .validation import _has_reference_audio\n\n\ndef update_negative_prompt_visibility(init_llm_checked):\n    \"\"\"Update negative prompt visibility: show if Initialize 5Hz LM checkbox is checked.\"\"\"\n    return gr.update(visible=init_llm_checked)\n\n\n# Default \"auto\" values per field — these cause the model to auto-infer.\n_AUTO_DEFAULTS = {\n    \"bpm\": None,\n    \"key_scale\": \"\",\n    \"time_signature\": \"\",\n    \"vocal_language\": \"unknown\",\n    \"audio_duration\": -1,\n}\n\n\ndef on_auto_checkbox_change(auto_checked: bool, field_name: str):\n    \"\"\"Toggle a field between auto (non-interactive, reset to default) and manual.\n\n    Args:\n        auto_checked: Whether the Auto checkbox is now checked.\n        field_name: One of the keys in _AUTO_DEFAULTS.\n\n    Returns:\n        gr.update for the corresponding input component.\n    \"\"\"\n    if auto_checked:\n        return gr.update(value=_AUTO_DEFAULTS[field_name], interactive=False)\n    return gr.update(interactive=True)\n\n\ndef reset_all_auto():\n    \"\"\"Reset all optional-parameter Auto checkboxes to checked.\n\n    Returns:\n        Tuple of 10 gr.update objects.\n    \"\"\"\n    return (\n        gr.update(value=True),\n        gr.update(value=True),\n        gr.update(value=True),\n        gr.update(value=True),\n        gr.update(value=True),\n        gr.update(value=_AUTO_DEFAULTS[\"bpm\"], interactive=False),\n        gr.update(value=_AUTO_DEFAULTS[\"key_scale\"], interactive=False),\n        gr.update(value=_AUTO_DEFAULTS[\"time_signature\"], interactive=False),\n        gr.update(value=_AUTO_DEFAULTS[\"vocal_language\"], interactive=False),\n        gr.update(value=_AUTO_DEFAULTS[\"audio_duration\"], interactive=False),\n    )\n\n\ndef uncheck_auto_for_populated_fields(bpm, key_scale, time_signature, vocal_language, audio_duration):\n    \"\"\"Uncheck Auto checkboxes for fields that were populated by external events.\n\n    Args:\n        bpm: Current BPM value.\n        key_scale: Current key scale value.\n        time_signature: Current time signature value.\n        vocal_language: Current vocal language value.\n        audio_duration: Current audio duration value.\n\n    Returns:\n        Tuple of 10 gr.update objects.\n    \"\"\"\n    bpm_has_value = bpm is not None and bpm != _AUTO_DEFAULTS[\"bpm\"]\n    key_has_value = bool(key_scale and key_scale != _AUTO_DEFAULTS[\"key_scale\"])\n    ts_has_value = bool(time_signature and time_signature != _AUTO_DEFAULTS[\"time_signature\"])\n    vl_has_value = vocal_language not in (None, \"\", _AUTO_DEFAULTS[\"vocal_language\"])\n    dur_has_value = (\n        audio_duration is not None\n        and audio_duration != _AUTO_DEFAULTS[\"audio_duration\"]\n        and audio_duration > 0\n    )\n\n    return (\n        gr.update(value=not bpm_has_value),\n        gr.update(value=not key_has_value),\n        gr.update(value=not ts_has_value),\n        gr.update(value=not vl_has_value),\n        gr.update(value=not dur_has_value),\n        gr.update(interactive=bpm_has_value),\n        gr.update(interactive=key_has_value),\n        gr.update(interactive=ts_has_value),\n        gr.update(interactive=vl_has_value),\n        gr.update(interactive=dur_has_value),\n    )\n\n\ndef update_audio_cover_strength_visibility(task_type_value, init_llm_checked, reference_audio=None):\n    \"\"\"Update audio_cover_strength visibility and label.\"\"\"\n    has_reference = _has_reference_audio(reference_audio)\n    is_visible = (task_type_value == \"cover\") or init_llm_checked or has_reference\n    if task_type_value == \"cover\":\n        label = t(\"generation.cover_strength_label\")\n        help_text = t(\"generation.cover_strength_info\")\n    elif init_llm_checked:\n        label = t(\"generation.codes_strength_label\")\n        help_text = t(\"generation.codes_strength_info\")\n    elif has_reference:\n        label = t(\"generation.similarity_denoise_label\")\n        help_text = t(\"generation.similarity_denoise_info\")\n    else:\n        label = t(\"generation.cover_strength_label\")\n        help_text = t(\"generation.cover_strength_info\")\n    return gr.update(visible=is_visible, label=label, info=help_text, elem_classes=[\"has-info-container\"])\n\n\ndef convert_src_audio_to_codes_wrapper(dit_handler, src_audio):\n    \"\"\"Wrapper for converting src audio to codes.\"\"\"\n    codes_string = dit_handler.convert_src_audio_to_codes(src_audio)\n    return codes_string\n\n\ndef update_instruction_ui(\n    dit_handler,\n    task_type_value: str,\n    track_name_value: Optional[str],\n    complete_track_classes_value: list,\n    init_llm_checked: bool = False,\n    reference_audio=None,\n) -> tuple:\n    \"\"\"Update instruction text based on task type.\n\n    Visibility of track_name, complete_track_classes, and repainting_group\n    is managed by compute_mode_ui_updates (via generation_mode.change).\n    This function only regenerates the instruction string.\n    \"\"\"\n    instruction = dit_handler.generate_instruction(\n        task_type=task_type_value,\n        track_name=track_name_value,\n        complete_track_classes=complete_track_classes_value,\n    )\n    return instruction\n\n\ndef update_transcribe_button_text(audio_code_string):\n    \"\"\"Update the transcribe button text based on input content.\"\"\"\n    if not audio_code_string or not audio_code_string.strip():\n        return gr.update(value=\"Generate Example\")\n    else:\n        return gr.update(value=\"Transcribe\")\n\n\ndef reset_format_caption_flag():\n    \"\"\"Reset is_format_caption to False when user manually edits caption/metadata.\"\"\"\n    return False\n\n\ndef update_audio_uploads_accordion(reference_audio, src_audio):\n    \"\"\"Update Audio Uploads accordion open state based on whether audio files are present.\"\"\"\n    has_audio = (reference_audio is not None) or (src_audio is not None)\n    return gr.Accordion(open=has_audio)\n\n\ndef handle_instrumental_checkbox(instrumental_checked, current_lyrics, saved_lyrics):\n    \"\"\"Handle instrumental checkbox changes.\n\n    When checked: save current lyrics to state, replace with [Instrumental].\n    When unchecked: restore saved lyrics from state.\n\n    Returns:\n        Tuple of (lyrics, lyrics_before_instrumental_state).\n    \"\"\"\n    if instrumental_checked:\n        return \"[Instrumental]\", current_lyrics\n    else:\n        restored = saved_lyrics if saved_lyrics else \"\"\n        return restored, \"\"\n\n\ndef handle_simple_instrumental_change(is_instrumental: bool):\n    \"\"\"Handle simple mode instrumental checkbox changes.\n\n    Args:\n        is_instrumental: Whether instrumental checkbox is checked.\n\n    Returns:\n        gr.update for simple_vocal_language dropdown.\n    \"\"\"\n    if is_instrumental:\n        return gr.update(value=\"unknown\", interactive=False)\n    else:\n        return gr.update(interactive=True)\n\n\ndef update_audio_components_visibility(batch_size):\n    \"\"\"Show/hide individual audio components based on batch size (1-8).\n\n    Row 1: Components 1-4 (batch_size 1-4)\n    Row 2: Components 5-8 (batch_size 5-8)\n    \"\"\"\n    if batch_size is None:\n        batch_size = 1\n    else:\n        try:\n            batch_size = min(max(int(batch_size), 1), 8)\n        except (TypeError, ValueError):\n            batch_size = 1\n\n    updates_row1 = (\n        gr.update(visible=True),\n        gr.update(visible=batch_size >= 2),\n        gr.update(visible=batch_size >= 3),\n        gr.update(visible=batch_size >= 4),\n    )\n\n    show_row_5_8 = batch_size >= 5\n    updates_row2 = (\n        gr.update(visible=show_row_5_8),\n        gr.update(visible=batch_size >= 5),\n        gr.update(visible=batch_size >= 6),\n        gr.update(visible=batch_size >= 7),\n        gr.update(visible=batch_size >= 8),\n    )\n\n    return updates_row1 + updates_row2\n"
  },
  {
    "path": "acestep/ui/gradio/events/generation/validation.py",
    "content": "\"\"\"Input validation helpers for generation handlers.\n\nContains functions for clamping, parsing, and validating user inputs\nsuch as duration limits, timesteps, and uploaded audio files.\n\"\"\"\n\nimport re\nimport gradio as gr\nimport soundfile\nfrom typing import Any, Optional, List, Tuple\n\nfrom acestep.gpu_config import get_global_gpu_config\nfrom acestep.ui.gradio.i18n import t\n\n\ndef clamp_duration_to_gpu_limit(duration_value: Optional[float], llm_handler=None) -> Optional[float]:\n    \"\"\"Clamp duration value to GPU memory limit.\n\n    Args:\n        duration_value: Duration in seconds (can be None or -1 for no limit).\n        llm_handler: LLM handler instance (to check if LM is initialized).\n\n    Returns:\n        Clamped duration value, or original value if within limits.\n    \"\"\"\n    if duration_value is None or duration_value <= 0:\n        return duration_value\n\n    gpu_config = get_global_gpu_config()\n    lm_initialized = llm_handler.llm_initialized if llm_handler else False\n    max_duration = gpu_config.max_duration_with_lm if lm_initialized else gpu_config.max_duration_without_lm\n\n    if duration_value > max_duration:\n        return float(max_duration)\n\n    return duration_value\n\n\ndef parse_and_validate_timesteps(\n    timesteps_str: str,\n    inference_steps: int,\n) -> Tuple[Optional[List[float]], bool, str]:\n    \"\"\"Parse timesteps string and validate.\n\n    Args:\n        timesteps_str: Comma-separated timesteps string.\n        inference_steps: Expected number of inference steps.\n\n    Returns:\n        Tuple of (parsed_timesteps, has_warning, warning_message).\n    \"\"\"\n    if not timesteps_str or not timesteps_str.strip():\n        return None, False, \"\"\n\n    values = [v.strip() for v in timesteps_str.split(\",\") if v.strip()]\n    if not values:\n        return None, False, \"\"\n\n    if values[-1] != \"0\":\n        values.append(\"0\")\n\n    try:\n        timesteps = [float(v) for v in values]\n    except ValueError:\n        gr.Warning(t(\"messages.invalid_timesteps_format\"))\n        return None, True, \"Invalid format\"\n\n    if any(ts < 0 or ts > 1 for ts in timesteps):\n        gr.Warning(t(\"messages.timesteps_out_of_range\"))\n        return None, True, \"Out of range\"\n\n    actual_steps = len(timesteps) - 1\n    if actual_steps != inference_steps:\n        gr.Warning(t(\"messages.timesteps_count_mismatch\", actual=actual_steps, expected=inference_steps))\n        return timesteps, True, f\"Using {actual_steps} steps from timesteps\"\n\n    return timesteps, False, \"\"\n\n\ndef _has_reference_audio(reference_audio) -> bool:\n    \"\"\"True if *reference_audio* has a usable value.\"\"\"\n    if reference_audio is None:\n        return False\n    if isinstance(reference_audio, str):\n        return bool(reference_audio.strip())\n    if isinstance(reference_audio, (list, tuple)) and reference_audio:\n        return bool(reference_audio[0])\n    return False\n\n\ndef _extract_audio_path(audio_value: Any) -> Optional[str]:\n    \"\"\"Extract normalized audio path from common Gradio audio input forms.\n\n    Returns:\n        Optional[str]: normalized file path or ``None``.\n    \"\"\"\n    if audio_value is None:\n        return None\n    if isinstance(audio_value, str):\n        return audio_value.strip() or None\n    if isinstance(audio_value, (list, tuple)) and audio_value:\n        first = audio_value[0]\n        if isinstance(first, str):\n            return first.strip() or None\n    return None\n\n\ndef validate_uploaded_audio_file(audio_value: Any, audio_role: str = \"reference\") -> Any:\n    \"\"\"Validate uploaded audio and show a toast for invalid/unsupported files.\n\n    Args:\n        audio_value: Gradio Audio component value.\n        audio_role: User-facing label context.\n\n    Returns:\n        ``gr.skip()`` for valid files, or ``gr.update(value=None)`` to clear.\n    \"\"\"\n    audio_path = _extract_audio_path(audio_value)\n    if not audio_path:\n        return gr.skip()\n\n    try:\n        soundfile.info(audio_path)\n        return gr.skip()\n    except (OSError, RuntimeError, ValueError):\n        role_label = (\n            t(\"generation.reference_audio\")\n            if audio_role == \"reference\"\n            else t(\"generation.source_audio\")\n        )\n        gr.Warning(t(\"messages.audio_format_invalid\", role=role_label))\n        return gr.update(value=None)\n\n\ndef _contains_audio_code_tokens(codes_string: str) -> bool:\n    \"\"\"Return True when a string contains at least one serialized audio-code token.\"\"\"\n    if not isinstance(codes_string, str):\n        return False\n    return bool(re.search(r\"<\\|audio_code_\\d+\\|>\", codes_string))\n"
  },
  {
    "path": "acestep/ui/gradio/events/generation_handlers.py",
    "content": "\"\"\"Generation Input Handlers Module — Facade.\n\nRe-exports all public symbols from the ``generation`` sub-package so\nthat existing callers (e.g. ``events/__init__.py``) continue to work\nunchanged via ``from . import generation_handlers as gen_h``.\n\"\"\"\n\nfrom .generation.validation import (  # noqa: F401\n    clamp_duration_to_gpu_limit,\n    parse_and_validate_timesteps,\n    _has_reference_audio,\n    _extract_audio_path,\n    validate_uploaded_audio_file,\n    _contains_audio_code_tokens,\n)\nfrom .generation.metadata_loading import (  # noqa: F401\n    load_metadata,\n    load_random_example,\n    sample_example_smart,\n    load_random_simple_description,\n)\nfrom .generation.service_init import (  # noqa: F401\n    refresh_checkpoints,\n    init_service_wrapper,\n    on_tier_change,\n)\nfrom .generation.model_config import (  # noqa: F401\n    is_pure_base_model,\n    is_sft_model,\n    update_model_type_settings,\n    get_ui_control_config,\n    get_model_type_ui_settings,\n    get_generation_mode_choices,\n)\nfrom .generation.mode_ui import (  # noqa: F401\n    compute_mode_ui_updates,\n    handle_generation_mode_change,\n    handle_extract_track_name_change,\n    handle_extract_src_audio_change,\n)\nfrom .generation.llm_actions import (  # noqa: F401\n    handle_create_sample,\n    handle_format_sample,\n    handle_format_caption,\n    handle_format_lyrics,\n    transcribe_audio_codes,\n    analyze_src_audio,\n)\nfrom .generation.ui_helpers import (  # noqa: F401\n    update_negative_prompt_visibility,\n    on_auto_checkbox_change,\n    reset_all_auto,\n    uncheck_auto_for_populated_fields,\n    update_audio_cover_strength_visibility,\n    convert_src_audio_to_codes_wrapper,\n    update_instruction_ui,\n    update_transcribe_button_text,\n    reset_format_caption_flag,\n    update_audio_uploads_accordion,\n    handle_instrumental_checkbox,\n    handle_simple_instrumental_change,\n    update_audio_components_visibility,\n)\n"
  },
  {
    "path": "acestep/ui/gradio/events/generation_handlers_test.py",
    "content": "\"\"\"Unit tests for generation input event handlers.\"\"\"\n\nimport unittest\nfrom types import SimpleNamespace\nfrom unittest.mock import patch, MagicMock\n\ntry:\n    from acestep.ui.gradio.events import generation_handlers\n    from acestep.ui.gradio.i18n import t as _t\n    _IMPORT_ERROR = None\nexcept Exception as exc:  # pragma: no cover - environment dependency guard\n    generation_handlers = None\n    _t = None\n    _IMPORT_ERROR = exc\n\n\nclass _FakeDitHandler:\n    \"\"\"Minimal DiT handler stub for analyze-src-audio tests.\"\"\"\n\n    def __init__(self, convert_result):\n        \"\"\"Store a configurable conversion return value for test scenarios.\"\"\"\n        self._convert_result = convert_result\n        self.model = MagicMock()  # Required by analyze_src_audio guard\n\n    def convert_src_audio_to_codes(self, _src_audio):\n        \"\"\"Return configured conversion output.\"\"\"\n        return self._convert_result\n\n\n@unittest.skipIf(generation_handlers is None, f\"generation_handlers import unavailable: {_IMPORT_ERROR}\")\nclass GenerationHandlersTests(unittest.TestCase):\n    \"\"\"Tests for source-audio analysis validation behavior.\"\"\"\n\n    @patch(\"acestep.ui.gradio.events.generation.llm_analysis_actions.gr.Warning\")\n    @patch(\"acestep.ui.gradio.events.generation.llm_analysis_actions.understand_music\")\n    def test_analyze_src_audio_rejects_non_audio_code_output(\n        self,\n        understand_music_mock,\n        warning_mock,\n    ):\n        \"\"\"Reject conversion output that has no serialized audio-code tokens.\"\"\"\n        dit_handler = _FakeDitHandler(\"ERROR: not an audio file\")\n        llm_handler = SimpleNamespace(llm_initialized=True)\n\n        result = generation_handlers.analyze_src_audio(\n            dit_handler=dit_handler,\n            llm_handler=llm_handler,\n            src_audio=\"fake.mp3\",\n            constrained_decoding_debug=False,\n        )\n\n        # When codes_string has no audio-code tokens, the function returns\n        # (codes_string, warning_message, \"\", \"\", None, None, \"\", \"\", \"\", False)\n        from acestep.ui.gradio.i18n import t\n        self.assertEqual(\n            result,\n            (\"ERROR: not an audio file\", t(\"messages.no_audio_codes_generated\"),\n             \"\", \"\", None, None, \"\", \"\", \"\", False),\n        )\n        understand_music_mock.assert_not_called()\n        warning_mock.assert_called_once()\n\n    @patch(\"acestep.ui.gradio.events.generation.llm_analysis_actions.gr.Warning\")\n    @patch(\"acestep.ui.gradio.events.generation.llm_analysis_actions.understand_music\")\n    def test_analyze_src_audio_allows_valid_audio_code_output(\n        self,\n        understand_music_mock,\n        warning_mock,\n    ):\n        \"\"\"Pass valid audio codes through to LM understanding.\"\"\"\n        dit_handler = _FakeDitHandler(\"<|audio_code_123|><|audio_code_456|>\")\n        llm_handler = SimpleNamespace(llm_initialized=True)\n        understand_music_mock.return_value = SimpleNamespace(\n            success=True,\n            status_message=\"ok\",\n            caption=\"caption\",\n            lyrics=\"lyrics\",\n            bpm=120,\n            duration=30.0,\n            keyscale=\"C major\",\n            language=\"en\",\n            timesignature=\"4\",\n        )\n\n        result = generation_handlers.analyze_src_audio(\n            dit_handler=dit_handler,\n            llm_handler=llm_handler,\n            src_audio=\"real.mp3\",\n            constrained_decoding_debug=False,\n        )\n\n        self.assertEqual(result[0], \"<|audio_code_123|><|audio_code_456|>\")\n        self.assertEqual(result[1], \"ok\")\n        understand_music_mock.assert_called_once()\n        warning_mock.assert_not_called()\n\n    @patch(\"acestep.ui.gradio.events.generation.service_init.get_global_gpu_config\")\n    @patch(\"acestep.ui.gradio.events.generation.service_init.get_model_type_ui_settings\")\n    def test_init_service_wrapper_preserves_batch_size(\n        self,\n        get_model_type_ui_settings_mock,\n        get_global_gpu_config_mock,\n    ):\n        \"\"\"Verify that init_service_wrapper preserves current batch_size when provided.\"\"\"\n        # Setup mocks\n        gpu_config_mock = MagicMock()\n        gpu_config_mock.max_batch_size_with_lm = 8\n        gpu_config_mock.max_batch_size_without_lm = 4\n        gpu_config_mock.max_duration_with_lm = 600\n        gpu_config_mock.max_duration_without_lm = 300\n        gpu_config_mock.tier = \"tier5\"\n        gpu_config_mock.available_lm_models = [\"acestep-5Hz-lm-1.7B\"]\n        get_global_gpu_config_mock.return_value = gpu_config_mock\n\n        get_model_type_ui_settings_mock.return_value = (None,) * 9  # 9 model type settings\n\n        dit_handler = MagicMock()\n        dit_handler.model = MagicMock()\n        dit_handler.is_turbo_model.return_value = True\n        dit_handler.initialize_service.return_value = (\"Success\", True)\n\n        llm_handler = MagicMock()\n        llm_handler.llm_initialized = True\n        llm_handler.initialize.return_value = (\"LLM initialized\", True)\n\n        # Test with current_batch_size = 5\n        result = generation_handlers.init_service_wrapper(\n            dit_handler=dit_handler,\n            llm_handler=llm_handler,\n            checkpoint=None,\n            config_path=\"acestep-v15-turbo\",\n            device=\"cuda\",\n            init_llm=True,\n            lm_model_path=None,\n            backend=\"vllm\",\n            use_flash_attention=True,\n            offload_to_cpu=False,\n            offload_dit_to_cpu=False,\n            compile_model=False,\n            quantization=False,\n            mlx_dit=False,\n            current_mode=\"Custom\",\n            current_batch_size=5,\n        )\n\n        # Result is a tuple: (status, btn_update, accordion, *model_settings, duration_update, batch_update, think_update)\n        # batch_update is at index -2 (second to last)\n        batch_update = result[-2]\n        \n        # Verify batch_update preserves the value 5 (clamped to max_batch of 8)\n        self.assertEqual(batch_update[\"value\"], 5)\n        self.assertEqual(batch_update[\"maximum\"], 8)\n\n    @patch(\"acestep.ui.gradio.events.generation.service_init.get_global_gpu_config\")\n    @patch(\"acestep.ui.gradio.events.generation.service_init.get_model_type_ui_settings\")\n    def test_init_service_wrapper_defaults_batch_size_when_none(\n        self,\n        get_model_type_ui_settings_mock,\n        get_global_gpu_config_mock,\n    ):\n        \"\"\"Verify that init_service_wrapper uses default batch_size when current_batch_size is None.\"\"\"\n        # Setup mocks\n        gpu_config_mock = MagicMock()\n        gpu_config_mock.max_batch_size_with_lm = 8\n        gpu_config_mock.max_batch_size_without_lm = 4\n        gpu_config_mock.max_duration_with_lm = 600\n        gpu_config_mock.max_duration_without_lm = 300\n        gpu_config_mock.tier = \"tier5\"\n        gpu_config_mock.available_lm_models = [\"acestep-5Hz-lm-1.7B\"]\n        get_global_gpu_config_mock.return_value = gpu_config_mock\n\n        get_model_type_ui_settings_mock.return_value = (None,) * 9\n\n        dit_handler = MagicMock()\n        dit_handler.model = MagicMock()\n        dit_handler.is_turbo_model.return_value = True\n        dit_handler.initialize_service.return_value = (\"Success\", True)\n\n        llm_handler = MagicMock()\n        llm_handler.llm_initialized = True\n        llm_handler.initialize.return_value = (\"LLM initialized\", True)\n\n        # Test with current_batch_size = None (should default to 2)\n        result = generation_handlers.init_service_wrapper(\n            dit_handler=dit_handler,\n            llm_handler=llm_handler,\n            checkpoint=None,\n            config_path=\"acestep-v15-turbo\",\n            device=\"cuda\",\n            init_llm=True,\n            lm_model_path=None,\n            backend=\"vllm\",\n            use_flash_attention=True,\n            offload_to_cpu=False,\n            offload_dit_to_cpu=False,\n            compile_model=False,\n            quantization=False,\n            mlx_dit=False,\n            current_mode=\"Custom\",\n            current_batch_size=None,\n        )\n\n        batch_update = result[-2]\n        \n        # Verify batch_update defaults to min(2, max_batch)\n        self.assertEqual(batch_update[\"value\"], 2)\n        self.assertEqual(batch_update[\"maximum\"], 8)\n\n    @patch(\"acestep.ui.gradio.events.generation.validation.gr.Warning\")\n    @patch(\"acestep.ui.gradio.events.generation.validation.soundfile.info\")\n    def test_validate_uploaded_audio_file_returns_none_for_invalid_file(\n        self,\n        info_mock,\n        warning_mock,\n    ):\n        \"\"\"Invalid audio upload should emit warning toast and clear component value.\"\"\"\n        info_mock.side_effect = RuntimeError(\"bad file\")\n        result = generation_handlers.validate_uploaded_audio_file(\"broken.bin\", \"reference\")\n        self.assertEqual(result.get(\"value\"), None)\n        warning_mock.assert_called_once()\n\n    @patch(\"acestep.ui.gradio.events.generation.validation.gr.Warning\")\n    @patch(\"acestep.ui.gradio.events.generation.validation.soundfile.info\")\n    def test_validate_uploaded_audio_file_keeps_valid_file(\n        self,\n        info_mock,\n        warning_mock,\n    ):\n        \"\"\"Valid audio upload should pass through unchanged without warning.\"\"\"\n        result = generation_handlers.validate_uploaded_audio_file(\"ok.wav\", \"reference\")\n        self.assertEqual(result, {\"__type__\": \"update\"})\n        info_mock.assert_called_once_with(\"ok.wav\")\n        warning_mock.assert_not_called()\n\n    @patch(\"acestep.ui.gradio.events.generation.validation.gr.Warning\")\n    @patch(\"acestep.ui.gradio.events.generation.validation.soundfile.info\")\n    def test_validate_uploaded_audio_file_shows_source_role_message(\n        self,\n        info_mock,\n        warning_mock,\n    ):\n        \"\"\"Source-role validation should surface a source-specific toast message.\"\"\"\n        info_mock.side_effect = RuntimeError(\"bad file\")\n        result = generation_handlers.validate_uploaded_audio_file(\"broken.bin\", \"source\")\n        self.assertEqual(result.get(\"value\"), None)\n        expected_role = _t(\"generation.source_audio\")\n        expected_message = _t(\"messages.audio_format_invalid\", role=expected_role)\n        warning_mock.assert_called_once_with(\n            expected_message\n        )\n\n    @patch(\"acestep.ui.gradio.events.generation.llm_sample_actions.gr.Info\")\n    @patch(\"acestep.ui.gradio.events.generation.llm_sample_actions.create_sample\")\n    def test_handle_create_sample_success_path(\n        self,\n        create_sample_mock,\n        info_mock,\n    ):\n        \"\"\"Successful sample creation should populate generation fields and mode switch.\"\"\"\n        llm_handler = SimpleNamespace(llm_initialized=True)\n        create_sample_mock.return_value = SimpleNamespace(\n            success=True,\n            caption=\"new caption\",\n            lyrics=\"new lyrics\",\n            bpm=120,\n            duration=42.0,\n            keyscale=\"C major\",\n            language=\"en\",\n            timesignature=\"4\",\n            instrumental=False,\n            status_message=\"ok\",\n        )\n\n        result = generation_handlers.handle_create_sample(\n            llm_handler=llm_handler,\n            query=\"test prompt\",\n            instrumental=False,\n            vocal_language=\"en\",\n            lm_temperature=0.85,\n            lm_top_k=20,\n            lm_top_p=0.9,\n            constrained_decoding_debug=False,\n        )\n\n        self.assertEqual(result[0], \"new caption\")\n        self.assertEqual(result[1], \"new lyrics\")\n        self.assertEqual(result[3], 42.0)\n        self.assertEqual(result[5], \"en\")\n        self.assertEqual(result[6], \"en\")\n        self.assertEqual(len(result), 15)\n        self.assertTrue(result[10])\n        self.assertEqual(result[13], \"ok\")\n        self.assertEqual(result[14][\"value\"], \"Custom\")\n        create_sample_mock.assert_called_once()\n        info_mock.assert_called_once()\n\n    @patch(\"acestep.ui.gradio.events.generation.llm_format_actions.gr.Warning\")\n    def test_handle_format_caption_lm_not_initialized_regression(self, warning_mock):\n        \"\"\"Caption formatting should return lm-not-initialized status when LM is unavailable.\"\"\"\n        llm_handler = SimpleNamespace(llm_initialized=False)\n\n        result = generation_handlers.handle_format_caption(\n            llm_handler=llm_handler,\n            caption=\"caption\",\n            lyrics=\"lyrics\",\n            bpm=120,\n            audio_duration=30.0,\n            key_scale=\"C major\",\n            time_signature=\"4\",\n            lm_temperature=0.85,\n            lm_top_k=0,\n            lm_top_p=0.9,\n            constrained_decoding_debug=False,\n        )\n\n        self.assertEqual(result[-1], _t(\"messages.lm_not_initialized\"))\n        warning_mock.assert_called_once_with(_t(\"messages.lm_not_initialized\"))\n\n    @patch(\"acestep.ui.gradio.events.generation.llm_format_actions.gr.Info\")\n    @patch(\"acestep.ui.gradio.events.generation.llm_format_actions.format_sample\")\n    def test_handle_format_lyrics_strips_quotes(self, format_sample_mock, info_mock):\n        \"\"\"Lyrics-only formatting should strip wrapper quotes from returned lyrics.\"\"\"\n        llm_handler = SimpleNamespace(llm_initialized=True)\n        format_sample_mock.return_value = SimpleNamespace(\n            success=True,\n            caption=\"unused\",\n            lyrics=\"'quoted lyrics'\",\n            bpm=100,\n            duration=10.0,\n            keyscale=\"D minor\",\n            language=\"en\",\n            timesignature=\"4\",\n            status_message=\"formatted\",\n        )\n\n        result = generation_handlers.handle_format_lyrics(\n            llm_handler=llm_handler,\n            caption=\"caption\",\n            lyrics=\"lyrics\",\n            bpm=100,\n            audio_duration=10.0,\n            key_scale=\"D minor\",\n            time_signature=\"4\",\n            lm_temperature=0.85,\n            lm_top_k=0,\n            lm_top_p=0.9,\n            constrained_decoding_debug=False,\n        )\n\n        self.assertEqual(result[0], \"quoted lyrics\")\n        self.assertEqual(result[4], \"en\")\n        self.assertEqual(len(result), 8)\n        self.assertEqual(result[-1], \"formatted\")\n        format_sample_mock.assert_called_once()\n        info_mock.assert_called_once()\n\n    @patch(\"acestep.ui.gradio.events.generation.llm_format_actions.gr.Info\")\n    @patch(\"acestep.ui.gradio.events.generation.llm_format_actions.format_sample\")\n    def test_handle_format_sample_preserves_output_contract(self, format_sample_mock, info_mock):\n        \"\"\"Full sample formatting should return 9 outputs with language at index 5.\"\"\"\n        llm_handler = SimpleNamespace(llm_initialized=True)\n        format_sample_mock.return_value = SimpleNamespace(\n            success=True,\n            caption=\"caption out\",\n            lyrics=\"lyrics out\",\n            bpm=112,\n            duration=12.0,\n            keyscale=\"G major\",\n            language=\"en\",\n            timesignature=\"3/4\",\n            status_message=\"formatted\",\n        )\n\n        result = generation_handlers.handle_format_sample(\n            llm_handler=llm_handler,\n            caption=\"caption in\",\n            lyrics=\"lyrics in\",\n            bpm=112,\n            audio_duration=12.0,\n            key_scale=\"G major\",\n            time_signature=\"3/4\",\n            lm_temperature=0.85,\n            lm_top_k=0,\n            lm_top_p=0.9,\n            constrained_decoding_debug=False,\n        )\n\n        self.assertEqual(len(result), 9)\n        self.assertEqual(result[5], \"en\")\n        self.assertEqual(result[8], \"formatted\")\n        format_sample_mock.assert_called_once()\n        info_mock.assert_called_once()\n\n\n@unittest.skipIf(generation_handlers is None, f\"generation_handlers import unavailable: {_IMPORT_ERROR}\")\nclass LoadMetadataLmCodesTests(unittest.TestCase):\n    \"\"\"Tests that load_metadata sets think=False when audio_codes are present.\"\"\"\n\n    def _write_json(self, tmpdir, data):\n        \"\"\"Write a JSON file and return a SimpleNamespace with .name pointing to it.\"\"\"\n        import json, os\n        path = os.path.join(tmpdir, \"test.json\")\n        with open(path, \"w\") as f:\n            json.dump(data, f)\n        return SimpleNamespace(name=path)\n\n    @patch(\"acestep.ui.gradio.events.generation.metadata_loading.gr.Info\")\n    @patch(\"acestep.ui.gradio.events.generation.metadata_loading.get_global_gpu_config\")\n    def test_think_set_false_when_audio_codes_present(self, gpu_mock, info_mock):\n        \"\"\"When JSON has thinking=True AND non-empty audio_codes, think should be False.\"\"\"\n        import tempfile\n        gpu_cfg = MagicMock()\n        gpu_cfg.max_batch_size_with_lm = 8\n        gpu_cfg.max_batch_size_without_lm = 8\n        gpu_mock.return_value = gpu_cfg\n\n        llm_handler = SimpleNamespace(llm_initialized=True)\n\n        with tempfile.TemporaryDirectory() as tmpdir:\n            file_obj = self._write_json(tmpdir, {\n                \"thinking\": True,\n                \"audio_codes\": \"<|audio_code_1|><|audio_code_2|>\",\n            })\n            result = generation_handlers.load_metadata(file_obj, llm_handler)\n\n        # think is at return position 30 (0-indexed)\n        think_value = result[30]\n        audio_codes_value = result[31]\n        self.assertFalse(think_value, \"think should be False when audio_codes present\")\n        self.assertEqual(audio_codes_value, \"<|audio_code_1|><|audio_code_2|>\")\n\n    @patch(\"acestep.ui.gradio.events.generation.metadata_loading.gr.Info\")\n    @patch(\"acestep.ui.gradio.events.generation.metadata_loading.get_global_gpu_config\")\n    def test_think_unchanged_when_audio_codes_empty(self, gpu_mock, info_mock):\n        \"\"\"When JSON has thinking=True AND empty audio_codes, think stays True.\"\"\"\n        import tempfile\n        gpu_cfg = MagicMock()\n        gpu_cfg.max_batch_size_with_lm = 8\n        gpu_cfg.max_batch_size_without_lm = 8\n        gpu_mock.return_value = gpu_cfg\n\n        llm_handler = SimpleNamespace(llm_initialized=True)\n\n        with tempfile.TemporaryDirectory() as tmpdir:\n            file_obj = self._write_json(tmpdir, {\n                \"thinking\": True,\n                \"audio_codes\": \"\",\n            })\n            result = generation_handlers.load_metadata(file_obj, llm_handler)\n\n        think_value = result[30]\n        self.assertTrue(think_value, \"think should remain True when audio_codes is empty\")\n\n\n@unittest.skipIf(generation_handlers is None, f\"generation_handlers import unavailable: {_IMPORT_ERROR}\")\nclass AutoCheckboxTests(unittest.TestCase):\n    \"\"\"Tests for optional-parameter Auto checkbox handler functions.\"\"\"\n\n    def test_on_auto_checkbox_change_checked_returns_default_and_non_interactive(self):\n        \"\"\"When Auto is checked, field should reset to default and become non-interactive.\"\"\"\n        result = generation_handlers.on_auto_checkbox_change(True, \"bpm\")\n        # gr.update returns a dict-like object; check value and interactive\n        self.assertIsNone(result[\"value\"])\n        self.assertFalse(result[\"interactive\"])\n\n    def test_on_auto_checkbox_change_unchecked_returns_interactive(self):\n        \"\"\"When Auto is unchecked, field should become interactive (no value reset).\"\"\"\n        result = generation_handlers.on_auto_checkbox_change(False, \"bpm\")\n        self.assertTrue(result[\"interactive\"])\n\n    def test_on_auto_checkbox_change_all_fields(self):\n        \"\"\"All supported field names should produce valid defaults when checked.\"\"\"\n        expected = {\n            \"bpm\": None,\n            \"key_scale\": \"\",\n            \"time_signature\": \"\",\n            \"vocal_language\": \"unknown\",\n            \"audio_duration\": -1,\n        }\n        for field_name, expected_value in expected.items():\n            result = generation_handlers.on_auto_checkbox_change(True, field_name)\n            self.assertEqual(result[\"value\"], expected_value, f\"Field {field_name}\")\n            self.assertFalse(result[\"interactive\"], f\"Field {field_name}\")\n\n    def test_reset_all_auto_returns_correct_count(self):\n        \"\"\"reset_all_auto should return exactly 10 gr.update objects.\"\"\"\n        result = generation_handlers.reset_all_auto()\n        self.assertEqual(len(result), 10)\n\n    def test_reset_all_auto_checkboxes_are_true(self):\n        \"\"\"First 5 outputs (auto checkboxes) should all be set to True.\"\"\"\n        result = generation_handlers.reset_all_auto()\n        for i in range(5):\n            self.assertTrue(result[i][\"value\"], f\"Auto checkbox at index {i}\")\n\n    def test_reset_all_auto_fields_are_defaults(self):\n        \"\"\"Last 5 outputs (fields) should be reset to auto defaults.\"\"\"\n        result = generation_handlers.reset_all_auto()\n        self.assertIsNone(result[5][\"value\"])         # bpm\n        self.assertEqual(result[6][\"value\"], \"\")       # key_scale\n        self.assertEqual(result[7][\"value\"], \"\")       # time_signature\n        self.assertEqual(result[8][\"value\"], \"unknown\") # vocal_language\n        self.assertEqual(result[9][\"value\"], -1)       # audio_duration\n\n    def test_uncheck_auto_for_populated_fields_all_default(self):\n        \"\"\"When all fields have default values, all auto checkboxes should stay checked.\"\"\"\n        result = generation_handlers.uncheck_auto_for_populated_fields(\n            bpm=None, key_scale=\"\", time_signature=\"\",\n            vocal_language=\"unknown\", audio_duration=-1,\n        )\n        self.assertEqual(len(result), 10)\n        # Auto checkboxes should be True (checked)\n        for i in range(5):\n            self.assertTrue(result[i][\"value\"], f\"Auto checkbox at index {i}\")\n        # Fields should be non-interactive\n        for i in range(5, 10):\n            self.assertFalse(result[i][\"interactive\"], f\"Field at index {i}\")\n\n    def test_uncheck_auto_for_populated_fields_all_populated(self):\n        \"\"\"When all fields have non-default values, all auto checkboxes should be unchecked.\"\"\"\n        result = generation_handlers.uncheck_auto_for_populated_fields(\n            bpm=120, key_scale=\"C major\", time_signature=\"4\",\n            vocal_language=\"en\", audio_duration=30.0,\n        )\n        # Auto checkboxes should be False (unchecked)\n        for i in range(5):\n            self.assertFalse(result[i][\"value\"], f\"Auto checkbox at index {i}\")\n        # Fields should be interactive\n        for i in range(5, 10):\n            self.assertTrue(result[i][\"interactive\"], f\"Field at index {i}\")\n\n    def test_uncheck_auto_for_populated_fields_mixed(self):\n        \"\"\"Mixed populated/default fields should only uncheck populated ones.\"\"\"\n        result = generation_handlers.uncheck_auto_for_populated_fields(\n            bpm=120, key_scale=\"\", time_signature=\"4\",\n            vocal_language=\"unknown\", audio_duration=-1,\n        )\n        self.assertFalse(result[0][\"value\"])   # bpm_auto unchecked\n        self.assertTrue(result[1][\"value\"])    # key_auto stays checked\n        self.assertFalse(result[2][\"value\"])   # timesig_auto unchecked\n        self.assertTrue(result[3][\"value\"])    # vocal_lang_auto stays checked\n        self.assertTrue(result[4][\"value\"])    # duration_auto stays checked\n\n\nif __name__ == \"__main__\":\n    unittest.main()\n"
  },
  {
    "path": "acestep/ui/gradio/events/results/__init__.py",
    "content": "\"\"\"\nResults sub-package.\n\nFocused modules for result handling, scoring, batch management, LRC utilities,\naudio transfer, and generation progress.\n\"\"\"\n"
  },
  {
    "path": "acestep/ui/gradio/events/results/_batch_management_test_support.py",
    "content": "\"\"\"Shared test utilities for ``batch_management`` unit tests.\"\"\"\n\nfrom __future__ import annotations\n\nimport importlib.util\nfrom pathlib import Path\nimport sys\nimport types\nfrom typing import Any, Dict, Tuple\nfrom unittest.mock import patch\n\n\n_MISSING = object()\n\n\ndef build_progress_result(*, length: int = 48, all_audio_paths: Any = _MISSING) -> tuple:\n    \"\"\"Build a minimally valid ``generate_with_progress`` result tuple.\"\"\"\n    result = [None] * length\n    for idx in range(8):\n        result[idx] = {\"value\": f\"audio_{idx}.flac\", \"playback_position\": 0}\n    result[8] = [\"audio_0.flac\", \"audio_0.json\"] if all_audio_paths is _MISSING else all_audio_paths\n    result[9] = \"generation info\"\n    result[10] = \"Generation Complete\"\n    result[11] = \"42\"\n    result[44] = {\"bpm\": 120}\n    result[45] = False\n    if length > 46:\n        result[46] = {\"lrcs\": [\"lrc\"] * 8, \"subtitles\": [\"sub\"] * 8}\n    if length > 47:\n        result[47] = [\"codes\"] * 8\n    if length > 48:\n        result[48] = {\"future_tail_field\": True}\n    return tuple(result)\n\n\ndef load_batch_management_module(\n    *, is_windows: bool = False, mps_available: bool = False\n) -> Tuple[Any, Dict[str, Any]]:\n    \"\"\"Load ``batch_management.py`` with dependency stubs and trackers.\n\n    Args:\n        is_windows: Simulate Windows platform flag in ``generation_info`` stub.\n        mps_available: When True, the fake ``torch`` stub will expose\n            ``torch.mps.empty_cache`` so MPS code-paths can be exercised.\n    \"\"\"\n    state: Dict[str, Any] = {\n        \"store_calls\": [],\n        \"info_messages\": [],\n        \"warning_messages\": [],\n        \"log_info\": [],\n        \"log_warning\": [],\n        \"cuda_empty_cache_calls\": 0,\n        \"mps_empty_cache_calls\": 0,\n    }\n\n    def _gr_update(**kwargs):\n        \"\"\"Return a deterministic Gradio-like update payload.\"\"\"\n        return {\"kind\": \"update\", **kwargs}\n\n    def _gr_skip():\n        \"\"\"Return a deterministic Gradio-like skip payload.\"\"\"\n        return {\"kind\": \"skip\"}\n\n    def _gr_info(message):\n        \"\"\"Capture ``gr.Info`` messages for assertions.\"\"\"\n        state[\"info_messages\"].append(message)\n\n    def _gr_warning(message):\n        \"\"\"Capture ``gr.Warning`` messages for assertions.\"\"\"\n        state[\"warning_messages\"].append(message)\n\n    def _logger_info(message):\n        \"\"\"Capture logger info messages for assertions.\"\"\"\n        state[\"log_info\"].append(str(message))\n\n    def _logger_warning(message):\n        \"\"\"Capture logger warning messages for assertions.\"\"\"\n        state[\"log_warning\"].append(str(message))\n\n    def _default_generate_with_progress(*_args, **_kwargs):\n        \"\"\"Default empty generator placeholder patched per test.\"\"\"\n        if False:\n            yield None\n\n    def _store_batch_in_queue(batch_queue, batch_idx, all_audio_paths, generation_info, seed_value_for_ui, **kwargs):\n        \"\"\"Store synthetic batch data and keep call history for assertions.\"\"\"\n        call = {\n            \"batch_queue\": dict(batch_queue),\n            \"batch_idx\": batch_idx,\n            \"all_audio_paths\": all_audio_paths,\n            \"generation_info\": generation_info,\n            \"seed_value_for_ui\": seed_value_for_ui,\n            **kwargs,\n        }\n        state[\"store_calls\"].append(call)\n        next_queue = dict(batch_queue)\n        next_queue[batch_idx] = {\"status\": \"completed\", **call}\n        return next_queue\n\n    def _translate(key, **kwargs):\n        \"\"\"Return predictable translation output with formatted kwargs.\"\"\"\n        return f\"{key}|{kwargs}\" if kwargs else key\n\n    # --- Fake torch stub --------------------------------------------------\n    # Provides just enough of the torch API used by batch-management modules\n    # (torch.cuda.is_available, torch.cuda.empty_cache, torch.mps.empty_cache).\n    # Call counts are recorded in ``state`` for assertion in tests.\n    def _cuda_empty_cache():\n        state[\"cuda_empty_cache_calls\"] += 1\n\n    fake_cuda = types.SimpleNamespace(\n        is_available=lambda: False,\n        empty_cache=_cuda_empty_cache,\n    )\n\n    fake_torch = types.ModuleType(\"torch\")\n    fake_torch.cuda = fake_cuda\n\n    fake_backends_mps = types.SimpleNamespace(is_available=lambda: mps_available)\n    fake_torch.backends = types.SimpleNamespace(mps=fake_backends_mps)\n\n    if mps_available:\n        def _mps_empty_cache():\n            state[\"mps_empty_cache_calls\"] += 1\n\n        fake_torch.mps = types.SimpleNamespace(empty_cache=_mps_empty_cache)\n    # When mps_available is False, ``torch.mps`` is absent, so\n    # ``hasattr(torch, \"mps\")`` returns False and the cache call is skipped.\n    # -----------------------------------------------------------------------\n\n    acestep_pkg = types.ModuleType(\"acestep\")\n    ui_pkg = types.ModuleType(\"acestep.ui\")\n    gradio_pkg = types.ModuleType(\"acestep.ui.gradio\")\n    events_pkg = types.ModuleType(\"acestep.ui.gradio.events\")\n    results_pkg = types.ModuleType(\"acestep.ui.gradio.events.results\")\n\n    results_dir = Path(__file__).resolve().parent\n    events_dir = results_dir.parent\n    gradio_dir = events_dir.parent\n    ui_dir = gradio_dir.parent\n    acestep_dir = ui_dir.parent\n\n    acestep_pkg.__path__ = [str(acestep_dir)]\n    ui_pkg.__path__ = [str(ui_dir)]\n    gradio_pkg.__path__ = [str(gradio_dir)]\n    events_pkg.__path__ = [str(events_dir)]\n    results_pkg.__path__ = [str(results_dir)]\n\n    fake_gradio = types.ModuleType(\"gradio\")\n    fake_gradio.update = _gr_update\n    fake_gradio.skip = _gr_skip\n    fake_gradio.Progress = lambda track_tqdm=True: None\n    fake_gradio.Info = _gr_info\n    fake_gradio.Warning = _gr_warning\n\n    fake_logger = types.SimpleNamespace(\n        info=_logger_info,\n        warning=_logger_warning,\n        error=lambda _msg: None,\n    )\n\n    modules = {\n        \"gradio\": fake_gradio,\n        \"torch\": fake_torch,\n        \"loguru\": types.SimpleNamespace(logger=fake_logger),\n        \"acestep\": acestep_pkg,\n        \"acestep.ui\": ui_pkg,\n        \"acestep.ui.gradio\": gradio_pkg,\n        \"acestep.ui.gradio.i18n\": types.SimpleNamespace(t=_translate),\n        \"acestep.ui.gradio.events\": events_pkg,\n        \"acestep.ui.gradio.events.results\": results_pkg,\n        \"acestep.ui.gradio.events.results.generation_info\": types.SimpleNamespace(IS_WINDOWS=is_windows),\n        \"acestep.ui.gradio.events.results.generation_progress\": types.SimpleNamespace(\n            generate_with_progress=_default_generate_with_progress\n        ),\n        \"acestep.ui.gradio.events.results.batch_queue\": types.SimpleNamespace(\n            store_batch_in_queue=_store_batch_in_queue,\n            update_batch_indicator=lambda current, total: f\"Batch {current + 1}/{total}\",\n            update_navigation_buttons=lambda current, total: (current > 0, current < total - 1),\n        ),\n    }\n\n    acestep_pkg.ui = ui_pkg\n    ui_pkg.gradio = gradio_pkg\n    gradio_pkg.events = events_pkg\n    events_pkg.results = results_pkg\n\n    for module_name in list(sys.modules):\n        if module_name.startswith(\"acestep.ui.gradio.events.results.batch_management\"):\n            sys.modules.pop(module_name, None)\n\n    module_path = Path(__file__).with_name(\"batch_management.py\")\n    spec = importlib.util.spec_from_file_location(\"batch_management\", module_path)\n    module = importlib.util.module_from_spec(spec)\n    with patch.dict(\"sys.modules\", modules):\n        spec.loader.exec_module(module)  # type: ignore[union-attr]\n    return module, state\n"
  },
  {
    "path": "acestep/ui/gradio/events/results/audio_playback_updates.py",
    "content": "\"\"\"Audio playback update helpers for Gradio result players.\n\nThese helpers standardize audio update payloads so playback always rewinds to\nthe start of the track when a new value is assigned.\n\"\"\"\n\nfrom typing import Any, Optional\n\n\ndef build_audio_slot_update(\n    gr_module: Any,\n    audio_path: Optional[str],\n    *,\n    label: Optional[str] = None,\n    interactive: Optional[bool] = None,\n) -> Any:\n    \"\"\"Build an audio slot update that always rewinds playback to 0.\n\n    Args:\n        gr_module: Module/object exposing ``update(**kwargs)``.\n        audio_path: Filepath for the audio component, or ``None`` to clear.\n        label: Optional component label override.\n        interactive: Optional component interactivity override.\n\n    Returns:\n        The framework-specific update object returned by ``gr_module.update``.\n    \"\"\"\n    update_kwargs = {\n        \"value\": audio_path,\n        \"playback_position\": 0,\n    }\n    if label is not None:\n        update_kwargs[\"label\"] = label\n    if interactive is not None:\n        update_kwargs[\"interactive\"] = interactive\n    return gr_module.update(**update_kwargs)\n"
  },
  {
    "path": "acestep/ui/gradio/events/results/audio_playback_updates_test.py",
    "content": "\"\"\"Unit tests for audio_playback_updates helpers.\"\"\"\n\nimport importlib.util\nfrom pathlib import Path\nimport unittest\n\n\ndef _load_module():\n    \"\"\"Load the target module directly by file path for isolated testing.\"\"\"\n    module_path = Path(__file__).with_name(\"audio_playback_updates.py\")\n    spec = importlib.util.spec_from_file_location(\"audio_playback_updates\", module_path)\n    module = importlib.util.module_from_spec(spec)\n    spec.loader.exec_module(module)  # type: ignore[union-attr]\n    return module\n\n\n_MODULE = _load_module()\nbuild_audio_slot_update = _MODULE.build_audio_slot_update\n\n\nclass _FakeGr:\n    \"\"\"Minimal Gradio-like stub exposing ``update``.\"\"\"\n\n    @staticmethod\n    def update(**kwargs):\n        \"\"\"Return kwargs for direct assertion in tests.\"\"\"\n        return kwargs\n\n\nclass AudioPlaybackUpdatesTests(unittest.TestCase):\n    \"\"\"Behavior tests for audio playback update builders.\"\"\"\n\n    def test_build_audio_slot_update_sets_value_and_rewinds(self):\n        \"\"\"Success path: slot update should carry path and playback reset.\"\"\"\n        sample_path = \"sample.flac\"\n        result = build_audio_slot_update(\n            _FakeGr,\n            sample_path,\n            label=\"Sample 1 (Ready)\",\n            interactive=False,\n        )\n        self.assertEqual(result[\"value\"], sample_path)\n        self.assertEqual(result[\"playback_position\"], 0)\n        self.assertEqual(result[\"label\"], \"Sample 1 (Ready)\")\n        self.assertFalse(result[\"interactive\"])\n\n    def test_build_audio_slot_update_clear_path_rewinds(self):\n        \"\"\"Regression path: clearing a slot should still force playback to start.\"\"\"\n        result = build_audio_slot_update(_FakeGr, None)\n        self.assertEqual(result[\"value\"], None)\n        self.assertEqual(result[\"playback_position\"], 0)\n\n    def test_build_audio_slot_update_without_optional_flags_preserves_defaults(self):\n        \"\"\"Non-target behavior: no label/interactivity overrides unless explicitly passed.\"\"\"\n        sample_path = \"sample.flac\"\n        result = build_audio_slot_update(_FakeGr, sample_path)\n        self.assertEqual(result[\"value\"], sample_path)\n        self.assertEqual(result[\"playback_position\"], 0)\n        self.assertNotIn(\"label\", result)\n        self.assertNotIn(\"interactive\", result)\n\n\nif __name__ == \"__main__\":\n    unittest.main()\n"
  },
  {
    "path": "acestep/ui/gradio/events/results/audio_transfer.py",
    "content": "\"\"\"Audio transfer helpers: send-to-Remix/Repaint and audio-to-codes conversion.\n\nProvides handlers that wire generated audio outputs back into the\ngeneration UI for remix, repaint, and code extraction workflows.\n\"\"\"\nimport gradio as gr\n\nfrom acestep.ui.gradio.i18n import t\nfrom acestep.ui.gradio.events.generation_handlers import compute_mode_ui_updates\n\n\ndef send_audio_to_src_with_metadata(audio_file, lm_metadata):\n    \"\"\"Send generated audio file to ``src_audio`` input.\n\n    Only sets the audio field; all other metadata fields are preserved via\n    ``gr.skip()``.\n\n    Args:\n        audio_file: Audio file path.\n        lm_metadata: LM metadata dict (unused, kept for API compat).\n\n    Returns:\n        10-tuple of Gradio updates.\n    \"\"\"\n    if audio_file is None:\n        return (gr.skip(),) * 10\n    return (\n        audio_file,\n        gr.skip(),  # bpm\n        gr.skip(),  # caption\n        gr.skip(),  # lyrics\n        gr.skip(),  # duration\n        gr.skip(),  # key_scale\n        gr.skip(),  # language\n        gr.skip(),  # time_signature\n        gr.skip(),  # is_format_caption\n        gr.Accordion(open=True),  # audio_uploads_accordion\n    )\n\n\ndef _extract_metadata_for_editing(lm_metadata, current_lyrics=\"\", current_caption=\"\"):\n    \"\"\"Extract lyrics and caption from *lm_metadata* with UI fallbacks.\n\n    Args:\n        lm_metadata: Metadata dictionary from LM generation (or ``None``).\n        current_lyrics: Current lyrics value from the UI.\n        current_caption: Current caption value from the UI.\n\n    Returns:\n        Tuple of ``(lyrics, caption)`` strings.\n    \"\"\"\n    lyrics = current_lyrics or \"\"\n    caption = current_caption or \"\"\n    if lm_metadata and isinstance(lm_metadata, dict):\n        lyrics = lm_metadata.get(\"lyrics\", lyrics)\n        caption = lm_metadata.get(\"caption\", caption)\n    return lyrics, caption\n\n\ndef send_audio_to_remix(audio_file, lm_metadata, current_lyrics, current_caption,\n                        current_mode, llm_handler=None):\n    \"\"\"Send generated audio to ``src_audio`` and switch mode to Remix.\n\n    Populates lyrics/caption from the generated audio and applies all\n    Remix-mode UI updates atomically.\n\n    Args:\n        audio_file: Generated audio file path.\n        lm_metadata: LM metadata dict (may be ``None``).\n        current_lyrics: Current lyrics text in the UI.\n        current_caption: Current caption text in the UI.\n        current_mode: Currently active mode string.\n        llm_handler: Optional LLM handler.\n\n    Returns:\n        50-tuple of Gradio updates (4 data + 46 mode-UI).\n    \"\"\"\n    n_outputs = 50\n    if audio_file is None:\n        return (gr.skip(),) * n_outputs\n\n    lyrics, caption = _extract_metadata_for_editing(lm_metadata, current_lyrics, current_caption)\n    mode_updates = list(compute_mode_ui_updates(\"Remix\", llm_handler, previous_mode=current_mode))\n    mode_updates[19] = gr.update(value=caption, visible=True, interactive=True)\n    mode_updates[20] = gr.update(value=lyrics, visible=True, interactive=True)\n\n    return (audio_file, gr.update(value=\"Remix\"), lyrics, caption, *mode_updates)\n\n\ndef send_audio_to_repaint(audio_file, lm_metadata, current_lyrics, current_caption,\n                          current_mode, llm_handler=None):\n    \"\"\"Send generated audio to ``src_audio`` and switch mode to Repaint.\n\n    Populates lyrics/caption from the generated audio and applies all\n    Repaint-mode UI updates atomically.\n\n    Args:\n        audio_file: Generated audio file path.\n        lm_metadata: LM metadata dict (may be ``None``).\n        current_lyrics: Current lyrics text in the UI.\n        current_caption: Current caption text in the UI.\n        current_mode: Currently active mode string.\n        llm_handler: Optional LLM handler.\n\n    Returns:\n        50-tuple of Gradio updates (4 data + 46 mode-UI).\n    \"\"\"\n    n_outputs = 50\n    if audio_file is None:\n        return (gr.skip(),) * n_outputs\n\n    lyrics, caption = _extract_metadata_for_editing(lm_metadata, current_lyrics, current_caption)\n    mode_updates = list(compute_mode_ui_updates(\"Repaint\", llm_handler, previous_mode=current_mode))\n    mode_updates[19] = gr.update(value=caption, visible=True, interactive=True)\n    mode_updates[20] = gr.update(value=lyrics, visible=True, interactive=True)\n\n    return (audio_file, gr.update(value=\"Repaint\"), lyrics, caption, *mode_updates)\n\n\ndef convert_result_audio_to_codes(dit_handler, generated_audio):\n    \"\"\"Convert a generated audio sample to LM audio codes.\n\n    Args:\n        dit_handler: DiT handler instance.\n        generated_audio: File path to the generated audio.\n\n    Returns:\n        Tuple of ``(codes_display_update, details_accordion_update)``.\n    \"\"\"\n    if not generated_audio:\n        gr.Warning(\"No audio to convert.\")\n        return gr.skip(), gr.skip()\n    if not dit_handler or dit_handler.model is None:\n        gr.Warning(t(\"messages.service_not_initialized\"))\n        return gr.skip(), gr.skip()\n    try:\n        codes_string = dit_handler.convert_src_audio_to_codes(generated_audio)\n        if not codes_string or codes_string.startswith(\"❌\"):\n            gr.Warning(f\"Failed to convert audio to codes: {codes_string}\")\n            return gr.skip(), gr.skip()\n        gr.Info(\"Audio converted to codes successfully.\")\n        return gr.update(value=codes_string), gr.update(open=True)\n    except Exception as e:\n        gr.Warning(f\"Error converting audio to codes: {e}\")\n        return gr.skip(), gr.skip()\n"
  },
  {
    "path": "acestep/ui/gradio/events/results/batch_management.py",
    "content": "\"\"\"Results batch-management facade.\n\nThis thin compatibility module re-exports decomposed batch-management\nfunctions and helper utilities so existing imports continue to work.\n\"\"\"\nfrom acestep.ui.gradio.events.results import batch_management_background as _background\nfrom acestep.ui.gradio.events.results import batch_management_helpers as _helpers\nfrom acestep.ui.gradio.events.results import batch_management_wrapper as _wrapper\n\n\ngenerate_with_batch_management = _wrapper.generate_with_batch_management\ngenerate_next_batch_background = _background.generate_next_batch_background\n\n# Backward-compat helper exports for existing internal import paths.\n_apply_param_defaults = _helpers._apply_param_defaults\n_build_saved_params = _helpers._build_saved_params\n_extract_scores = _helpers._extract_scores\n_extract_ui_core_outputs = _helpers._extract_ui_core_outputs\n_log_background_params = _helpers._log_background_params\n\n\n__all__ = [\n    \"generate_with_batch_management\",\n    \"generate_next_batch_background\",\n]\n"
  },
  {
    "path": "acestep/ui/gradio/events/results/batch_management_background.py",
    "content": "\"\"\"Background AutoGen batch generation orchestration.\"\"\"\n\nimport gc\nimport traceback\n\nimport gradio as gr\nimport torch\nfrom loguru import logger\n\nfrom acestep.ui.gradio.events.results.batch_management_helpers import (\n    _apply_param_defaults,\n    _extract_scores,\n    _log_background_params,\n)\nfrom acestep.ui.gradio.events.results.batch_queue import store_batch_in_queue\nfrom acestep.ui.gradio.events.results.generation_progress import generate_with_progress\nfrom acestep.ui.gradio.i18n import t\n\n\ndef generate_next_batch_background(\n    dit_handler, llm_handler,\n    autogen_enabled, generation_params,\n    current_batch_index, total_batches, batch_queue,\n    is_format_caption,\n    progress=gr.Progress(track_tqdm=True),\n):\n    \"\"\"Generate the next batch in background when AutoGen is enabled.\n\n    Returns:\n        Tuple of ``(batch_queue, total_batches, status_text, next_btn_update)``.\n    \"\"\"\n    if not autogen_enabled:\n        return batch_queue, total_batches, \"\", gr.update(interactive=False)\n\n    next_batch_idx = current_batch_index + 1\n\n    if next_batch_idx in batch_queue and batch_queue[next_batch_idx].get(\"status\") == \"completed\":\n        total_batches = max(total_batches, next_batch_idx + 1)\n        return (\n            batch_queue, total_batches,\n            t(\"messages.batch_ready\", n=next_batch_idx + 1),\n            gr.update(interactive=True),\n        )\n\n    total_batches = next_batch_idx + 1\n    gr.Info(t(\"messages.batch_generating\", n=next_batch_idx + 1))\n\n    params = generation_params.copy()\n    _log_background_params(params, next_batch_idx)\n\n    try:\n        _apply_param_defaults(params)\n\n        gc.collect()\n        if torch.cuda.is_available():\n            torch.cuda.empty_cache()\n        if (hasattr(torch, \"mps\") and hasattr(torch.mps, \"empty_cache\")\n                and hasattr(torch.backends, \"mps\")\n                and torch.backends.mps.is_available()):\n            torch.mps.empty_cache()\n\n        generator = generate_with_progress(\n            dit_handler, llm_handler,\n            captions=params.get(\"captions\"),\n            lyrics=params.get(\"lyrics\"),\n            bpm=params.get(\"bpm\"),\n            key_scale=params.get(\"key_scale\"),\n            time_signature=params.get(\"time_signature\"),\n            vocal_language=params.get(\"vocal_language\"),\n            inference_steps=params.get(\"inference_steps\"),\n            guidance_scale=params.get(\"guidance_scale\"),\n            random_seed_checkbox=params.get(\"random_seed_checkbox\"),\n            seed=params.get(\"seed\"),\n            reference_audio=params.get(\"reference_audio\"),\n            audio_duration=params.get(\"audio_duration\"),\n            batch_size_input=params.get(\"batch_size_input\"),\n            src_audio=params.get(\"src_audio\"),\n            text2music_audio_code_string=params.get(\"text2music_audio_code_string\"),\n            repainting_start=params.get(\"repainting_start\"),\n            repainting_end=params.get(\"repainting_end\"),\n            instruction_display_gen=params.get(\"instruction_display_gen\"),\n            audio_cover_strength=params.get(\"audio_cover_strength\"),\n            cover_noise_strength=params.get(\"cover_noise_strength\", 0.0),\n            task_type=params.get(\"task_type\"),\n            use_adg=params.get(\"use_adg\"),\n            cfg_interval_start=params.get(\"cfg_interval_start\"),\n            cfg_interval_end=params.get(\"cfg_interval_end\"),\n            shift=params.get(\"shift\"),\n            infer_method=params.get(\"infer_method\"),\n            custom_timesteps=params.get(\"custom_timesteps\"),\n            audio_format=params.get(\"audio_format\"),\n            lm_temperature=params.get(\"lm_temperature\"),\n            think_checkbox=params.get(\"think_checkbox\"),\n            lm_cfg_scale=params.get(\"lm_cfg_scale\"),\n            lm_top_k=params.get(\"lm_top_k\"),\n            lm_top_p=params.get(\"lm_top_p\"),\n            lm_negative_prompt=params.get(\"lm_negative_prompt\"),\n            use_cot_metas=params.get(\"use_cot_metas\"),\n            use_cot_caption=params.get(\"use_cot_caption\"),\n            use_cot_language=params.get(\"use_cot_language\"),\n            is_format_caption=is_format_caption,\n            constrained_decoding_debug=params.get(\"constrained_decoding_debug\"),\n            allow_lm_batch=params.get(\"allow_lm_batch\"),\n            auto_score=params.get(\"auto_score\"),\n            auto_lrc=params.get(\"auto_lrc\"),\n            score_scale=params.get(\"score_scale\"),\n            lm_batch_chunk_size=params.get(\"lm_batch_chunk_size\"),\n            enable_normalization=params.get(\"enable_normalization\"),\n            normalization_db=params.get(\"normalization_db\"),\n            fade_in_duration=params.get(\"fade_in_duration\", 0.0),\n            fade_out_duration=params.get(\"fade_out_duration\", 0.0),\n            latent_shift=params.get(\"latent_shift\", 0.0),\n            latent_rescale=params.get(\"latent_rescale\", 1.0),\n            repaint_mode=params.get(\"repaint_mode\", \"balanced\"),\n            repaint_strength=params.get(\"repaint_strength\", 0.5),\n            progress=progress,\n        )\n\n        final_result = None\n        for partial_result in generator:\n            final_result = partial_result\n\n        if final_result is None:\n            raise RuntimeError(\"generate_with_progress yielded no results\")\n\n        all_audio_paths = final_result[8]\n        generation_info = final_result[9]\n        seed_value_for_ui = final_result[11]\n        lm_generated_metadata = final_result[44]\n\n        raw_codes_list = final_result[47] if len(final_result) > 47 else [\"\"] * 8\n        generated_codes_batch = raw_codes_list if isinstance(raw_codes_list, list) else [\"\"] * 8\n        generated_codes_single = generated_codes_batch[0] if generated_codes_batch else \"\"\n        extra_outputs_from_bg = final_result[46] if len(final_result) > 46 and final_result[46] is not None else {}\n        scores_from_bg = _extract_scores(final_result)\n\n        batch_size = params.get(\"batch_size_input\", 2)\n        allow_lm_batch_val = params.get(\"allow_lm_batch\", False)\n        if allow_lm_batch_val and batch_size >= 2:\n            codes_to_store = generated_codes_batch[:int(batch_size)]\n        else:\n            codes_to_store = generated_codes_single\n\n        logger.info(f\"Codes extraction for Batch {next_batch_idx + 1}:\")\n        logger.info(f\"  - extra_outputs_from_bg exists: {extra_outputs_from_bg is not None}\")\n        logger.info(f\"  - scores_from_bg: {[bool(s) for s in scores_from_bg]}\")\n\n        batch_queue = store_batch_in_queue(\n            batch_queue, next_batch_idx,\n            all_audio_paths, generation_info, seed_value_for_ui,\n            codes=codes_to_store,\n            scores=scores_from_bg,\n            allow_lm_batch=allow_lm_batch_val,\n            batch_size=int(batch_size),\n            generation_params=params,\n            lm_generated_metadata=lm_generated_metadata,\n            extra_outputs=extra_outputs_from_bg,\n            status=\"completed\",\n        )\n\n        auto_lrc_flag = params.get(\"auto_lrc\", False)\n        if auto_lrc_flag and extra_outputs_from_bg:\n            batch_queue[next_batch_idx][\"lrcs\"] = extra_outputs_from_bg.get(\"lrcs\", [\"\"] * 8)\n            batch_queue[next_batch_idx][\"subtitles\"] = extra_outputs_from_bg.get(\"subtitles\", [None] * 8)\n\n        logger.info(f\"Batch {next_batch_idx + 1} stored in queue successfully\")\n        return (\n            batch_queue, total_batches,\n            t(\"messages.batch_ready\", n=next_batch_idx + 1),\n            gr.update(interactive=True),\n        )\n\n    except Exception as exc:\n        error_msg = t(\"messages.batch_failed\", error=str(exc))\n        gr.Warning(error_msg)\n        batch_queue[next_batch_idx] = {\n            \"status\": \"error\",\n            \"error\": str(exc),\n            \"traceback\": traceback.format_exc(),\n        }\n        return batch_queue, total_batches, error_msg, gr.update(interactive=False)\n"
  },
  {
    "path": "acestep/ui/gradio/events/results/batch_management_background_test.py",
    "content": "\"\"\"Unit tests for ``generate_next_batch_background`` behavior.\"\"\"\n\nimport unittest\nfrom unittest.mock import patch\n\nfrom _batch_management_test_support import build_progress_result\nfrom _batch_management_test_support import load_batch_management_module\n\n\nclass BatchManagementBackgroundTests(unittest.TestCase):\n    \"\"\"Tests for background AutoGen batch generation flow.\"\"\"\n\n    def test_autogen_disabled_returns_noop_state(self):\n        \"\"\"Disabled AutoGen should not trigger generation or queue mutations.\"\"\"\n        module, _state = load_batch_management_module(is_windows=False)\n\n        result = module.generate_next_batch_background(\n            None,\n            None,\n            autogen_enabled=False,\n            generation_params={},\n            current_batch_index=0,\n            total_batches=1,\n            batch_queue={},\n            is_format_caption=False,\n        )\n\n        self.assertEqual(result[1], 1)\n        self.assertEqual(result[2], \"\")\n        self.assertFalse(result[3][\"interactive\"])\n\n    def test_precompleted_next_batch_returns_ready(self):\n        \"\"\"Already-completed next batch should return ready state immediately.\"\"\"\n        module, _state = load_batch_management_module(is_windows=False)\n        batch_queue = {1: {\"status\": \"completed\"}}\n\n        result = module.generate_next_batch_background(\n            None,\n            None,\n            autogen_enabled=True,\n            generation_params={},\n            current_batch_index=0,\n            total_batches=1,\n            batch_queue=batch_queue,\n            is_format_caption=False,\n        )\n\n        self.assertEqual(result[1], 2)\n        self.assertIn(\"messages.batch_ready\", result[2])\n        self.assertTrue(result[3][\"interactive\"])\n\n    def test_background_generation_success_stores_batch(self):\n        \"\"\"Successful background generation should store next batch and enable next button.\"\"\"\n        module, state = load_batch_management_module(is_windows=False)\n\n        def _gen(*_args, **_kwargs):\n            \"\"\"Yield one synthetic final result for background success path.\"\"\"\n            yield build_progress_result(length=48)\n\n        with patch.dict(module.generate_next_batch_background.__globals__, {\"generate_with_progress\": _gen}):\n            result = module.generate_next_batch_background(\n                None,\n                None,\n                autogen_enabled=True,\n                generation_params={\"batch_size_input\": 2, \"allow_lm_batch\": False, \"auto_lrc\": False},\n                current_batch_index=0,\n                total_batches=1,\n                batch_queue={},\n                is_format_caption=False,\n            )\n\n        self.assertEqual(len(state[\"store_calls\"]), 1)\n        self.assertIn(1, result[0])\n        self.assertIn(\"messages.batch_ready\", result[2])\n        self.assertTrue(result[3][\"interactive\"])\n\n    def test_background_auto_lrc_copies_lrc_fields(self):\n        \"\"\"Background Auto-LRC should copy LRC/subtitle lists into queue entry.\"\"\"\n        module, _state = load_batch_management_module(is_windows=False)\n        lrcs = [f\"lrc-{idx}\" for idx in range(8)]\n        subtitles = [f\"sub-{idx}\" for idx in range(8)]\n\n        def _gen(*_args, **_kwargs):\n            \"\"\"Yield one result carrying LRC and subtitle lists.\"\"\"\n            result = list(build_progress_result(length=48))\n            result[46] = {\"lrcs\": lrcs, \"subtitles\": subtitles}\n            yield tuple(result)\n\n        with patch.dict(module.generate_next_batch_background.__globals__, {\"generate_with_progress\": _gen}):\n            result = module.generate_next_batch_background(\n                None,\n                None,\n                autogen_enabled=True,\n                generation_params={\"batch_size_input\": 2, \"allow_lm_batch\": False, \"auto_lrc\": True},\n                current_batch_index=0,\n                total_batches=1,\n                batch_queue={},\n                is_format_caption=False,\n            )\n\n        self.assertEqual(result[0][1][\"lrcs\"], lrcs)\n        self.assertEqual(result[0][1][\"subtitles\"], subtitles)\n\n    def test_background_generation_exception_sets_error_entry(self):\n        \"\"\"Background exceptions should produce warning and mark batch as error.\"\"\"\n        module, state = load_batch_management_module(is_windows=False)\n\n        def _raising_gen(*_args, **_kwargs):\n            \"\"\"Raise to simulate background generation failure.\"\"\"\n            raise RuntimeError(\"boom\")\n\n        with patch.dict(module.generate_next_batch_background.__globals__, {\"generate_with_progress\": _raising_gen}):\n            result = module.generate_next_batch_background(\n                None,\n                None,\n                autogen_enabled=True,\n                generation_params={},\n                current_batch_index=0,\n                total_batches=1,\n                batch_queue={},\n                is_format_caption=False,\n            )\n\n        self.assertIn(\"messages.batch_failed\", result[2])\n        self.assertFalse(result[3][\"interactive\"])\n        self.assertEqual(result[0][1][\"status\"], \"error\")\n        self.assertTrue(state[\"warning_messages\"])\n\n    def test_background_empty_generator_sets_error_entry(self):\n        \"\"\"Empty inner generator should return error state instead of indexing None.\"\"\"\n        module, state = load_batch_management_module(is_windows=False)\n\n        def _empty_gen(*_args, **_kwargs):\n            \"\"\"Yield nothing to simulate empty background generation output.\"\"\"\n            if False:\n                yield None\n\n        with patch.dict(module.generate_next_batch_background.__globals__, {\"generate_with_progress\": _empty_gen}):\n            result = module.generate_next_batch_background(\n                None,\n                None,\n                autogen_enabled=True,\n                generation_params={},\n                current_batch_index=0,\n                total_batches=1,\n                batch_queue={},\n                is_format_caption=False,\n            )\n\n        self.assertIn(\"messages.batch_failed\", result[2])\n        self.assertFalse(result[3][\"interactive\"])\n        self.assertEqual(result[0][1][\"status\"], \"error\")\n        self.assertTrue(state[\"warning_messages\"])\n\n    # ------------------------------------------------------------------\n    # MPS cache-clearing regression tests (macOS audio-mute fix)\n    # ------------------------------------------------------------------\n\n    def test_mps_cache_cleared_before_generation_on_mac(self):\n        \"\"\"On MPS, empty_cache must be called before generation to release memory.\"\"\"\n        module, state = load_batch_management_module(is_windows=False, mps_available=True)\n\n        def _gen(*_args, **_kwargs):\n            \"\"\"Yield one result for MPS cache-clearing path.\"\"\"\n            yield build_progress_result(length=48)\n\n        with patch.dict(module.generate_next_batch_background.__globals__, {\"generate_with_progress\": _gen}):\n            module.generate_next_batch_background(\n                None,\n                None,\n                autogen_enabled=True,\n                generation_params={\"batch_size_input\": 1, \"allow_lm_batch\": False, \"auto_lrc\": False},\n                current_batch_index=0,\n                total_batches=1,\n                batch_queue={},\n                is_format_caption=False,\n            )\n\n        self.assertGreater(\n            state[\"mps_empty_cache_calls\"],\n            0,\n            \"torch.mps.empty_cache() must be called before generation on macOS to prevent system audio mute\",\n        )\n\n    def test_mps_cache_not_called_when_mps_unavailable(self):\n        \"\"\"MPS cache clear must not be called when MPS is absent (non-Mac hosts).\"\"\"\n        module, state = load_batch_management_module(is_windows=False, mps_available=False)\n\n        def _gen(*_args, **_kwargs):\n            \"\"\"Yield one result for non-MPS path.\"\"\"\n            yield build_progress_result(length=48)\n\n        with patch.dict(module.generate_next_batch_background.__globals__, {\"generate_with_progress\": _gen}):\n            module.generate_next_batch_background(\n                None,\n                None,\n                autogen_enabled=True,\n                generation_params={\"batch_size_input\": 1, \"allow_lm_batch\": False, \"auto_lrc\": False},\n                current_batch_index=0,\n                total_batches=1,\n                batch_queue={},\n                is_format_caption=False,\n            )\n\n        self.assertEqual(\n            state[\"mps_empty_cache_calls\"],\n            0,\n            \"torch.mps.empty_cache() must not be called when MPS is unavailable\",\n        )\n\n\nif __name__ == \"__main__\":\n    unittest.main()\n"
  },
  {
    "path": "acestep/ui/gradio/events/results/batch_management_helpers.py",
    "content": "\"\"\"Helper utilities for batch-management generation flows.\n\nThis module contains pure helper functions used by the batch wrapper and\nbackground generation paths.\n\"\"\"\n\nfrom loguru import logger\n\n\ndef _extract_ui_core_outputs(result_tuple):\n    \"\"\"Return the fixed 46 core UI outputs from a generation result tuple.\n\n    The generate-button wiring expects 46 generation outputs from the wrapper,\n    followed by 9 batch-state outputs. Any trailing fields from\n    ``generate_with_progress`` are intentionally ignored here.\n    \"\"\"\n    return tuple(result_tuple[:46]) if len(result_tuple) >= 46 else tuple(result_tuple)\n\n\ndef _build_saved_params(\n    captions, lyrics, bpm, key_scale, time_signature, vocal_language,\n    inference_steps, guidance_scale, random_seed_checkbox, seed,\n    reference_audio, audio_duration, batch_size_input, src_audio,\n    text2music_audio_code_string, repainting_start, repainting_end,\n    instruction_display_gen, audio_cover_strength, cover_noise_strength, task_type,\n    use_adg, cfg_interval_start, cfg_interval_end, shift, infer_method,\n    audio_format, lm_temperature,\n    think_checkbox, lm_cfg_scale, lm_top_k, lm_top_p, lm_negative_prompt,\n    use_cot_metas, use_cot_caption, use_cot_language,\n    constrained_decoding_debug, allow_lm_batch, auto_score, auto_lrc,\n    score_scale, lm_batch_chunk_size,\n    track_name, complete_track_classes,\n    enable_normalization, normalization_db, fade_in_duration, fade_out_duration,\n    latent_shift, latent_rescale,\n    repaint_mode=\"balanced\", repaint_strength=0.5,\n):\n    \"\"\"Build the parameter snapshot dict stored in batch history.\"\"\"\n    return {\n        \"captions\": captions, \"lyrics\": lyrics, \"bpm\": bpm,\n        \"key_scale\": key_scale, \"time_signature\": time_signature,\n        \"vocal_language\": vocal_language, \"inference_steps\": inference_steps,\n        \"guidance_scale\": guidance_scale,\n        \"random_seed_checkbox\": random_seed_checkbox, \"seed\": seed,\n        \"reference_audio\": reference_audio, \"audio_duration\": audio_duration,\n        \"batch_size_input\": batch_size_input, \"src_audio\": src_audio,\n        \"text2music_audio_code_string\": text2music_audio_code_string,\n        \"repainting_start\": repainting_start, \"repainting_end\": repainting_end,\n        \"instruction_display_gen\": instruction_display_gen,\n        \"audio_cover_strength\": audio_cover_strength,\n        \"cover_noise_strength\": cover_noise_strength,\n        \"task_type\": task_type, \"use_adg\": use_adg,\n        \"cfg_interval_start\": cfg_interval_start,\n        \"cfg_interval_end\": cfg_interval_end,\n        \"shift\": shift, \"infer_method\": infer_method,\n        \"audio_format\": audio_format, \"lm_temperature\": lm_temperature,\n        \"think_checkbox\": think_checkbox, \"lm_cfg_scale\": lm_cfg_scale,\n        \"lm_top_k\": lm_top_k, \"lm_top_p\": lm_top_p,\n        \"lm_negative_prompt\": lm_negative_prompt,\n        \"use_cot_metas\": use_cot_metas, \"use_cot_caption\": use_cot_caption,\n        \"use_cot_language\": use_cot_language,\n        \"constrained_decoding_debug\": constrained_decoding_debug,\n        \"allow_lm_batch\": allow_lm_batch,\n        \"auto_score\": auto_score, \"auto_lrc\": auto_lrc,\n        \"score_scale\": score_scale, \"lm_batch_chunk_size\": lm_batch_chunk_size,\n        \"track_name\": track_name, \"complete_track_classes\": complete_track_classes,\n        \"enable_normalization\": enable_normalization,\n        \"normalization_db\": normalization_db,\n        \"fade_in_duration\": fade_in_duration,\n        \"fade_out_duration\": fade_out_duration,\n        \"latent_shift\": latent_shift, \"latent_rescale\": latent_rescale,\n        \"repaint_mode\": repaint_mode, \"repaint_strength\": repaint_strength,\n    }\n\n\ndef _log_background_params(params, next_batch_idx):\n    \"\"\"Log background-generation parameter values for diagnostics.\"\"\"\n    logger.info(f\"========== BACKGROUND GENERATION BATCH {next_batch_idx + 1} ==========\")\n    logger.info(f\"  - captions: {params.get('captions', 'N/A')}\")\n    lyr = params.get(\"lyrics\")\n    logger.info(f\"  - lyrics: {lyr[:50]}...\" if lyr else \"  - lyrics: N/A\")\n    logger.info(f\"  - bpm: {params.get('bpm')}\")\n    logger.info(f\"  - batch_size_input: {params.get('batch_size_input')}\")\n    logger.info(f\"  - allow_lm_batch: {params.get('allow_lm_batch')}\")\n    logger.info(f\"  - think_checkbox: {params.get('think_checkbox')}\")\n    logger.info(f\"  - lm_temperature: {params.get('lm_temperature')}\")\n    logger.info(f\"  - track_name: {params.get('track_name')}\")\n    codes_val = params.get(\"text2music_audio_code_string\")\n    logger.info(f\"  - text2music_audio_code_string: {'<CLEARED>' if codes_val == '' else 'HAS_VALUE'}\")\n    logger.info(\"=========================================================\")\n\n\ndef _apply_param_defaults(params):\n    \"\"\"Fill missing generation keys in ``params`` with safe defaults.\"\"\"\n    defaults = {\n        \"captions\": \"\", \"lyrics\": \"\", \"bpm\": None, \"key_scale\": \"\",\n        \"time_signature\": \"\", \"vocal_language\": \"unknown\",\n        \"inference_steps\": 8, \"guidance_scale\": 7.0,\n        \"random_seed_checkbox\": True, \"seed\": \"-1\",\n        \"reference_audio\": None, \"audio_duration\": -1,\n        \"batch_size_input\": 2, \"src_audio\": None,\n        \"text2music_audio_code_string\": \"\",\n        \"repainting_start\": 0.0, \"repainting_end\": -1,\n        \"instruction_display_gen\": \"\",\n        \"audio_cover_strength\": 1.0, \"cover_noise_strength\": 0.0,\n        \"task_type\": \"text2music\", \"use_adg\": False,\n        \"cfg_interval_start\": 0.0, \"cfg_interval_end\": 1.0,\n        \"shift\": 1.0, \"infer_method\": \"ode\", \"custom_timesteps\": \"\",\n        \"audio_format\": \"flac\", \"lm_temperature\": 0.85,\n        \"think_checkbox\": True, \"lm_cfg_scale\": 2.0,\n        \"lm_top_k\": 0, \"lm_top_p\": 0.9,\n        \"lm_negative_prompt\": \"NO USER INPUT\",\n        \"use_cot_metas\": True, \"use_cot_caption\": True,\n        \"use_cot_language\": True,\n        \"constrained_decoding_debug\": False,\n        \"allow_lm_batch\": True, \"auto_score\": False,\n        \"auto_lrc\": False, \"score_scale\": 0.5,\n        \"lm_batch_chunk_size\": 8,\n        \"track_name\": None, \"complete_track_classes\": [],\n        \"enable_normalization\": True, \"normalization_db\": -1.0,\n        \"fade_in_duration\": 0.0, \"fade_out_duration\": 0.0,\n        \"latent_shift\": 0.0, \"latent_rescale\": 1.0,\n        \"repaint_mode\": \"balanced\", \"repaint_strength\": 0.5,\n    }\n    for key, value in defaults.items():\n        params.setdefault(key, value)\n\n\ndef _extract_scores(final_result):\n    \"\"\"Extract score strings from generation tuple indices 12-19.\"\"\"\n    scores = []\n    for idx in range(12, 20):\n        if idx < len(final_result):\n            val = final_result[idx]\n            if hasattr(val, \"value\"):\n                scores.append(val.value if val.value else \"\")\n            elif isinstance(val, str):\n                scores.append(val)\n            else:\n                scores.append(\"\")\n        else:\n            scores.append(\"\")\n    return scores\n"
  },
  {
    "path": "acestep/ui/gradio/events/results/batch_management_helpers_test.py",
    "content": "\"\"\"Unit tests for internal helpers in ``batch_management.py``.\"\"\"\n\nimport unittest\n\nfrom _batch_management_test_support import load_batch_management_module\n\n\nclass _ValueWrapper:\n    \"\"\"Simple object exposing a ``value`` attribute for score extraction tests.\"\"\"\n\n    def __init__(self, value):\n        \"\"\"Store wrapped value for ``_extract_scores`` compatibility.\"\"\"\n        self.value = value\n\n\nclass BatchManagementHelperTests(unittest.TestCase):\n    \"\"\"Tests for helper functions used by batch-management flows.\"\"\"\n\n    def test_extract_ui_core_outputs_trims_to_46(self):\n        \"\"\"Helper should return exactly the first 46 entries from long tuples.\"\"\"\n        module, _state = load_batch_management_module(is_windows=False)\n        source = tuple(range(60))\n        result = module._extract_ui_core_outputs(source)\n        self.assertEqual(len(result), 46)\n        self.assertEqual(result[0], 0)\n        self.assertEqual(result[-1], 45)\n\n    def test_extract_ui_core_outputs_keeps_short_tuples(self):\n        \"\"\"Helper should preserve tuples shorter than 46 outputs unchanged.\"\"\"\n        module, _state = load_batch_management_module(is_windows=False)\n        source = tuple(range(12))\n        self.assertEqual(module._extract_ui_core_outputs(source), source)\n\n    def test_build_saved_params_keeps_input_fields(self):\n        \"\"\"Saved params snapshot should preserve core generation settings.\"\"\"\n        module, _state = load_batch_management_module(is_windows=False)\n        params = module._build_saved_params(\n            \"cap\",\n            \"lyr\",\n            120,\n            \"C\",\n            \"4/4\",\n            \"en\",\n            8,\n            7.0,\n            True,\n            \"42\",\n            None,\n            30,\n            2,\n            None,\n            \"\",\n            0.0,\n            10.0,\n            \"\",\n            1.0,\n            0.0,\n            \"text2music\",\n            False,\n            0.0,\n            1.0,\n            1.0,\n            \"ode\",\n            \"flac\",\n            0.85,\n            True,\n            2.0,\n            0,\n            0.9,\n            \"\",\n            True,\n            True,\n            True,\n            False,\n            False,\n            False,\n            False,\n            0.5,\n            8,\n            \"track\",\n            [],\n            True,\n            -1.0,\n            0.0,\n            0.0,\n            0.0,\n            1.0,\n        )\n        self.assertEqual(params[\"captions\"], \"cap\")\n        self.assertEqual(params[\"lyrics\"], \"lyr\")\n        self.assertEqual(params[\"track_name\"], \"track\")\n        self.assertIn(\"latent_rescale\", params)\n        self.assertIn(\"fade_in_duration\", params)\n        self.assertIn(\"fade_out_duration\", params)\n\n    def test_apply_param_defaults_adds_missing_without_overwrite(self):\n        \"\"\"Defaults helper should add absent keys and preserve existing values.\"\"\"\n        module, _state = load_batch_management_module(is_windows=False)\n        params = {\"captions\": \"keep\", \"lm_top_k\": 7}\n        module._apply_param_defaults(params)\n        self.assertEqual(params[\"captions\"], \"keep\")\n        self.assertEqual(params[\"lm_top_k\"], 7)\n        self.assertEqual(params[\"audio_format\"], \"flac\")\n        self.assertIn(\"latent_shift\", params)\n        self.assertIn(\"fade_in_duration\", params)\n        self.assertIn(\"fade_out_duration\", params)\n        self.assertEqual(params[\"fade_in_duration\"], 0.0)\n        self.assertEqual(params[\"fade_out_duration\"], 0.0)\n\n    def test_extract_scores_handles_wrapped_values_and_missing_indices(self):\n        \"\"\"Score extraction should normalize mixed score payload shapes.\"\"\"\n        module, _state = load_batch_management_module(is_windows=False)\n        final_result = [None] * 16\n        final_result[12] = _ValueWrapper(\"9.1\")\n        final_result[13] = \"8.2\"\n        final_result[14] = object()\n        scores = module._extract_scores(final_result)\n        self.assertEqual(len(scores), 8)\n        self.assertEqual(scores[0], \"9.1\")\n        self.assertEqual(scores[1], \"8.2\")\n        self.assertEqual(scores[2], \"\")\n        self.assertEqual(scores[-1], \"\")\n\n    def test_log_background_params_records_messages(self):\n        \"\"\"Logging helper should emit expected entries without raising.\"\"\"\n        module, state = load_batch_management_module(is_windows=False)\n        module._log_background_params(\n            {\"captions\": \"cap\", \"lyrics\": \"lyr\", \"track_name\": \"trk\", \"text2music_audio_code_string\": \"\"},\n            1,\n        )\n        self.assertTrue(state[\"log_info\"])\n        self.assertTrue(any(\"BACKGROUND GENERATION BATCH\" in line for line in state[\"log_info\"]))\n\n\nif __name__ == \"__main__\":\n    unittest.main()\n"
  },
  {
    "path": "acestep/ui/gradio/events/results/batch_management_test.py",
    "content": "\"\"\"Unit tests for ``generate_with_batch_management`` wrapper behavior.\"\"\"\n\nimport inspect\nimport unittest\nfrom unittest.mock import patch\n\nfrom _batch_management_test_support import build_progress_result\nfrom _batch_management_test_support import load_batch_management_module\n\n\ndef _build_call_kwargs(module):\n    \"\"\"Build complete kwargs for ``generate_with_batch_management``.\"\"\"\n    kwargs = {}\n    for name in list(inspect.signature(module.generate_with_batch_management).parameters)[2:]:\n        if name == \"progress\":\n            continue\n        if name == \"batch_size_input\":\n            kwargs[name] = 2\n        elif name in (\"allow_lm_batch\", \"auto_lrc\", \"autogen_checkbox\", \"auto_score\"):\n            kwargs[name] = False\n        elif name == \"current_batch_index\":\n            kwargs[name] = 0\n        elif name == \"total_batches\":\n            kwargs[name] = 0\n        elif name in (\"batch_queue\", \"generation_params_state\"):\n            kwargs[name] = {}\n        elif name == \"complete_track_classes\":\n            kwargs[name] = []\n        else:\n            kwargs[name] = None\n    return kwargs\n\n\nclass BatchManagementWrapperTests(unittest.TestCase):\n    \"\"\"Tests for streaming and final wrapper output mapping.\"\"\"\n\n    def test_non_windows_streams_partial_and_final_outputs(self):\n        \"\"\"Non-Windows path should emit partial UI updates plus final state.\"\"\"\n        module, state = load_batch_management_module(is_windows=False)\n\n        def _gen(*_args, **_kwargs):\n            \"\"\"Yield one standard progress result for wrapper streaming.\"\"\"\n            yield build_progress_result(length=48)\n\n        kwargs = _build_call_kwargs(module)\n        with patch.dict(module.generate_with_batch_management.__globals__, {\"generate_with_progress\": _gen}):\n            outputs = list(module.generate_with_batch_management(None, None, **kwargs))\n\n        self.assertEqual(len(outputs), 2)\n        self.assertEqual(len(outputs[0]), 55)\n        self.assertEqual(len(outputs[1]), 55)\n        self.assertEqual(outputs[0][0][\"playback_position\"], 0)\n        self.assertEqual(outputs[1][0][\"playback_position\"], 0)\n        self.assertEqual(len(state[\"store_calls\"]), 1)\n\n    def test_windows_emits_only_final_output(self):\n        \"\"\"Windows path should skip intermediate yields and emit final state only.\"\"\"\n        module, _state = load_batch_management_module(is_windows=True)\n\n        def _gen(*_args, **_kwargs):\n            \"\"\"Yield one standard progress result for Windows final-output path.\"\"\"\n            yield build_progress_result(length=48)\n\n        kwargs = _build_call_kwargs(module)\n        with patch.dict(module.generate_with_batch_management.__globals__, {\"generate_with_progress\": _gen}):\n            outputs = list(module.generate_with_batch_management(None, None, **kwargs))\n\n        self.assertEqual(len(outputs), 1)\n        self.assertEqual(len(outputs[0]), 55)\n        self.assertEqual(outputs[0][0][\"playback_position\"], 0)\n\n    def test_all_audio_paths_none_skips_batch_storage(self):\n        \"\"\"When inner result has no audio paths, wrapper should not store a batch.\"\"\"\n        module, state = load_batch_management_module(is_windows=False)\n\n        def _gen(*_args, **_kwargs):\n            \"\"\"Yield a result with no audio paths to trigger early return.\"\"\"\n            yield build_progress_result(length=48, all_audio_paths=None)\n\n        kwargs = _build_call_kwargs(module)\n        with patch.dict(module.generate_with_batch_management.__globals__, {\"generate_with_progress\": _gen}):\n            outputs = list(module.generate_with_batch_management(None, None, **kwargs))\n\n        self.assertEqual(len(outputs), 2)\n        self.assertEqual(outputs[1][8], None)\n        self.assertEqual(len(state[\"store_calls\"]), 0)\n\n    def test_allow_lm_batch_stores_multiple_codes(self):\n        \"\"\"Batch mode should store a list of generated codes up to batch size.\"\"\"\n        module, state = load_batch_management_module(is_windows=False)\n\n        def _gen(*_args, **_kwargs):\n            \"\"\"Yield a result carrying a list of generated codes.\"\"\"\n            result = list(build_progress_result(length=48))\n            result[47] = [f\"code-{idx}\" for idx in range(8)]\n            yield tuple(result)\n\n        kwargs = _build_call_kwargs(module)\n        kwargs[\"allow_lm_batch\"] = True\n        kwargs[\"batch_size_input\"] = 3\n        with patch.dict(module.generate_with_batch_management.__globals__, {\"generate_with_progress\": _gen}):\n            list(module.generate_with_batch_management(None, None, **kwargs))\n\n        self.assertEqual(state[\"store_calls\"][0][\"codes\"], [\"code-0\", \"code-1\", \"code-2\"])\n\n    def test_auto_lrc_copies_lrc_fields_to_batch_queue(self):\n        \"\"\"Auto-LRC mode should copy LRC/subtitle payloads into stored queue entry.\"\"\"\n        module, _state = load_batch_management_module(is_windows=False)\n\n        lrcs = [f\"lrc-{idx}\" for idx in range(8)]\n        subtitles = [f\"sub-{idx}\" for idx in range(8)]\n\n        def _gen(*_args, **_kwargs):\n            \"\"\"Yield a result with explicit LRC/subtitle payload.\"\"\"\n            result = list(build_progress_result(length=48))\n            result[46] = {\"lrcs\": lrcs, \"subtitles\": subtitles}\n            yield tuple(result)\n\n        kwargs = _build_call_kwargs(module)\n        kwargs[\"auto_lrc\"] = True\n        outputs = []\n        with patch.dict(module.generate_with_batch_management.__globals__, {\"generate_with_progress\": _gen}):\n            outputs = list(module.generate_with_batch_management(None, None, **kwargs))\n\n        final_batch_queue = outputs[-1][48]\n        self.assertEqual(final_batch_queue[0][\"lrcs\"], lrcs)\n        self.assertEqual(final_batch_queue[0][\"subtitles\"], subtitles)\n\n    def test_auto_lrc_sets_lrc_display_in_final_yield(self):\n        \"\"\"Final yield should carry gr.update(value=lrc) at positions 36-43.\"\"\"\n        module, _state = load_batch_management_module(is_windows=False)\n\n        lrcs = [f\"[00:01.00]Line {idx}\" for idx in range(8)]\n        subtitles = [f\"sub-{idx}\" for idx in range(8)]\n\n        def _gen(*_args, **_kwargs):\n            \"\"\"Yield a result with LRC data in extra_outputs.\"\"\"\n            result = list(build_progress_result(length=48))\n            result[46] = {\"lrcs\": lrcs, \"subtitles\": subtitles}\n            yield tuple(result)\n\n        kwargs = _build_call_kwargs(module)\n        kwargs[\"auto_lrc\"] = True\n        with patch.dict(module.generate_with_batch_management.__globals__, {\"generate_with_progress\": _gen}):\n            outputs = list(module.generate_with_batch_management(None, None, **kwargs))\n\n        final_yield = outputs[-1]\n        for i in range(8):\n            lrc_val = final_yield[36 + i]\n            self.assertIsInstance(lrc_val, dict, f\"LRC position {36 + i} should be a gr.update dict\")\n            self.assertEqual(\n                lrc_val.get(\"value\"), lrcs[i],\n                f\"LRC position {36 + i} should contain the LRC text\",\n            )\n\n    def test_auto_lrc_disabled_preserves_passthrough_values(self):\n        \"\"\"When auto_lrc is off, LRC positions pass through from inner generator.\"\"\"\n        module, _state = load_batch_management_module(is_windows=False)\n\n        def _gen(*_args, **_kwargs):\n            \"\"\"Yield a standard result without auto_lrc.\"\"\"\n            yield build_progress_result(length=48)\n\n        kwargs = _build_call_kwargs(module)\n        kwargs[\"auto_lrc\"] = False\n        with patch.dict(module.generate_with_batch_management.__globals__, {\"generate_with_progress\": _gen}):\n            outputs = list(module.generate_with_batch_management(None, None, **kwargs))\n\n        final_yield = outputs[-1]\n        for i in range(8):\n            lrc_val = final_yield[36 + i]\n            self.assertIsNone(lrc_val, f\"LRC position {36 + i} should be None when auto_lrc is off\")\n\n    def test_empty_inner_generator_returns_skip_tuple_and_warning(self):\n        \"\"\"Empty inner generator should fail gracefully without indexing None.\"\"\"\n        module, state = load_batch_management_module(is_windows=False)\n\n        def _gen(*_args, **_kwargs):\n            \"\"\"Yield nothing to simulate a defensive empty-generator edge case.\"\"\"\n            if False:\n                yield None\n\n        kwargs = _build_call_kwargs(module)\n        with patch.dict(module.generate_with_batch_management.__globals__, {\"generate_with_progress\": _gen}):\n            outputs = list(module.generate_with_batch_management(None, None, **kwargs))\n\n        self.assertEqual(len(outputs), 1)\n        self.assertEqual(len(outputs[0]), 55)\n        self.assertTrue(all(item.get(\"kind\") == \"skip\" for item in outputs[0]))\n        self.assertEqual(len(state[\"store_calls\"]), 0)\n        self.assertTrue(state[\"warning_messages\"])\n        self.assertIn(\"messages.batch_failed\", state[\"warning_messages\"][0])\n\n    # ------------------------------------------------------------------\n    # Score persistence regression tests (foreground batch fix)\n    # ------------------------------------------------------------------\n\n    def test_foreground_scores_passed_to_store_batch_in_queue(self):\n        \"\"\"Foreground generation must extract and pass scores to batch storage.\"\"\"\n        module, state = load_batch_management_module(is_windows=False)\n\n        def _gen(*_args, **_kwargs):\n            \"\"\"Yield a result with score values at indices 12-19.\"\"\"\n            result = list(build_progress_result(length=48))\n            for i in range(8):\n                result[12 + i] = f\"8.{i}\"\n            yield tuple(result)\n\n        kwargs = _build_call_kwargs(module)\n        with patch.dict(module.generate_with_batch_management.__globals__, {\"generate_with_progress\": _gen}):\n            list(module.generate_with_batch_management(None, None, **kwargs))\n\n        self.assertEqual(len(state[\"store_calls\"]), 1)\n        scores = state[\"store_calls\"][0][\"scores\"]\n        self.assertEqual(len(scores), 8)\n        self.assertEqual(scores[0], \"8.0\")\n        self.assertEqual(scores[7], \"8.7\")\n\n    def test_foreground_scores_default_empty_when_absent(self):\n        \"\"\"When result tuple lacks score indices, scores should be empty strings.\"\"\"\n        module, state = load_batch_management_module(is_windows=False)\n\n        def _gen(*_args, **_kwargs):\n            \"\"\"Yield a short result with no score data.\"\"\"\n            yield build_progress_result(length=48)\n\n        kwargs = _build_call_kwargs(module)\n        with patch.dict(module.generate_with_batch_management.__globals__, {\"generate_with_progress\": _gen}):\n            list(module.generate_with_batch_management(None, None, **kwargs))\n\n        self.assertEqual(len(state[\"store_calls\"]), 1)\n        scores = state[\"store_calls\"][0][\"scores\"]\n        self.assertEqual(len(scores), 8)\n        self.assertTrue(all(s == \"\" for s in scores), \"Absent scores should default to empty strings\")\n\n    # ------------------------------------------------------------------\n    # MPS cache-clearing regression tests (macOS audio-mute fix)\n    # ------------------------------------------------------------------\n\n    def test_mps_cache_cleared_before_and_after_generation_on_mac(self):\n        \"\"\"On MPS, empty_cache must be called both before and after generation.\"\"\"\n        module, state = load_batch_management_module(is_windows=False, mps_available=True)\n\n        def _gen(*_args, **_kwargs):\n            \"\"\"Yield one result for MPS cache-clearing path.\"\"\"\n            yield build_progress_result(length=48)\n\n        kwargs = _build_call_kwargs(module)\n        with patch.dict(module.generate_with_batch_management.__globals__, {\"generate_with_progress\": _gen}):\n            list(module.generate_with_batch_management(None, None, **kwargs))\n\n        self.assertGreaterEqual(\n            state[\"mps_empty_cache_calls\"],\n            2,\n            \"torch.mps.empty_cache() must be called before and after generation \"\n            \"on macOS to prevent system audio mute\",\n        )\n\n    def test_mps_cache_not_called_when_mps_unavailable(self):\n        \"\"\"MPS cache clear must not be called when MPS is absent (non-Mac hosts).\"\"\"\n        module, state = load_batch_management_module(is_windows=False, mps_available=False)\n\n        def _gen(*_args, **_kwargs):\n            \"\"\"Yield one result for non-MPS path.\"\"\"\n            yield build_progress_result(length=48)\n\n        kwargs = _build_call_kwargs(module)\n        with patch.dict(module.generate_with_batch_management.__globals__, {\"generate_with_progress\": _gen}):\n            list(module.generate_with_batch_management(None, None, **kwargs))\n\n        self.assertEqual(\n            state[\"mps_empty_cache_calls\"],\n            0,\n            \"torch.mps.empty_cache() must not be called when MPS is unavailable\",\n        )\n\n\nif __name__ == \"__main__\":\n    unittest.main()\n"
  },
  {
    "path": "acestep/ui/gradio/events/results/batch_management_wrapper.py",
    "content": "\"\"\"Foreground batch generation wrapper for UI streaming updates.\"\"\"\n\nimport gc\nimport time as time_module\n\nimport gradio as gr\nimport torch\nfrom loguru import logger\n\nfrom acestep.ui.gradio.events.results.batch_management_helpers import (\n    _build_saved_params,\n    _extract_scores,\n    _extract_ui_core_outputs,\n)\nfrom acestep.ui.gradio.events.results.batch_queue import (\n    store_batch_in_queue,\n    update_batch_indicator,\n    update_navigation_buttons,\n)\nfrom acestep.ui.gradio.events.results.generation_info import IS_WINDOWS\nfrom acestep.ui.gradio.events.results.generation_progress import generate_with_progress\nfrom acestep.ui.gradio.i18n import t\n\n\ndef generate_with_batch_management(\n    dit_handler, llm_handler,\n    captions, lyrics, bpm, key_scale, time_signature, vocal_language,\n    inference_steps, guidance_scale, random_seed_checkbox, seed,\n    reference_audio, audio_duration, batch_size_input, src_audio,\n    text2music_audio_code_string, repainting_start, repainting_end,\n    instruction_display_gen, audio_cover_strength, cover_noise_strength, task_type,\n    use_adg, cfg_interval_start, cfg_interval_end, shift, infer_method,\n    custom_timesteps, audio_format, lm_temperature,\n    think_checkbox, lm_cfg_scale, lm_top_k, lm_top_p, lm_negative_prompt,\n    use_cot_metas, use_cot_caption, use_cot_language, is_format_caption,\n    constrained_decoding_debug,\n    allow_lm_batch,\n    auto_score,\n    auto_lrc,\n    score_scale,\n    lm_batch_chunk_size,\n    track_name,\n    complete_track_classes,\n    enable_normalization,\n    normalization_db,\n    fade_in_duration,\n    fade_out_duration,\n    latent_shift,\n    latent_rescale,\n    repaint_mode,\n    repaint_strength,\n    autogen_checkbox,\n    current_batch_index,\n    total_batches,\n    batch_queue,\n    generation_params_state,\n    progress=gr.Progress(track_tqdm=True),\n):\n    \"\"\"Wrap ``generate_with_progress`` with batch queue management state.\"\"\"\n    _ = generation_params_state  # reserved for API compatibility with wiring/state outputs\n    gc.collect()\n    if torch.cuda.is_available():\n        torch.cuda.empty_cache()\n    if (hasattr(torch, \"mps\") and hasattr(torch.mps, \"empty_cache\")\n            and hasattr(torch.backends, \"mps\") and torch.backends.mps.is_available()):\n        torch.mps.empty_cache()\n    generator = generate_with_progress(\n        dit_handler, llm_handler,\n        captions, lyrics, bpm, key_scale, time_signature, vocal_language,\n        inference_steps, guidance_scale, random_seed_checkbox, seed,\n        reference_audio, audio_duration, batch_size_input, src_audio,\n        text2music_audio_code_string, repainting_start, repainting_end,\n        instruction_display_gen, audio_cover_strength, cover_noise_strength, task_type,\n        use_adg, cfg_interval_start, cfg_interval_end, shift, infer_method,\n        custom_timesteps, audio_format, lm_temperature,\n        think_checkbox, lm_cfg_scale, lm_top_k, lm_top_p, lm_negative_prompt,\n        use_cot_metas, use_cot_caption, use_cot_language, is_format_caption,\n        constrained_decoding_debug,\n        allow_lm_batch, auto_score, auto_lrc, score_scale,\n        lm_batch_chunk_size,\n        enable_normalization, normalization_db, fade_in_duration, fade_out_duration,\n        latent_shift, latent_rescale,\n        repaint_mode, repaint_strength,\n        progress,\n    )\n\n    final_result_from_inner = None\n    for partial_result in generator:\n        final_result_from_inner = partial_result\n        if not IS_WINDOWS:\n            ui_result = _extract_ui_core_outputs(partial_result)\n            yield ui_result + (\n                gr.skip(), gr.skip(), gr.skip(), gr.skip(),\n                gr.skip(), gr.skip(), gr.skip(), gr.skip(), gr.skip(),\n            )\n\n    # Release the generator frame and run GC to reclaim any accelerator memory\n    # that was not yet freed at the end of the inner generator.\n    del generator\n    gc.collect()\n    if torch.cuda.is_available():\n        torch.cuda.empty_cache()\n    if (hasattr(torch, \"mps\") and hasattr(torch.mps, \"empty_cache\")\n            and hasattr(torch.backends, \"mps\") and torch.backends.mps.is_available()):\n        torch.mps.empty_cache()\n\n    result = final_result_from_inner\n    if result is None:\n        error_msg = t(\"messages.batch_failed\", error=\"No generation result was produced\")\n        logger.warning(\"[generate_with_batch_management] generate_with_progress yielded no results\")\n        gr.Warning(error_msg)\n        yield (gr.skip(),) * 55\n        return\n\n    all_audio_paths = result[8]\n\n    if all_audio_paths is None:\n        ui_result = _extract_ui_core_outputs(result)\n        yield ui_result + (\n            gr.skip(), gr.skip(), gr.skip(), gr.skip(),\n            gr.skip(), gr.skip(), gr.skip(), gr.skip(), gr.skip(),\n        )\n        return\n\n    generation_info = result[9]\n    seed_value_for_ui = result[11]\n    lm_generated_metadata = result[44]\n\n    raw_codes_list = result[47] if len(result) > 47 else [\"\"] * 8\n    generated_codes_batch = raw_codes_list if isinstance(raw_codes_list, list) else [\"\"] * 8\n    generated_codes_single = generated_codes_batch[0] if generated_codes_batch else \"\"\n\n    if allow_lm_batch and batch_size_input >= 2:\n        codes_to_store = generated_codes_batch[:int(batch_size_input)]\n    else:\n        codes_to_store = generated_codes_single\n\n    saved_params = _build_saved_params(\n        captions, lyrics, bpm, key_scale, time_signature, vocal_language,\n        inference_steps, guidance_scale, random_seed_checkbox, seed,\n        reference_audio, audio_duration, batch_size_input, src_audio,\n        text2music_audio_code_string, repainting_start, repainting_end,\n        instruction_display_gen, audio_cover_strength, cover_noise_strength, task_type,\n        use_adg, cfg_interval_start, cfg_interval_end, shift, infer_method,\n        audio_format, lm_temperature,\n        think_checkbox, lm_cfg_scale, lm_top_k, lm_top_p, lm_negative_prompt,\n        use_cot_metas, use_cot_caption, use_cot_language,\n        constrained_decoding_debug, allow_lm_batch, auto_score, auto_lrc,\n        score_scale, lm_batch_chunk_size,\n        track_name, complete_track_classes,\n        enable_normalization, normalization_db, fade_in_duration, fade_out_duration,\n        latent_shift, latent_rescale,\n        repaint_mode=repaint_mode, repaint_strength=repaint_strength,\n    )\n\n    next_params = saved_params.copy()\n    next_params[\"text2music_audio_code_string\"] = \"\"\n    next_params[\"random_seed_checkbox\"] = True\n\n    extra_outputs_from_result = result[46] if len(result) > 46 and result[46] is not None else {}\n\n    scores_from_fg = _extract_scores(result)\n\n    batch_queue = store_batch_in_queue(\n        batch_queue, current_batch_index,\n        all_audio_paths, generation_info, seed_value_for_ui,\n        scores=scores_from_fg,\n        codes=codes_to_store,\n        allow_lm_batch=allow_lm_batch,\n        batch_size=int(batch_size_input),\n        generation_params=saved_params,\n        lm_generated_metadata=lm_generated_metadata,\n        extra_outputs=extra_outputs_from_result,\n        status=\"completed\",\n    )\n\n    if auto_lrc and extra_outputs_from_result:\n        batch_queue[current_batch_index][\"lrcs\"] = extra_outputs_from_result.get(\"lrcs\", [\"\"] * 8)\n        batch_queue[current_batch_index][\"subtitles\"] = extra_outputs_from_result.get(\"subtitles\", [None] * 8)\n\n    total_batches = max(total_batches, current_batch_index + 1)\n    batch_indicator_text = update_batch_indicator(current_batch_index, total_batches)\n    can_prev, can_next = update_navigation_buttons(current_batch_index, total_batches)\n    next_batch_status_text = t(\"messages.autogen_enabled\") if autogen_checkbox else \"\"\n\n    ui_core_list = list(_extract_ui_core_outputs(result))\n\n    if auto_lrc and isinstance(extra_outputs_from_result, dict):\n        lrcs = extra_outputs_from_result.get(\"lrcs\", [\"\"] * 8)\n        for i in range(min(8, len(lrcs))):\n            if lrcs[i]:\n                ui_core_list[36 + i] = gr.update(value=lrcs[i], visible=True)\n\n    logger.info(f\"[generate_with_batch_management] Final yield: {len(ui_core_list)} core + 9 state\")\n\n    yield tuple(ui_core_list) + (\n        current_batch_index, total_batches, batch_queue, next_params,\n        batch_indicator_text,\n        gr.update(interactive=can_prev),\n        gr.update(interactive=can_next),\n        next_batch_status_text,\n        gr.update(interactive=True),\n    )\n    time_module.sleep(0.1)\n"
  },
  {
    "path": "acestep/ui/gradio/events/results/batch_navigation.py",
    "content": "\"\"\"Batch navigation: previous / next batch with two-step subtitle yields.\n\nEach navigation function uses a two-step yield pattern to avoid\nsubtitle flickering:\n\n1. First yield — audio + clear LRC (triggers ``.change()`` to clear subtitles).\n2. Sleep 50 ms (let audio load).\n3. Second yield — skip audio + set actual LRC (triggers ``.change()`` to set subtitles).\n\"\"\"\nimport time as time_module\n\nimport gradio as gr\n\nfrom acestep.ui.gradio.i18n import t\nfrom acestep.ui.gradio.events.results.audio_playback_updates import (\n    build_audio_slot_update,\n)\nfrom acestep.ui.gradio.events.results.batch_queue import (\n    update_batch_indicator,\n    update_navigation_buttons,\n)\n\n\ndef navigate_to_previous_batch(current_batch_index, batch_queue):\n    \"\"\"Navigate to the previous batch (result view only).\n\n    Yields:\n        Two tuples of 48 Gradio component updates each.\n    \"\"\"\n    if current_batch_index <= 0:\n        gr.Warning(t(\"messages.at_first_batch\"))\n        yield tuple([gr.update()] * 48)\n        return\n\n    new_idx = current_batch_index - 1\n    if new_idx not in batch_queue:\n        gr.Warning(t(\"messages.batch_not_found\", n=new_idx + 1))\n        yield tuple([gr.update()] * 48)\n        return\n\n    batch_data = batch_queue[new_idx]\n    audio_paths = batch_data.get(\"audio_paths\", [])\n    generation_info_text = batch_data.get(\"generation_info\", \"\")\n\n    real_audio_paths = [p for p in audio_paths if not p.lower().endswith('.json')]\n    audio_updates = [\n        build_audio_slot_update(gr, real_audio_paths[i].replace(\"\\\\\", \"/\"))\n        if i < len(real_audio_paths)\n        else build_audio_slot_update(gr, None)\n        for i in range(8)\n    ]\n\n    total_batches = len(batch_queue)\n    batch_indicator_text = update_batch_indicator(new_idx, total_batches)\n    can_prev, can_next = update_navigation_buttons(new_idx, total_batches)\n\n    stored_scores = batch_data.get(\"scores\", [\"\"] * 8) or [\"\"] * 8\n    stored_lrcs = batch_data.get(\"lrcs\", [\"\"] * 8) or [\"\"] * 8\n\n    codes_updates, lrc_updates, lrc_clears, accordion_updates = _build_detail_updates(\n        batch_data, stored_lrcs,\n    )\n\n    # STEP 1: audio + clear LRC\n    yield (\n        *audio_updates,\n        audio_paths, generation_info_text, new_idx, batch_indicator_text,\n        gr.update(interactive=can_prev), gr.update(interactive=can_next),\n        t(\"messages.viewing_batch\", n=new_idx + 1),\n        *stored_scores, *codes_updates, *lrc_clears, *accordion_updates,\n        gr.update(interactive=True),\n    )\n\n    time_module.sleep(0.05)\n\n    # STEP 2: skip audio + set actual LRC\n    skip8 = [gr.skip()] * 8\n    yield (\n        *skip8,\n        gr.skip(), gr.skip(), gr.skip(), gr.skip(),\n        gr.skip(), gr.skip(), gr.skip(),\n        *skip8, *skip8, *lrc_updates, *skip8,\n        gr.skip(),\n    )\n\n\ndef navigate_to_next_batch(autogen_enabled, current_batch_index, total_batches, batch_queue):\n    \"\"\"Navigate to the next batch (result view only).\n\n    Yields:\n        Two tuples of 49 Gradio component updates each.\n    \"\"\"\n    # Derive actual total from batch_queue so we never rely on a stale\n    # total_batches state value (the background generator may have added\n    # batches after total_batches was last written to the Gradio state).\n    total_batches = max(total_batches, len(batch_queue))\n\n    if current_batch_index >= total_batches - 1:\n        gr.Warning(t(\"messages.at_last_batch\"))\n        yield tuple([gr.update()] * 49)\n        return\n\n    new_idx = current_batch_index + 1\n    if new_idx not in batch_queue:\n        gr.Warning(t(\"messages.batch_not_found\", n=new_idx + 1))\n        yield tuple([gr.update()] * 49)\n        return\n\n    batch_data = batch_queue[new_idx]\n    audio_paths = batch_data.get(\"audio_paths\", [])\n    generation_info_text = batch_data.get(\"generation_info\", \"\")\n\n    real_audio_paths = [p for p in audio_paths if not p.lower().endswith('.json')]\n    audio_updates = [\n        build_audio_slot_update(gr, real_audio_paths[i].replace(\"\\\\\", \"/\"))\n        if i < len(real_audio_paths)\n        else build_audio_slot_update(gr, None)\n        for i in range(8)\n    ]\n\n    batch_indicator_text = update_batch_indicator(new_idx, total_batches)\n    can_prev, can_next = update_navigation_buttons(new_idx, total_batches)\n\n    next_batch_status_text = \"\"\n    if autogen_enabled and new_idx == total_batches - 1:\n        next_batch_status_text = \"🔄 AutoGen will generate next batch in background...\"\n\n    stored_scores = batch_data.get(\"scores\", [\"\"] * 8) or [\"\"] * 8\n    stored_lrcs = batch_data.get(\"lrcs\", [\"\"] * 8) or [\"\"] * 8\n\n    codes_updates, lrc_updates, lrc_clears, accordion_updates = _build_detail_updates(\n        batch_data, stored_lrcs,\n    )\n\n    # STEP 1: audio + clear LRC\n    yield (\n        *audio_updates,\n        audio_paths, generation_info_text, new_idx, batch_indicator_text,\n        gr.update(interactive=can_prev), gr.update(interactive=can_next),\n        t(\"messages.viewing_batch\", n=new_idx + 1), next_batch_status_text,\n        *stored_scores, *codes_updates, *lrc_clears, *accordion_updates,\n        gr.update(interactive=True),\n    )\n\n    time_module.sleep(0.05)\n\n    # STEP 2: skip audio + set actual LRC\n    skip8 = [gr.skip()] * 8\n    yield (\n        *skip8,\n        gr.skip(), gr.skip(), gr.skip(), gr.skip(),\n        gr.skip(), gr.skip(),\n        gr.skip(), gr.skip(),\n        *skip8, *skip8, *lrc_updates, *skip8,\n        gr.skip(),\n    )\n\n\n# ---------------------------------------------------------------------------\n# Internal helper\n# ---------------------------------------------------------------------------\n\ndef _build_detail_updates(batch_data, lrc_displays):\n    \"\"\"Build codes / LRC / accordion Gradio updates for a batch.\n\n    Returns:\n        Tuple of four 8-element lists:\n        ``(codes_updates, lrc_updates, lrc_clears, accordion_updates)``.\n    \"\"\"\n    stored_codes = batch_data.get(\"codes\", \"\")\n    stored_allow_lm_batch = batch_data.get(\"allow_lm_batch\", False)\n\n    codes_updates = []\n    lrc_updates = []\n    lrc_clears = []\n    accordion_updates = []\n\n    for i in range(8):\n        if stored_allow_lm_batch and isinstance(stored_codes, list):\n            code_str = stored_codes[i] if i < len(stored_codes) else \"\"\n        else:\n            code_str = stored_codes if isinstance(stored_codes, str) and i == 0 else \"\"\n\n        lrc_str = lrc_displays[i] if i < len(lrc_displays) else \"\"\n\n        codes_updates.append(gr.update(value=code_str, visible=True))\n        lrc_updates.append(gr.update(value=lrc_str, visible=True))\n        lrc_clears.append(gr.update(value=\"\", visible=True))\n        accordion_updates.append(gr.skip())\n\n    return codes_updates, lrc_updates, lrc_clears, accordion_updates\n"
  },
  {
    "path": "acestep/ui/gradio/events/results/batch_navigation_test.py",
    "content": "\"\"\"Unit tests for batch_navigation module.\n\nFocuses on the navigate_to_next_batch guard logic that previously\nrelied on a potentially stale ``total_batches`` Gradio state value.\n\"\"\"\n\nimport unittest\nfrom unittest.mock import patch, MagicMock\n\n\ndef _make_batch(audio_path=\"/tmp/audio.flac\"):\n    \"\"\"Return a minimal completed batch dict for testing.\"\"\"\n    return {\n        \"status\": \"completed\",\n        \"audio_paths\": [audio_path],\n        \"generation_info\": \"test info\",\n        \"seeds\": \"42\",\n        \"codes\": \"\",\n        \"scores\": [\"\"] * 8,\n        \"allow_lm_batch\": False,\n        \"batch_size\": 2,\n        \"generation_params\": {},\n        \"lm_generated_metadata\": None,\n        \"extra_outputs\": {},\n    }\n\n\n# Patch Gradio helpers that are unavailable in a headless test environment.\n@patch(\"acestep.ui.gradio.events.results.batch_navigation.gr\")\n@patch(\"acestep.ui.gradio.events.results.batch_navigation.t\", side_effect=lambda key, **kw: key)\nclass NavigateToNextBatchTests(unittest.TestCase):\n    \"\"\"Tests for navigate_to_next_batch.\"\"\"\n\n    def _run_first_yield(self, gen):\n        \"\"\"Advance the generator to its first yield and return the tuple.\"\"\"\n        return next(gen)\n\n    def test_stale_total_batches_allows_navigation(self, _mock_t, mock_gr):\n        \"\"\"Navigation should succeed when batch_queue has the next batch\n        even if total_batches state is stale (not yet incremented).\"\"\"\n        mock_gr.update = MagicMock(side_effect=lambda **kw: (\"update\", kw))\n        mock_gr.skip = MagicMock(return_value=\"skip\")\n        mock_gr.Warning = MagicMock()\n\n        from acestep.ui.gradio.events.results.batch_navigation import navigate_to_next_batch\n\n        batch_queue = {0: _make_batch(), 1: _make_batch()}\n        # total_batches=1 is stale; actual queue has 2 entries.\n        gen = navigate_to_next_batch(\n            autogen_enabled=True,\n            current_batch_index=0,\n            total_batches=1,\n            batch_queue=batch_queue,\n        )\n        result = self._run_first_yield(gen)\n\n        # Should NOT have warned \"at_last_batch\".\n        mock_gr.Warning.assert_not_called()\n        # The 11th element (index 10) is the new batch index.\n        self.assertEqual(result[10], 1)\n\n    def test_no_next_batch_when_truly_last(self, _mock_t, mock_gr):\n        \"\"\"Warning should fire when there really is no next batch.\"\"\"\n        mock_gr.update = MagicMock(return_value=\"update\")\n        mock_gr.Warning = MagicMock()\n\n        from acestep.ui.gradio.events.results.batch_navigation import navigate_to_next_batch\n\n        batch_queue = {0: _make_batch()}\n        gen = navigate_to_next_batch(\n            autogen_enabled=False,\n            current_batch_index=0,\n            total_batches=1,\n            batch_queue=batch_queue,\n        )\n        result = self._run_first_yield(gen)\n\n        mock_gr.Warning.assert_called_once()\n        # All 49 outputs should be gr.update() no-ops.\n        self.assertEqual(len(result), 49)\n\n    def test_batch_not_in_queue(self, _mock_t, mock_gr):\n        \"\"\"Warning should fire when total_batches suggests a next batch\n        exists but the queue does not actually contain it.\"\"\"\n        mock_gr.update = MagicMock(return_value=\"update\")\n        mock_gr.Warning = MagicMock()\n\n        from acestep.ui.gradio.events.results.batch_navigation import navigate_to_next_batch\n\n        # total_batches=3 but queue only has batch 0.\n        batch_queue = {0: _make_batch()}\n        gen = navigate_to_next_batch(\n            autogen_enabled=False,\n            current_batch_index=0,\n            total_batches=3,\n            batch_queue=batch_queue,\n        )\n        result = self._run_first_yield(gen)\n\n        mock_gr.Warning.assert_called_once()\n        self.assertEqual(len(result), 49)\n\n\nif __name__ == \"__main__\":\n    unittest.main()\n"
  },
  {
    "path": "acestep/ui/gradio/events/results/batch_queue.py",
    "content": "\"\"\"Batch queue CRUD, parameter capture, and restore.\n\nManages the in-memory batch queue that stores generation results and\nparameters for navigation, replay, and AutoGen workflows.\n\"\"\"\nimport datetime\n\nimport gradio as gr\nimport torch\n\nfrom acestep.ui.gradio.i18n import t\n\n\ndef store_batch_in_queue(\n    batch_queue,\n    batch_index,\n    audio_paths,\n    generation_info,\n    seeds,\n    codes=None,\n    scores=None,\n    allow_lm_batch=False,\n    batch_size=2,\n    generation_params=None,\n    lm_generated_metadata=None,\n    extra_outputs=None,\n    status=\"completed\",\n):\n    \"\"\"Store batch results in queue with all generation parameters.\n\n    Args:\n        batch_queue: The mutable batch queue dict.\n        batch_index: Index of this batch.\n        audio_paths: List of generated audio file paths.\n        generation_info: Formatted generation timing string.\n        seeds: Seed value(s) used.\n        codes: Audio codes (list for batch, string for single).\n        scores: List of score display strings.\n        allow_lm_batch: Whether batch LM mode was used.\n        batch_size: Batch size used.\n        generation_params: Complete parameter dictionary.\n        lm_generated_metadata: LM metadata for scoring.\n        extra_outputs: Tensor dict for LRC generation.\n        status: Batch status string.\n\n    Returns:\n        The updated *batch_queue*.\n    \"\"\"\n    prev_index = batch_index - 1\n    if prev_index in batch_queue:\n        old_extra = batch_queue[prev_index].get(\"extra_outputs\", {})\n        for k, v in old_extra.items():\n            if isinstance(v, torch.Tensor) and v.is_cuda:\n                # Offload to CPU to free VRAM; data is preserved for potential re-scoring.\n                old_extra[k] = v.cpu()\n\n    batch_queue[batch_index] = {\n        \"status\": status,\n        \"audio_paths\": audio_paths,\n        \"generation_info\": generation_info,\n        \"seeds\": seeds,\n        \"codes\": codes,\n        \"scores\": scores if scores else [\"\"] * 8,\n        \"allow_lm_batch\": allow_lm_batch,\n        \"batch_size\": batch_size,\n        \"generation_params\": generation_params if generation_params else {},\n        \"lm_generated_metadata\": lm_generated_metadata,\n        \"extra_outputs\": extra_outputs if extra_outputs else {},\n        \"timestamp\": datetime.datetime.now().isoformat(),\n    }\n    return batch_queue\n\n\ndef update_batch_indicator(current_batch, total_batches):\n    \"\"\"Return localised batch indicator text.\"\"\"\n    return t(\"results.batch_indicator\", current=current_batch + 1, total=total_batches)\n\n\ndef update_navigation_buttons(current_batch, total_batches):\n    \"\"\"Determine navigation button interactive states.\n\n    Returns:\n        Tuple of ``(can_go_previous, can_go_next)`` booleans.\n    \"\"\"\n    return current_batch > 0, current_batch < total_batches - 1\n\n\ndef capture_current_params(\n    captions, lyrics, bpm, key_scale, time_signature, vocal_language,\n    inference_steps, guidance_scale, random_seed_checkbox, seed,\n    reference_audio, audio_duration, batch_size_input, src_audio,\n    text2music_audio_code_string, repainting_start, repainting_end,\n    instruction_display_gen, audio_cover_strength, cover_noise_strength, task_type,\n    use_adg, cfg_interval_start, cfg_interval_end, shift, infer_method,\n    custom_timesteps, audio_format, lm_temperature,\n    think_checkbox, lm_cfg_scale, lm_top_k, lm_top_p, lm_negative_prompt,\n    use_cot_metas, use_cot_caption, use_cot_language,\n    constrained_decoding_debug, allow_lm_batch, auto_score, auto_lrc,\n    score_scale, lm_batch_chunk_size,\n    track_name, complete_track_classes,\n    enable_normalization, normalization_db,\n    fade_in_duration, fade_out_duration,\n    latent_shift, latent_rescale,\n):\n    \"\"\"Capture current UI parameters for next-batch generation.\n\n    Audio codes are cleared so AutoGen batches always generate fresh content.\n    \"\"\"\n    return {\n        \"captions\": captions,\n        \"lyrics\": lyrics,\n        \"bpm\": bpm,\n        \"key_scale\": key_scale,\n        \"time_signature\": time_signature,\n        \"vocal_language\": vocal_language,\n        \"inference_steps\": inference_steps,\n        \"guidance_scale\": guidance_scale,\n        \"random_seed_checkbox\": True,\n        \"seed\": seed,\n        \"reference_audio\": reference_audio,\n        \"audio_duration\": audio_duration,\n        \"batch_size_input\": batch_size_input,\n        \"src_audio\": src_audio,\n        \"text2music_audio_code_string\": \"\",\n        \"repainting_start\": repainting_start,\n        \"repainting_end\": repainting_end,\n        \"instruction_display_gen\": instruction_display_gen,\n        \"audio_cover_strength\": audio_cover_strength,\n        \"cover_noise_strength\": cover_noise_strength,\n        \"task_type\": task_type,\n        \"use_adg\": use_adg,\n        \"cfg_interval_start\": cfg_interval_start,\n        \"cfg_interval_end\": cfg_interval_end,\n        \"shift\": shift,\n        \"infer_method\": infer_method,\n        \"custom_timesteps\": custom_timesteps,\n        \"audio_format\": audio_format,\n        \"lm_temperature\": lm_temperature,\n        \"think_checkbox\": think_checkbox,\n        \"lm_cfg_scale\": lm_cfg_scale,\n        \"lm_top_k\": lm_top_k,\n        \"lm_top_p\": lm_top_p,\n        \"lm_negative_prompt\": lm_negative_prompt,\n        \"use_cot_metas\": use_cot_metas,\n        \"use_cot_caption\": use_cot_caption,\n        \"use_cot_language\": use_cot_language,\n        \"constrained_decoding_debug\": constrained_decoding_debug,\n        \"allow_lm_batch\": allow_lm_batch,\n        \"auto_score\": auto_score,\n        \"auto_lrc\": auto_lrc,\n        \"score_scale\": score_scale,\n        \"lm_batch_chunk_size\": lm_batch_chunk_size,\n        \"track_name\": track_name,\n        \"complete_track_classes\": complete_track_classes,\n        \"enable_normalization\": enable_normalization,\n        \"normalization_db\": normalization_db,\n        \"fade_in_duration\": fade_in_duration,\n        \"fade_out_duration\": fade_out_duration,\n        \"latent_shift\": latent_shift,\n        \"latent_rescale\": latent_rescale,\n    }\n\n\ndef restore_batch_parameters(current_batch_index, batch_queue):\n    \"\"\"Restore parameters from the currently viewed batch to the Input UI.\n\n    Args:\n        current_batch_index: Index of the batch to restore from.\n        batch_queue: The batch queue dict.\n\n    Returns:\n        Tuple of restored parameter values for Gradio outputs.\n    \"\"\"\n    if current_batch_index not in batch_queue:\n        gr.Warning(t(\"messages.no_batch_data\"))\n        return [gr.update()] * 26\n\n    batch_data = batch_queue[current_batch_index]\n    params = batch_data.get(\"generation_params\", {})\n\n    captions = params.get(\"captions\", \"\")\n    lyrics = params.get(\"lyrics\", \"\")\n    bpm = params.get(\"bpm\", None)\n    key_scale = params.get(\"key_scale\", \"\")\n    time_signature = params.get(\"time_signature\", \"\")\n    vocal_language = params.get(\"vocal_language\", \"unknown\")\n    audio_duration = params.get(\"audio_duration\", -1)\n    batch_size_input = params.get(\"batch_size_input\", 2)\n    inference_steps = params.get(\"inference_steps\", 8)\n    lm_temperature = params.get(\"lm_temperature\", 0.85)\n    lm_cfg_scale = params.get(\"lm_cfg_scale\", 2.0)\n    lm_top_k = params.get(\"lm_top_k\", 0)\n    lm_top_p = params.get(\"lm_top_p\", 0.9)\n    think_checkbox = params.get(\"think_checkbox\", True)\n    use_cot_caption = params.get(\"use_cot_caption\", True)\n    use_cot_language = params.get(\"use_cot_language\", True)\n    allow_lm_batch = params.get(\"allow_lm_batch\", True)\n    track_name = params.get(\"track_name\", None)\n    complete_track_classes = params.get(\"complete_track_classes\", [])\n    enable_normalization = params.get(\"enable_normalization\", True)\n    normalization_db = params.get(\"normalization_db\", -1.0)\n    fade_in_duration = params.get(\"fade_in_duration\", 0.0)\n    fade_out_duration = params.get(\"fade_out_duration\", 0.0)\n    latent_shift = params.get(\"latent_shift\", 0.0)\n    latent_rescale = params.get(\"latent_rescale\", 1.0)\n\n    stored_codes = batch_data.get(\"codes\", \"\")\n    if stored_codes:\n        codes_main = stored_codes[0] if isinstance(stored_codes, list) and stored_codes else stored_codes\n    else:\n        codes_main = \"\"\n\n    gr.Info(t(\"messages.params_restored\", n=current_batch_index + 1))\n\n    return (\n        codes_main, captions, lyrics, bpm, key_scale, time_signature,\n        vocal_language, audio_duration, batch_size_input, inference_steps,\n        lm_temperature, lm_cfg_scale, lm_top_k, lm_top_p, think_checkbox,\n        use_cot_caption, use_cot_language, allow_lm_batch,\n        track_name, complete_track_classes,\n        enable_normalization, normalization_db,\n        fade_in_duration, fade_out_duration,\n        latent_shift, latent_rescale,\n    )\n"
  },
  {
    "path": "acestep/ui/gradio/events/results/batch_queue_test.py",
    "content": "\"\"\"Unit tests for batch_queue module.\"\"\"\n\nimport unittest\n\nfrom acestep.ui.gradio.events.results.batch_queue import (\n    store_batch_in_queue,\n    update_batch_indicator,\n    update_navigation_buttons,\n)\n\n\nclass UpdateNavigationButtonsTests(unittest.TestCase):\n    \"\"\"Tests for update_navigation_buttons.\"\"\"\n\n    def test_first_batch(self):\n        \"\"\"At first batch, prev should be False.\"\"\"\n        can_prev, can_next = update_navigation_buttons(0, 3)\n        self.assertFalse(can_prev)\n        self.assertTrue(can_next)\n\n    def test_last_batch(self):\n        \"\"\"At last batch, next should be False.\"\"\"\n        can_prev, can_next = update_navigation_buttons(2, 3)\n        self.assertTrue(can_prev)\n        self.assertFalse(can_next)\n\n    def test_middle_batch(self):\n        \"\"\"At a middle batch, both should be True.\"\"\"\n        can_prev, can_next = update_navigation_buttons(1, 3)\n        self.assertTrue(can_prev)\n        self.assertTrue(can_next)\n\n    def test_single_batch(self):\n        \"\"\"With only one batch, both should be False.\"\"\"\n        can_prev, can_next = update_navigation_buttons(0, 1)\n        self.assertFalse(can_prev)\n        self.assertFalse(can_next)\n\n\nclass StoreBatchInQueueTests(unittest.TestCase):\n    \"\"\"Tests for store_batch_in_queue.\"\"\"\n\n    def test_store_first_batch(self):\n        \"\"\"Storing the first batch should create a new queue entry.\"\"\"\n        queue = {}\n        result = store_batch_in_queue(\n            batch_queue=queue,\n            batch_index=0,\n            audio_paths=[\"/tmp/audio1.mp3\"],\n            generation_info=\"test info\",\n            seeds=\"42\",\n        )\n        self.assertIsInstance(result, dict)\n        self.assertIn(0, result)\n        self.assertEqual(result[0][\"audio_paths\"], [\"/tmp/audio1.mp3\"])\n        self.assertEqual(result[0][\"generation_info\"], \"test info\")\n\n    def test_store_preserves_existing_batches(self):\n        \"\"\"Storing a new batch should not remove existing batches.\"\"\"\n        queue = {\n            0: {\n                \"audio_paths\": [\"/tmp/old.mp3\"],\n                \"generation_info\": \"old info\",\n                \"seeds\": \"1\",\n                \"status\": \"completed\",\n            }\n        }\n        result = store_batch_in_queue(\n            batch_queue=queue,\n            batch_index=1,\n            audio_paths=[\"/tmp/new.mp3\"],\n            generation_info=\"new info\",\n            seeds=\"99\",\n        )\n        self.assertIn(0, result)\n        self.assertIn(1, result)\n        self.assertEqual(result[0][\"audio_paths\"], [\"/tmp/old.mp3\"])\n        self.assertEqual(result[1][\"audio_paths\"], [\"/tmp/new.mp3\"])\n\n    def test_store_with_scores_and_codes(self):\n        \"\"\"Storing with scores and codes should preserve them.\"\"\"\n        queue = {}\n        result = store_batch_in_queue(\n            batch_queue=queue,\n            batch_index=0,\n            audio_paths=[\"/tmp/a.mp3\"],\n            generation_info=\"info\",\n            seeds=\"42\",\n            codes=[\"code1\"],\n            scores=[\"8.5/10\"],\n        )\n        self.assertEqual(result[0][\"codes\"], [\"code1\"])\n        self.assertEqual(result[0][\"scores\"], [\"8.5/10\"])\n\n    def test_store_defaults_scores_to_empty(self):\n        \"\"\"Storing without scores should default to 8 empty strings.\"\"\"\n        queue = {}\n        result = store_batch_in_queue(\n            batch_queue=queue,\n            batch_index=0,\n            audio_paths=[\"/tmp/a.mp3\"],\n            generation_info=\"info\",\n            seeds=\"42\",\n        )\n        self.assertEqual(result[0][\"scores\"], [\"\"] * 8)\n\n    def test_store_offloads_previous_extra_outputs_tensors_to_cpu(self):\n        \"\"\"Storing a new batch should move CUDA tensors from the previous batch's extra_outputs to CPU.\"\"\"\n        import torch\n        # Use a CPU tensor to simulate: is_cuda is False, so no offload occurs\n        tensor = torch.zeros(2, 4)\n        queue = {\n            0: {\n                \"audio_paths\": [\"/tmp/old.mp3\"],\n                \"generation_info\": \"old info\",\n                \"seeds\": \"1\",\n                \"status\": \"completed\",\n                \"extra_outputs\": {\"pred_latents\": tensor},\n            }\n        }\n        result = store_batch_in_queue(\n            batch_queue=queue,\n            batch_index=1,\n            audio_paths=[\"/tmp/new.mp3\"],\n            generation_info=\"new info\",\n            seeds=\"99\",\n        )\n        # Tensor is preserved (not deleted) when already on CPU\n        self.assertIn(\"pred_latents\", result[0][\"extra_outputs\"])\n        self.assertIn(1, result)\n\n    @unittest.skipUnless(__import__(\"torch\").cuda.is_available(), \"CUDA not available\")\n    def test_store_offloads_cuda_tensor_to_cpu(self):\n        \"\"\"Storing a new batch should move CUDA tensors to CPU, freeing VRAM.\"\"\"\n        import torch\n        cuda_tensor = torch.zeros(2, 4, device=\"cuda\")\n        queue = {\n            0: {\n                \"audio_paths\": [\"/tmp/old.mp3\"],\n                \"generation_info\": \"old info\",\n                \"seeds\": \"1\",\n                \"status\": \"completed\",\n                \"extra_outputs\": {\"pred_latents\": cuda_tensor},\n            }\n        }\n        store_batch_in_queue(\n            batch_queue=queue,\n            batch_index=1,\n            audio_paths=[\"/tmp/new.mp3\"],\n            generation_info=\"new info\",\n            seeds=\"99\",\n        )\n        offloaded = queue[0][\"extra_outputs\"][\"pred_latents\"]\n        self.assertFalse(offloaded.is_cuda, \"Tensor should have been moved to CPU\")\n        self.assertEqual(offloaded.device.type, \"cpu\")\n\n    def test_store_offloads_only_previous_batch_cuda_tensors(self):\n        \"\"\"Only the immediately preceding batch's CUDA tensors should be offloaded.\"\"\"\n        import torch\n        tensor_a = torch.ones(1)\n        tensor_b = torch.ones(2)\n        queue = {\n            0: {\"audio_paths\": [], \"extra_outputs\": {\"pred_latents\": tensor_a}, \"status\": \"completed\"},\n            1: {\"audio_paths\": [], \"extra_outputs\": {\"pred_latents\": tensor_b}, \"status\": \"completed\"},\n        }\n        store_batch_in_queue(\n            batch_queue=queue,\n            batch_index=2,\n            audio_paths=[\"/tmp/c.mp3\"],\n            generation_info=\"info\",\n            seeds=\"7\",\n        )\n        # Both batch 0 and batch 1 should still have their tensors (CPU tensors are untouched)\n        self.assertIn(\"pred_latents\", queue[0][\"extra_outputs\"])\n        self.assertIn(\"pred_latents\", queue[1][\"extra_outputs\"])\n\n    def test_store_first_batch_no_prev_cleanup(self):\n        \"\"\"Storing the first batch (index 0) should not fail when there is no previous batch.\"\"\"\n        queue = {}\n        result = store_batch_in_queue(\n            batch_queue=queue,\n            batch_index=0,\n            audio_paths=[\"/tmp/a.mp3\"],\n            generation_info=\"info\",\n            seeds=\"42\",\n        )\n        self.assertIn(0, result)\n\n    def test_store_preserves_non_tensor_extra_outputs(self):\n        \"\"\"Storing a new batch should preserve non-tensor values in the previous batch's extra_outputs.\"\"\"\n        queue = {\n            0: {\n                \"audio_paths\": [],\n                \"extra_outputs\": {\n                    \"lrcs\": [\"[00:00.00] hello\"],\n                    \"subtitles\": [None],\n                },\n                \"status\": \"completed\",\n            }\n        }\n        store_batch_in_queue(\n            batch_queue=queue,\n            batch_index=1,\n            audio_paths=[\"/tmp/b.mp3\"],\n            generation_info=\"info\",\n            seeds=\"5\",\n        )\n        # Non-tensor values should be preserved since only CUDA tensors are offloaded\n        self.assertEqual(queue[0][\"extra_outputs\"][\"lrcs\"], [\"[00:00.00] hello\"])\n        self.assertEqual(queue[0][\"extra_outputs\"][\"subtitles\"], [None])\n\n\nif __name__ == \"__main__\":\n    unittest.main()\n"
  },
  {
    "path": "acestep/ui/gradio/events/results/generation_info.py",
    "content": "\"\"\"Generation info formatting and shared constants.\n\nProvides timing summary construction and module-level constants shared\nacross the results sub-package.\n\"\"\"\nimport os\nimport sys\nfrom typing import Dict, Any, Optional\n\nfrom acestep.ui.gradio.i18n import t\n\n# Platform detection for Windows-specific fixes\nIS_WINDOWS = sys.platform == \"win32\"\n\n# Global results directory inside project root\n# This file is in acestep/ui/gradio/events/results/, need 6 levels up to project root\nPROJECT_ROOT = os.path.dirname(\n    os.path.dirname(os.path.dirname(os.path.dirname(os.path.dirname(\n        os.path.dirname(os.path.abspath(__file__))))))\n)\nDEFAULT_RESULTS_DIR = os.path.join(PROJECT_ROOT, \"gradio_outputs\").replace(\"\\\\\", \"/\")\nos.makedirs(DEFAULT_RESULTS_DIR, exist_ok=True)\n\n\ndef clear_audio_outputs_for_new_generation():\n    \"\"\"Return pre-generation output updates without remounting audio players.\n\n    In Gradio runtime, ask each audio component to seek to the start via\n    ``gr.update(playback_position=0)`` and clear only the batch-download file\n    list (9th output). This rewinds playback on regenerate without assigning\n    ``value=None`` (which would remount players and risk browser-side volume\n    resets).\n\n    In non-Gradio test environments, gracefully fall back to 9 ``None`` values.\n    \"\"\"\n    try:\n        import gradio as gr  # local import keeps headless tests dependency-free\n    except (ModuleNotFoundError, ImportError):\n        return (None,) * 9\n    return tuple(gr.update(playback_position=0) for _ in range(8)) + (None,)\n\n\ndef _build_generation_info(\n    lm_metadata: Optional[Dict[str, Any]],\n    time_costs: Dict[str, float],\n    seed_value: str,\n    inference_steps: int,\n    num_audios: int,\n    audio_format: str = \"flac\",\n) -> str:\n    \"\"\"Build a compact generation timing summary.\n\n    Args:\n        lm_metadata: LM-generated metadata dictionary (unused, kept for API compat).\n        time_costs: Unified time costs dictionary.\n        seed_value: Seed value string (unused, kept for API compat).\n        inference_steps: Number of inference steps (unused, kept for API compat).\n        num_audios: Number of generated audios.\n        audio_format: Output audio format name (e.g. \"flac\", \"mp3\", \"wav32\").\n\n    Returns:\n        Formatted generation info string.\n    \"\"\"\n    if not time_costs or num_audios <= 0:\n        return \"\"\n\n    songs_label = f\"({num_audios} song{'s' if num_audios > 1 else ''})\"\n    info_parts = []\n\n    # --- Block 1: Generation time (LM + DiT) ---\n    lm_total = time_costs.get('lm_total_time', 0.0)\n    dit_total = time_costs.get('dit_total_time_cost', 0.0)\n    gen_total = lm_total + dit_total\n\n    if gen_total > 0:\n        avg = gen_total / num_audios\n        lines = [f\"**🎵 Total generation time {songs_label}: {gen_total:.2f}s**\"]\n        lines.append(f\"- {avg:.2f}s per song\")\n        if lm_total > 0:\n            lines.append(f\"- LM phase {songs_label}: {lm_total:.2f}s\")\n        if dit_total > 0:\n            lines.append(f\"- DiT phase {songs_label}: {dit_total:.2f}s\")\n        info_parts.append(\"\\n\".join(lines))\n\n    # --- Block 2: Processing time (conversion + scoring + LRC) ---\n    audio_conversion_time = time_costs.get('audio_conversion_time', 0.0)\n    auto_score_time = time_costs.get('auto_score_time', 0.0)\n    auto_lrc_time = time_costs.get('auto_lrc_time', 0.0)\n    proc_total = audio_conversion_time + auto_score_time + auto_lrc_time\n\n    if proc_total > 0:\n        fmt_label = audio_format.upper() if audio_format != \"wav32\" else \"WAV 32-bit\"\n        lines = [f\"**🔧 Total processing time {songs_label}: {proc_total:.2f}s**\"]\n        if audio_conversion_time > 0:\n            lines.append(f\"- to {fmt_label} {songs_label}: {audio_conversion_time:.2f}s\")\n        if auto_score_time > 0:\n            lines.append(f\"- scoring {songs_label}: {auto_score_time:.2f}s\")\n        if auto_lrc_time > 0:\n            lines.append(f\"- LRC detection {songs_label}: {auto_lrc_time:.2f}s\")\n        info_parts.append(\"\\n\".join(lines))\n\n    return \"\\n\\n\".join(info_parts)\n"
  },
  {
    "path": "acestep/ui/gradio/events/results/generation_info_test.py",
    "content": "\"\"\"Unit tests for generation_info module.\"\"\"\n\nimport importlib.util\nimport os\nfrom pathlib import Path\nimport sys\nimport types\nimport unittest\nimport builtins\nfrom unittest.mock import patch\n\n\ndef _load_module():\n    \"\"\"Load target module directly by file path for isolated testing.\"\"\"\n    # Stub i18n package path so importing generation_info.py does not require\n    # importing the full Gradio UI package in headless test environments.\n    # Keep these stubs scoped to module loading to avoid leaking into other tests.\n    acestep_pkg = types.ModuleType(\"acestep\")\n    ui_pkg = types.ModuleType(\"acestep.ui\")\n    gradio_pkg = types.ModuleType(\"acestep.ui.gradio\")\n    i18n_mod = types.ModuleType(\"acestep.ui.gradio.i18n\")\n    i18n_mod.t = lambda key, **_kwargs: key\n    acestep_pkg.ui = ui_pkg\n    ui_pkg.gradio = gradio_pkg\n    gradio_pkg.i18n = i18n_mod\n\n    module_path = Path(__file__).with_name(\"generation_info.py\")\n    spec = importlib.util.spec_from_file_location(\"generation_info\", module_path)\n    module = importlib.util.module_from_spec(spec)\n    with patch.dict(\n        \"sys.modules\",\n        {\n            \"acestep\": acestep_pkg,\n            \"acestep.ui\": ui_pkg,\n            \"acestep.ui.gradio\": gradio_pkg,\n            \"acestep.ui.gradio.i18n\": i18n_mod,\n        },\n    ):\n        spec.loader.exec_module(module)  # type: ignore[union-attr]\n    return module\n\n\n_MODULE = _load_module()\nDEFAULT_RESULTS_DIR = _MODULE.DEFAULT_RESULTS_DIR\nPROJECT_ROOT = _MODULE.PROJECT_ROOT\nclear_audio_outputs_for_new_generation = _MODULE.clear_audio_outputs_for_new_generation\n_build_generation_info = _MODULE._build_generation_info\n\n\nclass ConstantsTests(unittest.TestCase):\n    \"\"\"Tests for module-level constants.\"\"\"\n\n    def test_project_root_exists(self):\n        \"\"\"PROJECT_ROOT should point to an existing directory.\"\"\"\n        self.assertTrue(os.path.isdir(PROJECT_ROOT))\n\n    def test_default_results_dir_is_under_project_root(self):\n        \"\"\"DEFAULT_RESULTS_DIR should be a subdirectory of PROJECT_ROOT.\"\"\"\n        self.assertTrue(\n            DEFAULT_RESULTS_DIR.replace(\"\\\\\", \"/\").startswith(\n                PROJECT_ROOT.replace(\"\\\\\", \"/\")\n            )\n        )\n\n\nclass ClearAudioOutputsTests(unittest.TestCase):\n    \"\"\"Tests for clear_audio_outputs_for_new_generation.\"\"\"\n\n    def test_returns_nine_nones(self):\n        \"\"\"Should return a tuple of 9 None values when Gradio import fails.\"\"\"\n        real_import = builtins.__import__\n\n        def _mocked_import(name, *args, **kwargs):\n            \"\"\"Raise ImportError for gradio while delegating all other imports.\"\"\"\n            if name == \"gradio\":\n                raise ImportError(\"simulated missing gradio\")\n            return real_import(name, *args, **kwargs)\n\n        with patch(\"builtins.__import__\", side_effect=_mocked_import):\n            result = clear_audio_outputs_for_new_generation()\n        self.assertIsInstance(result, tuple)\n        self.assertEqual(len(result), 9)\n        for item in result:\n            self.assertIsNone(item)\n\n    def test_gradio_runtime_rewinds_audio_but_clears_batch_files(self):\n        \"\"\"With Gradio available, audio outputs should rewind without remounting.\"\"\"\n        fake_gradio = types.SimpleNamespace(update=lambda **kwargs: kwargs)\n        with patch.dict(\"sys.modules\", {\"gradio\": fake_gradio}):\n            result = clear_audio_outputs_for_new_generation()\n        self.assertEqual(len(result), 9)\n        self.assertEqual(result[:8], ({\"playback_position\": 0},) * 8)\n        self.assertIsNone(result[8])\n\n\nclass BuildGenerationInfoTests(unittest.TestCase):\n    \"\"\"Tests for _build_generation_info.\"\"\"\n\n    def test_basic_generation_info(self):\n        \"\"\"Should build a readable info string from basic parameters.\"\"\"\n        time_costs = {\n            \"lm_total_time\": 2.0,\n            \"dit_total_time_cost\": 3.0,\n            \"audio_conversion_time\": 0.5,\n        }\n        info = _build_generation_info(\n            lm_metadata=None,\n            time_costs=time_costs,\n            seed_value=\"42\",\n            inference_steps=100,\n            num_audios=2,\n            audio_format=\"flac\",\n        )\n        self.assertIsInstance(info, str)\n        self.assertIn(\"generation time\", info.lower())\n\n    def test_empty_time_costs_returns_empty(self):\n        \"\"\"Empty time_costs should return an empty string.\"\"\"\n        info = _build_generation_info(\n            lm_metadata=None,\n            time_costs={},\n            seed_value=\"0\",\n            inference_steps=50,\n            num_audios=1,\n        )\n        self.assertEqual(info, \"\")\n\n    def test_zero_audios_returns_empty(self):\n        \"\"\"Zero num_audios should return an empty string.\"\"\"\n        info = _build_generation_info(\n            lm_metadata=None,\n            time_costs={\"dit_total_time_cost\": 5.0},\n            seed_value=\"0\",\n            inference_steps=50,\n            num_audios=0,\n        )\n        self.assertEqual(info, \"\")\n\n    def test_non_target_behavior_unchanged(self):\n        \"\"\"Calling with same params twice should produce identical output.\"\"\"\n        kwargs = dict(\n            lm_metadata=None,\n            time_costs={\"dit_total_time_cost\": 5.0, \"lm_total_time\": 1.0},\n            seed_value=\"123\",\n            inference_steps=200,\n            num_audios=4,\n            audio_format=\"mp3\",\n        )\n        info1 = _build_generation_info(**kwargs)\n        info2 = _build_generation_info(**kwargs)\n        self.assertEqual(info1, info2)\n\n\nif __name__ == \"__main__\":\n    unittest.main()\n"
  },
  {
    "path": "acestep/ui/gradio/events/results/generation_progress.py",
    "content": "\"\"\"Core audio generation with progressive UI yields.\n\nContains the main ``generate_with_progress`` generator that drives the\nGradio generate button: validates GPU limits, calls the inference\npipeline, saves audio files, and optionally runs auto-scoring and\nauto-LRC in a single streaming pass.\n\"\"\"\nimport os\nimport json\nimport time as time_module\n\nimport gradio as gr\nimport torch\nfrom loguru import logger\n\nfrom acestep.inference import generate_music, GenerationParams, GenerationConfig\nfrom acestep.audio_utils import save_audio\nfrom acestep.gpu_config import (\n    get_global_gpu_config,\n    check_duration_limit,\n    check_batch_size_limit,\n)\nfrom acestep.ui.gradio.i18n import t\nfrom acestep.ui.gradio.events.generation_handlers import parse_and_validate_timesteps\nfrom acestep.ui.gradio.events.results.generation_info import (\n    DEFAULT_RESULTS_DIR,\n    _build_generation_info,\n)\nfrom acestep.ui.gradio.events.results.audio_playback_updates import (\n    build_audio_slot_update,\n)\nfrom acestep.ui.gradio.events.results.scoring import calculate_score_handler\nfrom acestep.ui.gradio.events.results.lrc_utils import lrc_to_vtt_file\n\n\ndef generate_with_progress(\n    dit_handler, llm_handler,\n    captions, lyrics, bpm, key_scale, time_signature, vocal_language,\n    inference_steps, guidance_scale, random_seed_checkbox, seed,\n    reference_audio, audio_duration, batch_size_input, src_audio,\n    text2music_audio_code_string, repainting_start, repainting_end,\n    instruction_display_gen, audio_cover_strength, cover_noise_strength, task_type,\n    use_adg, cfg_interval_start, cfg_interval_end, shift, infer_method,\n    custom_timesteps, audio_format, lm_temperature,\n    think_checkbox, lm_cfg_scale, lm_top_k, lm_top_p, lm_negative_prompt,\n    use_cot_metas, use_cot_caption, use_cot_language, is_format_caption,\n    constrained_decoding_debug,\n    allow_lm_batch,\n    auto_score,\n    auto_lrc,\n    score_scale,\n    lm_batch_chunk_size,\n    enable_normalization,\n    normalization_db,\n    fade_in_duration,\n    fade_out_duration,\n    latent_shift,\n    latent_rescale,\n    repaint_mode,\n    repaint_strength,\n    progress=gr.Progress(track_tqdm=True),\n):\n    \"\"\"Generate audio with progress tracking.\n\n    This is a Gradio generator that yields partial UI updates as each\n    sample is processed, enabling progressive display of results.\n\n    Yields:\n        Tuple of Gradio component updates for the 52-output generate event.\n    \"\"\"\n    # GPU memory validation\n    gpu_config = get_global_gpu_config()\n    lm_initialized = llm_handler.llm_initialized if llm_handler else False\n\n    if audio_duration is not None and audio_duration > 0:\n        is_valid, warning_msg = check_duration_limit(audio_duration, gpu_config, lm_initialized)\n        if not is_valid:\n            gr.Warning(warning_msg)\n            max_dur = gpu_config.max_duration_with_lm if lm_initialized else gpu_config.max_duration_without_lm\n            audio_duration = min(audio_duration, max_dur)\n            logger.warning(f\"Duration clamped to {audio_duration}s due to GPU memory limits\")\n\n    if batch_size_input is not None and batch_size_input > 0:\n        is_valid, warning_msg = check_batch_size_limit(int(batch_size_input), gpu_config, lm_initialized)\n        if not is_valid:\n            gr.Warning(warning_msg)\n            max_bs = gpu_config.max_batch_size_with_lm if lm_initialized else gpu_config.max_batch_size_without_lm\n            batch_size_input = min(int(batch_size_input), max_bs)\n            logger.warning(f\"Batch size clamped to {batch_size_input} due to GPU memory limits\")\n\n    # Skip Phase 1 metas COT if sample is already formatted\n    actual_use_cot_metas = use_cot_metas\n    if is_format_caption and use_cot_metas:\n        actual_use_cot_metas = False\n        logger.info(\"[generate_with_progress] Skipping Phase 1 metas COT: is_format_caption=True\")\n        gr.Info(t(\"messages.skipping_metas_cot\"))\n\n    parsed_timesteps, _has_ts_warn, _ = parse_and_validate_timesteps(custom_timesteps, inference_steps)\n    actual_inference_steps = len(parsed_timesteps) - 1 if parsed_timesteps is not None else inference_steps\n\n    if task_type == \"text2music\":\n        src_audio = None\n\n    # Defensive guard: cover/repaint/extract/lego tasks should never use\n    # stale audio codes from the text2music_audio_code_string textbox.\n    # Only text2music (Custom mode) with thinking disabled should pass codes.\n    if task_type != \"text2music\":\n        text2music_audio_code_string = \"\"\n\n    gen_params = GenerationParams(\n        task_type=task_type,\n        instruction=instruction_display_gen,\n        reference_audio=reference_audio,\n        src_audio=src_audio,\n        audio_codes=text2music_audio_code_string if not think_checkbox else \"\",\n        caption=captions or \"\",\n        lyrics=lyrics or \"\",\n        instrumental=False,\n        vocal_language=vocal_language,\n        bpm=bpm,\n        keyscale=key_scale,\n        timesignature=time_signature,\n        duration=audio_duration,\n        inference_steps=actual_inference_steps,\n        guidance_scale=guidance_scale,\n        use_adg=use_adg,\n        cfg_interval_start=cfg_interval_start,\n        cfg_interval_end=cfg_interval_end,\n        shift=shift,\n        infer_method=infer_method,\n        timesteps=parsed_timesteps,\n        repainting_start=repainting_start,\n        repainting_end=repainting_end,\n        audio_cover_strength=audio_cover_strength,\n        cover_noise_strength=cover_noise_strength,\n        thinking=think_checkbox,\n        lm_temperature=lm_temperature,\n        lm_cfg_scale=lm_cfg_scale,\n        lm_top_k=lm_top_k,\n        lm_top_p=lm_top_p,\n        lm_negative_prompt=lm_negative_prompt,\n        use_cot_metas=actual_use_cot_metas,\n        use_cot_caption=use_cot_caption,\n        use_cot_language=use_cot_language,\n        use_constrained_decoding=True,\n        enable_normalization=enable_normalization,\n        normalization_db=normalization_db,\n        fade_in_duration=fade_in_duration if fade_in_duration else 0.0,\n        fade_out_duration=fade_out_duration if fade_out_duration else 0.0,\n        latent_shift=latent_shift,\n        latent_rescale=latent_rescale,\n        repaint_mode=repaint_mode if repaint_mode else \"balanced\",\n        repaint_strength=float(repaint_strength) if repaint_strength is not None else 0.5,\n    )\n\n    if isinstance(seed, str) and seed.strip():\n        seed_list = [int(s.strip()) for s in seed.split(\",\")] if \",\" in seed else [int(seed.strip())]\n    else:\n        seed_list = None\n\n    gen_config = GenerationConfig(\n        batch_size=batch_size_input,\n        allow_lm_batch=allow_lm_batch,\n        use_random_seed=random_seed_checkbox,\n        seeds=seed_list,\n        lm_batch_chunk_size=lm_batch_chunk_size,\n        constrained_decoding_debug=constrained_decoding_debug,\n        audio_format=audio_format,\n    )\n\n    result = generate_music(dit_handler, llm_handler, params=gen_params, config=gen_config, progress=progress)\n\n    audio_outputs = [None] * 8\n    all_audio_paths: list = []\n    final_codes_list = [\"\"] * 8\n    final_scores_list = [\"\"] * 8\n    final_lrcs_list = [\"\"] * 8\n    final_subtitles_list = [None] * 8\n\n    seed_value_for_ui = result.extra_outputs.get(\"seed_value\", \"\")\n    lm_generated_metadata = result.extra_outputs.get(\"lm_metadata\", {})\n    time_costs = result.extra_outputs.get(\"time_costs\", {}).copy()\n\n    audio_conversion_start_time = time_module.time()\n    total_auto_score_time = 0.0\n    total_auto_lrc_time = 0.0\n\n    updated_audio_codes = text2music_audio_code_string if not think_checkbox else \"\"  # noqa: F841\n\n    generation_info = _build_generation_info(\n        lm_metadata=lm_generated_metadata,\n        time_costs=time_costs,\n        seed_value=seed_value_for_ui,\n        inference_steps=inference_steps,\n        num_audios=len(result.audios) if result.success else 0,\n        audio_format=audio_format,\n    )\n\n    if not result.success:\n        yield (\n            (None,) * 8\n            + (None, generation_info, result.status_message, gr.skip())\n            + (gr.skip(),) * 8  # scores\n            + (gr.skip(),) * 8  # codes_display\n            + (gr.skip(),) * 8  # details_accordion\n            + (gr.skip(),) * 8  # lrc_display\n            + (None, is_format_caption, None, None)\n        )\n        return\n\n    audios = result.audios\n    progress(0.99, \"Converting audio to mp3...\")\n\n    # Clear all scores/codes/lrc displays\n    clear_scores = [gr.update(value=\"\", visible=True) for _ in range(8)]\n    clear_codes = [gr.update(value=\"\", visible=True) for _ in range(8)]\n    clear_lrcs = [gr.update(value=\"\", visible=True) for _ in range(8)]\n    clear_accordions = [gr.skip() for _ in range(8)]\n    # Keep existing players mounted during generation to avoid browser volume reset.\n    dump_audio = [gr.skip()] * 8\n\n    yield (\n        *dump_audio,\n        None, generation_info, \"Preparing generation...\", gr.skip(),\n        *clear_scores, *clear_codes, *clear_accordions, *clear_lrcs,\n        lm_generated_metadata, is_format_caption, None, None,\n    )\n    time_module.sleep(0.1)\n\n    for i in range(8):\n        if i >= len(audios):\n            continue\n\n        key = audios[i][\"key\"]\n        audio_tensor = audios[i][\"tensor\"]\n        sample_rate = audios[i][\"sample_rate\"]\n        audio_params = audios[i][\"params\"]\n\n        timestamp = int(time_module.time())\n        temp_dir = os.path.join(DEFAULT_RESULTS_DIR, f\"batch_{timestamp}\")\n        temp_dir = os.path.abspath(temp_dir).replace(\"\\\\\", \"/\")\n        os.makedirs(temp_dir, exist_ok=True)\n        json_path = os.path.join(temp_dir, f\"{key}.json\").replace(\"\\\\\", \"/\")\n\n        ext = \"wav\" if audio_format == \"wav32\" else audio_format\n        audio_path = os.path.join(temp_dir, f\"{key}.{ext}\").replace(\"\\\\\", \"/\")\n\n        saved_path = save_audio(\n            audio_data=audio_tensor, output_path=audio_path,\n            sample_rate=sample_rate, format=audio_format, channels_first=True,\n        )\n        if saved_path:\n            audio_path = saved_path.replace(\"\\\\\", \"/\")\n\n        with open(json_path, 'w', encoding='utf-8') as f:\n            json.dump(audio_params, f, indent=2, ensure_ascii=False)\n\n        audio_outputs[i] = audio_path\n        all_audio_paths.append(audio_path)\n        all_audio_paths.append(json_path)\n\n        code_str = audio_params.get(\"audio_codes\", \"\")\n        final_codes_list[i] = code_str\n\n        scores_ui_updates = [gr.skip() for _ in range(8)]\n        score_str = \"Done!\"\n\n        if auto_score:\n            auto_score_start = time_module.time()\n            sample_tensor_data = _extract_sample_tensor(result.extra_outputs, i)\n            score_str = calculate_score_handler(\n                llm_handler, code_str, captions, lyrics, lm_generated_metadata,\n                bpm, key_scale, time_signature, audio_duration, vocal_language,\n                score_scale, dit_handler, sample_tensor_data, inference_steps,\n            )\n            total_auto_score_time += time_module.time() - auto_score_start\n\n        scores_ui_updates[i] = score_str\n        final_scores_list[i] = score_str\n\n        if auto_lrc:\n            auto_lrc_start = time_module.time()\n            _run_auto_lrc(\n                dit_handler, result.extra_outputs, i,\n                audio_duration, vocal_language, inference_steps,\n                final_lrcs_list, final_subtitles_list,\n            )\n            total_auto_lrc_time += time_module.time() - auto_lrc_start\n\n        # STEP 1: yield audio + clear LRC\n        cur_audio = [gr.skip()] * 8\n        cur_audio[i] = build_audio_slot_update(gr, audio_path)\n        cur_codes = [gr.skip()] * 8\n        cur_codes[i] = gr.update(value=code_str, visible=True)\n        cur_accordions = [gr.skip()] * 8\n        lrc_clear = [gr.skip()] * 8\n        lrc_clear[i] = gr.update(value=\"\", visible=True)\n\n        yield (\n            *cur_audio,\n            all_audio_paths, generation_info, f\"Encoding & Ready: {i + 1}/{len(audios)}\", seed_value_for_ui,\n            *scores_ui_updates, *cur_codes, *cur_accordions, *lrc_clear,\n            lm_generated_metadata, is_format_caption, None, None,\n        )\n        time_module.sleep(0.05)\n\n        # STEP 2: set actual LRC (triggers .change() for subtitles)\n        if final_lrcs_list[i]:\n            skip8 = [gr.skip()] * 8\n            lrc_set = [gr.skip()] * 8\n            lrc_set[i] = gr.update(value=final_lrcs_list[i], visible=True)\n            yield (\n                *skip8,\n                gr.skip(), gr.skip(), gr.skip(), gr.skip(),\n                *skip8, *skip8, *skip8, *lrc_set,\n                gr.skip(), gr.skip(), None, None,\n            )\n\n        time_module.sleep(0.05)\n\n    # Final timing\n    audio_conversion_time = time_module.time() - audio_conversion_start_time\n    if audio_conversion_time > 0:\n        time_costs['audio_conversion_time'] = audio_conversion_time\n    if total_auto_score_time > 0:\n        time_costs['auto_score_time'] = total_auto_score_time\n    if total_auto_lrc_time > 0:\n        time_costs['auto_lrc_time'] = total_auto_lrc_time\n    if 'pipeline_total_time' in time_costs:\n        time_costs['pipeline_total_time'] += audio_conversion_time + total_auto_score_time + total_auto_lrc_time\n\n    generation_info = _build_generation_info(\n        lm_metadata=lm_generated_metadata,\n        time_costs=time_costs,\n        seed_value=seed_value_for_ui,\n        inference_steps=inference_steps,\n        num_audios=len(result.audios),\n        audio_format=audio_format,\n    )\n\n    audio_playback_updates = []\n    for idx in range(8):\n        path = audio_outputs[idx]\n        if path:\n            audio_playback_updates.append(build_audio_slot_update(gr, path))\n            logger.info(f\"[generate_with_progress] Audio {idx + 1} path: {path}\")\n        else:\n            audio_playback_updates.append(build_audio_slot_update(gr, None))\n\n    final_codes_display = [gr.skip()] * 8\n    final_accordions = [gr.skip()] * 8\n\n    extra_to_store = {**result.extra_outputs, \"lrcs\": final_lrcs_list, \"subtitles\": final_subtitles_list}\n    for k, v in extra_to_store.items():\n        if isinstance(v, torch.Tensor) and v.is_cuda:\n            extra_to_store[k] = v.cpu()\n\n    yield (\n        *audio_playback_updates,\n        all_audio_paths, generation_info, \"Generation Complete\", seed_value_for_ui,\n        *final_scores_list, *final_codes_display, *final_accordions, *final_lrcs_list,\n        lm_generated_metadata, is_format_caption,\n        extra_to_store,\n        final_codes_list,\n    )\n\n\n# ---------------------------------------------------------------------------\n# Internal helpers\n# ---------------------------------------------------------------------------\n\ndef _extract_sample_tensor(extra_outputs, sample_idx):\n    \"\"\"Slice per-sample tensor data from *extra_outputs* for scoring.\n\n    Returns ``None`` when data is missing or incomplete.\n    \"\"\"\n    try:\n        full_pred = extra_outputs.get(\"pred_latents\")\n        if full_pred is None or sample_idx >= full_pred.shape[0]:\n            return None\n        data = {\n            \"pred_latent\": full_pred[sample_idx:sample_idx + 1],\n            \"encoder_hidden_states\": extra_outputs.get(\"encoder_hidden_states\")[sample_idx:sample_idx + 1]\n                if extra_outputs.get(\"encoder_hidden_states\") is not None else None,\n            \"encoder_attention_mask\": extra_outputs.get(\"encoder_attention_mask\")[sample_idx:sample_idx + 1]\n                if extra_outputs.get(\"encoder_attention_mask\") is not None else None,\n            \"context_latents\": extra_outputs.get(\"context_latents\")[sample_idx:sample_idx + 1]\n                if extra_outputs.get(\"context_latents\") is not None else None,\n            \"lyric_token_ids\": extra_outputs.get(\"lyric_token_idss\")[sample_idx:sample_idx + 1]\n                if extra_outputs.get(\"lyric_token_idss\") is not None else None,\n        }\n        if any(v is None for v in data.values()):\n            return None\n        return data\n    except Exception as e:\n        print(f\"[Auto Score] Failed to prepare tensor data for sample {sample_idx}: {e}\")\n        return None\n\n\ndef _run_auto_lrc(dit_handler, extra_outputs, sample_idx,\n                  audio_duration, vocal_language, inference_steps,\n                  final_lrcs_list, final_subtitles_list):\n    \"\"\"Run automatic LRC generation for a single sample in-place.\n\n    Updates *final_lrcs_list* and *final_subtitles_list* at *sample_idx*.\n    \"\"\"\n    logger.info(f\"[auto_lrc] Starting LRC generation for sample {sample_idx + 1}\")\n    try:\n        pred_latents = extra_outputs.get(\"pred_latents\")\n        enc_hs = extra_outputs.get(\"encoder_hidden_states\")\n        enc_am = extra_outputs.get(\"encoder_attention_mask\")\n        ctx_lat = extra_outputs.get(\"context_latents\")\n        lyric_ids = extra_outputs.get(\"lyric_token_idss\")\n\n        if not all(x is not None for x in [pred_latents, enc_hs, enc_am, ctx_lat, lyric_ids]):\n            logger.warning(f\"[auto_lrc] Missing required extra_outputs for sample {sample_idx + 1}\")\n            return\n\n        actual_duration = audio_duration\n        if actual_duration is None or actual_duration <= 0:\n            actual_duration = pred_latents.shape[1] / 25.0\n\n        lrc_result = dit_handler.get_lyric_timestamp(\n            pred_latent=pred_latents[sample_idx:sample_idx + 1],\n            encoder_hidden_states=enc_hs[sample_idx:sample_idx + 1],\n            encoder_attention_mask=enc_am[sample_idx:sample_idx + 1],\n            context_latents=ctx_lat[sample_idx:sample_idx + 1],\n            lyric_token_ids=lyric_ids[sample_idx:sample_idx + 1],\n            total_duration_seconds=float(actual_duration),\n            vocal_language=vocal_language or \"en\",\n            inference_steps=int(inference_steps),\n            seed=42,\n        )\n\n        if lrc_result.get(\"success\"):\n            lrc_text = lrc_result.get(\"lrc_text\", \"\")\n            final_lrcs_list[sample_idx] = lrc_text\n            logger.info(f\"[auto_lrc] LRC text length for sample {sample_idx + 1}: {len(lrc_text)}\")\n            vtt_path = lrc_to_vtt_file(lrc_text, total_duration=float(actual_duration))\n            final_subtitles_list[sample_idx] = vtt_path\n    except Exception as e:\n        logger.warning(f\"[auto_lrc] Failed to generate LRC for sample {sample_idx + 1}: {e}\")\n"
  },
  {
    "path": "acestep/ui/gradio/events/results/lrc_utils.py",
    "content": "\"\"\"LRC parsing, VTT conversion, subtitle updates, and LRC file I/O.\n\nHandles all LRC/VTT subtitle processing for the results UI including\nparsing, merging short lines, generating VTT files, and the on-demand\nLRC generation handler.\n\"\"\"\nimport os\nimport re\nimport datetime\nimport tempfile\nimport time as time_module\nfrom typing import Dict, Any, Optional, List\n\nimport gradio as gr\nfrom loguru import logger\n\nfrom acestep.ui.gradio.i18n import t\nfrom acestep.ui.gradio.events.results.generation_info import DEFAULT_RESULTS_DIR\n\n\ndef parse_lrc_to_subtitles(lrc_text: str, total_duration: Optional[float] = None) -> List[Dict[str, Any]]:\n    \"\"\"Parse LRC lyrics text to Gradio subtitles format with smart post-processing.\n\n    Merges lines that start very close to each other so they don't disappear\n    too quickly in the subtitle display.\n\n    Args:\n        lrc_text: LRC format lyrics string.\n        total_duration: Total audio duration in seconds.\n\n    Returns:\n        List of subtitle dictionaries with 'text' and 'timestamp' keys.\n    \"\"\"\n    if not lrc_text or not lrc_text.strip():\n        return []\n\n    timestamp_pattern = r'\\[(\\d{2}):(\\d{2})\\.(\\d{2,3})\\]'\n    raw_entries = []\n\n    for line in lrc_text.strip().split('\\n'):\n        line = line.strip()\n        if not line:\n            continue\n        timestamps = re.findall(timestamp_pattern, line)\n        if not timestamps:\n            continue\n        text = re.sub(timestamp_pattern, '', line).strip()\n        if not text:\n            continue\n\n        start_minutes, start_seconds, start_cs = timestamps[0]\n        cs = int(start_cs)\n        start_time = (\n            int(start_minutes) * 60 + int(start_seconds)\n            + (cs / 100.0 if len(start_cs) == 2 else cs / 1000.0)\n        )\n\n        end_time = None\n        if len(timestamps) >= 2:\n            end_min, end_sec, end_cs_str = timestamps[1]\n            cs_end = int(end_cs_str)\n            end_time = (\n                int(end_min) * 60 + int(end_sec)\n                + (cs_end / 100.0 if len(end_cs_str) == 2 else cs_end / 1000.0)\n            )\n\n        raw_entries.append({'start': start_time, 'explicit_end': end_time, 'text': text})\n\n    raw_entries.sort(key=lambda x: x['start'])\n    if not raw_entries:\n        return []\n\n    # Merge lines closer than MIN_DISPLAY_DURATION seconds\n    MIN_DISPLAY_DURATION = 2.0\n    merged_entries: list = []\n    i = 0\n    while i < len(raw_entries):\n        cur = raw_entries[i]\n        combined_text = cur['text']\n        combined_start = cur['start']\n        combined_explicit_end = cur['explicit_end']\n        next_idx = i + 1\n\n        while next_idx < len(raw_entries):\n            nxt = raw_entries[next_idx]\n            if nxt['start'] - combined_start < MIN_DISPLAY_DURATION:\n                combined_text += \"\\n\" + nxt['text']\n                if nxt['explicit_end']:\n                    combined_explicit_end = nxt['explicit_end']\n                next_idx += 1\n            else:\n                break\n\n        merged_entries.append({\n            'start': combined_start,\n            'explicit_end': combined_explicit_end,\n            'text': combined_text,\n        })\n        i = next_idx\n\n    # Build final subtitles list\n    subtitles = []\n    for idx, entry in enumerate(merged_entries):\n        start = entry['start']\n        if entry['explicit_end'] is not None:\n            end = entry['explicit_end']\n        elif idx + 1 < len(merged_entries):\n            end = merged_entries[idx + 1]['start']\n        elif total_duration is not None and total_duration > start:\n            end = total_duration\n        else:\n            end = start + 5.0\n        if end <= start:\n            end = start + 3.0\n        subtitles.append({'text': entry['text'], 'timestamp': [start, end]})\n\n    return subtitles\n\n\ndef _format_vtt_timestamp(seconds: float) -> str:\n    \"\"\"Format seconds to VTT timestamp ``HH:MM:SS.mmm``.\"\"\"\n    hours = int(seconds // 3600)\n    minutes = int((seconds % 3600) // 60)\n    secs = int(seconds % 60)\n    millis = int((seconds % 1) * 1000)\n    return f\"{hours:02d}:{minutes:02d}:{secs:02d}.{millis:03d}\"\n\n\ndef lrc_to_vtt_file(lrc_text: str, total_duration: float = None) -> Optional[str]:\n    \"\"\"Convert LRC text to a VTT subtitle file and return its path.\n\n    Args:\n        lrc_text: LRC format lyrics string.\n        total_duration: Total audio duration in seconds.\n\n    Returns:\n        Path to the generated VTT file, or ``None`` on failure.\n    \"\"\"\n    if not lrc_text or not lrc_text.strip():\n        return None\n    subtitles = parse_lrc_to_subtitles(lrc_text, total_duration=total_duration)\n    if not subtitles:\n        return None\n\n    vtt_lines = [\"WEBVTT\", \"\"]\n    for i, sub in enumerate(subtitles):\n        vtt_lines.append(str(i + 1))\n        vtt_lines.append(\n            f\"{_format_vtt_timestamp(sub['timestamp'][0])} --> {_format_vtt_timestamp(sub['timestamp'][1])}\"\n        )\n        vtt_lines.append(sub['text'])\n        vtt_lines.append(\"\")\n\n    try:\n        vtt_output_dir = os.path.join(DEFAULT_RESULTS_DIR, \"subtitles\")\n        os.makedirs(vtt_output_dir, exist_ok=True)\n        ts = int(time_module.time())\n        vtt_filename = f\"subtitles_{ts}_{datetime.datetime.now().strftime('%H%M%S')}.vtt\"\n        vtt_path = os.path.join(vtt_output_dir, vtt_filename).replace(\"\\\\\", \"/\")\n        with open(vtt_path, \"w\", encoding=\"utf-8\") as f:\n            f.write(\"\\n\".join(vtt_lines))\n        return vtt_path\n    except Exception as e:\n        logger.error(f\"[lrc_to_vtt_file] Failed to create VTT file: {e}\")\n        return None\n\n\ndef update_audio_subtitles_from_lrc(lrc_text: str, audio_duration: float = None):\n    \"\"\"Update Audio component subtitles from LRC text via a VTT file.\n\n    Args:\n        lrc_text: LRC format lyrics string.\n        audio_duration: Optional audio duration for last-line end time.\n\n    Returns:\n        ``gr.update`` with the subtitles path (or ``None`` to clear).\n    \"\"\"\n    if not lrc_text or not lrc_text.strip():\n        return gr.update(subtitles=None)\n    vtt_path = lrc_to_vtt_file(lrc_text, total_duration=audio_duration)\n    return gr.update(subtitles=vtt_path)\n\n\ndef save_lrc_to_file(lrc_text):\n    \"\"\"Save LRC text to a downloadable ``.lrc`` file.\n\n    Args:\n        lrc_text: The LRC text content to save.\n\n    Returns:\n        ``gr.update`` for the File component with the ``.lrc`` file path.\n    \"\"\"\n    if not lrc_text or not lrc_text.strip():\n        gr.Warning(\"No LRC content to save.\")\n        return gr.skip()\n    try:\n        tmp_dir = tempfile.mkdtemp()\n        lrc_path = os.path.join(tmp_dir, \"lyrics.lrc\")\n        with open(lrc_path, \"w\", encoding=\"utf-8\") as f:\n            f.write(lrc_text)\n        gr.Info(\"LRC file ready for download.\")\n        return gr.update(value=lrc_path, visible=True)\n    except Exception as e:\n        gr.Warning(f\"Error saving LRC file: {e}\")\n        return gr.skip()\n\n\ndef generate_lrc_handler(dit_handler, sample_idx, current_batch_index, batch_queue, vocal_language, inference_steps):\n    \"\"\"Generate LRC timestamps for a specific audio sample.\n\n    Retrieves cached generation data from *batch_queue* and calls the\n    handler's ``get_lyric_timestamp`` method.  Only updates ``lrc_display``;\n    audio subtitles are refreshed via a separate ``.change()`` event.\n\n    Args:\n        dit_handler: DiT handler instance.\n        sample_idx: 1-based sample index (1-8).\n        current_batch_index: Current batch index in *batch_queue*.\n        batch_queue: Dictionary storing all batch generation data.\n        vocal_language: Language code for lyrics.\n        inference_steps: Number of inference steps used.\n\n    Returns:\n        Tuple of ``(lrc_display_update, details_accordion_update, batch_queue)``.\n    \"\"\"\n    import torch  # noqa: F401 – kept for tensor slicing\n\n    if current_batch_index not in batch_queue:\n        return gr.skip(), gr.skip(), batch_queue\n\n    batch_data = batch_queue[current_batch_index]\n    extra_outputs = batch_data.get(\"extra_outputs\", {})\n\n    if not extra_outputs:\n        return gr.update(value=t(\"messages.lrc_no_extra_outputs\"), visible=True), gr.skip(), batch_queue\n\n    pred_latents = extra_outputs.get(\"pred_latents\")\n    encoder_hidden_states = extra_outputs.get(\"encoder_hidden_states\")\n    encoder_attention_mask = extra_outputs.get(\"encoder_attention_mask\")\n    context_latents = extra_outputs.get(\"context_latents\")\n    lyric_token_idss = extra_outputs.get(\"lyric_token_idss\")\n\n    if any(x is None for x in [pred_latents, encoder_hidden_states, encoder_attention_mask, context_latents, lyric_token_idss]):\n        return gr.update(value=t(\"messages.lrc_missing_tensors\"), visible=True), gr.skip(), batch_queue\n\n    idx0 = sample_idx - 1\n    if idx0 >= pred_latents.shape[0]:\n        return gr.update(value=t(\"messages.lrc_sample_not_exist\"), visible=True), gr.skip(), batch_queue\n\n    try:\n        params = batch_data.get(\"generation_params\", {})\n        audio_duration = params.get(\"audio_duration\", -1)\n        if audio_duration is None or audio_duration <= 0:\n            audio_duration = pred_latents.shape[1] / 25.0\n\n        result = dit_handler.get_lyric_timestamp(\n            pred_latent=pred_latents[idx0:idx0 + 1],\n            encoder_hidden_states=encoder_hidden_states[idx0:idx0 + 1],\n            encoder_attention_mask=encoder_attention_mask[idx0:idx0 + 1],\n            context_latents=context_latents[idx0:idx0 + 1],\n            lyric_token_ids=lyric_token_idss[idx0:idx0 + 1],\n            total_duration_seconds=float(audio_duration),\n            vocal_language=vocal_language or \"en\",\n            inference_steps=int(inference_steps),\n            seed=42,\n        )\n\n        if result.get(\"success\"):\n            lrc_text = result.get(\"lrc_text\", \"\")\n            if not lrc_text:\n                return gr.update(value=t(\"messages.lrc_empty_result\"), visible=True), gr.skip(), batch_queue\n\n            if \"lrcs\" not in batch_queue[current_batch_index]:\n                batch_queue[current_batch_index][\"lrcs\"] = [\"\"] * 8\n            batch_queue[current_batch_index][\"lrcs\"][idx0] = lrc_text\n\n            vtt_path = lrc_to_vtt_file(lrc_text, total_duration=float(audio_duration))\n            if \"subtitles\" not in batch_queue[current_batch_index]:\n                batch_queue[current_batch_index][\"subtitles\"] = [None] * 8\n            batch_queue[current_batch_index][\"subtitles\"][idx0] = vtt_path\n\n            return gr.update(value=lrc_text, visible=True), gr.skip(), batch_queue\n        else:\n            error_msg = result.get(\"error\", \"Unknown error\")\n            return gr.update(value=f\"❌ {error_msg}\", visible=True), gr.skip(), batch_queue\n\n    except Exception as e:\n        logger.exception(\"[generate_lrc_handler] Error generating LRC\")\n        return gr.update(value=f\"❌ Error: {str(e)}\", visible=True), gr.skip(), batch_queue\n"
  },
  {
    "path": "acestep/ui/gradio/events/results/lrc_utils_test.py",
    "content": "\"\"\"Unit tests for lrc_utils module.\"\"\"\n\nimport unittest\n\nfrom acestep.ui.gradio.events.results.lrc_utils import (\n    parse_lrc_to_subtitles,\n    _format_vtt_timestamp,\n    save_lrc_to_file,\n)\n\n\nclass ParseLrcToSubtitlesTests(unittest.TestCase):\n    \"\"\"Tests for parse_lrc_to_subtitles.\"\"\"\n\n    def test_empty_input_returns_empty_list(self):\n        \"\"\"Empty or None input should return an empty list.\"\"\"\n        self.assertEqual(parse_lrc_to_subtitles(\"\"), [])\n        self.assertEqual(parse_lrc_to_subtitles(None), [])\n        self.assertEqual(parse_lrc_to_subtitles(\"   \"), [])\n\n    def test_single_line(self):\n        \"\"\"A single LRC line should produce one subtitle entry.\"\"\"\n        lrc = \"[00:05.00]Hello world\"\n        result = parse_lrc_to_subtitles(lrc, total_duration=30.0)\n        self.assertGreaterEqual(len(result), 1)\n        self.assertEqual(result[0][\"text\"], \"Hello world\")\n        # Start time is in timestamp[0]\n        self.assertAlmostEqual(result[0][\"timestamp\"][0], 5.0, places=1)\n\n    def test_multiple_lines(self):\n        \"\"\"Multiple LRC lines should produce multiple subtitle entries.\"\"\"\n        lrc = \"[00:05.00]Line one\\n[00:10.00]Line two\\n[00:15.00]Line three\"\n        result = parse_lrc_to_subtitles(lrc, total_duration=30.0)\n        self.assertEqual(len(result), 3)\n        texts = [s[\"text\"] for s in result]\n        self.assertIn(\"Line one\", texts)\n        self.assertIn(\"Line two\", texts)\n        self.assertIn(\"Line three\", texts)\n\n    def test_lines_without_timestamps_are_ignored(self):\n        \"\"\"Lines without LRC timestamps should be skipped.\"\"\"\n        lrc = \"No timestamp here\\n[00:05.00]Valid line\"\n        result = parse_lrc_to_subtitles(lrc, total_duration=30.0)\n        self.assertEqual(len(result), 1)\n        self.assertEqual(result[0][\"text\"], \"Valid line\")\n\n    def test_empty_text_lines_are_ignored(self):\n        \"\"\"Lines with timestamps but no text should be skipped.\"\"\"\n        lrc = \"[00:05.00]\\n[00:10.00]Has text\"\n        result = parse_lrc_to_subtitles(lrc, total_duration=30.0)\n        self.assertEqual(len(result), 1)\n        self.assertEqual(result[0][\"text\"], \"Has text\")\n\n    def test_three_digit_centiseconds(self):\n        \"\"\"LRC with 3-digit milliseconds should be parsed correctly.\"\"\"\n        lrc = \"[01:23.456]Three digit\"\n        result = parse_lrc_to_subtitles(lrc, total_duration=120.0)\n        self.assertEqual(len(result), 1)\n        expected_time = 1 * 60 + 23 + 0.456\n        self.assertAlmostEqual(result[0][\"timestamp\"][0], expected_time, places=2)\n\n    def test_two_digit_centiseconds(self):\n        \"\"\"LRC with 2-digit centiseconds should be parsed correctly.\"\"\"\n        lrc = \"[00:30.50]Two digit\"\n        result = parse_lrc_to_subtitles(lrc, total_duration=60.0)\n        self.assertEqual(len(result), 1)\n        expected_time = 30.5\n        self.assertAlmostEqual(result[0][\"timestamp\"][0], expected_time, places=2)\n\n    def test_subtitle_has_timestamp_pair(self):\n        \"\"\"Each subtitle entry should have a [start, end] timestamp pair.\"\"\"\n        lrc = \"[00:05.00]Line one\\n[00:10.00]Line two\"\n        result = parse_lrc_to_subtitles(lrc, total_duration=30.0)\n        for entry in result:\n            self.assertIn(\"timestamp\", entry)\n            self.assertEqual(len(entry[\"timestamp\"]), 2)\n            self.assertLess(entry[\"timestamp\"][0], entry[\"timestamp\"][1])\n\n\nclass FormatVttTimestampTests(unittest.TestCase):\n    \"\"\"Tests for _format_vtt_timestamp.\"\"\"\n\n    def test_zero_seconds(self):\n        \"\"\"0 seconds should format as 00:00:00.000.\"\"\"\n        self.assertEqual(_format_vtt_timestamp(0), \"00:00:00.000\")\n\n    def test_simple_seconds(self):\n        \"\"\"Simple seconds value should format correctly.\"\"\"\n        result = _format_vtt_timestamp(65.5)\n        self.assertEqual(result, \"00:01:05.500\")\n\n    def test_hours(self):\n        \"\"\"Values over 3600 should include hours.\"\"\"\n        result = _format_vtt_timestamp(3661.123)\n        self.assertEqual(result, \"01:01:01.123\")\n\n\nclass SaveLrcToFileTests(unittest.TestCase):\n    \"\"\"Tests for save_lrc_to_file.\"\"\"\n\n    def test_empty_lrc_returns_skip(self):\n        \"\"\"Empty LRC text should return a gr.skip() dict.\"\"\"\n        result = save_lrc_to_file(\"\")\n        self.assertIsInstance(result, dict)\n\n    def test_none_lrc_returns_skip(self):\n        \"\"\"None LRC text should return a gr.skip() dict.\"\"\"\n        result = save_lrc_to_file(None)\n        self.assertIsInstance(result, dict)\n\n    def test_valid_lrc_returns_update_dict(self):\n        \"\"\"Valid LRC text should return a gr.update dict with a file path.\"\"\"\n        lrc_text = \"[00:05.00]Hello world\\n[00:10.00]Goodbye\"\n        result = save_lrc_to_file(lrc_text)\n        self.assertIsInstance(result, dict)\n        # gr.update returns a dict with __type__ == 'update'\n        self.assertEqual(result.get(\"__type__\"), \"update\")\n        # Should have a value pointing to a .lrc file\n        self.assertIn(\"value\", result)\n        self.assertTrue(result[\"value\"].endswith(\".lrc\"))\n\n\nif __name__ == \"__main__\":\n    unittest.main()\n"
  },
  {
    "path": "acestep/ui/gradio/events/results/scoring.py",
    "content": "\"\"\"PMI-based quality scoring and per-sample score selection.\n\nProvides handlers for computing PMI quality scores and DiT alignment\nscores on generated audio samples.\n\"\"\"\nimport traceback\n\nimport gradio as gr\n\nfrom acestep.ui.gradio.i18n import t\n\n\ndef calculate_score_handler(\n    llm_handler,\n    audio_codes_str,\n    caption,\n    lyrics,\n    lm_metadata,\n    bpm,\n    key_scale,\n    time_signature,\n    audio_duration,\n    vocal_language,\n    score_scale,\n    dit_handler,\n    extra_tensor_data,\n    inference_steps,\n):\n    \"\"\"Calculate PMI-based quality score for generated audio.\n\n    PMI (Pointwise Mutual Information) removes condition bias:\n    ``score = log P(condition|codes) - log P(condition)``\n\n    Falls back to DiT alignment scoring when audio codes are unavailable\n    (e.g. Cover/Repaint modes).\n\n    Args:\n        llm_handler: LLM handler instance.\n        audio_codes_str: Generated audio codes string.\n        caption: Caption text used for generation.\n        lyrics: Lyrics text used for generation.\n        lm_metadata: LM-generated metadata dictionary.\n        bpm: BPM value.\n        key_scale: Key scale value.\n        time_signature: Time signature value.\n        audio_duration: Audio duration value.\n        vocal_language: Vocal language value.\n        score_scale: Sensitivity scale parameter.\n        dit_handler: DiT handler instance (for alignment scoring).\n        extra_tensor_data: Dictionary containing tensors for the specific sample.\n        inference_steps: Number of inference steps used.\n\n    Returns:\n        Score display string.\n    \"\"\"\n    from acestep.core.scoring.lm_score import calculate_pmi_score_per_condition\n\n    has_audio_codes = audio_codes_str and audio_codes_str.strip()\n    has_dit_alignment_data = dit_handler and extra_tensor_data and lyrics and lyrics.strip()\n\n    if not has_audio_codes and not has_dit_alignment_data:\n        return t(\"messages.no_codes\")\n\n    try:\n        scores_per_condition = {}\n        global_score = 0.0\n        alignment_report = \"\"\n\n        # PMI-based scoring (requires audio codes and LLM)\n        if has_audio_codes:\n            if not llm_handler.llm_initialized:\n                if not has_dit_alignment_data:\n                    return t(\"messages.lm_not_initialized\")\n            else:\n                metadata = {}\n                if lm_metadata and isinstance(lm_metadata, dict):\n                    metadata.update(lm_metadata)\n                if bpm is not None and 'bpm' not in metadata:\n                    try:\n                        metadata['bpm'] = int(bpm)\n                    except Exception:\n                        pass\n                if caption and 'caption' not in metadata:\n                    metadata['caption'] = caption\n                if audio_duration is not None and audio_duration > 0 and 'duration' not in metadata:\n                    try:\n                        metadata['duration'] = int(audio_duration)\n                    except Exception:\n                        pass\n                if key_scale and key_scale.strip() and 'keyscale' not in metadata:\n                    metadata['keyscale'] = key_scale.strip()\n                if vocal_language and vocal_language.strip() and 'language' not in metadata:\n                    metadata['language'] = vocal_language.strip()\n                if time_signature and time_signature.strip() and 'timesignature' not in metadata:\n                    metadata['timesignature'] = time_signature.strip()\n\n                scores_per_condition, global_score, _status = calculate_pmi_score_per_condition(\n                    llm_handler=llm_handler,\n                    audio_codes=audio_codes_str,\n                    caption=caption or \"\",\n                    lyrics=lyrics or \"\",\n                    metadata=metadata if metadata else None,\n                    temperature=1.0,\n                    topk=10,\n                    score_scale=score_scale,\n                )\n\n        # DiT alignment scoring\n        if has_dit_alignment_data:\n            try:\n                align_result = dit_handler.get_lyric_score(\n                    pred_latent=extra_tensor_data.get('pred_latent'),\n                    encoder_hidden_states=extra_tensor_data.get('encoder_hidden_states'),\n                    encoder_attention_mask=extra_tensor_data.get('encoder_attention_mask'),\n                    context_latents=extra_tensor_data.get('context_latents'),\n                    lyric_token_ids=extra_tensor_data.get('lyric_token_ids'),\n                    vocal_language=vocal_language or \"en\",\n                    inference_steps=int(inference_steps),\n                    seed=42,\n                )\n                if align_result.get(\"success\"):\n                    lm_align = align_result.get(\"lm_score\", 0.0)\n                    dit_align = align_result.get(\"dit_score\", 0.0)\n                    alignment_report = (\n                        f\"  • llm lyrics alignment score: {lm_align:.4f}\\n\"\n                        f\"  • dit lyrics alignment score: {dit_align:.4f}\\n\"\n                        \"\\n(Measures how well lyrics timestamps match audio energy using Cross-Attention)\"\n                    )\n                else:\n                    alignment_report = f\"\\n⚠️ Alignment Score Failed: {align_result.get('error', 'Unknown error')}\"\n            except Exception as e:\n                alignment_report = f\"\\n⚠️ Alignment Score Error: {str(e)}\"\n\n        # Format display string\n        if has_audio_codes and llm_handler.llm_initialized:\n            if global_score == 0.0 and not scores_per_condition:\n                if alignment_report and not alignment_report.startswith(\"\\n⚠️\"):\n                    return \"📊 DiT Alignment Scores (LM codes not available):\\n\" + alignment_report\n                return t(\"messages.score_failed\", error=\"PMI scoring returned no results\")\n\n            condition_lines = [\n                f\"  • {name}: {val:.4f}\"\n                for name, val in sorted(scores_per_condition.items())\n            ]\n            conditions_display = \"\\n\".join(condition_lines) if condition_lines else \"  (no conditions)\"\n            final_output = (\n                f\"✅ Global Quality Score: {global_score:.4f} (0-1, higher=better)\\n\\n\"\n                f\"📊 Per-Condition Scores (0-1):\\n{conditions_display}\\n\"\n            )\n            if alignment_report:\n                final_output += alignment_report + \"\\n\"\n            final_output += \"Note: Metadata uses Top-k Recall, Caption/Lyrics use PMI\"\n            return final_output\n        else:\n            if alignment_report and not alignment_report.startswith(\"\\n⚠️\"):\n                return \"📊 DiT Alignment Scores (LM codes not available for Cover/Repaint mode):\\n\" + alignment_report\n            elif alignment_report:\n                return alignment_report\n            return \"⚠️ No scoring data available\"\n\n    except Exception as e:\n        return t(\"messages.score_error\", error=str(e)) + f\"\\n{traceback.format_exc()}\"\n\n\ndef calculate_score_handler_with_selection(\n    dit_handler,\n    llm_handler,\n    sample_idx,\n    score_scale,\n    current_batch_index,\n    batch_queue,\n):\n    \"\"\"Calculate quality score for a specific sample from batch queue data.\n\n    Reads all parameters from the historical batch rather than current UI\n    values, ensuring scores reflect the actual generation settings.\n\n    Args:\n        dit_handler: DiT handler instance.\n        llm_handler: LLM handler instance.\n        sample_idx: 1-based sample index (1-8).\n        score_scale: Sensitivity scale parameter.\n        current_batch_index: Current batch index.\n        batch_queue: Batch queue dict.\n\n    Returns:\n        Tuple of ``(score_display_update, accordion_update, batch_queue)``.\n    \"\"\"\n    if current_batch_index not in batch_queue:\n        return gr.skip(), gr.skip(), batch_queue\n\n    batch_data = batch_queue[current_batch_index]\n    params = batch_data.get(\"generation_params\", {})\n\n    caption = params.get(\"captions\", \"\")\n    lyrics = params.get(\"lyrics\", \"\")\n    bpm = params.get(\"bpm\")\n    key_scale = params.get(\"key_scale\", \"\")\n    time_signature = params.get(\"time_signature\", \"\")\n    audio_duration = params.get(\"audio_duration\", -1)\n    vocal_language = params.get(\"vocal_language\", \"\")\n    inference_steps = params.get(\"inference_steps\", 8)\n    lm_metadata = batch_data.get(\"lm_generated_metadata\", None)\n\n    stored_codes = batch_data.get(\"codes\", \"\")\n    stored_allow_lm_batch = batch_data.get(\"allow_lm_batch\", False)\n\n    audio_codes_str = \"\"\n    if stored_allow_lm_batch and isinstance(stored_codes, list):\n        if 0 <= sample_idx - 1 < len(stored_codes):\n            code_item = stored_codes[sample_idx - 1]\n            audio_codes_str = code_item if isinstance(code_item, str) else \"\"\n    else:\n        audio_codes_str = stored_codes if isinstance(stored_codes, str) else \"\"\n\n    # Extract tensor data for alignment scoring\n    extra_tensor_data = None\n    extra_outputs = batch_data.get(\"extra_outputs\", {})\n    if extra_outputs and dit_handler:\n        pred_latents = extra_outputs.get(\"pred_latents\")\n        if pred_latents is not None:\n            idx0 = sample_idx - 1\n            if 0 <= idx0 < pred_latents.shape[0]:\n                try:\n                    extra_tensor_data = {\n                        \"pred_latent\": pred_latents[idx0:idx0 + 1],\n                        \"encoder_hidden_states\": extra_outputs.get(\"encoder_hidden_states\")[idx0:idx0 + 1],\n                        \"encoder_attention_mask\": extra_outputs.get(\"encoder_attention_mask\")[idx0:idx0 + 1],\n                        \"context_latents\": extra_outputs.get(\"context_latents\")[idx0:idx0 + 1],\n                        \"lyric_token_ids\": extra_outputs.get(\"lyric_token_idss\")[idx0:idx0 + 1],\n                    }\n                    if any(v is None for v in extra_tensor_data.values()):\n                        extra_tensor_data = None\n                except Exception as e:\n                    print(f\"Error slicing tensor data for score: {e}\")\n                    extra_tensor_data = None\n\n    score_display = calculate_score_handler(\n        llm_handler, audio_codes_str, caption, lyrics, lm_metadata,\n        bpm, key_scale, time_signature, audio_duration, vocal_language,\n        score_scale, dit_handler, extra_tensor_data, inference_steps,\n    )\n\n    if current_batch_index in batch_queue:\n        if \"scores\" not in batch_queue[current_batch_index]:\n            batch_queue[current_batch_index][\"scores\"] = [\"\"] * 8\n        batch_queue[current_batch_index][\"scores\"][sample_idx - 1] = score_display\n\n    return (\n        gr.update(value=score_display, visible=True),\n        gr.skip(),\n        batch_queue,\n    )\n"
  },
  {
    "path": "acestep/ui/gradio/events/results_handlers.py",
    "content": "\"\"\"\nResults Handlers Facade\n\nThin re-export layer that preserves the original ``results_handlers`` public\ninterface while delegating to focused sub-modules under ``results/``.\n\nAll symbols that were previously importable from this module are still\navailable here so that existing callers (e.g. ``events/__init__.py``,\n``api_server.py``) continue to work without changes.\n\"\"\"\n\n# --- constants ----------------------------------------------------------\nfrom acestep.ui.gradio.events.results.generation_info import (\n    DEFAULT_RESULTS_DIR,\n    PROJECT_ROOT,\n)\n\n# --- generation info & audio clearing -----------------------------------\nfrom acestep.ui.gradio.events.results.generation_info import (\n    clear_audio_outputs_for_new_generation,\n    _build_generation_info,\n)\n\n# --- LRC / VTT utilities -----------------------------------------------\nfrom acestep.ui.gradio.events.results.lrc_utils import (\n    parse_lrc_to_subtitles,\n    _format_vtt_timestamp,\n    lrc_to_vtt_file,\n    update_audio_subtitles_from_lrc,\n    save_lrc_to_file,\n    generate_lrc_handler,\n)\n\n# --- batch queue management ---------------------------------------------\nfrom acestep.ui.gradio.events.results.batch_queue import (\n    store_batch_in_queue,\n    update_batch_indicator,\n    update_navigation_buttons,\n    capture_current_params,\n    restore_batch_parameters,\n)\n\n# --- scoring ------------------------------------------------------------\nfrom acestep.ui.gradio.events.results.scoring import (\n    calculate_score_handler,\n    calculate_score_handler_with_selection,\n)\n\n# --- audio transfer (remix / repaint / codes) ---------------------------\nfrom acestep.ui.gradio.events.results.audio_transfer import (\n    send_audio_to_src_with_metadata,\n    _extract_metadata_for_editing,\n    send_audio_to_remix,\n    send_audio_to_repaint,\n    convert_result_audio_to_codes,\n)\n\n# --- generation progress ------------------------------------------------\nfrom acestep.ui.gradio.events.results.generation_progress import (\n    generate_with_progress,\n)\n\n# --- batch management & AutoGen -----------------------------------------\nfrom acestep.ui.gradio.events.results.batch_management import (\n    generate_with_batch_management,\n    generate_next_batch_background,\n)\n\n# --- batch navigation ---------------------------------------------------\nfrom acestep.ui.gradio.events.results.batch_navigation import (\n    navigate_to_previous_batch,\n    navigate_to_next_batch,\n)\n\n__all__ = [\n    # constants\n    \"DEFAULT_RESULTS_DIR\",\n    \"PROJECT_ROOT\",\n    # generation info\n    \"clear_audio_outputs_for_new_generation\",\n    \"_build_generation_info\",\n    # LRC / VTT\n    \"parse_lrc_to_subtitles\",\n    \"_format_vtt_timestamp\",\n    \"lrc_to_vtt_file\",\n    \"update_audio_subtitles_from_lrc\",\n    \"save_lrc_to_file\",\n    \"generate_lrc_handler\",\n    # batch queue\n    \"store_batch_in_queue\",\n    \"update_batch_indicator\",\n    \"update_navigation_buttons\",\n    \"capture_current_params\",\n    \"restore_batch_parameters\",\n    # scoring\n    \"calculate_score_handler\",\n    \"calculate_score_handler_with_selection\",\n    # audio transfer\n    \"send_audio_to_src_with_metadata\",\n    \"_extract_metadata_for_editing\",\n    \"send_audio_to_remix\",\n    \"send_audio_to_repaint\",\n    \"convert_result_audio_to_codes\",\n    # generation\n    \"generate_with_progress\",\n    \"generate_with_batch_management\",\n    \"generate_next_batch_background\",\n    # navigation\n    \"navigate_to_previous_batch\",\n    \"navigate_to_next_batch\",\n]\n"
  },
  {
    "path": "acestep/ui/gradio/events/results_handlers_facade_test.py",
    "content": "\"\"\"Unit tests for the results_handlers facade module.\n\nVerifies that the thin re-export layer exposes every public symbol that\ncallers (e.g. ``events/__init__.py``, ``api_server.py``) depend on.\n\"\"\"\n\nimport unittest\n\nfrom acestep.ui.gradio.events import results_handlers as rh\n\n\nclass FacadeReExportTests(unittest.TestCase):\n    \"\"\"Ensure the facade re-exports all required public symbols.\"\"\"\n\n    _EXPECTED_SYMBOLS = [\n        # constants\n        \"DEFAULT_RESULTS_DIR\",\n        \"PROJECT_ROOT\",\n        # generation info\n        \"clear_audio_outputs_for_new_generation\",\n        \"_build_generation_info\",\n        # LRC / VTT\n        \"parse_lrc_to_subtitles\",\n        \"_format_vtt_timestamp\",\n        \"lrc_to_vtt_file\",\n        \"update_audio_subtitles_from_lrc\",\n        \"save_lrc_to_file\",\n        \"generate_lrc_handler\",\n        # batch queue\n        \"store_batch_in_queue\",\n        \"update_batch_indicator\",\n        \"update_navigation_buttons\",\n        \"capture_current_params\",\n        \"restore_batch_parameters\",\n        # scoring\n        \"calculate_score_handler\",\n        \"calculate_score_handler_with_selection\",\n        # audio transfer\n        \"send_audio_to_src_with_metadata\",\n        \"_extract_metadata_for_editing\",\n        \"send_audio_to_remix\",\n        \"send_audio_to_repaint\",\n        \"convert_result_audio_to_codes\",\n        # generation\n        \"generate_with_progress\",\n        \"generate_with_batch_management\",\n        \"generate_next_batch_background\",\n        # navigation\n        \"navigate_to_previous_batch\",\n        \"navigate_to_next_batch\",\n    ]\n\n    def test_all_expected_symbols_are_importable(self):\n        \"\"\"Every symbol that callers depend on must be importable from the facade.\"\"\"\n        missing = [s for s in self._EXPECTED_SYMBOLS if not hasattr(rh, s)]\n        self.assertEqual(\n            missing,\n            [],\n            f\"Missing symbols in results_handlers facade: {missing}\",\n        )\n\n    def test_symbols_are_callable_or_constant(self):\n        \"\"\"Each symbol should be either callable (function) or a constant (str/int).\"\"\"\n        for name in self._EXPECTED_SYMBOLS:\n            obj = getattr(rh, name)\n            self.assertTrue(\n                callable(obj) or isinstance(obj, (str, int, float)),\n                f\"{name} is neither callable nor a constant: {type(obj)}\",\n            )\n\n\nif __name__ == \"__main__\":\n    unittest.main()\n"
  },
  {
    "path": "acestep/ui/gradio/events/training/__init__.py",
    "content": "\"\"\"Training event handlers sub-package.\n\nRe-exports all public symbols from the training sub-modules so that\ncallers can import directly from ``acestep.ui.gradio.events.training``.\n\"\"\"\n\nfrom .training_utils import (  # noqa: F401\n    SAFE_TRAINING_ROOT,\n    create_dataset_builder,\n    _safe_slider,\n    _safe_join,\n    _format_duration,\n    _training_loss_figure,\n)\nfrom .dataset_ops import (  # noqa: F401\n    scan_directory,\n    auto_label_all,\n    get_sample_preview,\n    save_sample_edit,\n    update_settings,\n    save_dataset,\n)\nfrom .preprocess import (  # noqa: F401\n    load_existing_dataset_for_preprocess,\n    preprocess_dataset,\n    load_training_dataset,\n)\nfrom .lora_training import (  # noqa: F401\n    start_training,\n    stop_training,\n    export_lora,\n)\nfrom .lokr_training import (  # noqa: F401\n    start_lokr_training,\n    list_lokr_export_epochs,\n    export_lokr,\n)\n"
  },
  {
    "path": "acestep/ui/gradio/events/training/dataset_ops.py",
    "content": "\"\"\"Dataset operations for the training UI.\n\nContains handlers for scanning directories, auto-labeling samples,\npreviewing/editing individual samples, updating settings, and saving\ndatasets to JSON.\n\"\"\"\n\nfrom typing import Any, List, Optional, Tuple\n\nimport gradio as gr\n\nfrom acestep.training.dataset_builder import DatasetBuilder\nfrom .training_utils import _safe_slider\n\n\ndef scan_directory(\n    audio_dir: str,\n    dataset_name: str,\n    custom_tag: str,\n    tag_position: str,\n    all_instrumental: bool,\n    builder_state: Optional[DatasetBuilder],\n) -> Tuple[Any, str, Any, DatasetBuilder]:\n    \"\"\"Scan a directory for audio files.\n\n    Returns:\n        Tuple of (table_data, status, slider_update, builder_state).\n    \"\"\"\n    if not audio_dir or not audio_dir.strip():\n        return [], \"❌ Please enter a directory path\", _safe_slider(0, value=0, visible=False), builder_state\n\n    builder = builder_state if builder_state else DatasetBuilder()\n\n    builder.metadata.name = dataset_name\n    builder.metadata.custom_tag = custom_tag\n    builder.metadata.tag_position = tag_position\n    builder.metadata.all_instrumental = all_instrumental\n\n    samples, status = builder.scan_directory(audio_dir.strip())\n\n    if not samples:\n        return [], status, _safe_slider(0, value=0, visible=False), builder\n\n    builder.set_all_instrumental(all_instrumental)\n    if custom_tag:\n        builder.set_custom_tag(custom_tag, tag_position)\n\n    table_data = builder.get_samples_dataframe_data()\n    slider_max = max(0, len(samples) - 1)\n\n    return table_data, status, _safe_slider(slider_max, value=0, visible=len(samples) > 1), builder\n\n\ndef auto_label_all(\n    dit_handler,\n    llm_handler,\n    builder_state: Optional[DatasetBuilder],\n    skip_metas: bool = False,\n    format_lyrics: bool = False,\n    transcribe_lyrics: bool = False,\n    only_unlabeled: bool = False,\n    progress=None,\n) -> Tuple[List[List[Any]], str, DatasetBuilder]:\n    \"\"\"Auto-label all samples in the dataset.\n\n    Args:\n        dit_handler: DiT handler for audio processing.\n        llm_handler: LLM handler for caption generation.\n        builder_state: Dataset builder state.\n        skip_metas: Skip generating BPM/Key/TimeSig but still generate caption/genre.\n        format_lyrics: Use LLM to format user-provided lyrics from .txt files.\n        transcribe_lyrics: Use LLM to transcribe lyrics from audio.\n        only_unlabeled: Only label samples without caption.\n        progress: Progress callback.\n\n    Returns:\n        Tuple of (table_data, status, builder_state).\n    \"\"\"\n    if builder_state is None:\n        return [], \"❌ Please scan a directory first\", builder_state\n\n    if not builder_state.samples:\n        return [], \"❌ No samples to label. Please scan a directory first.\", builder_state\n\n    if dit_handler is None or dit_handler.model is None:\n        return (\n            builder_state.get_samples_dataframe_data(),\n            \"❌ Model not initialized. Please initialize the service first.\",\n            builder_state,\n        )\n\n    if llm_handler is None or not llm_handler.llm_initialized:\n        return (\n            builder_state.get_samples_dataframe_data(),\n            \"❌ LLM not initialized. Please initialize the service with LLM enabled.\",\n            builder_state,\n        )\n\n    def progress_callback(msg):\n        if progress:\n            try:\n                progress(msg)\n            except Exception:\n                pass\n\n    samples, status = builder_state.label_all_samples(\n        dit_handler=dit_handler,\n        llm_handler=llm_handler,\n        format_lyrics=format_lyrics,\n        transcribe_lyrics=transcribe_lyrics,\n        skip_metas=skip_metas,\n        only_unlabeled=only_unlabeled,\n        progress_callback=progress_callback,\n    )\n\n    table_data = builder_state.get_samples_dataframe_data()\n    return gr.update(value=table_data), gr.update(value=status), builder_state\n\n\ndef get_sample_preview(\n    sample_idx: int,\n    builder_state: Optional[DatasetBuilder],\n):\n    \"\"\"Get preview data for a specific sample.\n\n    Returns:\n        Tuple of (audio_path, filename, caption, genre, prompt_override, lyrics,\n                  bpm, keyscale, timesig, duration, language, instrumental,\n                  raw_lyrics, raw_lyrics_visible).\n    \"\"\"\n    empty = (None, \"\", \"\", \"\", \"Use Global Ratio\", \"\", None, \"\", \"\", 0.0, \"instrumental\", True, \"\", False)\n\n    if builder_state is None or not builder_state.samples:\n        return empty\n\n    if sample_idx is None:\n        return empty\n\n    idx = int(sample_idx)\n    if idx < 0 or idx >= len(builder_state.samples):\n        return empty\n\n    sample = builder_state.samples[idx]\n    has_raw = sample.has_raw_lyrics()\n\n    if sample.prompt_override == \"genre\":\n        override_choice = \"Genre\"\n    elif sample.prompt_override == \"caption\":\n        override_choice = \"Caption\"\n    else:\n        override_choice = \"Use Global Ratio\"\n\n    display_lyrics = sample.lyrics if sample.lyrics else sample.formatted_lyrics\n\n    return (\n        sample.audio_path,\n        sample.filename,\n        sample.caption,\n        sample.genre,\n        override_choice,\n        display_lyrics,\n        sample.bpm,\n        sample.keyscale,\n        sample.timesignature,\n        sample.duration,\n        sample.language,\n        sample.is_instrumental,\n        sample.raw_lyrics if has_raw else \"\",\n        has_raw,\n    )\n\n\ndef save_sample_edit(\n    sample_idx: int,\n    caption: str,\n    genre: str,\n    prompt_override: str,\n    lyrics: str,\n    bpm: Optional[int],\n    keyscale: str,\n    timesig: str,\n    language: str,\n    is_instrumental: bool,\n    builder_state: Optional[DatasetBuilder],\n) -> Tuple[List[List[Any]], str, DatasetBuilder]:\n    \"\"\"Save edits to a sample.\n\n    Returns:\n        Tuple of (table_data, status, builder_state).\n    \"\"\"\n    if builder_state is None:\n        return [], \"❌ No dataset loaded\", builder_state\n\n    idx = int(sample_idx)\n\n    if prompt_override == \"Genre\":\n        override_value = \"genre\"\n    elif prompt_override == \"Caption\":\n        override_value = \"caption\"\n    else:\n        override_value = None\n\n    updated_lyrics = lyrics if not is_instrumental else \"[Instrumental]\"\n    updated_formatted = updated_lyrics if updated_lyrics and updated_lyrics != \"[Instrumental]\" else \"\"\n    sample, status = builder_state.update_sample(\n        idx,\n        caption=caption,\n        genre=genre,\n        prompt_override=override_value,\n        lyrics=updated_lyrics,\n        formatted_lyrics=updated_formatted,\n        bpm=int(bpm) if bpm else None,\n        keyscale=keyscale,\n        timesignature=timesig,\n        language=\"unknown\" if is_instrumental else language,\n        is_instrumental=is_instrumental,\n        labeled=True,\n    )\n\n    table_data = builder_state.get_samples_dataframe_data()\n    return table_data, status, builder_state\n\n\ndef update_settings(\n    custom_tag: str,\n    tag_position: str,\n    all_instrumental: bool,\n    genre_ratio: int,\n    builder_state: Optional[DatasetBuilder],\n) -> DatasetBuilder:\n    \"\"\"Update dataset settings.\n\n    Returns:\n        Updated builder_state.\n    \"\"\"\n    if builder_state is None:\n        return builder_state\n\n    if custom_tag:\n        builder_state.set_custom_tag(custom_tag, tag_position)\n\n    builder_state.set_all_instrumental(all_instrumental)\n    builder_state.metadata.genre_ratio = int(genre_ratio)\n\n    return builder_state\n\n\ndef save_dataset(\n    save_path: str,\n    dataset_name: str,\n    builder_state: Optional[DatasetBuilder],\n) -> Tuple[str, Any]:\n    \"\"\"Save the dataset to a JSON file.\n\n    Returns:\n        Tuple of (status, save_path_update).\n    \"\"\"\n    if builder_state is None:\n        return \"❌ No dataset to save. Please scan a directory first.\", gr.update()\n\n    if not builder_state.samples:\n        return \"❌ No samples in dataset.\", gr.update()\n\n    if not save_path or not save_path.strip():\n        return \"❌ Please enter a save path.\", gr.update()\n\n    save_path = save_path.strip()\n    if not save_path.lower().endswith(\".json\"):\n        save_path = save_path + \".json\"\n\n    labeled_count = builder_state.get_labeled_count()\n    if labeled_count == 0:\n        return (\n            \"⚠️ Warning: No samples have been labeled. Consider auto-labeling first.\\nSaving anyway...\",\n            gr.update(value=save_path),\n        )\n\n    return builder_state.save_dataset(save_path, dataset_name), gr.update(value=save_path)\n"
  },
  {
    "path": "acestep/ui/gradio/events/training/dataset_ops_test.py",
    "content": "\"\"\"Unit tests for dataset_ops.py.\"\"\"\n\nimport unittest\nfrom unittest.mock import MagicMock, patch\n\nfrom acestep.ui.gradio.events.training.dataset_ops import (\n    get_sample_preview,\n    save_sample_edit,\n    update_settings,\n    save_dataset,\n)\n\n\nclass TestGetSamplePreview(unittest.TestCase):\n    \"\"\"Tests for get_sample_preview.\"\"\"\n\n    def test_none_builder_returns_empty(self):\n        result = get_sample_preview(0, None)\n        # Should return the empty tuple\n        self.assertIsNone(result[0])  # audio_path\n        self.assertEqual(result[1], \"\")  # filename\n\n    def test_empty_samples_returns_empty(self):\n        builder = MagicMock()\n        builder.samples = []\n        result = get_sample_preview(0, builder)\n        self.assertIsNone(result[0])\n\n    def test_none_index_returns_empty(self):\n        builder = MagicMock()\n        builder.samples = [MagicMock()]\n        result = get_sample_preview(None, builder)\n        self.assertIsNone(result[0])\n\n    def test_out_of_range_index_returns_empty(self):\n        builder = MagicMock()\n        builder.samples = [MagicMock()]\n        result = get_sample_preview(5, builder)\n        self.assertIsNone(result[0])\n\n    def test_valid_sample_returns_data(self):\n        sample = MagicMock()\n        sample.audio_path = \"/path/to/audio.wav\"\n        sample.filename = \"audio.wav\"\n        sample.caption = \"Test caption\"\n        sample.genre = \"rock\"\n        sample.prompt_override = \"genre\"\n        sample.lyrics = \"Hello world\"\n        sample.formatted_lyrics = \"\"\n        sample.bpm = 120\n        sample.keyscale = \"C major\"\n        sample.timesignature = \"4/4\"\n        sample.duration = 30.0\n        sample.language = \"en\"\n        sample.is_instrumental = False\n        sample.raw_lyrics = \"\"\n        sample.has_raw_lyrics.return_value = False\n\n        builder = MagicMock()\n        builder.samples = [sample]\n\n        result = get_sample_preview(0, builder)\n        self.assertEqual(result[0], \"/path/to/audio.wav\")\n        self.assertEqual(result[1], \"audio.wav\")\n        self.assertEqual(result[4], \"Genre\")  # prompt_override converted\n\n\nclass TestUpdateSettings(unittest.TestCase):\n    \"\"\"Tests for update_settings.\"\"\"\n\n    def test_none_builder_returns_none(self):\n        result = update_settings(\"tag\", \"prefix\", False, 50, None)\n        self.assertIsNone(result)\n\n    def test_updates_genre_ratio(self):\n        builder = MagicMock()\n        builder.metadata = MagicMock()\n        result = update_settings(\"\", \"prefix\", False, 75, builder)\n        self.assertEqual(result.metadata.genre_ratio, 75)\n\n\nclass TestSaveDataset(unittest.TestCase):\n    \"\"\"Tests for save_dataset.\"\"\"\n\n    def test_none_builder(self):\n        status, _ = save_dataset(\"path.json\", \"name\", None)\n        self.assertIn(\"❌\", status)\n\n    def test_empty_samples(self):\n        builder = MagicMock()\n        builder.samples = []\n        status, _ = save_dataset(\"path.json\", \"name\", builder)\n        self.assertIn(\"❌\", status)\n\n    def test_empty_path(self):\n        builder = MagicMock()\n        builder.samples = [MagicMock()]\n        status, _ = save_dataset(\"\", \"name\", builder)\n        self.assertIn(\"❌\", status)\n\n\nif __name__ == \"__main__\":\n    unittest.main()\n"
  },
  {
    "path": "acestep/ui/gradio/events/training/lokr_training.py",
    "content": "\"\"\"LoKr training handlers for the training UI.\n\nContains functions for starting LoKr training, listing available\ncheckpoint epochs, and exporting trained LoKr weights.\n\"\"\"\n\nimport os\nimport re\nimport time\nfrom typing import Any, Dict, List, Optional, Tuple\n\nimport gradio as gr\nfrom loguru import logger\n\nfrom acestep.training.path_safety import safe_path\nfrom acestep.ui.gradio.i18n import t\nfrom .training_utils import _format_duration, _training_loss_figure\n\n\ndef start_lokr_training(\n    tensor_dir: str,\n    dit_handler,\n    lokr_linear_dim: int,\n    lokr_linear_alpha: int,\n    lokr_factor: int,\n    lokr_decompose_both: bool,\n    lokr_use_tucker: bool,\n    lokr_use_scalar: bool,\n    lokr_weight_decompose: bool,\n    learning_rate: float,\n    train_epochs: int,\n    train_batch_size: int,\n    gradient_accumulation: int,\n    save_every_n_epochs: int,\n    training_shift: float,\n    training_seed: int,\n    lokr_output_dir: str,\n    training_state: Dict,\n    progress=None,\n):\n    \"\"\"Start LoKr training from preprocessed tensors.\n\n    This is a generator function that yields progress updates as\n    (status, log_text, plot_figure, training_state) tuples.\n    \"\"\"\n    if not tensor_dir or not tensor_dir.strip():\n        yield \"❌ Please enter a tensor directory path\", \"\", None, training_state\n        return\n\n    try:\n        tensor_dir = safe_path(tensor_dir.strip())\n    except ValueError:\n        yield f\"❌ Rejected unsafe tensor directory path: {tensor_dir}\", \"\", None, training_state\n        return\n    if not os.path.isdir(tensor_dir):\n        yield f\"❌ Tensor directory not found: {tensor_dir}\", \"\", None, training_state\n        return\n\n    if dit_handler is None or dit_handler.model is None:\n        yield \"❌ Model not initialized. Please initialize the service first.\", \"\", None, training_state\n        return\n\n    if getattr(dit_handler, \"quantization\", None) is not None:\n        yield \"Switching model to training preset (disable quantization)...\", \"\", None, training_state\n        if hasattr(dit_handler, \"switch_to_training_preset\"):\n            switch_status, switched = dit_handler.switch_to_training_preset()\n            if not switched:\n                yield f\"❌ {switch_status}\", \"\", None, training_state\n                return\n            yield f\"✅ {switch_status}\", \"\", None, training_state\n        else:\n            yield (\n                \"❌ Training requires non-quantized DiT, and auto-switch is unavailable in this build.\",\n                \"\", None, training_state,\n            )\n            return\n\n    try:\n        from lightning.fabric import Fabric  # noqa: F401\n    except ImportError as e:\n        yield (\n            f\"❌ Missing required packages: {e}\\nPlease install: pip install lightning lycoris-lora\",\n            \"\", None, training_state,\n        )\n        return\n\n    training_state[\"is_training\"] = True\n    training_state[\"should_stop\"] = False\n    training_state[\"adapter_type\"] = \"lokr\"\n\n    try:\n        from acestep.training.configs import LoKRConfig as LoKRConfigClass, TrainingConfig\n        from acestep.training.trainer import LoKRTrainer\n\n        device_attr = getattr(dit_handler, \"device\", \"\")\n        if hasattr(device_attr, \"type\"):\n            device_type = str(device_attr.type).lower()\n        else:\n            device_type = str(device_attr).split(\":\", 1)[0].lower()\n\n        if device_type == \"cuda\":\n            num_workers, pin_memory, prefetch_factor = 4, True, 2\n            persistent_workers, pin_memory_device, mixed_precision = True, \"cuda\", \"bf16\"\n        elif device_type == \"xpu\":\n            num_workers, pin_memory, prefetch_factor = 4, True, 2\n            persistent_workers, pin_memory_device, mixed_precision = True, \"\", \"bf16\"\n        elif device_type == \"mps\":\n            num_workers, pin_memory, prefetch_factor = 0, False, 2\n            persistent_workers, pin_memory_device, mixed_precision = False, \"\", \"fp16\"\n        else:\n            num_workers, pin_memory, prefetch_factor = 0, False, 2\n            persistent_workers, pin_memory_device, mixed_precision = False, \"\", \"fp32\"\n\n        lokr_config = LoKRConfigClass(\n            linear_dim=lokr_linear_dim, linear_alpha=lokr_linear_alpha,\n            factor=lokr_factor, decompose_both=lokr_decompose_both,\n            use_tucker=lokr_use_tucker, use_scalar=lokr_use_scalar,\n            weight_decompose=lokr_weight_decompose,\n        )\n        training_config = TrainingConfig(\n            shift=training_shift, learning_rate=learning_rate,\n            batch_size=train_batch_size, gradient_accumulation_steps=gradient_accumulation,\n            max_epochs=train_epochs, save_every_n_epochs=save_every_n_epochs,\n            seed=training_seed, output_dir=lokr_output_dir,\n            num_workers=num_workers, pin_memory=pin_memory,\n            prefetch_factor=prefetch_factor, persistent_workers=persistent_workers,\n            pin_memory_device=pin_memory_device, mixed_precision=mixed_precision,\n        )\n\n        log_lines: list = []\n        step_list: list = []\n        loss_list: list = []\n        initial_plot = _training_loss_figure(training_state, step_list, loss_list)\n        start_time = time.time()\n        yield f\"🚀 Starting LoKr training from {tensor_dir}...\", \"\", initial_plot, training_state\n\n        trainer = LoKRTrainer(\n            dit_handler=dit_handler, lokr_config=lokr_config, training_config=training_config,\n        )\n\n        training_failed = False\n        failure_message = \"\"\n\n        for step, loss, status in trainer.train_from_preprocessed(tensor_dir, training_state):\n            status_text = str(status)\n            status_lower = status_text.lower()\n            if (\n                status_text.startswith(\"❌\")\n                or \"training failed\" in status_lower\n                or \"error:\" in status_lower\n                or \"module not found\" in status_lower\n            ):\n                training_failed = True\n                failure_message = status_text\n\n            elapsed_seconds = time.time() - start_time\n            time_info = f\"⏱️ Elapsed: {_format_duration(elapsed_seconds)}\"\n            match = re.search(r\"Epoch\\s+(\\d+)/(\\d+)\", status_text)\n            if match:\n                current_ep, total_ep = int(match.group(1)), int(match.group(2))\n                if current_ep > 0:\n                    eta_seconds = (elapsed_seconds / current_ep) * (total_ep - current_ep)\n                    time_info += f\" | ETA: ~{_format_duration(eta_seconds)}\"\n\n            display_status = f\"{status_text}\\n{time_info}\"\n            log_lines.append(status_text)\n            if len(log_lines) > 15:\n                log_lines = log_lines[-15:]\n            log_text = \"\\n\".join(log_lines)\n\n            if step > 0 and loss is not None and loss == loss:\n                step_list.append(step)\n                loss_list.append(float(loss))\n\n            plot_figure = _training_loss_figure(training_state, step_list, loss_list)\n            yield display_status, log_text, plot_figure, training_state\n\n            if training_state.get(\"should_stop\", False):\n                log_lines.append(\"ℹ️ Training stopped by user\")\n                yield f\"ℹ️ Stopped ({time_info})\", \"\\n\".join(log_lines[-15:]), plot_figure, training_state\n                break\n\n        total_time = time.time() - start_time\n        training_state[\"is_training\"] = False\n        final_plot = _training_loss_figure(training_state, step_list, loss_list)\n        if training_failed:\n            final_msg = f\"{failure_message}\\nElapsed: {_format_duration(total_time)}\"\n            log_lines.append(failure_message)\n            yield final_msg, \"\\n\".join(log_lines[-15:]), final_plot, training_state\n            return\n\n        completion_msg = f\"✅ LoKr training completed! Total time: {_format_duration(total_time)}\"\n        log_lines.append(completion_msg)\n        yield completion_msg, \"\\n\".join(log_lines[-15:]), final_plot, training_state\n\n    except Exception as e:\n        logger.exception(\"LoKr training error\")\n        training_state[\"is_training\"] = False\n        yield f\"❌ Error: {str(e)}\", str(e), _training_loss_figure({}, [], []), training_state\n\n\ndef list_lokr_export_epochs(lokr_output_dir: str) -> Tuple[Any, str]:\n    \"\"\"List available LoKr checkpoint epochs for export dropdown.\n\n    Returns:\n        Tuple of (dropdown_update, status_message).\n    \"\"\"\n    default_choice = t(\"training.latest_auto\")\n    if not lokr_output_dir or not lokr_output_dir.strip():\n        return (\n            gr.update(choices=[default_choice], value=default_choice),\n            t(\"training.lokr_output_dir_required\"),\n        )\n\n    try:\n        lokr_output_dir = safe_path(lokr_output_dir.strip())\n    except ValueError:\n        return (\n            gr.update(choices=[default_choice], value=default_choice),\n            \"❌ Rejected unsafe output directory path\",\n        )\n\n    checkpoint_dir = os.path.join(lokr_output_dir, \"checkpoints\")\n    if not os.path.isdir(checkpoint_dir):\n        return (\n            gr.update(choices=[default_choice], value=default_choice),\n            t(\"training.lokr_no_checkpoints_use_latest\"),\n        )\n\n    checkpoints: List[Tuple[int, str]] = []\n    for d in os.listdir(checkpoint_dir):\n        if not d.startswith(\"epoch_\"):\n            continue\n        weight_file = os.path.join(checkpoint_dir, d, \"lokr_weights.safetensors\")\n        if not os.path.exists(weight_file):\n            continue\n        try:\n            epoch_num = int(d.split(\"_\")[1])\n        except Exception:\n            continue\n        checkpoints.append((epoch_num, d))\n\n    if not checkpoints:\n        return (\n            gr.update(choices=[default_choice], value=default_choice),\n            t(\"training.lokr_no_exportable_checkpoints\"),\n        )\n\n    checkpoints.sort(key=lambda x: x[0], reverse=True)\n    choices = [default_choice] + [d for _, d in checkpoints]\n    return (\n        gr.update(choices=choices, value=default_choice),\n        t(\"training.lokr_found_checkpoints\", count=len(checkpoints)),\n    )\n\n\ndef export_lokr(\n    export_path: str,\n    lokr_output_dir: str,\n    selected_epoch: Optional[str] = None,\n) -> str:\n    \"\"\"Export trained LoKr weights.\n\n    Returns:\n        Status message.\n    \"\"\"\n    if not export_path or not export_path.strip():\n        return t(\"training.export_path_required\")\n\n    try:\n        lokr_output_dir = safe_path(lokr_output_dir)\n        export_path = safe_path(export_path.strip())\n    except ValueError:\n        return \"❌ Rejected unsafe path\"\n\n    final_dir = os.path.join(lokr_output_dir, \"final\")\n    checkpoint_dir = os.path.join(lokr_output_dir, \"checkpoints\")\n    default_epoch_choice = t(\"training.latest_auto\")\n\n    chosen_epoch = (selected_epoch or \"\").strip()\n    if not chosen_epoch:\n        chosen_epoch = default_epoch_choice\n\n    checkpoint_names: List[str] = []\n    if os.path.isdir(checkpoint_dir):\n        for d in os.listdir(checkpoint_dir):\n            if not d.startswith(\"epoch_\"):\n                continue\n            try:\n                int(d.split(\"_\")[1])\n            except Exception:\n                continue\n            checkpoint_names.append(d)\n        checkpoint_names.sort(key=lambda x: int(x.split(\"_\")[1]))\n\n    explicit_epoch = chosen_epoch not in {\n        default_epoch_choice, \"latest\", \"Latest\", \"auto\", \"Auto\",\n    }\n    if explicit_epoch:\n        requested = chosen_epoch\n        if requested.isdigit():\n            requested = f\"epoch_{requested}\"\n        if requested not in checkpoint_names:\n            return t(\n                \"training.lokr_selected_epoch_not_found\",\n                chosen=chosen_epoch,\n                available=(\", \".join(checkpoint_names) if checkpoint_names else \"(none)\"),\n            )\n        source_file = os.path.join(checkpoint_dir, requested, \"lokr_weights.safetensors\")\n        if not os.path.exists(source_file):\n            return t(\"training.lokr_no_weights_selected_epoch\", epoch=requested)\n    elif os.path.exists(os.path.join(final_dir, \"lokr_weights.safetensors\")):\n        source_file = os.path.join(final_dir, \"lokr_weights.safetensors\")\n    elif checkpoint_names:\n        latest_checkpoint = checkpoint_names[-1]\n        source_file = os.path.join(\n            checkpoint_dir, latest_checkpoint, \"lokr_weights.safetensors\",\n        )\n        if not os.path.exists(source_file):\n            return t(\"training.lokr_no_weights_latest_checkpoint\", checkpoint=latest_checkpoint)\n    else:\n        return t(\"training.lokr_no_trained_weights_found\", path=lokr_output_dir)\n\n    try:\n        import shutil\n\n        if export_path.lower().endswith(\".safetensors\"):\n            os.makedirs(\n                os.path.dirname(export_path) if os.path.dirname(export_path) else \".\",\n                exist_ok=True,\n            )\n            shutil.copy2(source_file, export_path)\n            return t(\"training.lokr_exported\", path=export_path)\n\n        os.makedirs(export_path, exist_ok=True)\n        dst_file = os.path.join(export_path, \"lokr_weights.safetensors\")\n        shutil.copy2(source_file, dst_file)\n        return t(\"training.lokr_exported\", path=dst_file)\n\n    except Exception as e:\n        logger.exception(\"LoKr export error\")\n        return t(\"training.export_failed\", error=str(e))\n"
  },
  {
    "path": "acestep/ui/gradio/events/training/lora_training.py",
    "content": "\"\"\"LoRA training handlers for the training UI.\n\nContains functions for starting LoRA training, stopping training,\nand exporting trained LoRA weights.\n\"\"\"\n\nimport os\nimport re\nimport time\nfrom typing import Dict, Tuple\n\nfrom loguru import logger\n\nfrom acestep.gpu_config import get_global_gpu_config\nfrom acestep.training.path_safety import safe_path\nfrom acestep.ui.gradio.i18n import t\nfrom .training_utils import (\n    _format_duration,\n    _training_loss_figure,\n)\n\n\ndef start_training(\n    tensor_dir: str,\n    dit_handler,\n    lora_rank: int,\n    lora_alpha: int,\n    lora_dropout: float,\n    learning_rate: float,\n    train_epochs: int,\n    train_batch_size: int,\n    gradient_accumulation: int,\n    save_every_n_epochs: int,\n    training_shift: float,\n    training_seed: int,\n    lora_output_dir: str,\n    resume_checkpoint_dir: str,\n    training_state: Dict,\n    progress=None,\n):\n    \"\"\"Start LoRA training from preprocessed tensors.\n\n    This is a generator function that yields progress updates as\n    (status, log_text, plot_figure, training_state) tuples.\n    \"\"\"\n    if not tensor_dir or not tensor_dir.strip():\n        yield \"❌ Please enter a tensor directory path\", \"\", None, training_state\n        return\n\n    try:\n        tensor_dir = safe_path(tensor_dir.strip())\n    except ValueError:\n        yield f\"❌ Rejected unsafe tensor directory path: {tensor_dir}\", \"\", None, training_state\n        return\n    if not os.path.isdir(tensor_dir):\n        yield f\"❌ Tensor directory not found: {tensor_dir}\", \"\", None, training_state\n        return\n\n    if dit_handler is None or dit_handler.model is None:\n        yield \"❌ Model not initialized. Please initialize the service first.\", \"\", None, training_state\n        return\n\n    # Training preset: LoRA training must run on non-quantized DiT.\n    if getattr(dit_handler, \"quantization\", None) is not None:\n        gpu_config = get_global_gpu_config()\n        if gpu_config.gpu_memory_gb <= 0:\n            yield (\n                \"WARNING: CPU-only training detected. Using best-effort training path \"\n                \"(non-quantized DiT). Performance will be sub-optimal.\",\n                \"\", None, training_state,\n            )\n        elif gpu_config.tier in {\"tier1\", \"tier2\", \"tier3\", \"tier4\"}:\n            yield (\n                f\"WARNING: Low VRAM tier detected ({gpu_config.gpu_memory_gb:.1f} GB, \"\n                f\"{gpu_config.tier}). Using best-effort training path (non-quantized DiT). \"\n                \"Performance may be sub-optimal.\",\n                \"\", None, training_state,\n            )\n\n        yield \"Switching model to training preset (disable quantization)...\", \"\", None, training_state\n        if hasattr(dit_handler, \"switch_to_training_preset\"):\n            switch_status, switched = dit_handler.switch_to_training_preset()\n            if not switched:\n                yield f\"❌ {switch_status}\", \"\", None, training_state\n                return\n            yield f\"✅ {switch_status}\", \"\", None, training_state\n        else:\n            yield (\n                \"❌ Training requires non-quantized DiT, and auto-switch is unavailable in this build.\",\n                \"\", None, training_state,\n            )\n            return\n\n    # Check for required training dependencies\n    try:\n        from lightning.fabric import Fabric  # noqa: F401\n        from peft import get_peft_model, LoraConfig  # noqa: F401\n    except ImportError as e:\n        yield (\n            f\"❌ Missing required packages: {e}\\nPlease install: pip install peft lightning\",\n            \"\", None, training_state,\n        )\n        return\n\n    training_state[\"is_training\"] = True\n    training_state[\"should_stop\"] = False\n\n    try:\n        from acestep.training.trainer import LoRATrainer\n        from acestep.training.configs import LoRAConfig as LoRAConfigClass, TrainingConfig\n\n        lora_config = LoRAConfigClass(r=lora_rank, alpha=lora_alpha, dropout=lora_dropout)\n\n        device_attr = getattr(dit_handler, \"device\", \"\")\n        if hasattr(device_attr, \"type\"):\n            device_type = str(device_attr.type).lower()\n        else:\n            device_type = str(device_attr).split(\":\", 1)[0].lower()\n\n        # Device-tuned dataloader defaults\n        if device_type == \"cuda\":\n            num_workers, pin_memory, prefetch_factor = 4, True, 2\n            persistent_workers, pin_memory_device, mixed_precision = True, \"cuda\", \"bf16\"\n        elif device_type == \"xpu\":\n            num_workers, pin_memory, prefetch_factor = 4, True, 2\n            persistent_workers, pin_memory_device, mixed_precision = True, \"\", \"bf16\"\n        elif device_type == \"mps\":\n            num_workers, pin_memory, prefetch_factor = 0, False, 2\n            persistent_workers, pin_memory_device, mixed_precision = False, \"\", \"fp16\"\n        else:\n            cpu_count = os.cpu_count() or 2\n            num_workers = min(4, max(1, cpu_count // 2))\n            pin_memory, prefetch_factor = False, 2\n            persistent_workers = num_workers > 0\n            pin_memory_device, mixed_precision = \"\", \"fp32\"\n\n        logger.info(\n            f\"Training loader config: device={device_type}, workers={num_workers}, \"\n            f\"pin_memory={pin_memory}, pin_memory_device={pin_memory_device}, \"\n            f\"persistent_workers={persistent_workers}\"\n        )\n        training_config = TrainingConfig(\n            shift=training_shift, learning_rate=learning_rate,\n            batch_size=train_batch_size, gradient_accumulation_steps=gradient_accumulation,\n            max_epochs=train_epochs, save_every_n_epochs=save_every_n_epochs,\n            seed=training_seed, output_dir=lora_output_dir,\n            num_workers=num_workers, pin_memory=pin_memory,\n            prefetch_factor=prefetch_factor, persistent_workers=persistent_workers,\n            pin_memory_device=pin_memory_device, mixed_precision=mixed_precision,\n        )\n\n        log_lines: list = []\n        step_list: list = []\n        loss_list: list = []\n        initial_plot = _training_loss_figure(training_state, step_list, loss_list)\n        start_time = time.time()\n\n        yield f\"🚀 Starting training from {tensor_dir}...\", \"\", initial_plot, training_state\n\n        trainer = LoRATrainer(\n            dit_handler=dit_handler, lora_config=lora_config, training_config=training_config,\n        )\n\n        training_failed = False\n        failure_message = \"\"\n\n        resume_from = None\n        if resume_checkpoint_dir and resume_checkpoint_dir.strip():\n            try:\n                normalized_resume = safe_path(resume_checkpoint_dir.strip())\n                if os.path.exists(normalized_resume):\n                    resume_from = normalized_resume\n            except ValueError:\n                logger.warning(f\"Rejected unsafe resume path: {resume_checkpoint_dir}\")\n                resume_from = None\n\n        for step, loss, status in trainer.train_from_preprocessed(\n            tensor_dir, training_state, resume_from=resume_from,\n        ):\n            status_text = str(status)\n            status_lower = status_text.lower()\n            if (\n                status_text.startswith(\"❌\")\n                or \"training failed\" in status_lower\n                or \"error:\" in status_lower\n                or \"module not found\" in status_lower\n            ):\n                training_failed = True\n                failure_message = status_text\n\n            elapsed_seconds = time.time() - start_time\n            time_info = f\"⏱️ Elapsed: {_format_duration(elapsed_seconds)}\"\n\n            match = re.search(r\"Epoch\\s+(\\d+)/(\\d+)\", str(status))\n            if match:\n                current_ep, total_ep = int(match.group(1)), int(match.group(2))\n                if current_ep > 0:\n                    eta_seconds = (elapsed_seconds / current_ep) * (total_ep - current_ep)\n                    time_info += f\" | ETA: ~{_format_duration(eta_seconds)}\"\n\n            display_status = f\"{status}\\n{time_info}\"\n            log_msg = f\"[{_format_duration(elapsed_seconds)}] Step {step}: {status}\"\n            logger.info(log_msg)\n\n            log_lines.append(status)\n            if len(log_lines) > 15:\n                log_lines = log_lines[-15:]\n            log_text = \"\\n\".join(log_lines)\n\n            if step > 0 and loss is not None and loss == loss:  # NaN check\n                step_list.append(step)\n                loss_list.append(float(loss))\n\n            plot_figure = _training_loss_figure(training_state, step_list, loss_list)\n            yield display_status, log_text, plot_figure, training_state\n\n            if training_state.get(\"should_stop\", False):\n                logger.info(\"ℹ️ Training stopped by user\")\n                log_lines.append(\"ℹ️ Training stopped by user\")\n                yield f\"ℹ️ Stopped ({time_info})\", \"\\n\".join(log_lines[-15:]), plot_figure, training_state\n                break\n\n        total_time = time.time() - start_time\n        training_state[\"is_training\"] = False\n        final_plot = _training_loss_figure(training_state, step_list, loss_list)\n        if training_failed:\n            final_msg = f\"{failure_message}\\nElapsed: {_format_duration(total_time)}\"\n            logger.warning(final_msg)\n            log_lines.append(failure_message)\n            yield final_msg, \"\\n\".join(log_lines[-15:]), final_plot, training_state\n            return\n        completion_msg = f\"✅ Training completed! Total time: {_format_duration(total_time)}\"\n        logger.info(completion_msg)\n        log_lines.append(completion_msg)\n        yield completion_msg, \"\\n\".join(log_lines[-15:]), final_plot, training_state\n\n    except Exception as e:\n        logger.exception(\"Training error\")\n        training_state[\"is_training\"] = False\n        yield f\"❌ Error: {str(e)}\", str(e), _training_loss_figure({}, [], []), training_state\n\n\ndef stop_training(training_state: Dict) -> Tuple[str, Dict]:\n    \"\"\"Stop the current training process.\n\n    Returns:\n        Tuple of (status, training_state).\n    \"\"\"\n    if not training_state.get(\"is_training\", False):\n        return t(\"training.stop_no_training\"), training_state\n\n    training_state[\"should_stop\"] = True\n    return t(\"training.stop_stopping\"), training_state\n\n\ndef export_lora(export_path: str, lora_output_dir: str) -> str:\n    \"\"\"Export the trained LoRA weights.\n\n    Returns:\n        Status message.\n    \"\"\"\n    if not export_path or not export_path.strip():\n        return t(\"training.export_path_required\")\n\n    try:\n        safe_lora_dir = safe_path(lora_output_dir)\n    except ValueError:\n        return t(\"training.invalid_lora_output_dir\")\n\n    final_dir = os.path.join(safe_lora_dir, \"final\")\n    checkpoint_dir = os.path.join(safe_lora_dir, \"checkpoints\")\n\n    if os.path.exists(final_dir):\n        source_path = final_dir\n    elif os.path.exists(checkpoint_dir):\n        checkpoints = [d for d in os.listdir(checkpoint_dir) if d.startswith(\"epoch_\")]\n        if not checkpoints:\n            return t(\"training.no_checkpoints_found\")\n        checkpoints.sort(key=lambda x: int(x.split(\"_\")[1]))\n        latest = checkpoints[-1]\n        source_path = os.path.join(checkpoint_dir, latest)\n    else:\n        return t(\"training.no_trained_model_found\", path=lora_output_dir)\n\n    try:\n        safe_export = safe_path(export_path.strip())\n    except ValueError:\n        return t(\"training.invalid_export_path\")\n\n    try:\n        import shutil\n\n        parent_dir = os.path.dirname(safe_export) or \".\"\n        os.makedirs(parent_dir, exist_ok=True)\n\n        if os.path.exists(safe_export):\n            shutil.rmtree(safe_export)\n\n        shutil.copytree(source_path, safe_export)\n        return t(\"training.lora_exported\", path=safe_export)\n\n    except Exception as e:\n        logger.exception(\"Export error\")\n        return t(\"training.export_failed\", error=str(e))\n"
  },
  {
    "path": "acestep/ui/gradio/events/training/preprocess.py",
    "content": "\"\"\"Preprocessing and dataset loading for the training UI.\n\nContains handlers for loading existing datasets, preprocessing\naudio to tensor files, and loading preprocessed tensor datasets.\n\"\"\"\n\nimport os\nimport json\nfrom typing import Any, Optional\n\nimport gradio as gr\nfrom loguru import logger\n\nfrom acestep.training.dataset_builder import DatasetBuilder\nfrom acestep.training.path_safety import safe_path\nfrom acestep.debug_utils import debug_log_for, debug_start_for, debug_end_for\nfrom .training_utils import _safe_slider\n\n\ndef load_existing_dataset_for_preprocess(\n    dataset_path: str,\n    builder_state: Optional[DatasetBuilder],\n):\n    \"\"\"Load an existing dataset JSON file for preprocessing.\n\n    This allows users to load a previously saved dataset and proceed to\n    preprocessing without having to re-scan and re-label.\n\n    Returns:\n        Tuple of (status, table_data, slider_update, builder_state,\n                  audio_path, filename, caption, genre, prompt_override,\n                  lyrics, bpm, keyscale, timesig, duration, language,\n                  instrumental, raw_lyrics, has_raw,\n                  name_update, tag_update, pos_update, instr_update,\n                  ratio_update).\n    \"\"\"\n    empty_preview = (\n        None, \"\", \"\", \"\", \"Use Global Ratio\", \"\",\n        None, \"\", \"\", 0.0, \"instrumental\", True, \"\", False,\n    )\n\n    if not dataset_path or not dataset_path.strip():\n        updates = (gr.update(), gr.update(), gr.update(), gr.update(), gr.update())\n        return (\n            \"❌ Please enter a dataset path\",\n            [],\n            _safe_slider(0, value=0, visible=False),\n            builder_state,\n        ) + empty_preview + updates\n\n    try:\n        dataset_path = safe_path(dataset_path.strip())\n    except ValueError:\n        updates = (gr.update(), gr.update(), gr.update(), gr.update(), gr.update())\n        return (\n            f\"❌ Rejected unsafe dataset path: {dataset_path}\",\n            [],\n            _safe_slider(0, value=0, visible=False),\n            builder_state,\n        ) + empty_preview + updates\n\n    debug_log_for(\"dataset\", f\"UI load_existing_dataset_for_preprocess: path='{dataset_path}'\")\n\n    if not os.path.exists(dataset_path):\n        updates = (gr.update(), gr.update(), gr.update(), gr.update(), gr.update())\n        return (\n            f\"❌ Dataset not found: {dataset_path}\",\n            [],\n            _safe_slider(0, value=0, visible=False),\n            builder_state,\n        ) + empty_preview + updates\n\n    builder = DatasetBuilder()\n\n    t0 = debug_start_for(\"dataset\", \"load_dataset\")\n    samples, status = builder.load_dataset(dataset_path)\n    debug_end_for(\"dataset\", \"load_dataset\", t0)\n\n    if not samples:\n        updates = (gr.update(), gr.update(), gr.update(), gr.update(), gr.update())\n        return (\n            status,\n            [],\n            _safe_slider(0, value=0, visible=False),\n            builder,\n        ) + empty_preview + updates\n\n    table_data = builder.get_samples_dataframe_data()\n    slider_max = max(0, len(samples) - 1)\n\n    labeled_count = builder.get_labeled_count()\n    info = f\"📂 Loaded dataset: {builder.metadata.name}\\n\"\n    info += f\"🔢 Samples: {len(samples)} ({labeled_count} labeled)\\n\"\n    info += f\"🏷️ Custom Tag: {builder.metadata.custom_tag or '(none)'}\\n\"\n    info += \"✅ Ready for preprocessing! You can also edit samples below.\"\n    if any((s.formatted_lyrics and not s.lyrics) for s in builder.samples):\n        info += \"\\nℹ️ Showing formatted lyrics where lyrics are empty.\"\n\n    first_sample = builder.samples[0]\n    has_raw = first_sample.has_raw_lyrics()\n\n    if first_sample.prompt_override == \"genre\":\n        override_choice = \"Genre\"\n    elif first_sample.prompt_override == \"caption\":\n        override_choice = \"Caption\"\n    else:\n        override_choice = \"Use Global Ratio\"\n\n    display_lyrics = first_sample.lyrics if first_sample.lyrics else first_sample.formatted_lyrics\n\n    preview = (\n        first_sample.audio_path,\n        first_sample.filename,\n        first_sample.caption,\n        first_sample.genre,\n        override_choice,\n        display_lyrics,\n        first_sample.bpm,\n        first_sample.keyscale,\n        first_sample.timesignature,\n        first_sample.duration,\n        first_sample.language,\n        first_sample.is_instrumental,\n        first_sample.raw_lyrics if has_raw else \"\",\n        has_raw,\n    )\n\n    updates = (\n        gr.update(value=builder.metadata.name),\n        gr.update(value=builder.metadata.custom_tag),\n        gr.update(value=builder.metadata.tag_position),\n        gr.update(value=builder.metadata.all_instrumental),\n        gr.update(value=builder.metadata.genre_ratio),\n    )\n\n    return (\n        info,\n        table_data,\n        _safe_slider(slider_max, value=0, visible=len(samples) > 1),\n        builder,\n    ) + preview + updates\n\n\ndef preprocess_dataset(\n    output_dir: str,\n    preprocess_mode: str,\n    dit_handler,\n    builder_state: Optional[DatasetBuilder],\n    progress=None,\n) -> str:\n    \"\"\"Preprocess dataset to tensor files for fast training.\n\n    Converts audio files to VAE latents and text to embeddings.\n\n    Returns:\n        Status message.\n    \"\"\"\n    if builder_state is None:\n        return \"❌ No dataset loaded. Please scan a directory first.\"\n\n    if not builder_state.samples:\n        return \"❌ No samples in dataset.\"\n\n    labeled_count = builder_state.get_labeled_count()\n    if labeled_count == 0:\n        return \"❌ No labeled samples. Please auto-label or manually label samples first.\"\n\n    if not output_dir or not output_dir.strip():\n        return \"❌ Please enter an output directory.\"\n\n    if dit_handler is None or dit_handler.model is None:\n        return \"❌ Model not initialized. Please initialize the service first.\"\n\n    def progress_callback(msg):\n        if progress:\n            try:\n                progress(msg)\n            except Exception:\n                pass\n\n    mode = str(preprocess_mode or \"lora\").strip().lower()\n    if mode not in {\"lora\", \"lokr\"}:\n        mode = \"lora\"\n\n    t0 = debug_start_for(\"dataset\", \"preprocess_to_tensors\")\n    output_paths, status = builder_state.preprocess_to_tensors(\n        dit_handler=dit_handler,\n        output_dir=output_dir.strip(),\n        preprocess_mode=mode,\n        progress_callback=progress_callback,\n    )\n    debug_end_for(\"dataset\", \"preprocess_to_tensors\", t0)\n\n    return status\n\n\ndef load_training_dataset(tensor_dir: str) -> str:\n    \"\"\"Load a preprocessed tensor dataset for training.\n\n    Returns:\n        Info text about the dataset.\n    \"\"\"\n    if not tensor_dir or not tensor_dir.strip():\n        return \"❌ Please enter a tensor directory path\"\n\n    try:\n        tensor_dir = safe_path(tensor_dir.strip())\n    except ValueError:\n        return f\"❌ Rejected unsafe tensor directory path: {tensor_dir}\"\n\n    if not os.path.exists(tensor_dir):\n        return f\"❌ Directory not found: {tensor_dir}\"\n\n    if not os.path.isdir(tensor_dir):\n        return f\"❌ Not a directory: {tensor_dir}\"\n\n    manifest_path = os.path.join(tensor_dir, \"manifest.json\")\n    if os.path.exists(manifest_path):\n        try:\n            with open(manifest_path, \"r\") as f:\n                manifest = json.load(f)\n\n            num_samples = manifest.get(\"num_samples\", 0)\n            metadata = manifest.get(\"metadata\", {})\n            name = metadata.get(\"name\", \"Unknown\")\n            custom_tag = metadata.get(\"custom_tag\", \"\")\n\n            info = f\"📂 Loaded preprocessed dataset: {name}\\n\"\n            info += f\"🔢 Samples: {num_samples} preprocessed tensors\\n\"\n            info += f\"🏷️ Custom Tag: {custom_tag or '(none)'}\"\n\n            return info\n        except Exception as e:\n            logger.warning(f\"Failed to read manifest: {e}\")\n\n    pt_files = [f for f in os.listdir(tensor_dir) if f.endswith(\".pt\")]\n\n    if not pt_files:\n        return f\"❌ No .pt tensor files found in {tensor_dir}\"\n\n    info = f\"📂 Found {len(pt_files)} tensor files in {tensor_dir}\\n\"\n    info += \"ℹ️ No manifest.json found - using all .pt files\"\n\n    return info\n"
  },
  {
    "path": "acestep/ui/gradio/events/training/preprocess_test.py",
    "content": "\"\"\"Unit tests for preprocess.py.\"\"\"\n\nimport os\nimport json\nimport tempfile\nimport unittest\nfrom unittest.mock import MagicMock\n\nfrom acestep.ui.gradio.events.training.preprocess import (\n    load_training_dataset,\n    preprocess_dataset,\n)\n\n\nclass TestLoadTrainingDataset(unittest.TestCase):\n    \"\"\"Tests for load_training_dataset.\"\"\"\n\n    def test_empty_path(self):\n        result = load_training_dataset(\"\")\n        self.assertIn(\"❌\", result)\n\n    def test_nonexistent_path(self):\n        result = load_training_dataset(\"/nonexistent/path/xyz\")\n        self.assertIn(\"❌\", result)\n\n    def test_with_manifest(self):\n        with tempfile.TemporaryDirectory() as tmpdir:\n            manifest = {\n                \"num_samples\": 10,\n                \"metadata\": {\"name\": \"TestDataset\", \"custom_tag\": \"test\"},\n            }\n            with open(os.path.join(tmpdir, \"manifest.json\"), \"w\") as f:\n                json.dump(manifest, f)\n            # Create a dummy .pt file\n            open(os.path.join(tmpdir, \"sample_0.pt\"), \"w\").close()\n\n            result = load_training_dataset(tmpdir)\n            self.assertIn(\"TestDataset\", result)\n            self.assertIn(\"10\", result)\n\n    def test_without_manifest(self):\n        with tempfile.TemporaryDirectory() as tmpdir:\n            # Create some .pt files\n            for i in range(3):\n                open(os.path.join(tmpdir, f\"sample_{i}.pt\"), \"w\").close()\n\n            result = load_training_dataset(tmpdir)\n            self.assertIn(\"3\", result)\n            self.assertIn(\"tensor files\", result)\n\n    def test_no_pt_files(self):\n        with tempfile.TemporaryDirectory() as tmpdir:\n            result = load_training_dataset(tmpdir)\n            self.assertIn(\"❌\", result)\n\n\nclass TestPreprocessDataset(unittest.TestCase):\n    \"\"\"Tests for preprocess_dataset.\"\"\"\n\n    def test_none_builder(self):\n        result = preprocess_dataset(\"/out\", \"lora\", MagicMock(), None)\n        self.assertIn(\"❌\", result)\n\n    def test_empty_samples(self):\n        builder = MagicMock()\n        builder.samples = []\n        result = preprocess_dataset(\"/out\", \"lora\", MagicMock(), builder)\n        self.assertIn(\"❌\", result)\n\n    def test_no_labeled_samples(self):\n        builder = MagicMock()\n        builder.samples = [MagicMock()]\n        builder.get_labeled_count.return_value = 0\n        result = preprocess_dataset(\"/out\", \"lora\", MagicMock(), builder)\n        self.assertIn(\"❌\", result)\n\n    def test_empty_output_dir(self):\n        builder = MagicMock()\n        builder.samples = [MagicMock()]\n        builder.get_labeled_count.return_value = 5\n        result = preprocess_dataset(\"\", \"lora\", MagicMock(), builder)\n        self.assertIn(\"❌\", result)\n\n    def test_no_model(self):\n        builder = MagicMock()\n        builder.samples = [MagicMock()]\n        builder.get_labeled_count.return_value = 5\n        result = preprocess_dataset(\"/out\", \"lora\", None, builder)\n        self.assertIn(\"❌\", result)\n\n\nif __name__ == \"__main__\":\n    unittest.main()\n"
  },
  {
    "path": "acestep/ui/gradio/events/training/training_facade_test.py",
    "content": "\"\"\"Unit tests for the training_handlers facade.\n\nVerifies that all expected public symbols are re-exported correctly\nthrough the facade at ``acestep.ui.gradio.events.training_handlers``.\n\"\"\"\n\nimport unittest\n\nfrom acestep.ui.gradio.events import training_handlers as facade\n\n\nEXPECTED_SYMBOLS = [\n    # training_utils\n    \"SAFE_TRAINING_ROOT\",\n    \"create_dataset_builder\",\n    # dataset_ops\n    \"scan_directory\",\n    \"auto_label_all\",\n    \"get_sample_preview\",\n    \"save_sample_edit\",\n    \"update_settings\",\n    \"save_dataset\",\n    # preprocess\n    \"load_existing_dataset_for_preprocess\",\n    \"preprocess_dataset\",\n    \"load_training_dataset\",\n    # lora_training\n    \"start_training\",\n    \"stop_training\",\n    \"export_lora\",\n    # lokr_training\n    \"start_lokr_training\",\n    \"list_lokr_export_epochs\",\n    \"export_lokr\",\n]\n\n\nclass TestTrainingFacadeExports(unittest.TestCase):\n    \"\"\"Verify the facade re-exports all expected symbols.\"\"\"\n\n    def test_all_symbols_present(self):\n        for name in EXPECTED_SYMBOLS:\n            with self.subTest(symbol=name):\n                self.assertTrue(\n                    hasattr(facade, name),\n                    f\"Missing symbol: {name}\",\n                )\n\n    def test_callable_symbols(self):\n        callables = [s for s in EXPECTED_SYMBOLS if s != \"SAFE_TRAINING_ROOT\"]\n        for name in callables:\n            with self.subTest(symbol=name):\n                self.assertTrue(\n                    callable(getattr(facade, name)),\n                    f\"Symbol not callable: {name}\",\n                )\n\n\nif __name__ == \"__main__\":\n    unittest.main()\n"
  },
  {
    "path": "acestep/ui/gradio/events/training/training_utils.py",
    "content": "\"\"\"Shared helpers for training event handlers.\n\nContains constants, utility functions, and common UI helpers\nused across dataset, preprocessing, and training sub-modules.\n\"\"\"\n\nimport os\nimport re\nimport time\nfrom typing import Any, Dict, List, Optional\n\nimport gradio as gr\nimport matplotlib\nmatplotlib.use(\"Agg\")\nimport matplotlib.pyplot as plt  # noqa: E402\n\nfrom acestep.ui.gradio.i18n import t\nfrom acestep.training.path_safety import get_safe_root\n\nSAFE_TRAINING_ROOT = get_safe_root()\n\n\ndef create_dataset_builder():\n    \"\"\"Create a new DatasetBuilder instance.\n\n    Lazy import to avoid heavy module load at startup.\n    \"\"\"\n    from acestep.training.dataset_builder import DatasetBuilder\n    return DatasetBuilder()\n\n\ndef _safe_slider(\n    max_value: int,\n    value: int = 0,\n    visible: Optional[bool] = None,\n) -> gr.Slider:\n    \"\"\"Create a slider with a non-zero range to avoid Gradio math errors.\"\"\"\n    max_value = max(1, int(max_value))\n    kwargs: Dict[str, Any] = {\n        \"maximum\": max_value,\n        \"value\": min(int(value), max_value),\n    }\n    if visible is not None:\n        kwargs[\"visible\"] = visible\n    return gr.Slider(**kwargs)\n\n\ndef _safe_join(base_root: str, user_path: str) -> Optional[str]:\n    \"\"\"Safely join user path to base root, preventing directory traversal.\n\n    Uses ``os.path.normpath`` + ``startswith`` — the pattern CodeQL\n    recognises as a path-injection sanitiser.\n    \"\"\"\n    if not user_path or not user_path.strip():\n        return None\n    candidate = user_path.strip()\n    if os.path.isabs(candidate):\n        return None\n    abs_root = os.path.normpath(os.path.abspath(base_root))\n    joined = os.path.normpath(os.path.join(abs_root, candidate))\n    if not joined.startswith(abs_root + os.sep) and joined != abs_root:\n        return None\n    return joined\n\n\ndef _format_duration(seconds: float) -> str:\n    \"\"\"Format seconds to human readable string (e.g. ``2m 30s``).\"\"\"\n    seconds = int(seconds)\n    if seconds < 60:\n        return f\"{seconds}s\"\n    elif seconds < 3600:\n        return f\"{seconds // 60}m {seconds % 60}s\"\n    else:\n        return f\"{seconds // 3600}h {(seconds % 3600) // 60}m\"\n\n\ndef _training_loss_figure(\n    training_state: Dict,\n    step_list: List[int],\n    loss_list: List[float],\n) -> Optional[Any]:\n    \"\"\"Build a training/validation loss plot (matplotlib Figure) for ``gr.Plot``.\"\"\"\n    steps = training_state.get(\"plot_steps\") or step_list\n    loss = training_state.get(\"plot_loss\") or loss_list\n    if not steps or not loss:\n        fig, ax = plt.subplots(figsize=(6, 3))\n        ax.set_xlabel(\"Step\")\n        ax.set_ylabel(\"Loss\")\n        ax.set_title(\"Training loss\")\n        fig.tight_layout()\n        return fig\n    ema = training_state.get(\"plot_ema\")\n    val_steps = training_state.get(\"plot_val_steps\") or []\n    val_loss = training_state.get(\"plot_val_loss\") or []\n    best_step = training_state.get(\"plot_best_step\")\n\n    fig, ax = plt.subplots(figsize=(6, 3))\n    ax.plot(steps, loss, color=\"tab:blue\", alpha=0.35, label=\"Loss (raw)\", linewidth=1)\n    if ema and len(ema) == len(steps):\n        ax.plot(steps, ema, color=\"tab:blue\", alpha=1.0, label=\"Loss (smoothed)\", linewidth=1.5)\n    if val_steps and val_loss:\n        ax.scatter(val_steps, val_loss, color=\"tab:orange\", s=24, zorder=5, label=\"Validation\")\n    if best_step is not None:\n        ax.axvline(x=best_step, color=\"tab:green\", linestyle=\"--\", alpha=0.8, label=\"Best checkpoint\")\n    ax.set_xlabel(\"Step\")\n    ax.set_ylabel(\"Loss\")\n    ax.set_title(\"Training loss\")\n    ax.legend(loc=\"upper right\", fontsize=8)\n    ax.grid(True, alpha=0.3)\n    fig.tight_layout()\n    return fig\n"
  },
  {
    "path": "acestep/ui/gradio/events/training/training_utils_test.py",
    "content": "\"\"\"Unit tests for training_utils.py.\"\"\"\n\nimport unittest\nfrom unittest.mock import patch\n\nfrom acestep.ui.gradio.events.training.training_utils import (\n    _format_duration,\n    _safe_join,\n    _safe_slider,\n    _training_loss_figure,\n    SAFE_TRAINING_ROOT,\n)\n\n\nclass TestFormatDuration(unittest.TestCase):\n    \"\"\"Tests for _format_duration.\"\"\"\n\n    def test_seconds_only(self):\n        self.assertEqual(_format_duration(45), \"45s\")\n\n    def test_minutes_and_seconds(self):\n        self.assertEqual(_format_duration(125), \"2m 5s\")\n\n    def test_hours(self):\n        self.assertEqual(_format_duration(3661), \"1h 1m\")\n\n    def test_zero(self):\n        self.assertEqual(_format_duration(0), \"0s\")\n\n\nclass TestSafeJoin(unittest.TestCase):\n    \"\"\"Tests for _safe_join.\"\"\"\n\n    def test_valid_relative_path(self):\n        result = _safe_join(\"/base\", \"subdir/file.txt\")\n        # Should be under /base\n        self.assertIsNotNone(result)\n        self.assertTrue(result.startswith(\"/base\"))\n\n    def test_absolute_path_rejected(self):\n        result = _safe_join(\"/base\", \"/etc/passwd\")\n        self.assertIsNone(result)\n\n    def test_traversal_rejected(self):\n        result = _safe_join(\"/base/root\", \"../../etc/passwd\")\n        self.assertIsNone(result)\n\n    def test_empty_path(self):\n        result = _safe_join(\"/base\", \"\")\n        self.assertIsNone(result)\n\n    def test_none_path(self):\n        result = _safe_join(\"/base\", None)\n        self.assertIsNone(result)\n\n\nclass TestSafeSlider(unittest.TestCase):\n    \"\"\"Tests for _safe_slider.\"\"\"\n\n    def test_minimum_max_value(self):\n        slider = _safe_slider(0, value=0)\n        # max_value should be at least 1\n        self.assertIsNotNone(slider)\n\n    def test_with_visible(self):\n        slider = _safe_slider(10, value=5, visible=True)\n        self.assertIsNotNone(slider)\n\n\nclass TestTrainingLossFigure(unittest.TestCase):\n    \"\"\"Tests for _training_loss_figure.\"\"\"\n\n    def test_empty_data_returns_figure(self):\n        fig = _training_loss_figure({}, [], [])\n        self.assertIsNotNone(fig)\n\n    def test_with_data_returns_figure(self):\n        fig = _training_loss_figure(\n            {},\n            [1, 2, 3, 4, 5],\n            [0.5, 0.4, 0.3, 0.25, 0.2],\n        )\n        self.assertIsNotNone(fig)\n\n    def test_with_ema_and_validation(self):\n        state = {\n            \"plot_ema\": [0.5, 0.45, 0.35, 0.28, 0.22],\n            \"plot_val_steps\": [3, 5],\n            \"plot_val_loss\": [0.35, 0.25],\n            \"plot_best_step\": 5,\n        }\n        fig = _training_loss_figure(\n            state,\n            [1, 2, 3, 4, 5],\n            [0.5, 0.4, 0.3, 0.25, 0.2],\n        )\n        self.assertIsNotNone(fig)\n\n\nclass TestSafeTrainingRoot(unittest.TestCase):\n    \"\"\"Tests for SAFE_TRAINING_ROOT constant.\"\"\"\n\n    def test_is_absolute(self):\n        import os\n        self.assertTrue(os.path.isabs(SAFE_TRAINING_ROOT))\n\n\nif __name__ == \"__main__\":\n    unittest.main()\n"
  },
  {
    "path": "acestep/ui/gradio/events/training_handlers.py",
    "content": "\"\"\"Training Event Handlers Module — Facade.\n\nRe-exports all public symbols from the ``training`` sub-package so\nthat existing callers (e.g. ``events/__init__.py``) continue to work\nunchanged via ``from . import training_handlers as train_h``.\n\"\"\"\n\nfrom .training.training_utils import (  # noqa: F401\n    SAFE_TRAINING_ROOT,\n    create_dataset_builder,\n    _safe_slider,\n    _safe_join,\n    _format_duration,\n    _training_loss_figure,\n)\nfrom .training.dataset_ops import (  # noqa: F401\n    scan_directory,\n    auto_label_all,\n    get_sample_preview,\n    save_sample_edit,\n    update_settings,\n    save_dataset,\n)\nfrom .training.preprocess import (  # noqa: F401\n    load_existing_dataset_for_preprocess,\n    preprocess_dataset,\n    load_training_dataset,\n)\nfrom .training.lora_training import (  # noqa: F401\n    start_training,\n    stop_training,\n    export_lora,\n)\nfrom .training.lokr_training import (  # noqa: F401\n    start_lokr_training,\n    list_lokr_export_epochs,\n    export_lokr,\n)\n"
  },
  {
    "path": "acestep/ui/gradio/events/wiring/__init__.py",
    "content": "\"\"\"Wiring helpers for Gradio event registration.\n\nThis package provides shared context and list-builder helpers used by the\nevent wiring facade in ``acestep.ui.gradio.events``.\n\"\"\"\n\nfrom .context import (\n    GenerationWiringContext,\n    TrainingWiringContext,\n    build_auto_checkbox_inputs,\n    build_auto_checkbox_outputs,\n    build_mode_ui_outputs,\n)\nfrom .generation_metadata_wiring import register_generation_metadata_handlers\nfrom .generation_metadata_file_wiring import register_generation_metadata_file_handlers\nfrom .generation_batch_navigation_wiring import register_generation_batch_navigation_handlers\nfrom .generation_mode_wiring import register_generation_mode_handlers\nfrom .generation_run_wiring import register_generation_run_handlers\nfrom .results_aux_wiring import register_results_aux_handlers\nfrom .results_display_wiring import (\n    register_results_restore_and_lrc_handlers,\n    register_results_save_button_handlers,\n)\nfrom .generation_service_wiring import register_generation_service_handlers\nfrom .training_dataset_builder_wiring import register_training_dataset_builder_handlers\nfrom .training_dataset_preprocess_wiring import (\n    register_training_dataset_load_handler,\n    register_training_preprocess_handler,\n)\nfrom .training_run_wiring import register_training_run_handlers\n\n__all__ = [\n    \"GenerationWiringContext\",\n    \"TrainingWiringContext\",\n    \"build_auto_checkbox_inputs\",\n    \"build_auto_checkbox_outputs\",\n    \"build_mode_ui_outputs\",\n    \"register_generation_batch_navigation_handlers\",\n    \"register_generation_metadata_file_handlers\",\n    \"register_generation_metadata_handlers\",\n    \"register_generation_mode_handlers\",\n    \"register_generation_run_handlers\",\n    \"register_results_aux_handlers\",\n    \"register_results_restore_and_lrc_handlers\",\n    \"register_results_save_button_handlers\",\n    \"register_generation_service_handlers\",\n    \"register_training_dataset_builder_handlers\",\n    \"register_training_dataset_load_handler\",\n    \"register_training_preprocess_handler\",\n    \"register_training_run_handlers\",\n]\n"
  },
  {
    "path": "acestep/ui/gradio/events/wiring/ast_test_utils.py",
    "content": "\"\"\"Shared AST parsing helpers for wiring contract tests.\"\"\"\n\nimport ast\nfrom pathlib import Path\n\n\ndef load_module_ast(module_path: Path) -> ast.Module:\n    \"\"\"Return the parsed AST module for the provided source path.\"\"\"\n\n    return ast.parse(module_path.read_text(encoding=\"utf-8\"))\n\n\ndef subscript_key(node: ast.Subscript) -> str | None:\n    \"\"\"Return constant key value from a simple subscript expression.\"\"\"\n\n    if isinstance(node.slice, ast.Constant) and isinstance(node.slice.value, str):\n        return node.slice.value\n    return None\n"
  },
  {
    "path": "acestep/ui/gradio/events/wiring/context.py",
    "content": "\"\"\"Typed wiring context and shared component-list builders.\n\nThe event facade contains several long output/input lists that must remain in\nstrict order. This module centralizes those list contracts to reduce copy-paste\nrisk while keeping handler wiring behavior unchanged.\n\"\"\"\n\nfrom dataclasses import dataclass\nfrom typing import Any, Mapping\n\n\nComponentMap = Mapping[str, Any]\n\n_AUTO_CHECKBOX_OUTPUT_KEYS = (\n    \"bpm_auto\",\n    \"key_auto\",\n    \"timesig_auto\",\n    \"vocal_lang_auto\",\n    \"duration_auto\",\n    \"bpm\",\n    \"key_scale\",\n    \"time_signature\",\n    \"vocal_language\",\n    \"audio_duration\",\n)\n\n_AUTO_CHECKBOX_INPUT_KEYS = (\n    \"bpm\",\n    \"key_scale\",\n    \"time_signature\",\n    \"vocal_language\",\n    \"audio_duration\",\n)\n\n_MODE_UI_OUTPUT_KEYS = (\n    \"simple_mode_group\",\n    \"custom_mode_group\",\n    \"generate_btn\",\n    \"simple_sample_created\",\n    \"optional_params_accordion\",\n    \"task_type\",\n    \"src_audio_row\",\n    \"repainting_group\",\n    \"text2music_audio_codes_group\",\n    \"track_name\",\n    \"complete_track_classes\",\n    \"generate_btn_row\",\n    \"generation_mode\",\n    \"results_wrapper\",\n    \"think_checkbox\",\n    \"load_file_col\",\n    \"load_file\",\n    \"audio_cover_strength\",\n    \"cover_noise_strength\",\n    \"captions\",\n    \"lyrics\",\n    \"bpm\",\n    \"key_scale\",\n    \"time_signature\",\n    \"vocal_language\",\n    \"audio_duration\",\n    \"auto_score\",\n    \"autogen_checkbox\",\n    \"auto_lrc\",\n    \"analyze_btn\",\n    \"repainting_header_html\",\n    \"repainting_start\",\n    \"repainting_end\",\n    \"repaint_mode\",\n    \"repaint_strength\",\n    \"previous_generation_mode\",\n    \"remix_help_group\",\n    \"extract_help_group\",\n    \"complete_help_group\",\n    \"bpm_auto\",\n    \"key_auto\",\n    \"timesig_auto\",\n    \"vocal_lang_auto\",\n    \"duration_auto\",\n    \"text2music_audio_code_string\",\n    \"src_audio\",\n)\n\n\n@dataclass(frozen=True)\nclass GenerationWiringContext:\n    \"\"\"Inputs required for generation/results event wiring.\"\"\"\n\n    demo: Any\n    dit_handler: Any\n    llm_handler: Any\n    dataset_handler: Any\n    dataset_section: ComponentMap\n    generation_section: ComponentMap\n    results_section: ComponentMap\n\n\n@dataclass(frozen=True)\nclass TrainingWiringContext:\n    \"\"\"Inputs required for training event wiring.\"\"\"\n\n    demo: Any\n    dit_handler: Any\n    llm_handler: Any\n    training_section: ComponentMap\n\n\ndef build_auto_checkbox_outputs(context: GenerationWiringContext) -> list[Any]:\n    \"\"\"Return ordered auto-checkbox outputs for metadata field sync.\"\"\"\n\n    generation = context.generation_section\n    return [generation[key] for key in _AUTO_CHECKBOX_OUTPUT_KEYS]\n\n\ndef build_auto_checkbox_inputs(context: GenerationWiringContext) -> list[Any]:\n    \"\"\"Return ordered metadata fields used to derive auto-checkbox state.\"\"\"\n\n    generation = context.generation_section\n    return [generation[key] for key in _AUTO_CHECKBOX_INPUT_KEYS]\n\n\ndef build_mode_ui_outputs(context: GenerationWiringContext) -> list[Any]:\n    \"\"\"Return ordered mode-UI outputs shared across mode/remix/repaint wiring.\"\"\"\n\n    generation = context.generation_section\n    return [generation[key] for key in _MODE_UI_OUTPUT_KEYS]\n"
  },
  {
    "path": "acestep/ui/gradio/events/wiring/context_test.py",
    "content": "\"\"\"Unit tests for event-wiring context helpers.\"\"\"\n\nimport importlib.util\nfrom pathlib import Path\nimport unittest\n\n\nAUTO_OUTPUT_EXPECTED = [\n    \"bpm_auto\",\n    \"key_auto\",\n    \"timesig_auto\",\n    \"vocal_lang_auto\",\n    \"duration_auto\",\n    \"bpm\",\n    \"key_scale\",\n    \"time_signature\",\n    \"vocal_language\",\n    \"audio_duration\",\n]\n\nAUTO_INPUT_EXPECTED = [\n    \"bpm\",\n    \"key_scale\",\n    \"time_signature\",\n    \"vocal_language\",\n    \"audio_duration\",\n]\n\nMODE_OUTPUT_EXPECTED = [\n    \"simple_mode_group\",\n    \"custom_mode_group\",\n    \"generate_btn\",\n    \"simple_sample_created\",\n    \"optional_params_accordion\",\n    \"task_type\",\n    \"src_audio_row\",\n    \"repainting_group\",\n    \"text2music_audio_codes_group\",\n    \"track_name\",\n    \"complete_track_classes\",\n    \"generate_btn_row\",\n    \"generation_mode\",\n    \"results_wrapper\",\n    \"think_checkbox\",\n    \"load_file_col\",\n    \"load_file\",\n    \"audio_cover_strength\",\n    \"cover_noise_strength\",\n    \"captions\",\n    \"lyrics\",\n    \"bpm\",\n    \"key_scale\",\n    \"time_signature\",\n    \"vocal_language\",\n    \"audio_duration\",\n    \"auto_score\",\n    \"autogen_checkbox\",\n    \"auto_lrc\",\n    \"analyze_btn\",\n    \"repainting_header_html\",\n    \"repainting_start\",\n    \"repainting_end\",\n    \"repaint_mode\",\n    \"repaint_strength\",\n    \"previous_generation_mode\",\n    \"remix_help_group\",\n    \"extract_help_group\",\n    \"complete_help_group\",\n    \"bpm_auto\",\n    \"key_auto\",\n    \"timesig_auto\",\n    \"vocal_lang_auto\",\n    \"duration_auto\",\n    \"text2music_audio_code_string\",\n    \"src_audio\",\n]\n\n\ndef _load_context_module():\n    \"\"\"Load the context module directly from disk without package side effects.\"\"\"\n    module_path = Path(__file__).with_name(\"context.py\")\n    spec = importlib.util.spec_from_file_location(\"events_wiring_context\", module_path)\n    if spec is None or spec.loader is None:\n        raise RuntimeError(f\"Unable to load spec for {module_path}\")\n    module = importlib.util.module_from_spec(spec)\n    spec.loader.exec_module(module)\n    return module\n\n\n_MODULE = _load_context_module()\nGenerationWiringContext = _MODULE.GenerationWiringContext\nTrainingWiringContext = _MODULE.TrainingWiringContext\nbuild_auto_checkbox_inputs = _MODULE.build_auto_checkbox_inputs\nbuild_auto_checkbox_outputs = _MODULE.build_auto_checkbox_outputs\nbuild_mode_ui_outputs = _MODULE.build_mode_ui_outputs\n\n\nclass GenerationWiringContextTests(unittest.TestCase):\n    \"\"\"Verify ordered component-list builders used by event wiring.\"\"\"\n\n    def setUp(self):\n        \"\"\"Build a minimal context with deterministic component values.\"\"\"\n        required_keys = set(MODE_OUTPUT_EXPECTED + AUTO_OUTPUT_EXPECTED + AUTO_INPUT_EXPECTED)\n        self.generation_section = {key: key for key in required_keys}\n        self.context = GenerationWiringContext(\n            demo=object(),\n            dit_handler=object(),\n            llm_handler=object(),\n            dataset_handler=object(),\n            dataset_section={},\n            generation_section=self.generation_section,\n            results_section={},\n        )\n\n    def test_build_auto_checkbox_outputs_uses_expected_order(self):\n        \"\"\"Auto checkbox output order must remain stable across refactors.\"\"\"\n        self.assertEqual(build_auto_checkbox_outputs(self.context), AUTO_OUTPUT_EXPECTED)\n\n    def test_build_auto_checkbox_inputs_uses_expected_order(self):\n        \"\"\"Auto checkbox input order must remain stable across refactors.\"\"\"\n        self.assertEqual(build_auto_checkbox_inputs(self.context), AUTO_INPUT_EXPECTED)\n\n    def test_build_mode_ui_outputs_uses_expected_order(self):\n        \"\"\"Mode output list must match wiring contract for event handlers.\"\"\"\n        self.assertEqual(build_mode_ui_outputs(self.context), MODE_OUTPUT_EXPECTED)\n\n\nclass TrainingWiringContextTests(unittest.TestCase):\n    \"\"\"Verify the training context stores expected references.\"\"\"\n\n    def test_training_context_keeps_training_section_reference(self):\n        \"\"\"Training context should keep the original section mapping.\"\"\"\n        training_section = {\"training_progress\": \"training_progress\"}\n        context = TrainingWiringContext(\n            demo=object(),\n            dit_handler=object(),\n            llm_handler=object(),\n            training_section=training_section,\n        )\n        self.assertIs(context.training_section, training_section)\n\n\nif __name__ == \"__main__\":\n    unittest.main()\n"
  },
  {
    "path": "acestep/ui/gradio/events/wiring/decomposition_contract_generation_test.py",
    "content": "\"\"\"Generation-focused decomposition contract tests.\"\"\"\n\nimport ast\nimport unittest\n\ntry:\n    from .decomposition_contract_helpers import (\n        call_name,\n        load_generation_batch_navigation_wiring_node,\n        load_generation_metadata_file_wiring_module,\n        load_generation_mode_wiring_node,\n        load_generation_run_wiring_node,\n        load_results_display_wiring_module,\n        load_setup_event_handlers_node,\n    )\nexcept ImportError:  # pragma: no cover - supports direct file execution\n    from decomposition_contract_helpers import (\n        call_name,\n        load_generation_batch_navigation_wiring_node,\n        load_generation_metadata_file_wiring_module,\n        load_generation_mode_wiring_node,\n        load_generation_run_wiring_node,\n        load_results_display_wiring_module,\n        load_setup_event_handlers_node,\n    )\n\n\nclass DecompositionContractGenerationTests(unittest.TestCase):\n    \"\"\"Verify generation-side delegation contracts for event wiring extraction.\"\"\"\n\n    def test_setup_event_handlers_uses_generation_wiring_helpers(self):\n        \"\"\"setup_event_handlers should delegate generation wiring registration.\"\"\"\n\n        setup_node = load_setup_event_handlers_node()\n        call_names = []\n        for node in ast.walk(setup_node):\n            if isinstance(node, ast.Call):\n                name = call_name(node.func)\n                if name:\n                    call_names.append(name)\n\n        self.assertIn(\"register_generation_service_handlers\", call_names)\n        self.assertIn(\"register_generation_batch_navigation_handlers\", call_names)\n        self.assertIn(\"register_generation_metadata_file_handlers\", call_names)\n        self.assertIn(\"register_generation_metadata_handlers\", call_names)\n        self.assertIn(\"register_generation_mode_handlers\", call_names)\n        self.assertIn(\"register_generation_run_handlers\", call_names)\n        self.assertIn(\"register_results_aux_handlers\", call_names)\n        self.assertIn(\"register_results_save_button_handlers\", call_names)\n        self.assertIn(\"register_results_restore_and_lrc_handlers\", call_names)\n        self.assertIn(\"build_mode_ui_outputs\", call_names)\n\n    def test_generation_metadata_file_wiring_calls_expected_handlers(self):\n        \"\"\"Metadata file wiring should call load-metadata and auto-uncheck handlers.\"\"\"\n\n        wiring_node = load_generation_metadata_file_wiring_module()\n        attribute_names = []\n        for node in ast.walk(wiring_node):\n            if isinstance(node, ast.Attribute):\n                attribute_names.append(node.attr)\n\n        self.assertIn(\"load_metadata\", attribute_names)\n        self.assertIn(\"uncheck_auto_for_populated_fields\", attribute_names)\n\n    def test_generation_mode_wiring_uses_mode_ui_outputs_variable(self):\n        \"\"\"Mode wiring helper should bind generation_mode outputs to mode_ui_outputs.\"\"\"\n\n        wiring_node = load_generation_mode_wiring_node()\n        found_mode_change_output_binding = False\n\n        for node in ast.walk(wiring_node):\n            if not isinstance(node, ast.Call):\n                continue\n            if not isinstance(node.func, ast.Attribute) or node.func.attr != \"change\":\n                continue\n            for keyword in node.keywords:\n                if keyword.arg != \"outputs\":\n                    continue\n                if isinstance(keyword.value, ast.Name) and keyword.value.id == \"mode_ui_outputs\":\n                    found_mode_change_output_binding = True\n                    break\n            if found_mode_change_output_binding:\n                break\n\n        self.assertTrue(found_mode_change_output_binding)\n\n    def test_generation_run_wiring_calls_expected_results_handlers(self):\n        \"\"\"Run wiring should call clear, generate stream, and background pre-generation helpers.\"\"\"\n\n        wiring_node = load_generation_run_wiring_node()\n        call_names = []\n        attribute_names = []\n        for node in ast.walk(wiring_node):\n            if isinstance(node, ast.Call):\n                name = call_name(node.func)\n                if name:\n                    call_names.append(name)\n            if isinstance(node, ast.Attribute):\n                attribute_names.append(node.attr)\n\n        self.assertIn(\"clear_audio_outputs_for_new_generation\", attribute_names)\n        self.assertIn(\"generate_with_batch_management\", call_names)\n        self.assertIn(\"generate_next_batch_background\", call_names)\n\n    def test_batch_navigation_wiring_calls_expected_results_handlers(self):\n        \"\"\"Batch navigation wiring should call previous/next/background results helpers.\"\"\"\n\n        wiring_node = load_generation_batch_navigation_wiring_node()\n        call_names = []\n        attribute_names = []\n        for node in ast.walk(wiring_node):\n            if isinstance(node, ast.Call):\n                name = call_name(node.func)\n                if name:\n                    call_names.append(name)\n            if isinstance(node, ast.Attribute):\n                attribute_names.append(node.attr)\n\n        self.assertIn(\"navigate_to_previous_batch\", attribute_names)\n        self.assertIn(\"capture_current_params\", attribute_names)\n        self.assertIn(\"navigate_to_next_batch\", attribute_names)\n        self.assertIn(\"generate_next_batch_background\", call_names)\n\n    def test_results_display_wiring_calls_expected_results_handlers(self):\n        \"\"\"Results display wiring should call restore and LRC subtitle handlers.\"\"\"\n\n        wiring_node = load_results_display_wiring_module()\n        attribute_names = []\n        for node in ast.walk(wiring_node):\n            if isinstance(node, ast.Attribute):\n                attribute_names.append(node.attr)\n\n        self.assertIn(\"restore_batch_parameters\", attribute_names)\n        self.assertIn(\"update_audio_subtitles_from_lrc\", attribute_names)\n\n\nif __name__ == \"__main__\":\n    unittest.main()\n"
  },
  {
    "path": "acestep/ui/gradio/events/wiring/decomposition_contract_helpers.py",
    "content": "\"\"\"Shared AST helpers for decomposition contract tests.\"\"\"\n\nimport ast\nfrom pathlib import Path\n\n\n_EVENTS_INIT_PATH = Path(__file__).resolve().parents[1] / \"__init__.py\"\n_MODE_WIRING_PATH = Path(__file__).resolve().with_name(\"generation_mode_wiring.py\")\n_METADATA_FILE_WIRING_PATH = Path(__file__).resolve().with_name(\n    \"generation_metadata_file_wiring.py\"\n)\n_RUN_WIRING_PATH = Path(__file__).resolve().with_name(\"generation_run_wiring.py\")\n_BATCH_NAV_WIRING_PATH = Path(__file__).resolve().with_name(\n    \"generation_batch_navigation_wiring.py\"\n)\n_RESULTS_DISPLAY_WIRING_PATH = Path(__file__).resolve().with_name(\n    \"results_display_wiring.py\"\n)\n_TRAINING_DATASET_BUILDER_WIRING_PATH = Path(__file__).resolve().with_name(\n    \"training_dataset_builder_wiring.py\"\n)\n_TRAINING_DATASET_PREPROCESS_WIRING_PATH = Path(__file__).resolve().with_name(\n    \"training_dataset_preprocess_wiring.py\"\n)\n_TRAINING_RUN_WIRING_PATH = Path(__file__).resolve().with_name(\"training_run_wiring.py\")\n_TRAINING_LOKR_WIRING_PATH = Path(__file__).resolve().with_name(\"training_lokr_wiring.py\")\n\n\ndef load_setup_event_handlers_node() -> ast.FunctionDef:\n    \"\"\"Return the AST node for ``setup_event_handlers``.\"\"\"\n\n    source = _EVENTS_INIT_PATH.read_text(encoding=\"utf-8\")\n    module = ast.parse(source)\n    for node in module.body:\n        if isinstance(node, ast.FunctionDef) and node.name == \"setup_event_handlers\":\n            return node\n    raise AssertionError(\"setup_event_handlers not found\")\n\n\ndef load_setup_training_event_handlers_node() -> ast.FunctionDef:\n    \"\"\"Return the AST node for ``setup_training_event_handlers``.\"\"\"\n\n    source = _EVENTS_INIT_PATH.read_text(encoding=\"utf-8\")\n    module = ast.parse(source)\n    for node in module.body:\n        if isinstance(node, ast.FunctionDef) and node.name == \"setup_training_event_handlers\":\n            return node\n    raise AssertionError(\"setup_training_event_handlers not found\")\n\n\ndef load_generation_mode_wiring_node() -> ast.FunctionDef:\n    \"\"\"Return the AST node for ``register_generation_mode_handlers``.\"\"\"\n\n    source = _MODE_WIRING_PATH.read_text(encoding=\"utf-8\")\n    module = ast.parse(source)\n    for node in module.body:\n        if isinstance(node, ast.FunctionDef) and node.name == \"register_generation_mode_handlers\":\n            return node\n    raise AssertionError(\"register_generation_mode_handlers not found\")\n\n\ndef load_generation_metadata_file_wiring_module() -> ast.Module:\n    \"\"\"Return the parsed AST module for metadata file-load wiring.\"\"\"\n\n    source = _METADATA_FILE_WIRING_PATH.read_text(encoding=\"utf-8\")\n    return ast.parse(source)\n\n\ndef load_generation_run_wiring_node() -> ast.FunctionDef:\n    \"\"\"Return the AST node for ``register_generation_run_handlers``.\"\"\"\n\n    source = _RUN_WIRING_PATH.read_text(encoding=\"utf-8\")\n    module = ast.parse(source)\n    for node in module.body:\n        if isinstance(node, ast.FunctionDef) and node.name == \"register_generation_run_handlers\":\n            return node\n    raise AssertionError(\"register_generation_run_handlers not found\")\n\n\ndef load_generation_batch_navigation_wiring_node() -> ast.FunctionDef:\n    \"\"\"Return the AST node for ``register_generation_batch_navigation_handlers``.\"\"\"\n\n    source = _BATCH_NAV_WIRING_PATH.read_text(encoding=\"utf-8\")\n    module = ast.parse(source)\n    for node in module.body:\n        if isinstance(node, ast.FunctionDef) and node.name == \"register_generation_batch_navigation_handlers\":\n            return node\n    raise AssertionError(\"register_generation_batch_navigation_handlers not found\")\n\n\ndef load_results_display_wiring_module() -> ast.Module:\n    \"\"\"Return the parsed AST module for results display/save wiring.\"\"\"\n\n    source = _RESULTS_DISPLAY_WIRING_PATH.read_text(encoding=\"utf-8\")\n    return ast.parse(source)\n\n\ndef load_training_run_wiring_module() -> ast.Module:\n    \"\"\"Return the parsed AST module for ``training_run_wiring.py``.\"\"\"\n\n    source = _TRAINING_RUN_WIRING_PATH.read_text(encoding=\"utf-8\")\n    return ast.parse(source)\n\n\ndef load_training_lokr_wiring_module() -> ast.Module:\n    \"\"\"Return the parsed AST module for ``training_lokr_wiring.py``.\"\"\"\n\n    source = _TRAINING_LOKR_WIRING_PATH.read_text(encoding=\"utf-8\")\n    return ast.parse(source)\n\n\ndef load_training_dataset_preprocess_wiring_module() -> ast.Module:\n    \"\"\"Return the parsed AST module for training dataset/preprocess wiring.\"\"\"\n\n    source = _TRAINING_DATASET_PREPROCESS_WIRING_PATH.read_text(encoding=\"utf-8\")\n    return ast.parse(source)\n\n\ndef load_training_dataset_builder_wiring_module() -> ast.Module:\n    \"\"\"Return the parsed AST module for training dataset-builder wiring.\"\"\"\n\n    source = _TRAINING_DATASET_BUILDER_WIRING_PATH.read_text(encoding=\"utf-8\")\n    return ast.parse(source)\n\n\ndef call_name(node: ast.AST) -> str | None:\n    \"\"\"Extract a simple function name from a call node target.\"\"\"\n\n    if isinstance(node, ast.Name):\n        return node.id\n    if isinstance(node, ast.Attribute):\n        return node.attr\n    return None\n"
  },
  {
    "path": "acestep/ui/gradio/events/wiring/decomposition_contract_training_test.py",
    "content": "\"\"\"Training-focused decomposition contract tests.\"\"\"\n\nimport ast\nimport unittest\n\ntry:\n    from .decomposition_contract_helpers import (\n        call_name,\n        load_setup_training_event_handlers_node,\n        load_training_dataset_builder_wiring_module,\n        load_training_dataset_preprocess_wiring_module,\n        load_training_lokr_wiring_module,\n        load_training_run_wiring_module,\n    )\nexcept ImportError:  # pragma: no cover - supports direct file execution\n    from decomposition_contract_helpers import (\n        call_name,\n        load_setup_training_event_handlers_node,\n        load_training_dataset_builder_wiring_module,\n        load_training_dataset_preprocess_wiring_module,\n        load_training_lokr_wiring_module,\n        load_training_run_wiring_module,\n    )\n\n\nclass DecompositionContractTrainingTests(unittest.TestCase):\n    \"\"\"Verify training-side delegation contracts for event wiring extraction.\"\"\"\n\n    def test_setup_training_event_handlers_uses_training_run_wiring_helper(self):\n        \"\"\"setup_training_event_handlers should delegate run-tab wiring registration.\"\"\"\n\n        setup_node = load_setup_training_event_handlers_node()\n        call_names = []\n        for node in ast.walk(setup_node):\n            if isinstance(node, ast.Call):\n                name = call_name(node.func)\n                if name:\n                    call_names.append(name)\n\n        self.assertIn(\"register_training_run_handlers\", call_names)\n        self.assertIn(\"register_training_dataset_builder_handlers\", call_names)\n        self.assertIn(\"register_training_dataset_load_handler\", call_names)\n        self.assertIn(\"register_training_preprocess_handler\", call_names)\n\n    def test_training_run_wiring_calls_expected_training_handlers(self):\n        \"\"\"Training run wiring should invoke both LoRA and LoKr training entry points.\"\"\"\n\n        training_run_node = load_training_run_wiring_module()\n        lokr_node = load_training_lokr_wiring_module()\n\n        training_run_call_names = []\n        for node in ast.walk(training_run_node):\n            if isinstance(node, ast.Call):\n                name = call_name(node.func)\n                if name:\n                    training_run_call_names.append(name)\n\n        lokr_call_names = []\n        lokr_attribute_names = []\n        for node in ast.walk(lokr_node):\n            if isinstance(node, ast.Call):\n                name = call_name(node.func)\n                if name:\n                    lokr_call_names.append(name)\n            if isinstance(node, ast.Attribute):\n                lokr_attribute_names.append(node.attr)\n\n        self.assertIn(\"start_training\", training_run_call_names)\n        self.assertIn(\"register_lokr_training_handlers\", training_run_call_names)\n        self.assertIn(\"start_lokr_training\", lokr_call_names)\n        self.assertIn(\"stop_training\", lokr_attribute_names)\n\n    def test_training_dataset_builder_wiring_calls_expected_handlers(self):\n        \"\"\"Dataset-builder wiring should call scan/label/edit/settings/save handlers.\"\"\"\n\n        wiring_node = load_training_dataset_builder_wiring_module()\n        call_names = []\n        attribute_names = []\n        for node in ast.walk(wiring_node):\n            if isinstance(node, ast.Call):\n                name = call_name(node.func)\n                if name:\n                    call_names.append(name)\n            if isinstance(node, ast.Attribute):\n                attribute_names.append(node.attr)\n\n        self.assertIn(\"scan_directory\", call_names)\n        self.assertIn(\"auto_label_all\", call_names)\n        self.assertIn(\"save_sample_edit\", attribute_names)\n        self.assertIn(\"update_settings\", attribute_names)\n        self.assertIn(\"save_dataset\", attribute_names)\n\n    def test_training_dataset_preprocess_wiring_calls_expected_handlers(self):\n        \"\"\"Dataset/preprocess wiring should call existing training handler entry points.\"\"\"\n\n        wiring_node = load_training_dataset_preprocess_wiring_module()\n        call_names = []\n        attribute_names = []\n        for node in ast.walk(wiring_node):\n            if isinstance(node, ast.Call):\n                name = call_name(node.func)\n                if name:\n                    call_names.append(name)\n            if isinstance(node, ast.Attribute):\n                attribute_names.append(node.attr)\n\n        self.assertIn(\"load_existing_dataset_for_preprocess\", attribute_names)\n        self.assertIn(\"preprocess_dataset\", call_names)\n\n\nif __name__ == \"__main__\":\n    unittest.main()\n"
  },
  {
    "path": "acestep/ui/gradio/events/wiring/docstring_coverage_test.py",
    "content": "\"\"\"Docstring coverage tests for decomposed event-wiring modules.\"\"\"\n\nimport ast\nfrom pathlib import Path\nimport unittest\n\n\n_MODULE_PATHS = [\n    Path(__file__).resolve().parents[1] / \"__init__.py\",\n    Path(__file__).resolve().with_name(\"generation_metadata_file_wiring.py\"),\n    Path(__file__).resolve().with_name(\"results_display_wiring.py\"),\n    Path(__file__).resolve().with_name(\"training_dataset_builder_wiring.py\"),\n    Path(__file__).resolve().with_name(\"training_dataset_preprocess_wiring.py\"),\n    Path(__file__).resolve().with_name(\"training_run_wiring.py\"),\n    Path(__file__).resolve().with_name(\"training_lokr_wiring.py\"),\n]\n\n\ndef _collect_nodes_missing_docstrings(module: ast.Module) -> list[str]:\n    \"\"\"Return qualified names for functions/classes missing docstrings.\"\"\"\n\n    missing: list[str] = []\n\n    def visit(node: ast.AST, prefix: str = \"\") -> None:\n        for child in ast.iter_child_nodes(node):\n            if isinstance(child, (ast.FunctionDef, ast.AsyncFunctionDef, ast.ClassDef)):\n                name = f\"{prefix}{child.name}\"\n                if ast.get_docstring(child) is None:\n                    missing.append(name)\n                visit(child, f\"{name}.\")\n            else:\n                visit(child, prefix)\n\n    visit(module)\n    return missing\n\n\nclass DocstringCoverageTests(unittest.TestCase):\n    \"\"\"Ensure decomposed event-wiring modules keep full docstring coverage.\"\"\"\n\n    def test_module_and_symbol_docstrings_are_present(self):\n        \"\"\"Each target module and all nested defs/classes should have docstrings.\"\"\"\n\n        failures: list[str] = []\n        for module_path in _MODULE_PATHS:\n            source = module_path.read_text(encoding=\"utf-8\")\n            tree = ast.parse(source)\n            try:\n                module_name = str(module_path.relative_to(Path.cwd()))\n            except ValueError:\n                module_name = module_path.name\n            if ast.get_docstring(tree) is None:\n                failures.append(f\"{module_name}: <module>\")\n            for symbol in _collect_nodes_missing_docstrings(tree):\n                failures.append(f\"{module_name}: {symbol}\")\n\n        self.assertEqual(failures, [], f\"Missing docstrings: {failures}\")\n\n\nif __name__ == \"__main__\":\n    unittest.main()\n"
  },
  {
    "path": "acestep/ui/gradio/events/wiring/generation_batch_navigation_wiring.py",
    "content": "\"\"\"Generation batch navigation event wiring helpers.\n\nThis module contains previous/next batch navigation wiring for generated\nresults and background next-batch preparation.\n\"\"\"\n\nfrom typing import Any\n\nfrom .. import results_handlers as res_h\nfrom .context import GenerationWiringContext\n\n\ndef _build_navigation_outputs(results_section: dict[str, Any], include_next_status: bool) -> list[Any]:\n    \"\"\"Build ordered outputs for previous/next batch navigation callbacks.\n\n    Args:\n        results_section (dict[str, Any]): Results component map containing\n            generated audio outputs (`generated_audio_1..8`,\n            `generated_audio_batch`), navigation/status fields\n            (`generation_info`, `current_batch_index`, `batch_indicator`,\n            `prev_batch_btn`, `next_batch_btn`, `status_output`,\n            optional `next_batch_status`), plus score/code/LRC/details slots\n            (`score_display_1..8`, `codes_display_1..8`, `lrc_display_1..8`,\n            `details_accordion_1..8`) and `restore_params_btn`.\n        include_next_status (bool): Whether to include `next_batch_status` in\n            the navigation output contract.\n\n    Returns:\n        list[Any]: Ordered Gradio outputs used by batch navigation handlers.\n    \"\"\"\n\n    outputs = [\n        results_section[\"generated_audio_1\"],\n        results_section[\"generated_audio_2\"],\n        results_section[\"generated_audio_3\"],\n        results_section[\"generated_audio_4\"],\n        results_section[\"generated_audio_5\"],\n        results_section[\"generated_audio_6\"],\n        results_section[\"generated_audio_7\"],\n        results_section[\"generated_audio_8\"],\n        results_section[\"generated_audio_batch\"],\n        results_section[\"generation_info\"],\n        results_section[\"current_batch_index\"],\n        results_section[\"batch_indicator\"],\n        results_section[\"prev_batch_btn\"],\n        results_section[\"next_batch_btn\"],\n        results_section[\"status_output\"],\n    ]\n    if include_next_status:\n        outputs.append(results_section[\"next_batch_status\"])\n    outputs.extend(\n        [\n            results_section[\"score_display_1\"],\n            results_section[\"score_display_2\"],\n            results_section[\"score_display_3\"],\n            results_section[\"score_display_4\"],\n            results_section[\"score_display_5\"],\n            results_section[\"score_display_6\"],\n            results_section[\"score_display_7\"],\n            results_section[\"score_display_8\"],\n            results_section[\"codes_display_1\"],\n            results_section[\"codes_display_2\"],\n            results_section[\"codes_display_3\"],\n            results_section[\"codes_display_4\"],\n            results_section[\"codes_display_5\"],\n            results_section[\"codes_display_6\"],\n            results_section[\"codes_display_7\"],\n            results_section[\"codes_display_8\"],\n            results_section[\"lrc_display_1\"],\n            results_section[\"lrc_display_2\"],\n            results_section[\"lrc_display_3\"],\n            results_section[\"lrc_display_4\"],\n            results_section[\"lrc_display_5\"],\n            results_section[\"lrc_display_6\"],\n            results_section[\"lrc_display_7\"],\n            results_section[\"lrc_display_8\"],\n            results_section[\"details_accordion_1\"],\n            results_section[\"details_accordion_2\"],\n            results_section[\"details_accordion_3\"],\n            results_section[\"details_accordion_4\"],\n            results_section[\"details_accordion_5\"],\n            results_section[\"details_accordion_6\"],\n            results_section[\"details_accordion_7\"],\n            results_section[\"details_accordion_8\"],\n            results_section[\"restore_params_btn\"],\n        ]\n    )\n    return outputs\n\n\ndef _build_capture_current_params_inputs(generation_section: dict[str, Any]) -> list[Any]:\n    \"\"\"Build ordered generation-control inputs captured before next-batch navigation.\n\n    Args:\n        generation_section (dict[str, Any]): Generation component map containing\n            core prompt/music controls (`captions`, `lyrics`, `bpm`,\n            `key_scale`, `inference_steps`, `guidance_scale`), seed/reference\n            controls (`random_seed_checkbox`, `seed`, `reference_audio`,\n            `batch_size_input`, `audio_format`), LM/COT controls\n            (`lm_temperature`, `lm_cfg_scale`, `lm_top_k`, `lm_top_p`,\n            `lm_negative_prompt`, `use_cot_metas`, `use_cot_caption`,\n            `use_cot_language`), automation controls\n            (`auto_score`, `auto_lrc`, `score_scale`), and normalization/latent\n            controls (`enable_normalization`, `normalization_db`,\n            `latent_shift`, `latent_rescale`).\n\n    Returns:\n        list[Any]: Ordered generation control values used to preserve and\n        restore generation state when navigating batches.\n    \"\"\"\n\n    return [\n        generation_section[\"captions\"],\n        generation_section[\"lyrics\"],\n        generation_section[\"bpm\"],\n        generation_section[\"key_scale\"],\n        generation_section[\"time_signature\"],\n        generation_section[\"vocal_language\"],\n        generation_section[\"inference_steps\"],\n        generation_section[\"guidance_scale\"],\n        generation_section[\"random_seed_checkbox\"],\n        generation_section[\"seed\"],\n        generation_section[\"reference_audio\"],\n        generation_section[\"audio_duration\"],\n        generation_section[\"batch_size_input\"],\n        generation_section[\"src_audio\"],\n        generation_section[\"text2music_audio_code_string\"],\n        generation_section[\"repainting_start\"],\n        generation_section[\"repainting_end\"],\n        generation_section[\"instruction_display_gen\"],\n        generation_section[\"audio_cover_strength\"],\n        generation_section[\"cover_noise_strength\"],\n        generation_section[\"task_type\"],\n        generation_section[\"use_adg\"],\n        generation_section[\"cfg_interval_start\"],\n        generation_section[\"cfg_interval_end\"],\n        generation_section[\"shift\"],\n        generation_section[\"infer_method\"],\n        generation_section[\"custom_timesteps\"],\n        generation_section[\"audio_format\"],\n        generation_section[\"lm_temperature\"],\n        generation_section[\"think_checkbox\"],\n        generation_section[\"lm_cfg_scale\"],\n        generation_section[\"lm_top_k\"],\n        generation_section[\"lm_top_p\"],\n        generation_section[\"lm_negative_prompt\"],\n        generation_section[\"use_cot_metas\"],\n        generation_section[\"use_cot_caption\"],\n        generation_section[\"use_cot_language\"],\n        generation_section[\"constrained_decoding_debug\"],\n        generation_section[\"allow_lm_batch\"],\n        generation_section[\"auto_score\"],\n        generation_section[\"auto_lrc\"],\n        generation_section[\"score_scale\"],\n        generation_section[\"lm_batch_chunk_size\"],\n        generation_section[\"track_name\"],\n        generation_section[\"complete_track_classes\"],\n        generation_section[\"enable_normalization\"],\n        generation_section[\"normalization_db\"],\n        generation_section[\"fade_in_duration\"],\n        generation_section[\"fade_out_duration\"],\n        generation_section[\"latent_shift\"],\n        generation_section[\"latent_rescale\"],\n    ]\n\n\ndef register_generation_batch_navigation_handlers(context: GenerationWiringContext) -> None:\n    \"\"\"Register previous/next batch navigation and background pre-generation wiring.\n\n    Args:\n        context (GenerationWiringContext): Shared generation wiring context used\n            by `register_generation_batch_navigation_handlers`; reads\n            `generation_section`, `results_section`, `dit_handler`, and\n            `llm_handler` to bind Gradio events.\n\n    Returns:\n        None: Registers click-chain handlers in-place on batch navigation\n        components.\n\n    Raises:\n        KeyError: If required component keys are missing from context maps.\n    \"\"\"\n\n    generation_section = context.generation_section\n    results_section = context.results_section\n    dit_handler = context.dit_handler\n    llm_handler = context.llm_handler\n\n    prev_navigation_outputs = _build_navigation_outputs(results_section, include_next_status=False)\n    next_navigation_outputs = _build_navigation_outputs(results_section, include_next_status=True)\n\n    results_section[\"prev_batch_btn\"].click(\n        fn=res_h.navigate_to_previous_batch,\n        inputs=[\n            results_section[\"current_batch_index\"],\n            results_section[\"batch_queue\"],\n        ],\n        outputs=prev_navigation_outputs,\n    )\n\n    results_section[\"next_batch_btn\"].click(\n        fn=res_h.capture_current_params,\n        inputs=_build_capture_current_params_inputs(generation_section),\n        outputs=[results_section[\"generation_params_state\"]],\n    ).then(\n        fn=res_h.navigate_to_next_batch,\n        inputs=[\n            generation_section[\"autogen_checkbox\"],\n            results_section[\"current_batch_index\"],\n            results_section[\"total_batches\"],\n            results_section[\"batch_queue\"],\n        ],\n        outputs=next_navigation_outputs,\n    ).then(\n        fn=lambda *args: res_h.generate_next_batch_background(dit_handler, llm_handler, *args),\n        inputs=[\n            generation_section[\"autogen_checkbox\"],\n            results_section[\"generation_params_state\"],\n            results_section[\"current_batch_index\"],\n            results_section[\"total_batches\"],\n            results_section[\"batch_queue\"],\n            results_section[\"is_format_caption_state\"],\n        ],\n        outputs=[\n            results_section[\"batch_queue\"],\n            results_section[\"total_batches\"],\n            results_section[\"next_batch_status\"],\n            results_section[\"next_batch_btn\"],\n        ],\n    )\n"
  },
  {
    "path": "acestep/ui/gradio/events/wiring/generation_metadata_file_wiring.py",
    "content": "\"\"\"Generation metadata file-load wiring helpers.\"\"\"\n\nfrom typing import Any, Sequence\n\nfrom .. import generation_handlers as gen_h\nfrom .context import GenerationWiringContext\n\n\n_LOAD_METADATA_GENERATION_OUTPUT_KEYS = (\n    \"task_type\",\n    \"captions\",\n    \"lyrics\",\n    \"vocal_language\",\n    \"bpm\",\n    \"key_scale\",\n    \"time_signature\",\n    \"audio_duration\",\n    \"batch_size_input\",\n    \"inference_steps\",\n    \"guidance_scale\",\n    \"seed\",\n    \"random_seed_checkbox\",\n    \"use_adg\",\n    \"cfg_interval_start\",\n    \"cfg_interval_end\",\n    \"shift\",\n    \"infer_method\",\n    \"custom_timesteps\",\n    \"audio_format\",\n    \"lm_temperature\",\n    \"lm_cfg_scale\",\n    \"lm_top_k\",\n    \"lm_top_p\",\n    \"lm_negative_prompt\",\n    \"use_cot_metas\",\n    \"use_cot_caption\",\n    \"use_cot_language\",\n    \"audio_cover_strength\",\n    \"cover_noise_strength\",\n    \"think_checkbox\",\n    \"text2music_audio_code_string\",\n    \"repainting_start\",\n    \"repainting_end\",\n    \"track_name\",\n    \"complete_track_classes\",\n    \"instrumental_checkbox\",\n)\n\n\ndef _build_load_metadata_outputs(context: GenerationWiringContext) -> list[Any]:\n    \"\"\"Return ordered outputs for the metadata file-load upload handler.\"\"\"\n\n    generation_section = context.generation_section\n    results_section = context.results_section\n    outputs = [\n        generation_section[key] for key in _LOAD_METADATA_GENERATION_OUTPUT_KEYS\n    ]\n    outputs.append(results_section[\"is_format_caption_state\"])\n    return outputs\n\n\ndef register_generation_metadata_file_handlers(\n    context: GenerationWiringContext,\n    *,\n    auto_checkbox_inputs: Sequence[Any],\n    auto_checkbox_outputs: Sequence[Any],\n) -> None:\n    \"\"\"Register metadata load-file upload and auto-checkbox sync handlers.\"\"\"\n\n    generation_section = context.generation_section\n    llm_handler = context.llm_handler\n\n    generation_section[\"load_file\"].upload(\n        fn=lambda file_obj: gen_h.load_metadata(file_obj, llm_handler),\n        inputs=[generation_section[\"load_file\"]],\n        outputs=_build_load_metadata_outputs(context),\n    ).then(\n        fn=gen_h.uncheck_auto_for_populated_fields,\n        inputs=list(auto_checkbox_inputs),\n        outputs=list(auto_checkbox_outputs),\n    )\n"
  },
  {
    "path": "acestep/ui/gradio/events/wiring/generation_metadata_file_wiring_test.py",
    "content": "\"\"\"Unit tests for generation metadata file wiring contracts.\"\"\"\n\nimport ast\nfrom pathlib import Path\nimport unittest\n\ntry:\n    from .ast_test_utils import load_module_ast\nexcept ImportError:  # pragma: no cover - supports direct file execution\n    from ast_test_utils import load_module_ast\n\n\n_WIRING_PATH = Path(__file__).with_name(\"generation_metadata_file_wiring.py\")\n\n_EXPECTED_METADATA_KEYS = [\n    \"task_type\",\n    \"captions\",\n    \"lyrics\",\n    \"vocal_language\",\n    \"bpm\",\n    \"key_scale\",\n    \"time_signature\",\n    \"audio_duration\",\n    \"batch_size_input\",\n    \"inference_steps\",\n    \"guidance_scale\",\n    \"seed\",\n    \"random_seed_checkbox\",\n    \"use_adg\",\n    \"cfg_interval_start\",\n    \"cfg_interval_end\",\n    \"shift\",\n    \"infer_method\",\n    \"custom_timesteps\",\n    \"audio_format\",\n    \"lm_temperature\",\n    \"lm_cfg_scale\",\n    \"lm_top_k\",\n    \"lm_top_p\",\n    \"lm_negative_prompt\",\n    \"use_cot_metas\",\n    \"use_cot_caption\",\n    \"use_cot_language\",\n    \"audio_cover_strength\",\n    \"cover_noise_strength\",\n    \"think_checkbox\",\n    \"text2music_audio_code_string\",\n    \"repainting_start\",\n    \"repainting_end\",\n    \"track_name\",\n    \"complete_track_classes\",\n    \"instrumental_checkbox\",\n]\n\ndef _tuple_string_values(node: ast.AST) -> list[str]:\n    \"\"\"Return string literal values from a tuple/list literal node.\"\"\"\n\n    if not isinstance(node, (ast.Tuple, ast.List)):\n        raise AssertionError(\"Expected tuple/list node\")\n    values = []\n    for element in node.elts:\n        if not isinstance(element, ast.Constant) or not isinstance(element.value, str):\n            raise AssertionError(\"Expected string literal\")\n        values.append(element.value)\n    return values\n\n\nclass GenerationMetadataFileWiringTests(unittest.TestCase):\n    \"\"\"Verify metadata file-load wiring ordering and handler contracts.\"\"\"\n\n    def test_metadata_output_key_contract_order_is_stable(self):\n        \"\"\"The metadata output key tuple should match the expected UI ordering.\"\"\"\n\n        module = load_module_ast(_WIRING_PATH)\n        for node in module.body:\n            if isinstance(node, ast.Assign):\n                for target in node.targets:\n                    if isinstance(target, ast.Name) and target.id == \"_LOAD_METADATA_GENERATION_OUTPUT_KEYS\":\n                        self.assertEqual(_tuple_string_values(node.value), _EXPECTED_METADATA_KEYS)\n                        return\n        self.fail(\"_LOAD_METADATA_GENERATION_OUTPUT_KEYS not found\")\n\n    def test_build_outputs_appends_format_caption_state_last(self):\n        \"\"\"build outputs helper should append is_format_caption_state at the tail.\"\"\"\n\n        module = load_module_ast(_WIRING_PATH)\n        for node in module.body:\n            if not isinstance(node, ast.FunctionDef) or node.name != \"_build_load_metadata_outputs\":\n                continue\n            for inner in ast.walk(node):\n                if isinstance(inner, ast.Call) and isinstance(inner.func, ast.Attribute):\n                    if inner.func.attr == \"append\" and inner.args:\n                        arg = inner.args[0]\n                        if isinstance(arg, ast.Subscript) and isinstance(arg.slice, ast.Constant):\n                            self.assertEqual(arg.slice.value, \"is_format_caption_state\")\n                            return\n        self.fail(\"append(results_section['is_format_caption_state']) not found\")\n\n    def test_register_function_references_expected_generation_handlers(self):\n        \"\"\"Register helper should reference load-metadata and auto-uncheck handlers.\"\"\"\n\n        module = load_module_ast(_WIRING_PATH)\n        attrs = []\n        for node in ast.walk(module):\n            if isinstance(node, ast.Attribute):\n                attrs.append(node.attr)\n        self.assertIn(\"load_metadata\", attrs)\n        self.assertIn(\"uncheck_auto_for_populated_fields\", attrs)\n\n\nif __name__ == \"__main__\":\n    unittest.main()\n"
  },
  {
    "path": "acestep/ui/gradio/events/wiring/generation_metadata_wiring.py",
    "content": "\"\"\"Generation metadata/text event wiring helpers.\n\nThis module contains wiring for source analysis, transcribe/sample operations,\nand caption/lyrics formatting flows.\n\"\"\"\n\nfrom typing import Any, Sequence\n\nfrom .. import generation_handlers as gen_h\nfrom .context import GenerationWiringContext\nfrom .generation_text_format_wiring import register_generation_text_format_handlers\n\n\ndef register_generation_metadata_handlers(\n    context: GenerationWiringContext,\n    auto_checkbox_inputs: Sequence[Any],\n    auto_checkbox_outputs: Sequence[Any],\n) -> None:\n    \"\"\"Register metadata and text-format generation handlers.\"\"\"\n\n    generation_section = context.generation_section\n    results_section = context.results_section\n    dit_handler = context.dit_handler\n    llm_handler = context.llm_handler\n\n    # ========== Audio Conversion (LM Codes Hints accordion in Custom mode) ==========\n    generation_section[\"convert_src_to_codes_btn\"].click(\n        fn=lambda src: gen_h.convert_src_audio_to_codes_wrapper(dit_handler, src),\n        inputs=[generation_section[\"lm_codes_audio_upload\"]],\n        outputs=[generation_section[\"text2music_audio_code_string\"]],\n    )\n\n    # ========== Analyze Source Audio (Remix/Repaint: convert to codes + transcribe) ==========\n    generation_section[\"analyze_btn\"].click(\n        fn=lambda src, debug: gen_h.analyze_src_audio(dit_handler, llm_handler, src, debug),\n        inputs=[\n            generation_section[\"src_audio\"],\n            generation_section[\"constrained_decoding_debug\"],\n        ],\n        outputs=[\n            generation_section[\"text2music_audio_code_string\"],\n            results_section[\"status_output\"],\n            generation_section[\"captions\"],\n            generation_section[\"lyrics\"],\n            generation_section[\"bpm\"],\n            generation_section[\"audio_duration\"],\n            generation_section[\"key_scale\"],\n            generation_section[\"vocal_language\"],\n            generation_section[\"time_signature\"],\n            results_section[\"is_format_caption_state\"],\n        ],\n    ).then(\n        fn=gen_h.uncheck_auto_for_populated_fields,\n        inputs=list(auto_checkbox_inputs),\n        outputs=list(auto_checkbox_outputs),\n    )\n\n    # ========== Instruction UI Updates ==========\n    for trigger in [\n        generation_section[\"task_type\"],\n        generation_section[\"track_name\"],\n        generation_section[\"complete_track_classes\"],\n        generation_section[\"reference_audio\"],\n    ]:\n        trigger.change(\n            fn=lambda *args: gen_h.update_instruction_ui(dit_handler, *args),\n            inputs=[\n                generation_section[\"task_type\"],\n                generation_section[\"track_name\"],\n                generation_section[\"complete_track_classes\"],\n                generation_section[\"init_llm_checkbox\"],\n                generation_section[\"reference_audio\"],\n            ],\n            outputs=[generation_section[\"instruction_display_gen\"]],\n        )\n\n    # Validate reference audio eagerly so users get immediate feedback on invalid files.\n    generation_section[\"reference_audio\"].change(\n        fn=lambda reference_audio: gen_h.validate_uploaded_audio_file(reference_audio, \"reference\"),\n        inputs=[generation_section[\"reference_audio\"]],\n        outputs=[generation_section[\"reference_audio\"]],\n    )\n\n    # ========== Sample/Transcribe Handlers ==========\n    generation_section[\"sample_btn\"].click(\n        fn=lambda task: gen_h.load_random_example(task, llm_handler) + (True,),\n        inputs=[generation_section[\"task_type\"]],\n        outputs=[\n            generation_section[\"captions\"],\n            generation_section[\"lyrics\"],\n            generation_section[\"think_checkbox\"],\n            generation_section[\"bpm\"],\n            generation_section[\"audio_duration\"],\n            generation_section[\"key_scale\"],\n            generation_section[\"vocal_language\"],\n            generation_section[\"time_signature\"],\n            results_section[\"is_format_caption_state\"],\n        ],\n    ).then(\n        fn=gen_h.uncheck_auto_for_populated_fields,\n        inputs=list(auto_checkbox_inputs),\n        outputs=list(auto_checkbox_outputs),\n    )\n\n    generation_section[\"text2music_audio_code_string\"].change(\n        fn=gen_h.update_transcribe_button_text,\n        inputs=[generation_section[\"text2music_audio_code_string\"]],\n        outputs=[generation_section[\"transcribe_btn\"]],\n    )\n\n    generation_section[\"transcribe_btn\"].click(\n        fn=lambda codes, debug: gen_h.transcribe_audio_codes(llm_handler, codes, debug),\n        inputs=[\n            generation_section[\"text2music_audio_code_string\"],\n            generation_section[\"constrained_decoding_debug\"],\n        ],\n        outputs=[\n            results_section[\"status_output\"],\n            generation_section[\"captions\"],\n            generation_section[\"lyrics\"],\n            generation_section[\"bpm\"],\n            generation_section[\"audio_duration\"],\n            generation_section[\"key_scale\"],\n            generation_section[\"vocal_language\"],\n            generation_section[\"time_signature\"],\n            results_section[\"is_format_caption_state\"],\n        ],\n    ).then(\n        fn=gen_h.uncheck_auto_for_populated_fields,\n        inputs=list(auto_checkbox_inputs),\n        outputs=list(auto_checkbox_outputs),\n    )\n\n    # ========== Reset Format Caption Flag ==========\n    for trigger in [\n        generation_section[\"captions\"],\n        generation_section[\"lyrics\"],\n        generation_section[\"bpm\"],\n        generation_section[\"key_scale\"],\n        generation_section[\"time_signature\"],\n        generation_section[\"vocal_language\"],\n        generation_section[\"audio_duration\"],\n    ]:\n        trigger.change(\n            fn=gen_h.reset_format_caption_flag,\n            inputs=[],\n            outputs=[results_section[\"is_format_caption_state\"]],\n        )\n\n    # ========== Instrumental Checkbox ==========\n    generation_section[\"instrumental_checkbox\"].change(\n        fn=gen_h.handle_instrumental_checkbox,\n        inputs=[\n            generation_section[\"instrumental_checkbox\"],\n            generation_section[\"lyrics\"],\n            generation_section[\"lyrics_before_instrumental\"],\n        ],\n        outputs=[\n            generation_section[\"lyrics\"],\n            generation_section[\"lyrics_before_instrumental\"],\n        ],\n    )\n\n    register_generation_text_format_handlers(\n        context,\n        auto_checkbox_inputs=auto_checkbox_inputs,\n        auto_checkbox_outputs=auto_checkbox_outputs,\n    )\n"
  },
  {
    "path": "acestep/ui/gradio/events/wiring/generation_mode_wiring.py",
    "content": "\"\"\"Generation mode and simple-mode event wiring helpers.\n\nThis module contains mode-switch and simple-mode related handlers to keep\n``events.__init__`` as a thin facade.\n\"\"\"\n\nfrom typing import Any, Sequence\n\nimport gradio as gr\n\nfrom .. import generation_handlers as gen_h\nfrom .context import GenerationWiringContext\n\n\ndef _on_repaint_mode_change(mode, current_strength, memory):\n    \"\"\"Update slider value and interactivity when repaint mode changes.\"\"\"\n    if mode == \"conservative\":\n        new_memory = current_strength if 0.0 < current_strength < 1.0 else memory\n        return gr.update(value=0.0, interactive=False), new_memory\n    if mode == \"aggressive\":\n        new_memory = current_strength if 0.0 < current_strength < 1.0 else memory\n        return gr.update(value=1.0, interactive=False), new_memory\n    return gr.update(value=memory, interactive=True), memory\n\n\ndef _on_repaint_strength_change(strength, current_mode):\n    \"\"\"Auto-switch mode when slider hits boundary values.\"\"\"\n    if strength == 0.0 and current_mode != \"conservative\":\n        return gr.update(value=\"conservative\"), gr.update(interactive=False)\n    if strength == 1.0 and current_mode != \"aggressive\":\n        return gr.update(value=\"aggressive\"), gr.update(interactive=False)\n    if current_mode != \"balanced\" and 0.0 < strength < 1.0:\n        return gr.update(value=\"balanced\"), gr.update(interactive=True)\n    return gr.skip(), gr.skip()\n\n\ndef register_generation_mode_handlers(\n    context: GenerationWiringContext,\n    mode_ui_outputs: Sequence[Any],\n    auto_checkbox_inputs: Sequence[Any],\n    auto_checkbox_outputs: Sequence[Any],\n) -> None:\n    \"\"\"Register generation mode and simple-mode handlers.\"\"\"\n\n    generation_section = context.generation_section\n    results_section = context.results_section\n    llm_handler = context.llm_handler\n\n    # Shared handler for mode-change and initial page load — extracted to\n    # avoid duplicating the lambda and to keep both call sites in sync.\n    def _handle_mode_change(mode: str, prev: str | None):\n        \"\"\"Proxy mode-change handling for both .change() and .load() events.\"\"\"\n        return gen_h.handle_generation_mode_change(mode, prev, llm_handler)\n\n    mode_change_inputs = [\n        generation_section[\"generation_mode\"],\n        generation_section[\"previous_generation_mode\"],\n    ]\n\n    # ========== Generation Mode Change ==========\n    generation_section[\"generation_mode\"].change(\n        fn=_handle_mode_change,\n        inputs=mode_change_inputs,\n        outputs=mode_ui_outputs,\n    )\n\n    # ========== Initial Mode State on Page Load ==========\n    # compute_mode_ui_updates() controls visibility for 44 mode-dependent UI\n    # components (think_checkbox, generate_btn_row, src_audio_row, etc.) but\n    # is only triggered via the .change() event above.  Gradio does not fire\n    # .change() for the initial value assignment, so mode-dependent state is\n    # never applied on first render — causing the Think checkbox (and\n    # potentially other components) to be missing on page load.\n    # This .load() event fires once on page load to initialize all\n    # mode-dependent UI state using the same handler.\n    context.demo.load(\n        fn=_handle_mode_change,\n        inputs=mode_change_inputs,\n        outputs=mode_ui_outputs,\n    )\n\n    # ========== Extract Mode: Auto-fill caption from track_name ==========\n    generation_section[\"track_name\"].change(\n        fn=gen_h.handle_extract_track_name_change,\n        inputs=[\n            generation_section[\"track_name\"],\n            generation_section[\"generation_mode\"],\n        ],\n        outputs=[generation_section[\"captions\"]],\n    )\n\n    # Validate source audio eagerly so users get immediate feedback on invalid files.\n    generation_section[\"src_audio\"].change(\n        fn=lambda src_audio: gen_h.validate_uploaded_audio_file(src_audio, \"source\"),\n        inputs=[generation_section[\"src_audio\"]],\n        outputs=[generation_section[\"src_audio\"]],\n    )\n\n    # ========== Extract/Lego Mode: Auto-fill audio_duration from src_audio ==========\n    generation_section[\"src_audio\"].change(\n        fn=gen_h.handle_extract_src_audio_change,\n        inputs=[\n            generation_section[\"src_audio\"],\n            generation_section[\"generation_mode\"],\n        ],\n        outputs=[generation_section[\"audio_duration\"]],\n    )\n\n    # ========== Simple Mode Instrumental Checkbox ==========\n    generation_section[\"simple_instrumental_checkbox\"].change(\n        fn=gen_h.handle_simple_instrumental_change,\n        inputs=[generation_section[\"simple_instrumental_checkbox\"]],\n        outputs=[generation_section[\"simple_vocal_language\"]],\n    )\n\n    # ========== Random Description Button ==========\n    generation_section[\"random_desc_btn\"].click(\n        fn=gen_h.load_random_simple_description,\n        inputs=[],\n        outputs=[\n            generation_section[\"simple_query_input\"],\n            generation_section[\"simple_instrumental_checkbox\"],\n            generation_section[\"simple_vocal_language\"],\n        ],\n    )\n\n    # ========== Create Sample Button (Simple Mode) ==========\n    generation_section[\"create_sample_btn\"].click(\n        fn=lambda query, instrumental, vocal_lang, temp, top_k, top_p, debug: gen_h.handle_create_sample(\n            llm_handler, query, instrumental, vocal_lang, temp, top_k, top_p, debug\n        ),\n        inputs=[\n            generation_section[\"simple_query_input\"],\n            generation_section[\"simple_instrumental_checkbox\"],\n            generation_section[\"simple_vocal_language\"],\n            generation_section[\"lm_temperature\"],\n            generation_section[\"lm_top_k\"],\n            generation_section[\"lm_top_p\"],\n            generation_section[\"constrained_decoding_debug\"],\n        ],\n        outputs=[\n            generation_section[\"captions\"],\n            generation_section[\"lyrics\"],\n            generation_section[\"bpm\"],\n            generation_section[\"audio_duration\"],\n            generation_section[\"key_scale\"],\n            generation_section[\"vocal_language\"],\n            generation_section[\"simple_vocal_language\"],\n            generation_section[\"time_signature\"],\n            generation_section[\"instrumental_checkbox\"],\n            generation_section[\"generate_btn\"],\n            generation_section[\"simple_sample_created\"],\n            generation_section[\"think_checkbox\"],\n            results_section[\"is_format_caption_state\"],\n            results_section[\"status_output\"],\n            generation_section[\"generation_mode\"],\n        ],\n    ).then(\n        fn=gen_h.uncheck_auto_for_populated_fields,\n        inputs=list(auto_checkbox_inputs),\n        outputs=list(auto_checkbox_outputs),\n    )\n\n    # ========== Repaint Mode <-> Strength Bidirectional Sync ==========\n    generation_section[\"repaint_mode\"].change(\n        fn=_on_repaint_mode_change,\n        inputs=[\n            generation_section[\"repaint_mode\"],\n            generation_section[\"repaint_strength\"],\n            generation_section[\"repaint_strength_memory\"],\n        ],\n        outputs=[\n            generation_section[\"repaint_strength\"],\n            generation_section[\"repaint_strength_memory\"],\n        ],\n    )\n    generation_section[\"repaint_strength\"].change(\n        fn=_on_repaint_strength_change,\n        inputs=[\n            generation_section[\"repaint_strength\"],\n            generation_section[\"repaint_mode\"],\n        ],\n        outputs=[\n            generation_section[\"repaint_mode\"],\n            generation_section[\"repaint_strength\"],\n        ],\n    )\n"
  },
  {
    "path": "acestep/ui/gradio/events/wiring/generation_run_wiring.py",
    "content": "\"\"\"Generation run event wiring helpers.\n\nThis module isolates the primary generation-button click chain that clears\noutputs, runs batched generation, and schedules background pre-generation.\n\"\"\"\n\nfrom .. import results_handlers as res_h\nfrom .context import GenerationWiringContext\n\n\ndef register_generation_run_handlers(context: GenerationWiringContext) -> None:\n    \"\"\"Register batched generation-run event wiring for audio inference.\n\n    Args:\n        context (GenerationWiringContext): Shared wiring context used by\n        `register_generation_run_handlers`; reads `generation_section`,\n        `results_section`, `dit_handler`, and `llm_handler` to bind the\n        generate-button click chain.\n\n    Returns:\n        None: Registers click/then handlers in-place on generation components.\n    \"\"\"\n\n    generation_section = context.generation_section\n    results_section = context.results_section\n    dit_handler = context.dit_handler\n    llm_handler = context.llm_handler\n\n    def generation_wrapper(*args):\n        \"\"\"Proxy passthrough to `res_h.generate_with_batch_management`.\n\n        Args:\n            *args (Any): Positional passthrough inputs forwarded unchanged to\n                `res_h.generate_with_batch_management(dit_handler, llm_handler, *args)`.\n\n        Yields:\n            Any: Streamed generation updates yielded by\n            `res_h.generate_with_batch_management`.\n\n        Raises:\n            Exception: Propagates exceptions raised by\n            `res_h.generate_with_batch_management`.\n        \"\"\"\n\n        yield from res_h.generate_with_batch_management(dit_handler, llm_handler, *args)\n\n    generation_section[\"generate_btn\"].click(\n        fn=res_h.clear_audio_outputs_for_new_generation,\n        outputs=[\n            results_section[\"generated_audio_1\"],\n            results_section[\"generated_audio_2\"],\n            results_section[\"generated_audio_3\"],\n            results_section[\"generated_audio_4\"],\n            results_section[\"generated_audio_5\"],\n            results_section[\"generated_audio_6\"],\n            results_section[\"generated_audio_7\"],\n            results_section[\"generated_audio_8\"],\n            results_section[\"generated_audio_batch\"],\n        ],\n    ).then(\n        fn=generation_wrapper,\n        inputs=[\n            generation_section[\"captions\"],\n            generation_section[\"lyrics\"],\n            generation_section[\"bpm\"],\n            generation_section[\"key_scale\"],\n            generation_section[\"time_signature\"],\n            generation_section[\"vocal_language\"],\n            generation_section[\"inference_steps\"],\n            generation_section[\"guidance_scale\"],\n            generation_section[\"random_seed_checkbox\"],\n            generation_section[\"seed\"],\n            generation_section[\"reference_audio\"],\n            generation_section[\"audio_duration\"],\n            generation_section[\"batch_size_input\"],\n            generation_section[\"src_audio\"],\n            generation_section[\"text2music_audio_code_string\"],\n            generation_section[\"repainting_start\"],\n            generation_section[\"repainting_end\"],\n            generation_section[\"instruction_display_gen\"],\n            generation_section[\"audio_cover_strength\"],\n            generation_section[\"cover_noise_strength\"],\n            generation_section[\"task_type\"],\n            generation_section[\"use_adg\"],\n            generation_section[\"cfg_interval_start\"],\n            generation_section[\"cfg_interval_end\"],\n            generation_section[\"shift\"],\n            generation_section[\"infer_method\"],\n            generation_section[\"custom_timesteps\"],\n            generation_section[\"audio_format\"],\n            generation_section[\"lm_temperature\"],\n            generation_section[\"think_checkbox\"],\n            generation_section[\"lm_cfg_scale\"],\n            generation_section[\"lm_top_k\"],\n            generation_section[\"lm_top_p\"],\n            generation_section[\"lm_negative_prompt\"],\n            generation_section[\"use_cot_metas\"],\n            generation_section[\"use_cot_caption\"],\n            generation_section[\"use_cot_language\"],\n            results_section[\"is_format_caption_state\"],\n            generation_section[\"constrained_decoding_debug\"],\n            generation_section[\"allow_lm_batch\"],\n            generation_section[\"auto_score\"],\n            generation_section[\"auto_lrc\"],\n            generation_section[\"score_scale\"],\n            generation_section[\"lm_batch_chunk_size\"],\n            generation_section[\"track_name\"],\n            generation_section[\"complete_track_classes\"],\n            generation_section[\"enable_normalization\"],\n            generation_section[\"normalization_db\"],\n            generation_section[\"fade_in_duration\"],\n            generation_section[\"fade_out_duration\"],\n            generation_section[\"latent_shift\"],\n            generation_section[\"latent_rescale\"],\n            generation_section[\"repaint_mode\"],\n            generation_section[\"repaint_strength\"],\n            generation_section[\"autogen_checkbox\"],\n            results_section[\"current_batch_index\"],\n            results_section[\"total_batches\"],\n            results_section[\"batch_queue\"],\n            results_section[\"generation_params_state\"],\n        ],\n        outputs=[\n            results_section[\"generated_audio_1\"],\n            results_section[\"generated_audio_2\"],\n            results_section[\"generated_audio_3\"],\n            results_section[\"generated_audio_4\"],\n            results_section[\"generated_audio_5\"],\n            results_section[\"generated_audio_6\"],\n            results_section[\"generated_audio_7\"],\n            results_section[\"generated_audio_8\"],\n            results_section[\"generated_audio_batch\"],\n            results_section[\"generation_info\"],\n            results_section[\"status_output\"],\n            generation_section[\"seed\"],\n            results_section[\"score_display_1\"],\n            results_section[\"score_display_2\"],\n            results_section[\"score_display_3\"],\n            results_section[\"score_display_4\"],\n            results_section[\"score_display_5\"],\n            results_section[\"score_display_6\"],\n            results_section[\"score_display_7\"],\n            results_section[\"score_display_8\"],\n            results_section[\"codes_display_1\"],\n            results_section[\"codes_display_2\"],\n            results_section[\"codes_display_3\"],\n            results_section[\"codes_display_4\"],\n            results_section[\"codes_display_5\"],\n            results_section[\"codes_display_6\"],\n            results_section[\"codes_display_7\"],\n            results_section[\"codes_display_8\"],\n            results_section[\"details_accordion_1\"],\n            results_section[\"details_accordion_2\"],\n            results_section[\"details_accordion_3\"],\n            results_section[\"details_accordion_4\"],\n            results_section[\"details_accordion_5\"],\n            results_section[\"details_accordion_6\"],\n            results_section[\"details_accordion_7\"],\n            results_section[\"details_accordion_8\"],\n            results_section[\"lrc_display_1\"],\n            results_section[\"lrc_display_2\"],\n            results_section[\"lrc_display_3\"],\n            results_section[\"lrc_display_4\"],\n            results_section[\"lrc_display_5\"],\n            results_section[\"lrc_display_6\"],\n            results_section[\"lrc_display_7\"],\n            results_section[\"lrc_display_8\"],\n            results_section[\"lm_metadata_state\"],\n            results_section[\"is_format_caption_state\"],\n            results_section[\"current_batch_index\"],\n            results_section[\"total_batches\"],\n            results_section[\"batch_queue\"],\n            results_section[\"generation_params_state\"],\n            results_section[\"batch_indicator\"],\n            results_section[\"prev_batch_btn\"],\n            results_section[\"next_batch_btn\"],\n            results_section[\"next_batch_status\"],\n            results_section[\"restore_params_btn\"],\n        ],\n    ).then(\n        fn=lambda *args: res_h.generate_next_batch_background(dit_handler, llm_handler, *args),\n        inputs=[\n            generation_section[\"autogen_checkbox\"],\n            results_section[\"generation_params_state\"],\n            results_section[\"current_batch_index\"],\n            results_section[\"total_batches\"],\n            results_section[\"batch_queue\"],\n            results_section[\"is_format_caption_state\"],\n        ],\n        outputs=[\n            results_section[\"batch_queue\"],\n            results_section[\"total_batches\"],\n            results_section[\"next_batch_status\"],\n            results_section[\"next_batch_btn\"],\n        ],\n    )\n"
  },
  {
    "path": "acestep/ui/gradio/events/wiring/generation_service_wiring.py",
    "content": "\"\"\"Generation service-layer event wiring helpers.\n\nThis module contains wiring related to service initialization, LoRA controls,\nauto-checkbox controls, and visibility updates for generation components.\n\"\"\"\n\nfrom typing import Any\n\nimport gradio as gr\n\nfrom .. import generation_handlers as gen_h\nfrom ...i18n import get_i18n, reset_language_context, set_language_context\nfrom .context import (\n    GenerationWiringContext,\n    build_auto_checkbox_inputs,\n    build_auto_checkbox_outputs,\n)\n\n\ndef register_generation_service_handlers(\n    context: GenerationWiringContext,\n) -> tuple[list[Any], list[Any]]:\n    \"\"\"Register generation service/init handlers and return auto-checkbox lists.\"\"\"\n\n    dataset_section = context.dataset_section\n    generation_section = context.generation_section\n    results_section = context.results_section\n    dit_handler = context.dit_handler\n    llm_handler = context.llm_handler\n    dataset_handler = context.dataset_handler\n\n    # ========== Dataset Handlers ==========\n    dataset_section[\"import_dataset_btn\"].click(\n        fn=dataset_handler.import_dataset,\n        inputs=[dataset_section[\"dataset_type\"]],\n        outputs=[dataset_section[\"data_status\"]],\n    )\n\n    # ========== Service Initialization ==========\n    generation_section[\"refresh_btn\"].click(\n        fn=lambda: gen_h.refresh_checkpoints(dit_handler),\n        outputs=[generation_section[\"checkpoint_dropdown\"]],\n    )\n\n    generation_section[\"language_dropdown\"].change(\n        fn=lambda language: _apply_runtime_language(language),\n        inputs=[generation_section[\"language_dropdown\"]],\n        outputs=[generation_section[\"language_dropdown\"]],\n    )\n\n    generation_section[\"config_path\"].change(\n        fn=gen_h.update_model_type_settings,\n        inputs=[generation_section[\"config_path\"], generation_section[\"generation_mode\"]],\n        outputs=[\n            generation_section[\"inference_steps\"],\n            generation_section[\"guidance_scale\"],\n            generation_section[\"use_adg\"],\n            generation_section[\"shift\"],\n            generation_section[\"cfg_interval_start\"],\n            generation_section[\"cfg_interval_end\"],\n            generation_section[\"task_type\"],\n            generation_section[\"generation_mode\"],\n            generation_section[\"init_llm_checkbox\"],\n        ],\n    )\n\n    # ========== Tier Override ==========\n    generation_section[\"tier_dropdown\"].change(\n        fn=lambda tier: gen_h.on_tier_change(tier, llm_handler),\n        inputs=[generation_section[\"tier_dropdown\"]],\n        outputs=[\n            generation_section[\"offload_to_cpu_checkbox\"],\n            generation_section[\"offload_dit_to_cpu_checkbox\"],\n            generation_section[\"compile_model_checkbox\"],\n            generation_section[\"quantization_checkbox\"],\n            generation_section[\"backend_dropdown\"],\n            generation_section[\"lm_model_path\"],\n            generation_section[\"init_llm_checkbox\"],\n            generation_section[\"batch_size_input\"],\n            generation_section[\"audio_duration\"],\n            generation_section[\"gpu_info_display\"],\n        ],\n    )\n\n    generation_section[\"init_btn\"].click(\n        fn=lambda *args: gen_h.init_service_wrapper(dit_handler, llm_handler, *args),\n        inputs=[\n            generation_section[\"checkpoint_dropdown\"],\n            generation_section[\"config_path\"],\n            generation_section[\"device\"],\n            generation_section[\"init_llm_checkbox\"],\n            generation_section[\"lm_model_path\"],\n            generation_section[\"backend_dropdown\"],\n            generation_section[\"use_flash_attention_checkbox\"],\n            generation_section[\"offload_to_cpu_checkbox\"],\n            generation_section[\"offload_dit_to_cpu_checkbox\"],\n            generation_section[\"compile_model_checkbox\"],\n            generation_section[\"quantization_checkbox\"],\n            generation_section[\"mlx_dit_checkbox\"],\n            generation_section[\"generation_mode\"],\n            generation_section[\"batch_size_input\"],\n        ],\n        outputs=[\n            generation_section[\"init_status\"],\n            generation_section[\"generate_btn\"],\n            generation_section[\"service_config_accordion\"],\n            generation_section[\"inference_steps\"],\n            generation_section[\"guidance_scale\"],\n            generation_section[\"use_adg\"],\n            generation_section[\"shift\"],\n            generation_section[\"cfg_interval_start\"],\n            generation_section[\"cfg_interval_end\"],\n            generation_section[\"task_type\"],\n            generation_section[\"generation_mode\"],\n            generation_section[\"init_llm_checkbox\"],\n            generation_section[\"audio_duration\"],\n            generation_section[\"batch_size_input\"],\n            generation_section[\"think_checkbox\"],\n        ],\n    )\n\n    # ========== LoRA Handlers ==========\n    generation_section[\"load_lora_btn\"].click(\n        fn=dit_handler.load_lora,\n        inputs=[generation_section[\"lora_path\"]],\n        outputs=[generation_section[\"lora_status\"]],\n    ).then(\n        fn=lambda: gr.update(value=True),\n        outputs=[generation_section[\"use_lora_checkbox\"]],\n    )\n\n    generation_section[\"unload_lora_btn\"].click(\n        fn=dit_handler.unload_lora,\n        outputs=[generation_section[\"lora_status\"]],\n    ).then(\n        fn=lambda: gr.update(value=False),\n        outputs=[generation_section[\"use_lora_checkbox\"]],\n    )\n\n    generation_section[\"use_lora_checkbox\"].change(\n        fn=dit_handler.set_use_lora,\n        inputs=[generation_section[\"use_lora_checkbox\"]],\n        outputs=[generation_section[\"lora_status\"]],\n    )\n\n    generation_section[\"lora_scale_slider\"].change(\n        fn=dit_handler.set_lora_scale,\n        inputs=[generation_section[\"lora_scale_slider\"]],\n        outputs=[generation_section[\"lora_status\"]],\n    )\n\n    # ========== Auto Checkbox Handlers ==========\n    auto_field_map = {\n        \"bpm_auto\": (\"bpm\", \"bpm\"),\n        \"key_auto\": (\"key_scale\", \"key_scale\"),\n        \"timesig_auto\": (\"time_signature\", \"time_signature\"),\n        \"vocal_lang_auto\": (\"vocal_language\", \"vocal_language\"),\n        \"duration_auto\": (\"audio_duration\", \"audio_duration\"),\n    }\n    for auto_key, (field_name, comp_key) in auto_field_map.items():\n        generation_section[auto_key].change(\n            fn=lambda checked, fn=field_name: gen_h.on_auto_checkbox_change(checked, fn),\n            inputs=[generation_section[auto_key]],\n            outputs=[generation_section[comp_key]],\n        )\n\n    auto_checkbox_outputs = build_auto_checkbox_outputs(context)\n    auto_checkbox_inputs = build_auto_checkbox_inputs(context)\n\n    generation_section[\"reset_all_auto_btn\"].click(\n        fn=gen_h.reset_all_auto,\n        outputs=auto_checkbox_outputs,\n    )\n\n    # ========== UI Visibility Updates ==========\n    generation_section[\"init_llm_checkbox\"].change(\n        fn=gen_h.update_negative_prompt_visibility,\n        inputs=[generation_section[\"init_llm_checkbox\"]],\n        outputs=[generation_section[\"lm_negative_prompt\"]],\n    )\n\n    generation_section[\"batch_size_input\"].change(\n        fn=gen_h.update_audio_components_visibility,\n        inputs=[generation_section[\"batch_size_input\"]],\n        outputs=[\n            results_section[\"audio_col_1\"],\n            results_section[\"audio_col_2\"],\n            results_section[\"audio_col_3\"],\n            results_section[\"audio_col_4\"],\n            results_section[\"audio_row_5_8\"],\n            results_section[\"audio_col_5\"],\n            results_section[\"audio_col_6\"],\n            results_section[\"audio_col_7\"],\n            results_section[\"audio_col_8\"],\n        ],\n    )\n\n    return auto_checkbox_inputs, auto_checkbox_outputs\n\n\ndef _apply_runtime_language(language: str) -> dict[str, Any]:\n    \"\"\"Update i18n language at the Gradio request boundary.\n\n    Sets a per-request ``ContextVar`` so any ``t()`` calls within this\n    handler use *language*, then updates the shared instance default so\n    future requests without an explicit context inherit it.  The\n    ``ContextVar`` is reset on exit to avoid poisoning reused\n    thread-pool workers with a stale language value.\n\n    Args:\n        language: Selected UI language code from the language dropdown.\n\n    Returns:\n        A ``gr.update`` payload preserving the selected dropdown value.\n    \"\"\"\n    # Set ContextVar for this handler's scope.  No t() calls happen here\n    # today, but the pattern establishes the request-boundary convention\n    # for future handlers that adopt per-request language isolation.\n    token = set_language_context(language)\n    try:\n        get_i18n(language)\n        return gr.update(value=language)\n    finally:\n        reset_language_context(token)\n"
  },
  {
    "path": "acestep/ui/gradio/events/wiring/generation_service_wiring_test.py",
    "content": "\"\"\"Contract tests for generation service wiring.\"\"\"\n\nimport ast\nfrom pathlib import Path\nimport unittest\n\n\n_WIRING_PATH = Path(__file__).resolve().parent / \"generation_service_wiring.py\"\n\n\nclass GenerationServiceWiringTests(unittest.TestCase):\n    \"\"\"Verify key event hooks are present in generation service wiring.\"\"\"\n\n    def test_registers_language_dropdown_change_handler(self):\n        \"\"\"Service wiring should attach a change handler for language dropdown.\"\"\"\n\n        module = ast.parse(_WIRING_PATH.read_text(encoding=\"utf-8\"))\n        register_fn = next(\n            node\n            for node in module.body\n            if isinstance(node, ast.FunctionDef) and node.name == \"register_generation_service_handlers\"\n        )\n\n        found_language_change = False\n        for node in ast.walk(register_fn):\n            if not isinstance(node, ast.Call):\n                continue\n            if not isinstance(node.func, ast.Attribute) or node.func.attr != \"change\":\n                continue\n            if not isinstance(node.func.value, ast.Subscript):\n                continue\n            target = node.func.value\n            if (\n                isinstance(target.value, ast.Name)\n                and target.value.id == \"generation_section\"\n                and isinstance(target.slice, ast.Constant)\n                and target.slice.value == \"language_dropdown\"\n            ):\n                found_language_change = True\n                break\n\n        self.assertTrue(found_language_change, \"language_dropdown.change handler was not found\")\n\n    def test_language_runtime_helper_exists(self):\n        \"\"\"Runtime language helper should exist for dropdown change wiring.\"\"\"\n\n        module = ast.parse(_WIRING_PATH.read_text(encoding=\"utf-8\"))\n        function_names = {\n            node.name for node in module.body if isinstance(node, ast.FunctionDef)\n        }\n        self.assertIn(\"_apply_runtime_language\", function_names)\n\n\nif __name__ == \"__main__\":\n    unittest.main()\n"
  },
  {
    "path": "acestep/ui/gradio/events/wiring/generation_text_format_wiring.py",
    "content": "\"\"\"Generation text-format event wiring helpers.\n\nThis module isolates caption/lyrics formatting event registration.\n\"\"\"\n\nfrom typing import Any, Sequence\n\nfrom .. import generation_handlers as gen_h\nfrom .context import GenerationWiringContext\n\n\ndef register_generation_text_format_handlers(\n    context: GenerationWiringContext,\n    auto_checkbox_inputs: Sequence[Any],\n    auto_checkbox_outputs: Sequence[Any],\n) -> None:\n    \"\"\"Register caption/lyrics format handlers and their auto-checkbox sync.\"\"\"\n\n    generation_section = context.generation_section\n    results_section = context.results_section\n    llm_handler = context.llm_handler\n\n    # ========== Format Caption Button ==========\n    generation_section[\"format_caption_btn\"].click(\n        fn=lambda caption, lyrics, bpm, duration, key_scale, time_sig, temp, top_k, top_p, debug: gen_h.handle_format_caption(\n            llm_handler, caption, lyrics, bpm, duration, key_scale, time_sig, temp, top_k, top_p, debug\n        ),\n        inputs=[\n            generation_section[\"captions\"],\n            generation_section[\"lyrics\"],\n            generation_section[\"bpm\"],\n            generation_section[\"audio_duration\"],\n            generation_section[\"key_scale\"],\n            generation_section[\"time_signature\"],\n            generation_section[\"lm_temperature\"],\n            generation_section[\"lm_top_k\"],\n            generation_section[\"lm_top_p\"],\n            generation_section[\"constrained_decoding_debug\"],\n        ],\n        outputs=[\n            generation_section[\"captions\"],\n            generation_section[\"bpm\"],\n            generation_section[\"audio_duration\"],\n            generation_section[\"key_scale\"],\n            generation_section[\"vocal_language\"],\n            generation_section[\"time_signature\"],\n            results_section[\"is_format_caption_state\"],\n            results_section[\"status_output\"],\n        ],\n    ).then(\n        fn=gen_h.uncheck_auto_for_populated_fields,\n        inputs=list(auto_checkbox_inputs),\n        outputs=list(auto_checkbox_outputs),\n    )\n\n    # ========== Format Lyrics Button ==========\n    generation_section[\"format_lyrics_btn\"].click(\n        fn=lambda caption, lyrics, bpm, duration, key_scale, time_sig, temp, top_k, top_p, debug: gen_h.handle_format_lyrics(\n            llm_handler, caption, lyrics, bpm, duration, key_scale, time_sig, temp, top_k, top_p, debug\n        ),\n        inputs=[\n            generation_section[\"captions\"],\n            generation_section[\"lyrics\"],\n            generation_section[\"bpm\"],\n            generation_section[\"audio_duration\"],\n            generation_section[\"key_scale\"],\n            generation_section[\"time_signature\"],\n            generation_section[\"lm_temperature\"],\n            generation_section[\"lm_top_k\"],\n            generation_section[\"lm_top_p\"],\n            generation_section[\"constrained_decoding_debug\"],\n        ],\n        outputs=[\n            generation_section[\"lyrics\"],\n            generation_section[\"bpm\"],\n            generation_section[\"audio_duration\"],\n            generation_section[\"key_scale\"],\n            generation_section[\"vocal_language\"],\n            generation_section[\"time_signature\"],\n            results_section[\"is_format_caption_state\"],\n            results_section[\"status_output\"],\n        ],\n    ).then(\n        fn=gen_h.uncheck_auto_for_populated_fields,\n        inputs=list(auto_checkbox_inputs),\n        outputs=list(auto_checkbox_outputs),\n    )\n"
  },
  {
    "path": "acestep/ui/gradio/events/wiring/results_aux_wiring.py",
    "content": "\"\"\"Results auxiliary event wiring helpers.\n\nThis module contains results-side helper button wiring that is separate from\ncore generation and batch navigation orchestration.\n\"\"\"\n\nfrom typing import Any, Sequence\n\nfrom .. import results_handlers as res_h\nfrom .context import GenerationWiringContext\n\n\ndef register_results_aux_handlers(\n    context: GenerationWiringContext,\n    mode_ui_outputs: Sequence[Any],\n) -> None:\n    \"\"\"Register remix/repaint, scoring, LRC, codes, and save helpers for results UI.\n\n    Args:\n        context (GenerationWiringContext): Shared generation/results wiring\n            context providing `generation_section`, `results_section`,\n            `dit_handler`, and `llm_handler`.\n        mode_ui_outputs (Sequence[Any]): Ordered mode UI outputs reused when\n            wiring send-to-remix/repaint updates (for example `src_audio`,\n            `lyrics`, `captions`, `generation_mode`, and mode visibility/state\n            outputs).\n\n    Returns:\n        None: Registers click handlers in-place for results controls including\n        `generated_audio_N`, `lm_metadata_state`, `generation_mode`,\n        `score_display_N`, `details_accordion_N`, and `batch_queue` updates.\n    \"\"\"\n\n    generation_section = context.generation_section\n    results_section = context.results_section\n    dit_handler = context.dit_handler\n    llm_handler = context.llm_handler\n\n    # ========== Send to Remix / Repaint Handlers ==========\n    # Mode-UI outputs shared with generation_mode.change — applied atomically\n    # so we don't rely on a chained .change() event for visibility/label updates.\n    for btn_idx in range(1, 9):\n        results_section[f\"send_to_remix_btn_{btn_idx}\"].click(\n            fn=lambda audio, lm, ly, cap, cur_mode: res_h.send_audio_to_remix(\n                audio, lm, ly, cap, cur_mode, llm_handler\n            ),\n            inputs=[\n                results_section[f\"generated_audio_{btn_idx}\"],\n                results_section[\"lm_metadata_state\"],\n                generation_section[\"lyrics\"],\n                generation_section[\"captions\"],\n                generation_section[\"generation_mode\"],\n            ],\n            outputs=[\n                generation_section[\"src_audio\"],\n                generation_section[\"generation_mode\"],\n                generation_section[\"lyrics\"],\n                generation_section[\"captions\"],\n            ]\n            + list(mode_ui_outputs),\n        )\n        results_section[f\"send_to_repaint_btn_{btn_idx}\"].click(\n            fn=lambda audio, lm, ly, cap, cur_mode: res_h.send_audio_to_repaint(\n                audio, lm, ly, cap, cur_mode, llm_handler\n            ),\n            inputs=[\n                results_section[f\"generated_audio_{btn_idx}\"],\n                results_section[\"lm_metadata_state\"],\n                generation_section[\"lyrics\"],\n                generation_section[\"captions\"],\n                generation_section[\"generation_mode\"],\n            ],\n            outputs=[\n                generation_section[\"src_audio\"],\n                generation_section[\"generation_mode\"],\n                generation_section[\"lyrics\"],\n                generation_section[\"captions\"],\n            ]\n            + list(mode_ui_outputs),\n        )\n\n    # ========== Score Calculation Handlers ==========\n    # Use default argument to capture btn_idx value at definition time.\n    def make_score_handler(idx: int):\n        \"\"\"Build a score callback bound to one result-slot index.\n\n        Args:\n            idx (int): Result slot index (`1..8`) used by the callback.\n\n        Returns:\n            Callable[[Any, Any, Any], Any]: Callback with signature\n            `(scale, batch_idx, queue)` that forwards to\n            `res_h.calculate_score_handler_with_selection(...)` and returns\n            updates for score/details UI plus the batch queue state.\n        \"\"\"\n\n        return lambda scale, batch_idx, queue: res_h.calculate_score_handler_with_selection(\n            dit_handler, llm_handler, idx, scale, batch_idx, queue\n        )\n\n    for btn_idx in range(1, 9):\n        results_section[f\"score_btn_{btn_idx}\"].click(\n            fn=make_score_handler(btn_idx),\n            inputs=[\n                generation_section[\"score_scale\"],\n                results_section[\"current_batch_index\"],\n                results_section[\"batch_queue\"],\n            ],\n            outputs=[\n                results_section[f\"score_display_{btn_idx}\"],\n                results_section[f\"details_accordion_{btn_idx}\"],\n                results_section[\"batch_queue\"],\n            ],\n        )\n\n    # ========== LRC Timestamp Handlers ==========\n    # Use default argument to capture btn_idx value at definition time.\n    def make_lrc_handler(idx: int):\n        \"\"\"Build an LRC callback bound to one result-slot index.\n\n        Args:\n            idx (int): Result slot index (`1..8`) used by the callback.\n\n        Returns:\n            Callable[[Any, Any, Any, Any], Any]: Callback with signature\n            `(batch_idx, queue, vocal_lang, infer_steps)` that forwards to\n            `res_h.generate_lrc_handler(...)` and returns updates for LRC,\n            details UI, and batch queue state.\n        \"\"\"\n\n        return lambda batch_idx, queue, vocal_lang, infer_steps: res_h.generate_lrc_handler(\n            dit_handler, idx, batch_idx, queue, vocal_lang, infer_steps\n        )\n\n    for btn_idx in range(1, 9):\n        results_section[f\"lrc_btn_{btn_idx}\"].click(\n            fn=make_lrc_handler(btn_idx),\n            inputs=[\n                results_section[\"current_batch_index\"],\n                results_section[\"batch_queue\"],\n                generation_section[\"vocal_language\"],\n                generation_section[\"inference_steps\"],\n            ],\n            outputs=[\n                results_section[f\"lrc_display_{btn_idx}\"],\n                results_section[f\"details_accordion_{btn_idx}\"],\n                results_section[\"batch_queue\"],\n            ],\n        )\n\n    # ========== Convert To Codes Handlers ==========\n    for btn_idx in range(1, 9):\n        results_section[f\"convert_to_codes_btn_{btn_idx}\"].click(\n            fn=lambda audio: res_h.convert_result_audio_to_codes(dit_handler, audio),\n            inputs=[results_section[f\"generated_audio_{btn_idx}\"]],\n            outputs=[\n                results_section[f\"codes_display_{btn_idx}\"],\n                results_section[f\"details_accordion_{btn_idx}\"],\n            ],\n        )\n\n    # ========== Save LRC Handlers ==========\n    for btn_idx in range(1, 9):\n        results_section[f\"save_lrc_btn_{btn_idx}\"].click(\n            fn=res_h.save_lrc_to_file,\n            inputs=[results_section[f\"lrc_display_{btn_idx}\"]],\n            outputs=[results_section[f\"lrc_download_file_{btn_idx}\"]],\n        )\n"
  },
  {
    "path": "acestep/ui/gradio/events/wiring/results_display_wiring.py",
    "content": "\"\"\"Results display/restore/LRC event wiring helpers.\"\"\"\n\nfrom .context import GenerationWiringContext\nfrom .. import results_handlers as res_h\n\n\n_DOWNLOAD_EXISTING_JS = \"\"\"(current_audio, batch_files) => {\n    // Debug: print what the input actually is\n    console.log(\"[Debug] Current Audio Input:\", current_audio);\n\n    // 1. Safety check\n    if (!current_audio) {\n        console.warn(\"Warning: No audio selected or audio is empty.\");\n        return;\n    }\n    if (!batch_files || !Array.isArray(batch_files)) {\n        console.warn(\"Warning: Batch file list is empty/not ready.\");\n        return;\n    }\n\n    // 2. Smartly extract path string\n    let pathString = \"\";\n\n    if (typeof current_audio === \"string\") {\n        // Case A: direct path string received\n        pathString = current_audio;\n    } else if (typeof current_audio === \"object\") {\n        // Case B: an object is received, try common properties\n        // Gradio file objects usually have path, url, or name\n        pathString = current_audio.path || current_audio.name || current_audio.url || \"\";\n    }\n\n    if (!pathString) {\n        console.error(\"Error: Could not extract a valid path string from input.\", current_audio);\n        return;\n    }\n\n    // 3. Extract Key (UUID)\n    // Path could be /tmp/.../uuid.mp3 or url like /file=.../uuid.mp3\n    let filename = pathString.split(/[\\\\/]/).pop(); // get the filename\n    let key = filename.split('.')[0]; // get UUID without extension\n\n    console.log(`Key extracted: ${key}`);\n\n    // 4. Find matching file(s) in the list\n    let targets = batch_files.filter(f => {\n        // Also extract names from batch_files objects\n        // f usually contains name (backend path) and orig_name (download name)\n        const fPath = f.name || f.path || \"\";\n        return fPath.includes(key);\n    });\n\n    if (targets.length === 0) {\n        console.warn(\"Warning: No matching files found in batch list for key:\", key);\n        alert(\"Batch list does not contain this file yet. Please wait for generation to finish.\");\n        return;\n    }\n\n    // 5. Trigger download(s)\n    console.log(`Found ${targets.length} files to download.`);\n    targets.forEach((f, index) => {\n        setTimeout(() => {\n            const a = document.createElement('a');\n            // Prefer url (frontend-accessible link), otherwise try data\n            a.href = f.url || f.data;\n            a.download = f.orig_name || \"download\";\n            a.style.display = 'none';\n            document.body.appendChild(a);\n            a.click();\n            document.body.removeChild(a);\n        }, index * 1000); // 1000ms interval per index to avoid browser blocking\n    });\n}\n\"\"\"\n\n\ndef register_results_save_button_handlers(context: GenerationWiringContext) -> None:\n    \"\"\"Register save/download button JS handlers for the 8 result slots.\"\"\"\n\n    results_section = context.results_section\n    for btn_idx in range(1, 9):\n        results_section[f\"save_btn_{btn_idx}\"].click(\n            fn=None,\n            inputs=[\n                results_section[f\"generated_audio_{btn_idx}\"],\n                results_section[\"generated_audio_batch\"],\n            ],\n            js=_DOWNLOAD_EXISTING_JS,\n        )\n\n\ndef register_results_restore_and_lrc_handlers(context: GenerationWiringContext) -> None:\n    \"\"\"Register restore-parameters and LRC subtitle-sync handlers.\"\"\"\n\n    generation_section = context.generation_section\n    results_section = context.results_section\n\n    results_section[\"restore_params_btn\"].click(\n        fn=res_h.restore_batch_parameters,\n        inputs=[\n            results_section[\"current_batch_index\"],\n            results_section[\"batch_queue\"],\n        ],\n        outputs=[\n            generation_section[\"text2music_audio_code_string\"],\n            generation_section[\"captions\"],\n            generation_section[\"lyrics\"],\n            generation_section[\"bpm\"],\n            generation_section[\"key_scale\"],\n            generation_section[\"time_signature\"],\n            generation_section[\"vocal_language\"],\n            generation_section[\"audio_duration\"],\n            generation_section[\"batch_size_input\"],\n            generation_section[\"inference_steps\"],\n            generation_section[\"lm_temperature\"],\n            generation_section[\"lm_cfg_scale\"],\n            generation_section[\"lm_top_k\"],\n            generation_section[\"lm_top_p\"],\n            generation_section[\"think_checkbox\"],\n            generation_section[\"use_cot_caption\"],\n            generation_section[\"use_cot_language\"],\n            generation_section[\"allow_lm_batch\"],\n            generation_section[\"track_name\"],\n            generation_section[\"complete_track_classes\"],\n            generation_section[\"enable_normalization\"],\n            generation_section[\"normalization_db\"],\n            generation_section[\"fade_in_duration\"],\n            generation_section[\"fade_out_duration\"],\n            generation_section[\"latent_shift\"],\n            generation_section[\"latent_rescale\"],\n        ],\n    )\n\n    for lrc_idx in range(1, 9):\n        results_section[f\"lrc_display_{lrc_idx}\"].change(\n            fn=res_h.update_audio_subtitles_from_lrc,\n            inputs=[results_section[f\"lrc_display_{lrc_idx}\"]],\n            outputs=[results_section[f\"generated_audio_{lrc_idx}\"]],\n        )\n"
  },
  {
    "path": "acestep/ui/gradio/events/wiring/results_display_wiring_test.py",
    "content": "\"\"\"Unit tests for results display wiring contracts.\"\"\"\n\nimport ast\nfrom pathlib import Path\nimport unittest\n\ntry:\n    from .ast_test_utils import load_module_ast, subscript_key\nexcept ImportError:  # pragma: no cover - supports direct file execution\n    from ast_test_utils import load_module_ast, subscript_key\n\n\n_WIRING_PATH = Path(__file__).with_name(\"results_display_wiring.py\")\n\n_EXPECTED_RESTORE_OUTPUT_KEYS = [\n    \"text2music_audio_code_string\",\n    \"captions\",\n    \"lyrics\",\n    \"bpm\",\n    \"key_scale\",\n    \"time_signature\",\n    \"vocal_language\",\n    \"audio_duration\",\n    \"batch_size_input\",\n    \"inference_steps\",\n    \"lm_temperature\",\n    \"lm_cfg_scale\",\n    \"lm_top_k\",\n    \"lm_top_p\",\n    \"think_checkbox\",\n    \"use_cot_caption\",\n    \"use_cot_language\",\n    \"allow_lm_batch\",\n    \"track_name\",\n    \"complete_track_classes\",\n    \"enable_normalization\",\n    \"normalization_db\",\n    \"fade_in_duration\",\n    \"fade_out_duration\",\n    \"latent_shift\",\n    \"latent_rescale\",\n]\n\n_EXPECTED_JS_MARKERS = [\n    \"[Debug] Current Audio Input:\",\n    \"Warning: No audio selected or audio is empty.\",\n    \"Warning: Batch file list is empty/not ready.\",\n    \"Error: Could not extract a valid path string from input.\",\n    \"Key extracted:\",\n    \"Warning: No matching files found in batch list for key:\",\n    \"Found ${targets.length} files to download.\",\n]\n\n_FORBIDDEN_MOJIBAKE_MARKERS = [\"Ã\", \"ðŸ\", \"âš\", \"â\"]\n\nclass ResultsDisplayWiringTests(unittest.TestCase):\n    \"\"\"Verify save/download JS and restore/LRC wiring ordering contracts.\"\"\"\n\n    def test_download_js_contains_expected_ascii_messages(self):\n        \"\"\"Download JS should contain expected ASCII diagnostics and no mojibake markers.\"\"\"\n\n        module = load_module_ast(_WIRING_PATH)\n        js_literal = None\n        for node in module.body:\n            if isinstance(node, ast.Assign):\n                for target in node.targets:\n                    if isinstance(target, ast.Name) and target.id == \"_DOWNLOAD_EXISTING_JS\":\n                        if isinstance(node.value, ast.Constant) and isinstance(node.value.value, str):\n                            js_literal = node.value.value\n                            break\n            if js_literal is not None:\n                break\n        self.assertIsNotNone(js_literal, \"_DOWNLOAD_EXISTING_JS not found\")\n        for marker in _EXPECTED_JS_MARKERS:\n            self.assertIn(marker, js_literal)\n        for marker in _FORBIDDEN_MOJIBAKE_MARKERS:\n            self.assertNotIn(marker, js_literal)\n\n    def test_restore_outputs_keep_expected_order(self):\n        \"\"\"Restore params click outputs should keep existing generation field ordering.\"\"\"\n\n        module = load_module_ast(_WIRING_PATH)\n        for node in module.body:\n            if not isinstance(node, ast.FunctionDef) or node.name != \"register_results_restore_and_lrc_handlers\":\n                continue\n            for call in ast.walk(node):\n                if not isinstance(call, ast.Call):\n                    continue\n                if not isinstance(call.func, ast.Attribute) or call.func.attr != \"click\":\n                    continue\n                for keyword in call.keywords:\n                    if keyword.arg != \"outputs\" or not isinstance(keyword.value, ast.List):\n                        continue\n                    keys = []\n                    for element in keyword.value.elts:\n                        if isinstance(element, ast.Subscript):\n                            key = subscript_key(element)\n                            if key is not None:\n                                keys.append(key)\n                    if keys == _EXPECTED_RESTORE_OUTPUT_KEYS:\n                        return\n        self.fail(\"restore_params_btn outputs contract not found\")\n\n    def test_save_and_lrc_handlers_cover_all_8_result_slots(self):\n        \"\"\"Both save-btn and lrc-display loops should iterate over slots 1..8.\"\"\"\n\n        module = load_module_ast(_WIRING_PATH)\n        range_calls = []\n        for node in ast.walk(module):\n            if isinstance(node, ast.For) and isinstance(node.iter, ast.Call):\n                call = node.iter\n                if isinstance(call.func, ast.Name) and call.func.id == \"range\":\n                    args = []\n                    for arg in call.args:\n                        if isinstance(arg, ast.Constant) and isinstance(arg.value, int):\n                            args.append(arg.value)\n                    if args:\n                        range_calls.append(tuple(args))\n\n        self.assertIn((1, 9), range_calls)\n        self.assertGreaterEqual(range_calls.count((1, 9)), 2)\n\n\nif __name__ == \"__main__\":\n    unittest.main()\n"
  },
  {
    "path": "acestep/ui/gradio/events/wiring/training_dataset_builder_wiring.py",
    "content": "\"\"\"Training dataset-builder event wiring helpers.\"\"\"\n\nfrom typing import Any, Mapping\n\nimport gradio as gr\n\nfrom .. import training_handlers as train_h\nfrom .context import TrainingWiringContext\n\n\n_SAMPLE_PREVIEW_OUTPUT_KEYS = (\n    \"preview_audio\",\n    \"preview_filename\",\n    \"edit_caption\",\n    \"edit_genre\",\n    \"prompt_override\",\n    \"edit_lyrics\",\n    \"edit_bpm\",\n    \"edit_keyscale\",\n    \"edit_timesig\",\n    \"edit_duration\",\n    \"edit_language\",\n    \"edit_instrumental\",\n    \"raw_lyrics_display\",\n    \"has_raw_lyrics_state\",\n)\n\n_SETTINGS_TRIGGER_KEYS = (\n    \"custom_tag\",\n    \"tag_position\",\n    \"all_instrumental\",\n    \"genre_ratio\",\n)\n\n_CHECKMARK = \"\\u2705\"\n\n\ndef _build_sample_preview_outputs(training_section: Mapping[str, Any]) -> list[Any]:\n    \"\"\"Return ordered sample-preview outputs shared by preview refresh handlers.\"\"\"\n\n    return [training_section[key] for key in _SAMPLE_PREVIEW_OUTPUT_KEYS]\n\n\ndef register_training_dataset_builder_handlers(context: TrainingWiringContext) -> None:\n    \"\"\"Register dataset-builder handlers while preserving existing IO ordering.\"\"\"\n\n    training_section = context.training_section\n    dit_handler = context.dit_handler\n    llm_handler = context.llm_handler\n    sample_preview_outputs = _build_sample_preview_outputs(training_section)\n\n    training_section[\"scan_btn\"].click(\n        fn=lambda directory, name, tag, pos, instr, state: train_h.scan_directory(\n            directory, name, tag, pos, instr, state\n        ),\n        inputs=[\n            training_section[\"audio_directory\"],\n            training_section[\"dataset_name\"],\n            training_section[\"custom_tag\"],\n            training_section[\"tag_position\"],\n            training_section[\"all_instrumental\"],\n            training_section[\"dataset_builder_state\"],\n        ],\n        outputs=[\n            training_section[\"audio_files_table\"],\n            training_section[\"scan_status\"],\n            training_section[\"sample_selector\"],\n            training_section[\"dataset_builder_state\"],\n        ],\n    )\n\n    training_section[\"auto_label_btn\"].click(\n        fn=lambda state, skip, fmt_lyrics, trans_lyrics, only_unlab: train_h.auto_label_all(\n            dit_handler, llm_handler, state, skip, fmt_lyrics, trans_lyrics, only_unlab\n        ),\n        inputs=[\n            training_section[\"dataset_builder_state\"],\n            training_section[\"skip_metas\"],\n            training_section[\"format_lyrics\"],\n            training_section[\"transcribe_lyrics\"],\n            training_section[\"only_unlabeled\"],\n        ],\n        outputs=[\n            training_section[\"audio_files_table\"],\n            training_section[\"label_progress\"],\n            training_section[\"dataset_builder_state\"],\n        ],\n    ).then(\n        fn=train_h.get_sample_preview,\n        inputs=[\n            training_section[\"sample_selector\"],\n            training_section[\"dataset_builder_state\"],\n        ],\n        outputs=sample_preview_outputs,\n    ).then(\n        fn=lambda status: f\"{status or (_CHECKMARK + ' Auto-label complete.')}\\n{_CHECKMARK} Preview refreshed.\",\n        inputs=[training_section[\"label_progress\"]],\n        outputs=[training_section[\"label_progress\"]],\n    ).then(\n        fn=lambda has_raw: gr.update(visible=bool(has_raw)),\n        inputs=[training_section[\"has_raw_lyrics_state\"]],\n        outputs=[training_section[\"raw_lyrics_display\"]],\n    )\n\n    training_section[\"format_lyrics\"].change(\n        fn=lambda fmt: gr.update(value=False) if fmt else gr.update(),\n        inputs=[training_section[\"format_lyrics\"]],\n        outputs=[training_section[\"transcribe_lyrics\"]],\n    )\n\n    training_section[\"transcribe_lyrics\"].change(\n        fn=lambda trans: gr.update(value=False) if trans else gr.update(),\n        inputs=[training_section[\"transcribe_lyrics\"]],\n        outputs=[training_section[\"format_lyrics\"]],\n    )\n\n    training_section[\"sample_selector\"].change(\n        fn=train_h.get_sample_preview,\n        inputs=[\n            training_section[\"sample_selector\"],\n            training_section[\"dataset_builder_state\"],\n        ],\n        outputs=sample_preview_outputs,\n    ).then(\n        fn=lambda has_raw: gr.update(visible=has_raw),\n        inputs=[training_section[\"has_raw_lyrics_state\"]],\n        outputs=[training_section[\"raw_lyrics_display\"]],\n    )\n\n    training_section[\"save_edit_btn\"].click(\n        fn=train_h.save_sample_edit,\n        inputs=[\n            training_section[\"sample_selector\"],\n            training_section[\"edit_caption\"],\n            training_section[\"edit_genre\"],\n            training_section[\"prompt_override\"],\n            training_section[\"edit_lyrics\"],\n            training_section[\"edit_bpm\"],\n            training_section[\"edit_keyscale\"],\n            training_section[\"edit_timesig\"],\n            training_section[\"edit_language\"],\n            training_section[\"edit_instrumental\"],\n            training_section[\"dataset_builder_state\"],\n        ],\n        outputs=[\n            training_section[\"audio_files_table\"],\n            training_section[\"edit_status\"],\n            training_section[\"dataset_builder_state\"],\n        ],\n    )\n\n    for trigger_key in _SETTINGS_TRIGGER_KEYS:\n        training_section[trigger_key].change(\n            fn=train_h.update_settings,\n            inputs=[\n                training_section[\"custom_tag\"],\n                training_section[\"tag_position\"],\n                training_section[\"all_instrumental\"],\n                training_section[\"genre_ratio\"],\n                training_section[\"dataset_builder_state\"],\n            ],\n            outputs=[training_section[\"dataset_builder_state\"]],\n        )\n\n    training_section[\"save_dataset_btn\"].click(\n        fn=train_h.save_dataset,\n        inputs=[\n            training_section[\"save_path\"],\n            training_section[\"dataset_name\"],\n            training_section[\"dataset_builder_state\"],\n        ],\n        outputs=[\n            training_section[\"save_status\"],\n            training_section[\"save_path\"],\n        ],\n    )\n"
  },
  {
    "path": "acestep/ui/gradio/events/wiring/training_dataset_preprocess_wiring.py",
    "content": "\"\"\"Training dataset-load and preprocess wiring helpers.\"\"\"\n\nfrom typing import Any, Mapping\n\nimport gradio as gr\n\nfrom .. import training_handlers as train_h\nfrom .context import TrainingWiringContext\n\n\n_DATASET_LOAD_SHARED_OUTPUT_KEYS = (\n    \"audio_files_table\",\n    \"sample_selector\",\n    \"dataset_builder_state\",\n    \"preview_audio\",\n    \"preview_filename\",\n    \"edit_caption\",\n    \"edit_genre\",\n    \"prompt_override\",\n    \"edit_lyrics\",\n    \"edit_bpm\",\n    \"edit_keyscale\",\n    \"edit_timesig\",\n    \"edit_duration\",\n    \"edit_language\",\n    \"edit_instrumental\",\n    \"raw_lyrics_display\",\n    \"has_raw_lyrics_state\",\n    \"dataset_name\",\n    \"custom_tag\",\n    \"tag_position\",\n    \"all_instrumental\",\n    \"genre_ratio\",\n)\n\n\ndef _build_dataset_load_outputs(\n    training_section: Mapping[str, Any],\n    status_key: str,\n) -> list[Any]:\n    \"\"\"Return the ordered output list for dataset-load button wiring.\"\"\"\n\n    return [training_section[status_key]] + [\n        training_section[key] for key in _DATASET_LOAD_SHARED_OUTPUT_KEYS\n    ]\n\n\ndef register_training_dataset_load_handler(\n    context: TrainingWiringContext,\n    *,\n    button_key: str,\n    path_key: str,\n    status_key: str,\n) -> None:\n    \"\"\"Register one dataset JSON load button with shared output/update contracts.\"\"\"\n\n    training_section = context.training_section\n    training_section[button_key].click(\n        fn=train_h.load_existing_dataset_for_preprocess,\n        inputs=[\n            training_section[path_key],\n            training_section[\"dataset_builder_state\"],\n        ],\n        outputs=_build_dataset_load_outputs(training_section, status_key),\n    ).then(\n        fn=lambda has_raw: gr.update(visible=has_raw),\n        inputs=[training_section[\"has_raw_lyrics_state\"]],\n        outputs=[training_section[\"raw_lyrics_display\"]],\n    )\n\n\ndef register_training_preprocess_handler(context: TrainingWiringContext) -> None:\n    \"\"\"Register preprocess button wiring for tensor conversion.\"\"\"\n\n    training_section = context.training_section\n    dit_handler = context.dit_handler\n    training_section[\"preprocess_btn\"].click(\n        fn=lambda output_dir, mode, state: train_h.preprocess_dataset(\n            output_dir, mode, dit_handler, state\n        ),\n        inputs=[\n            training_section[\"preprocess_output_dir\"],\n            training_section[\"preprocess_mode\"],\n            training_section[\"dataset_builder_state\"],\n        ],\n        outputs=[training_section[\"preprocess_progress\"]],\n    )\n"
  },
  {
    "path": "acestep/ui/gradio/events/wiring/training_lokr_wiring.py",
    "content": "\"\"\"LoKr-specific training run wiring helpers.\"\"\"\n\nfrom typing import Any, Callable, Iterator\n\nfrom loguru import logger\n\nfrom .. import training_handlers as train_h\nfrom .context import TrainingWiringContext\n\n\ndef _build_lokr_training_wrapper(\n    dit_handler: Any,\n    normalize_training_state: Callable[[Any], dict[str, bool]],\n):\n    \"\"\"Build the LoKr training stream wrapper bound to the current DiT handler.\"\"\"\n\n    def lokr_training_wrapper(\n        tensor_dir: Any,\n        lokr_linear_dim: Any,\n        lokr_linear_alpha: Any,\n        lokr_factor: Any,\n        lokr_decompose_both: Any,\n        lokr_use_tucker: Any,\n        lokr_use_scalar: Any,\n        lokr_weight_decompose: Any,\n        lokr_learning_rate: Any,\n        lokr_train_epochs: Any,\n        lokr_train_batch_size: Any,\n        lokr_gradient_accumulation: Any,\n        lokr_save_every_n_epochs: Any,\n        lokr_training_shift: Any,\n        lokr_training_seed: Any,\n        lokr_output_dir: Any,\n        training_state: Any,\n    ) -> Iterator[tuple[Any, Any, Any, dict[str, bool]]]:\n        \"\"\"Stream LoKr training progress and normalize failure outputs for UI.\"\"\"\n\n        state = normalize_training_state(training_state)\n        try:\n            for progress, log_msg, plot, next_state in train_h.start_lokr_training(\n                tensor_dir,\n                dit_handler,\n                lokr_linear_dim,\n                lokr_linear_alpha,\n                lokr_factor,\n                lokr_decompose_both,\n                lokr_use_tucker,\n                lokr_use_scalar,\n                lokr_weight_decompose,\n                lokr_learning_rate,\n                lokr_train_epochs,\n                lokr_train_batch_size,\n                lokr_gradient_accumulation,\n                lokr_save_every_n_epochs,\n                lokr_training_shift,\n                lokr_training_seed,\n                lokr_output_dir,\n                state,\n            ):\n                yield progress, log_msg, plot, next_state\n        except Exception as exc:  # pragma: no cover - defensive UI wrapper\n            logger.exception(\"LoKr training wrapper error\")\n            yield f\"\\u274c Error: {exc!r}\", f\"{exc!r}\", None, state\n\n    return lokr_training_wrapper\n\n\ndef register_lokr_training_handlers(\n    context: TrainingWiringContext,\n    *,\n    normalize_training_state: Callable[[Any], dict[str, bool]],\n) -> None:\n    \"\"\"Register LoKr training handlers with stable IO ordering.\"\"\"\n\n    training_section = context.training_section\n    lokr_training_wrapper = _build_lokr_training_wrapper(\n        context.dit_handler,\n        normalize_training_state,\n    )\n\n    # ========== LoKr Training Tab Handlers ==========\n    training_section[\"lokr_load_dataset_btn\"].click(\n        fn=train_h.load_training_dataset,\n        inputs=[training_section[\"lokr_training_tensor_dir\"]],\n        outputs=[training_section[\"lokr_training_dataset_info\"]],\n    )\n\n    training_section[\"start_lokr_training_btn\"].click(\n        fn=lokr_training_wrapper,\n        inputs=[\n            training_section[\"lokr_training_tensor_dir\"],\n            training_section[\"lokr_linear_dim\"],\n            training_section[\"lokr_linear_alpha\"],\n            training_section[\"lokr_factor\"],\n            training_section[\"lokr_decompose_both\"],\n            training_section[\"lokr_use_tucker\"],\n            training_section[\"lokr_use_scalar\"],\n            training_section[\"lokr_weight_decompose\"],\n            training_section[\"lokr_learning_rate\"],\n            training_section[\"lokr_train_epochs\"],\n            training_section[\"lokr_train_batch_size\"],\n            training_section[\"lokr_gradient_accumulation\"],\n            training_section[\"lokr_save_every_n_epochs\"],\n            training_section[\"lokr_training_shift\"],\n            training_section[\"lokr_training_seed\"],\n            training_section[\"lokr_output_dir\"],\n            training_section[\"training_state\"],\n        ],\n        outputs=[\n            training_section[\"lokr_training_progress\"],\n            training_section[\"lokr_training_log\"],\n            training_section[\"lokr_training_loss_plot\"],\n            training_section[\"training_state\"],\n        ],\n    )\n\n    training_section[\"stop_lokr_training_btn\"].click(\n        fn=train_h.stop_training,\n        inputs=[training_section[\"training_state\"]],\n        outputs=[\n            training_section[\"lokr_training_progress\"],\n            training_section[\"training_state\"],\n        ],\n    )\n\n    training_section[\"refresh_lokr_export_epochs_btn\"].click(\n        fn=train_h.list_lokr_export_epochs,\n        inputs=[training_section[\"lokr_output_dir\"]],\n        outputs=[\n            training_section[\"lokr_export_epoch\"],\n            training_section[\"lokr_export_status\"],\n        ],\n    )\n\n    training_section[\"export_lokr_btn\"].click(\n        fn=train_h.export_lokr,\n        inputs=[\n            training_section[\"lokr_export_path\"],\n            training_section[\"lokr_output_dir\"],\n            training_section[\"lokr_export_epoch\"],\n        ],\n        outputs=[training_section[\"lokr_export_status\"]],\n    )\n"
  },
  {
    "path": "acestep/ui/gradio/events/wiring/training_run_wiring.py",
    "content": "\"\"\"Training run wiring helpers extracted from ``events.__init__``.\"\"\"\n\nfrom typing import Any, Iterator\n\nfrom loguru import logger\n\nfrom .. import training_handlers as train_h\nfrom .context import TrainingWiringContext\nfrom .training_lokr_wiring import register_lokr_training_handlers\n\n\ndef _normalize_training_state(training_state: Any) -> dict[str, bool]:\n    \"\"\"Return a valid mutable training-state mapping for streaming wrappers.\"\"\"\n\n    if isinstance(training_state, dict):\n        return training_state\n    return {\"is_training\": False, \"should_stop\": False}\n\n\ndef _build_training_wrapper(dit_handler: Any):\n    \"\"\"Build the training stream wrapper bound to the current DiT handler.\"\"\"\n\n    def training_wrapper(\n        tensor_dir: Any,\n        lora_rank: Any,\n        lora_alpha: Any,\n        lora_dropout: Any,\n        learning_rate: Any,\n        train_epochs: Any,\n        train_batch_size: Any,\n        gradient_accumulation: Any,\n        save_every_n_epochs: Any,\n        training_shift: Any,\n        training_seed: Any,\n        lora_output_dir: Any,\n        resume_checkpoint_dir: Any,\n        training_state: Any,\n    ) -> Iterator[tuple[Any, Any, Any, dict[str, bool]]]:\n        \"\"\"Stream LoRA training progress and normalize failure outputs for UI.\"\"\"\n\n        state = _normalize_training_state(training_state)\n        try:\n            for progress, log_msg, plot, next_state in train_h.start_training(\n                tensor_dir,\n                dit_handler,\n                lora_rank,\n                lora_alpha,\n                lora_dropout,\n                learning_rate,\n                train_epochs,\n                train_batch_size,\n                gradient_accumulation,\n                save_every_n_epochs,\n                training_shift,\n                training_seed,\n                lora_output_dir,\n                resume_checkpoint_dir,\n                state,\n            ):\n                yield progress, log_msg, plot, next_state\n        except Exception as exc:  # pragma: no cover - defensive UI wrapper\n            logger.exception(\"Training wrapper error\")\n            yield f\"\\u274c Error: {exc!s}\", f\"{exc!s}\", None, state\n\n    return training_wrapper\n\n\ndef register_training_run_handlers(context: TrainingWiringContext) -> None:\n    \"\"\"Register training run-tab handlers with stable IO ordering.\"\"\"\n\n    training_section = context.training_section\n    training_wrapper = _build_training_wrapper(context.dit_handler)\n\n    # ========== Training Tab Handlers ==========\n    training_section[\"load_dataset_btn\"].click(\n        fn=train_h.load_training_dataset,\n        inputs=[training_section[\"training_tensor_dir\"]],\n        outputs=[training_section[\"training_dataset_info\"]],\n    )\n\n    training_section[\"start_training_btn\"].click(\n        fn=training_wrapper,\n        inputs=[\n            training_section[\"training_tensor_dir\"],\n            training_section[\"lora_rank\"],\n            training_section[\"lora_alpha\"],\n            training_section[\"lora_dropout\"],\n            training_section[\"learning_rate\"],\n            training_section[\"train_epochs\"],\n            training_section[\"train_batch_size\"],\n            training_section[\"gradient_accumulation\"],\n            training_section[\"save_every_n_epochs\"],\n            training_section[\"training_shift\"],\n            training_section[\"training_seed\"],\n            training_section[\"lora_output_dir\"],\n            training_section[\"resume_checkpoint_dir\"],\n            training_section[\"training_state\"],\n        ],\n        outputs=[\n            training_section[\"training_progress\"],\n            training_section[\"training_log\"],\n            training_section[\"training_loss_plot\"],\n            training_section[\"training_state\"],\n        ],\n    )\n\n    training_section[\"stop_training_btn\"].click(\n        fn=train_h.stop_training,\n        inputs=[training_section[\"training_state\"]],\n        outputs=[\n            training_section[\"training_progress\"],\n            training_section[\"training_state\"],\n        ],\n    )\n\n    training_section[\"export_lora_btn\"].click(\n        fn=train_h.export_lora,\n        inputs=[\n            training_section[\"export_path\"],\n            training_section[\"lora_output_dir\"],\n        ],\n        outputs=[training_section[\"export_status\"]],\n    )\n\n    register_lokr_training_handlers(\n        context,\n        normalize_training_state=_normalize_training_state,\n    )\n"
  },
  {
    "path": "acestep/ui/gradio/help_content.py",
    "content": "\"\"\"\nHelp content module for Gradio UI.\n\nProvides a reusable inline help button + modal component that displays\ni18n-sourced Markdown documentation within the Gradio interface.\n\nThe button is rendered as a pure-HTML ``<span>`` so it takes zero layout\nspace and can be placed inside any existing row or header without\ncreating extra blank rows.\n\"\"\"\nimport gradio as gr\nfrom acestep.ui.gradio.i18n import t\n\n# Unique counter to avoid DOM id collisions across multiple help buttons.\n_help_counter = 0\n\n\ndef _next_id() -> str:\n    \"\"\"Return a unique DOM id suffix for each help modal instance.\"\"\"\n    global _help_counter\n    _help_counter += 1\n    return str(_help_counter)\n\n\ndef _md_to_html(md_text: str) -> str:\n    \"\"\"Convert Markdown to HTML with basic formatting.\n\n    Handles headings, bold, italic, code blocks, lists, blockquotes,\n    and paragraphs.  Intentionally lightweight so we avoid adding an\n    external ``markdown`` dependency.\n\n    Args:\n        md_text: Markdown-formatted string.\n\n    Returns:\n        HTML string.\n    \"\"\"\n    import re\n\n    lines = md_text.split(\"\\n\")\n    html_parts: list[str] = []\n    in_code = False\n    in_list = False\n\n    for line in lines:\n        # Fenced code blocks\n        if line.strip().startswith(\"```\"):\n            if in_code:\n                html_parts.append(\"</code></pre>\")\n                in_code = False\n            else:\n                html_parts.append(\"<pre><code>\")\n                in_code = True\n            continue\n        if in_code:\n            html_parts.append(line)\n            continue\n\n        stripped = line.strip()\n\n        # Close list if line is not a list item\n        if in_list and not stripped.startswith(\"- \") and not re.match(r\"^\\d+\\.\", stripped):\n            html_parts.append(\"</ul>\")\n            in_list = False\n\n        # Headings\n        if stripped.startswith(\"### \"):\n            heading = re.sub(\n                r\"\\[([^\\]]+)\\]\\(([^)]+)\\)\",\n                r'<a href=\"\\2\" target=\"_blank\" style=\"color:var(--color-accent,#4a9eff);\">\\1</a>',\n                stripped[4:],\n            )\n            html_parts.append(f\"<h4>{heading}</h4>\")\n            continue\n        if stripped.startswith(\"## \"):\n            heading = re.sub(\n                r\"\\[([^\\]]+)\\]\\(([^)]+)\\)\",\n                r'<a href=\"\\2\" target=\"_blank\" style=\"color:var(--color-accent,#4a9eff);\">\\1</a>',\n                stripped[3:],\n            )\n            html_parts.append(f\"<h3>{heading}</h3>\")\n            continue\n\n        # Blockquotes\n        if stripped.startswith(\"> \"):\n            content = stripped[2:]\n            content = re.sub(r\"\\*\\*(.+?)\\*\\*\", r\"<strong>\\1</strong>\", content)\n            content = re.sub(\n                r\"\\[([^\\]]+)\\]\\(([^)]+)\\)\",\n                r'<a href=\"\\2\" target=\"_blank\" style=\"color:var(--color-accent,#4a9eff);\">\\1</a>',\n                content,\n            )\n            html_parts.append(\n                f'<blockquote style=\"border-left:3px solid #888;'\n                f'padding-left:10px;color:#aaa;\">{content}</blockquote>'\n            )\n            continue\n\n        # List items\n        if stripped.startswith(\"- \") or re.match(r\"^\\d+\\.\\s\", stripped):\n            if not in_list:\n                html_parts.append(\"<ul style='padding-left:20px;'>\")\n                in_list = True\n            content = re.sub(r\"^-\\s|^\\d+\\.\\s\", \"\", stripped)\n            content = re.sub(r\"\\*\\*(.+?)\\*\\*\", r\"<strong>\\1</strong>\", content)\n            content = re.sub(r\"\\*(.+?)\\*\", r\"<em>\\1</em>\", content)\n            content = re.sub(r\"`([^`]+)`\", r\"<code>\\1</code>\", content)\n            content = re.sub(\n                r\"\\[([^\\]]+)\\]\\(([^)]+)\\)\",\n                r'<a href=\"\\2\" target=\"_blank\" style=\"color:var(--color-accent,#4a9eff);\">\\1</a>',\n                content,\n            )\n            html_parts.append(f\"<li>{content}</li>\")\n            continue\n\n        # Empty line\n        if not stripped:\n            if in_list:\n                html_parts.append(\"</ul>\")\n                in_list = False\n            html_parts.append(\"<br/>\")\n            continue\n\n        # Regular paragraph\n        p = stripped\n        p = re.sub(r\"\\*\\*(.+?)\\*\\*\", r\"<strong>\\1</strong>\", p)\n        p = re.sub(r\"\\*(.+?)\\*\", r\"<em>\\1</em>\", p)\n        p = re.sub(r\"`([^`]+)`\", r\"<code>\\1</code>\", p)\n        p = re.sub(\n            r\"\\[([^\\]]+)\\]\\(([^)]+)\\)\",\n            r'<a href=\"\\2\" target=\"_blank\" style=\"color:var(--color-accent,#4a9eff);\">\\1</a>',\n            p,\n        )\n        html_parts.append(f\"<p style='margin:4px 0;'>{p}</p>\")\n\n    if in_list:\n        html_parts.append(\"</ul>\")\n    if in_code:\n        html_parts.append(\"</code></pre>\")\n\n    return \"\\n\".join(html_parts)\n\n\ndef create_help_button(section_key: str) -> gr.HTML:\n    \"\"\"Create an inline (?) help button that opens a modal with documentation.\n\n    The entire widget (button + hidden modal) is a single ``gr.HTML``\n    component so it takes minimal layout space and can be placed inside\n    any existing ``gr.Row`` without creating extra blank areas.\n\n    Args:\n        section_key: The i18n sub-key under ``help.`` (e.g. ``\"generation_simple\"``).\n\n    Returns:\n        The ``gr.HTML`` instance.\n    \"\"\"\n    uid = _next_id()\n    modal_id = f\"help-modal-{uid}\"\n    btn_id = f\"help-btn-{uid}\"\n    md_content = t(f\"help.{section_key}\")\n    html_content = _md_to_html(md_content)\n    close_label = t(\"help.close_label\")\n\n    html = gr.HTML(\n        value=f\"\"\"\n        <span class=\"help-inline-wrapper\">\n          <button id=\"{btn_id}\" class=\"help-inline-btn\"\n                  onclick=\"document.getElementById('{modal_id}').style.display='flex'\"\n                  title=\"Help\">?</button>\n        </span>\n        <div id=\"{modal_id}\" class=\"help-modal-overlay\" style=\"display:none;\"\n             onclick=\"if(event.target===this)this.style.display='none'\">\n          <div class=\"help-modal-content\">\n            <button class=\"help-modal-close\"\n                    onclick=\"document.getElementById('{modal_id}').style.display='none'\">\n              {close_label}\n            </button>\n            <div class=\"help-modal-body\">\n              {html_content}\n            </div>\n          </div>\n        </div>\n        \"\"\",\n        elem_classes=[\"help-inline-container\"],\n    )\n\n    return html\n\n\n# ---------------------------------------------------------------------------\n# CSS to be injected into the main Blocks CSS string.\n# ---------------------------------------------------------------------------\nHELP_MODAL_CSS = \"\"\"\n/* ---- Inline help button container ---- */\n.help-inline-container {\n    min-height: 0 !important;\n    padding: 0 !important;\n    margin: 0 !important;\n    display: inline-flex !important;\n    align-items: center !important;\n    flex-shrink: 0 !important;\n    max-width: 32px !important;\n    min-width: 32px !important;\n    overflow: visible !important;\n}\n\n.help-inline-wrapper {\n    display: inline-flex;\n    align-items: center;\n    line-height: 1;\n}\n\n/* ---- Inline help button ---- */\n.help-inline-btn {\n    width: 22px;\n    height: 22px;\n    border-radius: 50%;\n    border: 1.5px solid var(--border-color-primary, #555);\n    background: transparent;\n    color: var(--body-text-color-subdued, #888);\n    font-size: 12px;\n    font-weight: 600;\n    line-height: 20px;\n    text-align: center;\n    cursor: pointer;\n    padding: 0;\n    transition: all 0.15s ease;\n    flex-shrink: 0;\n}\n.help-inline-btn:hover {\n    background: var(--color-accent, #4a9eff);\n    color: #fff;\n    border-color: var(--color-accent, #4a9eff);\n    transform: scale(1.1);\n}\n\n/* ---- Modal overlay ---- */\n.help-modal-overlay {\n    position: fixed;\n    top: 0; left: 0; right: 0; bottom: 0;\n    background: rgba(0,0,0,0.5);\n    z-index: 100000;\n    display: flex;\n    justify-content: center;\n    align-items: center;\n}\n\n.help-modal-content {\n    background: var(--background-fill-primary, #fff);\n    color: var(--body-text-color, #222);\n    border-radius: 12px;\n    max-width: 640px;\n    width: 90%;\n    max-height: 80vh;\n    display: flex;\n    flex-direction: column;\n    box-shadow: 0 20px 60px rgba(0,0,0,0.3);\n    position: relative;\n}\n\n.help-modal-close {\n    position: absolute;\n    top: 12px; right: 16px;\n    background: none;\n    border: none;\n    font-size: 20px;\n    cursor: pointer;\n    color: var(--body-text-color, #222);\n    z-index: 1;\n    opacity: 0.6;\n}\n.help-modal-close:hover { opacity: 1; }\n\n.help-modal-body {\n    padding: 28px 32px;\n    overflow-y: auto;\n    line-height: 1.7;\n    font-size: 0.92rem;\n}\n.help-modal-body h3 { margin: 16px 0 8px; font-size: 1.15rem; }\n.help-modal-body h4 { margin: 12px 0 6px; font-size: 1.0rem; }\n.help-modal-body pre {\n    background: var(--background-fill-secondary, #f5f5f5);\n    padding: 10px;\n    border-radius: 6px;\n    overflow-x: auto;\n    font-size: 0.85rem;\n}\n.help-modal-body code {\n    background: var(--background-fill-secondary, #f5f5f5);\n    padding: 1px 4px;\n    border-radius: 3px;\n    font-size: 0.88em;\n}\n.help-modal-body ul { margin: 6px 0; }\n.help-modal-body li { margin: 3px 0; }\n\"\"\"\n"
  },
  {
    "path": "acestep/ui/gradio/help_content_i18n_test.py",
    "content": "\"\"\"I18n key-coverage tests for help-content strings.\"\"\"\n\nimport json\nimport os\nimport unittest\n\nfrom acestep.ui.gradio.help_content_test_helpers import ensure_gradio_mocked\n\nensure_gradio_mocked()\n\nfrom acestep.ui.gradio.i18n import I18n  # noqa: E402\n\n\nclass I18nHelpKeysTests(unittest.TestCase):\n    \"\"\"Verify that all language files contain the required help.* keys.\"\"\"\n\n    REQUIRED_HELP_KEYS = frozenset({\n        \"btn_label\",\n        \"close_label\",\n        \"getting_started\",\n        \"service_config\",\n        \"generation_simple\",\n        \"generation_custom\",\n        \"generation_remix\",\n        \"generation_repaint\",\n        \"generation_extract\",\n        \"generation_lego\",\n        \"generation_complete\",\n    })\n\n    @classmethod\n    def setUpClass(cls):\n        \"\"\"Load all i18n language JSON files for help-key assertions.\"\"\"\n        i18n_dir = os.path.join(\n            os.path.dirname(os.path.abspath(__file__)), \"i18n\"\n        )\n        cls.languages: dict[str, dict] = {}\n        for fname in sorted(os.listdir(i18n_dir)):\n            if fname.endswith(\".json\"):\n                lang = fname[:-5]\n                with open(os.path.join(i18n_dir, fname), encoding=\"utf-8\") as handle:\n                    cls.languages[lang] = json.load(handle)\n\n    def test_en_has_help_section(self):\n        \"\"\"English JSON must have a top-level 'help' key.\"\"\"\n        self.assertIn(\"help\", self.languages[\"en\"])\n\n    def test_all_languages_have_required_keys(self):\n        \"\"\"Every language with a help section must contain all required keys.\"\"\"\n        for lang, data in self.languages.items():\n            help_section = data.get(\"help\")\n            if help_section is None:\n                continue\n            for key in self.REQUIRED_HELP_KEYS:\n                with self.subTest(lang=lang, key=key):\n                    self.assertIn(\n                        key,\n                        help_section,\n                        f\"Language '{lang}' is missing help.{key}\",\n                    )\n\n    def test_help_values_are_non_empty_strings(self):\n        \"\"\"Help values must be non-empty strings.\"\"\"\n        for lang, data in self.languages.items():\n            help_section = data.get(\"help\")\n            if help_section is None:\n                continue\n            for key in self.REQUIRED_HELP_KEYS:\n                with self.subTest(lang=lang, key=key):\n                    value = help_section.get(key)\n                    self.assertIsInstance(value, str)\n                    self.assertTrue(len(value) > 0)\n\n    def test_i18n_t_returns_help_content(self):\n        \"\"\"i18n t() resolves help.* keys to actual content, not the key.\"\"\"\n        i18n = I18n(default_language=\"en\")\n        result = i18n.t(\"help.getting_started\")\n        self.assertNotEqual(result, \"help.getting_started\")\n        self.assertIn(\"##\", result)\n\n\nif __name__ == \"__main__\":\n    unittest.main()\n"
  },
  {
    "path": "acestep/ui/gradio/help_content_md_test.py",
    "content": "\"\"\"Markdown conversion unit tests for help-content rendering.\"\"\"\n\nimport unittest\n\nfrom acestep.ui.gradio.help_content_test_helpers import ensure_gradio_mocked\n\nensure_gradio_mocked()\n\nfrom acestep.ui.gradio.help_content import _md_to_html  # noqa: E402\n\n\nclass MdToHtmlTests(unittest.TestCase):\n    \"\"\"Tests for the lightweight Markdown-to-HTML converter.\"\"\"\n\n    def test_heading_h2(self):\n        \"\"\"## headings become <h3> tags.\"\"\"\n        self.assertIn(\"<h3>Title</h3>\", _md_to_html(\"## Title\"))\n\n    def test_heading_h3(self):\n        \"\"\"### headings become <h4> tags.\"\"\"\n        self.assertIn(\"<h4>Subtitle</h4>\", _md_to_html(\"### Subtitle\"))\n\n    def test_bold_text(self):\n        \"\"\"**bold** becomes <strong>.\"\"\"\n        self.assertIn(\"<strong>bold</strong>\", _md_to_html(\"Use **bold** here\"))\n\n    def test_italic_text(self):\n        \"\"\"*italic* becomes <em>.\"\"\"\n        self.assertIn(\"<em>italic</em>\", _md_to_html(\"Use *italic* here\"))\n\n    def test_inline_code(self):\n        \"\"\"`code` becomes <code>.\"\"\"\n        self.assertIn(\"<code>pip install</code>\", _md_to_html(\"Run `pip install`\"))\n\n    def test_unordered_list(self):\n        \"\"\"Dash list items become <li> inside <ul>.\"\"\"\n        result = _md_to_html(\"- item one\\n- item two\")\n        self.assertIn(\"<ul\", result)\n        self.assertIn(\"<li>item one</li>\", result)\n        self.assertIn(\"<li>item two</li>\", result)\n\n    def test_ordered_list(self):\n        \"\"\"Numbered list items become <li>.\"\"\"\n        result = _md_to_html(\"1. first\\n2. second\")\n        self.assertIn(\"<li>first</li>\", result)\n        self.assertIn(\"<li>second</li>\", result)\n\n    def test_blockquote(self):\n        \"\"\"> lines become <blockquote>.\"\"\"\n        result = _md_to_html(\"> A tip here\")\n        self.assertIn(\"<blockquote\", result)\n        self.assertIn(\"A tip here\", result)\n\n    def test_code_block(self):\n        \"\"\"Fenced code blocks become <pre><code>.\"\"\"\n        result = _md_to_html(\"```\\nprint('hi')\\n```\")\n        self.assertIn(\"<pre><code>\", result)\n        self.assertIn(\"print('hi')\", result)\n        self.assertIn(\"</code></pre>\", result)\n\n    def test_empty_input(self):\n        \"\"\"Empty string produces output without errors.\"\"\"\n        self.assertIsInstance(_md_to_html(\"\"), str)\n\n    def test_paragraph(self):\n        \"\"\"Plain text becomes a <p> tag.\"\"\"\n        result = _md_to_html(\"Hello world\")\n        self.assertIn(\"<p\", result)\n        self.assertIn(\"Hello world\", result)\n\n    def test_list_closed_after_non_list_line(self):\n        \"\"\"<ul> opened by list items is closed when a non-list line follows.\"\"\"\n        result = _md_to_html(\"- a\\n- b\\n\\nParagraph\")\n        ul_close = result.index(\"</ul>\")\n        para = result.index(\"Paragraph\")\n        self.assertLess(ul_close, para)\n\n    def test_link_in_paragraph(self):\n        \"\"\"[text](url) in a paragraph becomes an <a> tag.\"\"\"\n        result = _md_to_html(\"See [Tutorial](https://example.com) for details\")\n        self.assertIn('<a href=\"https://example.com\"', result)\n        self.assertIn(\">Tutorial</a>\", result)\n        self.assertIn('target=\"_blank\"', result)\n\n    def test_link_in_list_item(self):\n        \"\"\"[text](url) in a list item becomes an <a> tag.\"\"\"\n        result = _md_to_html(\"- [Guide](https://example.com/guide) - Full guide\")\n        self.assertIn('<a href=\"https://example.com/guide\"', result)\n        self.assertIn(\">Guide</a>\", result)\n\n    def test_link_in_blockquote(self):\n        \"\"\"[text](url) in a blockquote becomes an <a> tag.\"\"\"\n        result = _md_to_html(\"> See [docs](https://example.com)\")\n        self.assertIn('<a href=\"https://example.com\"', result)\n        self.assertIn(\">docs</a>\", result)\n\n    def test_link_in_heading(self):\n        \"\"\"[text](url) in a heading becomes an <a> tag.\"\"\"\n        result = _md_to_html(\"### [Docs](https://example.com)\")\n        self.assertIn('<a href=\"https://example.com\"', result)\n        self.assertIn(\">Docs</a>\", result)\n\n\nif __name__ == \"__main__\":\n    unittest.main()\n"
  },
  {
    "path": "acestep/ui/gradio/help_content_misc_test.py",
    "content": "\"\"\"Miscellaneous unit tests for help-content ids, CSS, and button wiring.\"\"\"\n\nimport unittest\nfrom unittest.mock import MagicMock, patch\n\nfrom acestep.ui.gradio.help_content_test_helpers import ensure_gradio_mocked\n\nensure_gradio_mocked()\n\nfrom acestep.ui.gradio.help_content import (  # noqa: E402\n    HELP_MODAL_CSS,\n    _next_id,\n    create_help_button,\n)\n\n\nclass NextIdTests(unittest.TestCase):\n    \"\"\"Tests for the unique id counter.\"\"\"\n\n    def test_ids_are_unique(self):\n        \"\"\"Each call should produce a distinct DOM id suffix.\"\"\"\n        self.assertNotEqual(_next_id(), _next_id())\n\n    def test_ids_are_strings(self):\n        \"\"\"Generated id suffixes should be strings for safe HTML formatting.\"\"\"\n        self.assertIsInstance(_next_id(), str)\n\n\nclass HelpModalCssTests(unittest.TestCase):\n    \"\"\"Tests for the exported CSS constant.\"\"\"\n\n    def test_css_not_empty(self):\n        \"\"\"Help modal CSS should not be empty.\"\"\"\n        self.assertTrue(len(HELP_MODAL_CSS) > 0)\n\n    def test_css_contains_overlay_selector(self):\n        \"\"\"CSS should include modal overlay selector.\"\"\"\n        self.assertIn(\".help-modal-overlay\", HELP_MODAL_CSS)\n\n    def test_css_contains_content_selector(self):\n        \"\"\"CSS should include modal content selector.\"\"\"\n        self.assertIn(\".help-modal-content\", HELP_MODAL_CSS)\n\n    def test_css_contains_close_selector(self):\n        \"\"\"CSS should include close-button selector.\"\"\"\n        self.assertIn(\".help-modal-close\", HELP_MODAL_CSS)\n\n    def test_css_contains_inline_btn_selector(self):\n        \"\"\"CSS should include inline help button selector.\"\"\"\n        self.assertIn(\".help-inline-btn\", HELP_MODAL_CSS)\n\n    def test_css_contains_inline_container_selector(self):\n        \"\"\"CSS should include inline help container selector.\"\"\"\n        self.assertIn(\".help-inline-container\", HELP_MODAL_CSS)\n\n\nclass CreateHelpButtonTests(unittest.TestCase):\n    \"\"\"Tests for create_help_button with mocked Gradio.\"\"\"\n\n    def test_create_help_button_calls_gr_html(self):\n        \"\"\"create_help_button should call gr.HTML and return the result.\"\"\"\n        mock_html = MagicMock()\n        with patch(\"acestep.ui.gradio.help_content.gr.HTML\", return_value=mock_html) as mock_gr_html:\n            result = create_help_button(\"getting_started\")\n\n        mock_gr_html.assert_called()\n        self.assertEqual(result, mock_html)\n\n    def test_create_help_button_html_contains_modal(self):\n        \"\"\"The generated HTML should contain modal markup.\"\"\"\n        captured = {}\n\n        def capture_html(**kwargs):\n            \"\"\"Capture HTML kwargs passed to gr.HTML for markup assertions.\"\"\"\n            captured.update(kwargs)\n            return MagicMock()\n\n        with patch(\"acestep.ui.gradio.help_content.gr.HTML\", side_effect=capture_html):\n            create_help_button(\"getting_started\")\n\n        html_value = captured.get(\"value\", \"\")\n        self.assertIn(\"help-modal-overlay\", html_value)\n        self.assertIn(\"help-inline-btn\", html_value)\n        self.assertIn(\"help-modal-close\", html_value)\n\n\nif __name__ == \"__main__\":\n    unittest.main()\n"
  },
  {
    "path": "acestep/ui/gradio/help_content_test.py",
    "content": "\"\"\"Compatibility shim for split help-content test modules.\n\nThis file is intentionally left without test cases.\nRun the focused modules:\n- help_content_md_test.py\n- help_content_i18n_test.py\n- help_content_misc_test.py\n\"\"\"\n"
  },
  {
    "path": "acestep/ui/gradio/help_content_test_helpers.py",
    "content": "\"\"\"Shared helpers for help-content unit tests.\"\"\"\n\nimport sys\nfrom unittest.mock import MagicMock\n\n\ndef ensure_gradio_mocked() -> None:\n    \"\"\"Ensure a mock gradio module exists for package imports in tests.\"\"\"\n    if \"gradio\" not in sys.modules:\n        sys.modules[\"gradio\"] = MagicMock()\n"
  },
  {
    "path": "acestep/ui/gradio/i18n/__init__.py",
    "content": "\"\"\"UI i18n package: localization loading and translation helpers.\"\"\"\nfrom acestep.ui.gradio.i18n.i18n import (  # noqa: F401\n    I18n,\n    get_i18n,\n    t,\n    available_languages_info,\n    set_language_context,\n    reset_language_context,\n)\n"
  },
  {
    "path": "acestep/ui/gradio/i18n/en.json",
    "content": "{\n  \"app\": {\n    \"title\": \"🎛️ ACE-Step V1.5 Playground💡\",\n    \"subtitle\": \"Pushing the Boundaries of Open-Source Music Generation\"\n  },\n  \"common\": {\n    \"language_metadata\": {\n      \"name\": \"English\",\n      \"native_name\": \"English\"\n    }\n  },\n  \"dataset\": {\n    \"title\": \"📊 Dataset Explorer\",\n    \"dataset_label\": \"Dataset\",\n    \"dataset_info\": \"Choose dataset to explore.\",\n    \"import_btn\": \"📥 Import Dataset\",\n    \"search_type_label\": \"Search Type\",\n    \"search_type_info\": \"How to find items.\",\n    \"search_value_label\": \"Search Value\",\n    \"search_value_placeholder\": \"Enter keys or index (leave empty for random)\",\n    \"search_value_info\": \"Keys: exact match, Index: 0 to dataset size-1.\",\n    \"instruction_label\": \"📝 Instruction\",\n    \"instruction_placeholder\": \"No instruction available\",\n    \"metadata_title\": \"📋 Item Metadata (JSON)\",\n    \"metadata_label\": \"Complete Item Information\",\n    \"source_audio\": \"Source Audio\",\n    \"target_audio\": \"Target Audio\",\n    \"reference_audio\": \"Reference Audio\",\n    \"get_item_btn\": \"🔍 Get Item\",\n    \"use_src_checkbox\": \"Use Source Audio from Dataset\",\n    \"use_src_info\": \"Check to use the source audio from dataset.\",\n    \"data_status_label\": \"📊 Data Status\",\n    \"data_status_default\": \"❌ No dataset imported\",\n    \"autofill_btn\": \"📋 Auto-fill Generation Form\"\n  },\n  \"service\": {\n    \"title\": \"🔧 Service Configuration\",\n    \"checkpoint_label\": \"Checkpoint File\",\n    \"checkpoint_info\": \"The model weights file to load. 'turbo' models are faster (4–8 steps), 'base' models are slower but support more features (guidance scale, extract/lego modes). Pick turbo for quick generation, base for maximum control.\",\n    \"refresh_btn\": \"🔄 Refresh\",\n    \"model_path_label\": \"Main Model Path\",\n    \"model_path_info\": \"The directory containing model config and architecture files. Auto-detected from your checkpoint selection. Only change this if you have a custom model setup.\",\n    \"device_label\": \"Device\",\n    \"device_info\": \"Which hardware to run on. 'auto' picks the best available (recommended). 'cuda' = NVIDIA GPU, 'mps' = Apple Silicon, 'xpu' = Intel GPU, 'cpu' = very slow, last resort.\",\n    \"lm_model_path_label\": \"5Hz LM Model Path\",\n    \"lm_model_path_info\": \"The language model that powers Think mode, CoT metadata, caption enhancement, and semantic code generation. Required for Think mode. Larger LMs produce better results but need more VRAM.\",\n    \"backend_label\": \"5Hz LM Backend\",\n    \"backend_info\": \"Engine for the 5Hz LM. vLLM = significantly faster inference, recommended for NVIDIA GPUs with ≥8GB VRAM. PyTorch (pt) = slower but works on all hardware (CPU, MPS, XPU). Use pt if vLLM won't install or you're on non-NVIDIA hardware.\",\n    \"init_llm_label\": \"Initialize 5Hz LM\",\n    \"init_llm_info\": \"Load the 5Hz LM into memory on startup. Required for: Think mode, CoT metadata generation, caption/lyrics enhancement, and Auto Score. Uses additional VRAM (~2–6GB depending on model size). Disable if you only need basic generation without LM features.\",\n    \"lm_unavailable_vram\": \"⚠️ LM not available for this GPU tier (VRAM too low)\",\n    \"flash_attention_label\": \"Use Flash Attention\",\n    \"flash_attention_info_enabled\": \"Speeds up DiT inference by ~20–30% with lower memory usage. No quality difference — purely a performance optimization. Recommended if available. Requires the flash_attn package.\",\n    \"flash_attention_info_disabled\": \"Flash attention not available (flash_attn package not installed). Install with: pip install flash-attn. Provides ~20–30% speedup with no quality change.\",\n    \"offload_cpu_label\": \"Offload to CPU\",\n    \"offload_cpu_info\": \"Moves models to system RAM when not actively running, freeing GPU VRAM for the active model. Adds a small delay (~1–3s) when switching between models. Essential for GPUs with <16GB VRAM. Negligible impact on GPUs with >24GB.\",\n    \"offload_dit_cpu_label\": \"Offload DiT to CPU\",\n    \"offload_dit_cpu_info\": \"Also offloads the DiT model to CPU (in addition to the base offload). Saves more VRAM but adds extra swap time. Requires 'Offload to CPU' to be enabled. Use on very low VRAM GPUs (<10GB).\",\n    \"compile_model_label\": \"Compile Model (torch.compile)\",\n    \"compile_model_info\": \"Optimizes the model using PyTorch compilation for faster inference. First generation takes longer (compilation overhead), subsequent generations are ~10–20% faster. Required if you want to use INT8 quantization. Recommended to keep enabled.\",\n    \"quantization_label\": \"INT8 Quantization\",\n    \"quantization_info\": \"Reduces model weights from 32-bit to 8-bit, cutting VRAM usage by ~50% with minimal quality loss. Essential for GPUs with <16GB VRAM. Requires 'Compile Model' to be enabled. Note: incompatible with LoRA adapters.\",\n    \"mlx_dit_label\": \"MLX DiT (Apple Silicon)\",\n    \"mlx_dit_info_enabled\": \"Runs the DiT diffusion model using Apple's native MLX framework instead of PyTorch MPS. Significantly faster on M1/M2/M3/M4 Macs. Recommended for Apple Silicon users.\",\n    \"mlx_dit_info_disabled\": \"MLX not available. Requires: macOS + Apple Silicon (M1/M2/M3/M4) + mlx package installed. Install with: pip install mlx.\",\n    \"init_btn\": \"Initialize Service\",\n    \"status_label\": \"Status\",\n    \"language_label\": \"UI Language\",\n    \"language_info\": \"Select interface language.\",\n    \"gpu_auto_tier\": \"Auto-detected Tier\",\n    \"tier_label\": \"GPU Tier Override\",\n    \"tier_info\": \"Override the auto-detected GPU capability tier. Each tier adjusts defaults for offload, quantization, and backend to match your VRAM. Use 'Auto' unless the auto-detection is wrong or you want to force specific optimization settings.\"\n  },\n  \"generation\": {\n    \"tab_title\": \"🎵 Generation\",\n    \"required_inputs\": \"📝 Required Inputs\",\n    \"task_type_label\": \"Task Type *\",\n    \"task_type_info\": \"Select the task type for generation.\",\n    \"instruction_label\": \"Instruction\",\n    \"instruction_info\": \"Instruction is automatically generated based on task type.\",\n    \"load_btn\": \"📂 Load\",\n    \"track_name_label\": \"Track Name\",\n    \"track_name_info\": \"Select track name for lego/extract tasks.\",\n    \"track_classes_label\": \"Track Names\",\n    \"track_classes_info\": \"Select multiple track classes for complete task.\",\n    \"audio_uploads\": \"🎵 Audio Uploads\",\n    \"reference_audio\": \"Reference Audio\",\n    \"source_audio\": \"Source Audio\",\n    \"convert_codes_btn\": \"Convert to Codes\",\n    \"analyze_btn\": \"🔍 Analyze\",\n    \"sample_btn\": \"🎲 Click Me\",\n    \"lm_codes_hints\": \"🎼 LM Codes Hints\",\n    \"lm_codes_label\": \"LM Codes Hints\",\n    \"lm_codes_placeholder\": \"<|audio_code_10695|><|audio_code_54246|>.\",\n    \"lm_codes_info\": \"Paste LM codes hints for text2music generation.\",\n    \"lm_codes_sample\": \"LM Codes Hints (Sample {n})\",\n    \"lm_codes_sample_info\": \"Codes for sample {n}.\",\n    \"transcribe_btn\": \"Transcribe\",\n    \"repainting_controls\": \"🎨 Repainting Controls (seconds)\",\n    \"repainting_start\": \"Repainting Start\",\n    \"repainting_end\": \"Repainting End\",\n    \"mode_label\": \"Generation Mode *\",\n    \"mode_info\": \"Simple = describe in plain language, AI handles the rest (best for quick ideas). Custom = full manual control over caption, lyrics, BPM, key, etc. Remix = upload audio and restyle it with a new caption/lyrics. Repaint = upload audio and regenerate a specific time range. Extract = isolate a single track (vocals, drums, etc). Lego = replace one track in existing audio. Complete = fill in missing tracks.\",\n    \"mode_info_simple\": \"Simple: Describe your music in plain language — AI generates caption, lyrics, BPM, key, and structure for you. Best for quick ideas or if you're not sure what settings to use. Switch to Custom for full manual control.\",\n    \"mode_info_custom\": \"Custom: Full manual control over caption, lyrics, BPM, key, duration, and all generation parameters. Use this when you know exactly what you want. Switch to Simple if you'd rather describe your idea and let AI fill in the details.\",\n    \"mode_info_remix\": \"Remix: Upload source audio and restyle it with your own caption and lyrics. The AI uses the original as a structural guide while applying your new style. Adjust Remix Strength to control how closely it follows the original (high = faithful cover, low = loose reinterpretation).\",\n    \"mode_info_repaint\": \"Repaint: Upload source audio and regenerate only a specific time range (start/end in seconds). Everything outside that range stays untouched. Great for fixing a bad section or replacing a specific part without re-generating the whole track.\",\n    \"mode_info_extract\": \"Extract: Isolate a single track (vocals, drums, bass, etc.) from source audio using AI stem separation. Useful for creating instrumentals, acapellas, or isolating parts for remixing.\",\n    \"mode_info_lego\": \"Lego: Replace a specific track (e.g. drums, vocals) in your source audio while keeping everything else. Upload multi-track audio and choose which stem to regenerate with your new caption/lyrics.\",\n    \"mode_info_complete\": \"Complete: Fill in missing tracks from source audio. If you have a partial mix (e.g. just vocals and guitar), the AI generates the missing parts (drums, bass, etc.) to create a full arrangement.\",\n    \"mode_simple\": \"Simple\",\n    \"mode_custom\": \"Custom\",\n    \"simple_query_label\": \"Song Description *\",\n    \"simple_query_placeholder\": \"Describe the music you want to create, e.g., 'a soft Bengali love song for a quiet evening'. Leave empty for a random sample.\",\n    \"simple_query_info\": \"Enter a natural language description of the music you want to generate.\",\n    \"simple_vocal_language_label\": \"Vocal Language\",\n    \"simple_vocal_language_info\": \"Select preferred language(s) for lyrics. Use 'unknown' for any language.\",\n    \"create_sample_btn\": \"Create Sample\",\n    \"caption_title\": \"📝 Music Caption\",\n    \"caption_label\": \"Music Caption\",\n    \"caption_placeholder\": \"A peaceful acoustic guitar melody with soft vocals.\",\n    \"caption_info\": \"Describe the style, genre, instruments, and mood.\",\n    \"lyrics_title\": \"📝 Lyrics\",\n    \"lyrics_label\": \"Lyrics\",\n    \"lyrics_placeholder\": \"[Verse 1]\\\\nUnder the starry night\\\\nI feel so alive.\",\n    \"lyrics_info\": \"Song lyrics with structure.\",\n    \"instrumental_label\": \"Instrumental\",\n    \"format_btn\": \"Format\",\n    \"format_caption_btn\": \"Enhance Caption\",\n    \"format_lyrics_btn\": \"Enhance Lyrics\",\n    \"optional_params\": \"⚙️ Optional Parameters\",\n    \"optional_music_props\": \"🎵 Music Properties\",\n    \"optional_gen_settings\": \"📐 Generation Settings\",\n    \"advanced_dit_section\": \"🎛️ DiT Diffusion\",\n    \"advanced_lm_section\": \"🤖 LM Generation\",\n    \"advanced_output_section\": \"🔊 Audio Output & Post-processing\",\n    \"advanced_automation_section\": \"⚡ Automation & Batch\",\n    \"vocal_language_label\": \"Vocal Language\",\n    \"vocal_language_info\": \"Language for generated vocals. Set to match your lyrics language for best results. 'unknown' = let the model decide (good for instrumental or multilingual). 'instrumental' = no vocals.\",\n    \"bpm_label\": \"BPM (Beats Per Minute)\",\n    \"bpm_info\": \"Tempo of the song. Slow ballad: 60–80. Pop/Rock: 100–130. Dance/EDM: 120–140. Fast punk/metal: 160–200. Leave empty or check 'Auto' to let the model choose based on your caption.\",\n    \"keyscale_label\": \"Key\",\n    \"keyscale_placeholder\": \"e.g. C Major, A Minor, F# Minor\",\n    \"keyscale_info\": \"Musical key of the song (e.g. 'C Major', 'Am', 'F# Minor'). Major keys sound bright/happy, minor keys sound dark/sad. Leave empty or check 'Auto' to let the model choose.\",\n    \"timesig_label\": \"Time Signature\",\n    \"timesig_info\": \"Beats per measure. 4 = 4/4 (most pop/rock/electronic). 3 = 3/4 (waltz feel). 6 = 6/8 (compound, flowing feel). 2 = 2/4 (march feel). Use 'N/A' or Auto to let the model decide.\",\n    \"duration_label\": \"Audio Duration (seconds)\",\n    \"duration_info\": \"Length of the generated audio in seconds. Longer durations need more VRAM and time. -1 = let the model decide based on lyrics/structure. Check 'Auto' for automatic duration.\",\n    \"batch_size_label\": \"Batch Size\",\n    \"batch_size_info\": \"How many variations to generate at once. Higher = more options to choose from, but uses more VRAM and takes longer. Generate 2–4 to compare and pick the best result.\",\n    \"advanced_settings\": \"⚙️ Settings\",\n    \"inference_steps_label\": \"DiT Inference Steps\",\n    \"inference_steps_info\": \"How many denoising passes the DiT model makes. More steps = higher quality but slower. Turbo models: 4–8 steps (default 8, diminishing returns above 8). SFT models: 30–100 steps (default 50). Base/unknown models default to 32 steps. Doubling steps roughly doubles generation time.\",\n    \"guidance_scale_label\": \"DiT Guidance Scale (Base model only)\",\n    \"guidance_scale_info\": \"Controls how strictly the output follows your caption/prompt. Higher (10–15) = more faithful to prompt but can sound harsh or distorted. Lower (1–5) = more natural/creative but may drift from your description. Default 7.0. Base model only — has no effect on turbo models.\",\n    \"seed_label\": \"Seed\",\n    \"seed_info\": \"Fixed number for reproducible results — same seed + same settings = same output. Use comma-separated values (e.g. '42,123,456') to set per-sample seeds in a batch. -1 = random.\",\n    \"random_seed_label\": \"Random Seed\",\n    \"random_seed_info\": \"When enabled, generates a new random seed each time so every generation is unique. Disable this and set a fixed seed to reproduce a specific result.\",\n    \"audio_format_label\": \"Audio Format\",\n    \"audio_format_info\": \"FLAC = lossless, large files. MP3 = small files, slight quality loss. WAV 32-bit = studio quality, largest files. Opus/AAC = efficient lossy compression. Choose FLAC or WAV for production, MP3 for sharing.\",\n    \"use_adg_label\": \"Use ADG (Angle Domain Guidance)\",\n    \"use_adg_info\": \"Alternative guidance method that can improve prompt adherence with fewer artifacts than standard CFG. Try enabling if you get distortion at high guidance scales. Experimental — may not always improve results.\",\n    \"shift_label\": \"Shift\",\n    \"shift_info\": \"Controls the noise schedule timing. Higher values (3–5) concentrate denoising effort on early steps (better structure). Lower values (1–2) spread effort more evenly (finer details). Default 3.0. Only affects base models — turbo models ignore this.\",\n    \"infer_method_label\": \"Inference Method\",\n    \"infer_method_info\": \"ODE (Euler): Deterministic and faster — same seed always gives same result. Recommended for most use cases. SDE (Stochastic): Adds randomness during diffusion — can produce more varied/creative results but less predictable. Try SDE if ODE results feel too 'safe'.\",\n    \"custom_timesteps_label\": \"Custom Timesteps\",\n    \"custom_timesteps_info\": \"Advanced: Manually define the denoising schedule as comma-separated values from 1.0→0.0 (e.g. '0.97,0.76,0.615,0.5,0.395,0.28,0.18,0.085,0'). Overrides both Inference Steps and Shift. Leave empty to use automatic scheduling. Only change this if you know what you're doing.\",\n    \"cfg_interval_start\": \"CFG Interval Start\",\n    \"cfg_interval_start_info\": \"Controls when CFG guidance kicks in during denoising (0.0 = from the very start, 1.0 = never). Lower values apply guidance for more of the process, giving stronger prompt adherence. Raising this skips guidance in early steps, which can reduce artifacts while still steering the output. Default 0.0. Only affects base models.\",\n    \"cfg_interval_end\": \"CFG Interval End\",\n    \"cfg_interval_end_info\": \"Controls when CFG guidance stops during denoising (1.0 = at the very end, 0.0 = immediately). Lower values stop guidance early, letting later steps refine freely — can reduce harshness. Higher values maintain guidance longer for stronger prompt control. Default 1.0. Only affects base models.\",\n    \"lm_params_title\": \"🤖 LM Generation Parameters\",\n    \"lm_temperature_label\": \"LM Temperature\",\n    \"lm_temperature_info\": \"Controls creativity vs predictability of the 5Hz LM. Lower (0.0–0.5) = safer, more conventional musical choices. Higher (0.8–1.5) = more creative/surprising but riskier. Very high (1.5+) = chaotic, may produce nonsense. Default 0.85 is a good balance. Start here and adjust based on results.\",\n    \"lm_cfg_scale_label\": \"LM CFG Scale\",\n    \"lm_cfg_scale_info\": \"How strongly the LM follows your prompt vs generating freely. 1.0 = no guidance (LM ignores prompt influence). 1.5–2.0 = moderate guidance, good balance. 2.5–3.0 = strong guidance, very prompt-faithful but can reduce variety. 5.0–7.0 = maximum prompt control, may reduce musical quality or introduce artifacts. Values above 7.0 are experimental. Requires a negative prompt to work (set automatically if empty). Only matters when 5Hz LM is active.\",\n    \"lm_top_k_label\": \"LM Top-K\",\n    \"lm_top_k_info\": \"Limits LM choices to the K most likely tokens at each step. Lower (10–30) = more focused/predictable output. Higher (50–100) = more diverse. 0 = disabled (no filtering). Works alongside Top-P — both can be active. Start with 0 (disabled) unless you want to constrain diversity.\",\n    \"lm_top_p_label\": \"LM Top-P (Nucleus Sampling)\",\n    \"lm_top_p_info\": \"Keeps only tokens whose cumulative probability reaches P. 0.9 = consider the top 90% most likely tokens (cuts unlikely outliers). Lower (0.5–0.8) = more focused. 1.0 = disabled (consider all tokens). More adaptive than Top-K. Good default: 0.9–0.95.\",\n    \"lm_negative_prompt_label\": \"LM Negative Prompt\",\n    \"lm_negative_prompt_placeholder\": \"Enter negative prompt for CFG (default: NO USER INPUT)\",\n    \"lm_negative_prompt_info\": \"Tells the LM what to avoid. Only effective when LM CFG Scale > 1.0. The LM steers away from this prompt and toward your actual caption. Leave empty for the default behavior. Example: 'low quality, noise, distorted' to push away from poor outputs.\",\n    \"advanced_dit_params\": \"Advanced DiT Parameters\",\n    \"cot_metas_label\": \"CoT Metas (Chain-of-Thought Metadata)\",\n    \"cot_metas_info\": \"When enabled, the LM 'thinks through' music metadata (BPM, key, structure) before generating. Produces more coherent results but adds ~2–5s per generation. Disable to skip this step and use your manually set metadata directly. Recommended: keep enabled unless you've set all metadata yourself.\",\n    \"cot_language_label\": \"CoT Language Detection\",\n    \"cot_language_info\": \"When enabled, the LM auto-detects the vocal language during chain-of-thought reasoning. Useful when language is ambiguous or set to 'unknown'. Disable if you've explicitly set the vocal language.\",\n    \"constrained_debug_label\": \"Constrained Decoding Debug\",\n    \"constrained_debug_info\": \"Shows detailed logs of how the LM's output tokens are being filtered/constrained. Only useful for developers debugging token generation issues. Leave off for normal use.\",\n    \"auto_score_label\": \"Auto Score\",\n    \"auto_score_info\": \"Automatically calculates a quality score (0–1) for each generated audio using perplexity. Higher = better. Useful for comparing results in a batch to find the best one. Adds a few seconds per sample.\",\n    \"auto_lrc_label\": \"Auto LRC\",\n    \"auto_lrc_info\": \"Automatically generates timestamped lyrics (LRC format) for each generated audio. Useful for karaoke-style display or syncing lyrics to music. Adds processing time per sample.\",\n    \"lm_batch_chunk_label\": \"LM Batch Chunk Size\",\n    \"lm_batch_chunk_info\": \"How many samples the LM processes at once. Higher = faster batch generation but uses more VRAM. Lower if you get out-of-memory errors during batch generation. Default 8. Reduce to 1–4 on GPUs with <12GB VRAM.\",\n    \"codes_strength_label\": \"LM Codes Strength\",\n    \"codes_strength_info\": \"What fraction of DiT denoising steps use LM-generated semantic codes as guidance. Higher (0.7–1.0) = output closely follows the LM's musical plan. Lower (0.1–0.4) = DiT has more creative freedom. 0 = codes ignored entirely. Default 1.0 is a good starting point.\",\n    \"cover_strength_label\": \"Audio Cover Strength\",\n    \"cover_strength_info\": \"What fraction of denoising steps reference the source audio structure. Higher = output sounds closer to the original. Lower = more creative reinterpretation. Adjust alongside Cover Strength (Melody Retention) for fine-tuned remix control.\",\n    \"remix_strength_label\": \"Remix Strength\",\n    \"remix_strength_info\": \"How closely the remix follows the source audio's structure and melody. Higher (0.7–1.0) = very close to original, subtle style changes only. Lower (0.1–0.4) = loose interpretation, major creative liberties. 0.5 is a good starting point — adjust up for faithful covers, down for wild remixes.\",\n    \"cover_noise_strength_label\": \"Cover Strength (Melody Retention)\",\n    \"cover_noise_strength_info\": \"Controls how much of the original melody is preserved during remix. 0 = no melody retention (pure style transfer from your caption). 0.1–0.25 = recommended range with SFT model (restores melody while allowing style changes). 1.0 = maximum melody retention. Higher values keep the tune but may resist style changes — adjust your caption if needed.\",\n    \"enable_normalization\": \"Enable Normalization\",\n    \"enable_normalization_info\": \"Adjusts the final audio volume to a consistent peak level. Prevents clipping (distortion from too-loud audio) and ensures all outputs are at similar loudness. Recommended to keep enabled for consistent results.\",\n    \"normalization_db\": \"Target Peak (dB)\",\n    \"normalization_db_info\": \"How loud the normalized audio should be. -1.0 dB = industry standard safe peak (recommended, leaves headroom). -0.1 dB = maximum loudness before clipping. Lower values (e.g. -3.0) = quieter, more headroom for further mixing/mastering.\",\n    \"fade_in_duration\": \"Fade In (seconds)\",\n    \"fade_in_duration_info\": \"Gradually increases volume from silence at the start of the audio. 0 = no fade (starts at full volume). 1–3s = subtle intro. 5–10s = dramatic slow build. Useful for avoiding abrupt starts.\",\n    \"fade_out_duration\": \"Fade Out (seconds)\",\n    \"fade_out_duration_info\": \"Gradually decreases volume to silence at the end of the audio. 0 = no fade (may end abruptly). 2–5s = smooth ending. Useful for avoiding harsh cutoffs at the end of generated audio.\",\n    \"latent_shift\": \"Latent Shift\",\n    \"latent_shift_info\": \"Advanced: Shifts the internal audio representation before decoding. Try small negative values (e.g. -0.04) if your outputs have clipping/distortion. 0 = no shift (default). Only adjust if you're hearing audio artifacts.\",\n    \"latent_rescale\": \"Latent Rescale\",\n    \"latent_rescale_info\": \"Advanced: Scales the internal audio representation before decoding. Values below 1.0 (e.g. 0.91) can reduce clipping/distortion. 1.0 = no rescale (default). Only adjust if you're hearing audio artifacts despite normalization.\",\n    \"score_sensitivity_label\": \"Quality Score Sensitivity\",\n    \"score_sensitivity_info\": \"Controls how the quality score maps to 0–1 range. Lower values (e.g. 0.5) = more spread between scores, easier to distinguish good from bad. Higher values = scores cluster together. Default 1.0. Adjust if all your scores look too similar.\",\n    \"lora_accordion_title\": \"🔧 LoRA Adapter\",\n    \"lora_path_label\": \"LoRA Path\",\n    \"lora_path_placeholder\": \"./lora_output/final/adapter\",\n    \"lora_path_info\": \"Path to your trained LoRA adapter directory. Use the Export button in the Training tab to create one, or download a community LoRA.\",\n    \"load_lora_btn\": \"📥 Load LoRA\",\n    \"unload_lora_btn\": \"🗑️ Unload\",\n    \"use_lora_label\": \"Use LoRA\",\n    \"use_lora_info\": \"Toggle the loaded LoRA adapter on/off during generation. When enabled, the LoRA's trained style is applied. Disable to generate with the base model for comparison.\",\n    \"lora_scale_label\": \"LoRA Scale\",\n    \"lora_scale_info\": \"How strongly the LoRA style is applied. 0 = LoRA has no effect (same as base model). 0.5 = blended style. 1.0 = full LoRA effect. Values above 1.0 may over-amplify the style. Start at 1.0 and reduce if the style is too strong.\",\n    \"lora_status_label\": \"LoRA Status\",\n    \"lora_status_default\": \"No LoRA loaded\",\n    \"think_label\": \"Think\",\n    \"parallel_thinking_label\": \"ParallelThinking\",\n    \"parallel_thinking_info\": \"When generating multiple samples (batch size > 1), processes all LM thinking in parallel instead of one-by-one. Faster but uses more VRAM. Disable if you get out-of-memory errors with large batches.\",\n    \"generate_btn\": \"🎵 Generate Music\",\n    \"extract_stem_btn\": \"🎵 Extract Stem\",\n    \"add_stem_btn\": \"🎵 Add Stem\",\n    \"stem_area_controls\": \"🧩 New Stem Area (seconds)\",\n    \"stem_start\": \"Stem Start\",\n    \"stem_end\": \"Stem End\",\n    \"autogen_label\": \"AutoGen\",\n    \"caption_rewrite_label\": \"CaptionRewrite\",\n    \"caption_rewrite_info\": \"Lets the LM enhance and expand your caption before generation. Your brief description gets rewritten into a more detailed, model-friendly prompt. Useful if you write short captions and want the LM to fill in musical details.\",\n    \"auto_label\": \"Auto\",\n    \"bpm_auto_label\": \"BPM Auto\",\n    \"key_auto_label\": \"Key Auto\",\n    \"timesig_auto_label\": \"TimeSig Auto\",\n    \"vocal_lang_auto_label\": \"Language Auto\",\n    \"duration_auto_label\": \"Duration Auto\",\n    \"reset_all_auto\": \"🔄 Reset All to Auto\"\n  },\n  \"results\": {\n    \"title\": \"🎵 Results\",\n    \"generated_music\": \"🎵 Generated Music (Sample {n})\",\n    \"send_to_remix_btn\": \"🔗 Send To Remix\",\n    \"send_to_repaint_btn\": \"🔗 Send To Repaint\",\n    \"save_btn\": \"💾 Save\",\n    \"score_btn\": \"📊 Get Score\",\n    \"lrc_btn\": \"🎵 Get LRC\",\n    \"save_lrc_btn\": \"💾 Save LRC\",\n    \"convert_to_codes_btn\": \"🔄 Convert To Codes\",\n    \"quality_score_label\": \"Quality Score (Sample {n})\",\n    \"quality_score_placeholder\": \"Click 'Score' to calculate perplexity-based quality score\",\n    \"codes_label\": \"LM Codes (Sample {n})\",\n    \"lrc_label\": \"Lyrics Timestamps (Sample {n})\",\n    \"lrc_placeholder\": \"Click 'LRC' to generate timestamps\",\n    \"details_accordion\": \"📊 Score & LRC & LM Codes\",\n    \"generation_status\": \"Generation Status\",\n    \"current_batch\": \"Current Batch\",\n    \"batch_indicator\": \"Batch {current} / {total}\",\n    \"next_batch_status\": \"Next Batch Status\",\n    \"prev_btn\": \"◀ Previous\",\n    \"next_btn\": \"Next ▶\",\n    \"restore_params_btn\": \"↙️ Apply These Settings to UI (Restore Batch Parameters)\",\n    \"batch_results_title\": \"📁 Batch Results & Generation Details\",\n    \"all_files_label\": \"📁 All Generated Files (Download)\",\n    \"generation_details\": \"Generation Details\"\n  },\n  \"messages\": {\n    \"no_audio_to_save\": \"❌ No audio to save\",\n    \"save_success\": \"✅ Saved audio and metadata to {filename}\",\n    \"save_failed\": \"❌ Failed to save: {error}\",\n    \"no_file_selected\": \"⚠️ No file selected\",\n    \"params_loaded\": \"✅ Parameters loaded from {filename}\",\n    \"invalid_json\": \"❌ Invalid JSON file: {error}\",\n    \"load_error\": \"❌ Error loading file: {error}\",\n    \"example_loaded\": \"📁 Loaded example from {filename}\",\n    \"example_failed\": \"Failed to parse JSON file {filename}: {error}\",\n    \"example_error\": \"Error loading example: {error}\",\n    \"lm_generated\": \"🤖 Generated example using LM\",\n    \"lm_fallback\": \"Failed to generate example using LM, falling back to examples directory\",\n    \"lm_not_initialized\": \"❌ 5Hz LM not initialized. Please initialize it first.\",\n    \"think_requires_lm\": \"⚠️ 'Think' requires 5Hz LM to be initialized. Think has been disabled — generation will proceed without LM thinking.\",\n    \"autogen_enabled\": \"🔄 AutoGen enabled - next batch will generate after this\",\n    \"batch_ready\": \"✅ Batch {n} ready! Click 'Next' to view.\",\n    \"batch_generating\": \"🔄 Starting background generation for Batch {n}.\",\n    \"batch_failed\": \"❌ Background generation failed: {error}\",\n    \"viewing_batch\": \"✅ Viewing Batch {n}\",\n    \"at_first_batch\": \"Already at first batch\",\n    \"at_last_batch\": \"No next batch available\",\n    \"batch_not_found\": \"Batch {n} not found in queue\",\n    \"no_batch_data\": \"No batch data found to restore.\",\n    \"params_restored\": \"✅ UI Parameters restored from Batch {n}\",\n    \"scoring_failed\": \"❌ Error: Batch data not found\",\n    \"no_codes\": \"❌ No audio codes available. Please generate music first.\",\n    \"score_failed\": \"❌ Scoring failed: {error}\",\n    \"score_error\": \"❌ Error calculating score: {error}\",\n    \"lrc_no_batch_data\": \"❌ No batch data found. Please generate music first.\",\n    \"lrc_no_extra_outputs\": \"❌ No extra outputs found. Condition tensors not available.\",\n    \"lrc_missing_tensors\": \"❌ Missing required tensors for LRC generation.\",\n    \"lrc_sample_not_exist\": \"❌ Sample does not exist in current batch.\",\n    \"lrc_empty_result\": \"⚠️ LRC generation produced empty result.\",\n    \"empty_query\": \"⚠️ Please enter a music description.\",\n    \"sample_creation_failed\": \"❌ Failed to create sample. Please try again.\",\n    \"sample_created\": \"✅ Sample created! Review the caption and lyrics, then click Generate Music.\",\n    \"simple_examples_not_found\": \"⚠️ Simple mode examples directory not found.\",\n    \"simple_examples_empty\": \"⚠️ No example files found in simple mode examples.\",\n    \"simple_example_loaded\": \"🎲 Loaded random example from {filename}\",\n    \"format_success\": \"✅ Caption and lyrics formatted successfully\",\n    \"format_failed\": \"❌ Format failed: {error}\",\n    \"skipping_metas_cot\": \"⚡ Skipping Phase 1 metas COT (sample already formatted)\",\n    \"invalid_timesteps_format\": \"⚠️ Invalid timesteps format. Using default schedule.\",\n    \"timesteps_out_of_range\": \"⚠️ Timesteps must be in range [0, 1]. Using default schedule.\",\n    \"timesteps_count_mismatch\": \"⚠️ Timesteps count ({actual}) differs from inference_steps ({expected}). Using timesteps count.\",\n    \"audio_format_invalid\": \"{role} format is invalid or unsupported. Please upload a valid audio file.\"\n  },\n  \"training\": {\n    \"tab_title\": \"🎓 LoRA Training\",\n    \"tab_dataset_builder\": \"📁 Dataset Builder\",\n    \"tab_train_lora\": \"🚀 Train LoRA\",\n    \"quick_start_title\": \"🚀 Quick Start\",\n    \"load_dataset_label\": \"Dataset JSON Path\",\n    \"load_dataset_info\": \"Load a previously saved dataset.\",\n    \"load_btn\": \"📂 Load\",\n    \"load_status\": \"Load Status\",\n    \"scan_label\": \"Audio Directory Path\",\n    \"scan_info\": \"Scan for audio files (wav, mp3, flac, ogg, opus).\",\n    \"scan_btn\": \"🔍 Scan\",\n    \"scan_status\": \"Scan Status\",\n    \"found_audio_files\": \"Found Audio Files\",\n    \"dataset_name\": \"Dataset Name\",\n    \"dataset_name_placeholder\": \"Enter dataset name\",\n    \"dataset_settings_header\": \"Dataset Settings\",\n    \"tag_prepend\": \"Prepend (Tag, Caption)\",\n    \"tag_append\": \"Append (Caption, Tag)\",\n    \"tag_replace\": \"Replace Caption\",\n    \"step2_title\": \"Step 2: AI Auto-Labeling\",\n    \"step2_instruction\": \"Click the button below to use AI to automatically generate metadata for all audio files:\\n- **Caption**: Music style, genre, mood description\\n- **BPM**: Beats per minute\\n- **Key**: Music key (e.g. C Major, Am)\\n- **Time Signature**: 4/4, 3/4 etc.\",\n    \"step3_title\": \"Step 3: Preview & Edit\",\n    \"step4_title\": \"Step 4: Save Dataset\",\n    \"step5_title\": \"Step 5: Preprocess to Tensors\",\n    \"step5_intro\": \"**Preprocessing converts your dataset into pre-computed tensors for fast training.**\\n\\nYou can:\\n- Use the dataset from steps 1-4 above, **OR**\\n- Load an existing dataset JSON file (if you have one saved)\",\n    \"step5_details\": \"This step will:\\n- Encode audio to VAE latents\\n- Encode captions and lyrics to text embeddings\\n- Run condition encoders\\n- Save all tensors to `.pt` files\\n\\n⚠️ **This requires loading models and may take a few minutes.**\",\n    \"train_tensor_selection_desc\": \"Select the directory containing preprocessed tensor files (`.pt` files).\\nThese are created using the 'Preprocess' button in the 'Dataset Builder' tab.\",\n    \"all_instrumental\": \"All Instrumental\",\n    \"all_instrumental_info\": \"Check if all tracks are instrumental (no vocals).\",\n    \"custom_tag\": \"Custom Trigger Tag\",\n    \"custom_tag_info\": \"Unique tag to activate this LoRA style.\",\n    \"tag_position\": \"Tag Position\",\n    \"tag_position_info\": \"Where to place the custom tag in the caption.\",\n    \"genre_ratio\": \"Genre Ratio (%)\",\n    \"genre_ratio_info\": \"0%=All Caption, 100%=All Genre. Single sample override takes precedence.\",\n    \"skip_metas\": \"Skip BPM/Key/TimeSig\",\n    \"skip_metas_info\": \"Skip BPM/Key/TimeSig generation. Captions and genres are still generated by LM.\",\n    \"only_unlabeled\": \"Only Unlabeled\",\n    \"only_unlabeled_info\": \"Only label samples with no caption (for continuing failed labeling).\",\n    \"auto_label_btn\": \"🏷️ Auto-Label All\",\n    \"label_progress\": \"Labeling Progress\",\n    \"select_sample\": \"Select Sample #\",\n    \"select_sample_info\": \"Select sample to preview and edit.\",\n    \"audio_preview\": \"Audio Preview\",\n    \"filename\": \"Filename\",\n    \"caption\": \"Caption\",\n    \"genre\": \"Genre\",\n    \"prompt_override_label\": \"Prompt Override (This Sample)\",\n    \"prompt_override_info\": \"Override global ratio for this sample.\",\n    \"lyrics_editable_label\": \"Lyrics (Editable for Training)\",\n    \"raw_lyrics_label\": \"Raw Lyrics (from .txt file)\",\n    \"no_lyrics_placeholder\": \"(No .txt lyrics file)\",\n    \"bpm\": \"BPM\",\n    \"key_label\": \"Key\",\n    \"key_placeholder\": \"C Major\",\n    \"time_sig\": \"Time Sig\",\n    \"duration_s\": \"Duration (s)\",\n    \"language\": \"Language\",\n    \"instrumental\": \"Instrumental\",\n    \"save_changes_btn\": \"💾 Save Changes\",\n    \"edit_status\": \"Edit Status\",\n    \"save_path\": \"Save Path\",\n    \"save_path_info\": \"Path to save dataset JSON.\",\n    \"save_dataset_btn\": \"💾 Save Dataset\",\n    \"save_status\": \"Save Status\",\n    \"load_existing_label\": \"Load Existing Dataset\",\n    \"load_existing_info\": \"Path to previously saved dataset JSON file.\",\n    \"load_dataset_btn\": \"📂 Load Dataset\",\n    \"tensor_output_dir\": \"Tensor Output Directory\",\n    \"tensor_output_info\": \"Directory to save preprocessed tensor files.\",\n    \"preprocess_btn\": \"⚡ Preprocess\",\n    \"preprocess_progress\": \"Preprocessing Progress\",\n    \"preprocessed_tensors_dir\": \"Preprocessed Tensors Directory\",\n    \"preprocessed_tensors_info\": \"Directory containing preprocessed .pt tensor files.\",\n    \"dataset_info\": \"Dataset Info.\",\n    \"lora_rank\": \"LoRA Rank (r)\",\n    \"lora_rank_info\": \"Higher capacity but more VRAM.\",\n    \"lora_alpha\": \"LoRA Alpha\",\n    \"lora_alpha_info\": \"Scaling factor (usually 2x Rank).\",\n    \"lora_dropout\": \"LoRA Dropout\",\n    \"learning_rate\": \"Learning Rate\",\n    \"learning_rate_info\": \"Start with 3e-4, adjust as needed.\",\n    \"max_epochs\": \"Max Epochs\",\n    \"batch_size\": \"Batch Size\",\n    \"batch_size_info\": \"Increase if VRAM allows.\",\n    \"gradient_accumulation\": \"Gradient Accumulation\",\n    \"gradient_accumulation_info\": \"Effective Batch Size = batch_size * accum_steps.\",\n    \"save_every_n_epochs\": \"Save Every N Epochs\",\n    \"shift\": \"Shift\",\n    \"shift_info\": \"Timestep shift for Turbo models.\",\n    \"seed\": \"Seed\",\n    \"output_dir\": \"Output Directory\",\n    \"output_dir_info\": \"Directory to save trained LoRA weights.\",\n    \"start_training_btn\": \"🚀 Start Training\",\n    \"stop_training_btn\": \"⏹️ Stop Training\",\n    \"training_progress\": \"Training Progress\",\n    \"training_log\": \"Training Log\",\n    \"training_loss_title\": \"Training Loss\",\n    \"step\": \"Step\",\n    \"loss\": \"Loss\",\n    \"export_header\": \"Export LoRA\",\n    \"export_path\": \"Export Path\",\n    \"export_lora_btn\": \"📦 Export LoRA\",\n    \"export_status\": \"Export Status\",\n    \"stop_no_training\": \"ℹ No training in progress\",\n    \"stop_stopping\": \"⏹️ Stopping training...\",\n    \"latest_auto\": \"Latest (auto)\",\n    \"export_path_required\": \"❌ Please enter an export path\",\n    \"invalid_lora_output_dir\": \"❌ Invalid LoRA output directory\",\n    \"no_checkpoints_found\": \"❌ No checkpoints found\",\n    \"no_trained_model_found\": \"❌ No trained model found in {path}\",\n    \"invalid_export_path\": \"❌ Invalid export path\",\n    \"lora_exported\": \"✅ LoRA exported to {path}\",\n    \"export_failed\": \"❌ Export failed: {error}\",\n    \"lokr_output_dir_required\": \"⚠️ Enter LoKr output directory first\",\n    \"lokr_no_checkpoints_use_latest\": \"ℹ No checkpoints found; export will use latest available weights\",\n    \"lokr_no_exportable_checkpoints\": \"ℹ No exportable epoch checkpoints found\",\n    \"lokr_found_checkpoints\": \"✅ Found {count} LoKr checkpoints\",\n    \"lokr_selected_epoch_not_found\": \"❌ Selected epoch not found: {chosen}. Available: {available}\",\n    \"lokr_no_weights_selected_epoch\": \"❌ No LoKr weights found for selected epoch: {epoch}\",\n    \"lokr_no_weights_latest_checkpoint\": \"❌ No LoKr weights found in latest checkpoint: {checkpoint}\",\n    \"lokr_no_trained_weights_found\": \"❌ No trained LoKr weights found in {path}\",\n    \"lokr_exported\": \"✅ LoKr exported to {path}\",\n    \"tab_train_lokr\": \"🚀 Train LoKr\",\n    \"train_section_tensors\": \"Preprocessed Tensors\",\n    \"train_section_lora\": \"LoRA Settings\",\n    \"train_section_params\": \"Training Parameters\",\n    \"lokr_section_tensors\": \"Preprocessed Tensors\",\n    \"lokr_section_settings\": \"LoKr Settings\",\n    \"lokr_tensor_selection_desc\": \"Select the directory containing preprocessed tensor files (`.pt` files).\\nThese are created using the 'Preprocess' button in the 'Dataset Builder' tab.\",\n    \"lokr_linear_dim\": \"LoKr Linear Dim\",\n    \"lokr_linear_dim_info\": \"Rank (dimension) for LoKr adaptation matrices.\",\n    \"lokr_linear_alpha\": \"LoKr Linear Alpha\",\n    \"lokr_linear_alpha_info\": \"Scaling factor for LoKr (usually similar to dim).\",\n    \"lokr_factor\": \"LoKr Factor\",\n    \"lokr_factor_info\": \"Kronecker factor (-1 for auto).\",\n    \"lokr_decompose_both\": \"Decompose Both Sides\",\n    \"lokr_decompose_both_info\": \"When enabled, decomposes both left and right matrices.\",\n    \"lokr_use_tucker\": \"Use Tucker Decomposition\",\n    \"lokr_use_tucker_info\": \"Apply Tucker decomposition when applicable.\",\n    \"lokr_use_scalar\": \"Use Scalar Gate\",\n    \"lokr_use_scalar_info\": \"Enable scalar gating for LoKr weights.\",\n    \"lokr_weight_decompose\": \"Weight Decompose (WD)\",\n    \"lokr_weight_decompose_info\": \"Enable weight decomposition for more stable LoKr training.\",\n    \"lokr_learning_rate_info\": \"LoKr commonly uses a higher LR than LoRA. Tune per dataset.\",\n    \"lokr_output_dir_info\": \"Directory to save trained LoKr weights.\",\n    \"start_lokr_training_btn\": \"🚀 Start Training LoKr\",\n    \"lokr_training_loss_title\": \"LoKr Training Loss\",\n    \"lokr_export_header\": \"Export LoKr\",\n    \"export_lokr_btn\": \"📦 Export LoKr\",\n    \"lokr_checkpoint_epoch\": \"Checkpoint Epoch\",\n    \"lokr_checkpoint_epoch_info\": \"Select a specific epoch checkpoint to export, or keep Latest (auto).\",\n    \"refresh_epochs_btn\": \"↻ Refresh Epochs\"\n  },\n  \"help\": {\n    \"btn_label\": \"?\",\n    \"close_label\": \"✕\",\n    \"getting_started\": \"## Getting Started\\n\\n1. **Select a model** in the Settings accordion (e.g. `acestep-v15-turbo`)\\n2. **Choose a 5Hz LM** if you want Thinking mode (recommended)\\n3. Click **Initialize Service** and wait for the green status\\n4. Pick a **Generation Mode** (start with Simple)\\n5. Describe your music and click **Generate Music**\\n\\n> **Tip:** Turbo models are fastest. Enable \\\"Think\\\" for smarter generation.\",\n    \"service_config\": \"## Service Configuration\\n\\n### Quick Setup\\n1. Select **Main Model Path** (turbo recommended)\\n2. Select **5Hz LM Model Path** (auto-filtered by GPU)\\n3. Choose **Backend**: `vllm` (fast, NVIDIA ≥8GB) or `pt` (universal)\\n4. Check **Initialize 5Hz LM** for Thinking mode\\n5. Click **Initialize Service**\\n\\n### Performance Tips\\n- **Flash Attention**: Faster inference (needs flash_attn)\\n- **CPU Offload**: Auto-enabled on GPUs <20GB\\n- **INT8 Quantization**: Reduces VRAM, auto-enabled <20GB\\n- **Compile**: Required for quantization, enabled by default\\n\\n### LoRA\\n- Set LoRA path → Load → Enable \\\"Use LoRA\\\"\\n- ⚠️ Cannot use LoRA with INT8 quantization\",\n    \"generation_simple\": \"## Simple Mode Tutorial\\n\\n**Best for:** Quick music creation with minimal effort.\\n\\n### Steps\\n1. Select **Simple** in Generation Mode\\n2. Type a description, e.g. *\\\"upbeat pop song with catchy guitar riff\\\"*\\n3. (Optional) Check **Instrumental** for no vocals\\n4. (Optional) Select **Vocal Language**\\n5. Click **Create Sample** — AI generates caption, lyrics, metadata\\n6. Review and edit the generated content if needed\\n7. Click **Generate Music**\\n\\n### Tips\\n- Click 🎲 for random inspiration\\n- The more specific your description, the better the result\\n- Leave BPM/Key empty to let AI decide\",\n    \"generation_custom\": \"## Custom Mode Tutorial\\n\\n**Best for:** Full creative control over every parameter.\\n\\n### Steps\\n1. Select **Custom** in Generation Mode\\n2. Write a detailed **Caption** describing style, genre, instruments, mood\\n3. Write **Lyrics** with structure tags: `[Verse]`, `[Chorus]`, `[Bridge]`\\n4. (Optional) Upload **Reference Audio** for style guidance\\n5. Set **BPM**, **Key**, **Duration** or leave empty for auto\\n6. Click **Format** to enhance with LM (optional)\\n7. Click **Generate Music**\\n\\n### Caption Tips\\n- Be specific: *\\\"dreamy shoegaze with reverb-heavy guitars and whispered vocals\\\"*\\n- Include: genre, instruments, mood, tempo feel, vocal style\",\n    \"generation_remix\": \"## Remix Mode Tutorial\\n\\n**Best for:** Creating cover versions or style transfers.\\n\\n### Steps\\n1. Select **Remix** in Generation Mode\\n2. Upload **Source Audio** (the song to remix)\\n3. Write a **Caption** describing the target style\\n4. (Optional) Modify **Lyrics**\\n5. Adjust **Remix Strength** (0.0–1.0):\\n   - Higher = closer to original structure\\n   - Lower = more creative freedom\\n6. Click **Generate Music**\\n\\n### Tips\\n- Start with strength 0.5 and adjust\\n- Use SFT model with Cover Strength 0.1–0.25 for melody retention\",\n    \"generation_repaint\": \"## Repaint Mode Tutorial\\n\\n**Best for:** Fixing or regenerating specific sections of generated music while keeping the rest intact.\\n\\n### Steps\\n1. Select **Repaint** in Generation Mode\\n2. Upload **Source Audio**\\n3. Set **Repainting Start** (seconds) and **End** (-1 for end of file)\\n4. Write a **Caption** for the repainted section\\n5. Choose a **Repaint Mode** and adjust **Repaint Strength** if needed\\n6. Click **Generate Music**\\n\\n### Repaint Mode\\nControls how the model treats non-repainted regions:\\n\\n- **Conservative** (Strength = 0): Maximum source preservation. Source latents are injected at every diffusion step with long boundary crossfades. Best for seamless blending.\\n- **Balanced** (default): Source latents are injected for a fraction of steps controlled by the Repaint Strength slider. Good starting point.\\n- **Aggressive** (Strength = 1): No source injection at all — pure diffusion. Maximum creative freedom but less boundary consistency.\\n\\n### Repaint Strength\\nOnly active in **Balanced** mode. Drag to control the preserve-vs-regenerate tradeoff:\\n- **0** = Conservative behavior (auto-switches mode)\\n- **0.5** = Default — inject source during first 50% of steps\\n- **1** = Aggressive behavior (auto-switches mode)\\n\\n### Tips\\n- Use \\\"Send To Repaint\\\" from Results to quickly load audio\\n- Start with Balanced (0.5) and adjust based on results\\n- Lower strength for better boundary consistency, higher for more creative output\",\n    \"generation_extract\": \"## Extract Mode (Base Model Only)\\n\\n**Best for:** Stem separation — isolating instruments from a mix.\\n\\n### Steps\\n1. Select **Extract** in Generation Mode\\n2. Upload **Source Audio**\\n3. Select **Track Name** to extract (e.g. vocals, drums, bass)\\n4. Click **Extract Stem**\\n\\n### Available Tracks\\nvocals, backing_vocals, drums, bass, guitar, keyboard, percussion, strings, synth, fx, brass, woodwinds\",\n    \"generation_lego\": \"## Lego Mode (Base Model Only)\\n\\n**Best for:** Adding new instrument tracks to existing audio.\\n\\n### Steps\\n1. Select **Lego** in Generation Mode\\n2. Upload **Source Audio**\\n3. Select **Track Name** to add\\n4. Write a **Caption** describing the track\\n5. Click **Add Stem**\\n\\n### Tips\\n- Great for layering: add drums to a guitar track, add bass to vocals\\n- The caption should describe only the new track's characteristics\",\n    \"generation_complete\": \"## Complete Mode (Base Model Only)\\n\\n**Best for:** Auto-arranging — filling in missing instruments.\\n\\n### Steps\\n1. Select **Complete** in Generation Mode\\n2. Upload **Source Audio** (partial arrangement)\\n3. Select multiple **Track Names** to add\\n4. Write a **Caption** describing the desired style\\n5. Click **Generate Music**\",\n    \"generation_caption\": \"## Writing Good Captions\\n\\n### Structure\\nA good caption includes:\\n- **Genre/Style**: pop, rock, jazz, electronic, classical…\\n- **Instruments**: guitar, piano, synth, drums, strings…\\n- **Mood**: upbeat, melancholic, energetic, dreamy…\\n- **Vocal style**: whispered, powerful, falsetto, rap…\\n- **Tempo feel**: fast, slow, moderate, driving…\\n\\n### Examples\\n- *\\\"Energetic pop-punk with distorted guitars, fast drums, and shouted vocals\\\"*\\n- *\\\"Smooth jazz trio with walking bass, brushed drums, and mellow piano\\\"*\\n- *\\\"Ambient electronic with layered synth pads and no vocals\\\"*\\n\\n### Tips\\n- More detail = better results\\n- Use the **Format** button to let AI enhance your caption\\n- Check 🎲 for example captions\",\n    \"generation_lyrics\": \"## Writing Lyrics\\n\\n### Structure Tags\\nUse section tags to structure your song:\\n```\\n[Verse 1]\\nYour verse lyrics here\\n\\n[Chorus]\\nYour chorus lyrics here\\n\\n[Verse 2]\\nSecond verse here\\n\\n[Bridge]\\nBridge section\\n\\n[Outro]\\nEnding lyrics\\n```\\n\\n### Tips\\n- Keep verses 4–8 lines\\n- Choruses should be memorable and repetitive\\n- Use `[Instrumental]` or `[Interlude]` for non-vocal sections\\n- Check **Instrumental** checkbox for pure instrumental music\\n- Select **Vocal Language** to match your lyrics language\",\n    \"generation_advanced\": \"## Advanced Settings\\n\\n### Key Parameters\\n- **Inference Steps**: Turbo=8 (default), Base=up to 200. More steps ≠ always better for turbo\\n- **Guidance Scale**: Base model only. Higher = follows prompt more strictly\\n- **Shift**: Timestep shift (1.0–5.0). 3.0 recommended for turbo\\n- **Seed**: Set a specific seed for reproducible results\\n\\n### LM Parameters\\n- **Temperature** (0.0–2.0): Higher = more creative/random\\n- **CFG Scale** (1.0–3.0): Higher = follows prompt more\\n- **Top-K / Top-P**: Sampling strategies for diversity\\n\\n### Think Mode\\nEnable **Think** to use 5Hz LM for smarter generation:\\n- Generates semantic codes and metadata\\n- Requires LM to be initialized\\n- **ParallelThinking**: Process batches in parallel (faster)\",\n    \"results\": \"## Results Section\\n\\n### Per-Sample Controls\\n- **Audio Player**: Play, pause, download\\n- **Send To Remix/Repaint**: Use this result as source for further editing\\n- **Save**: Export audio + metadata as JSON\\n- **Score**: Calculate quality score (perplexity-based)\\n- **LRC**: Generate lyrics timestamps\\n\\n### Batch Navigation\\n- Use **◀ Previous** / **Next ▶** to browse batches\\n- Enable **AutoGen** to auto-generate next batch\\n- Click **Apply These Settings to UI** to reuse parameters from a good result\\n\\n### Tips\\n- Generate 2–4 variations (batch size) and pick the best\\n- Use Score to objectively compare results\\n- Save good results for reference\",\n    \"training_dataset\": \"## Dataset Builder Tutorial\\n\\n### Step 1: Load or Scan\\n- **Load**: Enter path to existing dataset JSON → Click Load\\n- **Scan**: Enter audio folder path → Click Scan\\n  - Supported: wav, mp3, flac, ogg, opus\\n\\n### Step 2: Configure\\n- Set **Dataset Name**\\n- Check **All Instrumental** if no vocals\\n- Set **Custom Activation Tag** (unique trigger word for your LoRA)\\n- Choose **Tag Position**: Prepend, Append, or Replace\\n\\n### Step 3: Auto-Label\\n- Click **Auto-Label All** to generate captions, BPM, key, time sig\\n- Use **Skip Metas** to skip BPM/Key/TimeSig (faster)\\n\\n### Step 4: Preview & Edit\\n- Use slider to browse samples\\n- Edit caption, lyrics, BPM, key manually\\n- Click **Save Changes** per sample\\n\\n### Step 5: Save\\n- Enter save path → Click **Save Dataset**\\n\\n### Step 6: Preprocess\\n- Set tensor output directory → Click **Preprocess**\\n- This encodes audio/text to tensors for training\\n\\n### 📖 Documentation\\n- [LoRA Training Tutorial](https://github.com/ACE-Step/ACE-Step-1.5/blob/main/docs/en/LoRA_Training_Tutorial.md) — Full step-by-step guide\\n- [Side-Step Advanced Training](https://github.com/ACE-Step/ACE-Step-1.5/blob/main/docs/sidestep/Getting%20Started.md) — CLI-based training with advanced features\",\n    \"training_train\": \"## LoRA Training Tutorial\\n\\n### Setup\\n1. Enter **Preprocessed Tensors Directory** → Click **Load Dataset**\\n2. Configure LoRA:\\n   - **Rank** (r): 64 default. Higher = more capacity\\n   - **Alpha**: Usually 2× rank (128)\\n   - **Dropout**: 0.1 for regularization\\n\\n### Training\\n3. Set **Learning Rate** (start with 1e-4)\\n4. Set **Max Epochs** (500 default)\\n5. Click **Start Training**\\n6. Monitor loss curve — it should decrease over time\\n7. Click **Stop Training** when satisfied\\n\\n### Export\\n8. Enter export path → Click **Export LoRA**\\n9. Load in Settings: set LoRA Path → Load LoRA → Enable Use LoRA\\n\\n### 🚀 Try LoKr for Faster Training\\nLoKr has greatly improved training efficiency. What used to take an hour now only takes 5 minutes — **over 10× faster**. This is crucial for training on consumer-grade GPUs. Switch to the **Train LoKr** tab to get started.\\n\\n### Tips\\n- Use small batch size (1) if VRAM is limited\\n- Gradient accumulation increases effective batch size\\n- Save checkpoints frequently (every 200 epochs)\\n\\n### 📖 Documentation\\n- [LoRA Training Tutorial](https://github.com/ACE-Step/ACE-Step-1.5/blob/main/docs/en/LoRA_Training_Tutorial.md) — Full step-by-step guide\\n- [Side-Step Advanced Training](https://github.com/ACE-Step/ACE-Step-1.5/blob/main/docs/sidestep/Getting%20Started.md) — CLI training with corrected timesteps, LoKR, VRAM optimization\",\n    \"training_lokr\": \"## 🚀 LoKr Training Tutorial\\n\\nLoKr (Low-rank Kronecker product) has greatly improved training efficiency. What used to take an hour with LoRA now only takes 5 minutes — **over 10× faster**. This is crucial for training on consumer-grade GPUs.\\n\\n### Setup\\n1. Enter **Preprocessed Tensors Directory** → Click **Load Dataset**\\n2. Configure LoKr:\\n   - **Linear Dim**: 64 default (similar to LoRA rank)\\n   - **Linear Alpha**: 128 default (scaling factor)\\n   - **Weight Decompose (DoRA)**: Enabled by default for better quality\\n\\n### Training\\n3. Set **Learning Rate** (LoKr commonly uses higher LR, start with 1e-3)\\n4. Set **Max Epochs** (500 default)\\n5. Click **Start LoKr Training**\\n6. Monitor loss curve — it should decrease over time\\n7. Click **Stop Training** when satisfied\\n\\n### Export\\n8. Enter export path → Click **Export LoKr**\\n9. Load in Settings: set LoRA Path → Load LoRA → Enable Use LoRA\\n\\n### LoKr vs LoRA\\n| | LoKr | LoRA |\\n|---|---|---|\\n| Speed | ⚡ ~10× faster | Slower |\\n| VRAM | Lower | Higher |\\n| Quality | Comparable | Baseline |\\n| Best for | Consumer GPUs, rapid iteration | Maximum fidelity |\\n\\n### Tips\\n- LoKr uses Kronecker decomposition for extreme efficiency\\n- Enable **DoRA** (Weight Decompose) for improved quality\\n- Use **Tucker decomposition** for additional compression\\n- Higher learning rate (1e-3) often works better than LoRA's typical 1e-4\",\n    \"training_export\": \"## Using Your Trained LoRA\\n\\n### Export\\n1. After training, enter export path\\n2. Click **Export LoRA**\\n\\n### Load & Use\\n1. In Settings, set **LoRA Path** to your exported directory\\n2. Click **Load LoRA**\\n3. Enable **Use LoRA** checkbox\\n4. Generate music — your LoRA style will be applied\\n\\n### Tips\\n- Use your **Custom Activation Tag** in captions to trigger the style\\n- ⚠️ LoRA is incompatible with INT8 quantization\\n- You can unload and switch between different LoRAs\"\n  },\n  \"gen\": {\n    \"enable_normalization\": \"Enable Normalization\",\n    \"enable_normalization_info\": \"Adjusts the final audio volume to a consistent peak level. Prevents clipping (distortion from too-loud audio) and ensures all outputs are at similar loudness. Recommended to keep enabled for consistent results.\",\n    \"normalization_db\": \"Target Peak (dB)\",\n    \"normalization_db_info\": \"How loud the normalized audio should be. -1.0 dB = industry standard safe peak (recommended, leaves headroom). -0.1 dB = maximum loudness before clipping. Lower values (e.g. -3.0) = quieter, more headroom for further mixing/mastering.\",\n    \"fade_in_duration\": \"Fade In (seconds)\",\n    \"fade_in_duration_info\": \"Gradually increases volume from silence at the start of the audio. 0 = no fade (starts at full volume). 1–3s = subtle intro. 5–10s = dramatic slow build. Useful for avoiding abrupt starts.\",\n    \"fade_out_duration\": \"Fade Out (seconds)\",\n    \"fade_out_duration_info\": \"Gradually decreases volume to silence at the end of the audio. 0 = no fade (may end abruptly). 2–5s = smooth ending. Useful for avoiding harsh cutoffs at the end of generated audio.\",\n    \"latent_shift\": \"Latent Shift\",\n    \"latent_shift_info\": \"Advanced: Shifts the internal audio representation before decoding. Try small negative values (e.g. -0.04) if your outputs have clipping/distortion. 0 = no shift (default). Only adjust if you're hearing audio artifacts.\",\n    \"latent_rescale\": \"Latent Rescale\",\n    \"latent_rescale_info\": \"Advanced: Scales the internal audio representation before decoding. Values below 1.0 (e.g. 0.91) can reduce clipping/distortion. 1.0 = no rescale (default). Only adjust if you're hearing audio artifacts despite normalization.\"\n  }\n}\n"
  },
  {
    "path": "acestep/ui/gradio/i18n/he.json",
    "content": "{\n  \"app\": {\n    \"title\": \"🎛️ ACE-Step V1.5 Playground💡\",\n    \"subtitle\": \"פורצים את גבולות יצירת המוזיקה בקוד פתוח\"\n  },\n  \"common\": {\n    \"language_metadata\": {\n      \"name\": \"Hebrew\",\n      \"native_name\": \"עברית\"\n    }\n  },\n  \"dataset\": {\n    \"title\": \"📊 סייר מערכי נתונים (Dataset)\",\n    \"dataset_label\": \"מערך נתונים\",\n    \"dataset_info\": \"בחר מערך נתונים לחקירה.\",\n    \"import_btn\": \"📥 ייבוא מערך נתונים\",\n    \"search_type_label\": \"סוג חיפוש\",\n    \"search_type_info\": \"כיצד למצוא פריטים.\",\n    \"search_value_label\": \"ערך חיפוש\",\n    \"search_value_placeholder\": \"הזן מפתחות או אינדקס (השאר ריק לבחירה אקראית)\",\n    \"search_value_info\": \"מפתחות: התאמה מדויקת, אינדקס: מ-0 עד גודל המערך פחות 1.\",\n    \"instruction_label\": \"📝 הנחיה (Instruction)\",\n    \"instruction_placeholder\": \"אין הנחיה זמינה\",\n    \"metadata_title\": \"📋 מטא-דאטה של הפריט (JSON)\",\n    \"metadata_label\": \"מידע מלא על הפריט\",\n    \"source_audio\": \"אודיו מקור\",\n    \"target_audio\": \"אודיו יעד\",\n    \"reference_audio\": \"אודיו ייחוס\",\n    \"get_item_btn\": \"🔍 קבל פריט\",\n    \"use_src_checkbox\": \"השתמש באודיו מקור ממערך הנתונים\",\n    \"use_src_info\": \"סמן כדי להשתמש באודיו המקור מתוך מערך הנתונים.\",\n    \"data_status_label\": \"📊 סטטוס נתונים\",\n    \"data_status_default\": \"❌ לא יובא מערך נתונים\",\n    \"autofill_btn\": \"📋 מילוי אוטומטי של טופס היצירה\"\n  },\n  \"service\": {\n    \"title\": \"🔧 תצורת שירות\",\n    \"checkpoint_label\": \"קובץ Checkpoint\",\n    \"checkpoint_info\": \"בחר קובץ מודל מאומן (נתיב מלא או שם קובץ).\",\n    \"refresh_btn\": \"🔄 רענון\",\n    \"model_path_label\": \"נתיב מודל ראשי\",\n    \"model_path_info\": \"בחר את ספריית הגדרות המודל (נסרק אוטומטית מה-checkpoints).\",\n    \"device_label\": \"מכשיר (Device)\",\n    \"device_info\": \"מכשיר עיבוד (מומלץ זיהוי אוטומטי).\",\n    \"lm_model_path_label\": \"נתיב מודל 5Hz LM\",\n    \"lm_model_path_info\": \"בחר את קובץ המודל 5Hz LM (נסרק אוטומטית).\",\n    \"backend_label\": \"Backend של 5Hz LM\",\n    \"backend_info\": \"בחר Backend עבור 5Hz LM: vllm (מהיר יותר) או pt (PyTorch, תואם יותר).\",\n    \"init_llm_label\": \"אתחול 5Hz LM\",\n    \"init_llm_info\": \"סמן כדי לאתחל את 5Hz LM במהלך אתחול השירות.\",\n    \"lm_unavailable_vram\": \"⚠️ LM אינו זמין עבור דרגת GPU זו (VRAM נמוך מדי)\",\n    \"flash_attention_label\": \"שימוש ב-Flash Attention\",\n    \"flash_attention_info_enabled\": \"אפשר Flash Attention להסקה מהירה יותר (דורש חבילת flash_attn).\",\n    \"flash_attention_info_disabled\": \"Flash Attention אינו זמין (חבילת flash_attn לא מותקנת).\",\n    \"offload_cpu_label\": \"העברה ל-CPU (Offload)\",\n    \"offload_cpu_info\": \"העבר מודלים ל-CPU כשאינם בשימוש כדי לחסוך בזיכרון GPU.\",\n    \"offload_dit_cpu_label\": \"העברת DiT ל-CPU\",\n    \"offload_dit_cpu_info\": \"העבר את מודל ה-DiT ל-CPU (דורש 'העברה ל-CPU').\",\n    \"compile_model_label\": \"קימפול מודל (Compile)\",\n    \"compile_model_info\": \"השתמש ב-torch.compile לאופטימיזציה (נדרש עבור קוונטיזציה).\",\n    \"quantization_label\": \"קוונטיזציה INT8\",\n    \"quantization_info\": \"אפשר קוונטיזציית משקלים INT8 לצמצום שימוש ב-VRAM (דורש קימפול מודל).\",\n    \"mlx_dit_label\": \"MLX DiT (Apple Silicon)\",\n    \"mlx_dit_info_enabled\": \"השתמש ב-MLX מקורי עבור דיפוזיית DiT במעבדי Apple (מהיר יותר מ-MPS).\",\n    \"mlx_dit_info_disabled\": \"MLX אינו זמין (דורש macOS + Apple Silicon + חבילת mlx).\",\n    \"init_btn\": \"אתחול שירות\",\n    \"status_label\": \"סטטוס\",\n    \"language_label\": \"שפת ממשק\",\n    \"language_info\": \"בחר את שפת הממשק.\",\n    \"gpu_auto_tier\": \"דרגה שזוהתה אוטומטית\",\n    \"tier_label\": \"עקיפת דרגת GPU\",\n    \"tier_info\": \"בחר ידנית דרגת GPU כדי להתאים את ברירת המחדל של האופטימיזציות.\"\n  },\n  \"generation\": {\n    \"tab_title\": \"🎵 יצירה\",\n    \"required_inputs\": \"📝 קלטים נדרשים\",\n    \"task_type_label\": \"סוג משימה *\",\n    \"task_type_info\": \"בחר את סוג המשימה ליצירה.\",\n    \"instruction_label\": \"הנחיה\",\n    \"instruction_info\": \"ההנחיה נוצרת אוטומטית בהתבסס על סוג המשימה.\",\n    \"load_btn\": \"📂 טעינה\",\n    \"track_name_label\": \"שם ערוץ\",\n    \"track_name_info\": \"בחר שם ערוץ למשימות lego/extract.\",\n    \"track_classes_label\": \"שמות ערוצים\",\n    \"track_classes_info\": \"בחר מספר סוגי ערוצים למשימה מלאה.\",\n    \"audio_uploads\": \"🎵 העלאות אודיו\",\n    \"reference_audio\": \"אודיו ייחוס\",\n    \"source_audio\": \"אודיו מקור\",\n    \"convert_codes_btn\": \"המר לקודים\",\n    \"analyze_btn\": \"🔍 ניתוח\",\n    \"sample_btn\": \"🎲 לחץ עליי\",\n    \"lm_codes_hints\": \"🎼 רמזי קודי LM\",\n    \"lm_codes_label\": \"רמזי קודי LM\",\n    \"lm_codes_placeholder\": \"<|audio_code_10695|><|audio_code_54246|>.\",\n    \"lm_codes_info\": \"הדבק רמזי קודי LM עבור יצירת text2music.\",\n    \"lm_codes_sample\": \"רמזי קודי LM (דגימה {n})\",\n    \"lm_codes_sample_info\": \"קודים עבור דגימה {n}.\",\n    \"transcribe_btn\": \"תמלול\",\n    \"repainting_controls\": \"🎨 בקרת צביעה מחדש (שניות)\",\n    \"repainting_start\": \"תחילת צביעה\",\n    \"repainting_end\": \"סיום צביעה\",\n    \"mode_label\": \"מצב יצירה *\",\n    \"mode_info\": \"בחר מצב יצירה כדי להתחיל.\",\n    \"mode_info_simple\": \"תאר את המוזיקה שלך בשפה חופשית. הבינה המלאכותית תייצר עבורך תיאור, מילים ומטא-דאטה.\",\n    \"mode_info_custom\": \"שליטה מלאה על התיאור, המילים וכל הפרמטרים.\",\n    \"mode_info_remix\": \"העלה אודיו מקור ליצירת גרסת רמיקס עם התיאור והמילים שלך.\",\n    \"mode_info_repaint\": \"העלה אודיו מקור וצבע מחדש טווח זמן ספציפי.\",\n    \"mode_info_extract\": \"חלץ ערוץ ספציפי (שירה, תופים וכו') מאודיו מקור.\",\n    \"mode_info_lego\": \"הרכב ערוצים מחדש: החלף ערוץ ספציפי באודיו המקור.\",\n    \"mode_info_complete\": \"השלם ערוצים חסרים באודיו המקור.\",\n    \"mode_simple\": \"פשוט\",\n    \"mode_custom\": \"מותאם אישית\",\n    \"simple_query_label\": \"תיאור השיר *\",\n    \"simple_query_placeholder\": \"תאר את המוזיקה שברצונך ליצור, למשל 'שיר אהבה אקוסטי שקט'. השאר ריק לדגימה אקראית.\",\n    \"simple_query_info\": \"הזן תיאור בשפה חופשית של המוזיקה שברצונך ליצור.\",\n    \"simple_vocal_language_label\": \"שפת שירה\",\n    \"simple_vocal_language_info\": \"בחר שפה מועדפת למילים. השתמש ב-'unknown' לכל שפה.\",\n    \"create_sample_btn\": \"צור דגימה\",\n    \"caption_title\": \"📝 תיאור מוזיקלי (Caption)\",\n    \"caption_label\": \"תיאור המוזיקה\",\n    \"caption_placeholder\": \"מנגינת גיטרה אקוסטית שלווה עם שירה רכה.\",\n    \"caption_info\": \"תאר את הסגנון, הז'אנר, הכלים והאווירה.\",\n    \"lyrics_title\": \"📝 מילים\",\n    \"lyrics_label\": \"מילים\",\n    \"lyrics_placeholder\": \"[Verse 1]\\nמתחת לשמיים זרועי כוכבים\\nאני מרגיש כל כך חי.\",\n    \"lyrics_info\": \"מילות השיר עם מבנה.\",\n    \"instrumental_label\": \"אינסטרומנטלי (ללא שירה)\",\n    \"format_btn\": \"עיצוב\",\n    \"format_caption_btn\": \"שיפור תיאור\",\n    \"format_lyrics_btn\": \"שיפור מילים\",\n    \"optional_params\": \"⚙️ פרמטרים אופציונליים\",\n    \"optional_music_props\": \"🎵 תכונות מוזיקה\",\n    \"optional_gen_settings\": \"📐 הגדרות יצירה\",\n    \"advanced_dit_section\": \"🎛️ דיפוזיית DiT\",\n    \"advanced_lm_section\": \"🤖 יצירת LM\",\n    \"advanced_output_section\": \"🔊 פלט אודיו ועיבוד פוסט\",\n    \"advanced_automation_section\": \"⚡ אוטומציה ואצווה (Batch)\",\n    \"vocal_language_label\": \"שפת שירה\",\n    \"vocal_language_info\": \"'unknown' = אינסטרומנטלי / אוטומטי.\",\n    \"bpm_label\": \"BPM (קצב)\",\n    \"bpm_info\": \"השאר ריק אם לא רלוונטי.\",\n    \"keyscale_label\": \"סולם\",\n    \"keyscale_placeholder\": \"השאר ריק אם לא רלוונטי\",\n    \"keyscale_info\": \"A-G, #/♭, מז'ור/מינור.\",\n    \"timesig_label\": \"משקל (Time Signature)\",\n    \"timesig_info\": \"2/4, 3/4, 4/4.\",\n    \"duration_label\": \"משך אודיו (שניות)\",\n    \"duration_info\": \"השתמש ב-1- לבחירה אקראית.\",\n    \"batch_size_label\": \"גודל אצווה\",\n    \"batch_size_info\": \"מספר קבצי אודיו ליצירה (מקסימום 8).\",\n    \"advanced_settings\": \"⚙️ הגדרות\",\n    \"inference_steps_label\": \"צעדי הסקה של DiT\",\n    \"inference_steps_info\": \"Turbo: מקסימום 8, Base: מקסימום 200.\",\n    \"guidance_scale_label\": \"קנה מידה להנחיה (רק למודל Base)\",\n    \"guidance_scale_info\": \"ערכים גבוהים יותר נצמדים יותר לטקסט.\",\n    \"seed_label\": \"Seed (גרעין)\",\n    \"seed_info\": \"השתמש בערכים מופרדים בפסיקים עבור אצוות.\",\n    \"random_seed_label\": \"Seed אקראי\",\n    \"random_seed_info\": \"אפשר ליצירה אוטומטית של גרעינים.\",\n    \"audio_format_label\": \"פורמט אודיו\",\n    \"audio_format_info\": \"פורמט האודיו לשמירה.\",\n    \"use_adg_label\": \"שימוש ב-ADG\",\n    \"use_adg_info\": \"אפשר Angle Domain Guidance.\",\n    \"shift_label\": \"Shift (הסטה)\",\n    \"shift_info\": \"גורם הסטת צעדי זמן למודלי Base (טווח 1.0~5.0, ברירת מחדל 3.0). לא משפיע על מודלי Turbo.\",\n    \"infer_method_label\": \"שיטת הסקה\",\n    \"infer_method_info\": \"שיטת הסקת דיפוזיה. ODE (Euler) מהיר יותר, SDE (stochastic) עשוי להניב תוצאות שונות.\",\n    \"custom_timesteps_label\": \"צעדי זמן מותאמים\",\n    \"custom_timesteps_info\": \"ערכים מופרדים בפסיקים מ-1.0 ל-0.0. עוקף את צעדי ההסקה וההסטה.\",\n    \"cfg_interval_start\": \"תחילת אינטרוול CFG\",\n    \"cfg_interval_end\": \"סיום אינטרוול CFG\",\n    \"lm_params_title\": \"🤖 פרמטרי יצירת LM\",\n    \"lm_temperature_label\": \"טמפרטורת LM\",\n    \"lm_temperature_info\": \"טמפרטורת 5Hz LM (גבוה יותר = אקראי יותר).\",\n    \"lm_cfg_scale_label\": \"קנה מידה CFG של LM\",\n    \"lm_cfg_scale_info\": \"CFG של 5Hz LM (1.0 = ללא CFG).\",\n    \"lm_top_k_label\": \"LM Top-K\",\n    \"lm_top_k_info\": \"Top-K (0 = מנוטרל).\",\n    \"lm_top_p_label\": \"LM Top-P\",\n    \"lm_top_p_info\": \"Top-P (1.0 = מנוטרל).\",\n    \"lm_negative_prompt_label\": \"הנחיה שלילית ל-LM\",\n    \"lm_negative_prompt_placeholder\": \"הזן הנחיה שלילית עבור CFG\",\n    \"lm_negative_prompt_info\": \"הנחיה שלילית (לשימוש כאשר LM CFG Scale > 1.0).\",\n    \"advanced_dit_params\": \"פרמטרי DiT מתקדמים\",\n    \"cot_metas_label\": \"מטא-דאטה CoT\",\n    \"cot_metas_info\": \"השתמש ב-LM כדי ליצור מטא-דאטה של 'שרשרת מחשבה' (בטל לדילוג על שלב זה).\",\n    \"cot_language_label\": \"שפת CoT\",\n    \"cot_language_info\": \"ייצור שפה בתוך שרשרת המחשבה (CoT).\",\n    \"constrained_debug_label\": \"ניקוי באגים של פענוח מוגבל\",\n    \"constrained_debug_info\": \"אפשר רישום לוגים לניקוי באגים של פענוח מוגבל.\",\n    \"auto_score_label\": \"ציון אוטומטי\",\n    \"auto_score_info\": \"חשב אוטומטית ציוני איכות לכל האודיו שנוצר.\",\n    \"auto_lrc_label\": \"LRC אוטומטי\",\n    \"auto_lrc_info\": \"ייצר אוטומטית חותמות זמן למילים (LRC) לכל האודיו שנוצר.\",\n    \"lm_batch_chunk_label\": \"גודל מקטע אצווה של LM\",\n    \"lm_batch_chunk_info\": \"מספר פריטים מקסימלי למקטע אצווה של LM (תלוי בזיכרון GPU).\",\n    \"codes_strength_label\": \"חוזק קודי LM\",\n    \"codes_strength_info\": \"קבע כמה צעדי ניקוי רעשים ישתמשו בקודי ה-LM שנוצרו.\",\n    \"cover_strength_label\": \"חוזק כיסוי אודיו\",\n    \"cover_strength_info\": \"קבע כמה צעדי ניקוי רעשים ישתמשו במצב כיסוי (cover).\",\n    \"remix_strength_label\": \"חוזק רמיקס\",\n    \"remix_strength_info\": \"קבע עד כמה הרמיקס יעקוב מקרוב אחרי אודיו המקור (גבוה יותר = קרוב יותר למקור).\",\n    \"cover_noise_strength_label\": \"חוזק כיסוי\",\n    \"cover_noise_strength_info\": \"שולט על שימור המלודיה במצב רמיקס. מומלץ: 0.1–0.25 עם מודל SFT.\",\n    \"enable_normalization\": \"אפשר נורמליזציה\",\n    \"enable_normalization_info\": \"נרמל את עוצמת האודיו לרמת שיא מוגדרת כדי למנוע קטיעה (clipping).\",\n    \"normalization_db\": \"שיא יעד (dB)\",\n    \"normalization_db_info\": \"רמת שיא היעד בדציבלים. -1.0 dB הוא תקן בטוח.\",\n    \"latent_shift\": \"הסטת לטנטים (Latent Shift)\",\n    \"latent_shift_info\": \"הסטה המוחלת על ה-DiT latents לפני פענוח VAE. יכול להפחית קטיעה.\",\n    \"latent_rescale\": \"שינוי קנה מידה לטנטי\",\n    \"latent_rescale_info\": \"גורם שינוי קנה מידה לפני פענוח VAE. ערכים < 1.0 יכולים להפחית קטיעה.\",\n    \"score_sensitivity_label\": \"רגישות ציון איכות\",\n    \"score_sensitivity_info\": \"נמוך יותר = רגיש יותר (ברירת מחדל: 1.0).\",\n    \"lora_accordion_title\": \"🔧 מתאם LoRA\",\n    \"lora_path_label\": \"נתיב LoRA\",\n    \"lora_path_placeholder\": \"./lora_output/final/adapter\",\n    \"lora_path_info\": \"נתיב לספריית מתאם LoRA מאומן\",\n    \"load_lora_btn\": \"📥 טען LoRA\",\n    \"unload_lora_btn\": \"🗑️ פריקה\",\n    \"use_lora_label\": \"השתמש ב-LoRA\",\n    \"use_lora_info\": \"אפשר מתאם LoRA להסקה\",\n    \"lora_scale_label\": \"קנה מידה LoRA\",\n    \"lora_scale_info\": \"חוזק ההשפעה של LoRA (0=מנוטרל, 1=מלא)\",\n    \"lora_status_label\": \"סטטוס LoRA\",\n    \"lora_status_default\": \"לא נטען LoRA\",\n    \"think_label\": \"חשיבה (Think)\",\n    \"parallel_thinking_label\": \"חשיבה מקבילית\",\n    \"parallel_thinking_info\": \"עיבוד דגימות אצווה במקביל ליצירה מהירה יותר.\",\n    \"generate_btn\": \"🎵 צור מוזיקה\",\n    \"extract_stem_btn\": \"🎵 חלץ ערוץ (Stem)\",\n    \"add_stem_btn\": \"🎵 הוסף ערוץ\",\n    \"stem_area_controls\": \"🧩 אזור ערוץ חדש (שניות)\",\n    \"stem_start\": \"תחילת ערוץ\",\n    \"stem_end\": \"סיום ערוץ\",\n    \"autogen_label\": \"AutoGen\",\n    \"caption_rewrite_label\": \"שכתוב תיאור\",\n    \"caption_rewrite_info\": \"השתמש ב-LM לשכתוב התיאור לפני היצירה.\",\n    \"auto_label\": \"אוטומטי\",\n    \"bpm_auto_label\": \"BPM אוטומטי\",\n    \"key_auto_label\": \"סולם אוטומטי\",\n    \"timesig_auto_label\": \"משקל אוטומטי\",\n    \"vocal_lang_auto_label\": \"שפה אוטומטית\",\n    \"duration_auto_label\": \"משך אוטומטי\",\n    \"reset_all_auto\": \"🔄 אפס הכל לאוטומטי\"\n  },\n  \"results\": {\n    \"title\": \"🎵 תוצאות\",\n    \"generated_music\": \"🎵 מוזיקה שנוצרה (דגימה {n})\",\n    \"send_to_remix_btn\": \"🔗 שלח לרמיקס\",\n    \"send_to_repaint_btn\": \"🔗 שלח לצביעה מחדש\",\n    \"save_btn\": \"💾 שמירה\",\n    \"score_btn\": \"📊 קבל ציון\",\n    \"lrc_btn\": \"🎵 קבל LRC\",\n    \"save_lrc_btn\": \"💾 שמור LRC\",\n    \"convert_to_codes_btn\": \"🔄 המר לקודים\",\n    \"quality_score_label\": \"ציון איכות (דגימה {n})\",\n    \"quality_score_placeholder\": \"לחץ על 'קבל ציון' לחישוב איכות מבוסס perplexity\",\n    \"codes_label\": \"קודי LM (דגימה {n})\",\n    \"lrc_label\": \"חותמות זמן למילים (דגימה {n})\",\n    \"lrc_placeholder\": \"לחץ על 'קבל LRC' ליצירת חותמות זמן\",\n    \"details_accordion\": \"📊 ציון, LRC וקודי LM\",\n    \"generation_status\": \"סטטוס יצירה\",\n    \"current_batch\": \"אצווה נוכחית\",\n    \"batch_indicator\": \"אצווה {current} / {total}\",\n    \"next_batch_status\": \"סטטוס אצווה הבאה\",\n    \"prev_btn\": \"◀ הקודם\",\n    \"next_btn\": \"הבא ▶\",\n    \"restore_params_btn\": \"↙️ החל הגדרות אלו על הממשק\",\n    \"batch_results_title\": \"📁 תוצאות אצווה ופרטי יצירה\",\n    \"all_files_label\": \"📁 כל הקבצים שנוצרו (הורדה)\",\n    \"generation_details\": \"פרטי יצירה\"\n  },\n  \"messages\": {\n    \"no_audio_to_save\": \"❌ אין אודיו לשמירה\",\n    \"save_success\": \"✅ אודיו ומטא-דאטה נשמרו ב-{filename}\",\n    \"save_failed\": \"❌ שמירה נכשלה: {error}\",\n    \"no_file_selected\": \"⚠️ לא נבחר קובץ\",\n    \"params_loaded\": \"✅ פרמטרים נטענו מ-{filename}\",\n    \"invalid_json\": \"❌ קובץ JSON לא תקין: {error}\",\n    \"load_error\": \"❌ שגיאה בטעינת קובץ: {error}\",\n    \"example_loaded\": \"📁 נטענה דוגמה מ-{filename}\",\n    \"example_failed\": \"טעינת JSON נכשלה {filename}: {error}\",\n    \"example_error\": \"שגיאה בטעינת דוגמה: {error}\",\n    \"lm_generated\": \"🤖 נוצרה דוגמה באמצעות LM\",\n    \"lm_fallback\": \"יצירת דגימה ב-LM נכשלה, חוזר לדגימות מהספרייה\",\n    \"lm_not_initialized\": \"❌ 5Hz LM לא מאותחל. אנא אתחל אותו תחילה.\",\n    \"think_requires_lm\": \"⚠️ מצב 'חשיבה' דורש אתחול 5Hz LM. המצב הושבת - היצירה תימשך ללא חשיבת LM.\",\n    \"autogen_enabled\": \"🔄 AutoGen מופעל - האצווה הבאה תיווצר לאחר זו\",\n    \"batch_ready\": \"✅ אצווה {n} מוכנה! לחץ על 'הבא' לצפייה.\",\n    \"batch_generating\": \"🔄 מתחילה יצירת אצווה {n} ברקע.\",\n    \"batch_failed\": \"❌ יצירת אצווה ברקע נכשלה: {error}\",\n    \"viewing_batch\": \"✅ צפייה באצווה {n}\",\n    \"at_first_batch\": \"כבר באצווה הראשונה\",\n    \"at_last_batch\": \"אין אצווה נוספת זמינה\",\n    \"batch_not_found\": \"אצווה {n} לא נמצאה בתור\",\n    \"no_batch_data\": \"לא נמצאו נתוני אצווה לשחזור.\",\n    \"params_restored\": \"✅ פרמטרי ממשק שוחזרו מאצווה {n}\",\n    \"scoring_failed\": \"❌ שגיאה: נתוני אצווה לא נמצאו\",\n    \"no_codes\": \"❌ אין קודי אודיו זמינים. אנא צור מוזיקה תחילה.\",\n    \"score_failed\": \"❌ חישוב הציון נכשל: {error}\",\n    \"score_error\": \"❌ שגיאה בחישוב ציון: {error}\",\n    \"lrc_no_batch_data\": \"❌ לא נמצאו נתוני אצווה. אנא צור מוזיקה תחילה.\",\n    \"lrc_no_extra_outputs\": \"❌ לא נמצאו פלטים נוספים.\",\n    \"lrc_missing_tensors\": \"❌ חסרים טנזורים נדרשים ליצירת LRC.\",\n    \"lrc_sample_not_exist\": \"❌ הדגימה לא קיימת באצווה הנוכחית.\",\n    \"lrc_empty_result\": \"⚠️ יצירת LRC החזירה תוצאה ריקה.\",\n    \"empty_query\": \"⚠️ אנא הזן תיאור מוזיקלי.\",\n    \"sample_creation_failed\": \"❌ יצירת דגימה נכשלה. אנא נסה שנית.\",\n    \"sample_created\": \"✅ דגימה נוצרה! בדוק את התיאור והמילים, ואז לחץ על 'צור מוזיקה'.\",\n    \"simple_examples_not_found\": \"⚠️ ספריית דוגמאות למצב פשוט לא נמצאה.\",\n    \"simple_examples_empty\": \"⚠️ לא נמצאו קבצי דוגמה.\",\n    \"simple_example_loaded\": \"🎲 נטענה דוגמה אקראית מ-{filename}\",\n    \"format_success\": \"✅ התיאור והמילים עובדו בהצלחה\",\n    \"format_failed\": \"❌ העיבוד נכשל: {error}\",\n    \"skipping_metas_cot\": \"⚡ מדלג על שלב 1 (הדגימה כבר מעוצבת)\",\n    \"invalid_timesteps_format\": \"⚠️ פורמט צעדי זמן לא תקין. משתמש בלוח זמנים ברירת מחדל.\",\n    \"timesteps_out_of_range\": \"⚠️ צעדי זמן חייבים להיות בטווח [0, 1].\",\n    \"timesteps_count_mismatch\": \"⚠️ מספר צעדי הזמן ({actual}) שונה מהמוגדר ({expected}).\",\n    \"audio_format_invalid\": \"פורמט ה-{role} לא תקין או לא נתמך. אנא העלה קובץ אודיו תקין.\"\n  },\n  \"training\": {\n    \"tab_title\": \"🎓 אימון LoRA\",\n    \"tab_dataset_builder\": \"📁 בונה מערכי נתונים\",\n    \"tab_train_lora\": \"🚀 אימון LoRA\",\n    \"quick_start_title\": \"🚀 התחלה מהירה\",\n    \"load_dataset_label\": \"נתיב JSON של מערך הנתונים\",\n    \"load_dataset_info\": \"טען מערך נתונים שנשמר בעבר.\",\n    \"load_btn\": \"📂 טעינה\",\n    \"load_status\": \"סטטוס טעינה\",\n    \"scan_label\": \"נתיב ספריית אודיו\",\n    \"scan_info\": \"סרוק קבצי אודיו (wav, mp3, flac, ogg, opus).\",\n    \"scan_btn\": \"🔍 סריקה\",\n    \"scan_status\": \"סטטוס סריקה\",\n    \"found_audio_files\": \"נמצאו קבצי אודיו\",\n    \"dataset_name\": \"שם מערך הנתונים\",\n    \"dataset_name_placeholder\": \"הזן שם למערך הנתונים\",\n    \"dataset_settings_header\": \"הגדרות מערך נתונים\",\n    \"tag_prepend\": \"הוספה להתחלה (Tag, Caption)\",\n    \"tag_append\": \"הוספה לסוף (Caption, Tag)\",\n    \"tag_replace\": \"החלף תיאור\",\n    \"step2_title\": \"שלב 2: תיוג אוטומטי מבוסס AI\",\n    \"step2_instruction\": \"לחץ על הכפתור למטה כדי להשתמש ב-AI לייצור מטא-דאטה אוטומטי לכל הקבצים:\\n- **תיאור**: סגנון, ז'אנר, אווירה\\n- **BPM**: קצב\\n- **סולם**: סולם מוזיקלי\\n- **משקל**: 4/4, 3/4 וכו'.\",\n    \"step3_title\": \"שלב 3: תצוגה מקדימה ועריכה\",\n    \"step4_title\": \"שלב 4: שמירת מערך נתונים\",\n    \"step5_title\": \"שלב 5: עיבוד מוקדם לטנזורים (Tensors)\",\n    \"step5_intro\": \"**עיבוד מוקדם ממיר את מערך הנתונים לטנזורים מחושבים מראש לאימון מהיר.**\\n\\nניתן:\\n- להשתמש במערך מהשלבים הקודמים, **או**\\n- לטעון קובץ JSON קיים.\",\n    \"step5_details\": \"שלב זה יבצע:\\n- קידוד אודיו ל-VAE latents\\n- קידוד תיאורים ומילים לייצוגי טקסט\\n- הרצת מקודדי תנאים\\n- שמירת הכל לקבצי `.pt`\",\n    \"train_tensor_selection_desc\": \"בחר את הספרייה המכילה את קבצי הטנזורים המעובדים (`.pt`).\",\n    \"all_instrumental\": \"הכל אינסטרומנטלי\",\n    \"all_instrumental_info\": \"סמן אם כל הרצועות הן ללא שירה.\",\n    \"custom_tag\": \"תג הפעלה מותאם (Trigger Tag)\",\n    \"custom_tag_info\": \"תג ייחודי להפעלת סגנון ה-LoRA הזה.\",\n    \"tag_position\": \"מיקום התג\",\n    \"tag_position_info\": \"היכן למקם את התג המותאם בתוך התיאור.\",\n    \"genre_ratio\": \"יחס ז'אנר (%)\",\n    \"genre_ratio_info\": \"0%=הכל תיאור, 100%=הכל ז'אנר.\",\n    \"skip_metas\": \"דלג על BPM/סולם/משקל\",\n    \"skip_metas_info\": \"דלג על ייצור BPM/Key/TimeSig. תיאורים וז'אנרים עדיין ייווצרו.\",\n    \"only_unlabeled\": \"רק לא מתויגים\",\n    \"only_unlabeled_info\": \"תייג רק דגימות ללא תיאור.\",\n    \"auto_label_btn\": \"🏷️ תיוג אוטומטי להכל\",\n    \"label_progress\": \"התקדמות תיוג\",\n    \"select_sample\": \"בחר דגימה #\",\n    \"select_sample_info\": \"בחר דגימה לתצוגה מקדימה ועריכה.\",\n    \"audio_preview\": \"תצוגת אודיו\",\n    \"filename\": \"שם קובץ\",\n    \"caption\": \"תיאור\",\n    \"genre\": \"ז'אנר\",\n    \"prompt_override_label\": \"עקיפת הנחיה (לדגימה זו)\",\n    \"prompt_override_info\": \"עקיפת היחס הגלובלי עבור דגימה זו.\",\n    \"lyrics_editable_label\": \"מילים (ניתן לעריכה לאימון)\",\n    \"raw_lyrics_label\": \"מילים גולמיות (מקובץ .txt)\",\n    \"no_lyrics_placeholder\": \"(אין קובץ מילים)\",\n    \"bpm\": \"BPM\",\n    \"key_label\": \"סולם\",\n    \"key_placeholder\": \"C Major\",\n    \"time_sig\": \"משקל\",\n    \"duration_s\": \"משך (שניות)\",\n    \"language\": \"שפה\",\n    \"instrumental\": \"אינסטרומנטלי\",\n    \"save_changes_btn\": \"💾 שמור שינויים\",\n    \"edit_status\": \"סטטוס עריכה\",\n    \"save_path\": \"נתיב שמירה\",\n    \"save_path_info\": \"נתיב לשמירת JSON של מערך הנתונים.\",\n    \"save_dataset_btn\": \"💾 שמור מערך נתונים\",\n    \"save_status\": \"סטטוס שמירה\",\n    \"load_existing_label\": \"טען מערך נתונים קיים\",\n    \"load_existing_info\": \"נתיב לקובץ JSON שנשמר בעבר.\",\n    \"load_dataset_btn\": \"📂 טען מערך נתונים\",\n    \"tensor_output_dir\": \"ספריית פלט טנזורים\",\n    \"tensor_output_info\": \"ספרייה לשמירת קבצי הטנזורים המעובדים.\",\n    \"preprocess_btn\": \"⚡ עיבוד מוקדם (Preprocess)\",\n    \"preprocess_progress\": \"התקדמות עיבוד\",\n    \"preprocessed_tensors_dir\": \"ספריית טנזורים מעובדים\",\n    \"preprocessed_tensors_info\": \"ספרייה המכילה קבצי .pt מעובדים.\",\n    \"dataset_info\": \"מידע על מערך הנתונים.\",\n    \"lora_rank\": \"דרגת LoRA (r)\",\n    \"lora_rank_info\": \"קיבולת גבוהה יותר אך דורש יותר VRAM.\",\n    \"lora_alpha\": \"LoRA Alpha\",\n    \"lora_alpha_info\": \"גורם קנה מידה (בדרך כלל פי 2 מהדרגה).\",\n    \"lora_dropout\": \"LoRA Dropout\",\n    \"learning_rate\": \"קצב למידה\",\n    \"learning_rate_info\": \"התחל עם 3e-4, התאם לפי הצורך.\",\n    \"max_epochs\": \"מקסימום איטרציות (Epochs)\",\n    \"batch_size\": \"גודל אצווה\",\n    \"batch_size_info\": \"הגדל אם זיכרון ה-GPU מאפשר.\",\n    \"gradient_accumulation\": \"צבירת גרדיאנטים\",\n    \"gradient_accumulation_info\": \"גודל אצווה אפקטיבי = גודל אצווה * צעדי צבירה.\",\n    \"save_every_n_epochs\": \"שמור כל N איטרציות\",\n    \"shift\": \"Shift (הסטה)\",\n    \"shift_info\": \"הסטת צעדי זמן למודלי Turbo.\",\n    \"seed\": \"Seed\",\n    \"output_dir\": \"ספריית פלט\",\n    \"output_dir_info\": \"ספרייה לשמירת משקלי LoRA המאומנים.\",\n    \"start_training_btn\": \"🚀 התחל אימון\",\n    \"stop_training_btn\": \"⏹️ עצור אימון\",\n    \"training_progress\": \"התקדמות אימון\",\n    \"training_log\": \"יומן אימון\",\n    \"training_loss_title\": \"אובדן אימון (Loss)\",\n    \"step\": \"צעד\",\n    \"loss\": \"אובדן\",\n    \"export_header\": \"ייצוא LoRA\",\n    \"export_path\": \"נתיב ייצוא\",\n    \"export_lora_btn\": \"📦 ייצוא LoRA\",\n    \"export_status\": \"סטטוס ייצוא\",\n    \"stop_no_training\": \"ℹ️ אין אימון בתהליך\",\n    \"stop_stopping\": \"⏹️ עוצר אימון...\",\n    \"latest_auto\": \"האחרון (אוטומטי)\",\n    \"export_path_required\": \"❌ אנא הזן נתיב ייצוא\",\n    \"invalid_lora_output_dir\": \"❌ ספריית פלט LoRA לא תקינה\",\n    \"no_checkpoints_found\": \"❌ לא נמצאו נקודות ביקורת (Checkpoints)\",\n    \"no_trained_model_found\": \"❌ לא נמצא מודל מאומן בנתיב {path}\",\n    \"invalid_export_path\": \"❌ נתיב ייצוא לא תקין\",\n    \"lora_exported\": \"✅ LoRA יוצא ל-{path}\",\n    \"export_failed\": \"❌ הייצוא נכשל: {error}\",\n    \"lokr_output_dir_required\": \"⚠️ הזן תחילה ספריית פלט LoKr\",\n    \"lokr_no_checkpoints_use_latest\": \"ℹ️ לא נמצאו נקודות ביקורת; הייצוא ישתמש במשקלים האחרונים הזמינים\",\n    \"lokr_no_exportable_checkpoints\": \"ℹ️ לא נמצאו נקודות ביקורת הניתנות לייצוא\",\n    \"lokr_found_checkpoints\": \"✅ נמצאו {count} נקודות ביקורת LoKr\",\n    \"lokr_selected_epoch_not_found\": \"❌ האיטרציה שנבחרה לא נמצאה: {chosen}. זמין: {available}\",\n    \"lokr_no_weights_selected_epoch\": \"❌ לא נמצאו משקלי LoKr לאיטרציה שנבחרה: {epoch}\",\n    \"lokr_no_weights_latest_checkpoint\": \"❌ לא נמצאו משקלי LoKr בנקודת הביקורת האחרונה\",\n    \"lokr_no_trained_weights_found\": \"❌ לא נמצאו משקלי LoKr מאומנים ב-{path}\",\n    \"lokr_exported\": \"✅ LoKr יוצא ל-{path}\",\n    \"tab_train_lokr\": \"🚀 אימון LoKr\",\n    \"train_section_tensors\": \"Preprocessed Tensors\",\n    \"train_section_lora\": \"LoRA Settings\",\n    \"train_section_params\": \"Training Parameters\",\n    \"lokr_section_tensors\": \"Preprocessed Tensors\",\n    \"lokr_section_settings\": \"LoKr Settings\",\n    \"lokr_tensor_selection_desc\": \"בחר את הספרייה המכילה את קבצי הטנזורים המעובדים (`.pt`).\",\n    \"lokr_linear_dim\": \"LoKr Linear Dim\",\n    \"lokr_linear_dim_info\": \"Rank (dimension) for LoKr adaptation matrices.\",\n    \"lokr_linear_alpha\": \"LoKr Linear Alpha\",\n    \"lokr_linear_alpha_info\": \"Scaling factor for LoKr (usually similar to dim).\",\n    \"lokr_factor\": \"LoKr Factor\",\n    \"lokr_factor_info\": \"Kronecker factor (-1 for auto).\",\n    \"lokr_decompose_both\": \"Decompose Both Sides\",\n    \"lokr_decompose_both_info\": \"When enabled, decomposes both left and right matrices.\",\n    \"lokr_use_tucker\": \"Use Tucker Decomposition\",\n    \"lokr_use_tucker_info\": \"Apply Tucker decomposition when applicable.\",\n    \"lokr_use_scalar\": \"Use Scalar Gate\",\n    \"lokr_use_scalar_info\": \"Enable scalar gating for LoKr weights.\",\n    \"lokr_weight_decompose\": \"Weight Decompose (WD)\",\n    \"lokr_weight_decompose_info\": \"Enable weight decomposition for more stable LoKr training.\",\n    \"lokr_learning_rate_info\": \"LoKr commonly uses a higher LR than LoRA. Tune per dataset.\",\n    \"lokr_output_dir_info\": \"ספרייה לשמירת משקלי LoKr המאומנים.\",\n    \"start_lokr_training_btn\": \"🚀 התחל אימון LoKr\",\n    \"lokr_training_loss_title\": \"LoKr אובדן אימון (Loss)\",\n    \"lokr_export_header\": \"ייצוא LoKr\",\n    \"export_lokr_btn\": \"📦 ייצוא LoKr\",\n    \"lokr_checkpoint_epoch\": \"Checkpoint Epoch\",\n    \"lokr_checkpoint_epoch_info\": \"Select a specific epoch checkpoint to export, or keep Latest (auto).\",\n    \"refresh_epochs_btn\": \"↻ רענון Epochs\"\n  },\n  \"help\": {\n    \"btn_label\": \"?\",\n    \"close_label\": \"✕\",\n    \"getting_started\": \"## תחילת עבודה\\n\\n1. **בחר מודל** בתפריט ההגדרות (למשל `acestep-v15-turbo`)\\n2. **בחר 5Hz LM** אם ברצונך להשתמש במצב 'חשיבה' (מומלץ)\\n3. לחץ על **אתחול שירות** והמתן לסטטוס הירוק\\n4. בחר **מצב יצירה** (התחל עם 'פשוט')\\n5. תאר את המוזיקה שלך ולחץ על **צור מוזיקה**\\n\\n> **טיפ:** מודלי Turbo הם המהירים ביותר. הפעל את \\\"חשיבה\\\" ליצירה חכמה יותר.\",\n    \"service_config\": \"## תצורת שירות\\n\\n### הגדרה מהירה\\n1. בחר **נתיב מודל ראשי** (מומלץ turbo)\\n2. בחר **נתיב מודל 5Hz LM** (מסונן אוטומטית לפי ה-GPU שלך)\\n3. בחר **Backend**: `vllm` (מהיר, NVIDIA ≥8GB) או `pt` (אוניברסלי)\\n4. סמן **אתחול 5Hz LM** עבור מצב חשיבה\\n5. לחץ על **אתחול שירות**\\n\\n### טיפים לביצועים\\n- **Flash Attention**: הסקה מהירה יותר (דורש flash_attn)\\n- **CPU Offload**: מופעל אוטומטית ב-GPUs מתחת ל-20GB\\n- **INT8 Quantization**: חוסך VRAM, מופעל אוטומטית מתחת ל-20GB\\n- **Compile**: נדרש לקוונטיזציה, מופעל כברירת מחדל\\n\\n### LoRA\\n- הגדר נתיב LoRA ← טען ← הפעל \\\"השתמש ב-LoRA\\\"\\n- ⚠️ לא ניתן להשתמש ב-LoRA עם קוונטיזציית INT8\",\n    \"generation_simple\": \"## מדריך מצב פשוט\\n\\n**הכי מתאים ל:** יצירת מוזיקה מהירה במינימום מאמץ.\\n\\n### שלבים\\n1. בחר **פשוט** במצב יצירה\\n2. הקלד תיאור, למשל *\\\"שיר פופ קצבי עם ריף גיטרה קליט\\\"*\\n3. (אופציונלי) סמן **אינסטרומנטלי** למוזיקה ללא שירה\\n4. (אופציונלי) בחר **שפת שירה**\\n5. לחץ על **צור דגימה** — ה-AI יצור תיאור, מילים ומטא-דאטה\\n6. בדוק וערוך את התוכן שנוצר אם צריך\\n7. לחץ על **צור מוזיקה**\\n\\n### טיפים\\n- לחץ על 🎲 לקבלת השראה אקראית\\n- ככל שהתיאור מפורט יותר, כך התוצאה תהיה טובה יותר\\n- השאר BPM/סולם ריקים כדי לתת ל-AI להחליט\",\n    \"generation_custom\": \"## מדריך מצב מותאם אישית\\n\\n**הכי מתאים ל:** שליטה יצירתית מלאה בכל פרמטר.\\n\\n### שלבים\\n1. בחר **מותאם אישית** במצב יצירה\\n2. כתוב **תיאור** מפורט המתאר סגנון, ז'אנר, כלים ואווירה\\n3. כתוב **מילים** עם תגיות מבנה: `[Verse]`, `[Chorus]`, `[Bridge]`\\n4. (אופציונלי) העלה **אודיו ייחוס** להנחיית הסגנון\\n5. הגדר **BPM**, **סולם**, **משך** או השאר ריק לאוטומטי\\n6. לחץ על **עיצוב** לשיפור הטקסט באמצעות LM (אופציונלי)\\n7. לחץ על **צור מוזיקה**\",\n    \"generation_remix\": \"## מדריך מצב רמיקס\\n\\n**הכי מתאים ל:** יצירת גרסאות כיסוי או שינוי סגנון.\\n\\n### שלבים\\n1. בחר **רמיקס** במצב יצירה\\n2. העלה **אודיו מקור** (השיר שברצונך לעשות לו רמיקס)\\n3. כתוב **תיאור** המתאר את סגנון היעד\\n4. (אופציונלי) שנה את ה**מילים**\\n5. כוונן את **חוזק הרמיקס** (0.0–1.0):\\n   - גבוה יותר = קרוב יותר למבנה המקורי\\n   - נמוך יותר = יותר חופש יצירתי\\n6. לחץ על **צור מוזיקה**\",\n    \"generation_repaint\": \"## מדריך מצב צביעה מחדש (Repaint)\\n\\n**הכי מתאים ל:** תיקון או יצירה מחדש של קטעים ספציפיים במוזיקה תוך שמירה על השאר.\\n\\n### שלבים\\n1. בחר **Repaint** במצב יצירה\\n2. העלה **אודיו מקור**\\n3. הגדר **תחילת צביעה** (בשניות) ו**סיום** (1- לסוף הקובץ)\\n4. כתוב **תיאור** לקטע שיצבע מחדש\\n5. בחר **Repaint Mode** וכוונן **Repaint Strength** לפי הצורך\\n6. לחץ על **צור מוזיקה**\\n\\n### Repaint Mode\\nשולט באופן שבו המודל מטפל באזורים שלא נצבעים מחדש:\\n\\n- **Conservative** (Strength = 0): שימור מקסימלי של המקור. הזרקת latent מקור בכל שלב דיפוזיה עם דעיכה ארוכה בגבולות. הכי טוב למיזוג חלק.\\n- **Balanced** (ברירת מחדל): הזרקת latent מקור בחלק מהשלבים, נשלט על ידי מחוון Repaint Strength. נקודת התחלה מומלצת.\\n- **Aggressive** (Strength = 1): ללא הזרקת מקור כלל - דיפוזיה טהורה. חופש יצירתי מרבי אך עקביות גבולות מינימלית.\\n\\n### Repaint Strength\\nפעיל רק במצב **Balanced**. גרור לשליטה באיזון בין שימור ליצירה מחדש:\\n- **0** = התנהגות שמרנית (מעבר אוטומטי למצב Conservative)\\n- **0.5** = ברירת מחדל - הזרקת מקור ב-50% הראשונים של השלבים\\n- **1** = התנהגות אגרסיבית (מעבר אוטומטי למצב Aggressive)\",\n    \"generation_extract\": \"## מצב חילוץ (Base Model בלבד)\\n\\n**הכי מתאים ל:** הפרדת ערוצים — בידוד כלים מתוך מיקס.\\n\\n### שלבים\\n1. בחר **Extract** במצב יצירה\\n2. העלה **אודיו מקור**\\n3. בחר **שם ערוץ** לחילוץ (למשל שירה, תופים, בס)\\n4. לחץ על **חלץ ערוץ**\",\n    \"generation_lego\": \"## מצב לגו (Base Model בלבד)\\n\\n**הכי מתאים ל:** הוספת ערוצי כלים חדשים לאודיו קיים.\\n\\n### שלבים\\n1. בחר **Lego** במצב יצירה\\n2. העלה **אודיו מקור**\\n3. בחר **שם ערוץ** להוספה\\n4. כתוב **תיאור** המתאר את הערוץ החדש\\n5. לחץ על **הוסף ערוץ**\",\n    \"generation_complete\": \"## מצב השלמה (Base Model בלבד)\\n\\n**הכי מתאים ל:** עיבוד אוטומטי — השלמת כלים חסרים.\\n\\n### שלבים\\n1. בחר **Complete** במצב יצירה\\n2. העלה **אודיו מקור** (עיבוד חלקי)\\n3. בחר מספר **שמות ערוצים** להוספה\\n4. כתוב **תיאור** לסגנון הרצוי\\n5. לחץ על **צור מוזיקה**\",\n    \"generation_caption\": \"## כתיבת תיאורים טובים\\n\\n### מבנה\\nתיאור טוב כולל:\\n- **ז'אנר/סגנון**: פופ, רוק, ג'אז, אלקטרוני, קלאסי…\\n- **כלים**: גיטרה, פסנתר, סינתיסייזר, תופים, כלי מיתר…\\n- **אווירה**: שמח, מלנכולי, אנרגטי, חלומי…\\n- **סגנון שירה**: לחישה, עוצמתי, פלסטו, ראפ…\\n- **תחושת קצב**: מהיר, איטי, מתון…\\n\\n### דוגמאות\\n- *\\\"פופ-פאנק אנרגטי עם גיטרות מעוותות, תופים מהירים ושירה צעקנית\\\"*\\n- *\\\"שלישיית ג'אז רכה עם 'ווקינג בס', תופים מוברשים ופסנתר רגוע\\\"*\",\n    \"generation_lyrics\": \"## כתיבת מילים\\n\\n### תגיות מבנה\\nהשתמש בתגיות כדי לבנות את השיר שלך:\\n```\\n[Verse 1]\\nמילות הבית כאן\\n\\n[Chorus]\\nמילות הפזמון כאן\\n\\n[Verse 2]\\nבית שני\\n\\n[Bridge]\\nקטע מעבר (גשר)\\n\\n[Outro]\\nמילות סיום\\n```\\n\\n### טיפים\\n- שמור על בתים של 4–8 שורות\\n- פזמונים צריכים להיות זכירים וחוזרים על עצמם\\n- השתמש ב-`[Instrumental]` לקטעים ללא שירה\",\n    \"generation_advanced\": \"## הגדרות מתקדמות\\n\\n### פרמטרים מרכזיים\\n- **צעדי הסקה**: Turbo=8 (ברירת מחדל), Base=עד 200. יותר צעדים לא תמיד טוב יותר ב-Turbo\\n- **Guidance Scale**: למודל Base בלבד. גבוה יותר = נצמד יותר להנחיה\\n- **Shift**: הסטת צעדי זמן (1.0–5.0). 3.0 מומלץ ל-turbo\\n- **Seed**: הגדר גרעין ספציפי לתוצאות הניתנות לשחזור\\n\\n### פרמטרי LM\\n- **Temperature**: גבוה יותר = יצירתי/אקראי יותר\\n- **CFG Scale**: גבוה יותר = עוקב יותר אחרי ההנחיה\\n\\n### מצב חשיבה (Think)\\nהפעל את **Think** לשימוש ב-5Hz LM ליצירה חכמה יותר.\",\n    \"results\": \"## מדור תוצאות\\n\\n### בקרות לכל דגימה\\n- **נגן אודיו**: נגן, השהה, הורד\\n- **שלח לרמיקס/צביעה מחדש**: השתמש בתוצאה זו כמקור להמשך עריכה\\n- **שמירה**: ייצא אודיו + מטא-דאטה כ-JSON\\n- **Score**: חשב ציון איכות\\n- **LRC**: ייצר חותמות זמן למילים\",\n    \"training_dataset\": \"## מדריך בונה מערכי נתונים\\n\\n### שלב 1: טעינה או סריקה\\n- **טעינה**: הזן נתיב ל-JSON קיים ← לחץ על טעינה\\n- **סריקה**: הזן נתיב לתיקיית אודיו ← לחץ על סריקה\\n\\n### שלב 2: תצורה\\n- הגדר **שם מערך נתונים**\\n- סמן **הכל אינסטרומנטלי** אם אין שירה\\n- הגדר **תג הפעלה מותאם**\\n\\n### שלב 3: תיוג אוטומטי\\n- לחץ על **תיוג אוטומטי להכל** לייצור תיאורים ונתונים מוזיקליים\",\n    \"training_train\": \"## מדריך אימון LoRA\\n\\n### הגדרה\\n1. הזן **ספריית טנזורים מעובדים** ← לחץ על **טען מערך נתונים**\\n2. הגדר LoRA:\\n   - **Rank** (r): 64 ברירת מחדל.\\n   - **Alpha**: בדרך כלל פי 2 מה-Rank (128)\\n\\n### אימון\\n3. הגדר **קצב למידה** (התחל עם 1e-4)\\n4. הגדר **מקסימום איטרציות** (500 ברירת מחדל)\\n5. לחץ על **התחל אימון**\\n\\n### ייצוא\\n8. הזן נתיב ייצוא ← לחץ על **ייצוא LoRA**\",\n    \"training_lokr\": \"## 🚀 מדריך אימון LoKr\\n\\nLoKr (Low-rank Kronecker product) שיפר משמעותית את יעילות האימון. מה שלקח שעה עם LoRA לוקח כעת 5 דקות — **פי 10 מהר יותר**. זה קריטי לאימון על כרטיסי מסך ביתיים.\\n\\n### הגדרה\\n1. הזן **ספריית טנזורים מעובדים** ← לחץ על **טען מערך נתונים**\\n2. הגדר LoKr:\\n   - **Linear Dim**: 64 ברירת מחדל (דומה לדרגת LoRA)\\n   - **Weight Decompose (DoRA)**: מופעל כברירת מחדל לאיכות טובה יותר\\n\\n### אימון\\n3. הגדר **קצב למידה** (LoKr דורש בדרך כלל LR גבוה יותר, התחל ב-1e-3)\\n4. לחץ על **התחל אימון LoKr**\",\n    \"training_export\": \"## שימוש ב-LoRA המאומן שלך\\n\\n### ייצוא\\n1. לאחר האימון, הזן נתיב ייצוא\\n2. לחץ על **ייצוא LoRA**\\n\\n### טעינה ושימוש\\n1. בהגדרות, הגדר את **נתיב LoRA** לספרייה שייצאת\\n2. לחץ על **טען LoRA**\\n3. סמן את תיבת הסימון **השתמש ב-LoRA**\\n4. צור מוזיקה — סגנון ה-LoRA שלך יוחל על התוצאה\"\n  },\n  \"gen\": {\n    \"enable_normalization\": \"אפשר נורמליזציה\",\n    \"enable_normalization_info\": \"נרמל את עוצמת האודיו לרמת שיא מוגדרת כדי למנוע קטיעה או להבטיח עוצמה עקבית.\",\n    \"normalization_db\": \"שיא יעד (dB)\",\n    \"normalization_db_info\": \"רמת שיא היעד בדציבלים. -1.0 dB הוא התקן הבטוח.\",\n    \"latent_shift\": \"הסטת לטנטים (Latent Shift)\",\n    \"latent_shift_info\": \"הסטה המוחלת על ה-DiT latents לפני פענוח VAE. ערכים שליליים (למשל -0.04) יכולים להפחית קטיעה.\",\n    \"latent_rescale\": \"שינוי קנה מידה לטנטי\",\n    \"latent_rescale_info\": \"גורם שינוי קנה מידה לפני פענוח VAE. ערכים < 1.0 (למשל 0.91) יכולים להפחית קטיעה.\"\n  }\n}\n"
  },
  {
    "path": "acestep/ui/gradio/i18n/i18n.py",
    "content": "\"\"\"\nInternationalization (i18n) module for Gradio UI\nSupports multiple languages with easy translation management\n\"\"\"\nimport contextvars\nimport os\nimport json\nfrom threading import Lock\nfrom typing import Dict, Optional\n\nfrom loguru import logger\n\n# Per-request language context.  When set, I18n.t() uses this value\n# instead of the shared current_language attribute, giving each\n# concurrent request its own language scope without cross-talk.\n_current_language_var: contextvars.ContextVar[str | None] = contextvars.ContextVar(\n    \"current_language\", default=None\n)\n\n\nclass I18n:\n    \"\"\"Internationalization handler\"\"\"\n\n    def __init__(self, default_language: str = \"en\"):\n        \"\"\"\n        Initialize i18n handler\n\n        Args:\n            default_language: Default language code (en, zh, ja, etc.)\n        \"\"\"\n        self._lock = Lock()\n        self.current_language = default_language\n        self.languages_info: list[tuple[str, str, str]] = []\n        self.translations: Dict[str, Dict[str, str]] = {}\n        self._load_all_translations()\n    \n    def _load_all_translations(self):\n        \"\"\"Load all translation files from i18n directory.\"\"\"\n        current_file = os.path.abspath(__file__)\n        # JSON files live alongside this module in the same directory\n        i18n_dir = os.path.dirname(current_file)\n        \n        if not os.path.exists(i18n_dir):\n            os.makedirs(i18n_dir)\n            return\n        \n        # Load all JSON files in i18n directory\n        for filename in os.listdir(i18n_dir):\n            if filename.endswith(\".json\"):\n                lang_code = filename[:-5]  # Remove .json extension\n                filepath = os.path.join(i18n_dir, filename)\n                try:\n                    with open(filepath, 'r', encoding='utf-8') as f:\n                        self.translations[lang_code] = json.load(f)\n                except Exception as e:\n                    print(f\"Error loading translation file {filename}: {e}\")\n                else:\n                    lang_name = self._get_nested_value(\n                        self.translations.get(lang_code, {}),\n                        \"common.language_metadata.name\") or lang_code.upper()\n                    lang_native_name = self._get_nested_value(\n                        self.translations.get(lang_code, {}),\n                        \"common.language_metadata.native_name\") or lang_code\n                    self.languages_info.append((lang_code, lang_name, lang_native_name))\n    \n    def set_language(self, language: str):\n        \"\"\"Set the instance-level default language (shared fallback when no ContextVar is active).\"\"\"\n        with self._lock:\n            if language in self.translations:\n                self.current_language = language\n            else:\n                print(f\"Warning: Language '{language}' not found, using default\")\n    \n    def t(self, key: str, **kwargs) -> str:\n        \"\"\"Translate *key* using per-request ContextVar, then instance default, then English.\"\"\"\n        # Prefer the per-request ContextVar; fall back to the shared\n        # instance attribute (snapshot under lock for thread safety).\n        lang = _current_language_var.get()\n        if lang is None:\n            with self._lock:\n                lang = self.current_language\n\n        # Get translation from current language\n        translation = self._get_nested_value(\n            self.translations.get(lang, {}),\n            key\n        )\n        \n        # Fallback to English if not found\n        if translation is None:\n            translation = self._get_nested_value(\n                self.translations.get('en', {}), \n                key\n            )\n        \n        # Final fallback to key itself\n        if translation is None:\n            translation = key\n        \n        # Apply formatting if kwargs provided\n        if kwargs:\n            try:\n                translation = translation.format(**kwargs)\n            except KeyError:\n                pass\n        \n        return translation\n    \n    def _get_nested_value(self, data: dict, key: str) -> Optional[str]:\n        \"\"\"\n        Get nested dictionary value using dot notation\n        \n        Args:\n            data: Dictionary to search\n            key: Dot-separated key (e.g., \"section.subsection.key\")\n        \n        Returns:\n            Value if found, None otherwise\n        \"\"\"\n        keys = key.split('.')\n        current = data\n        \n        for k in keys:\n            if isinstance(current, dict) and k in current:\n                current = current[k]\n            else:\n                return None\n        \n        return current if isinstance(current, str) else None\n    \n    def get_available_languages(self) -> list:\n        \"\"\"Get list of available language codes\"\"\"\n        return list(self.translations.keys())\n    \n    def get_available_languages_info(self) -> list[tuple[str, str, str]]:\n        \"\"\"\n        Provides a list of tuples containing ISO codes and descriptive language names\n        \n        Returns:\n            List of tuples (iso code, english name, native name)\n         \"\"\"\n        return list(self.languages_info)\n\n\n# Global i18n instance\n_i18n_instance: Optional[I18n] = None\n_i18n_lock = Lock()\n\n\ndef get_i18n(language: Optional[str] = None) -> I18n:\n    \"\"\"\n    Get global i18n instance\n\n    Args:\n        language: Optional language to set\n\n    Returns:\n        I18n instance\n    \"\"\"\n    global _i18n_instance\n\n    if _i18n_instance is None:\n        with _i18n_lock:\n            if _i18n_instance is None:\n                _i18n_instance = I18n(default_language=language or \"en\")\n                return _i18n_instance\n    if language is not None:\n        _i18n_instance.set_language(language)\n\n    return _i18n_instance\n\n\ndef set_language_context(language: str) -> contextvars.Token[str | None]:\n    \"\"\"Set the per-request language for the current execution context.\n\n    Call at a request boundary (Gradio event handler, FastAPI middleware)\n    to scope ``t()`` calls to *language* without mutating shared state.\n    If *language* is not in loaded translations, ``t()`` silently falls\n    back to English.  Requires the singleton to be initialised first\n    (via ``get_i18n()``) for validation; otherwise the check is skipped.\n\n    Returns a token for ``reset_language_context`` to restore the prior value.\n    \"\"\"\n    # Set the ContextVar BEFORE logging so that any reentrant t() call\n    # triggered by the logger already sees the new language.\n    token = _current_language_var.set(language)\n    instance = _i18n_instance\n    if instance is not None and language not in instance.translations:\n        logger.warning(\"Language '{}' not in translations, t() will fall back to English\",\n                       language)\n    return token\n\n\ndef reset_language_context(token: contextvars.Token[str | None]) -> None:\n    \"\"\"Restore the per-request language to its previous value.\"\"\"\n    _current_language_var.reset(token)\n\n\ndef t(key: str, **kwargs) -> str:\n    \"\"\"\n    Convenience function for translation\n\n    Args:\n        key: Translation key\n        **kwargs: Optional format parameters\n\n    Returns:\n        Translated string\n    \"\"\"\n    return get_i18n().t(key, **kwargs)\n\n\ndef available_languages_info() -> list[tuple[str, str, str]]:\n    \"\"\"\n    Provides a list of tuples containing ISO codes and descriptive language names\n\n    Returns:\n        List of tuples (iso code, english name, native name)\n    \"\"\"\n    return get_i18n().get_available_languages_info()\n"
  },
  {
    "path": "acestep/ui/gradio/i18n/i18n_thread_safety_test.py",
    "content": "\"\"\"Thread safety tests for the i18n singleton and ContextVar isolation.\"\"\"\n\nimport contextvars\nimport sys\nimport threading\nimport unittest\nfrom unittest.mock import patch\n\nfrom acestep.ui.gradio.i18n.i18n import (\n    _current_language_var,\n    _i18n_lock,\n    get_i18n,\n    reset_language_context,\n    set_language_context,\n    t,\n)\n\n\nclass I18nThreadSafetyTests(unittest.TestCase):\n    \"\"\"Verify get_i18n() returns a single instance under concurrent access.\"\"\"\n\n    def test_concurrent_get_i18n_returns_same_instance(self):\n        \"\"\"Multiple threads calling get_i18n() must all receive the same object.\"\"\"\n        results: list[int] = []\n        errors: list[str] = []\n        barrier = threading.Barrier(8)\n\n        def _call_get_i18n() -> None:\n            \"\"\"Fetch singleton after barrier synchronization.\"\"\"\n            try:\n                barrier.wait(timeout=5)\n                results.append(id(get_i18n()))\n            except Exception as exc:  # noqa: BLE001\n                errors.append(f\"get_i18n failed: {exc!r}\")\n\n        threads = [threading.Thread(target=_call_get_i18n) for _ in range(8)]\n        for th in threads:\n            th.start()\n        for th in threads:\n            th.join()\n\n        self.assertEqual(errors, [], f\"Thread failure detected: {errors}\")\n        self.assertEqual(\n            len(set(results)), 1,\n            \"get_i18n() returned different instances across threads\",\n        )\n\n    def test_lock_attribute_exists(self):\n        \"\"\"Module-level lock must be present.\"\"\"\n        self.assertIsInstance(_i18n_lock, type(threading.Lock()))\n\n\nclass ContextVarIsolationTests(unittest.TestCase):\n    \"\"\"Verify per-request language isolation via ContextVar.\"\"\"\n\n    def setUp(self):\n        \"\"\"Ensure ContextVar is clean before each test.\"\"\"\n        # Reset to default (None) so tests don't leak state\n        tok = _current_language_var.set(None)\n        self.addCleanup(_current_language_var.reset, tok)\n\n    def test_contextvar_overrides_instance_language(self):\n        \"\"\"t() must return the ContextVar language's translation, not the instance default.\"\"\"\n        i18n = get_i18n()\n        i18n.set_language(\"en\")\n        en_title = t(\"app.title\")\n\n        token = set_language_context(\"zh\")\n        try:\n            zh_title = t(\"app.title\")\n            # The ContextVar must have changed the language t() uses\n            self.assertEqual(_current_language_var.get(), \"zh\")\n            self.assertNotEqual(\n                en_title, zh_title,\n                \"t() returned the same string for en and zh — ContextVar was ignored\",\n            )\n        finally:\n            reset_language_context(token)\n\n        # After reset, t() falls back to the instance default (en)\n        self.assertIsNone(_current_language_var.get())\n        self.assertEqual(t(\"app.title\"), en_title)\n\n    def test_contextvar_none_falls_back_to_instance(self):\n        \"\"\"When ContextVar is unset (None), t() should use instance default.\"\"\"\n        i18n = get_i18n()\n        i18n.set_language(\"en\")\n\n        self.assertIsNone(_current_language_var.get())\n        # t() should still work — it falls back to instance language\n        result = t(\"nonexistent.key.for.test\")\n        self.assertEqual(result, \"nonexistent.key.for.test\")\n\n    def test_reset_restores_previous_value(self):\n        \"\"\"reset_language_context must restore the prior ContextVar value.\"\"\"\n        token1 = set_language_context(\"ja\")\n        try:\n            self.assertEqual(_current_language_var.get(), \"ja\")\n            token2 = set_language_context(\"zh\")\n            try:\n                self.assertEqual(_current_language_var.get(), \"zh\")\n            finally:\n                reset_language_context(token2)\n            # Should be back to \"ja\"\n            self.assertEqual(_current_language_var.get(), \"ja\")\n        finally:\n            reset_language_context(token1)\n        self.assertIsNone(_current_language_var.get())\n\n    def test_concurrent_contexts_are_isolated(self):\n        \"\"\"Two threads with different ContextVar values must not interfere.\"\"\"\n        barrier = threading.Barrier(2)\n        results: dict[str, str | None] = {}\n        errors: list[str] = []\n\n        def _worker(name: str, lang: str) -> None:\n            \"\"\"Set ContextVar, wait for peer, then verify own value.\"\"\"\n            try:\n                token = set_language_context(lang)\n                try:\n                    # Both threads set their ContextVar, then sync\n                    barrier.wait(timeout=5)\n                    # Each thread should still see its own language\n                    results[name] = _current_language_var.get()\n                finally:\n                    reset_language_context(token)\n            except Exception as exc:  # noqa: BLE001\n                errors.append(f\"{name} failed: {exc!r}\")\n\n        t1 = threading.Thread(target=_worker, args=(\"thread_zh\", \"zh\"))\n        t2 = threading.Thread(target=_worker, args=(\"thread_ja\", \"ja\"))\n        t1.start()\n        t2.start()\n        t1.join()\n        t2.join()\n\n        self.assertEqual(errors, [], f\"Thread failure: {errors}\")\n        self.assertEqual(results[\"thread_zh\"], \"zh\",\n                         \"Thread with zh context saw wrong language\")\n        self.assertEqual(results[\"thread_ja\"], \"ja\",\n                         \"Thread with ja context saw wrong language\")\n\n    def test_mixed_contextvar_and_fallback_threads(self):\n        \"\"\"One thread with ContextVar override, one without, must not interfere.\"\"\"\n        i18n = get_i18n()\n        i18n.set_language(\"en\")\n        en_title = t(\"app.title\")\n\n        barrier = threading.Barrier(2)\n        results: dict[str, str] = {}\n        errors: list[str] = []\n\n        def _worker_with_context() -> None:\n            \"\"\"Set ContextVar to zh and translate.\"\"\"\n            try:\n                token = set_language_context(\"zh\")\n                try:\n                    barrier.wait(timeout=5)\n                    results[\"with_ctx\"] = t(\"app.title\")\n                finally:\n                    reset_language_context(token)\n            except Exception as exc:  # noqa: BLE001\n                errors.append(f\"with_context failed: {exc!r}\")\n\n        def _worker_without_context() -> None:\n            \"\"\"No ContextVar — should use instance default (en).\"\"\"\n            try:\n                barrier.wait(timeout=5)\n                results[\"without_ctx\"] = t(\"app.title\")\n            except Exception as exc:  # noqa: BLE001\n                errors.append(f\"without_context failed: {exc!r}\")\n\n        t1 = threading.Thread(target=_worker_with_context)\n        t2 = threading.Thread(target=_worker_without_context)\n        t1.start()\n        t2.start()\n        t1.join()\n        t2.join()\n\n        self.assertEqual(errors, [], f\"Thread failure: {errors}\")\n        # Thread without ContextVar must see the instance default (en)\n        self.assertEqual(results[\"without_ctx\"], en_title,\n                         \"Fallback thread got wrong language\")\n        # Thread with ContextVar must see zh (different from en)\n        self.assertNotEqual(results[\"with_ctx\"], en_title,\n                            \"ContextVar thread got instance default instead of zh\")\n\n    def test_set_language_context_warns_on_invalid_language(self):\n        \"\"\"set_language_context logs a warning when the language is not in translations.\"\"\"\n        # Ensure singleton exists so validation can run\n        get_i18n()\n        # \"xyz_invalid\" is not a loaded translation\n        with patch.object(\n            sys.modules[set_language_context.__module__], \"logger\",\n        ) as mock_logger:\n            token = set_language_context(\"xyz_invalid\")\n            try:\n                # ContextVar is still set (graceful degradation)\n                self.assertEqual(_current_language_var.get(), \"xyz_invalid\")\n                # Warning must have fired exactly once\n                mock_logger.warning.assert_called_once()\n                # t() should fall back to English, then to key itself\n                result = t(\"app.title\")\n                # Should get the English fallback, not the raw key\n                self.assertNotEqual(result, \"app.title\",\n                                    \"Expected English fallback, got raw key\")\n            finally:\n                reset_language_context(token)\n\n    def test_contextvar_isolation_in_copy_context(self):\n        \"\"\"contextvars.copy_context isolates changes from the parent.\"\"\"\n        parent_token = set_language_context(\"en\")\n        try:\n            parent_val = _current_language_var.get()\n\n            def _child() -> str:\n                \"\"\"Run in a copied context; change should not leak back.\"\"\"\n                set_language_context(\"zh\")\n                return _current_language_var.get()\n\n            ctx = contextvars.copy_context()\n            child_val = ctx.run(_child)\n\n            self.assertEqual(parent_val, \"en\")\n            self.assertEqual(child_val, \"zh\")\n            # Parent context is unchanged\n            self.assertEqual(_current_language_var.get(), \"en\")\n        finally:\n            reset_language_context(parent_token)\n\n\nif __name__ == \"__main__\":\n    unittest.main()\n"
  },
  {
    "path": "acestep/ui/gradio/i18n/ja.json",
    "content": "{\n  \"app\": {\n    \"title\": \"🎛️ ACE-Step V1.5 プレイグラウンド💡\",\n    \"subtitle\": \"オープンソース音楽生成の限界を押し広げる\"\n  },\n  \"common\": {\n    \"language_metadata\": {\n      \"name\": \"Japanese\",\n      \"native_name\": \"日本語\"\n    }\n  },\n  \"dataset\": {\n    \"title\": \"📊 データセットエクスプローラー\",\n    \"dataset_label\": \"データセット\",\n    \"dataset_info\": \"探索するデータセットを選択。\",\n    \"import_btn\": \"📥 データセットをインポート\",\n    \"search_type_label\": \"検索タイプ\",\n    \"search_type_info\": \"アイテムの検索方法。\",\n    \"search_value_label\": \"検索値\",\n    \"search_value_placeholder\": \"キーまたはインデックスを入力(空白の場合はランダム)\",\n    \"search_value_info\": \"キー: 完全一致、インデックス: 0からデータセットサイズ-1。\",\n    \"instruction_label\": \"📝 指示\",\n    \"instruction_placeholder\": \"利用可能な指示がありません\",\n    \"metadata_title\": \"📋 アイテムメタデータ (JSON)\",\n    \"metadata_label\": \"完全なアイテム情報\",\n    \"source_audio\": \"ソースオーディオ\",\n    \"target_audio\": \"ターゲットオーディオ\",\n    \"reference_audio\": \"リファレンスオーディオ\",\n    \"get_item_btn\": \"🔍 アイテムを取得\",\n    \"use_src_checkbox\": \"データセットのソースオーディオを使用\",\n    \"use_src_info\": \"データセットのソースオーディオを使用する場合はチェック。\",\n    \"data_status_label\": \"📊 データステータス\",\n    \"data_status_default\": \"❌ データセットがインポートされていません\",\n    \"autofill_btn\": \"📋 生成フォームを自動入力\"\n  },\n  \"service\": {\n    \"title\": \"🔧 サービス設定\",\n    \"checkpoint_label\": \"チェックポイントファイル\",\n    \"checkpoint_info\": \"訓練済みモデルのチェックポイントファイルを選択(フルパスまたはファイル名)。\",\n    \"refresh_btn\": \"🔄 更新\",\n    \"model_path_label\": \"メインモデルパス\",\n    \"model_path_info\": \"モデル設定ディレクトリを選択(チェックポイントから自動スキャン)。\",\n    \"device_label\": \"デバイス\",\n    \"device_info\": \"処理デバイス(自動検出を推奨)。\",\n    \"lm_model_path_label\": \"5Hz LM モデルパス\",\n    \"lm_model_path_info\": \"5Hz LMモデルチェックポイントを選択(チェックポイントから自動スキャン)。\",\n    \"backend_label\": \"5Hz LM バックエンド\",\n    \"backend_info\": \"5Hz LMのバックエンドを選択: vllm(高速)またはpt(PyTorch、より互換性あり)。\",\n    \"init_llm_label\": \"5Hz LM を初期化\",\n    \"init_llm_info\": \"サービス初期化中に5Hz LMを初期化する場合はチェック。\",\n    \"lm_unavailable_vram\": \"⚠️ このGPUティアではLMを利用できません（VRAM不足）\",\n    \"flash_attention_label\": \"Flash Attention を使用\",\n    \"flash_attention_info_enabled\": \"推論を高速化するためにflash attentionを有効にする(flash_attnパッケージが必要)\",\n    \"flash_attention_info_disabled\": \"Flash attentionは利用できません(flash_attnパッケージがインストールされていません)\",\n    \"offload_cpu_label\": \"CPUにオフロード\",\n    \"offload_cpu_info\": \"使用していない時にモデルをCPUにオフロードしてGPUメモリを節約。\",\n    \"offload_dit_cpu_label\": \"DiTをCPUにオフロード\",\n    \"offload_dit_cpu_info\": \"DiTをCPUにオフロード(CPUへのオフロードが必要)。\",\n    \"compile_model_label\": \"モデルをコンパイル\",\n    \"compile_model_info\": \"torch.compileでモデルを最適化（量子化に必要）。\",\n    \"quantization_label\": \"INT8 量子化\",\n    \"quantization_info\": \"INT8重み量子化を有効にしてVRAMを節約（モデルのコンパイルが必要）。\",\n    \"mlx_dit_label\": \"MLX DiT (Apple Silicon)\",\n    \"mlx_dit_info_enabled\": \"Apple SiliconでMLXネイティブDiT拡散を使用（MPSより高速）\",\n    \"mlx_dit_info_disabled\": \"MLXは利用不可（macOS + Apple Silicon + mlxパッケージが必要）\",\n    \"init_btn\": \"サービスを初期化\",\n    \"status_label\": \"ステータス\",\n    \"language_label\": \"UI言語\",\n    \"language_info\": \"インターフェース言語を選択。\",\n    \"gpu_auto_tier\": \"自動検出ティア\",\n    \"tier_label\": \"GPU ティアの手動選択\",\n    \"tier_info\": \"GPUティアを手動で選択して最適化のデフォルト（オフロード、量子化、バックエンドなど）を調整します。\"\n  },\n  \"generation\": {\n    \"tab_title\": \"🎵 生成\",\n    \"required_inputs\": \"📝 必須入力\",\n    \"task_type_label\": \"タスクタイプ *\",\n    \"task_type_info\": \"生成のタスクタイプを選択。\",\n    \"instruction_label\": \"指示\",\n    \"instruction_info\": \"指示はタスクタイプに基づいて自動生成されます。\",\n    \"load_btn\": \"📂 読込\",\n    \"track_name_label\": \"トラック名\",\n    \"track_name_info\": \"lego/extractタスクのトラック名を選択。\",\n    \"track_classes_label\": \"トラック名\",\n    \"track_classes_info\": \"completeタスクの複数のトラッククラスを選択。\",\n    \"audio_uploads\": \"🎵 オーディオアップロード\",\n    \"reference_audio\": \"リファレンスオーディオ\",\n    \"source_audio\": \"ソースオーディオ\",\n    \"convert_codes_btn\": \"コードに変換\",\n    \"analyze_btn\": \"🔍 分析\",\n    \"sample_btn\": \"🎲 お試し\",\n    \"lm_codes_hints\": \"🎼 LM コードヒント\",\n    \"lm_codes_label\": \"LM コードヒント\",\n    \"lm_codes_placeholder\": \"<|audio_code_10695|><|audio_code_54246|>.\",\n    \"lm_codes_info\": \"text2music生成用のLMコードヒントを貼り付け。\",\n    \"lm_codes_sample\": \"LM コードヒント(サンプル {n})\",\n    \"lm_codes_sample_info\": \"サンプル{n}のコード。\",\n    \"transcribe_btn\": \"転写\",\n    \"repainting_controls\": \"🎨 再描画コントロール(秒)\",\n    \"repainting_start\": \"再描画開始\",\n    \"repainting_end\": \"再描画終了\",\n    \"mode_label\": \"生成モード *\",\n    \"mode_info\": \"生成モードを選択して開始します。\",\n    \"mode_info_simple\": \"自然言語で音楽を説明すると、AIがキャプション、歌詞、メタデータを自動生成します。\",\n    \"mode_info_custom\": \"キャプション、歌詞、すべてのパラメータを完全にコントロール。\",\n    \"mode_info_remix\": \"ソースオーディオをアップロードして、キャプションと歌詞でリミックスバージョンを作成。\",\n    \"mode_info_repaint\": \"ソースオーディオをアップロードして、指定した時間範囲を再描画。\",\n    \"mode_info_extract\": \"ソースオーディオから特定のトラック（ボーカル、ドラムなど）を抽出。\",\n    \"mode_info_lego\": \"トラックの再構成：ソースオーディオの特定のトラックを置き換え。\",\n    \"mode_info_complete\": \"ソースオーディオの欠落したトラックを補完。\",\n    \"mode_simple\": \"シンプル\",\n    \"mode_custom\": \"カスタム\",\n    \"simple_query_label\": \"曲の説明 *\",\n    \"simple_query_placeholder\": \"作成したい音楽を説明してください。例：'静かな夜のための優しいベンガルのラブソング'。空欄の場合はランダムなサンプルが生成されます。\",\n    \"simple_query_info\": \"生成したい音楽の自然言語の説明を入力。\",\n    \"simple_vocal_language_label\": \"ボーカル言語\",\n    \"simple_vocal_language_info\": \"歌詞の希望言語を選択。任意の言語の場合は'unknown'を使用。\",\n    \"create_sample_btn\": \"サンプル作成\",\n    \"caption_title\": \"📝 音楽キャプション\",\n    \"caption_label\": \"音楽キャプション\",\n    \"caption_placeholder\": \"柔らかいボーカルを伴う穏やかなアコースティックギターのメロディー.\",\n    \"caption_info\": \"スタイル、ジャンル、楽器、ムードを説明。\",\n    \"lyrics_title\": \"📝 歌詞\",\n    \"lyrics_label\": \"歌詞\",\n    \"lyrics_placeholder\": \"[バース1]\\\\n星空の下で\\\\nとても生きていると感じる.\",\n    \"lyrics_info\": \"構造を持つ曲の歌詞。\",\n    \"instrumental_label\": \"インストゥルメンタル\",\n    \"format_btn\": \"フォーマット\",\n    \"format_caption_btn\": \"キャプションを強化\",\n    \"format_lyrics_btn\": \"歌詞を強化\",\n    \"optional_params\": \"⚙️ オプションパラメータ\",\n    \"optional_music_props\": \"🎵 音楽プロパティ\",\n    \"optional_gen_settings\": \"📐 生成設定\",\n    \"advanced_dit_section\": \"🎛️ DiT 拡散パラメータ\",\n    \"advanced_lm_section\": \"🤖 LM 生成パラメータ\",\n    \"advanced_output_section\": \"🔊 オーディオ出力と後処理\",\n    \"advanced_automation_section\": \"⚡ 自動化とバッチ\",\n    \"vocal_language_label\": \"ボーカル言語\",\n    \"vocal_language_info\": \"'unknown' = インスト/自動。\",\n    \"bpm_label\": \"BPM\",\n    \"bpm_info\": \"空白の場合は N/A。\",\n    \"keyscale_label\": \"キー\",\n    \"keyscale_placeholder\": \"空白の場合はN/A\",\n    \"keyscale_info\": \"A-G, #/♭, メジャー/マイナー。\",\n    \"timesig_label\": \"拍子記号\",\n    \"timesig_info\": \"2/4, 3/4, 4/4。\",\n    \"duration_label\": \"オーディオ長(秒)\",\n    \"duration_info\": \"ランダムの場合は-1を使用。\",\n    \"batch_size_label\": \"バッチサイズ\",\n    \"batch_size_info\": \"生成するオーディオの数(最大8)。\",\n    \"advanced_settings\": \"⚙️ 設定\",\n    \"inference_steps_label\": \"DiT 推論ステップ\",\n    \"inference_steps_info\": \"Turbo: 最大8、Base: 最大200。\",\n    \"guidance_scale_label\": \"DiT ガイダンススケール(baseモデルのみサポート)\",\n    \"guidance_scale_info\": \"値が高いほどテキストに忠実に従う。\",\n    \"seed_label\": \"シード\",\n    \"seed_info\": \"バッチにはカンマ区切りの値を使用。\",\n    \"random_seed_label\": \"ランダムシード\",\n    \"random_seed_info\": \"有効にすると自動的にシードを生成。\",\n    \"audio_format_label\": \"オーディオフォーマット\",\n    \"audio_format_info\": \"保存ファイルのオーディオフォーマット。\",\n    \"use_adg_label\": \"ADG を使用\",\n    \"use_adg_info\": \"角度ドメインガイダンスを有効化。\",\n    \"shift_label\": \"シフト\",\n    \"shift_info\": \"baseモデル用タイムステップシフト係数 (範囲 1.0~5.0、デフォルト 3.0)。turboモデルには無効。\",\n    \"infer_method_label\": \"推論方法\",\n    \"infer_method_info\": \"拡散推論方法。ODE (オイラー) は高速、SDE (確率的) は異なる結果を生成する可能性があります。\",\n    \"custom_timesteps_label\": \"カスタムタイムステップ\",\n    \"custom_timesteps_info\": \"1.0から0.0へのカンマ区切り値（例：'0.97,0.76,0.615,0.5,0.395,0.28,0.18,0.085,0'）。推論ステップとシフトを上書きします。\",\n    \"cfg_interval_start\": \"CFG 間隔開始\",\n    \"cfg_interval_end\": \"CFG 間隔終了\",\n    \"lm_params_title\": \"🤖 LM 生成パラメータ\",\n    \"lm_temperature_label\": \"LM 温度\",\n    \"lm_temperature_info\": \"5Hz LM温度(高いほどランダム)。\",\n    \"lm_cfg_scale_label\": \"LM CFG スケール\",\n    \"lm_cfg_scale_info\": \"5Hz LM CFG (1.0 = CFGなし)。\",\n    \"lm_top_k_label\": \"LM Top-K\",\n    \"lm_top_k_info\": \"Top-K (0 = 無効)。\",\n    \"lm_top_p_label\": \"LM Top-P\",\n    \"lm_top_p_info\": \"Top-P (1.0 = 無効)。\",\n    \"lm_negative_prompt_label\": \"LM ネガティブプロンプト\",\n    \"lm_negative_prompt_placeholder\": \"CFGのネガティブプロンプトを入力(デフォルト: NO USER INPUT)\",\n    \"lm_negative_prompt_info\": \"ネガティブプロンプト(LM CFGスケール > 1.0の場合に使用)。\",\n    \"cot_metas_label\": \"CoT メタデータ\",\n    \"cot_metas_info\": \"LMを使用してCoTメタデータを生成(チェックを外すとLM CoT生成をスキップ)。\",\n    \"cot_language_label\": \"CoT 言語\",\n    \"cot_language_info\": \"CoTで言語を生成(思考の連鎖)。\",\n    \"constrained_debug_label\": \"制約付きデコーディングデバッグ\",\n    \"constrained_debug_info\": \"制約付きデコーディングのデバッグログを有効化(チェックすると詳細ログを表示)。\",\n    \"auto_score_label\": \"自動スコアリング\",\n    \"auto_score_info\": \"生成されたすべてのオーディオの品質スコアを自動計算。\",\n    \"auto_lrc_label\": \"自動 LRC\",\n    \"auto_lrc_info\": \"生成されたすべてのオーディオのLRC歌詞タイムスタンプを自動生成。\",\n    \"lm_batch_chunk_label\": \"LM バッチチャンクサイズ\",\n    \"lm_batch_chunk_info\": \"LMバッチチャンクあたりの最大アイテム数(デフォルト: 8、GPUメモリによる制限)。\",\n    \"codes_strength_label\": \"LM コード強度\",\n    \"codes_strength_info\": \"LM生成コードを使用するデノイジングステップ数を制御。\",\n    \"similarity_denoise_label\": \"類似度 / ノイズ除去\",\n    \"similarity_denoise_info\": \"出力が参照オーディオにどれだけ忠実かを制御します。高い値ほど構造を保持します。\",\n    \"cover_strength_label\": \"オーディオカバー強度\",\n    \"cover_strength_info\": \"カバーモードを使用するデノイジングステップ数を制御。\",\n    \"remix_strength_label\": \"リミックス強度\",\n    \"remix_strength_info\": \"リミックスがソースオーディオにどれだけ忠実かを制御（高い = オリジナルに近い）。\",\n    \"cover_noise_strength_label\": \"カバー強度\",\n    \"cover_noise_strength_info\": \"Remixモードでのメロディ復元を制御します。推奨：SFTモデルを使用し、値を0.1〜0.25に設定。わずかに上げるとメロディが復元されますが、スタイル変換には追加のプロンプト調整が必要な場合があります。（0 = 純粋なノイズ/カバーなし、1 = オリジナルに最も近い）。\",\n    \"score_sensitivity_label\": \"品質スコア感度\",\n    \"score_sensitivity_info\": \"低い = より敏感(デフォルト: 1.0)。PMIが[0,1]にマッピングする方法を調整。\",\n    \"think_label\": \"思考\",\n    \"parallel_thinking_label\": \"並列思考\",\n    \"parallel_thinking_info\": \"バッチサンプルを並列処理して高速生成。\",\n    \"generate_btn\": \"🎵 音楽を生成\",\n    \"extract_stem_btn\": \"🎵 ステム抽出\",\n    \"add_stem_btn\": \"🎵 ステム追加\",\n    \"stem_area_controls\": \"🧩 新ステム範囲（秒）\",\n    \"stem_start\": \"ステム開始\",\n    \"stem_end\": \"ステム終了\",\n    \"autogen_label\": \"自動生成\",\n    \"caption_rewrite_label\": \"キャプション書き換え\",\n    \"caption_rewrite_info\": \"生成前にLMでキャプションを書き換え。\",\n    \"auto_label\": \"自動\",\n    \"bpm_auto_label\": \"BPM 自動\",\n    \"key_auto_label\": \"キー 自動\",\n    \"timesig_auto_label\": \"拍子 自動\",\n    \"vocal_lang_auto_label\": \"言語 自動\",\n    \"duration_auto_label\": \"長さ 自動\",\n    \"reset_all_auto\": \"🔄 すべて自動にリセット\",\n    \"advanced_dit_params\": \"DiT 詳細パラメータ\"\n  },\n  \"results\": {\n    \"title\": \"🎵 結果\",\n    \"generated_music\": \"🎵 生成された音楽(サンプル {n})\",\n    \"send_to_remix_btn\": \"🔗 リミックスに送信\",\n    \"send_to_repaint_btn\": \"🔗 リペイントに送信\",\n    \"save_btn\": \"💾 保存\",\n    \"score_btn\": \"📊 スコア取得\",\n    \"lrc_btn\": \"🎵 LRC 取得\",\n    \"save_lrc_btn\": \"💾 LRC 保存\",\n    \"convert_to_codes_btn\": \"🔄 コードに変換\",\n    \"quality_score_label\": \"品質スコア(サンプル {n})\",\n    \"quality_score_placeholder\": \"'スコア'をクリックしてパープレキシティベースの品質スコアを計算\",\n    \"codes_label\": \"LM コード(サンプル {n})\",\n    \"lrc_label\": \"歌詞タイムスタンプ(サンプル {n})\",\n    \"lrc_placeholder\": \"'LRC'をクリックしてタイムスタンプを生成\",\n    \"details_accordion\": \"📊 スコア & LRC & LM コード\",\n    \"generation_status\": \"生成ステータス\",\n    \"current_batch\": \"現在のバッチ\",\n    \"batch_indicator\": \"バッチ {current} / {total}\",\n    \"next_batch_status\": \"次のバッチステータス\",\n    \"prev_btn\": \"◀ 前へ\",\n    \"next_btn\": \"次へ ▶\",\n    \"restore_params_btn\": \"↙️ これらの設定をUIに適用(バッチパラメータを復元)\",\n    \"batch_results_title\": \"👇 クリックしてバッチ結果と生成詳細を表示\",\n    \"all_files_label\": \"📁 すべての生成ファイル(ダウンロード)\",\n    \"generation_details\": \"生成詳細\"\n  },\n  \"messages\": {\n    \"no_audio_to_save\": \"❌ 保存するオーディオがありません\",\n    \"save_success\": \"✅ オーディオとメタデータを {filename} に保存しました\",\n    \"save_failed\": \"❌ 保存に失敗しました: {error}\",\n    \"no_file_selected\": \"⚠️ ファイルが選択されていません\",\n    \"params_loaded\": \"✅ {filename} からパラメータを読み込みました\",\n    \"invalid_json\": \"❌ 無効なJSONファイル: {error}\",\n    \"load_error\": \"❌ ファイルの読み込みエラー: {error}\",\n    \"example_loaded\": \"📁 {filename} からサンプルを読み込みました\",\n    \"example_failed\": \"JSONファイル {filename} の解析に失敗しました: {error}\",\n    \"example_error\": \"サンプル読み込みエラー: {error}\",\n    \"lm_generated\": \"🤖 LMを使用してサンプルを生成しました\",\n    \"lm_fallback\": \"LMを使用したサンプル生成に失敗、サンプルディレクトリにフォールバック\",\n    \"lm_not_initialized\": \"❌ 5Hz LMが初期化されていません。最初に初期化してください。\",\n    \"think_requires_lm\": \"⚠️ 「Think」機能には5Hz LMの初期化が必要です。Thinkは無効化されました — LM思考なしで生成を続行します。\",\n    \"autogen_enabled\": \"🔄 自動生成が有効 - このあと次のバッチを生成します\",\n    \"batch_ready\": \"✅ バッチ {n} の準備完了！'次へ'をクリックして表示。\",\n    \"batch_generating\": \"🔄 バッチ {n} のバックグラウンド生成を開始.\",\n    \"batch_failed\": \"❌ バックグラウンド生成に失敗しました: {error}\",\n    \"viewing_batch\": \"✅ バッチ {n} を表示中\",\n    \"at_first_batch\": \"すでに最初のバッチです\",\n    \"at_last_batch\": \"次のバッチはありません\",\n    \"batch_not_found\": \"キューにバッチ {n} が見つかりません\",\n    \"no_batch_data\": \"復元するバッチデータがありません。\",\n    \"params_restored\": \"✅ バッチ {n} からUIパラメータを復元しました\",\n    \"scoring_failed\": \"❌ エラー: バッチデータが見つかりません\",\n    \"no_codes\": \"❌ 利用可能なオーディオコードがありません。最初に音楽を生成してください。\",\n    \"score_failed\": \"❌ スコアリングに失敗しました: {error}\",\n    \"score_error\": \"❌ スコア計算エラー: {error}\",\n    \"lrc_no_batch_data\": \"❌ バッチデータが見つかりません。最初に音楽を生成してください。\",\n    \"lrc_no_extra_outputs\": \"❌ 追加出力が見つかりません。条件テンソルが利用できません。\",\n    \"lrc_missing_tensors\": \"❌ LRC生成に必要なテンソルがありません。\",\n    \"lrc_sample_not_exist\": \"❌ 現在のバッチにサンプルが存在しません。\",\n    \"lrc_empty_result\": \"⚠️ LRC生成の結果が空です。\",\n    \"empty_query\": \"⚠️ 音楽の説明を入力してください。\",\n    \"sample_creation_failed\": \"❌ サンプルの作成に失敗しました。もう一度お試しください。\",\n    \"sample_created\": \"✅ サンプルが作成されました！キャプションと歌詞を確認して、音楽を生成をクリックしてください。\",\n    \"simple_examples_not_found\": \"⚠️ シンプルモードサンプルディレクトリが見つかりません。\",\n    \"simple_examples_empty\": \"⚠️ シンプルモードサンプルにファイルがありません。\",\n    \"simple_example_loaded\": \"🎲 {filename} からランダムサンプルを読み込みました\",\n    \"format_success\": \"✅ キャプションと歌詞のフォーマットに成功しました\",\n    \"format_failed\": \"❌ フォーマットに失敗しました: {error}\",\n    \"skipping_metas_cot\": \"⚡ Phase 1 メタデータ COT をスキップ（サンプルは既にフォーマット済み）\",\n    \"invalid_timesteps_format\": \"⚠️ タイムステップ形式が無効です。デフォルトスケジュールを使用します。\",\n    \"timesteps_out_of_range\": \"⚠️ タイムステップは [0, 1] の範囲内である必要があります。デフォルトスケジュールを使用します。\",\n    \"timesteps_count_mismatch\": \"⚠️ タイムステップ数 ({actual}) が推論ステップ数 ({expected}) と異なります。タイムステップ数を使用します。\"\n  },\n  \"training\": {\n    \"tab_title\": \"🎓 LoRA トレーニング\",\n    \"tab_dataset_builder\": \"📁 データセットビルダー\",\n    \"tab_train_lora\": \"🚀 LoRA をトレーニング\",\n    \"quick_start_title\": \"🚀 クイックスタート\",\n    \"load_dataset_label\": \"データセット JSON パス\",\n    \"load_dataset_info\": \"以前保存したデータセットを読み込む。\",\n    \"load_btn\": \"📂 読み込み\",\n    \"load_status\": \"読み込み状態\",\n    \"scan_label\": \"オーディオディレクトリパス\",\n    \"scan_info\": \"オーディオファイルをスキャン（wav、mp3、flac、ogg、opus）。\",\n    \"scan_btn\": \"🔍 スキャン\",\n    \"scan_status\": \"スキャン状態\",\n    \"found_audio_files\": \"見つかったオーディオファイル\",\n    \"dataset_name\": \"データセット名\",\n    \"dataset_name_placeholder\": \"データセット名を入力\",\n    \"dataset_settings_header\": \"データセット設定\",\n    \"tag_prepend\": \"前置（タグ、キャプション）\",\n    \"tag_append\": \"後置（キャプション、タグ）\",\n    \"tag_replace\": \"キャプションを置換\",\n    \"step2_title\": \"ステップ 2: AI で自動ラベル\",\n    \"step2_instruction\": \"以下のボタンをクリックして、AI を使用してすべてのオーディオファイルのメタデータを自動生成します：\\n- **キャプション**：音楽スタイル、ジャンル、ムードの説明\\n- **BPM**：1分間あたりのビート数\\n- **キー**：音楽キー（例：C Major、Am）\\n- **拍子記号**：4/4、3/4 など。\",\n    \"step3_title\": \"ステップ 3: プレビューと編集\",\n    \"step4_title\": \"ステップ 4: データセットを保存\",\n    \"step5_title\": \"ステップ 5: テンソルに前処理\",\n    \"step5_intro\": \"**前処理により、データセットを高速トレーニング用の事前計算されたテンソルに変換します。**\\n\\n次のいずれかを選択できます：\\n- 上記のステップ 1-4 のデータセットを使用する、**または**\\n- 既存のデータセット JSON ファイルを読み込む（既に保存している場合）\",\n    \"step5_details\": \"このステップ：\\n- オーディオを VAE 潜在変数にエンコード\\n- キャプションと歌詞をテキスト埋め込みにエンコード\\n- 条件エンコーダーを実行\\n- すべてのテンソルを `.pt` ファイルに保存\\n\\n⚠️ **これにはモデルの読み込みが必要で、数分かかる場合があります。**\",\n    \"train_tensor_selection_desc\": \"前処理されたテンソルファイル（`.pt` ファイル）を含むディレクトリを選択します。\\nこれらは「データセットビルダー」タブの「前処理」ボタンを使用して作成されます。\",\n    \"all_instrumental\": \"すべてインストゥルメンタル\",\n    \"all_instrumental_info\": \"すべてのトラックがインストゥルメンタル（ボーカルなし）の場合にチェック。\",\n    \"custom_tag\": \"カスタムアクティベーションタグ\",\n    \"custom_tag_info\": \"この LoRA のスタイルを有効にする一意のタグ。\",\n    \"tag_position\": \"タグの位置\",\n    \"tag_position_info\": \"キャプション内でカスタムタグを配置する位置。\",\n    \"genre_ratio\": \"ジャンル比率 (%)\",\n    \"genre_ratio_info\": \"0%=すべてキャプション、100%=すべてジャンル。サンプル単位の上書きが優先。\",\n    \"skip_metas\": \"BPM/キー/拍子をスキップ\",\n    \"skip_metas_info\": \"BPM/キー/拍子の生成をスキップ。キャプションとジャンルは LM が生成。\",\n    \"only_unlabeled\": \"未ラベルのみ\",\n    \"only_unlabeled_info\": \"キャプションのないサンプルのみラベル付け（失敗したラベル付けの再開に便利）。\",\n    \"auto_label_btn\": \"🏷️ 一括自動ラベル\",\n    \"label_progress\": \"ラベル付け進捗\",\n    \"select_sample\": \"サンプル # を選択\",\n    \"select_sample_info\": \"プレビューと編集するサンプルを選択。\",\n    \"audio_preview\": \"オーディオプレビュー\",\n    \"filename\": \"ファイル名\",\n    \"caption\": \"キャプション\",\n    \"genre\": \"ジャンル\",\n    \"prompt_override_label\": \"プロンプト上書き（このサンプル）\",\n    \"prompt_override_info\": \"このサンプルのグローバル比率を上書き。\",\n    \"lyrics_editable_label\": \"歌詞（編集可、トレーニング用）\",\n    \"raw_lyrics_label\": \"生歌詞（.txt ファイルから）\",\n    \"no_lyrics_placeholder\": \"（.txt 歌詞ファイルなし）\",\n    \"bpm\": \"BPM\",\n    \"key_label\": \"キー\",\n    \"key_placeholder\": \"C Major\",\n    \"time_sig\": \"拍子\",\n    \"duration_s\": \"長さ (秒)\",\n    \"language\": \"言語\",\n    \"instrumental\": \"インストゥルメンタル\",\n    \"save_changes_btn\": \"💾 変更を保存\",\n    \"edit_status\": \"編集状態\",\n    \"save_path\": \"保存パス\",\n    \"save_path_info\": \"データセット JSON の保存先パス。\",\n    \"save_dataset_btn\": \"💾 データセットを保存\",\n    \"save_status\": \"保存状態\",\n    \"load_existing_label\": \"既存データセットを読み込み\",\n    \"load_existing_info\": \"以前保存したデータセット JSON ファイルのパス。\",\n    \"load_dataset_btn\": \"📂 データセットを読み込み\",\n    \"tensor_output_dir\": \"テンソル出力ディレクトリ\",\n    \"tensor_output_info\": \"前処理済みテンソルファイルの保存先ディレクトリ。\",\n    \"preprocess_btn\": \"⚡ 前処理\",\n    \"preprocess_progress\": \"前処理進捗\",\n    \"preprocessed_tensors_dir\": \"前処理済みテンソルディレクトリ\",\n    \"preprocessed_tensors_info\": \"前処理済み .pt テンソルファイルを含むディレクトリ。\",\n    \"train_section_tensors\": \"前処理済みデータセット選択\",\n    \"train_section_lora\": \"LoRA 設定\",\n    \"train_section_params\": \"トレーニングパラメータ\",\n    \"dataset_info\": \"データセット情報。\",\n    \"lora_rank\": \"LoRA ランク (r)\",\n    \"lora_rank_info\": \"高いほど容量は増えるがメモリ使用量も増加。\",\n    \"lora_alpha\": \"LoRA Alpha\",\n    \"lora_alpha_info\": \"スケーリング係数（通常はランクの2倍）。\",\n    \"lora_dropout\": \"LoRA Dropout\",\n    \"learning_rate\": \"学習率\",\n    \"learning_rate_info\": \"3e-4 から始め、必要に応じて調整。\",\n    \"max_epochs\": \"最大エポック数\",\n    \"batch_size\": \"バッチサイズ\",\n    \"batch_size_info\": \"VRAM に余裕があれば増やせます。\",\n    \"gradient_accumulation\": \"勾配累積\",\n    \"gradient_accumulation_info\": \"実効バッチ = batch_size × 累積。\",\n    \"save_every_n_epochs\": \"N エポックごとに保存\",\n    \"shift\": \"Shift\",\n    \"shift_info\": \"ターボモデル用タイムステップシフト。\",\n    \"seed\": \"シード\",\n    \"output_dir\": \"出力ディレクトリ\",\n    \"output_dir_info\": \"トレーニング済み LoRA 重みの保存先ディレクトリ。\",\n    \"start_training_btn\": \"🚀 トレーニング開始\",\n    \"stop_training_btn\": \"⏹️ トレーニング停止\",\n    \"training_progress\": \"トレーニング進捗\",\n    \"training_log\": \"トレーニングログ\",\n    \"training_loss_title\": \"トレーニング損失\",\n    \"step\": \"ステップ\",\n    \"loss\": \"損失\",\n    \"export_header\": \"LoRA をエクスポート\",\n    \"export_path\": \"エクスポートパス\",\n    \"export_lora_btn\": \"📦 LoRA をエクスポート\",\n    \"export_status\": \"エクスポート状態\",\n    \"stop_no_training\": \"ℹ トレーニングは実行されていません\",\n    \"stop_stopping\": \"⏹️ トレーニングを停止中...\",\n    \"latest_auto\": \"最新（自動）\",\n    \"export_path_required\": \"❌ エクスポートパスを入力してください\",\n    \"invalid_lora_output_dir\": \"❌ 無効なLoRA出力ディレクトリ\",\n    \"no_checkpoints_found\": \"❌ チェックポイントが見つかりません\",\n    \"no_trained_model_found\": \"❌ {path} にトレーニング済みモデルが見つかりません\",\n    \"invalid_export_path\": \"❌ 無効なエクスポートパス\",\n    \"lora_exported\": \"✅ LoRA を {path} にエクスポートしました\",\n    \"export_failed\": \"❌ エクスポートに失敗しました: {error}\",\n    \"lokr_output_dir_required\": \"⚠️ 最初にLoKr出力ディレクトリを入力してください\",\n    \"lokr_no_checkpoints_use_latest\": \"ℹ チェックポイントが見つかりません。エクスポートには最新の利用可能な重みが使用されます\",\n    \"lokr_no_exportable_checkpoints\": \"ℹ エクスポート可能なエポックチェックポイントが見つかりません\",\n    \"lokr_found_checkpoints\": \"✅ {count} 個のLoKrチェックポイントが見つかりました\",\n    \"lokr_selected_epoch_not_found\": \"❌ 選択したエポックが見つかりません: {chosen}。利用可能: {available}\",\n    \"lokr_no_weights_selected_epoch\": \"❌ 選択したエポック {epoch} にLoKr重みが見つかりません\",\n    \"lokr_no_weights_latest_checkpoint\": \"❌ 最新チェックポイント {checkpoint} にLoKr重みが見つかりません\",\n    \"lokr_no_trained_weights_found\": \"❌ {path} にトレーニング済みLoKr重みが見つかりません\",\n    \"lokr_exported\": \"✅ LoKr を {path} にエクスポートしました\",\n    \"tab_train_lokr\": \"🚀 LoKr をトレーニング\",\n    \"lokr_section_tensors\": \"前処理済みデータセット選択\",\n    \"lokr_section_settings\": \"LoKr 設定\",\n    \"lokr_tensor_selection_desc\": \"前処理されたテンソルファイル（`.pt` ファイル）を含むディレクトリを選択します。\\nこれらは「データセットビルダー」タブの「前処理」ボタンを使用して作成されます。\",\n    \"lokr_linear_dim\": \"LoKr Linear Dim\",\n    \"lokr_linear_dim_info\": \"Rank (dimension) for LoKr adaptation matrices.\",\n    \"lokr_linear_alpha\": \"LoKr Linear Alpha\",\n    \"lokr_linear_alpha_info\": \"Scaling factor for LoKr (usually similar to dim).\",\n    \"lokr_factor\": \"LoKr Factor\",\n    \"lokr_factor_info\": \"Kronecker factor (-1 for auto).\",\n    \"lokr_decompose_both\": \"Decompose Both Sides\",\n    \"lokr_decompose_both_info\": \"When enabled, decomposes both left and right matrices.\",\n    \"lokr_use_tucker\": \"Use Tucker Decomposition\",\n    \"lokr_use_tucker_info\": \"Apply Tucker decomposition when applicable.\",\n    \"lokr_use_scalar\": \"Use Scalar Gate\",\n    \"lokr_use_scalar_info\": \"Enable scalar gating for LoKr weights.\",\n    \"lokr_weight_decompose\": \"Weight Decompose (WD)\",\n    \"lokr_weight_decompose_info\": \"Enable weight decomposition for more stable LoKr training.\",\n    \"lokr_learning_rate_info\": \"LoKr commonly uses a higher LR than LoRA. Tune per dataset.\",\n    \"lokr_output_dir_info\": \"トレーニング済み LoKr 重みの保存先ディレクトリ。\",\n    \"start_lokr_training_btn\": \"🚀 トレーニング開始 LoKr\",\n    \"lokr_training_loss_title\": \"LoKr トレーニング損失\",\n    \"lokr_export_header\": \"LoKr をエクスポート\",\n    \"export_lokr_btn\": \"📦 LoKr をエクスポート\",\n    \"lokr_checkpoint_epoch\": \"Checkpoint Epoch\",\n    \"lokr_checkpoint_epoch_info\": \"Select a specific epoch checkpoint to export, or keep Latest (auto).\",\n    \"refresh_epochs_btn\": \"↻ 更新 Epochs\"\n  },\n  \"help\": {\n    \"btn_label\": \"?\",\n    \"close_label\": \"✕\",\n    \"getting_started\": \"## はじめに\\n\\n1. 設定アコーディオンで**モデルを選択**（例：`acestep-v15-turbo`）\\n2. Thinkingモードを使うなら**5Hz LMを選択**（推奨）\\n3. **サービスを初期化**をクリックし、緑色のステータスを待つ\\n4. **生成モード**を選択（Simpleから始めましょう）\\n5. 音楽を説明して**音楽を生成**をクリック\\n\\n> **ヒント：** Turboモデルが最速です。「Think」を有効にするとよりスマートな生成が可能です。\",\n    \"service_config\": \"## サービス設定\\n\\n### クイックセットアップ\\n1. **メインモデルパス**を選択（turbo推奨）\\n2. **5Hz LMモデルパス**を選択（GPUに応じて自動フィルタ）\\n3. **バックエンド**を選択：`vllm`（高速、NVIDIA ≥8GB）または`pt`（汎用）\\n4. Thinkingモード用に**5Hz LMを初期化**をチェック\\n5. **サービスを初期化**をクリック\\n\\n### パフォーマンスのヒント\\n- **Flash Attention**：高速推論（flash_attn必要）\\n- **CPUオフロード**：GPU <20GBで自動有効\\n- **INT8量子化**：VRAM削減、<20GBで自動有効\\n- **コンパイル**：量子化に必要、デフォルト有効\\n\\n### LoRA\\n- LoRAパスを設定 → 読み込み → 「LoRAを使用」を有効化\\n- ⚠️ INT8量子化ではLoRAを使用できません\",\n    \"generation_simple\": \"## Simpleモードチュートリアル\\n\\n**最適：** 最小限の操作で素早い音楽制作。\\n\\n### 手順\\n1. 生成モードで**Simple**を選択\\n2. 説明を入力、例：*「キャッチーなギターリフのあるアップビートなポップソング」*\\n3. （オプション）ボーカル不要なら**インストゥルメンタル**をチェック\\n4. （オプション）**ボーカル言語**を選択\\n5. **サンプルを作成**をクリック — AIがキャプション、歌詞、メタデータを生成\\n6. 生成されたコンテンツを確認・編集\\n7. **音楽を生成**をクリック\\n\\n### ヒント\\n- 🎲をクリックしてランダムなインスピレーション\\n- 説明が具体的なほど結果が良くなる\\n- BPM/キーを空にしてAIに任せる\",\n    \"generation_custom\": \"## Customモードチュートリアル\\n\\n**最適：** すべてのパラメータを完全にコントロール。\\n\\n### 手順\\n1. 生成モードで**Custom**を選択\\n2. 詳細な**キャプション**を記述（スタイル、ジャンル、楽器、ムード）\\n3. 構造タグ付きの**歌詞**を記述：`[Verse]`、`[Chorus]`、`[Bridge]`\\n4. （オプション）スタイルガイダンス用に**リファレンスオーディオ**をアップロード\\n5. **BPM**、**キー**、**Duration**を設定、または空で自動\\n6. **フォーマット**をクリックしてLMで強化（オプション）\\n7. **音楽を生成**をクリック\\n\\n### キャプションのコツ\\n- 具体的に：*「リバーブの効いたギターとささやくようなボーカルのドリーミーなシューゲイザー」*\\n- 含めるもの：ジャンル、楽器、ムード、テンポ感、ボーカルスタイル\",\n    \"generation_remix\": \"## Remixモードチュートリアル\\n\\n**最適：** カバーバージョンやスタイル転送の作成。\\n\\n### 手順\\n1. 生成モードで**Remix**を選択\\n2. **ソースオーディオ**をアップロード（リミックスする曲）\\n3. ターゲットスタイルを説明する**キャプション**を記述\\n4. （オプション）**歌詞**を修正\\n5. **Remix強度**（0.0–1.0）を調整：\\n   - 高い = 元の構造に近い\\n   - 低い = より創造的な自由\\n6. **音楽を生成**をクリック\\n\\n### ヒント\\n- 強度0.5から始めて調整\\n- メロディ保持にはSFTモデルでカバー強度0.1–0.25を使用\",\n    \"generation_repaint\": \"## Repaintモードチュートリアル\\n\\n**最適：** 生成された音楽の特定セクションを修正・再生成し、残りの部分を維持。\\n\\n### 手順\\n1. 生成モードで**Repaint**を選択\\n2. **ソースオーディオ**をアップロード\\n3. **再描画開始**（秒）と**終了**（-1でファイル終端）を設定\\n4. 再描画セクションの内容を説明する**キャプション**を記述\\n5. **Repaint Mode**を選択し、必要に応じて**Repaint Strength**を調整\\n6. **音楽を生成**をクリック\\n\\n### Repaint Mode（リペイントモード）\\n非リペイント領域のモデルの扱い方を制御：\\n\\n- **Conservative**（Strength = 0）：ソースを最大限保持。毎ステップでソースlatentを注入し、長い境界クロスフェードを適用。シームレスな接続に最適。\\n- **Balanced**（デフォルト）：Repaint Strengthスライダーで制御される一部の拡散ステップでソースlatentを注入。推奨の出発点。\\n- **Aggressive**（Strength = 1）：ソース注入なし。純粋な拡散生成。最大の創造的自由度だが境界の一貫性は最低。\\n\\n### Repaint Strength（リペイント強度）\\n**Balanced**モードでのみ有効。保持と再生成のバランスを制御：\\n- **0** = 保守的動作（自動的にConservativeモードへ切替）\\n- **0.5** = デフォルト — 最初の50%のステップでソースを注入\\n- **1** = 積極的動作（自動的にAggressiveモードへ切替）\\n\\n### ヒント\\n- 結果から「リペイントに送信」を使って素早くオーディオを読み込む\\n- まずBalanced (0.5)で試し、結果に応じて調整\\n- Strengthを下げると境界の接続性が向上、上げると創造的出力が増加\",\n    \"generation_extract\": \"## Extractモード（Baseモデルのみ）\\n\\n**最適：** ステム分離 — ミックスから楽器を分離。\\n\\n### 手順\\n1. 生成モードで**Extract**を選択\\n2. **ソースオーディオ**をアップロード\\n3. 抽出する**トラック名**を選択（例：vocals、drums、bass）\\n4. **ステム抽出**をクリック\\n\\n### 利用可能なトラック\\nvocals、backing_vocals、drums、bass、guitar、keyboard、percussion、strings、synth、fx、brass、woodwinds\",\n    \"generation_lego\": \"## Legoモード（Baseモデルのみ）\\n\\n**最適：** 既存のオーディオに新しい楽器トラックを追加。\\n\\n### 手順\\n1. 生成モードで**Lego**を選択\\n2. **ソースオーディオ**をアップロード\\n3. 追加する**トラック名**を選択\\n4. トラックを説明する**キャプション**を記述\\n5. **ステム追加**をクリック\\n\\n### ヒント\\n- レイヤリングに最適：ギタートラックにドラムを追加、ボーカルにベースを追加\\n- キャプションは新しいトラックの特徴のみを説明\",\n    \"generation_complete\": \"## Completeモード（Baseモデルのみ）\\n\\n**最適：** 自動アレンジ — 欠落している楽器を補完。\\n\\n### 手順\\n1. 生成モードで**Complete**を選択\\n2. **ソースオーディオ**をアップロード（部分的なアレンジ）\\n3. 追加する複数の**トラック名**を選択\\n4. 希望するスタイルを説明する**キャプション**を記述\\n5. **音楽を生成**をクリック\",\n    \"generation_caption\": \"## 良いキャプションの書き方\\n\\n### 構造\\n良いキャプションに含めるもの：\\n- **ジャンル/スタイル**：pop、rock、jazz、electronic、classical…\\n- **楽器**：guitar、piano、synth、drums、strings…\\n- **ムード**：upbeat、melancholic、energetic、dreamy…\\n- **ボーカルスタイル**：whispered、powerful、falsetto、rap…\\n- **テンポ感**：fast、slow、moderate、driving…\\n\\n### 例\\n- *「ディストーションギター、速いドラム、叫ぶボーカルのエネルギッシュなポップパンク」*\\n- *「ウォーキングベース、ブラシドラム、メロウなピアノのスムースジャズトリオ」*\\n- *「レイヤードシンセパッドとボーカルなしのアンビエントエレクトロニカ」*\\n\\n### ヒント\\n- 詳細 = より良い結果\\n- **フォーマット**ボタンでAIにキャプションを強化させる\\n- 🎲でキャプション例を確認\",\n    \"generation_lyrics\": \"## 歌詞の書き方\\n\\n### 構造タグ\\nセクションタグで曲を構成：\\n```\\n[Verse 1]\\nバースの歌詞をここに\\n\\n[Chorus]\\nコーラスの歌詞をここに\\n\\n[Verse 2]\\n2番のバース\\n\\n[Bridge]\\nブリッジセクション\\n\\n[Outro]\\nエンディングの歌詞\\n```\\n\\n### ヒント\\n- バースは4–8行\\n- コーラスは記憶に残りやすく反復的に\\n- ボーカルなしセクションには `[Instrumental]` や `[Interlude]` を使用\\n- 純粋なインストゥルメンタルには**インストゥルメンタル**チェックボックス\\n- 歌詞の言語に合わせて**ボーカル言語**を選択\",\n    \"generation_advanced\": \"## 高度な設定\\n\\n### 主要パラメータ\\n- **推論ステップ**：Turbo=8（デフォルト）、Base=最大200。turboでは多いステップ≠常に良い\\n- **ガイダンススケール**：Baseモデルのみ。高い = プロンプトにより忠実\\n- **シフト**：タイムステップシフト（1.0–5.0）。turboには3.0推奨\\n- **シード**：特定のシードで再現可能な結果\\n\\n### LMパラメータ\\n- **温度**（0.0–2.0）：高い = より創造的/ランダム\\n- **CFGスケール**（1.0–3.0）：高い = プロンプトにより忠実\\n- **Top-K / Top-P**：多様性のサンプリング戦略\\n\\n### Thinkモード\\n**Think**を有効にして5Hz LMでスマートな生成：\\n- セマンティックコードとメタデータを生成\\n- LMの初期化が必要\\n- **並列思考**：バッチを並列処理（高速）\",\n    \"results\": \"## 結果セクション\\n\\n### サンプルごとのコントロール\\n- **オーディオプレーヤー**：再生、一時停止、ダウンロード\\n- **リミックス/リペイントに送信**：この結果をソースとして更に編集\\n- **保存**：オーディオ + メタデータをJSONでエクスポート\\n- **スコア**：品質スコアを計算（パープレキシティベース）\\n- **LRC**：歌詞タイムスタンプを生成\\n\\n### バッチナビゲーション\\n- **◀ 前へ** / **次へ ▶** でバッチを閲覧\\n- **自動生成**を有効にして次のバッチを自動生成\\n- **これらの設定をUIに適用**をクリックして良い結果のパラメータを再利用\\n\\n### ヒント\\n- 2–4個のバリエーション（バッチサイズ）を生成して最良を選択\\n- スコアで客観的に結果を比較\\n- 良い結果を参考用に保存\",\n    \"training_dataset\": \"## データセットビルダーチュートリアル\\n\\n### ステップ1：読み込みまたはスキャン\\n- **読み込み**：既存のデータセットJSONパスを入力 → 読み込みをクリック\\n- **スキャン**：オーディオフォルダパスを入力 → スキャンをクリック\\n  - 対応：wav、mp3、flac、ogg、opus\\n\\n### ステップ2：設定\\n- **データセット名**を設定\\n- ボーカルなしなら**すべてインストゥルメンタル**をチェック\\n- **カスタムアクティベーションタグ**を設定（LoRAのユニークなトリガーワード）\\n- **タグの位置**を選択：前置、後置、または置換\\n\\n### ステップ3：自動ラベル\\n- **一括自動ラベル**をクリックしてキャプション、BPM、キー、拍子を生成\\n- **メタをスキップ**でBPM/キー/拍子をスキップ（高速）\\n\\n### ステップ4：プレビューと編集\\n- スライダーでサンプルを閲覧\\n- キャプション、歌詞、BPM、キーを手動編集\\n- サンプルごとに**変更を保存**をクリック\\n\\n### ステップ5：保存\\n- 保存パスを入力 → **データセットを保存**をクリック\\n\\n### ステップ6：前処理\\n- テンソル出力ディレクトリを設定 → **前処理**をクリック\\n- オーディオ/テキストをトレーニング用テンソルにエンコード\\n\\n### 📖 ドキュメント\\n- [LoRA トレーニングチュートリアル](https://github.com/ACE-Step/ACE-Step-1.5/blob/main/docs/ja/LoRA_Training_Tutorial.md) — 完全なステップバイステップガイド\\n- [Side-Step 高度なトレーニング](https://github.com/ACE-Step/ACE-Step-1.5/blob/main/docs/sidestep/Getting%20Started.md) — CLIベースのトレーニング、高度な機能付き\",\n    \"training_train\": \"## LoRAトレーニングチュートリアル\\n\\n### セットアップ\\n1. **前処理済みテンソルディレクトリ**を入力 → **データセットを読み込み**をクリック\\n2. LoRAを設定：\\n   - **ランク** (r)：デフォルト64。高い = より大きな容量\\n   - **Alpha**：通常はランクの2倍（128）\\n   - **Dropout**：正則化に0.1\\n\\n### トレーニング\\n3. **学習率**を設定（1e-4から開始）\\n4. **最大エポック数**を設定（デフォルト500）\\n5. **トレーニング開始**をクリック\\n6. 損失曲線を監視 — 時間とともに減少するはず\\n7. 満足したら**トレーニング停止**をクリック\\n\\n### エクスポート\\n8. エクスポートパスを入力 → **LoRAをエクスポート**をクリック\\n9. 設定で読み込み：LoRAパスを設定 → LoRAを読み込み → LoRAを使用を有効化\\n\\n### 🚀 LoKr で高速トレーニング\\nLoKr はトレーニング効率を大幅に向上させました。以前は1時間かかっていたトレーニングが、わずか5分で完了します——**10倍以上の高速化**。コンシューマーGPUでのトレーニングに最適です。**Train LoKr** タブに切り替えて始めましょう。\\n\\n### ヒント\\n- VRAMが限られている場合は小さいバッチサイズ（1）を使用\\n- 勾配累積で実効バッチサイズを増加\\n- チェックポイントを頻繁に保存（200エポックごと）\\n\\n### 📖 ドキュメント\\n- [LoRA トレーニングチュートリアル](https://github.com/ACE-Step/ACE-Step-1.5/blob/main/docs/ja/LoRA_Training_Tutorial.md) — 完全なステップバイステップガイド\\n- [Side-Step 高度なトレーニング](https://github.com/ACE-Step/ACE-Step-1.5/blob/main/docs/sidestep/Getting%20Started.md) — CLIトレーニング、修正タイムステップ、LoKR、VRAM最適化\",\n    \"training_lokr\": \"## 🚀 LoKr トレーニングチュートリアル\\n\\nLoKr（低ランククロネッカー積）はトレーニング効率を大幅に向上させました。LoRAで1時間かかっていたトレーニングが、わずか5分で完了します——**10倍以上の高速化**。コンシューマーGPUでのトレーニングに最適です。\\n\\n### セットアップ\\n1. **前処理済みテンソルディレクトリ**を入力 → **データセットを読み込み**をクリック\\n2. LoKrを設定：\\n   - **Linear Dim**：デフォルト64（LoRAのランクに相当）\\n   - **Linear Alpha**：デフォルト128（スケーリング係数）\\n   - **Weight Decompose (DoRA)**：デフォルト有効、品質向上\\n\\n### トレーニング\\n3. **学習率**を設定（LoKrは通常より高いLRを使用、1e-3から開始）\\n4. **最大エポック数**を設定（デフォルト500）\\n5. **LoKrトレーニング開始**をクリック\\n6. 損失曲線を監視 — 時間とともに減少するはず\\n7. 満足したら**トレーニング停止**をクリック\\n\\n### エクスポート\\n8. エクスポートパスを入力 → **LoKrをエクスポート**をクリック\\n9. 設定で読み込み：LoRAパスを設定 → LoRAを読み込み → LoRAを使用を有効化\\n\\n### LoKr vs LoRA 比較\\n| | LoKr | LoRA |\\n|---|---|---|\\n| 速度 | ⚡ 約10倍高速 | 遅い |\\n| VRAM | 少ない | 多い |\\n| 品質 | 同等 | 基準 |\\n| 最適 | コンシューマーGPU、高速反復 | 最高忠実度 |\\n\\n### ヒント\\n- LoKrはクロネッカー分解で極限の効率を実現\\n- **DoRA**（Weight Decompose）を有効にして品質向上\\n- **Tucker分解**でさらなる圧縮が可能\\n- 高い学習率（1e-3）がLoRAの典型的な1e-4より効果的\",\n    \"training_export\": \"## トレーニング済みLoRAの使用\\n\\n### エクスポート\\n1. トレーニング後、エクスポートパスを入力\\n2. **LoRAをエクスポート**をクリック\\n\\n### 読み込みと使用\\n1. 設定で**LoRAパス**をエクスポートディレクトリに設定\\n2. **LoRAを読み込み**をクリック\\n3. **LoRAを使用**チェックボックスを有効化\\n4. 音楽を生成 — LoRAスタイルが適用されます\\n\\n### ヒント\\n- キャプションに**カスタムアクティベーションタグ**を使用してスタイルをトリガー\\n- ⚠️ LoRAはINT8量子化と互換性がありません\\n- 異なるLoRA間でアンロードと切り替えが可能\"\n  },\n  \"gen\": {\n    \"enable_normalization\": \"ノーマライズを有効にする\",\n    \"enable_normalization_info\": \"クリッピングを防ぎ、ラウドネスを一定にするために、オーディオ音量をターゲットピークレベルに正規化します。\",\n    \"normalization_db\": \"ターゲットピーク (dB)\",\n    \"normalization_db_info\": \"デシベル単位のターゲットピークレベル。-1.0 dBが標準的な安全ピークです。-0.1 dBが最大です。\",\n    \"advanced_dit_params\": \"DiT 詳細パラメータ\",\n    \"latent_shift\": \"Latent シフト\",\n    \"latent_shift_info\": \"VAEデコード前にDiT latentに適用するシフト量。デフォルト0（シフトなし）。負の値（例: -0.04）でクリッピングを軽減できます。\",\n    \"latent_rescale\": \"Latent リスケール\",\n    \"latent_rescale_info\": \"VAEデコード前にDiT latentに適用するスケール係数。デフォルト1.0（スケーリングなし）。1.0未満の値（例: 0.91）でクリッピングを軽減できます。\"\n  }\n}\n"
  },
  {
    "path": "acestep/ui/gradio/i18n/zh.json",
    "content": "{\n  \"app\": {\n    \"title\": \"🎛️ ACE-Step V1.5 游乐场💡\",\n    \"subtitle\": \"推动开源音乐生成的边界\"\n  },\n  \"common\": {\n    \"language_metadata\": {\n      \"name\": \"Chinese\",\n      \"native_name\": \"中文\"\n    }\n  },\n  \"dataset\": {\n    \"title\": \"📊 数据集浏览器\",\n    \"dataset_label\": \"数据集\",\n    \"dataset_info\": \"选择要浏览的数据集。\",\n    \"import_btn\": \"📥 导入数据集\",\n    \"search_type_label\": \"搜索类型\",\n    \"search_type_info\": \"如何查找项目。\",\n    \"search_value_label\": \"搜索值\",\n    \"search_value_placeholder\": \"输入键或索引(留空表示随机)\",\n    \"search_value_info\": \"键: 精确匹配, 索引: 0到数据集大小-1。\",\n    \"instruction_label\": \"📝 指令\",\n    \"instruction_placeholder\": \"无可用指令\",\n    \"metadata_title\": \"📋 项目元数据 (JSON)\",\n    \"metadata_label\": \"完整项目信息\",\n    \"source_audio\": \"源音频\",\n    \"target_audio\": \"目标音频\",\n    \"reference_audio\": \"参考音频\",\n    \"get_item_btn\": \"🔍 获取项目\",\n    \"use_src_checkbox\": \"使用数据集中的源音频\",\n    \"use_src_info\": \"勾选以使用数据集中的源音频。\",\n    \"data_status_label\": \"📊 数据状态\",\n    \"data_status_default\": \"❌ 未导入数据集\",\n    \"autofill_btn\": \"📋 自动填充生成表单\"\n  },\n  \"service\": {\n    \"title\": \"🔧 服务配置\",\n    \"checkpoint_label\": \"检查点文件\",\n    \"checkpoint_info\": \"选择训练好的模型检查点文件(完整路径或文件名)。\",\n    \"refresh_btn\": \"🔄 刷新\",\n    \"model_path_label\": \"主模型路径\",\n    \"model_path_info\": \"选择模型配置目录(从检查点自动扫描)。\",\n    \"device_label\": \"设备\",\n    \"device_info\": \"处理设备(建议自动检测)。\",\n    \"lm_model_path_label\": \"5Hz LM 模型路径\",\n    \"lm_model_path_info\": \"选择5Hz LM模型检查点(从检查点自动扫描)。\",\n    \"backend_label\": \"5Hz LM 后端\",\n    \"backend_info\": \"选择5Hz LM的后端: vllm(更快)或pt(PyTorch, 更兼容)。\",\n    \"init_llm_label\": \"初始化 5Hz LM\",\n    \"init_llm_info\": \"勾选以在服务初始化期间初始化5Hz LM。\",\n    \"lm_unavailable_vram\": \"⚠️ 当前GPU档位不支持LM（显存不足）\",\n    \"flash_attention_label\": \"使用Flash Attention\",\n    \"flash_attention_info_enabled\": \"启用flash attention以加快推理速度(需要flash_attn包)\",\n    \"flash_attention_info_disabled\": \"Flash attention不可用(未安装flash_attn包)\",\n    \"offload_cpu_label\": \"闲置时转移到 CPU\",\n    \"offload_cpu_info\": \"不使用时将模型转移到CPU以节省GPU显存。\",\n    \"offload_dit_cpu_label\": \"将DiT转移到CPU\",\n    \"offload_dit_cpu_info\": \"将DiT转移到CPU(需要启用闲置时转移到 CPU)。\",\n    \"compile_model_label\": \"编译模型\",\n    \"compile_model_info\": \"使用 torch.compile 优化模型（量化必需）。\",\n    \"quantization_label\": \"INT8 量化\",\n    \"quantization_info\": \"启用 INT8 仅权重量化以减少显存占用（需要启用编译模型）。\",\n    \"mlx_dit_label\": \"MLX DiT (Apple Silicon)\",\n    \"mlx_dit_info_enabled\": \"使用原生 MLX 加速 DiT 扩散推理（比 MPS 更快）\",\n    \"mlx_dit_info_disabled\": \"MLX 不可用（需要 macOS + Apple Silicon + mlx 包）\",\n    \"init_btn\": \"初始化服务\",\n    \"status_label\": \"状态\",\n    \"language_label\": \"界面语言\",\n    \"language_info\": \"选择界面语言。\",\n    \"gpu_auto_tier\": \"自动检测层级\",\n    \"tier_label\": \"GPU 层级覆盖\",\n    \"tier_info\": \"手动选择 GPU 层级以调整优化默认值（卸载、量化、后端等）。\"\n  },\n  \"generation\": {\n    \"tab_title\": \"🎵 生成\",\n    \"required_inputs\": \"📝 必需输入\",\n    \"task_type_label\": \"任务类型 *\",\n    \"task_type_info\": \"选择生成的任务类型。\",\n    \"instruction_label\": \"指令\",\n    \"instruction_info\": \"指令根据任务类型自动生成。\",\n    \"load_btn\": \"📂 加载\",\n    \"track_name_label\": \"音轨名称\",\n    \"track_name_info\": \"为lego/extract任务选择音轨名称。\",\n    \"track_classes_label\": \"音轨名称\",\n    \"track_classes_info\": \"为complete任务选择多个音轨类别。\",\n    \"audio_uploads\": \"🎵 音频上传\",\n    \"reference_audio\": \"参考音频\",\n    \"source_audio\": \"源音频\",\n    \"convert_codes_btn\": \"转换为代码\",\n    \"analyze_btn\": \"🔍 分析\",\n    \"sample_btn\": \"🎲 试试看\",\n    \"lm_codes_hints\": \"🎼 LM 代码提示\",\n    \"lm_codes_label\": \"LM 代码提示\",\n    \"lm_codes_placeholder\": \"<|audio_code_10695|><|audio_code_54246|>.\",\n    \"lm_codes_info\": \"粘贴用于text2music生成的LM代码提示。\",\n    \"lm_codes_sample\": \"LM 代码提示(样本 {n})\",\n    \"lm_codes_sample_info\": \"样本{n}的代码。\",\n    \"transcribe_btn\": \"转录\",\n    \"repainting_controls\": \"🎨 重绘控制(秒)\",\n    \"repainting_start\": \"重绘开始\",\n    \"repainting_end\": \"重绘结束\",\n    \"mode_label\": \"生成模式 *\",\n    \"mode_info\": \"选择一种生成模式开始创作。\",\n    \"mode_info_simple\": \"用自然语言描述你想要的音乐，AI 将自动生成描述、歌词和元数据。\",\n    \"mode_info_custom\": \"完全控制描述、歌词和所有参数。\",\n    \"mode_info_remix\": \"上传源音频，用你的描述和歌词创建混音版本。\",\n    \"mode_info_repaint\": \"上传源音频，重绘指定时间范围的内容。\",\n    \"mode_info_extract\": \"从源音频中提取特定音轨（人声、鼓等）。\",\n    \"mode_info_lego\": \"重新组装音轨：替换源音频中的特定音轨。\",\n    \"mode_info_complete\": \"补全源音频中缺失的音轨。\",\n    \"mode_simple\": \"简单\",\n    \"mode_custom\": \"自定义\",\n    \"simple_query_label\": \"歌曲描述 *\",\n    \"simple_query_placeholder\": \"描述你想创作的音乐，例如：'给我生成一首暗黑的戏剧古风，歌词要华丽'。留空则随机生成样本。\",\n    \"simple_query_info\": \"输入你想生成的音乐的自然语言描述。\",\n    \"simple_vocal_language_label\": \"人声语言\",\n    \"simple_vocal_language_info\": \"选择歌词的首选语言。使用 'unknown' 表示任意语言。\",\n    \"create_sample_btn\": \"创建样本\",\n    \"caption_title\": \"📝 音乐描述\",\n    \"caption_label\": \"音乐描述\",\n    \"caption_placeholder\": \"一段平和的原声吉他旋律,配有柔和的人声.\",\n    \"caption_info\": \"描述风格、流派、乐器和情绪。\",\n    \"lyrics_title\": \"📝 歌词\",\n    \"lyrics_label\": \"歌词\",\n    \"lyrics_placeholder\": \"[第一段]\\\\n在星空下\\\\n我感到如此活跃.\",\n    \"lyrics_info\": \"带有结构的歌曲歌词。\",\n    \"instrumental_label\": \"纯音乐\",\n    \"format_btn\": \"格式化\",\n    \"format_caption_btn\": \"增强描述\",\n    \"format_lyrics_btn\": \"增强歌词\",\n    \"optional_params\": \"⚙️ 可选参数\",\n    \"optional_music_props\": \"🎵 音乐属性\",\n    \"optional_gen_settings\": \"📐 生成设置\",\n    \"advanced_dit_section\": \"🎛️ DiT 扩散参数\",\n    \"advanced_lm_section\": \"🤖 LM 生成参数\",\n    \"advanced_output_section\": \"🔊 音频输出与后处理\",\n    \"advanced_automation_section\": \"⚡ 自动化与批量\",\n    \"vocal_language_label\": \"人声语言\",\n    \"vocal_language_info\": \"'unknown' = 纯音乐/自动。\",\n    \"bpm_label\": \"BPM\",\n    \"bpm_info\": \"留空表示 N/A。\",\n    \"keyscale_label\": \"调\",\n    \"keyscale_placeholder\": \"留空表示N/A\",\n    \"keyscale_info\": \"A-G, #/♭, 大调/小调。\",\n    \"timesig_label\": \"拍号\",\n    \"timesig_info\": \"2/4, 3/4, 4/4。\",\n    \"duration_label\": \"音频时长 (秒)\",\n    \"duration_info\": \"使用-1表示随机。\",\n    \"batch_size_label\": \"批量大小\",\n    \"batch_size_info\": \"要生成的音频数量(最多8个)。\",\n    \"advanced_settings\": \"⚙️ 设置\",\n    \"inference_steps_label\": \"DiT 推理步数\",\n    \"inference_steps_info\": \"Turbo: 最多8, Base: 最多200。\",\n    \"guidance_scale_label\": \"DiT 引导比例(仅支持base模型)\",\n    \"guidance_scale_info\": \"更高的值更紧密地遵循文本。\",\n    \"seed_label\": \"种子\",\n    \"seed_info\": \"批量使用逗号分隔的值。\",\n    \"random_seed_label\": \"随机种子\",\n    \"random_seed_info\": \"启用以自动生成种子。\",\n    \"audio_format_label\": \"音频格式\",\n    \"audio_format_info\": \"保存文件的音频格式。\",\n    \"use_adg_label\": \"使用 ADG\",\n    \"use_adg_info\": \"启用角域引导。\",\n    \"shift_label\": \"Shift\",\n    \"shift_info\": \"时间步偏移因子，仅对 base 模型生效 (范围 1.0~5.0，默认 3.0)。对 turbo 模型无效。\",\n    \"infer_method_label\": \"推理方法\",\n    \"infer_method_info\": \"扩散推理方法。ODE (欧拉) 更快，SDE (随机) 可能产生不同结果。\",\n    \"custom_timesteps_label\": \"自定义时间步\",\n    \"custom_timesteps_info\": \"从 1.0 到 0.0 的逗号分隔值（例如 '0.97,0.76,0.615,0.5,0.395,0.28,0.18,0.085,0'）。会覆盖推理步数和 shift 设置。\",\n    \"cfg_interval_start\": \"CFG 间隔开始\",\n    \"cfg_interval_end\": \"CFG 间隔结束\",\n    \"lm_params_title\": \"🤖 LM 生成参数\",\n    \"lm_temperature_label\": \"LM 温度\",\n    \"lm_temperature_info\": \"5Hz LM温度(越高越随机)。\",\n    \"lm_cfg_scale_label\": \"LM CFG 比例\",\n    \"lm_cfg_scale_info\": \"5Hz LM CFG (1.0 = 无CFG)。\",\n    \"lm_top_k_label\": \"LM Top-K\",\n    \"lm_top_k_info\": \"Top-K (0 = 禁用)。\",\n    \"lm_top_p_label\": \"LM Top-P\",\n    \"lm_top_p_info\": \"Top-P (1.0 = 禁用)。\",\n    \"lm_negative_prompt_label\": \"LM 负面提示\",\n    \"lm_negative_prompt_placeholder\": \"输入CFG的负面提示(默认: NO USER INPUT)\",\n    \"lm_negative_prompt_info\": \"负面提示(当LM CFG比例 > 1.0时使用)。\",\n    \"cot_metas_label\": \"CoT 元数据\",\n    \"cot_metas_info\": \"使用 LM 生成 CoT 元数据(取消勾选则跳过 LM CoT 生成)。\",\n    \"cot_language_label\": \"CoT 语言\",\n    \"cot_language_info\": \"在CoT中生成语言(思维链)。\",\n    \"constrained_debug_label\": \"约束解码调试\",\n    \"constrained_debug_info\": \"启用约束解码的调试日志(勾选以查看详细日志)。\",\n    \"auto_score_label\": \"自动评分\",\n    \"auto_score_info\": \"自动计算所有生成音频的质量分数。\",\n    \"auto_lrc_label\": \"自动 LRC\",\n    \"auto_lrc_info\": \"自动为所有生成的音频生成LRC歌词时间戳。\",\n    \"lm_batch_chunk_label\": \"LM 批量块大小\",\n    \"lm_batch_chunk_info\": \"每个LM批量块的最大项目数(默认: 8, 受GPU内存限制)。\",\n    \"codes_strength_label\": \"LM 代码强度\",\n    \"codes_strength_info\": \"控制使用LM生成代码的去噪步骤数量。\",\n    \"similarity_denoise_label\": \"相似度 / 降噪\",\n    \"similarity_denoise_info\": \"控制输出与参考音频的贴合程度。数值越高保留越多结构。\",\n    \"cover_strength_label\": \"音频覆盖强度\",\n    \"cover_strength_info\": \"控制使用覆盖模式的去噪步骤数量。\",\n    \"remix_strength_label\": \"混音强度\",\n    \"remix_strength_info\": \"控制混音对原始音频的还原程度（越高越接近原始音频）。\",\n    \"cover_noise_strength_label\": \"翻唱强度\",\n    \"cover_noise_strength_info\": \"控制 Remix 模式下的旋律还原程度。推荐：使用 SFT 模型，值设为 0.1–0.25。稍微提升即可还原旋律，但风格迁移可能需要额外的 prompt 调参。（0 = 纯噪声/无翻唱效果，1 = 最接近原始音频）。\",\n    \"score_sensitivity_label\": \"质量评分敏感度\",\n    \"score_sensitivity_info\": \"更低 = 更敏感(默认: 1.0). 调整PMI如何映射到[0,1]。\",\n    \"think_label\": \"思考\",\n    \"parallel_thinking_label\": \"并行思考\",\n    \"parallel_thinking_info\": \"并行处理批量样本以加速生成。\",\n    \"generate_btn\": \"🎵 生成音乐\",\n    \"extract_stem_btn\": \"🎵 提取分轨\",\n    \"add_stem_btn\": \"🎵 添加分轨\",\n    \"stem_area_controls\": \"🧩 新分轨区域（秒）\",\n    \"stem_start\": \"分轨开始\",\n    \"stem_end\": \"分轨结束\",\n    \"autogen_label\": \"自动生成\",\n    \"caption_rewrite_label\": \"描述重写\",\n    \"caption_rewrite_info\": \"生成前使用LM重写描述。\",\n    \"auto_label\": \"自动\",\n    \"bpm_auto_label\": \"BPM 自动\",\n    \"key_auto_label\": \"调 自动\",\n    \"timesig_auto_label\": \"拍号 自动\",\n    \"vocal_lang_auto_label\": \"语言 自动\",\n    \"duration_auto_label\": \"时长 自动\",\n    \"reset_all_auto\": \"🔄 全部重置为自动\",\n    \"advanced_dit_params\": \"DiT 高级参数\"\n  },\n  \"results\": {\n    \"title\": \"🎵 结果\",\n    \"generated_music\": \"🎵 生成的音乐(样本 {n})\",\n    \"send_to_remix_btn\": \"🔗 发送到混音\",\n    \"send_to_repaint_btn\": \"🔗 发送到重绘\",\n    \"save_btn\": \"💾 保存\",\n    \"score_btn\": \"📊 获取评分\",\n    \"lrc_btn\": \"🎵 获取 LRC\",\n    \"save_lrc_btn\": \"💾 保存 LRC\",\n    \"convert_to_codes_btn\": \"🔄 转换为代码\",\n    \"quality_score_label\": \"质量分数(样本 {n})\",\n    \"quality_score_placeholder\": \"点击'评分'以计算基于困惑度的质量分数\",\n    \"codes_label\": \"LM 代码(样本 {n})\",\n    \"lrc_label\": \"歌词时间戳(样本 {n})\",\n    \"lrc_placeholder\": \"点击'LRC'生成时间戳\",\n    \"details_accordion\": \"📊 评分与LRC与LM代码\",\n    \"generation_status\": \"生成状态\",\n    \"current_batch\": \"当前批次\",\n    \"batch_indicator\": \"批次 {current} / {total}\",\n    \"next_batch_status\": \"下一批次状态\",\n    \"prev_btn\": \"◀ 上一个\",\n    \"next_btn\": \"下一个 ▶\",\n    \"restore_params_btn\": \"↙️ 将这些设置应用到UI(恢复批次参数)\",\n    \"batch_results_title\": \"👇 点击查看批量结果和生成详情\",\n    \"all_files_label\": \"📁 所有生成的文件(下载)\",\n    \"generation_details\": \"生成详情\"\n  },\n  \"messages\": {\n    \"no_audio_to_save\": \"❌ 没有要保存的音频\",\n    \"save_success\": \"✅ 已将音频和元数据保存到 {filename}\",\n    \"save_failed\": \"❌ 保存失败: {error}\",\n    \"no_file_selected\": \"⚠️ 未选择文件\",\n    \"params_loaded\": \"✅ 已从 {filename} 加载参数\",\n    \"invalid_json\": \"❌ 无效的JSON文件: {error}\",\n    \"load_error\": \"❌ 加载文件时出错: {error}\",\n    \"example_loaded\": \"📁 已从 {filename} 加载示例\",\n    \"example_failed\": \"解析JSON文件 {filename} 失败: {error}\",\n    \"example_error\": \"加载示例时出错: {error}\",\n    \"lm_generated\": \"🤖 使用LM生成的示例\",\n    \"lm_fallback\": \"使用LM生成示例失败,回退到示例目录\",\n    \"lm_not_initialized\": \"❌ 5Hz LM未初始化。请先初始化它。\",\n    \"think_requires_lm\": \"⚠️ \\\"Think\\\"功能需要先初始化 5Hz LM。Think 已自动关闭，生成将不使用 LM 思考。\",\n    \"autogen_enabled\": \"🔄 已启用自动生成 - 下一批次将在此之后生成\",\n    \"batch_ready\": \"✅ 批次 {n} 就绪!点击'下一个'查看。\",\n    \"batch_generating\": \"🔄 开始为批次 {n} 进行后台生成.\",\n    \"batch_failed\": \"❌ 后台生成失败: {error}\",\n    \"viewing_batch\": \"✅ 查看批次 {n}\",\n    \"at_first_batch\": \"已在第一批次\",\n    \"at_last_batch\": \"没有下一批次可用\",\n    \"batch_not_found\": \"在队列中未找到批次 {n}\",\n    \"no_batch_data\": \"没有要恢复的批次数据。\",\n    \"params_restored\": \"✅ 已从批次 {n} 恢复UI参数\",\n    \"scoring_failed\": \"❌ 错误: 未找到批次数据\",\n    \"no_codes\": \"❌ 没有可用的音频代码。请先生成音乐。\",\n    \"score_failed\": \"❌ 评分失败: {error}\",\n    \"score_error\": \"❌ 计算分数时出错: {error}\",\n    \"lrc_no_batch_data\": \"❌ 未找到批次数据。请先生成音乐。\",\n    \"lrc_no_extra_outputs\": \"❌ 未找到额外输出。条件张量不可用。\",\n    \"lrc_missing_tensors\": \"❌ 缺少LRC生成所需的张量。\",\n    \"lrc_sample_not_exist\": \"❌ 当前批次中不存在该样本。\",\n    \"lrc_empty_result\": \"⚠️ LRC生成结果为空。\",\n    \"empty_query\": \"⚠️ 请输入音乐描述。\",\n    \"sample_creation_failed\": \"❌ 创建样本失败。请重试。\",\n    \"sample_created\": \"✅ 样本已创建！检查描述和歌词，然后点击生成音乐。\",\n    \"simple_examples_not_found\": \"⚠️ 未找到简单模式示例目录。\",\n    \"simple_examples_empty\": \"⚠️ 简单模式示例中没有示例文件。\",\n    \"simple_example_loaded\": \"🎲 已从 {filename} 加载随机示例\",\n    \"format_success\": \"✅ 描述和歌词格式化成功\",\n    \"format_failed\": \"❌ 格式化失败: {error}\",\n    \"skipping_metas_cot\": \"⚡ 跳过 Phase 1 元数据 COT（样本已格式化）\",\n    \"invalid_timesteps_format\": \"⚠️ 时间步格式无效，使用默认调度。\",\n    \"timesteps_out_of_range\": \"⚠️ 时间步必须在 [0, 1] 范围内，使用默认调度。\",\n    \"timesteps_count_mismatch\": \"⚠️ 时间步数量 ({actual}) 与推理步数 ({expected}) 不匹配，将使用时间步数量。\"\n  },\n  \"training\": {\n    \"tab_title\": \"🎓 LoRA 训练\",\n    \"tab_dataset_builder\": \"📁 数据集构建\",\n    \"tab_train_lora\": \"🚀 训练 LoRA\",\n    \"quick_start_title\": \"🚀 快速开始\",\n    \"load_dataset_label\": \"数据集 JSON 路径\",\n    \"load_dataset_info\": \"加载之前保存的数据集。\",\n    \"load_btn\": \"📂 加载\",\n    \"load_status\": \"加载状态\",\n    \"scan_label\": \"音频目录路径\",\n    \"scan_info\": \"扫描音频文件（wav、mp3、flac、ogg、opus）。\",\n    \"scan_btn\": \"🔍 扫描\",\n    \"scan_status\": \"扫描状态\",\n    \"found_audio_files\": \"已找到的音频文件\",\n    \"dataset_name\": \"数据集名称\",\n    \"dataset_name_placeholder\": \"输入数据集名称\",\n    \"dataset_settings_header\": \"数据集设置\",\n    \"tag_prepend\": \"前置（标签，描述）\",\n    \"tag_append\": \"后置（描述，标签）\",\n    \"tag_replace\": \"替换描述\",\n    \"step2_title\": \"步骤 2：AI 自动标注\",\n    \"step2_instruction\": \"点击下方按钮，使用 AI 自动为所有音频文件生成元数据：\\n- **描述**：音乐风格、流派、情绪描述\\n- **BPM**：每分钟节拍数\\n- **调性**：音乐调（例如 C Major、Am）\\n- **拍号**：4/4、3/4 等。\",\n    \"step3_title\": \"步骤 3：预览与编辑\",\n    \"step4_title\": \"步骤 4：保存数据集\",\n    \"step5_title\": \"步骤 5：预处理为张量\",\n    \"step5_intro\": \"**预处理将您的数据集转换为预计算的张量，以便快速训练。**\\n\\n您可以：\\n- 使用上述步骤 1-4 的数据集，**或者**\\n- 加载现有的数据集 JSON 文件（如果您已经保存了一个）\",\n    \"step5_details\": \"此步骤：\\n- 将音频编码为 VAE 潜变量\\n- 将描述和歌词编码为文本嵌入\\n- 运行条件编码器\\n- 将所有张量保存到 `.pt` 文件\\n\\n⚠️ **这需要加载模型，可能需要几分钟。**\",\n    \"train_section_tensors\": \"预处理数据集选择\",\n    \"train_section_lora\": \"LoRA 设置\",\n    \"train_section_params\": \"训练参数\",\n    \"train_tensor_selection_desc\": \"选择包含预处理张量文件（`.pt` 文件）的目录。\\n这些文件在「数据集构建」标签页中使用「预处理」按钮创建。\",\n    \"all_instrumental\": \"全部为纯音乐\",\n    \"all_instrumental_info\": \"勾选表示所有曲目均为纯音乐（无人声）。\",\n    \"custom_tag\": \"自定义激活标签\",\n    \"custom_tag_info\": \"用于激活此 LoRA 风格的唯一标签。\",\n    \"tag_position\": \"标签位置\",\n    \"tag_position_info\": \"在描述中放置自定义标签的位置。\",\n    \"genre_ratio\": \"风格比例 (%)\",\n    \"genre_ratio_info\": \"0%=全部描述，100%=全部风格。单样本覆盖优先。\",\n    \"skip_metas\": \"跳过 BPM/调性/拍号\",\n    \"skip_metas_info\": \"跳过 BPM/调性/拍号生成。描述和风格仍由 LM 生成。\",\n    \"only_unlabeled\": \"仅未标注\",\n    \"only_unlabeled_info\": \"仅标注无描述的样本（用于继续失败的标注）。\",\n    \"auto_label_btn\": \"🏷️ 自动标注全部\",\n    \"label_progress\": \"标注进度\",\n    \"select_sample\": \"选择样本 #\",\n    \"select_sample_info\": \"选择要预览和编辑的样本。\",\n    \"audio_preview\": \"音频预览\",\n    \"filename\": \"文件名\",\n    \"caption\": \"描述\",\n    \"genre\": \"风格\",\n    \"prompt_override_label\": \"提示覆盖（本样本）\",\n    \"prompt_override_info\": \"覆盖本样本的全局比例。\",\n    \"lyrics_editable_label\": \"歌词（可编辑，用于训练）\",\n    \"raw_lyrics_label\": \"原始歌词（来自 .txt 文件）\",\n    \"no_lyrics_placeholder\": \"（无 .txt 歌词文件）\",\n    \"bpm\": \"BPM\",\n    \"key_label\": \"调性\",\n    \"key_placeholder\": \"C 大调\",\n    \"time_sig\": \"拍号\",\n    \"duration_s\": \"时长 (秒)\",\n    \"language\": \"语言\",\n    \"instrumental\": \"纯音乐\",\n    \"save_changes_btn\": \"💾 保存更改\",\n    \"edit_status\": \"编辑状态\",\n    \"save_path\": \"保存路径\",\n    \"save_path_info\": \"数据集 JSON 的保存路径。\",\n    \"save_dataset_btn\": \"💾 保存数据集\",\n    \"save_status\": \"保存状态\",\n    \"load_existing_label\": \"加载已有数据集\",\n    \"load_existing_info\": \"之前保存的数据集 JSON 文件路径。\",\n    \"load_dataset_btn\": \"📂 加载数据集\",\n    \"tensor_output_dir\": \"张量输出目录\",\n    \"tensor_output_info\": \"保存预处理张量文件的目录。\",\n    \"preprocess_btn\": \"⚡ 预处理\",\n    \"preprocess_progress\": \"预处理进度\",\n    \"preprocessed_tensors_dir\": \"预处理张量目录\",\n    \"preprocessed_tensors_info\": \"包含预处理 .pt 张量文件的目录。\",\n    \"dataset_info\": \"数据集信息。\",\n    \"lora_rank\": \"LoRA 秩 (r)\",\n    \"lora_rank_info\": \"越高容量越大，显存占用越多。\",\n    \"lora_alpha\": \"LoRA Alpha\",\n    \"lora_alpha_info\": \"缩放因子（通常为 2× 秩）。\",\n    \"lora_dropout\": \"LoRA Dropout\",\n    \"learning_rate\": \"学习率\",\n    \"learning_rate_info\": \"建议从 3e-4 开始，按需调整。\",\n    \"max_epochs\": \"最大轮数\",\n    \"batch_size\": \"批大小\",\n    \"batch_size_info\": \"显存充足时可增大。\",\n    \"gradient_accumulation\": \"梯度累积\",\n    \"gradient_accumulation_info\": \"有效批大小 = batch_size × 累积步数。\",\n    \"save_every_n_epochs\": \"每 N 轮保存\",\n    \"shift\": \"Shift\",\n    \"shift_info\": \"Turbo 模型时间步偏移。\",\n    \"seed\": \"随机种子\",\n    \"output_dir\": \"输出目录\",\n    \"output_dir_info\": \"保存训练后 LoRA 权重的目录。\",\n    \"start_training_btn\": \"🚀 开始训练\",\n    \"stop_training_btn\": \"⏹️ 停止训练\",\n    \"training_progress\": \"训练进度\",\n    \"training_log\": \"训练日志\",\n    \"training_loss_title\": \"训练损失\",\n    \"step\": \"步数\",\n    \"loss\": \"损失\",\n    \"export_header\": \"导出 LoRA\",\n    \"export_path\": \"导出路径\",\n    \"export_lora_btn\": \"📦 导出 LoRA\",\n    \"export_status\": \"导出状态\",\n    \"stop_no_training\": \"ℹ 当前没有正在进行的训练\",\n    \"stop_stopping\": \"⏹️ 正在停止训练...\",\n    \"latest_auto\": \"最新（自动）\",\n    \"export_path_required\": \"❌ 请输入导出路径\",\n    \"invalid_lora_output_dir\": \"❌ LoRA 输出目录无效\",\n    \"no_checkpoints_found\": \"❌ 未找到检查点\",\n    \"no_trained_model_found\": \"❌ 在 {path} 中未找到训练好的模型\",\n    \"invalid_export_path\": \"❌ 导出路径无效\",\n    \"lora_exported\": \"✅ LoRA 已导出到 {path}\",\n    \"export_failed\": \"❌ 导出失败: {error}\",\n    \"lokr_output_dir_required\": \"⚠️ 请先输入 LoKr 输出目录\",\n    \"lokr_no_checkpoints_use_latest\": \"ℹ 未找到检查点；导出将使用最新可用权重\",\n    \"lokr_no_exportable_checkpoints\": \"ℹ 未找到可导出的轮次检查点\",\n    \"lokr_found_checkpoints\": \"✅ 找到 {count} 个 LoKr 检查点\",\n    \"lokr_selected_epoch_not_found\": \"❌ 未找到所选轮次: {chosen}。可用: {available}\",\n    \"lokr_no_weights_selected_epoch\": \"❌ 所选轮次 {epoch} 中未找到 LoKr 权重\",\n    \"lokr_no_weights_latest_checkpoint\": \"❌ 最新检查点 {checkpoint} 中未找到 LoKr 权重\",\n    \"lokr_no_trained_weights_found\": \"❌ 在 {path} 中未找到训练好的 LoKr 权重\",\n    \"lokr_exported\": \"✅ LoKr 已导出到 {path}\",\n    \"tab_train_lokr\": \"🚀 训练 LoKr\",\n    \"lokr_section_tensors\": \"预处理数据集选择\",\n    \"lokr_section_settings\": \"LoKr 设置\",\n    \"lokr_tensor_selection_desc\": \"选择包含预处理张量文件（`.pt` 文件）的目录。\\n这些文件在「数据集构建」标签页中使用「预处理」按钮创建。\",\n    \"lokr_linear_dim\": \"LoKr Linear Dim\",\n    \"lokr_linear_dim_info\": \"Rank (dimension) for LoKr adaptation matrices.\",\n    \"lokr_linear_alpha\": \"LoKr Linear Alpha\",\n    \"lokr_linear_alpha_info\": \"Scaling factor for LoKr (usually similar to dim).\",\n    \"lokr_factor\": \"LoKr Factor\",\n    \"lokr_factor_info\": \"Kronecker factor (-1 for auto).\",\n    \"lokr_decompose_both\": \"Decompose Both Sides\",\n    \"lokr_decompose_both_info\": \"When enabled, decomposes both left and right matrices.\",\n    \"lokr_use_tucker\": \"Use Tucker Decomposition\",\n    \"lokr_use_tucker_info\": \"Apply Tucker decomposition when applicable.\",\n    \"lokr_use_scalar\": \"Use Scalar Gate\",\n    \"lokr_use_scalar_info\": \"Enable scalar gating for LoKr weights.\",\n    \"lokr_weight_decompose\": \"Weight Decompose (WD)\",\n    \"lokr_weight_decompose_info\": \"Enable weight decomposition for more stable LoKr training.\",\n    \"lokr_learning_rate_info\": \"LoKr commonly uses a higher LR than LoRA. Tune per dataset.\",\n    \"lokr_output_dir_info\": \"保存训练后 LoKr 权重的目录。\",\n    \"start_lokr_training_btn\": \"🚀 开始训练 LoKr\",\n    \"lokr_training_loss_title\": \"LoKr 训练损失\",\n    \"lokr_export_header\": \"导出 LoKr\",\n    \"export_lokr_btn\": \"📦 导出 LoKr\",\n    \"lokr_checkpoint_epoch\": \"Checkpoint Epoch\",\n    \"lokr_checkpoint_epoch_info\": \"Select a specific epoch checkpoint to export, or keep Latest (auto).\",\n    \"refresh_epochs_btn\": \"↻ 刷新 Epochs\"\n  },\n  \"help\": {\n    \"btn_label\": \"?\",\n    \"close_label\": \"✕\",\n    \"getting_started\": \"## 快速入门\\n\\n1. 在设置面板中**选择模型**（如 `acestep-v15-turbo`）\\n2. 如需 Thinking 模式，**选择 5Hz LM**（推荐）\\n3. 点击**初始化服务**，等待绿色状态\\n4. 选择**生成模式**（建议从 Simple 开始）\\n5. 描述你想要的音乐，点击**生成音乐**\\n\\n> **提示：** Turbo 模型最快。启用 Think 获得更智能的生成。\",\n    \"service_config\": \"## 服务配置\\n\\n### 快速设置\\n1. 选择**主模型路径**（推荐 turbo）\\n2. 选择 **5Hz LM 模型路径**（按 GPU 自动筛选）\\n3. 选择**后端**：`vllm`（快速，NVIDIA ≥8GB）或 `pt`（通用）\\n4. 勾选**初始化 5Hz LM** 以启用 Thinking 模式\\n5. 点击**初始化服务**\\n\\n### 性能提示\\n- **Flash Attention**：更快推理（需要 flash_attn）\\n- **闲置时转移到 CPU**：GPU <20GB 时自动启用\\n- **INT8 量化**：减少显存，<20GB 时自动启用\\n- **编译**：量化必需，默认启用\\n\\n### LoRA\\n- 设置 LoRA 路径 → 加载 → 启用「使用 LoRA」\\n- ⚠️ 不能在 INT8 量化下使用 LoRA\",\n    \"generation_simple\": \"## Simple 模式教程\\n\\n**适合：** 快速创作音乐，最少操作。\\n\\n### 步骤\\n1. 在生成模式中选择 **Simple**\\n2. 输入描述，如 *\\\"欢快的流行歌曲，带有吉他即兴演奏\\\"*\\n3. （可选）勾选**纯音乐**不要人声\\n4. （可选）选择**人声语言**\\n5. 点击**创建样本** — AI 生成描述、歌词、元数据\\n6. 检查并编辑生成的内容\\n7. 点击**生成音乐**\\n\\n### 提示\\n- 点击 🎲 获取随机灵感\\n- 描述越具体，结果越好\\n- 留空 BPM/调性让 AI 自动决定\",\n    \"generation_custom\": \"## Custom 模式教程\\n\\n**适合：** 完全控制每个参数。\\n\\n### 步骤\\n1. 在生成模式中选择 **Custom**\\n2. 编写详细的**描述**（风格、流派、乐器、情绪）\\n3. 编写带结构标签的**歌词**：`[Verse]`、`[Chorus]`、`[Bridge]`\\n4. （可选）上传**参考音频**用于风格引导\\n5. 设置 **BPM**、**调性**、**时长**，或留空自动\\n6. 点击**格式化**用 LM 增强（可选）\\n7. 点击**生成音乐**\\n\\n### 描述技巧\\n- 要具体：*\\\"梦幻的 shoegaze，带有大量混响的吉他和低语般的人声\\\"*\\n- 包含：流派、乐器、情绪、节奏感、人声风格\",\n    \"generation_remix\": \"## Remix 模式教程\\n\\n**适合：** 创建翻唱版本或风格迁移。\\n\\n### 步骤\\n1. 在生成模式中选择 **Remix**\\n2. 上传**源音频**（要 remix 的歌曲）\\n3. 编写描述目标风格的**描述**\\n4. （可选）修改**歌词**\\n5. 调整 **Remix 强度**（0.0–1.0）：\\n   - 越高 = 越接近原始结构\\n   - 越低 = 更多创意自由\\n6. 点击**生成音乐**\\n\\n### 提示\\n- 从强度 0.5 开始调整\\n- 使用 SFT 模型，翻唱强度 0.1–0.25 以保留旋律\",\n    \"generation_repaint\": \"## Repaint 模式教程\\n\\n**适合：** 修复或重新生成音乐的特定部分，同时保留其余部分不变。\\n\\n### 步骤\\n1. 在生成模式中选择 **Repaint**\\n2. 上传**源音频**\\n3. 设置**重绘开始**（秒）和**结束**（-1 表示文件末尾）\\n4. 编写描述重绘部分内容的**描述**\\n5. 选择 **Repaint Mode**，按需调节 **Repaint Strength**\\n6. 点击**生成音乐**\\n\\n### Repaint Mode（重绘模式）\\n控制模型如何处理非重绘区域：\\n\\n- **Conservative**（Strength = 0）：最大程度保留原音频。每步扩散都注入源 latent，并使用较长的边界交叉淡入淡出。适合无缝衔接。\\n- **Balanced**（默认）：在 Repaint Strength 控制的一部分扩散步骤中注入源 latent。推荐起始设置。\\n- **Aggressive**（Strength = 1）：完全不注入源 latent，纯扩散生成。创作自由度最高，但边界一致性最弱。\\n\\n### Repaint Strength（重绘强度）\\n仅在 **Balanced** 模式下可调。拖动滑杆控制保留与重生成的平衡：\\n- **0** = 保守行为（自动切换为 Conservative 模式）\\n- **0.5** = 默认 — 前 50% 扩散步骤注入源 latent\\n- **1** = 激进行为（自动切换为 Aggressive 模式）\\n\\n### 提示\\n- 从结果中使用「发送到重绘」快速加载音频\\n- 建议从 Balanced (0.5) 开始，根据结果调整\\n- 降低 Strength 可改善边界衔接，提高 Strength 可获得更多创作空间\",\n    \"generation_extract\": \"## Extract 模式（仅 Base 模型）\\n\\n**适合：** 音轨分离 — 从混音中分离乐器。\\n\\n### 步骤\\n1. 在生成模式中选择 **Extract**\\n2. 上传**源音频**\\n3. 选择要提取的**音轨名称**（如 vocals、drums、bass）\\n4. 点击**提取分轨**\\n\\n### 可用音轨\\nvocals、backing_vocals、drums、bass、guitar、keyboard、percussion、strings、synth、fx、brass、woodwinds\",\n    \"generation_lego\": \"## Lego 模式（仅 Base 模型）\\n\\n**适合：** 为现有音频添加新乐器轨道。\\n\\n### 步骤\\n1. 在生成模式中选择 **Lego**\\n2. 上传**源音频**\\n3. 选择要添加的**音轨名称**\\n4. 编写描述该音轨的**描述**\\n5. 点击**添加分轨**\\n\\n### 提示\\n- 非常适合叠加：为吉他轨道添加鼓，为人声添加贝斯\\n- 描述应只描述新音轨的特征\",\n    \"generation_complete\": \"## Complete 模式（仅 Base 模型）\\n\\n**适合：** 自动编排 — 填充缺失的乐器。\\n\\n### 步骤\\n1. 在生成模式中选择 **Complete**\\n2. 上传**源音频**（部分编排）\\n3. 选择多个要添加的**音轨名称**\\n4. 编写描述期望风格的**描述**\\n5. 点击**生成音乐**\",\n    \"generation_caption\": \"## 编写好的描述\\n\\n### 结构\\n好的描述包括：\\n- **流派/风格**：pop、rock、jazz、electronic、classical…\\n- **乐器**：guitar、piano、synth、drums、strings…\\n- **情绪**：upbeat、melancholic、energetic、dreamy…\\n- **人声风格**：whispered、powerful、falsetto、rap…\\n- **节奏感**：fast、slow、moderate、driving…\\n\\n### 示例\\n- *\\\"充满能量的朋克流行，失真吉他，快速鼓点，嘶吼人声\\\"*\\n- *\\\"流畅的爵士三重奏，行走贝斯，刷子鼓，柔和钢琴\\\"*\\n- *\\\"氛围电子，层叠的合成器垫和无人声\\\"*\\n\\n### 提示\\n- 越详细 = 越好的结果\\n- 使用**格式化**按钮让 AI 增强你的描述\\n- 点击 🎲 查看示例描述\",\n    \"generation_lyrics\": \"## 编写歌词\\n\\n### 结构标签\\n使用段落标签来组织歌曲：\\n```\\n[Verse 1]\\n在这里写你的主歌歌词\\n\\n[Chorus]\\n在这里写你的副歌歌词\\n\\n[Verse 2]\\n第二段主歌\\n\\n[Bridge]\\n过渡段\\n\\n[Outro]\\n结尾歌词\\n```\\n\\n### 提示\\n- 主歌保持 4-8 行\\n- 副歌应该朗朗上口且有重复性\\n- 使用 `[Instrumental]` 或 `[Interlude]` 表示无人声段落\\n- 勾选**纯音乐**复选框生成纯器乐音乐\\n- 选择**人声语言**以匹配歌词语言\",\n    \"generation_advanced\": \"## 高级设置\\n\\n### 关键参数\\n- **推理步数**：Turbo=8（默认），Base=最多 200。对 turbo 来说更多步数不一定更好\\n- **引导比例**：仅 Base 模型。越高 = 越严格遵循提示\\n- **Shift**：时间步偏移（1.0–5.0）。turbo 推荐 3.0\\n- **种子**：设置特定种子以获得可重现的结果\\n\\n### LM 参数\\n- **温度**（0.0–2.0）：越高 = 越有创意/随机\\n- **CFG 比例**（1.0–3.0）：越高 = 越遵循提示\\n- **Top-K / Top-P**：多样性的采样策略\\n\\n### Think 模式\\n启用 **Think** 使用 5Hz LM 进行更智能的生成：\\n- 生成语义代码和元数据\\n- 需要初始化 LM\\n- **并行思考**：并行处理批次（更快）\",\n    \"results\": \"## 结果区域\\n\\n### 每个样本的控制\\n- **音频播放器**：播放、暂停、下载\\n- **发送到混音/重绘**：将此结果作为源进行进一步编辑\\n- **保存**：导出音频 + 元数据为 JSON\\n- **评分**：计算质量分数（基于困惑度）\\n- **LRC**：生成歌词时间戳\\n\\n### 批次导航\\n- 使用 **◀ 上一个** / **下一个 ▶** 浏览批次\\n- 启用 **自动生成** 自动生成下一批\\n- 点击**将这些设置应用到 UI** 以重用好结果的参数\\n\\n### 提示\\n- 生成 2-4 个变体（批量大小）并选择最好的\\n- 使用评分客观比较结果\\n- 保存好的结果以备参考\",\n    \"training_dataset\": \"## 数据集构建教程\\n\\n### 步骤 1：加载或扫描\\n- **加载**：输入现有数据集 JSON 路径 → 点击加载\\n- **扫描**：输入音频文件夹路径 → 点击扫描\\n  - 支持：wav、mp3、flac、ogg、opus\\n\\n### 步骤 2：配置\\n- 设置**数据集名称**\\n- 勾选**全部为纯音乐**（如果没有人声）\\n- 设置**自定义激活标签**（LoRA 的唯一触发词）\\n- 选择**标签位置**：前置、后置或替换\\n\\n### 步骤 3：自动标注\\n- 点击**自动标注全部**生成描述、BPM、调性、拍号\\n- 使用**跳过元数据**跳过 BPM/调性/拍号（更快）\\n\\n### 步骤 4：预览与编辑\\n- 使用滑块浏览样本\\n- 手动编辑描述、歌词、BPM、调性\\n- 每个样本点击**保存更改**\\n\\n### 步骤 5：保存\\n- 输入保存路径 → 点击**保存数据集**\\n\\n### 步骤 6：预处理\\n- 设置张量输出目录 → 点击**预处理**\\n- 将音频/文本编码为张量用于训练\\n\\n### 📖 文档\\n- [LoRA 训练教程](https://github.com/ACE-Step/ACE-Step-1.5/blob/main/docs/zh/LoRA_Training_Tutorial.md) — 完整分步指南\\n- [Side-Step 高级训练](https://github.com/ACE-Step/ACE-Step-1.5/blob/main/docs/sidestep/Getting%20Started.md) — 命令行训练，支持高级功能\",\n    \"training_train\": \"## LoRA 训练教程\\n\\n### 设置\\n1. 输入**预处理张量目录** → 点击**加载数据集**\\n2. 配置 LoRA：\\n   - **秩** (r)：默认 64。越高 = 容量越大\\n   - **Alpha**：通常为秩的 2 倍（128）\\n   - **Dropout**：0.1 用于正则化\\n\\n### 训练\\n3. 设置**学习率**（从 1e-4 开始）\\n4. 设置**最大轮数**（默认 500）\\n5. 点击**开始训练**\\n6. 监控损失曲线 — 应该随时间下降\\n7. 满意时点击**停止训练**\\n\\n### 导出\\n8. 输入导出路径 → 点击**导出 LoRA**\\n9. 在设置中加载：设置 LoRA 路径 → 加载 LoRA → 启用使用 LoRA\\n\\n### 🚀 推荐使用 LoKr 加速训练\\nLoKr 大幅提升了训练效率，原来需要一小时的训练现在只需 5 分钟——**速度提升超过 10 倍**。这对于在消费级 GPU 上训练至关重要。切换到 **Train LoKr** 标签页即可开始。\\n\\n### 提示\\n- 显存有限时使用小批量（1）\\n- 梯度累积增加有效批量大小\\n- 频繁保存检查点（每 200 轮）\\n\\n### 📖 文档\\n- [LoRA 训练教程](https://github.com/ACE-Step/ACE-Step-1.5/blob/main/docs/zh/LoRA_Training_Tutorial.md) — 完整分步指南\\n- [Side-Step 高级训练](https://github.com/ACE-Step/ACE-Step-1.5/blob/main/docs/sidestep/Getting%20Started.md) — 命令行训练，修正时间步采样、LoKR、显存优化\",\n    \"training_lokr\": \"## 🚀 LoKr 训练教程\\n\\nLoKr（低秩 Kronecker 积）大幅提升了训练效率，原来使用 LoRA 需要一小时的训练现在只需 5 分钟——**速度提升超过 10 倍**。这对于在消费级 GPU 上训练至关重要。\\n\\n### 设置\\n1. 输入**预处理张量目录** → 点击**加载数据集**\\n2. 配置 LoKr：\\n   - **Linear Dim**：默认 64（类似 LoRA 的秩）\\n   - **Linear Alpha**：默认 128（缩放因子）\\n   - **Weight Decompose (DoRA)**：默认启用，质量更好\\n\\n### 训练\\n3. 设置**学习率**（LoKr 通常使用更高的学习率，从 1e-3 开始）\\n4. 设置**最大轮数**（默认 500）\\n5. 点击**开始 LoKr 训练**\\n6. 监控损失曲线 — 应该随时间下降\\n7. 满意时点击**停止训练**\\n\\n### 导出\\n8. 输入导出路径 → 点击**导出 LoKr**\\n9. 在设置中加载：设置 LoRA 路径 → 加载 LoRA → 启用使用 LoRA\\n\\n### LoKr vs LoRA 对比\\n| | LoKr | LoRA |\\n|---|---|---|\\n| 速度 | ⚡ 快约 10 倍 | 较慢 |\\n| 显存 | 更低 | 更高 |\\n| 质量 | 相当 | 基准 |\\n| 适合 | 消费级 GPU、快速迭代 | 追求最高保真度 |\\n\\n### 提示\\n- LoKr 使用 Kronecker 分解实现极致效率\\n- 启用 **DoRA**（Weight Decompose）可提升质量\\n- 使用 **Tucker 分解** 可进一步压缩\\n- 更高的学习率（1e-3）通常比 LoRA 的 1e-4 效果更好\",\n    \"training_export\": \"## 使用训练好的 LoRA\\n\\n### 导出\\n1. 训练后，输入导出路径\\n2. 点击**导出 LoRA**\\n\\n### 加载与使用\\n1. 在设置中，将 **LoRA 路径**设置为导出目录\\n2. 点击**加载 LoRA**\\n3. 启用**使用 LoRA** 复选框\\n4. 生成音乐 — 你的 LoRA 风格将被应用\\n\\n### 提示\\n- 在描述中使用你的**自定义激活标签**来触发风格\\n- ⚠️ LoRA 与 INT8 量化不兼容\\n- 你可以卸载并在不同的 LoRA 之间切换\"\n  },\n  \"gen\": {\n    \"enable_normalization\": \"启用归一化\",\n    \"enable_normalization_info\": \"将音频音量归一化到目标峰值电平，以防止削波或确保一致的响度。\",\n    \"normalization_db\": \"目标峰值 (dB)\",\n    \"normalization_db_info\": \"分贝单位的目标峰值电平。-1.0 dB 是标准安全峰值。-0.1 dB 是最大值。\",\n    \"latent_shift\": \"Latent 偏移\",\n    \"latent_shift_info\": \"VAE 解码前对 DiT latent 施加的偏移量。默认 0（不偏移）。负值（如 -0.04）可减少爆音。\",\n    \"latent_rescale\": \"Latent 缩放\",\n    \"latent_rescale_info\": \"VAE 解码前对 DiT latent 施加的缩放因子。默认 1.0（不缩放）。小于 1.0 的值（如 0.91）可减少爆音。\"\n  }\n}\n"
  },
  {
    "path": "acestep/ui/gradio/interfaces/__init__.py",
    "content": "\"\"\"\nGradio UI Components Module\nContains all Gradio interface component definitions and layouts\n\nLayout:\n  ┌──────────────────────────────────────┐\n  │  Header                              │\n  ├──────────────────────────────────────┤\n  │  Dataset Explorer (hidden accordion) │\n  ├──────────────────────────────────────┤\n  │  Settings (accordion, collapsed)     │\n  │   ├─ Service Configuration           │\n  │   ├─ DiT Parameters                  │\n  │   ├─ LM Parameters                   │\n  │   └─ Output / Automation             │\n  ├──────────────────────────────────────┤\n  │  ┌─ Generation ─┬─ Training ──────┐  │\n  │  │  Mode Radio   │  Dataset/LoRA  │  │\n  │  │  Inputs       │                │  │\n  │  │  Results      │                │  │\n  │  └───────────────┴────────────────┘  │\n  └──────────────────────────────────────┘\n\"\"\"\nimport gradio as gr\nfrom acestep.ui.gradio.i18n import get_i18n, t\nfrom acestep.ui.gradio.interfaces.dataset import create_dataset_section\nfrom acestep.ui.gradio.interfaces.generation import (\n    create_advanced_settings_section,\n    create_generation_tab_section,\n)\nfrom acestep.ui.gradio.interfaces.audio_player_preferences import (\n    get_audio_player_preferences_head,\n)\nfrom acestep.ui.gradio.interfaces.result import create_results_section\nfrom acestep.ui.gradio.interfaces.training import create_training_section\nfrom acestep.ui.gradio.events import setup_event_handlers, setup_training_event_handlers\nfrom acestep.ui.gradio.help_content import create_help_button, HELP_MODAL_CSS\n\n\ndef create_gradio_interface(dit_handler, llm_handler, dataset_handler, init_params=None, language='en') -> gr.Blocks:\n    \"\"\"\n    Create Gradio interface\n    \n    Args:\n        dit_handler: DiT handler instance\n        llm_handler: LM handler instance\n        dataset_handler: Dataset handler instance\n        init_params: Dictionary containing initialization parameters and state.\n                    If None, service will not be pre-initialized.\n        language: UI language code ('en', 'zh', 'ja', default: 'en')\n        \n    Returns:\n        Gradio Blocks instance\n    \"\"\"\n    # Update i18n with selected language\n    i18n = get_i18n(language)\n    \n    # Check if running in service mode (hide training tab)\n    service_mode = init_params is not None and init_params.get('service_mode', False)\n    \n    with gr.Blocks(\n        title=t(\"app.title\"),\n        theme=gr.themes.Soft(),\n        head=get_audio_player_preferences_head() + \"\"\"\n        <script>\n        /* Flip tooltips upward when they would overflow the viewport bottom.\n           Handles both .has-info-container and .checkbox-container elements. */\n        document.addEventListener('mouseover', function(e) {\n            var el = e.target.closest('.has-info-container, .checkbox-container');\n            if (!el) return;\n            var rect = el.getBoundingClientRect();\n            if (rect.bottom > window.innerHeight * 0.65) {\n                el.classList.add('tooltip-flip');\n            } else {\n                el.classList.remove('tooltip-flip');\n            }\n        });\n        </script>\n        \"\"\",\n        css=\"\"\"\n        .main-header {\n            text-align: center;\n            margin-bottom: 2rem;\n        }\n        .section-header {\n            background: linear-gradient(90deg, #4CAF50, #45a049);\n            color: white;\n            padding: 10px;\n            border-radius: 5px;\n            margin: 10px 0;\n        }\n        .lm-hints-row {\n            align-items: stretch;\n        }\n        .lm-hints-col {\n            display: flex;\n        }\n        .lm-hints-col > div {\n            flex: 1;\n            display: flex;\n        }\n        .lm-hints-btn button {\n            height: 100%;\n            width: 100%;\n        }\n        /* Position Audio time labels lower to avoid scrollbar overlap */\n        .component-wrapper > .timestamps {\n            transform: translateY(15px);\n        }\n        /* Equal-height row for instrumental checkbox + enhance lyrics button */\n        .instrumental-row {\n            align-items: stretch !important;\n        }\n        .instrumental-row > div {\n            display: flex !important;\n            align-items: stretch !important;\n        }\n        .instrumental-row > div > div {\n            flex: 1;\n            display: flex;\n            align-items: center;\n        }\n        .instrumental-row button {\n            height: 100% !important;\n            min-height: 42px;\n        }\n        /* Ensure buttons in instrumental-row fill height */\n        .instrumental-row > div > button {\n            height: 100% !important;\n            min-height: 42px;\n        }\n        /* Two-line icon buttons: emoji on top, text below */\n        .icon-btn-wrap button, .icon-btn-wrap > button {\n            word-spacing: 100vw;\n            text-align: center;\n            line-height: 1.4;\n        }\n\n        /* --- On-hover Tooltips --- */\n        /* Safely ensure parents don't clip the tooltips using the container class */\n        .has-info-container {\n            overflow: visible !important;\n            contain: none !important;\n        }\n\n        /* Ensure immediate flex parents (like rows, accordions) also allow overflow if they contain an info container */\n        .row:has(.has-info-container),\n        .column:has(.has-info-container),\n        .form:has(.has-info-container),\n        .accordion:has(.has-info-container),\n        .tabs:has(.has-info-container),\n        .gr-block:has(.has-info-container),\n        .gr-box:has(.has-info-container) {\n            overflow: visible !important;\n            contain: none !important;\n        }\n\n        /* Hide info text by default and format as tooltip.\n           In Gradio 6, info is often a div following the span[data-testid=\"block-info\"].\n           Uses visibility/opacity (not display:none) so the tooltip remains interactive\n           and doesn't collapse when the user moves their mouse onto it to scroll. */\n        .has-info-container span[data-testid=\"block-info\"] + div,\n        .has-info-container span[data-testid=\"block-info\"] + span,\n        .checkbox-container + div {\n            visibility: hidden;\n            opacity: 0;\n            transition: opacity 0.1s ease, visibility 0.1s ease;\n            transition-delay: 0.08s;\n            position: absolute;\n            background: rgba(25, 25, 25, 0.98);\n            color: #ffffff;\n            padding: 12px 16px;\n            border-radius: 10px;\n            font-size: 0.85rem;\n            z-index: 999999;\n            max-width: 320px;\n            min-width: 180px;\n            box-shadow: 0 8px 25px rgba(0,0,0,0.5);\n            pointer-events: none;\n            line-height: 1.5;\n            margin-top: 6px;\n            border: 1px solid rgba(255,255,255,0.15);\n            backdrop-filter: blur(10px);\n            left: 0;\n            font-weight: 400;\n            text-transform: none;\n        }\n\n        /* Prevent tooltip CSS from hiding content inside .no-tooltip components */\n        .no-tooltip span[data-testid=\"block-info\"] + div,\n        .no-tooltip span[data-testid=\"block-info\"] + span {\n            display: block !important;\n            position: static !important;\n            background: none !important;\n            padding: 0 !important;\n            border: none !important;\n            box-shadow: none !important;\n            backdrop-filter: none !important;\n            max-width: none !important;\n            min-width: 0 !important;\n            z-index: auto !important;\n            pointer-events: auto !important;\n            margin-top: 0 !important;\n            color: inherit !important;\n            font-size: inherit !important;\n            line-height: inherit !important;\n            font-weight: inherit !important;\n            text-transform: inherit !important;\n            border-radius: 0 !important;\n        }\n        .no-tooltip span[data-testid=\"block-info\"]::after {\n            display: none !important;\n        }\n\n        /* Show tooltips on hover of the label/icon, OR when hovering the tooltip itself.\n           The sibling :hover rule keeps the tooltip visible while the user scrolls it. */\n        .has-info-container span[data-testid=\"block-info\"]:hover + div,\n        .has-info-container span[data-testid=\"block-info\"]:hover + span,\n        .has-info-container span[data-testid=\"block-info\"] + div:hover,\n        .has-info-container span[data-testid=\"block-info\"] + span:hover,\n        .checkbox-container:hover + div,\n        .checkbox-container + div:hover {\n            visibility: visible !important;\n            opacity: 1 !important;\n            transition-delay: 0s;\n        }\n\n        /* High-res info icon using SVG, appended to the label text */\n        .has-info-container span[data-testid=\"block-info\"]::after,\n        .checkbox-container:has(+ div) .label-text::after {\n            content: \"\";\n            display: inline-block;\n            width: 14px;\n            height: 14px;\n            margin-left: 8px;\n            vertical-align: middle;\n            background-image: url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%234a9eff' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='12' cy='12' r='10'/%3E%3Cline x1='12' y1='16' x2='12' y2='12'/%3E%3Cline x1='12' y1='8' x2='12.01' y2='8'/%3E%3C/svg%3E\");\n            background-repeat: no-repeat;\n            background-size: contain;\n            opacity: 0.6;\n            transition: opacity 0.2s, transform 0.2s;\n            cursor: help;\n        }\n\n        /* Hide original Gradio info icon if present */\n        .has-info-container span[data-testid=\"block-info\"] svg,\n        .has-info-container span[data-testid=\"block-info\"]::before {\n            display: none !important;\n        }\n\n        .has-info-container span[data-testid=\"block-info\"]:hover::after,\n        .checkbox-container:hover .label-text::after {\n            opacity: 1;\n            transform: scale(1.15);\n        }\n\n        /* Cap tooltip height, allow scrolling, and enable pointer events so users\n           can hover over and scroll long tooltips without them collapsing */\n        .has-info-container span[data-testid=\"block-info\"]:hover + div,\n        .has-info-container span[data-testid=\"block-info\"]:hover + span,\n        .has-info-container span[data-testid=\"block-info\"] + div:hover,\n        .has-info-container span[data-testid=\"block-info\"] + span:hover,\n        .checkbox-container:hover + div,\n        .checkbox-container + div:hover {\n            max-height: 40vh;\n            overflow-y: auto;\n            pointer-events: auto;\n        }\n\n        /* Flip tooltip above when near the bottom of the viewport */\n        .has-info-container.tooltip-flip span[data-testid=\"block-info\"] + div,\n        .has-info-container.tooltip-flip span[data-testid=\"block-info\"] + span {\n            bottom: 100%;\n            top: auto;\n            margin-top: 0;\n            margin-bottom: 6px;\n        }\n\n        /* --- Auto-toggle checkbox row --- */\n        /* Compact row of Auto checkboxes that mirrors the field row above */\n        .auto-toggles-row {\n            margin-top: -8px !important;\n            margin-bottom: 0 !important;\n            padding: 0 !important;\n            gap: 16px !important;\n            min-height: 0 !important;\n        }\n        .auto-toggle {\n            text-align: center !important;\n        }\n        .auto-toggle label {\n            font-size: 0.8rem !important;\n            gap: 4px !important;\n            white-space: nowrap !important;\n            cursor: pointer !important;\n            opacity: 0.5;\n            transition: opacity 0.15s;\n            justify-content: center !important;\n        }\n        .auto-toggle:hover label {\n            opacity: 1;\n        }\n        .auto-toggle input[type=\"checkbox\"] {\n            width: 13px !important;\n            height: 13px !important;\n        }\n        \"\"\" + HELP_MODAL_CSS,\n    ) as demo:\n        \n        gr.HTML(f\"\"\"\n        <div class=\"main-header\">\n            <h1>{t(\"app.title\")}</h1>\n            <p>{t(\"app.subtitle\")}</p>\n        </div>\n        \"\"\")\n        create_help_button(\"getting_started\")\n        \n        # Dataset Explorer Section (hidden)\n        dataset_section = create_dataset_section(dataset_handler)\n        \n        # ═══════════════════════════════════════════\n        # Top-level: Settings (contains Service Config + Advanced Settings)\n        # ═══════════════════════════════════════════\n        settings_section = create_advanced_settings_section(\n            dit_handler, llm_handler, init_params=init_params, language=language\n        )\n        \n        # ═══════════════════════════════════════════\n        # Tabs: Generation | Training\n        # ═══════════════════════════════════════════\n        with gr.Tabs():\n            # --- Generation Tab ---\n            with gr.Tab(t(\"generation.tab_title\")):\n                gen_section = create_generation_tab_section(\n                    dit_handler, llm_handler, init_params=init_params, language=language\n                )\n                \n                # Results Section (inside the Generation tab, wrapped for visibility control)\n                with gr.Column(visible=True) as results_wrapper:\n                    results_section = create_results_section(dit_handler)\n                # Store the wrapper in gen_section so event handlers can toggle it\n                gen_section[\"results_wrapper\"] = results_wrapper\n            \n            # --- Training Tab ---\n            with gr.Tab(t(\"training.tab_title\"), visible=not service_mode):\n                training_section = create_training_section(\n                    dit_handler, llm_handler, init_params=init_params\n                )\n        \n        # ═══════════════════════════════════════════\n        # Merge all generation-related component dicts for event wiring\n        # ═══════════════════════════════════════════\n        # The event handlers expect a single \"generation_section\" dict with all\n        # components from settings (service config + advanced) and generation tab.\n        generation_section = {}\n        generation_section.update(settings_section)\n        generation_section.update(gen_section)\n        \n        # Connect event handlers\n        setup_event_handlers(\n            demo, dit_handler, llm_handler, dataset_handler,\n            dataset_section, generation_section, results_section\n        )\n        \n        # Connect training event handlers\n        setup_training_event_handlers(demo, dit_handler, llm_handler, training_section)\n    \n    return demo\n"
  },
  {
    "path": "acestep/ui/gradio/interfaces/audio_player_preferences.js",
    "content": "(() => {\n    const STORAGE_KEY = \"acestep.ui.audio.volume\";\n    const GENERATE_BUTTON_ID = \"acestep-generate-btn\";\n    const DEFAULT_VOLUME = 0.5;\n    const EPSILON = 0.001;\n    const STARTUP_RESYNC_WINDOW_MS = 3000;\n    const STARTUP_RESYNC_INTERVAL_MS = 120;\n    const seenPlayers = new WeakSet();\n    const seenVolumeSliders = new WeakSet();\n    const sliderSyncSuppressedUntil = new WeakMap();\n    const observedRoots = new WeakSet();\n    const knownRoots = [];\n    const readyForPersistence = new WeakMap();\n    const wasReadyBeforeLoad = new WeakMap();\n    let scanScheduled = false;\n    let preferredVolume = null;\n    let startupResyncTimer = null;\n\n    const clampVolume = (value) => {\n        if (value === null || value === undefined || value === \"\") {\n            return null;\n        }\n        const parsed = Number(value);\n        if (!Number.isFinite(parsed)) {\n            return null;\n        }\n        if (parsed < 0) {\n            return 0;\n        }\n        if (parsed > 1) {\n            return 1;\n        }\n        return parsed;\n    };\n\n    const loadPreferredVolume = () => {\n        try {\n            const stored = window.localStorage.getItem(STORAGE_KEY);\n            return clampVolume(stored);\n        } catch (_error) {\n            return null;\n        }\n    };\n\n    const storePreferredVolume = (value) => {\n        const clamped = clampVolume(value);\n        if (clamped === null) {\n            return;\n        }\n        preferredVolume = clamped;\n        try {\n            window.localStorage.setItem(STORAGE_KEY, String(clamped));\n        } catch (_error) {\n            // Ignore storage failures (private mode / blocked storage).\n        }\n    };\n\n    const isTrustedUserEvent = (event) => Boolean(event && event.isTrusted);\n\n    const applyPreferredVolume = (player) => {\n        if (!player || preferredVolume === null) {\n            return;\n        }\n        if (Math.abs(player.volume - preferredVolume) <= EPSILON) {\n            return;\n        }\n        player.volume = preferredVolume;\n    };\n\n    const forEachAudioPlayer = (callback) => {\n        for (let i = 0; i < knownRoots.length; i += 1) {\n            const root = knownRoots[i];\n            if (!root || !root.querySelectorAll) {\n                continue;\n            }\n            root.querySelectorAll(\"audio\").forEach((player) => callback(player));\n        }\n    };\n\n    const forEachVolumeSlider = (callback) => {\n        for (let i = 0; i < knownRoots.length; i += 1) {\n            const root = knownRoots[i];\n            if (!root || !root.querySelectorAll) {\n                continue;\n            }\n            root.querySelectorAll(\"input.volume-slider[type='range'], input#volume[type='range']\").forEach(\n                (slider) => callback(slider)\n            );\n        }\n    };\n\n    const applyPreferredVolumeToSlider = (slider) => {\n        if (!slider || preferredVolume === null) {\n            return;\n        }\n        const current = clampVolume(slider.value);\n        if (current !== null && Math.abs(current - preferredVolume) <= EPSILON) {\n            return;\n        }\n        sliderSyncSuppressedUntil.set(slider, Date.now() + 250);\n        slider.value = String(preferredVolume);\n        slider.dispatchEvent(new Event(\"input\", { bubbles: true }));\n    };\n\n    const syncAllVolumeControlsToPreferred = (sourcePlayer = null, sourceSlider = null) => {\n        if (preferredVolume === null) {\n            return;\n        }\n        forEachAudioPlayer((player) => {\n            if (!player) {\n                return;\n            }\n            if (sourcePlayer && player !== sourcePlayer) {\n                if (Math.abs(player.volume - preferredVolume) > EPSILON) {\n                    player.volume = preferredVolume;\n                }\n                return;\n            }\n            applyPreferredVolume(player);\n        });\n        forEachVolumeSlider((slider) => {\n            if (!slider || slider === sourceSlider) {\n                return;\n            }\n            applyPreferredVolumeToSlider(slider);\n        });\n    };\n\n    const stopAndRewindAllPlayers = () => {\n        discoverRoots();\n        forEachAudioPlayer((player) => {\n            if (!player) {\n                return;\n            }\n            try {\n                player.pause();\n            } catch (_error) {\n                // Ignore pause failures from detached or blocked media elements.\n            }\n            if (player.currentTime > 0) {\n                player.currentTime = 0;\n            }\n            applyPreferredVolume(player);\n        });\n    };\n\n    const isGenerateButtonClick = (event) => {\n        if (!event) {\n            return false;\n        }\n        const selector = `#${GENERATE_BUTTON_ID}`;\n        const target = event.target;\n        if (target && typeof target.closest === \"function\" && target.closest(selector)) {\n            return true;\n        }\n        if (typeof event.composedPath !== \"function\") {\n            return false;\n        }\n        const path = event.composedPath();\n        for (let i = 0; i < path.length; i += 1) {\n            const node = path[i];\n            if (node && node.id === GENERATE_BUTTON_ID) {\n                return true;\n            }\n        }\n        return false;\n    };\n\n    const handleDocumentClick = (event) => {\n        if (!isGenerateButtonClick(event)) {\n            return;\n        }\n        stopAndRewindAllPlayers();\n    };\n\n    const stopStartupResync = () => {\n        if (startupResyncTimer === null) {\n            return;\n        }\n        window.clearInterval(startupResyncTimer);\n        startupResyncTimer = null;\n    };\n\n    const beginStartupResync = () => {\n        stopStartupResync();\n        if (preferredVolume === null) {\n            return;\n        }\n\n        const startedAt = Date.now();\n        startupResyncTimer = window.setInterval(() => {\n            scanPlayers();\n            syncAllVolumeControlsToPreferred();\n            if (Date.now() - startedAt >= STARTUP_RESYNC_WINDOW_MS) {\n                stopStartupResync();\n            }\n        }, STARTUP_RESYNC_INTERVAL_MS);\n    };\n\n    const observeRoot = (root) => {\n        if (!root || observedRoots.has(root)) {\n            return;\n        }\n        observedRoots.add(root);\n        knownRoots.push(root);\n\n        const observeTarget = root === document ? document.documentElement : root;\n        if (!observeTarget) {\n            return;\n        }\n\n        new MutationObserver(() => {\n            scheduleScan();\n        }).observe(observeTarget, { childList: true, subtree: true });\n    };\n\n    const scheduleScan = () => {\n        if (scanScheduled) {\n            return;\n        }\n        scanScheduled = true;\n        requestAnimationFrame(() => {\n            scanScheduled = false;\n            scanPlayers();\n        });\n    };\n\n    const discoverRoots = () => {\n        const queue = [document];\n        const visited = new WeakSet();\n\n        while (queue.length > 0) {\n            const root = queue.pop();\n            if (!root || visited.has(root)) {\n                continue;\n            }\n            visited.add(root);\n            observeRoot(root);\n\n            if (!root.querySelectorAll) {\n                continue;\n            }\n            root.querySelectorAll(\"*\").forEach((node) => {\n                if (node && node.shadowRoot) {\n                    queue.push(node.shadowRoot);\n                }\n            });\n        }\n    };\n\n    const registerPlayer = (player) => {\n        if (!player || seenPlayers.has(player)) {\n            return;\n        }\n        seenPlayers.add(player);\n        readyForPersistence.set(player, player.readyState > 0);\n        wasReadyBeforeLoad.set(player, false);\n        applyPreferredVolume(player);\n\n        player.addEventListener(\"volumechange\", (event) => {\n            const next = clampVolume(player.volume);\n            if (next === null) {\n                return;\n            }\n\n            if (!isTrustedUserEvent(event)) {\n                applyPreferredVolume(player);\n                return;\n            }\n\n            if (preferredVolume !== null && Math.abs(next - preferredVolume) <= EPSILON) {\n                return;\n            }\n\n            if (\n                readyForPersistence.get(player) !== true\n                && wasReadyBeforeLoad.get(player) !== true\n            ) {\n                // Ignore mount/load reset events before media metadata is ready.\n                applyPreferredVolume(player);\n                return;\n            }\n\n            storePreferredVolume(next);\n            syncAllVolumeControlsToPreferred(player, null);\n        }, { passive: true });\n\n        const markReadyForPersistence = () => {\n            readyForPersistence.set(player, true);\n            wasReadyBeforeLoad.set(player, false);\n            applyPreferredVolume(player);\n            if (player.currentTime > 0) {\n                player.currentTime = 0;\n            }\n        };\n\n        player.addEventListener(\"loadedmetadata\", () => {\n            markReadyForPersistence();\n        }, { passive: true });\n\n        player.addEventListener(\"loadstart\", () => {\n            wasReadyBeforeLoad.set(player, readyForPersistence.get(player) === true);\n            readyForPersistence.set(player, false);\n            applyPreferredVolume(player);\n            if (player.currentTime > 0) {\n                player.currentTime = 0;\n            }\n        }, { passive: true });\n\n        if (player.readyState > 0) {\n            markReadyForPersistence();\n        }\n    };\n\n    const registerVolumeSlider = (slider) => {\n        if (!slider || seenVolumeSliders.has(slider)) {\n            return;\n        }\n        seenVolumeSliders.add(slider);\n        applyPreferredVolumeToSlider(slider);\n\n        const onSliderInput = (event) => {\n            const suppressedUntil = sliderSyncSuppressedUntil.get(slider) || 0;\n            if (Date.now() <= suppressedUntil) {\n                return;\n            }\n\n            if (!isTrustedUserEvent(event)) {\n                applyPreferredVolumeToSlider(slider);\n                return;\n            }\n\n            const next = clampVolume(slider.value);\n            if (next === null) {\n                return;\n            }\n            if (preferredVolume !== null && Math.abs(next - preferredVolume) <= EPSILON) {\n                return;\n            }\n            storePreferredVolume(next);\n            syncAllVolumeControlsToPreferred(null, slider);\n        };\n\n        slider.addEventListener(\"input\", onSliderInput, { passive: true });\n        slider.addEventListener(\"change\", onSliderInput, { passive: true });\n    };\n\n    const scanPlayers = () => {\n        discoverRoots();\n        forEachAudioPlayer(registerPlayer);\n        forEachVolumeSlider(registerVolumeSlider);\n        syncAllVolumeControlsToPreferred();\n    };\n\n    const start = () => {\n        preferredVolume = loadPreferredVolume();\n        if (preferredVolume === null) {\n            // First run (or invalid storage): seed a sane audible default.\n            storePreferredVolume(DEFAULT_VOLUME);\n            if (preferredVolume === null) {\n                preferredVolume = DEFAULT_VOLUME;\n            }\n        }\n        document.addEventListener(\"click\", handleDocumentClick, true);\n        scanPlayers();\n        beginStartupResync();\n        window.addEventListener(\"beforeunload\", () => {\n            stopStartupResync();\n            document.removeEventListener(\"click\", handleDocumentClick, true);\n        }, { once: true });\n    };\n\n    if (document.readyState === \"loading\") {\n        document.addEventListener(\"DOMContentLoaded\", start, { once: true });\n    } else {\n        start();\n    }\n})();\n"
  },
  {
    "path": "acestep/ui/gradio/interfaces/audio_player_preferences.py",
    "content": "\"\"\"Frontend audio-player preference helpers for the Gradio UI.\"\"\"\n\nfrom pathlib import Path\n\n\n_ASSET_FILENAME = \"audio_player_preferences.js\"\n\n\ndef _load_preferences_script() -> str:\n    \"\"\"Load the external audio-preferences JavaScript asset.\n\n    Returns:\n        JavaScript source text used by the Gradio ``head`` injection.\n    \"\"\"\n    asset_path = Path(__file__).with_name(_ASSET_FILENAME)\n    return asset_path.read_text(encoding=\"utf-8\").strip()\n\n\ndef get_audio_player_preferences_head() -> str:\n    \"\"\"Return Gradio head HTML that injects audio preference behavior.\n\n    Returns:\n        HTML snippet with a single ``<script>`` tag containing the externalized\n        audio preference JavaScript payload.\n    \"\"\"\n    script_source = _load_preferences_script()\n    return f\"<script>\\n{script_source}\\n</script>\"\n"
  },
  {
    "path": "acestep/ui/gradio/interfaces/audio_player_preferences_test.py",
    "content": "\"\"\"Unit tests for audio player preference head-script generation.\"\"\"\n\nimport importlib.util\nfrom pathlib import Path\nimport unittest\n\n\ndef _load_module():\n    \"\"\"Load the target module directly by file path for isolated testing.\"\"\"\n    module_path = Path(__file__).with_name(\"audio_player_preferences.py\")\n    spec = importlib.util.spec_from_file_location(\"audio_player_preferences\", module_path)\n    module = importlib.util.module_from_spec(spec)\n    spec.loader.exec_module(module)  # type: ignore[union-attr]\n    return module\n\n\n_MODULE = _load_module()\nget_audio_player_preferences_head = _MODULE.get_audio_player_preferences_head\n_load_preferences_script = _MODULE._load_preferences_script\n_SCRIPT_PATH = Path(__file__).with_name(\"audio_player_preferences.js\")\n\n\nclass AudioPlayerPreferencesHeadTests(unittest.TestCase):\n    \"\"\"Tests for browser script generation used by Gradio ``Blocks(head=...)``.\"\"\"\n\n    def test_external_script_asset_exists(self):\n        \"\"\"The externalized JavaScript asset should exist and be non-empty.\"\"\"\n        self.assertTrue(_SCRIPT_PATH.is_file())\n        script_asset = _load_preferences_script()\n        self.assertTrue(script_asset)\n\n    def test_script_contains_volume_persistence_and_sync_hooks(self):\n        \"\"\"Success path: script should include storage and volume-change handling.\"\"\"\n        script = get_audio_player_preferences_head()\n        self.assertIn(\"<script>\", script)\n        self.assertIn(\"localStorage\", script)\n        self.assertIn(\"volumechange\", script)\n        self.assertIn(\"MutationObserver\", script)\n        self.assertIn(\"shadowRoot\", script)\n        self.assertIn(\"syncAllVolumeControlsToPreferred\", script)\n        self.assertIn(\"volume-slider\", script)\n        self.assertIn(\"readyForPersistence\", script)\n        self.assertIn(\"wasReadyBeforeLoad\", script)\n        self.assertIn(\"markReadyForPersistence\", script)\n        self.assertIn(\"isTrustedUserEvent\", script)\n        self.assertIn(\"acestep-generate-btn\", script)\n        self.assertIn(\"player.pause()\", script)\n        self.assertIn(\"STARTUP_RESYNC_WINDOW_MS\", script)\n        self.assertIn(\"setInterval\", script)\n        self.assertIn(\"DEFAULT_VOLUME = 0.5\", script)\n\n    def test_script_resets_audio_position_on_updates(self):\n        \"\"\"Regression path: script should force playback to track start on reloads.\"\"\"\n        script = get_audio_player_preferences_head()\n        self.assertIn(\"currentTime = 0\", script)\n        self.assertIn(\"loadstart\", script)\n        self.assertIn(\"loadedmetadata\", script)\n\n    def test_script_seeds_sane_default_volume_when_storage_missing(self):\n        \"\"\"Missing/invalid storage should seed and persist a 0.5 default on startup.\"\"\"\n        script = get_audio_player_preferences_head()\n        self.assertIn(\"if (value === null || value === undefined || value === \\\"\\\")\", script)\n        self.assertIn(\"if (preferredVolume === null)\", script)\n        self.assertIn(\"storePreferredVolume(DEFAULT_VOLUME);\", script)\n\n    def test_script_generation_is_stable(self):\n        \"\"\"Non-target behavior: function should be deterministic for repeated calls.\"\"\"\n        script_1 = get_audio_player_preferences_head()\n        script_2 = get_audio_player_preferences_head()\n        self.assertEqual(script_1, script_2)\n\n\nif __name__ == \"__main__\":\n    unittest.main()\n"
  },
  {
    "path": "acestep/ui/gradio/interfaces/dataset.py",
    "content": "\"\"\"\nGradio UI Dataset Section Module\nContains dataset explorer section component definitions\n\"\"\"\nimport gradio as gr\n\n\ndef create_dataset_section(dataset_handler) -> dict:\n    \"\"\"Create dataset explorer section\"\"\"\n    with gr.Accordion(\"📊 Dataset Explorer\", open=False, visible=False):\n        with gr.Row(equal_height=True):\n            dataset_type = gr.Dropdown(\n                choices=[\"train\", \"test\"],\n                value=\"train\",\n                label=\"Dataset\",\n                info=\"Choose dataset to explore\", elem_classes=[\"has-info-container\"],\n                scale=2\n            )\n            import_dataset_btn = gr.Button(\"📥 Import Dataset\", variant=\"primary\", scale=1)\n            \n            search_type = gr.Dropdown(\n                choices=[\"keys\", \"idx\", \"random\"],\n                value=\"random\",\n                label=\"Search Type\",\n                info=\"How to find items\", elem_classes=[\"has-info-container\"],\n                scale=1\n            )\n            search_value = gr.Textbox(\n                label=\"Search Value\",\n                placeholder=\"Enter keys or index (leave empty for random)\",\n                info=\"Keys: exact match, Index: 0 to dataset size-1\", elem_classes=[\"has-info-container\"],\n                scale=2\n            )\n\n        instruction_display = gr.Textbox(\n            label=\"📝 Instruction\",\n            interactive=False,\n            placeholder=\"No instruction available\",\n            lines=1\n        )\n        \n        repaint_viz_plot = gr.Plot()\n        \n        with gr.Accordion(\"📋 Item Metadata (JSON)\", open=False):\n            item_info_json = gr.Code(\n                label=\"Complete Item Information\",\n                language=\"json\",\n                interactive=False,\n                lines=15\n            )\n        \n        with gr.Row(equal_height=True):\n            item_src_audio = gr.Audio(\n                label=\"Source Audio\",\n                type=\"filepath\",\n                interactive=False,\n                scale=8\n            )\n            get_item_btn = gr.Button(\"🔍 Get Item\", variant=\"secondary\", interactive=False, scale=2)\n        \n        with gr.Row(equal_height=True):\n            item_target_audio = gr.Audio(\n                label=\"Target Audio\",\n                type=\"filepath\",\n                interactive=False,\n                scale=8\n            )\n            item_refer_audio = gr.Audio(\n                label=\"Reference Audio\",\n                type=\"filepath\",\n                interactive=False,\n                scale=2\n            )\n        \n        with gr.Row():\n            use_src_checkbox = gr.Checkbox(\n                label=\"Use Source Audio from Dataset\",\n                value=True,\n                info=\"Check to use the source audio from dataset\"\n            )\n\n        data_status = gr.Textbox(label=\"📊 Data Status\", interactive=False, value=\"❌ No dataset imported\")\n        auto_fill_btn = gr.Button(\"📋 Auto-fill Generation Form\", variant=\"primary\")\n    \n    return {\n        \"dataset_type\": dataset_type,\n        \"import_dataset_btn\": import_dataset_btn,\n        \"search_type\": search_type,\n        \"search_value\": search_value,\n        \"instruction_display\": instruction_display,\n        \"repaint_viz_plot\": repaint_viz_plot,\n        \"item_info_json\": item_info_json,\n        \"item_src_audio\": item_src_audio,\n        \"get_item_btn\": get_item_btn,\n        \"item_target_audio\": item_target_audio,\n        \"item_refer_audio\": item_refer_audio,\n        \"use_src_checkbox\": use_src_checkbox,\n        \"data_status\": data_status,\n        \"auto_fill_btn\": auto_fill_btn,\n    }\n\n"
  },
  {
    "path": "acestep/ui/gradio/interfaces/generation.py",
    "content": "\"\"\"Generation interface facade for advanced settings and tab builders.\"\"\"\n\nfrom typing import Any\n\nfrom .generation_advanced_settings import create_advanced_settings_section\nfrom .generation_defaults import compute_init_defaults\nfrom .generation_service_config import (\n    create_service_config_content as _create_service_config_content,\n    create_service_config_section,\n)\nfrom .generation_tab_section import create_generation_tab_section\n\n\ndef _compute_init_defaults(\n    dit_handler: Any,\n    llm_handler: Any,\n    init_params: dict[str, Any] | None,\n    language: str,\n) -> dict[str, Any]:\n    \"\"\"Backward-compatible wrapper for legacy private defaults helper signature.\n\n    Args:\n        dit_handler: Unused legacy placeholder to preserve old call signature.\n        llm_handler: Unused legacy placeholder to preserve old call signature.\n        init_params: Optional initialization dictionary from CLI/startup.\n        language: Default UI language code.\n\n    Returns:\n        A normalized defaults dictionary used by generation UI builders.\n    \"\"\"\n\n    _ = (dit_handler, llm_handler)\n    return compute_init_defaults(init_params=init_params, language=language)\n\n\ndef create_generation_section(\n    dit_handler: Any,\n    llm_handler: Any,\n    init_params: dict[str, Any] | None = None,\n    language: str = \"en\",\n) -> dict[str, Any]:\n    \"\"\"Build the legacy combined generation section for backward compatibility.\n\n    Args:\n        dit_handler: DiT service handler used to build generation controls.\n        llm_handler: LM service handler used to build generation controls.\n        init_params: Optional initialization state for pre-populating controls.\n        language: UI language code.\n\n    Returns:\n        A merged component map containing both advanced settings and generation-tab controls.\n    \"\"\"\n\n    settings_section = create_advanced_settings_section(\n        dit_handler=dit_handler,\n        llm_handler=llm_handler,\n        init_params=init_params,\n        language=language,\n    )\n    generation_tab_section = create_generation_tab_section(\n        dit_handler=dit_handler,\n        llm_handler=llm_handler,\n        init_params=init_params,\n        language=language,\n    )\n    merged: dict[str, Any] = {}\n    merged.update(settings_section)\n    merged.update(generation_tab_section)\n    return merged\n"
  },
  {
    "path": "acestep/ui/gradio/interfaces/generation_advanced_dit_controls.py",
    "content": "\"\"\"DiT diffusion controls for generation advanced settings.\"\"\"\n\nfrom typing import Any\n\nimport gradio as gr\n\nfrom acestep.ui.gradio.help_content import create_help_button\nfrom acestep.ui.gradio.i18n import t\n\n\ndef build_dit_controls(ui_config: dict[str, Any]) -> dict[str, Any]:\n    \"\"\"Create DiT diffusion controls for advanced settings.\n\n    Args:\n        ui_config: Visibility/range/value configuration returned by generation handler UI config logic.\n\n    Returns:\n        A component map containing DiT sampling, CFG interval, ADG, shift, and seed controls.\n    \"\"\"\n\n    with gr.Accordion(t(\"generation.advanced_dit_section\"), open=True, elem_classes=[\"has-info-container\"]):\n        create_help_button(\"generation_advanced\")\n        with gr.Row():\n            inference_steps = gr.Slider(\n                minimum=ui_config[\"inference_steps_minimum\"],\n                maximum=ui_config[\"inference_steps_maximum\"],\n                value=ui_config[\"inference_steps_value\"],\n                step=1,\n                label=t(\"generation.inference_steps_label\"),\n                info=t(\"generation.inference_steps_info\"),\n                elem_classes=[\"has-info-container\"],\n            )\n            guidance_scale = gr.Slider(\n                minimum=1.0,\n                maximum=15.0,\n                value=7.0,\n                step=0.1,\n                label=t(\"generation.guidance_scale_label\"),\n                info=t(\"generation.guidance_scale_info\"),\n                elem_classes=[\"has-info-container\"],\n                visible=ui_config[\"guidance_scale_visible\"],\n            )\n            infer_method = gr.Dropdown(\n                choices=[\"ode\", \"sde\"],\n                value=\"ode\",\n                label=t(\"generation.infer_method_label\"),\n                info=t(\"generation.infer_method_info\"),\n                elem_classes=[\"has-info-container\"],\n            )\n        with gr.Row():\n            use_adg = gr.Checkbox(\n                label=t(\"generation.use_adg_label\"),\n                value=False,\n                info=t(\"generation.use_adg_info\"),\n                elem_classes=[\"has-info-container\"],\n                visible=ui_config[\"use_adg_visible\"],\n            )\n            shift = gr.Slider(\n                minimum=1.0,\n                maximum=5.0,\n                value=ui_config[\"shift_value\"],\n                step=0.1,\n                label=t(\"generation.shift_label\"),\n                info=t(\"generation.shift_info\"),\n                elem_classes=[\"has-info-container\"],\n                visible=ui_config[\"shift_visible\"],\n            )\n        with gr.Row():\n            custom_timesteps = gr.Textbox(\n                label=t(\"generation.custom_timesteps_label\"),\n                placeholder=\"0.97,0.76,0.615,0.5,0.395,0.28,0.18,0.085,0\",\n                value=\"\",\n                info=t(\"generation.custom_timesteps_info\"),\n                elem_classes=[\"has-info-container\"],\n            )\n        with gr.Row():\n            cfg_interval_start = gr.Slider(\n                minimum=0.0,\n                maximum=1.0,\n                value=0.0,\n                step=0.01,\n                label=t(\"generation.cfg_interval_start\"),\n                info=t(\"generation.cfg_interval_start_info\"),\n                visible=ui_config[\"cfg_interval_start_visible\"],\n                elem_classes=[\"has-info-container\"],\n            )\n            cfg_interval_end = gr.Slider(\n                minimum=0.0,\n                maximum=1.0,\n                value=1.0,\n                step=0.01,\n                label=t(\"generation.cfg_interval_end\"),\n                info=t(\"generation.cfg_interval_end_info\"),\n                visible=ui_config[\"cfg_interval_end_visible\"],\n                elem_classes=[\"has-info-container\"],\n            )\n        with gr.Row():\n            with gr.Column():\n                seed = gr.Textbox(\n                    label=t(\"generation.seed_label\"),\n                    value=\"-1\",\n                    info=t(\"generation.seed_info\"),\n                    elem_classes=[\"has-info-container\"],\n                )\n                random_seed_checkbox = gr.Checkbox(\n                    label=t(\"generation.random_seed_label\"),\n                    value=True,\n                    info=t(\"generation.random_seed_info\"),\n                    elem_classes=[\"has-info-container\"],\n                )\n    return {\n        \"inference_steps\": inference_steps,\n        \"guidance_scale\": guidance_scale,\n        \"infer_method\": infer_method,\n        \"use_adg\": use_adg,\n        \"shift\": shift,\n        \"custom_timesteps\": custom_timesteps,\n        \"cfg_interval_start\": cfg_interval_start,\n        \"cfg_interval_end\": cfg_interval_end,\n        \"seed\": seed,\n        \"random_seed_checkbox\": random_seed_checkbox,\n    }\n"
  },
  {
    "path": "acestep/ui/gradio/interfaces/generation_advanced_output_controls.py",
    "content": "\"\"\"Output and automation controls for generation advanced settings.\"\"\"\n\nfrom typing import Any\n\nimport gradio as gr\n\nfrom acestep.ui.gradio.i18n import t\n\n\ndef build_output_controls(\n    service_pre_initialized: bool,\n    service_mode: bool,\n    init_params: dict[str, Any] | None,\n) -> dict[str, Any]:\n    \"\"\"Create audio-output and post-processing controls for advanced settings.\n\n    Args:\n        service_pre_initialized: Whether existing init params should prefill values.\n        service_mode: Whether the UI is running in service mode (disables some controls).\n        init_params: Optional startup state containing persisted output values.\n\n    Returns:\n        A component map containing format, scoring, normalization, and latent controls.\n    \"\"\"\n\n    params = init_params or {}\n    with gr.Accordion(t(\"generation.advanced_output_section\"), open=False, elem_classes=[\"has-info-container\"]):\n        with gr.Row():\n            audio_format = gr.Dropdown(\n                choices=[\n                    (\"FLAC\", \"flac\"),\n                    (\"MP3\", \"mp3\"),\n                    (\"Opus\", \"opus\"),\n                    (\"AAC\", \"aac\"),\n                    (\"WAV (16-bit)\", \"wav\"),\n                    (\"WAV (32-bit Float)\", \"wav32\"),\n                ],\n                value=\"mp3\",\n                label=t(\"generation.audio_format_label\"),\n                info=t(\"generation.audio_format_info\"),\n                elem_classes=[\"has-info-container\"],\n                interactive=not service_mode,\n            )\n            score_scale = gr.Slider(\n                minimum=0.01,\n                maximum=1.0,\n                value=0.5,\n                step=0.01,\n                label=t(\"generation.score_sensitivity_label\"),\n                info=t(\"generation.score_sensitivity_info\"),\n                elem_classes=[\"has-info-container\"],\n                scale=1,\n                visible=not service_mode,\n            )\n        with gr.Row():\n            enable_normalization = gr.Checkbox(\n                label=t(\"generation.enable_normalization\"),\n                value=params.get(\"enable_normalization\", True) if service_pre_initialized else True,\n                info=t(\"generation.enable_normalization_info\"),\n                elem_classes=[\"has-info-container\"],\n            )\n            normalization_db = gr.Slider(\n                label=t(\"generation.normalization_db\"),\n                minimum=-10.0,\n                maximum=0.0,\n                step=0.1,\n                value=params.get(\"normalization_db\", -1.0) if service_pre_initialized else -1.0,\n                info=t(\"generation.normalization_db_info\"),\n                elem_classes=[\"has-info-container\"],\n            )\n        with gr.Row():\n            fade_in_duration = gr.Slider(\n                label=t(\"generation.fade_in_duration\"),\n                minimum=0.0,\n                maximum=10.0,\n                step=0.1,\n                value=params.get(\"fade_in_duration\", 0.0) if service_pre_initialized else 0.0,\n                info=t(\"generation.fade_in_duration_info\"),\n                elem_classes=[\"has-info-container\"],\n            )\n            fade_out_duration = gr.Slider(\n                label=t(\"generation.fade_out_duration\"),\n                minimum=0.0,\n                maximum=10.0,\n                step=0.1,\n                value=params.get(\"fade_out_duration\", 0.0) if service_pre_initialized else 0.0,\n                info=t(\"generation.fade_out_duration_info\"),\n                elem_classes=[\"has-info-container\"],\n            )\n        with gr.Row():\n            latent_shift = gr.Slider(\n                label=t(\"generation.latent_shift\"),\n                minimum=-0.2,\n                maximum=0.2,\n                step=0.01,\n                value=params.get(\"latent_shift\", 0.0) if service_pre_initialized else 0.0,\n                info=t(\"generation.latent_shift_info\"),\n                elem_classes=[\"has-info-container\"],\n            )\n            latent_rescale = gr.Slider(\n                label=t(\"generation.latent_rescale\"),\n                minimum=0.5,\n                maximum=1.5,\n                step=0.01,\n                value=params.get(\"latent_rescale\", 1.0) if service_pre_initialized else 1.0,\n                info=t(\"generation.latent_rescale_info\"),\n                elem_classes=[\"has-info-container\"],\n            )\n    return {\n        \"audio_format\": audio_format,\n        \"score_scale\": score_scale,\n        \"enable_normalization\": enable_normalization,\n        \"normalization_db\": normalization_db,\n        \"fade_in_duration\": fade_in_duration,\n        \"fade_out_duration\": fade_out_duration,\n        \"latent_shift\": latent_shift,\n        \"latent_rescale\": latent_rescale,\n    }\n\n\ndef build_automation_controls(service_mode: bool) -> dict[str, Any]:\n    \"\"\"Create automation controls for LM batch chunking.\n\n    Args:\n        service_mode: Whether the UI is running in service mode (disables some controls).\n\n    Returns:\n        A component map containing ``lm_batch_chunk_size``.\n    \"\"\"\n\n    with gr.Accordion(\n        t(\"generation.advanced_automation_section\"),\n        open=False,\n        elem_classes=[\"has-info-container\"],\n    ):\n        with gr.Row():\n            lm_batch_chunk_size = gr.Number(\n                label=t(\"generation.lm_batch_chunk_label\"),\n                value=8,\n                minimum=1,\n                maximum=32,\n                step=1,\n                info=t(\"generation.lm_batch_chunk_info\"),\n                scale=1,\n                interactive=not service_mode,\n                elem_classes=[\"has-info-container\"],\n            )\n    return {\"lm_batch_chunk_size\": lm_batch_chunk_size}\n"
  },
  {
    "path": "acestep/ui/gradio/interfaces/generation_advanced_primary_controls.py",
    "content": "\"\"\"Primary advanced-settings controls for generation UI.\"\"\"\n\nfrom typing import Any\n\nimport gradio as gr\n\nfrom acestep.ui.gradio.i18n import t\n\n\ndef build_lora_controls() -> dict[str, Any]:\n    \"\"\"Create LoRA adapter controls for loading and scaling inference adapters.\n\n    Args:\n        None.\n\n    Returns:\n        A component map containing LoRA path, action buttons, toggles, and status controls.\n    \"\"\"\n\n    with gr.Accordion(t(\"generation.lora_accordion_title\"), open=False, elem_classes=[\"has-info-container\"]):\n        with gr.Row():\n            lora_path = gr.Textbox(\n                label=t(\"generation.lora_path_label\"),\n                placeholder=t(\"generation.lora_path_placeholder\"),\n                info=t(\"generation.lora_path_info\"),\n                scale=3,\n            )\n            load_lora_btn = gr.Button(t(\"generation.load_lora_btn\"), variant=\"secondary\", scale=1)\n            unload_lora_btn = gr.Button(t(\"generation.unload_lora_btn\"), variant=\"secondary\", scale=1)\n        with gr.Row():\n            use_lora_checkbox = gr.Checkbox(\n                label=t(\"generation.use_lora_label\"),\n                value=False,\n                info=t(\"generation.use_lora_info\"),\n                scale=1,\n            )\n            lora_scale_slider = gr.Slider(\n                minimum=0.0,\n                maximum=1.0,\n                value=1.0,\n                step=0.05,\n                label=t(\"generation.lora_scale_label\"),\n                info=t(\"generation.lora_scale_info\"),\n                scale=2,\n            )\n        lora_status = gr.Textbox(\n            label=t(\"generation.lora_status_label\"),\n            value=t(\"generation.lora_status_default\"),\n            interactive=False,\n            lines=1,\n            elem_classes=[\"no-tooltip\"],\n        )\n    return {\n        \"lora_path\": lora_path,\n        \"load_lora_btn\": load_lora_btn,\n        \"unload_lora_btn\": unload_lora_btn,\n        \"use_lora_checkbox\": use_lora_checkbox,\n        \"lora_scale_slider\": lora_scale_slider,\n        \"lora_status\": lora_status,\n    }\n\n\ndef build_lm_controls(service_mode: bool) -> dict[str, Any]:\n    \"\"\"Create language-model generation controls for advanced settings.\n\n    Args:\n        service_mode: Whether the UI is running in service mode (disables some controls).\n\n    Returns:\n        A component map containing LM sampling, CoT, negative prompt, and batch controls.\n    \"\"\"\n\n    with gr.Accordion(t(\"generation.advanced_lm_section\"), open=False, elem_classes=[\"has-info-container\"]):\n        with gr.Row():\n            lm_temperature = gr.Slider(\n                label=t(\"generation.lm_temperature_label\"),\n                minimum=0.0,\n                maximum=2.0,\n                value=0.85,\n                step=0.1,\n                scale=1,\n                info=t(\"generation.lm_temperature_info\"),\n                elem_classes=[\"has-info-container\"],\n            )\n            lm_cfg_scale = gr.Slider(\n                label=t(\"generation.lm_cfg_scale_label\"),\n                minimum=1.0,\n                maximum=3.0,\n                value=2.0,\n                step=0.1,\n                scale=1,\n                info=t(\"generation.lm_cfg_scale_info\"),\n                elem_classes=[\"has-info-container\"],\n            )\n        with gr.Row():\n            lm_top_k = gr.Slider(\n                label=t(\"generation.lm_top_k_label\"),\n                minimum=0,\n                maximum=100,\n                value=0,\n                step=1,\n                scale=1,\n                info=t(\"generation.lm_top_k_info\"),\n                elem_classes=[\"has-info-container\"],\n            )\n            lm_top_p = gr.Slider(\n                label=t(\"generation.lm_top_p_label\"),\n                minimum=0.0,\n                maximum=1.0,\n                value=0.9,\n                step=0.01,\n                scale=1,\n                info=t(\"generation.lm_top_p_info\"),\n                elem_classes=[\"has-info-container\"],\n            )\n        with gr.Row():\n            lm_negative_prompt = gr.Textbox(\n                label=t(\"generation.lm_negative_prompt_label\"),\n                value=\"NO USER INPUT\",\n                placeholder=t(\"generation.lm_negative_prompt_placeholder\"),\n                info=t(\"generation.lm_negative_prompt_info\"),\n                elem_classes=[\"has-info-container\"],\n                lines=2,\n            )\n        with gr.Row():\n            use_cot_metas = gr.Checkbox(\n                label=t(\"generation.cot_metas_label\"),\n                value=True,\n                info=t(\"generation.cot_metas_info\"),\n                scale=1,\n                elem_classes=[\"has-info-container\"],\n            )\n            use_cot_language = gr.Checkbox(\n                label=t(\"generation.cot_language_label\"),\n                value=True,\n                info=t(\"generation.cot_language_info\"),\n                scale=1,\n                elem_classes=[\"has-info-container\"],\n            )\n            constrained_decoding_debug = gr.Checkbox(\n                label=t(\"generation.constrained_debug_label\"),\n                value=False,\n                info=t(\"generation.constrained_debug_info\"),\n                scale=1,\n                interactive=not service_mode,\n            )\n        with gr.Row():\n            allow_lm_batch = gr.Checkbox(\n                label=t(\"generation.parallel_thinking_label\"),\n                value=True,\n                info=t(\"generation.parallel_thinking_info\"),\n                scale=1,\n                elem_classes=[\"has-info-container\"],\n            )\n            use_cot_caption = gr.Checkbox(\n                label=t(\"generation.caption_rewrite_label\"),\n                value=False,\n                info=t(\"generation.caption_rewrite_info\"),\n                scale=1,\n                elem_classes=[\"has-info-container\"],\n            )\n\n    return {\n        \"lm_temperature\": lm_temperature,\n        \"lm_cfg_scale\": lm_cfg_scale,\n        \"lm_top_k\": lm_top_k,\n        \"lm_top_p\": lm_top_p,\n        \"lm_negative_prompt\": lm_negative_prompt,\n        \"use_cot_metas\": use_cot_metas,\n        \"use_cot_language\": use_cot_language,\n        \"constrained_decoding_debug\": constrained_decoding_debug,\n        \"allow_lm_batch\": allow_lm_batch,\n        \"use_cot_caption\": use_cot_caption,\n    }\n"
  },
  {
    "path": "acestep/ui/gradio/interfaces/generation_advanced_settings.py",
    "content": "\"\"\"Top-level advanced settings builder for generation UI.\"\"\"\n\nfrom typing import Any\n\nimport gradio as gr\n\nfrom acestep.ui.gradio.events.generation_handlers import (\n    is_pure_base_model,\n    is_sft_model,\n    get_ui_control_config,\n)\nfrom acestep.ui.gradio.i18n import t\n\nfrom .generation_advanced_dit_controls import build_dit_controls\nfrom .generation_advanced_output_controls import (\n    build_automation_controls,\n    build_output_controls,\n)\nfrom .generation_advanced_primary_controls import (\n    build_lm_controls,\n    build_lora_controls,\n)\nfrom .generation_defaults import compute_init_defaults\nfrom .generation_service_config import create_service_config_content\n\n\ndef create_advanced_settings_section(\n    dit_handler: Any,\n    llm_handler: Any,\n    init_params: dict[str, Any] | None = None,\n    language: str = \"en\",\n) -> dict[str, Any]:\n    \"\"\"Create the Settings accordion and return advanced generation controls.\n\n    Args:\n        dit_handler: DiT service handler used for model-aware control defaults.\n        llm_handler: LM service handler used for LM/service configuration controls.\n        init_params: Optional startup state used to prefill control values.\n        language: UI language code.\n\n    Returns:\n        A merged component map for service, LoRA, DiT, LM, output, and automation controls.\n    \"\"\"\n\n    defaults = compute_init_defaults(init_params, language)\n    service_pre_initialized = defaults[\"service_pre_initialized\"]\n    service_mode = defaults[\"service_mode\"]\n\n    if service_pre_initialized and init_params and \"dit_handler\" in init_params:\n        config_path = init_params.get(\"config_path\", \"\")\n        is_turbo_model = init_params[\"dit_handler\"].is_turbo_model()\n        config_lower = (config_path or \"\").lower()\n        ui_config = get_ui_control_config(\n            is_turbo_model,\n            is_pure_base=is_pure_base_model(config_lower),\n            is_sft=is_sft_model(config_lower),\n        )\n    else:\n        ui_config = get_ui_control_config(True)\n\n    with gr.Accordion(\n        t(\"generation.advanced_settings\"),\n        open=not service_pre_initialized,\n    ) as advanced_settings_accordion:\n        service_components = create_service_config_content(\n            dit_handler=dit_handler,\n            llm_handler=llm_handler,\n            defaults=defaults,\n            init_params=init_params,\n        )\n        lora_components = build_lora_controls()\n        dit_components = build_dit_controls(ui_config)\n        lm_components = build_lm_controls(service_mode=service_mode)\n        output_components = build_output_controls(\n            service_pre_initialized=service_pre_initialized,\n            service_mode=service_mode,\n            init_params=init_params,\n        )\n        automation_components = build_automation_controls(service_mode=service_mode)\n\n    result: dict[str, Any] = {\"advanced_settings_accordion\": advanced_settings_accordion}\n    result.update(dit_components)\n    result.update(lm_components)\n    result.update(output_components)\n    result.update(automation_components)\n    result.update(lora_components)\n    result.update(service_components)\n    return result\n"
  },
  {
    "path": "acestep/ui/gradio/interfaces/generation_contract_ast_utils.py",
    "content": "\"\"\"AST utility helpers for generation interface decomposition contract tests.\"\"\"\n\nimport ast\nfrom pathlib import Path\n\n\nINTERFACES_DIR = Path(__file__).resolve().parent\nWIRING_DIR = INTERFACES_DIR.parent / \"events\" / \"wiring\"\n\n\ndef load_module(module_name: str) -> ast.Module:\n    \"\"\"Parse and return AST for a generation interface module.\n\n    Args:\n        module_name: Filename under ``acestep/ui/gradio/interfaces`` to parse.\n\n    Returns:\n        Parsed ``ast.Module`` tree for the requested module.\n    \"\"\"\n\n    path = INTERFACES_DIR / module_name\n    return ast.parse(path.read_text(encoding=\"utf-8\"))\n\n\ndef call_name(node: ast.AST) -> str | None:\n    \"\"\"Extract a simple call-target name from an AST call function node.\n\n    Args:\n        node: AST node representing a call target expression.\n\n    Returns:\n        The simple function/attribute name when resolvable; otherwise ``None``.\n    \"\"\"\n\n    if isinstance(node, ast.Name):\n        return node.id\n    if isinstance(node, ast.Attribute):\n        return node.attr\n    return None\n\n\ndef collect_return_dict_keys(module_name: str, function_name: str) -> set[str]:\n    \"\"\"Collect string keys from dict literals assigned/returned in a function.\n\n    Args:\n        module_name: Module filename under ``interfaces`` to inspect.\n        function_name: Function name whose body should be scanned.\n\n    Returns:\n        Set of string keys found in literal dict assignments/updates/returns.\n    \"\"\"\n\n    module = load_module(module_name)\n    function_node = None\n    for node in module.body:\n        if isinstance(node, ast.FunctionDef) and node.name == function_name:\n            function_node = node\n            break\n    if function_node is None:\n        raise AssertionError(f\"{function_name} not found in {module_name}\")\n\n    keys: set[str] = set()\n    for node in ast.walk(function_node):\n        if isinstance(node, ast.Assign) and isinstance(node.value, ast.Dict):\n            for key in node.value.keys:\n                if isinstance(key, ast.Constant) and isinstance(key.value, str):\n                    keys.add(key.value)\n        if isinstance(node, ast.AnnAssign) and isinstance(node.value, ast.Dict):\n            for key in node.value.keys:\n                if isinstance(key, ast.Constant) and isinstance(key.value, str):\n                    keys.add(key.value)\n        if isinstance(node, ast.Call) and isinstance(node.func, ast.Attribute) and node.func.attr == \"update\":\n            if node.args and isinstance(node.args[0], ast.Dict):\n                for key in node.args[0].keys:\n                    if isinstance(key, ast.Constant) and isinstance(key.value, str):\n                        keys.add(key.value)\n        if isinstance(node, ast.Return) and isinstance(node.value, ast.Dict):\n            for key in node.value.keys:\n                if isinstance(key, ast.Constant) and isinstance(key.value, str):\n                    keys.add(key.value)\n    return keys\n\n\ndef collect_generation_section_keys_used_by_wiring() -> set[str]:\n    \"\"\"Collect generation-section keys referenced by wiring modules.\n\n    Args:\n        None.\n\n    Returns:\n        Set of ``generation_section[...]`` keys consumed by wiring modules.\n    \"\"\"\n\n    keys: set[str] = set()\n    for path in WIRING_DIR.glob(\"*.py\"):\n        module = ast.parse(path.read_text(encoding=\"utf-8\"))\n        for node in ast.walk(module):\n            if not isinstance(node, ast.Subscript):\n                continue\n            if not isinstance(node.value, ast.Name) or node.value.id != \"generation_section\":\n                continue\n            if isinstance(node.slice, ast.Constant) and isinstance(node.slice.value, str):\n                keys.add(node.slice.value)\n    return keys\n"
  },
  {
    "path": "acestep/ui/gradio/interfaces/generation_decomposition_contract_test.py",
    "content": "\"\"\"AST contract tests for generation interface decomposition.\"\"\"\n\nimport ast\nimport unittest\n\ntry:\n    from .generation_contract_ast_utils import (\n        call_name,\n        collect_generation_section_keys_used_by_wiring,\n        collect_return_dict_keys,\n        load_module,\n    )\nexcept ImportError:\n    from generation_contract_ast_utils import (  # type: ignore[no-redef]\n        call_name,\n        collect_generation_section_keys_used_by_wiring,\n        collect_return_dict_keys,\n        load_module,\n    )\n\n\nclass GenerationDecompositionContractTests(unittest.TestCase):\n    \"\"\"Verify that generation interface facade delegates to focused helpers.\"\"\"\n\n    def test_generation_facade_imports(self):\n        \"\"\"`generation.py` should import advanced-settings, service, and tab helpers.\"\"\"\n\n        module = load_module(\"generation.py\")\n        imported_modules = []\n        for node in ast.walk(module):\n            if isinstance(node, ast.ImportFrom) and node.module:\n                imported_modules.append(node.module)\n\n        self.assertIn(\"generation_advanced_settings\", imported_modules)\n        self.assertIn(\"generation_service_config\", imported_modules)\n        self.assertIn(\"generation_tab_section\", imported_modules)\n\n    def test_generation_facade_merges_sections(self):\n        \"\"\"`generation.py` should compose settings/tab sections into a merged map.\"\"\"\n\n        module = load_module(\"generation.py\")\n        call_names = []\n        update_calls = 0\n        for node in ast.walk(module):\n            if not isinstance(node, ast.Call):\n                continue\n            name = call_name(node.func)\n            if name:\n                call_names.append(name)\n            if isinstance(node.func, ast.Attribute) and node.func.attr == \"update\":\n                update_calls += 1\n\n        self.assertIn(\"create_advanced_settings_section\", call_names)\n        self.assertIn(\"create_generation_tab_section\", call_names)\n        self.assertGreaterEqual(update_calls, 2)\n\n    def test_generation_facade_exposes_required_public_symbols(self):\n        \"\"\"Facade should expose key constructors imported by interfaces package.\"\"\"\n\n        module = load_module(\"generation.py\")\n        names = set()\n        for node in module.body:\n            if isinstance(node, ast.FunctionDef):\n                names.add(node.name)\n            if isinstance(node, ast.ImportFrom):\n                for alias in node.names:\n                    names.add(alias.asname or alias.name)\n\n        self.assertIn(\"create_advanced_settings_section\", names)\n        self.assertIn(\"create_generation_tab_section\", names)\n        self.assertIn(\"create_service_config_section\", names)\n\n    def test_advanced_settings_section_delegates_to_control_builders(self):\n        \"\"\"Advanced settings should compose service/lora/dit/lm/output helpers.\"\"\"\n\n        module = load_module(\"generation_advanced_settings.py\")\n        call_names = []\n        for node in ast.walk(module):\n            if isinstance(node, ast.Call):\n                name = call_name(node.func)\n                if name:\n                    call_names.append(name)\n\n        self.assertIn(\"create_service_config_content\", call_names)\n        self.assertIn(\"build_lora_controls\", call_names)\n        self.assertIn(\"build_dit_controls\", call_names)\n        self.assertIn(\"build_lm_controls\", call_names)\n        self.assertIn(\"build_output_controls\", call_names)\n        self.assertIn(\"build_automation_controls\", call_names)\n\n    def test_generation_tab_section_delegates_to_component_builders(self):\n        \"\"\"Generation tab should compose focused primary/secondary/runtime helpers.\"\"\"\n\n        module = load_module(\"generation_tab_section.py\")\n        call_names = []\n        for node in ast.walk(module):\n            if isinstance(node, ast.Call):\n                name = call_name(node.func)\n                if name:\n                    call_names.append(name)\n\n        self.assertIn(\"build_mode_selector_controls\", call_names)\n        self.assertIn(\"build_hidden_generation_state\", call_names)\n        self.assertIn(\"build_simple_mode_controls\", call_names)\n        self.assertIn(\"build_source_track_and_code_controls\", call_names)\n        self.assertIn(\"build_cover_strength_controls\", call_names)\n        self.assertIn(\"build_custom_mode_controls\", call_names)\n        self.assertIn(\"build_repainting_controls\", call_names)\n        self.assertIn(\"build_optional_parameter_controls\", call_names)\n        self.assertIn(\"build_generate_row_controls\", call_names)\n\n    def test_service_config_section_delegates_to_row_and_toggle_helpers(self):\n        \"\"\"Service config section should compose row/toggle helper builders.\"\"\"\n\n        module = load_module(\"generation_service_config.py\")\n        call_names = []\n        for node in ast.walk(module):\n            if isinstance(node, ast.Call):\n                name = call_name(node.func)\n                if name:\n                    call_names.append(name)\n\n        self.assertIn(\"build_language_selector\", call_names)\n        self.assertIn(\"build_gpu_info_and_tier\", call_names)\n        self.assertIn(\"build_checkpoint_controls\", call_names)\n        self.assertIn(\"build_model_device_controls\", call_names)\n        self.assertIn(\"build_lm_backend_controls\", call_names)\n        self.assertIn(\"build_service_toggles\", call_names)\n        self.assertIn(\"build_service_init_controls\", call_names)\n\n    def test_generation_keys_cover_all_wiring_generation_section_requirements(self):\n        \"\"\"Returned generation keys should cover all keys consumed by wiring modules.\"\"\"\n\n        produced_keys: set[str] = set()\n        key_sources = [\n            (\"generation_tab_section.py\", \"create_generation_tab_section\"),\n            (\"generation_advanced_settings.py\", \"create_advanced_settings_section\"),\n            (\"generation_service_config.py\", \"create_service_config_content\"),\n            (\"generation_tab_primary_controls.py\", \"build_mode_selector_controls\"),\n            (\"generation_tab_primary_controls.py\", \"build_hidden_generation_state\"),\n            (\"generation_tab_simple_controls.py\", \"build_simple_mode_controls\"),\n            (\"generation_tab_source_controls.py\", \"build_source_track_and_code_controls\"),\n            (\"generation_tab_secondary_controls.py\", \"build_cover_strength_controls\"),\n            (\"generation_tab_secondary_controls.py\", \"build_custom_mode_controls\"),\n            (\"generation_tab_secondary_controls.py\", \"build_repainting_controls\"),\n            (\"generation_tab_optional_controls.py\", \"build_optional_parameter_controls\"),\n            (\"generation_tab_generate_controls.py\", \"build_generate_row_controls\"),\n            (\"generation_advanced_dit_controls.py\", \"build_dit_controls\"),\n            (\"generation_advanced_primary_controls.py\", \"build_lm_controls\"),\n            (\"generation_advanced_primary_controls.py\", \"build_lora_controls\"),\n            (\"generation_advanced_output_controls.py\", \"build_output_controls\"),\n            (\"generation_advanced_output_controls.py\", \"build_automation_controls\"),\n            (\"generation_service_config_rows.py\", \"build_language_selector\"),\n            (\"generation_service_config_rows.py\", \"build_gpu_info_and_tier\"),\n            (\"generation_service_config_rows.py\", \"build_checkpoint_controls\"),\n            (\"generation_service_config_rows.py\", \"build_model_device_controls\"),\n            (\"generation_service_config_rows.py\", \"build_lm_backend_controls\"),\n            (\"generation_service_config_toggles.py\", \"build_service_toggles\"),\n            (\"generation_service_config_toggles.py\", \"build_service_init_controls\"),\n        ]\n        for module_name, function_name in key_sources:\n            produced_keys |= collect_return_dict_keys(module_name, function_name)\n        produced_keys.discard(\"device_value\")\n\n        required_keys = collect_generation_section_keys_used_by_wiring()\n        self.assertTrue(\n            required_keys.issubset(produced_keys),\n            f\"Missing generation_section keys: {sorted(required_keys - produced_keys)}\",\n        )\n\n\nif __name__ == \"__main__\":\n    unittest.main()\n"
  },
  {
    "path": "acestep/ui/gradio/interfaces/generation_defaults.py",
    "content": "\"\"\"Shared defaults/helpers for generation interface builders.\"\"\"\n\nimport sys\nfrom typing import Any\n\nfrom acestep.gpu_config import GPUConfig, get_global_gpu_config\nfrom acestep.ui.gradio.events.generation_handlers import is_pure_base_model\n\n\ndef compute_init_defaults(\n    init_params: dict[str, Any] | None,\n    language: str,\n) -> dict[str, Any]:\n    \"\"\"Compute normalized defaults shared by generation interface sections.\n\n    Args:\n        init_params: Optional startup parameters passed to the UI layer.\n        language: Fallback language code when no language is present in init params.\n\n    Returns:\n        A dictionary with computed service, GPU, and control-default values.\n    \"\"\"\n\n    service_pre_initialized = init_params is not None and init_params.get(\"pre_initialized\", False)\n    service_mode = init_params is not None and init_params.get(\"service_mode\", False)\n    current_language = init_params.get(\"language\", language) if init_params else language\n\n    gpu_config: GPUConfig | None = init_params.get(\"gpu_config\") if init_params else None\n    if gpu_config is None:\n        gpu_config = get_global_gpu_config()\n\n    lm_initialized = init_params.get(\"init_llm\", False) if init_params else False\n    max_duration = (\n        gpu_config.max_duration_with_lm\n        if lm_initialized\n        else gpu_config.max_duration_without_lm\n    )\n    max_batch_size = (\n        gpu_config.max_batch_size_with_lm\n        if lm_initialized\n        else gpu_config.max_batch_size_without_lm\n    )\n\n    cli_batch_size = (init_params or {}).get(\"default_batch_size\")\n    if cli_batch_size is not None:\n        default_batch_size = min(cli_batch_size, max_batch_size)\n    else:\n        default_batch_size = min(2, max_batch_size)\n\n    init_lm_default = gpu_config.init_lm_default\n    default_offload = gpu_config.offload_to_cpu_default\n    default_offload_dit = gpu_config.offload_dit_to_cpu_default\n\n    try:\n        import torch\n\n        if hasattr(torch, \"xpu\") and torch.xpu.is_available():\n            default_offload = False\n            default_offload_dit = False\n    except ImportError:\n        pass\n\n    default_quantization = gpu_config.quantization_default\n    default_compile = gpu_config.compile_model_default\n    if sys.platform == \"darwin\":\n        default_quantization = False\n        default_compile = False\n\n    if gpu_config.lm_backend_restriction == \"pt_mlx_only\":\n        available_backends = [\"pt\", \"mlx\"]\n    else:\n        available_backends = [\"vllm\", \"pt\", \"mlx\"]\n    recommended_backend = gpu_config.recommended_backend\n    if recommended_backend not in available_backends:\n        recommended_backend = available_backends[0]\n\n    return {\n        \"service_pre_initialized\": service_pre_initialized,\n        \"service_mode\": service_mode,\n        \"current_language\": current_language,\n        \"gpu_config\": gpu_config,\n        \"lm_initialized\": lm_initialized,\n        \"max_duration\": max_duration,\n        \"max_batch_size\": max_batch_size,\n        \"default_batch_size\": default_batch_size,\n        \"init_lm_default\": init_lm_default,\n        \"default_offload\": default_offload,\n        \"default_offload_dit\": default_offload_dit,\n        \"default_quantization\": default_quantization,\n        \"default_compile\": default_compile,\n        \"available_backends\": available_backends,\n        \"recommended_backend\": recommended_backend,\n        \"recommended_lm\": gpu_config.recommended_lm_model,\n    }\n\n\ndef resolve_is_pure_base_model(\n    dit_handler: Any,\n    init_params: dict[str, Any] | None,\n    service_pre_initialized: bool,\n) -> bool:\n    \"\"\"Resolve whether current model selection should use pure-base mode behavior.\n\n    Args:\n        dit_handler: DiT handler used to inspect available model names.\n        init_params: Optional startup parameters that may include selected config path.\n        service_pre_initialized: Whether service was already initialized before UI render.\n\n    Returns:\n        ``True`` when the selected model should use base-only generation mode options.\n    \"\"\"\n\n    if service_pre_initialized and init_params and \"dit_handler\" in init_params:\n        config_path = init_params.get(\"config_path\", \"\")\n        return is_pure_base_model((config_path or \"\").lower())\n\n    available_models = dit_handler.get_available_acestep_v15_models()\n    default_model = (\n        \"acestep-v15-turbo\"\n        if \"acestep-v15-turbo\" in available_models\n        else (available_models[0] if available_models else None)\n    )\n    actual_model = init_params.get(\"config_path\", default_model) if init_params else default_model\n    return is_pure_base_model((actual_model or \"\").lower())\n"
  },
  {
    "path": "acestep/ui/gradio/interfaces/generation_service_config.py",
    "content": "\"\"\"Service-configuration builders for the generation interface.\"\"\"\n\nfrom typing import Any\n\nimport gradio as gr\n\nfrom acestep.ui.gradio.help_content import create_help_button\nfrom acestep.ui.gradio.i18n import t\n\nfrom .generation_defaults import compute_init_defaults\nfrom .generation_service_config_rows import (\n    build_checkpoint_controls,\n    build_gpu_info_and_tier,\n    build_language_selector,\n    build_lm_backend_controls,\n    build_model_device_controls,\n)\nfrom .generation_service_config_toggles import (\n    build_service_init_controls,\n    build_service_toggles,\n)\n\n\ndef create_service_config_content(\n    dit_handler: Any,\n    llm_handler: Any,\n    defaults: dict[str, Any],\n    init_params: dict[str, Any] | None,\n) -> dict[str, Any]:\n    \"\"\"Build service-configuration controls embedded inside the Settings accordion.\n\n    Args:\n        dit_handler: DiT service handler used for checkpoint/model/device options.\n        llm_handler: LM service handler used for LM model/backend options.\n        defaults: Precomputed defaults from ``compute_init_defaults``.\n        init_params: Optional startup state used to prefill control values.\n\n    Returns:\n        A keyed component dictionary for all service configuration controls.\n    \"\"\"\n\n    params = init_params or {}\n    service_pre_initialized = defaults[\"service_pre_initialized\"]\n    service_mode = defaults[\"service_mode\"]\n\n    with gr.Accordion(\n        t(\"service.title\"),\n        open=not service_pre_initialized,\n        visible=not service_mode,\n        elem_classes=[\"has-info-container\"],\n    ) as service_config_accordion:\n        create_help_button(\"service_config\")\n        language_controls = build_language_selector(defaults[\"current_language\"])\n        gpu_controls = build_gpu_info_and_tier(defaults[\"gpu_config\"])\n        checkpoint_controls = build_checkpoint_controls(\n            dit_handler=dit_handler,\n            service_pre_initialized=service_pre_initialized,\n            params=params,\n        )\n        model_device_controls = build_model_device_controls(\n            dit_handler=dit_handler,\n            service_pre_initialized=service_pre_initialized,\n            params=params,\n        )\n        lm_backend_controls = build_lm_backend_controls(\n            llm_handler=llm_handler,\n            service_pre_initialized=service_pre_initialized,\n            params=params,\n            recommended_lm=defaults[\"recommended_lm\"],\n            available_backends=defaults[\"available_backends\"],\n            recommended_backend=defaults[\"recommended_backend\"],\n            gpu_config=defaults[\"gpu_config\"],\n        )\n        toggle_controls = build_service_toggles(\n            dit_handler=dit_handler,\n            device_value=model_device_controls[\"device_value\"],\n            service_pre_initialized=service_pre_initialized,\n            params=params,\n            init_lm_default=defaults[\"init_lm_default\"],\n            default_offload=defaults[\"default_offload\"],\n            default_offload_dit=defaults[\"default_offload_dit\"],\n            default_compile=defaults[\"default_compile\"],\n            default_quantization=defaults[\"default_quantization\"],\n            gpu_config=defaults[\"gpu_config\"],\n        )\n        init_controls = build_service_init_controls(\n            service_pre_initialized=service_pre_initialized,\n            params=params,\n        )\n\n    result: dict[str, Any] = {\"service_config_accordion\": service_config_accordion}\n    result.update(language_controls)\n    result.update(gpu_controls)\n    result.update(checkpoint_controls)\n    result.update(\n        {\n            \"config_path\": model_device_controls[\"config_path\"],\n            \"device\": model_device_controls[\"device\"],\n        }\n    )\n    result.update(lm_backend_controls)\n    result.update(toggle_controls)\n    result.update(init_controls)\n    result[\"gpu_config\"] = defaults[\"gpu_config\"]\n    return result\n\n\ndef create_service_config_section(\n    dit_handler: Any,\n    llm_handler: Any,\n    init_params: dict[str, Any] | None = None,\n    language: str = \"en\",\n) -> dict[str, Any]:\n    \"\"\"Build the legacy standalone service-config map for compatibility callers.\n\n    Args:\n        dit_handler: DiT service handler used to build service controls.\n        llm_handler: LM service handler used to build service controls.\n        init_params: Optional startup state used to prefill control values.\n        language: UI language code.\n\n    Returns:\n        A keyed component dictionary matching the legacy service-config contract.\n    \"\"\"\n\n    defaults = compute_init_defaults(init_params, language)\n    return create_service_config_content(dit_handler, llm_handler, defaults, init_params)\n"
  },
  {
    "path": "acestep/ui/gradio/interfaces/generation_service_config_rows.py",
    "content": "\"\"\"Row builders for generation service configuration section.\"\"\"\n\nfrom typing import Any\n\nimport gradio as gr\n\nfrom acestep.gpu_config import (\n    GPU_TIER_LABELS,\n    find_best_lm_model_on_disk,\n    get_gpu_device_name,\n)\nfrom acestep.ui.gradio.i18n import t, available_languages_info\n\n\ndef build_language_selector(current_language: str) -> dict[str, Any]:\n    \"\"\"Create the service-language selector row.\n\n    Args:\n        current_language: Preselected UI language code.\n\n    Returns:\n        A component map containing the ``language_dropdown`` control.\n    \"\"\"\n\n    with gr.Row():\n        language_dropdown = gr.Dropdown(\n            choices=[(native_name + f\" ({name})\" if name != native_name else name, code) for code, name, native_name in available_languages_info()],\n            value=current_language,\n            label=t(\"service.language_label\"),\n            info=t(\"service.language_info\"),\n            interactive=True,\n            elem_classes=[\"has-info-container\"],\n            scale=1,\n        )\n    return {\"language_dropdown\": language_dropdown}\n\n\ndef build_gpu_info_and_tier(gpu_config: Any) -> dict[str, Any]:\n    \"\"\"Create GPU info display and manual tier override controls.\n\n    Args:\n        gpu_config: Active GPU configuration object with tier and VRAM metadata.\n\n    Returns:\n        A component map containing ``gpu_info_display`` and ``tier_dropdown``.\n    \"\"\"\n\n    gpu_text = (\n        f\"\\U0001f5a5\\ufe0f **{get_gpu_device_name()}** \\u2014 {gpu_config.gpu_memory_gb:.1f} GB VRAM \"\n        f\"\\u2014 {t('service.gpu_auto_tier')}: **{GPU_TIER_LABELS.get(gpu_config.tier, gpu_config.tier)}**\"\n    )\n    with gr.Row():\n        gpu_info_display = gr.Markdown(value=gpu_text)\n    with gr.Row():\n        tier_dropdown = gr.Dropdown(\n            choices=[(label, key) for key, label in GPU_TIER_LABELS.items()],\n            value=gpu_config.tier,\n            label=t(\"service.tier_label\"),\n            info=t(\"service.tier_info\"),\n            elem_classes=[\"has-info-container\"],\n            scale=1,\n        )\n    return {\"gpu_info_display\": gpu_info_display, \"tier_dropdown\": tier_dropdown}\n\n\ndef build_checkpoint_controls(dit_handler: Any, service_pre_initialized: bool, params: dict[str, Any]) -> dict[str, Any]:\n    \"\"\"Create checkpoint selection and refresh controls.\n\n    Args:\n        dit_handler: DiT handler used to list available checkpoints.\n        service_pre_initialized: Whether existing init params should prefill values.\n        params: Startup state dictionary containing optional checkpoint value.\n\n    Returns:\n        A component map containing ``checkpoint_dropdown`` and ``refresh_btn``.\n    \"\"\"\n\n    with gr.Row(equal_height=True):\n        with gr.Column(scale=4):\n            checkpoint_dropdown = gr.Dropdown(\n                label=t(\"service.checkpoint_label\"),\n                choices=dit_handler.get_available_checkpoints(),\n                value=params.get(\"checkpoint\") if service_pre_initialized else None,\n                info=t(\"service.checkpoint_info\"),\n                elem_classes=[\"has-info-container\"],\n            )\n        with gr.Column(scale=1, min_width=90):\n            refresh_btn = gr.Button(t(\"service.refresh_btn\"), size=\"sm\")\n    return {\"checkpoint_dropdown\": checkpoint_dropdown, \"refresh_btn\": refresh_btn}\n\n\ndef build_model_device_controls(\n    dit_handler: Any,\n    service_pre_initialized: bool,\n    params: dict[str, Any],\n) -> dict[str, Any]:\n    \"\"\"Create model-path and device selection controls.\n\n    Args:\n        dit_handler: DiT handler used to list available model configs.\n        service_pre_initialized: Whether existing init params should prefill values.\n        params: Startup state dictionary containing optional model/device values.\n\n    Returns:\n        A component map containing ``config_path``, ``device``, and ``device_value``.\n    \"\"\"\n\n    with gr.Row():\n        available_models = dit_handler.get_available_acestep_v15_models()\n        default_model = (\n            \"acestep-v15-turbo\"\n            if \"acestep-v15-turbo\" in available_models\n            else (available_models[0] if available_models else None)\n        )\n        config_path = gr.Dropdown(\n            label=t(\"service.model_path_label\"),\n            choices=available_models,\n            value=params.get(\"config_path\", default_model) if service_pre_initialized else default_model,\n            info=t(\"service.model_path_info\"),\n            elem_classes=[\"has-info-container\"],\n        )\n        device_value = params.get(\"device\", \"auto\") if service_pre_initialized else \"auto\"\n        device = gr.Dropdown(\n            choices=[\"auto\", \"cuda\", \"mps\", \"xpu\", \"cpu\"],\n            value=device_value,\n            label=t(\"service.device_label\"),\n            info=t(\"service.device_info\"),\n            elem_classes=[\"has-info-container\"],\n        )\n    return {\n        \"config_path\": config_path,\n        \"device\": device,\n        \"device_value\": device_value,\n    }\n\n\ndef build_lm_backend_controls(\n    llm_handler: Any,\n    service_pre_initialized: bool,\n    params: dict[str, Any],\n    recommended_lm: str | None,\n    available_backends: list[str],\n    recommended_backend: str,\n    gpu_config: Any,\n) -> dict[str, Any]:\n    \"\"\"Create LM model-path and backend selector controls.\n\n    Args:\n        llm_handler: LM handler used to list available LM model choices.\n        service_pre_initialized: Whether existing init params should prefill values.\n        params: Startup state dictionary containing optional LM/backend values.\n        recommended_lm: Recommended LM model identifier for this tier.\n        available_backends: Backend choices allowed for current environment.\n        recommended_backend: Preferred backend selected by defaults logic.\n        gpu_config: GPU configuration object used for backend info text.\n\n    Returns:\n        A component map containing ``lm_model_path`` and ``backend_dropdown``.\n    \"\"\"\n\n    with gr.Row():\n        all_lm_models = llm_handler.get_available_5hz_lm_models()\n        default_lm_model = find_best_lm_model_on_disk(recommended_lm, all_lm_models)\n        lm_model_path = gr.Dropdown(\n            label=t(\"service.lm_model_path_label\"),\n            choices=all_lm_models,\n            value=params.get(\"lm_model_path\", default_lm_model) if service_pre_initialized else default_lm_model,\n            info=t(\"service.lm_model_path_info\")\n            + (\n                f\" (Recommended: {recommended_lm})\"\n                if recommended_lm\n                else \" (LM not available for this GPU tier)\"\n            ),\n            elem_classes=[\"has-info-container\"],\n        )\n        backend_dropdown = gr.Dropdown(\n            choices=available_backends,\n            value=params.get(\"backend\", recommended_backend) if service_pre_initialized else recommended_backend,\n            label=t(\"service.backend_label\"),\n            info=t(\"service.backend_info\")\n            + (\n                f\" (vllm unavailable for {gpu_config.tier}: VRAM too low)\"\n                if gpu_config.lm_backend_restriction == \"pt_mlx_only\"\n                else \"\"\n            ),\n            elem_classes=[\"has-info-container\"],\n        )\n    return {\n        \"lm_model_path\": lm_model_path,\n        \"backend_dropdown\": backend_dropdown,\n    }\n"
  },
  {
    "path": "acestep/ui/gradio/interfaces/generation_service_config_rows_test.py",
    "content": "\"\"\"Contract tests for generation service-config row builders.\"\"\"\n\nimport ast\nfrom pathlib import Path\nimport unittest\n\n\n_ROWS_PATH = Path(__file__).resolve().parent / \"generation_service_config_rows.py\"\n\n\nclass GenerationServiceConfigRowsTests(unittest.TestCase):\n    \"\"\"Verify service row builder contracts needed by the UI wiring.\"\"\"\n\n    def test_language_dropdown_is_explicitly_interactive(self):\n        \"\"\"Language selector should remain interactive for runtime language selection.\"\"\"\n\n        module = ast.parse(_ROWS_PATH.read_text(encoding=\"utf-8\"))\n        func = next(\n            node\n            for node in module.body\n            if isinstance(node, ast.FunctionDef) and node.name == \"build_language_selector\"\n        )\n\n        dropdown_calls = [\n            node\n            for node in ast.walk(func)\n            if isinstance(node, ast.Call)\n            and isinstance(node.func, ast.Attribute)\n            and node.func.attr == \"Dropdown\"\n        ]\n        self.assertTrue(dropdown_calls, \"Expected a gr.Dropdown call in build_language_selector\")\n\n        interactive_kw = next(\n            (\n                kw\n                for kw in dropdown_calls[0].keywords\n                if kw.arg == \"interactive\"\n            ),\n            None,\n        )\n        self.assertIsNotNone(interactive_kw, \"language_dropdown should set interactive explicitly\")\n        self.assertIsInstance(interactive_kw.value, ast.Constant)\n        self.assertTrue(interactive_kw.value.value)\n\n\nif __name__ == \"__main__\":\n    unittest.main()\n"
  },
  {
    "path": "acestep/ui/gradio/interfaces/generation_service_config_toggles.py",
    "content": "\"\"\"Toggle and init controls for generation service configuration.\"\"\"\n\nfrom typing import Any\n\nimport gradio as gr\n\nfrom acestep.ui.gradio.i18n import t\n\ntry:\n    from acestep.models.mlx import mlx_available as _mlx_avail\nexcept ImportError:\n    def _mlx_avail() -> bool:\n        \"\"\"Return False when MLX dependency is unavailable.\"\"\"\n\n        return False\n\n\ndef build_service_toggles(\n    dit_handler: Any,\n    device_value: str,\n    service_pre_initialized: bool,\n    params: dict[str, Any],\n    init_lm_default: bool,\n    default_offload: bool,\n    default_offload_dit: bool,\n    default_compile: bool,\n    default_quantization: bool,\n    gpu_config: Any,\n) -> dict[str, Any]:\n    \"\"\"Create service toggle checkboxes for runtime and optimization settings.\n\n    Args:\n        dit_handler: DiT handler used for flash-attention capability detection.\n        device_value: Current device dropdown value used for availability checks.\n        service_pre_initialized: Whether existing init params should prefill values.\n        params: Startup state dictionary with optional toggle overrides.\n        init_lm_default: Default value for init-LLM toggle.\n        default_offload: Default value for LM offload-to-CPU toggle.\n        default_offload_dit: Default value for DiT offload-to-CPU toggle.\n        default_compile: Default value for compile-model toggle.\n        default_quantization: Default value for quantization toggle.\n        gpu_config: GPU configuration object used for LM availability messaging.\n\n    Returns:\n        A component map for all service toggles (LLM, flash attention, offload, compile, quantization, MLX).\n    \"\"\"\n\n    with gr.Row():\n        lm_info_text = t(\"service.init_llm_info\")\n        if not gpu_config.available_lm_models:\n            lm_info_text += \" \" + t(\"service.lm_unavailable_vram\")\n        init_llm_checkbox = gr.Checkbox(\n            label=t(\"service.init_llm_label\"),\n            value=params.get(\"init_llm\", init_lm_default) if service_pre_initialized else init_lm_default,\n            info=lm_info_text,\n            elem_classes=[\"has-info-container\"],\n        )\n\n        flash_attn_available = dit_handler.is_flash_attention_available(device_value)\n        use_flash_attention_checkbox = gr.Checkbox(\n            label=t(\"service.flash_attention_label\"),\n            value=params.get(\"use_flash_attention\", flash_attn_available)\n            if service_pre_initialized\n            else flash_attn_available,\n            interactive=flash_attn_available,\n            info=t(\"service.flash_attention_info_enabled\")\n            if flash_attn_available\n            else t(\"service.flash_attention_info_disabled\"),\n            elem_classes=[\"has-info-container\"],\n        )\n        offload_to_cpu_checkbox = gr.Checkbox(\n            label=t(\"service.offload_cpu_label\"),\n            value=params.get(\"offload_to_cpu\", default_offload) if service_pre_initialized else default_offload,\n            info=t(\"service.offload_cpu_info\")\n            + (\" (recommended for this tier)\" if default_offload else \" (optional for this tier)\"),\n            elem_classes=[\"has-info-container\"],\n        )\n        offload_dit_to_cpu_checkbox = gr.Checkbox(\n            label=t(\"service.offload_dit_cpu_label\"),\n            value=params.get(\"offload_dit_to_cpu\", default_offload_dit)\n            if service_pre_initialized\n            else default_offload_dit,\n            info=t(\"service.offload_dit_cpu_info\")\n            + (\" (recommended for this tier)\" if default_offload_dit else \" (optional for this tier)\"),\n            elem_classes=[\"has-info-container\"],\n        )\n        compile_model_checkbox = gr.Checkbox(\n            label=t(\"service.compile_model_label\"),\n            value=params.get(\"compile_model\", default_compile) if service_pre_initialized else default_compile,\n            info=t(\"service.compile_model_info\"),\n            elem_classes=[\"has-info-container\"],\n        )\n        quantization_checkbox = gr.Checkbox(\n            label=t(\"service.quantization_label\"),\n            value=params.get(\"quantization\", default_quantization) if service_pre_initialized else default_quantization,\n            info=t(\"service.quantization_info\")\n            + (\" (recommended for this tier)\" if default_quantization else \" (optional for this tier)\"),\n            elem_classes=[\"has-info-container\"],\n        )\n\n        mlx_ok = _mlx_avail()\n        mlx_dit_checkbox = gr.Checkbox(\n            label=t(\"service.mlx_dit_label\"),\n            value=params.get(\"mlx_dit\", mlx_ok) if service_pre_initialized else mlx_ok,\n            interactive=mlx_ok,\n            info=t(\"service.mlx_dit_info_enabled\") if mlx_ok else t(\"service.mlx_dit_info_disabled\"),\n            elem_classes=[\"has-info-container\"],\n        )\n    return {\n        \"init_llm_checkbox\": init_llm_checkbox,\n        \"use_flash_attention_checkbox\": use_flash_attention_checkbox,\n        \"offload_to_cpu_checkbox\": offload_to_cpu_checkbox,\n        \"offload_dit_to_cpu_checkbox\": offload_dit_to_cpu_checkbox,\n        \"compile_model_checkbox\": compile_model_checkbox,\n        \"quantization_checkbox\": quantization_checkbox,\n        \"mlx_dit_checkbox\": mlx_dit_checkbox,\n    }\n\n\ndef build_service_init_controls(service_pre_initialized: bool, params: dict[str, Any]) -> dict[str, Any]:\n    \"\"\"Create service initialization action and status controls.\n\n    Args:\n        service_pre_initialized: Whether existing init params should prefill status.\n        params: Startup state dictionary containing optional init status text.\n\n    Returns:\n        A component map containing ``init_btn`` and ``init_status``.\n    \"\"\"\n\n    init_btn = gr.Button(t(\"service.init_btn\"), variant=\"primary\", size=\"lg\")\n    init_status = gr.Textbox(\n        label=t(\"service.status_label\"),\n        interactive=False,\n        lines=3,\n        value=params.get(\"init_status\", \"\") if service_pre_initialized else \"\",\n    )\n    return {\"init_btn\": init_btn, \"init_status\": init_status}\n"
  },
  {
    "path": "acestep/ui/gradio/interfaces/generation_tab_generate_controls.py",
    "content": "\"\"\"Generate-row controls for the generation tab.\"\"\"\n\nfrom typing import Any\n\nimport gradio as gr\n\nfrom acestep.ui.gradio.i18n import t\n\n\ndef _build_left_generate_toggles(\n    lm_initialized: bool,\n    service_mode: bool,\n) -> tuple[gr.Checkbox, gr.Checkbox]:\n    \"\"\"Create the left-side runtime toggles shown next to the generate button.\n\n    Args:\n        lm_initialized: Whether LM is initialized, used to gate Think interactivity.\n        service_mode: Whether UI is in service mode, used to gate toggle interactivity.\n\n    Returns:\n        The ``think_checkbox`` and ``auto_score`` controls in creation order.\n    \"\"\"\n\n    with gr.Column(scale=1, variant=\"compact\"):\n        think_checkbox = gr.Checkbox(\n            label=t(\"generation.think_label\"),\n            value=lm_initialized,\n            visible=True,\n            scale=1,\n            interactive=lm_initialized,\n        )\n        auto_score = gr.Checkbox(\n            label=t(\"generation.auto_score_label\"),\n            value=False,\n            scale=1,\n            interactive=not service_mode,\n        )\n    return think_checkbox, auto_score\n\n\ndef _build_right_generate_toggles(service_mode: bool) -> tuple[gr.Checkbox, gr.Checkbox]:\n    \"\"\"Create the right-side runtime toggles shown next to the generate button.\n\n    Args:\n        service_mode: Whether UI is in service mode, used to gate toggle interactivity.\n\n    Returns:\n        The ``autogen_checkbox`` and ``auto_lrc`` controls in creation order.\n    \"\"\"\n\n    with gr.Column(scale=1, variant=\"compact\"):\n        autogen_checkbox = gr.Checkbox(\n            label=t(\"generation.autogen_label\"),\n            value=False,\n            scale=1,\n            interactive=not service_mode,\n        )\n        auto_lrc = gr.Checkbox(\n            label=t(\"generation.auto_lrc_label\"),\n            value=False,\n            scale=1,\n            interactive=not service_mode,\n        )\n    return autogen_checkbox, auto_lrc\n\n\ndef build_generate_row_controls(\n    service_pre_initialized: bool,\n    init_params: dict[str, Any] | None,\n    lm_initialized: bool,\n    service_mode: bool,\n) -> dict[str, Any]:\n    \"\"\"Compose generate-row controls from toggle helpers and the generate button.\n\n    Args:\n        service_pre_initialized: Whether startup params should prefill interactive defaults.\n        init_params: Optional startup state containing generate-button enable state.\n        lm_initialized: Whether LM is initialized, used to gate think-checkbox interactivity.\n        service_mode: Whether the UI is running in service mode (disables some controls).\n\n    Returns:\n        A component map containing generate button, runtime toggles, and row container.\n    \"\"\"\n\n    params = init_params or {}\n    generate_btn_interactive = params.get(\"enable_generate\", False) if service_pre_initialized else False\n    with gr.Row(equal_height=True, visible=True) as generate_btn_row:\n        think_checkbox, auto_score = _build_left_generate_toggles(\n            lm_initialized=lm_initialized,\n            service_mode=service_mode,\n        )\n        with gr.Column(scale=18):\n            generate_btn = gr.Button(\n                t(\"generation.generate_btn\"),\n                variant=\"primary\",\n                size=\"lg\",\n                interactive=generate_btn_interactive,\n                elem_id=\"acestep-generate-btn\",\n            )\n        autogen_checkbox, auto_lrc = _build_right_generate_toggles(service_mode=service_mode)\n    return {\n        \"think_checkbox\": think_checkbox,\n        \"auto_score\": auto_score,\n        \"generate_btn\": generate_btn,\n        \"generate_btn_row\": generate_btn_row,\n        \"autogen_checkbox\": autogen_checkbox,\n        \"auto_lrc\": auto_lrc,\n    }\n"
  },
  {
    "path": "acestep/ui/gradio/interfaces/generation_tab_optional_controls.py",
    "content": "\"\"\"Optional-parameter controls for the generation tab.\"\"\"\n\nfrom typing import Any\n\nimport gradio as gr\n\nfrom acestep.constants import VALID_LANGUAGES\nfrom acestep.ui.gradio.i18n import t\n\n\ndef build_optional_parameter_controls(\n    max_duration: float,\n    max_batch_size: int,\n    default_batch_size: int,\n    service_mode: bool,\n) -> dict[str, Any]:\n    \"\"\"Create optional generation metadata controls and auto-toggle controls.\n\n    Args:\n        max_duration: Maximum allowed duration derived from current GPU profile.\n        max_batch_size: Maximum allowed batch size derived from current GPU profile.\n        default_batch_size: Initial batch size value shown in the UI.\n        service_mode: Whether the UI is running in service mode (disables some controls).\n\n    Returns:\n        A component map containing optional metadata fields and auto-toggle controls.\n    \"\"\"\n\n    with gr.Accordion(\n        t(\"generation.optional_params\"),\n        open=True,\n        visible=True,\n        elem_classes=[\"has-info-container\"],\n    ) as optional_params_accordion:\n        with gr.Row():\n            bpm = gr.Number(\n                label=t(\"generation.bpm_label\"),\n                value=None,\n                step=1,\n                info=t(\"generation.bpm_info\"),\n                elem_classes=[\"has-info-container\"],\n                interactive=False,\n            )\n            key_scale = gr.Textbox(\n                label=t(\"generation.keyscale_label\"),\n                placeholder=t(\"generation.keyscale_placeholder\"),\n                value=\"\",\n                info=t(\"generation.keyscale_info\"),\n                elem_classes=[\"has-info-container\"],\n                interactive=False,\n            )\n            time_signature = gr.Dropdown(\n                choices=[\"\", \"2\", \"3\", \"4\", \"6\", \"N/A\"],\n                value=\"\",\n                label=t(\"generation.timesig_label\"),\n                allow_custom_value=True,\n                info=t(\"generation.timesig_info\"),\n                elem_classes=[\"has-info-container\"],\n                interactive=False,\n            )\n            vocal_language = gr.Dropdown(\n                choices=[(lang if lang != \"unknown\" else \"Instrumental / auto\", lang) for lang in VALID_LANGUAGES],\n                value=\"unknown\",\n                label=t(\"generation.vocal_language_label\"),\n                info=t(\"generation.vocal_language_info\"),\n                allow_custom_value=True,\n                elem_classes=[\"has-info-container\"],\n                interactive=False,\n            )\n        with gr.Row(elem_classes=[\"auto-toggles-row\"]):\n            bpm_auto = gr.Checkbox(\n                label=t(\"generation.bpm_auto_label\"),\n                value=True,\n                container=False,\n                elem_classes=[\"auto-toggle\"],\n            )\n            key_auto = gr.Checkbox(\n                label=t(\"generation.key_auto_label\"),\n                value=True,\n                container=False,\n                elem_classes=[\"auto-toggle\"],\n            )\n            timesig_auto = gr.Checkbox(\n                label=t(\"generation.timesig_auto_label\"),\n                value=True,\n                container=False,\n                elem_classes=[\"auto-toggle\"],\n            )\n            vocal_lang_auto = gr.Checkbox(\n                label=t(\"generation.vocal_lang_auto_label\"),\n                value=True,\n                container=False,\n                elem_classes=[\"auto-toggle\"],\n            )\n        with gr.Row():\n            audio_duration = gr.Number(\n                label=t(\"generation.duration_label\"),\n                value=-1,\n                minimum=-1,\n                maximum=float(max_duration),\n                step=0.1,\n                info=t(\"generation.duration_info\")\n                + f\" (Max: {max_duration}s / {max_duration // 60} min)\",\n                elem_classes=[\"has-info-container\"],\n                interactive=False,\n            )\n            batch_size_input = gr.Number(\n                label=t(\"generation.batch_size_label\"),\n                value=default_batch_size,\n                minimum=1,\n                maximum=max_batch_size,\n                step=1,\n                info=t(\"generation.batch_size_info\") + f\" (Max: {max_batch_size})\",\n                elem_classes=[\"has-info-container\"],\n                interactive=not service_mode,\n            )\n        with gr.Row(elem_classes=[\"auto-toggles-row\"]):\n            duration_auto = gr.Checkbox(\n                label=t(\"generation.duration_auto_label\"),\n                value=True,\n                container=False,\n                elem_classes=[\"auto-toggle\"],\n            )\n            gr.HTML(\"<span></span>\")\n        reset_all_auto_btn = gr.Button(t(\"generation.reset_all_auto\"), variant=\"secondary\", size=\"sm\")\n\n    return {\n        \"optional_params_accordion\": optional_params_accordion,\n        \"bpm\": bpm,\n        \"key_scale\": key_scale,\n        \"time_signature\": time_signature,\n        \"vocal_language\": vocal_language,\n        \"bpm_auto\": bpm_auto,\n        \"key_auto\": key_auto,\n        \"timesig_auto\": timesig_auto,\n        \"vocal_lang_auto\": vocal_lang_auto,\n        \"audio_duration\": audio_duration,\n        \"batch_size_input\": batch_size_input,\n        \"duration_auto\": duration_auto,\n        \"reset_all_auto_btn\": reset_all_auto_btn,\n    }\n"
  },
  {
    "path": "acestep/ui/gradio/interfaces/generation_tab_optional_controls_test.py",
    "content": "\"\"\"Contract tests for generation optional-parameter controls.\"\"\"\n\nimport ast\nfrom pathlib import Path\nimport unittest\n\n\n_OPTIONAL_PATH = Path(__file__).resolve().parent / \"generation_tab_optional_controls.py\"\n_EXPECTED_NAMES = {\n    \"bpm\",\n    \"key_scale\",\n    \"time_signature\",\n    \"vocal_language\",\n    \"audio_duration\",\n}\n\n\nclass GenerationTabOptionalControlsTests(unittest.TestCase):\n    \"\"\"Verify optional controls start locked when Auto toggles are enabled.\"\"\"\n\n    def test_optional_fields_default_to_non_interactive(self):\n        \"\"\"Optional controls should initialize with ``interactive=False``.\"\"\"\n\n        module = ast.parse(_OPTIONAL_PATH.read_text(encoding=\"utf-8\"))\n        func = next(\n            node\n            for node in module.body\n            if isinstance(node, ast.FunctionDef) and node.name == \"build_optional_parameter_controls\"\n        )\n\n        found: dict[str, ast.AST] = {}\n        for node in ast.walk(func):\n            if not isinstance(node, ast.Assign):\n                continue\n            if len(node.targets) != 1 or not isinstance(node.targets[0], ast.Name):\n                continue\n            target_name = node.targets[0].id\n            if target_name not in _EXPECTED_NAMES:\n                continue\n            if not isinstance(node.value, ast.Call):\n                continue\n            interactive_kw = next((kw for kw in node.value.keywords if kw.arg == \"interactive\"), None)\n            if interactive_kw is not None:\n                found[target_name] = interactive_kw.value\n\n        self.assertEqual(_EXPECTED_NAMES, set(found.keys()))\n        for field_name, expr in found.items():\n            self.assertIsInstance(expr, ast.Constant, f\"{field_name} should use constant False\")\n            self.assertFalse(expr.value, f\"{field_name} should default to non-interactive\")\n\n\nif __name__ == \"__main__\":\n    unittest.main()\n"
  },
  {
    "path": "acestep/ui/gradio/interfaces/generation_tab_primary_controls.py",
    "content": "\"\"\"Primary generation-tab controls shared across all generation modes.\"\"\"\n\nfrom typing import Any\n\nimport gradio as gr\n\nfrom acestep.constants import DEFAULT_DIT_INSTRUCTION\nfrom acestep.ui.gradio.i18n import t\n\nfrom .generation_tab_simple_controls import build_simple_mode_controls\nfrom .generation_tab_source_controls import build_source_track_and_code_controls\n\n\ndef build_mode_selector_controls(initial_mode_choices: list[str]) -> dict[str, Any]:\n    \"\"\"Create generation mode selector and load-metadata upload controls.\n\n    Args:\n        initial_mode_choices: Mode labels available for the currently selected model family.\n\n    Returns:\n        A component map containing ``generation_mode``, ``load_file``, and ``load_file_col``.\n    \"\"\"\n\n    with gr.Row(equal_height=True):\n        generation_mode = gr.Radio(\n            choices=initial_mode_choices,\n            value=\"Custom\",\n            label=t(\"generation.mode_label\"),\n            info=t(\"generation.mode_info_custom\"),\n            elem_classes=[\"has-info-container\"],\n            scale=10,\n        )\n        with gr.Column(scale=1, min_width=80, elem_classes=\"icon-btn-wrap\") as load_file_col:\n            load_file = gr.UploadButton(\n                t(\"generation.load_btn\"),\n                file_types=[\".json\"],\n                file_count=\"single\",\n                variant=\"secondary\",\n                size=\"lg\",\n            )\n    return {\n        \"generation_mode\": generation_mode,\n        \"load_file\": load_file,\n        \"load_file_col\": load_file_col,\n    }\n\n\ndef build_hidden_generation_state() -> dict[str, Any]:\n    \"\"\"Create hidden/state controls consumed by generation event wiring.\n\n    Args:\n        None.\n\n    Returns:\n        A component map containing hidden task/instruction fields and Gradio state objects.\n    \"\"\"\n\n    task_type = gr.Textbox(value=\"text2music\", visible=False, label=\"task_type\")\n    instruction_display_gen = gr.Textbox(\n        label=t(\"generation.instruction_label\"),\n        value=DEFAULT_DIT_INSTRUCTION,\n        interactive=False,\n        lines=1,\n        info=t(\"generation.instruction_info\"),\n        elem_classes=[\"has-info-container\"],\n        visible=False,\n    )\n    simple_sample_created = gr.State(value=False)\n    lyrics_before_instrumental = gr.State(value=\"\")\n    previous_generation_mode = gr.State(value=\"Custom\")\n    return {\n        \"task_type\": task_type,\n        \"instruction_display_gen\": instruction_display_gen,\n        \"simple_sample_created\": simple_sample_created,\n        \"lyrics_before_instrumental\": lyrics_before_instrumental,\n        \"previous_generation_mode\": previous_generation_mode,\n    }\n"
  },
  {
    "path": "acestep/ui/gradio/interfaces/generation_tab_runtime_controls.py",
    "content": "\"\"\"Facade exports for runtime generation-tab controls.\"\"\"\n\nfrom .generation_tab_generate_controls import build_generate_row_controls\nfrom .generation_tab_optional_controls import build_optional_parameter_controls\n"
  },
  {
    "path": "acestep/ui/gradio/interfaces/generation_tab_secondary_controls.py",
    "content": "\"\"\"Secondary generation-tab controls (cover, custom prompt, repaint).\"\"\"\n\nfrom typing import Any\n\nimport gradio as gr\n\nfrom acestep.ui.gradio.help_content import create_help_button\nfrom acestep.ui.gradio.i18n import t\n\n\ndef build_cover_strength_controls() -> dict[str, Any]:\n    \"\"\"Create code/remix strength controls used by non-simple generation modes.\n\n    Args:\n        None.\n\n    Returns:\n        A component map containing audio/code strength sliders and remix help group.\n    \"\"\"\n\n    audio_cover_strength = gr.Slider(\n        minimum=0.0,\n        maximum=1.0,\n        value=1.0,\n        step=0.01,\n        label=t(\"generation.codes_strength_label\"),\n        info=t(\"generation.codes_strength_info\"),\n        elem_classes=[\"has-info-container\"],\n        visible=True,\n    )\n    with gr.Group(visible=False) as remix_help_group:\n        create_help_button(\"generation_remix\")\n    cover_noise_strength = gr.Slider(\n        minimum=0.0,\n        maximum=1.0,\n        value=0.0,\n        step=0.01,\n        label=t(\"generation.cover_noise_strength_label\"),\n        info=t(\"generation.cover_noise_strength_info\"),\n        elem_classes=[\"has-info-container\"],\n        visible=False,\n    )\n    return {\n        \"audio_cover_strength\": audio_cover_strength,\n        \"remix_help_group\": remix_help_group,\n        \"cover_noise_strength\": cover_noise_strength,\n    }\n\n\ndef build_custom_mode_controls() -> dict[str, Any]:\n    \"\"\"Create custom-mode caption, lyrics, and reference-audio controls.\n\n    Args:\n        None.\n\n    Returns:\n        A component map containing custom-mode text/audio inputs and formatting actions.\n    \"\"\"\n\n    with gr.Group(visible=True, elem_classes=[\"has-info-container\"]) as custom_mode_group:\n        create_help_button(\"generation_custom\")\n        with gr.Row(equal_height=True):\n            with gr.Column(scale=2, min_width=200):\n                reference_audio = gr.Audio(\n                    label=t(\"generation.reference_audio\"),\n                    type=\"filepath\",\n                    show_label=True,\n                )\n            with gr.Column(scale=8):\n                with gr.Row(equal_height=True):\n                    with gr.Column(scale=1):\n                        captions = gr.Textbox(\n                            label=t(\"generation.caption_label\"),\n                            placeholder=t(\"generation.caption_placeholder\"),\n                            lines=12,\n                            max_lines=12,\n                        )\n                        with gr.Row(elem_classes=\"instrumental-row\"):\n                            format_caption_btn = gr.Button(\n                                t(\"generation.format_caption_btn\"),\n                                variant=\"secondary\",\n                                size=\"sm\",\n                            )\n                    with gr.Column(scale=1):\n                        lyrics = gr.Textbox(\n                            label=t(\"generation.lyrics_label\"),\n                            placeholder=t(\"generation.lyrics_placeholder\"),\n                            lines=12,\n                            max_lines=12,\n                        )\n                        with gr.Row(elem_classes=\"instrumental-row\"):\n                            instrumental_checkbox = gr.Checkbox(\n                                label=t(\"generation.instrumental_label\"),\n                                value=False,\n                                scale=1,\n                            )\n                            format_lyrics_btn = gr.Button(\n                                t(\"generation.format_lyrics_btn\"),\n                                variant=\"secondary\",\n                                size=\"sm\",\n                                scale=2,\n                            )\n            with gr.Column(scale=1, min_width=80, elem_classes=\"icon-btn-wrap\"):\n                sample_btn = gr.Button(t(\"generation.sample_btn\"), variant=\"primary\", size=\"lg\")\n    return {\n        \"custom_mode_group\": custom_mode_group,\n        \"reference_audio\": reference_audio,\n        \"captions\": captions,\n        \"format_caption_btn\": format_caption_btn,\n        \"lyrics\": lyrics,\n        \"instrumental_checkbox\": instrumental_checkbox,\n        \"format_lyrics_btn\": format_lyrics_btn,\n        \"sample_btn\": sample_btn,\n    }\n\n\ndef build_repainting_controls() -> dict[str, Any]:\n    \"\"\"Create repainting range controls used by repaint/lego flows.\n\n    Args:\n        None.\n\n    Returns:\n        A component map containing repainting group, header, and start/end controls.\n    \"\"\"\n\n    with gr.Group(visible=False) as repainting_group:\n        create_help_button(\"generation_repaint\")\n        repainting_header_html = gr.HTML(f\"<h5>{t('generation.repainting_controls')}</h5>\")\n        with gr.Row():\n            repainting_start = gr.Number(\n                label=t(\"generation.repainting_start\"),\n                value=0.0,\n                step=0.1,\n            )\n            repainting_end = gr.Number(\n                label=t(\"generation.repainting_end\"),\n                value=-1,\n                minimum=-1,\n                step=0.1,\n            )\n        with gr.Row():\n            repaint_mode = gr.Dropdown(\n                label=\"Repaint Mode\",\n                choices=[\"conservative\", \"balanced\", \"aggressive\"],\n                value=\"balanced\",\n                info=\"conservative=preserve source, aggressive=full regeneration\",\n            )\n            repaint_strength = gr.Slider(\n                label=\"Repaint Strength\",\n                minimum=0.0,\n                maximum=1.0,\n                step=0.05,\n                value=0.5,\n                info=\"0=conservative, 1=aggressive (balanced mode only)\",\n            )\n        repaint_strength_memory = gr.State(value=0.5)\n    return {\n        \"repainting_group\": repainting_group,\n        \"repainting_header_html\": repainting_header_html,\n        \"repainting_start\": repainting_start,\n        \"repainting_end\": repainting_end,\n        \"repaint_mode\": repaint_mode,\n        \"repaint_strength\": repaint_strength,\n        \"repaint_strength_memory\": repaint_strength_memory,\n    }\n"
  },
  {
    "path": "acestep/ui/gradio/interfaces/generation_tab_section.py",
    "content": "\"\"\"Generation-tab section orchestrator for the Gradio interface.\"\"\"\n\nfrom typing import Any\n\nimport gradio as gr\n\nfrom acestep.constants import GENERATION_MODES_BASE, GENERATION_MODES_TURBO\n\nfrom .generation_defaults import compute_init_defaults, resolve_is_pure_base_model\nfrom .generation_tab_primary_controls import (\n    build_hidden_generation_state,\n    build_mode_selector_controls,\n)\nfrom .generation_tab_simple_controls import (\n    build_simple_mode_controls,\n)\nfrom .generation_tab_source_controls import (\n    build_source_track_and_code_controls,\n)\nfrom .generation_tab_generate_controls import (\n    build_generate_row_controls,\n)\nfrom .generation_tab_optional_controls import (\n    build_optional_parameter_controls,\n)\nfrom .generation_tab_secondary_controls import (\n    build_cover_strength_controls,\n    build_custom_mode_controls,\n    build_repainting_controls,\n)\n\n\ndef create_generation_tab_section(\n    dit_handler: Any,\n    llm_handler: Any,\n    init_params: dict[str, Any] | None = None,\n    language: str = \"en\",\n) -> dict[str, Any]:\n    \"\"\"Create generation-tab controls and mode-specific UI sections.\n\n    Args:\n        dit_handler: DiT service handler used for model-aware mode defaults.\n        llm_handler: LM service handler retained for signature parity with callers.\n        init_params: Optional startup state used to prefill runtime defaults.\n        language: UI language code used for default computation.\n\n    Returns:\n        A merged component map for generation-tab controls and runtime metadata.\n    \"\"\"\n\n    _ = llm_handler  # retained for caller signature parity\n    defaults = compute_init_defaults(init_params, language)\n    service_pre_initialized = defaults[\"service_pre_initialized\"]\n    service_mode = defaults[\"service_mode\"]\n    lm_initialized = defaults[\"lm_initialized\"]\n    max_duration = defaults[\"max_duration\"]\n    max_batch_size = defaults[\"max_batch_size\"]\n    default_batch_size = defaults[\"default_batch_size\"]\n\n    is_pure_base_model = resolve_is_pure_base_model(\n        dit_handler=dit_handler,\n        init_params=init_params,\n        service_pre_initialized=service_pre_initialized,\n    )\n    initial_mode_choices = GENERATION_MODES_BASE if is_pure_base_model else GENERATION_MODES_TURBO\n\n    with gr.Group():\n        mode_controls = build_mode_selector_controls(initial_mode_choices)\n        hidden_state_controls = build_hidden_generation_state()\n        simple_mode_controls = build_simple_mode_controls()\n        source_track_code_controls = build_source_track_and_code_controls()\n        cover_controls = build_cover_strength_controls()\n        custom_mode_controls = build_custom_mode_controls()\n        repainting_controls = build_repainting_controls()\n        optional_controls = build_optional_parameter_controls(\n            max_duration=max_duration,\n            max_batch_size=max_batch_size,\n            default_batch_size=default_batch_size,\n            service_mode=service_mode,\n        )\n        generate_controls = build_generate_row_controls(\n            service_pre_initialized=service_pre_initialized,\n            init_params=init_params,\n            lm_initialized=lm_initialized,\n            service_mode=service_mode,\n        )\n\n    result: dict[str, Any] = {}\n    result.update(mode_controls)\n    result.update(hidden_state_controls)\n    result.update(simple_mode_controls)\n    result.update(source_track_code_controls)\n    result.update(cover_controls)\n    result.update(custom_mode_controls)\n    result.update(repainting_controls)\n    result.update(optional_controls)\n    result.update(generate_controls)\n    result.update(\n        {\n            \"max_duration\": max_duration,\n            \"max_batch_size\": max_batch_size,\n        }\n    )\n    return result\n"
  },
  {
    "path": "acestep/ui/gradio/interfaces/generation_tab_simple_controls.py",
    "content": "\"\"\"Simple-mode generation-tab controls.\"\"\"\n\nfrom typing import Any\n\nimport gradio as gr\n\nfrom acestep.constants import VALID_LANGUAGES\nfrom acestep.ui.gradio.help_content import create_help_button\nfrom acestep.ui.gradio.i18n import t\n\n\ndef build_simple_input_controls() -> tuple[gr.Textbox, gr.Dropdown, gr.Checkbox]:\n    \"\"\"Create simple-mode input widgets for prompt text and vocal configuration.\n\n    Args:\n        None.\n\n    Returns:\n        The ``simple_query_input``, ``simple_vocal_language``, and ``simple_instrumental_checkbox`` controls.\n    \"\"\"\n\n    simple_query_input = gr.Textbox(\n        label=t(\"generation.simple_query_label\"),\n        placeholder=t(\"generation.simple_query_placeholder\"),\n        lines=2,\n        info=t(\"generation.simple_query_info\"),\n        elem_classes=[\"has-info-container\"],\n        scale=9,\n    )\n    with gr.Column(scale=1):\n        simple_vocal_language = gr.Dropdown(\n            choices=[\n                (lang if lang != \"unknown\" else \"Instrumental / auto\", lang)\n                for lang in VALID_LANGUAGES\n            ],\n            value=\"unknown\",\n            allow_custom_value=True,\n            label=t(\"generation.simple_vocal_language_label\"),\n            interactive=True,\n            scale=1,\n        )\n        simple_instrumental_checkbox = gr.Checkbox(\n            label=t(\"generation.instrumental_label\"),\n            value=False,\n            scale=1,\n        )\n    return simple_query_input, simple_vocal_language, simple_instrumental_checkbox\n\n\ndef build_simple_action_controls(\n    create_random_desc: bool,\n    create_sample: bool,\n) -> tuple[gr.Button | None, gr.Button | None]:\n    \"\"\"Create simple-mode action buttons for random descriptions and sample generation.\n\n    Args:\n        create_random_desc: Whether to create and return the random-description button.\n        create_sample: Whether to create and return the create-sample button.\n\n    Returns:\n        A tuple of ``random_desc_btn`` and ``create_sample_btn``; entries are ``None`` when not requested.\n    \"\"\"\n\n    random_desc_btn: gr.Button | None = None\n    create_sample_btn: gr.Button | None = None\n    if create_random_desc:\n        random_desc_btn = gr.Button(\n            t(\"generation.sample_btn\"),\n            variant=\"secondary\",\n            size=\"lg\",\n        )\n    if create_sample:\n        create_sample_btn = gr.Button(\n            t(\"generation.create_sample_btn\"),\n            variant=\"primary\",\n            size=\"lg\",\n        )\n    return random_desc_btn, create_sample_btn\n\n\ndef build_simple_mode_controls() -> dict[str, Any]:\n    \"\"\"Create simple-mode prompt controls and sample action controls.\n\n    Args:\n        None.\n\n    Returns:\n        A component map containing simple-mode query inputs, language toggles, and action buttons.\n    \"\"\"\n\n    with gr.Group(visible=False, elem_classes=[\"has-info-container\"]) as simple_mode_group:\n        create_help_button(\"generation_simple\")\n        with gr.Row(equal_height=True):\n            (\n                simple_query_input,\n                simple_vocal_language,\n                simple_instrumental_checkbox,\n            ) = build_simple_input_controls()\n            with gr.Column(scale=1, min_width=80, elem_classes=\"icon-btn-wrap\"):\n                random_desc_btn, _ = build_simple_action_controls(\n                    create_random_desc=True,\n                    create_sample=False,\n                )\n        with gr.Row(equal_height=True):\n            _, create_sample_btn = build_simple_action_controls(\n                create_random_desc=False,\n                create_sample=True,\n            )\n    if random_desc_btn is None or create_sample_btn is None:\n        raise RuntimeError(\"Simple action controls were not created as expected.\")\n    return {\n        \"simple_mode_group\": simple_mode_group,\n        \"simple_query_input\": simple_query_input,\n        \"simple_vocal_language\": simple_vocal_language,\n        \"simple_instrumental_checkbox\": simple_instrumental_checkbox,\n        \"random_desc_btn\": random_desc_btn,\n        \"create_sample_btn\": create_sample_btn,\n    }\n"
  },
  {
    "path": "acestep/ui/gradio/interfaces/generation_tab_source_controls.py",
    "content": "\"\"\"Source-audio, track selection, and LM-code hint controls for generation tab.\"\"\"\n\nfrom typing import Any\n\nimport gradio as gr\n\nfrom acestep.constants import TRACK_NAMES\nfrom acestep.ui.gradio.help_content import create_help_button\nfrom acestep.ui.gradio.i18n import t\n\n\ndef build_source_audio_controls() -> dict[str, Any]:\n    \"\"\"Create source-audio controls used by remix/repaint/extract flows.\n\n    Args:\n        None.\n\n    Returns:\n        A component map containing ``src_audio_row``, ``src_audio``, ``analyze_btn``, and ``extract_help_group``.\n    \"\"\"\n\n    with gr.Row(equal_height=True, visible=False) as src_audio_row:\n        src_audio = gr.Audio(label=t(\"generation.source_audio\"), type=\"filepath\", scale=10)\n        with gr.Column(scale=1, min_width=80):\n            analyze_btn = gr.Button(\n                t(\"generation.analyze_btn\"),\n                variant=\"secondary\",\n                size=\"lg\",\n            )\n\n    with gr.Group(visible=False) as extract_help_group:\n        create_help_button(\"generation_extract\")\n    return {\n        \"src_audio_row\": src_audio_row,\n        \"src_audio\": src_audio,\n        \"analyze_btn\": analyze_btn,\n        \"extract_help_group\": extract_help_group,\n    }\n\n\ndef build_track_selection_controls() -> dict[str, Any]:\n    \"\"\"Create track selection controls for extract and complete generation modes.\n\n    Args:\n        None.\n\n    Returns:\n        A component map containing ``track_name``, ``complete_help_group``, and ``complete_track_classes``.\n    \"\"\"\n\n    track_name = gr.Dropdown(\n        choices=TRACK_NAMES,\n        value=None,\n        label=t(\"generation.track_name_label\"),\n        info=t(\"generation.track_name_info\"),\n        elem_classes=[\"has-info-container\"],\n        visible=False,\n    )\n    with gr.Group(visible=False) as complete_help_group:\n        create_help_button(\"generation_complete\")\n    complete_track_classes = gr.CheckboxGroup(\n        choices=TRACK_NAMES,\n        label=t(\"generation.track_classes_label\"),\n        info=t(\"generation.track_classes_info\"),\n        elem_classes=[\"has-info-container\"],\n        visible=False,\n    )\n    return {\n        \"track_name\": track_name,\n        \"complete_help_group\": complete_help_group,\n        \"complete_track_classes\": complete_track_classes,\n    }\n\n\ndef build_lm_code_hint_controls() -> dict[str, Any]:\n    \"\"\"Create optional LM code-hint controls for text2music generation.\n\n    Args:\n        None.\n\n    Returns:\n        A component map containing LM code hint controls and action buttons.\n    \"\"\"\n\n    with gr.Accordion(\n        t(\"generation.lm_codes_hints\"),\n        open=False,\n        visible=True,\n        elem_classes=[\"has-info-container\"],\n    ) as text2music_audio_codes_group:\n        with gr.Row(equal_height=True):\n            lm_codes_audio_upload = gr.Audio(label=t(\"generation.source_audio\"), type=\"filepath\", scale=3)\n            text2music_audio_code_string = gr.Textbox(\n                label=t(\"generation.lm_codes_label\"),\n                placeholder=t(\"generation.lm_codes_placeholder\"),\n                lines=6,\n                info=t(\"generation.lm_codes_info\"),\n                elem_classes=[\"has-info-container\"],\n                scale=6,\n            )\n        with gr.Row():\n            convert_src_to_codes_btn = gr.Button(\n                t(\"generation.convert_codes_btn\"),\n                variant=\"secondary\",\n                size=\"sm\",\n                scale=1,\n            )\n            transcribe_btn = gr.Button(\n                t(\"generation.transcribe_btn\"),\n                variant=\"secondary\",\n                size=\"sm\",\n                scale=1,\n            )\n    return {\n        \"text2music_audio_codes_group\": text2music_audio_codes_group,\n        \"lm_codes_audio_upload\": lm_codes_audio_upload,\n        \"text2music_audio_code_string\": text2music_audio_code_string,\n        \"convert_src_to_codes_btn\": convert_src_to_codes_btn,\n        \"transcribe_btn\": transcribe_btn,\n    }\n\n\ndef build_source_track_and_code_controls() -> dict[str, Any]:\n    \"\"\"Create source-audio, track-selector, and LM-code hint controls.\n\n    Args:\n        None.\n\n    Returns:\n        A component map containing source audio actions, track selectors, and LM code controls.\n    \"\"\"\n\n    source_audio_controls = build_source_audio_controls()\n    track_selection_controls = build_track_selection_controls()\n    lm_code_hint_controls = build_lm_code_hint_controls()\n\n    return {\n        \"src_audio_row\": source_audio_controls[\"src_audio_row\"],\n        \"src_audio\": source_audio_controls[\"src_audio\"],\n        \"analyze_btn\": source_audio_controls[\"analyze_btn\"],\n        \"extract_help_group\": source_audio_controls[\"extract_help_group\"],\n        \"track_name\": track_selection_controls[\"track_name\"],\n        \"complete_help_group\": track_selection_controls[\"complete_help_group\"],\n        \"complete_track_classes\": track_selection_controls[\"complete_track_classes\"],\n        \"text2music_audio_codes_group\": lm_code_hint_controls[\"text2music_audio_codes_group\"],\n        \"lm_codes_audio_upload\": lm_code_hint_controls[\"lm_codes_audio_upload\"],\n        \"text2music_audio_code_string\": lm_code_hint_controls[\"text2music_audio_code_string\"],\n        \"convert_src_to_codes_btn\": lm_code_hint_controls[\"convert_src_to_codes_btn\"],\n        \"transcribe_btn\": lm_code_hint_controls[\"transcribe_btn\"],\n    }\n"
  },
  {
    "path": "acestep/ui/gradio/interfaces/result.py",
    "content": "\"\"\"\nGradio UI Results Section Module\nContains results display section component definitions\n\"\"\"\nimport gradio as gr\nfrom acestep.ui.gradio.i18n import t\nfrom acestep.ui.gradio.help_content import create_help_button\n\n\ndef _create_audio_column(n, visible=True):\n    \"\"\"Create a single audio sample column with all its sub-components.\n    \n    Layout:\n        Audio player\n        Row: [Send To Cover] [Send To Repaint] [Save]\n        Accordion (Score & LRC & LM Codes):\n            codes_display\n            Row: score_display + score_btn\n            Row: lrc_display + lrc_btn\n    \"\"\"\n    with gr.Column(visible=visible) as audio_col:\n        generated_audio = gr.Audio(\n            label=t(\"results.generated_music\", n=n),\n            type=\"filepath\",\n            interactive=False,\n            buttons=[]\n        )\n        with gr.Row(equal_height=True):\n            send_to_remix_btn = gr.Button(\n                t(\"results.send_to_remix_btn\"),\n                variant=\"secondary\", size=\"sm\", scale=1\n            )\n            send_to_repaint_btn = gr.Button(\n                t(\"results.send_to_repaint_btn\"),\n                variant=\"secondary\", size=\"sm\", scale=1\n            )\n            save_btn = gr.Button(\n                t(\"results.save_btn\"),\n                variant=\"primary\", size=\"sm\", scale=1\n            )\n        with gr.Accordion(t(\"results.details_accordion\"), open=False, visible=True) as details_accordion:\n            codes_display = gr.Textbox(\n                label=t(\"results.codes_label\", n=n),\n                interactive=False, buttons=[\"copy\"],\n                lines=4, max_lines=4, visible=True\n            )\n            convert_to_codes_btn = gr.Button(\n                t(\"results.convert_to_codes_btn\"),\n                variant=\"secondary\", size=\"sm\"\n            )\n            score_display = gr.Textbox(\n                label=t(\"results.quality_score_label\", n=n),\n                interactive=False, buttons=[\"copy\"],\n                lines=6, max_lines=6, visible=True\n            )\n            score_btn = gr.Button(\n                t(\"results.score_btn\"),\n                variant=\"secondary\", size=\"sm\"\n            )\n            lrc_display = gr.Textbox(\n                label=t(\"results.lrc_label\", n=n),\n                interactive=True, buttons=[\"copy\"],\n                lines=8, max_lines=8, visible=True\n            )\n            with gr.Row(equal_height=True):\n                lrc_btn = gr.Button(\n                    t(\"results.lrc_btn\"),\n                    variant=\"secondary\", size=\"sm\"\n                )\n                save_lrc_btn = gr.Button(\n                    t(\"results.save_lrc_btn\"),\n                    variant=\"secondary\", size=\"sm\"\n                )\n            lrc_download_file = gr.File(\n                label=\"LRC Download\",\n                visible=False,\n                interactive=False,\n            )\n    return {\n        \"audio_col\": audio_col,\n        \"generated_audio\": generated_audio,\n        \"send_to_remix_btn\": send_to_remix_btn,\n        \"send_to_repaint_btn\": send_to_repaint_btn,\n        \"save_btn\": save_btn,\n        \"details_accordion\": details_accordion,\n        \"codes_display\": codes_display,\n        \"convert_to_codes_btn\": convert_to_codes_btn,\n        \"score_display\": score_display,\n        \"score_btn\": score_btn,\n        \"lrc_display\": lrc_display,\n        \"lrc_btn\": lrc_btn,\n        \"save_lrc_btn\": save_lrc_btn,\n        \"lrc_download_file\": lrc_download_file,\n    }\n\n\ndef create_results_section(dit_handler) -> dict:\n    \"\"\"Create results display section\"\"\"\n    with gr.Accordion(t(\"results.title\"), open=True):\n        create_help_button(\"results\")\n        # Hidden state to store LM-generated metadata\n        lm_metadata_state = gr.State(value=None)\n        \n        # Hidden state to track if caption/metadata is from formatted source (LM/transcription)\n        is_format_caption_state = gr.State(value=False)\n        \n        # Batch management states\n        current_batch_index = gr.State(value=0)\n        total_batches = gr.State(value=1)\n        batch_queue = gr.State(value={})\n        generation_params_state = gr.State(value={})\n        is_generating_background = gr.State(value=False)\n\n        # Row 1: samples 1-4\n        with gr.Row():\n            cols_1_4 = []\n            for i in range(1, 5):\n                cols_1_4.append(_create_audio_column(i, visible=(i <= 2)))\n        \n        # Row 2: samples 5-8 (initially hidden)\n        with gr.Row(visible=False) as audio_row_5_8:\n            cols_5_8 = []\n            for i in range(5, 9):\n                cols_5_8.append(_create_audio_column(i, visible=True))\n        \n        all_cols = cols_1_4 + cols_5_8\n        \n        status_output = gr.Textbox(label=t(\"results.generation_status\"), interactive=False)\n        \n        # Batch navigation controls\n        with gr.Row(equal_height=True):\n            prev_batch_btn = gr.Button(\n                t(\"results.prev_btn\"),\n                variant=\"secondary\", interactive=False, scale=1, size=\"sm\"\n            )\n            batch_indicator = gr.Textbox(\n                label=t(\"results.current_batch\"),\n                value=t(\"results.batch_indicator\", current=1, total=1),\n                interactive=False, scale=3\n            )\n            next_batch_status = gr.Textbox(\n                label=t(\"results.next_batch_status\"),\n                value=\"\", interactive=False, scale=3\n            )\n            next_batch_btn = gr.Button(\n                t(\"results.next_btn\"),\n                variant=\"primary\", interactive=False, scale=1, size=\"sm\"\n            )\n        \n        # One-click restore parameters button\n        restore_params_btn = gr.Button(\n            t(\"results.restore_params_btn\"),\n            variant=\"secondary\", interactive=False, size=\"sm\"\n        )\n        \n        with gr.Accordion(t(\"results.batch_results_title\"), open=True):\n            generated_audio_batch = gr.File(\n                label=t(\"results.all_files_label\"),\n                file_count=\"multiple\", interactive=False\n            )\n            generation_info = gr.Markdown(label=t(\"results.generation_details\"))\n    \n    # Build return dict from all_cols\n    result = {\n        \"lm_metadata_state\": lm_metadata_state,\n        \"is_format_caption_state\": is_format_caption_state,\n        \"current_batch_index\": current_batch_index,\n        \"total_batches\": total_batches,\n        \"batch_queue\": batch_queue,\n        \"generation_params_state\": generation_params_state,\n        \"is_generating_background\": is_generating_background,\n        \"status_output\": status_output,\n        \"prev_batch_btn\": prev_batch_btn,\n        \"batch_indicator\": batch_indicator,\n        \"next_batch_btn\": next_batch_btn,\n        \"next_batch_status\": next_batch_status,\n        \"restore_params_btn\": restore_params_btn,\n        \"audio_row_5_8\": audio_row_5_8,\n        \"generated_audio_batch\": generated_audio_batch,\n        \"generation_info\": generation_info,\n    }\n    \n    for idx, col_data in enumerate(all_cols, start=1):\n        result[f\"generated_audio_{idx}\"] = col_data[\"generated_audio\"]\n        result[f\"audio_col_{idx}\"] = col_data[\"audio_col\"]\n        result[f\"send_to_remix_btn_{idx}\"] = col_data[\"send_to_remix_btn\"]\n        result[f\"send_to_repaint_btn_{idx}\"] = col_data[\"send_to_repaint_btn\"]\n        result[f\"save_btn_{idx}\"] = col_data[\"save_btn\"]\n        result[f\"score_btn_{idx}\"] = col_data[\"score_btn\"]\n        result[f\"score_display_{idx}\"] = col_data[\"score_display\"]\n        result[f\"codes_display_{idx}\"] = col_data[\"codes_display\"]\n        result[f\"convert_to_codes_btn_{idx}\"] = col_data[\"convert_to_codes_btn\"]\n        result[f\"lrc_btn_{idx}\"] = col_data[\"lrc_btn\"]\n        result[f\"lrc_display_{idx}\"] = col_data[\"lrc_display\"]\n        result[f\"save_lrc_btn_{idx}\"] = col_data[\"save_lrc_btn\"]\n        result[f\"lrc_download_file_{idx}\"] = col_data[\"lrc_download_file\"]\n        result[f\"details_accordion_{idx}\"] = col_data[\"details_accordion\"]\n    \n    return result\n"
  },
  {
    "path": "acestep/ui/gradio/interfaces/training.py",
    "content": "\"\"\"Gradio UI training-tab facade that composes focused tab builders.\"\"\"\n\nfrom __future__ import annotations\n\nimport gradio as gr\n\nfrom acestep.constants import DEBUG_TRAINING\nfrom acestep.ui.gradio.interfaces.training_dataset_builder_tab import (\n    create_dataset_builder_tab,\n)\nfrom acestep.ui.gradio.interfaces.training_lokr_tab import create_training_lokr_tab\nfrom acestep.ui.gradio.interfaces.training_lora_tab import create_training_lora_tab\n\n\ndef _resolve_epoch_slider_defaults() -> tuple[int, int, int]:\n    \"\"\"Return epoch slider defaults adjusted for training debug mode.\"\"\"\n\n    debug_training_enabled = str(DEBUG_TRAINING).strip().upper() != \"OFF\"\n    if debug_training_enabled:\n        return 1, 1, 1\n    return 100, 100, 1000\n\n\ndef create_training_section(dit_handler, llm_handler, init_params=None) -> dict:\n    \"\"\"Create the training-tab content without the outer ``gr.Tab`` wrapper.\n\n    Args:\n        dit_handler: DiT handler instance.\n        llm_handler: LLM handler instance.\n        init_params: Optional initialization parameters.\n\n    Returns:\n        Mapping of component keys to Gradio components for training-event wiring.\n    \"\"\"\n\n    del dit_handler, llm_handler, init_params\n\n    epoch_min, epoch_step, epoch_default = _resolve_epoch_slider_defaults()\n\n    gr.HTML(\n        \"\"\"\n    <div style=\"text-align: center; padding: 10px; margin-bottom: 15px;\">\n        <h2>🎵 LoRA Training for ACE-Step</h2>\n        <p>Build datasets from your audio files and train custom LoRA adapters</p>\n    </div>\n    \"\"\"\n    )\n\n    training_section: dict[str, object] = {}\n    with gr.Tabs():\n        training_section.update(create_dataset_builder_tab())\n        training_section.update(\n            create_training_lora_tab(\n                epoch_min=epoch_min,\n                epoch_step=epoch_step,\n                epoch_default=epoch_default,\n            )\n        )\n        training_section.update(create_training_lokr_tab())\n        dataset_builder_state = gr.State(None)\n        training_state = gr.State({\"is_training\": False, \"should_stop\": False})\n        training_section.update(\n            {\n                \"dataset_builder_state\": dataset_builder_state,\n                \"training_state\": training_state,\n            }\n        )\n    return training_section\n"
  },
  {
    "path": "acestep/ui/gradio/interfaces/training_contract_ast_utils.py",
    "content": "\"\"\"AST utility helpers for training interface decomposition contract tests.\"\"\"\n\nfrom __future__ import annotations\n\nimport ast\nfrom pathlib import Path\n\n\nINTERFACES_DIR = Path(__file__).resolve().parent\nWIRING_DIR = INTERFACES_DIR.parent / \"events\" / \"wiring\"\n\n\ndef load_module(module_name: str) -> ast.Module:\n    \"\"\"Parse and return AST for an interfaces module.\"\"\"\n\n    path = INTERFACES_DIR / module_name\n    return ast.parse(path.read_text(encoding=\"utf-8\"))\n\n\ndef call_name(node: ast.AST) -> str | None:\n    \"\"\"Extract a simple call-target name from an AST call function node.\"\"\"\n\n    if isinstance(node, ast.Name):\n        return node.id\n    if isinstance(node, ast.Attribute):\n        return node.attr\n    return None\n\n\ndef collect_return_dict_keys(module_name: str, function_name: str) -> set[str]:\n    \"\"\"Collect string keys from dict literals assigned/updated/returned in a function.\"\"\"\n\n    module = load_module(module_name)\n    function_node = None\n    for node in module.body:\n        if isinstance(node, ast.FunctionDef) and node.name == function_name:\n            function_node = node\n            break\n    if function_node is None:\n        raise AssertionError(f\"{function_name} not found in {module_name}\")\n\n    keys: set[str] = set()\n    for node in ast.walk(function_node):\n        if isinstance(node, ast.Assign) and isinstance(node.value, ast.Dict):\n            for key in node.value.keys:\n                if isinstance(key, ast.Constant) and isinstance(key.value, str):\n                    keys.add(key.value)\n        if isinstance(node, ast.AnnAssign) and isinstance(node.value, ast.Dict):\n            for key in node.value.keys:\n                if isinstance(key, ast.Constant) and isinstance(key.value, str):\n                    keys.add(key.value)\n        if isinstance(node, ast.Call) and isinstance(node.func, ast.Attribute) and node.func.attr == \"update\":\n            if node.args and isinstance(node.args[0], ast.Dict):\n                for key in node.args[0].keys:\n                    if isinstance(key, ast.Constant) and isinstance(key.value, str):\n                        keys.add(key.value)\n        if isinstance(node, ast.Return) and isinstance(node.value, ast.Dict):\n            for key in node.value.keys:\n                if isinstance(key, ast.Constant) and isinstance(key.value, str):\n                    keys.add(key.value)\n    return keys\n\n\ndef collect_training_section_keys_used_by_wiring() -> set[str]:\n    \"\"\"Collect ``training_section[...]`` keys referenced by training wiring modules.\"\"\"\n\n    keys: set[str] = set()\n    for path in WIRING_DIR.glob(\"training_*wiring.py\"):\n        module = ast.parse(path.read_text(encoding=\"utf-8\"))\n        for node in ast.walk(module):\n            if not isinstance(node, ast.Subscript):\n                continue\n            if not isinstance(node.value, ast.Name) or node.value.id != \"training_section\":\n                continue\n            if isinstance(node.slice, ast.Constant) and isinstance(node.slice.value, str):\n                keys.add(node.slice.value)\n    return keys\n"
  },
  {
    "path": "acestep/ui/gradio/interfaces/training_dataset_builder_tab.py",
    "content": "\"\"\"Dataset-builder tab facade for the Gradio training interface.\"\"\"\n\nfrom __future__ import annotations\n\nimport gradio as gr\n\nfrom acestep.ui.gradio.help_content import create_help_button\nfrom acestep.ui.gradio.i18n import t\nfrom acestep.ui.gradio.interfaces.training_dataset_tab_label_preview import (\n    build_dataset_label_and_preview_controls,\n)\nfrom acestep.ui.gradio.interfaces.training_dataset_tab_save_preprocess import (\n    build_dataset_save_and_preprocess_controls,\n)\nfrom acestep.ui.gradio.interfaces.training_dataset_tab_scan_settings import (\n    build_dataset_scan_and_settings_controls,\n)\n\n\ndef create_dataset_builder_tab() -> dict[str, object]:\n    \"\"\"Create the Dataset Builder tab and return all exposed component handles.\"\"\"\n\n    with gr.Tab(t(\"training.tab_dataset_builder\")):\n        create_help_button(\"training_dataset\")\n        tab_controls: dict[str, object] = {}\n        tab_controls.update(build_dataset_scan_and_settings_controls())\n        tab_controls.update(build_dataset_label_and_preview_controls())\n        tab_controls.update(build_dataset_save_and_preprocess_controls())\n    return tab_controls\n"
  },
  {
    "path": "acestep/ui/gradio/interfaces/training_dataset_tab_label_preview.py",
    "content": "\"\"\"Dataset labeling and sample-preview controls for the training dataset tab.\"\"\"\n\nfrom __future__ import annotations\n\nimport gradio as gr\n\nfrom acestep.ui.gradio.i18n import t\n\n\ndef build_dataset_label_and_preview_controls() -> dict[str, object]:\n    \"\"\"Render auto-label and sample-preview editors for dataset-builder workflows.\"\"\"\n\n    gr.HTML(f\"<hr><h3>🤖 {t('training.step2_title')}</h3>\")\n\n    with gr.Row():\n        with gr.Column(scale=3):\n            gr.Markdown(t(\"training.step2_instruction\"))\n            skip_metas = gr.Checkbox(\n                label=t(\"training.skip_metas\"),\n                value=False,\n                info=t(\"training.skip_metas_info\"),\n                elem_classes=[\"has-info-container\"],\n            )\n            only_unlabeled = gr.Checkbox(\n                label=t(\"training.only_unlabeled\"),\n                value=False,\n                info=t(\"training.only_unlabeled_info\"),\n                elem_classes=[\"has-info-container\"],\n            )\n        with gr.Column(scale=1):\n            auto_label_btn = gr.Button(\n                t(\"training.auto_label_btn\"),\n                variant=\"primary\",\n                size=\"lg\",\n            )\n\n    label_progress = gr.Textbox(\n        label=t(\"training.label_progress\"),\n        interactive=False,\n        lines=2,\n    )\n\n    gr.HTML(f\"<hr><h3>👀 {t('training.step3_title')}</h3>\")\n\n    with gr.Row():\n        with gr.Column(scale=1):\n            sample_selector = gr.Slider(\n                minimum=0,\n                maximum=0,\n                step=1,\n                value=0,\n                label=t(\"training.select_sample\"),\n                info=t(\"training.select_sample_info\"),\n                elem_classes=[\"has-info-container\"],\n            )\n\n            preview_audio = gr.Audio(\n                label=t(\"training.audio_preview\"),\n                type=\"filepath\",\n                interactive=False,\n            )\n\n            preview_filename = gr.Textbox(\n                label=t(\"training.filename\"),\n                interactive=False,\n            )\n\n        with gr.Column(scale=2):\n            with gr.Row():\n                edit_caption = gr.Textbox(\n                    label=t(\"training.caption\"),\n                    lines=3,\n                    placeholder=\"Music description...\",\n                )\n\n            with gr.Row():\n                edit_genre = gr.Textbox(\n                    label=t(\"training.genre\"),\n                    lines=1,\n                    placeholder=\"pop, electronic, dance...\",\n                )\n                prompt_override = gr.Dropdown(\n                    choices=[\"Use Global Ratio\", \"Caption\", \"Genre\"],\n                    value=\"Use Global Ratio\",\n                    label=t(\"training.prompt_override_label\"),\n                    info=t(\"training.prompt_override_info\"),\n                    elem_classes=[\"has-info-container\"],\n                )\n\n            with gr.Row():\n                edit_lyrics = gr.Textbox(\n                    label=t(\"training.lyrics_editable_label\"),\n                    lines=6,\n                    placeholder=\"[Verse 1]\\nLyrics here...\\n\\n[Chorus]\\n...\",\n                )\n                raw_lyrics_display = gr.Textbox(\n                    label=t(\"training.raw_lyrics_label\"),\n                    lines=6,\n                    placeholder=t(\"training.no_lyrics_placeholder\"),\n                    interactive=False,\n                    visible=False,\n                )\n                has_raw_lyrics_state = gr.State(False)\n\n            with gr.Row():\n                edit_bpm = gr.Number(\n                    label=t(\"training.bpm\"),\n                    precision=0,\n                )\n                edit_keyscale = gr.Textbox(\n                    label=t(\"training.key_label\"),\n                    placeholder=t(\"training.key_placeholder\"),\n                )\n                edit_timesig = gr.Dropdown(\n                    choices=[\"\", \"2\", \"3\", \"4\", \"6\", \"N/A\"],\n                    label=t(\"training.time_sig\"),\n                )\n                edit_duration = gr.Number(\n                    label=t(\"training.duration_s\"),\n                    precision=1,\n                    interactive=False,\n                )\n\n            with gr.Row():\n                edit_language = gr.Dropdown(\n                    choices=[\n                        \"instrumental\",\n                        \"en\",\n                        \"zh\",\n                        \"ja\",\n                        \"ko\",\n                        \"es\",\n                        \"fr\",\n                        \"de\",\n                        \"pt\",\n                        \"ru\",\n                        \"unknown\",\n                    ],\n                    value=\"instrumental\",\n                    label=t(\"training.language\"),\n                )\n                edit_instrumental = gr.Checkbox(\n                    label=t(\"training.instrumental\"),\n                    value=True,\n                )\n                save_edit_btn = gr.Button(t(\"training.save_changes_btn\"), variant=\"secondary\")\n\n            edit_status = gr.Textbox(\n                label=t(\"training.edit_status\"),\n                interactive=False,\n            )\n\n    return {\n        \"skip_metas\": skip_metas,\n        \"only_unlabeled\": only_unlabeled,\n        \"auto_label_btn\": auto_label_btn,\n        \"label_progress\": label_progress,\n        \"sample_selector\": sample_selector,\n        \"preview_audio\": preview_audio,\n        \"preview_filename\": preview_filename,\n        \"edit_caption\": edit_caption,\n        \"edit_genre\": edit_genre,\n        \"prompt_override\": prompt_override,\n        \"edit_lyrics\": edit_lyrics,\n        \"raw_lyrics_display\": raw_lyrics_display,\n        \"has_raw_lyrics_state\": has_raw_lyrics_state,\n        \"edit_bpm\": edit_bpm,\n        \"edit_keyscale\": edit_keyscale,\n        \"edit_timesig\": edit_timesig,\n        \"edit_duration\": edit_duration,\n        \"edit_language\": edit_language,\n        \"edit_instrumental\": edit_instrumental,\n        \"save_edit_btn\": save_edit_btn,\n        \"edit_status\": edit_status,\n    }\n"
  },
  {
    "path": "acestep/ui/gradio/interfaces/training_dataset_tab_save_preprocess.py",
    "content": "\"\"\"Dataset save and preprocess controls for the training dataset tab.\"\"\"\n\nfrom __future__ import annotations\n\nimport gradio as gr\n\nfrom acestep.ui.gradio.i18n import t\n\n\ndef build_dataset_save_and_preprocess_controls() -> dict[str, object]:\n    \"\"\"Render dataset save/load-preprocess controls and return component handles.\"\"\"\n\n    gr.HTML(f\"<hr><h3>💾 {t('training.step4_title')}</h3>\")\n\n    with gr.Row():\n        with gr.Column(scale=3):\n            save_path = gr.Textbox(\n                label=t(\"training.save_path\"),\n                value=\"./datasets/my_lora_dataset.json\",\n                placeholder=\"./datasets/dataset_name.json\",\n                info=t(\"training.save_path_info\"),\n                elem_classes=[\"has-info-container\"],\n            )\n        with gr.Column(scale=1):\n            save_dataset_btn = gr.Button(\n                t(\"training.save_dataset_btn\"),\n                variant=\"primary\",\n                size=\"lg\",\n            )\n\n    save_status = gr.Textbox(\n        label=t(\"training.save_status\"),\n        interactive=False,\n        lines=2,\n    )\n\n    gr.HTML(f\"<hr><h3>⚡ {t('training.step5_title')}</h3>\")\n\n    gr.Markdown(t(\"training.step5_intro\"))\n\n    with gr.Row():\n        with gr.Column(scale=3):\n            load_existing_dataset_path = gr.Textbox(\n                label=t(\"training.load_existing_label\"),\n                placeholder=\"./datasets/my_lora_dataset.json\",\n                info=t(\"training.load_existing_info\"),\n                elem_classes=[\"has-info-container\"],\n            )\n        with gr.Column(scale=1):\n            load_existing_dataset_btn = gr.Button(\n                t(\"training.load_dataset_btn\"),\n                variant=\"secondary\",\n                size=\"lg\",\n            )\n\n    load_existing_status = gr.Textbox(\n        label=t(\"training.load_status\"),\n        interactive=False,\n    )\n\n    gr.Markdown(t(\"training.step5_details\"))\n\n    with gr.Row():\n        preprocess_mode = gr.Dropdown(\n            label=\"Preprocess For\",\n            choices=[\"LoRA\", \"LoKr\"],\n            value=\"LoRA\",\n            info=\"LoRA keeps compatibility mode; LoKr uses per-sample source-style context.\",\n            elem_classes=[\"has-info-container\"],\n        )\n\n    with gr.Row():\n        with gr.Column(scale=3):\n            preprocess_output_dir = gr.Textbox(\n                label=t(\"training.tensor_output_dir\"),\n                value=\"./datasets/preprocessed_tensors\",\n                placeholder=\"./datasets/preprocessed_tensors\",\n                info=t(\"training.tensor_output_info\"),\n                elem_classes=[\"has-info-container\"],\n            )\n        with gr.Column(scale=1):\n            preprocess_btn = gr.Button(\n                t(\"training.preprocess_btn\"),\n                variant=\"primary\",\n                size=\"lg\",\n            )\n\n    preprocess_progress = gr.Textbox(\n        label=t(\"training.preprocess_progress\"),\n        interactive=False,\n        lines=3,\n    )\n\n    return {\n        \"save_path\": save_path,\n        \"save_dataset_btn\": save_dataset_btn,\n        \"save_status\": save_status,\n        \"load_existing_dataset_path\": load_existing_dataset_path,\n        \"load_existing_dataset_btn\": load_existing_dataset_btn,\n        \"load_existing_status\": load_existing_status,\n        \"preprocess_mode\": preprocess_mode,\n        \"preprocess_output_dir\": preprocess_output_dir,\n        \"preprocess_btn\": preprocess_btn,\n        \"preprocess_progress\": preprocess_progress,\n    }\n"
  },
  {
    "path": "acestep/ui/gradio/interfaces/training_dataset_tab_scan_settings.py",
    "content": "\"\"\"Dataset scan/load and settings controls for the training dataset tab.\"\"\"\n\nfrom __future__ import annotations\n\nimport gradio as gr\n\nfrom acestep.ui.gradio.i18n import t\n\n\ndef build_dataset_scan_and_settings_controls() -> dict[str, object]:\n    \"\"\"Render scan/load controls and dataset settings for the dataset-builder tab.\"\"\"\n\n    gr.HTML(\n        f\"\"\"\n            <div style=\"padding: 10px; margin-bottom: 10px; border: 1px solid #4a4a6a; border-radius: 8px; background: linear-gradient(135deg, #2a2a4a 0%, #1a1a3a 100%);\">\n                <h3 style=\"margin: 0 0 5px 0;\">{t(\"training.quick_start_title\")}</h3>\n                <p style=\"margin: 0; color: #aaa;\">Choose one: <b>Load existing dataset</b> OR <b>Scan new directory</b></p>\n            </div>\n            \"\"\"\n    )\n\n    with gr.Row():\n        with gr.Column(scale=1):\n            gr.HTML(\"<h4>📂 Load Existing Dataset</h4>\")\n            with gr.Row():\n                load_json_path = gr.Textbox(\n                    label=t(\"training.load_dataset_label\"),\n                    placeholder=\"./datasets/my_lora_dataset.json\",\n                    info=t(\"training.load_dataset_info\"),\n                    elem_classes=[\"has-info-container\"],\n                    scale=3,\n                )\n                load_json_btn = gr.Button(t(\"training.load_btn\"), variant=\"primary\", scale=1)\n            load_json_status = gr.Textbox(\n                label=t(\"training.load_status\"),\n                interactive=False,\n            )\n\n        with gr.Column(scale=1):\n            gr.HTML(\"<h4>🔍 Scan New Directory</h4>\")\n            with gr.Row():\n                audio_directory = gr.Textbox(\n                    label=t(\"training.scan_label\"),\n                    placeholder=\"/path/to/your/audio/folder\",\n                    info=t(\"training.scan_info\"),\n                    elem_classes=[\"has-info-container\"],\n                    scale=3,\n                )\n                scan_btn = gr.Button(t(\"training.scan_btn\"), variant=\"secondary\", scale=1)\n            scan_status = gr.Textbox(\n                label=t(\"training.scan_status\"),\n                interactive=False,\n            )\n\n    gr.HTML(\"<hr>\")\n\n    with gr.Row():\n        with gr.Column(scale=2):\n            audio_files_table = gr.Dataframe(\n                headers=[\"#\", \"Filename\", \"Duration\", \"Lyrics\", \"Labeled\", \"BPM\", \"Key\", \"Caption\"],\n                datatype=[\"number\", \"str\", \"str\", \"str\", \"str\", \"str\", \"str\", \"str\"],\n                label=t(\"training.found_audio_files\"),\n                interactive=False,\n                wrap=True,\n            )\n\n        with gr.Column(scale=1):\n            gr.HTML(f\"<h3>⚙️ {t('training.dataset_settings_header')}</h3>\")\n\n            dataset_name = gr.Textbox(\n                label=t(\"training.dataset_name\"),\n                value=\"my_lora_dataset\",\n                placeholder=t(\"training.dataset_name_placeholder\"),\n            )\n\n            all_instrumental = gr.Checkbox(\n                label=t(\"training.all_instrumental\"),\n                value=True,\n                info=t(\"training.all_instrumental_info\"),\n                elem_classes=[\"has-info-container\"],\n            )\n\n            format_lyrics = gr.Checkbox(\n                label=\"Format Lyrics (LM)\",\n                value=False,\n                info=\"Use LM to format/structure user-provided lyrics from .txt files (coming soon)\",\n                elem_classes=[\"has-info-container\"],\n                interactive=False,\n            )\n\n            transcribe_lyrics = gr.Checkbox(\n                label=\"Transcribe Lyrics (LM)\",\n                value=False,\n                info=\"Use LM to transcribe lyrics from audio (coming soon)\",\n                elem_classes=[\"has-info-container\"],\n                interactive=False,\n            )\n\n            custom_tag = gr.Textbox(\n                label=t(\"training.custom_tag\"),\n                placeholder=\"e.g., 8bit_retro, my_style\",\n                info=t(\"training.custom_tag_info\"),\n                elem_classes=[\"has-info-container\"],\n            )\n\n            tag_position = gr.Radio(\n                choices=[\n                    (t(\"training.tag_prepend\"), \"prepend\"),\n                    (t(\"training.tag_append\"), \"append\"),\n                    (t(\"training.tag_replace\"), \"replace\"),\n                ],\n                value=\"replace\",\n                label=t(\"training.tag_position\"),\n                info=t(\"training.tag_position_info\"),\n                elem_classes=[\"has-info-container\"],\n            )\n\n            genre_ratio = gr.Slider(\n                minimum=0,\n                maximum=100,\n                step=10,\n                value=0,\n                label=t(\"training.genre_ratio\"),\n                info=t(\"training.genre_ratio_info\"),\n                elem_classes=[\"has-info-container\"],\n            )\n\n    return {\n        \"load_json_path\": load_json_path,\n        \"load_json_btn\": load_json_btn,\n        \"load_json_status\": load_json_status,\n        \"audio_directory\": audio_directory,\n        \"scan_btn\": scan_btn,\n        \"scan_status\": scan_status,\n        \"audio_files_table\": audio_files_table,\n        \"dataset_name\": dataset_name,\n        \"all_instrumental\": all_instrumental,\n        \"format_lyrics\": format_lyrics,\n        \"transcribe_lyrics\": transcribe_lyrics,\n        \"custom_tag\": custom_tag,\n        \"tag_position\": tag_position,\n        \"genre_ratio\": genre_ratio,\n    }\n"
  },
  {
    "path": "acestep/ui/gradio/interfaces/training_decomposition_contract_test.py",
    "content": "\"\"\"AST contract tests for training interface decomposition.\"\"\"\n\nfrom __future__ import annotations\n\nimport ast\nimport unittest\nfrom pathlib import Path\n\ntry:\n    from .training_contract_ast_utils import (\n        call_name,\n        collect_return_dict_keys,\n        collect_training_section_keys_used_by_wiring,\n        load_module,\n    )\nexcept ImportError:\n    from training_contract_ast_utils import (  # type: ignore[no-redef]\n        call_name,\n        collect_return_dict_keys,\n        collect_training_section_keys_used_by_wiring,\n        load_module,\n    )\n\n\nclass TrainingDecompositionContractTests(unittest.TestCase):\n    \"\"\"Verify the training interface facade composes focused helper modules.\"\"\"\n\n    def test_training_facade_imports_tab_helpers(self) -> None:\n        \"\"\"``training.py`` should import dataset, LoRA, and LoKr helper modules.\"\"\"\n\n        module = load_module(\"training.py\")\n        imported_modules = []\n        for node in ast.walk(module):\n            if isinstance(node, ast.ImportFrom) and node.module:\n                imported_modules.append(node.module)\n\n        self.assertIn(\n            \"acestep.ui.gradio.interfaces.training_dataset_builder_tab\",\n            imported_modules,\n        )\n        self.assertIn(\"acestep.ui.gradio.interfaces.training_lora_tab\", imported_modules)\n        self.assertIn(\"acestep.ui.gradio.interfaces.training_lokr_tab\", imported_modules)\n\n    def test_training_facade_merges_helper_sections(self) -> None:\n        \"\"\"``training.py`` should compose helper returns into one training-section map.\"\"\"\n\n        module = load_module(\"training.py\")\n        call_names: list[str] = []\n        update_calls = 0\n        for node in ast.walk(module):\n            if not isinstance(node, ast.Call):\n                continue\n            name = call_name(node.func)\n            if name:\n                call_names.append(name)\n            if isinstance(node.func, ast.Attribute) and node.func.attr == \"update\":\n                update_calls += 1\n\n        self.assertIn(\"create_dataset_builder_tab\", call_names)\n        self.assertIn(\"create_training_lora_tab\", call_names)\n        self.assertIn(\"create_training_lokr_tab\", call_names)\n        self.assertGreaterEqual(update_calls, 4)\n\n    def test_dataset_builder_tab_delegates_to_section_builders(self) -> None:\n        \"\"\"Dataset-builder facade should delegate to scan/label/preprocess builders.\"\"\"\n\n        module = load_module(\"training_dataset_builder_tab.py\")\n        call_names: list[str] = []\n        for node in ast.walk(module):\n            if isinstance(node, ast.Call):\n                name = call_name(node.func)\n                if name:\n                    call_names.append(name)\n\n        self.assertIn(\"build_dataset_scan_and_settings_controls\", call_names)\n        self.assertIn(\"build_dataset_label_and_preview_controls\", call_names)\n        self.assertIn(\"build_dataset_save_and_preprocess_controls\", call_names)\n\n    def test_training_keys_cover_wiring_requirements(self) -> None:\n        \"\"\"Returned training keys should cover all keys consumed by wiring modules.\"\"\"\n\n        produced_keys: set[str] = set()\n        key_sources = [\n            (\"training.py\", \"create_training_section\"),\n            (\"training_dataset_tab_scan_settings.py\", \"build_dataset_scan_and_settings_controls\"),\n            (\n                \"training_dataset_tab_label_preview.py\",\n                \"build_dataset_label_and_preview_controls\",\n            ),\n            (\n                \"training_dataset_tab_save_preprocess.py\",\n                \"build_dataset_save_and_preprocess_controls\",\n            ),\n            (\"training_lora_tab_dataset.py\", \"build_lora_dataset_and_adapter_controls\"),\n            (\"training_lora_tab_run_export.py\", \"build_lora_run_and_export_controls\"),\n            (\"training_lokr_tab_dataset.py\", \"build_lokr_dataset_and_adapter_controls\"),\n            (\"training_lokr_tab_run_export.py\", \"build_lokr_run_and_export_controls\"),\n        ]\n        for module_name, function_name in key_sources:\n            produced_keys |= collect_return_dict_keys(module_name, function_name)\n\n        required_keys = collect_training_section_keys_used_by_wiring()\n        self.assertTrue(\n            required_keys.issubset(produced_keys),\n            f\"Missing training_section keys: {sorted(required_keys - produced_keys)}\",\n        )\n\n    def test_training_ui_markers_preserved(self) -> None:\n        \"\"\"Key emoji UI markers should remain present after decomposition.\"\"\"\n\n        interfaces_dir = Path(__file__).resolve().parent\n        expected_markers = {\n            \"training.py\": [\"🎵 LoRA Training for ACE-Step\"],\n            \"training_dataset_tab_scan_settings.py\": [\"📂 Load Existing Dataset\", \"🔍 Scan New Directory\"],\n            \"training_dataset_tab_label_preview.py\": [\"🤖\", \"👀\"],\n            \"training_dataset_tab_save_preprocess.py\": [\"💾\", \"⚡\"],\n            \"training_lora_tab_dataset.py\": [\"📊\", \"⚙️\"],\n            \"training_lora_tab_run_export.py\": [\"🎛️\", \"📦\"],\n            \"training_lokr_tab_run_export.py\": [\"🎛️\", \"📦\"],\n        }\n        for module_name, markers in expected_markers.items():\n            source = (interfaces_dir / module_name).read_text(encoding=\"utf-8\")\n            for marker in markers:\n                self.assertIn(marker, source, f\"Missing marker {marker!r} in {module_name}\")\n\n    def test_lokr_helpers_use_i18n_translation_calls(self) -> None:\n        \"\"\"LoKr modules should import and call ``t(...)`` for user-facing labels.\"\"\"\n\n        for module_name in (\n            \"training_lokr_tab.py\",\n            \"training_lokr_tab_dataset.py\",\n            \"training_lokr_tab_run_export.py\",\n        ):\n            module = load_module(module_name)\n            imported_i18n = False\n            call_names: list[str] = []\n            for node in ast.walk(module):\n                if (\n                    isinstance(node, ast.ImportFrom)\n                    and node.module == \"acestep.ui.gradio.i18n\"\n                    and any(alias.name == \"t\" for alias in node.names)\n                ):\n                    imported_i18n = True\n                if isinstance(node, ast.Call):\n                    name = call_name(node.func)\n                    if name:\n                        call_names.append(name)\n\n            self.assertTrue(imported_i18n, f\"{module_name} does not import t from i18n\")\n            self.assertIn(\"t\", call_names, f\"{module_name} does not call t(...)\")\n\n\nif __name__ == \"__main__\":\n    unittest.main()\n"
  },
  {
    "path": "acestep/ui/gradio/interfaces/training_lokr_tab.py",
    "content": "\"\"\"LoKr training-tab facade for the Gradio training interface.\"\"\"\n\nfrom __future__ import annotations\n\nimport gradio as gr\n\nfrom acestep.ui.gradio.help_content import create_help_button\nfrom acestep.ui.gradio.i18n import t\nfrom acestep.ui.gradio.interfaces.training_lokr_tab_dataset import (\n    build_lokr_dataset_and_adapter_controls,\n)\nfrom acestep.ui.gradio.interfaces.training_lokr_tab_run_export import (\n    build_lokr_run_and_export_controls,\n)\n\n\ndef create_training_lokr_tab() -> dict[str, object]:\n    \"\"\"Create the LoKr training tab and return component handles for wiring.\"\"\"\n\n    with gr.Tab(t(\"training.tab_train_lokr\")):\n        create_help_button(\"training_lokr\")\n        tab_controls: dict[str, object] = {}\n        tab_controls.update(build_lokr_dataset_and_adapter_controls())\n        tab_controls.update(build_lokr_run_and_export_controls())\n    return tab_controls\n"
  },
  {
    "path": "acestep/ui/gradio/interfaces/training_lokr_tab_dataset.py",
    "content": "\"\"\"LoKr tab dataset and adapter-setting controls.\"\"\"\n\nfrom __future__ import annotations\n\nimport gradio as gr\n\nfrom acestep.ui.gradio.i18n import t\n\n\ndef build_lokr_dataset_and_adapter_controls() -> dict[str, object]:\n    \"\"\"Render LoKr dataset selector and adapter-parameter controls.\"\"\"\n\n    with gr.Row():\n        with gr.Column(scale=2):\n            gr.HTML(f\"<h3>📊 {t('training.lokr_section_tensors')}</h3>\")\n            gr.Markdown(t(\"training.lokr_tensor_selection_desc\"))\n\n            lokr_training_tensor_dir = gr.Textbox(\n                label=t(\"training.preprocessed_tensors_dir\"),\n                placeholder=\"./datasets/preprocessed_tensors\",\n                value=\"./datasets/preprocessed_tensors\",\n                info=t(\"training.preprocessed_tensors_info\"),\n                elem_classes=[\"has-info-container\"],\n            )\n\n            lokr_load_dataset_btn = gr.Button(t(\"training.load_dataset_btn\"), variant=\"secondary\")\n\n            lokr_training_dataset_info = gr.Textbox(\n                label=t(\"training.dataset_info\"),\n                interactive=False,\n                lines=3,\n            )\n\n        with gr.Column(scale=1):\n            gr.HTML(f\"<h3>⚙️ {t('training.lokr_section_settings')}</h3>\")\n\n            lokr_linear_dim = gr.Slider(\n                minimum=4,\n                maximum=256,\n                step=4,\n                value=64,\n                label=t(\"training.lokr_linear_dim\"),\n                info=t(\"training.lokr_linear_dim_info\"),\n                elem_classes=[\"has-info-container\"],\n            )\n            lokr_linear_alpha = gr.Slider(\n                minimum=4,\n                maximum=512,\n                step=4,\n                value=128,\n                label=t(\"training.lokr_linear_alpha\"),\n                info=t(\"training.lokr_linear_alpha_info\"),\n                elem_classes=[\"has-info-container\"],\n            )\n            lokr_factor = gr.Number(\n                label=t(\"training.lokr_factor\"),\n                value=-1,\n                precision=0,\n                info=t(\"training.lokr_factor_info\"),\n                elem_classes=[\"has-info-container\"],\n            )\n            lokr_decompose_both = gr.Checkbox(\n                label=t(\"training.lokr_decompose_both\"),\n                value=False,\n                info=t(\"training.lokr_decompose_both_info\"),\n                elem_classes=[\"has-info-container\"],\n            )\n            lokr_use_tucker = gr.Checkbox(\n                label=t(\"training.lokr_use_tucker\"),\n                value=False,\n                info=t(\"training.lokr_use_tucker_info\"),\n                elem_classes=[\"has-info-container\"],\n            )\n            lokr_use_scalar = gr.Checkbox(\n                label=t(\"training.lokr_use_scalar\"),\n                value=False,\n                info=t(\"training.lokr_use_scalar_info\"),\n                elem_classes=[\"has-info-container\"],\n            )\n            lokr_weight_decompose = gr.Checkbox(\n                label=t(\"training.lokr_weight_decompose\"),\n                value=True,\n                info=t(\"training.lokr_weight_decompose_info\"),\n                elem_classes=[\"has-info-container\"],\n            )\n\n    return {\n        \"lokr_training_tensor_dir\": lokr_training_tensor_dir,\n        \"lokr_load_dataset_btn\": lokr_load_dataset_btn,\n        \"lokr_training_dataset_info\": lokr_training_dataset_info,\n        \"lokr_linear_dim\": lokr_linear_dim,\n        \"lokr_linear_alpha\": lokr_linear_alpha,\n        \"lokr_factor\": lokr_factor,\n        \"lokr_decompose_both\": lokr_decompose_both,\n        \"lokr_use_tucker\": lokr_use_tucker,\n        \"lokr_use_scalar\": lokr_use_scalar,\n        \"lokr_weight_decompose\": lokr_weight_decompose,\n    }\n"
  },
  {
    "path": "acestep/ui/gradio/interfaces/training_lokr_tab_run_export.py",
    "content": "\"\"\"LoKr tab run and export controls.\"\"\"\n\nfrom __future__ import annotations\n\nimport gradio as gr\n\nfrom acestep.ui.gradio.i18n import t\n\n\ndef build_lokr_run_and_export_controls() -> dict[str, object]:\n    \"\"\"Render LoKr training-run and export controls for the training tab.\"\"\"\n\n    gr.HTML(f\"<hr><h3>🎛️ {t('training.train_section_params')}</h3>\")\n\n    with gr.Row():\n        lokr_learning_rate = gr.Number(\n            label=t(\"training.learning_rate\"),\n            value=1e-3,\n            info=t(\"training.lokr_learning_rate_info\"),\n            elem_classes=[\"has-info-container\"],\n        )\n\n        lokr_train_epochs = gr.Slider(\n            minimum=1,\n            maximum=4000,\n            step=1,\n            value=500,\n            label=t(\"training.max_epochs\"),\n        )\n\n        lokr_train_batch_size = gr.Slider(\n            minimum=1,\n            maximum=8,\n            step=1,\n            value=1,\n            label=t(\"training.batch_size\"),\n        )\n\n        lokr_gradient_accumulation = gr.Slider(\n            minimum=1,\n            maximum=16,\n            step=1,\n            value=4,\n            label=t(\"training.gradient_accumulation\"),\n        )\n\n    with gr.Row():\n        lokr_save_every_n_epochs = gr.Slider(\n            minimum=1,\n            maximum=1000,\n            step=1,\n            value=10,\n            label=t(\"training.save_every_n_epochs\"),\n        )\n\n        lokr_training_shift = gr.Slider(\n            minimum=1.0,\n            maximum=5.0,\n            step=0.5,\n            value=3.0,\n            label=t(\"training.shift\"),\n            info=t(\"training.shift_info\"),\n            elem_classes=[\"has-info-container\"],\n        )\n\n        lokr_training_seed = gr.Number(\n            label=t(\"training.seed\"),\n            value=42,\n            precision=0,\n        )\n\n    with gr.Row():\n        lokr_output_dir = gr.Textbox(\n            label=t(\"training.output_dir\"),\n            value=\"./lokr_output\",\n            placeholder=\"./lokr_output\",\n            info=t(\"training.lokr_output_dir_info\"),\n            elem_classes=[\"has-info-container\"],\n        )\n\n    gr.HTML(\"<hr>\")\n\n    with gr.Row():\n        with gr.Column(scale=1):\n            start_lokr_training_btn = gr.Button(\n                t(\"training.start_lokr_training_btn\"),\n                variant=\"primary\",\n                size=\"lg\",\n            )\n        with gr.Column(scale=1):\n            stop_lokr_training_btn = gr.Button(\n                t(\"training.stop_training_btn\"),\n                variant=\"stop\",\n                size=\"lg\",\n            )\n\n    lokr_training_progress = gr.Textbox(\n        label=t(\"training.training_progress\"),\n        interactive=False,\n        lines=2,\n    )\n\n    with gr.Row():\n        lokr_training_log = gr.Textbox(\n            label=t(\"training.training_log\"),\n            interactive=False,\n            lines=10,\n            max_lines=15,\n            scale=1,\n        )\n        lokr_training_loss_plot = gr.Plot(\n            label=t(\"training.lokr_training_loss_title\"),\n            scale=1,\n        )\n\n    gr.HTML(f\"<hr><h3>📦 {t('training.lokr_export_header')}</h3>\")\n\n    with gr.Row():\n        lokr_export_path = gr.Textbox(\n            label=t(\"training.export_path\"),\n            value=\"./lokr_output/final_lokr\",\n            placeholder=\"./lokr_output/my_lokr\",\n        )\n        export_lokr_btn = gr.Button(t(\"training.export_lokr_btn\"), variant=\"secondary\")\n\n    with gr.Row():\n        lokr_export_epoch = gr.Dropdown(\n            choices=[t(\"training.latest_auto\")],\n            value=t(\"training.latest_auto\"),\n            label=t(\"training.lokr_checkpoint_epoch\"),\n            info=t(\"training.lokr_checkpoint_epoch_info\"),\n            elem_classes=[\"has-info-container\"],\n        )\n        refresh_lokr_export_epochs_btn = gr.Button(\n            t(\"training.refresh_epochs_btn\"), variant=\"secondary\"\n        )\n\n    lokr_export_status = gr.Textbox(\n        label=t(\"training.export_status\"),\n        interactive=False,\n    )\n\n    return {\n        \"lokr_learning_rate\": lokr_learning_rate,\n        \"lokr_train_epochs\": lokr_train_epochs,\n        \"lokr_train_batch_size\": lokr_train_batch_size,\n        \"lokr_gradient_accumulation\": lokr_gradient_accumulation,\n        \"lokr_save_every_n_epochs\": lokr_save_every_n_epochs,\n        \"lokr_training_shift\": lokr_training_shift,\n        \"lokr_training_seed\": lokr_training_seed,\n        \"lokr_output_dir\": lokr_output_dir,\n        \"start_lokr_training_btn\": start_lokr_training_btn,\n        \"stop_lokr_training_btn\": stop_lokr_training_btn,\n        \"lokr_training_progress\": lokr_training_progress,\n        \"lokr_training_log\": lokr_training_log,\n        \"lokr_training_loss_plot\": lokr_training_loss_plot,\n        \"lokr_export_path\": lokr_export_path,\n        \"lokr_export_epoch\": lokr_export_epoch,\n        \"refresh_lokr_export_epochs_btn\": refresh_lokr_export_epochs_btn,\n        \"export_lokr_btn\": export_lokr_btn,\n        \"lokr_export_status\": lokr_export_status,\n    }\n"
  },
  {
    "path": "acestep/ui/gradio/interfaces/training_lora_tab.py",
    "content": "\"\"\"LoRA training-tab facade for the Gradio training interface.\"\"\"\n\nfrom __future__ import annotations\n\nimport gradio as gr\n\nfrom acestep.ui.gradio.help_content import create_help_button\nfrom acestep.ui.gradio.i18n import t\nfrom acestep.ui.gradio.interfaces.training_lora_tab_dataset import (\n    build_lora_dataset_and_adapter_controls,\n)\nfrom acestep.ui.gradio.interfaces.training_lora_tab_run_export import (\n    build_lora_run_and_export_controls,\n)\n\n\ndef create_training_lora_tab(\n    *,\n    epoch_min: int,\n    epoch_step: int,\n    epoch_default: int,\n) -> dict[str, object]:\n    \"\"\"Create the LoRA training tab and return component handles for wiring.\"\"\"\n\n    with gr.Tab(t(\"training.tab_train_lora\")):\n        create_help_button(\"training_train\")\n        tab_controls: dict[str, object] = {}\n        tab_controls.update(build_lora_dataset_and_adapter_controls())\n        tab_controls.update(\n            build_lora_run_and_export_controls(\n                epoch_min=epoch_min,\n                epoch_step=epoch_step,\n                epoch_default=epoch_default,\n            )\n        )\n    return tab_controls\n"
  },
  {
    "path": "acestep/ui/gradio/interfaces/training_lora_tab_dataset.py",
    "content": "\"\"\"LoRA tab dataset and adapter-setting controls.\"\"\"\n\nfrom __future__ import annotations\n\nimport gradio as gr\n\nfrom acestep.ui.gradio.i18n import t\n\n\ndef build_lora_dataset_and_adapter_controls() -> dict[str, object]:\n    \"\"\"Render LoRA dataset selector and adapter-parameter controls.\"\"\"\n\n    with gr.Row():\n        with gr.Column(scale=2):\n            gr.HTML(f\"<h3>📊 {t('training.train_section_tensors')}</h3>\")\n            gr.Markdown(t(\"training.train_tensor_selection_desc\"))\n\n            training_tensor_dir = gr.Textbox(\n                label=t(\"training.preprocessed_tensors_dir\"),\n                placeholder=\"./datasets/preprocessed_tensors\",\n                value=\"./datasets/preprocessed_tensors\",\n                info=t(\"training.preprocessed_tensors_info\"),\n                elem_classes=[\"has-info-container\"],\n            )\n\n            load_dataset_btn = gr.Button(t(\"training.load_dataset_btn\"), variant=\"secondary\")\n\n            training_dataset_info = gr.Textbox(\n                label=t(\"training.dataset_info\"),\n                interactive=False,\n                lines=3,\n            )\n\n        with gr.Column(scale=1):\n            gr.HTML(f\"<h3>⚙️ {t('training.train_section_lora')}</h3>\")\n\n            lora_rank = gr.Slider(\n                minimum=4,\n                maximum=256,\n                step=4,\n                value=64,\n                label=t(\"training.lora_rank\"),\n                info=t(\"training.lora_rank_info\"),\n                elem_classes=[\"has-info-container\"],\n            )\n\n            lora_alpha = gr.Slider(\n                minimum=4,\n                maximum=512,\n                step=4,\n                value=128,\n                label=t(\"training.lora_alpha\"),\n                info=t(\"training.lora_alpha_info\"),\n                elem_classes=[\"has-info-container\"],\n            )\n\n            lora_dropout = gr.Slider(\n                minimum=0.0,\n                maximum=0.5,\n                step=0.05,\n                value=0.1,\n                label=t(\"training.lora_dropout\"),\n            )\n\n    return {\n        \"training_tensor_dir\": training_tensor_dir,\n        \"load_dataset_btn\": load_dataset_btn,\n        \"training_dataset_info\": training_dataset_info,\n        \"lora_rank\": lora_rank,\n        \"lora_alpha\": lora_alpha,\n        \"lora_dropout\": lora_dropout,\n    }\n"
  },
  {
    "path": "acestep/ui/gradio/interfaces/training_lora_tab_run_export.py",
    "content": "\"\"\"LoRA tab run and export controls.\"\"\"\n\nfrom __future__ import annotations\n\nimport gradio as gr\n\nfrom acestep.ui.gradio.i18n import t\n\n\ndef build_lora_run_and_export_controls(\n    *,\n    epoch_min: int,\n    epoch_step: int,\n    epoch_default: int,\n) -> dict[str, object]:\n    \"\"\"Render LoRA training-run and export controls for the training tab.\"\"\"\n\n    gr.HTML(f\"<hr><h3>🎛️ {t('training.train_section_params')}</h3>\")\n\n    with gr.Row():\n        learning_rate = gr.Number(\n            label=t(\"training.learning_rate\"),\n            value=3e-4,\n            info=t(\"training.learning_rate_info\"),\n            elem_classes=[\"has-info-container\"],\n        )\n\n        train_epochs = gr.Slider(\n            minimum=epoch_min,\n            maximum=4000,\n            step=epoch_step,\n            value=epoch_default,\n            label=t(\"training.max_epochs\"),\n        )\n\n        train_batch_size = gr.Slider(\n            minimum=1,\n            maximum=8,\n            step=1,\n            value=1,\n            label=t(\"training.batch_size\"),\n            info=t(\"training.batch_size_info\"),\n            elem_classes=[\"has-info-container\"],\n        )\n\n        gradient_accumulation = gr.Slider(\n            minimum=1,\n            maximum=16,\n            step=1,\n            value=1,\n            label=t(\"training.gradient_accumulation\"),\n            info=t(\"training.gradient_accumulation_info\"),\n            elem_classes=[\"has-info-container\"],\n        )\n\n    with gr.Row():\n        save_every_n_epochs = gr.Slider(\n            minimum=1,\n            maximum=1000,\n            step=1,\n            value=10,\n            label=t(\"training.save_every_n_epochs\"),\n        )\n\n        training_shift = gr.Slider(\n            minimum=1.0,\n            maximum=5.0,\n            step=0.5,\n            value=3.0,\n            label=t(\"training.shift\"),\n            info=t(\"training.shift_info\"),\n            elem_classes=[\"has-info-container\"],\n        )\n\n        training_seed = gr.Number(\n            label=t(\"training.seed\"),\n            value=42,\n            precision=0,\n        )\n\n    with gr.Row():\n        lora_output_dir = gr.Textbox(\n            label=t(\"training.output_dir\"),\n            value=\"./lora_output\",\n            placeholder=\"./lora_output\",\n            info=t(\"training.output_dir_info\"),\n            elem_classes=[\"has-info-container\"],\n        )\n\n    with gr.Row():\n        resume_checkpoint_dir = gr.Textbox(\n            label=\"Resume Checkpoint\",\n            placeholder=\"./lora_output/checkpoints/epoch_200\",\n            info=\"Directory of a saved LoRA checkpoint to resume from\",\n            elem_classes=[\"has-info-container\"],\n        )\n\n    gr.HTML(\"<hr>\")\n\n    with gr.Row():\n        with gr.Column(scale=1):\n            start_training_btn = gr.Button(\n                t(\"training.start_training_btn\"),\n                variant=\"primary\",\n                size=\"lg\",\n            )\n        with gr.Column(scale=1):\n            stop_training_btn = gr.Button(\n                t(\"training.stop_training_btn\"),\n                variant=\"stop\",\n                size=\"lg\",\n            )\n\n    training_progress = gr.Textbox(\n        label=t(\"training.training_progress\"),\n        interactive=False,\n        lines=2,\n    )\n\n    with gr.Row():\n        training_log = gr.Textbox(\n            label=t(\"training.training_log\"),\n            interactive=False,\n            lines=10,\n            max_lines=15,\n            scale=1,\n        )\n        training_loss_plot = gr.Plot(\n            label=t(\"training.training_loss_title\"),\n            scale=1,\n        )\n\n    gr.HTML(f\"<hr><h3>📦 {t('training.export_header')}</h3>\")\n\n    with gr.Row():\n        export_path = gr.Textbox(\n            label=t(\"training.export_path\"),\n            value=\"./lora_output/final_lora\",\n            placeholder=\"./lora_output/my_lora\",\n        )\n        export_lora_btn = gr.Button(t(\"training.export_lora_btn\"), variant=\"secondary\")\n\n    export_status = gr.Textbox(\n        label=t(\"training.export_status\"),\n        interactive=False,\n    )\n\n    return {\n        \"learning_rate\": learning_rate,\n        \"train_epochs\": train_epochs,\n        \"train_batch_size\": train_batch_size,\n        \"gradient_accumulation\": gradient_accumulation,\n        \"save_every_n_epochs\": save_every_n_epochs,\n        \"training_shift\": training_shift,\n        \"training_seed\": training_seed,\n        \"lora_output_dir\": lora_output_dir,\n        \"resume_checkpoint_dir\": resume_checkpoint_dir,\n        \"start_training_btn\": start_training_btn,\n        \"stop_training_btn\": stop_training_btn,\n        \"training_progress\": training_progress,\n        \"training_log\": training_log,\n        \"training_loss_plot\": training_loss_plot,\n        \"export_path\": export_path,\n        \"export_lora_btn\": export_lora_btn,\n        \"export_status\": export_status,\n    }\n"
  },
  {
    "path": "acestep/ui/streamlit/.gitignore",
    "content": "__pycache__/\n*.pyc\n.cache/\nprojects/\nstreamlit.log\n"
  },
  {
    "path": "acestep/ui/streamlit/.streamlit/config.toml",
    "content": "[theme]\nprimaryColor = \"#FF6B9D\"\nbackgroundColor = \"#0F1419\"\nsecondaryBackgroundColor = \"#262730\"\ntextColor = \"#FAFAFA\"\nfont = \"sans serif\"\n\n[client]\ntoolbarMode = \"minimal\"\nshowErrorDetails = true\n\n[browser]\ngatherUsageStats = false\n\n[logger]\nlevel = \"info\"\n\n[server]\nmaxUploadSize = 200\nenableXsrfProtection = true\nport = 8501\nheadless = true\n"
  },
  {
    "path": "acestep/ui/streamlit/.streamlit/secrets.toml",
    "content": "# Empty secrets file - prevents email prompt\n"
  },
  {
    "path": "acestep/ui/streamlit/INSTALL.md",
    "content": "\"\"\"\nACE Studio Streamlit - Installation & Setup Guide\n\"\"\"\n\n# Installation Instructions\n\n## Prerequisites\n\n- Python 3.8+ (tested with 3.11)\n- ACE-Step main project installed (parent directory)\n- pip or uv for package management\n\n## Step 1: Install Dependencies\n\nFrom the `acestep/ui/streamlit` directory:\n\n```bash\npip install -r requirements.txt\n```\n\nOr with uv (faster):\n\n```bash\nuv pip install -r requirements.txt\n```\n\n## Step 2: Configure (Optional)\n\nEdit `config.py` to customize:\n- Default generation parameters\n- UI appearance\n- Storage paths\n- Audio formats\n\n## Step 3: Run the App\n\n```bash\nstreamlit run main.py\n```\n\nThe app will open at `http://localhost:8501`\n\n## System Requirements\n\n### Minimum\n- 4GB VRAM (CPU only)\n- Intel i5 or equivalent\n- 2GB RAM\n\n### Recommended\n- 8GB+ VRAM (GPU)\n- RTX 3060 or equivalent\n- 8GB+ RAM\n\n### Optimal\n- 16GB+ VRAM\n- RTX 4090 or A100\n- 16GB+ RAM\n\n## GPU Support\n\n### CUDA (NVIDIA)\nPreinstalled CUDA 12.1+\n\n### ROCm (AMD)\nSet environment variable:\n```bash\nexport PYTORCH_HIP_ALLOC_CONF=\":256:8\"\n```\n\n### MPS (Apple Silicon)\nAutomatic detection and use\n\n### CPU\nWorks but slow; set device to CPU in Settings\n\n## Troubleshooting Installation\n\n### Module not found errors\n```bash\n# Reinstall ACE-Step dependencies\ncd ..  # Go to main ACE-Step dir\npip install -e .\n```\n\n### Streamlit port already in use\n```bash\nstreamlit run main.py --server.port 8502\n```\n\n### Clear cache and restart\n```bash\nstreamlit cache clear\nstreamlit run main.py\n```\n\n## Docker Deployment (Optional)\n\nCreate `Dockerfile`:\n```dockerfile\nFROM python:3.11-slim\nWORKDIR /app\nCOPY requirements.txt .\nRUN pip install -r requirements.txt\nCOPY . .\nEXPOSE 8501\nCMD [\"streamlit\", \"run\", \"main.py\", \"--server.port=8501\", \"--server.address=0.0.0.0\"]\n```\n\nBuild and run:\n```bash\ndocker build -t ace-studio .\ndocker run -p 8501:8501 -v $(pwd)/projects:/app/projects ace-studio\n```\n\n## Environment Variables\n\nOptional `.env` file:\n\n```env\n# GPU Configuration\nDEVICE=cuda\nOFFLOAD_CPU=1\nFLASHATTN=1\n\n# Model Configuration\nDIT_MODEL=acestep-v15-turbo\nLLM_MODEL=1.7B\n\n# UI Configuration\nMAX_BATCH_SIZE=4\nDEFAULT_DURATION=120\nDEFAULT_BPM=120\n\n# Storage\nPROJECTS_DIR=./projects\nCACHE_DIR=./.cache\n```\n\n## Next Steps\n\n1. Go to **Dashboard** for quick start\n2. Try **Generate** to create first song\n3. Explore **Edit** features\n4. Check **Settings** for optimal configuration\n\n## Getting Help\n\n- 📖 See README.md for usage guide\n- 🐛 Report issues on GitHub\n- 💬 Ask in Discord community\n- 📚 Check ACE-Step documentation\n"
  },
  {
    "path": "acestep/ui/streamlit/PROJECT_SUMMARY.md",
    "content": "# 🎹 ACE Studio Streamlit MVP - Complete\n\n## ✅ Project Created Successfully!\n\nA modern Streamlit UI for ACE-Step music generation, located in:\n```\nacestep/ui/streamlit/\n```\n\n## 📦 What's Included\n\n### Core Files (5)\n- **main.py** - Main Streamlit app with routing and navigation\n- **config.py** - Centralized configuration for all settings\n- **requirements.txt** - Python dependencies (Streamlit, librosa, plotly, etc.)\n- **.streamlit/config.toml** - Streamlit theme and layout configuration\n- **run.sh / run.bat** - Quick-start scripts (macOS/Linux/Windows)\n\n### Components (7)\n1. **dashboard.py** - Home page with recent projects and quick-start cards\n2. **generation_wizard.py** - Multi-step song creation (inspiration → structure → advanced)\n3. **editor.py** - Audio editing (repaint, cover, extract, complete)\n4. **batch_generator.py** - Generate up to 8 songs simultaneously\n5. **settings_panel.py** - Hardware, models, storage configuration\n6. **audio_player.py** - Audio player widget with controls\n7. **__init__.py** - Component exports\n\n### Utilities (4)\n1. **cache.py** - LLM & DiT handler caching (persistent across reruns)\n2. **project_manager.py** - Project save/load, metadata tracking\n3. **audio_utils.py** - Audio file handling and analysis\n4. **__init__.py** - Utility exports\n\n### Documentation (4)\n1. **README.md** - Full user guide and feature documentation\n2. **INSTALL.md** - Detailed installation and troubleshooting\n3. **QUICKSTART.md** - Quick start guide (you are here!)\n4. **config.py** - Inline documentation for customization\n\n### Auto-Created Directories\n- **projects/** - Where generated songs are saved\n- **.cache/** - Model cache directory\n\n## 🎯 Key Features\n\n### 📊 Dashboard\n- Browse recent projects with thumbnails\n- Quick-play, edit, or delete buttons\n- Project statistics (total duration, favorite mood/genre)\n- One-click access to generate or batch operations\n\n### 🎵 Generation Wizard (3 Steps)\n1. **Inspiration** - Genre/mood selector or free-text description\n2. **Structure** - Duration, BPM, key, optional lyrics\n3. **Advanced** - Diffusion steps, guidance scale, AI reasoning toggle\n\n### 🎛️ Audio Editor\n- **Repaint** - Replace time section with new generation\n- **Cover** - Create cover versions with reference audio\n- **Extract** - Isolate vocals, drums, or stems\n- **Complete** - Generate missing sections of songs\n\n### 📦 Batch Generator\n- Queue up to 8 songs\n- Parallel processing support\n- Per-song progress tracking\n- Automatic project creation\n\n### ⚙️ Settings\n- Hardware info (GPU, CUDA, VRAM)\n- Model selection and backend configuration\n- Storage management (clear cache, open projects folder)\n- Links to ACE-Step resources\n\n## 🚀 How to Run\n\n### Quickest (Recommended)\n```bash\ncd acestep/ui/streamlit\n./run.sh    # macOS/Linux\n# or\nrun.bat     # Windows\n```\n\n### Manual\n```bash\ncd acestep/ui/streamlit\npip install -r requirements.txt\nstreamlit run main.py\n```\n\nOpens at: **http://localhost:8501**\n\n## 🔄 Architecture\n\n```\n┌─────────────────────────────────────────────────────┐\n│           STREAMLIT FRONTEND (main.py)              │\n│  Navigation + Sidebar + Tab Routing                 │\n└────────────────┬────────────────────────────────────┘\n                 │\n      ┌──────────┴──────────────────┬──────────────┐\n      │                             │              │\n┌─────▼──────┐  ┌────────────────┐  │ ┌──────────┐ │\n│ Components │  │    Utilities   │  │ │ Config   │ │\n├────────────┤  ├────────────────┤  │ └──────────┘ │\n│ Dashboard  │  │ ProjectManager │  │              │\n│ Generate   │  │ AudioUtils     │  │              │\n│ Editor     │  │ Caching        │  │              │\n│ Batch      │  │ Handlers       │  │              │\n│ Settings   │  │                │  │              │\n└─────┬──────┘  └────────┬───────┘  │              │\n      └──────────────────┴──────────┴──────────────┘\n                 │\n         ┌───────▼──────────┐\n         │   ACE-Step       │\n         │   Handlers       │\n         ├──────────────────┤\n         │ AceStepHandler   │\n         │ LLMHandler       │\n         │ DatasetHandler   │\n         └────────┬─────────┘\n                  │\n          ┌───────▼──────────┐\n          │ PyTorch + CUDA   │\n          │ MPS / CPU / ROCm │\n          └──────────────────┘\n```\n\n## 📋 Usage Workflow\n\n1. **Start App** → Opens to Dashboard (shows recent projects)\n2. **Generate** → Use wizard to describe new song\n3. **Generate** → Song saves to projects with metadata\n4. **Edit** → Repaint sections, create covers, extract vocals\n5. **Batch** → Queue multiple songs for simultaneous generation\n6. **Settings** → Configure GPU, models, storage as needed\n\n## 🎨 UI Design Improvements Over Gradio\n\n| Aspect | Gradio | ACE Studio |\n|--------|--------|-----------|\n| **Landing** | Config form | Creative dashboard |\n| **Generation** | Single form | 3-step wizard |\n| **Tasks** | Buried in dropdown | Prominent tabs |\n| **Projects** | File browser | Grid with metadata |\n| **Editing** | Regenerate scratch | Section-based tools |\n| **Batch** | Separate page | Integrated queue |\n| **Feedback** | Text logs | Progress bars & status |\n| **Mobile** | Limited | Responsive layout |\n\n## 🔧 Customization\n\nEdit `config.py` to change:\n```python\n# UI defaults\nDEFAULT_DURATION = 120\nDEFAULT_BPM = 120\nDEFAULT_GUIDANCE = 7.5\n\n# Available options in UI\nGENRES = [\"Pop\", \"Hip-Hop\", \"Jazz\", ...]\nMOODS = [\"Energetic\", \"Chill\", ...]\nINSTRUMENTS = [\"Guitar\", \"Piano\", ...]\n\n# Storage paths\nPROJECTS_DIR = \"./projects\"\nCACHE_DIR = \"./.cache\"\n```\n\n## 📊 File Statistics\n\n```\nTotal Files: 21\n├── Python Modules: 14 (main, components, utils, config)\n├── Documentation: 4 (README, INSTALL, QUICKSTART, inline)\n├── Configuration: 2 (.toml, config.py)\n├── Scripts: 2 (run.sh, run.bat)\n├── Data: 1 (requirements.txt)\n└── Auto-created: 2+ (projects/, .cache/)\n\nTotal Lines of Code: ~2,000+\nComponents: 7 (Dashboard, Generate, Editor, Batch, Settings, Audio, __init__)\nUtilities: 4 (Cache, ProjectManager, Audio, __init__)\n```\n\n## 🎓 Next Steps\n\n### Immediate (v0.1.0 - Current)\n- ✅ Core generation and editing UI\n- ✅ Project management\n- ✅ Batch operations\n- ✅ Settings panel\n\n### Phase 2 (v0.2.0)\n- [ ] Waveform visualization (wavesurfer.js integration)\n- [ ] Real-time progress with visualization\n- [ ] Bot preset save/load\n- [ ] Advanced audio analysis\n\n### Phase 3 (v0.3.0)\n- [ ] Mixing console (multi-track)\n- [ ] Lyrics editor with sync\n- [ ] Export formats (MP3, FLAC)\n- [ ] Cloud sync\n\n### Phase 4+ (v0.4.0+)\n- [ ] Electron wrapper for desktop\n- [ ] React upgrade for waveform editor\n- [ ] Collaborative features\n- [ ] Mobile app\n\n## 💡 Integration Points\n\n### With ACE-Step\n- Uses existing `AceStepHandler` (DiT model)\n- Uses `LLMHandler` for metadata generation\n- Compatible with all GenerationParams\n- Supports all task types (text2music, cover, repaint, lego, extract, complete)\n- Works with all GPU backends (CUDA, ROCm, MPS, CPU)\n\n### With Existing API\n- Can be deployed alongside `api_server.py`\n- Uses same model checkpoints and handlers\n- Extends rather than replaces existing UI\n- Backward compatible\n\n## 🔗 Links\n\n```\nACE-Step Repository\n└── acestep/ui/streamlit/\n    ├── main.py                 # Entry point\n    ├── config.py              # Customization\n    ├── components/            # UI sections\n    │   ├── dashboard.py       # Home page\n    │   ├── generation_wizard.py # Song creation\n    │   ├── editor.py          # Audio editing\n    │   ├── batch_generator.py # Multi-song gen\n    │   ├── settings_panel.py  # Configuration\n    │   └── audio_player.py    # Audio playback\n    ├── utils/                 # Helpers\n    │   ├── cache.py          # Model caching\n    │   ├── project_manager.py # Project management\n    │   └── audio_utils.py    # Audio processing\n    ├── projects/             # Generated songs\n    └── Documentation\n        ├── README.md         # Full guide\n        ├── INSTALL.md        # Installation\n        └── QUICKSTART.md     # Quick start\n```\n\n## 🎉 You're All Set!\n\nEverything is ready to go. Start creating music!\n\n```bash\ncd acestep/ui/streamlit\n./run.sh\n# 🚀 Opens at http://localhost:8501\n```\n\nQuestions? Check **README.md** or **INSTALL.md**!\n\nHappy music making! 🎵🎸🎹\n"
  },
  {
    "path": "acestep/ui/streamlit/QUICKSTART.md",
    "content": "# 🎹 ACE Studio Streamlit MVP - Quick Start Guide\n\n## ✅ What Was Created\n\nA complete Streamlit UI for ACE-Step v1.5 music generation with these features:\n\n### 📁 Project Structure\n```\nacestep/ui/streamlit/\n├── main.py                 # Main Streamlit app (entry point)\n├── config.py              # Configuration & constants\n├── requirements.txt       # Python dependencies\n├── README.md             # Full documentation\n├── INSTALL.md            # Installation guide\n├── run.sh / run.bat      # Quick start scripts\n│\n├── components/           # UI components\n│   ├── dashboard.py      # Home with recent projects\n│   ├── generation_wizard.py  # Create new songs\n│   ├── editor.py         # Edit existing songs\n│   ├── batch_generator.py   # Multi-song generation\n│   ├── settings_panel.py    # Configuration\n│   └── audio_player.py   # Audio playback\n│\n├── utils/                # Utility modules\n│   ├── cache.py          # Model handler caching\n│   ├── project_manager.py # Project save/load\n│   └── audio_utils.py    # Audio file handling\n│\n└── projects/             # Auto-created: saved projects\n```\n\n## 🚀 Getting Started\n\n### Option 1: Quick Start (Recommended)\n\n```bash\ncd acestep/ui/streamlit\n./run.sh  # macOS/Linux\n# or\nrun.bat   # Windows\n```\n\n### Option 2: Manual Start\n\n```bash\ncd acestep/ui/streamlit\n\n# Install dependencies (one-time)\npip install -r requirements.txt\n\n# Run the app\nstreamlit run main.py\n```\n\nThe app will open at: **http://localhost:8501**\n\n## 📋 Features Overview\n\n### 🎵 Generate Tab\n- **Step 1:** Choose genre/mood or describe your song\n- **Step 2:** Set duration, BPM, key, lyrics\n- **Step 3:** Fine-tune advanced settings\n- Creates new project and saves metadata\n\n### 🎛️ Edit Tab\n- **Repaint:** Replace sections of audio\n- **Cover:** Create cover versions\n- **Extract:** Isolate vocals/stems\n- **Complete:** Generate missing sections\n\n### 📦 Batch Tab\n- Queue up to 8 songs\n- Batch generation with parallel processing\n- See progress for each song\n- Automatic project creation\n\n### 📊 Dashboard Tab\n- View recent projects with metadata\n- Quick play/edit/delete buttons\n- Project statistics\n- One-click access to favorite songs\n\n### ⚙️ Settings Tab\n- Hardware info (GPU, CUDA, VRAM)\n- Model selection and configuration\n- Storage management and file cleanup\n- Links to ACE-Step resources\n\n## 💾 Project Management\n\nAll generated songs are saved in `projects/` directory with:\n- **Metadata** (genre, mood, BPM, duration, tags)\n- **Audio files** (WAV format)\n- **Creation/modification dates**\n\nProjects can be:\n- ✅ Played directly in UI\n- ✅ Downloaded as WAV files\n- ✅ Edited with advanced tools\n- ✅ Deleted or renamed\n- ✅ Tagged and organized\n\n## 🔧 Configuration\n\nEdit `config.py` to customize:\n\n```python\n# Generation defaults\nDEFAULT_DURATION = 120      # seconds\nDEFAULT_BPM = 120\nDEFAULT_GUIDANCE = 7.5\nDEFAULT_STEPS = 32\n\n# UI options\nGENRES = [\"Pop\", \"Hip-Hop\", \"Jazz\", ...]\nMOODS = [\"Energetic\", \"Chill\", ...]\nINSTRUMENTS = [\"Guitar\", \"Piano\", ...]\n\n# Storage\nPROJECTS_DIR = \"./projects\"\nCACHE_DIR = \"./.cache\"\n```\n\n## 🎮 Usage Workflow\n\n1. **Start at Dashboard** → See all your songs\n2. **Generate** → Create new song with wizard\n3. **Edit** → Refine sections with editing tools\n4. **Batch** → Generate multiple variations\n5. **Settings** → Configure GPU/models as needed\n\n## 📊 Architecture\n\n```\nStreamlit Frontend\n  ↓\nSession State Management\n  ↓\nComponent Modules (Generation, Editor, etc.)\n  ↓\nUtility Layer (Project Manager, Audio Utils, Caching)\n  ↓\nACE-Step Handlers\n  - AceStepHandler (DiT - Diffusion Transformer)\n  - LLMHandler (Language Model for metadata)\n  - DatasetHandler (Training data)\n  ↓\nPyTorch + CUDA/MPS/CPU\n```\n\n## 🔄 Integration with ACE-Step\n\nThe Streamlit UI connects to ACE-Step via:\n\n1. **Handler Caching** (`utils/cache.py`)\n   - Loads DIT and LLM handlers once\n   - Persists across Streamlit reruns\n   - Efficient VRAM usage\n\n2. **Generation Parameters** (from `acestep.inference`)\n   - Accepts all ACE-Step GenerationParams\n   - Supports all task types (text2music, cover, repaint, etc.)\n   - Uses existing LM and DiT models\n\n3. **Project Storage**\n   - Saves generated audio files\n   - Tracks metadata with JSON\n   - Compatible with existing workflows\n\n## 📈 Next Steps (Future Roadmap)\n\n**Phase 2 (v0.2.0):**\n- [ ] Waveform visualization with interactive timeline\n- [ ] Real-time progress visualization\n- [ ] Preset save/load for generation settings\n- [ ] Audio analysis (BPM detection, key detection)\n\n**Phase 3 (v0.3.0):**\n- [ ] Advanced mixing console (multi-track editing)\n- [ ] Lyrics editor with music sync\n- [ ] Export to different formats (MP3, FLAC)\n- [ ] Cloud project sync\n\n**Phase 4 (v0.4.0):**\n- [ ] Electron wrapper for desktop app\n- [ ] React upgrade for waveform editor\n- [ ] Collaborative features\n- [ ] Mobile app\n\n## ⚡ Performance Tips\n\n1. **First generation:** Takes longer (model loading)\n2. **Use batch mode:** More efficient for multiple songs\n3. **Enable Flash Attention:** Faster if GPU supports it\n4. **Use turbo model:** Faster generation (lower quality)\n5. **Enable CPU offload:** Reduce VRAM usage\n\n## 🐛 Troubleshooting\n\n### Models not found\n```bash\n# Let first generation auto-download or:\ncd .. && python -m acestep.model_downloader\n```\n\n### Port 8501 already in use\n```bash\nstreamlit run main.py --server.port 8502\n```\n\n### Clear cache and start fresh\n```bash\nstreamlit cache clear && streamlit run main.py\n```\n\n### CUDA out of memory\n- Reduce inference steps in advanced settings\n- Enable CPU offload in settings\n- Use smaller model (turbo instead of base)\n\n## 📚 Documentation\n\n- **README.md** - Full user guide\n- **INSTALL.md** - Detailed installation\n- **config.py** - Configuration options\n- **Main.py** - App routing and structure\n\n## 🔗 Useful Links\n\n- 🌍 [ACE-Step Website](https://ace-step.github.io/)\n- 🤗 [HuggingFace Model](https://huggingface.co/ACE-Step/Ace-Step1.5)\n- 💬 [Discord Community](https://discord.gg/PeWDxrkdj7)\n- 📄 [Technical Paper](https://arxiv.org/abs/2602.00744)\n- 🐙 [GitHub Repository](https://github.com/ace-step/ACE-Step-1.5)\n\n## 🎯 Key Improvements Over Existing Gradio UI\n\n| Feature | Gradio | ACE Studio |\n|---------|--------|-----------|\n| **Entry Point** | Technical config | Creative wizard |\n| **Task Discovery** | Hidden dropdown | Prominent cards |\n| **Visual Feedback** | Text logs | Progress bars |\n| **Project Management** | Outputs folder | Dashboard with recents |\n| **Editing** | Regenerate scratch | Non-linear by region |\n| **Batch Support** | Separate UI | Integrated queue |\n| **Settings** | Always visible | Hidden, toggle-able |\n| **Mobile Support** | Poor | Responsive |\n\n## 📝 Notes for Developers\n\n- Config-driven design: Change `config.py` for UI customization\n- Component-based: Easy to add new editing modes\n- Session state management: Preserves state across reruns\n- Handler caching: Efficient GPU memory usage\n- Project persistence: JSON metadata + audio files\n\n---\n\n## 🎉 You're Ready!\n\nRun the app and start generating music!\n\n```bash\ncd acestep/ui/streamlit\n./run.sh  # or run.bat on Windows\n```\n\nQuestions? Check the docs or ask on Discord!\n\nHappy music making! 🎵\n"
  },
  {
    "path": "acestep/ui/streamlit/README.md",
    "content": "# ACE Studio - Streamlit UI for ACE-Step\n\nA modern, user-friendly Streamlit interface for [ACE-Step v1.5](https://github.com/ace-step/ACE-Step-1.5) music generation.\n\n## Features\n\n- 🎵 **Generate** - Create music from text descriptions\n- 🎤 **Cover** - Generate cover versions of songs\n- 🎨 **Edit** - Repaint song sections, extract vocals, complete sections\n- 📦 **Batch** - Generate up to 8 songs simultaneously\n- 💾 **Projects** - Save and organize your music creations\n- ⚙️ **Settings** - Configure hardware, models, and storage\n\n## Quick Start\n\n### Installation\n\n1. Install dependencies:\n```bash\npip install -r requirements.txt\n```\n\n2. Run the app:\n```bash\nstreamlit run main.py\n```\n\n3. Open your browser to `http://localhost:8501`\n\n### First Generation\n\n1. Go to **Generate** tab\n2. Describe your song (e.g., \"Upbeat pop with electric guitars\")\n3. Adjust duration, BPM, and other settings\n4. Click **Generate Song**\n5. Wait for generation (first run may take longer to load models)\n\n## Project Structure\n\n```\nacestep/ui/streamlit/\n├── main.py                    # Main Streamlit app\n├── config.py                  # Configuration constants\n├── requirements.txt           # Python dependencies\n├── components/                # UI components\n│   ├── dashboard.py          # Home page with recent projects\n│   ├── generation_wizard.py   # Song creation wizard\n│   ├── editor.py             # Audio editing tools\n│   ├── batch_generator.py    # Batch generation queue\n│   ├── settings_panel.py     # Configuration panel\n│   └── audio_player.py       # Audio playback widget\n├── utils/                     # Utility modules\n│   ├── cache.py              # Handler caching\n│   ├── project_manager.py    # Project management\n│   └── audio_utils.py        # Audio file handling\n└── projects/                  # Saved projects directory\n```\n\n## Configuration\n\nEdit `config.py` to customize:\n- Default generation parameters (duration, BPM, guidance scale)\n- UI display options\n- Storage locations\n- Supported audio formats\n\n## Usage Guide\n\n### Dashboard (🎹 Home)\n\nShows recent projects and quick-start options. Click on any project to:\n- **▶️** - Play the audio\n- **✏️** - Edit with advanced tools\n- **🗑️** - Delete the project\n\n### Generation Wizard (🎵 Generate)\n\nCreate new songs in 3 steps:\n1. **Inspiration** - Choose genre/mood or describe your song\n2. **Structure** - Set duration, BPM, key, and lyrics\n3. **Advanced** - Fine-tune diffusion steps, guidance scale, and more\n\n### Audio Editor (🎛️ Edit)\n\nEdit existing songs:\n- **Repaint** - Replace a time section with new generation\n- **Cover** - Create cover versions with different vocals/style\n- **Extract** - Isolate vocals, drums, or other stems\n- **Complete** - Generate missing sections\n\n### Batch Generator (📦 Batch)\n\nGenerate multiple songs at once:\n1. Write song descriptions in queue\n2. Add up to 8 songs\n3. Configure batch settings\n4. Click **Generate All**\n\nResults are saved as separate projects.\n\n### Settings (⚙️ Settings)\n\nConfigure:\n- **Hardware** - GPU, CUDA, Flash Attention options\n- **Models** - Select DiT and LLM models, backends\n- **Storage** - Manage projects, clear cache\n- **About** - Links to ACE-Step resources\n\n## Keyboard Shortcuts\n\n- `R` - Refresh current tab\n- `S` - Open Settings\n- `D` - Go to Dashboard\n\n## Troubleshooting\n\n### \"Failed to load DiT handler\"\n- Ensure ACE-Step is installed in parent directory\n- Check PyTorch and CUDA installation\n- Run `python -c \"import torch; print(torch.cuda.is_available())\"` to verify\n\n### Models not found\n- Models auto-download on first use\n- Check internet connection during first generation\n- See Settings > Storage to pre-download models\n\n### Out of Memory (OOM)\n- Reduce inference steps in advanced settings\n- Enable Model Offload in settings\n- Run on GPU with larger VRAM\n\n### Audio quality issues\n- Increase inference steps (32-100)\n- Increase guidance scale (7.5-10.0)\n- Use base model instead of turbo (slower but higher quality)\n\n## Performance Tips\n\n- First generation takes longer (model loading)\n- Use batch mode for multiple songs (more efficient)\n- Enable Flash Attention if GPU supports it\n- Turbo model is faster; base model is higher quality\n\n## Development\n\n### Adding New Features\n\n1. Create component in `components/`\n2. Add to `components/__init__.py`\n3. Import and route in `main.py`\n4. Add tests if needed\n\n### Updating Configuration\n\nEdit `config.py`:\n- Add new UI categories\n- Change defaults\n- Add supported formats or languages\n\n### Extending Project Manager\n\nAdd to `utils/project_manager.py`:\n- Custom metadata fields\n- Export formats (MP3, FLAC, etc.)\n- Cloud storage support\n\n## Future Roadmap\n\n- [ ] Waveform visualization with interactive timeline\n- [ ] Real-time audio analysis and visualization\n- [ ] Advanced mixing console (multi-track editing)\n- [ ] Lyrics editor with music sync\n- [ ] Preset save/load for generation settings\n- [ ] Export to different formats (MP3, FLAC, WAV)\n- [ ] Cloud project sync\n- [ ] Collaborative features\n- [ ] Mobile app\n\n## Contributing\n\nContributions welcome! See [ACE-Step CONTRIBUTING.md](../CONTRIBUTING.md)\n\n## License\n\nSame as ACE-Step - see [LICENSE](../LICENSE)\n\n## Links\n\n- 🌍 [ACE-Step Website](https://ace-step.github.io/)\n- 🤗 [HuggingFace Model](https://huggingface.co/ACE-Step/Ace-Step1.5)\n- 💬 [Discord Community](https://discord.gg/PeWDxrkdj7)\n- 📄 [Technical Paper](https://arxiv.org/abs/2602.00744)\n- 🐙 [GitHub Repository](https://github.com/ace-step/ACE-Step-1.5)\n\n---\n\nMade with ❤️ for the music generation community\n"
  },
  {
    "path": "acestep/ui/streamlit/components/__init__.py",
    "content": "\"\"\"ACE Studio Components\"\"\"\nfrom .dashboard import show_dashboard\nfrom .generation_wizard import show_generation_wizard\nfrom .editor import show_editor\nfrom .batch_generator import show_batch_generator\nfrom .settings_panel import show_settings_panel\nfrom .audio_player import audio_player_widget\n\n__all__ = [\n    \"show_dashboard\",\n    \"show_generation_wizard\",\n    \"show_editor\",\n    \"show_batch_generator\",\n    \"show_settings_panel\",\n    \"audio_player_widget\",\n]\n"
  },
  {
    "path": "acestep/ui/streamlit/components/audio_player.py",
    "content": "\"\"\"\nAudio player widget - play and control audio playback\n\"\"\"\nimport streamlit as st\nfrom pathlib import Path\nfrom typing import Optional\n\n\ndef audio_player_widget(audio_path: str, label: str = \"Audio\", show_download: bool = True):\n    \"\"\"Display audio player with controls\n    \n    Args:\n        audio_path: Path to audio file\n        label: Label for the audio player\n        show_download: Show download button\n    \"\"\"\n    audio_file = Path(audio_path)\n    \n    if not audio_file.exists():\n        st.error(f\"❌ Audio file not found: {audio_path}\")\n        return\n    \n    # Read audio file\n    with open(audio_file, \"rb\") as f:\n        audio_bytes = f.read()\n    \n    # Display audio player\n    st.audio(audio_bytes, format=\"audio/wav\")\n    \n    # File info\n    col1, col2, col3 = st.columns(3)\n    \n    with col1:\n        file_size_mb = audio_file.stat().st_size / 1e6\n        st.metric(\"File Size\", f\"{file_size_mb:.2f} MB\")\n    \n    with col2:\n        # Try to get duration\n        try:\n            import librosa\n            duration = librosa.get_duration(filename=audio_path)\n            minutes = int(duration // 60)\n            seconds = int(duration % 60)\n            st.metric(\"Duration\", f\"{minutes}m {seconds}s\")\n        except:\n            st.metric(\"Duration\", \"Unknown\")\n    \n    with col3:\n        st.metric(\"Format\", audio_file.suffix.upper())\n    \n    # Download button\n    if show_download:\n        st.download_button(\n            label=\"📥 Download Audio\",\n            data=audio_bytes,\n            file_name=audio_file.name,\n            mime=\"audio/wav\",\n            use_container_width=True\n        )\n\n\ndef simple_audio_player(audio_path: str, label: str = \"▶️ Play\"):\n    \"\"\"Simple inline audio player\"\"\"\n    audio_file = Path(audio_path)\n    \n    if not audio_file.exists():\n        return\n    \n    with open(audio_file, \"rb\") as f:\n        audio_bytes = f.read()\n    \n    st.audio(audio_bytes, format=\"audio/wav\")\n"
  },
  {
    "path": "acestep/ui/streamlit/components/batch_generator.py",
    "content": "\"\"\"\nBatch Generator component - generate multiple songs at once\n\"\"\"\nimport streamlit as st\nfrom utils import ProjectManager, get_dit_handler\nfrom config import PROJECTS_DIR, GENRES, MOODS, DEFAULT_DURATION, DEFAULT_BPM\nfrom loguru import logger\n\n\ndef show_batch_generator():\n    \"\"\"Display batch generation interface (up to 8 songs)\"\"\"\n    st.markdown(\"## 📦 Batch Generator\")\n    st.info(\"🚀 Generate up to 8 songs simultaneously\")\n    \n    # Initialize batch queue\n    if \"batch_queue\" not in st.session_state:\n        st.session_state.batch_queue = []\n    \n    st.markdown(\"### Add Songs to Queue\")\n    \n    col1, col2 = st.columns([3, 1])\n    \n    with col1:\n        song_caption = st.text_input(\n            \"Song Description\",\n            placeholder=\"Upbeat pop with synth...\",\n            key=\"batch_caption\"\n        )\n    \n    with col2:\n        if st.button(\"➕ Add to Queue\", key=\"batch_add_btn\", use_container_width=True):\n            if song_caption and len(st.session_state.batch_queue) < 8:\n                st.session_state.batch_queue.append({\n                    \"caption\": song_caption,\n                    \"duration\": DEFAULT_DURATION,\n                    \"bpm\": DEFAULT_BPM,\n                    \"status\": \"queued\"\n                })\n                st.success(\"✅ Added to queue\")\n                st.rerun()\n            elif len(st.session_state.batch_queue) >= 8:\n                st.error(\"🔴 Queue is full (max 8 songs)\")\n            else:\n                st.error(\"Please enter a song description\")\n    \n    st.divider()\n    \n    # Queue display\n    st.markdown(f\"### Queue ({len(st.session_state.batch_queue)}/8)\")\n    \n    if st.session_state.batch_queue:\n        # Show as grid\n        cols = st.columns(4)\n        \n        for idx, song in enumerate(st.session_state.batch_queue):\n            with cols[idx % 4]:\n                with st.container(border=True):\n                    st.markdown(f\"**#{idx + 1}**\")\n                    st.caption(song[\"caption\"][:50] + \"...\" if len(song[\"caption\"]) > 50 else song[\"caption\"])\n                    \n                    # Status indicator\n                    status_emoji = {\n                        \"queued\": \"⏳\",\n                        \"generating\": \"⚙️\",\n                        \"completed\": \"✅\",\n                        \"failed\": \"❌\"\n                    }\n                    st.caption(f\"{status_emoji.get(song['status'], '?')} {song['status'].title()}\")\n                    \n                    # Remove button\n                    if song[\"status\"] == \"queued\":\n                        if st.button(\"🗑️\", key=f\"remove_{idx}\", use_container_width=True):\n                            st.session_state.batch_queue.pop(idx)\n                            st.rerun()\n    else:\n        st.info(\"📝 Add songs to the queue to get started\")\n    \n    st.divider()\n    \n    # Batch settings\n    with st.expander(\"⚙️ Batch Settings\", expanded=True):\n        col1, col2, col3 = st.columns(3)\n        \n        with col1:\n            parallel_count = st.slider(\n                \"Process in Parallel\",\n                min_value=1,\n                max_value=4,\n                value=2,\n                help=\"Number of songs to generate simultaneously\",\n                key=\"parallel_count\"\n            )\n        \n        with col2:\n            inference_steps = st.slider(\n                \"Diffusion Steps\",\n                min_value=8,\n                max_value=100,\n                value=32,\n                step=4,\n                key=\"batch_steps\"\n            )\n        \n        with col3:\n            guidance_scale = st.slider(\n                \"Guidance Scale\",\n                min_value=1.0,\n                max_value=15.0,\n                value=7.5,\n                step=0.5,\n                key=\"batch_guidance\"\n            )\n    \n    st.divider()\n    \n    # Generate Button\n    col1, col2, col3 = st.columns([1, 2, 1])\n    \n    with col2:\n        if st.button(\n            f\"🚀 Generate All ({len(st.session_state.batch_queue)})\",\n            use_container_width=True,\n            type=\"primary\",\n            key=\"batch_gen_btn\",\n            disabled=len(st.session_state.batch_queue) == 0\n        ):\n            generate_batch(st.session_state.batch_queue, parallel_count, inference_steps, guidance_scale)\n\n\ndef generate_batch(queue: list, parallel_count: int, steps: int, guidance: float):\n    \"\"\"Generate all songs in the batch queue\"\"\"\n    pm = ProjectManager(PROJECTS_DIR)\n    dit_handler = get_dit_handler()\n    \n    if not dit_handler:\n        st.error(\"❌ Failed to load generation model\")\n        return\n    \n    # Create progress tracking\n    progress_placeholder = st.empty()\n    status_placeholder = st.empty()\n    results_placeholder = st.empty()\n    \n    total_songs = len(queue)\n    completed = 0\n    failed = 0\n    results = []\n    \n    with st.spinner(f\"🎵 Generating {total_songs} songs...\"):\n        try:\n            for idx, song in enumerate(queue):\n                # Update progress\n                progress = (idx + 1) / total_songs\n                progress_placeholder.progress(progress)\n                status_placeholder.text(f\"Generating song {idx + 1}/{total_songs}: {song['caption'][:40]}...\")\n                \n                try:\n                    # Create project\n                    project_name = f\"Batch_{song['caption'][:20].replace(' ', '_')}\"\n                    project_path = pm.create_project(project_name, description=song['caption'])\n                    \n                    # TODO: Actual generation\n                    # result = dit_handler.generate(song['caption'], duration=song['duration'])\n                    # pm.save_audio(project_path, result['audio'], \"output.wav\")\n                    \n                    results.append({\n                        \"song\": song['caption'],\n                        \"project\": project_name,\n                        \"status\": \"✅ Success\"\n                    })\n                    completed += 1\n                \n                except Exception as e:\n                    logger.error(f\"Batch generation error for song {idx + 1}: {e}\")\n                    results.append({\n                        \"song\": song['caption'],\n                        \"project\": \"\",\n                        \"status\": f\"❌ Failed: {str(e)[:50]}\"\n                    })\n                    failed += 1\n            \n            # Display results\n            st.success(f\"🎉 Batch generation complete! Completed: {completed}/{total_songs}\")\n            \n            if results:\n                results_df = st.dataframe(results, use_container_width=True)\n            \n            # Clear queue\n            st.session_state.batch_queue = []\n            \n        except Exception as e:\n            logger.error(f\"Batch error: {e}\")\n            st.error(f\"❌ Batch generation failed: {e}\")\n"
  },
  {
    "path": "acestep/ui/streamlit/components/dashboard.py",
    "content": "\"\"\"\nDashboard component - shows recent projects and quick start options\n\"\"\"\nimport streamlit as st\nfrom datetime import datetime\nfrom utils import ProjectManager\nfrom config import PROJECTS_DIR, GENERATION_MODES\n\n\ndef show_dashboard():\n    \"\"\"Display dashboard with recent projects and quick start options\"\"\"\n    st.markdown(\"# 🎹 ACE Studio\")\n    st.markdown(\"*Music Generation & Editing Made Easy*\")\n    \n    col1, col2, col3, col4 = st.columns(4)\n    \n    with col1:\n        if st.button(\"🎵 Generate New\", key=\"quick_gen\", use_container_width=True, type=\"primary\"):\n            st.session_state.tab = \"generate\"\n            st.rerun()\n    \n    with col2:\n        if st.button(\"🎤 Create Cover\", key=\"quick_cover\", use_container_width=True):\n            st.session_state.tab = \"editor\"\n            st.session_state.editor_mode = \"cover\"\n            st.rerun()\n    \n    with col3:\n        if st.button(\"🎨 Edit Song\", key=\"quick_edit\", use_container_width=True):\n            st.session_state.tab = \"editor\"\n            st.session_state.editor_mode = \"repaint\"\n            st.rerun()\n    \n    with col4:\n        if st.button(\"📦 Batch\", key=\"quick_batch\", use_container_width=True):\n            st.session_state.tab = \"batch\"\n            st.rerun()\n    \n    st.divider()\n    \n    # Recent Projects Section\n    st.markdown(\"## 📚 Recent Projects\")\n    \n    pm = ProjectManager(PROJECTS_DIR)\n    projects = pm.list_projects()\n    \n    if projects:\n        # Display as grid\n        cols = st.columns(3)\n        for idx, project in enumerate(projects[:6]):  # Show first 6\n            with cols[idx % 3]:\n                with st.container():\n                    st.markdown(f\"### {project['name']}\")\n                    \n                    # Metadata\n                    if project.get('genre'):\n                        st.caption(f\"🎼 {project['genre']}\")\n                    if project.get('mood'):\n                        st.caption(f\"💭 {project['mood']}\")\n                    if project.get('duration'):\n                        st.caption(f\"⏱️ {project['duration']}s @ {project.get('bpm', '?')} BPM\")\n                    \n                    # Modified time\n                    modified = datetime.fromisoformat(project['modified_at'])\n                    st.caption(f\"📅 {modified.strftime('%b %d, %H:%M')}\")\n                    \n                    # Action buttons\n                    col_play, col_edit, col_del = st.columns(3)\n                    with col_play:\n                        if st.button(\"▶️\", key=f\"play_{project['name']}\", help=\"Play\"):\n                            st.session_state.selected_project = project['name']\n                            st.session_state.tab = \"editor\"\n                            st.rerun()\n                    \n                    with col_edit:\n                        if st.button(\"✏️\", key=f\"edit_{project['name']}\", help=\"Edit\"):\n                            st.session_state.selected_project = project['name']\n                            st.session_state.tab = \"editor\"\n                            st.rerun()\n                    \n                    with col_del:\n                        if st.button(\"🗑️\", key=f\"del_{project['name']}\", help=\"Delete\"):\n                            if pm.delete_project(project['name']):\n                                st.success(f\"Deleted: {project['name']}\")\n                                st.rerun()\n    else:\n        st.info(\"✨ No projects yet. Generate your first song!\")\n    \n    st.divider()\n    \n    # Statistics\n    st.markdown(\"## 📊 Stats\")\n    metrics_cols = st.columns(4)\n    with metrics_cols[0]:\n        st.metric(\"Total Projects\", len(projects))\n    with metrics_cols[1]:\n        total_duration = sum(p.get('duration', 0) for p in projects)\n        st.metric(\"Total Duration\", f\"{total_duration // 60}m\" if total_duration else \"0m\")\n    with metrics_cols[2]:\n        st.metric(\"Favorite Mood\", \"Coming Soon\", help=\"Based on generated songs\")\n    with metrics_cols[3]:\n        st.metric(\"Favorite Genre\", \"Coming Soon\", help=\"Based on generated songs\")\n"
  },
  {
    "path": "acestep/ui/streamlit/components/editor.py",
    "content": "\"\"\"\nEditor component – thin orchestrator for interactive audio editing.\n\nDelegates to:\n- ``editor_audio_picker`` – file selection from projects / outputs / upload\n- ``editor_waveform`` – waveform display and region selector\n- ``editor_tasks`` – repaint, cover, and complete UIs\n- ``editor_runner`` – shared generation call\n\"\"\"\nimport streamlit as st\n\nfrom utils import is_dit_ready\nfrom .editor_audio_picker import pick_audio_source\nfrom .editor_waveform import show_waveform_and_player\nfrom .editor_tasks import repaint_ui, cover_ui, complete_ui\n\n_TASK_LABELS = {\n    \"repaint\": \"🎨 Repaint a section\",\n    \"cover\": \"🎤 Create a cover / restyle\",\n    \"complete\": \"🎼 Extend / fill section\",\n}\n\n\ndef show_editor() -> None:\n    \"\"\"Top-level editor page.\"\"\"\n    st.markdown(\"## 🎛️ Audio Editor\")\n\n    if not is_dit_ready():\n        st.warning(\n            \"DiT model is **not loaded**.  \"\n            \"Load it in **⚙️ Settings → Models** first.\"\n        )\n\n    # 1. Pick source audio\n    audio_path = pick_audio_source()\n    if audio_path is None:\n        return\n\n    # 2. Waveform + metadata\n    duration_sec = show_waveform_and_player(audio_path)\n\n    st.divider()\n\n    # 3. Task selector → delegate to task-specific UI\n    task = st.selectbox(\n        \"Edit task\",\n        options=list(_TASK_LABELS),\n        format_func=_TASK_LABELS.get,\n        key=\"edit_task\",\n    )\n\n    if task == \"repaint\":\n        repaint_ui(audio_path, duration_sec)\n    elif task == \"cover\":\n        cover_ui(audio_path, duration_sec)\n    elif task == \"complete\":\n        complete_ui(audio_path, duration_sec)\n\n"
  },
  {
    "path": "acestep/ui/streamlit/components/editor_audio_picker.py",
    "content": "\"\"\"\nAudio source picker for the editor – browses projects, outputs, uploads.\n\nProvides ``pick_audio_source()`` which returns the selected path or None.\n\"\"\"\nimport tempfile\nfrom pathlib import Path\nfrom typing import Optional, List\n\nimport streamlit as st\n\nfrom utils import ProjectManager\nfrom config import PROJECTS_DIR, OUTPUT_DIR, AUDIO_FORMATS\n\n\ndef pick_audio_source() -> Optional[Path]:\n    \"\"\"Let the user choose from projects, gradio_outputs, or upload.\n\n    Returns:\n        Path to the chosen audio file, or ``None`` if nothing selected.\n    \"\"\"\n    tab_proj, tab_out, tab_upload = st.tabs(\n        [\"📁 Projects\", \"📂 All outputs\", \"⬆️ Upload file\"]\n    )\n\n    audio_path: Optional[Path] = None\n\n    with tab_proj:\n        audio_path = _pick_from_projects(audio_path)\n\n    with tab_out:\n        audio_path = _pick_from_outputs(audio_path)\n\n    with tab_upload:\n        audio_path = _pick_from_upload(audio_path)\n\n    return audio_path\n\n\n# ------------------------------------------------------------------\n# Tab helpers\n# ------------------------------------------------------------------\n\ndef _pick_from_projects(fallback: Optional[Path]) -> Optional[Path]:\n    \"\"\"Project-file picker tab content.\"\"\"\n    pm = ProjectManager(PROJECTS_DIR)\n    projects = pm.list_projects()\n    if not projects:\n        st.info(\"No projects yet – generate a song first.\")\n        return fallback\n\n    proj_names = [p[\"name\"] for p in projects]\n    sel_proj = st.selectbox(\"Project\", proj_names, key=\"ed_proj\")\n    proj_path = pm.get_project(sel_proj)\n    if not proj_path:\n        return fallback\n\n    files = pm.get_audio_files(proj_path)\n    if not files:\n        st.info(\"No audio in this project.\")\n        return fallback\n\n    sel_file = st.selectbox(\n        \"Audio file\",\n        [f.name for f in files],\n        key=\"ed_proj_file\",\n    )\n    return proj_path / sel_file\n\n\ndef _pick_from_outputs(fallback: Optional[Path]) -> Optional[Path]:\n    \"\"\"gradio_outputs browser tab content.\"\"\"\n    all_files = _scan_output_files()\n    if not all_files:\n        st.info(\"No output files found.\")\n        return fallback\n\n    labels = [\n        f\"{f.parent.name}/{f.name}\" if f.parent != OUTPUT_DIR else f.name\n        for f in all_files\n    ]\n    sel_idx = st.selectbox(\n        \"Output file\",\n        range(len(labels)),\n        format_func=lambda i: labels[i],\n        key=\"ed_out_file\",\n    )\n    return all_files[sel_idx]\n\n\ndef _pick_from_upload(fallback: Optional[Path]) -> Optional[Path]:\n    \"\"\"Upload tab content – persist to temp file.\"\"\"\n    uploaded = st.file_uploader(\n        \"Upload an audio file\",\n        type=[\"wav\", \"mp3\", \"flac\", \"m4a\"],\n        key=\"ed_upload\",\n    )\n    if uploaded is None:\n        return fallback\n    tmp = Path(tempfile.gettempdir()) / uploaded.name\n    tmp.write_bytes(uploaded.getvalue())\n    return tmp\n\n\ndef _scan_output_files() -> List[Path]:\n    \"\"\"Return all audio files under gradio_outputs (flat + batch dirs).\"\"\"\n    exts = set(AUDIO_FORMATS)\n    out: List[Path] = []\n    if not OUTPUT_DIR.exists():\n        return out\n    for p in sorted(OUTPUT_DIR.rglob(\"*\"), reverse=True):\n        if p.is_file() and p.suffix.lower() in exts:\n            out.append(p)\n        if len(out) >= 200:\n            break\n    return out\n"
  },
  {
    "path": "acestep/ui/streamlit/components/editor_runner.py",
    "content": "\"\"\"\nShared generation runner for editor edit tasks.\n\nCalls ``acestep.inference.generate_music()`` and displays results.\n\"\"\"\nimport shutil\nfrom pathlib import Path\n\nimport streamlit as st\nfrom loguru import logger\n\nfrom utils import (\n    get_dit_handler,\n    get_llm_handler,\n    is_dit_ready,\n    ProjectManager,\n)\nfrom config import OUTPUT_DIR, PROJECTS_DIR\n\n\ndef run_edit_task(\n    task_type: str,\n    src_audio: str,\n    caption: str,\n    lyrics: str = \"\",\n    repainting_start: float = 0.0,\n    repainting_end: float = -1.0,\n    audio_cover_strength: float = 1.0,\n    cover_noise_strength: float = 0.0,\n    inference_steps: int = 8,\n    seed: int = -1,\n) -> None:\n    \"\"\"Run an ACE-Step edit task and display results.\n\n    Args:\n        task_type: One of ``repaint``, ``cover``, ``complete``.\n        src_audio: Path to the source audio file.\n        caption: Text prompt describing the edit.\n        lyrics: Optional lyrics for the edited section.\n        repainting_start: Region start in seconds (repaint/complete).\n        repainting_end: Region end in seconds (repaint/complete).\n        audio_cover_strength: Cover similarity (cover task).\n        cover_noise_strength: Noise level (cover task).\n        inference_steps: DiT diffusion steps.\n        seed: Random seed (-1 for random).\n    \"\"\"\n    if not is_dit_ready():\n        st.error(\"DiT model not loaded.\")\n        return\n\n    with st.spinner(f\"Running {task_type}…\"):\n        try:\n            result = _generate(\n                task_type=task_type,\n                src_audio=src_audio,\n                caption=caption,\n                lyrics=lyrics,\n                repainting_start=repainting_start,\n                repainting_end=repainting_end,\n                audio_cover_strength=audio_cover_strength,\n                cover_noise_strength=cover_noise_strength,\n                inference_steps=inference_steps,\n                seed=seed,\n            )\n        except Exception as exc:\n            logger.error(f\"{task_type} error: {exc}\")\n            st.error(f\"❌ {task_type} failed: {exc}\")\n            return\n\n    if not result.success:\n        st.error(f\"Failed: {result.error}\")\n        return\n\n    st.success(f\"✅ {task_type.title()} complete!\")\n    _show_results(result, task_type, caption)\n\n\n# ------------------------------------------------------------------\n# Internal helpers\n# ------------------------------------------------------------------\n\ndef _generate(\n    task_type: str,\n    src_audio: str,\n    caption: str,\n    lyrics: str,\n    repainting_start: float,\n    repainting_end: float,\n    audio_cover_strength: float,\n    cover_noise_strength: float,\n    inference_steps: int,\n    seed: int,\n):\n    \"\"\"Build params, invoke generate_music, return GenerationResult.\"\"\"\n    from acestep.inference import (\n        GenerationParams,\n        GenerationConfig,\n        generate_music,\n    )\n\n    params = GenerationParams(\n        task_type=task_type,\n        caption=caption,\n        lyrics=lyrics or \"[Instrumental]\",\n        src_audio=src_audio,\n        repainting_start=repainting_start,\n        repainting_end=repainting_end,\n        audio_cover_strength=audio_cover_strength,\n        cover_noise_strength=cover_noise_strength,\n        inference_steps=inference_steps,\n        seed=seed,\n        thinking=False,\n    )\n    config = GenerationConfig(\n        batch_size=1,\n        use_random_seed=(seed < 0),\n        seeds=[seed] if seed >= 0 else None,\n    )\n\n    return generate_music(\n        dit_handler=get_dit_handler(),\n        llm_handler=get_llm_handler(),\n        params=params,\n        config=config,\n        save_dir=str(OUTPUT_DIR),\n    )\n\n\ndef _show_results(result, task_type: str, caption: str) -> None:\n    \"\"\"Display audio outputs and offer project-save buttons.\"\"\"\n    for idx, audio_info in enumerate(result.audios):\n        out_path = audio_info.get(\"path\", \"\")\n        if not out_path or not Path(out_path).exists():\n            continue\n        st.audio(out_path)\n        st.caption(Path(out_path).name)\n\n        if st.button(\n            \"💾 Save to project\",\n            key=f\"save_{task_type}_{idx}\",\n        ):\n            pm = ProjectManager(PROJECTS_DIR)\n            safe = caption[:25].replace(\" \", \"_\").replace(\"/\", \"_\")\n            proj = pm.create_project(\n                f\"{task_type}_{safe}\",\n                description=caption,\n            )\n            dst = proj / Path(out_path).name\n            shutil.copy2(out_path, str(dst))\n            st.success(\"Saved to project\")\n"
  },
  {
    "path": "acestep/ui/streamlit/components/editor_tasks.py",
    "content": "\"\"\"Edit-task UI panels – repaint, cover, and complete.\n\nDelegates generation to ``editor_runner.run_edit_task()``.\n\"\"\"\nfrom pathlib import Path\n\nimport streamlit as st\n\nfrom .editor_waveform import region_selector\nfrom .editor_runner import run_edit_task\n\n\ndef repaint_ui(audio_path: Path, duration_sec: float) -> None:\n    \"\"\"Interactive repaint: mark a region and regenerate it.\"\"\"\n    st.markdown(\"### 🎨 Repaint Region\")\n    st.caption(\n        \"Select a time region and describe what should replace it. \"\n        \"The rest of the song stays untouched.\"\n    )\n\n    start, end = region_selector(duration_sec, prefix=\"rp\")\n\n    prompt = st.text_area(\n        \"What should this section sound like?\",\n        placeholder=(\n            \"e.g. 'Energetic drum fill with rising synth' \"\n            \"or 'Soft piano interlude'\"\n        ),\n        key=\"rp_prompt\",\n    )\n    lyrics = st.text_area(\n        \"Lyrics for this section (optional)\",\n        placeholder=\"[Chorus]\\nNew lyrics...\",\n        height=80,\n        key=\"rp_lyrics\",\n    )\n\n    with st.expander(\"Advanced\", expanded=False):\n        col1, col2 = st.columns(2)\n        with col1:\n            steps = st.slider(\n                \"Diffusion steps\", 4, 100, 8, 4, key=\"rp_steps\"\n            )\n        with col2:\n            seed = st.number_input(\n                \"Seed (-1 random)\", value=-1, key=\"rp_seed\"\n            )\n\n    if st.button(\n        \"🎨 Repaint\", type=\"primary\",\n        use_container_width=True, key=\"rp_go\",\n    ):\n        if end <= start:\n            st.error(\"Invalid region — end must be after start.\")\n            return\n        run_edit_task(\n            task_type=\"repaint\",\n            src_audio=str(audio_path),\n            caption=prompt or \"Repaint section\",\n            lyrics=lyrics,\n            repainting_start=start,\n            repainting_end=end,\n            inference_steps=steps,\n            seed=int(seed),\n        )\n\n\ndef cover_ui(audio_path: Path, duration_sec: float) -> None:\n    \"\"\"Create a cover or restyle from source audio.\"\"\"\n    st.markdown(\"### 🎤 Cover / Restyle\")\n    st.caption(\n        \"Generate a new version of this audio in a different style.\"\n    )\n\n    prompt = st.text_area(\n        \"Describe the target style\",\n        placeholder=(\n            \"e.g. 'Acoustic folk version with female vocals' \"\n            \"or 'Lo-fi hip-hop remix'\"\n        ),\n        key=\"cv_prompt\",\n    )\n    lyrics = st.text_area(\n        \"Lyrics (optional)\", placeholder=\"[Verse]\\n...\",\n        height=80, key=\"cv_lyrics\",\n    )\n\n    col1, col2 = st.columns(2)\n    with col1:\n        strength = st.slider(\n            \"Cover strength\", 0.0, 1.0, 0.7, 0.05,\n            help=\"1.0 = very close to original; lower = more creative\",\n            key=\"cv_strength\",\n        )\n    with col2:\n        noise = st.slider(\n            \"Noise strength\", 0.0, 1.0, 0.0, 0.05,\n            help=\"0 = pure noise (new); 1 = closest to source\",\n            key=\"cv_noise\",\n        )\n\n    with st.expander(\"Advanced\", expanded=False):\n        col1, col2 = st.columns(2)\n        with col1:\n            steps = st.slider(\n                \"Diffusion steps\", 4, 100, 8, 4, key=\"cv_steps\"\n            )\n        with col2:\n            seed = st.number_input(\n                \"Seed (-1 random)\", value=-1, key=\"cv_seed\"\n            )\n\n    if st.button(\n        \"🎤 Create Cover\", type=\"primary\",\n        use_container_width=True, key=\"cv_go\",\n    ):\n        run_edit_task(\n            task_type=\"cover\",\n            src_audio=str(audio_path),\n            caption=prompt or \"Cover version\",\n            lyrics=lyrics,\n            audio_cover_strength=strength,\n            cover_noise_strength=noise,\n            inference_steps=steps,\n            seed=int(seed),\n        )\n\n\ndef complete_ui(audio_path: Path, duration_sec: float) -> None:\n    \"\"\"Fill a gap or extend a song.\"\"\"\n    st.markdown(\"### 🎼 Complete / Extend\")\n    st.caption(\n        \"Select a region to fill, or set end = duration to extend.\"\n    )\n\n    start, end = region_selector(duration_sec, prefix=\"cp\")\n\n    prompt = st.text_area(\n        \"Describe the section to generate\",\n        placeholder=\"e.g. 'Guitar solo bridge' or \"\n                    \"'Outro with fading strings'\",\n        key=\"cp_prompt\",\n    )\n    lyrics = st.text_area(\n        \"Lyrics (optional)\", height=80, key=\"cp_lyrics\",\n    )\n\n    with st.expander(\"Advanced\", expanded=False):\n        col1, col2 = st.columns(2)\n        with col1:\n            steps = st.slider(\n                \"Diffusion steps\", 4, 100, 8, 4, key=\"cp_steps\"\n            )\n        with col2:\n            seed = st.number_input(\n                \"Seed (-1 random)\", value=-1, key=\"cp_seed\"\n            )\n\n    if st.button(\n        \"🎼 Complete\", type=\"primary\",\n        use_container_width=True, key=\"cp_go\",\n    ):\n        if end <= start:\n            st.error(\"Invalid region.\")\n            return\n        run_edit_task(\n            task_type=\"complete\",\n            src_audio=str(audio_path),\n            caption=prompt or \"Complete section\",\n            lyrics=lyrics,\n            repainting_start=start,\n            repainting_end=end,\n            inference_steps=steps,\n            seed=int(seed),\n        )\n"
  },
  {
    "path": "acestep/ui/streamlit/components/editor_waveform.py",
    "content": "\"\"\"\nWaveform display and interactive region selector for the editor.\n\nProvides ``show_waveform_and_player()`` and ``region_selector()``.\n\"\"\"\nimport math\nfrom pathlib import Path\nfrom typing import Optional, Tuple\n\nimport numpy as np\nimport streamlit as st\n\n# ---------- optional heavy imports ----------------------------------\ntry:\n    import soundfile as sf\nexcept ImportError:\n    sf = None\n\ntry:\n    import librosa\nexcept ImportError:\n    librosa = None\n\n\ndef show_waveform_and_player(audio_path: Path) -> float:\n    \"\"\"Render the audio player, metadata line, and waveform chart.\n\n    Args:\n        audio_path: Path to the audio file.\n\n    Returns:\n        Duration of the audio in seconds.\n    \"\"\"\n    st.audio(str(audio_path))\n\n    duration_sec = _get_duration(audio_path)\n    size_kb = audio_path.stat().st_size / 1024\n    st.caption(\n        f\"**{audio_path.name}** — \"\n        f\"{duration_sec:.1f}s  |  \"\n        f\"{size_kb:.0f} KB\"\n    )\n\n    waveform = _load_waveform(audio_path)\n    if waveform is not None:\n        _draw_waveform(waveform, duration_sec)\n\n    return duration_sec\n\n\ndef region_selector(\n    duration_sec: float,\n    prefix: str = \"rp\",\n) -> Tuple[float, float]:\n    \"\"\"Two-slider region picker with a visual timeline bar.\n\n    Args:\n        duration_sec: Total audio duration in seconds.\n        prefix: Unique key prefix (avoids widget-key conflicts).\n\n    Returns:\n        Tuple of (start_seconds, end_seconds).\n    \"\"\"\n    dur_int = max(1, int(math.ceil(duration_sec)))\n\n    st.markdown(\"**Select region on the timeline:**\")\n    col1, col2 = st.columns(2)\n    with col1:\n        start = st.slider(\n            \"Start (s)\", 0, dur_int, 0, 1,\n            key=f\"{prefix}_start\",\n        )\n    with col2:\n        end = st.slider(\n            \"End (s)\", 0, dur_int, min(30, dur_int), 1,\n            key=f\"{prefix}_end\",\n        )\n    if end <= start:\n        st.warning(\"End must be after start.\")\n\n    _draw_region_bar(start, end, duration_sec)\n    return float(start), float(end)\n\n\n# ------------------------------------------------------------------\n# Internal helpers\n# ------------------------------------------------------------------\n\ndef _get_duration(audio_path: Path) -> float:\n    \"\"\"Return audio duration in seconds.\"\"\"\n    if sf is not None:\n        try:\n            return sf.info(str(audio_path)).duration\n        except Exception:\n            pass\n    if librosa is not None:\n        try:\n            return librosa.get_duration(path=str(audio_path))\n        except Exception:\n            pass\n    return 120.0  # fallback\n\n\ndef _load_waveform(\n    audio_path: Path,\n    target_sr: int = 8000,\n) -> Optional[np.ndarray]:\n    \"\"\"Load a mono, downsampled waveform for visualisation.\"\"\"\n    if librosa is not None:\n        try:\n            y, _ = librosa.load(str(audio_path), sr=target_sr, mono=True)\n            return y\n        except Exception:\n            pass\n    if sf is not None:\n        try:\n            y, _ = sf.read(str(audio_path), always_2d=True)\n            return y.mean(axis=1)\n        except Exception:\n            pass\n    return None\n\n\ndef _draw_waveform(y: np.ndarray, duration_sec: float) -> None:\n    \"\"\"Render a lightweight waveform via ``st.line_chart``.\"\"\"\n    import pandas as pd\n\n    n_points = min(len(y), 1000)\n    step = max(1, len(y) // n_points)\n    y_ds = y[::step]\n\n    times = np.linspace(0, duration_sec, len(y_ds))\n    df = pd.DataFrame({\"time (s)\": times, \"amplitude\": y_ds})\n    df = df.set_index(\"time (s)\")\n    st.line_chart(df, height=120, use_container_width=True)\n\n\ndef _draw_region_bar(\n    start: float,\n    end: float,\n    duration_sec: float,\n) -> None:\n    \"\"\"Coloured HTML bar showing the selected region on the timeline.\"\"\"\n    pct_left = start / duration_sec * 100 if duration_sec else 0\n    pct_width = (end - start) / duration_sec * 100 if duration_sec else 0\n    st.markdown(\n        f\"\"\"\n<div style=\"position:relative;height:28px;background:#333;\n            border-radius:6px;overflow:hidden;margin:4px 0 12px 0;\">\n  <div style=\"position:absolute;left:{pct_left:.1f}%;\n              width:{pct_width:.1f}%;height:100%;\n              background:rgba(255,100,100,0.55);\n              border:2px solid #ff6464;border-radius:4px;\"></div>\n  <div style=\"position:absolute;width:100%;text-align:center;\n              line-height:28px;color:#eee;font-size:0.8rem;\">\n    {start:.0f}s – {end:.0f}s &nbsp;(region)\n  </div>\n</div>\"\"\",\n        unsafe_allow_html=True,\n    )\n"
  },
  {
    "path": "acestep/ui/streamlit/components/generation_wizard.py",
    "content": "\"\"\"\nGeneration Wizard component - create new songs.\n\nProvides a single-page form for text-to-music generation\nusing the ACE-Step DiT + optional LLM pipeline.\n\"\"\"\nimport sys\nfrom pathlib import Path\nfrom typing import Optional\n\nimport streamlit as st\nfrom loguru import logger\n\nfrom utils import (\n    get_dit_handler,\n    get_llm_handler,\n    is_dit_ready,\n    initialize_dit,\n    ProjectManager,\n)\nfrom config import (\n    ACESTEP_ROOT,\n    PROJECTS_DIR,\n    OUTPUT_DIR,\n    GENRES,\n    MOODS,\n    DEFAULT_DURATION,\n    DEFAULT_BPM,\n)\n\n\ndef _quick_init_dit() -> None:\n    \"\"\"One-click DiT init from the Generate page.\"\"\"\n    import sys as _sys\n\n    with st.spinner(\"Loading DiT model...\"):\n        _status, _ok = initialize_dit(\n            config_path=\"acestep-v15-turbo\",\n            device=\"auto\",\n            offload_to_cpu=(_sys.platform != \"darwin\"),\n        )\n    if _ok:\n        st.success(\"DiT model loaded!\")\n        st.rerun()\n    else:\n        st.error(f\"Init failed: {_status}\")\n\n\ndef show_generation_wizard() -> None:\n    \"\"\"Display the song generation form (all sections visible).\"\"\"\n    st.markdown(\"## 🎵 Generate New Song\")\n\n    if not is_dit_ready():\n        st.warning(\n            \"DiT model is **not loaded** yet.  \"\n            \"Click below to load it, or go to \"\n            \"**⚙️ Settings → Models**.\"\n        )\n        if st.button(\n            \"🚀 Load DiT Model Now\",\n            key=\"quick_init_dit\",\n            type=\"primary\",\n        ):\n            _quick_init_dit()\n            return\n\n    # ------------------------------------------------------------------\n    # Section 1 – Inspiration & Vibe\n    # ------------------------------------------------------------------\n    st.markdown(\"### 🎨 Inspiration & Vibe\")\n\n    col1, col2 = st.columns(2)\n    with col1:\n        quick_genre = st.selectbox(\n            \"Genre\",\n            GENRES,\n            key=\"quick_genre\",\n        )\n    with col2:\n        quick_mood = st.selectbox(\n            \"Mood\",\n            MOODS,\n            key=\"quick_mood\",\n        )\n\n    caption = st.text_area(\n        \"Song Description (caption)\",\n        placeholder=(\n            \"E.g., 'Upbeat pop with electric guitars \"\n            \"and catchy chorus, feels summery and energetic'\"\n        ),\n        height=80,\n        key=\"caption\",\n    )\n    if not caption:\n        caption = f\"A {quick_mood.lower()} {quick_genre.lower()} song\"\n\n    st.divider()\n\n    # ------------------------------------------------------------------\n    # Section 2 – Song Structure\n    # ------------------------------------------------------------------\n    st.markdown(\"### 🎼 Song Structure\")\n\n    col1, col2, col3 = st.columns(3)\n\n    with col1:\n        duration = st.slider(\n            \"Duration (seconds)\",\n            min_value=10,\n            max_value=600,\n            value=DEFAULT_DURATION,\n            step=10,\n            key=\"duration\",\n        )\n    with col2:\n        bpm_opts = [\"Auto\", 60, 80, 90, 100, 110, 120, 140, 150, 160]\n        bpm_input = st.selectbox(\n            \"BPM\",\n            options=bpm_opts,\n            index=bpm_opts.index(DEFAULT_BPM),\n            key=\"bpm\",\n        )\n        bpm: Optional[int] = (\n            None if bpm_input == \"Auto\" else int(bpm_input)\n        )\n    with col3:\n        key_opts = [\n            \"Auto\",\n            \"C Major\", \"C Minor\",\n            \"D Major\", \"D Minor\",\n            \"E Major\", \"E Minor\",\n            \"F Major\", \"F Minor\",\n            \"G Major\", \"G Minor\",\n            \"A Major\", \"A Minor\",\n            \"B Major\", \"B Minor\",\n        ]\n        key_input = st.selectbox(\n            \"Key / Scale\",\n            options=key_opts,\n            index=0,\n            key=\"key\",\n        )\n        key_opt: str = \"\" if key_input == \"Auto\" else key_input\n\n    # Lyrics\n    st.markdown(\"**Lyrics (optional)**\")\n    use_lyrics = st.checkbox(\n        \"Add lyrics\", value=False, key=\"use_lyrics\"\n    )\n    lyrics = \"\"\n    if use_lyrics:\n        lyrics = st.text_area(\n            \"Lyrics\",\n            placeholder=(\n                \"[Verse 1]\\nLyrics here...\\n\\n\"\n                \"[Chorus]\\nCatchy chorus...\"\n            ),\n            height=150,\n            key=\"lyrics\",\n            label_visibility=\"collapsed\",\n        )\n\n    st.divider()\n\n    # ------------------------------------------------------------------\n    # Section 3 – Advanced Options\n    # ------------------------------------------------------------------\n    with st.expander(\"🔧 Advanced Settings\", expanded=False):\n        col1, col2, col3 = st.columns(3)\n\n        with col1:\n            inference_steps = st.slider(\n                \"Diffusion Steps\",\n                min_value=4,\n                max_value=100,\n                value=8,\n                step=4,\n                help=\"More steps = higher quality but slower\",\n                key=\"inference_steps\",\n            )\n        with col2:\n            guidance_scale = st.slider(\n                \"Guidance Scale\",\n                min_value=1.0,\n                max_value=15.0,\n                value=7.0,\n                step=0.5,\n                help=\"Higher = follows prompt more strictly\",\n                key=\"guidance_scale\",\n            )\n        with col3:\n            seed = st.number_input(\n                \"Seed (-1 = random)\",\n                value=-1,\n                key=\"seed\",\n            )\n\n        col4, col5 = st.columns(2)\n        with col4:\n            batch_size = st.number_input(\n                \"Batch Size\",\n                min_value=1,\n                max_value=8,\n                value=1,\n                key=\"batch_size\",\n            )\n        with col5:\n            use_cot = st.checkbox(\n                \"LLM Chain-of-Thought reasoning\",\n                value=True,\n                help=\"Let the LLM refine metadata + codes\",\n                key=\"use_cot\",\n            )\n\n    st.divider()\n\n    # ------------------------------------------------------------------\n    # Generate button\n    # ------------------------------------------------------------------\n    col_l, col_c, col_r = st.columns([1, 2, 1])\n    with col_c:\n        if st.button(\n            \"🚀 Generate Song\",\n            use_container_width=True,\n            type=\"primary\",\n            key=\"gen_btn\",\n        ):\n            generate_song(\n                caption=caption,\n                duration=duration,\n                bpm=bpm,\n                key=key_opt,\n                lyrics=lyrics if use_lyrics else \"\",\n                inference_steps=inference_steps,\n                guidance_scale=guidance_scale,\n                seed=int(seed),\n                batch_size=int(batch_size),\n                use_cot=use_cot,\n            )\n\n\n# ------------------------------------------------------------------\n# Actual generation logic\n# ------------------------------------------------------------------\n\ndef generate_song(\n    caption: str,\n    duration: int,\n    bpm: Optional[int] = None,\n    key: str = \"\",\n    lyrics: str = \"\",\n    inference_steps: int = 8,\n    guidance_scale: float = 7.0,\n    seed: int = -1,\n    batch_size: int = 1,\n    use_cot: bool = True,\n) -> None:\n    \"\"\"Run ACE-Step generation and persist outputs.\"\"\"\n    if not is_dit_ready():\n        st.error(\n            \"DiT model not loaded. \"\n            \"Please initialise it in **Settings → Models**.\"\n        )\n        return\n\n    with st.spinner(\"🎹 Generating your music...\"):\n        try:\n            dit_handler = get_dit_handler()\n            llm_handler = get_llm_handler()\n\n            progress_bar = st.progress(0)\n            status_text = st.empty()\n\n            status_text.text(\"⏳ Preparing generation...\")\n            progress_bar.progress(5)\n\n            # Use the high-level inference API\n            from acestep.inference import (\n                GenerationParams,\n                GenerationConfig,\n                generate_music,\n            )\n\n            params = GenerationParams(\n                task_type=\"text2music\",\n                caption=caption,\n                lyrics=lyrics or \"[Instrumental]\",\n                duration=float(duration),\n                bpm=bpm,\n                keyscale=key,\n                inference_steps=inference_steps,\n                guidance_scale=guidance_scale,\n                seed=seed,\n                thinking=use_cot,\n                use_cot_metas=use_cot,\n                use_cot_caption=use_cot,\n                use_cot_language=use_cot,\n            )\n\n            config = GenerationConfig(\n                batch_size=batch_size,\n                use_random_seed=(seed < 0),\n                seeds=[seed] if seed >= 0 else None,\n            )\n\n            status_text.text(\"🎨 Running ACE-Step pipeline...\")\n            progress_bar.progress(20)\n\n            result = generate_music(\n                dit_handler=dit_handler,\n                llm_handler=llm_handler,\n                params=params,\n                config=config,\n                save_dir=str(OUTPUT_DIR),\n            )\n\n            progress_bar.progress(100)\n\n            if not result.success:\n                st.error(f\"Generation failed: {result.error}\")\n                return\n\n            status_text.text(\"✅ Generation complete!\")\n\n            # Display generated audio files\n            if result.audios:\n                st.markdown(\"### 🎧 Results\")\n                for idx, audio_info in enumerate(result.audios):\n                    audio_path = audio_info.get(\"path\", \"\")\n                    if audio_path and Path(audio_path).exists():\n                        st.audio(audio_path)\n                        st.caption(\n                            f\"Song {idx + 1} — \"\n                            f\"{Path(audio_path).name}\"\n                        )\n\n            # Save as project\n            pm = ProjectManager(PROJECTS_DIR)\n            safe_name = (\n                caption[:30]\n                .replace(\" \", \"_\")\n                .replace(\"/\", \"_\")\n            )\n            project_path = pm.create_project(\n                safe_name, description=caption\n            )\n            pm.save_metadata(\n                project_path,\n                genre=caption,\n                mood=\"Generated\",\n                duration=duration,\n                bpm=bpm,\n            )\n\n            # Copy audio files into project\n            for audio_info in result.audios:\n                src = Path(audio_info.get(\"path\", \"\"))\n                if src.exists():\n                    import shutil\n                    dst = project_path / src.name\n                    shutil.copy2(str(src), str(dst))\n\n            st.success(\n                f\"🎉 Saved as project '{safe_name}'\"\n            )\n\n        except Exception as exc:\n            logger.error(f\"Generation error: {exc}\")\n            st.error(f\"❌ Generation failed: {exc}\")\n"
  },
  {
    "path": "acestep/ui/streamlit/components/settings_panel.py",
    "content": "\"\"\"\nSettings panel component - hardware and model configuration.\n\"\"\"\nimport sys\nfrom pathlib import Path\n\nimport streamlit as st\nfrom loguru import logger\n\nfrom config import PROJECTS_DIR, CACHE_DIR, CHECKPOINTS_DIR\nfrom utils import (\n    get_dit_handler,\n    get_llm_handler,\n    is_dit_ready,\n    is_llm_ready,\n    initialize_dit,\n    initialize_llm,\n)\n\n\ndef show_settings_panel() -> None:\n    \"\"\"Display settings and configuration panel.\"\"\"\n    st.markdown(\"## ⚙️ Settings & Configuration\")\n\n    tab1, tab2, tab3, tab4 = st.tabs(\n        [\"🤖 Models\", \"🖥️ Hardware\", \"📦 Storage\", \"ℹ️ About\"]\n    )\n\n    with tab1:\n        _show_model_settings()\n    with tab2:\n        _show_hardware_settings()\n    with tab3:\n        _show_storage_settings()\n    with tab4:\n        _show_about_section()\n\n\n# ------------------------------------------------------------------\n# Models tab\n# ------------------------------------------------------------------\n\ndef _show_model_settings() -> None:\n    \"\"\"Model initialisation controls.\"\"\"\n    st.markdown(\"### 🤖 Model Initialisation\")\n\n    # --- DiT ---\n    st.markdown(\"#### DiT (Diffusion Transformer)\")\n\n    dit_status = \"✅ Loaded\" if is_dit_ready() else \"⏳ Not loaded\"\n    st.write(f\"**Status:** {dit_status}\")\n\n    # Detect available DiT checkpoint names from disk\n    dit_models = _list_dit_models()\n    is_mac = sys.platform == \"darwin\"\n\n    col1, col2 = st.columns(2)\n    with col1:\n        dit_model = st.selectbox(\n            \"DiT Model\",\n            options=dit_models,\n            index=(\n                dit_models.index(\"acestep-v15-turbo\")\n                if \"acestep-v15-turbo\" in dit_models\n                else 0\n            ),\n            key=\"dit_model_select\",\n        )\n    with col2:\n        dit_device = st.selectbox(\n            \"Device\",\n            options=[\"auto\", \"cuda\", \"mps\", \"cpu\"],\n            index=0,\n            key=\"dit_device_select\",\n        )\n\n    offload_cpu = st.checkbox(\n        \"Offload to CPU when idle\",\n        value=not is_mac,\n        key=\"dit_offload\",\n    )\n\n    if st.button(\n        \"🚀 Load DiT Model\",\n        key=\"init_dit_btn\",\n        type=\"primary\",\n        use_container_width=True,\n    ):\n        with st.spinner(\"Loading DiT model (may take a minute)...\"):\n            status, ok = initialize_dit(\n                config_path=dit_model,\n                device=dit_device,\n                offload_to_cpu=offload_cpu,\n            )\n        if ok:\n            st.success(f\"✅ DiT loaded: {dit_model}\")\n        else:\n            st.error(f\"❌ DiT init failed: {status}\")\n\n    st.divider()\n\n    # --- LLM ---\n    st.markdown(\"#### 5Hz LM (Language Model)\")\n\n    llm_status = \"✅ Loaded\" if is_llm_ready() else \"⏳ Not loaded\"\n    st.write(f\"**Status:** {llm_status}\")\n\n    lm_models = _list_lm_models()\n    default_backend = \"mlx\" if is_mac else \"vllm\"\n\n    col1, col2 = st.columns(2)\n    with col1:\n        lm_model = st.selectbox(\n            \"LM Model\",\n            options=lm_models if lm_models else [\"acestep-5Hz-lm-1.7B\"],\n            index=0,\n            key=\"lm_model_select\",\n        )\n    with col2:\n        backend = st.selectbox(\n            \"Backend\",\n            options=[\"mlx\", \"pt\", \"vllm\"],\n            index=[\"mlx\", \"pt\", \"vllm\"].index(default_backend),\n            key=\"lm_backend_select\",\n        )\n\n    if st.button(\n        \"🚀 Load LLM\",\n        key=\"init_llm_btn\",\n        use_container_width=True,\n    ):\n        with st.spinner(\"Loading LLM (may take a minute)...\"):\n            status, ok = initialize_llm(\n                lm_model_path=lm_model,\n                backend=backend,\n                device=dit_device if \"dit_device_select\" in st.session_state else \"auto\",\n            )\n        if ok:\n            st.success(f\"✅ LLM loaded: {lm_model}\")\n        else:\n            st.error(f\"❌ LLM init failed: {status}\")\n\n    st.caption(\n        \"LLM is **optional** — it enriches generation with CoT \"\n        \"reasoning but is not required for basic text-to-music.\"\n    )\n\n\n# ------------------------------------------------------------------\n# Hardware tab\n# ------------------------------------------------------------------\n\ndef _show_hardware_settings() -> None:\n    \"\"\"Hardware and GPU configuration display.\"\"\"\n    st.markdown(\"### 🖥️ Hardware Info\")\n\n    try:\n        import torch\n\n        col1, col2, col3 = st.columns(3)\n        with col1:\n            st.metric(\"PyTorch\", torch.__version__)\n        with col2:\n            cuda = torch.cuda.is_available()\n            st.metric(\"CUDA\", \"✅\" if cuda else \"❌\")\n        with col3:\n            mps = (\n                hasattr(torch.backends, \"mps\")\n                and torch.backends.mps.is_available()\n            )\n            st.metric(\"MPS\", \"✅\" if mps else \"❌\")\n\n        if cuda:\n            for i in range(torch.cuda.device_count()):\n                name = torch.cuda.get_device_name(i)\n                mem = (\n                    torch.cuda.get_device_properties(i).total_memory\n                    / 1e9\n                )\n                st.write(f\"GPU {i}: **{name}** — {mem:.1f} GB\")\n    except ImportError:\n        st.warning(\"PyTorch not installed\")\n\n    st.markdown(\"#### System\")\n    col1, col2 = st.columns(2)\n    with col1:\n        st.metric(\"Platform\", sys.platform)\n    with col2:\n        st.metric(\"Python\", sys.version.split()[0])\n\n\n# ------------------------------------------------------------------\n# Storage tab\n# ------------------------------------------------------------------\n\ndef _show_storage_settings() -> None:\n    \"\"\"Storage and cache management.\"\"\"\n    st.markdown(\"### 📦 Storage & Cache\")\n\n    col1, col2 = st.columns(2)\n    with col1:\n        st.markdown(\"**Projects**\")\n        st.code(str(PROJECTS_DIR), language=\"bash\")\n        n_projects = len(list(PROJECTS_DIR.glob(\"*/\")))\n        st.metric(\"Projects\", n_projects)\n\n    with col2:\n        st.markdown(\"**Cache**\")\n        st.code(str(CACHE_DIR), language=\"bash\")\n        import os\n\n        cache_bytes = sum(\n            os.path.getsize(f)\n            for f in CACHE_DIR.rglob(\"*\")\n            if f.is_file()\n        )\n        st.metric(\"Cache Size\", f\"{cache_bytes / 1e6:.1f} MB\")\n\n    if st.button(\"🗑️ Clear Cache\", key=\"clear_cache_btn\"):\n        import shutil\n\n        shutil.rmtree(CACHE_DIR, ignore_errors=True)\n        CACHE_DIR.mkdir(exist_ok=True)\n        st.success(\"Cache cleared\")\n\n\n# ------------------------------------------------------------------\n# About tab\n# ------------------------------------------------------------------\n\ndef _show_about_section() -> None:\n    \"\"\"About ACE Studio.\"\"\"\n    st.markdown(\"### ℹ️ About ACE Studio\")\n    st.markdown(\n        \"\"\"\n**ACE Studio** is a modern Streamlit UI for\n[ACE-Step 1.5](https://github.com/ace-step/ACE-Step-1.5) —\nan open-source music generation foundation model.\n\n**Features:** text-to-music, covers, repainting, batch\ngeneration (up to 8 songs), project management.\n\"\"\"\n    )\n\n    col1, col2, col3 = st.columns(3)\n    with col1:\n        st.link_button(\"GitHub\", \"https://github.com/ace-step/ACE-Step-1.5\")\n    with col2:\n        st.link_button(\"HuggingFace\", \"https://huggingface.co/ACE-Step/Ace-Step1.5\")\n    with col3:\n        st.link_button(\"Discord\", \"https://discord.gg/PeWDxrkdj7\")\n\n    st.caption(\"ACE Studio v0.1.0 (MVP)\")\n\n\n# ------------------------------------------------------------------\n# Helpers\n# ------------------------------------------------------------------\n\ndef _list_dit_models() -> list:\n    \"\"\"Scan checkpoints dir for DiT model folders.\"\"\"\n    handler = get_dit_handler()\n    if handler is not None:\n        try:\n            models = handler.get_available_acestep_v15_models()\n            if models:\n                return models\n        except Exception:\n            pass\n    # Fallback: scan disk\n    pattern = \"acestep-v15-*\"\n    found = sorted(\n        p.name\n        for p in CHECKPOINTS_DIR.glob(pattern)\n        if p.is_dir()\n    )\n    return found if found else [\"acestep-v15-turbo\"]\n\n\ndef _list_lm_models() -> list:\n    \"\"\"Scan checkpoints dir for LM model folders.\"\"\"\n    handler = get_llm_handler()\n    if handler is not None:\n        try:\n            models = handler.get_available_5hz_lm_models()\n            if models:\n                return models\n        except Exception:\n            pass\n    # Fallback: scan disk\n    pattern = \"acestep-5Hz-lm-*\"\n    found = sorted(\n        p.name\n        for p in CHECKPOINTS_DIR.glob(pattern)\n        if p.is_dir()\n    )\n    return found if found else [\"acestep-5Hz-lm-1.7B\"]\n"
  },
  {
    "path": "acestep/ui/streamlit/config.py",
    "content": "\"\"\"\nACE Studio Streamlit Configuration\n\"\"\"\nimport os\nimport sys\nfrom pathlib import Path\n\n# Project paths\nPROJECT_ROOT = Path(__file__).parent\nACESTEP_ROOT = PROJECT_ROOT.parent.parent.parent  # ACE-Step-1.5 repo root\nCHECKPOINTS_DIR = ACESTEP_ROOT / \"checkpoints\"\nPROJECTS_DIR = PROJECT_ROOT / \"projects\"\nOUTPUT_DIR = ACESTEP_ROOT / \"gradio_outputs\"\nCACHE_DIR = PROJECT_ROOT / \".cache\"\n\n# Ensure ACE-Step repo is on Python path\nif str(ACESTEP_ROOT) not in sys.path:\n    sys.path.insert(0, str(ACESTEP_ROOT))\n\n# Ensure directories exist\nPROJECTS_DIR.mkdir(exist_ok=True)\nCACHE_DIR.mkdir(exist_ok=True)\nOUTPUT_DIR.mkdir(exist_ok=True)\n\n# UI Configuration\nGENERATION_MODES = {\n    \"text2music\": \"🎵 Text to Music\",\n    \"cover\": \"🎤 Create Cover\",\n    \"repaint\": \"🎨 Repaint Section\",\n    \"complete\": \"🎼 Complete Section\",\n    \"extract\": \"🎹 Extract Vocals\",\n}\n\nGENRES = [\n    \"Pop\", \"Hip-Hop\", \"Jazz\", \"Rock\", \"Classical\",\n    \"Electronic\", \"Indie\", \"Country\", \"R&B\", \"Ambient\"\n]\n\nMOODS = [\"Energetic\", \"Chill\", \"Melancholic\", \"Uplifting\", \"Dark\", \"Dreamy\"]\n\nINSTRUMENTS = [\n    \"Guitar\", \"Piano\", \"Drums\", \"Bass\", \"Strings\",\n    \"Synth\", \"Flute\", \"Trumpet\", \"Violin\", \"Cello\"\n]\n\n# Generation defaults\nDEFAULT_DURATION = 120  # seconds\nDEFAULT_BPM = 120\nDEFAULT_GUIDANCE = 7.5\nDEFAULT_STEPS = 32  # Base model steps (turbo uses fewer)\n\n# UI Display\nSIDEBAR_ICON = \"🎹\"\nAPP_TITLE = \"ACE Studio\"\nAPP_SUBTITLE = \"Music Generation & Editing\"\n\n# Supported audio formats\nAUDIO_FORMATS = [\".wav\", \".mp3\", \".m4a\", \".flac\"]\n"
  },
  {
    "path": "acestep/ui/streamlit/main.py",
    "content": "\"\"\"\nACE Studio - Modern Streamlit UI for Music Generation\nMain application entry point\n\"\"\"\nimport streamlit as st\nimport sys\nfrom pathlib import Path\n\n# Configure Streamlit page\nst.set_page_config(\n    page_title=\"ACE Studio\",\n    page_icon=\"🎹\",\n    layout=\"wide\",\n    initial_sidebar_state=\"expanded\",\n    menu_items={\n        \"Get Help\": (\n            \"https://github.com/ace-step/ACE-Step-1.5\"\n        ),\n        \"Report a bug\": (\n            \"https://github.com/ace-step/ACE-Step-1.5/issues\"\n        ),\n        \"About\": (\n            \"ACE Studio v0.1.0 - Streamlit UI for \"\n            \"ACE-Step Music Generation\"\n        ),\n    },\n)\n\n# Custom CSS\nst.markdown(\n    \"\"\"\n<style>\n    .main { padding: 1rem; }\n    [data-testid=\"stMetricValue\"] { font-size: 1.5rem; }\n    .stButton > button { border-radius: 8px; }\n</style>\n\"\"\",\n    unsafe_allow_html=True,\n)\n\n# Initialize session state\nif \"tab\" not in st.session_state:\n    st.session_state.tab = \"dashboard\"\nif \"editor_mode\" not in st.session_state:\n    st.session_state.editor_mode = \"repaint\"\nif \"selected_project\" not in st.session_state:\n    st.session_state.selected_project = None\n\n# Import components\nfrom components import (\n    show_dashboard,\n    show_generation_wizard,\n    show_editor,\n    show_batch_generator,\n    show_settings_panel,\n)\nfrom utils import is_dit_ready, initialize_dit, initialize_llm\n\n# ------------------------------------------------------------------\n# Auto-initialise models on first load (runs once per session)\n# ------------------------------------------------------------------\nif \"_models_auto_init_done\" not in st.session_state:\n    st.session_state._models_auto_init_done = True\n    if not is_dit_ready():\n        with st.spinner(\n            \"Loading DiT model (first launch, may take a minute)...\"\n        ):\n            _status, _ok = initialize_dit(\n                config_path=\"acestep-v15-turbo\",\n                device=\"auto\",\n                offload_to_cpu=(sys.platform != \"darwin\"),\n            )\n            if _ok:\n                st.toast(\"DiT model loaded successfully\", icon=\"✅\")\n            else:\n                st.toast(\n                    f\"DiT auto-init failed: {_status}\",\n                    icon=\"⚠️\",\n                )\n        # Also try LLM (non-blocking; optional)\n        _backend = \"mlx\" if sys.platform == \"darwin\" else \"vllm\"\n        with st.spinner(\"Loading LLM (optional, for CoT)...\"):\n            _lm_status, _lm_ok = initialize_llm(\n                backend=_backend, device=\"auto\",\n            )\n            if _lm_ok:\n                st.toast(\"LLM loaded successfully\", icon=\"✅\")\n            else:\n                st.toast(\n                    \"LLM not loaded (optional)\", icon=\"ℹ️\",\n                )\n\n# ------------------------------------------------------------------\n# Sidebar navigation\n# ------------------------------------------------------------------\nwith st.sidebar:\n    st.markdown(\"### 🎹 ACE Studio\")\n\n    nav_selection = st.radio(\n        \"Select Tab\",\n        options=[\n            \"📊 Dashboard\",\n            \"🎵 Generate\",\n            \"🎛️ Edit\",\n            \"📦 Batch\",\n            \"⚙️ Settings\",\n        ],\n        label_visibility=\"collapsed\",\n        index=[\n            \"dashboard\",\n            \"generate\",\n            \"editor\",\n            \"batch\",\n            \"settings\",\n        ].index(st.session_state.tab),\n    )\n\n    tab_map = {\n        \"📊 Dashboard\": \"dashboard\",\n        \"🎵 Generate\": \"generate\",\n        \"🎛️ Edit\": \"editor\",\n        \"📦 Batch\": \"batch\",\n        \"⚙️ Settings\": \"settings\",\n    }\n    st.session_state.tab = tab_map[nav_selection]\n\n    st.divider()\n\n    # Quick project count\n    try:\n        from utils import ProjectManager\n        from config import PROJECTS_DIR\n\n        pm = ProjectManager(PROJECTS_DIR)\n        projects = pm.list_projects()\n        st.metric(\"💾 Projects\", len(projects))\n    except Exception:\n        pass\n\n    st.divider()\n\n    # ------------------------------------------------------------------\n    # Model status (lightweight - never loads weights here)\n    # ------------------------------------------------------------------\n    st.markdown(\"### 🤖 Model Status\")\n\n    from utils import is_llm_ready\n\n    col1, col2 = st.columns(2)\n    with col1:\n        if is_dit_ready():\n            st.success(\"✅ DiT\")\n        else:\n            st.warning(\"⏳ DiT\")\n    with col2:\n        if is_llm_ready():\n            st.success(\"✅ LLM\")\n        else:\n            st.info(\"⏸️ LLM\")\n\n    if not is_dit_ready():\n        st.caption(\n            \"Go to **⚙️ Settings → Models** to initialise.\"\n        )\n\n    st.divider()\n\n    # Quick help\n    with st.expander(\"❓ Quick Help\"):\n        st.markdown(\n            \"\"\"\n**Getting Started:**\n1. Go to **Settings → Models** to load the AI model\n2. Use **Generate** to create new songs\n3. Use **Edit** to modify generated audio\n4. Use **Batch** to generate multiple songs\n\n**Tips:**\n- Be descriptive in song captions\n- Use editing to refine generated songs\n\"\"\"\n        )\n\n# ------------------------------------------------------------------\n# Main content area – route to selected tab\n# ------------------------------------------------------------------\nif st.session_state.tab == \"dashboard\":\n    show_dashboard()\nelif st.session_state.tab == \"generate\":\n    show_generation_wizard()\nelif st.session_state.tab == \"editor\":\n    show_editor()\nelif st.session_state.tab == \"batch\":\n    show_batch_generator()\nelif st.session_state.tab == \"settings\":\n    show_settings_panel()\nelse:\n    st.error(f\"Unknown tab: {st.session_state.tab}\")\n    show_dashboard()\n\n# Footer\nst.divider()\nst.markdown(\n    \"\"\"\n<div style=\"text-align: center; color: #888; font-size: 0.85rem;\">\n    <p>\n        🎵 <strong>ACE Studio</strong> v0.1.0 |\n        Powered by\n        <a href=\"https://github.com/ace-step/ACE-Step-1.5\">\n        ACE-Step</a> |\n        <a href=\"https://discord.gg/PeWDxrkdj7\">Discord</a>\n    </p>\n</div>\n\"\"\",\n    unsafe_allow_html=True,\n)\n"
  },
  {
    "path": "acestep/ui/streamlit/requirements.txt",
    "content": "streamlit==1.40.2\nstreamlit-player==0.1.5\nstreamlit-audio-recorder==0.0.8\nplotly==5.24.1\nlibrosa==0.10.2\nnumpy==1.26.4\nscipy==1.14.1\n"
  },
  {
    "path": "acestep/ui/streamlit/run.bat",
    "content": "@echo off\nREM Quick start script for ACE Studio Streamlit UI (Windows)\n\nsetlocal enabledelayedexpansion\n\necho 🎹 ACE Studio - Quick Start\necho ==================================\n\nREM Check Python\necho Checking Python...\npython --version\n\nREM Check if venv exists\nif not exist \"..\\..\\..\\.venv\" (\n    echo Creating virtual environment...\n    python -m venv ..\\..\\..\\.venv\n)\n\nREM Activate venv\necho Activating virtual environment...\ncall ..\\..\\..\\.venv\\Scripts\\activate.bat\n\nREM Install dependencies\necho Installing Streamlit dependencies...\npip install -q -r requirements.txt\n\nREM Run the app\necho.\necho ==================================\necho ✅ Setup complete!\necho 🚀 Starting ACE Studio...\necho 📱 Open: http://localhost:8501\necho ==================================\necho.\n\nstreamlit run main.py\n\nendlocal\n"
  },
  {
    "path": "acestep/ui/streamlit/run.sh",
    "content": "#!/bin/bash\n# Quick start script for ACE Studio Streamlit UI\n\nset -e\n\necho \"🎹 ACE Studio - Quick Start\"\necho \"==================================\"\n\n# Check Python\necho \"Checking Python...\"\npython --version\n\n# Check if venv exists\nif [ ! -d \"../../../.venv\" ]; then\n    echo \"Creating virtual environment...\"\n    python -m venv ../../../.venv\nfi\n\n# Activate venv\necho \"Activating virtual environment...\"\nsource ../../../.venv/bin/activate\n\n# Install dependencies\necho \"Installing Streamlit dependencies...\"\npip install -q -r requirements.txt\n\n# Run the app\necho \"\"\necho \"==================================\"\necho \"✅ Setup complete!\"\necho \"🚀 Starting ACE Studio...\"\necho \"📱 Open: http://localhost:8501\"\necho \"==================================\"\necho \"\"\n\nstreamlit run main.py\n"
  },
  {
    "path": "acestep/ui/streamlit/utils/__init__.py",
    "content": "\"\"\"ACE Studio Utilities\"\"\"\nfrom .cache import (\n    get_dit_handler,\n    get_llm_handler,\n    is_dit_ready,\n    is_llm_ready,\n    initialize_dit,\n    initialize_llm,\n)\nfrom .project_manager import ProjectManager\nfrom .audio_utils import (\n    save_audio_file,\n    load_audio_file,\n    get_audio_duration,\n)\n\n__all__ = [\n    \"get_dit_handler\",\n    \"get_llm_handler\",\n    \"is_dit_ready\",\n    \"is_llm_ready\",\n    \"initialize_dit\",\n    \"initialize_llm\",\n    \"ProjectManager\",\n    \"save_audio_file\",\n    \"load_audio_file\",\n    \"get_audio_duration\",\n]\n"
  },
  {
    "path": "acestep/ui/streamlit/utils/audio_utils.py",
    "content": "\"\"\"\nAudio file handling utilities\n\"\"\"\nimport numpy as np\nfrom pathlib import Path\nfrom typing import Tuple, Optional\nfrom loguru import logger\n\ntry:\n    import librosa\nexcept ImportError:\n    librosa = None\n\n\ndef load_audio_file(file_path: str, sr: int = 16000) -> Tuple[np.ndarray, int]:\n    \"\"\"Load audio file and return (audio_data, sample_rate)\"\"\"\n    if not librosa:\n        raise ImportError(\"librosa is required for audio loading\")\n    \n    try:\n        audio, sr = librosa.load(file_path, sr=sr)\n        return audio, sr\n    except Exception as e:\n        logger.error(f\"Failed to load audio from {file_path}: {e}\")\n        raise\n\n\ndef save_audio_file(audio_data: np.ndarray, file_path: str, sr: int = 16000) -> None:\n    \"\"\"Save audio data to file\"\"\"\n    if not librosa:\n        raise ImportError(\"librosa is required for audio saving\")\n    \n    try:\n        librosa.output.write_wav(file_path, audio_data, sr=sr)\n        logger.info(f\"Saved audio to {file_path}\")\n    except Exception as e:\n        logger.error(f\"Failed to save audio to {file_path}: {e}\")\n        raise\n\n\ndef get_audio_duration(file_path: str) -> float:\n    \"\"\"Get audio duration in seconds\"\"\"\n    if not librosa:\n        raise ImportError(\"librosa is required for audio analysis\")\n    \n    try:\n        duration = librosa.get_duration(filename=file_path)\n        return duration\n    except Exception as e:\n        logger.error(f\"Failed to get duration of {file_path}: {e}\")\n        return 0.0\n\n\ndef normalize_audio(audio_data: np.ndarray, target_db: float = -1.0) -> np.ndarray:\n    \"\"\"Normalize audio to target loudness (dB)\"\"\"\n    try:\n        # Calculate current RMS level\n        rms = np.sqrt(np.mean(audio_data ** 2))\n        if rms == 0:\n            return audio_data\n        \n        # Convert target dB to linear scale\n        target_linear = 10 ** (target_db / 20.0)\n        \n        # Scale audio\n        normalized = audio_data * (target_linear / rms)\n        \n        # Prevent clipping\n        max_val = np.max(np.abs(normalized))\n        if max_val > 1.0:\n            normalized = normalized / max_val\n        \n        return normalized\n    except Exception as e:\n        logger.error(f\"Failed to normalize audio: {e}\")\n        return audio_data\n\n\ndef get_waveform_data(audio_data: np.ndarray, num_points: int = 1000) -> np.ndarray:\n    \"\"\"Downsample audio for visualization\"\"\"\n    if len(audio_data) <= num_points:\n        return audio_data\n    \n    # Average pooling for downsampling\n    pool_size = len(audio_data) // num_points\n    downsampled = audio_data[:pool_size * num_points].reshape(-1, pool_size).mean(axis=1)\n    return downsampled\n"
  },
  {
    "path": "acestep/ui/streamlit/utils/cache.py",
    "content": "\"\"\"\nHandler caching for Streamlit.\n\nCreates / caches AceStepHandler and LLMHandler instances and exposes\na single ``initialize_models()`` that loads weights on demand.\n\"\"\"\nimport os\nimport sys\nfrom typing import Optional, Tuple\nfrom pathlib import Path\n\nimport streamlit as st\nfrom loguru import logger\n\n# Ensure ACE-Step repo is on Python path\n_project_root = Path(__file__).parent.parent.parent.parent.parent\nif str(_project_root) not in sys.path:\n    sys.path.insert(0, str(_project_root))\n\n\n# ------------------------------------------------------------------\n# Lightweight handler singletons (no model weights loaded yet)\n# ------------------------------------------------------------------\n\n@st.cache_resource\ndef get_dit_handler():\n    \"\"\"Return a cached AceStepHandler instance (uninitialised).\"\"\"\n    try:\n        from acestep.handler import AceStepHandler\n        logger.info(\"Creating AceStepHandler instance...\")\n        return AceStepHandler()\n    except Exception as exc:\n        logger.error(f\"Failed to create AceStepHandler: {exc}\")\n        return None\n\n\n@st.cache_resource\ndef get_llm_handler():\n    \"\"\"Return a cached LLMHandler instance (uninitialised).\"\"\"\n    try:\n        from acestep.llm_inference import LLMHandler\n        logger.info(\"Creating LLMHandler instance...\")\n        return LLMHandler()\n    except Exception as exc:\n        logger.error(f\"Failed to create LLMHandler: {exc}\")\n        return None\n\n\n@st.cache_resource\ndef get_dataset_handler():\n    \"\"\"Return a cached DatasetHandler instance.\"\"\"\n    try:\n        from acestep.dataset_handler import DatasetHandler\n        logger.info(\"Creating DatasetHandler instance...\")\n        return DatasetHandler()\n    except Exception as exc:\n        logger.error(f\"Failed to create DatasetHandler: {exc}\")\n        return None\n\n\n# ------------------------------------------------------------------\n# Model initialisation helpers\n# ------------------------------------------------------------------\n\ndef is_dit_ready() -> bool:\n    \"\"\"Check whether DiT model weights are loaded.\"\"\"\n    handler = get_dit_handler()\n    return handler is not None and handler.model is not None\n\n\ndef is_llm_ready() -> bool:\n    \"\"\"Check whether LLM model weights are loaded.\"\"\"\n    handler = get_llm_handler()\n    return handler is not None and handler.llm_initialized\n\n\ndef initialize_dit(\n    config_path: str = \"acestep-v15-turbo\",\n    device: str = \"auto\",\n    offload_to_cpu: bool = False,\n    compile_model: bool = False,\n) -> Tuple[str, bool]:\n    \"\"\"Load DiT model weights into the cached handler.\n\n    Returns:\n        (status_message, success)\n    \"\"\"\n    handler = get_dit_handler()\n    if handler is None:\n        return \"AceStepHandler could not be created\", False\n\n    project_root = str(_project_root)\n    use_flash = handler.is_flash_attention_available(device)\n\n    status, ok = handler.initialize_service(\n        project_root=project_root,\n        config_path=config_path,\n        device=device,\n        use_flash_attention=use_flash,\n        compile_model=compile_model,\n        offload_to_cpu=offload_to_cpu,\n    )\n    return status, ok\n\n\ndef initialize_llm(\n    lm_model_path: str = \"acestep-5Hz-lm-1.7B\",\n    backend: str = \"mlx\",\n    device: str = \"auto\",\n    offload_to_cpu: bool = False,\n) -> Tuple[str, bool]:\n    \"\"\"Load LLM model weights into the cached handler.\n\n    Returns:\n        (status_message, success)\n    \"\"\"\n    handler = get_llm_handler()\n    if handler is None:\n        return \"LLMHandler could not be created\", False\n\n    checkpoint_dir = str(_project_root / \"checkpoints\")\n\n    # Ensure model is downloaded\n    try:\n        from acestep.model_downloader import ensure_lm_model\n        dl_ok, dl_msg = ensure_lm_model(\n            model_name=lm_model_path,\n            checkpoints_dir=checkpoint_dir,\n        )\n        if not dl_ok:\n            logger.warning(f\"LM model download issue: {dl_msg}\")\n    except Exception as exc:\n        logger.warning(f\"LM model download check failed: {exc}\")\n\n    status, ok = handler.initialize(\n        checkpoint_dir=checkpoint_dir,\n        lm_model_path=lm_model_path,\n        backend=backend,\n        device=device,\n        offload_to_cpu=offload_to_cpu,\n    )\n    return status, ok\n\n\ndef clear_handlers() -> None:\n    \"\"\"Clear all cached handlers (forces re-creation).\"\"\"\n    st.cache_resource.clear()\n"
  },
  {
    "path": "acestep/ui/streamlit/utils/project_manager.py",
    "content": "\"\"\"\nProject management for ACE Studio\nHandles saving, loading, and organizing music projects\n\"\"\"\nimport json\nimport shutil\nfrom pathlib import Path\nfrom datetime import datetime\nfrom typing import Dict, List, Optional\nfrom dataclasses import dataclass, asdict\nfrom loguru import logger\nfrom config import PROJECTS_DIR\n\n\n@dataclass\nclass ProjectMetadata:\n    \"\"\"Metadata for a music project\"\"\"\n    name: str\n    created_at: str  # ISO format\n    modified_at: str  # ISO format\n    description: str = \"\"\n    genre: str = \"\"\n    mood: str = \"\"\n    bpm: Optional[int] = None\n    duration: Optional[int] = None  # seconds\n    tags: List[str] = None\n    \n    def __post_init__(self):\n        if self.tags is None:\n            self.tags = []\n\n\nclass ProjectManager:\n    \"\"\"Manage music projects (save, load, organize)\"\"\"\n    \n    def __init__(self, projects_dir: Path = PROJECTS_DIR):\n        self.projects_dir = projects_dir\n        self.projects_dir.mkdir(exist_ok=True)\n    \n    def create_project(self, name: str, description: str = \"\") -> Path:\n        \"\"\"Create a new project folder\"\"\"\n        project_path = self.projects_dir / name\n        project_path.mkdir(exist_ok=True)\n        \n        # Create metadata file\n        metadata = ProjectMetadata(\n            name=name,\n            created_at=datetime.now().isoformat(),\n            modified_at=datetime.now().isoformat(),\n            description=description,\n        )\n        self._save_metadata(project_path, metadata)\n        \n        logger.info(f\"Created project: {name} at {project_path}\")\n        return project_path\n    \n    def get_project(self, name: str) -> Optional[Path]:\n        \"\"\"Get project path by name\"\"\"\n        project_path = self.projects_dir / name\n        if project_path.exists():\n            return project_path\n        return None\n    \n    def list_projects(self) -> List[Dict]:\n        \"\"\"List all projects with metadata\"\"\"\n        projects = []\n        for project_path in self.projects_dir.iterdir():\n            if project_path.is_dir():\n                metadata = self._load_metadata(project_path)\n                if metadata:\n                    projects.append({\n                        \"path\": str(project_path),\n                        \"name\": project_path.name,\n                        **asdict(metadata),\n                    })\n        \n        # Sort by modified date (newest first)\n        projects.sort(key=lambda p: p[\"modified_at\"], reverse=True)\n        return projects\n    \n    def save_metadata(self, project_path: Path, **kwargs) -> None:\n        \"\"\"Update project metadata\"\"\"\n        metadata = self._load_metadata(project_path) or ProjectMetadata(\n            name=project_path.name,\n            created_at=datetime.now().isoformat(),\n            modified_at=datetime.now().isoformat(),\n        )\n        \n        # Update with provided kwargs\n        for key, value in kwargs.items():\n            if hasattr(metadata, key):\n                setattr(metadata, key, value)\n        \n        metadata.modified_at = datetime.now().isoformat()\n        self._save_metadata(project_path, metadata)\n    \n    def save_audio(self, project_path: Path, audio_data: bytes, filename: str = \"output.wav\") -> Path:\n        \"\"\"Save audio file to project\"\"\"\n        audio_path = project_path / filename\n        with open(audio_path, \"wb\") as f:\n            f.write(audio_data)\n        \n        self.save_metadata(project_path)  # Update modified_at\n        return audio_path\n    \n    def get_audio_files(self, project_path: Path) -> List[Path]:\n        \"\"\"Get all audio files in project\"\"\"\n        audio_extensions = [\".wav\", \".mp3\", \".m4a\", \".flac\"]\n        return [\n            f for f in project_path.iterdir()\n            if f.suffix.lower() in audio_extensions\n        ]\n    \n    def delete_project(self, name: str) -> bool:\n        \"\"\"Delete a project\"\"\"\n        project_path = self.projects_dir / name\n        if project_path.exists():\n            shutil.rmtree(project_path)\n            logger.info(f\"Deleted project: {name}\")\n            return True\n        return False\n    \n    def _save_metadata(self, project_path: Path, metadata: ProjectMetadata) -> None:\n        \"\"\"Save metadata JSON file\"\"\"\n        metadata_path = project_path / \"metadata.json\"\n        with open(metadata_path, \"w\") as f:\n            json.dump(asdict(metadata), f, indent=2)\n    \n    def _load_metadata(self, project_path: Path) -> Optional[ProjectMetadata]:\n        \"\"\"Load metadata JSON file\"\"\"\n        metadata_path = project_path / \"metadata.json\"\n        if metadata_path.exists():\n            try:\n                with open(metadata_path, \"r\") as f:\n                    data = json.load(f)\n                    return ProjectMetadata(**data)\n            except Exception as e:\n                logger.error(f\"Failed to load metadata from {metadata_path}: {e}\")\n        return None\n"
  },
  {
    "path": "check_update.bat",
    "content": "@echo off\nREM Git Update Check Utility\nREM This script checks for updates from GitHub and optionally updates the repository\n\nsetlocal enabledelayedexpansion\n\nREM Configuration\nset TIMEOUT_SECONDS=10\nset GIT_PORTABLE_PATH=%~dp0PortableGit\\bin\\git.exe\nset GIT_PATH=\nset REPO_PATH=%~dp0\nset PROXY_CONFIG_FILE=%~dp0proxy_config.txt\n\necho ========================================\necho ACE-Step Update Check\necho ========================================\necho.\n\nREM Check for Git: first try PortableGit, then system Git\nif exist \"%GIT_PORTABLE_PATH%\" (\n    set \"GIT_PATH=%GIT_PORTABLE_PATH%\"\n    echo [Git] Using PortableGit\n) else (\n    REM Try to find git in system PATH\n    where git >nul 2>&1\n    if !ERRORLEVEL! EQU 0 (\n        for /f \"tokens=*\" %%i in ('where git 2^>nul') do (\n            if not defined GIT_PATH set \"GIT_PATH=%%i\"\n        )\n        echo [Git] Using system Git: !GIT_PATH!\n    ) else (\n        echo [Error] Git not found.\n        echo   - PortableGit not found at: %GIT_PORTABLE_PATH%\n        echo   - System Git not found in PATH\n        echo.\n        echo Please either:\n        echo   1. Install PortableGit in the PortableGit folder, or\n        echo   2. Install Git and add it to your system PATH\n        echo.\n        echo ========================================\n        echo Press any key to close...\n        echo ========================================\n        pause >nul\n        exit /b 1\n    )\n)\necho.\n\nREM Check if this is a git repository\ncd /d \"%REPO_PATH%\"\n\"!GIT_PATH!\" rev-parse --git-dir >nul 2>&1\nif %ERRORLEVEL% NEQ 0 (\n    echo [Error] Not a git repository.\n    echo This folder does not appear to be a git repository.\n    echo.\n    echo ========================================\n    echo Press any key to close...\n    echo ========================================\n    pause >nul\n    exit /b 1\n)\n\nREM Load proxy configuration if exists\nset PROXY_ENABLED=0\nset PROXY_URL=\nif exist \"%PROXY_CONFIG_FILE%\" (\n    for /f \"usebackq tokens=1,* delims==\" %%a in (\"%PROXY_CONFIG_FILE%\") do (\n        if /i \"%%a\"==\"PROXY_ENABLED\" set PROXY_ENABLED=%%b\n        if /i \"%%a\"==\"PROXY_URL\" set PROXY_URL=%%b\n    )\n\n    if \"!PROXY_ENABLED!\"==\"1\" (\n        if not \"!PROXY_URL!\"==\"\" (\n            echo [Proxy] Using proxy server: !PROXY_URL!\n            \"!GIT_PATH!\" config --local http.proxy \"!PROXY_URL!\"\n            \"!GIT_PATH!\" config --local https.proxy \"!PROXY_URL!\"\n            echo.\n        )\n    )\n)\n\necho [1/4] Checking current version...\nREM Get current branch\nfor /f \"tokens=*\" %%i in ('\"!GIT_PATH!\" rev-parse --abbrev-ref HEAD 2^>nul') do set CURRENT_BRANCH=%%i\nif \"%CURRENT_BRANCH%\"==\"\" set CURRENT_BRANCH=main\n\nREM Get current commit\nfor /f \"tokens=*\" %%i in ('\"!GIT_PATH!\" rev-parse --short HEAD 2^>nul') do set CURRENT_COMMIT=%%i\n\necho   Branch: %CURRENT_BRANCH%\necho   Commit: %CURRENT_COMMIT%\necho.\n\necho [2/4] Checking for updates (timeout: %TIMEOUT_SECONDS%s)...\necho   Connecting to GitHub...\n\n:FetchRetry\nREM Fetch remote with timeout\nREM Use START /B to run in background and check timeout\nset FETCH_SUCCESS=0\n\"!GIT_PATH!\" fetch origin --quiet 2>nul\nif %ERRORLEVEL% EQU 0 (\n    set FETCH_SUCCESS=1\n)\nif !FETCH_SUCCESS! EQU 1 goto :FetchDone\n\nREM Try with timeout using a temp marker file\nset TEMP_MARKER=%TEMP%\\acestep_git_fetch_%RANDOM%.tmp\n\nREM Start fetch in background\nset \"FETCH_CMD=!GIT_PATH! fetch origin --quiet\"\nstart /b \"\" cmd /c \"!FETCH_CMD! >nul 2>&1 && echo SUCCESS > \"!TEMP_MARKER!\"\"\n\nREM Wait with timeout\nset /a COUNTER=0\n:WaitLoop\nif exist \"!TEMP_MARKER!\" (\n    set FETCH_SUCCESS=1\n    del \"!TEMP_MARKER!\" >nul 2>&1\n    goto :FetchDone\n)\n\ntimeout /t 1 /nobreak >nul\nset /a COUNTER+=1\nif !COUNTER! LSS %TIMEOUT_SECONDS% goto :WaitLoop\n\nREM Timeout reached\necho   [Timeout] Could not connect to GitHub within %TIMEOUT_SECONDS% seconds.\n\n:FetchDone\nif %FETCH_SUCCESS% EQU 0 (\n    echo   [Failed] Could not fetch from GitHub.\n    echo   Please check your internet connection.\n    echo.\n\n    REM Ask if user wants to configure proxy\n    set /p PROXY_CHOICE=\"Do you want to configure a proxy server to retry? (Y/N): \"\n    if /i \"!PROXY_CHOICE!\"==\"Y\" (\n        call :ConfigureProxy\n        if !ERRORLEVEL! EQU 0 (\n            echo.\n            echo [Proxy] Retrying with proxy configuration...\n            echo.\n            goto :FetchRetry\n        )\n    )\n\n    echo.\n    echo ========================================\n    echo Press any key to close...\n    echo ========================================\n    pause >nul\n    exit /b 2\n)\n\necho   [Success] Fetched latest information from GitHub.\necho.\n\necho [3/4] Comparing versions...\nREM Get remote commit\nfor /f \"tokens=*\" %%i in ('\"!GIT_PATH!\" rev-parse --short origin/%CURRENT_BRANCH% 2^>nul') do set REMOTE_COMMIT=%%i\n\nif \"%REMOTE_COMMIT%\"==\"\" (\n    echo   [Warning] Remote branch 'origin/%CURRENT_BRANCH%' not found.\n    echo.\n    echo   Your current branch '%CURRENT_BRANCH%' does not exist on the remote repository.\n    echo   This might be a local development branch.\n    echo.\n\n    REM Try to get main branch instead\n    set FALLBACK_BRANCH=main\n    echo   Checking main branch instead...\n    for /f \"tokens=*\" %%i in ('\"!GIT_PATH!\" rev-parse --short origin/!FALLBACK_BRANCH! 2^>nul') do set REMOTE_COMMIT=%%i\n\n    if \"!REMOTE_COMMIT!\"==\"\" (\n        echo   [Error] Could not find remote main branch either.\n        echo   Please ensure you are connected to the correct repository.\n        echo.\n        echo ========================================\n        echo Press any key to close...\n        echo ========================================\n        pause >nul\n        exit /b 1\n    )\n\n    echo   Found main branch: !REMOTE_COMMIT!\n    echo.\n    echo   Recommendation: Switch to main branch to check for official updates.\n    echo   Command: git checkout main\n    echo.\n\n    set /p SWITCH_BRANCH=\"Do you want to switch to main branch now? (Y/N): \"\n    if /i \"!SWITCH_BRANCH!\"==\"Y\" (\n        echo.\n        echo   Switching to main branch...\n        \"!GIT_PATH!\" checkout main\n\n        if !ERRORLEVEL! EQU 0 (\n            echo   [Success] Switched to main branch.\n            echo.\n            echo   Please run this script again to check for updates.\n            echo.\n            echo ========================================\n            echo Press any key to close...\n            echo ========================================\n            pause >nul\n            exit /b 0\n        ) else (\n            echo   [Error] Failed to switch branch.\n            echo.\n            echo ========================================\n            echo Press any key to close...\n            echo ========================================\n            pause >nul\n            exit /b 1\n        )\n    ) else (\n        echo.\n        echo   Staying on branch '%CURRENT_BRANCH%'. No update performed.\n        echo.\n        echo ========================================\n        echo Press any key to close...\n        echo ========================================\n        pause >nul\n        exit /b 0\n    )\n)\n\necho   Local:  %CURRENT_COMMIT%\necho   Remote: %REMOTE_COMMIT%\necho.\n\nREM Compare commits\nif \"%CURRENT_COMMIT%\"==\"%REMOTE_COMMIT%\" (\n    echo [4/4] Result: Already up to date!\n    echo   You have the latest version.\n    echo.\n    echo ========================================\n    echo Press any key to close...\n    echo ========================================\n    pause >nul\n    exit /b 0\n) else (\n    echo [4/4] Result: Update available!\n\n    REM Check if local is behind remote\n    \"!GIT_PATH!\" merge-base --is-ancestor HEAD origin/%CURRENT_BRANCH% 2>nul\n    if !ERRORLEVEL! EQU 0 (\n        echo   A new version is available on GitHub.\n        echo.\n\n        REM Show commits behind\n        echo   New commits:\n        \"!GIT_PATH!\" --no-pager log --oneline --graph --decorate HEAD..origin/%CURRENT_BRANCH% 2>nul\n        echo.\n\n        REM Ask if user wants to update\n        set /p UPDATE_CHOICE=\"Do you want to update now? (Y/N): \"\n        if /i \"!UPDATE_CHOICE!\"==\"Y\" (\n            echo.\n            echo Updating...\n\n            REM First, refresh the index to avoid false positives from line ending changes\n            \"!GIT_PATH!\" update-index --refresh >nul 2>&1\n\n            REM Check for uncommitted changes\n            \"!GIT_PATH!\" diff-index --quiet HEAD -- 2>nul\n            if !ERRORLEVEL! NEQ 0 (\n                echo.\n                echo [Info] Checking for potential conflicts...\n\n                REM Get list of locally modified files\n                set TEMP_LOCAL_CHANGES=%TEMP%\\acestep_local_changes_%RANDOM%.txt\n                \"!GIT_PATH!\" diff --name-only HEAD 2>nul > \"!TEMP_LOCAL_CHANGES!\"\n\n                REM Get list of files changed in remote\n                set TEMP_REMOTE_CHANGES=%TEMP%\\acestep_remote_changes_%RANDOM%.txt\n                \"!GIT_PATH!\" diff --name-only HEAD..origin/%CURRENT_BRANCH% 2>nul > \"!TEMP_REMOTE_CHANGES!\"\n\n                REM Check for conflicts\n                set HAS_CONFLICTS=0\n                REM Use wmic to get locale-independent date/time format (YYYYMMDDHHMMSS)\n                for /f \"tokens=2 delims==\" %%a in ('wmic os get localdatetime /value 2^>nul') do set \"DATETIME=%%a\"\n                set \"BACKUP_DIR=%~dp0.update_backup_!DATETIME:~0,8!_!DATETIME:~8,6!\"\n\n                REM Find conflicting files\n                for /f \"usebackq delims=\" %%a in (\"!TEMP_LOCAL_CHANGES!\") do (\n                    findstr /x /c:\"%%a\" \"!TEMP_REMOTE_CHANGES!\" >nul 2>&1\n                    if !ERRORLEVEL! EQU 0 (\n                        REM Found a conflict\n                        set HAS_CONFLICTS=1\n\n                        REM Create backup directory if not exists\n                        if not exist \"!BACKUP_DIR!\" (\n                            mkdir \"!BACKUP_DIR!\"\n                            echo.\n                            echo [Backup] Creating backup directory: !BACKUP_DIR!\n                        )\n\n                        REM Backup the file\n                        echo [Backup] Backing up: %%a\n                        set FILE_PATH=%%a\n                        set FILE_DIR=\n                        for %%i in (\"!FILE_PATH!\") do set FILE_DIR=%%~dpi\n\n                        REM Create subdirectories in backup if needed\n                        if not \"!FILE_DIR!\"==\"\" (\n                            if not \"!FILE_DIR!\"==\".\" (\n                                if not exist \"!BACKUP_DIR!\\!FILE_DIR!\" (\n                                    mkdir \"!BACKUP_DIR!\\!FILE_DIR!\" 2>nul\n                                )\n                            )\n                        )\n\n                        REM Copy file to backup\n                        copy \"%%a\" \"!BACKUP_DIR!\\%%a\" >nul 2>&1\n                    )\n                )\n\n                REM Clean up temp files\n                del \"!TEMP_LOCAL_CHANGES!\" >nul 2>&1\n                del \"!TEMP_REMOTE_CHANGES!\" >nul 2>&1\n\n                if !HAS_CONFLICTS! EQU 1 (\n                    echo.\n                    echo ========================================\n                    echo [Warning] Potential conflicts detected!\n                    echo ========================================\n                    echo.\n                    echo Your modified files may conflict with remote updates.\n                    echo Your changes have been backed up to:\n                    echo   !BACKUP_DIR!\n                    echo.\n                    echo Update will restore these files to the remote version.\n                    echo You can manually merge your changes later.\n                    echo.\n                    set /p CONFLICT_CHOICE=\"Continue with update? (Y/N): \"\n\n                    if /i \"!CONFLICT_CHOICE!\"==\"Y\" (\n                        echo.\n                        echo [Restore] Proceeding with update...\n                        echo [Restore] Files will be updated to remote version.\n                    ) else (\n                        echo.\n                        echo Update cancelled.\n                        echo Your backup remains at: !BACKUP_DIR!\n                        echo.\n                        echo ========================================\n                        echo Press any key to close...\n                        echo ========================================\n                        pause >nul\n                        exit /b 0\n                    )\n                ) else (\n                    echo.\n                    echo [Info] No conflicts detected. Safe to stash and update.\n                    echo.\n                    set /p STASH_CHOICE=\"Stash your changes and continue? (Y/N): \"\n                    if /i \"!STASH_CHOICE!\"==\"Y\" (\n                        echo Stashing changes...\n                        \"!GIT_PATH!\" stash push -m \"Auto-stash before update - %date% %time%\"\n                    ) else (\n                        echo.\n                        echo Update cancelled.\n                        echo.\n                        echo ========================================\n                        echo Press any key to close...\n                        echo ========================================\n                        pause >nul\n                        exit /b 0\n                    )\n                )\n            )\n\n            REM Check for untracked files that could be overwritten\n            set STASHED_UNTRACKED=0\n            set TEMP_UNTRACKED=%TEMP%\\acestep_untracked_%RANDOM%.txt\n            \"!GIT_PATH!\" ls-files --others --exclude-standard 2>nul > \"!TEMP_UNTRACKED!\"\n\n            REM Check if there are any untracked files\n            set HAS_UNTRACKED=0\n            for /f \"usebackq delims=\" %%u in (\"!TEMP_UNTRACKED!\") do set HAS_UNTRACKED=1\n\n            if !HAS_UNTRACKED! EQU 1 (\n                REM Get files added in remote\n                set TEMP_REMOTE_ADDED=%TEMP%\\acestep_remote_added_%RANDOM%.txt\n                \"!GIT_PATH!\" diff --name-only --diff-filter=A HEAD..origin/%CURRENT_BRANCH% 2>nul > \"!TEMP_REMOTE_ADDED!\"\n\n                set HAS_UNTRACKED_CONFLICTS=0\n                for /f \"usebackq delims=\" %%u in (\"!TEMP_UNTRACKED!\") do (\n                    findstr /x /c:\"%%u\" \"!TEMP_REMOTE_ADDED!\" >nul 2>&1\n                    if !ERRORLEVEL! EQU 0 (\n                        if !HAS_UNTRACKED_CONFLICTS! EQU 0 (\n                            echo.\n                            echo ========================================\n                            echo [Warning] Untracked files conflict with update!\n                            echo ========================================\n                            echo.\n                            echo The following untracked files would be overwritten:\n                        )\n                        set HAS_UNTRACKED_CONFLICTS=1\n                        echo   %%u\n                    )\n                )\n\n                del \"!TEMP_REMOTE_ADDED!\" >nul 2>&1\n\n                if !HAS_UNTRACKED_CONFLICTS! EQU 1 (\n                    echo.\n                    set /p STASH_UNTRACKED_CHOICE=\"Stash untracked files before updating? (Y/N): \"\n                    if /i \"!STASH_UNTRACKED_CHOICE!\"==\"Y\" (\n                        echo Stashing all changes including untracked files...\n                        \"!GIT_PATH!\" stash push --include-untracked -m \"pre-update-%RANDOM%\" >nul 2>&1\n                        if !ERRORLEVEL! EQU 0 (\n                            set STASHED_UNTRACKED=1\n                            echo [Stash] Changes stashed successfully.\n                        ) else (\n                            echo [Error] Failed to stash changes. Update aborted.\n                            del \"!TEMP_UNTRACKED!\" >nul 2>&1\n                            echo.\n                            echo ========================================\n                            echo Press any key to close...\n                            echo ========================================\n                            pause >nul\n                            exit /b 1\n                        )\n                    ) else (\n                        echo.\n                        echo Update cancelled. Please move or remove the conflicting files manually.\n                        del \"!TEMP_UNTRACKED!\" >nul 2>&1\n                        echo.\n                        echo ========================================\n                        echo Press any key to close...\n                        echo ========================================\n                        pause >nul\n                        exit /b 1\n                    )\n                    echo.\n                )\n            )\n\n            del \"!TEMP_UNTRACKED!\" >nul 2>&1\n\n            REM Pull changes\n            echo Pulling latest changes...\n            REM Force update by resetting to remote branch (discards any remaining local changes)\n            \"!GIT_PATH!\" reset --hard origin/%CURRENT_BRANCH% >nul 2>&1\n\n            if !ERRORLEVEL! EQU 0 (\n                echo.\n                echo ========================================\n                echo Update completed successfully!\n                echo ========================================\n                echo.\n\n                REM Check if backup was created\n                if defined BACKUP_DIR (\n                    if exist \"!BACKUP_DIR!\" (\n                        echo [Important] Your modified files were backed up to:\n                        echo   !BACKUP_DIR!\n                        echo.\n                        echo To restore your changes:\n                        echo   1. Run merge_config.bat to compare and merge files\n                        echo   2. Or manually compare backup with new version\n                        echo.\n                        echo Backed up files:\n                        set \"BACKUP_DIR_DISPLAY=!BACKUP_DIR!\"\n                        for /f \"delims=\" %%f in ('dir /b /s \"!BACKUP_DIR!\\*.*\" 2^>nul') do (\n                            set \"FILEPATH=%%f\"\n                            REM Use call to safely handle the string replacement\n                            call set \"FILEPATH=%%FILEPATH:!BACKUP_DIR_DISPLAY!\\=%%\"\n                            echo   - !FILEPATH!\n                        )\n                        echo.\n                    )\n                )\n\n                if !STASHED_UNTRACKED! EQU 1 (\n                    echo [Stash] Untracked files were stashed before the update.\n                    echo   To restore them:  git stash pop\n                    echo   To discard them:  git stash drop\n                    echo.\n                    echo   Note: 'git stash pop' may produce merge conflicts if\n                    echo   the update modified the same files. Resolve manually.\n                    echo.\n                )\n\n                echo Please restart the application to use the new version.\n                echo.\n                echo ========================================\n                echo Press any key to close...\n                echo ========================================\n                pause >nul\n                exit /b 0\n            ) else (\n                echo.\n                echo [Error] Update failed.\n                echo Please check the error messages above.\n\n                if !STASHED_UNTRACKED! EQU 1 (\n                    echo.\n                    echo [Stash] Restoring stashed changes...\n                    \"!GIT_PATH!\" stash pop >nul 2>&1\n                    if !ERRORLEVEL! EQU 0 (\n                        echo [Stash] Changes restored successfully.\n                    ) else (\n                        echo [Stash] Could not auto-restore. Run 'git stash pop' manually.\n                    )\n                )\n\n                REM If backup exists, mention it\n                if defined BACKUP_DIR (\n                    if exist \"!BACKUP_DIR!\" (\n                        echo.\n                        echo Your backup is still available at: !BACKUP_DIR!\n                    )\n                )\n\n                echo.\n                echo ========================================\n                echo Press any key to close...\n                echo ========================================\n                pause >nul\n                exit /b 1\n            )\n        ) else (\n            echo.\n            echo Update skipped.\n            echo.\n            echo ========================================\n            echo Press any key to close...\n            echo ========================================\n            pause >nul\n            exit /b 0\n        )\n    ) else (\n        echo   [Warning] Local version has diverged from remote.\n        echo   This might be because you have local commits.\n        echo   Please update manually or consult the documentation.\n        echo.\n        echo ========================================\n        echo Press any key to close...\n        echo ========================================\n        pause >nul\n        exit /b 0\n    )\n)\n\nREM ========================================\nREM Function: ConfigureProxy\nREM Configure proxy server for git\nREM ========================================\n:ConfigureProxy\necho.\necho ========================================\necho Proxy Server Configuration\necho ========================================\necho.\necho Please enter your proxy server URL.\necho.\necho Examples:\necho   - HTTP proxy:  http://127.0.0.1:7890\necho   - HTTPS proxy: https://proxy.example.com:8080\necho   - SOCKS5:      socks5://127.0.0.1:1080\necho.\necho Leave empty to disable proxy.\necho.\nset /p NEW_PROXY_URL=\"Proxy URL: \"\n\nif \"!NEW_PROXY_URL!\"==\"\" (\n    echo.\n    echo [Proxy] Disabling proxy...\n\n    REM Remove proxy configuration\n    \"!GIT_PATH!\" config --local --unset http.proxy 2>nul\n    \"!GIT_PATH!\" config --local --unset https.proxy 2>nul\n\n    REM Update config file\n    (\n        echo PROXY_ENABLED=0\n        echo PROXY_URL=\n    ) > \"%PROXY_CONFIG_FILE%\"\n\n    echo [Proxy] Proxy disabled.\n    exit /b 0\n) else (\n    echo.\n    echo [Proxy] Configuring proxy: !NEW_PROXY_URL!\n\n    REM Apply proxy to git\n    \"!GIT_PATH!\" config --local http.proxy \"!NEW_PROXY_URL!\"\n    \"!GIT_PATH!\" config --local https.proxy \"!NEW_PROXY_URL!\"\n\n    REM Save to config file\n    (\n        echo PROXY_ENABLED=1\n        echo PROXY_URL=!NEW_PROXY_URL!\n    ) > \"%PROXY_CONFIG_FILE%\"\n\n    echo [Proxy] Proxy configured successfully.\n    echo [Proxy] Configuration saved to: %PROXY_CONFIG_FILE%\n    exit /b 0\n)\n\nendlocal\n"
  },
  {
    "path": "check_update.sh",
    "content": "#!/usr/bin/env bash\n# Git Update Check Utility - Linux/macOS\n# This script checks for updates from GitHub and optionally updates the repository\n\nset -euo pipefail\nSCRIPT_DIR=\"$(cd \"$(dirname \"${BASH_SOURCE[0]}\")\" && pwd)\"\n\n# Configuration\nTIMEOUT_SECONDS=10\nGIT_PATH=\"\"\nREPO_PATH=\"$SCRIPT_DIR\"\n\necho \"========================================\"\necho \"ACE-Step Update Check\"\necho \"========================================\"\necho\n\n# Find git\nif command -v git &>/dev/null; then\n    GIT_PATH=\"$(command -v git)\"\n    echo \"[Git] Using system Git: $GIT_PATH\"\nelse\n    echo \"[Error] Git not found.\"\n    echo\n    if [[ \"$(uname)\" == \"Darwin\" ]]; then\n        echo \"Please install Git:\"\n        echo \"  xcode-select --install\"\n        echo \"  or: brew install git\"\n    else\n        echo \"Please install Git:\"\n        echo \"  Ubuntu/Debian: sudo apt install git\"\n        echo \"  CentOS/RHEL:   sudo yum install git\"\n        echo \"  Arch:          sudo pacman -S git\"\n    fi\n    echo\n    exit 1\nfi\necho\n\n# Check if this is a git repository\ncd \"$REPO_PATH\"\nif ! \"$GIT_PATH\" rev-parse --git-dir &>/dev/null; then\n    echo \"[Error] Not a git repository.\"\n    echo \"This folder does not appear to be a git repository.\"\n    echo\n    exit 1\nfi\n\necho \"[1/4] Checking current version...\"\nCURRENT_BRANCH=\"$(\"$GIT_PATH\" rev-parse --abbrev-ref HEAD 2>/dev/null || echo \"main\")\"\nCURRENT_COMMIT=\"$(\"$GIT_PATH\" rev-parse --short HEAD 2>/dev/null || echo \"unknown\")\"\n\necho \"  Branch: $CURRENT_BRANCH\"\necho \"  Commit: $CURRENT_COMMIT\"\necho\n\necho \"[2/4] Checking for updates (timeout: ${TIMEOUT_SECONDS}s)...\"\necho \"  Connecting to GitHub...\"\n\n# Fetch remote with timeout\nFETCH_SUCCESS=0\nif timeout \"$TIMEOUT_SECONDS\" \"$GIT_PATH\" fetch origin --quiet 2>/dev/null; then\n    FETCH_SUCCESS=1\nelif command -v gtimeout &>/dev/null; then\n    # macOS with coreutils installed via brew\n    if gtimeout \"$TIMEOUT_SECONDS\" \"$GIT_PATH\" fetch origin --quiet 2>/dev/null; then\n        FETCH_SUCCESS=1\n    fi\nelse\n    # Fallback: try without timeout (macOS without coreutils)\n    if \"$GIT_PATH\" fetch origin --quiet 2>/dev/null; then\n        FETCH_SUCCESS=1\n    fi\nfi\n\nif [[ $FETCH_SUCCESS -eq 0 ]]; then\n    echo \"  [Failed] Could not fetch from GitHub.\"\n    echo \"  Please check your internet connection.\"\n    echo\n    exit 2\nfi\n\necho \"  [Success] Fetched latest information from GitHub.\"\necho\n\necho \"[3/4] Comparing versions...\"\nREMOTE_COMMIT=\"$(\"$GIT_PATH\" rev-parse --short \"origin/$CURRENT_BRANCH\" 2>/dev/null || echo \"\")\"\n\nif [[ -z \"$REMOTE_COMMIT\" ]]; then\n    echo \"  [Warning] Remote branch 'origin/$CURRENT_BRANCH' not found.\"\n    echo\n    echo \"  Checking main branch instead...\"\n    FALLBACK_BRANCH=\"main\"\n    REMOTE_COMMIT=\"$(\"$GIT_PATH\" rev-parse --short \"origin/$FALLBACK_BRANCH\" 2>/dev/null || echo \"\")\"\n\n    if [[ -z \"$REMOTE_COMMIT\" ]]; then\n        echo \"  [Error] Could not find remote main branch either.\"\n        exit 1\n    fi\n\n    echo \"  Found main branch: $REMOTE_COMMIT\"\n    echo\n\n    read -rp \"  Switch to main branch? (Y/N): \" SWITCH_BRANCH\n    if [[ \"${SWITCH_BRANCH^^}\" == \"Y\" ]]; then\n        echo\n        echo \"  Switching to main branch...\"\n        if \"$GIT_PATH\" checkout main; then\n            echo \"  [Success] Switched to main branch.\"\n            echo \"  Please run this script again to check for updates.\"\n            exit 0\n        else\n            echo \"  [Error] Failed to switch branch.\"\n            exit 1\n        fi\n    else\n        echo\n        echo \"  Staying on branch '$CURRENT_BRANCH'. No update performed.\"\n        exit 0\n    fi\nfi\n\necho \"  Local:  $CURRENT_COMMIT\"\necho \"  Remote: $REMOTE_COMMIT\"\necho\n\n# Compare commits\nif [[ \"$CURRENT_COMMIT\" == \"$REMOTE_COMMIT\" ]]; then\n    echo \"[4/4] Result: Already up to date!\"\n    echo \"  You have the latest version.\"\n    echo\n    exit 0\nfi\n\necho \"[4/4] Result: Update available!\"\n\n# Check if local is behind remote\nif \"$GIT_PATH\" merge-base --is-ancestor HEAD \"origin/$CURRENT_BRANCH\" 2>/dev/null; then\n    echo \"  A new version is available on GitHub.\"\n    echo\n\n    # Show new commits\n    echo \"  New commits:\"\n    \"$GIT_PATH\" --no-pager log --oneline --graph --decorate \"HEAD..origin/$CURRENT_BRANCH\" 2>/dev/null\n    echo\n\n    read -rp \"Do you want to update now? (Y/N): \" UPDATE_CHOICE\n    if [[ \"${UPDATE_CHOICE^^}\" != \"Y\" ]]; then\n        echo\n        echo \"Update skipped.\"\n        exit 0\n    fi\n\n    echo\n    echo \"Updating...\"\n\n    # Refresh index\n    \"$GIT_PATH\" update-index --refresh &>/dev/null || true\n\n    # Check for uncommitted changes\n    if ! \"$GIT_PATH\" diff-index --quiet HEAD -- 2>/dev/null; then\n        echo\n        echo \"[Info] Checking for potential conflicts...\"\n\n        # Get locally modified files\n        LOCAL_CHANGES=\"$(\"$GIT_PATH\" diff --name-only HEAD 2>/dev/null || echo \"\")\"\n        REMOTE_CHANGES=\"$(\"$GIT_PATH\" diff --name-only \"HEAD..origin/$CURRENT_BRANCH\" 2>/dev/null || echo \"\")\"\n\n        # Check for conflicting files\n        HAS_CONFLICTS=0\n        BACKUP_DIR=\"$SCRIPT_DIR/.update_backup_$(date +%Y%m%d_%H%M%S)\"\n\n        while IFS= read -r local_file; do\n            [[ -z \"$local_file\" ]] && continue\n            if echo \"$REMOTE_CHANGES\" | grep -qxF \"$local_file\"; then\n                HAS_CONFLICTS=1\n\n                # Create backup directory if not exists\n                if [[ ! -d \"$BACKUP_DIR\" ]]; then\n                    mkdir -p \"$BACKUP_DIR\"\n                    echo\n                    echo \"[Backup] Creating backup directory: $BACKUP_DIR\"\n                fi\n\n                # Backup the file\n                echo \"[Backup] Backing up: $local_file\"\n                FILE_DIR=\"$(dirname \"$local_file\")\"\n                if [[ \"$FILE_DIR\" != \".\" ]]; then\n                    mkdir -p \"$BACKUP_DIR/$FILE_DIR\"\n                fi\n                cp \"$local_file\" \"$BACKUP_DIR/$local_file\" 2>/dev/null || true\n            fi\n        done <<< \"$LOCAL_CHANGES\"\n\n        if [[ $HAS_CONFLICTS -eq 1 ]]; then\n            echo\n            echo \"========================================\"\n            echo \"[Warning] Potential conflicts detected!\"\n            echo \"========================================\"\n            echo\n            echo \"Your modified files may conflict with remote updates.\"\n            echo \"Your changes have been backed up to:\"\n            echo \"  $BACKUP_DIR\"\n            echo\n\n            read -rp \"Continue with update? (Y/N): \" CONFLICT_CHOICE\n            if [[ \"${CONFLICT_CHOICE^^}\" != \"Y\" ]]; then\n                echo\n                echo \"Update cancelled. Your backup remains at: $BACKUP_DIR\"\n                exit 0\n            fi\n            echo\n            echo \"[Restore] Proceeding with update...\"\n        else\n            echo\n            echo \"[Info] No conflicts detected. Safe to stash and update.\"\n            echo\n\n            read -rp \"Stash your changes and continue? (Y/N): \" STASH_CHOICE\n            if [[ \"${STASH_CHOICE^^}\" == \"Y\" ]]; then\n                echo \"Stashing changes...\"\n                \"$GIT_PATH\" stash push -m \"Auto-stash before update - $(date)\"\n            else\n                echo\n                echo \"Update cancelled.\"\n                exit 0\n            fi\n        fi\n    fi\n\n    # Check for untracked files that could be overwritten\n    UNTRACKED_FILES=\"$(\"$GIT_PATH\" ls-files --others --exclude-standard 2>/dev/null || echo \"\")\"\n    STASHED_UNTRACKED=0\n\n    if [[ -n \"$UNTRACKED_FILES\" ]]; then\n        # Check if any untracked files conflict with incoming changes\n        REMOTE_ALL_FILES=\"$(\"$GIT_PATH\" diff --name-only --diff-filter=A \"HEAD..origin/$CURRENT_BRANCH\" 2>/dev/null || echo \"\")\"\n        CONFLICTING_UNTRACKED=\"\"\n\n        while IFS= read -r ufile; do\n            [[ -z \"$ufile\" ]] && continue\n            if echo \"$REMOTE_ALL_FILES\" | grep -qxF \"$ufile\"; then\n                CONFLICTING_UNTRACKED=\"${CONFLICTING_UNTRACKED}${ufile}\"$'\\n'\n            fi\n        done <<< \"$UNTRACKED_FILES\"\n\n        if [[ -n \"$CONFLICTING_UNTRACKED\" ]]; then\n            echo\n            echo \"========================================\"\n            echo \"[Warning] Untracked files conflict with update!\"\n            echo \"========================================\"\n            echo\n            echo \"The following untracked files would be overwritten:\"\n            echo \"$CONFLICTING_UNTRACKED\" | sed '/^$/d; s/^/  /'\n            echo\n\n            read -rp \"Stash untracked files before updating? (Y/N): \" STASH_UNTRACKED_CHOICE\n            if [[ \"${STASH_UNTRACKED_CHOICE^^}\" != \"Y\" ]]; then\n                echo\n                echo \"Update cancelled. Please move or remove the conflicting files manually.\"\n                exit 1\n            fi\n\n            echo \"Stashing all changes including untracked files...\"\n            if \"$GIT_PATH\" stash push --include-untracked -m \"pre-update-$(date +%s)\"; then\n                STASHED_UNTRACKED=1\n                echo \"[Stash] Changes stashed successfully.\"\n            else\n                echo \"[Error] Failed to stash changes. Update aborted.\"\n                exit 1\n            fi\n            echo\n        fi\n    fi\n\n    # Pull changes\n    echo \"Pulling latest changes...\"\n    if \"$GIT_PATH\" reset --hard \"origin/$CURRENT_BRANCH\" &>/dev/null; then\n        echo\n        echo \"========================================\"\n        echo \"Update completed successfully!\"\n        echo \"========================================\"\n        echo\n\n        if [[ -d \"${BACKUP_DIR:-}\" ]]; then\n            echo \"[Important] Your modified files were backed up to:\"\n            echo \"  $BACKUP_DIR\"\n            echo\n            echo \"To restore your changes:\"\n            echo \"  1. Run ./merge_config.sh to compare and merge files\"\n            echo \"  2. Or manually compare backup with new version\"\n            echo\n        fi\n\n        if [[ $STASHED_UNTRACKED -eq 1 ]]; then\n            echo \"[Stash] Untracked files were stashed before the update.\"\n            echo \"  To restore them:  git stash pop\"\n            echo \"  To discard them:  git stash drop\"\n            echo\n            echo \"  Note: 'git stash pop' may produce merge conflicts if\"\n            echo \"  the update modified the same files. Resolve manually.\"\n            echo\n        fi\n\n        echo \"Please restart the application to use the new version.\"\n        exit 0\n    else\n        echo\n        echo \"[Error] Update failed.\"\n        if [[ $STASHED_UNTRACKED -eq 1 ]]; then\n            echo \"[Stash] Restoring stashed changes...\"\n            if \"$GIT_PATH\" stash pop &>/dev/null; then\n                echo \"[Stash] Changes restored successfully.\"\n            else\n                echo \"[Stash] Could not auto-restore. Run 'git stash pop' manually.\"\n            fi\n        fi\n        if [[ -d \"${BACKUP_DIR:-}\" ]]; then\n            echo \"Your backup is still available at: $BACKUP_DIR\"\n        fi\n        exit 1\n    fi\nelse\n    echo \"  [Warning] Local version has diverged from remote.\"\n    echo \"  This might be because you have local commits.\"\n    echo \"  Please update manually or consult the documentation.\"\n    exit 0\nfi\n"
  },
  {
    "path": "cli.py",
    "content": "import argparse\nimport re\nimport ast\nimport os\nimport sys\nimport toml\nfrom pathlib import Path\nfrom typing import List, Optional, Tuple\n\n# Load environment variables from .env or .env.example (if available)\ntry:\n    from dotenv import load_dotenv\n    _current_file = os.path.abspath(__file__)\n    _project_root = os.path.dirname(_current_file)\n    _env_path = os.path.join(_project_root, '.env')\n    _env_example_path = os.path.join(_project_root, '.env.example')\n\n    if os.path.exists(_env_path):\n        load_dotenv(_env_path)\n        print(f\"Loaded configuration from {_env_path}\")\n    elif os.path.exists(_env_example_path):\n        load_dotenv(_env_example_path)\n        print(f\"Loaded configuration from {_env_example_path} (fallback)\")\nexcept ImportError:\n    pass\n\n# Clear proxy settings that may affect network behavior\nfor _proxy_var in ['http_proxy', 'https_proxy', 'HTTP_PROXY', 'HTTPS_PROXY', 'ALL_PROXY']:\n    os.environ.pop(_proxy_var, None)\n\ndef _configure_logging(\n    level: Optional[str] = None,\n    suppress_audio_tokens: Optional[bool] = None,\n) -> None:\n    try:\n        from loguru import logger\n    except Exception:\n        return\n\n    if suppress_audio_tokens is None:\n        suppress_audio_tokens = os.environ.get(\"ACE_STEP_SUPPRESS_AUDIO_TOKENS\", \"1\") not in {\"0\", \"false\", \"False\"}\n    if level is None:\n        level = \"INFO\"\n    level = str(level).upper()\n\n    def _log_filter(record) -> bool:\n        message = record.get(\"message\", \"\")\n        # Suppress duplicate DiT prompt logs (we print a single final prompt in cli.py)\n        if (\n            \"DiT TEXT ENCODER INPUT\" in message\n            or \"text_prompt:\" in message\n            or (message.strip() and set(message.strip()) == {\"=\"})\n        ):\n            return False\n        if not suppress_audio_tokens:\n            return True\n        return \"<|audio_code_\" not in message\n\n    logger.remove()\n    logger.add(sys.stderr, level=level, filter=_log_filter)\n\n\n_configure_logging()\n\nfrom acestep.handler import AceStepHandler\nfrom acestep.llm_inference import LLMHandler\nfrom acestep.inference import GenerationParams, GenerationConfig, generate_music, create_sample, format_sample\nfrom acestep.constants import DEFAULT_DIT_INSTRUCTION, TASK_INSTRUCTIONS\nfrom acestep.gpu_config import get_gpu_config, set_global_gpu_config, is_mps_platform\nimport torch\n\n\nTRACK_CHOICES = [\n    \"vocals\",\n    \"backing_vocals\",\n    \"drums\",\n    \"bass\",\n    \"guitar\",\n    \"keyboard\",\n    \"percussion\",\n    \"strings\",\n    \"synth\",\n    \"fx\",\n    \"brass\",\n    \"woodwinds\",\n]\n\n\ndef _get_project_root() -> str:\n    return os.path.dirname(os.path.abspath(__file__))\n\n\ndef _parse_description_hints(description: str) -> tuple[Optional[str], bool]:\n    import re\n\n    if not description:\n        return None, False\n\n    description_lower = description.lower().strip()\n\n    language_mapping = {\n        'english': 'en', 'en': 'en',\n        'chinese': 'zh', '中文': 'zh', 'zh': 'zh', 'mandarin': 'zh',\n        'japanese': 'ja', '日本語': 'ja', 'ja': 'ja',\n        'korean': 'ko', '한국어': 'ko', 'ko': 'ko',\n        'spanish': 'es', 'español': 'es', 'es': 'es',\n        'french': 'fr', 'français': 'fr', 'fr': 'fr',\n        'german': 'de', 'deutsch': 'de', 'de': 'de',\n        'italian': 'it', 'italiano': 'it', 'it': 'it',\n        'portuguese': 'pt', 'português': 'pt', 'pt': 'pt',\n        'russian': 'ru', 'русский': 'ru', 'ru': 'ru',\n        'bengali': 'bn', 'bn': 'bn',\n        'hindi': 'hi', 'hi': 'hi',\n        'arabic': 'ar', 'ar': 'ar',\n        'thai': 'th', 'th': 'th',\n        'vietnamese': 'vi', 'vi': 'vi',\n        'indonesian': 'id', 'id': 'id',\n        'turkish': 'tr', 'tr': 'tr',\n        'dutch': 'nl', 'nl': 'nl',\n        'polish': 'pl', 'pl': 'pl',\n    }\n\n    detected_language = None\n    for lang_name, lang_code in language_mapping.items():\n        if len(lang_name) <= 2:\n            pattern = r'(?:^|\\s|[.,;:!?])' + re.escape(lang_name) + r'(?:$|\\s|[.,;:!?])'\n        else:\n            pattern = r'\\b' + re.escape(lang_name) + r'\\b'\n        if re.search(pattern, description_lower):\n            detected_language = lang_code\n            break\n\n    is_instrumental = False\n    if 'instrumental' in description_lower:\n        is_instrumental = True\n    elif 'pure music' in description_lower or 'pure instrument' in description_lower:\n        is_instrumental = True\n    elif description_lower.endswith(' solo') or description_lower == 'solo':\n        is_instrumental = True\n\n    return detected_language, is_instrumental\n\n\ndef _prompt_non_empty(prompt: str) -> str:\n    value = input(prompt).strip()\n    while not value:\n        value = input(prompt).strip()\n    return value\n\n\ndef _prompt_with_default(prompt: str, default: Optional[str] = None, required: bool = False) -> str:\n    while True:\n        suffix = f\" [{default}]\" if default not in (None, \"\") else \"\"\n        value = input(f\"{prompt}{suffix}: \").strip()\n        if value:\n            return value\n        if default not in (None, \"\"):\n            return str(default)\n        if not required:\n            return \"\"\n        print(\"This value is required. Please try again.\")\n\n\ndef _prompt_bool(prompt: str, default: bool) -> bool:\n    default_str = \"y\" if default else \"n\"\n    while True:\n        value = input(f\"{prompt} (y/n) [default: {default_str}]: \").strip().lower()\n        if not value:\n            return default\n        if value in {\"y\", \"yes\", \"1\", \"true\"}:\n            return True\n        if value in {\"n\", \"no\", \"0\", \"false\"}:\n            return False\n        print(\"Please enter 'y' or 'n'.\")\n\n\ndef _prompt_choice_from_list(\n    prompt: str,\n    options: List[str],\n    default: Optional[str] = None,\n    allow_custom: bool = True,\n    custom_validator=None,\n    custom_error: Optional[str] = None,\n) -> Optional[str]:\n    if not options:\n        return default\n    print(\"\\n\" + prompt)\n    for idx, option in enumerate(options, start=1):\n        print(f\"{idx}. {option}\")\n    default_display = default if default not in (None, \"\") else \"auto\"\n    while True:\n        choice = input(f\"Choose a model (number or name) [default: {default_display}]: \").strip()\n        if not choice:\n            return None if default_display == \"auto\" else default\n        if choice.lower() == \"auto\":\n            return None\n        if choice.isdigit():\n            idx = int(choice)\n            if 1 <= idx <= len(options):\n                return options[idx - 1]\n            print(\"Invalid selection. Please choose a valid number.\")\n            continue\n        if allow_custom:\n            if custom_validator and not custom_validator(choice):\n                print(custom_error or \"Invalid selection. Please try again.\")\n                continue\n            if choice not in options:\n                print(\"Unknown model. Using as-is.\")\n            return choice\n        print(\"Please choose a valid option.\")\n\n\ndef _edit_formatted_prompt_via_file(formatted_prompt: str, instruction_path: str) -> str:\n    \"\"\"Write formatted prompt to file, wait for user edits, then read back.\"\"\"\n    try:\n        with open(instruction_path, \"w\", encoding=\"utf-8\") as f:\n            f.write(formatted_prompt)\n    except Exception as e:\n        print(f\"WARNING: Failed to write {instruction_path}: {e}\")\n        return formatted_prompt\n\n    print(\"\\n--- Final Draft Saved ---\")\n    print(f\"Saved to {instruction_path}\")\n    print(\"Edit the file now. Press Enter when ready to continue.\")\n    input()\n\n    try:\n        with open(instruction_path, \"r\", encoding=\"utf-8\") as f:\n            return f.read()\n    except Exception as e:\n        print(f\"WARNING: Failed to read {instruction_path}: {e}\")\n        return formatted_prompt\n\n\ndef _extract_caption_lyrics_from_formatted_prompt(formatted_prompt: str) -> Tuple[Optional[str], Optional[str]]:\n    \"\"\"Best-effort extraction of caption/lyrics from a formatted prompt string.\"\"\"\n    matches = list(re.finditer(r\"# Caption\\n(.*?)\\n+# Lyric\\n(.*)\", formatted_prompt, re.DOTALL))\n    if not matches:\n        return None, None\n\n    caption = matches[-1].group(1).strip()\n    lyrics = matches[-1].group(2)\n\n    # Trim lyrics if chat-template markers appear after the user message.\n    cut_markers = [\"<|eot_id|>\", \"<|start_header_id|>\", \"<|assistant|>\", \"<|user|>\", \"<|system|>\", \"<|im_end|>\", \"<|im_start|>\"]\n    cut_at = len(lyrics)\n    for marker in cut_markers:\n        pos = lyrics.find(marker)\n        if pos != -1:\n            cut_at = min(cut_at, pos)\n    lyrics = lyrics[:cut_at].rstrip()\n\n    return caption or None, lyrics or None\n\n\ndef _extract_instruction_from_formatted_prompt(formatted_prompt: str) -> Optional[str]:\n    \"\"\"Best-effort extraction of instruction text from a formatted prompt string.\"\"\"\n    match = re.search(r\"# Instruction\\n(.*?)\\n\\n\", formatted_prompt, re.DOTALL)\n    if not match:\n        return None\n    instruction = match.group(1).strip()\n    return instruction or None\n\n\ndef _extract_cot_metadata_from_formatted_prompt(formatted_prompt: str) -> dict:\n    \"\"\"Best-effort extraction of COT metadata from a formatted prompt string,\n    supporting multi-line values.\n    \"\"\"\n    matches = list(re.finditer(r\"<think>\\n(.*?)\\n</think>\", formatted_prompt, re.DOTALL))\n    if not matches:\n        return {}\n    block = matches[-1].group(1)\n    metadata = {}\n    current_key = None\n    current_value_lines = []\n\n    for line in block.splitlines():\n        line = line.strip()\n        if not line:\n            continue\n\n        key_match = re.match(r\"^(\\w+):\\s*(.*)\", line)\n        if key_match:\n            if current_key:\n                metadata[current_key] = \" \".join(current_value_lines).strip()\n\n            current_key = key_match.group(1).strip().lower()\n            current_value_lines = [key_match.group(2).strip()]\n        else:\n            if current_key:\n                current_value_lines.append(line)\n\n    if current_key and current_value_lines:\n        metadata[current_key] = \" \".join(current_value_lines).strip()\n\n    return metadata\n\n\ndef _parse_number(value: str) -> Optional[float]:\n    try:\n        match = re.search(r\"[-+]?\\d*\\.?\\d+\", value)\n        if not match:\n            return None\n        return float(match.group(0))\n    except Exception:\n        return None\n\n\ndef _parse_timesteps_input(value) -> Optional[List[float]]:\n    if value is None:\n        return None\n    if isinstance(value, list):\n        if all(isinstance(t, (int, float)) for t in value):\n            return [float(t) for t in value]\n        return None\n    if not isinstance(value, str):\n        return None\n    raw = value.strip()\n    if not raw:\n        return None\n    if raw.startswith(\"[\") or raw.startswith(\"(\"):\n        try:\n            parsed = ast.literal_eval(raw)\n        except Exception:\n            return None\n        if isinstance(parsed, list) and all(isinstance(t, (int, float)) for t in parsed):\n            return [float(t) for t in parsed]\n        return None\n    try:\n        return [float(t.strip()) for t in raw.split(\",\") if t.strip()]\n    except Exception:\n        return None\n\n\ndef _install_prompt_edit_hook(\n    llm_handler: LLMHandler,\n    instruction_path: str,\n    preloaded_prompt: Optional[str] = None,\n) -> None:\n    \"\"\"Intercept formatted prompt generation to allow user editing before audio tokens.\"\"\"\n    original = llm_handler.build_formatted_prompt_with_cot\n    cache = {}\n\n    def wrapped(caption, lyrics, cot_text, is_negative_prompt=False, negative_prompt=\"NO USER INPUT\"):\n        prompt = original(\n            caption,\n            lyrics,\n            cot_text,\n            is_negative_prompt=is_negative_prompt,\n            negative_prompt=negative_prompt,\n        )\n        if is_negative_prompt:\n            conditional_prompt = original(\n                caption,\n                lyrics,\n                cot_text,\n                is_negative_prompt=False,\n                negative_prompt=negative_prompt,\n            )\n            cached = cache.get(conditional_prompt)\n            if cached and (cached.get(\"edited_caption\") or cached.get(\"edited_lyrics\")):\n                edited_caption = cached.get(\"edited_caption\") or caption\n                edited_lyrics = cached.get(\"edited_lyrics\") or lyrics\n                return original(\n                    edited_caption,\n                    edited_lyrics,\n                    cot_text,\n                    is_negative_prompt=True,\n                    negative_prompt=negative_prompt,\n                )\n            return prompt\n        cached = cache.get(prompt)\n        if cached:\n            return cached[\"edited_prompt\"]\n        if getattr(llm_handler, \"_skip_prompt_edit\", False):\n            cache[prompt] = {\n                \"edited_prompt\": prompt,\n                \"edited_caption\": None,\n                \"edited_lyrics\": None,\n            }\n            return prompt\n        if preloaded_prompt is not None:\n            edited = preloaded_prompt\n        else:\n            edited = _edit_formatted_prompt_via_file(prompt, instruction_path)\n        edited_caption, edited_lyrics = _extract_caption_lyrics_from_formatted_prompt(edited)\n        if edited != prompt:\n            print(\"INFO: Using edited draft for audio-token prompt.\")\n            if edited_caption or edited_lyrics:\n                llm_handler._edited_caption = edited_caption\n                llm_handler._edited_lyrics = edited_lyrics\n            edited_instruction = _extract_instruction_from_formatted_prompt(edited)\n            if edited_instruction:\n                llm_handler._edited_instruction = edited_instruction\n            edited_metas = _extract_cot_metadata_from_formatted_prompt(edited)\n            if edited_metas:\n                llm_handler._edited_metas = edited_metas\n        cache[prompt] = {\n            \"edited_prompt\": edited,\n            \"edited_caption\": edited_caption,\n            \"edited_lyrics\": edited_lyrics,\n        }\n        return edited\n\n    llm_handler.build_formatted_prompt_with_cot = wrapped\n\n\ndef _prompt_int(prompt: str, default: Optional[int] = None, min_value: Optional[int] = None,\n                max_value: Optional[int] = None) -> Optional[int]:\n    default_display = \"auto\" if default is None else default\n    while True:\n        value = input(f\"{prompt} [{default_display}]: \").strip()\n        if not value:\n            return default\n        try:\n            parsed = int(value)\n        except ValueError:\n            print(\"Invalid input. Please enter an integer.\")\n            continue\n        if min_value is not None and parsed < min_value:\n            print(f\"Please enter a value >= {min_value}.\")\n            continue\n        if max_value is not None and parsed > max_value:\n            print(f\"Please enter a value <= {max_value}.\")\n            continue\n        return parsed\n\n\ndef _prompt_float(prompt: str, default: Optional[float] = None, min_value: Optional[float] = None,\n                  max_value: Optional[float] = None) -> Optional[float]:\n    default_display = \"auto\" if default is None else default\n    while True:\n        value = input(f\"{prompt} [{default_display}]: \").strip()\n        if not value:\n            return default\n        try:\n            parsed = float(value)\n        except ValueError:\n            print(\"Invalid input. Please enter a number.\")\n            continue\n        if min_value is not None and parsed < min_value:\n            print(f\"Please enter a value >= {min_value}.\")\n            continue\n        if max_value is not None and parsed > max_value:\n            print(f\"Please enter a value <= {max_value}.\")\n            continue\n        return parsed\n\n\ndef _prompt_existing_file(prompt: str, default: Optional[str] = None) -> str:\n    while True:\n        suffix = f\" [{default}]\" if default else \"\"\n        path = input(f\"{prompt}{suffix}: \").strip()\n        if not path and default:\n            path = default\n        if os.path.isfile(path):\n            return _expand_audio_path(path)\n        print(\"Invalid file path. Please try again.\")\n\n\ndef _expand_audio_path(path_str: Optional[str]) -> Optional[str]:\n    if not path_str or not isinstance(path_str, str):\n        return path_str\n    try:\n        return Path(path_str).expanduser().resolve(strict=False).as_posix()\n    except Exception:\n        return Path(path_str).expanduser().absolute().as_posix()\n\n\ndef _parse_bool(value: str) -> bool:\n    return str(value).lower() in {\"true\", \"1\", \"yes\", \"y\"}\n\n\ndef _resolve_device(device: str) -> str:\n    if device == \"auto\":\n        if hasattr(torch, 'xpu') and torch.xpu.is_available():\n            return \"xpu\"\n        if torch.cuda.is_available():\n            return \"cuda\"\n        if hasattr(torch.backends, \"mps\") and torch.backends.mps.is_available():\n            return \"mps\"\n        return \"cpu\"\n    return device\n\n\ndef _default_instruction_for_task(task_type: str, tracks: Optional[List[str]] = None) -> str:\n    if task_type == \"lego\":\n        track = tracks[0] if tracks else \"guitar\"\n        return TASK_INSTRUCTIONS[\"lego\"].format(TRACK_NAME=track.upper())\n    if task_type == \"extract\":\n        track = tracks[0] if tracks else \"vocals\"\n        return TASK_INSTRUCTIONS[\"extract\"].format(TRACK_NAME=track.upper())\n    if task_type == \"complete\":\n        tracks_list = \", \".join(tracks) if tracks else \"drums, bass, guitar\"\n        return TASK_INSTRUCTIONS[\"complete\"].format(TRACK_CLASSES=tracks_list)\n    return DEFAULT_DIT_INSTRUCTION\n\n\ndef _apply_optional_defaults(args, params_defaults: GenerationParams, config_defaults: GenerationConfig) -> None:\n    optional_defaults = {\n        \"duration\": params_defaults.duration,\n        \"bpm\": params_defaults.bpm,\n        \"keyscale\": params_defaults.keyscale,\n        \"timesignature\": params_defaults.timesignature,\n        \"vocal_language\": params_defaults.vocal_language,\n        \"inference_steps\": params_defaults.inference_steps,\n        \"seed\": params_defaults.seed,\n        \"guidance_scale\": params_defaults.guidance_scale,\n        \"use_adg\": params_defaults.use_adg,\n        \"cfg_interval_start\": params_defaults.cfg_interval_start,\n        \"cfg_interval_end\": params_defaults.cfg_interval_end,\n        \"shift\": 3.0,\n        \"infer_method\": params_defaults.infer_method,\n        \"timesteps\": None,\n        \"repainting_start\": params_defaults.repainting_start,\n        \"repainting_end\": params_defaults.repainting_end,\n        \"audio_cover_strength\": params_defaults.audio_cover_strength,\n        \"thinking\": params_defaults.thinking,\n        \"lm_temperature\": params_defaults.lm_temperature,\n        \"lm_cfg_scale\": params_defaults.lm_cfg_scale,\n        \"lm_top_k\": params_defaults.lm_top_k,\n        \"lm_top_p\": params_defaults.lm_top_p,\n        \"lm_negative_prompt\": params_defaults.lm_negative_prompt,\n        \"use_cot_metas\": params_defaults.use_cot_metas,\n        \"use_cot_caption\": params_defaults.use_cot_caption,\n        \"use_cot_lyrics\": params_defaults.use_cot_lyrics,\n        \"use_cot_language\": params_defaults.use_cot_language,\n        \"use_constrained_decoding\": params_defaults.use_constrained_decoding,\n        \"batch_size\": config_defaults.batch_size,\n        \"allow_lm_batch\": config_defaults.allow_lm_batch,\n        \"use_random_seed\": config_defaults.use_random_seed,\n        \"seeds\": config_defaults.seeds,\n        \"lm_batch_chunk_size\": config_defaults.lm_batch_chunk_size,\n        \"constrained_decoding_debug\": config_defaults.constrained_decoding_debug,\n        \"audio_format\": config_defaults.audio_format,\n        \"sample_mode\": False,\n        \"sample_query\": \"\",\n        \"use_format\": False,\n    }\n\n    for key, default_value in optional_defaults.items():\n        if getattr(args, key, None) is None:\n            setattr(args, key, default_value)\n\n\ndef _summarize_lyrics(lyrics: Optional[str]) -> str:\n    if not lyrics:\n        return \"none\"\n    if isinstance(lyrics, str):\n        stripped = lyrics.strip()\n        if not stripped:\n            return \"none\"\n        if os.path.isfile(stripped):\n            return f\"file: {os.path.basename(stripped)}\"\n        if len(stripped) <= 60:\n            return stripped.replace(\"\\n\", \" \")\n        return f\"text ({len(stripped)} chars)\"\n    return \"provided\"\n\n\ndef _print_final_parameters(\n    args,\n    params: GenerationParams,\n    config: GenerationConfig,\n    params_defaults: GenerationParams,\n    config_defaults: GenerationConfig,\n    compact: bool,\n    resolved_device: Optional[str] = None,\n) -> None:\n    if not compact:\n        print(\"\\n--- Final Parameters (Args) ---\")\n        for k in sorted(vars(args).keys()):\n            print(f\"{k}: {getattr(args, k)}\")\n        print(\"------------------------------\")\n        print(\"\\n--- Final Parameters (GenerationParams) ---\")\n        for k in sorted(vars(params).keys()):\n            print(f\"{k}: {getattr(params, k)}\")\n        print(\"-------------------------------------------\")\n        print(\"\\n--- Final Parameters (GenerationConfig) ---\")\n        for k in sorted(vars(config).keys()):\n            print(f\"{k}: {getattr(config, k)}\")\n        print(\"-------------------------------------------\\n\")\n        return\n\n    device_display = args.device\n    if resolved_device and resolved_device != args.device:\n        device_display = f\"{args.device} -> {resolved_device}\"\n\n    print(\"\\n--- Final Parameters (Summary) ---\")\n    print(f\"task_type: {params.task_type}\")\n    print(f\"caption: {params.caption or 'none'}\")\n    print(f\"lyrics: {_summarize_lyrics(params.lyrics)}\")\n    print(f\"duration: {params.duration}s\")\n    print(f\"outputs: {config.batch_size}\")\n    if params.bpm not in (None, params_defaults.bpm):\n        print(f\"bpm: {params.bpm}\")\n    if params.keyscale not in (None, params_defaults.keyscale):\n        print(f\"keyscale: {params.keyscale}\")\n    if params.timesignature not in (None, params_defaults.timesignature):\n        print(f\"timesignature: {params.timesignature}\")\n    print(f\"instrumental: {params.instrumental}\")\n    print(f\"thinking: {params.thinking}\")\n    print(f\"lm_model: {args.lm_model_path or 'auto'}\")\n    print(f\"dit_model: {args.config_path or 'auto'}\")\n    print(f\"backend: {args.backend}\")\n    print(f\"device: {device_display}\")\n    print(f\"audio_format: {config.audio_format}\")\n    print(f\"save_dir: {args.save_dir}\")\n    if config.seeds:\n        print(f\"seeds: {config.seeds}\")\n    else:\n        print(f\"seed: {params.seed} (random={config.use_random_seed})\")\n    print(\"-------------------------------\\n\")\n\n\ndef _build_meta_dict(params: GenerationParams) -> Optional[dict]:\n    meta = {}\n    if params.bpm is not None:\n        meta[\"bpm\"] = params.bpm\n    if params.timesignature:\n        meta[\"timesignature\"] = params.timesignature\n    if params.keyscale:\n        meta[\"keyscale\"] = params.keyscale\n    if params.duration is not None:\n        meta[\"duration\"] = params.duration\n    return meta or None\n\n\ndef _print_dit_prompt(dit_handler: \"AceStepHandler\", params: GenerationParams) -> None:\n    meta = _build_meta_dict(params)\n    caption_input, lyrics_input = dit_handler.build_dit_inputs(\n        task=params.task_type,\n        instruction=params.instruction,\n        caption=params.caption or \"\",\n        lyrics=params.lyrics or \"\",\n        metas=meta,\n        vocal_language=params.vocal_language or \"unknown\",\n    )\n    print(\"\\n--- Final DiT Prompt (Caption Branch) ---\")\n    print(caption_input)\n    print(\"\\n--- Final DiT Prompt (Lyrics Branch) ---\")\n    print(lyrics_input)\n    print(\"----------------------------------------\\n\")\n\n\ndef run_wizard(args, configure_only: bool = False, default_config_path: Optional[str] = None,\n               params_defaults: Optional[GenerationParams] = None,\n               config_defaults: Optional[GenerationConfig] = None):\n    \"\"\"\n    Runs an interactive wizard to set generation parameters.\n    \"\"\"\n    print(\"Welcome to the ACE-Step Music Generation Wizard!\")\n    print(\"This will guide you through creating your music.\")\n    print(\"Press Ctrl+C at any time to exit.\")\n    print(\"Note: Required models will be auto-downloaded if missing.\")\n    print(\"-\" * 30)\n\n    try:\n        # Task selection\n        print(\"\\n--- Task Type ---\")\n        print(\"1. text2music - generate music from text/lyrics.\")\n        print(\"2. cover     - transform existing audio into a new style.\")\n        print(\"3. repaint   - regenerate a specific time segment of audio.\")\n        print(\"4. lego      - generate a specific instrument track in context.\")\n        print(\"5. extract   - isolate a specific instrument track from a mix.\")\n        print(\"6. complete  - complete/extend partial tracks with new instruments.\")\n        task_map = {\n            \"1\": \"text2music\",\n            \"2\": \"cover\",\n            \"3\": \"repaint\",\n            \"4\": \"lego\",\n            \"5\": \"extract\",\n            \"6\": \"complete\",\n        }\n        current_task = args.task_type or \"text2music\"\n        task_default = next((k for k, v in task_map.items() if v == current_task), \"1\")\n        task_choice = input(f\"Choose a task (1-6) [default: {task_default}]: \").strip()\n        if not task_choice:\n            task_choice = task_default\n        args.task_type = task_map.get(task_choice, \"text2music\")\n        if args.task_type in {\"lego\", \"extract\", \"complete\"}:\n            print(\"Note: This task requires a base DiT model (acestep-v15-base). It will be auto-downloaded if missing.\")\n\n        # Model selection (DiT)\n        dit_handler = AceStepHandler()\n        available_dit_models = dit_handler.get_available_acestep_v15_models()\n        base_only = args.task_type in {\"lego\", \"extract\", \"complete\"}\n        if base_only and available_dit_models:\n            available_dit_models = [m for m in available_dit_models if \"base\" in m.lower()]\n\n        if base_only and args.config_path and \"base\" not in str(args.config_path).lower():\n            args.config_path = None\n\n        if base_only:\n            if available_dit_models:\n                if args.config_path in available_dit_models:\n                    selected = args.config_path\n                else:\n                    selected = available_dit_models[0]\n                args.config_path = selected\n                print(f\"\\nNote: This task requires a base model. Using: {selected}\")\n            else:\n                print(\"\\nNote: This task requires a base model (e.g., 'acestep-v15-base'). It will be auto-downloaded if missing.\")\n        elif available_dit_models:\n            selected = _prompt_choice_from_list(\n                \"--- Available DiT Models ---\",\n                available_dit_models,\n                default=args.config_path,\n                allow_custom=True,\n            )\n            if selected is not None:\n                args.config_path = selected\n        else:\n            print(\"\\nNote: No local DiT models found. The main model will be auto-downloaded during initialization.\")\n\n        # Model selection (LM)\n        llm_handler = LLMHandler()\n        available_lm_models = llm_handler.get_available_5hz_lm_models()\n        if available_lm_models:\n            selected_lm = _prompt_choice_from_list(\n                \"--- Available LM Models ---\",\n                available_lm_models,\n                default=args.lm_model_path,\n                allow_custom=True,\n            )\n            if selected_lm is not None:\n                args.lm_model_path = selected_lm\n        else:\n            print(\"\\nNote: No local LM models found. If LM features are enabled, a default LM will be auto-downloaded.\")\n\n        # Task-specific inputs\n        if args.task_type in {\"cover\", \"repaint\", \"lego\", \"extract\", \"complete\"}:\n            args.src_audio = _prompt_existing_file(\"Enter path to source audio file\", default=args.src_audio)\n\n        if args.task_type == \"repaint\":\n            args.repainting_start = _prompt_float(\n                \"Repaint start time in seconds\", args.repainting_start\n            )\n            args.repainting_end = _prompt_float(\n                \"Repaint end time in seconds\", args.repainting_end\n            )\n\n        if args.task_type in {\"lego\", \"extract\"}:\n            print(\"\\nAvailable tracks:\")\n            print(\", \".join(TRACK_CHOICES))\n            track_default = args.lego_track if args.task_type == \"lego\" else args.extract_track\n            track = _prompt_with_default(\"Choose a track\", track_default, required=True)\n            if track not in TRACK_CHOICES:\n                print(\"Unknown track. Using as-is.\")\n            if args.task_type == \"lego\":\n                args.lego_track = track\n            else:\n                args.extract_track = track\n            if not args.instruction or args.instruction == DEFAULT_DIT_INSTRUCTION:\n                args.instruction = _default_instruction_for_task(args.task_type, [track])\n            args.instruction = _prompt_with_default(\"Instruction\", args.instruction, required=True)\n\n        if args.task_type == \"complete\":\n            print(\"\\nAvailable tracks:\")\n            print(\", \".join(TRACK_CHOICES))\n            tracks_raw = _prompt_with_default(\"Choose tracks (comma-separated)\", args.complete_tracks, required=True)\n            tracks = [t.strip() for t in tracks_raw.split(\",\") if t.strip()]\n            args.complete_tracks = \",\".join(tracks)\n            if not args.instruction or args.instruction == DEFAULT_DIT_INSTRUCTION:\n                args.instruction = _default_instruction_for_task(args.task_type, tracks)\n            args.instruction = _prompt_with_default(\"Instruction\", args.instruction, required=True)\n\n        if args.task_type in {\"cover\", \"repaint\", \"lego\", \"complete\"}:\n            args.caption = _prompt_with_default(\n                \"Enter a music description (e.g., 'upbeat electronic dance music')\",\n                args.caption,\n                required=True,\n            )\n        elif args.task_type == \"text2music\":\n            args.sample_mode = _prompt_bool(\"Use Simple Mode (auto-generate caption/lyrics via LM)\", args.sample_mode)\n            if args.sample_mode:\n                args.sample_query = _prompt_with_default(\n                    \"Describe the music you want (for auto-generation)\",\n                    args.sample_query,\n                    required=False,\n                )\n            if not args.sample_mode:\n                caption = _prompt_with_default(\n                    \"Enter a music description (optional if you provide lyrics)\",\n                    args.caption,\n                    required=False,\n                )\n                if caption:\n                    args.caption = caption\n\n        # Lyrics\n        if args.task_type in {\"text2music\", \"cover\", \"repaint\", \"lego\", \"complete\"} and not args.sample_mode:\n            print(\"\\n--- Lyrics Options ---\")\n            print(\"1. Instrumental (no lyrics).\")\n            print(\"2. Generate lyrics automatically.\")\n            print(\"3. Provide path to a .txt file.\")\n            print(\"4. Paste lyrics directly.\")\n\n            if args.instrumental or args.lyrics == \"[Instrumental]\":\n                default_choice = \"1\"\n            elif args.use_cot_lyrics:\n                default_choice = \"2\"\n            elif args.lyrics and isinstance(args.lyrics, str) and os.path.isfile(args.lyrics):\n                default_choice = \"3\"\n            elif args.lyrics:\n                default_choice = \"4\"\n            else:\n                default_choice = \"1\"\n            choice = input(f\"Your choice (1-4) [default: {default_choice}]: \").strip()\n            if not choice:\n                choice = default_choice\n\n            if choice == \"1\":  # Instrumental\n                args.instrumental = True\n                args.lyrics = \"[Instrumental]\"\n                args.use_cot_lyrics = False\n                print(\"Instrumental music will be generated.\")\n            elif choice == \"2\":  # Generate lyrics automatically\n                args.use_cot_lyrics = True\n                args.lyrics = \"\"\n                args.instrumental = False\n                print(\"Lyrics will be generated automatically.\")\n            elif choice == \"3\":\n                args.instrumental = False\n                args.use_cot_lyrics = False\n                default_lyrics_path = args.lyrics if isinstance(args.lyrics, str) and os.path.isfile(args.lyrics) else None\n                while True:\n                    lyrics_path = _prompt_existing_file(\"Please enter the path to your .txt lyrics file\", default_lyrics_path)\n                    if lyrics_path.endswith('.txt'):\n                        args.lyrics = lyrics_path\n                        print(f\"Lyrics will be loaded from: {lyrics_path}\")\n                        break\n                    print(\"Invalid file path or not a .txt file. Please try again.\")\n            elif choice == \"4\":\n                args.instrumental = False\n                args.use_cot_lyrics = False\n                default_lyrics = args.lyrics if isinstance(args.lyrics, str) and args.lyrics and not os.path.isfile(args.lyrics) else None\n                args.lyrics = _prompt_with_default(\"Paste lyrics (single line or use \\\\n)\", default_lyrics, required=True)\n\n            if not args.instrumental:\n                lang = _prompt_with_default(\n                    \"Vocal language (e.g., 'en', 'zh', 'unknown')\",\n                    args.vocal_language,\n                    required=False\n                ).lower()\n                if lang:\n                    args.vocal_language = lang\n\n            if args.use_cot_lyrics:\n                if not args.caption:\n                    args.caption = _prompt_non_empty(\"Enter a music description for lyric generation: \")\n                if not args.thinking:\n                    print(\"INFO: Automatic lyric generation requires the LM handler. Enabling LM 'thinking'.\")\n                    args.thinking = True\n\n        args.batch_size = _prompt_int(\n            \"Number of outputs (audio clips) to generate\",\n            args.batch_size if args.batch_size is not None else 2,\n            min_value=1,\n        )\n\n        advanced = input(\"\\nConfigure advanced parameters? (y/n) [default: n]: \").lower()\n        if advanced == 'y':\n            if args.task_type == \"text2music\" and not args.sample_mode:\n                args.use_format = _prompt_bool(\"Use format_sample to enhance caption/lyrics\", args.use_format)\n            print(\"\\n--- Optional Metadata ---\")\n            args.duration = _prompt_float(\"Duration in seconds (10-600)\", args.duration, min_value=10, max_value=600)\n            args.bpm = _prompt_int(\"BPM (30-300, empty for auto)\", args.bpm, min_value=30, max_value=300)\n            args.keyscale = _prompt_with_default(\"Keyscale (e.g., 'C Major', empty for auto)\", args.keyscale)\n            args.timesignature = _prompt_with_default(\"Time signature (e.g., '4/4', empty for auto)\", args.timesignature)\n            args.vocal_language = _prompt_with_default(\"Vocal language (e.g., 'en', 'zh', 'unknown')\", args.vocal_language)\n\n            print(\"\\n--- Advanced DiT Settings ---\")\n            args.seed = _prompt_int(\"Random seed (-1 for random)\", args.seed)\n            args.inference_steps = _prompt_int(\"Inference steps\", args.inference_steps, min_value=1)\n            if args.config_path and 'base' in args.config_path:\n                args.guidance_scale = _prompt_float(\"Guidance scale (for base models)\", args.guidance_scale)\n                args.use_adg = _prompt_bool(\"Enable Adaptive Dual Guidance (ADG)\", args.use_adg)\n                args.cfg_interval_start = _prompt_float(\"CFG interval start (0.0-1.0)\", args.cfg_interval_start, 0.0, 1.0)\n                args.cfg_interval_end = _prompt_float(\"CFG interval end (0.0-1.0)\", args.cfg_interval_end, 0.0, 1.0)\n            args.shift = _prompt_float(\"Timestep shift (1.0-5.0)\", args.shift, 1.0, 5.0)\n            args.infer_method = _prompt_with_default(\"Inference method (ode/sde)\", args.infer_method)\n            timesteps_input = _prompt_with_default(\n                \"Custom timesteps list (e.g., [0.97, 0.5, 0])\",\n                args.timesteps,\n                required=False,\n            )\n            if timesteps_input:\n                args.timesteps = timesteps_input\n\n            if args.task_type == \"cover\":\n                args.audio_cover_strength = _prompt_float(\n                    \"Audio cover strength (0.0-1.0)\", args.audio_cover_strength, 0.0, 1.0\n                )\n\n            print(\"\\n--- Advanced LM Settings ---\")\n            args.thinking = _prompt_bool(\"Enable LM 'thinking'\", args.thinking)\n            args.lm_temperature = _prompt_float(\"LM temperature (0.0-2.0)\", args.lm_temperature, 0.0, 2.0)\n            args.lm_cfg_scale = _prompt_float(\"LM CFG scale\", args.lm_cfg_scale)\n            args.lm_top_k = _prompt_int(\"LM top-k (0 disables)\", args.lm_top_k, min_value=0)\n            args.lm_top_p = _prompt_float(\"LM top-p (0.0-1.0)\", args.lm_top_p, 0.0, 1.0)\n            args.lm_negative_prompt = _prompt_with_default(\"LM negative prompt\", args.lm_negative_prompt)\n            args.use_cot_metas = _prompt_bool(\"Use CoT for metadata\", args.use_cot_metas)\n            args.use_cot_caption = _prompt_bool(\"Use CoT for caption refinement\", args.use_cot_caption)\n            args.use_cot_lyrics = _prompt_bool(\"Use CoT for lyrics generation\", args.use_cot_lyrics)\n            args.use_cot_language = _prompt_bool(\"Use CoT for language detection\", args.use_cot_language)\n            args.use_constrained_decoding = _prompt_bool(\"Use constrained decoding\", args.use_constrained_decoding)\n\n            print(\"\\n--- Output Settings ---\")\n            args.save_dir = _prompt_with_default(\"Save directory\", args.save_dir)\n            args.audio_format = _prompt_with_default(\"Audio format (mp3/wav/flac)\", args.audio_format)\n            # Batch size already captured above.\n            args.use_random_seed = _prompt_bool(\"Use random seed per batch\", args.use_random_seed)\n            seeds_input = _prompt_with_default(\n                \"Custom seeds (comma/space separated, leave empty for random)\",\n                \"\",\n                required=False,\n            )\n            if seeds_input:\n                seeds = [s for s in seeds_input.replace(\",\", \" \").split() if s.strip()]\n                try:\n                    args.seeds = [int(s) for s in seeds]\n                except ValueError:\n                    print(\"Invalid seeds input. Ignoring custom seeds.\")\n            args.allow_lm_batch = _prompt_bool(\"Allow LM batch processing\", args.allow_lm_batch)\n            args.lm_batch_chunk_size = _prompt_int(\"LM batch chunk size\", args.lm_batch_chunk_size, min_value=1)\n            args.constrained_decoding_debug = _prompt_bool(\"Constrained decoding debug\", args.constrained_decoding_debug)\n        else:\n            if params_defaults and config_defaults:\n                _apply_optional_defaults(args, params_defaults, config_defaults)\n\n        # Ensure LM thinking is enabled when lyric generation is requested.\n        if args.use_cot_lyrics and not args.thinking:\n            print(\"INFO: Automatic lyric generation requires the LM handler. Enabling LM 'thinking'.\")\n            args.thinking = True\n\n        print(\"\\n--- Summary ---\")\n        print(f\"Task: {args.task_type}\")\n        if args.caption:\n            print(f\"Description: {args.caption}\")\n        if args.task_type in {\"lego\", \"extract\", \"complete\"}:\n            print(f\"Instruction: {args.instruction}\")\n        if args.src_audio:\n            print(f\"Source audio: {args.src_audio}\")\n        print(f\"Duration: {args.duration}s\")\n        print(f\"Outputs: {args.batch_size}\")\n        if args.instrumental:\n            print(\"Lyrics: Instrumental\")\n        elif args.use_cot_lyrics:\n            print(f\"Lyrics: Auto-generated ({args.vocal_language})\")\n        elif args.lyrics and os.path.isfile(args.lyrics):\n             print(f\"Lyrics: Provided from file ({args.lyrics})\")\n        elif args.lyrics:\n             print(f\"Lyrics: Provided as text\")\n\n        print(\"-\" * 30)\n        if not configure_only:\n            confirm = input(\"Start generation with these settings? (y/n) [default: y]: \").lower()\n            if confirm == 'n':\n                print(\"Generation cancelled.\")\n                sys.exit(0)\n\n        default_filename = default_config_path or \"config.toml\"\n        config_filename = input(f\"\\nEnter filename to save configuration [{default_filename}]: \")\n        if not config_filename:\n            config_filename = default_filename\n        if not config_filename.endswith(\".toml\"):\n            config_filename += \".toml\"\n\n        try:\n            config_to_save = {\n                k: v for k, v in vars(args).items()\n                if k not in ['config'] and not k.startswith('_')\n            }\n            with open(config_filename, 'w') as f:\n                toml.dump(config_to_save, f)\n            print(f\"Configuration saved to {config_filename}\")\n            print(f\"You can reuse it next time with: python cli.py -c {config_filename}\")\n        except Exception as e:\n            print(f\"Error saving configuration: {e}. Please try again.\")\n\n    except (KeyboardInterrupt, EOFError):\n        print(\"\\nWizard cancelled. Exiting.\")\n        sys.exit(0)\n\n    return args, not configure_only\n\n\ndef main():\n    \"\"\"\n    Main function to run ACE-Step music generation from the command line.\n    \"\"\"\n\n    gpu_config = get_gpu_config()\n    set_global_gpu_config(gpu_config)\n    mps_available = is_mps_platform()\n    # Mac (Apple Silicon) uses unified memory — offloading provides no benefit\n    auto_offload = (not mps_available) and gpu_config.gpu_memory_gb > 0 and gpu_config.gpu_memory_gb < 16\n    print(f\"\\n{'='*60}\")\n    print(\"GPU Configuration Detected:\")\n    print(f\"{'='*60}\")\n    print(f\"  GPU Memory: {gpu_config.gpu_memory_gb:.2f} GiB\")\n    print(f\"  Configuration Tier: {gpu_config.tier}\")\n    print(f\"  Max Duration (with LM): {gpu_config.max_duration_with_lm}s ({gpu_config.max_duration_with_lm // 60} min)\")\n    print(f\"  Max Duration (without LM): {gpu_config.max_duration_without_lm}s ({gpu_config.max_duration_without_lm // 60} min)\")\n    print(f\"  Max Batch Size (with LM): {gpu_config.max_batch_size_with_lm}\")\n    print(f\"  Max Batch Size (without LM): {gpu_config.max_batch_size_without_lm}\")\n    print(f\"  Default LM Init: {gpu_config.init_lm_default}\")\n    print(f\"  Available LM Models: {gpu_config.available_lm_models or 'None'}\")\n    print(f\"{'='*60}\\n\")\n\n    if auto_offload:\n        print(\"Auto-enabling CPU offload (GPU < 16GB)\")\n    elif gpu_config.gpu_memory_gb > 0:\n        print(\"CPU offload disabled by default (GPU >= 16GB)\")\n    elif mps_available:\n        print(\"MPS detected, running on Apple GPU\")\n    else:\n        print(\"No GPU detected, running on CPU\")\n\n    params_defaults = GenerationParams()\n    config_defaults = GenerationConfig()\n\n    parser = argparse.ArgumentParser(\n        description=\"ACE-Step 1.5: Music generation (wizard/config only).\",\n        formatter_class=argparse.ArgumentDefaultsHelpFormatter\n    )\n    parser.add_argument(\"-c\", \"--config\", type=str, help=\"Path to a TOML configuration file to load.\")\n    parser.add_argument(\"--configure\", action=\"store_true\", help=\"Run wizard to save configuration without generating.\")\n    parser.add_argument(\n        \"--backend\",\n        type=str,\n        default=None,\n        choices=[\"vllm\", \"pt\", \"mlx\"],\n        help=\"5Hz LM backend. Auto-detected if not specified: 'mlx' on Apple Silicon, 'vllm' on CUDA, 'pt' otherwise.\",\n    )\n    parser.add_argument(\n        \"--log-level\",\n        type=str,\n        default=\"INFO\",\n        help=\"Logging level for internal modules (TRACE/DEBUG/INFO/WARNING/ERROR/CRITICAL).\",\n    )\n    cli_args = parser.parse_args()\n\n    _configure_logging(level=cli_args.log_level)\n\n    default_batch_size = 1 if not cli_args.config else config_defaults.batch_size\n\n    # Auto-detect MLX on Apple Silicon, fall back to vllm\n    if mps_available:\n        try:\n            import mlx.core  # noqa: F401\n            default_backend = \"mlx\"\n            print(\"Apple Silicon detected with MLX available. Using MLX backend.\")\n        except ImportError:\n            default_backend = \"vllm\"\n    else:\n        default_backend = \"vllm\"\n\n    defaults = {\n        \"project_root\": _get_project_root(),\n        \"config_path\": None,\n        \"checkpoint_dir\": os.path.join(_get_project_root(), \"checkpoints\"),\n        \"lm_model_path\": None,\n        \"backend\": default_backend,\n        \"device\": \"auto\",\n        \"use_flash_attention\": None,\n        \"offload_to_cpu\": auto_offload,\n        \"offload_dit_to_cpu\": False,\n        \"save_dir\": \"output\",\n        \"audio_format\": config_defaults.audio_format,\n        \"caption\": \"\",\n        \"prompt\": \"\",\n        \"lyrics\": None,\n        \"duration\": params_defaults.duration,\n        \"instrumental\": False,\n        \"bpm\": params_defaults.bpm,\n        \"keyscale\": params_defaults.keyscale,\n        \"timesignature\": params_defaults.timesignature,\n        \"vocal_language\": params_defaults.vocal_language,\n        \"task_type\": params_defaults.task_type,\n        \"instruction\": params_defaults.instruction,\n        \"reference_audio\": params_defaults.reference_audio,\n        \"src_audio\": params_defaults.src_audio,\n        \"repainting_start\": params_defaults.repainting_start,\n        \"repainting_end\": params_defaults.repainting_end,\n        \"audio_cover_strength\": params_defaults.audio_cover_strength,\n        \"lego_track\": \"\",\n        \"extract_track\": \"\",\n        \"complete_tracks\": \"\",\n        \"sample_mode\": False,\n        \"sample_query\": \"\",\n        \"use_format\": False,\n        \"inference_steps\": params_defaults.inference_steps,\n        \"seed\": params_defaults.seed,\n        \"guidance_scale\": params_defaults.guidance_scale,\n        \"use_adg\": params_defaults.use_adg,\n        \"shift\": 3.0,\n        \"infer_method\": params_defaults.infer_method,\n        \"timesteps\": None,\n        \"thinking\": gpu_config.init_lm_default,\n        \"lm_temperature\": params_defaults.lm_temperature,\n        \"lm_cfg_scale\": params_defaults.lm_cfg_scale,\n        \"lm_top_k\": params_defaults.lm_top_k,\n        \"lm_top_p\": params_defaults.lm_top_p,\n        \"use_cot_metas\": params_defaults.use_cot_metas,\n        \"use_cot_caption\": params_defaults.use_cot_caption,\n        \"use_cot_lyrics\": params_defaults.use_cot_lyrics,\n        \"use_cot_language\": params_defaults.use_cot_language,\n        \"use_constrained_decoding\": params_defaults.use_constrained_decoding,\n        \"batch_size\": default_batch_size,\n        \"seeds\": None,\n        \"use_random_seed\": config_defaults.use_random_seed,\n        \"allow_lm_batch\": config_defaults.allow_lm_batch,\n        \"lm_batch_chunk_size\": config_defaults.lm_batch_chunk_size,\n        \"constrained_decoding_debug\": config_defaults.constrained_decoding_debug,\n        \"audio_codes\": \"\",\n        \"cfg_interval_start\": params_defaults.cfg_interval_start,\n        \"cfg_interval_end\": params_defaults.cfg_interval_end,\n        \"lm_negative_prompt\": params_defaults.lm_negative_prompt,\n        \"log_level\": cli_args.log_level,\n    }\n\n    args = argparse.Namespace(**defaults)\n    args.config = None\n    if cli_args.config:\n        if not os.path.exists(cli_args.config):\n            parser.error(f\"Config file not found: {cli_args.config}\")\n        try:\n            with open(cli_args.config, 'r') as f:\n                config_from_file = toml.load(f)\n            print(f\"Configuration loaded from {cli_args.config}\")\n        except Exception as e:\n            parser.error(f\"Error loading TOML config file {cli_args.config}: {e}\")\n        for key, value in config_from_file.items():\n            setattr(args, key, value)\n        args.config = cli_args.config\n\n    # CLI --backend overrides config file and auto-detection\n    if cli_args.backend is not None:\n        args.backend = cli_args.backend\n\n    if cli_args.configure:\n        args, _ = run_wizard(\n            args,\n            configure_only=True,\n            default_config_path=cli_args.config,\n            params_defaults=params_defaults,\n            config_defaults=config_defaults,\n        )\n        print(\"Configuration complete. Exiting without generation.\")\n        sys.exit(0)\n\n    if not cli_args.config:\n        args, should_generate = run_wizard(\n            args,\n            configure_only=False,\n            default_config_path=None,\n            params_defaults=params_defaults,\n            config_defaults=config_defaults,\n        )\n        if not should_generate:\n            print(\"Configuration complete. Exiting without generation.\")\n            sys.exit(0)\n\n    # --- Post-parsing Setup ---\n    if args.use_cot_lyrics and not args.thinking:\n        print(\"INFO: Automatic lyric generation requires the LM handler. Forcing --thinking=True.\")\n        args.thinking = True\n    \n    if not args.project_root:\n        args.project_root = _get_project_root()\n    else:\n        args.project_root = os.path.abspath(os.path.expanduser(str(args.project_root)))\n\n    if args.checkpoint_dir:\n        args.checkpoint_dir = os.path.expanduser(str(args.checkpoint_dir))\n        if not os.path.isabs(args.checkpoint_dir):\n            args.checkpoint_dir = os.path.join(args.project_root, args.checkpoint_dir)\n\n    if args.src_audio:\n        args.src_audio = _expand_audio_path(args.src_audio)\n    if args.reference_audio:\n        args.reference_audio = _expand_audio_path(args.reference_audio)\n\n    device = _resolve_device(args.device)\n\n    # --- Argument Post-processing ---\n    try:\n        timesteps = _parse_timesteps_input(args.timesteps)\n        if args.timesteps and timesteps is None:\n            raise ValueError(\"Timesteps must be a list of numbers or a comma-separated string.\")\n    except ValueError as e:\n        parser.error(f\"Invalid format for timesteps. Expected a list of numbers (e.g., '[1.0, 0.5, 0.0]' or '0.97,0.5,0'). Error: {e}\")\n\n    if args.seeds:\n        args.batch_size = len(args.seeds)\n        args.use_random_seed = False\n        args.seed = -1\n\n    if args.instrumental and not args.lyrics:\n        args.lyrics = \"[Instrumental]\"\n    elif isinstance(args.lyrics, str) and args.lyrics.strip().lower() in {\"[inst]\", \"[instrumental]\"}:\n        args.instrumental = True\n\n    # --- Task-specific validation and instruction helpers ---\n    if args.task_type in {\"cover\", \"repaint\", \"lego\", \"extract\", \"complete\"}:\n        if not args.src_audio:\n            parser.error(f\"--src_audio is required for task_type '{args.task_type}'.\")\n\n    if args.task_type in {\"cover\", \"repaint\", \"lego\", \"complete\"}:\n        if not args.caption:\n            parser.error(f\"--caption is required for task_type '{args.task_type}'.\")\n\n    if args.task_type == \"text2music\":\n        if not args.caption and not args.lyrics:\n            if not args.sample_mode and not args.sample_query:\n                parser.error(\"--caption or --lyrics is required for text2music.\")\n        if args.use_cot_lyrics and not args.caption:\n            parser.error(\"--use_cot_lyrics requires --caption for lyric generation.\")\n        if args.sample_mode or args.sample_query:\n            args.sample_mode = True\n    else:\n        if args.sample_mode or args.sample_query:\n            parser.error(\"--sample_mode/sample_query are only supported for task_type 'text2music'.\")\n\n    if args.sample_mode and args.use_cot_lyrics:\n        print(\"INFO: sample_mode enabled. Disabling --use_cot_lyrics.\")\n        args.use_cot_lyrics = False\n\n    # Auto-select instruction based on task_type if user didn't provide a custom instruction.\n    # Align with api_server behavior and TASK_INSTRUCTIONS defaults.\n    if args.instruction == DEFAULT_DIT_INSTRUCTION and args.task_type in TASK_INSTRUCTIONS:\n        if args.task_type in {\"text2music\", \"cover\", \"repaint\"}:\n            args.instruction = TASK_INSTRUCTIONS[args.task_type]\n\n    # Base-model-only task enforcement\n    base_only_tasks = {\"lego\", \"extract\", \"complete\"}\n    if args.task_type in base_only_tasks and args.config_path:\n        if \"base\" not in str(args.config_path).lower():\n            parser.error(f\"task_type '{args.task_type}' requires a base model config (e.g., 'acestep-v15-base').\")\n\n    if args.task_type == \"repaint\":\n        if args.repainting_end != -1 and args.repainting_end <= args.repainting_start:\n            parser.error(\"--repainting_end must be greater than --repainting_start (or -1).\")\n\n    if args.task_type in {\"lego\", \"extract\", \"complete\"}:\n        has_custom_instruction = bool(args.instruction and args.instruction.strip() and args.instruction.strip() != params_defaults.instruction)\n        if not has_custom_instruction:\n            if args.task_type == \"lego\":\n                if not args.lego_track:\n                    parser.error(\"--instruction or --lego_track is required for lego task.\")\n                args.instruction = _default_instruction_for_task(\"lego\", [args.lego_track.strip()])\n            elif args.task_type == \"extract\":\n                if not args.extract_track:\n                    parser.error(\"--instruction or --extract_track is required for extract task.\")\n                args.instruction = _default_instruction_for_task(\"extract\", [args.extract_track.strip()])\n            elif args.task_type == \"complete\":\n                if not args.complete_tracks:\n                    parser.error(\"--instruction or --complete_tracks is required for complete task.\")\n                tracks = [t.strip() for t in args.complete_tracks.split(\",\") if t.strip()]\n                if not tracks:\n                    parser.error(\"--complete_tracks must contain at least one track.\")\n                args.instruction = _default_instruction_for_task(\"complete\", tracks)\n    \n    # Handle lyrics argument\n    lyrics_arg = args.lyrics\n    if isinstance(lyrics_arg, str) and lyrics_arg:\n        lyrics_arg = os.path.expanduser(lyrics_arg)\n        if not os.path.isabs(lyrics_arg):\n            # Resolve relative lyrics path against config file location first, then project_root.\n            resolved = None\n            if args.config:\n                config_dir = os.path.dirname(os.path.abspath(args.config))\n                candidate = os.path.join(config_dir, lyrics_arg)\n                if os.path.isfile(candidate):\n                    resolved = candidate\n            if resolved is None and args.project_root:\n                candidate = os.path.join(os.path.abspath(args.project_root), lyrics_arg)\n                if os.path.isfile(candidate):\n                    resolved = candidate\n            if resolved is not None:\n                lyrics_arg = resolved\n\n    if lyrics_arg is not None:\n        if lyrics_arg == \"generate\":\n            args.use_cot_lyrics = True\n            args.lyrics = \"\"\n            print(\"Lyrics generation enabled.\")\n        elif os.path.isfile(lyrics_arg):\n            print(f\"INFO: Attempting to load lyrics from file: {lyrics_arg}\")\n            try:\n                with open(lyrics_arg, 'r', encoding='utf-8') as f:\n                    args.lyrics = f.read()\n                print(f\"Lyrics loaded from file: {lyrics_arg}\")\n            except Exception as e:\n                parser.error(f\"Could not read lyrics file {lyrics_arg}. Error: {e}\")\n        # else: lyrics is a string, use as is.\n\n    # --- Handler Initialization ---\n    if args.backend == \"pyTorch\":\n        args.backend = \"pt\"\n    if args.backend not in {\"vllm\", \"pt\", \"mlx\"}:\n        args.backend = \"vllm\"\n\n    print(\"Initializing ACE-Step handlers...\")\n    dit_handler = AceStepHandler()\n    llm_handler = LLMHandler()\n\n    base_only_tasks = {\"lego\", \"extract\", \"complete\"}\n    skip_lm_tasks = {\"cover\", \"repaint\"}\n    requires_lm = (\n        args.task_type not in skip_lm_tasks and (\n            args.thinking\n            or args.sample_mode\n            or bool(args.sample_query and str(args.sample_query).strip())\n            or args.use_format\n            or args.use_cot_metas\n            or args.use_cot_caption\n            or args.use_cot_lyrics\n            or args.use_cot_language\n        )\n    )\n\n    if args.config_path is None:\n        available_models = dit_handler.get_available_acestep_v15_models()\n        if args.task_type in base_only_tasks and available_models:\n            available_models = [m for m in available_models if \"base\" in m.lower()]\n        if not available_models:\n            print(\"No DiT models found. Downloading main model (acestep-v15-turbo + core components)...\")\n            from acestep.model_downloader import ensure_main_model, get_checkpoints_dir\n            checkpoints_dir = get_checkpoints_dir()\n            success, msg = ensure_main_model(checkpoints_dir)\n            print(msg)\n            if not success:\n                parser.error(f\"Failed to download main model: {msg}\")\n            available_models = dit_handler.get_available_acestep_v15_models()\n            if args.task_type in base_only_tasks and available_models:\n                available_models = [m for m in available_models if \"base\" in m.lower()]\n        if args.task_type in base_only_tasks and not available_models:\n            print(\"Base-only task selected. Downloading base DiT model (acestep-v15-base)...\")\n            from acestep.model_downloader import ensure_dit_model, get_checkpoints_dir\n            checkpoints_dir = get_checkpoints_dir()\n            success, msg = ensure_dit_model(\"acestep-v15-base\", checkpoints_dir)\n            print(msg)\n            if not success:\n                parser.error(f\"Failed to download base DiT model: {msg}\")\n            available_models = dit_handler.get_available_acestep_v15_models()\n            if available_models:\n                available_models = [m for m in available_models if \"base\" in m.lower()]\n        if available_models:\n            if args.task_type in {\"lego\", \"extract\", \"complete\"}:\n                preferred = \"acestep-v15-base\"\n            else:\n                preferred = \"acestep-v15-turbo\"\n            args.config_path = preferred if preferred in available_models else available_models[0]\n            print(f\"Auto-selected config_path: {args.config_path}\")\n        else:\n            parser.error(\"No available DiT models found. Please specify --config_path.\")\n    if args.task_type in {\"lego\", \"extract\", \"complete\"} and \"base\" not in str(args.config_path).lower():\n        parser.error(f\"task_type '{args.task_type}' requires a base model config (e.g., 'acestep-v15-base').\")\n\n    # Ensure required DiT/main models are present for the selected task/model.\n    from acestep.model_downloader import (\n        ensure_main_model,\n        ensure_dit_model,\n        get_checkpoints_dir,\n        check_main_model_exists,\n        check_model_exists,\n        SUBMODEL_REGISTRY,\n    )\n    checkpoints_dir = get_checkpoints_dir()\n    if not check_main_model_exists(checkpoints_dir):\n        print(\"Main model components not found. Downloading main model...\")\n        success, msg = ensure_main_model(checkpoints_dir)\n        print(msg)\n        if not success:\n            parser.error(f\"Failed to download main model: {msg}\")\n    if args.config_path:\n        config_name = str(args.config_path)\n        known_models = {\"acestep-v15-turbo\"} | set(SUBMODEL_REGISTRY.keys())\n        if check_model_exists(config_name, checkpoints_dir):\n            pass\n        elif config_name in known_models:\n            success, msg = ensure_dit_model(config_name, checkpoints_dir)\n            if not success:\n                parser.error(f\"Failed to download DiT model '{config_name}': {msg}\")\n        else:\n            print(f\"Warning: DiT model '{config_name}' not found locally and not in registry. Skipping auto-download.\")\n\n    use_flash_attention = args.use_flash_attention\n    if use_flash_attention is None:\n        use_flash_attention = dit_handler.is_flash_attention_available(device)\n\n    compile_model = os.environ.get(\"ACESTEP_COMPILE_MODEL\", \"\").strip().lower() in {\n        \"1\", \"true\", \"yes\", \"y\", \"on\",\n    }\n\n    print(f\"Initializing DiT handler with model: {args.config_path}\")\n    dit_handler.initialize_service(\n        project_root=args.project_root,\n        config_path=args.config_path,\n        device=device,\n        use_flash_attention=use_flash_attention,\n        compile_model=compile_model,\n        offload_to_cpu=args.offload_to_cpu,\n        offload_dit_to_cpu=args.offload_dit_to_cpu,\n    )\n\n    if requires_lm:\n        from acestep.model_downloader import ensure_lm_model\n        if args.lm_model_path is None:\n            available_lm_models = llm_handler.get_available_5hz_lm_models()\n            if available_lm_models:\n                args.lm_model_path = available_lm_models[0]\n                print(f\"Using default LM model: {args.lm_model_path}\")\n            else:\n                success, msg = ensure_lm_model(checkpoints_dir=checkpoints_dir)\n                print(msg)\n                if not success:\n                    parser.error(\"No LM models available. Please specify --lm_model_path or disable --thinking.\")\n                available_lm_models = llm_handler.get_available_5hz_lm_models()\n                if not available_lm_models:\n                    parser.error(\"No LM models available after download. Please specify --lm_model_path or disable --thinking.\")\n                args.lm_model_path = available_lm_models[0]\n                print(f\"Using default LM model: {args.lm_model_path}\")\n        else:\n            lm_model_path = str(args.lm_model_path)\n            if os.path.isabs(lm_model_path) and os.path.exists(lm_model_path):\n                pass\n            elif check_model_exists(lm_model_path, checkpoints_dir):\n                pass\n            elif lm_model_path in SUBMODEL_REGISTRY:\n                success, msg = ensure_lm_model(lm_model_path, checkpoints_dir=checkpoints_dir)\n                print(msg)\n                if not success:\n                    parser.error(f\"Failed to download LM model '{lm_model_path}': {msg}\")\n            else:\n                parser.error(f\"LM model '{lm_model_path}' not found locally and not in registry. Please provide a valid --lm_model_path.\")\n\n        print(f\"Initializing LM handler with model: {args.lm_model_path}\")\n        llm_handler.initialize(\n            checkpoint_dir=args.checkpoint_dir,\n            lm_model_path=args.lm_model_path,\n            backend=args.backend,\n            device=device,\n            offload_to_cpu=args.offload_to_cpu,\n            dtype=None,\n        )\n    else:\n        if args.task_type in skip_lm_tasks:\n            print(f\"LM is not required for task_type '{args.task_type}'. Skipping LM handler initialization.\")\n        else:\n            print(\"LM 'thinking' is disabled. Skipping LM handler initialization.\")\n\n    print(\"Handlers initialized.\")\n\n    format_has_duration = False\n\n    # --- Sample Mode / Description-based Auto-Generation ---\n    if args.sample_mode or (args.sample_query and str(args.sample_query).strip()):\n        if not llm_handler.llm_initialized:\n            parser.error(\"--sample_mode/sample_query requires the LM handler, but it's not initialized.\")\n\n        sample_query = args.sample_query if args.sample_query and str(args.sample_query).strip() else \"NO USER INPUT\"\n        parsed_language, parsed_instrumental = _parse_description_hints(sample_query)\n\n        if args.vocal_language and args.vocal_language not in (\"en\", \"unknown\", \"\"):\n            sample_language = args.vocal_language\n        else:\n            sample_language = parsed_language\n\n        print(\"\\nINFO: Creating sample via 'create_sample'...\")\n        sample_result = create_sample(\n            llm_handler=llm_handler,\n            query=sample_query,\n            instrumental=parsed_instrumental,\n            vocal_language=sample_language,\n            temperature=args.lm_temperature,\n            top_k=args.lm_top_k,\n            top_p=args.lm_top_p,\n        )\n\n        if sample_result.success:\n            args.caption = sample_result.caption\n            args.lyrics = sample_result.lyrics\n            args.instrumental = bool(sample_result.instrumental)\n            if args.bpm is None:\n                args.bpm = sample_result.bpm\n            if not args.keyscale:\n                args.keyscale = sample_result.keyscale\n            if not args.timesignature:\n                args.timesignature = sample_result.timesignature\n            if args.duration <= 0:\n                args.duration = sample_result.duration\n            if args.vocal_language in (\"unknown\", \"\", None):\n                args.vocal_language = sample_result.language\n            args.sample_mode = True\n            print(\"✓ Sample created. Using generated parameters.\")\n        else:\n            parser.error(f\"create_sample failed: {sample_result.error or sample_result.status_message}\")\n\n    # --- Format caption/lyrics if requested ---\n    if args.use_format and (args.caption or args.lyrics):\n        if not llm_handler.llm_initialized:\n            parser.error(\"--use_format requires the LM handler, but it's not initialized.\")\n\n        user_metadata_for_format = {}\n        if args.bpm is not None:\n            user_metadata_for_format[\"bpm\"] = args.bpm\n        if args.duration is not None and float(args.duration) > 0:\n            user_metadata_for_format[\"duration\"] = float(args.duration)\n        if args.keyscale:\n            user_metadata_for_format[\"keyscale\"] = args.keyscale\n        if args.timesignature:\n            user_metadata_for_format[\"timesignature\"] = args.timesignature\n        if args.vocal_language and args.vocal_language != \"unknown\":\n            user_metadata_for_format[\"language\"] = args.vocal_language\n\n        print(\"\\nINFO: Formatting caption/lyrics via 'format_sample'...\")\n        format_result = format_sample(\n            llm_handler=llm_handler,\n            caption=args.caption or \"\",\n            lyrics=args.lyrics or \"\",\n            user_metadata=user_metadata_for_format if user_metadata_for_format else None,\n            temperature=args.lm_temperature,\n            top_k=args.lm_top_k,\n            top_p=args.lm_top_p,\n        )\n\n        if format_result.success:\n            args.caption = format_result.caption or args.caption\n            args.lyrics = format_result.lyrics or args.lyrics\n            if format_result.duration:\n                args.duration = format_result.duration\n                format_has_duration = True\n            if format_result.bpm:\n                args.bpm = format_result.bpm\n            if format_result.keyscale:\n                args.keyscale = format_result.keyscale\n            if format_result.timesignature:\n                args.timesignature = format_result.timesignature\n            print(\"✓ Format complete.\")\n        else:\n            parser.error(f\"format_sample failed: {format_result.error or format_result.status_message}\")\n\n    # --- Auto-generate Lyrics if Requested ---\n    if args.use_cot_lyrics:\n        if not llm_handler.llm_initialized:\n             parser.error(\"--use_cot_lyrics requires the LM handler, but it's not initialized. Ensure --thinking is enabled.\")\n\n        print(\"\\nINFO: Generating lyrics and metadata via 'create_sample'...\")\n        sample_result = create_sample(\n            llm_handler=llm_handler,\n            query=args.caption,\n            instrumental=False,\n            vocal_language=args.vocal_language if args.vocal_language != 'unknown' else None,\n            temperature=args.lm_temperature,\n            top_k=args.lm_top_k,\n            top_p=args.lm_top_p,\n        )\n\n        if sample_result.success:\n            print(\"✓ Automatic sample creation successful. Using generated parameters:\")\n            # Update args with values from create_sample, respecting user-provided values\n            args.caption = sample_result.caption\n            args.lyrics = sample_result.lyrics\n            if args.bpm is None: args.bpm = sample_result.bpm\n            if not args.keyscale: args.keyscale = sample_result.keyscale\n            if not args.timesignature: args.timesignature = sample_result.timesignature\n            if args.duration <= 0: args.duration = sample_result.duration\n            if args.vocal_language == 'unknown': args.vocal_language = sample_result.language\n\n            print(f\"  - Caption: {args.caption}\")\n            lyrics_preview = args.lyrics[:150].strip().replace(\"\\n\", \" \")\n            print(f\"  - Lyrics: '{lyrics_preview}...'\")\n            print(f\"  - Metadata: BPM={args.bpm}, Key='{args.keyscale}', Lang='{args.vocal_language}'\")\n\n            # Disable subsequent CoT steps to avoid redundancy and save time\n            args.use_cot_metas = False\n            args.use_cot_caption = False\n        else:\n            print(f\"⚠️ WARNING: Automatic lyric generation via 'create_sample' failed: {sample_result.error}\")\n            print(\"         Proceeding with an instrumental track instead.\")\n            args.lyrics = \"[Instrumental]\"\n            args.instrumental = True\n\n        # Flag has served its purpose, disable it to avoid issues with GenerationParams\n        args.use_cot_lyrics = False\n\n    if args.sample_mode or format_has_duration:\n        args.use_cot_metas = False\n\n    # --- Prompt Editing Hook for LLM Audio Tokens ---\n    if args.thinking and args.task_type not in skip_lm_tasks:\n        instruction_path = os.path.join(\n            os.path.abspath(args.project_root) if args.project_root else os.getcwd(),\n            \"instruction.txt\",\n        )\n        preloaded_prompt = None\n        use_instruction_file = False\n        if args.config and os.path.exists(instruction_path):\n            use_instruction_file = True\n            try:\n                with open(instruction_path, \"r\", encoding=\"utf-8\") as f:\n                    preloaded_prompt = f.read()\n            except Exception as e:\n                print(f\"WARNING: Failed to read {instruction_path}: {e}\")\n                preloaded_prompt = None\n                use_instruction_file = False\n        if use_instruction_file:\n            print(f\"INFO: Found {instruction_path}. Using it without editing.\")\n        if preloaded_prompt is not None and not preloaded_prompt.strip():\n            preloaded_prompt = None\n        _install_prompt_edit_hook(llm_handler, instruction_path, preloaded_prompt=preloaded_prompt)\n\n    # --- Configure Generation ---\n    params = GenerationParams(\n        task_type=args.task_type,\n        instruction=args.instruction,\n        reference_audio=args.reference_audio,\n        src_audio=args.src_audio,\n        audio_codes=args.audio_codes,\n        caption=args.caption,\n        lyrics=args.lyrics,\n        instrumental=args.instrumental,\n        vocal_language=args.vocal_language,\n        bpm=args.bpm,\n        keyscale=args.keyscale,\n        timesignature=args.timesignature,\n        duration=args.duration,\n        inference_steps=args.inference_steps,\n        seed=args.seed,\n        guidance_scale=args.guidance_scale,\n        use_adg=args.use_adg,\n        cfg_interval_start=args.cfg_interval_start,\n        cfg_interval_end=args.cfg_interval_end,\n        shift=args.shift,\n        infer_method=args.infer_method,\n        timesteps=timesteps,\n        repainting_start=args.repainting_start,\n        repainting_end=args.repainting_end,\n        audio_cover_strength=args.audio_cover_strength,\n        thinking=args.thinking,\n        lm_temperature=args.lm_temperature,\n        lm_cfg_scale=args.lm_cfg_scale,\n        lm_top_k=args.lm_top_k,\n        lm_top_p=args.lm_top_p,\n        lm_negative_prompt=args.lm_negative_prompt,\n        use_cot_metas=args.use_cot_metas,\n        use_cot_caption=args.use_cot_caption,\n        use_cot_lyrics=args.use_cot_lyrics,\n        use_cot_language=args.use_cot_language,\n        use_constrained_decoding=args.use_constrained_decoding\n    )\n\n    config = GenerationConfig(\n        batch_size=args.batch_size,\n        allow_lm_batch=args.allow_lm_batch,\n        use_random_seed=args.use_random_seed,\n        seeds=args.seeds,\n        lm_batch_chunk_size=args.lm_batch_chunk_size,\n        constrained_decoding_debug=args.constrained_decoding_debug,\n        audio_format=args.audio_format\n    )\n\n    # --- Generate Music ---\n    log_level = getattr(args, \"log_level\", \"INFO\")\n    log_level_upper = str(log_level).upper()\n    compact_logs = log_level_upper != \"DEBUG\"\n    _print_final_parameters(\n        args,\n        params,\n        config,\n        params_defaults,\n        config_defaults,\n        compact=compact_logs,\n        resolved_device=device,\n    )\n\n    print(\"\\n--- Starting Generation ---\")\n    print(f\"Caption: \\\"{params.caption}\\\"\")\n    print(f\"Duration: {params.duration}s | Outputs: {config.batch_size}\")\n    if config.seeds:\n        print(f\"Custom Seeds: {config.seeds}\")\n    print(\"---------------------------\\n\")\n\n    manual_edit_pipeline = (\n        args.thinking\n        and args.task_type not in skip_lm_tasks\n        and not (params.audio_codes and str(params.audio_codes).strip())\n    )\n\n    lm_time_costs = None\n    if manual_edit_pipeline:\n        top_k_value = None if not params.lm_top_k or params.lm_top_k == 0 else int(params.lm_top_k)\n        top_p_value = None if not params.lm_top_p or params.lm_top_p >= 1.0 else params.lm_top_p\n\n        actual_batch_size = config.batch_size if config.batch_size is not None else 1\n        seed_for_generation = \"\"\n        if config.seeds is not None:\n            if isinstance(config.seeds, list) and len(config.seeds) > 0:\n                seed_for_generation = \",\".join(str(s) for s in config.seeds)\n            elif isinstance(config.seeds, int):\n                seed_for_generation = str(config.seeds)\n        actual_seed_list, _ = dit_handler.prepare_seeds(actual_batch_size, seed_for_generation, config.use_random_seed)\n\n        original_target_duration = params.duration\n        original_bpm = params.bpm\n        original_keyscale = params.keyscale\n        original_timesignature = params.timesignature\n        original_vocal_language = params.vocal_language\n        lm_result = None\n        lm_metadata = {}\n        edited_caption = None\n        edited_lyrics = None\n        edited_instruction = None\n        edited_metas = {}\n        lm_time_costs = {\n            \"phase1_time\": 0.0,\n            \"phase2_time\": 0.0,\n            \"total_time\": 0.0,\n        }\n        for attempt in range(2):\n            user_metadata = {}\n            if params.bpm is not None:\n                try:\n                    bpm_value = float(params.bpm)\n                    if bpm_value > 0:\n                        user_metadata[\"bpm\"] = int(bpm_value)\n                except (ValueError, TypeError):\n                    pass\n            if params.keyscale and params.keyscale.strip() and params.keyscale.strip().lower() not in [\"n/a\", \"\"]:\n                user_metadata[\"keyscale\"] = params.keyscale.strip()\n            if params.timesignature and params.timesignature.strip() and params.timesignature.strip().lower() not in [\"n/a\", \"\"]:\n                user_metadata[\"timesignature\"] = params.timesignature.strip()\n            if params.duration is not None:\n                try:\n                    duration_value = float(params.duration)\n                    if duration_value > 0:\n                        user_metadata[\"duration\"] = int(duration_value)\n                except (ValueError, TypeError):\n                    pass\n            # Only include caption and language in user_metadata on\n            # regeneration attempts.  On the first attempt the LM should\n            # generate/expand these via CoT (matching inference.py behaviour).\n            if attempt > 0:\n                if params.caption and params.caption.strip():\n                    user_metadata[\"caption\"] = params.caption.strip()\n                if params.vocal_language and params.vocal_language not in (\"\", \"unknown\"):\n                    user_metadata[\"language\"] = params.vocal_language\n            user_metadata_to_pass = user_metadata if user_metadata else None\n\n            lm_result = llm_handler.generate_with_stop_condition(\n                caption=params.caption or \"\",\n                lyrics=params.lyrics or \"\",\n                infer_type=\"llm_dit\",\n                temperature=params.lm_temperature,\n                cfg_scale=params.lm_cfg_scale,\n                negative_prompt=params.lm_negative_prompt,\n                top_k=top_k_value,\n                top_p=top_p_value,\n                target_duration=params.duration,\n                user_metadata=user_metadata_to_pass,\n                use_cot_caption=params.use_cot_caption,\n                use_cot_language=params.use_cot_language,\n                use_cot_metas=params.use_cot_metas,\n                use_constrained_decoding=params.use_constrained_decoding,\n                constrained_decoding_debug=config.constrained_decoding_debug,\n                batch_size=actual_batch_size,\n                seeds=actual_seed_list,\n            )\n            lm_extra_time = (lm_result.get(\"extra_outputs\") or {}).get(\"time_costs\", {})\n            if lm_extra_time:\n                lm_time_costs[\"phase1_time\"] += float(lm_extra_time.get(\"phase1_time\", 0.0) or 0.0)\n                lm_time_costs[\"phase2_time\"] += float(lm_extra_time.get(\"phase2_time\", 0.0) or 0.0)\n                lm_time_costs[\"total_time\"] += float(\n                    lm_extra_time.get(\n                        \"total_time\",\n                        (lm_extra_time.get(\"phase1_time\", 0.0) or 0.0)\n                        + (lm_extra_time.get(\"phase2_time\", 0.0) or 0.0),\n                    )\n                    or 0.0\n                )\n\n            if not lm_result.get(\"success\", False):\n                error_msg = lm_result.get(\"error\", \"Unknown LM error\")\n                print(f\"\\n❌ Generation failed: {error_msg}\")\n                print(f\"   Status: {lm_result.get('error', '')}\")\n                return\n\n            if actual_batch_size > 1:\n                lm_metadata = (lm_result.get(\"metadata\") or [{}])[0]\n                audio_codes = lm_result.get(\"audio_codes\", [])\n            else:\n                lm_metadata = lm_result.get(\"metadata\", {}) or {}\n                audio_codes = lm_result.get(\"audio_codes\", \"\")\n\n            if audio_codes:\n                params.audio_codes = audio_codes\n            else:\n                print(\"WARNING: LM did not return audio codes; proceeding without codes.\")\n\n            edited_caption = getattr(llm_handler, \"_edited_caption\", None)\n            edited_lyrics = getattr(llm_handler, \"_edited_lyrics\", None)\n            edited_instruction = getattr(llm_handler, \"_edited_instruction\", None)\n            edited_metas = getattr(llm_handler, \"_edited_metas\", {})\n\n            parsed_duration = None\n            parsed_bpm = None\n            parsed_keyscale = None\n            parsed_timesignature = None\n            parsed_language = None\n            if edited_metas:\n                bpm_value = edited_metas.get(\"bpm\")\n                if bpm_value:\n                    parsed = _parse_number(bpm_value)\n                    if parsed is not None and parsed > 0:\n                        parsed_bpm = int(parsed)\n                duration_value = edited_metas.get(\"duration\")\n                if duration_value:\n                    parsed = _parse_number(duration_value)\n                    if parsed is not None and parsed > 0:\n                        parsed_duration = float(parsed)\n                keyscale_value = edited_metas.get(\"keyscale\")\n                if keyscale_value:\n                    parsed_keyscale = keyscale_value\n                timesignature_value = edited_metas.get(\"timesignature\")\n                if timesignature_value:\n                    parsed_timesignature = timesignature_value\n                language_value = edited_metas.get(\"language\") or edited_metas.get(\"vocal_language\")\n                if language_value:\n                    parsed_language = language_value\n\n            if attempt == 0:\n                duration_changed = parsed_duration is not None and (\n                    original_target_duration is None\n                    or float(original_target_duration) <= 0\n                    or abs(float(original_target_duration) - parsed_duration) > 1e-6\n                )\n                bpm_changed = parsed_bpm is not None and parsed_bpm != original_bpm\n                keyscale_changed = parsed_keyscale is not None and parsed_keyscale != original_keyscale\n                timesignature_changed = parsed_timesignature is not None and parsed_timesignature != original_timesignature\n                language_changed = parsed_language is not None and parsed_language != original_vocal_language\n                if duration_changed or bpm_changed or keyscale_changed or timesignature_changed or language_changed:\n                    if duration_changed:\n                        params.duration = parsed_duration\n                    if bpm_changed:\n                        params.bpm = parsed_bpm\n                    if keyscale_changed:\n                        params.keyscale = parsed_keyscale\n                    if timesignature_changed:\n                        params.timesignature = parsed_timesignature\n                    if language_changed:\n                        params.vocal_language = parsed_language\n                    # Carry forward the expanded caption so the second\n                    # attempt's <think> block (and user_metadata) use it\n                    # instead of the short original caption.\n                    edited_caption_for_regen = edited_metas.get(\"caption\") if edited_metas else None\n                    if edited_caption_for_regen and edited_caption_for_regen.strip():\n                        params.caption = edited_caption_for_regen\n                    print(\"INFO: Edited metadata detected. Regenerating audio codes with updated values.\")\n                    llm_handler._skip_prompt_edit = True\n                    continue\n            break\n\n        edited_meta_caption = edited_metas.get(\"caption\") if edited_metas else None\n        if edited_meta_caption and edited_meta_caption.strip():\n            params.caption = edited_meta_caption\n        elif edited_caption:\n            params.caption = edited_caption\n        elif params.use_cot_caption and lm_metadata.get(\"caption\"):\n            params.caption = lm_metadata.get(\"caption\")\n\n        if edited_lyrics:\n            params.lyrics = edited_lyrics\n        elif not params.lyrics and lm_metadata.get(\"lyrics\"):\n            params.lyrics = lm_metadata.get(\"lyrics\")\n\n        if edited_instruction:\n            params.instruction = edited_instruction\n\n        if edited_metas:\n            bpm_value = edited_metas.get(\"bpm\")\n            if bpm_value:\n                parsed = _parse_number(bpm_value)\n                if parsed is not None:\n                    params.bpm = int(parsed)\n            duration_value = edited_metas.get(\"duration\")\n            if duration_value:\n                parsed = _parse_number(duration_value)\n                if parsed is not None:\n                    params.duration = float(parsed)\n            keyscale_value = edited_metas.get(\"keyscale\")\n            if keyscale_value:\n                params.keyscale = keyscale_value\n            timesignature_value = edited_metas.get(\"timesignature\")\n            if timesignature_value:\n                params.timesignature = timesignature_value\n            language_value = edited_metas.get(\"language\") or edited_metas.get(\"vocal_language\")\n            if language_value:\n                params.vocal_language = language_value\n        else:\n            if params.bpm is None and lm_metadata.get(\"bpm\") not in (None, \"N/A\", \"\"):\n                parsed = _parse_number(str(lm_metadata.get(\"bpm\")))\n                if parsed is not None:\n                    params.bpm = int(parsed)\n            if not params.keyscale and lm_metadata.get(\"keyscale\"):\n                params.keyscale = lm_metadata.get(\"keyscale\")\n            if not params.timesignature and lm_metadata.get(\"timesignature\"):\n                params.timesignature = lm_metadata.get(\"timesignature\")\n            if params.duration is None and lm_metadata.get(\"duration\") not in (None, \"N/A\", \"\"):\n                parsed = _parse_number(str(lm_metadata.get(\"duration\")))\n                if parsed is not None:\n                    params.duration = float(parsed)\n            if params.vocal_language in (None, \"\", \"unknown\"):\n                language_value = lm_metadata.get(\"vocal_language\") or lm_metadata.get(\"language\")\n                if language_value:\n                    params.vocal_language = language_value\n\n        # use_cot_language: override vocal_language with LM detection unless\n        # the user explicitly edited the language in the think block.\n        if params.use_cot_language:\n            edited_lang = (edited_metas.get(\"language\") or edited_metas.get(\"vocal_language\")) if edited_metas else None\n            if not edited_lang:\n                lm_lang = lm_metadata.get(\"vocal_language\") or lm_metadata.get(\"language\")\n                if lm_lang:\n                    params.vocal_language = lm_lang\n\n        # Populate cot_* fields for downstream reporting (mirrors inference.py)\n        if lm_metadata:\n            if original_bpm is None:\n                params.cot_bpm = params.bpm\n            if not original_keyscale:\n                params.cot_keyscale = params.keyscale\n            if not original_timesignature:\n                params.cot_timesignature = params.timesignature\n            if original_target_duration is None or float(original_target_duration) <= 0:\n                params.cot_duration = params.duration\n            if original_vocal_language in (None, \"\", \"unknown\"):\n                params.cot_vocal_language = params.vocal_language\n            if not params.caption:\n                params.cot_caption = lm_metadata.get(\"caption\", \"\")\n            if not params.lyrics:\n                params.cot_lyrics = lm_metadata.get(\"lyrics\", \"\")\n\n        params.thinking = False\n        params.use_cot_caption = False\n        params.use_cot_language = False\n        params.use_cot_metas = False\n        if hasattr(llm_handler, \"_skip_prompt_edit\"):\n            llm_handler._skip_prompt_edit = False\n\n        if log_level_upper in {\"INFO\", \"DEBUG\"}:\n            _print_dit_prompt(dit_handler, params)\n        print(\"Running DiT generation with edited prompt and cached audio codes...\")\n        result = generate_music(dit_handler, llm_handler, params, config, save_dir=args.save_dir)\n    else:\n        if log_level_upper in {\"INFO\", \"DEBUG\"}:\n            _print_dit_prompt(dit_handler, params)\n        result = generate_music(dit_handler, llm_handler, params, config, save_dir=args.save_dir)\n\n    # --- Process Results ---\n    if result.success:\n        print(f\"\\n✅ Generation successful! {len(result.audios)} audio(s) saved in '{args.save_dir}/'\")\n        for i, audio in enumerate(result.audios):\n            print(f\"  [{i+1}] Path: {audio['path']} | Seed: {audio['params']['seed']}\")\n        \n        time_costs = result.extra_outputs.get(\"time_costs\", {})\n        if manual_edit_pipeline and lm_time_costs and time_costs is not None:\n            if not isinstance(time_costs, dict):\n                time_costs = {}\n                result.extra_outputs[\"time_costs\"] = time_costs\n            if lm_time_costs[\"total_time\"] > 0.0:\n                time_costs[\"lm_phase1_time\"] = lm_time_costs[\"phase1_time\"]\n                time_costs[\"lm_phase2_time\"] = lm_time_costs[\"phase2_time\"]\n                time_costs[\"lm_total_time\"] = lm_time_costs[\"total_time\"]\n                dit_total = float(time_costs.get(\"dit_total_time_cost\", 0.0) or 0.0)\n                time_costs[\"pipeline_total_time\"] = time_costs[\"lm_total_time\"] + dit_total\n        if time_costs:\n            print(\"\\n--- Performance ---\")\n            total_time = time_costs.get('pipeline_total_time', 0)\n            print(f\"Total time: {total_time:.2f}s\")\n            if args.thinking:\n                lm1_time = time_costs.get('lm_phase1_time', 0)\n                lm2_time = time_costs.get('lm_phase2_time', 0)\n                print(f\"  - LM time: {lm1_time + lm2_time:.2f}s\")\n            dit_time = time_costs.get('dit_total_time_cost', 0)\n            print(f\"  - DiT time: {dit_time:.2f}s\")\n            print(\"-------------------\\n\")\n\n    else:\n        print(f\"\\n❌ Generation failed: {result.error}\")\n        print(f\"   Status: {result.status_message}\")\n\n\nif __name__ == \"__main__\":\n    main()\n"
  },
  {
    "path": "close_api_server.sh",
    "content": "#!/usr/bin/env bash\nset -euo pipefail\n\nusage() {\n\tcat <<'EOF'\nUsage:\n\t./close_api_server.sh [--port PORT] [--pid PID] [--force]\n\nDefaults:\n\tPORT: 8001\n\nBehavior:\n\t- If --pid is provided, stops that PID.\n\t- Otherwise, finds the listening PID(s) on --port and stops them.\n\t- By default, only stops processes whose cmdline contains \"uvicorn\" or \"acestep.api_server\".\n\t\tUse --force to skip this safety check.\nEOF\n}\n\nPORT=\"8002\"\nPID=\"\"\nFORCE=\"0\"\n\nwhile [[ $# -gt 0 ]]; do\n\tcase \"$1\" in\n\t\t--port)\n\t\t\tPORT=\"${2:-}\"; shift 2 ;;\n\t\t--pid)\n\t\t\tPID=\"${2:-}\"; shift 2 ;;\n\t\t--force)\n\t\t\tFORCE=\"1\"; shift ;;\n\t\t-h|--help)\n\t\t\tusage; exit 0 ;;\n\t\t*)\n\t\t\techo \"Unknown argument: $1\" >&2\n\t\t\tusage\n\t\t\texit 2\n\t\t\t;;\n\tesac\ndone\n\nif [[ -n \"$PORT\" ]] && ! [[ \"$PORT\" =~ ^[0-9]+$ ]]; then\n\techo \"Invalid --port: $PORT\" >&2\n\texit 2\nfi\nif [[ -n \"$PID\" ]] && ! [[ \"$PID\" =~ ^[0-9]+$ ]]; then\n\techo \"Invalid --pid: $PID\" >&2\n\texit 2\nfi\n\n_cmdline() {\n\tlocal pid=\"$1\"\n\tif [[ -r \"/proc/${pid}/cmdline\" ]]; then\n\t\ttr '\\0' ' ' < \"/proc/${pid}/cmdline\" | sed 's/[[:space:]]\\+/ /g' || true\n\telse\n\t\techo \"\"\n\tfi\n}\n\n_is_target_process() {\n\tlocal pid=\"$1\"\n\tlocal cmd\n\tcmd=\"$(_cmdline \"$pid\")\"\n\t[[ \"$cmd\" == *\"uvicorn\"* || \"$cmd\" == *\"acestep.api_server\"* ]]\n}\n\n_find_pids_by_port() {\n\tlocal port=\"$1\"\n\tlocal pids=\"\"\n\n\tif command -v lsof >/dev/null 2>&1; then\n\t\tpids=\"$(lsof -nP -t -iTCP:\"$port\" -sTCP:LISTEN 2>/dev/null | tr '\\n' ' ' || true)\"\n\telif command -v ss >/dev/null 2>&1; then\n\t\t# 输出示例：LISTEN 0 4096 127.0.0.1:8001 ... users:(\"python\",pid=12345,fd=3)\n\t\tpids=\"$(ss -lptn \"sport = :$port\" 2>/dev/null | sed -n 's/.*pid=\\([0-9]\\+\\).*/\\1/p' | sort -u | tr '\\n' ' ' || true)\"\n\telif command -v netstat >/dev/null 2>&1; then\n\t\t# 输出示例：tcp ... LISTEN 12345/python\n\t\tpids=\"$(netstat -lntp 2>/dev/null | awk -v p=\":${port}\" '$4 ~ p && $6==\"LISTEN\" {split($7,a,\"/\"); if (a[1] ~ /^[0-9]+$/) print a[1]}' | sort -u | tr '\\n' ' ' || true)\"\n\telif command -v fuser >/dev/null 2>&1; then\n\t\tpids=\"$(fuser -n tcp \"$port\" 2>/dev/null | tr '\\n' ' ' || true)\"\n\tfi\n\n\techo \"$pids\"\n}\n\n_stop_pid() {\n\tlocal pid=\"$1\"\n\n\tif ! kill -0 \"$pid\" 2>/dev/null; then\n\t\techo \"PID $pid not running.\"\n\t\treturn 0\n\tfi\n\n\tif [[ \"$FORCE\" != \"1\" ]] && ! _is_target_process \"$pid\"; then\n\t\techo \"Skip PID $pid (cmdline does not look like uvicorn/acestep.api_server). Use --force to stop anyway.\" >&2\n\t\techo \"cmdline: $(_cmdline \"$pid\")\" >&2\n\t\treturn 3\n\tfi\n\n\techo \"Stopping PID $pid...\"\n\tkill -TERM \"$pid\" 2>/dev/null || true\n\n\tfor _ in $(seq 1 30); do\n\t\tif ! kill -0 \"$pid\" 2>/dev/null; then\n\t\t\techo \"Stopped PID $pid.\"\n\t\t\treturn 0\n\t\tfi\n\t\tsleep 0.2\n\tdone\n\n\techo \"PID $pid did not exit; sending SIGKILL...\" >&2\n\tkill -KILL \"$pid\" 2>/dev/null || true\n\tsleep 0.1\n\tif kill -0 \"$pid\" 2>/dev/null; then\n\t\techo \"Failed to kill PID $pid.\" >&2\n\t\treturn 1\n\tfi\n\techo \"Killed PID $pid.\"\n\treturn 0\n}\n\nif [[ -n \"$PID\" ]]; then\n\t_stop_pid \"$PID\"\n\texit $?\nfi\n\npids=\"$(_find_pids_by_port \"$PORT\")\"\nif [[ -z \"${pids// }\" ]]; then\n\techo \"No listening process found on port $PORT.\"\n\texit 0\nfi\n\nrc=0\nfor pid in $pids; do\n\tif [[ -n \"$pid\" ]]; then\n\t\t_stop_pid \"$pid\" || rc=$?\n\tfi\ndone\n\nexit \"$rc\"\n"
  },
  {
    "path": "docker-compose.jetson.yml",
    "content": "# =============================================================================\n# ACE-Step 1.5 — Docker Compose for NVIDIA Jetson\n# =============================================================================\n#\n# Prerequisites:\n#   - JetPack 6.x (L4T R36.x) with NVIDIA Container Runtime\n#   - Docker Compose v2 (docker compose) or v1 (docker-compose)\n#\n# Usage:\n#   # Start Gradio UI (default):\n#   docker compose -f docker-compose.jetson.yml up\n#\n#   # Start REST API server instead:\n#   ACESTEP_MODE=api docker compose -f docker-compose.jetson.yml up\n#\n#   # Build and start:\n#   docker compose -f docker-compose.jetson.yml up --build\n#\n#   # Run in background:\n#   docker compose -f docker-compose.jetson.yml up -d\n#\n#   # Stop:\n#   docker compose -f docker-compose.jetson.yml down\n#\n#   # View logs:\n#   docker compose -f docker-compose.jetson.yml logs -f\n#\n#   # Override JetPack version at build time:\n#   L4T_VERSION=r36.3.0 docker compose -f docker-compose.jetson.yml up --build\n#\n# =============================================================================\n\nservices:\n  acestep:\n    build:\n      context: .\n      dockerfile: Dockerfile.jetson\n      args:\n        L4T_VERSION: ${L4T_VERSION:-r36.4.0}\n    image: acestep-jetson:latest\n    container_name: acestep-jetson\n\n    # ---- GPU access ----\n    runtime: nvidia\n\n    # ---- Mode: \"gradio\" (web UI) or \"api\" (REST API) ----\n    # Override from shell:  ACESTEP_MODE=api docker compose ... up\n    env_file:\n      - path: .env\n        required: false\n    environment:\n      - NVIDIA_VISIBLE_DEVICES=all\n      - ACESTEP_MODE=${ACESTEP_MODE:-gradio}\n      # vllm with 4B LM = best quality (README recommendation for ≥24GB).\n      # CUDA graph capture is auto-disabled on Jetson (enforce_eager).\n      - ACESTEP_LLM_BACKEND=${ACESTEP_LLM_BACKEND:-vllm}\n      - ACESTEP_INIT_SERVICE=${ACESTEP_INIT_SERVICE:-true}\n      - ACESTEP_CONFIG_PATH=${ACESTEP_CONFIG_PATH:-acestep-v15-turbo}\n      - ACESTEP_LM_MODEL_PATH=${ACESTEP_LM_MODEL_PATH:-acestep-5Hz-lm-4B}\n      - ACESTEP_EXTRA_ARGS=${ACESTEP_EXTRA_ARGS:-}\n      - TOKENIZERS_PARALLELISM=false\n\n    # ---- Ports ----\n    # Gradio UI on 7860, REST API on 8001\n    ports:\n      - \"${GRADIO_PORT:-7860}:7860\"\n      - \"${API_PORT:-8001}:8001\"\n\n    # ---- Persistent volumes ----\n    volumes:\n      # Model checkpoints — bind mount so models are visible on the host,\n      # can be shared across containers, and survive image rebuilds.\n      - ./checkpoints:/app/checkpoints\n      # HuggingFace cache — avoids re-downloading models if the checkpoint\n      # directory is empty and the downloader fetches from HF Hub.\n      - hf_cache:/root/.cache/huggingface\n      # Generated audio output\n      - ./gradio_outputs:/app/gradio_outputs\n      # LoRA training output — persists trained adapters across rebuilds\n      - ./lora_output:/app/lora_output\n      # ACE-Step generation output\n      - ./acestep_output:/app/acestep_output\n\n    # ---- Resource management ----\n    # Shared memory — needed for PyTorch DataLoader workers\n    shm_size: \"2gb\"\n\n    # ---- Restart policy ----\n    restart: unless-stopped\n\n    # ---- Health check ----\n    # Inherited from Dockerfile; compose-level override for faster feedback\n    healthcheck:\n      test: >-\n        curl -sf http://localhost:7860/ > /dev/null 2>&1 ||\n        curl -sf http://localhost:8001/health > /dev/null 2>&1 ||\n        exit 1\n      interval: 30s\n      timeout: 10s\n      start_period: 300s\n      retries: 3\n\nvolumes:\n  # HuggingFace download cache — persists across container rebuilds so models\n  # don't need to be re-downloaded from the Hub.\n  hf_cache:\n"
  },
  {
    "path": "docs/.vitepress/config.mts",
    "content": "import { defineConfig } from 'vitepress'\n\nexport default defineConfig({\n  title: 'ACE-Step 1.5',\n  description: 'Open-Source Music Generation Foundation Model',\n\n  base: '/ACE-Step-1.5/',\n  lastUpdated: true,\n  cleanUrls: true,\n  ignoreDeadLinks: [\n    /localhost/,\n    /\\.\\.\\/\\.\\.\\/README/,\n    // Missing translations\n    /\\.\\/BENCHMARK/,\n    // Links from awesome-ace-step README (external repo)\n    /\\.\\/CONTRIBUTING/,\n  ],\n\n  head: [\n    ['link', { rel: 'icon', type: 'image/svg+xml', href: '/ACE-Step-1.5/favicon.svg' }],\n    ['meta', { name: 'og:type', content: 'website' }],\n    ['meta', { name: 'og:title', content: 'ACE-Step 1.5 Documentation' }],\n    ['meta', { name: 'og:description', content: 'Open-Source Music Generation Foundation Model' }],\n  ],\n\n  locales: {\n    en: {\n      label: 'English',\n      lang: 'en',\n      link: '/en/',\n      themeConfig: {\n        nav: navEN(),\n        sidebar: sidebarEN(),\n      },\n    },\n    zh: {\n      label: '中文',\n      lang: 'zh-CN',\n      link: '/zh/',\n      themeConfig: {\n        nav: navZH(),\n        sidebar: sidebarZH(),\n        outline: { label: '页面导航' },\n        lastUpdated: { text: '最后更新于' },\n        docFooter: { prev: '上一页', next: '下一页' },\n        editLink: { pattern: 'https://github.com/ace-step/ACE-Step-1.5/edit/main/docs/:path', text: '在 GitHub 上编辑此页面' },\n      },\n    },\n    ja: {\n      label: '日本語',\n      lang: 'ja',\n      link: '/ja/',\n      themeConfig: {\n        nav: navJA(),\n        sidebar: sidebarJA(),\n        outline: { label: 'ページナビ' },\n        lastUpdated: { text: '最終更新' },\n        docFooter: { prev: '前へ', next: '次へ' },\n        editLink: { pattern: 'https://github.com/ace-step/ACE-Step-1.5/edit/main/docs/:path', text: 'GitHub でこのページを編集' },\n      },\n    },\n    ko: {\n      label: '한국어',\n      lang: 'ko',\n      link: '/ko/',\n      themeConfig: {\n        nav: navKO(),\n        sidebar: sidebarKO(),\n        outline: { label: '페이지 탐색' },\n        lastUpdated: { text: '마지막 업데이트' },\n        docFooter: { prev: '이전', next: '다음' },\n        editLink: { pattern: 'https://github.com/ace-step/ACE-Step-1.5/edit/main/docs/:path', text: 'GitHub에서 이 페이지 편집' },\n      },\n    },\n  },\n\n  themeConfig: {\n    logo: '/logo.png',\n\n    socialLinks: [\n      { icon: 'github', link: 'https://github.com/ace-step/ACE-Step-1.5' },\n      { icon: 'discord', link: 'https://discord.gg/PeWDxrkdj7' },\n    ],\n\n    search: {\n      provider: 'local',\n    },\n\n    editLink: {\n      pattern: 'https://github.com/ace-step/ACE-Step-1.5/edit/main/docs/:path',\n      text: 'Edit this page on GitHub',\n    },\n\n    footer: {\n      message: 'Released under the MIT License.',\n      copyright: 'Copyright 2025-present ACE-Step Team',\n    },\n  },\n})\n\n// ---------------------------------------------------------------------------\n// English\n// ---------------------------------------------------------------------------\n\nfunction navEN() {\n  return [\n    {\n      text: 'Guide',\n      items: [\n        { text: 'Installation', link: '/en/INSTALL' },\n        { text: 'Tutorial', link: '/en/Tutorial' },\n        { text: 'Gradio UI', link: '/en/GRADIO_GUIDE' },\n        { text: 'CLI', link: '/en/CLI' },\n      ],\n    },\n    {\n      text: 'API',\n      items: [\n        { text: 'Local API', link: '/en/API' },\n        { text: 'OpenRouter API', link: '/en/Openrouter_API_DOC' },\n      ],\n    },\n    {\n      text: 'Advanced',\n      items: [\n        { text: 'LoRA Training', link: '/en/LoRA_Training_Tutorial' },\n        { text: 'Benchmark', link: '/en/BENCHMARK' },\n        { text: 'GPU Compatibility', link: '/en/GPU_COMPATIBILITY' },\n      ],\n    },\n    {\n      text: 'SideStep',\n      link: '/sidestep/Getting Started',\n    },\n    {\n      text: 'Ecosystem',\n      link: '/en/awesome',\n    },\n  ]\n}\n\nfunction sidebarEN() {\n  return {\n    '/en/': [\n      {\n        text: 'Getting Started',\n        items: [\n          { text: 'Installation', link: '/en/INSTALL' },\n          { text: 'Tutorial (Must Read)', link: '/en/Tutorial' },\n        ],\n      },\n      {\n        text: 'User Guide',\n        items: [\n          { text: 'Gradio UI Guide', link: '/en/GRADIO_GUIDE' },\n          { text: 'CLI', link: '/en/CLI' },\n          { text: 'Studio', link: '/en/studio' },\n          { text: \"Musician's Guide\", link: '/en/ace_step_musicians_guide' },\n        ],\n      },\n      {\n        text: 'API Reference',\n        items: [\n          { text: 'Local API', link: '/en/API' },\n          { text: 'OpenRouter API', link: '/en/Openrouter_API_DOC' },\n          { text: 'Inference', link: '/en/INFERENCE' },\n        ],\n      },\n      {\n        text: 'Advanced',\n        items: [\n          { text: 'LoRA Training', link: '/en/LoRA_Training_Tutorial' },\n          { text: 'GPU Compatibility', link: '/en/GPU_COMPATIBILITY' },\n          { text: 'GPU Troubleshooting', link: '/en/GPU_TROUBLESHOOTING' },\n          { text: 'Benchmark', link: '/en/BENCHMARK' },\n          { text: 'ROCm on Linux', link: '/en/ACE-Step1.5-Rocm-Manual-Linux' },\n        ],\n      },\n      {\n        text: 'Ecosystem',\n        items: [\n          { text: 'Awesome ACE-Step', link: '/en/awesome' },\n        ],\n      },\n    ],\n    '/sidestep/': [\n      {\n        text: 'SideStep',\n        link: 'https://github.com/koda-dernet/Side-Step',\n        items: [\n          { text: 'Getting Started', link: '/sidestep/Getting Started' },\n          { text: 'Dataset Preparation', link: '/sidestep/Dataset Preparation' },\n          { text: 'Training Guide', link: '/sidestep/Training Guide' },\n          { text: 'End-to-End Tutorial', link: '/sidestep/End-to-End Tutorial' },\n          { text: 'Model Management', link: '/sidestep/Model Management' },\n          { text: 'Preset Management', link: '/sidestep/Preset Management' },\n          { text: 'Using Your Adapter', link: '/sidestep/Using Your Adapter' },\n          { text: 'Estimation Guide', link: '/sidestep/Estimation Guide' },\n          { text: 'Shift & Timestep Sampling', link: '/sidestep/Shift and Timestep Sampling' },\n          { text: 'The Settings Wizard', link: '/sidestep/The Settings Wizard' },\n          { text: 'VRAM Optimization', link: '/sidestep/VRAM Optimization Guide' },\n          { text: 'Windows Notes', link: '/sidestep/Windows Notes' },\n        ],\n      },\n    ],\n  }\n}\n\n// ---------------------------------------------------------------------------\n// Chinese\n// ---------------------------------------------------------------------------\n\nfunction navZH() {\n  return [\n    {\n      text: '指南',\n      items: [\n        { text: '安装', link: '/zh/INSTALL' },\n        { text: '教程', link: '/zh/Tutorial' },\n        { text: 'Gradio UI', link: '/zh/GRADIO_GUIDE' },\n      ],\n    },\n    {\n      text: 'API',\n      items: [\n        { text: '本地 API', link: '/zh/API' },\n        { text: 'OpenRouter API', link: '/zh/Openrouter_API_DOC' },\n      ],\n    },\n    {\n      text: '进阶',\n      items: [\n        { text: 'LoRA 训练', link: '/zh/LoRA_Training_Tutorial' },\n        { text: '评测', link: '/zh/BENCHMARK' },\n        { text: 'GPU 兼容性', link: '/zh/GPU_COMPATIBILITY' },\n      ],\n    },\n    {\n      text: '生态',\n      link: '/en/awesome',\n    },\n  ]\n}\n\nfunction sidebarZH() {\n  return {\n    '/zh/': [\n      {\n        text: '快速开始',\n        items: [\n          { text: '安装指南', link: '/zh/INSTALL' },\n          { text: '教程 (必读)', link: '/zh/Tutorial' },\n        ],\n      },\n      {\n        text: '使用指南',\n        items: [\n          { text: 'Gradio UI 指南', link: '/zh/GRADIO_GUIDE' },\n        ],\n      },\n      {\n        text: 'API 参考',\n        items: [\n          { text: '本地 API', link: '/zh/API' },\n          { text: 'OpenRouter API', link: '/zh/Openrouter_API_DOC' },\n          { text: '推理', link: '/zh/INFERENCE' },\n        ],\n      },\n      {\n        text: '进阶',\n        items: [\n          { text: 'LoRA 训练', link: '/zh/LoRA_Training_Tutorial' },\n          { text: 'GPU 兼容性', link: '/zh/GPU_COMPATIBILITY' },\n          { text: '评测', link: '/zh/BENCHMARK' },\n        ],\n      },\n    ],\n  }\n}\n\n// ---------------------------------------------------------------------------\n// Japanese\n// ---------------------------------------------------------------------------\n\nfunction navJA() {\n  return [\n    {\n      text: 'ガイド',\n      items: [\n        { text: 'インストール', link: '/ja/INSTALL' },\n        { text: 'チュートリアル', link: '/ja/Tutorial' },\n        { text: 'Gradio UI', link: '/ja/GRADIO_GUIDE' },\n      ],\n    },\n    {\n      text: 'API',\n      items: [\n        { text: 'ローカル API', link: '/ja/API' },\n        { text: 'OpenRouter API', link: '/ja/Openrouter_API_DOC' },\n      ],\n    },\n    {\n      text: '上級',\n      items: [\n        { text: 'LoRA 学習', link: '/ja/LoRA_Training_Tutorial' },\n        { text: 'GPU 互換性', link: '/ja/GPU_COMPATIBILITY' },\n      ],\n    },\n    {\n      text: 'エコシステム',\n      link: '/en/awesome',\n    },\n  ]\n}\n\nfunction sidebarJA() {\n  return {\n    '/ja/': [\n      {\n        text: 'はじめに',\n        items: [\n          { text: 'インストール', link: '/ja/INSTALL' },\n          { text: 'チュートリアル (必読)', link: '/ja/Tutorial' },\n        ],\n      },\n      {\n        text: '使い方',\n        items: [\n          { text: 'Gradio UI ガイド', link: '/ja/GRADIO_GUIDE' },\n        ],\n      },\n      {\n        text: 'APIリファレンス',\n        items: [\n          { text: 'ローカル API', link: '/ja/API' },\n          { text: 'OpenRouter API', link: '/ja/Openrouter_API_DOC' },\n          { text: '推論', link: '/ja/INFERENCE' },\n        ],\n      },\n      {\n        text: '上級',\n        items: [\n          { text: 'LoRA 学習', link: '/ja/LoRA_Training_Tutorial' },\n          { text: 'GPU 互換性', link: '/ja/GPU_COMPATIBILITY' },\n        ],\n      },\n    ],\n  }\n}\n\n// ---------------------------------------------------------------------------\n// Korean\n// ---------------------------------------------------------------------------\n\nfunction navKO() {\n  return [\n    {\n      text: '가이드',\n      items: [\n        { text: '튜토리얼', link: '/ko/Tutorial' },\n        { text: 'Gradio UI', link: '/ko/GRADIO_GUIDE' },\n      ],\n    },\n    {\n      text: 'API',\n      items: [\n        { text: '로컬 API', link: '/ko/API' },\n        { text: 'OpenRouter API', link: '/ko/Openrouter_API_DOC' },\n      ],\n    },\n    {\n      text: '고급',\n      items: [\n        { text: 'LoRA 학습', link: '/ko/LoRA_Training_Tutorial' },\n        { text: 'GPU 호환성', link: '/ko/GPU_COMPATIBILITY' },\n      ],\n    },\n    {\n      text: '에코시스템',\n      link: '/en/awesome',\n    },\n  ]\n}\n\nfunction sidebarKO() {\n  return {\n    '/ko/': [\n      {\n        text: '시작하기',\n        items: [\n          { text: '튜토리얼 (필독)', link: '/ko/Tutorial' },\n        ],\n      },\n      {\n        text: '사용 가이드',\n        items: [\n          { text: 'Gradio UI 가이드', link: '/ko/GRADIO_GUIDE' },\n        ],\n      },\n      {\n        text: 'API 레퍼런스',\n        items: [\n          { text: '로컬 API', link: '/ko/API' },\n          { text: 'OpenRouter API', link: '/ko/Openrouter_API_DOC' },\n          { text: '추론', link: '/ko/INFERENCE' },\n        ],\n      },\n      {\n        text: '고급',\n        items: [\n          { text: 'LoRA 학습', link: '/ko/LoRA_Training_Tutorial' },\n          { text: 'GPU 호환성', link: '/ko/GPU_COMPATIBILITY' },\n        ],\n      },\n    ],\n  }\n}\n"
  },
  {
    "path": "docs/.vitepress/theme/custom.css",
    "content": ":root {\n  --vp-c-brand-1: #6366f1;\n  --vp-c-brand-2: #818cf8;\n  --vp-c-brand-3: #a5b4fc;\n  --vp-c-brand-soft: rgba(99, 102, 241, 0.14);\n}\n\n.dark {\n  --vp-c-brand-1: #818cf8;\n  --vp-c-brand-2: #a5b4fc;\n  --vp-c-brand-3: #c7d2fe;\n  --vp-c-brand-soft: rgba(129, 140, 248, 0.14);\n}\n\n:root {\n  --vp-home-hero-name-color: transparent;\n  --vp-home-hero-name-background: -webkit-linear-gradient(\n    120deg,\n    #6366f1 30%,\n    #8b5cf6 70%\n  );\n  --vp-home-hero-image-background-image: linear-gradient(\n    -45deg,\n    #6366f1 50%,\n    #8b5cf6 50%\n  );\n  --vp-home-hero-image-filter: blur(44px);\n}\n\n@media (min-width: 640px) {\n  :root {\n    --vp-home-hero-image-filter: blur(56px);\n  }\n}\n\n@media (min-width: 960px) {\n  :root {\n    --vp-home-hero-image-filter: blur(68px);\n  }\n}\n\n/* Nav logo: invert on light mode (logo is white-on-black) */\n:root .VPNavBarTitle .logo {\n  filter: invert(1);\n}\n.dark .VPNavBarTitle .logo {\n  filter: none;\n}\n\n/* Hero image: round corners */\n.VPImage.image-src {\n  border-radius: 16px;\n}\n"
  },
  {
    "path": "docs/.vitepress/theme/index.ts",
    "content": "import DefaultTheme from 'vitepress/theme'\nimport './custom.css'\n\nexport default DefaultTheme\n"
  },
  {
    "path": "docs/en/ACE-Step1.5-Rocm-Manual-Linux.md",
    "content": "Date of the program this worked:\n07.02.2026 - 10:40 am UTC +1\n\nACE-Step1.5 Rocm Manual for cachy-os and tested with RDNA4/Strix Halo.\nStrix-Halo need manually set to be 16GB VRAM in Bios or more.\nAt this moment no GTT Ram size used.\n\n#Install python Version 3.11\nsudo pacman -S python311 git \n\n#Navigate to the folder you want ACE-Step to be in and open the terminal there\n\n# Get the Program and change into the folder\ngit clone https://github.com/ace-step/ACE-Step-1.5.git\ncd ACE-Step-1.5/ \n\n#Create the virtual python environment with python Version 3.11\npython3.11 -m venv .venv\n\n#activate the environment in the terminal\nsource .venv/bin/activate\n\n#install pytorch requirements\npip install torch torchaudio torchvision xformers --index-url https://download.pytorch.org/whl/rocm6.4\n\n#install requirements without uv\npip install -r requirements-rocm-linux.txt\n\n#start the program \n#\"--servername 0.0.0.0\" is for making this on all networks card available\n#\"--servername 127.0.0.1\" is for making this just local available\n#\"--servername localhost\" or no without the \"--servername\" option also local only\npython -m acestep.acestep_v15_pipeline --server-name 0.0.0.0 --port 7680\n\n#start the program local\npython -m acestep.acestep_v15_pipeline --server-name 127.0.0.1 --port 7680\n\n# Access the webui on your Browser\nhttp://127.0.0.1:7680\n\n#deactivate int8\n#set 5Hz LM Backend to \"pt\"\n#Click initialize and wait for download to finish\n#Have fun\n\n"
  },
  {
    "path": "docs/en/API.md",
    "content": "# ACE-Step API Client Documentation\n\n**Language / 语言 / 言語:** [English](API.md) | [中文](../zh/API.md) | [日本語](../ja/API.md)\n\n---\n\nThis service provides an HTTP-based asynchronous music generation API.\n\n**Basic Workflow**:\n1. Call `POST /release_task` to submit a task and obtain a `task_id`.\n2. Call `POST /query_result` to batch query task status until `status` is `1` (succeeded) or `2` (failed).\n3. Download audio files via `GET /v1/audio?path=...` URLs returned in the result.\n\n---\n\n## Table of Contents\n\n- [Authentication](#1-authentication)\n- [Response Format](#2-response-format)\n- [Task Status Description](#3-task-status-description)\n- [Create Generation Task](#4-create-generation-task)\n- [Batch Query Task Results](#5-batch-query-task-results)\n- [Format Input](#6-format-input)\n- [Get Random Sample](#7-get-random-sample)\n- [List Available Models](#8-list-available-models)\n- [Server Statistics](#9-server-statistics)\n- [Download Audio Files](#10-download-audio-files)\n- [Health Check](#11-health-check)\n- [Environment Variables](#12-environment-variables)\n\n---\n\n## 1. Authentication\n\nThe API supports optional API key authentication. When enabled, a valid key must be provided in requests.\n\n### Authentication Methods\n\nTwo authentication methods are supported:\n\n**Method A: ai_token in request body**\n\n```json\n{\n  \"ai_token\": \"your-api-key\",\n  \"prompt\": \"upbeat pop song\",\n  ...\n}\n```\n\n**Method B: Authorization header**\n\n```bash\ncurl -X POST http://localhost:8001/release_task \\\n  -H 'Authorization: Bearer your-api-key' \\\n  -H 'Content-Type: application/json' \\\n  -d '{\"prompt\": \"upbeat pop song\"}'\n```\n\n### Configuring API Key\n\nSet via environment variable or command-line argument:\n\n```bash\n# Environment variable\nexport ACESTEP_API_KEY=your-secret-key\n\n# Or command-line argument\npython -m acestep.api_server --api-key your-secret-key\n```\n\n---\n\n## 2. Response Format\n\nAll API responses use a unified wrapper format:\n\n```json\n{\n  \"data\": { ... },\n  \"code\": 200,\n  \"error\": null,\n  \"timestamp\": 1700000000000,\n  \"extra\": null\n}\n```\n\n| Field | Type | Description |\n| :--- | :--- | :--- |\n| `data` | any | Actual response data |\n| `code` | int | Status code (200=success) |\n| `error` | string | Error message (null on success) |\n| `timestamp` | int | Response timestamp (milliseconds) |\n| `extra` | any | Extra information (usually null) |\n\n---\n\n## 3. Task Status Description\n\nTask status (`status`) is represented as integers:\n\n| Status Code | Status Name | Description |\n| :--- | :--- | :--- |\n| `0` | queued/running | Task is queued or in progress |\n| `1` | succeeded | Generation succeeded, result is ready |\n| `2` | failed | Generation failed |\n\n---\n\n## 4. Create Generation Task\n\n### 4.1 API Definition\n\n- **URL**: `/release_task`\n- **Method**: `POST`\n- **Content-Type**: `application/json`, `multipart/form-data`, or `application/x-www-form-urlencoded`\n\n### 4.2 Request Parameters\n\n#### Parameter Naming Convention\n\nThe API supports both **snake_case** and **camelCase** naming for most parameters. For example:\n- `audio_duration` / `duration` / `audioDuration`\n- `key_scale` / `keyscale` / `keyScale`\n- `time_signature` / `timesignature` / `timeSignature`\n- `sample_query` / `sampleQuery` / `description` / `desc`\n- `use_format` / `useFormat` / `format`\n\nAdditionally, metadata can be passed in a nested object (`metas`, `metadata`, or `user_metadata`).\n\n#### Method A: JSON Request (application/json)\n\nSuitable for passing only text parameters, or referencing audio file paths that already exist on the server.\n\n**Basic Parameters**:\n\n| Parameter Name | Type | Default | Description |\n| :--- | :--- | :--- | :--- |\n| `prompt` | string | `\"\"` | Music description prompt (alias: `caption`) |\n| `lyrics` | string | `\"\"` | Lyrics content |\n| `thinking` | bool | `false` | Whether to use 5Hz LM to generate audio codes (lm-dit behavior) |\n| `vocal_language` | string | `\"en\"` | Lyrics language (en, zh, ja, etc.) |\n| `audio_format` | string | `\"mp3\"` | Output format (mp3, wav, flac) |\n\n**Sample/Description Mode Parameters**:\n\n| Parameter Name | Type | Default | Description |\n| :--- | :--- | :--- | :--- |\n| `sample_mode` | bool | `false` | Enable random sample generation mode (auto-generates caption/lyrics/metas via LM) |\n| `sample_query` | string | `\"\"` | Natural language description for sample generation (e.g., \"a soft Bengali love song\"). Aliases: `description`, `desc` |\n| `use_format` | bool | `false` | Use LM to enhance/format the provided caption and lyrics. Alias: `format` |\n\n**Multi-Model Support**:\n\n| Parameter Name | Type | Default | Description |\n| :--- | :--- | :--- | :--- |\n| `model` | string | null | Select which DiT model to use (e.g., `\"acestep-v15-turbo\"`, `\"acestep-v15-turbo-shift3\"`). Use `/v1/models` to list available models. If not specified, uses the default model. |\n\n**thinking Semantics (Important)**:\n\n- `thinking=false`:\n  - The server will **NOT** use 5Hz LM to generate `audio_code_string`.\n  - DiT runs in **text2music** mode and **ignores** any provided `audio_code_string`.\n- `thinking=true`:\n  - The server will use 5Hz LM to generate `audio_code_string` (lm-dit behavior).\n  - DiT runs with LM-generated codes for enhanced music quality.\n\n**Metadata Auto-Completion (Conditional)**:\n\nWhen `use_cot_caption=true` or `use_cot_language=true` or metadata fields are missing, the server may call 5Hz LM to fill the missing fields based on `caption`/`lyrics`:\n\n- `bpm`\n- `key_scale`\n- `time_signature`\n- `audio_duration`\n\nUser-provided values always win; LM only fills the fields that are empty/missing.\n\n**Music Attribute Parameters**:\n\n| Parameter Name | Type | Default | Description |\n| :--- | :--- | :--- | :--- |\n| `bpm` | int | null | Specify tempo (BPM), range 30-300 |\n| `key_scale` | string | `\"\"` | Key/scale (e.g., \"C Major\", \"Am\"). Aliases: `keyscale`, `keyScale` |\n| `time_signature` | string | `\"\"` | Time signature (2, 3, 4, 6 for 2/4, 3/4, 4/4, 6/8). Aliases: `timesignature`, `timeSignature` |\n| `audio_duration` | float | null | Generation duration (seconds), range 10-600. Aliases: `duration`, `target_duration` |\n\n**Audio Codes (Optional)**:\n\n| Parameter Name | Type | Default | Description |\n| :--- | :--- | :--- | :--- |\n| `audio_code_string` | string or string[] | `\"\"` | Audio semantic tokens (5Hz) for `llm_dit`. Alias: `audioCodeString` |\n\n**Generation Control Parameters**:\n\n| Parameter Name | Type | Default | Description |\n| :--- | :--- | :--- | :--- |\n| `inference_steps` | int | `8` | Number of inference steps. Turbo model: 1-20 (recommended 8). Base model: 1-200 (recommended 32-64). |\n| `guidance_scale` | float | `7.0` | Prompt guidance coefficient. Only effective for base model. |\n| `use_random_seed` | bool | `true` | Whether to use random seed |\n| `seed` | int | `-1` | Specify seed (when use_random_seed=false) |\n| `batch_size` | int | `2` | Batch generation count (max 8) |\n\n**Advanced DiT Parameters**:\n\n| Parameter Name | Type | Default | Description |\n| :--- | :--- | :--- | :--- |\n| `shift` | float | `3.0` | Timestep shift factor (range 1.0-5.0). Only effective for base models, not turbo models. |\n| `infer_method` | string | `\"ode\"` | Diffusion inference method: `\"ode\"` (Euler, faster) or `\"sde\"` (stochastic). |\n| `timesteps` | string | null | Custom timesteps as comma-separated values (e.g., `\"0.97,0.76,0.615,0.5,0.395,0.28,0.18,0.085,0\"`). Overrides `inference_steps` and `shift`. |\n| `use_adg` | bool | `false` | Use Adaptive Dual Guidance (base model only) |\n| `cfg_interval_start` | float | `0.0` | CFG application start ratio (0.0-1.0) |\n| `cfg_interval_end` | float | `1.0` | CFG application end ratio (0.0-1.0) |\n\n**5Hz LM Parameters (Optional, server-side)**:\n\nThese parameters control 5Hz LM sampling, used for metadata auto-completion and (when `thinking=true`) codes generation.\n\n| Parameter Name | Type | Default | Description |\n| :--- | :--- | :--- | :--- |\n| `lm_model_path` | string | null | 5Hz LM checkpoint dir name (e.g. `acestep-5Hz-lm-0.6B`) |\n| `lm_backend` | string | `\"vllm\"` | `vllm` or `pt` |\n| `lm_temperature` | float | `0.85` | Sampling temperature |\n| `lm_cfg_scale` | float | `2.5` | CFG scale (>1 enables CFG) |\n| `lm_negative_prompt` | string | `\"NO USER INPUT\"` | Negative prompt used by CFG |\n| `lm_top_k` | int | null | Top-k (0/null disables) |\n| `lm_top_p` | float | `0.9` | Top-p (>=1 will be treated as disabled) |\n| `lm_repetition_penalty` | float | `1.0` | Repetition penalty |\n\n**LM CoT (Chain-of-Thought) Parameters**:\n\n| Parameter Name | Type | Default | Description |\n| :--- | :--- | :--- | :--- |\n| `use_cot_caption` | bool | `true` | Let LM rewrite/enhance the input caption via CoT reasoning. Aliases: `cot_caption`, `cot-caption` |\n| `use_cot_language` | bool | `true` | Let LM detect vocal language via CoT. Aliases: `cot_language`, `cot-language` |\n| `constrained_decoding` | bool | `true` | Enable FSM-based constrained decoding for structured LM output. Aliases: `constrainedDecoding`, `constrained` |\n| `constrained_decoding_debug` | bool | `false` | Enable debug logging for constrained decoding |\n| `allow_lm_batch` | bool | `true` | Allow LM batch processing for efficiency |\n\n**Edit/Reference Audio Parameters** (requires absolute path on server):\n\n| Parameter Name | Type | Default | Description |\n| :--- | :--- | :--- | :--- |\n| `reference_audio_path` | string | null | Reference audio path (Style Transfer) |\n| `src_audio_path` | string | null | Source audio path (Repainting/Cover) |\n| `task_type` | string | `\"text2music\"` | Task type: `text2music`, `cover`, `repaint`, `lego`, `extract`, `complete` |\n| `instruction` | string | auto | Edit instruction (auto-generated based on task_type if not provided) |\n| `repainting_start` | float | `0.0` | Repainting start time (seconds) |\n| `repainting_end` | float | null | Repainting end time (seconds), -1 for end of audio |\n| `audio_cover_strength` | float | `1.0` | Cover strength (0.0-1.0). Lower values (0.2) for style transfer. |\n\n#### Method B: File Upload (multipart/form-data)\n\nUse this when you need to upload local audio files as reference or source audio.\n\nIn addition to supporting all the above fields as Form Fields, the following file fields are also supported:\n\n- `reference_audio` or `ref_audio`: (File) Upload reference audio file\n- `src_audio` or `ctx_audio`: (File) Upload source audio file\n\n> **Note**: After uploading files, the corresponding `_path` parameters will be automatically ignored, and the system will use the temporary file path after upload.\n\n### 4.3 Response Example\n\n```json\n{\n  \"data\": {\n    \"task_id\": \"550e8400-e29b-41d4-a716-446655440000\",\n    \"status\": \"queued\",\n    \"queue_position\": 1\n  },\n  \"code\": 200,\n  \"error\": null,\n  \"timestamp\": 1700000000000,\n  \"extra\": null\n}\n```\n\n### 4.4 Usage Examples (cURL)\n\n**Basic JSON Method**:\n\n```bash\ncurl -X POST http://localhost:8001/release_task \\\n  -H 'Content-Type: application/json' \\\n  -d '{\n    \"prompt\": \"upbeat pop song\",\n    \"lyrics\": \"Hello world\",\n    \"inference_steps\": 8\n  }'\n```\n\n**With thinking=true (LM generates codes + fills missing metas)**:\n\n```bash\ncurl -X POST http://localhost:8001/release_task \\\n  -H 'Content-Type: application/json' \\\n  -d '{\n    \"prompt\": \"upbeat pop song\",\n    \"lyrics\": \"Hello world\",\n    \"thinking\": true,\n    \"lm_temperature\": 0.85,\n    \"lm_cfg_scale\": 2.5\n  }'\n```\n\n**Description-driven generation (sample_query)**:\n\n```bash\ncurl -X POST http://localhost:8001/release_task \\\n  -H 'Content-Type: application/json' \\\n  -d '{\n    \"sample_query\": \"a soft Bengali love song for a quiet evening\",\n    \"thinking\": true\n  }'\n```\n\n**With format enhancement (use_format=true)**:\n\n```bash\ncurl -X POST http://localhost:8001/release_task \\\n  -H 'Content-Type: application/json' \\\n  -d '{\n    \"prompt\": \"pop rock\",\n    \"lyrics\": \"[Verse 1]\\nWalking down the street...\",\n    \"use_format\": true,\n    \"thinking\": true\n  }'\n```\n\n**Select specific model**:\n\n```bash\ncurl -X POST http://localhost:8001/release_task \\\n  -H 'Content-Type: application/json' \\\n  -d '{\n    \"prompt\": \"electronic dance music\",\n    \"model\": \"acestep-v15-turbo\",\n    \"thinking\": true\n  }'\n```\n\n**With custom timesteps**:\n\n```bash\ncurl -X POST http://localhost:8001/release_task \\\n  -H 'Content-Type: application/json' \\\n  -d '{\n    \"prompt\": \"jazz piano trio\",\n    \"timesteps\": \"0.97,0.76,0.615,0.5,0.395,0.28,0.18,0.085,0\",\n    \"thinking\": true\n  }'\n```\n\n**File Upload Method**:\n\n```bash\ncurl -X POST http://localhost:8001/release_task \\\n  -F \"prompt=remix this song\" \\\n  -F \"src_audio=@/path/to/local/song.mp3\" \\\n  -F \"task_type=repaint\"\n```\n\n---\n\n## 5. Batch Query Task Results\n\n### 5.1 API Definition\n\n- **URL**: `/query_result`\n- **Method**: `POST`\n- **Content-Type**: `application/json` or `application/x-www-form-urlencoded`\n\n### 5.2 Request Parameters\n\n| Parameter Name | Type | Description |\n| :--- | :--- | :--- |\n| `task_id_list` | string (JSON array) or array | List of task IDs to query |\n\n### 5.3 Response Example\n\n```json\n{\n  \"data\": [\n    {\n      \"task_id\": \"550e8400-e29b-41d4-a716-446655440000\",\n      \"status\": 1,\n      \"result\": \"[{\\\"file\\\": \\\"/v1/audio?path=...\\\", \\\"wave\\\": \\\"\\\", \\\"status\\\": 1, \\\"create_time\\\": 1700000000, \\\"env\\\": \\\"development\\\", \\\"prompt\\\": \\\"upbeat pop song\\\", \\\"lyrics\\\": \\\"Hello world\\\", \\\"metas\\\": {\\\"bpm\\\": 120, \\\"duration\\\": 30, \\\"genres\\\": \\\"\\\", \\\"keyscale\\\": \\\"C Major\\\", \\\"timesignature\\\": \\\"4\\\"}, \\\"generation_info\\\": \\\"...\\\", \\\"seed_value\\\": \\\"12345,67890\\\", \\\"lm_model\\\": \\\"acestep-5Hz-lm-0.6B\\\", \\\"dit_model\\\": \\\"acestep-v15-turbo\\\"}]\"\n    }\n  ],\n  \"code\": 200,\n  \"error\": null,\n  \"timestamp\": 1700000000000,\n  \"extra\": null\n}\n```\n\n**Result Field Description** (result is a JSON string, after parsing contains):\n\n| Field | Type | Description |\n| :--- | :--- | :--- |\n| `file` | string | Audio file URL (use with `/v1/audio` endpoint) |\n| `wave` | string | Waveform data (usually empty) |\n| `status` | int | Status code (0=in progress, 1=success, 2=failed) |\n| `create_time` | int | Creation time (Unix timestamp) |\n| `env` | string | Environment identifier |\n| `prompt` | string | Prompt used |\n| `lyrics` | string | Lyrics used |\n| `metas` | object | Metadata (bpm, duration, genres, keyscale, timesignature) |\n| `generation_info` | string | Generation info summary |\n| `seed_value` | string | Seed values used (comma-separated) |\n| `lm_model` | string | LM model name used |\n| `dit_model` | string | DiT model name used |\n\n### 5.4 Usage Example\n\n```bash\ncurl -X POST http://localhost:8001/query_result \\\n  -H 'Content-Type: application/json' \\\n  -d '{\n    \"task_id_list\": [\"550e8400-e29b-41d4-a716-446655440000\"]\n  }'\n```\n\n---\n\n## 6. Format Input\n\n### 6.1 API Definition\n\n- **URL**: `/format_input`\n- **Method**: `POST`\n\nThis endpoint uses LLM to enhance and format user-provided caption and lyrics.\n\n### 6.2 Request Parameters\n\n| Parameter Name | Type | Default | Description |\n| :--- | :--- | :--- | :--- |\n| `prompt` | string | `\"\"` | Music description prompt |\n| `lyrics` | string | `\"\"` | Lyrics content |\n| `temperature` | float | `0.85` | LM sampling temperature |\n| `param_obj` | string (JSON) | `\"{}\"` | JSON object containing metadata (duration, bpm, key, time_signature, language) |\n\n### 6.3 Response Example\n\n```json\n{\n  \"data\": {\n    \"caption\": \"Enhanced music description\",\n    \"lyrics\": \"Formatted lyrics...\",\n    \"bpm\": 120,\n    \"key_scale\": \"C Major\",\n    \"time_signature\": \"4\",\n    \"duration\": 180,\n    \"vocal_language\": \"en\"\n  },\n  \"code\": 200,\n  \"error\": null,\n  \"timestamp\": 1700000000000,\n  \"extra\": null\n}\n```\n\n### 6.4 Usage Example\n\n```bash\ncurl -X POST http://localhost:8001/format_input \\\n  -H 'Content-Type: application/json' \\\n  -d '{\n    \"prompt\": \"pop rock\",\n    \"lyrics\": \"Walking down the street\",\n    \"param_obj\": \"{\\\"duration\\\": 180, \\\"language\\\": \\\"en\\\"}\"\n  }'\n```\n\n---\n\n## 7. Get Random Sample\n\n### 7.1 API Definition\n\n- **URL**: `/create_random_sample`\n- **Method**: `POST`\n\nThis endpoint returns random sample parameters from pre-loaded example data for form filling.\n\n### 7.2 Request Parameters\n\n| Parameter Name | Type | Default | Description |\n| :--- | :--- | :--- | :--- |\n| `sample_type` | string | `\"simple_mode\"` | Sample type: `\"simple_mode\"` or `\"custom_mode\"` |\n\n### 7.3 Response Example\n\n```json\n{\n  \"data\": {\n    \"caption\": \"Upbeat pop song with guitar accompaniment\",\n    \"lyrics\": \"[Verse 1]\\nSunshine on my face...\",\n    \"bpm\": 120,\n    \"key_scale\": \"G Major\",\n    \"time_signature\": \"4\",\n    \"duration\": 180,\n    \"vocal_language\": \"en\"\n  },\n  \"code\": 200,\n  \"error\": null,\n  \"timestamp\": 1700000000000,\n  \"extra\": null\n}\n```\n\n### 7.4 Usage Example\n\n```bash\ncurl -X POST http://localhost:8001/create_random_sample \\\n  -H 'Content-Type: application/json' \\\n  -d '{\"sample_type\": \"simple_mode\"}'\n```\n\n---\n\n## 8. List Available Models\n\n### 8.1 API Definition\n\n- **URL**: `/v1/models`\n- **Method**: `GET`\n\nReturns a list of available DiT models loaded on the server.\n\n### 8.2 Response Example\n\n```json\n{\n  \"data\": {\n    \"models\": [\n      {\n        \"name\": \"acestep-v15-turbo\",\n        \"is_default\": true\n      },\n      {\n        \"name\": \"acestep-v15-turbo-shift3\",\n        \"is_default\": false\n      }\n    ],\n    \"default_model\": \"acestep-v15-turbo\"\n  },\n  \"code\": 200,\n  \"error\": null,\n  \"timestamp\": 1700000000000,\n  \"extra\": null\n}\n```\n\n### 8.3 Usage Example\n\n```bash\ncurl http://localhost:8001/v1/models\n```\n\n---\n\n## 9. Server Statistics\n\n### 9.1 API Definition\n\n- **URL**: `/v1/stats`\n- **Method**: `GET`\n\nReturns server runtime statistics.\n\n### 9.2 Response Example\n\n```json\n{\n  \"data\": {\n    \"jobs\": {\n      \"total\": 100,\n      \"queued\": 5,\n      \"running\": 1,\n      \"succeeded\": 90,\n      \"failed\": 4\n    },\n    \"queue_size\": 5,\n    \"queue_maxsize\": 200,\n    \"avg_job_seconds\": 8.5\n  },\n  \"code\": 200,\n  \"error\": null,\n  \"timestamp\": 1700000000000,\n  \"extra\": null\n}\n```\n\n### 9.3 Usage Example\n\n```bash\ncurl http://localhost:8001/v1/stats\n```\n\n---\n\n## 10. Download Audio Files\n\n### 10.1 API Definition\n\n- **URL**: `/v1/audio`\n- **Method**: `GET`\n\nDownload generated audio files by path.\n\n### 10.2 Request Parameters\n\n| Parameter Name | Type | Description |\n| :--- | :--- | :--- |\n| `path` | string | URL-encoded path to the audio file |\n\n### 10.3 Usage Example\n\n```bash\n# Download using the URL from task result\ncurl \"http://localhost:8001/v1/audio?path=%2Ftmp%2Fapi_audio%2Fabc123.mp3\" -o output.mp3\n```\n\n---\n\n## 11. Health Check\n\n### 11.1 API Definition\n\n- **URL**: `/health`\n- **Method**: `GET`\n\nReturns service health status.\n\n### 11.2 Response Example\n\n```json\n{\n  \"data\": {\n    \"status\": \"ok\",\n    \"service\": \"ACE-Step API\",\n    \"version\": \"1.0\"\n  },\n  \"code\": 200,\n  \"error\": null,\n  \"timestamp\": 1700000000000,\n  \"extra\": null\n}\n```\n\n---\n\n## 12. Environment Variables\n\nThe API server can be configured using environment variables:\n\n### Server Configuration\n\n| Variable | Default | Description |\n| :--- | :--- | :--- |\n| `ACESTEP_API_HOST` | `127.0.0.1` | Server bind host |\n| `ACESTEP_API_PORT` | `8001` | Server bind port |\n| `ACESTEP_API_KEY` | (empty) | API authentication key (empty disables auth) |\n| `ACESTEP_API_WORKERS` | `1` | API worker thread count |\n\n### Model Configuration\n\n| Variable | Default | Description |\n| :--- | :--- | :--- |\n| `ACESTEP_CONFIG_PATH` | `acestep-v15-turbo` | Primary DiT model path |\n| `ACESTEP_CONFIG_PATH2` | (empty) | Secondary DiT model path (optional) |\n| `ACESTEP_CONFIG_PATH3` | (empty) | Third DiT model path (optional) |\n| `ACESTEP_DEVICE` | `auto` | Device for model loading |\n| `ACESTEP_USE_FLASH_ATTENTION` | `true` | Enable flash attention |\n| `ACESTEP_OFFLOAD_TO_CPU` | `false` | Offload models to CPU when idle |\n| `ACESTEP_OFFLOAD_DIT_TO_CPU` | `false` | Offload DiT specifically to CPU |\n\n### LM Configuration\n\n| Variable | Default | Description |\n| :--- | :--- | :--- |\n| `ACESTEP_INIT_LLM` | auto | Whether to initialize LM at startup (auto determines based on GPU) |\n| `ACESTEP_LM_MODEL_PATH` | `acestep-5Hz-lm-0.6B` | Default 5Hz LM model |\n| `ACESTEP_LM_BACKEND` | `vllm` | LM backend (vllm or pt) |\n| `ACESTEP_LM_DEVICE` | (same as ACESTEP_DEVICE) | Device for LM |\n| `ACESTEP_LM_OFFLOAD_TO_CPU` | `false` | Offload LM to CPU |\n\n### Queue Configuration\n\n| Variable | Default | Description |\n| :--- | :--- | :--- |\n| `ACESTEP_QUEUE_MAXSIZE` | `200` | Maximum queue size |\n| `ACESTEP_QUEUE_WORKERS` | `1` | Number of queue workers |\n| `ACESTEP_AVG_JOB_SECONDS` | `5.0` | Initial average job duration estimate |\n| `ACESTEP_AVG_WINDOW` | `50` | Window for averaging job duration |\n\n### Cache Configuration\n\n| Variable | Default | Description |\n| :--- | :--- | :--- |\n| `ACESTEP_TMPDIR` | `.cache/acestep/tmp` | Temporary file directory |\n| `TRITON_CACHE_DIR` | `.cache/acestep/triton` | Triton cache directory |\n| `TORCHINDUCTOR_CACHE_DIR` | `.cache/acestep/torchinductor` | TorchInductor cache directory |\n\n---\n\n## Error Handling\n\n**HTTP Status Codes**:\n\n- `200`: Success\n- `400`: Invalid request (bad JSON, missing fields)\n- `401`: Unauthorized (missing or invalid API key)\n- `404`: Resource not found\n- `415`: Unsupported Content-Type\n- `429`: Server busy (queue is full)\n- `500`: Internal server error\n\n**Error Response Format**:\n\n```json\n{\n  \"detail\": \"Error message describing the issue\"\n}\n```\n\n---\n\n## Best Practices\n\n1. **Use `thinking=true`** for best quality results with LM-enhanced generation.\n\n2. **Use `sample_query`/`description`** for quick generation from natural language descriptions.\n\n3. **Use `use_format=true`** when you have caption/lyrics but want LM to enhance them.\n\n4. **Batch query task status** using the `/query_result` endpoint to query multiple tasks at once.\n\n5. **Check `/v1/stats`** to understand server load and average job time.\n\n6. **Use multi-model support** by setting `ACESTEP_CONFIG_PATH2` and `ACESTEP_CONFIG_PATH3` environment variables, then select with the `model` parameter.\n\n7. **For production**, set `ACESTEP_API_KEY` to enable authentication and secure your API.\n\n8. **For low VRAM environments**, enable `ACESTEP_OFFLOAD_TO_CPU=true` to support longer audio generation.\n"
  },
  {
    "path": "docs/en/BENCHMARK.md",
    "content": "# ACE-Step 1.5 Benchmark & Profiling Guide\n\n**Language / 语言:** [English](BENCHMARK.md) | [中文](../zh/BENCHMARK.md)\n\n---\n\n## Table of Contents\n\n- [Overview](#overview)\n- [Quick Start](#quick-start)\n- [Profiling Modes](#profiling-modes)\n- [CLI Reference](#cli-reference)\n- [Examples](#examples)\n- [Understanding Output](#understanding-output)\n- [Tips & Best Practices](#tips--best-practices)\n\n---\n\n## Overview\n\n`profile_inference.py` is a comprehensive profiling & benchmarking tool for ACE-Step 1.5 inference. It measures end-to-end wall time, LLM planning time, DiT diffusion time, VAE decoding time, and more — across different devices, backends, and configurations.\n\n### Supported Modes\n\n| Mode | Description |\n|------|-------------|\n| `profile` | Profile a single generation run with detailed timing breakdown |\n| `benchmark` | Run a matrix of configurations (duration × batch × thinking × steps) and produce a summary table |\n| `tier-test` | Automatically test all GPU tiers by simulating different VRAM sizes via `MAX_CUDA_VRAM` |\n| `understand` | Profile the `understand_music()` API (audio → metadata extraction) |\n| `create_sample` | Profile the `create_sample()` API (inspiration / simple mode) |\n| `format_sample` | Profile the `format_sample()` API (caption + lyrics → structured metadata) |\n\n### Supported Devices & Backends\n\n| Device | Flag | Notes |\n|--------|------|-------|\n| CUDA (NVIDIA) | `--device cuda` | Recommended. Auto-detected by default |\n| MPS (Apple Silicon) | `--device mps` | macOS with Apple Silicon |\n| CPU | `--device cpu` | Slow, for testing only |\n| Auto | `--device auto` | Automatically selects best available (default) |\n\n| LLM Backend | Flag | Notes |\n|-------------|------|-------|\n| vLLM | `--lm-backend vllm` | Fastest on CUDA, recommended for NVIDIA |\n| PyTorch | `--lm-backend pt` | Universal fallback, works everywhere |\n| MLX | `--lm-backend mlx` | Optimized for Apple Silicon |\n| Auto | `--lm-backend auto` | Selects best backend for device (default) |\n\n---\n\n## Quick Start\n\n```bash\n# Basic profile (text2music, default settings)\npython profile_inference.py\n\n# Profile with LLM thinking enabled\npython profile_inference.py --thinking\n\n# Run benchmark matrix\npython profile_inference.py --mode benchmark\n\n# Profile on Apple Silicon\npython profile_inference.py --device mps --lm-backend mlx\n\n# Profile with cProfile function-level analysis\npython profile_inference.py --detailed\n```\n\n---\n\n## Profiling Modes\n\n### 1. `profile` — Single Run Profiling\n\nRuns a single generation with detailed timing breakdown. Includes optional warmup and cProfile.\n\n```bash\npython profile_inference.py --mode profile\n```\n\n**What it measures:**\n- Total wall time (end-to-end)\n- LLM planning time (token generation, constrained decoding, CFG overhead)\n- DiT diffusion time (per-step and total)\n- VAE decode time\n- Audio save time\n\n**Options for this mode:**\n\n| Flag | Description |\n|------|-------------|\n| `--no-warmup` | Skip warmup run (includes compilation overhead in measurement) |\n| `--detailed` | Enable `cProfile` function-level analysis |\n| `--llm-debug` | Deep LLM debugging (token count, throughput) |\n| `--thinking` | Enable LLM Chain-of-Thought reasoning |\n| `--duration <sec>` | Override audio duration |\n| `--batch-size <n>` | Override batch size |\n| `--inference-steps <n>` | Override diffusion steps |\n\n### 2. `benchmark` — Configuration Matrix\n\nRuns a matrix of configurations and produces a summary table. Automatically adapts to GPU memory limits.\n\n```bash\npython profile_inference.py --mode benchmark\n```\n\n**Default matrix:**\n- Durations: 30s, 60s, 120s, 240s (clamped by GPU memory)\n- Batch sizes: 1, 2, 4 (clamped by GPU memory)\n- Thinking: True, False\n- Inference steps: 8, 16\n\n**Output example:**\n\n```\nDuration   Batch   Think   Steps   Wall(s)    LM(s)      DiT(s)     VAE(s)     Status\n--------------------------------------------------------------------------------------------------------------------------\n30         1       False   8       3.21       0.45       1.89       0.52       OK\n30         1       True    8       5.67       2.91       1.89       0.52       OK\n60         2       False   16      12.34      0.48       9.12       1.85       OK\n...\n```\n\n**Save results to JSON:**\n\n```bash\npython profile_inference.py --mode benchmark --benchmark-output results.json\n```\n\n### 3. `understand` — Audio Understanding Profiling\n\nProfiles the `understand_music()` API which extracts metadata (BPM, key, time signature, caption) from audio codes.\n\n```bash\npython profile_inference.py --mode understand\npython profile_inference.py --mode understand --audio-codes \"your_audio_codes_string\"\n```\n\n### 4. `create_sample` — Inspiration Mode Profiling\n\nProfiles the `create_sample()` API which generates a complete song blueprint from a simple text query.\n\n```bash\npython profile_inference.py --mode create_sample\npython profile_inference.py --mode create_sample --sample-query \"a soft Bengali love song\"\npython profile_inference.py --mode create_sample --instrumental\n```\n\n### 5. `format_sample` — Metadata Formatting Profiling\n\nProfiles the `format_sample()` API which converts caption + lyrics into structured metadata.\n\n```bash\npython profile_inference.py --mode format_sample\n```\n\n### 6. `tier-test` — Automated GPU Tier Testing\n\nAutomatically simulates different GPU VRAM sizes using `MAX_CUDA_VRAM` and runs a generation test at each tier. This is the recommended way to validate that all GPU tiers work correctly after modifying `acestep/gpu_config.py`.\n\n```bash\n# Test all tiers (4, 6, 8, 12, 16, 20, 24 GB)\npython profile_inference.py --mode tier-test\n\n# Test specific VRAM sizes\npython profile_inference.py --mode tier-test --tiers 6 8 16\n\n# Test with LM enabled (where the tier supports it)\npython profile_inference.py --mode tier-test --tier-with-lm\n\n# Quick test: skip torch.compile for non-quantized tiers\npython profile_inference.py --mode tier-test --tier-skip-compile\n```\n\n**What it validates per tier:**\n- Correct tier detection and `GPUConfig` construction\n- Model initialization (DiT, VAE, Text Encoder, optionally LM)\n- A short generation run (30s duration, batch=1) completes without OOM\n- Adaptive VAE decode fallback (GPU → CPU offload → full CPU)\n- VRAM usage stays within the simulated limit\n\n**Output example:**\n\n```\nTIER TEST RESULTS\n====================================================================================================\n  VRAM    Tier       LM      Duration   Status    Peak VRAM    Notes\n  ──────────────────────────────────────────────────────────────────────────────\n  4GB     tier1      —       30s        ✅ OK     3.8GB        VAE decoded on CPU\n  6GB     tier2      —       30s        ✅ OK     5.4GB        Tiled VAE chunk=256\n  8GB     tier4      0.6B    30s        ✅ OK     7.2GB        vllm backend\n  12GB    tier5      1.7B    30s        ✅ OK     10.8GB       vllm backend\n  16GB    tier6a     1.7B    30s        ✅ OK     14.5GB       offload enabled\n  20GB    tier6b     1.7B    30s        ✅ OK     17.2GB       no offload\n  24GB    unlimited  4B      30s        ✅ OK     21.3GB       full models on GPU\n```\n\n> **Note**: `tier-test` mode uses `torch.cuda.set_per_process_memory_fraction()` to enforce a hard VRAM cap, making simulations realistic even on high-end GPUs (e.g., A100 80GB).\n\n#### Boundary Testing\n\nUse `--tier-boundary` to find the minimum VRAM tier at which INT8 quantization and CPU offload can be safely disabled. For each tier, up to three configurations are tested:\n\n1. **default** — tier's standard settings\n2. **no-quant** — quantization disabled, offload unchanged\n3. **no-offload** — no quantization AND no CPU offload\n\n```bash\n# Run boundary tests across all tiers\npython profile_inference.py --mode tier-test --tier-boundary\n\n# Boundary test with LM enabled\npython profile_inference.py --mode tier-test --tier-boundary --tier-with-lm\n\n# Save boundary results to JSON\npython profile_inference.py --mode tier-test --tier-boundary --benchmark-output boundary_results.json\n```\n\nThe output includes a **Boundary Analysis** summary showing the minimum tier for each capability.\n\n#### Batch Size Boundary Testing\n\nUse `--tier-batch-boundary` to find the maximum safe batch size for each tier. For each tier, the tool progressively tests batch sizes 1, 2, 4, 8 (stopping at first OOM) with both LM-enabled and LM-disabled configurations:\n\n```bash\n# Run batch boundary tests\npython profile_inference.py --mode tier-test --tier-batch-boundary --tier-with-lm\n\n# Test specific tiers\npython profile_inference.py --mode tier-test --tier-batch-boundary --tier-with-lm --tiers 8 12 16 24\n```\n\nThe output includes a **Batch Boundary Summary** showing the maximum successful batch size per tier for both with-LM and without-LM configurations.\n\n---\n\n## CLI Reference\n\n### Device & Backend\n\n| Flag | Default | Description |\n|------|---------|-------------|\n| `--device` | `auto` | Device: `auto` / `cuda` / `mps` / `cpu` |\n| `--lm-backend` | `auto` | LLM backend: `auto` / `vllm` / `pt` / `mlx` |\n\n### Model Paths\n\n| Flag | Default | Description |\n|------|---------|-------------|\n| `--config-path` | `acestep-v15-turbo` | DiT model config |\n| `--lm-model` | `acestep-5Hz-lm-1.7B` | LLM model path |\n\n### Hardware Options\n\n| Flag | Default | Description |\n|------|---------|-------------|\n| `--offload-to-cpu` | off | Offload models to CPU when not in use |\n| `--offload-dit-to-cpu` | off | Offload DiT to CPU when not in use |\n| `--quantization` | none | Quantization: `int8_weight_only` / `fp8_weight_only` / `w8a8_dynamic` |\n\n### Generation Parameters\n\n| Flag | Default | Description |\n|------|---------|-------------|\n| `--duration` | from example | Audio duration in seconds |\n| `--batch-size` | from example | Batch size |\n| `--inference-steps` | from example | Diffusion inference steps |\n| `--seed` | from example | Random seed |\n| `--guidance-scale` | 7.0 | CFG guidance scale for DiT |\n\n### LLM / CoT Parameters\n\n| Flag | Default | Description |\n|------|---------|-------------|\n| `--thinking` | off | Enable LLM Chain-of-Thought reasoning |\n| `--use-cot-metas` | off | LLM generates music metadata via CoT |\n| `--use-cot-caption` | off | LLM rewrites/formats caption via CoT |\n| `--use-cot-language` | off | LLM detects vocal language via CoT |\n| `--use-constrained-decoding` | on | FSM-based constrained decoding |\n| `--no-constrained-decoding` | — | Disable constrained decoding |\n| `--lm-temperature` | 0.85 | LLM sampling temperature |\n| `--lm-cfg-scale` | 2.0 | LLM CFG scale |\n\n### Profiling Options\n\n| Flag | Default | Description |\n|------|---------|-------------|\n| `--mode` | `profile` | Mode: `profile` / `benchmark` / `tier-test` / `understand` / `create_sample` / `format_sample` |\n| `--no-warmup` | off | Skip warmup run |\n| `--detailed` | off | Enable `cProfile` function-level analysis |\n| `--llm-debug` | off | Deep LLM debugging (token count, throughput) |\n| `--benchmark-output` | none | Save benchmark results to JSON file |\n\n### Tier-Test Options\n\n| Flag | Default | Description |\n|------|---------|-------------|\n| `--tiers` | `4 6 8 12 16 20 24` | VRAM sizes (GB) to simulate |\n| `--tier-with-lm` | off | Enable LM initialization on tiers that support it |\n| `--tier-skip-compile` | off | Skip `torch.compile` for faster iteration on non-quantized tiers |\n| `--tier-boundary` | off | Test each tier with no-quant and no-offload variants to find minimum capability boundaries |\n| `--tier-batch-boundary` | off | Test each tier with batch sizes 1, 2, 4, 8 to find maximum safe batch size |\n\n### Input Options\n\n| Flag | Default | Description |\n|------|---------|-------------|\n| `--example` | `example_05.json` | Example JSON from `examples/text2music/` |\n| `--task-type` | `text2music` | Task: `text2music` / `cover` / `repaint` / `lego` / `extract` / `complete` |\n| `--reference-audio` | none | Reference audio path (for cover/style transfer) |\n| `--src-audio` | none | Source audio path (for audio-to-audio tasks) |\n| `--sample-query` | none | Query for `create_sample` mode |\n| `--instrumental` | off | Generate instrumental music (for `create_sample`) |\n| `--audio-codes` | none | Audio codes string (for `understand` mode) |\n\n---\n\n## Examples\n\n### Compare Devices\n\n```bash\n# NVIDIA GPU\npython profile_inference.py --device cuda --lm-backend vllm\n\n# Apple Silicon\npython profile_inference.py --device mps --lm-backend mlx\n\n# CPU baseline\npython profile_inference.py --device cpu --lm-backend pt\n```\n\n### Compare LLM Models\n\n```bash\n# Lightweight (0.6B)\npython profile_inference.py --lm-model acestep-5Hz-lm-0.6B\n\n# Default (1.7B)\npython profile_inference.py --lm-model acestep-5Hz-lm-1.7B\n\n# Large (4B)\npython profile_inference.py --lm-model acestep-5Hz-lm-4B\n```\n\n### Thinking vs No-Thinking\n\n```bash\n# Without thinking (faster)\npython profile_inference.py --mode benchmark\n\n# With thinking (better quality, slower)\npython profile_inference.py --thinking --use-cot-metas --use-cot-caption\n```\n\n### Low-VRAM Profiling\n\n```bash\n# Offload + quantization\npython profile_inference.py --offload-to-cpu --quantization int8_weight_only --lm-model acestep-5Hz-lm-0.6B\n```\n\n### Full Benchmark Suite\n\n```bash\n# Run full benchmark matrix and save results\npython profile_inference.py --mode benchmark --benchmark-output benchmark_results.json\n\n# Then inspect the JSON\ncat benchmark_results.json | python -m json.tool\n```\n\n### Function-Level Profiling\n\n```bash\n# Enable cProfile for detailed function-level analysis\npython profile_inference.py --detailed --llm-debug\n```\n\n---\n\n## Understanding Output\n\n### Time Costs Breakdown\n\nThe profiler prints a detailed breakdown of where time is spent:\n\n```\nTIME COSTS BREAKDOWN\n====================================================================================================\n  Component                          Time (s)       % of Total\n  ─────────────────────────────────────────────────────────────\n  LLM Planning (total)               2.91           45.2%\n    ├─ Token generation              2.45           38.1%\n    ├─ Constrained decoding          0.31            4.8%\n    └─ CFG overhead                  0.15            2.3%\n  DiT Diffusion (total)              1.89           29.4%\n    ├─ Per-step average              0.24            —\n    └─ Steps                         8               —\n  VAE Decode                         0.52            8.1%\n  Audio Save                         0.12            1.9%\n  Other / Overhead                   0.99           15.4%\n  ─────────────────────────────────────────────────────────────\n  Wall Time (total)                  6.43          100.0%\n```\n\n### Key Metrics\n\n| Metric | Description |\n|--------|-------------|\n| **Wall Time** | End-to-end time from start to finish |\n| **LM Total Time** | Time spent in LLM planning (token generation + parsing) |\n| **DiT Total Time** | Time spent in diffusion (all steps combined) |\n| **VAE Decode Time** | Time to decode latents to audio waveform |\n| **Tokens/sec** | LLM token generation throughput (with `--llm-debug`) |\n\n---\n\n## Tips & Best Practices\n\n1. **Always include warmup** (default) — The first run includes JIT compilation and memory allocation overhead. Warmup ensures measurements reflect steady-state performance.\n\n2. **Use `--benchmark-output`** to save results as JSON for later analysis or comparison across hardware.\n\n3. **Compare with thinking off vs on** — Thinking mode significantly increases LLM time but may improve generation quality.\n\n4. **Test with representative durations** — Short durations (30s) are dominated by LLM time; long durations (240s+) are dominated by DiT time.\n\n5. **GPU memory auto-adaptation** — The benchmark mode automatically clamps durations and batch sizes to what your GPU can handle, using the adaptive tier system in `acestep/gpu_config.py`.\n\n6. **Use `--detailed` sparingly** — `cProfile` adds overhead; use it only when investigating function-level bottlenecks.\n\n7. **Use `tier-test` for regression testing** — After modifying GPU tier configs, run `--mode tier-test` to verify all tiers still work correctly. This is especially important when changing offload thresholds, duration limits, or LM model availability.\n\n8. **Simulate low VRAM realistically** — When using `MAX_CUDA_VRAM`, the system enforces a hard VRAM cap via `set_per_process_memory_fraction()`, so OOM errors during simulation reflect real behavior on consumer GPUs.\n"
  },
  {
    "path": "docs/en/CLI.md",
    "content": "# ACE-Step 1.5 CLI Guide\n\nThis guide explains how to use `cli.py`, the interactive wizard and config-driven CLI for ACE-Step inference.\n\nThe CLI is **wizard/config only**: you either run the wizard to build a config, or load a `.toml` config and generate.\n\n---\n\n## Quick Start\n\nGenerate via wizard (interactive):\n\n```bash\npython cli.py\n```\n\nGenerate from a saved config:\n\n```bash\npython cli.py --config config.toml\n```\n\nCreate or edit a config without generating:\n\n```bash\npython cli.py --configure\npython cli.py --configure --config config.toml\n```\n\n---\n\n## CLI Flags\n\n- `-c` / `--config` — Path to a `.toml` configuration file to load.\n- `--configure` — Run wizard to save configuration without generating.\n- `--log-level` — Logging level for internal modules. One of `TRACE`, `DEBUG`, `INFO`, `WARNING`, `ERROR`, `CRITICAL`. Default: `INFO`.\n\n---\n\n## Wizard Flow\n\n1. Choose one of 6 tasks.\n2. Select a DiT model (from locally available models, or auto-download).\n3. Select an LM model (from locally available models, or auto-download).\n4. Provide task-specific inputs (source audio, tracks, etc.).\n5. For `text2music`: choose between Simple Mode (auto-generate caption/lyrics via LM) or manual input.\n6. Provide caption / description.\n7. Choose lyrics mode (instrumental / auto-generate / file / paste).\n8. Set number of outputs.\n9. Optionally configure advanced parameters (metadata, DiT settings, LM settings, output settings).\n10. Review summary and confirm generation.\n11. Save configuration to a `.toml` file.\n\nIf you skip advanced parameters, the wizard fills **all optional parameters** with defaults from `GenerationParams` and `GenerationConfig`.\n\n---\n\n## Configure Mode (`--configure`)\n\n`--configure` runs the wizard **without generation** and always saves a config.\n\nBehavior:\n- If `--config` is provided, the file is loaded and used as the wizard's starting values.\n- After the wizard, you choose a filename to save (overwriting or new).\n- The program exits without generation.\n\n---\n\n## Configuration File (`.toml`)\n\nThe wizard saves a `.toml` file containing all parameters. These keys map directly to the fields used in `cli.py`.\n\nWhen you load a config with `--config`, all keys are applied to the runtime settings.\n\n---\n\n## Prompt Editing (`instruction.txt`)\n\nWhen `thinking=True` and a config file is loaded via `--config`, the CLI looks for an `instruction.txt` file in the project root. If found, its contents are used as the pre-loaded formatted prompt for LM audio-token generation, bypassing the interactive editing step.\n\nWhen running without a config file (wizard mode), the CLI writes the LM's formatted prompt to `instruction.txt` and pauses so you can edit it before audio-token generation proceeds.\n\nThis allows fine-tuning the exact prompt (caption, lyrics, metadata) that the LM sees before generating audio codes.\n"
  },
  {
    "path": "docs/en/GPU_COMPATIBILITY.md",
    "content": "# GPU Compatibility Guide\n\nACE-Step 1.5 automatically adapts to your GPU's available VRAM, adjusting generation limits, LM model availability, offloading strategies, and UI defaults accordingly. The system detects GPU memory at startup and configures optimal settings for your hardware.\n\n## GPU Tier Configuration\n\n| VRAM | Tier | LM Models | Recommended LM | Backend | Max Duration (LM / No LM) | Max Batch (LM / No LM) | Offload | Quantization |\n|------|------|-----------|-----------------|---------|----------------------------|-------------------------|---------|--------------|\n| ≤4GB | Tier 1 | None | — | pt | 4 min / 6 min | 1 / 1 | CPU + DiT | INT8 |\n| 4-6GB | Tier 2 | None | — | pt | 8 min / 10 min | 1 / 1 | CPU + DiT | INT8 |\n| 6-8GB | Tier 3 | 0.6B | 0.6B | pt | 8 min / 10 min | 2 / 2 | CPU + DiT | INT8 |\n| 8-12GB | Tier 4 | 0.6B | 0.6B | vllm | 8 min / 10 min | 2 / 4 | CPU + DiT | INT8 |\n| 12-16GB | Tier 5 | 0.6B, 1.7B | 1.7B | vllm | 8 min / 10 min | 4 / 4 | CPU | INT8 |\n| 16-20GB | Tier 6a | 0.6B, 1.7B | 1.7B | vllm | 8 min / 10 min | 4 / 8 | CPU | INT8 |\n| 20-24GB | Tier 6b | 0.6B, 1.7B, 4B | 1.7B | vllm | 8 min / 8 min | 8 / 8 | None | None |\n| ≥24GB | Unlimited | All (0.6B, 1.7B, 4B) | 4B | vllm | 10 min / 10 min | 8 / 8 | None | None |\n\n### Column Descriptions\n\n- **LM Models**: Which 5Hz Language Model sizes can be loaded on this tier\n- **Recommended LM**: The default LM model selected in the UI for this tier\n- **Backend**: LM inference backend (`vllm` for NVIDIA GPUs with sufficient VRAM, `pt` for PyTorch fallback, `mlx` for Apple Silicon)\n- **Offload**: Memory offloading strategy\n  - **CPU + DiT**: All models (DiT, VAE, Text Encoder) offloaded to CPU when not in use; DiT also offloaded between steps\n  - **CPU**: VAE and Text Encoder offloaded to CPU; DiT stays on GPU\n  - **None**: All models remain on GPU\n- **Quantization**: Whether INT8 weight quantization is enabled by default to reduce VRAM usage\n\n## Adaptive UI Defaults\n\nThe Gradio UI automatically configures itself based on the detected GPU tier:\n\n- **LM Initialization Checkbox**: Checked by default for tiers that support LM (Tier 3+), unchecked and disabled for Tier 1-2\n- **LM Model Path**: Pre-populated with the recommended model for your tier; dropdown only shows compatible models\n- **Backend Dropdown**: Restricted to `pt`/`mlx` on Tier 1-3 (vllm KV cache is too memory-hungry); all backends available on Tier 4+\n- **CPU Offload / DiT Offload**: Enabled by default on lower tiers, disabled on higher tiers\n- **Quantization**: Enabled by default on Tier 1-6a, disabled on Tier 6b+ (sufficient VRAM)\n- **Compile Model**: Enabled by default on all tiers (required for quantization)\n\nIf you manually select an incompatible option (e.g., trying to use vllm on a 6GB GPU), the system will warn you and automatically fall back to a compatible configuration.\n\n## Runtime Safety Features\n\n- **VRAM Guard**: Before each inference, the system estimates VRAM requirements and automatically reduces batch size if needed\n- **Adaptive VAE Decode**: Three-tier fallback: GPU tiled decode → GPU decode with CPU offload → full CPU decode\n- **Auto Chunk Size**: VAE decode chunk size adapts to available free VRAM (64/128/256/512/1024/1536)\n- **Duration/Batch Clamping**: If you request values exceeding your tier's limits, they are clamped with a warning\n\n## Notes\n\n- **Default settings** are automatically configured based on detected GPU memory\n- **LM Mode** refers to the Language Model used for Chain-of-Thought generation and audio understanding\n- **Flash Attention** is auto-detected and enabled when available\n- **Constrained Decoding**: When LM is initialized, the LM's duration generation is also constrained to the GPU tier's maximum duration limit, preventing out-of-memory errors during CoT generation\n- For GPUs with ≤6GB VRAM (Tier 1-2), LM initialization is disabled by default to preserve memory for the DiT model\n- You can manually override settings via command-line arguments or the Gradio UI\n\n> **Community Contributions Welcome**: The GPU tier configurations above are based on our testing across common hardware. If you find that your device's actual performance differs from these parameters (e.g., can handle longer durations or larger batch sizes), we welcome you to conduct more thorough testing and submit a PR to optimize these configurations in `acestep/gpu_config.py`. Your contributions help improve the experience for all users!\n\n## Memory Optimization Tips\n\n1. **Very Low VRAM (≤6GB)**: Use DiT-only mode without LM initialization. INT8 quantization and full CPU offload are mandatory. VAE decode may fall back to CPU automatically.\n2. **Low VRAM (6-8GB)**: The 0.6B LM model can be used with `pt` backend. Keep offload enabled.\n3. **Medium VRAM (8-16GB)**: Use the 0.6B or 1.7B LM model. `vllm` backend works well on Tier 4+.\n4. **High VRAM (16-24GB)**: Enable larger LM models (1.7B recommended). Quantization becomes optional on 20GB+.\n5. **Very High VRAM (≥24GB)**: All models fit without offloading or quantization. Use 4B LM for best quality.\n\n## Debug Mode: Simulating Different GPU Configurations\n\nFor testing and development, you can simulate different GPU memory sizes using the `MAX_CUDA_VRAM` environment variable:\n\n```bash\n# Simulate a 4GB GPU (Tier 1)\nMAX_CUDA_VRAM=4 uv run acestep\n\n# Simulate a 6GB GPU (Tier 2)\nMAX_CUDA_VRAM=6 uv run acestep\n\n# Simulate an 8GB GPU (Tier 4)\nMAX_CUDA_VRAM=8 uv run acestep\n\n# Simulate a 12GB GPU (Tier 5)\nMAX_CUDA_VRAM=12 uv run acestep\n\n# Simulate a 16GB GPU (Tier 6a)\nMAX_CUDA_VRAM=16 uv run acestep\n```\n\nWhen `MAX_CUDA_VRAM` is set, the system also calls `torch.cuda.set_per_process_memory_fraction()` to enforce a hard VRAM cap, making the simulation realistic even on high-end GPUs.\n\n### Automated Tier Testing\n\nInstead of manually testing each tier through the UI, use the `tier-test` mode of `profile_inference.py`:\n\n```bash\n# Test all tiers automatically\npython profile_inference.py --mode tier-test\n\n# Test specific tiers\npython profile_inference.py --mode tier-test --tiers 6 8 16\n\n# Test with LM enabled (where supported)\npython profile_inference.py --mode tier-test --tier-with-lm\n\n# Quick test (skip torch.compile for non-quantized tiers)\npython profile_inference.py --mode tier-test --tier-skip-compile\n```\n\nSee [BENCHMARK.md](BENCHMARK.md) for full documentation of the profiling tool.\n\nThis is useful for:\n- Testing GPU tier configurations on high-end hardware\n- Verifying that warnings and limits work correctly for each tier\n- Automated regression testing after modifying `acestep/gpu_config.py`\n- CI/CD validation of VRAM compatibility\n\n### Boundary Testing (Finding Minimum Tiers)\n\nUse `--tier-boundary` to empirically determine the minimum VRAM tier at which INT8 quantization and CPU offload can be safely disabled. For each tier, this runs up to three configurations:\n\n1. **default** — tier's standard settings (quantization + offload as configured)\n2. **no-quant** — same offload settings, but quantization disabled\n3. **no-offload** — no quantization AND no CPU offload (all models on GPU)\n\n```bash\n# Run boundary tests across all tiers\npython profile_inference.py --mode tier-test --tier-boundary\n\n# Test specific tiers with boundary testing\npython profile_inference.py --mode tier-test --tier-boundary --tiers 8 12 16 20 24\n\n# Boundary test with LM enabled (where supported)\npython profile_inference.py --mode tier-test --tier-boundary --tier-with-lm\n\n# Save results to JSON for further analysis\npython profile_inference.py --mode tier-test --tier-boundary --benchmark-output boundary_results.json\n```\n\nThe output includes a **Boundary Analysis** section showing the minimum tier for each capability:\n\n```\nBOUNDARY ANALYSIS\n=================\n  Capability                                    Min Tier   VRAM\n  ------------------------------------------------------------\n  No INT8 Quantization                          tier6b      20GB\n  No CPU Offload (all models on GPU)            tier6b      20GB\n  ------------------------------------------------------------\n```\n\n> **Note:** Boundary results are empirical and may vary based on DiT model variant (turbo vs base), whether LM is enabled, generation duration, and flash attention availability. Community contributions to refine these boundaries are welcome!\n\n### Batch Size Boundary Testing\n\nUse `--tier-batch-boundary` to find the maximum safe batch size for each tier by progressively testing batch sizes 1, 2, 4, 8:\n\n```bash\n# Run batch boundary tests with LM enabled\npython profile_inference.py --mode tier-test --tier-batch-boundary --tier-with-lm\n\n# Test specific tiers\npython profile_inference.py --mode tier-test --tier-batch-boundary --tier-with-lm --tiers 8 12 16 24\n```\n\nThis tests both with-LM and without-LM configurations and reports the maximum successful batch size per tier.\n"
  },
  {
    "path": "docs/en/GPU_TROUBLESHOOTING.md",
    "content": "# GPU Detection Troubleshooting Guide\n\nThis guide helps resolve \"No GPU detected, running on CPU\" errors.\n\n## Quick Diagnostic\n\nRun the diagnostic tool to identify your issue:\n\n```bash\npython scripts/check_gpu.py\n```\n\nThis will check your PyTorch installation, GPU availability, and environment configuration.\n\n## Common Issues and Solutions\n\n### Issue 1: AMD GPU Not Detected (ROCm)\n\n**Symptoms:**\n- You have an AMD GPU (RX 6000/7000/9000 series)\n- ROCm is installed\n- Still getting \"No GPU detected\"\n\n**Solution:**\n\n#### For RDNA3 GPUs (RX 7000/9000 series):\n\nThe `HSA_OVERRIDE_GFX_VERSION` environment variable is required:\n\n**Linux/macOS:**\n```bash\nexport HSA_OVERRIDE_GFX_VERSION=11.0.0  # For RX 7900 XT/XTX, RX 9070 XT\nexport HSA_OVERRIDE_GFX_VERSION=11.0.1  # For RX 7800 XT, RX 7700 XT\nexport HSA_OVERRIDE_GFX_VERSION=11.0.2  # For RX 7600\n```\n\n**Windows:**\n```cmd\nset HSA_OVERRIDE_GFX_VERSION=11.0.0\n```\n\nOr use the provided launcher scripts which set this automatically:\n```cmd\nstart_gradio_ui_rocm.bat\nstart_api_server_rocm.bat\n```\n\n#### For RDNA2 GPUs (RX 6000 series):\n\n```bash\nexport HSA_OVERRIDE_GFX_VERSION=10.3.0  # Linux/macOS\nset HSA_OVERRIDE_GFX_VERSION=10.3.0     # Windows\n```\n\n#### Verify ROCm Installation:\n\n```bash\n# Check if ROCm can see your GPU\nrocm-smi\n\n# Check PyTorch ROCm build\npython -c \"import torch; print(f'ROCm: {torch.version.hip}')\"\n```\n\n### Issue 2: CPU-Only PyTorch Installed\n\n**Symptoms:**\n- Diagnostic shows \"Build type: CPU-only\"\n\n**Solution:**\n\nYou need to reinstall PyTorch with GPU support.\n\n#### For AMD GPUs:\n\n**Windows (ROCm 7.2):**\nFollow the detailed instructions in `requirements-rocm.txt`:\n\n```cmd\n# 1. Install ROCm SDK components (see requirements-rocm.txt for full URLs)\npip install --no-cache-dir [ROCm SDK wheels...]\n\n# 2. Install PyTorch for ROCm\npip install --no-cache-dir [PyTorch ROCm wheel...]\n\n# 3. Install dependencies\npip install -r requirements-rocm.txt\n```\n\n**Linux (ROCm 6.0+):**\n```bash\npip install torch --index-url https://download.pytorch.org/whl/rocm6.0\npip install -r requirements-rocm-linux.txt\n```\n\n#### For NVIDIA GPUs:\n\n```bash\n# For CUDA 12.1 (check PyTorch website for latest version)\npip install torch --index-url https://download.pytorch.org/whl/cu121\n# Or for CUDA 12.4+:\n# pip install torch --index-url https://download.pytorch.org/whl/cu124\n```\n\n> **Note:** Check https://pytorch.org/get-started/locally/ for the latest CUDA version supported by PyTorch.\n\n### Issue 3: NVIDIA GPU Not Detected (CUDA)\n\n**Symptoms:**\n- You have an NVIDIA GPU\n- CUDA is installed\n- Still getting \"No GPU detected\"\n\n**Solution:**\n\n1. **Check NVIDIA drivers:**\n   ```bash\n   nvidia-smi\n   ```\n   \n   If this fails, install/update NVIDIA drivers from: https://www.nvidia.com/download/index.aspx\n\n2. **Check CUDA version compatibility:**\n   \n   The CUDA version in your PyTorch build must be compatible with your driver.\n   \n   Check PyTorch CUDA version:\n   ```bash\n   python -c \"import torch; print(f'CUDA: {torch.version.cuda}')\"\n   ```\n   \n   Check driver CUDA version:\n   ```bash\n   nvidia-smi  # Look for \"CUDA Version: X.X\"\n   ```\n\n3. **Reinstall PyTorch if needed:**\n   ```bash\n   pip uninstall torch torchvision torchaudio\n   # Check https://pytorch.org/get-started/locally/ for the latest CUDA version\n   pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu121\n   ```\n\n### Issue 4: WSL2 GPU Access Issues\n\n**Symptoms:**\n- Running in WSL2 (Windows Subsystem for Linux)\n- GPU not detected\n\n**Solution:**\n\nFor NVIDIA GPUs in WSL2, you need CUDA on WSL2:\n1. Install NVIDIA drivers on Windows (not in WSL2)\n2. Install CUDA toolkit in WSL2\n3. Follow: https://docs.nvidia.com/cuda/wsl-user-guide/index.html\n\nFor AMD GPUs, ROCm support in WSL2 is limited. Consider:\n- Running on native Linux\n- Using Windows with `start_gradio_ui_rocm.bat` / `start_api_server_rocm.bat`\n\n## GPU-Specific Configuration\n\n### RX 9070 XT (RDNA3)\n\n```bash\n# Linux/macOS\nexport HSA_OVERRIDE_GFX_VERSION=11.0.0\nexport MIOPEN_FIND_MODE=FAST\n\n# Windows (or use start_gradio_ui_rocm.bat / start_api_server_rocm.bat)\nset HSA_OVERRIDE_GFX_VERSION=11.0.0\nset MIOPEN_FIND_MODE=FAST\n```\n\n### RX 7900 XT/XTX (RDNA3)\n\nSame as RX 9070 XT above.\n\n### RX 6900 XT (RDNA2)\n\n```bash\n# Linux/macOS\nexport HSA_OVERRIDE_GFX_VERSION=10.3.0\n\n# Windows\nset HSA_OVERRIDE_GFX_VERSION=10.3.0\n```\n\n## Additional Resources\n\n- **ROCm Linux Setup:** See `docs/en/ACE-Step1.5-Rocm-Manual-Linux.md`\n- **ROCm Windows Setup:** See `requirements-rocm.txt`\n- **GPU Tiers:** See `docs/en/GPU_COMPATIBILITY.md`\n- **General Installation:** See `README.md`\n\n## Still Having Issues?\n\nIf none of the above solutions work:\n\n1. Run the diagnostic tool and save the output:\n   ```bash\n   python scripts/check_gpu.py > gpu_diagnostic.txt\n   ```\n\n2. Open an issue on GitHub with:\n   - The diagnostic output\n   - Your GPU model\n   - Your OS (Windows/Linux/macOS)\n   - ROCm/CUDA version installed\n\n## Environment Variables Reference\n\n### ROCm (AMD GPUs)\n\n| Variable | Purpose | Example |\n|----------|---------|---------|\n| `HSA_OVERRIDE_GFX_VERSION` | Override GPU architecture | `11.0.0` (RDNA3), `10.3.0` (RDNA2) |\n| `MIOPEN_FIND_MODE` | MIOpen kernel selection mode | `FAST` (recommended) |\n| `TORCH_COMPILE_BACKEND` | PyTorch compilation backend | `eager` (ROCm Windows) |\n| `ACESTEP_LM_BACKEND` | Language model backend | `pt` (recommended for ROCm) |\n\n### CUDA (NVIDIA GPUs)\n\n| Variable | Purpose | Example |\n|----------|---------|---------|\n| `CUDA_VISIBLE_DEVICES` | Select which GPU to use | `0` (first GPU) |\n\n### ACE-Step Specific\n\n| Variable | Purpose | Example |\n|----------|---------|---------|\n| `MAX_CUDA_VRAM` | Override detected VRAM for tier simulation (also enforces hard VRAM cap via `set_per_process_memory_fraction`) | `8` (simulate 8GB GPU) |\n| `ACESTEP_VAE_ON_CPU` | Force VAE decode on CPU to save VRAM | `1` (enable) |\n\n> **Note on `MAX_CUDA_VRAM`**: When set, this variable not only changes the tier detection logic but also calls `torch.cuda.set_per_process_memory_fraction()` to enforce a hard VRAM limit. This means OOM errors during simulation are realistic and reflect actual behavior on GPUs with that amount of VRAM. See [GPU_COMPATIBILITY.md](GPU_COMPATIBILITY.md) for the full tier table.\n\n## LoRA Memory Issues (FIXED)\n\n### Issue: High VRAM Usage with LoRA (25-30GB)\n\n**Symptoms:**\n- Cannot use LoRA on 24GB VRAM GPUs (e.g., RTX 4090)\n- VRAM usage spikes to 25-30GB when loading LoRA\n- Out of memory errors during LoRA inference\n\n**Status:** ✅ **FIXED** (as of commit 731fabd)\n\n**Solution:**\n\nThis issue was caused by inefficient memory management in the LoRA lifecycle code. The fix replaces memory-heavy `deepcopy` operations with efficient `state_dict` backups stored on CPU.\n\n**Memory Usage:**\n- **Before fix**: 24-33GB VRAM (exceeds 24GB cards)\n- **After fix**: 14-18GB VRAM (fits on 24GB cards)\n- **Savings**: ~10-15GB VRAM per LoRA operation\n\n**What Changed:**\n- LoRA base model backup now stored on CPU (not GPU)\n- Uses `state_dict` (weights only) instead of `deepcopy` (full model)\n- Added memory diagnostics logging\n\n**Verify the Fix:**\n\nRun the validation script to confirm:\n```bash\npython scripts/validate_lora_memory.py\n```\n\nExpected output:\n```\n✓ No deepcopy found in load_lora/unload_lora\n✓ Using state_dict backup (memory-efficient)\n✓ Backing up to CPU (saves VRAM)\n✓ Memory diagnostics enabled\n```\n\n**Additional Information:**\n- Technical details: `docs/lora_memory_optimization.md`\n- Full fix summary: `docs/FIX_SUMMARY.md`\n- Unit tests: `tests/test_lora_lifecycle_memory.py`\n"
  },
  {
    "path": "docs/en/GRADIO_GUIDE.md",
    "content": "# ACE-Step Gradio Demo User Guide\n\n**Language / 语言 / 言語:** [English](GRADIO_GUIDE.md) | [中文](../zh/GRADIO_GUIDE.md) | [日本語](../ja/GRADIO_GUIDE.md)\n\n---\n\nThis guide provides comprehensive documentation for using the ACE-Step Gradio web interface for music generation, including all features and settings.\n\n## Table of Contents\n\n- [Getting Started](#getting-started)\n- [Service Configuration](#service-configuration)\n- [Generation Modes](#generation-modes)\n- [Input Parameters](#input-parameters)\n- [Advanced Settings](#advanced-settings)\n- [Results Section](#results-section)\n- [LoRA Training](#lora-training)\n- [Tips and Best Practices](#tips-and-best-practices)\n\n---\n\n## Getting Started\n\n### Launching the Demo\n\n```bash\n# Basic launch\npython app.py\n\n# With pre-initialization\npython app.py --config acestep-v15-turbo --init-llm\n\n# With specific port\npython app.py --port 7860\n```\n\n### Interface Overview\n\nThe Gradio interface is organized as follows:\n\n1. **Settings** (collapsed accordion) - Service configuration, DiT/LM parameters, output options\n2. **Generation Tab** - The main workspace with a **Generation Mode** radio selector:\n   - Turbo/SFT models: Simple, Custom, Remix, Repaint\n   - Base model: Simple, Custom, Remix, Repaint, Extract, Lego, Complete\n3. **Results Section** - Generated audio playback, scoring, batch navigation\n4. **Training Tab** - Dataset builder and LoRA training\n\n---\n\n## Service Configuration\n\n### Model Selection\n\n| Setting | Description |\n|---------|-------------|\n| **Checkpoint File** | Select a trained model checkpoint (if available) |\n| **Main Model Path** | Choose the DiT model configuration (e.g., `acestep-v15-turbo`, `acestep-v15-turbo-shift3`) |\n| **Device** | Processing device: `auto` (recommended), `cuda`, or `cpu` |\n\n### 5Hz LM Configuration\n\n| Setting | Description |\n|---------|-------------|\n| **5Hz LM Model Path** | Select the language model. **Available models are filtered by your GPU tier** — e.g., 6-8GB GPUs only show 0.6B, while 24GB+ GPUs show all sizes (0.6B, 1.7B, 4B). |\n| **5Hz LM Backend** | `vllm` (faster, recommended for NVIDIA with ≥8GB VRAM), `pt` (PyTorch, universal fallback), or `mlx` (Apple Silicon). **On GPUs <8GB, the backend is restricted to `pt`/`mlx`** because vllm's KV cache is too memory-hungry. |\n| **Initialize 5Hz LM** | Check to load the LM during initialization (required for thinking mode). **Automatically unchecked and disabled on GPUs ≤6GB** (Tier 1-2). |\n\n> **Adaptive Defaults**: All LM settings are automatically configured based on your GPU's VRAM tier. The recommended LM model, backend, and initialization state are pre-set for optimal performance. You can manually override these, but the system will warn you if your selection is incompatible with your GPU.\n\n### Performance Options\n\n| Setting | Description |\n|---------|-------------|\n| **Use Flash Attention** | Enable for faster inference (requires flash_attn package) |\n| **Offload to CPU** | Offload models to CPU when idle to save GPU memory. **Automatically enabled on GPUs <20GB.** |\n| **Offload DiT to CPU** | Specifically offload the DiT model to CPU. **Automatically enabled on GPUs <12GB.** |\n| **INT8 Quantization** | Reduce model VRAM footprint with INT8 weight quantization. **Automatically enabled on GPUs <20GB.** |\n| **Compile Model** | Enable `torch.compile` for optimized inference. **Enabled by default on all tiers** (required when quantization is active). |\n\n> **Tier-Aware Settings**: Offload, quantization, and compile options are automatically set based on your GPU tier. See [GPU_COMPATIBILITY.md](GPU_COMPATIBILITY.md) for the full tier table.\n\n### LoRA Adapter\n\n| Setting | Description |\n|---------|-------------|\n| **LoRA Path** | Path to trained LoRA adapter directory |\n| **Load LoRA** | Load the specified LoRA adapter |\n| **Unload** | Remove the currently loaded LoRA |\n| **Use LoRA** | Enable/disable the loaded LoRA for inference |\n\n> **⚠️ Note:** LoRA adapters cannot be loaded on quantized models due to a compatibility issue between PEFT and TorchAO. If you need to use LoRA, set **INT8 Quantization** to **None** before loading the adapter.\n\n### Initialization\n\nClick **Initialize Service** to load the models. The status box will show progress and confirmation, including:\n- The detected GPU tier and VRAM\n- Maximum allowed duration and batch size (adjusted dynamically based on whether LM was initialized)\n- Any warnings about incompatible settings that were automatically corrected\n\nAfter initialization, the **Audio Duration** and **Batch Size** sliders are automatically updated to reflect the tier's limits.\n\n---\n\n## Generation Modes\n\nThe **Generation Mode** radio selector at the top of the Generation tab determines your workflow. Turbo and SFT models offer four modes; Base models add three more.\n\n### Simple Mode\n\nDesigned for quick, natural language-based music generation.\n\n**How to use:**\n1. Select **Simple** in the Generation Mode radio\n2. Enter a natural language description in the \"Song Description\" field\n3. Optionally check \"Instrumental\" if you don't want vocals\n4. Optionally select a preferred vocal language\n5. Click **Create Sample** to generate caption, lyrics, and metadata\n6. Review the generated content in the expanded sections\n7. Click **Generate Music** to create the audio\n\n**Example descriptions:**\n- \"a soft Bengali love song for a quiet evening\"\n- \"upbeat electronic dance music with heavy bass drops\"\n- \"melancholic indie folk with acoustic guitar\"\n- \"jazz trio playing in a smoky bar\"\n\n**Random Sample:** Click the 🎲 button to load a random example description.\n\n### Custom Mode\n\nFull control over all generation parameters (text2music).\n\n**How to use:**\n1. Select **Custom** in the Generation Mode radio\n2. Manually fill in the Caption and Lyrics fields\n3. Optionally upload Reference Audio for style guidance\n4. Set optional metadata (BPM, Key, Duration, etc.)\n5. Optionally click **Format** to enhance your input using the LM\n6. Configure advanced settings as needed\n7. Click **Generate Music** to create the audio\n\n### Remix Mode\n\nTransform existing audio while maintaining its melodic structure but changing style.\n\n**How to use:**\n1. Select **Remix** in the Generation Mode radio\n2. Upload Source Audio (the song to remix)\n3. Write a Caption describing the target style\n4. Optionally modify Lyrics\n5. Adjust **Remix Strength** (0.0-1.0): higher = closer to original structure\n6. Click **Generate Music**\n\n**Use cases:** Creating cover versions, style transfer, generating variants of a song.\n\n### Repaint Mode\n\nRegenerate a specific time segment of audio while keeping the rest intact.\n\n**How to use:**\n1. Select **Repaint** in the Generation Mode radio\n2. Upload Source Audio\n3. Set **Repainting Start** and **Repainting End** (seconds; -1 for end of file)\n4. Write a Caption describing the desired content for the repainted section\n5. Click **Generate Music**\n\n**Use cases:** Fixing problematic sections, changing lyrics in a segment, extending songs.\n\n### Extract Mode (Base Model Only)\n\nExtract/isolate a specific instrument track from mixed audio.\n\n**How to use:**\n1. Select **Extract** in the Generation Mode radio\n2. Upload Source Audio\n3. Select the **Track Name** to extract from the dropdown\n4. Click **Generate Music**\n\n**Available tracks:** vocals, backing_vocals, drums, bass, guitar, keyboard, percussion, strings, synth, fx, brass, woodwinds\n\n### Lego Mode (Base Model Only)\n\nAdd a new instrument track to existing audio.\n\n**How to use:**\n1. Select **Lego** in the Generation Mode radio\n2. Upload Source Audio\n3. Select the **Track Name** to add from the dropdown\n4. Write a Caption describing the track characteristics\n5. Click **Generate Music**\n\n### Complete Mode (Base Model Only)\n\nComplete partial tracks with specified instruments (auto-arrangement).\n\n**How to use:**\n1. Select **Complete** in the Generation Mode radio\n2. Upload Source Audio\n3. Select multiple **Track Names** to add\n4. Write a Caption describing the desired style\n5. Click **Generate Music**\n\n---\n\n## Input Parameters\n\n### Audio Inputs\n\n| Field | Description |\n|-------|-------------|\n| **Reference Audio** | Optional audio for style/timbre guidance (visible in Custom mode) |\n| **Source Audio** | Required for Remix, Repaint, Extract, Lego, Complete modes |\n| **Convert to Codes** | Extract 5Hz semantic codes from source audio |\n\n#### LM Codes Hints (Custom Mode)\n\nPre-computed audio semantic codes can be pasted here to guide generation. Use the **Transcribe** button to analyze codes and extract metadata. This is an advanced feature for controlling melodic structure without uploading source audio.\n\n### Music Caption\n\nThe text description of the desired music. Be specific about:\n- Genre and style\n- Instruments\n- Mood and atmosphere\n- Tempo feel (if not specifying BPM)\n\n**Example:** \"upbeat pop rock with electric guitars, driving drums, and catchy synth hooks\"\n\nClick 🎲 to load a random example caption.\n\n### Lyrics\n\nEnter lyrics with structure tags:\n\n```\n[Verse 1]\nWalking down the street today\nThinking of the words you used to say\n\n[Chorus]\nI'm moving on, I'm staying strong\nThis is where I belong\n\n[Verse 2]\n...\n```\n\n**Instrumental checkbox:** Check this to generate instrumental music regardless of lyrics content.\n\n**Vocal Language:** Select the language for vocals. Use \"unknown\" for auto-detection or instrumental tracks.\n\n**Format button:** Click to enhance caption and lyrics using the 5Hz LM.\n\n### Optional Parameters\n\n| Parameter | Default | Description |\n|-----------|---------|-------------|\n| **BPM** | Auto | Tempo in beats per minute (30-300) |\n| **Key Scale** | Auto | Musical key (e.g., \"C Major\", \"Am\", \"F# minor\") |\n| **Time Signature** | Auto | Time signature: 2 (2/4), 3 (3/4), 4 (4/4), 6 (6/8) |\n| **Audio Duration** | Auto/-1 | Target length in seconds (10-600). -1 for automatic |\n| **Batch Size** | 2 | Number of audio variations to generate (1-8). **Value persists across mode changes and enhancement actions**. Can be set via `--batch_size` CLI argument |\n\n---\n\n## Advanced Settings\n\n### DiT Parameters\n\n| Parameter | Default | Description |\n|-----------|---------|-------------|\n| **Inference Steps** | 8 | Denoising steps. Turbo: 1-20, Base: 1-200 |\n| **Guidance Scale** | 7.0 | CFG strength (base model only). Higher = follows prompt more |\n| **Seed** | -1 | Random seed. Use comma-separated values for batches |\n| **Random Seed** | ✓ | When checked, generates random seeds |\n| **Audio Format** | mp3 | Output format: mp3, flac |\n| **Shift** | 3.0 | Timestep shift factor (1.0-5.0). Recommended 3.0 for turbo |\n| **Inference Method** | ode | ode (Euler, faster) or sde (stochastic) |\n| **Custom Timesteps** | - | Override timesteps (e.g., \"0.97,0.76,0.615,0.5,0.395,0.28,0.18,0.085,0\") |\n\n### Base Model Only Parameters\n\n| Parameter | Default | Description |\n|-----------|---------|-------------|\n| **Use ADG** | ✗ | Enable Adaptive Dual Guidance for better quality |\n| **CFG Interval Start** | 0.0 | When to start applying CFG (0.0-1.0) |\n| **CFG Interval End** | 1.0 | When to stop applying CFG (0.0-1.0) |\n\n### LM Parameters\n\n| Parameter | Default | Description |\n|-----------|---------|-------------|\n| **LM Temperature** | 0.85 | Sampling temperature (0.0-2.0). Higher = more creative |\n| **LM CFG Scale** | 2.0 | LM guidance strength (1.0-3.0) |\n| **LM Top-K** | 0 | Top-K sampling. 0 disables |\n| **LM Top-P** | 0.9 | Nucleus sampling (0.0-1.0) |\n| **LM Negative Prompt** | \"NO USER INPUT\" | Negative prompt for CFG |\n\n### CoT (Chain-of-Thought) Options\n\n| Option | Default | Description |\n|--------|---------|-------------|\n| **CoT Metas** | ✓ | Generate metadata via LM reasoning |\n| **CoT Language** | ✓ | Detect vocal language via LM |\n| **Constrained Decoding Debug** | ✗ | Enable debug logging |\n\n### Generation Options\n\n| Option | Default | Description |\n|--------|---------|-------------|\n| **LM Codes Strength** | 1.0 | How strongly LM codes influence generation (0.0-1.0) |\n| **Auto Score** | ✗ | Automatically calculate quality scores |\n| **Auto LRC** | ✗ | Automatically generate lyrics timestamps |\n| **LM Batch Chunk Size** | 8 | Max items per LM batch (GPU memory) |\n\n### Main Generation Controls\n\n| Control | Description |\n|---------|-------------|\n| **Think** | Enable 5Hz LM for code generation and metadata |\n| **ParallelThinking** | Enable parallel LM batch processing |\n| **CaptionRewrite** | Let LM enhance the input caption |\n| **AutoGen** | Automatically start next batch after completion |\n\n---\n\n## Results Section\n\n### Generated Audio\n\nUp to 8 audio samples are displayed based on batch size. Each sample includes:\n\n- **Audio Player** - Play, pause, and download the generated audio\n- **Send To Src** - Send this audio to the Source Audio input for further processing\n- **Save** - Save audio and metadata to a JSON file\n- **Score** - Calculate perplexity-based quality score\n- **LRC** - Generate lyrics timestamps (LRC format)\n\n### Details Accordion\n\nClick \"Score & LRC & LM Codes\" to expand and view:\n- **LM Codes** - The 5Hz semantic codes for this sample\n- **Quality Score** - Perplexity-based quality metric\n- **Lyrics Timestamps** - LRC format timing data\n\n### Batch Navigation\n\n| Control | Description |\n|---------|-------------|\n| **◀ Previous** | View the previous batch |\n| **Batch Indicator** | Shows current batch position (e.g., \"Batch 1 / 3\") |\n| **Next Batch Status** | Shows background generation progress |\n| **Next ▶** | View the next batch (triggers generation if AutoGen is on) |\n\n### Restore Parameters\n\nClick **Apply These Settings to UI** to restore all generation parameters from the current batch back to the input fields. Useful for iterating on a good result.\n\n### Batch Results\n\nThe \"Batch Results & Generation Details\" accordion contains:\n- **All Generated Files** - Download all files from all batches\n- **Generation Details** - Detailed information about the generation process\n\n---\n\n## LoRA Training\n\nThe LoRA Training tab provides tools for creating custom LoRA adapters.\n\n> 📖 **For a comprehensive step-by-step walkthrough** (data preparation, annotation, preprocessing, training, and export), see the [LoRA Training Tutorial](./LoRA_Training_Tutorial.md).\n\n### Dataset Builder Tab\n\n#### Step 1: Load or Scan\n\n**Option A: Load Existing Dataset**\n1. Enter the path to a previously saved dataset JSON\n2. Click **Load**\n\n**Option B: Scan New Directory**\n1. Enter the path to your audio folder\n2. Click **Scan** to find audio files (wav, mp3, flac, ogg, opus)\n\n#### Step 2: Configure Dataset\n\n| Setting | Description |\n|---------|-------------|\n| **Dataset Name** | Name for your dataset |\n| **All Instrumental** | Check if all tracks have no vocals |\n| **Custom Activation Tag** | Unique tag to activate this LoRA's style |\n| **Tag Position** | Where to place the tag: Prepend, Append, or Replace caption |\n\n#### Step 3: Auto-Label\n\nClick **Auto-Label All** to generate metadata for all audio files:\n- Caption (music description)\n- BPM\n- Key\n- Time Signature\n\n**Skip Metas** option will skip LLM labeling and use N/A values.\n\n#### Step 4: Preview & Edit\n\nUse the slider to select samples and manually edit:\n- Caption\n- Lyrics\n- BPM, Key, Time Signature\n- Language\n- Instrumental flag\n\nClick **Save Changes** to update the sample.\n\n#### Step 5: Save Dataset\n\nEnter a save path and click **Save Dataset** to export as JSON.\n\n#### Step 6: Preprocess\n\nConvert the dataset to pre-computed tensors for fast training:\n1. Optionally load an existing dataset JSON\n2. Set the tensor output directory\n3. Click **Preprocess**\n\nThis encodes audio to VAE latents, text to embeddings, and runs the condition encoder.\n\n### Train LoRA Tab\n\n#### Dataset Selection\n\nEnter the path to preprocessed tensors directory and click **Load Dataset**.\n\n#### LoRA Settings\n\n| Setting | Default | Description |\n|---------|---------|-------------|\n| **LoRA Rank (r)** | 64 | Capacity of LoRA. Higher = more capacity, more memory |\n| **LoRA Alpha** | 128 | Scaling factor (typically 2x rank) |\n| **LoRA Dropout** | 0.1 | Dropout rate for regularization |\n\n#### Training Parameters\n\n| Setting | Default | Description |\n|---------|---------|-------------|\n| **Learning Rate** | 1e-4 | Optimization learning rate |\n| **Max Epochs** | 500 | Maximum training epochs |\n| **Batch Size** | 1 | Training batch size |\n| **Gradient Accumulation** | 1 | Effective batch = batch_size × accumulation |\n| **Save Every N Epochs** | 200 | Checkpoint save frequency |\n| **Shift** | 3.0 | Timestep shift for turbo model |\n| **Seed** | 42 | Random seed for reproducibility |\n\n#### Training Controls\n\n- **Start Training** - Begin the training process\n- **Stop Training** - Interrupt training\n- **Training Progress** - Shows current epoch and loss\n- **Training Log** - Detailed training output\n- **Training Loss Plot** - Visual loss curve\n\n#### Export LoRA\n\nAfter training, export the final adapter:\n1. Enter the export path\n2. Click **Export LoRA**\n\n#### Performance notes (Windows / low VRAM)\n\nOn Windows or systems with limited VRAM, training and preprocessing can stall or use more memory than expected. The following can help:\n\n- **Persistent workers** – Epoch-boundary worker reinitialization on Windows can cause long pauses; the default behavior has been improved (see related fixes) so stalls are less common out of the box.\n- **Offload unused models** – During preprocessing, offloading models that are not needed for the current step (e.g. via **Offload to CPU** in Service Configuration) can greatly reduce VRAM use and avoid spikes that slow or block preprocessing.\n- **Tiled encode** – Using tiled encoding for preprocessing reduces peak VRAM and can turn multi-minute preprocessing into much shorter runs when VRAM is tight.\n- **Batch size** – Lower batch size during training reduces memory use at the cost of longer training; gradient accumulation can keep effective batch size while staying within VRAM limits.\n\nThese options are especially useful when preprocessing takes a long time or you see out-of-memory or long pauses between epochs.\n\n---\n\n## Tips and Best Practices\n\n### For Best Quality\n\n1. **Use thinking mode** - Keep \"Think\" checkbox enabled for LM-enhanced generation\n2. **Be specific in captions** - Include genre, instruments, mood, and style details\n3. **Let LM detect metadata** - Leave BPM/Key/Duration empty for auto-detection\n4. **Use batch generation** - Generate 2-4 variations and pick the best\n\n### For Faster Generation\n\n1. **Use turbo model** - Select `acestep-v15-turbo` or `acestep-v15-turbo-shift3`\n2. **Keep inference steps at 8** - Default is optimal for turbo\n3. **Reduce batch size** - Lower batch size if you need quick results\n4. **Disable AutoGen** - Manual control over batch generation\n\n### For Consistent Results\n\n1. **Set a specific seed** - Uncheck \"Random Seed\" and enter a seed value\n2. **Save good results** - Use \"Save\" to export parameters for reproduction\n3. **Use \"Apply These Settings\"** - Restore parameters from a good batch\n\n### For Long-form Music\n\n1. **Set explicit duration** - Specify duration in seconds\n2. **Use repaint task** - Fix problematic sections after initial generation\n3. **Chain generations** - Use \"Send To Src\" to build upon previous results\n\n### For Style Consistency\n\n1. **Train a LoRA** - Create a custom adapter for your style\n2. **Use reference audio** - Upload style reference in Audio Uploads\n3. **Use consistent captions** - Maintain similar descriptive language\n\n### Troubleshooting\n\n**No audio generated:**\n- Check that the model is initialized (green status message)\n- Ensure 5Hz LM is initialized if using thinking mode\n- Check the status output for error messages\n\n**Poor quality results:**\n- Increase inference steps (for base model)\n- Adjust guidance scale\n- Try different seeds\n- Make caption more specific\n\n**Out of memory:**\n- The system includes automatic VRAM management (VRAM guard, adaptive VAE decode, auto batch reduction). If OOM still occurs:\n- Reduce batch size manually\n- Enable CPU offloading (should be auto-enabled for GPUs <20GB)\n- Enable INT8 quantization (should be auto-enabled for GPUs <20GB)\n- Reduce LM batch chunk size\n- See [GPU_COMPATIBILITY.md](GPU_COMPATIBILITY.md) for recommended settings per tier\n\n**LM not working:**\n- Ensure \"Initialize 5Hz LM\" was checked during initialization (disabled by default on GPUs ≤6GB)\n- Check that a valid LM model path is selected (only tier-compatible models are shown)\n- Verify vllm or PyTorch backend is available (vllm restricted on GPUs <8GB)\n- If the LM checkbox is grayed out, your GPU tier does not support LM — use DiT-only mode\n\n---\n\n## Keyboard Shortcuts\n\nThe Gradio interface supports standard web shortcuts:\n- **Tab** - Move between input fields\n- **Enter** - Submit text inputs\n- **Space** - Toggle checkboxes\n\n---\n\n## Language Support\n\nThe interface supports multiple UI languages:\n- **English** (en)\n- **Chinese** (zh)\n- **Japanese** (ja)\n\nSelect your preferred language in the Service Configuration section.\n\n---\n\nFor more information, see:\n- Main README: [`../../README.md`](../../README.md)\n- REST API Documentation: [`API.md`](API.md)\n- Python Inference API: [`INFERENCE.md`](INFERENCE.md)\n"
  },
  {
    "path": "docs/en/INFERENCE.md",
    "content": "# ACE-Step Inference API Documentation\n\n**Language / 语言 / 言語:** [English](INFERENCE.md) | [中文](../zh/INFERENCE.md) | [日本語](../ja/INFERENCE.md)\n\n---\n\nThis document provides comprehensive documentation for the ACE-Step inference API, including parameter specifications for all supported task types.\n\n## Table of Contents\n\n- [Quick Start](#quick-start)\n- [API Overview](#api-overview)\n- [GenerationParams Parameters](#generationparams-parameters)\n- [GenerationConfig Parameters](#generationconfig-parameters)\n- [Task Types](#task-types)\n- [Helper Functions](#helper-functions)\n- [Complete Examples](#complete-examples)\n- [Best Practices](#best-practices)\n\n---\n\n## Quick Start\n\n### Basic Usage\n\n```python\nfrom acestep.handler import AceStepHandler\nfrom acestep.llm_inference import LLMHandler\nfrom acestep.inference import GenerationParams, GenerationConfig, generate_music\n\n# Initialize handlers\ndit_handler = AceStepHandler()\nllm_handler = LLMHandler()\n\n# Initialize services\ndit_handler.initialize_service(\n    project_root=\"/path/to/project\",\n    config_path=\"acestep-v15-turbo\",\n    device=\"cuda\"\n)\n\nllm_handler.initialize(\n    checkpoint_dir=\"/path/to/checkpoints\",\n    lm_model_path=\"acestep-5Hz-lm-0.6B\",\n    backend=\"vllm\",\n    device=\"cuda\"\n)\n\n# Configure generation parameters\nparams = GenerationParams(\n    caption=\"upbeat electronic dance music with heavy bass\",\n    bpm=128,\n    duration=30,\n)\n\n# Configure generation settings\nconfig = GenerationConfig(\n    batch_size=2,\n    audio_format=\"flac\",\n)\n\n# Generate music\nresult = generate_music(dit_handler, llm_handler, params, config, save_dir=\"/path/to/output\")\n\n# Access results\nif result.success:\n    for audio in result.audios:\n        print(f\"Generated: {audio['path']}\")\n        print(f\"Key: {audio['key']}\")\n        print(f\"Seed: {audio['params']['seed']}\")\nelse:\n    print(f\"Error: {result.error}\")\n```\n\n---\n\n## API Overview\n\n### Main Functions\n\n#### generate_music\n\n```python\ndef generate_music(\n    dit_handler,\n    llm_handler,\n    params: GenerationParams,\n    config: GenerationConfig,\n    save_dir: Optional[str] = None,\n    progress=None,\n) -> GenerationResult\n```\n\nMain function for generating music using the ACE-Step model.\n\n#### understand_music\n\n```python\ndef understand_music(\n    llm_handler,\n    audio_codes: str,\n    temperature: float = 0.85,\n    top_k: Optional[int] = None,\n    top_p: Optional[float] = None,\n    repetition_penalty: float = 1.0,\n    use_constrained_decoding: bool = True,\n    constrained_decoding_debug: bool = False,\n) -> UnderstandResult\n```\n\nAnalyze audio semantic codes and extract metadata (caption, lyrics, BPM, key, etc.).\n\n#### create_sample\n\n```python\ndef create_sample(\n    llm_handler,\n    query: str,\n    instrumental: bool = False,\n    vocal_language: Optional[str] = None,\n    temperature: float = 0.85,\n    top_k: Optional[int] = None,\n    top_p: Optional[float] = None,\n    repetition_penalty: float = 1.0,\n    use_constrained_decoding: bool = True,\n    constrained_decoding_debug: bool = False,\n) -> CreateSampleResult\n```\n\nGenerate a complete music sample (caption, lyrics, metadata) from a natural language description.\n\n#### format_sample\n\n```python\ndef format_sample(\n    llm_handler,\n    caption: str,\n    lyrics: str,\n    user_metadata: Optional[Dict[str, Any]] = None,\n    temperature: float = 0.85,\n    top_k: Optional[int] = None,\n    top_p: Optional[float] = None,\n    repetition_penalty: float = 1.0,\n    use_constrained_decoding: bool = True,\n    constrained_decoding_debug: bool = False,\n) -> FormatSampleResult\n```\n\nFormat and enhance user-provided caption and lyrics, generating structured metadata.\n\n### Configuration Objects\n\nThe API uses two configuration dataclasses:\n\n**GenerationParams** - Contains all music generation parameters:\n\n```python\n@dataclass\nclass GenerationParams:\n    # Task & Instruction\n    task_type: str = \"text2music\"\n    instruction: str = \"Fill the audio semantic mask based on the given conditions:\"\n    \n    # Audio Uploads\n    reference_audio: Optional[str] = None\n    src_audio: Optional[str] = None\n    \n    # LM Codes Hints\n    audio_codes: str = \"\"\n    \n    # Text Inputs\n    caption: str = \"\"\n    lyrics: str = \"\"\n    instrumental: bool = False\n    \n    # Metadata\n    vocal_language: str = \"unknown\"\n    bpm: Optional[int] = None\n    keyscale: str = \"\"\n    timesignature: str = \"\"\n    duration: float = -1.0\n    \n    # Advanced Settings\n    inference_steps: int = 8\n    seed: int = -1\n    guidance_scale: float = 7.0\n    use_adg: bool = False\n    cfg_interval_start: float = 0.0\n    cfg_interval_end: float = 1.0\n    shift: float = 1.0                    # NEW: Timestep shift factor\n    infer_method: str = \"ode\"             # NEW: Diffusion inference method\n    timesteps: Optional[List[float]] = None  # NEW: Custom timesteps\n    \n    repainting_start: float = 0.0\n    repainting_end: float = -1\n    audio_cover_strength: float = 1.0\n    \n    # 5Hz Language Model Parameters\n    thinking: bool = True\n    lm_temperature: float = 0.85\n    lm_cfg_scale: float = 2.0\n    lm_top_k: int = 0\n    lm_top_p: float = 0.9\n    lm_negative_prompt: str = \"NO USER INPUT\"\n    use_cot_metas: bool = True\n    use_cot_caption: bool = True\n    use_cot_lyrics: bool = False\n    use_cot_language: bool = True\n    use_constrained_decoding: bool = True\n    \n    # CoT Generated Values (auto-filled by LM)\n    cot_bpm: Optional[int] = None\n    cot_keyscale: str = \"\"\n    cot_timesignature: str = \"\"\n    cot_duration: Optional[float] = None\n    cot_vocal_language: str = \"unknown\"\n    cot_caption: str = \"\"\n    cot_lyrics: str = \"\"\n```\n\n**GenerationConfig** - Contains batch and output configuration:\n\n```python\n@dataclass\nclass GenerationConfig:\n    batch_size: int = 2\n    allow_lm_batch: bool = False\n    use_random_seed: bool = True\n    seeds: Optional[List[int]] = None\n    lm_batch_chunk_size: int = 8\n    constrained_decoding_debug: bool = False\n    audio_format: str = \"flac\"\n```\n\n### Result Objects\n\n**GenerationResult** - Result of music generation:\n\n```python\n@dataclass\nclass GenerationResult:\n    # Audio Outputs\n    audios: List[Dict[str, Any]]  # List of audio dictionaries\n    \n    # Generation Information\n    status_message: str           # Status message from generation\n    extra_outputs: Dict[str, Any] # Extra outputs (latents, masks, lm_metadata, time_costs)\n    \n    # Success Status\n    success: bool                 # Whether generation succeeded\n    error: Optional[str]          # Error message if failed\n```\n\n**Audio Dictionary Structure:**\n\nEach item in `audios` list contains:\n\n```python\n{\n    \"path\": str,           # File path to saved audio\n    \"tensor\": Tensor,      # Audio tensor [channels, samples], CPU, float32\n    \"key\": str,            # Unique audio key (UUID based on params)\n    \"sample_rate\": int,    # Sample rate (default: 48000)\n    \"params\": Dict,        # Generation params for this audio (includes seed, audio_codes, etc.)\n}\n```\n\n**UnderstandResult** - Result of music understanding:\n\n```python\n@dataclass\nclass UnderstandResult:\n    # Metadata Fields\n    caption: str = \"\"\n    lyrics: str = \"\"\n    bpm: Optional[int] = None\n    duration: Optional[float] = None\n    keyscale: str = \"\"\n    language: str = \"\"\n    timesignature: str = \"\"\n    \n    # Status\n    status_message: str = \"\"\n    success: bool = True\n    error: Optional[str] = None\n```\n\n**CreateSampleResult** - Result of sample creation:\n\n```python\n@dataclass\nclass CreateSampleResult:\n    # Metadata Fields\n    caption: str = \"\"\n    lyrics: str = \"\"\n    bpm: Optional[int] = None\n    duration: Optional[float] = None\n    keyscale: str = \"\"\n    language: str = \"\"\n    timesignature: str = \"\"\n    instrumental: bool = False\n    \n    # Status\n    status_message: str = \"\"\n    success: bool = True\n    error: Optional[str] = None\n```\n\n**FormatSampleResult** - Result of sample formatting:\n\n```python\n@dataclass\nclass FormatSampleResult:\n    # Metadata Fields\n    caption: str = \"\"\n    lyrics: str = \"\"\n    bpm: Optional[int] = None\n    duration: Optional[float] = None\n    keyscale: str = \"\"\n    language: str = \"\"\n    timesignature: str = \"\"\n    \n    # Status\n    status_message: str = \"\"\n    success: bool = True\n    error: Optional[str] = None\n```\n\n---\n\n## GenerationParams Parameters\n\n### Text Inputs\n\n| Parameter | Type | Default | Description |\n|-----------|------|---------|-------------|\n| `caption` | `str` | `\"\"` | Text description of the desired music. Can be a simple prompt like \"relaxing piano music\" or detailed description with genre, mood, instruments, etc. Max 512 characters. |\n| `lyrics` | `str` | `\"\"` | Lyrics text for vocal music. Use `\"[Instrumental]\"` for instrumental tracks. Supports multiple languages. Max 4096 characters. |\n| `instrumental` | `bool` | `False` | If True, generate instrumental music regardless of lyrics. |\n\n### Music Metadata\n\n| Parameter | Type | Default | Description |\n|-----------|------|---------|-------------|\n| `bpm` | `Optional[int]` | `None` | Beats per minute (30-300). `None` enables auto-detection via LM. |\n| `keyscale` | `str` | `\"\"` | Musical key (e.g., \"C Major\", \"Am\", \"F# minor\"). Empty string enables auto-detection. |\n| `timesignature` | `str` | `\"\"` | Time signature (2 for '2/4', 3 for '3/4', 4 for '4/4', 6 for '6/8'). Empty string enables auto-detection. |\n| `vocal_language` | `str` | `\"unknown\"` | Language code for vocals (ISO 639-1). Supported: `\"en\"`, `\"zh\"`, `\"ja\"`, `\"es\"`, `\"fr\"`, etc. Use `\"unknown\"` for auto-detection. |\n| `duration` | `float` | `-1.0` | Target audio length in seconds (10-600). If <= 0 or None, model chooses automatically based on lyrics length. |\n\n### Generation Parameters\n\n| Parameter | Type | Default | Description |\n|-----------|------|---------|-------------|\n| `inference_steps` | `int` | `8` | Number of denoising steps. Turbo model: 1-20 (recommended 8). Base model: 1-200 (recommended 32-64). Higher = better quality but slower. |\n| `guidance_scale` | `float` | `7.0` | Classifier-free guidance scale (1.0-15.0). Higher values increase adherence to text prompt. Only supported for non-turbo model. Typical range: 5.0-9.0. |\n| `seed` | `int` | `-1` | Random seed for reproducibility. Use `-1` for random seed, or any positive integer for fixed seed. |\n\n### Advanced DiT Parameters\n\n| Parameter | Type | Default | Description |\n|-----------|------|---------|-------------|\n| `use_adg` | `bool` | `False` | Use Adaptive Dual Guidance (base model only). Improves quality at the cost of speed. |\n| `cfg_interval_start` | `float` | `0.0` | CFG application start ratio (0.0-1.0). Controls when to start applying classifier-free guidance. |\n| `cfg_interval_end` | `float` | `1.0` | CFG application end ratio (0.0-1.0). Controls when to stop applying classifier-free guidance. |\n| `shift` | `float` | `1.0` | Timestep shift factor (range 1.0-5.0, default 1.0). When != 1.0, applies `t = shift * t / (1 + (shift - 1) * t)` to timesteps. Recommended 3.0 for turbo models. |\n| `infer_method` | `str` | `\"ode\"` | Diffusion inference method. `\"ode\"` (Euler) is faster and deterministic. `\"sde\"` (stochastic) may produce different results with variance. |\n| `timesteps` | `Optional[List[float]]` | `None` | Custom timesteps as a list of floats from 1.0 to 0.0 (e.g., `[0.97, 0.76, 0.615, 0.5, 0.395, 0.28, 0.18, 0.085, 0]`). If provided, overrides `inference_steps` and `shift`. |\n\n### Task-Specific Parameters\n\n| Parameter | Type | Default | Description |\n|-----------|------|---------|-------------|\n| `task_type` | `str` | `\"text2music\"` | Generation task type. See [Task Types](#task-types) section for details. |\n| `instruction` | `str` | `\"Fill the audio semantic mask based on the given conditions:\"` | Task-specific instruction prompt. |\n| `reference_audio` | `Optional[str]` | `None` | Path to reference audio file for style transfer or continuation tasks. |\n| `src_audio` | `Optional[str]` | `None` | Path to source audio file for audio-to-audio tasks (cover, repaint, etc.). |\n| `audio_codes` | `str` | `\"\"` | Pre-extracted 5Hz audio semantic codes as a string. Advanced use only. |\n| `repainting_start` | `float` | `0.0` | Repainting start time in seconds (for repaint/lego tasks). |\n| `repainting_end` | `float` | `-1` | Repainting end time in seconds. Use `-1` for end of audio. |\n| `audio_cover_strength` | `float` | `1.0` | Strength of audio cover/codes influence (0.0-1.0). Set smaller (0.2) for style transfer tasks. |\n\n### 5Hz Language Model Parameters\n\n| Parameter | Type | Default | Description |\n|-----------|------|---------|-------------|\n| `thinking` | `bool` | `True` | Enable 5Hz Language Model \"Chain-of-Thought\" reasoning for semantic/music metadata and codes. |\n| `lm_temperature` | `float` | `0.85` | LM sampling temperature (0.0-2.0). Higher = more creative/diverse, lower = more conservative. |\n| `lm_cfg_scale` | `float` | `2.0` | LM classifier-free guidance scale. Higher = stronger adherence to prompt. |\n| `lm_top_k` | `int` | `0` | LM top-k sampling. `0` disables top-k filtering. Typical values: 40-100. |\n| `lm_top_p` | `float` | `0.9` | LM nucleus sampling (0.0-1.0). `1.0` disables nucleus sampling. Typical values: 0.9-0.95. |\n| `lm_negative_prompt` | `str` | `\"NO USER INPUT\"` | Negative prompt for LM guidance. Helps avoid unwanted characteristics. |\n| `use_cot_metas` | `bool` | `True` | Generate metadata using LM CoT reasoning (BPM, key, duration, etc.). |\n| `use_cot_caption` | `bool` | `True` | Refine user caption using LM CoT reasoning. |\n| `use_cot_language` | `bool` | `True` | Detect vocal language using LM CoT reasoning. |\n| `use_cot_lyrics` | `bool` | `False` | (Reserved for future use) Generate/refine lyrics using LM CoT. |\n| `use_constrained_decoding` | `bool` | `True` | Enable constrained decoding for structured LM output. |\n\n### CoT Generated Values\n\nThese fields are automatically populated by the LM when CoT reasoning is enabled:\n\n| Parameter | Type | Default | Description |\n|-----------|------|---------|-------------|\n| `cot_bpm` | `Optional[int]` | `None` | LM-generated BPM value. |\n| `cot_keyscale` | `str` | `\"\"` | LM-generated key/scale. |\n| `cot_timesignature` | `str` | `\"\"` | LM-generated time signature. |\n| `cot_duration` | `Optional[float]` | `None` | LM-generated duration. |\n| `cot_vocal_language` | `str` | `\"unknown\"` | LM-detected vocal language. |\n| `cot_caption` | `str` | `\"\"` | LM-refined caption. |\n| `cot_lyrics` | `str` | `\"\"` | LM-generated/refined lyrics. |\n\n---\n\n## GenerationConfig Parameters\n\n| Parameter | Type | Default | Description |\n|-----------|------|---------|-------------|\n| `batch_size` | `int` | `2` | Number of samples to generate in parallel (1-8). Higher values require more GPU memory. |\n| `allow_lm_batch` | `bool` | `False` | Allow batch processing in LM. Faster when `batch_size >= 2` and `thinking=True`. |\n| `use_random_seed` | `bool` | `True` | Whether to use random seed. `True` for different results each time, `False` for reproducible results. |\n| `seeds` | `Optional[List[int]]` | `None` | List of seeds for batch generation. If provided, will be padded with random seeds if fewer than batch_size. Can also be single int. |\n| `lm_batch_chunk_size` | `int` | `8` | Maximum batch size per LM inference chunk (GPU memory constraint). |\n| `constrained_decoding_debug` | `bool` | `False` | Enable debug logging for constrained decoding. |\n| `audio_format` | `str` | `\"flac\"` | Output audio format. Options: `\"mp3\"`, `\"wav\"`, `\"flac\"`. Default is FLAC for fast saving. |\n\n---\n\n## Task Types\n\nACE-Step supports 6 different generation task types, each optimized for specific use cases.\n\n### 1. Text2Music (Default)\n\n**Purpose**: Generate music from text descriptions and optional metadata.\n\n**Key Parameters**:\n```python\nparams = GenerationParams(\n    task_type=\"text2music\",\n    caption=\"energetic rock music with electric guitar\",\n    lyrics=\"[Instrumental]\",  # or actual lyrics\n    bpm=140,\n    duration=30,\n)\n```\n\n**Required**:\n- `caption` or `lyrics` (at least one)\n\n**Optional but Recommended**:\n- `bpm`: Controls tempo\n- `keyscale`: Controls musical key\n- `timesignature`: Controls rhythm structure\n- `duration`: Controls length\n- `vocal_language`: Controls vocal characteristics\n\n**Use Cases**:\n- Generate music from text descriptions\n- Create backing tracks from prompts\n- Generate songs with lyrics\n\n---\n\n### 2. Cover\n\n**Purpose**: Transform existing audio while maintaining structure but changing style/timbre.\n\n**Key Parameters**:\n```python\nparams = GenerationParams(\n    task_type=\"cover\",\n    src_audio=\"original_song.mp3\",\n    caption=\"jazz piano version\",\n    audio_cover_strength=0.8,  # 0.0-1.0\n)\n```\n\n**Required**:\n- `src_audio`: Path to source audio file\n- `caption`: Description of desired style/transformation\n\n**Optional**:\n- `audio_cover_strength`: Controls influence of original audio\n  - `1.0`: Strong adherence to original structure\n  - `0.5`: Balanced transformation\n  - `0.1`: Loose interpretation\n- `lyrics`: New lyrics (if changing vocals)\n\n**Use Cases**:\n- Create covers in different styles\n- Change instrumentation while keeping melody\n- Genre transformation\n\n---\n\n### 3. Repaint\n\n**Purpose**: Regenerate a specific time segment of audio while keeping the rest unchanged.\n\n**Key Parameters**:\n```python\nparams = GenerationParams(\n    task_type=\"repaint\",\n    src_audio=\"original.mp3\",\n    repainting_start=10.0,  # seconds\n    repainting_end=20.0,    # seconds\n    caption=\"smooth transition with piano solo\",\n)\n```\n\n**Required**:\n- `src_audio`: Path to source audio file\n- `repainting_start`: Start time in seconds\n- `repainting_end`: End time in seconds (use `-1` for end of file)\n- `caption`: Description of desired content for repainted section\n\n**Use Cases**:\n- Fix specific sections of generated music\n- Add variations to parts of a song\n- Create smooth transitions\n- Replace problematic segments\n\n---\n\n### 4. Lego (Base Model Only)\n\n**Purpose**: Generate a specific instrument track in context of existing audio.\n\n**Key Parameters**:\n```python\nparams = GenerationParams(\n    task_type=\"lego\",\n    src_audio=\"backing_track.mp3\",\n    instruction=\"Generate the guitar track based on the audio context:\",\n    caption=\"lead guitar melody with bluesy feel\",\n    repainting_start=0.0,\n    repainting_end=-1,\n)\n```\n\n**Required**:\n- `src_audio`: Path to source/backing audio\n- `instruction`: Must specify the track type (e.g., \"Generate the {TRACK_NAME} track...\")\n- `caption`: Description of desired track characteristics\n\n**Available Tracks**:\n- `\"vocals\"`, `\"backing_vocals\"`, `\"drums\"`, `\"bass\"`, `\"guitar\"`, `\"keyboard\"`, \n- `\"percussion\"`, `\"strings\"`, `\"synth\"`, `\"fx\"`, `\"brass\"`, `\"woodwinds\"`\n\n**Use Cases**:\n- Add specific instrument tracks\n- Layer additional instruments over backing tracks\n- Create multi-track compositions iteratively\n\n---\n\n### 5. Extract (Base Model Only)\n\n**Purpose**: Extract/isolate a specific instrument track from mixed audio.\n\n**Key Parameters**:\n```python\nparams = GenerationParams(\n    task_type=\"extract\",\n    src_audio=\"full_mix.mp3\",\n    instruction=\"Extract the vocals track from the audio:\",\n)\n```\n\n**Required**:\n- `src_audio`: Path to mixed audio file\n- `instruction`: Must specify track to extract\n\n**Available Tracks**: Same as Lego task\n\n**Use Cases**:\n- Stem separation\n- Isolate specific instruments\n- Create remixes\n- Analyze individual tracks\n\n---\n\n### 6. Complete (Base Model Only)\n\n**Purpose**: Complete/extend partial tracks with specified instruments.\n\n**Key Parameters**:\n```python\nparams = GenerationParams(\n    task_type=\"complete\",\n    src_audio=\"incomplete_track.mp3\",\n    instruction=\"Complete the input track with drums, bass, guitar:\",\n    caption=\"rock style completion\",\n)\n```\n\n**Required**:\n- `src_audio`: Path to incomplete/partial track\n- `instruction`: Must specify which tracks to add\n- `caption`: Description of desired style\n\n**Use Cases**:\n- Arrange incomplete compositions\n- Add backing tracks\n- Auto-complete musical ideas\n\n---\n\n## Helper Functions\n\n### understand_music\n\nAnalyze audio codes to extract metadata about the music.\n\n```python\nfrom acestep.inference import understand_music\n\nresult = understand_music(\n    llm_handler=llm_handler,\n    audio_codes=\"<|audio_code_123|><|audio_code_456|>...\",\n    temperature=0.85,\n    use_constrained_decoding=True,\n)\n\nif result.success:\n    print(f\"Caption: {result.caption}\")\n    print(f\"Lyrics: {result.lyrics}\")\n    print(f\"BPM: {result.bpm}\")\n    print(f\"Key: {result.keyscale}\")\n    print(f\"Duration: {result.duration}s\")\n    print(f\"Language: {result.language}\")\nelse:\n    print(f\"Error: {result.error}\")\n```\n\n**Use Cases**:\n- Analyze existing music\n- Extract metadata from audio codes\n- Reverse-engineer generation parameters\n\n---\n\n### create_sample\n\nGenerate a complete music sample from a natural language description. This is the \"Simple Mode\" / \"Inspiration Mode\" feature.\n\n```python\nfrom acestep.inference import create_sample\n\nresult = create_sample(\n    llm_handler=llm_handler,\n    query=\"a soft Bengali love song for a quiet evening\",\n    instrumental=False,\n    vocal_language=\"bn\",  # Optional: constrain to Bengali\n    temperature=0.85,\n)\n\nif result.success:\n    print(f\"Caption: {result.caption}\")\n    print(f\"Lyrics: {result.lyrics}\")\n    print(f\"BPM: {result.bpm}\")\n    print(f\"Duration: {result.duration}s\")\n    print(f\"Key: {result.keyscale}\")\n    print(f\"Is Instrumental: {result.instrumental}\")\n    \n    # Use with generate_music\n    params = GenerationParams(\n        caption=result.caption,\n        lyrics=result.lyrics,\n        bpm=result.bpm,\n        duration=result.duration,\n        keyscale=result.keyscale,\n        vocal_language=result.language,\n    )\nelse:\n    print(f\"Error: {result.error}\")\n```\n\n**Parameters**:\n\n| Parameter | Type | Default | Description |\n|-----------|------|---------|-------------|\n| `query` | `str` | required | Natural language description of desired music |\n| `instrumental` | `bool` | `False` | Whether to generate instrumental music |\n| `vocal_language` | `Optional[str]` | `None` | Constrain lyrics to specific language (e.g., \"en\", \"zh\", \"bn\") |\n| `temperature` | `float` | `0.85` | Sampling temperature |\n| `top_k` | `Optional[int]` | `None` | Top-k sampling (None disables) |\n| `top_p` | `Optional[float]` | `None` | Top-p sampling (None disables) |\n| `repetition_penalty` | `float` | `1.0` | Repetition penalty |\n| `use_constrained_decoding` | `bool` | `True` | Use FSM-based constrained decoding |\n\n---\n\n### format_sample\n\nFormat and enhance user-provided caption and lyrics, generating structured metadata.\n\n```python\nfrom acestep.inference import format_sample\n\nresult = format_sample(\n    llm_handler=llm_handler,\n    caption=\"Latin pop, reggaeton\",\n    lyrics=\"[Verse 1]\\nBailando en la noche...\",\n    user_metadata={\"bpm\": 95},  # Optional: constrain specific values\n    temperature=0.85,\n)\n\nif result.success:\n    print(f\"Enhanced Caption: {result.caption}\")\n    print(f\"Formatted Lyrics: {result.lyrics}\")\n    print(f\"BPM: {result.bpm}\")\n    print(f\"Duration: {result.duration}s\")\n    print(f\"Key: {result.keyscale}\")\n    print(f\"Detected Language: {result.language}\")\nelse:\n    print(f\"Error: {result.error}\")\n```\n\n**Parameters**:\n\n| Parameter | Type | Default | Description |\n|-----------|------|---------|-------------|\n| `caption` | `str` | required | User's caption/description |\n| `lyrics` | `str` | required | User's lyrics with structure tags |\n| `user_metadata` | `Optional[Dict]` | `None` | Constrain specific metadata values (bpm, duration, keyscale, timesignature, language) |\n| `temperature` | `float` | `0.85` | Sampling temperature |\n| `top_k` | `Optional[int]` | `None` | Top-k sampling (None disables) |\n| `top_p` | `Optional[float]` | `None` | Top-p sampling (None disables) |\n| `repetition_penalty` | `float` | `1.0` | Repetition penalty |\n| `use_constrained_decoding` | `bool` | `True` | Use FSM-based constrained decoding |\n\n---\n\n## Complete Examples\n\n### Example 1: Simple Text-to-Music Generation\n\n```python\nfrom acestep.inference import GenerationParams, GenerationConfig, generate_music\n\nparams = GenerationParams(\n    task_type=\"text2music\",\n    caption=\"calm ambient music with soft piano and strings\",\n    duration=60,\n    bpm=80,\n    keyscale=\"C Major\",\n)\n\nconfig = GenerationConfig(\n    batch_size=2,  # Generate 2 variations\n    audio_format=\"flac\",\n)\n\nresult = generate_music(dit_handler, llm_handler, params, config, save_dir=\"/output\")\n\nif result.success:\n    for i, audio in enumerate(result.audios, 1):\n        print(f\"Variation {i}: {audio['path']}\")\n```\n\n### Example 2: Song Generation with Lyrics\n\n```python\nparams = GenerationParams(\n    task_type=\"text2music\",\n    caption=\"pop ballad with emotional vocals\",\n    lyrics=\"\"\"Verse 1:\nWalking down the street today\nThinking of the words you used to say\nEverything feels different now\nBut I'll find my way somehow\n\nChorus:\nI'm moving on, I'm staying strong\nThis is where I belong\n\"\"\",\n    vocal_language=\"en\",\n    bpm=72,\n    duration=45,\n)\n\nconfig = GenerationConfig(batch_size=1)\n\nresult = generate_music(dit_handler, llm_handler, params, config, save_dir=\"/output\")\n```\n\n### Example 3: Using Custom Timesteps\n\n```python\nparams = GenerationParams(\n    task_type=\"text2music\",\n    caption=\"jazz fusion with complex harmonies\",\n    # Custom 9-step schedule\n    timesteps=[0.97, 0.76, 0.615, 0.5, 0.395, 0.28, 0.18, 0.085, 0],\n    thinking=True,\n)\n\nconfig = GenerationConfig(batch_size=1)\n\nresult = generate_music(dit_handler, llm_handler, params, config, save_dir=\"/output\")\n```\n\n### Example 4: Using Shift Parameter (Turbo Model)\n\n```python\nparams = GenerationParams(\n    task_type=\"text2music\",\n    caption=\"upbeat electronic dance music\",\n    inference_steps=8,\n    shift=3.0,  # Recommended for turbo models\n    infer_method=\"ode\",\n)\n\nconfig = GenerationConfig(batch_size=2)\n\nresult = generate_music(dit_handler, llm_handler, params, config, save_dir=\"/output\")\n```\n\n### Example 5: Simple Mode with create_sample\n\n```python\nfrom acestep.inference import create_sample, GenerationParams, GenerationConfig, generate_music\n\n# Step 1: Create sample from description\nsample = create_sample(\n    llm_handler=llm_handler,\n    query=\"energetic K-pop dance track with catchy hooks\",\n    vocal_language=\"ko\",\n)\n\nif sample.success:\n    # Step 2: Generate music using the sample\n    params = GenerationParams(\n        caption=sample.caption,\n        lyrics=sample.lyrics,\n        bpm=sample.bpm,\n        duration=sample.duration,\n        keyscale=sample.keyscale,\n        vocal_language=sample.language,\n        thinking=True,\n    )\n    \n    config = GenerationConfig(batch_size=2)\n    result = generate_music(dit_handler, llm_handler, params, config, save_dir=\"/output\")\n```\n\n### Example 6: Format and Enhance User Input\n\n```python\nfrom acestep.inference import format_sample, GenerationParams, GenerationConfig, generate_music\n\n# Step 1: Format user input\nformatted = format_sample(\n    llm_handler=llm_handler,\n    caption=\"rock ballad\",\n    lyrics=\"[Verse]\\nIn the darkness I find my way...\",\n)\n\nif formatted.success:\n    # Step 2: Generate with enhanced input\n    params = GenerationParams(\n        caption=formatted.caption,\n        lyrics=formatted.lyrics,\n        bpm=formatted.bpm,\n        duration=formatted.duration,\n        keyscale=formatted.keyscale,\n        thinking=True,\n        use_cot_metas=False,  # Already formatted, skip metas CoT\n    )\n    \n    config = GenerationConfig(batch_size=2)\n    result = generate_music(dit_handler, llm_handler, params, config, save_dir=\"/output\")\n```\n\n### Example 7: Style Cover with LM Reasoning\n\n```python\nparams = GenerationParams(\n    task_type=\"cover\",\n    src_audio=\"original_pop_song.mp3\",\n    caption=\"orchestral symphonic arrangement\",\n    audio_cover_strength=0.7,\n    thinking=True,  # Enable LM for metadata\n    use_cot_metas=True,\n)\n\nconfig = GenerationConfig(batch_size=1)\n\nresult = generate_music(dit_handler, llm_handler, params, config, save_dir=\"/output\")\n\n# Access LM-generated metadata\nif result.extra_outputs.get(\"lm_metadata\"):\n    lm_meta = result.extra_outputs[\"lm_metadata\"]\n    print(f\"LM detected BPM: {lm_meta.get('bpm')}\")\n    print(f\"LM detected Key: {lm_meta.get('keyscale')}\")\n```\n\n### Example 8: Batch Generation with Specific Seeds\n\n```python\nparams = GenerationParams(\n    task_type=\"text2music\",\n    caption=\"epic cinematic trailer music\",\n)\n\nconfig = GenerationConfig(\n    batch_size=4,           # Generate 4 variations\n    seeds=[42, 123, 456],   # Specify 3 seeds, 4th will be random\n    use_random_seed=False,  # Use provided seeds\n    lm_batch_chunk_size=2,  # Process 2 at a time (GPU memory)\n)\n\nresult = generate_music(dit_handler, llm_handler, params, config, save_dir=\"/output\")\n\nif result.success:\n    print(f\"Generated {len(result.audios)} variations\")\n    for audio in result.audios:\n        print(f\"  Seed {audio['params']['seed']}: {audio['path']}\")\n```\n\n### Example 9: High-Quality Generation (Base Model)\n\n```python\nparams = GenerationParams(\n    task_type=\"text2music\",\n    caption=\"intricate jazz fusion with complex harmonies\",\n    inference_steps=64,     # High quality\n    guidance_scale=8.0,\n    use_adg=True,           # Adaptive Dual Guidance\n    cfg_interval_start=0.0,\n    cfg_interval_end=1.0,\n    shift=3.0,              # Timestep shift\n    seed=42,                # Reproducible results\n)\n\nconfig = GenerationConfig(\n    batch_size=1,\n    use_random_seed=False,\n    audio_format=\"wav\",     # Lossless format\n)\n\nresult = generate_music(dit_handler, llm_handler, params, config, save_dir=\"/output\")\n```\n\n### Example 10: Understand Audio from Codes\n\n```python\nfrom acestep.inference import understand_music\n\n# Analyze audio codes (e.g., from a previous generation)\nresult = understand_music(\n    llm_handler=llm_handler,\n    audio_codes=\"<|audio_code_10695|><|audio_code_54246|>...\",\n    temperature=0.85,\n)\n\nif result.success:\n    print(f\"Detected Caption: {result.caption}\")\n    print(f\"Detected Lyrics: {result.lyrics}\")\n    print(f\"Detected BPM: {result.bpm}\")\n    print(f\"Detected Key: {result.keyscale}\")\n    print(f\"Detected Duration: {result.duration}s\")\n    print(f\"Detected Language: {result.language}\")\n```\n\n---\n\n## Best Practices\n\n### 1. Caption Writing\n\n**Good Captions**:\n```python\n# Specific and descriptive\ncaption=\"upbeat electronic dance music with heavy bass and synthesizer leads\"\n\n# Include mood and genre\ncaption=\"melancholic indie folk with acoustic guitar and soft vocals\"\n\n# Specify instruments\ncaption=\"jazz trio with piano, upright bass, and brush drums\"\n```\n\n**Avoid**:\n```python\n# Too vague\ncaption=\"good music\"\n\n# Contradictory\ncaption=\"fast slow music\"  # Conflicting tempos\n```\n\n### 2. Parameter Tuning\n\n**For Best Quality**:\n- Use base model with `inference_steps=64` or higher\n- Enable `use_adg=True`\n- Set `guidance_scale=7.0-9.0`\n- Set `shift=3.0` for better timestep distribution\n- Use lossless audio format (`audio_format=\"wav\"`)\n\n**For Speed**:\n- Use turbo model with `inference_steps=8`\n- Disable ADG (`use_adg=False`)\n- Use `infer_method=\"ode\"` (default)\n- Use compressed format (`audio_format=\"mp3\"`) or default FLAC\n\n**For Consistency**:\n- Set `use_random_seed=False` in config\n- Use fixed `seeds` list or single `seed` in params\n- Keep `lm_temperature` lower (0.7-0.85)\n\n**For Diversity**:\n- Set `use_random_seed=True` in config\n- Increase `lm_temperature` (0.9-1.1)\n- Use `batch_size > 1` for variations\n\n### 3. Duration Guidelines\n\n- **Instrumental**: 30-180 seconds works well\n- **With Lyrics**: Auto-detection recommended (set `duration=-1` or leave default)\n- **Short clips**: 10-20 seconds minimum\n- **Long form**: Up to 600 seconds (10 minutes) maximum\n\n### 4. LM Usage\n\n**When to Enable LM (`thinking=True`)**:\n- Need automatic metadata detection\n- Want caption refinement\n- Generating from minimal input\n- Need diverse outputs\n\n**When to Disable LM (`thinking=False`)**:\n- Have precise metadata already\n- Need faster generation\n- Want full control over parameters\n\n### 5. Batch Processing\n\n```python\n# Efficient batch generation\nconfig = GenerationConfig(\n    batch_size=8,           # Max supported\n    allow_lm_batch=True,    # Enable for speed (when thinking=True)\n    lm_batch_chunk_size=4,  # Adjust based on GPU memory\n)\n```\n\n### 6. Error Handling\n\n```python\nresult = generate_music(dit_handler, llm_handler, params, config, save_dir=\"/output\")\n\nif not result.success:\n    print(f\"Generation failed: {result.error}\")\n    print(f\"Status: {result.status_message}\")\nelse:\n    # Process successful result\n    for audio in result.audios:\n        path = audio['path']\n        key = audio['key']\n        seed = audio['params']['seed']\n        # ... process audio files\n```\n\n### 7. Memory Management\n\nACE-Step 1.5 includes automatic VRAM management that adapts to your GPU:\n\n- **Automatic tier detection**: The system detects available VRAM and selects optimal settings (see [GPU_COMPATIBILITY.md](GPU_COMPATIBILITY.md))\n- **VRAM guard**: Before each inference, the system estimates VRAM requirements and automatically reduces `batch_size` if needed\n- **Adaptive VAE decode**: Three-tier fallback — GPU tiled decode → GPU decode with CPU offload → full CPU decode\n- **Auto chunk sizing**: VAE decode chunk size adapts to free VRAM (64/128/256/512/1024/1536)\n- **Duration/batch clamping**: Values exceeding your tier's limits are automatically clamped with a warning\n\nFor manual tuning:\n- Reduce `batch_size` if OOM errors persist\n- Reduce `lm_batch_chunk_size` for LM operations on low-VRAM GPUs\n- Enable `offload_to_cpu=True` during initialization for GPUs with <20GB VRAM\n- Enable `quantization=\"int8_weight_only\"` for GPUs with <20GB VRAM\n\n### 8. Accessing Time Costs\n\n```python\nresult = generate_music(dit_handler, llm_handler, params, config, save_dir=\"/output\")\n\nif result.success:\n    time_costs = result.extra_outputs.get(\"time_costs\", {})\n    print(f\"LM Phase 1 Time: {time_costs.get('lm_phase1_time', 0):.2f}s\")\n    print(f\"LM Phase 2 Time: {time_costs.get('lm_phase2_time', 0):.2f}s\")\n    print(f\"DiT Total Time: {time_costs.get('dit_total_time_cost', 0):.2f}s\")\n    print(f\"Pipeline Total: {time_costs.get('pipeline_total_time', 0):.2f}s\")\n```\n\n---\n\n## Troubleshooting\n\n### Common Issues\n\n**Issue**: Out of memory errors\n- **Solution**: The system should automatically handle most OOM scenarios via VRAM guard (batch reduction) and adaptive VAE decode (CPU fallback). If OOM still occurs: reduce `batch_size`, reduce `inference_steps`, enable CPU offloading (`offload_to_cpu=True`), or enable INT8 quantization. See [GPU_COMPATIBILITY.md](GPU_COMPATIBILITY.md) for recommended settings per VRAM tier.\n\n**Issue**: Poor quality results\n- **Solution**: Increase `inference_steps`, adjust `guidance_scale`, use base model\n\n**Issue**: Results don't match prompt\n- **Solution**: Make caption more specific, increase `guidance_scale`, enable LM refinement (`thinking=True`)\n\n**Issue**: Slow generation\n- **Solution**: Use turbo model, reduce `inference_steps`, disable ADG\n\n**Issue**: LM not generating codes\n- **Solution**: Verify `llm_handler` is initialized, check `thinking=True` and `use_cot_metas=True`\n\n**Issue**: Seeds not being respected\n- **Solution**: Set `use_random_seed=False` in config and provide `seeds` list or `seed` in params\n\n**Issue**: Custom timesteps not working\n- **Solution**: Ensure timesteps are a list of floats from 1.0 to 0.0, properly ordered\n\n---\n\n## API Reference Summary\n\n### GenerationParams Fields\n\nSee [GenerationParams Parameters](#generationparams-parameters) for complete documentation.\n\n### GenerationConfig Fields\n\nSee [GenerationConfig Parameters](#generationconfig-parameters) for complete documentation.\n\n### GenerationResult Fields\n\n```python\n@dataclass\nclass GenerationResult:\n    # Audio Outputs\n    audios: List[Dict[str, Any]]\n    # Each audio dict contains:\n    #   - \"path\": str (file path)\n    #   - \"tensor\": Tensor (audio data)\n    #   - \"key\": str (unique identifier)\n    #   - \"sample_rate\": int (48000)\n    #   - \"params\": Dict (generation params with seed, audio_codes, etc.)\n    \n    # Generation Information\n    status_message: str\n    extra_outputs: Dict[str, Any]\n    # extra_outputs contains:\n    #   - \"lm_metadata\": Dict (LM-generated metadata)\n    #   - \"time_costs\": Dict (timing information)\n    #   - \"latents\": Tensor (intermediate latents, if available)\n    #   - \"masks\": Tensor (attention masks, if available)\n    \n    # Success Status\n    success: bool\n    error: Optional[str]\n```\n\n---\n\n## Version History\n\n- **v1.5.2**: Current version\n  - Added `shift` parameter for timestep shifting\n  - Added `infer_method` parameter for ODE/SDE selection\n  - Added `timesteps` parameter for custom timestep schedules\n  - Added `understand_music()` function for audio analysis\n  - Added `create_sample()` function for simple mode generation\n  - Added `format_sample()` function for input enhancement\n  - Added `UnderstandResult`, `CreateSampleResult`, `FormatSampleResult` dataclasses\n\n- **v1.5.1**: Previous version\n  - Split `GenerationConfig` into `GenerationParams` and `GenerationConfig`\n  - Renamed parameters for consistency (`key_scale` → `keyscale`, `time_signature` → `timesignature`, `audio_duration` → `duration`, `use_llm_thinking` → `thinking`, `audio_code_string` → `audio_codes`)\n  - Added `instrumental` parameter\n  - Added `use_constrained_decoding` parameter\n  - Added CoT auto-filled fields (`cot_*`)\n  - Changed default `audio_format` to \"flac\"\n  - Changed default `batch_size` to 2\n  - Changed default `thinking` to True\n  - Simplified `GenerationResult` structure with unified `audios` list\n  - Added unified `time_costs` in `extra_outputs`\n\n- **v1.5**: Initial version\n  - Introduced `GenerationConfig` and `GenerationResult` dataclasses\n  - Simplified parameter passing\n  - Added comprehensive documentation\n\n---\n\nFor more information, see:\n- Main README: [`../../README.md`](../../README.md)\n- REST API Documentation: [`API.md`](API.md)\n- Gradio Demo Guide: [`GRADIO_GUIDE.md`](GRADIO_GUIDE.md)\n- Project repository: [ACE-Step-1.5](https://github.com/yourusername/ACE-Step-1.5)\n"
  },
  {
    "path": "docs/en/INSTALL.md",
    "content": "# ACE-Step 1.5 Installation Guide\n\n**Language / 语言 / 言語:** [English](INSTALL.md) | [中文](../zh/INSTALL.md) | [日本語](../ja/INSTALL.md)\n\n---\n\n## Table of Contents\n\n- [Requirements](#requirements)\n- [Quick Start (All Platforms)](#quick-start-all-platforms)\n- [Launch Scripts](#-launch-scripts)\n- [Windows Portable Package](#-windows-portable-package)\n- [macOS Portable Package](#-macos-portable-package)\n- [AMD / ROCm GPUs](#amd--rocm-gpus)\n- [Intel GPUs](#intel-gpus)\n- [CPU-Only Mode](#cpu-only-mode)\n- [Linux Notes](#linux-notes)\n- [Environment Variables (.env)](#environment-variables-env)\n- [Command Line Options](#command-line-options)\n- [Model Download](#-model-download)\n- [Which Model Should I Choose?](#-which-model-should-i-choose)\n- [Development](#development)\n\n---\n\n## Requirements\n\n| Item | Requirement |\n|------|-------------|\n| Python | 3.11-3.12 (stable release, not pre-release)<br>**Note:** ROCm on Windows requires Python 3.12 |\n| GPU | CUDA GPU recommended; MPS / ROCm / Intel XPU / CPU also supported |\n| VRAM | ≥4GB for DiT-only mode; ≥6GB for LLM+DiT |\n| Disk | ~10GB for core models |\n\n---\n\n## Quick Start (All Platforms)\n\n### 1. Install uv (Package Manager)\n\n```bash\n# macOS / Linux\ncurl -LsSf https://astral.sh/uv/install.sh | sh\n\n# Windows (PowerShell)\npowershell -ExecutionPolicy ByPass -c \"irm https://astral.sh/uv/install.ps1 | iex\"\n```\n\n### 2. Clone & Install\n\n```bash\ngit clone https://github.com/ACE-Step/ACE-Step-1.5.git\ncd ACE-Step-1.5\nuv sync\n```\n\n### 3. Launch\n\n**Gradio Web UI (Recommended):**\n\n```bash\nuv run acestep\n```\n\n**REST API Server:**\n\n```bash\nuv run acestep-api\n```\n\n**Using Python directly** (Conda / venv / system Python):\n\n```bash\n# Activate your environment first, then:\npython acestep/acestep_v15_pipeline.py          # Gradio UI\npython acestep/api_server.py                     # REST API\n```\n\n> Models are downloaded automatically on first run. Open http://localhost:7860 (Gradio) or http://localhost:8001 (API).\n\n---\n\n## 🚀 Launch Scripts\n\nReady-to-use launch scripts for all platforms. These scripts handle environment detection, dependency installation, and application startup automatically. All scripts check for updates on startup by default (configurable).\n\n### Available Scripts\n\n| Platform | Script | Description |\n|----------|--------|-------------|\n| **Windows** | `start_gradio_ui.bat` | Launch Gradio Web UI (CUDA) |\n| **Windows** | `start_api_server.bat` | Launch REST API Server (CUDA) |\n| **Windows** | `start_gradio_ui_rocm.bat` | Launch Gradio Web UI (AMD ROCm) |\n| **Windows** | `start_api_server_rocm.bat` | Launch REST API Server (AMD ROCm) |\n| **Linux** | `start_gradio_ui.sh` | Launch Gradio Web UI (CUDA) |\n| **Linux** | `start_api_server.sh` | Launch REST API Server (CUDA) |\n| **macOS** | `start_gradio_ui_macos.sh` | Launch Gradio Web UI (MLX) |\n| **macOS** | `start_api_server_macos.sh` | Launch REST API Server (MLX) |\n\n### Windows\n\n```bash\n# Launch Gradio Web UI (NVIDIA CUDA)\nstart_gradio_ui.bat\n\n# Launch REST API Server (NVIDIA CUDA)\nstart_api_server.bat\n\n# Launch Gradio Web UI (AMD ROCm)\nstart_gradio_ui_rocm.bat\n\n# Launch REST API Server (AMD ROCm)\nstart_api_server_rocm.bat\n```\n\n> **ROCm users:** The ROCm scripts (`start_gradio_ui_rocm.bat`, `start_api_server_rocm.bat`) auto-set `HSA_OVERRIDE_GFX_VERSION`, `ACESTEP_LM_BACKEND=pt`, `MIOPEN_FIND_MODE=FAST` and other ROCm-specific environment variables. They use a separate `venv_rocm` virtual environment to avoid CUDA/ROCm wheel conflicts.\n\n### Linux\n\n```bash\n# Make executable (first time only)\nchmod +x start_gradio_ui.sh start_api_server.sh\n\n# Launch Gradio Web UI\n./start_gradio_ui.sh\n\n# Launch REST API Server\n./start_api_server.sh\n```\n\n> **Note:** Git must be installed via your system package manager (`sudo apt install git`, `sudo yum install git`, `sudo pacman -S git`).\n\n### macOS (Apple Silicon / MLX)\n\nmacOS scripts use the **MLX backend** for native Apple Silicon acceleration (M1/M2/M3/M4).\n\n```bash\n# Make executable (first time only)\nchmod +x start_gradio_ui_macos.sh start_api_server_macos.sh\n\n# Launch Gradio Web UI with MLX backend\n./start_gradio_ui_macos.sh\n\n# Launch REST API Server with MLX backend\n./start_api_server_macos.sh\n```\n\nThe macOS scripts automatically set `ACESTEP_LM_BACKEND=mlx` and `--backend mlx` for native Apple Silicon acceleration, and fall back to PyTorch backend on non-arm64 machines.\n\n> **Note:** Install git via `xcode-select --install` or `brew install git`.\n\n### Script Features\n\n- Startup update check (enabled by default, configurable)\n- Auto environment detection (portable Python or uv)\n- Auto install `uv` if needed\n- Configurable download source (HuggingFace/ModelScope)\n- Customizable models and parameters\n\n### How to Modify Configuration\n\nAll configurable options are defined as variables at the top of each script. To customize, open the script with a text editor and modify the variable values.\n\n**Example: Change UI language to Chinese and use the 1.7B LM model**\n\n<table>\n<tr><th>Windows (.bat)</th><th>Linux / macOS (.sh)</th></tr>\n<tr><td>\n\nFind these lines in `start_gradio_ui.bat`:\n```batch\nset LANGUAGE=en\nset LM_MODEL_PATH=--lm_model_path acestep-5Hz-lm-0.6B\n```\nChange to:\n```batch\nset LANGUAGE=zh\nset LM_MODEL_PATH=--lm_model_path acestep-5Hz-lm-1.7B\n```\n\n</td><td>\n\nFind these lines in `start_gradio_ui.sh`:\n```bash\nLANGUAGE=\"en\"\nLM_MODEL_PATH=\"--lm_model_path acestep-5Hz-lm-0.6B\"\n```\nChange to:\n```bash\nLANGUAGE=\"zh\"\nLM_MODEL_PATH=\"--lm_model_path acestep-5Hz-lm-1.7B\"\n```\n\n</td></tr>\n</table>\n\n**Example: Disable startup update check**\n\n<table>\n<tr><th>Windows (.bat)</th><th>Linux / macOS (.sh)</th></tr>\n<tr><td>\n\n```batch\nREM set CHECK_UPDATE=true\nset CHECK_UPDATE=false\n```\n\n</td><td>\n\n```bash\n# CHECK_UPDATE=\"true\"\nCHECK_UPDATE=\"false\"\n```\n\n</td></tr>\n</table>\n\n**Example: Enable a commented-out option** — remove the comment prefix (`REM` for .bat, `#` for .sh):\n\n<table>\n<tr><th>Windows (.bat)</th><th>Linux / macOS (.sh)</th></tr>\n<tr><td>\n\nBefore:\n```batch\nREM set SHARE=--share\n```\nAfter:\n```batch\nset SHARE=--share\n```\n\n</td><td>\n\nBefore:\n```bash\n# SHARE=\"--share\"\n```\nAfter:\n```bash\nSHARE=\"--share\"\n```\n\n</td></tr>\n</table>\n\n**Common configurable options:**\n\n| Option | Gradio UI | API Server | Description |\n|--------|:---------:|:----------:|-------------|\n| `LANGUAGE` | ✅ | — | UI language: `en`, `zh`, `he`, `ja` |\n| `PORT` | ✅ | ✅ | Server port (default: 7860 / 8001) |\n| `SERVER_NAME` / `HOST` | ✅ | ✅ | Bind address (`127.0.0.1` or `0.0.0.0`) |\n| `CHECK_UPDATE` | ✅ | ✅ | Startup update check (`true` / `false`) |\n| `CONFIG_PATH` | ✅ | — | DiT model (`acestep-v15-turbo`, etc.) |\n| `LM_MODEL_PATH` | ✅ | ✅ | LM model (`acestep-5Hz-lm-0.6B` / `1.7B` / `4B`) |\n| `DOWNLOAD_SOURCE` | ✅ | ✅ | Download source (`huggingface` / `modelscope`) |\n| `SHARE` | ✅ | — | Create public Gradio link |\n| `INIT_LLM` | ✅ | — | Force LLM on/off (`true` / `false` / `auto`) |\n| `OFFLOAD_TO_CPU` | ✅ | — | CPU offload for low-VRAM GPUs |\n\n### Update & Maintenance Tools\n\n| Script (Windows) | Script (Linux/macOS) | Purpose |\n|-------------------|----------------------|---------|\n| `check_update.bat` | `check_update.sh` | Check and update from GitHub |\n| `merge_config.bat` | `merge_config.sh` | Merge backed-up configurations after update |\n| `install_uv.bat` | `install_uv.sh` | Install uv package manager |\n| `quick_test.bat` | `quick_test.sh` | Test environment setup |\n\n**Update workflow:**\n\n```bash\n# Windows                          # Linux / macOS\ncheck_update.bat                    ./check_update.sh\nmerge_config.bat                    ./merge_config.sh\n```\n\n---\n\n## 🪟 Windows Portable Package\n\nFor Windows users, we provide a portable package with pre-installed dependencies:\n\n1. Download and extract: [ACE-Step-1.5.7z](https://files.acemusic.ai/acemusic/win/ACE-Step-1.5.7z)\n2. The package includes `python_embedded` with all dependencies pre-installed\n3. **Requirements:** CUDA 12.8\n\n### Quick Start Scripts\n\n| Script | Description |\n|--------|-------------|\n| `start_gradio_ui.bat` | Launch Gradio Web UI |\n| `start_api_server.bat` | Launch REST API Server |\n\nBoth scripts support auto environment detection, auto `uv` install, configurable download source, optional Git update check, and customizable models/parameters.\n\n### Configuration\n\n**`start_gradio_ui.bat`:**\n\n```batch\nREM UI language (en, zh, he, ja)\nset LANGUAGE=zh\n\nREM Download source (auto, huggingface, modelscope)\nset DOWNLOAD_SOURCE=--download-source modelscope\n\nREM Git update check (true/false)\nset CHECK_UPDATE=true\n\nREM Model configuration\nset CONFIG_PATH=--config_path acestep-v15-turbo\nset LM_MODEL_PATH=--lm_model_path acestep-5Hz-lm-1.7B\n```\n\n**`start_api_server.bat`:**\n\n```batch\nREM LLM initialization via environment variable\nREM set ACESTEP_INIT_LLM=true   # Force enable LLM\nREM set ACESTEP_INIT_LLM=false  # Force disable LLM (DiT-only mode)\n```\n\n### Update & Maintenance\n\n| Script | Purpose |\n|--------|---------|\n| `check_update.bat` | Check and update from GitHub |\n| `merge_config.bat` | Merge backed-up configurations after update |\n| `install_uv.bat` | Install uv package manager |\n| `quick_test.bat` | Test environment setup |\n| `test_git_update.bat` | Test Git update functionality |\n\n**Update workflow:**\n\n```bash\ncheck_update.bat          # 1. Check for updates (requires PortableGit/)\nmerge_config.bat          # 2. Merge settings back if conflicts occur\n```\n\n### Portable Git Support\n\nPlace a `PortableGit/` folder in your package to enable auto-updates:\n\n```batch\nset CHECK_UPDATE=true     # in start_gradio_ui.bat or start_api_server.bat\n```\n\nFeatures: 10s timeout protection, smart conflict detection & backup, automatic rollback on failure, directory structure preserved in backups.\n\n### Environment Detection Priority\n\n1. `python_embedded\\python.exe` (if exists)\n2. `uv run acestep` (if uv is installed)\n3. Auto-install uv via winget or PowerShell\n\n---\n\n## 🍎 macOS Portable Package\n\nFor macOS users (Apple Silicon), we provide a portable package with pre-installed dependencies:\n\n1. Download and extract: [ACE-Step-1.5.zip](https://files.acemusic.ai/acemusic/mac/ACE-Step-1.5.zip)\n2. The package includes all dependencies pre-installed with MLX backend support\n3. **Requirements:** Apple Silicon (M1/M2/M3/M4) with macOS\n\n### Quick Start Scripts\n\n| Script | Description |\n|--------|-------------|\n| `start_gradio_ui_macos.sh` | Launch Gradio Web UI (MLX) |\n| `start_api_server_macos.sh` | Launch REST API Server (MLX) |\n\n```bash\n# Make executable (first time only)\nchmod +x start_gradio_ui_macos.sh start_api_server_macos.sh\n\n# Launch Gradio Web UI with MLX backend\n./start_gradio_ui_macos.sh\n\n# Launch REST API Server with MLX backend\n./start_api_server_macos.sh\n```\n\nThe macOS scripts automatically set `ACESTEP_LM_BACKEND=mlx` and `--backend mlx` for native Apple Silicon acceleration.\n\n### Configuration\n\nConfigurable options are defined as variables at the top of each script. Open the script with a text editor to customize:\n\n```bash\n# UI language (en, zh, he, ja)\nLANGUAGE=\"en\"\n\n# Download source (auto, huggingface, modelscope)\nDOWNLOAD_SOURCE=\"--download-source auto\"\n\n# Git update check (true/false)\nCHECK_UPDATE=\"true\"\n\n# Model configuration\nCONFIG_PATH=\"--config_path acestep-v15-turbo\"\nLM_MODEL_PATH=\"--lm_model_path acestep-5Hz-lm-1.7B\"\n```\n\n---\n\n## AMD / ROCm GPUs\n\n> ⚠️ `uv run acestep` installs CUDA PyTorch wheels and may overwrite an existing ROCm setup.\n\n### Windows - ROCm 7.2 (Python 3.12 Required)\n\n**Important:** AMD ROCm 7.2 on Windows requires **Python 3.12** (AMD officially provides Python 3.12 wheels only).\n\n```bash\n# 1. Ensure you have Python 3.12 installed\npython --version  # Should show Python 3.12.x\n\n# 2. Create and activate a virtual environment\npython -m venv venv_rocm\nvenv_rocm\\Scripts\\activate\n\n# 3. Follow the installation steps in requirements-rocm.txt\n# This installs ROCm SDK and PyTorch wheels from AMD's repository\n\n# 4. Install dependencies\npip install -r requirements-rocm.txt\n\n# 5. Launch with the ROCm-specific launcher\nstart_gradio_ui_rocm.bat\n# OR\nstart_api_server_rocm.bat\n```\n\nSee [`requirements-rocm.txt`](../../requirements-rocm.txt) for detailed ROCm 7.2 installation steps.\n\n### Linux - ROCm 6.0+ (Python 3.11 or 3.12)\n\n```bash\n# 1. Create and activate a virtual environment\npython -m venv .venv\nsource .venv/bin/activate\n\n# 2. Install ROCm-compatible PyTorch\npip install torch --index-url https://download.pytorch.org/whl/rocm6.0\n\n# 3. Install ACE-Step\npip install -e .\n\n# 4. Start the service\npython -m acestep.acestep_v15_pipeline --port 7680\n```\n\n> **Note:** `torchcodec` is not available for AMD ROCm GPUs due to CUDA-specific dependencies. ACE-Step automatically uses `soundfile` as a fallback for audio I/O, which provides full functionality on ROCm platforms.\n\n### GPU Detection Troubleshooting\n\nIf you see \"No GPU detected, running on CPU\" with an AMD GPU:\n\n1. Run the diagnostic tool: `python scripts/check_gpu.py`\n2. For RDNA3 GPUs, set `HSA_OVERRIDE_GFX_VERSION`:\n\n| GPU | Value |\n|-----|-------|\n| RX 7900 XT/XTX, RX 9070 XT | `export HSA_OVERRIDE_GFX_VERSION=11.0.0` |\n| RX 7800 XT, RX 7700 XT | `export HSA_OVERRIDE_GFX_VERSION=11.0.1` |\n| RX 7600 | `export HSA_OVERRIDE_GFX_VERSION=11.0.2` |\n\n3. On Windows, use `start_gradio_ui_rocm.bat` / `start_api_server_rocm.bat` which set required environment variables automatically.\n4. Verify ROCm installation: `rocm-smi` should list your GPU.\n\n### Linux (cachy-os / RDNA4)\n\nSee [ACE-Step1.5-Rocm-Manual-Linux.md](ACE-Step1.5-Rocm-Manual-Linux.md) for a detailed ROCm manual tested with RDNA4 on cachy-os.\n\n---\n\n## Intel GPUs\n\n| Item | Detail |\n|------|--------|\n| Tested Device | Windows laptop with Ultra 9 285H integrated graphics |\n| Offload | Disabled by default |\n| Compile & Quantization | Enabled by default |\n| LLM Inference | Supported (tested with `acestep-5Hz-lm-0.6B`) |\n| nanovllm acceleration | NOT supported on Intel GPUs |\n| Test Environment | PyTorch 2.8.0 from [Intel Extension for PyTorch](https://pytorch-extension.intel.com/?request=platform) |\n\n> **Note:** LLM inference speed may decrease when generating audio longer than 2 minutes. Intel discrete GPUs are expected to work but not yet tested.\n> \n> **Audio I/O:** `torchcodec` is not available for Intel XPU GPUs. ACE-Step automatically uses `soundfile` as a fallback for audio I/O, which provides full functionality on Intel platforms.\n\n---\n\n## CPU-Only Mode\n\nACE-Step can run on CPU for **inference only**, but performance will be significantly slower.\n\n- Training (including LoRA) on CPU is **not recommended**.\n- For low-VRAM systems, DiT-only mode (LLM disabled) is supported.\n\nIf you do not have a GPU, consider:\n- Using cloud GPU providers\n- Running inference-only workflows\n- Using DiT-only mode with `ACESTEP_INIT_LLM=false`\n\n---\n\n## Linux Notes\n\n### Python 3.11 Pre-Release Issue\n\nSome Linux distributions (including Ubuntu) ship Python 3.11.0rc1, which is a **pre-release** build. This can cause segmentation faults with the vLLM backend.\n\n**Recommendation:** Use a stable Python release (≥ 3.11.12). On Ubuntu, install via the deadsnakes PPA.\n\nIf upgrading Python is not possible, use the PyTorch backend:\n\n```bash\nuv run acestep --backend pt\n```\n\n---\n\n## Environment Variables (.env)\n\nThe `.env` file provides a centralized way to configure ACE-Step. Settings in `.env` are:\n- Used by Python scripts (CLI, API server, Gradio UI)\n- **Now also used by launcher scripts** (`start_gradio_ui.bat`, `start_gradio_ui.sh`, etc.)\n- **Preserved across repository updates** (unlike hardcoded values in launcher scripts)\n\n```bash\ncp .env.example .env   # Copy and edit\n```\n\n### Benefits of Using .env\n\n✅ **Survives Updates**: Your custom model paths and settings won't be overwritten when you update ACE-Step  \n✅ **Cross-Platform**: Same configuration works on Windows, Linux, and macOS  \n✅ **Version Control Safe**: `.env` is in `.gitignore`, so your personal settings stay private\n\n### Key Variables\n\n| Variable | Values | Description |\n|----------|--------|-------------|\n| `ACESTEP_INIT_LLM` | `auto` / `true` / `false` | LLM initialization mode |\n| `ACESTEP_CONFIG_PATH` | model name | DiT model path |\n| `ACESTEP_LM_MODEL_PATH` | model name | LM model path |\n| `ACESTEP_DOWNLOAD_SOURCE` | `auto` / `huggingface` / `modelscope` | Download source |\n| `ACESTEP_API_KEY` | string | API authentication key |\n| `PORT` | number | Server port (default: 7860) |\n| `SERVER_NAME` | IP address | Server host (default: 127.0.0.1) |\n| `LANGUAGE` | `en` / `zh` / `he` / `ja` | UI language (default: en) |\n\n### LLM Initialization (`ACESTEP_INIT_LLM`)\n\nProcessing flow: `GPU Detection → ACESTEP_INIT_LLM Override → Model Loading`\n\n| Value | Behavior |\n|-------|----------|\n| `auto` (or empty) | Use GPU auto-detection result (recommended) |\n| `true` / `1` / `yes` | Force enable LLM after GPU detection (may cause OOM) |\n| `false` / `0` / `no` | Force disable for pure DiT mode |\n\n**Example `.env` for different scenarios:**\n\n```bash\n# Auto mode (recommended)\nACESTEP_INIT_LLM=auto\n\n# Force enable on low VRAM GPU\nACESTEP_INIT_LLM=true\nACESTEP_LM_MODEL_PATH=acestep-5Hz-lm-0.6B\n\n# Force disable LLM for faster generation\nACESTEP_INIT_LLM=false\n```\n\n---\n\n## Command Line Options\n\n### Gradio UI (`acestep`)\n\n| Option | Default | Description |\n|--------|---------|-------------|\n| `--port` | 7860 | Server port |\n| `--server-name` | 127.0.0.1 | Server address (use `0.0.0.0` for network access) |\n| `--share` | false | Create public Gradio link |\n| `--language` | en | UI language: `en`, `zh`, `he`, `ja` |\n| `--batch_size` | None | Default batch size for generation (1 to GPU-dependent max). When not specified, defaults to `min(2, GPU_max)` |\n| `--init_service` | false | Auto-initialize models on startup |\n| `--init_llm` | auto | LLM init: `true` / `false` / omit for auto |\n| `--config_path` | auto | DiT model (e.g., `acestep-v15-turbo`) |\n| `--lm_model_path` | auto | LM model (e.g., `acestep-5Hz-lm-1.7B`) |\n| `--offload_to_cpu` | auto | CPU offload (auto-enabled if VRAM < 20GB) |\n| `--download-source` | auto | Model source: `auto` / `huggingface` / `modelscope` |\n| `--enable-api` | false | Enable REST API alongside Gradio UI |\n| `--api-key` | none | API key for authentication |\n| `--auth-username` | none | Gradio authentication username |\n| `--auth-password` | none | Gradio authentication password |\n\n**Examples:**\n\n```bash\n# Public access with Chinese UI\nuv run acestep --server-name 0.0.0.0 --share --language zh\n\n# Pre-initialize models on startup\nuv run acestep --init_service true --config_path acestep-v15-turbo\n\n# Set default batch size to 4\nuv run acestep --batch_size 4\n\n# Enable API endpoints with authentication\nuv run acestep --enable-api --api-key sk-your-secret-key --port 8001\n\n# Use ModelScope as download source\nuv run acestep --download-source modelscope\n```\n\n---\n\n## 📥 Model Download\n\nModels are automatically downloaded from [HuggingFace](https://huggingface.co/ACE-Step/Ace-Step1.5) or [ModelScope](https://modelscope.cn/organization/ACE-Step) on first run.\n\n### CLI Download\n\n```bash\nuv run acestep-download                              # Download main model\nuv run acestep-download --all                         # Download all models\nuv run acestep-download --download-source modelscope  # From ModelScope\nuv run acestep-download --model acestep-v15-sft       # Specific model\nuv run acestep-download --list                        # List all available\n```\n\nOr with Python directly:\n\n```bash\npython -m acestep.model_downloader                    # Download main model\npython -m acestep.model_downloader --all              # Download all models\n```\n\n### Manual Download (huggingface-cli)\n\n```bash\n# Main model (vae, Qwen3-Embedding-0.6B, acestep-v15-turbo, acestep-5Hz-lm-1.7B)\nhuggingface-cli download ACE-Step/Ace-Step1.5 --local-dir ./checkpoints\n\n# Optional models\nhuggingface-cli download ACE-Step/acestep-5Hz-lm-0.6B --local-dir ./checkpoints/acestep-5Hz-lm-0.6B\nhuggingface-cli download ACE-Step/acestep-5Hz-lm-4B --local-dir ./checkpoints/acestep-5Hz-lm-4B\n```\n\n### Available Models\n\n| Model | Description | HuggingFace |\n|-------|-------------|-------------|\n| **Ace-Step1.5** (Main) | Core: vae, Qwen3-Embedding-0.6B, acestep-v15-turbo, acestep-5Hz-lm-1.7B | [Link](https://huggingface.co/ACE-Step/Ace-Step1.5) |\n| acestep-5Hz-lm-0.6B | Lightweight LM (0.6B params) | [Link](https://huggingface.co/ACE-Step/acestep-5Hz-lm-0.6B) |\n| acestep-5Hz-lm-4B | Large LM (4B params) | [Link](https://huggingface.co/ACE-Step/acestep-5Hz-lm-4B) |\n| acestep-v15-base | Base DiT model | [Link](https://huggingface.co/ACE-Step/acestep-v15-base) |\n| acestep-v15-sft | SFT DiT model | [Link](https://huggingface.co/ACE-Step/acestep-v15-sft) |\n| acestep-v15-turbo-shift1 | Turbo DiT with shift1 | [Link](https://huggingface.co/ACE-Step/acestep-v15-turbo-shift1) |\n| acestep-v15-turbo-shift3 | Turbo DiT with shift3 | [Link](https://huggingface.co/ACE-Step/acestep-v15-turbo-shift3) |\n| acestep-v15-turbo-continuous | Turbo DiT with continuous shift (1-5) | [Link](https://huggingface.co/ACE-Step/acestep-v15-turbo-continuous) |\n\n---\n\n## 💡 Which Model Should I Choose?\n\nACE-Step automatically adapts to your GPU's VRAM. The UI pre-configures all settings (LM model, backend, offloading, quantization) based on your detected GPU tier:\n\n| Your GPU VRAM | Recommended LM Model | Backend | Notes |\n|---------------|---------------------|---------|-------|\n| **≤6GB** | None (DiT only) | — | LM disabled by default; INT8 quantization + full CPU offload |\n| **6-8GB** | `acestep-5Hz-lm-0.6B` | `pt` | Lightweight LM with PyTorch backend |\n| **8-16GB** | `0.6B` / `1.7B` | `vllm` | 0.6B for 8-12GB, 1.7B for 12-16GB |\n| **16-24GB** | `acestep-5Hz-lm-1.7B` | `vllm` | 4B available on 20GB+; no offload on 20GB+ |\n| **≥24GB** | `acestep-5Hz-lm-4B` | `vllm` | Best quality, all models fit without offload |\n\n> 📖 For detailed GPU compatibility information (tier table, duration limits, batch sizes, adaptive UI defaults, memory optimization), see [GPU Compatibility Guide](GPU_COMPATIBILITY.md).\n\n---\n\n## Development\n\n```bash\n# Add dependencies\nuv add package-name\nuv add --dev package-name\n\n# Update all dependencies\nuv sync --upgrade\n```\n"
  },
  {
    "path": "docs/en/LoRA_Training_Tutorial.md",
    "content": "# ACE-Step 1.5 LoRA Training Tutorial\n\n## Hardware Requirements\n\n| VRAM | Description |\n|------|-------------|\n| 16 GB (minimum) | Generally sufficient, but longer songs may cause out-of-memory errors |\n| 20 GB or more (recommended) | Handles full-length songs; VRAM usage typically stays around 17 GB during training |\n\n> **Note:** During the preprocessing stage before training, you may need to restart Gradio multiple times to free VRAM. The specific timing will be mentioned in the steps below.\n\n## Disclaimer\n\nThis tutorial uses the album *ナユタン星からの物体Y* by **Nayutan星人 (NayutalieN)** (13 tracks) as a demonstration, trained for 500 epochs (batch size 1). **This tutorial is intended solely for educational purposes to understand LoRA fine-tuning. Please use your own original works to train your LoRA.**\n\nAs a developer, I personally enjoy NayutalieN's work and chose one of their albums as an example. If you are the rights holder and believe this tutorial infringes upon your legitimate rights, please contact us immediately. We will remove the relevant content upon receiving a valid notice.\n\nTechnology should be used reasonably and lawfully. Please respect artists' creations and refrain from any actions that **harm or damage** the reputation, rights, or interests of original artists.\n\n---\n\n## Data Preparation\n\n> **Tip:** If you are unfamiliar with programming, you can provide this document to AI coding tools such as Claude Code / Codex CLI / Cursor / Copilot and let them handle the scripting tasks for you.\n\n### Overview\n\nTraining data for each song consists of the following:\n\n1. **Audio file** — Supported formats: `.mp3`, `.wav`, `.flac`, `.ogg`, `.opus`\n2. **Lyrics** — A `.lyrics.txt` file with the same name as the audio (`.txt` is also supported for backward compatibility)\n3. **Annotation data** — Metadata including `caption`, `bpm`, `keyscale`, `timesignature`, `language`, etc.\n\n### Annotation Data Format\n\nIf you already have complete annotation data, you can create JSON files and place them in the same directory as the audio and lyrics. The file structure is as follows:\n\n```\ndataset/\n├── song1.mp3               # Audio\n├── song1.lyrics.txt        # Lyrics\n├── song1.json              # Annotations (optional)\n├── song1.caption.txt       # Caption (optional, can also be included in JSON)\n├── song2.mp3\n├── song2.lyrics.txt\n├── song2.json\n└── ...\n```\n\nJSON file structure (all fields are optional):\n\n```json\n{\n    \"caption\": \"A high-energy J-pop track with synthesizer leads and fast tempo\",\n    \"bpm\": 190,\n    \"keyscale\": \"D major\",\n    \"timesignature\": \"4\",\n    \"language\": \"ja\"\n}\n```\n\nIf you don't have annotation data, you can obtain it using the methods described in later sections.\n\n---\n\n### Lyrics\n\nSave lyrics as a `.lyrics.txt` file with the same name as the audio file, placed in the same directory. Please ensure the lyrics are accurate.\n\nLyrics file lookup priority during scanning:\n\n1. `{filename}.lyrics.txt` (recommended)\n2. `{filename}.txt` (backward compatible)\n\n#### Lyrics Transcription\n\nIf you don't have existing lyrics text, you can obtain transcribed lyrics using the following tools:\n\n| Tool | Structural Tags | Accuracy | Ease of Use | Deployment |\n|------|----------------|----------|-------------|------------|\n| [acestep-transcriber](https://huggingface.co/ACE-Step/acestep-transcriber) | No | May contain errors | High difficulty (requires model deployment) | Self-hosted |\n| [Gemini](https://aistudio.google.com/) | Yes | May contain errors | Easy | Paid API |\n| [Whisper](https://github.com/openai/whisper) | No | May contain errors | Moderate | Self-hosted / Paid API |\n| [ElevenLabs](https://elevenlabs.io/app/developers) | No | May contain errors | Moderate | Paid API (generous free tier) |\n\nThis project provides transcription scripts under `scripts/lora_data_prepare/`:\n\n- `whisper_transcription.py` — Transcription via OpenAI Whisper API\n- `elevenlabs_transcription.py` — Transcription via ElevenLabs Scribe API\n\nBoth scripts support the `process_folder()` method for batch processing entire folders.\n\n#### Review and Cleanup (Required)\n\nTranscribed lyrics may contain errors and **must be manually reviewed and corrected**.\n\nIf you are using LRC format lyrics, you need to remove the timestamps. Here is a simple cleanup example:\n\n```python\nimport re\n\ndef clean_lrc_content(lines):\n    \"\"\"Clean LRC file content by removing timestamps\"\"\"\n    result = []\n    for line in lines:\n        line = line.strip()\n        if not line:\n            continue\n        # Remove timestamps [mm:ss.x] [mm:ss.xx] [mm:ss.xxx]\n        cleaned = re.sub(r\"\\[\\d{2}:\\d{2}\\.\\d{1,3}\\]\", \"\", line)\n        result.append(cleaned)\n\n    # Remove trailing empty lines\n    while result and not result[-1]:\n        result.pop()\n\n    return result\n```\n\n#### Structural Tags (Optional)\n\nIncluding structural tags in lyrics (such as `[Verse]`, `[Chorus]`, etc.) helps the model learn song structure more effectively. Training without structural tags is also possible.\n\n> **Tip:** You can use [Gemini](https://aistudio.google.com/) to add structural tags to existing lyrics.\n\nExample:\n\n```\n[Intro]\nLa la la...\n\n[Verse 1]\nWalking down the empty street\nEchoes dancing at my feet\n\n[Chorus]\nWe are the stars tonight\nShining through the endless sky\n\n[Bridge]\nClose your eyes and feel the sound\n```\n\n---\n\n### Automatic Annotation\n\n#### 1. Obtaining BPM and Key\n\nUse [Key-BPM-Finder](https://vocalremover.org/key-bpm-finder) to obtain BPM and key annotations online:\n\n1. Open the webpage and click **Browse my files** to select the audio files to process (processing too many at once may cause the page to freeze — batch processing and merging CSVs is recommended). Processing is done locally and files are not uploaded to a server.\n   ![key-bpm-finder-0.jpg](../pics/key-bpm-finder-0.jpg)\n\n2. After processing, click **Export CSV** to download the CSV file.\n   ![key-bpm-finder-1.jpg](../pics/key-bpm-finder-1.jpg)\n\n3. CSV file content example:\n\n   ```csv\n   File,Artist,Title,BPM,Key,Camelot\n   song1.wav,,,190,D major,10B\n   song2.wav,,,128,A minor,8A\n   ```\n\n4. Place the CSV file in the dataset folder. To include caption data, add an extra column after `Camelot`.\n\n#### 2. Obtaining Captions\n\nCaptions can be obtained in the following ways:\n\n- **Using acestep-5Hz-lm** (0.6B / 1.7B / 4B) — Via the Auto Label feature in the Gradio UI (see subsequent steps)\n- **Using Gemini API** — Refer to the script `scripts/lora_data_prepare/gemini_caption.py`, which supports `process_folder()` for batch processing and generates the following for each audio file:\n  - `{filename}.lyrics.txt` — Lyrics\n  - `{filename}.caption.txt` — Caption description\n\n---\n\n## Data Preprocessing\n\nOnce data is prepared, you can use the Gradio UI for data review and preprocessing.\n\n> **Important:** If using a startup script, you need to modify the launch parameters to disable service pre-initialization:\n>\n> - **Windows** (`start_gradio_ui.bat`): Change `if not defined INIT_SERVICE set INIT_SERVICE=--init_service true` to `if not defined INIT_SERVICE set INIT_SERVICE=--init_service false`\n> - **Linux/macOS** (`start_gradio_ui.sh`): Change `: \"${INIT_SERVICE:=--init_service true}\"` to `: \"${INIT_SERVICE:=--init_service false}\"`\n\nLaunch the Gradio UI (via the startup script or by running `acestep/acestep_v15_pipeline.py` directly).\n\n### Step 1: Load Models\n\n- **If you need to use LM for caption generation:** Select the desired LM model during initialization (acestep-5Hz-lm-0.6B / 1.7B / 4B).\n  ![](../pics/00_select_model_to_load.jpg)\n\n- **If you don't need LM:** Do not select any LM model.\n  ![](../pics/00_select_model_to_load_1.jpg)\n\n### Step 2: Load Data\n\nSwitch to the **LoRA Training** tab, enter the dataset directory path, and click **Scan**.\n\nThe scanner automatically recognizes the following files:\n\n| File | Description |\n|------|-------------|\n| `*.mp3` / `*.wav` / `*.flac` / ... | Audio files |\n| `{filename}.lyrics.txt` (or `{filename}.txt`) | Lyrics |\n| `{filename}.caption.txt` | Caption description |\n| `{filename}.json` | Annotation metadata (caption / bpm / keyscale / timesignature / language) |\n| `*.csv` | Batch BPM / Key annotations (exported from Key-BPM-Finder) |\n\n![](../pics/01_load_dataset_path.jpg)\n\n### Step 3: Review and Adjust Dataset\n\n- **Duration** — Automatically read from the audio file\n- **Lyrics** — Requires a corresponding `.lyrics.txt` file (`.txt` is also supported)\n- **Labeled** — Shows ✅ if caption exists, ❌ otherwise\n- **BPM / Key / Caption** — Loaded from JSON or CSV files\n- If the dataset is not entirely instrumental, uncheck **All Instrumental**\n- **Format Lyrics** and **Transcribe Lyrics** are currently disabled (not yet integrated with [acestep-transcriber](https://huggingface.co/ACE-Step/acestep-transcriber); using LM directly tends to produce hallucinations)\n- Enter a **Custom Trigger Tag** (currently has limited effect; any option other than `Replace Caption` is fine)\n- **Genre Ratio** controls the proportion of samples using genre instead of caption. Since the current LM-generated genre descriptions are far less descriptive than captions, keep this at 0\n\n![](../pics/02_preview_dataset.jpg)\n\n### Step 4: Auto Label Data\n\n- If you already have captions, you can skip this step\n- If your data lacks captions, use LM inference to generate them\n- If BPM / Key values are missing, obtain them via [Key-BPM-Finder](https://vocalremover.org/key-bpm-finder) first — generating them directly with LM will produce hallucinations\n\n![](../pics/03_label_data.jpg)\n\n### Step 5: Review and Edit Data\n\nIf needed, you can review and modify data entry by entry. **Remember to click Save after editing each entry.**\n\n![](../pics/04_edit_data.jpg)\n\n### Step 6: Save Dataset\n\nEnter a save path to export the dataset as a JSON file.\n\n![](../pics/05_save_dataset.jpg)\n\n### Step 7: Preprocess and Generate Tensor Files\n\n> **Note:** If you previously used LM to generate captions and VRAM is insufficient, restart Gradio to free VRAM first. When restarting, **do not select the LM model**. After restarting, enter the path to the saved JSON file and load it.\n\nEnter the save path for tensor files, click to start preprocessing, and wait for it to complete.\n\n![](../pics/06_preprocess_tensor.jpg)\n\n---\n\n## Training\n\n> **Note:** After generating tensor files, it is also recommended to restart Gradio to free VRAM.\n\n1. Switch to the **Train LoRA** tab, enter the tensor file path, and load the dataset.\n2. If you are unfamiliar with training parameters, the default values are generally fine.\n\n### Parameter Reference\n\n| Parameter | Description | Suggested Value |\n|-----------|-------------|-----------------|\n| **Max Epochs** | Adjust based on dataset size | ~100 songs → 500 epochs; 10–20 songs → 800 epochs (for reference only) |\n| **Batch Size** | Can be increased if VRAM is sufficient | 1 (default); try 2 or 4 if VRAM allows |\n| **Save Every N Epochs** | Checkpoint save interval | Set smaller for fewer Max Epochs, larger for more |\n\n> The above values are for reference only. Please adjust based on your actual situation.\n\n> **💡 LoKr Recommendation:** LoKR has greatly improved training efficiency. What used to take an hour now only takes 5 minutes—over 10 times faster. This is crucial for training on consumer-grade GPUs. You can try LoKr training in the **Train LoKr** tab, or use the [Side-Step](https://github.com/koda-dernet/Side-Step) toolkit for CLI-based LoKr workflows. See the [Training Guide](../sidestep/Training%20Guide.md) for details.\n\n3. Click **Start Training** and wait for training to complete.\n\n![](../pics/07_train.jpg)\n\n---\n\n## Using LoRA\n\n1. After training completes, **restart Gradio** and reload models (do not select the LM model).\n2. Once the model is initialized, load the trained LoRA weights.\n   ![](../pics/08_load_lora.jpg)\n3. Start generating music.\n\nCongratulations! You have completed the entire LoRA training workflow.\n\n---\n\n## Advanced Training with Side-Step\n\nFor users who want more control over LoRA training — including corrected timestep sampling, LoKR adapters, CLI-based workflows, VRAM optimization, and gradient sensitivity analysis — the community-developed **[Side-Step](https://github.com/koda-dernet/Side-Step)** toolkit provides an advanced alternative. Its documentation is bundled in this repository under `docs/sidestep/`.\n\n| Topic | Description |\n|-------|-------------|\n| [Getting Started](../sidestep/Getting%20Started.md) | Installation, prerequisites, and first-run setup |\n| [End-to-End Tutorial](../sidestep/End-to-End%20Tutorial.md) | Complete walkthrough from raw audio to generation |\n| [Dataset Preparation](../sidestep/Dataset%20Preparation.md) | JSON schema, audio formats, metadata fields, custom tags |\n| [Training Guide](../sidestep/Training%20Guide.md) | LoRA vs LoKR, corrected vs vanilla mode, hyperparameter guide |\n| [Using Your Adapter](../sidestep/Using%20Your%20Adapter.md) | Output layout, loading in Gradio, LoKR limitations |\n| [VRAM Optimization Guide](../sidestep/VRAM%20Optimization%20Guide.md) | GPU memory profiles and optimization strategies |\n| [Estimation Guide](../sidestep/Estimation%20Guide.md) | Gradient sensitivity analysis for targeted training |\n| [Shift and Timestep Sampling](../sidestep/Shift%20and%20Timestep%20Sampling.md) | How training timesteps work and why Side-Step differs from the built-in trainer |\n| [Preset Management](../sidestep/Preset%20Management.md) | Built-in presets, save/load/import/export |\n| [The Settings Wizard](../sidestep/The%20Settings%20Wizard.md) | Complete wizard settings reference |\n| [Model Management](../sidestep/Model%20Management.md) | Checkpoint structure and fine-tune support |\n| [Windows Notes](../sidestep/Windows%20Notes.md) | Windows-specific setup and workarounds |\n"
  },
  {
    "path": "docs/en/Openrouter_API_DOC.md",
    "content": "# ACE-Step OpenRouter API Documentation\n\n> OpenAI Chat Completions-compatible API for AI music generation\n\n**Base URL:** `http://{host}:{port}` (default `http://127.0.0.1:8002`)\n\n---\n\n## Table of Contents\n\n- [Authentication](#authentication)\n- [Endpoints](#endpoints)\n  - [POST /v1/chat/completions - Generate Music](#1-generate-music)\n  - [GET /v1/models - List Models](#2-list-models)\n  - [GET /health - Health Check](#3-health-check)\n- [Input Modes](#input-modes)\n- [Audio Input](#audio-input)\n- [Streaming Responses](#streaming-responses)\n- [Examples](#examples)\n- [Error Codes](#error-codes)\n\n---\n\n## Authentication\n\nIf the server is configured with an API key (via the `OPENROUTER_API_KEY` environment variable or `--api-key` CLI flag), all requests must include the following header:\n\n```\nAuthorization: Bearer <your-api-key>\n```\n\nNo authentication is required when no API key is configured.\n\n---\n\n## Endpoints\n\n### 1. Generate Music\n\n**POST** `/v1/chat/completions`\n\nGenerates music from chat messages and returns audio data along with LM-generated metadata.\n\n#### Request Parameters\n\n| Field | Type | Required | Default | Description |\n|---|---|---|---|---|\n| `model` | string | No | auto | Model ID (obtain from `/v1/models`) |\n| `messages` | array | **Yes** | - | Chat message list. See [Input Modes](#input-modes) |\n| `stream` | boolean | No | `false` | Enable streaming response. See [Streaming Responses](#streaming-responses) |\n| `audio_config` | object | No | `null` | Audio generation configuration. See below |\n| `temperature` | float | No | `0.85` | LM sampling temperature |\n| `top_p` | float | No | `0.9` | LM nucleus sampling parameter |\n| `seed` | int \\| string | No | `null` | Random seed. When `batch_size > 1`, use comma-separated values, e.g. `\"42,123,456\"` |\n| `lyrics` | string | No | `\"\"` | Lyrics passed directly (takes priority over lyrics parsed from messages). When set, messages text becomes the prompt |\n| `sample_mode` | boolean | No | `false` | Enable LLM sample mode. Messages text becomes sample_query for LLM to auto-generate prompt/lyrics |\n| `thinking` | boolean | No | `false` | Enable LLM thinking mode for deeper reasoning |\n| `use_format` | boolean | No | `false` | When user provides prompt/lyrics, enhance them via LLM formatting |\n| `use_cot_caption` | boolean | No | `true` | Rewrite/enhance the music description via Chain-of-Thought |\n| `use_cot_language` | boolean | No | `true` | Auto-detect vocal language via Chain-of-Thought |\n| `guidance_scale` | float | No | `7.0` | Classifier-free guidance scale |\n| `batch_size` | int | No | `1` | Number of audio samples to generate |\n| `task_type` | string | No | `\"text2music\"` | Task type. See [Audio Input](#audio-input) |\n| `repainting_start` | float | No | `0.0` | Repaint region start position (seconds) |\n| `repainting_end` | float | No | `null` | Repaint region end position (seconds) |\n| `audio_cover_strength` | float | No | `1.0` | Cover strength (0.0~1.0) |\n\n#### audio_config Object\n\n| Field | Type | Default | Description |\n|---|---|---|---|\n| `duration` | float | `null` | Audio duration in seconds. If omitted, determined automatically by the LM |\n| `bpm` | integer | `null` | Beats per minute. If omitted, determined automatically by the LM |\n| `vocal_language` | string | `\"en\"` | Vocal language code (e.g. `\"zh\"`, `\"en\"`, `\"ja\"`) |\n| `instrumental` | boolean | `null` | Whether to generate instrumental-only (no vocals). If omitted, auto-determined from lyrics |\n| `format` | string | `\"mp3\"` | Output audio format |\n| `key_scale` | string | `null` | Musical key (e.g. `\"C major\"`) |\n| `time_signature` | string | `null` | Time signature (e.g. `\"4/4\"`) |\n\n> **Messages text meaning depends on the mode:**\n> - If `lyrics` is set → messages text = caption\n> - If `sample_mode: true` is set → messages text = sample_query (let LLM generate everything)\n> - Neither set → auto-detect: tags → tag mode, lyrics-like → lyrics mode, otherwise used as caption directly for generation\n\n#### messages Format\n\nSupports both plain text and multimodal (text + audio) formats:\n\n**Plain text:**\n\n```json\n{\n  \"messages\": [\n    {\"role\": \"user\", \"content\": \"Your input content\"}\n  ]\n}\n```\n\n**Multimodal (with audio input):**\n\n```json\n{\n  \"messages\": [\n    {\n      \"role\": \"user\",\n      \"content\": [\n        {\"type\": \"text\", \"text\": \"Cover this song\"},\n        {\n          \"type\": \"input_audio\",\n          \"input_audio\": {\n            \"data\": \"<base64 audio data>\",\n            \"format\": \"mp3\"\n          }\n        }\n      ]\n    }\n  ]\n}\n```\n\n---\n\n#### Non-Streaming Response (`stream: false`)\n\n```json\n{\n  \"id\": \"chatcmpl-a1b2c3d4e5f6g7h8\",\n  \"object\": \"chat.completion\",\n  \"created\": 1706688000,\n  \"model\": \"acemusic/acestep-v15-turbo\",\n  \"choices\": [\n    {\n      \"index\": 0,\n      \"message\": {\n        \"role\": \"assistant\",\n        \"content\": \"## Metadata\\n**Caption:** Upbeat pop song...\\n**BPM:** 120\\n**Duration:** 30s\\n**Key:** C major\\n\\n## Lyrics\\n[Verse 1]\\nHello world...\",\n        \"audio\": [\n          {\n            \"type\": \"audio_url\",\n            \"audio_url\": {\n              \"url\": \"data:audio/mpeg;base64,SUQzBAAAAAAAI1RTU0UAAAA...\"\n            }\n          }\n        ]\n      },\n      \"finish_reason\": \"stop\"\n    }\n  ],\n  \"usage\": {\n    \"prompt_tokens\": 10,\n    \"completion_tokens\": 100,\n    \"total_tokens\": 110\n  }\n}\n```\n\n**Response Fields:**\n\n| Field | Description |\n|---|---|\n| `choices[0].message.content` | Text information generated by the LM, including Metadata (Caption/BPM/Duration/Key/Time Signature/Language) and Lyrics. Returns `\"Music generated successfully.\"` if LM was not involved |\n| `choices[0].message.audio` | Audio data array. Each item contains `type` (`\"audio_url\"`) and `audio_url.url` (Base64 Data URL in format `data:audio/mpeg;base64,...`) |\n| `choices[0].finish_reason` | `\"stop\"` indicates normal completion |\n\n**Decoding Audio:**\n\nThe `audio_url.url` value is a Data URL: `data:audio/mpeg;base64,<base64_data>`\n\nExtract the base64 portion after the comma and decode it to get the MP3 file:\n\n```python\nimport base64\n\nurl = response[\"choices\"][0][\"message\"][\"audio\"][0][\"audio_url\"][\"url\"]\n# Strip the \"data:audio/mpeg;base64,\" prefix\nb64_data = url.split(\",\", 1)[1]\naudio_bytes = base64.b64decode(b64_data)\n\nwith open(\"output.mp3\", \"wb\") as f:\n    f.write(audio_bytes)\n```\n\n```javascript\nconst url = response.choices[0].message.audio[0].audio_url.url;\nconst b64Data = url.split(\",\")[1];\nconst audioBytes = atob(b64Data);\n// Or use the Data URL directly in an <audio> element\nconst audio = new Audio(url);\naudio.play();\n```\n\n---\n\n### 2. List Models\n\n**GET** `/v1/models`\n\nReturns available model information.\n\n#### Response\n\n```json\n{\n  \"data\": [\n    {\n      \"id\": \"acemusic/acestep-v15-turbo\",\n      \"name\": \"ACE-Step\",\n      \"created\": 1706688000,\n      \"description\": \"High-performance text-to-music generation model. Supports multiple styles, lyrics input, and various audio durations.\",\n      \"input_modalities\": [\"text\", \"audio\"],\n      \"output_modalities\": [\"audio\", \"text\"],\n      \"context_length\": 4096,\n      \"pricing\": {\"prompt\": \"0\", \"completion\": \"0\", \"request\": \"0\"},\n      \"supported_sampling_parameters\": [\"temperature\", \"top_p\"]\n    }\n  ]\n}\n```\n\n---\n\n### 3. Health Check\n\n**GET** `/health`\n\n#### Response\n\n```json\n{\n  \"status\": \"ok\",\n  \"service\": \"ACE-Step OpenRouter API\",\n  \"version\": \"1.0\"\n}\n```\n\n---\n\n## Input Modes\n\nThe system automatically selects the input mode based on the content of the last `user` message. You can also explicitly specify via the `lyrics` or `sample_mode` fields.\n\n### Mode 1: Tagged Mode (Recommended)\n\nUse `<prompt>` and `<lyrics>` tags to explicitly specify the music description and lyrics:\n\n```json\n{\n  \"messages\": [\n    {\n      \"role\": \"user\",\n      \"content\": \"<prompt>A gentle acoustic ballad in C major, female vocal</prompt>\\n<lyrics>[Verse 1]\\nSunlight through the window\\nA brand new day begins\\n\\n[Chorus]\\nWe are the dreamers\\nWe are the light</lyrics>\"\n    }\n  ],\n  \"audio_config\": {\n    \"duration\": 30,\n    \"vocal_language\": \"en\"\n  }\n}\n```\n\n- `<prompt>...</prompt>` — Music style/scene description (caption)\n- `<lyrics>...</lyrics>` — Lyrics content\n- Either tag can be used alone\n- When `use_format: true`, the LLM automatically enhances both prompt and lyrics\n\n### Mode 2: Natural Language Mode (Sample Mode)\n\nDescribe the desired music in natural language. The system uses LLM to generate the prompt and lyrics automatically:\n\n```json\n{\n  \"messages\": [\n    {\"role\": \"user\", \"content\": \"Generate an upbeat pop song about summer and travel\"}\n  ],\n  \"sample_mode\": true,\n  \"audio_config\": {\n    \"vocal_language\": \"en\"\n  }\n}\n```\n\nTrigger condition: `sample_mode: true`, or message content contains no tags and does not resemble lyrics.\n\n### Mode 3: Lyrics-Only Mode\n\nPass in lyrics with structural markers directly. The system identifies them automatically:\n\n```json\n{\n  \"messages\": [\n    {\n      \"role\": \"user\",\n      \"content\": \"[Verse 1]\\nWalking down the street\\nFeeling the beat\\n\\n[Chorus]\\nDance with me tonight\\nUnder the moonlight\"\n    }\n  ],\n  \"audio_config\": {\"duration\": 30}\n}\n```\n\nTrigger condition: Message content contains `[Verse]`, `[Chorus]`, or similar markers, or has a multi-line short-text structure.\n\n### Mode 4: Lyrics + Prompt Separation\n\nUse the `lyrics` field to pass lyrics directly, and messages text automatically becomes the prompt:\n\n```json\n{\n  \"messages\": [\n    {\"role\": \"user\", \"content\": \"Energetic EDM with heavy bass drops\"}\n  ],\n  \"lyrics\": \"[Verse 1]\\nFeel the rhythm in your soul\\nLet the music take control\\n\\n[Drop]\\n(instrumental break)\",\n  \"audio_config\": {\n    \"bpm\": 128,\n    \"duration\": 60\n  }\n}\n```\n\n### Instrumental Mode\n\nSet `audio_config.instrumental: true`:\n\n```json\n{\n  \"messages\": [\n    {\"role\": \"user\", \"content\": \"<prompt>Epic orchestral cinematic score, dramatic and powerful</prompt>\"}\n  ],\n  \"audio_config\": {\n    \"instrumental\": true,\n    \"duration\": 30\n  }\n}\n```\n\n---\n\n## Audio Input\n\nAudio files can be passed via multimodal messages (base64 encoded) for cover, repaint, and other tasks.\n\n### task_type Types\n\n| task_type | Description | Audio Input Required |\n|---|---|---|\n| `text2music` | Text to music (default) | Optional (as reference) |\n| `cover` | Cover/style transfer | Requires src_audio |\n| `repaint` | Partial repaint | Requires src_audio |\n| `lego` | Audio splicing | Requires src_audio |\n| `extract` | Audio extraction | Requires src_audio |\n| `complete` | Audio continuation | Requires src_audio |\n\n### Audio Routing Rules\n\nMultiple `input_audio` blocks are routed to different parameters in order (similar to multi-image upload):\n\n| task_type | audio[0] | audio[1] |\n|---|---|---|\n| `text2music` | reference_audio (style reference) | - |\n| `cover/repaint/lego/extract/complete` | src_audio (audio to edit) | reference_audio (optional style reference) |\n\n### Audio Input Examples\n\n**Cover Task:**\n\n```json\n{\n  \"messages\": [\n    {\n      \"role\": \"user\",\n      \"content\": [\n        {\"type\": \"text\", \"text\": \"<prompt>Jazz style cover with saxophone</prompt>\"},\n        {\n          \"type\": \"input_audio\",\n          \"input_audio\": {\"data\": \"<base64 source audio>\", \"format\": \"mp3\"}\n        }\n      ]\n    }\n  ],\n  \"task_type\": \"cover\",\n  \"audio_cover_strength\": 0.8,\n  \"audio_config\": {\"duration\": 30}\n}\n```\n\n**Repaint Task:**\n\n```json\n{\n  \"messages\": [\n    {\n      \"role\": \"user\",\n      \"content\": [\n        {\"type\": \"text\", \"text\": \"<prompt>Replace with guitar solo</prompt>\"},\n        {\n          \"type\": \"input_audio\",\n          \"input_audio\": {\"data\": \"<base64 source audio>\", \"format\": \"mp3\"}\n        }\n      ]\n    }\n  ],\n  \"task_type\": \"repaint\",\n  \"repainting_start\": 10.0,\n  \"repainting_end\": 20.0,\n  \"audio_config\": {\"duration\": 30}\n}\n```\n\n---\n\n## Streaming Responses\n\nSet `\"stream\": true` to enable SSE (Server-Sent Events) streaming.\n\n### Event Format\n\nEach event starts with `data: `, followed by JSON, ending with a double newline `\\n\\n`:\n\n```\ndata: {\"id\":\"chatcmpl-xxx\",\"object\":\"chat.completion.chunk\",\"created\":1706688000,\"model\":\"acemusic/acestep-v15-turbo\",\"choices\":[{\"index\":0,\"delta\":{...},\"finish_reason\":null}]}\n\n```\n\n### Streaming Event Sequence\n\n| Phase | Delta Content | Description |\n|---|---|---|\n| 1. Initialization | `{\"role\":\"assistant\",\"content\":\"\"}` | Establishes the connection |\n| 2. LM Content | `{\"content\":\"\\n\\n## Metadata\\n...\"}` | Metadata and lyrics pushed after LM generation (if LM was used) |\n| 3. Heartbeat | `{\"content\":\".\"}` | Sent every 2 seconds during audio generation to keep the connection alive |\n| 4. Audio Data | `{\"audio\":[{\"type\":\"audio_url\",\"audio_url\":{\"url\":\"data:...\"}}]}` | Audio base64 data |\n| 5. Finish | `finish_reason: \"stop\"` | Generation complete |\n| 6. Termination | `data: [DONE]` | End-of-stream marker |\n\n### Streaming Response Example\n\n```\ndata: {\"id\":\"chatcmpl-abc123\",\"object\":\"chat.completion.chunk\",\"created\":1706688000,\"model\":\"acemusic/acestep-v15-turbo\",\"choices\":[{\"index\":0,\"delta\":{\"role\":\"assistant\",\"content\":\"\"},\"finish_reason\":null}]}\n\ndata: {\"id\":\"chatcmpl-abc123\",\"object\":\"chat.completion.chunk\",\"created\":1706688000,\"model\":\"acemusic/acestep-v15-turbo\",\"choices\":[{\"index\":0,\"delta\":{\"content\":\"\\n\\n## Metadata\\n**Caption:** Upbeat pop\\n**BPM:** 120\"},\"finish_reason\":null}]}\n\ndata: {\"id\":\"chatcmpl-abc123\",\"object\":\"chat.completion.chunk\",\"created\":1706688000,\"model\":\"acemusic/acestep-v15-turbo\",\"choices\":[{\"index\":0,\"delta\":{\"content\":\".\"},\"finish_reason\":null}]}\n\ndata: {\"id\":\"chatcmpl-abc123\",\"object\":\"chat.completion.chunk\",\"created\":1706688000,\"model\":\"acemusic/acestep-v15-turbo\",\"choices\":[{\"index\":0,\"delta\":{\"audio\":[{\"type\":\"audio_url\",\"audio_url\":{\"url\":\"data:audio/mpeg;base64,...\"}}]},\"finish_reason\":null}]}\n\ndata: {\"id\":\"chatcmpl-abc123\",\"object\":\"chat.completion.chunk\",\"created\":1706688000,\"model\":\"acemusic/acestep-v15-turbo\",\"choices\":[{\"index\":0,\"delta\":{},\"finish_reason\":\"stop\"}]}\n\ndata: [DONE]\n\n```\n\n### Client-Side Streaming Handling\n\n```python\nimport json\nimport httpx\n\nwith httpx.stream(\"POST\", \"http://127.0.0.1:8002/v1/chat/completions\", json={\n    \"messages\": [{\"role\": \"user\", \"content\": \"Generate a cheerful guitar piece\"}],\n    \"sample_mode\": True,\n    \"stream\": True,\n    \"audio_config\": {\"instrumental\": True}\n}) as response:\n    content_parts = []\n    audio_url = None\n\n    for line in response.iter_lines():\n        if not line or not line.startswith(\"data: \"):\n            continue\n        if line == \"data: [DONE]\":\n            break\n\n        chunk = json.loads(line[6:])\n        delta = chunk[\"choices\"][0][\"delta\"]\n\n        if \"content\" in delta and delta[\"content\"]:\n            content_parts.append(delta[\"content\"])\n\n        if \"audio\" in delta and delta[\"audio\"]:\n            audio_url = delta[\"audio\"][0][\"audio_url\"][\"url\"]\n\n        if chunk[\"choices\"][0].get(\"finish_reason\") == \"stop\":\n            print(\"Generation complete!\")\n\n    print(\"Content:\", \"\".join(content_parts))\n    if audio_url:\n        import base64\n        b64_data = audio_url.split(\",\", 1)[1]\n        with open(\"output.mp3\", \"wb\") as f:\n            f.write(base64.b64decode(b64_data))\n```\n\n```javascript\nconst response = await fetch(\"http://127.0.0.1:8002/v1/chat/completions\", {\n  method: \"POST\",\n  headers: { \"Content-Type\": \"application/json\" },\n  body: JSON.stringify({\n    messages: [{ role: \"user\", content: \"Generate a cheerful guitar piece\" }],\n    sample_mode: true,\n    stream: true,\n    audio_config: { instrumental: true }\n  })\n});\n\nconst reader = response.body.getReader();\nconst decoder = new TextDecoder();\nlet audioUrl = null;\nlet content = \"\";\n\nwhile (true) {\n  const { done, value } = await reader.read();\n  if (done) break;\n\n  const text = decoder.decode(value);\n  for (const line of text.split(\"\\n\")) {\n    if (!line.startsWith(\"data: \") || line === \"data: [DONE]\") continue;\n\n    const chunk = JSON.parse(line.slice(6));\n    const delta = chunk.choices[0].delta;\n\n    if (delta.content) content += delta.content;\n    if (delta.audio) audioUrl = delta.audio[0].audio_url.url;\n  }\n}\n\n// audioUrl can be used directly as <audio src=\"...\">\n```\n\n---\n\n## Examples\n\n### Example 1: Natural Language Generation (Simplest Usage)\n\n```bash\ncurl -X POST http://127.0.0.1:8002/v1/chat/completions \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\n    \"messages\": [\n      {\"role\": \"user\", \"content\": \"A soft folk song about hometown and memories\"}\n    ],\n    \"sample_mode\": true,\n    \"audio_config\": {\"vocal_language\": \"en\"}\n  }'\n```\n\n### Example 2: Tagged Mode with Specific Parameters\n\n```bash\ncurl -X POST http://127.0.0.1:8002/v1/chat/completions \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\n    \"messages\": [\n      {\n        \"role\": \"user\",\n        \"content\": \"<prompt>Energetic EDM track with heavy bass drops and synth leads</prompt><lyrics>[Verse 1]\\nFeel the rhythm in your soul\\nLet the music take control\\n\\n[Drop]\\n(instrumental break)</lyrics>\"\n      }\n    ],\n    \"audio_config\": {\n      \"bpm\": 128,\n      \"duration\": 60,\n      \"vocal_language\": \"en\"\n    }\n  }'\n```\n\n### Example 3: Instrumental with LM Enhancement Disabled\n\n```bash\ncurl -X POST http://127.0.0.1:8002/v1/chat/completions \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\n    \"messages\": [\n      {\n        \"role\": \"user\",\n        \"content\": \"<prompt>Peaceful piano solo, slow tempo, jazz harmony</prompt>\"\n      }\n    ],\n    \"use_cot_caption\": false,\n    \"audio_config\": {\n      \"instrumental\": true,\n      \"duration\": 45\n    }\n  }'\n```\n\n### Example 4: Streaming Request\n\n```bash\ncurl -X POST http://127.0.0.1:8002/v1/chat/completions \\\n  -H \"Content-Type: application/json\" \\\n  -N \\\n  -d '{\n    \"messages\": [\n      {\"role\": \"user\", \"content\": \"Generate a happy birthday song\"}\n    ],\n    \"sample_mode\": true,\n    \"stream\": true\n  }'\n```\n\n### Example 5: Multi-Seed Batch Generation\n\n```bash\ncurl -X POST http://127.0.0.1:8002/v1/chat/completions \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\n    \"messages\": [\n      {\"role\": \"user\", \"content\": \"<prompt>Lo-fi hip hop beat</prompt>\"}\n    ],\n    \"batch_size\": 3,\n    \"seed\": \"42,123,456\",\n    \"audio_config\": {\n      \"instrumental\": true,\n      \"duration\": 30\n    }\n  }'\n```\n\n---\n\n## Error Codes\n\n| HTTP Status | Description |\n|---|---|\n| 400 | Invalid request format or missing valid input |\n| 401 | Missing or invalid API key |\n| 429 | Service busy, queue full |\n| 500 | Internal error during music generation |\n| 503 | Model not yet initialized |\n| 504 | Generation timeout |\n\nError response format:\n\n```json\n{\n  \"detail\": \"Error description message\"\n}\n```\n\n---\n\n## Server Configuration (Environment Variables)\n\nThe following environment variables can be used to configure the server (for operations reference):\n\n| Variable | Default | Description |\n|---|---|---|\n| `OPENROUTER_API_KEY` | None | API authentication key |\n| `OPENROUTER_HOST` | `127.0.0.1` | Listen address |\n| `OPENROUTER_PORT` | `8002` | Listen port |\n| `ACESTEP_CONFIG_PATH` | `acestep-v15-turbo` | DiT model configuration path |\n| `ACESTEP_DEVICE` | `auto` | Inference device |\n| `ACESTEP_LM_MODEL_PATH` | `acestep-5Hz-lm-0.6B` | LLM model path |\n| `ACESTEP_LM_BACKEND` | `vllm` | LLM inference backend |\n| `ACESTEP_QUEUE_MAXSIZE` | `200` | Task queue max capacity |\n| `ACESTEP_GENERATION_TIMEOUT` | `600` | Non-streaming request timeout (seconds) |\n"
  },
  {
    "path": "docs/en/Tutorial.md",
    "content": "# ACE-Step 1.5 Ultimate Guide (Must Read)\n\n**Language / 语言 / 言語:** [English](Tutorial.md) | [中文](../zh/Tutorial.md) | [日本語](../ja/Tutorial.md)\n\n---\n\nHello everyone, I'm Gong Junmin, the developer of ACE-Step. Through this tutorial, I'll guide you through the design philosophy and usage of ACE-Step 1.5.\n\n## Mental Models\n\nBefore we begin, we need to establish the correct mental models to set proper expectations.\n\n### Human-Centered Design\n\nThis model is not designed for **one-click generation**, but for **human-centered generation**.\n\nUnderstanding this distinction is crucial.\n\n### What is One-Click Generation?\n\nYou input a prompt, click generate, listen to a few versions, pick one that sounds good, and use it. If someone else inputs the same prompt, they'll likely get similar results.\n\nIn this mode, you and AI have a **client-vendor** relationship. You come with a clear purpose, with a vague expectation in mind, hoping AI delivers a product close to that expectation. Essentially, it's not much different from searching on Google or finding songs on Spotify—just with a bit more customization.\n\nAI is a service, not a creative inspirer.\n\nSuno, Udio, MiniMax, Mureka—these platforms are all designed with this philosophy. They can scale up models as services to ensure delivery. Your generated music is bound by their agreements; you can't run it locally, can't fine-tune for personalized exploration; if they secretly change models or terms, you can only accept it.\n\n### What is Human-Centered Generation?\n\nIf we weaken the AI layer and strengthen the human layer—letting more human will, creativity, and inspiration give life to AI—this is human-centered generation.\n\nUnlike the strong purposefulness of one-click generation, human-centered generation has more of a **playful** nature. It's more like an interactive game where you and the model are **collaborators**.\n\nThe workflow is like this: you throw out some inspiration seeds, get a few songs, choose interesting directions from them to continue iterating—\n- Adjust prompts to regenerate\n- Use **Cover** to maintain structure and adjust details\n- Use **Repaint** for local modifications\n- Use **Add Layer** to add or remove instrument layers\n\nAt this point, AI is not a servant to you, but an **inspirer**.\n\n### What Conditions Must This Design Meet?\n\nFor human-centered generation to truly work, the model must meet several key conditions:\n\n**First, it must be open-source, locally runnable, and trainable.**\n\nThis isn't technical purism, but a matter of ownership. When you use closed-source platforms, you don't own the model, and your generated works are bound by their agreements. Version updates, term changes, service shutdowns—none of these are under your control.\n\nBut when the model is open-source and locally runnable, everything changes: **You forever own this model, and you forever own all the creations you make with it.** No third-party agreement hassles, no platform risks, you can fine-tune, modify, and build your own creative system based on it. Your works will forever belong to you. It's like buying an instrument—you can use it anytime, anywhere, and adjust it anytime, anywhere.\n\n**Second, it must be fast.**\n\nHuman time is precious, but more importantly—**slow generation breaks flow state**.\n\nThe core of human-centered workflow is the rapid cycle of \"try, listen, adjust.\" If each generation takes minutes, your inspiration dissipates while waiting, and the \"play\" experience degrades into the \"wait\" ordeal.\n\nTherefore, we specifically optimized ACE-Step for this: while ensuring quality, we made generation fast enough to support a smooth human-machine dialogue rhythm.\n\n### Finite Game vs Infinite Game\n\nOne-click generation is a **finite game**—clear goals, result-oriented, ends at the finish line. To some extent, it coldly hollows out the music industry, replacing many people's jobs.\n\nHuman-centered generation is an **infinite game**—because the fun lies in the process, and the process never ends.\n\nOur vision is to democratize AI music generation. Let ACE-Step become a big toy in your pocket, let music return to **Play** itself—the creative \"play,\" not just clicking play.\n\n---\n\n## The Elephant Rider Metaphor\n\n> Recommended reading: [The Complete Guide to Mastering Suno](https://www.notion.so/The-Complete-Guide-to-Mastering-Suno-Advanced-Strategies-for-Professional-Music-Generation-2d6ae744ebdf8024be42f6645f884221)—this blog tutorial can help you establish the foundational understanding of AI music.\n\nAI music generation is like the famous **elephant rider metaphor** in psychology.\n\nConsciousness rides on the subconscious, humans ride on elephants. You can give directions, but you can't make the elephant precisely and instantly execute every command. It has its own inertia, its own temperament, its own will.\n\nThis elephant is the music generation model.\n\n### The Iceberg Model\n\nBetween audio and semantics lies a hidden iceberg.\n\nWhat we can describe with language—style, instruments, timbre, emotion, scenes, progression, lyrics, vocal style—these are familiar words, the parts we can touch. But together, they're still just a tiny tip of the audio iceberg above the water.\n\nWhat's the most precise control? You input the expected audio, and the model returns it unchanged.\n\nBut as long as you're using text descriptions, references, prompts—the model will have room to play. This isn't a bug, it's the nature of things.\n\n### What is the Elephant?\n\nThis elephant is a fusion of countless elements: data distribution, model scale, algorithm design, annotation bias, evaluation bias—**it's an abstract crystallization of human music history and engineering trade-offs.**\n\nAny deviation in these elements will cause it to fail to accurately reflect your taste and expectations.\n\nOf course, we can expand data scale, improve algorithm efficiency, increase annotation precision, expand model capacity, introduce more professional evaluation systems—these are all directions we can optimize as model developers.\n\nBut even if one day we achieve technical \"perfection,\" there's still a fundamental problem we can't avoid: **taste.**\n\n### Taste and Expectations\n\nTaste varies from person to person.\n\nIf a music generation model tries to please all listeners, its output will tend toward the popular average of human music history—**this will be extremely mediocre.**\n\nIt's humans who give sound meaning, emotion, experience, life, and cultural symbolic value. It's a small group of artists who create unique tastes, then drive ordinary people to consume and follow, turning niche into mainstream popularity. These pioneering minority artists become legends.\n\nSo when you find the model's output \"not to your taste,\" this might not be the model's problem—**but rather your taste happens to be outside that \"average.\"** This is a good thing.\n\nThis means: **You need to learn to guide this elephant, not expect it to automatically understand you.**\n\n---\n\n## Knowing the Elephant Herd: Model Architecture and Selection\n\nNow you understand the \"elephant\" metaphor. But actually—\n\n**This isn't one elephant, but an entire herd—elephants large and small, forming a family.** 🐘🐘🐘🐘\n\n### Architecture Principles: Two Brains\n\nACE-Step 1.5 uses a **hybrid architecture** with two core components working together:\n\n```\nUser Input → [5Hz LM] → Semantic Blueprint → [DiT] → Audio\n              ↓\n         Metadata Inference\n         Caption Optimization\n         Structure Planning\n```\n\n**5Hz LM (Language Model) — Planner (Optional)**\n\nThe LM is an \"omni-capable planner\" responsible for understanding your intent and making plans:\n- Infers music metadata (BPM, key, duration, etc.) through **Chain-of-Thought**\n- Optimizes and expands your caption—understanding and supplementing your intent\n- Generates **semantic codes**—implicitly containing composition melody, orchestration, and some timbre information\n\nThe LM learns **world knowledge** from training data. It's a planner that improves usability and helps you quickly generate prototypes.\n\n**But the LM is not required.**\n\nIf you're very clear about what you want, or already have a clear planning goal—you can completely skip the LM planning step by not using `thinking` mode.\n\nFor example, in **Cover mode**, you use reference audio to constrain composition, chords, and structure, letting DiT generate directly. Here, **you replace the LM's work**—you become the planner yourself.\n\nAnother example: in **Repaint mode**, you use reference audio as context, constraining timbre, mixing, and details, letting DiT directly adjust locally. Here, DiT is more like your creative brainstorming partner, helping with creative ideation and fixing local disharmony.\n\n**DiT (Diffusion Transformer) — Executor**\n\nDiT is the \"audio craftsman,\" responsible for turning plans into reality:\n- Receives semantic codes and conditions generated by LM\n- Gradually \"carves\" audio from noise through the **diffusion process**\n- Decides final timbre, mixing, details\n\n**Why this design?**\n\nTraditional methods let diffusion models generate audio directly from text, but text-to-audio mapping is too vague. ACE-Step introduces LM as an intermediate layer:\n- LM excels at understanding semantics and planning\n- DiT excels at generating high-fidelity audio\n- They work together, each doing their part\n\n### Choosing the Planner: LM Models\n\nLM has four options: **No LM** (disable thinking mode), **0.6B**, **1.7B**, **4B**.\n\nTheir training data is completely identical; the difference is purely in **knowledge capacity**:\n- Larger models have richer world knowledge\n- Larger models have stronger memory (e.g., remembering reference audio melodies)\n- Larger models perform relatively better on long-tail styles or instruments\n\n| Choice | Speed | World Knowledge | Memory | Use Cases |\n|--------|:-----:|:---------------:|:------:|-----------|\n| No LM | ⚡⚡⚡⚡ | — | — | You do the planning (e.g., Cover mode) |\n| `0.6B` | ⚡⚡⚡ | Basic | Weak | Low VRAM (< 8GB), rapid prototyping |\n| `1.7B` | ⚡⚡ | Medium | Medium | **Default recommendation** |\n| `4B` | ⚡ | Rich | Strong | Complex tasks, high-quality generation |\n\n**How to choose?**\n\nBased on your hardware:\n- **VRAM < 8GB** → No LM or `0.6B`\n- **VRAM 8–16GB** → `1.7B` (default)\n- **VRAM > 16GB** → `1.7B` or `4B`\n\n### Choosing the Executor: DiT Models\n\nWith a planning scheme, you still need to choose an executor. DiT is the core of ACE-Step 1.5—it handles various tasks and decides how to interpret LM-generated codes.\n\nWe've open-sourced **4 Turbo models**, **1 SFT model**, and **1 Base model**.\n\n#### Turbo Series (Recommended for Daily Use)\n\nTurbo models are trained with distillation, generating high-quality audio in just 8 steps. The core difference between the four variants is the **shift hyperparameter configuration during distillation**.\n\n**What is shift?**\n\nShift determines the \"attention allocation\" during DiT denoising:\n- **Larger shift** → More effort spent on early denoising (building large structure from pure noise), **stronger semantics**, clearer overall framework\n- **Smaller shift** → More even step distribution, **more details**, but details might also be noise\n\nSimple understanding: high shift is like \"draw outline first then fill details,\" low shift is like \"draw and fix simultaneously.\"\n\n| Model | Distillation Config | Characteristics |\n|-------|---------------------|-----------------|\n| `turbo` (default) | Joint distillation on shift 1, 2, 3 | **Best balance of creativity and semantics**, thoroughly tested, recommended first choice |\n| `turbo-shift1` | Distilled only on shift=1 | Richer details, but semantics weaker |\n| `turbo-shift3` | Distilled only on shift=3 | Clearer, richer timbre, but may sound \"dry,\" minimal orchestration |\n| `turbo-continuous` | Experimental, supports continuous shift 1–5 | Most flexible tuning, but not thoroughly tested |\n\nYou can choose based on target music style—you might find you prefer a certain variant. **We recommend starting with default turbo**—it's the most balanced and proven choice.\n\n#### SFT Model\n\nCompared to Turbo, SFT model has two notable features:\n- **Supports CFG** (Classifier-Free Guidance), allowing fine-tuning of prompt adherence\n- **More steps** (50 steps), giving the model more time to \"think\"\n\nThe cost: more steps mean error accumulation, audio clarity may be slightly inferior to Turbo. But its **detail expression and semantic parsing will be better**.\n\nIf you don't care about inference time, like tuning CFG and steps, and prefer that rich detail feel—SFT is a good choice. LM-generated codes can also work with SFT models.\n\n#### Base Model\n\nBase is the **master of all tasks**, with three exclusive tasks beyond SFT and Turbo:\n\n| Task | Description |\n|------|-------------|\n| `extract` | Extract single tracks from mixed audio (e.g., separate vocals) |\n| `lego` | Add new tracks to existing tracks (e.g., add drums to guitar) |\n| `complete` | Add mixed accompaniment to single track (e.g., add guitar+drums accompaniment to vocals) |\n\nAdditionally, Base has the **strongest plasticity**. If you have large-scale fine-tuning needs, we recommend starting experiments with Base to train your own SFT model.\n\n#### Creating Your Custom Model\n\nBeyond official models, you can also use **LoRA fine-tuning** to create your custom model.\n\nWe'll release an example LoRA model—trained on 20+ \"Happy New Year\" themed songs, specifically suited for expressing festive atmosphere. This is just a starting point.\n\n**What does a custom model mean?**\n\nYou can reshape DiT's capabilities and preferences with your own data recipe:\n- Like a specific timbre style? Train with that type of songs\n- Want the model better at a certain genre? Collect related data for fine-tuning\n- Have your own unique aesthetic taste? \"Teach\" it to the model\n\nThis greatly expands **customization and playability**—train a model unique to you with your aesthetic taste.\n\n> For the detailed LoRA training guide, see the [LoRA Training Tutorial](./LoRA_Training_Tutorial.md). You can also use the \"LoRA Training\" tab in Gradio UI for one-click training.\n\n#### DiT Selection Summary\n\n| Model | Steps | CFG | Speed | Exclusive Tasks | Recommended Scenarios |\n|-------|:-----:|:---:|:-----:|-----------------|----------------------|\n| `turbo` (default) | 8 | ❌ | ⚡⚡⚡ | — | Daily use, rapid iteration |\n| `sft` | 50 | ✅ | ⚡ | — | Pursuing details, like tuning |\n| `base` | 50 | ✅ | ⚡ | extract, lego, complete | Special tasks, large-scale fine-tuning |\n\n### Combination Strategies\n\nDefault configuration is **turbo + 1.7B LM**, suitable for most scenarios.\n\n| Need | Recommended Combination |\n|------|------------------------|\n| Fastest speed | `turbo` + No LM or `0.6B` |\n| Daily use | `turbo` + `1.7B` (default) |\n| Pursuing details | `sft` + `1.7B` or `4B` |\n| Special tasks | `base` |\n| Large-scale fine-tuning | `base` |\n| Low VRAM (< 4GB) | `turbo` + No LM + CPU offload |\n\n### Downloading Models\n\n```bash\n# Download default models (turbo + 1.7B LM)\nuv run acestep-download\n\n# Download all models\nuv run acestep-download --all\n\n# Download specific model\nuv run acestep-download --model acestep-v15-base\nuv run acestep-download --model acestep-5Hz-lm-0.6B\n\n# List available models\nuv run acestep-download --list\n```\n\nYou need to download models into a `checkpoints` folder for easy identification.\n\n---\n\n## Guiding the Elephant: What Can You Control?\n\nNow that you know this herd of elephants, let's learn how to communicate with them.\n\nEach generation is determined by three types of factors: **input control**, **inference hyperparameters**, and **random factors**.\n\n### I. Input Control: What Do You Want?\n\nThis is the part where you communicate \"creative intent\" with the model—what kind of music you want to generate.\n\n| Category | Parameter | Function |\n|----------|-----------|----------|\n| **Task Type** | `task_type` | Determines generation mode: text2music, cover, repaint, lego, extract, complete |\n| **Text Input** | `caption` | Description of overall music elements: style, instruments, emotion, atmosphere, timbre, vocal gender, progression, etc. |\n| | `lyrics` | Temporal element description: lyric content, music structure evolution, vocal changes, vocal/instrument performance style, start/end style, articulation, etc. (use `[Instrumental]` for instrumental music) |\n| **Music Metadata** | `bpm` | Tempo (30–300) |\n| | `keyscale` | Key (e.g., C Major, Am) |\n| | `timesignature` | Time signature (4/4, 3/4, 6/8) |\n| | `vocal_language` | Vocal language |\n| | `duration` | Target duration (seconds) |\n| **Audio Reference** | `reference_audio` | Global reference for timbre or style (for cover, style transfer) |\n| | `src_audio` | Source audio for non-text2music tasks (text2music defaults to silence, no input needed) |\n| | `audio_codes` | Semantic codes input to model in Cover mode (advanced: reuse codes for variants, convert songs to codes for extension, combine like DJ mixing) |\n| **Interval Control** | `repainting_start/end` | Time interval for operations (repaint redraw area / lego new track area) |\n\n---\n\n#### About Caption: The Most Important Input\n\n**Caption is the most important factor affecting generated music.**\n\nIt supports multiple input formats: simple style words, comma-separated tags, complex natural language descriptions. We've trained to be compatible with various formats, ensuring text format doesn't significantly affect model performance.\n\n**We provide at least 5 ways to help you write good captions:**\n\n1. **Random Dice** — Click the random button in the UI to see how example captions are written. You can use this standardized caption as a template and have an LLM rewrite it to your desired form.\n\n2. **Format Auto-Rewrite** — We support using the `format` feature to automatically expand your handwritten simple caption into complex descriptions.\n\n3. **CoT Rewrite** — If LM is initialized, whether `thinking` mode is enabled or not, we support rewriting and expanding captions through Chain-of-Thought (unless you actively disable it in settings, or LM is not initialized).\n\n4. **Audio to Caption** — Our LM supports converting your input audio to caption. While precision is limited, the vague direction is correct—enough as a starting point.\n\n5. **Simple Mode** — Just input a simple song description, and LM will automatically generate complete caption, lyrics, and metas samples—suitable for quick starts.\n\nRegardless of which method, they all solve a real problem: **As ordinary people, our music vocabulary is impoverished.**\n\nIf you want generated music to be more interesting and meet expectations, **Prompting is always the optimal option**—it brings the highest marginal returns and surprises.\n\n**Common Dimensions for Caption Writing:**\n\n| Dimension | Examples |\n|-----------|----------|\n| **Style/Genre** | pop, rock, jazz, electronic, hip-hop, R&B, folk, classical, lo-fi, synthwave |\n| **Emotion/Atmosphere** | melancholic, uplifting, energetic, dreamy, dark, nostalgic, euphoric, intimate |\n| **Instruments** | acoustic guitar, piano, synth pads, 808 drums, strings, brass, electric bass |\n| **Timbre Texture** | warm, bright, crisp, muddy, airy, punchy, lush, raw, polished |\n| **Era Reference** | 80s synth-pop, 90s grunge, 2010s EDM, vintage soul, modern trap |\n| **Production Style** | lo-fi, high-fidelity, live recording, studio-polished, bedroom pop |\n| **Vocal Characteristics** | female vocal, male vocal, breathy, powerful, falsetto, raspy, choir |\n| **Speed/Rhythm** | slow tempo, mid-tempo, fast-paced, groovy, driving, laid-back |\n| **Structure Hints** | building intro, catchy chorus, dramatic bridge, fade-out ending |\n\n**Some Practical Principles:**\n\n1. **Specific beats vague** — \"sad piano ballad with female breathy vocal\" works better than \"a sad song.\"\n\n2. **Combine multiple dimensions** — Single-dimension descriptions give the model too much room to play; combining style+emotion+instruments+timbre can more precisely anchor your desired direction.\n\n3. **Use references well** — \"in the style of 80s synthwave\" or \"reminiscent of Bon Iver\" can quickly convey complex aesthetic preferences.\n\n4. **Texture words are useful** — Adjectives like warm, crisp, airy, punchy can influence mixing and timbre tendencies.\n\n5. **Don't pursue perfect descriptions** — Caption is a starting point, not an endpoint. Write a general direction first, then iterate based on results.\n\n6. **Description granularity determines freedom** — More omitted descriptions give the model more room to play, more random factor influence; more detailed descriptions constrain the model more. Decide specificity based on your needs—want surprises? Write less. Want control? Write more details.\n\n7. **Avoid conflicting words** — Conflicting style combinations easily lead to degraded output. For example, wanting both \"classical strings\" and \"hardcore metal\" simultaneously—the model will try to fuse but usually not ideal. Especially when `thinking` mode is enabled, LM has weaker caption generalization than DiT. When prompting is unreasonable, the chance of pleasant surprises is smaller.\n\n   **Ways to resolve conflicts:**\n   - **Repetition reinforcement** — Strengthen the elements you want more in mixed styles by repeating certain words\n   - **Conflict to evolution** — Transform style conflicts into temporal style evolution. For example: \"Start with soft strings, middle becomes noisy dynamic metal rock, end turns to hip-hop\"—this gives the model clear guidance on how to handle different styles, rather than mixing them into a mess\n\n> For more prompting tips, see: [The Complete Guide to Mastering Suno](https://www.notion.so/The-Complete-Guide-to-Mastering-Suno-Advanced-Strategies-for-Professional-Music-Generation-2d6ae744ebdf8024be42f6645f884221)—although it's a Suno tutorial, prompting ideas are universal.\n\n---\n\n#### About Lyrics: The Temporal Script\n\nIf Caption describes the music's \"overall portrait\"—style, atmosphere, timbre—then **Lyrics is the music's \"temporal script\"**, controlling how music unfolds over time.\n\nLyrics is not just lyric content. It carries:\n- The lyric text itself\n- **Structure tags** ([Verse], [Chorus], [Bridge]...)\n- **Vocal style hints** ([raspy vocal], [whispered]...)\n- **Instrumental sections** ([guitar solo], [drum break]...)\n- **Energy changes** ([building energy], [explosive drop]...)\n\n**Structure Tags are Key**\n\nStructure tags (Meta Tags) are the most powerful tool in Lyrics. They tell the model: \"What is this section, how should it be performed?\"\n\n**Common Structure Tags:**\n\n| Category | Tag | Description |\n|----------|-----|-------------|\n| **Basic Structure** | `[Intro]` | Opening, establish atmosphere |\n| | `[Verse]` / `[Verse 1]` | Verse, narrative progression |\n| | `[Pre-Chorus]` | Pre-chorus, build energy |\n| | `[Chorus]` | Chorus, emotional climax |\n| | `[Bridge]` | Bridge, transition or elevation |\n| | `[Outro]` | Ending, conclusion |\n| **Dynamic Sections** | `[Build]` | Energy gradually rising |\n| | `[Drop]` | Electronic music energy release |\n| | `[Breakdown]` | Reduced instrumentation, space |\n| **Instrumental Sections** | `[Instrumental]` | Pure instrumental, no vocals |\n| | `[Guitar Solo]` | Guitar solo |\n| | `[Piano Interlude]` | Piano interlude |\n| **Special Tags** | `[Fade Out]` | Fade out ending |\n| | `[Silence]` | Silence |\n\n**Combining Tags: Use Moderately**\n\nStructure tags can be combined with `-` for finer control:\n\n```\n[Chorus - anthemic]\nThis is the chorus lyrics\nDreams are burning\n\n[Bridge - whispered]\nWhisper those words softly\n```\n\nThis works better than writing `[Chorus]` alone—you're telling the model both what this section is (Chorus) and how to sing it (anthemic).\n\n**⚠️ Note: Don't stack too many tags.**\n\n```\n❌ Not recommended:\n[Chorus - anthemic - stacked harmonies - high energy - powerful - epic]\n\n✅ Recommended:\n[Chorus - anthemic]\n```\n\nStacking too many tags has two risks:\n1. The model might mistake tag content as lyrics to sing\n2. Too many instructions confuse the model, making effects worse\n\n**Principle**: Keep structure tags concise; put complex style descriptions in Caption.\n\n**⚠️ Key: Maintain Consistency Between Caption and Lyrics**\n\n**Models are not good at resolving conflicts.** If descriptions in Caption and Lyrics contradict, the model gets confused and output quality decreases.\n\n```\n❌ Conflict example:\nCaption: \"violin solo, classical, intimate chamber music\"\nLyrics: [Guitar Solo - electric - distorted]\n\n✅ Consistent example:\nCaption: \"violin solo, classical, intimate chamber music\"\nLyrics: [Violin Solo - expressive]\n```\n\n**Checklist:**\n- Instruments in Caption ↔ Instrumental section tags in Lyrics\n- Emotion in Caption ↔ Energy tags in Lyrics\n- Vocal description in Caption ↔ Vocal control tags in Lyrics\n\nThink of Caption as \"overall setting\" and Lyrics as \"shot script\"—they should tell the same story.\n\n**Vocal Control Tags:**\n\n| Tag | Effect |\n|-----|--------|\n| `[raspy vocal]` | Raspy, textured vocals |\n| `[whispered]` | Whispered |\n| `[falsetto]` | Falsetto |\n| `[powerful belting]` | Powerful, high-pitched singing |\n| `[spoken word]` | Rap/recitation |\n| `[harmonies]` | Layered harmonies |\n| `[call and response]` | Call and response |\n| `[ad-lib]` | Improvised embellishments |\n\n**Energy and Emotion Tags:**\n\n| Tag | Effect |\n|-----|--------|\n| `[high energy]` | High energy, passionate |\n| `[low energy]` | Low energy, restrained |\n| `[building energy]` | Increasing energy |\n| `[explosive]` | Explosive energy |\n| `[melancholic]` | Melancholic |\n| `[euphoric]` | Euphoric |\n| `[dreamy]` | Dreamy |\n| `[aggressive]` | Aggressive |\n\n**Lyric Text Writing Tips**\n\n**1. Control Syllable Count**\n\n**6-10 syllables per line** usually works best. The model aligns syllables to beats—if one line has 6 syllables and the next has 14, rhythm becomes strange.\n\n```\n❌ Bad example:\n我站在窗前看着外面的世界一切都在改变（18 syllables）\n你好（2 syllables）\n\n✅ Good example:\n我站在窗前（5 syllables）\n看着外面世界（6 syllables）\n一切都在改变（6 syllables）\n```\n\n**Tip**: Keep similar syllable counts for lines in the same position (e.g., first line of each verse) (±1-2 deviation).\n\n**2. Use Case to Control Intensity**\n\nUppercase indicates stronger vocal intensity:\n\n```\n[Verse]\nwalking through the empty streets (normal intensity)\n\n[Chorus]\nWE ARE THE CHAMPIONS! (high intensity, shouting)\n```\n\n**3. Use Parentheses for Background Vocals**\n\n```\n[Chorus]\nWe rise together (together)\nInto the light (into the light)\n```\n\nContent in parentheses is processed as background vocals or harmonies.\n\n**4. Extend Vowels**\n\nYou can extend sounds by repeating vowels:\n\n```\nFeeeling so aliiive\n```\n\nBut use cautiously—effects are unstable, sometimes ignored or mispronounced.\n\n**5. Clear Section Separation**\n\nSeparate each section with blank lines:\n\n```\n[Verse 1]\nFirst verse lyrics\nContinue first verse\n\n[Chorus]\nChorus lyrics\nChorus continues\n```\n\n**Avoiding \"AI-flavored\" Lyrics**\n\nThese characteristics make lyrics seem mechanical and lack human touch:\n\n| Red Flag 🚩 | Description |\n|-------------|-------------|\n| **Adjective stacking** | \"neon skies, electric hearts, endless dreams\"—filling a section with vague imagery |\n| **Rhyme chaos** | Inconsistent rhyme patterns, or forced rhymes causing semantic breaks |\n| **Blurred section boundaries** | Lyric content crosses structure tags, Verse content \"flows\" into Chorus |\n| **No breathing room** | Each line too long, can't sing in one breath |\n| **Mixed metaphors** | First verse uses water imagery, second suddenly becomes fire, third is flying—listeners can't anchor |\n\n**Metaphor discipline**: Stick to one core metaphor per song, exploring its multiple aspects. For example, choosing \"water\" as metaphor, you can explore: how love flows around obstacles like water, can be gentle rain or flood, reflects the other's image, can't be grasped but exists. One image, multiple facets—this gives lyrics cohesion.\n\n**Writing Instrumental Music**\n\nIf generating pure instrumental music without vocals:\n\n```\n[Instrumental]\n```\n\nOr use structure tags to describe instrumental development:\n\n```\n[Intro - ambient]\n\n[Main Theme - piano]\n\n[Climax - powerful]\n\n[Outro - fade out]\n```\n\n**Complete Example**\n\nAssuming Caption is: `female vocal, piano ballad, emotional, intimate atmosphere, strings, building to powerful chorus`\n\n```\n[Intro - piano]\n\n[Verse 1]\n月光洒在窗台上\n我听见你的呼吸\n城市在远处沉睡\n只有我们还醒着\n\n[Pre-Chorus]\n这一刻如此安静\n却藏着汹涌的心\n\n[Chorus - powerful]\n让我们燃烧吧\n像夜空中的烟火\n短暂却绚烂\n这就是我们的时刻\n\n[Verse 2]\n时间在指尖流过\n我们抓不住什么\n但至少此刻拥有\n彼此眼中的火焰\n\n[Bridge - whispered]\n如果明天一切消散\n至少我们曾经闪耀\n\n[Final Chorus]\n让我们燃烧吧\n像夜空中的烟火\n短暂却绚烂\nTHIS IS OUR MOMENT!\n\n[Outro - fade out]\n```\n\nNote: In this example, Lyrics tags (piano, powerful, whispered) are consistent with Caption descriptions (piano ballad, building to powerful chorus, intimate), with no conflicts.\n\n---\n\n#### About Music Metadata: Optional Fine Control\n\n**Most of the time, you don't need to manually set metadata.**\n\nWhen you enable `thinking` mode (or enable `use_cot_metas`), LM automatically infers appropriate BPM, key, time signature, etc. based on your Caption and Lyrics. This is usually good enough.\n\nBut if you have clear ideas, you can also manually control them:\n\n| Parameter | Control Range | Description |\n|-----------|--------------|-------------|\n| `bpm` | 30–300 | Tempo. Common distribution: slow songs 60–80, mid-tempo 90–120, fast songs 130–180 |\n| `keyscale` | Key | e.g., `C Major`, `Am`, `F# Minor`. Affects overall pitch and emotional color |\n| `timesignature` | Time signature | `4/4` (most common), `3/4` (waltz), `6/8` (swing feel) |\n| `vocal_language` | Language | Vocal language. LM usually auto-detects from lyrics |\n| `duration` | Seconds | Target duration. Actual generation may vary slightly |\n\n**Understanding Control Boundaries**\n\nThese parameters are **guidance** rather than **precise commands**:\n\n- **BPM**: Common range (60–180) works well; extreme values (like 30 or 280) have less training data, may be unstable\n- **Key**: Common keys (C, G, D, Am, Em) are stable; rare keys may be ignored or shifted\n- **Time signature**: `4/4` is most reliable; `3/4`, `6/8` usually OK; complex signatures (like `5/4`, `7/8`) are advanced, effects vary by style\n- **Duration**: Short songs (30–60s) and medium length (2–4min) are stable; very long generation may have repetition or structure issues\n\n**The Model's \"Reference\" Approach**\n\nThe model doesn't mechanically execute `bpm=120`, but rather:\n1. Uses `120 BPM` as an **anchor point**\n2. Samples from distribution near this anchor\n3. Final result might be 118 or 122, not exactly 120\n\nIt's like telling a musician \"around 120 tempo\"—they'll naturally play in this range, not rigidly follow a metronome.\n\n**When Do You Need Manual Settings?**\n\n| Scenario | Suggestion |\n|----------|------------|\n| Daily generation | Don't worry, let LM auto-infer |\n| Clear tempo requirement | Manually set `bpm` |\n| Specific style (e.g., waltz) | Manually set `timesignature=3/4` |\n| Need to match other material | Manually set `bpm` and `duration` |\n| Pursue specific key color | Manually set `keyscale` |\n\n**Tip**: If you manually set metadata but generation results clearly don't match—check if there's conflict with Caption/Lyrics. For example, Caption says \"slow ballad\" but `bpm=160`, the model gets confused.\n\n**Recommended Practice**: Don't write tempo, BPM, key, and other metadata information in Caption. These should be set through dedicated metadata parameters (`bpm`, `keyscale`, `timesignature`, etc.), not described in Caption. Caption should focus on style, emotion, instruments, timbre, and other musical characteristics, while metadata information is handled by corresponding parameters.\n\n---\n\n#### About Audio Control: Controlling Sound with Sound\n\n**Text is dimensionally reduced abstraction; the best control is still controlling with audio.**\n\nThere are three ways to control generation with audio, each with different control ranges and uses:\n\n---\n\n##### 1. Reference Audio: Global Acoustic Feature Control\n\nReference audio (`reference_audio`) is used to control the **acoustic features** of generated music—timbre, mixing style, performance style, etc. It **averages temporal dimension information** and acts **globally**.\n\n**What Does Reference Audio Control?**\n\nReference audio mainly controls the **acoustic features** of generated music, including:\n- **Timbre texture**: Vocal timbre, instrument timbre\n- **Mixing style**: Spatial sense, dynamic range, frequency distribution\n- **Performance style**: Vocal techniques, playing techniques, expression\n- **Overall atmosphere**: The \"feeling\" conveyed through reference audio\n\n**How Does the Backend Process Reference Audio?**\n\nWhen you provide reference audio, the system performs the following processing:\n\n1. **Audio Preprocessing**:\n   - Load audio file, normalize to **stereo 48kHz** format\n   - Detect silence, ignore if audio is completely silent\n   - If audio length is less than 30 seconds, repeat to fill to at least 30 seconds\n   - Randomly select 10-second segments from front, middle, and back positions, concatenate into 30-second reference segment\n\n2. **Encoding Conversion**:\n   - Use **VAE (Variational Autoencoder)** `tiled_encode` method to encode audio into **latent representation (latents)**\n   - These latents contain acoustic feature information but remove specific melody, rhythm, and other structural information\n   - Encoded latents are input as conditions to DiT generation process, **averaging temporal dimension information, acting globally on entire generation process**\n\n---\n\n##### 2. Source Audio: Semantic Structure Control\n\nSource audio (`src_audio`) is used for **Cover tasks**, performing **melodic structure control**. Its principle is to quantize your input source audio into semantically structured information.\n\n**What Does Source Audio Control?**\n\nSource audio is converted into **semantically structured information**, including:\n- **Melody**: Note direction and pitch\n- **Rhythm**: Beat, accent, groove\n- **Chords**: Harmonic progression and changes\n- **Orchestration**: Instrument arrangement and layers\n- **Some timbre**: Partial timbre information\n\n**What Can You Do With It?**\n\n1. **Control style**: Maintain source audio structure, change style and details\n2. **Transfer style**: Apply source audio structure to different styles\n3. **Retake lottery**: Generate similar structure but different variants, get different interpretations through multiple generations\n4. **Control influence degree**: Control source audio influence strength through `audio_cover_strength` parameter (0.0–1.0)\n   - Higher strength: generation results more strictly follow source audio structure\n   - Lower strength: generation results have more room for free play\n\n**Advanced Cover Usage**\n\nYou can use Cover to **Remix a song**, and it supports changing Caption and Lyrics:\n\n- **Remix creation**: Input a song as source audio, reinterpret it by modifying Caption and Lyrics\n  - Change style: Use different Caption descriptions (e.g., change from pop to rock)\n  - Change lyrics: Rewrite lyrics with new Lyrics, maintaining original melody structure\n  - Change emotion: Adjust overall atmosphere through Caption (e.g., change from sad to joyful)\n\n- **Build complex music structures**: Build complex melodic direction, layers, and groove based on your needed structure influence degree\n  - Fine-tune structure adherence through `audio_cover_strength`\n  - Combine Caption and Lyrics modifications to create new expression while maintaining core structure\n  - Can generate multiple versions, each with different emphasis on structure, style, lyrics\n\n---\n\n##### 3. Source Audio Context-Based Control: Local Completion and Modification\n\nThis is the **Repaint task**, performing completion or modification based on source audio context.\n\n**Repaint Principle**\n\nRepaint is based on **context completion** principle:\n- Can complete **beginning**, **middle local**, **ending**, or **any region**\n- Operation range: **3 seconds to 90 seconds**\n- Model references source audio context information, generating within specified interval\n\n**What Can You Do With It?**\n\n1. **Local modification**: Modify lyrics, structure, or content in specified interval\n2. **Change lyrics**: Maintain melody and orchestration, only change lyric content\n3. **Change structure**: Change music structure in specified interval (e.g., change Verse to Chorus)\n4. **Continue writing**: Continue writing beginning or ending based on context\n5. **Clone timbre**: Clone source audio timbre characteristics based on context\n\n**Advanced Repaint Usage**\n\nYou can use Repaint for more complex creative needs:\n\n- **Infinite duration generation**:\n  - Through multiple Repaint operations, can continuously extend audio, achieving infinite duration generation\n  - Each continuation is based on previous segment's context, maintaining natural transitions and coherence\n  - Can generate in segments, each 3–90 seconds, finally concatenate into complete work\n\n- **Intelligent audio stitching**:\n  - Intelligently organize and stitch two audios together\n  - Use Repaint at first audio's end to continue, making transitions naturally connect\n  - Or use Repaint to modify connection part between two audios for smooth transitions\n  - Model automatically handles rhythm, harmony, timbre connections based on context, making stitched audio sound like a complete work\n\n---\n\n##### 4. Base Model Advanced Audio Control Tasks\n\nIn the **Base model**, we also support more advanced audio control tasks:\n\n**Lego Task**: Intelligently add new tracks based on existing tracks\n- Input an existing audio track (e.g., vocals)\n- Model intelligently adds new tracks (e.g., drums, guitar, bass, etc.)\n- New tracks coordinate with original tracks in rhythm and harmony\n\n**Complete Task**: Add mixed tracks to single track\n- Input a single-track audio (e.g., a cappella vocals)\n- Model generates complete mixed accompaniment tracks\n- Generated accompaniment matches vocals in style, rhythm, and harmony\n\n**These advanced context completion tasks** greatly expand control methods, more intelligently providing inspiration and creativity.\n\n---\n\nThe combination of these parameters determines what you \"want.\" We'll explain input control **principles** and **techniques** in detail later.\n\n### II. Inference Hyperparameters: How Does the Model Generate?\n\nThis is the part that affects \"generation process behavior\"—doesn't change what you want, but changes how the model does it.\n\n**DiT (Diffusion Model) Hyperparameters:**\n\n| Parameter | Function | Default | Tuning Advice |\n|-----------|----------|---------|---------------|\n| `inference_steps` | Diffusion steps | 8 (turbo) | More steps = finer but slower. Turbo uses 8, Base uses 32–100 |\n| `guidance_scale` | CFG strength | 7.0 | Higher = more prompt adherence, but may overfit. Only Base model effective |\n| `use_adg` | Adaptive Dual Guidance | False | After enabling, dynamically adjusts CFG, Base model only |\n| `cfg_interval_start/end` | CFG effective interval | 0.0–1.0 | Controls which stage to apply CFG |\n| `shift` | Timestep offset | 1.0 | Adjusts denoising trajectory, affects generation style |\n| `infer_method` | Inference method | \"ode\" | `ode` deterministic, `sde` introduces randomness |\n| `timesteps` | Custom timesteps | None | Advanced usage, overrides steps and shift |\n| `audio_cover_strength` | Reference audio/codes influence strength | 1.0 | 0.0–1.0, higher = closer to reference, lower = more freedom |\n\n**5Hz LM (Language Model) Hyperparameters:**\n\n| Parameter | Function | Default | Tuning Advice |\n|-----------|----------|---------|---------------|\n| `thinking` | Enable CoT reasoning | True | Enable to let LM reason metadata and codes |\n| `lm_temperature` | Sampling temperature | 0.85 | Higher = more random/creative, lower = more conservative/deterministic |\n| `lm_cfg_scale` | LM CFG strength | 2.0 | Higher = more positive prompt adherence |\n| `lm_top_k` | Top-K sampling | 0 | 0 means disabled, limits candidate word count |\n| `lm_top_p` | Top-P sampling | 0.9 | Nucleus sampling, limits cumulative probability |\n| `lm_negative_prompt` | Negative prompt | \"NO USER INPUT\" | Tells LM what not to generate |\n| `use_cot_metas` | CoT reason metadata | True | Let LM auto-infer BPM, key, etc. |\n| `use_cot_caption` | CoT rewrite caption | True | Let LM optimize your description |\n| `use_cot_language` | CoT detect language | True | Let LM auto-detect vocal language |\n| `use_constrained_decoding` | Constrained decoding | True | Ensures correct output format |\n\nThe combination of these parameters determines how the model \"does it.\"\n\n**About Parameter Tuning**\n\nIt's important to emphasize that **tuning factors and random factors sometimes have comparable influence**. When you adjust a parameter, it may be hard to tell if it's the parameter's effect or randomness causing the change.\n\nTherefore, **we recommend fixing random factors when tuning**—by setting a fixed `seed` value, ensuring each generation starts from the same initial noise, so you can accurately feel the parameter's real impact on generated audio. Otherwise, parameter change effects may be masked by randomness, causing you to misjudge the parameter's role.\n\n### III. Random Factors: Sources of Uncertainty\n\nEven with identical inputs and hyperparameters, two generations may produce different results. This is because:\n\n**1. DiT's Initial Noise**\n- Diffusion models start from random noise and gradually denoise\n- `seed` parameter controls this initial noise\n- Different seed → different starting point → different endpoint\n\n**2. LM's Sampling Randomness**\n- When `lm_temperature > 0`, the sampling process itself has randomness\n- Same prompt, each sampling may choose different tokens\n\n**3. Additional Noise When `infer_method = \"sde\"`**\n- SDE method injects additional randomness during denoising\n\n---\n\n#### Pros and Cons of Random Factors\n\nRandomness is a double-edged sword.\n\n**Benefits of Randomness:**\n- **Explore creative space**: Same input can produce different variants, giving you more choices\n- **Discover unexpected surprises**: Sometimes randomness brings excellent results you didn't expect\n- **Avoid repetition**: Each generation is different, won't fall into single-pattern loops\n\n**Challenges of Randomness:**\n- **Uncontrollable results**: You can't precisely predict generation results, may generate multiple times without satisfaction\n- **Hard to reproduce**: Even with identical inputs, hard to reproduce a specific good result\n- **Tuning difficulty**: When adjusting parameters, hard to tell if it's parameter effect or randomness change\n- **Screening cost**: Need to generate multiple versions to find satisfactory ones, increasing time cost\n\n#### What Mindset to Face Random Factors?\n\n**1. Accept Uncertainty**\n- Randomness is an essential characteristic of AI music generation, not a bug, but a feature\n- Don't expect every generation to be perfect; treat randomness as an exploration tool\n\n**2. Embrace the Exploration Process**\n- Treat generation process as \"gacha\" or \"treasure hunting\"—try multiple times, always find surprises\n- Enjoy discovering unexpectedly good results, rather than obsessing over one-time success\n\n**3. Use Fixed Seed Wisely**\n- When you want to **understand parameter effects**, fix `seed` to eliminate randomness interference\n- When you want to **explore creative space**, let `seed` vary randomly\n\n**4. Batch Generation + Intelligent Screening**\n- Don't rely on single generation; batch generate multiple versions\n- Use automatic scoring mechanisms for initial screening to improve efficiency\n\n#### Our Solution: Large Batch + Automatic Scoring\n\nBecause our inference is extremely fast, if your GPU VRAM is sufficient, you can explore random space through **large batch**:\n\n- **Batch generation**: Generate multiple versions at once (e.g., batch_size=2,4,8), quickly explore random space\n- **Automatic scoring mechanism**: We provide automatic scoring mechanisms that can help you initially screen, doing **test time scaling**\n\n**Automatic Scoring Mechanism**\n\nWe provide multiple scoring metrics, among which **my favorite is DiT Lyrics Alignment Score**:\n\n- **DiT Lyrics Alignment Score**: This score implicitly affects lyric accuracy\n  - It evaluates the alignment degree between lyrics and audio in generated audio\n  - Higher score means lyrics are more accurately positioned in audio, better match between singing and lyrics\n  - This is particularly important for music generation with lyrics, can help you screen versions with higher lyric accuracy\n\n- **Other scoring metrics**: Also include other quality assessment metrics, can evaluate generation results from multiple dimensions\n\n**Recommended Workflow:**\n\n1. **Batch generation**: Set larger `batch_size` (e.g., 2, 4, 8), generate multiple versions at once\n2. **Enable AutoGen**: Enable automatic generation, let system continuously generate new batches in background\n   - **AutoGen mechanism**: AutoGen automatically uses same parameters (but random seed) to generate next batch in background while you're viewing current batch results\n   - This lets you continuously explore random space without manually clicking generate button\n   - Each new batch uses new random seed, ensuring result diversity\n3. **Automatic scoring**: Enable automatic scoring, let system automatically score each version\n4. **Initial screening**: Screen versions with higher scores based on DiT Lyrics Alignment Score and other metrics\n5. **Manual selection**: Manually select the final version that best meets your needs from screened versions\n\nThis fully utilizes randomness to explore creative space while improving efficiency through automation tools, avoiding blind searching in large generation results. AutoGen lets you \"generate while listening\"—while browsing current results, the next batch is already prepared in the background.\n\n---\n\n## Conclusion\n\nThis tutorial currently covers ACE-Step 1.5's core concepts and usage methods:\n\n- **Mental Models**: Understanding human-centered generation design philosophy\n- **Model Architecture**: Understanding how LM and DiT work together\n- **Input Control**: Mastering text (Caption, Lyrics, metadata) and audio (reference audio, source audio) control methods\n- **Inference Hyperparameters**: Understanding parameters affecting generation process\n- **Random Factors**: Learning to use randomness to explore creative space, improving efficiency through Large Batch + AutoGen + Automatic Scoring\n\nThis is just the beginning. There's much more content we want to share with you:\n\n- More Prompting tips and practical cases\n- Detailed usage guides for different task types\n- Advanced techniques and creative workflows\n- Common issues and solutions\n- Performance optimization suggestions\n\n**This tutorial will continue to be updated and improved.** If you have any questions or suggestions during use, feedback is welcome. Let's make ACE-Step your creative partner in your pocket together.\n\n---\n\n*To be continued...*\n"
  },
  {
    "path": "docs/en/VST3_BACKEND_CONTRACT.md",
    "content": "# ACE-Step VST3 Plugin Backend Contract\n\nThis document defines the MVP contract between a future ACE-Step VST3 plugin and the existing\nACE-Step backend/API. The goal is to keep the plugin thin and reuse the current REST endpoints\ninstead of introducing a separate inference stack inside the DAW process.\n\n## Contract Summary\n\nFor the MVP, the plugin should use this flow:\n\n1. Check backend availability with `GET /health`.\n2. Submit a generation job with `POST /release_task`.\n3. Poll job status with `POST /query_result`.\n4. Use `GET /v1/audio` for preview or download once a job succeeds.\n\nThis matches the current REST surface documented in [API.md](./API.md) and the browser Studio flow\nin [ui/studio.html](../../ui/studio.html).\n\n## Backend Checks\n\n### `GET /health`\n\nUse this as the plugin's first reachability check.\n\nCurrent API behavior:\n\n- Returns a wrapped response with `code`, `data`, `error`, `timestamp`, and `extra`\n- `data.status` is `\"ok\"` when the service is healthy\n- `data.service` identifies the API service\n\nPlugin interpretation:\n\n- `offline`: request fails, times out, or returns a non-200 wrapper\n- `ready`: `code === 200` and `data.status === \"ok\"`\n- `degraded`: reachable, but the backend reports a non-ideal readiness state, such as models not\n  being initialized yet\n\nThe plugin should keep the UI editable when offline, but generation should remain disabled until the\nbackend becomes reachable again.\n\n## Generation Submission\n\n### `POST /release_task`\n\nThe API accepts JSON, multipart form data, and URL-encoded form data. For the VST3 MVP, the plugin\nshould prefer JSON because the MVP does not need file upload.\n\nRecommended request shape for text-to-music:\n\n```json\n{\n  \"prompt\": \"a bright indie pop chorus\",\n  \"lyrics\": \"...\",\n  \"vocal_language\": \"en\",\n  \"thinking\": false,\n  \"audio_duration\": 30,\n  \"inference_steps\": 8,\n  \"guidance_scale\": 7.0,\n  \"use_random_seed\": false,\n  \"seed\": 12345,\n  \"batch_size\": 1,\n  \"audio_format\": \"wav\"\n}\n```\n\nNotes:\n\n- `prompt` and `lyrics` are the primary user inputs.\n- `audio_duration` maps to the plugin's duration control.\n- `seed` and `use_random_seed` cover repeatability.\n- `batch_size` should stay `1` for the MVP plugin UI unless a later issue explicitly adds batch\n  handling.\n- `audio_format` should be set to a format the plugin can preview reliably. `wav` is the safest\n  default for handoff and playback.\n- `model` can be added later if the plugin exposes explicit model selection, but it is not required\n  for the MVP contract.\n\nCurrent API response shape:\n\n- `code === 200` indicates submission succeeded\n- `data.task_id` is the identifier used for polling\n- `data.status` is typically `\"queued\"`\n- `data.queue_position` may be present\n\nPlugin interpretation:\n\n- Treat `task_id` as the only required field for follow-up polling\n- Preserve the original prompt/lyrics locally so the user can recover context even if the backend\n  later fails\n\n## Job Polling\n\n### `POST /query_result`\n\nThe plugin should poll using JSON with a `task_id_list` array:\n\n```json\n{\n  \"task_id_list\": [\"550e8400-e29b-41d4-a716-446655440000\"]\n}\n```\n\nCurrent API behavior:\n\n- The request accepts JSON or URL-encoded form data\n- `task_id_list` may be a real array or a JSON-encoded string\n- `status` uses integer codes:\n  - `0` = queued or running\n  - `1` = succeeded\n  - `2` = failed\n- Running responses may include `progress_text`\n- Successful responses include `result` as a JSON string, not a parsed object\n\nPlugin-side normalized job states:\n\n- `idle`: no active job\n- `submitting`: request is in flight\n- `queued_or_running`: API status `0`\n- `succeeded`: API status `1`\n- `failed`: API status `2`\n\nThe plugin should not assume a separate queued-vs-running distinction unless the backend adds one in a\nfuture API revision.\n\n## Result Handling\n\nWhen a task succeeds, the plugin should:\n\n1. Parse the `result` string as JSON.\n2. Use the first result item as the primary preview target.\n3. Read `file` or `url` from that parsed object.\n4. Build a playable URL using `GET /v1/audio` when the path is server-relative.\n\nCurrent Studio behavior in [ui/studio.html](../../ui/studio.html) follows the same general pattern:\npoll until status `1`, parse `task.result`, and then resolve the returned audio path into a final\nURL.\n\nPlugin result fields worth keeping locally:\n\n- `file_url`\n- `prompt`\n- `lyrics`\n- `metas`\n- `progress_text`\n- `error`\n\n## Audio Preview\n\n### `GET /v1/audio`\n\nUse this endpoint for preview and download of generated files.\n\nThe plugin should treat the returned file path as the source of truth for:\n\n- in-plugin preview playback\n- reveal/open-in-folder handoff\n- export or copy-to-project workflows if needed later\n\nIf the `file` value is already a full URL, the plugin can use it directly. If it is server-relative,\nprefix it with the configured base URL.\n\n## Authentication\n\nThe API server can be configured with `ACESTEP_API_KEY`.\n\nRecommended plugin behavior:\n\n- Prefer `Authorization: Bearer <token>` when auth is enabled\n- Avoid placing tokens in request bodies\n- Keep the base URL configurable so the plugin can connect to a local API server or another trusted\n  endpoint\n\n## API Gaps For Follow-Up\n\nThe current API is sufficient for the MVP contract, but the plugin would benefit from a few future\nenhancements:\n\n- A clearer readiness signal than a single health wrapper\n- Structured JSON for `query_result.result` instead of a JSON string\n- A task-detail endpoint for single-task polling\n- More task-specific progress reporting\n- Explicit artifact metadata beyond a file path\n- A documented cancellation flow for in-flight generation jobs\n\nThese gaps should remain follow-up items, not blockers for the first plugin milestone.\n"
  },
  {
    "path": "docs/en/VST3_MVP.md",
    "content": "# ACE-Step VST3 MVP Architecture\n\nThis document defines the initial architecture for packaging ACE-Step as a VST3 plugin for DAW\nworkflows.\n\n## Summary\n\nThe MVP should be a thin VST3 plugin that delegates music generation to the existing ACE-Step\nbackend/API. The plugin must not embed model inference or reimplement the current generation stack\ninside the DAW process.\n\nThe recommended default framework for the first implementation is JUCE, because it gives us mature\ncross-platform VST3 support, stable host integration, and a practical state persistence model for\nDAW projects.\n\n## MVP Scope\n\nThe first release should focus on text-to-music generation only:\n\n- prompt and lyrics input\n- duration, seed, and quality preset controls\n- job submission and polling\n- generated audio preview\n- basic file handoff back to the DAW workflow\n\nExplicitly deferred from the MVP:\n\n- reference audio input\n- repaint/edit workflows\n- stem routing and multitrack orchestration\n- host tempo or transport sync\n- AU, CLAP, and AAX builds\n\n## Process Boundaries\n\nThe plugin process should stay lightweight.\n\n- The DAW hosts the plugin UI and project state.\n- The plugin talks to a local ACE-Step backend over the existing API.\n- The backend owns model loading, generation, polling, and output files.\n- All long-running work must stay off the audio thread.\n\nThis split keeps the plugin responsive, reduces risk to DAW stability, and avoids duplicating the\ncurrent inference stack.\n\n## Plugin State Model\n\nThe plugin should persist only UI and workflow state that matters to the current DAW project:\n\n- prompt and lyrics text\n- generation controls such as duration, seed, and preset\n- backend base URL or connection target\n- last selected result metadata\n- a versioned state schema for forward compatibility\n\nState should be restored automatically when the DAW project is reopened. If the backend is\nunavailable, the plugin should still restore its local UI state and show a disconnected state rather\nthan failing to open.\n\n## Offline And Error Behavior\n\nThe plugin should treat backend failures as recoverable workflow states, not fatal errors.\n\n- If the backend is unreachable, the plugin should show a clear disconnected status.\n- Generation controls should remain editable, but generation should be disabled until connectivity is\n  restored.\n- Job polling should happen on a background path, never on the audio thread.\n- Failed jobs should surface an actionable error message and preserve the user inputs.\n\n## Validation Hosts\n\nThe MVP should be validated in:\n\n- Reaper on Windows\n- Reaper on macOS\n\nThese hosts are the default compatibility targets for the first plugin milestone because they are\npractical, widely used, and suitable for checking load, state restore, and result handoff behavior.\n\n## Why JUCE\n\nJUCE is the default framework choice for the MVP because it gives us the most direct route to a\ncross-platform VST3 plugin with predictable editor, parameter, and state handling.\n\nThat makes it a good fit for a first implementation where the main risk is workflow integration, not\nmodel research or audio DSP novelty.\n\n"
  },
  {
    "path": "docs/en/VST3_SETUP.md",
    "content": "# ACE-Step VST3 Setup and Validation\n\nThis guide documents the current ACE-Step VST3 MVP workflow, including contributor build steps,\nbackend setup expectations, user-facing behavior, and the validation matrix for the current draft\nplugin implementation.\n\n## Current MVP Scope\n\nThe current VST3 MVP implementation is intentionally narrow:\n\n- isolated JUCE/CMake VST3 shell\n- plugin UI for prompt, lyrics, duration, seed, preset, and quality mode\n- persisted plugin state across DAW reopen\n- backend health check, task submission, and polling\n- generated-preview download and playback\n- reveal-file handoff through the host operating system\n\nThe following items are explicitly deferred:\n\n- reference-audio workflows\n- repaint/edit workflows\n- drag-and-drop into the DAW timeline\n- AU, CLAP, and AAX formats\n\n## Contributor Build\n\nBuild requirements:\n\n- CMake 3.22 or newer\n- a C++20-capable compiler\n- Git access during configure so JUCE can be fetched\n\nBuild commands:\n\n```bash\ncmake -S plugins/acestep_vst3 -B build/acestep_vst3\ncmake --build build/acestep_vst3 --config Release\n```\n\nPlatform notes:\n\n- Windows: Visual Studio 2022 or Ninja is recommended\n- macOS: Xcode or Ninja is recommended\n- The plugin workspace is isolated under `plugins/acestep_vst3/` and does not modify the repo's\n  Python packaging flow\n\n## Backend Setup\n\nThe VST3 MVP architecture assumes a separate ACE-Step backend/API process.\n\nRecommended backend startup for future integration work:\n\n```bash\nuv run acestep-api\n```\n\nDefault local endpoint:\n\n- `http://localhost:8001`\n\nThe plugin makes live backend requests for:\n\n- `GET /health`\n- `POST /release_task`\n- `POST /query_result`\n\nThe backend must already be running before the plugin is opened. Auto-launch and backend lifecycle\nmanagement are not part of the MVP.\n\n## Current User Workflow\n\nIn the current MVP implementation:\n\n1. Open the plugin inside a supported VST3 host.\n2. Enter prompt, lyrics, duration, seed, preset, and quality mode.\n3. Confirm the backend URL points to a running ACE-Step backend.\n4. Trigger generation from the plugin.\n5. Wait for submission, queued/running, and completion states to resolve through live polling.\n6. Preview the downloaded result audio inside the plugin.\n7. Play, stop, clear, or reveal the preview file from the plugin UI.\n\nThe reveal-file path is intentionally file based. Drag-and-drop into the DAW timeline is deferred\nfor MVP stability.\n\n## Validation Matrix\n\n| Area | Target | Current status | Notes |\n|------|--------|----------------|-------|\n| Plugin shell build | Windows | Pending manual validation | Build instructions are present; no Windows validation was run in this environment |\n| Plugin shell build | macOS | Implemented | Local build succeeded in this workspace after command line tools were installed |\n| Host load | Reaper (Windows) | Pending manual validation | This is the default Windows validation host for the MVP |\n| Host load | Reaper (macOS) | Implemented | Plugin shell was loaded in Reaper on macOS in this workspace |\n| State persistence | DAW save/reopen | Implemented, pending broader host validation | Prompt, lyrics, controls, result slots, backend metadata, and preview metadata are serialized |\n| Backend offline UX | Live backend health check | Implemented | Uses real `/health` requests and visible error/status messaging |\n| Prompt/job workflow | Live backend task flow | Implemented | Uses `/release_task` and `/query_result` with submission, queued/running, success, and failure states |\n| Preview playback | Downloaded result playback | Implemented, pending host validation | Generated output is downloaded to a local cache file and played through JUCE transport primitives |\n| File handoff | Reveal file in OS | Implemented, pending host validation | Uses file-based handoff; drag-and-drop is deferred |\n\n## Known Limitations\n\n- The plugin depends on an already-running ACE-Step backend\n- No plugin CI pipeline is active yet\n- The editor timer currently drives backend polling, so generation workflow should be exercised with\n  the plugin UI open\n- Windows host validation is still pending\n- Drag-and-drop into the DAW timeline is intentionally out of scope for this milestone\n\n## Tracking\n\nThis guide corresponds to the VST3 umbrella issue and its current child issues:\n\n- `#890` umbrella tracker\n- `#893` plugin shell\n- `#894` plugin UI and backend job state\n- `#895` preview playback and file handoff\n"
  },
  {
    "path": "docs/en/ace_step_musicians_guide.md",
    "content": "# ACE-Step 1.5 — A Musician's Guide\n\n## What Is This Thing?\n\nACE-Step is a music-making AI that runs on your own computer. You describe the music you want — the style, the instruments, the mood, the lyrics — and it generates a full song in seconds. Not a loop, not a beat — a complete song with vocals, instruments, and structure.\n\nUnlike cloud services like Suno or Udio, ACE-Step runs locally. You own the software, you own the output, and you can use it offline with no subscription, no rate limits, and no terms of service restrictions.\n\nIt's open-source and free.\n\n---\n\n## How Does It Actually Work?\n\nACE-Step has two \"brains\" that work together, like a songwriter and a studio engineer:\n\n```\n    ┌─────────────────────────────────────────────────────────┐\n    │                    YOU (the musician)                   │\n    │                                                         │\n    │   \"I want an upbeat pop song with electric guitars,     │\n    │    catchy chorus, female vocals, 120 BPM\"               │\n    └──────────────────────┬──────────────────────────────────┘\n                           │\n                    Your description\n                           │\n                           ▼\n    ┌─────────────────────────────────────────────────────────┐\n    │              BRAIN 1: The Songwriter (LM)               │\n    │                                                         │\n    │   Reads your description and thinks about it.           │\n    │   Fills in the gaps you didn't specify:                 │\n    │     - What key fits this mood? → G Major                │\n    │     - What tempo feels right? → 122 BPM                 │\n    │     - How should the song be structured?                │\n    │     - Where should energy peak?                         │\n    │                                                         │\n    │   Creates a detailed blueprint of the song.             │\n    │                                                         │\n    │   (Optional — you can skip this brain for speed,        │\n    │    or if you already know exactly what you want.)       │\n    └──────────────────────┬──────────────────────────────────┘\n                           │\n                      Blueprint\n                           │\n                           ▼\n    ┌─────────────────────────────────────────────────────────┐\n    │           BRAIN 2: The Studio Engineer (DiT)            │\n    │                                                         │\n    │   Takes the blueprint and builds the actual audio.      │\n    │   Starts with pure noise (like static on a TV)          │\n    │   and gradually shapes it into music — step by step.    │\n    │                                                         │\n    │   Each step removes a layer of noise and adds           │\n    │   detail: instruments come into focus, vocals           │\n    │   emerge, drums tighten up, mix clears.                 │\n    │                                                         │\n    │   After 8 steps (fast mode) or 50 steps (quality        │\n    │   mode), you have a finished song.                      │\n    └──────────────────────┬──────────────────────────────────┘\n                           │\n                     Finished audio\n                           │\n                           ▼\n    ┌─────────────────────────────────────────────────────────┐\n    │                    YOUR SONG  ♪ ♫                       │\n    │           (WAV or MP3, ready to play)                   │\n    └─────────────────────────────────────────────────────────┘\n```\n\n**The key idea:** Brain 1 (the Songwriter) is optional. You can give Brain 2 (the Studio Engineer) your own blueprint directly if you prefer full control. Or you can let Brain 1 handle the planning for you. It's your choice every time.\n\n---\n\n## What Can It Do?\n\nACE-Step has six creative modes. Think of them like different tools in a studio:\n\n```\n    ┌──────────────────────────────────────────────────────┐\n    │                  YOUR CREATIVE TOOLKIT               │\n    │                                                      │\n    │  🎵 Text to Music    Describe it → Get a song        │\n    │  🎨 Cover            Restyle an existing song        │\n    │  🖌️ Repaint          Fix one section of a song       │\n    │  🧱 Lego             Add layers to a backing track   │\n    │  🔬 Extract          Pull out individual instruments │\n    │  🎹 Complete         Add accompaniment to vocals     │\n    └──────────────────────────────────────────────────────┘\n```\n\n### Text to Music — Start From Scratch\n\nThe simplest mode. Type a description, get a song.\n\n**You write:** \"melancholic indie folk with acoustic guitar and breathy female vocals\"\n**You get:** A complete song matching that description.\n\n### Cover — Transform a Song's Style\n\nFeed it an existing song and tell it what style you want instead. It keeps the structure (melody shape, rhythm, song form) but changes everything else.\n\n**You provide:** A country ballad\n**You write:** \"heavy metal rock with distorted guitars and screaming vocals\"\n**You get:** The same song reimagined as heavy metal\n\n### Repaint — Fix Just One Part\n\nGenerated a song you love, except the intro is weak? Repaint lets you regenerate just that section while keeping the rest untouched.\n\n**You provide:** A song where seconds 0-10 need work\n**You write:** \"dramatic orchestral build-up\"\n**You get:** Same song, but with a new intro\n\n### Lego — Stack Instrument Layers\n\nHave a drum loop? Add bass. Have a guitar track? Add strings on top. Lego lets you build up a song one layer at a time.\n\n### Extract — Pull Apart a Mix\n\nThe opposite of Lego. Give it a full mix and ask it to isolate just the vocals, or just the drums, or just the guitar.\n\n### Complete — Add Accompaniment\n\nHave a vocal recording with nothing else? Complete generates the backing instruments to match.\n\n---\n\n## What Do I Need to Run It?\n\n### The Short Answer\n\nA computer with a decent graphics card (GPU). The better the GPU, the faster and longer your songs can be.\n\n### Hardware Guide\n\n```\n    YOUR GPU MEMORY          WHAT YOU CAN DO\n    ─────────────────────────────────────────────────────\n\n    4 GB  (entry level)      Songs up to 6 minutes\n    ▓░░░░░░░░░░░░░░░░░░░    1 song at a time\n                             Basic mode only (no Songwriter brain)\n\n    6-8 GB  (budget)         Songs up to 10 minutes\n    ▓▓▓░░░░░░░░░░░░░░░░░    1-2 songs at a time\n                             Optional lightweight Songwriter brain (0.6B)\n\n    8-12 GB (mainstream)     Songs up to 10 minutes\n    ▓▓▓▓▓░░░░░░░░░░░░░░░    2-4 songs at a time\n                             Songwriter brain available (0.6B)\n\n    12-16 GB (sweet spot)    Songs up to 10 minutes\n    ▓▓▓▓▓▓▓░░░░░░░░░░░░░    2-4 songs at a time\n                             Full Songwriter brain (1.7B)\n\n    16-20 GB (enthusiast)    Songs up to 10 minutes\n    ▓▓▓▓▓▓▓▓▓░░░░░░░░░░░    1-4 songs at a time\n                             Larger Songwriter brain (1.7B)\n\n    20-24 GB (high end)      Songs up to 8 minutes\n    ▓▓▓▓▓▓▓▓▓▓░░░░░░░░░░    2-8 songs at a time\n                             All Songwriter brains (0.6B/1.7B/4B), no offload needed\n\n    24 GB+ (pro)             Songs up to 10 minutes\n    ▓▓▓▓▓▓▓▓▓▓▓▓░░░░░░░░    Up to 8 songs at a time\n                             All features unlocked, best quality (4B)\n```\n\n**Common GPUs and where they land:**\n\n| GPU | Memory | Tier |\n|-----|--------|------|\n| GTX 1050 Ti | 4 GB | Entry (Tier 1) |\n| GTX 1660 / RTX 2060 | 6 GB | Budget (Tier 2) |\n| RTX 3060 / 4060 | 8 GB | Mainstream (Tier 4) |\n| RTX 3070 / 4070 | 8-12 GB | Mainstream-Sweet spot (Tier 4-5) |\n| RTX 3080 16GB / 4060 Ti 16GB | 16 GB | Enthusiast (Tier 6a) |\n| RTX 3090 / 4090 | 24 GB | High end / Pro (Tier 6b-Unlimited) |\n| Apple M1/M2/M3 (Mac) | Shared memory | Supported, varies |\n\n**Disk space:** About 100 GB free. The AI models are large files (around 60 GB total) that download automatically the first time you run the software.\n\n**Operating system:** Windows, Mac, or Linux all work.\n\n---\n\n## Getting It Running\n\n### On Windows (Easiest Path)\n\n1. Download the portable package from the ACE-Step website (a single .7z file)\n2. Extract it (right-click → Extract with 7-Zip or WinRAR)\n3. Double-click **start_gradio_ui.bat** inside the extracted folder\n4. A browser window opens — that's your studio\n5. On first launch, models download automatically (30 min to 2 hours depending on internet speed)\n\nThat's it. No programming required.\n\n### On Mac or Linux\n\nYou'll need to type a few commands in the terminal, but it's straightforward:\n\n```\nStep 1:  Install the \"uv\" package manager (a one-time setup)\nStep 2:  Download ACE-Step from GitHub\nStep 3:  Run \"uv sync\" to install everything\nStep 4:  Run \"uv run acestep\" to launch\nStep 5:  Open your browser to http://localhost:7860\n```\n\nThe project's README on GitHub walks through each step with copy-paste commands.\n\n---\n\n## The Interface: What You'll See\n\nWhen ACE-Step opens in your browser, you get a web interface with three main areas:\n\n```\n    ┌─────────────────────────────────────────────────────────────┐\n    │  ACE-Step 1.5                                               │\n    ├─────────────┬───────────────────┬───────────────────────────┤\n    │  Generate   │  LoRA Training    │  Dataset Explorer         │\n    ├─────────────┴───────────────────┴───────────────────────────┤\n    │                                                             │\n    │  The Generate tab is where you'll spend 95% of your time.   │\n    │                                                             │\n    │  LoRA Training is for teaching the AI your personal style.  │\n    │                                                             │\n    │  Dataset Explorer is for browsing example prompts.          │\n    │                                                             │\n    └─────────────────────────────────────────────────────────────┘\n```\n\n### The Generate Tab\n\nThis is your main workspace. It has two modes:\n\n**Simple Mode** — For when you want quick results\n- Type a natural description like \"a soft love song for a quiet evening\"\n- Click \"Create Sample\" and the AI fills in all the details\n- Click \"Generate Music\" — done\n\n**Custom Mode** — For when you want precise control\n- You write the exact description (caption)\n- You write the lyrics with structure tags\n- You set the tempo, key, and duration\n- You adjust advanced settings if you want\n\nMost people start with Simple Mode, then move to Custom Mode once they understand how the system responds.\n\n---\n\n## Writing Prompts: Talking to the AI\n\nThe most important skill with ACE-Step is learning how to describe what you want. You communicate through two main inputs:\n\n### The Caption — Your Overall Vision\n\nThe caption is a short paragraph describing the entire song's vibe. Think of it as the answer to: \"If you walked into a studio with session musicians, how would you describe what you want?\"\n\n**Vague (the AI will guess a lot):**\n> \"a sad song\"\n\n**Better (gives the AI real direction):**\n> \"melancholic piano ballad with soft female vocals, gentle string accompaniment, slow tempo, intimate and heartbreaking atmosphere\"\n\n**Tips for good captions:**\n- Name the genre: pop, rock, jazz, electronic, folk, hip-hop, lo-fi, synthwave\n- Name the instruments: acoustic guitar, piano, synth pads, 808 drums, strings\n- Name the mood: melancholic, uplifting, energetic, dreamy, aggressive, intimate\n- Name the production style: lo-fi, polished, live recording, bedroom pop, orchestral\n\n### The Lyrics — Your Song's Script\n\nLyrics do double duty in ACE-Step. They're not just words — they tell the AI how the song should be **structured** over time.\n\nYou use tags in square brackets to mark sections:\n\n```\n[Intro]\n\n[Verse 1]\nWalking through the empty streets\nThinking of your gentle touch\nSummer nights and softer dreams\n\n[Chorus]\nWe rise together\nInto the light\nThis is our moment tonight\n\n[Verse 2]\nStars are falling from the sky\nYour hand fits perfectly in mine\n\n[Bridge]\nIf tomorrow never comes\nAt least we had this\n\n[Chorus]\nWe rise together\nInto the light\nThis is our moment tonight\n\n[Outro]\n```\n\n**What the tags do:**\n\n```\n    [Intro]          → Sets up atmosphere, usually instrumental\n    [Verse]          → Main storytelling section, moderate energy\n    [Pre-Chorus]     → Builds tension before the chorus\n    [Chorus]         → Emotional peak, highest energy\n    [Bridge]         → A shift — different melody, different feel\n    [Instrumental]   → No vocals, just instruments\n    [Outro]          → Winds down, often fades\n```\n\n**Lyric tips:**\n- Keep lines around 6-10 syllables so the AI can fit them naturally\n- Use UPPERCASE for words you want emphasized or shouted\n- Use (parentheses) for background vocals or echoes\n- Add descriptors to tags for extra guidance: `[Chorus - anthemic]` or `[Verse - whispered]`\n\n### Optional: Metadata\n\nYou can also set specific musical parameters:\n\n| Setting | What It Means | Typical Values |\n|---------|---------------|----------------|\n| **BPM** | Speed of the song | 60-80 (slow), 90-120 (medium), 130-180 (fast) |\n| **Key** | Musical key | C Major (bright), A minor (melancholic), etc. |\n| **Duration** | Song length in seconds | 60 (1 min), 180 (3 min), 300 (5 min) |\n| **Language** | Vocal language | English, Spanish, Japanese, Chinese, 50+ others |\n\nIf you don't set these, the AI will choose sensible defaults based on your caption and lyrics.\n\n---\n\n## Working With Reference Audio\n\nOne of ACE-Step's most powerful features is using existing audio to guide generation. There are three ways to do this:\n\n```\n    ┌──────────────────────────────────────────────────────────┐\n    │               THREE WAYS TO USE AUDIO INPUT              │\n    │                                                          │\n    │   1. REFERENCE AUDIO (style guide)                       │\n    │      ┌──────────┐                                        │\n    │      │ jazz.mp3 │──→ \"Make something that SOUNDS         │\n    │      └──────────┘     like this — same warmth, same      │\n    │                       texture, same vibe\"                │\n    │                                                          │\n    │   2. SOURCE AUDIO + COVER (restyle a song)               │\n    │      ┌──────────┐                                        │\n    │      │ song.mp3 │──→ \"Keep the STRUCTURE of this song    │\n    │      └──────────┘     but change the style completely\"   │\n    │                                                          │\n    │   3. SOURCE AUDIO + REPAINT (fix a section)              │\n    │      ┌──────────┐                                        │\n    │      │ song.mp3 │──→ \"Keep the whole song EXCEPT         │\n    │      └──────────┘     regenerate seconds 10-20\"          │\n    │                                                          │\n    └──────────────────────────────────────────────────────────┘\n```\n\n### Cover Mode: The Style Transformer\n\nThis is the mode for turning one genre into another. The key control is **Audio Cover Strength** — a slider from 0 to 100%:\n\n```\n    Audio Cover Strength\n\n    0%                     50%                    100%\n    ├──────────────────────┼──────────────────────┤\n    │                      │                      │\n    Ignores the         Balanced              Follows the\n    original audio.     blend.                original closely.\n    Pure text-based     Recognizable          Same structure,\n    generation.         but transformed.      subtle changes only.\n\n\n    For dramatic genre changes (country → metal):  use 30-50%\n    For moderate changes (pop → jazz):             use 50-70%\n    For subtle changes (rock → indie rock):        use 70-90%\n```\n\n**Example: Country to Heavy Metal**\n\n1. Upload your country song as source audio\n2. Select the \"Cover\" task\n3. Set Audio Cover Strength to about 40%\n4. Write a caption like: *\"heavy metal rock with heavily distorted electric guitars, aggressive double bass drumming, powerful screaming vocals, fast tempo, high energy, intense dark atmosphere\"*\n5. Generate a few variations (batch size 2-4)\n6. Pick your favorite\n\n---\n\n## The Batch Generation Workflow\n\nA critical concept: **you should almost never generate just one version.** AI music generation involves randomness. Think of it like rolling dice — sometimes you get exactly what you wanted, sometimes you don't. The solution is to roll several times and pick the best.\n\n```\n    THE RECOMMENDED WORKFLOW\n\n    ┌──────────────┐     ┌──────────────┐     ┌──────────────┐\n    │  Write your  │────▶│  Generate a  │────▶│  Listen to   │\n    │  description │     │  batch of 4  │     │  all four    │\n    └──────────────┘     └──────────────┘     └─────┬────────┘\n                                                    │\n                                ┌───────────────────┼──────────┐\n                                │                   │          │\n                                ▼                   ▼          ▼\n                          ┌──────────┐       ┌──────────┐  ┌──────────┐\n                          │ Love it? │       │ Close    │  │ Not      │\n                          │ Export!  │       │ but not  │  │ right?   │\n                          └──────────┘       │ quite?   │  │ Tweak    │\n                                             │ Repaint  │  │ prompt   │\n                                             │ the weak │  │ & retry  │\n                                             │ section  │  └──────────┘\n                                             └──────────┘\n```\n\n**AutoGen:** There's also an \"auto-generate\" feature that starts preparing the next batch while you're listening to the current one. This keeps your creative flow uninterrupted.\n\n---\n\n## Training Your Own Style (LoRA)\n\nLoRA is a way to teach ACE-Step your personal sound. If you have a collection of songs that represent a style you want the AI to learn — your own recordings, a specific genre, a particular mood — you can train a custom \"style adapter.\"\n\n### What Is a LoRA?\n\nThink of it as a small plug-in that sits on top of the base AI model:\n\n```\n    ┌──────────────────────────────────────┐\n    │         BASE AI MODEL                │\n    │   (knows how to make all kinds       │\n    │    of music in general)              │\n    │                                      │\n    │    ┌──────────────────────────┐      │\n    │    │    YOUR LoRA ADAPTER     │      │\n    │    │  (teaches it YOUR style) │      │\n    │    │                          │      │\n    │    │  Trained on 8-20 of      │      │\n    │    │  your reference songs    │      │\n    │    └──────────────────────────┘      │\n    │                                      │\n    └──────────────────────────────────────┘\n\n    Without LoRA: generic but versatile\n    With LoRA:    sounds more like YOUR music\n```\n\n### How to Train One\n\n1. **Collect 8-20 songs** that represent the style you want\n2. Go to the **LoRA Training** tab in the interface\n3. Point it at the folder with your audio files\n4. Click \"Scan\" — it analyzes each file automatically\n5. Review and edit the auto-generated labels if needed\n6. Click \"Start Training\" — takes about 1 hour on a good GPU\n7. When finished, you have a LoRA adapter file you can load any time\n\n### Using Your LoRA\n\n1. In the Generate tab, find the \"LoRA Adapter\" section\n2. Enter the path to your trained LoRA\n3. Click \"Load LoRA\"\n4. Adjust the **LoRA Scale** slider:\n\n```\n    LoRA Scale\n\n    0%                     50%                    100%\n    ├──────────────────────┼──────────────────────┤\n    │                      │                      │\n    No LoRA effect.     Half strength.         Full LoRA effect.\n    Pure base model.    Blended style.         Maximum influence\n                                               from your training.\n```\n\n5. Generate music as usual — the output will now be influenced by your trained style\n\n### Current Limitation: One LoRA at a Time\n\nToday, you can only use one LoRA adapter at a time. Loading a new one replaces the previous one. You cannot stack multiple styles simultaneously (for example, \"jazz LoRA at 60% + vocal LoRA at 40%\"). This is a known limitation that may be addressed in a future update.\n\n---\n\n## The Speed Question\n\nHow long does generation take? It depends on your hardware and settings:\n\n```\n    GENERATION SPEED (approximate)\n\n    GPU Tier          30-sec song    2-min song     5-min song\n    ──────────────────────────────────────────────────────────\n    Entry (4 GB)      10-15 sec      20-30 sec      N/A\n    Mainstream (8 GB)  5-10 sec      10-18 sec      15-25 sec\n    Sweet spot (12 GB) 3-8 sec        8-12 sec      10-15 sec\n    High end (24 GB)   1-3 sec        3-7 sec        5-10 sec\n```\n\n**Fast Mode vs. Quality Mode:**\n- **Turbo** (default): 8 processing steps, very fast, good quality\n- **SFT/Base**: 50 processing steps, slower, more detail and nuance\n\nMost people use Turbo for day-to-day work and switch to SFT/Base for final versions.\n\n---\n\n## Languages\n\nACE-Step can generate vocals in 50+ languages, including:\n\nEnglish, Spanish, French, German, Italian, Portuguese, Chinese (Mandarin & Cantonese), Japanese, Korean, Hindi, Bengali, Arabic, Turkish, Thai, Vietnamese, Swedish, Dutch, Polish, Hebrew, and many more.\n\nTo use a different language:\n1. Select the vocal language in the interface\n2. Write your lyrics in that language\n3. The AI generates vocals with appropriate pronunciation and style\n\nYou can even mix languages within a single song.\n\n---\n\n## Tips From Experience\n\n### Start Simple, Then Refine\nDon't try to control everything on your first attempt. Start with a short caption and see what the AI gives you. Then add detail in areas where the output surprised you.\n\n### Generate in Batches\nAlways generate 2-4 versions at once. Picking the best from several options is faster and more satisfying than trying to get one perfect result.\n\n### Fix, Don't Redo\nIf 90% of a song is great but one section is off, use **Repaint** to regenerate just that section. Don't throw away the whole thing.\n\n### Be Specific About Instruments\n\"rock song\" gives the AI too much freedom. \"rock song with crunchy rhythm guitar, punchy snare, and gravelly male vocals\" tells it exactly what you're hearing in your head.\n\n### Use Structure Tags in Lyrics\nEven if you don't care about the actual words yet, writing `[Intro] [Verse] [Chorus] [Verse] [Chorus] [Bridge] [Chorus] [Outro]` gives the AI a roadmap for energy and dynamics.\n\n### Try Different Seeds\nEvery generation uses a random \"seed\" number. If you like your settings but want to hear different interpretations, just click generate again — each run uses a new seed automatically. You can also set a specific seed number to reproduce a result you liked.\n\n### The Songwriter Brain Is Optional\nIf you already know exactly what you want (tempo, key, structure, instruments), you can turn off \"Thinking Mode\" to skip Brain 1 entirely. This makes generation faster and gives you more direct control.\n\n---\n\n## What ACE-Step Is Not\n\nIt's worth being clear about what this tool isn't:\n\n- **It's not a DAW.** It doesn't replace Ableton, Logic, or FL Studio. It generates raw audio that you can import into your DAW for further editing.\n- **It's not perfect every time.** Expect to generate several versions and pick the best. Think of it as a creative collaborator, not a jukebox.\n- **It's not a cloud service.** It runs on your machine. If your GPU is small, results will be limited. There's no server doing the work for you.\n- **It's not one-click magic.** The best results come from learning how to describe what you want. That's a skill that improves with practice.\n\nWhat it *is*: a powerful, free, open instrument that puts AI music generation in your hands — literally on your own hardware — with full creative control and ownership.\n\n---\n\n## Quick Reference Card\n\n```\n    ┌─────────────────────────────────────────────────────────┐\n    │                    QUICK REFERENCE                      │\n    │                                                         │\n    │  GENERATE A SONG                                        │\n    │    Caption:  Describe style, instruments, mood          │\n    │    Lyrics:   [Verse] [Chorus] [Bridge] with words       │\n    │    Click:    Generate Music                             │\n    │                                                         │\n    │  RESTYLE A SONG (Cover)                                 │\n    │    Upload:   Source audio                               │\n    │    Task:     Cover                                      │\n    │    Caption:  Describe the NEW style                     │\n    │    Strength: 30-50% for big changes, 70-90% for subtle  │\n    │                                                         │\n    │  FIX A SECTION (Repaint)                                │\n    │    Upload:   Source audio                               │\n    │    Task:     Repaint                                    │\n    │    Time:     Set start and end (in seconds)             │\n    │    Caption:  Describe what the fixed section should be  │\n    │                                                         │\n    │  APPLY CUSTOM STYLE (LoRA)                              │\n    │    Load:     Your trained LoRA adapter file             │\n    │    Scale:    0-100% (how much style influence)          │\n    │    Then:     Generate as usual                          │\n    │                                                         │\n    │  KEYBOARD SHORTCUTS                                     │\n    │    Batch size 2-4 recommended for every generation      │\n    │    Use Turbo mode for speed, SFT/Base for quality       │\n    │    Turn off Thinking Mode if you know exactly what      │\n    │    you want                                             │\n    └─────────────────────────────────────────────────────────┘\n```\n"
  },
  {
    "path": "docs/en/index.md",
    "content": "---\nlayout: home\nhero:\n  name: ACE-Step 1.5\n  text: Open-Source Music Generation\n  tagline: Commercial-grade music generation on consumer hardware. Under 2s per song on A100, <4GB VRAM.\n  image:\n    src: /logo.png\n    alt: ACE-Step\n  actions:\n    - theme: brand\n      text: Installation\n      link: /en/INSTALL\n    - theme: alt\n      text: Tutorial (Must Read)\n      link: /en/Tutorial\n    - theme: alt\n      text: API Reference\n      link: /en/API\n\nfeatures:\n  - icon: \"&#9889;\"\n    title: Ultra-Fast Generation\n    details: Under 2s per full song on A100, under 10s on RTX 3090. Supports 10s to 10min audio generation.\n  - icon: \"&#127925;\"\n    title: Commercial-Grade Quality\n    details: 1000+ instruments and styles, 50+ languages with lyrics prompt for structure and style control.\n  - icon: \"&#127899;\"\n    title: Versatile Editing\n    details: Cover generation, repainting, track separation, vocal-to-BGM, multi-track generation, and more.\n  - icon: \"&#128640;\"\n    title: Lightweight & Customizable\n    details: Runs locally with <4GB VRAM. Train a LoRA from just a few songs in 1 hour on a 3090.\n  - icon: \"&#127908;\"\n    title: Reference Audio Input\n    details: Use reference audio to guide generation style. Create covers from existing audio.\n  - icon: \"&#128300;\"\n    title: Audio Understanding\n    details: Extract BPM, key/scale, time signature and caption from audio. Auto-generate LRC timestamps.\n---\n"
  },
  {
    "path": "docs/en/studio.md",
    "content": "# Experimental Studio UI\n\nACE-Step includes an optional, experimental HTML-based Studio UI for users who want a more structured, DAW-like interface.\n\nThis UI:\n\n- Is frontend-only\n- Talks to the same REST API (`/release_task`, `/query_result`)\n- Does not change model behavior\n\nFor the plugin-oriented contract and status mapping, see\n[VST3 Backend Contract](./VST3_BACKEND_CONTRACT.md).\n\n## How to use\n\n1. Start the ACE-Step API server (e.g. `uv run acestep --enable-api --port 8001` or your usual API launch command).\n2. Open `ui/studio.html` in a browser (double-click or `file:///path/to/ACE-Step-1.5/ui/studio.html`).\n3. Set the API base URL if needed (default: `http://localhost:8001`).\n4. Enter prompt and options, then click **Generate**. The UI will poll for results and display audio when ready.\n\n## Scope\n\n- **Optional:** The default way to use ACE-Step remains the Gradio Web UI.\n- **No backend changes:** This UI uses the existing REST API only.\n- **Experimental:** Layout and features may change based on community feedback.\n"
  },
  {
    "path": "docs/index.md",
    "content": "---\nlayout: home\nhero:\n  name: ACE-Step 1.5\n  text: Open-Source Music Generation\n  tagline: Commercial-grade music generation on consumer hardware. Under 2s per song on A100, <4GB VRAM.\n  image:\n    src: /logo.png\n    alt: ACE-Step\n  actions:\n    - theme: brand\n      text: Get Started\n      link: /en/INSTALL\n    - theme: alt\n      text: Tutorial\n      link: /en/Tutorial\n    - theme: alt\n      text: GitHub\n      link: https://github.com/ace-step/ACE-Step-1.5\n\nfeatures:\n  - icon: \"&#9889;\"\n    title: Ultra-Fast Generation\n    details: Under 2s per full song on A100, under 10s on RTX 3090. Supports 10s to 10min audio.\n  - icon: \"&#127925;\"\n    title: Commercial-Grade Quality\n    details: 1000+ instruments and styles, 50+ languages, fine-grained timbre description and metadata control.\n  - icon: \"&#127899;\"\n    title: Versatile Editing\n    details: Cover generation, repainting, track separation, vocal-to-BGM, multi-track generation, and more.\n  - icon: \"&#128640;\"\n    title: Lightweight & Customizable\n    details: Runs locally with <4GB VRAM. Train a LoRA from just a few songs to capture your own style.\n---\n"
  },
  {
    "path": "docs/ja/API.md",
    "content": "# ACE-Step API クライアントドキュメント\n\n**Language / 语言 / 言語:** [English](../en/API.md) | [中文](../zh/API.md) | [日本語](API.md)\n\n---\n\n本サービスはHTTPベースの非同期音楽生成APIを提供します。\n\n**基本的なワークフロー**：\n1. `POST /release_task` を呼び出してタスクを送信し、`task_id` を取得します。\n2. `POST /query_result` を呼び出してタスクステータスを一括クエリし、`status` が `1`（成功）または `2`（失敗）になるまで待ちます。\n3. 結果で返された `GET /v1/audio?path=...` URL から音声ファイルをダウンロードします。\n\n---\n\n## 目次\n\n- [認証](#1-認証)\n- [レスポンス形式](#2-レスポンス形式)\n- [タスクステータスの説明](#3-タスクステータスの説明)\n- [生成タスクの作成](#4-生成タスクの作成)\n- [タスク結果の一括クエリ](#5-タスク結果の一括クエリ)\n- [入力のフォーマット](#6-入力のフォーマット)\n- [ランダムサンプルの取得](#7-ラ���ダムサンプルの取得)\n- [利用可能なモデルの一覧](#8-利用可能なモデルの一覧)\n- [サーバー統計](#9-サーバー統計)\n- [音声ファイルのダウンロード](#10-音声ファイルのダウンロード)\n- [ヘルスチェック](#11-ヘルスチェック)\n- [環境変数](#12-環境変数)\n\n---\n\n## 1. 認証\n\nAPIはオプションのAPIキー認証をサポートしています。有効にすると、リクエストに有効なキーを提供する必要があります。\n\n### 認証方法\n\n2つの認証方法をサポート：\n\n**方法 A：リクエストボディの ai_token**\n\n```json\n{\n  \"ai_token\": \"your-api-key\",\n  \"prompt\": \"アップビートなポップソング\",\n  ...\n}\n```\n\n**方法 B：Authorization ヘッダー**\n\n```bash\ncurl -X POST http://localhost:8001/release_task \\\n  -H 'Authorization: Bearer your-api-key' \\\n  -H 'Content-Type: application/json' \\\n  -d '{\"prompt\": \"アップビートなポップソング\"}'\n```\n\n### APIキーの設定\n\n環境変数またはコマンドライン引数で設定：\n\n```bash\n# 環境変数\nexport ACESTEP_API_KEY=your-secret-key\n\n# またはコマンドライン引数\npython -m acestep.api_server --api-key your-secret-key\n```\n\n---\n\n## 2. レスポンス形式\n\nすべてのAPIレスポンスは統一されたラッパー形式を使用します：\n\n```json\n{\n  \"data\": { ... },\n  \"code\": 200,\n  \"error\": null,\n  \"timestamp\": 1700000000000,\n  \"extra\": null\n}\n```\n\n| フィールド | 型 | 説明 |\n| :--- | :--- | :--- |\n| `data` | any | 実際のレスポンスデータ |\n| `code` | int | ステータスコード（200=成功）|\n| `error` | string | エラーメッセージ（成功時はnull）|\n| `timestamp` | int | レスポンスタイムスタンプ（ミリ秒）|\n| `extra` | any | 追加情報���通常はnull）|\n\n---\n\n## 3. タスクステータスの説明\n\nタスクステータス（`status`）は整数で表されます：\n\n| ステータスコード | ステータス名 | 説明 |\n| :--- | :--- | :--- |\n| `0` | queued/running | タスクがキュー中または実行中 |\n| `1` | succeeded | 生成成功、結果が準備完了 |\n| `2` | failed | 生成失敗 |\n\n---\n\n## 4. 生成タスクの作成\n\n### 4.1 API 定義\n\n- **URL**：`/release_task`\n- **メソッド**：`POST`\n- **Content-Type**：`application/json`、`multipart/form-data`、または `application/x-www-form-urlencoded`\n\n### 4.2 リクエストパラメータ\n\n#### パラメータ命名規則\n\nAPIはほとんどのパラメータで **snake_case** と **camelCase** の両方の命名をサポートしています。例：\n- `audio_duration` / `duration` / `audioDuration`\n- `key_scale` / `keyscale` / `keyScale`\n- `time_signature` / `timesignature` / `timeSignature`\n- `sample_query` / `sampleQuery` / `description` / `desc`\n- `use_format` / `useFormat` / `format`\n\nまた、メタデータはネストされたオブジェクト（`metas`、`metadata`、または `user_metadata`）で渡すことができます。\n\n#### 方法 A：JSONリクエスト（application/json）\n\nテキストパラメータのみを渡す場合、またはサーバー上に既に存在する音声ファイルパスを参照する場合に適しています。\n\n**基本パラメータ**：\n\n| パラメータ名 | 型 | デフォルト | 説明 |\n| :--- | :--- | :--- | :--- |\n| `prompt` | string | `\"\"` | 音楽の説明プロンプト（別名：`caption`）|\n| `lyrics` | string | `\"\"` | 歌詞の内容 |\n| `thinking` | bool | `false` | 5Hz LMを使用してオーディオコードを生成するかどうか（lm-dit動作）|\n| `vocal_language` | string | `\"en\"` | 歌詞の言語（en、zh、jaなど）|\n| `audio_format` | string | `\"mp3\"` | 出力形式（mp3、wav、flac）|\n\n**サンプル/説明モードパラメータ**：\n\n| パラメータ名 | 型 | デフォルト | 説明 |\n| :--- | :--- | :--- | :--- |\n| `sample_mode` | bool | `false` | ランダムサンプル生成モードを有効にする（LM経由でcaption/lyrics/metasを自動生成）|\n| `sample_query` | string | `\"\"` | サンプル生成のための自然言語の説明（例：「静かな夜のための柔らかいベンガルのラブソング」）。別名：`description`、`desc` |\n| `use_format` | bool | `false` | LMを使用して提供されたcaptionとlyricsを強化/フォーマットする。別名：`format` |\n\n**マルチモデルサポート**：\n\n| パラメータ名 | 型 | デフォルト | 説明 |\n| :--- | :--- | :--- | :--- |\n| `model` | string | null | 使用するDiTモデルを選択（例：`\"acestep-v15-turbo\"`、`\"acestep-v15-turbo-shift3\"`）。`/v1/models` で利用可能なモデルを一覧表示。指定しない場合はデフォルトモデルを使用。|\n\n**thinkingのセマンティクス（重要）**：\n\n- `thinking=false`：\n  - サーバーは5Hz LMを使用して `audio_code_string` を生成**しません**。\n  - DiTは **text2music** モードで実行され、提供された `audio_code_string` を**無視**します。\n- `thinking=true`：\n  - サーバーは5Hz LMを使用して `audio_code_string` を生成します（lm-dit動作）。\n  - DiTはLM生成のコードで実行され、音楽品質が向上します。\n\n**メタデータの自動補完（条件付き）**：\n\n`use_cot_caption=true` または `use_cot_language=true` またはメタデータフィールドが欠落している場合、サーバーは `caption`/`lyrics` に基づいて5Hz LMを呼び出し、欠落しているフィールドを補完することがあります：\n\n- `bpm`\n- `key_scale`\n- `time_signature`\n- `audio_duration`\n\nユーザー提供の値が常に優先されます。LMは空/欠落しているフィールドのみを補完します。\n\n**音楽属性パラメータ**：\n\n| パラメータ名 | 型 | デフォルト | 説明 |\n| :--- | :--- | :--- | :--- |\n| `bpm` | int | null | テンポ（BPM）を指定、範囲30-300 |\n| `key_scale` | string | `\"\"` | キー/スケール（例：「C Major」、「Am」）。別名：`keyscale`、`keyScale` |\n| `time_signature` | string | `\"\"` | 拍子記号（2、3、4、6はそれぞれ2/4、3/4、4/4、6/8）。別名：`timesignature`、`timeSignature` |\n| `audio_duration` | float | null | 生成時間（秒）、範囲10-600。別名：`duration`、`target_duration` |\n\n**オーディオコード（オプション）**：\n\n| パラメータ名 | 型 | デフォルト | 説明 |\n| :--- | :--- | :--- | :--- |\n| `audio_code_string` | string または string[] | `\"\"` | `llm_dit` 用のオーディオセマンティックトークン（5Hz）。別名：`audioCodeString` |\n\n**生成制御パラメータ**：\n\n| パラメータ名 | 型 | デフォルト | 説明 |\n| :--- | :--- | :--- | :--- |\n| `inference_steps` | int | `8` | 推論ステップ数。Turboモデル：1-20（推奨8）。Baseモデル：1-200（推奨32-64）|\n| `guidance_scale` | float | `7.0` | プロンプトガイダンス係数。baseモデルのみ有効 |\n| `use_random_seed` | bool | `true` | ランダムシードを使用するかどうか |\n| `seed` | int | `-1` | シードを指定（use_random_seed=falseの場合）|\n| `batch_size` | int | `2` | バッチ生成数（最大8）|\n\n**高度なDiTパラメータ**：\n\n| パラメータ名 | 型 | デフォルト | 説明 |\n| :--- | :--- | :--- | :--- |\n| `shift` | float | `3.0` | タイムステップシフト係数（範囲1.0-5.0）。baseモデルのみ有効、turboモデルには無効 |\n| `infer_method` | string | `\"ode\"` | 拡散推論方法：`\"ode\"`（Euler、より高速）または `\"sde\"`（確率的）|\n| `timesteps` | string | null | カンマ区切りのカスタムタイムステップ（例：`\"0.97,0.76,0.615,0.5,0.395,0.28,0.18,0.085,0\"`）。`inference_steps` と `shift` をオーバーライド |\n| `use_adg` | bool | `false` | 適応デュアルガイダンスを使用（baseモデルのみ）|\n| `cfg_interval_start` | float | `0.0` | CFG適用開始比率（0.0-1.0）|\n| `cfg_interval_end` | float | `1.0` | CFG適用終了比率（0.0-1.0）|\n\n**5Hz LMパラメータ（オプション、サーバー側）**：\n\nこれらのパラメータは5Hz LMサンプリングを制御し、メタデータの自動補完と（`thinking=true` の場合）コード生成に使用されます。\n\n| パラメータ名 | 型 | デフォルト | 説明 |\n| :--- | :--- | :--- | :--- |\n| `lm_model_path` | string | null | 5Hz LMチェックポイントディレクトリ名（例：`acestep-5Hz-lm-0.6B`）|\n| `lm_backend` | string | `\"vllm\"` | `vllm` または `pt` |\n| `lm_temperature` | float | `0.85` | サンプリング温度 |\n| `lm_cfg_scale` | float | `2.5` | CFGスケール（>1でCFGを有効化）|\n| `lm_negative_prompt` | string | `\"NO USER INPUT\"` | CFGで使用するネガティブプロンプト |\n| `lm_top_k` | int | null | Top-k（0/nullで無効）|\n| `lm_top_p` | float | `0.9` | Top-p（>=1は無効として扱われる）|\n| `lm_repetition_penalty` | float | `1.0` | 繰り返しペナルティ |\n\n**LM CoT（思考の連鎖）パラメータ**：\n\n| パラメータ名 | 型 | デフォルト | 説明 |\n| :--- | :--- | :--- | :--- |\n| `use_cot_caption` | bool | `true` | LMにCoT推論で入力captionを書き換え/強化させる。別名：`cot_caption`、`cot-caption` |\n| `use_cot_language` | bool | `true` | LMにCoTでボーカル言語を検出させる。別名：`cot_language`、`cot-language` |\n| `constrained_decoding` | bool | `true` | 構造化されたLM出力のためのFSMベースの制約付きデコーディングを有効にする。別名：`constrainedDecoding`、`constrained` |\n| `constrained_decoding_debug` | bool | `false` | 制約付きデコーディングのデバッグログを有効にする |\n| `allow_lm_batch` | bool | `true` | 効率向上のためにLMバッチ処理を許可 |\n\n**編集/参照オーディオパラメータ**（サーバー上の絶対パスが必要）：\n\n| パラメータ名 | 型 | デフォルト | 説明 |\n| :--- | :--- | :--- | :--- |\n| `reference_audio_path` | string | null | 参照オーディオパス（スタイル転送）|\n| `src_audio_path` | string | null | ソースオーディオパス（リペイント/カバー）|\n| `task_type` | string | `\"text2music\"` | タスクタイプ：`text2music`、`cover`、`repaint`、`lego`、`extract`、`complete` |\n| `instruction` | string | auto | 編集指示（提供されない場合はtask_typeに基づいて自動生成）|\n| `repainting_start` | float | `0.0` | リペイント開始時間（秒）|\n| `repainting_end` | float | null | リペイント終了時間（秒）、-1でオーディオの終端 |\n| `audio_cover_strength` | float | `1.0` | カバー強度（0.0-1.0）。スタイル転送には小さい値（0.2）を使用 |\n\n#### 方法 B：ファイルアップロード（multipart/form-data）\n\n参照またはソースオーディオとしてローカルオーディオファイルをアップロードする必要がある場合に使用します。\n\n上記のすべてのフィールドをフォームフィールドとしてサポートすることに加えて、以下のファイルフィールドもサポートしています：\n\n- `reference_audio` または `ref_audio`：（ファイル）参照オーディオファイルをアップロード\n- `src_audio` または `ctx_audio`：（ファイル）ソースオーディオファイルをアップロード\n\n> **注意**：ファイルをアップロードすると、対応する `_path` パラメータは自動的に無視され、システムはアップロード後の一時ファイルパスを使用します。\n\n### 4.3 レスポンス例\n\n```json\n{\n  \"data\": {\n    \"task_id\": \"550e8400-e29b-41d4-a716-446655440000\",\n    \"status\": \"queued\",\n    \"queue_position\": 1\n  },\n  \"code\": 200,\n  \"error\": null,\n  \"timestamp\": 1700000000000,\n  \"extra\": null\n}\n```\n\n### 4.4 使用例（cURL）\n\n**基本的なJSONメソッド**：\n\n```bash\ncurl -X POST http://localhost:8001/release_task \\\n  -H 'Content-Type: application/json' \\\n  -d '{\n    \"prompt\": \"アップビートなポップソング\",\n    \"lyrics\": \"Hello world\",\n    \"inference_steps\": 8\n  }'\n```\n\n**thinking=trueの場合（LMがコードを生成 + 欠落メタを補完）**：\n\n```bash\ncurl -X POST http://localhost:8001/release_task \\\n  -H 'Content-Type: application/json' \\\n  -d '{\n    \"prompt\": \"アップビートなポップソング\",\n    \"lyrics\": \"Hello world\",\n    \"thinking\": true,\n    \"lm_temperature\": 0.85,\n    \"lm_cfg_scale\": 2.5\n  }'\n```\n\n**説明駆動型生成（sample_query）**：\n\n```bash\ncurl -X POST http://localhost:8001/release_task \\\n  -H 'Content-Type: application/json' \\\n  -d '{\n    \"sample_query\": \"静かな夜のための柔らかいベンガルのラブソング\",\n    \"thinking\": true\n  }'\n```\n\n**フォーマット強化（use_format=true）**：\n\n```bash\ncurl -X POST http://localhost:8001/release_task \\\n  -H 'Content-Type: application/json' \\\n  -d '{\n    \"prompt\": \"ポップロック\",\n    \"lyrics\": \"[Verse 1]\\n街を歩いて...\",\n    \"use_format\": true,\n    \"thinking\": true\n  }'\n```\n\n**特定のモデルを選択**：\n\n```bash\ncurl -X POST http://localhost:8001/release_task \\\n  -H 'Content-Type: application/json' \\\n  -d '{\n    \"prompt\": \"エレクトロニックダンスミュージック\",\n    \"model\": \"acestep-v15-turbo\",\n    \"thinking\": true\n  }'\n```\n\n**カスタムタイムステップを使用**：\n\n```bash\ncurl -X POST http://localhost:8001/release_task \\\n  -H 'Content-Type: application/json' \\\n  -d '{\n    \"prompt\": \"ジャズピアノトリオ\",\n    \"timesteps\": \"0.97,0.76,0.615,0.5,0.395,0.28,0.18,0.085,0\",\n    \"thinking\": true\n  }'\n```\n\n**ファイルアップロードメソッド**：\n\n```bash\ncurl -X POST http://localhost:8001/release_task \\\n  -F \"prompt=この曲をリミックス\" \\\n  -F \"src_audio=@/path/to/local/song.mp3\" \\\n  -F \"task_type=repaint\"\n```\n\n---\n\n## 5. タスク結果の一括クエリ\n\n### 5.1 API 定義\n\n- **URL**：`/query_result`\n- **メソッド**：`POST`\n- **Content-Type**：`application/json` または `application/x-www-form-urlencoded`\n\n### 5.2 リクエストパラメータ\n\n| パラメータ名 | 型 | 説明 |\n| :--- | :--- | :--- |\n| `task_id_list` | string (JSON array) または array | クエリするタスクIDのリスト |\n\n### 5.3 レスポンス例\n\n```json\n{\n  \"data\": [\n    {\n      \"task_id\": \"550e8400-e29b-41d4-a716-446655440000\",\n      \"status\": 1,\n      \"result\": \"[{\\\"file\\\": \\\"/v1/audio?path=...\\\", \\\"wave\\\": \\\"\\\", \\\"status\\\": 1, \\\"create_time\\\": 1700000000, \\\"env\\\": \\\"development\\\", \\\"prompt\\\": \\\"アップビートなポップソング\\\", \\\"lyrics\\\": \\\"Hello world\\\", \\\"metas\\\": {\\\"bpm\\\": 120, \\\"duration\\\": 30, \\\"genres\\\": \\\"\\\", \\\"keyscale\\\": \\\"C Major\\\", \\\"timesignature\\\": \\\"4\\\"}, \\\"generation_info\\\": \\\"...\\\", \\\"seed_value\\\": \\\"12345,67890\\\", \\\"lm_model\\\": \\\"acestep-5Hz-lm-0.6B\\\", \\\"dit_model\\\": \\\"acestep-v15-turbo\\\"}]\"\n    }\n  ],\n  \"code\": 200,\n  \"error\": null,\n  \"timestamp\": 1700000000000,\n  \"extra\": null\n}\n```\n\n**結果フィールドの説明**（resultはJSON文字列、パース後に含まれる）：\n\n| フィールド | 型 | 説明 |\n| :--- | :--- | :--- |\n| `file` | string | オーディオファイルURL（`/v1/audio` エンドポイントと併用）|\n| `wave` | string | 波形データ（通常は空）|\n| `status` | int | ステータスコード（0=進行中、1=成功、2=失敗）|\n| `create_time` | int | 作成時間（Unixタイムスタンプ）|\n| `env` | string | 環境識別子 |\n| `prompt` | string | 使用されたプロンプト |\n| `lyrics` | string | 使用された歌詞 |\n| `metas` | object | メタデータ（bpm、duration、genres、keyscale、timesignature）|\n| `generation_info` | string | 生成情報の概要 |\n| `seed_value` | string | 使用されたシード値（カンマ区切り）|\n| `lm_model` | string | 使用されたLMモデル名 |\n| `dit_model` | string | 使用されたDiTモデル名 |\n\n### 5.4 使用例\n\n```bash\ncurl -X POST http://localhost:8001/query_result \\\n  -H 'Content-Type: application/json' \\\n  -d '{\n    \"task_id_list\": [\"550e8400-e29b-41d4-a716-446655440000\"]\n  }'\n```\n\n---\n\n## 6. 入力のフォーマット\n\n### 6.1 API 定義\n\n- **URL**：`/format_input`\n- **メソッド**：`POST`\n\nこのエンドポイントはLLMを使用してユーザー提供のcaptionとlyricsを強化・フォーマットします。\n\n### 6.2 リクエストパラメータ\n\n| パラメータ名 | 型 | デフォルト | 説明 |\n| :--- | :--- | :--- | :--- |\n| `prompt` | string | `\"\"` | 音楽の説明プロンプト |\n| `lyrics` | string | `\"\"` | 歌詞の内容 |\n| `temperature` | float | `0.85` | LMサンプリング温度 |\n| `param_obj` | string (JSON) | `\"{}\"` | メタデータを含むJSONオブジェクト（duration、bpm、key、time_signature、language）|\n\n### 6.3 レスポンス例\n\n```json\n{\n  \"data\": {\n    \"caption\": \"強化された音楽の説明\",\n    \"lyrics\": \"フォーマットされた歌詞...\",\n    \"bpm\": 120,\n    \"key_scale\": \"C Major\",\n    \"time_signature\": \"4\",\n    \"duration\": 180,\n    \"vocal_language\": \"ja\"\n  },\n  \"code\": 200,\n  \"error\": null,\n  \"timestamp\": 1700000000000,\n  \"extra\": null\n}\n```\n\n### 6.4 使用例\n\n```bash\ncurl -X POST http://localhost:8001/format_input \\\n  -H 'Content-Type: application/json' \\\n  -d '{\n    \"prompt\": \"ポップロック\",\n    \"lyrics\": \"街を歩いて\",\n    \"param_obj\": \"{\\\"duration\\\": 180, \\\"language\\\": \\\"ja\\\"}\"\n  }'\n```\n\n---\n\n## 7. ランダムサンプルの取得\n\n### 7.1 API 定義\n\n- **URL**：`/create_random_sample`\n- **メソッド**：`POST`\n\nこのエンドポイントは事前にロードされたサンプルデータからランダムなサンプルパラメータを返します。フォーム入力に使用します。\n\n### 7.2 リクエストパラメータ\n\n| パラメータ名 | 型 | デフォルト | 説明 |\n| :--- | :--- | :--- | :--- |\n| `sample_type` | string | `\"simple_mode\"` | サンプルタイプ：`\"simple_mode\"` または `\"custom_mode\"` |\n\n### 7.3 レスポンス例\n\n```json\n{\n  \"data\": {\n    \"caption\": \"ギター伴奏のある軽快なポップソング\",\n    \"lyrics\": \"[Verse 1]\\n陽の光が顔に...\",\n    \"bpm\": 120,\n    \"key_scale\": \"G Major\",\n    \"time_signature\": \"4\",\n    \"duration\": 180,\n    \"vocal_language\": \"ja\"\n  },\n  \"code\": 200,\n  \"error\": null,\n  \"timestamp\": 1700000000000,\n  \"extra\": null\n}\n```\n\n### 7.4 使用例\n\n```bash\ncurl -X POST http://localhost:8001/create_random_sample \\\n  -H 'Content-Type: application/json' \\\n  -d '{\"sample_type\": \"simple_mode\"}'\n```\n\n---\n\n## 8. 利用可能なモデルの一覧\n\n### 8.1 API 定義\n\n- **URL**：`/v1/models`\n- **メソッド**：`GET`\n\nサーバーにロードされている利用可能なDiTモデルのリストを返します。\n\n### 8.2 レスポンス例\n\n```json\n{\n  \"data\": {\n    \"models\": [\n      {\n        \"name\": \"acestep-v15-turbo\",\n        \"is_default\": true\n      },\n      {\n        \"name\": \"acestep-v15-turbo-shift3\",\n        \"is_default\": false\n      }\n    ],\n    \"default_model\": \"acestep-v15-turbo\"\n  },\n  \"code\": 200,\n  \"error\": null,\n  \"timestamp\": 1700000000000,\n  \"extra\": null\n}\n```\n\n### 8.3 使用例\n\n```bash\ncurl http://localhost:8001/v1/models\n```\n\n---\n\n## 9. サーバー統計\n\n### 9.1 API 定義\n\n- **URL**：`/v1/stats`\n- **メソッド**：`GET`\n\nサーバーの実���統計情報を返します。\n\n### 9.2 レスポンス例\n\n```json\n{\n  \"data\": {\n    \"jobs\": {\n      \"total\": 100,\n      \"queued\": 5,\n      \"running\": 1,\n      \"succeeded\": 90,\n      \"failed\": 4\n    },\n    \"queue_size\": 5,\n    \"queue_maxsize\": 200,\n    \"avg_job_seconds\": 8.5\n  },\n  \"code\": 200,\n  \"error\": null,\n  \"timestamp\": 1700000000000,\n  \"extra\": null\n}\n```\n\n### 9.3 使用例\n\n```bash\ncurl http://localhost:8001/v1/stats\n```\n\n---\n\n## 10. 音声ファイルのダウンロード\n\n### 10.1 API 定義\n\n- **URL**：`/v1/audio`\n- **メソッド**：`GET`\n\nパスで生成されたオーディオファイルをダウンロードします。\n\n### 10.2 リクエストパラメータ\n\n| パラメータ名 | 型 | 説明 |\n| :--- | :--- | :--- |\n| `path` | string | URLエンコードされたオーディオファイルパス |\n\n### 10.3 使用例\n\n```bash\n# タスク結果のURLを使用してダウンロード\ncurl \"http://localhost:8001/v1/audio?path=%2Ftmp%2Fapi_audio%2Fabc123.mp3\" -o output.mp3\n```\n\n---\n\n## 11. ヘルスチェック\n\n### 11.1 API 定義\n\n- **URL**：`/health`\n- **メソッド**：`GET`\n\nサービスのヘルスステータスを返します。\n\n### 11.2 レスポンス例\n\n```json\n{\n  \"data\": {\n    \"status\": \"ok\",\n    \"service\": \"ACE-Step API\",\n    \"version\": \"1.0\"\n  },\n  \"code\": 200,\n  \"error\": null,\n  \"timestamp\": 1700000000000,\n  \"extra\": null\n}\n```\n\n---\n\n## 12. 環境変数\n\nAPIサーバーは環境変数で設定できます：\n\n### サーバー設定\n\n| 変数 | デフォルト | 説明 |\n| :--- | :--- | :--- |\n| `ACESTEP_API_HOST` | `127.0.0.1` | サーバーバインドホスト |\n| `ACESTEP_API_PORT` | `8001` | サーバーバインドポート |\n| `ACESTEP_API_KEY` | （空）| API認証キー（空の場合は認証無効）|\n| `ACESTEP_API_WORKERS` | `1` | APIワーカースレッド数 |\n\n### モデル設定\n\n| 変数 | デフォルト | 説明 |\n| :--- | :--- | :--- |\n| `ACESTEP_CONFIG_PATH` | `acestep-v15-turbo` | プライマリDiTモデルパス |\n| `ACESTEP_CONFIG_PATH2` | （空）| セカンダリDiTモデルパス（オプション）|\n| `ACESTEP_CONFIG_PATH3` | （空）| 3番目のDiTモデルパス（オプション）|\n| `ACESTEP_DEVICE` | `auto` | モデルロードデバイス |\n| `ACESTEP_USE_FLASH_ATTENTION` | `true` | flash attentionを有効化 |\n| `ACESTEP_OFFLOAD_TO_CPU` | `false` | アイドル時にモデルをCPUにオフロード |\n| `ACESTEP_OFFLOAD_DIT_TO_CPU` | `false` | DiTを特にCPUにオフロード |\n\n### LM設定\n\n| 変数 | デフォルト | 説明 |\n| :--- | :--- | :--- |\n| `ACESTEP_INIT_LLM` | auto | 起動時にLMを初期化するかどうか（autoはGPUに基づいて自動決定）|\n| `ACESTEP_LM_MODEL_PATH` | `acestep-5Hz-lm-0.6B` | デフォルト5Hz LMモデル |\n| `ACESTEP_LM_BACKEND` | `vllm` | LMバックエンド（vllmまたはpt）|\n| `ACESTEP_LM_DEVICE` | （ACESTEP_DEVICEと同じ）| LMデバイス |\n| `ACESTEP_LM_OFFLOAD_TO_CPU` | `false` | LMをCPUにオフロード |\n\n### キュー設定\n\n| 変数 | デフォルト | 説明 |\n| :--- | :--- | :--- |\n| `ACESTEP_QUEUE_MAXSIZE` | `200` | 最大キューサイズ |\n| `ACESTEP_QUEUE_WORKERS` | `1` | キューワーカー数 |\n| `ACESTEP_AVG_JOB_SECONDS` | `5.0` | 初期平均ジョブ時間推定 |\n| `ACESTEP_AVG_WINDOW` | `50` | 平均ジョブ時間計算ウィンドウ |\n\n### キャッシュ設定\n\n| 変数 | デフォルト | 説明 |\n| :--- | :--- | :--- |\n| `ACESTEP_TMPDIR` | `.cache/acestep/tmp` | 一時ファイルディレクトリ |\n| `TRITON_CACHE_DIR` | `.cache/acestep/triton` | Tritonキャッシュディレクトリ |\n| `TORCHINDUCTOR_CACHE_DIR` | `.cache/acestep/torchinductor` | TorchInductorキャッシュディレクトリ |\n\n---\n\n## エラー処理\n\n**HTTPステータスコード**：\n\n- `200`：成功\n- `400`：無効なリクエスト（不正なJSON、フィールドの欠落）\n- `401`：未認証（APIキーがないか無効）\n- `404`：リソースが見つからない\n- `415`：サポートされていないContent-Type\n- `429`：サーバービジー（キューが満杯）\n- `500`：内部サーバーエラー\n\n**エラーレスポンス形式**：\n\n```json\n{\n  \"detail\": \"問題を説明するエラーメッセージ\"\n}\n```\n\n---\n\n## ベストプラクティス\n\n1. **`thinking=true` を使用** してLM強化生成で最高品質の結果を得る。\n\n2. **`sample_query`/`description` を使用** して自然言語の説明から素早く生成。\n\n3. **`use_format=true` を使用** してcaption/lyricsがあるがLMに強化してもらいたい場合。\n\n4. **タスクステータスの一括クエリ** `/query_result` エンドポイントを使用して複数のタスクを一度にクエリ。\n\n5. **`/v1/stats` を確認** してサーバーの負荷と平均ジョブ時間を把握。\n\n6. **マルチモデルサポートを使用** するには `ACESTEP_CONFIG_PATH2` と `ACESTEP_CONFIG_PATH3` 環境変数を設定し、`model` パラメータで選択。\n\n7. **本番環境** では `ACESTEP_API_KEY` を設定して認証を有効にし、APIを保護。\n\n8. **低VRAM環境** では `ACESTEP_OFFLOAD_TO_CPU=true` を有効にして、より長いオーディオ生成をサポート。\n"
  },
  {
    "path": "docs/ja/GPU_COMPATIBILITY.md",
    "content": "# GPU 互換性ガイド\n\nACE-Step 1.5 は GPU の VRAM に自動的に適応し、生成時間の制限、使用可能な LM モデル、オフロード戦略、UI デフォルト設定を調整します。システムは起動時に GPU メモリを検出し、最適な設定を自動構成します。\n\n## GPU ティア構成\n\n| VRAM | ティア | LM モデル | 推奨 LM | バックエンド | 最大時間 (LM有 / LM無) | 最大バッチ (LM有 / LM無) | オフロード | 量子化 |\n|------|--------|-----------|---------|-------------|------------------------|--------------------------|------------|--------|\n| ≤4GB | Tier 1 | なし | — | pt | 4分 / 6分 | 1 / 1 | CPU + DiT | INT8 |\n| 4-6GB | Tier 2 | なし | — | pt | 8分 / 10分 | 1 / 1 | CPU + DiT | INT8 |\n| 6-8GB | Tier 3 | 0.6B | 0.6B | pt | 8分 / 10分 | 2 / 2 | CPU + DiT | INT8 |\n| 8-12GB | Tier 4 | 0.6B | 0.6B | vllm | 8分 / 10分 | 2 / 4 | CPU + DiT | INT8 |\n| 12-16GB | Tier 5 | 0.6B, 1.7B | 1.7B | vllm | 8分 / 10分 | 4 / 4 | CPU | INT8 |\n| 16-20GB | Tier 6a | 0.6B, 1.7B | 1.7B | vllm | 8分 / 10分 | 4 / 8 | CPU | INT8 |\n| 20-24GB | Tier 6b | 0.6B, 1.7B, 4B | 1.7B | vllm | 8分 / 8分 | 8 / 8 | なし | なし |\n| ≥24GB | 無制限 | 全モデル (0.6B, 1.7B, 4B) | 4B | vllm | 10分 / 10分 | 8 / 8 | なし | なし |\n\n### 列の説明\n\n- **LM モデル**: このティアでロードできる 5Hz 言語モデルのサイズ\n- **推奨 LM**: UI でこのティアにデフォルト選択される LM モデル\n- **バックエンド**: LM 推論バックエンド（`vllm` は十分な VRAM を持つ NVIDIA GPU 向け、`pt` は PyTorch フォールバック、`mlx` は Apple Silicon 向け）\n- **オフロード**:\n  - **CPU + DiT**: すべてのモデル（DiT、VAE、テキストエンコーダー）を未使用時に CPU にオフロード；DiT もステップ間でオフロード\n  - **CPU**: VAE とテキストエンコーダーを CPU にオフロード；DiT は GPU に保持\n  - **なし**: すべてのモデルを GPU に保持\n- **量子化**: VRAM 使用量を削減するため、デフォルトで INT8 重み量子化を有効にするかどうか\n\n## アダプティブ UI デフォルト\n\nGradio UI は検出された GPU ティアに基づいて自動的に設定されます：\n\n- **LM 初期化チェックボックス**: LM をサポートするティア（Tier 3+）ではデフォルトでチェック、Tier 1-2 ではチェックなし・無効\n- **LM モデルパス**: ティアの推奨モデルが自動入力；ドロップダウンには互換モデルのみ表示\n- **バックエンドドロップダウン**: Tier 1-3 では `pt`/`mlx` に制限（vllm KV キャッシュがメモリを消費しすぎる）；Tier 4+ ではすべてのバックエンドが利用可能\n- **CPU オフロード / DiT オフロード**: 低ティアではデフォルトで有効、高ティアでは無効\n- **量子化**: Tier 1-6a ではデフォルトで有効、Tier 6b+ では無効（十分な VRAM）\n- **モデルコンパイル**: すべてのティアでデフォルトで有効（量子化に必要）\n\n互換性のないオプションを手動で選択した場合（例：6GB GPU で vllm を使用しようとした場合）、システムは警告を表示し、互換性のある設定に自動フォールバックします。\n\n## ランタイム安全機能\n\n- **VRAM ガード**: 各推論前に VRAM 要件を推定し、必要に応じてバッチサイズを自動削減\n- **アダプティブ VAE デコード**: 3 段階フォールバック：GPU タイルデコード → GPU デコード+CPU オフロード → 完全 CPU デコード\n- **自動チャンクサイズ**: VAE デコードチャンクサイズが利用可能な空き VRAM に適応（64/128/256/512/1024/1536）\n- **時間/バッチクランプ**: ティアの制限を超える値を要求した場合、警告とともに自動調整\n\n## 注意事項\n\n- **デフォルト設定** は検出された GPU メモリに基づいて自動構成されます\n- **LM モード** は Chain-of-Thought 生成とオーディオ理解に使用される言語モデルを指します\n- **Flash Attention** は自動検出され、利用可能な場合に有効化されます\n- **制約付きデコード**: LM が初期化されると、LM の時間生成も GPU ティアの最大時間制限内に制約され、CoT 生成時のメモリ不足エラーを防ぎます\n- VRAM ≤6GB の GPU（Tier 1-2）では、DiT モデル用のメモリを確保するため、デフォルトで LM 初期化が無効になります\n- コマンドライン引数または Gradio UI で設定を手動で上書きできます\n\n> **コミュニティ貢献歓迎**: 上記の GPU ティア構成は一般的なハードウェアでのテストに基づいています。お使いのデバイスの実際のパフォーマンスがこれらのパラメータと異なる場合（例：より長い時間やより大きなバッチサイズを処理できる）、より徹底的なテストを行い、`acestep/gpu_config.py` の構成を最適化する PR を提出することを歓迎します。\n\n## メモリ最適化のヒント\n\n1. **超低 VRAM (≤6GB)**: LM 初期化なしの DiT のみモードを使用。INT8 量子化と完全 CPU オフロードが必須。VAE デコードは自動的に CPU にフォールバックする場合があります。\n2. **低 VRAM (6-8GB)**: `pt` バックエンドで 0.6B LM モデルを使用可能。オフロードを有効に保ちます。\n3. **中 VRAM (8-16GB)**: 0.6B または 1.7B LM モデルを使用。Tier 4+ では `vllm` バックエンドが良好に動作します。\n4. **高 VRAM (16-24GB)**: より大きな LM モデル（1.7B 推奨）を有効化。20GB+ では量子化はオプションになります。\n5. **超高 VRAM (≥24GB)**: すべてのモデルがオフロードや量子化なしで動作。最高品質のため 4B LM を使用。\n\n## デバッグモード：異なる GPU 構成のシミュレーション\n\nテストと開発のため、`MAX_CUDA_VRAM` 環境変数を使用して異なる GPU メモリサイズをシミュレートできます：\n\n```bash\n# 4GB GPU (Tier 1) をシミュレート\nMAX_CUDA_VRAM=4 uv run acestep\n\n# 6GB GPU (Tier 2) をシミュレート\nMAX_CUDA_VRAM=6 uv run acestep\n\n# 8GB GPU (Tier 4) をシミュレート\nMAX_CUDA_VRAM=8 uv run acestep\n\n# 12GB GPU (Tier 5) をシミュレート\nMAX_CUDA_VRAM=12 uv run acestep\n\n# 16GB GPU (Tier 6a) をシミュレート\nMAX_CUDA_VRAM=16 uv run acestep\n```\n\n`MAX_CUDA_VRAM` を設定すると、システムは `torch.cuda.set_per_process_memory_fraction()` を呼び出して VRAM のハードキャップを強制し、ハイエンド GPU でもリアルなシミュレーションを実現します。\n\n### 自動ティアテスト\n\nUI で各ティアを手動テストする代わりに、`profile_inference.py` の `tier-test` モードを使用できます：\n\n```bash\n# すべてのティアを自動テスト\npython profile_inference.py --mode tier-test\n\n# 特定のティアをテスト\npython profile_inference.py --mode tier-test --tiers 6 8 16\n\n# LM を有効にしてテスト（サポートされるティアで）\npython profile_inference.py --mode tier-test --tier-with-lm\n\n# 高速テスト（非量子化ティアで torch.compile をスキップ）\npython profile_inference.py --mode tier-test --tier-skip-compile\n```\n\nプロファイリングツールの完全なドキュメントは [BENCHMARK.md](BENCHMARK.md) を参照してください。\n\n用途：\n- ハイエンドハードウェアで GPU ティア構成をテスト\n- 各ティアの警告と制限が正しく機能することを確認\n- `acestep/gpu_config.py` 変更後の自動回帰テスト\n- CI/CD VRAM 互換性検証\n\n### 境界テスト（最小ティアの特定）\n\n`--tier-boundary` を使用すると、INT8 量子化と CPU オフロードを安全に無効化できる最小 VRAM ティアを実験的に特定できます。各ティアに対して最大3つの構成でテストします：\n\n1. **default** — ティアの標準設定（量子化 + オフロードを設定通りに使用）\n2. **no-quant** — オフロード設定はそのまま、量子化を無効化\n3. **no-offload** — 量子化なし、CPU オフロードなし（すべてのモデルを GPU に保持）\n\n```bash\n# すべてのティアで境界テストを実行\npython profile_inference.py --mode tier-test --tier-boundary\n\n# 特定のティアの境界テスト\npython profile_inference.py --mode tier-test --tier-boundary --tiers 8 12 16 20 24\n\n# LM を有効にした境界テスト（サポートされるティアで）\npython profile_inference.py --mode tier-test --tier-boundary --tier-with-lm\n\n# 結果を JSON に保存\npython profile_inference.py --mode tier-test --tier-boundary --benchmark-output boundary_results.json\n```\n\n> **注意：** 境界テスト結果は経験的なものであり、DiT モデルバリアント（turbo vs base）、LM の有効化状態、生成時間、flash attention の利用可否によって異なる場合があります。\n\n### バッチサイズ境界テスト\n\n`--tier-batch-boundary` を使用して、バッチサイズ 1、2、4、8 を段階的にテストし、各ティアの最大安全バッチサイズを見つけます：\n\n```bash\n# LM 有効でバッチ境界テストを実行\npython profile_inference.py --mode tier-test --tier-batch-boundary --tier-with-lm\n\n# 特定のティアをテスト\npython profile_inference.py --mode tier-test --tier-batch-boundary --tier-with-lm --tiers 8 12 16 24\n```\n\nLM あり/なしの両方の構成をテストし、各ティアの最大成功バッチサイズを報告します。\n"
  },
  {
    "path": "docs/ja/GRADIO_GUIDE.md",
    "content": "# ACE-Step Gradio デモユーザーガイド\n\n**Language / 语言 / 言語:** [English](../en/GRADIO_GUIDE.md) | [中文](../zh/GRADIO_GUIDE.md) | [日本語](GRADIO_GUIDE.md)\n\n---\n\n本ガイドはACE-Step Gradio Webインターフェースを使用した音楽生成の包括的なドキュメントを提供し、すべての機能と設定を含みます。\n\n## 目次\n\n- [はじめに](#はじめに)\n- [サービス設定](#サービス設定)\n- [生成モード](#生成モード)\n- [入力パラメータ](#入力パラメータ)\n- [高度な設定](#高度な設定)\n- [結果セクション](#結果セクション)\n- [LoRAトレーニング](#loraトレーニング)\n- [ヒントとベストプラクティス](#ヒントとベストプラクティス)\n\n---\n\n## はじめに\n\n### デモの起動\n\n```bash\n# 基本的な起動\npython app.py\n\n# 事前初期化付き\npython app.py --config acestep-v15-turbo --init-llm\n\n# 特定のポートで\npython app.py --port 7860\n```\n\n### インターフェース概要\n\nGradioインターフェースのレイアウト：\n\n1. **設定**（折りたたみアコーディオン）- サービス設定、DiT/LMパラメータ、出力オプション\n2. **生成タブ** - メインワークスペース。上部に**生成モード**ラジオセレクター：\n   - Turbo/SFTモデル：Simple、Custom、Remix、Repaint\n   - Baseモデル：Simple、Custom、Remix、Repaint、Extract、Lego、Complete\n3. **結果セクション** - 生成されたオーディオの再生、スコアリング、バッチナビゲーション\n4. **トレーニングタブ** - データセットビルダーとLoRAトレーニング\n\n---\n\n## サービス設定\n\n### モデル選択\n\n| 設定 | 説明 |\n|---------|-------------|\n| **チェックポイントファイル** | トレーニング済みモデルチェックポイントを選択（利用可能な場合）|\n| **メインモデルパス** | DiTモデル設定を選択（例：`acestep-v15-turbo`、`acestep-v15-turbo-shift3`）|\n| **デバイス** | 処理デバイス：`auto`（推奨）、`cuda`、または `cpu` |\n\n### 5Hz LM設定\n\n| 設定 | 説明 |\n|---------|-------------|\n| **5Hz LMモデルパス** | 言語モデルを選択。**利用可能なモデルはGPUティアに基づいて自動フィルタリング**されます — 例：6-8GB GPUでは0.6Bのみ、24GB+ GPUではすべてのサイズ（0.6B、1.7B、4B）が表示されます。|\n| **5Hz LMバックエンド** | `vllm`（より高速、VRAM ≥8GBのNVIDIA GPU推奨）、`pt`（PyTorch、ユニバーサルフォールバック）、または `mlx`（Apple Silicon）。**VRAM <8GBのGPUでは `pt`/`mlx` に制限**されます（vllmのKVキャッシュがメモリを消費しすぎるため）。|\n| **5Hz LMを初期化** | 初期化時にLMを読み込むためにチェック（thinkingモードに必要）。**VRAM ≤6GBのGPU（Tier 1-2）ではデフォルトでチェックなし・無効。**|\n\n> **アダプティブデフォルト**: すべてのLM設定はGPUのVRAMティアに基づいて自動構成されます。推奨LMモデル、バックエンド、初期化状態は最適なパフォーマンスに事前設定されています。手動で上書きできますが、GPUと互換性のない選択をした場合、システムが警告を表示します。\n\n### パフォーマンスオプション\n\n| 設定 | 説明 |\n|---------|-------------|\n| **Flash Attentionを使用** | より高速な推論のために有効化（flash_attnパッケージが必要）|\n| **CPUにオフロード** | アイドル時にモデルをCPUにオフロードしてGPUメモリを節約。**VRAM <20GBのGPUでデフォルト自動有効。**|\n| **DiTをCPUにオフロード** | DiTモデルを特にCPUにオフロード。**VRAM <12GBのGPUでデフォルト自動有効。**|\n| **INT8量子化** | INT8重み量子化でモデルのVRAM使用量を削減。**VRAM <20GBのGPUでデフォルト自動有効。**|\n| **モデルコンパイル** | 最適化推論のため `torch.compile` を有効化。**すべてのティアでデフォルト有効**（量子化がアクティブな場合に必要）。|\n\n> **ティア対応設定**: オフロード、量子化、コンパイルオプションはGPUティアに基づいて自動設定されます。完全なティアテーブルは [GPU_COMPATIBILITY.md](../ja/GPU_COMPATIBILITY.md) を参照してください。\n\n### LoRAアダプター\n\n| 設定 | 説明 |\n|---------|-------------|\n| **LoRAパス** | トレーニング済みLoRAアダプターディレクトリへのパス |\n| **LoRAを読み込み** | 指定されたLoRAアダプターを読み込み |\n| **アンロード** | 現在読み込まれているLoRAを削除 |\n| **LoRAを使用** | 推論用の読み込まれたLoRAを有効化/無効化 |\n\n> **⚠️ 注意：** PEFTとTorchAO間の互換性の問題により、量子化されたモデルにLoRAアダプターを読み込むことはできません。LoRAを使用する必要がある場合は、アダプターを読み込む前に **INT8量子化** を **None** に設定してください。\n\n### 初期化\n\n**サービスを初期化** をクリックしてモデルを読み込みます。ステータスボックスに以下を含む進捗と確認が表示されます：\n- 検出されたGPUティアとVRAM\n- 最大許容時間とバッチサイズ（LMが初期化されたかどうかに基づいて動的に調整）\n- 自動修正された互換性のない設定に関する警告\n\n初期化後、**オーディオ時間** と **バッチサイズ** スライダーはティアの制限を反映するように自動更新されます。\n\n---\n\n## 生成モード\n\n生成タブ上部の**生成モード**ラジオセレクターでワークフローを決定します。TurboとSFTモデルは4つのモード、Baseモデルはさらに3つのモードを追加で提供します。\n\n### Simpleモード\n\n迅速な自然言語ベースの音楽生成用に設計されています。\n\n**使用方法：**\n1. 生成モードで **Simple** を選択\n2. 「曲の説明」フィールドに自然言語の説明を入力\n3. ボーカルが不要な場合は「インストゥルメンタル」をオプションでチェック\n4. オプションで希望するボーカル言語を選択\n5. **サンプルを作成** をクリックしてcaption、歌詞、メタデータを生成\n6. 展開されたセクションで生成されたコンテンツを確認\n7. **音楽を生成** をクリックしてオーディオを作成\n\n**説明の例：**\n- 「静かな夜のための柔らかいベンガルのラブソング」\n- 「重いベースドロップのアップビートなエレクトロニックダンスミュージック」\n- 「アコースティックギターのメランコリックなインディーフォーク」\n- 「煙たいバーで演奏するジャズトリオ」\n\n**ランダムサンプル：** 🎲 ボタンをクリックしてランダムな例の説明を読み込みます。\n\n### Customモード\n\nすべての生成パラメータの完全な制御を提供します（text2music）。\n\n**使用方法：**\n1. 生成モードで **Custom** を選択\n2. Captionと歌詞フィールドを手動で入力\n3. オプションで参照オーディオをアップロードしてスタイルガイダンス\n4. オプションのメタデータを設定（BPM、キー、Durationなど）\n5. オプションで **フォーマット** をクリックしてLMを使用して入力を強化\n6. 必要に応じて高度な設定を構成\n7. **音楽を生成** をクリックしてオーディオを作成\n\n### Remixモード\n\n既存のオーディオのメロディ構造を維持しながらスタイルを変更。\n\n**使用方法：**\n1. 生成モードで **Remix** を選択\n2. ソースオーディオをアップロード（リミックスする曲）\n3. ターゲットスタイルを説明するCaptionを記述\n4. オプションで歌詞を修正\n5. **Remix強度**（0.0-1.0）を調整：高い = 元の構造に近い\n6. **音楽を生成** をクリック\n\n**ユースケース：** カバーバージョンの作成、スタイル転送、曲のバリエーション生成。\n\n### Repaintモード\n\nオーディオの特定の時間セグメントを再生成し、残りは維持。\n\n**使用方法：**\n1. 生成モードで **Repaint** を選択\n2. ソースオーディオをアップロード\n3. **リペイント開始**と**リペイント終了**を設定（秒；-1でファイル終端）\n4. リペイントセクションの希望するコンテンツを説明するCaptionを記述\n5. **音楽を生成** をクリック\n\n**ユースケース：** 問題のあるセクションの修正、セグメント内の歌詞変更、曲の延長。\n\n### Extractモード（Baseモデルのみ）\n\nミックスオーディオから特定の楽器トラックを抽出/分離。\n\n**使用方法：**\n1. 生成モードで **Extract** を選択\n2. ソースオーディオをアップロード\n3. ドロップダウンから抽出する**トラック名**を選択\n4. **音楽を生成** をクリック\n\n**利用可能なトラック：** vocals、backing_vocals、drums、bass、guitar、keyboard、percussion、strings、synth、fx、brass、woodwinds\n\n### Legoモード（Baseモデルのみ）\n\n既存のオーディオに新しい楽器トラックを追加。\n\n**使用方法：**\n1. 生成モードで **Lego** を選択\n2. ソースオーディオをアップロード\n3. ドロップダウンから追加する**トラック名**を選択\n4. トラック特性を説明するCaptionを記述\n5. **音楽を生成** をクリック\n\n### Completeモード（Baseモデルのみ）\n\n指定された楽器で部分的なトラックを完成（自動アレンジ）。\n\n**使用方法：**\n1. 生成モードで **Complete** を選択\n2. ソースオーディオをアップロード\n3. 追加する複数の**トラック名**を選択\n4. 希望するスタイルを説明するCaptionを記述\n5. **音楽を生成** をクリック\n\n---\n\n## 入力パラメータ\n\n### オーディオ入力\n\n| フィールド | 説明 |\n|-------|-------------|\n| **参照オーディオ** | スタイル/音色ガイダンス用のオプションオーディオ（Customモードで表示） |\n| **ソースオーディオ** | Remix、Repaint、Extract、Lego、Completeモードに必須 |\n| **コードに変換** | ソースオーディオから5Hzセマンティックコードを抽出 |\n\n#### LMコードヒント（Customモード）\n\n事前計算されたオーディオセマンティックコードをここに貼り付けて生成をガイドできます。**トランスクライブ** ボタンを使用してコードを分析しメタデータを抽出します。これはソースオーディオをアップロードせずにメロディ構造を制御するための高度な機能です。\n\n### 音楽キャプション\n\n希望する音楽のテキスト説明。以下について具体的に：\n- ジャンルとスタイル\n- 楽器\n- ムードと雰囲気\n- テンポ感（BPMを指定しない場合）\n\n**例：** 「エレキギター、力強いドラム、キャッチーなシンセフックのアップビートなポップロック」\n\n🎲 をクリックしてランダムな例のcaptionを読み込みます。\n\n### 歌詞\n\n構造タグ付きの歌詞を入力：\n\n```\n[Verse 1]\n今日街を歩いていて\n君が言っていた言葉を思い出していた\n\n[Chorus]\n前に進んでいく、強くいる\nここが僕の居場所\n\n[Verse 2]\n...\n```\n\n**インストゥルメンタルチェックボックス：** これをチェックすると、歌詞の内容に関係なくインストゥルメンタル音楽を生成します。\n\n**ボーカル言語：** ボーカルの言語を選択。自動検出またはインストゥルメンタルトラックには「unknown」を使用。\n\n**フォーマットボタン：** クリックして5Hz LMを使用してcaptionと歌詞を強化。\n\n### オプションパラメータ\n\n| パラメータ | デフォルト | 説明 |\n|-----------|---------|-------------|\n| **BPM** | 自動 | 1分あたりのビート数（30-300）|\n| **キースケール** | 自動 | 音楽キー（例：「C Major」、「Am」、「F# minor」）|\n| **拍子記号** | 自動 | 拍子記号：2（2/4）、3（3/4）、4（4/4）、6（6/8）|\n| **オーディオ長** | 自動/-1 | 目標長（秒）（10-600）。-1で自動 |\n| **バッチサイズ** | 2 | 生成するオーディオバリエーションの数（1-8）|\n\n---\n\n## 高度な設定\n\n### DiTパラメータ\n\n| パラメータ | デフォルト | 説明 |\n|-----------|---------|-------------|\n| **推論ステップ** | 8 | デノイズステップ。Turbo：1-20、Base：1-200 |\n| **ガイダンススケール** | 7.0 | CFG強度（baseモデルのみ）。高い = プロンプトにより従う |\n| **シード** | -1 | ランダムシード。バッチにはカンマ区切りの値を使用 |\n| **ランダムシード** | ✓ | チェック時にランダムシードを生成 |\n| **オーディオ形式** | mp3 | 出力形式：mp3、flac |\n| **シフト** | 3.0 | タイムステップシフト係数（1.0-5.0）。turboには3.0推奨 |\n| **推論方法** | ode | ode（Euler、より高速）またはsde（確率的）|\n| **カスタムタイムステップ** | - | タイムステップをオーバーライド（例：「0.97,0.76,0.615,0.5,0.395,0.28,0.18,0.085,0」）|\n\n### Baseモデルのみのパラメータ\n\n| パラメータ | デフォルト | 説明 |\n|-----------|---------|-------------|\n| **ADGを使用** | ✗ | より良い品質のために適応デュアルガイダンスを有効化 |\n| **CFG区間開始** | 0.0 | CFGを適用し始めるタイミング（0.0-1.0）|\n| **CFG区間終了** | 1.0 | CFGの適用を停止するタイミング（0.0-1.0）|\n\n### LMパラメータ\n\n| パラメータ | デフォルト | 説明 |\n|-----------|---------|-------------|\n| **LM温度** | 0.85 | サンプリング温度（0.0-2.0）。高い = より創造的 |\n| **LM CFGスケール** | 2.0 | LMガイダンス強度（1.0-3.0）|\n| **LM Top-K** | 0 | Top-Kサンプリング。0で無効 |\n| **LM Top-P** | 0.9 | 核サンプリング（0.0-1.0）|\n| **LMネガティブプロンプト** | \"NO USER INPUT\" | CFG用のネガティブプロンプト |\n\n### CoT（思考の連鎖）オプション\n\n| オプション | デフォルト | 説明 |\n|--------|---------|-------------|\n| **CoT Metas** | ✓ | LM推論でメタデータを生成 |\n| **CoT Language** | ✓ | LMでボーカル言語を検出 |\n| **制約付きデコーディングデバッグ** | ✗ | デバッグログを有効化 |\n\n### 生成オプション\n\n| オプション | デフォルト | 説明 |\n|--------|---------|-------------|\n| **LMコード強度** | 1.0 | LMコードが生成に与える影響の強さ（0.0-1.0）|\n| **自動スコア** | ✗ | 品質スコアを自動計算 |\n| **自動LRC** | ✗ | 歌詞タイムスタンプを自動生成 |\n| **LMバッチチャンクサイズ** | 8 | LMバッチあたりの最大アイテム数（GPUメモリ）|\n\n### メイン生成コントロール\n\n| コントロール | 説明 |\n|---------|-------------|\n| **Think** | コード生成とメタデータ用の5Hz LMを有効化 |\n| **ParallelThinking** | 並列LMバッチ処理を有効化 |\n| **CaptionRewrite** | LMに入力captionを強化させる |\n| **AutoGen** | 完了後に次のバッチを自動開始 |\n\n---\n\n## 結果セクション\n\n### 生成されたオーディオ\n\nバッチサイズに基づいて最大8つのオーディオサンプルが表示されます。各サンプルには以下が含まれます：\n\n- **オーディオプレーヤー** - 生成されたオーディオの再生、一時停止、ダウンロード\n- **ソースに送信** - このオーディオをソースオーディオ入力に送信してさらに処理\n- **保存** - オーディオとメタデータをJSONファイルに保存\n- **スコア** - パープレキシティベースの品質スコアを計算\n- **LRC** - 歌詞タイムスタンプを生成（LRC形式）\n\n### 詳細アコーディオン\n\n「スコア & LRC & LMコード」をクリックして展開し、以下を表示：\n- **LMコード** - このサンプルの5Hzセマンティックコード\n- **品質スコア** - パープレキシティベースの品質メトリック\n- **歌詞タイムスタンプ** - LRC形式のタイミングデータ\n\n### バッチナビゲーション\n\n| コントロール | 説明 |\n|---------|-------------|\n| **◀ 前へ** | 前のバッチを表示 |\n| **バッチインジケーター** | 現在のバッチ位置を表示（例：「バッチ 1 / 3」）|\n| **次バッチステータス** | バックグラウンド生成の進捗を表示 |\n| **次へ ▶** | 次のバッチを表示（AutoGenがオンの場合は生成をトリガー）|\n\n### パラメータの復元\n\n**これらの設定をUIに適用** をクリックして、現在のバッチからすべての生成パラメータを入力フィールドに復元。良い結果を反復するのに便利。\n\n### バッチ結果\n\n「バッチ結果と生成詳細」アコーディオンには以下が含まれます：\n- **すべての生成ファイル** - すべてのバッチからすべてのファイルをダウンロード\n- **生成詳細** - 生成プロセスに関する詳細情報\n\n---\n\n## LoRAトレーニング\n\nLoRAトレーニングタブはカスタムLoRAアダプターを作成するためのツールを提供します。\n\n> 📖 **包括的なステップバイステップガイド**（データ準備、アノテーション、前処理、訓練、エクスポート）については、[LoRA トレーニングチュートリアル](./LoRA_Training_Tutorial.md)を参照してください。\n\n### データセットビルダータブ\n\n#### ステップ1：読み込みまたはスキャン\n\n**オプションA：既存のデータセットを読み込み**\n1. 以前保存したデータセットJSONへのパスを入力\n2. **読み込み** をクリック\n\n**オプションB：新しいディレクトリをスキャン**\n1. オーディオフォルダへのパスを入力\n2. **スキャン** をクリックしてオーディオファイルを検索（wav、mp3、flac、ogg、opus）\n\n#### ステップ2：データセットの設定\n\n| 設定 | 説明 |\n|---------|-------------|\n| **データセット名** | データセットの名前 |\n| **すべてインストゥルメンタル** | すべてのトラックにボーカルがない場合にチェック |\n| **カスタムアクティベーションタグ** | このLoRAのスタイルをアクティブにするユニークなタグ |\n| **タグ位置** | タグを配置する場所：前に追加、後に追加、またはcaptionを置換 |\n\n#### ステップ3：自動ラベル\n\n**すべて自動ラベル** をクリックしてすべてのオーディオファイルのメタデータを生成：\n- Caption（音楽の説明）\n- BPM\n- キー\n- 拍子記号\n\n**Metasをスキップ** オプションはLLMラベリングをスキップしてN/A値を使用します。\n\n#### ステップ4：プレビューと編集\n\nスライダーを使用してサンプルを選択し、手動で編集：\n- Caption\n- 歌詞\n- BPM、キー、拍子記号\n- 言語\n- インストゥルメンタルフラグ\n\n**変更を保存** をクリックしてサンプルを更新。\n\n#### ステップ5：データセットを保存\n\n保存パスを入力し、**データセットを保存** をクリックしてJSONとしてエクスポート。\n\n#### ステップ6：前処理\n\n高速トレーニングのためにデータセットを事前計算テンソルに変換：\n1. オプションで既存のデータセットJSONを読み込み\n2. テンソル出力ディレクトリを設定\n3. **前処理** をクリック\n\nこれによりオーディオがVAE潜在変数にエンコードされ、テキストが埋め込みにエンコードされ、条件エンコーダーが実行されます。\n\n### LoRAトレーニングタブ\n\n#### データセット選択\n\n前処理されたテンソルディレクトリへのパスを入力し、**データセットを読み込み** をクリック。\n\n#### LoRA設定\n\n| 設定 | デフォルト | 説明 |\n|---------|---------|-------------|\n| **LoRAランク (r)** | 64 | LoRAの容量。高い = より多くの容量、より多くのメモリ |\n| **LoRA Alpha** | 128 | スケーリング係数（通常はランクの2倍）|\n| **LoRA Dropout** | 0.1 | 正則化のためのドロップアウト率 |\n\n#### トレーニングパラメータ\n\n| 設定 | デフォルト | 説明 |\n|---------|---------|-------------|\n| **学習率** | 1e-4 | 最適化学習率 |\n| **最大エポック** | 500 | 最大トレーニングエポック |\n| **バッチサイズ** | 1 | トレーニングバッチサイズ |\n| **勾配累積** | 1 | 有効バッチ = batch_size × accumulation |\n| **Nエポックごとに保存** | 200 | チェックポイント保存頻度 |\n| **シフト** | 3.0 | turboモデルのタイムステップシフト |\n| **シード** | 42 | 再現性のためのランダムシード |\n\n#### トレーニングコントロール\n\n- **トレーニング開始** - トレーニングプロセスを開始\n- **トレーニング停止** - トレーニングを中断\n- **トレーニング進捗** - 現在のエポックとロスを表示\n- **トレーニングログ** - 詳細なトレーニング出力\n- **トレーニングロスプロット** - 視覚的なロス曲線\n\n#### LoRAのエクスポート\n\nトレーニング後、最終アダプターをエクスポート：\n1. エクスポートパスを入力\n2. **LoRAをエクスポート** をクリック\n\n---\n\n## ヒントとベストプラクティス\n\n### 最高品質のために\n\n1. **thinkingモードを使用** - LM強化生成のために「Think」チェックボックスを有効に保つ\n2. **captionを具体的に** - ジャンル、楽器、ムード、スタイルの詳細を含める\n3. **LMにメタデータを検出させる** - 自動検出のためにBPM/キー/Durationを空のままにする\n4. **バッチ生成を使用** - 2-4のバリエーションを生成し、最良のものを選ぶ\n\n### より高速な生成のために\n\n1. **turboモデルを使用** - `acestep-v15-turbo` または `acestep-v15-turbo-shift3` を選択\n2. **推論ステップを8に保つ** - turboに最適なデフォルト\n3. **バッチサイズを減らす** - 迅速な結果が必要な場合はバッチサイズを下げる\n4. **AutoGenを無効化** - バッチ生成の手動制御\n\n### 一貫した結果のために\n\n1. **特定のシードを設定** - 「ランダムシード」のチェックを外してシード値を入力\n2. **良い結果を保存** - 再現のためにパラメータをエクスポートするために「保存」を使用\n3. **「これらの設定を適用」を使用** - 良いバッチからパラメータを復元\n\n### 長尺音楽のために\n\n1. **明示的なdurationを設定** - 秒単位でdurationを指定\n2. **repaintタスクを使用** - 初期生成後に問題のあるセクションを修正\n3. **生成をチェーン** - 以前の結果の上に構築するために「ソースに送信」を使用\n\n### スタイルの一貫性のために\n\n1. **LoRAをトレーニング** - あなたのスタイル用のカスタムアダプターを作成\n2. **参照オーディオを使用** - オーディオアップロードでスタイル参照をアップロード\n3. **一貫したcaptionを使用** - 類似の説明的な言語を維持\n\n### トラブルシューティング\n\n**オーディオが生成されない：**\n- モデルが初期化されていることを確認（緑のステータスメッセージ）\n- thinkingモードを使用している場合は5Hz LMが初期化されていることを確認\n- エラーメッセージのステータス出力を確認\n\n**結果の品質が悪い：**\n- 推論ステップを増やす（baseモデルの場合）\n- ガイダンススケールを調整\n- 異なるシードを試す\n- captionをより具体的にする\n\n**メモリ不足（OOM）：**\n- システムは自動VRAMガード（バッチ自動削減）とアダプティブVAEデコード（CPUフォールバック）を含みます。それでもOOMが発生する場合：\n- 手動でバッチサイズを減らす\n- CPUオフロードを有効化（VRAM <20GBでは自動有効のはず）\n- INT8量子化を有効化（VRAM <20GBでは自動有効のはず）\n- LMバッチチャンクサイズを減らす\n- 各ティアの推奨設定は [GPU_COMPATIBILITY.md](../ja/GPU_COMPATIBILITY.md) を参照\n\n**LMが機能しない：**\n- 初期化時に「5Hz LMを初期化」がチェックされていたことを確認（VRAM ≤6GBのGPUではデフォルト無効）\n- 有効なLMモデルパスが選択されていることを確認（ティア互換モデルのみ表示）\n- vllmまたはPyTorchバックエンドが利用可能であることを確認（VRAM <8GBではvllm制限）\n- LMチェックボックスがグレーアウトしている場合、GPUティアがLMをサポートしていません — DiTのみモードを使用\n\n---\n\n## キーボードショートカット\n\nGradioインターフェースは標準的なWebショートカットをサポート：\n- **Tab** - 入力フィールド間を移動\n- **Enter** - テキスト入力を送信\n- **Space** - チェックボックスを切り替え\n\n---\n\n## 言語サポート\n\nインターフェースは複数のUI言語をサポート：\n- **英語** (en)\n- **中国語** (zh)\n- **日本語** (ja)\n\nサービス設定セクションで好みの言語を選択してください。\n\n---\n\n詳細については以下を参照：\n- メインREADME：[`../../README.md`](../../README.md)\n- REST APIドキュメント：[`API.md`](API.md)\n- Python推論API：[`INFERENCE.md`](INFERENCE.md)\n"
  },
  {
    "path": "docs/ja/INFERENCE.md",
    "content": "# ACE-Step 推論 API ドキュメント\n\n**Language / 语言 / 言語:** [English](../en/INFERENCE.md) | [中文](../zh/INFERENCE.md) | [日本語](INFERENCE.md)\n\n---\n\n本ドキュメントはACE-Step推論APIの包括的なドキュメントを提供し、サポートされているすべてのタスクタイプのパラメータ仕様を含みます。\n\n## 目次\n\n- [クイックスタート](#クイックスタート)\n- [API概要](#api概要)\n- [GenerationParamsパラメータ](#generationparamsパラメータ)\n- [GenerationConfigパラメータ](#generationconfigパラメータ)\n- [タスクタイプ](#タスクタイプ)\n- [ヘルパー関数](#ヘルパー関数)\n- [完全な例](#完全な例)\n- [ベストプラクティス](#ベストプラクティス)\n\n---\n\n## クイックスタート\n\n### 基本的な使用法\n\n```python\nfrom acestep.handler import AceStepHandler\nfrom acestep.llm_inference import LLMHandler\nfrom acestep.inference import GenerationParams, GenerationConfig, generate_music\n\n# ハンドラーの初期化\ndit_handler = AceStepHandler()\nllm_handler = LLMHandler()\n\n# サービスの初期化\ndit_handler.initialize_service(\n    project_root=\"/path/to/project\",\n    config_path=\"acestep-v15-turbo\",\n    device=\"cuda\"\n)\n\nllm_handler.initialize(\n    checkpoint_dir=\"/path/to/checkpoints\",\n    lm_model_path=\"acestep-5Hz-lm-0.6B\",\n    backend=\"vllm\",\n    device=\"cuda\"\n)\n\n# 生成パラメータの設定\nparams = GenerationParams(\n    caption=\"重低音のアップビートなエレクトロニックダンスミュージック\",\n    bpm=128,\n    duration=30,\n)\n\n# 生成設定の構成\nconfig = GenerationConfig(\n    batch_size=2,\n    audio_format=\"flac\",\n)\n\n# 音楽を生成\nresult = generate_music(dit_handler, llm_handler, params, config, save_dir=\"/path/to/output\")\n\n# 結果にアクセス\nif result.success:\n    for audio in result.audios:\n        print(f\"生成完了：{audio['path']}\")\n        print(f\"Key：{audio['key']}\")\n        print(f\"Seed：{audio['params']['seed']}\")\nelse:\n    print(f\"エラー：{result.error}\")\n```\n\n---\n\n## API概要\n\n### メイン関数\n\n#### generate_music\n\n```python\ndef generate_music(\n    dit_handler,\n    llm_handler,\n    params: GenerationParams,\n    config: GenerationConfig,\n    save_dir: Optional[str] = None,\n    progress=None,\n) -> GenerationResult\n```\n\nACE-Stepモデルを使用して音楽を生成するメイン関数。\n\n#### understand_music\n\n```python\ndef understand_music(\n    llm_handler,\n    audio_codes: str,\n    temperature: float = 0.85,\n    top_k: Optional[int] = None,\n    top_p: Optional[float] = None,\n    repetition_penalty: float = 1.0,\n    use_constrained_decoding: bool = True,\n    constrained_decoding_debug: bool = False,\n) -> UnderstandResult\n```\n\nオーディオセマンティックコードを分析し、メタデータ（caption、lyrics、BPM、キーなど）を抽出します。\n\n#### create_sample\n\n```python\ndef create_sample(\n    llm_handler,\n    query: str,\n    instrumental: bool = False,\n    vocal_language: Optional[str] = None,\n    temperature: float = 0.85,\n    top_k: Optional[int] = None,\n    top_p: Optional[float] = None,\n    repetition_penalty: float = 1.0,\n    use_constrained_decoding: bool = True,\n    constrained_decoding_debug: bool = False,\n) -> CreateSampleResult\n```\n\n自然言語の説明から完全な音楽サンプル（caption、lyrics、メタデータ）を生成します。\n\n#### format_sample\n\n```python\ndef format_sample(\n    llm_handler,\n    caption: str,\n    lyrics: str,\n    user_metadata: Optional[Dict[str, Any]] = None,\n    temperature: float = 0.85,\n    top_k: Optional[int] = None,\n    top_p: Optional[float] = None,\n    repetition_penalty: float = 1.0,\n    use_constrained_decoding: bool = True,\n    constrained_decoding_debug: bool = False,\n) -> FormatSampleResult\n```\n\nユーザー提供のcaptionとlyricsをフォーマット・強化し、構造化されたメタデータを生成します。\n\n### 設定オブジェクト\n\nAPIは2つの設定データクラスを使用します：\n\n**GenerationParams** - すべての音楽生成パラメータを含む：\n\n```python\n@dataclass\nclass GenerationParams:\n    # タスクと指示\n    task_type: str = \"text2music\"\n    instruction: str = \"Fill the audio semantic mask based on the given conditions:\"\n    \n    # オーディオアップロード\n    reference_audio: Optional[str] = None\n    src_audio: Optional[str] = None\n    \n    # LMコードヒント\n    audio_codes: str = \"\"\n    \n    # テキスト入力\n    caption: str = \"\"\n    lyrics: str = \"\"\n    instrumental: bool = False\n    \n    # メタデータ\n    vocal_language: str = \"unknown\"\n    bpm: Optional[int] = None\n    keyscale: str = \"\"\n    timesignature: str = \"\"\n    duration: float = -1.0\n    \n    # 高度な設定\n    inference_steps: int = 8\n    seed: int = -1\n    guidance_scale: float = 7.0\n    use_adg: bool = False\n    cfg_interval_start: float = 0.0\n    cfg_interval_end: float = 1.0\n    shift: float = 1.0                    # 新規：タイムステップシフト係数\n    infer_method: str = \"ode\"             # 新規：拡散推論方法\n    timesteps: Optional[List[float]] = None  # 新規：カスタムタイムステップ\n    \n    repainting_start: float = 0.0\n    repainting_end: float = -1\n    audio_cover_strength: float = 1.0\n    \n    # 5Hz言語モデルパラメータ\n    thinking: bool = True\n    lm_temperature: float = 0.85\n    lm_cfg_scale: float = 2.0\n    lm_top_k: int = 0\n    lm_top_p: float = 0.9\n    lm_negative_prompt: str = \"NO USER INPUT\"\n    use_cot_metas: bool = True\n    use_cot_caption: bool = True\n    use_cot_lyrics: bool = False\n    use_cot_language: bool = True\n    use_constrained_decoding: bool = True\n    \n    # CoT生成値（LMによって自動入力）\n    cot_bpm: Optional[int] = None\n    cot_keyscale: str = \"\"\n    cot_timesignature: str = \"\"\n    cot_duration: Optional[float] = None\n    cot_vocal_language: str = \"unknown\"\n    cot_caption: str = \"\"\n    cot_lyrics: str = \"\"\n```\n\n**GenerationConfig** - バッチと出力設定を含む：\n\n```python\n@dataclass\nclass GenerationConfig:\n    batch_size: int = 2\n    allow_lm_batch: bool = False\n    use_random_seed: bool = True\n    seeds: Optional[List[int]] = None\n    lm_batch_chunk_size: int = 8\n    constrained_decoding_debug: bool = False\n    audio_format: str = \"flac\"\n```\n\n### 結果オブジェクト\n\n**GenerationResult** - 音楽生成の結果：\n\n```python\n@dataclass\nclass GenerationResult:\n    # オーディオ出力\n    audios: List[Dict[str, Any]]  # オーディオ辞書のリスト\n    \n    # 生成情報\n    status_message: str           # 生成からのステータスメッセージ\n    extra_outputs: Dict[str, Any] # 追加出力（latents、masks、lm_metadata、time_costs）\n    \n    # 成功ステータス\n    success: bool                 # 生成が成功したかどうか\n    error: Optional[str]          # 失敗した場合のエラーメッセージ\n```\n\n**オーディオ辞書構造：**\n\n`audios` リストの各アイテムには以下が含まれます：\n\n```python\n{\n    \"path\": str,           # 保存されたオーディオへのファイルパス\n    \"tensor\": Tensor,      # オーディオテンソル [channels, samples]、CPU、float32\n    \"key\": str,            # ユニークなオーディオキー（パラメータに基づくUUID）\n    \"sample_rate\": int,    # サンプルレート（デフォルト：48000）\n    \"params\": Dict,        # このオーディオの生成パラメータ（seed、audio_codesなどを含む）\n}\n```\n\n---\n\n## GenerationParamsパラメータ\n\n### テキスト入力\n\n| パラメータ | 型 | デフォルト | 説明 |\n|-----------|------|---------|-------------|\n| `caption` | `str` | `\"\"` | 希望する音楽のテキスト説明。「リラックスしたピアノ音楽」のような単純なプロンプトや、ジャンル、ムード、楽器などを含む詳細な説明が可能。最大512文字。|\n| `lyrics` | `str` | `\"\"` | ボーカル音楽の歌詞テキスト。インストゥルメンタルトラックには `\"[Instrumental]\"` を使用。複数言語をサポート。最大4096文字。|\n| `instrumental` | `bool` | `False` | Trueの場合、歌詞に関係なくインストゥルメンタル音楽を生成。|\n\n### 音楽メタデータ\n\n| パラメータ | 型 | デフォルト | 説明 |\n|-----------|------|---------|-------------|\n| `bpm` | `Optional[int]` | `None` | 1分あたりのビート数（30-300）。`None` でLM経由の自動検出を有効化。|\n| `keyscale` | `str` | `\"\"` | 音楽キー（例：「C Major」、「Am」、「F# minor」）。空文字列で自動検出を有効化。|\n| `timesignature` | `str` | `\"\"` | 拍子記号（2は'2/4'、3は'3/4'、4は'4/4'、6は'6/8'）。空文字列で自動検出を有効化。|\n| `vocal_language` | `str` | `\"unknown\"` | ボーカルの言語コード（ISO 639-1）。サポート：`\"en\"`、`\"zh\"`、`\"ja\"`、`\"es\"`、`\"fr\"` など。自動検出には `\"unknown\"` を使用。|\n| `duration` | `float` | `-1.0` | 目標オーディオ長（秒）（10-600）。<= 0またはNoneの場合、モデルが歌詞の長さに基づいて自動選択。|\n\n### 生成パラメータ\n\n| パラメータ | 型 | デフォルト | 説明 |\n|-----------|------|---------|-------------|\n| `inference_steps` | `int` | `8` | デノイズステップ数。Turboモデル：1-20（推奨8）。Baseモデル：1-200（推奨32-64）。高い = 品質向上だが遅い。|\n| `guidance_scale` | `float` | `7.0` | 分類器フリーガイダンススケール（1.0-15.0）。高い値はテキストプロンプトへの忠実性を増加。非turboモデルのみサポート。典型的な範囲：5.0-9.0。|\n| `seed` | `int` | `-1` | 再現性のためのランダムシード。ランダムシードには `-1`、固定シードには任意の正の整数を使用。|\n\n### 高度なDiTパラメータ\n\n| パラメータ | 型 | デフォルト | 説明 |\n|-----------|------|---------|-------------|\n| `use_adg` | `bool` | `False` | 適応デュアルガイダンスを使用（baseモデルのみ）。速度を犠牲にして品質を向上。|\n| `cfg_interval_start` | `float` | `0.0` | CFG適用開始比率（0.0-1.0）。分類器フリーガイダンスの適用開始タイミングを制御。|\n| `cfg_interval_end` | `float` | `1.0` | CFG適用終了比率（0.0-1.0）。分類器フリーガイダンスの適用終了タイミングを制御。|\n| `shift` | `float` | `1.0` | タイムステップシフト係数（範囲1.0-5.0、デフォルト1.0）。!= 1.0の場合、タイムステップに `t = shift * t / (1 + (shift - 1) * t)` を適用。turboモデルには3.0推奨。|\n| `infer_method` | `str` | `\"ode\"` | 拡散推論方法。`\"ode\"`（Euler）はより高速で決定的。`\"sde\"`（確率的）は分散のある異なる結果を生成する可能性あり。|\n| `timesteps` | `Optional[List[float]]` | `None` | カスタムタイムステップ、1.0から0.0の浮動小数点リスト（例：`[0.97, 0.76, 0.615, 0.5, 0.395, 0.28, 0.18, 0.085, 0]`）。提供された場合、`inference_steps` と `shift` をオーバーライド。|\n\n### タスク固有パラメータ\n\n| パラメータ | 型 | デフォルト | 説明 |\n|-----------|------|---------|-------------|\n| `task_type` | `str` | `\"text2music\"` | 生成タスクタイプ。詳細は[タスクタイプ](#タスクタイプ)セクションを参照。|\n| `instruction` | `str` | `\"Fill the audio semantic mask based on the given conditions:\"` | タスク固有の指示プロンプト。|\n| `reference_audio` | `Optional[str]` | `None` | スタイル転送または継続タスク用の参照オーディオファイルパス。|\n| `src_audio` | `Optional[str]` | `None` | オーディオ間タスク（cover、repaintなど）用のソースオーディオファイルパス。|\n| `audio_codes` | `str` | `\"\"` | 事前抽出された5Hzオーディオセマンティックコード文字列。高度な使用のみ。|\n| `repainting_start` | `float` | `0.0` | リペイント開始時間（秒）（repaint/legoタスク用）。|\n| `repainting_end` | `float` | `-1` | リペイント終了時間（秒）。オーディオの終端には `-1` を使用。|\n| `audio_cover_strength` | `float` | `1.0` | オーディオカバー/コードの影響強度（0.0-1.0）。スタイル転送タスクには小さい値（0.2）を設定。|\n\n### 5Hz言語モデルパラメータ\n\n| パラメータ | 型 | デフォルト | 説明 |\n|-----------|------|---------|-------------|\n| `thinking` | `bool` | `True` | セマンティック/音楽メタデータとコード用の5Hz言語モデル「思考の連鎖」推論を有効化。|\n| `lm_temperature` | `float` | `0.85` | LMサンプリング温度（0.0-2.0）。高い = より創造的/多様、低い = より保守的。|\n| `lm_cfg_scale` | `float` | `2.0` | LM分類器フリーガイダンススケール。高い = プロンプトへのより強い忠実性。|\n| `lm_top_k` | `int` | `0` | LM top-kサンプリング。`0` でtop-kフィルタリングを無効化。典型的な値：40-100。|\n| `lm_top_p` | `float` | `0.9` | LM核サンプリング（0.0-1.0）。`1.0` で核サンプリングを無効化。典型的な値：0.9-0.95。|\n| `lm_negative_prompt` | `str` | `\"NO USER INPUT\"` | LMガイダンス用のネガティブプロンプト。不要な特性を避けるのに役立つ。|\n| `use_cot_metas` | `bool` | `True` | LM CoT推論を使用してメタデータを生成（BPM、キー、duration など）。|\n| `use_cot_caption` | `bool` | `True` | LM CoT推論を使用してユーザーcaptionを改良。|\n| `use_cot_language` | `bool` | `True` | LM CoT推論を使用してボーカル言語を検出。|\n| `use_cot_lyrics` | `bool` | `False` | （将来の使用のために予約）LM CoTを使用して歌詞を生成/改良。|\n| `use_constrained_decoding` | `bool` | `True` | 構造化されたLM出力のための制約付きデコーディングを有効化。|\n\n---\n\n## GenerationConfigパラメータ\n\n| パラメータ | 型 | デフォルト | 説明 |\n|-----------|------|---------|-------------|\n| `batch_size` | `int` | `2` | 並列生成するサンプル数（1-8）。高い値はより多くのGPUメモリを必要とする。|\n| `allow_lm_batch` | `bool` | `False` | LMでのバッチ処理を許可。`batch_size >= 2` かつ `thinking=True` の場合により高速。|\n| `use_random_seed` | `bool` | `True` | ランダムシードを使用するかどうか。`True` で毎回異なる結果、`False` で再現可能な結果。|\n| `seeds` | `Optional[List[int]]` | `None` | バッチ生成用のシードリスト。提供された場合、batch_sizeより少なければランダムシードでパディング。単一のintも可。|\n| `lm_batch_chunk_size` | `int` | `8` | LM推論チャンクあたりの最大バッチサイズ（GPUメモリ制約）。|\n| `constrained_decoding_debug` | `bool` | `False` | 制約付きデコーディングのデバッグログを有効化。|\n| `audio_format` | `str` | `\"flac\"` | 出力オーディオ形式。オプション：`\"mp3\"`、`\"wav\"`、`\"flac\"`。高速保存のためデフォルトはFLAC。|\n\n---\n\n## タスクタイプ\n\nACE-Stepは6種類の生成タスクタイプをサポートし、それぞれ特定のユースケースに最適化されています。\n\n### 1. Text2Music（デフォルト）\n\n**目的**：テキスト説明とオプションのメタデータから音楽を生成。\n\n**主要パラメータ**：\n```python\nparams = GenerationParams(\n    task_type=\"text2music\",\n    caption=\"エレキギターのエネルギッシュなロック音楽\",\n    lyrics=\"[Instrumental]\",  # または実際の歌詞\n    bpm=140,\n    duration=30,\n)\n```\n\n**必須**：\n- `caption` または `lyrics`（少なくとも1つ）\n\n**オプションだが推奨**：\n- `bpm`：テンポを制御\n- `keyscale`：音楽キーを制御\n- `timesignature`：リズム構造を制御\n- `duration`：長さを制御\n- `vocal_language`：ボーカル特性を制御\n\n**ユースケース**：\n- テキスト説明から音楽を生成\n- プロンプトからバッキングトラックを作成\n- 歌詞付きの曲を生成\n\n---\n\n### 2. Cover\n\n**目的**：既存のオーディオを構造を維持しながらスタイル/音色を変更して変換。\n\n**主要パラメータ**：\n```python\nparams = GenerationParams(\n    task_type=\"cover\",\n    src_audio=\"original_song.mp3\",\n    caption=\"ジャズピアノバージョン\",\n    audio_cover_strength=0.8,  # 0.0-1.0\n)\n```\n\n**必須**：\n- `src_audio`：ソースオーディオファイルパス\n- `caption`：希望するスタイル/変換の説明\n\n**オプション**：\n- `audio_cover_strength`：元のオーディオの影響を制御\n  - `1.0`：元の構造を強く維持\n  - `0.5`：バランスの取れた変換\n  - `0.1`：緩やかな解釈\n- `lyrics`：新しい歌詞（ボーカルを変更する場合）\n\n**ユースケース**：\n- 異なるスタイルのカバーを作成\n- メロディを維持しながら楽器編成を変更\n- ジャンル変換\n\n---\n\n### 3. Repaint\n\n**目的**：オーディオの特定の時間セグメントを再生成し、残りは変更しない。\n\n**主要パラメータ**：\n```python\nparams = GenerationParams(\n    task_type=\"repaint\",\n    src_audio=\"original.mp3\",\n    repainting_start=10.0,  # 秒\n    repainting_end=20.0,    # 秒\n    caption=\"ピアノソロでスムーズなトランジション\",\n)\n```\n\n**必須**：\n- `src_audio`：ソースオーディオファイルパス\n- `repainting_start`：開始時間（秒）\n- `repainting_end`：終了時間（秒）（ファイル終端には `-1` を使用）\n- `caption`：リペイントセクションの希望するコンテンツの説明\n\n**ユースケース**：\n- 生成された音楽の特定セクションを修正\n- 曲の一部にバリエーションを追加\n- スムーズなトランジションを作成\n- 問題のあるセグメントを置き換え\n\n---\n\n### 4. Lego（Baseモデルのみ）\n\n**目的**：既存のオーディオのコンテキストで特定の楽器トラックを生成。\n\n**主要パラメータ**：\n```python\nparams = GenerationParams(\n    task_type=\"lego\",\n    src_audio=\"backing_track.mp3\",\n    instruction=\"Generate the guitar track based on the audio context:\",\n    caption=\"ブルージーな感じのリードギターメロディ\",\n    repainting_start=0.0,\n    repainting_end=-1,\n)\n```\n\n**必須**：\n- `src_audio`：ソース/バッキングオーディオパス\n- `instruction`：トラックタイプを指定する必要あり（例：「Generate the {TRACK_NAME} track...」）\n- `caption`：希望するトラック特性の説明\n\n**利用可能なトラック**：\n- `\"vocals\"`、`\"backing_vocals\"`、`\"drums\"`、`\"bass\"`、`\"guitar\"`、`\"keyboard\"`、\n- `\"percussion\"`、`\"strings\"`、`\"synth\"`、`\"fx\"`、`\"brass\"`、`\"woodwinds\"`\n\n**ユースケース**：\n- 特定の楽器トラックを追加\n- バッキングトラック上に追加の楽器をレイヤー\n- マルチトラック作品を反復的に作成\n\n---\n\n### 5. Extract（Baseモデルのみ）\n\n**目的**：ミックスオーディオから特定の楽器トラックを抽出/分離。\n\n**主要パラメータ**：\n```python\nparams = GenerationParams(\n    task_type=\"extract\",\n    src_audio=\"full_mix.mp3\",\n    instruction=\"Extract the vocals track from the audio:\",\n)\n```\n\n**必須**：\n- `src_audio`：ミックスオーディオファイルパス\n- `instruction`：抽出するトラックを指定する必要あり\n\n**利用可能なトラック**：Legoタスクと同じ\n\n**ユースケース**：\n- ステム分離\n- 特定の楽器を分離\n- リミックスを作成\n- 個別トラックを分析\n\n---\n\n### 6. Complete（Baseモデルのみ）\n\n**目的**：指定された楽器で部分的なトラックを完成/拡張。\n\n**主要パラメータ**：\n```python\nparams = GenerationParams(\n    task_type=\"complete\",\n    src_audio=\"incomplete_track.mp3\",\n    instruction=\"Complete the input track with drums, bass, guitar:\",\n    caption=\"ロックスタイルの完成\",\n)\n```\n\n**必須**：\n- `src_audio`：不完全/部分的なトラックのパス\n- `instruction`：追加するトラックを指定する必要あり\n- `caption`：希望するスタイルの説明\n\n**ユースケース**：\n- 不完全な作品をアレンジ\n- バッキングトラックを追加\n- 音楽アイデアを自動完成\n\n---\n\n## ヘルパー関数\n\n### understand_music\n\nオーディオコードを分析して音楽についてのメタデータを抽出。\n\n```python\nfrom acestep.inference import understand_music\n\nresult = understand_music(\n    llm_handler=llm_handler,\n    audio_codes=\"<|audio_code_123|><|audio_code_456|>...\",\n    temperature=0.85,\n    use_constrained_decoding=True,\n)\n\nif result.success:\n    print(f\"Caption：{result.caption}\")\n    print(f\"歌詞：{result.lyrics}\")\n    print(f\"BPM：{result.bpm}\")\n    print(f\"キー：{result.keyscale}\")\n    print(f\"長さ：{result.duration}秒\")\n    print(f\"言語：{result.language}\")\nelse:\n    print(f\"エラー：{result.error}\")\n```\n\n**ユースケース**：\n- 既存の音楽を分析\n- オーディオコードからメタデータを抽出\n- 生成パラメータをリバースエンジニアリング\n\n---\n\n### create_sample\n\n自然言語の説明から完全な音楽サンプルを生成。これは「シンプルモード」/「インスピレーションモード」機能です。\n\n```python\nfrom acestep.inference import create_sample\n\nresult = create_sample(\n    llm_handler=llm_handler,\n    query=\"静かな夜のための柔らかいベンガルのラブソング\",\n    instrumental=False,\n    vocal_language=\"bn\",  # オプション：ベンガル語に制限\n    temperature=0.85,\n)\n\nif result.success:\n    print(f\"Caption：{result.caption}\")\n    print(f\"歌詞：{result.lyrics}\")\n    print(f\"BPM：{result.bpm}\")\n    print(f\"長さ：{result.duration}秒\")\n    print(f\"キー：{result.keyscale}\")\n    print(f\"インストゥルメンタルか：{result.instrumental}\")\n    \n    # generate_musicと一緒に使用\n    params = GenerationParams(\n        caption=result.caption,\n        lyrics=result.lyrics,\n        bpm=result.bpm,\n        duration=result.duration,\n        keyscale=result.keyscale,\n        vocal_language=result.language,\n    )\nelse:\n    print(f\"エラー：{result.error}\")\n```\n\n---\n\n### format_sample\n\nユーザー提供のcaptionとlyricsをフォーマット・強化し、構造化されたメタデータを生成。\n\n```python\nfrom acestep.inference import format_sample\n\nresult = format_sample(\n    llm_handler=llm_handler,\n    caption=\"ラテンポップ、レゲトン\",\n    lyrics=\"[Verse 1]\\nBailando en la noche...\",\n    user_metadata={\"bpm\": 95},  # オプション：特定の値を制約\n    temperature=0.85,\n)\n\nif result.success:\n    print(f\"強化されたCaption：{result.caption}\")\n    print(f\"フォーマットされた歌詞：{result.lyrics}\")\n    print(f\"BPM：{result.bpm}\")\n    print(f\"長さ：{result.duration}秒\")\n    print(f\"キー：{result.keyscale}\")\n    print(f\"検出された言語：{result.language}\")\nelse:\n    print(f\"エラー：{result.error}\")\n```\n\n---\n\n## ベストプラクティス\n\n### 1. Captionの書き方\n\n**良いCaption**：\n```python\n# 具体的で説明的\ncaption=\"重低音とシンセサイザーリードのアップビートなエレクトロニックダンスミュージック\"\n\n# ムードとジャンルを含む\ncaption=\"アコースティックギターと柔らかいボーカルのメランコリックなインディーフォーク\"\n\n# 楽器を指定\ncaption=\"ピアノ、アップライトベース、ブラシドラムのジャズトリオ\"\n```\n\n**避けるべき**：\n```python\n# 曖昧すぎる\ncaption=\"良い音楽\"\n\n# 矛盾\ncaption=\"速い遅い音楽\"  # テンポの矛盾\n```\n\n### 2. パラメータチューニング\n\n**最高品質のために**：\n- baseモデルを使用し、`inference_steps=64` 以上\n- `use_adg=True` を有効化\n- `guidance_scale=7.0-9.0` を設定\n- より良いタイムステップ分布のために `shift=3.0` を設定\n- ロスレスオーディオ形式を使用（`audio_format=\"wav\"`）\n\n**速度のために**：\n- turboモデルを使用し、`inference_steps=8`\n- ADGを無効化（`use_adg=False`）\n- `infer_method=\"ode\"`（デフォルト）を使用\n- 圧縮形式を使用（`audio_format=\"mp3\"`）またはデフォルトのFLAC\n\n**一貫性のために**：\n- configで `use_random_seed=False` を設定\n- 固定 `seeds` リストまたはparamsで単一 `seed` を使用\n- `lm_temperature` を低く保つ（0.7-0.85）\n\n**多様性のために**：\n- configで `use_random_seed=True` を設定\n- `lm_temperature` を増加（0.9-1.1）\n- バリエーションのために `batch_size > 1` を使用\n\n### 3. Durationガイドライン\n\n- **インストゥルメンタル**：30-180秒が適切\n- **歌詞付き**：自動検出を推奨（`duration=-1` を設定またはデフォルトのまま）\n- **短いクリップ**：最小10-20秒\n- **長尺**：最大600秒（10分）\n\n### 4. LMの使用\n\n**LMを有効にする場合（`thinking=True`）**：\n- 自動メタデータ検出が必要\n- caption改良が欲しい\n- 最小限の入力から生成\n- 多様な出力が必要\n\n**LMを無効にする場合（`thinking=False`）**：\n- すでに正確なメタデータがある\n- より高速な生成が必要\n- パラメータの完全な制御が欲しい\n\n---\n\n## トラブルシューティング\n\n### よくある問題\n\n**問題**：メモリ不足（OOM）エラー\n- **解決策**：システムは VRAM ガード（バッチ自動削減）とアダプティブ VAE デコード（CPU フォールバック）により、ほとんどの OOM シナリオを自動処理します。それでも OOM が発生する場合：`batch_size` を減らす、`inference_steps` を減らす、CPU オフロード（`offload_to_cpu=True`）を有効化、または INT8 量子化を有効化してください。各 VRAM ティアの推奨設定は [GPU_COMPATIBILITY.md](../ja/GPU_COMPATIBILITY.md) を参照してください。\n\n**問題**：結果の品質が悪い\n- **解決策**：`inference_steps` を増やす、`guidance_scale` を調整、baseモデルを使用\n\n**問題**：結果がプロンプトと一致しない\n- **解決策**：captionをより具体的に、`guidance_scale` を増やす、LM改良を有効化（`thinking=True`）\n\n**問題**：生成が遅い\n- **解決策**：turboモデルを使用、`inference_steps` を減らす、ADGを無効化\n\n**問題**：LMがコードを生成しない\n- **解決策**：`llm_handler` が初期化されていることを確認、`thinking=True` と `use_cot_metas=True` を確認\n\n**問題**：シードが尊重されない\n- **解決策**：configで `use_random_seed=False` を設定し、`seeds` リストまたはparamsで `seed` を提供\n\n**問題**：カスタムタイムステップが機能しない\n- **解決策**：タイムステップが1.0から0.0の浮動小数点リストで、適切に順序付けられていることを確認\n\n---\n\n詳細については以下を参照：\n- メインREADME：[`../../README.md`](../../README.md)\n- REST APIドキュメント：[`API.md`](API.md)\n- Gradioデモガイド：[`GRADIO_GUIDE.md`](GRADIO_GUIDE.md)\n- プロジェクトリポジトリ：[ACE-Step-1.5](https://github.com/yourusername/ACE-Step-1.5)\n"
  },
  {
    "path": "docs/ja/INSTALL.md",
    "content": "# ACE-Step 1.5 インストールガイド\n\n**Language / 语言 / 言語:** [English](../en/INSTALL.md) | [中文](../zh/INSTALL.md) | [日本語](INSTALL.md)\n\n---\n\n## 目次\n\n- [動作要件](#動作要件)\n- [クイックスタート（全プラットフォーム）](#クイックスタート全プラットフォーム)\n- [起動スクリプト](#-起動スクリプト)\n- [Windows ポータブルパッケージ](#-windows-ポータブルパッケージ)\n- [AMD / ROCm GPU](#amd--rocm-gpu)\n- [Intel GPU](#intel-gpu)\n- [CPUのみモード](#cpuのみモード)\n- [Linux の注意事項](#linux-の注意事項)\n- [環境変数 (.env)](#環境変数-env)\n- [コマンドラインオプション](#コマンドラインオプション)\n- [モデルダウンロード](#-モデルダウンロード)\n- [どのモデルを選ぶべき？](#-どのモデルを選ぶべき)\n- [開発](#開発)\n\n---\n\n## 動作要件\n\n| 項目 | 要件 |\n|------|------|\n| Python | 3.11-3.12（安定版、プレリリース版は不可）<br>**注意：** Windows 上の ROCm は Python 3.12 が必要です |\n| GPU | CUDA GPU 推奨。MPS / ROCm / Intel XPU / CPU もサポート |\n| VRAM | DiTのみモード ≥4GB、LLM+DiT ≥6GB |\n| ディスク | コアモデルに約10GB |\n\n---\n\n## クイックスタート（全プラットフォーム）\n\n### 1. uv のインストール（パッケージマネージャー）\n\n```bash\n# macOS / Linux\ncurl -LsSf https://astral.sh/uv/install.sh | sh\n\n# Windows (PowerShell)\npowershell -ExecutionPolicy ByPass -c \"irm https://astral.sh/uv/install.ps1 | iex\"\n```\n\n### 2. クローン & インストール\n\n```bash\ngit clone https://github.com/ACE-Step/ACE-Step-1.5.git\ncd ACE-Step-1.5\nuv sync\n```\n\n### 3. 起動\n\n**Gradio Web UI（推奨）：**\n\n```bash\nuv run acestep\n```\n\n**REST API サーバー：**\n\n```bash\nuv run acestep-api\n```\n\n**Python を直接使用**（Conda / venv / システム Python）：\n\n```bash\n# まず環境をアクティベートしてから：\npython acestep/acestep_v15_pipeline.py          # Gradio UI\npython acestep/api_server.py                     # REST API\n```\n\n> 初回実行時にモデルが自動ダウンロードされます。http://localhost:7860（Gradio）または http://localhost:8001（API）を開いてください。\n\n---\n\n## 🚀 起動スクリプト\n\n全プラットフォーム対応のすぐに使える起動スクリプトです。これらのスクリプトは環境検出、依存関係のインストール、アプリケーションの起動を自動的に処理します。すべてのスクリプトはデフォルトで起動時に更新チェックを行います（設定変更可能）。\n\n### 利用可能なスクリプト\n\n| プラットフォーム | スクリプト | 説明 |\n|----------|--------|------|\n| **Windows** | `start_gradio_ui.bat` | Gradio Web UI を起動（CUDA） |\n| **Windows** | `start_api_server.bat` | REST API サーバーを起動（CUDA） |\n| **Windows** | `start_gradio_ui_rocm.bat` | Gradio Web UI を起動（AMD ROCm） |\n| **Windows** | `start_api_server_rocm.bat` | REST API サーバーを起動（AMD ROCm） |\n| **Linux** | `start_gradio_ui.sh` | Gradio Web UI を起動（CUDA） |\n| **Linux** | `start_api_server.sh` | REST API サーバーを起動（CUDA） |\n| **macOS** | `start_gradio_ui_macos.sh` | Gradio Web UI を起動（MLX） |\n| **macOS** | `start_api_server_macos.sh` | REST API サーバーを起動（MLX） |\n\n### Windows\n\n```bash\n# Gradio Web UI を起動（NVIDIA CUDA）\nstart_gradio_ui.bat\n\n# REST API サーバーを起動（NVIDIA CUDA）\nstart_api_server.bat\n\n# Gradio Web UI を起動（AMD ROCm）\nstart_gradio_ui_rocm.bat\n\n# REST API サーバーを起動（AMD ROCm）\nstart_api_server_rocm.bat\n```\n\n> **ROCm ユーザー：** ROCm スクリプト（`start_gradio_ui_rocm.bat`、`start_api_server_rocm.bat`）は `HSA_OVERRIDE_GFX_VERSION`、`ACESTEP_LM_BACKEND=pt`、`MIOPEN_FIND_MODE=FAST` およびその他の ROCm 固有の環境変数を自動設定します。CUDA/ROCm wheel の競合を避けるため、別の `venv_rocm` 仮想環境を使用します。\n\n### Linux\n\n```bash\n# 実行権限を付与（初回のみ）\nchmod +x start_gradio_ui.sh start_api_server.sh\n\n# Gradio Web UI を起動\n./start_gradio_ui.sh\n\n# REST API サーバーを起動\n./start_api_server.sh\n```\n\n> **注意：** Git はシステムのパッケージマネージャーでインストールする必要があります（`sudo apt install git`、`sudo yum install git`、`sudo pacman -S git`）。\n\n### macOS（Apple Silicon / MLX）\n\nmacOS スクリプトはネイティブの Apple Silicon アクセラレーション（M1/M2/M3/M4）のために **MLX バックエンド**を使用します。\n\n```bash\n# 実行権限を付与（初回のみ）\nchmod +x start_gradio_ui_macos.sh start_api_server_macos.sh\n\n# MLX バックエンドで Gradio Web UI を起動\n./start_gradio_ui_macos.sh\n\n# MLX バックエンドで REST API サーバーを起動\n./start_api_server_macos.sh\n```\n\nmacOS スクリプトはネイティブの Apple Silicon アクセラレーションのために `ACESTEP_LM_BACKEND=mlx` と `--backend mlx` を自動設定し、非 arm64 マシンでは PyTorch バックエンドにフォールバックします。\n\n> **注意：** Git は `xcode-select --install` または `brew install git` でインストールしてください。\n\n### スクリプトの機能\n\n- 起動時の更新チェック（デフォルトで有効、設定変更可能）\n- 自動環境検出（ポータブル Python または uv）\n- 必要に応じて `uv` を自動インストール\n- ダウンロードソースの設定（HuggingFace/ModelScope）\n- モデルとパラメータのカスタマイズ\n\n### 設定の変更方法\n\nすべての設定可能なオプションは、各スクリプトの先頭で変数として定義されています。カスタマイズするには、テキストエディタでスクリプトを開き、変数の値を変更してください。\n\n**例：UI 言語を中国語に変更し、1.7B LM モデルを使用する**\n\n<table>\n<tr><th>Windows (.bat)</th><th>Linux / macOS (.sh)</th></tr>\n<tr><td>\n\n`start_gradio_ui.bat` で以下の行を見つけます：\n```batch\nset LANGUAGE=en\nset LM_MODEL_PATH=--lm_model_path acestep-5Hz-lm-0.6B\n```\n以下のように変更します：\n```batch\nset LANGUAGE=zh\nset LM_MODEL_PATH=--lm_model_path acestep-5Hz-lm-1.7B\n```\n\n</td><td>\n\n`start_gradio_ui.sh` で以下の行を見つけます：\n```bash\nLANGUAGE=\"en\"\nLM_MODEL_PATH=\"--lm_model_path acestep-5Hz-lm-0.6B\"\n```\n以下のように変更します：\n```bash\nLANGUAGE=\"zh\"\nLM_MODEL_PATH=\"--lm_model_path acestep-5Hz-lm-1.7B\"\n```\n\n</td></tr>\n</table>\n\n**例：起動時の更新チェックを無効にする**\n\n<table>\n<tr><th>Windows (.bat)</th><th>Linux / macOS (.sh)</th></tr>\n<tr><td>\n\n```batch\nREM set CHECK_UPDATE=true\nset CHECK_UPDATE=false\n```\n\n</td><td>\n\n```bash\n# CHECK_UPDATE=\"true\"\nCHECK_UPDATE=\"false\"\n```\n\n</td></tr>\n</table>\n\n**例：コメントアウトされたオプションを有効にする** — コメントプレフィックス（.bat は `REM`、.sh は `#`）を削除します：\n\n<table>\n<tr><th>Windows (.bat)</th><th>Linux / macOS (.sh)</th></tr>\n<tr><td>\n\n変更前：\n```batch\nREM set SHARE=--share\n```\n変更後：\n```batch\nset SHARE=--share\n```\n\n</td><td>\n\n変更前：\n```bash\n# SHARE=\"--share\"\n```\n変更後：\n```bash\nSHARE=\"--share\"\n```\n\n</td></tr>\n</table>\n\n**主な設定可能オプション：**\n\n| オプション | Gradio UI | API サーバー | 説明 |\n|--------|:---------:|:----------:|------|\n| `LANGUAGE` | ✅ | — | UI 言語：`en`、`zh`、`he`、`ja` |\n| `PORT` | ✅ | ✅ | サーバーポート（デフォルト：7860 / 8001） |\n| `SERVER_NAME` / `HOST` | ✅ | ✅ | バインドアドレス（`127.0.0.1` または `0.0.0.0`） |\n| `CHECK_UPDATE` | ✅ | ✅ | 起動時の更新チェック（`true` / `false`） |\n| `CONFIG_PATH` | ✅ | — | DiT モデル（`acestep-v15-turbo` など） |\n| `LM_MODEL_PATH` | ✅ | ✅ | LM モデル（`acestep-5Hz-lm-0.6B` / `1.7B` / `4B`） |\n| `DOWNLOAD_SOURCE` | ✅ | ✅ | ダウンロードソース（`huggingface` / `modelscope`） |\n| `SHARE` | ✅ | — | 公開 Gradio リンクを作成 |\n| `INIT_LLM` | ✅ | — | LLM の強制オン/オフ（`true` / `false` / `auto`） |\n| `OFFLOAD_TO_CPU` | ✅ | — | 低 VRAM GPU 向け CPU オフロード |\n\n### 更新 & メンテナンスツール\n\n| スクリプト（Windows） | スクリプト（Linux/macOS） | 用途 |\n|-------------------|----------------------|------|\n| `check_update.bat` | `check_update.sh` | GitHub から更新をチェック |\n| `merge_config.bat` | `merge_config.sh` | 更新後にバックアップされた設定をマージ |\n| `install_uv.bat` | `install_uv.sh` | uv パッケージマネージャーをインストール |\n| `quick_test.bat` | `quick_test.sh` | 環境セットアップをテスト |\n\n**更新ワークフロー：**\n\n```bash\n# Windows                          # Linux / macOS\ncheck_update.bat                    ./check_update.sh\nmerge_config.bat                    ./merge_config.sh\n```\n\n---\n\n## 🪟 Windows ポータブルパッケージ\n\nWindows ユーザー向けに、依存関係がプリインストールされたポータブルパッケージを提供しています：\n\n1. ダウンロードして解凍：[ACE-Step-1.5.7z](https://files.acemusic.ai/acemusic/win/ACE-Step-1.5.7z)\n2. `python_embedded` に全依存関係がプリインストール済み\n3. **要件：** CUDA 12.8\n\n### クイックスタートスクリプト\n\n| スクリプト | 説明 |\n|------------|------|\n| `start_gradio_ui.bat` | Gradio Web UI を起動 |\n| `start_api_server.bat` | REST API サーバーを起動 |\n\n両スクリプトは自動環境検出、自動 `uv` インストール、ダウンロードソース設定、Git 更新チェック（オプション）、モデル・パラメータのカスタマイズに対応しています。\n\n### 設定\n\n**`start_gradio_ui.bat`：**\n\n```batch\nREM UI言語 (en, zh, he, ja)\nset LANGUAGE=ja\n\nREM ダウンロードソース (auto, huggingface, modelscope)\nset DOWNLOAD_SOURCE=--download-source huggingface\n\nREM Git更新チェック (true/false)\nset CHECK_UPDATE=true\n\nREM モデル設定\nset CONFIG_PATH=--config_path acestep-v15-turbo\nset LM_MODEL_PATH=--lm_model_path acestep-5Hz-lm-1.7B\n```\n\n### 更新 & メンテナンス\n\n| スクリプト | 用途 |\n|------------|------|\n| `check_update.bat` | GitHub から更新をチェック |\n| `merge_config.bat` | 更新後にバックアップされた設定をマージ |\n| `install_uv.bat` | uv パッケージマネージャーをインストール |\n| `quick_test.bat` | 環境セットアップをテスト |\n\n---\n\n## AMD / ROCm GPU\n\n> ⚠️ `uv run acestep` は CUDA PyTorch wheels をインストールするため、既存の ROCm 環境を上書きする可能性があります。\n\n### 推奨ワークフロー\n\n```bash\n# 1. 仮想環境を作成してアクティベート\npython -m venv .venv\nsource .venv/bin/activate\n\n# 2. ROCm 対応 PyTorch をインストール\npip install torch --index-url https://download.pytorch.org/whl/rocm6.0\n\n# 3. ACE-Step をインストール\npip install -e .\n\n# 4. サービスを起動\npython -m acestep.acestep_v15_pipeline --port 7680\n```\n\n### GPU 検出のトラブルシューティング\n\n「No GPU detected, running on CPU」と表示される場合：\n\n1. 診断ツールを実行：`python scripts/check_gpu.py`\n2. RDNA3 GPU の場合、`HSA_OVERRIDE_GFX_VERSION` を設定：\n\n| GPU | 値 |\n|-----|---|\n| RX 7900 XT/XTX, RX 9070 XT | `export HSA_OVERRIDE_GFX_VERSION=11.0.0` |\n| RX 7800 XT, RX 7700 XT | `export HSA_OVERRIDE_GFX_VERSION=11.0.1` |\n| RX 7600 | `export HSA_OVERRIDE_GFX_VERSION=11.0.2` |\n\n3. Windows では `start_gradio_ui_rocm.bat` / `start_api_server_rocm.bat` を使用\n4. ROCm インストールを確認：`rocm-smi`\n\n### Linux（cachy-os / RDNA4）\n\n詳細は [ACE-Step1.5-Rocm-Manual-Linux.md](../en/ACE-Step1.5-Rocm-Manual-Linux.md) を参照してください。\n\n---\n\n## Intel GPU\n\n| 項目 | 詳細 |\n|------|------|\n| テスト済みデバイス | Windows ノートPC、Ultra 9 285H 内蔵グラフィックス |\n| オフロード | デフォルトで無効 |\n| コンパイル & 量子化 | デフォルトで有効 |\n| LLM 推論 | サポート（`acestep-5Hz-lm-0.6B` でテスト済み） |\n| nanovllm アクセラレーション | Intel GPU では未サポート |\n| テスト環境 | PyTorch 2.8.0（[Intel Extension for PyTorch](https://pytorch-extension.intel.com/?request=platform)） |\n\n> 注意：2分以上の音声生成時、LLM 推論速度が低下する場合があります。Intel ディスクリート GPU は動作が期待されますが、まだテストされていません。\n\n---\n\n## CPUのみモード\n\nACE-Step は CPU で**推論のみ**実行できますが、速度は大幅に遅くなります。\n\n- CPU でのトレーニング（LoRA を含む）は**推奨されません**。\n- 低 VRAM システムでは、DiTのみモード（LLM 無効）がサポートされています。\n\nGPU がない場合：\n- クラウド GPU プロバイダーの利用\n- 推論のみのワークフロー\n- `ACESTEP_INIT_LLM=false` で DiTのみモードを使用\n\n---\n\n## Linux の注意事項\n\n### Python 3.11 プレリリース版の問題\n\n一部の Linux ディストリビューション（Ubuntu を含む）には Python 3.11.0rc1 プレリリース版が同梱されており、vLLM バックエンドでセグメンテーションフォルトを引き起こす可能性があります。\n\n**推奨：** 安定版 Python（≥ 3.11.12）を使用してください。Ubuntu では deadsnakes PPA からインストールできます。\n\nPython のアップグレードができない場合、PyTorch バックエンドを使用：\n\n```bash\nuv run acestep --backend pt\n```\n\n---\n\n## 環境変数 (.env)\n\n```bash\ncp .env.example .env   # コピーして編集\n```\n\n### 主要な変数\n\n| 変数 | 値 | 説明 |\n|------|---|------|\n| `ACESTEP_INIT_LLM` | `auto` / `true` / `false` | LLM 初期化モード |\n| `ACESTEP_CONFIG_PATH` | モデル名 | DiT モデルパス |\n| `ACESTEP_LM_MODEL_PATH` | モデル名 | LM モデルパス |\n| `ACESTEP_DOWNLOAD_SOURCE` | `auto` / `huggingface` / `modelscope` | ダウンロードソース |\n| `ACESTEP_API_KEY` | 文字列 | API 認証キー |\n\n### LLM 初期化 (`ACESTEP_INIT_LLM`)\n\n処理フロー：`GPU 検出 → ACESTEP_INIT_LLM オーバーライド → モデル読み込み`\n\n| 値 | 動作 |\n|----|------|\n| `auto`（または空） | GPU 自動検出結果を使用（推奨） |\n| `true` / `1` / `yes` | GPU 検出後に LLM を強制有効化（OOM の可能性あり） |\n| `false` / `0` / `no` | 強制無効化、純粋な DiT モード |\n\n**シナリオ別 `.env` の例：**\n\n```bash\n# 自動モード（推奨）\nACESTEP_INIT_LLM=auto\n\n# 低 VRAM GPU で強制有効化\nACESTEP_INIT_LLM=true\nACESTEP_LM_MODEL_PATH=acestep-5Hz-lm-0.6B\n\n# LLM を無効化して高速生成\nACESTEP_INIT_LLM=false\n```\n\n---\n\n## コマンドラインオプション\n\n### Gradio UI (`acestep`)\n\n| オプション | デフォルト | 説明 |\n|------------|-----------|------|\n| `--port` | 7860 | サーバーポート |\n| `--server-name` | 127.0.0.1 | サーバーアドレス（ネットワークアクセスには `0.0.0.0`） |\n| `--share` | false | 公開 Gradio リンクを作成 |\n| `--language` | en | UI 言語：`en`、`zh`、`he`、`ja` |\n| `--init_service` | false | 起動時にモデルを自動初期化 |\n| `--init_llm` | auto | LLM 初期化：`true` / `false` / 省略で自動 |\n| `--config_path` | auto | DiT モデル（例：`acestep-v15-turbo`） |\n| `--lm_model_path` | auto | LM モデル（例：`acestep-5Hz-lm-1.7B`） |\n| `--offload_to_cpu` | auto | CPU オフロード（GPU ティアに基づいて自動設定） |\n| `--download-source` | auto | モデルソース：`auto` / `huggingface` / `modelscope` |\n| `--enable-api` | false | Gradio UI と同時に REST API エンドポイントを有効化 |\n\n**例：**\n\n```bash\n# ネットワーク公開 + 日本語 UI\nuv run acestep --server-name 0.0.0.0 --share --language ja\n\n# 起動時にモデルを事前初期化\nuv run acestep --init_service true --config_path acestep-v15-turbo\n\n# ModelScope からダウンロード\nuv run acestep --download-source modelscope\n```\n\n---\n\n## 📥 モデルダウンロード\n\n初回実行時にモデルが [HuggingFace](https://huggingface.co/ACE-Step/Ace-Step1.5) または [ModelScope](https://modelscope.cn/organization/ACE-Step) から自動ダウンロードされます。\n\n### CLI ダウンロード\n\n```bash\nuv run acestep-download                              # メインモデルをダウンロード\nuv run acestep-download --all                         # 全モデルをダウンロード\nuv run acestep-download --download-source modelscope  # ModelScope から\nuv run acestep-download --model acestep-v15-sft       # 特定のモデル\nuv run acestep-download --list                        # 利用可能な全モデルを一覧表示\n```\n\n### 手動ダウンロード (huggingface-cli)\n\n```bash\n# メインモデル（vae, Qwen3-Embedding-0.6B, acestep-v15-turbo, acestep-5Hz-lm-1.7B）\nhuggingface-cli download ACE-Step/Ace-Step1.5 --local-dir ./checkpoints\n\n# オプションモデル\nhuggingface-cli download ACE-Step/acestep-5Hz-lm-0.6B --local-dir ./checkpoints/acestep-5Hz-lm-0.6B\nhuggingface-cli download ACE-Step/acestep-5Hz-lm-4B --local-dir ./checkpoints/acestep-5Hz-lm-4B\n```\n\n### 利用可能なモデル\n\n| モデル | 説明 | HuggingFace |\n|--------|------|-------------|\n| **Ace-Step1.5**（メイン） | コア：vae, Qwen3-Embedding-0.6B, acestep-v15-turbo, acestep-5Hz-lm-1.7B | [リンク](https://huggingface.co/ACE-Step/Ace-Step1.5) |\n| acestep-5Hz-lm-0.6B | 軽量 LM（0.6B パラメータ） | [リンク](https://huggingface.co/ACE-Step/acestep-5Hz-lm-0.6B) |\n| acestep-5Hz-lm-4B | 大規模 LM（4B パラメータ） | [リンク](https://huggingface.co/ACE-Step/acestep-5Hz-lm-4B) |\n| acestep-v15-base | ベース DiT モデル | [リンク](https://huggingface.co/ACE-Step/acestep-v15-base) |\n| acestep-v15-sft | SFT DiT モデル | [リンク](https://huggingface.co/ACE-Step/acestep-v15-sft) |\n| acestep-v15-turbo-shift1 | Turbo DiT（shift1） | [リンク](https://huggingface.co/ACE-Step/acestep-v15-turbo-shift1) |\n| acestep-v15-turbo-shift3 | Turbo DiT（shift3） | [リンク](https://huggingface.co/ACE-Step/acestep-v15-turbo-shift3) |\n| acestep-v15-turbo-continuous | Turbo DiT（continuous shift 1-5） | [リンク](https://huggingface.co/ACE-Step/acestep-v15-turbo-continuous) |\n\n---\n\n## 💡 どのモデルを選ぶべき？\n\nACE-Step は GPU の VRAM に自動適応します。UI は検出された GPU ティアに基づいてすべての設定（LM モデル、バックエンド、オフロード、量子化）を事前構成します：\n\n| GPU VRAM | 推奨 LM モデル | バックエンド | 備考 |\n|----------|---------------|-------------|------|\n| **≤6GB** | なし（DiTのみ） | — | LM はデフォルトで無効；INT8 量子化 + 完全 CPU オフロード |\n| **6-8GB** | `acestep-5Hz-lm-0.6B` | `pt` | 軽量 LM、PyTorch バックエンド |\n| **8-16GB** | `0.6B` / `1.7B` | `vllm` | 8-12GB は 0.6B、12-16GB は 1.7B |\n| **16-24GB** | `acestep-5Hz-lm-1.7B` | `vllm` | 20GB+ で 4B 利用可能；20GB+ でオフロード不要 |\n| **≥24GB** | `acestep-5Hz-lm-4B` | `vllm` | 最高品質、すべてのモデルがオフロードなしで動作 |\n\n> 📖 GPU 互換性の詳細（ティアテーブル、時間制限、バッチサイズ、アダプティブ UI デフォルト、メモリ最適化）は [GPU 互換性ガイド](GPU_COMPATIBILITY.md) を参照してください。\n\n---\n\n## 開発\n\n```bash\n# 依存関係を追加\nuv add package-name\nuv add --dev package-name\n\n# 全依存関係を更新\nuv sync --upgrade\n```\n"
  },
  {
    "path": "docs/ja/LoRA_Training_Tutorial.md",
    "content": "# ACE-Step 1.5 LoRA トレーニングチュートリアル\n\n## ハードウェア要件\n\n| VRAM | 説明 |\n|------|------|\n| 16 GB（最低） | 通常は使用可能ですが、長い楽曲ではメモリ不足になる場合があります |\n| 20 GB 以上（推奨） | フルレングスの楽曲に対応可能。トレーニング中のVRAM使用量は通常17 GB前後です |\n\n> **ヒント：** トレーニング前の前処理段階では、VRAMを解放するためにGradioを複数回再起動する必要があります。具体的なタイミングは以降の手順で説明します。\n\n## 免責事項\n\n本チュートリアルでは、**ナユタン星人 (NayutalieN)** のアルバム *ナユタン星からの物体Y*（全13曲）をデモとして使用し、500エポック（バッチサイズ1）でトレーニングを行いました。**本チュートリアルはLoRAファインチューニング技術を理解するための教育目的のみに使用されます。ご自身のオリジナル作品でLoRAをトレーニングしてください。**\n\n開発者として、私はナユタン星人の楽曲が大好きで、そのアルバムの一つを例として選びました。権利者の方で本チュートリアルが正当な権利を侵害していると思われる場合は、すぐにご連絡ください。有効な通知を受け次第、関連コンテンツを削除いたします。\n\n技術は合理的かつ合法的に使用されるべきです。アーティストの創作を尊重し、オリジナルアーティストの名誉、権利、利益を**損害または傷つける**行為は行わないでください。\n\n---\n\n## データ準備\n\n> **ヒント：** プログラミングに詳しくない方は、本ドキュメントをClaude Code / Codex CLI / Cursor / Copilotなどのコーディングツールに渡して、作業を代行してもらうことができます。\n\n### 概要\n\n各楽曲のトレーニングデータには以下が含まれます：\n\n1. **音声ファイル** — `.mp3`、`.wav`、`.flac`、`.ogg`、`.opus` 形式に対応\n2. **歌詞** — 音声ファイルと同名の `.lyrics.txt` ファイル（後方互換のため `.txt` も対応）\n3. **アノテーションデータ** — `caption`、`bpm`、`keyscale`、`timesignature`、`language` などのメタデータ\n\n### アノテーションデータ形式\n\n完全なアノテーションデータをお持ちの場合は、JSONファイルを作成し、音声・歌詞と同じディレクトリに配置できます。ファイル構造は以下の通りです：\n\n```\ndataset/\n├── song1.mp3               # 音声\n├── song1.lyrics.txt        # 歌詞\n├── song1.json              # アノテーション（任意）\n├── song1.caption.txt       # キャプション（任意、JSONに含めることも可能）\n├── song2.mp3\n├── song2.lyrics.txt\n├── song2.json\n└── ...\n```\n\nJSONファイルの構造（すべてのフィールドは任意）：\n\n```json\n{\n    \"caption\": \"A high-energy J-pop track with synthesizer leads and fast tempo\",\n    \"bpm\": 190,\n    \"keyscale\": \"D major\",\n    \"timesignature\": \"4\",\n    \"language\": \"ja\"\n}\n```\n\nアノテーションデータがない場合は、後続のセクションで紹介する方法で取得できます。\n\n---\n\n### 歌詞\n\n歌詞を音声ファイルと同名の `.lyrics.txt` ファイルとして保存し、同じディレクトリに配置してください。歌詞の正確性を確認してください。\n\nスキャン時の歌詞ファイル検索優先順位：\n\n1. `{ファイル名}.lyrics.txt`（推奨）\n2. `{ファイル名}.txt`（後方互換）\n\n#### 歌詞の文字起こし\n\n既存の歌詞テキストがない場合は、以下のツールで文字起こしが可能です：\n\n| ツール | 構造化タグ | 精度 | 使いやすさ | デプロイ方式 |\n|--------|-----------|------|-----------|------------|\n| [acestep-transcriber](https://huggingface.co/ACE-Step/acestep-transcriber) | なし | 誤字の可能性あり | 高難度（モデルのデプロイが必要） | セルフホスト |\n| [Gemini](https://aistudio.google.com/) | あり | 誤字の可能性あり | 簡単 | 有料API |\n| [Whisper](https://github.com/openai/whisper) | なし | 誤字の可能性あり | 普通 | セルフホスト / 有料API |\n| [ElevenLabs](https://elevenlabs.io/app/developers) | なし | 誤字の可能性あり | 普通 | 有料API（無料枠あり） |\n\n本プロジェクトでは `scripts/lora_data_prepare/` に対応する文字起こしスクリプトを提供しています：\n\n- `whisper_transcription.py` — OpenAI Whisper APIによる文字起こし\n- `elevenlabs_transcription.py` — ElevenLabs Scribe APIによる文字起こし\n\n両スクリプトとも `process_folder()` メソッドによるフォルダ一括処理に対応しています。\n\n#### 確認とクリーニング（必須）\n\n文字起こしされた歌詞には誤字が含まれる可能性があり、**手動で確認・修正する必要があります**。\n\nLRC形式の歌詞を使用している場合は、タイムスタンプを除去する必要があります。以下は簡単なクリーニング例です：\n\n```python\nimport re\n\ndef clean_lrc_content(lines):\n    \"\"\"LRCファイルの内容をクリーニングし、タイムスタンプを除去\"\"\"\n    result = []\n    for line in lines:\n        line = line.strip()\n        if not line:\n            continue\n        # タイムスタンプを除去 [mm:ss.x] [mm:ss.xx] [mm:ss.xxx]\n        cleaned = re.sub(r\"\\[\\d{2}:\\d{2}\\.\\d{1,3}\\]\", \"\", line)\n        result.append(cleaned)\n\n    # 末尾の空行を除去\n    while result and not result[-1]:\n        result.pop()\n\n    return result\n```\n\n#### 構造化タグ（任意）\n\n歌詞に構造化タグ（`[Verse]`、`[Chorus]` など）が含まれていると、モデルが楽曲構造をより効果的に学習できます。構造化タグがなくてもトレーニングは可能です。\n\n> **ヒント：** [Gemini](https://aistudio.google.com/) を使用して既存の歌詞に構造化タグを追加できます。\n\n例：\n\n```\n[Intro]\nLa la la...\n\n[Verse 1]\nWalking down the empty street\nEchoes dancing at my feet\n\n[Chorus]\nWe are the stars tonight\nShining through the endless sky\n\n[Bridge]\nClose your eyes and feel the sound\n```\n\n---\n\n### 自動アノテーション\n\n#### 1. BPMとKeyの取得\n\n[Key-BPM-Finder](https://vocalremover.org/key-bpm-finder) を使用してBPMとキーのアノテーションをオンラインで取得します：\n\n1. ウェブページを開き、**Browse my files** をクリックして処理する音声ファイルを選択します（一度に多すぎるとフリーズする場合があります。分割して処理し、CSVを結合することを推奨）。処理はローカルで行われ、サーバーにはアップロードされません。\n   ![key-bpm-finder-0.jpg](../pics/key-bpm-finder-0.jpg)\n\n2. 処理完了後、**Export CSV** をクリックしてCSVファイルをダウンロードします。\n   ![key-bpm-finder-1.jpg](../pics/key-bpm-finder-1.jpg)\n\n3. CSVファイルの内容例：\n\n   ```csv\n   File,Artist,Title,BPM,Key,Camelot\n   song1.wav,,,190,D major,10B\n   song2.wav,,,128,A minor,8A\n   ```\n\n4. CSVファイルをデータセットフォルダに配置します。キャプションデータを追加する場合は、`Camelot` 列の後に新しい列を追加してください。\n\n#### 2. Captionの取得\n\n以下の方法で楽曲のキャプションを取得できます：\n\n- **acestep-5Hz-lmを使用**（0.6B / 1.7B / 4B）— Gradio UIのAuto Label機能から呼び出し（後続の手順を参照）\n- **Gemini APIを使用** — スクリプト `scripts/lora_data_prepare/gemini_caption.py` を参照。`process_folder()` による一括処理に対応し、各音声ファイルに対して以下を生成します：\n  - `{ファイル名}.lyrics.txt` — 歌詞\n  - `{ファイル名}.caption.txt` — キャプション\n\n---\n\n## データの前処理\n\nデータの準備が完了したら、Gradio UIを使用してデータの確認と前処理を行います。\n\n> **重要：** 起動スクリプトを使用する場合、サービスの事前初期化を無効にするために起動パラメータを変更する必要があります：\n>\n> - **Windows** (`start_gradio_ui.bat`)：`if not defined INIT_SERVICE set INIT_SERVICE=--init_service true` を `if not defined INIT_SERVICE set INIT_SERVICE=--init_service false` に変更\n> - **Linux/macOS** (`start_gradio_ui.sh`)：`: \"${INIT_SERVICE:=--init_service true}\"` を `: \"${INIT_SERVICE:=--init_service false}\"` に変更\n\nGradio UIを起動します（起動スクリプトまたは `acestep/acestep_v15_pipeline.py` を直接実行）。\n\n### ステップ 1：モデルの読み込み\n\n- **LMでキャプションを生成する場合：** 初期化時に使用したいLMモデル（acestep-5Hz-lm-0.6B / 1.7B / 4B）を選択します。\n  ![](../pics/00_select_model_to_load.jpg)\n\n- **LMを使用しない場合：** LMモデルを選択しないでください。\n  ![](../pics/00_select_model_to_load_1.jpg)\n\n### ステップ 2：データの読み込み\n\n**LoRA Training** タブに切り替え、データセットディレクトリのパスを入力し、**Scan** をクリックします。\n\nスキャナーは以下のファイルを自動認識します：\n\n| ファイル | 説明 |\n|---------|------|\n| `*.mp3` / `*.wav` / `*.flac` / ... | 音声ファイル |\n| `{ファイル名}.lyrics.txt`（または `{ファイル名}.txt`） | 歌詞 |\n| `{ファイル名}.caption.txt` | キャプション |\n| `{ファイル名}.json` | アノテーションメタデータ（caption / bpm / keyscale / timesignature / language） |\n| `*.csv` | BPM / Key の一括アノテーション（Key-BPM-Finderからエクスポート） |\n\n![](../pics/01_load_dataset_path.jpg)\n\n### ステップ 3：データセットのプレビューと調整\n\n- **Duration** — 音声ファイルから自動的に読み取り\n- **Lyrics** — 対応する `.lyrics.txt` ファイルが必要（`.txt` も対応）\n- **Labeled** — キャプションがある場合は ✅、ない場合は ❌ と表示\n- **BPM / Key / Caption** — JSONまたはCSVファイルから読み込み\n- データセットがすべてインストゥルメンタルでない場合は、**All Instrumental** のチェックを外してください\n- **Format Lyrics** と **Transcribe Lyrics** は現在無効化されています（[acestep-transcriber](https://huggingface.co/ACE-Step/acestep-transcriber) 未接続のため、LMの直接使用はハルシネーションが発生しやすい）\n- **Custom Trigger Tag** を入力してください（現在は効果が限定的です。`Replace Caption` 以外であれば問題ありません）\n- **Genre Ratio** はキャプションの代わりにジャンルを使用するサンプルの割合を制御します。現在のLMが生成するジャンル記述はキャプションに遠く及ばないため、0のままにして��ださい\n\n![](../pics/02_preview_dataset.jpg)\n\n### ステップ 4：Auto Label Data\n\n- 既にキャプションがある場合は、このステップをスキップできます\n- データにキャプションがない場合は、LM推論で生成できます\n- BPM / Key の値が不足している場合は、まず [Key-BPM-Finder](https://vocalremover.org/key-bpm-finder) で取得してください。LMによる直接生成はハルシネーションが発生します\n\n![](../pics/03_label_data.jpg)\n\n### ステップ 5：データのプレビューと編集\n\n必要に応じて、データを一件ずつ確認・修正できます。**各データの編集後は必ず保存をクリックしてください。**\n\n![](../pics/04_edit_data.jpg)\n\n### ステップ 6：データセットの保存\n\n保存パスを入力し、データセットをJSONファイルとして保存します。\n\n![](../pics/05_save_dataset.jpg)\n\n### ステップ 7：前処理によるTensorファイルの生成\n\n> **注意：** 以前にLMでキャプションを生成し、VRAMが不足している場合は、まずGradioを再起動してVRAMを解放してください。再起動時は**LMモデルを選択しないでください**。再起動後、保存したJSONファイルのパスを入力して読み込みます。\n\nTensorファイルの保存パスを入力し、前処理を開始して完了を待ちます。\n\n![](../pics/06_preprocess_tensor.jpg)\n\n---\n\n## トレーニング\n\n> **注意：** Tensorファイル生成後も、VRAMを解放するためにGradioを再起動することを推奨します。\n\n1. **Train LoRA** タブに切り替え、Tensorファイルのパスを入力してデータセットを読み込みます。\n2. トレーニングパラメータに詳しくない場合は、デフォルト値で問題ありません。\n\n### パラメータ参考\n\n| パラメータ | 説明 | 推奨値 |\n|-----------|------|--------|\n| **Max Epochs** | データセットのサイズに応じて調整 | 約100曲 → 500エポック、10〜20曲 → 800エポック（参考値） |\n| **Batch Size** | VRAMに余裕がある場合は増加可能 | 1（デフォルト）、VRAMが十分であれば 2 または 4 |\n| **Save Every N Epochs** | チェックポイントの保存間隔 | Max Epochsが小さい場合は短く、大きい場合は長く設定 |\n\n> 上記の数値は参考値です。実際の状況に応じて調整してください。\n\n> **💡 LoKr のおすすめ：** LoKR はトレーニング効率を大幅に向上させました。以前は1時間かかっていたトレーニングが、わずか5分で完了します——10倍以上の高速化です。これは消費者向けGPUでのトレーニングにとって非常に重要です。**Train LoKr** タブで LoKr トレーニングをお試しいただくか、[Side-Step](https://github.com/koda-dernet/Side-Step) ツールキットでCLIベースの LoKr ワークフローをご利用ください。詳細は [Training Guide](../sidestep/Training%20Guide.md) をご参照ください。\n\n3. **Start Training** をクリックし、トレーニングの完了を待ちます。\n\n![](../pics/07_train.jpg)\n\n---\n\n## LoRAの使用\n\n1. トレーニング完了後、**Gradioを再起動**し、モデルを再読み込みします（LMモデルは選択しないでください）。\n2. モデルの初期化完了後、トレーニング済みのLoRAウェイトを読み込みます。\n   ![](../pics/08_load_lora.jpg)\n3. 音楽生成を開始します。\n\nおめでとうございます！LoRAトレーニングの全プロセスが完了しました。\n\n---\n\n## 高度なトレーニング：Side-Step\n\nLoRAトレーニングをより細かく制御したい場合——修正されたタイムステップサンプリング、LoKRアダプター、CLIベースのワークフロー、VRAM最適化、勾配感度分析など——コミュニティ開発の **[Side-Step](https://github.com/koda-dernet/Side-Step)** ツールキットが高度な代替手段を提供します。ドキュメントは本リポジトリの `docs/sidestep/` に収録されています。\n\n| トピック | 説明 |\n|---------|------|\n| [Getting Started](../sidestep/Getting%20Started.md) | インストール、前提条件、初回セットアップ |\n| [End-to-End Tutorial](../sidestep/End-to-End%20Tutorial.md) | 生音声ファイルから生成までの完全ガイド |\n| [Dataset Preparation](../sidestep/Dataset%20Preparation.md) | JSONスキーマ、音声形式、メタデータフィールド、カスタムタグ |\n| [Training Guide](../sidestep/Training%20Guide.md) | LoRA vs LoKR、修正モード vs バニラモード、ハイパーパラメータガイド |\n| [Using Your Adapter](../sidestep/Using%20Your%20Adapter.md) | 出力ディレクトリ構造、Gradioでの読み込み、LoKRの制限 |\n| [VRAM Optimization Guide](../sidestep/VRAM%20Optimization%20Guide.md) | VRAM最適化戦略とGPUティア別設定 |\n| [Estimation Guide](../sidestep/Estimation%20Guide.md) | ターゲットトレーニングのための勾配感度分析 |\n| [Shift and Timestep Sampling](../sidestep/Shift%20and%20Timestep%20Sampling.md) | トレーニングタイムステップの仕組みとSide-Stepの違い |\n| [Preset Management](../sidestep/Preset%20Management.md) | ビルトインプリセット、保存/読み込み/インポート/エクスポート |\n| [The Settings Wizard](../sidestep/The%20Settings%20Wizard.md) | ウィザード設定の完全リファレンス |\n| [Model Management](../sidestep/Model%20Management.md) | チェックポイント構造とファインチューンサポート |\n| [Windows Notes](../sidestep/Windows%20Notes.md) | Windows固有のセットアップと回避策 |\n"
  },
  {
    "path": "docs/ja/Openrouter_API_DOC.md",
    "content": "# ACE-Step OpenRouter API ドキュメント\n\n> OpenAI Chat Completions 互換の AI 音楽生成 API\n\n**ベース URL:** `http://{host}:{port}`（デフォルト `http://127.0.0.1:8002`）\n\n---\n\n## 目次\n\n- [認証](#認証)\n- [エンドポイント一覧](#エンドポイント一覧)\n  - [POST /v1/chat/completions - 音楽生成](#1-音楽生成)\n  - [GET /v1/models - モデル一覧](#2-モデル一覧)\n  - [GET /health - ヘルスチェック](#3-ヘルスチェック)\n- [入力モード](#入力モード)\n- [オーディオ入力](#オーディオ入力)\n- [ストリーミングレスポンス](#ストリーミングレスポンス)\n- [リクエスト例](#リクエスト例)\n- [エラーコード](#エラーコード)\n\n---\n\n## 認証\n\nサーバーに API キーが設定されている場合（環境変数 `OPENROUTER_API_KEY` または起動パラメータ `--api-key`）、すべてのリクエストに以下のヘッダーが必要です：\n\n```\nAuthorization: Bearer <your-api-key>\n```\n\nAPI キーが未設定の場合、認証は不要です。\n\n---\n\n## エンドポイント一覧\n\n### 1. 音楽生成\n\n**POST** `/v1/chat/completions`\n\nチャットメッセージから音楽を生成し、オーディオデータと LM が生成したメタ情報を返します。\n\n#### リクエストパラメータ\n\n| フィールド | 型 | 必須 | デフォルト | 説明 |\n|---|---|---|---|---|\n| `model` | string | いいえ | 自動 | モデル ID（`/v1/models` から取得） |\n| `messages` | array | **はい** | - | チャットメッセージリスト。[入力モード](#入力モード)を参照 |\n| `stream` | boolean | いいえ | `false` | ストリーミングレスポンスを有効にする。[ストリーミングレスポンス](#ストリーミングレスポンス)を参照 |\n| `audio_config` | object | いいえ | `null` | オーディオ生成設定。下記参照 |\n| `temperature` | float | いいえ | `0.85` | LM サンプリング温度 |\n| `top_p` | float | いいえ | `0.9` | LM nucleus sampling パラメータ |\n| `seed` | int \\| string | いいえ | `null` | ランダムシード。`batch_size > 1` の場合、カンマ区切りで複数指定可能（例: `\"42,123,456\"`） |\n| `lyrics` | string | いいえ | `\"\"` | 歌詞を直接指定（messages から解析された歌詞より優先）。設定時、messages テキストは prompt として扱われる |\n| `sample_mode` | boolean | いいえ | `false` | LLM sample モードを有効化。messages テキストが sample_query として LLM に渡され、prompt/lyrics が自動生成される |\n| `thinking` | boolean | いいえ | `false` | LLM の thinking モード（深い推論）を有効にする |\n| `use_format` | boolean | いいえ | `false` | ユーザーが prompt/lyrics を提供した場合、LLM でフォーマット・強化する |\n| `use_cot_caption` | boolean | いいえ | `true` | CoT で音楽説明文を書き換え・強化する |\n| `use_cot_language` | boolean | いいえ | `true` | CoT でボーカル言語を自動検出する |\n| `guidance_scale` | float | いいえ | `7.0` | Classifier-free guidance scale |\n| `batch_size` | int | いいえ | `1` | 生成するオーディオの数 |\n| `task_type` | string | いいえ | `\"text2music\"` | タスクタイプ。[オーディオ入力](#オーディオ入力)を参照 |\n| `repainting_start` | float | いいえ | `0.0` | repaint 領域の開始位置（秒） |\n| `repainting_end` | float | いいえ | `null` | repaint 領域の終了位置（秒） |\n| `audio_cover_strength` | float | いいえ | `1.0` | カバー強度（0.0〜1.0） |\n\n#### audio_config オブジェクト\n\n| フィールド | 型 | デフォルト | 説明 |\n|---|---|---|---|\n| `duration` | float | `null` | オーディオの長さ（秒）。省略時は LM が自動決定 |\n| `bpm` | integer | `null` | テンポ（BPM）。省略時は LM が自動決定 |\n| `vocal_language` | string | `\"en\"` | ボーカル言語コード（例: `\"zh\"`, `\"en\"`, `\"ja\"`） |\n| `instrumental` | boolean | `null` | インストゥルメンタル（ボーカルなし）かどうか。省略時は歌詞に基づき自動判定 |\n| `format` | string | `\"mp3\"` | 出力オーディオフォーマット |\n| `key_scale` | string | `null` | 調号（例: `\"C major\"`） |\n| `time_signature` | string | `null` | 拍子（例: `\"4/4\"`） |\n\n> **messages テキストの意味はモードにより異なります：**\n> - `lyrics` を設定 → messages テキスト = caption\n> - `sample_mode: true` を設定 → messages テキスト = sample_query（LLM にすべて生成させる）\n> - どちらも未設定 → 自動検出：タグがあればタグモード、歌詞らしければ歌詞モード、それ以外は caption としてそのまま生成に使用\n\n#### messages フォーマット\n\nプレーンテキストとマルチモーダル（テキスト＋オーディオ）の2つの形式をサポート：\n\n**プレーンテキスト：**\n\n```json\n{\n  \"messages\": [\n    {\"role\": \"user\", \"content\": \"入力内容\"}\n  ]\n}\n```\n\n**マルチモーダル（オーディオ入力あり）：**\n\n```json\n{\n  \"messages\": [\n    {\n      \"role\": \"user\",\n      \"content\": [\n        {\"type\": \"text\", \"text\": \"この曲をカバーして\"},\n        {\n          \"type\": \"input_audio\",\n          \"input_audio\": {\n            \"data\": \"<base64 オーディオデータ>\",\n            \"format\": \"mp3\"\n          }\n        }\n      ]\n    }\n  ]\n}\n```\n\n---\n\n#### 非ストリーミングレスポンス (`stream: false`)\n\n```json\n{\n  \"id\": \"chatcmpl-a1b2c3d4e5f6g7h8\",\n  \"object\": \"chat.completion\",\n  \"created\": 1706688000,\n  \"model\": \"acemusic/acestep-v15-turbo\",\n  \"choices\": [\n    {\n      \"index\": 0,\n      \"message\": {\n        \"role\": \"assistant\",\n        \"content\": \"## Metadata\\n**Caption:** Upbeat pop song...\\n**BPM:** 120\\n**Duration:** 30s\\n**Key:** C major\\n\\n## Lyrics\\n[Verse 1]\\nHello world...\",\n        \"audio\": [\n          {\n            \"type\": \"audio_url\",\n            \"audio_url\": {\n              \"url\": \"data:audio/mpeg;base64,SUQzBAAAAAAAI1RTU0UAAAA...\"\n            }\n          }\n        ]\n      },\n      \"finish_reason\": \"stop\"\n    }\n  ],\n  \"usage\": {\n    \"prompt_tokens\": 10,\n    \"completion_tokens\": 100,\n    \"total_tokens\": 110\n  }\n}\n```\n\n**レスポンスフィールド説明：**\n\n| フィールド | 説�� |\n|---|---|\n| `choices[0].message.content` | LM が生成したテキスト情報。Metadata（Caption/BPM/Duration/Key/Time Signature/Language）と Lyrics を含む。LM が関与していない場合は `\"Music generated successfully.\"` を返す |\n| `choices[0].message.audio` | オーディオデータ配列。各項目に `type`（`\"audio_url\"`）と `audio_url.url`（Base64 Data URL、形式: `data:audio/mpeg;base64,...`）を含む |\n| `choices[0].finish_reason` | `\"stop\"` は正常完了を示す |\n\n**オーディオのデコード方法：**\n\n`audio_url.url` の値は Data URL 形式です: `data:audio/mpeg;base64,<base64_data>`\n\nカンマ以降の base64 データ部分を抽出してデコードすると MP3 ファイルが得られます：\n\n```python\nimport base64\n\nurl = response[\"choices\"][0][\"message\"][\"audio\"][0][\"audio_url\"][\"url\"]\n# \"data:audio/mpeg;base64,\" プレフィックスを除去\nb64_data = url.split(\",\", 1)[1]\naudio_bytes = base64.b64decode(b64_data)\n\nwith open(\"output.mp3\", \"wb\") as f:\n    f.write(audio_bytes)\n```\n\n```javascript\nconst url = response.choices[0].message.audio[0].audio_url.url;\nconst b64Data = url.split(\",\")[1];\nconst audioBytes = atob(b64Data);\n// Data URL を直接 <audio> タグで使用可能\nconst audio = new Audio(url);\naudio.play();\n```\n\n---\n\n### 2. モデル一覧\n\n**GET** `/v1/models`\n\n利用可能なモデル情報を返します。\n\n#### レスポンス\n\n```json\n{\n  \"data\": [\n    {\n      \"id\": \"acemusic/acestep-v15-turbo\",\n      \"name\": \"ACE-Step\",\n      \"created\": 1706688000,\n      \"description\": \"High-performance text-to-music generation model. Supports multiple styles, lyrics input, and various audio durations.\",\n      \"input_modalities\": [\"text\", \"audio\"],\n      \"output_modalities\": [\"audio\", \"text\"],\n      \"context_length\": 4096,\n      \"pricing\": {\"prompt\": \"0\", \"completion\": \"0\", \"request\": \"0\"},\n      \"supported_sampling_parameters\": [\"temperature\", \"top_p\"]\n    }\n  ]\n}\n```\n\n---\n\n### 3. ヘルスチェック\n\n**GET** `/health`\n\n#### レスポンス\n\n```json\n{\n  \"status\": \"ok\",\n  \"service\": \"ACE-Step OpenRouter API\",\n  \"version\": \"1.0\"\n}\n```\n\n---\n\n## 入力モード\n\nシステムは最後の `user` メッセージの内容に基づいて入力モードを自動選択します。`lyrics` または `sample_mode` フィールドで明示的に指定することも可能です。\n\n### モード 1: タグモード（推奨）\n\n`<prompt>` と `<lyrics>` タグを使用して、音楽の説明と歌詞を明示的に指定します：\n\n```json\n{\n  \"messages\": [\n    {\n      \"role\": \"user\",\n      \"content\": \"<prompt>A gentle acoustic ballad in C major, female vocal</prompt>\\n<lyrics>[Verse 1]\\nSunlight through the window\\nA brand new day begins\\n\\n[Chorus]\\nWe are the dreamers\\nWe are the light</lyrics>\"\n    }\n  ],\n  \"audio_config\": {\n    \"duration\": 30,\n    \"vocal_language\": \"en\"\n  }\n}\n```\n\n- `<prompt>...</prompt>` — 音楽のスタイル・シーンの説明（キャプション）\n- `<lyrics>...</lyrics>` — 歌詞の内容\n- どちらか一方のタグだけでも使用可能\n- `use_format: true` の場合、LLM が prompt と lyrics を自動的に強化\n\n### モード 2: 自然言語モード（サンプルモード）\n\n自然言語で欲しい音楽を記述すると、システムが LLM を使って prompt と lyrics を自動生成します：\n\n```json\n{\n  \"messages\": [\n    {\"role\": \"user\", \"content\": \"夏と旅行をテーマにした明るい日本語のポップソングを作ってください\"}\n  ],\n  \"sample_mode\": true,\n  \"audio_config\": {\n    \"vocal_language\": \"ja\"\n  }\n}\n```\n\nトリガー条件：`sample_mode: true`、またはメッセージにタグが含まれず歌詞らしくない内容の場合に自動トリガー。\n\n### モード 3: 歌詞のみモード\n\n構造マーカー付きの歌詞を直接渡すと、システムが自動認識します：\n\n```json\n{\n  \"messages\": [\n    {\n      \"role\": \"user\",\n      \"content\": \"[Verse 1]\\nWalking down the street\\nFeeling the beat\\n\\n[Chorus]\\nDance with me tonight\\nUnder the moonlight\"\n    }\n  ],\n  \"audio_config\": {\"duration\": 30}\n}\n```\n\nトリガー条件：メッセージに `[Verse]`、`[Chorus]` などのマーカーが含まれている、または複数行の短いテキスト構造を持つ場合。\n\n### モード 4: 歌詞 + Prompt 分離\n\n`lyrics` フィールドで歌詞を直接渡し、messages テキストは自動的に prompt として扱われます：\n\n```json\n{\n  \"messages\": [\n    {\"role\": \"user\", \"content\": \"Energetic EDM with heavy bass drops\"}\n  ],\n  \"lyrics\": \"[Verse 1]\\nFeel the rhythm in your soul\\nLet the music take control\\n\\n[Drop]\\n(instrumental break)\",\n  \"audio_config\": {\n    \"bpm\": 128,\n    \"duration\": 60\n  }\n}\n```\n\n### インストゥルメンタルモード\n\n`audio_config.instrumental: true` を設定：\n\n```json\n{\n  \"messages\": [\n    {\"role\": \"user\", \"content\": \"<prompt>Epic orchestral cinematic score, dramatic and powerful</prompt>\"}\n  ],\n  \"audio_config\": {\n    \"instrumental\": true,\n    \"duration\": 30\n  }\n}\n```\n\n---\n\n## オーディオ入力\n\nマルチモーダル messages でオーディオファイル（base64 エンコード）を渡すことで、cover、repaint などのタスクに使用できます。\n\n### task_type タイプ\n\n| task_type | 説明 | オーディオ入力 |\n|---|---|---|\n| `text2music` | テキストから音楽生成（デフォルト） | 任意（reference として） |\n| `cover` | カバー/スタイル変換 | src_audio が必要 |\n| `repaint` | 部分的なリペイント | src_audio が必要 |\n| `lego` | オーディオ接合 | src_audio が必要 |\n| `extract` | オーディオ抽出 | src_audio が必要 |\n| `complete` | オーディオ続き生成 | src_audio が必要 |\n\n### オーディオルーティングルール\n\n複数の `input_audio` ブロックは順番に異なるパラメータにルーティングされます（複数画像アップロードと同様）：\n\n| task_type | audio[0] | audio[1] |\n|---|---|---|\n| `text2music` | reference_audio（スタイル参照） | - |\n| `cover/repaint/lego/extract/complete` | src_audio（編集対象オーディオ） | reference_audio（任意のスタイル参照） |\n\n### オーディオ入力の例\n\n**Cover タスク（カバー）：**\n\n```json\n{\n  \"messages\": [\n    {\n      \"role\": \"user\",\n      \"content\": [\n        {\"type\": \"text\", \"text\": \"<prompt>Jazz style cover with saxophone</prompt>\"},\n        {\n          \"type\": \"input_audio\",\n          \"input_audio\": {\"data\": \"<base64 元オーディオ>\", \"format\": \"mp3\"}\n        }\n      ]\n    }\n  ],\n  \"task_type\": \"cover\",\n  \"audio_cover_strength\": 0.8,\n  \"audio_config\": {\"duration\": 30}\n}\n```\n\n**Repaint タスク（部分リペイント）：**\n\n```json\n{\n  \"messages\": [\n    {\n      \"role\": \"user\",\n      \"content\": [\n        {\"type\": \"text\", \"text\": \"<prompt>Replace with guitar solo</prompt>\"},\n        {\n          \"type\": \"input_audio\",\n          \"input_audio\": {\"data\": \"<base64 元オーディオ>\", \"format\": \"mp3\"}\n        }\n      ]\n    }\n  ],\n  \"task_type\": \"repaint\",\n  \"repainting_start\": 10.0,\n  \"repainting_end\": 20.0,\n  \"audio_config\": {\"duration\": 30}\n}\n```\n\n---\n\n## ストリーミングレスポンス\n\n`\"stream\": true` を設定すると SSE（Server-Sent Events）ストリーミングが有効になります。\n\n### イベントフォーマット\n\n各イベントは `data: ` で始まり、JSON が続き、二重改行 `\\n\\n` で終了します：\n\n```\ndata: {\"id\":\"chatcmpl-xxx\",\"object\":\"chat.completion.chunk\",\"created\":1706688000,\"model\":\"acemusic/acestep-v15-turbo\",\"choices\":[{\"index\":0,\"delta\":{...},\"finish_reason\":null}]}\n\n```\n\n### ストリーミングイベントの順序\n\n| フェーズ | delta の内容 | 説明 |\n|---|---|---|\n| 1. 初期化 | `{\"role\":\"assistant\",\"content\":\"\"}` | 接続の確立 |\n| 2. LM コンテンツ | `{\"content\":\"\\n\\n## Metadata\\n...\"}` | LM 使用時に metadata と lyrics を送信 |\n| 3. ハートビート | `{\"content\":\".\"}` | オーディオ生成中に2秒ごとに送信（接続維持） |\n| 4. オーディオデータ | `{\"audio\":[{\"type\":\"audio_url\",\"audio_url\":{\"url\":\"data:...\"}}]}` | オーディオ base64 データ |\n| 5. 完了 | `finish_reason: \"stop\"` | 生成完了 |\n| 6. 終了 | `data: [DONE]` | ストリーム終了マーカー |\n\n### ストリーミングレスポンス例\n\n```\ndata: {\"id\":\"chatcmpl-abc123\",\"object\":\"chat.completion.chunk\",\"created\":1706688000,\"model\":\"acemusic/acestep-v15-turbo\",\"choices\":[{\"index\":0,\"delta\":{\"role\":\"assistant\",\"content\":\"\"},\"finish_reason\":null}]}\n\ndata: {\"id\":\"chatcmpl-abc123\",\"object\":\"chat.completion.chunk\",\"created\":1706688000,\"model\":\"acemusic/acestep-v15-turbo\",\"choices\":[{\"index\":0,\"delta\":{\"content\":\"\\n\\n## Metadata\\n**Caption:** Upbeat pop\\n**BPM:** 120\"},\"finish_reason\":null}]}\n\ndata: {\"id\":\"chatcmpl-abc123\",\"object\":\"chat.completion.chunk\",\"created\":1706688000,\"model\":\"acemusic/acestep-v15-turbo\",\"choices\":[{\"index\":0,\"delta\":{\"content\":\".\"},\"finish_reason\":null}]}\n\ndata: {\"id\":\"chatcmpl-abc123\",\"object\":\"chat.completion.chunk\",\"created\":1706688000,\"model\":\"acemusic/acestep-v15-turbo\",\"choices\":[{\"index\":0,\"delta\":{\"audio\":[{\"type\":\"audio_url\",\"audio_url\":{\"url\":\"data:audio/mpeg;base64,...\"}}]},\"finish_reason\":null}]}\n\ndata: {\"id\":\"chatcmpl-abc123\",\"object\":\"chat.completion.chunk\",\"created\":1706688000,\"model\":\"acemusic/acestep-v15-turbo\",\"choices\":[{\"index\":0,\"delta\":{},\"finish_reason\":\"stop\"}]}\n\ndata: [DONE]\n\n```\n\n### クライアント側のストリーミング処理\n\n```python\nimport json\nimport httpx\n\nwith httpx.stream(\"POST\", \"http://127.0.0.1:8002/v1/chat/completions\", json={\n    \"messages\": [{\"role\": \"user\", \"content\": \"明るいギター曲を生成してください\"}],\n    \"sample_mode\": True,\n    \"stream\": True,\n    \"audio_config\": {\"instrumental\": True}\n}) as response:\n    content_parts = []\n    audio_url = None\n\n    for line in response.iter_lines():\n        if not line or not line.startswith(\"data: \"):\n            continue\n        if line == \"data: [DONE]\":\n            break\n\n        chunk = json.loads(line[6:])\n        delta = chunk[\"choices\"][0][\"delta\"]\n\n        if \"content\" in delta and delta[\"content\"]:\n            content_parts.append(delta[\"content\"])\n\n        if \"audio\" in delta and delta[\"audio\"]:\n            audio_url = delta[\"audio\"][0][\"audio_url\"][\"url\"]\n\n        if chunk[\"choices\"][0].get(\"finish_reason\") == \"stop\":\n            print(\"生成完了！\")\n\n    print(\"Content:\", \"\".join(content_parts))\n    if audio_url:\n        import base64\n        b64_data = audio_url.split(\",\", 1)[1]\n        with open(\"output.mp3\", \"wb\") as f:\n            f.write(base64.b64decode(b64_data))\n```\n\n```javascript\nconst response = await fetch(\"http://127.0.0.1:8002/v1/chat/completions\", {\n  method: \"POST\",\n  headers: { \"Content-Type\": \"application/json\" },\n  body: JSON.stringify({\n    messages: [{ role: \"user\", content: \"明るいギター曲を生成してください\" }],\n    sample_mode: true,\n    stream: true,\n    audio_config: { instrumental: true }\n  })\n});\n\nconst reader = response.body.getReader();\nconst decoder = new TextDecoder();\nlet audioUrl = null;\nlet content = \"\";\n\nwhile (true) {\n  const { done, value } = await reader.read();\n  if (done) break;\n\n  const text = decoder.decode(value);\n  for (const line of text.split(\"\\n\")) {\n    if (!line.startsWith(\"data: \") || line === \"data: [DONE]\") continue;\n\n    const chunk = JSON.parse(line.slice(6));\n    const delta = chunk.choices[0].delta;\n\n    if (delta.content) content += delta.content;\n    if (delta.audio) audioUrl = delta.audio[0].audio_url.url;\n  }\n}\n\n// audioUrl は <audio src=\"...\"> で直接使用可能\n```\n\n---\n\n## リクエスト例\n\n### 例 1: 自然言語生成（最もシンプルな使い方）\n\n```bash\ncurl -X POST http://127.0.0.1:8002/v1/chat/completions \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\n    \"messages\": [\n      {\"role\": \"user\", \"content\": \"故郷と思い出についての優しい日本語のフォークソング\"}\n    ],\n    \"sample_mode\": true,\n    \"audio_config\": {\"vocal_language\": \"ja\"}\n  }'\n```\n\n### 例 2: タグモード + パラメータ指定\n\n```bash\ncurl -X POST http://127.0.0.1:8002/v1/chat/completions \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\n    \"messages\": [\n      {\n        \"role\": \"user\",\n        \"content\": \"<prompt>Energetic EDM track with heavy bass drops and synth leads</prompt><lyrics>[Verse 1]\\nFeel the rhythm in your soul\\nLet the music take control\\n\\n[Drop]\\n(instrumental break)</lyrics>\"\n      }\n    ],\n    \"audio_config\": {\n      \"bpm\": 128,\n      \"duration\": 60,\n      \"vocal_language\": \"en\"\n    }\n  }'\n```\n\n### 例 3: インストゥルメンタル + LM 強化無効\n\n```bash\ncurl -X POST http://127.0.0.1:8002/v1/chat/completions \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\n    \"messages\": [\n      {\n        \"role\": \"user\",\n        \"content\": \"<prompt>Peaceful piano solo, slow tempo, jazz harmony</prompt>\"\n      }\n    ],\n    \"use_cot_caption\": false,\n    \"audio_config\": {\n      \"instrumental\": true,\n      \"duration\": 45\n    }\n  }'\n```\n\n### 例 4: ストリーミングリクエスト\n\n```bash\ncurl -X POST http://127.0.0.1:8002/v1/chat/completions \\\n  -H \"Content-Type: application/json\" \\\n  -N \\\n  -d '{\n    \"messages\": [\n      {\"role\": \"user\", \"content\": \"誕生日おめでとうの歌を作ってください\"}\n    ],\n    \"sample_mode\": true,\n    \"stream\": true\n  }'\n```\n\n### 例 5: マルチシード バッチ生成\n\n```bash\ncurl -X POST http://127.0.0.1:8002/v1/chat/completions \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\n    \"messages\": [\n      {\"role\": \"user\", \"content\": \"<prompt>Lo-fi hip hop beat</prompt>\"}\n    ],\n    \"batch_size\": 3,\n    \"seed\": \"42,123,456\",\n    \"audio_config\": {\n      \"instrumental\": true,\n      \"duration\": 30\n    }\n  }'\n```\n\n---\n\n## エラーコード\n\n| HTTP ステータス | 説明 |\n|---|---|\n| 400 | リクエスト形式が不正、または有効な入力がない |\n| 401 | API キーが未指定、または無効 |\n| 429 | サービスがビジー状態、キューが満杯 |\n| 500 | 音楽生成中に内部エラーが発生 |\n| 503 | モデルがまだ初期化されていない |\n| 504 | 生成タイムアウト |\n\nエラーレスポンス形式：\n\n```json\n{\n  \"detail\": \"エラーの説明メッセージ\"\n}\n```\n\n---\n\n## サーバー設定（環境変数）\n\n以下の環境変数でサーバーを設定できます（運用担当者向け）：\n\n| 変数名 | デフォルト | 説明 |\n|---|---|---|\n| `OPENROUTER_API_KEY` | なし | API 認証キー |\n| `OPENROUTER_HOST` | `127.0.0.1` | リッスンアドレス |\n| `OPENROUTER_PORT` | `8002` | リッスンポート |\n| `ACESTEP_CONFIG_PATH` | `acestep-v15-turbo` | DiT モデル設定パス |\n| `ACESTEP_DEVICE` | `auto` | 推論デバイス |\n| `ACESTEP_LM_MODEL_PATH` | `acestep-5Hz-lm-0.6B` | LLM モデルパス |\n| `ACESTEP_LM_BACKEND` | `vllm` | LLM 推論バックエンド |\n| `ACESTEP_QUEUE_MAXSIZE` | `200` | タスクキューの最大容量 |\n| `ACESTEP_GENERATION_TIMEOUT` | `600` | 非ストリーミングリクエストのタイムアウト（秒） |\n"
  },
  {
    "path": "docs/ja/Tutorial.md",
    "content": "# ACE-Step 1.5 究極ガイド（必読）\n\n**Language / 语言 / 言語:** [English](../en/Tutorial.md) | [中文](../zh/Tutorial.md) | [日本語](Tutorial.md)\n\n---\n\nこんにちは、ACE-Stepの開発者、龔俊民です。このチュートリアルを通じて、ACE-Step 1.5の設計哲学と使用方法をご紹介します。\n\n## メンタルモデル\n\n始める前に、適切な期待管理のために正しいメンタルモデルを確立する必要があります。\n\n### 人間中心の設計\n\nこのモデルは**ワンクリック生成**のためではなく、**人間中心の生成**のために設計されています。\n\nこの違いを理解することが重要です。\n\n### ワンクリック生成とは？\n\nプロンプトを入力し、生成をクリックし、いくつかのバージョンを聞いて、良さそうなものを選んで使用します。別の人が同じプロンプトを入力すると、おそらく似た結果が得られます。\n\nこのモードでは、あなたとAIは**クライアントとベンダー**の関係です。明確な目的を持って来て、頭の中に曖昧な期待があり、AIがその期待に近い製品を提供することを望みます。本質的には、Googleで検索したり、Spotifyで曲を探したりするのと大差ありません——カスタマイズが少し増えただけです。\n\nAIはサービスであり、創造的なインスピレーションを与えるものではありません。\n\nSuno、Udio、MiniMax、Mureka——これらのプラットフォームはすべてこの設計思想を持っています。モデルを大きくしてサービスとして提供すればよいのです。あなたが生成した音楽は彼らの契約に縛られます；ローカルで実行できず、パーソナライズされた探索のために微調整できません；彼らが密かにモデルや条項を変更しても、あなたはそれを受け入れるしかありません。\n\n### 人間中心の生成とは？\n\nAIの層を弱め、人間の層を強化する——より多くの人間の意志、創造性、インスピレーションがAIに生命を与える——これが人間中心の生成です。\n\nワンクリック生成の強い目的性とは異なり、人間中心の生成はより**遊び**の性質を持っています。それは対話的なゲームのようなもので、あなたとモデルは**協力者**の関係です。\n\nワークフローは次のとおりです：いくつかのインスピレーションの種を投げ、いくつかの曲を得て、そこから興味深い方向を選択して反復を続けます——\n- プロンプトを調整して再生成\n- **Cover**を使用して構造を維持し、詳細を調整\n- **Repaint**で局所的な変更\n- **Add Layer**で楽器の層を追加または削除\n\nこの時点で、AIはあなたにとってサービス提供者ではなく、**インスピレーションを与えるもの**です。\n\n### この設計はどのような条件を満たす必要があるか？\n\n人間中心の生成を真に機能させるには、モデルがいくつかの重要な条件を満たす必要があります：\n\n**第一に、オープンソースで、ローカルで実行可能で、訓練可能でなければなりません。**\n\nこれは技術的な純粋主義ではなく、所有権の問題です。クローズドソースのプラットフォームを使用すると、モデルを所有せず、生成した作品も彼らの契約に縛られます。バージョン更新、条項変更、サービスの停止——これらはすべてあなたの制御下にありません。\n\nしかし、モデルがオープンソースでローカル実行可能な場合、すべてが変わります：**あなたは永遠にこのモデルを所有し、あなたとモデルが一緒に作成したすべての産物を永遠に所有します。** サードパーティの契約の煩わしさがなく、プラットフォームのリスクもなく、微調整、改造、それに基づいて独自の創作システムを構築できます。あなたの作品は永遠にあなたのものです。それは楽器を買うようなものです——いつでもどこでも使用でき、いつでもどこでも調整できます。\n\n**第二に、速くなければなりません。**\n\n人間の時間は貴重ですが、さらに重要なのは——**遅い生成はフロー状態を破壊する**ことです。\n\n人間中心のワークフローの核心は、「試す、聞く、調整する」の迅速なサイクルです。各生成に数分かかる場合、待機中にインスピレーションが消え、「遊び」の体験が「待つ」苦痛に退化します。\n\nしたがって、私たちはACE-Stepをこれに特化して最適化しました：品質を保証しながら、生成を十分に速くし、スムーズな人間と機械の対話リズムを支えることができるようにしました。\n\n### 有限ゲーム vs 無限ゲーム\n\nワンクリック生成は**有限ゲーム**です——明確な目標、結果指向、終点で終了します。ある程度、それは音楽産業を冷たく空洞化し、多くの人の仕事を置き換えました。\n\n人間中心の生成は**無限ゲーム**です——楽しみはプロセスの中にあり、プロセスは決して終わらないからです。\n\n私たちのビジョンは、AI音楽生成を民主化することです。ACE-Stepをあなたのポケットの中の大きなおもちゃにし、音楽を**Play**そのものに戻す——創造的な「遊び」であり、単に再生をクリックするだけではありません。\n\n---\n\n## 象使いのメタファー\n\n> 推奨読書：[The Complete Guide to Mastering Suno](https://www.notion.so/The-Complete-Guide-to-Mastering-Suno-Advanced-Strategies-for-Professional-Music-Generation-2d6ae744ebdf8024be42f6645f884221)——このブログチュートリアルは、AI音楽の基礎理解を確立するのに役立ちます。\n\nAI音楽生成は、心理学の有名な**象使いのメタファー**のようなものです。\n\n意識は潜在意識の上に乗り、人間は象の上に乗ります。方向を与えることはできますが、象にすべての命令を正確に、即座に実行させることはできません。それは独自の慣性、独自の気質、独自の意志を持っています。\n\nこの象が、音楽生成モデルです。\n\n### 氷山モデル\n\nオーディオと意味の間には、隠された氷山があります。\n\n言語で説明できるもの——スタイル、楽器、音色、感情、シーン、展開、歌詞、ボーカルスタイル——これらは私たちが知っている言葉で、触れることができる部分です。しかし、それらを合わせても、オーディオという氷山が海面から浮かび上がっている小さな一角に過ぎません。\n\n最も正確な制御とは何ですか？期待されるオーディオを入力し、モデルがそれを変更せずに返すことです。\n\nしかし、テキスト記述、参照、プロンプトを使用する限り——モデルには遊ぶ余地があります。これはバグではなく、物事の本質です。\n\n### 象とは何か？\n\nこの象は無数の要素の融合です：データ分布、モデル規模、アルゴリズム設計、注釈の偏り、評価の偏り——**それは人間の音楽史とエンジニアリングのトレードオフの抽象的な結晶です。**\n\nこれらの要素のいずれかの偏差は、あなたの好みや期待を正確に反映できない原因となります。\n\nもちろん、データ規模を拡大し、アルゴリズム効率を向上させ、注釈精度を向上させ、モデル容量を拡大し、より専門的な評価システムを導入できます——これらはすべて、モデル開発者として最適化できる方向です。\n\nしかし、技術的に「完璧」を達成したとしても、回避できない根本的な問題があります：**好み。**\n\n### 好みと期待\n\n好みは人によって異なります。\n\n音楽生成モデルがすべてのリスナーを喜ばせようとすると、その出力は人間の音楽史の流行平均に向かいます——**これは極めて平凡になります。**\n\n音に意味、感情、経験、生命、文化的象徴的価値を与えるのは人間です。少数のアーティストグループが独特の好みを作り出し、その後、一般の人々を消費し、追随させ、ニッチが大衆の人気になりました。これらの少数派の先駆的なアーティストが伝説になりました。\n\nしたがって、モデルの出力が「好みに合わない」と感じた場合、これはモデルの問題ではない可能性があります——**あなたの好みがその「平均」の外にあるということです。** これは良いことです。\n\nこれは意味します：**象を自動的に理解することを期待するのではなく、この象を導く方法を学ぶ必要があるということです。**\n\n---\n\n## 象の群れを知る：モデルアーキテクチャと選択\n\n今、あなたは「象」のメタファーを理解しています。しかし実際には——\n\n**これは1頭の象ではなく、大小さまざまな象の群れ——家族を形成しています。** 🐘🐘🐘🐘\n\n### アーキテクチャの原理：2つの脳\n\nACE-Step 1.5は、2つのコアコンポーネントが協力して動作する**ハイブリッドアーキテクチャ**を使用します：\n\n```\nユーザー入力 → [5Hz LM] → セマンティックブループリント → [DiT] → オーディオ\n              ↓\n         メタデータ推論\n         Caption最適化\n         構造計画\n```\n\n**5Hz LM（言語モデル）—— 計画者（オプション）**\n\nLMは「全能的計画者」で、あなたの意図を理解し、計画を立てる責任があります：\n- **Chain-of-Thought**を通じて音楽メタデータ（BPM、キー、時間など）を推論\n- あなたのキャプションを最適化および拡張——あなたの意図の理解と補足\n- **セマンティックコード**を生成——作曲メロディ、オーケストレーション、およびいくつかの音色情報を暗黙的に含む\n\nLMは訓練データから**世界知識**を学びます。それは可用性を向上させ、迅速にプロトタイプを生成するのに役立つ計画者です。\n\n**しかし、LMは必須ではありません。**\n\n何が欲しいかが非常に明確である場合、または明確な計画目標が既にある場合——`thinking`モードを使用せず、LMの計画ステップを完全にスキップできます。\n\n例えば、**Coverモード**では、参照オーディオを使用して作曲、和音、構造を制約し、DiTに直接生成させます。ここでは、**あなたがLMの仕事を置き換えます**——あなた自身が計画者になります。\n\n別の例：**Repaintモード**では、参照オーディオをコンテキストとして使用し、音色、ミキシング、詳細を制約し、DiTに局所的に直接調整させます。この時点で、DiTは創造的なブレインストーミングパートナーのようなもので、創造的なアイデア出しを助け、局所的な不調和を修正するために使用できます。\n\n**DiT（Diffusion Transformer）—— 実行者**\n\nDiTは「オーディオ職人」で、計画を現実に変える責任があります：\n- LMが生成したセマンティックコードと条件を受信\n- **拡散プロセス**を通じてノイズから徐々にオーディオを「彫刻」\n- 最終的な音色、ミキシング、詳細を決定\n\n**なぜこの設計なのか？**\n\n従来の方法では、拡散モデルがテキストから直接オーディオを生成しますが、テキストからオーディオへのマッピングは曖昧すぎます。ACE-Stepは中間層としてLMを導入します：\n- LMは意味の理解と計画が得意\n- DiTは高忠実度オーディオの生成が得意\n- 2つが協力し、それぞれの役割を果たす\n\n### 計画者の選択：LMモデル\n\nLMには4つの選択肢があります：**LMなし**（thinkingモードを無効化）、**0.6B**、**1.7B**、**4B**。\n\nそれらの訓練データは完全に同一で、違いは純粋に**知識容量**にあります：\n- モデルが大きいほど、世界知識が豊富\n- モデルが大きいほど、記憶能力が強い（例：参照オーディオのメロディを記憶）\n- モデルが大きいほど、ロングテールのスタイルや楽器で相対的に優れたパフォーマンス\n\n| 選択 | 速度 | 世界知識 | 記憶能力 | 使用ケース |\n|------|:----:|:--------:|:--------:|----------|\n| LMなし | ⚡⚡⚡⚡ | — | — | あなたが計画を行う（例：Coverモード） |\n| `0.6B` | ⚡⚡⚡ | 基本 | 弱い | 低VRAM（< 8GB）、迅速なプロトタイピング |\n| `1.7B` | ⚡⚡ | 中程度 | 中程度 | **デフォルト推奨** |\n| `4B` | ⚡ | 豊富 | 強い | 複雑なタスク、高品質生成 |\n\n**選択方法は？**\n\nハードウェアに基づいて：\n- **VRAM < 8GB** → LMなしまたは`0.6B`\n- **VRAM 8–16GB** → `1.7B`（デフォルト）\n- **VRAM > 16GB** → `1.7B`または`4B`\n\n### 実行者の選択：DiTモデル\n\n計画スキームがあっても、実行者を選択する必要があります。DiTはACE-Step 1.5の核心——さまざまなタスクを処理し、LMが生成したコードを解釈する方法を決定します。\n\n私たちは**4つのTurboモデル**、**1つのSFTモデル**、**1つのBaseモデル**をオープンソース化しました。\n\n#### Turboシリーズ（日常使用に推奨）\n\nTurboモデルは蒸留訓練を受け、わずか8ステップで高品質オーディオを生成します。4つのバリアントの核心的な違いは、**蒸留時のshiftハイパーパラメータ設定**です。\n\n**shiftとは何か？**\n\nshiftはDiTのノイズ除去時の「注意配分」を決定します：\n- **shiftが大きい** → 初期ノイズ除去（純粋なノイズから大きな構造を構築）により多くの労力を費やす、**セマンティクスが強い**、全体的なフレームワークがより明確\n- **shiftが小さい** → ステップ配分がより均等、**詳細が多い**、ただし詳細はノイズの可能性もある\n\n簡単な理解：高shiftは「輪郭を先に描いてから詳細を埋める」、低shiftは「描きながら修正する」ようなものです。\n\n| モデル | 蒸留設定 | 特徴 |\n|--------|----------|------|\n| `turbo`（デフォルト） | shift 1、2、3で共同蒸留 | **創造性とセマンティクスの最良のバランス**、十分にテスト済み、推奨の第一選択 |\n| `turbo-shift1` | shift=1のみで蒸留 | 詳細がより豊富だが、セマンティクスは弱い |\n| `turbo-shift3` | shift=3のみで蒸留 | 音色がより明確で豊富だが、「乾いた」感じになり、オーケストレーションはミニマル |\n| `turbo-continuous` | 実験的、shift 1–5の連続調整をサポート | 調整が最も柔軟だが、十分にテストされていない |\n\n目標音楽スタイルに基づいて選択できます。特定のバリアントに好みを見つけるかもしれません。**デフォルトのturboから始めることを推奨します**——最もバランスが取れて、実証済みの選択です。\n\n#### SFTモデル\n\nTurboと比較して、SFTモデルには2つの顕著な特徴があります：\n- **CFG（Classifier-Free Guidance）をサポート**、プロンプトの遵守度を細かく調整可能\n- **ステップ数が多い**（50ステップ）、モデルに「考える」時間をより多く与える\n\n代償：ステップ数が多いということは、誤差の蓄積を意味し、オーディオの明瞭度はTurboよりわずかに劣る可能性があります。しかし、その**詳細表現とセマンティック解析はより良い**です。\n\n推論時間を気にせず、CFGとステップ数の調整が好きで、その豊かな詳細感を好む場合——SFTは良い選択です。LMが生成したコードもSFTモデルで機能します。\n\n#### Baseモデル\n\nBaseは**タスクの集大成**で、SFTとTurboを超える3つの独占タスクがあります：\n\n| タスク | 説明 |\n|--------|------|\n| `extract` | 混合オーディオから単一トラックを抽出（例：ボーカルを分離） |\n| `lego` | 既存のトラックに新しいトラックを追加（例：ギターにドラムを追加） |\n| `complete` | 単一トラックに混合伴奏を追加（例：ボーカルにギター+ドラムの伴奏を追加） |\n\nさらに、Baseは**可塑性が最も強い**です。大規模な微調整のニーズがある場合、Baseから実験を開始し、独自のSFTモデルを訓練することを推奨します。\n\n#### 独自のカスタムモデルの作成\n\n公式モデルに加えて、**LoRA微調整**を使用して独自のカスタムモデルを作成することもできます。\n\nサンプルLoRAモデルをリリースします——20曲以上の「新年おめでとう」テーマの曲で訓練され、祝祭の雰囲気を表現するのに適しています。これは出発点に過ぎません。\n\n**カスタムモデルとは何を意味するか？**\n\n独自のデータレシピでDiTの能力と好みを再形成できます：\n- 特定の音色スタイルが好きですか？そのタイプの曲で訓練\n- モデルを特定のジャンルに優れさせたいですか？関連データを収集して微調整\n- 独自の独特な美的趣味がありますか？それをモデルに「教える」\n\nこれは**カスタマイズと遊びやすさ**を大幅に拡張します——あなたの美的趣味で、あなた専用のモデルを訓練します。\n\n> LoRA訓練の詳細ガイドについては、[LoRA トレーニングチュートリアル](./LoRA_Training_Tutorial.md)を参照してください。Gradio UIの「LoRA Training」タブからワンクリックで訓練することもできます。\n\n#### DiT選択のまとめ\n\n| モデル | ステップ | CFG | 速度 | 独占タスク | 推奨シナリオ |\n|--------|:-------:|:---:|:----:|----------|------------|\n| `turbo`（デフォルト） | 8 | ❌ | ⚡⚡⚡ | — | 日常使用、迅速な反復 |\n| `sft` | 50 | ✅ | ⚡ | — | 詳細を追求、調整が好き |\n| `base` | 50 | ✅ | ⚡ | extract, lego, complete | 特殊タスク、大規模微調整 |\n\n### 組み合わせ戦略\n\nデフォルト設定は**turbo + 1.7B LM**で、ほとんどのシナリオに適しています。\n\n| ニーズ | 推奨組み合わせ |\n|--------|--------------|\n| 最速 | `turbo` + LMなしまたは`0.6B` |\n| 日常使用 | `turbo` + `1.7B`（デフォルト） |\n| 詳細を追求 | `sft` + `1.7B`または`4B` |\n| 特殊タスク | `base` |\n| 大規模微調整 | `base` |\n| 低VRAM（< 4GB） | `turbo` + LMなし + CPUオフロード |\n\n### モデルのダウンロード\n\n```bash\n# デフォルトモデルをダウンロード（turbo + 1.7B LM）\nuv run acestep-download\n\n# すべてのモデルをダウンロード\nuv run acestep-download --all\n\n# 特定のモデルをダウンロード\nuv run acestep-download --model acestep-v15-base\nuv run acestep-download --model acestep-5Hz-lm-0.6B\n\n# 利用可能なモデルを表示\nuv run acestep-download --list\n```\n\nモデルは`checkpoints`フォルダにダウンロードする必要があります。識別しやすくするためです。\n\n---\n\n## 象を導く：何を制御できるか？\n\n今、あなたはこの象の群れを知っています。次に、それらとコミュニケーションを取る方法を学びましょう。\n\n各生成は、**入力制御**、**推論ハイパーパラメータ**、**ランダム要因**の3種類の要因によって決定されます。\n\n### I. 入力制御：何が欲しいか？\n\nこれは、モデルと「創造的意図」をコミュニケーションする部分——どのような音楽を生成したいか。\n\n| カテゴリ | パラメータ | 機能 |\n|----------|-----------|------|\n| **タスクタイプ** | `task_type` | 生成モードを決定：text2music、cover、repaint、lego、extract、complete |\n| **テキスト入力** | `caption` | 音楽の全体的な要素の説明：スタイル、楽器、感情、雰囲気、音色、ボーカルの性別、展開など |\n| | `lyrics` | 時間的要素の説明：歌詞内容、音楽構造の進化、ボーカルの変化、ボーカル/楽器の演奏スタイル、開始/終了スタイル、発声スタイルなど（インストゥルメンタル音楽には`[Instrumental]`を使用） |\n| **音楽メタデータ** | `bpm` | テンポ（30–300） |\n| | `keyscale` | キー（例：C Major、Am） |\n| | `timesignature` | 拍子記号（4/4、3/4、6/8） |\n| | `vocal_language` | ボーカル言語 |\n| | `duration` | 目標時間（秒） |\n| **オーディオ参照** | `reference_audio` | 音色またはスタイルのグローバル参照（cover、スタイル転送用） |\n| | `src_audio` | 非text2musicタスク用のソースオーディオ（text2musicはデフォルトでサイレント、入力不要） |\n| | `audio_codes` | Coverモードでモデルに入力するセマンティックコード（高度な使用：コードを再利用してバリアントを生成、曲をコードに変換して拡張、DJのように組み合わせてミックス） |\n| **間隔制御** | `repainting_start/end` | 操作の時間間隔（repaint再描画領域 / lego新規トラック領域） |\n\n---\n\n#### Captionについて：最も重要な入力\n\n**Captionは生成音楽に影響を与える最も重要な要因です。**\n\n複数の入力形式をサポート：簡単なスタイル単語、カンマ区切りのタグ、複雑な自然言語記述。訓練でさまざまな形式と互換性があるようにし、テキスト形式がモデルのパフォーマンスに大きく影響しないようにしました。\n\n**良いキャプションを書くための少なくとも5つの方法を提供します：**\n\n1. **ランダムダイス** — UIのランダムボタンをクリックして、サンプルのキャプションの書き方を確認します。この標準化されたキャプションをテンプレートとして使用し、LLMに希望の形式に書き換えてもらうことができます。\n\n2. **Format自動書き換え** — `format`機能を使用して、手書きの簡単なキャプションを自動的に複雑な記述に拡張することをサポートします。\n\n3. **CoT書き換え** — LMが初期化されている場合、`thinking`モードが有効かどうかに関わらず、Chain-of-Thoughtを通じてキャプションを書き換えおよび拡張することをサポートします（設定で明示的に無効にしない限り、またはLMが初期化されていない場合）。\n\n4. **オーディオからCaptionへ** — 私たちのLMは、入力オーディオをキャプションに変換することをサポートします。精度は限られていますが、曖昧な方向は正しい——出発点として十分です。\n\n5. **Simpleモード** — 簡単な曲の説明を入力するだけで、LMが自動的に完全なキャプション、歌詞、メタサンプルを生成します——迅速な開始に適しています。\n\nどの方法でも、現実の問題を解決します：**普通の人として、私たちの音楽語彙は貧弱です。**\n\n生成された音楽をより興味深く、期待に応えるものにしたい場合、**Promptingは常に最適なオプション**です——それは最高の限界収益と驚きをもたらします。\n\n**Caption作成の一般的な次元：**\n\n| 次元 | 例 |\n|------|-----|\n| **スタイル/ジャンル** | pop, rock, jazz, electronic, hip-hop, R&B, folk, classical, lo-fi, synthwave |\n| **感情/雰囲気** | melancholic, uplifting, energetic, dreamy, dark, nostalgic, euphoric, intimate |\n| **楽器** | acoustic guitar, piano, synth pads, 808 drums, strings, brass, electric bass |\n| **音色テクスチャ** | warm, bright, crisp, muddy, airy, punchy, lush, raw, polished |\n| **時代参照** | 80s synth-pop, 90s grunge, 2010s EDM, vintage soul, modern trap |\n| **制作スタイル** | lo-fi, high-fidelity, live recording, studio-polished, bedroom pop |\n| **ボーカル特性** | female vocal, male vocal, breathy, powerful, falsetto, raspy, choir |\n| **速度/リズム** | slow tempo, mid-tempo, fast-paced, groovy, driving, laid-back |\n| **構造ヒント** | building intro, catchy chorus, dramatic bridge, fade-out ending |\n\n**いくつかの実用的な原則：**\n\n1. **具体的は曖昧より優れている** — 「sad piano ballad with female breathy vocal」は「a sad song」より効果的です。\n\n2. **複数の次元を組み合わせる** — 単一次元の記述はモデルに遊ぶ余地を与えすぎます。スタイル+感情+楽器+音色を組み合わせることで、希望する方向をより正確に固定できます。\n\n3. **参照をうまく使用する** — 「in the style of 80s synthwave」または「reminiscent of Bon Iver」は、複雑な美的好みを迅速に伝えることができます。\n\n4. **テクスチャ単語は有用** — warm、crisp、airy、punchyなどの形容詞は、ミキシングと音色の傾向に影響を与える可能性があります。\n\n5. **完璧な記述を追求しない** — Captionは出発点であり、終点ではありません。まず一般的な方向を書き、結果に基づいて反復調整します。\n\n6. **記述粒度が自由度を決定** — 省略された記述が多いほど、モデルの遊ぶ余地が大きくなり、ランダム要因の影響が大きくなります。詳細な記述が多いほど、モデルはより制約されます。ニーズに基づいて具体性を決定——驚きが欲しい場合は少なく書き、制御したい場合は詳細に書きます。\n\n7. **衝突する単語を避ける** — 衝突するスタイルの組み合わせは、劣化した出力を引き起こしやすいです。たとえば、「クラシック弦楽」と「ハードコアメタル」を同時に要求する——モデルは融合を試みますが、通常は理想的ではありません。特に`thinking`モードが有効な場合、LMはDiTよりもキャプションの汎化性が弱いです。プロンプティングが不合理な場合、驚きが出る確率は低くなります。\n\n   **衝突を解決する方法：**\n   - **繰り返し強化** — 特定の単語を繰り返すことで、ミックススタイルでより欲しい要素を強化\n   - **衝突を進化に変える** — スタイルの衝突を時間的なスタイルの進化に変換。たとえば：「始まりは柔らかい弦楽、中間は騒々しい動的なメタルロック、終わりはhip-hopに変わる」——これにより、モデルは異なるスタイルを混ぜるのではなく、それらを処理する方法について明確なガイダンスを得ます\n\n> より多くのプロンプティングのヒントについては、[The Complete Guide to Mastering Suno](https://www.notion.so/The-Complete-Guide-to-Mastering-Suno-Advanced-Strategies-for-Professional-Music-Generation-2d6ae744ebdf8024be42f6645f884221)を参照してください——Sunoのチュートリアルですが、プロンプティングのアイデアは普遍的です。\n\n---\n\n#### Lyricsについて：時間的スクリプト\n\nCaptionが音楽の「全体的な肖像」——スタイル、雰囲気、音色——を記述する場合、**Lyricsは音楽の「時間的スクリプト」**であり、音楽が時間とともにどのように展開するかを制御します。\n\nLyricsは単なる歌詞内容ではありません。以下を含みます：\n- 歌詞テキスト自体\n- **構造タグ**（[Verse]、[Chorus]、[Bridge]...）\n- **ボーカルスタイルのヒント**（[raspy vocal]、[whispered]...）\n- **楽器セクション**（[guitar solo]、[drum break]...）\n- **エネルギー変化**（[building energy]、[explosive drop]...）\n\n**構造タグが重要**\n\n構造タグ（Meta Tags）はLyricsで最も強力なツールです。モデルに「このセクションは何で、どのように実行すべきか」を伝えます。\n\n**一般的な構造タグ：**\n\n| カテゴリ | タグ | 説明 |\n|----------|------|------|\n| **基本構造** | `[Intro]` | オープニング、雰囲気を確立 |\n| | `[Verse]` / `[Verse 1]` | 主歌、物語の進行 |\n| | `[Pre-Chorus]` | プレコーラス、エネルギーを構築 |\n| | `[Chorus]` | コーラス、感情のクライマックス |\n| | `[Bridge]` | ブリッジ、転換または高揚 |\n| | `[Outro]` | エンディング、結論 |\n| **動的セクション** | `[Build]` | エネルギーが徐々に上昇 |\n| | `[Drop]` | エレクトロニックミュージックのエネルギー解放 |\n| | `[Breakdown]` | 楽器編成の削減、スペース |\n| **楽器セクション** | `[Instrumental]` | 純粋なインストゥルメンタル、ボーカルなし |\n| | `[Guitar Solo]` | ギターソロ |\n| | `[Piano Interlude]` | ピアノ間奏 |\n| **特殊タグ** | `[Fade Out]` | フェードアウトエンディング |\n| | `[Silence]` | サイレンス |\n\n**タグの組み合わせ：適度に使用**\n\n構造タグは`-`で組み合わせて、より細かい制御が可能：\n\n```\n[Chorus - anthemic]\nこれはコーラスの歌詞\n夢が燃えている\n\n[Bridge - whispered]\nそっとその言葉をささやく\n```\n\nこれは`[Chorus]`だけを書くよりも効果的——モデルにこのセクションが何であるか（Chorus）と、どのように歌うか（anthemic）の両方を伝えます。\n\n**⚠️ 注意：タグを積み重ねすぎないでください。**\n\n```\n❌ 推奨されない：\n[Chorus - anthemic - stacked harmonies - high energy - powerful - epic]\n\n✅ 推奨：\n[Chorus - anthemic]\n```\n\nタグを積み重ねすぎると2つのリスクがあります：\n1. モデルがタグの内容を歌詞として誤って歌う可能性がある\n2. 指示が多すぎるとモデルが混乱し、効果が悪化する\n\n**原則**：構造タグは簡潔に保ち、複雑なスタイル記述はCaptionに配置します。\n\n**⚠️ 重要：CaptionとLyricsの一貫性を維持**\n\n**モデルは衝突を解決するのが得意ではありません。** CaptionとLyricsの記述が矛盾する場合、モデルは混乱し、出力品質が低下します。\n\n```\n❌ 衝突例：\nCaption: \"violin solo, classical, intimate chamber music\"\nLyrics: [Guitar Solo - electric - distorted]\n\n✅ 一貫した例：\nCaption: \"violin solo, classical, intimate chamber music\"\nLyrics: [Violin Solo - expressive]\n```\n\n**チェックリスト：**\n- Captionの楽器 ↔ Lyricsの楽器セクションタグ\n- Captionの感情 ↔ Lyricsのエネルギータグ\n- Captionのボーカル記述 ↔ Lyricsのボーカル制御タグ\n\nCaptionを「全体的な設定」、Lyricsを「ショットスクリプト」と考えてください——それらは同じ物語を語るべきです。\n\n**ボーカル制御タグ：**\n\n| タグ | 効果 |\n|------|------|\n| `[raspy vocal]` | かすれた、テクスチャのあるボーカル |\n| `[whispered]` | ささやき |\n| `[falsetto]` | ファルセット |\n| `[powerful belting]` | 力強い、高音の歌唱 |\n| `[spoken word]` | ラップ/朗読 |\n| `[harmonies]` | 層状のハーモニー |\n| `[call and response]` | コールアンドレスポンス |\n| `[ad-lib]` | 即興の装飾 |\n\n**エネルギーと感情タグ：**\n\n| タグ | 効果 |\n|------|------|\n| `[high energy]` | 高エネルギー、情熱的 |\n| `[low energy]` | 低エネルギー、抑制的 |\n| `[building energy]` | エネルギー増加 |\n| `[explosive]` | 爆発的なエネルギー |\n| `[melancholic]` | 憂鬱 |\n| `[euphoric]` | 多幸感 |\n| `[dreamy]` | 夢のような |\n| `[aggressive]` | 攻撃的 |\n\n**歌詞テキストの書き方のヒント**\n\n**1. 音節数を制御**\n\n**1行あたり6-10音節**が通常最適です。モデルは音節をビートに合わせます——1行が6音節で次の行が14音節の場合、リズムが奇妙になります。\n\n```\n❌ 悪い例：\n我站在窗前看着外面的世界一切都在改变（18音節）\n你好（2音節）\n\n✅ 良い例：\n我站在窗前（5音節）\n看着外面世界（6音節）\n一切都在改变（6音節）\n```\n\n**ヒント**：同じ位置の行（例：各節の最初の行）は類似の音節数を保ちます（±1-2の偏差）。\n\n**2. 大文字小文字で強度を制御**\n\n大文字はより強いボーカル強度を示します：\n\n```\n[Verse]\nwalking through the empty streets（通常の強度）\n\n[Chorus]\nWE ARE THE CHAMPIONS!（高強度、叫び）\n```\n\n**3. 括弧で背景ボーカルを表す**\n\n```\n[Chorus]\nWe rise together (together)\nInto the light (into the light)\n```\n\n括弧内の内容は背景ボーカルまたはハーモニーとして処理されます。\n\n**4. 母音を延長**\n\n母音を繰り返すことで音を延長できます：\n\n```\nFeeeling so aliiive\n```\n\nただし、慎重に使用してください——効果は不安定で、無視されたり誤って発音されたりする場合があります。\n\n**5. セクションを明確に分離**\n\n各セクションを空行で区切ります：\n\n```\n[Verse 1]\n最初の節の歌詞\n最初の節を続ける\n\n[Chorus]\nコーラスの歌詞\nコーラスを続ける\n```\n\n**「AI風」の歌詞を避ける**\n\nこれらの特徴は歌詞を機械的で人間味のないものにします：\n\n| 赤旗 🚩 | 説明 |\n|---------|------|\n| **形容詞の積み重ね** | 「neon skies, electric hearts, endless dreams」——セクションに曖昧なイメージを詰め込む |\n| **韻の混乱** | 一貫性のない韻パターン、または強制的な韻による意味の断裂 |\n| **セクション境界の曖昧さ** | 歌詞内容が構造タグを越え、Verseの内容がChorusに「流れる」 |\n| **呼吸感がない** | 各行が長すぎて、一息で歌えない |\n| **混合メタファー** | 最初の節が水のイメージを使用し、2番目が突然火になり、3番目が飛翔——リスナーは固定できない |\n\n**メタファーの規律**：1曲につき1つのコアメタファーに固執し、その複数の側面を深く掘り下げます。たとえば、「水」をメタファーとして選択すると、愛が水のように障害を回避する方法、細かい雨でも洪水でもあり得る、相手の姿を反映できる、掴めないが存在する、を探索できます。1つのイメージ、複数の側面——これにより歌詞に結束力が生まれます。\n\n**インストゥルメンタル音楽の書き方**\n\nボーカルなしの純粋なインストゥルメンタル音楽を生成する場合：\n\n```\n[Instrumental]\n```\n\nまたは、構造タグを使用してインストゥルメンタルの展開を記述：\n\n```\n[Intro - ambient]\n\n[Main Theme - piano]\n\n[Climax - powerful]\n\n[Outro - fade out]\n```\n\n**完全な例**\n\nCaptionが次のとおりと仮定：`female vocal, piano ballad, emotional, intimate atmosphere, strings, building to powerful chorus`\n\n```\n[Intro - piano]\n\n[Verse 1]\n月光洒在窗台上\n我听见你的呼吸\n城市在远处沉睡\n只有我们还醒着\n\n[Pre-Chorus]\n这一刻如此安静\n却藏着汹涌的心\n\n[Chorus - powerful]\n让我们燃烧吧\n像夜空中的烟火\n短暂却绚烂\n这就是我们的时刻\n\n[Verse 2]\n时间在指尖流过\n我们抓不住什么\n但至少此刻拥有\n彼此眼中的火焰\n\n[Bridge - whispered]\n如果明天一切消散\n至少我们曾经闪耀\n\n[Final Chorus]\n让我们燃烧吧\n像夜空中的烟火\n短暂却绚烂\nTHIS IS OUR MOMENT!\n\n[Outro - fade out]\n```\n\n注意：この例では、Lyricsのタグ（piano、powerful、whispered）はCaptionの記述（piano ballad、building to powerful chorus、intimate）と一貫しており、衝突はありません。\n\n---\n\n#### 音楽メタデータについて：オプションの細かい制御\n\n**ほとんどの場合、メタデータを手動で設定する必要はありません。**\n\n`thinking`モードを有効にした場合（または`use_cot_metas`を有効にした場合）、LMはCaptionとLyricsに基づいて適切なBPM、キー、拍子記号などを自動的に推論します。これは通常十分です。\n\nただし、明確なアイデアがある場合は、手動で制御することもできます：\n\n| パラメータ | 制御範囲 | 説明 |\n|-----------|----------|------|\n| `bpm` | 30–300 | テンポ。一般的な分布：遅い曲60–80、中速90–120、速い曲130–180 |\n| `keyscale` | キー | 例：`C Major`、`Am`、`F# Minor`。全体的なピッチと感情の色に影響 |\n| `timesignature` | 拍子記号 | `4/4`（最も一般的）、`3/4`（ワルツ）、`6/8`（スイング感） |\n| `vocal_language` | 言語 | ボーカル言語。LMは通常歌詞から自動検出 |\n| `duration` | 秒 | 目標時間。実際の生成はわずかに異なる場合があります |\n\n**制御の境界を理解する**\n\nこれらのパラメータは**ガイダンス**であり、**正確なコマンド**ではありません：\n\n- **BPM**：一般的な範囲（60–180）は良好に機能します。極端な値（30や280など）は訓練データが少なく、不安定な可能性があります\n- **キー**：一般的なキー（C、G、D、Am、Em）は安定しています。まれなキーは無視されたりシフトされたりする可能性があります\n- **拍子記号**：`4/4`が最も信頼性が高い。`3/4`、`6/8`は通常OK。複雑な拍子記号（`5/4`、`7/8`など）は高度で、スタイルによって効果が異なります\n- **時間**：短い曲（30–60秒）と中程度の長さ（2–4分）は安定しています。非常に長い生成は繰り返しや構造の問題が発生する可能性があります\n\n**モデルの「参照」アプローチ**\n\nモデルは`bpm=120`を機械的に実行するのではなく、次のようにします：\n1. `120 BPM`を**アンカーポイント**として使用\n2. このアンカー付近の分布からサンプリング\n3. 最終結果は118または122の可能性があり、正確に120ではない\n\nそれはミュージシャンに「約120のテンポ」と言うようなものです——彼らはこの範囲内で自然に演奏し、メトロノームに厳密に従うのではありません。\n\n**手動設定が必要な場合**\n\n| シナリオ | 提案 |\n|----------|------|\n| 日常生成 | 気にしない、LMに自動推論させる |\n| 明確なテンポ要件 | `bpm`を手動設定 |\n| 特定のスタイル（例：ワルツ） | `timesignature=3/4`を手動設定 |\n| 他の素材と一致させる必要がある | `bpm`と`duration`を手動設定 |\n| 特定のキーの色を追求 | `keyscale`を手動設定 |\n\n**ヒント**：メタデータを手動で設定したが、生成結果が明らかに一致しない場合——Caption/Lyricsとの衝突を確認してください。たとえば、Captionに「slow ballad」と書いて`bpm=160`の場合、モデルは混乱します。\n\n**推奨される実践**：Captionにテンポ、BPM、キーなどのメタデータ情報を書かないでください。これらは専用のメタデータパラメータ（`bpm`、`keyscale`、`timesignature`など）を通じて設定すべきであり、Captionで記述すべきではありません。Captionはスタイル、感情、楽器、音色などの音楽的特徴に焦点を当て、メタデータ情報は対応するパラメータに任せます。\n\n---\n\n#### オーディオ制御について：音で音を制御する\n\n**テキストは次元削減された抽象化です。最良の制御は、やはりオーディオで制御することです。**\n\nオーディオで生成を制御する方法は3つあり、それぞれ異なる制御範囲と用途があります：\n\n---\n\n##### 1. 参照オーディオ（Reference Audio）：グローバル音響特徴制御\n\n参照オーディオ（`reference_audio`）は、生成音楽の**音響特徴**——音色、ミキシングスタイル、演奏スタイルなど——を制御するために使用されます。それは**時間次元情報を平均化**し、**グローバルに**作用します。\n\n**参照オーディオは何を制御するか？**\n\n参照オーディオは主に生成音楽の**音響特徴**を制御します：\n- **音色テクスチャ**：ボーカル音色、楽器音色\n- **ミキシングスタイル**：空間感、ダイナミックレンジ、周波数分布\n- **演奏スタイル**：ボーカルテクニック、演奏テクニック、表現\n- **全体的な雰囲気**：参照オーディオを通じて伝えられる「感覚」\n\n**バックエンドは参照オーディオをどのように処理するか？**\n\n参照オーディオを提供すると、システムは次の処理を実行します：\n\n1. **オーディオ前処理**：\n   - オーディオファイルを読み込み、**ステレオ48kHz**形式に統一標準化\n   - サイレンスを検出し、オーディオが完全にサイレントの場合は無視\n   - オーディオの長さが30秒未満の場合、少なくとも30秒まで繰り返して埋める\n   - 前、中、後の3つの位置からそれぞれ10秒のセグメントをランダムに選択し、30秒の参照セグメントに連結\n\n2. **エンコーディング変換**：\n   - **VAE（変分オートエンコーダー）**の`tiled_encode`メソッドを使用して、オーディオを**潜在表現（latents）**にエンコード\n   - これらのlatentsは音響特徴情報を含みますが、特定のメロディ、リズム、その他の構造情報を除去\n   - エンコードされたlatentsは、DiTの生成プロセスに条件として入力され、**時間次元情報を平均化し、生成プロセス全体にグローバルに作用**\n\n---\n\n##### 2. ソースオーディオ（Source Audio）：セマンティック構造制御\n\nソースオーディオ（`src_audio`）は**Coverタスク**に使用され、**メロディ構造制御**を実行します。その原理は、入力したソースオーディオをセマンティックに構造化された情報に量子化することです。\n\n**ソースオーディオは何を制御するか？**\n\nソースオーディオは**セマンティックに構造化された情報**に変換されます：\n- **メロディ**：音符の方向とピッチ\n- **リズム**：ビート、アクセント、グルーヴ\n- **和音**：和声進行と変化\n- **オーケストレーション**：楽器の配置と層\n- **いくつかの音色**：部分的な音色情報\n\n**それで何ができるか？**\n\n1. **スタイルを制御**：ソースオーディオの構造を維持し、スタイルと詳細を変更\n2. **スタイルを転送**：ソースオーディオの構造を異なるスタイルに適用\n3. **Retake抽選**：類似の構造だが異なるバリアントを生成し、複数の生成を通じて異なる解釈を得る\n4. **影響度を制御**：`audio_cover_strength`パラメータ（0.0–1.0）を通じてソースオーディオの影響強度を制御\n   - 強度が高い：生成結果がソースオーディオの構造により厳密に従う\n   - 強度が低い：生成結果により多くの自由な遊びの余地がある\n\n**Coverの高度な使用法**\n\nCoverを使用して**曲をリミックス**でき、CaptionとLyricsの変更をサポートします：\n\n- **リミックス作成**：曲をソースオーディオとして入力し、CaptionとLyricsを変更して再解釈\n  - スタイルを変更：異なるCaption記述を使用（例：popからrockに変更）\n  - 歌詞を変更：新しいLyricsで歌詞を書き直し、元のメロディ構造を維持\n  - 感情を変更：Captionを通じて全体的な雰囲気を調整（例：悲しいから楽しいに変更）\n\n- **複雑な音楽構造を構築**：必要な構造影響度に基づいて、複雑なメロディ方向、層、グルーヴを構築\n  - `audio_cover_strength`を通じて構造遵守度を細かく調整\n  - CaptionとLyricsの変更を組み合わせ、コア構造を維持しながら新しい表現を作成\n  - 複数のバージョンを生成でき、各バージョンは構造、スタイル、歌詞で異なる重点を持つ\n\n---\n\n##### 3. ソースオーディオコンテキストベースの制御：局所的な補完と変更\n\nこれは**Repaintタスク**で、ソースオーディオのコンテキストに基づいて補完または変更を実行します。\n\n**Repaintの原理**\n\nRepaintは**コンテキスト補完**の原理に基づいています：\n- **始まり**、**中間局所**、**終わり**、または**任意の領域**を補完可能\n- 操作範囲：**3秒から90秒**\n- モデルはソースオーディオのコンテキスト情報を参照し、指定された間隔内で生成\n\n**それで何ができるか？**\n\n1. **局所的な変更**：指定された間隔の歌詞、構造、または内容を変更\n2. **歌詞を変更**：メロディとオーケストレーションを維持し、歌詞内容のみを変更\n3. **構造を変更**：指定された間隔で音楽構造を変更（例：VerseをChorusに変更）\n4. **続きを書く**：コンテキストに基づいて始まりまたは終わりを続きを書く\n5. **音色をクローン**：コンテキストに基づいてソースオーディオの音色特徴をクローン\n\n**Repaintの高度な使用法**\n\nRepaintを使用して、より複雑な創造的ニーズを実現できます：\n\n- **無限時間生成**：\n  - 複数のRepaint操作を通じて、オーディオを継続的に拡張し、無限時間生成を実現\n  - 各継続は前のセグメントのコンテキストに基づき、自然な遷移と一貫性を維持\n  - セグメントごとに生成でき、各セグメントは3–90秒、最終的に完全な作品に連結\n\n- **インテリジェントオーディオステッチング**：\n  - 2つのオーディオをインテリジェントに組織してステッチ\n  - 最初のオーディオの終わりでRepaintを使用して続きを書き、遷移を自然に接続\n  - または、2つのオーディオ間の接続部分をRepaintで変更し、スムーズな遷移を実現\n  - モデルはコンテキストに基づいてリズム、和声、音色の接続を自動的に処理し、ステッチされたオーディオを完全な作品のように聞こえさせます\n\n---\n\n##### 4. Baseモデルの高度なオーディオ制御タスク\n\n**Baseモデル**では、より高度なオーディオ制御タスクもサポートしています：\n\n**Legoタスク**：既存のトラックに基づいてインテリジェントに新しいトラックを追加\n- 既存のオーディオトラックを入力（例：ボーカル）\n- モデルはインテリジェントに新しいトラックを追加（例：ドラム、ギター、ベースなど）\n- 新しいトラックは元のトラックとリズムと和声で協調\n\n**Completeタスク**：単一トラックに混合トラックを追加\n- 単一トラックオーディオを入力（例：アカペラボーカル）\n- モデルは完全な混合伴奏トラックを生成\n- 生成された伴奏はボーカルとスタイル、リズム、和声で一致\n\n**これらの高度なコンテキスト補完タスク**は、制御方法を大幅に拡張し、よりインテリジェントにインスピレーションと創造性を提供します。\n\n---\n\nこれらのパラメータの組み合わせが、あなたが「欲しいもの」を決定します。後で入力制御の**原則**と**テクニック**を詳しく説明します。\n\n### II. 推論ハイパーパラメータ：モデルはどのように生成するか？\n\nこれは「生成プロセス動作」に影響を与える部分——何が欲しいかは変えませんが、モデルがそれをどのように行うかを変えます。\n\n**DiT（拡散モデル）ハイパーパラメータ：**\n\n| パラメータ | 機能 | デフォルト | 調整アドバイス |\n|-----------|------|-----------|---------------|\n| `inference_steps` | 拡散ステップ | 8（turbo） | ステップが多いほど細かいが遅い。Turboは8、Baseは32–100を使用 |\n| `guidance_scale` | CFG強度 | 7.0 | 高いほどプロンプト遵守度が高いが、過適合の可能性。Baseモデルのみ有効 |\n| `use_adg` | 適応的デュアルガイダンス | False | 有効にすると、CFGを動的に調整、Baseモデルのみ |\n| `cfg_interval_start/end` | CFG有効間隔 | 0.0–1.0 | どの段階でCFGを適用するかを制御 |\n| `shift` | タイムステップオフセット | 1.0 | ノイズ除去軌跡を調整し、生成スタイルに影響 |\n| `infer_method` | 推論方法 | \"ode\" | `ode`決定論的、`sde`ランダム性を導入 |\n| `timesteps` | カスタムタイムステップ | None | 高度な使用法、ステップとshiftを上書き |\n| `audio_cover_strength` | 参照オーディオ/コードの影響強度 | 1.0 | 0.0–1.0、高いほど参照に近く、低いほど自由度が高い |\n\n**5Hz LM（言語モデル）ハイパーパラメータ：**\n\n| パラメータ | 機能 | デフォルト | 調整アドバイス |\n|-----------|------|-----------|---------------|\n| `thinking` | CoT推論を有効化 | True | 有効にするとLMがメタデータとコードを推論 |\n| `lm_temperature` | サンプリング温度 | 0.85 | 高いほどランダム/創造的、低いほど保守的/決定論的 |\n| `lm_cfg_scale` | LM CFG強度 | 2.0 | 高いほど正のプロンプト遵守度が高い |\n| `lm_top_k` | Top-Kサンプリング | 0 | 0は無効、候補単語数を制限 |\n| `lm_top_p` | Top-Pサンプリング | 0.9 | 核サンプリング、累積確率を制限 |\n| `lm_negative_prompt` | ネガティブプロンプト | \"NO USER INPUT\" | LMに何を生成しないかを伝える |\n| `use_cot_metas` | CoTメタデータ推論 | True | LMにBPM、キーなどを自動推論させる |\n| `use_cot_caption` | CoTキャプション書き換え | True | LMに記述を最適化させる |\n| `use_cot_language` | CoT言語検出 | True | LMにボーカル言語を自動検出させる |\n| `use_constrained_decoding` | 制約付きデコーディング | True | 正しい出力形式を保証 |\n\nこれらのパラメータの組み合わせが、モデルが「どのように行うか」を決定します。\n\n**パラメータ調整について**\n\n強調すべきは、**調整要因とランダム要因は時として同等の影響を持つ**ことです。パラメータを調整する場合、パラメータ自体の影響なのか、ランダム性による変化なのかを判断するのが難しい場合があります。\n\nしたがって、**調整時にランダム要因を固定することを推奨します**——固定された`seed`値を設定することで、各生成が同じ初期ノイズから開始されることを保証し、パラメータが生成オーディオに与える実際の影響を正確に感じることができます。そうしないと、パラメータ変更の効果がランダム性によってマスクされ、パラメータの役割を誤って判断する可能性があります。\n\n### III. ランダム要因：不確実性の源\n\n入力とハイパーパラメータが完全に同じでも、2つの生成が異なる結果を生む場合があります。これは次の理由によるものです：\n\n**1. DiTの初期ノイズ**\n- 拡散モデルはランダムノイズから開始し、徐々にノイズを除去\n- `seed`パラメータがこの初期ノイズを制御\n- 異なるseed → 異なる開始点 → 異なる終了点\n\n**2. LMのサンプリングランダム性**\n- `lm_temperature > 0`の場合、サンプリングプロセス自体にランダム性がある\n- 同じプロンプトでも、各サンプリングは異なるトークンを選択する可能性がある\n\n**3. `infer_method = \"sde\"`の場合の追加ノイズ**\n- SDEメソッドはノイズ除去プロセス中に追加のランダム性を注入\n\n---\n\n#### ランダム要因の利点と欠点\n\nランダム性は両刃の剣です。\n\n**ランダム性の利点：**\n- **創造的空間を探索**：同じ入力が異なるバリアントを生成し、より多くの選択肢を提供\n- **予期しない驚きを発見**：時としてランダム性が予期しない優れた結果をもたらす\n- **繰り返しを避ける**：各生成が異なり、単一パターンのループに陥らない\n\n**ランダム性の課題：**\n- **結果が制御不能**：生成結果を正確に予測できず、複数回生成しても満足できない可能性がある\n- **再現が困難**：入力が完全に同じでも、特定の良い結果を再現するのが困難\n- **調整が困難**：パラメータを調整する場合、パラメータの影響なのかランダム性の変化なのかを判断するのが困難\n- **スクリーニングコスト**：満足のいくものを見つけるために複数のバージョンを生成する必要があり、時間コストが増加\n\n#### ランダム要因にどのような心構えで向き合うか？\n\n**1. 不確実性を受け入れる**\n- ランダム性はAI音楽生成の本質的な特徴であり、バグではなく機能です\n- すべての生成が完璧であることを期待せず、ランダム性を探索ツールとして扱う\n\n**2. 探索プロセスを受け入れる**\n- 生成プロセスを「ガチャ」または「宝探し」として扱う——複数回試すと、常に驚きが見つかる\n- 一度の成功にこだわるのではなく、予期しない良い結果を発見するプロセスを楽しむ\n\n**3. 固定seedをうまく使用する**\n- **パラメータの影響を理解したい**場合、`seed`を固定してランダム性の干渉を排除\n- **創造的空間を探索したい**場合、`seed`をランダムに変化させる\n\n**4. バッチ生成 + インテリジェントスクリーニング**\n- 単一生成に依存せず、複数のバージョンをバッチ生成\n- 自動スコアリングメカニズムを利用して初期スクリーニングを行い、効率を向上\n\n#### 私たちのソリューション：大バッチ + 自動スコアリング\n\n推論が非常に高速なため、GPU VRAMが十分であれば、**大バッチでランダム空間を探索**できます：\n\n- **バッチ生成**：一度に複数のバージョンを生成（例：batch_size=2,4,8）、ランダム空間を迅速に探索\n- **自動スコアリングメカニズム**：初期スクリーニングに役立つ自動スコアリングメカニズムを提供し、**test time scaling**を実行\n\n**自動スコアリングメカニズム**\n\n複数のスコアリングメトリクスを提供しており、その中で**私のお気に入りはDiT Lyrics Alignment Score**です：\n\n- **DiT Lyrics Alignment Score**：このスコアは歌詞の正確性に暗黙的に影響します\n  - 生成オーディオ内の歌詞とオーディオの整列度を評価\n  - スコアが高いほど、歌詞がオーディオ内でより正確に配置され、歌唱と歌詞の一致度が良いことを意味\n  - これは歌詞付きの音楽生成に特に重要で、歌詞の正確性が高いバージョンをスクリーニングするのに役立ちます\n\n- **その他のスコアリングメトリクス**：他の品質評価メトリクスも含まれ、複数の次元から生成結果を評価できます\n\n**推奨ワークフロー：**\n\n1. **バッチ生成**：より大きな`batch_size`を設定（例：2、4、8）、一度に複数のバージョンを生成\n2. **AutoGenを有効化**：自動生成機能を有効化し、システムがバックグラウンドで継続的に新しいバッチを生成\n   - **AutoGenのメカニズム**：AutoGenは、現在のバッチ結果を表示している間に、バックグラウンドで同じパラメータ（ただしランダムseed）を使用して次のバッチを自動生成します\n   - これにより、手動で生成ボタンをクリックすることなく、ランダム空間を継続的に探索できます\n   - 各新しいバッチは新しいランダムseedを使用し、結果の多様性を保証\n3. **自動スコアリング**：自動スコアリング機能を有効化し、システムが各バージョンを自動的にスコアリング\n4. **初期スクリーニング**：DiT Lyrics Alignment Scoreなどのメトリクスに基づいて、スコアが高いバージョンをスクリーニング\n5. **手動選択**：スクリーニングされたバージョンから、ニーズに最も合う最終バージョンを手動で選択\n\nこれにより、ランダム性を最大限に活用して創造的空間を探索しながら、自動化ツールを通じて効率を向上させ、大量の生成結果の中での盲目的な検索を避けることができます。AutoGenにより、「聞きながら生成」が可能になり、現在の結果を閲覧している間に、次のバッチがバックグラウンドで準備されています。\n\n---\n\n## 結語\n\nこのチュートリアルは現在、ACE-Step 1.5の核心概念と使用方法をカバーしています：\n\n- **メンタルモデル**：人間中心の生成設計哲学を理解\n- **モデルアーキテクチャ**：LMとDiTがどのように協力するかを理解\n- **入力制御**：テキスト（Caption、Lyrics、メタデータ）とオーディオ（参照オーディオ、ソースオーディオ）の制御方法を習得\n- **推論ハイパーパラメータ**：生成プロセスに影響を与えるパラメータを理解\n- **ランダム要因**：ランダム性を利用して創造的空間を探索する方法を学び、大バッチ + AutoGen + 自動スコアリングを通じて効率を向上\n\nこれは始まりに過ぎません。あなたと共有したい内容はまだたくさんあります：\n\n- より多くのPromptingテクニックと実践的なケース\n- 異なるタスクタイプの詳細な使用ガイド\n- 高度なテクニックと創造的なワークフロー\n- よくある問題と解決策\n- パフォーマンス最適化の提案\n\n**このチュートリアルは継続的に更新および改善されます。** 使用中に質問や提案がある場合は、フィードバックを歓迎します。一緒にACE-Stepをあなたのポケットの中の創造的なパートナーにしましょう。\n\n---\n\n*続く...*\n"
  },
  {
    "path": "docs/ja/index.md",
    "content": "---\nlayout: home\nhero:\n  name: ACE-Step 1.5\n  text: オープンソース音楽生成\n  tagline: コンシューマーハードウェアで商用グレードの音楽生成。A100で1曲2秒未満、VRAM 4GB未満。\n  image:\n    src: /logo.png\n    alt: ACE-Step\n  actions:\n    - theme: brand\n      text: インストール\n      link: /ja/INSTALL\n    - theme: alt\n      text: チュートリアル (必読)\n      link: /ja/Tutorial\n    - theme: alt\n      text: API リファレンス\n      link: /ja/API\n\nfeatures:\n  - icon: \"&#9889;\"\n    title: 超高速生成\n    details: A100で1曲2秒未満、RTX 3090で10秒未満。10秒から10分の音声生成に対応。\n  - icon: \"&#127925;\"\n    title: 商用グレード品質\n    details: 1000以上の楽器・スタイル、50以上の言語、きめ細やかな音色記述と歌詞構造制御。\n  - icon: \"&#127899;\"\n    title: 多彩な編集機能\n    details: カバー生成、リペイント、トラック分離、ボーカルからBGM、マルチトラック生成など。\n  - icon: \"&#128640;\"\n    title: 軽量・カスタマイズ可能\n    details: 4GB未満のVRAMでローカル実行。数曲からLoRAを学習、3090で1時間。\n---\n"
  },
  {
    "path": "docs/ko/API.md",
    "content": "# ACE-Step API 클라이언트 문서\n\n**언어 / Language / 语言 / 言語:** [English](../en/API.md) | [한국어](API.md) | [中文](../zh/API.md) | [日本語](../ja/API.md)\n\n---\n\n이 서비스는 HTTP 기반의 비동기 음악 생성 API를 제공합니다.\n\n**기본 워크플로우**:\n1. `POST /release_task`를 호출하여 작업을 제출하고 `task_id`를 획득합니다.\n2. `POST /query_result`를 호출하여 작업 상태가 `1`(성공) 또는 `2`(실패)가 될 때까지 배치 쿼리를 수행합니다.\n3. 결과에 반환된 `GET /v1/audio?path=...` URL을 통해 오디오 파일을 다운로드합니다.\n\n---\n\n## 목차\n\n- [1. 인증](#1-인증)\n- [2. 응답 형식](#2-응답-형식)\n- [3. 작업 상태 설명](#3-작업-상태-설명)\n- [4. 생성 작업 생성](#4-생성-작업-생성)\n- [5. 작업 결과 배치 조회](#5-작업-결과-배치-조회)\n- [6. 입력 포맷팅 (Format Input)](#6-입력-포맷팅-format-input)\n- [7. 랜덤 샘플 가져오기](#7-랜덤-샘플-가져오기)\n- [8. 사용 가능한 모델 목록](#8-사용-가능한-모델-목록)\n- [9. 서버 통계](#9-서버-통계)\n- [10. 오디오 파일 다운로드](#10-오디오-파일-다운로드)\n- [11. 헬스 체크](#11-헬스-체크)\n- [12. 환경 변수](#12-환경-변수)\n\n---\n\n## 1. 인증\n\nAPI는 선택적으로 API 키 인증을 지원합니다. 활성화된 경우 요청 시 유효한 키를 제공해야 합니다.\n\n### 인증 방법\n\n두 가지 인증 방법을 지원합니다:\n\n**방법 A: 요청 본문의 ai_token**\n\n```json\n{\n  \"ai_token\": \"your-api-key\",\n  \"prompt\": \"upbeat pop song\",\n  ...\n}\n```\n\n**방법 B: Authorization 헤더**\n\n```bash\ncurl -X POST http://localhost:8001/release_task \\\n  -H 'Authorization: Bearer your-api-key' \\\n  -H 'Content-Type: application/json' \\\n  -d '{\"prompt\": \"upbeat pop song\"}'\n```\n\n---\n\n## 2. 응답 형식\n\n모든 API 응답은 통합 래퍼 형식을 사용합니다:\n\n```json\n{\n  \"data\": { ... },\n  \"code\": 200,\n  \"error\": null,\n  \"timestamp\": 1700000000000,\n  \"extra\": null\n}\n```\n\n| 필드 | 타입 | 설명 |\n| :--- | :--- | :--- |\n| `data` | any | 실제 응답 데이터 |\n| `code` | int | 상태 코드 (200=성공) |\n| `error` | string | 에러 메시지 (성공 시 null) |\n| `timestamp` | int | 응답 타임스탬프 (밀리초) |\n| `extra` | any | 추가 정보 (보통 null) |\n\n---\n\n## 3. 작업 상태 설명\n\n작업 상태(`status`)는 정수로 표현됩니다:\n\n| 상태 코드 | 상태 이름 | 설명 |\n| :--- | :--- | :--- |\n| `0` | 대기 중/실행 중 | 작업이 대기열에 있거나 진행 중임 |\n| `1` | 성공 | 생성이 성공적이며 결과가 준비됨 |\n| `2` | 실패 | 생성 실패 |\n\n---\n\n## 4. 생성 작업 생성\n\n### 4.1 API 정의\n\n- **URL**: `/release_task`\n- **Method**: `POST`\n- **Content-Type**: `application/json`, `multipart/form-data`, 또는 `application/x-www-form-urlencoded`\n\n### 4.2 요청 파라미터\n\n#### 파라미터 명명 규칙\n\nAPI는 대부분의 파라미터에 대해 **snake_case**와 **camelCase** 명명을 모두 지원합니다. 예:\n- `audio_duration` / `duration` / `audioDuration`\n- `key_scale` / `keyscale` / `keyScale`\n- `time_signature` / `timesignature` / `timeSignature`\n- `sample_query` / `sampleQuery` / `description` / `desc`\n- `use_format` / `useFormat` / `format`\n\n또한 메타데이터는 중첩된 객체(`metas`, `metadata`, 또는 `user_metadata`)로 전달할 수 있습니다.\n\n#### 방법 A: JSON 요청 (application/json)\n\n텍스트 파라미터만 전달하거나 서버에 이미 존재하는 오디오 파일 경로를 참조할 때 적합합니다.\n\n**기본 파라미터**:\n\n| 파라미터 명 | 타입 | 기본값 | 설명 |\n| :--- | :--- | :--- | :--- |\n| `prompt` | string | `\"\"` | 음악 설명 프롬프트 (별칭: `caption`) |\n| `lyrics` | string | `\"\"` | 가사 내용 |\n| `thinking` | bool | `false` | 5Hz LM을 사용하여 오디오 코드를 생성할지 여부 (lm-dit 동작) |\n| `vocal_language` | string | `\"en\"` | 가사 언어 (en, zh, ja 등) |\n| `audio_format` | string | `\"mp3\"` | 출력 형식 (mp3, wav, flac) |\n\n**샘플/설명 모드 파라미터**:\n\n| 파라미터 명 | 타입 | 기본값 | 설명 |\n| :--- | :--- | :--- | :--- |\n| `sample_mode` | bool | `false` | 랜덤 샘플 생성 모드 활성화 (LM을 통해 캡션/가사/메타데이터 자동 생성) |\n| `sample_query` | string | `\"\"` | 샘플 생성을 위한 자연어 설명 (예: \"조용한 저녁을 위한 부드러운 벵골어 사랑 노래\"). 별칭: `description`, `desc` |\n| `use_format` | bool | `false` | LM을 사용하여 제공된 캡션과 가사를 개선/포맷팅합니다. 별칭: `format` |\n\n**다중 모델 지원**:\n\n| 파라미터 명 | 타입 | 기본값 | 설명 |\n| :--- | :--- | :--- | :--- |\n| `model` | string | null | 사용할 DiT 모델 선택 (예: `\"acestep-v15-turbo\"`, `\"acestep-v15-turbo-shift3\"`). `/v1/models`를 사용하여 가능한 모델 목록을 확인하세요. 지정하지 않으면 기본 모델을 사용합니다. |\n\n**thinking 의미론 (중요)**:\n\n- `thinking=false`:\n  - 서버는 `audio_code_string`을 생성하기 위해 5Hz LM을 사용하지 **않습니다**.\n  - DiT는 **text2music** 모드에서 실행되며 제공된 `audio_code_string`을 **무시**합니다.\n- `thinking=true`:\n  - 서버는 `audio_code_string`을 생성하기 위해 5Hz LM을 사용합니다 (lm-dit 동작).\n  - DiT는 향상된 음악 품질을 위해 LM이 생성한 코드를 기반으로 실행됩니다.\n\n**메타데이터 자동 완성 (조건부)**:\n\n`use_cot_caption=true` 또는 `use_cot_language=true`이거나 메타데이터 필드가 누락된 경우, 서버는 `caption`/`lyrics`를 기반으로 누락된 필드를 채우기 위해 5Hz LM을 호출할 수 있습니다:\n\n- `bpm`\n- `key_scale`\n- `time_signature`\n- `audio_duration`\n\n사용자가 제공한 값이 항상 우선하며, LM은 비어 있거나 누락된 필드만 채웁니다.\n\n**음악 속성 파라미터**:\n\n| 파라미터 명 | 타입 | 기본값 | 설명 |\n| :--- | :--- | :--- | :--- |\n| `bpm` | int | null | 템포(BPM) 지정, 범위 30-300 |\n| `key_scale` | string | `\"\"` | 키/스케일 (예: \"C Major\", \"Am\"). 별칭: `keyscale`, `keyScale` |\n| `time_signature` | string | `\"\"` | 박자 기호 (2/4, 3/4, 4/4, 6/8의 경우 2, 3, 4, 6). 별칭: `timesignature`, `timeSignature` |\n| `audio_duration` | float | null | 생성 길이 (초), 범위 10-600. 별칭: `duration`, `target_duration` |\n\n**오디오 코드 (선택 사항)**:\n\n| 파라미터 명 | 타입 | 기본값 | 설명 |\n| :--- | :--- | :--- | :--- |\n| `audio_code_string` | string or string[] | `\"\"` | `llm_dit`를 위한 오디오 시맨틱 토큰(5Hz) 문자열. 별칭: `audioCodeString` |\n\n**생성 제어 파라미터**:\n\n| 파라미터 명 | 타입 | 기본값 | 설명 |\n| :--- | :--- | :--- | :--- |\n| `inference_steps` | int | `8` | 추론 단계 수. Turbo 모델: 1-20 (권장 8). Base 모델: 1-200 (권장 32-64). |\n| `guidance_scale` | float | `7.0` | 프롬프트 가이드 계수. Base 모델에서만 유효합니다. |\n| `use_random_seed` | bool | `true` | 랜덤 시드 사용 여부 |\n| `seed` | int | `-1` | 시드 지정 (use_random_seed=false일 때) |\n| `batch_size` | int | `2` | 배치 생성 수 (최대 8) |\n\n**고급 DiT 파라미터**:\n\n| 파라미터 명 | 타입 | 기본값 | 설명 |\n| :--- | :--- | :--- | :--- |\n| `shift` | float | `3.0` | 타임스텝 시프트 계수 (범위 1.0-5.0). Turbo 모델이 아닌 Base 모델에서만 유효합니다. |\n| `infer_method` | string | `\"ode\"` | 확산 추론 방법: `\"ode\"` (Euler, 더 빠름) 또는 `\"sde\"` (확률적). |\n| `timesteps` | string | null | 쉼표로 구분된 커스텀 타임스텝 (예: `\"0.97,0.76,0.615,0.5,0.395,0.28,0.18,0.085,0\"`). `inference_steps`와 `shift`를 재정의합니다. |\n| `use_adg` | bool | `false` | ADG (Adaptive Dual Guidance) 사용 (Base 모델 전용) |\n| `cfg_interval_start` | float | `0.0` | CFG 적용 시작 비율 (0.0-1.0) |\n| `cfg_interval_end` | float | `1.0` | CFG 적용 종료 비율 (0.0-1.0) |\n\n**5Hz LM 파라미터 (선택 사항, 서버측)**:\n\n이 파라미터들은 메타데이터 자동 완성 및 (thinking=true일 때) 코드 생성에 사용되는 5Hz LM 샘플링을 제어합니다.\n\n| 파라미터 명 | 타입 | 기본값 | 설명 |\n| :--- | :--- | :--- | :--- |\n| `lm_model_path` | string | null | 5Hz LM 체크포인트 디렉토리 이름 (예: `acestep-5Hz-lm-0.6B`) |\n| `lm_backend` | string | `\"vllm\"` | `vllm` 또는 `pt` |\n| `lm_temperature` | float | `0.85` | 샘플링 온도 |\n| `lm_cfg_scale` | float | `2.5` | CFG 스케일 (>1일 경우 CFG 활성화) |\n| `lm_negative_prompt` | string | `\"NO USER INPUT\"` | CFG에 사용되는 네거티브 프롬프트 |\n| `lm_top_k` | int | null | Top-k (0/null은 비활성) |\n| `lm_top_p` | float | `0.9` | Top-p (>=1은 비활성) |\n| `lm_repetition_penalty` | float | `1.0` | 반복 페널티 |\n\n**LM CoT (Chain-of-Thought) 파라미터**:\n\n| 파라미터 명 | 타입 | 기본값 | 설명 |\n| :--- | :--- | :--- | :--- |\n| `use_cot_caption` | bool | `true` | CoT 추론을 통해 LM이 입력된 캡션을 다시 쓰거나 개선하도록 합니다. 별칭: `cot_caption`, `cot-caption` |\n| `use_cot_language` | bool | `true` | CoT를 통해 LM이 가창 언어를 감지하도록 합니다. 별칭: `cot_language`, `cot-language` |\n| `constrained_decoding` | bool | `true` | 구조화된 LM 출력을 위해 FSM 기반 제약 디코딩을 활성화합니다. 별칭: `constrainedDecoding`, `constrained` |\n| `constrained_decoding_debug` | bool | `false` | 제약 디코딩에 대한 디버그 로깅 활성화 |\n| `allow_lm_batch` | bool | `true` | 효율성을 위해 LM 배치 처리 허용 |\n\n**편집/참조 오디오 파라미터** (서버의 절대 경로 필요):\n\n| 파라미터 명 | 타입 | 기본값 | 설명 |\n| :--- | :--- | :--- | :--- |\n| `reference_audio_path` | string | null | 참조 오디오 경로 (Style Transfer) |\n| `src_audio_path` | string | null | 소스 오디오 경로 (Repainting/Cover) |\n| `task_type` | string | `\"text2music\"` | 작업 유형: `text2music`, `cover`, `repaint`, `lego`, `extract`, `complete` |\n| `instruction` | string | auto | 편집 지침 (제공되지 않으면 task_type에 따라 자동 생성됨) |\n| `repainting_start` | float | `0.0` | 리페인팅 시작 시간 (초) |\n| `repainting_end` | float | null | 리페인팅 종료 시간 (초), 오디오 끝까지의 경우 -1 |\n| `audio_cover_strength` | float | `1.0` | 오디오 커버 강도 (0.0-1.0). 스타일 전송 작업의 경우 낮은 값(0.2)을 설정합니다. |\n\n#### 방법 B: 파일 업로드 (multipart/form-data)\n\n로컬 오디오 파일을 참조 또는 소스 오디오로 업로드해야 할 때 사용합니다.\n\n위의 모든 필드를 폼 필드로 지원할 뿐만 아니라, 다음 파일 필드도 지원합니다:\n\n- `reference_audio` 또는 `ref_audio`: (파일) 참조 오디오 파일 업로드\n- `src_audio` 또는 `ctx_audio`: (파일) 소스 오디오 파일 업로드\n\n> **참고**: 파일을 업로드하면 해당 `_path` 파라미터는 자동으로 무시되고 시스템은 업로드 후 생성된 임시 파일 경로를 사용합니다.\n\n### 4.3 응답 예시\n\n```json\n{\n  \"data\": {\n    \"task_id\": \"550e8400-e29b-41d4-a716-446655440000\",\n    \"status\": \"queued\",\n    \"queue_position\": 1\n  },\n  \"code\": 200,\n  \"error\": null,\n  \"timestamp\": 1700000000000,\n  \"extra\": null\n}\n```\n\n---\n\n## 5. 작업 결과 배치 조회\n\n### 5.1 API 정의\n\n- **URL**: `/query_result`\n- **Method**: `POST`\n- **Content-Type**: `application/json` 또는 `application/x-www-form-urlencoded`\n\n### 5.2 요청 파라미터\n\n| 파라미터 명 | 타입 | 설명 |\n| :--- | :--- | :--- |\n| `task_id_list` | string (JSON array) or array | 조회할 작업 ID 목록 |\n\n### 5.3 응답 예시\n\n```json\n{\n  \"data\": [\n    {\n      \"task_id\": \"550e8400-e29b-41d4-a716-446655440000\",\n      \"status\": 1,\n      \"result\": \"[{\\\"file\\\": \\\"/v1/audio?path=...\\\", \\\"wave\\\": \\\"\\\", \\\"status\\\": 1, \\\"create_time\\\": 1700000000, \\\"env\\\": \\\"development\\\", \\\"prompt\\\": \\\"upbeat pop song\\\", \\\"lyrics\\\": \\\"Hello world\\\", \\\"metas\\\": {\\\"bpm\\\": 120, \\\"duration\\\": 30, \\\"genres\\\": \\\"\\\", \\\"keyscale\\\": \\\"C Major\\\", \\\"timesignature\\\": \\\"4\\\"}, \\\"generation_info\\\": \\\"...\\\", \\\"seed_value\\\": \\\"12345,67890\\\", \\\"lm_model\\\": \\\"acestep-5Hz-lm-0.6B\\\", \\\"dit_model\\\": \\\"acestep-v15-turbo\\\"}]\"\n    }\n  ],\n  \"code\": 200,\n  \"error\": null,\n  \"timestamp\": 1700000000000,\n  \"extra\": null\n}\n```\n\n**Result 필드 설명** (result는 JSON 문자열이며, 파싱 후 다음을 포함):\n\n| 필드 | 타입 | 설명 |\n| :--- | :--- | :--- |\n| `file` | string | 오디오 파일 URL (`/v1/audio` 엔드포인트와 함께 사용) |\n| `wave` | string | 파형 데이터 (보통 비어 있음) |\n| `status` | int | 상태 코드 (0=진행 중, 1=성공, 2=실패) |\n| `create_time` | int | 생성 시간 (Unix 타임스탬프) |\n| `env` | string | 환경 식별자 |\n| `prompt` | string | 사용된 프롬프트 |\n| `lyrics` | string | 사용된 가사 |\n| `metas` | object | 메타데이터 (bpm, duration, genres, keyscale, timesignature) |\n| `generation_info` | string | 생성 정보 요약 |\n| `seed_value` | string | 사용된 시드 값 (쉼표로 구분) |\n| `lm_model` | string | 사용된 LM 모델 명 |\n| `dit_model` | string | 사용된 DiT 모델 명 |\n\n---\n\n## 6. 입력 포맷팅 (Format Input)\n\n### 6.1 API 정의\n\n- **URL**: `/format_input`\n- **Method**: `POST`\n\n이 엔드포인트는 LLM을 사용하여 사용자가 제공한 캡션과 가사를 개선하고 포맷팅합니다.\n\n### 6.2 요청 파라미터\n\n| 파라미터 명 | 타입 | 기본값 | 설명 |\n| :--- | :--- | :--- | :--- |\n| `prompt` | string | `\"\"` | 음악 설명 프롬프트 |\n| `lyrics` | string | `\"\"` | 가사 내용 |\n| `temperature` | float | `0.85` | LM 샘플링 온도 |\n| `param_obj` | string (JSON) | `\"{}\"` | 메타데이터를 포함하는 JSON 객체 (duration, bpm, key, time_signature, language) |\n\n### 6.3 응답 예시\n\n```json\n{\n  \"data\": {\n    \"caption\": \"Enhanced music description\",\n    \"lyrics\": \"Formatted lyrics...\",\n    \"bpm\": 120,\n    \"key_scale\": \"C Major\",\n    \"time_signature\": \"4\",\n    \"duration\": 180,\n    \"vocal_language\": \"en\"\n  },\n  \"code\": 200,\n  \"error\": null,\n  \"timestamp\": 1700000000000,\n  \"extra\": null\n}\n```\n\n---\n\n## 7. 랜덤 샘플 가져오기\n\n### 7.1 API 정의\n\n- **URL**: `/create_random_sample`\n- **Method**: `POST`\n\n이 엔드포인트는 폼 채우기를 위해 사전 로드된 예제 데이터에서 임의의 샘플 파라미터를 반환합니다.\n\n### 7.2 요청 파라미터\n\n| 파라미터 명 | 타입 | 기본값 | 설명 |\n| :--- | :--- | :--- | :--- |\n| `sample_type` | string | `\"simple_mode\"` | 샘플 유형: `\"simple_mode\"` 또는 `\"custom_mode\"` |\n\n---\n\n## 8. 사용 가능한 모델 목록\n\n### 8.1 API 정의\n\n- **URL**: `/v1/models`\n- **Method**: `GET`\n\n서버에 로드된 사용 가능한 DiT 모델 목록을 반환합니다.\n\n### 8.2 응답 예시\n\n```json\n{\n  \"data\": {\n    \"models\": [\n      {\n        \"name\": \"acestep-v15-turbo\",\n        \"is_default\": true\n      },\n      {\n        \"name\": \"acestep-v15-turbo-shift3\",\n        \"is_default\": false\n      }\n    ],\n    \"default_model\": \"acestep-v15-turbo\"\n  },\n  \"code\": 200,\n  \"error\": null,\n  \"timestamp\": 1700000000000,\n  \"extra\": null\n}\n```\n\n---\n\n## 9. 서버 통계\n\n### 9.1 API 정의\n\n- **URL**: `/v1/stats`\n- **Method**: `GET`\n\n서버 런타임 통계를 반환합니다.\n\n---\n\n## 10. 오디오 파일 다운로드\n\n### 10.1 API 정의\n\n- **URL**: `/v1/audio`\n- **Method**: `GET`\n\n경로별로 생성된 오디오 파일을 다운로드합니다.\n\n### 10.2 요청 파라미터\n\n| 파라미터 명 | 타입 | 설명 |\n| :--- | :--- | :--- |\n| `path` | string | 오디오 파일의 URL 인코딩된 경로 |\n\n---\n\n## 11. 헬스 체크\n\n### 11.1 API 정의\n\n- **URL**: `/health`\n- **Method**: `GET`\n\n서비스 상태를 반환합니다.\n\n---\n\n## 12. 환경 변수\n\nAPI 서버는 환경 변수를 사용하여 구성할 수 있습니다:\n\n### 서버 구성\n\n| 변수 | 기본값 | 설명 |\n| :--- | :--- | :--- |\n| `ACESTEP_API_HOST` | `127.0.0.1` | 서버 바인드 호스트 |\n| `ACESTEP_API_PORT` | `8001` | 서버 바인드 포트 |\n| `ACESTEP_API_KEY` | (비어 있음) | API 인증 키 (비어 있으면 인증 비활성화) |\n| `ACESTEP_API_WORKERS` | `1` | API 워커 스레드 수 |\n\n### 모델 구성\n\n| 변수 | 기본값 | 설명 |\n| :--- | :--- | :--- |\n| `ACESTEP_CONFIG_PATH` | `acestep-v15-turbo` | 주 DiT 모델 경로 |\n| `ACESTEP_DEVICE` | `auto` | 모델 로딩 장치 |\n| `ACESTEP_OFFLOAD_TO_CPU` | `false` | 유휴 시 모델을 CPU로 오프로드 |\n\n### LM 구성\n\n| 변수 | 기본값 | 설명 |\n| :--- | :--- | :--- |\n| `ACESTEP_INIT_LLM` | auto | 시작 시 LM을 초기화할지 여부 (GPU에 따라 자동 결정) |\n| `ACESTEP_LM_MODEL_PATH` | `acestep-5Hz-lm-0.6B` | 기본 5Hz LM 모델 |\n| `ACESTEP_LM_BACKEND` | `vllm` | LM 백엔드 (vllm 또는 pt) |\n\n---\n\n## 에러 처리\n\n**HTTP 상태 코드**:\n\n- `200`: 성공\n- `400`: 잘못된 요청 (잘못된 JSON, 누락된 필드)\n- `401`: 미인증 (누락되었거나 잘못된 API 키)\n- `429`: 서버 바쁨 (대기열이 가득 참)\n- `500`: 내부 서버 오류\n\n---\n\n## 모범 사례\n\n1.  **`thinking=true`를 사용**하여 LM이 향상된 생성 품질의 결과를 얻으세요.\n2.  자연어 설명에서 빠른 생성을 위해 **`sample_query`/`description`을 사용**하세요.\n3.  캡션/가사가 있지만 LM이 이를 개선하기를 원할 때 **`use_format=true`를 사용**하세요.\n4.  `/query_result` 엔드포인트를 사용하여 여러 작업 상태를 **배치 조회**하세요.\n5.  **/v1/stats를 확인**하여 서버 부하와 평균 작업 시간을 파악하세요.\n6.  **보안을 위해** `ACESTEP_API_KEY`를 설정하여 인증을 활성화하세요.\n"
  },
  {
    "path": "docs/ko/GPU_COMPATIBILITY.md",
    "content": "# GPU 호환성 가이드\n\nACE-Step 1.5는 GPU의 사용 가능한 VRAM에 자동으로 적응하여 생성 제한, LM 모델 가용성, 오프로드 전략 및 UI 기본 설정을 적절히 조정합니다. 시스템은 시작 시 GPU 메모리를 감지하고 최적의 설정을 구성합니다.\n\n## GPU 티어 구성\n\n| VRAM | 티어 | LM 모델 | 추천 LM | 백엔드 | 최대 길이 (LM 사용 / 미사용) | 최대 배치 (LM 사용 / 미사용) | 오프로드 | 양자화 |\n|------|------|---------|---------|--------|------------------------------|------------------------------|----------|--------|\n| ≤4GB | 티어 1 | 없음 | — | pt | 4분 / 6분 | 1 / 1 | CPU + DiT | INT8 |\n| 4-6GB | 티어 2 | 없음 | — | pt | 8분 / 10분 | 1 / 1 | CPU + DiT | INT8 |\n| 6-8GB | 티어 3 | 0.6B | 0.6B | pt | 8분 / 10분 | 1 / 2 | CPU + DiT | INT8 |\n| 8-12GB | 티어 4 | 0.6B | 0.6B | vllm | 8분 / 10분 | 2 / 4 | CPU + DiT | INT8 |\n| 12-16GB | 티어 5 | 0.6B, 1.7B | 1.7B | vllm | 8분 / 10분 | 2 / 4 | CPU | INT8 |\n| 16-20GB | 티어 6a | 0.6B, 1.7B | 1.7B | vllm | 8분 / 10분 | 4 / 8 | CPU | INT8 |\n| 20-24GB | 티어 6b | 0.6B, 1.7B, 4B | 1.7B | vllm | 8분 / 8분 | 4 / 8 | 없음 | 없음 |\n| ≥24GB | 제한 없음 | 전체 (0.6B, 1.7B, 4B) | 4B | vllm | 10분 / 10분 | 8 / 8 | 없음 | 없음 |\n\n### 열 설명\n\n- **LM 모델**: 해당 티어에서 로드할 수 있는 5Hz 언어 모델 크기\n- **추천 LM**: UI에서 해당 티어에 기본 선택되는 LM 모델\n- **백엔드**: LM 추론 백엔드 (`vllm`은 충분한 VRAM을 가진 NVIDIA GPU용, `pt`는 PyTorch 대체, `mlx`는 Apple Silicon용)\n- **오프로드**:\n  - **CPU + DiT**: 모든 모델(DiT, VAE, 텍스트 인코더)을 미사용 시 CPU로 오프로드; DiT도 단계 간 오프로드\n  - **CPU**: VAE와 텍스트 인코더를 CPU로 오프로드; DiT는 GPU에 유지\n  - **없음**: 모든 모델을 GPU에 유지\n- **양자화**: VRAM 사용량을 줄이기 위해 기본적으로 INT8 가중치 양자화를 활성화할지 여부\n\n## 적응형 UI 기본 설정\n\nGradio UI는 감지된 GPU 티어에 따라 자동으로 설정됩니다:\n\n- **LM 초기화 체크박스**: LM을 지원하는 티어(티어 3+)에서 기본 체크, 티어 1-2에서는 체크 해제 및 비활성화\n- **LM 모델 경로**: 티어의 추천 모델이 자동 입력; 드롭다운에는 호환 모델만 표시\n- **백엔드 드롭다운**: 티어 1-3에서는 `pt`/`mlx`로 제한(vllm KV 캐시가 메모리를 과도하게 사용); 티어 4+에서는 모든 백엔드 사용 가능\n- **CPU 오프로드 / DiT 오프로드**: 낮은 티어에서 기본 활성화, 높은 티어에서 비활성화\n- **양자화**: 티어 1-6a에서 기본 활성화, 티어 6b+에서 비활성화(충분한 VRAM)\n- **모델 컴파일**: 모든 티어에서 기본 활성화(양자화에 필요)\n\n호환되지 않는 옵션을 수동으로 선택한 경우(예: 6GB GPU에서 vllm 사용 시도), 시스템이 경고를 표시하고 호환 가능한 설정으로 자동 대체합니다.\n\n## 런타임 안전 기능\n\n- **VRAM 가드**: 각 추론 전에 VRAM 요구 사항을 추정하고 필요 시 배치 크기를 자동 축소\n- **적응형 VAE 디코딩**: 3단계 대체: GPU 타일 디코딩 → GPU 디코딩+CPU 오프로드 → 완전 CPU 디코딩\n- **자동 청크 크기**: VAE 디코딩 청크 크기가 사용 가능한 여유 VRAM에 적응(64/128/256/512/1024/1536)\n- **길이/배치 클램핑**: 티어 제한을 초과하는 값을 요청하면 경고와 함께 자동 조정\n\n## 참고 사항\n\n- **기본 설정**은 감지된 GPU 메모리에 따라 자동으로 구성됩니다\n- **LM 모드**는 Chain-of-Thought 생성 및 오디오 이해에 사용되는 언어 모델을 의미합니다\n- **Flash Attention**은 자동 감지되며 사용 가능할 때 활성화됩니다\n- **제약 디코딩**: LM이 초기화되면 LM의 길이 생성도 GPU 티어의 최대 길이 제한으로 제약되어 CoT 생성 중 OOM 에러를 방지합니다\n- VRAM이 6GB 이하인 GPU(티어 1-2)의 경우, DiT 모델의 메모리 확보를 위해 LM 초기화가 기본적으로 비활성화됩니다\n- CLI 인자 또는 Gradio UI를 통해 설정을 수동으로 무시할 수 있습니다\n\n> **커뮤니티 기여 환영**: 위의 GPU 티어 구성은 일반적인 하드웨어에서의 테스트를 바탕으로 합니다. 사용 중인 장치의 실제 성능이 이 파라미터와 다르다면, 더 철저한 테스트를 수행하고 `acestep/gpu_config.py`에서 구성을 최적화하기 위한 PR을 제출해 주시기 바랍니다.\n\n## 메모리 최적화 팁\n\n1. **초저 VRAM (≤6GB)**: LM 초기화 없이 DiT 전용 모드를 사용. INT8 양자화와 완전 CPU 오프로드가 필수. VAE 디코딩이 자동으로 CPU로 대체될 수 있습니다.\n2. **저 VRAM (6-8GB)**: `pt` 백엔드로 0.6B LM 모델 사용 가능. 오프로드를 활성 상태로 유지하세요.\n3. **중간 VRAM (8-16GB)**: 0.6B 또는 1.7B LM 모델을 사용. 티어 4+에서 `vllm` 백엔드가 잘 작동합니다.\n4. **높은 VRAM (16-24GB)**: 더 큰 LM 모델(1.7B 추천)을 활성화. 20GB+에서는 양자화가 선택 사항이 됩니다.\n5. **초고 VRAM (≥24GB)**: 모든 모델이 오프로드나 양자화 없이 작동. 최고 품질을 위해 4B LM을 사용하세요.\n\n## 디버그 모드: 다른 GPU 구성 시뮬레이션\n\n테스트 및 개발을 위해 `MAX_CUDA_VRAM` 환경 변수를 사용하여 다른 GPU 메모리 크기를 시뮬레이션할 수 있습니다:\n\n```bash\n# 4GB GPU 시뮬레이션 (티어 1)\nMAX_CUDA_VRAM=4 uv run acestep\n\n# 6GB GPU 시뮬레이션 (티어 2)\nMAX_CUDA_VRAM=6 uv run acestep\n\n# 8GB GPU 시뮬레이션 (티어 4)\nMAX_CUDA_VRAM=8 uv run acestep\n\n# 12GB GPU 시뮬레이션 (티어 5)\nMAX_CUDA_VRAM=12 uv run acestep\n\n# 16GB GPU 시뮬레이션 (티어 6a)\nMAX_CUDA_VRAM=16 uv run acestep\n```\n\n`MAX_CUDA_VRAM`을 설정하면 시스템은 `torch.cuda.set_per_process_memory_fraction()`을 호출하여 VRAM 하드 캡을 강제하며, 고사양 GPU에서도 현실적인 시뮬레이션을 제공합니다.\n\n### 자동 티어 테스트\n\nUI에서 각 티어를 수동으로 테스트하는 대신, `profile_inference.py`의 `tier-test` 모드를 사용할 수 있습니다:\n\n```bash\n# 모든 티어 자동 테스트\npython profile_inference.py --mode tier-test\n\n# 특정 티어 테스트\npython profile_inference.py --mode tier-test --tiers 6 8 16\n\n# LM 활성화하여 테스트 (지원되는 티어에서)\npython profile_inference.py --mode tier-test --tier-with-lm\n\n# 빠른 테스트 (비양자화 티어에서 torch.compile 건너뛰기)\npython profile_inference.py --mode tier-test --tier-skip-compile\n```\n\n프로파일링 도구의 전체 문서는 [BENCHMARK.md](BENCHMARK.md)를 참조하세요.\n\n이는 다음과 같은 경우에 유용합니다:\n- 고사양 하드웨어에서 GPU 티어 구성 테스트\n- 각 티어에 대해 경고 및 제한이 올바르게 작동하는지 확인\n- `acestep/gpu_config.py` 수정 후 자동 회귀 테스트\n- CI/CD VRAM 호환성 검증\n\n### 경계 테스트 (최소 티어 찾기)\n\n`--tier-boundary`를 사용하면 INT8 양자화와 CPU 오프로드를 안전하게 비활성화할 수 있는 최소 VRAM 티어를 실험적으로 확인할 수 있습니다. 각 티어에 대해 최대 3가지 구성으로 테스트합니다:\n\n1. **default** — 티어의 기본 설정 (양자화 + 오프로드를 구성대로 사용)\n2. **no-quant** — 오프로드 설정은 유지하되 양자화 비활성화\n3. **no-offload** — 양자화 없음, CPU 오프로드 없음 (모든 모델을 GPU에 유지)\n\n```bash\n# 모든 티어에서 경계 테스트 실행\npython profile_inference.py --mode tier-test --tier-boundary\n\n# 특정 티어의 경계 테스트\npython profile_inference.py --mode tier-test --tier-boundary --tiers 8 12 16 20 24\n\n# LM 활성화된 경계 테스트 (지원되는 티어에서)\npython profile_inference.py --mode tier-test --tier-boundary --tier-with-lm\n\n# 결과를 JSON으로 저장\npython profile_inference.py --mode tier-test --tier-boundary --benchmark-output boundary_results.json\n```\n\n> **참고:** 경계 테스트 결과는 경험적이며, DiT 모델 변형 (turbo vs base), LM 활성화 여부, 생성 시간, flash attention 가용성에 따라 달라질 수 있습니다.\n\n### 배치 크기 경계 테스트\n\n`--tier-batch-boundary`를 사용하여 배치 크기 1, 2, 4, 8을 단계적으로 테스트하여 각 티어의 최대 안전 배치 크기를 찾습니다:\n\n```bash\n# LM 활성화 상태에서 배치 경계 테스트 실행\npython profile_inference.py --mode tier-test --tier-batch-boundary --tier-with-lm\n\n# 특정 티어 테스트\npython profile_inference.py --mode tier-test --tier-batch-boundary --tier-with-lm --tiers 8 12 16 24\n```\n\nLM 사용/미사용 두 가지 구성을 모두 테스트하고 각 티어의 최대 성공 배치 크기를 보고합니다.\n"
  },
  {
    "path": "docs/ko/GRADIO_GUIDE.md",
    "content": "# ACE-Step Gradio 데모 사용자 가이드\n\n**언어 / Language / 语言 / 言語:** [English](../en/GRADIO_GUIDE.md) | [한국어](GRADIO_GUIDE.md) | [中文](../zh/GRADIO_GUIDE.md) | [日本語](../ja/GRADIO_GUIDE.md)\n\n---\n\n이 가이드는 ACE-Step Gradio 웹 인터페이스를 사용한 음악 생성에 대한 포괄적인 문서를 제공하며, 모든 기능과 설정을 포함합니다.\n\n## 목차\n\n- [시작하기](#시작하기)\n- [서비스 설정](#서비스-설정)\n- [생성 모드](#생성-모드)\n- [입력 파라미터](#입력-파라미터)\n- [고급 설정](#고급-설정)\n- [결과 섹션](#결과-섹션)\n- [LoRA 학습](#lora-학습)\n- [팁과 모범 사례](#팁과-모범-사례)\n\n---\n\n## 시작하기\n\n### 데모 실행\n\n```bash\n# 기본 실행\npython app.py\n\n# 사전 초기화 포함\npython app.py --config acestep-v15-turbo --init-llm\n\n# 특정 포트 지정\npython app.py --port 7860\n```\n\n### 인터페이스 개요\n\nGradio 인터페이스의 레이아웃:\n\n1. **설정** (접이식 아코디언) - 서비스 설정, DiT/LM 파라미터, 출력 옵션\n2. **생성 탭** - 메인 작업 공간. 상단에 **생성 모드** 라디오 선택기:\n   - Turbo/SFT 모델: Simple, Custom, Remix, Repaint\n   - Base 모델: Simple, Custom, Remix, Repaint, Extract, Lego, Complete\n3. **결과 섹션** - 생성된 오디오 재생, 스코어링, 배치 내비게이션\n4. **학습 탭** - 데이터셋 빌더 및 LoRA 학습\n\n---\n\n## 서비스 설정\n\n### 모델 선택\n\n| 설정 | 설명 |\n|------|------|\n| **체크포인트 파일** | 학습된 모델 체크포인트 선택 (사용 가능한 경우) |\n| **메인 모델 경로** | DiT 모델 설정 선택 (예: `acestep-v15-turbo`, `acestep-v15-turbo-shift3`) |\n| **디바이스** | 처리 디바이스: `auto` (권장), `cuda`, 또는 `cpu` |\n\n### 5Hz LM 설정\n\n| 설정 | 설명 |\n|------|------|\n| **5Hz LM 모델 경로** | 언어 모델 선택. **사용 가능한 모델은 GPU 티어에 따라 자동 필터링** — 예: 6-8GB GPU는 0.6B만, 24GB+ GPU는 모든 크기(0.6B, 1.7B, 4B) 표시. |\n| **5Hz LM 백엔드** | `vllm` (더 빠름, VRAM ≥8GB NVIDIA GPU 권장), `pt` (PyTorch, 범용 폴백), 또는 `mlx` (Apple Silicon). **VRAM <8GB GPU에서는 `pt`/`mlx`로 제한** (vllm의 KV 캐시가 메모리를 과도하게 사용하므로). |\n| **5Hz LM 초기화** | 초기화 시 LM을 로드하려면 체크 (thinking 모드에 필요). **VRAM ≤6GB GPU(Tier 1-2)에서 기본적으로 체크 해제 및 비활성화.** |\n\n> **적응형 기본값**: 모든 LM 설정은 GPU의 VRAM 티어에 따라 자동 구성됩니다. 권장 LM 모델, 백엔드, 초기화 상태가 최적 성능을 위해 사전 설정됩니다. 수동으로 변경할 수 있지만, GPU와 호환되지 않는 선택 시 시스템이 경고를 표시합니다.\n\n### 성능 옵션\n\n| 설정 | 설명 |\n|------|------|\n| **Flash Attention 사용** | 더 빠른 추론을 위해 활성화 (flash_attn 패키지 필요) |\n| **CPU로 오프로드** | 유휴 시 모델을 CPU로 오프로드하여 GPU 메모리 절약. **VRAM <20GB GPU에서 자동 활성화.** |\n| **DiT를 CPU로 오프로드** | DiT 모델을 특별히 CPU로 오프로드. **VRAM <12GB GPU에서 자동 활성화.** |\n| **INT8 양자화** | INT8 가중치 양자화로 모델 VRAM 사용량 감소. **VRAM <20GB GPU에서 자동 활성화.** |\n| **모델 컴파일** | 최적화된 추론을 위해 `torch.compile` 활성화. **모든 티어에서 기본 활성화** (양자화 활성 시 필요). |\n\n> **티어 인식 설정**: 오프로드, 양자화, 컴파일 옵션은 GPU 티어에 따라 자동 설정됩니다. 전체 티어 테이블은 [GPU_COMPATIBILITY.md](../ko/GPU_COMPATIBILITY.md)를 참조하세요.\n\n### LoRA 어댑터\n\n| 설정 | 설명 |\n|------|------|\n| **LoRA 경로** | 학습된 LoRA 어댑터 디렉토리 경로 |\n| **LoRA 로드** | 지정된 LoRA 어댑터 로드 |\n| **언로드** | 현재 로드된 LoRA 제거 |\n| **LoRA 사용** | 추론용 로드된 LoRA 활성화/비활성화 |\n\n> **⚠️ 참고:** PEFT와 TorchAO 간 호환성 문제로 양자화된 모델에 LoRA 어댑터를 로드할 수 없습니다. LoRA를 사용해야 하는 경우 어댑터를 로드하기 전에 **INT8 양자화**를 **None**으로 설정하세요.\n\n### 초기화\n\n**서비스 초기화**를 클릭하여 모델을 로드합니다. 상태 박스에 다음을 포함한 진행 상황과 확인이 표시됩니다:\n- 감지된 GPU 티어 및 VRAM\n- 최대 허용 시간 및 배치 크기 (LM 초기화 여부에 따라 동적 조정)\n- 자동 수정된 호환되지 않는 설정에 대한 경고\n\n초기화 후 **오디오 시간** 및 **배치 크기** 슬라이더가 티어 제한을 반영하도록 자동 업데이트됩니다.\n\n---\n\n## 생성 모드\n\n생성 탭 상단의 **생성 모드** 라디오 선택기가 워크플로를 결정합니다. Turbo 및 SFT 모델은 4가지 모드를 제공하고, Base 모델은 3가지를 추가로 제공합니다.\n\n### Simple 모드\n\n빠른 자연어 기반 음악 생성을 위해 설계되었습니다.\n\n**사용 방법:**\n1. 생성 모드에서 **Simple** 선택\n2. \"곡 설명\" 필드에 자연어 설명 입력\n3. 보컬이 필요 없으면 \"인스트루멘탈\" 옵션 체크\n4. 선호하는 보컬 언어 옵션 선택\n5. **샘플 생성** 클릭하여 caption, 가사, 메타데이터 생성\n6. 확장된 섹션에서 생성된 콘텐츠 확인\n7. **음악 생성** 클릭하여 오디오 생성\n\n**설명 예시:**\n- \"조용한 저녁을 위한 부드러운 벵골 러브송\"\n- \"강렬한 베이스 드롭이 있는 업비트 일렉트로닉 댄스 뮤직\"\n- \"어쿠스틱 기타의 멜랑콜리한 인디 포크\"\n- \"연기 자욱한 바에서 연주하는 재즈 트리오\"\n\n**랜덤 샘플:** 🎲 버튼을 클릭하여 랜덤 예시 설명을 로드합니다.\n\n### Custom 모드\n\n모든 생성 파라미터를 완전히 제어합니다 (text2music).\n\n**사용 방법:**\n1. 생성 모드에서 **Custom** 선택\n2. Caption과 가사 필드를 수동으로 입력\n3. 옵션으로 참조 오디오를 업로드하여 스타일 가이던스\n4. 옵션 메타데이터 설정 (BPM, 키, 시간 등)\n5. 옵션으로 **포맷** 클릭하여 LM으로 입력 향상\n6. 필요에 따라 고급 설정 구성\n7. **음악 생성** 클릭하여 오디오 생성\n\n### Remix 모드\n\n기존 오디오의 멜로디 구조를 유지하면서 스타일을 변경합니다.\n\n**사용 방법:**\n1. 생성 모드에서 **Remix** 선택\n2. 소스 오디오 업로드 (리믹스할 곡)\n3. 타겟 스타일을 설명하는 Caption 작성\n4. 옵션으로 가사 수정\n5. **Remix 강도** (0.0-1.0) 조정: 높을수록 = 원본 구조에 가까움\n6. **음악 생성** 클릭\n\n**용도:** 커버 버전 생성, 스타일 전이, 곡 변형 생성.\n\n### Repaint 모드\n\n오디오의 특정 시간 구간을 재생성하고 나머지는 유지합니다.\n\n**사용 방법:**\n1. 생성 모드에서 **Repaint** 선택\n2. 소스 오디오 업로드\n3. **리페인트 시작**과 **리페인트 끝** 설정 (초; -1은 파일 끝)\n4. 리페인트 섹션의 원하는 콘텐츠를 설명하는 Caption 작성\n5. **음악 생성** 클릭\n\n**용도:** 문제 있는 섹션 수정, 구간 내 가사 변경, 곡 연장.\n\n### Extract 모드 (Base 모델 전용)\n\n믹스된 오디오에서 특정 악기 트랙을 추출/분리합니다.\n\n**사용 방법:**\n1. 생성 모드에서 **Extract** 선택\n2. 소스 오디오 업로드\n3. 드롭다운에서 추출할 **트랙 이름** 선택\n4. **음악 생성** 클릭\n\n**사용 가능한 트랙:** vocals, backing_vocals, drums, bass, guitar, keyboard, percussion, strings, synth, fx, brass, woodwinds\n\n### Lego 모드 (Base 모델 전용)\n\n기존 오디오에 새로운 악기 트랙을 추가합니다.\n\n**사용 방법:**\n1. 생성 모드에서 **Lego** 선택\n2. 소스 오디오 업로드\n3. 드롭다운에서 추가할 **트랙 이름** 선택\n4. 트랙 특성을 설명하는 Caption 작성\n5. **음악 생성** 클릭\n\n### Complete 모드 (Base 모델 전용)\n\n지정된 악기로 부분적인 트랙을 완성합니다 (자동 편곡).\n\n**사용 방법:**\n1. 생성 모드에서 **Complete** 선택\n2. 소스 오디오 업로드\n3. 추가할 여러 **트랙 이름** 선택\n4. 원하는 스타일을 설명하는 Caption 작성\n5. **음악 생성** 클릭\n\n---\n\n## 입력 파라미터\n\n### 오디오 입력\n\n| 필드 | 설명 |\n|------|------|\n| **참조 오디오** | 스타일/음색 가이던스를 위한 옵션 오디오 (Custom 모드에서 표시) |\n| **소스 오디오** | Remix, Repaint, Extract, Lego, Complete 모드에 필수 |\n| **코드로 변환** | 소스 오디오에서 5Hz 시맨틱 코드 추출 |\n\n#### LM 코드 힌트 (Custom 모드)\n\n사전 계산된 오디오 시맨틱 코드를 여기에 붙여넣어 생성을 가이드할 수 있습니다. **트랜스크라이브** 버튼을 사용하여 코드를 분석하고 메타데이터를 추출합니다. 소스 오디오 업로드 없이 멜로디 구조를 제어하기 위한 고급 기능입니다.\n\n### 음악 Caption\n\n원하는 음악의 텍스트 설명. 다음에 대해 구체적으로 작성:\n- 장르와 스타일\n- 악기\n- 분위기와 느낌\n- 템포 느낌 (BPM을 지정하지 않는 경우)\n\n**예시:** \"일렉 기타, 강렬한 드럼, 캐치한 신스 훅이 있는 업비트 팝 록\"\n\n🎲를 클릭하여 랜덤 예시 caption을 로드합니다.\n\n### 가사\n\n구조 태그가 포함된 가사를 입력:\n\n```\n[Verse 1]\n오늘 거리를 걸으며\n네가 했던 말들을 떠올렸어\n\n[Chorus]\n나는 앞으로 나아가, 강하게 서서\n여기가 내 자리야\n\n[Verse 2]\n...\n```\n\n**인스트루멘탈 체크박스:** 가사 내용에 관계없이 인스트루멘탈 음악을 생성하려면 체크합니다.\n\n**보컬 언어:** 보컬 언어를 선택합니다. 자동 감지 또는 인스트루멘탈 트랙에는 \"unknown\"을 사용합니다.\n\n**포맷 버튼:** 5Hz LM을 사용하여 caption과 가사를 향상시키려면 클릭합니다.\n\n### 옵션 파라미터\n\n| 파라미터 | 기본값 | 설명 |\n|----------|--------|------|\n| **BPM** | 자동 | 분당 비트 수 (30-300) |\n| **키 스케일** | 자동 | 음악 키 (예: \"C Major\", \"Am\", \"F# minor\") |\n| **박자 기호** | 자동 | 박자 기호: 2 (2/4), 3 (3/4), 4 (4/4), 6 (6/8) |\n| **오디오 시간** | 자동/-1 | 목표 길이(초) (10-600). -1은 자동 |\n| **배치 크기** | 2 | 생성할 오디오 변형 수 (1-8) |\n\n---\n\n## 고급 설정\n\n### DiT 파라미터\n\n| 파라미터 | 기본값 | 설명 |\n|----------|--------|------|\n| **추론 스텝** | 8 | 디노이징 스텝. Turbo: 1-20, Base: 1-200 |\n| **가이던스 스케일** | 7.0 | CFG 강도 (base 모델만). 높을수록 = 프롬프트를 더 따름 |\n| **시드** | -1 | 랜덤 시드. 배치에는 쉼표로 구분된 값 사용 |\n| **랜덤 시드** | ✓ | 체크 시 랜덤 시드 생성 |\n| **오디오 형식** | mp3 | 출력 형식: mp3, flac |\n| **시프트** | 3.0 | 타임스텝 시프트 계수 (1.0-5.0). turbo에 3.0 권장 |\n| **추론 방법** | ode | ode (Euler, 더 빠름) 또는 sde (확률적) |\n| **커스텀 타임스텝** | - | 타임스텝 오버라이드 (예: \"0.97,0.76,0.615,0.5,0.395,0.28,0.18,0.085,0\") |\n\n### Base 모델 전용 파라미터\n\n| 파라미터 | 기본값 | 설명 |\n|----------|--------|------|\n| **ADG 사용** | ✗ | 더 나은 품질을 위해 적응형 듀얼 가이던스 활성화 |\n| **CFG 구간 시작** | 0.0 | CFG 적용 시작 시점 (0.0-1.0) |\n| **CFG 구간 끝** | 1.0 | CFG 적용 종료 시점 (0.0-1.0) |\n\n### LM 파라미터\n\n| 파라미터 | 기본값 | 설명 |\n|----------|--------|------|\n| **LM 온도** | 0.85 | 샘플링 온도 (0.0-2.0). 높을수록 = 더 창의적 |\n| **LM CFG 스케일** | 2.0 | LM 가이던스 강도 (1.0-3.0) |\n| **LM Top-K** | 0 | Top-K 샘플링. 0이면 비활성화 |\n| **LM Top-P** | 0.9 | 핵 샘플링 (0.0-1.0) |\n| **LM 네거티브 프롬프트** | \"NO USER INPUT\" | CFG용 네거티브 프롬프트 |\n\n### CoT (사고의 연쇄) 옵션\n\n| 옵션 | 기본값 | 설명 |\n|------|--------|------|\n| **CoT Metas** | ✓ | LM 추론을 통해 메타데이터 생성 |\n| **CoT Language** | ✓ | LM으로 보컬 언어 감지 |\n| **제약 디코딩 디버그** | ✗ | 디버그 로깅 활성화 |\n\n### 생성 옵션\n\n| 옵션 | 기본값 | 설명 |\n|------|--------|------|\n| **LM 코드 강도** | 1.0 | LM 코드가 생성에 미치는 영향의 강도 (0.0-1.0) |\n| **자동 스코어** | ✗ | 품질 스코어 자동 계산 |\n| **자동 LRC** | ✗ | 가사 타임스탬프 자동 생성 |\n| **LM 배치 청크 크기** | 8 | LM 배치당 최대 항목 수 (GPU 메모리) |\n\n### 메인 생성 컨트롤\n\n| 컨트롤 | 설명 |\n|--------|------|\n| **Think** | 코드 생성 및 메타데이터를 위한 5Hz LM 활성화 |\n| **ParallelThinking** | 병렬 LM 배치 처리 활성화 |\n| **CaptionRewrite** | LM이 입력 caption을 향상시키도록 함 |\n| **AutoGen** | 완료 후 다음 배치 자동 시작 |\n\n---\n\n## 결과 섹션\n\n### 생성된 오디오\n\n배치 크기에 따라 최대 8개의 오디오 샘플이 표시됩니다. 각 샘플에는 다음이 포함됩니다:\n\n- **오디오 플레이어** - 생성된 오디오 재생, 일시 정지, 다운로드\n- **소스로 전송** - 이 오디오를 소스 오디오 입력으로 전송하여 추가 처리\n- **저장** - 오디오와 메타데이터를 JSON 파일로 저장\n- **스코어** - 퍼플렉시티 기반 품질 스코어 계산\n- **LRC** - 가사 타임스탬프 생성 (LRC 형식)\n\n### 상세 아코디언\n\n\"Score & LRC & LM Codes\"를 클릭하여 확장하고 다음을 확인:\n- **LM 코드** - 이 샘플의 5Hz 시맨틱 코드\n- **품질 스코어** - 퍼플렉시티 기반 품질 메트릭\n- **가사 타임스탬프** - LRC 형식 타이밍 데이터\n\n### 배치 내비게이션\n\n| 컨트롤 | 설명 |\n|--------|------|\n| **◀ 이전** | 이전 배치 보기 |\n| **배치 인디케이터** | 현재 배치 위치 표시 (예: \"배치 1 / 3\") |\n| **다음 배치 상태** | 백그라운드 생성 진행 상황 표시 |\n| **다음 ▶** | 다음 배치 보기 (AutoGen이 켜져 있으면 생성 트리거) |\n\n### 파라미터 복원\n\n**이 설정을 UI에 적용**을 클릭하여 현재 배치의 모든 생성 파라미터를 입력 필드로 복원합니다. 좋은 결과를 반복하는 데 유용합니다.\n\n### 배치 결과\n\n\"배치 결과 및 생성 상세\" 아코디언에는 다음이 포함됩니다:\n- **모든 생성 파일** - 모든 배치의 모든 파일 다운로드\n- **생성 상세** - 생성 과정에 대한 상세 정보\n\n---\n\n## LoRA 학습\n\nLoRA 학습 탭은 커스텀 LoRA 어댑터를 만들기 위한 도구를 제공합니다.\n\n> 📖 **전체 단계별 안내** (데이터 준비, 주석, 전처리, 학습, 내보내기)는 [LoRA 학습 튜토리얼](./LoRA_Training_Tutorial.md)을 참조하세요.\n\n### 데이터셋 빌더 탭\n\n#### 1단계: 로드 또는 스캔\n\n**옵션 A: 기존 데이터셋 로드**\n1. 이전에 저장한 데이터셋 JSON 경로 입력\n2. **로드** 클릭\n\n**옵션 B: 새 디렉토리 스캔**\n1. 오디오 폴더 경로 입력\n2. **스캔** 클릭하여 오디오 파일 검색 (wav, mp3, flac, ogg, opus)\n\n#### 2단계: 데이터셋 설정\n\n| 설정 | 설명 |\n|------|------|\n| **데이터셋 이름** | 데이터셋 이름 |\n| **모두 인스트루멘탈** | 모든 트랙에 보컬이 없는 경우 체크 |\n| **커스텀 활성화 태그** | 이 LoRA의 스타일을 활성화하는 고유 태그 |\n| **태그 위치** | 태그를 배치할 위치: 앞에 추가, 뒤에 추가, 또는 caption 대체 |\n\n#### 3단계: 자동 라벨링\n\n**모두 자동 라벨링**을 클릭하여 모든 오디오 파일의 메타데이터를 생성:\n- Caption (음악 설명)\n- BPM\n- 키\n- 박자 기호\n\n**메타 건너뛰기** 옵션은 LLM 라벨링을 건너뛰고 N/A 값을 사용합니다.\n\n#### 4단계: 미리보기 및 편집\n\n슬라이더를 사용하여 샘플을 선택하고 수동 편집:\n- Caption\n- 가사\n- BPM, 키, 박자 기호\n- 언어\n- 인스트루멘탈 플래그\n\n**변경 저장**을 클릭하여 샘플을 업데이트합니다.\n\n#### 5단계: 데이터셋 저장\n\n저장 경로를 입력하고 **데이터셋 저장**을 클릭하여 JSON으로 내보냅니다.\n\n#### 6단계: 전처리\n\n빠른 학습을 위해 데이터셋을 사전 계산 텐서로 변환:\n1. 옵션으로 기존 데이터셋 JSON 로드\n2. 텐서 출력 디렉토리 설정\n3. **전처리** 클릭\n\n이것은 오디오를 VAE 잠재 변수로 인코딩하고, 텍스트를 임베딩으로 인코딩하며, 조건 인코더를 실행합니다.\n\n### LoRA 학습 탭\n\n#### 데이터셋 선택\n\n전처리된 텐서 디렉토리 경로를 입력하고 **데이터셋 로드**를 클릭합니다.\n\n#### LoRA 설정\n\n| 설정 | 기본값 | 설명 |\n|------|--------|------|\n| **LoRA 랭크 (r)** | 64 | LoRA의 용량. 높을수록 = 더 많은 용량, 더 많은 메모리 |\n| **LoRA 알파** | 128 | 스케일링 계수 (일반적으로 랭크의 2배) |\n| **LoRA 드롭아웃** | 0.1 | 정규화를 위한 드롭아웃 비율 |\n\n#### 학습 파라미터\n\n| 설정 | 기본값 | 설명 |\n|------|--------|------|\n| **학습률** | 1e-4 | 최적화 학습률 |\n| **최대 에폭** | 500 | 최대 학습 에폭 |\n| **배치 크기** | 1 | 학습 배치 크기 |\n| **그래디언트 누적** | 1 | 유효 배치 = batch_size × accumulation |\n| **N 에폭마다 저장** | 200 | 체크포인트 저장 빈도 |\n| **시프트** | 3.0 | turbo 모델의 타임스텝 시프트 |\n| **시드** | 42 | 재현성을 위한 랜덤 시드 |\n\n#### 학습 컨트롤\n\n- **학습 시작** - 학습 프로세스 시작\n- **학습 중지** - 학습 중단\n- **학습 진행** - 현재 에폭과 손실 표시\n- **학습 로그** - 상세 학습 출력\n- **학습 손실 플롯** - 시각적 손실 곡선\n\n#### LoRA 내보내기\n\n학습 후 최종 어댑터를 내보냅니다:\n1. 내보내기 경로 입력\n2. **LoRA 내보내기** 클릭\n\n---\n\n## 팁과 모범 사례\n\n### 최고 품질을 위해\n\n1. **thinking 모드 사용** - LM 향상 생성을 위해 \"Think\" 체크박스를 활성화 유지\n2. **caption을 구체적으로** - 장르, 악기, 분위기, 스타일 세부 사항 포함\n3. **LM이 메타데이터를 감지하도록** - 자동 감지를 위해 BPM/키/시간을 비워 둠\n4. **배치 생성 사용** - 2-4개 변형을 생성하고 최적의 것을 선택\n\n### 더 빠른 생성을 위해\n\n1. **turbo 모델 사용** - `acestep-v15-turbo` 또는 `acestep-v15-turbo-shift3` 선택\n2. **추론 스텝을 8로 유지** - turbo에 최적인 기본값\n3. **배치 크기 줄이기** - 빠른 결과가 필요하면 배치 크기 낮추기\n4. **AutoGen 비활성화** - 배치 생성의 수동 제어\n\n### 일관된 결과를 위해\n\n1. **특정 시드 설정** - \"랜덤 시드\" 체크 해제 후 시드 값 입력\n2. **좋은 결과 저장** - 재현을 위해 파라미터를 내보내려면 \"저장\" 사용\n3. **\"이 설정 적용\" 사용** - 좋은 배치에서 파라미터 복원\n\n### 장시간 음악을 위해\n\n1. **명시적 시간 설정** - 초 단위로 시간 지정\n2. **Repaint 모드 사용** - 초기 생성 후 문제 있는 섹션 수정\n3. **생성 체인** - \"소스로 전송\"을 사용하여 이전 결과를 기반으로 구축\n\n### 스타일 일관성을 위해\n\n1. **LoRA 학습** - 스타일에 맞는 커스텀 어댑터 생성\n2. **참조 오디오 사용** - 오디오 업로드에서 스타일 참조 업로드\n3. **일관된 caption 사용** - 유사한 설명적 언어 유지\n\n### 문제 해결\n\n**오디오가 생성되지 않음:**\n- 모델이 초기화되었는지 확인 (녹색 상태 메시지)\n- thinking 모드 사용 시 5Hz LM이 초기화되었는지 확인\n- 오류 메시지에 대한 상태 출력 확인\n\n**결과 품질이 낮음:**\n- 추론 스텝 증가 (base 모델의 경우)\n- 가이던스 스케일 조정\n- 다른 시드 시도\n- caption을 더 구체적으로 작성\n\n**메모리 부족 (OOM):**\n- 시스템에 자동 VRAM 관리 (VRAM 가드, 적응형 VAE 디코드, 자동 배치 축소) 포함. 그래도 OOM 발생 시:\n- 수동으로 배치 크기 줄이기\n- CPU 오프로드 활성화 (VRAM <20GB에서 자동 활성화되어야 함)\n- INT8 양자화 활성화 (VRAM <20GB에서 자동 활성화되어야 함)\n- LM 배치 청크 크기 줄이기\n\n**LM이 작동하지 않음:**\n- 초기화 시 \"5Hz LM 초기화\"가 체크되었는지 확인 (VRAM ≤6GB GPU에서 기본 비활성화)\n- 유효한 LM 모델 경로가 선택되었는지 확인 (티어 호환 모델만 표시)\n- vllm 또는 PyTorch 백엔드가 사용 가능한지 확인 (VRAM <8GB에서 vllm 제한)\n- LM 체크박스가 회색이면 GPU 티어가 LM을 지원하지 않음 — DiT 전용 모드 사용\n\n---\n\n## 키보드 단축키\n\nGradio 인터페이스는 표준 웹 단축키를 지원합니다:\n- **Tab** - 입력 필드 간 이동\n- **Enter** - 텍스트 입력 제출\n- **Space** - 체크박스 토글\n\n---\n\n## 언어 지원\n\n인터페이스는 여러 UI 언어를 지원합니다:\n- **영어** (en)\n- **중국어** (zh)\n- **일본어** (ja)\n- **한국어** (ko)\n\n서비스 설정 섹션에서 선호하는 언어를 선택하세요.\n\n---\n\n자세한 내용은 다음을 참조하세요:\n- 메인 README: [`../../README.md`](../../README.md)\n- REST API 문서: [`../en/API.md`](../en/API.md)\n- Python 추론 API: [`../en/INFERENCE.md`](../en/INFERENCE.md)\n"
  },
  {
    "path": "docs/ko/INFERENCE.md",
    "content": "# ACE-Step 추론 API 문서\n\n**언어 / Language / 语言 / 言語:** [English](INFERENCE.md) | [한국어](INFERENCE.md) | [中文](../zh/INFERENCE.md) | [日本語](../ja/INFERENCE.md)\n\n---\n\n이 문서는 모든 지원되는 작업 유형에 대한 파라미터 사양을 포함하여 ACE-Step 추론 API에 대한 포괄적인 문서를 제공합니다.\n\n## 목차\n\n- [빠른 시작](#빠른-시작)\n- [API 개요](#api-개요)\n- [GenerationParams 파라미터](#generationparams-파라미터)\n- [GenerationConfig 파라미터](#generationconfig-파라미터)\n- [작업 유형 (Task Types)](#작업-유형-task-types)\n- [도우미 함수](#도우미-함수)\n- [전체 예제](#전체-예제)\n- [모범 사례](#모범-사례)\n\n---\n\n## 빠른 시작\n\n### 기본 사용법\n\n```python\nfrom acestep.handler import AceStepHandler\nfrom acestep.llm_inference import LLMHandler\nfrom acestep.inference import GenerationParams, GenerationConfig, generate_music\n\n# 핸들러 초기화\ndit_handler = AceStepHandler()\nllm_handler = LLMHandler()\n\n# 서비스 초기화\ndit_handler.initialize_service(\n    project_root=\"/path/to/project\",\n    config_path=\"acestep-v15-turbo\",\n    device=\"cuda\"\n)\n\nllm_handler.initialize(\n    checkpoint_dir=\"/path/to/checkpoints\",\n    lm_model_path=\"acestep-5Hz-lm-0.6B\",\n    backend=\"vllm\",\n    device=\"cuda\"\n)\n\n# 생성 파라미터 설정\nparams = GenerationParams(\n    caption=\"upbeat electronic dance music with heavy bass\",\n    bpm=128,\n    duration=30,\n)\n\n# 생성 설정 구성\nconfig = GenerationConfig(\n    batch_size=2,\n    audio_format=\"flac\",\n)\n\n# 음악 생성\nresult = generate_music(dit_handler, llm_handler, params, config, save_dir=\"/path/to/output\")\n\n# 결과 확인\nif result.success:\n    for audio in result.audios:\n        print(f\"Generated: {audio['path']}\")\n        print(f\"Key: {audio['key']}\")\n        print(f\"Seed: {audio['params']['seed']}\")\nelse:\n    print(f\"Error: {result.error}\")\n```\n\n---\n\n## API 개요\n\n### 주요 함수\n\n#### generate_music\n\n```python\ndef generate_music(\n    dit_handler,\n    llm_handler,\n    params: GenerationParams,\n    config: GenerationConfig,\n    save_dir: Optional[str] = None,\n    progress=None,\n) -> GenerationResult\n```\n\nACE-Step 모델을 사용하여 음악을 생성하는 메인 함수입니다.\n\n#### understand_music\n\n```python\ndef understand_music(\n    llm_handler,\n    audio_codes: str,\n    temperature: float = 0.85,\n    top_k: Optional[int] = None,\n    top_p: Optional[float] = None,\n    repetition_penalty: float = 1.0,\n    use_constrained_decoding: bool = True,\n    constrained_decoding_debug: bool = False,\n) -> UnderstandResult\n```\n\n오디오 시맨틱 코드를 분석하고 메타데이터(캡션, 가사, BPM, 키 등)를 추출합니다.\n\n#### create_sample\n\n```python\ndef create_sample(\n    llm_handler,\n    query: str,\n    instrumental: bool = False,\n    vocal_language: Optional[str] = None,\n    temperature: float = 0.85,\n    top_k: Optional[int] = None,\n    top_p: Optional[float] = None,\n    repetition_penalty: float = 1.0,\n    use_constrained_decoding: bool = True,\n    constrained_decoding_debug: bool = False,\n) -> CreateSampleResult\n```\n\n자연어 설명으로부터 완전한 음악 샘플(캡션, 가사, 메타데이터)을 생성합니다.\n\n#### format_sample\n\n```python\ndef format_sample(\n    llm_handler,\n    caption: str,\n    lyrics: str,\n    user_metadata: Optional[Dict[str, Any]] = None,\n    temperature: float = 0.85,\n    top_k: Optional[int] = None,\n    top_p: Optional[float] = None,\n    repetition_penalty: float = 1.0,\n    use_constrained_decoding: bool = True,\n    constrained_decoding_debug: bool = False,\n) -> FormatSampleResult\n```\n\n사용자가 제공한 캡션과 가사를 개선/포맷팅하고 구조화된 메타데이터를 생성합니다.\n\n---\n\n## GenerationParams 파라미터\n\n### 텍스트 입력\n\n| 파라미터 | 타입 | 기본값 | 설명 |\n|-----------|------|---------|-------------|\n| `caption` | `str` | `\"\"` | 원하는 음악에 대한 텍스트 설명. 간단한 프롬프트나 장르, 분위기, 악기 등이 포함된 상세 설명이 가능합니다. 최대 512자. |\n| `lyrics` | `str` | `\"\"` | 보컬 음악을 위한 가사. 연주곡의 경우 `\"[Instrumental]\"`을 사용하세요. 다국어를 지원합니다. 최대 4096자. |\n| `instrumental` | `bool` | `False` | True일 경우 가사에 상관없이 연주곡을 생성합니다. |\n\n### 음악 메타데이터\n\n| 파라미터 | 타입 | 기본값 | 설명 |\n|-----------|------|---------|-------------|\n| `bpm` | `Optional[int]` | `None` | 분당 비트수(30-300). `None`으로 설정하면 LM을 통한 자동 감지를 활성화합니다. |\n| `keyscale` | `str` | `\"\"` | 음악 키 (예: \"C Major\", \"Am\", \"F# minor\"). 빈 문자열은 자동 감지를 활성화합니다. |\n| `timesignature` | `str` | `\"\"` | 박자 기호 ('2/4'는 2, '3/4'는 3, '4/4'는 4, '6/8'은 6). 빈 문자열은 자동 감지를 활성화합니다. |\n| `vocal_language` | `str` | `\"unknown\"` | 보컬 언어 코드 (ISO 639-1). 지원: `\"en\"`, `\"zh\"`, `\"ja\"`, `\"ko\"`, `\"es\"`, `\"fr\"` 등. 자동 감지는 `\"unknown\"` 사용. |\n| `duration` | `float` | `-1.0` | 대상 오디오 길이(초, 10-600). 0 이하이거나 None인 경우 가사 길이에 따라 모델이 자동으로 선택합니다. |\n\n### 생성 파라미터\n\n| 파라미터 | 타입 | 기본값 | 설명 |\n|-----------|------|---------|-------------|\n| `inference_steps` | `int` | `8` | 노이즈 제거 단계 수. Turbo 모델: 1-20 (8 권장). Base 모델: 1-200 (32-64 권장). 높을수록 품질은 좋아지지만 속도는 느려집니다. |\n| `guidance_scale` | `float` | `7.0` | Classifier-free guidance 스케일 (1.0-15.0). 높을수록 텍스트 프롬프트에 더 가깝게 생성됩니다. 비-Turbo 모델에서만 지원됩니다. |\n| `seed` | `int` | `-1` | 재현성을 위한 랜덤 시드. 랜덤은 `-1`, 고정된 결과는 양의 정수를 사용하세요. |\n\n### 고급 DiT 파라미터\n\n| 파라미터 | 타입 | 기본값 | 설명 |\n|-----------|------|---------|-------------|\n| `use_adg` | `bool` | `False` | Adaptive Dual Guidance 사용 (Base 모델 전용). 속도는 느려지지만 품질이 향상됩니다. |\n| `cfg_interval_start` | `float` | `0.0` | CFG 적용 시작 비율 (0.0-1.0). |\n| `cfg_interval_end` | `float` | `1.0` | CFG 적용 종료 비율 (0.0-1.0). |\n| `shift` | `float` | `1.0` | 타임스텝 시프트 계수 (범위 1.0-5.0). Turbo 모델의 경우 3.0을 권장합니다. |\n| `infer_method` | `str` | `\"ode\"` | 확산 추론 방법. `\"ode\"`(Euler)는 빠르고 결정론적입니다. `\"sde\"`는 결과에 분산이 발생할 수 있습니다. |\n\n### 작업별 파라미터\n\n| 파라미터 | 타입 | 기본값 | 설명 |\n|-----------|------|---------|-------------|\n| `task_type` | `str` | `\"text2music\"` | 생성 작업 유형. [작업 유형](#작업-유형-task-types) 섹션을 참조하세요. |\n| `reference_audio` | `Optional[str]` | `None` | 스타일 전송 또는 연속 생성 작업을 위한 참조 오디오 파일 경로. |\n| `src_audio` | `Optional[str]` | `None` | 오디오-투-오디오 작업(cover, repaint 등)을 위한 소스 오디오 파일 경로. |\n| `repainting_start` | `float` | `0.0` | 리페인팅 시작 시간 (초). |\n| `repainting_end` | `float` | `-1` | 리페인팅 종료 시간 (초). -1은 오디오 끝을 의미합니다. |\n| `audio_cover_strength` | `float` | `1.0` | 오디오 커버/코드 영향력 강도 (0.0-1.0). 스타일 전송의 경우 낮게(0.2) 설정하세요. |\n\n### 5Hz 언어 모델 파라미터\n\n| 파라미터 | 타입 | 기본값 | 설명 |\n|-----------|------|---------|-------------|\n| `thinking` | `bool` | `True` | 시맨틱/음악 메타데이터 및 코드를 위한 5Hz LM \"추론(Chain-of-Thought)\" 활성화. |\n| `lm_temperature` | `float` | `0.85` | LM 샘플링 온도. 높을수록 창의적/다양함, 낮을수록 보수적임. |\n| `lm_cfg_scale` | `float` | `2.0` | LM classifier-free guidance 스케일. |\n| `use_cot_metas` | `bool` | `True` | LM CoT 추론을 사용하여 메타데이터(BPM, 키 등) 생성. |\n| `use_cot_caption` | `bool` | `True` | LM CoT 추론을 사용하여 사용자 캡션 개선. |\n| `use_constrained_decoding` | `bool` | `True` | 구조화된 LM 출력을 위한 제약 디코딩 활성화. |\n\n---\n\n## 작업 유형 (Task Types)\n\n### 1. Text2Music (기본)\n텍스트 설명과 선택적 메타데이터로부터 음악을 생성합니다.\n\n### 2. Cover\n원본의 구조는 유지하면서 스타일이나 음색을 변형합니다. `src_audio`와 `caption`이 필요합니다.\n\n### 3. Repaint\n오디오의 특정 시간 구간만 다시 생성합니다. `repainting_start`와 `repainting_end`를 사용합니다.\n\n### 4. Lego (Base 모델 전용)\n기존 오디오 컨텍스트 내에서 특정 악기 트랙(보컬, 드럼 등)을 생성합니다.\n\n### 5. Extract (Base 모델 전용)\n믹스된 오디오에서 특정 악기 트랙을 분리/추출합니다.\n\n### 6. Complete (Base 모델 전용)\n부분적인 트랙에 지정된 악기를 추가하여 완성합니다.\n\n---\n\n## 예제: 가사가 포함된 노래 생성\n\n```python\nparams = GenerationParams(\n    task_type=\"text2music\",\n    caption=\"pop ballad with emotional vocals\",\n    lyrics=\"\"\"Verse 1:\nWalking down the street today\nThinking of the words you used to say\nEverything feels different now\nBut I'll find my way somehow\n\nChorus:\nI'm moving on, I'm staying strong\nThis is where I belong\n\"\"\",\n    vocal_language=\"en\",\n    bpm=72,\n    duration=45,\n)\n\nconfig = GenerationConfig(batch_size=1)\nresult = generate_music(dit_handler, llm_handler, params, config, save_dir=\"/output\")\n```\n\n---\n\n## 모범 사례\n\n1. **상세한 프롬프트**: \"슬픈 노래\"보다는 \"피아노와 보컬이 어우러진 잔잔하고 애절한 발라드\"가 더 나은 결과를 얻습니다.\n2. **Turbo 모델 활용**: 빠른 반복 작업에는 `turbo` 모델을 사용하는 것이 효율적입니다.\n3. **Thinking 모드**: 더 논리적인 음악 구조가 필요할 때 `thinking=True`를 사용하되, 메모리가 부족하면 끌 수 있습니다.\n4. **결과 반복**: 배치 크기를 2-4로 설정하여 여러 버전을 한 번에 듣고 최적의 결과를 고르는 것이 좋습니다.\n5. **메모리 관리**: ACE-Step 1.5는 자동 VRAM 관리를 포함합니다 — VRAM 가드(자동 배치 축소), 적응형 VAE 디코딩(CPU 대체), 자동 청크 크기 조정. OOM이 발생하면 시스템이 자동으로 처리합니다. 각 VRAM 티어의 권장 설정은 [GPU_COMPATIBILITY.md](../ko/GPU_COMPATIBILITY.md)를 참조하세요."
  },
  {
    "path": "docs/ko/LoRA_Training_Tutorial.md",
    "content": "# ACE-Step 1.5 LoRA 학습 튜토리얼\n\n## 하드웨어 요구사항\n\n| VRAM | 설명 |\n|------|------|\n| 16 GB (최소) | 일반적으로 사용 가능하나, 긴 곡의 경우 메모리 부족이 발생할 수 있습니다 |\n| 20 GB 이상 (권장) | 전체 길이의 곡을 처리 가능. 학습 중 VRAM 사용량은 보통 17 GB 수준입니다 |\n\n> **참고:** 학습 시작 전 전처리 단계에서 VRAM을 확보하기 위해 Gradio를 여러 번 재시작해야 할 수 있습니다. 구체적인 시점은 이후 단계에서 안내합니다.\n\n## 면책 조항\n\n본 튜토리얼은 **나유탄성인 (NayutalieN)** 의 앨범 *ナユタン星からの物体Y* (총 13곡)을 데모로 사용하며, 500 에포크(배치 사이즈 1)로 학습했습니다. **본 튜토리얼은 LoRA 파인튜닝 기술을 이해하기 위한 교육 목적으로만 사용됩니다. 자신의 원작으로 LoRA를 학습해 주세요.**\n\n개발자로서 나유탄성인의 작품을 매우 좋아하여 앨범 하나를 예시로 선택했습니다. 권리 보유자분께서 본 튜토리얼이 합법적인 권리를 침해한다고 판단하시면 즉시 연락 주세요. 유효한 통지를 받은 후 관련 콘텐츠를 삭제하겠습니다.\n\n기술은 합리적이고 합법적으로 사용되어야 합니다. 아티스트의 창작물을 존중하고, 원작 아티스트의 명예, 권리 또는 이익을 **손상시키거나 해치는** 행위를 하지 마세요.\n\n---\n\n## 데이터 준비\n\n> **팁:** 프로그래밍에 익숙하지 않은 경우, 이 문서를 Claude Code / Codex CLI / Cursor / Copilot 등의 AI 코딩 도구에 전달하여 작업을 대신 수행하게 할 수 있습니다.\n\n### 개요\n\n각 곡의 학습 데이터는 다음 항목으로 구성됩니다:\n\n1. **오디오 파일** — `.mp3`, `.wav`, `.flac`, `.ogg`, `.opus` 형식 지원\n2. **가사** — 오디오와 동일한 이름의 `.lyrics.txt` 파일 (하위 호환을 위해 `.txt`도 지원)\n3. **어노테이션 데이터** — `caption`, `bpm`, `keyscale`, `timesignature`, `language` 등의 메타데이터\n\n### 어노테이션 데이터 형식\n\n완전한 어노테이션 데이터를 보유하고 있다면, JSON 파일을 생성하여 오디오 및 가사와 같은 디렉토리에 배치할 수 있습니다. 파일 구조는 다음과 같습니다:\n\n```\ndataset/\n├── song1.mp3               # 오디오\n├── song1.lyrics.txt        # 가사\n├── song1.json              # 어노테이션 (선택)\n├── song1.caption.txt       # 캡션 (선택, JSON에 포함할 수도 있음)\n├── song2.mp3\n├── song2.lyrics.txt\n├── song2.json\n└── ...\n```\n\nJSON 파일 구조 (모든 필드는 선택 사항):\n\n```json\n{\n    \"caption\": \"A high-energy J-pop track with synthesizer leads and fast tempo\",\n    \"bpm\": 190,\n    \"keyscale\": \"D major\",\n    \"timesignature\": \"4\",\n    \"language\": \"ja\"\n}\n```\n\n어노테이션 데이터가 없는 경우, 이후 섹션에서 소개하는 방법으로 취득할 수 있습니다.\n\n---\n\n### 가사\n\n가사를 오디오 파일과 동일한 이름의 `.lyrics.txt` 파일로 저장하고 같은 디렉토리에 배치하세요. 가사의 정확성을 확인해 주세요.\n\n스캔 시 가사 파일 검색 우선순위:\n\n1. `{파일명}.lyrics.txt` (권장)\n2. `{파일명}.txt` (하위 호환)\n\n#### 가사 전사\n\n기존 가사 텍스트가 없는 경우, 다음 도구를 사용하여 전사할 수 있습니다:\n\n| 도구 | 구조화 태그 | 정확도 | 사용 난이도 | 배포 방식 |\n|------|-----------|--------|-----------|----------|\n| [acestep-transcriber](https://huggingface.co/ACE-Step/acestep-transcriber) | 없음 | 오류 가능성 있음 | 높음 (모델 배포 필요) | 자체 호스팅 |\n| [Gemini](https://aistudio.google.com/) | 있음 | 오류 가능성 있음 | 낮음 | 유료 API |\n| [Whisper](https://github.com/openai/whisper) | 없음 | 오류 가능성 있음 | 보통 | 자체 호스팅 / 유료 API |\n| [ElevenLabs](https://elevenlabs.io/app/developers) | 없음 | 오류 가능성 있음 | 보통 | 유료 API (무료 크레딧 제공) |\n\n본 프로젝트는 `scripts/lora_data_prepare/`에 해당 전사 스크립트를 제공합니다:\n\n- `whisper_transcription.py` — OpenAI Whisper API를 통한 전사\n- `elevenlabs_transcription.py` — ElevenLabs Scribe API를 통한 전사\n\n두 스크립트 모두 `process_folder()` 메서드를 통한 폴더 일괄 처리를 지원합니다.\n\n#### 검토 및 정제 (필수)\n\n전사된 가사에는 오류가 포함될 수 있으며, **반드시 수동으로 검토하고 수정해야 합니다**.\n\nLRC 형식의 가사를 사용하는 경우, 타임스탬프를 제거해야 합니다. 다음은 간단한 정제 예시입니다:\n\n```python\nimport re\n\ndef clean_lrc_content(lines):\n    \"\"\"LRC 파일 내용을 정제하고 타임스탬프를 제거\"\"\"\n    result = []\n    for line in lines:\n        line = line.strip()\n        if not line:\n            continue\n        # 타임스탬프 제거 [mm:ss.x] [mm:ss.xx] [mm:ss.xxx]\n        cleaned = re.sub(r\"\\[\\d{2}:\\d{2}\\.\\d{1,3}\\]\", \"\", line)\n        result.append(cleaned)\n\n    # 끝부분 빈 줄 제거\n    while result and not result[-1]:\n        result.pop()\n\n    return result\n```\n\n#### 구조화 태그 (선택)\n\n가사에 구조화 태그(`[Verse]`, `[Chorus]` 등)가 포함되어 있으면, 모델이 곡의 구조를 더 효과적으로 학습할 수 있습니다. 구조화 태그 없이도 정상적으로 학습이 가능합니다.\n\n> **팁:** [Gemini](https://aistudio.google.com/)를 사용하여 기존 가사에 구조화 태그를 추가할 수 있습니다.\n\n예시:\n\n```\n[Intro]\nLa la la...\n\n[Verse 1]\nWalking down the empty street\nEchoes dancing at my feet\n\n[Chorus]\nWe are the stars tonight\nShining through the endless sky\n\n[Bridge]\nClose your eyes and feel the sound\n```\n\n---\n\n### 자동 어노테이션\n\n#### 1. BPM 및 Key 취득\n\n[Key-BPM-Finder](https://vocalremover.org/key-bpm-finder)를 사용하여 BPM과 키 어노테이션을 온라인으로 취득합니다:\n\n1. 웹 페이지를 열고 **Browse my files**를 클릭하여 처리할 오디오 파일을 선택합니다 (한 번에 너무 많이 처리하면 멈출 수 있으므로, 분할 처리 후 CSV를 병합하는 것을 권장합니다). 처리는 로컬에서 수행되며 서버에 업로드되지 않습니다.\n   ![key-bpm-finder-0.jpg](../pics/key-bpm-finder-0.jpg)\n\n2. 처리 완료 후, **Export CSV**를 클릭하여 CSV 파일을 다운로드합니다.\n   ![key-bpm-finder-1.jpg](../pics/key-bpm-finder-1.jpg)\n\n3. CSV 파일 내용 예시:\n\n   ```csv\n   File,Artist,Title,BPM,Key,Camelot\n   song1.wav,,,190,D major,10B\n   song2.wav,,,128,A minor,8A\n   ```\n\n4. CSV 파일을 데이터셋 폴더에 배치합니다. 캡션 데이터를 추가하려면 `Camelot` 열 뒤에 새 열을 추가하세요.\n\n#### 2. Caption 취득\n\n다음 방법으로 곡의 캡션을 취득할 수 있습니다:\n\n- **acestep-5Hz-lm 사용** (0.6B / 1.7B / 4B) — Gradio UI의 Auto Label 기능에서 호출 (이후 단계 참조)\n- **Gemini API 사용** — 스크립트 `scripts/lora_data_prepare/gemini_caption.py`를 참조. `process_folder()`로 일괄 처리를 지원하며, 각 오디오 파일에 대해 다음을 생성합니다:\n  - `{파일명}.lyrics.txt` — 가사\n  - `{파일명}.caption.txt` — 캡션 설명\n\n---\n\n## 데이터 전처리\n\n데이터가 준비되면 Gradio UI를 사용하여 데이터 검토 및 전처리를 수행합니다.\n\n> **중요:** 시작 스크립트를 사용하는 경우, 서비스 사전 초기화를 비활성화하도록 시작 매개변수를 수정해야 합니다:\n>\n> - **Windows** (`start_gradio_ui.bat`): `if not defined INIT_SERVICE set INIT_SERVICE=--init_service true`를 `if not defined INIT_SERVICE set INIT_SERVICE=--init_service false`로 변경\n> - **Linux/macOS** (`start_gradio_ui.sh`): `: \"${INIT_SERVICE:=--init_service true}\"`를 `: \"${INIT_SERVICE:=--init_service false}\"`로 변경\n\nGradio UI를 시작합니다 (시작 스크립트 또는 `acestep/acestep_v15_pipeline.py` 직접 실행).\n\n### 단계 1: 모델 로드\n\n- **LM으로 캡션을 생성해야 하는 경우:** 초기화 시 사용할 LM 모델(acestep-5Hz-lm-0.6B / 1.7B / 4B)을 선택합니다.\n  ![](../pics/00_select_model_to_load.jpg)\n\n- **LM이 필요하지 않은 경우:** LM 모델을 선택하지 마세요.\n  ![](../pics/00_select_model_to_load_1.jpg)\n\n### 단계 2: 데이터 로드\n\n**LoRA Training** 탭으로 전환하고, 데이터셋 디렉토리 경로를 입력한 후 **Scan**을 클릭합니다.\n\n스캐너는 다음 파일을 자동으로 인식합니다:\n\n| 파일 | 설명 |\n|------|------|\n| `*.mp3` / `*.wav` / `*.flac` / ... | 오디오 파일 |\n| `{파일명}.lyrics.txt` (또는 `{파일명}.txt`) | 가사 |\n| `{파일명}.caption.txt` | 캡션 설명 |\n| `{파일명}.json` | 어노테이션 메타데이터 (caption / bpm / keyscale / timesignature / language) |\n| `*.csv` | BPM / Key 일괄 어노테이션 (Key-BPM-Finder에서 내보내기) |\n\n![](../pics/01_load_dataset_path.jpg)\n\n### 단계 3: 데이터셋 미리보기 및 조정\n\n- **Duration** — 오디오 파일에서 자동으로 읽기\n- **Lyrics** — 동일한 이름의 `.lyrics.txt` 파일이 필요 (`.txt`도 지원)\n- **Labeled** — 캡션이 있으면 ✅, 없으면 ❌로 표시\n- **BPM / Key / Caption** — JSON 또는 CSV 파일에서 로드\n- 데이터셋이 모두 인스트루멘탈이 아닌 경우, **All Instrumental** 체크를 해제하세요\n- **Format Lyrics** 및 **Transcribe Lyrics** 기능은 현재 비활성화 상태입니다 ([acestep-transcriber](https://huggingface.co/ACE-Step/acestep-transcriber) 미연동으로 인해 LM 직접 사용 시 환각 발생 가능)\n- **Custom Trigger Tag**를 입력하세요 (현재 효과가 제한적이며, `Replace Caption` 이외의 옵션이면 괜찮습니다)\n- **Genre Ratio**는 캡션 대신 장르를 사용하는 샘플 비율을 제어합니다. 현재 LM이 생성하는 장르 설명은 캡션에 비해 부족하므로 0으로 유지하세요\n\n![](../pics/02_preview_dataset.jpg)\n\n### 단계 4: Auto Label Data\n\n- 이미 캡션이 있는 경우, 이 단계를 건너뛸 수 있습니다\n- 데이터에 캡션이 없는 경우, LM 추론을 통해 생성할 수 있습니다\n- BPM / Key 값이 없는 경우, 먼저 [Key-BPM-Finder](https://vocalremover.org/key-bpm-finder)로 취득하세요. LM으로 직접 생성하면 환각이 발생합니다\n\n![](../pics/03_label_data.jpg)\n\n### 단계 5: 데이터 미리보기 및 편집\n\n필요한 경우, 데이터를 항목별로 검토하고 수정할 수 있습니다. **각 데이터 편집 후 반드시 저장을 클릭하세요.**\n\n![](../pics/04_edit_data.jpg)\n\n### 단계 6: 데이터셋 저장\n\n저장 경로를 입력하고 데이터셋을 JSON 파일로 저장합니다.\n\n![](../pics/05_save_dataset.jpg)\n\n### 단계 7: 전처리를 통한 Tensor 파일 생성\n\n> **주의:** 이전에 LM으로 캡션을 생성했고 VRAM이 부족한 경우, 먼저 Gradio를 재시작하여 VRAM을 확보하세요. 재시작 시 **LM 모델을 선택하지 마세요**. ��시작 후, 저장된 JSON 파일의 경로를 입력하고 로드합니다.\n\nTensor 파일 저장 경로를 입력하고 전처리를 시작한 후 완료를 기다립니다.\n\n![](../pics/06_preprocess_tensor.jpg)\n\n---\n\n## 학습\n\n> **주의:** Tensor 파일 생성 후에도 VRAM을 확보하기 위해 Gradio를 재시작하는 것을 권장합니다.\n\n1. **Train LoRA** 탭으로 전환하고, Tensor 파일 경로를 입력하여 데이터셋을 로드합니다.\n2. 학습 파라미터에 익숙하지 않은 경우, 기본값을 사용해도 됩니다.\n\n### 파라미터 참고\n\n| 파라미터 | 설명 | 권장값 |\n|---------|------|--------|\n| **Max Epochs** | 데이터셋 크기에 따라 조정 | 약 100곡 → 500 에포크; 10–20곡 → 800 에포크 (참고용) |\n| **Batch Size** | VRAM이 충분하면 증가 가능 | 1 (기본값), VRAM이 충분하면 2 또는 4 |\n| **Save Every N Epochs** | 체크포인트 저장 간격 | Max Epochs가 작으면 짧게, 크면 길게 설정 |\n\n> 위 수치는 참고용입니다. 실제 상황에 맞게 조정해 주세요.\n\n> **💡 LoKr 추천:** LoKR은 학습 효율을 크게 향상시켰습니다. 이전에 1시간이 걸리던 학습이 이제 단 5분이면 완료됩니다—10배 이상 빠릅니다. 이는 소비자용 GPU에서의 학습에 매우 중요합니다. **Train LoKr** 탭에서 LoKr 학습을 시도하거나, [Side-Step](https://github.com/koda-dernet/Side-Step) 툴킷을 사용하여 CLI 기반 LoKr 워크플로우를 이용할 수 있습니다. 자세한 내용은 [Training Guide](../sidestep/Training%20Guide.md)를 참조하세요.\n\n3. **Start Training**을 클릭하고 학습 완료를 기다립니다.\n\n![](../pics/07_train.jpg)\n\n---\n\n## LoRA 사용\n\n1. 학습 완료 후 **Gradio를 재시작**하고 모델을 다시 로드합니다 (LM 모델은 선택하지 마세요).\n2. 모델 초기화 완료 후, 학습된 LoRA 가중치를 로드합니다.\n   ![](../pics/08_load_lora.jpg)\n3. 음악 생성을 시작합니다.\n\n축하합니다! LoRA 학습의 전체 과정을 완료했습니다.\n\n---\n\n## 고급 학습: Side-Step\n\nLoRA 학습을 더 세밀하게 제어하고 싶다면 — 수정된 타임스텝 샘플링, LoKR 어댑터, CLI 기반 워크플로우, VRAM 최적화, 그래디언트 감도 분석 등 — 커뮤니티에서 개발한 **[Side-Step](https://github.com/koda-dernet/Side-Step)** 툴킷이 고급 대안을 제공합니다. 문서는 이 저장소의 `docs/sidestep/` 디렉토리에 포함되어 있습니다.\n\n| 주제 | 설명 |\n|------|------|\n| [Getting Started](../sidestep/Getting%20Started.md) | 설치, 사전 요구사항, 첫 실행 설정 |\n| [End-to-End Tutorial](../sidestep/End-to-End%20Tutorial.md) | 원본 오디오에서 생성까지 전체 과정 안내 |\n| [Dataset Preparation](../sidestep/Dataset%20Preparation.md) | JSON 스키마, 오디오 형식, 메타데이터 필드, 커스텀 태그 |\n| [Training Guide](../sidestep/Training%20Guide.md) | LoRA vs LoKR, 수정 모드 vs 바닐라 모드, 하이퍼파라미터 가이드 |\n| [Using Your Adapter](../sidestep/Using%20Your%20Adapter.md) | 출력 디렉토리 구조, Gradio에서 로드, LoKR 제한사항 |\n| [VRAM Optimization Guide](../sidestep/VRAM%20Optimization%20Guide.md) | VRAM 최적화 전략 및 GPU 티어별 설정 |\n| [Estimation Guide](../sidestep/Estimation%20Guide.md) | 타겟 학습을 위한 그래디언트 감도 분석 |\n| [Shift and Timestep Sampling](../sidestep/Shift%20and%20Timestep%20Sampling.md) | 학습 타임스텝 작동 원리와 Side-Step의 차이점 |\n| [Preset Management](../sidestep/Preset%20Management.md) | 내장 프리셋, 저장/로드/가져오기/내보내기 |\n| [The Settings Wizard](../sidestep/The%20Settings%20Wizard.md) | 위자드 설정 전체 참조 |\n| [Model Management](../sidestep/Model%20Management.md) | 체크포인트 구조 및 파인튜닝 모델 지원 |\n| [Windows Notes](../sidestep/Windows%20Notes.md) | Windows 전용 설정 및 해결 방법 |\n"
  },
  {
    "path": "docs/ko/Openrouter_API_DOC.md",
    "content": "# ACE-Step OpenRouter API 문서\n\n> AI 음악 생성을 위한 OpenAI Chat Completions 호환 API\n\n**Base URL:** `http://{host}:{port}` (기본값 `http://127.0.0.1:8002`)\n\n---\n\n## 목차\n\n- [인증](#인증)\n- [엔드포인트](#엔드포인트)\n  - [POST /v1/chat/completions - 음악 생성](#1-음악-생성)\n  - [GET /v1/models - 모델 목록](#2-모델-목록)\n  - [GET /health - 헬스 체크](#3-헬스-체크)\n- [입력 모드](#입력-모드)\n- [오디오 입력](#오디오-입력)\n- [스트리밍 응답](#스트리밍-응답)\n- [예제](#예제)\n- [에러 코드](#에러-코드)\n\n---\n\n## 인증\n\n서버에 API 키가 설정된 경우(환경 변수 `OPENROUTER_API_KEY` 또는 `--api-key` 플래그 사용), 모든 요청은 다음 헤더를 포함해야 합니다:\n\n```\nAuthorization: Bearer <your-api-key>\n```\n\nAPI 키가 설정되지 않은 경우 인증이 필요하지 않습니다.\n\n---\n\n## 엔드포인트\n\n### 1. 음악 생성\n\n**POST** `/v1/chat/completions`\n\n채팅 메시지로부터 음악을 생성하고 오디오 데이터와 LM이 생성한 메타데이터를 반환합니다.\n\n#### 요청 파라미터\n\n| 필드 | 타입 | 필수 | 기본값 | 설명 |\n|---|---|---|---|---|\n| `model` | string | 아니요 | 자동 | 모델 ID (`/v1/models`에서 확인) |\n| `messages` | array | **예** | - | 채팅 메시지 리스트. [입력 모드](#입력-모드) 참조 |\n| `stream` | boolean | 아니요 | `false` | 스트리밍 응답 활성화. [스트리밍 응답](#스트리밍-응답) 참조 |\n| `audio_config` | object | 아니요 | `null` | 오디오 생성 설정. 아래 참조 |\n| `temperature` | float | 아니요 | `0.85` | LM 샘플링 온도 |\n| `top_p` | float | 아니요 | `0.9` | LM nucleus sampling 파라미터 |\n| `seed` | int \\| string | 아니요 | `null` | 랜덤 시드. `batch_size > 1`일 때 쉼표로 구분하여 여러 개 지정 가능 (예: `\"42,123,456\"`) |\n| `lyrics` | string | 아니요 | `\"\"` | 직접 전달되는 가사 (메시지에서 파싱된 가사보다 우선). 설정 시 messages 텍스트는 prompt로 사용 |\n| `sample_mode` | boolean | 아니요 | `false` | LLM sample 모드 활성화. messages 텍스트가 sample_query로 LLM에 전달되어 prompt/lyrics 자동 생성 |\n| `thinking` | boolean | 아니요 | `false` | 더 깊은 추론을 위한 LLM thinking 모드 활성화 |\n| `use_format` | boolean | 아니요 | `false` | 사용자가 prompt/lyrics를 제공할 때 LLM 포맷팅으로 개선 |\n| `use_cot_caption` | boolean | 아니요 | `true` | CoT를 통해 음악 설명을 재작성/개선 |\n| `use_cot_language` | boolean | 아니요 | `true` | CoT를 통해 보컬 언어를 자동 감지 |\n| `guidance_scale` | float | 아니요 | `7.0` | Classifier-free guidance scale |\n| `batch_size` | int | 아니요 | `1` | 생성할 오디오 수 |\n| `task_type` | string | 아니요 | `\"text2music\"` | 작업 유형. [오디오 입력](#오디오-입력) 참조 |\n| `repainting_start` | float | 아니요 | `0.0` | repaint 영역 시작 위치(초) |\n| `repainting_end` | float | 아니요 | `null` | repaint 영역 종료 위치(초) |\n| `audio_cover_strength` | float | 아니요 | `1.0` | 커버 강도 (0.0~1.0) |\n\n#### audio_config 객체\n\n| 필드 | 타입 | 기본값 | 설명 |\n|---|---|---|---|\n| `duration` | float | `null` | 오디오 길이(초). 생략 시 LM이 자동 결정 |\n| `bpm` | integer | `null` | 분당 비트수(BPM). 생략 시 LM이 자동 결정 |\n| `vocal_language` | string | `\"en\"` | 보컬 언어 코드 (예: `\"ko\"`, `\"en\"`, `\"ja\"`) |\n| `instrumental` | boolean | `null` | 보컬 없는 연주곡 여부. 생략 시 가사에 따라 자동 판단 |\n| `format` | string | `\"mp3\"` | 출력 오디오 포맷 |\n| `key_scale` | string | `null` | 조성 (예: `\"C major\"`) |\n| `time_signature` | string | `null` | 박자 (예: `\"4/4\"`) |\n\n> **messages 텍스트의 의미는 모드에 따라 다릅니다:**\n> - `lyrics` 설정 시 → messages 텍스트 = caption\n> - `sample_mode: true` 설정 시 → messages 텍스트 = sample_query (LLM에게 모든 것을 생성하도록 함)\n> - 둘 다 미설정 → 자동 감지: 태그가 있으면 태그 모드, 가사처럼 보이면 가사 모드, 그 외 caption 로 직접 생성에 사용\n\n#### messages 형식\n\n일반 텍스트와 멀티모달(텍스트 + 오디오) 두 가지 형식을 지원합니다:\n\n**일반 텍스트:**\n\n```json\n{\n  \"messages\": [\n    {\"role\": \"user\", \"content\": \"입력 내용\"}\n  ]\n}\n```\n\n**멀티모달 (오디오 입력 포함):**\n\n```json\n{\n  \"messages\": [\n    {\n      \"role\": \"user\",\n      \"content\": [\n        {\"type\": \"text\", \"text\": \"이 노래를 커버해줘\"},\n        {\n          \"type\": \"input_audio\",\n          \"input_audio\": {\n            \"data\": \"<base64 오디오 데이터>\",\n            \"format\": \"mp3\"\n          }\n        }\n      ]\n    }\n  ]\n}\n```\n\n---\n\n#### 비스트리밍 응답 (`stream: false`)\n\n```json\n{\n  \"id\": \"chatcmpl-a1b2c3d4e5f6g7h8\",\n  \"object\": \"chat.completion\",\n  \"created\": 1706688000,\n  \"model\": \"acemusic/acestep-v15-turbo\",\n  \"choices\": [\n    {\n      \"index\": 0,\n      \"message\": {\n        \"role\": \"assistant\",\n        \"content\": \"## Metadata\\n**Caption:** Upbeat pop song...\\n**BPM:** 120\\n**Duration:** 30s\\n**Key:** C major\\n\\n## Lyrics\\n[Verse 1]\\nHello world...\",\n        \"audio\": [\n          {\n            \"type\": \"audio_url\",\n            \"audio_url\": {\n              \"url\": \"data:audio/mpeg;base64,SUQzBAAAAAAAI1RTU0UAAAA...\"\n            }\n          }\n        ]\n      },\n      \"finish_reason\": \"stop\"\n    }\n  ],\n  \"usage\": {\n    \"prompt_tokens\": 10,\n    \"completion_tokens\": 100,\n    \"total_tokens\": 110\n  }\n}\n```\n\n**응답 필드 설명:**\n\n| 필드 | 설명 |\n|---|---|\n| `choices[0].message.content` | LM이 생성한 텍스트 정보. Metadata(Caption/BPM/Duration/Key/Time Signature/Language)와 Lyrics를 포함. LM이 관여하지 않은 경우 `\"Music generated successfully.\"` 반환 |\n| `choices[0].message.audio` | 오디오 데이터 배열. 각 항목에 `type` (`\"audio_url\"`)과 `audio_url.url` (Base64 Data URL, 형식: `data:audio/mpeg;base64,...`)을 포함 |\n| `choices[0].finish_reason` | `\"stop\"`은 정상 완료를 나타냄 |\n\n**오디오 디코딩 형식:**\n\n`audio_url.url` 값은 Data URL 형식: `data:audio/mpeg;base64,<base64_data>`\n\n쉼표 이후의 base64 데이터 부분을 추출하여 디코딩하면 MP3 파일을 얻을 수 있습니다:\n\n```python\nimport base64\n\nurl = response[\"choices\"][0][\"message\"][\"audio\"][0][\"audio_url\"][\"url\"]\n# \"data:audio/mpeg;base64,\" 접두사 제거\nb64_data = url.split(\",\", 1)[1]\naudio_bytes = base64.b64decode(b64_data)\n\nwith open(\"output.mp3\", \"wb\") as f:\n    f.write(audio_bytes)\n```\n\n```javascript\nconst url = response.choices[0].message.audio[0].audio_url.url;\nconst b64Data = url.split(\",\")[1];\nconst audioBytes = atob(b64Data);\n// Data URL을 <audio> 태그에 직접 사용 가능\nconst audio = new Audio(url);\naudio.play();\n```\n\n---\n\n### 2. 모델 목록\n\n**GET** `/v1/models`\n\n사용 가능한 모델 정보를 반환합니다.\n\n#### 응답\n\n```json\n{\n  \"data\": [\n    {\n      \"id\": \"acemusic/acestep-v15-turbo\",\n      \"name\": \"ACE-Step\",\n      \"created\": 1706688000,\n      \"description\": \"High-performance text-to-music generation model. Supports multiple styles, lyrics input, and various audio durations.\",\n      \"input_modalities\": [\"text\", \"audio\"],\n      \"output_modalities\": [\"audio\", \"text\"],\n      \"context_length\": 4096,\n      \"pricing\": {\"prompt\": \"0\", \"completion\": \"0\", \"request\": \"0\"},\n      \"supported_sampling_parameters\": [\"temperature\", \"top_p\"]\n    }\n  ]\n}\n```\n\n---\n\n### 3. 헬스 체크\n\n**GET** `/health`\n\n#### 응답\n\n```json\n{\n  \"status\": \"ok\",\n  \"service\": \"ACE-Step OpenRouter API\",\n  \"version\": \"1.0\"\n}\n```\n\n---\n\n## 입력 모드\n\n시스템은 마지막 `user` 메시지의 내용에 따라 입력 모드를 자동으로 선택합니다. `lyrics` 또는 `sample_mode` 필드로 명시적으로 지정할 수도 있습니다.\n\n### 모드 1: 태그 모드 (권장)\n\n`<prompt>`와 `<lyrics>` 태그를 사용하여 음악 설명과 가사를 명시적으로 지정합니다:\n\n```json\n{\n  \"messages\": [\n    {\n      \"role\": \"user\",\n      \"content\": \"<prompt>A gentle acoustic ballad in C major, female vocal</prompt>\\n<lyrics>[Verse 1]\\nSunlight through the window\\nA brand new day begins\\n\\n[Chorus]\\nWe are the dreamers\\nWe are the light</lyrics>\"\n    }\n  ],\n  \"audio_config\": {\n    \"duration\": 30,\n    \"vocal_language\": \"en\"\n  }\n}\n```\n\n- `<prompt>...</prompt>` — 음악 스타일/장면 설명 (caption)\n- `<lyrics>...</lyrics>` — 가사 내용\n- 하나의 태그만 사용할 수도 있음\n- `use_format: true`일 때 LLM이 prompt와 lyrics를 자동으로 개선\n\n### 모드 2: 자연어 모드 (샘플 모드)\n\n원하는 음악을 자연어로 설명합니다. 시스템이 LLM을 사용하여 prompt와 lyrics를 자동으로 생성합니다:\n\n```json\n{\n  \"messages\": [\n    {\"role\": \"user\", \"content\": \"여름과 여행에 관한 신나는 팝송을 만들어줘\"}\n  ],\n  \"sample_mode\": true,\n  \"audio_config\": {\n    \"vocal_language\": \"ko\"\n  }\n}\n```\n\n트리거 조건: `sample_mode: true`, 또는 메시지에 태그가 없고 가사처럼 보이지 않을 때 자동 트리거.\n\n### 모드 3: 가사 전용 모드\n\n구조 마커가 있는 가사를 직접 전달하면 시스템이 자동으로 인식합니다:\n\n```json\n{\n  \"messages\": [\n    {\n      \"role\": \"user\",\n      \"content\": \"[Verse 1]\\nWalking down the street\\nFeeling the beat\\n\\n[Chorus]\\nDance with me tonight\\nUnder the moonlight\"\n    }\n  ],\n  \"audio_config\": {\"duration\": 30}\n}\n```\n\n트리거 조건: 메시지에 `[Verse]`, `[Chorus]` 등의 마커가 포함되거나 여러 줄의 짧은 텍스트 구조를 가진 경우.\n\n### 모드 4: 가사 + Prompt 분리\n\n`lyrics` 필드로 가사를 직접 전달하고, messages 텍스트는 자동으로 prompt로 사용됩니다:\n\n```json\n{\n  \"messages\": [\n    {\"role\": \"user\", \"content\": \"Energetic EDM with heavy bass drops\"}\n  ],\n  \"lyrics\": \"[Verse 1]\\nFeel the rhythm in your soul\\nLet the music take control\\n\\n[Drop]\\n(instrumental break)\",\n  \"audio_config\": {\n    \"bpm\": 128,\n    \"duration\": 60\n  }\n}\n```\n\n### 연주곡 모드\n\n`audio_config.instrumental: true` 설정:\n\n```json\n{\n  \"messages\": [\n    {\"role\": \"user\", \"content\": \"<prompt>Epic orchestral cinematic score, dramatic and powerful</prompt>\"}\n  ],\n  \"audio_config\": {\n    \"instrumental\": true,\n    \"duration\": 30\n  }\n}\n```\n\n---\n\n## 오디오 입력\n\n멀티모달 messages를 통해 오디오 파일(base64 인코딩)을 전달하여 cover, repaint 등의 작업에 사용할 수 있습니다.\n\n### task_type 유형\n\n| task_type | 설명 | 오디오 입력 필요 |\n|---|---|---|\n| `text2music` | 텍스트에서 음악 생성 (기본값) | 선택 (reference로) |\n| `cover` | 커버/스타일 전환 | src_audio 필요 |\n| `repaint` | 부분 리페인팅 | src_audio 필요 |\n| `lego` | 오디오 접합 | src_audio 필요 |\n| `extract` | 오디오 추출 | src_audio 필요 |\n| `complete` | 오디오 이어쓰기 | src_audio 필요 |\n\n### 오디오 라우팅 규칙\n\n여러 `input_audio` 블록은 순서대로 다른 파라미터에 라우팅됩니다 (다중 이미지 업로드와 유사):\n\n| task_type | audio[0] | audio[1] |\n|---|---|---|\n| `text2music` | reference_audio (스타일 참조) | - |\n| `cover/repaint/lego/extract/complete` | src_audio (편집 대상 오디오) | reference_audio (선택적 스타일 참조) |\n\n### 오디오 입력 예제\n\n**Cover 작업 (커버):**\n\n```json\n{\n  \"messages\": [\n    {\n      \"role\": \"user\",\n      \"content\": [\n        {\"type\": \"text\", \"text\": \"<prompt>Jazz style cover with saxophone</prompt>\"},\n        {\n          \"type\": \"input_audio\",\n          \"input_audio\": {\"data\": \"<base64 원본 오디오>\", \"format\": \"mp3\"}\n        }\n      ]\n    }\n  ],\n  \"task_type\": \"cover\",\n  \"audio_cover_strength\": 0.8,\n  \"audio_config\": {\"duration\": 30}\n}\n```\n\n**Repaint 작업 (부분 리페인팅):**\n\n```json\n{\n  \"messages\": [\n    {\n      \"role\": \"user\",\n      \"content\": [\n        {\"type\": \"text\", \"text\": \"<prompt>Replace with guitar solo</prompt>\"},\n        {\n          \"type\": \"input_audio\",\n          \"input_audio\": {\"data\": \"<base64 원본 오디오>\", \"format\": \"mp3\"}\n        }\n      ]\n    }\n  ],\n  \"task_type\": \"repaint\",\n  \"repainting_start\": 10.0,\n  \"repainting_end\": 20.0,\n  \"audio_config\": {\"duration\": 30}\n}\n```\n\n---\n\n## 스트리밍 응답\n\n`\"stream\": true`로 설정하면 SSE(Server-Sent Events) 스트리밍이 활성화됩니다.\n\n### 이벤트 형식\n\n각 이벤트는 `data: `로 시작하고 JSON이 뒤따르며 이중 줄바꿈 `\\n\\n`으로 끝납니다:\n\n```\ndata: {\"id\":\"chatcmpl-xxx\",\"object\":\"chat.completion.chunk\",\"created\":1706688000,\"model\":\"acemusic/acestep-v15-turbo\",\"choices\":[{\"index\":0,\"delta\":{...},\"finish_reason\":null}]}\n\n```\n\n### 스트리밍 이벤트 순서\n\n| 단계 | delta 내용 | 설명 |\n|---|---|---|\n| 1. 초기화 | `{\"role\":\"assistant\",\"content\":\"\"}` | 연결 수립 |\n| 2. LM 콘텐츠 | `{\"content\":\"\\n\\n## Metadata\\n...\"}` | LM 사용 시 metadata와 lyrics 전송 |\n| 3. 하트비트 | `{\"content\":\".\"}` | 오디오 생성 중 2초마다 전송, 연결 유지 |\n| 4. 오디오 데이터 | `{\"audio\":[{\"type\":\"audio_url\",\"audio_url\":{\"url\":\"data:...\"}}]}` | 오디오 base64 데이터 |\n| 5. 완료 | `finish_reason: \"stop\"` | 생성 완료 |\n| 6. 종료 | `data: [DONE]` | 스트림 종료 마커 |\n\n### 스트리밍 응답 예시\n\n```\ndata: {\"id\":\"chatcmpl-abc123\",\"object\":\"chat.completion.chunk\",\"created\":1706688000,\"model\":\"acemusic/acestep-v15-turbo\",\"choices\":[{\"index\":0,\"delta\":{\"role\":\"assistant\",\"content\":\"\"},\"finish_reason\":null}]}\n\ndata: {\"id\":\"chatcmpl-abc123\",\"object\":\"chat.completion.chunk\",\"created\":1706688000,\"model\":\"acemusic/acestep-v15-turbo\",\"choices\":[{\"index\":0,\"delta\":{\"content\":\"\\n\\n## Metadata\\n**Caption:** Upbeat pop\\n**BPM:** 120\"},\"finish_reason\":null}]}\n\ndata: {\"id\":\"chatcmpl-abc123\",\"object\":\"chat.completion.chunk\",\"created\":1706688000,\"model\":\"acemusic/acestep-v15-turbo\",\"choices\":[{\"index\":0,\"delta\":{\"content\":\".\"},\"finish_reason\":null}]}\n\ndata: {\"id\":\"chatcmpl-abc123\",\"object\":\"chat.completion.chunk\",\"created\":1706688000,\"model\":\"acemusic/acestep-v15-turbo\",\"choices\":[{\"index\":0,\"delta\":{\"audio\":[{\"type\":\"audio_url\",\"audio_url\":{\"url\":\"data:audio/mpeg;base64,...\"}}]},\"finish_reason\":null}]}\n\ndata: {\"id\":\"chatcmpl-abc123\",\"object\":\"chat.completion.chunk\",\"created\":1706688000,\"model\":\"acemusic/acestep-v15-turbo\",\"choices\":[{\"index\":0,\"delta\":{},\"finish_reason\":\"stop\"}]}\n\ndata: [DONE]\n\n```\n\n### 클라이언트 측 스트리밍 처리\n\n```python\nimport json\nimport httpx\n\nwith httpx.stream(\"POST\", \"http://127.0.0.1:8002/v1/chat/completions\", json={\n    \"messages\": [{\"role\": \"user\", \"content\": \"경쾌한 기타 곡을 생성해줘\"}],\n    \"sample_mode\": True,\n    \"stream\": True,\n    \"audio_config\": {\"instrumental\": True}\n}) as response:\n    content_parts = []\n    audio_url = None\n\n    for line in response.iter_lines():\n        if not line or not line.startswith(\"data: \"):\n            continue\n        if line == \"data: [DONE]\":\n            break\n\n        chunk = json.loads(line[6:])\n        delta = chunk[\"choices\"][0][\"delta\"]\n\n        if \"content\" in delta and delta[\"content\"]:\n            content_parts.append(delta[\"content\"])\n\n        if \"audio\" in delta and delta[\"audio\"]:\n            audio_url = delta[\"audio\"][0][\"audio_url\"][\"url\"]\n\n        if chunk[\"choices\"][0].get(\"finish_reason\") == \"stop\":\n            print(\"생성 완료!\")\n\n    print(\"Content:\", \"\".join(content_parts))\n    if audio_url:\n        import base64\n        b64_data = audio_url.split(\",\", 1)[1]\n        with open(\"output.mp3\", \"wb\") as f:\n            f.write(base64.b64decode(b64_data))\n```\n\n```javascript\nconst response = await fetch(\"http://127.0.0.1:8002/v1/chat/completions\", {\n  method: \"POST\",\n  headers: { \"Content-Type\": \"application/json\" },\n  body: JSON.stringify({\n    messages: [{ role: \"user\", content: \"경쾌한 기타 곡을 생성해줘\" }],\n    sample_mode: true,\n    stream: true,\n    audio_config: { instrumental: true }\n  })\n});\n\nconst reader = response.body.getReader();\nconst decoder = new TextDecoder();\nlet audioUrl = null;\nlet content = \"\";\n\nwhile (true) {\n  const { done, value } = await reader.read();\n  if (done) break;\n\n  const text = decoder.decode(value);\n  for (const line of text.split(\"\\n\")) {\n    if (!line.startsWith(\"data: \") || line === \"data: [DONE]\") continue;\n\n    const chunk = JSON.parse(line.slice(6));\n    const delta = chunk.choices[0].delta;\n\n    if (delta.content) content += delta.content;\n    if (delta.audio) audioUrl = delta.audio[0].audio_url.url;\n  }\n}\n\n// audioUrl은 <audio src=\"...\">에 직접 사용 가능\n```\n\n---\n\n## 예제\n\n### 예제 1: 자연어 생성 (가장 간단한 사용법)\n\n```bash\ncurl -X POST http://127.0.0.1:8002/v1/chat/completions \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\n    \"messages\": [\n      {\"role\": \"user\", \"content\": \"고향과 추억에 관한 부드러운 포크 송\"}\n    ],\n    \"sample_mode\": true,\n    \"audio_config\": {\"vocal_language\": \"ko\"}\n  }'\n```\n\n### 예제 2: 태그 모드 + 파라미터 지정\n\n```bash\ncurl -X POST http://127.0.0.1:8002/v1/chat/completions \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\n    \"messages\": [\n      {\n        \"role\": \"user\",\n        \"content\": \"<prompt>Energetic EDM track with heavy bass drops and synth leads</prompt><lyrics>[Verse 1]\\nFeel the rhythm in your soul\\nLet the music take control\\n\\n[Drop]\\n(instrumental break)</lyrics>\"\n      }\n    ],\n    \"audio_config\": {\n      \"bpm\": 128,\n      \"duration\": 60,\n      \"vocal_language\": \"en\"\n    }\n  }'\n```\n\n### 예제 3: 연주곡 + LM 개선 비활성화\n\n```bash\ncurl -X POST http://127.0.0.1:8002/v1/chat/completions \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\n    \"messages\": [\n      {\n        \"role\": \"user\",\n        \"content\": \"<prompt>Peaceful piano solo, slow tempo, jazz harmony</prompt>\"\n      }\n    ],\n    \"use_cot_caption\": false,\n    \"audio_config\": {\n      \"instrumental\": true,\n      \"duration\": 45\n    }\n  }'\n```\n\n### 예제 4: 스트리밍 요청\n\n```bash\ncurl -X POST http://127.0.0.1:8002/v1/chat/completions \\\n  -H \"Content-Type: application/json\" \\\n  -N \\\n  -d '{\n    \"messages\": [\n      {\"role\": \"user\", \"content\": \"생일 축하 노래를 만들어줘\"}\n    ],\n    \"sample_mode\": true,\n    \"stream\": true\n  }'\n```\n\n### 예제 5: 멀티 시드 배치 생성\n\n```bash\ncurl -X POST http://127.0.0.1:8002/v1/chat/completions \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\n    \"messages\": [\n      {\"role\": \"user\", \"content\": \"<prompt>Lo-fi hip hop beat</prompt>\"}\n    ],\n    \"batch_size\": 3,\n    \"seed\": \"42,123,456\",\n    \"audio_config\": {\n      \"instrumental\": true,\n      \"duration\": 30\n    }\n  }'\n```\n\n---\n\n## 에러 코드\n\n| HTTP 상태 코드 | 설명 |\n|---|---|\n| 400 | 잘못된 요청 형식 또는 유효한 입력 누락 |\n| 401 | API 키 누락 또는 유효하지 않음 |\n| 429 | 서비스 과부하, 큐 가득 참 |\n| 500 | 음악 생성 중 내부 오류 발생 |\n| 503 | 모델이 아직 초기화되지 않음 |\n| 504 | 생성 타임아웃 |\n\n에러 응답 형식:\n\n```json\n{\n  \"detail\": \"에러 설명 메시지\"\n}\n```\n\n---\n\n## 서버 설정 (환경 변수)\n\n다음 환경 변수로 서버를 설정할 수 있습니다 (운영 참고용):\n\n| 변수명 | 기본값 | 설명 |\n|---|---|---|\n| `OPENROUTER_API_KEY` | 없음 | API 인증 키 |\n| `OPENROUTER_HOST` | `127.0.0.1` | 리슨 주소 |\n| `OPENROUTER_PORT` | `8002` | 리슨 포트 |\n| `ACESTEP_CONFIG_PATH` | `acestep-v15-turbo` | DiT 모델 설정 경로 |\n| `ACESTEP_DEVICE` | `auto` | 추론 디바이스 |\n| `ACESTEP_LM_MODEL_PATH` | `acestep-5Hz-lm-0.6B` | LLM 모델 경로 |\n| `ACESTEP_LM_BACKEND` | `vllm` | LLM 추론 백엔드 |\n| `ACESTEP_QUEUE_MAXSIZE` | `200` | 작업 큐 최대 용량 |\n| `ACESTEP_GENERATION_TIMEOUT` | `600` | 비스트리밍 요청 타임아웃(초) |\n"
  },
  {
    "path": "docs/ko/Tutorial.md",
    "content": "# ACE-Step 1.5 전체 가이드 (필독)\n\n**언어 / Language / 语言 / 言語:** [English](Tutorial.md) | [한국어](Tutorial.md) | [中文](../zh/Tutorial.md) | [日本語](../ja/Tutorial.md)\n\n---\n\n안녕하세요, ACE-Step 개발자 공준민(Gong Junmin)입니다. 이 튜토리얼을 통해 ACE-Step 1.5의 설계 철학과 사용법을 안내해 드리겠습니다.\n\n## 멘탈 모델 (Mental Models)\n\n시작하기에 앞서, 적절한 기대를 갖기 위해 올바른 멘탈 모델을 세울 필요가 있습니다.\n\n### 인간 중심 디자인 (Human-Centered Design)\n\n이 모델은 **'원클릭 생성'**을 위해 설계된 것이 아니라, **'인간 중심의 생성'**을 위해 설계되었습니다.\n\n이 차이를 이해하는 것이 매우 중요합니다.\n\n### 원클릭 생성(One-Click Generation)이란 무엇인가요?\n\n프롬프트를 입력하고 생성 버튼을 누른 뒤, 몇 가지 버전을 들어보고 마음에 드는 것을 골라 사용하는 방식입니다. 다른 사람이 같은 프롬프트를 입력하면 아마 비슷한 결과를 얻게 될 것입니다.\n\n이 모드에서 여러분과 AI는 **'고객-공급업체'** 관계입니다. 여러분은 명확한 목적과 막연한 기대치를 가지고 오며, AI가 그 기대치에 근접한 제품을 제공하기를 바랍니다. 본질적으로 구글 검색이나 스포티파이에서 노래를 찾는 것과 크게 다르지 않으며, 약간의 커스터마이징이 추가된 정도입니다.\n\n여기서 AI는 서비스일 뿐, 창의적인 영감을 주는 존재는 아닙니다.\n\nSuno, Udio, MiniMax, Mureka 등의 플랫폼은 모두 이러한 철학으로 설계되었습니다. 그들은 서비스를 제공하기 위해 모델의 규모를 키웁니다. 여러분이 생성한 음악은 그들의 약관에 묶여 있습니다. 로컬에서 실행할 수 없고, 개인화된 탐구를 위해 미세 조정(fine-tune)할 수도 없습니다. 그들이 몰래 모델이나 약관을 변경하더라도 여러분은 받아들일 수밖에 없습니다.\n\n### 인간 중심의 생성(Human-Centered Generation)이란 무엇인가요?\n\nAI 레이어를 약화시키고 인간 레이어를 강화하여, 인간의 의지, 창의성, 영감이 AI에 생명력을 불어넣게 하는 것이 인간 중심의 생성입니다.\n\n원클릭 생성의 강한 목적성과 달리, 인간 중심의 생성은 더 **'유희적인(playful)'** 성격을 띱니다. 여러분과 모델이 **'협력자'**가 되어 즐기는 인터랙티브 게임에 가깝습니다.\n\n워크플로우는 이렇습니다. 영감의 씨앗을 던져 몇 곡을 얻고, 그중에서 흥미로운 방향을 선택하여 계속 반복(iteration)합니다.\n- 프롬프트를 조정하여 다시 생성\n- **Cover** 기능을 사용하여 구조는 유지하면서 세부 사항 조정\n- **Repaint** 기능을 사용하여 국소적인 수정\n- **Add Layer**를 사용하여 악기 레이어 추가 또는 제거\n\n이 지점에서 AI는 여러분의 하인이 아니라 **'영감 제공자(inspirer)'**가 됩니다.\n\n### 이 디자인이 충족해야 할 조건은 무엇인가요?\n\n인간 중심의 워크플로우가 제대로 작동하려면 모델이 몇 가지 핵심 조건을 충족해야 합니다.\n\n**첫째, 오픈 소스여야 하며 로컬에서 실행 및 학습이 가능해야 합니다.**\n\n이것은 단순히 기술적인 순수주의의 문제가 아니라 소유권의 문제입니다. 폐쇄형 플랫폼을 사용할 때 여러분은 모델을 소유하지 않으며, 생성된 작업물은 그들의 약관에 묶입니다. 버전 업데이트, 약관 변경, 서비스 중단 등 그 무엇도 여러분의 통제 하에 있지 않습니다.\n\n하지만 모델이 오픈 소스이고 로컬에서 실행 가능하다면 모든 것이 바뀝니다. **여러분은 이 모델을 영원히 소유하며, 이를 통해 만든 모든 창작물 또한 영원히 여러분의 소유입니다.** 제3자의 약관 문제나 플랫폼 리스크 없이 여러분만의 창의적인 시스템을 미세 조정하고, 수정하고, 구축할 수 있습니다. 여러분의 작업물은 영원히 여러분의 것입니다. 마치 악기를 사는 것과 같습니다. 언제 어디서나 사용할 수 있고, 원할 때 언제든 조정할 수 있습니다.\n\n**둘째, 빨라야 합니다.**\n\n인간의 시간은 소중하지만, 더 중요한 것은 **느린 생성이 몰입(flow) 상태를 깨뜨린다**는 점입니다.\n\n인간 중심 워크플로우의 핵심은 \"시도하고, 듣고, 조정하는\" 빠른 사이클입니다. 생성이 매번 몇 분씩 걸린다면 기다리는 동안 영감은 흩어지고, \"놀이\"의 경험은 \"기다림\"의 고통으로 변질됩니다.\n\n따라서 우리는 품질을 보장하면서도 원활한 인간-기계 대화 리듬을 지원할 수 있을 만큼 생성 속도를 최적화했습니다.\n\n### 유한 게임(Finite Game) vs 무한 게임(Infinite Game)\n\n원클릭 생성은 **유한 게임**입니다. 목표가 명확하고 결과 지향적이며 결승선에서 끝납니다. 어떤 면에서 그것은 음악 산업을 차갑게 비우고 많은 사람의 일자리를 대체합니다.\n\n인간 중심의 생성은 **무한 게임**입니다. 재미가 과정에 있고, 그 과정은 결코 끝나지 않기 때문입니다.\n\n우리의 비전은 AI 음악 생성을 민주화하는 것입니다. ACE-Step이 여러분의 주머니 속 큰 장난감이 되게 하고, 음악이 **'Play(연주/놀이)'** 그 자체로 돌아가게 하는 것입니다. 단순히 재생 버튼을 클릭하는 것이 아니라 창의적으로 \"노는\" 것 말이죠.\n\n---\n\n## 코끼리와 기수 비유 (The Elephant Rider Metaphor)\n\n> 추천 읽을거리: [Suno 마스터를 위한 완전 가이드](https://www.notion.so/The-Complete-Guide-to-Mastering-Suno-Advanced-Strategies-for-Professional-Music-Generation-2d6ae744ebdf8024be42f6645f884221) — 이 블로그 튜토리얼은 AI 음악에 대한 기초적인 이해를 세우는 데 도움이 될 것입니다.\n\nAI 음악 생성은 심리학에서 유명한 **'코끼리와 기수'** 비유와 같습니다.\n\n의식은 무의식 위에 올라타 있고, 인간은 코끼리 위에 타 있습니다. 방향을 제시할 수는 있지만 코끼리가 모든 명령을 정확하고 즉각적으로 수행하게 만들 수는 없습니다. 코끼리는 자신만의 관성, 기질, 의지를 가지고 있습니다.\n\n이 코끼리가 바로 음악 생성 모델입니다.\n\n### 빙산 모델 (The Iceberg Model)\n\n오디오와 시맨틱(의미) 사이에는 숨겨진 빙산이 있습니다.\n\n우리가 언어로 묘사할 수 있는 것들 — 스타일, 악기, 음색, 감정, 장면, 전개, 가사, 보컬 스타일 — 은 익숙한 단어들이며 우리가 만질 수 있는 부분입니다. 하지만 이들을 모두 합쳐도 수면 위로 드러난 오디오 빙산의 아주 작은 일부분일 뿐입니다.\n\n가장 정밀한 제어는 무엇일까요? 예상되는 오디오를 입력하면 모델이 그것을 그대로 변함없이 반환하는 것입니다.\n\n하지만 텍스트 설명, 참조, 프롬프트를 사용하는 한 모델은 상상의 나래를 펼칠 공간을 갖게 됩니다. 이것은 버그가 아니라 사물의 본질입니다.\n\n### 코끼리는 무엇인가요?\n\n이 코끼리는 수많은 요소의 융합체입니다. 데이터 분포, 모델 규모, 알고리즘 설계, 어노테이션(주석) 편향, 평가 편향 — **이것은 인류 음악 역사와 엔지니어링적 절충안이 추상적으로 결정화된 것입니다.**\n\n이러한 요소들 중 하나라도 어긋난다면 여러분의 취향과 기대를 정확하게 반영하지 못할 것입니다.\n\n물론 우리는 데이터 규모를 확장하고, 알고리즘 효율을 높이고, 어노테이션의 정밀도를 높이고, 모델 용량을 키우고, 더 전문적인 평가 시스템을 도입할 수 있습니다. 이것들은 모델 개발자로서 우리가 최적화할 수 있는 방향입니다.\n\n하지만 언젠가 기술적 \"완벽함\"에 도달한다 하더라도 피할 수 없는 근본적인 문제가 있습니다. 바로 **취향(taste)**입니다.\n\n### 취향과 기대치\n\n취향은 사람마다 다릅니다.\n\n음악 생성 모델이 모든 청취자를 만족시키려 한다면, 그 출력물은 인류 음악 역사의 대중적 평균으로 수렴할 것입니다. **이것은 극도로 평범할 것입니다.**\n\n소리에 의미, 감정, 경험, 삶, 문화적 상징 가치를 부여하는 것은 인간입니다. 독특한 취향을 만들어내는 것은 소수의 아티스트들이며, 그들이 일반 대중이 소비하고 따르게 만들며 비주류를 주류로 바꿉니다. 이러한 선구적인 소수 아티스트들이 전설이 됩니다.\n\n따라서 모델의 결과물이 \"내 취향이 아니다\"라고 느낀다면, 그것은 모델의 문제가 아니라 **여러분의 취향이 그 \"평균\" 밖에 있기 때문일 수 있습니다.** 이것은 좋은 일입니다.\n\n즉, **여러분은 코끼리가 자동으로 여러분을 이해하기를 기대하기보다 코끼리를 가이드하는 법을 배워야 합니다.**\n\n---\n\n## 코끼리 떼 이해하기: 모델 아키텍처 및 선택\n\n이제 \"코끼리\" 비유를 이해하셨을 겁니다. 사실 이것은 —\n\n**한 마리의 코끼리가 아니라 크고 작은 코끼리들이 가족을 이룬 코끼리 떼입니다.** 🐘🐘🐘🐘\n\n### 아키텍처 원칙: 두 개의 뇌\n\nACE-Step 1.5는 두 개의 핵심 구성 요소가 함께 작동하는 **하이브리드 아키텍처**를 사용합니다.\n\n```\n사용자 입력 → [5Hz LM] → 시맨틱 청사진 → [DiT] → 오디오\n               ↓\n         메타데이터 추론\n         캡션 최적화\n         구조 계획\n```\n\n**5Hz LM (언어 모델) — 기획자 (선택 사항)**\n\nLM은 여러분의 의도를 이해하고 계획을 세우는 담당자입니다.\n- **Chain-of-Thought**를 통해 음악 메타데이터(BPM, 키, 길이 등)를 추론합니다.\n- 여러분의 캡션을 최적화하고 확장하여 의도를 이해하고 보충합니다.\n- **시맨틱 코드(semantic codes)**를 생성합니다. 여기에는 작곡 멜로디, 편곡, 일부 음색 정보가 암시적으로 포함되어 있습니다.\n\nLM은 학습 데이터로부터 **세상에 대한 지식**을 배웁니다. 사용성을 개선하고 프로토타입을 빠르게 생성하도록 돕는 기획자입니다.\n\n**하지만 LM이 반드시 필요한 것은 아닙니다.**\n\n원하는 것이 매우 명확하거나 계획이 이미 서 있다면 `thinking` 모드를 사용하지 않음으로써 LM 계획 단계를 완전히 건너뛸 수 있습니다.\n\n예를 들어, **Cover 모드**에선 참조 오디오를 사용하여 작곡, 화음, 구조를 제약하고 DiT가 직접 생성하게 합니다. 여기서 여러분은 LM의 작업을 대신하는 **기획자 본인**이 됩니다.\n\n또 다른 예로 **Repaint 모드**에선 참조 오디오를 컨텍스트로 사용하여 음색, 믹싱, 세부 사항을 제약하고 DiT가 국소적으로 직접 조정하게 합니다. 여기서 DiT는 창의적인 아이디어를 돕고 불협화음을 고치는 브레인스토밍 파트너에 가깝습니다.\n\n**DiT (Diffusion Transformer) — 실행자**\n\nDiT는 계획을 현실로 바꾸는 \"오디오 장인\"입니다.\n- LM이 생성한 시맨틱 코드와 조건을 전달받습니다.\n- **확산 공정(diffusion process)**을 통해 노이즈로부터 오디오를 점진적으로 \"조각\"해냅니다.\n- 최종적인 음색, 믹싱, 세부 사항을 결정합니다.\n\n**왜 이렇게 설계했나요?**\n\n전통적인 방식은 디퓨전 모델이 텍스트로부터 오디오를 직접 생성하게 하지만, 텍스트-오디오 매핑은 너무 모호합니다. ACE-Step은 중간 레이어로 LM을 도입했습니다.\n- LM은 시맨틱 이해와 계획에 능숙합니다.\n- DiT는 고음질 오디오 생성에 능숙합니다.\n- 두 모델이 각자의 역할에 집중하며 협력합니다.\n\n### 기획자 선택: LM 모델\n\nLM에는 네 가지 옵션이 있습니다: **LM 미사용** (thinking 모드 비활성), **0.6B**, **1.7B**, **4B**.\n\n학습 데이터는 완전히 동일하며, 차이는 순수하게 **지식 용량**에 있습니다.\n- 모델이 클수록 세상에 대한 지식이 풍부합니다.\n- 모델이 클수록 기억력이 좋습니다 (예: 참조 오디오 멜로디 기억).\n- 모델이 클수록 희귀한 스타일이나 악기에 대해 상대적으로 더 잘 작동합니다.\n\n| 선택 | 속도 | 지식 수준 | 기억력 | 활용 사례 |\n|--------|:-----:|:---------------:|:------:|-----------|\n| No LM | ⚡⚡⚡⚡ | — | — | 직접 기획할 때 (예: Cover 모드) |\n| `0.6B` | ⚡⚡⚡ | 기초 | 낮음 | 저사양 GPU (< 8GB), 빠른 프로토타이핑 |\n| `1.7B` | ⚡⚡ | 중간 | 중간 | **기본 권장 사항** |\n| `4B` | ⚡ | 풍부 | 강함 | 복잡한 작업, 고품질 생성 |\n\n**어떻게 선택하나요?**\n\n하드웨어 사양에 맞춰 선택하세요.\n- **VRAM < 8GB** → LM 미사용 또는 `0.6B`\n- **VRAM 8–16GB** → `1.7B` (기본값)\n- **VRAM > 16GB** → `1.7B` 또는 `4B`\n\n### 실행자 선택: DiT 모델\n\n계획이 세워졌다면 실행자를 선택해야 합니다. DiT는 ACE-Step 1.5의 핵심으로, 다양한 작업을 처리하고 LM이 생성한 코드를 해석하는 방식을 결정합니다.\n\n우리는 **4개의 Turbo 모델**, **1개의 SFT 모델**, **1개의 Base 모델**을 제공합니다.\n\n#### Turbo 시리즈 (일상적 사용 권장)\n\nTurbo 모델은 증류(distillation) 학습을 거쳐 단 8단계 만에 고품질 오디오를 생성합니다. 네 가지 변형 모델의 핵심적인 차이는 증류 과정에서의 **시프트(shift) 하이퍼파라미터 설정**입니다.\n\n**시프트(shift)란 무엇인가요?**\n\n시프트는 DiT 디노이징 과정에서 \"주의 집중 배분\"을 결정합니다.\n- **큰 시프트** → 초기 디노이징에 더 많은 노력을 들여 **강한 시맨틱**과 명확한 골격을 구축합니다.\n- **작은 시프트** → 균등한 단계 배분으로 **더 많은 세부 사항**을 표현하지만, 노이즈가 섞일 수 있습니다.\n\n쉽게 이해하자면: 높은 시프트는 \"외곽선을 먼저 그리고 세부 사항을 채우는\" 방식이고, 낮은 시프트는 \"그리면서 동시에 수정해 나가는\" 방식입니다.\n\n| 모델 | 증류 설정 | 특징 |\n|-------|---------------------|-----------------|\n| `turbo` (기본) | shift 1, 2, 3 공동 증류 | **창의성과 시맨틱의 최적 균형**, 가장 추천하는 모델 |\n| `turbo-shift1` | shift=1 전용 증류 | 세부 표현이 풍부하지만 시맨틱은 상대적으로 약함 |\n| `turbo-shift3` | shift=3 전용 증류 | 더 명확하고 풍부한 음색, 하지만 건조하게 들릴 수 있음 |\n| `turbo-continuous` | 실험적 변형 | 1~5 사이의 연속적인 시프트 조절 지원 |\n\n음악 스타일에 따라 선호하는 모델을 선택할 수 있습니다. **처음에는 가장 균형 잡힌 `turbo` 모델로 시작하는 것을 권장합니다.**\n\n#### SFT 모델\n\nTurbo와 비교하여 SFT 모델은 두 가지 특징이 있습니다.\n- **CFG (Classifier-Free Guidance) 지원**: 프롬프트 준수 능력을 미세 조정할 수 있습니다.\n- **더 많은 단계 (50 steps)**: 모델이 더 오래 \"생각\"할 시간을 줍니다.\n\n단점은 단계가 많아질수록 에러가 누적되어 오디오의 선명도가 Turbo보다 약간 떨어질 수 있다는 점입니다. 하지만 **세부 묘사와 시맨틱 파싱 능력은 더 뛰어납니다.**\n\n#### Base 모델\n\nBase 모델은 **모든 작업의 마스터**이며, SFT나 Turbo에는 없는 3가지 전용 작업을 지원합니다.\n\n| 작업 | 설명 |\n|------|-------------|\n| `extract` | 믹스된 오디오에서 단일 트랙 추출 (예: 보컬 제거) |\n| `lego` | 기존 트랙에 새로운 트랙 추가 (예: 기타에 드럼 추가) |\n| `complete` | 단일 트랙에 믹스된 반주 추가 (예: 보컬에 기타+드럼 반주 추가) |\n\n또한 Base 모델은 **가소성이 가장 높습니다.** 대규모 미세 조정이 필요한 경우 Base 모델로 실험을 시작하는 것이 좋습니다.\n\n---\n\n## 코끼리 가이드하기: 무엇을 제어할 수 있나요?\n\n이제 코끼리 떼에 대해 알게 되었으니, 그들과 소통하는 법을 배워봅시다.\n\n모든 생성은 **입력 제어**, **추론 하이퍼파라미터**, **랜덤 요소**라는 세 가지 요인에 의해 결정됩니다.\n\n### I. 입력 제어: 무엇을 원하는가?\n\n이 부분은 모델과 \"창작 의도\"를 소통하는 부분입니다.\n\n| 카테고리 | 파라미터 | 역할 |\n|----------|-----------|----------|\n| **작업 유형** | `task_type` | 생성 모드 결정: text2music, cover, repaint, lego, extract, complete |\n| **텍스트 입력** | `caption` | 음악 전반에 대한 설명: 스타일, 악기, 감정, 분위기, 음색, 보컬 성별, 전개 등 |\n| | `lyrics` | 시간에 따른 전개 설명: 가사 내용, 음악 구조 진화, 보컬 변화, 연주 스타일 등 (연주곡은 `[Instrumental]` 사용) |\n| **음악 메타데이터** | `bpm` | 템포 (30–300) |\n| | `keyscale` | 키 (예: C Major, Am) |\n| | `timesignature` | 박자 기호 (4/4, 3/4, 6/8) |\n| | `vocal_language` | 보컬 언어 |\n| | `duration` | 목표 길이 (초) |\n| **오디오 참조** | `reference_audio` | 음색이나 스타일에 대한 전역 참조 (속성 전이용) |\n| | `src_audio` | 오디오 기반 작업의 소스 파일 |\n| | `audio_codes` | 시맨틱 코드 직접 입력 (고급 사용자용) |\n| **구간 제어** | `repainting_start/end` | 작업 시간 범위 (repaint 구역 등) |\n\n---\n\n#### Caption에 대하여: 가장 중요한 입력\n\n**Caption(캡션)은 생성된 음악에 영향을 주는 가장 중요한 요소입니다.**\n\n단순한 스타일 단어, 쉼표로 구분된 태그, 복잡한 자연어 설명 등 다양한 형식을 지원합니다.\n\n**좋은 캡션을 쓰기 위한 5가지 방법:**\n\n1. **무작위 주사위** — UI의 랜덤 버튼을 클릭하여 예제 캡션이 어떻게 작성되었는지 확인하세요. 이를 템플릿으로 사용할 수 있습니다.\n2. **Format 자동 재작성** — 간단히 쓴 내용을 LLM이 자동으로 확장해 주는 `format` 기능을 활용하세요.\n3. **CoT 재작성** — LM이 초기화된 경우, Chain-of-Thought를 통해 캡션을 최적화하고 확장할 수 있습니다.\n4. **오디오에서 캡션 추출** — 입력 오디오를 캡션으로 변환하는 기능도 제공합니다. 완벽하진 않아도 시작점으로 충분합니다.\n5. **Simple Mode** — 간단한 곡 설명만 입력하면 LM이 캡션, 가사, 메타데이터를 모두 자동으로 생성합니다.\n\n**캡션 작성을 위한 차원들:**\n주장(Style), 감정(Emotion), 악기(Instruments), 음색 질감(Timbre Texture), 시대(Era), 프로덕션 스타일(Production Style), 보컬 특징(Vocal), 속도/리듬(Speed) 등을 조합하세요.\n\n**실질적인 원칙:**\n1. **구체적으로 쓰세요** — \"슬픈 노래\"보다는 \"피아노 발라드와 허스키한 여성 보컬\"이 낫습니다.\n2. **여러 차원을 조합하세요** — 스타일+감정+악기+질감을 조합하면 의도를 더 정확히 고착시킬 수 있습니다.\n3. **충돌하는 단어를 피하세요** — \"클래식 현악기\"와 \"하드코어 메탈\"을 동시에 원하면 결과가 모호해질 수 있습니다.\n\n---\n\n#### 가사(Lyrics)에 대하여: 시간적 시나리오\n\n캡션이 음악의 \"전체 초상화\"라면, **가사는 음악의 \"시간적 시나리오\"**입니다.\n- 가사 텍스트 그 자체\n- **구조 태그** ([Verse], [Chorus], [Bridge]...)\n- **보컬 스타일 힌트** ([raspy vocal], [whispered]...)\n- **악기 연주 구간** ([guitar solo], [drum break]...)\n- **에너지 변화** ([building energy], [explosive drop]...)\n\n**구조 태그가 핵심입니다.**\n각 섹션이 시작될 때 `[Verse]`, `[Chorus]` 등의 태그를 사용하여 모델에게 현재 구간의 성격을 알려주세요. `[Chorus - anthemic]`과 같이 세부 묘사를 추가할 수도 있습니다.\n\n**모델과의 일관성 유지:**\n캡션에서 \"피아노 발라드\"라고 했다면 가사 구간에서 `[Guitar Solo - electric]`과 같은 충돌하는 태그를 쓰지 않도록 주의하세요.\n\n---\n\n#### 음악 메타데이터: 선택적인 미세 제어\n\n대부분의 경우 메타데이터를 직접 설정할 필요는 없습니다. `thinking` 모드를 켜면 LM이 캡션과 가사를 바탕으로 적절한 BPM, 키, 박자를 스스로 결정합니다.\n\n하지만 명확한 요구 사항이 있다면 직접 `bpm`, `keyscale`, `timesignature` 등을 설정할 수 있습니다. 이는 \"엄밀한 명령\"이라기보다 모델이 참고하는 **\"가이드라인\"**임을 명심하세요.\n\n---\n\n#### 오디오 제어: 소리로 소리 제어하기\n\n**텍스트는 추상화된 전달이지만, 가장 강력한 제어는 여전히 오디오를 통하는 방식입니다.**\n\n1. **참조 오디오 (Reference Audio)**: 음색, 믹싱 스타일, 연주 기법 등 **전반적인 질감**을 제어합니다.\n2. **소스 오디오 (Source Audio - Cover)**: **멜로디 구조**를 제어합니다. 원곡의 구조를 유지하면서 스타일만 바꾸고 싶을 때 사용합니다.\n3. **컨텍스트 기반 제어 (Repaint)**: 기존 오디오의 **특정 구간을 수정하거나 이어 쓰기** 위해 사용합니다. 인트로, 중간 구간, 엔딩 등 어디든 가능합니다.\n\n---\n\n## 결론\n\n이 튜토리얼은 ACE-Step 1.5의 핵심 개념과 사용법을 다루었습니다.\n- **멘탈 모델**: 인간 중심의 생성 철학 이해\n- **아키텍처**: LM과 DiT의 협업 이해\n- **입력 제어**: 텍스트 및 오디오를 통한 제어 방법 마스터\n- **추론 하이퍼파라미터**: 생성 공정에 영향을 주는 파라미터 이해\n- **랜덤 요소**: 랜덤성을 탐색 도구로 활용하고 자동화 툴로 효율을 높이는 법\n\n이것은 시작일 뿐입니다. 더 많은 프롬프트 팁, 작업별 상세 가이드, 고급 기술 등을 계속 업데이트할 예정입니다. 질문이나 제안이 있다면 언제든 피드백을 주세요. ACE-Step이 여러분의 훌륭한 창의적 파트너가 되기를 바랍니다.\n\n---\n\n*계속될 예정입니다...*\n"
  },
  {
    "path": "docs/ko/index.md",
    "content": "---\nlayout: home\nhero:\n  name: ACE-Step 1.5\n  text: 오픈소스 음악 생성\n  tagline: 소비자 하드웨어에서 상용 수준의 음악 생성. A100에서 곡당 2초 미만, VRAM 4GB 미만.\n  image:\n    src: /logo.png\n    alt: ACE-Step\n  actions:\n    - theme: brand\n      text: 튜토리얼 (필독)\n      link: /ko/Tutorial\n    - theme: alt\n      text: API 레퍼런스\n      link: /ko/API\n\nfeatures:\n  - icon: \"&#9889;\"\n    title: 초고속 생성\n    details: A100에서 곡당 2초 미만, RTX 3090에서 10초 미만. 10초에서 10분까지 오디오 생성 지원.\n  - icon: \"&#127925;\"\n    title: 상용 수준 품질\n    details: 1000개 이상의 악기와 스타일, 50개 이상의 언어, 세밀한 음색 기술과 가사 구조 제어.\n  - icon: \"&#127899;\"\n    title: 다양한 편집 기능\n    details: 커버 생성, 리페인팅, 트랙 분리, 보컬-BGM 변환, 멀티트랙 생성 등.\n  - icon: \"&#128640;\"\n    title: 경량 & 맞춤 설정\n    details: 4GB 미만 VRAM으로 로컬 실행. 몇 곡으로 LoRA 학습, 3090에서 1시간.\n---\n"
  },
  {
    "path": "docs/sidestep/Dataset Preparation.md",
    "content": "# Dataset Preparation\n\nSide-Step supports two ways to prepare your audio dataset for training: **folder-only mode** (zero configuration) and **JSON mode** (full metadata control).\n\nSide-Step is **fully compatible** with ACE-Step's dataset JSON format. If you built your dataset using ACE-Step's Dataset Builder (Gradio UI), the resulting JSON works directly with Side-Step -- all fields are recognized.\n\nBoth modes produce the same preprocessed `.pt` tensors. The only difference is how much information you provide about each audio file.\n\n---\n\n## Supported Audio Formats\n\n`.wav`, `.mp3`, `.flac`, `.ogg`, `.opus`, `.m4a`\n\nSide-Step recursively scans directories, so you can organize files into subfolders.\n\n---\n\n## Folder-Only Mode (No JSON)\n\nThe simplest approach. Point Side-Step at a folder of audio files:\n\n```bash\nuv run train.py fixed \\\n    --checkpoint-dir ./checkpoints \\\n    --model-variant turbo \\\n    --preprocess \\\n    --audio-dir ./my_audio \\\n    --tensor-output ./my_tensors\n```\n\nSide-Step auto-generates metadata for each file:\n\n| Field | Auto-generated value |\n| :--- | :--- |\n| Caption | Filename with `_` and `-` replaced by spaces (e.g., `heavy_metal_riff.wav` becomes `heavy metal riff`) |\n| Lyrics | `[Instrumental]` |\n| Genre | *(empty)* |\n| BPM / Key / Time Signature | `N/A` |\n| Is Instrumental | `True` |\n\nThis is fine for quick experiments but you will get better training results by providing proper metadata.\n\n---\n\n## JSON Mode (Full Metadata)\n\nCreate a JSON file describing your dataset, then pass it alongside `--audio-dir`:\n\n```bash\nuv run train.py fixed \\\n    --checkpoint-dir ./checkpoints \\\n    --model-variant turbo \\\n    --preprocess \\\n    --audio-dir ./my_audio \\\n    --dataset-json ./my_dataset.json \\\n    --tensor-output ./my_tensors\n```\n\n### JSON Structure\n\nThree formats are accepted:\n\n**Array format** (simplest -- just a list of samples):\n\n```json\n[\n  { \"audio_path\": \"./song1.wav\", \"caption\": \"Upbeat pop track\" },\n  { \"audio_path\": \"./song2.wav\", \"caption\": \"Slow jazz ballad\" }\n]\n```\n\n**Object format with samples only:**\n\n```json\n{\n  \"samples\": [\n    { \"audio_path\": \"./song1.wav\", \"caption\": \"Upbeat pop track\" },\n    { \"audio_path\": \"./song2.wav\", \"caption\": \"Slow jazz ballad\" }\n  ]\n}\n```\n\n**Full ACE-Step format** (with dataset-level metadata -- this is what ACE-Step's Dataset Builder produces):\n\n```json\n{\n  \"metadata\": {\n    \"name\": \"my_dataset\",\n    \"custom_tag\": \"mytrigger\",\n    \"tag_position\": \"prepend\",\n    \"created_at\": \"2026-02-12T00:28:25.419505\",\n    \"num_samples\": 2,\n    \"all_instrumental\": false,\n    \"genre_ratio\": 90\n  },\n  \"samples\": [\n    {\n      \"id\": \"00edb2c3\",\n      \"audio_path\": \"./songs/track1.mp3\",\n      \"filename\": \"track1.mp3\",\n      \"caption\": \"An energetic rock track with electric guitar and driving drums\",\n      \"genre\": \"Rock\",\n      \"lyrics\": \"[Verse 1]\\nRising up from the ashes tonight\\n[Chorus]\\nWe're on fire, burning bright\",\n      \"raw_lyrics\": \"\",\n      \"formatted_lyrics\": \"[Verse 1]\\nRising up...\",\n      \"bpm\": 140,\n      \"keyscale\": \"E minor\",\n      \"timesignature\": \"4\",\n      \"duration\": 180,\n      \"language\": \"en\",\n      \"is_instrumental\": false,\n      \"custom_tag\": \"mytrigger\",\n      \"labeled\": true,\n      \"prompt_override\": null\n    }\n  ]\n}\n```\n\n### Path Resolution\n\nRelative paths in `audio_path` are resolved **from the JSON file's directory**, not from where you run the command. For example, if your JSON is at `./data/my_dataset.json` and contains `\"audio_path\": \"./songs/track1.wav\"`, Side-Step looks for `./data/songs/track1.wav`.\n\n---\n\n## Dataset-Level Metadata Block\n\nWhen using the full ACE-Step format, the top-level `metadata` block controls dataset-wide behavior:\n\n| Field | Default | Description |\n| :--- | :--- | :--- |\n| `name` | `\"untitled_dataset\"` | Dataset name (informational) |\n| `custom_tag` | *(empty)* | Default trigger word applied to all samples that don't define their own `custom_tag` |\n| `tag_position` | `\"prepend\"` | Where to place the `custom_tag` relative to the caption: `\"prepend\"`, `\"append\"`, or `\"replace\"` |\n| `genre_ratio` | `0` | Percentage (0-100) of samples that use `genre` instead of `caption` as the text prompt. For example, `90` means 90% of samples use genre, 10% use caption |\n| `all_instrumental` | `true` | Whether all tracks are instrumental (informational) |\n| `created_at` | *(auto)* | Creation timestamp (informational) |\n| `num_samples` | `0` | Sample count (informational) |\n\n**How `genre_ratio` works:** At preprocessing time, Side-Step randomly selects the specified percentage of samples (seeded for reproducibility) and uses their `genre` field instead of `caption` for the text prompt. This adds variety to training -- the model learns to respond to both detailed captions and genre tags. With `genre_ratio=0` (default), all samples use caption. With `genre_ratio=90`, 90% use genre.\n\n**How `custom_tag` works:** The dataset-level `custom_tag` is applied as a fallback to any sample that doesn't have its own. In ACE-Step's Dataset Builder, `set_custom_tag()` copies the tag to every sample, so typically all samples already have it. Side-Step respects both the per-sample and dataset-level values.\n\n---\n\n## Per-Sample Field Reference\n\n| Field | Required | Default | Used by Side-Step | Description |\n| :--- | :--- | :--- | :--- | :--- |\n| `audio_path` | Yes* | -- | Yes | Path to the audio file. Relative paths resolve from the JSON file's directory |\n| `filename` | Fallback* | -- | Yes | Alternative to `audio_path`. Also used as the metadata lookup key |\n| `caption` | No | Derived from filename | Yes | Text description of the audio. Primary prompt text |\n| `genre` | No | *(empty)* | Yes | Genre description (e.g., `\"Rock\"`, `\"Electronic ambient\"`). Used as prompt when `genre_ratio > 0` or `prompt_override = \"genre\"` |\n| `lyrics` | No | `[Instrumental]` | Yes | Song lyrics with section markers (`[Verse]`, `[Chorus]`, etc.) |\n| `bpm` | No | `N/A` | Yes | Beats per minute |\n| `keyscale` | No | `N/A` | Yes | Musical key (e.g., `\"C major\"`, `\"Bb minor\"`) |\n| `timesignature` | No | `N/A` | Yes | Time signature (e.g., `\"4\"`, `\"4/4\"`, `\"3/4\"`) |\n| `duration` | No | `0` | Yes | Duration in seconds. Informational; actual duration comes from the audio file |\n| `is_instrumental` | No | `True` | Yes | Whether the track is instrumental |\n| `custom_tag` | No | *(from dataset metadata)* | Yes | Trigger word for this sample. Falls back to dataset-level `custom_tag` if empty |\n| `prompt_override` | No | `null` | Yes | Per-sample override: `\"caption\"` or `\"genre\"`. Overrides `genre_ratio` for this sample |\n| `id` | No | *(auto)* | Accepted | Sample identifier. Passed through in metadata |\n| `raw_lyrics` | No | *(empty)* | Accepted | Original user-provided lyrics (pre-formatting). Passed through |\n| `formatted_lyrics` | No | *(empty)* | Accepted | LM-formatted lyrics. Passed through |\n| `language` | No | `\"unknown\"` | Accepted | Language code (e.g., `\"en\"`). Passed through |\n| `labeled` | No | `false` | Accepted | Whether the sample has been labeled. Passed through |\n\n\\*At least one of `audio_path` or `filename` is required for Side-Step to find the audio file.\n\n**\"Accepted\"** means Side-Step reads and preserves the field in preprocessed tensor metadata but does not use it to modify the training prompt. These fields exist for compatibility with ACE-Step's Dataset Builder.\n\n---\n\n## Custom Tags (Trigger Words)\n\nThe `custom_tag` field lets you train a LoRA that activates with a specific trigger word. For example:\n\n```json\n{\n  \"metadata\": {\n    \"custom_tag\": \"myguitarstyle\",\n    \"tag_position\": \"prepend\"\n  },\n  \"samples\": [\n    {\n      \"audio_path\": \"./guitar_solo_1.wav\",\n      \"caption\": \"Electric guitar solo with heavy distortion\",\n      \"custom_tag\": \"myguitarstyle\"\n    }\n  ]\n}\n```\n\nDuring training, the prompt becomes `\"myguitarstyle, Electric guitar solo with heavy distortion\"`. At inference time, include `myguitarstyle` in your prompt to activate the trained style.\n\nThe `tag_position` field controls placement:\n\n- `\"prepend\"` (default): `\"myguitarstyle, Electric guitar solo...\"` -- tag comes first\n- `\"append\"`: `\"Electric guitar solo..., myguitarstyle\"` -- tag comes last\n- `\"replace\"`: `\"myguitarstyle\"` -- tag replaces the entire caption\n\n---\n\n## Complete Examples\n\n### Minimal (two vocal tracks, array format)\n\n```json\n[\n  {\n    \"audio_path\": \"./vocals/track1.wav\",\n    \"caption\": \"Female vocals over acoustic guitar\"\n  },\n  {\n    \"audio_path\": \"./vocals/track2.wav\",\n    \"caption\": \"Male vocals with piano accompaniment\"\n  }\n]\n```\n\n### Full ACE-Step format (as produced by the Dataset Builder)\n\n```json\n{\n  \"metadata\": {\n    \"name\": \"my_artist_dataset\",\n    \"custom_tag\": \"myartist\",\n    \"tag_position\": \"prepend\",\n    \"created_at\": \"2026-02-14T12:00:00.000000\",\n    \"num_samples\": 2,\n    \"all_instrumental\": false,\n    \"genre_ratio\": 90\n  },\n  \"samples\": [\n    {\n      \"id\": \"a1b2c3d4\",\n      \"audio_path\": \"./songs/energetic_rock.wav\",\n      \"filename\": \"energetic_rock.wav\",\n      \"caption\": \"Energetic rock track with electric guitar and driving drums\",\n      \"genre\": \"Rock\",\n      \"lyrics\": \"[Verse 1]\\nRising up from the ashes tonight\\n[Chorus]\\nWe're on fire, burning bright\",\n      \"raw_lyrics\": \"\",\n      \"formatted_lyrics\": \"[Verse 1]\\nRising up from the ashes tonight\\n[Chorus]\\nWe're on fire, burning bright\",\n      \"bpm\": 140,\n      \"keyscale\": \"E minor\",\n      \"timesignature\": \"4\",\n      \"duration\": 180,\n      \"language\": \"en\",\n      \"is_instrumental\": false,\n      \"custom_tag\": \"myartist\",\n      \"labeled\": true,\n      \"prompt_override\": null\n    },\n    {\n      \"id\": \"e5f6g7h8\",\n      \"audio_path\": \"./songs/ambient_pad.wav\",\n      \"filename\": \"ambient_pad.wav\",\n      \"caption\": \"Ethereal ambient pad with slow evolving textures\",\n      \"genre\": \"Ambient\",\n      \"lyrics\": \"[Instrumental]\",\n      \"raw_lyrics\": \"\",\n      \"formatted_lyrics\": \"[Instrumental]\",\n      \"bpm\": 70,\n      \"keyscale\": \"C major\",\n      \"timesignature\": \"4\",\n      \"duration\": 240,\n      \"language\": \"unknown\",\n      \"is_instrumental\": true,\n      \"custom_tag\": \"myartist\",\n      \"labeled\": true,\n      \"prompt_override\": null\n    }\n  ]\n}\n```\n\nWith `genre_ratio: 90`, about 90% of these samples will use their `genre` field (e.g., \"Rock\", \"Ambient\") as the training prompt instead of the full `caption`. This matches ACE-Step's upstream behavior.\n\n---\n\n## Tips\n\n- **Minimum dataset size:** 5+ audio files is recommended. Fewer samples may lead to overfitting (the model memorizes rather than generalizes).\n- **Consistent quality:** Keep audio quality consistent across your dataset. Mixing high and low quality recordings confuses training.\n- **Duration range:** Audio should be between 30 and 240 seconds. Longer files are truncated to `--max-duration` (default: 240s). Very short clips may not provide enough context.\n- **Preprocessing is adapter-agnostic:** The same preprocessed tensors work for both LoRA and LoKR training. You only need to preprocess once.\n- **Captions matter:** Descriptive captions give the model more to learn from. \"Energetic rock with distorted guitars\" is better than \"song1\".\n- **Lyrics format:** Use section markers like `[Verse 1]`, `[Chorus]`, `[Bridge]` for structure. Use `[Instrumental]` for tracks without vocals.\n- **Genre ratio:** If you have both `caption` and `genre` filled out, use `genre_ratio` to add prompt variety during training.\n- **ACE-Step compatibility:** JSONs created by ACE-Step's Dataset Builder work directly. All fields are recognized.\n\n---\n\n## See Also\n\n- [[Training Guide]] -- Full training walkthrough\n- [[End-to-End Tutorial]] -- Step-by-step from raw audio to generation\n- [[The Settings Wizard]] -- Wizard settings reference\n"
  },
  {
    "path": "docs/sidestep/End-to-End Tutorial.md",
    "content": "# End-to-End Tutorial\n\nThis walkthrough takes you from raw audio files to generating music with a trained LoRA adapter. Every step includes the CLI command and links to detailed documentation.\n\n**Prerequisites:** Side-Step installed and working, model checkpoints downloaded, GPU with CUDA support. See [[Getting Started]] if you have not set up yet.\n\n---\n\n## Step 1: Prepare Your Dataset\n\nCollect your audio files into a single folder. Side-Step supports `.wav`, `.mp3`, `.flac`, `.ogg`, `.opus`, and `.m4a`.\n\n```text\nmy_audio/\n├── track1.wav\n├── track2.wav\n├── track3.mp3\n└── track4.flac\n```\n\n**Optional but recommended:** Create a dataset JSON file with metadata for each track. This gives the model more information to learn from (captions, lyrics, genre, BPM, etc.):\n\n```json\n[\n  {\n    \"audio_path\": \"./track1.wav\",\n    \"caption\": \"Energetic rock with distorted guitars and driving drums\",\n    \"genre\": \"Rock\",\n    \"bpm\": 140,\n    \"custom_tag\": \"mystyle\"\n  },\n  {\n    \"audio_path\": \"./track2.wav\",\n    \"caption\": \"Mellow acoustic folk song with fingerpicked guitar\",\n    \"genre\": \"Folk\",\n    \"bpm\": 95\n  }\n]\n```\n\nSave this as `my_dataset.json` in the same directory as your audio files.\n\nFor full details on all available fields, see [[Dataset Preparation]].\n\n---\n\n## Step 2: Preprocess\n\nConvert your raw audio into preprocessed `.pt` tensor files. This runs in two low-VRAM passes: (1) VAE + Text Encoder (~3 GB), then (2) DIT encoder (~6 GB).\n\n**Without a dataset JSON (auto-captions from filenames):**\n\n```bash\nuv run train.py fixed \\\n    --checkpoint-dir ./checkpoints \\\n    --model-variant turbo \\\n    --preprocess \\\n    --audio-dir ./my_audio \\\n    --tensor-output ./my_tensors\n```\n\n**With a dataset JSON:**\n\n```bash\nuv run train.py fixed \\\n    --checkpoint-dir ./checkpoints \\\n    --model-variant turbo \\\n    --preprocess \\\n    --audio-dir ./my_audio \\\n    --dataset-json ./my_audio/my_dataset.json \\\n    --tensor-output ./my_tensors\n```\n\nAfter preprocessing, you will have a `my_tensors/` directory containing `.pt` files and a `manifest.json`. These tensors work for both LoRA and LoKR training -- you only need to preprocess once.\n\n---\n\n## Step 3: Train\n\nStart training with the preprocessed tensors:\n\n```bash\nuv run train.py fixed \\\n    --checkpoint-dir ./checkpoints \\\n    --model-variant turbo \\\n    --dataset-dir ./my_tensors \\\n    --output-dir ./output/my_lora \\\n    --epochs 100\n```\n\nThis uses the `recommended` defaults (rank 64, cosine LR schedule, AdamW optimizer). To use a preset instead:\n\n```bash\n# Start the wizard and load a preset\nuv run train.py\n```\n\nThe wizard lets you load a preset (e.g., `vram_12gb` for a 12 GB GPU), adjust individual settings, and start training interactively. See [[Preset Management]] for the full list of built-in presets.\n\n**Key flags to know:**\n\n| Flag | Purpose |\n| :--- | :--- |\n| `--epochs 100` | How many times to loop through the dataset |\n| `--rank 64` | LoRA capacity (higher = more expressive, more VRAM) |\n| `--save-every 10` | Save a checkpoint every N epochs |\n| `--offload-encoder` | Free ~2-4 GB VRAM by moving encoders to CPU |\n| `--optimizer-type adamw8bit` | Use 8-bit optimizer to save VRAM |\n\nFor all available options, see the Complete Argument Reference in the README or [[The Settings Wizard]].\n\n---\n\n## Step 4: Monitor\n\nWhile training runs (or after it finishes), view your training metrics with TensorBoard:\n\n```bash\ntensorboard --logdir ./output/my_lora/runs\n```\n\nOpen `http://localhost:6006` in your browser. Watch for:\n\n- **Loss** decreasing and stabilizing (good) vs. loss dropping then rising (overfitting).\n- **Learning rate** following the expected schedule (warmup then decay).\n- **Gradient norms** staying stable (spikes may indicate training issues).\n\n---\n\n## Step 5: Use Your LoRA\n\nAfter training completes, your adapter is saved in `./output/my_lora/final/`.\n\n### In ACE-Step Gradio\n\n1. Start ACE-Step's Gradio UI.\n2. In **Service Configuration**, find the **LoRA Adapter** section.\n3. Enter the path to your adapter:\n   ```\n   /full/path/to/Side-Step/output/my_lora/final\n   ```\n4. Click **Load LoRA**.\n5. Toggle **Use LoRA** on.\n6. Adjust **LoRA Scale** (1.0 = full strength).\n7. Generate audio. If you used a `custom_tag`, include it in your prompt.\n\n**Important:** Use the correct shift and inference steps for your model variant. If you trained on turbo, use `shift=3.0` and 8 inference steps. For base/sft, use `shift=1.0` and 50 steps. See [[Shift and Timestep Sampling]] for details.\n\nFor the full guide on output layout, LoKR limitations, and checkpoint usage, see [[Using Your Adapter]].\n\n---\n\n## Step 6: Iterate\n\nTraining is iterative. Here are common next steps:\n\n### Resume training for more epochs\n\n```bash\nuv run train.py fixed \\\n    --checkpoint-dir ./checkpoints \\\n    --model-variant turbo \\\n    --dataset-dir ./my_tensors \\\n    --output-dir ./output/my_lora \\\n    --resume-from ./output/my_lora/checkpoints/epoch_100 \\\n    --epochs 200\n```\n\n### Try a different preset\n\nLoad a VRAM-appropriate preset to optimize for your GPU:\n\n```bash\nuv run train.py    # wizard mode, load a preset at the start\n```\n\n### Test intermediate checkpoints\n\nEvery checkpoint is inference-ready. Point ACE-Step at any checkpoint directory to hear how your LoRA sounds at different training stages:\n\n```\n./output/my_lora/checkpoints/epoch_50\n./output/my_lora/checkpoints/epoch_100\n```\n\n### Adjust hyperparameters\n\n- **Overfitting?** (loss drops then rises, output sounds like your training data verbatim) -- Lower rank, increase dropout, add more training data.\n- **Underfitting?** (loss stays high, LoRA has no audible effect) -- Increase epochs, increase rank, check your dataset quality.\n- **Running out of VRAM?** -- See [[VRAM Optimization Guide]] for tier-specific settings.\n\n---\n\n## Quick Reference\n\n| Step | Command | Output |\n| :--- | :--- | :--- |\n| Preprocess | `uv run train.py fixed --preprocess --audio-dir ./my_audio --tensor-output ./my_tensors ...` | `./my_tensors/*.pt` |\n| Train | `uv run train.py fixed --dataset-dir ./my_tensors --output-dir ./output/my_lora ...` | `./output/my_lora/final/` |\n| Monitor | `tensorboard --logdir ./output/my_lora/runs` | Browser at localhost:6006 |\n| Inference | Load `./output/my_lora/final` in ACE-Step Gradio | Generated audio |\n\n---\n\n## See Also\n\n- [[Dataset Preparation]] -- JSON format, metadata fields, audio requirements\n- [[Using Your Adapter]] -- Output layout, Gradio loading, LoKR limitations\n- [[Training Guide]] -- Full training options and hyperparameters\n- [[Preset Management]] -- Built-in presets, save/load/import/export\n- [[VRAM Optimization Guide]] -- GPU memory profiles\n- [[Windows Notes]] -- Windows-specific setup and workarounds\n"
  },
  {
    "path": "docs/sidestep/Estimation Guide.md",
    "content": "\n## What Is Gradient Estimation?\n\nGradient estimation (also called sensitivity analysis) ranks the attention modules inside the ACE-Step decoder by how much they respond to **your specific dataset**. Instead of blindly training every `q_proj`, `k_proj`, `v_proj`, and `o_proj` layer equally, estimation tells you which ones matter most.\n\nThink of it like an X-ray of the model: it shows where the gradients concentrate when your audio is passed through the network.\n\n---\n\n## Why It Matters\n\n- **Targeted training**: Focus the adapter on the layers that actually learn from your data.\n- **Fewer wasted parameters**: If layer 22 barely responds to your dataset, you don't need to train it.\n- **Better results at lower rank**: By selecting only the top-K most sensitive modules, a rank-32 adapter trained on 16 carefully chosen modules can outperform a rank-64 adapter spread across all 80+ modules.\n- **Dataset comparison**: Run estimation on two different datasets and compare -- you'll see where they differ.\n\n---\n\n## How To Run Estimation\n\n### Via the Wizard (Recommended)\n\n```bash\nuv run python train.py\n```\n\n1. From the main menu, select **Estimate gradient sensitivity**\n2. Point it to your checkpoint directory and preprocessed dataset\n3. Adjust the parameters (or press Enter for defaults)\n4. Review the results and save the JSON\n\n### Via CLI\n\n```bash\nuv run python train.py estimate \\\n    --checkpoint-dir ../ACE-Step-1.5/checkpoints \\\n    --model-variant base \\\n    --dataset-dir ./my_tensors \\\n    --estimate-batches 5 \\\n    --top-k 16 \\\n    --granularity module \\\n    --estimate-output ./estimate_results.json\n```\n\n---\n\n## Reading the Output\n\nEstimation produces a JSON file with a ranked list:\n\n```json\n[\n  {\"module\": \"decoder.layers.22.self_attn.q_proj\", \"sensitivity\": 0.04231},\n  {\"module\": \"decoder.layers.22.self_attn.v_proj\", \"sensitivity\": 0.03894},\n  {\"module\": \"decoder.layers.18.cross_attn.k_proj\", \"sensitivity\": 0.03512},\n  ...\n]\n```\n\n### What Each Field Means\n\n| Field | Meaning |\n|-------|---------|\n| `module` | Full dot-path name of the attention projection inside the decoder |\n| `sensitivity` | Average gradient norm across estimation batches (higher = more responsive) |\n\n**Higher sensitivity = more important for your dataset.** The modules at the top of the list are where the model \"wants\" to change the most when it sees your audio.\n\n---\n\n## Understanding Module Names\n\nACE-Step's decoder is a stack of transformer layers. Each layer has attention blocks, and each attention block has four linear projections:\n\n| Projection | Role |\n|------------|------|\n| `q_proj` | **Query** -- what the model is looking for |\n| `k_proj` | **Key** -- what each position offers |\n| `v_proj` | **Value** -- the actual content to read |\n| `o_proj` | **Output** -- projects the attention result back |\n\n### Self-Attention vs Cross-Attention\n\n| Type | Path Pattern | What It Does |\n|------|-------------|--------------|\n| Self-attention | `decoder.layers.N.self_attn.*` | Relates audio positions to each other (rhythm, structure, patterns) |\n| Cross-attention | `decoder.layers.N.cross_attn.*` | Connects audio to text conditioning (lyrics, genre, prompt) |\n\n**Interpretation tips:**\n\n- If **self-attention** modules rank high, your dataset has distinctive audio patterns (rhythms, timbres, structures) the model wants to learn.\n- If **cross-attention** modules rank high, the text/lyrics conditioning is strongly tied to the audio -- the model is learning text-to-audio alignment.\n- If a specific **layer number** dominates (e.g., layers 18-22), those are the layers where your dataset diverges most from the pre-trained weights.\n\n---\n\n## Module-Level vs Layer-Level Granularity\n\n| Granularity | `--granularity` | What It Ranks | When To Use |\n|-------------|-----------------|---------------|-------------|\n| Module | `module` (default) | Individual projections (`q_proj`, `k_proj`, etc.) | Fine-grained selection, small datasets, precise control |\n| Layer | `layer` | Entire attention blocks (`self_attn`, `cross_attn`) | Quick overview, large datasets, coarse selection |\n\n**Module-level** is almost always the better choice. It lets you pick exactly which projections to target. Layer-level is useful as a quick first pass to see which depth regions of the decoder are most active.\n\n---\n\n## Using Results for Training\n\n### Selecting Target Modules\n\nAfter estimation, the top-K modules tell you which projections to target. For example, if the top 8 modules are all `q_proj` and `v_proj` in layers 18-24:\n\n- You might set `--target-modules \"q_proj v_proj\"` (skip `k_proj` and `o_proj`)\n- Or focus rank on those specific layers\n\n### Practical Example\n\nSuppose estimation returns:\n\n```\n#1  decoder.layers.22.self_attn.q_proj   0.042\n#2  decoder.layers.22.self_attn.v_proj   0.039\n#3  decoder.layers.18.cross_attn.k_proj  0.035\n#4  decoder.layers.18.cross_attn.v_proj  0.033\n#5  decoder.layers.20.self_attn.q_proj   0.031\n...\n#12 decoder.layers.5.self_attn.o_proj    0.008\n#16 decoder.layers.2.cross_attn.k_proj   0.002\n```\n\n**What this tells you:**\n- Layers 18-22 are the most sensitive -- your dataset is \"different\" from the pre-trained model at those depths\n- Self-attention dominates -- the model wants to learn audio patterns more than text alignment\n- Layer 2 barely responds -- it's already general enough and doesn't need fine-tuning\n- `q_proj` and `v_proj` rank higher than `k_proj` and `o_proj` -- queries and values carry the signal\n\n**Action:** You could train with `--target-modules \"q_proj v_proj\"` and expect strong results even at lower rank, since you're focusing on what matters.\n\n---\n\n## Parameter Guide\n\n| Parameter | Default | Guidance |\n|-----------|---------|----------|\n| `--estimate-batches` | 5 | More batches = more stable ranking. 3-5 is enough for small datasets; 10+ for large/diverse ones. |\n| `--top-k` | 16 | How many modules to highlight. 8-16 is a good range. Beyond 32 you're training most of the model anyway. |\n| `--granularity` | `module` | Use `module` unless you want a quick layer-level overview first. |\n\n### VRAM Considerations\n\nEstimation loads the full model and runs forward + backward passes, similar to training. Budget the same VRAM you would for training:\n\n| GPU VRAM | Recommended `--estimate-batches` |\n|----------|----------------------------------|\n| 8 GB | 3 |\n| 12 GB | 5 |\n| 24 GB | 10 |\n| 48 GB | 10-20 |\n\nEstimation is fast -- typically 1-3 minutes regardless of batch count.\n\n---\n\n## See Also\n\n- [[Training Guide]] -- Full training workflow and hyperparameter guide\n- [[Model Management]] -- Checkpoint structure and model selection\n"
  },
  {
    "path": "docs/sidestep/Getting Started.md",
    "content": "## Prerequisites\n\n- **Python 3.11+**\n- **NVIDIA GPU with CUDA** (for training -- CPU/MPS are experimental)\n- **Git** (to clone the repositories)\n- **uv** (recommended) -- the fast Python package manager from Astral\n\n### Installing uv\n\n```bash\n# Linux / macOS\ncurl -LsSf https://astral.sh/uv/install.sh | sh\n\n# Windows (PowerShell)\nirm https://astral.sh/uv/install.ps1 | iex\n```\n\n---\n\n## Installation\n\n### Option 1: Windows Easy Install\n\n1. Clone Side-Step (or download as zip)\n2. Double-click `install_windows.bat`\n3. The script handles everything: uv, Python, ACE-Step, dependencies, model download\n\nThe installer creates two sibling folders:\n```\nyour-folder/\n  ACE-Step-1.5/     # Base repo (checkpoints, optional vanilla)\n  Side-Step/         # Your training toolkit\n```\n\n### Option 2: Manual Install (Linux / macOS / Windows)\n\n```bash\n# 1. Clone Side-Step\ngit clone https://github.com/koda-dernet/Side-Step.git\ncd Side-Step\n\n# 2. Install dependencies (includes PyTorch with CUDA)\nuv sync\n\n# 3. Launch -- first run triggers the setup wizard\nuv run python train.py\n```\n\n### Getting Model Checkpoints\n\nYou need the ACE-Step model weights before training. Two options:\n\n**Option A: Use ACE-Step's downloader**\n```bash\ngit clone https://github.com/ace-step/ACE-Step-1.5.git\ncd ACE-Step-1.5\nuv sync\nuv run acestep-download\n```\nThis downloads ~8 GB of weights into `ACE-Step-1.5/checkpoints/`.\n\n**Option B: Manual download from HuggingFace**\nGo to [HuggingFace ACE-Step](https://huggingface.co/ACE-Step/Ace-Step1.5) and download the model folders into a `checkpoints/` directory.\n\n> **IMPORTANT:** Never rename checkpoint folders. See [[Model Management]] for details.\n\n---\n\n## First-Run Setup\n\nWhen you run `python train.py` for the first time (without any arguments), the setup wizard activates:\n\n1. **Welcome + disclaimers** -- Reminds you about model weights and the no-rename rule\n2. **Vanilla intent** -- \"Do you plan to use Vanilla training mode?\"\n   - If **yes**: provide the path to your ACE-Step installation\n   - If **no**: corrected mode is fully standalone, no ACE-Step needed\n3. **Checkpoint directory** -- Where your model weights live (e.g., `../ACE-Step-1.5/checkpoints`)\n4. **Model scan** -- Lists all discovered models with official/custom labels\n\nSettings are saved to:\n- Linux/macOS: `~/.config/sidestep/settings.json`\n- Windows: `%APPDATA%\\sidestep\\settings.json`\n\nYou can re-run setup at any time from the main menu: **Settings (paths, vanilla mode)**.\n\n---\n\n## Included Automatically\n\nEverything is installed by `uv sync` -- no extras, no manual pip installs:\n\n- **Flash Attention 2** -- Prebuilt wheels, no compilation. Auto-detected on Ampere+ GPUs (RTX 30xx+). Falls back to SDPA on older hardware or macOS. See [[VRAM Optimization Guide]].\n- **Gradient checkpointing** -- Enabled by default. Cuts VRAM dramatically (~7 GiB for batch size 1, down from 20-42 GiB without it). See [[VRAM Optimization Guide]].\n- **PyTorch with CUDA 12.8** -- Correct CUDA-enabled build per platform.\n- **bitsandbytes** -- 8-bit optimizers (AdamW8bit) for ~30-40% optimizer VRAM savings.\n- **Prodigy** -- Adaptive optimizer that auto-tunes learning rate.\n- **LyCORIS** -- LoKR adapter support (experimental Kronecker product adapters).\n\n---\n\n## Next Steps\n\n- [[Model Management]] -- Understand checkpoint structure and fine-tune support\n- [[Training Guide]] -- Start training your first adapter\n- [[VRAM Optimization Guide]] -- VRAM optimizations, GPU profiles, and all wizard settings explained\n"
  },
  {
    "path": "docs/sidestep/Model Management.md",
    "content": "\n## Checkpoint Directory Structure\n\nACE-Step models are organized as subdirectories under a root `checkpoints/` folder. Each model variant has its own folder with a `config.json` and weight files:\n\n```text\ncheckpoints/\n  acestep-v15-turbo/     # Turbo (8-step accelerated)\n    config.json\n    modeling.py\n    model.safetensors\n    silence_latent.pt\n  acestep-v15-base/      # Base (full diffusion)\n    config.json\n    ...\n  acestep-v15-sft/       # SFT (supervised fine-tune)\n    config.json\n    ...\n  vae/                   # VAE encoder/decoder (shared)\n  Qwen3-Embedding-0.6B/  # Text encoder (shared)\n```\n\n### The Golden Rule: Never Rename Checkpoint Folders\n\nThe model loader uses `AutoModel.from_pretrained()` with `trust_remote_code=True`. This means:\n- The `config.json` tells HuggingFace Transformers which Python class to load\n- The `modeling.py` file in each folder defines the actual model architecture\n- Renaming folders breaks the loading mechanism\n\nIf you downloaded weights manually, make sure the folder names match what the model expects.\n\n---\n\n## Official vs Custom Models\n\nSide-Step's model discovery automatically classifies models:\n\n- **Official models**: Folder names starting with `acestep-v15-` (e.g., `acestep-v15-turbo`). These are auto-detected with correct timestep parameters.\n- **Custom models / fine-tunes**: Any other folder containing a `config.json`. Side-Step will ask which base model they descend from.\n\n### How Discovery Works\n\nWhen you start training or preprocessing, the wizard:\n1. Scans your checkpoint directory for subfolders with `config.json`\n2. Filters out non-model directories (VAE, text encoder, etc.)\n3. Labels each as official or custom\n4. Presents a numbered list for selection\n5. Offers fuzzy search if you have many models\n\nYou can also type a name (or part of one) to filter the list.\n\n---\n\n## Training on Fine-Tunes\n\nSide-Step supports training on community fine-tunes, not just the official turbo/base/sft.\n\n### Requirements\n\n1. **You MUST have the original base model** that the fine-tune was built from. The training loop needs it for correct timestep conditioning.\n2. **The fine-tune folder** must contain a valid `config.json` (same format as official models).\n3. **Do not rename** the fine-tune folder.\n\n### Wizard Flow\n\n1. The model picker lists your fine-tune alongside official models\n2. If the fine-tune's `config.json` doesn't specify `is_turbo` or timestep parameters, Side-Step asks: \"Which base model was this fine-tune trained from?\"\n3. Your answer conditions the training: turbo uses discrete scheduling, base/sft use continuous\n4. Training proceeds normally\n\n### CLI Flow\n\n```bash\nuv run python train.py fixed \\\n    --checkpoint-dir ./checkpoints \\\n    --model-variant my-custom-finetune \\\n    --base-model turbo \\\n    --dataset-dir ./my_tensors \\\n    --output-dir ./output/my_lora\n```\n\nThe `--model-variant` accepts any folder name under `--checkpoint-dir`.\nThe `--base-model` tells Side-Step which timestep parameters to use.\n\n---\n\n## Base Model Differences\n\nUnderstanding which base model you're working with matters for training quality:\n\n| Base | `is_turbo` | Timestep Sampling | CFG | Best For |\n|------|-----------|-------------------|-----|----------|\n| **Turbo** | Yes | Discrete (8-step) | Not trained with CFG | Fast generation, the original training script was built for this |\n| **Base** | No | Continuous (logit-normal) | Trained with CFG dropout | Full quality, benefits most from corrected training |\n| **SFT** | No | Continuous (logit-normal) | Trained with CFG dropout | Instruction-following generation |\n\nSide-Step's corrected (fixed) training mode uses continuous timestep sampling and CFG dropout -- matching how base and SFT models were actually trained. For turbo, the original discrete schedule is appropriate.\n\n---\n\n## Shared Components\n\nSome checkpoint directories are shared across all model variants:\n\n- **`vae/`** -- The audio VAE (AutoencoderOobleck). Encodes raw audio into latent space and decodes back.\n- **`Qwen3-Embedding-0.6B/`** -- The text encoder. Converts text prompts into embeddings for conditioning.\n- **`silence_latent.pt`** -- Pre-computed silence latent used for LoRA preprocessing context.\n\nThese are loaded separately during preprocessing and training. They don't need to be inside each model variant's folder.\n\n---\n\n## See Also\n\n- [[Getting Started]] -- Installation and first-run setup\n- [[Training Guide]] -- Start training adapters\n"
  },
  {
    "path": "docs/sidestep/ObsidianREADME.md",
    "content": "# Side-Step Guide\n\n> **Note:** This documentation accompanies the upstream-integrated version of Side-Step.\n> For the standalone version with additional features and more frequent updates,\n> visit: [github.com/koda-dernet/Side-Step](https://github.com/koda-dernet/Side-Step)\n\nWelcome to the Side-Step documentation. This guide covers training, preprocessing, and model management.\n\n## Pages\n\n- [[Getting Started]] -- Installation, first-run setup, prerequisites\n- [[End-to-End Tutorial]] -- Raw audio to generated music walkthrough\n- [[Dataset Preparation]] -- JSON schema, audio formats, metadata fields\n- [[Training Guide]] -- LoRA vs LoKR, corrected vs vanilla, wizard walkthrough, CLI examples\n- [[Using Your Adapter]] -- Output layout, loading in Gradio, LoKR limitations\n- [[Model Management]] -- Checkpoint structure, fine-tunes, the \"never rename\" rule\n- [[Preset Management]] -- Built-in presets, save/load/import/export\n- [[The Settings Wizard]] -- All wizard settings reference\n- [[VRAM Optimization Guide]] -- VRAM optimizations, GPU profiles\n- [[Estimation Guide]] -- Gradient sensitivity analysis for targeted training\n- [[Shift and Timestep Sampling]] -- How training timesteps work, what shift actually does, Side-Step vs upstream\n- [[Windows Notes]] -- num_workers, paths, installation, known workarounds\n\n## Quick Links\n\n- [Side-Step on GitHub](https://github.com/koda-dernet/Side-Step)\n- [ACE-Step 1.5 on GitHub](https://github.com/ace-step/ACE-Step-1.5)\n- [ACE-Step models on HuggingFace](https://huggingface.co/ACE-Step/Ace-Step1.5)\n\n## Version\n\nThis guide is for the **Side-Step upstream integration** into ACE-Step-1.5.\n"
  },
  {
    "path": "docs/sidestep/Preset Management.md",
    "content": "# Preset Management\n\nPresets are named JSON files containing training hyperparameters. They let you save, share, and reuse training configurations without re-entering every setting.\n\n---\n\n## What a Preset Contains\n\nA preset stores **38 training fields** covering adapter type, LoRA/LoKR settings, training hyperparameters, and VRAM-related options. It does **not** store:\n\n- File paths (checkpoint dir, dataset dir, output dir)\n- Device settings (GPU, precision)\n- Model-derived timestep parameters (`timestep_mu`, `timestep_sigma`)\n\nThis means presets are portable between machines and projects. When you load a preset, missing fields fall back to wizard defaults. Unknown fields are silently ignored.\n\n### Fields Included in Presets\n\n| Category | Fields |\n| :--- | :--- |\n| Adapter | `adapter_type` |\n| LoRA | `rank`, `alpha`, `dropout`, `target_modules_str`, `attention_type`, `bias` |\n| LoKR | `lokr_linear_dim`, `lokr_linear_alpha`, `lokr_factor`, `lokr_decompose_both`, `lokr_use_tucker`, `lokr_use_scalar`, `lokr_weight_decompose` |\n| Training | `learning_rate`, `batch_size`, `gradient_accumulation`, `epochs`, `warmup_steps`, `weight_decay`, `max_grad_norm`, `seed`, `shift`, `num_inference_steps`, `optimizer_type`, `scheduler_type`, `cfg_ratio` |\n| Checkpointing / Logging | `save_every`, `log_every`, `log_heavy_every`, `sample_every_n_epochs` |\n| VRAM | `gradient_checkpointing`, `offload_encoder` |\n\n---\n\n## Storage Locations\n\nPresets are stored in three locations, searched in this priority order:\n\n| Priority | Location | Platform | Purpose |\n| :--- | :--- | :--- | :--- |\n| 1 (highest) | `./presets/` | All | Project-local user presets. New saves go here. |\n| 2 | `~/.config/sidestep/presets/` | Linux/macOS | Global user presets (fallback). |\n| 2 | `%APPDATA%\\sidestep\\presets\\` | Windows | Global user presets (fallback). |\n| 3 (lowest) | `acestep/training_v2/presets/` | All | Built-in presets shipped with Side-Step. Read-only. |\n\n**Key behaviors:**\n\n- **Loading** searches local first, then global, then built-in. The first match wins.\n- **Saving** always writes to the local directory (`./presets/`).\n- **Deleting** can remove local or global presets. Built-in presets cannot be deleted.\n- A local preset with the same name as a built-in effectively overrides it.\n\nThe local directory is anchored to the Side-Step project root (found by looking for `train.py` or `pyproject.toml` + `acestep/`), so presets are always found regardless of your current working directory.\n\n---\n\n## Built-in Presets\n\nSide-Step ships with seven built-in presets:\n\n| Preset | Description | Key Settings |\n| :--- | :--- | :--- |\n| `recommended` | Balanced defaults for most LoRA fine-tuning tasks | Rank 64, alpha 128, 100 epochs, AdamW, cosine LR |\n| `quick_test` | Fast iteration for testing | Rank 16, alpha 32, 10 epochs |\n| `high_quality` | High capacity, long training | Rank 128, alpha 256, 1000 epochs |\n| `vram_24gb_plus` | Comfortable tier (RTX 3090, 4090, A100) | Rank 128, batch 2, grad accumulation 2, AdamW |\n| `vram_16gb` | Standard tier (RTX 4080, 3080 Ti) | Rank 64, batch 1, AdamW |\n| `vram_12gb` | Tight tier (RTX 3060 12GB, 4070) | Rank 32, AdamW8bit, encoder offloading |\n| `vram_8gb` | Minimal tier (RTX 4060 8GB, 3050, GTX 1080) | Rank 16, AdamW8bit, encoder offloading, high grad accumulation |\n\nAll built-in presets are configured for **turbo** models (`shift=3.0`, `num_inference_steps=8`). If training on a base or sft model, adjust these after loading the preset.\n\n---\n\n## Using Presets in the Wizard\n\n### Loading a Preset\n\nWhen starting a training flow in the wizard, Side-Step offers to load a preset before asking configuration questions. The preset values pre-fill the wizard prompts so you can accept defaults or modify individual settings.\n\n### Saving a Preset\n\nAfter configuring training, the wizard offers to save your current settings as a named preset. Enter a name and optional description. The preset is saved to `./presets/` as a JSON file.\n\n### Managing Presets\n\nFrom the wizard's main menu, select **Manage presets** to access the preset management submenu:\n\n- **List** -- Show all available presets (local, global, and built-in) with descriptions.\n- **View** -- Display the full contents of a preset.\n- **Delete** -- Remove a user preset (local or global). Built-in presets cannot be deleted.\n- **Import** -- Import a preset from an external JSON file into your local presets directory.\n- **Export** -- Export any preset (including built-ins) to a file path of your choice.\n\n---\n\n## Import and Export\n\n### Importing\n\nImport copies an external JSON file into your local presets directory (`./presets/`):\n\n- The file must be valid JSON and under 1 MB.\n- The preset name is taken from the `\"name\"` field in the JSON, or from the filename if no name field exists.\n- The name is sanitized for filesystem safety (see naming rules below).\n\n### Exporting\n\nExport copies any preset (local, global, or built-in) to a specified file path. This is useful for sharing presets with others or backing them up.\n\n### Naming Rules\n\nPreset names are sanitized to be safe filenames on all platforms:\n\n- Spaces are replaced with underscores.\n- The following characters are removed: `/\\:*?\"<>|`\n- Path traversal (`..`, leading `/` or `\\`) is rejected.\n- Windows reserved names (`CON`, `PRN`, `AUX`, `NUL`, `COM1`-`COM9`, `LPT1`-`LPT9`) are rejected.\n\n---\n\n## Preset JSON Format\n\nIf you want to create a preset by hand, here is the format:\n\n```json\n{\n  \"name\": \"my_preset\",\n  \"description\": \"My custom training configuration\",\n  \"adapter_type\": \"lora\",\n  \"rank\": 64,\n  \"alpha\": 128,\n  \"dropout\": 0.1,\n  \"target_modules_str\": \"q_proj k_proj v_proj o_proj\",\n  \"attention_type\": \"both\",\n  \"bias\": \"none\",\n  \"learning_rate\": 0.0001,\n  \"batch_size\": 1,\n  \"gradient_accumulation\": 4,\n  \"epochs\": 100,\n  \"warmup_steps\": 100,\n  \"weight_decay\": 0.01,\n  \"max_grad_norm\": 1.0,\n  \"seed\": 42,\n  \"shift\": 3.0,\n  \"num_inference_steps\": 8,\n  \"optimizer_type\": \"adamw\",\n  \"scheduler_type\": \"cosine\",\n  \"cfg_ratio\": 0.15,\n  \"save_every\": 10,\n  \"log_every\": 10,\n  \"log_heavy_every\": 50,\n  \"gradient_checkpointing\": true,\n  \"offload_encoder\": false,\n  \"sample_every_n_epochs\": 0\n}\n```\n\nYou do not need to include every field. Missing fields use wizard defaults. The `name` and `description` fields are metadata and not used during training.\n\n---\n\n## See Also\n\n- [[The Settings Wizard]] -- Full wizard settings reference\n- [[VRAM Optimization Guide]] -- GPU memory profiles and trade-offs\n- [[Training Guide]] -- Training options and hyperparameters\n"
  },
  {
    "path": "docs/sidestep/RepositoryREADME.md",
    "content": "# [BETA] Side-Step for ACE-Step 1.5\n\n```bash\n  ███████ ██ ██████  ███████       ███████ ████████ ███████ ██████\n  ██      ██ ██   ██ ██            ██         ██    ██      ██   ██\n  ███████ ██ ██   ██ █████   █████ ███████    ██    █████   ██████\n       ██ ██ ██   ██ ██                 ██    ██    ██      ██\n  ███████ ██ ██████  ███████       ███████    ██    ███████ ██\n  by dernet     ((BETA TESTING))\n```\n\n**Side-Step** is a **standalone** training toolkit for [ACE-Step 1.5](https://github.com/ace-step/ACE-Step-1.5) models. It provides corrected LoRA and LoKR fine-tuning implementations that fix fundamental bugs (for models other than turbo) in the original trainer while adding low-VRAM support for local GPUs.\n\n> **Standalone?** Yes. Side-Step installs as its own project with its own dependencies. The corrected (fixed) training loop, preprocessing, and wizard all work without a base ACE-Step installation -- you only need the model checkpoints. Vanilla training mode still requires base ACE-Step installed alongside.\n\n\n## Why Side-Step?\n\nThe original ACE-Step trainer has two critical discrepancies from how the base models were actually trained. Side-Step was built to bridge this gap:\n\n1.  **Continuous Timestep Sampling:** The original trainer uses a discrete 8-step schedule. This is fine for turbo, which the original training script is hardcoded for. Side-Step implements **Logit-Normal continuous sampling**, ensuring the model learns the full range of the denoising process.\n2.  **CFG Dropout (Classifier-Free Guidance):** The original trainer lacks condition dropout. Side-Step implements a **15% null-condition dropout**, teaching the model how to handle both prompted and unprompted generation. Without this, inference quality suffers.\n3.  **Standalone Core:** The corrected training loop, preprocessing, and wizard bundle all required ACE-Step utilities. No base ACE-Step install needed -- just the model weights.\n4.  **Built for the cloud:** The original Gradio breaks when you try to use it for training. Use this instead :)\n\n---\n\n## Beta Status & Support\n**Current Version:** 0.8.0-beta\n\n| Feature | Status | Standalone? | Note |\n| :--- | :--- | :--- | :--- |\n| **Fixed Training (LoRA)** | Working | Yes | Recommended for all users. Corrected timesteps + CFG dropout. |\n| **Fixed Training (LoKR)** | **Experimental** | Yes | Uses LyCORIS. May have rough edges. |\n| **Vanilla Training** | Working | **No** | Reproduction of original behavior. Requires base ACE-Step 1.5 installed alongside. |\n| **Interactive Wizard** | Working | Yes | `python train.py` with no args. Session loop, go-back, presets, first-run setup. |\n| **CLI Preprocessing** | Beta | Yes | Two-pass pipeline, low VRAM. Adapter-agnostic (same tensors for LoRA and LoKR). |\n| **Gradient Estimation** | Beta | Yes | Ranks attention modules by sensitivity. In Experimental menu. |\n| **Presets System** | Working | Yes | Save/load/manage training configurations. Stores adapter type. |\n| **TUI (Textual UI)** | **BROKEN** | -- | Do not use `sidestep_tui.py` yet. |\n\n> **Something broken?** This is a beta. You can always roll back:\n> ```bash\n> git log --oneline -5   # find the commit you want\n> git checkout <hash>\n> ```\n> If you hit issues, please open an issue -- it helps us stabilize faster.\n\n### What's new in 0.8.0-beta\n\n**Bug fixes:**\n- **Fixed gradient checkpointing crash** -- Training with gradient checkpointing enabled (the default) would crash with `element 0 of tensors does not require grad`. The autograd graph was disconnecting through checkpointed segments because the `xt` input tensor wasn't carrying gradients. Now forces `xt.requires_grad_(True)` when checkpointing is active, matching ACE-Step's upstream behavior. This was the #1 blocker for new users.\n- **Fixed training completing with 0 steps on Windows** -- Lightning Fabric's `setup_dataloaders()` was wrapping the DataLoader with a shim that yielded 0 batches on Windows, causing training to silently \"complete\" with 0 epochs and 0 steps. Reported by multiple users on RTX 3090 and other GPUs. The Fabric DataLoader wrapping is now skipped entirely (the model/optimizer are still Fabric-managed for mixed precision).\n- **Fixed multi-GPU device selection** -- Using `cuda:1` (or any non-default GPU) no longer causes training to silently fail. The Fabric device setup has been rewritten to use `torch.cuda.set_device()` instead of passing device indices as lists.\n- **LoRA save path fix** -- Adapter files (`adapter_config.json`, `adapter_model.safetensors`) are now saved directly into the output directory. Previously they were nested in an `adapter/` subdirectory, causing Gradio/ComfyUI to fail to find the weights at the path Side-Step reported.\n- **Massive VRAM reduction** -- Gradient checkpointing is now ON by default and actually works (see above fix). Measured at ~7 GiB for batch size 1 on a 48 GiB GPU (15% utilization). Previously Side-Step had checkpointing off or broken, causing 20-42 GiB VRAM usage. This brings Side-Step well below ACE-Step's memory footprint.\n- **0-step training detection** -- If training completes with zero steps processed, Side-Step now reports a clear `[FAIL]` error instead of a misleading \"Training Complete\" screen with 0 epochs.\n- **Windows `num_workers` safety** -- Explicitly clamps `num_workers=0` on Windows even if overridden via CLI, preventing spawn-based multiprocessing crashes.\n\n**Features:**\n- **Inference-ready checkpoints** -- Intermediate checkpoints (`checkpoints/epoch_N/`) now save adapter files flat alongside `training_state.pt`. Point any inference tool directly at a checkpoint directory -- no more digging into nested subdirectories. Checkpoints are usable for both inference AND resume.\n- **Resume support in basic training loop** -- The non-Fabric fallback loop now supports `--resume-from`, matching the Fabric path.\n- **VRAM-tier presets** -- Four new built-in presets (`vram_24gb_plus`, `vram_16gb`, `vram_12gb`, `vram_8gb`) with tuned settings for each GPU tier. Rank, optimizer, batch size, and offloading are pre-configured for your VRAM budget.\n- **Flash Attention 2 auto-installed** -- Prebuilt wheels are now a default dependency. No compilation, no `--extra flash`. Falls back to SDPA silently on unsupported hardware.\n- **Banner shows version** -- The startup banner now displays the Side-Step version for easier bug reporting.\n\n### What's new in 0.7.0-beta\n\n- **Truly standalone packaging** -- Side-Step is now its own project with a real `pyproject.toml` and full dependency list. Install it with `uv sync` -- no ACE-Step overlay required. The installer now creates Side-Step alongside ACE-Step as sibling directories.\n- **First-run setup wizard** -- On first launch, Side-Step walks you through configuring your checkpoint directory, ACE-Step path (if you want vanilla mode), and validates your setup. Accessible any time from the main menu under \"Settings\".\n- **Model discovery with fuzzy search** -- Instead of hardcoded `turbo/base/sft` choices, the wizard now scans your checkpoint directory for all model folders, labels official vs custom models, and lets you pick by number or search by name. Fine-tunes with arbitrary folder names are fully supported.\n- **Fine-tune training support** -- Train on custom fine-tunes by selecting their folder. Side-Step auto-detects the base model from `config.json`. If it can't, it asks which base the fine-tune descends from to condition timestep sampling correctly.\n- **`--base-model` CLI argument** -- New flag for CLI users training on fine-tunes. Overrides timestep parameters when `config.json` doesn't contain them.\n- **`--model-variant` accepts any folder name** -- No longer restricted to turbo/base/sft. Pass any subfolder name from your checkpoints directory (e.g., `--model-variant my-custom-finetune`).\n- **`acestep.__path__` extension** -- When vanilla mode is configured, Side-Step extends its package path to reach ACE-Step's modules. No overlay, no symlinks, no `sys.path` hacks.\n- **Settings persistence** -- Checkpoint dir, ACE-Step path, and vanilla intent are saved to `~/.config/sidestep/settings.json` and reused as defaults in subsequent sessions.\n\n### What's new in 0.6.0-beta\n\n- **Mostly standalone** -- The corrected (fixed) training loop, preprocessing pipeline, and wizard no longer require a base ACE-Step installation. All needed ACE-Step utilities are vendored in `_vendor/`. You only need the model checkpoint files. Vanilla training mode still requires base ACE-Step.\n- **Enhanced prompt builder** -- Preprocessing now supports `custom_tag`, `genre`, and `prompt_override` fields from dataset JSON metadata, matching upstream feature parity without the AudioSample dependency.\n- **Hardened metadata lookup** -- Dataset JSON entries with `audio_path` but no `filename` field are now handled correctly (basename is extracted as fallback key).\n\n### What's new in 0.5.0-beta\n\n- **LoKR adapter support (experimental)** -- Train LoKR (Low-Rank Kronecker) adapters via [LyCORIS](https://github.com/KohakuBlueleaf/LyCORIS) as an alternative to LoRA. LoKR uses Kronecker product factorization and may capture different patterns than LoRA. **This is experimental and may break.** The underlying LyCORIS + Fabric interaction has not been exhaustively tested across all hardware.\n- **Restructured wizard menu** -- The main menu now offers \"Train a LoRA\" and \"Train a LoKR\" as distinct top-level choices, each leading to a corrected/vanilla sub-menu\n- **Unified preprocessing** -- Preprocessing is adapter-agnostic: the same tensors work for both LoRA and LoKR. The adapter type only affects weight injection during training, not the data pipeline. *(Previously, LoKR had a separate preprocessing mode that incorrectly fed target audio into context latents, giving the decoder the answer during training and producing misleadingly low loss.)*\n- **LoKR-aware presets** -- Presets now save and restore adapter type and all LoKR-specific hyperparameters\n\n### What's new in 0.4.0-beta\n\n- **Session loop** -- the wizard no longer exits after each action; preprocess, train, and manage presets in one session\n- **Go-back navigation** -- type `b` at any prompt to return to the previous question\n- **Step indicators** -- `[Step 3/8] LoRA Settings` shows your progress through each flow\n- **Presets system** -- save, load, import, and export named training configurations\n- **Flow chaining** -- after preprocessing, the wizard offers to start training immediately\n- **Experimental submenu** -- gradient estimation and upcoming features live here\n- **GPU cleanup** -- memory is released between session loop iterations to prevent VRAM leaks\n- **Config summaries** -- preprocessing and estimation show a summary before starting\n- **Basic/Advanced mode** -- choose how many questions the training wizard asks\n\n---\n\n## Prerequisites\n\n- **Python 3.11+** -- Managed automatically by `uv`. If using pip, install Python 3.11 manually.\n- **NVIDIA GPU with CUDA support** -- CUDA 12.x recommended. AMD and Intel GPUs are not supported.\n- **8 GB+ VRAM** -- See [VRAM Profiles](#optimization--vram-profiles) for per-tier settings. Training is possible on 8 GB GPUs with aggressive optimization.\n- **Git** -- Required for cloning repositories and version management.\n- **uv** (recommended) or **pip** -- `uv` handles Python, PyTorch+CUDA, and all dependencies automatically. Plain pip requires manual PyTorch installation.\n\n---\n\n## Installation\n\nSide-Step is **partly standalone**: the corrected training loop, preprocessing, wizard, and all CLI tools work without a base ACE-Step installation. You only need the model checkpoint files. The only thing that requires ACE-Step installed alongside is **vanilla training mode** (which reproduces the original bugged behavior for backward compatibility).\n\nWe **strongly recommend** using [uv](https://docs.astral.sh/uv/) for dependency management -- it handles Python 3.11, PyTorch with CUDA, Flash Attention wheels, and all other dependencies automatically.\n\n### Windows (Easy Install)\n\nDownload or clone Side-Step, then double-click **`install_windows.bat`** (or run the PowerShell script). It handles everything: uv, Python 3.11, Side-Step deps, ACE-Step (alongside for checkpoints), and model download.\n\n```powershell\n# Or run from PowerShell directly:\ngit clone https://github.com/koda-dernet/Side-Step.git\ncd Side-Step\n.\\install_windows.ps1\n```\n\nThe installer creates two sibling directories:\n- `Side-Step/` -- your training toolkit (standalone)\n- `ACE-Step-1.5/` -- model checkpoints + optional vanilla mode\n\n### Linux / macOS (Recommended: uv)\n\n```bash\n# 1. Install uv if you don't have it\ncurl -LsSf https://astral.sh/uv/install.sh | sh\n\n# 2. Clone Side-Step\ngit clone https://github.com/koda-dernet/Side-Step.git\ncd Side-Step\n\n# 3. Install dependencies (includes PyTorch with CUDA + Flash Attention)\nuv sync\n\n# 4. First run will guide you through setup (checkpoint path, etc.)\nuv run python train.py\n```\n\n### Model Checkpoints\n\nYou need the model weights before you can train. Options:\n\n1. **From ACE-Step (recommended):** Clone ACE-Step 1.5 alongside Side-Step and use `acestep-download`:\n   ```bash\n   git clone https://github.com/ace-step/ACE-Step-1.5.git\n   cd ACE-Step-1.5 && uv sync && uv run acestep-download\n   ```\n   Then point Side-Step at the checkpoints folder on first run or via `--checkpoint-dir ../ACE-Step-1.5/checkpoints`.\n2. **Manual download:** Get the weights from [HuggingFace](https://huggingface.co/ACE-Step/Ace-Step1.5) and place them in a `checkpoints/` directory inside Side-Step.\n\n> **IMPORTANT: Never rename checkpoint folders.** The model loader uses folder names and `config.json` files to identify model variants (turbo, base, sft). Renaming them will break loading.\n\n### Vanilla Mode (optional -- requires ACE-Step)\n\nVanilla training mode reproduces the original ACE-Step training behavior (bugged discrete timesteps, no CFG dropout). Most users should use **fixed** mode instead. If you specifically need vanilla mode:\n\n```bash\n# Clone ACE-Step alongside Side-Step\ngit clone https://github.com/ace-step/ACE-Step-1.5.git\ncd ACE-Step-1.5 && uv sync && cd ..\n\n# On first run, Side-Step's setup wizard will ask if you want vanilla mode\n# and where your ACE-Step installation is.\n```\n\n> **Note:** With plain pip, you are responsible for installing the correct PyTorch version with CUDA support for your platform. This is the #1 source of \"it doesn't work\" issues. `uv sync` handles this automatically.\n\n### Included automatically\n\nEverything is installed by `uv sync` -- no extras, no manual pip installs:\n\n- **Flash Attention 2** -- Prebuilt wheels, no compilation. Auto-detected on Ampere+ GPUs (RTX 30xx+). Falls back to SDPA on older hardware or macOS.\n- **Gradient checkpointing** -- Enabled by default. Cuts VRAM dramatically (~7 GiB for batch size 1, down from 20-42 GiB without it).\n- **PyTorch with CUDA 12.8** -- Correct CUDA-enabled build per platform.\n- **bitsandbytes** -- 8-bit optimizers (AdamW8bit) for ~30-40% optimizer VRAM savings.\n- **Prodigy** -- Adaptive optimizer that auto-tunes learning rate.\n- **LyCORIS** -- LoKR adapter support (experimental Kronecker product adapters).\n\n---\n\n## Platform Compatibility\n\n| Platform | Status | Notes |\n| :--- | :--- | :--- |\n| **Linux (CUDA)** | Primary | Developed and tested here |\n| **Windows (CUDA)** | Supported | Easy installer included; DataLoader workers auto-set to 0 |\n| **macOS (MPS)** | Experimental | Apple Silicon only; some ops may fall back to CPU |\n\n---\n\n## Usage\n\n### Option A: The Interactive Wizard (Recommended)\nSimply run the script with no arguments. The wizard now stays open in a session loop -- you can preprocess, configure, train, and manage presets without restarting.\n```bash\n# With uv (recommended)\nuv run python train.py\n\n# Without uv\npython train.py\n```\n\nThe wizard supports:\n- **Go-back**: Type `b` at any prompt to return to the previous question\n- **Presets**: Save and load named training configurations\n- **Flow chaining**: After preprocessing, jump straight to training\n- **Basic/Advanced modes**: Choose how detailed you want the configuration\n\n### Option B: The Quick Start One-Liner\nIf you have your preprocessed tensors ready in `./my_data`, run:\n```bash\n# LoRA (default)\nuv run python train.py fixed \\\n    --checkpoint-dir ./checkpoints \\\n    --model-variant turbo \\\n    --dataset-dir ./my_data \\\n    --output-dir ./output/my_lora \\\n    --epochs 100\n\n# LoKR (experimental)\nuv run python train.py fixed \\\n    --checkpoint-dir ./checkpoints \\\n    --model-variant turbo \\\n    --adapter-type lokr \\\n    --dataset-dir ./my_data \\\n    --output-dir ./output/my_lokr \\\n    --epochs 100\n```\n\n### Option C: Preprocess Audio (Two-Pass, Low VRAM)\nConvert raw audio files into `.pt` tensors without loading all models at once.\nThe pipeline runs in two passes: (1) VAE + Text Encoder (~3 GB), then (2) DIT encoder (~6 GB).\n```bash\nuv run python train.py fixed \\\n    --checkpoint-dir ./checkpoints \\\n    --model-variant turbo \\\n    --preprocess \\\n    --audio-dir ./my_audio \\\n    --tensor-output ./my_tensors\n```\nWith a metadata JSON for lyrics/genre/BPM:\n```bash\nuv run python train.py fixed \\\n    --checkpoint-dir ./checkpoints \\\n    --preprocess \\\n    --audio-dir ./my_audio \\\n    --dataset-json ./my_dataset.json \\\n    --tensor-output ./my_tensors\n```\n\n### Option D: Gradient Estimation\nFind which attention modules learn fastest for your dataset (useful for rank/target selection):\n```bash\nuv run python train.py estimate \\\n    --checkpoint-dir ./checkpoints \\\n    --model-variant turbo \\\n    --dataset-dir ./my_tensors \\\n    --estimate-batches 5 \\\n    --top-k 16\n```\n\n### Option E: Vanilla Training (Requires ACE-Step)\nReproduces the original ACE-Step training behavior (bugged discrete timesteps, no CFG dropout). Most users should use **fixed** mode instead. Requires a base ACE-Step installation alongside Side-Step:\n```bash\nuv run python train.py vanilla \\\n    --checkpoint-dir ./ACE-Step-1.5/checkpoints \\\n    --audio-dir ./my_audio \\\n    --output-dir ./output/my_vanilla_lora\n```\n\n> **Advanced subcommands:** `selective` (corrected training with dataset-specific module selection) and `compare-configs` (compare module config JSON files) are also available. These are advanced/WIP features -- run `uv run train.py selective --help` or `uv run train.py compare-configs --help` for details.\n\n---\n\n## Presets\n\nSide-Step ships with seven built-in presets:\n\n| Preset | Description |\n| :--- | :--- |\n| `recommended` | Balanced defaults for most LoRA fine-tuning tasks |\n| `high_quality` | Rank 128, 1000 epochs -- for when quality matters most |\n| `quick_test` | Rank 16, 10 epochs -- fast iteration for testing |\n| `vram_24gb_plus` | Comfortable tier -- Rank 128, Batch 2, AdamW |\n| `vram_16gb` | Standard tier -- Rank 64, Batch 1, AdamW |\n| `vram_12gb` | Tight tier -- Rank 32, AdamW8bit, Encoder offloading |\n| `vram_8gb` | Minimal tier -- Rank 16, AdamW8bit, Encoder offloading, High grad accumulation |\n\nUser presets are saved to `./presets/` (project-local, next to your training data). This ensures presets persist across Docker runs and stay visible alongside your project. Presets from the global location (`~/.config/sidestep/presets/`) are also scanned as a fallback. You can import/export presets as JSON files to share with others.\n\n---\n\n## Optimization & VRAM Profiles\nSide-Step is optimized for both heavy Cloud GPUs (H100/A100) and local \"underpowered\" gear (RTX 3060/4070).\n\n**Applied automatically (no configuration needed):**\n- **Gradient checkpointing** (ON by default) -- recomputes activations during backward, saves ~40-60% activation VRAM. This matches the original ACE-Step behavior.\n- **Flash Attention 2** (auto-installed) -- fused attention kernels for better GPU utilization. Requires Ampere+ GPU (RTX 30xx+). Falls back to SDPA on older hardware.\n\n| Profile | VRAM | Key Settings |\n| :--- | :--- | :--- |\n| **Comfortable** | 24 GB+ | AdamW, Batch 2+, Rank 64-128 |\n| **Standard** | 16-24 GB | AdamW, Batch 1, Rank 64 |\n| **Tight** | 10-16 GB | **AdamW8bit**, Encoder Offloading, Rank 32-64 |\n| **Minimal** | <10 GB | **AdaFactor** or **AdamW8bit**, Encoder Offloading, Rank 16, High Grad Accumulation |\n\n### Additional VRAM Options (Advanced mode):\n*   **`--offload-encoder`**: Moves the heavy VAE and Text Encoders to CPU after setup. Frees ~2-4 GB VRAM.\n*   **`--no-gradient-checkpointing`**: Disable gradient checkpointing for max speed if you have VRAM to spare.\n*   **`--optimizer-type prodigy`**: Uses the Prodigy optimizer to automatically find the best learning rate for you.\n\n---\n\n## Project Structure\n```text\nSide-Step/                       <-- Standalone project root\n├── train.py                     <-- Your main entry point\n├── pyproject.toml               <-- Dependencies (uv sync installs everything)\n├── requirements-sidestep.txt    <-- Fallback for plain pip\n├── install_windows.bat          <-- Windows easy installer (double-click)\n├── install_windows.ps1          <-- PowerShell installer script\n└── acestep/\n    └── training_v2/             <-- Side-Step logic (all standalone)\n        ├── trainer_fixed.py     <-- The corrected training loop\n        ├── preprocess.py        <-- Two-pass preprocessing pipeline\n        ├── estimate.py          <-- Gradient sensitivity estimation\n        ├── model_loader.py      <-- Per-component model loading (supports fine-tunes)\n        ├── model_discovery.py   <-- Checkpoint scanning & fuzzy search\n        ├── settings.py          <-- Persistent user settings (~/.config/sidestep/)\n        ├── _compat.py           <-- Version pin & compatibility check\n        ├── optim.py             <-- 8-bit and adaptive optimizers\n        ├── _vendor/             <-- Vendored ACE-Step utilities (standalone)\n        ├── presets/             <-- Built-in preset JSON files\n        ├── cli/                 <-- CLI argument parsing & dispatch\n        └── ui/                  <-- Wizard, flows, setup, presets, visual logic\n```\n\n---\n## Complete Argument Reference\n\nEvery argument, its default, and what it does.\n\n### Global Flags\n\nAvailable in: all subcommands (placed **before** the subcommand name)\n\n| Argument | Default | Description |\n|----------|---------|-------------|\n| `--plain` | `False` | Disable Rich output; use plain text. Also set automatically when stdout is piped |\n| `--yes` or `-y` | `False` | Skip the confirmation prompt and start training immediately |\n\n### Model and Paths\n\nAvailable in: vanilla, fixed\n\n| Argument | Default | Description |\n|----------|---------|-------------|\n| `--checkpoint-dir` | **(required)** | Path to the root checkpoints directory (contains `acestep-v15-turbo/`, etc.) |\n| `--model-variant` | `turbo` | Model variant or subfolder name. Official: `turbo`, `base`, `sft`. For fine-tunes: use the exact folder name (e.g., `my-custom-finetune`) |\n| `--base-model` | *(auto)* | Base model a fine-tune was trained from: `turbo`, `base`, or `sft`. Auto-detected for official models. Only needed for custom fine-tunes whose `config.json` lacks timestep parameters |\n| `--dataset-dir` | **(required)** | Directory containing your preprocessed `.pt` tensor files and `manifest.json` |\n\n### Device and Precision\n\nAvailable in: all subcommands\n\n| Argument | Default | Description |\n|----------|---------|-------------|\n| `--device` | `auto` | Which device to train on. Options: `auto`, `cuda`, `cuda:0`, `cuda:1`, `mps`, `xpu`, `cpu`. Auto-detection priority: CUDA > MPS (Apple Silicon) > XPU (Intel) > CPU |\n| `--precision` | `auto` | Floating point precision. Options: `auto`, `bf16`, `fp16`, `fp32`. Auto picks: bf16 on CUDA/XPU, fp16 on MPS, fp32 on CPU |\n\n### Adapter Selection\n\nAvailable in: vanilla, fixed\n\n| Argument | Default | Description |\n|----------|---------|-------------|\n| `--adapter-type` | `lora` | Adapter type: `lora` (PEFT, stable) or `lokr` (LyCORIS, experimental). LoKR uses Kronecker product factorization |\n\n### LoRA Settings (used when --adapter-type=lora)\n\nAvailable in: vanilla, fixed\n\n| Argument | Default | Description |\n|----------|---------|-------------|\n| `--rank` or `-r` | `64` | LoRA rank. Higher = more capacity and more VRAM. Recommended: 64 (ACE-Step dev recommendation) |\n| `--alpha` | `128` | LoRA scaling factor. Controls how strongly the adapter affects the model. Usually 2x the rank. Recommended: 128 |\n| `--dropout` | `0.1` | Dropout probability on LoRA layers. Helps prevent overfitting. Range: 0.0 to 0.5 |\n| `--attention-type` | `both` | Which attention layers to target. Options: `both` (self + cross attention, 192 modules), `self` (self-attention only, audio patterns, 96 modules), `cross` (cross-attention only, text conditioning, 96 modules) |\n| `--target-modules` | `q_proj k_proj v_proj o_proj` | Which projection layers get adapters. Space-separated list. Combined with `--attention-type` to determine final target modules |\n| `--bias` | `none` | Whether to train bias parameters. Options: `none` (no bias training), `all` (train all biases), `lora_only` (only biases in LoRA layers) |\n\n### LoKR Settings (used when --adapter-type=lokr) -- Experimental\n\nAvailable in: vanilla, fixed.\n\n| Argument | Default | Description |\n|----------|---------|-------------|\n| `--lokr-linear-dim` | `64` | LoKR linear dimension (analogous to LoRA rank) |\n| `--lokr-linear-alpha` | `128` | LoKR linear alpha (scaling factor, analogous to LoRA alpha) |\n| `--lokr-factor` | `-1` | Kronecker factorization factor. -1 = automatic |\n| `--lokr-decompose-both` | `False` | Decompose both Kronecker factors for additional compression |\n| `--lokr-use-tucker` | `False` | Use Tucker decomposition for more efficient factorization |\n| `--lokr-use-scalar` | `False` | Use scalar scaling |\n| `--lokr-weight-decompose` | `False` | Enable DoRA-style weight decomposition |\n\n### Training Hyperparameters\n\nAvailable in: vanilla, fixed\n\n| Argument | Default | Description |\n|----------|---------|-------------|\n| `--lr` or `--learning-rate` | `0.0001` | Initial learning rate. For Prodigy optimizer, set to `1.0` |\n| `--batch-size` | `1` | Number of samples per training step. Usually 1 for music generation (audio tensors are large) |\n| `--gradient-accumulation` | `4` | Number of steps to accumulate gradients before updating weights. Effective batch size = batch-size x gradient-accumulation |\n| `--epochs` | `100` | Maximum number of training epochs (full passes through the dataset) |\n| `--warmup-steps` | `100` | Number of optimizer steps where the learning rate ramps up from 10% to 100% |\n| `--weight-decay` | `0.01` | Weight decay (L2 regularization). Helps prevent overfitting |\n| `--max-grad-norm` | `1.0` | Maximum gradient norm for gradient clipping. Prevents training instability from large gradients |\n| `--seed` | `42` | Random seed for reproducibility. Same seed + same data = same results |\n| `--shift` | `3.0` | Noise schedule shift for inference. Turbo=`3.0`, base/sft=`1.0`. Stored as metadata -- does not affect the training loop (see [Technical Notes](#technical-notes-shift-and-timestep-sampling)) |\n| `--num-inference-steps` | `8` | Denoising steps for inference. Turbo=`8`, base/sft=`50`. Stored as metadata -- does not affect the training loop |\n| `--optimizer-type` | `adamw` | Optimizer: `adamw`, `adamw8bit` (saves VRAM), `adafactor` (minimal state), `prodigy` (auto-tunes LR) |\n| `--scheduler-type` | `cosine` | LR schedule: `cosine`, `cosine_restarts`, `linear`, `constant`, `constant_with_warmup`. Prodigy auto-forces `constant` |\n| `--gradient-checkpointing` | `True` | Recompute activations during backward to save VRAM (~40-60% less activation memory, ~10-30% slower). On by default; use `--no-gradient-checkpointing` to disable |\n| `--offload-encoder` | `False` | Move encoder/VAE to CPU after setup. Frees ~2-4GB VRAM with minimal speed impact |\n\n### Corrected Training (fixed mode only)\n\nAvailable in: fixed\n\n| Argument | Default | Description |\n|----------|---------|-------------|\n| `--cfg-ratio` | `0.15` | Classifier-free guidance dropout rate. With this probability, each sample's condition is replaced with a null embedding during training. This teaches the model to work both with and without text prompts. The model was originally trained with 0.15 |\n\n### Data Loading\n\nAvailable in: vanilla, fixed\n\n| Argument | Default | Description |\n|----------|---------|-------------|\n| `--num-workers` | `4` (Linux), `0` (Windows) | Number of parallel data loading worker processes. Auto-set to 0 on Windows |\n| `--pin-memory` / `--no-pin-memory` | `True` | Pin loaded tensors in CPU memory for faster GPU transfer. Disable if you're low on RAM |\n| `--prefetch-factor` | `2` | Number of batches each worker prefetches in advance |\n| `--persistent-workers` / `--no-persistent-workers` | `True` | Keep data loading workers alive between epochs instead of respawning them |\n\n### Checkpointing\n\nAvailable in: vanilla, fixed\n\n| Argument | Default | Description |\n|----------|---------|-------------|\n| `--output-dir` | **(required)** | Directory where LoRA weights, checkpoints, and TensorBoard logs are saved |\n| `--save-every` | `10` | Save a full checkpoint (LoRA weights + optimizer + scheduler state) every N epochs |\n| `--resume-from` | *(none)* | Path to a checkpoint directory to resume training from. Restores LoRA weights, optimizer state, and scheduler state |\n\n### Logging and Monitoring\n\nAvailable in: vanilla, fixed\n\n| Argument | Default | Description |\n|----------|---------|-------------|\n| `--log-dir` | `{output-dir}/runs` | Directory for TensorBoard log files. View with `tensorboard --logdir <path>` |\n| `--log-every` | `10` | Log loss and learning rate every N optimizer steps |\n| `--log-heavy-every` | `50` | Log per-layer gradient norms every N optimizer steps. These are more expensive to compute but useful for debugging |\n| `--sample-every-n-epochs` | `0` | Generate an audio sample every N epochs during training. 0 = disabled. (Not yet implemented) |\n\n> **Log file:** All runs automatically append to `sidestep.log` in the working directory. This file captures full tracebacks and debug-level messages that may not appear in the terminal. Useful for diagnosing silent crashes or sharing logs when reporting issues.\n\n### Preprocessing (optional)\n\nAvailable in: vanilla, fixed\n\n| Argument | Default | Description |\n|----------|---------|-------------|\n| `--preprocess` | `False` (flag) | If set, run audio preprocessing before training |\n| `--audio-dir` | *(none)* | Source directory containing audio files (for preprocessing) |\n| `--dataset-json` | *(none)* | Path to labeled dataset JSON file (for preprocessing) |\n| `--tensor-output` | *(none)* | Output directory where preprocessed .pt tensor files will be saved |\n| `--max-duration` | `240` | Maximum audio duration in seconds. Longer files are truncated |\n\n---\n\n## Technical Notes: Shift and Timestep Sampling\n\n> **Important:** The `--shift` and `--num-inference-steps` settings are **inference metadata only**. They are saved alongside your adapter so you know which values to use when generating audio with the trained LoRA/LoKR. **They do not enter the training loop.**\n\n### How Side-Step trains (corrected/fixed mode)\n\nSide-Step's corrected training loop uses **continuous logit-normal timestep sampling** -- an exact reimplementation of the `sample_t_r()` function defined inside each ACE-Step model variant's own `forward()` method. The core operation is:\n\n```python\nt = sigmoid(N(timestep_mu, timestep_sigma))\n```\n\nThe `timestep_mu` and `timestep_sigma` parameters are read automatically from each model's `config.json` at startup. All three model variants (turbo, base, sft) define the same `sample_t_r()` function and call it the same way during their native training forward pass. Our `sample_timesteps()` matches this line-for-line.\n\n### How the upstream community trainer trains\n\nThe original ACE-Step community trainer (`acestep/training/trainer.py`) uses a **discrete 8-step schedule** hardcoded from `shift=3.0`:\n\n```python\nTURBO_SHIFT3_TIMESTEPS = [1.0, 0.955, 0.9, 0.833, 0.75, 0.643, 0.5, 0.3]\n```\n\nEach training step randomly picks one of these 8 values. This is **not** how the models were originally trained -- it only approximates the turbo model's inference schedule. For base and sft models, this schedule is wrong entirely.\n\n### Where shift actually matters\n\n`shift` controls the **inference** timestep schedule via `t_shifted = shift * t / (1 + (shift - 1) * t)`. This warp is applied inside `generate_audio()`, not during training. With `shift=1.0` you get a uniform linear schedule (more steps needed); with `shift=3.0` the schedule compresses toward the high end (fewer steps needed -- that's what makes turbo fast).\n\n### Why this matters\n\n- **Side-Step can train all variants** (turbo, base, sft) because it uses the same continuous sampling the models expect.\n- **The upstream trainer only works properly for turbo** because its discrete schedule is derived from `shift=3.0`.\n- **Changing `--shift` in Side-Step will not change your training results** -- the training timestep distribution is controlled by `timestep_mu` and `timestep_sigma` from the model config, which Side-Step reads automatically.\n- **You still need the correct shift at inference time.** Use `shift=3.0` for turbo LoRAs and `shift=1.0` for base/sft LoRAs when generating audio.\n\n---\n\n## Contributing\nContributions are welcome! Specifically looking for help fixing the **Textual TUI** and testing the new preprocessing + estimation modules.\n\n**License:** Follows the original ACE-Step 1.5 licensing\n"
  },
  {
    "path": "docs/sidestep/Shift and Timestep Sampling.md",
    "content": "\nThis page explains how timestep sampling works during training, what the `shift` parameter actually does, and why Side-Step's approach differs from the upstream community trainer.\n\n> **TL;DR:** `shift` is an **inference-only** parameter. It does not affect the training loop. Side-Step's corrected training uses the same continuous timestep sampling as the model's own `forward()` method. The `--shift` and `--num-inference-steps` settings are stored as metadata so you know what values to use when generating audio with your trained adapter.\n\n---\n\n## What shift does (inference only)\n\nDuring **inference** (audio generation), `shift` warps the timestep schedule used by the diffusion ODE/SDE solver:\n\n```\nt_shifted = shift * t / (1 + (shift - 1) * t)\n```\n\nThis formula appears in `generate_audio()` inside each model variant. It controls how denoising steps are distributed:\n\n- **shift=1.0** -- Uniform linear schedule. Steps are evenly spaced from 1.0 to 0.0. This is the standard schedule and requires more steps (typically 50) for good quality. Used by **base** and **sft** models.\n- **shift=3.0** -- Compressed schedule. More denoising happens at the high end (near t=1.0), less at the low end. This allows fewer steps (typically 8) with minimal quality loss. Used by **turbo** models.\n\nThe turbo model also has pre-computed discrete timestep tables for each shift value:\n\n| Shift | 8-step schedule |\n|-------|----------------|\n| 1.0 | `[1.0, 0.875, 0.75, 0.625, 0.5, 0.375, 0.25, 0.125]` |\n| 2.0 | `[1.0, 0.933, 0.857, 0.769, 0.667, 0.545, 0.4, 0.222]` |\n| 3.0 | `[1.0, 0.955, 0.9, 0.833, 0.75, 0.643, 0.5, 0.3]` |\n\n---\n\n## What controls training timesteps\n\nDuring **training**, timesteps are sampled from a continuous distribution. All three ACE-Step model variants (turbo, base, sft) define the same `sample_t_r()` function in their model code:\n\n```python\ndef sample_t_r(batch_size, device, dtype, data_proportion, timestep_mu, timestep_sigma, use_meanflow):\n    t = torch.sigmoid(torch.randn((batch_size,)) * timestep_sigma + timestep_mu)\n    r = torch.sigmoid(torch.randn((batch_size,)) * timestep_sigma + timestep_mu)\n    t, r = torch.maximum(t, r), torch.minimum(t, r)\n    # use_meanflow=False during training -> r = t for all samples\n    ...\n    return t, r\n```\n\nThis is **logit-normal sampling**: draw from a normal distribution, then pass through a sigmoid to get values in (0, 1). The shape of this distribution is controlled by two parameters from the model's `config.json`:\n\n| Parameter | Typical value | Effect |\n|-----------|--------------|--------|\n| `timestep_mu` | `-0.4` | Shifts the distribution center. Negative values bias toward lower timesteps |\n| `timestep_sigma` | `1.0` | Controls spread. Larger values give a wider range of timesteps |\n\nSide-Step reads these automatically from each model's `config.json` at startup. You never need to set them manually.\n\n---\n\n## Side-Step vs upstream (vanilla) trainer\n\n### Side-Step corrected training (fixed mode)\n\nSide-Step's `sample_timesteps()` function (in `timestep_sampling.py`) is a **line-for-line reimplementation** of the model's own `sample_t_r()`:\n\n```python\n# Side-Step (timestep_sampling.py)\nt = torch.sigmoid(\n    torch.randn((batch_size,), device=device, dtype=dtype) * timestep_sigma + timestep_mu\n)\n```\n\nThis matches the model's native training `forward()` method exactly, for all three variants. The parameters come from each model's `config.json`.\n\n**Result:** Side-Step can correctly train adapters for turbo, base, and sft models because it uses the same timestep distribution the models were originally trained with.\n\n### Upstream community trainer\n\nThe original ACE-Step community trainer (`acestep/training/trainer.py`) uses a **different approach** -- discrete timesteps hardcoded from `shift=3.0`:\n\n```python\n# Upstream trainer (trainer.py)\nTURBO_SHIFT3_TIMESTEPS = [1.0, 0.955, 0.9, 0.833, 0.75, 0.643, 0.5, 0.3]\n\ndef sample_discrete_timestep(bsz, timesteps_tensor):\n    indices = torch.randint(0, timesteps_tensor.shape[0], (bsz,))\n    t = timesteps_tensor[indices]\n    return t, t\n```\n\nEach training step uniformly picks one of those 8 discrete values. This approach:\n\n1. **Does not match how the models were actually trained.** The models use continuous logit-normal sampling, not discrete uniform sampling.\n2. **Is hardcoded for turbo.** Those specific timestep values come from `shift=3.0` with 8 steps. For base or sft models (which use `shift=1.0` and more steps), this schedule is incorrect.\n3. **Samples from a fundamentally different distribution.** Uniform over 8 points vs. continuous logit-normal over the full (0, 1) range.\n\n---\n\n## What the shift setting does in Side-Step\n\nWhen you set `--shift` or configure shift in the wizard, Side-Step:\n\n1. **Saves it to the training config JSON** alongside your adapter weights\n2. **Does NOT use it during training** -- the training timestep distribution is entirely controlled by `timestep_mu` and `timestep_sigma` from the model config\n\nThe value is stored so that you (and anyone you share your adapter with) know what shift value to use at **inference time** when generating audio with the trained LoRA/LoKR.\n\n### Recommended values\n\n| Model variant | `--shift` | `--num-inference-steps` |\n|--------------|-----------|------------------------|\n| Turbo | `3.0` | `8` |\n| Base | `1.0` | `50` |\n| SFT | `1.0` | `50` |\n\nThe wizard auto-detects these from the model you select.\n\n---\n\n## FAQ\n\n**Q: I changed `--shift` and my training results didn't change. Is this a bug?**\nNo. Shift does not affect training. The training timestep distribution comes from the model's own `timestep_mu`/`timestep_sigma` parameters, which Side-Step reads automatically.\n\n**Q: If shift doesn't affect training, why is it a setting?**\nIt's metadata. When you finish training and want to generate audio with your LoRA, you need to know the correct shift value. Storing it with the adapter config prevents guesswork.\n\n**Q: Can I train a turbo model and use it with shift=1.0 at inference?**\nTechnically yes, but the quality will differ from what the model expects. Also, i don't think it is fully supported by upstream. Use the shift value that matches the model variant you trained on.\n\n**Q: Why does the upstream trainer use discrete timesteps?**\nThe upstream community trainer was written specifically for the turbo model. It takes the 8 discrete timestep values from the turbo inference schedule and samples uniformly from them. This is a reasonable approximation for turbo but does not match the model's actual training distribution, and it does not work for base or sft models.\n\n---\n\n## Source references\n\nThese are the relevant source locations for anyone who wants to verify:\n\n- **Model's native training sampling:** `sample_t_r()` in `modeling_acestep_v15_turbo.py` (lines 169-194), `modeling_acestep_v15_base.py` (same), `sft/modeling_acestep_v15_base.py` (same)\n- **Model's inference shift warp:** `generate_audio()` in each model file, applies `t = shift * t / (1 + (shift - 1) * t)`\n- **Side-Step's corrected sampling:** `sample_timesteps()` in `acestep/training_v2/timestep_sampling.py`\n- **Upstream discrete sampling:** `sample_discrete_timestep()` in `acestep/training/trainer.py` (lines 302-323)\n\n---\n\n## See Also\n\n- [[Training Guide]] -- Training modes, hyperparameters, and monitoring\n- [[The Settings Wizard]] -- All wizard settings explained\n- [[VRAM Optimization Guide]] -- GPU tiers and memory management\n"
  },
  {
    "path": "docs/sidestep/The Settings Wizard.md",
    "content": "\n## Wizard Settings Reference\n\nThe wizard has two modes: **Basic** (fewer questions, good defaults) and **Advanced** (all settings exposed). Basic mode settings are shown to everyone. Advanced settings appear only when you select \"Advanced\" at the start.\n\n### Basic Mode Settings\n\nThese are always shown regardless of mode.\n\n#### Required Settings\n\n| Setting | Default | What it does | Why you'd change it |\n|---|---|---|---|\n| Checkpoint directory | From settings or `./checkpoints` | Where model weights live | Point to your ACE-Step checkout or custom weights |\n| Model | Interactive picker | Which model variant to train on | Pick base, turbo, sft, or a community fine-tune |\n| Dataset directory | *(none)* | Folder with preprocessed `.pt` files | Always required -- your training data |\n| Output directory | *(none)* | Where adapter weights and logs are saved | Always required -- pick a descriptive name |\n\n#### LoRA Settings\n\n| Setting | Default | What it does | Why you'd change it |\n|---|---|---|---|\n| Rank | `64` | Number of low-rank dimensions. Higher = more capacity, more VRAM | Lower for quick tests (16), higher for max quality (128). See [[Training Guide]] |\n| Alpha | `128` | Scaling factor (usually 2x rank). Controls adapter strength | Keep at 2x rank unless experimenting |\n| Dropout | `0.1` | Dropout on LoRA layers. Prevents overfitting | Increase (0.2-0.3) for very small datasets, decrease (0.05) for large ones |\n| Attention type | `both` | Which attention layers get adapters: self, cross, or both | `self` = audio patterns only, `cross` = text conditioning only. See [[Estimation Guide]] to decide |\n| Target projections | `q_proj k_proj v_proj o_proj` | Which projections inside each attention block | Use [[Estimation Guide]] results to narrow this down |\n\n#### LoKR Settings (when training LoKR)\n\n| Setting | Default | What it does | Why you'd change it |\n|---|---|---|---|\n| Linear dimension | `64` | Analogous to LoRA rank | Same guidance as LoRA rank |\n| Linear alpha | `128` | Scaling factor | Keep at 2x linear dim |\n| Factor | `-1` | Kronecker factorization factor (-1 = auto) | Leave at auto unless you understand Kronecker factorization |\n| Decompose both | `no` | Decompose both Kronecker factors | May improve compression at the cost of capacity |\n| Tucker decomposition | `no` | Use Tucker decomposition | Alternative factorization -- experimental |\n| Scalar scaling | `no` | Use scalar scaling | Experimental |\n| DoRA weight decompose | `no` | DoRA-style weight decomposition | Can improve quality in some cases |\n| Attention type | `both` | Same as LoRA | Same guidance |\n| Target projections | `q_proj k_proj v_proj o_proj` | Same as LoRA | Same guidance |\n\n#### Training Settings\n\n| Setting | Default | What it does | Why you'd change it |\n|---|---|---|---|\n| Learning rate | `1e-4` | How fast the optimizer moves. **For Prodigy, set to 1.0** | Lower (5e-5) for stability, higher (2e-4) for faster convergence |\n| Batch size | `1` | Samples per step | Increase only if you have VRAM to spare |\n| Gradient accumulation | `4` | Steps before weight update. Effective batch = batch_size x this | Higher for smoother gradients, lower for faster updates |\n| Max epochs | `100` | Full passes through the dataset | More for small datasets (200-500), fewer for large (50-100) |\n| Warmup steps | `100` | LR ramps from 10% to 100% over this many steps | Longer warmup (200+) for stability with large LR |\n| Seed | `42` | Random seed for reproducibility | Change to get different training runs |\n\n#### CFG Settings (corrected mode only)\n\n| Setting | Default | What it does | Why you'd change it |\n|---|---|---|---|\n| CFG dropout ratio | `0.15` | Probability of replacing conditions with null embeddings | The base model was trained with 0.15 -- match it. Lower values reduce CFG effectiveness |\n\n#### Logging & Checkpoints\n\n| Setting | Default | What it does | Why you'd change it |\n|---|---|---|---|\n| Save every N epochs | `10` | Full checkpoint (adapter + optimizer + scheduler) | Lower for safety on long runs, higher to save disk space |\n| Log every N steps | `10` | TensorBoard loss/LR logging | Lower for more granular curves, higher to reduce overhead |\n| Resume from | *(empty)* | Path to a checkpoint to resume from | Use after interrupted training. Points to a `checkpoint-epoch-N` folder |\n\n---\n\n### Advanced Mode Settings\n\nThese appear only when \"Advanced\" is selected at the start of the wizard.\n\n#### Device & Precision\n\n| Setting | Default | What it does | Why you'd change it |\n|---|---|---|---|\n| Device | `auto` | GPU selection. Auto picks: CUDA > MPS > XPU > CPU | Multi-GPU: pick `cuda:0` or `cuda:1`. Force CPU for debugging |\n| Precision | `auto` | Float format. Auto picks: bf16 (CUDA), fp16 (MPS), fp32 (CPU) | Force `fp32` for debugging NaN issues. `fp16` if your GPU lacks bf16 |\n\n#### Optimizer & Scheduler\n\n| Setting | Default | What it does | Why you'd change it |\n|---|---|---|---|\n| Optimizer | `adamw` | Weight update algorithm | `adamw8bit` saves VRAM. `prodigy` auto-tunes LR (set LR to 1.0). `adafactor` for minimal state |\n| Scheduler | `cosine` | LR decay curve after warmup | `constant` for Prodigy. `linear` for steady decay. `constant_with_warmup` for flat after ramp |\n\n> **Prodigy note:** When you select Prodigy, set the learning rate to `1.0` and the scheduler to `constant`. Prodigy auto-tunes the actual learning rate internally.\n\n#### VRAM Savings\n\n| Setting | Default | What it does | Why you'd change it |\n|---|---|---|---|\n| Gradient checkpointing | `yes` | Recompute activations to save VRAM (~40-60% less, ~10-30% slower) | Disable only if you have abundant VRAM and want max speed |\n| Offload encoder | `no` | Move encoder/VAE to CPU after setup (~2-4 GB saved) | Enable on tight VRAM budgets (10-16 GB GPUs) |\n\n#### Advanced Training\n\n| Setting | Default | What it does | Why you'd change it |\n|---|---|---|---|\n| Weight decay | `0.01` | L2 regularization. Prevents overfitting | Increase (0.05) for very small datasets, decrease (0.001) for large |\n| Max grad norm | `1.0` | Gradient clipping threshold | Increase if you see \"gradient clipping\" warnings everywhere; decrease for stability |\n| Bias mode | `none` | Train bias parameters: `none`, `all`, `lora_only` | `lora_only` may marginally improve quality; `all` trains all biases |\n\n#### Data Loading\n\n| Setting | Default | What it does | Why you'd change it |\n|---|---|---|---|\n| Workers | `4` (Linux), `0` (Windows) | Parallel data loading processes | More workers = faster loading. Windows forces 0 (multiprocessing limitation) |\n| Pin memory | `yes` | Pin loaded tensors in CPU for faster GPU transfer | Disable if low on system RAM |\n| Prefetch factor | `2` | Batches each worker prefetches ahead | Higher for faster GPUs that consume data quickly |\n| Persistent workers | `yes` | Keep workers alive between epochs | Disable if you see memory leaks from data loading |\n\n#### Advanced Logging\n\n| Setting | Default | What it does | Why you'd change it |\n|---|---|---|---|\n| TensorBoard dir | `{output}/runs` | Where TensorBoard logs go | Custom path if you want all runs in one place |\n| Heavy log every N steps | `50` | Per-layer gradient norm logging | Lower for debugging training dynamics, higher to reduce overhead |\n| Sample every N epochs | `0` (disabled) | Generate audio samples during training | Not yet implemented |\n"
  },
  {
    "path": "docs/sidestep/Training Guide.md",
    "content": "## Overview\n\nSide-Step supports two adapter types and two training modes:\n\n|                    | Corrected (Fixed) | Vanilla (Original)          |\n| ------------------ | ----------------- | --------------------------- |\n| **LoRA** (PEFT)    | Recommended       | For reproducing old results |\n| **LoKR** (LyCORIS) | Experimental      | Experimental                |\n\n**Corrected mode** (the default and recommended path) uses:\n- Continuous logit-normal timestep sampling (matches how base/SFT were trained)\n- 15% CFG dropout (teaches the model to handle prompted and unprompted generation)\n- Standalone -- no base ACE-Step installation needed\n\n**Vanilla mode** reproduces the original ACE-Step training behavior:\n- Discrete 8-step timestep schedule\n- No CFG dropout\n- Requires base ACE-Step installed alongside\n\n---\n\n## Quick Start: Wizard\n\nThe easiest way to train is the interactive wizard:\n\n```bash\nuv run python train.py\n```\n\nThe wizard walks you through:\n1. Selecting adapter type (LoRA or LoKR)\n2. Choosing training mode (Corrected or Vanilla)\n3. Picking your model (interactive selector with fuzzy search)\n4. Setting hyperparameters (Basic mode uses good defaults, Advanced exposes everything)\n5. Confirming and starting\n\n### Wizard Features\n\n- **Go-back navigation**: Type `b` at any prompt to return to the previous question\n- **Presets**: Save and load named configurations (main menu > Manage presets)\n- **Flow chaining**: After preprocessing, the wizard offers to start training immediately\n- **Settings**: Configure checkpoint paths and vanilla mode (main menu > Settings)\n- **Session loop**: The wizard stays open after each action -- no need to restart\n\n---\n\n## Quick Start: CLI\n\nFor automated pipelines or when you know exactly what you want:\n\n### Preprocessing\n\nConvert raw audio to training tensors:\n\n```bash\n# With a dataset JSON (lyrics, genre, BPM metadata)\nuv run python train.py fixed \\\n    --checkpoint-dir ../ACE-Step-1.5/checkpoints \\\n    --model-variant base \\\n    --preprocess \\\n    --dataset-json ./my_dataset.json \\\n    --audio-dir ./my_audio \\\n    --tensor-output ./my_tensors\n\n# Without metadata (all tracks treated as instrumentals)\nuv run python train.py fixed \\\n    --checkpoint-dir ../ACE-Step-1.5/checkpoints \\\n    --model-variant base \\\n    --preprocess \\\n    --audio-dir ./my_audio \\\n    --tensor-output ./my_tensors\n```\n\nPreprocessing runs in two passes to minimize VRAM:\n1. **Pass 1** -- VAE + Text Encoder (~3 GB): encodes audio to latents, text to embeddings\n2. **Pass 2** -- DiT Encoder (~6 GB): generates condition encodings\n\n### Training\n\n```bash\n# LoRA (stable, recommended)\nuv run python train.py fixed \\\n    --checkpoint-dir ../ACE-Step-1.5/checkpoints \\\n    --model-variant base \\\n    --dataset-dir ./my_tensors \\\n    --output-dir ./output/my_lora \\\n    --epochs 100 \\\n    --lr 1e-4\n\n# LoKR (experimental)\nuv run python train.py fixed \\\n    --checkpoint-dir ../ACE-Step-1.5/checkpoints \\\n    --model-variant base \\\n    --adapter-type lokr \\\n    --dataset-dir ./my_tensors \\\n    --output-dir ./output/my_lokr \\\n    --epochs 100\n\n# Training on a fine-tune\nuv run python train.py fixed \\\n    --checkpoint-dir ../ACE-Step-1.5/checkpoints \\\n    --model-variant my-custom-finetune \\\n    --base-model base \\\n    --dataset-dir ./my_tensors \\\n    --output-dir ./output/finetune_lora\n```\n\n---\n\n## LoRA vs LoKR\n\n### LoRA (Low-Rank Adaptation)\n\n- Uses the PEFT library\n- Well-tested, stable, widely supported\n- Adds low-rank matrices to attention layers\n- Good default: rank 64, alpha 128\n\n### LoKR (Low-Rank Kronecker)\n\n- Uses the LyCORIS library (included automatically)\n- **Experimental** -- may have rough edges\n- Uses Kronecker product factorization instead of simple low-rank decomposition\n- May capture different patterns than LoRA\n- Additional options: Tucker decomposition, DoRA-style weight decomposition\n\n> **Warning:** LoKR is experimental. The LyCORIS + Lightning Fabric interaction has not been exhaustively tested. If you encounter issues, fall back to LoRA.\n\n### Preprocessing is adapter-agnostic\n\nPreprocessing produces the same tensors regardless of whether you plan to train with LoRA or LoKR. The adapter type only affects how trainable weights are injected into the model during training -- it does not change the data pipeline. You only need to preprocess your audio once, and the resulting `.pt` files work for both adapter types.\n\n---\n\n## Hyperparameter Guide\n\n### Learning Rate\n\n| Optimizer | Recommended LR | Notes |\n|-----------|----------------|-------|\n| AdamW | `1e-4` | Standard choice |\n| AdamW8bit | `1e-4` | Same as AdamW but saves ~30% optimizer VRAM |\n| Adafactor | `1e-4` | Minimal state memory |\n| Prodigy | `1.0` | Auto-tunes the actual LR. Set scheduler to `constant` |\n\n### Rank (LoRA) / Linear Dim (LoKR)\n\n| Rank | Capacity | VRAM | Use Case |\n|------|----------|------|----------|\n| 16 | Low | Minimal | Quick tests, very small datasets |\n| 64 | Medium | Standard | Recommended default |\n| 128 | High | Higher | Large datasets, maximum quality |\n\n### Epochs\n\nDepends heavily on dataset size:\n- **1-10 songs**: 200-500 epochs\n- **10-50 songs**: 100-200 epochs\n- **50+ songs**: 50-100 epochs\n\nWatch the loss curve in TensorBoard. If it plateaus, you can stop early.\n\n### VRAM Optimization\n\nSide-Step applies several optimizations automatically and exposes others as options. For the full deep-dive, see [[VRAM Optimization Guide]].\n\n**Automatic (no user action needed):**\n\n1. **Gradient checkpointing** (ON by default) -- recomputes activations during backward pass, saves ~40-60% activation VRAM (~10-30% slower). Matches what the original ACE-Step trainer always did.\n2. **Flash Attention 2** (auto-installed) -- fused attention kernels for better GPU utilization. Requires Ampere+ GPU (RTX 30xx or newer). Falls back to SDPA on older hardware.\n\n**User-configurable (from least to most aggressive):**\n\n3. **Batch size 1** (default) -- minimum memory per step\n4. **8-bit optimizer** (`--optimizer-type adamw8bit`) -- saves ~30% optimizer VRAM\n5. **Encoder offloading** (`--offload-encoder`) -- saves ~2-4 GB after setup\n6. **Lower rank** (16 instead of 64) -- fewer trainable parameters\n\n---\n\n## Monitoring Training\n\n### TensorBoard\n\nSide-Step logs training metrics to TensorBoard automatically:\n\n```bash\n# In a separate terminal\ntensorboard --logdir ./output/my_lora/runs\n\n# Then open http://localhost:6006 in your browser\n```\n\nKey metrics to watch:\n- **loss/train** -- Should decrease over time. Spikes are normal but persistent increase means overfitting\n- **lr** -- Learning rate schedule. Should warm up then follow your chosen scheduler\n- **grad_norm/** -- Per-layer gradient norms (logged every `--log-heavy-every` steps)\n\n### Log File\n\nAll sessions append to `sidestep.log` in the working directory. This captures full tracebacks and debug-level messages that may not appear in the terminal. Useful for diagnosing issues.\n\n---\n\n## Resuming Training\n\nIf training is interrupted, resume from a checkpoint:\n\n```bash\nuv run python train.py fixed \\\n    --checkpoint-dir ../ACE-Step-1.5/checkpoints \\\n    --model-variant base \\\n    --dataset-dir ./my_tensors \\\n    --output-dir ./output/my_lora \\\n    --resume-from ./output/my_lora/checkpoint-epoch-50\n```\n\nThe checkpoint contains LoRA/LoKR weights, optimizer state, and scheduler state. Training continues from where it left off.\n\n---\n\n## Gradient Estimation\n\nBefore training, you can analyze which attention modules are most sensitive to your dataset:\n\n```bash\nuv run python train.py estimate \\\n    --checkpoint-dir ../ACE-Step-1.5/checkpoints \\\n    --model-variant base \\\n    --dataset-dir ./my_tensors \\\n    --estimate-batches 5 \\\n    --top-k 16\n```\n\nThis ranks modules by gradient sensitivity. Useful for:\n- Deciding which `--target-modules` to use\n- Understanding what your dataset teaches the model\n- Comparing different datasets\n\n---\n\n## See Also\n\n- [[Getting Started]] -- Installation and setup\n- [[Model Management]] -- Checkpoint structure and fine-tune support\n- [[Shift and Timestep Sampling]] -- How training timesteps work, what shift actually does, Side-Step vs upstream\n- [[Estimation Guide]] -- How to use and read gradient sensitivity analysis\n- [[VRAM Optimization Guide]] -- VRAM profiles, GPU tiers, and complete wizard settings reference\n"
  },
  {
    "path": "docs/sidestep/Using Your Adapter.md",
    "content": "# Using Your Adapter\n\nAfter training completes, Side-Step saves your adapter weights to the output directory. This page explains the output layout, how to load adapters in ACE-Step's Gradio UI, and important considerations for inference.\n\n---\n\n## Output Directory Layout\n\n### LoRA Training\n\n```\noutput/my_lora/\n├── final/\n│   ├── adapter_config.json         # PEFT adapter configuration\n│   └── adapter_model.safetensors   # Trained LoRA weights\n├── checkpoints/\n│   └── epoch_10/                   # Saved every N epochs (--save-every)\n│       ├── adapter_config.json\n│       ├── adapter_model.safetensors\n│       └── training_state.pt       # Optimizer + scheduler state for resume\n└── runs/\n    └── [TensorBoard event files]   # Training metrics\n```\n\n### LoKR Training\n\n```\noutput/my_lokr/\n├── final/\n│   └── lokr_weights.safetensors    # Trained LoKR weights (config in metadata)\n├── checkpoints/\n│   └── epoch_10/\n│       ├── lokr_weights.safetensors\n│       └── training_state.pt\n└── runs/\n    └── [TensorBoard event files]\n```\n\nKey differences:\n\n- **LoRA** saves two files: `adapter_config.json` (PEFT configuration) + `adapter_model.safetensors` (weights).\n- **LoKR** saves one file: `lokr_weights.safetensors` (weights + configuration stored in safetensors metadata).\n- **Checkpoints** include `training_state.pt` for resuming training. The adapter files in each checkpoint are also inference-ready.\n- The `final/` directory contains only the adapter weights (no training state) -- this is what you point inference tools at.\n\n---\n\n## Loading LoRA in ACE-Step Gradio\n\nACE-Step's Gradio UI has a built-in LoRA loading section. Here is how to use it:\n\n1. **Start ACE-Step's Gradio UI** as you normally would.\n2. In the **Service Configuration** section, find the **LoRA Adapter** panel.\n3. In the **LoRA Path** field, enter the path to your adapter directory:\n   ```\n   /path/to/Side-Step/output/my_lora/final\n   ```\n   Point at the directory, not at a specific file. ACE-Step expects to find `adapter_config.json` inside it.\n4. Click **Load LoRA**. You should see a success message.\n5. Toggle **Use LoRA** to enable the adapter during generation.\n6. Adjust the **LoRA Scale** slider to control how strongly the adapter affects output (1.0 = full strength, lower values blend with the base model).\n7. Generate audio as usual.\n\nTo switch back to the base model, click **Unload** or toggle **Use LoRA** off.\n\n### Requirements\n\n- **Quantization must be disabled.** LoRA loading is not supported when INT8 quantization is active. If you see an error about quantization, re-initialize the ACE-Step service with quantization set to `None`.\n- The adapter was trained with PEFT, so ACE-Step's standard LoRA loading path works directly.\n\n### Using Checkpoints for Inference\n\nEvery checkpoint directory (`checkpoints/epoch_N/`) also contains inference-ready adapter files. You can point the Gradio LoRA path at any checkpoint to test intermediate training results:\n\n```\n/path/to/Side-Step/output/my_lora/checkpoints/epoch_50\n```\n\n---\n\n## LoKR Limitation\n\nACE-Step's Gradio UI currently **only supports PEFT LoRA adapters**. The loading code checks for `adapter_config.json`, which LoKR does not produce (LoKR uses LyCORIS format with `lokr_weights.safetensors`).\n\n**LoKR adapters cannot be loaded in the standard ACE-Step Gradio UI at this time.** If you trained a LoKR adapter and want to use it for inference, you will need to write custom inference code using the LyCORIS library, or wait for LoKR support to be added to ACE-Step.\n\nIf you are unsure which adapter type to use, **LoRA is the safe choice** for both training and inference compatibility.\n\n---\n\n## Shift and Inference Steps\n\nWhen generating audio with your trained adapter, use the correct `shift` and inference step values for your model variant:\n\n| Model Variant | Shift | Inference Steps |\n| :--- | :--- | :--- |\n| Turbo | `3.0` | `8` |\n| Base | `1.0` | `50` |\n| SFT | `1.0` | `50` |\n\nThese values were saved as metadata during training (via `--shift` and `--num-inference-steps`) but **do not affect the training loop itself**. They tell you what to use at inference time. See [[Shift and Timestep Sampling]] for the full explanation.\n\nUsing the wrong shift value at inference will produce degraded audio quality, even if the adapter was trained correctly.\n\n---\n\n## Viewing TensorBoard Logs\n\nSide-Step writes TensorBoard logs to the `runs/` subdirectory of your output directory (or to `--log-dir` if you specified one). To view them:\n\n```bash\ntensorboard --logdir ./output/my_lora/runs\n```\n\nThen open `http://localhost:6006` in your browser. Key metrics:\n\n- **loss** -- Training loss over time. Should decrease and stabilize.\n- **lr** -- Learning rate schedule. Verify warmup and decay look correct.\n- **grad_norm** -- Gradient magnitudes. Spikes may indicate training instability.\n\n---\n\n## Resuming Training\n\nTo continue training from a checkpoint:\n\n```bash\nuv run train.py fixed \\\n    --checkpoint-dir ./checkpoints \\\n    --model-variant turbo \\\n    --dataset-dir ./my_tensors \\\n    --output-dir ./output/my_lora \\\n    --resume-from ./output/my_lora/checkpoints/epoch_50 \\\n    --epochs 200\n```\n\nThis restores the adapter weights, optimizer state, and learning rate scheduler from the checkpoint. Training continues from where it left off.\n\nYou can also point `--resume-from` at a file inside the checkpoint directory (e.g., `training_state.pt`) -- Side-Step will automatically use the parent directory.\n\n---\n\n## See Also\n\n- [[End-to-End Tutorial]] -- Full walkthrough from raw audio to generation\n- [[Shift and Timestep Sampling]] -- Why shift matters for inference\n- [[Training Guide]] -- Training options and hyperparameters\n- [[VRAM Optimization Guide]] -- GPU memory management\n"
  },
  {
    "path": "docs/sidestep/VRAM Optimization Guide.md",
    "content": "# VRAM Optimization Guide\n\nThis page documents every VRAM optimization Side-Step applies and the VRAM profiles for different GPU tiers.\n\n---\n\n## VRAM Optimizations\n\nSide-Step applies several layers of VRAM optimization. Some are automatic; others are user-configurable. They are listed here from most impactful to least.\n\n### Gradient Checkpointing (automatic, on by default)\n\n**What it does:** During the backward pass, PyTorch normally stores all intermediate activations from the forward pass so it can compute gradients. Gradient checkpointing discards those activations and recomputes them on-the-fly during backpropagation.\n\n**VRAM savings:** ~40-60% reduction in activation memory. For ACE-Step's decoder this is easily 10-15 GB on large batches.\n\n**Trade-off:** ~10-30% slower training (recomputation cost).\n\n**Default:** ON. This matches what the original ACE-Step trainer always did silently. Side-Step exposes it as a toggle so power users can disable it if they have VRAM to spare and want maximum speed.\n\n**How to disable:** In the wizard (Advanced mode), answer \"no\" to \"Enable gradient checkpointing?\". Via CLI: `--no-gradient-checkpointing`.\n\n> Side-Step also disables `use_cache` on the decoder (frees KV-cache memory) and enables `input_require_grads` (needed for PEFT + checkpointing compatibility). These happen automatically when gradient checkpointing is on.\n\n### Flash Attention 2 (automatic, no user action needed)\n\n**What it does:** Replaces the standard attention implementation with a fused CUDA kernel that is both faster and more memory-efficient. Instead of materializing the full N x N attention matrix, Flash Attention computes attention in tiles.\n\n**VRAM savings:** Reduces attention memory from O(N^2) to O(N). In practice, this translates to lower peak VRAM during the forward pass, especially for long audio sequences.\n\n**Speed benefit:** 10-30% faster training steps on supported hardware due to better GPU utilization (100% compute occupancy vs ~70-80% with SDPA).\n\n**Requirements:** NVIDIA Ampere or newer GPU (RTX 30xx, RTX 40xx, A100, H100, etc. -- compute capability >= 8.0).\n\n**How it works:** Side-Step installs Flash Attention 2 from prebuilt wheels (no compilation needed) as part of `uv sync`. At runtime, the model loader auto-detects whether Flash Attention is available and falls back to SDPA (Scaled Dot-Product Attention) if it is not. You do not need to configure anything.\n\n**Fallback:** On older GPUs (RTX 20xx, GTX 16xx, etc.) or macOS, SDPA is used automatically.\n\n### 8-bit Optimizer (optional, Advanced mode)\n\n**What it does:** Replaces the standard 32-bit AdamW optimizer with an 8-bit quantized version. AdamW stores two state tensors (momentum and variance) per trainable parameter. Quantizing these to 8-bit halves their memory footprint.\n\n**VRAM savings:** ~30% reduction in optimizer state memory. For a rank-64 LoRA with ~10M trainable parameters, this saves ~2-3 GB.\n\n**Trade-off:** Negligible quality difference in practice. The quantization is applied to optimizer state, not to the model weights or gradients.\n\n**How to enable:** In the wizard (Advanced > Optimizer & Scheduler), select \"AdamW 8-bit\". Via CLI: `--optimizer-type adamw8bit`. The `bitsandbytes` package is included automatically by `uv sync`.\n\n### Encoder Offloading (optional, Advanced mode)\n\n**What it does:** After the model is set up for training, moves non-decoder submodules (VAE, text encoder, condition encoders) from GPU to CPU. These components are only needed during preprocessing -- during the training loop itself, only the decoder runs on GPU.\n\n**VRAM savings:** ~2-4 GB, depending on the model.\n\n**Trade-off:** Minimal. These components are not used during the training loop, so offloading them has no speed impact.\n\n**How to enable:** In the wizard (Advanced > VRAM Savings), answer \"yes\" to \"Offload encoder/VAE to CPU?\". Via CLI: `--offload-encoder`.\n\n### Lower Rank\n\n**What it does:** Reduces the number of trainable parameters in the LoRA/LoKR adapter. Fewer parameters means less memory for gradients, optimizer state, and activation storage.\n\n**VRAM savings:** Roughly proportional. Rank 16 uses ~4x less adapter VRAM than rank 64.\n\n**Trade-off:** Lower capacity. The adapter can capture less of your dataset's style. See the rank guide in [[Training Guide]].\n\n### Gradient Accumulation\n\n**What it does:** Instead of updating weights after every batch, accumulates gradients over N batches before applying a single optimizer step. This gives the same effective batch size as `batch_size x gradient_accumulation` without the VRAM cost of a larger batch.\n\n**VRAM savings:** Keeps per-step VRAM at `batch_size=1` levels while achieving the training dynamics of a larger effective batch.\n\n**Default:** 4 steps of accumulation with batch size 1 (effective batch size = 4).\n\n---\n\n## VRAM Profiles\n\n| Profile | GPU VRAM | Automatic | Recommended Settings |\n|---|---|---|---|\n| **Comfortable** | 24 GB+ | Grad checkpointing ON, Flash Attention | Batch 2+, AdamW, Rank 64-128 |\n| **Standard** | 16-24 GB | Grad checkpointing ON, Flash Attention | Batch 1, AdamW, Rank 64, Grad accumulation 4 |\n| **Tight** | 10-16 GB | Grad checkpointing ON, Flash Attention | Batch 1, **AdamW8bit**, Encoder offloading, Rank 32-64 |\n| **Minimal** | <10 GB | Grad checkpointing ON, Flash Attention | Batch 1, **AdamW8bit** or **Adafactor**, Encoder offloading, Rank 16, High grad accumulation |\n\n> Gradient checkpointing and Flash Attention are always active (when supported). The profiles differ in optimizer choice, rank, and optional offloading.\n> \n---\n\n## See Also\n\n- [[Training Guide]] -- Full training workflow, hyperparameter guide, LoRA vs LoKR\n- [[Estimation Guide]] -- Gradient sensitivity analysis for targeted training\n- [[Getting Started]] -- Installation and first-run setup\n- [[Model Management]] -- Checkpoint structure and fine-tune support\n"
  },
  {
    "path": "docs/sidestep/Windows Notes.md",
    "content": "# Windows Notes\n\nSide-Step fully supports Windows with CUDA GPUs. This page documents Windows-specific behavior, workarounds, and configuration details that differ from Linux/macOS.\n\n---\n\n## Installation\n\nThe easiest way to install on Windows is the **Easy Installer**:\n\n1. Clone or download Side-Step.\n2. Double-click `install_windows.bat` (or run `install_windows.ps1` from PowerShell).\n\nThe installer handles everything:\n\n- Installs `uv` (if not already present)\n- Installs Python 3.11\n- Clones ACE-Step 1.5 alongside Side-Step\n- Runs `uv sync` for all dependencies\n- Optionally downloads model checkpoints\n\n**Requirements:** Windows 10/11, PowerShell 5.1+, Git, NVIDIA GPU with CUDA drivers.\n\nThe installer creates two sibling directories:\n\n```\nParent/\n├── Side-Step/       <-- Your training toolkit\n└── ACE-Step-1.5/    <-- Model checkpoints + optional vanilla mode\n```\n\n### Running from PowerShell\n\n```powershell\ncd Side-Step\nuv run train.py\n```\n\nBoth PowerShell and CMD work. The wizard displays Windows-native paths (backslashes) in its prompts.\n\n---\n\n## DataLoader Workers (num_workers = 0)\n\n**On Windows, Side-Step forces `num_workers=0` regardless of what you set.**\n\nThis is because Windows uses spawn-based multiprocessing (rather than fork), which breaks PyTorch's DataLoader workers. Attempting to use workers > 0 on Windows causes crashes or hangs.\n\nSide-Step handles this automatically:\n\n- The CLI default is `0` on Windows.\n- The wizard warns you and clamps to `0` if you enter a higher value.\n- The trainer enforces `0` at runtime even if overridden via CLI.\n\nWhen `num_workers=0`:\n\n- `prefetch_factor` is forced to `0` (no background prefetching).\n- `persistent_workers` is forced to `False`.\n\n**Impact:** Data loading is slightly slower (single-threaded), but training speed is dominated by GPU computation, so the difference is usually negligible.\n\n---\n\n## Multi-GPU Device Selection\n\nOn Windows, Lightning Fabric's `devices=[index]` parameter causes `DistributedSampler` to produce 0 batches, which makes training silently \"complete\" with 0 steps.\n\nSide-Step works around this by using `devices=1` and calling `torch.cuda.set_device(device_idx)` directly. This means multi-GPU selection (e.g., `--device cuda:1`) works correctly on Windows.\n\n---\n\n## Configuration and Preset Paths\n\nSide-Step stores user configuration and presets at Windows-standard locations:\n\n| Item | Path |\n| :--- | :--- |\n| Settings | `%APPDATA%\\sidestep\\settings.json` |\n| Global presets | `%APPDATA%\\sidestep\\presets\\` |\n| Local presets | `.\\presets\\` (in the Side-Step project directory) |\n\n`%APPDATA%` typically resolves to `C:\\Users\\<you>\\AppData\\Roaming`.\n\nLocal presets take priority over global presets. See [[Preset Management]] for details.\n\n---\n\n## Log File\n\nSide-Step writes a log file (`sidestep.log`) to the current working directory. On some Windows setups (e.g., running from a read-only directory or a restricted location), the log file may fail to create. In that case, Side-Step falls back to console-only logging with no error.\n\nIf you need the log file for troubleshooting, make sure you run Side-Step from a writable directory (e.g., the Side-Step project folder itself).\n\n---\n\n## Preset Name Safety\n\nPreset names are validated against Windows reserved filenames. The following names are rejected:\n\n`CON`, `PRN`, `AUX`, `NUL`, `COM1`-`COM9`, `LPT1`-`LPT9`\n\nCharacters `/\\:*?\"<>|` are also stripped from preset names. This validation applies on all platforms, not just Windows, to keep presets portable.\n\n---\n\n## Path Length (MAX_PATH)\n\nWindows has a historical 260-character path length limit (MAX_PATH). Side-Step does not explicitly handle this. If you encounter path-related errors:\n\n- Keep your project close to the drive root (e.g., `C:\\ai\\Side-Step\\` rather than deeply nested directories).\n- Avoid very long output directory names.\n- Consider enabling long paths in Windows: Settings > System > For Developers > Enable long paths. This requires Windows 10 version 1607 or later.\n\n---\n\n## Summary of Windows-Specific Behavior\n\n| Behavior | What Happens | Why |\n| :--- | :--- | :--- |\n| `num_workers` clamped to `0` | DataLoader runs single-threaded | Windows spawn-based multiprocessing breaks PyTorch workers |\n| `prefetch_factor` forced to `0` | No background batch prefetching | Required when `num_workers=0` |\n| `persistent_workers` forced off | Workers not kept alive between epochs | Required when `num_workers=0` |\n| Fabric `devices=1` | Uses `torch.cuda.set_device()` instead of device list | `devices=[index]` causes 0-batch bug on Windows |\n| Backslash paths in prompts | Path display uses `\\` separator | Native Windows path convention |\n| Config stored in `%APPDATA%` | Settings and global presets in AppData | Windows standard user config location |\n| File explorer uses `explorer` | \"Open folder\" actions use Windows Explorer | Platform-appropriate file manager |\n\n---\n\n## See Also\n\n- [[Getting Started]] -- Installation and first-run setup\n- [[Preset Management]] -- Preset storage and management\n- [[VRAM Optimization Guide]] -- GPU memory profiles\n"
  },
  {
    "path": "docs/zh/API.md",
    "content": "# ACE-Step API 客户端文档\n\n**Language / 语言 / 言語:** [English](../en/API.md) | [中文](API.md) | [日本語](../ja/API.md)\n\n---\n\n本服务提供基于 HTTP 的异步音乐生成 API。\n\n**基本工作流程**：\n1. 调用 `POST /release_task` 提交任务并获取 `task_id`。\n2. 调用 `POST /query_result` 批量查询任务状态，直到 `status` 为 `1`（成功）或 `2`（失败）。\n3. 通过结果中返回的 `GET /v1/audio?path=...` URL 下载音频文件。\n\n---\n\n## 目录\n\n- [认证](#1-认证)\n- [响应格式](#2-响应格式)\n- [任务状态说明](#3-任务状态说明)\n- [创建生成任务](#4-创建生成任务)\n- [批量查询任务结果](#5-批量查询任务结果)\n- [格式化输入](#6-格式化输入)\n- [获取随机样本](#7-获取随机样本)\n- [列出可用模型](#8-列出可用模型)\n- [服务器统计](#9-服务器统计)\n- [下载音频文件](#10-下载音频文件)\n- [健康检查](#11-健康检查)\n- [环境变量](#12-环境变量)\n\n---\n\n## 1. 认证\n\nAPI 支持可选的 API Key 认证。启用后，必须在请求中提供有效的密钥。\n\n### 认证方式\n\n支持两种认证方式：\n\n**方式 A：请求体中的 ai_token**\n\n```json\n{\n  \"ai_token\": \"your-api-key\",\n  \"prompt\": \"欢快的流行歌曲\",\n  ...\n}\n```\n\n**方式 B：Authorization 头**\n\n```bash\ncurl -X POST http://localhost:8001/release_task \\\n  -H 'Authorization: Bearer your-api-key' \\\n  -H 'Content-Type: application/json' \\\n  -d '{\"prompt\": \"欢快的流行歌曲\"}'\n```\n\n### 配置 API Key\n\n通过环境变量或命令行参数设置：\n\n```bash\n# 环境变量\nexport ACESTEP_API_KEY=your-secret-key\n\n# 或命令行参数\npython -m acestep.api_server --api-key your-secret-key\n```\n\n---\n\n## 2. 响应格式\n\n所有 API 响应使用统一的包装格式：\n\n```json\n{\n  \"data\": { ... },\n  \"code\": 200,\n  \"error\": null,\n  \"timestamp\": 1700000000000,\n  \"extra\": null\n}\n```\n\n| 字段 | 类型 | 说明 |\n| :--- | :--- | :--- |\n| `data` | any | 实际响应数据 |\n| `code` | int | 状态码（200=成功）|\n| `error` | string | 错误信息（成功时为 null）|\n| `timestamp` | int | 响应时间戳（毫秒）|\n| `extra` | any | 额外信息（通常为 null）|\n\n---\n\n## 3. 任务状态说明\n\n任务状态（`status`）使用整数表示：\n\n| 状态码 | 状态名 | 说明 |\n| :--- | :--- | :--- |\n| `0` | queued/running | 任务排队中或执行中 |\n| `1` | succeeded | 生成成功，结果已就绪 |\n| `2` | failed | 生成失败 |\n\n---\n\n## 4. 创建生成任务\n\n### 4.1 API 定义\n\n- **URL**：`/release_task`\n- **方法**：`POST`\n- **Content-Type**：`application/json`、`multipart/form-data` 或 `application/x-www-form-urlencoded`\n\n### 4.2 请求参数\n\n#### 参数命名约定\n\nAPI 支持大多数参数的 **snake_case** 和 **camelCase** 命名。例如：\n- `audio_duration` / `duration` / `audioDuration`\n- `key_scale` / `keyscale` / `keyScale`\n- `time_signature` / `timesignature` / `timeSignature`\n- `sample_query` / `sampleQuery` / `description` / `desc`\n- `use_format` / `useFormat` / `format`\n\n此外，元数据可以通过嵌套对象传递（`metas`、`metadata` 或 `user_metadata`）。\n\n#### 方法 A：JSON 请求（application/json）\n\n适用于仅传递文本参数，或引用服务器上已存在的音频文件路径。\n\n**基本参数**：\n\n| 参数名 | 类型 | 默认值 | 说明 |\n| :--- | :--- | :--- | :--- |\n| `prompt` | string | `\"\"` | 音乐描述提示词（别名：`caption`）|\n| `lyrics` | string | `\"\"` | 歌词内容 |\n| `thinking` | bool | `false` | 是否使用 5Hz LM 生成音频代码（lm-dit 行为）|\n| `vocal_language` | string | `\"en\"` | 歌词语言（en、zh、ja 等）|\n| `audio_format` | string | `\"mp3\"` | 输出格式（mp3、wav、flac）|\n\n**样本/描述模式参数**：\n\n| 参数名 | 类型 | 默认值 | 说明 |\n| :--- | :--- | :--- | :--- |\n| `sample_mode` | bool | `false` | 启用随机样本生成模式（通过 LM 自动生成 caption/lyrics/metas）|\n| `sample_query` | string | `\"\"` | 用于样本生成的自然语言描述（例如\"一首柔和的孟加拉情歌\"）。别名：`description`、`desc` |\n| `use_format` | bool | `false` | 使用 LM 增强/格式化提供的 caption 和 lyrics。别名：`format` |\n\n**多模型支持**：\n\n| 参数名 | 类型 | 默认值 | 说明 |\n| :--- | :--- | :--- | :--- |\n| `model` | string | null | 选择使用哪个 DiT 模型（例如 `\"acestep-v15-turbo\"`、`\"acestep-v15-turbo-shift3\"`）。使用 `/v1/models` 列出可用模型。如果未指定，使用默认模型。|\n\n**thinking 语义（重要）**：\n\n- `thinking=false`：\n  - 服务器**不会**使用 5Hz LM 生成 `audio_code_string`。\n  - DiT 以 **text2music** 模式运行，**忽略**任何提供的 `audio_code_string`。\n- `thinking=true`：\n  - 服务器将使用 5Hz LM 生成 `audio_code_string`（lm-dit 行为）。\n  - DiT 使用 LM 生成的代码运行，以增强音乐质量。\n\n**元数据自动补全（条件性）**：\n\n当 `use_cot_caption=true` 或 `use_cot_language=true` 或元数据字段缺失时，服务器可能会调用 5Hz LM 根据 `caption`/`lyrics` 填充缺失的字段：\n\n- `bpm`\n- `key_scale`\n- `time_signature`\n- `audio_duration`\n\n用户提供的值始终优先；LM 只填充空/缺失的字段。\n\n**音乐属性参数**：\n\n| 参数名 | 类型 | 默认值 | 说明 |\n| :--- | :--- | :--- | :--- |\n| `bpm` | int | null | 指定节奏（BPM），范围 30-300 |\n| `key_scale` | string | `\"\"` | 调性（例如\"C Major\"、\"Am\"）。别名：`keyscale`、`keyScale` |\n| `time_signature` | string | `\"\"` | 拍号（2、3、4、6 分别表示 2/4、3/4、4/4、6/8）。别名：`timesignature`、`timeSignature` |\n| `audio_duration` | float | null | 生成时长（秒），范围 10-600。别名：`duration`、`target_duration` |\n\n**音频代码（可选）**：\n\n| 参数名 | 类型 | 默认值 | 说明 |\n| :--- | :--- | :--- | :--- |\n| `audio_code_string` | string 或 string[] | `\"\"` | 用于 `llm_dit` 的音频语义令牌（5Hz）。别名：`audioCodeString` |\n\n**生成控制参数**：\n\n| 参数名 | 类型 | 默认值 | 说明 |\n| :--- | :--- | :--- | :--- |\n| `inference_steps` | int | `8` | 推理步数。Turbo 模型：1-20（推荐 8）。Base 模型：1-200（推荐 32-64）|\n| `guidance_scale` | float | `7.0` | 提示引导系数。仅对 base 模型有效 |\n| `use_random_seed` | bool | `true` | 是否使用随机种子 |\n| `seed` | int | `-1` | 指定种子（当 use_random_seed=false 时）|\n| `batch_size` | int | `2` | 批量生成数量（最多 8）|\n\n**高级 DiT 参数**：\n\n| 参数名 | 类型 | 默认值 | 说明 |\n| :--- | :--- | :--- | :--- |\n| `shift` | float | `3.0` | 时间步偏移因子（范围 1.0-5.0）。仅对 base 模型有效，对 turbo 模型无效 |\n| `infer_method` | string | `\"ode\"` | 扩散推理方法：`\"ode\"`（Euler，更快）或 `\"sde\"`（随机）|\n| `timesteps` | string | null | 自定义时间步，逗号分隔值（例如 `\"0.97,0.76,0.615,0.5,0.395,0.28,0.18,0.085,0\"`）。覆盖 `inference_steps` 和 `shift` |\n| `use_adg` | bool | `false` | 使用自适应双引导（仅 base 模型）|\n| `cfg_interval_start` | float | `0.0` | CFG 应用起始比例（0.0-1.0）|\n| `cfg_interval_end` | float | `1.0` | CFG 应用结束比例（0.0-1.0）|\n\n**5Hz LM 参数（可选，服务器端）**：\n\n这些参数控制 5Hz LM 采样，用于元数据自动补全和（当 `thinking=true` 时）代码生成。\n\n| 参数名 | 类型 | 默认值 | 说明 |\n| :--- | :--- | :--- | :--- |\n| `lm_model_path` | string | null | 5Hz LM 检查点目录名（例如 `acestep-5Hz-lm-0.6B`）|\n| `lm_backend` | string | `\"vllm\"` | `vllm` 或 `pt` |\n| `lm_temperature` | float | `0.85` | 采样温度 |\n| `lm_cfg_scale` | float | `2.5` | CFG 比例（>1 启用 CFG）|\n| `lm_negative_prompt` | string | `\"NO USER INPUT\"` | CFG 使用的负面提示 |\n| `lm_top_k` | int | null | Top-k（0/null 禁用）|\n| `lm_top_p` | float | `0.9` | Top-p（>=1 将被视为禁用）|\n| `lm_repetition_penalty` | float | `1.0` | 重复惩罚 |\n\n**LM CoT（思维链）参数**：\n\n| 参数名 | 类型 | 默认值 | 说明 |\n| :--- | :--- | :--- | :--- |\n| `use_cot_caption` | bool | `true` | 让 LM 通过 CoT 推理重写/增强输入 caption。别名：`cot_caption`、`cot-caption` |\n| `use_cot_language` | bool | `true` | 让 LM 通过 CoT 检测人声语言。别名：`cot_language`、`cot-language` |\n| `constrained_decoding` | bool | `true` | 启用基于 FSM 的约束解码以获得结构化 LM 输出。别名：`constrainedDecoding`、`constrained` |\n| `constrained_decoding_debug` | bool | `false` | 启用约束解码的调试日志 |\n| `allow_lm_batch` | bool | `true` | 允许 LM 批量处理以提高效率 |\n\n**编辑/参考音频参数**（需要服务器上的绝对路径）：\n\n| 参数名 | 类型 | 默认值 | 说明 |\n| :--- | :--- | :--- | :--- |\n| `reference_audio_path` | string | null | 参考音频路径（风格迁移）|\n| `src_audio_path` | string | null | 源音频路径（重绘/翻唱）|\n| `task_type` | string | `\"text2music\"` | 任务类型：`text2music`、`cover`、`repaint`、`lego`、`extract`、`complete` |\n| `instruction` | string | auto | 编辑指令（如未提供则根据 task_type 自动生成）|\n| `repainting_start` | float | `0.0` | 重绘开始时间（秒）|\n| `repainting_end` | float | null | 重绘结束时间（秒），-1 表示音频末尾 |\n| `audio_cover_strength` | float | `1.0` | 翻唱强度（0.0-1.0）。风格迁移使用较小值（0.2）|\n\n#### 方法 B：文件上传（multipart/form-data）\n\n当需要上传本地音频文件作为参考或源音频时使用。\n\n除了支持上述所有字段作为表单字段外，还支持以下文件字段：\n\n- `reference_audio` 或 `ref_audio`：（文件）上传参考音频文件\n- `src_audio` 或 `ctx_audio`：（文件）上传源音频文件\n\n> **注意**：上传文件后，相应的 `_path` 参数将被自动忽略，系统将使用上传后的临时文件路径。\n\n### 4.3 响应示例\n\n```json\n{\n  \"data\": {\n    \"task_id\": \"550e8400-e29b-41d4-a716-446655440000\",\n    \"status\": \"queued\",\n    \"queue_position\": 1\n  },\n  \"code\": 200,\n  \"error\": null,\n  \"timestamp\": 1700000000000,\n  \"extra\": null\n}\n```\n\n### 4.4 使用示例（cURL）\n\n**基本 JSON 方法**：\n\n```bash\ncurl -X POST http://localhost:8001/release_task \\\n  -H 'Content-Type: application/json' \\\n  -d '{\n    \"prompt\": \"欢快的流行歌曲\",\n    \"lyrics\": \"你好世界\",\n    \"inference_steps\": 8\n  }'\n```\n\n**使用 thinking=true（LM 生成代码 + 填充缺失元数据）**：\n\n```bash\ncurl -X POST http://localhost:8001/release_task \\\n  -H 'Content-Type: application/json' \\\n  -d '{\n    \"prompt\": \"欢快的流行歌曲\",\n    \"lyrics\": \"你好世界\",\n    \"thinking\": true,\n    \"lm_temperature\": 0.85,\n    \"lm_cfg_scale\": 2.5\n  }'\n```\n\n**描述驱动生成（sample_query）**：\n\n```bash\ncurl -X POST http://localhost:8001/release_task \\\n  -H 'Content-Type: application/json' \\\n  -d '{\n    \"sample_query\": \"一首适合安静夜晚的柔和孟加拉情歌\",\n    \"thinking\": true\n  }'\n```\n\n**使用格式增强（use_format=true）**：\n\n```bash\ncurl -X POST http://localhost:8001/release_task \\\n  -H 'Content-Type: application/json' \\\n  -d '{\n    \"prompt\": \"流行摇滚\",\n    \"lyrics\": \"[Verse 1]\\n走在街上...\",\n    \"use_format\": true,\n    \"thinking\": true\n  }'\n```\n\n**选择特定模型**：\n\n```bash\ncurl -X POST http://localhost:8001/release_task \\\n  -H 'Content-Type: application/json' \\\n  -d '{\n    \"prompt\": \"电子舞曲\",\n    \"model\": \"acestep-v15-turbo\",\n    \"thinking\": true\n  }'\n```\n\n**使用自定义时间步**：\n\n```bash\ncurl -X POST http://localhost:8001/release_task \\\n  -H 'Content-Type: application/json' \\\n  -d '{\n    \"prompt\": \"爵士钢琴三重奏\",\n    \"timesteps\": \"0.97,0.76,0.615,0.5,0.395,0.28,0.18,0.085,0\",\n    \"thinking\": true\n  }'\n```\n\n**文件上传方法**：\n\n```bash\ncurl -X POST http://localhost:8001/release_task \\\n  -F \"prompt=重新混音这首歌\" \\\n  -F \"src_audio=@/path/to/local/song.mp3\" \\\n  -F \"task_type=repaint\"\n```\n\n---\n\n## 5. 批量查询任务结果\n\n### 5.1 API 定义\n\n- **URL**：`/query_result`\n- **方法**：`POST`\n- **Content-Type**：`application/json` 或 `application/x-www-form-urlencoded`\n\n### 5.2 请求参数\n\n| 参数名 | 类型 | 说明 |\n| :--- | :--- | :--- |\n| `task_id_list` | string (JSON array) 或 array | 要查询的任务 ID 列表 |\n\n### 5.3 响应示例\n\n```json\n{\n  \"data\": [\n    {\n      \"task_id\": \"550e8400-e29b-41d4-a716-446655440000\",\n      \"status\": 1,\n      \"result\": \"[{\\\"file\\\": \\\"/v1/audio?path=...\\\", \\\"wave\\\": \\\"\\\", \\\"status\\\": 1, \\\"create_time\\\": 1700000000, \\\"env\\\": \\\"development\\\", \\\"prompt\\\": \\\"欢快的流行歌曲\\\", \\\"lyrics\\\": \\\"你好世界\\\", \\\"metas\\\": {\\\"bpm\\\": 120, \\\"duration\\\": 30, \\\"genres\\\": \\\"\\\", \\\"keyscale\\\": \\\"C Major\\\", \\\"timesignature\\\": \\\"4\\\"}, \\\"generation_info\\\": \\\"...\\\", \\\"seed_value\\\": \\\"12345,67890\\\", \\\"lm_model\\\": \\\"acestep-5Hz-lm-0.6B\\\", \\\"dit_model\\\": \\\"acestep-v15-turbo\\\"}]\"\n    }\n  ],\n  \"code\": 200,\n  \"error\": null,\n  \"timestamp\": 1700000000000,\n  \"extra\": null\n}\n```\n\n**结果字段说明**（result 为 JSON 字符串，解析后包含）：\n\n| 字段 | 类型 | 说明 |\n| :--- | :--- | :--- |\n| `file` | string | 音频文件 URL（配合 `/v1/audio` 端点使用）|\n| `wave` | string | 波形数据（通常为空）|\n| `status` | int | 状态码（0=进行中，1=成功，2=失败）|\n| `create_time` | int | 创建时间（Unix 时间戳）|\n| `env` | string | 环境标识 |\n| `prompt` | string | 使用的提示词 |\n| `lyrics` | string | 使用的歌词 |\n| `metas` | object | 元数据（bpm、duration、genres、keyscale、timesignature）|\n| `generation_info` | string | 生成信息摘要 |\n| `seed_value` | string | 使用的种子值（逗号分隔）|\n| `lm_model` | string | 使用的 LM 模型名称 |\n| `dit_model` | string | 使用的 DiT 模型名称 |\n\n### 5.4 使用示例\n\n```bash\ncurl -X POST http://localhost:8001/query_result \\\n  -H 'Content-Type: application/json' \\\n  -d '{\n    \"task_id_list\": [\"550e8400-e29b-41d4-a716-446655440000\"]\n  }'\n```\n\n---\n\n## 6. 格式化输入\n\n### 6.1 API 定义\n\n- **URL**：`/format_input`\n- **方法**：`POST`\n\n此端点使用 LLM 增强和格式化用户提供的 caption 和 lyrics。\n\n### 6.2 请求参数\n\n| 参数名 | 类型 | 默认值 | 说明 |\n| :--- | :--- | :--- | :--- |\n| `prompt` | string | `\"\"` | 音乐描述提示词 |\n| `lyrics` | string | `\"\"` | 歌词内容 |\n| `temperature` | float | `0.85` | LM 采样温度 |\n| `param_obj` | string (JSON) | `\"{}\"` | 包含元数据的 JSON 对象（duration、bpm、key、time_signature、language）|\n\n### 6.3 响应示例\n\n```json\n{\n  \"data\": {\n    \"caption\": \"增强后的音乐描述\",\n    \"lyrics\": \"格式化后的歌词...\",\n    \"bpm\": 120,\n    \"key_scale\": \"C Major\",\n    \"time_signature\": \"4\",\n    \"duration\": 180,\n    \"vocal_language\": \"zh\"\n  },\n  \"code\": 200,\n  \"error\": null,\n  \"timestamp\": 1700000000000,\n  \"extra\": null\n}\n```\n\n### 6.4 使用示例\n\n```bash\ncurl -X POST http://localhost:8001/format_input \\\n  -H 'Content-Type: application/json' \\\n  -d '{\n    \"prompt\": \"流行摇滚\",\n    \"lyrics\": \"在街上漫步\",\n    \"param_obj\": \"{\\\"duration\\\": 180, \\\"language\\\": \\\"zh\\\"}\"\n  }'\n```\n\n---\n\n## 7. 获取随机样本\n\n### 7.1 API 定义\n\n- **URL**：`/create_random_sample`\n- **方法**：`POST`\n\n此端点从预加载的示例数据中返回随机样本参数，用于表单填充。\n\n### 7.2 请求参数\n\n| 参数名 | 类型 | 默认值 | 说明 |\n| :--- | :--- | :--- | :--- |\n| `sample_type` | string | `\"simple_mode\"` | 样本类型：`\"simple_mode\"` 或 `\"custom_mode\"` |\n\n### 7.3 响应示例\n\n```json\n{\n  \"data\": {\n    \"caption\": \"轻快的流行歌曲，带有吉他伴奏\",\n    \"lyrics\": \"[Verse 1]\\n阳光洒在脸上...\",\n    \"bpm\": 120,\n    \"key_scale\": \"G Major\",\n    \"time_signature\": \"4\",\n    \"duration\": 180,\n    \"vocal_language\": \"zh\"\n  },\n  \"code\": 200,\n  \"error\": null,\n  \"timestamp\": 1700000000000,\n  \"extra\": null\n}\n```\n\n### 7.4 使用示例\n\n```bash\ncurl -X POST http://localhost:8001/create_random_sample \\\n  -H 'Content-Type: application/json' \\\n  -d '{\"sample_type\": \"simple_mode\"}'\n```\n\n---\n\n## 8. 列出可用模型\n\n### 8.1 API 定义\n\n- **URL**：`/v1/models`\n- **方法**：`GET`\n\n返回服务器上加载的可用 DiT 模型列表。\n\n### 8.2 响应示例\n\n```json\n{\n  \"data\": {\n    \"models\": [\n      {\n        \"name\": \"acestep-v15-turbo\",\n        \"is_default\": true\n      },\n      {\n        \"name\": \"acestep-v15-turbo-shift3\",\n        \"is_default\": false\n      }\n    ],\n    \"default_model\": \"acestep-v15-turbo\"\n  },\n  \"code\": 200,\n  \"error\": null,\n  \"timestamp\": 1700000000000,\n  \"extra\": null\n}\n```\n\n### 8.3 使用示例\n\n```bash\ncurl http://localhost:8001/v1/models\n```\n\n---\n\n## 9. 服务器统计\n\n### 9.1 API 定义\n\n- **URL**：`/v1/stats`\n- **方法**：`GET`\n\n返回服务器运行统计信息。\n\n### 9.2 响应示例\n\n```json\n{\n  \"data\": {\n    \"jobs\": {\n      \"total\": 100,\n      \"queued\": 5,\n      \"running\": 1,\n      \"succeeded\": 90,\n      \"failed\": 4\n    },\n    \"queue_size\": 5,\n    \"queue_maxsize\": 200,\n    \"avg_job_seconds\": 8.5\n  },\n  \"code\": 200,\n  \"error\": null,\n  \"timestamp\": 1700000000000,\n  \"extra\": null\n}\n```\n\n### 9.3 使用示例\n\n```bash\ncurl http://localhost:8001/v1/stats\n```\n\n---\n\n## 10. 下载音频文件\n\n### 10.1 API 定义\n\n- **URL**：`/v1/audio`\n- **方法**：`GET`\n\n通过路径下载生成的音频文件。\n\n### 10.2 请求参数\n\n| 参数名 | 类型 | 说明 |\n| :--- | :--- | :--- |\n| `path` | string | URL 编码的音频文件路径 |\n\n### 10.3 使用示例\n\n```bash\n# 使用任务结果中的 URL 下载\ncurl \"http://localhost:8001/v1/audio?path=%2Ftmp%2Fapi_audio%2Fabc123.mp3\" -o output.mp3\n```\n\n---\n\n## 11. 健康检查\n\n### 11.1 API 定义\n\n- **URL**：`/health`\n- **方法**：`GET`\n\n返回服务健康状态。\n\n### 11.2 响应示例\n\n```json\n{\n  \"data\": {\n    \"status\": \"ok\",\n    \"service\": \"ACE-Step API\",\n    \"version\": \"1.0\"\n  },\n  \"code\": 200,\n  \"error\": null,\n  \"timestamp\": 1700000000000,\n  \"extra\": null\n}\n```\n\n---\n\n## 12. 环境变量\n\nAPI 服务器可以通过环境变量进行配置：\n\n### 服务器配置\n\n| 变量 | 默认值 | 说明 |\n| :--- | :--- | :--- |\n| `ACESTEP_API_HOST` | `127.0.0.1` | 服务器绑定主机 |\n| `ACESTEP_API_PORT` | `8001` | 服务器绑定端口 |\n| `ACESTEP_API_KEY` | （空）| API 认证密钥（空则禁用认证）|\n| `ACESTEP_API_WORKERS` | `1` | API 工作线程数 |\n\n### 模型配置\n\n| 变量 | 默认值 | 说明 |\n| :--- | :--- | :--- |\n| `ACESTEP_CONFIG_PATH` | `acestep-v15-turbo` | 主 DiT 模型路径 |\n| `ACESTEP_CONFIG_PATH2` | （空）| 辅助 DiT 模型路径（可选）|\n| `ACESTEP_CONFIG_PATH3` | （空）| 第三个 DiT 模型路径（可选）|\n| `ACESTEP_DEVICE` | `auto` | 模型加载设备 |\n| `ACESTEP_USE_FLASH_ATTENTION` | `true` | 启用 flash attention |\n| `ACESTEP_OFFLOAD_TO_CPU` | `false` | 空闲时将模型卸载到 CPU |\n| `ACESTEP_OFFLOAD_DIT_TO_CPU` | `false` | 专门将 DiT 卸载到 CPU |\n\n### LM 配置\n\n| 变量 | 默认值 | 说明 |\n| :--- | :--- | :--- |\n| `ACESTEP_INIT_LLM` | auto | 是否在启动时初始化 LM（auto 根据 GPU 自动决定）|\n| `ACESTEP_LM_MODEL_PATH` | `acestep-5Hz-lm-0.6B` | 默认 5Hz LM 模型 |\n| `ACESTEP_LM_BACKEND` | `vllm` | LM 后端（vllm 或 pt）|\n| `ACESTEP_LM_DEVICE` | （与 ACESTEP_DEVICE 相同）| LM 设备 |\n| `ACESTEP_LM_OFFLOAD_TO_CPU` | `false` | 将 LM 卸载到 CPU |\n\n### 队列配置\n\n| 变量 | 默认值 | 说明 |\n| :--- | :--- | :--- |\n| `ACESTEP_QUEUE_MAXSIZE` | `200` | 最大队列大小 |\n| `ACESTEP_QUEUE_WORKERS` | `1` | 队列工作者数量 |\n| `ACESTEP_AVG_JOB_SECONDS` | `5.0` | 初始平均任务持续时间估算 |\n| `ACESTEP_AVG_WINDOW` | `50` | 平均任务时间计算窗口 |\n\n### 缓存配置\n\n| 变量 | 默认值 | 说明 |\n| :--- | :--- | :--- |\n| `ACESTEP_TMPDIR` | `.cache/acestep/tmp` | 临时文件目录 |\n| `TRITON_CACHE_DIR` | `.cache/acestep/triton` | Triton 缓存目录 |\n| `TORCHINDUCTOR_CACHE_DIR` | `.cache/acestep/torchinductor` | TorchInductor 缓存目录 |\n\n---\n\n## 错误处理\n\n**HTTP 状态码**：\n\n- `200`：成功\n- `400`：无效请求（错误的 JSON、缺少字段）\n- `401`：未授权（缺少或无效的 API Key）\n- `404`：资源未找到\n- `415`：不支持的 Content-Type\n- `429`：服务器繁忙（队列已满）\n- `500`：内部服务器错误\n\n**错误响应格式**：\n\n```json\n{\n  \"detail\": \"描述问题的错误消息\"\n}\n```\n\n---\n\n## 最佳实践\n\n1. **使用 `thinking=true`** 以获得 LM 增强生成的最佳质量结果。\n\n2. **使用 `sample_query`/`description`** 从自然语言描述快速生成。\n\n3. **使用 `use_format=true`** 当你有 caption/lyrics 但希望 LM 增强它们时。\n\n4. **批量查询任务状态** 使用 `/query_result` 端点一次查询多个任务。\n\n5. **检查 `/v1/stats`** 响应来了解服务器负载和平均任务时间。\n\n6. **使用多模型支持** 通过设置 `ACESTEP_CONFIG_PATH2` 和 `ACESTEP_CONFIG_PATH3` 环境变量，然后通过 `model` 参数选择。\n\n7. **生产环境** 中，设置 `ACESTEP_API_KEY` 以启用认证，保护 API 安全。\n\n8. **低显存环境** 中，启用 `ACESTEP_OFFLOAD_TO_CPU=true` 以支持更长的音频生成。\n"
  },
  {
    "path": "docs/zh/BENCHMARK.md",
    "content": "# ACE-Step 1.5 基准测试与性能分析指南\n\n**Language / 语言:** [English](../en/BENCHMARK.md) | [中文](BENCHMARK.md)\n\n---\n\n## 目录\n\n- [概述](#概述)\n- [快速开始](#快速开始)\n- [测试模式](#测试模式)\n- [命令行参数](#命令行参数)\n- [使用示例](#使用示例)\n- [理解输出](#理解输出)\n- [技巧与最佳实践](#技巧与最佳实践)\n\n---\n\n## 概述\n\n`profile_inference.py` 是 ACE-Step 1.5 推理的综合性能分析与基准测试工具。它可以测量端到端耗时、LLM 规划耗时、DiT 扩散耗时、VAE 解码耗时等，支持不同设备、后端和配置的组合测试。\n\n### 支持的模式\n\n| 模式 | 说明 |\n|------|------|\n| `profile` | 对单次生成进行详细的计时分析 |\n| `benchmark` | 运行配置矩阵（时长 × 批量 × 思考 × 步数），输出汇总表 |\n| `tier-test` | 通过 `MAX_CUDA_VRAM` 模拟不同显存大小，自动测试所有 GPU 等级 |\n| `understand` | 分析 `understand_music()` API（音频 → 元数据提取） |\n| `create_sample` | 分析 `create_sample()` API（灵感/简单模式） |\n| `format_sample` | 分析 `format_sample()` API（标题+歌词 → 结构化元数据） |\n\n### 支持的设备与后端\n\n| 设备 | 参数 | 说明 |\n|------|------|------|\n| CUDA (NVIDIA) | `--device cuda` | 推荐，默认自动检测 |\n| MPS (Apple Silicon) | `--device mps` | macOS Apple 芯片 |\n| CPU | `--device cpu` | 慢，仅用于测试 |\n| 自动 | `--device auto` | 自动选择最佳设备（默认） |\n\n| LLM 后端 | 参数 | 说明 |\n|-----------|------|------|\n| vLLM | `--lm-backend vllm` | CUDA 上最快，推荐 NVIDIA 使用 |\n| PyTorch | `--lm-backend pt` | 通用后端，所有平台可用 |\n| MLX | `--lm-backend mlx` | Apple Silicon 优化 |\n| 自动 | `--lm-backend auto` | 根据设备自动选择（默认） |\n\n---\n\n## 快速开始\n\n```bash\n# 基本分析（text2music，默认设置）\npython profile_inference.py\n\n# 启用 LLM 思考模式\npython profile_inference.py --thinking\n\n# 运行基准测试矩阵\npython profile_inference.py --mode benchmark\n\n# Apple Silicon 上测试\npython profile_inference.py --device mps --lm-backend mlx\n\n# 启用 cProfile 函数级分析\npython profile_inference.py --detailed\n```\n\n---\n\n## 测试模式\n\n### 1. `profile` — 单次运行分析\n\n运行单次生成，输出详细计时分解。包含可选的预热和 cProfile。\n\n```bash\npython profile_inference.py --mode profile\n```\n\n**测量内容：**\n- 总耗时（端到端）\n- LLM 规划耗时（token 生成、约束解码、CFG 开销）\n- DiT 扩散耗时（每步和总计）\n- VAE 解码耗时\n- 音频保存耗时\n\n**此模式的选项：**\n\n| 参数 | 说明 |\n|------|------|\n| `--no-warmup` | 跳过预热（测量将包含编译开销） |\n| `--detailed` | 启用 `cProfile` 函数级分析 |\n| `--llm-debug` | 深度 LLM 调试（token 数量、吞吐量） |\n| `--thinking` | 启用 LLM 思维链推理 |\n| `--duration <秒>` | 覆盖音频时长 |\n| `--batch-size <n>` | 覆盖批量大小 |\n| `--inference-steps <n>` | 覆盖扩散步数 |\n\n### 2. `benchmark` — 配置矩阵测试\n\n运行配置矩阵并输出汇总表。自动适配 GPU 显存限制。\n\n```bash\npython profile_inference.py --mode benchmark\n```\n\n**默认矩阵：**\n- 时长：30s, 60s, 120s, 240s（根据 GPU 显存裁剪）\n- 批量大小：1, 2, 4（根据 GPU 显存裁剪）\n- 思考模式：True, False\n- 推理步数：8, 16\n\n**输出示例：**\n\n```\nDuration   Batch   Think   Steps   Wall(s)    LM(s)      DiT(s)     VAE(s)     Status\n--------------------------------------------------------------------------------------------------------------------------\n30         1       False   8       3.21       0.45       1.89       0.52       OK\n30         1       True    8       5.67       2.91       1.89       0.52       OK\n60         2       False   16      12.34      0.48       9.12       1.85       OK\n...\n```\n\n**保存结果为 JSON：**\n\n```bash\npython profile_inference.py --mode benchmark --benchmark-output results.json\n```\n\n### 3. `understand` — 音频理解分析\n\n分析 `understand_music()` API，从音频 codes 提取元数据（BPM、调性、拍号、描述）。\n\n```bash\npython profile_inference.py --mode understand\npython profile_inference.py --mode understand --audio-codes \"your_audio_codes_string\"\n```\n\n### 4. `create_sample` — 灵感模式分析\n\n分析 `create_sample()` API，从简单文本查询生成完整歌曲蓝图。\n\n```bash\npython profile_inference.py --mode create_sample\npython profile_inference.py --mode create_sample --sample-query \"一首柔和的孟加拉情歌\"\npython profile_inference.py --mode create_sample --instrumental\n```\n\n### 5. `format_sample` — 元数据格式化分析\n\n分析 `format_sample()` API，将描述+歌词转换为结构化元数据。\n\n```bash\npython profile_inference.py --mode format_sample\n```\n\n### 6. `tier-test` — 自动化 GPU 等级测试\n\n使用 `MAX_CUDA_VRAM` 自动模拟不同的 GPU 显存大小，并在每个等级运行生成测试。这是修改 `acestep/gpu_config.py` 后验证所有 GPU 等级是否正常工作的推荐方式。\n\n```bash\n# 测试所有等级 (4, 6, 8, 12, 16, 20, 24 GB)\npython profile_inference.py --mode tier-test\n\n# 测试特定显存大小\npython profile_inference.py --mode tier-test --tiers 6 8 16\n\n# 启用 LM 测试（在支持的等级上）\npython profile_inference.py --mode tier-test --tier-with-lm\n\n# 快速测试：非量化等级跳过 torch.compile\npython profile_inference.py --mode tier-test --tier-skip-compile\n```\n\n**每个等级验证的内容：**\n- 正确的等级检测和 `GPUConfig` 构建\n- 模型初始化（DiT、VAE、文本编码器，可选 LM）\n- 短时间生成（30秒时长，batch=1）无 OOM 完成\n- 自适应 VAE 解码回退（GPU → CPU 卸载 → 完全 CPU）\n- 显存使用保持在模拟限制内\n\n**输出示例：**\n\n```\nTIER TEST RESULTS\n====================================================================================================\n  VRAM    Tier       LM      Duration   Status    Peak VRAM    Notes\n  ──────────────────────────────────────────────────────────────────────────────\n  4GB     tier1      —       30s        ✅ OK     3.8GB        VAE 在 CPU 上解码\n  6GB     tier2      —       30s        ✅ OK     5.4GB        分片 VAE chunk=256\n  8GB     tier4      0.6B    30s        ✅ OK     7.2GB        vllm 后端\n  12GB    tier5      1.7B    30s        ✅ OK     10.8GB       vllm 后端\n  16GB    tier6a     1.7B    30s        ✅ OK     14.5GB       启用卸载\n  20GB    tier6b     1.7B    30s        ✅ OK     17.2GB       无卸载\n  24GB    unlimited  4B      30s        ✅ OK     21.3GB       所有模型在 GPU 上\n```\n\n> **注意**: `tier-test` 模式使用 `torch.cuda.set_per_process_memory_fraction()` 强制执行显存硬上限，即使在高端 GPU（如 A100 80GB）上也能实现真实的模拟。\n\n#### 边界测试\n\n使用 `--tier-boundary` 查找可以安全关闭 INT8 量化和 CPU 卸载的最低显存等级。对每个等级最多测试三种配置：\n\n1. **default** — 等级的标准设置\n2. **no-quant** — 关闭量化，卸载不变\n3. **no-offload** — 不使用量化，也不使用 CPU 卸载\n\n```bash\n# 在所有等级运行边界测试\npython profile_inference.py --mode tier-test --tier-boundary\n\n# 启用 LM 的边界测试\npython profile_inference.py --mode tier-test --tier-boundary --tier-with-lm\n\n# 将边界测试结果保存为 JSON\npython profile_inference.py --mode tier-test --tier-boundary --benchmark-output boundary_results.json\n```\n\n输出包含一个 **边界分析** 摘要，显示每种能力的最低等级。\n\n#### 批次大小边界测试\n\n使用 `--tier-batch-boundary` 查找每个等级的最大安全批次大小。对每个等级，工具会递进测试批次大小 1、2、4、8（在首次 OOM 时停止），同时测试启用 LM 和未启用 LM 的配置：\n\n```bash\n# 运行批次边界测试\npython profile_inference.py --mode tier-test --tier-batch-boundary --tier-with-lm\n\n# 测试特定等级\npython profile_inference.py --mode tier-test --tier-batch-boundary --tier-with-lm --tiers 8 12 16 24\n```\n\n输出包含一个 **批次边界摘要**，显示每个等级在有 LM 和无 LM 配置下的最大成功批次大小。\n\n---\n\n## 命令行参数\n\n### 设备与后端\n\n| 参数 | 默认值 | 说明 |\n|------|--------|------|\n| `--device` | `auto` | 设备：`auto` / `cuda` / `mps` / `cpu` |\n| `--lm-backend` | `auto` | LLM 后端：`auto` / `vllm` / `pt` / `mlx` |\n\n### 模型路径\n\n| 参数 | 默认值 | 说明 |\n|------|--------|------|\n| `--config-path` | `acestep-v15-turbo` | DiT 模型配置 |\n| `--lm-model` | `acestep-5Hz-lm-1.7B` | LLM 模型路径 |\n\n### 硬件选项\n\n| 参数 | 默认值 | 说明 |\n|------|--------|------|\n| `--offload-to-cpu` | 关闭 | 不使用时卸载模型到 CPU |\n| `--offload-dit-to-cpu` | 关闭 | 不使用时卸载 DiT 到 CPU |\n| `--quantization` | 无 | 量化：`int8_weight_only` / `fp8_weight_only` / `w8a8_dynamic` |\n\n### 生成参数\n\n| 参数 | 默认值 | 说明 |\n|------|--------|------|\n| `--duration` | 来自示例 | 音频时长（秒） |\n| `--batch-size` | 来自示例 | 批量大小 |\n| `--inference-steps` | 来自示例 | 扩散推理步数 |\n| `--seed` | 来自示例 | 随机种子 |\n| `--guidance-scale` | 7.0 | DiT 的 CFG 引导缩放 |\n\n### LLM / CoT 参数\n\n| 参数 | 默认值 | 说明 |\n|------|--------|------|\n| `--thinking` | 关闭 | 启用 LLM 思维链推理 |\n| `--use-cot-metas` | 关闭 | LLM 通过 CoT 生成音乐元数据 |\n| `--use-cot-caption` | 关闭 | LLM 通过 CoT 改写/格式化描述 |\n| `--use-cot-language` | 关闭 | LLM 通过 CoT 检测人声语言 |\n| `--use-constrained-decoding` | 开启 | 基于 FSM 的约束解码 |\n| `--no-constrained-decoding` | — | 禁用约束解码 |\n| `--lm-temperature` | 0.85 | LLM 采样温度 |\n| `--lm-cfg-scale` | 2.0 | LLM CFG 缩放 |\n\n### 分析选项\n\n| 参数 | 默认值 | 说明 |\n|------|--------|------|\n| `--mode` | `profile` | 模式：`profile` / `benchmark` / `tier-test` / `understand` / `create_sample` / `format_sample` |\n| `--no-warmup` | 关闭 | 跳过预热 |\n| `--detailed` | 关闭 | 启用 `cProfile` 函数级分析 |\n| `--llm-debug` | 关闭 | 深度 LLM 调试（token 数量、吞吐量） |\n| `--benchmark-output` | 无 | 保存基准测试结果为 JSON 文件 |\n\n### 等级测试选项\n\n| 参数 | 默认值 | 说明 |\n|------|--------|------|\n| `--tiers` | `4 6 8 12 16 20 24` | 要模拟的显存大小（GB） |\n| `--tier-with-lm` | 关闭 | 在支持的等级上启用 LM 初始化 |\n| `--tier-skip-compile` | 关闭 | 非量化等级跳过 `torch.compile` 以加速迭代 |\n| `--tier-boundary` | 关闭 | 对每个等级测试 no-quant 和 no-offload 变体，查找最低能力边界 |\n| `--tier-batch-boundary` | 关闭 | 对每个等级测试批次大小 1、2、4、8，查找最大安全批次大小 |\n\n### 输入选项\n\n| 参数 | 默认值 | 说明 |\n|------|--------|------|\n| `--example` | `example_05.json` | `examples/text2music/` 中的示例 JSON |\n| `--task-type` | `text2music` | 任务类型：`text2music` / `cover` / `repaint` / `lego` / `extract` / `complete` |\n| `--reference-audio` | 无 | 参考音频路径（用于翻唱/风格迁移） |\n| `--src-audio` | 无 | 源音频路径（用于音频到音频任务） |\n| `--sample-query` | 无 | `create_sample` 模式的查询文本 |\n| `--instrumental` | 关闭 | 生成纯音乐（用于 `create_sample`） |\n| `--audio-codes` | 无 | 音频 codes 字符串（用于 `understand` 模式） |\n\n---\n\n## 使用示例\n\n### 对比不同设备\n\n```bash\n# NVIDIA GPU\npython profile_inference.py --device cuda --lm-backend vllm\n\n# Apple Silicon\npython profile_inference.py --device mps --lm-backend mlx\n\n# CPU 基线\npython profile_inference.py --device cpu --lm-backend pt\n```\n\n### 对比不同 LLM 模型\n\n```bash\n# 轻量版 (0.6B)\npython profile_inference.py --lm-model acestep-5Hz-lm-0.6B\n\n# 默认版 (1.7B)\npython profile_inference.py --lm-model acestep-5Hz-lm-1.7B\n\n# 大型版 (4B)\npython profile_inference.py --lm-model acestep-5Hz-lm-4B\n```\n\n### 思考模式 vs 非思考模式\n\n```bash\n# 不使用思考（更快）\npython profile_inference.py --mode benchmark\n\n# 使用思考（质量更好，更慢）\npython profile_inference.py --thinking --use-cot-metas --use-cot-caption\n```\n\n### 低显存测试\n\n```bash\n# 卸载 + 量化\npython profile_inference.py --offload-to-cpu --quantization int8_weight_only --lm-model acestep-5Hz-lm-0.6B\n```\n\n### 完整基准测试套件\n\n```bash\n# 运行完整基准测试矩阵并保存结果\npython profile_inference.py --mode benchmark --benchmark-output benchmark_results.json\n\n# 查看 JSON 结果\ncat benchmark_results.json | python -m json.tool\n```\n\n### 函数级分析\n\n```bash\n# 启用 cProfile 进行详细的函数级分析\npython profile_inference.py --detailed --llm-debug\n```\n\n---\n\n## 理解输出\n\n### 耗时分解\n\n分析器会打印详细的耗时分解：\n\n```\nTIME COSTS BREAKDOWN\n====================================================================================================\n  Component                          Time (s)       % of Total\n  ─────────────────────────────────────────────────────────────\n  LLM Planning (total)               2.91           45.2%\n    ├─ Token generation              2.45           38.1%\n    ├─ Constrained decoding          0.31            4.8%\n    └─ CFG overhead                  0.15            2.3%\n  DiT Diffusion (total)              1.89           29.4%\n    ├─ Per-step average              0.24            —\n    └─ Steps                         8               —\n  VAE Decode                         0.52            8.1%\n  Audio Save                         0.12            1.9%\n  Other / Overhead                   0.99           15.4%\n  ─────────────────────────────────────────────────────────────\n  Wall Time (total)                  6.43          100.0%\n```\n\n### 关键指标\n\n| 指标 | 说明 |\n|------|------|\n| **Wall Time** | 从开始到结束的端到端耗时 |\n| **LM Total Time** | LLM 规划耗时（token 生成 + 解析） |\n| **DiT Total Time** | 扩散耗时（所有步骤合计） |\n| **VAE Decode Time** | 将潜变量解码为音频波形的耗时 |\n| **Tokens/sec** | LLM token 生成吞吐量（需 `--llm-debug`） |\n\n---\n\n## 技巧与最佳实践\n\n1. **始终包含预热**（默认）— 首次运行包含 JIT 编译和内存分配开销。预热确保测量反映稳态性能。\n\n2. **使用 `--benchmark-output`** 将结果保存为 JSON，方便后续分析或跨硬件对比。\n\n3. **对比思考开启 vs 关闭** — 思考模式显著增加 LLM 耗时，但可能提升生成质量。\n\n4. **使用代表性时长测试** — 短时长（30s）以 LLM 耗时为主；长时长（240s+）以 DiT 耗时为主。\n\n5. **GPU 显存自动适配** — benchmark 模式会自动将时长和批量大小裁剪到 GPU 可处理的范围，使用 `acestep/gpu_config.py` 中的自适应等级系统。\n\n6. **谨慎使用 `--detailed`** — `cProfile` 会增加开销；仅在需要调查函数级瓶颈时使用。\n\n7. **使用 `tier-test` 进行回归测试** — 修改 GPU 等级配置后，运行 `--mode tier-test` 验证所有等级仍然正常工作。这在更改卸载阈值、时长限制或 LM 模型可用性时尤为重要。\n\n8. **真实模拟低显存** — 使用 `MAX_CUDA_VRAM` 时，系统通过 `set_per_process_memory_fraction()` 强制执行显存硬上限，因此模拟期间的 OOM 错误反映了消费级 GPU 上的真实行为。\n"
  },
  {
    "path": "docs/zh/GPU_COMPATIBILITY.md",
    "content": "# GPU 兼容性指南\n\nACE-Step 1.5 会自动适配您的 GPU 显存大小，相应调整生成时长限制、可用的 LM 模型、卸载策略和 UI 默认设置。系统在启动时检测 GPU 显存并自动配置最佳设置。\n\n## GPU 分级配置\n\n| 显存 | 等级 | LM 模型 | 推荐 LM | 后端 | 最大时长 (有LM / 无LM) | 最大批次 (有LM / 无LM) | 卸载策略 | 量化 |\n|------|------|---------|---------|------|------------------------|------------------------|----------|------|\n| ≤4GB | Tier 1 | 无 | — | pt | 4分 / 6分 | 1 / 1 | CPU + DiT | INT8 |\n| 4-6GB | Tier 2 | 无 | — | pt | 8分 / 10分 | 1 / 1 | CPU + DiT | INT8 |\n| 6-8GB | Tier 3 | 0.6B | 0.6B | pt | 8分 / 10分 | 2 / 2 | CPU + DiT | INT8 |\n| 8-12GB | Tier 4 | 0.6B | 0.6B | vllm | 8分 / 10分 | 2 / 4 | CPU + DiT | INT8 |\n| 12-16GB | Tier 5 | 0.6B, 1.7B | 1.7B | vllm | 8分 / 10分 | 4 / 4 | CPU | INT8 |\n| 16-20GB | Tier 6a | 0.6B, 1.7B | 1.7B | vllm | 8分 / 10分 | 4 / 8 | CPU | INT8 |\n| 20-24GB | Tier 6b | 0.6B, 1.7B, 4B | 1.7B | vllm | 8分 / 8分 | 8 / 8 | 无 | 无 |\n| ≥24GB | 无限制 | 全部 (0.6B, 1.7B, 4B) | 4B | vllm | 10分 / 10分 | 8 / 8 | 无 | 无 |\n\n### 列说明\n\n- **LM 模型**: 该等级可以加载的 5Hz 语言模型尺寸\n- **推荐 LM**: UI 中该等级默认选择的 LM 模型\n- **后端**: LM 推理后端（`vllm` 用于显存充足的 NVIDIA GPU，`pt` 为 PyTorch 回退方案，`mlx` 用于 Apple Silicon）\n- **卸载策略**:\n  - **CPU + DiT**: 所有模型（DiT、VAE、文本编码器）不使用时卸载到 CPU；DiT 也在步骤间卸载\n  - **CPU**: VAE 和文本编码器卸载到 CPU；DiT 保留在 GPU 上\n  - **无**: 所有模型保留在 GPU 上\n- **量化**: 是否默认启用 INT8 权重量化以减少显存占用\n\n## 自适应 UI 默认设置\n\nGradio UI 会根据检测到的 GPU 等级自动配置：\n\n- **LM 初始化复选框**: 支持 LM 的等级（Tier 3+）默认勾选，Tier 1-2 默认不勾选且禁用\n- **LM 模型路径**: 自动填充该等级推荐的模型；下拉菜单仅显示兼容的模型\n- **后端下拉菜单**: Tier 1-3 限制为 `pt`/`mlx`（vllm KV 缓存占用过大）；Tier 4+ 所有后端可用\n- **CPU 卸载 / DiT 卸载**: 低等级默认启用，高等级默认禁用\n- **量化**: Tier 1-6a 默认启用，Tier 6b+ 默认禁用（显存充足）\n- **模型编译**: 所有等级默认启用（量化需要）\n\n如果您手动选择了不兼容的选项（例如在 6GB GPU 上使用 vllm），系统会发出警告并自动回退到兼容配置。\n\n## 运行时安全特性\n\n- **显存守卫**: 每次推理前，系统会估算显存需求，必要时自动减小批次大小\n- **自适应 VAE 解码**: 三级回退机制：GPU 分片解码 → GPU 解码+结果卸载到 CPU → 完全 CPU 解码\n- **自动分片大小**: VAE 解码分片大小根据可用空闲显存自适应调整（64/128/256/512/1024/1536）\n- **时长/批次裁剪**: 如果请求的值超出等级限制，会自动裁剪并显示警告\n\n## 说明\n\n- **默认设置** 会根据检测到的 GPU 显存自动配置\n- **LM 模式** 指用于思维链 (Chain-of-Thought) 生成和音频理解的语言模型\n- **Flash Attention** 会自动检测并在可用时启用\n- **约束解码**: 当 LM 初始化后，LM 生成的时长也会被约束在 GPU 等级的最大时长限制内，防止在 CoT 生成时出现显存不足错误\n- 对于显存 ≤6GB 的 GPU（Tier 1-2），默认禁用 LM 初始化以保留显存给 DiT 模型\n- 您可以通过命令行参数或 Gradio UI 手动覆盖设置\n\n> **欢迎社区贡献**: 以上 GPU 分级配置基于我们在常见硬件上的测试。如果您发现您的设备实际性能与这些参数不符（例如，可以处理更长的时长或更大的批次），欢迎您进行更充分的测试，并提交 PR 来优化 `acestep/gpu_config.py` 中的配置。您的贡献将帮助改善所有用户的体验！\n\n## 显存优化建议\n\n1. **极低显存 (≤6GB)**: 使用纯 DiT 模式，不初始化 LM。INT8 量化和完全 CPU 卸载是必须的。VAE 解码可能会自动回退到 CPU。\n2. **低显存 (6-8GB)**: 可使用 0.6B LM 模型，配合 `pt` 后端。保持卸载启用。\n3. **中等显存 (8-16GB)**: 使用 0.6B 或 1.7B LM 模型。Tier 4+ 上 `vllm` 后端表现良好。\n4. **高显存 (16-24GB)**: 启用更大的 LM 模型（推荐 1.7B）。20GB+ 量化变为可选。\n5. **超高显存 (≥24GB)**: 所有模型无需卸载或量化即可运行。使用 4B LM 获得最佳质量。\n\n## 调试模式：模拟不同的 GPU 配置\n\n在测试和开发时，您可以使用 `MAX_CUDA_VRAM` 环境变量来模拟不同的 GPU 显存大小：\n\n```bash\n# 模拟 4GB GPU (Tier 1)\nMAX_CUDA_VRAM=4 uv run acestep\n\n# 模拟 6GB GPU (Tier 2)\nMAX_CUDA_VRAM=6 uv run acestep\n\n# 模拟 8GB GPU (Tier 4)\nMAX_CUDA_VRAM=8 uv run acestep\n\n# 模拟 12GB GPU (Tier 5)\nMAX_CUDA_VRAM=12 uv run acestep\n\n# 模拟 16GB GPU (Tier 6a)\nMAX_CUDA_VRAM=16 uv run acestep\n```\n\n设置 `MAX_CUDA_VRAM` 时，系统还会调用 `torch.cuda.set_per_process_memory_fraction()` 来强制执行显存硬上限，即使在高端 GPU 上也能实现真实的模拟。\n\n### 自动化分级测试\n\n无需通过 UI 手动测试每个等级，可以使用 `profile_inference.py` 的 `tier-test` 模式：\n\n```bash\n# 自动测试所有等级\npython profile_inference.py --mode tier-test\n\n# 测试特定等级\npython profile_inference.py --mode tier-test --tiers 6 8 16\n\n# 测试时启用 LM（在支持的等级上）\npython profile_inference.py --mode tier-test --tier-with-lm\n\n# 快速测试（非量化等级跳过 torch.compile）\npython profile_inference.py --mode tier-test --tier-skip-compile\n```\n\n详见 [BENCHMARK.md](BENCHMARK.md) 获取性能分析工具的完整文档。\n\n适用场景：\n- 在高端硬件上测试 GPU 分级配置\n- 验证各等级的警告和限制是否正常工作\n- 修改 `acestep/gpu_config.py` 后的自动化回归测试\n- CI/CD 显存兼容性验证\n\n### 边界测试（查找最低等级）\n\n使用 `--tier-boundary` 可以通过实际运行来确定从哪个显存等级开始可以安全地关闭 INT8 量化和 CPU 卸载。对于每个等级，最多运行三种配置：\n\n1. **default** — 该等级的默认设置（按配置使用量化 + 卸载）\n2. **no-quant** — 保持卸载设置不变，但关闭量化\n3. **no-offload** — 不使用量化，也不使用 CPU 卸载（所有模型保留在 GPU 上）\n\n```bash\n# 在所有等级上运行边界测试\npython profile_inference.py --mode tier-test --tier-boundary\n\n# 测试特定等级的边界\npython profile_inference.py --mode tier-test --tier-boundary --tiers 8 12 16 20 24\n\n# 启用 LM 的边界测试（在支持的等级上）\npython profile_inference.py --mode tier-test --tier-boundary --tier-with-lm\n\n# 将结果保存为 JSON 以便进一步分析\npython profile_inference.py --mode tier-test --tier-boundary --benchmark-output boundary_results.json\n```\n\n输出包含一个 **边界分析** 部分，显示每种能力的最低等级：\n\n```\nBOUNDARY ANALYSIS\n=================\n  Capability                                    Min Tier   VRAM\n  ------------------------------------------------------------\n  No INT8 Quantization                          tier6b      20GB\n  No CPU Offload (all models on GPU)            tier6b      20GB\n  ------------------------------------------------------------\n```\n\n> **注意：** 边界测试结果是经验性的，可能因 DiT 模型变体（turbo vs base）、是否启用 LM、生成时长和 flash attention 可用性而有所不同。欢迎社区贡献来完善这些边界值！\n\n### 批次大小边界测试\n\n使用 `--tier-batch-boundary` 通过递进测试批次大小 1、2、4、8 来查找每个等级的最大安全批次大小：\n\n```bash\n# 运行启用 LM 的批次边界测试\npython profile_inference.py --mode tier-test --tier-batch-boundary --tier-with-lm\n\n# 测试特定等级\npython profile_inference.py --mode tier-test --tier-batch-boundary --tier-with-lm --tiers 8 12 16 24\n```\n\n该测试同时测试有 LM 和无 LM 的配置，并报告每个等级的最大成功批次大小。\n"
  },
  {
    "path": "docs/zh/GRADIO_GUIDE.md",
    "content": "# ACE-Step Gradio 演示用户指南\n\n**Language / 语言 / 言語:** [English](../en/GRADIO_GUIDE.md) | [中文](GRADIO_GUIDE.md) | [日本語](../ja/GRADIO_GUIDE.md)\n\n---\n\n本指南提供使用 ACE-Step Gradio Web 界面进行音乐生成的综合文档，包括所有功能和设置。\n\n## 目录\n\n- [快速开始](#快速开始)\n- [服务配置](#服务配置)\n- [生成模式](#生成模式)\n- [输入参数](#输入参数)\n- [高级设置](#高级设置)\n- [结果区域](#结果区域)\n- [LoRA 训练](#lora-训练)\n- [技巧与最佳实践](#技巧与最佳实践)\n\n---\n\n## 快速开始\n\n### 启动演示\n\n```bash\n# 基本启动\npython app.py\n\n# 预初始化\npython app.py --config acestep-v15-turbo --init-llm\n\n# 指定端口\npython app.py --port 7860\n```\n\n### 界面概述\n\nGradio 界面布局如下：\n\n1. **设置**（折叠式手风琴）- 服务配置、DiT/LM 参数、输出选项\n2. **生成标签页** - 主工作区，顶部有**生成模式**单选选择器：\n   - Turbo/SFT 模型：Simple、Custom、Remix、Repaint\n   - Base 模型：Simple、Custom、Remix、Repaint、Extract、Lego、Complete\n3. **结果区域** - 生成的音频播放、评分、批次导航\n4. **训练标签页** - 数据集构建器和 LoRA 训练\n\n---\n\n## 服务配置\n\n### 模型选择\n\n| 设置 | 说明 |\n|---------|-------------|\n| **检查点文件** | 选择已训练的模型检查点（如果可用）|\n| **主模型路径** | 选择 DiT 模型配置（例如 `acestep-v15-turbo`、`acestep-v15-turbo-shift3`）|\n| **设备** | 处理设备：`auto`（推荐）、`cuda` 或 `cpu` |\n\n### 5Hz LM 配置\n\n| 设置 | 说明 |\n|---------|-------------|\n| **5Hz LM 模型路径** | 选择语言模型。**可用模型根据 GPU 等级自动过滤** — 例如，6-8GB GPU 仅显示 0.6B，而 24GB+ GPU 显示所有尺寸（0.6B、1.7B、4B）。|\n| **5Hz LM 后端** | `vllm`（更快，推荐显存 ≥8GB 的 NVIDIA GPU）、`pt`（PyTorch，通用回退方案）或 `mlx`（Apple Silicon）。**显存 <8GB 的 GPU 限制为 `pt`/`mlx`**，因为 vllm 的 KV 缓存占用过大。|\n| **初始化 5Hz LM** | 勾选以在初始化期间加载 LM（thinking 模式必需）。**显存 ≤6GB 的 GPU（Tier 1-2）默认不勾选且禁用。**|\n\n> **自适应默认设置**: 所有 LM 设置根据 GPU 显存等级自动配置。推荐的 LM 模型、后端和初始化状态已预设为最佳性能。您可以手动覆盖，但如果选择与 GPU 不兼容，系统会发出警告。\n\n### 性能选项\n\n| 设置 | 说明 |\n|---------|-------------|\n| **使用 Flash Attention** | 启用以加速推理（需要 flash_attn 包）|\n| **卸载到 CPU** | 空闲时将模型卸载到 CPU 以节省 GPU 显存。**显存 <20GB 的 GPU 默认自动启用。**|\n| **将 DiT 卸载到 CPU** | 专门将 DiT 模型卸载到 CPU。**显存 <12GB 的 GPU 默认自动启用。**|\n| **INT8 量化** | 使用 INT8 权重量化减少模型显存占用。**显存 <20GB 的 GPU 默认自动启用。**|\n| **模型编译** | 启用 `torch.compile` 优化推理。**所有等级默认启用**（量化激活时必需）。|\n\n> **等级感知设置**: 卸载、量化和编译选项根据 GPU 等级自动设置。详见 [GPU_COMPATIBILITY.md](GPU_COMPATIBILITY.md) 了解完整的等级表。\n\n### LoRA 适配器\n\n| 设置 | 说明 |\n|---------|-------------|\n| **LoRA 路径** | 已训练的 LoRA 适配器目录路径 |\n| **加载 LoRA** | 加载指定的 LoRA 适配器 |\n| **卸载** | 移除当前加载的 LoRA |\n| **使用 LoRA** | 启用/禁用已加载的 LoRA 进行推理 |\n\n> **⚠️ 注意：** 由于 PEFT 和 TorchAO 之间的兼容性问题，无法在量化模型上加载 LoRA 适配器。如果需要使用 LoRA，请在加载适配器之前将 **INT8 量化** 设置为 **None**。\n\n### 初始化\n\n点击 **初始化服务** 加载模型。状态框将显示进度和确认信息，包括：\n- 检测到的 GPU 等级和显存\n- 最大允许时长和批次大小（根据是否初始化了 LM 动态调整）\n- 任何不兼容设置被自动修正的警告\n\n初始化后，**音频时长** 和 **批量大小** 滑块会自动更新以反映等级限制。\n\n---\n\n## 生成模式\n\n生成标签页顶部的**生成模式**单选选择器决定了你的工作流。Turbo 和 SFT 模型提供四种模式；Base 模型额外增加三种。\n\n### Simple 模式\n\n专为快速、基于自然语言的音乐生成设计。\n\n**使用方法：**\n1. 在生成模式中选择 **Simple**\n2. 在\"歌曲描述\"字段中输入自然语言描述\n3. 如果不想要人声，可选择勾选\"纯音乐\"\n4. 可选择首选人声语言\n5. 点击 **创建样本** 生成 caption、歌词和元数据\n6. 在展开的部分中查看生成的内容\n7. 点击 **生成音乐** 创建音频\n\n**示例描述：**\n- \"一首适合安静夜晚的柔和孟加拉情歌\"\n- \"欢快的电子舞曲，重低音\"\n- \"忧郁的独立民谣，原声吉他\"\n- \"在烟雾弥漫的酒吧里演奏的爵士三重奏\"\n\n**随机样本：** 点击 🎲 按钮加载随机示例描述。\n\n### Custom 模式\n\n完全控制所有生成参数（text2music）。\n\n**使用方法：**\n1. 在生成模式中选择 **Custom**\n2. 手动填写 Caption 和歌词字段\n3. 可选上传参考音频用于风格引导\n4. 设置可选元数据（BPM、调性、时长等）\n5. 可选点击 **格式化** 使用 LM 增强您的输入\n6. 根据需要配置高级设置\n7. 点击 **生成音乐** 创建音频\n\n### Remix 模式\n\n保持现有音频的旋律结构，同时改变风格。\n\n**使用方法：**\n1. 在生成模式中选择 **Remix**\n2. 上传源音频（要 remix 的歌曲）\n3. 编写描述目标风格的 Caption\n4. 可选修改歌词\n5. 调整 **Remix 强度**（0.0-1.0）：越高 = 越接近原始结构\n6. 点击 **生成音乐**\n\n**用例：** 创建翻唱版本、风格迁移、生成歌曲变体。\n\n### Repaint 模式\n\n重新生成音频的特定时间段，保持其余部分不变。\n\n**使用方法：**\n1. 在生成模式中选择 **Repaint**\n2. 上传源音频\n3. 设置**重绘开始**和**重绘结束**（秒；-1 表示文件末尾）\n4. 编写描述重绘部分期望内容的 Caption\n5. 点击 **生成音乐**\n\n**用例：** 修复有问题的部分、修改某段歌词、延长歌曲。\n\n### Extract 模式（仅 Base 模型）\n\n从混音音频中提取/分离特定乐器轨道。\n\n**使用方法：**\n1. 在生成模式中选择 **Extract**\n2. 上传源音频\n3. 从下拉菜单中选择要提取的**轨道名称**\n4. 点击 **生成音乐**\n\n**可用轨道：** vocals、backing_vocals、drums、bass、guitar、keyboard、percussion、strings、synth、fx、brass、woodwinds\n\n### Lego 模式（仅 Base 模型）\n\n为现有音频添加新的乐器轨道。\n\n**使用方法：**\n1. 在生成模式中选择 **Lego**\n2. 上传源音频\n3. 从下拉菜单中选择要添加的**轨道名称**\n4. 编写描述轨道特征的 Caption\n5. 点击 **生成音乐**\n\n### Complete 模式（仅 Base 模型）\n\n用指定的乐器完成部分轨道（自动编排）。\n\n**使用方法：**\n1. 在生成模式中选择 **Complete**\n2. 上传源音频\n3. 选择多个要添加的**轨道名称**\n4. 编写描述期望风格的 Caption\n5. 点击 **生成音乐**\n\n---\n\n## 输入参数\n\n### 音频输入\n\n| 字段 | 说明 |\n|-------|-------------|\n| **参考音频** | 用于风格/音色引导的可选音频（Custom 模式下可见） |\n| **源音频** | Remix、Repaint、Extract、Lego、Complete 模式必需 |\n| **转换为代码** | 从源音频提取 5Hz 语义代码 |\n\n#### LM 代码提示（Custom 模式）\n\n可以在此粘贴预计算的音频语义代码来引导生成。使用 **转录** 按钮分析代码并提取元数据。这是一个高级功能，用于在不上传源音频的情况下控制旋律结构。\n\n### 音乐描述\n\n期望音乐的文本描述。请具体说明：\n- 风格和类型\n- 乐器\n- 情绪和氛围\n- 节奏感（如果不指定 BPM）\n\n**示例：** \"欢快的流行摇滚，电吉他、有力的鼓点和朗朗上口的合成器钩子\"\n\n点击 🎲 加载随机示例 caption。\n\n### 歌词\n\n输入带结构标签的歌词：\n\n```\n[Verse 1]\n今天走在街上\n想着你曾说过的话\n\n[Chorus]\n我在前进，我很坚强\n这就是我属于的地方\n\n[Verse 2]\n...\n```\n\n**纯音乐复选框：** 勾选此项以生成纯音乐，无论歌词内容如何。\n\n**人声语言：** 选择人声语言。对于自动检测或纯音乐，使用\"unknown\"。\n\n**格式化按钮：** 点击使用 5Hz LM 增强 caption 和歌词。\n\n### 可选参数\n\n| 参数 | 默认值 | 说明 |\n|-----------|---------|-------------|\n| **BPM** | 自动 | 每分钟节拍数（30-300）|\n| **调性** | 自动 | 音乐调性（例如\"C Major\"、\"Am\"、\"F# minor\"）|\n| **拍号** | 自动 | 拍号：2（2/4）、3（3/4）、4（4/4）、6（6/8）|\n| **音频时长** | 自动/-1 | 目标长度（秒）（10-600）。-1 为自动 |\n| **批量大小** | 2 | 要生成的音频变体数量（1-8）|\n\n---\n\n## 高级设置\n\n### DiT 参数\n\n| 参数 | 默认值 | 说明 |\n|-----------|---------|-------------|\n| **推理步数** | 8 | 去噪步数。Turbo：1-20，Base：1-200 |\n| **引导比例** | 7.0 | CFG 强度（仅 base 模型）。越高 = 越遵循提示 |\n| **种子** | -1 | 随机种子。批量使用逗号分隔的值 |\n| **随机种子** | ✓ | 勾选时生成随机种子 |\n| **音频格式** | mp3 | 输出格式：mp3、flac |\n| **偏移** | 3.0 | 时间步偏移因子（1.0-5.0）。turbo 推荐 3.0 |\n| **推理方法** | ode | ode（Euler，更快）或 sde（随机）|\n| **自定义时间步** | - | 覆盖时间步（例如\"0.97,0.76,0.615,0.5,0.395,0.28,0.18,0.085,0\"）|\n\n### 仅 Base 模型参数\n\n| 参数 | 默认值 | 说明 |\n|-----------|---------|-------------|\n| **使用 ADG** | ✗ | 启用自适应双引导以获得更好的质量 |\n| **CFG 区间开始** | 0.0 | 何时开始应用 CFG（0.0-1.0）|\n| **CFG 区间结束** | 1.0 | 何时停止应用 CFG（0.0-1.0）|\n\n### LM 参数\n\n| 参数 | 默认值 | 说明 |\n|-----------|---------|-------------|\n| **LM 温度** | 0.85 | 采样温度（0.0-2.0）。越高 = 越有创意 |\n| **LM CFG 比例** | 2.0 | LM 引导强度（1.0-3.0）|\n| **LM Top-K** | 0 | Top-K 采样。0 禁用 |\n| **LM Top-P** | 0.9 | 核采样（0.0-1.0）|\n| **LM 负面提示** | \"NO USER INPUT\" | CFG 的负面提示 |\n\n### CoT（思维链）选项\n\n| 选项 | 默认值 | 说明 |\n|--------|---------|-------------|\n| **CoT Metas** | ✓ | 通过 LM 推理生成元数据 |\n| **CoT Language** | ✓ | 通过 LM 检测人声语言 |\n| **约束解码调试** | ✗ | 启用调试日志 |\n\n### 生成选项\n\n| 选项 | 默认值 | 说明 |\n|--------|---------|-------------|\n| **LM 代码强度** | 1.0 | LM 代码对生成的影响程度（0.0-1.0）|\n| **自动评分** | ✗ | 自动计算质量分数 |\n| **自动 LRC** | ✗ | 自动生成歌词时间戳 |\n| **LM 批处理块大小** | 8 | 每个 LM 批次的最大项目数（GPU 内存）|\n\n### 主要生成控制\n\n| 控制 | 说明 |\n|---------|-------------|\n| **Think** | 启用 5Hz LM 进行代码生成和元数据 |\n| **ParallelThinking** | 启用并行 LM 批处理 |\n| **CaptionRewrite** | 让 LM 增强输入 caption |\n| **AutoGen** | 完成后自动开始下一批次 |\n\n---\n\n## 结果区域\n\n### 生成的音频\n\n根据批量大小最多显示 8 个音频样本。每个样本包括：\n\n- **音频播放器** - 播放、暂停和下载生成的音频\n- **发送到源** - 将此音频发送到源音频输入以进行进一步处理\n- **保存** - 将音频和元数据保存到 JSON 文件\n- **评分** - 计算基于困惑度的质量分数\n- **LRC** - 生成歌词时间戳（LRC 格式）\n\n### 详情折叠面板\n\n点击\"评分 & LRC & LM 代码\"展开并查看：\n- **LM 代码** - 此样本的 5Hz 语义代码\n- **质量分数** - 基于困惑度的质量指标\n- **歌词时间戳** - LRC 格式的时间数据\n\n### 批次导航\n\n| 控制 | 说明 |\n|---------|-------------|\n| **◀ 上一批** | 查看上一批 |\n| **批次指示器** | 显示当前批次位置（例如\"批次 1 / 3\"）|\n| **下一批状态** | 显示后台生成进度 |\n| **下一批 ▶** | 查看下一批（如果 AutoGen 开启则触发生成）|\n\n### 恢复参数\n\n点击 **应用这些设置到 UI** 将当前批次的所有生成参数恢复到输入字段。适用于迭代优化好的结果。\n\n### 批次结果\n\n\"批次结果和生成详情\"折叠面板包含：\n- **所有生成的文件** - 下载所有批次的所有文件\n- **生成详情** - 关于生成过程的详细信息\n\n---\n\n## LoRA 训练\n\nLoRA 训练选项卡提供创建自定义 LoRA 适配器的工具。\n\n> 📖 **完整的分步教程**（数据准备、标注、预处理、训练和导出），请参阅 [LoRA 训练教程](./LoRA_Training_Tutorial.md)。\n\n### 数据集构建器选项卡\n\n#### 步骤 1：加载或扫描\n\n**选项 A：加载现有数据集**\n1. 输入之前保存的数据集 JSON 路径\n2. 点击 **加载**\n\n**选项 B：扫描新目录**\n1. 输入音频文件夹路径\n2. 点击 **扫描** 查找音频文件（wav、mp3、flac、ogg、opus）\n\n#### 步骤 2：配置数据集\n\n| 设置 | 说明 |\n|---------|-------------|\n| **数据集名称** | 您的数据集名称 |\n| **全部纯音乐** | 如果所有曲目都没有人声，请勾选 |\n| **自定义激活标签** | 激活此 LoRA 风格的唯一标签 |\n| **标签位置** | 放置标签的位置：前置、追加或替换 caption |\n\n#### 步骤 3：自动标注\n\n点击 **自动标注全部** 为所有音频文件生成元数据：\n- Caption（音乐描述）\n- BPM\n- 调性\n- 拍号\n\n**跳过 Metas** 选项将跳过 LLM 标注并使用 N/A 值。\n\n#### 步骤 4：预览和编辑\n\n使用滑块选择样本并手动编辑：\n- Caption\n- 歌词\n- BPM、调性、拍号\n- 语言\n- 纯音乐标志\n\n点击 **保存更改** 更新样本。\n\n#### 步骤 5：保存数据集\n\n输入保存路径并点击 **保存数据集** 导出为 JSON。\n\n#### 步骤 6：预处理\n\n将数据集转换为预计算张量以加快训练：\n1. 可选加载现有数据集 JSON\n2. 设置张量输出目录\n3. 点击 **预处理**\n\n这会将音频编码为 VAE 潜变量，将文本编码为嵌入，并运行条件编码器。\n\n### 训练 LoRA 选项卡\n\n#### 数据集选择\n\n输入预处理张量目录路径并点击 **加载数据集**。\n\n#### LoRA 设置\n\n| 设置 | 默认值 | 说明 |\n|---------|---------|-------------|\n| **LoRA 秩 (r)** | 64 | LoRA 容量。越高 = 容量越大，内存越多 |\n| **LoRA Alpha** | 128 | 缩放因子（通常是秩的 2 倍）|\n| **LoRA Dropout** | 0.1 | 用于正则化的 dropout 率 |\n\n#### 训练参数\n\n| 设置 | 默认值 | 说明 |\n|---------|---------|-------------|\n| **学习率** | 1e-4 | 优化学习率 |\n| **最大 Epochs** | 500 | 最大训练 epochs |\n| **批量大小** | 1 | 训练批量大小 |\n| **梯度累积** | 1 | 有效批次 = batch_size × accumulation |\n| **每 N Epochs 保存** | 200 | 检查点保存频率 |\n| **偏移** | 3.0 | turbo 模型的时间步偏移 |\n| **种子** | 42 | 用于可重复性的随机种子 |\n\n#### 训练控制\n\n- **开始训练** - 开始训练过程\n- **停止训练** - 中断训练\n- **训练进度** - 显示当前 epoch 和损失\n- **训练日志** - 详细训练输出\n- **训练损失图** - 可视化损失曲线\n\n#### 导出 LoRA\n\n训练后，导出最终适配器：\n1. 输入导出路径\n2. 点击 **导出 LoRA**\n\n---\n\n## 技巧与最佳实践\n\n### 获得最佳质量\n\n1. **使用 thinking 模式** - 保持\"Think\"复选框启用以获得 LM 增强的生成\n2. **具体描述 caption** - 包含风格、乐器、情绪和风格细节\n3. **让 LM 检测元数据** - 将 BPM/调性/时长留空以自动检测\n4. **使用批量生成** - 生成 2-4 个变体并选择最好的\n\n### 加快生成速度\n\n1. **使用 turbo 模型** - 选择 `acestep-v15-turbo` 或 `acestep-v15-turbo-shift3`\n2. **保持推理步数为 8** - 这是 turbo 的最佳默认值\n3. **减少批量大小** - 如果需要快速结果，降低批量大小\n4. **禁用 AutoGen** - 手动控制批次生成\n\n### 获得一致结果\n\n1. **设置特定种子** - 取消勾选\"随机种子\"并输入种子值\n2. **保存好的结果** - 使用\"保存\"导出参数以便重现\n3. **使用\"应用这些设置\"** - 从好的批次恢复参数\n\n### 长格式音乐\n\n1. **设置明确的时长** - 以秒为单位指定时长\n2. **使用 repaint 任务** - 初始生成后修复有问题的部分\n3. **链式生成** - 使用\"发送到源\"在之前的结果上构建\n\n### 风格一致性\n\n1. **训练 LoRA** - 为您的风格创建自定义适配器\n2. **使用参考音频** - 在音频上传中上传风格参考\n3. **使用一致的 caption** - 保持相似的描述性语言\n\n### 故障排除\n\n**没有生成音频：**\n- 检查模型是否已初始化（绿色状态消息）\n- 如果使用 thinking 模式，确保 5Hz LM 已初始化\n- 检查状态输出中的错误消息\n\n**结果质量差：**\n- 增加推理步数（对于 base 模型）\n- 调整引导比例\n- 尝试不同的种子\n- 使 caption 更具体\n\n**显存不足 (OOM)：**\n- 系统包含自动显存管理（显存守卫、自适应 VAE 解码、自动批次减小）。如果仍然 OOM：\n- 手动减少批量大小\n- 启用 CPU 卸载（显存 <20GB 应已自动启用）\n- 启用 INT8 量化（显存 <20GB 应已自动启用）\n- 减少 LM 批处理块大小\n- 详见 [GPU_COMPATIBILITY.md](GPU_COMPATIBILITY.md) 了解各等级推荐设置\n\n**LM 不工作：**\n- 确保初始化期间勾选了\"初始化 5Hz LM\"（显存 ≤6GB 的 GPU 默认禁用）\n- 检查是否选择了有效的 LM 模型路径（仅显示与等级兼容的模型）\n- 验证 vllm 或 PyTorch 后端可用（显存 <8GB 限制使用 vllm）\n- 如果 LM 复选框灰色不可用，说明您的 GPU 等级不支持 LM — 请使用纯 DiT 模式\n\n---\n\n## 键盘快捷键\n\nGradio 界面支持标准 Web 快捷键：\n- **Tab** - 在输入字段之间移动\n- **Enter** - 提交文本输入\n- **Space** - 切换复选框\n\n---\n\n## 语言支持\n\n界面支持多种 UI 语言：\n- **英文** (en)\n- **中文** (zh)\n- **日文** (ja)\n\n在服务配置区域选择您的首选语言。\n\n---\n\n更多信息，请参阅：\n- 主 README：[`../../README.md`](../../README.md)\n- REST API 文档：[`API.md`](API.md)\n- Python 推理 API：[`INFERENCE.md`](INFERENCE.md)\n"
  },
  {
    "path": "docs/zh/INFERENCE.md",
    "content": "# ACE-Step 推理 API 文档\n\n**Language / 语言 / 言語:** [English](../en/INFERENCE.md) | [中文](INFERENCE.md) | [日本語](../ja/INFERENCE.md)\n\n---\n\n本文档提供 ACE-Step 推理 API 的综合文档，包括所有支持任务类型的参数规范。\n\n## 目录\n\n- [快速开始](#快速开始)\n- [API 概述](#api-概述)\n- [GenerationParams 参数](#generationparams-参数)\n- [GenerationConfig 参数](#generationconfig-参数)\n- [任务类型](#任务类型)\n- [辅助函数](#辅助函数)\n- [完整示例](#完整示例)\n- [最佳实践](#最佳实践)\n\n---\n\n## 快速开始\n\n### 基本用法\n\n```python\nfrom acestep.handler import AceStepHandler\nfrom acestep.llm_inference import LLMHandler\nfrom acestep.inference import GenerationParams, GenerationConfig, generate_music\n\n# 初始化处理器\ndit_handler = AceStepHandler()\nllm_handler = LLMHandler()\n\n# 初始化服务\ndit_handler.initialize_service(\n    project_root=\"/path/to/project\",\n    config_path=\"acestep-v15-turbo\",\n    device=\"cuda\"\n)\n\nllm_handler.initialize(\n    checkpoint_dir=\"/path/to/checkpoints\",\n    lm_model_path=\"acestep-5Hz-lm-0.6B\",\n    backend=\"vllm\",\n    device=\"cuda\"\n)\n\n# 配置生成参数\nparams = GenerationParams(\n    caption=\"欢快的电子舞曲，重低音\",\n    bpm=128,\n    duration=30,\n)\n\n# 配置生成设置\nconfig = GenerationConfig(\n    batch_size=2,\n    audio_format=\"flac\",\n)\n\n# 生成音乐\nresult = generate_music(dit_handler, llm_handler, params, config, save_dir=\"/path/to/output\")\n\n# 访问结果\nif result.success:\n    for audio in result.audios:\n        print(f\"已生成：{audio['path']}\")\n        print(f\"Key：{audio['key']}\")\n        print(f\"Seed：{audio['params']['seed']}\")\nelse:\n    print(f\"错误：{result.error}\")\n```\n\n---\n\n## API 概述\n\n### 主要函数\n\n#### generate_music\n\n```python\ndef generate_music(\n    dit_handler,\n    llm_handler,\n    params: GenerationParams,\n    config: GenerationConfig,\n    save_dir: Optional[str] = None,\n    progress=None,\n) -> GenerationResult\n```\n\n使用 ACE-Step 模型生成音乐的主函数。\n\n#### understand_music\n\n```python\ndef understand_music(\n    llm_handler,\n    audio_codes: str,\n    temperature: float = 0.85,\n    top_k: Optional[int] = None,\n    top_p: Optional[float] = None,\n    repetition_penalty: float = 1.0,\n    use_constrained_decoding: bool = True,\n    constrained_decoding_debug: bool = False,\n) -> UnderstandResult\n```\n\n分析音频语义代码并提取元数据（caption、lyrics、BPM、调性等）。\n\n#### create_sample\n\n```python\ndef create_sample(\n    llm_handler,\n    query: str,\n    instrumental: bool = False,\n    vocal_language: Optional[str] = None,\n    temperature: float = 0.85,\n    top_k: Optional[int] = None,\n    top_p: Optional[float] = None,\n    repetition_penalty: float = 1.0,\n    use_constrained_decoding: bool = True,\n    constrained_decoding_debug: bool = False,\n) -> CreateSampleResult\n```\n\n从自然语言描述生成完整的音乐样本（caption、lyrics、元数据）。\n\n#### format_sample\n\n```python\ndef format_sample(\n    llm_handler,\n    caption: str,\n    lyrics: str,\n    user_metadata: Optional[Dict[str, Any]] = None,\n    temperature: float = 0.85,\n    top_k: Optional[int] = None,\n    top_p: Optional[float] = None,\n    repetition_penalty: float = 1.0,\n    use_constrained_decoding: bool = True,\n    constrained_decoding_debug: bool = False,\n) -> FormatSampleResult\n```\n\n格式化和增强用户提供的 caption 和 lyrics，生成结构化元数据。\n\n### 配置对象\n\nAPI 使用两个配置数据类：\n\n**GenerationParams** - 包含所有音乐生成参数：\n\n```python\n@dataclass\nclass GenerationParams:\n    # 任务和指令\n    task_type: str = \"text2music\"\n    instruction: str = \"Fill the audio semantic mask based on the given conditions:\"\n    \n    # 音频上传\n    reference_audio: Optional[str] = None\n    src_audio: Optional[str] = None\n    \n    # LM 代码提示\n    audio_codes: str = \"\"\n    \n    # 文本输入\n    caption: str = \"\"\n    lyrics: str = \"\"\n    instrumental: bool = False\n    \n    # 元数据\n    vocal_language: str = \"unknown\"\n    bpm: Optional[int] = None\n    keyscale: str = \"\"\n    timesignature: str = \"\"\n    duration: float = -1.0\n    \n    # 高级设置\n    inference_steps: int = 8\n    seed: int = -1\n    guidance_scale: float = 7.0\n    use_adg: bool = False\n    cfg_interval_start: float = 0.0\n    cfg_interval_end: float = 1.0\n    shift: float = 1.0                    # 新增：时间步偏移因子\n    infer_method: str = \"ode\"             # 新增：扩散推理方法\n    timesteps: Optional[List[float]] = None  # 新增：自定义时间步\n    \n    repainting_start: float = 0.0\n    repainting_end: float = -1\n    audio_cover_strength: float = 1.0\n    \n    # 5Hz 语言模型参数\n    thinking: bool = True\n    lm_temperature: float = 0.85\n    lm_cfg_scale: float = 2.0\n    lm_top_k: int = 0\n    lm_top_p: float = 0.9\n    lm_negative_prompt: str = \"NO USER INPUT\"\n    use_cot_metas: bool = True\n    use_cot_caption: bool = True\n    use_cot_lyrics: bool = False\n    use_cot_language: bool = True\n    use_constrained_decoding: bool = True\n    \n    # CoT 生成的值（由 LM 自动填充）\n    cot_bpm: Optional[int] = None\n    cot_keyscale: str = \"\"\n    cot_timesignature: str = \"\"\n    cot_duration: Optional[float] = None\n    cot_vocal_language: str = \"unknown\"\n    cot_caption: str = \"\"\n    cot_lyrics: str = \"\"\n```\n\n**GenerationConfig** - 包含批处理和输出配置：\n\n```python\n@dataclass\nclass GenerationConfig:\n    batch_size: int = 2\n    allow_lm_batch: bool = False\n    use_random_seed: bool = True\n    seeds: Optional[List[int]] = None\n    lm_batch_chunk_size: int = 8\n    constrained_decoding_debug: bool = False\n    audio_format: str = \"flac\"\n```\n\n### 结果对象\n\n**GenerationResult** - 音乐生成结果：\n\n```python\n@dataclass\nclass GenerationResult:\n    # 音频输出\n    audios: List[Dict[str, Any]]  # 音频字典列表\n    \n    # 生成信息\n    status_message: str           # 生成状态消息\n    extra_outputs: Dict[str, Any] # 额外输出（latents、masks、lm_metadata、time_costs）\n    \n    # 成功状态\n    success: bool                 # 生成是否成功\n    error: Optional[str]          # 失败时的错误消息\n```\n\n**音频字典结构：**\n\n`audios` 列表中的每个项目包含：\n\n```python\n{\n    \"path\": str,           # 保存的音频文件路径\n    \"tensor\": Tensor,      # 音频张量 [channels, samples]，CPU，float32\n    \"key\": str,            # 唯一音频键（基于参数的 UUID）\n    \"sample_rate\": int,    # 采样率（默认：48000）\n    \"params\": Dict,        # 此音频的生成参数（包括 seed、audio_codes 等）\n}\n```\n\n**UnderstandResult** - 音乐理解结果：\n\n```python\n@dataclass\nclass UnderstandResult:\n    # 元数据字段\n    caption: str = \"\"\n    lyrics: str = \"\"\n    bpm: Optional[int] = None\n    duration: Optional[float] = None\n    keyscale: str = \"\"\n    language: str = \"\"\n    timesignature: str = \"\"\n    \n    # 状态\n    status_message: str = \"\"\n    success: bool = True\n    error: Optional[str] = None\n```\n\n**CreateSampleResult** - 样本创建结果：\n\n```python\n@dataclass\nclass CreateSampleResult:\n    # 元数据字段\n    caption: str = \"\"\n    lyrics: str = \"\"\n    bpm: Optional[int] = None\n    duration: Optional[float] = None\n    keyscale: str = \"\"\n    language: str = \"\"\n    timesignature: str = \"\"\n    instrumental: bool = False\n    \n    # 状态\n    status_message: str = \"\"\n    success: bool = True\n    error: Optional[str] = None\n```\n\n**FormatSampleResult** - 样本格式化结果：\n\n```python\n@dataclass\nclass FormatSampleResult:\n    # 元数据字段\n    caption: str = \"\"\n    lyrics: str = \"\"\n    bpm: Optional[int] = None\n    duration: Optional[float] = None\n    keyscale: str = \"\"\n    language: str = \"\"\n    timesignature: str = \"\"\n    \n    # 状态\n    status_message: str = \"\"\n    success: bool = True\n    error: Optional[str] = None\n```\n\n---\n\n## GenerationParams 参数\n\n### 文本输入\n\n| 参数 | 类型 | 默认值 | 说明 |\n|-----------|------|---------|-------------|\n| `caption` | `str` | `\"\"` | 期望音乐的文本描述。可以是简单提示如\"放松的钢琴音乐\"，或包含风格、情绪、乐器等的详细描述。最多 512 字符。|\n| `lyrics` | `str` | `\"\"` | 人声音乐的歌词文本。纯音乐使用 `\"[Instrumental]\"`。支持多种语言。最多 4096 字符。|\n| `instrumental` | `bool` | `False` | 如果为 True，无论歌词如何都生成纯音乐。|\n\n### 音乐元数据\n\n| 参数 | 类型 | 默认值 | 说明 |\n|-----------|------|---------|-------------|\n| `bpm` | `Optional[int]` | `None` | 每分钟节拍数（30-300）。`None` 启用通过 LM 自动检测。|\n| `keyscale` | `str` | `\"\"` | 音乐调性（例如\"C Major\"、\"Am\"、\"F# minor\"）。空字符串启用自动检测。|\n| `timesignature` | `str` | `\"\"` | 拍号（2 表示 '2/4'，3 表示 '3/4'，4 表示 '4/4'，6 表示 '6/8'）。空字符串启用自动检测。|\n| `vocal_language` | `str` | `\"unknown\"` | 人声语言代码（ISO 639-1）。支持：`\"en\"`、`\"zh\"`、`\"ja\"`、`\"es\"`、`\"fr\"` 等。使用 `\"unknown\"` 自动检测。|\n| `duration` | `float` | `-1.0` | 目标音频长度（秒）（10-600）。如果 <= 0 或 None，模型根据歌词长度自动选择。|\n\n### 生成参数\n\n| 参数 | 类型 | 默认值 | 说明 |\n|-----------|------|---------|-------------|\n| `inference_steps` | `int` | `8` | 去噪步数。Turbo 模型：1-20（推荐 8）。Base 模型：1-200（推荐 32-64）。越高 = 质量越好但更慢。|\n| `guidance_scale` | `float` | `7.0` | 无分类器引导比例（1.0-15.0）。较高的值增加对文本提示的遵循度。仅支持非 turbo 模型。典型范围：5.0-9.0。|\n| `seed` | `int` | `-1` | 用于可重复性的随机种子。使用 `-1` 表示随机种子，或任何正整数表示固定种子。|\n\n### 高级 DiT 参数\n\n| 参数 | 类型 | 默认值 | 说明 |\n|-----------|------|---------|-------------|\n| `use_adg` | `bool` | `False` | 使用自适应双引导（仅 base 模型）。以速度为代价提高质量。|\n| `cfg_interval_start` | `float` | `0.0` | CFG 应用起始比例（0.0-1.0）。控制何时开始应用无分类器引导。|\n| `cfg_interval_end` | `float` | `1.0` | CFG 应用结束比例（0.0-1.0）。控制何时停止应用无分类器引导。|\n| `shift` | `float` | `1.0` | 时间步偏移因子（范围 1.0-5.0，默认 1.0）。当 != 1.0 时，对时间步应用 `t = shift * t / (1 + (shift - 1) * t)`。turbo 模型推荐 3.0。|\n| `infer_method` | `str` | `\"ode\"` | 扩散推理方法。`\"ode\"`（Euler）更快且确定性。`\"sde\"`（随机）可能产生不同的带方差结果。|\n| `timesteps` | `Optional[List[float]]` | `None` | 自定义时间步，从 1.0 到 0.0 的浮点数列表（例如 `[0.97, 0.76, 0.615, 0.5, 0.395, 0.28, 0.18, 0.085, 0]`）。如果提供，覆盖 `inference_steps` 和 `shift`。|\n\n### 任务特定参数\n\n| 参数 | 类型 | 默认值 | 说明 |\n|-----------|------|---------|-------------|\n| `task_type` | `str` | `\"text2music\"` | 生成任务类型。详见[任务类型](#任务类型)部分。|\n| `instruction` | `str` | `\"Fill the audio semantic mask based on the given conditions:\"` | 任务特定指令提示。|\n| `reference_audio` | `Optional[str]` | `None` | 用于风格迁移或续写任务的参考音频文件路径。|\n| `src_audio` | `Optional[str]` | `None` | 用于音频到音频任务（cover、repaint 等）的源音频文件路径。|\n| `audio_codes` | `str` | `\"\"` | 预提取的 5Hz 音频语义代码字符串。仅供高级使用。|\n| `repainting_start` | `float` | `0.0` | 重绘开始时间（秒）（用于 repaint/lego 任务）。|\n| `repainting_end` | `float` | `-1` | 重绘结束时间（秒）。使用 `-1` 表示音频末尾。|\n| `audio_cover_strength` | `float` | `1.0` | 音频 cover/代码影响强度（0.0-1.0）。风格迁移任务设置较小值（0.2）。|\n\n### 5Hz 语言模型参数\n\n| 参数 | 类型 | 默认值 | 说明 |\n|-----------|------|---------|-------------|\n| `thinking` | `bool` | `True` | 启用 5Hz 语言模型\"思维链\"推理用于语义/音乐元数据和代码。|\n| `lm_temperature` | `float` | `0.85` | LM 采样温度（0.0-2.0）。越高 = 更有创意/多样，越低 = 更保守。|\n| `lm_cfg_scale` | `float` | `2.0` | LM 无分类器引导比例。越高 = 更强的提示遵循度。|\n| `lm_top_k` | `int` | `0` | LM top-k 采样。`0` 禁用 top-k 过滤。典型值：40-100。|\n| `lm_top_p` | `float` | `0.9` | LM 核采样（0.0-1.0）。`1.0` 禁用核采样。典型值：0.9-0.95。|\n| `lm_negative_prompt` | `str` | `\"NO USER INPUT\"` | LM 引导的负面提示。帮助避免不想要的特征。|\n| `use_cot_metas` | `bool` | `True` | 使用 LM CoT 推理生成元数据（BPM、调性、时长等）。|\n| `use_cot_caption` | `bool` | `True` | 使用 LM CoT 推理优化用户 caption。|\n| `use_cot_language` | `bool` | `True` | 使用 LM CoT 推理检测人声语言。|\n| `use_cot_lyrics` | `bool` | `False` | （保留供将来使用）使用 LM CoT 生成/优化歌词。|\n| `use_constrained_decoding` | `bool` | `True` | 启用结构化 LM 输出的约束解码。|\n\n### CoT 生成的值\n\n这些字段在启用 CoT 推理时由 LM 自动填充：\n\n| 参数 | 类型 | 默认值 | 说明 |\n|-----------|------|---------|-------------|\n| `cot_bpm` | `Optional[int]` | `None` | LM 生成的 BPM 值。|\n| `cot_keyscale` | `str` | `\"\"` | LM 生成的调性。|\n| `cot_timesignature` | `str` | `\"\"` | LM 生成的拍号。|\n| `cot_duration` | `Optional[float]` | `None` | LM 生成的时长。|\n| `cot_vocal_language` | `str` | `\"unknown\"` | LM 检测的人声语言。|\n| `cot_caption` | `str` | `\"\"` | LM 优化的 caption。|\n| `cot_lyrics` | `str` | `\"\"` | LM 生成/优化的歌词。|\n\n---\n\n## GenerationConfig 参数\n\n| 参数 | 类型 | 默认值 | 说明 |\n|-----------|------|---------|-------------|\n| `batch_size` | `int` | `2` | 并行生成的样本数量（1-8）。较高的值需要更多 GPU 内存。|\n| `allow_lm_batch` | `bool` | `False` | 允许 LM 批处理。当 `batch_size >= 2` 且 `thinking=True` 时更快。|\n| `use_random_seed` | `bool` | `True` | 是否使用随机种子。`True` 每次不同结果，`False` 可重复结果。|\n| `seeds` | `Optional[List[int]]` | `None` | 批量生成的种子列表。如果提供的种子少于 batch_size，将用随机种子填充。也可以是单个 int。|\n| `lm_batch_chunk_size` | `int` | `8` | 每个 LM 推理块的最大批处理大小（GPU 内存限制）。|\n| `constrained_decoding_debug` | `bool` | `False` | 启用约束解码的调试日志。|\n| `audio_format` | `str` | `\"flac\"` | 输出音频格式。选项：`\"mp3\"`、`\"wav\"`、`\"flac\"`。默认 FLAC 以快速保存。|\n\n---\n\n## 任务类型\n\nACE-Step 支持 6 种不同的生成任务类型，每种都针对特定用例进行了优化。\n\n### 1. Text2Music（默认）\n\n**目的**：从文本描述和可选元数据生成音乐。\n\n**关键参数**：\n```python\nparams = GenerationParams(\n    task_type=\"text2music\",\n    caption=\"充满活力的摇滚音乐，电吉他\",\n    lyrics=\"[Instrumental]\",  # 或实际歌词\n    bpm=140,\n    duration=30,\n)\n```\n\n**必需**：\n- `caption` 或 `lyrics`（至少一个）\n\n**可选但推荐**：\n- `bpm`：控制节奏\n- `keyscale`：控制音乐调性\n- `timesignature`：控制节拍结构\n- `duration`：控制长度\n- `vocal_language`：控制人声特征\n\n**用例**：\n- 从文本描述生成音乐\n- 从提示创建伴奏\n- 生成带歌词的歌曲\n\n---\n\n### 2. Cover\n\n**目的**：转换现有音频，保持结构但改变风格/音色。\n\n**关键参数**：\n```python\nparams = GenerationParams(\n    task_type=\"cover\",\n    src_audio=\"original_song.mp3\",\n    caption=\"爵士钢琴版本\",\n    audio_cover_strength=0.8,  # 0.0-1.0\n)\n```\n\n**必需**：\n- `src_audio`：源音频文件路径\n- `caption`：期望风格/转换的描述\n\n**可选**：\n- `audio_cover_strength`：控制原始音频的影响\n  - `1.0`：强烈保持原始结构\n  - `0.5`：平衡转换\n  - `0.1`：宽松解读\n- `lyrics`：新歌词（如果要更改人声）\n\n**用例**：\n- 创建不同风格的翻唱\n- 在保持旋律的同时更改乐器\n- 风格转换\n\n---\n\n### 3. Repaint\n\n**目的**：重新生成音频的特定时间段，保持其余部分不变。\n\n**关键参数**：\n```python\nparams = GenerationParams(\n    task_type=\"repaint\",\n    src_audio=\"original.mp3\",\n    repainting_start=10.0,  # 秒\n    repainting_end=20.0,    # 秒\n    caption=\"带钢琴独奏的平滑过渡\",\n)\n```\n\n**必需**：\n- `src_audio`：源音频文件路径\n- `repainting_start`：开始时间（秒）\n- `repainting_end`：结束时间（秒）（使用 `-1` 表示文件末尾）\n- `caption`：重绘部分期望内容的描述\n\n**用例**：\n- 修复生成音乐的特定部分\n- 为歌曲的某些部分添加变化\n- 创建平滑过渡\n- 替换有问题的片段\n\n---\n\n### 4. Lego（仅 Base 模型）\n\n**目的**：在现有音频的上下文中生成特定乐器轨道。\n\n**关键参数**：\n```python\nparams = GenerationParams(\n    task_type=\"lego\",\n    src_audio=\"backing_track.mp3\",\n    instruction=\"Generate the guitar track based on the audio context:\",\n    caption=\"带有蓝调感觉的主音吉他旋律\",\n    repainting_start=0.0,\n    repainting_end=-1,\n)\n```\n\n**必需**：\n- `src_audio`：源/伴奏音频路径\n- `instruction`：必须指定轨道类型（例如\"Generate the {TRACK_NAME} track...\"）\n- `caption`：期望轨道特征的描述\n\n**可用轨道**：\n- `\"vocals\"`、`\"backing_vocals\"`、`\"drums\"`、`\"bass\"`、`\"guitar\"`、`\"keyboard\"`、\n- `\"percussion\"`、`\"strings\"`、`\"synth\"`、`\"fx\"`、`\"brass\"`、`\"woodwinds\"`\n\n**用例**：\n- 添加特定乐器轨道\n- 在伴奏轨道上叠加额外乐器\n- 迭代创建多轨作品\n\n---\n\n### 5. Extract（仅 Base 模型）\n\n**目的**：从混音音频中提取/分离特定乐器轨道。\n\n**关键参数**：\n```python\nparams = GenerationParams(\n    task_type=\"extract\",\n    src_audio=\"full_mix.mp3\",\n    instruction=\"Extract the vocals track from the audio:\",\n)\n```\n\n**必需**：\n- `src_audio`：混音音频文件路径\n- `instruction`：必须指定要提取的轨道\n\n**可用轨道**：与 Lego 任务相同\n\n**用例**：\n- 音轨分离\n- 分离特定乐器\n- 创建混音\n- 分析单独轨道\n\n---\n\n### 6. Complete（仅 Base 模型）\n\n**目的**：用指定的乐器完成/扩展部分轨道。\n\n**关键参数**：\n```python\nparams = GenerationParams(\n    task_type=\"complete\",\n    src_audio=\"incomplete_track.mp3\",\n    instruction=\"Complete the input track with drums, bass, guitar:\",\n    caption=\"摇滚风格完成\",\n)\n```\n\n**必需**：\n- `src_audio`：不完整/部分轨道的路径\n- `instruction`：必须指定要添加的轨道\n- `caption`：期望风格的描述\n\n**用例**：\n- 编排不完整的作品\n- 添加伴奏轨道\n- 自动完成音乐想法\n\n---\n\n## 辅助函数\n\n### understand_music\n\n分析音频代码以提取音乐元数据。\n\n```python\nfrom acestep.inference import understand_music\n\nresult = understand_music(\n    llm_handler=llm_handler,\n    audio_codes=\"<|audio_code_123|><|audio_code_456|>...\",\n    temperature=0.85,\n    use_constrained_decoding=True,\n)\n\nif result.success:\n    print(f\"Caption：{result.caption}\")\n    print(f\"歌词：{result.lyrics}\")\n    print(f\"BPM：{result.bpm}\")\n    print(f\"调性：{result.keyscale}\")\n    print(f\"时长：{result.duration}s\")\n    print(f\"语言：{result.language}\")\nelse:\n    print(f\"错误：{result.error}\")\n```\n\n**用例**：\n- 分析现有音乐\n- 从音频代码提取元数据\n- 逆向工程生成参数\n\n---\n\n### create_sample\n\n从自然语言描述生成完整的音乐样本。这是\"简单模式\"/\"灵感模式\"功能。\n\n```python\nfrom acestep.inference import create_sample\n\nresult = create_sample(\n    llm_handler=llm_handler,\n    query=\"一首适合安静夜晚的柔和孟加拉情歌\",\n    instrumental=False,\n    vocal_language=\"bn\",  # 可选：限制为孟加拉语\n    temperature=0.85,\n)\n\nif result.success:\n    print(f\"Caption：{result.caption}\")\n    print(f\"歌词：{result.lyrics}\")\n    print(f\"BPM：{result.bpm}\")\n    print(f\"时长：{result.duration}s\")\n    print(f\"调性：{result.keyscale}\")\n    print(f\"是否纯音乐：{result.instrumental}\")\n    \n    # 与 generate_music 一起使用\n    params = GenerationParams(\n        caption=result.caption,\n        lyrics=result.lyrics,\n        bpm=result.bpm,\n        duration=result.duration,\n        keyscale=result.keyscale,\n        vocal_language=result.language,\n    )\nelse:\n    print(f\"错误：{result.error}\")\n```\n\n**参数**：\n\n| 参数 | 类型 | 默认值 | 说明 |\n|-----------|------|---------|-------------|\n| `query` | `str` | 必需 | 期望音乐的自然语言描述 |\n| `instrumental` | `bool` | `False` | 是否生成纯音乐 |\n| `vocal_language` | `Optional[str]` | `None` | 将歌词限制为特定语言（例如\"en\"、\"zh\"、\"bn\"）|\n| `temperature` | `float` | `0.85` | 采样温度 |\n| `top_k` | `Optional[int]` | `None` | Top-k 采样（None 禁用）|\n| `top_p` | `Optional[float]` | `None` | Top-p 采样（None 禁用）|\n| `repetition_penalty` | `float` | `1.0` | 重复惩罚 |\n| `use_constrained_decoding` | `bool` | `True` | 使用基于 FSM 的约束解码 |\n\n---\n\n### format_sample\n\n格式化和增强用户提供的 caption 和 lyrics，生成结构化元数据。\n\n```python\nfrom acestep.inference import format_sample\n\nresult = format_sample(\n    llm_handler=llm_handler,\n    caption=\"拉丁流行，雷鬼音\",\n    lyrics=\"[Verse 1]\\nBailando en la noche...\",\n    user_metadata={\"bpm\": 95},  # 可选：约束特定值\n    temperature=0.85,\n)\n\nif result.success:\n    print(f\"增强后的 Caption：{result.caption}\")\n    print(f\"格式化后的歌词：{result.lyrics}\")\n    print(f\"BPM：{result.bpm}\")\n    print(f\"时长：{result.duration}s\")\n    print(f\"调性：{result.keyscale}\")\n    print(f\"检测到的语言：{result.language}\")\nelse:\n    print(f\"错误：{result.error}\")\n```\n\n**参数**：\n\n| 参数 | 类型 | 默认值 | 说明 |\n|-----------|------|---------|-------------|\n| `caption` | `str` | 必需 | 用户的 caption/描述 |\n| `lyrics` | `str` | 必需 | 用户的带结构标签的歌词 |\n| `user_metadata` | `Optional[Dict]` | `None` | 约束特定元数据值（bpm、duration、keyscale、timesignature、language）|\n| `temperature` | `float` | `0.85` | 采样温度 |\n| `top_k` | `Optional[int]` | `None` | Top-k 采样（None 禁用）|\n| `top_p` | `Optional[float]` | `None` | Top-p 采样（None 禁用）|\n| `repetition_penalty` | `float` | `1.0` | 重复惩罚 |\n| `use_constrained_decoding` | `bool` | `True` | 使用基于 FSM 的约束解码 |\n\n---\n\n## 完整示例\n\n### 示例 1：简单文本到音乐生成\n\n```python\nfrom acestep.inference import GenerationParams, GenerationConfig, generate_music\n\nparams = GenerationParams(\n    task_type=\"text2music\",\n    caption=\"宁静的氛围音乐，柔和的钢琴和弦乐\",\n    duration=60,\n    bpm=80,\n    keyscale=\"C Major\",\n)\n\nconfig = GenerationConfig(\n    batch_size=2,  # 生成 2 个变体\n    audio_format=\"flac\",\n)\n\nresult = generate_music(dit_handler, llm_handler, params, config, save_dir=\"/output\")\n\nif result.success:\n    for i, audio in enumerate(result.audios, 1):\n        print(f\"变体 {i}：{audio['path']}\")\n```\n\n### 示例 2：带歌词的歌曲生成\n\n```python\nparams = GenerationParams(\n    task_type=\"text2music\",\n    caption=\"流行民谣，情感人声\",\n    lyrics=\"\"\"Verse 1:\n今天走在街上\n想着你曾说过的话\n一切都变得不同了\n但我会找到自己的路\n\nChorus:\n我在前进，我很坚强\n这就是我属于的地方\n\"\"\",\n    vocal_language=\"zh\",\n    bpm=72,\n    duration=45,\n)\n\nconfig = GenerationConfig(batch_size=1)\n\nresult = generate_music(dit_handler, llm_handler, params, config, save_dir=\"/output\")\n```\n\n### 示例 3：使用自定义时间步\n\n```python\nparams = GenerationParams(\n    task_type=\"text2music\",\n    caption=\"复杂和声的爵士融合\",\n    # 自定义 9 步调度\n    timesteps=[0.97, 0.76, 0.615, 0.5, 0.395, 0.28, 0.18, 0.085, 0],\n    thinking=True,\n)\n\nconfig = GenerationConfig(batch_size=1)\n\nresult = generate_music(dit_handler, llm_handler, params, config, save_dir=\"/output\")\n```\n\n### 示例 4：使用 Shift 参数（Turbo 模型）\n\n```python\nparams = GenerationParams(\n    task_type=\"text2music\",\n    caption=\"欢快的电子舞曲\",\n    inference_steps=8,\n    shift=3.0,  # Turbo 模型推荐\n    infer_method=\"ode\",\n)\n\nconfig = GenerationConfig(batch_size=2)\n\nresult = generate_music(dit_handler, llm_handler, params, config, save_dir=\"/output\")\n```\n\n### 示例 5：使用 create_sample 的简单模式\n\n```python\nfrom acestep.inference import create_sample, GenerationParams, GenerationConfig, generate_music\n\n# 步骤 1：从描述创建样本\nsample = create_sample(\n    llm_handler=llm_handler,\n    query=\"充满活力的韩国流行舞曲，带有朗朗上口的 Hook\",\n    vocal_language=\"ko\",\n)\n\nif sample.success:\n    # 步骤 2：使用样本生成音乐\n    params = GenerationParams(\n        caption=sample.caption,\n        lyrics=sample.lyrics,\n        bpm=sample.bpm,\n        duration=sample.duration,\n        keyscale=sample.keyscale,\n        vocal_language=sample.language,\n        thinking=True,\n    )\n    \n    config = GenerationConfig(batch_size=2)\n    result = generate_music(dit_handler, llm_handler, params, config, save_dir=\"/output\")\n```\n\n### 示例 6：格式化和增强用户输入\n\n```python\nfrom acestep.inference import format_sample, GenerationParams, GenerationConfig, generate_music\n\n# 步骤 1：格式化用户输入\nformatted = format_sample(\n    llm_handler=llm_handler,\n    caption=\"摇滚民谣\",\n    lyrics=\"[Verse]\\n在黑暗中我找到了自己的路...\",\n)\n\nif formatted.success:\n    # 步骤 2：使用增强后的输入生成\n    params = GenerationParams(\n        caption=formatted.caption,\n        lyrics=formatted.lyrics,\n        bpm=formatted.bpm,\n        duration=formatted.duration,\n        keyscale=formatted.keyscale,\n        thinking=True,\n        use_cot_metas=False,  # 已格式化，跳过元数据 CoT\n    )\n    \n    config = GenerationConfig(batch_size=2)\n    result = generate_music(dit_handler, llm_handler, params, config, save_dir=\"/output\")\n```\n\n---\n\n## 最佳实践\n\n### 1. Caption 写作\n\n**好的 Caption**：\n```python\n# 具体且描述性强\ncaption=\"欢快的电子舞曲，重低音和合成器主旋律\"\n\n# 包含情绪和风格\ncaption=\"忧郁的独立民谣，原声吉他和柔和的人声\"\n\n# 指定乐器\ncaption=\"爵士三重奏，钢琴、立式贝斯和刷子鼓\"\n```\n\n**避免**：\n```python\n# 太模糊\ncaption=\"好音乐\"\n\n# 矛盾\ncaption=\"快慢音乐\"  # 节奏冲突\n```\n\n### 2. 参数调优\n\n**最佳质量**：\n- 使用 base 模型，`inference_steps=64` 或更高\n- 启用 `use_adg=True`\n- 设置 `guidance_scale=7.0-9.0`\n- 设置 `shift=3.0` 以获得更好的时间步分布\n- 使用无损音频格式（`audio_format=\"wav\"`）\n\n**追求速度**：\n- 使用 turbo 模型，`inference_steps=8`\n- 禁用 ADG（`use_adg=False`）\n- 使用 `infer_method=\"ode\"`（默认）\n- 使用压缩格式（`audio_format=\"mp3\"`）或默认 FLAC\n\n**一致性**：\n- 在 config 中设置 `use_random_seed=False`\n- 使用固定的 `seeds` 列表或在 params 中使用单个 `seed`\n- 保持较低的 `lm_temperature`（0.7-0.85）\n\n**多样性**：\n- 在 config 中设置 `use_random_seed=True`\n- 增加 `lm_temperature`（0.9-1.1）\n- 使用 `batch_size > 1` 获得变体\n\n### 3. 时长指南\n\n- **纯音乐**：30-180 秒效果良好\n- **带歌词**：推荐自动检测（设置 `duration=-1` 或保持默认）\n- **短片段**：最少 10-20 秒\n- **长格式**：最多 600 秒（10 分钟）\n\n### 4. LM 使用\n\n**何时启用 LM（`thinking=True`）**：\n- 需要自动元数据检测\n- 想要 caption 优化\n- 从最少输入生成\n- 需要多样化输出\n\n**何时禁用 LM（`thinking=False`）**：\n- 已有精确的元数据\n- 需要更快的生成\n- 想要完全控制参数\n\n### 5. 批处理\n\n```python\n# 高效批量生成\nconfig = GenerationConfig(\n    batch_size=8,           # 支持的最大值\n    allow_lm_batch=True,    # 启用以提速（当 thinking=True 时）\n    lm_batch_chunk_size=4,  # 根据 GPU 内存调整\n)\n```\n\n### 6. 错误处理\n\n```python\nresult = generate_music(dit_handler, llm_handler, params, config, save_dir=\"/output\")\n\nif not result.success:\n    print(f\"生成失败：{result.error}\")\n    print(f\"状态：{result.status_message}\")\nelse:\n    # 处理成功结果\n    for audio in result.audios:\n        path = audio['path']\n        key = audio['key']\n        seed = audio['params']['seed']\n        # ... 处理音频文件\n```\n\n### 7. 显存管理\n\nACE-Step 1.5 包含自动显存管理，可适应您的 GPU：\n\n- **自动等级检测**: 系统检测可用显存并选择最佳设置（详见 [GPU_COMPATIBILITY.md](../zh/GPU_COMPATIBILITY.md)）\n- **显存守卫**: 每次推理前，系统估算显存需求，必要时自动减小 `batch_size`\n- **自适应 VAE 解码**: 三级回退 — GPU 分片解码 → GPU 解码+CPU 卸载 → 完全 CPU 解码\n- **自动分片大小**: VAE 解码分片大小根据空闲显存自适应调整（64/128/256/512/1024/1536）\n- **时长/批次裁剪**: 超出等级限制的值会自动裁剪并显示警告\n\n手动调优：\n- 如果仍然出现 OOM 错误，减少 `batch_size`\n- 低显存 GPU 上减少 `lm_batch_chunk_size` 用于 LM 操作\n- 显存 <20GB 时启用 `offload_to_cpu=True`\n- 显存 <20GB 时启用 `quantization=\"int8_weight_only\"`\n\n---\n\n## 故障排除\n\n### 常见问题\n\n**问题**：显存不足 (OOM) 错误\n- **解决方案**：系统应通过显存守卫（自动减小批次）和自适应 VAE 解码（CPU 回退）自动处理大多数 OOM 场景。如果仍然出现 OOM：减少 `batch_size`、减少 `inference_steps`、启用 CPU 卸载（`offload_to_cpu=True`）或启用 INT8 量化。详见 [GPU_COMPATIBILITY.md](../zh/GPU_COMPATIBILITY.md) 了解各显存等级的推荐设置。\n\n**问题**：结果质量差\n- **解决方案**：增加 `inference_steps`，调整 `guidance_scale`，使用 base 模型\n\n**问题**：结果与提示不匹配\n- **解决方案**：使 caption 更具体，增加 `guidance_scale`，启用 LM 优化（`thinking=True`）\n\n**问题**：生成缓慢\n- **解决方案**：使用 turbo 模型，减少 `inference_steps`，禁用 ADG\n\n**问题**：LM 不生成代码\n- **解决方案**：验证 `llm_handler` 已初始化，检查 `thinking=True` 和 `use_cot_metas=True`\n\n**问题**：种子不被尊重\n- **解决方案**：在 config 中设置 `use_random_seed=False` 并提供 `seeds` 列表或在 params 中提供 `seed`\n\n**问题**：自定义时间步不工作\n- **解决方案**：确保时间步是从 1.0 到 0.0 的浮点数列表，正确排序\n\n---\n\n## 版本历史\n\n- **v1.5.2**：当前版本\n  - 添加了 `shift` 参数用于时间步偏移\n  - 添加了 `infer_method` 参数用于 ODE/SDE 选择\n  - 添加了 `timesteps` 参数用于自定义时间步调度\n  - 添加了 `understand_music()` 函数用于音频分析\n  - 添加了 `create_sample()` 函数用于简单模式生成\n  - 添加了 `format_sample()` 函数用于输入增强\n  - 添加了 `UnderstandResult`、`CreateSampleResult`、`FormatSampleResult` 数据类\n\n- **v1.5.1**：上一版本\n  - 将 `GenerationConfig` 拆分为 `GenerationParams` 和 `GenerationConfig`\n  - 重命名参数以保持一致性（`key_scale` → `keyscale`、`time_signature` → `timesignature`、`audio_duration` → `duration`、`use_llm_thinking` → `thinking`、`audio_code_string` → `audio_codes`）\n  - 添加了 `instrumental` 参数\n  - 添加了 `use_constrained_decoding` 参数\n  - 添加了 CoT 自动填充字段（`cot_*`）\n  - 将默认 `audio_format` 更改为 \"flac\"\n  - 将默认 `batch_size` 更改为 2\n  - 将默认 `thinking` 更改为 True\n  - 简化了 `GenerationResult` 结构，统一 `audios` 列表\n  - 在 `extra_outputs` 中添加了统一的 `time_costs`\n\n- **v1.5**：初始版本\n  - 引入了 `GenerationConfig` 和 `GenerationResult` 数据类\n  - 简化了参数传递\n  - 添加了综合文档\n\n---\n\n更多信息，请参阅：\n- 主 README：[`../../README.md`](../../README.md)\n- REST API 文档：[`API.md`](API.md)\n- Gradio 演示指南：[`GRADIO_GUIDE.md`](GRADIO_GUIDE.md)\n- 项目仓库：[ACE-Step-1.5](https://github.com/yourusername/ACE-Step-1.5)\n"
  },
  {
    "path": "docs/zh/INSTALL.md",
    "content": "# ACE-Step 1.5 安装指南\n\n**Language / 语言 / 言語:** [English](../en/INSTALL.md) | [中文](INSTALL.md) | [日本語](../ja/INSTALL.md)\n\n---\n\n## 目录\n\n- [环境要求](#环境要求)\n- [快速开始（全平台）](#快速开始全平台)\n- [启动脚本](#-启动脚本)\n- [Windows 便携包](#-windows-便携包)\n- [AMD / ROCm 显卡](#amd--rocm-显卡)\n- [Intel 显卡](#intel-显卡)\n- [仅 CPU 模式](#仅-cpu-模式)\n- [Linux 注意事项](#linux-注意事项)\n- [环境变量 (.env)](#环境变量-env)\n- [命令行参数](#命令行参数)\n- [模型下载](#-模型下载)\n- [如何选择模型？](#-如何选择模型)\n- [开发](#开发)\n\n---\n\n## 环境要求\n\n| 项目 | 要求 |\n|------|------|\n| Python | 3.11-3.12（正式版，非预发布版）<br>**注意：** Windows 上的 ROCm 需要 Python 3.12 |\n| GPU | 推荐 CUDA GPU；也支持 MPS / ROCm / Intel XPU / CPU |\n| 显存 | 仅 DiT 模式 ≥4GB；LLM+DiT ≥6GB |\n| 磁盘 | 核心模型约 10GB |\n\n---\n\n## 快速开始（全平台）\n\n### 1. 安装 uv（包管理器）\n\n```bash\n# macOS / Linux\ncurl -LsSf https://astral.sh/uv/install.sh | sh\n\n# Windows (PowerShell)\npowershell -ExecutionPolicy ByPass -c \"irm https://astral.sh/uv/install.ps1 | iex\"\n```\n\n### 2. 克隆 & 安装\n\n```bash\ngit clone https://github.com/ACE-Step/ACE-Step-1.5.git\ncd ACE-Step-1.5\nuv sync\n```\n\n### 3. 启动\n\n**Gradio 网页界面（推荐）：**\n\n```bash\nuv run acestep\n```\n\n**REST API 服务器：**\n\n```bash\nuv run acestep-api\n```\n\n**直接使用 Python**（Conda / venv / 系统 Python）：\n\n```bash\n# 先激活你的环境，然后：\npython acestep/acestep_v15_pipeline.py          # Gradio UI\npython acestep/api_server.py                     # REST API\n```\n\n> 首次运行时模型会自动下载。打开 http://localhost:7860（Gradio）或 http://localhost:8001（API）。\n\n---\n\n## 🚀 启动脚本\n\n为所有平台提供开箱即用的启动脚本。这些脚本会自动处理环境检测、依赖安装和应用启动。所有脚本默认在启动时检查更新（可配置）。\n\n### 可用脚本\n\n| 平台 | 脚本 | 说明 |\n|------|------|------|\n| **Windows** | `start_gradio_ui.bat` | 启动 Gradio 网页界面（CUDA） |\n| **Windows** | `start_api_server.bat` | 启动 REST API 服务器（CUDA） |\n| **Windows** | `start_gradio_ui_rocm.bat` | 启动 Gradio 网页界面（AMD ROCm） |\n| **Windows** | `start_api_server_rocm.bat` | 启动 REST API 服务器（AMD ROCm） |\n| **Linux** | `start_gradio_ui.sh` | 启动 Gradio 网页界面（CUDA） |\n| **Linux** | `start_api_server.sh` | 启动 REST API 服务器（CUDA） |\n| **macOS** | `start_gradio_ui_macos.sh` | 启动 Gradio 网页界面（MLX） |\n| **macOS** | `start_api_server_macos.sh` | 启动 REST API 服务器（MLX） |\n\n### Windows\n\n```bash\n# 启动 Gradio 网页界面（NVIDIA CUDA）\nstart_gradio_ui.bat\n\n# 启动 REST API 服务器（NVIDIA CUDA）\nstart_api_server.bat\n\n# 启动 Gradio 网页界面（AMD ROCm）\nstart_gradio_ui_rocm.bat\n\n# 启动 REST API 服务器（AMD ROCm）\nstart_api_server_rocm.bat\n```\n\n> **ROCm 用户：** ROCm 脚本（`start_gradio_ui_rocm.bat`、`start_api_server_rocm.bat`）会自动设置 `HSA_OVERRIDE_GFX_VERSION`、`ACESTEP_LM_BACKEND=pt`、`MIOPEN_FIND_MODE=FAST` 及其他 ROCm 相关环境变量。这些脚本使用独立的 `venv_rocm` 虚拟环境，以避免 CUDA/ROCm wheel 冲突。\n\n### Linux\n\n```bash\n# 首次使用需添加执行权限\nchmod +x start_gradio_ui.sh start_api_server.sh\n\n# 启动 Gradio 网页界面\n./start_gradio_ui.sh\n\n# 启动 REST API 服务器\n./start_api_server.sh\n```\n\n> **注意：** 需要通过系统包管理器安装 Git（`sudo apt install git`、`sudo yum install git`、`sudo pacman -S git`）。\n\n### macOS（Apple Silicon / MLX）\n\nmacOS 脚本使用 **MLX 后端**，提供原生 Apple Silicon 加速（M1/M2/M3/M4）。\n\n```bash\n# 首次使用需添加执行权限\nchmod +x start_gradio_ui_macos.sh start_api_server_macos.sh\n\n# 启动 Gradio 网页界面（MLX 后端）\n./start_gradio_ui_macos.sh\n\n# 启动 REST API 服务器（MLX 后端）\n./start_api_server_macos.sh\n```\n\nmacOS 脚本会自动设置 `ACESTEP_LM_BACKEND=mlx` 和 `--backend mlx` 以启用原生 Apple Silicon 加速，在非 arm64 机器上则回退到 PyTorch 后端。\n\n> **注意：** 通过 `xcode-select --install` 或 `brew install git` 安装 Git。\n\n### 脚本功能\n\n- 启动时自动检查更新（默认启用，可配置）\n- 自动环境检测（便携 Python 或 uv）\n- 自动安装 `uv`（如需要）\n- 可配置下载源（HuggingFace/ModelScope）\n- 可自定义模型和参数\n\n### 如何修改配置\n\n所有可配置选项均定义为每个脚本顶部的变量。如需自定义，请用文本编辑器打开脚本并修改变量值。\n\n**示例：将界面语言改为中文并使用 1.7B LM 模型**\n\n<table>\n<tr><th>Windows (.bat)</th><th>Linux / macOS (.sh)</th></tr>\n<tr><td>\n\n在 `start_gradio_ui.bat` 中找到以下行：\n```batch\nset LANGUAGE=en\nset LM_MODEL_PATH=--lm_model_path acestep-5Hz-lm-0.6B\n```\n修改为：\n```batch\nset LANGUAGE=zh\nset LM_MODEL_PATH=--lm_model_path acestep-5Hz-lm-1.7B\n```\n\n</td><td>\n\n在 `start_gradio_ui.sh` 中找到以下行：\n```bash\nLANGUAGE=\"en\"\nLM_MODEL_PATH=\"--lm_model_path acestep-5Hz-lm-0.6B\"\n```\n修改为：\n```bash\nLANGUAGE=\"zh\"\nLM_MODEL_PATH=\"--lm_model_path acestep-5Hz-lm-1.7B\"\n```\n\n</td></tr>\n</table>\n\n**示例：禁用启动时更新检查**\n\n<table>\n<tr><th>Windows (.bat)</th><th>Linux / macOS (.sh)</th></tr>\n<tr><td>\n\n```batch\nREM set CHECK_UPDATE=true\nset CHECK_UPDATE=false\n```\n\n</td><td>\n\n```bash\n# CHECK_UPDATE=\"true\"\nCHECK_UPDATE=\"false\"\n```\n\n</td></tr>\n</table>\n\n**示例：启用已注释的选项** —— 删除注释前缀（.bat 用 `REM`，.sh 用 `#`）：\n\n<table>\n<tr><th>Windows (.bat)</th><th>Linux / macOS (.sh)</th></tr>\n<tr><td>\n\n修改前：\n```batch\nREM set SHARE=--share\n```\n修改后：\n```batch\nset SHARE=--share\n```\n\n</td><td>\n\n修改前：\n```bash\n# SHARE=\"--share\"\n```\n修改后：\n```bash\nSHARE=\"--share\"\n```\n\n</td></tr>\n</table>\n\n**常用可配置选项：**\n\n| 选项 | Gradio UI | API 服务器 | 说明 |\n|------|:---------:|:----------:|------|\n| `LANGUAGE` | ✅ | — | 界面语言：`en`、`zh`、`he`、`ja` |\n| `PORT` | ✅ | ✅ | 服务端口（默认：7860 / 8001） |\n| `SERVER_NAME` / `HOST` | ✅ | ✅ | 绑定地址（`127.0.0.1` 或 `0.0.0.0`） |\n| `CHECK_UPDATE` | ✅ | ✅ | 启动时更新检查（`true` / `false`） |\n| `CONFIG_PATH` | ✅ | — | DiT 模型（`acestep-v15-turbo` 等） |\n| `LM_MODEL_PATH` | ✅ | ✅ | LM 模型（`acestep-5Hz-lm-0.6B` / `1.7B` / `4B`） |\n| `DOWNLOAD_SOURCE` | ✅ | ✅ | 下载源（`huggingface` / `modelscope`） |\n| `SHARE` | ✅ | — | 创建公开 Gradio 链接 |\n| `INIT_LLM` | ✅ | — | 强制启用/禁用 LLM（`true` / `false` / `auto`） |\n| `OFFLOAD_TO_CPU` | ✅ | — | 低显存 GPU 的 CPU 卸载 |\n\n### 更新与维护工具\n\n| 脚本（Windows） | 脚本（Linux/macOS） | 用途 |\n|------------------|----------------------|------|\n| `check_update.bat` | `check_update.sh` | 从 GitHub 检查并更新 |\n| `merge_config.bat` | `merge_config.sh` | 更新后合并备份的配置 |\n| `install_uv.bat` | `install_uv.sh` | 安装 uv 包管理器 |\n| `quick_test.bat` | `quick_test.sh` | 测试环境配置 |\n\n**更新工作流：**\n\n```bash\n# Windows                          # Linux / macOS\ncheck_update.bat                    ./check_update.sh\nmerge_config.bat                    ./merge_config.sh\n```\n\n---\n\n## 🪟 Windows 便携包\n\n为 Windows 用户提供了预装依赖的便携包：\n\n1. 下载并解压：[ACE-Step-1.5.7z](https://files.acemusic.ai/acemusic/win/ACE-Step-1.5.7z)\n2. 包含 `python_embedded`，所有依赖已预装\n3. **要求：** CUDA 12.8\n\n### 快速启动脚本\n\n| 脚本 | 说明 |\n|------|------|\n| `start_gradio_ui.bat` | 启动 Gradio 网页界面 |\n| `start_api_server.bat` | 启动 REST API 服务器 |\n\n两个脚本均支持自动环境检测、自动安装 `uv`、可配置下载源、可选 Git 更新检查、可自定义模型和参数。\n\n### 配置\n\n**`start_gradio_ui.bat`：**\n\n```batch\nREM 界面语言 (en, zh, he, ja)\nset LANGUAGE=zh\n\nREM 下载源 (auto, huggingface, modelscope)\nset DOWNLOAD_SOURCE=--download-source modelscope\n\nREM Git 更新检查 (true/false)\nset CHECK_UPDATE=true\n\nREM 模型配置\nset CONFIG_PATH=--config_path acestep-v15-turbo\nset LM_MODEL_PATH=--lm_model_path acestep-5Hz-lm-1.7B\n```\n\n### 更新与维护\n\n| 脚本 | 用途 |\n|------|------|\n| `check_update.bat` | 从 GitHub 检查并更新 |\n| `merge_config.bat` | 更新后合并备份的配置 |\n| `install_uv.bat` | 安装 uv 包管理器 |\n| `quick_test.bat` | 测试环境配置 |\n\n---\n\n## AMD / ROCm 显卡\n\n> ⚠️ `uv run acestep` 会安装 CUDA PyTorch wheels，可能覆盖已有的 ROCm 环境。\n\n### 推荐工作流\n\n```bash\n# 1. 创建并激活虚拟环境\npython -m venv .venv\nsource .venv/bin/activate\n\n# 2. 安装 ROCm 兼容的 PyTorch\npip install torch --index-url https://download.pytorch.org/whl/rocm6.0\n\n# 3. 安装 ACE-Step\npip install -e .\n\n# 4. 启动服务\npython -m acestep.acestep_v15_pipeline --port 7680\n```\n\n### GPU 检测问题排查\n\n如果显示 \"No GPU detected, running on CPU\"：\n\n1. 运行诊断工具：`python scripts/check_gpu.py`\n2. RDNA3 GPU 设置 `HSA_OVERRIDE_GFX_VERSION`：\n\n| GPU | 值 |\n|-----|---|\n| RX 7900 XT/XTX, RX 9070 XT | `export HSA_OVERRIDE_GFX_VERSION=11.0.0` |\n| RX 7800 XT, RX 7700 XT | `export HSA_OVERRIDE_GFX_VERSION=11.0.1` |\n| RX 7600 | `export HSA_OVERRIDE_GFX_VERSION=11.0.2` |\n\n3. Windows 上使用 `start_gradio_ui_rocm.bat` / `start_api_server_rocm.bat`\n4. 验证 ROCm 安装：`rocm-smi`\n\n### Linux（cachy-os / RDNA4）\n\n详见 [ACE-Step1.5-Rocm-Manual-Linux.md](../en/ACE-Step1.5-Rocm-Manual-Linux.md)\n\n---\n\n## Intel 显卡\n\n| 项目 | 详情 |\n|------|------|\n| 测试设备 | Windows 笔记本，Ultra 9 285H 集成显卡 |\n| 卸载 | 默认禁用 |\n| 编译与量化 | 默认启用 |\n| LLM 推理 | 支持（已测试 `acestep-5Hz-lm-0.6B`） |\n| nanovllm 加速 | Intel GPU 暂不支持 |\n| 测试环境 | PyTorch 2.8.0（[Intel Extension for PyTorch](https://pytorch-extension.intel.com/?request=platform)） |\n\n> 注意：生成超过 2 分钟的音频时，LLM 推理速度可能下降。Intel 独立显卡预计可用但尚未测试。\n\n---\n\n## 仅 CPU 模式\n\nACE-Step 可以在 CPU 上运行**仅推理**，但速度会显著变慢。\n\n- 不推荐在 CPU 上训练（包括 LoRA）。\n- 低显存系统可使用 DiT-only 模式（禁用 LLM）。\n\n如果没有 GPU，建议：\n- 使用云 GPU 服务\n- 仅运行推理工作流\n- 使用 `ACESTEP_INIT_LLM=false` 启用 DiT-only 模式\n\n---\n\n## Linux 注意事项\n\n### Python 3.11 预发布版问题\n\n部分 Linux 发行版（包括 Ubuntu）自带 Python 3.11.0rc1 预发布版，可能导致 vLLM 后端出现段错误。\n\n**建议：** 使用稳定版 Python（≥ 3.11.12）。Ubuntu 上可通过 deadsnakes PPA 安装。\n\n如无法升级 Python，使用 PyTorch 后端：\n\n```bash\nuv run acestep --backend pt\n```\n\n---\n\n## 环境变量 (.env)\n\n```bash\ncp .env.example .env   # 复制并编辑\n```\n\n### 关键变量\n\n| 变量 | 取值 | 说明 |\n|------|------|------|\n| `ACESTEP_INIT_LLM` | `auto` / `true` / `false` | LLM 初始化模式 |\n| `ACESTEP_CONFIG_PATH` | 模型名称 | DiT 模型路径 |\n| `ACESTEP_LM_MODEL_PATH` | 模型名称 | LM 模型路径 |\n| `ACESTEP_DOWNLOAD_SOURCE` | `auto` / `huggingface` / `modelscope` | 下载源 |\n| `ACESTEP_API_KEY` | 字符串 | API 认证密钥 |\n\n### LLM 初始化 (`ACESTEP_INIT_LLM`)\n\n处理流程：`GPU 检测 → ACESTEP_INIT_LLM 覆盖 → 模型加载`\n\n| 值 | 行为 |\n|----|------|\n| `auto`（或空） | 使用 GPU 自动检测结果（推荐） |\n| `true` / `1` / `yes` | 强制启用 LLM（可能导致 OOM） |\n| `false` / `0` / `no` | 强制禁用，纯 DiT 模式 |\n\n**示例 `.env`：**\n\n```bash\n# 自动模式（推荐）\nACESTEP_INIT_LLM=auto\n\n# 低显存 GPU 强制启用\nACESTEP_INIT_LLM=true\nACESTEP_LM_MODEL_PATH=acestep-5Hz-lm-0.6B\n\n# 禁用 LLM 加速生成\nACESTEP_INIT_LLM=false\n```\n\n---\n\n## 命令行参数\n\n### Gradio UI (`acestep`)\n\n| 参数 | 默认值 | 说明 |\n|------|--------|------|\n| `--port` | 7860 | 服务端口 |\n| `--server-name` | 127.0.0.1 | 服务地址（使用 `0.0.0.0` 开放网络访问） |\n| `--share` | false | 创建公开 Gradio 链接 |\n| `--language` | en | 界面语言：`en`、`zh`、`he`、`ja` |\n| `--init_service` | false | 启动时自动初始化模型 |\n| `--init_llm` | auto | LLM 初始化：`true` / `false` / 省略为自动 |\n| `--config_path` | auto | DiT 模型（如 `acestep-v15-turbo`） |\n| `--lm_model_path` | auto | LM 模型（如 `acestep-5Hz-lm-1.7B`） |\n| `--offload_to_cpu` | auto | CPU 卸载（显存 < 20GB 时自动启用） |\n| `--download-source` | auto | 模型源：`auto` / `huggingface` / `modelscope` |\n| `--enable-api` | false | 同时启用 REST API 端点 |\n\n**示例：**\n\n```bash\n# 公开访问 + 中文界面\nuv run acestep --server-name 0.0.0.0 --share --language zh\n\n# 启动时预初始化模型\nuv run acestep --init_service true --config_path acestep-v15-turbo\n\n# 使用 ModelScope 下载\nuv run acestep --download-source modelscope\n```\n\n---\n\n## 📥 模型下载\n\n首次运行时模型会从 [HuggingFace](https://huggingface.co/ACE-Step/Ace-Step1.5) 或 [ModelScope](https://modelscope.cn/organization/ACE-Step) 自动下载。\n\n### CLI 下载\n\n```bash\nuv run acestep-download                              # 下载主模型\nuv run acestep-download --all                         # 下载所有模型\nuv run acestep-download --download-source modelscope  # 从 ModelScope 下载\nuv run acestep-download --model acestep-v15-sft       # 指定模型\nuv run acestep-download --list                        # 列出所有可用模型\n```\n\n### 手动下载 (huggingface-cli)\n\n```bash\n# 主模型\nhuggingface-cli download ACE-Step/Ace-Step1.5 --local-dir ./checkpoints\n\n# 可选模型\nhuggingface-cli download ACE-Step/acestep-5Hz-lm-0.6B --local-dir ./checkpoints/acestep-5Hz-lm-0.6B\nhuggingface-cli download ACE-Step/acestep-5Hz-lm-4B --local-dir ./checkpoints/acestep-5Hz-lm-4B\n```\n\n### 可用模型\n\n| 模型 | 说明 | HuggingFace |\n|------|------|-------------|\n| **Ace-Step1.5**（主模型） | 核心：vae, Qwen3-Embedding-0.6B, acestep-v15-turbo, acestep-5Hz-lm-1.7B | [链接](https://huggingface.co/ACE-Step/Ace-Step1.5) |\n| acestep-5Hz-lm-0.6B | 轻量 LM（0.6B 参数） | [链接](https://huggingface.co/ACE-Step/acestep-5Hz-lm-0.6B) |\n| acestep-5Hz-lm-4B | 大型 LM（4B 参数） | [链接](https://huggingface.co/ACE-Step/acestep-5Hz-lm-4B) |\n| acestep-v15-base | 基础 DiT 模型 | [链接](https://huggingface.co/ACE-Step/acestep-v15-base) |\n| acestep-v15-sft | SFT DiT 模型 | [链接](https://huggingface.co/ACE-Step/acestep-v15-sft) |\n| acestep-v15-turbo-shift1 | Turbo DiT（shift1） | [链接](https://huggingface.co/ACE-Step/acestep-v15-turbo-shift1) |\n| acestep-v15-turbo-shift3 | Turbo DiT（shift3） | [链接](https://huggingface.co/ACE-Step/acestep-v15-turbo-shift3) |\n| acestep-v15-turbo-continuous | Turbo DiT（continuous shift 1-5） | [链接](https://huggingface.co/ACE-Step/acestep-v15-turbo-continuous) |\n\n---\n\n## 💡 如何选择模型？\n\nACE-Step 会自动适配你的 GPU 显存。UI 会根据检测到的 GPU 等级预配置所有设置（LM 模型、后端、卸载、量化）：\n\n| GPU 显存 | 推荐 LM 模型 | 后端 | 说明 |\n|----------|--------------|------|------|\n| **≤6GB** | 无（仅 DiT） | — | 默认禁用 LM；INT8 量化 + 完全 CPU 卸载 |\n| **6-8GB** | `acestep-5Hz-lm-0.6B` | `pt` | 轻量 LM，PyTorch 后端 |\n| **8-16GB** | `0.6B` / `1.7B` | `vllm` | 8-12GB 用 0.6B，12-16GB 用 1.7B |\n| **16-24GB** | `acestep-5Hz-lm-1.7B` | `vllm` | 20GB+ 可用 4B；20GB+ 无需卸载 |\n| **≥24GB** | `acestep-5Hz-lm-4B` | `vllm` | 最佳质量，所有模型无需卸载 |\n\n> 📖 详细 GPU 兼容性信息（等级表、时长限制、批量大小、自适应 UI 默认设置、显存优化），请参阅 [GPU 兼容性指南](GPU_COMPATIBILITY.md)。\n\n---\n\n## 开发\n\n```bash\n# 添加依赖\nuv add package-name\nuv add --dev package-name\n\n# 更新所有依赖\nuv sync --upgrade\n```\n"
  },
  {
    "path": "docs/zh/LoRA_Training_Tutorial.md",
    "content": "# ACE-Step 1.5 LoRA 训练教程\n\n## 硬件需求\n\n| 显存 | 说明 |\n|------|------|\n| 16 GB（最低） | 通常可用，但处理较长歌曲时可能出现显存不足 |\n| 20 GB 及以上（推荐） | 可处理全曲长度，训练时显存占用通常维持在 17 GB 左右 |\n\n> **提示：** 在训练开始之前的预处理阶段，需要多次重启 Gradio 以释放显存，具体时机会在后续步骤中说明。\n\n## 免责声明\n\n本教程使用 **Nayutan星人 (NayutalieN)** 的专辑 *ナユタン星からの物体Y*（共 13 首歌曲）作为演示，训练了 500 个 epoch（batch size 为 1）。**本教程仅用于理解 LoRA 微调技术的教育目的，请使用您的原创作品训练 LoRA。**\n\n作为开发者，我本人非常喜欢 Nayutan星人 的作品，因此选用了其中一张专辑作为示例。如果您是权利持有者并认为本教程侵犯了您的合法权益，请立即联系我们，我们将在收到有效通知后移除相关内容。\n\n技术应当被合理合法地使用，请尊重艺术家的创作，不要做出**损害或伤害**原创艺术家的声誉、权利或利益的行为。\n\n---\n\n## 数据准备\n\n> **提示：** 对于程序脚本操作部分，如果您不熟悉编程，可以将本文档交给 Claude Code / Codex CLI / Cursor / Copilot 等 AI 编程工具，让它来帮助您完成。\n\n### 概述\n\n每首歌的训练数据包含以下内容：\n\n1. **音频文件** — 支持 `.mp3`、`.wav`、`.flac`、`.ogg`、`.opus` 格式\n2. **歌词** — 与音频同名的 `.lyrics.txt` 文件（也兼容 `.txt`）\n3. **标注数据** — 包含 `caption`、`bpm`、`keyscale`、`timesignature`、`language` 等元信息\n\n### 标注数据格式\n\n如果您已拥有完整的标注数据，可以构造 JSON 文件，与音频、歌词放置在同一目录。文件结构如下：\n\n```\ndataset/\n├── song1.mp3               # 音频\n├── song1.lyrics.txt        # 歌词\n├── song1.json              # 标注（可选）\n├── song1.caption.txt       # caption（可选，也可写在 json 中）\n├── song2.mp3\n├── song2.lyrics.txt\n├── song2.json\n└── ...\n```\n\nJSON 文件结构（所有字段均为可选）：\n\n```json\n{\n    \"caption\": \"A high-energy J-pop track with synthesizer leads and fast tempo\",\n    \"bpm\": 190,\n    \"keyscale\": \"D major\",\n    \"timesignature\": \"4\",\n    \"language\": \"ja\"\n}\n```\n\n如果没有标注数据，可以通过后续章节介绍的方案获取。\n\n---\n\n### 歌词\n\n将歌词保存为与音频同名的 `.lyrics.txt` 文件，放置在相同目录下。请确保歌词内容的准确性。\n\n扫描时的歌词文件查找优先级：\n\n1. `{文件名}.lyrics.txt`（推荐）\n2. `{文件名}.txt`（向后兼容）\n\n#### 歌词转录\n\n如果您没有现成的歌词文本，可以通过以下工具转录获取：\n\n| 工具 | 结构化标签 | 准确性 | 使用难度 | 部署方式 |\n|------|-----------|--------|---------|---------|\n| [acestep-transcriber](https://huggingface.co/ACE-Step/acestep-transcriber) | 无 | 可能有错别字 | 较高（需部署模型） | 自部署 |\n| [Gemini](https://aistudio.google.com/) | 有 | 可能有错别字 | 低 | 付费 API |\n| [Whisper](https://github.com/openai/whisper) | 无 | 可能有错别字 | 中等 | 自部署 / 付费 API |\n| [ElevenLabs](https://elevenlabs.io/app/developers) | 无 | 可能有错别字 | 中等 | 付费 API（有免费额度） |\n\n本项目在 `scripts/lora_data_prepare/` 下提供了对应的转录脚本：\n\n- `whisper_transcription.py` — 调用 OpenAI Whisper API 转录\n- `elevenlabs_transcription.py` — 调用 ElevenLabs Scribe API 转录\n\n两个脚本均支持 `process_folder()` 方法批量处理整个文件夹。\n\n#### 检查与清洗（必须）\n\n模型转录出来的歌词可能包含错别字，**必须人工检查并修正**。\n\n如果您使用的是 LRC 格式的歌词，需要移除其中的时间戳。以下是一个简单的清洗示例：\n\n```python\nimport re\n\ndef clean_lrc_content(lines):\n    \"\"\"清洗 LRC 文件内容，移除时间戳\"\"\"\n    result = []\n    for line in lines:\n        line = line.strip()\n        if not line:\n            continue\n        # 移除时间戳 [mm:ss.x] [mm:ss.xx] [mm:ss.xxx]\n        cleaned = re.sub(r\"\\[\\d{2}:\\d{2}\\.\\d{1,3}\\]\", \"\", line)\n        result.append(cleaned)\n\n    # 移除末尾空行\n    while result and not result[-1]:\n        result.pop()\n\n    return result\n```\n\n#### 结构化标签（非必须）\n\n如果歌词包含结构化标签（如 `[Verse]`、`[Chorus]` 等），能够帮助模型更好地学习歌曲结构。没有结构化标签也可以正常训练。\n\n> **提示：** 可以使用 [Gemini](https://aistudio.google.com/) 为已有歌词添加结构化标签。\n\n示例：\n\n```\n[Intro]\nLa la la...\n\n[Verse 1]\nWalking down the empty street\nEchoes dancing at my feet\n\n[Chorus]\nWe are the stars tonight\nShining through the endless sky\n\n[Bridge]\nClose your eyes and feel the sound\n```\n\n---\n\n### 自动标注\n\n#### 1. 获取 BPM 和 Key\n\n使用 [Key-BPM-Finder](https://vocalremover.org/key-bpm-finder) 在线获取 BPM 和调式标注：\n\n1. 打开网页后点击 **Browse my files**，选择待处理的音频文件（一次处理过多可能会卡住，建议分批处理后合并 CSV）。处理在本地完成，不会上传至服务器。\n   ![key-bpm-finder-0.jpg](../pics/key-bpm-finder-0.jpg)\n\n2. 处理完成后，点击 **Export CSV** 下载 CSV 文件。\n   ![key-bpm-finder-1.jpg](../pics/key-bpm-finder-1.jpg)\n\n3. CSV 文件内容示例：\n\n   ```csv\n   File,Artist,Title,BPM,Key,Camelot\n   song1.wav,,,190,D major,10B\n   song2.wav,,,128,A minor,8A\n   ```\n\n4. 将 CSV 文件放置到数据集文件夹中。如需附加 caption 数据，可在 `Camelot` 列后新增一列。\n\n#### 2. 获取 Caption\n\n可通过以下方式获取歌曲的 caption 描述：\n\n- **使用 acestep-5Hz-lm**（0.6B / 1.7B / 4B）— 在 Gradio UI 中通过 Auto Label 功能调用（见后续操作步骤）\n- **使用 Gemini API** — 参考脚本 `scripts/lora_data_prepare/gemini_caption.py`，支持 `process_folder()` 批量处理，会为每个音频生成：\n  - `{文件名}.lyrics.txt` — 歌词\n  - `{文件名}.caption.txt` — caption 描述\n\n---\n\n## 数据预处理\n\n准备好数据后，即可使用 Gradio UI 进行数据检查与预处理。\n\n> **重要：** 如果使用启动脚本启动，需要修改启动参数以禁用服务预初始化：\n>\n> - **Windows** (`start_gradio_ui.bat`)：将 `if not defined INIT_SERVICE set INIT_SERVICE=--init_service true` 修改为 `if not defined INIT_SERVICE set INIT_SERVICE=--init_service false`\n> - **Linux/macOS** (`start_gradio_ui.sh`)：将 `: \"${INIT_SERVICE:=--init_service true}\"` 修改为 `: \"${INIT_SERVICE:=--init_service false}\"`\n\n启动 Gradio UI（通过启动脚本或直接运行 `acestep/acestep_v15_pipeline.py`）。\n\n### 步骤 1：加载模型\n\n- **需要使用 LM 生成 caption 的情况：** 在初始化时勾选想要使用的 LM 模型（acestep-5Hz-lm-0.6B / 1.7B / 4B）。\n  ![](../pics/00_select_model_to_load.jpg)\n\n- **不需要使用 LM 的情况：** 不要勾选 LM 模型。\n  ![](../pics/00_select_model_to_load_1.jpg)\n\n### 步骤 2：加载数据\n\n切换到 **LoRA Training** 选项卡，输入数据集目录路径，点击 **Scan**。\n\n扫描时会自动识别以下文件：\n\n| 文件 | 说明 |\n|------|------|\n| `*.mp3` / `*.wav` / `*.flac` / ... | 音频文件 |\n| `{文件名}.lyrics.txt`（或 `{文件名}.txt`） | 歌词 |\n| `{文件名}.caption.txt` | Caption 描述 |\n| `{文件名}.json` | 标注元数据（caption / bpm / keyscale / timesignature / language） |\n| `*.csv` | 批量 BPM / Key 标注（由 Key-BPM-Finder 导出） |\n\n![](../pics/01_load_dataset_path.jpg)\n\n### 步骤 3：预览并调整数据集\n\n- **Duration** — 自动从音频文件读取\n- **Lyrics** — 需要存在同名 `.lyrics.txt` 文件（也兼容 `.txt`）\n- **Labeled** — 如果有 caption 则显示 ✅，否则显示 ❌\n- **BPM / Key / Caption** — 从 JSON 或 CSV 文件中加载\n- 如果数据集并非全部为纯音乐（Instrumental），请取消勾选 **All Instrumental**\n- **Format Lyrics** 与 **Transcribe Lyrics** 功能当前暂时禁用（未接入 [acestep-transcriber](https://huggingface.co/ACE-Step/acestep-transcriber)，直接使用 LM 容易产生幻觉）\n- 输入 **Custom Trigger Tag**（当前效果尚不明显，只要不选 `Replace Caption` 即可）\n- **Genre Ratio** 表示使用 genre 替代 caption 的比例。由于当前 LM 生成的 genre 描述能力远不及 caption，建议保持为 0\n\n![](../pics/02_preview_dataset.jpg)\n\n### 步骤 4：Auto Label Data\n\n- 如果已有 caption，可跳过此步骤\n- 如果数据缺少 caption，可通过 LM 推理生成\n- 如果缺少 BPM / Key 等数值，请先使用 [Key-BPM-Finder](https://vocalremover.org/key-bpm-finder) 获取，直接由 LM 生成会产生幻觉\n\n![](../pics/03_label_data.jpg)\n\n### 步骤 5：预览并编辑数据\n\n如有需要，可以逐条检查并修改数据。**每条数据修改后请记得点击保存。**\n\n![](../pics/04_edit_data.jpg)\n\n### 步骤 6：保存数据集\n\n输入保存路径，将数据集保存为 JSON 文件。\n\n![](../pics/05_save_dataset.jpg)\n\n### 步骤 7：预处理生成 Tensor 文件\n\n> **注意：** 如果此前使用了 LM 生成 caption 且显存不足，建议先重启 Gradio 释放显存，重启时**不要勾选 LM 模型**。重启后，在输入框中填入已保存的 JSON 文件路径并加载。\n\n输入 Tensor 文件的保存路径，点击开始预处理，等待生成完成。\n\n![](../pics/06_preprocess_tensor.jpg)\n\n---\n\n## 训练\n\n> **注意：** 生成 Tensor 文件后，同样建议重启 Gradio 以释放显存。\n\n1. 切换到 **Train LoRA** 选项卡，输入 Tensor 文件路径并加载数据集。\n2. 如果您对训练参数不熟悉，通常使用默认值即可。\n\n### 参数参考\n\n| 参数 | 说明 | 建议值 |\n|------|------|--------|\n| **Max Epochs** | 根据数据集大小调整 | 约 100 首歌 → 500 epoch；10–20 首歌 → 800 epoch（仅供参考） |\n| **Batch Size** | 显存充足时可适当增大 | 1（默认），显存足够的话 可尝试 2 或 4 |\n| **Save Every N Epochs** | Checkpoint 保存间隔 | Max Epochs 较小时可设小一些，较大时可设大一些 |\n\n> 以上数值仅供参考，请根据实际情况调整。\n\n> **💡 推荐使用 LoKr：** LoKR 大幅提升了训练效率，原本需要一小时的训练现在只需 5 分钟——速度提升超过 10 倍。这对于在消费级 GPU 上训练尤为关键。您可以在 **Train LoKr** 选项卡中尝试 LoKr 训练，或使用 [Side-Step](https://github.com/koda-dernet/Side-Step) 工具包进行命令行 LoKr 训练。详见 [Training Guide](../sidestep/Training%20Guide.md)。\n\n3. 点击 **Start Training**，等待训练完成。\n\n![](../pics/07_train.jpg)\n\n---\n\n## 使用 LoRA\n\n1. 训练完成后**重启 Gradio**，重新加载模型（不要勾选 LM 模型）。\n2. 模型初始化完成后，加载训练好的 LoRA 权重。\n   ![](../pics/08_load_lora.jpg)\n3. 开始合成音乐。\n\n恭喜！您已完成 LoRA 训练的全部流程。\n\n---\n\n## 高级训练：Side-Step\n\n如果你需要更精细地控制 LoRA 训练——包括修正的时间步采样、LoKR 适配器、命令行工作流、显存优化和梯度敏感度分析——社区开发的 **[Side-Step](https://github.com/koda-dernet/Side-Step)** 工具包提供了高级替代方案。其文档已收录在本仓库的 `docs/sidestep/` 目录下。\n\n| 主题 | 说明 |\n|------|------|\n| [Getting Started](../sidestep/Getting%20Started.md) | 安装、前置条件和首次运行设置 |\n| [End-to-End Tutorial](../sidestep/End-to-End%20Tutorial.md) | 从原始音频到生成的完整流程 |\n| [Dataset Preparation](../sidestep/Dataset%20Preparation.md) | JSON 格式、音频要求、元数据字段、自定义标签 |\n| [Training Guide](../sidestep/Training%20Guide.md) | LoRA vs LoKR、修正模式 vs 原始模式、超参数指南 |\n| [Using Your Adapter](../sidestep/Using%20Your%20Adapter.md) | 输出目录结构、在 Gradio 中加载、LoKR 限制 |\n| [VRAM Optimization Guide](../sidestep/VRAM%20Optimization%20Guide.md) | 显存优化策略和 GPU 分级配置 |\n| [Estimation Guide](../sidestep/Estimation%20Guide.md) | 梯度敏感度分析，用于针对性训练 |\n| [Shift and Timestep Sampling](../sidestep/Shift%20and%20Timestep%20Sampling.md) | 训练时间步的工作原理，Side-Step 与内置训练器的区别 |\n| [Preset Management](../sidestep/Preset%20Management.md) | 内置预设、保存/加载/导入/导出 |\n| [The Settings Wizard](../sidestep/The%20Settings%20Wizard.md) | 完整的向导设置参考 |\n| [Model Management](../sidestep/Model%20Management.md) | 检查点结构和微调模型支持 |\n| [Windows Notes](../sidestep/Windows%20Notes.md) | Windows 特定的设置和注意事项 |\n"
  },
  {
    "path": "docs/zh/Openrouter_API_DOC.md",
    "content": "# ACE-Step OpenRouter API 文档\n\n> 兼容 OpenAI Chat Completions 格式的 AI 音乐生成接口\n\n**Base URL:** `http://{host}:{port}` (默认 `http://127.0.0.1:8002`)\n\n---\n\n## 目录\n\n- [认证](#认证)\n- [接口列表](#接口列表)\n  - [POST /v1/chat/completions - 生成音乐](#1-生成音乐)\n  - [GET /v1/models - 模型列表](#2-模型列表)\n  - [GET /health - 健康检查](#3-健康检查)\n- [输入模式](#输入模式)\n- [音频输入](#音频输入)\n- [流式响应](#流式响应)\n- [完整示例](#完整示例)\n- [错误码](#错误码)\n\n---\n\n## 认证\n\n如果服务端配置了 API Key（环境变量 `OPENROUTER_API_KEY` 或启动参数 `--api-key`），所有请求需在 Header 中携带：\n\n```\nAuthorization: Bearer <your-api-key>\n```\n\n未配置 API Key 时无需认证。\n\n---\n\n## 接口列表\n\n### 1. 生成音乐\n\n**POST** `/v1/chat/completions`\n\n通过聊天消息生成音乐，返回音频数据和 LM 生成的元信息。\n\n#### 请求参数\n\n| 字段 | 类型 | 必填 | 默认值 | 说明 |\n|---|---|---|---|---|\n| `model` | string | 否 | 自动 | 模型 ID（从 `/v1/models` 获取） |\n| `messages` | array | **是** | - | 聊天消息列表，见 [输入模式](#输入模式) |\n| `stream` | boolean | 否 | `false` | 是否启用流式返回，见 [流式响应](#流式响应) |\n| `audio_config` | object | 否 | `null` | 音频生成配置，见下方 |\n| `temperature` | float | 否 | `0.85` | LM 采样温度 |\n| `top_p` | float | 否 | `0.9` | LM nucleus sampling |\n| `seed` | int \\| string | 否 | `null` | 随机种子。`batch_size > 1` 时可用逗号分隔指定多个，如 `\"42,123,456\"` |\n| `lyrics` | string | 否 | `\"\"` | 直接传入歌词（优先级高于 messages 中解析的歌词），此时 messages 文本作为 prompt |\n| `sample_mode` | boolean | 否 | `false` | 启用 LLM sample 模式，messages 文本作为 sample_query 由 LLM 自动生成 prompt/lyrics |\n| `thinking` | boolean | 否 | `false` | 是否启用 LLM thinking 模式（更深度推理） |\n| `use_format` | boolean | 否 | `false` | 当用户提供 prompt/lyrics 时，是否先通过 LLM 格式化增强 |\n| `use_cot_caption` | boolean | 否 | `true` | 是否通过 CoT 改写/增强音乐描述 |\n| `use_cot_language` | boolean | 否 | `true` | 是否通过 CoT 自动检测歌词语言 |\n| `guidance_scale` | float | 否 | `7.0` | Classifier-free guidance scale |\n| `batch_size` | int | 否 | `1` | 生成音频数量 |\n| `task_type` | string | 否 | `\"text2music\"` | 任务类型，见 [音频输入](#音频输入) |\n| `repainting_start` | float | 否 | `0.0` | repaint 区域起始位置（秒） |\n| `repainting_end` | float | 否 | `null` | repaint 区域结束位置（秒） |\n| `audio_cover_strength` | float | 否 | `1.0` | cover 强度 (0.0~1.0) |\n\n#### audio_config 对象\n\n| 字段 | 类型 | 默认值 | 说明 |\n|---|---|---|---|\n| `duration` | float | `null` | 音频时长（秒），不传由 LM 自动决定 |\n| `bpm` | integer | `null` | 每分钟节拍数，不传由 LM 自动决定 |\n| `vocal_language` | string | `\"en\"` | 歌词语言代码（如 `\"zh\"`, `\"en\"`, `\"ja\"`） |\n| `instrumental` | boolean | `null` | 是否为纯器乐（无人声）。不传时根据歌词自动判断 |\n| `format` | string | `\"mp3\"` | 输出音频格式 |\n| `key_scale` | string | `null` | 调号（如 `\"C major\"`） |\n| `time_signature` | string | `null` | 拍号（如 `\"4/4\"`） |\n\n> **messages 文本含义取决于模式：**\n> - 设置了 `lyrics` → messages 文本 = caption\n> - 设置了 `sample_mode: true` → messages 文本 = sample_query（交给 LLM 生成一切）\n> - 均未设置 → 自动检测：有标签走标签模式，像歌词走歌词模式，否则作为 caption 直接传入生成\n\n#### messages 格式\n\n支持纯文本和多模态（文本 + 音频）两种格式：\n\n**纯文本：**\n\n```json\n{\n  \"messages\": [\n    {\"role\": \"user\", \"content\": \"你的输入内容\"}\n  ]\n}\n```\n\n**多模态（含音频输入）：**\n\n```json\n{\n  \"messages\": [\n    {\n      \"role\": \"user\",\n      \"content\": [\n        {\"type\": \"text\", \"text\": \"翻唱这首歌\"},\n        {\n          \"type\": \"input_audio\",\n          \"input_audio\": {\n            \"data\": \"<base64 音频数据>\",\n            \"format\": \"mp3\"\n          }\n        }\n      ]\n    }\n  ]\n}\n```\n\n---\n\n#### 非流式响应 (`stream: false`)\n\n```json\n{\n  \"id\": \"chatcmpl-a1b2c3d4e5f6g7h8\",\n  \"object\": \"chat.completion\",\n  \"created\": 1706688000,\n  \"model\": \"acemusic/acestep-v15-turbo\",\n  \"choices\": [\n    {\n      \"index\": 0,\n      \"message\": {\n        \"role\": \"assistant\",\n        \"content\": \"## Metadata\\n**Caption:** Upbeat pop song...\\n**BPM:** 120\\n**Duration:** 30s\\n**Key:** C major\\n\\n## Lyrics\\n[Verse 1]\\nHello world...\",\n        \"audio\": [\n          {\n            \"type\": \"audio_url\",\n            \"audio_url\": {\n              \"url\": \"data:audio/mpeg;base64,SUQzBAAAAAAAI1RTU0UAAAA...\"\n            }\n          }\n        ]\n      },\n      \"finish_reason\": \"stop\"\n    }\n  ],\n  \"usage\": {\n    \"prompt_tokens\": 10,\n    \"completion_tokens\": 100,\n    \"total_tokens\": 110\n  }\n}\n```\n\n**响应字段说明：**\n\n| 字段 | 说明 |\n|---|---|\n| `choices[0].message.content` | LM 生成的文本信息，包含 Metadata（Caption/BPM/Duration/Key/Time Signature/Language）和 Lyrics。如果 LM 未参与，返回 `\"Music generated successfully.\"` |\n| `choices[0].message.audio` | 音频数据数组，每项包含 `type` (`\"audio_url\"`) 和 `audio_url.url`（Base64 Data URL，格式 `data:audio/mpeg;base64,...`） |\n| `choices[0].finish_reason` | `\"stop\"` 表示正常完成 |\n\n**音频解码格式：**\n\n`audio_url.url` 值为 Data URL 格式：`data:audio/mpeg;base64,<base64_data>`\n\n客户端提取 base64 数据部分后解码即可得到 MP3 文件：\n\n```python\nimport base64\n\nurl = response[\"choices\"][0][\"message\"][\"audio\"][0][\"audio_url\"][\"url\"]\n# 去掉 \"data:audio/mpeg;base64,\" 前缀\nb64_data = url.split(\",\", 1)[1]\naudio_bytes = base64.b64decode(b64_data)\n\nwith open(\"output.mp3\", \"wb\") as f:\n    f.write(audio_bytes)\n```\n\n```javascript\nconst url = response.choices[0].message.audio[0].audio_url.url;\nconst b64Data = url.split(\",\")[1];\nconst audioBytes = atob(b64Data);\n// 或直接用于 <audio> 标签\nconst audio = new Audio(url);\naudio.play();\n```\n\n---\n\n### 2. 模型列表\n\n**GET** `/v1/models`\n\n返回可用模型信息。\n\n#### 响应\n\n```json\n{\n  \"data\": [\n    {\n      \"id\": \"acemusic/acestep-v15-turbo\",\n      \"name\": \"ACE-Step\",\n      \"created\": 1706688000,\n      \"description\": \"High-performance text-to-music generation model. Supports multiple styles, lyrics input, and various audio durations.\",\n      \"input_modalities\": [\"text\", \"audio\"],\n      \"output_modalities\": [\"audio\", \"text\"],\n      \"context_length\": 4096,\n      \"pricing\": {\"prompt\": \"0\", \"completion\": \"0\", \"request\": \"0\"},\n      \"supported_sampling_parameters\": [\"temperature\", \"top_p\"]\n    }\n  ]\n}\n```\n\n---\n\n### 3. 健康检查\n\n**GET** `/health`\n\n#### 响应\n\n```json\n{\n  \"status\": \"ok\",\n  \"service\": \"ACE-Step OpenRouter API\",\n  \"version\": \"1.0\"\n}\n```\n\n---\n\n## 输入模式\n\n系统根据 `messages` 中最后一条 `user` 消息的内容自动选择输入模式。也可通过 `lyrics` 或 `sample_mode` 字段显式指定。\n\n### 模式 1: 标签模式（推荐）\n\n使用 `<prompt>` 和 `<lyrics>` 标签明确指定音乐描述和歌词：\n\n```json\n{\n  \"messages\": [\n    {\n      \"role\": \"user\",\n      \"content\": \"<prompt>A gentle acoustic ballad in C major, female vocal</prompt>\\n<lyrics>[Verse 1]\\nSunlight through the window\\nA brand new day begins\\n\\n[Chorus]\\nWe are the dreamers\\nWe are the light</lyrics>\"\n    }\n  ],\n  \"audio_config\": {\n    \"duration\": 30,\n    \"vocal_language\": \"en\"\n  }\n}\n```\n\n- `<prompt>...</prompt>` — 音乐风格/场景描述（即 caption）\n- `<lyrics>...</lyrics>` — 歌词内容\n- 两个标签可以只传其中一个\n- 当 `use_format: true` 时，LLM 会自动增强 prompt 和 lyrics\n\n### 模式 2: 自然语言模式（Sample 模式）\n\n直接用自然语言描述想要的音乐，系统自动通过 LLM 生成 prompt 和 lyrics：\n\n```json\n{\n  \"messages\": [\n    {\"role\": \"user\", \"content\": \"帮我生成一首欢快的中文流行歌曲，关于夏天和旅行\"}\n  ],\n  \"sample_mode\": true,\n  \"audio_config\": {\n    \"vocal_language\": \"zh\"\n  }\n}\n```\n\n触发条件：`sample_mode: true`，或消息内容不包含标签且不像歌词时自动触发。\n\n### 模式 3: 纯歌词模式\n\n直接传入带结构标记的歌词，系统自动识别：\n\n```json\n{\n  \"messages\": [\n    {\n      \"role\": \"user\",\n      \"content\": \"[Verse 1]\\nWalking down the street\\nFeeling the beat\\n\\n[Chorus]\\nDance with me tonight\\nUnder the moonlight\"\n    }\n  ],\n  \"audio_config\": {\"duration\": 30}\n}\n```\n\n触发条件：消息内容包含 `[Verse]`、`[Chorus]` 等标记，或有多行短文本结构。\n\n### 模式 4: 歌词 + Prompt 分离\n\n通过 `lyrics` 字段直接传入歌词，messages 文本自动作为 prompt：\n\n```json\n{\n  \"messages\": [\n    {\"role\": \"user\", \"content\": \"Energetic EDM with heavy bass drops\"}\n  ],\n  \"lyrics\": \"[Verse 1]\\nFeel the rhythm in your soul\\nLet the music take control\\n\\n[Drop]\\n(instrumental break)\",\n  \"audio_config\": {\n    \"bpm\": 128,\n    \"duration\": 60\n  }\n}\n```\n\n### 器乐模式\n\n设置 `audio_config.instrumental: true`：\n\n```json\n{\n  \"messages\": [\n    {\"role\": \"user\", \"content\": \"<prompt>Epic orchestral cinematic score, dramatic and powerful</prompt>\"}\n  ],\n  \"audio_config\": {\n    \"instrumental\": true,\n    \"duration\": 30\n  }\n}\n```\n\n---\n\n## 音频输入\n\n支持通过多模态 messages 传入音频文件（base64 编码），用于 cover、repaint 等任务。\n\n### task_type 类型\n\n| task_type | 说明 | 需要音频输入 |\n|---|---|---|\n| `text2music` | 文本生成音乐（默认） | 可选（作为 reference） |\n| `cover` | 翻唱/风格迁移 | 需要 src_audio |\n| `repaint` | 局部重绘 | 需要 src_audio |\n| `lego` | 音频拼接 | 需要 src_audio |\n| `extract` | 音频提取 | 需要 src_audio |\n| `complete` | 音频续写 | 需要 src_audio |\n\n### 音频路由规则\n\n多个 `input_audio` 块按顺序路由到不同参数（类似多图片上传）：\n\n| task_type | audio[0] | audio[1] |\n|---|---|---|\n| `text2music` | reference_audio（风格参考） | - |\n| `cover/repaint/lego/extract/complete` | src_audio（待编辑音频） | reference_audio（可选风格参考） |\n\n### 音频输入示例\n\n**Cover 任务（翻唱）：**\n\n```json\n{\n  \"messages\": [\n    {\n      \"role\": \"user\",\n      \"content\": [\n        {\"type\": \"text\", \"text\": \"<prompt>Jazz style cover with saxophone</prompt>\"},\n        {\n          \"type\": \"input_audio\",\n          \"input_audio\": {\"data\": \"<base64 原始音频>\", \"format\": \"mp3\"}\n        }\n      ]\n    }\n  ],\n  \"task_type\": \"cover\",\n  \"audio_cover_strength\": 0.8,\n  \"audio_config\": {\"duration\": 30}\n}\n```\n\n**Repaint 任务（局部重绘）：**\n\n```json\n{\n  \"messages\": [\n    {\n      \"role\": \"user\",\n      \"content\": [\n        {\"type\": \"text\", \"text\": \"<prompt>Replace with guitar solo</prompt>\"},\n        {\n          \"type\": \"input_audio\",\n          \"input_audio\": {\"data\": \"<base64 原始音频>\", \"format\": \"mp3\"}\n        }\n      ]\n    }\n  ],\n  \"task_type\": \"repaint\",\n  \"repainting_start\": 10.0,\n  \"repainting_end\": 20.0,\n  \"audio_config\": {\"duration\": 30}\n}\n```\n\n---\n\n## 流式响应\n\n设置 `\"stream\": true` 启用 SSE（Server-Sent Events）流式返回。\n\n### 事件格式\n\n每个事件以 `data: ` 开头，后跟 JSON，以双换行 `\\n\\n` 结尾：\n\n```\ndata: {\"id\":\"chatcmpl-xxx\",\"object\":\"chat.completion.chunk\",\"created\":1706688000,\"model\":\"acemusic/acestep-v15-turbo\",\"choices\":[{\"index\":0,\"delta\":{...},\"finish_reason\":null}]}\n\n```\n\n### 流式事件顺序\n\n| 阶段 | delta 内容 | 说明 |\n|---|---|---|\n| 1. 初始化 | `{\"role\":\"assistant\",\"content\":\"\"}` | 建立连接 |\n| 2. LM 内容 | `{\"content\":\"\\n\\n## Metadata\\n...\"}` | LM 参与时推送 metadata 和 lyrics |\n| 3. 心跳 | `{\"content\":\".\"}` | 音频生成期间每 2 秒发送，保持连接 |\n| 4. 音频数据 | `{\"audio\":[{\"type\":\"audio_url\",\"audio_url\":{\"url\":\"data:...\"}}]}` | 音频 base64 |\n| 5. 结束 | `finish_reason: \"stop\"` | 生成完成 |\n| 6. 终止 | `data: [DONE]` | 流结束标记 |\n\n### 流式响应示例\n\n```\ndata: {\"id\":\"chatcmpl-abc123\",\"object\":\"chat.completion.chunk\",\"created\":1706688000,\"model\":\"acemusic/acestep-v15-turbo\",\"choices\":[{\"index\":0,\"delta\":{\"role\":\"assistant\",\"content\":\"\"},\"finish_reason\":null}]}\n\ndata: {\"id\":\"chatcmpl-abc123\",\"object\":\"chat.completion.chunk\",\"created\":1706688000,\"model\":\"acemusic/acestep-v15-turbo\",\"choices\":[{\"index\":0,\"delta\":{\"content\":\"\\n\\n## Metadata\\n**Caption:** Upbeat pop\\n**BPM:** 120\"},\"finish_reason\":null}]}\n\ndata: {\"id\":\"chatcmpl-abc123\",\"object\":\"chat.completion.chunk\",\"created\":1706688000,\"model\":\"acemusic/acestep-v15-turbo\",\"choices\":[{\"index\":0,\"delta\":{\"content\":\".\"},\"finish_reason\":null}]}\n\ndata: {\"id\":\"chatcmpl-abc123\",\"object\":\"chat.completion.chunk\",\"created\":1706688000,\"model\":\"acemusic/acestep-v15-turbo\",\"choices\":[{\"index\":0,\"delta\":{\"audio\":[{\"type\":\"audio_url\",\"audio_url\":{\"url\":\"data:audio/mpeg;base64,...\"}}]},\"finish_reason\":null}]}\n\ndata: {\"id\":\"chatcmpl-abc123\",\"object\":\"chat.completion.chunk\",\"created\":1706688000,\"model\":\"acemusic/acestep-v15-turbo\",\"choices\":[{\"index\":0,\"delta\":{},\"finish_reason\":\"stop\"}]}\n\ndata: [DONE]\n\n```\n\n### 客户端处理流式响应\n\n```python\nimport json\nimport httpx\n\nwith httpx.stream(\"POST\", \"http://127.0.0.1:8002/v1/chat/completions\", json={\n    \"messages\": [{\"role\": \"user\", \"content\": \"生成一首轻快的吉他曲\"}],\n    \"sample_mode\": True,\n    \"stream\": True,\n    \"audio_config\": {\"instrumental\": True}\n}) as response:\n    content_parts = []\n    audio_url = None\n\n    for line in response.iter_lines():\n        if not line or not line.startswith(\"data: \"):\n            continue\n        if line == \"data: [DONE]\":\n            break\n\n        chunk = json.loads(line[6:])\n        delta = chunk[\"choices\"][0][\"delta\"]\n\n        if \"content\" in delta and delta[\"content\"]:\n            content_parts.append(delta[\"content\"])\n\n        if \"audio\" in delta and delta[\"audio\"]:\n            audio_url = delta[\"audio\"][0][\"audio_url\"][\"url\"]\n\n        if chunk[\"choices\"][0].get(\"finish_reason\") == \"stop\":\n            print(\"Generation complete!\")\n\n    print(\"Content:\", \"\".join(content_parts))\n    if audio_url:\n        import base64\n        b64_data = audio_url.split(\",\", 1)[1]\n        with open(\"output.mp3\", \"wb\") as f:\n            f.write(base64.b64decode(b64_data))\n```\n\n```javascript\nconst response = await fetch(\"http://127.0.0.1:8002/v1/chat/completions\", {\n  method: \"POST\",\n  headers: { \"Content-Type\": \"application/json\" },\n  body: JSON.stringify({\n    messages: [{ role: \"user\", content: \"生成一首轻快的吉他曲\" }],\n    sample_mode: true,\n    stream: true,\n    audio_config: { instrumental: true }\n  })\n});\n\nconst reader = response.body.getReader();\nconst decoder = new TextDecoder();\nlet audioUrl = null;\nlet content = \"\";\n\nwhile (true) {\n  const { done, value } = await reader.read();\n  if (done) break;\n\n  const text = decoder.decode(value);\n  for (const line of text.split(\"\\n\")) {\n    if (!line.startsWith(\"data: \") || line === \"data: [DONE]\") continue;\n\n    const chunk = JSON.parse(line.slice(6));\n    const delta = chunk.choices[0].delta;\n\n    if (delta.content) content += delta.content;\n    if (delta.audio) audioUrl = delta.audio[0].audio_url.url;\n  }\n}\n\n// audioUrl 可直接用于 <audio src=\"...\">\n```\n\n---\n\n## 完整示例\n\n### 示例 1: 自然语言生成（最简用法）\n\n```bash\ncurl -X POST http://127.0.0.1:8002/v1/chat/completions \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\n    \"messages\": [\n      {\"role\": \"user\", \"content\": \"一首温柔的中文民谣，关于故乡和回忆\"}\n    ],\n    \"sample_mode\": true,\n    \"audio_config\": {\"vocal_language\": \"zh\"}\n  }'\n```\n\n### 示例 2: 标签模式 + 指定参数\n\n```bash\ncurl -X POST http://127.0.0.1:8002/v1/chat/completions \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\n    \"messages\": [\n      {\n        \"role\": \"user\",\n        \"content\": \"<prompt>Energetic EDM track with heavy bass drops and synth leads</prompt><lyrics>[Verse 1]\\nFeel the rhythm in your soul\\nLet the music take control\\n\\n[Drop]\\n(instrumental break)</lyrics>\"\n      }\n    ],\n    \"audio_config\": {\n      \"bpm\": 128,\n      \"duration\": 60,\n      \"vocal_language\": \"en\"\n    }\n  }'\n```\n\n### 示例 3: 纯器乐 + 关闭 LM 增强\n\n```bash\ncurl -X POST http://127.0.0.1:8002/v1/chat/completions \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\n    \"messages\": [\n      {\n        \"role\": \"user\",\n        \"content\": \"<prompt>Peaceful piano solo, slow tempo, jazz harmony</prompt>\"\n      }\n    ],\n    \"use_cot_caption\": false,\n    \"audio_config\": {\n      \"instrumental\": true,\n      \"duration\": 45\n    }\n  }'\n```\n\n### 示例 4: 流式请求\n\n```bash\ncurl -X POST http://127.0.0.1:8002/v1/chat/completions \\\n  -H \"Content-Type: application/json\" \\\n  -N \\\n  -d '{\n    \"messages\": [\n      {\"role\": \"user\", \"content\": \"Generate a happy birthday song\"}\n    ],\n    \"sample_mode\": true,\n    \"stream\": true\n  }'\n```\n\n### 示例 5: 多种子批量生成\n\n```bash\ncurl -X POST http://127.0.0.1:8002/v1/chat/completions \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\n    \"messages\": [\n      {\"role\": \"user\", \"content\": \"<prompt>Lo-fi hip hop beat</prompt>\"}\n    ],\n    \"batch_size\": 3,\n    \"seed\": \"42,123,456\",\n    \"audio_config\": {\n      \"instrumental\": true,\n      \"duration\": 30\n    }\n  }'\n```\n\n---\n\n## 错误码\n\n| HTTP 状态码 | 说明 |\n|---|---|\n| 400 | 请求格式错误或缺少有效输入 |\n| 401 | API Key 缺失或无效 |\n| 429 | 服务繁忙，队列已满 |\n| 500 | 音乐生成过程中发生内部错误 |\n| 503 | 模型尚未初始化完成 |\n| 504 | 生成超时 |\n\n错误响应格式：\n\n```json\n{\n  \"detail\": \"错误描述信息\"\n}\n```\n\n---\n\n## 环境变量配置\n\n以下环境变量可用于配置服务端（供运维参考）：\n\n| 变量名 | 默认值 | 说明 |\n|---|---|---|\n| `OPENROUTER_API_KEY` | 无 | API 认证密钥 |\n| `OPENROUTER_HOST` | `127.0.0.1` | 监听地址 |\n| `OPENROUTER_PORT` | `8002` | 监听端口 |\n| `ACESTEP_CONFIG_PATH` | `acestep-v15-turbo` | DiT 模型配置路径 |\n| `ACESTEP_DEVICE` | `auto` | 推理设备 |\n| `ACESTEP_LM_MODEL_PATH` | `acestep-5Hz-lm-0.6B` | LLM 模型路径 |\n| `ACESTEP_LM_BACKEND` | `vllm` | LLM 推理后端 |\n| `ACESTEP_QUEUE_MAXSIZE` | `200` | 任务队列最大容量 |\n| `ACESTEP_GENERATION_TIMEOUT` | `600` | 非流式请求超时（秒） |\n"
  },
  {
    "path": "docs/zh/Tutorial.md",
    "content": "# ACE-Step 1.5 终极指南（必读）\n\n大家好，我是ACE-Step 的开发者，龚俊民。我将通过这篇教程，带你了解 ACE-Step 1.5 的设计哲学与使用方法。\n\n## 心智模型\n\n在开始之前，我们需要先建立正确的心智模型，以便做好预期管理。\n\n### 以人为中心的设计\n\n这个模型不是为**一键生成**而设计的，而是为**以人为中心的生成**而设计的。\n\n理解这个区别至关重要。\n\n### 什么是一键生成？\n\n你输入提示词，点击生成，听几个版本，选一个听起来不错的，拿来用。换一个人输入同样的提示词，大概率得到相似的结果。\n\n这种模式下，你和 AI 是**甲方与乙方**的关系。你带着明确的目的而来，脑海中已有一个模糊的预期，希望 AI 交付一个接近那个预期的成品。本质上，它和去 Google 搜索、去 Spotify 找歌没有太大区别——只是多了一点定制化。\n\nAI 是一种服务，而不是创意的启发者。\n\nSuno、Udio、MiniMax、Mureka——这些平台都是这样的设计初衷。它们可以把模型堆大，作为服务保障交付即可。你生成的音乐受他们的协议约束；你无法在本地运行，无法微调做个性化的探索；如果他们暗中改变模型或条款，你只能接受。\n\n### 什么是以人为中心的生成？\n\n如果我们弱化 AI 那一层，强化人那一层——让更多的人的意志、创意、灵感赋予 AI 生命——这就是以人为中心的生成。\n\n不同于一键生成的强目的性，以人为中心的生成更具备**玩**的性质。它更像一场交互的游戏，你和模型是**合作者**的关系。\n\n工作流是这样的：你先抛出一些灵感种子，得到几首歌，从中选择感兴趣的方向继续迭代——\n- 调整 prompt 重新生成\n- 用 **Cover** 保持结构、调整细节\n- 用 **Repaint** 做局部修改\n- 用 **Add Layer** 增减乐器层次\n\n这时，AI 对你而言不是服务者，而是**启发者**。\n\n### 这种设计需要满足什么条件？\n\n要让以人为中心的生成真正成立，模型必须满足几个关键条件：\n\n**首先，必须开源、本地可运行、可训练。**\n\n这不是技术洁癖，而是所有权的问题。当你使用闭源平台，你不拥有模型，你生成的作品也受制于他们的协议。版本更新、条款变更、服务下线——这些都不在你的掌控之中。\n\n而当模型开源且可本地运行，一切都不同了：**你永远拥有这个模型，你也永远拥有你和模型一起创造的所有产物。** 没有第三方协议的困扰，没有平台风险，你可以微调、可以魔改、可以基于它构建属于自己的创作系统，你的作品将永远属于你。他就像是你买的一个乐器，你可以随时随地使用它，也可以随时随地调整它。\n\n**其次，必须快。**\n\n人的时间是宝贵的，但更重要的是——**慢的生成会破坏心流**。\n\n以人为中心的工作流的核心是「试一试、听一听、再调整」的快速循环。如果每次生成都要等几分钟，你的灵感会在等待中消散，「玩」的体验会退化成「等」的煎熬。\n\n因此，我们专门为此优化了 ACE-Step：在保证质量的前提下，让生成速度足够快，快到能够承载一个流畅的人机对话节奏。\n\n### 有限游戏 vs 无限游戏\n\n一键生成是一场**有限游戏**——目标明确，结果导向，结束即终点。某种程度上，它冷酷地掏空了音乐产业，取代了许多人的工作。\n\n以人为中心的生成是一场**无限游戏**——因为乐趣藏在过程之中，而过程永无止境。\n\n我们的愿景是民主化 AI 音乐生成。让 ACE-Step 成为你口袋里的一个大玩具，让音乐回归 **Play** 本身——是融入创意的「玩」，而不只是点击播放的「Play」。\n\n---\n\n## 骑象人的隐喻\n\n> 推荐阅读：[The Complete Guide to Mastering Suno](https://www.notion.so/The-Complete-Guide-to-Mastering-Suno-Advanced-Strategies-for-Professional-Music-Generation-2d6ae744ebdf8024be42f6645f884221)——这篇博文教程能帮助你建立理解 AI 音乐的基础认知。\n\nAI 音乐生成，就像心理学中那个著名的**骑象人隐喻**。\n\n意识骑在潜意识上，人骑在大象上。你可以给出方向，但你无法让大象精准地、即时地执行你的每一个指令。它有自己的惯性，自己的脾气，自己的意志。\n\n这只大象，就是音乐生成模型。\n\n### 冰山模型\n\n音频和语义之间的联系，隐藏着一座冰山。\n\n我们能用语言描述的东西——风格、乐器、音色、情绪、场景、起承转合、歌词内容、演唱方式——这些都是我们熟悉的词汇，是我们能触及的部分。但它们加在一起，仍然只是音频这座冰山浮出海面的很小一角。\n\n最精准的控制是什么？是你拿着预期的音频输入，模型原封不动地返回输出。\n\n而只要你用的是文字描述、是参考、是提示——模型就一定有自己的发挥空间。这不是 bug，这是本质。\n\n### 大象是什么？\n\n这只大象是无数元素的融合体：数据的分布、模型的规模、算法的设计、标注的偏差、评估的偏差——**它是人类音乐历史与工程权衡的抽象结晶。**\n\n其中任意一个要素的偏差，都会导致它无法精准地反映你的品味和预期。\n\n当然，我们可以扩大数据规模、提升算法效率、提高标注精度、扩大模型容量、引入更专业的评估体系——这些都是作为模型开发者可以优化的方向。\n\n但即使有一天，技术上我们做到了「完美」，还有一个根本问题无法回避：**品味。**\n\n### 品味与期望\n\n品味因人而异。\n\n如果一个音乐生成模型试图取悦所有听众，它的输出将趋向于人类音乐历史的流行平均值——**这将平庸至极。**\n\n是人赋予声音以意义以情感以经历以生命，赋予它们文化符号的价值。是少数艺术家群体创造了独特的品味，然后带动普通人去消费、去追随，小众才变成了大众流行。这些少数派的先锋艺术家，便成为了传奇。\n\n所以，当你发现模型的输出「不对味」时，这有时可能不是模型的问题——**而是你的品味恰好不在那个「平均」上。** 这是好事。\n\n这意味着：**你需要学会引导这只大象，而不是期待它自动懂你。**\n\n---\n\n## 认识象群：模型架构与选择\n\n现在你已经理解了「大象」这个隐喻。但实际上——\n\n**这不是一只大象，而是一整个象群——大大小小的象，组成了一个家族。** 🐘🐘🐘🐘\n\n### 架构原理：两个大脑\n\nACE-Step 1.5 采用**混合架构**，有两个核心组件协同工作：\n\n```\n用户输入 → [5Hz LM] → 语义蓝图 → [DiT] → 音频\n              ↓\n         元数据推理\n         Caption 优化\n         结构规划\n```\n\n**5Hz LM（语言模型）—— 规划者（可选）**\n\nLM 是「全能规划器」，负责理解你的意图并制定计划：\n- 通过 **Chain-of-Thought** 推理音乐元数据（BPM、调性、时长等）\n- 优化和扩展你的 caption——这是对你意图的理解和补充\n- 生成**语义 codes**——隐式包含作曲旋律、配器编排、以及少许音色信息\n\nLM 学到的是训练数据中的**世界知识**。它是一个提升可用性、帮你快速生成原型的规划者。\n\n**但 LM 不是必须的。**\n\n如果你非常清楚自己想要什么，或者已经有了明确的规划目标——你完全可以不用 `thinking` 模式，跳过 LM 的规划步骤。\n\n比如在 **Cover 模式**中，你用参考音频来约束作曲、和弦、结构，直接让 DiT 去生成。这时，**你取代了 LM 的工作**——你自己成为了规划者。\n再比如，在 **Repaint 模式**中，你将参考音频作为上下文，限定音色、混音和细节，让 DiT 直接对局部进行调整。此时，DiT 更像是你的灵感激发伙伴，既可以帮助你进行创意脑暴，也可以用于修复局部的不和谐。\n\n**DiT（Diffusion Transformer）—— 执行者**\n\nDiT 是「音频工匠」，负责将规划变为现实：\n- 接收 LM 生成的语义 codes 和条件\n- 通过**扩散过程**从噪声中逐步「雕刻」出音频\n- 决定最终的音色、混音、细节\n\n**为什么这样设计？**\n\n传统方法让扩散模型直接从文本生成音频，但文本到音频的映射太模糊。ACE-Step 引入 LM 作为中间层：\n- LM 擅长理解语义、做规划\n- DiT 擅长生成高保真音频\n- 两者配合，各司其职\n\n### 选择规划者：LM 模型\n\nLM 有四种选择：**无 LM**（关闭 thinking 模式）、**0.6B**、**1.7B**、**4B**。\n\n它们的训练数据完全一致，区别纯粹在于**知识容量**：\n- 模型越大，世界知识越丰富\n- 模型越大，记忆能力越强（比如记住参考音频的旋律）\n- 模型越大，在长尾的风格或乐器中表现也相对更好\n\n| 选择 | 速度 | 世界知识 | 记忆能力 | 适用场景 |\n|------|:----:|:--------:|:--------:|----------|\n| 无 LM | ⚡⚡⚡⚡ | — | — | 你自己做规划（如 Cover 模式） |\n| `0.6B` | ⚡⚡⚡ | 基础 | 弱 | 低显存（< 8GB）、快速原型 |\n| `1.7B` | ⚡⚡ | 中等 | 中等 | **默认推荐** |\n| `4B` | ⚡ | 丰富 | 强 | 复杂任务、高质量生成 |\n\n**如何选择？**\n\n根据你的硬件条件：\n- **显存 < 8GB** → 无 LM 或 `0.6B`\n- **显存 8–16GB** → `1.7B`（默认）\n- **显存 > 16GB** → `1.7B` 或 `4B`\n\n### 选择执行者：DiT 模型\n\n有了规划方案，还需要选择执行者。DiT 是 ACE-Step 1.5 最核心的部分——它承载各种任务，决定如何解读 LM 生成的 codes。\n\n我们开源了 **4 个 Turbo 模型**、**1 个 SFT 模型**、**1 个 Base 模型**。\n\n#### Turbo 系列（推荐日常使用）\n\nTurbo 模型经过蒸馏训练，只需 8 步即可生成高质量音频。四个变体的核心差别在于**蒸馏时的 shift 超参配置**。\n\n**什么是 shift？**\n\nshift 决定了 DiT 去噪时的「注意力分配」：\n- **shift 越大** → 更多精力花在早期去噪（从纯噪声中建立大结构），**语义更强**，整体框架更清晰\n- **shift 越小** → 去噪步数分配更均匀，**细节更多**，但细节也可能是噪音\n\n简单理解：高 shift 像「先画轮廓再填细节」，低 shift 像「边画边修」。\n\n| 模型 | 蒸馏配置 | 特点 |\n|------|----------|------|\n| `turbo`（默认） | 在 shift 1, 2, 3 上联合蒸馏 | **创造性与语义兼顾最佳**，经过充分测试，推荐首选 |\n| `turbo-shift1` | 仅在 shift=1 上蒸馏 | 细节更丰富，但语义会弱一些 |\n| `turbo-shift3` | 仅在 shift=3 上蒸馏 | 音色更清晰丰富，但会显得「干」，配器偏极简 |\n| `turbo-continuous` | 实验性，支持 shift 1–5 连续调节 | 调参最灵活，但未经充分测试 |\n\n你可以根据目标音乐风格选择，也许你会发现自己对某个变体有偏好。**我们推荐从默认 turbo 开始**——它是最平衡、最经得起考验的选择。\n\n#### SFT 模型\n\n与 Turbo 相比，SFT 模型有两个显著特点：\n- **支持 CFG**（Classifier-Free Guidance），可以精细调节 prompt 遵循程度\n- **步数更多**（50 步），给模型更多时间「思考」\n\n代价是：步数多意味着误差累积，音质清晰度可能略逊于 Turbo。但它的**细节表现和语义解析会更好**。\n\n如果你不在乎推理时间，喜欢调 CFG 和步数，且偏好那种丰富的细节感——SFT 是一个好选择。LM 生成的 codes 同样可以作用于 SFT 模型。\n\n#### Base 模型\n\nBase 是**任务的集大成者**，比 SFT 和 Turbo 多出三个独占任务：\n\n| 任务 | 说明 |\n|------|------|\n| `extract` | 从混合轨道中抽取单个音轨（如分离人声） |\n| `lego` | 给已有轨道添加新轨道（如给吉他加鼓） |\n| `complete` | 给单轨添加混合伴奏（如给人声加吉他+鼓的伴奏） |\n\n此外，Base 的**可塑性最强**。如果你有大规模数据微调的需求，推荐从 Base 开始实验，训练专属你的 SFT 模型。\n\n#### 创建专属你的自定义模型\n\n除了官方模型，你还可以用 **LoRA 微调**创建专属你的自定义模型。\n\n我们会发布一个示例 LoRA 模型——用 20 多首「新年快乐」主题的歌曲训练，专门适合表达节日氛围。这只是一个起点。\n\n**自定义模型意味着什么？**\n\n你可以用专属的数据配方，重塑 DiT 的能力和偏好：\n- 喜欢某种特定的音色风格？用那类歌曲训练\n- 想让模型更擅长某种曲风？收集相关数据微调\n- 有自己独特的审美品味？把它「教」给模型\n\n这极大拓展了**定制化和可玩性**——用你的审美品味，训练出专属你的模型。\n\n> 关于 LoRA 训练的详细指南，请参阅 [LoRA 训练教程](./LoRA_Training_Tutorial.md)。你也可以使用 Gradio UI 中的「LoRA Training」标签页进行一键训练。\n\n#### DiT 选择总结\n\n| 模型 | 步数 | CFG | 速度 | 独占任务 | 推荐场景 |\n|------|:----:|:---:|:----:|----------|----------|\n| `turbo`（默认） | 8 | ❌ | ⚡⚡⚡ | — | 日常使用，快速迭代 |\n| `sft` | 50 | ✅ | ⚡ | — | 追求细节，喜欢调参 |\n| `base` | 50 | ✅ | ⚡ | extract, lego, complete | 特殊任务，大规模微调 |\n\n### 组合搭配\n\n默认配置是 **turbo + 1.7B LM**，适合大多数场景。\n\n| 需求 | 推荐组合 |\n|------|----------|\n| 最快速度 | `turbo` + 无 LM 或 `0.6B` |\n| 日常使用 | `turbo` + `1.7B`（默认） |\n| 追求细节 | `sft` + `1.7B` 或 `4B` |\n| 特殊任务 | `base`|\n| 大规模微调 | `base`|\n| 低显存（< 4GB） | `turbo` + 无 LM + CPU offload |\n\n### 下载模型\n\n```bash\n# 下载默认模型（turbo + 1.7B LM）\nuv run acestep-download\n\n# 下载全部模型\nuv run acestep-download --all\n\n# 下载特定模型\nuv run acestep-download --model acestep-v15-base\nuv run acestep-download --model acestep-5Hz-lm-0.6B\n\n# 查看可用模型\nuv run acestep-download --list\n```\n\n你需要把模型下载在一个`checkpoints`的文件夹中，方便识别。\n\n---\n\n## 引导大象：你能控制什么？\n\n现在你已经认识了这群大象，接下来让我们学习如何与它们沟通。\n\n每一次生成，结果都由三类因素共同决定：**输入控制**、**推理超参**和**随机因素**。\n\n### 一、输入控制：你想要什么？\n\n这是你与模型沟通「创意意图」的部分——你想生成什么样的音乐。\n\n| 类别 | 参数 | 作用 |\n|------|------|------|\n| **任务类型** | `task_type` | 决定生成模式：text2music、cover、repaint、lego、extract、complete |\n| **文本输入** | `caption` | 对音乐整体要素的描述：风格、乐器、情绪、氛围、音色、演唱者性别、起承转合等 |\n| | `lyrics` | 时序要素的描述：歌词内容、音乐结构演进、演唱者变化、人声/乐器演奏方式、开始/结束方式、发声方式等（纯音乐填 `[Instrumental]`） |\n| **音乐元数据** | `bpm` | 速度（30–300） |\n| | `keyscale` | 调性（如 C Major、Am） |\n| | `timesignature` | 拍号（4/4、3/4、6/8） |\n| | `vocal_language` | 人声语言 |\n| | `duration` | 目标时长（秒） |\n| **音频参考** | `reference_audio` | 音色或风格的全局参考（用于 cover、风格迁移） |\n| | `src_audio` | 源音频，用于非 text2music 任务（text2music 默认静音，无需输入） |\n| | `audio_codes` | Cover模式下输入模型的语义 codes（高级用法：复用 codes 生成变体、将歌曲转 codes 拓展衍生、拼接组合像 DJ 一样混搭） |\n| **区间控制** | `repainting_start/end` | 操作的时间区间（repaint 重绘区域 / lego 新增分轨区域） |\n\n---\n\n#### 关于 Caption：最重要的输入\n\n**Caption 是影响生成音乐最重要的因素。**\n\n它支持多种输入形式：简单的风格词、逗号分隔的 tags、复杂的自然语言描述。我们在训练中兼容了各种各样的格式，确保文本形式不会显著影响模型表现。\n\n**我们提供了至少 5 种方式帮你写好 caption：**\n\n1. **随机骰子** — 点击 UI 中的随机按钮，看看样例的 caption 是怎么写的。你可以把这个规范化的 caption 作为模板，让 LLM 帮你改写成想要的形式。\n\n2. **Format 自动改写** — 我们支持用 `format` 功能，把你手写的简单 caption 自动扩展成复杂描述。\n\n3. **CoT 重写** — 如果初始化了 LM，无论是否开启 `thinking` 模式，我们都支持通过 Chain-of-Thought 为你重写和扩展 caption（除非你在设置中主动关闭，或没有初始化 LM）。\n\n4. **音频转 Caption** — 我们的 LM 支持将你输入的音频转换为 caption。虽然精度有限，但模糊的方向是对的——足以作为起点。\n\n5. **Simple 模式** — 只需输入一句简单的歌曲描述，LM 会自动为你生成完整的 caption、lyrics 和 metas 样本——适合快速起步。\n\n无论哪种方式，它们都解决了一个现实问题：**作为普通人，我们的音乐词汇是贫瘠的。**\n\n如果你想让生成的音乐更有趣、更符合预期，**Prompting 始终是最优选项**——它带来的边际收益和惊喜最大。\n\n**Caption 写作的常用维度：**\n\n| 维度 | 示例 |\n|------|------|\n| **风格/流派** | pop, rock, jazz, electronic, hip-hop, R&B, folk, classical, lo-fi, synthwave |\n| **情绪/氛围** | melancholic, uplifting, energetic, dreamy, dark, nostalgic, euphoric, intimate |\n| **乐器** | acoustic guitar, piano, synth pads, 808 drums, strings, brass, electric bass |\n| **音色质感** | warm, bright, crisp, muddy, airy, punchy, lush, raw, polished |\n| **时代参考** | 80s synth-pop, 90s grunge, 2010s EDM, vintage soul, modern trap |\n| **制作风格** | lo-fi, high-fidelity, live recording, studio-polished, bedroom pop |\n| **人声特点** | female vocal, male vocal, breathy, powerful, falsetto, raspy, choir |\n| **速度/节奏** | slow tempo, mid-tempo, fast-paced, groovy, driving, laid-back |\n| **结构提示** | building intro, catchy chorus, dramatic bridge, fade-out ending |\n\n**一些实用原则：**\n\n1. **具体优于模糊** — 「sad piano ballad with female breathy vocal」比「a sad song」效果好。\n\n2. **组合多个维度** — 单一维度的描述会让模型有太多发挥空间，组合风格+情绪+乐器+音色能更精准地锚定你想要的方向。\n\n3. **善用参考** — 「in the style of 80s synthwave」或「reminiscent of Bon Iver」可以快速传达复杂的美学偏好。\n\n4. **质感词很有用** — warm, crisp, airy, punchy 这类形容词能影响混音和音色的倾向。\n\n5. **不必追求完美描述** — Caption 是起点而非终点。先写一个大致方向，生成后根据结果迭代调整。\n\n6. **描述粒度决定自由度** — 描述越省略，模型发挥空间越大，随机因素影响越多；描述越细致，模型越受约束。根据你的需求决定具体程度——想要惊喜就写少点，想要可控就写详细点。\n\n7. **避免冲突词汇** — 冲突的风格组合容易导致劣化输出。比如同时要「古典弦乐」和「硬核金属」，模型会尝试融合但通常不理想。尤其开启 `thinking` 模式时，LM 在 caption 泛化性上弱于 DiT。当你prompting不合理时，出来惊喜的概率更小。\n\n   **解决冲突的方法：**\n   - **重复强化** — 通过重复某些词来强化混搭风格中你更想要的元素\n   - **冲突变演变** — 把风格冲突转化为时间上的风格演变。比如：「开头是柔和的弦乐，中段变成噪杂动态的金属摇滚，结尾转为 hip-hop」——这样模型有明确的指引，知道如何处理不同风格，而不是把它们混成一团\n\n> 更多 prompting 技巧可参考：[The Complete Guide to Mastering Suno](https://www.notion.so/The-Complete-Guide-to-Mastering-Suno-Advanced-Strategies-for-Professional-Music-Generation-2d6ae744ebdf8024be42f6645f884221)——虽然是针对 Suno 的教程，但 prompting 的思路是通用的。\n\n---\n\n#### 关于 Lyrics：时序的脚本\n\n如果说 Caption 描述的是音乐的「整体画像」——风格、氛围、音色——那么 **Lyrics 就是音乐的「时间脚本」**，它控制着音乐如何随时间展开。\n\nLyrics 不仅仅是歌词内容。它承载着：\n- 歌词文本本身\n- **结构标记**（[Verse]、[Chorus]、[Bridge]...）\n- **演唱方式提示**（[raspy vocal]、[whispered]...）\n- **乐器段落**（[guitar solo]、[drum break]...）\n- **能量变化**（[building energy]、[explosive drop]...）\n\n**结构标记是关键**\n\n结构标记（Meta Tags）是 Lyrics 中最强大的工具。它们告诉模型：「这一段是什么，应该怎么表现。」\n\n**常用结构标记：**\n\n| 类别 | 标记 | 说明 |\n|------|------|------|\n| **基础结构** | `[Intro]` | 开场，建立氛围 |\n| | `[Verse]` / `[Verse 1]` | 主歌，叙事推进 |\n| | `[Pre-Chorus]` | 导歌，积蓄能量 |\n| | `[Chorus]` | 副歌，情感高潮 |\n| | `[Bridge]` | 桥段，转折或升华 |\n| | `[Outro]` | 结尾，收束 |\n| **动态段落** | `[Build]` | 能量逐渐攀升 |\n| | `[Drop]` | 电子乐的能量释放 |\n| | `[Breakdown]` | 配器减少，留白 |\n| **器乐段落** | `[Instrumental]` | 纯器乐，无人声 |\n| | `[Guitar Solo]` | 吉他独奏 |\n| | `[Piano Interlude]` | 钢琴间奏 |\n| **特殊标记** | `[Fade Out]` | 渐弱结束 |\n| | `[Silence]` | 静默 |\n\n**组合标记：适度使用**\n\n结构标记可以用 `-` 符号组合，实现更精细的控制：\n\n```\n[Chorus - anthemic]\n这是副歌的歌词\n梦想在燃烧\n\n[Bridge - whispered]\n轻轻地说出那些话\n```\n\n这比单独写 `[Chorus]` 效果好——你同时告诉了模型这段是什么（Chorus）、以及怎么唱（anthemic）。\n\n**⚠️ 注意：不要堆叠太多标记。**\n\n```\n❌ 不推荐：\n[Chorus - anthemic - stacked harmonies - high energy - powerful - epic]\n\n✅ 推荐：\n[Chorus - anthemic]\n```\n\n堆叠过多标记有两个风险：\n1. 模型可能把标记内容错误地当作歌词唱出来\n2. 过多指令会让模型困惑，效果反而变差\n\n**原则**：结构标记保持简洁，复杂的风格描述放在 Caption 中。\n\n**⚠️ 关键：保持 Caption 和 Lyrics 的一致性**\n\n**模型不擅长解决冲突。** 如果 Caption 和 Lyrics 中的描述相矛盾，模型会困惑，输出质量下降。\n\n```\n❌ 冲突示例：\nCaption: \"violin solo, classical, intimate chamber music\"\nLyrics: [Guitar Solo - electric - distorted]\n\n✅ 一致示例：\nCaption: \"violin solo, classical, intimate chamber music\"\nLyrics: [Violin Solo - expressive]\n```\n\n**检查清单**：\n- Caption 中的乐器 ↔ Lyrics 中的器乐段落标记\n- Caption 中的情绪 ↔ Lyrics 中的能量标记\n- Caption 中的人声描述 ↔ Lyrics 中的人声控制标记\n\n把 Caption 想象成「整体设定」，Lyrics 想象成「分镜脚本」——它们应该讲述同一个故事。\n\n**人声控制标记：**\n\n| 标记 | 效果 |\n|------|------|\n| `[raspy vocal]` | 沙哑、有质感的人声 |\n| `[whispered]` | 轻声细语 |\n| `[falsetto]` | 假声 |\n| `[powerful belting]` | 高亢有力的演唱 |\n| `[spoken word]` | 说唱/朗诵 |\n| `[harmonies]` | 和声层叠 |\n| `[call and response]` | 一呼一应 |\n| `[ad-lib]` | 即兴装饰音 |\n\n**能量与情绪标记：**\n\n| 标记 | 效果 |\n|------|------|\n| `[high energy]` | 高能量、激昂 |\n| `[low energy]` | 低能量、内敛 |\n| `[building energy]` | 能量递增 |\n| `[explosive]` | 爆发性能量 |\n| `[melancholic]` | 忧郁 |\n| `[euphoric]` | 欣快 |\n| `[dreamy]` | 梦幻 |\n| `[aggressive]` | 激进 |\n\n**歌词文本的写作技巧**\n\n**1. 控制音节数**\n\n每行 **6-10 个音节**通常效果最好。模型会将音节对齐到节拍上——如果一行 6 音节，下一行 14 音节，节奏会变得奇怪。\n\n```\n❌ 不好的例子：\n我站在窗前看着外面的世界一切都在改变（18 音节）\n你好（2 音节）\n\n✅ 好的例子：\n我站在窗前（5 音节）\n看着外面世界（6 音节）\n一切都在改变（6 音节）\n```\n\n**技巧**：同一位置的行（如每段的第一行）保持相近的音节数（±1-2 偏差）。\n\n**2. 用大小写控制强度**\n\n大写表示更强的演唱力度：\n\n```\n[Verse]\nwalking through the empty streets（正常力度）\n\n[Chorus]\nWE ARE THE CHAMPIONS!（高强度、呐喊）\n```\n\n**3. 用括号表示背景人声**\n\n```\n[Chorus]\nWe rise together (together)\nInto the light (into the light)\n```\n\n括号内的内容会被处理为背景人声或和声。\n\n**4. 延长元音**\n\n可以通过重复元音来延长音：\n\n```\nFeeeling so aliiive\n```\n\n但要谨慎使用——效果不稳定，有时会被忽略或发音错误。\n\n**5. 段落清晰分隔**\n\n每个段落之间用空行分隔：\n\n```\n[Verse 1]\n第一段的歌词\n继续第一段\n\n[Chorus]\n副歌的歌词\n副歌继续\n```\n\n**避免「AI 味」歌词**\n\n以下特征会让歌词显得机械、缺乏人味：\n\n| 红旗 🚩 | 说明 |\n|---------|------|\n| **形容词堆砌** | 「neon skies, electric hearts, endless dreams」——一段里塞满模糊意象 |\n| **押韵混乱** | 押韵模式不一致，或刻意凑韵导致语义断裂 |\n| **段落边界模糊** | 歌词内容跨越结构标记，Verse 的内容「流」进了 Chorus |\n| **没有呼吸感** | 每行太长，无法一口气唱完 |\n| **隐喻混用** | 第一段用水的意象，第二段突然变成火，第三段又是飞翔——听众无法锚定 |\n\n**隐喻纪律**：一首歌坚持一个核心隐喻，深入挖掘它的多个方面。比如选择「水」作为隐喻，就可以探索：爱如何像水一样绕过障碍、可以是细雨也可以是洪流、能倒映出对方的样子、无法握住却真实存在。一个意象，多个切面——这让歌词有凝聚力。\n\n**纯音乐的写法**\n\n如果生成纯器乐无人声：\n\n```\n[Instrumental]\n```\n\n或者用结构标记描述器乐的展开：\n\n```\n[Intro - ambient]\n\n[Main Theme - piano]\n\n[Climax - powerful]\n\n[Outro - fade out]\n```\n\n**完整示例**\n\n假设 Caption 是：`female vocal, piano ballad, emotional, intimate atmosphere, strings, building to powerful chorus`\n\n```\n[Intro - piano]\n\n[Verse 1]\n月光洒在窗台上\n我听见你的呼吸\n城市在远处沉睡\n只有我们还醒着\n\n[Pre-Chorus]\n这一刻如此安静\n却藏着汹涌的心\n\n[Chorus - powerful]\n让我们燃烧吧\n像夜空中的烟火\n短暂却绚烂\n这就是我们的时刻\n\n[Verse 2]\n时间在指尖流过\n我们抓不住什么\n但至少此刻拥有\n彼此眼中的火焰\n\n[Bridge - whispered]\n如果明天一切消散\n至少我们曾经闪耀\n\n[Final Chorus]\n让我们燃烧吧\n像夜空中的烟火\n短暂却绚烂\nTHIS IS OUR MOMENT!\n\n[Outro - fade out]\n```\n\n注意：这个示例中，Lyrics 的标记（piano、powerful、whispered）与 Caption 的描述（piano ballad、building to powerful chorus、intimate）保持一致，没有冲突。\n\n---\n\n#### 关于音乐元数据：可选的精细控制\n\n**大部分时候，你不需要手动设置元数据。**\n\n当你开启 `thinking` 模式（或启用 `use_cot_metas`），LM 会根据你的 Caption 和 Lyrics 自动推断合适的 BPM、调性、拍号等。这通常已经足够好了。\n\n但如果你有明确的想法，也可以手动控制它们：\n\n| 参数 | 控制范围 | 说明 |\n|------|----------|------|\n| `bpm` | 30–300 | 速度。常见分布：慢歌 60–80，中速 90–120，快歌 130–180 |\n| `keyscale` | 调性 | 如 `C Major`、`Am`、`F# Minor`。影响整体音高和情绪色彩 |\n| `timesignature` | 拍号 | `4/4`（最常见）、`3/4`（华尔兹）、`6/8`（摇摆感） |\n| `vocal_language` | 语言 | 人声的语言。LM 通常能根据歌词自动识别 |\n| `duration` | 秒 | 目标时长。实际生成可能略有偏差 |\n\n**理解控制的边界**\n\n这些参数是**引导**而非**精确指令**：\n\n- **BPM**：常见范围（60–180）控制效果较好；极端值（如 30 或 280）模型见过的数据少，可能不稳定\n- **调性**：常见调（C、G、D、Am、Em）效果稳定；冷门调可能被忽略或偏移\n- **拍号**：`4/4` 最可靠；`3/4`、`6/8` 通常 OK；复杂拍号（如 `5/4`、`7/8`）是高级玩法，效果因风格而异\n- **时长**：短歌（30–60s）和中等长度（2–4min）较稳定；超长生成可能出现重复或结构问题\n\n**模型的「参考」方式**\n\n模型并不是机械地执行 `bpm=120`，而是：\n1. 把 `120 BPM` 作为一个**锚点**\n2. 在这个锚点附近的分布中采样\n3. 最终结果可能是 118 或 122，而非精确的 120\n\n这就像告诉乐手「大概 120 的速度」——他们会在这个范围内自然演奏，而非死板地跟着节拍器。\n\n**什么时候需要手动设置？**\n\n| 场景 | 建议 |\n|------|------|\n| 日常生成 | 不用管，让 LM 自动推断 |\n| 有明确速度要求 | 手动设 `bpm` |\n| 做特定风格（如华尔兹） | 手动设 `timesignature=3/4` |\n| 要配合其他素材 | 手动设 `bpm` 和 `duration` |\n| 追求特定调性色彩 | 手动设 `keyscale` |\n\n**小贴士**：如果你手动设置了元数据，但生成结果明显不符合——检查一下是否和 Caption/Lyrics 有冲突。比如 Caption 写「slow ballad」但 `bpm=160`，模型会困惑。\n\n**推荐做法**：不要在 Caption 中写速度、BPM、调性等元数据信息。这些应该通过专门的元数据参数（`bpm`、`keyscale`、`timesignature` 等）来设置，而不是在 Caption 中描述。Caption 应该专注于风格、情绪、乐器、音色等音乐特征，而元数据信息交给对应的参数控制。\n\n---\n\n#### 关于音频控制：用声音控制声音\n\n**文本是降维抽象的，最好的控制还是用音频去控制。**\n\n用音频控制生成的方式有三种，它们各有不同的控制范围和用途：\n\n---\n\n##### 1. 参考音频（Reference Audio）：全局声学特征控制\n\n参考音频（`reference_audio`）用于控制生成音乐的**声学特征**——音色、混音风格、演奏风格等。它**平均了时间维度的信息**，是**作用全局**的。\n\n**参考音频控制什么？**\n\n参考音频主要控制生成音乐的**声学特征**，包括：\n- **音色质感**：人声的音色、乐器的音色\n- **混音风格**：空间感、动态范围、频率分布\n- **演奏风格**：演唱技巧、演奏技法、表达方式\n- **整体氛围**：通过参考音频传递的「感觉」\n\n**后台如何处理参考音频？**\n\n当你提供参考音频时，系统会进行以下处理：\n\n1. **音频预处理**：\n   - 加载音频文件，统一标准化为**立体声 48kHz** 格式\n   - 检测静音，如果音频完全静音则忽略\n   - 如果音频长度不足 30 秒，会重复填充到至少 30 秒\n   - 从前、中、后三个位置各随机选择 10 秒片段，拼接成 30 秒的参考片段\n\n2. **编码转换**：\n   - 使用 **VAE（变分自编码器）** 的 `tiled_encode` 方法将音频编码为**潜在表示（latents）**\n   - 这些 latents 包含了音频的声学特征信息，但去除了具体的旋律、节奏等结构信息\n   - 编码后的 latents 会作为条件输入到 DiT 的生成过程中，**平均时间维度信息，全局作用于整个生成过程**\n\n---\n\n##### 2. 源音频（Source Audio）：语义结构控制\n\n源音频（`src_audio`）用于 **Cover 任务**，进行**旋律结构控制**。它的原理是将你输入的源音频量化成语义结构化的信息。\n\n**源音频控制什么？**\n\n源音频会被转换为**语义结构化的信息**，包括：\n- **旋律**：音符的走向和音高\n- **节奏**：节拍、重音、律动\n- **和弦**：和声进行和变化\n- **配器**：乐器的编排和层次\n- **少许音色**：部分音色信息\n\n**你可以用它做什么？**\n\n1. **控制风格**：保持源音频的结构，改变风格和细节\n2. **迁移风格**：将源音频的结构应用到不同的风格中\n3. **Retake 抽卡**：生成相似结构但不同的变体，通过多次生成获得不同的演绎\n4. **控制影响程度**：通过 `audio_cover_strength` 参数（0.0–1.0）控制源音频的影响强度\n   - 强度越高，生成结果越严格遵循源音频的结构\n   - 强度越低，生成结果有更多自由发挥的空间\n\n**Cover 的高级用法**\n\n你可以用 Cover 去 **Remix 一首歌**，且支持更改 Caption 和 Lyrics：\n\n- **Remix 创作**：输入一首歌作为源音频，通过修改 Caption 和 Lyrics 来重新诠释它\n  - 改变风格：用不同的 Caption 描述（如从 pop 改为 rock）\n  - 改变歌词：用新的 Lyrics 重新填词，保持原有的旋律结构\n  - 改变情绪：通过 Caption 调整整体氛围（如从悲伤改为欢快）\n\n- **构建复杂的音乐结构**：根据你需要的结构影响程度来构建复杂的音乐旋律走向、层次和律动\n  - 通过 `audio_cover_strength` 精细控制结构遵循程度\n  - 结合 Caption 和 Lyrics 的修改，在保持核心结构的同时创造新的表达\n  - 可以生成多个版本，每个版本在结构、风格、歌词上有不同的侧重\n\n---\n\n##### 3. 基于源音频上下文的控制：局部补全与修改\n\n这是 **Repaint 任务**，基于源音频的上下文进行补全或修改。\n\n**Repaint 的原理**\n\nRepaint 基于**上下文补全**的原理：\n- 可以补全**开头**、**中间局部**、**结尾**，或**任意区域**\n- 操作范围：**3 秒到 90 秒**\n- 模型会参考源音频的上下文信息，在指定区间内进行生成\n\n**你可以用它做什么？**\n\n1. **局部修改**：修改指定区间的歌词、结构或内容\n2. **改歌词**：保持旋律和配器，只改变歌词内容\n3. **改结构**：在指定区间改变音乐结构（如将 Verse 改为 Chorus）\n4. **续写**：基于上下文续写开头或结尾\n5. **克隆音色**：基于上下文克隆源音频的音色特征\n\n**Repaint 的高级用法**\n\n你可以用 Repaint 实现更复杂的创作需求：\n\n- **无限时长生成**：\n  - 通过多次 Repaint 操作，可以不断续写音频，实现无限时长的生成\n  - 每次续写都会基于前一段的上下文，保持音乐的自然过渡和连贯性\n  - 可以分段生成，每段 3–90 秒，最终拼接成完整的作品\n\n- **智能音频缝合**：\n  - 将两个音频智能地组织缝合在一起\n  - 在第一个音频的结尾使用 Repaint 续写，让过渡自然衔接\n  - 或者用 Repaint 修改两个音频之间的连接部分，实现平滑过渡\n  - 模型会基于上下文自动处理节奏、和声、音色的衔接，让拼接后的音频听起来像一首完整的作品\n\n---\n\n##### 4. Base 模型的高级音频控制任务\n\n在 **Base 模型**中，我们还支持更多高级的音频控制任务：\n\n**Lego 任务**：基于已有轨道智能添加新轨道\n- 输入一个已有的音频轨道（如人声）\n- 模型会智能地添加新的轨道（如鼓、吉他、贝斯等）\n- 新轨道会与原有轨道在节奏、和声上协调配合\n\n**Complete 任务**：给单轨添加混合轨道\n- 输入一个单轨音频（如清唱人声）\n- 模型会生成完整的混合伴奏轨道\n- 生成的伴奏会与人声在风格、节奏、和声上匹配\n\n**这些高级上下文补全任务**极大拓展了控制方式，更智能地提供灵感和创意。\n\n---\n\n这些参数的组合，决定了你「想要什么」。后面我们会详细讲解输入控制的**原则**与**技巧**。\n\n### 二、推理超参：模型怎么生成？\n\n这是影响「生成过程行为」的部分——不改变你要什么，但改变模型怎么做。\n\n**DiT（扩散模型）超参：**\n\n| 参数 | 作用 | 默认值 | 调参建议 |\n|------|------|--------|----------|\n| `inference_steps` | 扩散步数 | 8 (turbo) | 越多越精细，但越慢。Turbo 用 8，Base 用 32–100 |\n| `guidance_scale` | CFG 强度 | 7.0 | 越高越遵循 prompt，但可能过拟合。仅 Base 模型有效 |\n| `use_adg` | 自适应双重引导 | False | 开启后动态调整 CFG，仅 Base 模型 |\n| `cfg_interval_start/end` | CFG 生效区间 | 0.0–1.0 | 控制在哪个阶段应用 CFG |\n| `shift` | 时间步偏移 | 1.0 | 调整去噪轨迹，影响生成风格 |\n| `infer_method` | 推理方法 | \"ode\" | `ode` 确定性，`sde` 引入随机性 |\n| `timesteps` | 自定义时间步 | None | 高级用法，覆盖 steps 和 shift |\n| `audio_cover_strength` | 参考音频/codes 的影响强度 | 1.0 | 0.0–1.0，越高越接近参考，越低越自由发挥 |\n\n**5Hz LM（语言模型）超参：**\n\n| 参数 | 作用 | 默认值 | 调参建议 |\n|------|------|--------|----------|\n| `thinking` | 启用 CoT 推理 | True | 开启让 LM 推理元数据和 codes |\n| `lm_temperature` | 采样温度 | 0.85 | 越高越随机/创意，越低越保守/确定 |\n| `lm_cfg_scale` | LM 的 CFG 强度 | 2.0 | 越高越遵循正向 prompt |\n| `lm_top_k` | Top-K 采样 | 0 | 0 表示禁用，限制候选词数量 |\n| `lm_top_p` | Top-P 采样 | 0.9 | 核采样，限制累积概率 |\n| `lm_negative_prompt` | 负面提示 | \"NO USER INPUT\" | 告诉 LM 不要生成什么 |\n| `use_cot_metas` | CoT 推理元数据 | True | 让 LM 自动推断 BPM、调性等 |\n| `use_cot_caption` | CoT 重写 caption | True | 让 LM 优化你的描述 |\n| `use_cot_language` | CoT 检测语言 | True | 让 LM 自动识别人声语言 |\n| `use_constrained_decoding` | 约束解码 | True | 确保输出格式正确 |\n\n这些参数的组合，决定了模型「怎么做」。\n\n**关于调参的说明**\n\n需要强调的是，**调参因素和随机因素有时候影响相当**。当你调整某个参数时，可能很难判断是参数本身的影响，还是随机性带来的变化。\n\n因此，**推荐固定随机因素去调参**——通过设置固定的 `seed` 值，确保每次生成都从相同的初始噪声开始，这样你才能准确感受到参数对生成音频的真实影响。否则，参数变化的效果可能会被随机性掩盖，让你误判参数的作用。\n\n### 三、随机因素：不确定性的来源\n\n即使所有输入和超参完全相同，两次生成的结果也可能不同。这是因为：\n\n**1. DiT 的初始噪声**\n- 扩散模型从随机噪声开始逐步去噪\n- `seed` 参数控制这个初始噪声\n- 不同的 seed → 不同的起点 → 不同的终点\n\n**2. LM 的采样随机性**\n- 当 `lm_temperature > 0`，采样过程本身带有随机性\n- 同样的 prompt，每次采样可能选择不同的 token\n\n**3. `infer_method = \"sde\"` 时的额外噪声**\n- SDE 方法在去噪过程中注入额外随机性\n\n---\n\n#### 随机因素的利弊\n\n随机性是一把双刃剑。\n\n**随机性的好处**：\n- **探索创作空间**：同样的输入可以产生不同的变体，给你更多选择\n- **发现意外惊喜**：有时候随机性会带来你意想不到的优秀结果\n- **避免重复**：每次生成都有所不同，不会陷入单一模式的循环\n\n**随机性的挑战**：\n- **结果不可控**：你无法精确预测生成结果，可能多次生成都不满意\n- **难以复现**：即使输入完全相同，也很难复现某个特定的好结果\n- **调参困难**：当你调整参数时，很难判断是参数的影响还是随机性的变化\n- **筛选成本**：需要生成多个版本才能找到满意的，增加了时间成本\n\n#### 用怎样的心态面对随机因素？\n\n**1. 接受不确定性**\n- 随机性是 AI 音乐生成的本质特征，不是 bug，而是 feature\n- 不要期望每次生成都完美，把随机性当作探索的工具\n\n**2. 拥抱探索过程**\n- 把生成过程看作「抽卡」或「挖宝」——多试几次，总能找到惊喜\n- 享受发现意外好结果的过程，而不是执着于一次成功\n\n**3. 善用固定 seed**\n- 当你想要**理解参数影响**时，固定 `seed` 来消除随机性干扰\n- 当你想要**探索创作空间**时，让 `seed` 随机变化\n\n**4. 批量生成 + 智能筛选**\n- 不要依赖单次生成，而是批量生成多个版本\n- 利用自动打分机制进行初步筛选，提高效率\n\n#### 我们的解决方案：大 Batch + 自动打分\n\n因为我们推理速度极快，如果你的显卡显存足够，你可以通过**大 batch 去探索随机空间**：\n\n- **批量生成**：一次生成多个版本（如 batch_size=2,4,8），快速探索随机空间\n- **自动打分机制**：我们提供自动打分机制，可以帮助你初步筛选，做 **test time scaling**\n\n**自动打分机制**\n\n我们提供了多种打分指标，其中**我最喜欢的是 DiT Lyrics Alignment Score**：\n\n- **DiT Lyrics Alignment Score**：这个分数隐式地影响了歌词的准确性\n  - 它评估生成音频中歌词与音频的对齐程度\n  - 分数越高，说明歌词在音频中的位置越准确，演唱与歌词的匹配度越好\n  - 这对于有歌词的音乐生成特别重要，可以帮助你筛选出歌词准确性更高的版本\n\n- **其他打分指标**：还包括其他质量评估指标，可以从多个维度评估生成结果\n\n**工作流程建议**：\n\n1. **批量生成**：设置较大的 `batch_size`（如 2、4、8），一次生成多个版本\n2. **开启 AutoGen**：启用自动生成功能，让系统在后台持续生成新的批次\n   - **AutoGen 的机制**：AutoGen 会在你查看当前批次结果时，自动在后台使用相同的参数（但使用随机 seed）生成下一批次\n   - 这样你可以持续探索随机空间，而不需要手动点击生成按钮\n   - 每个新批次都会使用新的随机 seed，确保结果的多样性\n3. **自动打分**：开启自动打分功能，让系统自动为每个版本打分\n4. **初步筛选**：根据 DiT Lyrics Alignment Score 等指标，筛选出分数较高的版本\n5. **人工精挑**：在筛选出的版本中，人工选择最符合你需求的最终版本\n\n这样既能充分利用随机性探索创作空间，又能通过自动化工具提高效率，避免在大量生成结果中盲目寻找。AutoGen 让你可以「边听边生成」，在浏览当前结果的同时，下一批次已经在后台准备好了。\n\n---\n\n## 结语\n\n这篇教程目前涵盖了 ACE-Step 1.5 的核心概念和使用方法：\n\n- **心智模型**：理解以人为中心的生成设计哲学\n- **模型架构**：认识 LM 和 DiT 的协同工作方式\n- **输入控制**：掌握文本（Caption、Lyrics、元数据）和音频（参考音频、源音频）的控制方法\n- **推理超参**：了解影响生成过程的参数\n- **随机因素**：学会利用随机性探索创作空间，并通过大 Batch + AutoGen + 自动打分提高效率\n\n这只是一个开始。还有很多内容我们想分享给你：\n\n- 更多 Prompting 技巧和实战案例\n- 不同任务类型的详细使用指南\n- 高级玩法和创意工作流\n- 常见问题与解决方案\n- 性能优化建议\n\n**这篇教程会持续更新和完善。** 如果你在使用过程中有任何问题或建议，欢迎反馈。让我们一起让 ACE-Step 成为你口袋里的创作伙伴。\n\n---\n\n*未完待续...*\n"
  },
  {
    "path": "docs/zh/index.md",
    "content": "---\nlayout: home\nhero:\n  name: ACE-Step 1.5\n  text: 开源音乐生成\n  tagline: 消费级硬件上的商业级音乐生成。A100 上每首歌不到 2 秒，显存需求 <4GB。\n  image:\n    src: /logo.png\n    alt: ACE-Step\n  actions:\n    - theme: brand\n      text: 安装指南\n      link: /zh/INSTALL\n    - theme: alt\n      text: 教程 (必读)\n      link: /zh/Tutorial\n    - theme: alt\n      text: API 文档\n      link: /zh/API\n\nfeatures:\n  - icon: \"&#9889;\"\n    title: 极速生成\n    details: A100 上每首完整歌曲不到 2 秒，RTX 3090 不到 10 秒。支持 10 秒到 10 分钟音频生成。\n  - icon: \"&#127925;\"\n    title: 商业级质量\n    details: 1000+ 种乐器和风格，50+ 种语言，细粒度音色描述和歌词结构控制。\n  - icon: \"&#127899;\"\n    title: 多功能编辑\n    details: 翻唱生成、局部重绘、音轨分离、人声转伴奏、多轨生成等。\n  - icon: \"&#128640;\"\n    title: 轻量可定制\n    details: 本地运行仅需 <4GB 显存。用几首歌即可训练 LoRA，在 3090 上 1 小时完成。\n---\n"
  },
  {
    "path": "examples/simple_mode/example_01.json",
    "content": "{\n    \"description\": \"a soft Bengali love song for a quiet evening\",\n    \"instrumental\": false,\n    \"vocal_language\": \"bn\"\n}\n"
  },
  {
    "path": "examples/simple_mode/example_02.json",
    "content": "{\n    \"description\": \"an upbeat summer pop song with catchy hooks\",\n    \"instrumental\": false,\n    \"vocal_language\": \"en\"\n}\n"
  },
  {
    "path": "examples/simple_mode/example_03.json",
    "content": "{\n    \"description\": \"epic orchestral cinematic music for a movie trailer\",\n    \"instrumental\": true,\n    \"vocal_language\": \"unknown\"\n}\n"
  },
  {
    "path": "examples/simple_mode/example_04.json",
    "content": "{\n    \"description\": \"一首深情的中文抒情歌曲，适合夜晚独自聆听\",\n    \"instrumental\": false,\n    \"vocal_language\": \"zh\"\n}\n"
  },
  {
    "path": "examples/simple_mode/example_05.json",
    "content": "{\n    \"description\": \"Japanese city pop with nostalgic 80s vibes\",\n    \"instrumental\": false,\n    \"vocal_language\": \"ja\"\n}\n"
  },
  {
    "path": "examples/simple_mode/example_06.json",
    "content": "{\n    \"description\": \"lo-fi hip hop beats for studying and relaxing\",\n    \"instrumental\": true,\n    \"vocal_language\": \"unknown\"\n}\n"
  },
  {
    "path": "examples/simple_mode/example_07.json",
    "content": "{\n    \"description\": \"energetic K-pop dance track with powerful vocals\",\n    \"instrumental\": false,\n    \"vocal_language\": \"ko\"\n}\n"
  },
  {
    "path": "examples/simple_mode/example_08.json",
    "content": "{\n    \"description\": \"romantic Spanish guitar ballad with heartfelt lyrics\",\n    \"instrumental\": false,\n    \"vocal_language\": \"es\"\n}\n"
  },
  {
    "path": "examples/simple_mode/example_09.json",
    "content": "{\n    \"description\": \"中国风电子舞曲，融合古典乐器与现代节拍\",\n    \"instrumental\": false,\n    \"vocal_language\": \"zh\"\n}\n"
  },
  {
    "path": "examples/simple_mode/example_10.json",
    "content": "{\n    \"description\": \"peaceful piano melody for meditation and relaxation\",\n    \"instrumental\": true,\n    \"vocal_language\": \"unknown\"\n}\n"
  },
  {
    "path": "examples/simple_mode/example_100.json",
    "content": "{\n    \"description\": \"Kraftvoller deutscher Metal-Anthem mit aggressivem Gesang und Double-Bass-Drums\",\n    \"instrumental\": false,\n    \"vocal_language\": \"de\"\n}\n"
  },
  {
    "path": "examples/simple_mode/example_101.json",
    "content": "{\n    \"description\": \"Energiegeladene Neue Deutsche Welle mit Retro-Synths und punkiger Attitüde\",\n    \"instrumental\": false,\n    \"vocal_language\": \"de\"\n}\n"
  },
  {
    "path": "examples/simple_mode/example_102.json",
    "content": "{\n    \"description\": \"Entspannter deutscher Hip-Hop mit lässigem Flow und jazzigen Samples\",\n    \"instrumental\": false,\n    \"vocal_language\": \"de\"\n}\n"
  },
  {
    "path": "examples/simple_mode/example_103.json",
    "content": "{\n    \"description\": \"Atmosphärische deutsche Elektronik mit Ambient-Texturen und sanftem Gesang\",\n    \"instrumental\": false,\n    \"vocal_language\": \"de\"\n}\n"
  },
  {
    "path": "examples/simple_mode/example_104.json",
    "content": "{\n    \"description\": \"Chanson française romantique avec accordéon et cordes nostalgiques\",\n    \"instrumental\": false,\n    \"vocal_language\": \"fr\"\n}\n"
  },
  {
    "path": "examples/simple_mode/example_105.json",
    "content": "{\n    \"description\": \"French house groovy avec samples disco et ligne de basse funky\",\n    \"instrumental\": true,\n    \"vocal_language\": \"fr\"\n}\n"
  },
  {
    "path": "examples/simple_mode/example_106.json",
    "content": "{\n    \"description\": \"Rap français poétique avec samples jazz et flow smooth\",\n    \"instrumental\": false,\n    \"vocal_language\": \"fr\"\n}\n"
  },
  {
    "path": "examples/simple_mode/example_107.json",
    "content": "{\n    \"description\": \"Pop française rêveuse avec voix éthérées et synthés luxuriants\",\n    \"instrumental\": false,\n    \"vocal_language\": \"fr\"\n}\n"
  },
  {
    "path": "examples/simple_mode/example_108.json",
    "content": "{\n    \"description\": \"Style yé-yé rétro avec rythme entraînant et voix enjouées\",\n    \"instrumental\": false,\n    \"vocal_language\": \"fr\"\n}\n"
  },
  {
    "path": "examples/simple_mode/example_109.json",
    "content": "{\n    \"description\": \"Ballade française mélancolique avec piano et émotion\",\n    \"instrumental\": false,\n    \"vocal_language\": \"fr\"\n}\n"
  },
  {
    "path": "examples/simple_mode/example_11.json",
    "content": "{\n    \"description\": \"a melancholic indie rock ballad with atmospheric guitars and dreamy reverb\",\n    \"instrumental\": false,\n    \"vocal_language\": \"en\"\n}\n"
  },
  {
    "path": "examples/simple_mode/example_110.json",
    "content": "{\n    \"description\": \"Électropop française énergique avec hooks accrocheurs\",\n    \"instrumental\": false,\n    \"vocal_language\": \"fr\"\n}\n"
  },
  {
    "path": "examples/simple_mode/example_111.json",
    "content": "{\n    \"description\": \"Britpop anthem with jangly guitars, catchy hooks, and witty lyrics about working-class life in modern Britain, featuring a driving rhythm section and melodic vocal harmonies\",\n    \"instrumental\": false,\n    \"vocal_language\": \"en\"\n}\n"
  },
  {
    "path": "examples/simple_mode/example_112.json",
    "content": "{\n    \"description\": \"Raw garage rock track with fuzzy distorted guitars, primal drumming, and aggressive vocals delivering rebellious lyrics about teenage angst and urban decay\",\n    \"instrumental\": false,\n    \"vocal_language\": \"en\"\n}\n"
  },
  {
    "path": "examples/simple_mode/example_113.json",
    "content": "{\n    \"description\": \"Psychedelic rock journey with swirling organ, phased guitars, and trippy effects, featuring dreamy vocals singing about cosmic exploration and altered consciousness\",\n    \"instrumental\": false,\n    \"vocal_language\": \"en\"\n}\n"
  },
  {
    "path": "examples/simple_mode/example_114.json",
    "content": "{\n    \"description\": \"Energetic surf rock instrumental with reverb-drenched twangy guitars, driving drums, and a catchy melody evoking sun-soaked beaches and crashing waves\",\n    \"instrumental\": true,\n    \"vocal_language\": \"en\"\n}\n"
  },
  {
    "path": "examples/simple_mode/example_115.json",
    "content": "{\n    \"description\": \"Flamboyant glam rock anthem with stomping beats, glittery guitar riffs, and theatrical vocals celebrating self-expression and rock and roll excess\",\n    \"instrumental\": false,\n    \"vocal_language\": \"en\"\n}\n"
  },
  {
    "path": "examples/simple_mode/example_116.json",
    "content": "{\n    \"description\": \"Experimental art rock composition with unconventional song structures, avant-garde instrumentation, and introspective vocals exploring themes of identity and alienation\",\n    \"instrumental\": false,\n    \"vocal_language\": \"en\"\n}\n"
  },
  {
    "path": "examples/simple_mode/example_117.json",
    "content": "{\n    \"description\": \"Complex math rock instrumental with intricate time signatures, angular guitar riffs, and precise polyrhythmic drumming creating a technically demanding sonic puzzle\",\n    \"instrumental\": true,\n    \"vocal_language\": \"en\"\n}\n"
  },
  {
    "path": "examples/simple_mode/example_118.json",
    "content": "{\n    \"description\": \"Abrasive noise rock track with dissonant guitar feedback, pounding bass, and shouted vocals expressing frustration and chaos in an industrial urban landscape\",\n    \"instrumental\": false,\n    \"vocal_language\": \"en\"\n}\n"
  },
  {
    "path": "examples/simple_mode/example_119.json",
    "content": "{\n    \"description\": \"Heavy stoner rock groove with thick fuzzy riffs, slow hypnotic tempo, and hazy vocals singing about desert highways and transcendental experiences\",\n    \"instrumental\": false,\n    \"vocal_language\": \"en\"\n}\n"
  },
  {
    "path": "examples/simple_mode/example_12.json",
    "content": "{\n    \"description\": \"energetic EDM festival anthem with heavy bass drops and euphoric synth leads\",\n    \"instrumental\": false,\n    \"vocal_language\": \"en\"\n}\n"
  },
  {
    "path": "examples/simple_mode/example_120.json",
    "content": "{\n    \"description\": \"Soulful southern rock ballad with slide guitar, Hammond organ, and heartfelt vocals telling stories of small-town life and lost love in the American South\",\n    \"instrumental\": false,\n    \"vocal_language\": \"en\"\n}\n"
  },
  {
    "path": "examples/simple_mode/example_121.json",
    "content": "{\n    \"description\": \"Anthemic heartland rock song with ringing guitars, driving rhythm, and earnest vocals celebrating blue-collar values and the American working-class spirit\",\n    \"instrumental\": false,\n    \"vocal_language\": \"en\"\n}\n"
  },
  {
    "path": "examples/simple_mode/example_122.json",
    "content": "{\n    \"description\": \"Infectious power pop track with crunchy guitars, tight harmonies, and an irresistible chorus about summer romance and youthful optimism\",\n    \"instrumental\": false,\n    \"vocal_language\": \"en\"\n}\n"
  },
  {
    "path": "examples/simple_mode/example_123.json",
    "content": "{\n    \"description\": \"Shimmering jangle pop tune with chiming arpeggiated guitars, upbeat tempo, and breezy vocals singing about nostalgic memories and bittersweet longing\",\n    \"instrumental\": false,\n    \"vocal_language\": \"en\"\n}\n"
  },
  {
    "path": "examples/simple_mode/example_124.json",
    "content": "{\n    \"description\": \"Ornate baroque pop arrangement with harpsichord, string quartet, and lush orchestration, featuring elegant vocals weaving tales of aristocratic romance and melancholy\",\n    \"instrumental\": false,\n    \"vocal_language\": \"en\"\n}\n"
  },
  {
    "path": "examples/simple_mode/example_125.json",
    "content": "{\n    \"description\": \"Sophisticated chamber pop piece with piano, woodwinds, and sweeping strings, featuring intimate vocals exploring themes of existential wonder and quiet introspection\",\n    \"instrumental\": false,\n    \"vocal_language\": \"en\"\n}\n"
  },
  {
    "path": "examples/simple_mode/example_126.json",
    "content": "{\n    \"description\": \"Aggressive dubstep track with heavy wobble bass, distorted synths, and intense drops that shake the speakers\",\n    \"instrumental\": false,\n    \"vocal_language\": \"en\"\n}\n"
  },
  {
    "path": "examples/simple_mode/example_127.json",
    "content": "{\n    \"description\": \"High-energy drum and bass anthem with rolling breakbeats, deep sub-bass, and euphoric vocal chops\",\n    \"instrumental\": false,\n    \"vocal_language\": \"en\"\n}\n"
  },
  {
    "path": "examples/simple_mode/example_128.json",
    "content": "{\n    \"description\": \"Classic house music with four-on-the-floor beats, soulful piano chords, and uplifting female vocals\",\n    \"instrumental\": false,\n    \"vocal_language\": \"en\"\n}\n"
  },
  {
    "path": "examples/simple_mode/example_129.json",
    "content": "{\n    \"description\": \"Dark industrial techno with pounding kicks, hypnotic synth loops, and relentless mechanical rhythms\",\n    \"instrumental\": true,\n    \"vocal_language\": \"en\"\n}\n"
  },
  {
    "path": "examples/simple_mode/example_13.json",
    "content": "{\n    \"description\": \"smooth R&B love song with soulful vocals and silky piano chords\",\n    \"instrumental\": false,\n    \"vocal_language\": \"en\"\n}\n"
  },
  {
    "path": "examples/simple_mode/example_130.json",
    "content": "{\n    \"description\": \"Uplifting trance with soaring melodies, ethereal pads, and emotional breakdowns that build to euphoric climaxes\",\n    \"instrumental\": false,\n    \"vocal_language\": \"en\"\n}\n"
  },
  {
    "path": "examples/simple_mode/example_131.json",
    "content": "{\n    \"description\": \"Hardstyle banger with distorted kicks, reverse bass, and anthemic vocals that ignite the crowd\",\n    \"instrumental\": false,\n    \"vocal_language\": \"en\"\n}\n"
  },
  {
    "path": "examples/simple_mode/example_132.json",
    "content": "{\n    \"description\": \"Colorful future bass with lush synth chords, pitched vocal samples, and emotional melodic drops\",\n    \"instrumental\": false,\n    \"vocal_language\": \"en\"\n}\n"
  },
  {
    "path": "examples/simple_mode/example_133.json",
    "content": "{\n    \"description\": \"Sunny tropical house with steel drums, marimba melodies, and breezy summer vocals\",\n    \"instrumental\": false,\n    \"vocal_language\": \"en\"\n}\n"
  },
  {
    "path": "examples/simple_mode/example_134.json",
    "content": "{\n    \"description\": \"Smooth deep house groove with warm basslines, subtle percussion, and hypnotic late-night atmosphere\",\n    \"instrumental\": false,\n    \"vocal_language\": \"en\"\n}\n"
  },
  {
    "path": "examples/simple_mode/example_135.json",
    "content": "{\n    \"description\": \"Epic progressive house journey with layered synths, gradual builds, and massive festival-ready drops\",\n    \"instrumental\": false,\n    \"vocal_language\": \"en\"\n}\n"
  },
  {
    "path": "examples/simple_mode/example_136.json",
    "content": "{\n    \"description\": \"Vintage electro swing with jazzy brass samples, swinging rhythms, and playful retro vocals\",\n    \"instrumental\": false,\n    \"vocal_language\": \"en\"\n}\n"
  },
  {
    "path": "examples/simple_mode/example_137.json",
    "content": "{\n    \"description\": \"Funky breakbeat track with chopped drum breaks, funky basslines, and energetic vocal hooks\",\n    \"instrumental\": false,\n    \"vocal_language\": \"en\"\n}\n"
  },
  {
    "path": "examples/simple_mode/example_138.json",
    "content": "{\n    \"description\": \"Chilled downtempo with ambient textures, slow grooves, and dreamy atmospheric soundscapes\",\n    \"instrumental\": true,\n    \"vocal_language\": \"en\"\n}\n"
  },
  {
    "path": "examples/simple_mode/example_139.json",
    "content": "{\n    \"description\": \"Experimental IDM with complex polyrhythms, glitchy textures, and intricate sound design\",\n    \"instrumental\": false,\n    \"vocal_language\": \"en\"\n}\n"
  },
  {
    "path": "examples/simple_mode/example_14.json",
    "content": "{\n    \"description\": \"uplifting country road trip anthem with acoustic guitar and harmonica\",\n    \"instrumental\": false,\n    \"vocal_language\": \"en\"\n}\n"
  },
  {
    "path": "examples/simple_mode/example_140.json",
    "content": "{\n    \"description\": \"Chaotic glitch hop with stuttering beats, digital artifacts, and fragmented vocal samples\",\n    \"instrumental\": false,\n    \"vocal_language\": \"en\"\n}\n"
  },
  {
    "path": "examples/simple_mode/example_141.json",
    "content": "{\n    \"description\": \"轻快的国风电子舞曲，融合古筝与现代节拍\",\n    \"instrumental\": false,\n    \"vocal_language\": \"zh\"\n}\n"
  },
  {
    "path": "examples/simple_mode/example_142.json",
    "content": "{\n    \"description\": \"深情的粤语情歌，带有港式复古风情\",\n    \"instrumental\": false,\n    \"vocal_language\": \"zh\"\n}\n"
  },
  {
    "path": "examples/simple_mode/example_143.json",
    "content": "{\n    \"description\": \"热血沸腾的电竞主题曲，激昂的电子音效\",\n    \"instrumental\": false,\n    \"vocal_language\": \"zh\"\n}\n"
  },
  {
    "path": "examples/simple_mode/example_144.json",
    "content": "{\n    \"description\": \"空灵的禅意音乐，适合瑜伽冥想\",\n    \"instrumental\": true,\n    \"vocal_language\": \"zh\"\n}\n"
  },
  {
    "path": "examples/simple_mode/example_145.json",
    "content": "{\n    \"description\": \"欢快的儿童歌曲，充满童真童趣\",\n    \"instrumental\": false,\n    \"vocal_language\": \"zh\"\n}\n"
  },
  {
    "path": "examples/simple_mode/example_146.json",
    "content": "{\n    \"description\": \"激情四射的摇滚现场版，吉他solo燃爆全场\",\n    \"instrumental\": false,\n    \"vocal_language\": \"zh\"\n}\n"
  },
  {
    "path": "examples/simple_mode/example_147.json",
    "content": "{\n    \"description\": \"温馨的家庭主题曲，充满爱与温暖\",\n    \"instrumental\": false,\n    \"vocal_language\": \"zh\"\n}\n"
  },
  {
    "path": "examples/simple_mode/example_148.json",
    "content": "{\n    \"description\": \"神秘的武侠风格配乐，刀光剑影江湖梦\",\n    \"instrumental\": true,\n    \"vocal_language\": \"zh\"\n}\n"
  },
  {
    "path": "examples/simple_mode/example_149.json",
    "content": "{\n    \"description\": \"动感的健身房音乐，节奏强劲充满力量\",\n    \"instrumental\": false,\n    \"vocal_language\": \"zh\"\n}\n"
  },
  {
    "path": "examples/simple_mode/example_15.json",
    "content": "{\n    \"description\": \"dark trap beat with haunting melodies and 808 bass\",\n    \"instrumental\": false,\n    \"vocal_language\": \"en\"\n}\n"
  },
  {
    "path": "examples/simple_mode/example_150.json",
    "content": "{\n    \"description\": \"古典戏曲风格流行歌曲，京剧元素与现代编曲融合\",\n    \"instrumental\": false,\n    \"vocal_language\": \"zh\"\n}\n"
  },
  {
    "path": "examples/simple_mode/example_151.json",
    "content": "{\n    \"description\": \"浪漫的校园民谣，青春回忆满满\",\n    \"instrumental\": false,\n    \"vocal_language\": \"zh\"\n}\n"
  },
  {
    "path": "examples/simple_mode/example_152.json",
    "content": "{\n    \"description\": \"悠扬的草原风情歌曲，马头琴与长调交织\",\n    \"instrumental\": false,\n    \"vocal_language\": \"zh\"\n}\n"
  },
  {
    "path": "examples/simple_mode/example_153.json",
    "content": "{\n    \"description\": \"时尚的都市R&B，慵懒性感的夜生活氛围\",\n    \"instrumental\": false,\n    \"vocal_language\": \"zh\"\n}\n"
  },
  {
    "path": "examples/simple_mode/example_154.json",
    "content": "{\n    \"description\": \"古风仙侠主题曲，飘逸空灵如临仙境\",\n    \"instrumental\": false,\n    \"vocal_language\": \"zh\"\n}\n"
  },
  {
    "path": "examples/simple_mode/example_155.json",
    "content": "{\n    \"description\": \"励志的毕业季歌曲，告别与祝福\",\n    \"instrumental\": false,\n    \"vocal_language\": \"zh\"\n}\n"
  },
  {
    "path": "examples/simple_mode/example_156.json",
    "content": "{\n    \"description\": \"深沉的蓝调爵士，午夜酒吧的忧郁情调\",\n    \"instrumental\": false,\n    \"vocal_language\": \"zh\"\n}\n"
  },
  {
    "path": "examples/simple_mode/example_157.json",
    "content": "{\n    \"description\": \"欢乐的新年贺岁歌曲，喜庆热闹迎新春\",\n    \"instrumental\": false,\n    \"vocal_language\": \"zh\"\n}\n"
  },
  {
    "path": "examples/simple_mode/example_158.json",
    "content": "{\n    \"description\": \"唯美的古典钢琴曲，如诗如画的江南水乡\",\n    \"instrumental\": true,\n    \"vocal_language\": \"zh\"\n}\n"
  },
  {
    "path": "examples/simple_mode/example_159.json",
    "content": "{\n    \"description\": \"热情的拉丁风格华语歌曲，异域风情与中文歌词碰撞\",\n    \"instrumental\": false,\n    \"vocal_language\": \"zh\"\n}\n"
  },
  {
    "path": "examples/simple_mode/example_16.json",
    "content": "{\n    \"description\": \"groovy funk jam with slap bass and wah-wah guitar riffs\",\n    \"instrumental\": false,\n    \"vocal_language\": \"en\"\n}\n"
  },
  {
    "path": "examples/simple_mode/example_160.json",
    "content": "{\n    \"description\": \"磅礴大气的史诗级电影配乐，气势恢宏震撼人心\",\n    \"instrumental\": false,\n    \"vocal_language\": \"zh\"\n}\n"
  },
  {
    "path": "examples/simple_mode/example_161.json",
    "content": "{\n    \"description\": \"疾走感のあるアニソンロック、熱いギターリフとパワフルなボーカル\",\n    \"instrumental\": false,\n    \"vocal_language\": \"ja\"\n}\n"
  },
  {
    "path": "examples/simple_mode/example_162.json",
    "content": "{\n    \"description\": \"切ない冬のバラード、ピアノと弦楽器が織りなす感動的なメロディー\",\n    \"instrumental\": false,\n    \"vocal_language\": \"ja\"\n}\n"
  },
  {
    "path": "examples/simple_mode/example_163.json",
    "content": "{\n    \"description\": \"ノスタルジックな昭和歌謡、レトロなサウンドと哀愁漂うメロディー\",\n    \"instrumental\": false,\n    \"vocal_language\": \"ja\"\n}\n"
  },
  {
    "path": "examples/simple_mode/example_164.json",
    "content": "{\n    \"description\": \"キラキラしたアイドルポップ、元気いっぱいのダンスナンバー\",\n    \"instrumental\": false,\n    \"vocal_language\": \"ja\"\n}\n"
  },
  {
    "path": "examples/simple_mode/example_165.json",
    "content": "{\n    \"description\": \"ダークで激しいメタルコア、重厚なリフとシャウトボーカル\",\n    \"instrumental\": false,\n    \"vocal_language\": \"ja\"\n}\n"
  },
  {
    "path": "examples/simple_mode/example_166.json",
    "content": "{\n    \"description\": \"おしゃれなジャズヒップホップ、スムースなビートとクールなラップ\",\n    \"instrumental\": false,\n    \"vocal_language\": \"ja\"\n}\n"
  },
  {
    "path": "examples/simple_mode/example_167.json",
    "content": "{\n    \"description\": \"感動的な卒業ソング、合唱とオーケストラの壮大なアレンジ\",\n    \"instrumental\": false,\n    \"vocal_language\": \"ja\"\n}\n"
  },
  {
    "path": "examples/simple_mode/example_168.json",
    "content": "{\n    \"description\": \"夏祭りをイメージした和風ポップ、太鼓と笛が響く祭囃子\",\n    \"instrumental\": false,\n    \"vocal_language\": \"ja\"\n}\n"
  },
  {
    "path": "examples/simple_mode/example_169.json",
    "content": "{\n    \"description\": \"幻想的な和風インストゥルメンタル、琴と尺八が奏でる静寂の世界\",\n    \"instrumental\": true,\n    \"vocal_language\": \"ja\"\n}\n"
  },
  {
    "path": "examples/simple_mode/example_17.json",
    "content": "{\n    \"description\": \"chill lo-fi hip-hop beats for late night studying\",\n    \"instrumental\": true,\n    \"vocal_language\": \"en\"\n}\n"
  },
  {
    "path": "examples/simple_mode/example_170.json",
    "content": "{\n    \"description\": \"エモーショナルなビジュアル系ロック、美しいメロディーと激しいサウンド\",\n    \"instrumental\": false,\n    \"vocal_language\": \"ja\"\n}\n"
  },
  {
    "path": "examples/simple_mode/example_171.json",
    "content": "{\n    \"description\": \"爽やかなシティポップ、80年代風のグルーヴィーなサウンド\",\n    \"instrumental\": false,\n    \"vocal_language\": \"ja\"\n}\n"
  },
  {
    "path": "examples/simple_mode/example_172.json",
    "content": "{\n    \"description\": \"泣けるアコースティックバラード、ギターの弾き語りで綴る恋の歌\",\n    \"instrumental\": false,\n    \"vocal_language\": \"ja\"\n}\n"
  },
  {
    "path": "examples/simple_mode/example_173.json",
    "content": "{\n    \"description\": \"アップテンポなボカロ風エレクトロポップ、キャッチーなシンセサウンド\",\n    \"instrumental\": false,\n    \"vocal_language\": \"ja\"\n}\n"
  },
  {
    "path": "examples/simple_mode/example_174.json",
    "content": "{\n    \"description\": \"壮大なオーケストラインストゥルメンタル、映画音楽のような感動的なサウンドトラック\",\n    \"instrumental\": true,\n    \"vocal_language\": \"ja\"\n}\n"
  },
  {
    "path": "examples/simple_mode/example_175.json",
    "content": "{\n    \"description\": \"チルアウトなローファイヒップホップ、深夜の勉強BGMにぴったりな癒し系ビート\",\n    \"instrumental\": false,\n    \"vocal_language\": \"ja\"\n}\n"
  },
  {
    "path": "examples/simple_mode/example_176.json",
    "content": "{\n    \"description\": \"청량한 여름 느낌의 K-Pop\",\n    \"instrumental\": false,\n    \"vocal_language\": \"ko\"\n}\n"
  },
  {
    "path": "examples/simple_mode/example_177.json",
    "content": "{\n    \"description\": \"감성적인 새벽 감성 발라드\",\n    \"instrumental\": false,\n    \"vocal_language\": \"ko\"\n}\n"
  },
  {
    "path": "examples/simple_mode/example_178.json",
    "content": "{\n    \"description\": \"파워풀한 걸그룹 댄스곡\",\n    \"instrumental\": false,\n    \"vocal_language\": \"ko\"\n}\n"
  },
  {
    "path": "examples/simple_mode/example_179.json",
    "content": "{\n    \"description\": \"레트로 감성의 시티팝\",\n    \"instrumental\": false,\n    \"vocal_language\": \"ko\"\n}\n"
  },
  {
    "path": "examples/simple_mode/example_18.json",
    "content": "{\n    \"description\": \"vintage disco groove with funky bassline and shimmering strings\",\n    \"instrumental\": false,\n    \"vocal_language\": \"en\"\n}\n"
  },
  {
    "path": "examples/simple_mode/example_180.json",
    "content": "{\n    \"description\": \"힙한 느낌의 K-R&B\",\n    \"instrumental\": false,\n    \"vocal_language\": \"ko\"\n}\n"
  },
  {
    "path": "examples/simple_mode/example_181.json",
    "content": "{\n    \"description\": \"신나는 EDM 파티 트랙\",\n    \"instrumental\": false,\n    \"vocal_language\": \"ko\"\n}\n"
  },
  {
    "path": "examples/simple_mode/example_182.json",
    "content": "{\n    \"description\": \"잔잔한 어쿠스틱 포크\",\n    \"instrumental\": false,\n    \"vocal_language\": \"ko\"\n}\n"
  },
  {
    "path": "examples/simple_mode/example_183.json",
    "content": "{\n    \"description\": \"웅장한 영화 OST 스타일\",\n    \"instrumental\": false,\n    \"vocal_language\": \"ko\"\n}\n"
  },
  {
    "path": "examples/simple_mode/example_184.json",
    "content": "{\n    \"description\": \"몽환적인 K-Pop 인스트루멘탈\",\n    \"instrumental\": true,\n    \"vocal_language\": \"ko\"\n}\n"
  },
  {
    "path": "examples/simple_mode/example_185.json",
    "content": "{\n    \"description\": \"트렌디한 보이그룹 힙합 트랙\",\n    \"instrumental\": false,\n    \"vocal_language\": \"ko\"\n}\n"
  },
  {
    "path": "examples/simple_mode/example_186.json",
    "content": "{\n    \"description\": \"애절한 이별 감성 트로트\",\n    \"instrumental\": false,\n    \"vocal_language\": \"ko\"\n}\n"
  },
  {
    "path": "examples/simple_mode/example_187.json",
    "content": "{\n    \"description\": \"서정적인 피아노 재즈 인스트루멘탈\",\n    \"instrumental\": true,\n    \"vocal_language\": \"ko\"\n}\n"
  },
  {
    "path": "examples/simple_mode/example_188.json",
    "content": "{\n    \"description\": \"Romantischer deutscher Pop mit sanfter Melodie\",\n    \"instrumental\": false,\n    \"vocal_language\": \"de\"\n}\n"
  },
  {
    "path": "examples/simple_mode/example_189.json",
    "content": "{\n    \"description\": \"Energiegeladener deutscher Punk-Rock\",\n    \"instrumental\": false,\n    \"vocal_language\": \"de\"\n}\n"
  },
  {
    "path": "examples/simple_mode/example_19.json",
    "content": "{\n    \"description\": \"laid-back reggae summer vibes with offbeat guitar and warm organ\",\n    \"instrumental\": false,\n    \"vocal_language\": \"en\"\n}\n"
  },
  {
    "path": "examples/simple_mode/example_190.json",
    "content": "{\n    \"description\": \"Entspannter deutscher Reggae mit Sommergefühl\",\n    \"instrumental\": false,\n    \"vocal_language\": \"de\"\n}\n"
  },
  {
    "path": "examples/simple_mode/example_191.json",
    "content": "{\n    \"description\": \"Epischer deutscher Symphonic Metal\",\n    \"instrumental\": true,\n    \"vocal_language\": \"de\"\n}\n"
  },
  {
    "path": "examples/simple_mode/example_192.json",
    "content": "{\n    \"description\": \"Deutscher Schlager mit fröhlichem Rhythmus\",\n    \"instrumental\": false,\n    \"vocal_language\": \"de\"\n}\n"
  },
  {
    "path": "examples/simple_mode/example_193.json",
    "content": "{\n    \"description\": \"Melancholischer deutscher Indie-Folk\",\n    \"instrumental\": false,\n    \"vocal_language\": \"de\"\n}\n"
  },
  {
    "path": "examples/simple_mode/example_194.json",
    "content": "{\n    \"description\": \"Kraftvoller deutscher Hip-Hop mit tiefem Bass\",\n    \"instrumental\": false,\n    \"vocal_language\": \"de\"\n}\n"
  },
  {
    "path": "examples/simple_mode/example_195.json",
    "content": "{\n    \"description\": \"Chanson d'amour française douce et romantique\",\n    \"instrumental\": false,\n    \"vocal_language\": \"fr\"\n}\n"
  },
  {
    "path": "examples/simple_mode/example_196.json",
    "content": "{\n    \"description\": \"Électro française moderne avec beats énergiques\",\n    \"instrumental\": false,\n    \"vocal_language\": \"fr\"\n}\n"
  },
  {
    "path": "examples/simple_mode/example_197.json",
    "content": "{\n    \"description\": \"Jazz manouche avec guitare acoustique\",\n    \"instrumental\": true,\n    \"vocal_language\": \"fr\"\n}\n"
  },
  {
    "path": "examples/simple_mode/example_198.json",
    "content": "{\n    \"description\": \"Rock français alternatif avec paroles poétiques\",\n    \"instrumental\": false,\n    \"vocal_language\": \"fr\"\n}\n"
  },
  {
    "path": "examples/simple_mode/example_199.json",
    "content": "{\n    \"description\": \"Variété française nostalgique avec accordéon\",\n    \"instrumental\": false,\n    \"vocal_language\": \"fr\"\n}\n"
  },
  {
    "path": "examples/simple_mode/example_20.json",
    "content": "{\n    \"description\": \"aggressive thrash metal with shredding guitar solos and double bass drums\",\n    \"instrumental\": false,\n    \"vocal_language\": \"en\"\n}\n"
  },
  {
    "path": "examples/simple_mode/example_200.json",
    "content": "{\n    \"description\": \"Pop française contemporaine avec synthétiseurs\",\n    \"instrumental\": false,\n    \"vocal_language\": \"fr\"\n}\n"
  },
  {
    "path": "examples/simple_mode/example_21.json",
    "content": "{\n    \"description\": \"smoky jazz club ballad with brushed drums and mellow saxophone\",\n    \"instrumental\": false,\n    \"vocal_language\": \"en\"\n}\n"
  },
  {
    "path": "examples/simple_mode/example_22.json",
    "content": "{\n    \"description\": \"raw delta blues with slide guitar and gritty harmonica\",\n    \"instrumental\": false,\n    \"vocal_language\": \"en\"\n}\n"
  },
  {
    "path": "examples/simple_mode/example_23.json",
    "content": "{\n    \"description\": \"ethereal ambient soundscape with floating pads and gentle textures\",\n    \"instrumental\": true,\n    \"vocal_language\": \"en\"\n}\n"
  },
  {
    "path": "examples/simple_mode/example_24.json",
    "content": "{\n    \"description\": \"heartfelt acoustic folk storytelling with fingerpicked guitar and soft harmonies\",\n    \"instrumental\": false,\n    \"vocal_language\": \"en\"\n}\n"
  },
  {
    "path": "examples/simple_mode/example_25.json",
    "content": "{\n    \"description\": \"classic Motown soul with rich brass section and driving rhythm\",\n    \"instrumental\": false,\n    \"vocal_language\": \"en\"\n}\n"
  },
  {
    "path": "examples/simple_mode/example_26.json",
    "content": "{\n    \"description\": \"warm acoustic folk ballad with fingerpicked guitar and heartfelt vocals\",\n    \"instrumental\": false,\n    \"vocal_language\": \"en\"\n}\n"
  },
  {
    "path": "examples/simple_mode/example_27.json",
    "content": "{\n    \"description\": \"powerful gospel choir anthem with soaring harmonies and uplifting spirit\",\n    \"instrumental\": false,\n    \"vocal_language\": \"en\"\n}\n"
  },
  {
    "path": "examples/simple_mode/example_28.json",
    "content": "{\n    \"description\": \"raw punk rock anthem with aggressive energy and rebellious attitude\",\n    \"instrumental\": false,\n    \"vocal_language\": \"en\"\n}\n"
  },
  {
    "path": "examples/simple_mode/example_29.json",
    "content": "{\n    \"description\": \"dark grunge track with heavy distorted guitars and melancholic vocals\",\n    \"instrumental\": false,\n    \"vocal_language\": \"en\"\n}\n"
  },
  {
    "path": "examples/simple_mode/example_30.json",
    "content": "{\n    \"description\": \"energetic new wave dance track with punchy synths and catchy hooks\",\n    \"instrumental\": false,\n    \"vocal_language\": \"en\"\n}\n"
  },
  {
    "path": "examples/simple_mode/example_31.json",
    "content": "{\n    \"description\": \"nostalgic synthwave journey with retro 80s arpeggios and neon vibes\",\n    \"instrumental\": false,\n    \"vocal_language\": \"en\"\n}\n"
  },
  {
    "path": "examples/simple_mode/example_32.json",
    "content": "{\n    \"description\": \"hazy chillwave sunset track with lo-fi textures and dreamy pads\",\n    \"instrumental\": true,\n    \"vocal_language\": \"en\"\n}\n"
  },
  {
    "path": "examples/simple_mode/example_33.json",
    "content": "{\n    \"description\": \"ethereal dream pop with shimmering guitars and whispered vocals\",\n    \"instrumental\": false,\n    \"vocal_language\": \"en\"\n}\n"
  },
  {
    "path": "examples/simple_mode/example_34.json",
    "content": "{\n    \"description\": \"dreamy shoegaze wall of sound with layered reverb guitars and distant vocals\",\n    \"instrumental\": false,\n    \"vocal_language\": \"en\"\n}\n"
  },
  {
    "path": "examples/simple_mode/example_35.json",
    "content": "{\n    \"description\": \"expansive post-rock soundscape with crescendoing guitars and cinematic atmosphere\",\n    \"instrumental\": true,\n    \"vocal_language\": \"en\"\n}\n"
  },
  {
    "path": "examples/simple_mode/example_36.json",
    "content": "{\n    \"description\": \"complex progressive rock epic with shifting time signatures and virtuoso solos\",\n    \"instrumental\": false,\n    \"vocal_language\": \"en\"\n}\n"
  },
  {
    "path": "examples/simple_mode/example_37.json",
    "content": "{\n    \"description\": \"moody alternative rock with introspective lyrics and dynamic builds\",\n    \"instrumental\": false,\n    \"vocal_language\": \"en\"\n}\n"
  },
  {
    "path": "examples/simple_mode/example_38.json",
    "content": "{\n    \"description\": \"emotional emo ballad with confessional lyrics and soaring chorus\",\n    \"instrumental\": false,\n    \"vocal_language\": \"en\"\n}\n"
  },
  {
    "path": "examples/simple_mode/example_39.json",
    "content": "{\n    \"description\": \"upbeat ska punk with bouncy brass section and infectious energy\",\n    \"instrumental\": false,\n    \"vocal_language\": \"en\"\n}\n"
  },
  {
    "path": "examples/simple_mode/example_40.json",
    "content": "{\n    \"description\": \"deep dub reggae with heavy bass drops and spacey echo effects\",\n    \"instrumental\": true,\n    \"vocal_language\": \"en\"\n}\n"
  },
  {
    "path": "examples/simple_mode/example_41.json",
    "content": "{\n    \"description\": \"intimate acoustic singer-songwriter piece with gentle strumming and poetic lyrics\",\n    \"instrumental\": false,\n    \"vocal_language\": \"en\"\n}\n"
  },
  {
    "path": "examples/simple_mode/example_42.json",
    "content": "{\n    \"description\": \"driving synthwave chase theme with pulsing bass and dramatic tension\",\n    \"instrumental\": true,\n    \"vocal_language\": \"en\"\n}\n"
  },
  {
    "path": "examples/simple_mode/example_43.json",
    "content": "{\n    \"description\": \"soulful gospel-influenced R&B with powerful vocal runs and spiritual depth\",\n    \"instrumental\": false,\n    \"vocal_language\": \"en\"\n}\n"
  },
  {
    "path": "examples/simple_mode/example_44.json",
    "content": "{\n    \"description\": \"gritty grunge revival with fuzzy riffs and angst-filled screams\",\n    \"instrumental\": false,\n    \"vocal_language\": \"en\"\n}\n"
  },
  {
    "path": "examples/simple_mode/example_45.json",
    "content": "{\n    \"description\": \"melancholic dream pop lullaby with soft synths and ethereal harmonies\",\n    \"instrumental\": false,\n    \"vocal_language\": \"en\"\n}\n"
  },
  {
    "path": "examples/simple_mode/example_46.json",
    "content": "{\n    \"description\": \"一首充满青春活力的校园流行歌曲，适合毕业季\",\n    \"instrumental\": false,\n    \"vocal_language\": \"zh\"\n}\n"
  },
  {
    "path": "examples/simple_mode/example_47.json",
    "content": "{\n    \"description\": \"古风仙侠风格的唯美歌曲，带有琵琶和笛子元素\",\n    \"instrumental\": false,\n    \"vocal_language\": \"zh\"\n}\n"
  },
  {
    "path": "examples/simple_mode/example_48.json",
    "content": "{\n    \"description\": \"深夜电台风格的慢摇情歌，诉说着都市人的孤独\",\n    \"instrumental\": false,\n    \"vocal_language\": \"zh\"\n}\n"
  },
  {
    "path": "examples/simple_mode/example_49.json",
    "content": "{\n    \"description\": \"激昂的摇滚励志歌曲，唱出不服输的精神\",\n    \"instrumental\": false,\n    \"vocal_language\": \"zh\"\n}\n"
  },
  {
    "path": "examples/simple_mode/example_50.json",
    "content": "{\n    \"description\": \"温柔的民谣小调，适合午后阳光下的慵懒时光\",\n    \"instrumental\": false,\n    \"vocal_language\": \"zh\"\n}\n"
  },
  {
    "path": "examples/simple_mode/example_51.json",
    "content": "{\n    \"description\": \"带有中国风元素的现代流行曲，融合古典与时尚\",\n    \"instrumental\": false,\n    \"vocal_language\": \"zh\"\n}\n"
  },
  {
    "path": "examples/simple_mode/example_52.json",
    "content": "{\n    \"description\": \"甜蜜的恋爱告白歌曲，充满粉红泡泡的氛围\",\n    \"instrumental\": false,\n    \"vocal_language\": \"zh\"\n}\n"
  },
  {
    "path": "examples/simple_mode/example_53.json",
    "content": "{\n    \"description\": \"伤感的分手情歌，带有淡淡的忧伤和释然\",\n    \"instrumental\": false,\n    \"vocal_language\": \"zh\"\n}\n"
  },
  {
    "path": "examples/simple_mode/example_54.json",
    "content": "{\n    \"description\": \"节奏感强烈的说唱歌曲，展现街头文化态度\",\n    \"instrumental\": false,\n    \"vocal_language\": \"zh\"\n}\n"
  },
  {
    "path": "examples/simple_mode/example_55.json",
    "content": "{\n    \"description\": \"慵懒的爵士风格歌曲，适合咖啡馆的悠闲午后\",\n    \"instrumental\": false,\n    \"vocal_language\": \"zh\"\n}\n"
  },
  {
    "path": "examples/simple_mode/example_56.json",
    "content": "{\n    \"description\": \"动感的电子舞曲，适合派对和夜店氛围\",\n    \"instrumental\": false,\n    \"vocal_language\": \"zh\"\n}\n"
  },
  {
    "path": "examples/simple_mode/example_57.json",
    "content": "{\n    \"description\": \"怀旧的八九十年代港风情歌，复古浪漫\",\n    \"instrumental\": false,\n    \"vocal_language\": \"zh\"\n}\n"
  },
  {
    "path": "examples/simple_mode/example_58.json",
    "content": "{\n    \"description\": \"柔美的R&B情歌，带有丝滑的和声编排\",\n    \"instrumental\": false,\n    \"vocal_language\": \"zh\"\n}\n"
  },
  {
    "path": "examples/simple_mode/example_59.json",
    "content": "{\n    \"description\": \"宁静的古筝轻音乐，适合冥想和放松\",\n    \"instrumental\": true,\n    \"vocal_language\": \"zh\"\n}\n"
  },
  {
    "path": "examples/simple_mode/example_60.json",
    "content": "{\n    \"description\": \"热血的二次元风格动漫主题曲\",\n    \"instrumental\": false,\n    \"vocal_language\": \"zh\"\n}\n"
  },
  {
    "path": "examples/simple_mode/example_61.json",
    "content": "{\n    \"description\": \"治愈系的温暖民谣，讲述平凡生活中的小确幸\",\n    \"instrumental\": false,\n    \"vocal_language\": \"zh\"\n}\n"
  },
  {
    "path": "examples/simple_mode/example_62.json",
    "content": "{\n    \"description\": \"大气磅礴的史诗级纯音乐，适合影视配乐\",\n    \"instrumental\": true,\n    \"vocal_language\": \"zh\"\n}\n"
  },
  {
    "path": "examples/simple_mode/example_63.json",
    "content": "{\n    \"description\": \"清新的夏日海边风格流行歌曲，充满阳光气息\",\n    \"instrumental\": false,\n    \"vocal_language\": \"zh\"\n}\n"
  },
  {
    "path": "examples/simple_mode/example_64.json",
    "content": "{\n    \"description\": \"深情的钢琴伴奏抒情曲，诉说思念与等待\",\n    \"instrumental\": false,\n    \"vocal_language\": \"zh\"\n}\n"
  },
  {
    "path": "examples/simple_mode/example_65.json",
    "content": "{\n    \"description\": \"悠扬的竹笛与钢琴交织的中国风纯音乐\",\n    \"instrumental\": true,\n    \"vocal_language\": \"zh\"\n}\n"
  },
  {
    "path": "examples/simple_mode/example_66.json",
    "content": "{\n    \"description\": \"エネルギッシュなJ-Rockアニメオープニング、力強いボーカルとドライブ感のあるギターリフ\",\n    \"instrumental\": false,\n    \"vocal_language\": \"ja\"\n}\n"
  },
  {
    "path": "examples/simple_mode/example_67.json",
    "content": "{\n    \"description\": \"切ないピアノバラード、感情的な女性ボーカル\",\n    \"instrumental\": false,\n    \"vocal_language\": \"ja\"\n}\n"
  },
  {
    "path": "examples/simple_mode/example_68.json",
    "content": "{\n    \"description\": \"懐かしい80年代シティポップ、ファンキーなベースとスムースなサックス\",\n    \"instrumental\": false,\n    \"vocal_language\": \"ja\"\n}\n"
  },
  {
    "path": "examples/simple_mode/example_69.json",
    "content": "{\n    \"description\": \"アップビートなカワイイフューチャーベース、キュートなボーカルチョップとキラキラシンセ\",\n    \"instrumental\": false,\n    \"vocal_language\": \"ja\"\n}\n"
  },
  {
    "path": "examples/simple_mode/example_70.json",
    "content": "{\n    \"description\": \"ドラマチックなビジュアル系ロック、オーケストラ要素と劇的な男性ボーカル\",\n    \"instrumental\": false,\n    \"vocal_language\": \"ja\"\n}\n"
  },
  {
    "path": "examples/simple_mode/example_71.json",
    "content": "{\n    \"description\": \"伝統的な演歌バラード、モダンなプロダクションとソウルフルな男性ボーカル\",\n    \"instrumental\": false,\n    \"vocal_language\": \"ja\"\n}\n"
  },
  {
    "path": "examples/simple_mode/example_72.json",
    "content": "{\n    \"description\": \"ハイエナジーなボカロ風エレクトロポップ、速いテンポとロボティックなボーカル加工\",\n    \"instrumental\": false,\n    \"vocal_language\": \"ja\"\n}\n"
  },
  {
    "path": "examples/simple_mode/example_73.json",
    "content": "{\n    \"description\": \"チルな日本語ヒップホップ、ローファイビートとリラックスしたラップフロー\",\n    \"instrumental\": false,\n    \"vocal_language\": \"ja\"\n}\n"
  },
  {
    "path": "examples/simple_mode/example_74.json",
    "content": "{\n    \"description\": \"ドリーミーな渋谷系インディーポップ、フレンチハウスの影響と息づかいのある女性ボーカル\",\n    \"instrumental\": false,\n    \"vocal_language\": \"ja\"\n}\n"
  },
  {
    "path": "examples/simple_mode/example_75.json",
    "content": "{\n    \"description\": \"壮大なアニメバトルテーマ、シンフォニックメタル要素とコーラス\",\n    \"instrumental\": true,\n    \"vocal_language\": \"ja\"\n}\n"
  },
  {
    "path": "examples/simple_mode/example_76.json",
    "content": "{\n    \"description\": \"明るいJ-Popアイドルグループソング、キャッチーなフックとシンクロダンスビート\",\n    \"instrumental\": false,\n    \"vocal_language\": \"ja\"\n}\n"
  },
  {
    "path": "examples/simple_mode/example_77.json",
    "content": "{\n    \"description\": \"幻想的な和風アンビエント、伝統的な琴とモダンなエレクトロニックテクスチャー\",\n    \"instrumental\": true,\n    \"vocal_language\": \"ja\"\n}\n"
  },
  {
    "path": "examples/simple_mode/example_78.json",
    "content": "{\n    \"description\": \"激しい日本語メタルコア、スクリームボーカルとブレイクダウンセクション\",\n    \"instrumental\": false,\n    \"vocal_language\": \"ja\"\n}\n"
  },
  {
    "path": "examples/simple_mode/example_79.json",
    "content": "{\n    \"description\": \"ロマンチックなアニメエンディングテーマ、アコースティックギターと優しい女性ボーカル\",\n    \"instrumental\": false,\n    \"vocal_language\": \"ja\"\n}\n"
  },
  {
    "path": "examples/simple_mode/example_80.json",
    "content": "{\n    \"description\": \"グルーヴィーな日本語ファンクロック、スラップベースとエネルギッシュなブラスセクション\",\n    \"instrumental\": false,\n    \"vocal_language\": \"ja\"\n}\n"
  },
  {
    "path": "examples/simple_mode/example_81.json",
    "content": "{\n    \"description\": \"중독성 있는 후렴구와 신나는 K-Pop 댄스곡\",\n    \"instrumental\": false,\n    \"vocal_language\": \"ko\"\n}\n"
  },
  {
    "path": "examples/simple_mode/example_82.json",
    "content": "{\n    \"description\": \"현악 편곡이 아름다운 감성적인 K-드라마 OST 발라드\",\n    \"instrumental\": false,\n    \"vocal_language\": \"ko\"\n}\n"
  },
  {
    "path": "examples/simple_mode/example_83.json",
    "content": "{\n    \"description\": \"부드러운 보컬의 세련된 K-R&B\",\n    \"instrumental\": false,\n    \"vocal_language\": \"ko\"\n}\n"
  },
  {
    "path": "examples/simple_mode/example_84.json",
    "content": "{\n    \"description\": \"강렬한 트랩 비트의 K-힙합\",\n    \"instrumental\": false,\n    \"vocal_language\": \"ko\"\n}\n"
  },
  {
    "path": "examples/simple_mode/example_85.json",
    "content": "{\n    \"description\": \"몽환적인 K-인디 포크송\",\n    \"instrumental\": false,\n    \"vocal_language\": \"ko\"\n}\n"
  },
  {
    "path": "examples/simple_mode/example_86.json",
    "content": "{\n    \"description\": \"트로피컬 하우스 바이브의 상쾌한 K-Pop 여름 앤썸\",\n    \"instrumental\": false,\n    \"vocal_language\": \"ko\"\n}\n"
  },
  {
    "path": "examples/simple_mode/example_87.json",
    "content": "{\n    \"description\": \"파워풀한 기타 리프의 K-Rock\",\n    \"instrumental\": false,\n    \"vocal_language\": \"ko\"\n}\n"
  },
  {
    "path": "examples/simple_mode/example_88.json",
    "content": "{\n    \"description\": \"모던한 감각의 레트로 트로트\",\n    \"instrumental\": false,\n    \"vocal_language\": \"ko\"\n}\n"
  },
  {
    "path": "examples/simple_mode/example_89.json",
    "content": "{\n    \"description\": \"웅장한 오케스트라의 시네마틱 한국 OST 인스트루멘탈\",\n    \"instrumental\": true,\n    \"vocal_language\": \"ko\"\n}\n"
  },
  {
    "path": "examples/simple_mode/example_90.json",
    "content": "{\n    \"description\": \"레트로 신스와 디스코 베이스라인의 그루비한 K-펑크\",\n    \"instrumental\": false,\n    \"vocal_language\": \"ko\"\n}\n"
  },
  {
    "path": "examples/simple_mode/example_91.json",
    "content": "{\n    \"description\": \"파워풀한 보컬 클라이맥스의 애절한 K-발라드\",\n    \"instrumental\": false,\n    \"vocal_language\": \"ko\"\n}\n"
  },
  {
    "path": "examples/simple_mode/example_92.json",
    "content": "{\n    \"description\": \"강렬한 EDM 드롭의 파워풀한 K-Pop 걸그룹 앤썸\",\n    \"instrumental\": false,\n    \"vocal_language\": \"ko\"\n}\n"
  },
  {
    "path": "examples/simple_mode/example_93.json",
    "content": "{\n    \"description\": \"잔잔한 비트의 감성적인 K-R&B 로파이\",\n    \"instrumental\": false,\n    \"vocal_language\": \"ko\"\n}\n"
  },
  {
    "path": "examples/simple_mode/example_94.json",
    "content": "{\n    \"description\": \"몽환적인 앰비언트 텍스처의 K-인디 인스트루멘탈\",\n    \"instrumental\": true,\n    \"vocal_language\": \"ko\"\n}\n"
  },
  {
    "path": "examples/simple_mode/example_95.json",
    "content": "{\n    \"description\": \"랩 버스와 멜로딕 훅의 다이나믹한 K-Pop 보이그룹 트랙\",\n    \"instrumental\": false,\n    \"vocal_language\": \"ko\"\n}\n"
  },
  {
    "path": "examples/simple_mode/example_96.json",
    "content": "{\n    \"description\": \"Fröhlicher deutscher Schlager mit eingängiger Melodie und mitreißendem Refrain\",\n    \"instrumental\": false,\n    \"vocal_language\": \"de\"\n}\n"
  },
  {
    "path": "examples/simple_mode/example_97.json",
    "content": "{\n    \"description\": \"Dunkler deutscher Industrial-Rock mit verzerrten Gitarren\",\n    \"instrumental\": false,\n    \"vocal_language\": \"de\"\n}\n"
  },
  {
    "path": "examples/simple_mode/example_98.json",
    "content": "{\n    \"description\": \"Berliner Techno mit treibenden Beats und hypnotischen Synth-Mustern\",\n    \"instrumental\": true,\n    \"vocal_language\": \"de\"\n}\n"
  },
  {
    "path": "examples/simple_mode/example_99.json",
    "content": "{\n    \"description\": \"Melancholischer deutscher Indie-Pop mit nachdenklichen Texten\",\n    \"instrumental\": false,\n    \"vocal_language\": \"de\"\n}\n"
  },
  {
    "path": "examples/text2music/example_01.json",
    "content": "{\n    \"think\": true,\n    \"caption\": \"An explosive, high-energy pop-rock track with a strong anime theme song feel. The song kicks off with a catchy, synthesized brass fanfare over a driving rock beat with punchy drums and a solid bassline. A powerful, clear male vocal enters with a theatrical and energetic delivery, soaring through the verses and hitting powerful high notes in the chorus. The arrangement is dense and dynamic, featuring rhythmic electric guitar chords, brief instrumental breaks with synth flourishes, and a consistent, danceable groove throughout. The overall mood is triumphant, adventurous, and exhilarating.\",\n    \"lyrics\": \"[Intro - Synth Brass Fanfare]\\n\\n[Verse 1]\\n黑夜里的风吹过耳畔\\n甜蜜时光转瞬即万\\n脚步飘摇在星光上\\n心追节奏心跳狂乱\\n耳边传来电吉他呼唤\\n手指轻触碰点流点燃\\n梦在云端任它蔓延\\n疯狂跳跃自由无间\\n\\n[Chorus]\\n心电感应在震动间\\n拥抱未来勇敢冒险\\n那旋律在心中无限\\n世界变得如此耀眼\\n\\n[Instrumental Break - Synth Brass Melody]\\n\\n[Verse 2]\\n鼓点撞击黑夜的底端\\n跳动节拍连接你我俩\\n在这里让灵魂发光\\n燃尽所有不留遗憾\\n\\n[Instrumental Break - Synth Brass Melody]\\n\\n[Bridge]\\n光影交错彼此的视线\\n霓虹之下夜空的蔚蓝\\n月光洒下温热心田\\n追逐梦想它不会遥远\\n\\n[Chorus]\\n心电感应在震动间\\n拥抱未来勇敢冒险\\n那旋律在心中无限\\n世界变得如此耀眼\\n\\n[Outro - Instrumental with Synth Brass Melody]\\n[Song ends abruptly]\",\n    \"bpm\": 100,\n    \"duration\": 160,\n    \"keyscale\": \"B minor\",\n    \"language\": \"zh\",\n    \"timesignature\": \"4\"\n}"
  },
  {
    "path": "examples/text2music/example_02.json",
    "content": "{\n    \"think\": true,\n    \"caption\": \"A melancholic Latin trap track built on a foundation of deep 808 sub-bass and crisp, rolling hi-hats from a drum machine. A somber synth pad provides an atmospheric backdrop for the emotional male lead vocal, which is treated with noticeable auto-tune and spacious reverb. The chorus introduces layered vocals for added intensity and features prominent echoed ad-libs that drift through the mix. The arrangement includes a brief breakdown where the beat recedes to emphasize the raw vocal delivery before returning to the full instrumental for a final section featuring melodic synth lines over the main groove.\",\n    \"lyrics\": \"[Intro]\\nYeah\\nMe dicen ven, pero yo ya no quiero na'\\nTe cansaste de estar pa' mí, ya no hay marcha atrás\\nTu esencia se fue sin avisar\\nPero este mundo no me va a borrar\\n\\n[Verse 1]\\nNo hay más pa' ti ni de mami, ahora ves\\nNo vengas con drama, lo sabes\\nMe dijeron pa' siempre, pero mentían\\nComo si tú no estuvieras\\nSi yo fui tu juego y tú fuiste mi cárcel\\nAhora no lloro aunque cierre la cana\\nMe arde el aire, no hay vuelta, no hay miedo\\nHoy dejo atrás todo lo que me da miedo\\nTú me botaste, te fuiste del puerto\\nYo me quedé solo, fue pura derrota\\n\\n[Pre-Chorus]\\nNo era de por ti, lo entiendo, mi pana\\nTe vas con otros aunque duela la mañana\\nY si vuelvo, mira donde he llegado\\nYa no hay vuelta, no\\nNi tu plan en la mano\\n\\n[Chorus]\\nMe dicen ven, pero yo ya no quiero na'\\nNo quiero\\nTe cansaste de estar pa' mí, ya no hay marcha atrás\\nTu esencia se fue sin avisar\\nPero este mundo no me va a borrar\\nNo me va a borrar\\nSigo solo, sigo vacío, sigo abajo de mi tierra\\nAhora dejo atrás lo que me diste\\nEn un año me despido, te miro a los ojos\\nYa no soy tu tonto\\nTe lo avisé, pero nunca intentaste conmigo\\n\\n[Verse 2]\\nTe vi delirar, te vi mirarte\\nAhora entiendo que no fuiste amante\\nPero ya no me duele, ya no es rabia\\nYa no soy el tonto que dejaste en tu cama\\n\\n[Chorus]\\nMe dicen ven, pero yo ya no quiero na'\\nNo quiero\\nTe cansaste de estar pa' mí, ya no hay marcha atrás\\nTu esencia se fue sin avisar\\nPero este mundo no me va a borrar\\n\\n[Outro]\\n[Instrumental fades out]\",\n    \"bpm\": 100,\n    \"duration\": 159,\n    \"keyscale\": \"G# minor\",\n    \"language\": \"es\",\n    \"timesignature\": \"4\"\n}"
  },
  {
    "path": "examples/text2music/example_03.json",
    "content": "{\n    \"think\": true,\n    \"caption\": \"A dark, atmospheric trap track driven by a deep 808 sub-bass line and crisp, rolling hi-hats from a drum machine. A male vocalist delivers assertive French rap verses with a confident flow over moody synth pads that create an urban, nocturnal soundscape. The chorus features layered vocals for emphasis, enhancing the hypnotic feel. The arrangement includes sections where vocal chops and ad-libs are used rhythmically alongside subtle sound effects like record scratches, culminating in a filtered outro that fades into silence before reprising the main hook one last time.\",\n    \"lyrics\": \"[Intro]\\nAh\\nLa rue est froide\\nEh, eh, eh\\n\\n[Chorus]\\nLa nuit tombe et je rentre, je fume sous la lune\\nLes ombres m'appellent, je suis pas seul, je continue\\nLes rêves sous la pluie, mon cœur sous la béton\\nJe trace ma route même si la route est longue\\n\\n[Verse 1]\\nLes murs ont des oreilles, les pavés des secrets\\nUn faux sourire et t'es déjà trop proche de ta mère\\nJ'ai des chaînes invisibles mais elles claquent plus fort\\nChaque épreuve c'est une chance, faut qu'on en profite encore\\nJ'entends les sirènes, mais je suis déjà en bas\\nLe silence est dur mais ça me tient le bras\\nTrop de choses à dire, je te jure c'est une blague\\nJe sais que le monde tourne mais j'avance sans drague\\nFaut que ça pète, pas de place pour les faux\\nLa rue c'est un jeu, faut pas se prendre trop au sérieux\\nLes rêves c'est du béton, pas des gratte-ciels\\nJe fais mon truc, je suis un soldat, pas un pasteur\\nLes vautours tournent, je suis dans mon délire\\nChaque erreur me fait rire, chaque choix me fait frémir\\nJ'ai le cœur glacé mais le mental est solide\\nLa rue m'apprend qu'il faut jamais on la liquide\\nJ'entends des voix mais elles ne disent rien\\nLe silence est une arme, faut que je prenne un destin\\nFaut que ça tourne, laisse-les rêver ou c'est du passé\\nC'est la vie, faut jamais lâcher\\n\\n[Chorus]\\nLa nuit tombe et je rentre, je fume sous la lune\\nLes ombres m'appellent, je suis pas seul, je continue\\nLes rêves sous la pluie, mon cœur sous la béton\\nJe trace ma route même si la route est longue\\nLa nuit tombe et je rentre, je fume sous la lune\\nLes ombres m'appellent, je suis pas seul, je continue\\nLes rêves sous la pluie, mon cœur sous la béton\\nJe trace ma route même si la route est longue\\n\\n[Verse 2]\\nTrop de gens cherchent une main, je trouve que des pièges\\nChaque pas est un combat, faut que je lâche\\nLe monde est lent mais les vrais sont lucides\\nJ'ai gravé mon nom dans la peur et l'acide\\nLa ville dort mais je garde mon miroir\\nLes faux veulent ma peau mais le regard est noir\\nLa rue c'est un livre, j'y crache ma libération\\nJe suis là pour tout prendre, pas pour la direction\\nLes ombres murmurent mais je suis déjà loin\\nLe silence m'éteint, je garde la lumière au poignet\\nLes regards sont froids, je vois des âmes en veille\\nJe fais mon taf, je vois le ciel qui surveille\\n\\n[Chorus]\\nLa nuit tombe et je rentre, je fume sous la lune\\nLes ombres m'appellent, je suis pas seul, je continue\\nLes rêves sous la pluie, mon cœur sous la béton\\nJe trace ma route même si la route est longue\\n\\n[Outro]\\nLa nuit tombe\\nEh, eh, eh\\nLa nuit tombe\\nEh, eh, eh\\nLa nuit tombe et je rentre, je fume sous la lune\\nLes ombres m'appellent, je suis pas seul, je continue\\nLes rêves sous la pluie, mon cœur sous la béton\\nJe trace ma route même si la route est longue\\n[Beat fades out]\",\n    \"bpm\": 100,\n    \"duration\": 142,\n    \"keyscale\": \"E minor\",\n    \"language\": \"fr\",\n    \"timesignature\": \"4\"\n}"
  },
  {
    "path": "examples/text2music/example_04.json",
    "content": "{\n    \"think\": true,\n    \"caption\": \"A mid-tempo Mandopop ballad built on a steady electronic drum machine groove and a clean synth bassline. The arrangement features layered synthesizers providing chordal pads and melodic counterpoints, complemented by a clean electric guitar playing arpeggiated figures. The emotional male lead vocal, sung in Mandarin, soars through the verses and choruses, often reaching into a powerful falsetto. The track includes an expressive, melodic electric guitar solo and a dynamic bridge that builds tension before a final, passionate chorus filled with vocal ad-libs and a climactic guitar flourish.\",\n    \"lyrics\": \"[Intro]\\nYeah\\nOne\\n\\n[Verse  1]\\n[zh] ye4 wan3 de5 feng1   qing1 qing1 chui1 guo4\\n[zh] ni3 de5 xiao4 rong2   zai4 wo3 xin1 zhong1 shan3 shuo4\\n[zh] yi1 ju4 hua4   shuo1 bu4 chu1 kou3 de5 zhi2 zhuo2\\n[zh] xiang4 xing1 guang1 sa3 man3   wu2 jin4 de5 ye4 kong1\\n\\n[Chorus]\\n[zh] ni3 shi4 wo3 xin1 di3   wu2 fa3 mo3 qu4 de5 meng4\\n[zh] zai4 mei3 yi2 ge4 shun4 jian1   dou1 rang4 wo3 chen2 zui4 tong4\\n[zh] ai4 zai4 xuan2 lv4 zhong1   wo3 de5 ling2 hun2 xiang1 tong1\\n[zh] gen1 sui2 jie2 pai1   yi1 qie4 dou1 shi4 xin1 dong4\\n\\n[Verse  2]\\n[zh] jie1 jiao3 de5 deng1 ying3   ying4 chu1 bi3 ci3 yan3 shen2\\n[zh] xin1 tiao4 de5 jie2 zou4   bian4 de2 geng4 mi2 ren2\\n[zh] yong1 bao4 de5 wen1 du4   rang4 shi4 jie4 bian4 qing1 chen2\\n[zh] ai4 xiang4 yi1 shou3 wu2 fa3 ting2 zhi3 de5 qu1 ben3\\n\\n[Pre-Chorus]\\n[zh] ni3 de5 sheng1 yin1   zai4 yin1 fu2 li3 piao1 you2\\n[zh] mei3 yi2 ge4 shun4 jian1   dou1 rang4 wo3 xin1 gan3 shou4\\n[zh] ji2 ta1 de5 sheng1 bo1   hua4 chu1 ni3 de5 xiao4 rong2\\n[zh] he2 sheng1 qi3 he2 gu3 dian3 dou1 zai4 zhi4 re4 you2 dong4\\n\\n[Chorus]\\n[zh] ni3 shi4 wo3 xin1 di3   wu2 fa3 mo3 qu4 de5 meng4\\n[zh] zai4 mei3 yi2 ge4 shun4 jian1   dou1 rang4 wo3 chen2 zui4 tong4\\n[zh] ai4 zai4 xuan2 lv4 zhong1   wo3 de5 ling2 hun2 xiang1 tong1\\n[zh] gen1 sui2 jie2 pai1   yi1 qie4 dou1 shi4 xin1 dong4\\n\\n[Guitar Solo]\\nOh\\nYeah\\n\\n[Bridge]\\n[zh] dang1 dian4 liu2 de5 shan3 shuo4   rang4 ye4 wan3 fei4 teng2\\n[zh] wo3 men5 de5 xin1 ling2   ru2 gu3 sheng1 ban1 fan1 gun3\\n[zh] jiu4 rang4 zhe4 yi1 ke4   sui2 yin1 yue4 geng4 zhen1\\n[zh] ni3 shi4 wo3 de5 yin1 yue4   shi4 yong3 heng2 de5 wen1 hen2\\n\\n[Outro]\\n[Vocal ad-libs]\\nOh\\nOh\\nOh\\nOh\\n[Final guitar chord and fade out]\",\n    \"bpm\": 100,\n    \"duration\": 235,\n    \"keyscale\": \"G# minor\",\n    \"language\": \"zh\",\n    \"timesignature\": \"4\"\n}"
  },
  {
    "path": "examples/text2music/example_05.json",
    "content": "{\n    \"think\": true,\n    \"caption\": \"An explosive, high-energy J-rock and pop-rock anthem driven by a powerful, punchy drum beat and a thick wall of distorted, chugging rhythm guitars. A passionate male lead vocal, delivered in a mix of Japanese and English, soars over the top with layered harmonies and echoed ad-libs that amplify the song's anthemic quality. The arrangement is dynamic, featuring a blistering, melodic guitar solo and a brief, atmospheric bridge with synth pads that provides a moment of contrast before slamming back into the high-octane chorus. The track concludes with a final, powerful guitar chord and a lingering sense of energy.\",\n    \"lyrics\": \"[Intro]\\nOne more time, just one more time\\nMou modorenai, mou modorenai\\nThe GURU, my dream come true, my dream come true\\n\\n[Guitar Riff]\\n\\n[Verse 1]\\nNani ga seigi ka, nani ga koukai ka\\nHakase tsuzukeru, hashirinukeru\\nNo life's a game, no rules to follow\\nDakedo arata na chikara ga yomigaeru\\n\\n[Pre-Chorus]\\nNo, this is our new life\\nAisuru chikara, ima koso\\nWe believe in ourselves\\nMou atomodori dekinai\\n\\n[Chorus]\\nEikou no hikari\\nSono saki ni iru jiyuu ga aru\\nOne more time, just one more time\\nMou modorenai, mou modorenai\\nThe GURU, my dream come true, my dream come true\\n\\n[Verse 2]\\nKizutsuita tsubasa mo aruita michi mo\\nOnaji hibi no naka de susumu\\nNo stage to the hill, sore demo susumu\\nMayowanai de susumu, susumu\\n\\n[Pre-Chorus]\\nAisuru chikara, ima koso\\nWe believe in ourselves\\nMou atomodori dekinai\\n\\n[Chorus]\\nEikou no hikari\\nSono saki ni iru jiyuu ga aru\\nOne more time, just one more time\\nMou modorenai, mou modorenai\\nThe GURU, my dream come true, my dream come true\\n\\n[Guitar Solo]\\n\\n[Bridge]\\nDonna arashi ni matsu ka? I know\\nNando mo yami ni shizumu ka?\\nOre wa yuku, ore wa yuku\\nChikara tsuyoku, yume wo motte\\nChikara tsuyoku, yume wo motte\\nTooi hikari, moeagaru\\nKono kokoro ni hibiku takami\\nWe are in the zone, we are in the zone\\n\\n[Breakdown]\\nSono saki ni iru mirai ga aru\\nOne more time, just one more time\\nMou modorenai, mou modorenai\\nThe GURU, my dream come true, my dream come true\\n\\n[Outro]\\nKizutsuite mo\\nMakenai yume wo\\nNo stage to the hill, sore demo\\nOre wa susumu, ore wa susumu\\nMata tachiagaru, mata tachiagaru\\n\\n[Final Guitar Riff and Fade Out]\",\n    \"bpm\": 100,\n    \"duration\": 200,\n    \"keyscale\": \"E♭ minor\",\n    \"language\": \"ja\",\n    \"timesignature\": \"4\"\n}"
  },
  {
    "path": "examples/text2music/example_06.json",
    "content": "{\n    \"think\": true,\n    \"caption\": \"An energetic and uplifting J-pop track with strong anime theme song characteristics. The song opens with a bright piano melody and shimmering synth arpeggios before launching into a driving pop-rock arrangement. A clear, powerful male vocal leads the track, supported by a tight rhythm section of punchy drums and a melodic bassline. Clean and slightly overdriven electric guitars provide rhythmic chords and soaring lead lines, particularly during the anthemic chorus and a brief, expressive guitar solo. The structure includes a reflective bridge that momentarily softens the dynamics, followed by a powerful final chorus and an outro featuring melodic guitar licks and vocal ad-libs that fade to a clean finish.\",\n    \"lyrics\": \"[Intro - Synth Arpeggio & Guitar Riff]\\n\\n[Verse 1]\\n空に浮かぶ雲の切れ間に\\n願い事をそっと浮かべて\\n今日がまた新しい始まり\\n今この瞬間を生きていこう\\n\\n[Pre-Chorus]\\nほら 聞こえるよ\\n心の奥の声が\\n何か始まる予感を抱いて\\n今すぐに飛び出そう\\n\\n[Chorus]\\n飛び出そう 明日へと\\n風をまとって進むだけさ\\nどんな日もが物語るから\\n輝く未来を掴もう\\n光の中へ踊ろう\\n\\n[Instrumental Break]\\n\\n[Verse 2]\\n朝日が差し込む君の影\\n迷わずに進んでいけばいい\\n不安も希望も抱きしめて\\n強く踏み出してゆくよ\\n\\n[Pre-Chorus]\\nほら 聞こえるよ\\n胸の奥の鼓動が\\n夢の扉を開いてゆく\\n輝きを捕まえる\\n\\n[Chorus]\\n飛び出そう 明日へと\\n風をまとって進むだけさ\\nどんな日もが物語るから\\n輝く未来を掴もう\\n光の中へ踊ろう\\n\\n[Guitar Solo]\\n\\n[Bridge]\\nもしも道に迷って立ち止まる日が来ても\\nこの道の先は笑顔が待ってるから\\n信じてみようよ\\n未来は輝いてる\\n一つの星に生まれ変わるんだ\\n\\n[Chorus]\\n飛び出そう 明日へと\\n風をまとって進むだけさ\\nどんな日もが物語るから\\n輝く未来を掴もう\\n光の中へ踊ろう\\n\\n[Outro]\\n音楽と共に飛ぶよ\\n[Synth arpeggio fades out]\",\n    \"bpm\": 100,\n    \"duration\": 205,\n    \"keyscale\": \"F# major\",\n    \"language\": \"ja\",\n    \"timesignature\": \"2\"\n}"
  },
  {
    "path": "examples/text2music/example_07.json",
    "content": "{\n    \"think\": true,\n    \"caption\": \"An energetic electro-pop track driven by a squelchy, funky synth bassline and a punchy drum machine beat. The song opens with a distinctive, pitch-bending synth lead that serves as a recurring hook. The male vocals are delivered in a confident, rhythmic, almost rap-like cadence during the verses, transitioning to a more melodic and anthemic style in the chorus. The production is clean and modern, with layered synths and dynamic builds. A brief, atmospheric bridge offers a moment of contrast with sustained synth pads before the track slams back into a high-energy instrumental section and a final, powerful chorus.\",\n    \"lyrics\": \"[Intro - Synth Bass Riff]\\n\\n[Verse 1]\\nChaque jour, c'est la retraite, c'est le plein de repas\\nOn est déjà en vacances, on est là pour ça\\nLes copains ont tout ce qu'on veut, on est prêts à bosser\\nMais on revient à pied, on va tout explodir\\nLes clients regardent, faut qu'on les contacte\\nC'est pas une course, c'est un moment de spectacle\\nOn attend, on sourit, on fait la loi\\nMais on préfère l'action, pas l'effort du choix\\n\\n[Chorus]\\nOn est là pour marquer, là pour tout exploser\\nLe feu, la patate, faut vite tout chambouler\\nMême en retard, faut bouger\\nParce qu'on a plus peur d'exister\\n\\n[Instrumental Break - Synth Bass Riff]\\n\\n[Verse 2]\\nPas besoin d'armure, faut du capital\\nOn est les mêmes, on est dans l'agenda digital\\nOn se frotte les mains, c'est l'énergie pure\\nMême s'il y a bientôt dix jours à défendre sans murmure\\nLes affiches tremblent, les commandes explosent\\nL'agence, c'est notre trône, pas juste une cause\\nOn fait le taf, on fait bouger le pays\\nMais ensemble on a tout, c'est pour rassoumer ici\\nLes copains, les meufs, c'est la règle de tout\\nSi on part en morceaux, c'est qu'on y va jusqu'au bout\\nLa patate en flammes, l'action dans la main\\nOn est là pour marquer, faut pas lâcher notre refrain\\n\\n[Chorus]\\nOn est là pour marquer, là pour tout exploser\\nLe feu, la patate, faut vite tout chambouler\\nMême en retard, faut bouger\\nParce qu'on a plus peur d'exister\\n\\n[Bridge]\\nLe stress monte, la galère s'installe\\nOn est là pour gratter tout, peu importe le débat fatal\\nOn rêve grand, on part à l'aventure\\nLa patate au niveau haut, c'est notre vraie mur\\nAlors levons nos verres, remplissons notre esprit\\nLes coups de malaxe, on\\n'est pas à se trahir\\nC'est l'ambiance qu'on déclare, pas besoin d'armure\\nOn va marquer l'équipe, on est là, on assure\\n\\n[Instrumental Break - Synth Bass Riff]\\n\\n[Outro]\\nLe stress monte, la galère s'installe\\nOn est là pour gratter tout, peu importe le débat fatal\\nOn rêve grand, on part à l'aventure\\nLa patate au niveau haut, c'est notre vraie mur\\nAlors levons nos verres, remplissons notre esprit\\nLes coups de malaxe, on\\n'est pas à se trahir\\nC'est l'ambiance qu'on déclare, pas besoin d'armure\\nOn va marquer l'équipe, on est là, on assure\\n[Synth bass riff fades out]\",\n    \"bpm\": 100,\n    \"duration\": 180,\n    \"keyscale\": \"F minor\",\n    \"language\": \"fr\",\n    \"timesignature\": \"4\"\n}"
  },
  {
    "path": "examples/text2music/example_08.json",
    "content": "{\n    \"think\": true,\n    \"caption\": \"An upbeat and celebratory Brazilian samba-pop track driven by a vibrant rhythm section. A nimble nylon-string acoustic guitar lays down the chordal foundation, while a lively brass section, featuring trumpets and trombones, punctuates the arrangement with festive fanfares and melodic lines. The lead male vocal is clear and joyful, singing over a tight groove provided by a clean electric bass and a full drum kit. The song's structure is built for dancing, with an infectious chorus and an instrumental break showcasing a spirited brass and guitar interplay.\",\n    \"lyrics\": \"[Intro - Brass Section Melody]\\n\\n[Verse 1]\\nOlha a morena dançando na rua\\nVestido vermelho é pura magia\\nParece rainha de chapéu de bua\\nMeu coração bate na tua melodia\\n\\n[Chorus]\\nParabéns, malagueira morena\\nPra todos os cães do nosso Brasil\\nCaminho no pôr do sol, pequena\\nEntri no nosso show\\nFeliz sinal\\n\\n[Instrumental Break - Brass Section]\\n\\n[Verse 2]\\nMorena gira com sua piquenino\\nE os olhos d'água refletindo no céu\\nCabelo caído com o rostinho fino\\nDesperta no ritmo do carrossel\\n\\n[Chorus]\\nParabéns, malagueira morena\\nPra todos os cães do nosso Brasil\\nCaminho no pôr do sol, pequena\\nEntri no nosso show\\nFeliz sinal\\n\\n[Instrumental Break - Brass Section]\\n\\n[Bridge]\\nLuzes estreladas iluminam a noite\\nReflete nos becos, nas ruas, nos bares\\nVem brincar no canto, sorrir no derroche\\nEssa morena dança onde as estrelas caem\\n\\n[Chorus]\\nParabéns, malagueira morena\\nPra todos os cães do nosso Brasil\\nCaminho no pôr do sol, pequena\\nEntri no nosso show\\nFeliz sinal\\n\\n[Outro - Brass Section Melody]\\n[Final chord fades out]\",\n    \"bpm\": 100,\n    \"duration\": 174,\n    \"keyscale\": \"C major\",\n    \"language\": \"pt\",\n    \"timesignature\": \"4\"\n}"
  },
  {
    "path": "examples/text2music/example_09.json",
    "content": "{\n    \"think\": true,\n    \"caption\": \"An explosive, high-energy J-pop track with strong hyperpop and chiptune influences. The song is driven by a relentless four-on-the-floor electronic drum beat and a punchy synth bassline. A high-pitched, digitally processed female vocal, reminiscent of Vocaloid, delivers rapid-fire melodies over layers of bright, arpeggiated synths and video game-style sound effects. The structure is dynamic, featuring intense verses and anthemic choruses that build into a frenetic instrumental break filled with complex synth runs and glitched-out fills. The track concludes with a dramatic tape-stop effect, deconstructing the beat into a wash of fading synth noise.\",\n    \"lyrics\": \"[Intro]\\nKimi no koe ga kikoeru\\nMotto motto tooku tooku\\nAnata no ai wa eien ni\\nSugiru omoi koto ni kaete\\n\\n[Instrumental Break]\\n\\n[Verse 1]\\nYume no naka de kawasu kotoba\\nTada no kakehiki\\nKokoro no naka de narihibiku\\nAnata e no ai koi suru\\n\\n[Chorus]\\nAnata no ai\\nItsumademo yume mitai\\nKienai omoi\\nItsumademo tsunagatteru\\n\\n[Post-Chorus]\\nKimi to deatta ano hi\\nSubete ga chigatta\\nAnata no ai de tsunagatte\\nOwaranai you ni kono mama\\n\\n[Instrumental Break]\\n\\n[Verse 2]\\nKurikaesu hibi no naka de\\nAi ga afuredasu\\nAnata no nukumori o kanjiru\\nYukuate no nai koi\\n\\n[Chorus]\\nAnata no ai\\nItsumademo yume mitai\\nKienai omoi\\nItsumademo tsunagatteru\\n\\n[Instrumental Solo]\\n\\n[Bridge]\\nKurikaesu hibi no naka de\\nAi ga afuredasu\\nAnata no nukumori o kanjiru\\nYukuate no nai koi\\n\\n[Chorus]\\nAnata no ai\\nItsumademo yume mitai\\nKienai omoi\\nItsumademo tsunagatteru\\n\\n[Outro]\\n[Instrumental Breakdown]\\n[Synth arpeggio fades out]\",\n    \"bpm\": 100,\n    \"duration\": 167,\n    \"keyscale\": \"E♭ minor\",\n    \"language\": \"ja\",\n    \"timesignature\": \"2\"\n}"
  },
  {
    "path": "examples/text2music/example_10.json",
    "content": "{\n    \"think\": true,\n    \"caption\": \"A smooth, contemporary R&B track built on a foundation of clean, chorused electric guitar chords and a steady, unobtrusive drum machine beat. A round synth bass provides a warm low end. The lead male vocal is clear and emotive, delivered in a smooth tenor with occasional falsetto ad-libs and layered harmonies that swell during the anthemic chorus. The arrangement features a brief, intimate bridge with whispered vocals before transitioning into a melodic guitar-led instrumental break. The track concludes with a layered vocal outro, combining sung melodies with whispered phrases that fade to a clean finish.\",\n    \"lyrics\": \"[Intro]\\nYeah\\nOh\\nYeah\\n\\n[Verse 1]\\nMidnight whispers in my ear\\nStars above, they're shining clear\\nCity lights, they start to fade\\nUnderneath, our plans we've made\\nMoonlit shadows twist and turn\\nHearts on fire, passions burn\\nLaughter echoes through the night\\nHolding hands, we take flight\\n\\n[Chorus]\\nYou're my heartbeat symphony\\nEchoes of sweet destiny\\nEvery beat a symphony\\nYou and me, we're wild and free\\n\\n[Verse 2]\\nNeon dreams and city haze\\nLost in love's enchanting maze\\nWhisper secrets in the breeze\\nTime just stops as we appease\\n\\n[Chorus]\\nYou're my heartbeat symphony\\nEchoes of sweet destiny\\nEvery beat a symphony\\nYou and me, we're wild and free\\n\\n[Bridge]\\nDance through stars and find our way\\nIn your arms, I'll always stay\\nLove so strong, it never bends\\nTogether 'til the journey ends\\n\\n[Instrumental Break]\\n\\n[Outro]\\nDance through stars and find our way\\nIn your arms, I'll always stay\\nLove so strong, it never bends\\nTogether 'til the journey ends\\nYou're my heartbeat symphony\\nEchoes of sweet destiny\\nEvery beat a symphony\\nYou and me, we're wild and free\\nDance through stars and find our way\\nIn your arms, I'll always stay\\nLove so strong, it never bends\\nTogether 'til the journey ends\",\n    \"bpm\": 100,\n    \"duration\": 228,\n    \"keyscale\": \"A major\",\n    \"language\": \"en\",\n    \"timesignature\": \"4\"\n}"
  },
  {
    "path": "examples/text2music/example_100.json",
    "content": "{\n    \"think\": true,\n    \"caption\": \"A catchy Chinese hip-hop track with confident male rap verses, trap-influenced beats, and a melodic sung hook. The production features heavy 808 bass, hi-hat rolls, and modern synth textures.\",\n    \"lyrics\": \"[Intro]\\nYeah 准备好了吗\\n让我们开始\\n\\n[Verse 1]\\n从地下室到舞台中央\\n一路走来我从不迷茫\\n他们说我不行 我用实力证明\\n每一个音符都是我的武器\\n麦克风在手 我就是王\\n节奏响起 全场跟我一起唱\\n\\n[Chorus]\\n我们不一样 不一样\\n走自己的路 发自己的光\\n我们不一样 不一样\\n用音乐改变世界的模样\\n\\n[Verse 2]\\n凌晨四点还在写词\\n为了梦想我可以付出一切\\n别跟我说什么不可能\\n我的字典里没有这个词\\n从零开始 一步一步\\n现在站在这里 就是最好的证明\\n\\n[Chorus]\\n我们不一样 不一样\\n走自己的路 发自己的光\\n我们不一样 不一样\\n用音乐改变世界的模样\\n\\n[Outro]\\n这就是我的故事\\n还没有结束\",\n    \"bpm\": 130,\n    \"duration\": 195,\n    \"keyscale\": \"F minor\",\n    \"language\": \"zh\",\n    \"timesignature\": \"4\"\n}\n"
  },
  {
    "path": "examples/text2music/example_101.json",
    "content": "{\n    \"think\": true,\n    \"caption\": \"A warm Chinese folk song (民谣) with acoustic guitar fingerpicking, harmonica, and heartfelt male vocals. The production is intimate and organic, capturing the essence of wandering and nostalgia.\",\n    \"lyrics\": \"[Intro]\\n\\n[Verse 1]\\n背上行囊离开家乡\\n火车带我去远方\\n妈妈站在村口挥手\\n眼泪模糊了她的脸庞\\n\\n[Verse 2]\\n城市的灯火很璀璨\\n却照不亮我的孤单\\n合租房里的小床\\n装不下我的梦想\\n\\n[Chorus]\\n我想回家 回到那个小村庄\\n门前的老槐树 还在不在\\n我想回家 看看年迈的爹娘\\n他们的白发 又添了几根\\n\\n[Verse 3]\\n电话那头妈妈说\\n家里一切都很好\\n可我听到她的声音\\n藏着多少思念和牵挂\\n\\n[Chorus]\\n我想回家 回到那个小村庄\\n门前的老槐树 还在不在\\n我想回家 看看年迈的爹娘\\n他们的白发 又添了几根\\n\\n[Outro]\\n\\n等我 等我回家\",\n    \"bpm\": 92,\n    \"duration\": 209,\n    \"keyscale\": \"C major\",\n    \"language\": \"zh\",\n    \"timesignature\": \"4\"\n}"
  },
  {
    "path": "examples/text2music/example_102.json",
    "content": "{\n    \"think\": true,\n    \"caption\": \"A bright and uplifting C-pop dance track with catchy female vocals, synth hooks, and four-on-the-floor beats. The production features sparkling arpeggios, punchy kicks, and an infectious chorus designed for maximum catchiness.\",\n    \"lyrics\": \"[Intro]\\n\\nHey hey hey\\n\\n[Verse 1]\\n今天的阳光特别灿烂\\n心情好得想要飞上天\\n穿上最爱的那条裙子\\n对着镜子笑一笑\\n\\n[Pre-Chorus]\\n管他什么烦恼\\n今天统统忘掉\\n\\n[Chorus]\\n跳起来 跳起来\\n让快乐填满整个世界\\n摇起来 摇起来\\n把所有的不开心都甩开\\nLa la la la la\\n今天我最闪亮\\n\\n[Verse 2]\\n朋友们都在等我\\n派对马上就要开始\\n音乐响起的那一刻\\n我就是舞池的女王\\n\\n[Chorus]\\n跳起来 跳起来\\n让快乐填满整个世界\\n摇起来 摇起来\\n把所有的不开心都甩开\\n\\n[Bridge]\\n不管明天会怎样\\n至少今晚我们一起疯狂\\n\\n[Outro]\\nLa la la la la\\n永远年轻 永远热泪盈眶\",\n    \"bpm\": 128,\n    \"duration\": 198,\n    \"keyscale\": \"Bb major\",\n    \"language\": \"zh\",\n    \"timesignature\": \"4\"\n}"
  },
  {
    "path": "examples/text2music/example_103.json",
    "content": "{\n    \"think\": true,\n    \"caption\": \"A romantic duet ballad with interweaving male and female vocals, lush orchestral arrangement, and emotional piano. The song builds from intimate verses to a soaring chorus with full string section.\",\n    \"lyrics\": \"[Intro]\\n\\n[Verse 1]\\n第一次遇见你的那天\\n阳光正好 微风不燥\\n你的笑容像春天的花\\n悄悄住进我心里\\n\\n[Verse 1]\\n我假装不经意地看你\\n心跳却出卖了我\\n原来爱情来的时候\\n真的没有任何预兆\\n\\n[Chorus]\\n让我牵着你的手\\n走过春夏秋冬\\n不管前方有多少风雨\\n我们一起面对\\n你是我的唯一\\n我是你的永远\\n这一生只爱你一个人\\n\\n[Verse 2]\\n我愿意为你摘下星星\\n\\n[Verse 2]\\n我愿意陪你看遍风景\\n\\n[Chorus]\\n让我牵着你的手\\n走过春夏秋冬\\n不管前方有多少风雨\\n我们一起面对\\n\\n[Outro]\\n执子之手 与子偕老\\n这就是我对你的承诺\",\n    \"bpm\": 76,\n    \"duration\": 217,\n    \"keyscale\": \"D major\",\n    \"language\": \"zh\",\n    \"timesignature\": \"4\"\n}"
  },
  {
    "path": "examples/text2music/example_104.json",
    "content": "{\n    \"think\": true,\n    \"caption\": \"A nostalgic Chinese indie rock song with jangly guitars, warm bass tones, and introspective male vocals. The production has a vintage feel with analog warmth and dreamy reverb effects.\",\n    \"lyrics\": \"[Intro]\\n\\n[Verse 1]\\n毕业那年的夏天\\n我们在操场上告别\\n说好要一直联系\\n却渐渐失去了消息\\n\\n[Verse 2]\\n翻开发黄的同学录\\n看到你写的那句话\\n愿你前程似锦\\n我们后会有期\\n\\n[Chorus]\\n那些年 我们一起走过的路\\n那些年 我们一起做过的梦\\n如今散落在天涯\\n只剩回忆陪伴着我\\n\\n[Verse 3]\\n听说你已经结婚了\\n过着幸福的生活\\n而我还在漂泊\\n寻找属于我的角落\\n\\n[Chorus]\\n那些年 我们一起走过的路\\n那些年 我们一起做过的梦\\n如今散落在天涯\\n只剩回忆陪伴着我\\n\\n[Outro]\\n青春不散场\\n我们不说再见\",\n    \"bpm\": 118,\n    \"duration\": 235,\n    \"keyscale\": \"G major\",\n    \"language\": \"zh\",\n    \"timesignature\": \"4\"\n}"
  },
  {
    "path": "examples/text2music/example_105.json",
    "content": "{\n    \"think\": true,\n    \"caption\": \"A smooth Chinese jazz vocal track with sultry female vocals, walking bass, brushed drums, and mellow piano chords. The arrangement features sophisticated harmonies and a late-night lounge atmosphere.\",\n    \"lyrics\": \"[Intro]\\n\\n[Verse 1]\\n昏暗的酒吧里\\n萨克斯在低语\\n我点了一杯红酒\\n等一个不会来的人\\n\\n[Verse 2]\\n烟雾缭绕中\\n我看到了你的影子\\n是幻觉还是真实\\n我已经分不清\\n\\n[Chorus]\\n爱情就像一首爵士\\n即兴而来 随性而去\\n没有固定的旋律\\n只有此刻的心情\\n\\n[Verse 3]\\n调酒师问我\\n为什么总是一个人\\n我笑着说\\n习惯了孤独的味道\\n\\n[Chorus]\\n爱情就像一首爵士\\n即兴而来 随性而去\\n没有固定的旋律\\n只有此刻的心情\\n\\n[Outro]\\n\\n今夜 让音乐陪伴我\",\n    \"bpm\": 95,\n    \"duration\": 218,\n    \"keyscale\": \"Eb major\",\n    \"language\": \"zh\",\n    \"timesignature\": \"4\"\n}"
  },
  {
    "path": "examples/text2music/example_106.json",
    "content": "{\n    \"think\": true,\n    \"caption\": \"An anime-style opening theme with energetic female vocals, fast-paced rock instrumentation, and dramatic orchestral hits. The production combines J-rock influences with epic symphonic elements.\",\n    \"lyrics\": \"[Intro]\\n\\n[Verse 1]\\n命运的齿轮开始转动\\n黑暗中闪烁着希望的光\\n我握紧拳头向前冲\\n绝不会放弃我的梦想\\n\\n[Pre-Chorus]\\n就算前方是万丈深渊\\n我也要展翅飞翔\\n\\n[Chorus]\\n燃烧吧 我的灵魂\\n冲破一切阻挡\\n奇迹就在前方等待\\n只要相信就能到达\\n无限的可能 无限的力量\\n我们一起创造明天\\n\\n[Verse 2]\\n伙伴们并肩作战\\n友情是最强的武器\\n不管敌人有多强大\\n我们的羁绊永不断裂\\n\\n[Chorus]\\n燃烧吧 我的灵魂\\n冲破一切阻挡\\n奇迹就在前方等待\\n只要相信就能到达\\n\\n[Outro]\\n向着光明 勇敢前进\\n这就是我们的故事\",\n    \"bpm\": 168,\n    \"duration\": 185,\n    \"keyscale\": \"B minor\",\n    \"language\": \"zh\",\n    \"timesignature\": \"4\"\n}"
  },
  {
    "path": "examples/text2music/example_107.json",
    "content": "{\n    \"think\": true,\n    \"caption\": \"A soulful Chinese gospel-influenced pop song with powerful female vocals, choir harmonies, and uplifting piano. The arrangement builds from a gentle start to a triumphant climax with full band.\",\n    \"lyrics\": \"[Intro]\\n\\n[Verse 1]\\n曾经我迷失在黑暗中\\n找不到前进的方向\\n每一天都像在挣扎\\n看不到一丝希望\\n\\n[Verse 2]\\n直到那一天\\n有个声音对我说\\n不要害怕 不要放弃\\n你比想象中更强大\\n\\n[Chorus]\\n我相信 明天会更好\\n阳光总在风雨后\\n我相信 爱能创造奇迹\\n只要心中有光\\n就不会迷失方向\\n\\n[Verse 3]\\n现在我站在这里\\n感谢所有的经历\\n那些伤痛让我成长\\n那些泪水让我坚强\\n\\n[Chorus]\\n我相信 明天会更好\\n阳光总在风雨后\\n我相信 爱能创造奇迹\\n\\n[Outro]\\n\\n我们都是自己的英雄\\n永远不要放弃希望\",\n    \"bpm\": 78,\n    \"duration\": 218,\n    \"keyscale\": \"Ab major\",\n    \"language\": \"zh\",\n    \"timesignature\": \"4\"\n}"
  },
  {
    "path": "examples/text2music/example_108.json",
    "content": "{\n    \"think\": true,\n    \"caption\": \"A melancholic Chinese post-rock instrumental with ambient textures, delayed guitars, and gradual dynamic builds. The production features ethereal soundscapes with sparse vocals appearing only in the climax.\",\n    \"lyrics\": \"[Intro]\\n\\n[Verse 1]\\n\\n[Build]\\n\\n[Verse 2]\\n城市的尽头\\n有一片海\\n我站在那里\\n听风的声音\\n\\n[Climax]\\n所有的故事\\n都随风而去\\n所有的眼泪\\n都化作星辰\\n\\n[Verse 3]\\n\\n[Outro]\\n再见了\\n我的过去\\n你好啊\\n我的未来\",\n    \"bpm\": 65,\n    \"duration\": 236,\n    \"keyscale\": \"F# minor\",\n    \"language\": \"zh\",\n    \"timesignature\": \"4\"\n}"
  },
  {
    "path": "examples/text2music/example_109.json",
    "content": "{\n    \"think\": true,\n    \"caption\": \"A Chinese electronic dance music track with pulsing synths, euphoric builds, and powerful female vocals. The production features sidechained bass, soaring leads, and festival-ready drops.\",\n    \"lyrics\": \"[Intro]\\n\\n[Build]\\n闭上眼睛\\n感受节奏\\n让音乐带你飞\\n\\n[Drop]\\n\\n[Verse 1]\\n今夜我们不回家\\n让灵魂在音乐中燃烧\\n忘掉所有的烦恼\\n只剩下此刻的心跳\\n\\n[Build]\\n举起你的双手\\n跟我一起\\n三 二 一\\n\\n[Drop/Chorus]\\n飞翔 在星空下\\n自由 没有牵挂\\n这一刻 我们都是光\\n照亮整个夜晚\\n\\n[Breakdown]\\n\\n你感受到了吗\\n这就是音乐的力量\\n\\n[Final Drop]\\n飞翔 在星空下\\n自由 没有牵挂\\n永远不要停下\\n\\n[Outro]\",\n    \"bpm\": 138,\n    \"duration\": 210,\n    \"keyscale\": \"F minor\",\n    \"language\": \"zh\",\n    \"timesignature\": \"4\"\n}"
  },
  {
    "path": "examples/text2music/example_11.json",
    "content": "{\n    \"think\": true,\n    \"caption\": \"An explosive, high-energy K-pop and EDM track driven by a relentless four-on-the-floor beat and a pulsing synth bassline. The arrangement opens with a bright piano melody and shimmering arpeggiated synths before slamming into the main groove. A powerful, clear male lead vocal delivers an anthemic melody, punctuated by energetic ad-libs and hype-man shouts. The production is dense with layered synthesizers, including soaring leads, atmospheric pads, and dynamic FX like risers and sweeps that build tension into the explosive choruses. A mid-song instrumental break features a melodic synth lead and vocal chops, leading into a final, climactic chorus and an abrupt ending with a tape-stop sound effect.\",\n    \"lyrics\": \"[Intro]\\n[Synth arpeggio and pads]\\n\\n[Verse  1]\\n[ko] hwangholhan i jilseo-e neon ppajyeo\\n\\n[en]\\n\\n[ko] lideum wi-e sinhoneul jilleo\\n\\n[en]\\n\\n[ko] eodum sog-e bich-eul kkeul-eo\\n[ko] modeun geos-i bultago\\n\\n[Pre-Chorus]\\n[ko] bich-i nal mag-eulyeo\\n[ko] moduga geudaelo bichna\\n[ko] geo-ul sog-e bichwojwo\\n[ko] naneun jasin-ui jibjunghae\\n\\n[Chorus]\\n[ko] oelo-un i jilseo gip-eojyeo\\n\\n[en]\\n\\n[ko] lideum wi-e him-eul jwi-yeo\\n\\n[en]\\n\\n[ko] saelo-un sidaeleul yeol-eo\\n\\n[en]\\n\\n[ko] gaseumsog-e bulkkoch-i pi-eo\\n\\n[Verse  2]\\n[ko] geodaehan mudae sog-eseo\\n[ko] nan tae-eonal geo-ya\\n[ko] modeun geos-i choego-ui jilseo\\n[ko] uli hamkke chumchwo\\n\\n[Bridge]\\n[ko] bichgwa eodum-i salajigo\\n[ko] ulin seololeul bichwo\\n[ko] eunmilhan i sungan sog-eseo\\n[ko] ulin hamkke mandeul-eoga\\n\\n[Chorus]\\n[ko] oelo-un i jilseo gip-eojyeo\\n\\n[en]\\n\\n[ko] lideum wi-e him-eul jwi-yeo\\n\\n[en]\\n\\n[ko] saelo-un sidaeleul yeol-eo\\n\\n[en]\\n\\n[ko] gaseumsog-e bulkkoch-i pi-eo\\n\\n[Instrumental Break]\\n[Synth lead melody with vocal chops]\\n\\n[Outro]\\n[Synth arpeggio fades out]\\n[abrupt silence]\",\n    \"bpm\": 40,\n    \"duration\": 210,\n    \"keyscale\": \"E♭ minor\",\n    \"language\": \"ko\",\n    \"timesignature\": \"4\"\n}"
  },
  {
    "path": "examples/text2music/example_110.json",
    "content": "{\n    \"think\": true,\n    \"caption\": \"A traditional Chinese opera fusion track blending Peking opera vocals (戏腔) with modern pop production. Features dramatic vocal techniques, traditional percussion, and contemporary electronic elements.\",\n    \"lyrics\": \"[Intro]\\n\\n[Verse 1]\\n长亭送别泪两行\\n十里红妆为谁妆\\n戏台上演悲欢离合\\n戏台下看人生无常\\n\\n[Verse 2]\\n油彩画不出真心\\n戏服藏不住伤痕\\n台上一分钟\\n台下十年功\\n\\n[Chorus]\\n人生如戏 戏如人生\\n谁是主角 谁是配角\\n唱念做打 演尽悲欢\\n曲终人散 不过一场梦\\n\\n[Bridge]\\n看那水袖翻飞\\n听那锣鼓声声\\n千年的故事\\n今夜再重演\\n\\n[Chorus]\\n人生如戏 戏如人生\\n谁是主角 谁是配角\\n\\n[Outro]\\n好一个 人生如梦\\n梦醒时分 曲终人散\",\n    \"bpm\": 88,\n    \"duration\": 229,\n    \"keyscale\": \"D minor\",\n    \"language\": \"zh\",\n    \"timesignature\": \"4\"\n}"
  },
  {
    "path": "examples/text2music/example_111.json",
    "content": "{\n    \"think\": true,\n    \"caption\": \"A heartfelt Chinese graduation song with acoustic guitar, gentle strings, and emotional mixed choir. The arrangement captures bittersweet feelings of farewell and hope for the future.\",\n    \"lyrics\": \"[Intro]\\n\\n[Verse 1]\\n栀子花开的季节\\n我们穿上学士服\\n在校门口合影留念\\n笑容里藏着不舍\\n\\n[Verse 2]\\n四年时光转眼过\\n从陌生到熟悉\\n图书馆里的深夜\\n食堂门口的拥挤\\n\\n[Chorus]\\n再见了 我的大学\\n再见了 我的青春\\n带着梦想去远方\\n我们后会有期\\n不管走到哪里\\n都不要忘记彼此\\n\\n[Verse 3]\\n老师说的那些话\\n现在终于懂了\\n原来成长的代价\\n就是学会告别\\n\\n[Chorus]\\n再见了 我的大学\\n再见了 我的青春\\n带着梦想去远方\\n我们后会有期\\n\\n[Outro]\\n\\n愿你前程似锦\\n愿我们都能成为\\n更好的自己\",\n    \"bpm\": 82,\n    \"duration\": 227,\n    \"keyscale\": \"G major\",\n    \"language\": \"zh\",\n    \"timesignature\": \"4\"\n}"
  },
  {
    "path": "examples/text2music/example_112.json",
    "content": "{\n    \"think\": true,\n    \"caption\": \"A Chinese reggae-influenced pop song with laid-back grooves, offbeat guitar skanks, and relaxed male vocals. The production features warm bass, tropical percussion, and a carefree summer vibe.\",\n    \"lyrics\": \"[Intro]\\n\\n[Verse 1]\\n阳光洒在沙滩上\\n海风轻轻吹过脸庞\\n今天什么都不想\\n只想躺在这里发呆\\n\\n[Verse 2]\\n手机关机放一边\\n工作明天再说吧\\n生活不只是忙碌\\n偶尔也要放慢脚步\\n\\n[Chorus]\\n慢慢来 不着急\\n人生就像一场旅行\\n慢慢来 别担心\\n快乐其实很简单\\n\\n[Verse 3]\\n看海鸥在天空飞\\n听浪花拍打礁石\\n这一刻很美好\\n我想永远记住\\n\\n[Chorus]\\n慢慢来 不着急\\n人生就像一场旅行\\n慢慢来 别担心\\n快乐其实很简单\\n\\n[Outro]\\n就这样 慢慢来\\n享受每一天\",\n    \"bpm\": 92,\n    \"duration\": 215,\n    \"keyscale\": \"A major\",\n    \"language\": \"zh\",\n    \"timesignature\": \"4\"\n}"
  },
  {
    "path": "examples/text2music/example_113.json",
    "content": "{\n    \"think\": true,\n    \"caption\": \"A powerful Chinese metal ballad with soaring male vocals, heavy guitar riffs, and emotional piano passages. The song transitions between soft verses and explosive choruses with double bass drumming.\",\n    \"lyrics\": \"[Intro]\\n\\n[Verse 1]\\n站在悬崖的边缘\\n回望走过的路\\n多少次跌倒又爬起\\n伤疤是我的勋章\\n\\n[Verse 2]\\n他们说我疯了\\n追逐不可能的梦\\n但我知道\\n只有疯子才能改变世界\\n\\n[Chorus]\\n\\n我不会倒下 永远不会\\n就算全世界与我为敌\\n我不会放弃 永远不会\\n直到最后一刻\\n我依然站立\\n\\n[Verse 3]\\n\\n感谢那些伤害我的人\\n让我变得更强大\\n感谢那些离开的人\\n让我学会独立\\n\\n[Chorus]\\n我不会倒下 永远不会\\n就算全世界与我为敌\\n\\n[Outro]\\n\\n这就是我的信仰\",\n    \"bpm\": 75,\n    \"duration\": 220,\n    \"keyscale\": \"C minor\",\n    \"language\": \"zh\",\n    \"timesignature\": \"4\"\n}"
  },
  {
    "path": "examples/text2music/example_114.json",
    "content": "{\n    \"think\": true,\n    \"caption\": \"A cute Chinese idol pop song with bright female vocals, bubbly synths, and playful melodies. The production features kawaii-style sound effects, cheerful chord progressions, and an addictive hook.\",\n    \"lyrics\": \"[Intro]\\n一二三 开始啦\\n\\n[Verse 1]\\n今天的心情超级好\\n像草莓蛋糕一样甜\\n蹦蹦跳跳去上学\\n遇见你就更开心\\n\\n[Pre-Chorus]\\n脸红红 心跳加速\\n是不是生病了呢\\n\\n[Chorus]\\n喜欢你 喜欢你\\n每天都想见到你\\n喜欢你 喜欢你\\n这种感觉好奇妙\\nDoki doki 心在跳\\n是恋爱的味道\\n\\n[Verse 2]\\n偷偷看你的背影\\n假装在系鞋带\\n其实是想多看你一眼\\n你发现了吗\\n\\n[Chorus]\\n喜欢你 喜欢你\\n每天都想见到你\\n喜欢你 喜欢你\\n这种感觉好奇妙\\n\\n[Outro]\\n如果你也喜欢我\\n那就太好了\\n嘻嘻\",\n    \"bpm\": 135,\n    \"duration\": 188,\n    \"keyscale\": \"E major\",\n    \"language\": \"zh\",\n    \"timesignature\": \"4\"\n}\n"
  },
  {
    "path": "examples/text2music/example_115.json",
    "content": "{\n    \"think\": true,\n    \"caption\": \"A Chinese country-folk crossover with warm acoustic guitars, fiddle, and sincere male vocals. The production has an earthy, organic feel celebrating rural life and simple pleasures.\",\n    \"lyrics\": \"[Intro]\\n\\n[Verse 1]\\n老家门前那条河\\n还在静静地流\\n河边的柳树长高了\\n我却很久没回去\\n\\n[Verse 2]\\n爷爷的烟斗还在吗\\n奶奶的手擀面\\n那些简单的幸福\\n现在想起来好甜\\n\\n[Chorus]\\n我的家乡 在远方\\n那里有我的爹娘\\n我的家乡 在心上\\n无论走多远都不会忘\\n\\n[Verse 3]\\n城里的楼越来越高\\n却装不下乡愁\\n霓虹灯再亮\\n也比不上家里的灯火\\n\\n[Chorus]\\n我的家乡 在远方\\n那里有我的爹娘\\n\\n[Outro]\\n等我攒够了钱\\n就回家盖房子\\n陪着爸妈慢慢变老\",\n    \"bpm\": 98,\n    \"duration\": 216,\n    \"keyscale\": \"D major\",\n    \"language\": \"zh\",\n    \"timesignature\": \"4\"\n}"
  },
  {
    "path": "examples/text2music/example_116.json",
    "content": "{\n    \"think\": true,\n    \"caption\": \"A Chinese synthwave track with retro 80s synths, pulsing arpeggios, and dreamy female vocals. The production features gated reverb drums, analog warmth, and nostalgic neon-lit atmosphere.\",\n    \"lyrics\": \"[Intro]\\n\\n[Verse 1]\\n霓虹灯闪烁的街道\\n像八十年代的电影\\n我穿越时空来到这里\\n寻找失落的记忆\\n\\n[Pre-Chorus]\\n收音机里放着老歌\\n熟悉的旋律\\n\\n[Chorus]\\n在午夜的城市\\n我们一起跳舞\\n让时间停止\\n永远停在这一刻\\n复古的梦 霓虹的光\\n带我回到过去\\n\\n[Verse 2]\\n录像带里的画面\\n模糊却很温暖\\n那个年代的爱情\\n简单却很真实\\n\\n[Chorus]\\n在午夜的城市\\n我们一起跳舞\\n让时间停止\\n永远停在这一刻\\n\\n[Outro]\\n\\n再见 八十年代\",\n    \"bpm\": 118,\n    \"duration\": 225,\n    \"keyscale\": \"F# minor\",\n    \"language\": \"zh\",\n    \"timesignature\": \"4\"\n}"
  },
  {
    "path": "examples/text2music/example_117.json",
    "content": "{\n    \"think\": true,\n    \"caption\": \"A Chinese waltz ballad with elegant piano, sweeping strings, and tender female vocals. The 3/4 time signature creates a romantic, dance-like quality perfect for wedding ceremonies.\",\n    \"lyrics\": \"[Intro]\\n\\n[Verse 1]\\n穿上白色的婚纱\\n我走向你身边\\n从今以后的日子\\n有你陪伴\\n\\n[Verse 2]\\n还记得第一次见面\\n你笨拙的样子\\n没想到那个人\\n会成为我的新郎\\n\\n[Chorus]\\n让我们跳一支舞\\n在月光下旋转\\n你是我的王子\\n我是你的公主\\n从此幸福快乐\\n直到永远\\n\\n[Verse 3]\\n谢谢你选择了我\\n给我一个家\\n我会用一生\\n来爱你\\n\\n[Chorus]\\n让我们跳一支舞\\n在月光下旋转\\n你是我的王子\\n我是你的公主\\n\\n[Outro]\\n我愿意\\n和你走过一生\",\n    \"bpm\": 88,\n    \"duration\": 211,\n    \"keyscale\": \"Eb major\",\n    \"language\": \"zh\",\n    \"timesignature\": \"3\"\n}"
  },
  {
    "path": "examples/text2music/example_118.json",
    "content": "{\n    \"think\": true,\n    \"caption\": \"A Chinese trap song with aggressive male rap, heavy 808s, and dark atmospheric synths. The production features hard-hitting drums, vocal chops, and an intense energy throughout.\",\n    \"lyrics\": \"[Intro]\\n\\nYeah yeah\\n\\n[Verse 1]\\n从底层爬上来\\n没人能阻挡我的脚步\\n他们说我不行\\n现在看看谁在笑\\n钞票数不完\\n但我不会忘记初心\\n\\n[Hook]\\n数钱数到手抽筋\\n成功没有捷径\\n只有拼命\\n\\n[Verse 2]\\n兄弟们跟我一起\\n从无到有的故事\\n那些看不起我的人\\n现在排队想认识\\n但我记得清清楚楚\\n谁真谁假\\n\\n[Hook]\\n数钱数到手抽筋\\n成功没有捷径\\n只有拼命\\n\\n[Outro]\\n这就是生活\\n适者生存\",\n    \"bpm\": 145,\n    \"duration\": 178,\n    \"keyscale\": \"G minor\",\n    \"language\": \"zh\",\n    \"timesignature\": \"4\"\n}"
  },
  {
    "path": "examples/text2music/example_119.json",
    "content": "{\n    \"think\": true,\n    \"caption\": \"A Chinese children's song with cheerful melody, playful instrumentation, and innocent vocals. Features xylophone, recorder, and bouncy rhythms perfect for kindergarten sing-alongs.\",\n    \"lyrics\": \"[Intro]\\n\\n[Verse 1]\\n小兔子乖乖\\n把门开开\\n妈妈回来了\\n快把门打开\\n\\n[Verse 2]\\n太阳公公起床了\\n小鸟在唱歌\\n我背上小书包\\n开开心心上学校\\n\\n[Chorus]\\n啦啦啦 啦啦啦\\n我是快乐的小朋友\\n啦啦啦 啦啦啦\\n每天都有新发现\\n\\n[Verse 3]\\n老师教我们画画\\n画一个大太阳\\n红红的苹果\\n绿绿的小草\\n\\n[Chorus]\\n啦啦啦 啦啦啦\\n我是快乐的小朋友\\n啦啦啦 啦啦啦\\n每天都有新发现\\n\\n[Outro]\\n放学啦 回家啦\\n明天见\",\n    \"bpm\": 110,\n    \"duration\": 145,\n    \"keyscale\": \"C major\",\n    \"language\": \"zh\",\n    \"timesignature\": \"4\"\n}"
  },
  {
    "path": "examples/text2music/example_12.json",
    "content": "{\n    \"think\": true,\n    \"caption\": \"An energetic and anthemic pop-rock track driven by a clean, funky electric guitar riff and a punchy, tight drum and bass groove. The song opens with a catchy guitar hook before settling into a verse led by a clear, powerful male vocal. The arrangement builds dynamically into a soaring, uplifting chorus with layered vocals and driving instrumentation. A melodic guitar solo section features expressive bends and fills. The track includes a brief, atmospheric bridge with wordless vocalizations before launching into a final, powerful chorus and concluding with the initial guitar riff.\",\n    \"lyrics\": \"[Intro - Guitar Riff]\\n\\n[Verse 1]\\n翻过山又像迷雾\\n心也照亮每一步\\n大地在脚下伸出手\\n追逐梦想不要停留\\n\\n[Pre-Chorus]\\n星光摇曳在夜幕\\n未来就在眼前呼\\n跳动脉搏像闪电火\\n展开翅膀冲破束缚\\n\\n[Chorus]\\n在梦的边缘跳跃光辉\\n无数的光点汇聚成美\\n燃烧的希望把世界敲碎\\n一切再次新的节奏到位\\n\\n[Guitar Interlude]\\n\\n[Verse 2]\\n音符交错夜色深处\\n心的律动难以抗拒\\n脚步合拍如同律步\\n舞出一曲全新的篇幅\\n\\n[Pre-Chorus]\\n银河展开狂奔翅膀\\n你和我合奏不息光\\n跨越万千热浪激荡\\n前行不停冲破过往\\n\\n[Chorus]\\n在梦的边缘跳跃光辉\\n无数的光点汇聚成美\\n燃烧的希望把世界敲碎\\n一切再次新的节奏到位\\n\\n[Guitar Solo]\\n\\n[Bridge - Vocal Harmonies]\\n\\n[Chorus]\\n在梦的边缘跳跃光辉\\n无数的光点汇聚成美\\n燃烧的希望把世界敲碎\\n一切再次新的节奏到位\\n\\n[Outro - Guitar Riff]\",\n    \"bpm\": 100,\n    \"duration\": 190,\n    \"keyscale\": \"C# minor\",\n    \"language\": \"zh\",\n    \"timesignature\": \"4\"\n}"
  },
  {
    "path": "examples/text2music/example_120.json",
    "content": "{\n    \"think\": true,\n    \"caption\": \"A Chinese bossa nova track with gentle nylon guitar, soft brushed percussion, and breathy female vocals. The production creates a cozy cafe atmosphere with warm, intimate tones.\",\n    \"lyrics\": \"[Intro]\\n\\n[Verse 1]\\n午后的咖啡馆\\n阳光透过玻璃窗\\n我翻开一本书\\n享受这安静的时光\\n\\n[Verse 2]\\n咖啡的香气\\n弥漫在空气中\\n窗外的行人匆匆\\n我却不想走\\n\\n[Chorus]\\n就这样 慢慢地\\n让时间静止\\n就这样 轻轻地\\n听风的声音\\n生活可以很简单\\n幸福就在身边\\n\\n[Verse 3]\\n服务员微笑着\\n问我要不要续杯\\n我点点头说好\\n再待一会儿\\n\\n[Chorus]\\n就这样 慢慢地\\n让时间静止\\n\\n[Outro]\\n\\n美好的下午\",\n    \"bpm\": 105,\n    \"duration\": 198,\n    \"keyscale\": \"F major\",\n    \"language\": \"zh\",\n    \"timesignature\": \"4\"\n}"
  },
  {
    "path": "examples/text2music/example_121.json",
    "content": "{\n    \"think\": true,\n    \"caption\": \"A Chinese punk rock anthem with raw energy, distorted guitars, and rebellious male vocals. Fast tempo with aggressive drums and anti-establishment lyrics.\",\n    \"lyrics\": \"[Intro]\\n\\n一二三四!\\n\\n[Verse 1]\\n每天重复一样的生活\\n上班下班像个机器\\n他们说这就是现实\\n我说去他的现实\\n\\n[Chorus]\\n我不要做听话的绵羊\\n我不要过无聊的人生\\n打破规则 冲出牢笼\\n做自己的主人\\n\\n[Verse 2]\\n西装领带不适合我\\n朝九晚五不是我的命\\n给我一把吉他\\n我就能改变世界\\n\\n[Chorus]\\n我不要做听话的绵羊\\n我不要过无聊的人生\\n打破规则 冲出牢笼\\n做自己的主人\\n\\n[Outro]\\n这就是朋克\\n永不妥协\",\n    \"bpm\": 175,\n    \"duration\": 165,\n    \"keyscale\": \"E minor\",\n    \"language\": \"zh\",\n    \"timesignature\": \"4\"\n}"
  },
  {
    "path": "examples/text2music/example_122.json",
    "content": "{\n    \"think\": true,\n    \"caption\": \"A Chinese new age meditation track with ambient pads, Tibetan singing bowls, and gentle nature sounds. Ethereal female humming creates a peaceful, spiritual atmosphere.\",\n    \"lyrics\": \"[Intro]\\n\\n[Verse 1]\\n闭上眼睛\\n深呼吸\\n让心静下来\\n感受此刻的宁静\\n\\n[Meditation]\\n\\nOm...\\n\\n[Verse 2]\\n放下所有的烦恼\\n放下所有的执念\\n你只是一片云\\n飘在蓝天上\\n\\n[Meditation]\\n\\n心如止水\\n万物归一\\n\\n[Verse 3]\\n听风的声音\\n听水的声音\\n听自己心跳的声音\\n一切都很美好\\n\\n[Outro]\\n\\n平静 安宁\\n回归本心\",\n    \"bpm\": 60,\n    \"duration\": 233,\n    \"keyscale\": \"D major\",\n    \"language\": \"zh\",\n    \"timesignature\": \"4\"\n}"
  },
  {
    "path": "examples/text2music/example_123.json",
    "content": "{\n    \"think\": true,\n    \"caption\": \"A Chinese soul ballad with powerful female vocals, gospel choir harmonies, and rich organ textures. The arrangement builds emotionally with brass accents and heartfelt delivery.\",\n    \"lyrics\": \"[Intro]\\n\\n[Verse 1]\\n多少个夜晚\\n我独自流泪\\n以为这世界\\n没有人懂我\\n\\n[Verse 2]\\n直到遇见你\\n你告诉我\\n每个人都值得被爱\\n包括我自己\\n\\n[Chorus]\\n我终于学会了\\n爱自己\\n不再为别人的眼光\\n委屈自己\\n我终于明白了\\n我很美\\n不完美才是最真实的美\\n\\n[Bridge]\\n\\n你是独一无二的\\n不要忘记\\n\\n[Chorus]\\n我终于学会了\\n爱自己\\n\\n[Outro]\\n谢谢你\\n让我找到自己\",\n    \"bpm\": 68,\n    \"duration\": 208,\n    \"keyscale\": \"Bb major\",\n    \"language\": \"zh\",\n    \"timesignature\": \"4\"\n}"
  },
  {
    "path": "examples/text2music/example_124.json",
    "content": "{\n    \"think\": true,\n    \"caption\": \"A Chinese military march style patriotic song with brass band, snare drums, and powerful mixed choir. The arrangement is grand and ceremonial with strong rhythmic drive.\",\n    \"lyrics\": \"[Intro]\\n\\n[Verse 1]\\n五星红旗迎风飘扬\\n胜利歌声多么响亮\\n歌唱我们亲爱的祖国\\n从今走向繁荣富强\\n\\n[Verse 2]\\n越过高山 越过平原\\n跨过奔腾的黄河长江\\n宽广美丽的土地\\n是我们亲爱的家乡\\n\\n[Chorus]\\n前进 前进\\n向着胜利的方向\\n前进 前进\\n我们的队伍向太阳\\n\\n[Verse 3]\\n英雄的人民站起来了\\n我们团结友爱坚强如钢\\n\\n[Chorus]\\n前进 前进\\n向着胜利的方向\\n\\n[Outro]\\n\\n祖国万岁\",\n    \"bpm\": 120,\n    \"duration\": 195,\n    \"keyscale\": \"G major\",\n    \"language\": \"zh\",\n    \"timesignature\": \"2\"\n}"
  },
  {
    "path": "examples/text2music/example_125.json",
    "content": "{\n    \"think\": true,\n    \"caption\": \"A Chinese lo-fi hip-hop track with mellow beats, vinyl crackle, and soft male vocals. The production features jazzy samples, warm bass, and a nostalgic late-night study vibe.\",\n    \"lyrics\": \"[Intro]\\n\\n[Verse 1]\\n深夜的台灯下\\n我写着未完成的作业\\n咖啡已经凉了\\n但我不想睡\\n\\n[Verse 2]\\n窗外的月亮很圆\\n像你寄来的那张明信片\\n上面写着想念\\n我看了一遍又一遍\\n\\n[Chorus]\\n在这个安静的夜晚\\n只有音乐陪伴\\n思绪飘向远方\\n飘向有你的地方\\n\\n[Verse 3]\\n书架上的照片\\n记录着我们的从前\\n那时候的笑容\\n现在看来好遥远\\n\\n[Chorus]\\n在这个安静的夜晚\\n只有音乐陪伴\\n\\n[Outro]\\n\\n晚安 我的朋友\",\n    \"bpm\": 78,\n    \"duration\": 215,\n    \"keyscale\": \"Ab major\",\n    \"language\": \"zh\",\n    \"timesignature\": \"4\"\n}"
  },
  {
    "path": "examples/text2music/example_126.json",
    "content": "{\n    \"think\": true,\n    \"caption\": \"A Chinese progressive rock epic with complex time signatures, virtuosic guitar work, and dramatic male vocals. The arrangement features multiple movements and dynamic shifts.\",\n    \"lyrics\": \"[Intro]\\n\\n[Verse 1]\\n时间的河流\\n带走了多少故事\\n我站在岸边\\n看着浪花翻涌\\n\\n[Verse 2]\\n宇宙的尽头\\n是否有另一个我\\n在平行世界里\\n做着不同的选择\\n\\n[Chorus]\\n穿越时空的迷雾\\n寻找生命的答案\\n我们都是旅人\\n在无尽的路上\\n\\n[Bridge]\\n\\n[Verse 3]\\n星辰大海\\n是我的归宿\\n即使孤独\\n也要继续前行\\n\\n[Chorus]\\n穿越时空的迷雾\\n寻找生命的答案\\n\\n[Outro]\\n\\n永恒的追寻\\n永不停息\",\n    \"bpm\": 132,\n    \"duration\": 215,\n    \"keyscale\": \"B minor\",\n    \"language\": \"zh\",\n    \"timesignature\": \"4\"\n}"
  },
  {
    "path": "examples/text2music/example_127.json",
    "content": "{\n    \"think\": true,\n    \"caption\": \"A Chinese acoustic love song with fingerstyle guitar, soft harmonica, and tender male vocals. Simple and heartfelt production capturing the innocence of first love.\",\n    \"lyrics\": \"[Intro]\\n\\n[Verse 1]\\n那年夏天的蝉鸣\\n和你的笑声一样动听\\n我们坐在树荫下\\n分享一瓶汽水\\n\\n[Verse 2]\\n你说喜欢看星星\\n我就陪你数到天明\\n那时候不懂爱情\\n只知道想和你在一起\\n\\n[Chorus]\\n简简单单的喜欢\\n不需要太多语言\\n牵着你的手\\n就是最大的幸福\\n\\n[Verse 3]\\n后来我们都长大了\\n各自有了新的生活\\n但每当夏天来临\\n我还是会想起你\\n\\n[Chorus]\\n简简单单的喜欢\\n不需要太多语言\\n\\n[Outro]\\n\\n谢谢你 出现在我的青春里\",\n    \"bpm\": 85,\n    \"duration\": 228,\n    \"keyscale\": \"C major\",\n    \"language\": \"zh\",\n    \"timesignature\": \"4\"\n}"
  },
  {
    "path": "examples/text2music/example_128.json",
    "content": "{\n    \"think\": true,\n    \"caption\": \"A Chinese funk track with groovy bass lines, wah-wah guitar, and energetic male vocals. The production features tight horn stabs, syncopated rhythms, and a danceable party atmosphere.\",\n    \"lyrics\": \"[Intro]\\n\\nUh! 来吧!\\n\\n[Verse 1]\\n周五的晚上\\n工作终于结束\\n换上最帅的衣服\\n今晚我要放松\\n\\n[Pre-Chorus]\\n音乐响起来\\n身体动起来\\n\\n[Chorus]\\n跟着节奏摇摆\\n让身体自由自在\\n不管明天怎样\\n今晚尽情狂欢\\nFunk it up funk it up\\n一起来\\n\\n[Verse 2]\\n舞池里的灯光\\n照亮每个人的脸\\n陌生人变朋友\\n音乐是最好的语言\\n\\n[Chorus]\\n跟着节奏摇摆\\n让身体自由自在\\n\\n[Outro]\\n\\n这就是放克的魅力\",\n    \"bpm\": 108,\n    \"duration\": 205,\n    \"keyscale\": \"E minor\",\n    \"language\": \"zh\",\n    \"timesignature\": \"4\"\n}"
  },
  {
    "path": "examples/text2music/example_129.json",
    "content": "{\n    \"think\": true,\n    \"caption\": \"A Chinese blues rock track with soulful male vocals, expressive guitar bends, and Hammond organ. The production captures raw emotion with gritty tones and heartfelt delivery.\",\n    \"lyrics\": \"[Intro]\\n\\n[Verse 1]\\n又是一个下雨天\\n我坐在窗前发呆\\n烟灰缸里的烟头\\n数不清有多少\\n\\n[Verse 2]\\n她走的那天也下雨\\n我没有挽留\\n现在想起来\\n真是个傻瓜\\n\\n[Chorus]\\n蓝调的夜晚\\n只有吉他懂我\\n弹一首老歌\\n献给失去的爱\\n\\n[Verse 3]\\n酒瓶空了又满\\n心却越来越空\\n有些人错过了\\n就是一辈子\\n\\n[Chorus]\\n蓝调的夜晚\\n只有吉他懂我\\n\\n[Outro]\\n\\n这就是生活\\n苦中带甜\",\n    \"bpm\": 72,\n    \"duration\": 226,\n    \"keyscale\": \"A minor\",\n    \"language\": \"zh\",\n    \"timesignature\": \"4\"\n}"
  },
  {
    "path": "examples/text2music/example_13.json",
    "content": "{\n    \"think\": true,\n    \"caption\": \"A classic boom-bap hip-hop track built on a nostalgic foundation. A steady drum machine groove with a crisp snare drives the song forward beneath atmospheric synth pads that create an introspective mood. The male rapper delivers confident verses with a clear flow, while the chorus shifts to melodic, layered vocal harmonies soaked in reverb for an anthemic feel. The arrangement is punctuated by spoken ad-libs treated with echo effects and concludes with an extended outro featuring heavily filtered vocals over a stripped-back beat before fading into ambient textures.\",\n    \"lyrics\": \"[Intro]\\nYo\\nIt's Laðum\\nYou already know\\nMoney talks\\nThey don't talk back\\n\\n[Verse 1]\\nI stay with the heat, streets raised me\\nNever folded under pressure, now I'm way crazy\\nChains on my neck, still my grind daily\\nBut my soul stay heavy, yeah the grind ain't lazy\\nOld heads stackin', but I flip through the beat\\nStackin' chips on chips, now they movin' in the street\\nBut the streets ain't ready, now my path got heat\\nUsed to dream to win, now I move with the beat\\nCopped a cold brick, got heat in my heart\\nNow my chain swing tight, I been playin' my part\\nMoney ain't a thing, but it takes its part\\nStill I carry my soul like it's built from the start\\n\\n[Chorus]\\nSo tell me, why they hate when you live?\\nGot the heart of a king, but the soul in the bills\\nTell me, who the heck do they feel?\\nWhen the world keep spinnin' but you lost it all still\\n\\nWhy they hate when you live?\\nWith the heart of a king, but the soul in the bills\\nTell me, who the heck do they feel?\\nWhen the world keep spinnin' but you lost it all still\\n\\nWhy they hate when you live?\\nWith the heart of a king, but the soul in the bills\\nTell me, who the heck do they feel?\\nWhen the world keep spinnin' but you lost it all still\\n\\n[Verse 2]\\nThey talk about the grind but I'm broke, I'm grindin'\\nEvery dollar spent, now the people still whinin'\\nBut I keep my head high, never fold, never lyin'\\nAnd my heart's still cold even when the day's lyin'\\nOne road left but I can't ride that chain\\nI'ma keep it movin', yeah they all feel my pain\\nThey say money talks, but I'm answerin' it's still\\nSo I made it in silence, now I'm free from the deal\\n\\n[Chorus]\\nTell me, why they hate when you live?\\nGot the heart of a king, but the soul in the bills\\nTell me, who the heck do they feel?\\nWhen the world keep spinnin' but you lost it all still\\n\\nWhy they hate when you live?\\nWith the heart of a king, but the soul in the bills\\nTell me, who the heck do they feel?\\nWhen the world keep spinnin' but you lost it all still\\n\\nWhy they hate when you live?\\nWith the heart of a king, but the soul in the bills\\nTell me, who the heck do they feel?\\nWhen the world keep spinnin' but you lost it all still\\n\\n[Outro]\\nThey can't cage the vibe, yeah\\nYou gotta stay in\\nIt's money and power, a universe, one rule\\nMoney is the money\\nAnd I'm not at the bottom\\n[Instrumental fades out]\",\n    \"bpm\": 100,\n    \"duration\": 210,\n    \"keyscale\": \"F# major\",\n    \"language\": \"en\",\n    \"timesignature\": \"4\"\n}"
  },
  {
    "path": "examples/text2music/example_130.json",
    "content": "{\n    \"think\": true,\n    \"caption\": \"A Chinese cinematic orchestral piece with sweeping strings, epic brass, and ethereal female vocals. The arrangement builds from intimate beginnings to a grand triumphant finale.\",\n    \"lyrics\": \"[Intro]\\n\\n[Verse 1]\\n黎明前的黑暗\\n最是漫长\\n但我知道\\n太阳终会升起\\n\\n[Verse 2]\\n走过千山万水\\n历经风霜雨雪\\n每一步都算数\\n每一滴汗都值得\\n\\n[Chorus]\\n向着光明前进\\n永不放弃希望\\n就算跌倒一百次\\n也要站起一百零一次\\n这就是生命的意义\\n\\n[Bridge]\\n\\n[Verse 3]\\n当我站在山顶\\n回望来时的路\\n所有的苦难\\n都变成了风景\\n\\n[Chorus]\\n向着光明前进\\n永不放弃希望\\n\\n[Outro]\\n\\n荣耀属于每一个\\n不曾放弃的灵魂\",\n    \"bpm\": 88,\n    \"duration\": 232,\n    \"keyscale\": \"D major\",\n    \"language\": \"zh\",\n    \"timesignature\": \"4\"\n}"
  },
  {
    "path": "examples/text2music/example_131.json",
    "content": "{\n    \"think\": true,\n    \"caption\": \"An energetic J-rock anime opening with powerful electric guitars, driving drums, and passionate male vocals. Features intense guitar riffs, dynamic tempo changes, and an anthemic chorus perfect for battle scenes.\",\n    \"lyrics\": \"[Intro]\\n\\n[Verse 1]\\n燃え上がる魂 止められない\\n運命の扉を今 蹴り開けろ\\n誰にも負けない この意志を胸に\\n立ち向かう勇気が 力になる\\n\\n[Pre-Chorus]\\n迷いなんて捨てて\\n前だけを見つめて\\n\\n[Chorus]\\n走り出せ 限界を超えて\\n叫び続けろ 夢の果てまで\\n何度でも立ち上がれ\\nこの手で掴み取れ 明日を\\n\\n[Verse 2]\\n傷ついた過去も 涙の夜も\\n全部が今の俺を作ってきた\\n仲間がいるから 怖くはない\\n一緒に進もう その先へ\\n\\n[Pre-Chorus]\\n諦めるなんて\\n俺らしくないだろ\\n\\n[Chorus]\\n走り出せ 限界を超えて\\n叫び続けろ 夢の果てまで\\n何度でも立ち上がれ\\nこの手で掴み取れ 明日を\\n\\n[Bridge]\\n暗闇の中でも 光は見える\\n信じる心が 道を照らす\\n\\n[Final Chorus]\\n走り出せ 限界を超えて\\n叫び続けろ 夢の果てまで\\n何度でも立ち上がれ\\nこの手で掴み取れ 明日を\\n輝く未来を\\n\\n[Outro]\",\n    \"bpm\": 178,\n    \"duration\": 240,\n    \"keyscale\": \"E minor\",\n    \"language\": \"ja\",\n    \"timesignature\": \"4\"\n}"
  },
  {
    "path": "examples/text2music/example_132.json",
    "content": "{\n    \"think\": true,\n    \"caption\": \"A sweet and dreamy J-pop idol song with sparkling synths, cute vocal harmonies, and an uplifting dance beat. Features bright piano melodies and cheerful female vocals perfect for a summer festival.\",\n    \"lyrics\": \"[Intro]\\nキラキラ輝く夏が来た!\\n\\n[Verse 1]\\n朝の光が窓を叩いて\\n今日も始まる 特別な一日\\nお気に入りの服を選んで\\n鏡の前で くるっと回る\\n\\n[Pre-Chorus]\\nドキドキが止まらない\\n会いたい気持ちが溢れ出す\\n\\n[Chorus]\\nキラキラ 輝いて\\n夢見る少女のままで\\nふわふわ 舞い上がれ\\n君と過ごす この夏を\\n忘れない 絶対に\\n\\n[Verse 2]\\n待ち合わせの場所 走って向かう\\n遅刻しちゃうかも ごめんね\\n君の笑顔が見えた瞬間\\n心臓バクバク 顔が熱い\\n\\n[Pre-Chorus]\\nこの気持ち伝えたい\\nでもちょっと恥ずかしいな\\n\\n[Chorus]\\nキラキラ 輝いて\\n夢見る少女のままで\\nふわふわ 舞い上がれ\\n君と過ごす この夏を\\n忘れない 絶対に\\n\\n[Bridge]\\n花火が夜空に咲いて\\n二人の影が重なる\\n\\n[Outro]\\nキラキラ 輝く夏\\n君とずっと一緒にいたい\",\n    \"bpm\": 128,\n    \"duration\": 210,\n    \"keyscale\": \"G major\",\n    \"language\": \"ja\",\n    \"timesignature\": \"4\"\n}\n"
  },
  {
    "path": "examples/text2music/example_133.json",
    "content": "{\n    \"think\": true,\n    \"caption\": \"A melancholic Japanese ballad with gentle piano, soft strings, and emotional female vocals. The arrangement builds gradually with orchestral elements, conveying deep feelings of farewell and nostalgia.\",\n    \"lyrics\": \"[Intro]\\n\\n[Verse 1]\\n窓辺に揺れる カーテンの影\\n思い出すのは あなたの横顔\\n言えなかった言葉が\\n今も胸の奥で眠ってる\\n\\n[Verse 2]\\n季節は巡り 桜が散って\\nあの日の約束 風に消えた\\n握りしめた手のぬくもりだけ\\n確かにここに 残ってる\\n\\n[Chorus]\\nさよなら 言えないまま\\n時は流れてゆく\\n届かない想いを抱いて\\n私は歩き続ける\\nいつかまた会える日まで\\n\\n[Verse 3]\\n雨の日には あなたを想う\\n傘を差し出してくれた あの優しさ\\n何気ない日々が\\n宝物だったと 今なら分かる\\n\\n[Chorus]\\nさよなら 言えないまま\\n時は流れてゆく\\n届かない想いを抱いて\\n私は歩き続ける\\nいつかまた会える日まで\\n\\n[Bridge]\\n星空の下で 願いを込めて\\nあなたの幸せを 祈ってる\\n\\n[Outro]\\nさよなら 大好きだった\\nありがとう 出会えたこと\",\n    \"bpm\": 68,\n    \"duration\": 229,\n    \"keyscale\": \"D minor\",\n    \"language\": \"ja\",\n    \"timesignature\": \"4\"\n}"
  },
  {
    "path": "examples/text2music/example_134.json",
    "content": "{\n    \"think\": true,\n    \"caption\": \"A groovy city pop track with funky bass lines, smooth saxophone, and nostalgic 80s synthesizers. Features laid-back male vocals with a cool, urban nightlife atmosphere reminiscent of classic Japanese city pop.\",\n    \"lyrics\": \"[Intro]\\n\\n[Verse 1]\\nネオンが照らす 夜の街を\\n一人歩く 金曜の夜\\nポケットには 君の写真\\nまだ忘れられないんだ\\n\\n[Pre-Chorus]\\nあの頃の二人は\\n何も怖くなかった\\n\\n[Chorus]\\nMidnight City 踊り明かそう\\n思い出に浸りながら\\nグラス傾け 乾杯しよう\\n過ぎ去った日々に\\nTonight 君を想う\\n\\n[Verse 2]\\nジュークボックスから流れる\\n懐かしいあのメロディー\\nバーテンダーに話しかけて\\n愚痴をこぼす 夜更け\\n\\n[Chorus]\\nMidnight City 踊り明かそう\\n思い出に浸りながら\\nグラス傾け 乾杯しよう\\n過ぎ去った日々に\\nTonight 君を想う\\n\\n[Bridge]\\nサックスの音色が\\n心に染みる夜さ\\n\\n[Outro]\\nMidnight City\\n夜が明けるまで\",\n    \"bpm\": 108,\n    \"duration\": 232,\n    \"keyscale\": \"F major\",\n    \"language\": \"ja\",\n    \"timesignature\": \"4\"\n}"
  },
  {
    "path": "examples/text2music/example_135.json",
    "content": "{\n    \"think\": true,\n    \"caption\": \"An intense visual kei rock anthem with heavy distorted guitars, dramatic orchestral arrangements, and theatrical male vocals. Features dark gothic atmosphere with powerful emotional crescendos.\",\n    \"lyrics\": \"[Intro]\\n\\n[Verse 1]\\n闇に堕ちた 天使の羽根\\n血に染まった 薔薇の棘\\n誰も知らない 孤独の檻で\\n叫び続ける 救いを求めて\\n\\n[Pre-Chorus]\\n壊れそうな心を\\n抱きしめてくれ\\n\\n[Chorus]\\n永遠の闇の中で\\n光を探し続ける\\n傷だらけの翼で\\nそれでも飛び立つ\\n愛という名の 呪縛から\\n逃れられない 運命\\n\\n[Verse 2]\\n鏡に映る 偽りの顔\\n本当の自分は どこにいる\\n仮面を外せば 見えるのは\\n醜い傷跡 だけなのか\\n\\n[Chorus]\\n永遠の闘の中で\\n光を探し続ける\\n傷だらけの翼で\\nそれでも飛び立つ\\n\\n[Bridge]\\n月が照らす 墓標の前で\\n誓いを立てる 生きると\\n\\n[Final Chorus]\\n永遠の闇を切り裂いて\\n光になってみせる\\n傷だらけの翼で\\n必ず飛び立つ\\n\\n[Outro]\",\n    \"bpm\": 165,\n    \"duration\": 210,\n    \"keyscale\": \"B minor\",\n    \"language\": \"ja\",\n    \"timesignature\": \"4\"\n}"
  },
  {
    "path": "examples/text2music/example_136.json",
    "content": "{\n    \"think\": true,\n    \"caption\": \"A traditional enka ballad with shamisen, shakuhachi flute, and heartfelt mature female vocals. Features classic Japanese pentatonic melodies with emotional vibrato and melancholic themes of lost love.\",\n    \"lyrics\": \"[Intro]\\n\\n[Verse 1]\\n北の港町 雪が降る\\nあなたを待って 幾年月\\n波の音だけが 友達で\\n一人酒場で 杯を傾ける\\n\\n[Verse 2]\\n写真の中の あなたの笑顔\\n色褪せても 忘れない\\n約束したね また会おうと\\n春が来たら 迎えに来ると\\n\\n[Chorus]\\n恋しくて 恋しくて\\n涙が止まらない\\n北風に 吹かれても\\n待ち続ける この場所で\\nあなただけを 信じて\\n\\n[Verse 3]\\n漁火揺れる 夜の海\\n思い出すのは 二人の日々\\n手を繋いで 歩いた道\\n今は一人 影法師\\n\\n[Chorus]\\n恋しくて 恋しくて\\n涙が止まらない\\n北風に 吹かれても\\n待ち続ける この場所で\\n\\n[Outro]\\nいつの日か また会える\\nその日まで 生きてゆく\",\n    \"bpm\": 72,\n    \"duration\": 209,\n    \"keyscale\": \"A minor\",\n    \"language\": \"ja\",\n    \"timesignature\": \"4\"\n}"
  },
  {
    "path": "examples/text2music/example_137.json",
    "content": "{\n    \"think\": true,\n    \"caption\": \"A high-energy anime ending theme with electronic dance beats, catchy synth hooks, and bright female vocals. Features uplifting melodies and an infectious chorus perfect for credits sequences.\",\n    \"lyrics\": \"[Intro]\\n\\n[Verse 1]\\n放課後の教室 夕日が差して\\n今日も一日 頑張ったね\\n明日への期待 胸に秘めて\\n家路を急ぐ 帰り道\\n\\n[Pre-Chorus]\\nいつもの景色が\\n特別に見える\\n\\n[Chorus]\\nShining Days 輝く毎日\\n君がいるから 笑顔になれる\\nどんな時も 一緒にいよう\\n最高の仲間と\\nShining Days\\n\\n[Verse 2]\\n些細なことで 笑い合って\\nくだらない話で 盛り上がる\\nこんな日々が 続けばいいな\\n永遠に終わらない 青春を\\n\\n[Chorus]\\nShining Days 輝く毎日\\n君がいるから 笑顔になれる\\nどんな時も 一緒にいよう\\n最高の仲間と\\n\\n[Outro]\\nShining Days ずっと続く\\nこの瞬間を 忘れない\",\n    \"bpm\": 138,\n    \"duration\": 195,\n    \"keyscale\": \"A major\",\n    \"language\": \"ja\",\n    \"timesignature\": \"4\"\n}"
  },
  {
    "path": "examples/text2music/example_138.json",
    "content": "{\n    \"think\": true,\n    \"caption\": \"A Japanese hip-hop track with hard-hitting 808 bass, trap hi-hats, and confident male rap vocals. Features modern production with auto-tuned hooks and street-style lyrics about ambition and success.\",\n    \"lyrics\": \"[Intro]\\nYeah, ここから始まる\\n\\n[Verse 1]\\n底辺から這い上がってきた\\n誰も信じてくれなかった\\nでも俺は知ってた 自分の価値\\nマイク一本で 世界を変える\\n\\n夢見る奴を笑う奴ら\\n今どこにいる? 見えないな\\n俺はここ ステージの上\\nスポットライト浴びて 輝いてる\\n\\n[Hook]\\n止まらない 止められない\\nこの勢いは 誰にも\\n頂点まで 駆け上がる\\nこれが俺の生き様\\n\\n[Verse 2]\\n金も名誉も 後からついてくる\\n大事なのは 信念を貫くこと\\n仲間と一緒に 積み上げてきた\\n血と汗と涙の 結晶\\n\\n批判なんて 燃料にして\\nもっと高く 飛んでやる\\nリミッター外して フルスロットル\\n限界なんて 俺が決める\\n\\n[Hook]\\n止まらない 止められない\\nこの勢いは 誰にも\\n頂点まで 駆け上がる\\nこれが俺の生き様\\n\\n[Outro]\\nまだまだ終わらない\\n見届けろ 俺の伝説\",\n    \"bpm\": 140,\n    \"duration\": 220,\n    \"keyscale\": \"C minor\",\n    \"language\": \"ja\",\n    \"timesignature\": \"4\"\n}\n"
  },
  {
    "path": "examples/text2music/example_139.json",
    "content": "{\n    \"think\": true,\n    \"caption\": \"A romantic J-pop duet with acoustic guitar, gentle piano, and warm male-female vocal harmonies. Features heartfelt lyrics about eternal love with a sweet, wedding-appropriate atmosphere.\",\n    \"lyrics\": \"[Intro]\\n\\n[Verse 1 - Male]\\n君と出会った あの日から\\n世界が色づき始めた\\n何気ない日々が 宝物に変わる\\n君がいるだけで\\n\\n[Verse 2 - Female]\\n不器用なあなたの 優しさが\\n私の心を 溶かしていく\\nそばにいるだけで 安心できる\\nあなたがいるから\\n\\n[Chorus - Duet]\\n永遠を誓おう 二人で\\nどんな困難も 乗り越えて\\n手を繋いで 歩いていこう\\nこれからの未来を\\n愛してる その言葉を\\n何度でも 伝えたい\\n\\n[Verse 3 - Male]\\n喧嘩した夜も 仲直りして\\n朝には笑顔で おはようって\\n\\n[Verse 4 - Female]\\nそんな当たり前が 幸せだと\\n気づかせてくれた あなたに感謝\\n\\n[Chorus - Duet]\\n永遠を誓おう 二人で\\nどんな困難も 乗り越えて\\n手を繋いで 歩いていこう\\nこれからの未来を\\n\\n[Outro - Duet]\\nありがとう 出会えたこと\\nずっと一緒に いようね\",\n    \"bpm\": 76,\n    \"duration\": 206,\n    \"keyscale\": \"C major\",\n    \"language\": \"ja\",\n    \"timesignature\": \"4\"\n}"
  },
  {
    "path": "examples/text2music/example_14.json",
    "content": "{\n    \"think\": true,\n    \"caption\": \"An aggressive, high-energy electronic track driven by a relentless four-on-the-floor kick drum and a gritty, distorted synth bassline. The arrangement opens with a chiptune-style arpeggiated synth melody before slamming into the main groove. A forceful male vocal, delivered in a rhythmic, almost-rapped style, cuts through the dense mix of sharp synth stabs and atmospheric pads. The chorus is anthemic and powerful, with layered vocals creating a sense of defiance. The track features dynamic shifts, including a breakdown with filtered vocals and a build-up that reintroduces the intense beat, culminating in a powerful outro with vocal chops and a final, abrupt stop.\",\n    \"lyrics\": \"[Intro]\\n[Synth arpeggio intro]\\n[Drum build-up]\\n\\n[Verse 1]\\nEfo, siren klocha' mi kocha\\nDu mevi shemol al kol ha'bachar me'ha'ba\\nTachat, kai la'pata\\nNima bila mefila\\n\\n[Chorus]\\nTishuvot lefater bach'ka\\nBatecha nolecha im telev elor lachta\\nTirot lanu, venashmeach\\nKa'otzot pachta\\n\\n[Instrumental Drop]\\n\\n[Verse 2]\\nHakavat et hasnan\\nHakol bishvili al kol hachol rotza\\nHesham tamash, tsurad lo\\nHesham rishon, rosh, orad\\n\\n[Chorus]\\nTishuvot lefater bach'ka\\nBatecha nolecha im telev elor lachta\\nTirot lanu, venashmeach\\nKa'otzot pachta\\n\\n[Instrumental Drop]\\n\\n[Bridge]\\nTishuvot, hetta, bach'ka\\nBatecha nolecha im telev elor lachta\\nTirot lanu, venashmeach\\nKa'otzot pachta\\n\\n[Breakdown]\\n[Filtered synth arpeggio]\\n[pitched down, reverbed]\\n\\n[Chorus]\\nTishuvot lefater bach'ka\\nBatecha nolecha im telev elor lachta\\nTirot lanu, venashmeach\\nKa'otzot pachta\\n\\n[Outro]\\n[Synth arpeggio fades out]\",\n    \"bpm\": 100,\n    \"duration\": 212,\n    \"keyscale\": \"E minor\",\n    \"language\": \"he\",\n    \"timesignature\": \"4\"\n}"
  },
  {
    "path": "examples/text2music/example_140.json",
    "content": "{\n    \"think\": true,\n    \"caption\": \"A jazzy Japanese lounge track with smooth piano, upright bass, and sultry female vocals. Features sophisticated chord progressions and a late-night bar atmosphere with hints of bossa nova.\",\n    \"lyrics\": \"[Intro]\\n\\n[Verse 1]\\n煙草の煙 漂う夜\\nグラスの氷が 溶けていく\\nあなたの隣 座りたくて\\n今夜もここに 来てしまった\\n\\n[Verse 2]\\n視線が合って 微笑み合う\\n言葉はいらない この瞬間\\nジャズの調べに 身を任せて\\n二人だけの 世界へ\\n\\n[Chorus]\\n夜が更けるほど\\n心が近づく\\nこのまま時間よ\\n止まってほしい\\n\\n[Verse 3]\\nあなたの声が 耳に残る\\n甘い囁き 忘れられない\\n明日になれば 他人同士\\nでも今夜だけは\\n\\n[Chorus]\\n夜が更けるほど\\n心が近づく\\nこのまま時間よ\\n止まってほしい\\n\\n[Outro]\\nLast order 告げられても\\nまだ帰りたくない\",\n    \"bpm\": 92,\n    \"duration\": 240,\n    \"keyscale\": \"Eb major\",\n    \"language\": \"ja\",\n    \"timesignature\": \"4\"\n}"
  },
  {
    "path": "examples/text2music/example_141.json",
    "content": "{\n    \"think\": true,\n    \"caption\": \"A powerful anime battle theme with orchestral strings, epic brass, and intense choir. Features dramatic male vocals building to an explosive climax perfect for final confrontation scenes.\",\n    \"lyrics\": \"[Intro]\\n\\n[Verse 1]\\n剣を握りしめ 立ち上がれ\\n守るべきものが ここにある\\n血塗られた大地を 踏みしめて\\n最後の戦いが 始まる\\n\\n[Pre-Chorus]\\n恐れるな 退くな\\n仲間の想いを背負って\\n\\n[Chorus]\\n今こそ立ち向かえ\\n運命を切り開け\\n命燃やし尽くしても\\n譲れないものがある\\n勝利を掴み取れ\\n\\n[Verse 2]\\n幾千の夜を 越えてきた\\n修羅の道を 歩んできた\\nすべてはこの時の ために\\n覚悟は決まった\\n\\n[Chorus]\\n今こそ立ち向かえ\\n運命を切り開け\\n命燃やし尽くしても\\n譲れないものがある\\n\\n[Bridge]\\n\\n[Final Chorus]\\n今こそ立ち向かえ\\n運命を切り開け\\n英雄の魂よ\\n永遠に輝け\\n\\n[Outro]\",\n    \"bpm\": 155,\n    \"duration\": 214,\n    \"keyscale\": \"D minor\",\n    \"language\": \"ja\",\n    \"timesignature\": \"4\"\n}"
  },
  {
    "path": "examples/text2music/example_142.json",
    "content": "{\n    \"think\": true,\n    \"caption\": \"A nostalgic Japanese folk pop song with acoustic instruments, harmonica, and warm male vocals. Features countryside imagery and themes of hometown memories with a gentle, storytelling quality.\",\n    \"lyrics\": \"[Intro]\\n\\n[Verse 1]\\n田舎道を 自転車で走る\\n夕焼け空が オレンジに染まる\\nあぜ道の向こうに 見える家\\nおばあちゃんが 手を振ってる\\n\\n[Verse 2]\\n縁側で食べた スイカの味\\n蛍を追いかけた 夏の夜\\n何もなかったけど 幸せだった\\nあの頃に 戻りたい\\n\\n[Chorus]\\nふるさとの風が 呼んでいる\\n帰っておいで と言うように\\n都会の空は 狭いけど\\n心の中には 広い空\\n\\n[Verse 3]\\n祭りの夜 浴衣を着て\\n好きな子の手を そっと握った\\n花火が上がって 照れ隠し\\n甘酸っぱい 思い出\\n\\n[Chorus]\\nふるさとの風が 呼んでいる\\n帰っておいで と言うように\\n忙しい毎日 忘れそうになる\\n大切なものを\\n\\n[Outro]\\nいつか帰るよ あの場所へ\\n待っててね ふるさと\",\n    \"bpm\": 98,\n    \"duration\": 235,\n    \"keyscale\": \"G major\",\n    \"language\": \"ja\",\n    \"timesignature\": \"4\"\n}"
  },
  {
    "path": "examples/text2music/example_143.json",
    "content": "{\n    \"think\": true,\n    \"caption\": \"A dreamy electronic J-pop track with ethereal synth pads, glitchy beats, and soft female vocals. Features ambient textures and futuristic soundscapes with themes of digital love and virtual worlds.\",\n    \"lyrics\": \"[Intro]\\n\\n[Verse 1]\\nスクリーンの向こう 君がいる\\nピクセルの海を 泳いでく\\n触れられないけど 感じてる\\nデジタルの愛が 溢れ出す\\n\\n[Pre-Chorus]\\n0と1の世界で\\n本当の気持ち 見つけた\\n\\n[Chorus]\\nConnect 繋がっていたい\\nどんなに遠くても\\n電波に乗せて 届けるよ\\n私の想いを\\n\\n[Verse 2]\\nアバターの笑顔 本物だよ\\n心は嘘を つけないから\\nログインするたび ドキドキする\\n君に会えるって 思うだけで\\n\\n[Chorus]\\nConnect 繋がっていたい\\nどんなに遠くても\\n電波に乗せて 届けるよ\\n私の想いを\\n\\n[Outro]\\nいつか現実で 会えたなら\\nその時も好きって 言えるかな\",\n    \"bpm\": 118,\n    \"duration\": 215,\n    \"keyscale\": \"F# minor\",\n    \"language\": \"ja\",\n    \"timesignature\": \"4\"\n}"
  },
  {
    "path": "examples/text2music/example_144.json",
    "content": "{\n    \"think\": true,\n    \"caption\": \"A cheerful school idol group song with bouncy synths, handclaps, and energetic multi-voice female vocals. Features call-and-response sections and an ultra-catchy dance chorus.\",\n    \"lyrics\": \"[Intro]\\nHey! Hey! Hey!\\nみんな準備はいい?\\n\\n[Verse 1]\\n朝起きたら 鏡の前で\\nポーズ決めて ウインクして\\n今日も一日 全力で\\nアイドル魂 見せつけろ!\\n\\n[Pre-Chorus]\\n\\n笑顔が一番の武器だよ\\n\\n[Chorus]\\nキュンキュン させちゃうぞ\\nハートを撃ち抜いて\\nドキドキ 止まらない\\n私たちについてきて!\\nLa La La 歌おう\\nみんなで一緒に\\n最高のステージを\\n届けるよ!\\n\\n[Verse 2]\\nレッスン毎日 汗だくで\\n夢に向かって 走り続ける\\n辛い時も 仲間がいるから\\n絶対に 諦めない!\\n\\n[Chorus]\\nキュンキュン させちゃうぞ\\nハートを撃ち抜いて\\nドキドキ 止まらない\\n私たちについてきて!\\n\\n[Outro]\\nありがとう みんな大好き!\\nまた会おうね!\",\n    \"bpm\": 145,\n    \"duration\": 200,\n    \"keyscale\": \"Bb major\",\n    \"language\": \"ja\",\n    \"timesignature\": \"4\"\n}"
  },
  {
    "path": "examples/text2music/example_145.json",
    "content": "{\n    \"think\": true,\n    \"caption\": \"A melancholic post-rock instrumental with layered guitars, atmospheric reverb, and building crescendos. Features emotional piano passages and cinematic soundscapes evoking winter landscapes.\",\n    \"lyrics\": \"[Intro]\\n\\n[Verse 1]\\n白い息が 空に消える\\n冬の朝は 静かすぎて\\n足跡だけが 残される\\n誰もいない 通学路\\n\\n[Verse 2]\\n窓ガラスに 描いた絵\\n君の名前 そっと書いた\\n溶けてしまう前に\\n伝えたかった この気持ち\\n\\n[Chorus]\\n雪が降る 音もなく\\n世界を白く 染めていく\\n凍えそうな 心にも\\nいつか春は 来るのかな\\n\\n[Instrumental]\\n\\n[Verse 3]\\n卒業式の 日が来ても\\n言えないまま 終わるのかな\\n桜が咲く頃には\\n君はもう いないんだね\\n\\n[Chorus]\\n雪が降る 音もなく\\n思い出を 包んでいく\\n\\n[Outro]\",\n    \"bpm\": 85,\n    \"duration\": 208,\n    \"keyscale\": \"E minor\",\n    \"language\": \"ja\",\n    \"timesignature\": \"4\"\n}"
  },
  {
    "path": "examples/text2music/example_146.json",
    "content": "{\n    \"think\": true,\n    \"caption\": \"A funky Japanese disco track with groovy bass, wah-wah guitars, and soulful female vocals. Features retro 70s production with modern touches and an irresistible dance floor energy.\",\n    \"lyrics\": \"[Intro]\\n\\n[Verse 1]\\nミラーボールが 回り出す\\n今夜は踊り明かそう\\nヒールを鳴らして フロアへ\\n退屈な日々に サヨナラ\\n\\n[Pre-Chorus]\\n音楽に身を任せて\\n自由になれる この瞬間\\n\\n[Chorus]\\nDisco Night 踊ろう\\n朝まで止まらない\\nGroovy Night 感じて\\nリズムに乗って\\nLet's Dance!\\n\\n[Verse 2]\\n嫌なことは 忘れちゃえ\\n今この瞬間を 楽しもう\\nストロボライトの中で\\n誰もが主役になれる\\n\\n[Chorus]\\nDisco Night 踊ろう\\n朝まで止まらない\\nGroovy Night 感じて\\nリズムに乗って\\n\\n[Outro]\\nDisco Night\\nまた会おう ダンスフロアで\",\n    \"bpm\": 120,\n    \"duration\": 225,\n    \"keyscale\": \"Ab major\",\n    \"language\": \"ja\",\n    \"timesignature\": \"4\"\n}"
  },
  {
    "path": "examples/text2music/example_147.json",
    "content": "{\n    \"think\": true,\n    \"caption\": \"A dramatic anime insert song with piano and strings building to powerful rock instrumentation. Features emotional female vocals conveying sacrifice and determination in a climactic scene.\",\n    \"lyrics\": \"[Intro]\\n\\n[Verse 1]\\n守りたいものがある\\nだから私は戦う\\nこの命が尽きるまで\\n絶対に諦めない\\n\\n[Verse 2]\\n涙を拭いて 立ち上がる\\n弱さを見せる 暇はない\\n背負った想い 重いけど\\nそれが私の 強さになる\\n\\n[Chorus]\\n光の中へ 飛び込んで\\n闇を切り裂く 剣となれ\\n一人じゃないと 信じてる\\n仲間の声が 聞こえるから\\n\\n[Bridge]\\n\\n[Final Chorus]\\n光の中へ 飛び込んで\\n未来を掴む この手で\\n奇跡を起こせ 今ここで\\n\\n[Outro]\",\n    \"bpm\": 148,\n    \"duration\": 230,\n    \"keyscale\": \"C minor\",\n    \"language\": \"ja\",\n    \"timesignature\": \"4\"\n}"
  },
  {
    "path": "examples/text2music/example_148.json",
    "content": "{\n    \"think\": true,\n    \"caption\": \"A chill lo-fi Japanese hip-hop track with mellow beats, vinyl crackle, and relaxed male vocals. Features jazzy samples and rainy day atmosphere perfect for studying or relaxing.\",\n    \"lyrics\": \"[Intro]\\n\\n[Verse 1]\\n雨の音を聴きながら\\nコーヒー片手に 窓の外\\n何もしない 贅沢な時間\\nこれでいいんだ 今日は\\n\\n[Verse 2]\\n本を開いて 読み始める\\n気づけば夕方 時間が溶ける\\n焦らなくていい ゆっくりでいい\\n自分のペースで 生きていく\\n\\n[Hook]\\nChill out 深呼吸して\\n世界は回り続ける\\nChill out 力を抜いて\\n明日のことは 明日考えよう\\n\\n[Verse 3]\\n夜になったら 音楽かけて\\nビートに揺られて まどろむ\\n夢の中では 自由に飛べる\\nどこまでも 高く\\n\\n[Hook]\\nChill out 深呼吸して\\n世界は回り続ける\\n\\n[Outro]\",\n    \"bpm\": 75,\n    \"duration\": 195,\n    \"keyscale\": \"Db major\",\n    \"language\": \"ja\",\n    \"timesignature\": \"4\"\n}"
  },
  {
    "path": "examples/text2music/example_149.json",
    "content": "{\n    \"think\": true,\n    \"caption\": \"A powerful Japanese punk rock anthem with fast distorted guitars, aggressive drums, and raw male vocals. Features rebellious lyrics about breaking free from society's expectations.\",\n    \"lyrics\": \"[Intro]\\n\\n[Verse 1]\\nつまらない毎日に 中指立てろ\\n誰かの決めたルール なんて知らない\\n自分の道は 自分で決める\\nそれが俺たちの 生き方だ\\n\\n[Chorus]\\n叫べ 叫べ 声が枯れるまで\\n走れ 走れ 足が止まるまで\\n誰にも止められない\\nこれが俺たちの パンクロック!\\n\\n[Verse 2]\\n大人たちは言う 現実を見ろと\\nでも現実って 誰が決めた?\\n夢を追うことの 何が悪い\\n笑いたい奴は 笑えばいい\\n\\n[Chorus]\\n叫べ 叫べ 声が枯れるまで\\n走れ 走れ 足が止まるまで\\n\\n[Bridge]\\n1 2 3 4!\\n\\n[Outro]\\nこれが俺たちの 生き様だ!\",\n    \"bpm\": 185,\n    \"duration\": 180,\n    \"keyscale\": \"A major\",\n    \"language\": \"ja\",\n    \"timesignature\": \"4\"\n}"
  },
  {
    "path": "examples/text2music/example_15.json",
    "content": "{\n    \"think\": true,\n    \"caption\": \"An intense, high-energy electronic track driven by a relentless, arpeggiated synth melody and a hard-hitting trap beat with rapid-fire hi-hats and a deep sub-bass. A powerful female vocal, delivered in Mandarin, cuts through the mix with a clear, assertive tone. The arrangement builds through tense verses into an anthemic, soaring chorus where the vocals become more melodic and layered. The track features dynamic drops and builds, including a brief, atmospheric bridge with filtered vocals and pads before slamming back into a final, climactic chorus and an instrumental outro that deconstructs the main synth motif.\",\n    \"lyrics\": \"[Intro - Arpeggiated Synth Melody]\\n\\n[Verse 1]\\n午夜城市灯光闪\\n黑夜中你藏心弦\\n一脚踏入深渊洞\\n脚下跳动电波涌\\n喧嚣夜深云雾涌\\n孤单的你在夜空\\n光与影交织梦境\\n每一拍都在追忆\\n\\n[Chorus]\\nYeah\\n黑夜之上我是逃亡\\n风暴之中寻找方向\\n燃烧灵魂去疯狂\\n这世界锁不住渴望\\n\\n[Instrumental Break - Synth Melody]\\n\\n[Verse 2]\\n时间律动催人转\\n繁星作画流星卷\\n故事未完灵魂闪\\n快将心跳连接遍\\n\\n[Instrumental Drop]\\n\\n[Bridge]\\n冲破那无边黑暗\\n光束驱散悲伤酸\\n虚伪遮眼无需问\\n黑夜是我唯一的吻\\n\\n[Chorus]\\n黑夜之上我是逃亡\\n风暴之中寻找方向\\n燃烧灵魂去疯狂\\n这世界锁不住渴望\\n\\n[Instrumental Break]\\n\\n[Chorus - Layered Vocals]\\n冲破那无边黑暗\\n光束驱散悲伤酸\\n虚伪遮眼无需问\\n黑夜是我唯一的吻\\n\\n[Outro - Synth Melody Fades Out]\",\n    \"bpm\": 100,\n    \"duration\": 194,\n    \"keyscale\": \"E minor\",\n    \"language\": \"zh\",\n    \"timesignature\": \"4\"\n}"
  },
  {
    "path": "examples/text2music/example_150.json",
    "content": "{\n    \"think\": true,\n    \"caption\": \"A gentle Japanese lullaby with music box melodies, soft strings, and tender female vocals. Features soothing harmonies and dreamlike atmosphere perfect for bedtime.\",\n    \"lyrics\": \"[Intro]\\n\\n[Verse 1]\\nおやすみ 小さな天使\\n今日も一日 頑張ったね\\n目を閉じて 夢の世界へ\\nママがそばに いるからね\\n\\n[Verse 2]\\n星たちが 見守ってる\\n月の光が 包み込む\\n怖いものは 何もないよ\\n安心して 眠りなさい\\n\\n[Chorus]\\nねんねんころりよ\\n夢の中で遊ぼう\\n明日になったら\\nまた会おうね\\n\\n[Verse 3]\\n大きくなったら\\nどんな夢を見るのかな\\n何にでもなれるよ\\n可能性は無限大\\n\\n[Outro]\\nおやすみなさい\\n良い夢を\",\n    \"bpm\": 65,\n    \"duration\": 180,\n    \"keyscale\": \"F major\",\n    \"language\": \"ja\",\n    \"timesignature\": \"3\"\n}"
  },
  {
    "path": "examples/text2music/example_151.json",
    "content": "{\n    \"think\": true,\n    \"caption\": \"A high-energy Japanese EDM festival anthem with massive synth drops, pounding kicks, and euphoric female vocals. Features build-ups and breakdowns designed for maximum crowd impact.\",\n    \"lyrics\": \"[Intro]\\n\\n[Verse 1]\\nフロアが揺れる 心臓が跳ねる\\n今夜は最高の 夜になる\\n両手を上げて 声を上げて\\n一つになろう みんなで\\n\\n[Build-up]\\nAre you ready?\\n3 2 1...\\n\\n[Drop]\\nJump! Jump! Jump!\\n飛び跳ねろ\\nHands up! Hands up!\\n空を掴め\\n\\n[Verse 2]\\n汗が光る ライトの中で\\n音楽だけが 全てを繋ぐ\\n言葉はいらない 感じるだけ\\nこの瞬間を 生きている\\n\\n[Build-up]\\nもっと もっと 高く!\\n\\n[Drop]\\nJump! Jump! Jump!\\n飛び跳ねろ\\nHands up! Hands up!\\n空を掴め\\n\\n[Outro]\\nThank you! また会おう!\",\n    \"bpm\": 150,\n    \"duration\": 210,\n    \"keyscale\": \"G minor\",\n    \"language\": \"ja\",\n    \"timesignature\": \"4\"\n}"
  },
  {
    "path": "examples/text2music/example_152.json",
    "content": "{\n    \"think\": true,\n    \"caption\": \"A bittersweet Japanese graduation song with acoustic guitar, piano, and heartfelt choir harmonies. Features emotional male vocals reflecting on school memories and farewells.\",\n    \"lyrics\": \"[Intro]\\n\\n[Verse 1]\\n三年間の 思い出が\\n走馬灯のように 駆け巡る\\n教室の窓から見た 空\\n今日で最後なんだね\\n\\n[Verse 2]\\n隣の席の 君の笑顔\\n放課後の 部活の汗\\n何気ない日々が\\n宝物だったと 気づく\\n\\n[Chorus]\\nさよなら 僕らの教室\\nありがとう 全ての日々に\\nそれぞれの道を 歩き出す\\nまた会える日まで\\n\\n[Verse 3]\\n先生の言葉 胸に刻んで\\n新しい世界へ 旅立つ\\n不安もあるけど 大丈夫\\n仲間がいるから\\n\\n[Chorus]\\nさよなら 僕らの青春\\nありがとう 出会えたことに\\n\\n[Outro]\\n桜舞う この場所で\\n誓おう また会おうと\",\n    \"bpm\": 78,\n    \"duration\": 214,\n    \"keyscale\": \"D major\",\n    \"language\": \"ja\",\n    \"timesignature\": \"4\"\n}"
  },
  {
    "path": "examples/text2music/example_153.json",
    "content": "{\n    \"think\": true,\n    \"caption\": \"A mystical Japanese fantasy RPG theme with orchestral arrangements, ethereal choir, and epic brass. Features sweeping melodies evoking magical worlds and heroic adventures.\",\n    \"lyrics\": \"[Intro]\\n\\n[Verse 1]\\n古の伝説が 語り継がれる\\n選ばれし者よ 目覚めの時\\n剣と魔法の 世界へ\\n冒険が今 始まる\\n\\n[Verse 2]\\n仲間と出会い 絆を結び\\n試練を乗り越え 強くなる\\n闇の王を倒すため\\n光の勇者よ 立ち上がれ\\n\\n[Chorus]\\n運命の歯車が 回り出す\\n伝説は今 紡がれる\\n勇気を胸に 進め\\n新たなる世界へ\\n\\n[Bridge]\\n\\n[Final Chorus]\\n運命の歯車が 回り出す\\n英雄の物語 始まる\\n\\n[Outro]\",\n    \"bpm\": 130,\n    \"duration\": 231,\n    \"keyscale\": \"Bb minor\",\n    \"language\": \"ja\",\n    \"timesignature\": \"4\"\n}"
  },
  {
    "path": "examples/text2music/example_154.json",
    "content": "{\n    \"think\": true,\n    \"caption\": \"A romantic Japanese R&B slow jam with smooth synths, sensual bass, and silky male vocals. Features late-night vibes and intimate lyrics about passionate love.\",\n    \"lyrics\": \"[Intro]\\n\\n[Verse 1]\\n月明かりの下で 君を見つめる\\n言葉にできない この気持ち\\n触れたい 抱きしめたい\\n今夜だけは 離さない\\n\\n[Pre-Chorus]\\n時間よ止まれ\\nこのまま二人で\\n\\n[Chorus]\\n愛してる 伝えたい\\n君だけを 見つめてる\\n永遠に 続くように\\nこの夜を 忘れない\\n\\n[Verse 2]\\n君の香りに 酔いしれて\\n甘い吐息が 耳をくすぐる\\n何も考えなくていい\\nただ感じて\\n\\n[Chorus]\\n愛してる 伝えたい\\n君だけを 見つめてる\\n\\n[Outro]\\n朝が来るまで\\nそばにいて\",\n    \"bpm\": 70,\n    \"duration\": 240,\n    \"keyscale\": \"Eb minor\",\n    \"language\": \"ja\",\n    \"timesignature\": \"4\"\n}"
  },
  {
    "path": "examples/text2music/example_155.json",
    "content": "{\n    \"think\": true,\n    \"caption\": \"A catchy Japanese Vocaloid-style electronic pop song with chiptune elements, fast arpeggios, and high-pitched synthesized vocals. Features energetic tempo and otaku culture references.\",\n    \"lyrics\": \"[Intro]\\n\\n[Verse 1]\\n画面の中の 世界へようこそ\\nピクセルアートの 冒険が始まる\\nコントローラー握りしめて\\nハイスコア目指せ\\n\\n[Pre-Chorus]\\nゲームオーバーなんて\\n怖くない リトライすればいい\\n\\n[Chorus]\\nPlay! Play! Play!\\n止まらない\\n電子の海を 駆け抜けろ\\nLevel up! Level up!\\n強くなれ\\n最強の勇者になるまで\\n\\n[Verse 2]\\nバグも仕様も 楽しんじゃえ\\n予想外の展開 ワクワクする\\nセーブポイント 見つけたら\\n一息ついて また進もう\\n\\n[Chorus]\\nPlay! Play! Play!\\n止まらない\\n電子の海を 駆け抜けろ\\n\\n[Outro]\\nGame Clear!\\nおめでとう!\",\n    \"bpm\": 175,\n    \"duration\": 190,\n    \"keyscale\": \"B major\",\n    \"language\": \"ja\",\n    \"timesignature\": \"4\"\n}"
  },
  {
    "path": "examples/text2music/example_156.json",
    "content": "{\n    \"think\": true,\n    \"caption\": \"An energetic K-pop dance track with punchy synth bass, crisp snare hits, and layered vocal harmonies. Features a catchy hook with a mix of powerful female idol vocals and rhythmic rap verses, building to an explosive chorus with EDM-influenced drops.\",\n    \"lyrics\": \"[Intro]\\n라라라 라라라\\n느껴봐 이 순간\\n\\n[Verse 1]\\n어두운 밤하늘 아래서\\n빛나는 별처럼 우린 춤을 춰\\n심장이 뛰는 대로 따라가\\n오늘 밤 우린 자유로워\\n\\n[Pre-Chorus]\\n멈추지 마 이 느낌\\n더 높이 날아올라\\n\\n[Chorus]\\n빛나는 우리 tonight\\n세상을 다 가진 것처럼\\n소리 질러 더 크게\\n이 밤이 끝나지 않게\\n빛나는 우리 tonight\\n\\n[Verse 2]\\n걱정은 다 잊어버려\\n지금 이 순간만 느껴봐\\n음악에 몸을 맡겨봐\\n우리만의 파티가 시작돼\\n\\n[Pre-Chorus]\\n멈추지 마 이 느낌\\n더 높이 날아올라\\n\\n[Chorus]\\n빛나는 우리 tonight\\n세상을 다 가진 것처럼\\n소리 질러 더 크게\\n이 밤이 끝나지 않게\\n빛나는 우리 tonight\\n\\n[Bridge]\\n하나 둘 셋 넷\\n다 같이 뛰어봐\\n이 순간을 영원히\\n\\n[Outro]\\n빛나는 우리 tonight\\n라라라 라라라\",\n    \"bpm\": 125,\n    \"duration\": 195,\n    \"keyscale\": \"F# minor\",\n    \"language\": \"ko\",\n    \"timesignature\": \"4\"\n}\n"
  },
  {
    "path": "examples/text2music/example_157.json",
    "content": "{\n    \"think\": true,\n    \"caption\": \"A heartfelt Korean ballad with gentle piano accompaniment and sweeping string arrangements. The male vocalist delivers emotional, breathy verses that build to a powerful, soaring chorus with rich vocal runs and subtle orchestral swells.\",\n    \"lyrics\": \"[Intro]\\n\\n[Verse 1]\\n텅 빈 방 안에 홀로 앉아\\n너의 사진을 바라봐\\n함께했던 그 시간들이\\n눈물처럼 흘러내려\\n\\n[Verse 2]\\n네가 없는 하루하루가\\n이렇게 길 줄 몰랐어\\n익숙했던 네 향기가\\n아직도 여기 남아있어\\n\\n[Chorus]\\n보고 싶어 너무 보고 싶어\\n이 밤이 지나도 변하지 않아\\n사랑해 아직도 사랑해\\n내 마음속에 너만 있어\\n영원히\\n\\n[Verse 3]\\n우리 걸었던 그 거리에\\n혼자 서서 널 불러봐\\n대답 없는 메아리만\\n바람에 흩어져 가\\n\\n[Chorus]\\n보고 싶어 너무 보고 싶어\\n이 밤이 지나도 변하지 않아\\n사랑해 아직도 사랑해\\n내 마음속에 너만 있어\\n영원히\\n\\n[Bridge]\\n다시 돌아와 줘\\n내 곁에 있어 줘\\n이 아픔을 멈춰줘\\n\\n[Outro]\\n보고 싶어... 너무...\\n사랑해...\",\n    \"bpm\": 68,\n    \"duration\": 225,\n    \"keyscale\": \"G major\",\n    \"language\": \"ko\",\n    \"timesignature\": \"4\"\n}"
  },
  {
    "path": "examples/text2music/example_158.json",
    "content": "{\n    \"think\": true,\n    \"caption\": \"A hard-hitting K-hip-hop track with heavy 808 bass, trap hi-hats, and aggressive synth stabs. Features confident male rap verses with rapid-fire flow and a melodic sung hook, showcasing the swagger and intensity of Korean underground hip-hop.\",\n    \"lyrics\": \"[Intro]\\nYeah, uh\\n시작해볼까\\n\\n[Verse 1]\\n난 멈추지 않아 계속 달려가\\n정상까지 올라가 다 밟아버려\\n니가 뭘 알아 내 삶을\\n바닥부터 시작해 여기까지 왔어\\n매일 밤 작업실에서 불태워\\n꿈을 향해 달려가 멈추지 마\\n\\n[Hook]\\n위로 위로 올라가\\n아무도 날 막을 수 없어\\n위로 위로 올라가\\n이건 나의 시대야\\n\\n[Verse 2]\\n다들 불가능하다 했지만\\n난 증명해냈어 내 실력으로\\n화려한 조명 아래 서있어\\n이게 바로 내가 원했던 거야\\n포기란 없어 내 사전에\\n끝까지 가볼 거야 믿어봐\\n\\n[Hook]\\n위로 위로 올라가\\n아무도 날 막을 수 없어\\n위로 위로 올라가\\n이건 나의 시대야\\n\\n[Bridge]\\n땀과 눈물로 만든 결과\\n이제 세상에 보여줄 차례야\\n\\n[Outro]\\n위로 올라가\\nYeah, we made it\",\n    \"bpm\": 88,\n    \"duration\": 185,\n    \"keyscale\": \"D minor\",\n    \"language\": \"ko\",\n    \"timesignature\": \"4\"\n}\n"
  },
  {
    "path": "examples/text2music/example_159.json",
    "content": "{\n    \"think\": true,\n    \"caption\": \"A smooth K-R&B track with lush neo-soul chords, warm bass grooves, and subtle electronic textures. The female vocalist delivers silky, intimate verses with delicate falsetto moments, creating a late-night romantic atmosphere.\",\n    \"lyrics\": \"[Intro]\\nMm, yeah\\n오늘 밤\\n\\n[Verse 1]\\n달빛이 창문을 비추고\\n네 생각에 잠 못 들어\\n부드러운 음악 속에서\\n너와 함께한 밤을 그려\\n\\n[Pre-Chorus]\\n이 느낌을 뭐라 해야 할까\\n설레임인지 사랑인지\\n\\n[Chorus]\\n너에게 빠져들어 깊이\\n헤어날 수 없는 이 감정\\n밤새도록 너만 생각해\\n이게 사랑인 거겠지\\nOh baby\\n\\n[Verse 2]\\n네 목소리가 귓가에 맴돌아\\n달콤한 속삭임처럼\\n시간이 멈춘 것 같아\\n너와 함께라면\\n\\n[Pre-Chorus]\\n이 느낌을 뭐라 해야 할까\\n설레임인지 사랑인지\\n\\n[Chorus]\\n너에게 빠져들어 깊이\\n헤어날 수 없는 이 감정\\n밤새도록 너만 생각해\\n이게 사랑인 거겠지\\nOh baby\\n\\n[Bridge]\\n영원히 이 순간 속에\\n너와 함께 있고 싶어\\n\\n[Outro]\\n빠져들어... 너에게...\",\n    \"bpm\": 75,\n    \"duration\": 225,\n    \"keyscale\": \"Eb major\",\n    \"language\": \"ko\",\n    \"timesignature\": \"4\"\n}\n"
  },
  {
    "path": "examples/text2music/example_16.json",
    "content": "{\n    \"think\": true,\n    \"caption\": \"An upbeat, retro-flavored synth-pop track with a distinct 80s city pop aesthetic. The song is built on a foundation of a punchy, gated-reverb drum machine beat and a funky, melodic synth bassline that drives the groove. Layers of bright, brassy synth stabs and shimmering pads create a vibrant, nostalgic soundscape. A clean, funky electric guitar adds rhythmic texture with muted strums and short licks. The lead vocal is a clear, smooth female voice, delivering a catchy melody with a touch of reverb. The track follows a classic pop structure, with an energetic chorus and a brief, more reflective bridge before a final instrumental fade-out.\",\n    \"lyrics\": \"[Intro - Synth & Drum Machine]\\n\\n[Verse 1]\\n月亮挂在夜空轻轻摇\\n城市霓虹在眼前飘\\n你的脚步像慢动作漂\\n心跳加速无法逃跑\\n\\n[Chorus]\\n跟着节奏慢慢靠近\\n梦里的旋律吸引不停\\n你的眼神如星光的印\\n我的世界因你而安静\\n\\n[Instrumental Break]\\n\\n[Verse 2]\\n街头热气弥漫着热浪\\n脚步和节拍越来越长\\n空气中弥漫淡淡芬芳\\n我们的距离瞬间在曝光\\n\\n[Chorus]\\n跟着节奏慢慢靠近\\n梦里的旋律吸引不停\\n你的眼神如星光的印\\n我的世界因你而安静\\n\\n[Bridge]\\n午夜钟声在耳边回荡\\n时间却静止无法隐藏\\n你的轮廓在脑海点亮\\n每一瞬间都让我疯狂\\n\\n[Instrumental Break]\\n\\n[Chorus]\\n跟着节奏慢慢靠近\\n梦里的旋律吸引不停\\n你的眼神如星光的印\\n我的世界因你而安静\\n\\n[Outro - Instrumental Fade Out]\",\n    \"bpm\": 100,\n    \"duration\": 187,\n    \"keyscale\": \"E minor\",\n    \"language\": \"zh\",\n    \"timesignature\": \"4\"\n}"
  },
  {
    "path": "examples/text2music/example_160.json",
    "content": "{\n    \"think\": true,\n    \"caption\": \"An upbeat trot song with bouncy accordion melodies, cheerful brass sections, and traditional Korean percussion elements. The energetic male vocalist delivers playful verses with characteristic trot vibrato and catchy call-and-response hooks.\",\n    \"lyrics\": \"[Intro]\\n얼쑤! 좋다!\\n\\n[Verse 1]\\n오늘 같은 날엔 신나게\\n한잔 하면서 놀아보자\\n걱정 근심 다 잊어버리고\\n흥겹게 춤을 춰봐요\\n\\n[Chorus]\\n얼쑤 좋다 신난다\\n오늘 밤은 우리 세상\\n쿵짝쿵짝 장단 맞춰\\n모두 함께 노래해요\\n라라라 랄랄라\\n인생 뭐 있어 즐기자\\n\\n[Verse 2]\\n힘든 일도 많았지만\\n웃으면 복이 와요\\n좋은 사람들과 함께라면\\n매일이 축제야\\n\\n[Chorus]\\n얼쑤 좋다 신난다\\n오늘 밤은 우리 세상\\n쿵짝쿵짝 장단 맞춰\\n모두 함께 노래해요\\n라라라 랄랄라\\n인생 뭐 있어 즐기자\\n\\n[Bridge]\\n자 모두 손뼉을 쳐봐요\\n하나 둘 셋 넷\\n\\n[Outro]\\n얼쑤! 좋다!\\n다 같이 놀아보자!\",\n    \"bpm\": 128,\n    \"duration\": 180,\n    \"keyscale\": \"C major\",\n    \"language\": \"ko\",\n    \"timesignature\": \"4\"\n}\n"
  },
  {
    "path": "examples/text2music/example_161.json",
    "content": "{\n    \"think\": true,\n    \"caption\": \"A dreamy Korean indie rock track with jangly guitars, warm analog synths, and soft drum patterns. The gentle male vocalist delivers introspective lyrics with a nostalgic, lo-fi aesthetic reminiscent of Korean indie bands.\",\n    \"lyrics\": \"[Intro]\\n\\n[Verse 1]\\n오래된 카페 창가에 앉아\\n흐린 하늘을 바라봐\\n커피 향기 속에 떠오르는\\n지난 여름의 기억들\\n\\n[Verse 2]\\n낡은 레코드판이 돌아가고\\n익숙한 멜로디가 흘러\\n그때 우리 함께 들었던\\n그 노래가 생각나\\n\\n[Chorus]\\n시간은 흘러가도\\n그 순간은 멈춰있어\\n바래진 사진 속에서\\n우리는 여전히 웃고 있어\\n\\n[Verse 3]\\n골목길을 걸으며\\n네 이름을 불러봐\\n대답 없는 메아리만\\n바람에 실려 가\\n\\n[Chorus]\\n시간은 흘러가도\\n그 순간은 멈춰있어\\n바래진 사진 속에서\\n우리는 여전히 웃고 있어\\n\\n[Outro]\\n그리운 그 시절로\\n돌아갈 수 있다면...\",\n    \"bpm\": 95,\n    \"duration\": 210,\n    \"keyscale\": \"A major\",\n    \"language\": \"ko\",\n    \"timesignature\": \"4\"\n}"
  },
  {
    "path": "examples/text2music/example_162.json",
    "content": "{\n    \"think\": true,\n    \"caption\": \"A high-energy K-pop boy group track with aggressive synth leads, powerful brass stabs, and hard-hitting drums. Features synchronized group chants, intense rap verses, and a anthemic chorus with layered male vocals showcasing fierce choreography energy.\",\n    \"lyrics\": \"[Intro]\\nHey! Ho!\\n우리가 왔다\\n\\n[Verse 1]\\n무대 위에 올라서면\\n세상이 달라져\\n수천 개의 눈빛이\\n우릴 향해 빛나\\n두려움 따윈 없어\\n우린 준비됐어\\n\\n[Pre-Chorus]\\n자 시작해볼까\\n모두 주목해\\n\\n[Chorus]\\nWe are the champions\\n누구도 막을 수 없어\\n하늘 높이 날아올라\\n세상을 뒤흔들어\\nWe are the champions\\n영원히 빛날 거야\\n\\n[Verse 2 - Rap]\\nYo listen up 들어봐 이건 우리 이야기\\n바닥부터 시작해 정상까지 달려\\n피와 땀으로 만든 이 무대\\n포기란 없어 우리 사전에\\n\\n[Pre-Chorus]\\n자 시작해볼까\\n모두 주목해\\n\\n[Chorus]\\nWe are the champions\\n누구도 막을 수 없어\\n하늘 높이 날아올라\\n세상을 뒤흔들어\\n\\n[Bridge]\\n하나로 뭉쳐서\\n함께 외쳐봐\\nHey! Ho! Hey! Ho!\\n\\n[Outro]\\nWe are the champions!\",\n    \"bpm\": 118,\n    \"duration\": 200,\n    \"keyscale\": \"E minor\",\n    \"language\": \"ko\",\n    \"timesignature\": \"4\"\n}\n"
  },
  {
    "path": "examples/text2music/example_163.json",
    "content": "{\n    \"think\": true,\n    \"caption\": \"A cinematic Korean OST ballad with orchestral strings, delicate piano, and emotional crescendos. The powerful female vocalist delivers a heart-wrenching performance with dramatic high notes and vulnerable soft passages, perfect for a drama's climactic scene.\",\n    \"lyrics\": \"[Intro]\\n\\n[Verse 1]\\n너를 처음 만난 그날\\n운명인 줄 알았어\\n눈부신 햇살 아래서\\n네 미소가 빛났어\\n\\n[Verse 2]\\n함께한 모든 순간들이\\n꿈처럼 아름다웠어\\n영원할 줄 알았던\\n우리의 사랑이\\n\\n[Chorus]\\n잊을 수 없어 너를\\n지울 수 없어 우리를\\n가슴 깊이 새겨진\\n너라는 사람을\\n이 아픔이 지나가도\\n너만은 기억할게\\n영원히\\n\\n[Verse 3]\\n빗소리에 잠 못 드는 밤\\n네 목소리가 들려\\n다시 볼 수 없다 해도\\n사랑했어 진심으로\\n\\n[Chorus]\\n잊을 수 없어 너를\\n지울 수 없어 우리를\\n가슴 깊이 새겨진\\n너라는 사람을\\n\\n[Bridge]\\n시간이 흘러도\\n계절이 바뀌어도\\n내 마음은 그대로야\\n\\n[Outro]\\n사랑해... 영원히...\",\n    \"bpm\": 65,\n    \"duration\": 214,\n    \"keyscale\": \"Bb major\",\n    \"language\": \"ko\",\n    \"timesignature\": \"4\"\n}"
  },
  {
    "path": "examples/text2music/example_164.json",
    "content": "{\n    \"think\": true,\n    \"caption\": \"A groovy K-pop girl group track with funky bass lines, retro disco influences, and sparkling synth arpeggios. Features sassy female vocals with playful ad-libs, a catchy whistle hook, and an irresistible dance break section.\",\n    \"lyrics\": \"[Intro]\\n휘파람~ 휘파람~\\nHey boy\\n\\n[Verse 1]\\n오늘 뭔가 달라 보여\\n거울 속에 비친 나\\n반짝이는 드레스 입고\\n파티에 갈 준비 완료\\n\\n[Pre-Chorus]\\n다들 날 쳐다봐\\n시선을 사로잡아\\n\\n[Chorus]\\n나를 따라와 baby\\n이 리듬에 몸을 맡겨\\n오늘 밤 주인공은 나야\\n눈을 뗄 수 없을걸\\n나를 따라와 baby\\n\\n[Verse 2]\\n자신감이 넘쳐흘러\\n누구보다 빛나는 밤\\n걱정 따윈 버려버려\\n지금 이 순간을 즐겨\\n\\n[Pre-Chorus]\\n다들 날 쳐다봐\\n시선을 사로잡아\\n\\n[Chorus]\\n나를 따라와 baby\\n이 리듬에 몸을 맡겨\\n오늘 밤 주인공은 나야\\n눈을 뗄 수 없을걸\\n\\n[Bridge]\\nLa la la la la\\n모두 함께 춤춰봐\\n\\n[Outro]\\n휘파람~ 휘파람~\\n나를 따라와~\",\n    \"bpm\": 115,\n    \"duration\": 190,\n    \"keyscale\": \"D major\",\n    \"language\": \"ko\",\n    \"timesignature\": \"4\"\n}\n"
  },
  {
    "path": "examples/text2music/example_165.json",
    "content": "{\n    \"think\": true,\n    \"caption\": \"A melancholic Korean acoustic ballad with fingerpicked guitar, soft cello accompaniment, and minimal percussion. The tender male vocalist delivers a bittersweet farewell song with raw emotion and gentle vibrato.\",\n    \"lyrics\": \"[Intro]\\n\\n[Verse 1]\\n마지막이라는 걸 알면서도\\n너를 보내야 했어\\n떨리는 목소리로\\n안녕이라 말했지\\n\\n[Verse 2]\\n네가 걸어가는 뒷모습을\\n한참을 바라봤어\\n돌아오지 않을 걸 알면서도\\n기다렸어 그 자리에서\\n\\n[Chorus]\\n안녕 내 사랑\\n행복해야 해\\n나 없이도 웃을 수 있게\\n좋은 사람 만나\\n안녕 내 사랑\\n잊지 않을게 우리를\\n\\n[Verse 3]\\n함께했던 계절들이\\n스쳐 지나가\\n봄 여름 가을 겨울\\n모두 너와 함께였는데\\n\\n[Chorus]\\n안녕 내 사랑\\n행복해야 해\\n나 없이도 웃을 수 있게\\n좋은 사람 만나\\n\\n[Bridge]\\n다음 생에 다시 만나면\\n그땐 놓지 않을게\\n\\n[Outro]\\n안녕... 내 사랑...\\n안녕...\",\n    \"bpm\": 72,\n    \"duration\": 240,\n    \"keyscale\": \"C minor\",\n    \"language\": \"ko\",\n    \"timesignature\": \"4\"\n}"
  },
  {
    "path": "examples/text2music/example_166.json",
    "content": "{\n    \"think\": true,\n    \"caption\": \"A pulsating Korean EDM track with massive synth drops, driving four-on-the-floor beats, and euphoric build-ups. Features pitched vocal chops, festival-ready breakdowns, and an explosive chorus designed for club and concert energy.\",\n    \"lyrics\": \"[Intro]\\n손을 들어\\n하늘 높이\\n\\n[Build-up]\\n느껴봐 이 순간을\\n심장이 뛰는 소리\\n더 크게 더 높이\\n폭발할 것 같아\\n\\n[Drop]\\n뛰어 뛰어 뛰어\\n멈추지 마\\n뛰어 뛰어 뛰어\\n밤새도록\\n\\n[Verse 1]\\n어둠을 밝히는 불빛\\n우리를 감싸는 음악\\n하나가 되는 이 순간\\n영원히 기억할 거야\\n\\n[Build-up]\\n느껴봐 이 순간을\\n심장이 뛰는 소리\\n더 크게 더 높이\\n\\n[Drop]\\n뛰어 뛰어 뛰어\\n멈추지 마\\n뛰어 뛰어 뛰어\\n밤새도록\\n\\n[Bridge]\\n모두 함께\\n소리 질러\\nOh oh oh oh\\n\\n[Final Drop]\\n뛰어 뛰어 뛰어\\n멈추지 마\\n\\n[Outro]\\n이 밤이 끝나지 않게\",\n    \"bpm\": 128,\n    \"duration\": 195,\n    \"keyscale\": \"A minor\",\n    \"language\": \"ko\",\n    \"timesignature\": \"4\"\n}\n"
  },
  {
    "path": "examples/text2music/example_167.json",
    "content": "{\n    \"think\": true,\n    \"caption\": \"A sentimental Korean pop rock ballad with electric guitar solos, steady drum beats, and emotional piano layers. The male rock vocalist delivers passionate verses with gritty texture building to powerful belt notes in the chorus.\",\n    \"lyrics\": \"[Intro]\\n\\n[Verse 1]\\n비 내리는 거리를 걸으며\\n너와의 추억을 떠올려\\n함께 웃던 그 카페 앞에서\\n발걸음이 멈춰버렸어\\n\\n[Pre-Chorus]\\n왜 이렇게 힘든 건지\\n너 없인 안 되는 건지\\n\\n[Chorus]\\n소리쳐 불러봐도\\n넌 돌아오지 않아\\n이 빗속에 홀로 서서\\n너의 이름을 외쳐\\n사랑했어 정말로\\n미치도록 사랑했어\\n\\n[Verse 2]\\n네가 남긴 편지를 읽으며\\n눈물이 멈추질 않아\\n다시 시작하자던 약속은\\n바람에 흩어져 버렸어\\n\\n[Pre-Chorus]\\n왜 이렇게 힘든 건지\\n너 없인 안 되는 건지\\n\\n[Chorus]\\n소리쳐 불러봐도\\n넌 돌아오지 않아\\n이 빗속에 홀로 서서\\n너의 이름을 외쳐\\n\\n[Guitar Solo]\\n\\n[Bridge]\\n시간이 지나면 괜찮아질까\\n이 아픔도 사라질까\\n\\n[Outro]\\n사랑했어... 정말로...\",\n    \"bpm\": 85,\n    \"duration\": 212,\n    \"keyscale\": \"B minor\",\n    \"language\": \"ko\",\n    \"timesignature\": \"4\"\n}"
  },
  {
    "path": "examples/text2music/example_168.json",
    "content": "{\n    \"think\": true,\n    \"caption\": \"A cute and bubbly K-pop track with bright synth melodies, playful xylophone accents, and bouncy electronic beats. Features adorable female vocals with aegyo-style delivery, perfect for a refreshing summer concept.\",\n    \"lyrics\": \"[Intro]\\n빠빠빠 빠빠빠\\n안녕!\\n\\n[Verse 1]\\n오늘 날씨가 너무 좋아\\n기분이 방방 뛰어올라\\n예쁜 원피스 입고서\\n너를 만나러 갈 거야\\n\\n[Pre-Chorus]\\n두근두근 설레는 맘\\n콩닥콩닥 심장 소리\\n\\n[Chorus]\\n사랑해 너를 사랑해\\n세상에서 제일 많이\\n달콤한 솜사탕처럼\\n너는 나의 전부야\\n사랑해 사랑해\\n빠빠빠 빠빠빠\\n\\n[Verse 2]\\n네가 웃으면 나도 웃어\\n네가 행복하면 나도 행복해\\n매일매일 함께하고 싶어\\n영원히 네 곁에 있을게\\n\\n[Pre-Chorus]\\n두근두근 설레는 맘\\n콩닥콩닥 심장 소리\\n\\n[Chorus]\\n사랑해 너를 사랑해\\n세상에서 제일 많이\\n달콤한 솜사탕처럼\\n너는 나의 전부야\\n\\n[Bridge]\\n라라라 랄랄라\\n너와 함께라면\\n매일이 행복해\\n\\n[Outro]\\n사랑해!\\n빠빠빠~\",\n    \"bpm\": 120,\n    \"duration\": 175,\n    \"keyscale\": \"F major\",\n    \"language\": \"ko\",\n    \"timesignature\": \"4\"\n}\n"
  },
  {
    "path": "examples/text2music/example_169.json",
    "content": "{\n    \"think\": true,\n    \"caption\": \"A chill Korean lo-fi hip-hop track with jazzy piano samples, vinyl crackle textures, and laid-back boom-bap drums. Features smooth male vocals with introspective rap verses about late-night thoughts and self-reflection.\",\n    \"lyrics\": \"[Intro]\\nYeah, 새벽 세시\\n잠이 안 와\\n\\n[Verse 1]\\n창밖엔 비가 내리고\\n방 안엔 음악이 흘러\\n생각이 많은 밤이야\\n펜을 들어 적어봐\\n지나간 시간들을\\n후회와 추억들을\\n\\n[Hook]\\n밤새 뒤척이며\\n생각에 잠겨\\n내일은 달라질까\\n아무도 몰라\\n\\n[Verse 2]\\n스물다섯 청춘이라지만\\n아직도 길을 찾는 중\\n어디로 가야 할지\\n뭘 해야 할지 몰라\\n그냥 오늘도 버텨\\n내일을 위해서\\n\\n[Hook]\\n밤새 뒤척이며\\n생각에 잠겨\\n내일은 달라질까\\n아무도 몰라\\n\\n[Outro]\\n괜찮아질 거야\\n언젠간...\",\n    \"bpm\": 78,\n    \"duration\": 200,\n    \"keyscale\": \"Db major\",\n    \"language\": \"ko\",\n    \"timesignature\": \"4\"\n}\n"
  },
  {
    "path": "examples/text2music/example_17.json",
    "content": "{\n    \"think\": true,\n    \"caption\": \"A melancholic piano melody opens over atmospheric pads, setting an introspective tone before a crisp lo-fi hip-hop beat enters with a deep sub-bass foundation. The lead male vocal is smooth and emotive, delivered with significant reverb that enhances its spacious quality. The arrangement builds dynamically into a powerful chorus where layered vocals soar over swelling synth strings and intensified drums. A brief bridge offers a moment of reflection with more sparse instrumentation before launching back into a climactic final chorus featuring passionate ad-libs and harmonies. The track concludes with fading ambient textures and lingering piano notes.\",\n    \"lyrics\": \"[Intro: Piano Arpeggio]\\n\\n[Verse 1]\\nFootsteps echo in the quiet night\\nA lamp flicker, casting cold light\\nShadows stretch long on the pavement below\\nWhat they say, I don't know\\n\\n[Pre-Chorus]\\nWhispers in the misty air\\nA promise made, left somewhere\\nWhoa\\n\\n[Chorus]\\nI've got dreams that fade, but they stay\\nLost in the glow of yesterday\\nWhoa\\nI'm chasing shadows in the rain\\nBut every step feels the same\\n\\n[Verse 2]\\nNeon signs hum their lonesome tune\\nThe sky painted dark, a fading moon\\nWindows fogged with stories untold\\nThis city's heart is icy cold\\n\\n[Pre-Chorus]\\nEvery corner hides a piece of me\\nA ghost of who I used to be\\nOh\\n\\n[Chorus]\\nI've got dreams that fade, but they stay\\nLost in the glow of yesterday\\nWhoa\\nI'm chasing shadows in the rain\\nBut every step feels the same\\n\\n[Outro]\\n[Piano arpeggio fades out]\",\n    \"bpm\": 100,\n    \"duration\": 185,\n    \"keyscale\": \"B♭ minor\",\n    \"language\": \"en\",\n    \"timesignature\": \"4\"\n}"
  },
  {
    "path": "examples/text2music/example_170.json",
    "content": "{\n    \"think\": true,\n    \"caption\": \"A powerful Korean rock anthem with distorted guitars, thundering drums, and aggressive bass lines. The male vocalist delivers rebellious lyrics with raw energy, featuring screaming high notes and a headbanging chorus.\",\n    \"lyrics\": \"[Intro]\\n\\n[Verse 1]\\n규칙 따윈 집어치워\\n남들 시선 신경 꺼\\n내 길은 내가 정해\\n누구도 막을 수 없어\\n\\n[Pre-Chorus]\\n불꽃처럼 타올라\\n멈추지 않을 거야\\n\\n[Chorus]\\n소리 질러 더 크게\\n세상을 깨워버려\\n우리는 멈추지 않아\\n끝까지 달려갈 거야\\nRock and roll!\\n\\n[Verse 2]\\n실패해도 괜찮아\\n다시 일어서면 돼\\n상처투성이여도\\n포기란 없어 우리에겐\\n\\n[Pre-Chorus]\\n불꽃처럼 타올라\\n멈추지 않을 거야\\n\\n[Chorus]\\n소리 질러 더 크게\\n세상을 깨워버려\\n우리는 멈추지 않아\\n끝까지 달려갈 거야\\n\\n[Guitar Solo]\\n\\n[Bridge]\\n자유를 외쳐\\n두려움을 버려\\n\\n[Outro]\\nRock and roll!\\n영원히!\",\n    \"bpm\": 140,\n    \"duration\": 210,\n    \"keyscale\": \"E minor\",\n    \"language\": \"ko\",\n    \"timesignature\": \"4\"\n}"
  },
  {
    "path": "examples/text2music/example_171.json",
    "content": "{\n    \"think\": true,\n    \"caption\": \"A sophisticated K-pop R&B track with smooth jazz influences, mellow Rhodes piano, and subtle trap percussion. The male duo delivers silky harmonies with falsetto runs, creating an intimate late-night vibe.\",\n    \"lyrics\": \"[Intro]\\nOoh yeah\\n오늘 밤\\n\\n[Verse 1]\\n조명이 꺼진 방 안에서\\n너의 향기가 맴돌아\\n시간이 멈춘 것 같아\\n이 순간 속에 갇혀\\n\\n[Pre-Chorus]\\n말하지 않아도 알아\\n네 눈빛만 봐도\\n\\n[Chorus]\\n너와 나 둘만의 시간\\n아무도 모르게\\n밤새 속삭여줄게\\n달콤한 말들을\\nBaby stay with me tonight\\n\\n[Verse 2]\\n네 손을 잡으면\\n심장이 빨라져\\n이런 느낌 처음이야\\n너라서 그런 거야\\n\\n[Chorus]\\n너와 나 둘만의 시간\\n아무도 모르게\\n밤새 속삭여줄게\\n달콤한 말들을\\n\\n[Bridge]\\n영원히 이 순간\\n멈춰있으면 좋겠어\\n\\n[Outro]\\nStay with me...\\nTonight...\",\n    \"bpm\": 82,\n    \"duration\": 215,\n    \"keyscale\": \"Ab major\",\n    \"language\": \"ko\",\n    \"timesignature\": \"4\"\n}\n"
  },
  {
    "path": "examples/text2music/example_172.json",
    "content": "{\n    \"think\": true,\n    \"caption\": \"An uplifting Korean graduation song with acoustic guitar strumming, warm piano chords, and gentle orchestral swells. Features a mixed choir of young voices delivering hopeful lyrics about friendship and new beginnings.\",\n    \"lyrics\": \"[Intro]\\n\\n[Verse 1]\\n함께 걸었던 이 길 위에서\\n우리 많이 웃고 울었지\\n교실 창가에 앉아서\\n꿈을 이야기했던 날들\\n\\n[Verse 2]\\n시험 끝나고 떡볶이 먹으며\\n밤새 수다 떨던 우리\\n그 시간들이 벌써\\n추억이 되어버렸네\\n\\n[Chorus]\\n안녕 친구야\\n고마웠어 함께해줘서\\n어디에 있든 잊지 마\\n우리의 약속을\\n다시 만날 그날까지\\n건강하게 잘 지내\\n\\n[Verse 3]\\n졸업장을 손에 들고\\n교문을 나서는 이 순간\\n눈물이 나려 해도\\n웃으며 인사할게\\n\\n[Chorus]\\n안녕 친구야\\n고마웠어 함께해줘서\\n어디에 있든 잊지 마\\n우리의 약속을\\n\\n[Bridge]\\n새로운 시작 앞에서\\n두렵지만 괜찮아\\n우리 함께니까\\n\\n[Outro]\\n안녕... 또 만나...\\n친구야...\",\n    \"bpm\": 76,\n    \"duration\": 219,\n    \"keyscale\": \"G major\",\n    \"language\": \"ko\",\n    \"timesignature\": \"4\"\n}"
  },
  {
    "path": "examples/text2music/example_173.json",
    "content": "{\n    \"think\": true,\n    \"caption\": \"A dramatic Korean musical theater ballad with Broadway-style orchestration, sweeping strings, and powerful brass. The female vocalist delivers theatrical high notes with operatic technique, expressing intense longing and determination.\",\n    \"lyrics\": \"[Intro]\\n\\n[Verse 1]\\n어둠 속에 홀로 서서\\n빛을 찾아 헤매이네\\n길을 잃은 이 마음이\\n어디로 가야 하는지\\n\\n[Verse 2]\\n수많은 시련 앞에서\\n무너질 것 같았지만\\n포기하지 않을 거야\\n끝까지 걸어갈 거야\\n\\n[Chorus]\\n나는 꿈을 꾸네\\n저 높은 곳을 향해\\n날개를 펼치고\\n하늘로 날아오르리\\n두려움을 넘어서\\n새로운 세상으로\\n\\n[Verse 3]\\n눈물로 밤을 지새워도\\n아침은 다시 오고\\n희망의 빛이 비추면\\n다시 일어설 수 있어\\n\\n[Chorus]\\n나는 꿈을 꾸네\\n저 높은 곳을 향해\\n날개를 펼치고\\n하늘로 날아오르리\\n\\n[Bridge]\\n이 순간을 위해\\n모든 걸 바쳤으니\\n\\n[Outro]\\n날아오르리... 높이...\",\n    \"bpm\": 70,\n    \"duration\": 210,\n    \"keyscale\": \"Eb major\",\n    \"language\": \"ko\",\n    \"timesignature\": \"4\"\n}"
  },
  {
    "path": "examples/text2music/example_174.json",
    "content": "{\n    \"think\": true,\n    \"caption\": \"A trendy K-pop dance track with tropical house influences, bright marimba melodies, and punchy sidechained synths. Features a catchy female vocal hook with whispered verses and an explosive drop chorus perfect for summer playlists.\",\n    \"lyrics\": \"[Intro]\\nHey hey hey\\n여름이 왔어\\n\\n[Verse 1]\\n뜨거운 태양 아래서\\n시원한 바다를 향해\\n달려가 자유롭게\\n오늘만큼은\\n\\n[Pre-Chorus]\\n걱정은 잠시 잊어\\n지금 이 순간만\\n\\n[Chorus]\\n여름밤 파도 소리\\n너와 함께 춤을 춰\\n별빛 아래서\\n영원히 이 순간\\nSummer night\\n\\n[Verse 2]\\n모래사장 위를 걸으며\\n손을 잡고 웃어봐\\n이 계절이 지나기 전에\\n추억을 만들자\\n\\n[Pre-Chorus]\\n걱정은 잠시 잊어\\n지금 이 순간만\\n\\n[Chorus]\\n여름밤 파도 소리\\n너와 함께 춤을 춰\\n별빛 아래서\\n영원히 이 순간\\n\\n[Bridge]\\nLa la la la\\n함께라면 어디든\\n\\n[Outro]\\nSummer night...\\n잊지 못할 거야\",\n    \"bpm\": 110,\n    \"duration\": 185,\n    \"keyscale\": \"B major\",\n    \"language\": \"ko\",\n    \"timesignature\": \"4\"\n}\n"
  },
  {
    "path": "examples/text2music/example_175.json",
    "content": "{\n    \"think\": true,\n    \"caption\": \"A heartfelt Korean folk ballad with traditional gayageum accents, acoustic guitar, and gentle percussion. The warm female vocalist delivers a nostalgic song about hometown memories with authentic Korean emotional expression.\",\n    \"lyrics\": \"[Intro]\\n\\n[Verse 1]\\n고향의 봄바람이\\n창문을 두드려\\n어릴 적 뛰놀던\\n그 들판이 그리워\\n\\n[Verse 2]\\n할머니 손잡고\\n시장에 가던 길\\n떡볶이 냄새가\\n아직도 생생해\\n\\n[Chorus]\\n돌아가고 싶어\\n그 시절 그 곳으로\\n엄마의 따뜻한 밥상\\n아버지의 미소\\n다시 볼 수 있다면\\n\\n[Verse 3]\\n기차를 타고서\\n떠나온 그날 밤\\n눈물을 삼키며\\n손 흔들었었지\\n\\n[Chorus]\\n돌아가고 싶어\\n그 시절 그 곳으로\\n엄마의 따뜻한 밥상\\n아버지의 미소\\n\\n[Bridge]\\n세월이 흘러도\\n변하지 않는 건\\n고향을 향한 마음\\n\\n[Outro]\\n보고 싶어... 고향이...\",\n    \"bpm\": 68,\n    \"duration\": 230,\n    \"keyscale\": \"D minor\",\n    \"language\": \"ko\",\n    \"timesignature\": \"3\"\n}"
  },
  {
    "path": "examples/text2music/example_176.json",
    "content": "{\n    \"think\": true,\n    \"caption\": \"A powerful industrial metal track with heavy distorted guitars, pounding drums, and aggressive male vocals in the style of Neue Deutsche Härte. The production features electronic elements layered with crushing riffs and a dark, intense atmosphere.\",\n    \"lyrics\": \"[Intro]\\n\\n[Verse 1]\\nFeuer brennt in meiner Brust\\nDunkelheit und wilde Lust\\nStahl und Eisen, Blut und Schweiß\\nMeine Seele brennt so heiß\\n\\n[Pre-Chorus]\\nWir sind die Kinder der Nacht\\nAus Asche und Glut gemacht\\n\\n[Chorus]\\nWir brennen! Wir brennen!\\nNichts kann uns trennen\\nWir brennen! Wir brennen!\\nDie Flammen werden uns erkennen\\n\\n[Verse 2]\\nDurch die Schatten geh ich blind\\nWo die dunklen Seelen sind\\nKeine Angst vor dem Verfall\\nIch erhebe mich aus dem All\\n\\n[Pre-Chorus]\\nWir sind die Kinder der Nacht\\nAus Asche und Glut gemacht\\n\\n[Chorus]\\nWir brennen! Wir brennen!\\nNichts kann uns trennen\\nWir brennen! Wir brennen!\\nDie Flammen werden uns erkennen\\n\\n[Bridge]\\nAus der Asche steigen wir empor\\nÖffnen weit das schwarze Tor\\nKeine Ketten halten uns\\nWir sind frei in diesem Bund\\n\\n[Chorus]\\nWir brennen! Wir brennen!\\nNichts kann uns trennen\\nWir brennen! Wir brennen!\\nDie Flammen werden uns erkennen\\n\\n[Outro]\\nWir brennen... wir brennen...\",\n    \"bpm\": 130,\n    \"duration\": 221,\n    \"keyscale\": \"D minor\",\n    \"language\": \"de\",\n    \"timesignature\": \"4\"\n}"
  },
  {
    "path": "examples/text2music/example_177.json",
    "content": "{\n    \"think\": true,\n    \"caption\": \"An upbeat Schlager pop song with catchy synthesizer melodies, cheerful brass sections, and a warm female vocal performance. The production is polished and radio-friendly with a danceable groove perfect for summer parties.\",\n    \"lyrics\": \"[Intro]\\nLa la la, la la la la\\n\\n[Verse 1]\\nDie Sonne scheint, der Himmel lacht\\nHeute wird die Nacht zum Tag gemacht\\nZieh dein schönstes Kleid an\\nDenn das Leben ist so wunderbar\\n\\n[Pre-Chorus]\\nVergiss die Sorgen, lass sie los\\nHeute Nacht wird einfach grandios\\n\\n[Chorus]\\nTanz mit mir durch diese Nacht\\nBis die Sonne wieder lacht\\nHalt mich fest und lass nicht los\\nDieses Gefühl ist einfach famos\\nTanz mit mir, tanz mit mir\\nIch bleib für immer hier bei dir\\n\\n[Verse 2]\\nDie Musik spielt, der Bass erklingt\\nJeder hier im Saal jetzt singt\\nNimm meine Hand, komm zu mir\\nDenn ich will nur tanzen hier mit dir\\n\\n[Pre-Chorus]\\nVergiss die Sorgen, lass sie los\\nHeute Nacht wird einfach grandios\\n\\n[Chorus]\\nTanz mit mir durch diese Nacht\\nBis die Sonne wieder lacht\\nHalt mich fest und lass nicht los\\nDieses Gefühl ist einfach famos\\nTanz mit mir, tanz mit mir\\nIch bleib für immer hier bei dir\\n\\n[Bridge]\\nEins, zwei, drei - wir sind dabei\\nVier, fünf, sechs - das ist der Reflex\\nSieben, acht - was für eine Nacht!\\n\\n[Chorus]\\nTanz mit mir durch diese Nacht\\nBis die Sonne wieder lacht\\nHalt mich fest und lass nicht los\\nDieses Gefühl ist einfach famos\\n\\n[Outro]\\nLa la la, la la la la\\nTanz mit mir... tanz mit mir...\",\n    \"bpm\": 128,\n    \"duration\": 198,\n    \"keyscale\": \"G major\",\n    \"language\": \"de\",\n    \"timesignature\": \"4\"\n}\n"
  },
  {
    "path": "examples/text2music/example_178.json",
    "content": "{\n    \"think\": true,\n    \"caption\": \"A melancholic German indie folk ballad featuring acoustic guitar fingerpicking, soft cello accompaniment, and intimate male vocals. The arrangement is sparse and emotional, creating a reflective atmosphere about lost love and memories.\",\n    \"lyrics\": \"[Intro]\\n\\n[Verse 1]\\nDer Herbstwind trägt die Blätter fort\\nWie Erinnerungen an einen fernen Ort\\nDein Lächeln seh ich noch vor mir\\nObwohl du längst nicht mehr bist hier\\n\\n[Verse 2]\\nDie alten Fotos an der Wand\\nErzählen von dem, was uns verband\\nJeder Moment, so kostbar und rein\\nWird für immer in mir sein\\n\\n[Chorus]\\nIch vermisse dich in jeder Nacht\\nWenn der Mond am Himmel wacht\\nDeine Stimme, dein Gesicht\\nVergessen kann ich dich nicht\\nVergessen kann ich dich nicht\\n\\n[Verse 3]\\nDie Straßen, die wir einst gegangen\\nSind voll von unserem Verlangen\\nJede Ecke, jeder Stein\\nErinnert mich an unser Sein\\n\\n[Chorus]\\nIch vermisse dich in jeder Nacht\\nWenn der Mond am Himmel wacht\\nDeine Stimme, dein Gesicht\\nVergessen kann ich dich nicht\\n\\n[Bridge]\\nVielleicht in einem anderen Leben\\nWird es ein Wiedersehen geben\\nBis dahin trag ich dich bei mir\\nIn meinem Herzen, für und für\\n\\n[Outro]\\nVergessen kann ich dich nicht...\\nVergessen kann ich dich nicht...\",\n    \"bpm\": 72,\n    \"duration\": 226,\n    \"keyscale\": \"A minor\",\n    \"language\": \"de\",\n    \"timesignature\": \"4\"\n}"
  },
  {
    "path": "examples/text2music/example_179.json",
    "content": "{\n    \"think\": true,\n    \"caption\": \"A high-energy German techno track with driving four-on-the-floor beats, pulsating basslines, and hypnotic synthesizer arpeggios. Features processed vocal samples and builds to an explosive drop, perfect for Berlin club nights.\",\n    \"lyrics\": \"[Intro]\\n\\n[Build-Up]\\nDie Nacht gehört uns\\nDie Nacht gehört uns\\nDie Nacht gehört uns allein\\n\\n[Drop]\\n\\n[Verse 1]\\nNeonlichter in der Dunkelheit\\nWir sind bereit, wir sind bereit\\nDer Bass durchdringt den ganzen Raum\\nDies ist kein Traum, dies ist kein Traum\\n\\n[Build-Up]\\nHände hoch! Lasst uns fliegen!\\nHeute Nacht werden wir siegen!\\nHände hoch! Lasst uns fliegen!\\n\\n[Drop]\\n\\n[Breakdown]\\nIn diesem Moment\\nSind wir eins\\nDie Musik verbindet uns\\nFür immer und ewig\\n\\n[Build-Up]\\nEins! Zwei! Drei! Vier!\\nAlle zusammen, alle hier!\\nEins! Zwei! Drei! Vier!\\n\\n[Drop]\\n\\n[Verse 2]\\nSchweißgetränkte Körper tanzen wild\\nDie Energie, sie ist so mild\\nBis zum Morgengrauen hier\\nDas ist unser Revier\\n\\n[Outro]\\nDie Nacht gehört uns...\\nDie Nacht gehört uns...\",\n    \"bpm\": 138,\n    \"duration\": 215,\n    \"keyscale\": \"F minor\",\n    \"language\": \"de\",\n    \"timesignature\": \"4\"\n}"
  },
  {
    "path": "examples/text2music/example_18.json",
    "content": "{\n    \"think\": true,\n    \"caption\": \"A clean, melodic electric guitar riff with a touch of chorus effect opens the track, establishing a catchy, looping motif. A male vocalist enters with a confident, rhythmic rap flow over a steady, mid-tempo hip-hop beat and a smooth bassline. The chorus elevates the energy with a more powerful, sung vocal delivery, punctuated by echoed, soaring ad-libs. The arrangement is built around the interplay between the crisp guitar and the dynamic vocal performance, which shifts between rapping and melodic singing. The track concludes with the initial guitar riff returning, accompanied by a whispered vocal, before fading to silence.\",\n    \"lyrics\": \"[Intro: Electric Guitar Melody]\\n\\n[Verse 1]\\nJCC的爱\\n是永不凋零的rose\\nJCC的爱\\n是永不凋零的rose\\nJCC的爱\\n是永不凋零的rose\\nJCC的爱\\n是永不凋零的rose\\n\\n[Pre-Chorus]\\nJCC的爱是永不凋零的rose\\nJCC的爱是永不凋零的rose\\nJCC的爱是永不凋零的rose\\nJCC的爱是永不凋零的rose\\n\\n[Chorus]\\nJCC的爱是永不凋零的rose\\nJCC的爱是永不凋零的rose\\nJCC的爱是永不凋零的rose\\nJCC的爱是永不凋零的rose\\nJCC的爱是永不凋零的rose\\nJCC的爱是永不凋零的rose\\nJCC的爱是永不凋零的rose\\nJCC的爱是永不凋零的rose\\n\\n[Verse 2]\\nJCC的爱是永不凋零的rose\\nJCC的爱是永不凋零的rose\\nJCC的爱是永不凋零的rose\\nJCC的爱是永不凋零的rose\\n\\n[Chorus]\\nJCC的爱是永不凋零的rose\\nJCC的爱是永不凋零的rose\\nJCC的爱是永不凋零的rose\\nJCC的爱是永不凋零的rose\\n\\n[Outro: Electric Guitar Melody]\\nJCC的rose\\nJCC的rose\",\n    \"bpm\": 100,\n    \"duration\": 175,\n    \"keyscale\": \"E minor\",\n    \"language\": \"zh\",\n    \"timesignature\": \"4\"\n}"
  },
  {
    "path": "examples/text2music/example_180.json",
    "content": "{\n    \"think\": true,\n    \"caption\": \"A nostalgic Neue Deutsche Welle track with vintage synthesizers, punchy drum machines, and quirky new wave guitar riffs. The male vocals are delivered with characteristic 80s German coolness and slight irony.\",\n    \"lyrics\": \"[Intro]\\n\\n[Verse 1]\\nIch steh am Fenster, schau hinaus\\nDie Stadt sieht heute anders aus\\nGraue Häuser, graue Wände\\nIch halt die Zukunft in den Händen\\n\\n[Pre-Chorus]\\nAlles dreht sich, alles bewegt sich\\nNichts bleibt wie es war\\n\\n[Chorus]\\nModerne Zeiten, moderne Welt\\nAlles was zählt ist nur das Geld\\nModerne Zeiten, kaltes Herz\\nIch mach daraus nur einen Scherz\\nHa! Ha! Ha!\\n\\n[Verse 2]\\nRoboter tanzen auf der Straße\\nIch trink Kaffee aus meiner Tasse\\nDie Maschinen übernehmen\\nWir müssen uns nicht mehr schämen\\n\\n[Pre-Chorus]\\nAlles dreht sich, alles bewegt sich\\nNichts bleibt wie es war\\n\\n[Chorus]\\nModerne Zeiten, moderne Welt\\nAlles was zählt ist nur das Geld\\nModerne Zeiten, kaltes Herz\\nIch mach daraus nur einen Scherz\\n\\n[Bridge]\\nPiep, piep, piep - der Computer spricht\\nBitte, bitte - vergiss mich nicht\\nKlick, klick, klick - die Maus bewegt sich\\nDoch mein Herz, das regt sich\\n\\n[Chorus]\\nModerne Zeiten, moderne Welt\\nAlles was zählt ist nur das Geld\\nModerne Zeiten, kaltes Herz\\nIch mach daraus nur einen Scherz\\n\\n[Outro]\\nHa! Ha! Ha!\\nModerne Zeiten...\",\n    \"bpm\": 122,\n    \"duration\": 215,\n    \"keyscale\": \"E minor\",\n    \"language\": \"de\",\n    \"timesignature\": \"4\"\n}"
  },
  {
    "path": "examples/text2music/example_181.json",
    "content": "{\n    \"think\": true,\n    \"caption\": \"A German hip-hop track with hard-hitting 808 bass, crisp hi-hats, and confident male rap vocals. The production blends modern trap elements with classic boom-bap influences, delivering street poetry about urban life.\",\n    \"lyrics\": \"[Intro]\\nYeah, yeah, Berlin City\\nHör zu, hör zu\\n\\n[Verse 1]\\nIch komm aus dem Block, wo die Träume entstehen\\nWo wir jeden Tag kämpfen, um weiterzugehen\\nBetonwüste, Graffiti an der Wand\\nDas ist mein Zuhause, das ist mein Land\\nVon unten nach oben, das ist der Plan\\nJeder Schritt nach vorn, ich bin der Mann\\nKeine Ausreden, keine Zeit zu verlieren\\nMit meinen Jungs werd ich triumphieren\\n\\n[Chorus]\\nWir kommen aus dem Nichts\\nAber geben niemals auf\\nDas Leben ist ein Kampf\\nWir nehmen unseren Lauf\\nStraßenpoesie, das ist unser Sound\\nBis wir ganz oben sind, Runde um Runde\\n\\n[Verse 2]\\nMama hat geweint, als ich nachts nicht kam\\nPapa war nicht da, also wurde ich zum Mann\\nJetzt schreib ich Reime, die die Seele berühren\\nMeine Worte werden dich durch die Nacht führen\\nEchte Geschichten, kein Fake, kein Schein\\nIch bleib mir treu, ich bleib allein\\nMit meinem Stift als Waffe in der Hand\\nSchreib ich Geschichte in diesem Land\\n\\n[Chorus]\\nWir kommen aus dem Nichts\\nAber geben niemals auf\\nDas Leben ist ein Kampf\\nWir nehmen unseren Lauf\\n\\n[Outro]\\nYeah... Berlin City...\\nFür immer real...\",\n    \"bpm\": 85,\n    \"duration\": 210,\n    \"keyscale\": \"G minor\",\n    \"language\": \"de\",\n    \"timesignature\": \"4\"\n}\n"
  },
  {
    "path": "examples/text2music/example_182.json",
    "content": "{\n    \"think\": true,\n    \"caption\": \"A traditional German folk song with accordion, acoustic guitar, and warm group vocals. The arrangement evokes Bavarian beer hall celebrations with a waltz rhythm and joyful, communal singing atmosphere.\",\n    \"lyrics\": \"[Intro]\\n\\n[Verse 1]\\nIn den Bergen, wo die Sonne lacht\\nWo der Enzian so schön erwacht\\nDa ist meine Heimat, da gehör ich hin\\nMit den Alpen fest im Sinn\\n\\n[Chorus]\\nProst! Auf die Heimat, auf das Land\\nMit dem Bierkrug in der Hand\\nWir singen laut, wir singen froh\\nIn Bayern ist das immer so\\nLa la la, la la la\\nIn Bayern ist das immer so\\n\\n[Verse 2]\\nDie Kühe grasen auf der Alm\\nDer Bauer singt den alten Psalm\\nDie Glocken läuten weit und breit\\nDas ist echte Seligkeit\\n\\n[Chorus]\\nProst! Auf die Heimat, auf das Land\\nMit dem Bierkrug in der Hand\\nWir singen laut, wir singen froh\\nIn Bayern ist das immer so\\n\\n[Bridge]\\nOb im Frühling oder Herbst\\nOb du lachst oder weinst\\nHier in unsren schönen Bergen\\nBist du niemals ganz allein\\n\\n[Verse 3]\\nWenn der Abend kommt so still\\nUnd die Musik erklingen will\\nDann stoßen wir zusammen an\\nAuf alles, was noch kommen kann\\n\\n[Chorus]\\nProst! Auf die Heimat, auf das Land\\nMit dem Bierkrug in der Hand\\nWir singen laut, wir singen froh\\nIn Bayern ist das immer so\\n\\n[Outro]\\nLa la la, la la la...\",\n    \"bpm\": 95,\n    \"duration\": 195,\n    \"keyscale\": \"D major\",\n    \"language\": \"de\",\n    \"timesignature\": \"3\"\n}"
  },
  {
    "path": "examples/text2music/example_183.json",
    "content": "{\n    \"think\": true,\n    \"caption\": \"An emotional German power ballad with soaring orchestral strings, grand piano, and a passionate female vocal performance. The song builds from intimate verses to an explosive, anthemic chorus about eternal love.\",\n    \"lyrics\": \"[Intro]\\n\\n[Verse 1]\\nAls ich dich zum ersten Mal sah\\nWusste ich, dass es Schicksal war\\nDeine Augen, tief wie das Meer\\nSeitdem lieb ich dich so sehr\\n\\n[Verse 2]\\nDurch die Stürme, durch die Zeit\\nWar mein Herz für dich bereit\\nJede Träne, jeder Schmerz\\nFührte mich zu deinem Herz\\n\\n[Chorus]\\nFür immer und ewig, nur du und ich\\nMeine Seele brennt unsterblich\\nKein Sturm kann uns zerbrechen\\nKeine Macht kann uns schwächen\\nFür immer und ewig, das schwör ich dir\\nMeine Liebe gehört nur dir\\n\\n[Verse 3]\\nWenn die Welt um uns zerfällt\\nBist du alles, was mich hält\\nIn der Dunkelheit mein Licht\\nOhne dich leb ich nicht\\n\\n[Chorus]\\nFür immer und ewig, nur du und ich\\nMeine Seele brennt unsterblich\\nKein Sturm kann uns zerbrechen\\nKeine Macht kann uns schwächen\\nFür immer und ewig, das schwör ich dir\\nMeine Liebe gehört nur dir\\n\\n[Bridge]\\nUnd wenn der letzte Tag anbricht\\nVergess ich deine Liebe nicht\\nÜber alle Grenzen hinaus\\nFindest du mich, ich find dich raus\\n\\n[Final Chorus]\\nFür immer und ewig, nur du und ich\\nMeine Seele brennt unsterblich\\nFür immer... und ewig...\\n\\n[Outro]\",\n    \"bpm\": 68,\n    \"duration\": 201,\n    \"keyscale\": \"Eb major\",\n    \"language\": \"de\",\n    \"timesignature\": \"4\"\n}"
  },
  {
    "path": "examples/text2music/example_184.json",
    "content": "{\n    \"think\": true,\n    \"caption\": \"An energetic German punk rock anthem with fast distorted guitars, driving drums, and raw, shouted male vocals. The production is deliberately rough and aggressive, capturing youthful rebellion and anti-establishment sentiment.\",\n    \"lyrics\": \"[Intro]\\n\\nEins, zwei, drei, vier!\\n\\n[Verse 1]\\nSie sagen uns, was wir tun sollen\\nAber wir machen, was wir wollen\\nIhre Regeln sind uns egal\\nWir leben ohne ihre Qual\\n\\n[Pre-Chorus]\\nKeine Kompromisse, kein Zurück\\nDas hier ist unser Augenblick\\n\\n[Chorus]\\nWir sind laut! Wir sind frei!\\nScheißegal, was morgen sei!\\nWir sind laut! Wir sind hier!\\nNiemand nimmt das je von mir!\\nHey! Hey! Hey!\\n\\n[Verse 2]\\nDie Anzugträger in der Stadt\\nHaben uns schon lange satt\\nDoch wir schreien immer weiter\\nKlettern hoch auf ihrer Leiter\\n\\n[Pre-Chorus]\\nKeine Kompromisse, kein Zurück\\nDas hier ist unser Augenblick\\n\\n[Chorus]\\nWir sind laut! Wir sind frei!\\nScheißegal, was morgen sei!\\nWir sind laut! Wir sind hier!\\nNiemand nimmt das je von mir!\\n\\n[Bridge]\\nSie können uns nicht brechen\\nSie können uns nicht stoppen\\nWir werden weitermachen\\nBis ihre Mauern fallen!\\n\\n[Chorus]\\nWir sind laut! Wir sind frei!\\nScheißegal, was morgen sei!\\nWir sind laut! Wir sind hier!\\nNiemand nimmt das je von mir!\\n\\n[Outro]\\nHey! Hey! Hey!\\nWir sind frei!\",\n    \"bpm\": 175,\n    \"duration\": 168,\n    \"keyscale\": \"E major\",\n    \"language\": \"de\",\n    \"timesignature\": \"4\"\n}"
  },
  {
    "path": "examples/text2music/example_185.json",
    "content": "{\n    \"think\": true,\n    \"caption\": \"A dreamy German synth-pop track with lush synthesizer pads, arpeggiated sequences, and ethereal female vocals. The production has a nostalgic 80s feel with modern polish, exploring themes of longing and escape.\",\n    \"lyrics\": \"[Intro]\\n\\n[Verse 1]\\nMitternacht, die Stadt schläft ein\\nNur die Sterne und ich allein\\nIch träume mich so weit weg\\nAn einen geheimen Fleck\\n\\n[Pre-Chorus]\\nWo die Zeit still steht\\nUnd der Wind sanft weht\\n\\n[Chorus]\\nNimm mich mit in die Unendlichkeit\\nWo nichts mehr wehtut, wo nichts mehr schreit\\nNimm mich mit, lass uns fliegen\\nÜber Wolken, über Kriegen\\nIn die Unendlichkeit\\n\\n[Verse 2]\\nLichtermeer am Horizont\\nEin Gefühl, das sich lohnt\\nIch schließe meine Augen zu\\nUnd finde endlich Ruh\\n\\n[Pre-Chorus]\\nWo die Zeit still steht\\nUnd der Wind sanft weht\\n\\n[Chorus]\\nNimm mich mit in die Unendlichkeit\\nWo nichts mehr wehtut, wo nichts mehr schreit\\nNimm mich mit, lass uns fliegen\\nÜber Wolken, über Kriegen\\n\\n[Bridge]\\nSchwerelos durch Raum und Zeit\\nBin ich endlich frei, so weit\\nKeine Grenzen, keine Mauern\\nNur das Glück wird ewig dauern\\n\\n[Outro]\\nIn die Unendlichkeit...\\nIn die Unendlichkeit...\",\n    \"bpm\": 110,\n    \"duration\": 211,\n    \"keyscale\": \"C# minor\",\n    \"language\": \"de\",\n    \"timesignature\": \"4\"\n}"
  },
  {
    "path": "examples/text2music/example_186.json",
    "content": "{\n    \"think\": true,\n    \"caption\": \"A groovy German funk-pop track with slap bass, wah-wah guitar, tight horn sections, and smooth male vocals. The production is warm and danceable with a retro 70s disco influence and feel-good summer vibes.\",\n    \"lyrics\": \"[Intro]\\n\\nUh! Yeah! Komm schon!\\n\\n[Verse 1]\\nFreitagabend, die Woche ist vorbei\\nZieh mich an, ich bin dabei\\nDisco-Kugel dreht sich rund\\nHeute Nacht wird's kunterbunt\\n\\n[Pre-Chorus]\\nDer Groove geht in die Beine\\nIch tanz heut nicht alleine\\n\\n[Chorus]\\nBeweg deinen Körper, links und rechts\\nHeute Nacht wird alles echt\\nFunk it up, lass dich gehen\\nWir werden die Sonne aufgehen sehen\\nFunk it up! Funk it up!\\nYeah!\\n\\n[Verse 2]\\nDie Band spielt tight, der Sound ist fett\\nJeder hier hat Style, ich wett\\nSchweiß auf der Stirn, Glanz im Blick\\nDas ist unser Augenblick\\n\\n[Pre-Chorus]\\nDer Groove geht in die Beine\\nIch tanz heut nicht alleine\\n\\n[Chorus]\\nBeweg deinen Körper, links und rechts\\nHeute Nacht wird alles echt\\nFunk it up, lass dich gehen\\nWir werden die Sonne aufgehen sehen\\n\\n[Bridge]\\nBass! Drums! Gitarre! Horn!\\nAlle zusammen, niemand verlorn\\nEins! Zwei! Eins, zwei, drei!\\nMach dich frei!\\n\\n[Outro]\\nFunk it up! Funk it up!\\nYeah, yeah, yeah...\",\n    \"bpm\": 115,\n    \"duration\": 225,\n    \"keyscale\": \"Bb major\",\n    \"language\": \"de\",\n    \"timesignature\": \"4\"\n}"
  },
  {
    "path": "examples/text2music/example_187.json",
    "content": "{\n    \"think\": true,\n    \"caption\": \"A melancholic German singer-songwriter track with fingerpicked acoustic guitar, subtle piano, and heartfelt female vocals. The intimate production captures the pain of heartbreak and the journey toward healing.\",\n    \"lyrics\": \"[Intro]\\n\\n[Verse 1]\\nDu hast gesagt, du bleibst für immer\\nDoch für immer war nur ein Schimmer\\nJetzt steh ich hier im leeren Raum\\nUnd wach auf aus dem schönsten Traum\\n\\n[Verse 2]\\nDeine Sachen sind noch hier\\nDein Geruch klebt noch an mir\\nJedes Lied erinnert mich\\nAn das, was war zwischen dir und mich\\n\\n[Chorus]\\nGebrochenes Herz, lern wieder zu schlagen\\nGebrochenes Herz, hör auf zu klagen\\nIrgendwann wird es nicht mehr wehtun\\nIrgendwann kann ich wieder ruhn\\n\\n[Verse 3]\\nDie Fotos hab ich weggepackt\\nDie Erinnerung bleibt intakt\\nSchritt für Schritt geh ich voran\\nAuch wenn ich dich nicht vergessen kann\\n\\n[Chorus]\\nGebrochenes Herz, lern wieder zu schlagen\\nGebrochenes Herz, hör auf zu klagen\\nIrgendwann wird es nicht mehr wehtun\\nIrgendwann kann ich wieder ruhn\\n\\n[Bridge]\\nVielleicht war es nicht bestimmt\\nVielleicht hat die Zeit es nimmt\\nWas auch immer kommen mag\\nIch steh auf, Tag für Tag\\n\\n[Outro]\\nGebrochenes Herz...\\nLern wieder zu schlagen...\",\n    \"bpm\": 78,\n    \"duration\": 235,\n    \"keyscale\": \"F# minor\",\n    \"language\": \"de\",\n    \"timesignature\": \"4\"\n}"
  },
  {
    "path": "examples/text2music/example_188.json",
    "content": "{\n    \"think\": true,\n    \"caption\": \"A dramatic German gothic rock track with dark atmospheric guitars, thundering drums, and theatrical male vocals. The production blends orchestral elements with heavy rock, creating an epic and mysterious soundscape.\",\n    \"lyrics\": \"[Intro]\\n\\n[Verse 1]\\nIn den Schatten der alten Burg\\nWo die Zeit so langsam ging\\nHör ich Stimmen aus der Nacht\\nDie mich rufen, die mich fangen\\n\\n[Verse 2]\\nKerzen flackern an der Wand\\nKalter Wind aus fernem Land\\nDie Geister tanzen ihren Tanz\\nIm fahlen Mondenschein so ganz\\n\\n[Chorus]\\nKinder der Dunkelheit\\nGefangen in der Ewigkeit\\nWir wandeln zwischen den Welten\\nWo Licht und Schatten sich melden\\nKinder der Dunkelheit\\n\\n[Verse 3]\\nRaben kreisen überm Turm\\nVor dem großen, letzten Sturm\\nDas Schicksal ist besiegelt nun\\nEs gibt nichts mehr zu tun\\n\\n[Chorus]\\nKinder der Dunkelheit\\nGefangen in der Ewigkeit\\nWir wandeln zwischen den Welten\\nWo Licht und Schatten sich melden\\n\\n[Bridge]\\nDurch die Nebel, durch die Zeit\\nSind wir zum Kampf bereit\\nUnsterblich ist die Nacht\\nDie uns hierher gebracht\\n\\n[Outro]\\nKinder der Dunkelheit...\",\n    \"bpm\": 92,\n    \"duration\": 202,\n    \"keyscale\": \"B minor\",\n    \"language\": \"de\",\n    \"timesignature\": \"4\"\n}"
  },
  {
    "path": "examples/text2music/example_189.json",
    "content": "{\n    \"think\": true,\n    \"caption\": \"A classic chanson française ballad with warm acoustic guitar, gentle piano accompaniment, and a melancholic string section. The male vocalist delivers the lyrics with a tender, romantic crooner style reminiscent of Jacques Brel, building emotional intensity through the chorus.\",\n    \"lyrics\": \"[Intro]\\n\\n[Verse 1]\\nSous les lumières de Paris\\nJe marche seul dans la nuit\\nTon parfum flotte encore ici\\nDans chaque rue, dans chaque pluie\\n\\n[Verse 2]\\nLes cafés ferment leurs portes\\nLes souvenirs me transportent\\nVers ces jours où tu étais là\\nOù ton sourire éclairait mes pas\\n\\n[Chorus]\\nEt je t'attends, je t'attends encore\\nAu coin de rue où battait mon cœur\\nEt je t'attends, jusqu'à l'aurore\\nDans ce Paris qui pleure ta douceur\\n\\n[Verse 3]\\nLa Seine coule doucement\\nEmportant tous nos serments\\nMais ton image reste gravée\\nDans mon âme à jamais\\n\\n[Chorus]\\nEt je t'attends, je t'attends encore\\nAu coin de rue où battait mon cœur\\nEt je t'attends, jusqu'à l'aurore\\nDans ce Paris qui pleure ta douceur\\n\\n[Bridge]\\nLes étoiles sont témoins\\nDe cet amour sans fin\\nQui brûle encore en moi\\nMalgré le froid\\n\\n[Outro]\\nSous les lumières de Paris\\nJe t'attendrai toute ma vie...\",\n    \"bpm\": 72,\n    \"duration\": 206,\n    \"keyscale\": \"A minor\",\n    \"language\": \"fr\",\n    \"timesignature\": \"4\"\n}"
  },
  {
    "path": "examples/text2music/example_19.json",
    "content": "{\n    \"think\": true,\n    \"caption\": \"A classic boom-bap hip-hop track built on a steady drum machine groove and a prominent, funky bassline. A clean electric guitar plays a recurring melodic riff and chords, giving the song a slightly jazzy, contemplative feel. The lead vocal is a male rapper delivering a clear, narrative-driven story in French. The choruses introduce layered, harmonized male vocals that add a melodic and slightly melancholic dimension. The track concludes with a spoken-word outro over the fading instrumental, reinforcing the song's humorous and relatable theme.\",\n    \"lyrics\": \"[Intro]\\nYo, écoute l'histoire de Cécile 8\\nLa femme du crocodile\\nElle achète pas du pain mais du vernis sans malice\\nQuand elle passe, ça devient trop pire, trop radical\\nElle préfère des roupettes, c'est pas méchant, c'est capital\\n\\n[Verse 1]\\nSa femme se fait des coups par trois équipes sévères\\nMais quand elle sort, c'est pas des coups mais des bières\\nElle a montré un CV, pas un collègue à l'école\\nElle a frappé le premier, dit que c'était du mollo sans bol\\n\\n[Chorus]\\nCécile 8 est ma muse, elle a le front censé clair\\nMais derrière ses lunettes, y'a que des bonnes affaires\\nCécile 8 est ma muse, elle a le front censé clair\\nMais derrière ses lunettes, y'a que des bonnes affaires\\n\\n[Verse 2]\\nUn soir elle s'est fait pousser, trois pierres de regards\\nElle l'a pris pour une coquée, pas le genre de fille qui s'égare\\nMais dans la cour, elle court, se balade sur le trottoir\\nElle traque ses fichiers bidons comme un dandy sans espoir\\nElle a vu l'argent du renouveau, pas la galère\\nMais dans la cour elle plane comme un résidu dans la mer\\nCertains s'excusent du bien avec leurs valises\\nMais moi ce que je veux, c'est des billets frits en vitrine\\n\\n[Chorus]\\nCécile 8 est ma muse, elle a le front censé clair\\nMais derrière ses lunettes, y'a que des bonnes affaires\\nCécile 8 est ma muse, elle a le front censé clair\\nMais derrière ses lunettes, y'a que des bonnes affaires\\n\\n[Bridge]\\nL'argent monte à l'eau mais c'est du cocaïne\\nElle veut des femmes en trop mais c'est pas l'amour qui gagne\\nLes romans partent plus tard, elle compte des milliers\\nUn service de boulot, c'est pas ce qu'elle veut pour les oubliés\\nLe seul travail qui paye, c'est la richesse du décor\\nLe seul job qu'elle trouve, c'est lui même en cas de mort\\nElle arrive à la porte, amour que reine sa libido\\nCe mec, t'as capté ? C'est du vin dans ton vino, mon amigo\\n\\n[Verse 3]\\nSon bar tabou, Sécile 8 au premier virage\\nElle s'installe dans le théâtre, love dans le carnage\\nMais la seule vérité, c'est qu'elle fait pas le bien\\nElle veut voler, elle veut ça, sans jamais aller loin\\n\\n[Chorus]\\nCécile 8 est ma muse, elle a le front censé clair\\nMais derrière ses lunettes, y'a que des bonnes affaires\\nCécile 8 est ma muse, elle a le front censé clair\\nMais derrière ses lunettes, y'a que des bonnes affaires\\n\\n[Outro]\\nYo, et dans le chill, y'a des flammes à manger\\nMais Cécile 8, elle peut pas les oublier\\nElle rêve de biff ou d'un voyage loin d'ici\\nUn jour, je dirai ce que j'ai déjà pris\\nC'est pas l'amour, c'est un carnaval\\nUn jour, elle verra, je suis pas ton carnaval\\nCecile 8, la fille du coin dans la vie\\nTu dois courir après l'argent ou mourir pour la justice\\nCécile 8, la femme du crocodile\\nElle aime, elle craint, mais elle veut son style\\nCécile 8, la femme du crocodile\\nElle aime, elle craint, mais elle veut son style\\nCécile 8, la femme du crocodile\\nElle aime, elle craint, mais elle veut son style\\nCecile 8, la femme du crocodile\\nElle aime, elle craint, mais elle veut son style\",\n    \"bpm\": 200,\n    \"duration\": 213,\n    \"keyscale\": \"D minor\",\n    \"language\": \"fr\",\n    \"timesignature\": \"4\"\n}"
  },
  {
    "path": "examples/text2music/example_190.json",
    "content": "{\n    \"think\": true,\n    \"caption\": \"An energetic French house track with pulsating synthesizers, four-on-the-floor beats, and filtered disco samples. Features a female vocalist with a breathy, seductive delivery over driving electronic production with classic Daft Punk-inspired vocoder effects.\",\n    \"lyrics\": \"[Intro]\\n\\n[Verse 1]\\nCe soir on danse jusqu'au bout\\nLes néons brillent partout\\nLa musique dans nos veines\\nOn oublie toutes nos peines\\n\\n[Pre-Chorus]\\nPlus rien ne peut nous arrêter\\nLa nuit est faite pour rêver\\n\\n[Chorus]\\nDanse avec moi, danse avec moi\\nSous les étoiles, il n'y a que toi\\nDanse avec moi, danse avec moi\\nCette nuit magique n'appartient qu'à nous\\n\\n[Verse 2]\\nLes basses font trembler le sol\\nTon corps devient mon idole\\nDans cette foule électrique\\nNotre amour est magnifique\\n\\n[Pre-Chorus]\\nPlus rien ne peut nous arrêter\\nLa nuit est faite pour rêver\\n\\n[Chorus]\\nDanse avec moi, danse avec moi\\nSous les étoiles, il n'y a que toi\\nDanse avec moi, danse avec moi\\nCette nuit magique n'appartient qu'à nous\\n\\n[Bridge]\\n\\nUn, deux, trois, quatre\\nOn va tout casser\\nUn, deux, trois, quatre\\nJamais s'arrêter\\n\\n[Drop]\\n\\n[Outro]\\nDanse avec moi...\\nDanse avec moi...\",\n    \"bpm\": 124,\n    \"duration\": 210,\n    \"keyscale\": \"F minor\",\n    \"language\": \"fr\",\n    \"timesignature\": \"4\"\n}"
  },
  {
    "path": "examples/text2music/example_191.json",
    "content": "{\n    \"think\": true,\n    \"caption\": \"A hard-hitting French hip-hop track with booming 808 bass, crisp trap hi-hats, and dark atmospheric pads. The male rapper delivers aggressive verses with sharp wordplay and social commentary, switching between rapid-fire flows and melodic hooks.\",\n    \"lyrics\": \"[Intro]\\n\\nYeah, ouais, c'est le son de la rue\\n\\n[Verse 1]\\nJe viens des quartiers où personne nous écoute\\nOù les rêves se brisent au bout de chaque route\\nMais j'ai la plume comme arme, les mots comme bouclier\\nJe raconte ma vie, pas besoin de tricher\\nDans le béton gris, on a grandi trop vite\\nLes sirènes la nuit, c'était notre berceuse maudite\\nMais regarde-moi maintenant, debout, fier\\nJe transforme la douleur en or, en lumière\\n\\n[Chorus]\\nOn vient de loin, on ira plus loin encore\\nLa rue dans le sang, le succès dans le corps\\nOn vient de loin, ils ne nous arrêteront pas\\nChaque obstacle franchi nous rend plus forts que ça\\n\\n[Verse 2]\\nMaman travaillait dur pour qu'on mange à notre faim\\nPapa absent, j'ai dû devenir un homme trop tôt le matin\\nLes frères au coin de la rue, certains sont partis\\nD'autres enfermés, la vie les a trahis\\nMais moi j'ai choisi le micro, pas le vice\\nMa voix porte leur histoire, leur sacrifice\\n\\n[Chorus]\\nOn vient de loin, on ira plus loin encore\\nLa rue dans le sang, le succès dans le corps\\n\\n[Outro]\\nPour tous ceux qui galèrent, tenez bon\\nLa lumière arrive, c'est notre saison\",\n    \"bpm\": 140,\n    \"duration\": 195,\n    \"keyscale\": \"D minor\",\n    \"language\": \"fr\",\n    \"timesignature\": \"4\"\n}"
  },
  {
    "path": "examples/text2music/example_192.json",
    "content": "{\n    \"think\": true,\n    \"caption\": \"A nostalgic yé-yé style pop song with jangly guitars, tambourine, and vintage organ sounds reminiscent of 1960s French pop. The female vocalist sings with youthful exuberance and innocent charm, capturing the carefree spirit of the era.\",\n    \"lyrics\": \"[Intro]\\n\\nLa la la, la la la la\\n\\n[Verse 1]\\nC'est l'été, le soleil brille\\nJe mets ma plus jolie robe à fleurs\\nDans la rue, les garçons sifflent\\nMais moi je n'ai qu'un seul dans le cœur\\n\\n[Verse 2]\\nIl m'attend au café du coin\\nAvec son sourire charmant\\nQuand il me prend par la main\\nJe me sens voler dans le vent\\n\\n[Chorus]\\nOh mon cœur fait boum boum boum\\nQuand je le vois arriver\\nMon cœur fait boum boum boum\\nJe crois que je suis tombée\\nAmoureuse, amoureuse\\nDe ses yeux, de sa voix\\nAmoureuse, amoureuse\\nIl n'y a que lui pour moi\\n\\n[Verse 3]\\nOn danse le twist sur la plage\\nOn mange des glaces au citron\\nÀ dix-sept ans, c'est le bel âge\\nL'amour est notre seule raison\\n\\n[Chorus]\\nOh mon cœur fait boum boum boum\\nQuand je le vois arriver\\nMon cœur fait boum boum boum\\nJe crois que je suis tombée\\nAmoureuse, amoureuse\\n\\n[Bridge]\\nLes copines sont jalouses\\nMais je m'en fiche bien\\nCar sa bouche est si douce\\nQuand elle touche la mienne\\n\\n[Outro]\\nLa la la, la la la la\\nAmoureuse...\\nLa la la, la la la la\",\n    \"bpm\": 138,\n    \"duration\": 175,\n    \"keyscale\": \"G major\",\n    \"language\": \"fr\",\n    \"timesignature\": \"4\"\n}"
  },
  {
    "path": "examples/text2music/example_193.json",
    "content": "{\n    \"think\": true,\n    \"caption\": \"A smoky French jazz ballad featuring brushed drums, upright bass, and warm piano chords. The female vocalist delivers the lyrics with a sultry, intimate tone reminiscent of classic jazz singers, with subtle brass accents adding depth to the arrangement.\",\n    \"lyrics\": \"[Intro]\\n\\n[Verse 1]\\nLa fumée des cigarettes\\nS'élève dans le bar\\nTu me regardes, je suis prête\\nÀ tomber dans le noir\\n\\n[Verse 2]\\nTon whisky sur la table\\nMes lèvres sur le verre\\nCet instant est improbable\\nMais tellement sincère\\n\\n[Chorus]\\nViens plus près, encore plus près\\nMurmure-moi des secrets\\nDans cette nuit de velours\\nInventons notre amour\\n\\n[Verse 3]\\nLe saxo pleure doucement\\nComme mon cœur ce soir\\nJe me perds dans tes yeux blancs\\nDans ton regard si noir\\n\\n[Chorus]\\nViens plus près, encore plus près\\nMurmure-moi des secrets\\nDans cette nuit de velours\\nInventons notre amour\\n\\n[Bridge]\\nLe temps s'arrête ici\\nEntre deux notes de blues\\nTa main cherche la mienne\\nJe n'ai plus rien à perdre\\n\\n[Outro]\\n\\nViens plus près...\\nEncore plus près...\",\n    \"bpm\": 68,\n    \"duration\": 200,\n    \"keyscale\": \"Bb major\",\n    \"language\": \"fr\",\n    \"timesignature\": \"4\"\n}"
  },
  {
    "path": "examples/text2music/example_194.json",
    "content": "{\n    \"think\": true,\n    \"caption\": \"A driving French rock anthem with distorted electric guitars, powerful drums, and aggressive bass lines. The male vocalist delivers passionate, rebellious lyrics with raw energy, building to explosive choruses with gang vocals and anthemic hooks.\",\n    \"lyrics\": \"[Intro]\\n\\n[Verse 1]\\nIls nous disent de nous taire\\nDe baisser les yeux\\nMais on en a rien à faire\\nOn veut toucher les cieux\\n\\n[Verse 2]\\nDans cette société\\nQui nous veut à genoux\\nOn refuse de plier\\nOn reste debout, c'est tout\\n\\n[Chorus]\\nRévolution dans nos têtes\\nOn ne sera jamais leurs marionnettes\\nRévolution dans nos cœurs\\nOn transforme la rage en ardeur\\nOh oh oh, on lâche rien\\nOh oh oh, jusqu'à la fin\\n\\n[Verse 3]\\nLes murs sont faits pour tomber\\nLes chaînes pour se briser\\nNotre voix va résonner\\nJusqu'à les faire trembler\\n\\n[Chorus]\\nRévolution dans nos têtes\\nOn ne sera jamais leurs marionnettes\\nRévolution dans nos cœurs\\nOn transforme la rage en ardeur\\n\\n[Bridge]\\n\\nUn pour tous, tous pour un\\nNotre combat n'a pas de fin\\nUn pour tous, tous pour un\\n\\n[Outro]\\nRévolution!\\nRévolution!\",\n    \"bpm\": 155,\n    \"duration\": 185,\n    \"keyscale\": \"E minor\",\n    \"language\": \"fr\",\n    \"timesignature\": \"4\"\n}"
  },
  {
    "path": "examples/text2music/example_195.json",
    "content": "{\n    \"think\": true,\n    \"caption\": \"A dreamy French indie pop song with shimmering synth arpeggios, soft electronic beats, and reverb-drenched guitars. The female vocalist sings with an ethereal, whispery quality, creating an atmospheric and introspective mood throughout the track.\",\n    \"lyrics\": \"[Intro]\\n\\n[Verse 1]\\nJe flotte entre les nuages\\nDans un rêve éveillé\\nTon visage en mirage\\nQue je ne peux toucher\\n\\n[Verse 2]\\nLes heures passent comme l'eau\\nJe perds la notion du temps\\nDans ce monde si beau\\nOù tout est différent\\n\\n[Chorus]\\nEst-ce que tu m'entends\\nDe l'autre côté du vent\\nEst-ce que tu me vois\\nQuand je tends les bras vers toi\\nDans ce rêve infini\\nOù nos âmes sont unies\\n\\n[Verse 3]\\nLes couleurs se mélangent\\nLe ciel devient la mer\\nDans ce monde étrange\\nPlus rien n'est éphémère\\n\\n[Chorus]\\nEst-ce que tu m'entends\\nDe l'autre côté du vent\\nEst-ce que tu me vois\\nQuand je tends les bras vers toi\\n\\n[Bridge]\\nJe ne veux pas me réveiller\\nJe veux rester ici\\nDans cette éternité\\nAvec toi, loin d'ici\\n\\n[Outro]\\n\\nEst-ce que tu m'entends...\",\n    \"bpm\": 95,\n    \"duration\": 230,\n    \"keyscale\": \"C major\",\n    \"language\": \"fr\",\n    \"timesignature\": \"4\"\n}"
  },
  {
    "path": "examples/text2music/example_196.json",
    "content": "{\n    \"think\": true,\n    \"caption\": \"A traditional French waltz with accordion, violin, and acoustic guitar creating an authentic Parisian atmosphere. The male vocalist sings with nostalgic warmth and theatrical flair, evoking images of cobblestone streets and riverside cafés.\",\n    \"lyrics\": \"[Intro]\\n\\n[Verse 1]\\nSur les quais de la Seine\\nOù les amoureux se promènent\\nJe revois ton sourire\\nQui me faisait tant frémir\\n\\n[Verse 2]\\nLes bouquinistes ferment\\nLe soir tombe sur Paris\\nMais dans mon cœur bohème\\nTu restes mon seul abri\\n\\n[Chorus]\\nValse, valse avec moi\\nSous le pont des Arts\\nValse, valse avec moi\\nAvant qu'il soit trop tard\\nLa vie est si courte\\nL'amour est si grand\\nValse, valse avec moi\\nComme au premier temps\\n\\n[Verse 3]\\nLes réverbères s'allument\\nSur le pavé mouillé\\nDans la douce amertume\\nDe nos baisers volés\\n\\n[Chorus]\\nValse, valse avec moi\\nSous le pont des Arts\\nValse, valse avec moi\\nAvant qu'il soit trop tard\\n\\n[Bridge]\\nMontmartre nous attend\\nAvec ses peintres et ses rêves\\nDans ce Paris d'antan\\nQue notre amour achève\\n\\n[Outro]\\n\\nValse avec moi...\",\n    \"bpm\": 88,\n    \"duration\": 200,\n    \"keyscale\": \"D major\",\n    \"language\": \"fr\",\n    \"timesignature\": \"3\"\n}"
  },
  {
    "path": "examples/text2music/example_197.json",
    "content": "{\n    \"think\": true,\n    \"caption\": \"A melancholic French pop ballad with piano-driven arrangement, subtle strings, and emotional dynamics. The female vocalist delivers a powerful performance about heartbreak, building from intimate verses to soaring, cathartic choruses.\",\n    \"lyrics\": \"[Intro]\\n\\n[Verse 1]\\nTu as pris tes valises\\nSans même dire au revoir\\nLa maison est si grise\\nDepuis ce soir de désespoir\\n\\n[Verse 2]\\nTes photos sur les murs\\nMe regardent en silence\\nChaque seconde est si dure\\nDans cette immense absence\\n\\n[Chorus]\\nComment vivre sans toi\\nQuand tout me rappelle nous\\nComment croire encore\\nQuand l'amour nous rend fous\\nJe cherche ton ombre\\nDans chaque recoin\\nMais tu n'es plus là\\nEt je sombre\\n\\n[Verse 3]\\nLe café du matin\\nA perdu sa saveur\\nJe tends la main en vain\\nVers ce bonheur en pleurs\\n\\n[Chorus]\\nComment vivre sans toi\\nQuand tout me rappelle nous\\n\\n[Bridge]\\nPeut-être qu'un jour\\nLa douleur s'effacera\\nMais cet amour\\nToujours vivra en moi\\n\\n[Outro]\\nComment vivre...\\nSans toi...\",\n    \"bpm\": 76,\n    \"duration\": 206,\n    \"keyscale\": \"F minor\",\n    \"language\": \"fr\",\n    \"timesignature\": \"4\"\n}"
  },
  {
    "path": "examples/text2music/example_198.json",
    "content": "{\n    \"think\": true,\n    \"caption\": \"An upbeat French reggae-pop fusion with sunny guitar skanks, laid-back bass grooves, and tropical percussion. The male vocalist sings with a relaxed, positive vibe about enjoying life and summer days, featuring catchy melodic hooks.\",\n    \"lyrics\": \"[Intro]\\n\\n[Verse 1]\\nLe soleil se lève sur la plage\\nLes pieds dans le sable chaud\\nPas besoin de bagages\\nJuste la mer et le repos\\n\\n[Verse 2]\\nUne bière à la main\\nLes soucis sont si loin\\nAujourd'hui tout va bien\\nDemain on verra demain\\n\\n[Chorus]\\nC'est la vie, c'est la vie\\nProfite de chaque instant\\nC'est la vie, c'est la vie\\nSous le soleil éclatant\\nPas de stress, pas de pression\\nJuste de bonnes vibrations\\nC'est la vie, c'est la vie\\nEt c'est notre saison\\n\\n[Verse 3]\\nLes copains sont tous là\\nOn rit, on chante, on danse\\nLe bonheur est dans ces moments-là\\nDans cette douce insouciance\\n\\n[Chorus]\\nC'est la vie, c'est la vie\\nProfite de chaque instant\\n\\n[Bridge]\\nOublie tes problèmes\\nLaisse-toi porter\\nLa vie est un poème\\nQu'il faut savourer\\n\\n[Outro]\\nC'est la vie...\\nYeah, c'est la vie...\",\n    \"bpm\": 92,\n    \"duration\": 190,\n    \"keyscale\": \"G major\",\n    \"language\": \"fr\",\n    \"timesignature\": \"4\"\n}"
  },
  {
    "path": "examples/text2music/example_199.json",
    "content": "{\n    \"think\": true,\n    \"caption\": \"A spoken word French slam poetry piece over minimalist electronic beats and ambient textures. The male performer delivers introspective verses about urban life and existential questions with rhythmic intensity and poetic flow.\",\n    \"lyrics\": \"[Intro]\\n\\n[Verse 1]\\nJe marche dans la ville\\nLes yeux grands ouverts\\nChaque visage défile\\nComme des pages d'un livre amer\\nQui sommes-nous vraiment\\nDerrière nos masques de fer\\nDes âmes errantes\\nDans cet univers\\n\\n[Verse 2]\\nLe métro nous avale\\nNous recrache plus loin\\nDans cette course infernale\\nOn a perdu le chemin\\nLes écrans nous hypnotisent\\nLes mots ont perdu leur sens\\nDans cette ville qui se brise\\nSous le poids du silence\\n\\n[Chorus]\\nMais je continue\\nÀ chercher la lumière\\nDans les rues\\nDans les yeux de mes frères\\nJe continue\\nÀ croire en demain\\nMalgré tout\\nJe tends encore la main\\n\\n[Verse 3]\\nLes murs parlent de révolte\\nLes tags crient notre histoire\\nDans cette jungle de béton\\nOn garde encore l'espoir\\n\\n[Outro]\\nJe marche...\\nJe cherche...\\nJe vis...\",\n    \"bpm\": 85,\n    \"duration\": 220,\n    \"keyscale\": \"B minor\",\n    \"language\": \"fr\",\n    \"timesignature\": \"4\"\n}"
  },
  {
    "path": "examples/text2music/example_20.json",
    "content": "{\n    \"think\": true,\n    \"caption\": \"A classic, gritty hip-hop track built on a steady boom-bap drum machine groove and a deep, foundational sub-bass line. A male vocalist delivers a confident, narrative rap in Spanish, detailing the life of a tough-guy truck driver with a clear, rhythmic flow. The production is clean yet raw, with subtle atmospheric pads in the background and standard vocal reverb. The track transitions into a more reflective, spoken-word style bridge before concluding with an instrumental outro featuring a melodic synth line over the persistent beat.\",\n    \"lyrics\": \"[Intro]\\nHey\\nEste es pa' la güera\\nEn San Antonio\\nEl corazón frío\\nPa' que quede frío\\nAsí\\nYeah\\n\\n[Verse 1]\\nPa' la güera en el hospital\\nDonde el 11 de 2001 suena criminal\\nYa se metió pa' pegarle a la lejanía\\nDonde el calor es de verdad, ¿dónde empieza el día?\\nYa no es la abuela, la sonrisa en los zapatos\\nAquí el café en la mesa ya tiene los cuajazos\\nAquí el taller de ley ya viste el tajío\\nY el viejo sin lluvia llega, qué desafío\\nConecta, te conecta, siente el mensaje\\nDale que en la calle no hay sabotaje\\nLa calle es caldo, el asfalto pura vida\\nAquí se escribe pa' cada chiva la movida\\nYa es tradición, la historia bien escrita\\nEn cada puerta que toca hay mil citas\\nEl tío Javier ya se jodió el lío\\nY ahora en el punk ya está su artilgo\\nDesde Jalisco hasta la 115 en la piel\\nYa está el vecindario y el volante a romper\\nYa es borrar pendejos, el arte respeto\\nPonte trucha en lo que te pillo, es nuestro decreto\\n\\n[Verse 2]\\nUnos en ayuda, otros en parque\\nOtros tienen GPS, otros cruzan barcos\\nEn caminos que pasan sin conocer\\nPero, ¿quién te pone el estilo, quién?\\nEn 4L, el gas bajo, pa' allá nadie\\nSomos tronos, tú ya cayó que esto no es botarla\\nAsí que chinguen a su madre\\nCon buenas frases las cantas, bro\\n\\n[Outro]\\nY te voy pa' allá\\nPa' la ruta\\nAh\\nHey\\n[Instrumental fades out]\",\n    \"bpm\": 100,\n    \"duration\": 124,\n    \"keyscale\": \"F# minor\",\n    \"language\": \"es\",\n    \"timesignature\": \"4\"\n}"
  },
  {
    "path": "examples/text2music/example_200.json",
    "content": "{\n    \"think\": true,\n    \"caption\": \"A festive French folk-pop song with acoustic guitars, fiddle, and hand claps creating a celebratory atmosphere. The mixed male and female vocals trade verses with joyful energy, perfect for dancing and singing along at gatherings.\",\n    \"lyrics\": \"[Intro]\\n\\nHey! Ho!\\n\\n[Verse 1]\\nCe soir on fait la fête\\nOn oublie tous nos soucis\\nLève ton verre à la vie\\nEt chante avec nous ici\\n\\n[Verse 2]\\nLes amis sont réunis\\nAutour de la grande table\\nLes rires et les folies\\nRendent ce moment mémorable\\n\\n[Chorus]\\nAllez, allez, on danse\\nJusqu'au lever du jour\\nAllez, allez, on chante\\nDes chansons d'amour\\nLa vie est une chance\\nQu'il faut célébrer\\nAllez, allez, on danse\\nCe soir on va s'éclater\\n\\n[Verse 3]\\nGrand-père sort l'accordéon\\nMamie tape dans ses mains\\nOn reprend la chanson\\nQui nous unit si bien\\n\\n[Chorus]\\nAllez, allez, on danse\\nJusqu'au lever du jour\\n\\n[Bridge]\\nUn, deux, trois, tournez\\nQuatre, cinq, six, sautez\\nTout le monde est invité\\nÀ cette nuit enchantée\\n\\n[Outro]\\nHey! Ho! Allez!\\nHey! Ho! Dansez!\",\n    \"bpm\": 118,\n    \"duration\": 180,\n    \"keyscale\": \"C major\",\n    \"language\": \"fr\",\n    \"timesignature\": \"2\"\n}"
  },
  {
    "path": "examples/text2music/example_21.json",
    "content": "{\n    \"think\": true,\n    \"caption\": \"A smooth, jazzy lo-fi hip-hop track built on a foundation of a gentle piano melody and a relaxed, steady drum machine groove. A warm, round bassline provides a solid harmonic base. The song features a duet between a clear, melodic female vocalist and a smooth, conversational male vocalist who trade verses and harmonize beautifully in the choruses. The arrangement is punctuated by tasteful, melodic saxophone fills that enhance the jazzy, late-night atmosphere. The track concludes with an extended instrumental outro where the saxophone takes center stage with an expressive, improvisational solo over the core piano and rhythm section, before fading out with a final, lingering piano chord and a soft whoosh effect.\",\n    \"lyrics\": \"[Intro: Piano & Saxophone]\\n\\n[Verse 1: Female Vocal]\\n月光落进窗\\n像是起色的那杯\\n你还在我的心底旋转\\n抛开所有烦忧\\n这爱像流星坠落\\n在夜空闪耀\\n无需解答 心动是唯一的解药\\n\\n[Verse 2: Male Vocal]\\n你的眼神像迷宫\\n我徘徊其中\\n每个音符都带了心脏的轰鸣\\n触碰你的温度就像电流穿心\\n无法抗拒你的爱把我拉入梦境\\n\\n[Chorus: Duet]\\n心跳随着你狂奔\\n如海潮汹涌\\n爱的节奏翻滚着\\n像梦境中梦\\n你的名字是旋律\\n旋律中成风\\n每一拍都诉说爱无声的悸动\\n\\n[Instrumental Break: Saxophone Solo]\\n\\n[Verse 3: Male Vocal]\\n黑夜像个舞台\\n我们点了彩灯\\n节拍跟随心跳\\n默契融成一吻\\n别让夜晚停下来\\n爱永远在认真\\n每一秒都像歌\\n开启奇妙人生\\n\\n[Chorus: Duet]\\n心跳随着你狂奔\\n如海潮汹涌\\n爱的节奏翻滚着\\n像梦境中梦\\n你的名字是旋律\\n旋律中成风\\n每一拍都诉说爱无声的悸动\\n\\n[Bridge: Duet]\\n当黎明来临时\\n我们点燃光芒\\n你的爱是我心中最暖的信仰\\n再多风雨兼程\\n也不愿停下\\n因为你的存在是我唯一牵挂\\n\\n[Instrumental Break: Saxophone Solo]\\n\\n[Chorus: Duet]\\n心跳随着你狂奔\\n如海潮汹涌\\n爱的节奏翻滚着\\n像梦境中梦\\n你的名字是旋律\\n旋律中成风\\n每一拍都诉说爱无声的悸动\\n\\n[Outro: Duet & Saxophone]\\n当黎明来临时\\n我们点燃光芒\\n你的爱是我心中最暖的信仰\\n再多风雨兼程\\n也不愿停下\\n因为你的存在是我唯一牵挂\\n[Saxophone melody fades out]\",\n    \"bpm\": 100,\n    \"duration\": 233,\n    \"keyscale\": \"B♭ major\",\n    \"language\": \"zh\",\n    \"timesignature\": \"4\"\n}"
  },
  {
    "path": "examples/text2music/example_22.json",
    "content": "{\n    \"think\": true,\n    \"caption\": \"An upbeat, celebratory synth-pop track driven by a punchy four-on-the-floor drum machine beat and a vibrant synth bassline. The song opens with a catchy, wordless vocal chop melody that serves as a recurring hook. A clear, enthusiastic male lead vocal carries the verses and soars into an anthemic, layered chorus. The production is polished and modern, featuring bright synth pads, melodic synth leads, and subtle atmospheric effects that create a sense of scale and joy. The track builds dynamically into each chorus, followed by an instrumental break that reprises the main vocal chop hook, before culminating in a powerful final chorus and a clean, decisive ending.\",\n    \"lyrics\": \"[Intro - Vocal Chop Melody]\\n\\n[Verse 1]\\nÉbred a természet, vigan\\nA végtelen a tájba\\nAhol a nyár áll az iskola\\nA szívünkben tombol a zaj\\n\\n[Pre-Chorus]\\nFel is encontrató mámor\\nEgy szolidi táncparkett\\nEz a miénk tű early\\nEnrég a tűz, enyhék a fák közt\\n\\n[Chorus]\\nEz a mi időnk, rád gondolok\\nTáncolok a holdvilág\\nA szívünk dobban, de mégis újra élek\\nMost és újra\\nÉbred a természet, mindkötöm nevét most az élet\\nSzállj velem, csak értünk lennem\\nA város szívében élj egy szebb világban\\n\\n[Instrumental Break - Vocal Chop Melody]\\n\\n[Verse 2]\\nA színek és áram szövedezik\\nA parkett üteme hallom\\nNézd, ahogy a fény táncot jár\\nA világ velünk egy táncot vonva\\n\\n[Pre-Chorus]\\nCsillagok mutatója\\nEgyütt lélegzünk\\nA tenger színeivel esküszünk\\n\\n[Chorus]\\nEz a mi időnk, rád gondolok\\nTáncolok a holdvilág\\nA szívünk dobban, de mégis újra élek\\nMost és újra\\nÉbred a természet, mindkötöm nevét most az élet\\nSzállj velem, csak értünk lennem\\nA város szívében élj egy szebb világban\\n\\n[Bridge]\\nA naplemente vezető ma\\nCsak miénk az idő és a pillanat\\nA természetünk vivan már\\nMost és most húz a szívbe, hopp!\\n\\n[Instrumental Break - Vocal Chop Melody]\\n\\n[Outro]\\nÉbredj már, együtt repülünk\\nAhol a nyár a tengernek ad\\nÚjra itt leszünk\\nA természet vivan most és mindkötöm nevem\",\n    \"bpm\": 201,\n    \"duration\": 184,\n    \"keyscale\": \"F# minor\",\n    \"language\": \"hu\",\n    \"timesignature\": \"4\"\n}"
  },
  {
    "path": "examples/text2music/example_23.json",
    "content": "{\n    \"think\": true,\n    \"caption\": \"A heartfelt Latin pop-rock ballad driven by a clean, melodic electric guitar that weaves intricate fills and arpeggios throughout the arrangement. The track opens with a distinctive guitar hook before settling into a steady groove laid down by an acoustic drum kit and a solid bassline. The lead male vocal is clear and emotional, delivering a nostalgic and melancholic narrative with increasing passion in the soaring choruses. The song's structure includes a dynamic bridge that shifts the mood towards hopefulness, followed by an expressive and melodic guitar solo that carries the emotional weight of the track before a final, powerful chorus and a gentle, reflective outro.\",\n    \"lyrics\": \"[Intro - Electric Guitar Melody]\\n\\n[Verse 1]\\nTe extraño demasiado\\nSin ti ya no es igual\\nEstoy viendo tus fotos\\nY el mundo se me va\\nEspero que un día\\nMe hayas vuelto a ver\\nQue yo por lo menos\\nPueda hacerte saber\\n\\n[Pre-Chorus]\\nQue aunque ya no estés aquí\\nMi corazón te extraña, sí\\nY eso es todo lo que soy\\nSiempre te recordaré\\n\\n[Chorus]\\nY aunque ya no estés aquí\\nMi corazón te extraña, sí\\nY eso es todo lo que soy\\nSiempre te recordaré\\n\\n[Instrumental Break - Guitar Melody]\\n\\n[Verse 2]\\nSi acaso he pensado\\nPero jamás te olvidé\\nEres parte de mi vida\\nUn regalo que soñé\\nMe sobran tus recuerdos\\nPero falta tu calor\\nMe falta la esperanza\\nDe que vuelvas, por favor\\n\\n[Pre-Chorus]\\nY aunque ya no estés aquí\\nMi corazón te extraña, sí\\nY eso es todo lo que soy\\nSiempre te recordaré\\n\\n[Chorus]\\nY aunque ya no estés aquí\\nMi corazón te extraña, sí\\nY eso es todo lo que soy\\nSiempre te recordaré\\n\\n[Bridge]\\nTal vez el tiempo me traiga de vuelta a tu vida\\nTal vez en tus días\\nYa no quede cicatriz\\nPero yo quiero contarte\\nQue aún vives en mí\\nQue te quiero, lo sabes\\nY te extraño, lo sé\\n\\n[Chorus]\\nY aunque ya no estés aquí\\nMi corazón te extraña, sí\\nY eso es todo lo que soy\\nSiempre te recordaré\\n\\n[Outro]\\nCariño mío\\nLo sentiste tan real\\nTe amo tanto\\nQue ni lo puedo olvidar\\nEres mi razón\\nY mi eterno despertar\\n\\n[Guitar Solo]\\n\\n[Final Outro]\\nCariño mío\\nLo sentiste tan real\\nTe amo tanto\\nQue ni lo puedo olvidar\\nEres mi razón\\nY mi eterno despertar\\n[Song fades out]\",\n    \"bpm\": 100,\n    \"duration\": 225,\n    \"keyscale\": \"A major\",\n    \"language\": \"es\",\n    \"timesignature\": \"4\"\n}"
  },
  {
    "path": "examples/text2music/example_24.json",
    "content": "{\n    \"think\": true,\n    \"caption\": \"An energetic J-rock or anime-style rock track driven by powerful, distorted electric guitars and a driving drum beat. The song opens with a clean, arpeggiated guitar figure before exploding into a full-band arrangement with a soaring lead guitar melody. A clear, powerful female vocal delivers an emotional performance in Japanese, building from the verses into an anthemic, belted chorus. The arrangement features a dynamic bridge with atmospheric vocalizations and a melodic, technically proficient guitar solo complete with expressive bends and fast runs. The track concludes with a powerful final chorus and a climactic guitar flourish.\",\n    \"lyrics\": \"[Intro - Arpeggiated Electric Guitar]\\n\\n[Verse 1]\\n晨光吻醒陌生的街道\\n耳边风轻拂昨日的欢笑\\n时针转为脚边的影子奔跑\\n梦醒之后谁还在拥抱\\n\\n[Pre-Chorus]\\n轻快的节拍 穿越了时间\\n青春像火在燃烧着热血\\n遗失的时间 留不住一切\\n青春像光它忽明又忽灭\\n\\n[Chorus]\\n黄昏的余音在耳边倾诉\\n追逐的脚印已模糊模糊\\n翻滚的青春是烈焰的舞\\n我们在光阴里漫步反复\\n\\n[Instrumental Break - Guitar Melody]\\n\\n[Verse 2]\\n汗水挥洒出闪亮的汗珠\\n双手扣紧那未完的赌注\\n岁月灼热月却描摹着温度\\n青春绽放刺破天空深处\\n\\n[Pre-Chorus]\\n轻快的节拍 穿越了时间\\n青春像火在燃烧着热血\\n遗失的时间 留不住一切\\n青春像光它忽明又忽灭\\n\\n[Bridge - Vocalizations]\\n\\n[Guitar Solo]\\n\\n[Pre-Chorus]\\n轻快的节拍 穿越了时间\\n青春像火在燃烧着热血\\n遗失的时间 留不住一切\\n青春像光它忽明又忽灭\\n\\n[Chorus]\\n黄昏的余音在耳边倾诉\\n追逐的脚印已模糊模糊\\n翻滚的青春是烈焰的舞\\n我们在光阴里漫步反复\\n\\n[Outro - Guitar Solo over Chorus Chords]\\n[Song ends abruptly]\",\n    \"bpm\": 100,\n    \"duration\": 213,\n    \"keyscale\": \"F minor\",\n    \"language\": \"zh\",\n    \"timesignature\": \"2\"\n}"
  },
  {
    "path": "examples/text2music/example_25.json",
    "content": "{\n    \"think\": true,\n    \"caption\": \"An explosive, high-energy anime rock anthem driven by a powerful male tenor vocal performance in Mandarin. The track kicks off with an anthemic 'whoa-oh' vocal hook over a driving four-on-the-floor beat, immediately establishing a J-rock or C-pop rock feel. The production is dense and polished, layering crunchy, distorted power-chord guitars with a punchy synth bass and a tight, modern drum kit. The choruses erupt with soaring, emotional vocals and layered harmonies, creating a massive wall of sound. A brief instrumental bridge features a chiptune-style synth arpeggio before a final, powerful chorus and an outro that fades out with the signature vocal hook.\",\n    \"lyrics\": \"[Intro]\\nWoah-oh-oh-oh-oh-oh\\nWoah-oh-oh-oh-oh-oh\\nWoah-oh-oh-oh-oh-oh\\nWoah-oh-oh-oh-oh-oh\\n\\n[Verse 1]\\n满天星辰都沉默\\n谁在黑暗中闪烁\\n脚步轻踏入枷锁\\n世界若你如此执着\\n\\n[Pre-Chorus]\\nWoah-oh-oh-oh-oh-oh\\nWoah-oh-oh-oh-oh-oh\\n\\n[Verse 2]\\n你听风声在飘散\\n梦的影子太凌乱\\n无边黑夜探不安\\n你的光芒怎能熄灭\\n\\n[Chorus]\\n燃烧吧烈火之光\\n黑暗中我们敢闯\\n即使跌倒心不慌\\n听那世界心跳响\\n\\n[Post-Chorus]\\nWoah-oh-oh-oh-oh-oh\\nWoah-oh-oh-oh-oh-oh\\n\\n[Verse 3]\\n冷雨敲窗滴作响\\n谁的伤痛扎中央\\n双拳紧握去前方\\n哪怕破碎也不会慌\\n\\n[Bridge]\\n与爱相逢也能追\\n日出时分睁开眼\\n点起它如火蔓延\\n这一切都有它的未来\\n\\n[Chorus]\\n燃烧吧烈火之光\\n黑暗中我们敢闯\\n即使跌倒心不慌\\n听那世界心跳响\\n\\n[Post-Chorus]\\nWoah-oh-oh-oh-oh-oh\\nWoah-oh-oh-oh-oh-oh\\nWoah-oh-oh-oh-oh-oh\\nWoah-oh-oh-oh-oh-oh\\n\\n[Instrumental Break]\\n\\n[Bridge]\\n与爱相逢也能追\\n日出时分睁开眼\\n点起它如火蔓延\\n这一切都有它的未来\\n\\n[Chorus]\\n燃烧吧烈火之光\\n黑暗中我们敢闯\\n即使跌倒心不慌\\n听那世界心跳响\\n\\n[Outro]\\nWoah-oh-oh-oh-oh-oh\\nWoah-oh-oh-oh-oh-oh\\nWoah-oh-oh-oh-oh-oh\\nWoah-oh-oh-oh-oh-oh\\n[abrupt silence]\",\n    \"bpm\": 200,\n    \"duration\": 190,\n    \"keyscale\": \"E♭ major\",\n    \"language\": \"zh\",\n    \"timesignature\": \"2\"\n}"
  },
  {
    "path": "examples/text2music/example_26.json",
    "content": "{\n    \"think\": true,\n    \"caption\": \"A modern reggaeton track with a confident, defiant energy, built on a classic dembow drum machine beat and a deep sub-bass line. The song opens with a catchy, pitched-up vocal chop melody that serves as a recurring hook. The lead female vocal is clear and assertive, delivering lyrics with a rhythmic, almost confrontational flow. The chorus expands with layered vocal harmonies, adding power and emphasis. A bridge section introduces a filtered, telephone-like vocal effect for contrast before the track builds back into a final, powerful chorus and fades out with the initial vocal chop melody and atmospheric synth pads.\",\n    \"lyrics\": \"[Intro - Vocal Chop Melody]\\n\\n[Verse 1]\\nMe decían que no iba a llegar\\nPero este paso me hizo dudar\\nTodo lo que quise, todo lo que fui\\nHoy vuelven y quieren venir hacia mí\\nDicen que soy fría, que no valgo na'\\nPero lo que ves es lo que gané ya\\nNo me digas pobre, yo ya me cansé\\nConozco lo duro que vengo y lo sé\\n\\n[Chorus]\\nDicen que no valgo, que yo soy raro\\nPero si me ven raro, mejor ni me hablen claro\\nLa envidia y la envidia, eso no se nota\\nNo me vendo, no me borran, no me joden en la boca\\n\\n[Verse 2]\\nTengo el estilo que quieren copiar\\nPero yo prefiero a quien me quiera mirar\\nDicen que me odian, que quieren juzgar\\nPero no me importa, ya aprendí a luchar\\nTengo el estilo que quieren copiar\\nPero yo prefiero a quien me quiera mirar\\nDicen que me odian, que quieren juzgar\\nPero no me importa, ya aprendí a luchar\\n\\n[Chorus]\\nDicen que no valgo, que yo soy raro\\nPero si me ven raro, mejor ni me hablen claro\\nLa envidia y la envidia, eso no se nota\\nNo me vendo, no me borran, no me joden en la boca\\n\\n[Bridge - Filtered Vocals]\\nNo soy de los que suelen juzgar\\nNo soy de los que saben tratar\\nDicen que he cambiado, que ya no soy igual\\nPero no me quejo, no voy a parar\\n\\n[Chorus - Layered Vocals]\\nDicen que no valgo, que yo soy raro\\nPero si me ven raro, mejor ni me hablen claro\\nLa envidia y la envidia, eso no se nota\\nNo me vendo, no me borran, no me joden en la boca\\n\\n[Outro]\\nNo me vendo, no me borran, no me joden en la boca\\nNo me vendo, no me borran, no me joden en la boca\\n[Vocal chop melody fades out]\",\n    \"bpm\": 100,\n    \"duration\": 140,\n    \"keyscale\": \"E♭ minor\",\n    \"language\": \"es\",\n    \"timesignature\": \"4\"\n}"
  },
  {
    "path": "examples/text2music/example_27.json",
    "content": "{\n    \"think\": true,\n    \"caption\": \"A moody, atmospheric trap track opens with a clean, arpeggiated synth melody and a deep sub-bass foundation. A crisp trap beat with punchy kicks and rattling hi-hats drives the rhythm. The male lead vocal, delivered in Polish, shifts between melodic rapping and singing, conveying a sense of urban melancholy and introspection. The choruses are marked by a prominent, expressive saxophone melody that weaves through the mix, adding a layer of jazzy, melancholic character. The track progresses through verses and choruses, culminating in an extended instrumental outro where the beat deconstructs, leaving behind atmospheric synth pads and a final, lingering saxophone motif before fading into a music box-like synth melody.\",\n    \"lyrics\": \"[Intro]\\nYeah\\nYeah\\n\\n[Verse 1]\\nDrzwi otwarte na zakrętach, suki uderzały w lód\\nEj, ej\\nW białych obłokach mrok unosi, to sen dla nas jest blues\\nBłyskawice na kolanach, a serca na dłoni\\nŻycie bez reguł, jedno ja i ona, patrząc w prawdę, ale bez słów\\nŻycie bez reguł, jedno ja i ona, patrząc w prawdę, ale bez słów\\n\\n[Chorus - Instrumental Drop]\\n[Synth lead melody with vocal chops]\\n\\n[Verse 2]\\nZnów nie widać dla nich, patrz, szkło zasłania się światłem\\nEj, ej\\nKażda zła chwila to ciężar, by zgubić ślad choćby jasne\\nBłyskawice na kolanach, a serca na dłoni\\nŻycie bez reguł, jedno ja i ona, patrząc w prawdę, ale bez słów\\nŻycie bez reguł, jedno ja i ona, patrząc w prawdę, ale bez słów\\n\\n[Chorus - Instrumental Drop]\\n[Synth lead melody with vocal chops]\\n\\n[Bridge]\\nZnów nie widać dla nich, patrz, szkło zasłania się światłem\\nKażda zła chwila to ciężar, by zgubić ślad choćby jasne\\n[Synth arpeggios and beat]\\n\\n[Chorus - Instrumental Drop]\\n[Synth lead melody with vocal chops]\\n\\n[Outro]\\n[Synth lead melody with vocal chops and beat]\\n[Beat fades out, synth melody continues and fades]\",\n    \"bpm\": 100,\n    \"duration\": 177,\n    \"keyscale\": \"F minor\",\n    \"language\": \"pl\",\n    \"timesignature\": \"4\"\n}"
  },
  {
    "path": "examples/text2music/example_28.json",
    "content": "{\n    \"think\": true,\n    \"caption\": \"An energetic, high-tempo J-pop and chiptune fusion track driven by a relentless four-on-the-floor drum machine beat and a pulsing synth bassline. The soundscape is dominated by bright, arpeggiated 8-bit style synthesizers that create a vibrant, video-game-like atmosphere. A clear, high-pitched female vocal delivers the melody with an upbeat, almost frantic energy, soaring over the dense electronic arrangement. The structure includes dynamic builds and drops, with a brief, atmospheric bridge featuring a whispered English vocal line before launching back into the powerful, synth-laden chorus and an instrumental synth-heavy outro.\",\n    \"lyrics\": \"[Intro - Synth Arpeggio]\\n\\n[Verse 1]\\n森の奥で育ちの音\\n素衣ざなたてが木が笑う\\n流れてゆく時の中で\\nそれたちの声が踊り出す\\n\\n[Pre-Chorus]\\n鳥が歌えば風がふわりと\\n母の愛を運んできたよ\\n子供たちの背中を追って\\n深い森の上で生きる\\n\\n[Chorus]\\n森の鳥語るよ\\n好き君を想うその時に\\n月夜の影忍び寄る\\n静けさの中君を呼ぶ\\n\\n[Instrumental Break]\\n\\n[Verse 2]\\n木の下で続く坂道\\n鳥たちの声は夢を誘う\\n絵を描いた木の夢\\n木が叫ぶ運命の声\\n\\n[Pre-Chorus]\\n時は流れて僕は行く\\n名もない木は今もここに\\n君がくれたそのぬくもり\\n風がそっと背中を押す\\n\\n[Chorus]\\n森の鳥語るよ\\n好き君を想うその時に\\n月夜の影忍び寄る\\n静けさの中君を呼ぶ\\n\\n[Bridge]\\n月の影に隠れた船\\n季節巡り風が歌う\\n風が呼ぶ声の先に\\n静かにささやく君の名を\\n\\n[Breakdown]\\n[whispered]\\n響けその歌で\\n静かに響く木の音\\n\\n[Instrumental Break]\\n\\n[Outro]\\n森の奥の果てまで\\n[Synth arpeggio fades out]\",\n    \"bpm\": 100,\n    \"duration\": 218,\n    \"keyscale\": \"F minor\",\n    \"language\": \"ja\",\n    \"timesignature\": \"4\"\n}"
  },
  {
    "path": "examples/text2music/example_29.json",
    "content": "{\n    \"think\": true,\n    \"caption\": \"An energetic chiptune-pop track driven by a punchy electronic drum machine and a bright, catchy 8-bit synth lead that plays a memorable riff. A clear, powerful male vocal delivers an anthemic melody in Mandarin, soaring over the vibrant digital arrangement. The song follows a classic pop structure with verses building into an explosive, uplifting chorus. A brief, more atmospheric bridge provides a moment of reflection before launching back into the final chorus and an instrumental outro that fades out on the iconic synth melody.\",\n    \"lyrics\": \"[Intro - Chiptune Synth Melody]\\nOh!\\n\\n[Verse 1]\\n翻过山峰\\n找寻光\\n脚步轻快像飞翔\\n天空洒满\\n梦的光\\n未来在呼唤我方向\\n\\n[Chorus]\\n一起飞越那片天\\n勇敢拥抱每个瞬间\\n冒险是我们的语言\\n心跳同步无边无边\\n\\n[Instrumental Break - Chiptune Synth Melody]\\n\\n[Verse 2]\\n风吹过\\n沙漠青烟\\n勇气化作星的线\\n脚步带着\\n希望远\\n未知旅途从不停歇\\n\\n[Chorus]\\n一起飞越那片天\\n勇敢拥抱每个瞬间\\n冒险是我们的语言\\n心跳同步无边无边\\n\\n[Instrumental Break - Chiptune Synth Melody]\\n\\n[Bridge]\\n脚印落在时间线\\n画下每一个明天\\n星辰为我们兑现\\n爱是唯一的心愿\\n\\n[Chorus]\\n一起飞越那片天\\n勇敢拥抱每个瞬间\\n冒险是我们的语言\\n心跳同步无边无边\\n\\n[Outro - Chiptune Synth Melody & Beat]\\n[Beat fades out, synth melody continues and fades]\",\n    \"bpm\": 100,\n    \"duration\": 163,\n    \"keyscale\": \"B♭ major\",\n    \"language\": \"zh\",\n    \"timesignature\": \"4\"\n}"
  },
  {
    "path": "examples/text2music/example_30.json",
    "content": "{\n    \"think\": true,\n    \"caption\": \"An upbeat French pop-rap track built on a clean, catchy electric guitar riff that loops throughout. The production is modern and crisp, featuring a punchy drum machine beat with sharp claps and steady hi-hats, anchored by a smooth synth bassline. A confident male lead vocal delivers rhythmic verses and an anthemic chorus filled with layered harmonies for emphasis. The song includes sections where the vocals become more processed and filtered, adding texture before transitioning into a brief instrumental break highlighting the main guitar motif alongside melodic humming ad-libs.\",\n    \"lyrics\": \"[Intro]\\n[Clean electric guitar riff]\\nYeah\\nYeah\\n\\n[Verse 1]\\nDans le game, on trace, on trace\\nDès le matin, on ne se relâche\\nRêve en couleur, rêve en or\\nTous les autres, quelqu'un ignore\\n\\n[Chorus]\\nMains dans les poches\\nLèvres dans les nuits\\nLis-moi pas, moi\\nC'est quoi? C'est qu'une vraie vie\\n\\n[Verse 2]\\nJe pars en bataille, sourire au coin\\nNouvelle vision, non, j'en ai rien\\nToujours au top, jamais en panne\\nLa révolution vient d'une autre âge, c'est l'heure du barrage\\n\\n[Pre-Chorus]\\nMains dans les poches, lèvres dans les nuits\\nLis-moi pas, moi, c'est quoi? C'est qu'une vraie vie\\nJe pars en bataille, sourire au coin\\nNouvelle vision, non, j'en ai rien\\nToujours au top, jamais en panne\\nLa révolution vient d'une autre âge, c'est l'heure du barrage\\n\\n[Chorus]\\nMains dans les poches\\nLèvres dans les nuits\\nLis-moi pas, moi\\nC'est quoi? C'est qu'une vraie vie\\n\\n[Bridge]\\nJe pars en bataille, sourire au coin\\nNouvelle vision, non, j'en ai rien\\nToujours au top, jamais en panne\\nLa révolution vient d'une autre âge, c'est l'heure du barrage\\n\\n[Pre-Chorus]\\nMains dans les poches, lèvres dans les nuits\\nLis-moi pas, moi, c'est quoi? C'est qu'une vraie vie\\n\\n[Chorus]\\nMains dans les poches, lèvres dans les nuits\\nLis-moi pas, moi, c'est quoi? C'est qu'une vraie vie\\nJe pars en bataille, sourire au coin\\nNouvelle vision, non, j'en ai rien\\nToujours au top, jamais en panne\\nLa révolution vient d'une autre âge, c'est l'heure du barrage\\n\\n[Outro]\\nMains dans les poches\\nLèvres dans les nuits\\nLis-moi pas, moi\\nC'est quoi? C'est qu'une vraie vie\\n[Instrumental break with guitar solo]\\nJe pars en bataille, sourire au coin\\nNouvelle vision, non, j'en ai rien\\nToujours au top, jamais en panne\\nLa révolution vient d'une autre âge, c'est l'heure du barrage\\nMains dans les poches, lèvres dans les nuits\\nLis-moi pas, moi, c'est quoi? C'est qu'une vraie vie\\nJe pars en bataille, sourire au coin\\nNouvelle vision, non, j'en ai rien\\nToujours au top, jamais en panne\\nLa révolution vient d'une autre âge, c'est l'heure du barrage\\n[Music fades out]\",\n    \"bpm\": 100,\n    \"duration\": 220,\n    \"keyscale\": \"A major\",\n    \"language\": \"fr\",\n    \"timesignature\": \"4\"\n}"
  },
  {
    "path": "examples/text2music/example_31.json",
    "content": "{\n    \"think\": true,\n    \"caption\": \"A classic country-folk ballad driven by a steady acoustic guitar rhythm and a warm, earnest male vocal with a gentle twang. A simple bassline and a straightforward drum beat establish a heartfelt, mid-tempo groove. A plaintive harmonica weaves in and out, providing melodic fills and taking the lead during the instrumental breaks and the extended outro. The production is clean and direct, focusing on the storytelling and the sincere vocal performance, creating a nostalgic and romantic atmosphere.\",\n    \"lyrics\": \"[Intro - Acoustic Guitar]\\n\\n[Verse 1]\\nFound you standing in the river's roar\\nHeartbeats racing like never before\\nEyes met mine and time stood still\\nDreams were spinning 'round this hill\\nWalking barefoot on a dusty road\\nFingers tracing where the pelo grow\\nHear your laugh, it's a sweet melody\\nLove a tune that sets me free\\n\\n[Chorus]\\nI'll ride these heartstrings all night long\\nSing our song where we belong\\nIn the quiet moments where we're strong\\nYour heartbeat's my favorite song\\n\\n[Instrumental Break - Harmonica Solo]\\n\\n[Verse 2]\\nStars above us start to glow\\nEvening whispers, soft and low\\nUnderneath the moonlit sky\\nWe're just two souls, you and I\\nIn the silence, hearts will find their tune\\nUnderneath the prairie moon\\n\\n[Instrumental Break - Acoustic Guitar]\\n\\n[Bridge]\\nI'll ride those heartstrings 'til they stray\\nWe'll find our way back someday\\n\\n[Chorus]\\nI'll ride these heartstrings all night long\\nSing our song where we belong\\nIn the quiet moments where we're strong\\nYour heartbeat's my favorite song\\n\\n[Outro - Harmonica and Guitar]\\n[Final guitar strum]\",\n    \"bpm\": 200,\n    \"duration\": 202,\n    \"keyscale\": \"A major\",\n    \"language\": \"en\",\n    \"timesignature\": \"4\"\n}"
  },
  {
    "path": "examples/text2music/example_32.json",
    "content": "{\n    \"think\": true,\n    \"caption\": \"An energetic, bilingual J-pop and French pop vocal performance over a driving electronic beat. The track is built on a foundation of punchy synth bass, crisp drum machine rhythms, and layered synthesizers. A powerful female lead vocal delivers catchy melodies in Japanese, contrasted by a male rapper who performs a verse in French and English. The production is polished and modern, featuring vocal chops, synth arpeggios, and dynamic builds that lead into an anthemic, soaring chorus with layered harmonies and expressive vocal ad-libs. The song concludes with a brief, reflective spoken-word section in Japanese before fading out.\",\n    \"lyrics\": \"[Intro]\\nKaze ni notte\\nAtarashii\\nDoboji to omoide\\n\\n[Verse  1]\\nJono wa hirogaru  100% yorokobi\\nKamishime dori mo imi ni naru shi\\nMinna ore o yurugasu\\nTaifuu ga shinai no kamo\\n\\n[Pre-Chorus]\\nJinchou onna no you ni ikki\\nKoukou de kyou mo ikitsuku\\nJiyuu no kaze ni notte yotte\\nDoboji to omoide\\n\\n[Chorus]\\nChoushi sawarazu\\nHidari ni wo terashite\\nKyou mo tokubetsu sugite\\nOre no jinsei wo kakeru\\n\\n[Post-Chorus]\\nSubete wo yakareta ore no machi\\nIchido ikiru nara imi ga wakaru\\nOmae wa sou yatte karada wo katte\\nKuzusenai nai\\nKoko de doko made mo yukou ka\\n\\n[Instrumental Break]\\n\\n[Verse  2 -  Male Rap]\\nCulte de fiesta\\nHousou shite\\nKyou mo tokubetsu sugite\\nOre no jinsei wo kakeru\\n\\n[Bridge]\\nSubete wo yakareta ore no machi\\nIchido ikiru nara imi ga wakaru\\nOmae wa sou yatte karada wo katte\\nKuzusenai nai\\nKoko de doko made mo yukou ka\\n\\n[Chorus]\\nSubete wo yakareta ore no machi\\nIchido ikiru nara imi ga wakaru\\nOmae wa sou yatte karada wo katte\\nKuzusenai nai\\nKoko de doko made mo yukou ka\\n\\n[Outro]\\nSubete wo yakareta ore no machi\\nIchido ikiru nara imi ga wakaru\\nOmae wa sou yatte karada wo katte\\nKuzusenai nai\\nKoko de doko made mo yukou ka\\nSaa saa doko made mo oikakero\\nJiyuu no kaze ni notte yotte\\nDoboji to omoide\\n[Synth arpeggio fades out]\",\n    \"bpm\": 100,\n    \"duration\": 197,\n    \"keyscale\": \"F# major\",\n    \"language\": \"ja\",\n    \"timesignature\": \"4\"\n}"
  },
  {
    "path": "examples/text2music/example_33.json",
    "content": "{\n    \"think\": true,\n    \"caption\": \"A romantic Latin pop track opens with a clean, arpeggiated piano melody that forms the song's harmonic core. A heartfelt male vocal enters, singing in Spanish with an earnest and emotional delivery. The arrangement builds as a steady, mid-tempo reggaeton-style drum machine beat and a subtle synth bassline kick in, transforming the ballad into a danceable yet tender piece. The chorus is memorable and features layered vocal harmonies for emphasis. The track includes an instrumental break highlighting the piano and synth melody before concluding with a final chorus and a brief, atmospheric piano-led outro.\",\n    \"lyrics\": \"[Intro: Piano Melody]\\n\\n[Verse 1]\\nMe enamoré de ti\\nPorque tú eres la princesa\\nY yo un príncipe soñando con tu belleza\\nY ya no sé cómo puedo explicarlo\\nPero ya la vida me trajo\\nA tu lado, me siento orgulloso de ser el caballo más enamorado\\n\\n[Pre-Chorus]\\nPero si yo pudiera retroceder el tiempo\\nMe acercaría más a ti\\n\\n[Chorus]\\nPero, oh-oh-oh\\nPero, oh-oh-oh\\nSi yo pudiera retroceder el tiempo\\nMe acercaría más a ti\\nPero, oh-oh-oh\\nPero, oh-oh-oh\\n\\n[Verse 2]\\nTú te quedaste para siempre en mi mente\\nSi te miro a los ojos, siento todo lo diferente\\nPorque contigo se detiene el tiempo\\nSolo tú y yo sabemos el momento\\nMe gustaría detener el tiempo\\nAbrazarte, besarte, bailarte lento\\nTu mirada me atrapa, es un cuento\\nQue aún no termina, no, no\\n\\n[Bridge]\\nEs imposible\\nQue yo te quiera más\\nY es increíble\\nQue yo te quiera más\\nY es increíble\\nQue yo te quiera más\\nMe haces falta\\nTe amo y duele tanto, mi vida\\n\\n[Chorus]\\nPero si yo pudiera retroceder el tiempo\\nMe acercaría más a ti\\nPero, oh-oh-oh\\nPero, oh-oh-oh\\nPero si yo pudiera retroceder el tiempo\\nMe acercaría más a ti\\nPero, oh-oh-oh\\nPero, oh-oh-oh\\n\\n[Outro: Instrumental with Piano and Synth Pads]\\n[Song fades out]\",\n    \"bpm\": 100,\n    \"duration\": 150,\n    \"keyscale\": \"G major\",\n    \"language\": \"es\",\n    \"timesignature\": \"4\"\n}"
  },
  {
    "path": "examples/text2music/example_34.json",
    "content": "{\n    \"think\": true,\n    \"caption\": \"An explosive modern metal track driven by high-gain, palm-muted guitar riffs and relentless double-bass drumming. The song kicks off with an aggressive, chugging guitar intro that sets a powerful, energetic tone. A clean, forceful male vocal enters, delivering an anthemic melody over the driving rhythm section. The arrangement features dynamic shifts, including a melodic and technical guitar solo section with harmonized leads. The production is polished and punchy, emphasizing the tight, powerful interplay between the dual guitars and the rhythm section, creating a sound reminiscent of high-energy anime theme music or J-rock fusedic metal.\",\n    \"lyrics\": \"[Intro - Guitar Riff]\\n\\n[Verse 1]\\nMain selfie, bukan main kejar\\nKata-kata manis jadi gelombang besar\\nInsta buat teman, semua terkata\\nTapi Wi-Fi raya tarik ke mana?\\n\\n[Chorus]\\nMain dengan lowkey, buat hidup terasa\\nHarga naik, story mahal punya\\nBicara macam maya, suka duka\\nTapi cuma idea buat dunia\\n\\n[Guitar Solo]\\n\\n[Verse 2]\\nScroll TikTok semua berisi hiburan\\nCaption kejar hilang, semua tumpang keban\\nTapi lapar jalan gelak ketawa\\nIngat kenapa setiap malam termenung rasa\\n\\n[Chorus]\\nMain dengan lowkey, buat hidup terasa\\nHarga naik, story mahal punya\\nBicara macam maya, suka duka\\nTapi cuma idea buat dunia\\n\\n[Bridge]\\nPandai dengan semua orang\\nTapi tahu di mana damaikan\\nRekam-mu belaka, sini hulur tangan\\nWalau dunia ini penuh cabaran\\n\\n[Guitar Solo]\\n\\n[Chorus]\\nMain dengan lowkey, buat hidup terasa\\nHarga naik, story mahal punya\\nBicara macam maya, suka duka\\nTapi cuma idea buat dunia\\n\\n[Outro - Guitar Solo]\",\n    \"bpm\": 100,\n    \"duration\": 218,\n    \"keyscale\": \"B♭ minor\",\n    \"language\": \"ms\",\n    \"timesignature\": \"4\"\n}"
  },
  {
    "path": "examples/text2music/example_35.json",
    "content": "{\n    \"think\": true,\n    \"caption\": \"An energetic, bilingual pop-rap track built on a foundation of punchy trap drums and a deep sub-bass. The song's signature element is a highly catchy, synthesized woodwind melody with a distinct Middle Eastern or Balkan flavor, which serves as the main hook. A male vocalist delivers confident, rhythmic rap verses, seamlessly switching between English and French. The production is clean and modern, with hype-man ad-libs and vocal shouts punctuating the arrangement, creating a vibrant, club-ready atmosphere perfect for a night out.\",\n    \"lyrics\": \"[Intro]\\n[Synth melody intro]\\nYo, c'est Big Boss sur le beat\\nMaxi sans détour\\nOMG, hey baby, viens goûter au détour\\nOn lève les bras, tourne le ciel\\nLaisse l'énergie nous appeler\\nLaisse-moi chauffer ton corps\\nDécollage, gars!\\n\\n[Instrumental Drop]\\n\\n[Verse 1]\\nSway, DJ, pousse ton petto\\nLes basses cognent, c'est trop chaud\\nLa vibe est dans ma tête, pas de règles ni de stop\\nJe suis déjà hors de contrôle, ready to drop\\nShort lu, ta playlist, elle déchire le trône\\nJ'essaie de conduire mais la passion m'emprisonne\\nLa vibe est divine, dansons sans limite\\nGarde la vitesse, ce soir c'est la frénésie\\n\\n[Chorus]\\nOn est les boss, on chauffe sans hésitation\\nMaxi, Silan, Moustique dans la mission\\nJusque la nuit, fais-moi vibrer\\nTant que la musique monte, je ne peux plus freiner\\n\\n[Instrumental Drop]\\n\\n[Verse 2]\\nOn est les boss, on chauffe sans hésitation\\nMaxi, Silan, Moustique dans la mission\\nJusque la nuit, fais-moi vibrer\\nTant que la musique monte, je ne peux plus freiner\\nDes ladies all in, te fait sourire en public\\nJe suis prêt pour l'action, pas pour te faire diviser\\nLa peau douce, ton corps contre le mien\\nOn se donne à fond, plus rien ne nous retient\\nJe t'invite à la danse, je suis ton vestin\\nQuand tu danses, c'est le moment, laisse-toi porter par le refrain\\nOn est là pour le show, pas besoin de mots\\nJe t'emmène au-delà de ce tempo\\nDanse, balance, oublie tout, on brille ensemble\\nLa nuit est jeune, l'énergie nous rassemble\\nAlors viens, collé-serré, laisse-toi porter\\nBig Boss, on est là pour tout casser\\n\\n[Instrumental Drop]\\n\\n[Outro]\\n[Synth melody fades out]\",\n    \"bpm\": 100,\n    \"duration\": 135,\n    \"keyscale\": \"G minor\",\n    \"language\": \"fr\",\n    \"timesignature\": \"4\"\n}"
  },
  {
    "path": "examples/text2music/example_36.json",
    "content": "{\n    \"think\": true,\n    \"caption\": \"An intense, high-energy industrial metal track driven by a powerful, pounding drum machine and chugging, heavily distorted rhythm guitars. The song opens with a tense, cinematic synth arpeggio before erupting into a full-throttle verse. A commanding female lead vocal soars over the dense instrumentation, delivering a dramatic and powerful performance. The arrangement features a dynamic shift into a spoken-word bridge with a menacing, processed male vocal, adding to the dark, narrative atmosphere. The track culminates in a massive, anthemic chorus with layered vocals and a final, screamed vocal flourish before fading out with atmospheric synths and a lingering guitar motif.\",\n    \"lyrics\": \"[Intro - Synth Arpeggio & Driving Beat]\\n\\n[Verse 1]\\nSous les cieux de la nuit, elle se lève\\nLes mains caressant l'épaule en alerte\\nSes doigts effleurent les vêtements qui comptent\\nSon rire est une promesse qu'il comprendra\\n\\n[Pre-Chorus]\\nElle est parée de rouge et de sang\\nForte, sans force, infinie, forte\\nSes épaules sont chaotiques, liées par la réalité\\nL'écho de son corps gronde, la pression qui monte\\n\\n[Chorus]\\nLa sorcière au caoutchouc se couvre des habits vêtements\\nDevaient emporter les fils de son corps\\nElle brandit sa lame tendue et ses yeux ne brillent plus\\nQuand elle embrasse les ténèbres de son ombre\\n\\n[Instrumental Break]\\n\\n[Verse 2]\\nLes chasseurs se battent dans l'ombre, mais elle ne chancelle pas\\nSa sagesse est une bataille et la menace est son instinct\\nElle évoque les légendes des plus terres\\nElle aime la nuit, la transpirance infinie\\nL'attirance, la puissance qui les hante\\n\\n[Instrumental Break]\\n\\n[Bridge - Male Spoken Word, Filtered]\\nLes indices se cachent, les espoirs s'effacent\\nElle est l'empereur de son château sacré\\nSon père est une victime\\nElle règne à sa loi\\nDe la sorcière au caoutchouc, les cris de son esprit\\n\\n[Chorus]\\nLa sorcière au caoutchouc, la danse du monde se nourrit\\nDe ses coups de poing plus fin, de son rire plus fatal\\nDans ce chaos de la nuit, elle est le chant de la mort\\nLa sorcière au caoutchouc, la mort, la mort, la mort\\n\\n[Instrumental Outro with Vocal Ad-libs]\\n\\n[Final Verse - Layered Vocals]\\nElle est parée de rouge et de sang\\nForte, sans force, infinie, forte\\nElle est parée de rouge et de sang\\nForte, sans force, infinie, forte\\nElle est parée de rouge et de sang\\nForte, sans force, infinie, forte\\nElle est parée de rouge et de sang\\nForte, sans force, infinie, forte\\nForte!\\n\\n[Outro - Male Spoken Word, Filtered]\\nLa sorcière au caoutchouc, la mort, la mort, la mort\\n[Song ends abruptly]\",\n    \"bpm\": 100,\n    \"duration\": 211,\n    \"keyscale\": \"E minor\",\n    \"language\": \"fr\",\n    \"timesignature\": \"4\"\n}"
  },
  {
    "path": "examples/text2music/example_37.json",
    "content": "{\n    \"think\": true,\n    \"caption\": \"A classic blues-rock arrangement with a soulful, nocturnal groove. The track is built on a tight rhythm section of a round-toned bass guitar and a crisp acoustic drum kit. A clean, slightly overdriven electric guitar provides bluesy licks and chordal stabs throughout the verses. The lead male vocal is smooth and soulful with a touch of rasp, soaring into layered harmonies during the expansive chorus. The song features a melodic and expressive guitar solo with classic bends and vibrato, followed by a breakdown and a final, stripped-down vocal section that fades into a concluding guitar flourish.\",\n    \"lyrics\": \"[Intro - Guitar Riff]\\n\\n[Verse 1]\\nCity lights, they dance for miles\\nNeon dreams, they hum in style\\nLate night tales in smoky bars\\nWishing on these falling stars\\n\\n[Verse 2]\\nFootsteps echo on the street\\nMelodies in perfect beat\\nLonely hearts with hidden scars\\nStill we chase these falling stars\\n\\n[Chorus]\\nOh, let's take this ride tonight\\nThrough the shadows in the night\\nFeel the rhythm of guitars\\nLost in wishes, flying far\\n\\n[Verse 3]\\nIn a world of glass and steel\\nBroken dreams feel so unreal\\nYet we sing beneath the stars\\nWishing on these falling stars\\n\\n[Guitar Solo]\\n\\n[Bridge]\\nBaselines thumping through the dark\\nPianos playing in the park\\nEvery note a shot of heart\\nEvery whisper, falling stars\\n\\n[Chorus]\\nOh, let's take this ride tonight\\nThrough the shadows in the night\\nFeel the rhythm of guitars\\nLost in wishes, flying far\\n\\n[Outro]\\nIn a world of glass and steel\\nBroken dreams feel so unreal\\nYet we sing beneath the stars\\nWishing on these falling stars\\n\\n[Extended Guitar Solo and Outro]\\n[Song fades out]\",\n    \"bpm\": 100,\n    \"duration\": 235,\n    \"keyscale\": \"G minor\",\n    \"language\": \"en\",\n    \"timesignature\": \"4\"\n}"
  },
  {
    "path": "examples/text2music/example_38.json",
    "content": "{\n    \"think\": true,\n    \"caption\": \"A driving post-punk arrangement kicks off with layered electric guitars—one clean and arpeggiated, the other providing distorted chordal texture—over a solid bassline and powerful live drums. The male lead vocal is delivered with an angsty, strained quality that builds into an anthemic, shouted chorus where his voice cracks with emotion. Following a melodic yet noisy guitar solo filled with feedback and expressive bends, the track breaks down to its core rhythmic elements before fading out on lingering guitar noise.\",\n    \"lyrics\": \"[Intro - Arpeggiated Electric Guitar]\\n\\n[Verse 1]\\nUnder neon lights, they flicker and fade\\nLost in the hum of this restless parade\\nA city's heartbeat pulses in my veins\\nSearching for answers in the acid rain\\nShadows stretch long, they're clawing my way\\nThe night is alive but it's mine to obey\\n\\n[Chorus]\\nOh, shadows of neon\\nWhere do you run?\\nBleeding out the night just to make us one\\nOh, shadows of neon\\nTell me the truth\\nAre you the ghost or the one I chase with you?\\n\\n[Guitar Solo]\\n\\n[Verse 2]\\nThe walls are whispering secrets they can't keep\\nEchoes of footsteps buried six feet deep\\nEvery corner's a story you'll never forget\\nI'm tangled in chaos, dressed up as regret\\n\\n[Chorus]\\nOh, shadows of neon\\nWhere do you run?\\nBleeding out the night just to make us one\\nOh, shadows of neon\\nTell me the truth\\nAre you the ghost or the one I chase with you?\\n\\n[Outro - Extended Guitar Solo]\\n[Music fades out]\",\n    \"bpm\": 100,\n    \"duration\": 178,\n    \"keyscale\": \"A minor\",\n    \"language\": \"en\",\n    \"timesignature\": \"4\"\n}"
  },
  {
    "path": "examples/text2music/example_39.json",
    "content": "{\n    \"think\": true,\n    \"caption\": \"An explosive fusion of chiptune and punk rock, this track erupts with a high-energy, 8-bit synth melody playing over a driving, distorted power-chord guitar riff and a punchy, tight drum beat. The lead male vocal is delivered with a clear, energetic, and slightly nasal punk-rock inflection. The song maintains a relentless pace, structured around catchy, anthemic choruses and verses that playfully list various types of coffee with satiric words. The chiptune synth hook serves as a recurring motif, reinforcing the track's video game-inspired sonic identity before ending abruptly after a final guitar flourish.\",\n    \"lyrics\": \"[Intro - Chiptune Synth Melody]\\n\\n[Verse 1]\\nVos p'tits mots le pes, c'est pour me réconforter\\nJe rentre chez moi avec rien à boire\\nOn fait caca du pain chaud sur le lait qui grêle\\nOn fume du shit sur le clocher des pommes\\nOn oublie de nettoyer le four\\n\\n[Pre-Chorus]\\nVos p'tits mots le pes, c'est le vin qui me délecte\\nL'assiette\\n'est plus un médicament\\nOn danse au musée avec des pieds en terrasse\\nUn Ricard qui tourne à plein poumons\\nOn boit un verre pour oublier\\n\\n[Chorus]\\nJ'aimerais mieux, j'ai pas la cocaïne\\nQu'on ferme les yeux pour être tous ensemble\\nLes wokos sont tristes, la bière est toxique\\nLes poches sont vides mais vous y pensez\\nJ'aimerais mieux, j'ai pas la cocaïne\\nQu'on ferme les yeux pour être tous ensemble\\nLes wokos sont tristes, la bière est toxique\\nLes poches sont vides mais vous y pensez\\n\\n[Instrumental Break - Chiptune Synth Melody]\\n\\n[Verse 2]\\nVos p'tits mots le pes, c'est pour me rassasier\\nOn sort en berne avec des céréales\\nOn boit pour oublier le cocaïne qu'on boit\\nOn oublie de saluer le pot de bon matin\\nLa bise aux potes, le rhum, le rhum\\n\\n[Pre-Chorus]\\nVos p'tits mots le pes, c'est pour m'amender le cocaïne\\nLa table en grand avec du café\\nOn rit aux larmes quand on a rien à perdre\\nOn s'amuse dans le coin de la cuisine\\nÀ faire de la merde avec des souris\\n\\n[Chorus]\\nJ'aimerais mieux, j'ai pas la cocaïne\\nQu'on ferme les yeux pour être tous ensemble\\nLes wokos sont tristes, la bière est toxique\\nLes poches sont vides mais vous y pensez\\nJ'aimerais mieux, j'ai pas la cocaïne\\nQu'on ferme les yeux pour être tous ensemble\\nLes wokos sont tristes, la bière est toxique\\nLes poches sont vides mais vous y pensez\\n\\n[Outro - Chiptune Synth Melody]\\n[abrupt silence]\",\n    \"bpm\": 100,\n    \"duration\": 190,\n    \"keyscale\": \"E major\",\n    \"language\": \"fr\",\n    \"timesignature\": \"2\"\n}"
  },
  {
    "path": "examples/text2music/example_40.json",
    "content": "{\n    \"think\": true,\n    \"caption\": \"A driving indie rock track with dream pop undertones, built on a steady drum machine beat and an active bassline that anchors the song's momentum. Clean electric guitars weave intricate arpeggios throughout the verses; one plays rhythmic chords while another adds atmospheric lead lines soaked in delay during instrumental breaks. A clear female vocal delivers a melancholic melody in Polish, soaring into layered harmonies for the expansive chorus sections. The arrangement features dynamic shifts between sparser verses and fuller choruses, culminating in an extended outro where melodic guitar leads soar over wordless 'ah' vocals before fading out to a final sustained chord.\",\n    \"lyrics\": \"[Intro - Instrumental]\\n\\n[Verse 1]\\nChciałbym zatrzymać czas\\nGdy zatapiam się w tobie\\nByleby nie palić się\\nA byłem w niebie\\n\\n[Chorus]\\nBo twoje oczy\\nA ja tworzę świat\\nPrzez ciebie\\nNiebo niebo\\nI światło jest we mnie\\nBo jesteś tu\\n\\n[Guitar Solo]\\n\\n[Verse 2]\\nKiedy widzę z daleka twoją twarz\\nNic już nie muszę cieszyć się\\nRozczaruję twoją ciszę\\nI pragnę tej chwili\\n\\n[Chorus]\\nBo twoje oczy\\nA ja tworzę świat\\nPrzez ciebie\\nNiebo niebo\\nI światło jest we mnie\\nBo jesteś tu\\n\\n[Instrumental Bridge with Guitar Solo]\\n\\n[Outro]\\n[Scat singing]\\nAhhh...\\nAhhh...\\nAhhh...\\nAhhh...\\n[Song fades out]\",\n    \"bpm\": 100,\n    \"duration\": 194,\n    \"keyscale\": \"D major\",\n    \"language\": \"pl\",\n    \"timesignature\": \"4\"\n}"
  },
  {
    "path": "examples/text2music/example_41.json",
    "content": "{\n    \"think\": true,\n    \"caption\": \"An energetic and quirky funk-rock track driven by a tight, groovy bassline and a punchy drum machine beat. The song opens with a catchy, scatted vocal hook that sets a playful tone. The lead male vocal is delivered in a rapid-fire, almost rap-like cadence during the verses, shifting to a more melodic and anthemic style for the chorus. The arrangement is punctuated by bright, synthesized brass stabs and a lively saxophone and trumpet-led instrumental break. The track breaks down into a more contemplative section with clean electric guitar before rebuilding to a high-energy finale that fades out with the initial scat motif.\",\n    \"lyrics\": \"[Intro]\\n[Scatting vocal sample]\\nLig na...\\nLig na...\\nLig na...\\nLig na...\\n\\n[Verse 1]\\nCzasem chciałbym woda na prysznic\\nNa lajczak zawsze zemykać\\nMyśli, że mam złe wieści\\nŻe to za mała kawiatura\\nA może niedziela, mam chwilę później\\nWtedy to poszło nie tak\\nMój ziomal umyślny stek w tym cyfrowym mieście\\nZa oknem jeszcze\\n\\n[Pre-Chorus]\\nDzień jak co dzień w kaploferze\\nPod goliszkiem jak na różowo\\nJak już obchodzi, co jutro się dzieje\\nI co nam znowu przyszło\\n\\n[Chorus]\\nŻycie to nie te dni, ani te dni\\nCzyli zatem trzy, do tego trochę chwili\\nLecz jestem tym zimnym i zimnym\\nZimnym i zimnym\\nBo w zimie jest coś, co ma zapalić\\nCztery, podpisane pod jajami\\nZimy, to chyba nie obchodzi nas\\nI tu każda parada jest zimna jak twoja krew\\n\\n[Instrumental Break with Synth Brass]\\n\\n[Verse 2]\\nLecimy dalej\\nNa celownik wziął\\nA więc rano\\nPod szkołą pod osłoną nocy\\nPłacąc za stare nieco\\nWszystko się kończy, a my możemy się przejąć\\nZegarek kolejny leci\\nMiasto żyje naprawdę\\nTo jeszcze nie koniec\\nTo jeszcze nie koniec\\nNie\\n\\n[Bridge]\\nA co to za pech, że wiecznie upiętne dni mijają\\nI mimo, że już za późno\\nDziś, jutro, niezniszczalny\\nJuż nie zniknął\\n\\n[Instrumental Break with Synth Brass]\\n\\n[Outro]\\n[Scatting vocal sample]\\n[Synth brass melody]\\n[Final chord]\",\n    \"bpm\": 100,\n    \"duration\": 208,\n    \"keyscale\": \"D minor\",\n    \"language\": \"pl\",\n    \"timesignature\": \"4\"\n}"
  },
  {
    "path": "examples/text2music/example_42.json",
    "content": "{\n    \"think\": true,\n    \"caption\": \"An explosive big band jazz arrangement kicks off with a powerful brass fanfare and a driving swing rhythm section featuring a walking upright bass and crisp ride cymbals. A commanding female vocalist enters with a theatrical, powerful delivery, her voice soaring over the dynamic horn stabs and saxophone lines. The track includes an energetic, improvisational saxophone solo over the tight rhythm section. The arrangement is dynamic, shifting between full-band shouts and more subdued passages, culminating in a dramatic final vocal statement and a classic big band flourish to finish.\",\n    \"lyrics\": \"[Intro - Full Band Fanfare]\\n\\n[Verse 1]\\nKani\\nKuni no kodoku ni omoi dashi\\nKuni no yasuraki mo yoyotsu mo nashi\\nTsuranuku utagoe yo\\nIshisakiyo moeyo\\nKanawanu negai o\\n\\n[Pre-Chorus]\\nKujike no sakeba\\nKono yo no owari\\nKodoku no naka de\\nKasumi ni ikiru\\n\\n[Chorus]\\nTsuranuku utagoe yo\\nKanawanu negai o\\nKujike no sakeba\\nKono yo no owari\\nKodoku no naka de\\nKasumi ni ikiru\\n\\n[Instrumental Break - Saxophone Solo]\\n\\n[Bridge]\\nKujike no sakeba\\nKono yo no owari\\nKodoku no naka de\\nKasumi ni ikiru\\n\\n[Chorus]\\nTsuranuku utagoe yo\\nKanawanu negai o\\nKujike no sakeba\\nKono yo no owari\\nKodoku no naka de\\nKasumi ni ikiru\\n\\n[Outro - Full Band Crescendo and Final Chord]\",\n    \"bpm\": 100,\n    \"duration\": 175,\n    \"keyscale\": \"D minor\",\n    \"language\": \"ja\",\n    \"timesignature\": \"2\"\n}"
  },
  {
    "path": "examples/text2music/example_43.json",
    "content": "{\n    \"think\": true,\n    \"caption\": \"An energetic and playful children's pop-rock song with a driving, upbeat tempo. The track is built on a foundation of a punchy drum machine beat and a clean electric bassline. Distorted electric guitars play catchy power-chord riffs, giving the chorus a rock edge. A clear, enthusiastic male lead vocal delivers the lyrics with a sing-along quality, supported by layered backing vocals in the chorus. The arrangement includes an instrumental break featuring a synth lead melody and a brief, stripped-down bridge before launching back into the high-energy chorus and a final guitar-led outro.\",\n    \"lyrics\": \"[Intro]\\nHé, csávó!\\nMicsoda csávó, a főnök királyfi, figyelj jól!\\n[Verse 1]\\nPörög a főnix, pörög a táj\\nMindenki nevet, ez nem vitás\\nCsini, Miki, vidám sztorikat\\nA kocsma így rogy, a tűz benned ragad\\n[Chorus]\\nHé, hé, kicsi Miki, gyere vissza hajnalig\\nTámadjon hát, és szórja a vizet\\nHé, hé, Miki Miki, hajnalig jön, de\\nNem áll meg senki, jöhet a tánc, ne késlekedj el!\\n[Verse 2]\\nA kocsma illatát mesteri a nevetés\\nMiki meg a csini is énekel, ez az egész éves élmény\\nPoci, csiki, pörög a rúzs\\nMindenki vele, ezt sose fogja\\n[Chorus]\\nHé, hé, kicsi Miki, gyere vissza hajnalig\\nTámadjon hát, és szórja a vizet\\nHé, hé, Miki Miki, hajnalig jön, de\\nNem áll meg senki, jöhet a tánc, ne késlekedj el!\\n[Bridge]\\nHé, hé, há, te Miki Miki, mesteri\\nEzt mi sose hagynád\\nÓ, micsoda, micsoda, Miki Miki, gyere vissza, gyere vissza!\\n[Instrumental Break - Synth Solo]\\n[Verse 3]\\nA kocsma illatát mesteri a nevetés\\nMiki meg a csini is énekel, ez az egész éves élmény\\nPoci, csiki, pörög a rúzs\\nMindenki vele, ezt sose fogja\\n[Chorus]\\nHé, hé, kicsi Miki, gyere vissza hajnalig\\nTámadjon hát, és szórja a vizet\\nHé, hé, Miki Miki, hajnalig jön, de\\nNem áll meg senki, jöhet a tánc, ne késlekedj el!\\n[Outro]\\nHé, hih, teli a kocsma\\nMiki Miki, Miki Miki, az öröm\\nÓ, micsoda, micsoda, Miki Miki\\nGyere vissza, gyere vissza!\\n[Instrumental Outro with Synth Solo]\",\n    \"bpm\": 100,\n    \"duration\": 181,\n    \"keyscale\": \"C major\",\n    \"language\": \"hu\",\n    \"timesignature\": \"4\"\n}"
  },
  {
    "path": "examples/text2music/example_44.json",
    "content": "{\n    \"think\": true,\n    \"caption\": \"A smooth, contemporary R&B track built on a foundation of clean, melodic electric guitar and a steady, unobtrusive drum machine beat. The song opens with a catchy, wordless vocal hook that sets a romantic, nighttime city mood. A clear male tenor vocal, delivered in a mix of Mandarin and English, glides over the arrangement, supported by lush, layered harmonies and echoed ad-libs that add depth and space to the mix. The production is polished and modern, with a focus on creating an immersive, heartfelt atmosphere through tasteful reverb and a well-balanced low end. The track concludes with a brief, melodic guitar solo that fades out, reinforcing its soulful character.\",\n    \"lyrics\": \"[Intro]\\n\\n[Verse  1]\\n[zh] ni2 hong2 deng1 xia4 wo3 men5 man4 bu4 zai4 ye4 wan3\\n[en]\\n\\n[zh] ni3 de5 yan3 shen2 xiang4 xing1 chen2 zai4 wo3 xin1 shang4 shan3\\n[en]\\n\\n[zh] ye4 feng1 chui1 dong4 zhe5 jie1 tou2 de5 lang4 man4\\n[en]\\n\\n[zh] mei3 ge4 jiao3 luo4 dou1 you3 wei4 zhi1 de5 da2 an4\\n[en]\\n\\n[en] [chorus]\\n\\n[zh] ai4 zai4 yong1 ji3 de5 di4 fang1 jing4 jing4 su4 shuo1\\n[zh] ni3 de5 wen1 rou2 rang4 wo3 mei2 ban4 fa3 duo3\\n[zh] shi4 jie4 tai4 da4 que4 yin1 ni3 yi3 jing1 wo3\\n[zh] wu2 lun4 duo1 yuan3 ye3 bu2 hui4 mi2 shi1 zi4 wo3\\n\\n[Post-Chorus]\\n[zh] ni3 shi4 wo3 de5 deng1 ta3   zhi3 yin3 wo3 qian2 xing2\\n[zh] sheng1 ming4 de5 lv3 tu2 yin1 ni3 bian4 de2 an1 ding4\\n[zh] tian1 bian1 de5 yun2 duo3 jiu4 zai4 tou1 tou1 kan4 ni3\\n[zh] zhe4 yi1 miao3 zhong1 zai4 wo3 xin1 li3 hua4 xuan2 lv4\\n[en]\\n\\n[en] [verse two]\\n\\n[zh] ni3 de5 shou3 zhi3 hua2 guo4 wo3 xin1 tiao4 de5 mei3\\n[zh] mei3 ge4 zi4 jie2 xiang4 shi4 liu2 xing1 hua2 guo4 de5 hui1\\n[zh] gu3 dian3 chen2 zhong4 dan4 shi4 yin1 ni3 zhong4 yue4\\n[zh] xin1 tiao4 li3 shi4 ni3 ai4 de5 jie2 zou4 mei2 yan2\\n[en]\\n\\n[zh] ni3 de5 shou3 zhi3 hua2 guo4 wo3 xin1 tiao4 de5 mei3\\n[zh] mei3 ge4 zi4 jie2 xiang4 shi4 liu2 xing1 hua2 guo4 de5 hui1\\n[zh] gu3 dian3 chen2 zhong4 dan4 shi4 yin1 ni3 zhong4 yue4\\n[zh] xin1 tiao4 li3 shi4 ni3 ai4 de5 jie2 zou4 mei2 yan2\\n[en]\\n\\n[en] [bridge]\\n\\n[zh] ai4 zai4 yong1 ji3 de5 di4 fang1 jing4 jing4 su4 shuo1\\n[zh] ni3 de5 wen1 rou2 rang4 wo3 mei2 ban4 fa3 duo3\\n[zh] shi4 jie4 tai4 da4 que4 yin1 ni3 yi3 jing1 wo3\\n[zh] wu2 lun4 duo1 yuan3 ye3 bu2 hui4 mi2 shi1 zi4 wo3\\n[zh] yin1 fu2 zai4 wo3 men5 zhi1 jian1 qing1 qing1 xuan2 zhuan3\\n[zh] ling2 hun2 de5 xuan2 lv4 tiao4 dong4 liu2 xia4 shi1 pian1\\n[zh] zhe4 yi1 shou3 ge1 de5 ge1 ci2 ni3 lai2 ting1 jian4\\n[zh] ai4 zai4 yong1 ji3 zhong1 rong2 hua4   zai4 shun4 jian1\\n[en]\\n\\n[en] [chorus]\\n\\n[zh] ai4 zai4 yong1 ji3 de5 di4 fang1 jing4 jing4 su4 shuo1\\n[zh] ni3 de5 wen1 rou2 rang4 wo3 mei2 ban4 fa3 duo3\\n[zh] shi4 jie4 tai4 da4 que4 yin1 ni3 yi3 jing1 wo3\\n[zh] wu2 lun4 duo1 yuan3 ye3 bu2 hui4 mi2 shi1 zi4 wo3\\n\\n[Outro]\\n[Instrumental with vocal ad-libs]\\n\\n[Music fades out]\",\n    \"bpm\": 100,\n    \"duration\": 202,\n    \"keyscale\": \"C# major\",\n    \"language\": \"zh\",\n    \"timesignature\": \"4\"\n}"
  },
  {
    "path": "examples/text2music/example_45.json",
    "content": "{\n    \"think\": true,\n    \"caption\": \"An explosive burst of high-energy J-rock and chiptune, the track kicks off with a blistering, harmonized guitar and synth arpeggio intro reminiscent of a video game boss battle. A powerful, clear female vocal drives the verses over a tight, funky slap bassline and a driving drum beat. The arrangement builds into an anthemic, soaring chorus with layered vocals and powerful guitar chords. The track is punctuated by two virtuosic, shred-style guitar solos filled with rapid-fire licks and technical flourishes. The song concludes with a final, triumphant chorus and a flurry of guitar pyrotechnics before an abrupt end.\",\n    \"lyrics\": \"[Intro - Guitar & Synth Lead]\\n\\n[Verse  1]\\n[zh] ye4 feng1 fu2 guo4 wo3 de5 lian3\\n[zh] ni2 hong2 xia4 de5 meng4 jing4 wu2 bian1\\n[zh] cheng2 shi4 jie2 zou4 xiang4 xin1 tiao4 zai4 bian4\\n[zh] mei3 ge4 jiao3 bu4 dai4 zhe5 xin1 de5 xuan2 nian4\\n[zh] ni2 hong2 jian4 yue4 que4 kan4 bu4 qing1 lian3\\n[zh] cang2 zhe5 huan1 xiao4 he2 wu2 sheng1 de5 zhai4\\n[zh] wo3 gen1 sui2 zhe5 xin1 zhong1 de5 bo1 lan2\\n[zh] yue4 guo4 fan2 hua2 zhui1 sui2 zhe5 guang1 huan2\\n\\n[Chorus]\\n[zh] tiao4 jin4 ye4 se4 de5 yin2 he2 xuan2 lv4\\n[zh] fan1 yue4 gu1 dan1 yu3 wei4 zhi1 de5 mi2\\n[zh] xin1 zai4 fei1 xiang2   zhui1 zhu2 de5 ji4 yi4\\n[zh] rang4 meng4 ru2 xing1 chen2 zai4 ye4 kong1 yan2 xu4\\n\\n[Guitar & Synth Solo]\\n\\n[Verse  2]\\n[zh] mei3 shan4 chuang1 wai4 dou1 cang2 zhe5 hua4 yu3\\n[zh] guo4 qu4 wei4 lai2 dou1 qiao3 ran2 kao4 jin4\\n[zh] jiao3 bu4 wu2 sheng1 dan4 ji4 yi4 tou4 ming2\\n[zh] zai4 chen2 mo4 zhong1   zhao3 dao4 xin1 de5 su1 xing3\\n[zh] shui2 shuo1 meng4 jing4 zong3 shi4 bu4 ming2 bai2\\n[zh] zhui1 zhu2 xing1 chen2   yue4 guo4 zhe4 shan1 mai4\\n[zh] yi1 pian4 guang1 ying3 jiang1 ling2 hun2 jie3 kai1\\n[zh] ye4 wan3 dai4 zhe5 yi1 chang2 wu2 jin4 de5 ai4\\n\\n[Chorus]\\n[zh] tiao4 jin4 ye4 se4 de5 yin2 he2 xuan2 lv4\\n[zh] fan1 yue4 gu1 dan1 yu3 wei4 zhi1 de5 mi2\\n[zh] xin1 zai4 fei1 xiang2   zhui1 zhu2 de5 ji4 yi4\\n[zh] rang4 meng4 ru2 xing1 chen2 zai4 ye4 kong1 yan2 xu4\\n\\n[Guitar & Synth Solo]\\n\\n[Bridge]\\n[zh] shui2 shuo1 meng4 jing4 zong3 shi4 bu4 ming2 bai2\\n[zh] zhui1 zhu2 xing1 chen2   yue4 guo4 zhe4 shan1 mai4\\n[zh] yi1 pian4 guang1 ying3 jiang1 ling2 hun2 jie3 kai1\\n[zh] ye4 wan3 dai4 zhe5 yi1 chang2 wu2 jin4 de5 ai4\\n\\n[Chorus]\\n[zh] tiao4 jin4 ye4 se4 de5 yin2 he2 xuan2 lv4\\n[zh] fan1 yue4 gu1 dan1 yu3 wei4 zhi1 de5 mi2\\n[zh] xin1 zai4 fei1 xiang2   zhui1 zhu2 de5 ji4 yi4\\n[zh] rang4 meng4 ru2 xing1 chen2 zai4 ye4 kong1 yan2 xu4\\n\\n[Outro - Guitar & Synth Solo]\\n[Song ends abruptly]\",\n    \"bpm\": 40,\n    \"duration\": 224,\n    \"keyscale\": \"E minor\",\n    \"language\": \"zh\",\n    \"timesignature\": \"2\"\n}"
  },
  {
    "path": "examples/text2music/example_46.json",
    "content": "{\n    \"think\": true,\n    \"caption\": \"An energetic indie rock track driven by a clean, catchy electric guitar riff and a punchy, straightforward drum and bass groove. The male lead vocal is clear and powerful, delivering an anthemic melody that soars during the high-energy chorus. The arrangement follows a classic verse-chorus structure, punctuated by a brief, melodic guitar break and a dynamic bridge that builds back into a final, powerful chorus before concluding with the initial guitar riff.\",\n    \"lyrics\": \"[Intro - Guitar Riff]\\n\\n[Verse 1]\\nWoke up in the electric city, bright light\\nNeon signs and shadows we ignite\\nStepping to the beat, feel the heart race\\nLife's a wild ride in this endless place\\n\\n[Pre-Chorus]\\nSynths and bass, they carry us above\\nFunk rhythms mixed with electric love\\nDrums pounding loud in the crowded street\\nGuitar strings strum to our moving feet\\n\\n[Chorus]\\nTurn it up, feel the electric heartbeat\\nEvery pulse bringing us to our feet\\nDance through the night, we're invincible\\nElectric heartbeat, unstoppable\\n\\n[Instrumental Break - Guitar Riff]\\n\\n[Verse 2]\\nCity lights flicker in a rhythmic trance\\nUnder moon's glow, we take a chance\\nVoices harmonize in a primal scream\\nEvery note a spark, fueling our dream\\n\\n[Pre-Chorus]\\nFeel the rush, let it take control\\nElectric fire burning in our soul\\nNo turning back, we're lost in the sound\\nIn this moment, forever unbound\\n\\n[Chorus]\\nTurn it up, feel the electric heartbeat\\nEvery pulse bringing us to our feet\\nDance through the night, we're invincible\\nElectric heartbeat, unstoppable\\n\\n[Outro - Guitar Riff and Drums]\\n[abrupt silence]\",\n    \"bpm\": 100,\n    \"duration\": 153,\n    \"keyscale\": \"A major\",\n    \"language\": \"en\",\n    \"timesignature\": \"4\"\n}"
  },
  {
    "path": "examples/text2music/example_47.json",
    "content": "{\n    \"think\": true,\n    \"caption\": \"A bright and breezy indie pop track driven by a clean, jangly electric guitar riff and a straightforward, punchy drum beat. A clear, youthful female vocal delivers a sweet and melodic topline in Mandarin. The arrangement is built on a classic verse-chorus structure, with a solid bassline providing a steady foundation. The choruses lift the energy with more sustained vocal notes and a catchy, memorable melody. The track concludes with an instrumental outro that reprises the main guitar riff before ending on a final, resonant chord.\",\n    \"lyrics\": \"[Intro - Guitar Riff]\\n\\n[Verse 1]\\n我问风儿 我问水\\n他笑得真 谁笑得美\\n白山铺地 云舞水\\n林间小道 声声悲\\n\\n[Chorus]\\n悠悠夜湖 繁星缀\\n水中月亮 睡不归\\n叫唤风声 万物归\\n秘密藏在月光碎\\n\\n[Guitar Interlude]\\n\\n[Verse 2]\\n云雀三声 歌尽夜\\n枝叶下诉 万物悲\\n鸟鸣惊起 山中年\\n风中传来 一湾春水\\n\\n[Chorus]\\n悠悠夜湖 繁星缀\\n水中月亮 睡不归\\n叫唤风声 万物归\\n秘密藏在月光碎\\n\\n[Bridge]\\n山坡头上 潮归\\n草帽扑鼻 可深坠\\n银色蝴蝶 向银河\\n月圆星星 在笑坠\\n\\n[Chorus]\\n悠悠夜湖 繁星缀\\n水中月亮 睡不归\\n叫唤风声 万物归\\n秘密藏在月光碎\\n\\n[Outro - Guitar Riff]\\n[Final chord fades out]\",\n    \"bpm\": 100,\n    \"duration\": 165,\n    \"keyscale\": \"B♭ major\",\n    \"language\": \"zh\",\n    \"timesignature\": \"4\"\n}"
  },
  {
    "path": "examples/text2music/example_48.json",
    "content": "{\n    \"think\": true,\n    \"caption\": \"A sentimental C-pop ballad opens with a delicate, arpeggiated guzheng melody layered over gentle piano chords and atmospheric synth pads. A clear, emotive male vocal enters, carrying the verse with a smooth delivery. The arrangement builds into a fuller chorus, introducing a steady pop drum beat, a warm bassline, and soaring string synths that add emotional weight. The track features a brief, melodic instrumental interlude highlighting the guzheng and piano before returning to a powerful final chorus. The song concludes with a gentle decrescendo, fading out on a lingering piano and guzheng motif.\",\n    \"lyrics\": \"[Intro - Piano & Synth Pads]\\n\\n[Verse  1]\\n[zh] zai4 cheng2 shi4 de5 ni2 hong2 li3 you2 dang4\\n[zh] meng4 de5 chi4 bang3 zai4 xin1 li3 zhan4 fang4\\n[zh] yi1 qie4 dou1 zai4 wei4 lai2 zhong1 shan3 guang1\\n[zh] mei3 ge4 ren2 dou1 you3 zi4 ji3 de5 xi1 wang4\\n\\n[Pre-Chorus]\\n[zh] ni2 hong2 deng1 shan3 shuo4 ru2 tong2 xing1 chen2\\n[zh] tiao4 dong4 de5 xin1 he2 ye4 de5 xin1 sheng1\\n[zh] xiang4 yi1 chang2 mao4 xian3 wu2 jin4 de5 lv3 cheng2\\n[zh] zai4 xing1 kong1 xia4 wo3 men5 wu2 suo3 ju1 shu4 de5\\n\\n[Chorus]\\n[zh] xing1 kong1 xia4 wo3 men5 de5 mi4 mi4 jie3 fang4\\n[zh] yong4 ai4 dian3 liang4 shi4 jie4 de5 guang1 mang2\\n[zh] mei3 yi1 ci4 hu1 xi1 dou1 shi4 xin4 yang3\\n[zh] ni3 he2 wo3 yi4 qi3 fei1 xiang2 qu4 tian1 tang2\\n\\n[Instrumental Break - Synth Lead]\\n\\n[Verse  2]\\n[zh] shi2 jian1 liu2 zhuan3 dai4 bu4 zou3 de5 meng4\\n[zh] shi4 ni3 yan3 mou2 li3 zui4 shen1 de5 tong4\\n[zh] dan4 qi3 ji2 ta1 zou3 chu1 gu4 shi4 de5 zhong1\\n[zh] ni3 de5 yong3 gan3 zai4 wo3 xin1 li3 liu2 dong4\\n\\n[Bridge]\\n[zh] yue4 guang1 wen1 rou2 sa3 zai4 hei1 ye4 chang2 lang2\\n[zh] jian1 ding4 ru2 gang1 zhao4 yao4 wo3 men5 qian2 fang1\\n[zh] ai4 shi4 zhi3 nan2 zhen1 zhi3 yin3 wo3 men5 qian2 fang1\\n[zh] wei4 lai2 zai4 yan3 qian2 bu4 zai4 pang2 huang2\\n\\n[Chorus]\\n[zh] xing1 kong1 xia4 wo3 men5 de5 mi4 mi4 jie3 fang4\\n[zh] yong4 ai4 dian3 liang4 shi4 jie4 de5 guang1 mang2\\n[zh] mei3 yi1 ci4 hu1 xi1 dou1 shi4 xin4 yang3\\n[zh] ni3 he2 wo3 yi4 qi3 fei1 xiang2 qu4 tian1 tang2\\n\\n[Outro - Instrumental Fade Out]\",\n    \"bpm\": 100,\n    \"duration\": 155,\n    \"keyscale\": \"D minor\",\n    \"language\": \"zh\",\n    \"timesignature\": \"4\"\n}"
  },
  {
    "path": "examples/text2music/example_49.json",
    "content": "{\n    \"think\": true,\n    \"caption\": \"A dark, atmospheric trap track opens with a reversed vocal sample and a whispered tag before dropping into a hard-hitting beat. The production is built on a deep, resonant 808 bassline, crisp trap hi-hats, and a sharp snare. A male vocalist delivers an intense, emotional rap performance in Mandarin, his voice layered with reverb and occasional auto-tune for effect. Melancholic synth pads and a recurring, mournful synth lead melody add to the somber atmosphere. The song's structure alternates between aggressive rap verses and a more melodic, sung chorus, culminating in a reflective bridge and an atmospheric outro that fades with the initial vocal sample and synth textures.\",\n    \"lyrics\": \"[Intro]\\n\\n[Verse  1]\\n[zh] bei4 gao4 zhi1 zhe4 shi4 jie4   you3 hua2 li4 you3 huang1 dan4\\n[zh] dan4 yan3 qian2 de5 ni3 shi4 wei2 yi1 de5 ban4\\n[zh] bei4 gao4 zhi1 zhe4 shi4 jie4   you3 hua2 li4 you3 huang1 dan4\\n[zh] dan4 yan3 qian2 de5 ni3 shi4 wei2 yi1 de5 ban4\\n[zh] liu2 yan2 fei1 yu3   dou1 xiang4 shi4 zai4 wang4 xiang3\\n[zh] wei4 le5 dian3 tou2   ni3 ke3 yi3 hua4 di4 wei2 lao2 chuang3\\n[zh] cheng2 gong1 de5 jin4 guo3   ye3 hui4 chu1 mai4 fu4 qiang2\\n[zh] zhui1 zhu2 zhe5 wei4 lai2 ye3 hui4 bei4 bie2 ren2 ya1 shang1\\n[zh] ni3 shi4 fou3 ke3 yi3 guan1 diao4 ni3 de5 men2 suo3\\n[zh] guan1 diao4 ni3 de5 lan2 ping2 xin1   ba3 guo4 qu4 xie3 cheng2 zhong3 zi5\\n[zh] cai3 zai4 bai3 you2 lu4   yu4 dao4 kun4 nan2 ni3 de5 jian1 bang3\\n[zh] ni3 dou1 fang4 xia4 na4 bei4 kong3 ju4 ya1 kua3\\n[zh] qing1 xi1 de5 zi4 mu3   ye3 hui4 shuo1 chu1 dian3 yuan2 wei3\\n[zh] ni3 yi2 ding4 hui4 bian4 hao3   er2 bu2 shi4 xie4 zhe5 ye3 gui3\\n\\n[Chorus]\\n[zh] bie2 pa4 shi1 bai4   bie2 pa4 cheng2 shou4 shang1 hai4\\n[zh] ni3 xiang3 yao4 de5 yi1 qie4 dou1 yao4 jing1 shen2 de5 huai2\\n[zh] bie2 pa4 shi1 bai4   bie2 pa4 cheng2 shou4 shang1 hai4\\n[zh] ni3 xiang3 yao4 de5 yi1 qie4 dou1 yao4 jing1 shen2 de5 huai2\\n[zh] bie2 pa4 shi1 bai4   bie2 pa4 cheng2 shou4 shang1 hai4\\n[zh] ni3 xiang3 yao4 de5 yi1 qie4 dou1 yao4 jing1 shen2 de5 huai2\\n[zh] bie2 pa4 shi1 bai4   bie2 pa4 cheng2 shou4 shang1 hai4\\n[zh] ni3 xiang3 yao4 de5 yi1 qie4 dou1 yao4 jing1 shen2 de5 huai2\\n\\n[Verse  2]\\n[zh] ni3 yi3 jing1 zhun3 bei4 hao3   li2 qu4 mei2 you3 da4 bu4 liao3 de5 xian4 zai4\\n[zh] yi1 qie4 dou1 de2 qu4 hui2 bao4   mei2 you3 ren2 neng2 dui4 ni3 hao3\\n[zh] zhe4 ge5 she4 hui4 ru2 ci3 de5 bu4 yi2 yang4   suo3 yi3 fang4 xia4 ni3 de5 xin1 qing2\\n[zh] mei2 you3 ren2 hui4 qu4 xin1 shang1\\n[zh] cong2 tou2 dao4 wei3   wo3 shi4 ge4 hao3 jiao4 xiao1\\n[zh] you3 tai4 duo1 de5 ren2   huo2 zai4 jiu3 shi2 jiu3 liang4\\n[zh] ceng2 jing1 chao2 xiao4 wo3 de5 jing1 zhi4 rang4 wo3 cheng2 wei2 guo4 ke4\\n[zh] dan4 wo3 bu4 ke3 neng2 bian4 cheng2 yi2 ge4 ren2 de5 cuo4 zhe2\\n\\n[Chorus]\\n[zh] bie2 pa4 shi1 bai4   bie2 pa4 cheng2 shou4 shang1 hai4\\n[zh] ni3 xiang3 yao4 de5 yi1 qie4 dou1 yao4 jing1 shen2 de5 huai2\\n[zh] bie2 pa4 shi1 bai4   bie2 pa4 cheng2 shou4 shang1 hai4\\n[zh] ni3 xiang3 yao4 de5 yi1 qie4 dou1 yao4 jing1 shen2 de5 huai2\\n\\n[Bridge]\\n[zh] na4 jiu4 ji4 xu4 chang4   na4 jiu4 ji4 xu4 he2 bie2 ren2 dui4 kang4\\n[zh] xiang1 xin4 zi4 ji3   jiu4 suan4 shi1 bai4 ye3 yao4 ba3 zi4 ji3 kang2\\n[zh] ni3 ying1 gai1 xue2 hui4 wang4 ji4   wei4 shen2 me5 guo4 de2 ru2 ci3 kuang2\\n[zh] shen2 me5 jiao4 zuo4 mei3 hao3   ke3 shi4 zi4 you2 hai2 shi4 zhe4 yang4\\n\\n[Chorus]\\n[zh] bie2 pa4 shi1 bai4   bie2 pa4 cheng2 shou4 shang1 hai4\\n[zh] ni3 xiang3 yao4 de5 yi1 qie4 dou1 yao4 jing1 shen2 de5 huai2\\n[zh] bie2 pa4 shi1 bai4   bie2 pa4 cheng2 shou4 shang1 hai4\\n[zh] ni3 xiang3 yao4 de5 yi1 qie4 dou1 yao4 jing1 shen2 de5 huai2\\n\\n[Outro]\\n[zh] bie2 pa4 shi1 bai4   bie2 pa4 cheng2 shou4 shang1 hai4\\n[zh] bie2 pa4 shi1 bai4   bie2 pa4 cheng2 shou4 shang1 hai4\\n[zh] bie2 pa4 shi1 bai4   bie2 pa4 cheng2 shou4 shang1 hai4\\n[zh] bie2 pa4 shi1 bai4   bie2 pa4 cheng2 shou4 shang1 hai4\\n\\n[Instrumental fades out]\",\n    \"bpm\": 100,\n    \"duration\": 172,\n    \"keyscale\": \"F minor\",\n    \"language\": \"zh\",\n    \"timesignature\": \"4\"\n}"
  },
  {
    "path": "examples/text2music/example_50.json",
    "content": "{\n    \"think\": true,\n    \"caption\": \"A clean, melodic electric guitar loop with a touch of delay sets a dreamy, introspective tone, underpinning a smooth male vocal performance in Mandarin. The track quickly drops into a modern trap beat, featuring crisp hi-hats, a punchy snare, and a deep, resonant 808 bass that drives the rhythm. The artist seamlessly blends melodic singing with a confident rap flow, delivering lyrics in both Mandarin and English. The production is polished and contemporary, with atmospheric synth pads filling the space. A brief, filtered vocal breakdown creates a moment of contemplation before the track returns to its confident chorus and eventually fades out on the initial guitar motif.\",\n    \"lyrics\": \"[Intro]\\nYeah\\nYeah\\n\\n[Verse 1]\\n镜子里的我 是谁的眼神\\n映着真实的我 自成全\\n追逐太虚幻 追逐梦的边缘\\n梦的边界 梦的边缘\\n\\n[Chorus]\\nLook in the mirror 你到底是谁\\nAin't no reflection 谁会了解\\nLook in the mirror 抬起双眼\\nBe myself now 我要的完美\\n\\n[Verse 2]\\n思绪飞旋 追逐自由的瞬间\\n自由的瞬间\\n闭上眼睛 看清世界的一切\\n世界的一切\\n无数故事藏在心底难言\\n心底难言\\n这次我蜕变 像流星划裂\\nLike a star\\n\\n[Chorus]\\nLook in the mirror 你到底是谁\\nAin't no reflection 谁会了解\\nLook in the mirror 抬起双眼\\nBe myself now 我要的完美\\n\\n[Bridge]\\nEvery scar, every fall made me who I am\\n清晰反射内心的光点\\n眼神做证别放下一切\\nI'm defined, I'm defined\\n向未来世界\\n\\n[Chorus]\\nLook in the mirror 你到底是谁\\nAin't no reflection 谁会了解\\nLook in the mirror 抬起双眼\\nBe myself now 我要的完美\\n\\n[Outro]\\n[Instrumental fades out]\",\n    \"bpm\": 200,\n    \"duration\": 160,\n    \"keyscale\": \"E major\",\n    \"language\": \"zh\",\n    \"timesignature\": \"4\"\n}"
  },
  {
    "path": "examples/text2music/example_51.json",
    "content": "{\n    \"think\": true,\n    \"caption\": \"A dreamy indie pop track with shimmering synth pads, gentle acoustic guitar arpeggios, and soft female vocals. The production features reverb-drenched harmonies and a subtle electronic beat, creating an ethereal atmosphere perfect for late-night contemplation.\",\n    \"lyrics\": \"[Intro]\\n\\n[Verse 1]\\nCity lights blur through the window pane\\nI trace your name in the morning rain\\nMemories float like dust in the air\\nI reach for you but you're not there\\n\\n[Pre-Chorus]\\nWe were young and we were free\\nNow you're just a ghost to me\\n\\n[Chorus]\\nFading photographs on my wall\\nI still hear your voice in the hall\\nTime moves on but I'm standing still\\nGuess I always will, guess I always will\\n\\n[Verse 2]\\nYour favorite song plays on the radio\\nI turn it up then I let it go\\nSome things change and some things stay\\nBut you're the one that got away\\n\\n[Pre-Chorus]\\nWe were young and we were free\\nNow you're just a ghost to me\\n\\n[Chorus]\\nFading photographs on my wall\\nI still hear your voice in the hall\\nTime moves on but I'm standing still\\nGuess I always will, guess I always will\\n\\n[Bridge]\\nMaybe in another life\\nWe could get the timing right\\n\\n[Outro]\\nFading, fading away\",\n    \"bpm\": 98,\n    \"duration\": 215,\n    \"keyscale\": \"D major\",\n    \"language\": \"en\",\n    \"timesignature\": \"4\"\n}"
  },
  {
    "path": "examples/text2music/example_52.json",
    "content": "{\n    \"think\": true,\n    \"caption\": \"An energetic hip-hop banger with hard-hitting 808 bass, crisp hi-hats, and aggressive male rap vocals. The production features trap-style percussion, dark synth stabs, and a hypnotic melody that builds intensity throughout the track.\",\n    \"lyrics\": \"[Intro]\\nYeah, let's go\\nYou already know what it is\\n\\n[Verse 1]\\nStarted from the bottom now I'm climbing to the top\\nHaters tried to stop me but I never gonna stop\\nGrinding every day yeah I'm putting in the work\\nDiamonds on my wrist and I'm flexing on the earth\\nCame up from nothing had to hustle for the bread\\nNow I'm living large got these visions in my head\\nThey said I couldn't make it but I proved them all wrong\\nNow I'm writing history putting pain into this song\\n\\n[Chorus]\\nRise up, rise up, we don't fall\\nStand tall, stand tall, through it all\\nRise up, rise up, hear the call\\nWe the ones who run it all\\n\\n[Verse 2]\\nEvery scar I got is just a story that I tell\\nWent through heaven and I walked right out of hell\\nMy ambition is a fire that will never burn out\\nThis is what success and dedication's all about\\nLate nights early mornings yeah I paid the price\\nRolled the dice and now I'm living paradise\\nTo my day ones yeah I got you till the end\\nThis ain't just a moment this a legacy my friend\\n\\n[Chorus]\\nRise up, rise up, we don't fall\\nStand tall, stand tall, through it all\\nRise up, rise up, hear the call\\nWe the ones who run it all\\n\\n[Outro]\\nYeah, we made it\\nThis just the beginning\",\n    \"bpm\": 85,\n    \"duration\": 198,\n    \"keyscale\": \"G minor\",\n    \"language\": \"en\",\n    \"timesignature\": \"4\"\n}\n"
  },
  {
    "path": "examples/text2music/example_53.json",
    "content": "{\n    \"think\": true,\n    \"caption\": \"A soulful R&B ballad featuring smooth male falsetto vocals over lush piano chords and warm bass. The arrangement includes subtle strings, finger snaps, and a gentle drum groove that creates an intimate late-night atmosphere perfect for romance.\",\n    \"lyrics\": \"[Intro]\\nOoh, baby\\n\\n[Verse 1]\\nCandles burning low in our room tonight\\nYour silhouette dancing in the golden light\\nI've been waiting all day just to hold you close\\nYou're the only one who matters the most\\n\\n[Pre-Chorus]\\nEvery moment with you feels like a dream\\nYou're everything and more than you seem\\n\\n[Chorus]\\nLet me love you slow\\nLet the whole world go\\nIn your arms I've found my home\\nLet me love you slow\\nWatch the moonlight glow\\nBaby you're the one I know\\n\\n[Verse 2]\\nWhisper secrets only we can share\\nRun my fingers gently through your hair\\nTime stands still when I look in your eyes\\nWith you I don't need no disguise\\n\\n[Pre-Chorus]\\nEvery moment with you feels like a dream\\nYou're everything and more than you seem\\n\\n[Chorus]\\nLet me love you slow\\nLet the whole world go\\nIn your arms I've found my home\\nLet me love you slow\\nWatch the moonlight glow\\nBaby you're the one I know\\n\\n[Bridge]\\nI don't need the stars when I have your light\\nYou make everything feel so right\\n\\n[Outro]\\nLet me love you slow\\nOoh, baby, slow\",\n    \"bpm\": 68,\n    \"duration\": 238,\n    \"keyscale\": \"Eb major\",\n    \"language\": \"en\",\n    \"timesignature\": \"4\"\n}"
  },
  {
    "path": "examples/text2music/example_54.json",
    "content": "{\n    \"think\": true,\n    \"caption\": \"A high-energy EDM festival anthem with massive synth drops, pounding four-on-the-floor kicks, and euphoric build-ups. Features pitched vocal chops, soaring lead synths, and an explosive drop that commands the dancefloor.\",\n    \"lyrics\": \"[Intro]\\n\\n[Verse 1]\\nWe came to light up the night\\nHands up reaching for the sky\\nFeel the bass running through your veins\\nLet go of all your fears and pain\\n\\n[Build-Up]\\nCan you feel it rising\\nThe moment is now\\nWe're all together\\nScream it out loud\\n\\n[Drop]\\nWe are the fire\\nBurning so bright\\nWe are the dreamers\\nOwning the night\\nLet the music take control\\nFeel it deep within your soul\\n\\n[Verse 2]\\nStrangers become family here\\nUnited by the sound we hear\\nThis moment will live forever more\\nThis is what we're living for\\n\\n[Build-Up]\\nCan you feel it rising\\nThe moment is now\\nWe're all together\\nScream it out loud\\n\\n[Drop]\\nWe are the fire\\nBurning so bright\\nWe are the dreamers\\nOwning the night\\nLet the music take control\\nFeel it deep within your soul\\n\\n[Bridge]\\n\\nOne life, one night, one tribe\\n\\n[Final Drop]\\nWe are the fire\\nBurning so bright\\nWe are the dreamers\\nOwning the night\\n\\n[Outro]\",\n    \"bpm\": 128,\n    \"duration\": 210,\n    \"keyscale\": \"F minor\",\n    \"language\": \"en\",\n    \"timesignature\": \"4\"\n}"
  },
  {
    "path": "examples/text2music/example_55.json",
    "content": "{\n    \"think\": true,\n    \"caption\": \"A heartfelt country ballad with warm acoustic guitar fingerpicking, pedal steel guitar, and sincere male vocals. The production features gentle fiddle accents, soft brushed drums, and rich harmonies that evoke wide open spaces and honest emotion.\",\n    \"lyrics\": \"[Intro]\\n\\n[Verse 1]\\nDriving down these old dirt roads\\nWhere the cotton fields and memories grow\\nPassed the church where grandma prayed\\nAnd the creek where we used to wade\\n\\n[Verse 2]\\nDaddy's truck is rusting now\\nBut I still remember how\\nHe taught me everything I know\\nAbout working hard and letting go\\n\\n[Chorus]\\nThese roots run deep beneath my feet\\nThrough every joy and every defeat\\nNo matter where this life may lead\\nI'll always know where I come from\\nThese roots run deep\\n\\n[Verse 3]\\nMama's kitchen smells the same\\nBiscuits rising, her love unchanged\\nSunday dinners, family ties\\nThe simple things money can't buy\\n\\n[Chorus]\\nThese roots run deep beneath my feet\\nThrough every joy and every defeat\\nNo matter where this life may lead\\nI'll always know where I come from\\nThese roots run deep\\n\\n[Bridge]\\nCity lights may call my name\\nBut this red clay runs through my veins\\n\\n[Outro Chorus]\\nThese roots run deep beneath my feet\\nI'll always know where I come from\\nThese roots run deep\",\n    \"bpm\": 72,\n    \"duration\": 238,\n    \"keyscale\": \"G major\",\n    \"language\": \"en\",\n    \"timesignature\": \"4\"\n}"
  },
  {
    "path": "examples/text2music/example_56.json",
    "content": "{\n    \"think\": true,\n    \"caption\": \"A gritty blues rock track with overdriven electric guitar riffs, walking bass line, and raspy male vocals. The production features vintage tube amp warmth, Hammond organ fills, and a driving shuffle beat that captures raw emotional intensity.\",\n    \"lyrics\": \"[Intro]\\n\\n[Verse 1]\\nWoke up this morning with the devil on my back\\nMy woman left me and she ain't coming back\\nPoured myself some whiskey to ease the pain\\nBut every drop just reminds me of her name\\n\\n[Chorus]\\nI got the blues down in my bones\\nSitting here all alone\\nHeartache is all I've known\\nI got the blues down in my bones\\n\\n[Verse 2]\\nWorked my fingers bloody for twenty years\\nGave her everything now I'm drowning in tears\\nShe took the car and she took my pride\\nLeft me with nothing but this pain inside\\n\\n[Chorus]\\nI got the blues down in my bones\\nSitting here all alone\\nHeartache is all I've known\\nI got the blues down in my bones\\n\\n[Guitar Solo]\\n\\n[Verse 3]\\nSun going down on another lonely night\\nI'll keep on fighting till I see the light\\nThese blues won't break me I've been here before\\nI'll pick myself up off this barroom floor\\n\\n[Outro Chorus]\\nI got the blues down in my bones\\nBut I won't stay here alone\\nGonna find my way back home\\nI got the blues but I'll carry on\",\n    \"bpm\": 92,\n    \"duration\": 217,\n    \"keyscale\": \"E minor\",\n    \"language\": \"en\",\n    \"timesignature\": \"4\"\n}"
  },
  {
    "path": "examples/text2music/example_57.json",
    "content": "{\n    \"think\": true,\n    \"caption\": \"An uplifting gospel choir anthem with powerful harmonies, soaring lead vocals, and triumphant organ. The arrangement builds from intimate verses to a massive congregational chorus with handclaps, tambourine, and full brass section.\",\n    \"lyrics\": \"[Intro]\\n\\n[Verse 1]\\nThrough the valley of shadows I have walked\\nWhen my faith was shaken and my spirit was lost\\nBut a light came shining through the dark\\nAnd it filled my soul and healed my heart\\n\\n[Pre-Chorus]\\nI was blind but now I see\\nGrace has set my spirit free\\n\\n[Chorus]\\nHallelujah, I am saved\\nLifted up from the grave\\nHallelujah, praise His name\\nI will never be the same\\nHallelujah, hallelujah\\n\\n[Verse 2]\\nEvery burden that I used to carry\\nEvery tear and every worry\\nLaid them down at His feet\\nFound a peace that is so sweet\\n\\n[Pre-Chorus]\\nI was lost but now I'm found\\nSolid rock is where I stand my ground\\n\\n[Chorus]\\nHallelujah, I am saved\\nLifted up from the grave\\nHallelujah, praise His name\\nI will never be the same\\nHallelujah, hallelujah\\n\\n[Bridge]\\nLet the whole world hear us sing\\nLet the bells of freedom ring\\nEvery voice lift up as one\\nPraise the Father and the Son\\n\\n[Final Chorus]\\nHallelujah, I am saved\\nHallelujah, praise His name\\nHallelujah, hallelujah\\n\\n[Outro]\",\n    \"bpm\": 78,\n    \"duration\": 219,\n    \"keyscale\": \"Ab major\",\n    \"language\": \"en\",\n    \"timesignature\": \"4\"\n}"
  },
  {
    "path": "examples/text2music/example_58.json",
    "content": "{\n    \"think\": true,\n    \"caption\": \"A groovy funk track with slap bass, tight horn stabs, and rhythmic guitar scratching. Features a charismatic male lead vocal with call-and-response backing vocals, clavinet riffs, and an irresistible pocket groove that demands movement.\",\n    \"lyrics\": \"[Intro]\\n\\nUh! Get up!\\n\\n[Verse 1]\\nSaturday night and the city's alive\\nPut on your dancing shoes it's time to arrive\\nThe DJ's spinning and the floor is hot\\nGive me everything you got\\n\\n[Pre-Chorus]\\nCan you feel it in your feet\\nMoving to that funky beat\\n\\n[Chorus]\\nGet down, get funky tonight\\nLet the rhythm take you high\\nGet down, get funky with me\\nSet your body free\\nOw!\\n\\n[Verse 2]\\nLeave your troubles at the door\\nWe came to party nothing more\\nThe bass is thumping through the floor\\nCome on y'all let me hear you roar\\n\\n[Pre-Chorus]\\nCan you feel it in your feet\\nMoving to that funky beat\\n\\n[Chorus]\\nGet down, get funky tonight\\nLet the rhythm take you high\\nGet down, get funky with me\\nSet your body free\\n\\n[Bridge]\\n\\nBrass section take it!\\nNow bring it back!\\n\\n[Verse 3]\\nWe don't stop till the morning light\\nKeep on grooving feeling right\\nThis is what we live for\\nFunk forever more\\n\\n[Outro]\\nGet down! Get funky!\",\n    \"bpm\": 108,\n    \"duration\": 225,\n    \"keyscale\": \"E minor\",\n    \"language\": \"en\",\n    \"timesignature\": \"4\"\n}"
  },
  {
    "path": "examples/text2music/example_59.json",
    "content": "{\n    \"think\": true,\n    \"caption\": \"A melancholic acoustic folk song with fingerpicked guitar, gentle cello, and intimate female vocals. The sparse arrangement features subtle harmonium drones and soft percussion, creating a contemplative atmosphere of quiet reflection.\",\n    \"lyrics\": \"[Intro]\\n\\n[Verse 1]\\nAutumn leaves are falling down\\nCovering this sleepy town\\nI walk alone these empty streets\\nWhere our memories still meet\\n\\n[Verse 2]\\nThe coffee shop where we first talked\\nThe park bench where we always walked\\nNow just ghosts of what we were\\nSeasons change but I'm still here\\n\\n[Chorus]\\nLike the river flows to sea\\nYou flowed right out of me\\nAnd I'm left here wondering\\nWhere did all the time go\\nWhere did all the time go\\n\\n[Verse 3]\\nI found your letter yesterday\\nWords you never got to say\\nFolded up and tucked away\\nIn a box of yesterday\\n\\n[Chorus]\\nLike the river flows to sea\\nYou flowed right out of me\\nAnd I'm left here wondering\\nWhere did all the time go\\nWhere did all the time go\\n\\n[Bridge]\\nMaybe someday I'll understand\\nWhy you let go of my hand\\n\\n[Outro]\\nWhere did all the time go\",\n    \"bpm\": 76,\n    \"duration\": 232,\n    \"keyscale\": \"A minor\",\n    \"language\": \"en\",\n    \"timesignature\": \"3\"\n}"
  },
  {
    "path": "examples/text2music/example_60.json",
    "content": "{\n    \"think\": true,\n    \"caption\": \"A hard-hitting metal anthem with crushing distorted guitars, double bass drumming, and aggressive male vocals alternating between screams and melodic singing. Features technical guitar riffs, breakdown sections, and an epic orchestral bridge.\",\n    \"lyrics\": \"[Intro]\\n\\n[Verse 1]\\nRising from the ashes of a broken world\\nBattlefield of chaos flags unfurled\\nThey tried to silence us but we won't break\\nThis is our moment everything's at stake\\n\\n[Pre-Chorus]\\nWe are the ones they fear\\nOur time is finally here\\n\\n[Chorus]\\nUnbreakable! We stand as one!\\nUnbreakable! Until it's done!\\nThrough fire and pain we will remain\\nUnbreakable!\\n\\n[Verse 2]\\nScars of war upon our skin\\nEvery loss fuels the fire within\\nNo surrender no retreat\\nVictory or defeat\\n\\n[Pre-Chorus]\\nWe are the ones they fear\\nOur time is finally here\\n\\n[Chorus]\\nUnbreakable! We stand as one!\\nUnbreakable! Until it's done!\\nThrough fire and pain we will remain\\nUnbreakable!\\n\\n[Breakdown]\\n\\nFight! Fight! Fight!\\nWe will never fall!\\n\\n[Bridge]\\n\\nFrom the darkness we emerge\\nOn the edge of the world\\n\\n[Final Chorus]\\nUnbreakable! We stand as one!\\nUnbreakable! Until it's done!\\nUnbreakable!\\n\\n[Outro]\",\n    \"bpm\": 135,\n    \"duration\": 211,\n    \"keyscale\": \"D minor\",\n    \"language\": \"en\",\n    \"timesignature\": \"4\"\n}"
  },
  {
    "path": "examples/text2music/example_61.json",
    "content": "{\n    \"think\": true,\n    \"caption\": \"A retro disco track with four-on-the-floor beat, lush string arrangements, and sparkling female vocals. Features funky rhythm guitar, groovy bass lines, and shimmering synth pads that capture the glamour of the 70s dance floor.\",\n    \"lyrics\": \"[Intro]\\n\\n[Verse 1]\\nMirror ball is spinning round\\nSilver lights upon the ground\\nPut your platforms on tonight\\nWe're gonna dance until the light\\n\\n[Pre-Chorus]\\nThe music's calling out your name\\nNothing's ever gonna be the same\\n\\n[Chorus]\\nDisco fever in my soul\\nLet the rhythm take control\\nDancing queen under the lights\\nWe're gonna boogie all night\\nBoogie all night\\n\\n[Verse 2]\\nSequin dress and golden chains\\nForget about your daily pains\\nOn this floor we're all the same\\nLost inside this disco flame\\n\\n[Chorus]\\nDisco fever in my soul\\nLet the rhythm take control\\nDancing queen under the lights\\nWe're gonna boogie all night\\nBoogie all night\\n\\n[Bridge]\\n\\nFeel the groove inside your heart\\nThis is where the magic starts\\n\\n[Outro]\\nBoogie all night\\nBoogie all night\",\n    \"bpm\": 118,\n    \"duration\": 235,\n    \"keyscale\": \"Bb major\",\n    \"language\": \"en\",\n    \"timesignature\": \"4\"\n}"
  },
  {
    "path": "examples/text2music/example_62.json",
    "content": "{\n    \"think\": true,\n    \"caption\": \"A laid-back reggae track with offbeat guitar skanks, deep dub bass, and smooth male vocals. The production features classic one-drop drumming, melodica accents, and warm analog delay effects that create a sunny island vibe.\",\n    \"lyrics\": \"[Intro]\\n\\n[Verse 1]\\nSun is rising over the bay\\nAnother beautiful Caribbean day\\nNo worries on my mind today\\nJust let the music play\\n\\n[Chorus]\\nOne love, one heart\\nWe're never gonna be apart\\nOne love, one soul\\nTogether we are whole\\nYeah mon\\n\\n[Verse 2]\\nFeel the breeze upon my face\\nThis island is my sacred place\\nRoots and culture in my veins\\nWashing away all the pains\\n\\n[Chorus]\\nOne love, one heart\\nWe're never gonna be apart\\nOne love, one soul\\nTogether we are whole\\n\\n[Bridge]\\n\\nPositive vibration\\nAcross every nation\\nSpread love not hate\\nBefore it's too late\\n\\n[Verse 3]\\nFrom the mountains to the sea\\nThis is where I'm meant to be\\nLiving life so naturally\\nRoots and reggae setting me free\\n\\n[Outro Chorus]\\nOne love, one heart\\nOne love, one soul\\nYeah mon, irie\",\n    \"bpm\": 82,\n    \"duration\": 205,\n    \"keyscale\": \"G major\",\n    \"language\": \"en\",\n    \"timesignature\": \"4\"\n}"
  },
  {
    "path": "examples/text2music/example_63.json",
    "content": "{\n    \"think\": true,\n    \"caption\": \"A fast punk rock anthem with distorted power chords, aggressive drumming, and raw shouted vocals. The production is deliberately lo-fi with maximum energy, featuring gang vocals on the chorus and a rebellious anti-establishment message.\",\n    \"lyrics\": \"[Intro]\\n\\nOne two three four!\\n\\n[Verse 1]\\nThey tell us what to think and say\\nTry to control us every day\\nBut we won't be their puppets anymore\\nWe're breaking down the door\\n\\n[Chorus]\\nWe won't conform! We won't obey!\\nWe're gonna do it our own way!\\nNo more lies! No more chains!\\nWe're taking back our lives again!\\n\\n[Verse 2]\\nSuit and tie they sell their souls\\nEmpty promises and empty goals\\nBut we see through their disguise\\nTime to open up your eyes\\n\\n[Chorus]\\nWe won't conform! We won't obey!\\nWe're gonna do it our own way!\\nNo more lies! No more chains!\\nWe're taking back our lives again!\\n\\n[Bridge]\\n\\nStand up! Fight back!\\nStand up! Fight back!\\n\\n[Verse 3]\\nThis is our generation's call\\nUnited we will never fall\\nRaise your fist into the air\\nShow them that we're everywhere\\n\\n[Final Chorus]\\nWe won't conform! We won't obey!\\nWe're gonna do it our own way!\\nNo more lies! No more chains!\\nWe're taking back our lives!\\n\\n[Outro]\\nOi! Oi! Oi!\",\n    \"bpm\": 172,\n    \"duration\": 165,\n    \"keyscale\": \"A major\",\n    \"language\": \"en\",\n    \"timesignature\": \"4\"\n}"
  },
  {
    "path": "examples/text2music/example_64.json",
    "content": "{\n    \"think\": true,\n    \"caption\": \"A smooth jazz lounge track with brushed drums, walking upright bass, and mellow saxophone lead. Features sophisticated piano voicings, subtle vibraphone accents, and a relaxed swing feel perfect for a late-night cocktail bar.\",\n    \"lyrics\": \"[Intro]\\n\\n[Verse 1]\\nSmoke curls up in the dim lit room\\nSaxophone plays a midnight tune\\nStrangers meet with a knowing glance\\nWould you care to share this dance\\n\\n[Chorus]\\nIn the blue hour of the night\\nEverything feels just right\\nLet the music set the mood\\nJazz and wine and solitude\\n\\n[Verse 2]\\nIce cubes clink in a crystal glass\\nMoments like these they never last\\nBut tonight we'll make them stay\\nLet tomorrow fade away\\n\\n[Sax Solo]\\n\\n[Verse 3]\\nThe pianist plays with gentle hands\\nOnly the night understands\\nThese melodies of love and loss\\nWorth whatever it may cost\\n\\n[Chorus]\\nIn the blue hour of the night\\nEverything feels just right\\nLet the music set the mood\\nJazz and wine and solitude\\n\\n[Outro]\\nJazz and wine and solitude\",\n    \"bpm\": 95,\n    \"duration\": 217,\n    \"keyscale\": \"Db major\",\n    \"language\": \"en\",\n    \"timesignature\": \"4\"\n}"
  },
  {
    "path": "examples/text2music/example_65.json",
    "content": "{\n    \"think\": true,\n    \"caption\": \"An anthemic alternative rock track with jangly guitars, driving drums, and passionate male vocals. The production features layered guitar textures, dynamic shifts from quiet verses to explosive choruses, and emotionally charged lyrics about self-discovery.\",\n    \"lyrics\": \"[Intro]\\n\\n[Verse 1]\\nStaring at the ceiling at 3 AM\\nWondering how I got here again\\nAll the paths I didn't take\\nAll the choices I didn't make\\n\\n[Verse 2]\\nPhotographs of who I used to be\\nA stranger looking back at me\\nSomewhere along the way I lost my name\\nBut I'm done playing their game\\n\\n[Chorus]\\nI'm finding my way back to myself\\nDusting off dreams from the shelf\\nNo more hiding who I am\\nThis is where my life began\\nFinding my way back\\n\\n[Verse 3]\\nBurned the map they drew for me\\nNow I'm finally running free\\nEvery scar tells a story\\nThis is my territory\\n\\n[Chorus]\\nI'm finding my way back to myself\\nDusting off dreams from the shelf\\nNo more hiding who I am\\nThis is where my life began\\nFinding my way back\\n\\n[Bridge]\\nIt's never too late to start again\\nTo rise up from where you've been\\n\\n[Final Chorus]\\nI'm finding my way back to myself\\nThis is where my life began\\nFinding my way back\\n\\n[Outro]\",\n    \"bpm\": 126,\n    \"duration\": 235,\n    \"keyscale\": \"E major\",\n    \"language\": \"en\",\n    \"timesignature\": \"4\"\n}"
  },
  {
    "path": "examples/text2music/example_66.json",
    "content": "{\n    \"think\": true,\n    \"caption\": \"A romantic duet ballad with lush orchestral strings, grand piano, and intertwining male and female vocals. The arrangement builds from intimate verses to a sweeping cinematic chorus, capturing the timeless essence of love.\",\n    \"lyrics\": \"[Intro]\\n\\n[Verse 1 - Female]\\nI never knew what love could be\\nUntil you came and rescued me\\nIn your eyes I found my home\\nNever have to be alone\\n\\n[Verse 2 - Male]\\nYou're the answer to my prayer\\nThe one I searched for everywhere\\nNow that I have found you here\\nI'll hold you close and keep you near\\n\\n[Chorus - Both]\\nForever starts tonight\\nTwo hearts become one light\\nThrough every storm we'll find our way\\nI promise you I'll stay\\nForever starts tonight\\n\\n[Verse 3 - Female]\\nEvery moment by your side\\nFeels like a beautiful ride\\n\\n[Verse 3 - Male]\\nYou're my sunrise every day\\nWords cannot begin to say\\n\\n[Chorus - Both]\\nForever starts tonight\\nTwo hearts become one light\\nThrough every storm we'll find our way\\nI promise you I'll stay\\n\\n[Bridge - Both]\\nIn this dance of destiny\\nYou were always meant for me\\n\\n[Outro]\\nForever starts tonight\",\n    \"bpm\": 66,\n    \"duration\": 203,\n    \"keyscale\": \"F major\",\n    \"language\": \"en\",\n    \"timesignature\": \"4\"\n}"
  },
  {
    "path": "examples/text2music/example_67.json",
    "content": "{\n    \"think\": true,\n    \"caption\": \"An upbeat synthwave track with retro analog synthesizers, pulsing arpeggios, and vocoder-processed vocals. The production features gated reverb drums, neon-soaked pads, and a driving bassline that evokes 80s nostalgia.\",\n    \"lyrics\": \"[Intro]\\n\\n[Verse 1]\\nNeon lights flash through the rain\\nDriving fast down memory lane\\nThe city sleeps but we're alive\\nChasing dreams at midnight drive\\n\\n[Pre-Chorus]\\nTurn the radio up high\\nWatch the stars go flying by\\n\\n[Chorus]\\nRunning through the night\\nChasing electric lights\\nWe're living in a dream\\nNothing's what it seems\\nRunning through the night\\n\\n[Verse 2]\\nRetro future in my mind\\nLeaving yesterday behind\\nSynthesizers fill the air\\nTake me anywhere\\n\\n[Chorus]\\nRunning through the night\\nChasing electric lights\\nWe're living in a dream\\nNothing's what it seems\\nRunning through the night\\n\\n[Synth Solo]\\n\\n[Bridge]\\nWe are the children of the night\\nBathed in artificial light\\n\\n[Outro Chorus]\\nRunning through the night\\nChasing electric lights\\nRunning through the night\",\n    \"bpm\": 118,\n    \"duration\": 228,\n    \"keyscale\": \"A minor\",\n    \"language\": \"en\",\n    \"timesignature\": \"4\"\n}"
  },
  {
    "path": "examples/text2music/example_68.json",
    "content": "{\n    \"think\": true,\n    \"caption\": \"A powerful female pop anthem with punchy drums, bright synth hooks, and confident belting vocals. The production features modern pop production techniques, catchy melodic hooks, and an empowering message of self-love and independence.\",\n    \"lyrics\": \"[Intro]\\n\\n[Verse 1]\\nUsed to dim my light for you\\nBend and break to make it through\\nBut I found my voice again\\nThis is where my story begins\\n\\n[Pre-Chorus]\\nNo more playing small\\nI'm ready to stand tall\\n\\n[Chorus]\\nI'm a queen in my own right\\nWatch me shine so bright\\nDon't need your crown\\nI built my own\\nI'm a queen in my own right\\n\\n[Verse 2]\\nEvery scar made me strong\\nKnew my worth all along\\nNow I walk with my head high\\nTouch the clouds in the sky\\n\\n[Pre-Chorus]\\nNo more playing small\\nI'm ready to stand tall\\n\\n[Chorus]\\nI'm a queen in my own right\\nWatch me shine so bright\\nDon't need your crown\\nI built my own\\nI'm a queen in my own right\\n\\n[Bridge]\\nTo every girl who feels unseen\\nYou're already a queen\\nBelieve in who you are\\nYou're gonna go far\\n\\n[Final Chorus]\\nI'm a queen in my own right\\nWatch me shine so bright\\nI'm a queen in my own right\\n\\n[Outro]\\nYeah, I'm a queen\",\n    \"bpm\": 112,\n    \"duration\": 205,\n    \"keyscale\": \"C major\",\n    \"language\": \"en\",\n    \"timesignature\": \"4\"\n}"
  },
  {
    "path": "examples/text2music/example_69.json",
    "content": "{\n    \"think\": true,\n    \"caption\": \"A melancholic indie rock track with tremolo guitars, steady bass, and vulnerable male vocals. The production features atmospheric reverb, subtle keyboard textures, and a slow-building arrangement that captures bittersweet nostalgia.\",\n    \"lyrics\": \"[Intro]\\n\\n[Verse 1]\\nPolaroid pictures on the wall\\nReminders of before the fall\\nYour handwriting on a note\\nWords you carefully wrote\\n\\n[Verse 2]\\nThe apartment still smells like you\\nMorning coffee for two\\nNow I drink alone and stare\\nAt your empty chair\\n\\n[Chorus]\\nGhosts of summer haunt these halls\\nEchoes bouncing off the walls\\nI'm still here where you left me\\nWaiting for a memory\\n\\n[Verse 3]\\nYour books still line the shelf\\nI can't move them myself\\nIt would mean that you're really gone\\nSo I just carry on\\n\\n[Chorus]\\nGhosts of summer haunt these halls\\nEchoes bouncing off the walls\\nI'm still here where you left me\\nWaiting for a memory\\n\\n[Bridge]\\nMaybe time will ease this ache\\nMaybe hearts are meant to break\\n\\n[Outro]\\nGhosts of summer\\nGhosts of you\",\n    \"bpm\": 88,\n    \"duration\": 233,\n    \"keyscale\": \"D minor\",\n    \"language\": \"en\",\n    \"timesignature\": \"4\"\n}"
  },
  {
    "path": "examples/text2music/example_70.json",
    "content": "{\n    \"think\": true,\n    \"caption\": \"A high-energy dance-pop track with four-on-the-floor beats, catchy synth riffs, and energetic female vocals. Features a massive drop, vocal chops, and an infectious hook designed for radio play and club rotation.\",\n    \"lyrics\": \"[Intro]\\n\\n[Verse 1]\\nFriday night the week is done\\nTime to have a little fun\\nCall my girls we're heading out\\nThis is what it's all about\\n\\n[Pre-Chorus]\\nFeel the bass drop in my chest\\nTonight we're gonna be the best\\n\\n[Chorus]\\nDance until the sun comes up\\nNever gonna get enough\\nHands up if you feel alive\\nThis is how we survive\\nDance dance dance\\n\\n[Verse 2]\\nStrobe lights flashing everywhere\\nMusic pumping through the air\\nNothing matters anymore\\nWe own this dance floor\\n\\n[Pre-Chorus]\\nFeel the bass drop in my chest\\nTonight we're gonna be the best\\n\\n[Chorus]\\nDance until the sun comes up\\nNever gonna get enough\\nHands up if you feel alive\\nThis is how we survive\\nDance dance dance\\n\\n[Drop]\\n\\n[Bridge]\\nLet it go let it flow\\nLet the rhythm steal the show\\n\\n[Outro Chorus]\\nDance until the sun comes up\\nDance dance dance\",\n    \"bpm\": 124,\n    \"duration\": 198,\n    \"keyscale\": \"G major\",\n    \"language\": \"en\",\n    \"timesignature\": \"4\"\n}"
  },
  {
    "path": "examples/text2music/example_71.json",
    "content": "{\n    \"think\": true,\n    \"caption\": \"A cinematic orchestral piece with sweeping strings, French horns, and epic percussion. The arrangement builds from a delicate piano motif to a triumphant full orchestra climax, evoking adventure and heroic journeys.\",\n    \"lyrics\": \"[Intro]\\n\\n[Verse 1]\\nBeyond the mountains far away\\nWhere legends live and heroes stay\\nA journey calls my restless heart\\nTime for my story to start\\n\\n[Chorus]\\nInto the unknown I will go\\nThrough the fire through the snow\\nWith courage as my guiding star\\nI'll travel near and far\\nInto the unknown\\n\\n[Verse 2]\\nAncient maps and whispered tales\\nThrough stormy seas and hidden trails\\nThe world awaits with open arms\\nIts mysteries and charms\\n\\n[Chorus]\\nInto the unknown I will go\\nThrough the fire through the snow\\nWith courage as my guiding star\\nI'll travel near and far\\n\\n[Bridge]\\n\\nEvery step a leap of faith\\nEvery dawn a brand new day\\n\\n[Final Chorus]\\nInto the unknown I will go\\nWith courage as my guiding star\\nInto the unknown\\n\\n[Outro]\",\n    \"bpm\": 85,\n    \"duration\": 237,\n    \"keyscale\": \"D major\",\n    \"language\": \"en\",\n    \"timesignature\": \"4\"\n}"
  },
  {
    "path": "examples/text2music/example_72.json",
    "content": "{\n    \"think\": true,\n    \"caption\": \"A chill lo-fi hip-hop track with dusty vinyl crackle, mellow Rhodes piano, and laid-back boom-bap drums. Features jazzy chord progressions, subtle bass, and a relaxed vibe perfect for studying or late-night reflection.\",\n    \"lyrics\": \"[Intro]\\n\\n[Verse 1]\\nLate night thoughts and coffee steam\\nChasing shadows of a dream\\nBooks are open mind is closed\\nWhere this journey goes who knows\\n\\n[Chorus]\\nJust breathe and let it flow\\nTake it easy take it slow\\nThe answers come in time\\nPeace of mind peace of mind\\n\\n[Verse 2]\\nRain drops tapping on the glass\\nWatching hours slowly pass\\nIn this moment I am free\\nJust the music and me\\n\\n[Chorus]\\nJust breathe and let it flow\\nTake it easy take it slow\\nThe answers come in time\\nPeace of mind peace of mind\\n\\n[Bridge]\\n\\nLet the worries fade away\\nTomorrow is another day\\n\\n[Outro]\\nPeace of mind\",\n    \"bpm\": 75,\n    \"duration\": 185,\n    \"keyscale\": \"Eb major\",\n    \"language\": \"en\",\n    \"timesignature\": \"4\"\n}"
  },
  {
    "path": "examples/text2music/example_73.json",
    "content": "{\n    \"think\": true,\n    \"caption\": \"A fiery Latin pop track with driving reggaeton beat, brass stabs, and passionate bilingual-style vocals. Features acoustic guitar flourishes, electronic production elements, and an irresistible rhythm that demands dancing.\",\n    \"lyrics\": \"[Intro]\\n\\n[Verse 1]\\nThe night is young and so are we\\nFeel the rhythm set us free\\nMove your body to the beat\\nFeel the fire feel the heat\\n\\n[Pre-Chorus]\\nCome a little closer now\\nLet me show you how\\n\\n[Chorus]\\nFuego in my heart tonight\\nBurning burning so bright\\nDancing underneath the stars\\nThis feeling takes us far\\nFuego fuego\\n\\n[Verse 2]\\nSweat is dripping bodies close\\nThis is what I love the most\\nMusic pumping through my veins\\nBreaking free from all the chains\\n\\n[Pre-Chorus]\\nCome a little closer now\\nLet me show you how\\n\\n[Chorus]\\nFuego in my heart tonight\\nBurning burning so bright\\nDancing underneath the stars\\nThis feeling takes us far\\nFuego fuego\\n\\n[Bridge]\\n\\nOne two three let's go\\nFeel the rhythm flow\\n\\n[Outro]\\nFuego fuego\",\n    \"bpm\": 98,\n    \"duration\": 208,\n    \"keyscale\": \"A minor\",\n    \"language\": \"en\",\n    \"timesignature\": \"4\"\n}"
  },
  {
    "path": "examples/text2music/example_74.json",
    "content": "{\n    \"think\": true,\n    \"caption\": \"A tender acoustic ballad with nylon string guitar, soft cello, and gentle female vocals. The intimate production features minimal arrangement, allowing the emotional lyrics about loss and healing to take center stage.\",\n    \"lyrics\": \"[Intro]\\n\\n[Verse 1]\\nEmpty chair at the table\\nSilence where laughter used to be\\nI still set a place for you\\nOut of habit out of need\\n\\n[Verse 2]\\nYour garden still blooms in spring\\nThe roses you planted grow\\nI tend them like you taught me\\nIt's the only way I know\\n\\n[Chorus]\\nI carry you with me\\nIn everything I do\\nThough you're gone from this world\\nI still feel you\\nI carry you\\n\\n[Verse 3]\\nSome days the grief is heavy\\nSome days I find my peace\\nI know you'd want me happy\\nSo I'm learning to release\\n\\n[Chorus]\\nI carry you with me\\nIn everything I do\\nThough you're gone from this world\\nI still feel you\\nI carry you\\n\\n[Bridge]\\nLove doesn't end with goodbye\\nIt lives on it never dies\\n\\n[Outro]\\nI carry you\",\n    \"bpm\": 65,\n    \"duration\": 240,\n    \"keyscale\": \"C major\",\n    \"language\": \"en\",\n    \"timesignature\": \"3\"\n}"
  },
  {
    "path": "examples/text2music/example_75.json",
    "content": "{\n    \"think\": true,\n    \"caption\": \"An aggressive trap metal track with distorted 808s, screamed vocals, and chaotic production. Features industrial sound design, rapid hi-hats, and a dark aggressive energy that blends hip-hop and metal influences.\",\n    \"lyrics\": \"[Intro]\\n\\nLet's go!\\n\\n[Verse 1]\\nDemon in my head won't let me sleep\\nDarkness running through me running deep\\nEverybody fake everybody lies\\nWatch the world burn before my eyes\\nRage inside me can't contain\\nFuel the fire feel the pain\\nBreaking chains breaking free\\nThis is the real me\\n\\n[Chorus]\\nChaos! In my veins!\\nChaos! Break the chains!\\nChaos! Feel no pain!\\nChaos!\\n\\n[Verse 2]\\nThey don't understand what I've been through\\nJudging from the outside with no clue\\nBattle scars across my soul\\nLost myself but now I'm whole\\nRising from the ashes of the past\\nBuilt to break but built to last\\nNo more hiding who I am\\nThis is my final stand\\n\\n[Chorus]\\nChaos! In my veins!\\nChaos! Break the chains!\\nChaos! Feel no pain!\\nChaos!\\n\\n[Breakdown]\\n\\nCan't stop me now!\\n\\n[Outro]\\nChaos!\",\n    \"bpm\": 140,\n    \"duration\": 175,\n    \"keyscale\": \"E minor\",\n    \"language\": \"en\",\n    \"timesignature\": \"4\"\n}"
  },
  {
    "path": "examples/text2music/example_76.json",
    "content": "{\n    \"think\": true,\n    \"caption\": \"A groovy neo-soul track with warm Wurlitzer keys, tight pocket drums, and silky female vocals. Features rich harmonies, subtle guitar licks, and a head-nodding groove that blends classic soul with modern production.\",\n    \"lyrics\": \"[Intro]\\n\\n[Verse 1]\\nSunday morning golden light\\nYou stayed over through the night\\nCoffee brewing records spin\\nThis is where our love begins\\n\\n[Pre-Chorus]\\nNo rush no hurry\\nNo stress no worry\\n\\n[Chorus]\\nEasy like a Sunday morning\\nLove without a warning\\nYou and me we flow so free\\nEasy like it's meant to be\\n\\n[Verse 2]\\nBarefoot dancing in the kitchen\\nThis right here is what I'm missing\\nSimple moments pure and true\\nAll I need is me and you\\n\\n[Chorus]\\nEasy like a Sunday morning\\nLove without a warning\\nYou and me we flow so free\\nEasy like it's meant to be\\n\\n[Bridge]\\n\\nLet the world keep spinning\\nWe're just here winning\\n\\n[Outro]\\nEasy easy\\nSo easy\",\n    \"bpm\": 92,\n    \"duration\": 218,\n    \"keyscale\": \"Ab major\",\n    \"language\": \"en\",\n    \"timesignature\": \"4\"\n}"
  },
  {
    "path": "examples/text2music/example_77.json",
    "content": "{\n    \"think\": true,\n    \"caption\": \"A driving indie folk anthem with stomping drums, banjo, and passionate group vocals. Features acoustic guitars, mandolin accents, and a rousing sing-along chorus that builds to an euphoric climax.\",\n    \"lyrics\": \"[Intro]\\n\\n[Verse 1]\\nWe were born to run wild and free\\nAcross the plains and the rolling sea\\nWith nothing but the clothes on our backs\\nFollowing the railroad tracks\\n\\n[Verse 2]\\nCampfire stories under the stars\\nPlaying songs on old guitars\\nWe don't need much to get by\\nJust good friends and open sky\\n\\n[Chorus]\\nHey ho here we go\\nDown the road where the wild winds blow\\nHey ho sing it loud\\nWe're the dreamers we're the proud\\n\\n[Verse 3]\\nEvery stranger is a friend\\nEvery road has got an end\\nBut the journey is the prize\\nAdventure in our eyes\\n\\n[Chorus]\\nHey ho here we go\\nDown the road where the wild winds blow\\nHey ho sing it loud\\nWe're the dreamers we're the proud\\n\\n[Bridge]\\n\\nOh oh oh oh\\n\\n[Final Chorus]\\nHey ho here we go\\nWe're the dreamers we're the proud\\nHey ho!\",\n    \"bpm\": 138,\n    \"duration\": 225,\n    \"keyscale\": \"G major\",\n    \"language\": \"en\",\n    \"timesignature\": \"4\"\n}"
  },
  {
    "path": "examples/text2music/example_78.json",
    "content": "{\n    \"think\": true,\n    \"caption\": \"A dark electronic track with pulsing bass, haunting synth pads, and ethereal processed female vocals. Features industrial textures, glitchy percussion, and an atmospheric build that creates tension and release.\",\n    \"lyrics\": \"[Intro]\\n\\n[Verse 1]\\nShadows crawling up the wall\\nI can hear the silence call\\nDigital dreams in analog skin\\nLet the darkness pull me in\\n\\n[Pre-Chorus]\\nLosing grip on what is real\\nTell me what am I supposed to feel\\n\\n[Chorus]\\nIn the void I find my peace\\nWhere the noise will finally cease\\nFloat away into the black\\nNever looking back\\n\\n[Verse 2]\\nScreens are glowing in the night\\nArtificial satellite\\nConnected yet so alone\\nSearching for a place called home\\n\\n[Chorus]\\nIn the void I find my peace\\nWhere the noise will finally cease\\nFloat away into the black\\nNever looking back\\n\\n[Bridge]\\n\\nStatic fills my mind\\nLeaving self behind\\n\\n[Outro]\\nFloat away\\nFloat away\",\n    \"bpm\": 110,\n    \"duration\": 235,\n    \"keyscale\": \"B minor\",\n    \"language\": \"en\",\n    \"timesignature\": \"4\"\n}"
  },
  {
    "path": "examples/text2music/example_79.json",
    "content": "{\n    \"think\": true,\n    \"caption\": \"A classic rock power ballad with soaring electric guitar, thunderous drums, and emotional male vocals. Features a quiet verse building to an explosive chorus with layered harmonies and an iconic guitar solo.\",\n    \"lyrics\": \"[Intro]\\n\\n[Verse 1]\\nStanding at the crossroads of my life\\nLooking back at all the sacrifice\\nEvery battle every war\\nWondering what it was all for\\n\\n[Verse 2]\\nThe road was long and full of pain\\nSunshine always follows rain\\nI've been knocked down time and again\\nBut I always rise my friend\\n\\n[Chorus]\\nI will stand unbroken\\nEvery word I've spoken\\nLed me to this moment here\\nI will stand unbroken\\nWith my heart wide open\\nI have conquered all my fear\\n\\n[Verse 3]\\nTo everyone who said I'd fail\\nYour doubt became my holy grail\\nFueled the fire in my soul\\nNow I've finally reached my goal\\n\\n[Chorus]\\nI will stand unbroken\\nEvery word I've spoken\\nLed me to this moment here\\n\\n[Guitar Solo]\\n\\n[Final Chorus]\\nI will stand unbroken\\nI have conquered all my fear\\nUnbroken\\n\\n[Outro]\",\n    \"bpm\": 78,\n    \"duration\": 226,\n    \"keyscale\": \"B minor\",\n    \"language\": \"en\",\n    \"timesignature\": \"4\"\n}"
  },
  {
    "path": "examples/text2music/example_80.json",
    "content": "{\n    \"think\": true,\n    \"caption\": \"An upbeat ska punk track with bouncy offbeat guitar, punchy brass section, and energetic male vocals. Features fast tempos, walking bass lines, and an infectious energy that gets crowds moving and singing along.\",\n    \"lyrics\": \"[Intro]\\n\\nPick it up!\\n\\n[Verse 1]\\nMonday morning alarm goes off\\nBoss is yelling had enough\\nBills are piling traffic's bad\\nBut I refuse to be sad\\n\\n[Pre-Chorus]\\nLife's too short to waste on stress\\nGonna give it my best\\n\\n[Chorus]\\nKeep on smiling through the pain\\nDancing in the pouring rain\\nNothing's gonna bring me down\\nI'm the happiest fool in town\\nHey hey hey!\\n\\n[Verse 2]\\nPeople staring think I'm crazy\\nMaybe I am maybe maybe\\nBut I'd rather laugh than cry\\nLive it up before I die\\n\\n[Chorus]\\nKeep on smiling through the pain\\nDancing in the pouring rain\\nNothing's gonna bring me down\\nI'm the happiest fool in town\\n\\n[Bridge]\\n\\nOne two three four!\\n\\n[Outro]\\nHey hey hey!\\nKeep on smiling!\",\n    \"bpm\": 165,\n    \"duration\": 178,\n    \"keyscale\": \"F major\",\n    \"language\": \"en\",\n    \"timesignature\": \"4\"\n}"
  },
  {
    "path": "examples/text2music/example_81.json",
    "content": "{\n    \"think\": true,\n    \"caption\": \"A dreamy shoegaze track with walls of distorted guitars, ethereal reverb-drenched vocals, and hypnotic drum patterns. Features lush layered textures, tremolo effects, and a wash of sound that creates an immersive sonic landscape.\",\n    \"lyrics\": \"[Intro]\\n\\n[Verse 1]\\nDrifting through a haze of sound\\nFeet not touching the ground\\nColors bleeding into one\\nChasing shadows of the sun\\n\\n[Verse 2]\\nYour voice echoes in my head\\nWords that never could be said\\nFading like a photograph\\nMemories cut in half\\n\\n[Chorus]\\nLost in waves of noise\\nSearching for your voice\\nEverything dissolves\\nInto the void\\n\\n[Verse 3]\\nTime moves slow then fast\\nNothing ever lasts\\nBeauty in decay\\nWashing all away\\n\\n[Chorus]\\nLost in waves of noise\\nSearching for your voice\\nEverything dissolves\\nInto the void\\n\\n[Outro]\\n\\nInto the void\\nInto the void\",\n    \"bpm\": 95,\n    \"duration\": 231,\n    \"keyscale\": \"E major\",\n    \"language\": \"en\",\n    \"timesignature\": \"4\"\n}"
  },
  {
    "path": "examples/text2music/example_82.json",
    "content": "{\n    \"think\": true,\n    \"caption\": \"A bouncy electro-pop track with arpeggiated synths, four-on-the-floor kick, and bright female vocals. Features catchy hooks, sidechained bass, and a playful energy perfect for summer playlists.\",\n    \"lyrics\": \"[Intro]\\n\\n[Verse 1]\\nSummer breeze and salty air\\nSand between my toes without a care\\nSunset painting skies so bright\\nThis is gonna be our night\\n\\n[Pre-Chorus]\\nTurn the music up so loud\\nLose ourselves inside the crowd\\n\\n[Chorus]\\nSummer love is in the air\\nThrow your hands up everywhere\\nFeel the beat drop let it go\\nThis is all we need to know\\n\\n[Verse 2]\\nBonfire burning on the beach\\nHappiness within our reach\\nStrangers dancing side by side\\nRiding on this summer tide\\n\\n[Chorus]\\nSummer love is in the air\\nThrow your hands up everywhere\\nFeel the beat drop let it go\\nThis is all we need to know\\n\\n[Bridge]\\nOh oh oh\\nSummer nights\\nOh oh oh\\nCity lights\\n\\n[Outro]\\nSummer love\\nSummer love\",\n    \"bpm\": 122,\n    \"duration\": 195,\n    \"keyscale\": \"D major\",\n    \"language\": \"en\",\n    \"timesignature\": \"4\"\n}"
  },
  {
    "path": "examples/text2music/example_83.json",
    "content": "{\n    \"think\": true,\n    \"caption\": \"A moody trip-hop track with downtempo beats, atmospheric samples, and smoky female vocals. Features vinyl crackle, deep sub-bass, and cinematic strings creating a late-night urban atmosphere.\",\n    \"lyrics\": \"[Intro]\\n\\n[Verse 1]\\nMidnight city streets are wet\\nNeon signs and silhouettes\\nWalking through the urban maze\\nLost inside this purple haze\\n\\n[Chorus]\\nIn the shadows we exist\\nLike smoke we twist and drift\\nAnonymous and free\\nThis is where I need to be\\n\\n[Verse 2]\\nConcrete jungle breathing slow\\nSecrets only night will know\\nEvery corner tells a tale\\nBeauty hiding behind the veil\\n\\n[Chorus]\\nIn the shadows we exist\\nLike smoke we twist and drift\\nAnonymous and free\\nThis is where I need to be\\n\\n[Bridge]\\n\\nThe city never sleeps\\nIts heart forever beats\\n\\n[Outro]\\nIn the shadows\\nIn the shadows\",\n    \"bpm\": 85,\n    \"duration\": 207,\n    \"keyscale\": \"F minor\",\n    \"language\": \"en\",\n    \"timesignature\": \"4\"\n}"
  },
  {
    "path": "examples/text2music/example_84.json",
    "content": "{\n    \"think\": true,\n    \"caption\": \"A heartfelt singer-songwriter track with warm acoustic guitar, subtle piano, and honest male vocals. The stripped-back production lets the storytelling shine through with gentle string swells in the chorus.\",\n    \"lyrics\": \"[Intro]\\n\\n[Verse 1]\\nI wrote this song at 2 AM\\nThinking about where I've been\\nAll the roads that led me here\\nAll the love and all the fear\\n\\n[Verse 2]\\nMy father's hands were rough and worn\\nWorked the fields since he was born\\nTaught me how to be a man\\nDid the best that he can\\n\\n[Chorus]\\nThese are the stories of my life\\nThe joy the pain the sacrifice\\nEvery chapter made me whole\\nThese stories shaped my soul\\n\\n[Verse 3]\\nFirst love broke my heart in two\\nThought I'd never make it through\\nBut time has got a way to heal\\nTeaching us what's truly real\\n\\n[Chorus]\\nThese are the stories of my life\\nThe joy the pain the sacrifice\\nEvery chapter made me whole\\nThese stories shaped my soul\\n\\n[Bridge]\\nAnd when my time has come to go\\nI hope these songs let people know\\n\\n[Outro]\\nThese stories shaped my soul\",\n    \"bpm\": 82,\n    \"duration\": 235,\n    \"keyscale\": \"G major\",\n    \"language\": \"en\",\n    \"timesignature\": \"4\"\n}"
  },
  {
    "path": "examples/text2music/example_85.json",
    "content": "{\n    \"think\": true,\n    \"caption\": \"A progressive rock epic with complex time signatures, intricate guitar work, and dynamic male vocals. Features extended instrumental passages, synthesizer layers, and dramatic shifts between soft and heavy sections.\",\n    \"lyrics\": \"[Intro]\\n\\n[Verse 1]\\nWaking in a world that's not my own\\nSeeds of doubt have long been sown\\nReality is bending at the seams\\nCan't tell the difference between life and dreams\\n\\n[Verse 2]\\nClockwork minds and digital souls\\nPlaying predetermined roles\\nAre we the masters or the slaves\\nOf the futures that we crave\\n\\n[Chorus]\\nParallel dimensions collide\\nNowhere left to run and hide\\nThe truth is stranger than we know\\nLet the revelation flow\\n\\n[Instrumental]\\n\\n[Verse 3]\\nQuantum leaps through space and time\\nSearching for the paradigm\\nEvery answer breeds more questions still\\nClimbing up the endless hill\\n\\n[Chorus]\\nParallel dimensions collide\\nNowhere left to run and hide\\n\\n[Outro]\",\n    \"bpm\": 132,\n    \"duration\": 239,\n    \"keyscale\": \"F# minor\",\n    \"language\": \"en\",\n    \"timesignature\": \"4\"\n}"
  },
  {
    "path": "examples/text2music/example_86.json",
    "content": "{\n    \"think\": true,\n    \"caption\": \"A sassy pop-R&B track with snappy finger snaps, groovy bass, and confident female vocals with attitude. Features call-and-response backing vocals, brass stabs, and a strutting beat perfect for empowerment anthems.\",\n    \"lyrics\": \"[Intro]\\n\\nMm hmm\\n\\n[Verse 1]\\nWalking in like I own the place\\nConfidence written on my face\\nThey can talk but I don't care\\nFlip my hair without a prayer\\n\\n[Pre-Chorus]\\nUsed to let them dim my shine\\nBut those days are left behind\\n\\n[Chorus]\\nI'm that girl yeah you know it's true\\nDoing things you wish you could do\\nCan't be stopped won't be denied\\nWatch me walk with all this pride\\nI'm that girl\\n\\n[Verse 2]\\nHaters gonna hate that's fine\\nI'm too busy on my grind\\nBuilding empires in my name\\nPlaying my own kind of game\\n\\n[Chorus]\\nI'm that girl yeah you know it's true\\nDoing things you wish you could do\\nCan't be stopped won't be denied\\nWatch me walk with all this pride\\n\\n[Bridge]\\nTo all my ladies feeling low\\nLet your inner goddess show\\n\\n[Outro]\\nI'm that girl\\nYeah I'm that girl\",\n    \"bpm\": 104,\n    \"duration\": 198,\n    \"keyscale\": \"E minor\",\n    \"language\": \"en\",\n    \"timesignature\": \"4\"\n}"
  },
  {
    "path": "examples/text2music/example_87.json",
    "content": "{\n    \"think\": true,\n    \"caption\": \"A melancholic post-punk track with angular guitar riffs, driving bass, and brooding baritone vocals. Features cold synth textures, mechanical drums, and a dark atmospheric production style.\",\n    \"lyrics\": \"[Intro]\\n\\n[Verse 1]\\nFluorescent lights flicker and fade\\nAnother night another masquerade\\nFaces blur in the crowded room\\nDancing slowly toward our doom\\n\\n[Verse 2]\\nConversations without meaning\\nSmiles that hide the silent screaming\\nWe perform our daily roles\\nEmpty vessels hollow souls\\n\\n[Chorus]\\nWe're all just ghosts in the machine\\nGoing through motions in between\\nSearching for something that feels real\\nSomething that we can truly feel\\n\\n[Verse 3]\\nConcrete towers touch the sky\\nMillions living asking why\\nConnected yet so far apart\\nLonely beats of every heart\\n\\n[Chorus]\\nWe're all just ghosts in the machine\\nGoing through motions in between\\n\\n[Outro]\\nGhosts in the machine\",\n    \"bpm\": 125,\n    \"duration\": 232,\n    \"keyscale\": \"C minor\",\n    \"language\": \"en\",\n    \"timesignature\": \"4\"\n}"
  },
  {
    "path": "examples/text2music/example_88.json",
    "content": "{\n    \"think\": true,\n    \"caption\": \"A warm Americana track with pedal steel guitar, acoustic strumming, and heartfelt male-female harmonies. Features fiddle accents, upright bass, and a nostalgic sound that evokes open highways and small-town memories.\",\n    \"lyrics\": \"[Intro]\\n\\n[Verse 1]\\nTwo lane highway stretching far\\nChasing down the evening star\\nWindows down and radio on\\nSinging to our favorite song\\n\\n[Verse 2]\\nPassed the town where we first met\\nA night I never will forget\\nYoung and wild without a plan\\nJust a girl and just a man\\n\\n[Chorus]\\nMiles and memories behind us now\\nWe made it through somehow\\nStill together still in love\\nThank the stars above\\n\\n[Verse 3]\\nHair is gray but hearts are young\\nBest songs still remain unsung\\nEvery wrinkle tells our tale\\nLove that never once grew stale\\n\\n[Chorus]\\nMiles and memories behind us now\\nWe made it through somehow\\nStill together still in love\\nThank the stars above\\n\\n[Outro]\\nThank the stars above\",\n    \"bpm\": 95,\n    \"duration\": 228,\n    \"keyscale\": \"A major\",\n    \"language\": \"en\",\n    \"timesignature\": \"4\"\n}"
  },
  {
    "path": "examples/text2music/example_89.json",
    "content": "{\n    \"think\": true,\n    \"caption\": \"A high-energy drum and bass track with rapid breakbeats, heavy sub-bass, and chopped vocal samples. Features aggressive synth stabs, rolling percussion, and an intense build-drop structure designed for the dancefloor.\",\n    \"lyrics\": \"[Intro]\\n\\n[Verse 1]\\nPressure rising can you feel it now\\nBass is dropping gonna show you how\\nSpeakers shaking walls are caving in\\nLet the madness begin\\n\\n[Build]\\nThree two one let it drop\\nOnce we start we never stop\\n\\n[Drop]\\nRun it back run it back\\nFeel the bass attack\\nRun it back run it back\\nNever looking back\\n\\n[Verse 2]\\nAdrenaline is pumping through my veins\\nBreaking free from all the chains\\nLost inside the rhythm and the sound\\nFeet don't touch the ground\\n\\n[Build]\\nThree two one let it drop\\nOnce we start we never stop\\n\\n[Drop]\\nRun it back run it back\\nFeel the bass attack\\nRun it back run it back\\nNever looking back\\n\\n[Breakdown]\\n\\n[Final Drop]\\nRun it back!\",\n    \"bpm\": 174,\n    \"duration\": 185,\n    \"keyscale\": \"F minor\",\n    \"language\": \"en\",\n    \"timesignature\": \"4\"\n}"
  },
  {
    "path": "examples/text2music/example_90.json",
    "content": "{\n    \"think\": true,\n    \"caption\": \"A theatrical cabaret track with dramatic piano, swinging rhythm section, and expressive female vocals. Features brass flourishes, dramatic dynamics, and a vintage showbiz atmosphere with modern production polish.\",\n    \"lyrics\": \"[Intro]\\n\\n[Verse 1]\\nWelcome to the show tonight\\nWhere shadows dance in candlelight\\nTake your seat and hold on tight\\nThings aren't always what they seem\\n\\n[Verse 2]\\nBehind the curtain secrets hide\\nMasks we wear to save our pride\\nBut when the spotlight hits the stage\\nWe bare our souls upon this page\\n\\n[Chorus]\\nLife is but a cabaret my friend\\nA beautiful show that has to end\\nSo raise your glass and join the dance\\nThis might be your only chance\\n\\n[Verse 3]\\nThe clown who cries the queen who falls\\nThe echoes bouncing off these walls\\nWe're all performers in this play\\nMaking magic every day\\n\\n[Chorus]\\nLife is but a cabaret my friend\\nA beautiful show that has to end\\n\\n[Outro]\\nThe show must go on\",\n    \"bpm\": 115,\n    \"duration\": 225,\n    \"keyscale\": \"Bb minor\",\n    \"language\": \"en\",\n    \"timesignature\": \"4\"\n}"
  },
  {
    "path": "examples/text2music/example_91.json",
    "content": "{\n    \"think\": true,\n    \"caption\": \"A gritty Southern rock track with slide guitar, Hammond organ, and gravelly male vocals. Features driving drums, bluesy guitar solos, and a swampy groove that captures the spirit of the American South.\",\n    \"lyrics\": \"[Intro]\\n\\n[Verse 1]\\nDown in Louisiana where the cypress grows\\nMuddy water and the bayou flows\\nGot my guitar and a bottle of rye\\nPlaying blues beneath the southern sky\\n\\n[Chorus]\\nSwamp rock running through my veins\\nWashing away all my pains\\nThis is where I belong\\nSinging my swamp rock song\\n\\n[Verse 2]\\nCrawfish boiling gators in the creek\\nBeen down here going on a week\\nNo cell service and I don't care\\nGot everything I need right here\\n\\n[Chorus]\\nSwamp rock running through my veins\\nWashing away all my pains\\nThis is where I belong\\nSinging my swamp rock song\\n\\n[Guitar Solo]\\n\\n[Outro]\\nSwamp rock\\nYeah swamp rock\",\n    \"bpm\": 105,\n    \"duration\": 240,\n    \"keyscale\": \"E major\",\n    \"language\": \"en\",\n    \"timesignature\": \"4\"\n}"
  },
  {
    "path": "examples/text2music/example_92.json",
    "content": "{\n    \"think\": true,\n    \"caption\": \"A chilled ambient electronic track with evolving pad textures, gentle arpeggios, and whispered vocals. Features field recordings, granular synthesis, and a meditative atmosphere perfect for relaxation and introspection.\",\n    \"lyrics\": \"[Intro]\\n\\n[Verse 1]\\nBreathing in the morning air\\nSunlight dancing everywhere\\nLet the world just fall away\\nFind your peace in this new day\\n\\n[Chorus]\\nBe still and know\\nLet your spirit flow\\nIn this moment find\\nQuiet of the mind\\n\\n[Verse 2]\\nWaves are lapping on the shore\\nNothing matters anymore\\nJust the rhythm of your heart\\nThis is where healing starts\\n\\n[Chorus]\\nBe still and know\\nLet your spirit flow\\nIn this moment find\\nQuiet of the mind\\n\\n[Outro]\\n\\nBe still\\nBe still\",\n    \"bpm\": 70,\n    \"duration\": 213,\n    \"keyscale\": \"C major\",\n    \"language\": \"en\",\n    \"timesignature\": \"4\"\n}"
  },
  {
    "path": "examples/text2music/example_93.json",
    "content": "{\n    \"think\": true,\n    \"caption\": \"A punchy garage rock track with fuzzy guitars, driving drums, and raw energetic vocals. Features lo-fi production aesthetic, catchy riffs, and a back-to-basics rock and roll attitude.\",\n    \"lyrics\": \"[Intro]\\n\\n[Verse 1]\\nFriday night and I'm feeling alive\\nGonna rock this town till the sun arrives\\nTurn it up don't turn it down\\nWe're the loudest band in this whole town\\n\\n[Chorus]\\nRock and roll will never die\\nRaise your fist up to the sky\\nPlay it loud and play it proud\\nWe're here to rock this crowd\\n\\n[Verse 2]\\nSweat is dripping amps are blown\\nThis is everything we've ever known\\nNo fancy tricks just three chords true\\nThis one goes out to you\\n\\n[Chorus]\\nRock and roll will never die\\nRaise your fist up to the sky\\nPlay it loud and play it proud\\nWe're here to rock this crowd\\n\\n[Bridge]\\n\\nOne two three four!\\n\\n[Outro]\\nRock and roll!\\nRock and roll!\",\n    \"bpm\": 145,\n    \"duration\": 175,\n    \"keyscale\": \"A major\",\n    \"language\": \"en\",\n    \"timesignature\": \"4\"\n}"
  },
  {
    "path": "examples/text2music/example_94.json",
    "content": "{\n    \"think\": true,\n    \"caption\": \"A vibrant Afrobeat track with polyrhythmic percussion, horn section, and call-and-response vocals. Features infectious guitar licks, driving bass, and an irresistible groove rooted in West African musical traditions.\",\n    \"lyrics\": \"[Intro]\\n\\n[Verse 1]\\nThe rhythm is calling from across the sea\\nAncient beats setting spirits free\\nMove your body let it sway\\nThis is how we start the day\\n\\n[Chorus]\\nDance to the Afrobeat\\nFeel it in your feet\\nLet the rhythm take you higher\\nFueled by ancestral fire\\n\\n[Verse 2]\\nFrom Lagos to the world we bring\\nThis joyful sound that makes us sing\\nUnity in every drum\\nTogether we become one\\n\\n[Chorus]\\nDance to the Afrobeat\\nFeel it in your feet\\nLet the rhythm take you higher\\nFueled by ancestral fire\\n\\n[Bridge]\\n\\nEverybody move!\\n\\n[Outro]\\nAfrobeat forever\\nAfrobeat together\",\n    \"bpm\": 112,\n    \"duration\": 211,\n    \"keyscale\": \"G minor\",\n    \"language\": \"en\",\n    \"timesignature\": \"4\"\n}"
  },
  {
    "path": "examples/text2music/example_95.json",
    "content": "{\n    \"think\": true,\n    \"caption\": \"A lush chamber pop track with string quartet, grand piano, and delicate female vocals. Features intricate arrangements, dynamic swells, and a cinematic quality that blends classical instrumentation with modern pop sensibilities.\",\n    \"lyrics\": \"[Intro]\\n\\n[Verse 1]\\nIn the gallery of my mind\\nPaintings of the life I left behind\\nEvery color tells a story\\nOf the love and all its glory\\n\\n[Verse 2]\\nViolin strings echo my heart\\nA symphony of every part\\nThe crescendo of our days\\nPlaying out in different ways\\n\\n[Chorus]\\nWe were a masterpiece\\nA work of art that found release\\nFramed in time forever more\\nBeautiful to the core\\n\\n[Verse 3]\\nNow the music softly fades\\nLike sunlight through the window shades\\nBut the melody remains\\nRunning through my veins\\n\\n[Chorus]\\nWe were a masterpiece\\nA work of art that found release\\nFramed in time forever more\\nBeautiful to the core\\n\\n[Outro]\\n\\nA masterpiece\",\n    \"bpm\": 72,\n    \"duration\": 231,\n    \"keyscale\": \"D minor\",\n    \"language\": \"en\",\n    \"timesignature\": \"3\"\n}"
  },
  {
    "path": "examples/text2music/example_96.json",
    "content": "{\n    \"think\": true,\n    \"caption\": \"A melancholic C-pop ballad featuring soft female vocals with piano accompaniment and gentle string arrangements. The production emphasizes emotional depth with reverb-laden vocals and a slow, heartfelt delivery that builds to a powerful chorus.\",\n    \"lyrics\": \"[Intro]\\n\\n[Verse 1]\\n窗外的雨滴落在玻璃上\\n模糊了你离开的方向\\n我还在原地傻傻等待\\n等一个不会回来的人\\n\\n[Pre-Chorus]\\n翻开手机里的照片\\n每一张都是回忆的碎片\\n\\n[Chorus]\\n如果时光能够倒流\\n我会紧紧握住你的手\\n不让眼泪代替所有的话\\n不让沉默变成永远的伤疤\\n\\n[Verse 2]\\n咖啡凉了我还在喝\\n苦涩的味道像极了生活\\n你说过的那些承诺\\n如今都变成了泡沫\\n\\n[Chorus]\\n如果时光能够倒流\\n我会紧紧握住你的手\\n不让眼泪代替所有的话\\n不让沉默变成永远的伤疤\\n\\n[Bridge]\\n也许放手才是最好的选择\\n让你去追寻你的快乐\\n\\n[Outro]\\n窗外的雨还在下\\n而我学会了放下\",\n    \"bpm\": 72,\n    \"duration\": 221,\n    \"keyscale\": \"G major\",\n    \"language\": \"zh\",\n    \"timesignature\": \"4\"\n}"
  },
  {
    "path": "examples/text2music/example_97.json",
    "content": "{\n    \"think\": true,\n    \"caption\": \"An energetic Chinese rock anthem with powerful male vocals, distorted electric guitars, and driving drums. The arrangement features aggressive riffs during verses and an explosive chorus with gang vocals.\",\n    \"lyrics\": \"[Intro]\\n\\n[Verse 1]\\n城市的霓虹刺痛我的眼\\n每个人都在为生存奔波\\n西装革履的外表下\\n藏着一颗疲惫的心\\n\\n[Pre-Chorus]\\n我不想再这样活着\\n我要打破所有的枷锁\\n\\n[Chorus]\\n燃烧吧 我的青春\\n就算粉身碎骨也不认输\\n呐喊吧 用尽全力\\n让世界听到我们的声音\\n\\n[Verse 2]\\n他们说梦想不能当饭吃\\n他们说现实会把你打醒\\n但我宁愿头破血流\\n也不愿浑浑噩噩过一生\\n\\n[Chorus]\\n燃烧吧 我的青春\\n就算粉身碎骨也不认输\\n呐喊吧 用尽全力\\n让世界听到我们的声音\\n\\n[Bridge]\\n\\n[Outro]\\n我们不会倒下\\n永远不会倒下\",\n    \"bpm\": 145,\n    \"duration\": 218,\n    \"keyscale\": \"E minor\",\n    \"language\": \"zh\",\n    \"timesignature\": \"4\"\n}"
  },
  {
    "path": "examples/text2music/example_98.json",
    "content": "{\n    \"think\": true,\n    \"caption\": \"A dreamy Chinese R&B track with smooth male vocals, lo-fi beats, and jazzy chord progressions. The production features warm synth pads, subtle bass grooves, and atmospheric textures creating a late-night urban vibe.\",\n    \"lyrics\": \"[Intro]\\n\\n[Verse 1]\\n凌晨三点的街道\\n只有路灯陪我思考\\n耳机里放着老歌\\n想起了你的微笑\\n\\n[Pre-Chorus]\\n我们的故事\\n像褪色的照片\\n\\n[Chorus]\\n在这个城市的夜晚\\n我一个人慢慢走\\n霓虹灯闪烁的街角\\n到处都是你的影子\\n想你 想你 想你\\n却不敢再打扰你\\n\\n[Verse 2]\\n手机屏幕亮了又暗\\n我打了几个字又删\\n明明只是想问你好不好\\n却变成了最难开口的话\\n\\n[Chorus]\\n在这个城市的夜晚\\n我一个人慢慢走\\n霓虹灯闪烁的街角\\n到处都是你的影子\\n\\n[Outro]\\n夜还很长\\n思念更长\",\n    \"bpm\": 85,\n    \"duration\": 232,\n    \"keyscale\": \"Db major\",\n    \"language\": \"zh\",\n    \"timesignature\": \"4\"\n}"
  },
  {
    "path": "examples/text2music/example_99.json",
    "content": "{\n    \"think\": true,\n    \"caption\": \"A traditional Chinese ancient style song (古风) featuring ethereal female vocals with traditional instruments like guzheng, erhu, and bamboo flute. The arrangement blends classical Chinese melodies with modern production elements.\",\n    \"lyrics\": \"[Intro]\\n\\n[Verse 1]\\n月落乌啼霜满天\\n江枫渔火对愁眠\\n一壶浊酒话离别\\n千里江山入梦来\\n\\n[Verse 2]\\n青丝白发转瞬间\\n红尘往事如云烟\\n执笔写下相思意\\n却不知寄往何方\\n\\n[Chorus]\\n长亭外 古道边\\n芳草碧连天\\n问君此去几时还\\n来时莫徘徊\\n\\n[Verse 3]\\n琴声悠悠诉衷肠\\n谁人知我心中伤\\n明月千里寄相思\\n只愿君心似我心\\n\\n[Chorus]\\n长亭外 古道边\\n芳草碧连天\\n问君此去几时还\\n来时莫徘徊\\n\\n[Outro]\\n\\n此情可待成追忆\\n只是当时已惘然\",\n    \"bpm\": 68,\n    \"duration\": 220,\n    \"keyscale\": \"A minor\",\n    \"language\": \"zh\",\n    \"timesignature\": \"4\"\n}"
  },
  {
    "path": "generate_examples.py",
    "content": "#!/usr/bin/env python3\n\"\"\"\nBatch Generate Text2Music Examples using LM\nGenerates 50 examples and saves them to examples/text2music/\n\"\"\"\nimport os\nimport json\nimport sys\nfrom pathlib import Path\n\n# Add project root to path\nproject_root = Path(__file__).parent\nsys.path.insert(0, str(project_root))\n\nfrom acestep.llm_inference import LLMHandler\nfrom loguru import logger\nfrom tqdm import tqdm\n\n\ndef generate_examples(num_examples=50, output_dir=\"examples/text2music\", start_index=1):\n    \"\"\"\n    Generate examples using LM and save to JSON files\n    \n    Args:\n        num_examples: Number of examples to generate\n        output_dir: Output directory for JSON files\n        start_index: Starting index for example files\n    \"\"\"\n    # Initialize LLM Handler\n    logger.info(\"Initializing LLM Handler...\")\n    llm_handler = LLMHandler()\n    \n    # Initialize LM\n    checkpoint_dir = os.path.join(project_root, \"checkpoints\")\n    \n    # Use default LM model\n    available_models = llm_handler.get_available_5hz_lm_models()\n    if not available_models:\n        logger.error(\"No 5Hz LM models found in checkpoints directory\")\n        return\n    \n    # Prefer acestep-5Hz-lm-0.6B if available\n    lm_model = \"acestep-5Hz-lm-0.6B\" if \"acestep-5Hz-lm-0.6B\" in available_models else available_models[0]\n    logger.info(f\"Using LM model: {lm_model}\")\n    \n    # Initialize LM\n    status_msg, success = llm_handler.initialize(\n        checkpoint_dir=checkpoint_dir,\n        lm_model_path=lm_model,\n        backend=\"vllm\",  # Use vllm for faster generation\n        device=\"auto\",\n        offload_to_cpu=False,\n        dtype=None,\n    )\n    \n    if not success:\n        logger.error(f\"Failed to initialize LM: {status_msg}\")\n        return\n    \n    logger.info(f\"LM initialized successfully: {status_msg}\")\n    \n    # Create output directory if it doesn't exist\n    os.makedirs(output_dir, exist_ok=True)\n    \n    # Generate examples\n    successful_count = 0\n    failed_count = 0\n    \n    for i in tqdm(range(num_examples), desc=\"Generating examples\"):\n        example_num = start_index + i\n        output_file = os.path.join(output_dir, f\"example_{example_num:02d}.json\")\n        \n        logger.info(f\"Generating example {example_num}/{start_index + num_examples - 1}...\")\n        \n        try:\n            # Generate example using LM\n            metadata, status = llm_handler.understand_audio_from_codes(\n                audio_codes=\"NO USER INPUT\",  # Empty input triggers example generation\n                use_constrained_decoding=True,\n                temperature=0.85,\n                cfg_scale=1.0,\n                top_k=None,\n                top_p=0.9,\n            )\n            \n            if not metadata:\n                logger.warning(f\"Failed to generate example {example_num}: {status}\")\n                failed_count += 1\n                continue\n            \n            # Build JSON data with all available fields\n            example_data = {\n                \"think\": True,  # Always true for LM-generated examples\n                \"caption\": metadata.get(\"caption\", \"\"),\n                \"lyrics\": metadata.get(\"lyrics\", \"\"),\n            }\n            \n            # Add optional metadata fields if they exist and are not \"N/A\"\n            if \"bpm\" in metadata and metadata[\"bpm\"] not in [None, \"N/A\", \"\"]:\n                try:\n                    # Convert to int if it's a valid number\n                    example_data[\"bpm\"] = int(metadata[\"bpm\"]) if isinstance(metadata[\"bpm\"], (int, str)) else metadata[\"bpm\"]\n                except (ValueError, TypeError):\n                    example_data[\"bpm\"] = metadata[\"bpm\"]\n            \n            if \"duration\" in metadata and metadata[\"duration\"] not in [None, \"N/A\", \"\"]:\n                try:\n                    # Convert to int if it's a valid number\n                    example_data[\"duration\"] = int(metadata[\"duration\"]) if isinstance(metadata[\"duration\"], (int, str)) else metadata[\"duration\"]\n                except (ValueError, TypeError):\n                    example_data[\"duration\"] = metadata[\"duration\"]\n            \n            if \"keyscale\" in metadata and metadata[\"keyscale\"] not in [None, \"N/A\", \"\"]:\n                example_data[\"keyscale\"] = metadata[\"keyscale\"]\n            \n            if \"language\" in metadata and metadata[\"language\"] not in [None, \"N/A\", \"\"]:\n                example_data[\"language\"] = metadata[\"language\"]\n            \n            if \"timesignature\" in metadata and metadata[\"timesignature\"] not in [None, \"N/A\", \"\"]:\n                example_data[\"timesignature\"] = metadata[\"timesignature\"]\n            \n            # Save to JSON file\n            with open(output_file, 'w', encoding='utf-8') as f:\n                json.dump(example_data, f, ensure_ascii=False, indent=4)\n            \n            logger.info(f\"✅ Saved example {example_num} to {output_file}\")\n            logger.info(f\"   Caption preview: {example_data['caption'][:100]}...\")\n            successful_count += 1\n            \n        except Exception as e:\n            logger.error(f\"❌ Error generating example {example_num}: {str(e)}\")\n            failed_count += 1\n            continue\n    \n    # Summary\n    logger.info(f\"\\n{'='*60}\")\n    logger.info(f\"Generation complete!\")\n    logger.info(f\"Successful: {successful_count}/{num_examples}\")\n    logger.info(f\"Failed: {failed_count}/{num_examples}\")\n    logger.info(f\"Output directory: {output_dir}\")\n    logger.info(f\"{'='*60}\\n\")\n\n\nif __name__ == \"__main__\":\n    import argparse\n    \n    parser = argparse.ArgumentParser(description=\"Generate text2music examples using LM\")\n    parser.add_argument(\"--num\", type=int, default=100, help=\"Number of examples to generate (default: 100)\")\n    parser.add_argument(\"--output-dir\", type=str, default=\"examples/text2music\", help=\"Output directory (default: examples/text2music)\")\n    parser.add_argument(\"--start-index\", type=int, default=1, help=\"Starting index for example files (default: 1)\")\n    \n    args = parser.parse_args()\n    \n    generate_examples(\n        num_examples=args.num,\n        output_dir=args.output_dir,\n        start_index=args.start_index\n    )\n"
  },
  {
    "path": "install_uv.bat",
    "content": "@echo off\nsetlocal enabledelayedexpansion\nREM Install uv Package Manager\nREM This script installs uv using PowerShell or winget\nREM\nREM Usage:\nREM   install_uv.bat           - Interactive mode (default)\nREM   install_uv.bat --silent  - Silent mode for script calls\nREM\nREM Exit codes:\nREM   0 - Success (uv installed and available)\nREM   1 - Installation failed\nREM   2 - User cancelled (interactive mode only)\n\nREM Check for silent mode\nset SILENT_MODE=0\nif /i \"%~1\"==\"--silent\" set SILENT_MODE=1\nif /i \"%~1\"==\"-s\" set SILENT_MODE=1\n\nif %SILENT_MODE% EQU 0 (\n    echo ========================================\n    echo Install uv Package Manager\n    echo ========================================\n    echo.\n    echo This script will install uv, a fast Python package manager.\n    echo Installation location: %USERPROFILE%\\.local\\bin\\\n    echo.\n    echo Press any key to continue or Ctrl+C to cancel...\n    pause >nul\n    echo.\n)\n\nREM Check if uv is already installed\nwhere uv >nul 2>&1\nif !ERRORLEVEL! EQU 0 (\n    if %SILENT_MODE% EQU 1 (\n        REM In silent mode, uv already installed is success\n        endlocal & exit /b 0\n    )\n\n    echo uv is already installed!\n    echo Current version:\n    uv --version\n    echo.\n    echo Installation location:\n    where uv\n    echo.\n\n    set /p REINSTALL=\"Reinstall uv? (Y/N): \"\n    if /i not \"!REINSTALL!\"==\"Y\" (\n        echo.\n        echo Installation cancelled.\n        pause\n        endlocal & exit /b 2\n    )\n    echo.\n)\n\nif %SILENT_MODE% EQU 0 (\n    echo Installing uv...\n    echo.\n)\n\nREM Try PowerShell first (preferred method)\nif %SILENT_MODE% EQU 0 (\n    echo [Method 1] Using PowerShell...\n    echo This may take a few moments...\n    echo.\n)\n\nREM Check if PowerShell is available\npowershell -Command \"Write-Host 'PowerShell is available'\" >nul 2>&1\nif !ERRORLEVEL! EQU 0 (\n    REM Install uv using PowerShell\n    if %SILENT_MODE% EQU 1 (\n        powershell -NoProfile -ExecutionPolicy Bypass -Command \"Invoke-RestMethod https://astral.sh/uv/install.ps1 | Invoke-Expression\" >nul 2>&1\n    ) else (\n        echo Downloading uv installer...\n        powershell -NoProfile -ExecutionPolicy Bypass -Command \"Invoke-RestMethod https://astral.sh/uv/install.ps1 | Invoke-Expression\"\n    )\n\n    if !ERRORLEVEL! EQU 0 (\n        goto :VerifyInstallation\n    ) else (\n        if %SILENT_MODE% EQU 0 (\n            echo.\n            echo PowerShell installation failed, trying winget...\n            echo.\n        )\n    )\n) else (\n    if %SILENT_MODE% EQU 0 (\n        echo [Info] PowerShell not available, trying winget...\n        echo.\n    )\n)\n\nREM Fallback to winget (Windows 10 1809+ / Windows 11)\nwhere winget >nul 2>&1\nif !ERRORLEVEL! EQU 0 (\n    if %SILENT_MODE% EQU 0 (\n        echo [Method 2] Using winget ^(Windows Package Manager^)...\n        echo.\n    )\n\n    if %SILENT_MODE% EQU 1 (\n        winget install --id=astral-sh.uv -e --silent >nul 2>&1\n    ) else (\n        winget install --id=astral-sh.uv -e\n    )\n\n    if !ERRORLEVEL! EQU 0 (\n        if %SILENT_MODE% EQU 0 (\n            echo.\n            echo ========================================\n            echo uv installed successfully via winget!\n            echo ========================================\n        )\n        goto :VerifyInstallation\n    ) else (\n        if %SILENT_MODE% EQU 0 (\n            echo.\n            echo winget installation also failed.\n            echo.\n        )\n    )\n) else (\n    if %SILENT_MODE% EQU 0 (\n        echo [Info] winget not available.\n        echo.\n    )\n)\n\nREM Both methods failed\nif %SILENT_MODE% EQU 0 (\n    echo ========================================\n    echo ERROR: All installation methods failed!\n    echo ========================================\n    echo.\n    echo Please install uv manually:\n    echo.\n    echo 1. Open PowerShell and run:\n    echo    irm https://astral.sh/uv/install.ps1 ^| iex\n    echo.\n    echo 2. Or use winget:\n    echo    winget install --id=astral-sh.uv -e\n    echo.\n    echo 3. Or download portable package:\n    echo    https://files.acemusic.ai/acemusic/win/ACE-Step-1.5.7z\n    echo.\n    pause\n)\nendlocal & exit /b 1\n\n:VerifyInstallation\n\nREM Check if uv is in PATH\nwhere uv >nul 2>&1\nif !ERRORLEVEL! EQU 0 (\n    if %SILENT_MODE% EQU 0 (\n        echo.\n        echo ========================================\n        echo Installation successful!\n        echo ========================================\n        echo.\n        echo uv version:\n        uv --version\n        echo.\n        echo Installation location:\n        where uv\n        echo.\n        echo You can now use ACE-Step by running:\n        echo   start_gradio_ui.bat\n        echo   start_api_server.bat\n        echo.\n        pause\n    )\n    endlocal & exit /b 0\n)\n\nREM Check in the default installation location and update PATH\nif exist \"%USERPROFILE%\\.local\\bin\\uv.exe\" (\n    endlocal & set \"PATH=%USERPROFILE%\\.local\\bin;%PATH%\" & goto :PostEndlocal_UserProfile\n)\nif exist \"%LOCALAPPDATA%\\Microsoft\\WinGet\\Links\\uv.exe\" (\n    endlocal & set \"PATH=%LOCALAPPDATA%\\Microsoft\\WinGet\\Links;%PATH%\" & goto :PostEndlocal_WinGet\n)\n\nREM Not found anywhere\nif %SILENT_MODE% EQU 0 (\n    echo.\n    echo ========================================\n    echo Installation completed but uv not found!\n    echo ========================================\n    echo.\n    echo Please restart your terminal and try again.\n    echo.\n    pause\n)\nendlocal & exit /b 1\n\n:PostEndlocal_UserProfile\nif \"%SILENT_MODE%\"==\"0\" (\n    echo.\n    echo ========================================\n    echo Installation successful!\n    echo ========================================\n    echo.\n    echo Installation location: %USERPROFILE%\\.local\\bin\\uv.exe\n    echo.\n    echo NOTE: uv is not in your PATH yet.\n    echo Please restart your terminal, or manually add to PATH:\n    echo   setx PATH \"%%PATH%%;%USERPROFILE%\\.local\\bin\"\n    echo.\n    echo For now, you can use the full path:\n    echo   %USERPROFILE%\\.local\\bin\\uv.exe --version\n    echo.\n    pause\n)\nexit /b 0\n\n:PostEndlocal_WinGet\nif \"%SILENT_MODE%\"==\"0\" (\n    echo.\n    echo ========================================\n    echo Installation successful!\n    echo ========================================\n    echo.\n    echo Installation location: %LOCALAPPDATA%\\Microsoft\\WinGet\\Links\\uv.exe\n    echo.\n    echo NOTE: uv is not in your PATH yet.\n    echo Please restart your terminal.\n    echo.\n    pause\n)\nexit /b 0\n"
  },
  {
    "path": "install_uv.sh",
    "content": "#!/usr/bin/env bash\n# Install uv Package Manager\n# This script installs uv using the official installer\n#\n# Usage:\n#   ./install_uv.sh           - Interactive mode (default)\n#   ./install_uv.sh --silent  - Silent mode for script calls\n#\n# Exit codes:\n#   0 - Success (uv installed and available)\n#   1 - Installation failed\n#   2 - User cancelled (interactive mode only)\n\nset -euo pipefail\n\nSILENT_MODE=0\nif [[ \"${1:-}\" == \"--silent\" || \"${1:-}\" == \"-s\" ]]; then\n    SILENT_MODE=1\nfi\n\nlog() {\n    if [[ \"$SILENT_MODE\" -eq 0 ]]; then\n        echo \"$@\"\n    fi\n}\n\n# Check if uv is already installed\nif command -v uv &>/dev/null; then\n    if [[ \"$SILENT_MODE\" -eq 1 ]]; then\n        exit 0\n    fi\n\n    echo \"uv is already installed!\"\n    echo \"Current version:\"\n    uv --version\n    echo\n    echo \"Installation location:\"\n    command -v uv\n    echo\n\n    read -rp \"Reinstall uv? (Y/N): \" REINSTALL\n    if [[ \"${REINSTALL^^}\" != \"Y\" ]]; then\n        echo\n        echo \"Installation cancelled.\"\n        exit 2\n    fi\n    echo\nfi\n\nlog \"Installing uv...\"\nlog\n\n# Try the official installer (works on both Linux and macOS)\nlog \"Using official installer (curl)...\"\n\nif command -v curl &>/dev/null; then\n    if [[ \"$SILENT_MODE\" -eq 1 ]]; then\n        curl -LsSf https://astral.sh/uv/install.sh 2>/dev/null | sh >/dev/null 2>&1 || true\n    else\n        log \"Downloading uv installer...\"\n        curl -LsSf https://astral.sh/uv/install.sh | sh || true\n    fi\nelif command -v wget &>/dev/null; then\n    log \"curl not found, trying wget...\"\n    if [[ \"$SILENT_MODE\" -eq 1 ]]; then\n        wget -qO- https://astral.sh/uv/install.sh 2>/dev/null | sh >/dev/null 2>&1 || true\n    else\n        wget -qO- https://astral.sh/uv/install.sh | sh || true\n    fi\nelse\n    log \"========================================\"\n    log \"ERROR: Neither curl nor wget found!\"\n    log \"========================================\"\n    log\n    log \"Please install curl or wget first:\"\n    log\n    if [[ \"$(uname)\" == \"Darwin\" ]]; then\n        log \"  brew install curl\"\n    else\n        log \"  Ubuntu/Debian: sudo apt install curl\"\n        log \"  CentOS/RHEL:   sudo yum install curl\"\n        log \"  Arch:          sudo pacman -S curl\"\n    fi\n    log\n    exit 1\nfi\n\n# Update PATH to include common uv install locations\nexport PATH=\"$HOME/.local/bin:$HOME/.cargo/bin:$PATH\"\n\n# Verify installation\nif command -v uv &>/dev/null; then\n    log\n    log \"========================================\"\n    log \"Installation successful!\"\n    log \"========================================\"\n    log\n    log \"uv version:\"\n    log \"$(uv --version)\"\n    log\n    log \"Installation location:\"\n    log \"$(command -v uv)\"\n    log\n    log \"You can now use ACE-Step by running:\"\n    log \"  ./start_gradio_ui.sh\"\n    log \"  ./start_api_server.sh\"\n    if [[ \"$(uname)\" == \"Darwin\" ]]; then\n        log \"  ./start_gradio_ui_macos.sh  (Apple Silicon with MLX)\"\n        log \"  ./start_api_server_macos.sh (Apple Silicon with MLX)\"\n    fi\n    log\n    exit 0\nfi\n\n# Check default installation location\nif [[ -x \"$HOME/.local/bin/uv\" ]]; then\n    log\n    log \"========================================\"\n    log \"Installation successful!\"\n    log \"========================================\"\n    log\n    log \"Installation location: $HOME/.local/bin/uv\"\n    log\n    log \"NOTE: uv is not in your PATH yet.\"\n    log \"Add to your shell profile:\"\n    log \"  echo 'export PATH=\\\"\\$HOME/.local/bin:\\$PATH\\\"' >> ~/.bashrc\"\n    log \"  source ~/.bashrc\"\n    log\n    exit 0\nfi\n\nif [[ -x \"$HOME/.cargo/bin/uv\" ]]; then\n    log\n    log \"========================================\"\n    log \"Installation successful!\"\n    log \"========================================\"\n    log\n    log \"Installation location: $HOME/.cargo/bin/uv\"\n    log\n    log \"NOTE: uv is not in your PATH yet.\"\n    log \"Add to your shell profile:\"\n    log \"  echo 'export PATH=\\\"\\$HOME/.cargo/bin:\\$PATH\\\"' >> ~/.bashrc\"\n    log \"  source ~/.bashrc\"\n    log\n    exit 0\nfi\n\n# Installation failed\nlog\nlog \"========================================\"\nlog \"ERROR: Installation failed!\"\nlog \"========================================\"\nlog\nlog \"Please install uv manually:\"\nlog\nlog \"  curl -LsSf https://astral.sh/uv/install.sh | sh\"\nlog\nif [[ \"$(uname)\" == \"Darwin\" ]]; then\n    log \"Or using Homebrew:\"\n    log \"  brew install uv\"\nfi\nlog\nexit 1\n"
  },
  {
    "path": "merge_config.bat",
    "content": "@echo off\nREM Config Merge Helper\nREM This script helps merge backed up files with new version\n\nsetlocal enabledelayedexpansion\n\necho ========================================\necho ACE-Step Backup Merge Helper\necho ========================================\necho.\n\nREM Check for backup directories\nset FOUND_BACKUPS=0\necho Searching for backup directories...\necho.\n\nfor /d %%d in (\"%~dp0.update_backup_*\") do (\n    set FOUND_BACKUPS=1\n    set \"CURRENT_BACKUP_DIR=%%d\"\n    echo Found backup: %%~nxd\n    echo   Location: %%d\n    echo   Files:\n    for /f \"delims=\" %%f in ('dir /b /s \"%%d\\*.*\" 2^>nul') do (\n        set \"FILEPATH=%%f\"\n        REM Use call to safely handle the string replacement\n        call set \"FILEPATH=%%FILEPATH:!CURRENT_BACKUP_DIR!\\=%%\"\n        echo     - !FILEPATH!\n    )\n    echo.\n)\n\nif %FOUND_BACKUPS% EQU 0 (\n    echo No backup directories found.\n    echo.\n    echo Backups are created when updates conflict with your local changes.\n    pause\n    exit /b 0\n)\n\necho ========================================\necho Merge Options\necho ========================================\necho.\necho 1. Compare backup with current files (opens Notepad)\necho 2. Restore a file from backup (overwrites current)\necho 3. List all backed up files\necho 4. Delete old backups\necho 5. Exit\necho.\n\nset /p CHOICE=\"Select option (1-5): \"\n\nif \"%CHOICE%\"==\"1\" goto :Compare\nif \"%CHOICE%\"==\"2\" goto :Restore\nif \"%CHOICE%\"==\"3\" goto :ListFiles\nif \"%CHOICE%\"==\"4\" goto :DeleteBackups\nif \"%CHOICE%\"==\"5\" exit /b 0\n\necho Invalid choice.\npause\nexit /b 1\n\n:Compare\necho.\necho ========================================\necho Compare Files\necho ========================================\necho.\necho Available backup directories:\nset INDEX=0\nfor /d %%d in (\"%~dp0.update_backup_*\") do (\n    set /a INDEX+=1\n    set BACKUP_!INDEX!=%%d\n    echo !INDEX!. %%~nxd\n)\n\nif %INDEX% EQU 0 (\n    echo No backups found.\n    pause\n    exit /b 0\n)\n\necho.\nset /p BACKUP_CHOICE=\"Select backup number: \"\n\nset SELECTED_BACKUP=!BACKUP_%BACKUP_CHOICE%!\nif not defined SELECTED_BACKUP (\n    echo Invalid selection.\n    pause\n    exit /b 1\n)\n\necho.\necho Files in backup:\nset \"SELECTED_BACKUP_DISPLAY=!SELECTED_BACKUP!\"\nfor /f \"delims=\" %%f in ('dir /b /s \"!SELECTED_BACKUP!\\*.*\" 2^>nul') do (\n    set \"FILEPATH=%%f\"\n    REM Use call to safely handle the string replacement\n    call set \"FILEPATH=%%FILEPATH:!SELECTED_BACKUP_DISPLAY!\\=%%\"\n    echo   - !FILEPATH!\n)\n\necho.\nset /p FILE_NAME=\"Enter filename to compare (e.g., start_gradio_ui.bat or acestep\\handler.py): \"\n\nset BACKUP_FILE=%SELECTED_BACKUP%\\%FILE_NAME%\nset CURRENT_FILE=%~dp0%FILE_NAME%\n\nif not exist \"%BACKUP_FILE%\" (\n    echo Backup file not found: %BACKUP_FILE%\n    pause\n    exit /b 1\n)\n\nif not exist \"%CURRENT_FILE%\" (\n    echo Current file not found: %CURRENT_FILE%\n    pause\n    exit /b 1\n)\n\necho.\necho Opening files for comparison...\necho.\necho Backup version (LEFT):  %BACKUP_FILE%\necho Current version (RIGHT): %CURRENT_FILE%\necho.\n\nREM Open both files side by side\nstart \"\" notepad \"%BACKUP_FILE%\"\ntimeout /t 1 /nobreak >nul\nstart \"\" notepad \"%CURRENT_FILE%\"\n\necho.\necho Files opened in Notepad.\necho Compare the files and manually apply your configuration changes.\necho.\npause\nexit /b 0\n\n:Restore\necho.\necho ========================================\necho Restore File from Backup\necho ========================================\necho.\necho [Warning] This will OVERWRITE the current file!\necho.\necho Available backup directories:\nset INDEX=0\nfor /d %%d in (\"%~dp0.update_backup_*\") do (\n    set /a INDEX+=1\n    set BACKUP_!INDEX!=%%d\n    echo !INDEX!. %%~nxd\n)\n\nif %INDEX% EQU 0 (\n    echo No backups found.\n    pause\n    exit /b 0\n)\n\necho.\nset /p BACKUP_CHOICE=\"Select backup number: \"\n\nset SELECTED_BACKUP=!BACKUP_%BACKUP_CHOICE%!\nif not defined SELECTED_BACKUP (\n    echo Invalid selection.\n    pause\n    exit /b 1\n)\n\necho.\necho Files in backup:\nset \"SELECTED_BACKUP_DISPLAY=!SELECTED_BACKUP!\"\nfor /f \"delims=\" %%f in ('dir /b /s \"!SELECTED_BACKUP!\\*.*\" 2^>nul') do (\n    set \"FILEPATH=%%f\"\n    REM Use call to safely handle the string replacement\n    call set \"FILEPATH=%%FILEPATH:!SELECTED_BACKUP_DISPLAY!\\=%%\"\n    echo   - !FILEPATH!\n)\n\necho.\nset /p FILE_NAME=\"Enter filename to restore (e.g., start_gradio_ui.bat or acestep\\handler.py): \"\n\nset BACKUP_FILE=%SELECTED_BACKUP%\\%FILE_NAME%\nset CURRENT_FILE=%~dp0%FILE_NAME%\n\nif not exist \"%BACKUP_FILE%\" (\n    echo Backup file not found: %BACKUP_FILE%\n    pause\n    exit /b 1\n)\n\necho.\necho About to restore:\necho   From: %BACKUP_FILE%\necho   To:   %CURRENT_FILE%\necho.\nset /p CONFIRM=\"Are you sure? This will overwrite the current file. (Y/N): \"\n\nif /i \"%CONFIRM%\"==\"Y\" (\n    copy /y \"%BACKUP_FILE%\" \"%CURRENT_FILE%\" >nul\n    if !ERRORLEVEL! EQU 0 (\n        echo.\n        echo [Success] File restored successfully.\n    ) else (\n        echo.\n        echo [Error] Failed to restore file.\n    )\n) else (\n    echo.\n    echo Restore cancelled.\n)\n\necho.\npause\nexit /b 0\n\n:ListFiles\necho.\necho ========================================\necho All Backed Up Files\necho ========================================\necho.\n\nfor /d %%d in (\"%~dp0.update_backup_*\") do (\n    set \"CURRENT_BACKUP_DIR=%%d\"\n    echo Backup: %%~nxd\n    echo Location: %%d\n    echo Files:\n    for /f \"delims=\" %%f in ('dir /b /s \"%%d\" 2^>nul') do (\n        set \"FILEPATH=%%f\"\n        REM Use call to safely handle the string replacement\n        call set \"FILEPATH=%%FILEPATH:!CURRENT_BACKUP_DIR!\\=%%\"\n        echo   - !FILEPATH!\n    )\n    echo.\n)\n\npause\nexit /b 0\n\n:DeleteBackups\necho.\necho ========================================\necho Delete Old Backups\necho ========================================\necho.\necho [Warning] This will permanently delete backup directories!\necho.\necho Available backups:\nfor /d %%d in (\"%~dp0.update_backup_*\") do (\n    echo   - %%~nxd\n)\n\necho.\nset /p DELETE_CONFIRM=\"Delete all backups? (Y/N): \"\n\nif /i \"%DELETE_CONFIRM%\"==\"Y\" (\n    echo.\n    echo Deleting backups...\n    for /d %%d in (\"%~dp0.update_backup_*\") do (\n        echo   Deleting: %%~nxd\n        rmdir /s /q \"%%d\" 2>nul\n    )\n    echo.\n    echo [Done] Backups deleted.\n) else (\n    echo.\n    echo Deletion cancelled.\n)\n\necho.\npause\nexit /b 0\n"
  },
  {
    "path": "merge_config.sh",
    "content": "#!/usr/bin/env bash\n# Config Merge Helper - Linux/macOS\n# This script helps merge backed up files with new version\n\nset -euo pipefail\nSCRIPT_DIR=\"$(cd \"$(dirname \"${BASH_SOURCE[0]}\")\" && pwd)\"\n\necho \"========================================\"\necho \"ACE-Step Backup Merge Helper\"\necho \"========================================\"\necho\n\n# Check for backup directories\nFOUND_BACKUPS=0\nBACKUP_DIRS=()\n\necho \"Searching for backup directories...\"\necho\n\nfor dir in \"$SCRIPT_DIR\"/.update_backup_*; do\n    [[ -d \"$dir\" ]] || continue\n    FOUND_BACKUPS=1\n    BACKUP_DIRS+=(\"$dir\")\n    echo \"Found backup: $(basename \"$dir\")\"\n    echo \"  Location: $dir\"\n    echo \"  Files:\"\n    find \"$dir\" -type f | while read -r f; do\n        echo \"    - ${f#$dir/}\"\n    done\n    echo\ndone\n\nif [[ $FOUND_BACKUPS -eq 0 ]]; then\n    echo \"No backup directories found.\"\n    echo\n    echo \"Backups are created when updates conflict with your local changes.\"\n    exit 0\nfi\n\necho \"========================================\"\necho \"Merge Options\"\necho \"========================================\"\necho\necho \"1. Compare backup with current files\"\necho \"2. Restore a file from backup (overwrites current)\"\necho \"3. List all backed up files\"\necho \"4. Delete old backups\"\necho \"5. Exit\"\necho\n\nread -rp \"Select option (1-5): \" CHOICE\n\ncase \"$CHOICE\" in\n    1)\n        echo\n        echo \"========================================\"\n        echo \"Compare Files\"\n        echo \"========================================\"\n        echo\n        echo \"Available backup directories:\"\n        for i in \"${!BACKUP_DIRS[@]}\"; do\n            echo \"  $((i + 1)). $(basename \"${BACKUP_DIRS[$i]}\")\"\n        done\n        echo\n\n        read -rp \"Select backup number: \" BACKUP_CHOICE\n        BACKUP_IDX=$((BACKUP_CHOICE - 1))\n\n        if [[ $BACKUP_IDX -lt 0 || $BACKUP_IDX -ge ${#BACKUP_DIRS[@]} ]]; then\n            echo \"Invalid selection.\"\n            exit 1\n        fi\n\n        SELECTED_BACKUP=\"${BACKUP_DIRS[$BACKUP_IDX]}\"\n        echo\n        echo \"Files in backup:\"\n        find \"$SELECTED_BACKUP\" -type f | while read -r f; do\n            echo \"  - ${f#$SELECTED_BACKUP/}\"\n        done\n        echo\n\n        read -rp \"Enter filename to compare (e.g., start_gradio_ui.sh or acestep/handler.py): \" FILE_NAME\n\n        BACKUP_FILE=\"$SELECTED_BACKUP/$FILE_NAME\"\n        CURRENT_FILE=\"$SCRIPT_DIR/$FILE_NAME\"\n\n        if [[ ! -f \"$BACKUP_FILE\" ]]; then\n            echo \"Backup file not found: $BACKUP_FILE\"\n            exit 1\n        fi\n\n        if [[ ! -f \"$CURRENT_FILE\" ]]; then\n            echo \"Current file not found: $CURRENT_FILE\"\n            exit 1\n        fi\n\n        echo\n        echo \"Comparing files...\"\n        echo \"Backup version:  $BACKUP_FILE\"\n        echo \"Current version: $CURRENT_FILE\"\n        echo\n\n        # Use diff to compare\n        if command -v colordiff &>/dev/null; then\n            colordiff -u \"$BACKUP_FILE\" \"$CURRENT_FILE\" || true\n        else\n            diff -u \"$BACKUP_FILE\" \"$CURRENT_FILE\" || true\n        fi\n        ;;\n\n    2)\n        echo\n        echo \"========================================\"\n        echo \"Restore File from Backup\"\n        echo \"========================================\"\n        echo\n        echo \"[Warning] This will OVERWRITE the current file!\"\n        echo\n        echo \"Available backup directories:\"\n        for i in \"${!BACKUP_DIRS[@]}\"; do\n            echo \"  $((i + 1)). $(basename \"${BACKUP_DIRS[$i]}\")\"\n        done\n        echo\n\n        read -rp \"Select backup number: \" BACKUP_CHOICE\n        BACKUP_IDX=$((BACKUP_CHOICE - 1))\n\n        if [[ $BACKUP_IDX -lt 0 || $BACKUP_IDX -ge ${#BACKUP_DIRS[@]} ]]; then\n            echo \"Invalid selection.\"\n            exit 1\n        fi\n\n        SELECTED_BACKUP=\"${BACKUP_DIRS[$BACKUP_IDX]}\"\n        echo\n        echo \"Files in backup:\"\n        find \"$SELECTED_BACKUP\" -type f | while read -r f; do\n            echo \"  - ${f#$SELECTED_BACKUP/}\"\n        done\n        echo\n\n        read -rp \"Enter filename to restore (e.g., start_gradio_ui.sh or acestep/handler.py): \" FILE_NAME\n\n        BACKUP_FILE=\"$SELECTED_BACKUP/$FILE_NAME\"\n        CURRENT_FILE=\"$SCRIPT_DIR/$FILE_NAME\"\n\n        if [[ ! -f \"$BACKUP_FILE\" ]]; then\n            echo \"Backup file not found: $BACKUP_FILE\"\n            exit 1\n        fi\n\n        echo\n        echo \"About to restore:\"\n        echo \"  From: $BACKUP_FILE\"\n        echo \"  To:   $CURRENT_FILE\"\n        echo\n\n        read -rp \"Are you sure? This will overwrite the current file. (Y/N): \" CONFIRM\n        if [[ \"${CONFIRM^^}\" == \"Y\" ]]; then\n            cp \"$BACKUP_FILE\" \"$CURRENT_FILE\"\n            echo\n            echo \"[Success] File restored successfully.\"\n        else\n            echo\n            echo \"Restore cancelled.\"\n        fi\n        ;;\n\n    3)\n        echo\n        echo \"========================================\"\n        echo \"All Backed Up Files\"\n        echo \"========================================\"\n        echo\n\n        for dir in \"${BACKUP_DIRS[@]}\"; do\n            echo \"Backup: $(basename \"$dir\")\"\n            echo \"Location: $dir\"\n            echo \"Files:\"\n            find \"$dir\" -type f | while read -r f; do\n                echo \"  - ${f#$dir/}\"\n            done\n            echo\n        done\n        ;;\n\n    4)\n        echo\n        echo \"========================================\"\n        echo \"Delete Old Backups\"\n        echo \"========================================\"\n        echo\n        echo \"[Warning] This will permanently delete backup directories!\"\n        echo\n        echo \"Available backups:\"\n        for dir in \"${BACKUP_DIRS[@]}\"; do\n            echo \"  - $(basename \"$dir\")\"\n        done\n        echo\n\n        read -rp \"Delete all backups? (Y/N): \" DELETE_CONFIRM\n        if [[ \"${DELETE_CONFIRM^^}\" == \"Y\" ]]; then\n            echo\n            echo \"Deleting backups...\"\n            for dir in \"${BACKUP_DIRS[@]}\"; do\n                echo \"  Deleting: $(basename \"$dir\")\"\n                rm -rf \"$dir\"\n            done\n            echo\n            echo \"[Done] Backups deleted.\"\n        else\n            echo\n            echo \"Deletion cancelled.\"\n        fi\n        ;;\n\n    5)\n        exit 0\n        ;;\n\n    *)\n        echo \"Invalid choice.\"\n        exit 1\n        ;;\nesac\n"
  },
  {
    "path": "openrouter/__init__.py",
    "content": ""
  },
  {
    "path": "openrouter/client_test.py",
    "content": "\"\"\"\nACE-Step OpenRouter API 客户端测试代码\n\n使用 requests 库测试 API 的各个端点和功能模式。\n\nUsage:\n    python -m openrouter.test_client\n    python -m openrouter.test_client --base-url http://127.0.0.1:8002\n    python -m openrouter.test_client --api-key your-api-key\n\"\"\"\n\nimport argparse\nimport base64\nimport json\nimport os\nimport sys\nimport time\nfrom typing import Optional\n\nimport requests\n\n# This file is an executable API client script, not a pytest test module.\n__test__ = False\n\n\n# =============================================================================\n# 配置\n# =============================================================================\n\nDEFAULT_BASE_URL = \"https://api.acemusic.ai\"\nOUTPUT_DIR = os.path.join(os.path.dirname(__file__), \"test_outputs\")\n\n\ndef get_headers(api_key: Optional[str] = None) -> dict:\n    \"\"\"构建请求头\"\"\"\n    headers = {\"Content-Type\": \"application/json\"}\n    if api_key:\n        headers[\"Authorization\"] = f\"Bearer {api_key}\"\n    return headers\n\n\ndef handle_response(resp, audio_filename: str) -> bool:\n    \"\"\"处理 API 响应并保存音频\"\"\"\n    print(f\"状态码: {resp.status_code}\")\n\n    if resp.status_code != 200:\n        print(f\"错误响应: {resp.text}\")\n        return False\n\n    data = resp.json()\n    message = data[\"choices\"][0][\"message\"]\n    content = message.get(\"content\") or \"\"\n    audio_list = message.get(\"audio\") or []\n\n    print(f\"\\n内容:\\n{content if content else '(无文本内容)'}\")\n    print(f\"音频数量: {len(audio_list)}\")\n\n    if audio_list and len(audio_list) > 0:\n        audio_url = audio_list[0].get(\"audio_url\", {}).get(\"url\", \"\")\n        if audio_url:\n            filepath = save_audio(audio_url, audio_filename)\n            print(f\"音频已保存: {filepath}\")\n        else:\n            print(\"警告: audio_url 为空\")\n    else:\n        print(\"警告: 没有返回音频数据\")\n\n    return True\n\n\ndef save_audio(audio_url: str, filename: str) -> str:\n    \"\"\"从 base64 data URL 保存音频文件\"\"\"\n    os.makedirs(OUTPUT_DIR, exist_ok=True)\n\n    # 解析 data URL: data:audio/mpeg;base64,<data>\n    if not audio_url.startswith(\"data:\"):\n        print(f\"  [警告] 无效的 audio URL 格式\")\n        return \"\"\n\n    # 提取 base64 数据\n    b64_data = audio_url.split(\",\", 1)[1]\n    audio_bytes = base64.b64decode(b64_data)\n\n    filepath = os.path.join(OUTPUT_DIR, filename)\n    with open(filepath, \"wb\") as f:\n        f.write(audio_bytes)\n\n    return filepath\n\n\n# =============================================================================\n# 测试函数\n# =============================================================================\n\ndef test_health(base_url: str, api_key: Optional[str] = None) -> bool:\n    \"\"\"测试健康检查端点\"\"\"\n    print(\"\\n\" + \"=\" * 60)\n    print(\"测试: GET /health\")\n    print(\"=\" * 60)\n\n    try:\n        resp = requests.get(f\"{base_url}/health\", timeout=10)\n        print(f\"状态码: {resp.status_code}\")\n        print(f\"响应: {json.dumps(resp.text, indent=2, ensure_ascii=False)}\")\n        return resp.status_code == 200\n    except Exception as e:\n        print(f\"错误: {e}\")\n        return False\n\n\ndef test_list_models(base_url: str, api_key: Optional[str] = None) -> bool:\n    \"\"\"测试模型列表端点\"\"\"\n    print(\"\\n\" + \"=\" * 60)\n    print(\"测试: GET /api/v1/models\")\n    print(\"=\" * 60)\n\n    try:\n        resp = requests.get(\n            f\"{base_url}/api/v1/models\",\n            headers=get_headers(api_key),\n            timeout=10\n        )\n        print(f\"状态码: {resp.status_code}\")\n        print(f\"响应: {json.dumps(resp.json(), indent=2, ensure_ascii=False)}\")\n        return resp.status_code == 200\n    except Exception as e:\n        print(f\"错误: {e}\")\n        return False\n\n\ndef test_natural_language_mode(base_url: str, api_key: Optional[str] = None) -> bool:\n    \"\"\"测试自然语言模式 (Sample Mode)\"\"\"\n    print(\"\\n\" + \"=\" * 60)\n    print(\"测试: 自然语言模式 (Sample Mode)\")\n    print(\"=\" * 60)\n\n    payload = {\n        \"messages\": [\n            {\"role\": \"user\", \"content\": \"Generate an upbeat pop song about summer and travel\"}\n        ],\n        \"sample_mode\": True,\n        \"audio_config\": {\n            \"vocal_language\": \"en\",\n            \"duration\": 30,\n        },\n    }\n\n    print(f\"请求: {json.dumps(payload, indent=2, ensure_ascii=False)}\")\n\n    try:\n        resp = requests.post(\n            f\"{base_url}/v1/chat/completions\",\n            headers=get_headers(api_key),\n            json=payload,\n            timeout=300\n        )\n        print(f\"状态码: {resp.status_code}\")\n\n        if resp.status_code == 200:\n            data = resp.json()\n            message = data[\"choices\"][0][\"message\"]\n            content = message.get(\"content\") or \"\"\n            audio_list = message.get(\"audio\") or []\n\n            print(f\"\\n内容:\\n{content if content else '(无文本内容)'}\")\n            print(f\"音频数量: {len(audio_list)}\")\n\n            if audio_list and len(audio_list) > 0:\n                audio_item = audio_list[0]\n                audio_url = audio_item.get(\"audio_url\", {}).get(\"url\", \"\")\n                if audio_url:\n                    filepath = save_audio(audio_url, \"test_natural_language.mp3\")\n                    print(f\"音频已保存: {filepath}\")\n                else:\n                    print(\"警告: audio_url 为空\")\n            else:\n                print(\"警告: 没有返回音频数据\")\n\n            return True\n        else:\n            print(f\"错误响应: {resp.text}\")\n            return False\n    except Exception as e:\n        print(f\"错误: {e}\")\n        import traceback\n        traceback.print_exc()\n        return False\n\n\ndef test_tagged_mode(base_url: str, api_key: Optional[str] = None) -> bool:\n    \"\"\"测试标签模式 (Tagged Mode)\"\"\"\n    print(\"\\n\" + \"=\" * 60)\n    print(\"测试: 标签模式 (Tagged Mode)\")\n    print(\"=\" * 60)\n\n    content = \"\"\"<prompt>A gentle acoustic ballad in C major, 80 BPM, female vocal</prompt>\n<lyrics>[Verse 1]\nSunlight through the window\nA brand new day begins\n\n[Chorus]\nWe are the dreamers\nWe are the light</lyrics>\"\"\"\n\n    payload = {\n        \"messages\": [{\"role\": \"user\", \"content\": content}],\n        \"audio_config\": {\n            \"vocal_language\": \"en\",\n            \"duration\": 30,\n        },\n    }\n\n    print(f\"请求: {json.dumps(payload, indent=2, ensure_ascii=False)}\")\n\n    try:\n        resp = requests.post(\n            f\"{base_url}/v1/chat/completions\",\n            headers=get_headers(api_key),\n            json=payload,\n            timeout=300\n        )\n        print(f\"状态码: {resp.status_code}\")\n\n        if resp.status_code == 200:\n            data = resp.json()\n            message = data[\"choices\"][0][\"message\"]\n            content = message.get(\"content\") or \"\"\n            audio_list = message.get(\"audio\") or []\n\n            print(f\"\\n内容:\\n{content if content else '(无文本内容)'}\")\n            print(f\"音频数量: {len(audio_list)}\")\n\n            if audio_list and len(audio_list) > 0:\n                audio_url = audio_list[0].get(\"audio_url\", {}).get(\"url\", \"\")\n                if audio_url:\n                    filepath = save_audio(audio_url, \"test_tagged_mode.mp3\")\n                    print(f\"音频已保存: {filepath}\")\n\n            return True\n        else:\n            print(f\"错误响应: {resp.text}\")\n            return False\n    except Exception as e:\n        print(f\"错误: {e}\")\n        import traceback\n        traceback.print_exc()\n        return False\n\n\ndef test_lyrics_only_mode(base_url: str, api_key: Optional[str] = None) -> bool:\n    \"\"\"测试纯歌词模式 (Lyrics-Only Mode)\"\"\"\n    print(\"\\n\" + \"=\" * 60)\n    print(\"测试: 纯歌词模式 (Lyrics-Only Mode)\")\n    print(\"=\" * 60)\n\n    lyrics = \"\"\"[Verse 1]\nWalking down the street\nFeeling the beat\n\n[Chorus]\nDance with me tonight\nUnder the moonlight\"\"\"\n\n    payload = {\n        \"messages\": [{\"role\": \"user\", \"content\": lyrics}],\n        \"audio_config\": {\n            \"vocal_language\": \"en\",\n            \"duration\": 30,\n        },\n    }\n\n    print(f\"请求: {json.dumps(payload, indent=2, ensure_ascii=False)}\")\n\n    try:\n        resp = requests.post(\n            f\"{base_url}/v1/chat/completions\",\n            headers=get_headers(api_key),\n            json=payload,\n            timeout=300\n        )\n        print(f\"状态码: {resp.status_code}\")\n\n        return handle_response(resp, \"test_lyrics_only.mp3\")\n    except Exception as e:\n        print(f\"错误: {e}\")\n        import traceback\n        traceback.print_exc()\n        return False\n\n\ndef test_instrumental_mode(base_url: str, api_key: Optional[str] = None) -> bool:\n    \"\"\"测试纯音乐模式 (Instrumental Mode)\"\"\"\n    print(\"\\n\" + \"=\" * 60)\n    print(\"测试: 纯音乐模式 (Instrumental Mode)\")\n    print(\"=\" * 60)\n\n    payload = {\n        \"messages\": [\n            {\"role\": \"user\", \"content\": \"<prompt>Epic orchestral cinematic score, dramatic and powerful</prompt>\"}\n        ],\n        \"audio_config\": {\n            \"instrumental\": True,\n            \"duration\": 30,\n        },\n    }\n\n    print(f\"请求: {json.dumps(payload, indent=2, ensure_ascii=False)}\")\n\n    try:\n        resp = requests.post(\n            f\"{base_url}/v1/chat/completions\",\n            headers=get_headers(api_key),\n            json=payload,\n            timeout=300\n        )\n        print(f\"状态码: {resp.status_code}\")\n\n        return handle_response(resp, \"test_instrumental.mp3\")\n    except Exception as e:\n        print(f\"错误: {e}\")\n        import traceback\n        traceback.print_exc()\n        return False\n\n\ndef test_streaming_mode(base_url: str, api_key: Optional[str] = None) -> bool:\n    \"\"\"测试流式响应模式 (Streaming Mode)\"\"\"\n    print(\"\\n\" + \"=\" * 60)\n    print(\"测试: 流式响应模式 (Streaming Mode)\")\n    print(\"=\" * 60)\n\n    payload = {\n        \"messages\": [\n            {\"role\": \"user\", \"content\": \"Generate a cheerful guitar piece\"}\n        ],\n        \"stream\": True,\n        \"sample_mode\": True,\n        \"audio_config\": {\n            \"instrumental\": True,\n            \"duration\": 30,\n        },\n    }\n\n    print(f\"请求: {json.dumps(payload, indent=2, ensure_ascii=False)}\")\n\n    try:\n        resp = requests.post(\n            f\"{base_url}/v1/chat/completions\",\n            headers=get_headers(api_key),\n            json=payload,\n            stream=True,\n            timeout=300\n        )\n        print(f\"状态码: {resp.status_code}\")\n\n        if resp.status_code == 200:\n            content_parts = []\n            audio_url = None\n\n            print(\"\\n接收流式数据:\")\n            for line in resp.iter_lines(decode_unicode=True):\n                if not line:\n                    continue\n\n                if not line.startswith(\"data: \"):\n                    continue\n\n                if line == \"data: [DONE]\":\n                    print(\"  [DONE]\")\n                    break\n\n                try:\n                    chunk = json.loads(line[6:])\n                    delta = chunk[\"choices\"][0][\"delta\"]\n                    finish_reason = chunk[\"choices\"][0].get(\"finish_reason\")\n\n                    if \"role\" in delta:\n                        print(f\"  角色: {delta['role']}\")\n\n                    if \"content\" in delta and delta[\"content\"]:\n                        content_parts.append(delta[\"content\"])\n                        # 心跳点不打印\n                        if delta[\"content\"] != \".\":\n                            print(f\"  内容: {delta['content'][:100]}...\")\n                        else:\n                            print(\"  [心跳]\")\n\n                    if \"audio\" in delta and delta[\"audio\"]:\n                        audio_item = delta[\"audio\"][0]\n                        audio_url = audio_item.get(\"audio_url\", {}).get(\"url\", \"\")\n                        if audio_url:\n                            print(f\"  音频数据已接收 (长度: {len(audio_url)} 字符)\")\n\n                    if finish_reason:\n                        print(f\"  完成原因: {finish_reason}\")\n\n                except json.JSONDecodeError as e:\n                    print(f\"  [解析错误] {e}\")\n\n            full_content = \"\".join(content_parts)\n            print(f\"\\n完整内容:\\n{full_content}\")\n\n            if audio_url:\n                filepath = save_audio(audio_url, \"test_streaming.mp3\")\n                print(f\"\\n音频已保存: {filepath}\")\n\n            return True\n        else:\n            print(f\"错误响应: {resp.text}\")\n            return False\n    except Exception as e:\n        print(f\"错误: {e}\")\n        return False\n\n\ndef test_full_parameters(base_url: str, api_key: Optional[str] = None) -> bool:\n    \"\"\"测试完整参数控制\"\"\"\n    print(\"\\n\" + \"=\" * 60)\n    print(\"测试: 完整参数控制\")\n    print(\"=\" * 60)\n\n    payload = {\n        \"messages\": [\n            {\n                \"role\": \"user\",\n                \"content\": \"<prompt>Dreamy lo-fi hip hop beat with vinyl crackle</prompt><lyrics>[inst]</lyrics>\"\n            }\n        ],\n        \"temperature\": 0.9,\n        \"top_p\": 0.95,\n        \"thinking\": False,\n        \"use_cot_caption\": True,\n        \"use_cot_language\": False,\n        \"use_format\": True,\n        \"audio_config\": {\n            \"bpm\": 85,\n            \"duration\": 30,\n            \"instrumental\": True,\n        },\n    }\n\n    print(f\"请求: {json.dumps(payload, indent=2, ensure_ascii=False)}\")\n\n    try:\n        resp = requests.post(\n            f\"{base_url}/v1/chat/completions\",\n            headers=get_headers(api_key),\n            json=payload,\n            timeout=300\n        )\n        print(f\"状态码: {resp.status_code}\")\n\n        return handle_response(resp, \"test_full_params.mp3\")\n    except Exception as e:\n        print(f\"错误: {e}\")\n        import traceback\n        traceback.print_exc()\n        return False\n\n\ndef test_error_handling(base_url: str, api_key: Optional[str] = None) -> bool:\n    \"\"\"测试错误处理\"\"\"\n    print(\"\\n\" + \"=\" * 60)\n    print(\"测试: 错误处理\")\n    print(\"=\" * 60)\n\n    # 测试空消息\n    print(\"\\n1. 测试空消息:\")\n    payload = {\"messages\": []}\n    try:\n        resp = requests.post(\n            f\"{base_url}/v1/chat/completions\",\n            headers=get_headers(api_key),\n            json=payload,\n            timeout=30\n        )\n        print(f\"  状态码: {resp.status_code}\")\n        print(f\"  响应: {resp.text[:200]}\")\n    except Exception as e:\n        print(f\"  错误: {e}\")\n\n    # 测试无内容消息\n    print(\"\\n2. 测试无内容消息:\")\n    payload = {\"messages\": [{\"role\": \"user\", \"content\": \"\"}]}\n    try:\n        resp = requests.post(\n            f\"{base_url}/v1/chat/completions\",\n            headers=get_headers(api_key),\n            json=payload,\n            timeout=30\n        )\n        print(f\"  状态码: {resp.status_code}\")\n        print(f\"  响应: {resp.text[:200]}\")\n    except Exception as e:\n        print(f\"  错误: {e}\")\n\n    return True\n\n\n# =============================================================================\n# 主函数\n# =============================================================================\n\ndef main():\n    parser = argparse.ArgumentParser(description=\"ACE-Step OpenRouter API 客户端测试\")\n    parser.add_argument(\n        \"--base-url\",\n        default=os.getenv(\"OPENROUTER_BASE_URL\", DEFAULT_BASE_URL),\n        help=f\"API 基础 URL (默认: {DEFAULT_BASE_URL})\"\n    )\n    parser.add_argument(\n        \"--api-key\",\n        default=os.getenv(\"OPENROUTER_API_KEY\"),\n        help=\"API 密钥 (可选)\"\n    )\n    parser.add_argument(\n        \"--test\",\n        choices=[\n            \"health\", \"models\", \"natural\", \"tagged\", \"lyrics\",\n            \"instrumental\", \"streaming\", \"full\", \"error\", \"all\"\n        ],\n        default=\"health\",\n        help=\"要运行的测试 (默认: health)\"\n    )\n    args = parser.parse_args()\n\n    print(\"=\" * 60)\n    print(\"ACE-Step OpenRouter API 客户端测试\")\n    print(\"=\" * 60)\n    print(f\"Base URL: {args.base_url}\")\n    print(f\"API Key: {'已设置' if args.api_key else '未设置'}\")\n    print(f\"输出目录: {OUTPUT_DIR}\")\n\n    tests = {\n        \"health\": test_health,\n        \"models\": test_list_models,\n        \"natural\": test_natural_language_mode,\n        \"tagged\": test_tagged_mode,\n        \"lyrics\": test_lyrics_only_mode,\n        \"instrumental\": test_instrumental_mode,\n        \"streaming\": test_streaming_mode,\n        \"full\": test_full_parameters,\n        \"error\": test_error_handling,\n    }\n\n    results = {}\n\n    if args.test == \"all\":\n        for name, test_func in tests.items():\n            results[name] = test_func(args.base_url, args.api_key)\n    else:\n        results[args.test] = tests[args.test](args.base_url, args.api_key)\n\n    # 打印测试结果摘要\n    print(\"\\n\" + \"=\" * 60)\n    print(\"测试结果摘要\")\n    print(\"=\" * 60)\n    for name, passed in results.items():\n        status = \"通过\" if passed else \"失败\"\n        print(f\"  {name}: {status}\")\n\n    # 返回退出码\n    all_passed = all(results.values())\n    sys.exit(0 if all_passed else 1)\n\n\nif __name__ == \"__main__\":\n    main()\n"
  },
  {
    "path": "openrouter/openrouter_api_server.py",
    "content": "\"\"\"OpenRouter-compatible API server for ACE-Step V1.5.\n\nProvides OpenAI Chat Completions API format for text-to-music generation.\n\nEndpoints:\n- GET  /v1/models            List available models with pricing\n- POST /v1/chat/completions  Generate music from text prompt\n- GET  /health               Health check\n\nUsage:\n    python -m openrouter.openrouter_api_server --host 0.0.0.0 --port 8002\n\"\"\"\n\nfrom __future__ import annotations\n\nimport argparse\nimport asyncio\nimport base64\nimport functools\nimport json\nimport os\nimport sys\nimport tempfile\nimport time\nimport traceback\nfrom concurrent.futures import ThreadPoolExecutor\nfrom contextlib import asynccontextmanager\nfrom typing import Any, Dict, List, Optional, Union\n\n# Add parent directory to path for imports\nsys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))\n\n# Load .env file from project root\nfrom dotenv import load_dotenv\n_project_root = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))\nload_dotenv(os.path.join(_project_root, \".env\"))\n\nfrom fastapi import FastAPI, HTTPException, Depends, Header, Request\nfrom fastapi.responses import JSONResponse, StreamingResponse\nfrom pydantic import BaseModel, Field\n\nfrom acestep.handler import AceStepHandler\nfrom acestep.llm_inference import LLMHandler\nfrom acestep.inference import (\n    GenerationParams,\n    GenerationConfig,\n    generate_music,\n    format_sample,\n)\nfrom acestep.constants import TASK_INSTRUCTIONS\n\n# =============================================================================\n# Constants\n# =============================================================================\n\nMODEL_ID = \"acemusic/acestep-v15-turbo\"\nMODEL_NAME = \"ACE-Step\"\nMODEL_CREATED = 1706688000  # Unix timestamp\n\n# Pricing (USD per token/unit) - adjust as needed\nPRICING_PROMPT = \"0\"\nPRICING_COMPLETION = \"0\"\nPRICING_REQUEST = \"0\"\n\n# =============================================================================\n# API Key Authentication\n# =============================================================================\n\n_api_key: Optional[str] = None\n\n\ndef set_api_key(key: Optional[str]):\n    \"\"\"Set the API key for authentication\"\"\"\n    global _api_key\n    _api_key = key\n\n\nasync def verify_api_key(authorization: Optional[str] = Header(None)):\n    \"\"\"Verify API key from Authorization header\"\"\"\n    if _api_key is None:\n        return  # No auth required\n\n    if not authorization:\n        raise HTTPException(status_code=401, detail=\"Missing Authorization header\")\n\n    # Support \"Bearer <key>\" format\n    if authorization.startswith(\"Bearer \"):\n        token = authorization[7:]\n    else:\n        token = authorization\n\n    if token != _api_key:\n        raise HTTPException(status_code=401, detail=\"Invalid API key\")\n\n\n# =============================================================================\n# Request/Response Models (OpenAI Compatible)\n# =============================================================================\n\nclass ChatMessage(BaseModel):\n    role: str = \"user\"\n    content: Union[str, List[Dict[str, Any]]] = \"\"\n\n\nclass AudioConfig(BaseModel):\n    \"\"\"Audio generation configuration.\"\"\"\n    duration: Optional[float] = None\n    format: str = \"mp3\"\n    bpm: Optional[int] = None\n    key_scale: Optional[str] = None\n    time_signature: Optional[str] = None\n    vocal_language: Optional[str] = None\n    instrumental: Optional[bool] = None\n\n\nclass ChatCompletionRequest(BaseModel):\n    model: str = MODEL_ID\n    messages: List[ChatMessage] = Field(default_factory=list)\n    modalities: List[str] = Field(default=[\"audio\"])\n    audio_config: Optional[AudioConfig] = None\n    stream: bool = False  # Enable streaming response\n    temperature: float = 0.85\n    top_p: float = 0.9\n    max_tokens: Optional[int] = None\n    seed: Optional[Union[int, str]] = Field(default=None, description=\"Seed(s) for reproducibility. Comma-separated for batch (e.g. '42,123,456')\")\n    # ACE-Step specific parameters\n    thinking: bool = False\n    guidance_scale: Optional[float] = None\n    batch_size: Optional[int] = None\n    lyrics: str = \"\"\n    sample_mode: bool = False\n    use_format: bool = False\n    use_cot_caption: bool = True\n    use_cot_language: bool = True\n    use_cot_metas: Optional[bool] = None\n    # Task type\n    task_type: str = \"text2music\"\n    # Audio editing parameters\n    repainting_start: float = 0.0\n    repainting_end: Optional[float] = None\n    audio_cover_strength: float = 1.0\n    # Extended fields for ComfyUI node compatibility\n    audio_codes: str = \"\"\n    cover_noise_strength: float = 0.0\n    inference_steps: int = 8\n    infer_method: str = \"ode\"\n    lm_cfg_scale: float = 2.0\n    top_k: int = 0\n\n\nclass AudioUrlContent(BaseModel):\n    \"\"\"Audio URL content in OpenRouter format.\"\"\"\n    url: str = \"\"\n\n\nclass AudioOutputItem(BaseModel):\n    \"\"\"Single audio output item in OpenRouter format.\"\"\"\n    type: str = \"audio_url\"\n    audio_url: AudioUrlContent = Field(default_factory=AudioUrlContent)\n\n\nclass ResponseMessage(BaseModel):\n    role: str = \"assistant\"\n    content: Optional[str] = None\n    audio: Optional[List[AudioOutputItem]] = None\n    audio_codes: Optional[str] = None\n\n\nclass Choice(BaseModel):\n    index: int = 0\n    message: ResponseMessage\n    finish_reason: str = \"stop\"\n\n\nclass Usage(BaseModel):\n    prompt_tokens: int = 0\n    completion_tokens: int = 0\n    total_tokens: int = 0\n\n\nclass ChatCompletionResponse(BaseModel):\n    id: str = \"\"\n    object: str = \"chat.completion\"\n    created: int = 0\n    model: str = MODEL_ID\n    choices: List[Choice] = Field(default_factory=list)\n    usage: Usage = Field(default_factory=Usage)\n\n\n# Streaming response models\nclass DeltaContent(BaseModel):\n    \"\"\"Delta content for streaming responses.\"\"\"\n    role: Optional[str] = None\n    content: Optional[str] = None\n    audio: Optional[List[AudioOutputItem]] = None\n\n\nclass StreamChoice(BaseModel):\n    \"\"\"Single choice in streaming response.\"\"\"\n    index: int = 0\n    delta: DeltaContent = Field(default_factory=DeltaContent)\n    finish_reason: Optional[str] = None\n\n\nclass ChatCompletionChunk(BaseModel):\n    \"\"\"Streaming chunk response.\"\"\"\n    id: str = \"\"\n    object: str = \"chat.completion.chunk\"\n    created: int = 0\n    model: str = MODEL_ID\n    choices: List[StreamChoice] = Field(default_factory=list)\n\n\nclass ModelInfo(BaseModel):\n    id: str\n    name: str\n    created: int\n    description: str\n    input_modalities: List[str]\n    output_modalities: List[str]\n    context_length: int\n    pricing: Dict[str, str]\n    supported_sampling_parameters: List[str]\n\n\nclass ModelsResponse(BaseModel):\n    data: List[ModelInfo]\n\n\n# =============================================================================\n# Helper Functions\n# =============================================================================\n\ndef _get_project_root() -> str:\n    \"\"\"Get the project root directory.\"\"\"\n    current_file = os.path.abspath(__file__)\n    return os.path.dirname(os.path.dirname(current_file))\n\n\ndef _env_bool(name: str, default: bool) -> bool:\n    \"\"\"Parse boolean from environment variable.\"\"\"\n    v = os.getenv(name)\n    if v is None:\n        return default\n    return v.strip().lower() in {\"1\", \"true\", \"yes\", \"y\", \"on\"}\n\n\nimport re\n\n\ndef _looks_like_lyrics(text: str) -> bool:\n    \"\"\"\n    Heuristic to detect if text looks like song lyrics.\n    \"\"\"\n    if not text:\n        return False\n\n    # Check for common lyrics markers\n    lyrics_markers = [\n        \"[verse\", \"[chorus\", \"[bridge\", \"[intro\", \"[outro\",\n        \"[hook\", \"[pre-chorus\", \"[refrain\", \"[inst\",\n    ]\n    text_lower = text.lower()\n    for marker in lyrics_markers:\n        if marker in text_lower:\n            return True\n\n    # Check line structure (lyrics tend to have many short lines)\n    lines = [l.strip() for l in text.split(\"\\n\") if l.strip()]\n    if len(lines) >= 4:\n        avg_line_length = sum(len(l) for l in lines) / len(lines)\n        if avg_line_length < 60:\n            return True\n\n    return False\n\n\ndef _extract_tagged_content(text: str) -> tuple[str, str, str]:\n    \"\"\"\n    Extract content from <prompt> and <lyrics> tags.\n\n    Returns:\n        (prompt, lyrics, remaining_text)\n    \"\"\"\n    prompt = None\n    lyrics = None\n    remaining = text\n\n    # Extract <prompt>...</prompt>\n    prompt_match = re.search(r'<prompt>(.*?)</prompt>', text, re.DOTALL | re.IGNORECASE)\n    if prompt_match:\n        prompt = prompt_match.group(1).strip()\n        remaining = remaining.replace(prompt_match.group(0), '').strip()\n\n    # Extract <lyrics>...</lyrics>\n    lyrics_match = re.search(r'<lyrics>(.*?)</lyrics>', text, re.DOTALL | re.IGNORECASE)\n    if lyrics_match:\n        lyrics = lyrics_match.group(1).strip()\n        remaining = remaining.replace(lyrics_match.group(0), '').strip()\n\n    return prompt, lyrics, remaining\n\n\ndef _base64_to_temp_file(b64_data: str, audio_format: str = \"mp3\") -> str:\n    \"\"\"Save base64 audio data to temporary file.\"\"\"\n    if \",\" in b64_data:\n        b64_data = b64_data.split(\",\", 1)[1]\n\n    audio_bytes = base64.b64decode(b64_data)\n    suffix = f\".{audio_format}\" if not audio_format.startswith(\".\") else audio_format\n    fd, path = tempfile.mkstemp(suffix=suffix, prefix=\"openrouter_audio_\")\n    os.close(fd)\n\n    with open(path, \"wb\") as f:\n        f.write(audio_bytes)\n\n    return path\n\n\ndef _extract_prompt_and_lyrics(messages: List[ChatMessage]) -> tuple[str, str, str, List[str]]:\n    \"\"\"\n    Extract prompt (caption), lyrics, sample_query, and audio paths from messages.\n\n    Supports multimodal content (text + input_audio blocks).\n\n    Processing logic:\n    1. If <prompt> and/or <lyrics> tags present: extract tagged content\n    2. If no tags: use heuristic detection\n       - If text looks like lyrics -> set as lyrics\n       - If text doesn't look like lyrics -> set as sample_query (for LLM sample mode)\n\n    Multiple input_audio blocks are collected in order (like multiple images).\n    The caller routes them to src_audio / reference_audio based on task_type.\n\n    Returns:\n        (prompt, lyrics, sample_query, audio_paths)\n    \"\"\"\n    prompt = \"\"\n    lyrics = \"\"\n    sample_query = \"\"\n    audio_paths: List[str] = []\n    has_tags = False\n\n    # Get the last user message\n    for msg in reversed(messages):\n        if msg.role == \"user\" and msg.content:\n            # Handle multimodal content (list of parts)\n            if isinstance(msg.content, list):\n                text_parts = []\n                for part in msg.content:\n                    if isinstance(part, dict):\n                        part_type = part.get(\"type\", \"\")\n                        if part_type == \"text\":\n                            text_parts.append(part.get(\"text\", \"\").strip())\n                        elif part_type == \"input_audio\":\n                            audio_data = part.get(\"input_audio\", {})\n                            if isinstance(audio_data, dict):\n                                b64_data = audio_data.get(\"data\", \"\")\n                                audio_format = audio_data.get(\"format\", \"mp3\")\n                                if b64_data:\n                                    try:\n                                        path = _base64_to_temp_file(b64_data, audio_format)\n                                        audio_paths.append(path)\n                                    except Exception:\n                                        pass\n                content = \"\\n\".join(text_parts).strip()\n            else:\n                content = msg.content.strip()\n\n            if not content:\n                break\n\n            # Try to extract tagged content first\n            tagged_prompt, tagged_lyrics, remaining = _extract_tagged_content(content)\n\n            if tagged_prompt is not None or tagged_lyrics is not None:\n                has_tags = True\n                prompt = tagged_prompt or \"\"\n                lyrics = tagged_lyrics or \"\"\n                if remaining and not prompt:\n                    prompt = remaining\n            else:\n                # No tags - use heuristic detection\n                if _looks_like_lyrics(content):\n                    lyrics = content\n                else:\n                    prompt = content\n            break\n\n    return prompt, lyrics, sample_query, audio_paths\n\n\ndef _read_audio_as_base64(file_path: str) -> str:\n    \"\"\"Read audio file and return Base64 encoded string.\"\"\"\n    with open(file_path, \"rb\") as f:\n        return base64.b64encode(f.read()).decode(\"utf-8\")\n\n\ndef _audio_to_base64_url(audio_path: str, audio_format: str = \"mp3\") -> str:\n    \"\"\"Convert audio file to base64 data URL (OpenRouter format).\"\"\"\n    if not audio_path or not os.path.exists(audio_path):\n        return \"\"\n\n    mime_types = {\n        \"mp3\": \"audio/mpeg\",\n        \"wav\": \"audio/wav\",\n        \"flac\": \"audio/flac\",\n        \"ogg\": \"audio/ogg\",\n        \"m4a\": \"audio/mp4\",\n        \"aac\": \"audio/aac\",\n    }\n    mime_type = mime_types.get(audio_format.lower(), \"audio/mpeg\")\n\n    with open(audio_path, \"rb\") as f:\n        audio_data = f.read()\n\n    b64_data = base64.b64encode(audio_data).decode(\"utf-8\")\n    return f\"data:{mime_type};base64,{b64_data}\"\n\n\ndef _format_lm_content(result: Dict[str, Any]) -> str:\n    \"\"\"\n    Format LM generation result as content string.\n\n    If LM was used, returns formatted metadata and lyrics.\n    Otherwise returns a simple success message.\n    \"\"\"\n    metadata = result.get(\"metadata\", {})\n    lyrics = result.get(\"lyrics\", \"\")\n\n    parts = []\n\n    # Add metadata section\n    meta_lines = []\n    if metadata.get(\"caption\"):\n        meta_lines.append(f\"**Caption:** {metadata['caption']}\")\n    if metadata.get(\"bpm\"):\n        meta_lines.append(f\"**BPM:** {metadata['bpm']}\")\n    if metadata.get(\"duration\"):\n        meta_lines.append(f\"**Duration:** {metadata['duration']}s\")\n    if metadata.get(\"keyscale\"):\n        meta_lines.append(f\"**Key:** {metadata['keyscale']}\")\n    if metadata.get(\"timesignature\"):\n        meta_lines.append(f\"**Time Signature:** {metadata['timesignature']}/4\")\n    if metadata.get(\"language\"):\n        meta_lines.append(f\"**Language:** {metadata['language']}\")\n\n    if meta_lines:\n        parts.append(\"## Metadata\\n\" + \"\\n\".join(meta_lines))\n\n    # Add lyrics section\n    if lyrics and lyrics.strip() and lyrics.strip().lower() not in (\"[inst]\", \"[instrumental]\"):\n        parts.append(f\"## Lyrics\\n{lyrics}\")\n\n    if parts:\n        return \"\\n\\n\".join(parts)\n    else:\n        return \"Music generated successfully.\"\n\n\ndef _make_stream_chunk(\n    completion_id: str,\n    created: int,\n    model_id: str,\n    content: Optional[str] = None,\n    role: Optional[str] = None,\n    audio: Optional[List[AudioOutputItem]] = None,\n    finish_reason: Optional[str] = None,\n) -> str:\n    \"\"\"Build SSE chunk JSON string.\"\"\"\n    delta = DeltaContent()\n    if role:\n        delta.role = role\n    if content is not None:\n        delta.content = content\n    if audio is not None:\n        delta.audio = audio\n\n    chunk = ChatCompletionChunk(\n        id=completion_id,\n        created=created,\n        model=model_id,\n        choices=[\n            StreamChoice(\n                index=0,\n                delta=delta,\n                finish_reason=finish_reason,\n            )\n        ],\n    )\n    return f\"data: {chunk.model_dump_json()}\\n\\n\"\n\n\n# =============================================================================\n# Application Factory\n# =============================================================================\n\ndef create_app() -> FastAPI:\n    \"\"\"Create and configure the FastAPI application.\"\"\"\n    \n    # API Key from environment\n    api_key = os.getenv(\"OPENROUTER_API_KEY\", None)\n    set_api_key(api_key)\n    \n    @asynccontextmanager\n    async def lifespan(app: FastAPI):\n        \"\"\"Application lifespan: initialize and cleanup resources.\"\"\"\n\n        # Setup cache directories\n        project_root = _get_project_root()\n        cache_root = os.path.join(project_root, \".cache\", \"openrouter\")\n        tmp_root = os.path.join(cache_root, \"tmp\")\n\n        for p in [cache_root, tmp_root]:\n            os.makedirs(p, exist_ok=True)\n\n        # Initialize handlers\n        handler = AceStepHandler()\n        llm_handler = LLMHandler()\n\n        app.state.handler = handler\n        app.state.llm_handler = llm_handler\n        app.state._initialized = False\n        app.state._init_error = None\n        app.state._llm_initialized = False\n        app.state.temp_audio_dir = tmp_root\n\n        # Thread pool for blocking operations\n        executor = ThreadPoolExecutor(max_workers=1)\n        app.state.executor = executor\n\n        # =================================================================\n        # Initialize models at startup\n        # =================================================================\n        print(\"[OpenRouter API] Initializing models at startup...\")\n\n        config_path = os.getenv(\"ACESTEP_CONFIG_PATH\", \"acestep-v15-turbo\")\n        device = os.getenv(\"ACESTEP_DEVICE\", \"auto\")\n        use_flash_attention = _env_bool(\"ACESTEP_USE_FLASH_ATTENTION\", True)\n        offload_to_cpu = _env_bool(\"ACESTEP_OFFLOAD_TO_CPU\", False)\n        offload_dit_to_cpu = _env_bool(\"ACESTEP_OFFLOAD_DIT_TO_CPU\", False)\n        compile_model = _env_bool(\"ACESTEP_COMPILE_MODEL\", False)\n\n        # Initialize DiT model\n        print(f\"[OpenRouter API] Loading DiT model: {config_path}\")\n        status_msg, ok = handler.initialize_service(\n            project_root=project_root,\n            config_path=config_path,\n            device=device,\n            use_flash_attention=use_flash_attention,\n            compile_model=compile_model,\n            offload_to_cpu=offload_to_cpu,\n            offload_dit_to_cpu=offload_dit_to_cpu,\n        )\n\n        if not ok:\n            app.state._init_error = status_msg\n            print(f\"[OpenRouter API] ERROR: DiT model failed: {status_msg}\")\n            raise RuntimeError(status_msg)\n\n        app.state._initialized = True\n        print(f\"[OpenRouter API] DiT model loaded successfully\")\n\n        # Initialize LLM\n        print(\"[OpenRouter API] Loading LLM model...\")\n        checkpoint_dir = os.path.join(project_root, \"checkpoints\")\n        lm_model_path = os.getenv(\"ACESTEP_LM_MODEL_PATH\", \"acestep-5Hz-lm-0.6B\")\n        backend = os.getenv(\"ACESTEP_LM_BACKEND\", \"vllm\")\n        lm_offload = _env_bool(\"ACESTEP_LM_OFFLOAD_TO_CPU\", False)\n\n        try:\n            lm_status, lm_ok = llm_handler.initialize(\n                checkpoint_dir=checkpoint_dir,\n                lm_model_path=lm_model_path,\n                backend=backend,\n                device=device,\n                offload_to_cpu=lm_offload,\n                dtype=None,\n            )\n            app.state._llm_initialized = lm_ok\n            if lm_ok:\n                print(f\"[OpenRouter API] LLM model loaded: {lm_model_path}\")\n            else:\n                print(f\"[OpenRouter API] Warning: LLM failed: {lm_status}\")\n        except Exception as e:\n            app.state._llm_initialized = False\n            print(f\"[OpenRouter API] Warning: LLM init error: {e}\")\n\n        print(\"[OpenRouter API] All models initialized!\")\n\n        try:\n            yield\n        finally:\n            executor.shutdown(wait=False, cancel_futures=True)\n    \n    app = FastAPI(\n        title=\"ACE-Step OpenRouter API\",\n        version=\"1.0\",\n        description=\"OpenRouter-compatible API for text-to-music generation\",\n        lifespan=lifespan,\n    )\n    \n    # -------------------------------------------------------------------------\n    # Endpoints\n    # -------------------------------------------------------------------------\n    \n    @app.get(\"/v1/models\", response_model=ModelsResponse)\n    async def list_models(_: None = Depends(verify_api_key)) -> ModelsResponse:\n        \"\"\"List available models with capabilities and pricing.\"\"\"\n        return ModelsResponse(\n            data=[\n                ModelInfo(\n                    id=MODEL_ID,\n                    name=MODEL_NAME,\n                    created=MODEL_CREATED,\n                    description=\"High-performance text-to-music generation model. Supports multiple styles, lyrics input, and various audio durations.\",\n                    input_modalities=[\"text\", \"audio\"],\n                    output_modalities=[\"audio\", \"text\"],\n                    context_length=4096,\n                    pricing={\n                        \"prompt\": PRICING_PROMPT,\n                        \"completion\": PRICING_COMPLETION,\n                        \"request\": PRICING_REQUEST,\n                    },\n                    supported_sampling_parameters=[\"temperature\", \"top_p\"],\n                )\n            ]\n        )\n    \n    @app.post(\"/v1/chat/completions\")\n    async def chat_completions(\n        request: ChatCompletionRequest,\n        _: None = Depends(verify_api_key),\n    ):\n        \"\"\"\n        Generate music from text prompt (OpenAI Chat Completions format).\n\n        Input processing:\n        - With tags: use <prompt>...</prompt> and <lyrics>...</lyrics>\n        - Without tags: heuristic detection (lyrics vs sample_query for LLM)\n\n        Supports streaming mode when request.stream=True.\n        \"\"\"\n        # Check if model is initialized\n        if not app.state._initialized:\n            raise HTTPException(status_code=503, detail=\"Model not initialized\")\n\n        # Extract prompt, lyrics, sample_query, and audio paths from messages\n        prompt, lyrics_from_msg, sample_query, audio_paths = _extract_prompt_and_lyrics(request.messages)\n\n        # When lyrics or sample_mode is explicitly provided, the message text role\n        # is already known — skip auto-detection results.\n        if request.lyrics or request.sample_mode:\n            raw_text = prompt or sample_query or \"\"\n            if request.lyrics:\n                # lyrics provided → message text is the prompt\n                prompt = raw_text\n                lyrics_from_msg = \"\"\n                sample_query = \"\"\n            else:\n                # sample_mode → message text is the sample_query\n                prompt = \"\"\n                lyrics_from_msg = \"\"\n                sample_query = raw_text\n\n        lyrics = request.lyrics or lyrics_from_msg\n\n        # Validate input\n        if not prompt and not lyrics and not sample_query and not audio_paths:\n            raise HTTPException(status_code=400, detail=\"No input provided in messages\")\n\n        # Resolve audio_config parameters\n        audio_config = request.audio_config or AudioConfig()\n        resolved_vocal_language = audio_config.vocal_language or \"en\"\n        resolved_instrumental = audio_config.instrumental if audio_config.instrumental is not None else (not lyrics)\n        resolved_duration = audio_config.duration\n        resolved_bpm = audio_config.bpm\n        resolved_key_scale = audio_config.key_scale or \"\"\n        resolved_time_signature = audio_config.time_signature or \"\"\n\n        # Route audio paths based on task_type.\n        # cover / repaint / lego / extract / complete:\n        #   audio[0] → src_audio, audio[1] → reference_audio\n        # text2music (default):\n        #   audio[0] → reference_audio\n        reference_audio_path = None\n        src_audio_path = None\n        _SRC_AUDIO_TASK_TYPES = {\"cover\", \"repaint\", \"lego\", \"extract\", \"complete\"}\n        if audio_paths:\n            if request.task_type in _SRC_AUDIO_TASK_TYPES:\n                src_audio_path = audio_paths[0]\n                if len(audio_paths) > 1:\n                    reference_audio_path = audio_paths[1]\n            else:\n                reference_audio_path = audio_paths[0]\n\n        # Determine if instrumental\n        instrumental = resolved_instrumental\n\n        # Generate unique IDs\n        completion_id = f\"chatcmpl-{os.urandom(8).hex()}\"\n        created_timestamp = int(time.time())\n\n        def _run_lm_sample() -> Dict[str, Any]:\n            \"\"\"Run LLM sample generation or format_sample (blocking).\"\"\"\n            nonlocal prompt, lyrics, instrumental\n\n            llm = app.state.llm_handler if app.state._llm_initialized else None\n            lm_result = {\n                \"prompt\": prompt,\n                \"lyrics\": lyrics,\n                \"instrumental\": instrumental,\n                \"lm_used\": False,\n                \"metadata\": {},\n                \"format_has_duration\": False,\n            }\n\n            if sample_query and llm:\n                # Sample mode: LLM generates prompt and lyrics from query\n                try:\n                    sample_result, status_msg = llm.create_sample_from_query(\n                        query=sample_query,\n                        instrumental=instrumental,\n                        vocal_language=resolved_vocal_language,\n                        temperature=request.temperature,\n                        top_p=request.top_p,\n                    )\n                    if sample_result:\n                        lm_result[\"prompt\"] = sample_result.get(\"caption\", \"\") or prompt\n                        lm_result[\"lyrics\"] = sample_result.get(\"lyrics\", \"\") or lyrics\n                        lm_result[\"instrumental\"] = sample_result.get(\"instrumental\", instrumental)\n                        lm_result[\"lm_used\"] = True\n                        lm_result[\"format_has_duration\"] = bool(sample_result.get(\"duration\"))\n                        lm_result[\"metadata\"] = {\n                            \"caption\": lm_result[\"prompt\"],\n                            \"bpm\": sample_result.get(\"bpm\"),\n                            \"duration\": sample_result.get(\"duration\"),\n                            \"keyscale\": sample_result.get(\"keyscale\"),\n                            \"timesignature\": sample_result.get(\"timesignature\"),\n                            \"language\": sample_result.get(\"language\") or resolved_vocal_language,\n                        }\n                        print(f\"[OpenRouter API] Sample mode: {status_msg}\")\n                except Exception as e:\n                    print(f\"[OpenRouter API] Warning: create_sample_from_query failed: {e}\")\n                    if not prompt:\n                        lm_result[\"prompt\"] = sample_query\n\n            elif (prompt or lyrics) and llm and request.use_format:\n                # Format mode: use format_sample to enhance caption and lyrics\n                try:\n                    user_metadata = {}\n                    if resolved_bpm is not None:\n                        user_metadata[\"bpm\"] = resolved_bpm\n                    if resolved_duration:\n                        user_metadata[\"duration\"] = float(resolved_duration)\n                    if resolved_vocal_language and resolved_vocal_language != \"unknown\":\n                        user_metadata[\"language\"] = resolved_vocal_language\n\n                    format_result = format_sample(\n                        llm_handler=llm,\n                        caption=prompt,\n                        lyrics=lyrics,\n                        user_metadata=user_metadata if user_metadata else None,\n                        temperature=request.temperature,\n                        top_p=request.top_p,\n                        use_constrained_decoding=True,\n                    )\n\n                    if format_result.success:\n                        lm_result[\"prompt\"] = format_result.caption or prompt\n                        lm_result[\"lyrics\"] = format_result.lyrics or lyrics\n                        lm_result[\"lm_used\"] = True\n                        lm_result[\"format_has_duration\"] = bool(format_result.duration)\n                        lm_result[\"metadata\"] = {\n                            \"caption\": lm_result[\"prompt\"],\n                            \"bpm\": format_result.bpm or resolved_bpm,\n                            \"duration\": format_result.duration or resolved_duration,\n                            \"keyscale\": format_result.keyscale or None,\n                            \"timesignature\": format_result.timesignature or None,\n                            \"language\": format_result.language or resolved_vocal_language,\n                        }\n                        print(f\"[OpenRouter API] Format mode: {format_result.status_message}\")\n                    else:\n                        print(f\"[OpenRouter API] Warning: format_sample failed: {format_result.error}\")\n                except Exception as e:\n                    print(f\"[OpenRouter API] Warning: format_sample error: {e}\")\n\n            return lm_result\n\n        def _run_audio_generation(lm_result: Dict[str, Any]) -> Dict[str, Any]:\n            \"\"\"Run audio generation (blocking).\"\"\"\n            h: AceStepHandler = app.state.handler\n            llm = app.state.llm_handler if app.state._llm_initialized else None\n\n            gen_prompt = lm_result[\"prompt\"]\n            gen_lyrics = lm_result[\"lyrics\"]\n            gen_instrumental = lm_result[\"instrumental\"]\n\n            # Use metadata from LM/format if available, fallback to audio_config params\n            lm_meta = lm_result.get(\"metadata\", {})\n            gen_bpm = lm_meta.get(\"bpm\") or resolved_bpm\n            gen_duration = lm_meta.get(\"duration\") or (resolved_duration if resolved_duration else -1.0)\n            gen_keyscale = lm_meta.get(\"keyscale\") or resolved_key_scale\n            gen_timesignature = lm_meta.get(\"timesignature\") or resolved_time_signature\n            gen_language = lm_meta.get(\"language\") or resolved_vocal_language\n\n            is_sample_mode = bool(sample_query and lm_result.get(\"lm_used\"))\n            format_has_duration = lm_result.get(\"format_has_duration\", False)\n\n            default_timesteps = [0.97, 0.76, 0.615, 0.5, 0.395, 0.28, 0.18, 0.085, 0.0]\n\n            task_instruction = TASK_INSTRUCTIONS.get(request.task_type, TASK_INSTRUCTIONS[\"text2music\"])\n\n            no_lm_task = request.task_type in (\"cover\", \"repaint\")\n\n            # Auto-convert src_audio to codes for cover mode when no codes provided\n            resolved_audio_codes = request.audio_codes\n            if (src_audio_path and not resolved_audio_codes\n                    and request.task_type == \"cover\"):\n                try:\n                    codes_str = h.convert_src_audio_to_codes(src_audio_path)\n                    if codes_str and not codes_str.startswith(\"❌\"):\n                        resolved_audio_codes = codes_str\n                        print(f\"[OpenRouter API] Auto-converted src_audio to {len(codes_str)} chars of audio codes\")\n                except Exception as e:\n                    print(f\"[OpenRouter API] Warning: auto audio2code failed: {e}\")\n\n            resolved_thinking = False if no_lm_task else request.thinking\n            resolved_cot_caption = False if no_lm_task else request.use_cot_caption\n            resolved_cot_language = False if no_lm_task else request.use_cot_language\n            if request.use_cot_metas is not None:\n                resolved_cot_metas = False if no_lm_task else request.use_cot_metas\n            else:\n                resolved_cot_metas = False if no_lm_task else (not is_sample_mode and not format_has_duration)\n\n            params = GenerationParams(\n                task_type=request.task_type,\n                instruction=task_instruction,\n                reference_audio=reference_audio_path,\n                src_audio=src_audio_path,\n                audio_codes=resolved_audio_codes,\n                caption=gen_prompt,\n                lyrics=gen_lyrics,\n                instrumental=gen_instrumental,\n                vocal_language=gen_language,\n                bpm=gen_bpm,\n                keyscale=gen_keyscale,\n                timesignature=gen_timesignature,\n                duration=gen_duration if gen_duration else -1.0,\n                inference_steps=request.inference_steps,\n                infer_method=request.infer_method,\n                guidance_scale=request.guidance_scale if request.guidance_scale is not None else 7.0,\n                lm_temperature=request.temperature,\n                lm_cfg_scale=request.lm_cfg_scale,\n                lm_top_p=request.top_p,\n                lm_top_k=request.top_k,\n                thinking=resolved_thinking,\n                use_cot_metas=resolved_cot_metas,\n                use_cot_caption=resolved_cot_caption,\n                use_cot_language=resolved_cot_language,\n                use_constrained_decoding=True,\n                timesteps=default_timesteps,\n                repainting_start=request.repainting_start,\n                repainting_end=request.repainting_end if request.repainting_end is not None else -1,\n                audio_cover_strength=request.audio_cover_strength,\n                cover_noise_strength=request.cover_noise_strength,\n            )\n\n            # Resolve seed(s): parse into Optional[List[int]] for GenerationConfig.seeds\n            use_random_seed = request.seed is None\n            resolved_seeds = None\n            if request.seed is not None:\n                if isinstance(request.seed, int):\n                    resolved_seeds = [request.seed]\n                elif isinstance(request.seed, str):\n                    resolved_seeds = []\n                    for s in request.seed.split(\",\"):\n                        s = s.strip()\n                        if s:\n                            try:\n                                resolved_seeds.append(int(s))\n                            except ValueError:\n                                pass\n                    if not resolved_seeds:\n                        resolved_seeds = None\n                        use_random_seed = True\n\n            config = GenerationConfig(\n                batch_size=request.batch_size or 1,\n                use_random_seed=use_random_seed,\n                seeds=resolved_seeds,\n                audio_format=audio_config.format or \"mp3\",\n            )\n\n            result = generate_music(\n                dit_handler=h,\n                llm_handler=llm,\n                params=params,\n                config=config,\n                save_dir=app.state.temp_audio_dir,\n            )\n\n            if not result.success:\n                raise RuntimeError(result.error or \"Music generation failed\")\n\n            # Get first audio path\n            audio_path = None\n            if result.audios and result.audios[0].get(\"path\"):\n                audio_path = result.audios[0][\"path\"]\n\n            if not audio_path or not os.path.exists(audio_path):\n                raise RuntimeError(\"No audio file generated\")\n\n            # Build metadata\n            metadata = lm_result.get(\"metadata\", {})\n            if not metadata:\n                metadata = {\n                    \"caption\": gen_prompt,\n                    \"bpm\": resolved_bpm,\n                    \"duration\": resolved_duration,\n                    \"keyscale\": None,\n                    \"timesignature\": None,\n                    \"language\": resolved_vocal_language,\n                    \"instrumental\": gen_instrumental,\n                }\n\n            # Extract LM metadata and audio codes from result if available\n            extra = result.extra_outputs if hasattr(result, 'extra_outputs') and result.extra_outputs else {}\n            lm_metadata = extra.get(\"lm_metadata\", {})\n            if lm_metadata:\n                for key in [\"caption\", \"bpm\", \"duration\", \"keyscale\", \"timesignature\", \"language\"]:\n                    if lm_metadata.get(key):\n                        metadata[key] = lm_metadata.get(key)\n\n            output_audio_codes = extra.get(\"audio_codes\", \"\")\n            if not output_audio_codes and result.audios:\n                output_audio_codes = result.audios[0].get(\"params\", {}).get(\"audio_codes\", \"\")\n            if not output_audio_codes:\n                output_audio_codes = resolved_audio_codes or \"\"\n\n            return {\n                \"audio_path\": audio_path,\n                \"lyrics\": gen_lyrics,\n                \"metadata\": metadata,\n                \"lm_used\": lm_result.get(\"lm_used\", False),\n                \"audio_codes\": output_audio_codes,\n            }\n\n        # Handle streaming mode\n        if request.stream:\n            async def stream_generator():\n                \"\"\"Generate SSE stream.\"\"\"\n                loop = asyncio.get_running_loop()\n                executor = app.state.executor\n\n                # Send initial role chunk\n                yield _make_stream_chunk(\n                    completion_id, created_timestamp, request.model,\n                    role=\"assistant\", content=\"\"\n                )\n                await asyncio.sleep(0)\n\n                # Step 1: Run LM sample generation\n                print(\"[OpenRouter API] Stream: Running LM sample...\")\n                try:\n                    lm_result = await loop.run_in_executor(executor, _run_lm_sample)\n                except Exception as e:\n                    print(f\"[OpenRouter API] Stream: LM error: {e}\")\n                    lm_result = {\n                        \"prompt\": prompt or sample_query,\n                        \"lyrics\": lyrics,\n                        \"instrumental\": instrumental,\n                        \"lm_used\": False,\n                        \"metadata\": {},\n                    }\n\n                # If LM was used, stream the content\n                if lm_result.get(\"lm_used\"):\n                    lm_content = _format_lm_content({\n                        \"lm_used\": True,\n                        \"lyrics\": lm_result.get(\"lyrics\", \"\"),\n                        \"metadata\": lm_result.get(\"metadata\", {}),\n                    })\n                    # Stream LM content in chunks\n                    yield _make_stream_chunk(\n                        completion_id, created_timestamp, request.model,\n                        content=f\"\\n\\n{lm_content}\"\n                    )\n                    await asyncio.sleep(0)\n                    print(\"[OpenRouter API] Stream: LM content sent\")\n\n                # Step 2: Run audio generation with heartbeats\n                print(\"[OpenRouter API] Stream: Starting audio generation...\")\n                audio_future = loop.run_in_executor(\n                    executor,\n                    functools.partial(_run_audio_generation, lm_result)\n                )\n\n                # Send heartbeat while waiting\n                heartbeat_interval = 2.0\n                dot_count = 0\n                while not audio_future.done():\n                    try:\n                        await asyncio.wait_for(asyncio.shield(audio_future), timeout=heartbeat_interval)\n                        break\n                    except asyncio.TimeoutError:\n                        dot_count += 1\n                        yield _make_stream_chunk(\n                            completion_id, created_timestamp, request.model,\n                            content=\".\"\n                        )\n                        await asyncio.sleep(0)\n                        print(f\"[OpenRouter API] Stream: Heartbeat {dot_count}\")\n\n                # Get audio result\n                try:\n                    audio_result = await audio_future\n                    print(f\"[OpenRouter API] Stream: Audio generation completed\")\n                except Exception as e:\n                    print(f\"[OpenRouter API] Stream: Audio generation error: {e}\")\n                    yield _make_stream_chunk(\n                        completion_id, created_timestamp, request.model,\n                        content=f\"\\n\\nError: {str(e)}\"\n                    )\n                    yield _make_stream_chunk(\n                        completion_id, created_timestamp, request.model,\n                        finish_reason=\"error\"\n                    )\n                    yield \"data: [DONE]\\n\\n\"\n                    return\n\n                # Send audio data\n                audio_path = audio_result.get(\"audio_path\")\n                if audio_path and os.path.exists(audio_path):\n                    b64_url = _audio_to_base64_url(audio_path, \"mp3\")\n                    if b64_url:\n                        audio_list = [\n                            AudioOutputItem(\n                                type=\"audio_url\",\n                                audio_url=AudioUrlContent(url=b64_url)\n                            )\n                        ]\n                        yield _make_stream_chunk(\n                            completion_id, created_timestamp, request.model,\n                            audio=audio_list\n                        )\n                        await asyncio.sleep(0)\n                        print(\"[OpenRouter API] Stream: Audio data sent\")\n                    else:\n                        yield _make_stream_chunk(\n                            completion_id, created_timestamp, request.model,\n                            content=\"\\n\\nError: Failed to encode audio\"\n                        )\n                else:\n                    yield _make_stream_chunk(\n                        completion_id, created_timestamp, request.model,\n                        content=\"\\n\\nError: Audio file not found\"\n                    )\n\n                # Send finish\n                yield _make_stream_chunk(\n                    completion_id, created_timestamp, request.model,\n                    finish_reason=\"stop\"\n                )\n                yield \"data: [DONE]\\n\\n\"\n                print(\"[OpenRouter API] Stream: Complete\")\n\n            return StreamingResponse(\n                stream_generator(),\n                media_type=\"text/event-stream\",\n            )\n\n        # Non-streaming mode\n        def _blocking_generate() -> Dict[str, Any]:\n            \"\"\"Run full generation in thread pool.\"\"\"\n            lm_result = _run_lm_sample()\n            return _run_audio_generation(lm_result)\n\n        try:\n            loop = asyncio.get_running_loop()\n            result = await loop.run_in_executor(app.state.executor, _blocking_generate)\n        except Exception as e:\n            raise HTTPException(status_code=500, detail=f\"Generation failed: {str(e)}\")\n\n        # Format content with LM results\n        text_content = _format_lm_content(result)\n\n        # Build audio in OpenRouter format\n        audio_list = None\n        audio_path = result.get(\"audio_path\")\n        if audio_path and os.path.exists(audio_path):\n            b64_url = _audio_to_base64_url(audio_path, \"mp3\")\n            if b64_url:\n                audio_list = [\n                    AudioOutputItem(\n                        type=\"audio_url\",\n                        audio_url=AudioUrlContent(url=b64_url)\n                    )\n                ]\n\n        response = ChatCompletionResponse(\n            id=completion_id,\n            created=created_timestamp,\n            model=request.model,\n            choices=[\n                Choice(\n                    index=0,\n                    message=ResponseMessage(\n                        role=\"assistant\",\n                        content=text_content,\n                        audio=audio_list,\n                        audio_codes=result.get(\"audio_codes\") or None,\n                    ),\n                    finish_reason=\"stop\",\n                )\n            ],\n            usage=Usage(\n                prompt_tokens=len(prompt.split()) if prompt else 0,\n                completion_tokens=100,\n                total_tokens=(len(prompt.split()) if prompt else 0) + 100,\n            ),\n        )\n\n        return response\n    \n    @app.get(\"/health\")\n    async def health_check():\n        \"\"\"Health check endpoint.\"\"\"\n        return {\n            \"status\": \"ok\",\n            \"service\": \"ACE-Step OpenRouter API\",\n            \"version\": \"1.0\",\n        }\n\n    return app\n\n\n# Create app instance\napp = create_app()\n\n\ndef main() -> None:\n    \"\"\"Run the server.\"\"\"\n    import uvicorn\n    \n    parser = argparse.ArgumentParser(description=\"ACE-Step OpenRouter API server\")\n    parser.add_argument(\n        \"--host\",\n        default=os.getenv(\"OPENROUTER_HOST\", \"127.0.0.1\"),\n        help=\"Bind host (default: 127.0.0.1)\",\n    )\n    parser.add_argument(\n        \"--port\",\n        type=int,\n        default=int(os.getenv(\"OPENROUTER_PORT\", \"8002\")),\n        help=\"Bind port (default: 8002)\",\n    )\n    parser.add_argument(\n        \"--api-key\",\n        type=str,\n        default=os.getenv(\"OPENROUTER_API_KEY\"),\n        help=\"API key for authentication\",\n    )\n    args = parser.parse_args()\n    \n    if args.api_key:\n        os.environ[\"OPENROUTER_API_KEY\"] = args.api_key\n    \n    uvicorn.run(\n        \"openrouter.openrouter_api_server:app\",\n        host=str(args.host),\n        port=int(args.port),\n        reload=False,\n        workers=1,\n    )\n\n\nif __name__ == \"__main__\":\n    main()\n"
  },
  {
    "path": "openrouter/stress_test.py",
    "content": "\"\"\"\nACE-Step OpenRouter API 压力测试脚本\n\n支持并发测试，用于测试服务的最大 QPS 和性能表现。\n\nUsage:\n    # 基本测试 - 10 并发，100 请求\n    python -m openrouter.stress_test\n\n    # 自定义参数测试\n    python -m openrouter.stress_test --concurrency 50 --requests 500\n\n    # 逐步加压测试\n    python -m openrouter.stress_test --mode ramp --max-concurrency 100 --step 10\n\n    # 持续压测\n    python -m openrouter.stress_test --mode duration --duration 60 --concurrency 20\n\"\"\"\n\nimport argparse\nimport json\nimport os\nimport sys\nimport time\nimport threading\nimport statistics\nfrom concurrent.futures import ThreadPoolExecutor, as_completed\nfrom dataclasses import dataclass, field\nfrom typing import Optional, List, Dict, Any\nfrom collections import defaultdict\nfrom datetime import datetime\nimport queue\n\nimport requests\n\n\n# =============================================================================\n# 配置\n# =============================================================================\n\nDEFAULT_BASE_URL = \"https://api.acemusic.ai\"\nDEFAULT_CONCURRENCY = 4\nDEFAULT_TOTAL_REQUESTS = 100\n\n\n@dataclass\nclass RequestResult:\n    \"\"\"单次请求结果\"\"\"\n    success: bool\n    status_code: int\n    latency: float  # 秒\n    error_message: str = \"\"\n    timestamp: float = 0.0\n\n\n@dataclass\nclass StressTestStats:\n    \"\"\"压力测试统计数据\"\"\"\n    total_requests: int = 0\n    successful_requests: int = 0\n    failed_requests: int = 0\n    latencies: List[float] = field(default_factory=list)\n    errors: Dict[str, int] = field(default_factory=lambda: defaultdict(int))\n    status_codes: Dict[int, int] = field(default_factory=lambda: defaultdict(int))\n    start_time: float = 0.0\n    end_time: float = 0.0\n\n    def add_result(self, result: RequestResult):\n        \"\"\"添加请求结果\"\"\"\n        self.total_requests += 1\n        self.status_codes[result.status_code] += 1\n\n        if result.success:\n            self.successful_requests += 1\n            self.latencies.append(result.latency)\n        else:\n            self.failed_requests += 1\n            self.errors[result.error_message] += 1\n\n    @property\n    def success_rate(self) -> float:\n        \"\"\"成功率\"\"\"\n        if self.total_requests == 0:\n            return 0.0\n        return (self.successful_requests / self.total_requests) * 100\n\n    @property\n    def duration(self) -> float:\n        \"\"\"测试持续时间\"\"\"\n        return self.end_time - self.start_time\n\n    @property\n    def qps(self) -> float:\n        \"\"\"每秒请求数 (QPS)\"\"\"\n        if self.duration == 0:\n            return 0.0\n        return self.total_requests / self.duration\n\n    @property\n    def successful_qps(self) -> float:\n        \"\"\"成功请求的 QPS\"\"\"\n        if self.duration == 0:\n            return 0.0\n        return self.successful_requests / self.duration\n\n    def get_latency_stats(self) -> Dict[str, float]:\n        \"\"\"获取延迟统计数据\"\"\"\n        if not self.latencies:\n            return {\n                \"min\": 0.0,\n                \"max\": 0.0,\n                \"avg\": 0.0,\n                \"median\": 0.0,\n                \"p90\": 0.0,\n                \"p95\": 0.0,\n                \"p99\": 0.0,\n            }\n\n        sorted_latencies = sorted(self.latencies)\n        n = len(sorted_latencies)\n\n        return {\n            \"min\": min(sorted_latencies),\n            \"max\": max(sorted_latencies),\n            \"avg\": statistics.mean(sorted_latencies),\n            \"median\": statistics.median(sorted_latencies),\n            \"p90\": sorted_latencies[int(n * 0.90)] if n > 0 else 0.0,\n            \"p95\": sorted_latencies[int(n * 0.95)] if n > 0 else 0.0,\n            \"p99\": sorted_latencies[int(n * 0.99)] if n > 0 else 0.0,\n        }\n\n\nclass StressTester:\n    \"\"\"压力测试器\"\"\"\n\n    def __init__(\n        self,\n        base_url: str,\n        api_key: Optional[str] = None,\n        timeout: int = 300,\n        test_type: str = \"health\",\n    ):\n        self.base_url = base_url.rstrip(\"/\")\n        self.api_key = api_key\n        self.timeout = timeout\n        self.test_type = test_type\n        self.session = requests.Session()\n        self.lock = threading.Lock()\n        self.request_counter = 0\n        self.live_stats = StressTestStats()\n\n    def get_headers(self) -> dict:\n        \"\"\"构建请求头\"\"\"\n        headers = {\"Content-Type\": \"application/json\"}\n        if self.api_key:\n            headers[\"Authorization\"] = f\"Bearer {self.api_key}\"\n        return headers\n\n    def make_request(self) -> RequestResult:\n        \"\"\"执行单次请求\"\"\"\n        start_time = time.time()\n        timestamp = start_time\n\n        try:\n            if self.test_type == \"health\":\n                resp = requests.get(\n                    f\"{self.base_url}/health\",\n                    timeout=self.timeout\n                )\n            elif self.test_type == \"models\":\n                resp = requests.get(\n                    f\"{self.base_url}/api/v1/models\",\n                    headers=self.get_headers(),\n                    timeout=self.timeout\n                )\n            elif self.test_type == \"generate\":\n                payload = self._get_generate_payload()\n                resp = requests.post(\n                    f\"{self.base_url}/v1/chat/completions\",\n                    headers=self.get_headers(),\n                    json=payload,\n                    timeout=self.timeout\n                )\n            elif self.test_type == \"instrumental\":\n                payload = self._get_instrumental_payload()\n                resp = requests.post(\n                    f\"{self.base_url}/v1/chat/completions\",\n                    headers=self.get_headers(),\n                    json=payload,\n                    timeout=self.timeout\n                )\n            else:\n                # 默认 health\n                resp = requests.get(\n                    f\"{self.base_url}/health\",\n                    timeout=self.timeout\n                )\n\n            latency = time.time() - start_time\n\n            if resp.status_code == 200:\n                return RequestResult(\n                    success=True,\n                    status_code=resp.status_code,\n                    latency=latency,\n                    timestamp=timestamp\n                )\n            else:\n                return RequestResult(\n                    success=False,\n                    status_code=resp.status_code,\n                    latency=latency,\n                    error_message=f\"HTTP {resp.status_code}\",\n                    timestamp=timestamp\n                )\n\n        except requests.exceptions.Timeout:\n            return RequestResult(\n                success=False,\n                status_code=0,\n                latency=time.time() - start_time,\n                error_message=\"Timeout\",\n                timestamp=timestamp\n            )\n        except requests.exceptions.ConnectionError as e:\n            return RequestResult(\n                success=False,\n                status_code=0,\n                latency=time.time() - start_time,\n                error_message=f\"ConnectionError: {str(e)[:50]}\",\n                timestamp=timestamp\n            )\n        except Exception as e:\n            return RequestResult(\n                success=False,\n                status_code=0,\n                latency=time.time() - start_time,\n                error_message=f\"{type(e).__name__}: {str(e)[:50]}\",\n                timestamp=timestamp\n            )\n\n    def _get_generate_payload(self) -> dict:\n        \"\"\"获取生成请求的 payload\"\"\"\n        return {\n            \"messages\": [\n                {\"role\": \"user\", \"content\": \"Generate an upbeat pop song about summer\"}\n            ],\n            \"sample_mode\": True,\n            \"audio_config\": {\n                \"vocal_language\": \"en\",\n                \"duration\": 30,\n            },\n        }\n\n    def _get_instrumental_payload(self) -> dict:\n        \"\"\"获取纯音乐请求的 payload\"\"\"\n        return {\n            \"messages\": [\n                {\"role\": \"user\", \"content\": \"<prompt>Epic orchestral cinematic score</prompt>\"}\n            ],\n            \"audio_config\": {\n                \"instrumental\": True,\n                \"duration\": 30,\n            },\n        }\n\n    def run_fixed_requests(\n        self,\n        concurrency: int,\n        total_requests: int,\n        show_progress: bool = True\n    ) -> StressTestStats:\n        \"\"\"固定请求数模式\"\"\"\n        stats = StressTestStats()\n        stats.start_time = time.time()\n\n        completed = 0\n        completed_lock = threading.Lock()\n\n        def worker():\n            nonlocal completed\n            result = self.make_request()\n\n            with completed_lock:\n                completed += 1\n                stats.add_result(result)\n\n                if show_progress and completed % 10 == 0:\n                    elapsed = time.time() - stats.start_time\n                    current_qps = completed / elapsed if elapsed > 0 else 0\n                    print(\n                        f\"\\r进度: {completed}/{total_requests} \"\n                        f\"({completed/total_requests*100:.1f}%) | \"\n                        f\"成功: {stats.successful_requests} | \"\n                        f\"失败: {stats.failed_requests} | \"\n                        f\"当前 QPS: {current_qps:.2f}\",\n                        end=\"\", flush=True\n                    )\n\n        with ThreadPoolExecutor(max_workers=concurrency) as executor:\n            futures = [executor.submit(worker) for _ in range(total_requests)]\n            for future in as_completed(futures):\n                try:\n                    future.result()\n                except Exception as e:\n                    print(f\"\\n工作线程异常: {e}\")\n\n        stats.end_time = time.time()\n\n        if show_progress:\n            print()  # 换行\n\n        return stats\n\n    def run_duration_based(\n        self,\n        concurrency: int,\n        duration: int,\n        show_progress: bool = True\n    ) -> StressTestStats:\n        \"\"\"持续时间模式\"\"\"\n        stats = StressTestStats()\n        stats.start_time = time.time()\n        stop_event = threading.Event()\n\n        def worker():\n            while not stop_event.is_set():\n                result = self.make_request()\n                with self.lock:\n                    stats.add_result(result)\n\n        # 启动工作线程\n        threads = []\n        for _ in range(concurrency):\n            t = threading.Thread(target=worker, daemon=True)\n            t.start()\n            threads.append(t)\n\n        # 显示进度\n        try:\n            end_time = time.time() + duration\n            while time.time() < end_time:\n                elapsed = time.time() - stats.start_time\n                remaining = duration - elapsed\n                current_qps = stats.total_requests / elapsed if elapsed > 0 else 0\n\n                if show_progress:\n                    print(\n                        f\"\\r剩余时间: {remaining:.1f}s | \"\n                        f\"请求数: {stats.total_requests} | \"\n                        f\"成功: {stats.successful_requests} | \"\n                        f\"失败: {stats.failed_requests} | \"\n                        f\"QPS: {current_qps:.2f}\",\n                        end=\"\", flush=True\n                    )\n                time.sleep(0.5)\n        finally:\n            stop_event.set()\n\n        # 等待所有线程结束\n        for t in threads:\n            t.join(timeout=5)\n\n        stats.end_time = time.time()\n\n        if show_progress:\n            print()  # 换行\n\n        return stats\n\n    def run_ramp_up(\n        self,\n        max_concurrency: int,\n        step: int,\n        requests_per_step: int,\n        show_progress: bool = True\n    ) -> List[Dict[str, Any]]:\n        \"\"\"逐步加压模式\"\"\"\n        results = []\n\n        for concurrency in range(step, max_concurrency + 1, step):\n            print(f\"\\n{'='*60}\")\n            print(f\"测试并发数: {concurrency}\")\n            print(\"=\" * 60)\n\n            stats = self.run_fixed_requests(\n                concurrency=concurrency,\n                total_requests=requests_per_step,\n                show_progress=show_progress\n            )\n\n            latency_stats = stats.get_latency_stats()\n\n            result = {\n                \"concurrency\": concurrency,\n                \"total_requests\": stats.total_requests,\n                \"successful_requests\": stats.successful_requests,\n                \"failed_requests\": stats.failed_requests,\n                \"success_rate\": stats.success_rate,\n                \"qps\": stats.qps,\n                \"successful_qps\": stats.successful_qps,\n                \"avg_latency\": latency_stats[\"avg\"],\n                \"p95_latency\": latency_stats[\"p95\"],\n                \"p99_latency\": latency_stats[\"p99\"],\n            }\n            results.append(result)\n\n            self._print_step_summary(result)\n\n            # 短暂休息让服务恢复\n            time.sleep(2)\n\n        return results\n\n\n    def _print_step_summary(self, result: Dict[str, Any]):\n        \"\"\"打印单步测试摘要\"\"\"\n        print(f\"\\n并发数 {result['concurrency']} 测试结果:\")\n        print(f\"  总请求数: {result['total_requests']}\")\n        print(f\"  成功/失败: {result['successful_requests']}/{result['failed_requests']}\")\n        print(f\"  成功率: {result['success_rate']:.2f}%\")\n        print(f\"  QPS: {result['qps']:.2f}\")\n        print(f\"  成功 QPS: {result['successful_qps']:.2f}\")\n        print(f\"  平均延迟: {result['avg_latency']*1000:.2f}ms\")\n        print(f\"  P95 延迟: {result['p95_latency']*1000:.2f}ms\")\n        print(f\"  P99 延迟: {result['p99_latency']*1000:.2f}ms\")\n\n\ndef print_stats(stats: StressTestStats, title: str = \"压力测试结果\"):\n    \"\"\"打印统计结果\"\"\"\n    latency_stats = stats.get_latency_stats()\n\n    print(\"\\n\")\n    print(\"=\" * 70)\n    print(f\" {title}\")\n    print(\"=\" * 70)\n\n    print(\"\\n📊 基本统计\")\n    print(\"-\" * 40)\n    print(f\"  总请求数:       {stats.total_requests}\")\n    print(f\"  成功请求数:     {stats.successful_requests}\")\n    print(f\"  失败请求数:     {stats.failed_requests}\")\n    print(f\"  成功率:         {stats.success_rate:.2f}%\")\n\n    print(\"\\n⏱️ 时间统计\")\n    print(\"-\" * 40)\n    print(f\"  测试持续时间:   {stats.duration:.2f} 秒\")\n    print(f\"  总 QPS:         {stats.qps:.2f}\")\n    print(f\"  成功 QPS:       {stats.successful_qps:.2f}\")\n\n    print(\"\\n📈 延迟统计 (毫秒)\")\n    print(\"-\" * 40)\n    print(f\"  最小延迟:       {latency_stats['min']*1000:.2f}ms\")\n    print(f\"  最大延迟:       {latency_stats['max']*1000:.2f}ms\")\n    print(f\"  平均延迟:       {latency_stats['avg']*1000:.2f}ms\")\n    print(f\"  中位数延迟:     {latency_stats['median']*1000:.2f}ms\")\n    print(f\"  P90 延迟:       {latency_stats['p90']*1000:.2f}ms\")\n    print(f\"  P95 延迟:       {latency_stats['p95']*1000:.2f}ms\")\n    print(f\"  P99 延迟:       {latency_stats['p99']*1000:.2f}ms\")\n\n    if stats.status_codes:\n        print(\"\\n📋 状态码分布\")\n        print(\"-\" * 40)\n        for code, count in sorted(stats.status_codes.items()):\n            percentage = (count / stats.total_requests) * 100\n            print(f\"  {code}:  {count:>8} ({percentage:.1f}%)\")\n\n    if stats.errors:\n        print(\"\\n❌ 错误分布 (Top 10)\")\n        print(\"-\" * 40)\n        sorted_errors = sorted(stats.errors.items(), key=lambda x: x[1], reverse=True)[:10]\n        for error, count in sorted_errors:\n            percentage = (count / stats.total_requests) * 100\n            print(f\"  {error[:50]}: {count} ({percentage:.1f}%)\")\n\n    print(\"\\n\" + \"=\" * 70)\n\n\ndef print_ramp_summary(results: List[Dict[str, Any]]):\n    \"\"\"打印逐步加压测试的汇总\"\"\"\n    print(\"\\n\")\n    print(\"=\" * 90)\n    print(\" 逐步加压测试汇总\")\n    print(\"=\" * 90)\n\n    # 表头\n    print(f\"\\n{'并发':>8} | {'请求数':>8} | {'成功率':>8} | {'QPS':>10} | {'成功QPS':>10} | {'平均延迟':>10} | {'P99延迟':>10}\")\n    print(\"-\" * 90)\n\n    # 数据行\n    for r in results:\n        print(\n            f\"{r['concurrency']:>8} | \"\n            f\"{r['total_requests']:>8} | \"\n            f\"{r['success_rate']:>7.1f}% | \"\n            f\"{r['qps']:>10.2f} | \"\n            f\"{r['successful_qps']:>10.2f} | \"\n            f\"{r['avg_latency']*1000:>9.1f}ms | \"\n            f\"{r['p99_latency']*1000:>9.1f}ms\"\n        )\n\n    print(\"-\" * 90)\n\n    # 找出最佳 QPS\n    best_qps = max(results, key=lambda x: x['successful_qps'])\n    print(f\"\\n🏆 最佳成功 QPS: {best_qps['successful_qps']:.2f} (并发数: {best_qps['concurrency']})\")\n\n    # 找出延迟瓶颈点（P99 延迟开始急剧上升的点）\n    for i in range(1, len(results)):\n        if results[i]['p99_latency'] > results[i-1]['p99_latency'] * 2:\n            print(f\"⚠️  延迟瓶颈点: 并发数 {results[i]['concurrency']} (P99 延迟开始急剧上升)\")\n            break\n\n    # 找出错误率开始上升的点\n    for i, r in enumerate(results):\n        if r['success_rate'] < 99:\n            print(f\"⚠️  稳定性下降点: 并发数 {r['concurrency']} (成功率: {r['success_rate']:.1f}%)\")\n            break\n\n    print()\n\n\ndef main():\n    parser = argparse.ArgumentParser(\n        description=\"ACE-Step OpenRouter API 压力测试工具\",\n        formatter_class=argparse.RawDescriptionHelpFormatter,\n        epilog=\"\"\"\n示例:\n  # 健康检查接口压测\n  python -m openrouter.stress_test --test health --concurrency 100 --requests 1000\n\n  # 模型列表接口压测\n  python -m openrouter.stress_test --test models --concurrency 50 --requests 500\n\n  # 音乐生成接口压测 (注意: 生成请求较慢)\n  python -m openrouter.stress_test --test generate --concurrency 5 --requests 20\n\n  # 逐步加压测试\n  python -m openrouter.stress_test --mode ramp --max-concurrency 100 --step 10\n\n  # 持续时间压测 (60秒)\n  python -m openrouter.stress_test --mode duration --duration 60 --concurrency 50\n        \"\"\"\n    )\n\n    parser.add_argument(\n        \"--base-url\",\n        default=os.getenv(\"OPENROUTER_BASE_URL\", DEFAULT_BASE_URL),\n        help=f\"API 基础 URL (默认: {DEFAULT_BASE_URL})\"\n    )\n    parser.add_argument(\n        \"--api-key\",\n        default=os.getenv(\"OPENROUTER_API_KEY\"),\n        help=\"API 密钥 (可选)\"\n    )\n    parser.add_argument(\n        \"--test\",\n        choices=[\"health\", \"models\", \"generate\", \"instrumental\"],\n        default=\"health\",\n        help=\"要测试的接口类型 (默认: health)\"\n    )\n    parser.add_argument(\n        \"--mode\",\n        choices=[\"fixed\", \"duration\", \"ramp\"],\n        default=\"fixed\",\n        help=\"测试模式: fixed=固定请求数, duration=持续时间, ramp=逐步加压 (默认: fixed)\"\n    )\n    parser.add_argument(\n        \"--concurrency\", \"-c\",\n        type=int,\n        default=DEFAULT_CONCURRENCY,\n        help=f\"并发数 (默认: {DEFAULT_CONCURRENCY})\"\n    )\n    parser.add_argument(\n        \"--requests\", \"-n\",\n        type=int,\n        default=DEFAULT_TOTAL_REQUESTS,\n        help=f\"总请求数 (fixed 模式) (默认: {DEFAULT_TOTAL_REQUESTS})\"\n    )\n    parser.add_argument(\n        \"--duration\", \"-d\",\n        type=int,\n        default=60,\n        help=\"测试持续时间秒数 (duration 模式) (默认: 60)\"\n    )\n    parser.add_argument(\n        \"--max-concurrency\",\n        type=int,\n        default=100,\n        help=\"最大并发数 (ramp 模式) (默认: 100)\"\n    )\n    parser.add_argument(\n        \"--step\",\n        type=int,\n        default=10,\n        help=\"并发增长步长 (ramp 模式) (默认: 10)\"\n    )\n    parser.add_argument(\n        \"--requests-per-step\",\n        type=int,\n        default=100,\n        help=\"每个步骤的请求数 (ramp 模式) (默认: 100)\"\n    )\n    parser.add_argument(\n        \"--timeout\",\n        type=int,\n        default=300,\n        help=\"请求超时时间秒数 (默认: 300)\"\n    )\n    parser.add_argument(\n        \"--output\", \"-o\",\n        type=str,\n        help=\"输出结果到 JSON 文件\"\n    )\n    parser.add_argument(\n        \"--quiet\", \"-q\",\n        action=\"store_true\",\n        help=\"减少输出信息\"\n    )\n\n    args = parser.parse_args()\n\n    # 打印配置信息\n    print(\"=\" * 70)\n    print(\" ACE-Step OpenRouter API 压力测试\")\n    print(\"=\" * 70)\n    print(f\"  时间:           {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}\")\n    print(f\"  Base URL:       {args.base_url}\")\n    print(f\"  API Key:        {'已设置' if args.api_key else '未设置'}\")\n    print(f\"  测试接口:       {args.test}\")\n    print(f\"  测试模式:       {args.mode}\")\n\n    if args.mode == \"fixed\":\n        print(f\"  并发数:         {args.concurrency}\")\n        print(f\"  总请求数:       {args.requests}\")\n    elif args.mode == \"duration\":\n        print(f\"  并发数:         {args.concurrency}\")\n        print(f\"  持续时间:       {args.duration} 秒\")\n    elif args.mode == \"ramp\":\n        print(f\"  最大并发数:     {args.max_concurrency}\")\n        print(f\"  步长:           {args.step}\")\n        print(f\"  每步请求数:     {args.requests_per_step}\")\n\n    print(f\"  请求超时:       {args.timeout} 秒\")\n    print(\"=\" * 70)\n\n    # 创建测试器\n    tester = StressTester(\n        base_url=args.base_url,\n        api_key=args.api_key,\n        timeout=args.timeout,\n        test_type=args.test\n    )\n\n    # 执行测试\n    try:\n        if args.mode == \"fixed\":\n            print(f\"\\n开始固定请求数测试 (并发: {args.concurrency}, 请求数: {args.requests})...\\n\")\n            stats = tester.run_fixed_requests(\n                concurrency=args.concurrency,\n                total_requests=args.requests,\n                show_progress=not args.quiet\n            )\n            print_stats(stats, f\"压力测试结果 - {args.test.upper()} 接口\")\n\n            # 保存结果\n            if args.output:\n                latency_stats = stats.get_latency_stats()\n                output_data = {\n                    \"test_type\": args.test,\n                    \"mode\": args.mode,\n                    \"concurrency\": args.concurrency,\n                    \"total_requests\": stats.total_requests,\n                    \"successful_requests\": stats.successful_requests,\n                    \"failed_requests\": stats.failed_requests,\n                    \"success_rate\": stats.success_rate,\n                    \"duration\": stats.duration,\n                    \"qps\": stats.qps,\n                    \"successful_qps\": stats.successful_qps,\n                    \"latency\": latency_stats,\n                    \"status_codes\": dict(stats.status_codes),\n                    \"errors\": dict(stats.errors),\n                    \"timestamp\": datetime.now().isoformat()\n                }\n                with open(args.output, \"w\") as f:\n                    json.dump(output_data, f, indent=2, ensure_ascii=False)\n                print(f\"\\n结果已保存到: {args.output}\")\n\n        elif args.mode == \"duration\":\n            print(f\"\\n开始持续时间测试 (并发: {args.concurrency}, 时长: {args.duration}秒)...\\n\")\n            stats = tester.run_duration_based(\n                concurrency=args.concurrency,\n                duration=args.duration,\n                show_progress=not args.quiet\n            )\n            print_stats(stats, f\"压力测试结果 - {args.test.upper()} 接口 ({args.duration}秒)\")\n\n        elif args.mode == \"ramp\":\n            print(f\"\\n开始逐步加压测试 (最大并发: {args.max_concurrency}, 步长: {args.step})...\\n\")\n            results = tester.run_ramp_up(\n                max_concurrency=args.max_concurrency,\n                step=args.step,\n                requests_per_step=args.requests_per_step,\n                show_progress=not args.quiet\n            )\n            print_ramp_summary(results)\n\n            # 保存结果\n            if args.output:\n                output_data = {\n                    \"test_type\": args.test,\n                    \"mode\": args.mode,\n                    \"max_concurrency\": args.max_concurrency,\n                    \"step\": args.step,\n                    \"requests_per_step\": args.requests_per_step,\n                    \"results\": results,\n                    \"timestamp\": datetime.now().isoformat()\n                }\n                with open(args.output, \"w\") as f:\n                    json.dump(output_data, f, indent=2, ensure_ascii=False)\n                print(f\"结果已保存到: {args.output}\")\n\n    except KeyboardInterrupt:\n        print(\"\\n\\n测试被用户中断\")\n        sys.exit(1)\n    except Exception as e:\n        print(f\"\\n测试出错: {e}\")\n        import traceback\n        traceback.print_exc()\n        sys.exit(1)\n\n\nif __name__ == \"__main__\":\n    main()\n"
  },
  {
    "path": "package.json",
    "content": "{\n  \"private\": true,\n  \"scripts\": {\n    \"docs:fetch\": \"node scripts/fetch-awesome.mjs\",\n    \"docs:dev\": \"npm run docs:fetch && vitepress dev docs\",\n    \"docs:build\": \"npm run docs:fetch && vitepress build docs\",\n    \"docs:preview\": \"vitepress preview docs\"\n  },\n  \"devDependencies\": {\n    \"vitepress\": \"^1.6.3\"\n  }\n}\n"
  },
  {
    "path": "plugins/acestep_vst3/CMakeLists.txt",
    "content": "cmake_minimum_required(VERSION 3.22)\n\nproject(ACEStepVST3Shell VERSION 0.1.0 LANGUAGES C CXX)\n\ninclude(FetchContent)\n\nset(FETCHCONTENT_QUIET OFF)\nset(FETCHCONTENT_UPDATES_DISCONNECTED TRUE)\n\nFetchContent_Declare(\n    juce\n    GIT_REPOSITORY https://github.com/juce-framework/JUCE.git\n    GIT_TAG 8.0.8\n)\n\nFetchContent_MakeAvailable(juce)\n\njuce_add_plugin(\n    acestep_vst3\n    COMPANY_NAME \"ACE-Step\"\n    PLUGIN_MANUFACTURER_CODE ACST\n    PLUGIN_CODE ASTP\n    PRODUCT_NAME \"ACE-Step VST3 Shell\"\n    FORMATS VST3\n    IS_SYNTH TRUE\n    NEEDS_MIDI_INPUT TRUE\n    NEEDS_MIDI_OUTPUT FALSE\n    IS_MIDI_EFFECT FALSE\n    EDITOR_WANTS_KEYBOARD_FOCUS TRUE\n    VST3_CATEGORIES Instrument\n)\n\njuce_generate_juce_header(acestep_vst3)\n\ntarget_sources(\n    acestep_vst3\n    PRIVATE\n        src/PluginBackendClient.cpp\n        src/PluginEditor.cpp\n        src/PluginEditorState.cpp\n        src/PluginEditorPreview.cpp\n        src/PluginEnums.cpp\n        src/PluginPreview.cpp\n        src/PluginProcessor.cpp\n        src/PluginState.cpp\n)\n\ntarget_compile_features(acestep_vst3 PRIVATE cxx_std_20)\n\ntarget_compile_definitions(\n    acestep_vst3\n    PRIVATE\n        JUCE_VST3_CAN_REPLACE_VST2=0\n        JUCE_WEB_BROWSER=0\n        JUCE_USE_CURL=0\n)\n\ntarget_link_libraries(\n    acestep_vst3\n    PRIVATE\n        juce::juce_audio_utils\n)\n"
  },
  {
    "path": "plugins/acestep_vst3/README.md",
    "content": "# ACE-Step VST3 Shell\n\nThis directory contains the isolated JUCE/CMake scaffold for the ACE-Step VST3 MVP shell.\n\nWhat it includes:\n\n- a VST3-only JUCE plugin target\n- state-driven MVP editor UI for prompt and job workflow\n- versioned plugin state persistence for the DAW project\n- no backend or generation calls yet\n\nThe current UI persists:\n\n- backend URL\n- prompt and lyrics\n- duration and seed\n- model preset and quality mode\n- backend/job status selections\n- result slot labels and selected slot\n\n## Build\n\nRequirements:\n\n- CMake 3.22 or newer\n- a C++20-capable compiler\n- Git access to fetch JUCE during configure\n\nConfigure and build:\n\n```bash\ncmake -S plugins/acestep_vst3 -B build/acestep_vst3\ncmake --build build/acestep_vst3 --config Release\n```\n\nOn Windows, use Visual Studio 2022 or the Ninja generator. On macOS, Xcode or Ninja both work.\n\nThe first configure step downloads JUCE from GitHub. If you need to work offline later, vendor or\npin JUCE locally before widening the scope of this plugin.\n\n## Validate\n\nThe current shell is intentionally minimal. Manual validation should focus on:\n\n- plugin loads in Reaper on Windows\n- plugin loads in Reaper on macOS\n- editor opens and closes cleanly\n- state survives save and reopen\n\nThere is no backend integration in this milestone.\n"
  },
  {
    "path": "plugins/acestep_vst3/src/PluginBackendClient.cpp",
    "content": "#include \"PluginBackendClient.h\"\n\nnamespace acestep::vst3\n{\nnamespace\n{\nconstexpr int kNetworkTimeoutMs = 15000;\n\njuce::String normalizeBaseUrl(juce::String baseUrl)\n{\n    baseUrl = baseUrl.trim();\n    while (baseUrl.endsWithChar('/'))\n    {\n        baseUrl = baseUrl.dropLastCharacters(1);\n    }\n    return baseUrl;\n}\n\njuce::URL buildUrl(const juce::String& baseUrl, const juce::String& path)\n{\n    if (path.startsWithIgnoreCase(\"http://\") || path.startsWithIgnoreCase(\"https://\"))\n    {\n        return juce::URL(path);\n    }\n\n    const auto normalizedBaseUrl = normalizeBaseUrl(baseUrl);\n    const auto normalizedPath = path.startsWithChar('/') ? path : \"/\" + path;\n    return juce::URL(normalizedBaseUrl + normalizedPath);\n}\n\nbool readJsonResponse(const juce::URL& url,\n                      const juce::String& httpMethod,\n                      const juce::String& requestBody,\n                      const juce::String& contentType,\n                      juce::var& parsedResponse,\n                      juce::String& errorMessage)\n{\n    int statusCode = 0;\n    auto requestUrl = requestBody.isNotEmpty() ? url.withPOSTData(requestBody) : url;\n    auto options = juce::URL::InputStreamOptions(juce::URL::ParameterHandling::inAddress)\n                       .withConnectionTimeoutMs(kNetworkTimeoutMs)\n                       .withStatusCode(&statusCode)\n                       .withNumRedirectsToFollow(4)\n                       .withHttpRequestCmd(httpMethod)\n                       .withExtraHeaders(contentType.isEmpty() ? juce::String()\n                                                              : \"Content-Type: \" + contentType\n                                                                    + \"\\r\\n\");\n\n    auto stream = requestUrl.createInputStream(options);\n    if (stream == nullptr)\n    {\n        errorMessage = \"Could not connect to the ACE-Step backend.\";\n        return false;\n    }\n\n    const auto responseText = stream->readEntireStreamAsString();\n    parsedResponse = juce::JSON::parse(responseText);\n    if (parsedResponse.isVoid())\n    {\n        errorMessage = responseText.isEmpty() ? \"Backend returned an empty response.\"\n                                              : \"Backend returned invalid JSON.\";\n        return false;\n    }\n\n    auto* rootObject = parsedResponse.getDynamicObject();\n    if (rootObject == nullptr)\n    {\n        errorMessage = \"Backend returned an unexpected response shape.\";\n        return false;\n    }\n\n    if (statusCode != 200)\n    {\n        errorMessage = rootObject->getProperty(\"error\").toString();\n        if (errorMessage.isEmpty())\n        {\n            errorMessage = \"Backend request failed with HTTP \" + juce::String(statusCode) + \".\";\n        }\n        return false;\n    }\n\n    return true;\n}\n\njuce::DynamicObject* getWrappedDataObject(const juce::var& response)\n{\n    auto* rootObject = response.getDynamicObject();\n    if (rootObject == nullptr)\n    {\n        return nullptr;\n    }\n\n    if (static_cast<int>(rootObject->getProperty(\"code\")) != 200)\n    {\n        return nullptr;\n    }\n\n    return rootObject->getProperty(\"data\").getDynamicObject();\n}\n\njuce::String buildResultLabel(const juce::DynamicObject& itemObject, int slotIndex)\n{\n    const auto prompt = itemObject.getProperty(\"prompt\").toString().trim();\n    const auto promptLabel = prompt.isEmpty() ? \"Untitled prompt\" : prompt.substring(0, 28);\n    const auto metasVar = itemObject.getProperty(\"metas\");\n    const auto* metas = metasVar.getDynamicObject();\n    const auto duration = metas != nullptr ? metas->getProperty(\"duration\").toString() : juce::String();\n    const auto keyScale = metas != nullptr ? metas->getProperty(\"keyscale\").toString() : juce::String();\n    juce::String suffix;\n    if (duration.isNotEmpty())\n    {\n        suffix << duration << \"s\";\n    }\n    if (keyScale.isNotEmpty())\n    {\n        if (suffix.isNotEmpty())\n        {\n            suffix << \", \";\n        }\n        suffix << keyScale;\n    }\n\n    juce::String label = \"Result \" + juce::String(slotIndex + 1) + \" - \" + promptLabel;\n    if (suffix.isNotEmpty())\n    {\n        label << \" (\" << suffix << \")\";\n    }\n    return label;\n}\n\njuce::String chooseModelName(ModelPreset preset)\n{\n    switch (preset)\n    {\n        case ModelPreset::turbo:\n            return \"acestep-v15-turbo\";\n        case ModelPreset::standard:\n        case ModelPreset::quality:\n            break;\n    }\n\n    return {};\n}\n\nint chooseInferenceSteps(QualityMode qualityMode)\n{\n    switch (qualityMode)\n    {\n        case QualityMode::fast:\n            return 6;\n        case QualityMode::balanced:\n            return 8;\n        case QualityMode::high:\n            return 12;\n    }\n\n    return 8;\n}\n\njuce::String chooseFileExtension(const juce::String& remoteFileUrl)\n{\n    const auto decoded = juce::URL::removeEscapeChars(remoteFileUrl);\n    const auto dotIndex = decoded.lastIndexOfChar('.');\n    if (dotIndex < 0)\n    {\n        return \".wav\";\n    }\n\n    const auto extension = decoded.substring(dotIndex);\n    if (extension.length() > 8 || extension.containsAnyOf(\"/?&\"))\n    {\n        return \".wav\";\n    }\n\n    return extension;\n}\n}  // namespace\n\nPluginHealthCheckResult PluginBackendClient::checkHealth(const juce::String& baseUrl) const\n{\n    PluginHealthCheckResult result;\n    juce::var response;\n    juce::String errorMessage;\n    if (!readJsonResponse(buildUrl(baseUrl, \"/health\"), \"GET\", {}, {}, response, errorMessage))\n    {\n        result.status = BackendStatus::offline;\n        result.errorMessage = errorMessage;\n        return result;\n    }\n\n    auto* rootObject = response.getDynamicObject();\n    auto* dataObject = rootObject != nullptr ? rootObject->getProperty(\"data\").getDynamicObject() : nullptr;\n    const auto status = dataObject != nullptr ? dataObject->getProperty(\"status\").toString() : juce::String();\n    result.status = status == \"ok\" ? BackendStatus::ready : BackendStatus::degraded;\n    if (result.status != BackendStatus::ready)\n    {\n        result.errorMessage = \"Backend health check returned a degraded status.\";\n    }\n    return result;\n}\n\nPluginGenerationStartResult PluginBackendClient::startGeneration(const PluginState& state) const\n{\n    PluginGenerationStartResult result;\n\n    juce::DynamicObject::Ptr payload = new juce::DynamicObject();\n    payload->setProperty(\"prompt\", state.prompt);\n    payload->setProperty(\"lyrics\", state.lyrics);\n    payload->setProperty(\"task_type\", \"text2music\");\n    payload->setProperty(\"audio_duration\", state.durationSeconds);\n    payload->setProperty(\"batch_size\", 1);\n    payload->setProperty(\"audio_format\", \"wav\");\n    payload->setProperty(\"thinking\", false);\n    payload->setProperty(\"use_random_seed\", false);\n    payload->setProperty(\"seed\", state.seed);\n    payload->setProperty(\"inference_steps\", chooseInferenceSteps(state.qualityMode));\n    payload->setProperty(\"guidance_scale\", 7.0);\n\n    if (const auto modelName = chooseModelName(state.modelPreset); modelName.isNotEmpty())\n    {\n        payload->setProperty(\"model\", modelName);\n    }\n\n    juce::var response;\n    juce::String errorMessage;\n    if (!readJsonResponse(buildUrl(state.backendBaseUrl, \"/release_task\"),\n                          \"POST\",\n                          juce::JSON::toString(juce::var(payload.get())),\n                          \"application/json\",\n                          response,\n                          errorMessage))\n    {\n        result.errorMessage = errorMessage;\n        return result;\n    }\n\n    auto* dataObject = getWrappedDataObject(response);\n    if (dataObject == nullptr)\n    {\n        auto* rootObject = response.getDynamicObject();\n        result.errorMessage = rootObject != nullptr ? rootObject->getProperty(\"error\").toString()\n                                                    : \"Backend did not return a task id.\";\n        if (result.errorMessage.isEmpty())\n        {\n            result.errorMessage = \"Backend did not return a task id.\";\n        }\n        return result;\n    }\n\n    result.taskId = dataObject->getProperty(\"task_id\").toString();\n    result.succeeded = result.taskId.isNotEmpty();\n    if (!result.succeeded)\n    {\n        result.errorMessage = \"Backend accepted the request but did not return a task id.\";\n    }\n    return result;\n}\n\nPluginGenerationPollResult PluginBackendClient::pollGeneration(const juce::String& baseUrl,\n                                                               const juce::String& taskId) const\n{\n    PluginGenerationPollResult result;\n    result.status = JobStatus::failed;\n\n    juce::DynamicObject::Ptr payload = new juce::DynamicObject();\n    juce::Array<juce::var> taskIds;\n    taskIds.add(taskId);\n    payload->setProperty(\"task_id_list\", juce::var(taskIds));\n\n    juce::var response;\n    juce::String errorMessage;\n    if (!readJsonResponse(buildUrl(baseUrl, \"/query_result\"),\n                          \"POST\",\n                          juce::JSON::toString(juce::var(payload.get())),\n                          \"application/json\",\n                          response,\n                          errorMessage))\n    {\n        result.errorMessage = errorMessage;\n        return result;\n    }\n\n    auto* rootObject = response.getDynamicObject();\n    if (rootObject == nullptr)\n    {\n        result.errorMessage = \"Backend returned an invalid query_result payload.\";\n        return result;\n    }\n\n    const auto dataVar = rootObject->getProperty(\"data\");\n    if (!dataVar.isArray() || dataVar.size() <= 0)\n    {\n        result.status = JobStatus::queuedOrRunning;\n        result.progressText = \"Waiting for backend result...\";\n        return result;\n    }\n\n    auto* taskObject = dataVar[0].getDynamicObject();\n    if (taskObject == nullptr)\n    {\n        result.errorMessage = \"Backend returned an invalid task payload.\";\n        return result;\n    }\n\n    const auto statusCode = static_cast<int>(taskObject->getProperty(\"status\"));\n    result.progressText = taskObject->getProperty(\"progress_text\").toString();\n\n    if (statusCode == 0)\n    {\n        result.status = JobStatus::queuedOrRunning;\n        if (result.progressText.isEmpty())\n        {\n            result.progressText = \"Queued / Running\";\n        }\n        return result;\n    }\n\n    const auto parsedResult = juce::JSON::parse(taskObject->getProperty(\"result\").toString());\n    if (!parsedResult.isArray() || parsedResult.size() <= 0)\n    {\n        result.status = statusCode == 1 ? JobStatus::succeeded : JobStatus::failed;\n        result.errorMessage = statusCode == 1 ? \"Task finished without any audio file.\" : \"Task failed.\";\n        return result;\n    }\n\n    if (statusCode == 2)\n    {\n        result.status = JobStatus::failed;\n        auto* failedItem = parsedResult[0].getDynamicObject();\n        result.errorMessage = failedItem != nullptr ? failedItem->getProperty(\"error\").toString()\n                                                    : \"Task failed.\";\n        if (result.errorMessage.isEmpty())\n        {\n            result.errorMessage = \"Task failed.\";\n        }\n        return result;\n    }\n\n    result.status = JobStatus::succeeded;\n    for (int index = 0; index < juce::jmin(kResultSlotCount, parsedResult.size()); ++index)\n    {\n        auto* itemObject = parsedResult[index].getDynamicObject();\n        if (itemObject == nullptr)\n        {\n            continue;\n        }\n\n        auto& slot = result.resultSlots[static_cast<size_t>(index)];\n        slot.remoteFileUrl = itemObject->getProperty(\"url\").toString();\n        if (slot.remoteFileUrl.isEmpty())\n        {\n            slot.remoteFileUrl = itemObject->getProperty(\"file\").toString();\n        }\n        slot.label = buildResultLabel(*itemObject, index);\n    }\n\n    return result;\n}\n\nPluginPreviewDownloadResult PluginBackendClient::downloadPreviewFile(const juce::String& baseUrl,\n                                                                     const juce::String& remoteFileUrl,\n                                                                     int slotIndex) const\n{\n    PluginPreviewDownloadResult result;\n    result.slotIndex = slotIndex;\n    if (remoteFileUrl.isEmpty())\n    {\n        result.errorMessage = \"The backend did not return an audio file URL.\";\n        return result;\n    }\n\n    int statusCode = 0;\n    auto stream = buildUrl(baseUrl, remoteFileUrl)\n                      .createInputStream(juce::URL::InputStreamOptions(juce::URL::ParameterHandling::inAddress)\n                                             .withConnectionTimeoutMs(kNetworkTimeoutMs)\n                                             .withStatusCode(&statusCode)\n                                             .withNumRedirectsToFollow(4)\n                                             .withHttpRequestCmd(\"GET\"));\n    if (stream == nullptr || statusCode != 200)\n    {\n        result.errorMessage = \"Could not download the generated preview audio.\";\n        return result;\n    }\n\n    auto previewFile = juce::File::getSpecialLocation(juce::File::tempDirectory)\n                           .getNonexistentChildFile(\"acestep-vst3-preview-\"\n                                                        + juce::String(slotIndex + 1),\n                                                    chooseFileExtension(remoteFileUrl),\n                                                    false);\n    juce::FileOutputStream output(previewFile);\n    if (!output.openedOk())\n    {\n        result.errorMessage = \"Could not create a temporary preview file.\";\n        return result;\n    }\n\n    output.writeFromInputStream(*stream, -1);\n    output.flush();\n\n    result.succeeded = true;\n    result.localFilePath = previewFile.getFullPathName();\n    result.displayName = previewFile.getFileName();\n    return result;\n}\n}  // namespace acestep::vst3\n"
  },
  {
    "path": "plugins/acestep_vst3/src/PluginBackendClient.h",
    "content": "#pragma once\n\n#include <array>\n\n#include <JuceHeader.h>\n\n#include \"PluginEnums.h\"\n#include \"PluginState.h\"\n\nnamespace acestep::vst3\n{\nstruct PluginBackendResultSlot final\n{\n    juce::String label;\n    juce::String remoteFileUrl;\n};\n\nstruct PluginHealthCheckResult final\n{\n    BackendStatus status = BackendStatus::offline;\n    juce::String errorMessage;\n};\n\nstruct PluginGenerationStartResult final\n{\n    bool succeeded = false;\n    juce::String taskId;\n    juce::String errorMessage;\n};\n\nstruct PluginGenerationPollResult final\n{\n    JobStatus status = JobStatus::failed;\n    juce::String progressText;\n    juce::String errorMessage;\n    std::array<PluginBackendResultSlot, static_cast<size_t>(kResultSlotCount)> resultSlots;\n};\n\nstruct PluginPreviewDownloadResult final\n{\n    int slotIndex = -1;\n    bool succeeded = false;\n    juce::String localFilePath;\n    juce::String displayName;\n    juce::String errorMessage;\n};\n\nclass PluginBackendClient final\n{\npublic:\n    [[nodiscard]] PluginHealthCheckResult checkHealth(const juce::String& baseUrl) const;\n    [[nodiscard]] PluginGenerationStartResult startGeneration(const PluginState& state) const;\n    [[nodiscard]] PluginGenerationPollResult pollGeneration(const juce::String& baseUrl,\n                                                            const juce::String& taskId) const;\n    [[nodiscard]] PluginPreviewDownloadResult downloadPreviewFile(const juce::String& baseUrl,\n                                                                  const juce::String& remoteFileUrl,\n                                                                  int slotIndex) const;\n};\n}  // namespace acestep::vst3\n"
  },
  {
    "path": "plugins/acestep_vst3/src/PluginConfig.h",
    "content": "#pragma once\n\nnamespace acestep::vst3\n{\ninline constexpr const char* kPluginName = \"ACE-Step VST3 Shell\";\ninline constexpr const char* kVendorName = \"ACE-Step\";\ninline constexpr const char* kPluginVersion = \"0.1.0\";\ninline constexpr const char* kDefaultBackendBaseUrl = \"http://localhost:8001\";\ninline constexpr const char* kStateRootTag = \"acestep_vst3_shell_state\";\ninline constexpr int kCurrentStateVersion = 1;\ninline constexpr int kDefaultDurationSeconds = 30;\ninline constexpr int kDefaultSeed = 12345;\ninline constexpr int kResultSlotCount = 3;\n}  // namespace acestep::vst3\n"
  },
  {
    "path": "plugins/acestep_vst3/src/PluginEditor.cpp",
    "content": "#include \"PluginEditor.h\"\n\n#include \"PluginProcessor.h\"\n\nnamespace acestep::vst3\n{\nnamespace\n{\nconstexpr int kEditorWidth = 720;\nconstexpr int kEditorHeight = 760;\n}  // namespace\n\nACEStepVST3AudioProcessorEditor::ACEStepVST3AudioProcessorEditor(\n    ACEStepVST3AudioProcessor& processor)\n    : juce::AudioProcessorEditor(&processor), processor_(processor)\n{\n    setSize(kEditorWidth, kEditorHeight);\n    configureLabels();\n    configureEditors();\n    configureSelectors();\n    syncFromProcessor();\n    refreshResultSelector();\n    refreshStatusViews();\n    startTimerHz(4);\n}\n\nACEStepVST3AudioProcessorEditor::~ACEStepVST3AudioProcessorEditor() = default;\n\nvoid ACEStepVST3AudioProcessorEditor::paint(juce::Graphics& g)\n{\n    g.fillAll(juce::Colour::fromRGB(18, 22, 32));\n    g.setColour(juce::Colour::fromRGB(44, 54, 74));\n    g.drawRoundedRectangle(getLocalBounds().toFloat().reduced(12.0f), 12.0f, 1.5f);\n}\n\nvoid ACEStepVST3AudioProcessorEditor::resized()\n{\n    auto bounds = getLocalBounds().reduced(20);\n    auto header = bounds.removeFromTop(56);\n    titleLabel_.setBounds(header.removeFromTop(28));\n    subtitleLabel_.setBounds(header.removeFromTop(20));\n\n    auto top = bounds.removeFromTop(168);\n    auto left = top.removeFromLeft(top.getWidth() / 2).reduced(0, 4);\n    auto right = top.reduced(0, 4);\n\n    backendUrlLabel_.setBounds(left.removeFromTop(18));\n    backendUrlEditor_.setBounds(left.removeFromTop(28));\n    left.removeFromTop(8);\n    promptLabel_.setBounds(left.removeFromTop(18));\n    promptEditor_.setBounds(left.removeFromTop(44));\n    left.removeFromTop(8);\n    lyricsLabel_.setBounds(left.removeFromTop(18));\n    promptEditor_.setBounds(promptEditor_.getBounds());\n    lyricsEditor_.setBounds(left.removeFromTop(44));\n\n    durationLabel_.setBounds(right.removeFromTop(18));\n    durationBox_.setBounds(right.removeFromTop(28));\n    right.removeFromTop(8);\n    seedLabel_.setBounds(right.removeFromTop(18));\n    seedEditor_.setBounds(right.removeFromTop(28));\n    right.removeFromTop(8);\n    modelLabel_.setBounds(right.removeFromTop(18));\n    modelBox_.setBounds(right.removeFromTop(28));\n    right.removeFromTop(8);\n    qualityLabel_.setBounds(right.removeFromTop(18));\n    qualityBox_.setBounds(right.removeFromTop(28));\n\n    auto statusArea = bounds.removeFromTop(156);\n    auto statusLeft = statusArea.removeFromLeft(statusArea.getWidth() / 2).reduced(0, 4);\n    auto statusRight = statusArea.reduced(0, 4);\n\n    backendStatusTitle_.setBounds(statusLeft.removeFromTop(18));\n    backendStatusBox_.setBounds(statusLeft.removeFromTop(28));\n    statusLeft.removeFromTop(8);\n    backendStatusValue_.setBounds(statusLeft.removeFromTop(40));\n    statusLeft.removeFromTop(8);\n    jobStatusTitle_.setBounds(statusLeft.removeFromTop(18));\n    jobStatusValue_.setBounds(statusLeft.removeFromTop(40));\n\n    errorTitle_.setBounds(statusRight.removeFromTop(18));\n    errorValue_.setBounds(statusRight.removeFromTop(94));\n    statusRight.removeFromTop(10);\n    generateButton_.setBounds(statusRight.removeFromTop(30).removeFromLeft(180));\n\n    bounds.removeFromTop(8);\n    resultsLabel_.setBounds(bounds.removeFromTop(18));\n    resultSlotBox_.setBounds(bounds.removeFromTop(28));\n\n    bounds.removeFromTop(12);\n    previewTitle_.setBounds(bounds.removeFromTop(18));\n    previewValue_.setBounds(bounds.removeFromTop(56));\n    bounds.removeFromTop(8);\n    auto previewButtons = bounds.removeFromTop(30);\n    choosePreviewButton_.setBounds(previewButtons.removeFromLeft(180));\n    previewButtons.removeFromLeft(8);\n    playPreviewButton_.setBounds(previewButtons.removeFromLeft(72));\n    previewButtons.removeFromLeft(8);\n    stopPreviewButton_.setBounds(previewButtons.removeFromLeft(72));\n    previewButtons.removeFromLeft(8);\n    clearPreviewButton_.setBounds(previewButtons.removeFromLeft(72));\n    previewButtons.removeFromLeft(8);\n    revealPreviewButton_.setBounds(previewButtons.removeFromLeft(120));\n}\n\nvoid ACEStepVST3AudioProcessorEditor::timerCallback()\n{\n    processor_.pumpBackendWorkflow();\n    refreshResultSelector();\n    refreshStatusViews();\n}\n}  // namespace acestep::vst3\n"
  },
  {
    "path": "plugins/acestep_vst3/src/PluginEditor.h",
    "content": "#pragma once\n\n#include <JuceHeader.h>\n\nnamespace acestep::vst3\n{\nclass ACEStepVST3AudioProcessor;\n\nclass ACEStepVST3AudioProcessorEditor final : public juce::AudioProcessorEditor,\n                                              private juce::Timer\n{\npublic:\n    explicit ACEStepVST3AudioProcessorEditor(ACEStepVST3AudioProcessor& processor);\n    ~ACEStepVST3AudioProcessorEditor() override;\n\n    void paint(juce::Graphics& g) override;\n    void resized() override;\n\nprivate:\n    void timerCallback() override;\n    void configureLabels();\n    void configureEditors();\n    void configureSelectors();\n    void syncFromProcessor();\n    void persistTextFields();\n    void refreshResultSelector();\n    void refreshStatusViews();\n    void choosePreviewFile();\n    void playPreviewFile();\n    void stopPreviewFile();\n    void clearPreviewFile();\n    void revealPreviewFile();\n\n    ACEStepVST3AudioProcessor& processor_;\n    juce::Label titleLabel_;\n    juce::Label subtitleLabel_;\n    juce::Label backendUrlLabel_;\n    juce::Label promptLabel_;\n    juce::Label lyricsLabel_;\n    juce::Label durationLabel_;\n    juce::Label seedLabel_;\n    juce::Label modelLabel_;\n    juce::Label qualityLabel_;\n    juce::Label backendStatusTitle_;\n    juce::Label backendStatusValue_;\n    juce::Label jobStatusTitle_;\n    juce::Label jobStatusValue_;\n    juce::Label errorTitle_;\n    juce::Label errorValue_;\n    juce::Label resultsLabel_;\n    juce::Label previewTitle_;\n    juce::Label previewValue_;\n    juce::TextEditor backendUrlEditor_;\n    juce::TextEditor promptEditor_;\n    juce::TextEditor lyricsEditor_;\n    juce::TextEditor seedEditor_;\n    juce::ComboBox durationBox_;\n    juce::ComboBox modelBox_;\n    juce::ComboBox qualityBox_;\n    juce::ComboBox backendStatusBox_;\n    juce::ComboBox resultSlotBox_;\n    juce::TextButton generateButton_ {\"Generate\"};\n    juce::TextButton choosePreviewButton_ {\"Load Preview File\"};\n    juce::TextButton playPreviewButton_ {\"Play\"};\n    juce::TextButton stopPreviewButton_ {\"Stop\"};\n    juce::TextButton clearPreviewButton_ {\"Clear\"};\n    juce::TextButton revealPreviewButton_ {\"Reveal File\"};\n    std::unique_ptr<juce::FileChooser> previewChooser_;\n    bool isSyncing_ = false;\n\n    JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(ACEStepVST3AudioProcessorEditor)\n};\n}  // namespace acestep::vst3\n"
  },
  {
    "path": "plugins/acestep_vst3/src/PluginEditorPreview.cpp",
    "content": "#include \"PluginEditor.h\"\n\n#include \"PluginProcessor.h\"\n\nnamespace acestep::vst3\n{\nvoid ACEStepVST3AudioProcessorEditor::choosePreviewFile()\n{\n    previewChooser_ = std::make_unique<juce::FileChooser>(\"Select preview audio file\",\n                                                          juce::File(),\n                                                          \"*.wav;*.aiff;*.flac;*.ogg;*.mp3\");\n    previewChooser_->launchAsync(juce::FileBrowserComponent::openMode\n                                     | juce::FileBrowserComponent::canSelectFiles,\n                                 [this](const juce::FileChooser& chooser) {\n                                     const auto file = chooser.getResult();\n                                     previewChooser_.reset();\n                                     if (file == juce::File())\n                                     {\n                                         return;\n                                     }\n\n                                     processor_.stopPreview();\n                                     [[maybe_unused]] const auto loaded = processor_.loadPreviewFile(file);\n                                     refreshStatusViews();\n                                 });\n}\n\nvoid ACEStepVST3AudioProcessorEditor::playPreviewFile()\n{\n    processor_.playPreview();\n    refreshStatusViews();\n}\n\nvoid ACEStepVST3AudioProcessorEditor::stopPreviewFile()\n{\n    processor_.stopPreview();\n    refreshStatusViews();\n}\n\nvoid ACEStepVST3AudioProcessorEditor::clearPreviewFile()\n{\n    processor_.stopPreview();\n    processor_.clearPreviewFile();\n    refreshStatusViews();\n}\n\nvoid ACEStepVST3AudioProcessorEditor::revealPreviewFile()\n{\n    processor_.revealPreviewFile();\n}\n}  // namespace acestep::vst3\n"
  },
  {
    "path": "plugins/acestep_vst3/src/PluginEditorState.cpp",
    "content": "#include \"PluginEditor.h\"\n\n#include \"PluginEnums.h\"\n#include \"PluginProcessor.h\"\n\nnamespace acestep::vst3\n{\nvoid ACEStepVST3AudioProcessorEditor::configureLabels()\n{\n    titleLabel_.setText(\"ACE-Step VST3 MVP UI\", juce::dontSendNotification);\n    titleLabel_.setFont(juce::Font(juce::FontOptions(20.0f, juce::Font::bold)));\n    subtitleLabel_.setText(\"State-driven prompt, job, and result workflow shell.\",\n                           juce::dontSendNotification);\n\n    for (auto* label : {&titleLabel_, &subtitleLabel_, &backendUrlLabel_, &promptLabel_,\n                        &lyricsLabel_, &durationLabel_, &seedLabel_, &modelLabel_,\n                        &qualityLabel_, &backendStatusTitle_, &backendStatusValue_,\n                        &jobStatusTitle_, &jobStatusValue_, &errorTitle_, &errorValue_,\n                        &resultsLabel_, &previewTitle_, &previewValue_})\n    {\n        label->setJustificationType(juce::Justification::centredLeft);\n        addAndMakeVisible(*label);\n    }\n\n    backendUrlLabel_.setText(\"Backend URL\", juce::dontSendNotification);\n    promptLabel_.setText(\"Prompt\", juce::dontSendNotification);\n    lyricsLabel_.setText(\"Lyrics\", juce::dontSendNotification);\n    durationLabel_.setText(\"Duration\", juce::dontSendNotification);\n    seedLabel_.setText(\"Seed\", juce::dontSendNotification);\n    modelLabel_.setText(\"Model preset\", juce::dontSendNotification);\n    qualityLabel_.setText(\"Quality mode\", juce::dontSendNotification);\n    backendStatusTitle_.setText(\"Backend status\", juce::dontSendNotification);\n    jobStatusTitle_.setText(\"Job status\", juce::dontSendNotification);\n    errorTitle_.setText(\"Error state\", juce::dontSendNotification);\n    resultsLabel_.setText(\"Result slot selection\", juce::dontSendNotification);\n    previewTitle_.setText(\"Preview and file handoff\", juce::dontSendNotification);\n    errorValue_.setColour(juce::Label::textColourId, juce::Colours::lightsalmon);\n}\n\nvoid ACEStepVST3AudioProcessorEditor::configureEditors()\n{\n    backendUrlEditor_.setTextToShowWhenEmpty(kDefaultBackendBaseUrl, juce::Colours::grey);\n    backendUrlEditor_.onTextChange = [this] { persistTextFields(); };\n    promptEditor_.setTextToShowWhenEmpty(\"Describe the song idea\", juce::Colours::grey);\n    promptEditor_.onTextChange = [this] { persistTextFields(); };\n    lyricsEditor_.setTextToShowWhenEmpty(\"Optional lyric sketch\", juce::Colours::grey);\n    lyricsEditor_.setMultiLine(true);\n    lyricsEditor_.onTextChange = [this] { persistTextFields(); };\n    seedEditor_.setInputRestrictions(10, \"0123456789\");\n    seedEditor_.onTextChange = [this] { persistTextFields(); };\n\n    for (auto* editor : {&backendUrlEditor_, &promptEditor_, &lyricsEditor_, &seedEditor_})\n    {\n        addAndMakeVisible(*editor);\n    }\n}\n\nvoid ACEStepVST3AudioProcessorEditor::configureSelectors()\n{\n    for (const auto duration : {10, 30, 60, 120})\n    {\n        durationBox_.addItem(juce::String(duration) + \" seconds\", duration);\n    }\n    modelBox_.addItem(toString(ModelPreset::turbo), 1);\n    modelBox_.addItem(toString(ModelPreset::standard), 2);\n    modelBox_.addItem(toString(ModelPreset::quality), 3);\n    qualityBox_.addItem(toString(QualityMode::fast), 1);\n    qualityBox_.addItem(toString(QualityMode::balanced), 2);\n    qualityBox_.addItem(toString(QualityMode::high), 3);\n    backendStatusBox_.addItem(toString(BackendStatus::ready), 1);\n    backendStatusBox_.addItem(toString(BackendStatus::offline), 2);\n    backendStatusBox_.addItem(toString(BackendStatus::degraded), 3);\n    backendStatusBox_.setEnabled(false);\n\n    durationBox_.onChange = [this] { persistTextFields(); };\n    modelBox_.onChange = [this] { persistTextFields(); };\n    qualityBox_.onChange = [this] { persistTextFields(); };\n    resultSlotBox_.onChange = [this] {\n        if (isSyncing_)\n        {\n            return;\n        }\n        processor_.selectResultSlot(juce::jmax(0, resultSlotBox_.getSelectedItemIndex()));\n        refreshStatusViews();\n    };\n    generateButton_.onClick = [this] {\n        persistTextFields();\n        processor_.requestGeneration();\n        refreshStatusViews();\n    };\n    choosePreviewButton_.onClick = [this] { choosePreviewFile(); };\n    playPreviewButton_.onClick = [this] { playPreviewFile(); };\n    stopPreviewButton_.onClick = [this] { stopPreviewFile(); };\n    clearPreviewButton_.onClick = [this] { clearPreviewFile(); };\n    revealPreviewButton_.onClick = [this] { revealPreviewFile(); };\n\n    for (auto* component : {static_cast<juce::Component*>(&durationBox_),\n                            static_cast<juce::Component*>(&modelBox_),\n                            static_cast<juce::Component*>(&qualityBox_),\n                            static_cast<juce::Component*>(&backendStatusBox_),\n                            static_cast<juce::Component*>(&resultSlotBox_),\n                            static_cast<juce::Component*>(&generateButton_),\n                            static_cast<juce::Component*>(&choosePreviewButton_),\n                            static_cast<juce::Component*>(&playPreviewButton_),\n                            static_cast<juce::Component*>(&stopPreviewButton_),\n                            static_cast<juce::Component*>(&clearPreviewButton_),\n                            static_cast<juce::Component*>(&revealPreviewButton_)})\n    {\n        addAndMakeVisible(*component);\n    }\n}\n\nvoid ACEStepVST3AudioProcessorEditor::syncFromProcessor()\n{\n    const auto& state = processor_.getState();\n    isSyncing_ = true;\n    backendUrlEditor_.setText(state.backendBaseUrl, juce::dontSendNotification);\n    promptEditor_.setText(state.prompt, juce::dontSendNotification);\n    lyricsEditor_.setText(state.lyrics, juce::dontSendNotification);\n    seedEditor_.setText(juce::String(state.seed), juce::dontSendNotification);\n    durationBox_.setSelectedId(state.durationSeconds, juce::dontSendNotification);\n    modelBox_.setSelectedId(static_cast<int>(state.modelPreset) + 1, juce::dontSendNotification);\n    qualityBox_.setSelectedId(static_cast<int>(state.qualityMode) + 1,\n                              juce::dontSendNotification);\n    backendStatusBox_.setSelectedId(static_cast<int>(state.backendStatus) + 1,\n                                    juce::dontSendNotification);\n    isSyncing_ = false;\n}\n\nvoid ACEStepVST3AudioProcessorEditor::persistTextFields()\n{\n    if (isSyncing_)\n    {\n        return;\n    }\n\n    auto& state = processor_.getMutableState();\n    state.backendBaseUrl = backendUrlEditor_.getText().trim();\n    if (state.backendBaseUrl.isEmpty())\n    {\n        state.backendBaseUrl = kDefaultBackendBaseUrl;\n        backendUrlEditor_.setText(state.backendBaseUrl, juce::dontSendNotification);\n    }\n\n    state.prompt = promptEditor_.getText();\n    state.lyrics = lyricsEditor_.getText();\n    state.durationSeconds = durationBox_.getSelectedId() == 0 ? kDefaultDurationSeconds\n                                                              : durationBox_.getSelectedId();\n    state.seed = seedEditor_.getText().getIntValue();\n    if (state.seed <= 0)\n    {\n        state.seed = kDefaultSeed;\n        seedEditor_.setText(juce::String(state.seed), juce::dontSendNotification);\n    }\n\n    state.modelPreset = static_cast<ModelPreset>(juce::jmax(0, modelBox_.getSelectedItemIndex()));\n    state.qualityMode = static_cast<QualityMode>(juce::jmax(0, qualityBox_.getSelectedItemIndex()));\n    refreshStatusViews();\n}\n\nvoid ACEStepVST3AudioProcessorEditor::refreshResultSelector()\n{\n    const auto& state = processor_.getState();\n    isSyncing_ = true;\n    resultSlotBox_.clear(juce::dontSendNotification);\n    for (int index = 0; index < kResultSlotCount; ++index)\n    {\n        auto label = state.resultSlots[static_cast<size_t>(index)];\n        if (label.isEmpty())\n        {\n            label = \"Result \" + juce::String(index + 1) + \" - empty\";\n        }\n        resultSlotBox_.addItem(label, index + 1);\n    }\n    resultSlotBox_.setSelectedId(state.selectedResultSlot + 1, juce::dontSendNotification);\n    isSyncing_ = false;\n}\n\nvoid ACEStepVST3AudioProcessorEditor::refreshStatusViews()\n{\n    const auto& state = processor_.getState();\n    backendStatusBox_.setSelectedId(static_cast<int>(state.backendStatus) + 1,\n                                    juce::dontSendNotification);\n    backendStatusValue_.setText(\n        \"Target: \" + state.backendBaseUrl + \"\\nStatus: \" + toString(state.backendStatus),\n        juce::dontSendNotification);\n    jobStatusValue_.setText(\"State: \" + toString(state.jobStatus) + \"\\nSelected slot: \"\n                                + juce::String(state.selectedResultSlot + 1) + \"\\nMessage: \"\n                                + (state.progressText.isEmpty() ? \"Idle\" : state.progressText),\n                            juce::dontSendNotification);\n    errorValue_.setText(state.errorMessage.isEmpty() ? \"No active error.\" : state.errorMessage,\n                        juce::dontSendNotification);\n\n    auto previewText = state.previewDisplayName.isEmpty() ? \"No preview file loaded.\"\n                                                          : state.previewDisplayName;\n    previewText += \"\\n\";\n    previewText += state.previewFilePath.isEmpty() ? \"Choose a local audio file to preview or reveal.\"\n                                                   : state.previewFilePath;\n    if (processor_.isPreviewPlaying())\n    {\n        previewText += \"\\nPlayback: active\";\n    }\n    previewValue_.setText(previewText, juce::dontSendNotification);\n\n    const auto isBusy = state.jobStatus == JobStatus::submitting\n                        || state.jobStatus == JobStatus::queuedOrRunning;\n    generateButton_.setEnabled(!isBusy);\n    generateButton_.setButtonText(isBusy ? \"Rendering...\" : \"Generate\");\n}\n}  // namespace acestep::vst3\n"
  },
  {
    "path": "plugins/acestep_vst3/src/PluginEnums.cpp",
    "content": "#include \"PluginEnums.h\"\n\nnamespace acestep::vst3\n{\nnamespace\n{\njuce::String normalized(juce::String value)\n{\n    return value.trim().toLowerCase();\n}\n}  // namespace\n\njuce::String toString(BackendStatus status)\n{\n    switch (status)\n    {\n        case BackendStatus::ready:\n            return \"Ready\";\n        case BackendStatus::offline:\n            return \"Offline\";\n        case BackendStatus::degraded:\n            return \"Degraded\";\n    }\n\n    return \"Ready\";\n}\n\njuce::String toString(JobStatus status)\n{\n    switch (status)\n    {\n        case JobStatus::idle:\n            return \"Idle\";\n        case JobStatus::submitting:\n            return \"Submitting\";\n        case JobStatus::queuedOrRunning:\n            return \"Queued / Running\";\n        case JobStatus::succeeded:\n            return \"Succeeded\";\n        case JobStatus::failed:\n            return \"Failed\";\n    }\n\n    return \"Idle\";\n}\n\njuce::String toString(ModelPreset preset)\n{\n    switch (preset)\n    {\n        case ModelPreset::turbo:\n            return \"Turbo\";\n        case ModelPreset::standard:\n            return \"Standard\";\n        case ModelPreset::quality:\n            return \"Quality\";\n    }\n\n    return \"Turbo\";\n}\n\njuce::String toString(QualityMode mode)\n{\n    switch (mode)\n    {\n        case QualityMode::fast:\n            return \"Fast\";\n        case QualityMode::balanced:\n            return \"Balanced\";\n        case QualityMode::high:\n            return \"High\";\n    }\n\n    return \"Balanced\";\n}\n\nBackendStatus backendStatusFromString(const juce::String& value)\n{\n    const auto key = normalized(value);\n    if (key == \"offline\")\n    {\n        return BackendStatus::offline;\n    }\n    if (key == \"degraded\")\n    {\n        return BackendStatus::degraded;\n    }\n    return BackendStatus::ready;\n}\n\nJobStatus jobStatusFromString(const juce::String& value)\n{\n    const auto key = normalized(value);\n    if (key == \"submitting\")\n    {\n        return JobStatus::submitting;\n    }\n    if (key == \"queued / running\" || key == \"queued/running\" || key == \"queued_or_running\")\n    {\n        return JobStatus::queuedOrRunning;\n    }\n    if (key == \"succeeded\")\n    {\n        return JobStatus::succeeded;\n    }\n    if (key == \"failed\")\n    {\n        return JobStatus::failed;\n    }\n    return JobStatus::idle;\n}\n\nModelPreset modelPresetFromString(const juce::String& value)\n{\n    const auto key = normalized(value);\n    if (key == \"standard\")\n    {\n        return ModelPreset::standard;\n    }\n    if (key == \"quality\")\n    {\n        return ModelPreset::quality;\n    }\n    return ModelPreset::turbo;\n}\n\nQualityMode qualityModeFromString(const juce::String& value)\n{\n    const auto key = normalized(value);\n    if (key == \"fast\")\n    {\n        return QualityMode::fast;\n    }\n    if (key == \"high\")\n    {\n        return QualityMode::high;\n    }\n    return QualityMode::balanced;\n}\n}  // namespace acestep::vst3\n"
  },
  {
    "path": "plugins/acestep_vst3/src/PluginEnums.h",
    "content": "#pragma once\n\n#include <JuceHeader.h>\n\nnamespace acestep::vst3\n{\nenum class BackendStatus\n{\n    ready,\n    offline,\n    degraded,\n};\n\nenum class JobStatus\n{\n    idle,\n    submitting,\n    queuedOrRunning,\n    succeeded,\n    failed,\n};\n\nenum class ModelPreset\n{\n    turbo,\n    standard,\n    quality,\n};\n\nenum class QualityMode\n{\n    fast,\n    balanced,\n    high,\n};\n\n[[nodiscard]] juce::String toString(BackendStatus status);\n[[nodiscard]] juce::String toString(JobStatus status);\n[[nodiscard]] juce::String toString(ModelPreset preset);\n[[nodiscard]] juce::String toString(QualityMode mode);\n\n[[nodiscard]] BackendStatus backendStatusFromString(const juce::String& value);\n[[nodiscard]] JobStatus jobStatusFromString(const juce::String& value);\n[[nodiscard]] ModelPreset modelPresetFromString(const juce::String& value);\n[[nodiscard]] QualityMode qualityModeFromString(const juce::String& value);\n}  // namespace acestep::vst3\n"
  },
  {
    "path": "plugins/acestep_vst3/src/PluginMockGeneration.cpp",
    "content": "#include \"PluginMockGeneration.h\"\n\n#include \"PluginEnums.h\"\n\nnamespace acestep::vst3\n{\nnamespace\n{\njuce::String buildResultLabel(const PluginState& state, int slotIndex)\n{\n    const auto prompt = state.prompt.isEmpty() ? \"Untitled prompt\" : state.prompt.upToFirstOccurrenceOf(\"\\n\", false, false);\n    return \"Result \" + juce::String(slotIndex + 1) + \" - \" + prompt.substring(0, 28) + \" (\"\n           + juce::String(state.durationSeconds) + \"s, \" + toString(state.qualityMode) + \")\";\n}\n}  // namespace\n\nbool beginMockGeneration(PluginState& state)\n{\n    state.errorMessage = {};\n    if (state.prompt.trim().isEmpty())\n    {\n        state.jobStatus = JobStatus::failed;\n        state.errorMessage = \"Prompt is required before generation.\";\n        return false;\n    }\n\n    if (state.backendStatus == BackendStatus::offline)\n    {\n        state.jobStatus = JobStatus::failed;\n        state.errorMessage = \"Backend is offline. Update the backend status before generating.\";\n        return false;\n    }\n\n    state.jobStatus = JobStatus::submitting;\n    return true;\n}\n\nvoid advanceMockGeneration(PluginState& state, int phaseIndex)\n{\n    if (phaseIndex == 0)\n    {\n        state.jobStatus = JobStatus::queuedOrRunning;\n        state.errorMessage = {};\n        return;\n    }\n\n    state.jobStatus = JobStatus::succeeded;\n    state.errorMessage = {};\n    for (int index = 0; index < kResultSlotCount; ++index)\n    {\n        state.resultSlots[static_cast<size_t>(index)] = buildResultLabel(state, index);\n    }\n    state.selectedResultSlot = 0;\n}\n}  // namespace acestep::vst3\n"
  },
  {
    "path": "plugins/acestep_vst3/src/PluginMockGeneration.h",
    "content": "#pragma once\n\n#include \"PluginState.h\"\n\nnamespace acestep::vst3\n{\n[[nodiscard]] bool beginMockGeneration(PluginState& state);\nvoid advanceMockGeneration(PluginState& state, int phaseIndex);\n}  // namespace acestep::vst3\n"
  },
  {
    "path": "plugins/acestep_vst3/src/PluginPreview.cpp",
    "content": "#include \"PluginPreview.h\"\n\nnamespace acestep::vst3\n{\nPluginPreview::PluginPreview()\n{\n    formatManager_.registerBasicFormats();\n}\n\nPluginPreview::~PluginPreview()\n{\n    clear();\n}\n\nvoid PluginPreview::prepareToPlay(double sampleRate, int samplesPerBlock)\n{\n    const juce::ScopedLock lock(lock_);\n    sampleRate_ = sampleRate > 0.0 ? sampleRate : 44100.0;\n    transportSource_.prepareToPlay(samplesPerBlock, sampleRate_);\n}\n\nvoid PluginPreview::releaseResources()\n{\n    const juce::ScopedLock lock(lock_);\n    transportSource_.releaseResources();\n}\n\nvoid PluginPreview::render(juce::AudioBuffer<float>& buffer)\n{\n    const juce::ScopedTryLock lock(lock_);\n    if (!lock.isLocked() || readerSource_ == nullptr)\n    {\n        return;\n    }\n\n    juce::AudioSourceChannelInfo channelInfo(&buffer, 0, buffer.getNumSamples());\n    transportSource_.getNextAudioBlock(channelInfo);\n}\n\nbool PluginPreview::loadFile(const juce::File& file, juce::String& errorMessage)\n{\n    errorMessage = {};\n    if (!file.existsAsFile())\n    {\n        errorMessage = \"Preview file not found.\";\n        return false;\n    }\n\n    std::unique_ptr<juce::AudioFormatReader> reader(formatManager_.createReaderFor(file));\n    if (reader == nullptr)\n    {\n        errorMessage = \"Preview file format is not supported.\";\n        return false;\n    }\n\n    const auto readerSampleRate = reader->sampleRate;\n    auto nextReaderSource = std::make_unique<juce::AudioFormatReaderSource>(reader.release(), true);\n\n    const juce::ScopedLock lock(lock_);\n    transportSource_.stop();\n    transportSource_.setSource(nullptr);\n    readerSource_.reset();\n    transportSource_.setSource(nextReaderSource.get(), 0, nullptr, readerSampleRate);\n    readerSource_ = std::move(nextReaderSource);\n    currentFile_ = file;\n    return true;\n}\n\nvoid PluginPreview::clear()\n{\n    const juce::ScopedLock lock(lock_);\n    transportSource_.stop();\n    transportSource_.setSource(nullptr);\n    readerSource_.reset();\n    currentFile_ = juce::File();\n}\n\nvoid PluginPreview::play()\n{\n    const juce::ScopedLock lock(lock_);\n    if (readerSource_ == nullptr)\n    {\n        return;\n    }\n\n    transportSource_.setPosition(0.0);\n    transportSource_.start();\n}\n\nvoid PluginPreview::stop()\n{\n    const juce::ScopedLock lock(lock_);\n    transportSource_.stop();\n}\n\nvoid PluginPreview::revealToUser() const\n{\n    const juce::ScopedLock lock(lock_);\n    if (currentFile_.existsAsFile())\n    {\n        currentFile_.revealToUser();\n    }\n}\n\nbool PluginPreview::hasLoadedFile() const\n{\n    const juce::ScopedLock lock(lock_);\n    return readerSource_ != nullptr && currentFile_.existsAsFile();\n}\n\nbool PluginPreview::isPlaying() const\n{\n    const juce::ScopedLock lock(lock_);\n    return transportSource_.isPlaying();\n}\n\njuce::String PluginPreview::getDisplayName() const\n{\n    const juce::ScopedLock lock(lock_);\n    return currentFile_.existsAsFile() ? currentFile_.getFileName() : juce::String();\n}\n\njuce::String PluginPreview::getFilePath() const\n{\n    const juce::ScopedLock lock(lock_);\n    return currentFile_.getFullPathName();\n}\n}  // namespace acestep::vst3\n"
  },
  {
    "path": "plugins/acestep_vst3/src/PluginPreview.h",
    "content": "#pragma once\n\n#include <memory>\n\n#include <JuceHeader.h>\n\nnamespace acestep::vst3\n{\nclass PluginPreview final\n{\npublic:\n    PluginPreview();\n    ~PluginPreview();\n\n    void prepareToPlay(double sampleRate, int samplesPerBlock);\n    void releaseResources();\n    void render(juce::AudioBuffer<float>& buffer);\n\n    [[nodiscard]] bool loadFile(const juce::File& file, juce::String& errorMessage);\n    void clear();\n    void play();\n    void stop();\n    void revealToUser() const;\n\n    [[nodiscard]] bool hasLoadedFile() const;\n    [[nodiscard]] bool isPlaying() const;\n    [[nodiscard]] juce::String getDisplayName() const;\n    [[nodiscard]] juce::String getFilePath() const;\n\nprivate:\n    mutable juce::CriticalSection lock_;\n    juce::AudioFormatManager formatManager_;\n    juce::AudioTransportSource transportSource_;\n    std::unique_ptr<juce::AudioFormatReaderSource> readerSource_;\n    juce::File currentFile_;\n    double sampleRate_ = 44100.0;\n\n    JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(PluginPreview)\n};\n}  // namespace acestep::vst3\n"
  },
  {
    "path": "plugins/acestep_vst3/src/PluginProcessor.cpp",
    "content": "#include \"PluginProcessor.h\"\n\n#include \"PluginEditor.h\"\n\nnamespace acestep::vst3\n{\nACEStepVST3AudioProcessor::ACEStepVST3AudioProcessor()\n    : juce::AudioProcessor(\n          BusesProperties().withOutput(\"Output\", juce::AudioChannelSet::stereo(), true))\n{\n}\n\nACEStepVST3AudioProcessor::~ACEStepVST3AudioProcessor() = default;\n\nvoid ACEStepVST3AudioProcessor::prepareToPlay(double sampleRate, int samplesPerBlock)\n{\n    preview_.prepareToPlay(sampleRate, samplesPerBlock);\n}\n\nvoid ACEStepVST3AudioProcessor::releaseResources()\n{\n    preview_.releaseResources();\n}\n\nbool ACEStepVST3AudioProcessor::isBusesLayoutSupported(const BusesLayout& layouts) const\n{\n    if (layouts.getMainOutputChannelSet() != juce::AudioChannelSet::stereo())\n    {\n        return false;\n    }\n\n    return layouts.getMainInputChannelSet().isDisabled();\n}\n\nvoid ACEStepVST3AudioProcessor::processBlock(juce::AudioBuffer<float>& buffer,\n                                             juce::MidiBuffer& midiMessages)\n{\n    juce::ignoreUnused(midiMessages);\n    buffer.clear();\n    preview_.render(buffer);\n}\n\njuce::AudioProcessorEditor* ACEStepVST3AudioProcessor::createEditor()\n{\n    return new ACEStepVST3AudioProcessorEditor(*this);\n}\n\nbool ACEStepVST3AudioProcessor::hasEditor() const\n{\n    return true;\n}\n\nconst juce::String ACEStepVST3AudioProcessor::getName() const\n{\n    return kPluginName;\n}\n\nbool ACEStepVST3AudioProcessor::acceptsMidi() const\n{\n    return true;\n}\n\nbool ACEStepVST3AudioProcessor::producesMidi() const\n{\n    return false;\n}\n\nbool ACEStepVST3AudioProcessor::isMidiEffect() const\n{\n    return false;\n}\n\nbool ACEStepVST3AudioProcessor::isSynth() const\n{\n    return true;\n}\n\ndouble ACEStepVST3AudioProcessor::getTailLengthSeconds() const\n{\n    return 0.0;\n}\n\nint ACEStepVST3AudioProcessor::getNumPrograms()\n{\n    return 1;\n}\n\nint ACEStepVST3AudioProcessor::getCurrentProgram()\n{\n    return 0;\n}\n\nvoid ACEStepVST3AudioProcessor::setCurrentProgram(int index)\n{\n    juce::ignoreUnused(index);\n}\n\nconst juce::String ACEStepVST3AudioProcessor::getProgramName(int index)\n{\n    juce::ignoreUnused(index);\n    return {};\n}\n\nvoid ACEStepVST3AudioProcessor::changeProgramName(int index, const juce::String& newName)\n{\n    juce::ignoreUnused(index, newName);\n}\n\nvoid ACEStepVST3AudioProcessor::getStateInformation(juce::MemoryBlock& destData)\n{\n    if (auto xml = createStateXml(state_))\n    {\n        copyXmlToBinary(*xml, destData);\n    }\n}\n\nvoid ACEStepVST3AudioProcessor::setStateInformation(const void* data, int sizeInBytes)\n{\n    std::unique_ptr<juce::XmlElement> xml(getXmlFromBinary(data, sizeInBytes));\n    if (xml != nullptr)\n    {\n        if (auto parsedState = parseStateXml(*xml))\n        {\n            state_ = *parsedState;\n            syncPreviewFromState();\n        }\n    }\n}\n\nconst PluginState& ACEStepVST3AudioProcessor::getState() const noexcept\n{\n    return state_;\n}\n\nPluginState& ACEStepVST3AudioProcessor::getMutableState() noexcept\n{\n    return state_;\n}\n\nbool ACEStepVST3AudioProcessor::loadPreviewFile(const juce::File& file)\n{\n    juce::String errorMessage;\n    if (!preview_.loadFile(file, errorMessage))\n    {\n        state_.errorMessage = errorMessage;\n        return false;\n    }\n\n    state_.previewFilePath = file.getFullPathName();\n    state_.previewDisplayName = file.getFileName();\n    state_.errorMessage = {};\n    return true;\n}\n\nvoid ACEStepVST3AudioProcessor::clearPreviewFile()\n{\n    preview_.clear();\n    state_.previewFilePath = {};\n    state_.previewDisplayName = {};\n    state_.errorMessage = {};\n}\n\nvoid ACEStepVST3AudioProcessor::playPreview()\n{\n    if (!hasPreviewFile())\n    {\n        state_.errorMessage = \"Load a preview file before playing it.\";\n        return;\n    }\n\n    state_.errorMessage = {};\n    preview_.play();\n}\n\nvoid ACEStepVST3AudioProcessor::stopPreview()\n{\n    preview_.stop();\n}\n\nvoid ACEStepVST3AudioProcessor::revealPreviewFile() const\n{\n    preview_.revealToUser();\n}\n\nbool ACEStepVST3AudioProcessor::hasPreviewFile() const\n{\n    return preview_.hasLoadedFile();\n}\n\nbool ACEStepVST3AudioProcessor::isPreviewPlaying() const\n{\n    return preview_.isPlaying();\n}\n\nvoid ACEStepVST3AudioProcessor::requestGeneration()\n{\n    if (state_.prompt.trim().isEmpty())\n    {\n        state_.jobStatus = JobStatus::failed;\n        state_.progressText = {};\n        state_.errorMessage = \"Prompt is required before generation.\";\n        return;\n    }\n\n    clearGeneratedResults();\n    stopPreview();\n    clearPreviewFile();\n    state_.jobStatus = JobStatus::submitting;\n    state_.progressText = \"Submitting request...\";\n    state_.errorMessage = {};\n}\n\nvoid ACEStepVST3AudioProcessor::selectResultSlot(int index)\n{\n    state_.selectedResultSlot = juce::jlimit(0, kResultSlotCount - 1, index);\n    const auto& localPath = state_.resultLocalPaths[static_cast<size_t>(state_.selectedResultSlot)];\n    if (localPath.isNotEmpty())\n    {\n        [[maybe_unused]] const auto loaded = loadPreviewFile(juce::File(localPath));\n    }\n}\n\nvoid ACEStepVST3AudioProcessor::pumpBackendWorkflow()\n{\n    std::optional<BackendTaskResult> completedTask;\n    {\n        const juce::ScopedLock lock(backendTaskLock_);\n        if (completedBackendTask_.has_value())\n        {\n            completedTask = std::move(completedBackendTask_);\n            completedBackendTask_.reset();\n        }\n    }\n\n    if (completedTask.has_value())\n    {\n        applyCompletedTask(*completedTask);\n    }\n\n    if (backendTaskRunning_.load())\n    {\n        return;\n    }\n\n    if (pendingPreviewDownloadSlot_.has_value())\n    {\n        schedulePreviewDownload(*pendingPreviewDownloadSlot_);\n        pendingPreviewDownloadSlot_.reset();\n        return;\n    }\n\n    const auto now = juce::Time::getMillisecondCounter();\n    if (state_.jobStatus == JobStatus::submitting)\n    {\n        scheduleGenerationStart();\n        return;\n    }\n\n    if (state_.jobStatus == JobStatus::queuedOrRunning && state_.currentTaskId.isNotEmpty()\n        && now - lastPollRequestAtMs_ >= 1500)\n    {\n        scheduleGenerationPoll();\n        return;\n    }\n\n    if (state_.jobStatus == JobStatus::idle || state_.jobStatus == JobStatus::failed\n        || state_.jobStatus == JobStatus::succeeded)\n    {\n        if (lastHealthCheckedBaseUrl_ != state_.backendBaseUrl\n            || now - lastHealthCheckAtMs_ >= 5000)\n        {\n            scheduleHealthCheck();\n        }\n    }\n}\n\nvoid ACEStepVST3AudioProcessor::scheduleHealthCheck()\n{\n    if (backendTaskRunning_.exchange(true))\n    {\n        return;\n    }\n\n    lastHealthCheckedBaseUrl_ = state_.backendBaseUrl;\n    lastHealthCheckAtMs_ = juce::Time::getMillisecondCounter();\n    const auto baseUrl = state_.backendBaseUrl;\n    backendThreadPool_.addJob(std::function<juce::ThreadPoolJob::JobStatus()>([this, baseUrl]() {\n        BackendTaskResult taskResult;\n        taskResult.kind = BackendTaskKind::healthCheck;\n        taskResult.health = backendClient_.checkHealth(baseUrl);\n        const juce::ScopedLock lock(backendTaskLock_);\n        completedBackendTask_ = std::move(taskResult);\n        backendTaskRunning_.store(false);\n        return juce::ThreadPoolJob::jobHasFinished;\n    }));\n}\n\nvoid ACEStepVST3AudioProcessor::scheduleGenerationStart()\n{\n    if (backendTaskRunning_.exchange(true))\n    {\n        return;\n    }\n\n    const auto stateSnapshot = state_;\n    backendThreadPool_.addJob(std::function<juce::ThreadPoolJob::JobStatus()>([this, stateSnapshot]() {\n        BackendTaskResult taskResult;\n        taskResult.kind = BackendTaskKind::submitGeneration;\n        taskResult.generationStart = backendClient_.startGeneration(stateSnapshot);\n        const juce::ScopedLock lock(backendTaskLock_);\n        completedBackendTask_ = std::move(taskResult);\n        backendTaskRunning_.store(false);\n        return juce::ThreadPoolJob::jobHasFinished;\n    }));\n}\n\nvoid ACEStepVST3AudioProcessor::scheduleGenerationPoll()\n{\n    if (backendTaskRunning_.exchange(true))\n    {\n        return;\n    }\n\n    const auto baseUrl = state_.backendBaseUrl;\n    const auto taskId = state_.currentTaskId;\n    lastPollRequestAtMs_ = juce::Time::getMillisecondCounter();\n    backendThreadPool_.addJob(std::function<juce::ThreadPoolJob::JobStatus()>([this, baseUrl, taskId]() {\n        BackendTaskResult taskResult;\n        taskResult.kind = BackendTaskKind::pollGeneration;\n        taskResult.generationPoll = backendClient_.pollGeneration(baseUrl, taskId);\n        const juce::ScopedLock lock(backendTaskLock_);\n        completedBackendTask_ = std::move(taskResult);\n        backendTaskRunning_.store(false);\n        return juce::ThreadPoolJob::jobHasFinished;\n    }));\n}\n\nvoid ACEStepVST3AudioProcessor::schedulePreviewDownload(int slotIndex)\n{\n    if (backendTaskRunning_.exchange(true))\n    {\n        pendingPreviewDownloadSlot_ = slotIndex;\n        return;\n    }\n\n    const auto baseUrl = state_.backendBaseUrl;\n    const auto remoteFileUrl = state_.resultFileUrls[static_cast<size_t>(slotIndex)];\n    backendThreadPool_.addJob(std::function<juce::ThreadPoolJob::JobStatus()>(\n        [this, baseUrl, remoteFileUrl, slotIndex]() {\n            BackendTaskResult taskResult;\n            taskResult.kind = BackendTaskKind::downloadPreview;\n            taskResult.previewDownload =\n                backendClient_.downloadPreviewFile(baseUrl, remoteFileUrl, slotIndex);\n            const juce::ScopedLock lock(backendTaskLock_);\n            completedBackendTask_ = std::move(taskResult);\n            backendTaskRunning_.store(false);\n            return juce::ThreadPoolJob::jobHasFinished;\n        }));\n}\n\nvoid ACEStepVST3AudioProcessor::applyCompletedTask(const BackendTaskResult& taskResult)\n{\n    switch (taskResult.kind)\n    {\n        case BackendTaskKind::healthCheck:\n            state_.backendStatus = taskResult.health.status;\n            if (taskResult.health.status == BackendStatus::ready\n                && state_.jobStatus != JobStatus::failed)\n            {\n                state_.errorMessage = {};\n            }\n            else if (taskResult.health.status != BackendStatus::ready\n                     && state_.jobStatus == JobStatus::idle)\n            {\n                state_.errorMessage = taskResult.health.errorMessage;\n            }\n            return;\n        case BackendTaskKind::submitGeneration:\n            if (!taskResult.generationStart.succeeded)\n            {\n                state_.jobStatus = JobStatus::failed;\n                state_.progressText = {};\n                state_.errorMessage = taskResult.generationStart.errorMessage;\n                state_.currentTaskId = {};\n                return;\n            }\n\n            state_.backendStatus = BackendStatus::ready;\n            state_.jobStatus = JobStatus::queuedOrRunning;\n            state_.currentTaskId = taskResult.generationStart.taskId;\n            state_.progressText = \"Task started: \" + state_.currentTaskId;\n            state_.errorMessage = {};\n            return;\n        case BackendTaskKind::pollGeneration:\n            state_.jobStatus = taskResult.generationPoll.status;\n            state_.progressText = taskResult.generationPoll.progressText;\n            if (taskResult.generationPoll.status == JobStatus::failed)\n            {\n                state_.errorMessage = taskResult.generationPoll.errorMessage;\n                state_.currentTaskId = {};\n                return;\n            }\n\n            if (taskResult.generationPoll.status != JobStatus::succeeded)\n            {\n                return;\n            }\n\n            state_.currentTaskId = {};\n            state_.errorMessage = {};\n            for (int index = 0; index < kResultSlotCount; ++index)\n            {\n                const auto& slot = taskResult.generationPoll.resultSlots[static_cast<size_t>(index)];\n                state_.resultSlots[static_cast<size_t>(index)] = slot.label;\n                state_.resultFileUrls[static_cast<size_t>(index)] = slot.remoteFileUrl;\n            }\n            state_.selectedResultSlot = 0;\n            if (state_.resultFileUrls[0].isNotEmpty())\n            {\n                pendingPreviewDownloadSlot_ = 0;\n            }\n            else\n            {\n                state_.errorMessage = \"Task finished but no audio file was returned.\";\n            }\n            return;\n        case BackendTaskKind::downloadPreview:\n            if (!taskResult.previewDownload.succeeded)\n            {\n                state_.errorMessage = taskResult.previewDownload.errorMessage;\n                return;\n            }\n\n            if (taskResult.previewDownload.slotIndex >= 0\n                && taskResult.previewDownload.slotIndex < kResultSlotCount)\n            {\n                const auto slotIndex = static_cast<size_t>(taskResult.previewDownload.slotIndex);\n                state_.resultLocalPaths[slotIndex] = taskResult.previewDownload.localFilePath;\n                if (state_.selectedResultSlot == taskResult.previewDownload.slotIndex)\n                {\n                    [[maybe_unused]] const auto loaded =\n                        loadPreviewFile(juce::File(taskResult.previewDownload.localFilePath));\n                }\n            }\n            return;\n        case BackendTaskKind::none:\n            return;\n    }\n}\n\nvoid ACEStepVST3AudioProcessor::clearGeneratedResults()\n{\n    state_.currentTaskId = {};\n    state_.progressText = {};\n    state_.selectedResultSlot = 0;\n    pendingPreviewDownloadSlot_.reset();\n    for (int index = 0; index < kResultSlotCount; ++index)\n    {\n        state_.resultSlots[static_cast<size_t>(index)] = {};\n        state_.resultFileUrls[static_cast<size_t>(index)] = {};\n        state_.resultLocalPaths[static_cast<size_t>(index)] = {};\n    }\n}\n\nvoid ACEStepVST3AudioProcessor::syncPreviewFromState()\n{\n    preview_.clear();\n    if (state_.previewFilePath.isEmpty())\n    {\n        return;\n    }\n\n    juce::String errorMessage;\n    const juce::File previewFile(state_.previewFilePath);\n    if (!preview_.loadFile(previewFile, errorMessage))\n    {\n        state_.errorMessage = errorMessage;\n        return;\n    }\n\n    state_.previewDisplayName = previewFile.getFileName();\n}\n}  // namespace acestep::vst3\n\njuce::AudioProcessor* JUCE_CALLTYPE createPluginFilter()\n{\n    return new acestep::vst3::ACEStepVST3AudioProcessor();\n}\n"
  },
  {
    "path": "plugins/acestep_vst3/src/PluginProcessor.h",
    "content": "#pragma once\n\n#include <atomic>\n#include <optional>\n\n#include <JuceHeader.h>\n\n#include \"PluginBackendClient.h\"\n#include \"PluginConfig.h\"\n#include \"PluginPreview.h\"\n#include \"PluginState.h\"\n\nnamespace acestep::vst3\n{\nclass ACEStepVST3AudioProcessor final : public juce::AudioProcessor\n{\npublic:\n    ACEStepVST3AudioProcessor();\n    ~ACEStepVST3AudioProcessor() override;\n\n    void prepareToPlay(double sampleRate, int samplesPerBlock) override;\n    void releaseResources() override;\n    bool isBusesLayoutSupported(const BusesLayout& layouts) const override;\n    void processBlock(juce::AudioBuffer<float>& buffer, juce::MidiBuffer& midiMessages) override;\n\n    juce::AudioProcessorEditor* createEditor() override;\n    bool hasEditor() const override;\n\n    const juce::String getName() const override;\n    bool acceptsMidi() const override;\n    bool producesMidi() const override;\n    bool isMidiEffect() const override;\n    bool isSynth() const;\n    double getTailLengthSeconds() const override;\n\n    int getNumPrograms() override;\n    int getCurrentProgram() override;\n    void setCurrentProgram(int index) override;\n    const juce::String getProgramName(int index) override;\n    void changeProgramName(int index, const juce::String& newName) override;\n    void getStateInformation(juce::MemoryBlock& destData) override;\n    void setStateInformation(const void* data, int sizeInBytes) override;\n\n    const PluginState& getState() const noexcept;\n    PluginState& getMutableState() noexcept;\n    [[nodiscard]] bool loadPreviewFile(const juce::File& file);\n    void clearPreviewFile();\n    void playPreview();\n    void stopPreview();\n    void revealPreviewFile() const;\n    [[nodiscard]] bool hasPreviewFile() const;\n    [[nodiscard]] bool isPreviewPlaying() const;\n    void requestGeneration();\n    void selectResultSlot(int index);\n    void pumpBackendWorkflow();\n\nprivate:\n    enum class BackendTaskKind\n    {\n        none,\n        healthCheck,\n        submitGeneration,\n        pollGeneration,\n        downloadPreview,\n    };\n\n    struct BackendTaskResult final\n    {\n        BackendTaskKind kind = BackendTaskKind::none;\n        PluginHealthCheckResult health;\n        PluginGenerationStartResult generationStart;\n        PluginGenerationPollResult generationPoll;\n        PluginPreviewDownloadResult previewDownload;\n    };\n\n    void scheduleHealthCheck();\n    void scheduleGenerationStart();\n    void scheduleGenerationPoll();\n    void schedulePreviewDownload(int slotIndex);\n    void applyCompletedTask(const BackendTaskResult& taskResult);\n    void clearGeneratedResults();\n    void syncPreviewFromState();\n\n    PluginState state_;\n    PluginPreview preview_;\n    PluginBackendClient backendClient_;\n    juce::ThreadPool backendThreadPool_ {1};\n    juce::CriticalSection backendTaskLock_;\n    std::optional<BackendTaskResult> completedBackendTask_;\n    std::atomic<bool> backendTaskRunning_ {false};\n    juce::uint32 lastHealthCheckAtMs_ = 0;\n    juce::uint32 lastPollRequestAtMs_ = 0;\n    juce::String lastHealthCheckedBaseUrl_;\n    std::optional<int> pendingPreviewDownloadSlot_;\n\n    JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(ACEStepVST3AudioProcessor)\n};\n}  // namespace acestep::vst3\n"
  },
  {
    "path": "plugins/acestep_vst3/src/PluginState.cpp",
    "content": "#include \"PluginState.h\"\n\nnamespace acestep::vst3\n{\nstd::unique_ptr<juce::XmlElement> createStateXml(const PluginState& state)\n{\n    auto xml = std::make_unique<juce::XmlElement>(kStateRootTag);\n    xml->setAttribute(\"schemaVersion\", state.schemaVersion);\n    xml->setAttribute(\"backendBaseUrl\", state.backendBaseUrl);\n    xml->setAttribute(\"prompt\", state.prompt);\n    xml->setAttribute(\"lyrics\", state.lyrics);\n    xml->setAttribute(\"durationSeconds\", state.durationSeconds);\n    xml->setAttribute(\"seed\", state.seed);\n    xml->setAttribute(\"modelPreset\", toString(state.modelPreset));\n    xml->setAttribute(\"qualityMode\", toString(state.qualityMode));\n    xml->setAttribute(\"backendStatus\", toString(state.backendStatus));\n    xml->setAttribute(\"jobStatus\", toString(state.jobStatus));\n    xml->setAttribute(\"currentTaskId\", state.currentTaskId);\n    xml->setAttribute(\"progressText\", state.progressText);\n    xml->setAttribute(\"errorMessage\", state.errorMessage);\n    xml->setAttribute(\"selectedResultSlot\", state.selectedResultSlot);\n    xml->setAttribute(\"previewFilePath\", state.previewFilePath);\n    xml->setAttribute(\"previewDisplayName\", state.previewDisplayName);\n    for (size_t index = 0; index < state.resultSlots.size(); ++index)\n    {\n        xml->setAttribute(\"resultSlot\" + juce::String(static_cast<int>(index)),\n                          state.resultSlots[index]);\n        xml->setAttribute(\"resultFileUrl\" + juce::String(static_cast<int>(index)),\n                          state.resultFileUrls[index]);\n        xml->setAttribute(\"resultLocalPath\" + juce::String(static_cast<int>(index)),\n                          state.resultLocalPaths[index]);\n    }\n    return xml;\n}\n\nstd::optional<PluginState> parseStateXml(const juce::XmlElement& xml)\n{\n    if (!xml.hasTagName(kStateRootTag))\n    {\n        return std::nullopt;\n    }\n\n    PluginState state;\n    state.schemaVersion = xml.getIntAttribute(\"schemaVersion\", kCurrentStateVersion);\n    state.backendBaseUrl = xml.getStringAttribute(\"backendBaseUrl\", kDefaultBackendBaseUrl).trim();\n    state.prompt = xml.getStringAttribute(\"prompt\");\n    state.lyrics = xml.getStringAttribute(\"lyrics\");\n    state.durationSeconds = xml.getIntAttribute(\"durationSeconds\", kDefaultDurationSeconds);\n    state.seed = xml.getIntAttribute(\"seed\", kDefaultSeed);\n    state.modelPreset = modelPresetFromString(xml.getStringAttribute(\"modelPreset\"));\n    state.qualityMode = qualityModeFromString(xml.getStringAttribute(\"qualityMode\"));\n    state.backendStatus = backendStatusFromString(xml.getStringAttribute(\"backendStatus\"));\n    state.jobStatus = jobStatusFromString(xml.getStringAttribute(\"jobStatus\"));\n    state.currentTaskId = xml.getStringAttribute(\"currentTaskId\");\n    state.progressText = xml.getStringAttribute(\"progressText\");\n    state.errorMessage = xml.getStringAttribute(\"errorMessage\");\n    state.selectedResultSlot =\n        juce::jlimit(0, kResultSlotCount - 1, xml.getIntAttribute(\"selectedResultSlot\", 0));\n    state.previewFilePath = xml.getStringAttribute(\"previewFilePath\");\n    state.previewDisplayName = xml.getStringAttribute(\"previewDisplayName\");\n    for (size_t index = 0; index < state.resultSlots.size(); ++index)\n    {\n        state.resultSlots[index] =\n            xml.getStringAttribute(\"resultSlot\" + juce::String(static_cast<int>(index)));\n        state.resultFileUrls[index] =\n            xml.getStringAttribute(\"resultFileUrl\" + juce::String(static_cast<int>(index)));\n        state.resultLocalPaths[index] =\n            xml.getStringAttribute(\"resultLocalPath\" + juce::String(static_cast<int>(index)));\n    }\n\n    if (state.backendBaseUrl.isEmpty())\n    {\n        state.backendBaseUrl = kDefaultBackendBaseUrl;\n    }\n\n    return state;\n}\n}  // namespace acestep::vst3\n"
  },
  {
    "path": "plugins/acestep_vst3/src/PluginState.h",
    "content": "#pragma once\n\n#include <array>\n#include <memory>\n#include <optional>\n\n#include <JuceHeader.h>\n\n#include \"PluginConfig.h\"\n#include \"PluginEnums.h\"\n\nnamespace acestep::vst3\n{\nstruct PluginState final\n{\n    int schemaVersion = kCurrentStateVersion;\n    juce::String backendBaseUrl = kDefaultBackendBaseUrl;\n    juce::String prompt;\n    juce::String lyrics;\n    int durationSeconds = kDefaultDurationSeconds;\n    int seed = kDefaultSeed;\n    ModelPreset modelPreset = ModelPreset::turbo;\n    QualityMode qualityMode = QualityMode::balanced;\n    BackendStatus backendStatus = BackendStatus::ready;\n    JobStatus jobStatus = JobStatus::idle;\n    juce::String currentTaskId;\n    juce::String progressText;\n    juce::String errorMessage;\n    int selectedResultSlot = 0;\n    std::array<juce::String, static_cast<size_t>(kResultSlotCount)> resultSlots;\n    std::array<juce::String, static_cast<size_t>(kResultSlotCount)> resultFileUrls;\n    std::array<juce::String, static_cast<size_t>(kResultSlotCount)> resultLocalPaths;\n    juce::String previewFilePath;\n    juce::String previewDisplayName;\n};\n\n[[nodiscard]] std::unique_ptr<juce::XmlElement> createStateXml(const PluginState& state);\n[[nodiscard]] std::optional<PluginState> parseStateXml(const juce::XmlElement& xml);\n}  // namespace acestep::vst3\n"
  },
  {
    "path": "profile_inference.py",
    "content": "#!/usr/bin/env python3\n\"\"\"\nACE-Step 1.5 Inference Profiler & Benchmark\n\nComprehensive profiling tool that supports all features, devices, and backends.\nUses the high-level inference API and built-in time_costs for accurate timing.\n\nModes:\n    profile         - Profile a single generation run with detailed timing breakdown\n    benchmark       - Run a matrix of configurations and produce a summary table\n    tier-test       - Auto-test across simulated GPU tiers (4/6/8/12/16/24/48 GB)\n    understand      - Profile the understand_music() API (audio codes -> metadata)\n    create_sample   - Profile the create_sample() API (inspiration/simple mode)\n    format_sample   - Profile the format_sample() API (caption+lyrics -> metadata)\n\nUsage:\n    # Profile text2music with default settings\n    python profile_inference.py\n\n    # Profile with thinking enabled on MPS\n    python profile_inference.py --device mps --thinking\n\n    # Benchmark across configurations\n    python profile_inference.py --mode benchmark\n\n    # Test all GPU tiers automatically (the key feature!)\n    python profile_inference.py --mode tier-test\n\n    # Test specific tiers only\n    python profile_inference.py --mode tier-test --tiers 6 8 16\n\n    # Test tiers with LM enabled (where supported)\n    python profile_inference.py --mode tier-test --tier-with-lm\n\n    # Profile create_sample (inspiration mode)\n    python profile_inference.py --mode create_sample --sample-query \"a soft Bengali love song\"\n\n    # Profile understand mode\n    python profile_inference.py --mode understand\n\n    # Full profiling with cProfile\n    python profile_inference.py --detailed --llm-debug\n\"\"\"\n\nimport time\nimport argparse\nimport sys\nimport os\nimport json\nimport tempfile\nimport traceback\nfrom contextlib import contextmanager\nfrom collections import defaultdict\nfrom typing import Tuple, Dict, Any, List, Optional\n\n# Add project root to path\nPROJECT_ROOT = os.path.abspath(os.path.dirname(__file__))\nif PROJECT_ROOT not in sys.path:\n    sys.path.insert(0, PROJECT_ROOT)\n\nimport torch\n\nfrom acestep.inference import (\n    generate_music,\n    understand_music,\n    create_sample,\n    format_sample,\n    GenerationParams,\n    GenerationConfig,\n    GenerationResult,\n)\nfrom acestep.handler import AceStepHandler\nfrom acestep.llm_inference import LLMHandler\nfrom acestep.gpu_config import (\n    get_gpu_config,\n    set_global_gpu_config,\n    get_gpu_tier,\n    find_best_lm_model_on_disk,\n    is_lm_model_size_allowed,\n    GPUConfig,\n    VRAM_AUTO_OFFLOAD_THRESHOLD_GB,\n)\n\n\n# =============================================================================\n# Device / Backend helpers\n# =============================================================================\n\n\ndef resolve_device(device: str) -> str:\n    \"\"\"Resolve 'auto' device to the best available device.\"\"\"\n    if device == \"auto\":\n        if hasattr(torch, \"xpu\") and torch.xpu.is_available():\n            return \"xpu\"\n        if torch.cuda.is_available():\n            return \"cuda\"\n        if hasattr(torch.backends, \"mps\") and torch.backends.mps.is_available():\n            return \"mps\"\n        return \"cpu\"\n    return device\n\n\ndef auto_detect_backend(device: str) -> str:\n    \"\"\"Auto-detect the best LLM backend for the resolved device.\"\"\"\n    if device == \"mps\":\n        try:\n            import mlx.core  # noqa: F401\n            return \"mlx\"\n        except ImportError:\n            return \"pt\"\n    if device.startswith(\"cuda\"):\n        return \"vllm\"\n    return \"pt\"\n\n\ndef load_env_config() -> Dict[str, str]:\n    \"\"\"Load configuration defaults from .env file.\"\"\"\n    env_config = {\n        \"ACESTEP_CONFIG_PATH\": \"acestep-v15-turbo\",\n        \"ACESTEP_LM_MODEL_PATH\": \"acestep-5Hz-lm-0.6B\",\n        \"ACESTEP_DEVICE\": \"auto\",\n        \"ACESTEP_LM_BACKEND\": \"auto\",\n    }\n    env_file = os.path.join(PROJECT_ROOT, \".env\")\n    if os.path.exists(env_file):\n        with open(env_file, \"r\", encoding=\"utf-8\") as f:\n            for line in f:\n                line = line.strip()\n                if not line or line.startswith(\"#\"):\n                    continue\n                if \"=\" in line:\n                    key, value = line.split(\"=\", 1)\n                    key = key.strip()\n                    value = value.strip()\n                    if key in env_config and value:\n                        env_config[key] = value\n    return env_config\n\n\n# =============================================================================\n# Timer utilities\n# =============================================================================\n\n\nclass PreciseTimer:\n    \"\"\"High-precision timer with GPU synchronization for accurate timing.\"\"\"\n\n    def __init__(self, device: str = \"cpu\"):\n        self.device = device\n        self.timings: Dict[str, List[float]] = defaultdict(list)\n        self.enabled = True\n\n    def sync(self):\n        \"\"\"Synchronize GPU operations for accurate timing.\"\"\"\n        if not self.enabled:\n            return\n        if self.device.startswith(\"cuda\") and torch.cuda.is_available():\n            torch.cuda.synchronize()\n        elif self.device == \"mps\" and hasattr(torch.backends, \"mps\") and torch.backends.mps.is_available():\n            if hasattr(torch, \"mps\"):\n                torch.mps.synchronize()\n        elif self.device.startswith(\"xpu\") and hasattr(torch, \"xpu\"):\n            torch.xpu.synchronize()\n\n    @contextmanager\n    def time(self, name: str):\n        \"\"\"Time a code section with GPU synchronization.\"\"\"\n        if not self.enabled:\n            yield\n            return\n        self.sync()\n        start = time.perf_counter()\n        try:\n            yield\n        finally:\n            self.sync()\n            elapsed = time.perf_counter() - start\n            self.timings[name].append(elapsed)\n\n    def get_total(self, name: str) -> float:\n        return sum(self.timings.get(name, []))\n\n    def get_mean(self, name: str) -> float:\n        times = self.timings.get(name, [])\n        return sum(times) / len(times) if times else 0.0\n\n    def get_count(self, name: str) -> int:\n        return len(self.timings.get(name, []))\n\n    def reset(self):\n        self.timings.clear()\n\n\n# =============================================================================\n# Example config loader\n# =============================================================================\n\n\ndef load_example_config(\n    example_file: str, cli_overrides: argparse.Namespace\n) -> Tuple[Optional[GenerationParams], Optional[GenerationConfig]]:\n    \"\"\"Load configuration from example JSON file, applying CLI overrides.\"\"\"\n    try:\n        with open(example_file, \"r\", encoding=\"utf-8\") as f:\n            data = json.load(f)\n\n        params = GenerationParams(\n            caption=data.get(\"caption\", \"\"),\n            lyrics=data.get(\"lyrics\", \"\"),\n            bpm=data.get(\"bpm\"),\n            keyscale=data.get(\"keyscale\", \"\"),\n            timesignature=data.get(\"timesignature\", \"\"),\n            vocal_language=data.get(\"language\", \"unknown\"),\n            duration=(\n                cli_overrides.duration\n                if cli_overrides.duration is not None\n                else data.get(\"duration\", -1.0)\n            ),\n            thinking=cli_overrides.thinking,\n            use_cot_metas=cli_overrides.use_cot_metas,\n            use_cot_caption=cli_overrides.use_cot_caption,\n            use_cot_language=cli_overrides.use_cot_language,\n            use_constrained_decoding=cli_overrides.use_constrained_decoding,\n            inference_steps=(\n                cli_overrides.inference_steps\n                if cli_overrides.inference_steps is not None\n                else data.get(\"inference_steps\", 8)\n            ),\n            seed=(\n                cli_overrides.seed\n                if cli_overrides.seed is not None\n                else data.get(\"seed\", 42)\n            ),\n            task_type=cli_overrides.task_type,\n            lm_temperature=cli_overrides.lm_temperature,\n            lm_cfg_scale=cli_overrides.lm_cfg_scale,\n            guidance_scale=cli_overrides.guidance_scale,\n            reference_audio=cli_overrides.reference_audio,\n            src_audio=cli_overrides.src_audio,\n        )\n\n        config = GenerationConfig(\n            batch_size=(\n                cli_overrides.batch_size\n                if cli_overrides.batch_size is not None\n                else data.get(\"batch_size\", 1)\n            ),\n            seeds=[params.seed] if params.seed >= 0 else None,\n            use_random_seed=(params.seed < 0),\n            audio_format=\"flac\",\n        )\n\n        return params, config\n\n    except Exception as e:\n        print(f\"  Failed to load example: {e}\")\n        return None, None\n\n\n# =============================================================================\n# Printing helpers\n# =============================================================================\n\n\ndef print_time_costs_breakdown(\n    time_costs: Dict[str, float], total_wall_time: float\n):\n    \"\"\"Print a detailed timing breakdown from result.extra_outputs['time_costs'].\"\"\"\n    print(\"\\n\" + \"=\" * 100)\n    print(\"PROFILING RESULTS\")\n    print(\"=\" * 100)\n\n    if not time_costs:\n        print(\"\\n  (No time_costs data available from the pipeline)\")\n        print(f\"\\n  Total wall time: {total_wall_time:.3f}s\")\n        return\n\n    # Categorize keys\n    lm_keys = {\n        k: v\n        for k, v in time_costs.items()\n        if k.startswith(\"lm_\") and isinstance(v, (int, float))\n    }\n    dit_keys = {\n        k: v\n        for k, v in time_costs.items()\n        if k.startswith(\"dit_\") and isinstance(v, (int, float))\n    }\n    pipeline_keys = {\n        k: v\n        for k, v in time_costs.items()\n        if k.startswith(\"pipeline_\") and isinstance(v, (int, float))\n    }\n    other_keys = {\n        k: v\n        for k, v in time_costs.items()\n        if not k.startswith((\"lm_\", \"dit_\", \"pipeline_\"))\n        and isinstance(v, (int, float))\n    }\n\n    print(f\"\\n{'COMPONENT':<50} {'TIME (s)':<12} {'% of wall':<10}\")\n    print(\"-\" * 72)\n\n    # LM timing\n    lm_total = lm_keys.get(\"lm_total_time\", 0.0)\n    if lm_keys:\n        print(\n            f\"\\n{'LLM (5Hz Language Model)':<50} \"\n            f\"{lm_total:<12.3f} {100 * lm_total / total_wall_time:>6.1f}%\"\n        )\n        for k, v in sorted(lm_keys.items()):\n            if k != \"lm_total_time\":\n                label = k.replace(\"lm_\", \"  \")\n                print(\n                    f\"  {label:<48} \"\n                    f\"{v:<12.3f} {100 * v / total_wall_time:>6.1f}%\"\n                )\n\n    # DiT timing\n    dit_total = dit_keys.get(\"dit_total_time_cost\", 0.0)\n    if dit_keys:\n        print(\n            f\"\\n{'DiT (Diffusion Transformer)':<50} \"\n            f\"{dit_total:<12.3f} {100 * dit_total / total_wall_time:>6.1f}%\"\n        )\n        for k, v in sorted(dit_keys.items()):\n            if k != \"dit_total_time_cost\":\n                label = k.replace(\"dit_\", \"  \")\n                print(\n                    f\"  {label:<48} \"\n                    f\"{v:<12.3f} {100 * v / total_wall_time:>6.1f}%\"\n                )\n\n    # Pipeline total\n    if pipeline_keys:\n        for k, v in sorted(pipeline_keys.items()):\n            print(\n                f\"\\n{'Pipeline: ' + k:<50} \"\n                f\"{v:<12.3f} {100 * v / total_wall_time:>6.1f}%\"\n            )\n\n    # Other keys\n    if other_keys:\n        print(f\"\\n{'Other:':<50}\")\n        for k, v in sorted(other_keys.items()):\n            print(\n                f\"  {k:<48} \"\n                f\"{v:<12.3f} {100 * v / total_wall_time:>6.1f}%\"\n            )\n\n    # Overhead (wall time minus accounted time)\n    accounted = lm_total + dit_total\n    overhead = total_wall_time - accounted\n    if overhead > 0.01:\n        print(\n            f\"\\n{'Overhead (I/O, audio save, etc.)':<50} \"\n            f\"{overhead:<12.3f} {100 * overhead / total_wall_time:>6.1f}%\"\n        )\n\n    print(f\"\\n{'TOTAL WALL TIME':<50} {total_wall_time:<12.3f} {'100.0%':>6}\")\n\n    # Performance insights\n    print(\"\\n\" + \"=\" * 100)\n    print(\"PERFORMANCE INSIGHTS\")\n    print(\"=\" * 100)\n\n    if lm_total > 0 and dit_total > 0:\n        if lm_total > dit_total * 2:\n            print(\n                f\"\\n  LLM is the bottleneck: {lm_total:.1f}s \"\n                f\"({100 * lm_total / total_wall_time:.0f}% of total)\"\n            )\n            print(\"  Suggestions:\")\n            print(\"    1. Run with --llm-debug for token-level throughput analysis\")\n            print(\"    2. Try --no-constrained-decoding to reduce FSM overhead\")\n            print(\"    3. Compare backends: --lm-backend vllm vs pt vs mlx\")\n            print(\n                \"    4. Reduce lm_cfg_scale \"\n                \"(currently doubles forward passes if > 1.0)\"\n            )\n        elif dit_total > lm_total * 2:\n            print(\n                f\"\\n  DiT is the bottleneck: {dit_total:.1f}s \"\n                f\"({100 * dit_total / total_wall_time:.0f}% of total)\"\n            )\n            print(\"  Suggestions:\")\n            print(\"    1. Reduce --inference-steps (turbo model supports 4-8)\")\n            print(\"    2. Reduce --duration\")\n            print(\"    3. Try --quantization int8_weight_only\")\n        else:\n            print(\n                f\"\\n  Balanced pipeline: LLM={lm_total:.1f}s, DiT={dit_total:.1f}s\"\n            )\n    elif dit_total > 0:\n        print(f\"\\n  DiT only (no LLM): {dit_total:.1f}s\")\n        vae_time = dit_keys.get(\"dit_vae_decode_time_cost\", 0.0)\n        diffusion_time = dit_keys.get(\n            \"dit_diffusion_time_cost\", dit_total - vae_time\n        )\n        if vae_time > 0:\n            print(\n                f\"    Diffusion: {diffusion_time:.1f}s, \"\n                f\"VAE decode: {vae_time:.1f}s\"\n            )\n\n\ndef print_result_summary(result: GenerationResult, mode: str = \"profile\"):\n    \"\"\"Print a short summary of the generation result.\"\"\"\n    if result.success:\n        n_audios = len(result.audios)\n        silent_count = sum(1 for a in result.audios if a.get(\"silent\", False))\n        print(f\"\\n  Success! Generated {n_audios} audio(s)\", end=\"\")\n        if silent_count:\n            print(f\" ({silent_count} silent)\", end=\"\")\n        print()\n    else:\n        print(f\"\\n  FAILED: {result.error}\")\n\n\n# =============================================================================\n# Mode: profile (text2music and other task types)\n# =============================================================================\n\n\ndef run_profile_mode(dit_handler, llm_handler, args, timer: PreciseTimer):\n    \"\"\"Run a single profiled generation.\"\"\"\n    example_dir = \"text2music\"\n    example_file = os.path.join(\n        PROJECT_ROOT, \"examples\", example_dir, args.example\n    )\n    if not os.path.exists(example_file):\n        print(f\"\\n  Example not found: {example_file}\")\n        sys.exit(1)\n\n    print(f\"\\n  Loading example: {args.example}\")\n    params, config = load_example_config(example_file, args)\n    if not params or not config:\n        print(\"  Failed to load example config\")\n        sys.exit(1)\n\n    caption_preview = (\n        params.caption[:80] + \"...\"\n        if len(params.caption) > 80\n        else params.caption\n    )\n    print(f\"  Caption: {caption_preview}\")\n    print(\n        f\"  Task: {params.task_type}, Batch: {config.batch_size}, \"\n        f\"Steps: {params.inference_steps}\"\n    )\n    print(\n        f\"  Thinking: {params.thinking}, CoT Metas: {params.use_cot_metas}, \"\n        f\"CoT Caption: {params.use_cot_caption}\"\n    )\n\n    # Use a temporary directory for output (don't pollute project root)\n    save_dir = tempfile.mkdtemp(prefix=\"acestep_profile_\")\n\n    # Warmup\n    if not args.no_warmup:\n        print(\"\\n\" + \"-\" * 100)\n        print(\"WARMUP RUN\")\n        print(\"-\" * 100)\n        warmup_params = GenerationParams(\n            caption=params.caption,\n            lyrics=params.lyrics,\n            bpm=params.bpm,\n            keyscale=params.keyscale,\n            timesignature=params.timesignature,\n            vocal_language=params.vocal_language,\n            duration=params.duration,\n            thinking=params.thinking,\n            use_cot_metas=params.use_cot_metas,\n            use_cot_caption=params.use_cot_caption,\n            use_cot_language=params.use_cot_language,\n            use_constrained_decoding=params.use_constrained_decoding,\n            inference_steps=params.inference_steps,\n            seed=42,\n            task_type=params.task_type,\n            lm_temperature=params.lm_temperature,\n            lm_cfg_scale=params.lm_cfg_scale,\n            guidance_scale=params.guidance_scale,\n        )\n        warmup_config = GenerationConfig(\n            batch_size=1, seeds=[42], use_random_seed=False, audio_format=\"flac\"\n        )\n        warmup_start = time.perf_counter()\n        warmup_result = generate_music(\n            dit_handler, llm_handler, warmup_params, warmup_config,\n            save_dir=save_dir,\n        )\n        warmup_time = time.perf_counter() - warmup_start\n        print(f\"  Warmup completed: {warmup_time:.2f}s\")\n        if not warmup_result.success:\n            print(f\"  Warning: warmup failed: {warmup_result.error}\")\n        timer.reset()\n\n    # Profiling run\n    print(\"\\n\" + \"=\" * 100)\n    print(\"PROFILING RUN\")\n    print(\"=\" * 100)\n\n    # Optional cProfile\n    prof = None\n    if args.detailed:\n        import cProfile\n        prof = cProfile.Profile()\n        prof.enable()\n\n    timer.sync()\n    total_start = time.perf_counter()\n\n    result = generate_music(\n        dit_handler, llm_handler, params, config, save_dir=save_dir\n    )\n\n    timer.sync()\n    total_wall_time = time.perf_counter() - total_start\n\n    if args.detailed and prof:\n        prof.disable()\n        _print_cprofile(prof)\n\n    # Print results\n    print_result_summary(result, \"profile\")\n\n    time_costs = (\n        result.extra_outputs.get(\"time_costs\", {}) if result.success else {}\n    )\n    print_time_costs_breakdown(time_costs, total_wall_time)\n\n    # Cleanup temp dir\n    _cleanup_dir(save_dir)\n\n    return result, total_wall_time\n\n\n# =============================================================================\n# Mode: benchmark\n# =============================================================================\n\n\ndef run_benchmark_mode(dit_handler, llm_handler, args, timer: PreciseTimer):\n    \"\"\"Run a matrix of configurations and produce a summary table.\"\"\"\n    example_file = os.path.join(\n        PROJECT_ROOT, \"examples\", \"text2music\", args.example\n    )\n    if not os.path.exists(example_file):\n        print(f\"\\n  Example not found: {example_file}\")\n        sys.exit(1)\n\n    with open(example_file, \"r\", encoding=\"utf-8\") as f:\n        example_data = json.load(f)\n\n    save_dir = tempfile.mkdtemp(prefix=\"acestep_bench_\")\n\n    # Define benchmark matrix\n    durations = [30, 60, 120]\n    batch_sizes = [1, 2]\n    thinking_options = (\n        [False, True] if llm_handler.llm_initialized else [False]\n    )\n    inference_steps_options = [8]\n\n    # Clamp to GPU limits\n    gpu_config = get_gpu_config()\n    max_dur = gpu_config.max_duration_without_lm\n    max_batch = gpu_config.max_batch_size_without_lm\n    durations = [d for d in durations if d <= max_dur]\n    batch_sizes = [b for b in batch_sizes if b <= max_batch]\n\n    if not durations:\n        durations = [30]\n    if not batch_sizes:\n        batch_sizes = [1]\n\n    configs = []\n    for dur in durations:\n        for bs in batch_sizes:\n            for think in thinking_options:\n                for steps in inference_steps_options:\n                    configs.append(\n                        {\n                            \"duration\": dur,\n                            \"batch_size\": bs,\n                            \"thinking\": think,\n                            \"inference_steps\": steps,\n                        }\n                    )\n\n    print(f\"\\n  Running {len(configs)} benchmark configurations...\")\n    print(f\"  Durations: {durations}, Batch sizes: {batch_sizes}\")\n    print(f\"  Thinking: {thinking_options}, Steps: {inference_steps_options}\")\n\n    # Warmup\n    if not args.no_warmup:\n        print(\"\\n  Warmup run...\")\n        warmup_params = GenerationParams(\n            caption=example_data.get(\"caption\", \"\"),\n            lyrics=example_data.get(\"lyrics\", \"\"),\n            duration=30,\n            thinking=False,\n            inference_steps=8,\n            seed=42,\n        )\n        warmup_config = GenerationConfig(\n            batch_size=1, seeds=[42], use_random_seed=False, audio_format=\"flac\"\n        )\n        generate_music(\n            dit_handler, llm_handler, warmup_params, warmup_config,\n            save_dir=save_dir,\n        )\n        print(\"  Warmup done.\")\n\n    # Run benchmark\n    results = []\n    for i, cfg in enumerate(configs):\n        label = (\n            f\"dur={cfg['duration']}s, bs={cfg['batch_size']}, \"\n            f\"think={cfg['thinking']}, steps={cfg['inference_steps']}\"\n        )\n        print(f\"\\n  [{i + 1}/{len(configs)}] {label}\")\n\n        params = GenerationParams(\n            caption=example_data.get(\"caption\", \"\"),\n            lyrics=example_data.get(\"lyrics\", \"\"),\n            bpm=example_data.get(\"bpm\"),\n            keyscale=example_data.get(\"keyscale\", \"\"),\n            timesignature=example_data.get(\"timesignature\", \"\"),\n            vocal_language=example_data.get(\"language\", \"unknown\"),\n            duration=cfg[\"duration\"],\n            thinking=cfg[\"thinking\"],\n            use_cot_metas=cfg[\"thinking\"],\n            use_cot_caption=cfg[\"thinking\"],\n            use_cot_language=cfg[\"thinking\"],\n            use_constrained_decoding=args.use_constrained_decoding,\n            inference_steps=cfg[\"inference_steps\"],\n            seed=42,\n            lm_temperature=args.lm_temperature,\n            lm_cfg_scale=args.lm_cfg_scale,\n            guidance_scale=args.guidance_scale,\n        )\n        config = GenerationConfig(\n            batch_size=cfg[\"batch_size\"],\n            seeds=[42 + j for j in range(cfg[\"batch_size\"])],\n            use_random_seed=False,\n            audio_format=\"flac\",\n        )\n\n        timer.sync()\n        t0 = time.perf_counter()\n        result = generate_music(\n            dit_handler, llm_handler, params, config, save_dir=save_dir\n        )\n        timer.sync()\n        wall_time = time.perf_counter() - t0\n\n        tc = (\n            result.extra_outputs.get(\"time_costs\", {})\n            if result.success\n            else {}\n        )\n        entry = {\n            \"config\": cfg,\n            \"wall_time\": wall_time,\n            \"success\": result.success,\n            \"error\": result.error,\n            \"lm_time\": tc.get(\"lm_total_time\", 0.0),\n            \"dit_time\": tc.get(\"dit_total_time_cost\", 0.0),\n            \"vae_time\": tc.get(\"dit_vae_decode_time_cost\", 0.0),\n            \"n_audios\": len(result.audios) if result.success else 0,\n        }\n        results.append(entry)\n\n        status = \"OK\" if result.success else f\"FAIL: {result.error}\"\n        print(\n            f\"    {status} | wall={wall_time:.1f}s, \"\n            f\"lm={entry['lm_time']:.1f}s, dit={entry['dit_time']:.1f}s\"\n        )\n\n    # Print summary table\n    print(\"\\n\" + \"=\" * 120)\n    print(\"BENCHMARK SUMMARY\")\n    print(\"=\" * 120)\n\n    header = (\n        f\"{'Duration':<10} {'Batch':<7} {'Think':<7} {'Steps':<7} \"\n        f\"{'Wall(s)':<10} {'LM(s)':<10} {'DiT(s)':<10} \"\n        f\"{'VAE(s)':<10} {'Status':<10}\"\n    )\n    print(header)\n    print(\"-\" * 120)\n\n    for entry in results:\n        cfg = entry[\"config\"]\n        status = \"OK\" if entry[\"success\"] else \"FAIL\"\n        print(\n            f\"{cfg['duration']:<10} {cfg['batch_size']:<7} \"\n            f\"{str(cfg['thinking']):<7} {cfg['inference_steps']:<7} \"\n            f\"{entry['wall_time']:<10.2f} {entry['lm_time']:<10.2f} \"\n            f\"{entry['dit_time']:<10.2f} {entry['vae_time']:<10.2f} \"\n            f\"{status:<10}\"\n        )\n\n    # Save benchmark results as JSON\n    if args.benchmark_output:\n        output_path = args.benchmark_output\n        with open(output_path, \"w\", encoding=\"utf-8\") as f:\n            json.dump(results, f, indent=2, default=str)\n        print(f\"\\n  Benchmark results saved to: {output_path}\")\n\n    _cleanup_dir(save_dir)\n    return results\n\n\n# =============================================================================\n# Mode: tier-test  (THE KEY FEATURE)\n# =============================================================================\n\n\ndef _get_vram_info_str() -> str:\n    \"\"\"Get current VRAM usage string for logging.\"\"\"\n    if not torch.cuda.is_available():\n        return \"N/A\"\n    allocated = torch.cuda.memory_allocated() / (1024 ** 3)\n    reserved = torch.cuda.memory_reserved() / (1024 ** 3)\n    return f\"alloc={allocated:.2f}GB, reserved={reserved:.2f}GB\"\n\n\ndef _run_single_tier_test(\n    sim_gb: float,\n    gpu_config: GPUConfig,\n    args,\n    example_data: Dict,\n    checkpoint_dir: str,\n    disk_lm_models: List[str],\n    *,\n    offload_override: Optional[bool] = None,\n    offload_dit_override: Optional[bool] = None,\n    quantization_override: Optional[str] = \"USE_DEFAULT\",\n    test_variant: str = \"default\",\n    batch_size_override: Optional[int] = None,\n    use_lm_override: Optional[bool] = None,\n) -> Dict[str, Any]:\n    \"\"\"\n    Run a single tier test with the given configuration.\n\n    Args:\n        sim_gb: Simulated VRAM in GB\n        gpu_config: GPU configuration for this tier\n        args: CLI arguments\n        example_data: Example JSON data for generation\n        checkpoint_dir: Path to checkpoints directory\n        disk_lm_models: List of LM models found on disk\n        offload_override: If not None, override offload_to_cpu setting\n        offload_dit_override: If not None, override offload_dit_to_cpu setting\n        quantization_override: If not \"USE_DEFAULT\", override quantization setting\n                               (None means no quantization, \"int8_weight_only\" etc.)\n        test_variant: Label for this test variant (\"default\", \"no-quant\", \"no-offload\")\n        batch_size_override: If not None, override batch size (used by batch boundary tests)\n        use_lm_override: If not None, force LM on (True) or off (False)\n\n    Returns:\n        Result dictionary for this test\n    \"\"\"\n    tier = gpu_config.tier\n\n    # Determine test configuration\n    if use_lm_override is not None:\n        use_lm = use_lm_override and gpu_config.init_lm_default and bool(gpu_config.available_lm_models)\n    else:\n        use_lm = args.tier_with_lm and gpu_config.init_lm_default and bool(gpu_config.available_lm_models)\n\n    if hasattr(torch, \"xpu\") and torch.xpu.is_available():\n        offload_override = False\n\n    if offload_override is not None:\n        offload = offload_override\n    else:\n        offload = gpu_config.offload_to_cpu_default\n\n    if offload_dit_override is not None:\n        offload_dit = offload_dit_override\n    else:\n        offload_dit = gpu_config.offload_dit_to_cpu_default\n\n    if quantization_override != \"USE_DEFAULT\":\n        quantization = quantization_override\n    else:\n        quantization = \"int8_weight_only\" if gpu_config.quantization_default else None\n\n    # Find LM model on disk\n    lm_model = None\n    lm_backend = gpu_config.recommended_backend\n    if use_lm:\n        lm_model = find_best_lm_model_on_disk(\n            gpu_config.recommended_lm_model, disk_lm_models\n        )\n        if not lm_model:\n            print(f\"  ⚠️ No compatible LM model on disk for tier {tier}, skipping LM\")\n            use_lm = False\n\n    # Clamp duration to tier limit\n    test_duration = args.tier_duration\n    max_dur = gpu_config.max_duration_with_lm if use_lm else gpu_config.max_duration_without_lm\n    if test_duration > max_dur:\n        test_duration = max_dur\n        print(f\"  Duration clamped to {test_duration}s (tier limit)\")\n\n    batch_size = batch_size_override if batch_size_override is not None else 1\n\n    print(f\"\\n  Test config [{test_variant}]: duration={test_duration}s, batch={batch_size}, LM={use_lm}\")\n    if use_lm:\n        print(f\"    LM model: {lm_model}, backend: {lm_backend}\")\n    print(f\"    offload={offload}, offload_dit={offload_dit}, quant={quantization}\")\n\n    # Enforce VRAM cap\n    if torch.cuda.is_available():\n        total_bytes = torch.cuda.get_device_properties(0).total_memory\n        total_gb = total_bytes / (1024 ** 3)\n        if sim_gb < total_gb:\n            reference_context_gb = 0.5\n            allocator_budget_gb = max(0.5, sim_gb - reference_context_gb)\n            fraction = max(0.01, min(1.0, allocator_budget_gb / total_gb))\n            torch.cuda.set_per_process_memory_fraction(fraction)\n\n        torch.cuda.empty_cache()\n        torch.cuda.reset_peak_memory_stats()\n\n    # Initialize result entry\n    result_entry = {\n        \"tier_gb\": sim_gb,\n        \"tier\": tier,\n        \"test_variant\": test_variant,\n        \"use_lm\": use_lm,\n        \"lm_model\": lm_model,\n        \"lm_backend\": lm_backend,\n        \"offload\": offload,\n        \"offload_dit\": offload_dit,\n        \"quantization\": quantization,\n        \"duration\": test_duration,\n        \"batch_size\": batch_size,\n        \"init_success\": False,\n        \"gen_success\": False,\n        \"wall_time\": 0.0,\n        \"error\": None,\n        \"peak_vram_gb\": 0.0,\n    }\n\n    dit_handler = None\n    llm_handler = None\n\n    try:\n        print(f\"\\n  Initializing DiT handler... ({_get_vram_info_str()})\")\n        dit_handler = AceStepHandler()\n\n        # Determine flash attention availability\n        use_flash_attention = False\n        try:\n            import flash_attn  # noqa: F401\n            use_flash_attention = True\n        except ImportError:\n            pass\n\n        # compile_model must be True when quantization is used;\n        # --tier-skip-compile can skip it for non-quantized tiers to save time\n        if quantization:\n            compile_model = True\n        elif args.tier_skip_compile:\n            compile_model = False\n        else:\n            compile_model = gpu_config.compile_model_default\n\n        status_dit, success_dit = dit_handler.initialize_service(\n            project_root=PROJECT_ROOT,\n            config_path=args.config_path,\n            device=\"auto\",\n            use_flash_attention=use_flash_attention,\n            compile_model=compile_model,\n            offload_to_cpu=offload,\n            offload_dit_to_cpu=offload_dit,\n            quantization=quantization,\n        )\n\n        if not success_dit:\n            result_entry[\"error\"] = f\"DiT init failed: {status_dit}\"\n            print(f\"  ❌ DiT init failed: {status_dit}\")\n            _cleanup_handlers(dit_handler, None)\n            return result_entry\n\n        print(f\"  ✅ DiT ready ({_get_vram_info_str()})\")\n\n        llm_handler = LLMHandler()\n\n        if use_lm:\n            print(f\"  Initializing LLM handler (backend={lm_backend})... ({_get_vram_info_str()})\")\n            status_llm, success_llm = llm_handler.initialize(\n                checkpoint_dir=checkpoint_dir,\n                lm_model_path=lm_model,\n                backend=lm_backend,\n                device=\"auto\",\n                offload_to_cpu=offload,\n                dtype=None,\n            )\n            if success_llm:\n                print(f\"  ✅ LLM ready ({_get_vram_info_str()})\")\n            else:\n                print(f\"  ⚠️ LLM init failed: {status_llm}\")\n                use_lm = False\n                result_entry[\"use_lm\"] = False\n                result_entry[\"error\"] = f\"LM init failed (non-fatal): {status_llm}\"\n\n        result_entry[\"init_success\"] = True\n\n    except torch.cuda.OutOfMemoryError as e:\n        result_entry[\"error\"] = f\"Init OOM: {e}\"\n        print(f\"  ❌ Init OOM: {e}\")\n        _cleanup_handlers(dit_handler, llm_handler)\n        return result_entry\n    except Exception as e:\n        result_entry[\"error\"] = f\"Init exception: {e}\"\n        print(f\"  ❌ Init exception: {e}\")\n        traceback.print_exc()\n        _cleanup_handlers(dit_handler, llm_handler)\n        return result_entry\n\n    # Run generation\n    try:\n        print(f\"\\n  Running generation... ({_get_vram_info_str()})\")\n        save_dir = tempfile.mkdtemp(prefix=f\"acestep_tier{int(sim_gb)}_{test_variant}_\")\n\n        params = GenerationParams(\n            caption=example_data.get(\"caption\", \"\"),\n            lyrics=example_data.get(\"lyrics\", \"\"),\n            bpm=example_data.get(\"bpm\"),\n            keyscale=example_data.get(\"keyscale\", \"\"),\n            timesignature=example_data.get(\"timesignature\", \"\"),\n            vocal_language=example_data.get(\"language\", \"unknown\"),\n            duration=test_duration,\n            thinking=use_lm,\n            use_cot_metas=use_lm,\n            use_cot_caption=False,\n            use_cot_language=False,\n            use_constrained_decoding=True,\n            inference_steps=8,\n            seed=42,\n            lm_temperature=0.85,\n            lm_cfg_scale=2.0,\n            guidance_scale=7.0,\n        )\n        config = GenerationConfig(\n            batch_size=batch_size,\n            seeds=[42 + j for j in range(batch_size)],\n            use_random_seed=False,\n            audio_format=\"flac\",\n        )\n\n        # When testing batch boundaries, temporarily override the GPU tier config's\n        # max_batch limits so that inference.py's clamping doesn't reduce our test\n        # batch size. We restore the original values after the test.\n        _patched_tier_config = False\n        _orig_batch_with_lm = None\n        _orig_batch_without_lm = None\n        if batch_size_override is not None and batch_size_override > 1:\n            from acestep.gpu_config import GPU_TIER_CONFIGS as _tier_configs\n            tier = gpu_config.tier\n            if tier in _tier_configs:\n                _patched_tier_config = True\n                _orig_batch_with_lm = _tier_configs[tier][\"max_batch_size_with_lm\"]\n                _orig_batch_without_lm = _tier_configs[tier][\"max_batch_size_without_lm\"]\n                _tier_configs[tier][\"max_batch_size_with_lm\"] = max(batch_size_override, _orig_batch_with_lm)\n                _tier_configs[tier][\"max_batch_size_without_lm\"] = max(batch_size_override, _orig_batch_without_lm)\n\n        t0 = time.perf_counter()\n        try:\n            result = generate_music(\n                dit_handler, llm_handler, params, config, save_dir=save_dir\n            )\n        finally:\n            # Restore original tier config values\n            if _patched_tier_config:\n                _tier_configs[tier][\"max_batch_size_with_lm\"] = _orig_batch_with_lm\n                _tier_configs[tier][\"max_batch_size_without_lm\"] = _orig_batch_without_lm\n        wall_time = time.perf_counter() - t0\n\n        result_entry[\"wall_time\"] = wall_time\n        result_entry[\"gen_success\"] = result.success\n\n        if result.success:\n            tc = result.extra_outputs.get(\"time_costs\", {})\n            result_entry[\"lm_time\"] = tc.get(\"lm_total_time\", 0.0)\n            result_entry[\"dit_time\"] = tc.get(\"dit_total_time_cost\", 0.0)\n            result_entry[\"vae_time\"] = tc.get(\"dit_vae_decode_time_cost\", 0.0)\n            n_audios = len(result.audios)\n            print(f\"  ✅ [{test_variant}] Generation OK: {n_audios} audio(s) in {wall_time:.1f}s\")\n        else:\n            result_entry[\"error\"] = result.error\n            print(f\"  ❌ [{test_variant}] Generation FAILED: {result.error}\")\n\n        _cleanup_dir(save_dir)\n\n    except torch.cuda.OutOfMemoryError as e:\n        result_entry[\"error\"] = f\"OOM: {e}\"\n        print(f\"  ❌ [{test_variant}] OOM ERROR: {e}\")\n    except Exception as e:\n        result_entry[\"error\"] = f\"Generation exception: {e}\"\n        print(f\"  ❌ [{test_variant}] Exception: {e}\")\n        traceback.print_exc()\n\n    # Record peak VRAM\n    if torch.cuda.is_available():\n        peak_bytes = torch.cuda.max_memory_allocated()\n        result_entry[\"peak_vram_gb\"] = peak_bytes / (1024 ** 3)\n        print(f\"  Peak VRAM: {result_entry['peak_vram_gb']:.2f}GB\")\n\n    # Cleanup\n    _cleanup_handlers(dit_handler, llm_handler)\n\n    return result_entry\n\n\ndef run_tier_test_mode(args):\n    \"\"\"\n    Automatically test inference across multiple simulated GPU tiers.\n\n    For each tier:\n      1. Set MAX_CUDA_VRAM to simulate the VRAM limit\n      2. Initialize gpu_config for that tier\n      3. Initialize DiT + (optionally) LLM handlers with tier-appropriate settings\n      4. Run a short generation and verify it completes without OOM\n      5. Report results\n\n    When --tier-boundary is enabled, each tier is tested with up to 3 configurations:\n      - default: tier's default settings (quantization + offload as configured)\n      - no-quant: same as default but with quantization disabled\n      - no-offload: no quantization AND no CPU offload (all models on GPU)\n\n    This replaces the manual workflow of:\n      MAX_CUDA_VRAM=8 uv run acestep → click UI → wait → check\n    \"\"\"\n    # Determine which tiers to test\n    default_tiers = [4, 6, 8, 12, 16, 24, 48]\n    tiers_to_test = args.tiers if args.tiers else default_tiers\n\n    # Load example for generation\n    example_file = os.path.join(\n        PROJECT_ROOT, \"examples\", \"text2music\", args.example\n    )\n    if not os.path.exists(example_file):\n        print(f\"\\n  Example not found: {example_file}\")\n        sys.exit(1)\n\n    with open(example_file, \"r\", encoding=\"utf-8\") as f:\n        example_data = json.load(f)\n\n    # Scan available LM models on disk\n    checkpoint_dir = os.path.join(PROJECT_ROOT, \"checkpoints\")\n    disk_lm_models = []\n    if os.path.exists(checkpoint_dir):\n        for item in sorted(os.listdir(checkpoint_dir)):\n            if os.path.isdir(os.path.join(checkpoint_dir, item)) and item.startswith(\"acestep-5Hz-lm-\"):\n                disk_lm_models.append(item)\n\n    boundary_mode = getattr(args, \"tier_boundary\", False)\n    batch_boundary_mode = getattr(args, \"tier_batch_boundary\", False)\n\n    print(f\"\\n  Tiers to test: {tiers_to_test}\")\n    print(f\"  LM models on disk: {disk_lm_models}\")\n    print(f\"  Test with LM: {args.tier_with_lm}\")\n    print(f\"  Test duration: {args.tier_duration}s\")\n    print(f\"  Boundary testing: {boundary_mode}\")\n    print(f\"  Batch boundary testing: {batch_boundary_mode}\")\n    print(f\"  Example: {args.example}\")\n\n    # Results collector\n    all_results = []\n\n    for sim_gb in tiers_to_test:\n        print(\"\\n\" + \"=\" * 120)\n        print(f\"  TIER TEST: {sim_gb}GB simulated VRAM\")\n        print(\"=\" * 120)\n\n        # Configure GPU simulation\n        os.environ[\"MAX_CUDA_VRAM\"] = str(sim_gb)\n\n        # Force re-detection of GPU config\n        gpu_config = get_gpu_config(gpu_memory_gb=float(sim_gb))\n        set_global_gpu_config(gpu_config)\n\n        tier = gpu_config.tier\n        print(f\"  Tier: {tier}\")\n        print(f\"  init_lm_default: {gpu_config.init_lm_default}\")\n        print(f\"  available_lm_models: {gpu_config.available_lm_models}\")\n        print(f\"  recommended_lm_model: {gpu_config.recommended_lm_model}\")\n        print(f\"  recommended_backend: {gpu_config.recommended_backend}\")\n        print(f\"  lm_backend_restriction: {gpu_config.lm_backend_restriction}\")\n        print(f\"  offload_to_cpu: {gpu_config.offload_to_cpu_default}\")\n        print(f\"  offload_dit_to_cpu: {gpu_config.offload_dit_to_cpu_default}\")\n        print(f\"  quantization: {gpu_config.quantization_default}\")\n        print(f\"  max_duration_with_lm: {gpu_config.max_duration_with_lm}s\")\n        print(f\"  max_duration_without_lm: {gpu_config.max_duration_without_lm}s\")\n        print(f\"  max_batch_with_lm: {gpu_config.max_batch_size_with_lm}\")\n        print(f\"  max_batch_without_lm: {gpu_config.max_batch_size_without_lm}\")\n\n        # ---- Test 1: Default configuration ----\n        print(f\"\\n  --- Variant: default ---\")\n        result_default = _run_single_tier_test(\n            sim_gb, gpu_config, args, example_data,\n            checkpoint_dir, disk_lm_models,\n            test_variant=\"default\",\n        )\n        all_results.append(result_default)\n\n        if boundary_mode:\n            # ---- Test 2: No quantization (keep offload as default) ----\n            # Skip if the tier already doesn't use quantization (no point re-testing)\n            if gpu_config.quantization_default:\n                print(f\"\\n  --- Variant: no-quant (offload={gpu_config.offload_to_cpu_default}) ---\")\n                result_no_quant = _run_single_tier_test(\n                    sim_gb, gpu_config, args, example_data,\n                    checkpoint_dir, disk_lm_models,\n                    quantization_override=None,\n                    test_variant=\"no-quant\",\n                )\n                all_results.append(result_no_quant)\n            else:\n                print(f\"\\n  --- Variant: no-quant — SKIPPED (tier already has quantization=False) ---\")\n\n            # ---- Test 3: No quantization AND no offload ----\n            # Skip if the tier already has both disabled\n            # Also skip if simulated VRAM is too small — the unquantized DiT model\n            # alone needs ~6GB; without offload there is no room left for VAE decode,\n            # which causes a fallback to CPU VAE with tiny chunk_size and 20+ hour runs.\n            MIN_VRAM_FOR_NO_OFFLOAD = 8  # GB — DiT (~6GB) + VAE headroom (~2GB)\n            if sim_gb < MIN_VRAM_FOR_NO_OFFLOAD:\n                print(f\"\\n  --- Variant: no-offload — SKIPPED (simulated {sim_gb}GB < {MIN_VRAM_FOR_NO_OFFLOAD}GB minimum for no-offload) ---\")\n            elif gpu_config.quantization_default or gpu_config.offload_to_cpu_default:\n                print(f\"\\n  --- Variant: no-offload (quant=None, offload=False) ---\")\n                result_no_offload = _run_single_tier_test(\n                    sim_gb, gpu_config, args, example_data,\n                    checkpoint_dir, disk_lm_models,\n                    offload_override=False,\n                    offload_dit_override=False,\n                    quantization_override=None,\n                    test_variant=\"no-offload\",\n                )\n                all_results.append(result_no_offload)\n            else:\n                print(f\"\\n  --- Variant: no-offload — SKIPPED (tier already has offload=False, quant=False) ---\")\n\n        if batch_boundary_mode:\n            # ---- Batch boundary tests: escalate batch size until OOM ----\n            BATCH_SIZES_TO_TEST = [1, 2, 4, 8]\n\n            # Test WITHOUT LM\n            print(f\"\\n  --- Batch boundary: without LM ---\")\n            for bs in BATCH_SIZES_TO_TEST:\n                print(f\"\\n  --- Variant: batch-noLM-{bs} (batch_size={bs}, no LM) ---\")\n                result_batch = _run_single_tier_test(\n                    sim_gb, gpu_config, args, example_data,\n                    checkpoint_dir, disk_lm_models,\n                    test_variant=f\"batch-noLM-{bs}\",\n                    batch_size_override=bs,\n                    use_lm_override=False,\n                )\n                all_results.append(result_batch)\n                if not result_batch[\"gen_success\"]:\n                    print(f\"  ⚠️ Batch size {bs} failed without LM — stopping escalation\")\n                    break\n\n            # Test WITH LM (if tier supports it)\n            if gpu_config.init_lm_default and bool(gpu_config.available_lm_models):\n                print(f\"\\n  --- Batch boundary: with LM ---\")\n                for bs in BATCH_SIZES_TO_TEST:\n                    print(f\"\\n  --- Variant: batch-LM-{bs} (batch_size={bs}, with LM) ---\")\n                    result_batch_lm = _run_single_tier_test(\n                        sim_gb, gpu_config, args, example_data,\n                        checkpoint_dir, disk_lm_models,\n                        test_variant=f\"batch-LM-{bs}\",\n                        batch_size_override=bs,\n                        use_lm_override=True,\n                    )\n                    all_results.append(result_batch_lm)\n                    if not result_batch_lm[\"gen_success\"]:\n                        print(f\"  ⚠️ Batch size {bs} failed with LM — stopping escalation\")\n                        break\n\n    # ---- Print summary ----\n    _print_tier_test_summary(all_results)\n\n    if boundary_mode:\n        _print_boundary_summary(all_results)\n\n    if batch_boundary_mode:\n        _print_batch_boundary_summary(all_results)\n\n    # Save results\n    if args.benchmark_output:\n        with open(args.benchmark_output, \"w\", encoding=\"utf-8\") as f:\n            json.dump(all_results, f, indent=2, default=str)\n        print(f\"\\n  Results saved to: {args.benchmark_output}\")\n\n    return all_results\n\n\ndef _cleanup_handlers(dit_handler, llm_handler):\n    \"\"\"Clean up handlers and free GPU memory.\"\"\"\n    try:\n        if dit_handler is not None:\n            if hasattr(dit_handler, 'model') and dit_handler.model is not None:\n                dit_handler.model = None\n            if hasattr(dit_handler, 'vae') and dit_handler.vae is not None:\n                dit_handler.vae = None\n            if hasattr(dit_handler, 'text_encoder') and dit_handler.text_encoder is not None:\n                dit_handler.text_encoder = None\n            del dit_handler\n    except Exception:\n        pass\n\n    try:\n        if llm_handler is not None:\n            if hasattr(llm_handler, 'llm') and llm_handler.llm is not None:\n                llm_handler.llm = None\n            del llm_handler\n    except Exception:\n        pass\n\n    import gc\n    gc.collect()\n    if torch.cuda.is_available():\n        torch.cuda.empty_cache()\n        torch.cuda.reset_peak_memory_stats()\n\n\ndef _print_tier_test_summary(results: List[Dict]):\n    \"\"\"Print a summary table of all tier test results.\"\"\"\n    # Detect if any result has a test_variant (boundary mode)\n    has_variants = any(r.get(\"test_variant\", \"default\") != \"default\" for r in results)\n\n    print(\"\\n\" + \"=\" * 160)\n    print(\"TIER TEST SUMMARY\")\n    print(\"=\" * 160)\n\n    if has_variants:\n        header = (\n            f\"{'VRAM':>6} {'Tier':<10} {'Variant':<12} {'LM':>4} {'LM Model':<24} {'Backend':<8} \"\n            f\"{'Offload':<8} {'Quant':<6} {'Init':>5} {'Gen':>5} \"\n            f\"{'Wall(s)':>8} {'Peak(GB)':>9} {'Status':<30}\"\n        )\n    else:\n        header = (\n            f\"{'VRAM':>6} {'Tier':<10} {'LM':>4} {'LM Model':<28} {'Backend':<8} \"\n            f\"{'Offload':<8} {'Quant':<6} {'Init':>5} {'Gen':>5} \"\n            f\"{'Wall(s)':>8} {'Peak(GB)':>9} {'Status':<30}\"\n        )\n    print(header)\n    print(\"-\" * 160)\n\n    pass_count = 0\n    fail_count = 0\n\n    for r in results:\n        lm_model_short = (r.get(\"lm_model\") or \"-\")\n        max_lm_len = 22 if has_variants else 26\n        if len(lm_model_short) > max_lm_len:\n            lm_model_short = lm_model_short[:max_lm_len] + \"..\"\n\n        init_ok = \"✅\" if r[\"init_success\"] else \"❌\"\n        gen_ok = \"✅\" if r[\"gen_success\"] else \"❌\"\n        status = \"PASS\" if r[\"gen_success\"] else (r.get(\"error\", \"FAIL\") or \"FAIL\")\n        if len(status) > 28:\n            status = status[:28] + \"..\"\n\n        if r[\"gen_success\"]:\n            pass_count += 1\n        else:\n            fail_count += 1\n\n        quant = \"int8\" if r.get(\"quantization\") else \"-\"\n        variant = r.get(\"test_variant\", \"default\")\n\n        if has_variants:\n            print(\n                f\"{r['tier_gb']:5d}GB {r['tier']:<10} {variant:<12} \"\n                f\"{'Y' if r['use_lm'] else 'N':>4} {lm_model_short:<24} \"\n                f\"{r.get('lm_backend', '-'):<8} \"\n                f\"{'Y' if r['offload'] else 'N':<8} {quant:<6} \"\n                f\"{init_ok:>5} {gen_ok:>5} \"\n                f\"{r['wall_time']:>8.1f} {r.get('peak_vram_gb', 0):>9.2f} \"\n                f\"{status:<30}\"\n            )\n        else:\n            print(\n                f\"{r['tier_gb']:5d}GB {r['tier']:<10} \"\n                f\"{'Y' if r['use_lm'] else 'N':>4} {lm_model_short:<28} \"\n                f\"{r.get('lm_backend', '-'):<8} \"\n                f\"{'Y' if r['offload'] else 'N':<8} {quant:<6} \"\n                f\"{init_ok:>5} {gen_ok:>5} \"\n                f\"{r['wall_time']:>8.1f} {r.get('peak_vram_gb', 0):>9.2f} \"\n                f\"{status:<30}\"\n            )\n\n    print(\"-\" * 160)\n    print(f\"  Total: {len(results)} tests run, {pass_count} PASSED, {fail_count} FAILED\")\n\n\ndef _print_boundary_summary(results: List[Dict]):\n    \"\"\"\n    Print a boundary analysis summary showing the minimum tier for each capability.\n\n    Analyzes results from boundary testing to determine:\n    - Minimum tier that works WITHOUT INT8 quantization\n    - Minimum tier that works WITHOUT CPU offload (and without quantization)\n    \"\"\"\n    print(\"\\n\" + \"=\" * 100)\n    print(\"BOUNDARY ANALYSIS\")\n    print(\"=\" * 100)\n    print()\n    print(\"  This analysis shows the minimum VRAM tier at which each optimization\")\n    print(\"  can be safely disabled while still completing inference successfully.\")\n    print()\n\n    # Collect results by variant\n    no_quant_results = [r for r in results if r.get(\"test_variant\") == \"no-quant\"]\n    no_offload_results = [r for r in results if r.get(\"test_variant\") == \"no-offload\"]\n    default_results = [r for r in results if r.get(\"test_variant\") == \"default\"]\n\n    # Also consider default results where the tier already has quant/offload disabled\n    # (e.g., tier6b default already has quantization=False)\n    for r in default_results:\n        if not r.get(\"quantization\") and r not in no_quant_results:\n            # This tier's default already runs without quantization\n            no_quant_results.append(r)\n        if not r.get(\"offload\") and not r.get(\"quantization\") and r not in no_offload_results:\n            # This tier's default already runs without offload and without quantization\n            no_offload_results.append(r)\n\n    # Sort by VRAM\n    no_quant_results.sort(key=lambda r: r[\"tier_gb\"])\n    no_offload_results.sort(key=lambda r: r[\"tier_gb\"])\n\n    # Find minimum passing tier for each capability\n    def _find_min_passing(result_list, capability_name):\n        passing = [r for r in result_list if r.get(\"gen_success\")]\n        failing = [r for r in result_list if not r.get(\"gen_success\")]\n\n        if passing:\n            min_pass = passing[0]\n            print(f\"  {capability_name}:\")\n            print(f\"    Minimum tier:  {min_pass['tier']} ({min_pass['tier_gb']}GB)\")\n            print(f\"    Peak VRAM:     {min_pass.get('peak_vram_gb', 0):.2f}GB\")\n            if failing:\n                max_fail = failing[-1]\n                print(f\"    Last failure:  {max_fail['tier']} ({max_fail['tier_gb']}GB) — {max_fail.get('error', 'unknown')[:60]}\")\n        else:\n            if failing:\n                print(f\"  {capability_name}:\")\n                print(f\"    ❌ No tier passed this test. All tested tiers failed.\")\n                for r in failing:\n                    err = (r.get(\"error\") or \"unknown\")[:50]\n                    print(f\"       {r['tier_gb']}GB ({r['tier']}): {err}\")\n            else:\n                print(f\"  {capability_name}:\")\n                print(f\"    ⚠️ No test results available for this capability.\")\n        print()\n        return passing[0] if passing else None\n\n    min_no_quant = _find_min_passing(no_quant_results, \"Without INT8 Quantization\")\n    min_no_offload = _find_min_passing(no_offload_results, \"Without CPU Offload (and no quantization)\")\n\n    # Print compact summary table\n    print(\"  \" + \"-\" * 60)\n    print(f\"  {'Capability':<45} {'Min Tier':<10} {'VRAM':>6}\")\n    print(\"  \" + \"-\" * 60)\n\n    if min_no_quant:\n        print(f\"  {'No INT8 Quantization':<45} {min_no_quant['tier']:<10} {min_no_quant['tier_gb']:>5}GB\")\n    else:\n        print(f\"  {'No INT8 Quantization':<45} {'N/A':<10} {'N/A':>6}\")\n\n    if min_no_offload:\n        print(f\"  {'No CPU Offload (all models on GPU)':<45} {min_no_offload['tier']:<10} {min_no_offload['tier_gb']:>5}GB\")\n    else:\n        print(f\"  {'No CPU Offload (all models on GPU)':<45} {'N/A':<10} {'N/A':>6}\")\n\n    print(\"  \" + \"-\" * 60)\n    print()\n    print(\"  Note: These boundaries are empirical and may vary based on:\")\n    print(\"    - DiT model variant (turbo vs base)\")\n    print(\"    - Whether LM is enabled (--tier-with-lm)\")\n    print(\"    - Generation duration and batch size\")\n    print(\"    - Flash attention availability\")\n\n\ndef _print_batch_boundary_summary(results: List[Dict]):\n    \"\"\"\n    Print a batch boundary analysis summary showing the maximum safe batch size per tier.\n\n    Analyzes results from batch boundary testing to determine:\n    - Maximum batch size WITHOUT LM for each tier\n    - Maximum batch size WITH LM for each tier\n    \"\"\"\n    print(\"\\n\" + \"=\" * 120)\n    print(\"BATCH BOUNDARY ANALYSIS\")\n    print(\"=\" * 120)\n    print()\n    print(\"  This analysis shows the maximum batch size that completed successfully\")\n    print(\"  for each simulated VRAM tier.\")\n    print()\n\n    # Collect batch boundary results\n    batch_no_lm = [r for r in results if r.get(\"test_variant\", \"\").startswith(\"batch-noLM-\")]\n    batch_with_lm = [r for r in results if r.get(\"test_variant\", \"\").startswith(\"batch-LM-\")]\n\n    # Group by tier_gb\n    def _group_by_tier(result_list):\n        groups = {}\n        for r in result_list:\n            tier_gb = r[\"tier_gb\"]\n            if tier_gb not in groups:\n                groups[tier_gb] = {\"tier\": r[\"tier\"], \"results\": []}\n            groups[tier_gb][\"results\"].append(r)\n        return groups\n\n    no_lm_groups = _group_by_tier(batch_no_lm)\n    with_lm_groups = _group_by_tier(batch_with_lm)\n\n    # Find max passing batch per tier\n    def _max_passing_batch(group_results):\n        max_bs = 0\n        peak_vram = 0.0\n        for r in group_results:\n            if r.get(\"gen_success\"):\n                bs = r.get(\"batch_size\", 1)\n                if bs > max_bs:\n                    max_bs = bs\n                    peak_vram = r.get(\"peak_vram_gb\", 0)\n        return max_bs, peak_vram\n\n    # Collect all tier_gb values\n    all_tier_gbs = sorted(set(list(no_lm_groups.keys()) + list(with_lm_groups.keys())))\n\n    # Print table\n    print(f\"  {'VRAM':>6}  {'Tier':<12}  {'Max Batch (no LM)':>18}  {'Peak VRAM':>10}  {'Max Batch (with LM)':>20}  {'Peak VRAM':>10}\")\n    print(\"  \" + \"-\" * 90)\n\n    summary_rows = []\n    for tier_gb in all_tier_gbs:\n        tier_name = no_lm_groups.get(tier_gb, with_lm_groups.get(tier_gb, {})).get(\"tier\", \"?\")\n\n        no_lm_max, no_lm_peak = (0, 0.0)\n        if tier_gb in no_lm_groups:\n            no_lm_max, no_lm_peak = _max_passing_batch(no_lm_groups[tier_gb][\"results\"])\n\n        with_lm_max, with_lm_peak = (0, 0.0)\n        if tier_gb in with_lm_groups:\n            with_lm_max, with_lm_peak = _max_passing_batch(with_lm_groups[tier_gb][\"results\"])\n\n        no_lm_str = str(no_lm_max) if no_lm_max > 0 else \"FAIL\"\n        with_lm_str = str(with_lm_max) if with_lm_max > 0 else (\"N/A\" if tier_gb not in with_lm_groups else \"FAIL\")\n\n        no_lm_peak_str = f\"{no_lm_peak:.2f}GB\" if no_lm_max > 0 else \"-\"\n        with_lm_peak_str = f\"{with_lm_peak:.2f}GB\" if with_lm_max > 0 else \"-\"\n\n        print(\n            f\"  {tier_gb:5d}GB  {tier_name:<12}  {no_lm_str:>18}  {no_lm_peak_str:>10}  \"\n            f\"{with_lm_str:>20}  {with_lm_peak_str:>10}\"\n        )\n\n        summary_rows.append({\n            \"tier_gb\": tier_gb,\n            \"tier\": tier_name,\n            \"max_batch_no_lm\": no_lm_max,\n            \"max_batch_with_lm\": with_lm_max if tier_gb in with_lm_groups else None,\n        })\n\n    print(\"  \" + \"-\" * 90)\n    print()\n\n    # Print comparison with current GPU_TIER_CONFIGS\n    print(\"  Comparison with current GPU_TIER_CONFIGS:\")\n    print(f\"  {'VRAM':>6}  {'Tier':<12}  {'Config (no LM)':>15}  {'Tested (no LM)':>15}  {'Config (LM)':>12}  {'Tested (LM)':>12}  {'Recommendation':<30}\")\n    print(\"  \" + \"-\" * 110)\n\n    for row in summary_rows:\n        tier_gb = row[\"tier_gb\"]\n        tier_name = row[\"tier\"]\n        cfg = get_gpu_config(gpu_memory_gb=float(tier_gb))\n\n        cfg_no_lm = cfg.max_batch_size_without_lm\n        cfg_with_lm = cfg.max_batch_size_with_lm\n        tested_no_lm = row[\"max_batch_no_lm\"]\n        tested_with_lm = row[\"max_batch_with_lm\"]\n\n        tested_no_lm_str = str(tested_no_lm) if tested_no_lm > 0 else \"FAIL\"\n        tested_with_lm_str = str(tested_with_lm) if tested_with_lm is not None and tested_with_lm > 0 else (\"N/A\" if tested_with_lm is None else \"FAIL\")\n\n        # Recommendation\n        rec_parts = []\n        if tested_no_lm > 0 and tested_no_lm != cfg_no_lm:\n            rec_parts.append(f\"no_lm: {cfg_no_lm}→{tested_no_lm}\")\n        if tested_with_lm is not None and tested_with_lm > 0 and tested_with_lm != cfg_with_lm:\n            rec_parts.append(f\"lm: {cfg_with_lm}→{tested_with_lm}\")\n        recommendation = \", \".join(rec_parts) if rec_parts else \"OK\"\n\n        print(\n            f\"  {tier_gb:5d}GB  {tier_name:<12}  {cfg_no_lm:>15}  {tested_no_lm_str:>15}  \"\n            f\"{cfg_with_lm:>12}  {tested_with_lm_str:>12}  {recommendation:<30}\"\n        )\n\n    print(\"  \" + \"-\" * 110)\n    print()\n    print(\"  Note: Batch boundary results are empirical and depend on:\")\n    print(\"    - DiT model variant (turbo vs base)\")\n    print(\"    - Generation duration (longer = more VRAM per batch)\")\n    print(\"    - Flash attention availability\")\n    print(\"    - LM model size (0.6B vs 1.7B vs 4B)\")\n    print(\"    - Quantization and offload settings\")\n\n\n# =============================================================================\n# Mode: understand\n# =============================================================================\n\n\ndef run_understand_mode(dit_handler, llm_handler, args, timer: PreciseTimer):\n    \"\"\"Profile the understand_music() API.\"\"\"\n    if not llm_handler.llm_initialized:\n        print(\"\\n  LLM not initialized. understand mode requires LLM.\")\n        print(\"  Re-run with --thinking or ensure LLM is available.\")\n        sys.exit(1)\n\n    audio_codes = args.audio_codes if args.audio_codes else \"\"\n\n    print(\n        f\"\\n  Audio codes: \"\n        f\"{'<provided>' if audio_codes else '<empty - will generate sample>'}\"\n    )\n\n    timer.sync()\n    t0 = time.perf_counter()\n\n    result = understand_music(\n        llm_handler=llm_handler,\n        audio_codes=audio_codes,\n        temperature=args.lm_temperature,\n        use_constrained_decoding=args.use_constrained_decoding,\n    )\n\n    timer.sync()\n    wall_time = time.perf_counter() - t0\n\n    print(f\"\\n  Wall time: {wall_time:.3f}s\")\n    print(f\"  Success: {result.success}\")\n    if result.success:\n        print(f\"  Caption: {result.caption[:100]}...\")\n        print(\n            f\"  BPM: {result.bpm}, Duration: {result.duration}, \"\n            f\"Key: {result.keyscale}\"\n        )\n        print(\n            f\"  Language: {result.language}, Time Sig: {result.timesignature}\"\n        )\n        if result.lyrics:\n            print(f\"  Lyrics: {result.lyrics[:100]}...\")\n    else:\n        print(f\"  Error: {result.error}\")\n\n    return result, wall_time\n\n\n# =============================================================================\n# Mode: create_sample\n# =============================================================================\n\n\ndef run_create_sample_mode(\n    dit_handler, llm_handler, args, timer: PreciseTimer\n):\n    \"\"\"Profile the create_sample() API (inspiration/simple mode).\"\"\"\n    if not llm_handler.llm_initialized:\n        print(\"\\n  LLM not initialized. create_sample mode requires LLM.\")\n        sys.exit(1)\n\n    query = args.sample_query or \"a soft love song for a quiet evening\"\n    print(f\"\\n  Query: {query}\")\n    print(f\"  Instrumental: {args.instrumental}\")\n\n    timer.sync()\n    t0 = time.perf_counter()\n\n    result = create_sample(\n        llm_handler=llm_handler,\n        query=query,\n        instrumental=args.instrumental,\n        temperature=args.lm_temperature,\n        use_constrained_decoding=args.use_constrained_decoding,\n    )\n\n    timer.sync()\n    wall_time = time.perf_counter() - t0\n\n    print(f\"\\n  Wall time: {wall_time:.3f}s\")\n    print(f\"  Success: {result.success}\")\n    if result.success:\n        print(f\"  Caption: {result.caption[:100]}...\")\n        print(\n            f\"  BPM: {result.bpm}, Duration: {result.duration}, \"\n            f\"Key: {result.keyscale}\"\n        )\n        print(\n            f\"  Language: {result.language}, Time Sig: {result.timesignature}\"\n        )\n        print(f\"  Instrumental: {result.instrumental}\")\n        if result.lyrics:\n            print(f\"  Lyrics: {result.lyrics[:100]}...\")\n    else:\n        print(f\"  Error: {result.error}\")\n\n    return result, wall_time\n\n\n# =============================================================================\n# Mode: format_sample\n# =============================================================================\n\n\ndef run_format_sample_mode(\n    dit_handler, llm_handler, args, timer: PreciseTimer\n):\n    \"\"\"Profile the format_sample() API.\"\"\"\n    if not llm_handler.llm_initialized:\n        print(\"\\n  LLM not initialized. format_sample mode requires LLM.\")\n        sys.exit(1)\n\n    example_file = os.path.join(\n        PROJECT_ROOT, \"examples\", \"text2music\", args.example\n    )\n    if not os.path.exists(example_file):\n        print(f\"\\n  Example not found: {example_file}\")\n        sys.exit(1)\n\n    with open(example_file, \"r\", encoding=\"utf-8\") as f:\n        data = json.load(f)\n\n    caption = data.get(\"caption\", \"Latin pop, reggaeton\")\n    lyrics = data.get(\"lyrics\", \"[Verse 1]\\nHola mundo\")\n\n    print(f\"\\n  Caption: {caption[:80]}...\")\n    print(f\"  Lyrics: {lyrics[:80]}...\")\n\n    timer.sync()\n    t0 = time.perf_counter()\n\n    result = format_sample(\n        llm_handler=llm_handler,\n        caption=caption,\n        lyrics=lyrics,\n        temperature=args.lm_temperature,\n        use_constrained_decoding=args.use_constrained_decoding,\n    )\n\n    timer.sync()\n    wall_time = time.perf_counter() - t0\n\n    print(f\"\\n  Wall time: {wall_time:.3f}s\")\n    print(f\"  Success: {result.success}\")\n    if result.success:\n        print(f\"  Caption: {result.caption[:100]}...\")\n        print(\n            f\"  BPM: {result.bpm}, Duration: {result.duration}, \"\n            f\"Key: {result.keyscale}\"\n        )\n        print(\n            f\"  Language: {result.language}, Time Sig: {result.timesignature}\"\n        )\n    else:\n        print(f\"  Error: {result.error}\")\n\n    return result, wall_time\n\n\n# =============================================================================\n# cProfile helper\n# =============================================================================\n\n\ndef _print_cprofile(prof):\n    \"\"\"Print cProfile results and save to file.\"\"\"\n    import pstats\n    import io\n\n    output_file = \"profile_cprofile_detailed.txt\"\n    with open(output_file, \"w\") as f:\n        ps = pstats.Stats(prof, stream=f)\n        ps.sort_stats(\"cumulative\")\n        ps.print_stats(100)\n\n    print(\"\\n\" + \"=\" * 100)\n    print(\"TOP 20 FUNCTIONS BY CUMULATIVE TIME (cProfile)\")\n    print(\"=\" * 100)\n    s = io.StringIO()\n    ps = pstats.Stats(prof, stream=s)\n    ps.sort_stats(\"cumulative\")\n    ps.print_stats(20)\n    print(s.getvalue())\n    print(f\"Full report saved to: {output_file}\")\n\n\ndef _cleanup_dir(path: str):\n    \"\"\"Remove temporary directory silently.\"\"\"\n    try:\n        import shutil\n        shutil.rmtree(path, ignore_errors=True)\n    except Exception:\n        pass\n\n\n# =============================================================================\n# Handler initialization (for non-tier-test modes)\n# =============================================================================\n\n\ndef initialize_handlers(\n    args, device: str\n) -> Tuple[AceStepHandler, LLMHandler]:\n    \"\"\"Initialize DiT and LLM handlers with current API.\"\"\"\n    dit_handler = AceStepHandler()\n    llm_handler = LLMHandler()\n\n    # Determine flash attention availability\n    use_flash_attention = False\n    if device.startswith(\"cuda\"):\n        try:\n            import flash_attn  # noqa: F401\n            use_flash_attention = True\n        except ImportError:\n            pass\n\n    compile_model = os.environ.get(\n        \"ACESTEP_COMPILE_MODEL\", \"\"\n    ).strip().lower() in {\"1\", \"true\", \"yes\", \"y\", \"on\"}\n\n    print(\"  Initializing DiT handler...\")\n    status_dit, success_dit = dit_handler.initialize_service(\n        project_root=PROJECT_ROOT,\n        config_path=args.config_path,\n        device=args.device,  # Pass original device string (handler resolves \"auto\")\n        use_flash_attention=use_flash_attention,\n        compile_model=compile_model,\n        offload_to_cpu=args.offload_to_cpu,\n        offload_dit_to_cpu=args.offload_dit_to_cpu,\n        quantization=args.quantization,\n    )\n    if not success_dit:\n        print(f\"  DiT initialization failed: {status_dit}\")\n        sys.exit(1)\n    print(f\"  DiT ready (device={dit_handler.device})\")\n\n    # Determine if LLM should be initialized\n    need_llm = (\n        args.thinking\n        or args.use_cot_metas\n        or args.use_cot_caption\n        or args.use_cot_language\n        or args.mode in (\"understand\", \"create_sample\", \"format_sample\")\n    )\n\n    if need_llm:\n        print(f\"  Initializing LLM handler (backend={args.lm_backend})...\")\n        status_llm, success_llm = llm_handler.initialize(\n            checkpoint_dir=os.path.join(PROJECT_ROOT, \"checkpoints\"),\n            lm_model_path=args.lm_model,\n            backend=args.lm_backend,\n            device=args.device,\n            offload_to_cpu=args.offload_to_cpu,\n            dtype=None,\n        )\n        if success_llm:\n            print(f\"  LLM ready (backend={llm_handler.llm_backend})\")\n        else:\n            print(f\"  LLM initialization failed: {status_llm}\")\n            if args.mode in (\"understand\", \"create_sample\", \"format_sample\"):\n                sys.exit(1)\n    else:\n        print(\n            \"  LLM not needed for current configuration \"\n            \"(thinking/CoT disabled)\"\n        )\n\n    return dit_handler, llm_handler\n\n\n# =============================================================================\n# CLI argument parser\n# =============================================================================\n\n\ndef build_parser() -> argparse.ArgumentParser:\n    \"\"\"Build the argument parser with all options.\"\"\"\n    env_config = load_env_config()\n\n    parser = argparse.ArgumentParser(\n        description=\"ACE-Step 1.5 Inference Profiler & Benchmark\",\n        formatter_class=argparse.RawDescriptionHelpFormatter,\n        epilog=\"\"\"\nExamples:\n  python profile_inference.py                                    # Profile text2music\n  python profile_inference.py --thinking --llm-debug             # With LLM analysis\n  python profile_inference.py --mode benchmark                   # Benchmark matrix\n  python profile_inference.py --mode tier-test                   # Test all GPU tiers\n  python profile_inference.py --mode tier-test --tiers 6 8 16    # Test specific tiers\n  python profile_inference.py --mode tier-test --tier-with-lm    # Test tiers with LM\n  python profile_inference.py --mode understand                  # Profile understand API\n  python profile_inference.py --mode create_sample --sample-query \"jazz ballad\"\n  python profile_inference.py --device mps --lm-backend mlx      # Apple Silicon\n  python profile_inference.py --device cuda --lm-backend vllm    # NVIDIA GPU\n\"\"\",\n    )\n\n    # Mode\n    parser.add_argument(\n        \"--mode\",\n        type=str,\n        default=\"profile\",\n        choices=[\n            \"profile\",\n            \"benchmark\",\n            \"tier-test\",\n            \"understand\",\n            \"create_sample\",\n            \"format_sample\",\n        ],\n        help=\"Profiling mode (default: profile)\",\n    )\n\n    # Device & backend\n    parser.add_argument(\n        \"--device\",\n        type=str,\n        default=env_config[\"ACESTEP_DEVICE\"],\n        help=(\n            f\"Device: auto/cuda/mps/cpu \"\n            f\"(default: {env_config['ACESTEP_DEVICE']})\"\n        ),\n    )\n    parser.add_argument(\n        \"--lm-backend\",\n        type=str,\n        default=env_config[\"ACESTEP_LM_BACKEND\"],\n        choices=[\"auto\", \"vllm\", \"pt\", \"mlx\"],\n        help=(\n            f\"LLM backend \"\n            f\"(default: {env_config['ACESTEP_LM_BACKEND']})\"\n        ),\n    )\n\n    # Model paths\n    parser.add_argument(\n        \"--config-path\",\n        type=str,\n        default=env_config[\"ACESTEP_CONFIG_PATH\"],\n        help=(\n            f\"DiT model config \"\n            f\"(default: {env_config['ACESTEP_CONFIG_PATH']})\"\n        ),\n    )\n    parser.add_argument(\n        \"--lm-model\",\n        type=str,\n        default=env_config[\"ACESTEP_LM_MODEL_PATH\"],\n        help=(\n            f\"LLM model path \"\n            f\"(default: {env_config['ACESTEP_LM_MODEL_PATH']})\"\n        ),\n    )\n\n    # Hardware options\n    parser.add_argument(\n        \"--offload-to-cpu\",\n        action=\"store_true\",\n        help=\"Offload models to CPU when not in use\",\n    )\n    parser.add_argument(\n        \"--offload-dit-to-cpu\",\n        action=\"store_true\",\n        help=\"Offload DiT to CPU when not in use\",\n    )\n    parser.add_argument(\n        \"--quantization\",\n        type=str,\n        default=None,\n        choices=[\"int8_weight_only\", \"fp8_weight_only\", \"w8a8_dynamic\"],\n        help=\"Quantization mode for DiT model\",\n    )\n\n    # Example & input\n    parser.add_argument(\n        \"--example\",\n        type=str,\n        default=\"example_05.json\",\n        help=\"Example JSON file from examples/text2music/\",\n    )\n\n    # Task type\n    parser.add_argument(\n        \"--task-type\",\n        type=str,\n        default=\"text2music\",\n        choices=[\n            \"text2music\",\n            \"cover\",\n            \"repaint\",\n            \"lego\",\n            \"extract\",\n            \"complete\",\n        ],\n        help=\"Generation task type (default: text2music)\",\n    )\n    parser.add_argument(\n        \"--reference-audio\",\n        type=str,\n        default=None,\n        help=\"Reference audio path (for cover/style transfer)\",\n    )\n    parser.add_argument(\n        \"--src-audio\",\n        type=str,\n        default=None,\n        help=\"Source audio path (for audio-to-audio tasks)\",\n    )\n\n    # Generation parameters\n    parser.add_argument(\n        \"--duration\",\n        type=float,\n        default=None,\n        help=\"Audio duration in seconds (overrides example)\",\n    )\n    parser.add_argument(\n        \"--batch-size\",\n        type=int,\n        default=None,\n        help=\"Batch size (overrides example)\",\n    )\n    parser.add_argument(\n        \"--inference-steps\",\n        type=int,\n        default=None,\n        help=\"Diffusion inference steps (overrides example)\",\n    )\n    parser.add_argument(\n        \"--seed\",\n        type=int,\n        default=None,\n        help=\"Random seed (overrides example)\",\n    )\n    parser.add_argument(\n        \"--guidance-scale\",\n        type=float,\n        default=7.0,\n        help=\"CFG guidance scale for DiT (default: 7.0)\",\n    )\n\n    # LLM / CoT parameters\n    parser.add_argument(\n        \"--thinking\",\n        action=\"store_true\",\n        help=\"Enable 5Hz LM Chain-of-Thought reasoning\",\n    )\n    parser.add_argument(\n        \"--use-cot-metas\",\n        action=\"store_true\",\n        help=\"Enable LLM to generate music metadata via CoT\",\n    )\n    parser.add_argument(\n        \"--use-cot-caption\",\n        action=\"store_true\",\n        help=\"Enable LLM to rewrite/format caption via CoT\",\n    )\n    parser.add_argument(\n        \"--use-cot-language\",\n        action=\"store_true\",\n        help=\"Enable LLM to detect vocal language via CoT\",\n    )\n    parser.add_argument(\n        \"--use-constrained-decoding\",\n        action=\"store_true\",\n        default=True,\n        help=\"Use FSM-based constrained decoding (default: True)\",\n    )\n    parser.add_argument(\n        \"--no-constrained-decoding\",\n        action=\"store_true\",\n        help=\"Disable constrained decoding\",\n    )\n    parser.add_argument(\n        \"--lm-temperature\",\n        type=float,\n        default=0.85,\n        help=\"LLM sampling temperature (default: 0.85)\",\n    )\n    parser.add_argument(\n        \"--lm-cfg-scale\",\n        type=float,\n        default=2.0,\n        help=\"LLM CFG scale (default: 2.0)\",\n    )\n\n    # Profiling options\n    parser.add_argument(\n        \"--no-warmup\",\n        action=\"store_true\",\n        help=\"Skip warmup run (includes compilation overhead)\",\n    )\n    parser.add_argument(\n        \"--detailed\",\n        action=\"store_true\",\n        help=\"Enable cProfile function-level analysis\",\n    )\n    parser.add_argument(\n        \"--llm-debug\",\n        action=\"store_true\",\n        help=\"Enable deep LLM debugging (token count, throughput)\",\n    )\n\n    # Benchmark options\n    parser.add_argument(\n        \"--benchmark-output\",\n        type=str,\n        default=None,\n        help=\"Save benchmark results to JSON file\",\n    )\n\n    # Tier-test options\n    parser.add_argument(\n        \"--tiers\",\n        type=int,\n        nargs=\"+\",\n        default=None,\n        help=\"Specific VRAM tiers to test (e.g., --tiers 6 8 16). Default: all tiers\",\n    )\n    parser.add_argument(\n        \"--tier-with-lm\",\n        action=\"store_true\",\n        help=\"Enable LM for tiers that support it (default: DiT-only test)\",\n    )\n    parser.add_argument(\n        \"--tier-duration\",\n        type=float,\n        default=240,\n        help=\"Test generation duration in seconds for tier-test (default: 240)\",\n    )\n    parser.add_argument(\n        \"--tier-skip-compile\",\n        action=\"store_true\",\n        help=\"Skip torch.compile for non-quantized tiers (faster testing, less realistic)\",\n    )\n    parser.add_argument(\n        \"--tier-boundary\",\n        action=\"store_true\",\n        help=\"Enable boundary testing: for each tier, also test without INT8 quantization \"\n             \"and without CPU offload to find the minimum VRAM tier for each capability\",\n    )\n    parser.add_argument(\n        \"--tier-batch-boundary\",\n        action=\"store_true\",\n        help=\"Enable batch size boundary testing: for each tier, progressively test \"\n             \"batch sizes 1, 2, 4, 8 (stop at first OOM) to find the maximum safe batch \"\n             \"size. Tests both with-LM and without-LM configurations.\",\n    )\n\n    # create_sample / understand options\n    parser.add_argument(\n        \"--sample-query\",\n        type=str,\n        default=None,\n        help=\"Query for create_sample mode\",\n    )\n    parser.add_argument(\n        \"--instrumental\",\n        action=\"store_true\",\n        help=\"Generate instrumental music (for create_sample)\",\n    )\n    parser.add_argument(\n        \"--audio-codes\",\n        type=str,\n        default=None,\n        help=\"Audio codes string (for understand mode)\",\n    )\n\n    return parser\n\n\n# =============================================================================\n# Main\n# =============================================================================\n\n\ndef main():\n    parser = build_parser()\n    args = parser.parse_args()\n\n    # Handle --no-constrained-decoding\n    if args.no_constrained_decoding:\n        args.use_constrained_decoding = False\n\n    # Tier-test mode has its own initialization flow\n    if args.mode == \"tier-test\":\n        print(\"=\" * 120)\n        print(\"ACE-Step 1.5 Tier Compatibility Test\")\n        print(\"=\" * 120)\n        run_tier_test_mode(args)\n        print(\"\\n\" + \"=\" * 120)\n        print(\"DONE\")\n        print(\"=\" * 120)\n        return\n\n    # Resolve device\n    device = resolve_device(args.device)\n\n    # Auto-detect backend\n    if args.lm_backend == \"auto\":\n        args.lm_backend = auto_detect_backend(device)\n\n    # Setup GPU config\n    gpu_config = get_gpu_config()\n    set_global_gpu_config(gpu_config)\n\n    # Auto-enable offload for small GPUs\n    if (\n        gpu_config.gpu_memory_gb > 0\n        and gpu_config.gpu_memory_gb < VRAM_AUTO_OFFLOAD_THRESHOLD_GB\n        and not args.offload_to_cpu\n    ):\n        args.offload_to_cpu = True\n\n    # Print header\n    print(\"=\" * 100)\n    print(\"ACE-Step 1.5 Inference Profiler\")\n    print(\"=\" * 100)\n    print(f\"\\n  Mode:           {args.mode}\")\n    print(f\"  Device:         {device} (requested: {args.device})\")\n    print(f\"  LLM Backend:    {args.lm_backend}\")\n    print(f\"  DiT Config:     {args.config_path}\")\n    print(f\"  LLM Model:      {args.lm_model}\")\n    print(\n        f\"  GPU Memory:     {gpu_config.gpu_memory_gb:.1f} GB \"\n        f\"(tier: {gpu_config.tier})\"\n    )\n    if args.quantization:\n        print(f\"  Quantization:   {args.quantization}\")\n    if args.offload_to_cpu:\n        print(\"  CPU Offload:    enabled\")\n    print(f\"\\n  Thinking:       {args.thinking}\")\n    print(f\"  CoT Metas:      {args.use_cot_metas}\")\n    print(f\"  CoT Caption:    {args.use_cot_caption}\")\n    print(f\"  CoT Language:   {args.use_cot_language}\")\n    print(f\"  Constrained:    {args.use_constrained_decoding}\")\n    print(f\"  Warmup:         {'disabled' if args.no_warmup else 'enabled'}\")\n\n    # Initialize handlers\n    print(\"\\n\" + \"-\" * 100)\n    print(\"INITIALIZING MODELS\")\n    print(\"-\" * 100)\n\n    dit_handler, llm_handler = initialize_handlers(args, device)\n\n    # Create timer with resolved device\n    actual_device = getattr(dit_handler, \"device\", device)\n    timer = PreciseTimer(device=actual_device)\n\n    # Dispatch to mode\n    print(\"\\n\" + \"=\" * 100)\n    print(f\"RUNNING MODE: {args.mode.upper()}\")\n    print(\"=\" * 100)\n\n    if args.mode == \"profile\":\n        run_profile_mode(dit_handler, llm_handler, args, timer)\n    elif args.mode == \"benchmark\":\n        run_benchmark_mode(dit_handler, llm_handler, args, timer)\n    elif args.mode == \"understand\":\n        run_understand_mode(dit_handler, llm_handler, args, timer)\n    elif args.mode == \"create_sample\":\n        run_create_sample_mode(dit_handler, llm_handler, args, timer)\n    elif args.mode == \"format_sample\":\n        run_format_sample_mode(dit_handler, llm_handler, args, timer)\n\n    print(\"\\n\" + \"=\" * 100)\n    print(\"DONE\")\n    print(\"=\" * 100)\n\n\nif __name__ == \"__main__\":\n    main()\n"
  },
  {
    "path": "proxy_config.txt.example",
    "content": "# Proxy Configuration Example\n# Copy this file to proxy_config.txt and modify the settings\n# 代理配置示例文件\n# 复制此文件为 proxy_config.txt 并修改配置\n\n# Enable or disable proxy (1 = enabled, 0 = disabled)\n# 启用或禁用代理（1 = 启用，0 = 禁用）\nPROXY_ENABLED=0\n\n# Proxy server URL\n# 代理服务器 URL\n#\n# Supported formats / 支持的格式:\n#   - HTTP:   http://127.0.0.1:7890\n#   - HTTPS:  https://proxy.example.com:8080\n#   - SOCKS5: socks5://127.0.0.1:1080\n#\n# With authentication / 带认证:\n#   - http://username:password@proxy.example.com:8080\n#\n# Common proxy ports / 常见代理端口:\n#   - Clash:         7890\n#   - V2Ray:         1080 (SOCKS5) or 10809 (HTTP)\n#   - Shadowsocks:   1080\n#\nPROXY_URL=\n\n# Examples / 示例配置:\n# ========================================\n# Example 1: Local Clash proxy\n# PROXY_ENABLED=1\n# PROXY_URL=http://127.0.0.1:7890\n\n# Example 2: Local V2Ray SOCKS5 proxy\n# PROXY_ENABLED=1\n# PROXY_URL=socks5://127.0.0.1:1080\n\n# Example 3: Corporate proxy with authentication\n# PROXY_ENABLED=1\n# PROXY_URL=http://username:password@proxy.company.com:8080\n\n# Example 4: No proxy (direct connection)\n# PROXY_ENABLED=0\n# PROXY_URL=\n"
  },
  {
    "path": "pyproject.toml",
    "content": "[project]\nname = \"ace-step\"\nversion = \"1.5.0\"\ndescription = \"ACE-Step 1.5\"\nreadme = \"README.md\"\nrequires-python = \">=3.11,<3.13\"\nlicense = {text = \"MIT\"}\ndependencies = [\n    # PyTorch for Windows with CUDA 12.8\n    \"torch==2.7.1+cu128; sys_platform == 'win32'\",\n    \"torchvision==0.22.1+cu128; sys_platform == 'win32'\",\n    \"torchaudio==2.7.1+cu128; sys_platform == 'win32'\",\n    # PyTorch for Linux x86_64 with CUDA 12.8\n    \"torch==2.10.0+cu128; sys_platform == 'linux' and platform_machine == 'x86_64'\",\n    \"torchvision==0.25.0+cu128; sys_platform == 'linux' and platform_machine == 'x86_64'\",\n    \"torchaudio==2.10.0+cu128; sys_platform == 'linux' and platform_machine == 'x86_64'\",\n    # PyTorch for Linux aarch64 with CUDA 13.0 (e.g. NVIDIA DGX Spark)\n    \"torch==2.10.0+cu130; sys_platform == 'linux' and platform_machine == 'aarch64'\",\n    \"torchvision==0.25.0+cu130; sys_platform == 'linux' and platform_machine == 'aarch64'\",\n    \"torchaudio==2.10.0+cu130; sys_platform == 'linux' and platform_machine == 'aarch64'\",\n    # PyTorch for macOS (CPU / MPS)\n    \"torch>=2.9.1; sys_platform == 'darwin' and platform_machine == 'arm64'\",\n    \"torchvision; sys_platform == 'darwin' and platform_machine == 'arm64'\",\n    \"torchaudio>=2.9.1; sys_platform == 'darwin' and platform_machine == 'arm64'\",\n    # Common dependencies\n    \"transformers>=4.51.0,<4.58.0\",\n    \"diffusers\",\n    \"gradio==6.2.0\",\n    \"matplotlib>=3.7.5\",\n    \"scipy>=1.10.1\",\n    \"soundfile>=0.13.1\",\n    \"loguru>=0.7.3\",\n    \"einops>=0.8.1\",\n    \"accelerate>=1.12.0\",\n    \"fastapi>=0.110.0\",\n    \"diskcache\",\n    \"uvicorn[standard]>=0.27.0\",\n    \"numba>=0.63.1\",\n    \"vector-quantize-pytorch>=1.27.15\",\n    \"torchcodec>=0.9.1; platform_machine != 'aarch64'\",\n    \"torchao>=0.14.1,<0.16.0; platform_machine != 'aarch64'\",\n    \"torchao; platform_machine == 'aarch64'\",\n    \"toml\",\n    # MLX dependencies (Apple Silicon native acceleration - macOS only)\n    \"mlx>=0.25.2; sys_platform == 'darwin' and platform_machine == 'arm64'\",\n    \"mlx-lm>=0.20.0; sys_platform == 'darwin' and platform_machine == 'arm64'\",\n    # Training dependencies\n    \"peft>=0.18.0\",\n    \"lycoris-lora\",\n    \"lightning>=2.0.0\",\n    \"tensorboard>=2.0.0\",\n    # Local third-party packages\n    # nano-vllm source is configured in [tool.uv.sources]\n    \"nano-vllm; sys_platform != 'darwin' or platform_machine != 'arm64'\",\n    \"modelscope\",\n    \"tensorboard>=2.20.0\",\n    \"typer-slim>=0.21.1\",\n]\n\n[[tool.uv.index]]\nname = \"pytorch-cu128\"\nurl = \"https://download.pytorch.org/whl/cu128\"\nexplicit = true\n\n[[tool.uv.index]]\nname = \"pytorch-cu130\"\nurl = \"https://download.pytorch.org/whl/cu130\"\nexplicit = true\n\n[tool.uv]\nrequired-environments = [\n    \"sys_platform == 'win32' and platform_machine == 'AMD64'\",\n    \"sys_platform == 'linux' and platform_machine == 'x86_64'\",\n    \"sys_platform == 'linux' and platform_machine == 'aarch64'\",\n    \"sys_platform == 'darwin' and platform_machine == 'arm64'\",\n]\n\n[tool.uv.sources]\nnano-vllm = { path = \"acestep/third_parts/nano-vllm\" }\ntorch = [\n    { index = \"pytorch-cu128\", marker = \"sys_platform == 'win32' or (sys_platform == 'linux' and platform_machine == 'x86_64')\" },\n    { index = \"pytorch-cu130\", marker = \"sys_platform == 'linux' and platform_machine == 'aarch64'\" },\n]\ntorchvision = [\n    { index = \"pytorch-cu128\", marker = \"sys_platform == 'win32' or (sys_platform == 'linux' and platform_machine == 'x86_64')\" },\n    { index = \"pytorch-cu130\", marker = \"sys_platform == 'linux' and platform_machine == 'aarch64'\" },\n]\ntorchaudio = [\n    { index = \"pytorch-cu128\", marker = \"sys_platform == 'win32' or (sys_platform == 'linux' and platform_machine == 'x86_64')\" },\n    { index = \"pytorch-cu130\", marker = \"sys_platform == 'linux' and platform_machine == 'aarch64'\" },\n]\n\n[project.scripts]\nacestep = \"acestep.acestep_v15_pipeline:main\"\nacestep-api = \"acestep.api_server:main\"\nacestep-download = \"acestep.model_downloader:main\"\nacestep-openrouter = \"openrouter.openrouter_api_server:main\"\n\n[build-system]\nrequires = [\"hatchling\"]\nbuild-backend = \"hatchling.build\"\n\n[dependency-groups]\ndev = []\n\n[tool.hatch.build.targets.wheel]\npackages = [\"acestep\", \"openrouter\"]\n\n[tool.hatch.build.targets.wheel.force-include]\n\"acestep/ui/gradio/interfaces/audio_player_preferences.js\" = \"acestep/ui/gradio/interfaces/audio_player_preferences.js\"\n"
  },
  {
    "path": "quick_test.bat",
    "content": "@echo off\nsetlocal enabledelayedexpansion\n\nREM Quick test for PowerShell and uv installation\n\necho ========================================\necho Quick Environment Test\necho ========================================\necho.\n\nREM Test 1: Check PowerShell\necho [Test 1] Checking PowerShell...\npowershell -Command \"Write-Host 'PowerShell is available' -ForegroundColor Green; Write-Host 'Version:'; $PSVersionTable.PSVersion\" 2>nul\nif !ERRORLEVEL! EQU 0 (\n    echo [PASS] PowerShell is working\n) else (\n    echo [FAIL] PowerShell not available\n)\necho.\n\nREM Test 2: Check winget\necho [Test 2] Checking winget...\nwhere winget >nul 2>&1\nif !ERRORLEVEL! EQU 0 (\n    echo [PASS] winget found\n    winget --version\n) else (\n    echo [INFO] winget not found\n    echo Note: winget is available on Windows 10 1809+ and Windows 11\n)\necho.\n\nREM Test 3: Check python_embedded\necho [Test 3] Checking python_embedded...\nif exist \"%~dp0python_embedded\\python.exe\" (\n    echo [PASS] python_embedded found\n    \"%~dp0python_embedded\\python.exe\" --version\n) else (\n    echo [INFO] python_embedded not found\n)\necho.\n\nREM Test 4: Check uv\necho [Test 4] Checking uv...\nwhere uv >nul 2>&1\nif !ERRORLEVEL! EQU 0 (\n    echo [PASS] uv found in PATH\n    uv --version\n) else (\n    echo [INFO] uv not found in PATH\n    if exist \"%USERPROFILE%\\.local\\bin\\uv.exe\" (\n        echo [INFO] But uv.exe exists at: %USERPROFILE%\\.local\\bin\\uv.exe\n        \"%USERPROFILE%\\.local\\bin\\uv.exe\" --version\n    ) else (\n        if exist \"%LOCALAPPDATA%\\Microsoft\\WinGet\\Links\\uv.exe\" (\n            echo [INFO] But uv.exe exists at: %LOCALAPPDATA%\\Microsoft\\WinGet\\Links\\uv.exe\n            \"%LOCALAPPDATA%\\Microsoft\\WinGet\\Links\\uv.exe\" --version\n        ) else (\n            echo [INFO] uv not installed\n        )\n    )\n)\necho.\n\nREM Test 5: Test internet connectivity\necho [Test 5] Testing internet connectivity...\npowershell -NoProfile -Command \"try { $null = Invoke-WebRequest -Uri 'https://astral.sh' -UseBasicParsing -TimeoutSec 5; Write-Host '[PASS] Can access astral.sh' -ForegroundColor Green } catch { Write-Host '[FAIL] Cannot access astral.sh' -ForegroundColor Red; Write-Host 'Error:' $_.Exception.Message }\"\necho.\n\nREM Summary\necho ========================================\necho Summary\necho ========================================\necho.\n\nREM Determine which environment will be used\nset ENV_FOUND=0\n\nif exist \"%~dp0python_embedded\\python.exe\" (\n    echo [RESULT] Will use: python_embedded\n    echo No additional setup needed!\n    set ENV_FOUND=1\n)\n\nif !ENV_FOUND! EQU 0 (\n    where uv >nul 2>&1\n    if !ERRORLEVEL! EQU 0 (\n        echo [RESULT] Will use: uv ^(from PATH^)\n        echo No additional setup needed!\n        set ENV_FOUND=1\n    )\n)\n\nif !ENV_FOUND! EQU 0 (\n    if exist \"%USERPROFILE%\\.local\\bin\\uv.exe\" (\n        echo [RESULT] Will use: uv ^(not in PATH^)\n        echo Action: Add to PATH or restart terminal\n        set ENV_FOUND=1\n    )\n)\n\nif !ENV_FOUND! EQU 0 (\n    if exist \"%LOCALAPPDATA%\\Microsoft\\WinGet\\Links\\uv.exe\" (\n        echo [RESULT] Will use: uv ^(not in PATH^)\n        echo Action: Add to PATH or restart terminal\n        set ENV_FOUND=1\n    )\n)\n\nif !ENV_FOUND! EQU 0 (\n    echo [RESULT] No environment found\n    echo Action: Run start_gradio_ui.bat to install uv\n    echo Or: Download portable package\n)\n\necho.\necho ========================================\necho Press any key to close...\necho ========================================\npause >nul\n\nendlocal\n"
  },
  {
    "path": "quick_test.sh",
    "content": "#!/usr/bin/env bash\n# Quick Environment Test - Linux/macOS\n# This script tests the environment for ACE-Step\n\nset -euo pipefail\nSCRIPT_DIR=\"$(cd \"$(dirname \"${BASH_SOURCE[0]}\")\" && pwd)\"\n\necho \"========================================\"\necho \"Quick Environment Test\"\necho \"========================================\"\necho\n\nOS_NAME=\"$(uname)\"\nARCH=\"$(uname -m)\"\necho \"[Info] OS: $OS_NAME ($ARCH)\"\necho\n\n# Test 1: Check Python\necho \"[Test 1] Checking Python...\"\nif command -v python3 &>/dev/null; then\n    echo \"[PASS] Python3 found\"\n    python3 --version\nelif command -v python &>/dev/null; then\n    echo \"[PASS] Python found\"\n    python --version\nelse\n    echo \"[INFO] Python not found in PATH\"\nfi\necho\n\n# Test 2: Check uv\necho \"[Test 2] Checking uv...\"\nUV_FOUND=0\nif command -v uv &>/dev/null; then\n    echo \"[PASS] uv found in PATH\"\n    uv --version\n    UV_FOUND=1\nelse\n    echo \"[INFO] uv not found in PATH\"\n    if [[ -x \"$HOME/.local/bin/uv\" ]]; then\n        echo \"[INFO] But uv exists at: $HOME/.local/bin/uv\"\n        \"$HOME/.local/bin/uv\" --version\n        UV_FOUND=1\n    elif [[ -x \"$HOME/.cargo/bin/uv\" ]]; then\n        echo \"[INFO] But uv exists at: $HOME/.cargo/bin/uv\"\n        \"$HOME/.cargo/bin/uv\" --version\n        UV_FOUND=1\n    else\n        echo \"[INFO] uv not installed\"\n    fi\nfi\necho\n\n# Test 3: Check git\necho \"[Test 3] Checking git...\"\nif command -v git &>/dev/null; then\n    echo \"[PASS] git found\"\n    git --version\nelse\n    echo \"[INFO] git not found\"\n    if [[ \"$OS_NAME\" == \"Darwin\" ]]; then\n        echo \"Install: xcode-select --install  or  brew install git\"\n    else\n        echo \"Install: sudo apt install git  or  sudo yum install git\"\n    fi\nfi\necho\n\n# Test 4: Check GPU / accelerator\necho \"[Test 4] Checking GPU/accelerator...\"\nif [[ \"$OS_NAME\" == \"Darwin\" && \"$ARCH\" == \"arm64\" ]]; then\n    echo \"[PASS] Apple Silicon detected (MPS/MLX available)\"\n    # Check for MLX\n    if command -v python3 &>/dev/null; then\n        python3 -c \"import mlx; print(f'MLX version: {mlx.__version__}')\" 2>/dev/null && echo \"[PASS] MLX is available\" || echo \"[INFO] MLX not installed (will be installed by uv sync)\"\n    fi\nelif [[ \"$OS_NAME\" == \"Linux\" ]]; then\n    if command -v nvidia-smi &>/dev/null; then\n        echo \"[PASS] NVIDIA GPU detected\"\n        nvidia-smi --query-gpu=name,memory.total --format=csv,noheader 2>/dev/null || echo \"  (could not query GPU details)\"\n    else\n        echo \"[INFO] NVIDIA GPU not detected (nvidia-smi not found)\"\n        echo \"  CUDA is recommended for Linux. CPU mode may be very slow.\"\n    fi\nelse\n    echo \"[INFO] No known accelerator detected\"\nfi\necho\n\n# Test 5: Test internet connectivity\necho \"[Test 5] Testing internet connectivity...\"\nif command -v curl &>/dev/null; then\n    if curl -s --connect-timeout 5 -o /dev/null -w \"%{http_code}\" https://astral.sh 2>/dev/null | grep -q \"^[23]\"; then\n        echo \"[PASS] Can access astral.sh\"\n    else\n        echo \"[FAIL] Cannot access astral.sh\"\n    fi\nelif command -v wget &>/dev/null; then\n    if wget -q --spider --timeout=5 https://astral.sh 2>/dev/null; then\n        echo \"[PASS] Can access astral.sh\"\n    else\n        echo \"[FAIL] Cannot access astral.sh\"\n    fi\nelse\n    echo \"[INFO] Neither curl nor wget found, skipping connectivity test\"\nfi\necho\n\n# Test 6: Check pyproject.toml\necho \"[Test 6] Checking project configuration...\"\nif [[ -f \"$SCRIPT_DIR/pyproject.toml\" ]]; then\n    echo \"[PASS] pyproject.toml found\"\n    echo\n    echo \"Available scripts:\"\n    grep -E \"^(acestep|acestep-api|acestep-download) = \" \"$SCRIPT_DIR/pyproject.toml\" 2>/dev/null || echo \"  (scripts section not found)\"\nelse\n    echo \"[FAIL] pyproject.toml not found\"\nfi\necho\n\n# Summary\necho \"========================================\"\necho \"Summary\"\necho \"========================================\"\necho\n\nif [[ $UV_FOUND -eq 1 ]]; then\n    echo \"[RESULT] Environment: uv\"\n    echo \"  Ready to use!\"\n    if [[ \"$OS_NAME\" == \"Darwin\" && \"$ARCH\" == \"arm64\" ]]; then\n        echo \"  Recommended launcher: ./start_gradio_ui_macos.sh (MLX)\"\n    else\n        echo \"  Recommended launcher: ./start_gradio_ui.sh\"\n    fi\nelse\n    echo \"[RESULT] No environment found\"\n    echo \"  Action: Run ./install_uv.sh to install uv\"\nfi\necho\n"
  },
  {
    "path": "requirements-rocm-linux.txt",
    "content": "# Requirements ROCM\n# Core dependencies\ntransformers>=4.51.0,<4.58.0\ndiffusers\ngradio==6.2.0\nmatplotlib>=3.7.5\nscipy>=1.10.1\nsoundfile>=0.13.1\nloguru>=0.7.3\neinops>=0.8.1\naccelerate>=1.12.0\nfastapi>=0.110.0\nuvicorn[standard]>=0.27.0\nnumba>=0.63.1\nvector-quantize-pytorch>=1.27.15\n# torchcodec>=0.9.1  # Not supported on ROCM - soundfile fallback will be used\ntorchao\ntoml\nmodelscope\n\n# Training dependencies (required for LoRA training)\npeft>=0.18.0\nlightning>=2.0.0\ntensorboard>=2.0.0\nxxhash\n\n# Local package - install with: pip install -e acestep/third_parts/nano-vllm\n# nano-vllm\n"
  },
  {
    "path": "requirements-rocm.txt",
    "content": "# ACE-Step 1.5 - AMD ROCm 7.2 Windows Dependencies\n# =================================================\n# IMPORTANT: ROCm on Windows requires Python 3.12 (not 3.11)\n# AMD officially only provides Python 3.12 wheels for ROCm 7.2 on Windows\n# Requires: Windows 11, Python 3.12, AMD RX 7000+ or RX 6000+ GPU\n# AMD driver: 26.1.1 or later\n#\n# STEP 1: Install ROCm SDK components\n#   pip install --no-cache-dir ^\n#     https://repo.radeon.com/rocm/windows/rocm-rel-7.2/rocm_sdk_core-7.2.0.dev0-py3-none-win_amd64.whl ^\n#     https://repo.radeon.com/rocm/windows/rocm-rel-7.2/rocm_sdk_devel-7.2.0.dev0-py3-none-win_amd64.whl ^\n#     https://repo.radeon.com/rocm/windows/rocm-rel-7.2/rocm_sdk_libraries_custom-7.2.0.dev0-py3-none-win_amd64.whl ^\n#     https://repo.radeon.com/rocm/windows/rocm-rel-7.2/rocm-7.2.0.dev0.tar.gz\n#\n# STEP 2: Install PyTorch for ROCm\n#   pip install --no-cache-dir ^\n#     https://repo.radeon.com/rocm/windows/rocm-rel-7.2/torch-2.9.1+rocmsdk20260116-cp312-cp312-win_amd64.whl ^\n#     https://repo.radeon.com/rocm/windows/rocm-rel-7.2/torchaudio-2.9.1+rocmsdk20260116-cp312-cp312-win_amd64.whl ^\n#     https://repo.radeon.com/rocm/windows/rocm-rel-7.2/torchvision-0.24.1+rocmsdk20260116-cp312-cp312-win_amd64.whl\n#\n# STEP 3: Install these dependencies\n#   pip install -r requirements-rocm.txt\n#\n# STEP 4: Launch with ROCm launcher\n#   start_gradio_ui_rocm.bat\n\n# Core dependencies\ntransformers>=4.51.0,<4.58.0\ndiffusers\ngradio==6.2.0\nmatplotlib>=3.7.5\nscipy>=1.10.1\nsoundfile>=0.13.1\nloguru>=0.7.3\neinops>=0.8.1\naccelerate>=1.12.0\nfastapi>=0.110.0\nuvicorn[standard]>=0.27.0\nnumba>=0.63.1\nvector-quantize-pytorch>=1.27.15\n# torchao excluded: imports torch.distributed which isn't available in ROCm Windows builds\n# Quantization features (--quantization flag) will not be available\nmodelscope\n\n# Training dependencies (optional - for LoRA fine-tuning)\npeft>=0.18.0\nlightning>=2.0.0\ntensorboard>=2.0.0\n\n# nano-vllm tokenizer dependency (needed even with pt backend)\nxxhash\n"
  },
  {
    "path": "requirements-sidestep.txt",
    "content": "# ╔══════════════════════════════════════════════════════════════╗\n# ║  Side-Step -- Extra dependencies for ACE-Step LoRA training ║\n# ║  Install: pip install -r requirements-sidestep.txt          ║\n# ╚══════════════════════════════════════════════════════════════╝\n#\n# Side-Step is a companion CLI/TUI for ACE-Step.\n# Install ACE-Step's own requirements first, then these.\n\n# ── Required for Side-Step CLI ────────────────────────────────\nrich>=13.0.0\n\n# ── Required for Side-Step TUI ────────────────────────────────\ntextual>=0.47.0\n\n# ── Optional: 8-bit optimizers (saves ~30-40% optimizer VRAM) ─\n# Uncomment to enable AdamW8bit in the optimizer selector.\n# Supports Linux and Windows (official wheels).\n# bitsandbytes>=0.45.0\n\n# ── Optional: Prodigy adaptive optimizer (auto-tunes LR) ─────\n# Uncomment to enable the Prodigy optimizer.\n# Great if you don't want to manually tune learning rate.\n# prodigyopt>=1.1.2\n"
  },
  {
    "path": "requirements-xpu.txt",
    "content": "# PyTorch with Intel XPU/GPU support (for Windows/Linux)\n--extra-index-url https://download.pytorch.org/whl/xpu\ntorch; sys_platform == 'win32'\ntorchaudio; sys_platform == 'win32'\ntorchvision; sys_platform == 'win32'\n\n# Core dependencies\ntransformers>=4.51.0,<4.58.0\ndiffusers\ngradio==6.2.0\nmatplotlib>=3.7.5\nscipy>=1.10.1\nsoundfile>=0.13.1\nloguru>=0.7.3\neinops>=0.8.1\naccelerate>=1.12.0\nfastapi>=0.110.0\nuvicorn[standard]>=0.27.0\nnumba>=0.63.1\nvector-quantize-pytorch>=1.27.15\n# torchcodec>=0.9.1  # Not supported on Intel XPU - soundfile fallback will be used\ntorchao<0.16.0\nmodelscope\n\n# LoRA Training dependencies (optional)\npeft>=0.18.0\nlightning>=2.0.0\n"
  },
  {
    "path": "requirements.txt",
    "content": "# PyTorch with CUDA 12.8 / 13.0\nsafetensors==0.7.0\n--extra-index-url https://download.pytorch.org/whl/cu128\n--extra-index-url https://download.pytorch.org/whl/cu130\ntorch==2.7.1+cu128; sys_platform == 'win32'\ntorchvision==0.22.1+cu128; sys_platform == 'win32'\ntorchaudio==2.7.1+cu128; sys_platform == 'win32'\n# macOS arm64 (Apple Silicon): latest CPU/MPS wheels\ntorch>=2.9.1; sys_platform == 'darwin' and platform_machine == 'arm64'\ntorchaudio>=2.9.1; sys_platform == 'darwin' and platform_machine == 'arm64'\ntorchvision; sys_platform == 'darwin' and platform_machine == 'arm64'\n# Linux x86_64 with CUDA 12.8\ntorch==2.10.0+cu128; sys_platform == 'linux' and platform_machine == 'x86_64'\ntorchvision==0.25.0+cu128; sys_platform == 'linux' and platform_machine == 'x86_64'\ntorchaudio==2.10.0+cu128; sys_platform == 'linux' and platform_machine == 'x86_64'\n# Linux aarch64 with CUDA 13.0 (e.g. NVIDIA DGX Spark)\ntorch==2.10.0+cu130; sys_platform == 'linux' and platform_machine == 'aarch64'\ntorchvision==0.25.0+cu130; sys_platform == 'linux' and platform_machine == 'aarch64'\ntorchaudio==2.10.0+cu130; sys_platform == 'linux' and platform_machine == 'aarch64'\n\n# Core dependencies\ntransformers>=4.51.0,<4.58.0\ndiffusers\ngradio==6.2.0\nmatplotlib>=3.7.5\nscipy>=1.10.1\nsoundfile>=0.13.1\nloguru>=0.7.3\neinops>=0.8.1\naccelerate>=1.12.0\nfastapi>=0.110.0\nuvicorn[standard]>=0.27.0\nnumba>=0.63.1\nvector-quantize-pytorch>=1.27.15\ntorchcodec>=0.9.1; platform_machine != 'aarch64'\ntorchao\ntoml\nmodelscope\n\n# Training dependencies (required for LoRA/LoKr training)\npeft>=0.18.0\nlycoris-lora\nlightning>=2.0.0\ntensorboard>=2.0.0\n\n# MLX dependencies (Apple Silicon native acceleration - macOS only)\n# Provides significant speedup for LLM inference on Apple Silicon GPUs\nmlx>=0.25.2; sys_platform == 'darwin' and platform_machine == 'arm64'\nmlx-lm>=0.20.0; sys_platform == 'darwin' and platform_machine == 'arm64'\n\n# nano-vllm dependencies\ntriton-windows>=3.0.0,<3.4; sys_platform == 'win32'\ntriton>=3.0.0; sys_platform == 'linux'\nflash-attn @ https://github.com/sdbds/flash-attention-for-windows/releases/download/2.8.2/flash_attn-2.8.2+cu128torch2.7.1cxx11abiFALSEfullbackward-cp311-cp311-win_amd64.whl ; sys_platform == 'win32' and python_version == '3.11' and platform_machine == 'AMD64'\nflash-attn; sys_platform == 'linux' and platform_machine == 'x86_64'\nxxhash\n\n# Local package - install with: pip install -e acestep/third_parts/nano-vllm\n# nano-vllm\n"
  },
  {
    "path": "run_api_server.sh",
    "content": "#!/usr/bin/env bash\nset -euo pipefail\n\nROOT_DIR=\"$(cd \"$(dirname \"${BASH_SOURCE[0]}\")\" && pwd)\"\n\nCONDA_ACTIVATE=\"${CONDA_ACTIVATE:-/root/data/repo/gongjunmin/miniconda3/bin/activate}\"\nCONDA_ENV_NAME=\"${ACESTEP_CONDA_ENV:-acestep_v15_train}\"\n\nHOST=\"${ACESTEP_API_HOST:-0.0.0.0}\"\nPORT=\"${ACESTEP_API_PORT:-8001}\"\nLOG_LEVEL=\"${ACESTEP_API_LOG_LEVEL:-debug}\"\n\ncd \"$ROOT_DIR\"\n\n# 临时关闭 nounset 以避免 conda activate.d 脚本中的 unbound variable 错误\nset +u\n# shellcheck disable=SC1090\nsource \"$CONDA_ACTIVATE\" \"$CONDA_ENV_NAME\"\nset -u\n\n# NOTE: api_server 使用内存队列/任务存储，要求 workers=1。\nnohup python -m uvicorn acestep.api_server:app \\\n\t--host \"0.0.0.0\" \\\n\t--port \"8001\" \\\n\t--workers 1 \\\n\t--log-level \"$LOG_LEVEL\" > server.log 2>&1 &\necho \"Server started in background with PID $!. Logs in server.log\""
  },
  {
    "path": "run_openrouter_api_server.sh",
    "content": "#!/usr/bin/env bash\nset -euo pipefail\n\nROOT_DIR=\"$(cd \"$(dirname \"${BASH_SOURCE[0]}\")\" && pwd)\"\n\nCONDA_ACTIVATE=\"${CONDA_ACTIVATE:-/root/data/repo/gongjunmin/miniconda3/bin/activate}\"\nCONDA_ENV_NAME=\"${ACESTEP_CONDA_ENV:-acestep_v15_train}\"\n\nHOST=\"${ACESTEP_API_HOST:-0.0.0.0}\"\nPORT=\"${ACESTEP_API_PORT:-8001}\"\nLOG_LEVEL=\"${ACESTEP_API_LOG_LEVEL:-debug}\"\n\ncd \"$ROOT_DIR\"\n\n# 临时关闭 nounset 以避免 conda activate.d 脚本中的 unbound variable 错误\nset +u\n# shellcheck disable=SC1090\nsource \"$CONDA_ACTIVATE\" \"$CONDA_ENV_NAME\"\nset -u\n\n# NOTE: api_server 使用内存队列/任务存储，要求 workers=1。\nnohup python -m uvicorn openrouter.openrouter_api_server:app \\\n\t--host \"0.0.0.0\" \\\n\t--port \"8002\" \\\n\t--workers 1 \\\n\t--log-level \"$LOG_LEVEL\" > server.log 2>&1 &\necho \"Server started in background with PID $!. Logs in server.log\""
  },
  {
    "path": "scripts/check_gpu.py",
    "content": "#!/usr/bin/env python3\n\"\"\"\nGPU Detection Diagnostic Tool for ACE-Step\n\nThis script helps diagnose GPU detection issues by checking:\n- PyTorch installation and build type (CUDA/ROCm/CPU)\n- GPU availability and properties\n- Environment variables\n- Common configuration issues\n\nUsage:\n    python scripts/check_gpu.py\n\"\"\"\n\nimport os\nimport sys\nimport subprocess\n\n# Constants\nHEADER_WIDTH = 80\nPYTORCH_CUDA_INSTALL_URL = \"https://download.pytorch.org/whl/cu121\"\nPYTORCH_ROCM_INSTALL_URL = \"https://download.pytorch.org/whl/rocm6.0\"\n\n\ndef print_section(title):\n    \"\"\"Print a section header.\"\"\"\n    print(f\"\\n{'=' * HEADER_WIDTH}\")\n    print(f\"  {title}\")\n    print('=' * HEADER_WIDTH)\n\n\ndef check_pytorch():\n    \"\"\"Check PyTorch installation and build type.\"\"\"\n    print_section(\"PyTorch Installation\")\n    \n    try:\n        import torch\n        print(f\"✓ PyTorch installed: {torch.__version__}\")\n        \n        # Check build type\n        is_rocm = hasattr(torch.version, 'hip') and torch.version.hip is not None\n        is_cuda = hasattr(torch.version, 'cuda') and torch.version.cuda is not None\n        \n        if is_rocm:\n            print(f\"✓ Build type: ROCm (HIP {torch.version.hip})\")\n        elif is_cuda:\n            print(f\"✓ Build type: CUDA {torch.version.cuda}\")\n        else:\n            print(\"⚠️ Build type: CPU-only\")\n            print(\"\\n❌ You have installed a CPU-only version of PyTorch!\")\n            print(\"\\nTo enable GPU support:\")\n            print(\"  For NVIDIA GPUs:\")\n            print(f\"    pip install torch --index-url {PYTORCH_CUDA_INSTALL_URL}\")\n            print(\"\\n  For AMD GPUs with ROCm:\")\n            print(\"    Windows: See requirements-rocm.txt\")\n            print(f\"    Linux: pip install torch --index-url {PYTORCH_ROCM_INSTALL_URL}\")\n            return False\n        \n        return True\n    except ImportError:\n        print(\"❌ PyTorch not installed\")\n        print(\"\\nPlease install PyTorch first:\")\n        print(\"  pip install torch\")\n        return False\n\n\ndef check_cuda_availability():\n    \"\"\"Check CUDA/ROCm availability.\"\"\"\n    print_section(\"GPU Availability Check\")\n    \n    try:\n        import torch\n        \n        is_available = torch.cuda.is_available()\n        print(f\"torch.cuda.is_available(): {is_available}\")\n        \n        if is_available:\n            print(f\"✓ GPU detected!\")\n            device_count = torch.cuda.device_count()\n            print(f\"  Number of GPUs: {device_count}\")\n            \n            for i in range(device_count):\n                device_name = torch.cuda.get_device_name(i)\n                props = torch.cuda.get_device_properties(i)\n                memory_gb = props.total_memory / (1024**3)\n                print(f\"\\n  GPU {i}: {device_name}\")\n                print(f\"    Total memory: {memory_gb:.2f} GB\")\n                print(f\"    Compute capability: {props.major}.{props.minor}\")\n            \n            return True\n        else:\n            print(\"❌ No GPU detected by PyTorch\")\n            return False\n            \n    except Exception as e:\n        print(f\"❌ Error checking GPU availability: {e}\")\n        return False\n\n\ndef check_rocm_setup():\n    \"\"\"Check ROCm-specific setup for AMD GPUs.\"\"\"\n    print_section(\"ROCm Configuration (AMD GPUs)\")\n    \n    try:\n        import torch\n        is_rocm = hasattr(torch.version, 'hip') and torch.version.hip is not None\n        \n        if not is_rocm:\n            print(\"Skipping - not a ROCm build\")\n            return\n        \n        print(\"Checking ROCm environment variables:\")\n        \n        # Check HSA_OVERRIDE_GFX_VERSION\n        hsa_override = os.environ.get('HSA_OVERRIDE_GFX_VERSION')\n        if hsa_override:\n            print(f\"  ✓ HSA_OVERRIDE_GFX_VERSION = {hsa_override}\")\n        else:\n            print(\"  ⚠️ HSA_OVERRIDE_GFX_VERSION not set\")\n            print(\"\\n  This variable is required for many AMD GPUs!\")\n            print(\"  Set it according to your GPU:\")\n            print(\"    RX 7900 XT/XTX, RX 9070 XT: HSA_OVERRIDE_GFX_VERSION=11.0.0\")\n            print(\"    RX 7800 XT, RX 7700 XT: HSA_OVERRIDE_GFX_VERSION=11.0.1\")\n            print(\"    RX 7600: HSA_OVERRIDE_GFX_VERSION=11.0.2\")\n            print(\"    RX 6000 series: HSA_OVERRIDE_GFX_VERSION=10.3.0\")\n        \n        # Check MIOPEN_FIND_MODE\n        miopen_mode = os.environ.get('MIOPEN_FIND_MODE')\n        if miopen_mode:\n            print(f\"  ✓ MIOPEN_FIND_MODE = {miopen_mode}\")\n        else:\n            print(\"  ℹ️ MIOPEN_FIND_MODE not set (recommended: FAST)\")\n        \n        # Try to run rocm-smi\n        print(\"\\nChecking ROCm system management interface:\")\n        try:\n            result = subprocess.run(['rocm-smi'], capture_output=True, text=True, timeout=5)\n            if result.returncode == 0:\n                print(\"  ✓ rocm-smi found and working\")\n                print(\"\\n  Output (first 10 lines):\")\n                lines = result.stdout.split('\\n')[:10]\n                for line in lines:\n                    if line.strip():\n                        print(f\"    {line}\")\n            else:\n                print(\"  ⚠️ rocm-smi found but returned error\")\n        except FileNotFoundError:\n            print(\"  ❌ rocm-smi not found in PATH\")\n            print(\"     This suggests ROCm is not properly installed\")\n        except Exception as e:\n            print(f\"  ⚠️ Error running rocm-smi: {e}\")\n            \n    except ImportError:\n        print(\"❌ PyTorch not installed\")\n\n\ndef check_nvidia_setup():\n    \"\"\"Check NVIDIA CUDA setup.\"\"\"\n    print_section(\"NVIDIA CUDA Configuration\")\n    \n    try:\n        import torch\n        is_cuda = hasattr(torch.version, 'cuda') and torch.version.cuda is not None\n        \n        if not is_cuda:\n            print(\"Skipping - not a CUDA build\")\n            return\n        \n        print(f\"CUDA version in PyTorch: {torch.version.cuda}\")\n        \n        # Try to run nvidia-smi\n        print(\"\\nChecking NVIDIA System Management Interface:\")\n        try:\n            result = subprocess.run(['nvidia-smi'], capture_output=True, text=True, timeout=5)\n            if result.returncode == 0:\n                print(\"  ✓ nvidia-smi found and working\")\n                print(\"\\n  Output (first 15 lines):\")\n                lines = result.stdout.split('\\n')[:15]\n                for line in lines:\n                    if line.strip():\n                        print(f\"    {line}\")\n            else:\n                print(\"  ⚠️ nvidia-smi found but returned error\")\n        except FileNotFoundError:\n            print(\"  ❌ nvidia-smi not found in PATH\")\n            print(\"     This suggests NVIDIA drivers are not properly installed\")\n        except Exception as e:\n            print(f\"  ⚠️ Error running nvidia-smi: {e}\")\n            \n    except ImportError:\n        print(\"❌ PyTorch not installed\")\n\n\ndef check_ace_step_env():\n    \"\"\"Check ACE-Step specific environment variables.\"\"\"\n    print_section(\"ACE-Step Environment Variables\")\n    \n    relevant_vars = [\n        'MAX_CUDA_VRAM',\n        'HSA_OVERRIDE_GFX_VERSION',\n        'MIOPEN_FIND_MODE',\n        'TORCH_COMPILE_BACKEND',\n        'ACESTEP_LM_BACKEND',\n    ]\n    \n    found_any = False\n    for var in relevant_vars:\n        value = os.environ.get(var)\n        if value:\n            print(f\"  {var} = {value}\")\n            found_any = True\n    \n    if not found_any:\n        print(\"  No ACE-Step specific environment variables set\")\n\n\ndef print_recommendations():\n    \"\"\"Print recommendations based on detected issues.\"\"\"\n    print_section(\"Recommendations\")\n    \n    try:\n        import torch\n        \n        is_rocm = hasattr(torch.version, 'hip') and torch.version.hip is not None\n        is_cuda = hasattr(torch.version, 'cuda') and torch.version.cuda is not None\n        is_available = torch.cuda.is_available()\n        \n        if is_available:\n            print(\"✓ Your GPU setup appears to be working correctly!\")\n            print(\"\\nYou can now run ACE-Step with GPU acceleration.\")\n        elif is_rocm:\n            print(\"❌ ROCm build detected but GPU not available\")\n            print(\"\\nTroubleshooting steps for AMD GPUs:\")\n            print(\"  1. Set HSA_OVERRIDE_GFX_VERSION for your GPU model (see above)\")\n            print(\"  2. Verify ROCm installation with: rocm-smi\")\n            print(\"  3. Check that your GPU is supported by your ROCm version\")\n            print(\"  4. On Windows: Use start_gradio_ui_rocm.bat which sets all required variables\")\n            print(\"  5. On Linux: See docs/en/ACE-Step1.5-Rocm-Manual-Linux.md\")\n            print(\"\\nFor RX 9070 XT specifically:\")\n            print(\"  export HSA_OVERRIDE_GFX_VERSION=11.0.0\")\n            print(\"  or on Windows: set HSA_OVERRIDE_GFX_VERSION=11.0.0\")\n        elif is_cuda:\n            print(\"❌ CUDA build detected but GPU not available\")\n            print(\"\\nTroubleshooting steps for NVIDIA GPUs:\")\n            print(\"  1. Install NVIDIA drivers from https://www.nvidia.com/download/index.aspx\")\n            print(\"  2. Verify installation with: nvidia-smi\")\n            print(\"  3. Ensure CUDA version compatibility between driver and PyTorch\")\n        else:\n            print(\"❌ CPU-only PyTorch build detected\")\n            print(\"\\nYou need to reinstall PyTorch with GPU support:\")\n            print(\"\\nFor NVIDIA GPUs:\")\n            print(\"  pip uninstall torch torchvision torchaudio\")\n            print(f\"  pip install torch torchvision torchaudio --index-url {PYTORCH_CUDA_INSTALL_URL}\")\n            print(\"\\nFor AMD GPUs:\")\n            print(\"  Windows: Follow instructions in requirements-rocm.txt\")\n            print(f\"  Linux: pip install torch --index-url {PYTORCH_ROCM_INSTALL_URL}\")\n            \n    except ImportError:\n        print(\"❌ PyTorch not installed\")\n        print(\"\\nPlease install PyTorch first. See README.md for instructions.\")\n\n\ndef main():\n    \"\"\"Main diagnostic routine.\"\"\"\n    print(\"=\" * HEADER_WIDTH)\n    print(\"  ACE-Step GPU Detection Diagnostic Tool\")\n    print(\"=\" * HEADER_WIDTH)\n    print(\"\\nThis tool will help diagnose GPU detection issues.\")\n    print(\"Please share the output with support when reporting issues.\")\n    \n    # Run all checks\n    pytorch_ok = check_pytorch()\n    \n    if pytorch_ok:\n        gpu_ok = check_cuda_availability()\n        check_rocm_setup()\n        check_nvidia_setup()\n        check_ace_step_env()\n    \n    print_recommendations()\n    \n    print(\"\\n\" + \"=\" * HEADER_WIDTH)\n    print(\"  Diagnostic Complete\")\n    print(\"=\" * HEADER_WIDTH)\n\n\nif __name__ == \"__main__\":\n    main()\n"
  },
  {
    "path": "scripts/fetch-awesome.mjs",
    "content": "#!/usr/bin/env node\n/**\n * Fetches the awesome-ace-step README from GitHub at build time\n * and writes it to docs/en/awesome.md with VitePress frontmatter.\n */\nimport { writeFileSync, mkdirSync } from 'fs'\nimport { dirname } from 'path'\n\nconst RAW_URL = 'https://raw.githubusercontent.com/ace-step/awesome-ace-step/main/README.md'\nconst OUTPUT = 'docs/en/awesome.md'\n\nconst FRONTMATTER = `---\n# This file is auto-generated at build time from https://github.com/ace-step/awesome-ace-step\n# Do not edit manually — changes will be overwritten on next build.\neditLink: false\nlastUpdated: false\n---\n\n<script setup>\nconst updated = new Date().toISOString().slice(0, 10)\n</script>\n\n::: tip Auto-synced from GitHub\nThis page is automatically pulled from [ace-step/awesome-ace-step](https://github.com/ace-step/awesome-ace-step) at build time.\nLast synced: {{ updated }}\n:::\n\n`\n\nasync function main() {\n  try {\n    const res = await fetch(RAW_URL)\n    if (!res.ok) throw new Error(`HTTP ${res.status}`)\n    let content = await res.text()\n\n    // Remove the awesome badge line from title (already shown in sidebar)\n    content = content.replace(/^#\\s+Awesome ACE-Step.*\\n/m, '# Awesome ACE-Step\\n')\n\n    mkdirSync(dirname(OUTPUT), { recursive: true })\n    writeFileSync(OUTPUT, FRONTMATTER + content, 'utf-8')\n    console.log(`✓ Fetched awesome-ace-step README → ${OUTPUT}`)\n  } catch (err) {\n    console.error(`✗ Failed to fetch awesome-ace-step: ${err.message}`)\n    // Write a fallback so build doesn't break\n    const fallback = FRONTMATTER + `# Awesome ACE-Step\\n\\nFailed to fetch content. Visit [awesome-ace-step on GitHub](https://github.com/ace-step/awesome-ace-step) directly.\\n`\n    mkdirSync(dirname(OUTPUT), { recursive: true })\n    writeFileSync(OUTPUT, fallback, 'utf-8')\n    console.log(`✓ Wrote fallback → ${OUTPUT}`)\n  }\n}\n\nmain()\n"
  },
  {
    "path": "scripts/lora_data_prepare/elevenlabs_transcription.py",
    "content": "\"\"\"ElevenLabs Scribe transcription service.\n\nTranscribe audio to lyrics text using ElevenLabs Scribe API.\nUses word-level timestamps for intelligent line breaking,\nthen outputs plain text without timestamps.\n\"\"\"\n\nimport os\nfrom typing import Optional, List, Dict, Any\nfrom pathlib import Path\n\nimport requests\n\n\ndef is_cjk(ch: str) -> bool:\n    cp = ord(ch)\n    return (0x4E00 <= cp <= 0x9FFF or 0x3400 <= cp <= 0x4DBF or\n            0x20000 <= cp <= 0x2A6DF or 0x2A700 <= cp <= 0x2B73F or\n            0x2B740 <= cp <= 0x2B81F or 0x2B820 <= cp <= 0x2CEAF or\n            0xF900 <= cp <= 0xFAFF or 0x2F800 <= cp <= 0x2FA1F or\n            0x3000 <= cp <= 0x303F or 0x3040 <= cp <= 0x309F or\n            0x30A0 <= cp <= 0x30FF or 0xFF00 <= cp <= 0xFFEF)\n\n\ndef smart_join(word_list: List[str]) -> str:\n    if not word_list:\n        return \"\"\n    result = word_list[0]\n    for j in range(1, len(word_list)):\n        prev_last = word_list[j - 1][-1] if word_list[j - 1] else \"\"\n        curr_first = word_list[j][0] if word_list[j] else \"\"\n        if is_cjk(prev_last) or is_cjk(curr_first):\n            result += word_list[j]\n        else:\n            result += \" \" + word_list[j]\n    return result.strip()\n\n\ndef words_to_lyrics(words: List[Dict[str, Any]], line_gap: float = 1.5) -> str:\n    \"\"\"Convert word-level timestamps to plain lyrics text.\n\n    Uses timestamps to detect line breaks (by punctuation or time gaps),\n    then outputs text only.\n    \"\"\"\n    if not words:\n        return \"\"\n    lines = []\n    current_line = []\n\n    for i, w in enumerate(words):\n        current_line.append(w[\"word\"])\n        is_last = (i == len(words) - 1)\n        has_punct = w[\"word\"].rstrip().endswith((\".\", \"!\", \"?\", \"\\u3002\", \"\\uff01\", \"\\uff1f\", \"\\uff0c\", \",\"))\n        has_gap = (not is_last and words[i + 1][\"start\"] - w[\"end\"] > line_gap)\n\n        if is_last or has_punct or has_gap:\n            text = smart_join(current_line)\n            text = text.rstrip(\"\\uff0c\\u3002,.\")\n            if text:\n                lines.append(text)\n            current_line = []\n\n    return \"\\n\".join(lines) + \"\\n\"\n\n\ndef transcribe_elevenlabs(\n    audio_path: str,\n    api_key: str,\n    api_url: str = \"https://api.elevenlabs.io/v1\",\n    model: str = \"scribe_v2\",\n    language: Optional[str] = None,\n) -> List[Dict[str, Any]]:\n    \"\"\"Transcribe audio using ElevenLabs Scribe API.\n\n    Args:\n        audio_path: Path to the audio file\n        api_key: ElevenLabs API key\n        api_url: ElevenLabs API base URL\n        model: Scribe model name\n        language: Optional language code (e.g. \"zh\", \"en\", \"ja\")\n\n    Returns:\n        List of word-level timestamps [{word, start, end}, ...]\n    \"\"\"\n    if not os.path.exists(audio_path):\n        raise FileNotFoundError(f\"Audio file not found: {audio_path}\")\n\n    url = f\"{api_url.rstrip('/')}/speech-to-text\"\n    headers = {\"xi-api-key\": api_key}\n\n    data = {\"model_id\": model}\n    if language:\n        data[\"language_code\"] = language\n\n    with open(audio_path, \"rb\") as f:\n        files = {\"file\": (Path(audio_path).name, f)}\n        response = requests.post(url, headers=headers, data=data, files=files, timeout=300)\n\n    if response.status_code != 200:\n        error_msg = \"Unknown error\"\n        try:\n            err = response.json()\n            error_msg = err.get(\"detail\", {}).get(\"message\", \"\") or err.get(\"detail\", error_msg)\n        except Exception:\n            pass\n        raise RuntimeError(f\"ElevenLabs API error (HTTP {response.status_code}): {error_msg}\")\n\n    result = response.json()\n    # ElevenLabs returns {text, words: [{text, start, end, type}, ...]}\n    # Filter only \"word\" type entries and normalize field names\n    words = [\n        {\"word\": w[\"text\"], \"start\": w[\"start\"], \"end\": w[\"end\"]}\n        for w in result.get(\"words\", [])\n        if w.get(\"type\") == \"word\"\n    ]\n    return words\n\n\nAUDIO_EXTENSIONS = {\".mp3\", \".wav\", \".flac\", \".ogg\", \".aac\", \".aiff\"}\n\n\ndef transcribe_to_file(\n    audio_path: str,\n    output_path: str,\n    api_key: str,\n    api_url: str = \"https://api.elevenlabs.io/v1\",\n    model: str = \"scribe_v2\",\n    language: Optional[str] = None,\n    line_gap: float = 1.5,\n) -> str:\n    \"\"\"Transcribe audio and save plain lyrics text to file.\n\n    Args:\n        audio_path: Path to the audio file\n        output_path: Path to save the output txt file\n        api_key: ElevenLabs API key\n        api_url: ElevenLabs API base URL\n        model: Scribe model name\n        language: Optional language code\n        line_gap: Gap threshold (seconds) for line breaking\n\n    Returns:\n        Path to the output file\n    \"\"\"\n    words = transcribe_elevenlabs(audio_path, api_key, api_url, model, language)\n\n    if not words:\n        raise RuntimeError(\"No word-level timestamps returned from ElevenLabs API\")\n\n    content = words_to_lyrics(words, line_gap)\n\n    os.makedirs(os.path.dirname(output_path) or \".\", exist_ok=True)\n\n    with open(output_path, \"w\", encoding=\"utf-8\") as f:\n        f.write(content)\n\n    return output_path\n\n\ndef process_folder(\n    input_dir: str,\n    output_dir: str,\n    api_key: str,\n    api_url: str = \"https://api.elevenlabs.io/v1\",\n    model: str = \"scribe_v2\",\n    language: Optional[str] = None,\n    line_gap: float = 1.5,\n) -> List[str]:\n    \"\"\"Transcribe all audio files in a folder.\n\n    Args:\n        input_dir: Directory containing audio files\n        output_dir: Directory to save output txt files\n        api_key: ElevenLabs API key\n        api_url: ElevenLabs API base URL\n        model: Scribe model name\n        language: Optional language code\n        line_gap: Gap threshold (seconds) for line breaking\n\n    Returns:\n        List of output file paths\n    \"\"\"\n    input_path = Path(input_dir)\n    if not input_path.is_dir():\n        raise NotADirectoryError(f\"Input directory not found: {input_dir}\")\n\n    os.makedirs(output_dir, exist_ok=True)\n\n    audio_files = sorted(\n        f for f in input_path.iterdir()\n        if f.is_file() and f.suffix.lower() in AUDIO_EXTENSIONS\n    )\n\n    if not audio_files:\n        print(f\"No audio files found in {input_dir}\")\n        return []\n\n    output_paths = []\n    for i, audio_file in enumerate(audio_files, 1):\n        output_file = Path(output_dir) / f\"{audio_file.stem}.lyrics.txt\"\n        print(f\"[{i}/{len(audio_files)}] {audio_file.name}\")\n\n        try:\n            transcribe_to_file(\n                audio_path=str(audio_file),\n                output_path=str(output_file),\n                api_key=api_key,\n                api_url=api_url,\n                model=model,\n                language=language,\n                line_gap=line_gap,\n            )\n            output_paths.append(str(output_file))\n            print(f\"  -> {output_file.name}\")\n        except Exception as e:\n            print(f\"  Error: {e}\")\n\n    print(f\"Done: {len(output_paths)}/{len(audio_files)} files processed\")\n    return output_paths\n"
  },
  {
    "path": "scripts/lora_data_prepare/gemini_caption.py",
    "content": "\"\"\"Gemini service for audio analysis via the Gemini API.\n\nThis module provides a service for interacting with Gemini's API,\nsupporting audio inputs, file uploads, streaming, and structured outputs.\n\"\"\"\n\nimport os\nimport base64\nimport json\nimport mimetypes\nfrom typing import Optional, List, Dict, Any, Tuple, Union, Generator\nfrom pathlib import Path\n\nimport requests\n\nprompt = \"\"\"Analyze the input audio to generate detailed caption and lyrics. \nlyrics need contain structured tags for chorus, verse, bridge, etc.\n**Output Format:**\n```json\n{\n    \"caption\": <str>,\n    \"lyrics\": \"[Intro] <str>, [Verse] <str>...\"\n}\n```\n\"\"\"\n\n\nclass GeminiService:\n    \"\"\"Service for handling Gemini API audio interactions.\"\"\"\n\n    SUPPORTED_AUDIO_TYPES = [\n        \"audio/wav\",\n        \"audio/mp3\",\n        \"audio/aiff\",\n        \"audio/aac\",\n        \"audio/ogg\",\n        \"audio/flac\",\n    ]\n\n    def __init__(\n        self,\n        api_key: str,\n        base_url: str = \"https://generativelanguage.googleapis.com\",\n        model_name: str = \"gemini-3-flash\",\n    ):\n        self.api_key = api_key\n        self.base_url = base_url.rstrip(\"/\")\n        self.model_name = model_name\n\n    def _get_endpoint(\n        self, endpoint_type: str = \"generate\", model_name: Optional[str] = None\n    ) -> str:\n        model = model_name or self.model_name\n\n        if endpoint_type == \"generate\":\n            return f\"{self.base_url}/v1beta/models/{model}:generateContent\"\n        elif endpoint_type == \"stream\":\n            return (\n                f\"{self.base_url}/v1beta/models/{model}:streamGenerateContent?alt=sse\"\n            )\n        elif endpoint_type == \"upload\":\n            return f\"{self.base_url}/upload/v1beta/files\"\n        elif endpoint_type == \"files\":\n            return f\"{self.base_url}/v1beta/files\"\n        else:\n            raise ValueError(f\"Unknown endpoint type: {endpoint_type}\")\n\n    def _get_headers(self) -> Dict[str, str]:\n        return {\"x-goog-api-key\": self.api_key, \"Content-Type\": \"application/json\"}\n\n    def _encode_file_to_base64(self, file_path: str) -> str:\n        with open(file_path, \"rb\") as f:\n            return base64.b64encode(f.read()).decode(\"utf-8\")\n\n    def _get_mime_type(self, file_path: str) -> str:\n        mime_type, _ = mimetypes.guess_type(file_path)\n        if not mime_type:\n            ext = Path(file_path).suffix.lower()\n            mime_map = {\n                \".mp3\": \"audio/mp3\",\n                \".wav\": \"audio/wav\",\n                \".aac\": \"audio/aac\",\n                \".ogg\": \"audio/ogg\",\n                \".flac\": \"audio/flac\",\n                \".aiff\": \"audio/aiff\",\n            }\n            mime_type = mime_map.get(ext, \"application/octet-stream\")\n        return mime_type\n\n    def upload_file(\n        self,\n        file_path: str,\n        display_name: Optional[str] = None,\n        mime_type: Optional[str] = None,\n    ) -> Optional[Dict[str, Any]]:\n        \"\"\"Upload a file using the Files API.\n\n        Use this for files larger than 20MB or when you want to reuse files\n        across multiple requests.\n        \"\"\"\n        try:\n            if not os.path.exists(file_path):\n                raise FileNotFoundError(f\"File not found: {file_path}\")\n\n            if mime_type is None:\n                mime_type = self._get_mime_type(file_path)\n\n            num_bytes = os.path.getsize(file_path)\n\n            if display_name is None:\n                display_name = Path(file_path).stem\n\n            init_headers = {\n                \"x-goog-api-key\": self.api_key,\n                \"X-Goog-Upload-Protocol\": \"resumable\",\n                \"X-Goog-Upload-Command\": \"start\",\n                \"X-Goog-Upload-Header-Content-Length\": str(num_bytes),\n                \"X-Goog-Upload-Header-Content-Type\": mime_type,\n                \"Content-Type\": \"application/json\",\n            }\n\n            init_data = {\"file\": {\"display_name\": display_name}}\n\n            upload_endpoint = self._get_endpoint(\"upload\")\n            response = requests.post(\n                upload_endpoint, headers=init_headers, json=init_data\n            )\n\n            if response.status_code != 200:\n                print(\n                    f\"Failed to initiate upload: {response.status_code} - {response.text}\"\n                )\n                return None\n\n            upload_url = response.headers.get(\"x-goog-upload-url\")\n            if not upload_url:\n                print(\"No upload URL in response headers\")\n                return None\n\n            with open(file_path, \"rb\") as f:\n                file_data = f.read()\n\n            upload_headers = {\n                \"Content-Length\": str(num_bytes),\n                \"X-Goog-Upload-Offset\": \"0\",\n                \"X-Goog-Upload-Command\": \"upload, finalize\",\n            }\n\n            response = requests.post(upload_url, headers=upload_headers, data=file_data)\n\n            if response.status_code == 200:\n                file_info = response.json()\n                print(\n                    f\"File uploaded successfully: {file_info.get('file', {}).get('uri')}\"\n                )\n                return file_info.get(\"file\")\n            else:\n                print(\n                    f\"Failed to upload file data: {response.status_code} - {response.text}\"\n                )\n                return None\n\n        except Exception as e:\n            print(f\"Error uploading file: {e}\")\n            return None\n\n    def get_file_info(self, file_name: str) -> Optional[Dict[str, Any]]:\n        try:\n            files_endpoint = self._get_endpoint(\"files\")\n            url = f\"{files_endpoint}/{file_name}\"\n            response = requests.get(url, headers=self._get_headers())\n\n            if response.status_code == 200:\n                return response.json()\n            return None\n        except Exception as e:\n            print(f\"Error getting file info: {e}\")\n            return None\n\n    def delete_file(self, file_name: str) -> bool:\n        try:\n            files_endpoint = self._get_endpoint(\"files\")\n            url = f\"{files_endpoint}/{file_name}\"\n            response = requests.delete(url, headers=self._get_headers())\n            return response.status_code == 204\n        except Exception as e:\n            print(f\"Error deleting file: {e}\")\n            return False\n\n    def generate_content(\n        self,\n        prompt: Union[str, List[Dict[str, Any]]],\n        audio: Optional[List[str]] = None,\n        file_uris: Optional[List[Dict[str, str]]] = None,\n        system_instruction: Optional[str] = None,\n        generation_config: Optional[Dict[str, Any]] = None,\n        history: Optional[List[Dict[str, Any]]] = None,\n        model_name: Optional[str] = None,\n    ) -> Optional[Dict[str, Any]]:\n        \"\"\"Generate content with audio support.\n\n        Args:\n            prompt: Text prompt or list of content parts\n            audio: List of audio file paths (for inline data)\n            file_uris: List of file URIs from uploaded files, each dict with 'mime_type' and 'file_uri'\n            system_instruction: Optional system instruction to guide behavior\n            generation_config: Optional generation configuration (temperature, topP, etc.)\n            history: Optional conversation history for multi-turn chat\n            model_name: Optional model name to use for this request (overrides default)\n        \"\"\"\n        try:\n            body = self._build_request_body(\n                prompt=prompt,\n                audio=audio,\n                file_uris=file_uris,\n                system_instruction=system_instruction,\n                generation_config=generation_config,\n                history=history,\n            )\n\n            endpoint = self._get_endpoint(\"generate\", model_name)\n            response = requests.post(\n                endpoint, headers=self._get_headers(), json=body, timeout=300\n            )\n\n            if response.status_code == 200:\n                return response.json()\n            else:\n                print(\n                    f\"API call failed: {response.status_code} - {response.text[:500]}\"\n                )\n                return None\n\n        except Exception as e:\n            print(f\"Error generating content: {e}\")\n            return None\n\n    def stream_generate_content(\n        self,\n        prompt: Union[str, List[Dict[str, Any]]],\n        audio: Optional[List[str]] = None,\n        file_uris: Optional[List[Dict[str, str]]] = None,\n        system_instruction: Optional[str] = None,\n        generation_config: Optional[Dict[str, Any]] = None,\n        history: Optional[List[Dict[str, Any]]] = None,\n        model_name: Optional[str] = None,\n    ) -> Generator[Dict[str, Any], None, None]:\n        \"\"\"Stream generate content with server-sent events.\"\"\"\n        try:\n            body = self._build_request_body(\n                prompt=prompt,\n                audio=audio,\n                file_uris=file_uris,\n                system_instruction=system_instruction,\n                generation_config=generation_config,\n                history=history,\n            )\n\n            endpoint = self._get_endpoint(\"stream\", model_name)\n            response = requests.post(\n                endpoint,\n                headers=self._get_headers(),\n                json=body,\n                stream=True,\n                timeout=300,\n            )\n\n            if response.status_code == 200:\n                for line in response.iter_lines():\n                    if line:\n                        line = line.decode(\"utf-8\")\n                        if line.startswith(\"data: \"):\n                            data = line[6:]\n                            try:\n                                yield json.loads(data)\n                            except json.JSONDecodeError:\n                                continue\n            else:\n                print(\n                    f\"Streaming failed: {response.status_code} - {response.text[:500]}\"\n                )\n\n        except Exception as e:\n            print(f\"Error streaming content: {e}\")\n\n    def _build_request_body(\n        self,\n        prompt: Union[str, List[Dict[str, Any]]],\n        audio: Optional[List[str]] = None,\n        file_uris: Optional[List[Dict[str, str]]] = None,\n        system_instruction: Optional[str] = None,\n        generation_config: Optional[Dict[str, Any]] = None,\n        history: Optional[List[Dict[str, Any]]] = None,\n    ) -> Dict[str, Any]:\n        body = {}\n\n        if system_instruction:\n            body[\"system_instruction\"] = {\"parts\": [{\"text\": system_instruction}]}\n\n        contents = []\n\n        if history:\n            contents.extend(history)\n\n        parts = []\n\n        if isinstance(prompt, str):\n            parts.append({\"text\": prompt})\n        elif isinstance(prompt, list):\n            parts.extend(prompt)\n\n        if audio:\n            for audio_path in audio:\n                mime_type = self._get_mime_type(audio_path)\n                audio_data = self._encode_file_to_base64(audio_path)\n                parts.append(\n                    {\"inline_data\": {\"mime_type\": mime_type, \"data\": audio_data}}\n                )\n\n        if file_uris:\n            for file_ref in file_uris:\n                parts.append(\n                    {\n                        \"file_data\": {\n                            \"mime_type\": file_ref.get(\"mime_type\"),\n                            \"file_uri\": file_ref.get(\"file_uri\"),\n                        }\n                    }\n                )\n\n        contents.append({\"role\": \"user\", \"parts\": parts})\n\n        body[\"contents\"] = contents\n\n        if generation_config:\n            body[\"generationConfig\"] = generation_config\n\n        return body\n\n    def extract_text(self, response: Dict[str, Any]) -> Optional[str]:\n        try:\n            if response.get(\"candidates\"):\n                candidate = response[\"candidates\"][0]\n                if candidate.get(\"content\", {}).get(\"parts\"):\n                    parts = candidate[\"content\"][\"parts\"]\n                    texts = [part.get(\"text\", \"\") for part in parts if \"text\" in part]\n                    return \" \".join(texts)\n        except Exception as e:\n            print(f\"Error extracting text: {e}\")\n        return None\n\n    def analyze_audio(\n        self,\n        audio_path: str,\n        prompt: str,\n        model_name: Optional[str] = \"gemini-3-pro-preview\",\n        use_upload: bool = False,\n        **kwargs,\n    ) -> Optional[str]:\n        \"\"\"Analyze audio with a text prompt.\n\n        Args:\n            audio_path: Path to the audio file\n            prompt: Text prompt for analysis\n            model_name: Model name for analysis\n            use_upload: Whether to use File API (recommended for audio > 20MB)\n        \"\"\"\n        generation_config = {\n            \"thinkingConfig\": {\n                \"thinkingLevel\": \"HIGH\",\n            },\n            \"responseMimeType\": \"application/json\",\n        }\n        if use_upload:\n            file_info = self.upload_file(audio_path)\n            if file_info:\n                file_uris = [\n                    {\n                        \"mime_type\": file_info.get(\"mimeType\"),\n                        \"file_uri\": file_info.get(\"uri\"),\n                    }\n                ]\n                response = self.generate_content(\n                    prompt=prompt,\n                    file_uris=file_uris,\n                    model_name=model_name,\n                    generation_config=generation_config,\n                    **kwargs,\n                )\n                if response is None:\n                    return None\n                data = self.extract_text(response)\n                if data is None:\n                    return None\n                result = data.replace(\"```json\", \"\").replace(\"```\", \"\")\n                return result\n            return None\n        else:\n            response = self.generate_content(\n                prompt=prompt,\n                audio=[audio_path],\n                model_name=model_name,\n                generation_config=generation_config,\n                **kwargs,\n            )\n            if response is None:\n                return None\n            data = self.extract_text(response)\n            if data is None:\n                return None\n            result = data.replace(\"```json\", \"\").replace(\"```\", \"\")\n            return result\n\n    def transcribe_audio(\n        self,\n        audio_path: str,\n        use_upload: bool = False,\n        model_name: Optional[str] = \"gemini-3-pro-preview\",\n        **kwargs,\n    ) -> Optional[str]:\n        \"\"\"Transcribe audio to text.\"\"\"\n        response = self.analyze_audio(\n            audio_path=audio_path,\n            prompt=\"Please provide a complete transcription of this audio.\",\n            use_upload=use_upload,\n            model_name=model_name,\n            **kwargs,\n        )\n        return self.extract_text(response) if response else None\n\n\n_gemini_service = None\n\n\ndef get_gemini_service(\n    api_key: Optional[str] = None,\n    base_url: str = \"https://generativelanguage.googleapis.com\",\n    model_name: str = \"gemini-3-flash\",\n) -> GeminiService:\n    global _gemini_service\n\n    if not api_key:\n        raise ValueError(\n            \"API key must be provided or set in GEMINI_API_KEY environment variable\"\n        )\n\n    if _gemini_service is None:\n        _gemini_service = GeminiService(api_key, base_url, model_name)\n\n    return _gemini_service\n\n\nAUDIO_EXTENSIONS = {\".mp3\", \".wav\", \".flac\", \".ogg\", \".aac\", \".aiff\"}\n\n\ndef extract_json_from_text(text: str):\n    start = text.find(\"{\")\n    end = text.rfind(\"}\")\n    if start == -1 or end == -1:\n        return None\n    return text[start: end + 1]\n\n\ndef analysis_audio_by_gemini(\n    api_key: str, base_url: str, audio_path: str, duration=None, max_retry: int = 3\n):\n    global _gemini_service\n    if _gemini_service is None:\n        _gemini_service = get_gemini_service(api_key, base_url)\n\n    result = _gemini_service.analyze_audio(\n        audio_path, prompt, model_name=\"gemini-3-pro-preview\"\n    )\n    try:\n        json_result = json.loads(result)\n    except:\n        json_result = extract_json_from_text(result)\n    if json_result is None:\n        raise Exception(f\"无法解析json, {result}\")\n    return json_result\n\n\ndef analysis_audio_to_files(\n    api_key: str,\n    base_url: str,\n    audio_path: str,\n    output_dir: str,\n):\n    \"\"\"Analyze audio and save lyrics and caption as separate txt files.\n\n    Output files:\n        {stem}.lyrics.txt  - lyrics\n        {stem}.caption.txt - caption\n\n    Args:\n        api_key: Gemini API key\n        base_url: Gemini API base URL\n        audio_path: Path to the audio file\n        output_dir: Directory to save output txt files\n    \"\"\"\n    json_result = analysis_audio_by_gemini(api_key, base_url, audio_path)\n\n    if isinstance(json_result, str):\n        json_result = json.loads(json_result)\n\n    stem = Path(audio_path).stem\n    os.makedirs(output_dir, exist_ok=True)\n\n    lyrics = json_result.get(\"lyrics\", \"\")\n    caption = json_result.get(\"caption\", \"\")\n\n    lyrics_path = os.path.join(output_dir, f\"{stem}.lyrics.txt\")\n    with open(lyrics_path, \"w\", encoding=\"utf-8\") as f:\n        f.write(lyrics)\n\n    caption_path = os.path.join(output_dir, f\"{stem}.caption.txt\")\n    with open(caption_path, \"w\", encoding=\"utf-8\") as f:\n        f.write(caption)\n\n    return lyrics_path, caption_path\n\n\ndef process_folder(\n    input_dir: str,\n    output_dir: str,\n    api_key: str,\n    base_url: str = \"https://generativelanguage.googleapis.com\",\n) -> List[str]:\n    \"\"\"Analyze all audio files in a folder, saving lyrics and caption txt files.\n\n    Args:\n        input_dir: Directory containing audio files\n        output_dir: Directory to save output txt files\n        api_key: Gemini API key\n        base_url: Gemini API base URL\n\n    Returns:\n        List of output file paths\n    \"\"\"\n    input_path = Path(input_dir)\n    if not input_path.is_dir():\n        raise NotADirectoryError(f\"Input directory not found: {input_dir}\")\n\n    os.makedirs(output_dir, exist_ok=True)\n\n    audio_files = sorted(\n        f for f in input_path.iterdir()\n        if f.is_file() and f.suffix.lower() in AUDIO_EXTENSIONS\n    )\n\n    if not audio_files:\n        print(f\"No audio files found in {input_dir}\")\n        return []\n\n    output_paths = []\n    for i, audio_file in enumerate(audio_files, 1):\n        print(f\"[{i}/{len(audio_files)}] {audio_file.name}\")\n\n        try:\n            lyrics_path, caption_path = analysis_audio_to_files(\n                api_key=api_key,\n                base_url=base_url,\n                audio_path=str(audio_file),\n                output_dir=output_dir,\n            )\n            output_paths.extend([lyrics_path, caption_path])\n            print(f\"  -> {Path(lyrics_path).name}, {Path(caption_path).name}\")\n        except Exception as e:\n            print(f\"  Error: {e}\")\n\n    print(f\"Done: {len(output_paths) // 2}/{len(audio_files)} files processed\")\n    return output_paths\n"
  },
  {
    "path": "scripts/lora_data_prepare/whisper_transcription.py",
    "content": "\"\"\"OpenAI Whisper transcription service.\n\nTranscribe audio to lyrics text using OpenAI Whisper API.\nUses word-level timestamps for intelligent line breaking,\nthen outputs plain text without timestamps.\n\"\"\"\n\nimport os\nfrom typing import Optional, List, Dict, Any\nfrom pathlib import Path\n\nimport requests\n\n\ndef is_cjk(ch: str) -> bool:\n    cp = ord(ch)\n    return (0x4E00 <= cp <= 0x9FFF or 0x3400 <= cp <= 0x4DBF or\n            0x20000 <= cp <= 0x2A6DF or 0x2A700 <= cp <= 0x2B73F or\n            0x2B740 <= cp <= 0x2B81F or 0x2B820 <= cp <= 0x2CEAF or\n            0xF900 <= cp <= 0xFAFF or 0x2F800 <= cp <= 0x2FA1F or\n            0x3000 <= cp <= 0x303F or 0x3040 <= cp <= 0x309F or\n            0x30A0 <= cp <= 0x30FF or 0xFF00 <= cp <= 0xFFEF)\n\n\ndef smart_join(word_list: List[str]) -> str:\n    if not word_list:\n        return \"\"\n    result = word_list[0]\n    for j in range(1, len(word_list)):\n        prev_last = word_list[j - 1][-1] if word_list[j - 1] else \"\"\n        curr_first = word_list[j][0] if word_list[j] else \"\"\n        if is_cjk(prev_last) or is_cjk(curr_first):\n            result += word_list[j]\n        else:\n            result += \" \" + word_list[j]\n    return result.strip()\n\n\ndef words_to_lyrics(words: List[Dict[str, Any]], line_gap: float = 1.5) -> str:\n    \"\"\"Convert word-level timestamps to plain lyrics text.\n\n    Uses timestamps to detect line breaks (by punctuation or time gaps),\n    then outputs text only.\n    \"\"\"\n    if not words:\n        return \"\"\n    lines = []\n    current_line = []\n\n    for i, w in enumerate(words):\n        current_line.append(w[\"word\"])\n        is_last = (i == len(words) - 1)\n        has_punct = w[\"word\"].rstrip().endswith((\".\", \"!\", \"?\", \"\\u3002\", \"\\uff01\", \"\\uff1f\", \"\\uff0c\", \",\"))\n        has_gap = (not is_last and words[i + 1][\"start\"] - w[\"end\"] > line_gap)\n\n        if is_last or has_punct or has_gap:\n            text = smart_join(current_line)\n            text = text.rstrip(\"\\uff0c\\u3002,.\")\n            if text:\n                lines.append(text)\n            current_line = []\n\n    return \"\\n\".join(lines) + \"\\n\"\n\n\ndef transcribe_whisper(\n    audio_path: str,\n    api_key: str,\n    api_url: str = \"https://api.openai.com/v1\",\n    model: str = \"whisper-1\",\n    language: Optional[str] = None,\n) -> List[Dict[str, Any]]:\n    \"\"\"Transcribe audio using OpenAI Whisper API.\n\n    Args:\n        audio_path: Path to the audio file\n        api_key: OpenAI API key\n        api_url: OpenAI API base URL\n        model: Whisper model name\n        language: Optional language code (e.g. \"zh\", \"en\", \"ja\")\n\n    Returns:\n        List of word-level timestamps [{word, start, end}, ...]\n    \"\"\"\n    if not os.path.exists(audio_path):\n        raise FileNotFoundError(f\"Audio file not found: {audio_path}\")\n\n    url = f\"{api_url.rstrip('/')}/audio/transcriptions\"\n    headers = {\"Authorization\": f\"Bearer {api_key}\"}\n\n    data = {\n        \"model\": model,\n        \"response_format\": \"verbose_json\",\n        \"timestamp_granularities[]\": [\"word\", \"segment\"],\n    }\n    if language:\n        data[\"language\"] = language\n\n    with open(audio_path, \"rb\") as f:\n        files = {\"file\": (Path(audio_path).name, f)}\n        response = requests.post(url, headers=headers, data=data, files=files, timeout=300)\n\n    if response.status_code != 200:\n        error_msg = \"Unknown error\"\n        try:\n            err = response.json()\n            error_msg = err.get(\"error\", {}).get(\"message\", \"\") or err.get(\"detail\", error_msg)\n        except Exception:\n            pass\n        raise RuntimeError(f\"Whisper API error (HTTP {response.status_code}): {error_msg}\")\n\n    result = response.json()\n    words = [\n        {\"word\": w[\"word\"], \"start\": w[\"start\"], \"end\": w[\"end\"]}\n        for w in result.get(\"words\", [])\n    ]\n    return words\n\n\nAUDIO_EXTENSIONS = {\".mp3\", \".wav\", \".flac\", \".ogg\", \".aac\", \".aiff\"}\n\n\ndef transcribe_to_file(\n    audio_path: str,\n    output_path: str,\n    api_key: str,\n    api_url: str = \"https://api.openai.com/v1\",\n    model: str = \"whisper-1\",\n    language: Optional[str] = None,\n    line_gap: float = 1.5,\n) -> str:\n    \"\"\"Transcribe audio and save plain lyrics text to file.\n\n    Args:\n        audio_path: Path to the audio file\n        output_path: Path to save the output txt file\n        api_key: OpenAI API key\n        api_url: OpenAI API base URL\n        model: Whisper model name\n        language: Optional language code\n        line_gap: Gap threshold (seconds) for line breaking\n\n    Returns:\n        Path to the output file\n    \"\"\"\n    words = transcribe_whisper(audio_path, api_key, api_url, model, language)\n\n    if not words:\n        raise RuntimeError(\"No word-level timestamps returned from Whisper API\")\n\n    content = words_to_lyrics(words, line_gap)\n\n    os.makedirs(os.path.dirname(output_path) or \".\", exist_ok=True)\n\n    with open(output_path, \"w\", encoding=\"utf-8\") as f:\n        f.write(content)\n\n    return output_path\n\n\ndef process_folder(\n    input_dir: str,\n    output_dir: str,\n    api_key: str,\n    api_url: str = \"https://api.openai.com/v1\",\n    model: str = \"whisper-1\",\n    language: Optional[str] = None,\n    line_gap: float = 1.5,\n) -> List[str]:\n    \"\"\"Transcribe all audio files in a folder.\n\n    Args:\n        input_dir: Directory containing audio files\n        output_dir: Directory to save output txt files\n        api_key: OpenAI API key\n        api_url: OpenAI API base URL\n        model: Whisper model name\n        language: Optional language code\n        line_gap: Gap threshold (seconds) for line breaking\n\n    Returns:\n        List of output file paths\n    \"\"\"\n    input_path = Path(input_dir)\n    if not input_path.is_dir():\n        raise NotADirectoryError(f\"Input directory not found: {input_dir}\")\n\n    os.makedirs(output_dir, exist_ok=True)\n\n    audio_files = sorted(\n        f for f in input_path.iterdir()\n        if f.is_file() and f.suffix.lower() in AUDIO_EXTENSIONS\n    )\n\n    if not audio_files:\n        print(f\"No audio files found in {input_dir}\")\n        return []\n\n    output_paths = []\n    for i, audio_file in enumerate(audio_files, 1):\n        output_file = Path(output_dir) / f\"{audio_file.stem}.lyrics.txt\"\n        print(f\"[{i}/{len(audio_files)}] {audio_file.name}\")\n\n        try:\n            transcribe_to_file(\n                audio_path=str(audio_file),\n                output_path=str(output_file),\n                api_key=api_key,\n                api_url=api_url,\n                model=model,\n                language=language,\n                line_gap=line_gap,\n            )\n            output_paths.append(str(output_file))\n            print(f\"  -> {output_file.name}\")\n        except Exception as e:\n            print(f\"  Error: {e}\")\n\n    print(f\"Done: {len(output_paths)}/{len(audio_files)} files processed\")\n    return output_paths\n"
  },
  {
    "path": "scripts/new_pr_branch.ps1",
    "content": "param(\n    [Parameter(Mandatory = $true)]\n    [string]$BranchName,\n    [string]$BaseRef = \"upstream/main\"\n)\n\n$ErrorActionPreference = \"Stop\"\n\ngit fetch upstream\ngit checkout -b $BranchName $BaseRef\n\nWrite-Host \"Created '$BranchName' from '$BaseRef'.\"\n"
  },
  {
    "path": "scripts/prepare_vae_calibration_data.py",
    "content": "import torch\nimport os\nimport soundfile as sf\nfrom diffusers.models import AutoencoderOobleck\nfrom tqdm import tqdm\nimport torch.nn.functional as F\n\ndef process_audio(audio_path, target_sr=48000):\n    try:\n        # Load audio using soundfile\n        audio_np, sr = sf.read(audio_path, dtype='float32')\n        \n        # Convert to torch: [samples, channels] or [samples] -> [channels, samples]\n        if audio_np.ndim == 1:\n            audio = torch.from_numpy(audio_np).unsqueeze(0)\n        else:\n            audio = torch.from_numpy(audio_np.T)\n        \n        # Ensure stereo\n        if audio.shape[0] == 1:\n            audio = torch.cat([audio, audio], dim=0)\n        \n        audio = audio[:2]\n        \n        # Resample if needed\n        if sr != target_sr:\n            ratio = target_sr / sr\n            new_length = int(audio.shape[-1] * ratio)\n            audio = F.interpolate(audio.unsqueeze(0), size=new_length, mode='linear', align_corners=False).squeeze(0)\n        \n        audio = torch.clamp(audio, -1.0, 1.0)\n        return audio.unsqueeze(0) # Add batch dim: [1, 2, samples]\n        \n    except Exception as e:\n        print(f\"Error processing {audio_path}: {e}\")\n        return None\n\ndef main():\n    print(\"Initializing Calibration Data Preparation...\")\n    \n    current_dir = os.path.dirname(os.path.abspath(__file__))\n    project_root = os.path.dirname(current_dir)\n    data_dir = os.path.join(project_root, \"data\", \"quant_data\")\n    output_path = os.path.join(project_root, \"data\", \"calibration_latents.pt\")\n    vae_path = os.path.join(project_root, \"checkpoints\", \"vae\")\n    \n    if not os.path.exists(data_dir):\n        print(f\"Error: Data directory not found at {data_dir}\")\n        return\n\n    print(f\"Loading VAE from {vae_path}...\")\n    try:\n        vae = AutoencoderOobleck.from_pretrained(vae_path)\n    except Exception as e:\n        print(f\"Failed to load VAE: {e}\")\n        return\n\n    device = \"cuda\" if torch.cuda.is_available() else \"cpu\"\n    # Check for XPU\n    if hasattr(torch, \"xpu\") and torch.xpu.is_available():\n        device = \"xpu\"\n    \n    print(f\"Using device: {device}\")\n    vae = vae.to(device)\n    vae.eval()\n\n    audio_files = [f for f in os.listdir(data_dir) if f.endswith('.flac')]\n    print(f\"Found {len(audio_files)} audio files.\")\n    \n    all_chunks = []\n    chunk_size = 512 # Latent frames\n    samples_per_latent = 1920\n    audio_chunk_size = chunk_size * samples_per_latent\n    \n    pbar = tqdm(audio_files, desc=\"Processing audio\")\n    for audio_file in pbar:\n        file_path = os.path.join(data_dir, audio_file)\n        full_audio = process_audio(file_path)\n        \n        if full_audio is None:\n            continue\n            \n        # Split audio into chunks\n        num_samples = full_audio.shape[-1]\n        \n        for start_idx in range(0, num_samples, audio_chunk_size):\n            end_idx = start_idx + audio_chunk_size\n            if end_idx > num_samples:\n                break # Skip incomplete chunks\n                \n            audio_input = full_audio[:, :, start_idx:end_idx].to(device)\n            \n            try:\n                with torch.no_grad():\n                    # Encode\n                    # VAE encode expects [Batch, Channels, Samples]\n                    # Returns DiagonalGaussianDistribution\n                    posterior = vae.encode(audio_input).latent_dist\n                    latents = posterior.sample() # [1, 64, LatentLength]\n                    \n                    # It should be exactly chunk_size, but let's be safe\n                    if latents.shape[-1] >= chunk_size:\n                        all_chunks.append(latents[:, :, :chunk_size].cpu())\n                    \n                    pbar.set_postfix({\"chunks\": len(all_chunks)})\n                    \n            except Exception as e:\n                print(f\"Error encoding chunk {start_idx}-{end_idx} of {audio_file}: {e}\")\n                torch.cuda.empty_cache()\n                if device == \"xpu\":\n                    torch.xpu.empty_cache()\n    \n    print(f\"Collected {len(all_chunks)} chunks of size {chunk_size}.\")\n    \n    if len(all_chunks) > 0:\n        print(f\"Saving to {output_path}...\")\n        torch.save(all_chunks, output_path)\n        print(\"Done.\")\n    else:\n        print(\"No chunks collected.\")\n\nif __name__ == \"__main__\":\n    main()\n"
  },
  {
    "path": "scripts/profile_vram.py",
    "content": "#!/usr/bin/env python3\n\"\"\"\nVRAM Profiling Script for ACE-Step 1.5\n\nMeasures actual GPU memory consumption of each model component at different\nconfigurations. Results are used to calibrate the empirical VRAM constants\nin gpu_config.py.\n\nUsage:\n    python scripts/profile_vram.py                          # Profile all components\n    python scripts/profile_vram.py --component dit          # Profile DiT only\n    python scripts/profile_vram.py --component lm           # Profile LM only\n    python scripts/profile_vram.py --component vae          # Profile VAE only\n    python scripts/profile_vram.py --output results.json    # Save results to JSON\n\nRequirements:\n    - CUDA GPU with sufficient memory\n    - All model checkpoints downloaded\n\"\"\"\n\nimport argparse\nimport gc\nimport json\nimport os\nimport sys\nimport time\nfrom typing import Dict, Any, Optional, List\n\n# Add project root to path\nPROJECT_ROOT = os.path.abspath(os.path.join(os.path.dirname(__file__), \"..\"))\nif PROJECT_ROOT not in sys.path:\n    sys.path.insert(0, PROJECT_ROOT)\n\nimport torch\n\n\ndef get_memory_stats() -> Dict[str, float]:\n    \"\"\"Get current CUDA memory statistics in GB.\"\"\"\n    if not torch.cuda.is_available():\n        return {\"allocated\": 0, \"reserved\": 0, \"free\": 0, \"total\": 0, \"max_allocated\": 0}\n    \n    allocated = torch.cuda.memory_allocated() / (1024**3)\n    reserved = torch.cuda.memory_reserved() / (1024**3)\n    free, total = torch.cuda.mem_get_info()\n    free_gb = free / (1024**3)\n    total_gb = total / (1024**3)\n    max_allocated = torch.cuda.max_memory_allocated() / (1024**3)\n    \n    return {\n        \"allocated\": round(allocated, 3),\n        \"reserved\": round(reserved, 3),\n        \"free\": round(free_gb, 3),\n        \"total\": round(total_gb, 3),\n        \"max_allocated\": round(max_allocated, 3),\n    }\n\n\ndef reset_memory():\n    \"\"\"Reset CUDA memory stats and free caches.\"\"\"\n    if torch.cuda.is_available():\n        torch.cuda.empty_cache()\n        torch.cuda.reset_peak_memory_stats()\n        gc.collect()\n        torch.cuda.empty_cache()\n        # Wait for GPU to settle\n        torch.cuda.synchronize()\n\n\ndef measure_cuda_context() -> Dict[str, float]:\n    \"\"\"Measure CUDA context overhead.\"\"\"\n    print(\"\\n\" + \"=\" * 60)\n    print(\"Measuring CUDA context overhead...\")\n    print(\"=\" * 60)\n    \n    reset_memory()\n    before = get_memory_stats()\n    \n    # Force CUDA context initialization\n    _ = torch.zeros(1, device=\"cuda\")\n    del _\n    torch.cuda.synchronize()\n    \n    after = get_memory_stats()\n    \n    context_overhead = after[\"total\"] - after[\"free\"] - before.get(\"allocated\", 0)\n    \n    result = {\n        \"cuda_context_gb\": round(context_overhead, 3),\n        \"total_gpu_gb\": after[\"total\"],\n        \"free_after_context_gb\": after[\"free\"],\n    }\n    \n    print(f\"  CUDA context overhead: {result['cuda_context_gb']:.3f} GB\")\n    print(f\"  Total GPU memory: {result['total_gpu_gb']:.3f} GB\")\n    print(f\"  Free after context: {result['free_after_context_gb']:.3f} GB\")\n    \n    return result\n\n\ndef profile_dit(checkpoint_dir: str, config_path: str = \"acestep-v15-turbo\") -> Dict[str, Any]:\n    \"\"\"Profile DiT model memory consumption.\"\"\"\n    print(\"\\n\" + \"=\" * 60)\n    print(f\"Profiling DiT model: {config_path}\")\n    print(\"=\" * 60)\n    \n    from transformers import AutoModel\n    \n    model_path = os.path.join(checkpoint_dir, config_path)\n    if not os.path.exists(model_path):\n        print(f\"  Model not found: {model_path}\")\n        return {}\n    \n    reset_memory()\n    before = get_memory_stats()\n    \n    # Load model weights\n    print(\"  Loading DiT model weights...\")\n    model = AutoModel.from_pretrained(\n        model_path,\n        trust_remote_code=True,\n        attn_implementation=\"sdpa\",\n        dtype=torch.bfloat16,\n    )\n    model = model.to(\"cuda\").to(torch.bfloat16)\n    model.eval()\n    torch.cuda.synchronize()\n    \n    after_load = get_memory_stats()\n    weights_gb = after_load[\"allocated\"] - before[\"allocated\"]\n    \n    print(f\"  DiT model weights: {weights_gb:.3f} GB\")\n    \n    # Load silence latent\n    silence_path = os.path.join(model_path, \"silence_latent.pt\")\n    silence_latent = None\n    if os.path.exists(silence_path):\n        silence_latent = torch.load(silence_path, weights_only=True).transpose(1, 2)\n        silence_latent = silence_latent.to(\"cuda\").to(torch.bfloat16)\n    \n    # Determine if model has CFG (base vs turbo)\n    has_cfg = \"turbo\" not in config_path.lower()\n    \n    # Profile inference at different batch sizes and durations\n    inference_results = []\n    \n    # Duration -> latent_length mapping: 48000 Hz audio, 5 Hz latent = 9600 audio samples per latent frame\n    # Actually: latent_length = ceil(duration * 5) for 5Hz models\n    durations = [60, 120, 240]\n    batch_sizes = [1, 2, 4]\n    \n    for duration in durations:\n        for batch_size in batch_sizes:\n            reset_memory()\n            torch.cuda.reset_peak_memory_stats()\n            \n            # Reload model to GPU if needed\n            model = model.to(\"cuda\")\n            torch.cuda.synchronize()\n            \n            mem_before_inference = get_memory_stats()\n            \n            latent_length = int(duration * 5)  # 5 Hz\n            latent_dim = 64  # Standard latent dim\n            \n            try:\n                with torch.inference_mode():\n                    # Simulate DiT inference inputs\n                    # Create dummy latent noise\n                    noise = torch.randn(batch_size, latent_length, latent_dim, device=\"cuda\", dtype=torch.bfloat16)\n                    \n                    # Simulate text encoder output\n                    text_hidden = torch.randn(batch_size, 512, 768, device=\"cuda\", dtype=torch.bfloat16)\n                    text_mask = torch.ones(batch_size, 512, device=\"cuda\", dtype=torch.long)\n                    \n                    # If has CFG, double the batch for classifier-free guidance\n                    if has_cfg:\n                        noise_cfg = torch.cat([noise, noise], dim=0)\n                        text_hidden_cfg = torch.cat([text_hidden, text_hidden], dim=0)\n                        text_mask_cfg = torch.cat([text_mask, text_mask], dim=0)\n                        del noise_cfg, text_hidden_cfg, text_mask_cfg\n                    \n                    del noise, text_hidden, text_mask\n                    torch.cuda.synchronize()\n                    \n                mem_after_inference = get_memory_stats()\n                peak_gb = mem_after_inference[\"max_allocated\"] - mem_before_inference[\"allocated\"]\n                \n                result_entry = {\n                    \"duration_s\": duration,\n                    \"batch_size\": batch_size,\n                    \"has_cfg\": has_cfg,\n                    \"peak_inference_gb\": round(peak_gb, 3),\n                    \"latent_length\": latent_length,\n                }\n                inference_results.append(result_entry)\n                \n                print(f\"  batch={batch_size}, dur={duration}s: peak={peak_gb:.3f} GB (cfg={has_cfg})\")\n                \n            except RuntimeError as e:\n                if \"out of memory\" in str(e).lower():\n                    print(f\"  batch={batch_size}, dur={duration}s: OOM\")\n                    inference_results.append({\n                        \"duration_s\": duration,\n                        \"batch_size\": batch_size,\n                        \"has_cfg\": has_cfg,\n                        \"peak_inference_gb\": -1,\n                        \"error\": \"OOM\",\n                    })\n                    torch.cuda.empty_cache()\n                else:\n                    raise\n    \n    # Cleanup\n    del model\n    if silence_latent is not None:\n        del silence_latent\n    torch.cuda.empty_cache()\n    gc.collect()\n    \n    return {\n        \"config_path\": config_path,\n        \"weights_gb\": round(weights_gb, 3),\n        \"has_cfg\": has_cfg,\n        \"inference_results\": inference_results,\n    }\n\n\ndef profile_vae(checkpoint_dir: str) -> Dict[str, Any]:\n    \"\"\"Profile VAE model memory consumption.\"\"\"\n    print(\"\\n\" + \"=\" * 60)\n    print(\"Profiling VAE model\")\n    print(\"=\" * 60)\n    \n    from diffusers.models import AutoencoderOobleck\n    \n    vae_path = os.path.join(checkpoint_dir, \"vae\")\n    if not os.path.exists(vae_path):\n        print(f\"  VAE not found: {vae_path}\")\n        return {}\n    \n    reset_memory()\n    before = get_memory_stats()\n    \n    # Load VAE\n    print(\"  Loading VAE model weights...\")\n    vae = AutoencoderOobleck.from_pretrained(vae_path)\n    vae = vae.to(\"cuda\").to(torch.float16)\n    vae.eval()\n    torch.cuda.synchronize()\n    \n    after_load = get_memory_stats()\n    weights_gb = after_load[\"allocated\"] - before[\"allocated\"]\n    \n    print(f\"  VAE model weights: {weights_gb:.3f} GB\")\n    \n    # Profile decode at different chunk sizes\n    decode_results = []\n    chunk_sizes = [256, 512, 1024]\n    \n    for chunk_size in chunk_sizes:\n        reset_memory()\n        torch.cuda.reset_peak_memory_stats()\n        \n        vae = vae.to(\"cuda\")\n        torch.cuda.synchronize()\n        \n        mem_before = get_memory_stats()\n        \n        try:\n            with torch.inference_mode():\n                # Simulate latent input: [batch=1, channels=64, length=chunk_size]\n                latent = torch.randn(1, 64, chunk_size, device=\"cuda\", dtype=torch.float16)\n                decoder_output = vae.decode(latent)\n                audio = decoder_output.sample\n                del decoder_output, audio, latent\n                torch.cuda.synchronize()\n            \n            mem_after = get_memory_stats()\n            peak_gb = mem_after[\"max_allocated\"] - mem_before[\"allocated\"]\n            \n            decode_results.append({\n                \"chunk_size\": chunk_size,\n                \"peak_decode_gb\": round(peak_gb, 3),\n            })\n            print(f\"  chunk_size={chunk_size}: peak={peak_gb:.3f} GB\")\n            \n        except RuntimeError as e:\n            if \"out of memory\" in str(e).lower():\n                print(f\"  chunk_size={chunk_size}: OOM\")\n                decode_results.append({\n                    \"chunk_size\": chunk_size,\n                    \"peak_decode_gb\": -1,\n                    \"error\": \"OOM\",\n                })\n                torch.cuda.empty_cache()\n            else:\n                raise\n    \n    # Cleanup\n    del vae\n    torch.cuda.empty_cache()\n    gc.collect()\n    \n    return {\n        \"weights_gb\": round(weights_gb, 3),\n        \"decode_results\": decode_results,\n    }\n\n\ndef profile_text_encoder(checkpoint_dir: str) -> Dict[str, Any]:\n    \"\"\"Profile text encoder memory consumption.\"\"\"\n    print(\"\\n\" + \"=\" * 60)\n    print(\"Profiling Text Encoder\")\n    print(\"=\" * 60)\n    \n    from transformers import AutoModel, AutoTokenizer\n    \n    encoder_path = os.path.join(checkpoint_dir, \"text_encoder\")\n    if not os.path.exists(encoder_path):\n        print(f\"  Text encoder not found: {encoder_path}\")\n        return {}\n    \n    reset_memory()\n    before = get_memory_stats()\n    \n    # Load text encoder\n    print(\"  Loading text encoder weights...\")\n    tokenizer = AutoTokenizer.from_pretrained(encoder_path)\n    model = AutoModel.from_pretrained(encoder_path)\n    model = model.to(\"cuda\").to(torch.bfloat16)\n    model.eval()\n    torch.cuda.synchronize()\n    \n    after_load = get_memory_stats()\n    weights_gb = after_load[\"allocated\"] - before[\"allocated\"]\n    \n    print(f\"  Text encoder weights: {weights_gb:.3f} GB\")\n    \n    # Cleanup\n    del model, tokenizer\n    torch.cuda.empty_cache()\n    gc.collect()\n    \n    return {\n        \"weights_gb\": round(weights_gb, 3),\n    }\n\n\ndef profile_lm(checkpoint_dir: str, lm_models: Optional[List[str]] = None) -> Dict[str, Any]:\n    \"\"\"Profile LM model memory consumption.\"\"\"\n    print(\"\\n\" + \"=\" * 60)\n    print(\"Profiling 5Hz LM models\")\n    print(\"=\" * 60)\n    \n    from transformers import AutoModelForCausalLM, AutoTokenizer\n    \n    if lm_models is None:\n        # Auto-detect available LM models\n        lm_models = []\n        for name in os.listdir(checkpoint_dir):\n            if \"5Hz-lm\" in name and os.path.isdir(os.path.join(checkpoint_dir, name)):\n                lm_models.append(name)\n    \n    if not lm_models:\n        print(\"  No LM models found\")\n        return {}\n    \n    lm_models.sort()\n    results = {}\n    \n    for lm_name in lm_models:\n        lm_path = os.path.join(checkpoint_dir, lm_name)\n        if not os.path.exists(lm_path):\n            print(f\"  LM model not found: {lm_path}\")\n            continue\n        \n        print(f\"\\n  Profiling LM: {lm_name}\")\n        \n        reset_memory()\n        before = get_memory_stats()\n        \n        # Load model weights\n        print(f\"    Loading model weights...\")\n        model = AutoModelForCausalLM.from_pretrained(\n            lm_path,\n            torch_dtype=torch.bfloat16,\n            trust_remote_code=True,\n        )\n        model = model.to(\"cuda\")\n        model.eval()\n        torch.cuda.synchronize()\n        \n        after_load = get_memory_stats()\n        weights_gb = after_load[\"allocated\"] - before[\"allocated\"]\n        \n        print(f\"    Model weights: {weights_gb:.3f} GB\")\n        \n        # Estimate KV cache memory for different max_model_len values\n        # KV cache formula: 2 * num_layers * max_tokens * num_kv_heads * head_dim * dtype_size\n        config = model.config\n        num_layers = config.num_hidden_layers\n        num_kv_heads = getattr(config, \"num_key_value_heads\", config.num_attention_heads)\n        head_dim = getattr(config, \"head_dim\", config.hidden_size // config.num_attention_heads)\n        dtype_size = 2  # bfloat16 = 2 bytes\n        \n        kv_cache_estimates = {}\n        for max_len in [2048, 4096]:\n            # Per-token KV cache size\n            per_token_bytes = 2 * num_layers * num_kv_heads * head_dim * dtype_size\n            total_bytes = per_token_bytes * max_len\n            total_gb = total_bytes / (1024**3)\n            kv_cache_estimates[str(max_len)] = round(total_gb, 3)\n            print(f\"    KV cache ({max_len} tokens): {total_gb:.3f} GB\")\n        \n        results[lm_name] = {\n            \"weights_gb\": round(weights_gb, 3),\n            \"kv_cache_estimates\": kv_cache_estimates,\n            \"num_layers\": num_layers,\n            \"num_kv_heads\": num_kv_heads,\n            \"head_dim\": head_dim,\n        }\n        \n        # Cleanup\n        del model\n        torch.cuda.empty_cache()\n        gc.collect()\n    \n    return results\n\n\ndef main():\n    parser = argparse.ArgumentParser(description=\"VRAM Profiling for ACE-Step 1.5\")\n    parser.add_argument(\"--component\", type=str, default=\"all\",\n                       choices=[\"all\", \"cuda_context\", \"dit\", \"vae\", \"text_encoder\", \"lm\"],\n                       help=\"Component to profile (default: all)\")\n    parser.add_argument(\"--checkpoint-dir\", type=str, default=None,\n                       help=\"Checkpoint directory (default: auto-detect)\")\n    parser.add_argument(\"--dit-config\", type=str, default=\"acestep-v15-turbo\",\n                       help=\"DiT model config name (default: acestep-v15-turbo)\")\n    parser.add_argument(\"--lm-models\", type=str, nargs=\"*\", default=None,\n                       help=\"LM models to profile (default: auto-detect)\")\n    parser.add_argument(\"--output\", type=str, default=None,\n                       help=\"Output JSON file path\")\n    \n    args = parser.parse_args()\n    \n    if not torch.cuda.is_available():\n        print(\"ERROR: CUDA is not available. This script requires a CUDA GPU.\")\n        sys.exit(1)\n    \n    # Auto-detect checkpoint directory\n    if args.checkpoint_dir is None:\n        args.checkpoint_dir = os.path.join(PROJECT_ROOT, \"checkpoints\")\n    \n    if not os.path.exists(args.checkpoint_dir):\n        print(f\"ERROR: Checkpoint directory not found: {args.checkpoint_dir}\")\n        sys.exit(1)\n    \n    device_name = torch.cuda.get_device_name(0)\n    total_mem = torch.cuda.get_device_properties(0).total_memory / (1024**3)\n    \n    print(\"=\" * 60)\n    print(\"ACE-Step 1.5 VRAM Profiler\")\n    print(\"=\" * 60)\n    print(f\"  GPU: {device_name}\")\n    print(f\"  Total VRAM: {total_mem:.2f} GB\")\n    print(f\"  Checkpoint dir: {args.checkpoint_dir}\")\n    print(f\"  Component: {args.component}\")\n    \n    results = {\n        \"gpu_name\": device_name,\n        \"total_vram_gb\": round(total_mem, 3),\n        \"timestamp\": time.strftime(\"%Y-%m-%d %H:%M:%S\"),\n    }\n    \n    components = [args.component] if args.component != \"all\" else [\n        \"cuda_context\", \"dit\", \"vae\", \"text_encoder\", \"lm\"\n    ]\n    \n    for component in components:\n        if component == \"cuda_context\":\n            results[\"cuda_context\"] = measure_cuda_context()\n        elif component == \"dit\":\n            results[\"dit\"] = profile_dit(args.checkpoint_dir, args.dit_config)\n        elif component == \"vae\":\n            results[\"vae\"] = profile_vae(args.checkpoint_dir)\n        elif component == \"text_encoder\":\n            results[\"text_encoder\"] = profile_text_encoder(args.checkpoint_dir)\n        elif component == \"lm\":\n            results[\"lm\"] = profile_lm(args.checkpoint_dir, args.lm_models)\n    \n    # Print summary\n    print(\"\\n\" + \"=\" * 60)\n    print(\"SUMMARY\")\n    print(\"=\" * 60)\n    \n    if \"cuda_context\" in results:\n        print(f\"  CUDA context: {results['cuda_context'].get('cuda_context_gb', 'N/A')} GB\")\n    if \"dit\" in results and results[\"dit\"]:\n        print(f\"  DiT weights ({results['dit'].get('config_path', '')}): {results['dit'].get('weights_gb', 'N/A')} GB\")\n    if \"vae\" in results and results[\"vae\"]:\n        print(f\"  VAE weights: {results['vae'].get('weights_gb', 'N/A')} GB\")\n    if \"text_encoder\" in results and results[\"text_encoder\"]:\n        print(f\"  Text encoder weights: {results['text_encoder'].get('weights_gb', 'N/A')} GB\")\n    if \"lm\" in results and results[\"lm\"]:\n        for lm_name, lm_data in results[\"lm\"].items():\n            print(f\"  LM {lm_name} weights: {lm_data.get('weights_gb', 'N/A')} GB\")\n    \n    # Calculate total base VRAM (all models loaded simultaneously)\n    base_total = 0\n    if \"cuda_context\" in results:\n        base_total += results[\"cuda_context\"].get(\"cuda_context_gb\", 0)\n    if \"dit\" in results and results[\"dit\"]:\n        base_total += results[\"dit\"].get(\"weights_gb\", 0)\n    if \"vae\" in results and results[\"vae\"]:\n        base_total += results[\"vae\"].get(\"weights_gb\", 0)\n    if \"text_encoder\" in results and results[\"text_encoder\"]:\n        base_total += results[\"text_encoder\"].get(\"weights_gb\", 0)\n    \n    print(f\"\\n  Base VRAM (DiT+VAE+TextEnc+CUDA): {base_total:.3f} GB\")\n    print(f\"  Remaining for LM + inference: {total_mem - base_total:.3f} GB\")\n    \n    # Save results\n    if args.output:\n        output_path = args.output\n    else:\n        output_path = os.path.join(PROJECT_ROOT, \"scripts\", \"vram_profile_results.json\")\n    \n    os.makedirs(os.path.dirname(output_path), exist_ok=True)\n    with open(output_path, \"w\") as f:\n        json.dump(results, f, indent=2)\n    print(f\"\\n  Results saved to: {output_path}\")\n\n\nif __name__ == \"__main__\":\n    main()\n"
  },
  {
    "path": "setup_xpu.bat",
    "content": "@echo off\nsetlocal enabledelayedexpansion\nREM ACE-Step XPU Environment Setup Script\nREM This script creates the venv_xpu virtual environment and installs all dependencies\nREM For Intel Arc GPUs (A770, A750, A580, A380) and integrated graphics\n\necho ======================================================\necho     ACE-Step 1.5 - Intel XPU Environment Setup\necho ======================================================\necho.\necho This script will:\necho   1. Create venv_xpu virtual environment ^(Python 3.11^)\necho   2. Install PyTorch XPU nightly build\necho   3. Install all ACE-Step dependencies\necho.\necho Requirements:\necho   - Python 3.11 installed and in PATH\necho   - Intel Arc GPU with latest drivers\necho   - Internet connection for first-time installation\necho   - ~5-10 GB disk space\necho.\necho Press any key to continue or Ctrl+C to cancel...\npause >nul\necho.\n\nREM Check Python version\npython --version >nul 2>&1\nif !ERRORLEVEL! NEQ 0 (\n    echo ========================================\n    echo  ERROR: Python not found!\n    echo ========================================\n    echo.\n    echo Please install Python 3.11 from:\n    echo   https://www.python.org/downloads/release/python-3119/\n    echo.\n    echo Make sure to check \"Add Python to PATH\" during installation.\n    echo.\n    pause\n    exit /b 1\n)\n\npython --version | find \"3.11\" >nul 2>&1\nif !ERRORLEVEL! NEQ 0 (\n    echo WARNING: Python 3.11 recommended, but found:\n    python --version\n    echo.\n    set /p CONTINUE=\"Continue anyway? (Y/N): \"\n    if /i not \"!CONTINUE!\"==\"Y\" (\n        echo.\n        echo Please install Python 3.11 for best compatibility.\n        pause\n        exit /b 1\n    )\n    echo.\n)\n\nREM Check if venv_xpu already exists\nif exist \"venv_xpu\\Scripts\\activate.bat\" (\n    echo ========================================\n    echo  venv_xpu already exists!\n    echo ========================================\n    echo.\n    echo Location: %~dp0venv_xpu\n    echo.\n    set /p RECREATE=\"Recreate virtual environment? (Y/N): \"\n    if /i \"!RECREATE!\"==\"Y\" (\n        echo.\n        echo Removing old venv_xpu...\n        rmdir /s /q venv_xpu\n        echo.\n    ) else (\n        echo.\n        echo Existing environment will be updated.\n        echo.\n    )\n)\n\nREM Create virtual environment\necho ========================================\necho Step 1: Creating virtual environment\necho ========================================\necho.\n\nif exist \"venv_xpu\" (\n    echo Cleaning existing venv_xpu...\n    rmdir /s /q venv_xpu\n)\n\necho Running: python -m venv venv_xpu\necho.\npython -m venv venv_xpu\n\nif !ERRORLEVEL! NEQ 0 (\n    echo.\n    echo ========================================\n    echo  ERROR: Failed to create virtual environment!\n    echo ========================================\n    echo.\n    echo Please check:\n    echo   1. Python is installed correctly\n    echo   2. You have write permissions in this directory\n    echo   3. No antivirus is blocking venv creation\n    echo.\n    pause\n    exit /b 1\n)\n\necho Virtual environment created successfully!\necho.\n\nREM Activate virtual environment\necho ========================================\necho Step 2: Activating virtual environment\necho ========================================\necho.\n\ncall venv_xpu\\Scripts\\activate.bat\n\nREM Upgrade pip\necho ========================================\necho Step 3: Upgrading pip\necho ========================================\necho.\n\necho Running: python -m pip install --upgrade pip\npython -m pip install --upgrade pip -q\n\necho pip upgraded successfully!\necho.\n\nREM Check requirements-xpu.txt exists\nif not exist \"requirements-xpu.txt\" (\n    echo ========================================\n    echo  ERROR: requirements-xpu.txt not found!\n    echo ========================================\n    echo.\n    echo Please make sure you are running this script\n    echo from the ACE-Step-1.5 root directory.\n    echo.\n    pause\n    exit /b 1\n)\n\nREM Install dependencies\necho ========================================\necho Step 4: Installing XPU dependencies\necho ========================================\necho.\necho This will take a few minutes on first run...\necho.\necho Running: pip install -r requirements-xpu.txt\necho.\n\npip install -r requirements-xpu.txt\n\nif !ERRORLEVEL! NEQ 0 (\n    echo.\n    echo ========================================\n    echo  WARNING: Some packages may have failed to install\n    echo ========================================\n    echo.\n    echo This can happen due to:\n    echo   - Network issues\n    echo   - Incompatible package versions\n    echo.\n    echo Trying to continue with available packages...\n    echo.\n    timeout /t 5 /nobreak >nul\n)\n\necho.\necho ========================================\necho Step 5: Verifying Installation\necho ========================================\necho.\n\nREM Verify PyTorch XPU installation\necho Checking PyTorch XPU installation...\npython -c \"import torch; print(f'PyTorch version: {torch.__version__}'); print(f'XPU available: {torch.xpu.is_available()}')\" 2>nul\nif !ERRORLEVEL! NEQ 0 (\n    echo.\n    echo WARNING: PyTorch XPU verification failed!\n    echo The installation may be incomplete.\n    echo.\n    echo Try running manually:\n    echo   call venv_xpu\\Scripts\\activate\n    echo   pip install -r requirements-xpu.txt\n    echo.\n) else (\n    echo PyTorch XPU installed successfully!\n)\necho.\n\nREM Display summary\necho ======================================================\necho     Installation Complete!\necho ======================================================\necho.\necho Your ACE-Step XPU environment is ready to use!\necho.\necho Next steps:\necho   1. Download ACE-Step models to the 'checkpoints' folder\necho      ^(if not already present^)\necho.\necho   2. Launch the Gradio UI:\necho      start_gradio_ui_xpu.bat\necho.\necho   3. Or launch with manual model selection:\necho      start_gradio_ui_xpu_manual.bat\necho.\necho   4. Or launch the API server:\necho      start_api_server_xpu.bat\necho.\necho To activate the environment manually:\necho   call venv_xpu\\Scripts\\activate\necho.\necho ======================================================\necho.\npause\n\nendlocal\n"
  },
  {
    "path": "start_api_server.bat",
    "content": "@echo off\nsetlocal enabledelayedexpansion\nREM ACE-Step REST API Server Launcher\nREM This script launches the REST API server for ACE-Step\n\nREM ==================== Configuration ====================\nREM Uncomment and modify the parameters below as needed\n\nREM Server settings\nset HOST=127.0.0.1\nREM set HOST=0.0.0.0\nset PORT=8001\n\nREM API key for authentication (optional)\nREM set API_KEY=--api-key sk-your-secret-key\n\nREM Download source settings\nREM Preferred download source: auto (default), huggingface, or modelscope\nREM set DOWNLOAD_SOURCE=--download-source modelscope\nREM set DOWNLOAD_SOURCE=--download-source huggingface\nset DOWNLOAD_SOURCE=\n\nREM LLM (Language Model) initialization settings\nREM By default, LLM is auto-enabled/disabled based on GPU VRAM:\nREM   - <=6GB VRAM: LLM disabled (DiT-only mode)\nREM   - >6GB VRAM: LLM enabled\nREM Values: auto (default), true (force enable), false (force disable)\nset ACESTEP_INIT_LLM=auto\nREM set ACESTEP_INIT_LLM=true\nREM set ACESTEP_INIT_LLM=false\n\nREM LM model path (optional, only used when LLM is enabled)\nREM Available models: acestep-5Hz-lm-0.6B, acestep-5Hz-lm-1.7B, acestep-5Hz-lm-4B\nREM set LM_MODEL_PATH=--lm-model-path acestep-5Hz-lm-0.6B\n\nREM Update check on startup (set to false to disable)\nset CHECK_UPDATE=true\nREM set CHECK_UPDATE=false\n\nREM Skip model loading at startup (models will be lazy-loaded on first request)\nREM Set to true to start server quickly without loading models\nREM set ACESTEP_NO_INIT=false\nREM set ACESTEP_NO_INIT=true\n\nREM ==================== Launch ====================\n\nREM ==================== Startup Update Check ====================\nif /i not \"%CHECK_UPDATE%\"==\"true\" goto :SkipUpdateCheck\n\nREM Find git: try PortableGit first, then system git\nset \"UPDATE_GIT_CMD=\"\nif exist \"%~dp0PortableGit\\bin\\git.exe\" (\n    set \"UPDATE_GIT_CMD=%~dp0PortableGit\\bin\\git.exe\"\n) else (\n    where git >nul 2>&1\n    if !ERRORLEVEL! EQU 0 (\n        for /f \"tokens=*\" %%i in ('where git 2^>nul') do (\n            if not defined UPDATE_GIT_CMD set \"UPDATE_GIT_CMD=%%i\"\n        )\n    )\n)\nif not defined UPDATE_GIT_CMD goto :SkipUpdateCheck\n\ncd /d \"%~dp0\"\n\"!UPDATE_GIT_CMD!\" rev-parse --git-dir >nul 2>&1\nif !ERRORLEVEL! NEQ 0 goto :SkipUpdateCheck\n\necho [Update] Checking for updates...\n\nfor /f \"tokens=*\" %%i in ('\"!UPDATE_GIT_CMD!\" rev-parse --abbrev-ref HEAD 2^>nul') do set UPDATE_BRANCH=%%i\nif \"!UPDATE_BRANCH!\"==\"\" set UPDATE_BRANCH=main\nfor /f \"tokens=*\" %%i in ('\"!UPDATE_GIT_CMD!\" rev-parse --short HEAD 2^>nul') do set UPDATE_LOCAL=%%i\n\n\"!UPDATE_GIT_CMD!\" fetch origin --quiet 2>nul\nif !ERRORLEVEL! NEQ 0 (\n    echo [Update] Network unreachable, skipping.\n    echo.\n    goto :SkipUpdateCheck\n)\n\nfor /f \"tokens=*\" %%i in ('\"!UPDATE_GIT_CMD!\" rev-parse --short origin/!UPDATE_BRANCH! 2^>nul') do set UPDATE_REMOTE=%%i\n\nif \"!UPDATE_REMOTE!\"==\"\" goto :SkipUpdateCheck\nif \"!UPDATE_LOCAL!\"==\"!UPDATE_REMOTE!\" (\n    echo [Update] Already up to date ^(!UPDATE_LOCAL!^).\n    echo.\n    goto :SkipUpdateCheck\n)\n\necho.\necho ========================================\necho   Update available!\necho ========================================\necho   Current: !UPDATE_LOCAL!  -^>  Latest: !UPDATE_REMOTE!\necho.\necho   Recent changes:\n\"!UPDATE_GIT_CMD!\" --no-pager log --oneline HEAD..origin/!UPDATE_BRANCH! 2>nul\necho.\n\nset /p UPDATE_NOW=\"Update now before starting? (Y/N): \"\nif /i \"!UPDATE_NOW!\"==\"Y\" (\n    if exist \"%~dp0check_update.bat\" (\n        call \"%~dp0check_update.bat\"\n    ) else (\n        echo Pulling latest changes...\n        \"!UPDATE_GIT_CMD!\" pull --ff-only origin !UPDATE_BRANCH! 2>nul\n        if !ERRORLEVEL! NEQ 0 (\n            echo [Update] Update failed. Please update manually.\n        )\n    )\n) else (\n    echo [Update] Skipped. Run check_update.bat to update later.\n)\necho.\n\n:SkipUpdateCheck\n\necho Starting ACE-Step REST API Server...\necho API will be available at: http://%HOST%:%PORT%\necho API Documentation: http://%HOST%:%PORT%/docs\necho.\n\nREM Auto-detect Python environment\nif exist \"%~dp0python_embedded\\python.exe\" (\n    echo [Environment] Using embedded Python...\n\n    REM Build command with optional parameters\n    set \"PYTHON_EXE=%~dp0python_embedded\\python.exe\"\n    set \"SCRIPT_PATH=%~dp0acestep\\api_server.py\"\n    set \"CMD=--host %HOST% --port %PORT%\"\n    if not \"%API_KEY%\"==\"\" set \"CMD=!CMD! %API_KEY%\"\n    if not \"%DOWNLOAD_SOURCE%\"==\"\" set \"CMD=!CMD! %DOWNLOAD_SOURCE%\"\n    if not \"%LM_MODEL_PATH%\"==\"\" set \"CMD=!CMD! %LM_MODEL_PATH%\"\n\n    \"!PYTHON_EXE!\" \"!SCRIPT_PATH!\" !CMD!\n) else (\n    echo [Environment] Embedded Python not found, checking for uv...\n\n    REM Check if uv is installed\n    where uv >nul 2>&1\n    if !ERRORLEVEL! NEQ 0 (\n        echo.\n        echo ========================================\n        echo uv package manager not found!\n        echo ========================================\n        echo.\n        echo ACE-Step requires either:\n        echo   1. python_embedded directory ^(portable package^)\n        echo   2. uv package manager\n        echo.\n        echo Would you like to install uv now? ^(Recommended^)\n        echo.\n        set /p INSTALL_UV=\"Install uv? (Y/N): \"\n\n        if /i \"!INSTALL_UV!\"==\"Y\" (\n            echo.\n            REM Call install_uv.bat in silent mode\n            call \"%~dp0install_uv.bat\" --silent\n            set INSTALL_RESULT=!ERRORLEVEL!\n\n            if !INSTALL_RESULT! EQU 0 (\n                echo.\n                echo ========================================\n                echo uv installed successfully!\n                echo ========================================\n                echo.\n\n                REM Refresh PATH to include uv\n                if exist \"%USERPROFILE%\\.local\\bin\\uv.exe\" (\n                    set \"PATH=%USERPROFILE%\\.local\\bin;%PATH%\"\n                )\n                if exist \"%LOCALAPPDATA%\\Microsoft\\WinGet\\Links\\uv.exe\" (\n                    set \"PATH=%LOCALAPPDATA%\\Microsoft\\WinGet\\Links;%PATH%\"\n                )\n\n                REM Verify uv is available\n                where uv >nul 2>&1\n                if !ERRORLEVEL! EQU 0 (\n                    echo uv is now available!\n                    uv --version\n                    echo.\n                    goto :RunWithUv\n                ) else (\n                    REM Try direct paths\n                    if exist \"%USERPROFILE%\\.local\\bin\\uv.exe\" (\n                        set \"PATH=%USERPROFILE%\\.local\\bin;%PATH%\"\n                        goto :RunWithUv\n                    )\n                    if exist \"%LOCALAPPDATA%\\Microsoft\\WinGet\\Links\\uv.exe\" (\n                        set \"PATH=%LOCALAPPDATA%\\Microsoft\\WinGet\\Links;%PATH%\"\n                        goto :RunWithUv\n                    )\n\n                    echo.\n                    echo uv installed but not in PATH yet.\n                    echo Please restart your terminal or run:\n                    echo   %USERPROFILE%\\.local\\bin\\uv.exe run acestep-api\n                    echo.\n                    pause\n                    exit /b 1\n                )\n            ) else (\n                echo.\n                echo ========================================\n                echo Installation failed!\n                echo ========================================\n                echo.\n                echo Please install uv manually:\n                echo   1. Using PowerShell: irm https://astral.sh/uv/install.ps1 ^| iex\n                echo   2. Using winget: winget install --id=astral-sh.uv -e\n                echo   3. Download portable package: https://files.acemusic.ai/acemusic/win/ACE-Step-1.5.7z\n                echo.\n                pause\n                exit /b 1\n            )\n        ) else (\n            echo.\n            echo Installation cancelled.\n            echo.\n            echo To use ACE-Step, please either:\n            echo   1. Install uv: winget install --id=astral-sh.uv -e\n            echo   2. Download portable package: https://files.acemusic.ai/acemusic/win/ACE-Step-1.5.7z\n            echo.\n            pause\n            exit /b 1\n        )\n    )\n\n    :RunWithUv\n    echo [Environment] Using uv package manager...\n    echo.\n\n    REM Check if virtual environment exists\n    if not exist \"%~dp0.venv\" (\n        echo [Setup] Virtual environment not found. Setting up environment...\n        echo This will take a few minutes on first run.\n        echo.\n        echo Running: uv sync\n        echo.\n\n        uv sync\n\n        if !ERRORLEVEL! NEQ 0 (\n            echo.\n            echo [Retry] Online sync failed, retrying in offline mode...\n            echo.\n            uv sync --offline\n\n            if !ERRORLEVEL! NEQ 0 (\n                echo.\n                echo ========================================\n                echo [Error] Failed to setup environment\n                echo ========================================\n                echo.\n                echo Both online and offline modes failed.\n                echo Please check:\n                echo   1. Your internet connection ^(required for first-time setup^)\n                echo   2. Ensure you have enough disk space\n                echo   3. Try running: uv sync manually\n                echo.\n                pause\n                exit /b 1\n            )\n        )\n\n        echo.\n        echo ========================================\n        echo Environment setup completed!\n        echo ========================================\n        echo.\n    )\n\n    call :EnsureLegacyNvidiaTorchCompat\n    if !ERRORLEVEL! NEQ 0 exit /b !ERRORLEVEL!\n\n    echo Starting ACE-Step API Server...\n    echo.\n\n    REM Build command with optional parameters\n    set \"ACESTEP_ARGS=acestep-api --host %HOST% --port %PORT%\"\n    if not \"%API_KEY%\"==\"\" set \"ACESTEP_ARGS=!ACESTEP_ARGS! %API_KEY%\"\n    if not \"%DOWNLOAD_SOURCE%\"==\"\" set \"ACESTEP_ARGS=!ACESTEP_ARGS! %DOWNLOAD_SOURCE%\"\n    if not \"%LM_MODEL_PATH%\"==\"\" set \"ACESTEP_ARGS=!ACESTEP_ARGS! %LM_MODEL_PATH%\"\n\n    uv run --no-sync !ACESTEP_ARGS!\n    if !ERRORLEVEL! NEQ 0 (\n        echo.\n        echo [Retry] Online dependency resolution failed, retrying in offline mode...\n        echo.\n        uv run --offline --no-sync !ACESTEP_ARGS!\n        if !ERRORLEVEL! NEQ 0 (\n            echo.\n            echo ========================================\n            echo [Error] Failed to start ACE-Step API Server\n            echo ========================================\n            echo.\n            echo Both online and offline modes failed.\n            echo Please check:\n            echo   1. Your internet connection ^(for first-time setup^)\n            echo   2. If dependencies were previously installed ^(offline mode requires a prior successful install^)\n            echo   3. Try running: uv sync --offline\n            echo.\n            pause\n            exit /b 1\n        )\n    )\n)\n\npause\nendlocal\ngoto :eof\n\nREM ==================== Helper Functions ====================\n\n:EnsureLegacyNvidiaTorchCompat\nREM Auto-fix PyTorch for legacy NVIDIA GPUs (e.g., Pascal sm_61 on Quadro P1000)\nif /i \"%ACESTEP_SKIP_LEGACY_TORCH_FIX%\"==\"true\" exit /b 0\nif not exist \"%~dp0.venv\\Scripts\\python.exe\" exit /b 0\n\npushd \"%~dp0\"\n\".venv\\Scripts\\python.exe\" -c \"import os,sys; sys.path.insert(0, os.getcwd()); from acestep.launcher_compat import legacy_torch_fix_probe_exit_code; raise SystemExit(legacy_torch_fix_probe_exit_code())\" >nul 2>&1\nset \"LEGACY_CHECK_EXIT=!ERRORLEVEL!\"\n\nif \"!LEGACY_CHECK_EXIT!\"==\"0\" (\n    popd\n    exit /b 0\n)\nif not \"!LEGACY_CHECK_EXIT!\"==\"42\" (\n    echo [Compatibility] Error: legacy NVIDIA compatibility probe failed with exit code !LEGACY_CHECK_EXIT!.\n    popd\n    exit /b !LEGACY_CHECK_EXIT!\n)\n\necho [Compatibility] Legacy NVIDIA GPU detected with unsupported torch arch.\necho [Compatibility] Installing CUDA 12.1 torch build with sm_61 support...\nuv pip install --python .venv\\Scripts\\python.exe --force-reinstall --index-url https://download.pytorch.org/whl/cu121 torch==2.5.1+cu121 torchvision==0.20.1+cu121 torchaudio==2.5.1+cu121\nif !ERRORLEVEL! EQU 0 (\n    echo [Compatibility] Legacy torch install complete.\n    REM Keep a legacy-compatible torchao so INT8 quantization remains available\n    REM on low-VRAM Pascal/Quadro GPUs.\n    uv pip install --python .venv\\Scripts\\python.exe --force-reinstall torchao==0.11.0 >nul 2>&1\n    if !ERRORLEVEL! EQU 0 (\n        echo [Compatibility] Installed torchao==0.11.0 (legacy-compatible).\n    ) else (\n        echo [Compatibility] Warning: failed to install torchao==0.11.0. Quantization may be unavailable.\n        popd\n        exit /b !ERRORLEVEL!\n    )\n) else (\n    echo [Compatibility] Warning: automatic legacy torch install failed.\n    echo [Compatibility] Run manually:\n    echo   uv pip install --python .venv\\Scripts\\python.exe --force-reinstall --index-url https://download.pytorch.org/whl/cu121 torch==2.5.1+cu121 torchvision==0.20.1+cu121 torchaudio==2.5.1+cu121\n    popd\n    exit /b !ERRORLEVEL!\n)\npopd\nexit /b 0\n"
  },
  {
    "path": "start_api_server.sh",
    "content": "#!/usr/bin/env bash\n# ACE-Step REST API Server Launcher - Linux (CUDA)\n# This script launches the REST API server for ACE-Step\n\nset -euo pipefail\nSCRIPT_DIR=\"$(cd \"$(dirname \"${BASH_SOURCE[0]}\")\" && pwd)\"\n\n# ==================== Configuration ====================\n# Uncomment and modify the parameters below as needed\n\n# Server settings\nHOST=\"127.0.0.1\"\n# HOST=\"0.0.0.0\"\nPORT=8001\n\n# API key for authentication (optional)\nAPI_KEY=\"\"\n# API_KEY=\"--api-key sk-your-secret-key\"\n\n# Download source settings\n# Preferred download source: auto (default), huggingface, or modelscope\nDOWNLOAD_SOURCE=\"\"\n# DOWNLOAD_SOURCE=\"--download-source modelscope\"\n# DOWNLOAD_SOURCE=\"--download-source huggingface\"\n\n# LLM (Language Model) initialization settings\n# By default, LLM is auto-enabled/disabled based on GPU VRAM:\n#   - <=6GB VRAM: LLM disabled (DiT-only mode)\n#   - >6GB VRAM: LLM enabled\n# Values: auto (default), true (force enable), false (force disable)\nexport ACESTEP_INIT_LLM=auto\n# export ACESTEP_INIT_LLM=true\n# export ACESTEP_INIT_LLM=false\n\n# LM model path (optional, only used when LLM is enabled)\n# Available models: acestep-5Hz-lm-0.6B, acestep-5Hz-lm-1.7B, acestep-5Hz-lm-4B\nLM_MODEL_PATH=\"\"\n# LM_MODEL_PATH=\"--lm-model-path acestep-5Hz-lm-0.6B\"\n\n# Update check on startup (set to \"false\" to disable)\nCHECK_UPDATE=\"true\"\n# CHECK_UPDATE=\"false\"\n\n# Skip model loading at startup (models will be lazy-loaded on first request)\n# Set to \"true\" to start server quickly without loading models\n# export ACESTEP_NO_INIT=false\n# export ACESTEP_NO_INIT=true\n\n# ==================== Launch ====================\n\n# ==================== Startup Update Check ====================\n_startup_update_check() {\n    [[ \"$CHECK_UPDATE\" != \"true\" ]] && return 0\n    command -v git &>/dev/null || return 0\n    cd \"$SCRIPT_DIR\" || return 0\n    git rev-parse --git-dir &>/dev/null 2>&1 || return 0\n\n    local branch commit remote_commit\n    branch=\"$(git rev-parse --abbrev-ref HEAD 2>/dev/null || echo \"main\")\"\n    commit=\"$(git rev-parse --short HEAD 2>/dev/null || echo \"\")\"\n    [[ -z \"$commit\" ]] && return 0\n\n    echo \"[Update] Checking for updates...\"\n\n    # Fetch with timeout (10s)\n    local fetch_ok=0\n    if command -v timeout &>/dev/null; then\n        timeout 10 git fetch origin --quiet 2>/dev/null && fetch_ok=1\n    elif command -v gtimeout &>/dev/null; then\n        gtimeout 10 git fetch origin --quiet 2>/dev/null && fetch_ok=1\n    else\n        git fetch origin --quiet 2>/dev/null && fetch_ok=1\n    fi\n\n    if [[ $fetch_ok -eq 0 ]]; then\n        echo \"[Update] Network unreachable, skipping.\"\n        echo\n        return 0\n    fi\n\n    remote_commit=\"$(git rev-parse --short \"origin/$branch\" 2>/dev/null || echo \"\")\"\n\n    if [[ -z \"$remote_commit\" || \"$commit\" == \"$remote_commit\" ]]; then\n        echo \"[Update] Already up to date ($commit).\"\n        echo\n        return 0\n    fi\n\n    echo\n    echo \"========================================\"\n    echo \"  Update available!\"\n    echo \"========================================\"\n    echo \"  Current: $commit  ->  Latest: $remote_commit\"\n    echo\n    echo \"  Recent changes:\"\n    git --no-pager log --oneline \"HEAD..origin/$branch\" 2>/dev/null | head -10\n    echo\n\n    read -rp \"Update now before starting? (Y/N): \" update_choice\n    if [[ \"${update_choice^^}\" == \"Y\" ]]; then\n        if [[ -f \"$SCRIPT_DIR/check_update.sh\" ]]; then\n            bash \"$SCRIPT_DIR/check_update.sh\"\n        else\n            echo \"Pulling latest changes...\"\n            git pull --ff-only origin \"$branch\" 2>/dev/null || {\n                echo \"[Update] Update failed. Please run: git pull\"\n            }\n        fi\n    else\n        echo \"[Update] Skipped. Run ./check_update.sh to update later.\"\n    fi\n    echo\n}\n_startup_update_check\n\necho \"Starting ACE-Step REST API Server...\"\necho \"API will be available at: http://${HOST}:${PORT}\"\necho \"API Documentation: http://${HOST}:${PORT}/docs\"\necho\n\n# Check if uv is installed\nif ! command -v uv &>/dev/null; then\n    if [[ -x \"$HOME/.local/bin/uv\" ]]; then\n        export PATH=\"$HOME/.local/bin:$PATH\"\n    elif [[ -x \"$HOME/.cargo/bin/uv\" ]]; then\n        export PATH=\"$HOME/.cargo/bin:$PATH\"\n    fi\nfi\n\nif ! command -v uv &>/dev/null; then\n    echo\n    echo \"========================================\"\n    echo \"uv package manager not found!\"\n    echo \"========================================\"\n    echo\n    echo \"ACE-Step requires the uv package manager.\"\n    echo\n    read -rp \"Install uv now? (Y/N): \" INSTALL_UV\n\n    if [[ \"${INSTALL_UV^^}\" == \"Y\" ]]; then\n        echo\n        bash \"$SCRIPT_DIR/install_uv.sh\" --silent\n        INSTALL_RESULT=$?\n\n        if [[ $INSTALL_RESULT -eq 0 ]]; then\n            echo\n            echo \"uv installed successfully!\"\n            export PATH=\"$HOME/.local/bin:$HOME/.cargo/bin:$PATH\"\n\n            if ! command -v uv &>/dev/null; then\n                echo \"uv installed but not in PATH. Please restart your terminal.\"\n                exit 1\n            fi\n        else\n            echo \"Installation failed. Please install uv manually:\"\n            echo \"  curl -LsSf https://astral.sh/uv/install.sh | sh\"\n            exit 1\n        fi\n    else\n        echo \"Installation cancelled.\"\n        echo \"Please install uv: curl -LsSf https://astral.sh/uv/install.sh | sh\"\n        exit 1\n    fi\nfi\n\necho \"[Environment] Using uv package manager...\"\necho\n\n# Ensure PyTorch build supports legacy NVIDIA GPUs (e.g., Pascal/Quadro P1000).\n# Newer CUDA wheels can omit sm_61, which causes runtime model-init failures.\n_ensure_legacy_nvidia_torch_compat() {\n    [[ \"${ACESTEP_SKIP_LEGACY_TORCH_FIX:-}\" == \"true\" ]] && return 0\n    [[ ! -x \"$SCRIPT_DIR/.venv/bin/python\" ]] && return 0\n\n    local compat_status\n    if (cd \"$SCRIPT_DIR\" && .venv/bin/python -c \\\n        \"import os, sys; sys.path.insert(0, os.getcwd()); from acestep.launcher_compat import legacy_torch_fix_probe_exit_code; raise SystemExit(legacy_torch_fix_probe_exit_code())\"); then\n        return 0\n    else\n        compat_status=$?\n    fi\n\n    if [[ \"$compat_status\" -eq 0 ]]; then\n        return 0\n    fi\n    if [[ \"$compat_status\" -ne 42 ]]; then\n        echo \"[Compatibility] Error: legacy NVIDIA compatibility probe failed with exit code $compat_status.\"\n        return \"$compat_status\"\n    fi\n\n    echo \"[Compatibility] Applying legacy NVIDIA torch build (CUDA 12.1, supports sm_61)...\"\n    if (cd \"$SCRIPT_DIR\" && uv pip install --python .venv/bin/python --force-reinstall \\\n        --index-url https://download.pytorch.org/whl/cu121 \\\n        torch==2.5.1+cu121 torchvision==0.20.1+cu121 torchaudio==2.5.1+cu121); then\n        echo \"[Compatibility] Legacy torch install complete.\"\n        # Keep a legacy-compatible torchao so INT8 quantization remains available\n        # on low-VRAM Pascal/Quadro GPUs.\n        if (cd \"$SCRIPT_DIR\" && uv pip install --python .venv/bin/python --force-reinstall torchao==0.11.0 >/dev/null 2>&1); then\n            echo \"[Compatibility] Installed torchao==0.11.0 (legacy-compatible).\"\n        else\n            echo \"[Compatibility] Warning: failed to install torchao==0.11.0. Quantization may be unavailable.\"\n        fi\n    else\n        echo \"[Compatibility] Warning: failed to install legacy torch automatically.\"\n        echo \"[Compatibility] Run manually:\"\n        echo \"  uv pip install --python .venv/bin/python --force-reinstall --index-url https://download.pytorch.org/whl/cu121 torch==2.5.1+cu121 torchvision==0.20.1+cu121 torchaudio==2.5.1+cu121\"\n        return 1\n    fi\n}\n\n# Check if virtual environment exists\nif [[ ! -d \"$SCRIPT_DIR/.venv\" ]]; then\n    echo \"[Setup] Virtual environment not found. Setting up environment...\"\n    echo \"This will take a few minutes on first run.\"\n    echo\n    echo \"Running: uv sync\"\n    echo\n\n    if ! (cd \"$SCRIPT_DIR\" && uv sync); then\n        echo\n        echo \"[Retry] Online sync failed, retrying in offline mode...\"\n        echo\n        if ! (cd \"$SCRIPT_DIR\" && uv sync --offline); then\n            echo\n            echo \"========================================\"\n            echo \"[Error] Failed to setup environment\"\n            echo \"========================================\"\n            echo\n            echo \"Both online and offline modes failed.\"\n            echo \"Please check:\"\n            echo \"  1. Your internet connection (required for first-time setup)\"\n            echo \"  2. Ensure you have enough disk space\"\n            echo \"  3. Try running: uv sync manually\"\n            exit 1\n        fi\n    fi\n\n    echo\n    echo \"========================================\"\n    echo \"Environment setup completed!\"\n    echo \"========================================\"\n    echo\nfi\n\n_ensure_legacy_nvidia_torch_compat\n\necho \"Starting ACE-Step API Server...\"\necho\n\n# Build command with optional parameters\nACESTEP_ARGS=\"acestep-api --host $HOST --port $PORT\"\n[[ -n \"$API_KEY\" ]] && ACESTEP_ARGS=\"$ACESTEP_ARGS $API_KEY\"\n[[ -n \"$DOWNLOAD_SOURCE\" ]] && ACESTEP_ARGS=\"$ACESTEP_ARGS $DOWNLOAD_SOURCE\"\n[[ -n \"$LM_MODEL_PATH\" ]] && ACESTEP_ARGS=\"$ACESTEP_ARGS $LM_MODEL_PATH\"\n\ncd \"$SCRIPT_DIR\" && uv run --no-sync $ACESTEP_ARGS || {\n    echo\n    echo \"[Retry] Online dependency resolution failed, retrying in offline mode...\"\n    echo\n    uv run --offline --no-sync $ACESTEP_ARGS || {\n        echo\n        echo \"========================================\"\n        echo \"[Error] Failed to start ACE-Step API Server\"\n        echo \"========================================\"\n        echo\n        echo \"Both online and offline modes failed.\"\n        echo \"Please check:\"\n        echo \"  1. Your internet connection (for first-time setup)\"\n        echo \"  2. If dependencies were previously installed (offline mode requires a prior successful install)\"\n        echo \"  3. Try running: uv sync --offline\"\n        exit 1\n    }\n}\n"
  },
  {
    "path": "start_api_server_macos.sh",
    "content": "#!/usr/bin/env bash\n# ACE-Step REST API Server Launcher - macOS (Apple Silicon / MLX)\n# This script launches the REST API server using the MLX backend\n# for native Apple Silicon acceleration.\n#\n# Requirements: macOS with Apple Silicon (M1/M2/M3/M4)\n\nset -euo pipefail\nSCRIPT_DIR=\"$(cd \"$(dirname \"${BASH_SOURCE[0]}\")\" && pwd)\"\n\n# ==================== MLX Configuration ====================\n# Force MLX backend for native Apple Silicon acceleration\nexport ACESTEP_LM_BACKEND=\"mlx\"\n\n# Disable tokenizer parallelism warning\nexport TOKENIZERS_PARALLELISM=\"false\"\n\n# ==================== Server Configuration ====================\nHOST=\"127.0.0.1\"\n# HOST=\"0.0.0.0\"\nPORT=8001\n\n# API key for authentication (optional, value only)\nAPI_KEY=\"\"\n# API_KEY=\"sk-your-secret-key\"\n\n# Download source settings (value only: \"huggingface\" or \"modelscope\")\nDOWNLOAD_SOURCE=\"\"\n# DOWNLOAD_SOURCE=\"huggingface\"\n# DOWNLOAD_SOURCE=\"modelscope\"\n\n# LLM initialization settings\n# Values: auto (default), true (force enable), false (force disable)\nexport ACESTEP_INIT_LLM=auto\n# export ACESTEP_INIT_LLM=true\n# export ACESTEP_INIT_LLM=false\n\n# LM model path (value only)\nLM_MODEL_PATH=\"\"\n# LM_MODEL_PATH=\"acestep-5Hz-lm-0.6B\"\n\n# Update check on startup (set to \"false\" to disable)\nCHECK_UPDATE=\"true\"\n# CHECK_UPDATE=\"false\"\n\n# Skip model loading at startup (models will be lazy-loaded on first request)\n# Set to \"true\" to start server quickly without loading models\n# export ACESTEP_NO_INIT=false\n# export ACESTEP_NO_INIT=true\n\n# ==================== Launch ====================\n\n# Verify macOS\nif [[ \"$(uname)\" != \"Darwin\" ]]; then\n    echo \"ERROR: This script is for macOS only.\"\n    echo \"For Linux, use start_api_server.sh instead.\"\n    exit 1\nfi\n\nARCH=\"$(uname -m)\"\nif [[ \"$ARCH\" != \"arm64\" ]]; then\n    echo \"WARNING: MLX backend requires Apple Silicon (arm64).\"\n    echo \"Detected architecture: $ARCH\"\n    echo \"Falling back to PyTorch backend.\"\n    unset ACESTEP_LM_BACKEND\nfi\n\n# ==================== Startup Update Check ====================\n_startup_update_check() {\n    [[ \"$CHECK_UPDATE\" != \"true\" ]] && return 0\n    command -v git &>/dev/null || return 0\n    cd \"$SCRIPT_DIR\" || return 0\n    git rev-parse --git-dir &>/dev/null 2>&1 || return 0\n\n    local branch commit remote_commit\n    branch=\"$(git rev-parse --abbrev-ref HEAD 2>/dev/null || echo \"main\")\"\n    commit=\"$(git rev-parse --short HEAD 2>/dev/null || echo \"\")\"\n    [[ -z \"$commit\" ]] && return 0\n\n    echo \"[Update] Checking for updates...\"\n\n    # Fetch with timeout (10s) - macOS uses gtimeout from coreutils\n    local fetch_ok=0\n    if command -v gtimeout &>/dev/null; then\n        gtimeout 10 git fetch origin --quiet 2>/dev/null && fetch_ok=1\n    elif command -v timeout &>/dev/null; then\n        timeout 10 git fetch origin --quiet 2>/dev/null && fetch_ok=1\n    else\n        git fetch origin --quiet 2>/dev/null && fetch_ok=1\n    fi\n\n    if [[ $fetch_ok -eq 0 ]]; then\n        echo \"[Update] Network unreachable, skipping.\"\n        echo\n        return 0\n    fi\n\n    remote_commit=\"$(git rev-parse --short \"origin/$branch\" 2>/dev/null || echo \"\")\"\n\n    if [[ -z \"$remote_commit\" || \"$commit\" == \"$remote_commit\" ]]; then\n        echo \"[Update] Already up to date ($commit).\"\n        echo\n        return 0\n    fi\n\n    echo\n    echo \"========================================\"\n    echo \"  Update available!\"\n    echo \"========================================\"\n    echo \"  Current: $commit  ->  Latest: $remote_commit\"\n    echo\n    echo \"  Recent changes:\"\n    git --no-pager log --oneline -10 \"HEAD..origin/$branch\" 2>/dev/null\n    echo\n\n    read -rp \"Update now before starting? (Y/N): \" update_choice\n    if [[ \"${update_choice^^}\" == \"Y\" ]]; then\n        if [[ -f \"$SCRIPT_DIR/check_update.sh\" ]]; then\n            bash \"$SCRIPT_DIR/check_update.sh\"\n        else\n            echo \"Pulling latest changes...\"\n            git pull --ff-only origin \"$branch\" 2>/dev/null || {\n                echo \"[Update] Update failed. Please run: git pull\"\n            }\n        fi\n    else\n        echo \"[Update] Skipped. Run ./check_update.sh to update later.\"\n    fi\n    echo\n}\n_startup_update_check\n\necho \"============================================\"\necho \"  ACE-Step 1.5 API - macOS Apple Silicon (MLX)\"\necho \"============================================\"\necho\necho \"API will be available at: http://${HOST}:${PORT}\"\necho \"API Documentation: http://${HOST}:${PORT}/docs\"\necho\n\n# ==================== Auto-detect Python environment ====================\n# Priority: python_embedded (portable package) > uv\nif [[ -f \"$SCRIPT_DIR/python_embedded/bin/python3.11\" ]]; then\n    echo \"[Environment] Found embedded Python, verifying...\"\n\n    # Proactively fix permissions and Gatekeeper BEFORE any execution attempt.\n    # On macOS Sequoia, running a quarantined binary triggers a blocking popup,\n    # so we must strip attributes and re-sign first.\n    chmod +x \"$SCRIPT_DIR/python_embedded/bin/\"* 2>/dev/null || true\n    echo \"[Setup] Removing quarantine attributes...\"\n    xattr -cr \"$SCRIPT_DIR/python_embedded\" 2>/dev/null || true\n    echo \"[Setup] Re-signing binaries (ad-hoc)...\"\n    find \"$SCRIPT_DIR/python_embedded\" -type f \\( -name \"*.dylib\" -o -name \"*.so\" -o -perm +111 \\) \\\n        -exec codesign --force --sign - {} \\; 2>/dev/null || true\n\n    if \"$SCRIPT_DIR/python_embedded/bin/python3.11\" -c \"pass\" 2>/dev/null; then\n        echo \"[Environment] Using embedded Python.\"\n        PYTHON_EXE=\"$SCRIPT_DIR/python_embedded/bin/python3.11\"\n        SCRIPT_PATH=\"$SCRIPT_DIR/acestep/api_server.py\"\n\n        # On Apple Silicon, verify MLX packages work with this macOS version.\n        # python_embedded may ship wheels built for a different macOS; pip\n        # reinstall fetches the correct platform wheel automatically.\n        if [[ \"$ARCH\" == \"arm64\" ]]; then\n            _need_mlx_fix=0\n            if ! \"$PYTHON_EXE\" -c \"import mlx.core\" 2>/dev/null; then\n                echo \"[Setup] MLX incompatible with this macOS — will reinstall.\"\n                _need_mlx_fix=1\n            elif ! \"$PYTHON_EXE\" -c \"from mlx_lm.utils import load\" 2>/dev/null; then\n                echo \"[Setup] mlx-lm outdated — will upgrade.\"\n                _need_mlx_fix=1\n            fi\n            if [[ $_need_mlx_fix -eq 1 ]]; then\n                echo \"[Setup] Fixing MLX packages (this only runs once)...\"\n                \"$PYTHON_EXE\" -m pip install --upgrade mlx mlx-lm 'transformers>=4.51.0,<4.58.0' 'vector-quantize-pytorch>=1.27.15,<1.28.0' 2>&1 | tail -1\n            fi\n        fi\n\n        echo \"Starting ACE-Step API Server...\"\n        echo\n\n        # Build command with optional parameters\n        CMD=(\"$PYTHON_EXE\" \"$SCRIPT_PATH\" --host \"$HOST\" --port \"$PORT\")\n        [[ -n \"$API_KEY\" ]] && CMD+=(--api-key \"$API_KEY\")\n        [[ -n \"$DOWNLOAD_SOURCE\" ]] && CMD+=(--download-source \"$DOWNLOAD_SOURCE\")\n        [[ -n \"$LM_MODEL_PATH\" ]] && CMD+=(--lm-model-path \"$LM_MODEL_PATH\")\n\n        cd \"$SCRIPT_DIR\" && exec \"${CMD[@]}\"\n    else\n        echo \"[Setup] WARNING: Embedded Python cannot run on this machine.\"\n        echo \"[Setup] This may be a CPU architecture mismatch (e.g., arm64 binary on x86_64).\"\n        echo \"[Setup] Falling back to uv...\"\n        echo\n    fi\nfi\n\n# ==================== Fallback: uv package manager ====================\n# Check if uv is installed\nif ! command -v uv &>/dev/null; then\n    if [[ -x \"$HOME/.local/bin/uv\" ]]; then\n        export PATH=\"$HOME/.local/bin:$PATH\"\n    elif [[ -x \"$HOME/.cargo/bin/uv\" ]]; then\n        export PATH=\"$HOME/.cargo/bin:$PATH\"\n    fi\nfi\n\nif ! command -v uv &>/dev/null; then\n    echo\n    echo \"========================================\"\n    echo \"uv package manager not found!\"\n    echo \"========================================\"\n    echo\n    echo \"ACE-Step requires the uv package manager.\"\n    echo\n    read -rp \"Install uv now? (Y/N): \" INSTALL_UV\n\n    if [[ \"${INSTALL_UV^^}\" == \"Y\" ]]; then\n        echo\n        bash \"$SCRIPT_DIR/install_uv.sh\" --silent\n        INSTALL_RESULT=$?\n\n        if [[ $INSTALL_RESULT -eq 0 ]]; then\n            export PATH=\"$HOME/.local/bin:$HOME/.cargo/bin:$PATH\"\n            if ! command -v uv &>/dev/null; then\n                echo \"uv installed but not in PATH. Please restart your terminal.\"\n                exit 1\n            fi\n        else\n            echo \"Installation failed. Please install uv manually:\"\n            echo \"  curl -LsSf https://astral.sh/uv/install.sh | sh\"\n            echo \"  or: brew install uv\"\n            exit 1\n        fi\n    else\n        echo \"Please install uv: curl -LsSf https://astral.sh/uv/install.sh | sh\"\n        exit 1\n    fi\nfi\n\necho \"[Environment] Using uv package manager...\"\necho\n\n# Check if virtual environment exists\nif [[ ! -d \"$SCRIPT_DIR/.venv\" ]]; then\n    echo \"[Setup] Virtual environment not found. Setting up environment...\"\n    echo \"This will take a few minutes on first run.\"\n    echo\n    echo \"Running: uv sync\"\n    echo\n\n    if ! (cd \"$SCRIPT_DIR\" && uv sync); then\n        echo\n        echo \"[Retry] Online sync failed, retrying in offline mode...\"\n        echo\n        if ! (cd \"$SCRIPT_DIR\" && uv sync --offline); then\n            echo\n            echo \"========================================\"\n            echo \"[Error] Failed to setup environment\"\n            echo \"========================================\"\n            echo\n            echo \"Both online and offline modes failed.\"\n            echo \"Please check:\"\n            echo \"  1. Your internet connection (required for first-time setup)\"\n            echo \"  2. Ensure you have enough disk space\"\n            echo \"  3. Try running: uv sync manually\"\n            exit 1\n        fi\n    fi\n\n    echo\n    echo \"========================================\"\n    echo \"Environment setup completed!\"\n    echo \"========================================\"\n    echo\nfi\n\necho \"Starting ACE-Step API Server (MLX backend)...\"\necho\n\n# Build command with optional parameters\nACESTEP_ARGS=(acestep-api --host \"$HOST\" --port \"$PORT\")\n[[ -n \"$API_KEY\" ]] && ACESTEP_ARGS+=(--api-key \"$API_KEY\")\n[[ -n \"$DOWNLOAD_SOURCE\" ]] && ACESTEP_ARGS+=(--download-source \"$DOWNLOAD_SOURCE\")\n[[ -n \"$LM_MODEL_PATH\" ]] && ACESTEP_ARGS+=(--lm-model-path \"$LM_MODEL_PATH\")\n\ncd \"$SCRIPT_DIR\" && uv run \"${ACESTEP_ARGS[@]}\" || {\n    echo\n    echo \"[Retry] Online dependency resolution failed, retrying in offline mode...\"\n    echo\n    uv run --offline \"${ACESTEP_ARGS[@]}\" || {\n        echo\n        echo \"========================================\"\n        echo \"[Error] Failed to start ACE-Step API Server\"\n        echo \"========================================\"\n        echo\n        echo \"Both online and offline modes failed.\"\n        echo \"Please check:\"\n        echo \"  1. Your internet connection (for first-time setup)\"\n        echo \"  2. If dependencies were previously installed (offline mode requires a prior successful install)\"\n        echo \"  3. Try running: uv sync --offline\"\n        exit 1\n    }\n}\n"
  },
  {
    "path": "start_api_server_rocm.bat",
    "content": "@echo off\nsetlocal enabledelayedexpansion\nREM ACE-Step REST API Server Launcher - AMD ROCm 7.2\nREM For AMD RX 7000/6000 series GPUs on Windows 11\nREM IMPORTANT: Requires Python 3.12 (AMD ROCm 7.2 only provides Python 3.12 wheels)\nREM Requires: ROCm PyTorch from repo.radeon.com\n\nREM ==================== ROCm Configuration ====================\nREM Force PyTorch LM backend (bypasses nano-vllm flash_attn dependency)\nset ACESTEP_LM_BACKEND=pt\n\nREM RDNA3 GPU architecture override (RX 7900 XT/XTX, RX 7800 XT, etc.)\nREM Change to 11.0.1 for gfx1101 (RX 7700 XT, RX 7800 XT)\nREM Change to 11.0.2 for gfx1102 (RX 7600)\nset HSA_OVERRIDE_GFX_VERSION=11.0.0\n\nREM Disable torch.compile Triton backend (not available on ROCm Windows)\nset TORCH_COMPILE_BACKEND=eager\n\nREM MIOpen: use fast heuristic kernel selection instead of exhaustive benchmarking\nREM Without this, first-run VAE decode hangs for minutes on each conv layer\nset MIOPEN_FIND_MODE=FAST\n\nREM HuggingFace tokenizer parallelism\nset TOKENIZERS_PARALLELISM=false\n\nREM ==================== Server Configuration ====================\nset HOST=127.0.0.1\nREM set HOST=0.0.0.0\nset PORT=8001\n\nREM ==================== Model Configuration ====================\nREM API key for authentication (optional)\nREM set API_KEY=--api-key sk-your-secret-key\n\nREM Download source: auto, huggingface, modelscope\nset DOWNLOAD_SOURCE=\n\nREM LLM (Language Model) initialization settings\nREM By default, LLM is auto-enabled/disabled based on GPU VRAM:\nREM   - <=6GB VRAM: LLM disabled (DiT-only mode)\nREM   - >6GB VRAM: LLM enabled\nREM Values: auto (default), true (force enable), false (force disable)\nset ACESTEP_INIT_LLM=auto\nREM set ACESTEP_INIT_LLM=true\nREM set ACESTEP_INIT_LLM=false\n\nREM LM model path (optional, only used when LLM is enabled)\nREM Available models: acestep-5Hz-lm-0.6B, acestep-5Hz-lm-1.7B, acestep-5Hz-lm-4B\nREM set LM_MODEL_PATH=--lm-model-path acestep-5Hz-lm-0.6B\n\nREM Update check on startup (set to false to disable)\nset CHECK_UPDATE=true\nREM set CHECK_UPDATE=false\n\nREM Skip model loading at startup (models will be lazy-loaded on first request)\nREM Set to true to start server quickly without loading models\nREM set ACESTEP_NO_INIT=false\nREM set ACESTEP_NO_INIT=true\n\nREM ==================== Venv Configuration ====================\nREM Path to the ROCm virtual environment (relative to this script)\nset VENV_DIR=%~dp0venv_rocm\n\nREM ==================== Launch ====================\n\nREM ==================== Startup Update Check ====================\nif /i not \"%CHECK_UPDATE%\"==\"true\" goto :SkipUpdateCheck\n\nREM Find git: try PortableGit first, then system git\nset \"UPDATE_GIT_CMD=\"\nif exist \"%~dp0PortableGit\\bin\\git.exe\" (\n    set \"UPDATE_GIT_CMD=%~dp0PortableGit\\bin\\git.exe\"\n) else (\n    where git >nul 2>&1\n    if !ERRORLEVEL! EQU 0 (\n        for /f \"tokens=*\" %%i in ('where git 2^>nul') do (\n            if not defined UPDATE_GIT_CMD set \"UPDATE_GIT_CMD=%%i\"\n        )\n    )\n)\nif not defined UPDATE_GIT_CMD goto :SkipUpdateCheck\n\ncd /d \"%~dp0\"\n\"!UPDATE_GIT_CMD!\" rev-parse --git-dir >nul 2>&1\nif !ERRORLEVEL! NEQ 0 goto :SkipUpdateCheck\n\necho [Update] Checking for updates...\n\nfor /f \"tokens=*\" %%i in ('\"!UPDATE_GIT_CMD!\" rev-parse --abbrev-ref HEAD 2^>nul') do set UPDATE_BRANCH=%%i\nif \"!UPDATE_BRANCH!\"==\"\" set UPDATE_BRANCH=main\nfor /f \"tokens=*\" %%i in ('\"!UPDATE_GIT_CMD!\" rev-parse --short HEAD 2^>nul') do set UPDATE_LOCAL=%%i\n\n\"!UPDATE_GIT_CMD!\" fetch origin --quiet 2>nul\nif !ERRORLEVEL! NEQ 0 (\n    echo [Update] Network unreachable, skipping.\n    echo.\n    goto :SkipUpdateCheck\n)\n\nfor /f \"tokens=*\" %%i in ('\"!UPDATE_GIT_CMD!\" rev-parse --short origin/!UPDATE_BRANCH! 2^>nul') do set UPDATE_REMOTE=%%i\n\nif \"!UPDATE_REMOTE!\"==\"\" goto :SkipUpdateCheck\nif \"!UPDATE_LOCAL!\"==\"!UPDATE_REMOTE!\" (\n    echo [Update] Already up to date ^(!UPDATE_LOCAL!^).\n    echo.\n    goto :SkipUpdateCheck\n)\n\necho.\necho ========================================\necho   Update available!\necho ========================================\necho   Current: !UPDATE_LOCAL!  -^>  Latest: !UPDATE_REMOTE!\necho.\necho   Recent changes:\n\"!UPDATE_GIT_CMD!\" --no-pager log --oneline HEAD..origin/!UPDATE_BRANCH! 2>nul\necho.\n\nset /p UPDATE_NOW=\"Update now before starting? (Y/N): \"\nif /i \"!UPDATE_NOW!\"==\"Y\" (\n    if exist \"%~dp0check_update.bat\" (\n        call \"%~dp0check_update.bat\"\n    ) else (\n        echo Pulling latest changes...\n        \"!UPDATE_GIT_CMD!\" pull --ff-only origin !UPDATE_BRANCH! 2>nul\n        if !ERRORLEVEL! NEQ 0 (\n            echo [Update] Update failed. Please update manually.\n        )\n    )\n) else (\n    echo [Update] Skipped. Run check_update.bat to update later.\n)\necho.\n\n:SkipUpdateCheck\n\necho ============================================\necho   ACE-Step 1.5 API - AMD ROCm 7.2 Edition\necho ============================================\necho.\n\nREM Activate venv if it exists\nif exist \"%VENV_DIR%\\Scripts\\activate.bat\" (\n    echo Activating virtual environment: %VENV_DIR%\n    call \"%VENV_DIR%\\Scripts\\activate.bat\"\n) else (\n    echo WARNING: venv_rocm not found at %VENV_DIR%\n    echo Using system Python. See requirements-rocm.txt for setup instructions.\n)\necho.\n\nREM Verify ROCm PyTorch is installed\npython -c \"import torch; assert torch.cuda.is_available(), 'No GPU detected'; print(f'GPU: {torch.cuda.get_device_name(0)}'); hip=getattr(torch.version,'hip',None); print(f'HIP: {hip}' if hip else 'WARNING: Not a ROCm build')\" 2>nul\nif !ERRORLEVEL! NEQ 0 (\n    echo.\n    echo ========================================\n    echo  ERROR: ROCm PyTorch not detected!\n    echo ========================================\n    echo.\n    echo Please install ROCm PyTorch first. See requirements-rocm.txt for instructions.\n    echo.\n    pause\n    exit /b 1\n)\necho.\n\necho Starting ACE-Step REST API Server...\necho API will be available at: http://%HOST%:%PORT%\necho API Documentation: http://%HOST%:%PORT%/docs\necho.\n\nREM Build command with optional parameters\nset \"CMD=--host %HOST% --port %PORT%\"\nif not \"%API_KEY%\"==\"\" set \"CMD=!CMD! %API_KEY%\"\nif not \"%DOWNLOAD_SOURCE%\"==\"\" set \"CMD=!CMD! %DOWNLOAD_SOURCE%\"\nif not \"%LM_MODEL_PATH%\"==\"\" set \"CMD=!CMD! %LM_MODEL_PATH%\"\n\npython -u acestep\\api_server.py !CMD!\n\npause\nendlocal\n"
  },
  {
    "path": "start_api_server_rocm.sh",
    "content": "#!/usr/bin/env bash\n# ACE-Step REST API Server Launcher - Linux AMD ROCm\n# For AMD RX 7000/6000 series GPUs on Linux\n# Requires: ROCm 6.x+ and ROCm PyTorch from https://pytorch.org/\n#\n# Setup:\n#   1. Install ROCm: https://rocm.docs.amd.com/projects/install-on-linux/\n#   2. Create venv:  python3 -m venv venv_rocm\n#   3. Activate:     source venv_rocm/bin/activate\n#   4. Install PyTorch for ROCm:\n#      pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/rocm6.3\n#   5. Install dependencies:\n#      pip install -r requirements-rocm-linux.txt\n#   6. Run this script: ./start_api_server_rocm.sh\n\nset -euo pipefail\nSCRIPT_DIR=\"$(cd \"$(dirname \"${BASH_SOURCE[0]}\")\" && pwd)\"\n\n# ==================== ROCm Configuration ====================\n# Force PyTorch LM backend (bypasses nano-vllm flash_attn dependency)\nexport ACESTEP_LM_BACKEND=\"pt\"\n\n# RDNA3 GPU architecture override (RX 7900 XT/XTX, RX 7800 XT, etc.)\n# Change to 11.0.1 for gfx1101 (RX 7700 XT, RX 7800 XT)\n# Change to 11.0.2 for gfx1102 (RX 7600)\nexport HSA_OVERRIDE_GFX_VERSION=\"${HSA_OVERRIDE_GFX_VERSION:-11.0.0}\"\n\n# MIOpen: use fast heuristic kernel selection instead of exhaustive benchmarking\n# Without this, first-run VAE decode hangs for minutes on each conv layer\nexport MIOPEN_FIND_MODE=\"FAST\"\n\n# HuggingFace tokenizer parallelism\nexport TOKENIZERS_PARALLELISM=\"false\"\n\n# ==================== Server Configuration ====================\nHOST=\"127.0.0.1\"\n# HOST=\"0.0.0.0\"\nPORT=8001\n\n# ==================== Model Configuration ====================\n# API key for authentication (optional)\nAPI_KEY=\"\"\n# API_KEY=\"--api-key sk-your-secret-key\"\n\n# Download source: auto, huggingface, modelscope\nDOWNLOAD_SOURCE=\"\"\n# DOWNLOAD_SOURCE=\"--download-source modelscope\"\n\n# LLM (Language Model) initialization settings\n# By default, LLM is auto-enabled/disabled based on GPU VRAM:\n#   - <=6GB VRAM: LLM disabled (DiT-only mode)\n#   - >6GB VRAM: LLM enabled\n# Values: auto (default), true (force enable), false (force disable)\nexport ACESTEP_INIT_LLM=auto\n# export ACESTEP_INIT_LLM=true\n# export ACESTEP_INIT_LLM=false\n\n# LM model path (optional, only used when LLM is enabled)\n# Available models: acestep-5Hz-lm-0.6B, acestep-5Hz-lm-1.7B, acestep-5Hz-lm-4B\nLM_MODEL_PATH=\"\"\n# LM_MODEL_PATH=\"--lm-model-path acestep-5Hz-lm-0.6B\"\n\n# Update check on startup (set to \"false\" to disable)\nCHECK_UPDATE=\"true\"\n# CHECK_UPDATE=\"false\"\n\n# Skip model loading at startup (models will be lazy-loaded on first request)\n# Set to \"true\" to start server quickly without loading models\n# export ACESTEP_NO_INIT=false\n# export ACESTEP_NO_INIT=true\n\n# ==================== Venv Configuration ====================\nVENV_DIR=\"${SCRIPT_DIR}/venv_rocm\"\n\n# ==================== Startup Update Check ====================\n_startup_update_check() {\n    [[ \"$CHECK_UPDATE\" != \"true\" ]] && return 0\n    command -v git &>/dev/null || return 0\n    cd \"$SCRIPT_DIR\" || return 0\n    git rev-parse --git-dir &>/dev/null 2>&1 || return 0\n\n    local branch commit remote_commit\n    branch=\"$(git rev-parse --abbrev-ref HEAD 2>/dev/null || echo \"main\")\"\n    commit=\"$(git rev-parse --short HEAD 2>/dev/null || echo \"\")\"\n    [[ -z \"$commit\" ]] && return 0\n\n    echo \"[Update] Checking for updates...\"\n\n    local fetch_ok=0\n    if command -v timeout &>/dev/null; then\n        timeout 10 git fetch origin --quiet 2>/dev/null && fetch_ok=1\n    else\n        git fetch origin --quiet 2>/dev/null && fetch_ok=1\n    fi\n\n    if [[ $fetch_ok -eq 0 ]]; then\n        echo \"[Update] Network unreachable, skipping.\"\n        echo\n        return 0\n    fi\n\n    remote_commit=\"$(git rev-parse --short \"origin/$branch\" 2>/dev/null || echo \"\")\"\n\n    if [[ -z \"$remote_commit\" || \"$commit\" == \"$remote_commit\" ]]; then\n        echo \"[Update] Already up to date ($commit).\"\n        echo\n        return 0\n    fi\n\n    echo\n    echo \"========================================\"\n    echo \"  Update available!\"\n    echo \"========================================\"\n    echo \"  Current: $commit  ->  Latest: $remote_commit\"\n    echo\n    echo \"  Recent changes:\"\n    git --no-pager log --oneline \"HEAD..origin/$branch\" 2>/dev/null | head -10\n    echo\n\n    read -rp \"Update now before starting? (Y/N): \" update_choice\n    if [[ \"${update_choice^^}\" == \"Y\" ]]; then\n        if [[ -f \"$SCRIPT_DIR/check_update.sh\" ]]; then\n            bash \"$SCRIPT_DIR/check_update.sh\"\n        else\n            echo \"Pulling latest changes...\"\n            git pull --ff-only origin \"$branch\" 2>/dev/null || {\n                echo \"[Update] Update failed. Please run: git pull\"\n            }\n        fi\n    else\n        echo \"[Update] Skipped. Run ./check_update.sh to update later.\"\n    fi\n    echo\n}\n_startup_update_check\n\necho \"============================================\"\necho \"  ACE-Step 1.5 API - Linux AMD ROCm Edition\"\necho \"============================================\"\necho\n\n# Activate venv if it exists\nif [[ -f \"$VENV_DIR/bin/activate\" ]]; then\n    echo \"Activating virtual environment: $VENV_DIR\"\n    source \"$VENV_DIR/bin/activate\"\nelse\n    echo \"WARNING: venv_rocm not found at $VENV_DIR\"\n    echo \"Using system Python. See requirements-rocm-linux.txt for setup instructions.\"\nfi\necho\n\n# Verify ROCm PyTorch is installed\nif ! python3 -c \"\nimport torch\nassert torch.cuda.is_available(), 'No GPU detected'\nprint(f'GPU: {torch.cuda.get_device_name(0)}')\nhip = getattr(torch.version, 'hip', None)\nprint(f'HIP: {hip}' if hip else 'WARNING: Not a ROCm build')\n\" 2>/dev/null; then\n    echo\n    echo \"========================================\"\n    echo \" ERROR: ROCm PyTorch not detected!\"\n    echo \"========================================\"\n    echo\n    echo \"Please install ROCm PyTorch first.\"\n    echo \"See requirements-rocm-linux.txt for instructions.\"\n    echo\n    echo \"Quick setup:\"\n    echo \"  python3 -m venv venv_rocm\"\n    echo \"  source venv_rocm/bin/activate\"\n    echo \"  pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/rocm6.3\"\n    echo \"  pip install -r requirements-rocm-linux.txt\"\n    echo\n    exit 1\nfi\necho\n\necho \"Starting ACE-Step REST API Server...\"\necho \"API will be available at: http://${HOST}:${PORT}\"\necho \"API Documentation: http://${HOST}:${PORT}/docs\"\necho\n\n# Build command with optional parameters\nCMD=\"--host $HOST --port $PORT\"\n[[ -n \"$API_KEY\" ]] && CMD=\"$CMD $API_KEY\"\n[[ -n \"$DOWNLOAD_SOURCE\" ]] && CMD=\"$CMD $DOWNLOAD_SOURCE\"\n[[ -n \"$LM_MODEL_PATH\" ]] && CMD=\"$CMD $LM_MODEL_PATH\"\n\ncd \"$SCRIPT_DIR\" && python3 -u acestep/api_server.py $CMD\n"
  },
  {
    "path": "start_api_server_xpu.bat",
    "content": "@echo off\nsetlocal enabledelayedexpansion\nREM ACE-Step REST API Server Launcher - Intel XPU\nREM For Intel Arc GPUs (A770, A750, A580, A380) and integrated graphics\nREM Requires: Python 3.11, PyTorch XPU nightly from download.pytorch.org/whl/xpu\nREM IMPORTANT: Uses torch.xpu backend with SYCL/Level Zero acceleration\n\nREM ==================== XPU Configuration ====================\nREM XPU performance optimization (from verified working setup)\nset SYCL_CACHE_PERSISTENT=1\nset SYCL_PI_LEVEL_ZERO_USE_IMMEDIATE_COMMANDLISTS=1\nset PYTORCH_DEVICE=xpu\n\nREM Disable torch.compile (not fully supported on XPU yet)\nset TORCH_COMPILE_BACKEND=eager\n\nREM HuggingFace tokenizer parallelism\nset TOKENIZERS_PARALLELISM=false\n\nREM Force torchaudio to use ffmpeg backend (torchcodec not available on XPU)\nset TORCHAUDIO_USE_BACKEND=ffmpeg\n\nREM ==================== Server Configuration ====================\nset HOST=127.0.0.1\nREM set HOST=0.0.0.0\nset PORT=8001\n\nREM ==================== Model Configuration ====================\nREM API key for authentication (optional)\nREM set API_KEY=--api-key sk-your-secret-key\n\nREM Download source: auto, huggingface, modelscope\nset DOWNLOAD_SOURCE=\n\nREM LLM (Language Model) initialization settings\nREM By default, LLM is auto-enabled/disabled based on GPU VRAM:\nREM   - <=6GB VRAM: LLM disabled (DiT-only mode)\nREM   - >6GB VRAM: LLM enabled\nREM Values: auto (default), true (force enable), false (force disable)\nset ACESTEP_INIT_LLM=auto\nREM set ACESTEP_INIT_LLM=true\nREM set ACESTEP_INIT_LLM=false\n\nREM LM model path (optional, only used when LLM is enabled)\nREM Available models: acestep-5Hz-lm-0.6B, acestep-5Hz-lm-1.7B, acestep-5Hz-lm-4B\nREM set LM_MODEL_PATH=--lm-model-path acestep-5Hz-lm-4B\n\nREM Update check on startup (set to false to disable)\nset CHECK_UPDATE=true\nREM set CHECK_UPDATE=false\n\nREM Skip model loading at startup (models will be lazy-loaded on first request)\nREM Set to true to start server quickly without loading models\nREM set ACESTEP_NO_INIT=false\nREM set ACESTEP_NO_INIT=true\n\nREM ==================== Venv Configuration ====================\nREM Path to the XPU virtual environment (relative to this script)\nset VENV_DIR=%~dp0venv_xpu\n\nREM ==================== Launch ====================\n\nREM ==================== Startup Update Check ====================\nif /i not \"%CHECK_UPDATE%\"==\"true\" goto :SkipUpdateCheck\n\nREM Find git: try PortableGit first, then system git\nset \"UPDATE_GIT_CMD=\"\nif exist \"%~dp0PortableGit\\bin\\git.exe\" (\n    set \"UPDATE_GIT_CMD=%~dp0PortableGit\\bin\\git.exe\"\n) else (\n    where git >nul 2>&1\n    if !ERRORLEVEL! EQU 0 (\n        for /f \"tokens=*\" %%i in ('where git 2^>nul') do (\n            if not defined UPDATE_GIT_CMD set \"UPDATE_GIT_CMD=%%i\"\n        )\n    )\n)\nif not defined UPDATE_GIT_CMD goto :SkipUpdateCheck\n\ncd /d \"%~dp0\"\n\"!UPDATE_GIT_CMD!\" rev-parse --git-dir >nul 2>&1\nif !ERRORLEVEL! NEQ 0 goto :SkipUpdateCheck\n\necho [Update] Checking for updates...\n\nfor /f \"tokens=*\" %%i in ('\"!UPDATE_GIT_CMD!\" rev-parse --abbrev-ref HEAD 2^>nul') do set UPDATE_BRANCH=%%i\nif \"!UPDATE_BRANCH!\"==\"\" set UPDATE_BRANCH=main\nfor /f \"tokens=*\" %%i in ('\"!UPDATE_GIT_CMD!\" rev-parse --short HEAD 2^>nul') do set UPDATE_LOCAL=%%i\n\n\"!UPDATE_GIT_CMD!\" fetch origin --quiet 2>nul\nif !ERRORLEVEL! NEQ 0 (\n    echo [Update] Network unreachable, skipping.\n    echo.\n    goto :SkipUpdateCheck\n)\n\nfor /f \"tokens=*\" %%i in ('\"!UPDATE_GIT_CMD!\" rev-parse --short origin/!UPDATE_BRANCH! 2^>nul') do set UPDATE_REMOTE=%%i\n\nif \"!UPDATE_REMOTE!\"==\"\" goto :SkipUpdateCheck\nif \"!UPDATE_LOCAL!\"==\"!UPDATE_REMOTE!\" (\n    echo [Update] Already up to date ^(!UPDATE_LOCAL!^).\n    echo.\n    goto :SkipUpdateCheck\n)\n\necho.\necho ========================================\necho   Update available!\necho ========================================\necho   Current: !UPDATE_LOCAL!  -^>  Latest: !UPDATE_REMOTE!\necho.\necho   Recent changes:\n\"!UPDATE_GIT_CMD!\" --no-pager log --oneline HEAD..origin/!UPDATE_BRANCH! 2>nul\necho.\n\nset /p UPDATE_NOW=\"Update now before starting? (Y/N): \"\nif /i \"!UPDATE_NOW!\"==\"Y\" (\n    if exist \"%~dp0check_update.bat\" (\n        call \"%~dp0check_update.bat\"\n    ) else (\n        echo Pulling latest changes...\n        \"!UPDATE_GIT_CMD!\" pull --ff-only origin !UPDATE_BRANCH! 2>nul\n        if !ERRORLEVEL! NEQ 0 (\n            echo [Update] Update failed. Please update manually.\n        )\n    )\n) else (\n    echo [Update] Skipped. Run check_update.bat to update later.\n)\necho.\n\n:SkipUpdateCheck\n\necho ============================================\necho   ACE-Step 1.5 API - Intel XPU Edition\necho ============================================\necho.\n\nREM Activate venv if it exists\nif exist \"%VENV_DIR%\\Scripts\\activate.bat\" (\n    echo Activating XPU virtual environment: %VENV_DIR%\n    call \"%VENV_DIR%\\Scripts\\activate.bat\"\n) else (\n    echo ========================================\n    echo  ERROR: venv_xpu not found!\n    echo ========================================\n    echo.\n    echo Please create the XPU virtual environment first:\n    echo.\n    echo   1. Run: python -m venv venv_xpu\n    echo   2. Run: venv_xpu\\Scripts\\activate\n    echo   3. Run: pip install -r requirements-xpu.txt\n    echo.\n    echo Or use the setup script ^(if available^)\n    echo   setup_xpu.bat\n    echo.\n    pause\n    exit /b 1\n)\necho.\n\nREM Verify XPU PyTorch is installed\npython -c \"import torch; assert hasattr(torch, 'xpu') and torch.xpu.is_available(), 'Intel XPU not detected'; print(f'XPU: Intel Arc GPU detected'); print(f'PyTorch XPU version: {torch.__version__}')\" 2>nul\nif !ERRORLEVEL! NEQ 0 (\n    echo.\n    echo ========================================\n    echo  ERROR: Intel XPU PyTorch not detected!\n    echo ========================================\n    echo.\n    echo Please install PyTorch with XPU support. See requirements-xpu.txt for instructions.\n    echo.\n    echo Quick setup:\n    echo   1. Activate venv: venv_xpu\\Scripts\\activate\n    echo   2. Install: pip install --upgrade pip\n    echo   3. Install XPyTorch: pip install -r requirements-xpu.txt\n    echo.\n    pause\n    exit /b 1\n)\necho.\n\necho Starting ACE-Step REST API Server...\necho API will be available at: http://%HOST%:%PORT%\necho API Documentation: http://%HOST%:%PORT%/docs\necho.\n\nREM Build command with optional parameters\nset \"CMD=--host %HOST% --port %PORT%\"\nif not \"%API_KEY%\"==\"\" set \"CMD=!CMD! %API_KEY%\"\nif not \"%DOWNLOAD_SOURCE%\"==\"\" set \"CMD=!CMD! %DOWNLOAD_SOURCE%\"\nif not \"%LM_MODEL_PATH%\"==\"\" set \"CMD=!CMD! %LM_MODEL_PATH%\"\n\npython -u acestep\\api_server.py !CMD!\n\npause\nendlocal\n"
  },
  {
    "path": "start_gradio_ui.bat",
    "content": "@echo off\nsetlocal enabledelayedexpansion\nREM ACE-Step Gradio Web UI Launcher\nREM This script launches the Gradio web interface for ACE-Step\n\nREM ==================== Load .env Configuration ====================\nREM Load settings from .env file if it exists\ncall :LoadEnvFile\n\nREM ==================== Configuration ====================\nREM Default values (used if not set in .env file)\nREM You can override these by uncommenting and modifying the lines below\nREM or by creating a .env file (recommended to survive updates)\n\nREM Server settings\nif not defined PORT set PORT=7860\nif not defined SERVER_NAME set SERVER_NAME=127.0.0.1\nREM set SERVER_NAME=0.0.0.0\nREM set SHARE=--share\n\nREM UI language: en, zh, he, ja\nif not defined LANGUAGE set LANGUAGE=en\n\nREM Batch size: default batch size for generation (1 to GPU-dependent max)\nREM When not specified, defaults to min(2, GPU_max)\nREM set BATCH_SIZE=--batch_size 4\n\nREM Model settings\nif not defined CONFIG_PATH set CONFIG_PATH=--config_path acestep-v15-turbo\nif not defined LM_MODEL_PATH set LM_MODEL_PATH=--lm_model_path acestep-5Hz-lm-0.6B\nREM set OFFLOAD_TO_CPU=--offload_to_cpu true\n\nREM LLM (Language Model) initialization settings\nREM By default, LLM is auto-enabled/disabled based on GPU VRAM:\nREM   - <=6GB VRAM: LLM disabled (DiT-only mode)\nREM   - >6GB VRAM: LLM enabled\nREM Values: auto (default), true (force enable), false (force disable)\nREM set INIT_LLM=--init_llm auto\nREM set INIT_LLM=--init_llm true\nREM set INIT_LLM=--init_llm false\n\nREM Download source settings\nREM Preferred download source: auto (default), huggingface, or modelscope\nREM set DOWNLOAD_SOURCE=--download-source modelscope\nREM set DOWNLOAD_SOURCE=--download-source huggingface\nif not defined DOWNLOAD_SOURCE set DOWNLOAD_SOURCE=\n\nREM Update check on startup (set to false to disable)\nif not defined CHECK_UPDATE set CHECK_UPDATE=true\nREM set CHECK_UPDATE=false\n\nREM Auto-initialize models on startup\nif not defined INIT_SERVICE set INIT_SERVICE=--init_service true\n\nREM API settings (enable REST API alongside Gradio)\nREM set ENABLE_API=--enable-api\nREM set API_KEY=--api-key sk-your-secret-key\n\nREM Authentication settings\nREM set AUTH_USERNAME=--auth-username admin\nREM set AUTH_PASSWORD=--auth-password password\n\nREM ==================== Launch ====================\n\nREM ==================== Startup Update Check ====================\nif /i not \"%CHECK_UPDATE%\"==\"true\" goto :SkipUpdateCheck\n\nREM Find git: try PortableGit first, then system git\nset \"UPDATE_GIT_CMD=\"\nif exist \"%~dp0PortableGit\\bin\\git.exe\" (\n    set \"UPDATE_GIT_CMD=%~dp0PortableGit\\bin\\git.exe\"\n) else (\n    where git >nul 2>&1\n    if !ERRORLEVEL! EQU 0 (\n        for /f \"tokens=*\" %%i in ('where git 2^>nul') do (\n            if not defined UPDATE_GIT_CMD set \"UPDATE_GIT_CMD=%%i\"\n        )\n    )\n)\nif not defined UPDATE_GIT_CMD goto :SkipUpdateCheck\n\ncd /d \"%~dp0\"\n\"!UPDATE_GIT_CMD!\" rev-parse --git-dir >nul 2>&1\nif !ERRORLEVEL! NEQ 0 goto :SkipUpdateCheck\n\necho [Update] Checking for updates...\n\nfor /f \"tokens=*\" %%i in ('\"!UPDATE_GIT_CMD!\" rev-parse --abbrev-ref HEAD 2^>nul') do set UPDATE_BRANCH=%%i\nif \"!UPDATE_BRANCH!\"==\"\" set UPDATE_BRANCH=main\nfor /f \"tokens=*\" %%i in ('\"!UPDATE_GIT_CMD!\" rev-parse --short HEAD 2^>nul') do set UPDATE_LOCAL=%%i\n\n\"!UPDATE_GIT_CMD!\" fetch origin --quiet 2>nul\nif !ERRORLEVEL! NEQ 0 (\n    echo [Update] Network unreachable, skipping.\n    echo.\n    goto :SkipUpdateCheck\n)\n\nfor /f \"tokens=*\" %%i in ('\"!UPDATE_GIT_CMD!\" rev-parse --short origin/!UPDATE_BRANCH! 2^>nul') do set UPDATE_REMOTE=%%i\n\nif \"!UPDATE_REMOTE!\"==\"\" goto :SkipUpdateCheck\nif \"!UPDATE_LOCAL!\"==\"!UPDATE_REMOTE!\" (\n    echo [Update] Already up to date ^(!UPDATE_LOCAL!^).\n    echo.\n    goto :SkipUpdateCheck\n)\n\necho.\necho ========================================\necho   Update available!\necho ========================================\necho   Current: !UPDATE_LOCAL!  -^>  Latest: !UPDATE_REMOTE!\necho.\necho   Recent changes:\n\"!UPDATE_GIT_CMD!\" --no-pager log --oneline HEAD..origin/!UPDATE_BRANCH! 2>nul\necho.\n\nset /p UPDATE_NOW=\"Update now before starting? (Y/N): \"\nif /i \"!UPDATE_NOW!\"==\"Y\" (\n    if exist \"%~dp0check_update.bat\" (\n        call \"%~dp0check_update.bat\"\n    ) else (\n        echo Pulling latest changes...\n        \"!UPDATE_GIT_CMD!\" pull --ff-only origin !UPDATE_BRANCH! 2>nul\n        if !ERRORLEVEL! NEQ 0 (\n            echo [Update] Update failed. Please update manually.\n        )\n    )\n) else (\n    echo [Update] Skipped. Run check_update.bat to update later.\n)\necho.\n\n:SkipUpdateCheck\n\necho Starting ACE-Step Gradio Web UI...\necho Server will be available at: http://%SERVER_NAME%:%PORT%\necho.\n\nREM Auto-detect Python environment\nif exist \"%~dp0python_embedded\\python.exe\" (\n    echo [Environment] Using embedded Python...\n\n    REM Build command with optional parameters\n    set \"PYTHON_EXE=%~dp0python_embedded\\python.exe\"\n    set \"SCRIPT_PATH=%~dp0acestep\\acestep_v15_pipeline.py\"\n    set \"CMD=--port %PORT% --server-name %SERVER_NAME% --language %LANGUAGE%\"\n    if not \"%SHARE%\"==\"\" set \"CMD=!CMD! %SHARE%\"\n    if not \"%CONFIG_PATH%\"==\"\" set \"CMD=!CMD! %CONFIG_PATH%\"\n    if not \"%LM_MODEL_PATH%\"==\"\" set \"CMD=!CMD! %LM_MODEL_PATH%\"\n    if not \"%OFFLOAD_TO_CPU%\"==\"\" set \"CMD=!CMD! %OFFLOAD_TO_CPU%\"\n    if not \"%INIT_LLM%\"==\"\" set \"CMD=!CMD! %INIT_LLM%\"\n    if not \"%DOWNLOAD_SOURCE%\"==\"\" set \"CMD=!CMD! %DOWNLOAD_SOURCE%\"\n    if not \"%INIT_SERVICE%\"==\"\" set \"CMD=!CMD! %INIT_SERVICE%\"\n    if not \"%BATCH_SIZE%\"==\"\" set \"CMD=!CMD! %BATCH_SIZE%\"\n    if not \"%ENABLE_API%\"==\"\" set \"CMD=!CMD! %ENABLE_API%\"\n    if not \"%API_KEY%\"==\"\" set \"CMD=!CMD! %API_KEY%\"\n    if not \"%AUTH_USERNAME%\"==\"\" set \"CMD=!CMD! %AUTH_USERNAME%\"\n    if not \"%AUTH_PASSWORD%\"==\"\" set \"CMD=!CMD! %AUTH_PASSWORD%\"\n\n    \"!PYTHON_EXE!\" \"!SCRIPT_PATH!\" !CMD!\n) else (\n    echo [Environment] Embedded Python not found, checking for uv...\n\n    REM Check if uv is installed\n    where uv >nul 2>&1\n    if !ERRORLEVEL! NEQ 0 (\n        echo.\n        echo ========================================\n        echo uv package manager not found!\n        echo ========================================\n        echo.\n        echo ACE-Step requires either:\n        echo   1. python_embedded directory ^(portable package^)\n        echo   2. uv package manager\n        echo.\n        echo Would you like to install uv now? ^(Recommended^)\n        echo.\n        set /p INSTALL_UV=\"Install uv? (Y/N): \"\n\n        if /i \"!INSTALL_UV!\"==\"Y\" (\n            echo.\n            REM Call install_uv.bat in silent mode\n            call \"%~dp0install_uv.bat\" --silent\n            set INSTALL_RESULT=!ERRORLEVEL!\n\n            if !INSTALL_RESULT! EQU 0 (\n                echo.\n                echo ========================================\n                echo uv installed successfully!\n                echo ========================================\n                echo.\n\n                REM Refresh PATH to include uv\n                if exist \"%USERPROFILE%\\.local\\bin\\uv.exe\" (\n                    set \"PATH=%USERPROFILE%\\.local\\bin;%PATH%\"\n                )\n                if exist \"%LOCALAPPDATA%\\Microsoft\\WinGet\\Links\\uv.exe\" (\n                    set \"PATH=%LOCALAPPDATA%\\Microsoft\\WinGet\\Links;%PATH%\"\n                )\n\n                REM Verify uv is available\n                where uv >nul 2>&1\n                if !ERRORLEVEL! EQU 0 (\n                    echo uv is now available!\n                    uv --version\n                    echo.\n                    goto :RunWithUv\n                ) else (\n                    REM Try direct paths\n                    if exist \"%USERPROFILE%\\.local\\bin\\uv.exe\" (\n                        set \"PATH=%USERPROFILE%\\.local\\bin;%PATH%\"\n                        goto :RunWithUv\n                    )\n                    if exist \"%LOCALAPPDATA%\\Microsoft\\WinGet\\Links\\uv.exe\" (\n                        set \"PATH=%LOCALAPPDATA%\\Microsoft\\WinGet\\Links;%PATH%\"\n                        goto :RunWithUv\n                    )\n\n                    echo.\n                    echo uv installed but not in PATH yet.\n                    echo Please restart your terminal or run:\n                    echo   %USERPROFILE%\\.local\\bin\\uv.exe run acestep\n                    echo.\n                    pause\n                    exit /b 1\n                )\n            ) else (\n                echo.\n                echo ========================================\n                echo Installation failed!\n                echo ========================================\n                echo.\n                echo Please install uv manually:\n                echo   1. Using PowerShell: irm https://astral.sh/uv/install.ps1 ^| iex\n                echo   2. Using winget: winget install --id=astral-sh.uv -e\n                echo   3. Download portable package: https://files.acemusic.ai/acemusic/win/ACE-Step-1.5.7z\n                echo.\n                pause\n                exit /b 1\n            )\n        ) else (\n            echo.\n            echo Installation cancelled.\n            echo.\n            echo To use ACE-Step, please either:\n            echo   1. Install uv: winget install --id=astral-sh.uv -e\n            echo   2. Download portable package: https://files.acemusic.ai/acemusic/win/ACE-Step-1.5.7z\n            echo.\n            pause\n            exit /b 1\n        )\n    )\n\n    :RunWithUv\n    echo [Environment] Using uv package manager...\n    echo.\n\n    REM Check if virtual environment exists\n    if not exist \"%~dp0.venv\" (\n        echo [Setup] Virtual environment not found. Setting up environment...\n        echo This will take a few minutes on first run.\n        echo.\n        echo Running: uv sync\n        echo.\n\n        uv sync\n\n        if !ERRORLEVEL! NEQ 0 (\n            echo.\n            echo [Retry] Online sync failed, retrying in offline mode...\n            echo.\n            uv sync --offline\n\n            if !ERRORLEVEL! NEQ 0 (\n                echo.\n                echo ========================================\n                echo [Error] Failed to setup environment\n                echo ========================================\n                echo.\n                echo Both online and offline modes failed.\n                echo Please check:\n                echo   1. Your internet connection ^(required for first-time setup^)\n                echo   2. Ensure you have enough disk space\n                echo   3. Try running: uv sync manually\n                echo.\n                pause\n                exit /b 1\n            )\n        )\n\n        echo.\n        echo ========================================\n        echo Environment setup completed!\n        echo ========================================\n        echo.\n    )\n\n    call :EnsureLegacyNvidiaTorchCompat\n    if !ERRORLEVEL! NEQ 0 exit /b !ERRORLEVEL!\n\n    echo Starting ACE-Step Gradio UI...\n    echo.\n\n    REM Build command with optional parameters\n    set \"ACESTEP_ARGS=acestep --port %PORT% --server-name %SERVER_NAME% --language %LANGUAGE%\"\n    if not \"%SHARE%\"==\"\" set \"ACESTEP_ARGS=!ACESTEP_ARGS! %SHARE%\"\n    if not \"%CONFIG_PATH%\"==\"\" set \"ACESTEP_ARGS=!ACESTEP_ARGS! %CONFIG_PATH%\"\n    if not \"%LM_MODEL_PATH%\"==\"\" set \"ACESTEP_ARGS=!ACESTEP_ARGS! %LM_MODEL_PATH%\"\n    if not \"%OFFLOAD_TO_CPU%\"==\"\" set \"ACESTEP_ARGS=!ACESTEP_ARGS! %OFFLOAD_TO_CPU%\"\n    if not \"%INIT_LLM%\"==\"\" set \"ACESTEP_ARGS=!ACESTEP_ARGS! %INIT_LLM%\"\n    if not \"%DOWNLOAD_SOURCE%\"==\"\" set \"ACESTEP_ARGS=!ACESTEP_ARGS! %DOWNLOAD_SOURCE%\"\n    if not \"%INIT_SERVICE%\"==\"\" set \"ACESTEP_ARGS=!ACESTEP_ARGS! %INIT_SERVICE%\"\n    if not \"%BATCH_SIZE%\"==\"\" set \"ACESTEP_ARGS=!ACESTEP_ARGS! %BATCH_SIZE%\"\n    if not \"%ENABLE_API%\"==\"\" set \"ACESTEP_ARGS=!ACESTEP_ARGS! %ENABLE_API%\"\n    if not \"%API_KEY%\"==\"\" set \"ACESTEP_ARGS=!ACESTEP_ARGS! %API_KEY%\"\n    if not \"%AUTH_USERNAME%\"==\"\" set \"ACESTEP_ARGS=!ACESTEP_ARGS! %AUTH_USERNAME%\"\n    if not \"%AUTH_PASSWORD%\"==\"\" set \"ACESTEP_ARGS=!ACESTEP_ARGS! %AUTH_PASSWORD%\"\n\n    uv run !ACESTEP_ARGS!\n    if !ERRORLEVEL! NEQ 0 (\n        echo.\n        echo [Retry] Online dependency resolution failed, retrying in offline mode...\n        echo.\n        uv run --offline !ACESTEP_ARGS!\n        if !ERRORLEVEL! NEQ 0 (\n            echo.\n            echo ========================================\n            echo [Error] Failed to start ACE-Step\n            echo ========================================\n            echo.\n            echo Both online and offline modes failed.\n            echo Please check:\n            echo   1. Your internet connection ^(for first-time setup^)\n            echo   2. If dependencies were previously installed ^(offline mode requires a prior successful install^)\n            echo   3. Try running: uv sync --offline\n            echo.\n            pause\n            exit /b 1\n        )\n    )\n)\n\npause\nendlocal\ngoto :eof\n\nREM ==================== Helper Functions ====================\n\n:EnsureLegacyNvidiaTorchCompat\nREM Auto-fix PyTorch for legacy NVIDIA GPUs (e.g., Pascal sm_61 on Quadro P1000)\nif /i \"%ACESTEP_SKIP_LEGACY_TORCH_FIX%\"==\"true\" exit /b 0\nif not exist \"%~dp0.venv\\Scripts\\python.exe\" exit /b 0\n\npushd \"%~dp0\"\n\".venv\\Scripts\\python.exe\" -c \"import os,sys; sys.path.insert(0, os.getcwd()); from acestep.launcher_compat import legacy_torch_fix_probe_exit_code; raise SystemExit(legacy_torch_fix_probe_exit_code())\" >nul 2>&1\nset \"LEGACY_CHECK_EXIT=!ERRORLEVEL!\"\n\nif \"!LEGACY_CHECK_EXIT!\"==\"0\" (\n    popd\n    exit /b 0\n)\nif not \"!LEGACY_CHECK_EXIT!\"==\"42\" (\n    echo [Compatibility] Error: legacy NVIDIA compatibility probe failed with exit code !LEGACY_CHECK_EXIT!.\n    popd\n    exit /b !LEGACY_CHECK_EXIT!\n)\n\necho [Compatibility] Legacy NVIDIA GPU detected with unsupported torch arch.\necho [Compatibility] Installing CUDA 12.1 torch build with sm_61 support...\nuv pip install --python .venv\\Scripts\\python.exe --force-reinstall --index-url https://download.pytorch.org/whl/cu121 torch==2.5.1+cu121 torchvision==0.20.1+cu121 torchaudio==2.5.1+cu121\nif !ERRORLEVEL! EQU 0 (\n    echo [Compatibility] Legacy torch install complete.\n    REM Keep a legacy-compatible torchao so INT8 quantization remains available\n    REM on low-VRAM Pascal/Quadro GPUs.\n    uv pip install --python .venv\\Scripts\\python.exe --force-reinstall torchao==0.11.0 >nul 2>&1\n    set \"TORCHAO_INSTALL_EXIT=!ERRORLEVEL!\"\n    if !TORCHAO_INSTALL_EXIT! EQU 0 (\n        echo [Compatibility] Installed torchao==0.11.0 (legacy-compatible).\n    ) else (\n        echo [Compatibility] Warning: failed to install torchao==0.11.0. Quantization may be unavailable.\n        set \"LEGACY_HELPER_EXIT=!TORCHAO_INSTALL_EXIT!\"\n        popd\n        exit /b !LEGACY_HELPER_EXIT!\n    )\n) else (\n    set \"LEGACY_INSTALL_EXIT=!ERRORLEVEL!\"\n    echo [Compatibility] Warning: automatic legacy torch install failed.\n    echo [Compatibility] Run manually:\n    echo   uv pip install --python .venv\\Scripts\\python.exe --force-reinstall --index-url https://download.pytorch.org/whl/cu121 torch==2.5.1+cu121 torchvision==0.20.1+cu121 torchaudio==2.5.1+cu121\n    set \"LEGACY_HELPER_EXIT=!LEGACY_INSTALL_EXIT!\"\n    popd\n    exit /b !LEGACY_HELPER_EXIT!\n)\npopd\nexit /b 0\n\n:LoadEnvFile\nREM Load environment variables from .env file if it exists\nset \"ENV_FILE=%~dp0.env\"\nif not exist \"%ENV_FILE%\" (\n    exit /b 0\n)\n\necho [Config] Loading configuration from .env file...\nfor /f \"usebackq tokens=1,* delims==\" %%a in (\"%ENV_FILE%\") do (\n    set \"line=%%a\"\n    set \"value=%%b\"\n    \n    REM Skip empty lines and comments\n    if not \"!line!\"==\"\" (\n        set \"first_char=!line:~0,1!\"\n        if not \"!first_char!\"==\"#\" (\n            REM Remove leading/trailing spaces from key\n            for /f \"tokens=* delims= \" %%x in (\"!line!\") do set \"key=%%x\"\n            \n            REM Map .env variable names to batch script variables\n            if /i \"!key!\"==\"ACESTEP_CONFIG_PATH\" (\n                if not \"!value!\"==\"\" set \"CONFIG_PATH=--config_path !value!\"\n            )\n            if /i \"!key!\"==\"ACESTEP_LM_MODEL_PATH\" (\n                if not \"!value!\"==\"\" set \"LM_MODEL_PATH=--lm_model_path !value!\"\n            )\n            if /i \"!key!\"==\"ACESTEP_INIT_LLM\" (\n                if not \"!value!\"==\"\" (\n                    if not \"!value!\"==\"auto\" set \"INIT_LLM=--init_llm !value!\"\n                )\n            )\n            if /i \"!key!\"==\"ACESTEP_DOWNLOAD_SOURCE\" (\n                if not \"!value!\"==\"\" (\n                    if not \"!value!\"==\"auto\" set \"DOWNLOAD_SOURCE=--download-source !value!\"\n                )\n            )\n            if /i \"!key!\"==\"ACESTEP_API_KEY\" (\n                if not \"!value!\"==\"\" set \"API_KEY=--api-key !value!\"\n            )\n            if /i \"!key!\"==\"PORT\" (\n                if not \"!value!\"==\"\" set \"PORT=!value!\"\n            )\n            if /i \"!key!\"==\"SERVER_NAME\" (\n                if not \"!value!\"==\"\" set \"SERVER_NAME=!value!\"\n            )\n            if /i \"!key!\"==\"LANGUAGE\" (\n                if not \"!value!\"==\"\" set \"LANGUAGE=!value!\"\n            )\n            if /i \"!key!\"==\"ACESTEP_BATCH_SIZE\" (\n                if not \"!value!\"==\"\" set \"BATCH_SIZE=--batch_size !value!\"\n            )\n        )\n    )\n)\necho [Config] Configuration loaded from .env\nexit /b 0\n"
  },
  {
    "path": "start_gradio_ui.sh",
    "content": "#!/usr/bin/env bash\n# ACE-Step Gradio Web UI Launcher - Linux (CUDA)\n# This script launches the Gradio web interface for ACE-Step\n\nset -euo pipefail\nSCRIPT_DIR=\"$(cd \"$(dirname \"${BASH_SOURCE[0]}\")\" && pwd)\"\n\n# ==================== Load .env Configuration ====================\n# Load settings from .env file if it exists\n_load_env_file() {\n    local env_file=\"${SCRIPT_DIR}/.env\"\n    if [[ ! -f \"$env_file\" ]]; then\n        return 0\n    fi\n    \n    echo \"[Config] Loading configuration from .env file...\"\n    \n    # Read .env file and export variables\n    while IFS='=' read -r key value || [[ -n \"$key\" ]]; do\n        # Skip empty lines and comments\n        [[ -z \"$key\" || \"$key\" =~ ^[[:space:]]*# ]] && continue\n        \n        # Trim whitespace from key and value\n        key=\"${key#\"${key%%[![:space:]]*}\"}\"\n        key=\"${key%\"${key##*[![:space:]]}\"}\"\n        value=\"${value#\"${value%%[![:space:]]*}\"}\"\n        value=\"${value%\"${value##*[![:space:]]}\"}\"\n        \n        # Map .env variable names to script variables\n        case \"$key\" in\n            ACESTEP_CONFIG_PATH)\n                [[ -n \"$value\" ]] && CONFIG_PATH=\"--config_path $value\"\n                ;;\n            ACESTEP_LM_MODEL_PATH)\n                [[ -n \"$value\" ]] && LM_MODEL_PATH=\"--lm_model_path $value\"\n                ;;\n            ACESTEP_INIT_LLM)\n                if [[ -n \"$value\" && \"$value\" != \"auto\" ]]; then\n                    INIT_LLM=\"--init_llm $value\"\n                fi\n                ;;\n            ACESTEP_DOWNLOAD_SOURCE)\n                if [[ -n \"$value\" && \"$value\" != \"auto\" ]]; then\n                    DOWNLOAD_SOURCE=\"--download-source $value\"\n                fi\n                ;;\n            ACESTEP_API_KEY)\n                [[ -n \"$value\" ]] && API_KEY=\"--api-key $value\"\n                ;;\n            PORT)\n                [[ -n \"$value\" ]] && PORT=\"$value\"\n                ;;\n            SERVER_NAME)\n                [[ -n \"$value\" ]] && SERVER_NAME=\"$value\"\n                ;;\n            LANGUAGE)\n                [[ -n \"$value\" ]] && LANGUAGE=\"$value\"\n                ;;\n            ACESTEP_BATCH_SIZE)\n                [[ -n \"$value\" ]] && BATCH_SIZE=\"--batch_size $value\"\n                ;;\n        esac\n    done < \"$env_file\"\n    \n    echo \"[Config] Configuration loaded from .env\"\n}\n\n_load_env_file\n\n# ==================== Configuration ====================\n# Default values (used if not set in .env file)\n# You can override these by uncommenting and modifying the lines below\n# or by creating a .env file (recommended to survive updates)\n\n# Server settings\n: \"${PORT:=7860}\"\n: \"${SERVER_NAME:=127.0.0.1}\"\n# SERVER_NAME=\"0.0.0.0\"\nSHARE=\"${SHARE:-}\"\n# SHARE=\"--share\"\n\n# Reset LANGUAGE if it contains an invalid value (e.g. system locale like en_CA:en)\ncase \"$LANGUAGE\" in\n    en|zh|he|ja) ;;\n    *) unset LANGUAGE ;;\nesac\n# UI language: en, zh, he, ja\n: \"${LANGUAGE:=en}\"\n\n# Batch size: default batch size for generation (1 to GPU-dependent max)\n# When not specified, defaults to min(2, GPU_max)\nBATCH_SIZE=\"${BATCH_SIZE:-}\"\n# BATCH_SIZE=\"--batch_size 4\"\n\n# Model settings\n: \"${CONFIG_PATH:=--config_path acestep-v15-turbo}\"\n: \"${LM_MODEL_PATH:=--lm_model_path acestep-5Hz-lm-0.6B}\"\n# OFFLOAD_TO_CPU=\"--offload_to_cpu true\"\nOFFLOAD_TO_CPU=\"${OFFLOAD_TO_CPU:-}\"\n\n# LLM (Language Model) initialization settings\n# By default, LLM is auto-enabled/disabled based on GPU VRAM:\n#   - <=6GB VRAM: LLM disabled (DiT-only mode)\n#   - >6GB VRAM: LLM enabled\n# Values: auto (default), true (force enable), false (force disable)\nINIT_LLM=\"${INIT_LLM:-}\"\n# INIT_LLM=\"--init_llm auto\"\n# INIT_LLM=\"--init_llm true\"\n# INIT_LLM=\"--init_llm false\"\n\n# Download source settings\n# Preferred download source: auto (default), huggingface, or modelscope\nDOWNLOAD_SOURCE=\"${DOWNLOAD_SOURCE:-}\"\n# DOWNLOAD_SOURCE=\"--download-source modelscope\"\n# DOWNLOAD_SOURCE=\"--download-source huggingface\"\n\n# Update check on startup (set to \"false\" to disable)\n: \"${CHECK_UPDATE:=true}\"\n# CHECK_UPDATE=\"false\"\n\n# Auto-initialize models on startup\n: \"${INIT_SERVICE:=--init_service true}\"\n\n# API settings (enable REST API alongside Gradio)\nENABLE_API=\"${ENABLE_API:-}\"\n# ENABLE_API=\"--enable-api\"\nAPI_KEY=\"${API_KEY:-}\"\n# API_KEY=\"--api-key sk-your-secret-key\"\n\n# Authentication settings\nAUTH_USERNAME=\"${AUTH_USERNAME:-}\"\n# AUTH_USERNAME=\"--auth-username admin\"\nAUTH_PASSWORD=\"${AUTH_PASSWORD:-}\"\n# AUTH_PASSWORD=\"--auth-password password\"\n\n# ==================== Launch ====================\n\n# ==================== Startup Update Check ====================\n_startup_update_check() {\n    [[ \"$CHECK_UPDATE\" != \"true\" ]] && return 0\n    command -v git &>/dev/null || return 0\n    cd \"$SCRIPT_DIR\" || return 0\n    git rev-parse --git-dir &>/dev/null 2>&1 || return 0\n\n    local branch commit remote_commit\n    branch=\"$(git rev-parse --abbrev-ref HEAD 2>/dev/null || echo \"main\")\"\n    commit=\"$(git rev-parse --short HEAD 2>/dev/null || echo \"\")\"\n    [[ -z \"$commit\" ]] && return 0\n\n    echo \"[Update] Checking for updates...\"\n\n    # Fetch with timeout (10s)\n    local fetch_ok=0\n    if command -v timeout &>/dev/null; then\n        timeout 10 git fetch origin --quiet 2>/dev/null && fetch_ok=1\n    elif command -v gtimeout &>/dev/null; then\n        gtimeout 10 git fetch origin --quiet 2>/dev/null && fetch_ok=1\n    else\n        git fetch origin --quiet 2>/dev/null && fetch_ok=1\n    fi\n\n    if [[ $fetch_ok -eq 0 ]]; then\n        echo \"[Update] Network unreachable, skipping.\"\n        echo\n        return 0\n    fi\n\n    remote_commit=\"$(git rev-parse --short \"origin/$branch\" 2>/dev/null || echo \"\")\"\n\n    if [[ -z \"$remote_commit\" || \"$commit\" == \"$remote_commit\" ]]; then\n        echo \"[Update] Already up to date ($commit).\"\n        echo\n        return 0\n    fi\n\n    echo\n    echo \"========================================\"\n    echo \"  Update available!\"\n    echo \"========================================\"\n    echo \"  Current: $commit  ->  Latest: $remote_commit\"\n    echo\n    echo \"  Recent changes:\"\n    git --no-pager log --oneline \"HEAD..origin/$branch\" 2>/dev/null | head -10\n    echo\n\n    read -rp \"Update now before starting? (Y/N): \" update_choice\n    if [[ \"${update_choice^^}\" == \"Y\" ]]; then\n        if [[ -f \"$SCRIPT_DIR/check_update.sh\" ]]; then\n            bash \"$SCRIPT_DIR/check_update.sh\"\n        else\n            echo \"Pulling latest changes...\"\n            git pull --ff-only origin \"$branch\" 2>/dev/null || {\n                echo \"[Update] Update failed. Please run: git pull\"\n            }\n        fi\n    else\n        echo \"[Update] Skipped. Run ./check_update.sh to update later.\"\n    fi\n    echo\n}\n_startup_update_check\n\necho \"Starting ACE-Step Gradio Web UI...\"\necho \"Server will be available at: http://${SERVER_NAME}:${PORT}\"\necho\n\n# ==================== Standard uv Workflow ====================\n# Works on all platforms: x86_64 Linux (cu128), aarch64 Linux/DGX Spark (cu130),\n# macOS (MPS), Windows (cu128). uv resolves the correct PyTorch wheels via\n# platform-specific index mappings in pyproject.toml.\n\n# Check if uv is installed\nif ! command -v uv &>/dev/null; then\n    # Try common install locations\n    if [[ -x \"$HOME/.local/bin/uv\" ]]; then\n        export PATH=\"$HOME/.local/bin:$PATH\"\n    elif [[ -x \"$HOME/.cargo/bin/uv\" ]]; then\n        export PATH=\"$HOME/.cargo/bin:$PATH\"\n    fi\nfi\n\nif ! command -v uv &>/dev/null; then\n    echo\n    echo \"========================================\"\n    echo \"uv package manager not found!\"\n    echo \"========================================\"\n    echo\n    echo \"ACE-Step requires the uv package manager.\"\n    echo\n    read -rp \"Install uv now? (Y/N): \" INSTALL_UV\n\n    if [[ \"${INSTALL_UV^^}\" == \"Y\" ]]; then\n        echo\n        bash \"$SCRIPT_DIR/install_uv.sh\" --silent\n        INSTALL_RESULT=$?\n\n        if [[ $INSTALL_RESULT -eq 0 ]]; then\n            echo\n            echo \"========================================\"\n            echo \"uv installed successfully!\"\n            echo \"========================================\"\n            echo\n\n            export PATH=\"$HOME/.local/bin:$HOME/.cargo/bin:$PATH\"\n\n            if command -v uv &>/dev/null; then\n                echo \"uv is now available!\"\n                uv --version\n                echo\n            else\n                echo\n                echo \"uv installed but not in PATH yet.\"\n                echo \"Please restart your terminal or run:\"\n                echo \"  export PATH=\\\"\\$HOME/.local/bin:\\$PATH\\\"\"\n                echo\n                exit 1\n            fi\n        else\n            echo\n            echo \"========================================\"\n            echo \"Installation failed!\"\n            echo \"========================================\"\n            echo\n            echo \"Please install uv manually:\"\n            echo \"  curl -LsSf https://astral.sh/uv/install.sh | sh\"\n            echo\n            exit 1\n        fi\n    else\n        echo\n        echo \"Installation cancelled.\"\n        echo\n        echo \"To use ACE-Step, please install uv:\"\n        echo \"  curl -LsSf https://astral.sh/uv/install.sh | sh\"\n        echo\n        exit 1\n    fi\nfi\n\necho \"[Environment] Using uv package manager...\"\necho\n\n# Ensure PyTorch build supports legacy NVIDIA GPUs (e.g., Pascal/Quadro P1000).\n# Newer CUDA wheels can omit sm_61, which causes runtime model-init failures.\n_ensure_legacy_nvidia_torch_compat() {\n    [[ \"${ACESTEP_SKIP_LEGACY_TORCH_FIX:-}\" == \"true\" ]] && return 0\n    [[ ! -x \"$SCRIPT_DIR/.venv/bin/python\" ]] && return 0\n\n    local compat_status\n    local legacy_torch_fix_exit_code\n    if (cd \"$SCRIPT_DIR\" && .venv/bin/python -c \\\n        \"import os, sys; sys.path.insert(0, os.getcwd()); from acestep.launcher_compat import legacy_torch_fix_probe_exit_code; raise SystemExit(legacy_torch_fix_probe_exit_code())\"); then\n        return 0\n    else\n        compat_status=$?\n    fi\n    legacy_torch_fix_exit_code=\"$(cd \"$SCRIPT_DIR\" && .venv/bin/python -c \\\n        \"import os, sys; sys.path.insert(0, os.getcwd()); from acestep.launcher_compat import LEGACY_TORCH_FIX_EXIT_CODE; print(LEGACY_TORCH_FIX_EXIT_CODE)\")\" || legacy_torch_fix_exit_code=42\n\n    if [[ \"$compat_status\" -eq 0 ]]; then\n        return 0\n    fi\n    if [[ \"$compat_status\" -ne \"$legacy_torch_fix_exit_code\" ]]; then\n        echo \"[Compatibility] Error: legacy NVIDIA compatibility probe failed with exit code $compat_status.\"\n        return \"$compat_status\"\n    fi\n\n    echo \"[Compatibility] Applying legacy NVIDIA torch build (CUDA 12.1, supports sm_61)...\"\n    if (cd \"$SCRIPT_DIR\" && uv pip install --python .venv/bin/python --force-reinstall \\\n        --index-url https://download.pytorch.org/whl/cu121 \\\n        torch==2.5.1+cu121 torchvision==0.20.1+cu121 torchaudio==2.5.1+cu121); then\n        echo \"[Compatibility] Legacy torch install complete.\"\n        # Keep a legacy-compatible torchao so INT8 quantization remains available\n        # on low-VRAM Pascal/Quadro GPUs.\n        if (cd \"$SCRIPT_DIR\" && uv pip install --python .venv/bin/python --force-reinstall torchao==0.11.0 >/dev/null 2>&1); then\n            echo \"[Compatibility] Installed torchao==0.11.0 (legacy-compatible).\"\n        else\n            echo \"[Compatibility] Warning: failed to install torchao==0.11.0. Quantization may be unavailable.\"\n        fi\n    else\n        echo \"[Compatibility] Warning: failed to install legacy torch automatically.\"\n        echo \"[Compatibility] Run manually:\"\n        echo \"  uv pip install --python .venv/bin/python --force-reinstall --index-url https://download.pytorch.org/whl/cu121 torch==2.5.1+cu121 torchvision==0.20.1+cu121 torchaudio==2.5.1+cu121\"\n        return 1\n    fi\n}\n\n# Check if virtual environment exists\nif [[ ! -d \"$SCRIPT_DIR/.venv\" ]]; then\n    echo \"[Setup] Virtual environment not found. Setting up environment...\"\n    echo \"This will take a few minutes on first run.\"\n    echo\n    echo \"Running: uv sync\"\n    echo\n\n    if ! (cd \"$SCRIPT_DIR\" && uv sync); then\n        echo\n        echo \"[Retry] Online sync failed, retrying in offline mode...\"\n        echo\n        if ! (cd \"$SCRIPT_DIR\" && uv sync --offline); then\n            echo\n            echo \"========================================\"\n            echo \"[Error] Failed to setup environment\"\n            echo \"========================================\"\n            echo\n            echo \"Both online and offline modes failed.\"\n            echo \"Please check:\"\n            echo \"  1. Your internet connection (required for first-time setup)\"\n            echo \"  2. Ensure you have enough disk space\"\n            echo \"  3. Try running: uv sync manually\"\n            exit 1\n        fi\n    fi\n\n    echo\n    echo \"========================================\"\n    echo \"Environment setup completed!\"\n    echo \"========================================\"\n    echo\nfi\n\n_ensure_legacy_nvidia_torch_compat\n\necho \"Starting ACE-Step Gradio UI...\"\necho\n\n# Build command with optional parameters\nACESTEP_ARGS=\"acestep --port $PORT --server-name $SERVER_NAME --language $LANGUAGE\"\n[[ -n \"$SHARE\" ]] && ACESTEP_ARGS=\"$ACESTEP_ARGS $SHARE\"\n[[ -n \"$CONFIG_PATH\" ]] && ACESTEP_ARGS=\"$ACESTEP_ARGS $CONFIG_PATH\"\n[[ -n \"$LM_MODEL_PATH\" ]] && ACESTEP_ARGS=\"$ACESTEP_ARGS $LM_MODEL_PATH\"\n[[ -n \"$OFFLOAD_TO_CPU\" ]] && ACESTEP_ARGS=\"$ACESTEP_ARGS $OFFLOAD_TO_CPU\"\n[[ -n \"$INIT_LLM\" ]] && ACESTEP_ARGS=\"$ACESTEP_ARGS $INIT_LLM\"\n[[ -n \"$DOWNLOAD_SOURCE\" ]] && ACESTEP_ARGS=\"$ACESTEP_ARGS $DOWNLOAD_SOURCE\"\n[[ -n \"$INIT_SERVICE\" ]] && ACESTEP_ARGS=\"$ACESTEP_ARGS $INIT_SERVICE\"\n[[ -n \"$BATCH_SIZE\" ]] && ACESTEP_ARGS=\"$ACESTEP_ARGS $BATCH_SIZE\"\n[[ -n \"$ENABLE_API\" ]] && ACESTEP_ARGS=\"$ACESTEP_ARGS $ENABLE_API\"\n[[ -n \"$API_KEY\" ]] && ACESTEP_ARGS=\"$ACESTEP_ARGS $API_KEY\"\n[[ -n \"$AUTH_USERNAME\" ]] && ACESTEP_ARGS=\"$ACESTEP_ARGS $AUTH_USERNAME\"\n[[ -n \"$AUTH_PASSWORD\" ]] && ACESTEP_ARGS=\"$ACESTEP_ARGS $AUTH_PASSWORD\"\n\ncd \"$SCRIPT_DIR\" && uv run --no-sync $ACESTEP_ARGS || {\n    echo\n    echo \"[Retry] Online dependency resolution failed, retrying in offline mode...\"\n    echo\n    uv run --offline --no-sync $ACESTEP_ARGS || {\n        echo\n        echo \"========================================\"\n        echo \"[Error] Failed to start ACE-Step\"\n        echo \"========================================\"\n        echo\n        echo \"Both online and offline modes failed.\"\n        echo \"Please check:\"\n        echo \"  1. Your internet connection (for first-time setup)\"\n        echo \"  2. If dependencies were previously installed (offline mode requires a prior successful install)\"\n        echo \"  3. Try running: uv sync --offline\"\n        exit 1\n    }\n}\n"
  },
  {
    "path": "start_gradio_ui_macos.sh",
    "content": "#!/usr/bin/env bash\n# ACE-Step Gradio Web UI Launcher - macOS (Apple Silicon / MLX)\n# This script launches the Gradio web interface using the MLX backend\n# for native Apple Silicon acceleration.\n#\n# Requirements: macOS with Apple Silicon (M1/M2/M3/M4)\n\nset -euo pipefail\nSCRIPT_DIR=\"$(cd \"$(dirname \"${BASH_SOURCE[0]}\")\" && pwd)\"\n\n# ==================== Load .env Configuration ====================\n# Load settings from .env file if it exists\n_load_env_file() {\n    local env_file=\"${SCRIPT_DIR}/.env\"\n    if [[ ! -f \"$env_file\" ]]; then\n        return 0\n    fi\n    \n    echo \"[Config] Loading configuration from .env file...\"\n    \n    # Read .env file and export variables\n    while IFS='=' read -r key value || [[ -n \"$key\" ]]; do\n        # Skip empty lines and comments\n        [[ -z \"$key\" || \"$key\" =~ ^[[:space:]]*# ]] && continue\n        \n        # Trim whitespace from key and value\n        key=\"${key#\"${key%%[![:space:]]*}\"}\"\n        key=\"${key%\"${key##*[![:space:]]}\"}\"\n        value=\"${value#\"${value%%[![:space:]]*}\"}\"\n        value=\"${value%\"${value##*[![:space:]]}\"}\"\n        \n        # Map .env variable names to script variables\n        case \"$key\" in\n            ACESTEP_CONFIG_PATH)\n                [[ -n \"$value\" ]] && CONFIG_PATH=\"--config_path $value\"\n                ;;\n            ACESTEP_LM_MODEL_PATH)\n                [[ -n \"$value\" ]] && LM_MODEL_PATH=\"--lm_model_path $value\"\n                ;;\n            ACESTEP_INIT_LLM)\n                if [[ -n \"$value\" && \"$value\" != \"auto\" ]]; then\n                    INIT_LLM=\"--init_llm $value\"\n                fi\n                ;;\n            ACESTEP_DOWNLOAD_SOURCE)\n                if [[ -n \"$value\" && \"$value\" != \"auto\" ]]; then\n                    DOWNLOAD_SOURCE=\"--download-source $value\"\n                fi\n                ;;\n            ACESTEP_API_KEY)\n                [[ -n \"$value\" ]] && API_KEY=\"--api-key $value\"\n                ;;\n            PORT)\n                [[ -n \"$value\" ]] && PORT=\"$value\"\n                ;;\n            SERVER_NAME)\n                [[ -n \"$value\" ]] && SERVER_NAME=\"$value\"\n                ;;\n            LANGUAGE)\n                [[ -n \"$value\" ]] && LANGUAGE=\"$value\"\n                ;;\n            ACESTEP_BATCH_SIZE)\n                [[ -n \"$value\" ]] && BATCH_SIZE=\"--batch_size $value\"\n                ;;\n        esac\n    done < \"$env_file\"\n    \n    echo \"[Config] Configuration loaded from .env\"\n}\n\n_load_env_file\n\n# ==================== MLX Configuration ====================\n# Force MLX backend for native Apple Silicon acceleration\nexport ACESTEP_LM_BACKEND=\"mlx\"\n\n# Disable tokenizer parallelism warning\nexport TOKENIZERS_PARALLELISM=\"false\"\n\n# ==================== Server Configuration ====================\n# Default values (used if not set in .env file)\n# You can override these by uncommenting and modifying the lines below\n# or by creating a .env file (recommended to survive updates)\n\n: \"${PORT:=7860}\"\n: \"${SERVER_NAME:=127.0.0.1}\"\n# SERVER_NAME=\"0.0.0.0\"\nSHARE=\"${SHARE:-}\"\n# SHARE=\"--share\"\n\n# Reset LANGUAGE if it contains an invalid value (e.g. system locale like en_CA:en)\ncase \"$LANGUAGE\" in\n    en|zh|he|ja) ;;\n    *) unset LANGUAGE ;;\nesac\n# UI language: en, zh, he, ja\n: \"${LANGUAGE:=en}\"\n\n# Batch size: default batch size for generation (1 to GPU-dependent max)\n# When not specified, defaults to min(2, GPU_max)\nBATCH_SIZE=\"${BATCH_SIZE:-}\"\n# BATCH_SIZE=\"--batch_size 4\"\n\n# ==================== Model Configuration ====================\n: \"${CONFIG_PATH:=--config_path acestep-v15-turbo}\"\n: \"${LM_MODEL_PATH:=--lm_model_path acestep-5Hz-lm-0.6B}\"\n\n# CPU offload (recommended for models larger than 0.6B on devices with limited memory)\n# OFFLOAD_TO_CPU=\"--offload_to_cpu true\"\nOFFLOAD_TO_CPU=\"${OFFLOAD_TO_CPU:-}\"\n\n# LLM initialization: auto (default), true, false\nINIT_LLM=\"${INIT_LLM:-}\"\n# INIT_LLM=\"--init_llm auto\"\n# INIT_LLM=\"--init_llm true\"\n# INIT_LLM=\"--init_llm false\"\n\n# Download source: auto, huggingface, modelscope\nDOWNLOAD_SOURCE=\"${DOWNLOAD_SOURCE:-}\"\n# DOWNLOAD_SOURCE=\"--download-source huggingface\"\n\n# Auto-initialize models on startup\n: \"${INIT_SERVICE:=--init_service true}\"\n\n# LM backend: mlx for Apple Silicon native acceleration\nBACKEND=\"--backend mlx\"\n\n# API settings\nENABLE_API=\"${ENABLE_API:-}\"\n# ENABLE_API=\"--enable-api\"\nAPI_KEY=\"${API_KEY:-}\"\n# API_KEY=\"--api-key sk-your-secret-key\"\n\n# Authentication\nAUTH_USERNAME=\"${AUTH_USERNAME:-}\"\n# AUTH_USERNAME=\"--auth-username admin\"\nAUTH_PASSWORD=\"${AUTH_PASSWORD:-}\"\n# AUTH_PASSWORD=\"--auth-password password\"\n\n# Update check on startup (set to \"false\" to disable)\n: \"${CHECK_UPDATE:=true}\"\n# CHECK_UPDATE=\"false\"\n\n# ==================== Launch ====================\n\n# Verify Apple Silicon\nif [[ \"$(uname)\" != \"Darwin\" ]]; then\n    echo \"ERROR: This script is for macOS only.\"\n    echo \"For Linux, use start_gradio_ui.sh instead.\"\n    exit 1\nfi\n\nARCH=\"$(uname -m)\"\nif [[ \"$ARCH\" != \"arm64\" ]]; then\n    echo \"WARNING: This script is optimized for Apple Silicon (arm64).\"\n    echo \"Detected architecture: $ARCH\"\n    echo \"MLX backend requires Apple Silicon. Falling back to PyTorch backend.\"\n    echo\n    BACKEND=\"--backend pt\"\n    unset ACESTEP_LM_BACKEND\nfi\n\n# ==================== Startup Update Check ====================\n_startup_update_check() {\n    [[ \"$CHECK_UPDATE\" != \"true\" ]] && return 0\n    command -v git &>/dev/null || return 0\n    cd \"$SCRIPT_DIR\" || return 0\n    git rev-parse --git-dir &>/dev/null 2>&1 || return 0\n\n    local branch commit remote_commit\n    branch=\"$(git rev-parse --abbrev-ref HEAD 2>/dev/null || echo \"main\")\"\n    commit=\"$(git rev-parse --short HEAD 2>/dev/null || echo \"\")\"\n    [[ -z \"$commit\" ]] && return 0\n\n    echo \"[Update] Checking for updates...\"\n\n    # Fetch with timeout (10s) - macOS uses gtimeout from coreutils\n    local fetch_ok=0\n    if command -v gtimeout &>/dev/null; then\n        gtimeout 10 git fetch origin --quiet 2>/dev/null && fetch_ok=1\n    elif command -v timeout &>/dev/null; then\n        timeout 10 git fetch origin --quiet 2>/dev/null && fetch_ok=1\n    else\n        git fetch origin --quiet 2>/dev/null && fetch_ok=1\n    fi\n\n    if [[ $fetch_ok -eq 0 ]]; then\n        echo \"[Update] Network unreachable, skipping.\"\n        echo\n        return 0\n    fi\n\n    remote_commit=\"$(git rev-parse --short \"origin/$branch\" 2>/dev/null || echo \"\")\"\n\n    if [[ -z \"$remote_commit\" || \"$commit\" == \"$remote_commit\" ]]; then\n        echo \"[Update] Already up to date ($commit).\"\n        echo\n        return 0\n    fi\n\n    echo\n    echo \"========================================\"\n    echo \"  Update available!\"\n    echo \"========================================\"\n    echo \"  Current: $commit  ->  Latest: $remote_commit\"\n    echo\n    echo \"  Recent changes:\"\n    git --no-pager log --oneline -10 \"HEAD..origin/$branch\" 2>/dev/null\n    echo\n\n    read -rp \"Update now before starting? (Y/N): \" update_choice\n    if [[ \"$(echo \"$update_choice\" | tr '[:lower:]' '[:upper:]')\" == \"Y\" ]]; then\n        if [[ -f \"$SCRIPT_DIR/check_update.sh\" ]]; then\n            bash \"$SCRIPT_DIR/check_update.sh\"\n        else\n            echo \"Pulling latest changes...\"\n            git pull --ff-only origin \"$branch\" 2>/dev/null || {\n                echo \"[Update] Update failed. Please run: git pull\"\n            }\n        fi\n    else\n        echo \"[Update] Skipped. Run ./check_update.sh to update later.\"\n    fi\n    echo\n}\n_startup_update_check\n\necho \"============================================\"\necho \"  ACE-Step 1.5 - macOS Apple Silicon (MLX)\"\necho \"============================================\"\necho\necho \"Server will be available at: http://${SERVER_NAME}:${PORT}\"\necho\n\n# ==================== Auto-detect Python environment ====================\n# Priority: python_embedded (portable package) > uv\nif [[ -f \"$SCRIPT_DIR/python_embedded/bin/python3.11\" ]]; then\n    echo \"[Environment] Found embedded Python, verifying...\"\n\n    # Proactively fix permissions and Gatekeeper BEFORE any execution attempt.\n    # On macOS Sequoia, running a quarantined binary triggers a blocking popup,\n    # so we must strip attributes and re-sign first.\n    chmod +x \"$SCRIPT_DIR/python_embedded/bin/\"* 2>/dev/null || true\n    echo \"[Setup] Removing quarantine attributes...\"\n    xattr -cr \"$SCRIPT_DIR/python_embedded\" 2>/dev/null || true\n    echo \"[Setup] Re-signing binaries (ad-hoc)...\"\n    find \"$SCRIPT_DIR/python_embedded\" -type f \\( -name \"*.dylib\" -o -name \"*.so\" -o -perm +111 \\) \\\n        -exec codesign --force --sign - {} \\; 2>/dev/null || true\n\n    if \"$SCRIPT_DIR/python_embedded/bin/python3.11\" -c \"pass\" 2>/dev/null; then\n        echo \"[Environment] Using embedded Python.\"\n        PYTHON_EXE=\"$SCRIPT_DIR/python_embedded/bin/python3.11\"\n        SCRIPT_PATH=\"$SCRIPT_DIR/acestep/acestep_v15_pipeline.py\"\n\n        # On Apple Silicon, verify MLX packages work with this macOS version.\n        # python_embedded may ship wheels built for a different macOS; pip\n        # reinstall fetches the correct platform wheel automatically.\n        if [[ \"$ARCH\" == \"arm64\" ]]; then\n            _need_mlx_fix=0\n            if ! \"$PYTHON_EXE\" -c \"import mlx.core\" 2>/dev/null; then\n                echo \"[Setup] MLX incompatible with this macOS — will reinstall.\"\n                _need_mlx_fix=1\n            elif ! \"$PYTHON_EXE\" -c \"from mlx_lm.utils import load\" 2>/dev/null; then\n                echo \"[Setup] mlx-lm outdated — will upgrade.\"\n                _need_mlx_fix=1\n            fi\n            if [[ $_need_mlx_fix -eq 1 ]]; then\n                echo \"[Setup] Fixing MLX packages (this only runs once)...\"\n                \"$PYTHON_EXE\" -m pip install --upgrade mlx mlx-lm 'transformers>=4.51.0,<4.58.0' 'vector-quantize-pytorch>=1.27.15,<1.28.0' 2>&1 | tail -1\n            fi\n        fi\n\n        echo \"Starting ACE-Step Gradio UI...\"\n        echo\n\n        # Build command with optional parameters\n        CMD=\"--port $PORT --server-name $SERVER_NAME --language $LANGUAGE\"\n        [[ -n \"$SHARE\" ]] && CMD=\"$CMD $SHARE\"\n        [[ -n \"$CONFIG_PATH\" ]] && CMD=\"$CMD $CONFIG_PATH\"\n        [[ -n \"$LM_MODEL_PATH\" ]] && CMD=\"$CMD $LM_MODEL_PATH\"\n        [[ -n \"$OFFLOAD_TO_CPU\" ]] && CMD=\"$CMD $OFFLOAD_TO_CPU\"\n        [[ -n \"$INIT_LLM\" ]] && CMD=\"$CMD $INIT_LLM\"\n        [[ -n \"$DOWNLOAD_SOURCE\" ]] && CMD=\"$CMD $DOWNLOAD_SOURCE\"\n        [[ -n \"$INIT_SERVICE\" ]] && CMD=\"$CMD $INIT_SERVICE\"\n        [[ -n \"${BATCH_SIZE:-}\" ]] && CMD=\"$CMD $BATCH_SIZE\"\n        [[ -n \"$BACKEND\" ]] && CMD=\"$CMD $BACKEND\"\n        [[ -n \"$ENABLE_API\" ]] && CMD=\"$CMD $ENABLE_API\"\n        [[ -n \"$API_KEY\" ]] && CMD=\"$CMD $API_KEY\"\n        [[ -n \"$AUTH_USERNAME\" ]] && CMD=\"$CMD $AUTH_USERNAME\"\n        [[ -n \"$AUTH_PASSWORD\" ]] && CMD=\"$CMD $AUTH_PASSWORD\"\n\n        cd \"$SCRIPT_DIR\" && exec \"$PYTHON_EXE\" \"$SCRIPT_PATH\" $CMD\n    else\n        echo \"[Setup] WARNING: Embedded Python cannot run on this machine.\"\n        echo \"[Setup] This may be a CPU architecture mismatch (e.g., arm64 binary on x86_64).\"\n        echo \"[Setup] Falling back to uv...\"\n        echo\n    fi\nfi\n\n# ==================== Fallback: uv package manager ====================\n# Check if uv is installed\nif ! command -v uv &>/dev/null; then\n    if [[ -x \"$HOME/.local/bin/uv\" ]]; then\n        export PATH=\"$HOME/.local/bin:$PATH\"\n    elif [[ -x \"$HOME/.cargo/bin/uv\" ]]; then\n        export PATH=\"$HOME/.cargo/bin:$PATH\"\n    fi\nfi\n\nif ! command -v uv &>/dev/null; then\n    echo\n    echo \"========================================\"\n    echo \"uv package manager not found!\"\n    echo \"========================================\"\n    echo\n    echo \"ACE-Step requires the uv package manager.\"\n    echo\n    read -rp \"Install uv now? (Y/N): \" INSTALL_UV\n\n    if [[ \"$(echo \"$INSTALL_UV\" | tr '[:lower:]' '[:upper:]')\" == \"Y\" ]]; then\n        echo\n        bash \"$SCRIPT_DIR/install_uv.sh\" --silent\n        INSTALL_RESULT=$?\n\n        if [[ $INSTALL_RESULT -eq 0 ]]; then\n            export PATH=\"$HOME/.local/bin:$HOME/.cargo/bin:$PATH\"\n            if ! command -v uv &>/dev/null; then\n                echo \"uv installed but not in PATH. Please restart your terminal.\"\n                exit 1\n            fi\n            echo \"uv installed successfully!\"\n            echo\n        else\n            echo \"Installation failed. Please install uv manually:\"\n            echo \"  curl -LsSf https://astral.sh/uv/install.sh | sh\"\n            echo \"  or: brew install uv\"\n            exit 1\n        fi\n    else\n        echo \"Installation cancelled.\"\n        echo \"Please install uv:\"\n        echo \"  curl -LsSf https://astral.sh/uv/install.sh | sh\"\n        echo \"  or: brew install uv\"\n        exit 1\n    fi\nfi\n\necho \"[Environment] Using uv package manager...\"\necho\n\n# Check if virtual environment exists\nif [[ ! -d \"$SCRIPT_DIR/.venv\" ]]; then\n    echo \"[Setup] Virtual environment not found. Setting up environment...\"\n    echo \"This will take a few minutes on first run.\"\n    echo\n    echo \"Running: uv sync\"\n    echo\n\n    if ! (cd \"$SCRIPT_DIR\" && uv sync); then\n        echo\n        echo \"[Retry] Online sync failed, retrying in offline mode...\"\n        echo\n        if ! (cd \"$SCRIPT_DIR\" && uv sync --offline); then\n            echo\n            echo \"========================================\"\n            echo \"[Error] Failed to setup environment\"\n            echo \"========================================\"\n            echo\n            echo \"Both online and offline modes failed.\"\n            echo \"Please check:\"\n            echo \"  1. Your internet connection (required for first-time setup)\"\n            echo \"  2. Ensure you have enough disk space\"\n            echo \"  3. Try running: uv sync manually\"\n            exit 1\n        fi\n    fi\n\n    echo\n    echo \"========================================\"\n    echo \"Environment setup completed!\"\n    echo \"========================================\"\n    echo\nfi\n\necho \"Starting ACE-Step Gradio UI (MLX backend)...\"\necho\n\n# Build command with optional parameters\nACESTEP_ARGS=\"acestep --port $PORT --server-name $SERVER_NAME --language $LANGUAGE\"\n[[ -n \"$SHARE\" ]] && ACESTEP_ARGS=\"$ACESTEP_ARGS $SHARE\"\n[[ -n \"$CONFIG_PATH\" ]] && ACESTEP_ARGS=\"$ACESTEP_ARGS $CONFIG_PATH\"\n[[ -n \"$LM_MODEL_PATH\" ]] && ACESTEP_ARGS=\"$ACESTEP_ARGS $LM_MODEL_PATH\"\n[[ -n \"$OFFLOAD_TO_CPU\" ]] && ACESTEP_ARGS=\"$ACESTEP_ARGS $OFFLOAD_TO_CPU\"\n[[ -n \"$INIT_LLM\" ]] && ACESTEP_ARGS=\"$ACESTEP_ARGS $INIT_LLM\"\n[[ -n \"$DOWNLOAD_SOURCE\" ]] && ACESTEP_ARGS=\"$ACESTEP_ARGS $DOWNLOAD_SOURCE\"\n[[ -n \"$INIT_SERVICE\" ]] && ACESTEP_ARGS=\"$ACESTEP_ARGS $INIT_SERVICE\"\n[[ -n \"$BATCH_SIZE\" ]] && ACESTEP_ARGS=\"$ACESTEP_ARGS $BATCH_SIZE\"\n[[ -n \"$BACKEND\" ]] && ACESTEP_ARGS=\"$ACESTEP_ARGS $BACKEND\"\n[[ -n \"$ENABLE_API\" ]] && ACESTEP_ARGS=\"$ACESTEP_ARGS $ENABLE_API\"\n[[ -n \"$API_KEY\" ]] && ACESTEP_ARGS=\"$ACESTEP_ARGS $API_KEY\"\n[[ -n \"$AUTH_USERNAME\" ]] && ACESTEP_ARGS=\"$ACESTEP_ARGS $AUTH_USERNAME\"\n[[ -n \"$AUTH_PASSWORD\" ]] && ACESTEP_ARGS=\"$ACESTEP_ARGS $AUTH_PASSWORD\"\n\ncd \"$SCRIPT_DIR\" && uv run $ACESTEP_ARGS || {\n    echo\n    echo \"[Retry] Online dependency resolution failed, retrying in offline mode...\"\n    echo\n    uv run --offline $ACESTEP_ARGS || {\n        echo\n        echo \"========================================\"\n        echo \"[Error] Failed to start ACE-Step\"\n        echo \"========================================\"\n        echo\n        echo \"Both online and offline modes failed.\"\n        echo \"Please check:\"\n        echo \"  1. Your internet connection (for first-time setup)\"\n        echo \"  2. If dependencies were previously installed (offline mode requires a prior successful install)\"\n        echo \"  3. Try running: uv sync --offline\"\n        exit 1\n    }\n}\n"
  },
  {
    "path": "start_gradio_ui_macos_manual.sh",
    "content": "#!/usr/bin/env bash\n# ACE-Step Gradio Web UI Launcher - macOS (Apple Silicon / MLX)\n# This script launches the Gradio web interface using the MLX backend\n# for native Apple Silicon acceleration.\n#\n# Requirements: macOS with Apple Silicon (M1/M2/M3/M4)\n\nset -euo pipefail\nSCRIPT_DIR=\"$(cd \"$(dirname \"${BASH_SOURCE[0]}\")\" && pwd)\"\n\n# ==================== Load .env Configuration ====================\n# Load settings from .env file if it exists\n_load_env_file() {\n    local env_file=\"${SCRIPT_DIR}/.env\"\n    if [[ ! -f \"$env_file\" ]]; then\n        return 0\n    fi\n    \n    echo \"[Config] Loading configuration from .env file...\"\n    \n    # Read .env file and export variables\n    while IFS='=' read -r key value || [[ -n \"$key\" ]]; do\n        # Skip empty lines and comments\n        [[ -z \"$key\" || \"$key\" =~ ^[[:space:]]*# ]] && continue\n        \n        # Trim whitespace from key and value\n        key=\"${key#\"${key%%[![:space:]]*}\"}\"\n        key=\"${key%\"${key##*[![:space:]]}\"}\"\n        value=\"${value#\"${value%%[![:space:]]*}\"}\"\n        value=\"${value%\"${value##*[![:space:]]}\"}\"\n        \n        # Map .env variable names to script variables\n        case \"$key\" in\n            ACESTEP_CONFIG_PATH)\n                [[ -n \"$value\" ]] && CONFIG_PATH=\"--config_path $value\"\n                ;;\n            ACESTEP_LM_MODEL_PATH)\n                [[ -n \"$value\" ]] && LM_MODEL_PATH=\"--lm_model_path $value\"\n                ;;\n            ACESTEP_INIT_LLM)\n                if [[ -n \"$value\" && \"$value\" != \"auto\" ]]; then\n                    INIT_LLM=\"--init_llm $value\"\n                fi\n                ;;\n            ACESTEP_DOWNLOAD_SOURCE)\n                if [[ -n \"$value\" && \"$value\" != \"auto\" ]]; then\n                    DOWNLOAD_SOURCE=\"--download-source $value\"\n                fi\n                ;;\n            ACESTEP_API_KEY)\n                [[ -n \"$value\" ]] && API_KEY=\"--api-key $value\"\n                ;;\n            PORT)\n                [[ -n \"$value\" ]] && PORT=\"$value\"\n                ;;\n            SERVER_NAME)\n                [[ -n \"$value\" ]] && SERVER_NAME=\"$value\"\n                ;;\n            LANGUAGE)\n                [[ -n \"$value\" ]] && LANGUAGE=\"$value\"\n                ;;\n            ACESTEP_BATCH_SIZE)\n                [[ -n \"$value\" ]] && BATCH_SIZE=\"--batch_size $value\"\n                ;;\n        esac\n    done < \"$env_file\"\n    \n    echo \"[Config] Configuration loaded from .env\"\n}\n\n_load_env_file\n\n# ==================== Manual Startup Configuration ====================\n# Ask for manual settings\n_load_manual() {\n    echo -e \"\\033[1;36m\"\n    echo \"======================================================\"\n    echo \"            ACE-Step Manual Launch Mode\"\n    echo \"======================================================\"\n    echo\n\n    while true; do\n        read -rp \"Continue with manual configuration? (Y/N): \" MANUAL_CHOICE\n        case \"$MANUAL_CHOICE\" in\n            [Yy])\n                break ;;\n            [Nn])\n                echo -e \"\\033[0m\"\n                echo \"Proceeding with automatic configuration...\"\n                echo\n                return 0 ;;\n            *)\n                echo \"Invalid input. Please enter Y or N.\" ;;\n        esac\n    done\n\n    echo\n    echo \"-------------------- Update Settings --------------------\"\n    while true; do\n        read -rp \"Check for updates before launch? (Y/N): \" UPDATE_CHOICE\n        case \"$UPDATE_CHOICE\" in\n            [Yy])\n                CHECK_UPDATE=\"true\"\n                break ;;\n            [Nn])\n                CHECK_UPDATE=\"false\"\n                break ;;\n            *)\n                echo \"Invalid input. Please enter Y or N.\" ;;\n        esac\n    done\n\n    echo\n    echo \"-------------------- Select DiT Model --------------------\"\n    echo \"1) acestep-v15-base\"\n    echo \"2) acestep-v15-sft\"\n    echo \"3) acestep-v15-turbo (Recommended)\"\n    echo \"4) acestep-v15-turbo-rl\"\n    echo\n    while true; do\n        read -rp \"Enter selection (1-4): \" DIT_CHOICE\n        case \"$DIT_CHOICE\" in\n            1)\n                CONFIG_PATH=\"--config_path acestep-v15-base\"\n                break ;;\n            2)\n                CONFIG_PATH=\"--config_path acestep-v15-sft\"\n                break ;;\n            3)\n                CONFIG_PATH=\"--config_path acestep-v15-turbo\"\n                break ;;\n            4)\n                CONFIG_PATH=\"--config_path acestep-v15-turbo-rl\"\n                break ;;\n            *)\n                echo \"Invalid input. Please enter a number between 1 and 4.\" ;;\n        esac\n    done\n\n    echo\n    echo \"-------------------- Select LM Model --------------------\"\n    echo \"1) acestep-5Hz-lm-0.6B (Recommended)\"\n    echo \"2) acestep-5Hz-lm-1.7B\"\n    echo \"3) acestep-5Hz-lm-4B\"\n    echo \"4) Launch without LM Model\"\n    echo\n    while true; do\n        read -rp \"Enter selection (1-4): \" LM_CHOICE\n        case \"$LM_CHOICE\" in\n            1)\n                LM_MODEL_PATH=\"--lm_model_path acestep-5Hz-lm-0.6B\"\n                INIT_LLM=\"--init_llm true\"\n                break ;;\n            2)\n                LM_MODEL_PATH=\"--lm_model_path acestep-5Hz-lm-1.7B\"\n                INIT_LLM=\"--init_llm true\"\n                break ;;\n            3)\n                LM_MODEL_PATH=\"--lm_model_path acestep-5Hz-lm-4B\"\n                INIT_LLM=\"--init_llm true\"\n                break ;;\n            4)\n                LM_MODEL_PATH=\"\"\n                INIT_LLM=\"--init_llm false\"\n                break ;;\n            *)\n                echo \"Invalid input. Please enter a number between 1 and 4.\" ;;\n        esac\n    done\n\n    echo\n    echo \"-------------------- CPU Offload Option --------------------\"\n    while true; do\n        read -rp \"Enable CPU Offload? (Y/N): \" OFFLOAD_CHOICE\n        case \"$OFFLOAD_CHOICE\" in\n            [Yy])\n                OFFLOAD_TO_CPU=\"--offload_to_cpu true\"\n                break ;;\n            [Nn])\n                OFFLOAD_TO_CPU=\"--offload_to_cpu false\"\n                break ;;\n            *)\n                echo \"Invalid input. Please enter Y or N.\" ;;\n        esac\n    done\n\n    echo -e \"\\033[0m\"\n    echo \"Manual configuration applied successfully.\"\n    echo\n}\n\n_load_manual\n\n# ==================== MLX Configuration ====================\n# Force MLX backend for native Apple Silicon acceleration\nexport ACESTEP_LM_BACKEND=\"mlx\"\n\n# Disable tokenizer parallelism warning\nexport TOKENIZERS_PARALLELISM=\"false\"\n\n# ==================== Server Configuration ====================\n# Default values (used if not set in .env file)\n# You can override these by uncommenting and modifying the lines below\n# or by creating a .env file (recommended to survive updates)\n\n: \"${PORT:=7860}\"\n: \"${SERVER_NAME:=127.0.0.1}\"\n# SERVER_NAME=\"0.0.0.0\"\nSHARE=\"${SHARE:-}\"\n# SHARE=\"--share\"\n\n# Reset LANGUAGE if it contains an invalid value (e.g. system locale like en_CA:en)\ncase \"$LANGUAGE\" in\n    en|zh|he|ja) ;;\n    *) unset LANGUAGE ;;\nesac\n# UI language: en, zh, he, ja\n: \"${LANGUAGE:=en}\"\n\n# Batch size: default batch size for generation (1 to GPU-dependent max)\n# When not specified, defaults to min(2, GPU_max)\nBATCH_SIZE=\"${BATCH_SIZE:-}\"\n# BATCH_SIZE=\"--batch_size 4\"\n\n# ==================== Model Configuration ====================\n: \"${CONFIG_PATH:=--config_path acestep-v15-turbo}\"\n: \"${LM_MODEL_PATH:=--lm_model_path acestep-5Hz-lm-0.6B}\"\n\n# CPU offload (recommended for models larger than 0.6B on devices with limited memory)\n# OFFLOAD_TO_CPU=\"--offload_to_cpu true\"\nOFFLOAD_TO_CPU=\"${OFFLOAD_TO_CPU:-}\"\n\n# LLM initialization: auto (default), true, false\nINIT_LLM=\"${INIT_LLM:-}\"\n# INIT_LLM=\"--init_llm auto\"\n# INIT_LLM=\"--init_llm true\"\n# INIT_LLM=\"--init_llm false\"\n\n# Download source: auto, huggingface, modelscope\nDOWNLOAD_SOURCE=\"${DOWNLOAD_SOURCE:-}\"\n# DOWNLOAD_SOURCE=\"--download-source huggingface\"\n\n# Auto-initialize models on startup\n: \"${INIT_SERVICE:=--init_service true}\"\n\n# LM backend: mlx for Apple Silicon native acceleration\nBACKEND=\"--backend mlx\"\n\n# API settings\nENABLE_API=\"${ENABLE_API:-}\"\n# ENABLE_API=\"--enable-api\"\nAPI_KEY=\"${API_KEY:-}\"\n# API_KEY=\"--api-key sk-your-secret-key\"\n\n# Authentication\nAUTH_USERNAME=\"${AUTH_USERNAME:-}\"\n# AUTH_USERNAME=\"--auth-username admin\"\nAUTH_PASSWORD=\"${AUTH_PASSWORD:-}\"\n# AUTH_PASSWORD=\"--auth-password password\"\n\n# Update check on startup (set to \"false\" to disable)\n: \"${CHECK_UPDATE:=true}\"\n# CHECK_UPDATE=\"false\"\n\n# ==================== Launch ====================\n\n# Verify Apple Silicon\nif [[ \"$(uname)\" != \"Darwin\" ]]; then\n    echo \"ERROR: This script is for macOS only.\"\n    echo \"For Linux, use start_gradio_ui.sh instead.\"\n    exit 1\nfi\n\nARCH=\"$(uname -m)\"\nif [[ \"$ARCH\" != \"arm64\" ]]; then\n    echo \"WARNING: This script is optimized for Apple Silicon (arm64).\"\n    echo \"Detected architecture: $ARCH\"\n    echo \"MLX backend requires Apple Silicon. Falling back to PyTorch backend.\"\n    echo\n    BACKEND=\"--backend pt\"\n    unset ACESTEP_LM_BACKEND\nfi\n\n# ==================== Startup Update Check ====================\n_startup_update_check() {\n    [[ \"$CHECK_UPDATE\" != \"true\" ]] && return 0\n    command -v git &>/dev/null || return 0\n    cd \"$SCRIPT_DIR\" || return 0\n    git rev-parse --git-dir &>/dev/null 2>&1 || return 0\n\n    local branch commit remote_commit\n    branch=\"$(git rev-parse --abbrev-ref HEAD 2>/dev/null || echo \"main\")\"\n    commit=\"$(git rev-parse --short HEAD 2>/dev/null || echo \"\")\"\n    [[ -z \"$commit\" ]] && return 0\n\n    echo \"[Update] Checking for updates...\"\n\n    # Fetch with timeout (10s) - macOS uses gtimeout from coreutils\n    local fetch_ok=0\n    if command -v gtimeout &>/dev/null; then\n        gtimeout 10 git fetch origin --quiet 2>/dev/null && fetch_ok=1\n    elif command -v timeout &>/dev/null; then\n        timeout 10 git fetch origin --quiet 2>/dev/null && fetch_ok=1\n    else\n        git fetch origin --quiet 2>/dev/null && fetch_ok=1\n    fi\n\n    if [[ $fetch_ok -eq 0 ]]; then\n        echo \"[Update] Network unreachable, skipping.\"\n        echo\n        return 0\n    fi\n\n    remote_commit=\"$(git rev-parse --short \"origin/$branch\" 2>/dev/null || echo \"\")\"\n\n    if [[ -z \"$remote_commit\" || \"$commit\" == \"$remote_commit\" ]]; then\n        echo \"[Update] Already up to date ($commit).\"\n        echo\n        return 0\n    fi\n\n    echo\n    echo \"========================================\"\n    echo \"  Update available!\"\n    echo \"========================================\"\n    echo \"  Current: $commit  ->  Latest: $remote_commit\"\n    echo\n    echo \"  Recent changes:\"\n    git --no-pager log --oneline \"HEAD..origin/$branch\" 2>/dev/null | head -10\n    echo\n\n    read -rp \"Update now before starting? (Y/N): \" update_choice\n    if [[ \"${update_choice^^}\" == \"Y\" ]]; then\n        if [[ -f \"$SCRIPT_DIR/check_update.sh\" ]]; then\n            bash \"$SCRIPT_DIR/check_update.sh\"\n        else\n            echo \"Pulling latest changes...\"\n            git pull --ff-only origin \"$branch\" 2>/dev/null || {\n                echo \"[Update] Update failed. Please run: git pull\"\n            }\n        fi\n    else\n        echo \"[Update] Skipped. Run ./check_update.sh to update later.\"\n    fi\n    echo\n}\n_startup_update_check\n\necho \"============================================\"\necho \"  ACE-Step 1.5 - macOS Apple Silicon (MLX)\"\necho \"============================================\"\necho\necho \"Server will be available at: http://${SERVER_NAME}:${PORT}\"\necho\n\n# Check if uv is installed\nif ! command -v uv &>/dev/null; then\n    if [[ -x \"$HOME/.local/bin/uv\" ]]; then\n        export PATH=\"$HOME/.local/bin:$PATH\"\n    elif [[ -x \"$HOME/.cargo/bin/uv\" ]]; then\n        export PATH=\"$HOME/.cargo/bin:$PATH\"\n    fi\nfi\n\nif ! command -v uv &>/dev/null; then\n    echo\n    echo \"========================================\"\n    echo \"uv package manager not found!\"\n    echo \"========================================\"\n    echo\n    echo \"ACE-Step requires the uv package manager.\"\n    echo\n    read -rp \"Install uv now? (Y/N): \" INSTALL_UV\n\n    if [[ \"${INSTALL_UV^^}\" == \"Y\" ]]; then\n        echo\n        bash \"$SCRIPT_DIR/install_uv.sh\" --silent\n        INSTALL_RESULT=$?\n\n        if [[ $INSTALL_RESULT -eq 0 ]]; then\n            export PATH=\"$HOME/.local/bin:$HOME/.cargo/bin:$PATH\"\n            if ! command -v uv &>/dev/null; then\n                echo \"uv installed but not in PATH. Please restart your terminal.\"\n                exit 1\n            fi\n            echo \"uv installed successfully!\"\n            echo\n        else\n            echo \"Installation failed. Please install uv manually:\"\n            echo \"  curl -LsSf https://astral.sh/uv/install.sh | sh\"\n            echo \"  or: brew install uv\"\n            exit 1\n        fi\n    else\n        echo \"Installation cancelled.\"\n        echo \"Please install uv:\"\n        echo \"  curl -LsSf https://astral.sh/uv/install.sh | sh\"\n        echo \"  or: brew install uv\"\n        exit 1\n    fi\nfi\n\necho \"[Environment] Using uv package manager...\"\necho\n\n# Check if virtual environment exists\nif [[ ! -d \"$SCRIPT_DIR/.venv\" ]]; then\n    echo \"[Setup] Virtual environment not found. Setting up environment...\"\n    echo \"This will take a few minutes on first run.\"\n    echo\n    echo \"Running: uv sync\"\n    echo\n\n    if ! (cd \"$SCRIPT_DIR\" && uv sync); then\n        echo\n        echo \"[Retry] Online sync failed, retrying in offline mode...\"\n        echo\n        if ! (cd \"$SCRIPT_DIR\" && uv sync --offline); then\n            echo\n            echo \"========================================\"\n            echo \"[Error] Failed to setup environment\"\n            echo \"========================================\"\n            echo\n            echo \"Both online and offline modes failed.\"\n            echo \"Please check:\"\n            echo \"  1. Your internet connection (required for first-time setup)\"\n            echo \"  2. Ensure you have enough disk space\"\n            echo \"  3. Try running: uv sync manually\"\n            exit 1\n        fi\n    fi\n\n    echo\n    echo \"========================================\"\n    echo \"Environment setup completed!\"\n    echo \"========================================\"\n    echo\nfi\n\necho \"Starting ACE-Step Gradio UI (MLX backend)...\"\necho\n\n# Build command with optional parameters\nACESTEP_ARGS=\"acestep --port $PORT --server-name $SERVER_NAME --language $LANGUAGE\"\n[[ -n \"$SHARE\" ]] && ACESTEP_ARGS=\"$ACESTEP_ARGS $SHARE\"\n[[ -n \"$CONFIG_PATH\" ]] && ACESTEP_ARGS=\"$ACESTEP_ARGS $CONFIG_PATH\"\n[[ -n \"$LM_MODEL_PATH\" ]] && ACESTEP_ARGS=\"$ACESTEP_ARGS $LM_MODEL_PATH\"\n[[ -n \"$OFFLOAD_TO_CPU\" ]] && ACESTEP_ARGS=\"$ACESTEP_ARGS $OFFLOAD_TO_CPU\"\n[[ -n \"$INIT_LLM\" ]] && ACESTEP_ARGS=\"$ACESTEP_ARGS $INIT_LLM\"\n[[ -n \"$DOWNLOAD_SOURCE\" ]] && ACESTEP_ARGS=\"$ACESTEP_ARGS $DOWNLOAD_SOURCE\"\n[[ -n \"$INIT_SERVICE\" ]] && ACESTEP_ARGS=\"$ACESTEP_ARGS $INIT_SERVICE\"\n[[ -n \"$BATCH_SIZE\" ]] && ACESTEP_ARGS=\"$ACESTEP_ARGS $BATCH_SIZE\"\n[[ -n \"$BACKEND\" ]] && ACESTEP_ARGS=\"$ACESTEP_ARGS $BACKEND\"\n[[ -n \"$ENABLE_API\" ]] && ACESTEP_ARGS=\"$ACESTEP_ARGS $ENABLE_API\"\n[[ -n \"$API_KEY\" ]] && ACESTEP_ARGS=\"$ACESTEP_ARGS $API_KEY\"\n[[ -n \"$AUTH_USERNAME\" ]] && ACESTEP_ARGS=\"$ACESTEP_ARGS $AUTH_USERNAME\"\n[[ -n \"$AUTH_PASSWORD\" ]] && ACESTEP_ARGS=\"$ACESTEP_ARGS $AUTH_PASSWORD\"\n\ncd \"$SCRIPT_DIR\" && uv run $ACESTEP_ARGS || {\n    echo\n    echo \"[Retry] Online dependency resolution failed, retrying in offline mode...\"\n    echo\n    uv run --offline $ACESTEP_ARGS || {\n        echo\n        echo \"========================================\"\n        echo \"[Error] Failed to start ACE-Step\"\n        echo \"========================================\"\n        echo\n        echo \"Both online and offline modes failed.\"\n        echo \"Please check:\"\n        echo \"  1. Your internet connection (for first-time setup)\"\n        echo \"  2. If dependencies were previously installed (offline mode requires a prior successful install)\"\n        echo \"  3. Try running: uv sync --offline\"\n        exit 1\n    }\n}\n"
  },
  {
    "path": "start_gradio_ui_manual.bat",
    "content": "@echo off\nchcp 65001 >nul\nsetlocal enabledelayedexpansion\nREM ACE-Step Gradio Web UI Launcher\nREM This script launches the Gradio web interface for ACE-Step\n\nREM ==================== Load .env Configuration ====================\nREM Load settings from .env file if it exists\ncall :LoadEnvFile\n\nREM ==================== Manual Startup Configuration ====================\nREM Ask for manual settings\ncall :LoadManual\n\nREM ==================== Configuration ====================\nREM Default values (used if not set in .env file)\nREM You can override these by uncommenting and modifying the lines below\nREM or by creating a .env file (recommended to survive updates)\n\nREM Server settings\nif not defined PORT set PORT=7860\nif not defined SERVER_NAME set SERVER_NAME=127.0.0.1\nREM set SERVER_NAME=0.0.0.0\nREM set SHARE=--share\n\nREM UI language: en, zh, he, ja\nif not defined LANGUAGE set LANGUAGE=en\n\nREM Batch size: default batch size for generation (1 to GPU-dependent max)\nREM When not specified, defaults to min(2, GPU_max)\nREM set BATCH_SIZE=--batch_size 4\n\nREM Model settings\nif not defined CONFIG_PATH set CONFIG_PATH=--config_path acestep-v15-turbo\nif not defined LM_MODEL_PATH set LM_MODEL_PATH=--lm_model_path acestep-5Hz-lm-0.6B\nREM set OFFLOAD_TO_CPU=--offload_to_cpu true\n\nREM LLM (Language Model) initialization settings\nREM By default, LLM is auto-enabled/disabled based on GPU VRAM:\nREM   - <=6GB VRAM: LLM disabled (DiT-only mode)\nREM   - >6GB VRAM: LLM enabled\nREM Values: auto (default), true (force enable), false (force disable)\nREM set INIT_LLM=--init_llm auto\nREM set INIT_LLM=--init_llm true\nREM set INIT_LLM=--init_llm false\n\nREM Download source settings\nREM Preferred download source: auto (default), huggingface, or modelscope\nREM set DOWNLOAD_SOURCE=--download-source modelscope\nREM set DOWNLOAD_SOURCE=--download-source huggingface\nif not defined DOWNLOAD_SOURCE set DOWNLOAD_SOURCE=\n\nREM Update check on startup (set to false to disable)\nif not defined CHECK_UPDATE set CHECK_UPDATE=true\nREM set CHECK_UPDATE=false\n\nREM Auto-initialize models on startup\nif not defined INIT_SERVICE set INIT_SERVICE=--init_service true\n\nREM API settings (enable REST API alongside Gradio)\nREM set ENABLE_API=--enable-api\nREM set API_KEY=--api-key sk-your-secret-key\n\nREM Authentication settings\nREM set AUTH_USERNAME=--auth-username admin\nREM set AUTH_PASSWORD=--auth-password password\n\nREM ==================== Launch ====================\n\nREM ==================== Startup Update Check ====================\nif /i not \"%CHECK_UPDATE%\"==\"true\" goto :SkipUpdateCheck\n\nREM Find git: try PortableGit first, then system git\nset \"UPDATE_GIT_CMD=\"\nif exist \"%~dp0PortableGit\\bin\\git.exe\" (\n    set \"UPDATE_GIT_CMD=%~dp0PortableGit\\bin\\git.exe\"\n) else (\n    where git >nul 2>&1\n    if !ERRORLEVEL! EQU 0 (\n        for /f \"tokens=*\" %%i in ('where git 2^>nul') do (\n            if not defined UPDATE_GIT_CMD set \"UPDATE_GIT_CMD=%%i\"\n        )\n    )\n)\nif not defined UPDATE_GIT_CMD goto :SkipUpdateCheck\n\ncd /d \"%~dp0\"\n\"!UPDATE_GIT_CMD!\" rev-parse --git-dir >nul 2>&1\nif !ERRORLEVEL! NEQ 0 goto :SkipUpdateCheck\n\necho [Update] Checking for updates...\n\nfor /f \"tokens=*\" %%i in ('\"!UPDATE_GIT_CMD!\" rev-parse --abbrev-ref HEAD 2^>nul') do set UPDATE_BRANCH=%%i\nif \"!UPDATE_BRANCH!\"==\"\" set UPDATE_BRANCH=main\nfor /f \"tokens=*\" %%i in ('\"!UPDATE_GIT_CMD!\" rev-parse --short HEAD 2^>nul') do set UPDATE_LOCAL=%%i\n\n\"!UPDATE_GIT_CMD!\" fetch origin --quiet 2>nul\nif !ERRORLEVEL! NEQ 0 (\n    echo [Update] Network unreachable, skipping.\n    echo.\n    goto :SkipUpdateCheck\n)\n\nfor /f \"tokens=*\" %%i in ('\"!UPDATE_GIT_CMD!\" rev-parse --short origin/!UPDATE_BRANCH! 2^>nul') do set UPDATE_REMOTE=%%i\n\nif \"!UPDATE_REMOTE!\"==\"\" goto :SkipUpdateCheck\nif \"!UPDATE_LOCAL!\"==\"!UPDATE_REMOTE!\" (\n    echo [Update] Already up to date ^(!UPDATE_LOCAL!^).\n    echo.\n    goto :SkipUpdateCheck\n)\n\necho.\necho ========================================\necho   Update available!\necho ========================================\necho   Current: !UPDATE_LOCAL!  -^>  Latest: !UPDATE_REMOTE!\necho.\necho   Recent changes:\n\"!UPDATE_GIT_CMD!\" --no-pager log --oneline HEAD..origin/!UPDATE_BRANCH! 2>nul\necho.\n\nset /p UPDATE_NOW=\"Update now before starting? (Y/N): \"\nif /i \"!UPDATE_NOW!\"==\"Y\" (\n    if exist \"%~dp0check_update.bat\" (\n        call \"%~dp0check_update.bat\"\n    ) else (\n        echo Pulling latest changes...\n        \"!UPDATE_GIT_CMD!\" pull --ff-only origin !UPDATE_BRANCH! 2>nul\n        if !ERRORLEVEL! NEQ 0 (\n            echo [Update] Update failed. Please update manually.\n        )\n    )\n) else (\n    echo [Update] Skipped. Run check_update.bat to update later.\n)\necho.\n\n:SkipUpdateCheck\n\necho Starting ACE-Step Gradio Web UI...\necho Server will be available at: http://%SERVER_NAME%:%PORT%\necho.\n\nREM Auto-detect Python environment\nif exist \"%~dp0python_embedded\\python.exe\" (\n    echo [Environment] Using embedded Python...\n\n    REM Build command with optional parameters\n    set \"PYTHON_EXE=%~dp0python_embedded\\python.exe\"\n    set \"SCRIPT_PATH=%~dp0acestep\\acestep_v15_pipeline.py\"\n    set \"CMD=--port %PORT% --server-name %SERVER_NAME% --language %LANGUAGE%\"\n    if not \"%SHARE%\"==\"\" set \"CMD=!CMD! %SHARE%\"\n    if not \"%CONFIG_PATH%\"==\"\" set \"CMD=!CMD! %CONFIG_PATH%\"\n    if not \"%LM_MODEL_PATH%\"==\"\" set \"CMD=!CMD! %LM_MODEL_PATH%\"\n    if not \"%OFFLOAD_TO_CPU%\"==\"\" set \"CMD=!CMD! %OFFLOAD_TO_CPU%\"\n    if not \"%INIT_LLM%\"==\"\" set \"CMD=!CMD! %INIT_LLM%\"\n    if not \"%DOWNLOAD_SOURCE%\"==\"\" set \"CMD=!CMD! %DOWNLOAD_SOURCE%\"\n    if not \"%INIT_SERVICE%\"==\"\" set \"CMD=!CMD! %INIT_SERVICE%\"\n    if not \"%BATCH_SIZE%\"==\"\" set \"CMD=!CMD! %BATCH_SIZE%\"\n    if not \"%ENABLE_API%\"==\"\" set \"CMD=!CMD! %ENABLE_API%\"\n    if not \"%API_KEY%\"==\"\" set \"CMD=!CMD! %API_KEY%\"\n    if not \"%AUTH_USERNAME%\"==\"\" set \"CMD=!CMD! %AUTH_USERNAME%\"\n    if not \"%AUTH_PASSWORD%\"==\"\" set \"CMD=!CMD! %AUTH_PASSWORD%\"\n\n    \"!PYTHON_EXE!\" \"!SCRIPT_PATH!\" !CMD!\n) else (\n    echo [Environment] Embedded Python not found, checking for uv...\n\n    REM Check if uv is installed\n    where uv >nul 2>&1\n    if !ERRORLEVEL! NEQ 0 (\n        echo.\n        echo ========================================\n        echo uv package manager not found!\n        echo ========================================\n        echo.\n        echo ACE-Step requires either:\n        echo   1. python_embedded directory ^(portable package^)\n        echo   2. uv package manager\n        echo.\n        echo Would you like to install uv now? ^(Recommended^)\n        echo.\n        set /p INSTALL_UV=\"Install uv? (Y/N): \"\n\n        if /i \"!INSTALL_UV!\"==\"Y\" (\n            echo.\n            REM Call install_uv.bat in silent mode\n            call \"%~dp0install_uv.bat\" --silent\n            set INSTALL_RESULT=!ERRORLEVEL!\n\n            if !INSTALL_RESULT! EQU 0 (\n                echo.\n                echo ========================================\n                echo uv installed successfully!\n                echo ========================================\n                echo.\n\n                REM Refresh PATH to include uv\n                if exist \"%USERPROFILE%\\.local\\bin\\uv.exe\" (\n                    set \"PATH=%USERPROFILE%\\.local\\bin;%PATH%\"\n                )\n                if exist \"%LOCALAPPDATA%\\Microsoft\\WinGet\\Links\\uv.exe\" (\n                    set \"PATH=%LOCALAPPDATA%\\Microsoft\\WinGet\\Links;%PATH%\"\n                )\n\n                REM Verify uv is available\n                where uv >nul 2>&1\n                if !ERRORLEVEL! EQU 0 (\n                    echo uv is now available!\n                    uv --version\n                    echo.\n                    goto :RunWithUv\n                ) else (\n                    REM Try direct paths\n                    if exist \"%USERPROFILE%\\.local\\bin\\uv.exe\" (\n                        set \"PATH=%USERPROFILE%\\.local\\bin;%PATH%\"\n                        goto :RunWithUv\n                    )\n                    if exist \"%LOCALAPPDATA%\\Microsoft\\WinGet\\Links\\uv.exe\" (\n                        set \"PATH=%LOCALAPPDATA%\\Microsoft\\WinGet\\Links;%PATH%\"\n                        goto :RunWithUv\n                    )\n\n                    echo.\n                    echo uv installed but not in PATH yet.\n                    echo Please restart your terminal or run:\n                    echo   %USERPROFILE%\\.local\\bin\\uv.exe run acestep\n                    echo.\n                    pause\n                    exit /b 1\n                )\n            ) else (\n                echo.\n                echo ========================================\n                echo Installation failed!\n                echo ========================================\n                echo.\n                echo Please install uv manually:\n                echo   1. Using PowerShell: irm https://astral.sh/uv/install.ps1 ^| iex\n                echo   2. Using winget: winget install --id=astral-sh.uv -e\n                echo   3. Download portable package: https://files.acemusic.ai/acemusic/win/ACE-Step-1.5.7z\n                echo.\n                pause\n                exit /b 1\n            )\n        ) else (\n            echo.\n            echo Installation cancelled.\n            echo.\n            echo To use ACE-Step, please either:\n            echo   1. Install uv: winget install --id=astral-sh.uv -e\n            echo   2. Download portable package: https://files.acemusic.ai/acemusic/win/ACE-Step-1.5.7z\n            echo.\n            pause\n            exit /b 1\n        )\n    )\n\n    :RunWithUv\n    echo [Environment] Using uv package manager...\n    echo.\n\n    REM Check if virtual environment exists\n    if not exist \"%~dp0.venv\" (\n        echo [Setup] Virtual environment not found. Setting up environment...\n        echo This will take a few minutes on first run.\n        echo.\n        echo Running: uv sync\n        echo.\n\n        uv sync\n\n        if !ERRORLEVEL! NEQ 0 (\n            echo.\n            echo [Retry] Online sync failed, retrying in offline mode...\n            echo.\n            uv sync --offline\n\n            if !ERRORLEVEL! NEQ 0 (\n                echo.\n                echo ========================================\n                echo [Error] Failed to setup environment\n                echo ========================================\n                echo.\n                echo Both online and offline modes failed.\n                echo Please check:\n                echo   1. Your internet connection ^(required for first-time setup^)\n                echo   2. Ensure you have enough disk space\n                echo   3. Try running: uv sync manually\n                echo.\n                pause\n                exit /b 1\n            )\n        )\n\n        echo.\n        echo ========================================\n        echo Environment setup completed!\n        echo ========================================\n        echo.\n    )\n\n    echo Starting ACE-Step Gradio UI...\n    echo.\n\n    REM Build command with optional parameters\n    set \"ACESTEP_ARGS=acestep --port %PORT% --server-name %SERVER_NAME% --language %LANGUAGE%\"\n    if not \"%SHARE%\"==\"\" set \"ACESTEP_ARGS=!ACESTEP_ARGS! %SHARE%\"\n    if not \"%CONFIG_PATH%\"==\"\" set \"ACESTEP_ARGS=!ACESTEP_ARGS! %CONFIG_PATH%\"\n    if not \"%LM_MODEL_PATH%\"==\"\" set \"ACESTEP_ARGS=!ACESTEP_ARGS! %LM_MODEL_PATH%\"\n    if not \"%OFFLOAD_TO_CPU%\"==\"\" set \"ACESTEP_ARGS=!ACESTEP_ARGS! %OFFLOAD_TO_CPU%\"\n    if not \"%INIT_LLM%\"==\"\" set \"ACESTEP_ARGS=!ACESTEP_ARGS! %INIT_LLM%\"\n    if not \"%DOWNLOAD_SOURCE%\"==\"\" set \"ACESTEP_ARGS=!ACESTEP_ARGS! %DOWNLOAD_SOURCE%\"\n    if not \"%INIT_SERVICE%\"==\"\" set \"ACESTEP_ARGS=!ACESTEP_ARGS! %INIT_SERVICE%\"\n    if not \"%BATCH_SIZE%\"==\"\" set \"ACESTEP_ARGS=!ACESTEP_ARGS! %BATCH_SIZE%\"\n    if not \"%ENABLE_API%\"==\"\" set \"ACESTEP_ARGS=!ACESTEP_ARGS! %ENABLE_API%\"\n    if not \"%API_KEY%\"==\"\" set \"ACESTEP_ARGS=!ACESTEP_ARGS! %API_KEY%\"\n    if not \"%AUTH_USERNAME%\"==\"\" set \"ACESTEP_ARGS=!ACESTEP_ARGS! %AUTH_USERNAME%\"\n    if not \"%AUTH_PASSWORD%\"==\"\" set \"ACESTEP_ARGS=!ACESTEP_ARGS! %AUTH_PASSWORD%\"\n\n    uv run !ACESTEP_ARGS!\n    if !ERRORLEVEL! NEQ 0 (\n        echo.\n        echo [Retry] Online dependency resolution failed, retrying in offline mode...\n        echo.\n        uv run --offline !ACESTEP_ARGS!\n        if !ERRORLEVEL! NEQ 0 (\n            echo.\n            echo ========================================\n            echo [Error] Failed to start ACE-Step\n            echo ========================================\n            echo.\n            echo Both online and offline modes failed.\n            echo Please check:\n            echo   1. Your internet connection ^(for first-time setup^)\n            echo   2. If dependencies were previously installed ^(offline mode requires a prior successful install^)\n            echo   3. Try running: uv sync --offline\n            echo.\n            pause\n            exit /b 1\n        )\n    )\n)\n\npause\nendlocal\ngoto :eof\n\nREM ==================== Helper Functions ====================\n\n:LoadEnvFile\nREM Load environment variables from .env file if it exists\nset \"ENV_FILE=%~dp0.env\"\nif not exist \"%ENV_FILE%\" (\n    exit /b 0\n)\n\necho [Config] Loading configuration from .env file...\nfor /f \"usebackq tokens=1,* delims==\" %%a in (\"%ENV_FILE%\") do (\n    set \"line=%%a\"\n    set \"value=%%b\"\n    \n    REM Skip empty lines and comments\n    if not \"!line!\"==\"\" (\n        set \"first_char=!line:~0,1!\"\n        if not \"!first_char!\"==\"#\" (\n            REM Remove leading/trailing spaces from key\n            for /f \"tokens=* delims= \" %%x in (\"!line!\") do set \"key=%%x\"\n            \n            REM Map .env variable names to batch script variables\n            if /i \"!key!\"==\"ACESTEP_CONFIG_PATH\" (\n                if not \"!value!\"==\"\" set \"CONFIG_PATH=--config_path !value!\"\n            )\n            if /i \"!key!\"==\"ACESTEP_LM_MODEL_PATH\" (\n                if not \"!value!\"==\"\" set \"LM_MODEL_PATH=--lm_model_path !value!\"\n            )\n            if /i \"!key!\"==\"ACESTEP_INIT_LLM\" (\n                if not \"!value!\"==\"\" (\n                    if not \"!value!\"==\"auto\" set \"INIT_LLM=--init_llm !value!\"\n                )\n            )\n            if /i \"!key!\"==\"ACESTEP_DOWNLOAD_SOURCE\" (\n                if not \"!value!\"==\"\" (\n                    if not \"!value!\"==\"auto\" set \"DOWNLOAD_SOURCE=--download-source !value!\"\n                )\n            )\n            if /i \"!key!\"==\"ACESTEP_API_KEY\" (\n                if not \"!value!\"==\"\" set \"API_KEY=--api-key !value!\"\n            )\n            if /i \"!key!\"==\"PORT\" (\n                if not \"!value!\"==\"\" set \"PORT=!value!\"\n            )\n            if /i \"!key!\"==\"SERVER_NAME\" (\n                if not \"!value!\"==\"\" set \"SERVER_NAME=!value!\"\n            )\n            if /i \"!key!\"==\"LANGUAGE\" (\n                if not \"!value!\"==\"\" set \"LANGUAGE=!value!\"\n            )\n            if /i \"!key!\"==\"ACESTEP_BATCH_SIZE\" (\n                if not \"!value!\"==\"\" set \"BATCH_SIZE=--batch_size !value!\"\n            )\n        )\n    )\n)\necho [Config] Configuration loaded from .env\nexit /b 0\n\n:LoadManual\nREM Ask for manual settings\ncolor 0B\necho.\necho ======================================================\necho             ACE-Step Manual Launch Mode\necho ======================================================\necho.\n:manual_choice_ask\n    set /p MANUAL_CHOICE=\"Continue with manual configuration? (Y/N): \"\n    if /i \"%MANUAL_CHOICE%\"==\"Y\" (\n        goto manual_choice_done\n    )\n    if /i \"%MANUAL_CHOICE%\"==\"N\" (\n        color 07\n        echo.\n        echo Proceeding with automatic configuration...\n        echo.\n        exit /b 0\n    )\n    echo Invalid input. Please enter Y or N.\n    goto manual_choice_ask\n:manual_choice_done\n\necho.\necho -------------------- Update Settings --------------------\n:update_choice_ask\n    set /p UPDATE_CHOICE=\"Check for updates before launch? (Y/N): \"\n    if /i \"%UPDATE_CHOICE%\"==\"Y\" (\n        set CHECK_UPDATE=true\n        goto update_choice_done\n    )\n    if /i \"%UPDATE_CHOICE%\"==\"N\" (\n        set CHECK_UPDATE=false\n        goto update_choice_done\n    )\n    echo Invalid input. Please enter Y or N.\n    goto update_choice_ask\n:update_choice_done\necho Selected Update Check: %CHECK_UPDATE%\n\necho.\necho -------------------- Select DiT Model --------------------\necho 1^) acestep-v15-base\necho 2^) acestep-v15-sft\necho 3^) acestep-v15-turbo  (Recommended)\necho 4^) acestep-v15-turbo-rl\necho.\n:dit_choice_ask\n    set /p DIT_CHOICE=\"Enter selection (1-4): \"\n    if \"%DIT_CHOICE%\"==\"1\" (\n        set CONFIG_PATH=--config_path acestep-v15-base\n        goto dit_choice_done\n    )\n    if \"%DIT_CHOICE%\"==\"2\" (\n        set CONFIG_PATH=--config_path acestep-v15-sft\n        goto dit_choice_done\n    )\n    if \"%DIT_CHOICE%\"==\"3\" (\n        set CONFIG_PATH=--config_path acestep-v15-turbo\n        goto dit_choice_done\n    )\n    if \"%DIT_CHOICE%\"==\"4\" (\n        set CONFIG_PATH=--config_path acestep-v15-turbo-rl\n        goto dit_choice_done\n    )\n    echo Invalid input. Please enter a number between 1 and 4.\n    goto dit_choice_ask\n:dit_choice_done\necho Selected DiT Model: %CONFIG_PATH:--config_path =%\n\necho.\necho -------------------- Select LM Model --------------------\necho 1^) acestep-5Hz-lm-0.6B  (Recommended)\necho 2^) acestep-5Hz-lm-1.7B\necho 3^) acestep-5Hz-lm-4B\necho 4^) Launch without LM Model\necho.\n:lm_choice_ask\n    set /p LM_CHOICE=\"Enter selection (1-4): \"\n    if \"%LM_CHOICE%\"==\"1\" (\n        set LM_MODEL_PATH=--lm_model_path acestep-5Hz-lm-0.6B\n        set INIT_LLM=--init_llm true\n        goto lm_choice_done\n    )\n    if \"%LM_CHOICE%\"==\"2\" (\n        set LM_MODEL_PATH=--lm_model_path acestep-5Hz-lm-1.7B\n        set INIT_LLM=--init_llm true\n        goto lm_choice_done\n    )\n    if \"%LM_CHOICE%\"==\"3\" (\n        set LM_MODEL_PATH=--lm_model_path acestep-5Hz-lm-4B\n        set INIT_LLM=--init_llm true\n        goto lm_choice_done\n    )\n    if \"%LM_CHOICE%\"==\"4\" (\n        set LM_MODEL_PATH=\n        set INIT_LLM=--init_llm false\n        goto lm_choice_done\n    )\n    echo Invalid input. Please enter a number between 1 and 4.\n    goto lm_choice_ask\n:lm_choice_done\nif \"%LM_CHOICE%\"==\"4\" (\n    echo Selected LM Model: None\n    echo Selected Init LLM: false\n) else (\n    echo Selected LM Model: %LM_MODEL_PATH:--lm_model_path =%\n    echo Selected Init LLM: %INIT_LLM:--init_llm =%\n)\n\necho.\necho -------------------- Select UI Language --------------------\necho 1^) English (Default)\necho 2^) Hebrew (תירבע)\necho 3^) Chinese (中文)\necho 4^) Japanese (日本語)\necho.\n\n:lang_choice_ask\n    set \"LANG_PICK=1\"\n    set /p LANG_PICK=\"Select language [1-4] (Default: 1): \"\n    \n    if \"%LANG_PICK%\"==\"1\" (set LANGUAGE=en & goto lang_choice_done)\n    if \"%LANG_PICK%\"==\"2\" (set LANGUAGE=he & goto lang_choice_done)\n    if \"%LANG_PICK%\"==\"3\" (set LANGUAGE=zh & goto lang_choice_done)\n    if \"%LANG_PICK%\"==\"4\" (set LANGUAGE=ja & goto lang_choice_done)\n    \n    echo Invalid selection. Please enter 1, 2, 3 or 4.\n    goto lang_choice_ask\n\n:lang_choice_done\necho Selected language: %LANGUAGE%\n\necho.\necho -------------------- CPU Offload Option --------------------\n:offload_choice_ask\n    set /p OFFLOAD_CHOICE=\"Enable CPU Offload? (Y/N): \"\n    if /i \"%OFFLOAD_CHOICE%\"==\"Y\" (\n        set OFFLOAD_TO_CPU=--offload_to_cpu true\n        goto offload_choice_done\n    )\n    if /i \"%OFFLOAD_CHOICE%\"==\"N\" (\n        set OFFLOAD_TO_CPU=--offload_to_cpu false\n        goto offload_choice_done\n    )\n    echo Invalid input. Please enter Y or N.\n    goto offload_choice_ask\n:offload_choice_done\necho Selected Offload: %OFFLOAD_TO_CPU:--offload_to_cpu =%\n\ncolor 07\necho.\necho Manual configuration applied successfully.\necho.\nexit /b 0\n"
  },
  {
    "path": "start_gradio_ui_manual.sh",
    "content": "#!/usr/bin/env bash\n# ACE-Step Gradio Web UI Launcher - Linux (CUDA)\n# This script launches the Gradio web interface for ACE-Step\n\nset -euo pipefail\nSCRIPT_DIR=\"$(cd \"$(dirname \"${BASH_SOURCE[0]}\")\" && pwd)\"\n\n# ==================== Load .env Configuration ====================\n# Load settings from .env file if it exists\n_load_env_file() {\n    local env_file=\"${SCRIPT_DIR}/.env\"\n    if [[ ! -f \"$env_file\" ]]; then\n        return 0\n    fi\n    \n    echo \"[Config] Loading configuration from .env file...\"\n    \n    # Read .env file and export variables\n    while IFS='=' read -r key value || [[ -n \"$key\" ]]; do\n        # Skip empty lines and comments\n        [[ -z \"$key\" || \"$key\" =~ ^[[:space:]]*# ]] && continue\n        \n        # Trim whitespace from key and value\n        key=\"${key#\"${key%%[![:space:]]*}\"}\"\n        key=\"${key%\"${key##*[![:space:]]}\"}\"\n        value=\"${value#\"${value%%[![:space:]]*}\"}\"\n        value=\"${value%\"${value##*[![:space:]]}\"}\"\n        \n        # Map .env variable names to script variables\n        case \"$key\" in\n            ACESTEP_CONFIG_PATH)\n                [[ -n \"$value\" ]] && CONFIG_PATH=\"--config_path $value\"\n                ;;\n            ACESTEP_LM_MODEL_PATH)\n                [[ -n \"$value\" ]] && LM_MODEL_PATH=\"--lm_model_path $value\"\n                ;;\n            ACESTEP_INIT_LLM)\n                if [[ -n \"$value\" && \"$value\" != \"auto\" ]]; then\n                    INIT_LLM=\"--init_llm $value\"\n                fi\n                ;;\n            ACESTEP_DOWNLOAD_SOURCE)\n                if [[ -n \"$value\" && \"$value\" != \"auto\" ]]; then\n                    DOWNLOAD_SOURCE=\"--download-source $value\"\n                fi\n                ;;\n            ACESTEP_API_KEY)\n                [[ -n \"$value\" ]] && API_KEY=\"--api-key $value\"\n                ;;\n            PORT)\n                [[ -n \"$value\" ]] && PORT=\"$value\"\n                ;;\n            SERVER_NAME)\n                [[ -n \"$value\" ]] && SERVER_NAME=\"$value\"\n                ;;\n            LANGUAGE)\n                [[ -n \"$value\" ]] && LANGUAGE=\"$value\"\n                ;;\n            ACESTEP_BATCH_SIZE)\n                [[ -n \"$value\" ]] && BATCH_SIZE=\"--batch_size $value\"\n                ;;\n        esac\n    done < \"$env_file\"\n    \n    echo \"[Config] Configuration loaded from .env\"\n}\n\n_load_env_file\n\n# ==================== Manual Startup Configuration ====================\n# Ask for manual settings\n_load_manual() {\n    echo -e \"\\033[1;36m\"\n    echo \"======================================================\"\n    echo \"            ACE-Step Manual Launch Mode\"\n    echo \"======================================================\"\n    echo\n\n    while true; do\n        read -rp \"Continue with manual configuration? (Y/N): \" MANUAL_CHOICE\n        case \"$MANUAL_CHOICE\" in\n            [Yy])\n                break ;;\n            [Nn])\n                echo -e \"\\033[0m\"\n                echo \"Proceeding with automatic configuration...\"\n                echo\n                return 0 ;;\n            *)\n                echo \"Invalid input. Please enter Y or N.\" ;;\n        esac\n    done\n\n    echo\n    echo \"-------------------- Update Settings --------------------\"\n    while true; do\n        read -rp \"Check for updates before launch? (Y/N): \" UPDATE_CHOICE\n        case \"$UPDATE_CHOICE\" in\n            [Yy])\n                CHECK_UPDATE=\"true\"\n                break ;;\n            [Nn])\n                CHECK_UPDATE=\"false\"\n                break ;;\n            *)\n                echo \"Invalid input. Please enter Y or N.\" ;;\n        esac\n    done\n\n    echo\n    echo \"-------------------- Select DiT Model --------------------\"\n    echo \"1) acestep-v15-base\"\n    echo \"2) acestep-v15-sft\"\n    echo \"3) acestep-v15-turbo (Recommended)\"\n    echo \"4) acestep-v15-turbo-rl\"\n    echo\n    while true; do\n        read -rp \"Enter selection (1-4): \" DIT_CHOICE\n        case \"$DIT_CHOICE\" in\n            1)\n                CONFIG_PATH=\"--config_path acestep-v15-base\"\n                break ;;\n            2)\n                CONFIG_PATH=\"--config_path acestep-v15-sft\"\n                break ;;\n            3)\n                CONFIG_PATH=\"--config_path acestep-v15-turbo\"\n                break ;;\n            4)\n                CONFIG_PATH=\"--config_path acestep-v15-turbo-rl\"\n                break ;;\n            *)\n                echo \"Invalid input. Please enter a number between 1 and 4.\" ;;\n        esac\n    done\n\n    echo\n    echo \"-------------------- Select LM Model --------------------\"\n    echo \"1) acestep-5Hz-lm-0.6B (Recommended)\"\n    echo \"2) acestep-5Hz-lm-1.7B\"\n    echo \"3) acestep-5Hz-lm-4B\"\n    echo \"4) Launch without LM Model\"\n    echo\n    while true; do\n        read -rp \"Enter selection (1-4): \" LM_CHOICE\n        case \"$LM_CHOICE\" in\n            1)\n                LM_MODEL_PATH=\"--lm_model_path acestep-5Hz-lm-0.6B\"\n                INIT_LLM=\"--init_llm true\"\n                break ;;\n            2)\n                LM_MODEL_PATH=\"--lm_model_path acestep-5Hz-lm-1.7B\"\n                INIT_LLM=\"--init_llm true\"\n                break ;;\n            3)\n                LM_MODEL_PATH=\"--lm_model_path acestep-5Hz-lm-4B\"\n                INIT_LLM=\"--init_llm true\"\n                break ;;\n            4)\n                LM_MODEL_PATH=\"\"\n                INIT_LLM=\"--init_llm false\"\n                break ;;\n            *)\n                echo \"Invalid input. Please enter a number between 1 and 4.\" ;;\n        esac\n    done\n\n    echo\n    echo \"-------------------- CPU Offload Option --------------------\"\n    while true; do\n        read -rp \"Enable CPU Offload? (Y/N): \" OFFLOAD_CHOICE\n        case \"$OFFLOAD_CHOICE\" in\n            [Yy])\n                OFFLOAD_TO_CPU=\"--offload_to_cpu true\"\n                break ;;\n            [Nn])\n                OFFLOAD_TO_CPU=\"--offload_to_cpu false\"\n                break ;;\n            *)\n                echo \"Invalid input. Please enter Y or N.\" ;;\n        esac\n    done\n\n    echo -e \"\\033[0m\"\n    echo \"Manual configuration applied successfully.\"\n    echo\n}\n\n_load_manual\n\n# ==================== Configuration ====================\n# Default values (used if not set in .env file)\n# You can override these by uncommenting and modifying the lines below\n# or by creating a .env file (recommended to survive updates)\n\n# Server settings\n: \"${PORT:=7860}\"\n: \"${SERVER_NAME:=127.0.0.1}\"\n# SERVER_NAME=\"0.0.0.0\"\nSHARE=\"${SHARE:-}\"\n# SHARE=\"--share\"\n\n# Reset LANGUAGE if it contains an invalid value (e.g. system locale like en_CA:en)\ncase \"$LANGUAGE\" in\n    en|zh|he|ja) ;;\n    *) unset LANGUAGE ;;\nesac\n# UI language: en, zh, he, ja\n: \"${LANGUAGE:=en}\"\n\n# Batch size: default batch size for generation (1 to GPU-dependent max)\n# When not specified, defaults to min(2, GPU_max)\nBATCH_SIZE=\"${BATCH_SIZE:-}\"\n# BATCH_SIZE=\"--batch_size 4\"\n\n# Model settings\n: \"${CONFIG_PATH:=--config_path acestep-v15-turbo}\"\n: \"${LM_MODEL_PATH:=--lm_model_path acestep-5Hz-lm-0.6B}\"\n# OFFLOAD_TO_CPU=\"--offload_to_cpu true\"\nOFFLOAD_TO_CPU=\"${OFFLOAD_TO_CPU:-}\"\n\n# LLM (Language Model) initialization settings\n# By default, LLM is auto-enabled/disabled based on GPU VRAM:\n#   - <=6GB VRAM: LLM disabled (DiT-only mode)\n#   - >6GB VRAM: LLM enabled\n# Values: auto (default), true (force enable), false (force disable)\nINIT_LLM=\"${INIT_LLM:-}\"\n# INIT_LLM=\"--init_llm auto\"\n# INIT_LLM=\"--init_llm true\"\n# INIT_LLM=\"--init_llm false\"\n\n# Download source settings\n# Preferred download source: auto (default), huggingface, or modelscope\nDOWNLOAD_SOURCE=\"${DOWNLOAD_SOURCE:-}\"\n# DOWNLOAD_SOURCE=\"--download-source modelscope\"\n# DOWNLOAD_SOURCE=\"--download-source huggingface\"\n\n# Update check on startup (set to \"false\" to disable)\n: \"${CHECK_UPDATE:=true}\"\n# CHECK_UPDATE=\"false\"\n\n# Auto-initialize models on startup\n: \"${INIT_SERVICE:=--init_service true}\"\n\n# API settings (enable REST API alongside Gradio)\nENABLE_API=\"${ENABLE_API:-}\"\n# ENABLE_API=\"--enable-api\"\nAPI_KEY=\"${API_KEY:-}\"\n# API_KEY=\"--api-key sk-your-secret-key\"\n\n# Authentication settings\nAUTH_USERNAME=\"${AUTH_USERNAME:-}\"\n# AUTH_USERNAME=\"--auth-username admin\"\nAUTH_PASSWORD=\"${AUTH_PASSWORD:-}\"\n# AUTH_PASSWORD=\"--auth-password password\"\n\n# ==================== Launch ====================\n\n# ==================== Startup Update Check ====================\n_startup_update_check() {\n    [[ \"$CHECK_UPDATE\" != \"true\" ]] && return 0\n    command -v git &>/dev/null || return 0\n    cd \"$SCRIPT_DIR\" || return 0\n    git rev-parse --git-dir &>/dev/null 2>&1 || return 0\n\n    local branch commit remote_commit\n    branch=\"$(git rev-parse --abbrev-ref HEAD 2>/dev/null || echo \"main\")\"\n    commit=\"$(git rev-parse --short HEAD 2>/dev/null || echo \"\")\"\n    [[ -z \"$commit\" ]] && return 0\n\n    echo \"[Update] Checking for updates...\"\n\n    # Fetch with timeout (10s)\n    local fetch_ok=0\n    if command -v timeout &>/dev/null; then\n        timeout 10 git fetch origin --quiet 2>/dev/null && fetch_ok=1\n    elif command -v gtimeout &>/dev/null; then\n        gtimeout 10 git fetch origin --quiet 2>/dev/null && fetch_ok=1\n    else\n        git fetch origin --quiet 2>/dev/null && fetch_ok=1\n    fi\n\n    if [[ $fetch_ok -eq 0 ]]; then\n        echo \"[Update] Network unreachable, skipping.\"\n        echo\n        return 0\n    fi\n\n    remote_commit=\"$(git rev-parse --short \"origin/$branch\" 2>/dev/null || echo \"\")\"\n\n    if [[ -z \"$remote_commit\" || \"$commit\" == \"$remote_commit\" ]]; then\n        echo \"[Update] Already up to date ($commit).\"\n        echo\n        return 0\n    fi\n\n    echo\n    echo \"========================================\"\n    echo \"  Update available!\"\n    echo \"========================================\"\n    echo \"  Current: $commit  ->  Latest: $remote_commit\"\n    echo\n    echo \"  Recent changes:\"\n    git --no-pager log --oneline \"HEAD..origin/$branch\" 2>/dev/null | head -10\n    echo\n\n    read -rp \"Update now before starting? (Y/N): \" update_choice\n    if [[ \"${update_choice^^}\" == \"Y\" ]]; then\n        if [[ -f \"$SCRIPT_DIR/check_update.sh\" ]]; then\n            bash \"$SCRIPT_DIR/check_update.sh\"\n        else\n            echo \"Pulling latest changes...\"\n            git pull --ff-only origin \"$branch\" 2>/dev/null || {\n                echo \"[Update] Update failed. Please run: git pull\"\n            }\n        fi\n    else\n        echo \"[Update] Skipped. Run ./check_update.sh to update later.\"\n    fi\n    echo\n}\n_startup_update_check\n\necho \"Starting ACE-Step Gradio Web UI...\"\necho \"Server will be available at: http://${SERVER_NAME}:${PORT}\"\necho\n\n# ==================== Standard uv Workflow ====================\n# Works on all platforms: x86_64 Linux (cu128), aarch64 Linux/DGX Spark (cu130),\n# macOS (MPS), Windows (cu128). uv resolves the correct PyTorch wheels via\n# platform-specific index mappings in pyproject.toml.\n\n# Check if uv is installed\nif ! command -v uv &>/dev/null; then\n    # Try common install locations\n    if [[ -x \"$HOME/.local/bin/uv\" ]]; then\n        export PATH=\"$HOME/.local/bin:$PATH\"\n    elif [[ -x \"$HOME/.cargo/bin/uv\" ]]; then\n        export PATH=\"$HOME/.cargo/bin:$PATH\"\n    fi\nfi\n\nif ! command -v uv &>/dev/null; then\n    echo\n    echo \"========================================\"\n    echo \"uv package manager not found!\"\n    echo \"========================================\"\n    echo\n    echo \"ACE-Step requires the uv package manager.\"\n    echo\n    read -rp \"Install uv now? (Y/N): \" INSTALL_UV\n\n    if [[ \"${INSTALL_UV^^}\" == \"Y\" ]]; then\n        echo\n        bash \"$SCRIPT_DIR/install_uv.sh\" --silent\n        INSTALL_RESULT=$?\n\n        if [[ $INSTALL_RESULT -eq 0 ]]; then\n            echo\n            echo \"========================================\"\n            echo \"uv installed successfully!\"\n            echo \"========================================\"\n            echo\n\n            export PATH=\"$HOME/.local/bin:$HOME/.cargo/bin:$PATH\"\n\n            if command -v uv &>/dev/null; then\n                echo \"uv is now available!\"\n                uv --version\n                echo\n            else\n                echo\n                echo \"uv installed but not in PATH yet.\"\n                echo \"Please restart your terminal or run:\"\n                echo \"  export PATH=\\\"\\$HOME/.local/bin:\\$PATH\\\"\"\n                echo\n                exit 1\n            fi\n        else\n            echo\n            echo \"========================================\"\n            echo \"Installation failed!\"\n            echo \"========================================\"\n            echo\n            echo \"Please install uv manually:\"\n            echo \"  curl -LsSf https://astral.sh/uv/install.sh | sh\"\n            echo\n            exit 1\n        fi\n    else\n        echo\n        echo \"Installation cancelled.\"\n        echo\n        echo \"To use ACE-Step, please install uv:\"\n        echo \"  curl -LsSf https://astral.sh/uv/install.sh | sh\"\n        echo\n        exit 1\n    fi\nfi\n\necho \"[Environment] Using uv package manager...\"\necho\n\n# Check if virtual environment exists\nif [[ ! -d \"$SCRIPT_DIR/.venv\" ]]; then\n    echo \"[Setup] Virtual environment not found. Setting up environment...\"\n    echo \"This will take a few minutes on first run.\"\n    echo\n    echo \"Running: uv sync\"\n    echo\n\n    if ! (cd \"$SCRIPT_DIR\" && uv sync); then\n        echo\n        echo \"[Retry] Online sync failed, retrying in offline mode...\"\n        echo\n        if ! (cd \"$SCRIPT_DIR\" && uv sync --offline); then\n            echo\n            echo \"========================================\"\n            echo \"[Error] Failed to setup environment\"\n            echo \"========================================\"\n            echo\n            echo \"Both online and offline modes failed.\"\n            echo \"Please check:\"\n            echo \"  1. Your internet connection (required for first-time setup)\"\n            echo \"  2. Ensure you have enough disk space\"\n            echo \"  3. Try running: uv sync manually\"\n            exit 1\n        fi\n    fi\n\n    echo\n    echo \"========================================\"\n    echo \"Environment setup completed!\"\n    echo \"========================================\"\n    echo\nfi\n\necho \"Starting ACE-Step Gradio UI...\"\necho\n\n# Build command with optional parameters\nACESTEP_ARGS=\"acestep --port $PORT --server-name $SERVER_NAME --language $LANGUAGE\"\n[[ -n \"$SHARE\" ]] && ACESTEP_ARGS=\"$ACESTEP_ARGS $SHARE\"\n[[ -n \"$CONFIG_PATH\" ]] && ACESTEP_ARGS=\"$ACESTEP_ARGS $CONFIG_PATH\"\n[[ -n \"$LM_MODEL_PATH\" ]] && ACESTEP_ARGS=\"$ACESTEP_ARGS $LM_MODEL_PATH\"\n[[ -n \"$OFFLOAD_TO_CPU\" ]] && ACESTEP_ARGS=\"$ACESTEP_ARGS $OFFLOAD_TO_CPU\"\n[[ -n \"$INIT_LLM\" ]] && ACESTEP_ARGS=\"$ACESTEP_ARGS $INIT_LLM\"\n[[ -n \"$DOWNLOAD_SOURCE\" ]] && ACESTEP_ARGS=\"$ACESTEP_ARGS $DOWNLOAD_SOURCE\"\n[[ -n \"$INIT_SERVICE\" ]] && ACESTEP_ARGS=\"$ACESTEP_ARGS $INIT_SERVICE\"\n[[ -n \"$BATCH_SIZE\" ]] && ACESTEP_ARGS=\"$ACESTEP_ARGS $BATCH_SIZE\"\n[[ -n \"$ENABLE_API\" ]] && ACESTEP_ARGS=\"$ACESTEP_ARGS $ENABLE_API\"\n[[ -n \"$API_KEY\" ]] && ACESTEP_ARGS=\"$ACESTEP_ARGS $API_KEY\"\n[[ -n \"$AUTH_USERNAME\" ]] && ACESTEP_ARGS=\"$ACESTEP_ARGS $AUTH_USERNAME\"\n[[ -n \"$AUTH_PASSWORD\" ]] && ACESTEP_ARGS=\"$ACESTEP_ARGS $AUTH_PASSWORD\"\n\ncd \"$SCRIPT_DIR\" && uv run $ACESTEP_ARGS || {\n    echo\n    echo \"[Retry] Online dependency resolution failed, retrying in offline mode...\"\n    echo\n    uv run --offline $ACESTEP_ARGS || {\n        echo\n        echo \"========================================\"\n        echo \"[Error] Failed to start ACE-Step\"\n        echo \"========================================\"\n        echo\n        echo \"Both online and offline modes failed.\"\n        echo \"Please check:\"\n        echo \"  1. Your internet connection (for first-time setup)\"\n        echo \"  2. If dependencies were previously installed (offline mode requires a prior successful install)\"\n        echo \"  3. Try running: uv sync --offline\"\n        exit 1\n    }\n}\n"
  },
  {
    "path": "start_gradio_ui_rocm.bat",
    "content": "@echo off\nsetlocal enabledelayedexpansion\nREM ACE-Step Gradio Web UI Launcher - AMD ROCm 7.2\nREM For AMD RX 7000/6000 series GPUs on Windows 11\nREM IMPORTANT: Requires Python 3.12 (AMD ROCm 7.2 only provides Python 3.12 wheels)\nREM Requires: ROCm PyTorch from repo.radeon.com\n\nREM ==================== Load .env Configuration ====================\nREM Load settings from .env file if it exists\ncall :LoadEnvFile\n\nREM ==================== ROCm Configuration ====================\nREM Force PyTorch LM backend (bypasses nano-vllm flash_attn dependency)\nset ACESTEP_LM_BACKEND=pt\n\nREM RDNA3 GPU architecture override (RX 7900 XT/XTX, RX 7800 XT, etc.)\nREM Change to 11.0.1 for gfx1101 (RX 7700 XT, RX 7800 XT)\nREM Change to 11.0.2 for gfx1102 (RX 7600)\nset HSA_OVERRIDE_GFX_VERSION=11.0.0\n\nREM Disable torch.compile Triton backend (not available on ROCm Windows)\nset TORCH_COMPILE_BACKEND=eager\n\nREM MIOpen: use fast heuristic kernel selection instead of exhaustive benchmarking\nREM Without this, first-run VAE decode hangs for minutes on each conv layer\nset MIOPEN_FIND_MODE=FAST\n\nREM HuggingFace tokenizer parallelism\nset TOKENIZERS_PARALLELISM=false\n\nREM ==================== Server Configuration ====================\nREM Default values (used if not set in .env file)\nREM You can override these by uncommenting and modifying the lines below\nREM or by creating a .env file (recommended to survive updates)\n\nif not defined PORT set PORT=7860\nif not defined SERVER_NAME set SERVER_NAME=127.0.0.1\nREM set SERVER_NAME=0.0.0.0\nREM set SHARE=--share\n\nREM UI language: en, zh, ja\nif not defined LANGUAGE set LANGUAGE=en\n\nREM Batch size: default batch size for generation (1 to GPU-dependent max)\nREM When not specified, defaults to min(2, GPU_max)\nREM set BATCH_SIZE=--batch_size 4\n\nREM ==================== Model Configuration ====================\nif not defined CONFIG_PATH set CONFIG_PATH=--config_path acestep-v15-turbo\nif not defined LM_MODEL_PATH set LM_MODEL_PATH=--lm_model_path acestep-5Hz-lm-4B\n\nREM CPU offload: required for 4B LM on GPUs with <=20GB VRAM\nREM Models shuttle between CPU/GPU as needed (DiT stays on GPU, LM/VAE/text_encoder move on demand)\nREM Adds ~8-10s overhead per generation but prevents VRAM oversubscription\nREM Disable if using 1.7B/0.6B LM or if your GPU has >=24GB VRAM\nif not defined OFFLOAD_TO_CPU set OFFLOAD_TO_CPU=--offload_to_cpu true\n\nREM LLM initialization: auto (default), true, false\nREM set INIT_LLM=--init_llm auto\n\nREM Download source: auto, huggingface, modelscope\nif not defined DOWNLOAD_SOURCE set DOWNLOAD_SOURCE=\n\nREM Auto-initialize models on startup\nif not defined INIT_SERVICE set INIT_SERVICE=--init_service true\n\nREM LM backend: pt (PyTorch) recommended for ROCm\nset BACKEND=--backend pt\n\nREM API settings\nREM set ENABLE_API=--enable-api\nREM set API_KEY=--api-key sk-your-secret-key\n\nREM Authentication\nREM set AUTH_USERNAME=--auth-username admin\nREM set AUTH_PASSWORD=--auth-password password\n\nREM Update check on startup (set to false to disable)\nset CHECK_UPDATE=true\nREM set CHECK_UPDATE=false\n\nREM ==================== Venv Configuration ====================\nREM Path to the ROCm virtual environment (relative to this script)\nset VENV_DIR=%~dp0venv_rocm\n\nREM ==================== Launch ====================\n\nREM ==================== Startup Update Check ====================\nif /i not \"%CHECK_UPDATE%\"==\"true\" goto :SkipUpdateCheck\n\nREM Find git: try PortableGit first, then system git\nset \"UPDATE_GIT_CMD=\"\nif exist \"%~dp0PortableGit\\bin\\git.exe\" (\n    set \"UPDATE_GIT_CMD=%~dp0PortableGit\\bin\\git.exe\"\n) else (\n    where git >nul 2>&1\n    if !ERRORLEVEL! EQU 0 (\n        for /f \"tokens=*\" %%i in ('where git 2^>nul') do (\n            if not defined UPDATE_GIT_CMD set \"UPDATE_GIT_CMD=%%i\"\n        )\n    )\n)\nif not defined UPDATE_GIT_CMD goto :SkipUpdateCheck\n\ncd /d \"%~dp0\"\n\"!UPDATE_GIT_CMD!\" rev-parse --git-dir >nul 2>&1\nif !ERRORLEVEL! NEQ 0 goto :SkipUpdateCheck\n\necho [Update] Checking for updates...\n\nfor /f \"tokens=*\" %%i in ('\"!UPDATE_GIT_CMD!\" rev-parse --abbrev-ref HEAD 2^>nul') do set UPDATE_BRANCH=%%i\nif \"!UPDATE_BRANCH!\"==\"\" set UPDATE_BRANCH=main\nfor /f \"tokens=*\" %%i in ('\"!UPDATE_GIT_CMD!\" rev-parse --short HEAD 2^>nul') do set UPDATE_LOCAL=%%i\n\n\"!UPDATE_GIT_CMD!\" fetch origin --quiet 2>nul\nif !ERRORLEVEL! NEQ 0 (\n    echo [Update] Network unreachable, skipping.\n    echo.\n    goto :SkipUpdateCheck\n)\n\nfor /f \"tokens=*\" %%i in ('\"!UPDATE_GIT_CMD!\" rev-parse --short origin/!UPDATE_BRANCH! 2^>nul') do set UPDATE_REMOTE=%%i\n\nif \"!UPDATE_REMOTE!\"==\"\" goto :SkipUpdateCheck\nif \"!UPDATE_LOCAL!\"==\"!UPDATE_REMOTE!\" (\n    echo [Update] Already up to date ^(!UPDATE_LOCAL!^).\n    echo.\n    goto :SkipUpdateCheck\n)\n\necho.\necho ========================================\necho   Update available!\necho ========================================\necho   Current: !UPDATE_LOCAL!  -^>  Latest: !UPDATE_REMOTE!\necho.\necho   Recent changes:\n\"!UPDATE_GIT_CMD!\" --no-pager log --oneline HEAD..origin/!UPDATE_BRANCH! 2>nul\necho.\n\nset /p UPDATE_NOW=\"Update now before starting? (Y/N): \"\nif /i \"!UPDATE_NOW!\"==\"Y\" (\n    if exist \"%~dp0check_update.bat\" (\n        call \"%~dp0check_update.bat\"\n    ) else (\n        echo Pulling latest changes...\n        \"!UPDATE_GIT_CMD!\" pull --ff-only origin !UPDATE_BRANCH! 2>nul\n        if !ERRORLEVEL! NEQ 0 (\n            echo [Update] Update failed. Please update manually.\n        )\n    )\n) else (\n    echo [Update] Skipped. Run check_update.bat to update later.\n)\necho.\n\n:SkipUpdateCheck\n\necho ============================================\necho   ACE-Step 1.5 - AMD ROCm 7.2 Edition\necho ============================================\necho.\n\nREM Activate venv if it exists\nif exist \"%VENV_DIR%\\Scripts\\activate.bat\" (\n    echo Activating virtual environment: %VENV_DIR%\n    call \"%VENV_DIR%\\Scripts\\activate.bat\"\n) else (\n    echo WARNING: venv_rocm not found at %VENV_DIR%\n    echo Using system Python. See requirements-rocm.txt for setup instructions.\n)\necho.\n\nREM Verify ROCm PyTorch is installed\npython -c \"import torch; assert torch.cuda.is_available(), 'No GPU detected'; print(f'GPU: {torch.cuda.get_device_name(0)}'); hip=getattr(torch.version,'hip',None); print(f'HIP: {hip}' if hip else 'WARNING: Not a ROCm build')\" 2>nul\nif !ERRORLEVEL! NEQ 0 (\n    echo.\n    echo ========================================\n    echo  ERROR: ROCm PyTorch not detected!\n    echo ========================================\n    echo.\n    echo Please install ROCm PyTorch first. See requirements-rocm.txt for instructions.\n    echo.\n    pause\n    exit /b 1\n)\necho.\n\necho Starting ACE-Step Gradio Web UI...\necho Server will be available at: http://%SERVER_NAME%:%PORT%\necho.\n\nREM Build command with optional parameters\nset \"CMD=--port %PORT% --server-name %SERVER_NAME% --language %LANGUAGE%\"\nif not \"%SHARE%\"==\"\" set \"CMD=!CMD! %SHARE%\"\nif not \"%CONFIG_PATH%\"==\"\" set \"CMD=!CMD! %CONFIG_PATH%\"\nif not \"%LM_MODEL_PATH%\"==\"\" set \"CMD=!CMD! %LM_MODEL_PATH%\"\nif not \"%OFFLOAD_TO_CPU%\"==\"\" set \"CMD=!CMD! %OFFLOAD_TO_CPU%\"\nif not \"%INIT_LLM%\"==\"\" set \"CMD=!CMD! %INIT_LLM%\"\nif not \"%DOWNLOAD_SOURCE%\"==\"\" set \"CMD=!CMD! %DOWNLOAD_SOURCE%\"\nif not \"%INIT_SERVICE%\"==\"\" set \"CMD=!CMD! %INIT_SERVICE%\"\nif not \"%BATCH_SIZE%\"==\"\" set \"CMD=!CMD! %BATCH_SIZE%\"\nif not \"%BACKEND%\"==\"\" set \"CMD=!CMD! %BACKEND%\"\nif not \"%ENABLE_API%\"==\"\" set \"CMD=!CMD! %ENABLE_API%\"\nif not \"%API_KEY%\"==\"\" set \"CMD=!CMD! %API_KEY%\"\nif not \"%AUTH_USERNAME%\"==\"\" set \"CMD=!CMD! %AUTH_USERNAME%\"\nif not \"%AUTH_PASSWORD%\"==\"\" set \"CMD=!CMD! %AUTH_PASSWORD%\"\n\npython -u acestep\\acestep_v15_pipeline.py !CMD!\n\npause\nendlocal\ngoto :eof\n\nREM ==================== Helper Functions ====================\n\n:LoadEnvFile\nREM Load environment variables from .env file if it exists\nset \"ENV_FILE=%~dp0.env\"\nif not exist \"%ENV_FILE%\" (\n    exit /b 0\n)\n\necho [Config] Loading configuration from .env file...\nfor /f \"usebackq tokens=1,* delims==\" %%a in (\"%ENV_FILE%\") do (\n    set \"line=%%a\"\n    set \"value=%%b\"\n    \n    REM Skip empty lines and comments\n    if not \"!line!\"==\"\" (\n        set \"first_char=!line:~0,1!\"\n        if not \"!first_char!\"==\"#\" (\n            REM Remove leading/trailing spaces from key\n            for /f \"tokens=* delims= \" %%x in (\"!line!\") do set \"key=%%x\"\n            \n            REM Map .env variable names to batch script variables\n            if /i \"!key!\"==\"ACESTEP_CONFIG_PATH\" (\n                if not \"!value!\"==\"\" set \"CONFIG_PATH=--config_path !value!\"\n            )\n            if /i \"!key!\"==\"ACESTEP_LM_MODEL_PATH\" (\n                if not \"!value!\"==\"\" set \"LM_MODEL_PATH=--lm_model_path !value!\"\n            )\n            if /i \"!key!\"==\"ACESTEP_INIT_LLM\" (\n                if not \"!value!\"==\"\" (\n                    if not \"!value!\"==\"auto\" set \"INIT_LLM=--init_llm !value!\"\n                )\n            )\n            if /i \"!key!\"==\"ACESTEP_DOWNLOAD_SOURCE\" (\n                if not \"!value!\"==\"\" (\n                    if not \"!value!\"==\"auto\" set \"DOWNLOAD_SOURCE=--download-source !value!\"\n                )\n            )\n            if /i \"!key!\"==\"ACESTEP_API_KEY\" (\n                if not \"!value!\"==\"\" set \"API_KEY=--api-key !value!\"\n            )\n            if /i \"!key!\"==\"PORT\" (\n                if not \"!value!\"==\"\" set \"PORT=!value!\"\n            )\n            if /i \"!key!\"==\"SERVER_NAME\" (\n                if not \"!value!\"==\"\" set \"SERVER_NAME=!value!\"\n            )\n            if /i \"!key!\"==\"LANGUAGE\" (\n                if not \"!value!\"==\"\" set \"LANGUAGE=!value!\"\n            )\n            if /i \"!key!\"==\"ACESTEP_BATCH_SIZE\" (\n                if not \"!value!\"==\"\" set \"BATCH_SIZE=--batch_size !value!\"\n            )\n        )\n    )\n)\necho [Config] Configuration loaded from .env\nexit /b 0\n"
  },
  {
    "path": "start_gradio_ui_rocm.sh",
    "content": "#!/usr/bin/env bash\n# ACE-Step Gradio Web UI Launcher - Linux AMD ROCm\n# For AMD RX 7000/6000 series GPUs on Linux\n# Requires: ROCm 6.x+ and ROCm PyTorch from https://pytorch.org/\n#\n# Setup:\n#   1. Install ROCm: https://rocm.docs.amd.com/projects/install-on-linux/\n#   2. Create venv:  python3 -m venv venv_rocm\n#   3. Activate:     source venv_rocm/bin/activate\n#   4. Install PyTorch for ROCm:\n#      pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/rocm6.3\n#   5. Install dependencies:\n#      pip install -r requirements-rocm-linux.txt\n#   6. Run this script: ./start_gradio_ui_rocm.sh\n\nset -euo pipefail\nSCRIPT_DIR=\"$(cd \"$(dirname \"${BASH_SOURCE[0]}\")\" && pwd)\"\n\n# ==================== Load .env Configuration ====================\n_load_env_file() {\n    local env_file=\"${SCRIPT_DIR}/.env\"\n    if [[ ! -f \"$env_file\" ]]; then\n        return 0\n    fi\n\n    echo \"[Config] Loading configuration from .env file...\"\n\n    while IFS='=' read -r key value || [[ -n \"$key\" ]]; do\n        [[ -z \"$key\" || \"$key\" =~ ^[[:space:]]*# ]] && continue\n\n        key=\"${key#\"${key%%[![:space:]]*}\"}\"\n        key=\"${key%\"${key##*[![:space:]]}\"}\"\n        value=\"${value#\"${value%%[![:space:]]*}\"}\"\n        value=\"${value%\"${value##*[![:space:]]}\"}\"\n\n        case \"$key\" in\n            ACESTEP_CONFIG_PATH)\n                [[ -n \"$value\" ]] && CONFIG_PATH=\"--config_path $value\"\n                ;;\n            ACESTEP_LM_MODEL_PATH)\n                [[ -n \"$value\" ]] && LM_MODEL_PATH=\"--lm_model_path $value\"\n                ;;\n            ACESTEP_INIT_LLM)\n                if [[ -n \"$value\" && \"$value\" != \"auto\" ]]; then\n                    INIT_LLM=\"--init_llm $value\"\n                fi\n                ;;\n            ACESTEP_DOWNLOAD_SOURCE)\n                if [[ -n \"$value\" && \"$value\" != \"auto\" ]]; then\n                    DOWNLOAD_SOURCE=\"--download-source $value\"\n                fi\n                ;;\n            ACESTEP_API_KEY)\n                [[ -n \"$value\" ]] && API_KEY=\"--api-key $value\"\n                ;;\n            PORT)\n                [[ -n \"$value\" ]] && PORT=\"$value\"\n                ;;\n            SERVER_NAME)\n                [[ -n \"$value\" ]] && SERVER_NAME=\"$value\"\n                ;;\n            LANGUAGE)\n                [[ -n \"$value\" ]] && LANGUAGE=\"$value\"\n                ;;\n        esac\n    done < \"$env_file\"\n\n    echo \"[Config] Configuration loaded from .env\"\n}\n\n_load_env_file\n\n# ==================== ROCm Configuration ====================\n# Force PyTorch LM backend (bypasses nano-vllm flash_attn dependency)\nexport ACESTEP_LM_BACKEND=\"pt\"\n\n# RDNA3 GPU architecture override (RX 7900 XT/XTX, RX 7800 XT, etc.)\n# Change to 11.0.1 for gfx1101 (RX 7700 XT, RX 7800 XT)\n# Change to 11.0.2 for gfx1102 (RX 7600)\nexport HSA_OVERRIDE_GFX_VERSION=\"${HSA_OVERRIDE_GFX_VERSION:-11.0.0}\"\n\n# MIOpen: use fast heuristic kernel selection instead of exhaustive benchmarking\n# Without this, first-run VAE decode hangs for minutes on each conv layer\nexport MIOPEN_FIND_MODE=\"FAST\"\n\n# HuggingFace tokenizer parallelism\nexport TOKENIZERS_PARALLELISM=\"false\"\n\n# ==================== Server Configuration ====================\n: \"${PORT:=7860}\"\n: \"${SERVER_NAME:=127.0.0.1}\"\n# SERVER_NAME=\"0.0.0.0\"\nSHARE=\"${SHARE:-}\"\n# SHARE=\"--share\"\n\n# Reset LANGUAGE if it contains an invalid value (e.g. system locale like en_CA:en)\ncase \"$LANGUAGE\" in\n    en|zh|he|ja) ;;\n    *) unset LANGUAGE ;;\nesac\n# UI language: en, zh, he, ja\n: \"${LANGUAGE:=en}\"\n\n# ==================== Model Configuration ====================\n: \"${CONFIG_PATH:=--config_path acestep-v15-turbo}\"\n: \"${LM_MODEL_PATH:=--lm_model_path acestep-5Hz-lm-4B}\"\n\n# CPU offload: required for 4B LM on GPUs with <=20GB VRAM\n# Disable if using 1.7B/0.6B LM or if your GPU has >=24GB VRAM\n: \"${OFFLOAD_TO_CPU:=--offload_to_cpu true}\"\n\n# LLM initialization: auto (default), true, false\nINIT_LLM=\"${INIT_LLM:-}\"\n# INIT_LLM=\"--init_llm auto\"\n\n# Download source: auto, huggingface, modelscope\nDOWNLOAD_SOURCE=\"${DOWNLOAD_SOURCE:-}\"\n\n# Auto-initialize models on startup\n: \"${INIT_SERVICE:=--init_service true}\"\n\n# LM backend: pt (PyTorch) recommended for ROCm\nBACKEND=\"--backend pt\"\n\n# API settings\nENABLE_API=\"${ENABLE_API:-}\"\n# ENABLE_API=\"--enable-api\"\nAPI_KEY=\"${API_KEY:-}\"\n# API_KEY=\"--api-key sk-your-secret-key\"\n\n# Authentication\nAUTH_USERNAME=\"${AUTH_USERNAME:-}\"\n# AUTH_USERNAME=\"--auth-username admin\"\nAUTH_PASSWORD=\"${AUTH_PASSWORD:-}\"\n# AUTH_PASSWORD=\"--auth-password password\"\n\n# Update check on startup (set to \"false\" to disable)\n: \"${CHECK_UPDATE:=true}\"\n\n# ==================== Venv Configuration ====================\nVENV_DIR=\"${SCRIPT_DIR}/venv_rocm\"\n\n# ==================== Startup Update Check ====================\n_startup_update_check() {\n    [[ \"$CHECK_UPDATE\" != \"true\" ]] && return 0\n    command -v git &>/dev/null || return 0\n    cd \"$SCRIPT_DIR\" || return 0\n    git rev-parse --git-dir &>/dev/null 2>&1 || return 0\n\n    local branch commit remote_commit\n    branch=\"$(git rev-parse --abbrev-ref HEAD 2>/dev/null || echo \"main\")\"\n    commit=\"$(git rev-parse --short HEAD 2>/dev/null || echo \"\")\"\n    [[ -z \"$commit\" ]] && return 0\n\n    echo \"[Update] Checking for updates...\"\n\n    local fetch_ok=0\n    if command -v timeout &>/dev/null; then\n        timeout 10 git fetch origin --quiet 2>/dev/null && fetch_ok=1\n    else\n        git fetch origin --quiet 2>/dev/null && fetch_ok=1\n    fi\n\n    if [[ $fetch_ok -eq 0 ]]; then\n        echo \"[Update] Network unreachable, skipping.\"\n        echo\n        return 0\n    fi\n\n    remote_commit=\"$(git rev-parse --short \"origin/$branch\" 2>/dev/null || echo \"\")\"\n\n    if [[ -z \"$remote_commit\" || \"$commit\" == \"$remote_commit\" ]]; then\n        echo \"[Update] Already up to date ($commit).\"\n        echo\n        return 0\n    fi\n\n    echo\n    echo \"========================================\"\n    echo \"  Update available!\"\n    echo \"========================================\"\n    echo \"  Current: $commit  ->  Latest: $remote_commit\"\n    echo\n    echo \"  Recent changes:\"\n    git --no-pager log --oneline \"HEAD..origin/$branch\" 2>/dev/null | head -10\n    echo\n\n    read -rp \"Update now before starting? (Y/N): \" update_choice\n    if [[ \"${update_choice^^}\" == \"Y\" ]]; then\n        if [[ -f \"$SCRIPT_DIR/check_update.sh\" ]]; then\n            bash \"$SCRIPT_DIR/check_update.sh\"\n        else\n            echo \"Pulling latest changes...\"\n            git pull --ff-only origin \"$branch\" 2>/dev/null || {\n                echo \"[Update] Update failed. Please run: git pull\"\n            }\n        fi\n    else\n        echo \"[Update] Skipped. Run ./check_update.sh to update later.\"\n    fi\n    echo\n}\n_startup_update_check\n\necho \"============================================\"\necho \"  ACE-Step 1.5 - Linux AMD ROCm Edition\"\necho \"============================================\"\necho\n\n# Activate venv if it exists\nif [[ -f \"$VENV_DIR/bin/activate\" ]]; then\n    echo \"Activating virtual environment: $VENV_DIR\"\n    source \"$VENV_DIR/bin/activate\"\nelse\n    echo \"WARNING: venv_rocm not found at $VENV_DIR\"\n    echo \"Using system Python. See requirements-rocm-linux.txt for setup instructions.\"\nfi\necho\n\n# Verify ROCm PyTorch is installed\nif ! python3 -c \"\nimport torch\nassert torch.cuda.is_available(), 'No GPU detected'\nprint(f'GPU: {torch.cuda.get_device_name(0)}')\nhip = getattr(torch.version, 'hip', None)\nprint(f'HIP: {hip}' if hip else 'WARNING: Not a ROCm build')\n\" 2>/dev/null; then\n    echo\n    echo \"========================================\"\n    echo \" ERROR: ROCm PyTorch not detected!\"\n    echo \"========================================\"\n    echo\n    echo \"Please install ROCm PyTorch first.\"\n    echo \"See requirements-rocm-linux.txt for instructions.\"\n    echo\n    echo \"Quick setup:\"\n    echo \"  python3 -m venv venv_rocm\"\n    echo \"  source venv_rocm/bin/activate\"\n    echo \"  pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/rocm6.3\"\n    echo \"  pip install -r requirements-rocm-linux.txt\"\n    echo\n    exit 1\nfi\necho\n\necho \"Starting ACE-Step Gradio Web UI...\"\necho \"Server will be available at: http://${SERVER_NAME}:${PORT}\"\necho\n\n# Build command with optional parameters\nCMD=\"--port $PORT --server-name $SERVER_NAME --language $LANGUAGE\"\n[[ -n \"$SHARE\" ]] && CMD=\"$CMD $SHARE\"\n[[ -n \"$CONFIG_PATH\" ]] && CMD=\"$CMD $CONFIG_PATH\"\n[[ -n \"$LM_MODEL_PATH\" ]] && CMD=\"$CMD $LM_MODEL_PATH\"\n[[ -n \"$OFFLOAD_TO_CPU\" ]] && CMD=\"$CMD $OFFLOAD_TO_CPU\"\n[[ -n \"$INIT_LLM\" ]] && CMD=\"$CMD $INIT_LLM\"\n[[ -n \"$DOWNLOAD_SOURCE\" ]] && CMD=\"$CMD $DOWNLOAD_SOURCE\"\n[[ -n \"$INIT_SERVICE\" ]] && CMD=\"$CMD $INIT_SERVICE\"\n[[ -n \"$BACKEND\" ]] && CMD=\"$CMD $BACKEND\"\n[[ -n \"$ENABLE_API\" ]] && CMD=\"$CMD $ENABLE_API\"\n[[ -n \"$API_KEY\" ]] && CMD=\"$CMD $API_KEY\"\n[[ -n \"$AUTH_USERNAME\" ]] && CMD=\"$CMD $AUTH_USERNAME\"\n[[ -n \"$AUTH_PASSWORD\" ]] && CMD=\"$CMD $AUTH_PASSWORD\"\n\ncd \"$SCRIPT_DIR\" && python3 -u acestep/acestep_v15_pipeline.py $CMD\n"
  },
  {
    "path": "start_gradio_ui_rocm_manual.bat",
    "content": "@echo off\nsetlocal enabledelayedexpansion\nREM ACE-Step Gradio Web UI Launcher - AMD ROCm 7.2\nREM For AMD RX 7000/6000 series GPUs on Windows 11\nREM IMPORTANT: Requires Python 3.12 (AMD ROCm 7.2 only provides Python 3.12 wheels)\nREM Requires: ROCm PyTorch from repo.radeon.com\n\nREM ==================== Load .env Configuration ====================\nREM Load settings from .env file if it exists\ncall :LoadEnvFile\n\nREM ==================== Manual Startup Configuration ====================\nREM Ask for manual settings\ncall :LoadManual\n\nREM ==================== ROCm Configuration ====================\nREM Force PyTorch LM backend (bypasses nano-vllm flash_attn dependency)\nset ACESTEP_LM_BACKEND=pt\n\nREM RDNA3 GPU architecture override (RX 7900 XT/XTX, RX 7800 XT, etc.)\nREM Change to 11.0.1 for gfx1101 (RX 7700 XT, RX 7800 XT)\nREM Change to 11.0.2 for gfx1102 (RX 7600)\nset HSA_OVERRIDE_GFX_VERSION=11.0.0\n\nREM Disable torch.compile Triton backend (not available on ROCm Windows)\nset TORCH_COMPILE_BACKEND=eager\n\nREM MIOpen: use fast heuristic kernel selection instead of exhaustive benchmarking\nREM Without this, first-run VAE decode hangs for minutes on each conv layer\nset MIOPEN_FIND_MODE=FAST\n\nREM HuggingFace tokenizer parallelism\nset TOKENIZERS_PARALLELISM=false\n\nREM ==================== Server Configuration ====================\nREM Default values (used if not set in .env file)\nREM You can override these by uncommenting and modifying the lines below\nREM or by creating a .env file (recommended to survive updates)\n\nif not defined PORT set PORT=7860\nif not defined SERVER_NAME set SERVER_NAME=127.0.0.1\nREM set SERVER_NAME=0.0.0.0\nREM set SHARE=--share\n\nREM UI language: en, zh, ja\nif not defined LANGUAGE set LANGUAGE=en\n\nREM Batch size: default batch size for generation (1 to GPU-dependent max)\nREM When not specified, defaults to min(2, GPU_max)\nREM set BATCH_SIZE=--batch_size 4\n\nREM ==================== Model Configuration ====================\nif not defined CONFIG_PATH set CONFIG_PATH=--config_path acestep-v15-turbo\nif not defined LM_MODEL_PATH set LM_MODEL_PATH=--lm_model_path acestep-5Hz-lm-4B\n\nREM CPU offload: required for 4B LM on GPUs with <=20GB VRAM\nREM Models shuttle between CPU/GPU as needed (DiT stays on GPU, LM/VAE/text_encoder move on demand)\nREM Adds ~8-10s overhead per generation but prevents VRAM oversubscription\nREM Disable if using 1.7B/0.6B LM or if your GPU has >=24GB VRAM\nif not defined OFFLOAD_TO_CPU set OFFLOAD_TO_CPU=--offload_to_cpu true\n\nREM LLM initialization: auto (default), true, false\nREM set INIT_LLM=--init_llm auto\n\nREM Download source: auto, huggingface, modelscope\nif not defined DOWNLOAD_SOURCE set DOWNLOAD_SOURCE=\n\nREM Auto-initialize models on startup\nif not defined INIT_SERVICE set INIT_SERVICE=--init_service true\n\nREM LM backend: pt (PyTorch) recommended for ROCm\nset BACKEND=--backend pt\n\nREM API settings\nREM set ENABLE_API=--enable-api\nREM set API_KEY=--api-key sk-your-secret-key\n\nREM Authentication\nREM set AUTH_USERNAME=--auth-username admin\nREM set AUTH_PASSWORD=--auth-password password\n\nREM Update check on startup (set to false to disable)\nset CHECK_UPDATE=true\nREM set CHECK_UPDATE=false\n\nREM ==================== Venv Configuration ====================\nREM Path to the ROCm virtual environment (relative to this script)\nset VENV_DIR=%~dp0venv_rocm\n\nREM ==================== Launch ====================\n\nREM ==================== Startup Update Check ====================\nif /i not \"%CHECK_UPDATE%\"==\"true\" goto :SkipUpdateCheck\n\nREM Find git: try PortableGit first, then system git\nset \"UPDATE_GIT_CMD=\"\nif exist \"%~dp0PortableGit\\bin\\git.exe\" (\n    set \"UPDATE_GIT_CMD=%~dp0PortableGit\\bin\\git.exe\"\n) else (\n    where git >nul 2>&1\n    if !ERRORLEVEL! EQU 0 (\n        for /f \"tokens=*\" %%i in ('where git 2^>nul') do (\n            if not defined UPDATE_GIT_CMD set \"UPDATE_GIT_CMD=%%i\"\n        )\n    )\n)\nif not defined UPDATE_GIT_CMD goto :SkipUpdateCheck\n\ncd /d \"%~dp0\"\n\"!UPDATE_GIT_CMD!\" rev-parse --git-dir >nul 2>&1\nif !ERRORLEVEL! NEQ 0 goto :SkipUpdateCheck\n\necho [Update] Checking for updates...\n\nfor /f \"tokens=*\" %%i in ('\"!UPDATE_GIT_CMD!\" rev-parse --abbrev-ref HEAD 2^>nul') do set UPDATE_BRANCH=%%i\nif \"!UPDATE_BRANCH!\"==\"\" set UPDATE_BRANCH=main\nfor /f \"tokens=*\" %%i in ('\"!UPDATE_GIT_CMD!\" rev-parse --short HEAD 2^>nul') do set UPDATE_LOCAL=%%i\n\n\"!UPDATE_GIT_CMD!\" fetch origin --quiet 2>nul\nif !ERRORLEVEL! NEQ 0 (\n    echo [Update] Network unreachable, skipping.\n    echo.\n    goto :SkipUpdateCheck\n)\n\nfor /f \"tokens=*\" %%i in ('\"!UPDATE_GIT_CMD!\" rev-parse --short origin/!UPDATE_BRANCH! 2^>nul') do set UPDATE_REMOTE=%%i\n\nif \"!UPDATE_REMOTE!\"==\"\" goto :SkipUpdateCheck\nif \"!UPDATE_LOCAL!\"==\"!UPDATE_REMOTE!\" (\n    echo [Update] Already up to date ^(!UPDATE_LOCAL!^).\n    echo.\n    goto :SkipUpdateCheck\n)\n\necho.\necho ========================================\necho   Update available!\necho ========================================\necho   Current: !UPDATE_LOCAL!  -^>  Latest: !UPDATE_REMOTE!\necho.\necho   Recent changes:\n\"!UPDATE_GIT_CMD!\" --no-pager log --oneline HEAD..origin/!UPDATE_BRANCH! 2>nul\necho.\n\nset /p UPDATE_NOW=\"Update now before starting? (Y/N): \"\nif /i \"!UPDATE_NOW!\"==\"Y\" (\n    if exist \"%~dp0check_update.bat\" (\n        call \"%~dp0check_update.bat\"\n    ) else (\n        echo Pulling latest changes...\n        \"!UPDATE_GIT_CMD!\" pull --ff-only origin !UPDATE_BRANCH! 2>nul\n        if !ERRORLEVEL! NEQ 0 (\n            echo [Update] Update failed. Please update manually.\n        )\n    )\n) else (\n    echo [Update] Skipped. Run check_update.bat to update later.\n)\necho.\n\n:SkipUpdateCheck\n\necho ============================================\necho   ACE-Step 1.5 - AMD ROCm 7.2 Edition\necho ============================================\necho.\n\nREM Activate venv if it exists\nif exist \"%VENV_DIR%\\Scripts\\activate.bat\" (\n    echo Activating virtual environment: %VENV_DIR%\n    call \"%VENV_DIR%\\Scripts\\activate.bat\"\n) else (\n    echo WARNING: venv_rocm not found at %VENV_DIR%\n    echo Using system Python. See requirements-rocm.txt for setup instructions.\n)\necho.\n\nREM Verify ROCm PyTorch is installed\npython -c \"import torch; assert torch.cuda.is_available(), 'No GPU detected'; print(f'GPU: {torch.cuda.get_device_name(0)}'); hip=getattr(torch.version,'hip',None); print(f'HIP: {hip}' if hip else 'WARNING: Not a ROCm build')\" 2>nul\nif !ERRORLEVEL! NEQ 0 (\n    echo.\n    echo ========================================\n    echo  ERROR: ROCm PyTorch not detected!\n    echo ========================================\n    echo.\n    echo Please install ROCm PyTorch first. See requirements-rocm.txt for instructions.\n    echo.\n    pause\n    exit /b 1\n)\necho.\n\necho Starting ACE-Step Gradio Web UI...\necho Server will be available at: http://%SERVER_NAME%:%PORT%\necho.\n\nREM Build command with optional parameters\nset \"CMD=--port %PORT% --server-name %SERVER_NAME% --language %LANGUAGE%\"\nif not \"%SHARE%\"==\"\" set \"CMD=!CMD! %SHARE%\"\nif not \"%CONFIG_PATH%\"==\"\" set \"CMD=!CMD! %CONFIG_PATH%\"\nif not \"%LM_MODEL_PATH%\"==\"\" set \"CMD=!CMD! %LM_MODEL_PATH%\"\nif not \"%OFFLOAD_TO_CPU%\"==\"\" set \"CMD=!CMD! %OFFLOAD_TO_CPU%\"\nif not \"%INIT_LLM%\"==\"\" set \"CMD=!CMD! %INIT_LLM%\"\nif not \"%DOWNLOAD_SOURCE%\"==\"\" set \"CMD=!CMD! %DOWNLOAD_SOURCE%\"\nif not \"%INIT_SERVICE%\"==\"\" set \"CMD=!CMD! %INIT_SERVICE%\"\nif not \"%BATCH_SIZE%\"==\"\" set \"CMD=!CMD! %BATCH_SIZE%\"\nif not \"%BACKEND%\"==\"\" set \"CMD=!CMD! %BACKEND%\"\nif not \"%ENABLE_API%\"==\"\" set \"CMD=!CMD! %ENABLE_API%\"\nif not \"%API_KEY%\"==\"\" set \"CMD=!CMD! %API_KEY%\"\nif not \"%AUTH_USERNAME%\"==\"\" set \"CMD=!CMD! %AUTH_USERNAME%\"\nif not \"%AUTH_PASSWORD%\"==\"\" set \"CMD=!CMD! %AUTH_PASSWORD%\"\n\npython -u acestep\\acestep_v15_pipeline.py !CMD!\n\npause\nendlocal\ngoto :eof\n\nREM ==================== Helper Functions ====================\n\n:LoadEnvFile\nREM Load environment variables from .env file if it exists\nset \"ENV_FILE=%~dp0.env\"\nif not exist \"%ENV_FILE%\" (\n    exit /b 0\n)\n\necho [Config] Loading configuration from .env file...\nfor /f \"usebackq tokens=1,* delims==\" %%a in (\"%ENV_FILE%\") do (\n    set \"line=%%a\"\n    set \"value=%%b\"\n    \n    REM Skip empty lines and comments\n    if not \"!line!\"==\"\" (\n        set \"first_char=!line:~0,1!\"\n        if not \"!first_char!\"==\"#\" (\n            REM Remove leading/trailing spaces from key\n            for /f \"tokens=* delims= \" %%x in (\"!line!\") do set \"key=%%x\"\n            \n            REM Map .env variable names to batch script variables\n            if /i \"!key!\"==\"ACESTEP_CONFIG_PATH\" (\n                if not \"!value!\"==\"\" set \"CONFIG_PATH=--config_path !value!\"\n            )\n            if /i \"!key!\"==\"ACESTEP_LM_MODEL_PATH\" (\n                if not \"!value!\"==\"\" set \"LM_MODEL_PATH=--lm_model_path !value!\"\n            )\n            if /i \"!key!\"==\"ACESTEP_INIT_LLM\" (\n                if not \"!value!\"==\"\" (\n                    if not \"!value!\"==\"auto\" set \"INIT_LLM=--init_llm !value!\"\n                )\n            )\n            if /i \"!key!\"==\"ACESTEP_DOWNLOAD_SOURCE\" (\n                if not \"!value!\"==\"\" (\n                    if not \"!value!\"==\"auto\" set \"DOWNLOAD_SOURCE=--download-source !value!\"\n                )\n            )\n            if /i \"!key!\"==\"ACESTEP_API_KEY\" (\n                if not \"!value!\"==\"\" set \"API_KEY=--api-key !value!\"\n            )\n            if /i \"!key!\"==\"PORT\" (\n                if not \"!value!\"==\"\" set \"PORT=!value!\"\n            )\n            if /i \"!key!\"==\"SERVER_NAME\" (\n                if not \"!value!\"==\"\" set \"SERVER_NAME=!value!\"\n            )\n            if /i \"!key!\"==\"LANGUAGE\" (\n                if not \"!value!\"==\"\" set \"LANGUAGE=!value!\"\n            )\n            if /i \"!key!\"==\"ACESTEP_BATCH_SIZE\" (\n                if not \"!value!\"==\"\" set \"BATCH_SIZE=--batch_size !value!\"\n            )\n        )\n    )\n)\necho [Config] Configuration loaded from .env\nexit /b 0\n\n:LoadManual\nREM Ask for manual settings\ncolor 0B\necho.\necho ======================================================\necho             ACE-Step Manual Launch Mode\necho ======================================================\necho.\n:manual_choice_ask\n    set /p MANUAL_CHOICE=\"Continue with manual configuration? (Y/N): \"\n    if /i \"%MANUAL_CHOICE%\"==\"Y\" (\n        goto manual_choice_done\n    )\n    if /i \"%MANUAL_CHOICE%\"==\"N\" (\n        color 07\n        echo.\n        echo Proceeding with automatic configuration...\n        echo.\n        exit /b 0\n    )\n    echo Invalid input. Please enter Y or N.\n    goto manual_choice_ask\n:manual_choice_done\n\necho.\necho -------------------- Update Settings --------------------\n:update_choice_ask\n    set /p UPDATE_CHOICE=\"Check for updates before launch? (Y/N): \"\n    if /i \"%UPDATE_CHOICE%\"==\"Y\" (\n        set CHECK_UPDATE=true\n        goto update_choice_done\n    )\n    if /i \"%UPDATE_CHOICE%\"==\"N\" (\n        set CHECK_UPDATE=false\n        goto update_choice_done\n    )\n    echo Invalid input. Please enter Y or N.\n    goto update_choice_ask\n:update_choice_done\n\necho.\necho -------------------- Select DiT Model --------------------\necho 1^) acestep-v15-base\necho 2^) acestep-v15-sft\necho 3^) acestep-v15-turbo  (Recommended)\necho 4^) acestep-v15-turbo-rl\necho.\n:dit_choice_ask\n    set /p DIT_CHOICE=\"Enter selection (1-4): \"\n    if \"%DIT_CHOICE%\"==\"1\" (\n        set CONFIG_PATH=--config_path acestep-v15-base\n        goto dit_choice_done\n    )\n    if \"%DIT_CHOICE%\"==\"2\" (\n        set CONFIG_PATH=--config_path acestep-v15-sft\n        goto dit_choice_done\n    )\n    if \"%DIT_CHOICE%\"==\"3\" (\n        set CONFIG_PATH=--config_path acestep-v15-turbo\n        goto dit_choice_done\n    )\n    if \"%DIT_CHOICE%\"==\"4\" (\n        set CONFIG_PATH=--config_path acestep-v15-turbo-rl\n        goto dit_choice_done\n    )\n    echo Invalid input. Please enter a number between 1 and 4.\n    goto dit_choice_ask\n:dit_choice_done\n\necho.\necho -------------------- Select LM Model --------------------\necho 1^) acestep-5Hz-lm-0.6B  (Recommended)\necho 2^) acestep-5Hz-lm-1.7B\necho 3^) acestep-5Hz-lm-4B\necho 4^) Launch without LM Model\necho.\n:lm_choice_ask\n    set /p LM_CHOICE=\"Enter selection (1-4): \"\n    if \"%LM_CHOICE%\"==\"1\" (\n        set LM_MODEL_PATH=--lm_model_path acestep-5Hz-lm-0.6B\n        set INIT_LLM=--init_llm true\n        goto lm_choice_done\n    )\n    if \"%LM_CHOICE%\"==\"2\" (\n        set LM_MODEL_PATH=--lm_model_path acestep-5Hz-lm-1.7B\n        set INIT_LLM=--init_llm true\n        goto lm_choice_done\n    )\n    if \"%LM_CHOICE%\"==\"3\" (\n        set LM_MODEL_PATH=--lm_model_path acestep-5Hz-lm-4B\n        set INIT_LLM=--init_llm true\n        goto lm_choice_done\n    )\n    if \"%LM_CHOICE%\"==\"4\" (\n        set LM_MODEL_PATH=\n        set INIT_LLM=--init_llm false\n        goto lm_choice_done\n    )\n    echo Invalid input. Please enter a number between 1 and 4.\n    goto lm_choice_ask\n:lm_choice_done\n\necho.\necho -------------------- CPU Offload Option --------------------\n:offload_choice_ask\n    set /p OFFLOAD_CHOICE=\"Enable CPU Offload? (Y/N): \"\n    if /i \"%OFFLOAD_CHOICE%\"==\"Y\" (\n        set OFFLOAD_TO_CPU=--offload_to_cpu true\n        goto offload_choice_done\n    )\n    if /i \"%OFFLOAD_CHOICE%\"==\"N\" (\n        set OFFLOAD_TO_CPU=--offload_to_cpu false\n        goto offload_choice_done\n    )\n    echo Invalid input. Please enter Y or N.\n    goto offload_choice_ask\n:offload_choice_done\n\ncolor 07\necho.\necho Manual configuration applied successfully.\necho.\nexit /b 0\n"
  },
  {
    "path": "start_gradio_ui_rocm_manual.sh",
    "content": "#!/usr/bin/env bash\n# ACE-Step Gradio Web UI Launcher - Linux AMD ROCm\n# For AMD RX 7000/6000 series GPUs on Linux\n# Requires: ROCm 6.x+ and ROCm PyTorch from https://pytorch.org/\n#\n# Setup:\n#   1. Install ROCm: https://rocm.docs.amd.com/projects/install-on-linux/\n#   2. Create venv:  python3 -m venv venv_rocm\n#   3. Activate:     source venv_rocm/bin/activate\n#   4. Install PyTorch for ROCm:\n#      pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/rocm6.3\n#   5. Install dependencies:\n#      pip install -r requirements-rocm-linux.txt\n#   6. Run this script: ./start_gradio_ui_rocm.sh\n\nset -euo pipefail\nSCRIPT_DIR=\"$(cd \"$(dirname \"${BASH_SOURCE[0]}\")\" && pwd)\"\n\n# ==================== Load .env Configuration ====================\n_load_env_file() {\n    local env_file=\"${SCRIPT_DIR}/.env\"\n    if [[ ! -f \"$env_file\" ]]; then\n        return 0\n    fi\n\n    echo \"[Config] Loading configuration from .env file...\"\n\n    while IFS='=' read -r key value || [[ -n \"$key\" ]]; do\n        [[ -z \"$key\" || \"$key\" =~ ^[[:space:]]*# ]] && continue\n\n        key=\"${key#\"${key%%[![:space:]]*}\"}\"\n        key=\"${key%\"${key##*[![:space:]]}\"}\"\n        value=\"${value#\"${value%%[![:space:]]*}\"}\"\n        value=\"${value%\"${value##*[![:space:]]}\"}\"\n\n        case \"$key\" in\n            ACESTEP_CONFIG_PATH)\n                [[ -n \"$value\" ]] && CONFIG_PATH=\"--config_path $value\"\n                ;;\n            ACESTEP_LM_MODEL_PATH)\n                [[ -n \"$value\" ]] && LM_MODEL_PATH=\"--lm_model_path $value\"\n                ;;\n            ACESTEP_INIT_LLM)\n                if [[ -n \"$value\" && \"$value\" != \"auto\" ]]; then\n                    INIT_LLM=\"--init_llm $value\"\n                fi\n                ;;\n            ACESTEP_DOWNLOAD_SOURCE)\n                if [[ -n \"$value\" && \"$value\" != \"auto\" ]]; then\n                    DOWNLOAD_SOURCE=\"--download-source $value\"\n                fi\n                ;;\n            ACESTEP_API_KEY)\n                [[ -n \"$value\" ]] && API_KEY=\"--api-key $value\"\n                ;;\n            PORT)\n                [[ -n \"$value\" ]] && PORT=\"$value\"\n                ;;\n            SERVER_NAME)\n                [[ -n \"$value\" ]] && SERVER_NAME=\"$value\"\n                ;;\n            LANGUAGE)\n                [[ -n \"$value\" ]] && LANGUAGE=\"$value\"\n                ;;\n        esac\n    done < \"$env_file\"\n\n    echo \"[Config] Configuration loaded from .env\"\n}\n\n_load_env_file\n\n# ==================== Manual Startup Configuration ====================\n# Ask for manual settings\n_load_manual() {\n    echo -e \"\\033[1;36m\"\n    echo \"======================================================\"\n    echo \"            ACE-Step Manual Launch Mode\"\n    echo \"======================================================\"\n    echo\n\n    while true; do\n        read -rp \"Continue with manual configuration? (Y/N): \" MANUAL_CHOICE\n        case \"$MANUAL_CHOICE\" in\n            [Yy])\n                break ;;\n            [Nn])\n                echo -e \"\\033[0m\"\n                echo \"Proceeding with automatic configuration...\"\n                echo\n                return 0 ;;\n            *)\n                echo \"Invalid input. Please enter Y or N.\" ;;\n        esac\n    done\n\n    echo\n    echo \"-------------------- Update Settings --------------------\"\n    while true; do\n        read -rp \"Check for updates before launch? (Y/N): \" UPDATE_CHOICE\n        case \"$UPDATE_CHOICE\" in\n            [Yy])\n                CHECK_UPDATE=\"true\"\n                break ;;\n            [Nn])\n                CHECK_UPDATE=\"false\"\n                break ;;\n            *)\n                echo \"Invalid input. Please enter Y or N.\" ;;\n        esac\n    done\n\n    echo\n    echo \"-------------------- Select DiT Model --------------------\"\n    echo \"1) acestep-v15-base\"\n    echo \"2) acestep-v15-sft\"\n    echo \"3) acestep-v15-turbo (Recommended)\"\n    echo \"4) acestep-v15-turbo-rl\"\n    echo\n    while true; do\n        read -rp \"Enter selection (1-4): \" DIT_CHOICE\n        case \"$DIT_CHOICE\" in\n            1)\n                CONFIG_PATH=\"--config_path acestep-v15-base\"\n                break ;;\n            2)\n                CONFIG_PATH=\"--config_path acestep-v15-sft\"\n                break ;;\n            3)\n                CONFIG_PATH=\"--config_path acestep-v15-turbo\"\n                break ;;\n            4)\n                CONFIG_PATH=\"--config_path acestep-v15-turbo-rl\"\n                break ;;\n            *)\n                echo \"Invalid input. Please enter a number between 1 and 4.\" ;;\n        esac\n    done\n\n    echo\n    echo \"-------------------- Select LM Model --------------------\"\n    echo \"1) acestep-5Hz-lm-0.6B (Recommended)\"\n    echo \"2) acestep-5Hz-lm-1.7B\"\n    echo \"3) acestep-5Hz-lm-4B\"\n    echo \"4) Launch without LM Model\"\n    echo\n    while true; do\n        read -rp \"Enter selection (1-4): \" LM_CHOICE\n        case \"$LM_CHOICE\" in\n            1)\n                LM_MODEL_PATH=\"--lm_model_path acestep-5Hz-lm-0.6B\"\n                INIT_LLM=\"--init_llm true\"\n                break ;;\n            2)\n                LM_MODEL_PATH=\"--lm_model_path acestep-5Hz-lm-1.7B\"\n                INIT_LLM=\"--init_llm true\"\n                break ;;\n            3)\n                LM_MODEL_PATH=\"--lm_model_path acestep-5Hz-lm-4B\"\n                INIT_LLM=\"--init_llm true\"\n                break ;;\n            4)\n                LM_MODEL_PATH=\"\"\n                INIT_LLM=\"--init_llm false\"\n                break ;;\n            *)\n                echo \"Invalid input. Please enter a number between 1 and 4.\" ;;\n        esac\n    done\n\n    echo\n    echo \"-------------------- CPU Offload Option --------------------\"\n    while true; do\n        read -rp \"Enable CPU Offload? (Y/N): \" OFFLOAD_CHOICE\n        case \"$OFFLOAD_CHOICE\" in\n            [Yy])\n                OFFLOAD_TO_CPU=\"--offload_to_cpu true\"\n                break ;;\n            [Nn])\n                OFFLOAD_TO_CPU=\"--offload_to_cpu false\"\n                break ;;\n            *)\n                echo \"Invalid input. Please enter Y or N.\" ;;\n        esac\n    done\n\n    echo -e \"\\033[0m\"\n    echo \"Manual configuration applied successfully.\"\n    echo\n}\n\n_load_manual\n\n# ==================== ROCm Configuration ====================\n# Force PyTorch LM backend (bypasses nano-vllm flash_attn dependency)\nexport ACESTEP_LM_BACKEND=\"pt\"\n\n# RDNA3 GPU architecture override (RX 7900 XT/XTX, RX 7800 XT, etc.)\n# Change to 11.0.1 for gfx1101 (RX 7700 XT, RX 7800 XT)\n# Change to 11.0.2 for gfx1102 (RX 7600)\nexport HSA_OVERRIDE_GFX_VERSION=\"${HSA_OVERRIDE_GFX_VERSION:-11.0.0}\"\n\n# MIOpen: use fast heuristic kernel selection instead of exhaustive benchmarking\n# Without this, first-run VAE decode hangs for minutes on each conv layer\nexport MIOPEN_FIND_MODE=\"FAST\"\n\n# HuggingFace tokenizer parallelism\nexport TOKENIZERS_PARALLELISM=\"false\"\n\n# ==================== Server Configuration ====================\n: \"${PORT:=7860}\"\n: \"${SERVER_NAME:=127.0.0.1}\"\n# SERVER_NAME=\"0.0.0.0\"\nSHARE=\"${SHARE:-}\"\n# SHARE=\"--share\"\n\n# Reset LANGUAGE if it contains an invalid value (e.g. system locale like en_CA:en)\ncase \"$LANGUAGE\" in\n    en|zh|he|ja) ;;\n    *) unset LANGUAGE ;;\nesac\n# UI language: en, zh, he, ja\n: \"${LANGUAGE:=en}\"\n\n# ==================== Model Configuration ====================\n: \"${CONFIG_PATH:=--config_path acestep-v15-turbo}\"\n: \"${LM_MODEL_PATH:=--lm_model_path acestep-5Hz-lm-4B}\"\n\n# CPU offload: required for 4B LM on GPUs with <=20GB VRAM\n# Disable if using 1.7B/0.6B LM or if your GPU has >=24GB VRAM\n: \"${OFFLOAD_TO_CPU:=--offload_to_cpu true}\"\n\n# LLM initialization: auto (default), true, false\nINIT_LLM=\"${INIT_LLM:-}\"\n# INIT_LLM=\"--init_llm auto\"\n\n# Download source: auto, huggingface, modelscope\nDOWNLOAD_SOURCE=\"${DOWNLOAD_SOURCE:-}\"\n\n# Auto-initialize models on startup\n: \"${INIT_SERVICE:=--init_service true}\"\n\n# LM backend: pt (PyTorch) recommended for ROCm\nBACKEND=\"--backend pt\"\n\n# API settings\nENABLE_API=\"${ENABLE_API:-}\"\n# ENABLE_API=\"--enable-api\"\nAPI_KEY=\"${API_KEY:-}\"\n# API_KEY=\"--api-key sk-your-secret-key\"\n\n# Authentication\nAUTH_USERNAME=\"${AUTH_USERNAME:-}\"\n# AUTH_USERNAME=\"--auth-username admin\"\nAUTH_PASSWORD=\"${AUTH_PASSWORD:-}\"\n# AUTH_PASSWORD=\"--auth-password password\"\n\n# Update check on startup (set to \"false\" to disable)\n: \"${CHECK_UPDATE:=true}\"\n\n# ==================== Venv Configuration ====================\nVENV_DIR=\"${SCRIPT_DIR}/venv_rocm\"\n\n# ==================== Startup Update Check ====================\n_startup_update_check() {\n    [[ \"$CHECK_UPDATE\" != \"true\" ]] && return 0\n    command -v git &>/dev/null || return 0\n    cd \"$SCRIPT_DIR\" || return 0\n    git rev-parse --git-dir &>/dev/null 2>&1 || return 0\n\n    local branch commit remote_commit\n    branch=\"$(git rev-parse --abbrev-ref HEAD 2>/dev/null || echo \"main\")\"\n    commit=\"$(git rev-parse --short HEAD 2>/dev/null || echo \"\")\"\n    [[ -z \"$commit\" ]] && return 0\n\n    echo \"[Update] Checking for updates...\"\n\n    local fetch_ok=0\n    if command -v timeout &>/dev/null; then\n        timeout 10 git fetch origin --quiet 2>/dev/null && fetch_ok=1\n    else\n        git fetch origin --quiet 2>/dev/null && fetch_ok=1\n    fi\n\n    if [[ $fetch_ok -eq 0 ]]; then\n        echo \"[Update] Network unreachable, skipping.\"\n        echo\n        return 0\n    fi\n\n    remote_commit=\"$(git rev-parse --short \"origin/$branch\" 2>/dev/null || echo \"\")\"\n\n    if [[ -z \"$remote_commit\" || \"$commit\" == \"$remote_commit\" ]]; then\n        echo \"[Update] Already up to date ($commit).\"\n        echo\n        return 0\n    fi\n\n    echo\n    echo \"========================================\"\n    echo \"  Update available!\"\n    echo \"========================================\"\n    echo \"  Current: $commit  ->  Latest: $remote_commit\"\n    echo\n    echo \"  Recent changes:\"\n    git --no-pager log --oneline \"HEAD..origin/$branch\" 2>/dev/null | head -10\n    echo\n\n    read -rp \"Update now before starting? (Y/N): \" update_choice\n    if [[ \"${update_choice^^}\" == \"Y\" ]]; then\n        if [[ -f \"$SCRIPT_DIR/check_update.sh\" ]]; then\n            bash \"$SCRIPT_DIR/check_update.sh\"\n        else\n            echo \"Pulling latest changes...\"\n            git pull --ff-only origin \"$branch\" 2>/dev/null || {\n                echo \"[Update] Update failed. Please run: git pull\"\n            }\n        fi\n    else\n        echo \"[Update] Skipped. Run ./check_update.sh to update later.\"\n    fi\n    echo\n}\n_startup_update_check\n\necho \"============================================\"\necho \"  ACE-Step 1.5 - Linux AMD ROCm Edition\"\necho \"============================================\"\necho\n\n# Activate venv if it exists\nif [[ -f \"$VENV_DIR/bin/activate\" ]]; then\n    echo \"Activating virtual environment: $VENV_DIR\"\n    source \"$VENV_DIR/bin/activate\"\nelse\n    echo \"WARNING: venv_rocm not found at $VENV_DIR\"\n    echo \"Using system Python. See requirements-rocm-linux.txt for setup instructions.\"\nfi\necho\n\n# Verify ROCm PyTorch is installed\nif ! python3 -c \"\nimport torch\nassert torch.cuda.is_available(), 'No GPU detected'\nprint(f'GPU: {torch.cuda.get_device_name(0)}')\nhip = getattr(torch.version, 'hip', None)\nprint(f'HIP: {hip}' if hip else 'WARNING: Not a ROCm build')\n\" 2>/dev/null; then\n    echo\n    echo \"========================================\"\n    echo \" ERROR: ROCm PyTorch not detected!\"\n    echo \"========================================\"\n    echo\n    echo \"Please install ROCm PyTorch first.\"\n    echo \"See requirements-rocm-linux.txt for instructions.\"\n    echo\n    echo \"Quick setup:\"\n    echo \"  python3 -m venv venv_rocm\"\n    echo \"  source venv_rocm/bin/activate\"\n    echo \"  pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/rocm6.3\"\n    echo \"  pip install -r requirements-rocm-linux.txt\"\n    echo\n    exit 1\nfi\necho\n\necho \"Starting ACE-Step Gradio Web UI...\"\necho \"Server will be available at: http://${SERVER_NAME}:${PORT}\"\necho\n\n# Build command with optional parameters\nCMD=\"--port $PORT --server-name $SERVER_NAME --language $LANGUAGE\"\n[[ -n \"$SHARE\" ]] && CMD=\"$CMD $SHARE\"\n[[ -n \"$CONFIG_PATH\" ]] && CMD=\"$CMD $CONFIG_PATH\"\n[[ -n \"$LM_MODEL_PATH\" ]] && CMD=\"$CMD $LM_MODEL_PATH\"\n[[ -n \"$OFFLOAD_TO_CPU\" ]] && CMD=\"$CMD $OFFLOAD_TO_CPU\"\n[[ -n \"$INIT_LLM\" ]] && CMD=\"$CMD $INIT_LLM\"\n[[ -n \"$DOWNLOAD_SOURCE\" ]] && CMD=\"$CMD $DOWNLOAD_SOURCE\"\n[[ -n \"$INIT_SERVICE\" ]] && CMD=\"$CMD $INIT_SERVICE\"\n[[ -n \"$BACKEND\" ]] && CMD=\"$CMD $BACKEND\"\n[[ -n \"$ENABLE_API\" ]] && CMD=\"$CMD $ENABLE_API\"\n[[ -n \"$API_KEY\" ]] && CMD=\"$CMD $API_KEY\"\n[[ -n \"$AUTH_USERNAME\" ]] && CMD=\"$CMD $AUTH_USERNAME\"\n[[ -n \"$AUTH_PASSWORD\" ]] && CMD=\"$CMD $AUTH_PASSWORD\"\n\ncd \"$SCRIPT_DIR\" && python3 -u acestep/acestep_v15_pipeline.py $CMD\n"
  },
  {
    "path": "start_gradio_ui_xpu.bat",
    "content": "@echo off\nsetlocal enabledelayedexpansion\nREM ACE-Step Gradio Web UI Launcher - Intel XPU\nREM For Intel Arc GPUs (A770, A750, A580, A380) and integrated graphics\nREM Requires: Python 3.11, PyTorch XPU nightly from download.pytorch.org/whl/xpu\nREM IMPORTANT: Uses torch.xpu backend with SYCL/Level Zero acceleration\n\nREM ==================== Load .env Configuration ====================\nREM Load settings from .env file if it exists\ncall :LoadEnvFile\n\nREM ==================== XPU Configuration ====================\nREM XPU performance optimization (from verified working setup)\nset SYCL_CACHE_PERSISTENT=1\nset SYCL_PI_LEVEL_ZERO_USE_IMMEDIATE_COMMANDLISTS=1\nset PYTORCH_DEVICE=xpu\n\nREM Disable torch.compile (not fully supported on XPU yet)\nset TORCH_COMPILE_BACKEND=eager\n\nREM HuggingFace tokenizer parallelism\nset TOKENIZERS_PARALLELISM=false\n\nREM Force torchaudio to use ffmpeg backend (torchcodec not available on XPU)\nset TORCHAUDIO_USE_BACKEND=ffmpeg\n\nREM ==================== Server Configuration ====================\nREM Default values (used if not set in .env file)\nREM You can override these by uncommenting and modifying the lines below\nREM or by creating a .env file (recommended to survive updates)\n\nif not defined PORT set PORT=7860\nif not defined SERVER_NAME set SERVER_NAME=127.0.0.1\nREM set SERVER_NAME=0.0.0.0\nREM set SHARE=--share\n\nREM UI language: en, zh, ja\nif not defined LANGUAGE set LANGUAGE=en\n\nREM Batch size: default batch size for generation (1 to GPU-dependent max)\nREM When not specified, defaults to min(2, GPU_max)\nREM set BATCH_SIZE=--batch_size 4\n\nREM ==================== Model Configuration ====================\nREM Default model (can be overridden in .env file)\nif not defined CONFIG_PATH set CONFIG_PATH=--config_path acestep-v15-turbo\nif not defined LM_MODEL_PATH set LM_MODEL_PATH=--lm_model_path acestep-5Hz-lm-4B\n\nREM CPU offload: recommended for 4B LM on GPUs with <=16GB VRAM\nREM Models shuttle between CPU/GPU as needed (DiT stays on GPU, LM/VAE/text_encoder move on demand)\nREM Adds ~8-10s overhead per generation but prevents VRAM oversubscription\nREM Disable if using 1.7B/0.6B LM or if your GPU has >=20GB VRAM\nif not defined OFFLOAD_TO_CPU set OFFLOAD_TO_CPU=--offload_to_cpu true\n\nREM LLM initialization: auto (default), true, false\nREM set INIT_LLM=--init_llm auto\n\nREM Download source: auto, huggingface, modelscope\nif not defined DOWNLOAD_SOURCE set DOWNLOAD_SOURCE=\n\nREM Auto-initialize models on startup\nif not defined INIT_SERVICE set INIT_SERVICE=--init_service true\n\nREM API settings\nREM set ENABLE_API=--enable-api\nREM set API_KEY=--api-key sk-your-secret-key\n\nREM Authentication\nREM set AUTH_USERNAME=--auth-username admin\nREM set AUTH_PASSWORD=--auth-password password\n\nREM Update check on startup (set to false to disable)\nset CHECK_UPDATE=true\nREM set CHECK_UPDATE=false\n\nREM ==================== Venv Configuration ====================\nREM Path to the XPU virtual environment (relative to this script)\nset VENV_DIR=%~dp0venv_xpu\n\nREM ==================== Launch ====================\n\nREM ==================== Startup Update Check ====================\nif /i not \"%CHECK_UPDATE%\"==\"true\" goto :SkipUpdateCheck\n\nREM Find git: try PortableGit first, then system git\nset \"UPDATE_GIT_CMD=\"\nif exist \"%~dp0PortableGit\\bin\\git.exe\" (\n    set \"UPDATE_GIT_CMD=%~dp0PortableGit\\bin\\git.exe\"\n) else (\n    where git >nul 2>&1\n    if !ERRORLEVEL! EQU 0 (\n        for /f \"tokens=*\" %%i in ('where git 2^>nul') do (\n            if not defined UPDATE_GIT_CMD set \"UPDATE_GIT_CMD=%%i\"\n        )\n    )\n)\nif not defined UPDATE_GIT_CMD goto :SkipUpdateCheck\n\ncd /d \"%~dp0\"\n\"!UPDATE_GIT_CMD!\" rev-parse --git-dir >nul 2>&1\nif !ERRORLEVEL! NEQ 0 goto :SkipUpdateCheck\n\necho [Update] Checking for updates...\n\nfor /f \"tokens=*\" %%i in ('\"!UPDATE_GIT_CMD!\" rev-parse --abbrev-ref HEAD 2^>nul') do set UPDATE_BRANCH=%%i\nif \"!UPDATE_BRANCH!\"==\"\" set UPDATE_BRANCH=main\nfor /f \"tokens=*\" %%i in ('\"!UPDATE_GIT_CMD!\" rev-parse --short HEAD 2^>nul') do set UPDATE_LOCAL=%%i\n\n\"!UPDATE_GIT_CMD!\" fetch origin --quiet 2>nul\nif !ERRORLEVEL! NEQ 0 (\n    echo [Update] Network unreachable, skipping.\n    echo.\n    goto :SkipUpdateCheck\n)\n\nfor /f \"tokens=*\" %%i in ('\"!UPDATE_GIT_CMD!\" rev-parse --short origin/!UPDATE_BRANCH! 2^>nul') do set UPDATE_REMOTE=%%i\n\nif \"!UPDATE_REMOTE!\"==\"\" goto :SkipUpdateCheck\nif \"!UPDATE_LOCAL!\"==\"!UPDATE_REMOTE!\" (\n    echo [Update] Already up to date ^(!UPDATE_LOCAL!^).\n    echo.\n    goto :SkipUpdateCheck\n)\n\necho.\necho ========================================\necho   Update available!\necho ========================================\necho   Current: !UPDATE_LOCAL!  -^>  Latest: !UPDATE_REMOTE!\necho.\necho   Recent changes:\n\"!UPDATE_GIT_CMD!\" --no-pager log --oneline HEAD..origin/!UPDATE_BRANCH! 2>nul\necho.\n\nset /p UPDATE_NOW=\"Update now before starting? (Y/N): \"\nif /i \"!UPDATE_NOW!\"==\"Y\" (\n    if exist \"%~dp0check_update.bat\" (\n        call \"%~dp0check_update.bat\"\n    ) else (\n        echo Pulling latest changes...\n        \"!UPDATE_GIT_CMD!\" pull --ff-only origin !UPDATE_BRANCH! 2>nul\n        if !ERRORLEVEL! NEQ 0 (\n            echo [Update] Update failed. Please update manually.\n        )\n    )\n) else (\n    echo [Update] Skipped. Run check_update.bat to update later.\n)\necho.\n\n:SkipUpdateCheck\n\necho ============================================\necho   ACE-Step 1.5 - Intel XPU Edition\necho ============================================\necho.\n\nREM Activate venv if it exists\nif exist \"%VENV_DIR%\\Scripts\\activate.bat\" (\n    echo Activating XPU virtual environment: %VENV_DIR%\n    call \"%VENV_DIR%\\Scripts\\activate.bat\"\n) else (\n    echo ========================================\n    echo  ERROR: venv_xpu not found!\n    echo ========================================\n    echo.\n    echo Please create the XPU virtual environment first:\n    echo.\n    echo   1. Run: python -m venv venv_xpu\n    echo   2. Run: venv_xpu\\Scripts\\activate\n    echo   3. Run: pip install -r requirements-xpu.txt\n    echo.\n    echo Or use the setup script ^(if available^)\n    echo   setup_xpu.bat\n    echo.\n    pause\n    exit /b 1\n)\necho.\n\nREM Verify XPU PyTorch is installed\npython -c \"import torch; assert hasattr(torch, 'xpu') and torch.xpu.is_available(), 'Intel XPU not detected'; print(f'XPU: Intel Arc GPU detected'); print(f'PyTorch XPU version: {torch.__version__}')\" 2>nul\nif !ERRORLEVEL! NEQ 0 (\n    echo.\n    echo ========================================\n    echo  ERROR: Intel XPU PyTorch not detected!\n    echo ========================================\n    echo.\n    echo Please install PyTorch with XPU support. See requirements-xpu.txt for instructions.\n    echo.\n    echo Quick setup:\n    echo   1. Activate venv: venv_xpu\\Scripts\\activate\n    echo   2. Install: pip install --upgrade pip\n    echo   3. Install XPyTorch: pip install -r requirements-xpu.txt\n    echo.\n    pause\n    exit /b 1\n)\necho.\n\necho Starting ACE-Step Gradio Web UI...\necho Server will be available at: http://%SERVER_NAME%:%PORT%\necho Default Model: acestep-v15-turbo\necho LM Model: acestep-5Hz-lm-4B (with CPU offload)\necho.\necho Select your model in the UI if needed!\necho.\n\nREM Build command with optional parameters\nset \"CMD=--port %PORT% --server-name %SERVER_NAME% --language %LANGUAGE%\"\nif not \"%SHARE%\"==\"\" set \"CMD=!CMD! %SHARE%\"\nif not \"%CONFIG_PATH%\"==\"\" set \"CMD=!CMD! %CONFIG_PATH%\"\nif not \"%LM_MODEL_PATH%\"==\"\" set \"CMD=!CMD! %LM_MODEL_PATH%\"\nif not \"%OFFLOAD_TO_CPU%\"==\"\" set \"CMD=!CMD! %OFFLOAD_TO_CPU%\"\nif not \"%INIT_LLM%\"==\"\" set \"CMD=!CMD! %INIT_LLM%\"\nif not \"%DOWNLOAD_SOURCE%\"==\"\" set \"CMD=!CMD! %DOWNLOAD_SOURCE%\"\nif not \"%INIT_SERVICE%\"==\"\" set \"CMD=!CMD! %INIT_SERVICE%\"\nif not \"%BATCH_SIZE%\"==\"\" set \"CMD=!CMD! %BATCH_SIZE%\"\nif not \"%ENABLE_API%\"==\"\" set \"CMD=!CMD! %ENABLE_API%\"\nif not \"%API_KEY%\"==\"\" set \"CMD=!CMD! %API_KEY%\"\nif not \"%AUTH_USERNAME%\"==\"\" set \"CMD=!CMD! %AUTH_USERNAME%\"\nif not \"%AUTH_PASSWORD%\"==\"\" set \"CMD=!CMD! %AUTH_PASSWORD%\"\n\npython -u acestep\\acestep_v15_pipeline.py !CMD!\n\npause\nendlocal\ngoto :eof\n\nREM ==================== Helper Functions ====================\n\n:LoadEnvFile\nREM Load environment variables from .env file if it exists\nset \"ENV_FILE=%~dp0.env\"\nif not exist \"%ENV_FILE%\" (\n    exit /b 0\n)\n\necho [Config] Loading configuration from .env file...\nfor /f \"usebackq tokens=1,* delims==\" %%a in (\"%ENV_FILE%\") do (\n    set \"line=%%a\"\n    set \"value=%%b\"\n    \n    REM Skip empty lines and comments\n    if not \"!line!\"==\"\" (\n        set \"first_char=!line:~0,1!\"\n        if not \"!first_char!\"==\"#\" (\n            REM Remove leading/trailing spaces from key\n            for /f \"tokens=* delims= \" %%x in (\"!line!\") do set \"key=%%x\"\n            \n            REM Map .env variable names to batch script variables\n            if /i \"!key!\"==\"ACESTEP_CONFIG_PATH\" (\n                if not \"!value!\"==\"\" set \"CONFIG_PATH=--config_path !value!\"\n            )\n            if /i \"!key!\"==\"ACESTEP_LM_MODEL_PATH\" (\n                if not \"!value!\"==\"\" set \"LM_MODEL_PATH=--lm_model_path !value!\"\n            )\n            if /i \"!key!\"==\"ACESTEP_INIT_LLM\" (\n                if not \"!value!\"==\"\" (\n                    if not \"!value!\"==\"auto\" set \"INIT_LLM=--init_llm !value!\"\n                )\n            )\n            if /i \"!key!\"==\"ACESTEP_DOWNLOAD_SOURCE\" (\n                if not \"!value!\"==\"\" (\n                    if not \"!value!\"==\"auto\" set \"DOWNLOAD_SOURCE=--download-source !value!\"\n                )\n            )\n            if /i \"!key!\"==\"ACESTEP_API_KEY\" (\n                if not \"!value!\"==\"\" set \"API_KEY=--api-key !value!\"\n            )\n            if /i \"!key!\"==\"PORT\" (\n                if not \"!value!\"==\"\" set \"PORT=!value!\"\n            )\n            if /i \"!key!\"==\"SERVER_NAME\" (\n                if not \"!value!\"==\"\" set \"SERVER_NAME=!value!\"\n            )\n            if /i \"!key!\"==\"LANGUAGE\" (\n                if not \"!value!\"==\"\" set \"LANGUAGE=!value!\"\n            )\n            if /i \"!key!\"==\"ACESTEP_BATCH_SIZE\" (\n                if not \"!value!\"==\"\" set \"BATCH_SIZE=--batch_size !value!\"\n            )\n            if /i \"!key!\"==\"ACESTEP_OFFLOAD_TO_CPU\" (\n                if not \"!value!\"==\"\" set \"OFFLOAD_TO_CPU=--offload_to_cpu !value!\"\n            )\n        )\n    )\n)\necho [Config] Configuration loaded from .env\nexit /b 0\n"
  },
  {
    "path": "start_gradio_ui_xpu_manual.bat",
    "content": "@echo off\nsetlocal enabledelayedexpansion\nREM ACE-Step Gradio Web UI Launcher - Intel XPU (Manual Mode)\nREM For Intel Arc GPUs (A770, A750, A580, A380) and integrated graphics\nREM Requires: Python 3.11, PyTorch XPU nightly from download.pytorch.org/whl/xpu\nREM IMPORTANT: Uses torch.xpu backend with SYCL/Level Zero acceleration\n\nREM ==================== Manual Startup Configuration ====================\nREM Run interactive prompts for manual settings\ncall :LoadManual\n\nREM ==================== XPU Configuration ====================\nREM XPU performance optimization (from verified working setup)\nset SYCL_CACHE_PERSISTENT=1\nset SYCL_PI_LEVEL_ZERO_USE_IMMEDIATE_COMMANDLISTS=1\nset PYTORCH_DEVICE=xpu\n\nREM Disable torch.compile (not fully supported on XPU yet)\nset TORCH_COMPILE_BACKEND=eager\n\nREM HuggingFace tokenizer parallelism\nset TOKENIZERS_PARALLELISM=false\n\nREM Force torchaudio to use ffmpeg backend (torchcodec not available on XPU)\nset TORCHAUDIO_USE_BACKEND=ffmpeg\n\nREM ==================== Server Configuration ====================\nREM Default values\n\nif not defined PORT set PORT=7860\nif not defined SERVER_NAME set SERVER_NAME=127.0.0.1\nREM set SERVER_NAME=0.0.0.0\nREM set SHARE=--share\n\nREM UI language: en, zh, ja\nif not defined LANGUAGE set LANGUAGE=en\n\nREM Batch size: default batch size for generation (1 to GPU-dependent max)\nREM When not specified, defaults to min(2, GPU_max)\nREM set BATCH_SIZE=--batch_size 4\n\nREM ==================== Model Configuration ====================\nREM Values set by LoadManual function\nREM CONFIG_PATH and LM_MODEL_PATH are set based on user input\n\nREM CPU offload: set by user in manual mode\nREM set OFFLOAD_TO_CPU=--offload_to_cpu true\n\nREM LLM initialization: set by user in manual mode\nREM set INIT_LLM=--init_llm auto\n\nREM Download source: auto, huggingface, modelscope\nif not defined DOWNLOAD_SOURCE set DOWNLOAD_SOURCE=\n\nREM Auto-initialize models on startup\nif not defined INIT_SERVICE set INIT_SERVICE=--init_service true\n\nREM API settings\nREM set ENABLE_API=--enable-api\nREM set API_KEY=--api-key sk-your-secret-key\n\nREM Authentication\nREM set AUTH_USERNAME=--auth-username admin\nREM set AUTH_PASSWORD=--auth-password password\n\nREM Update check on startup\nset CHECK_UPDATE=true\nREM set CHECK_UPDATE=false\n\nREM ==================== Venv Configuration ====================\nREM Path to the XPU virtual environment (relative to this script)\nset VENV_DIR=%~dp0venv_xpu\n\nREM ==================== Launch ====================\n\nREM ==================== Startup Update Check ====================\nif /i not \"%CHECK_UPDATE%\"==\"true\" goto :SkipUpdateCheck\n\nREM Find git: try PortableGit first, then system git\nset \"UPDATE_GIT_CMD=\"\nif exist \"%~dp0PortableGit\\bin\\git.exe\" (\n    set \"UPDATE_GIT_CMD=%~dp0PortableGit\\bin\\git.exe\"\n) else (\n    where git >nul 2>&1\n    if !ERRORLEVEL! EQU 0 (\n        for /f \"tokens=*\" %%i in ('where git 2^>nul') do (\n            if not defined UPDATE_GIT_CMD set \"UPDATE_GIT_CMD=%%i\"\n        )\n    )\n)\nif not defined UPDATE_GIT_CMD goto :SkipUpdateCheck\n\ncd /d \"%~dp0\"\n\"!UPDATE_GIT_CMD!\" rev-parse --git-dir >nul 2>&1\nif !ERRORLEVEL! NEQ 0 goto :SkipUpdateCheck\n\necho [Update] Checking for updates...\n\nfor /f \"tokens=*\" %%i in ('\"!UPDATE_GIT_CMD!\" rev-parse --abbrev-ref HEAD 2^>nul') do set UPDATE_BRANCH=%%i\nif \"!UPDATE_BRANCH!\"==\"\" set UPDATE_BRANCH=main\nfor /f \"tokens=*\" %%i in ('\"!UPDATE_GIT_CMD!\" rev-parse --short HEAD 2^>nul') do set UPDATE_LOCAL=%%i\n\n\"!UPDATE_GIT_CMD!\" fetch origin --quiet 2>nul\nif !ERRORLEVEL! NEQ 0 (\n    echo [Update] Network unreachable, skipping.\n    echo.\n    goto :SkipUpdateCheck\n)\n\nfor /f \"tokens=*\" %%i in ('\"!UPDATE_GIT_CMD!\" rev-parse --short origin/!UPDATE_BRANCH! 2^>nul') do set UPDATE_REMOTE=%%i\n\nif \"!UPDATE_REMOTE!\"==\"\" goto :SkipUpdateCheck\nif \"!UPDATE_LOCAL!\"==\"!UPDATE_REMOTE!\" (\n    echo [Update] Already up to date ^(!UPDATE_LOCAL!^).\n    echo.\n    goto :SkipUpdateCheck\n)\n\necho.\necho ========================================\necho   Update available!\necho ========================================\necho   Current: !UPDATE_LOCAL!  -^>  Latest: !UPDATE_REMOTE!\necho.\necho   Recent changes:\n\"!UPDATE_GIT_CMD!\" --no-pager log --oneline HEAD..origin/!UPDATE_BRANCH! 2>nul\necho.\n\nset /p UPDATE_NOW=\"Update now before starting? (Y/N): \"\nif /i \"!UPDATE_NOW!\"==\"Y\" (\n    if exist \"%~dp0check_update.bat\" (\n        call \"%~dp0check_update.bat\"\n    ) else (\n        echo Pulling latest changes...\n        \"!UPDATE_GIT_CMD!\" pull --ff-only origin !UPDATE_BRANCH! 2>nul\n        if !ERRORLEVEL! NEQ 0 (\n            echo [Update] Update failed. Please update manually.\n        )\n    )\n) else (\n    echo [Update] Skipped. Run check_update.bat to update later.\n)\necho.\n\n:SkipUpdateCheck\n\necho ============================================\necho   ACE-Step 1.5 - Intel XPU Edition\necho ============================================\necho.\n\nREM Activate venv if it exists\nif exist \"%VENV_DIR%\\Scripts\\activate.bat\" (\n    echo Activating XPU virtual environment: %VENV_DIR%\n    call \"%VENV_DIR%\\Scripts\\activate.bat\"\n) else (\n    echo ========================================\n    echo  ERROR: venv_xpu not found!\n    echo ========================================\n    echo.\n    echo Please create the XPU virtual environment first:\n    echo.\n    echo   1. Run: python -m venv venv_xpu\n    echo   2. Run: venv_xpu\\Scripts\\activate\n    echo   3. Run: pip install -r requirements-xpu.txt\n    echo.\n    pause\n    exit /b 1\n)\necho.\n\nREM Verify XPU PyTorch is installed\npython -c \"import torch; assert hasattr(torch, 'xpu') and torch.xpu.is_available(), 'Intel XPU not detected'; print(f'XPU: Intel Arc GPU detected'); print(f'PyTorch XPU version: {torch.__version__}')\" 2>nul\nif !ERRORLEVEL! NEQ 0 (\n    echo.\n    echo ========================================\n    echo  ERROR: Intel XPU PyTorch not detected!\n    echo ========================================\n    echo.\n    echo Please install PyTorch with XPU support. See requirements-xpu.txt for instructions.\n    echo.\n    pause\n    exit /b 1\n)\necho.\n\necho Starting ACE-Step Gradio Web UI...\necho Server will be available at: http://%SERVER_NAME%:%PORT%\nif defined CONFIG_PATH_DISPLAY echo DiT Model: %CONFIG_PATH_DISPLAY%\nif defined LM_MODEL_PATH_DISPLAY echo LM Model: %LM_MODEL_PATH_DISPLAY%\nif defined OFFLOAD_DISPLAY echo CPU Offload: %OFFLOAD_DISPLAY%\necho.\n\nREM Build command with optional parameters\nset \"CMD=--port %PORT% --server-name %SERVER_NAME% --language %LANGUAGE%\"\nif not \"%SHARE%\"==\"\" set \"CMD=!CMD! %SHARE%\"\nif not \"%CONFIG_PATH%\"==\"\" set \"CMD=!CMD! %CONFIG_PATH%\"\nif not \"%LM_MODEL_PATH%\"==\"\" set \"CMD=!CMD! %LM_MODEL_PATH%\"\nif not \"%OFFLOAD_TO_CPU%\"==\"\" set \"CMD=!CMD! %OFFLOAD_TO_CPU%\"\nif not \"%INIT_LLM%\"==\"\" set \"CMD=!CMD! %INIT_LLM%\"\nif not \"%DOWNLOAD_SOURCE%\"==\"\" set \"CMD=!CMD! %DOWNLOAD_SOURCE%\"\nif not \"%INIT_SERVICE%\"==\"\" set \"CMD=!CMD! %INIT_SERVICE%\"\nif not \"%BATCH_SIZE%\"==\"\" set \"CMD=!CMD! %BATCH_SIZE%\"\nif not \"%ENABLE_API%\"==\"\" set \"CMD=!CMD! %ENABLE_API%\"\nif not \"%API_KEY%\"==\"\" set \"CMD=!CMD! %API_KEY%\"\nif not \"%AUTH_USERNAME%\"==\"\" set \"CMD=!CMD! %AUTH_USERNAME%\"\nif not \"%AUTH_PASSWORD%\"==\"\" set \"CMD=!CMD! %AUTH_PASSWORD%\"\n\npython -u acestep\\acestep_v15_pipeline.py !CMD!\n\npause\nendlocal\ngoto :eof\n\nREM ==================== Helper Functions ====================\n\n:LoadManual\nREM Interactive prompts for manual configuration\ncolor 0B\necho.\necho ======================================================\necho             ACE-Step XPU Manual Launch Mode\necho ======================================================\necho.\n\nREM Check if venv exists first\nif not exist \"%~dp0venv_xpu\\Scripts\\activate.bat\" (\n    echo WARNING: venv_xpu not found!\n    echo.\n    echo Please create the XPU environment first:\n    echo   1. Run: python -m venv venv_xpu\n    echo   2. Run: venv_xpu\\Scripts\\activate\n    echo   3. Run: pip install -r requirements-xpu.txt\n    echo.\n    pause\n    exit /b 1\n)\n\n:manual_choice_ask\n    set /p MANUAL_CHOICE=\"Continue with manual configuration? (Y/N): \"\n    if /i \"%MANUAL_CHOICE%\"==\"Y\" (\n        goto manual_choice_done\n    )\n    if /i \"%MANUAL_CHOICE%\"==\"N\" (\n        echo.\n        echo Use automatic configuration instead.\n        echo Please run: start_gradio_ui_xpu.bat\n        echo.\n        color 07\n        pause\n        exit /b 0\n    )\n    echo Invalid input. Please enter Y or N.\n    goto manual_choice_ask\n:manual_choice_done\n\necho.\necho -------------------- Update Settings --------------------\n:update_choice_ask\n    set /p UPDATE_CHOICE=\"Check for updates before launch? (Y/N): \"\n    if /i \"%UPDATE_CHOICE%\"==\"Y\" (\n        set CHECK_UPDATE=true\n        goto update_choice_done\n    )\n    if /i \"%UPDATE_CHOICE%\"==\"N\" (\n        set CHECK_UPDATE=false\n        goto update_choice_done\n    )\n    echo Invalid input. Please enter Y or N.\n    goto update_choice_ask\n:update_choice_done\n\necho.\necho -------------------- Select DiT Model --------------------\necho Scanning available models...\necho.\n\nREM Scan checkpoints directory for available DiT models\nset MODEL_COUNT=0\nif exist \"%~dp0checkpoints\" (\n    for /d %%D in (\"%~dp0checkpoints\\acestep-v15-*\") do (\n        set /a MODEL_COUNT+=1\n    )\n)\n\nif %MODEL_COUNT% EQU 0 (\n    echo No acestep-v15 models found in checkpoints folder.\n    echo Using default: acestep-v15-turbo\n    set CONFIG_PATH=--config_path acestep-v15-turbo\n    set CONFIG_PATH_DISPLAY=acestep-v15-turbo ^(default^)\n) else (\n    echo Available DiT models:\n    echo 1^) acestep-v15-turbo  (Recommended - Fast generation^)\n    echo 2^) acestep-v15-base    (Base model^)\n    echo 3^) acestep-v15-sft     (Supervised fine-tuned^)\n    echo 4^) acestep-v15-turbo-rl  (RL optimized^)\n    echo.\n    :dit_choice_ask\n        set /p DIT_CHOICE=\"Enter selection (1-4): \"\n        if \"%DIT_CHOICE%\"==\"1\" (\n            set CONFIG_PATH=--config_path acestep-v15-turbo\n            set CONFIG_PATH_DISPLAY=acestep-v15-turbo\n            goto dit_choice_done\n        )\n        if \"%DIT_CHOICE%\"==\"2\" (\n            set CONFIG_PATH=--config_path acestep-v15-base\n            set CONFIG_PATH_DISPLAY=acestep-v15-base\n            goto dit_choice_done\n        )\n        if \"%DIT_CHOICE%\"==\"3\" (\n            set CONFIG_PATH=--config_path acestep-v15-sft\n            set CONFIG_PATH_DISPLAY=acestep-v15-sft\n            goto dit_choice_done\n        )\n        if \"%DIT_CHOICE%\"==\"4\" (\n            set CONFIG_PATH=--config_path acestep-v15-turbo-rl\n            set CONFIG_PATH_DISPLAY=acestep-v15-turbo-rl\n            goto dit_choice_done\n        )\n        echo Invalid input. Please enter a number between 1 and 4.\n        goto dit_choice_ask\n    :dit_choice_done\n)\n\necho.\necho -------------------- Select LM Model --------------------\necho 1^) acestep-5Hz-lm-0.6B  (Recommended - Fast, low VRAM^)\necho 2^) acestep-5Hz-lm-1.7B  (Balanced^)\necho 3^) acestep-5Hz-lm-4B    (Best quality - requires CPU offload^)\necho 4^) Launch without LM Model ^(DiT-only mode^)\necho.\n:lm_choice_ask\n    set /p LM_CHOICE=\"Enter selection (1-4): \"\n    if \"%LM_CHOICE%\"==\"1\" (\n        set LM_MODEL_PATH=--lm_model_path acestep-5Hz-lm-0.6B\n        set LM_MODEL_PATH_DISPLAY=acestep-5Hz-lm-0.6B\n        set INIT_LLM=--init_llm true\n        goto lm_choice_done\n    )\n    if \"%LM_CHOICE%\"==\"2\" (\n        set LM_MODEL_PATH=--lm_model_path acestep-5Hz-lm-1.7B\n        set LM_MODEL_PATH_DISPLAY=acestep-5Hz-lm-1.7B\n        set INIT_LLM=--init_llm true\n        goto lm_choice_done\n    )\n    if \"%LM_CHOICE%\"==\"3\" (\n        set LM_MODEL_PATH=--lm_model_path acestep-5Hz-lm-4B\n        set LM_MODEL_PATH_DISPLAY=acestep-5Hz-lm-4B\n        set INIT_LLM=--init_llm true\n        goto lm_choice_done\n    )\n    if \"%LM_CHOICE%\"==\"4\" (\n        set LM_MODEL_PATH=\n        set LM_MODEL_PATH_DISPLAY=None ^(DiT-only mode^)\n        set INIT_LLM=--init_llm false\n        goto lm_choice_done\n    )\n    echo Invalid input. Please enter a number between 1 and 4.\n    goto lm_choice_ask\n:lm_choice_done\n\necho.\necho -------------------- CPU Offload Option --------------------\nif \"%LM_CHOICE%\"==\"3\" (\n    echo NOTE: 4B LM model requires CPU offload on most GPUs\n    set OFFLOAD_TO_CPU=--offload_to_cpu true\n    set OFFLOAD_DISPLAY=Enabled ^(required for 4B LM^)\n    goto offload_choice_skip\n)\n\n:offload_choice_ask\n    set /p OFFLOAD_CHOICE=\"Enable CPU Offload? (Y/N): \"\n    if /i \"%OFFLOAD_CHOICE%\"==\"Y\" (\n        set OFFLOAD_TO_CPU=--offload_to_cpu true\n        set OFFLOAD_DISPLAY=Enabled\n        goto offload_choice_done\n    )\n    if /i \"%OFFLOAD_CHOICE%\"==\"N\" (\n        set OFFLOAD_TO_CPU=--offload_to_cpu false\n        set OFFLOAD_DISPLAY=Disabled\n        goto offload_choice_done\n    )\n    echo Invalid input. Please enter Y or N.\n    goto offload_choice_ask\n:offload_choice_done\n:offload_choice_skip\n\ncolor 07\necho.\necho ======================================================\necho Configuration Summary\necho ======================================================\necho DiT Model:    %CONFIG_PATH_DISPLAY%\necho LM Model:     %LM_MODEL_PATH_DISPLAY%\necho CPU Offload:  %OFFLOAD_DISPLAY%\necho Update Check: %CHECK_UPDATE%\necho.\necho Starting ACE-Step with these settings...\necho.\nexit /b 0\n"
  },
  {
    "path": "test_env_detection.bat",
    "content": "@echo off\nsetlocal enabledelayedexpansion\nREM Test Environment Auto-Detection\nREM This script tests the environment detection logic\n\necho ========================================\necho ACE-Step Environment Detection Test\necho ========================================\necho.\n\nREM Test 1: Check if python_embedded exists\necho [Test 1] Checking for python_embedded...\nif exist \"%~dp0python_embedded\\python.exe\" (\n    echo [PASS] python_embedded detected\n    echo Location: %~dp0python_embedded\\python.exe\n\n    REM Get Python version\n    \"%~dp0python_embedded\\python.exe\" --version\n) else (\n    echo [INFO] python_embedded not found\n)\necho.\n\nREM Test 2: Check if uv is available\necho [Test 2] Checking for uv command...\nwhere uv >nul 2>&1\nif !ERRORLEVEL! EQU 0 (\n    echo [PASS] uv detected\n\n    REM Get uv version\n    uv --version\n) else (\n    echo [INFO] uv not found in PATH\n    echo To install uv, run: powershell -c \"irm https://astral.sh/uv/install.ps1 | iex\"\n)\necho.\n\nREM Test 3: Check project.scripts in pyproject.toml\necho [Test 3] Checking project scripts...\nif exist \"%~dp0pyproject.toml\" (\n    echo [PASS] pyproject.toml found\n    echo.\n    echo Available scripts:\n    findstr /C:\"acestep = \" \"%~dp0pyproject.toml\"\n    findstr /C:\"acestep-api = \" \"%~dp0pyproject.toml\"\n    findstr /C:\"acestep-download = \" \"%~dp0pyproject.toml\"\n) else (\n    echo [FAIL] pyproject.toml not found\n)\necho.\n\nREM Test 4: Determine which environment will be used\necho [Test 4] Environment selection logic...\nif exist \"%~dp0python_embedded\\python.exe\" (\n    echo [RESULT] Will use: Embedded Python ^(python_embedded^)\n    echo Command: python_embedded\\python.exe acestep\\acestep_v15_pipeline.py\n) else (\n    where uv >nul 2>&1\n    if !ERRORLEVEL! EQU 0 (\n        echo [RESULT] Will use: uv package manager\n        echo Command: uv run acestep\n    ) else (\n        echo [ERROR] Neither python_embedded nor uv found!\n        echo Please install uv or extract the portable package.\n    )\n)\necho.\n\necho ========================================\necho Test Complete\necho ========================================\npause\n"
  },
  {
    "path": "test_env_detection.sh",
    "content": "#!/usr/bin/env bash\n# Test Environment Auto-Detection - Linux/macOS\n# This script tests the environment detection logic\n\nset -euo pipefail\nSCRIPT_DIR=\"$(cd \"$(dirname \"${BASH_SOURCE[0]}\")\" && pwd)\"\n\necho \"========================================\"\necho \"ACE-Step Environment Detection Test\"\necho \"========================================\"\necho\n\nOS_NAME=\"$(uname)\"\nARCH=\"$(uname -m)\"\necho \"[Info] Platform: $OS_NAME ($ARCH)\"\necho\n\n# Test 1: Check for uv\necho \"[Test 1] Checking for uv command...\"\nif command -v uv &>/dev/null; then\n    echo \"[PASS] uv detected\"\n    uv --version\nelif [[ -x \"$HOME/.local/bin/uv\" ]]; then\n    echo \"[PASS] uv detected at $HOME/.local/bin/uv (not in PATH)\"\n    \"$HOME/.local/bin/uv\" --version\nelif [[ -x \"$HOME/.cargo/bin/uv\" ]]; then\n    echo \"[PASS] uv detected at $HOME/.cargo/bin/uv (not in PATH)\"\n    \"$HOME/.cargo/bin/uv\" --version\nelse\n    echo \"[INFO] uv not found\"\n    echo \"To install uv, run: curl -LsSf https://astral.sh/uv/install.sh | sh\"\nfi\necho\n\n# Test 2: Check project.scripts in pyproject.toml\necho \"[Test 2] Checking project scripts...\"\nif [[ -f \"$SCRIPT_DIR/pyproject.toml\" ]]; then\n    echo \"[PASS] pyproject.toml found\"\n    echo\n    echo \"Available scripts:\"\n    grep -E \"^acestep\" \"$SCRIPT_DIR/pyproject.toml\" 2>/dev/null | head -5 || echo \"  (not found)\"\nelse\n    echo \"[FAIL] pyproject.toml not found\"\nfi\necho\n\n# Test 3: Check accelerator\necho \"[Test 3] Checking accelerator...\"\nif [[ \"$OS_NAME\" == \"Darwin\" && \"$ARCH\" == \"arm64\" ]]; then\n    echo \"[INFO] Apple Silicon - MLX backend available\"\n    echo \"  Recommended: ./start_gradio_ui_macos.sh\"\nelif [[ \"$OS_NAME\" == \"Linux\" ]]; then\n    if command -v nvidia-smi &>/dev/null; then\n        echo \"[INFO] NVIDIA CUDA GPU available\"\n        echo \"  Recommended: ./start_gradio_ui.sh\"\n    else\n        echo \"[INFO] No NVIDIA GPU detected - CPU mode\"\n        echo \"  Recommended: ./start_gradio_ui.sh\"\n    fi\nelse\n    echo \"[INFO] Platform: $OS_NAME $ARCH\"\nfi\necho\n\n# Test 4: Environment selection logic\necho \"[Test 4] Environment selection logic...\"\nif command -v uv &>/dev/null || [[ -x \"$HOME/.local/bin/uv\" ]] || [[ -x \"$HOME/.cargo/bin/uv\" ]]; then\n    echo \"[RESULT] Will use: uv package manager\"\n    echo \"Command: uv run acestep\"\nelse\n    echo \"[ERROR] uv not found!\"\n    echo \"Please install uv first.\"\nfi\necho\n\necho \"========================================\"\necho \"Test Complete\"\necho \"========================================\"\n"
  },
  {
    "path": "test_git_update.bat",
    "content": "@echo off\nsetlocal enabledelayedexpansion\nREM Test Git Update Check Functionality\nREM This script tests the update check without actually starting the application\n\necho ========================================\necho Test Git Update Check\necho ========================================\necho.\n\nREM Test 1: Check if PortableGit exists\necho [Test 1] Checking PortableGit...\nif exist \"%~dp0PortableGit\\bin\\git.exe\" (\n    echo [PASS] PortableGit found\n    \"%~dp0PortableGit\\bin\\git.exe\" --version\n) else (\n    echo [FAIL] PortableGit not found at: %~dp0PortableGit\\bin\\git.exe\n    echo.\n    echo Please install PortableGit:\n    echo   1. Download: https://git-scm.com/download/win\n    echo   2. Extract to: %~dp0PortableGit\\\n    echo.\n    goto :TestFailed\n)\necho.\n\nREM Test 2: Check if this is a git repository\necho [Test 2] Checking git repository...\n\"%~dp0PortableGit\\bin\\git.exe\" rev-parse --git-dir >nul 2>&1\nif !ERRORLEVEL! EQU 0 (\n    echo [PASS] Valid git repository\n    for /f \"tokens=*\" %%i in ('\"%~dp0PortableGit\\bin\\git.exe\" rev-parse --abbrev-ref HEAD 2^>nul') do set CURRENT_BRANCH=%%i\n    for /f \"tokens=*\" %%i in ('\"%~dp0PortableGit\\bin\\git.exe\" rev-parse --short HEAD 2^>nul') do set CURRENT_COMMIT=%%i\n    echo   Branch: !CURRENT_BRANCH!\n    echo   Commit: !CURRENT_COMMIT!\n) else (\n    echo [FAIL] Not a git repository\n    echo.\n    echo This directory is not a git repository.\n    echo Please clone from GitHub:\n    echo   git clone https://github.com/ace-step/ACE-Step-1.5.git\n    echo.\n    goto :TestFailed\n)\necho.\n\nREM Test 3: Check if check_update.bat exists\necho [Test 3] Checking check_update.bat...\nif exist \"%~dp0check_update.bat\" (\n    echo [PASS] check_update.bat found\n) else (\n    echo [FAIL] check_update.bat not found\n    goto :TestFailed\n)\necho.\n\nREM Test 4: Run update check\necho [Test 4] Running update check...\necho ========================================\necho.\n\ncall \"%~dp0check_update.bat\"\nset UPDATE_RESULT=!ERRORLEVEL!\n\necho.\necho ========================================\necho.\n\nif !UPDATE_RESULT! EQU 0 (\n    echo [Test 4] Update check completed successfully\n    echo   Result: Already up to date or updated\n) else if !UPDATE_RESULT! EQU 1 (\n    echo [Test 4] Update check failed\n    echo   Result: Error occurred\n) else if !UPDATE_RESULT! EQU 2 (\n    echo [Test 4] Update check skipped\n    echo   Result: Network timeout\n) else (\n    echo [Test 4] Unknown result: !UPDATE_RESULT!\n)\necho.\n\nREM Summary\necho ========================================\necho Test Summary\necho ========================================\necho.\n\nif !UPDATE_RESULT! LEQ 2 (\n    echo [PASS] All tests completed\n    echo.\n    echo The update check feature is working correctly.\n    echo You can now enable it in start_gradio_ui.bat:\n    echo   set CHECK_UPDATE=true\n) else (\n    echo [FAIL] Some tests failed\n    goto :TestFailed\n)\n\npause\nexit /b 0\n\n:TestFailed\necho.\necho ========================================\necho Test Failed\necho ========================================\necho.\necho Please fix the issues above and try again.\necho.\npause\nexit /b 1\n"
  },
  {
    "path": "test_git_update.sh",
    "content": "#!/usr/bin/env bash\n# Test Git Update Check Functionality - Linux/macOS\n# This script tests the update check without actually starting the application\n\nset -euo pipefail\nSCRIPT_DIR=\"$(cd \"$(dirname \"${BASH_SOURCE[0]}\")\" && pwd)\"\n\necho \"========================================\"\necho \"Test Git Update Check\"\necho \"========================================\"\necho\n\n# Test 1: Check if git is available\necho \"[Test 1] Checking git...\"\nif command -v git &>/dev/null; then\n    echo \"[PASS] git found\"\n    git --version\nelse\n    echo \"[FAIL] git not found\"\n    echo\n    if [[ \"$(uname)\" == \"Darwin\" ]]; then\n        echo \"Please install git:\"\n        echo \"  xcode-select --install\"\n        echo \"  or: brew install git\"\n    else\n        echo \"Please install git:\"\n        echo \"  Ubuntu/Debian: sudo apt install git\"\n        echo \"  CentOS/RHEL:   sudo yum install git\"\n        echo \"  Arch:          sudo pacman -S git\"\n    fi\n    echo\n    echo \"========================================\"\n    echo \"Test Failed\"\n    echo \"========================================\"\n    exit 1\nfi\necho\n\n# Test 2: Check if this is a git repository\necho \"[Test 2] Checking git repository...\"\ncd \"$SCRIPT_DIR\"\nif git rev-parse --git-dir &>/dev/null; then\n    echo \"[PASS] Valid git repository\"\n    CURRENT_BRANCH=\"$(git rev-parse --abbrev-ref HEAD 2>/dev/null || echo \"unknown\")\"\n    CURRENT_COMMIT=\"$(git rev-parse --short HEAD 2>/dev/null || echo \"unknown\")\"\n    echo \"  Branch: $CURRENT_BRANCH\"\n    echo \"  Commit: $CURRENT_COMMIT\"\nelse\n    echo \"[FAIL] Not a git repository\"\n    echo\n    echo \"This directory is not a git repository.\"\n    echo \"Please clone from GitHub:\"\n    echo \"  git clone https://github.com/ace-step/ACE-Step-1.5.git\"\n    echo\n    echo \"========================================\"\n    echo \"Test Failed\"\n    echo \"========================================\"\n    exit 1\nfi\necho\n\n# Test 3: Check if check_update.sh exists\necho \"[Test 3] Checking check_update.sh...\"\nif [[ -f \"$SCRIPT_DIR/check_update.sh\" ]]; then\n    echo \"[PASS] check_update.sh found\"\nelse\n    echo \"[FAIL] check_update.sh not found\"\n    echo\n    echo \"========================================\"\n    echo \"Test Failed\"\n    echo \"========================================\"\n    exit 1\nfi\necho\n\n# Test 4: Run update check\necho \"[Test 4] Running update check...\"\necho \"========================================\"\necho\n\nUPDATE_RESULT=0\nbash \"$SCRIPT_DIR/check_update.sh\" || UPDATE_RESULT=$?\n\necho\necho \"========================================\"\necho\n\ncase $UPDATE_RESULT in\n    0)\n        echo \"[Test 4] Update check completed successfully\"\n        echo \"  Result: Already up to date or updated\"\n        ;;\n    1)\n        echo \"[Test 4] Update check failed\"\n        echo \"  Result: Error occurred\"\n        ;;\n    2)\n        echo \"[Test 4] Update check skipped\"\n        echo \"  Result: Network timeout\"\n        ;;\n    *)\n        echo \"[Test 4] Unknown result: $UPDATE_RESULT\"\n        ;;\nesac\necho\n\n# Summary\necho \"========================================\"\necho \"Test Summary\"\necho \"========================================\"\necho\n\nif [[ $UPDATE_RESULT -le 2 ]]; then\n    echo \"[PASS] All tests completed\"\n    echo\n    echo \"The update check feature is working correctly.\"\n    echo \"You can now enable it in the launcher scripts:\"\n    echo \"  CHECK_UPDATE=\\\"true\\\"\"\nelse\n    echo \"[FAIL] Some tests failed\"\n    echo\n    echo \"========================================\"\n    echo \"Test Failed\"\n    echo \"========================================\"\n    exit 1\nfi\n"
  },
  {
    "path": "train.py",
    "content": "#!/usr/bin/env python3\n\"\"\"\nACE-Step Training V2 (Side-Step) -- CLI Entry Point\n\nUsage:\n    python train.py <subcommand> [args]\n\nSubcommands:\n    vanilla          Reproduce existing (bugged) training for backward compatibility\n    fixed            Corrected training: continuous timesteps + CFG dropout\n    estimate         Gradient sensitivity analysis (no training)\n\nExamples:\n    python train.py fixed --checkpoint-dir ./checkpoints --model-variant turbo \\\\\n        --dataset-dir ./preprocessed_tensors/jazz --output-dir ./lora_output/jazz\n\n    python train.py --help\n\nNote:\n    This is the upstream-integrated version of Side-Step. For the standalone\n    version with additional features and more frequent updates, visit:\n    https://github.com/koda-dernet/Side-Step\n\"\"\"\n\nfrom __future__ import annotations\n\nimport gc\nimport logging\nimport sys\n\n# ---------------------------------------------------------------------------\n# Logging setup (before any library imports that might configure logging)\n# ---------------------------------------------------------------------------\n\n_log_formatter = logging.Formatter(\n    \"%(asctime)s [%(levelname)s] %(name)s: %(message)s\",\n    datefmt=\"%Y-%m-%d %H:%M:%S\",\n)\n\n# Console (same as before)\n_console_handler = logging.StreamHandler()\n_console_handler.setLevel(logging.INFO)\n_console_handler.setFormatter(_log_formatter)\n\n# File (captures DEBUG+ including tracebacks)\n# Guard against read-only working directories (e.g. some Windows setups)\ntry:\n    _file_handler = logging.FileHandler(\"sidestep.log\", mode=\"a\", encoding=\"utf-8\")\n    _file_handler.setLevel(logging.DEBUG)\n    _file_handler.setFormatter(_log_formatter)\n    _log_handlers = [_console_handler, _file_handler]\nexcept OSError:\n    _log_handlers = [_console_handler]\n\nlogging.basicConfig(level=logging.DEBUG, handlers=_log_handlers)\nlogger = logging.getLogger(\"train\")\n\n\ndef _has_subcommand() -> bool:\n    \"\"\"Check if sys.argv contains a recognized subcommand or --help.\"\"\"\n    args = sys.argv[1:]\n    if \"--help\" in args or \"-h\" in args:\n        return True  # let argparse handle help\n    known = {\"vanilla\", \"fixed\", \"estimate\"}\n    return bool(known & set(args))\n\n\ndef _cleanup_gpu() -> None:\n    \"\"\"Release GPU memory between session-loop iterations.\"\"\"\n    gc.collect()\n    try:\n        import torch\n        if torch.cuda.is_available():\n            torch.cuda.empty_cache()\n    except ImportError:\n        pass\n\n\ndef _dispatch(args) -> int:\n    \"\"\"Route a parsed argparse.Namespace to the correct subcommand runner.\n\n    Returns an int exit code (0 = success).\n    \"\"\"\n    from acestep.training_v2.cli.common import validate_paths\n\n    # -- Preprocessing (wizard flow) ----------------------------------------\n    if getattr(args, \"preprocess\", False):\n        return _run_preprocess(args)\n\n    sub = args.subcommand\n\n    # All subcommands need path validation\n    if not validate_paths(args):\n        return 1\n\n    if sub == \"vanilla\":\n        from acestep.training_v2.cli.train_vanilla import run_vanilla\n        return run_vanilla(args)\n\n    elif sub == \"fixed\":\n        from acestep.training_v2.cli.train_fixed import run_fixed\n        return run_fixed(args)\n\n    elif sub == \"estimate\":\n        return _run_estimate(args)\n\n    else:\n        print(f\"[FAIL] Unknown subcommand: {sub}\", file=sys.stderr)\n        return 1\n\n\ndef main() -> int:\n    \"\"\"Entry point for Side-Step training CLI.\n\n    When invoked with a subcommand (``python train.py fixed ...``), runs\n    that subcommand once and exits.  When invoked without arguments,\n    launches the interactive wizard in a session loop so the user can\n    preprocess, train, and manage presets without restarting.\n    \"\"\"\n    # -- Direct CLI mode (subcommand given) ---------------------------------\n    if _has_subcommand():\n        from acestep.training_v2.cli.common import build_root_parser\n        parser = build_root_parser()\n        args = parser.parse_args()\n        return _dispatch(args)\n\n    # -- Interactive wizard session loop ------------------------------------\n    from acestep.training_v2.ui.wizard import run_wizard_session\n\n    last_code = 0\n    for args in run_wizard_session():\n        try:\n            last_code = _dispatch(args)\n        except Exception as exc:\n            logger.exception(\"Unhandled error in session loop\")\n            print(f\"[FAIL] {exc}\", file=sys.stderr)\n            last_code = 1\n        finally:\n            _cleanup_gpu()\n\n    return last_code\n\n\n# ===========================================================================\n# Subcommand implementations\n# ===========================================================================\n\ndef _run_preprocess(args) -> int:\n    \"\"\"Run the two-pass preprocessing pipeline.\"\"\"\n    from acestep.training_v2.preprocess import preprocess_audio_files\n\n    audio_dir = getattr(args, \"audio_dir\", None)\n    dataset_json = getattr(args, \"dataset_json\", None)\n    tensor_output = getattr(args, \"tensor_output\", None)\n\n    if not audio_dir and not dataset_json:\n        print(\"[FAIL] --audio-dir or --dataset-json is required for preprocessing.\", file=sys.stderr)\n        return 1\n    if not tensor_output:\n        print(\"[FAIL] --tensor-output is required for preprocessing.\", file=sys.stderr)\n        return 1\n\n    source_label = dataset_json if dataset_json else audio_dir\n\n    # Show summary and confirm before starting\n    print(\"\\n\" + \"=\" * 60)\n    print(\"  Preprocessing Summary\")\n    print(\"=\" * 60)\n    print(f\"  Source:        {source_label}\")\n    print(f\"  Output:        {tensor_output}\")\n    print(f\"  Checkpoint:    {args.checkpoint_dir}\")\n    print(f\"  Model variant: {args.model_variant}\")\n    print(f\"  Max duration:  {getattr(args, 'max_duration', 240.0)}s\")\n    print(\"=\" * 60)\n    print(\"[INFO] Two-pass pipeline (sequential model loading for low VRAM)\")\n\n    try:\n        result = preprocess_audio_files(\n            audio_dir=audio_dir,\n            output_dir=tensor_output,\n            checkpoint_dir=args.checkpoint_dir,\n            variant=args.model_variant,\n            max_duration=getattr(args, \"max_duration\", 240.0),\n            dataset_json=dataset_json,\n            device=getattr(args, \"device\", \"auto\"),\n            precision=getattr(args, \"precision\", \"auto\"),\n        )\n    except Exception as exc:\n        print(f\"[FAIL] Preprocessing failed: {exc}\", file=sys.stderr)\n        logger.exception(\"Preprocessing error\")\n        return 1\n    finally:\n        _cleanup_gpu()\n\n    print(f\"\\n[OK] Preprocessing complete:\")\n    print(f\"     Processed: {result['processed']}/{result['total']}\")\n    if result[\"failed\"]:\n        print(f\"     Failed:    {result['failed']}\")\n    print(f\"     Output:    {result['output_dir']}\")\n    print(f\"\\n[INFO] You can now train with:\")\n    print(f\"       python train.py fixed --dataset-dir {result['output_dir']} ...\")\n    return 0\n\n\ndef _run_estimate(args) -> int:\n    \"\"\"Run gradient sensitivity estimation.\"\"\"\n    import json as _json\n    from acestep.training_v2.estimate import run_estimation\n\n    num_batches = getattr(args, \"estimate_batches\", 5) or 5\n\n    # Show summary before starting\n    print(\"\\n\" + \"=\" * 60)\n    print(\"  Gradient Estimation Summary\")\n    print(\"=\" * 60)\n    print(f\"  Checkpoint:    {args.checkpoint_dir}\")\n    print(f\"  Model variant: {args.model_variant}\")\n    print(f\"  Dataset:       {args.dataset_dir}\")\n    print(f\"  Batches:       {num_batches}\")\n    print(f\"  Top-K:         {getattr(args, 'top_k', 16)}\")\n    print(f\"  Granularity:   {getattr(args, 'granularity', 'module')}\")\n    print(\"=\" * 60)\n    print(f\"[INFO] Running gradient estimation ({num_batches} batches) ...\")\n    try:\n        results = run_estimation(\n            checkpoint_dir=args.checkpoint_dir,\n            variant=args.model_variant,\n            dataset_dir=args.dataset_dir,\n            num_batches=num_batches,\n            batch_size=args.batch_size,\n            top_k=getattr(args, \"top_k\", 16) or 16,\n            granularity=getattr(args, \"granularity\", \"module\") or \"module\",\n        )\n    except Exception as exc:\n        print(f\"[FAIL] Estimation failed: {exc}\", file=sys.stderr)\n        logger.exception(\"Estimation error\")\n        return 1\n    finally:\n        _cleanup_gpu()\n\n    if not results:\n        print(\"[WARN] No results -- dataset may be empty or model incompatible.\")\n        return 1\n\n    # Display results\n    print(\"\\n\" + \"=\" * 60)\n    print(f\"  Top-{len(results)} Modules by Gradient Sensitivity\")\n    print(\"=\" * 60)\n    for i, entry in enumerate(results, 1):\n        print(f\"  {i:3d}. {entry['module']:<50s}  {entry['sensitivity']:.6f}\")\n    print(\"=\" * 60 + \"\\n\")\n\n    # Save to JSON\n    output_path = getattr(args, \"estimate_output\", None) or \"./estimate_results.json\"\n    try:\n        with open(output_path, \"w\") as f:\n            _json.dump(results, f, indent=2)\n        print(f\"[OK] Results saved to {output_path}\")\n    except OSError as exc:\n        print(f\"[WARN] Could not save results: {exc}\", file=sys.stderr)\n\n    return 0\n\n\n# ===========================================================================\n# Entry\n# ===========================================================================\n\nif __name__ == \"__main__\":\n    sys.exit(main())\n"
  },
  {
    "path": "ui/studio.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n    <meta charset=\"UTF-8\">\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no\">\n    <title>ACE-Step Studio (Pro)</title>\n    \n    <script src=\"https://unpkg.com/wavesurfer.js@7\"></script>\n    <script src=\"https://unpkg.com/wavesurfer.js@7/dist/plugins/regions.min.js\"></script>\n\n    <style>\n        :root {\n            --bg-color: #080808;\n            --card-bg: #141414;\n            --panel-bg: #1e1e1e;\n            --accent: #1DB954; \n            --accent-hover: #1ed760;\n            --text: #ffffff;\n            --muted: #b3b3b3;\n            --border: #333;\n            --input-bg: #2a2a2a;\n            --danger: #ff4444;\n            --gold: #FFD700;\n        }\n\n        * { box-sizing: border-box; }\n\n        body {\n            background-color: var(--bg-color);\n            color: var(--text);\n            font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, Helvetica, Arial, sans-serif;\n            margin: 0;\n            height: 100vh;\n            display: flex;\n            flex-direction: column;\n            overflow: hidden; \n        }\n\n        /* --- Header --- */\n        header {\n            background: var(--card-bg);\n            border-bottom: 1px solid var(--border);\n            padding: 12px 20px;\n            display: flex;\n            align-items: center;\n            justify-content: space-between;\n            flex-wrap: wrap;\n            gap: 10px;\n            z-index: 10;\n        }\n\n        h1 { margin: 0; font-size: 1.1rem; font-weight: 700; display: flex; align-items: center; gap: 10px; white-space: nowrap; }\n        .badge { font-size: 0.65rem; background: var(--accent); color: black; padding: 2px 6px; border-radius: 4px; font-weight: 800; }\n\n        .connection-bar {\n            display: flex;\n            gap: 8px;\n            align-items: center;\n            flex: 1;\n            justify-content: flex-end;\n            min-width: 200px;\n        }\n\n        /* --- Layout --- */\n        .main-container {\n            display: grid;\n            grid-template-columns: 350px 1fr;\n            flex: 1;\n            overflow: hidden; \n        }\n\n        /* --- Sidebar (Controls) --- */\n        .sidebar {\n            background: var(--panel-bg);\n            border-right: 1px solid var(--border);\n            padding: 20px;\n            overflow-y: auto;\n            display: flex;\n            flex-direction: column;\n            gap: 18px;\n        }\n\n        .control-group { margin-bottom: 0; }\n        label { display: block; font-size: 0.75rem; font-weight: 700; color: var(--muted); margin-bottom: 6px; text-transform: uppercase; letter-spacing: 0.5px; }\n        \n        input[type=\"text\"], input[type=\"number\"], input[type=\"url\"], select, textarea {\n            width: 100%;\n            background: var(--input-bg);\n            border: 1px solid var(--border);\n            color: var(--text);\n            padding: 12px; \n            border-radius: 8px;\n            font-size: 0.95rem; \n            outline: none;\n            -webkit-appearance: none; \n        }\n        \n        textarea { resize: vertical; min-height: 80px; font-family: monospace; }\n        input:focus, select:focus, textarea:focus { border-color: var(--accent); }\n\n        .row { display: flex; gap: 12px; }\n        .row > div { flex: 1; }\n\n        .range-container { display: flex; align-items: center; gap: 10px; padding: 5px 0; }\n        input[type=\"range\"] { flex: 1; accent-color: var(--accent); height: 20px; }\n        .range-val { width: 35px; text-align: right; font-size: 0.8rem; color: var(--accent); }\n\n        .checkbox-group { display: flex; align-items: center; gap: 12px; cursor: pointer; padding: 5px 0; }\n        input[type=\"checkbox\"] { width: 20px; height: 20px; accent-color: var(--accent); margin: 0; }\n\n        .btn {\n            width: 100%;\n            padding: 14px;\n            border: none;\n            border-radius: 50px;\n            font-weight: 700;\n            font-size: 0.95rem;\n            cursor: pointer;\n            text-transform: uppercase;\n            transition: 0.2s;\n            touch-action: manipulation;\n        }\n        .btn-primary { background: var(--accent); color: black; box-shadow: 0 4px 15px rgba(29, 185, 84, 0.3); }\n        .btn-primary:hover { background: var(--accent-hover); transform: translateY(-1px); }\n        .btn-primary:active { transform: translateY(1px); }\n        .btn-primary:disabled { background: #333; color: #666; cursor: not-allowed; box-shadow: none; transform: none; }\n\n        .file-upload { position: relative; display: inline-block; width: 100%; }\n        .file-upload input[type=\"file\"] { display: none; }\n        .file-upload-label {\n            display: flex;\n            align-items: center;\n            justify-content: center;\n            padding: 16px;\n            background: rgba(255, 255, 255, 0.05);\n            border: 1px dashed var(--muted);\n            border-radius: 8px;\n            cursor: pointer;\n            color: var(--muted);\n            font-size: 0.9rem;\n            transition: 0.2s;\n            text-align: center;\n        }\n        .file-upload-label:hover { border-color: var(--accent); color: var(--accent); background: rgba(29, 185, 84, 0.05); }\n\n        /* --- Content Area --- */\n        .content-area {\n            padding: 20px;\n            display: flex;\n            flex-direction: column;\n            gap: 20px;\n            overflow-y: auto;\n            background: linear-gradient(135deg, #101010 0%, #080808 100%);\n        }\n\n        #waveform-wrapper {\n            background: #111;\n            border-radius: 12px;\n            padding: 15px;\n            border: 1px solid #333;\n            min-height: 140px;\n            display: flex;\n            flex-direction: column;\n            justify-content: center;\n            position: relative;\n        }\n        #waveform-wrapper.empty { display: none; }\n        #waveform { width: 100%; }\n        \n        .region-info {\n            font-size: 0.8rem;\n            color: var(--gold);\n            margin-top: 12px;\n            display: flex;\n            justify-content: space-between;\n            align-items: center;\n        }\n\n        .transport-controls { display: flex; align-items: center; gap: 8px; }\n        .btn-icon {\n            background: rgba(255,255,255,0.1);\n            border: 1px solid var(--border);\n            color: var(--text);\n            width: 36px; height: 36px;\n            border-radius: 50%;\n            display: flex; align-items: center; justify-content: center;\n            cursor: pointer; transition: 0.2s; font-size: 0.9rem; padding: 0;\n        }\n        .btn-icon:hover { background: rgba(255,255,255,0.2); border-color: var(--accent); }\n        .btn-icon.active { background: var(--accent); color: black; border-color: var(--accent); }\n        .btn-icon.main { width: 44px; height: 44px; font-size: 1.1rem; background: var(--accent); color: black; border:none; }\n        .btn-icon.main:hover { transform: scale(1.05); filter: brightness(1.1); }\n\n        /* --- Logs & Smart Progress --- */\n        .log-console {\n            background: rgba(0,0,0,0.5);\n            border: 1px solid var(--border);\n            border-radius: 8px;\n            padding: 15px;\n            font-family: 'Courier New', monospace;\n            font-size: 0.8rem;\n            color: #ccc;\n            height: 120px;\n            overflow-y: auto;\n            white-space: pre-wrap;\n        }\n        .log-info { color: #888; }\n        .log-success { color: var(--accent); }\n        .log-error { color: var(--danger); }\n        .log-progress { color: var(--gold); }\n\n        .progress-container {\n            height: 8px;\n            background: rgba(255,255,255,0.1);\n            border-radius: 4px;\n            overflow: hidden;\n            margin-bottom: 10px;\n            display: none; /* Hidden until needed */\n            position: relative;\n        }\n        .progress-fill {\n            height: 100%;\n            width: 0%;\n            background: linear-gradient(90deg, var(--accent) 0%, var(--accent-hover) 100%);\n            transition: width 0.2s linear; /* Smooth linear movement */\n            box-shadow: 0 0 15px rgba(29, 185, 84, 0.5);\n        }\n        \n        .progress-text-overlay {\n            position: absolute;\n            top: -20px;\n            right: 0;\n            font-size: 0.75rem;\n            color: var(--accent);\n            font-weight: bold;\n        }\n\n        .results-grid {\n            display: grid;\n            grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));\n            gap: 15px;\n        }\n        .result-card {\n            background: var(--panel-bg);\n            border: 1px solid var(--border);\n            border-radius: 12px;\n            padding: 15px;\n            transition: transform 0.2s;\n        }\n        .result-card:hover { border-color: var(--accent); }\n        .result-meta { font-size: 0.8rem; color: var(--muted); margin-bottom: 10px; line-height: 1.4; }\n        audio { width: 100%; margin-top: 5px; height: 40px; }\n\n        @media (max-width: 768px) {\n            body { height: auto; min-height: 100vh; overflow-y: auto; }\n            .main-container { display: flex; flex-direction: column; overflow: visible; height: auto; }\n            header { position: sticky; top: 0; z-index: 100; box-shadow: 0 2px 10px rgba(0,0,0,0.5); }\n            .sidebar { width: 100%; border-right: none; border-bottom: 1px solid var(--border); overflow: visible; padding: 20px 15px; }\n            .content-area { overflow: visible; padding: 15px; min-height: 500px; }\n            .connection-bar { width: 100%; margin-top: 5px; }\n            .connection-bar label { display: none; }\n        }\n    </style>\n</head>\n<body>\n\n<header>\n    <h1>ACE-Step Studio <span class=\"badge\">PRO</span></h1>\n    <div class=\"connection-bar\">\n        <input type=\"url\" id=\"apiBase\" value=\"http://localhost:8001\" placeholder=\"API URL (e.g. http://localhost:8001)\">\n    </div>\n</header>\n\n<div class=\"main-container\">\n    <aside class=\"sidebar\">\n        <!-- Audio Input -->\n        <div class=\"control-group\">\n            <label>1. Source Audio (Reference)</label>\n            <div class=\"file-upload\">\n                <label for=\"audioUpload\" class=\"file-upload-label\" id=\"uploadLabel\">📁 Tap to Upload Audio</label>\n                <input type=\"file\" id=\"audioUpload\" accept=\"audio/*\">\n            </div>\n            <div style=\"font-size: 0.7rem; color: #666; margin-top: 5px;\">Required for Cover, Repaint, Lego & Extract.</div>\n        </div>\n\n        <!-- Task Configuration -->\n        <div class=\"control-group\">\n            <label for=\"taskType\">2. Task Mode</label>\n            <select id=\"taskType\">\n                <option value=\"text2music\">Text to Music (Generate)</option>\n                <option value=\"cover\">Style Transfer (Cover)</option>\n                <option value=\"repaint\">In-Painting (Repaint)</option>\n                <option value=\"lego\">Add Layer (Lego)</option>\n                <option value=\"extract\">Isolate Layer (Extract)</option>\n                <option value=\"complete\">Complete / Extend</option>\n            </select>\n        </div>\n\n        <div class=\"control-group\" id=\"trackNameGroup\" style=\"display:none;\">\n            <label for=\"trackName\">Target Layer</label>\n            <select id=\"trackName\">\n                <option value=\"vocals\">Vocals</option>\n                <option value=\"drums\">Drums</option>\n                <option value=\"bass\">Bass</option>\n                <option value=\"guitar\">Guitar</option>\n                <option value=\"piano\">Piano</option>\n                <option value=\"synth\">Synth</option>\n            </select>\n        </div>\n\n        <div class=\"control-group\">\n            <label for=\"prompt\">3. Style / Description</label>\n            <textarea id=\"prompt\" placeholder=\"e.g. 80s pop song, upbeat, female vocals\"></textarea>\n        </div>\n\n        <div class=\"control-group\">\n            <label for=\"lyrics\">Lyrics (Optional)</label>\n            <textarea id=\"lyrics\" placeholder=\"[Verse 1]&#10;...\" style=\"min-height: 60px;\"></textarea>\n        </div>\n\n        <div class=\"control-group\">\n            <label>4. Parameters</label>\n            <div class=\"row\">\n                <div>\n                    <label>Language</label>\n                    <input type=\"text\" id=\"vocalLanguage\" value=\"en\" placeholder=\"en/nl/fr\">\n                </div>\n                <div>\n                    <label>Duration (s)</label>\n                    <input type=\"number\" id=\"duration\" value=\"30\" min=\"10\" max=\"300\">\n                </div>\n            </div>\n            <div class=\"row\" style=\"margin-top: 10px;\">\n                <div>\n                    <label>Steps</label>\n                    <input type=\"number\" id=\"steps\" value=\"8\" min=\"1\" max=\"50\">\n                </div>\n                <div>\n                    <label>CFG Scale</label>\n                    <input type=\"number\" id=\"guidance\" value=\"7.0\" step=\"0.5\">\n                </div>\n            </div>\n        </div>\n\n        <div class=\"control-group\" id=\"strengthGroup\" style=\"display:none;\">\n            <label>Audio Influence</label>\n            <div class=\"range-container\">\n                <span style=\"font-size:0.7rem\">Creative</span>\n                <input type=\"range\" id=\"strength\" min=\"0\" max=\"100\" value=\"40\">\n                <span class=\"range-val\" id=\"strengthVal\">0.4</span>\n            </div>\n        </div>\n\n        <div class=\"checkbox-group\">\n            <input type=\"checkbox\" id=\"thinking\" checked>\n            <label for=\"thinking\" style=\"margin:0; color: #fff; font-size: 0.9rem;\">Use Reasoning (Thinking)</label>\n        </div>\n\n        <div style=\"margin-top: 10px;\">\n            <button id=\"submitBtn\" class=\"btn btn-primary\">✨ Generate Music</button>\n        </div>\n    </aside>\n\n    <main class=\"content-area\">\n        <div id=\"waveform-wrapper\" class=\"empty\">\n            <div style=\"display:flex; justify-content:space-between; align-items:center; margin-bottom:10px; flex-wrap: wrap; gap: 10px;\">\n                <h3 style=\"margin: 0; font-size: 0.9rem; color: #888;\">Reference Audio</h3>\n                <div class=\"transport-controls\">\n                    <button id=\"wsLoopBtn\" class=\"btn-icon\" title=\"Toggle Loop\">🔁</button>\n                    <button id=\"wsStopBtn\" class=\"btn-icon\" title=\"Stop\">⏹</button>\n                    <button id=\"wsPlayBtn\" class=\"btn-icon main\" title=\"Play/Pause\">▶</button>\n                    <span id=\"wsTimeDisplay\" style=\"font-family:monospace; font-size:0.8rem; color:var(--accent); margin-left:8px; min-width: 80px; text-align:right;\">0:00</span>\n                </div>\n            </div>\n            <div id=\"waveform\"></div>\n            <div class=\"region-info\">\n                <span id=\"regionText\" style=\"flex: 1;\">No region selected</span>\n                <button id=\"clearRegionBtn\" style=\"background:none; border:1px solid #444; color:#888; border-radius:4px; cursor:pointer; font-size:0.7rem; padding: 4px 8px;\">Clear</button>\n            </div>\n        </div>\n\n        <input type=\"hidden\" id=\"regionStart\" value=\"0\">\n        <input type=\"hidden\" id=\"regionEnd\" value=\"-1\">\n\n        <div id=\"statusArea\">\n            <div class=\"progress-container\" id=\"progressContainer\">\n                <span id=\"progressText\" class=\"progress-text-overlay\">0%</span>\n                <div class=\"progress-fill\" id=\"progressFill\"></div>\n            </div>\n            <div class=\"log-console\" id=\"logConsole\">\n                <div>Welcome to ACE-Step Studio. Ready.</div>\n            </div>\n        </div>\n\n        <div>\n            <h3 style=\"border-bottom: 1px solid #333; padding-bottom: 10px; margin-bottom: 15px; font-size: 1rem;\">Generated Results</h3>\n            <div id=\"resultsGrid\" class=\"results-grid\"></div>\n        </div>\n    </main>\n</div>\n\n<script>\n    // --- Configuration ---\n    const elements = {\n        apiBase: document.getElementById('apiBase'),\n        fileInput: document.getElementById('audioUpload'),\n        uploadLabel: document.getElementById('uploadLabel'),\n        taskType: document.getElementById('taskType'),\n        prompt: document.getElementById('prompt'),\n        lyrics: document.getElementById('lyrics'),\n        language: document.getElementById('vocalLanguage'),\n        duration: document.getElementById('duration'),\n        steps: document.getElementById('steps'),\n        guidance: document.getElementById('guidance'),\n        strength: document.getElementById('strength'),\n        strengthVal: document.getElementById('strengthVal'),\n        trackName: document.getElementById('trackName'),\n        trackNameGroup: document.getElementById('trackNameGroup'),\n        strengthGroup: document.getElementById('strengthGroup'),\n        thinking: document.getElementById('thinking'),\n        submitBtn: document.getElementById('submitBtn'),\n        logConsole: document.getElementById('logConsole'),\n        resultsGrid: document.getElementById('resultsGrid'),\n        waveformWrapper: document.getElementById('waveform-wrapper'),\n        regionStart: document.getElementById('regionStart'),\n        regionEnd: document.getElementById('regionEnd'),\n        regionText: document.getElementById('regionText'),\n        clearRegionBtn: document.getElementById('clearRegionBtn'),\n        progressContainer: document.getElementById('progressContainer'),\n        progressFill: document.getElementById('progressFill'),\n        progressText: document.getElementById('progressText'),\n        wsPlayBtn: document.getElementById('wsPlayBtn'),\n        wsStopBtn: document.getElementById('wsStopBtn'),\n        wsLoopBtn: document.getElementById('wsLoopBtn'),\n        wsTimeDisplay: document.getElementById('wsTimeDisplay')\n    };\n\n    let wavesurfer = null;\n    let wsRegions = null;\n    let activeRegion = null;\n    let uploadedFile = null;\n    const DEFAULT_AUDIO_VOLUME = 0.5;\n    const AUDIO_VOLUME_STORAGE_KEY = \"acestep.studio.audio.volume\";\n    const AUDIO_EPSILON = 0.001;\n    const managedAudioElements = new WeakSet();\n    let preferredAudioVolume = null;\n\n    // --- SMART PROGRESS CONFIGURATION (Ported from Hitster) ---\n    // This allows the bar to move smoothly even when server is thinking\n    const ESTIMATED_DURATION_SEC = 300; // 5 Minutes baseline\n    const UPDATE_INTERVAL_MS = 200;     // Update animation every 200ms\n    const BASE_INCREMENT = 100 / ((ESTIMATED_DURATION_SEC * 1000) / UPDATE_INTERVAL_MS);\n\n    // Mappings from server logs to percentages\n    const progressSteps = {\n        \"queued\": 0,\n        \"initializing\": 2,\n        \"llm usage\": 5,\n        \"processing source\": 10,\n        \"cuda gpu\": 15,\n        \"loading text_encoder\": 18,\n        \"loaded model\": 22,\n        \"dit diffusion\": 50,       // The long wait starts here\n        \"offloading model\": 80,\n        \"tiled_decode\": 90,\n        \"decoding\": 92,\n        \"downloading\": 95,\n        \"saving\": 98,\n        \"done\": 100\n    };\n\n    // State object for the smart progress bar\n    let progressState = { \n        current: 0, \n        target: 0, \n        speedMod: 1.0, \n        timerId: null \n    };\n\n    function clampVolume(value) {\n        if (value === null || value === undefined || value === '') return null;\n        const parsed = Number(value);\n        if (!Number.isFinite(parsed)) return null;\n        if (parsed < 0) return 0;\n        if (parsed > 1) return 1;\n        return parsed;\n    }\n\n    function isTrustedUserEvent(event) {\n        return Boolean(event && event.isTrusted);\n    }\n\n    function loadPreferredAudioVolume() {\n        try {\n            const raw = window.localStorage.getItem(AUDIO_VOLUME_STORAGE_KEY);\n            if (raw === null || raw === undefined || raw === '') return DEFAULT_AUDIO_VOLUME;\n            const parsed = clampVolume(raw);\n            return parsed === null ? DEFAULT_AUDIO_VOLUME : parsed;\n        } catch (_error) {\n            return DEFAULT_AUDIO_VOLUME;\n        }\n    }\n\n    function savePreferredAudioVolume(value) {\n        const clamped = clampVolume(value);\n        if (clamped === null) return;\n        preferredAudioVolume = clamped;\n        try {\n            window.localStorage.setItem(AUDIO_VOLUME_STORAGE_KEY, String(clamped));\n        } catch (_error) {\n            // Ignore storage failures (private mode / blocked storage).\n        }\n        if (wavesurfer && typeof wavesurfer.setVolume === 'function') {\n            wavesurfer.setVolume(clamped);\n        }\n    }\n\n    function applyPreferredVolumeToAudio(audioEl) {\n        if (!audioEl || preferredAudioVolume === null) return;\n        if (Math.abs(audioEl.volume - preferredAudioVolume) <= AUDIO_EPSILON) return;\n        audioEl.volume = preferredAudioVolume;\n    }\n\n    function syncAllAudioVolumes(sourceAudio = null) {\n        if (preferredAudioVolume === null) return;\n        document.querySelectorAll('audio').forEach((audioEl) => {\n            if (!audioEl) return;\n            if (sourceAudio && audioEl === sourceAudio) {\n                applyPreferredVolumeToAudio(audioEl);\n                return;\n            }\n            if (Math.abs(audioEl.volume - preferredAudioVolume) > AUDIO_EPSILON) {\n                audioEl.volume = preferredAudioVolume;\n            }\n        });\n        if (wavesurfer && typeof wavesurfer.setVolume === 'function') {\n            wavesurfer.setVolume(preferredAudioVolume);\n        }\n    }\n\n    function registerAudioElement(audioEl) {\n        if (!audioEl || managedAudioElements.has(audioEl)) return;\n        managedAudioElements.add(audioEl);\n        applyPreferredVolumeToAudio(audioEl);\n\n        audioEl.addEventListener('volumechange', (event) => {\n            if (!isTrustedUserEvent(event)) {\n                applyPreferredVolumeToAudio(audioEl);\n                return;\n            }\n            const next = clampVolume(audioEl.volume);\n            if (next === null) return;\n            if (preferredAudioVolume !== null && Math.abs(next - preferredAudioVolume) <= AUDIO_EPSILON) return;\n            savePreferredAudioVolume(next);\n            syncAllAudioVolumes(audioEl);\n        }, { passive: true });\n\n        audioEl.addEventListener('loadedmetadata', () => {\n            applyPreferredVolumeToAudio(audioEl);\n            if (audioEl.currentTime > 0) audioEl.currentTime = 0;\n        }, { passive: true });\n\n        audioEl.addEventListener('loadstart', () => {\n            applyPreferredVolumeToAudio(audioEl);\n            if (audioEl.currentTime > 0) audioEl.currentTime = 0;\n        }, { passive: true });\n    }\n\n    function scanAndRegisterAudioPlayers() {\n        document.querySelectorAll('audio').forEach(registerAudioElement);\n        syncAllAudioVolumes();\n    }\n\n    preferredAudioVolume = loadPreferredAudioVolume();\n    savePreferredAudioVolume(preferredAudioVolume);\n    scanAndRegisterAudioPlayers();\n\n    // --- UI Listeners ---\n    elements.strength.addEventListener('input', (e) => {\n        elements.strengthVal.innerText = (e.target.value / 100).toFixed(2);\n    });\n\n    elements.taskType.addEventListener('change', (e) => {\n        const type = e.target.value;\n        elements.strengthGroup.style.display = (type === 'cover' || type === 'lego') ? 'block' : 'none';\n        elements.trackNameGroup.style.display = (type === 'lego' || type === 'extract') ? 'block' : 'none';\n        if(['lego', 'extract', 'repaint', 'complete'].includes(type)) {\n            elements.thinking.checked = false;\n        } else {\n            elements.thinking.checked = true;\n        }\n    });\n\n    // --- WaveSurfer Logic ---\n    function initWaveSurfer() {\n        if(wavesurfer) return;\n        \n        wavesurfer = WaveSurfer.create({\n            container: '#waveform',\n            waveColor: '#1DB954',\n            progressColor: '#1ed760',\n            height: 80,\n            cursorColor: '#FF6B35',\n            cursorWidth: 2,\n            barWidth: 3,\n            barGap: 2,\n            barRadius: 3,\n            normalize: true,\n        });\n\n        wavesurfer.on('ready', () => {\n            const dur = wavesurfer.getDuration();\n            elements.wsTimeDisplay.innerText = `0:00 / ${formatTime(dur)}`;\n            if (preferredAudioVolume !== null && typeof wavesurfer.setVolume === 'function') {\n                wavesurfer.setVolume(preferredAudioVolume);\n            }\n        });\n\n        wavesurfer.on('audioprocess', (time) => {\n            const dur = wavesurfer.getDuration();\n            elements.wsTimeDisplay.innerText = `${formatTime(time)} / ${formatTime(dur)}`;\n        });\n\n        wavesurfer.on('play', () => elements.wsPlayBtn.innerText = \"⏸\");\n        wavesurfer.on('pause', () => elements.wsPlayBtn.innerText = \"▶\");\n        wavesurfer.on('finish', () => {\n            elements.wsPlayBtn.innerText = \"▶\";\n            if(elements.wsLoopBtn.classList.contains('active')) wavesurfer.play();\n        });\n\n        wsRegions = wavesurfer.registerPlugin(WaveSurfer.Regions.create());\n        wsRegions.enableDragSelection({ color: 'rgba(29, 185, 84, 0.3)' });\n\n        wsRegions.on('region-created', (region) => {\n            if (activeRegion) { activeRegion.remove(); }\n            activeRegion = region;\n            updateRegionInputs(region);\n        });\n\n        wsRegions.on('region-updated', (region) => updateRegionInputs(region));\n        wsRegions.on('region-out', (region) => {\n            if (elements.wsLoopBtn.classList.contains('active')) region.play();\n        });\n        wsRegions.on('region-clicked', (region, e) => {\n            e.stopPropagation();\n            region.play();\n        });\n    }\n\n    function formatTime(seconds) {\n        const m = Math.floor(seconds / 60);\n        const s = Math.floor(seconds % 60);\n        return `${m}:${s < 10 ? '0' : ''}${s}`;\n    }\n\n    function updateRegionInputs(region) {\n        elements.regionStart.value = region.start.toFixed(2);\n        elements.regionEnd.value = region.end.toFixed(2);\n        elements.regionText.innerText = `Selected: ${region.start.toFixed(1)}s - ${region.end.toFixed(1)}s`;\n    }\n\n    // --- Transport & File ---\n    elements.wsPlayBtn.addEventListener('click', () => { if(wavesurfer) wavesurfer.playPause(); });\n    elements.wsStopBtn.addEventListener('click', () => { \n        if(wavesurfer) { \n            wavesurfer.stop(); \n            elements.wsTimeDisplay.innerText = `0:00 / ${formatTime(wavesurfer.getDuration())}`;\n        } \n    });\n    elements.wsLoopBtn.addEventListener('click', () => { elements.wsLoopBtn.classList.toggle('active'); });\n    elements.clearRegionBtn.addEventListener('click', () => {\n        if(wsRegions) wsRegions.clearRegions();\n        elements.regionStart.value = 0;\n        elements.regionEnd.value = -1;\n        elements.regionText.innerText = \"No region selected\";\n        activeRegion = null;\n    });\n\n    window.addEventListener('resize', () => { if(wavesurfer) setTimeout(() => {}, 100); });\n\n    elements.fileInput.addEventListener('change', function(e) {\n        const file = e.target.files[0];\n        if (!file) return;\n        uploadedFile = file;\n        elements.uploadLabel.innerText = \"✅ \" + file.name;\n        elements.uploadLabel.style.borderColor = \"var(--accent)\";\n        elements.uploadLabel.style.color = \"var(--accent)\";\n        elements.waveformWrapper.classList.remove('empty');\n        initWaveSurfer();\n        wavesurfer.load(URL.createObjectURL(file));\n    });\n\n    // --- SMART PROGRESS LOGIC ---\n\n    function startSmartProgressBar() {\n        if (progressState.timerId) clearInterval(progressState.timerId);\n        \n        progressState.current = 0;\n        progressState.target = 0;\n        progressState.speedMod = 1.0;\n        \n        progressState.timerId = setInterval(() => {\n            const gap = progressState.target - progressState.current;\n\n            // 1. Determine Speed\n            if (gap > 0) {\n                // Behind target? Speed up to catch up\n                progressState.speedMod = 2.0 + (gap * 2); \n            } else if (gap < -5) {\n                // Way ahead? Slow down significantly\n                progressState.speedMod = 0.1;\n            } else {\n                // Cruise speed (simulates slow processing)\n                progressState.speedMod = 1.0;\n            }\n\n            // 2. Increment\n            progressState.current += BASE_INCREMENT * progressState.speedMod;\n\n            // 3. Clamp\n            // If target is 100, allow completion. Else cap at 99.5%\n            const hardLimit = (progressState.target >= 100) ? 100 : 99.5;\n            if (progressState.current > hardLimit) progressState.current = hardLimit;\n\n            // 4. Render\n            elements.progressFill.style.width = `${progressState.current}%`;\n            elements.progressText.innerText = `${progressState.current.toFixed(1)}%`;\n\n        }, UPDATE_INTERVAL_MS);\n    }\n\n    function stopSmartProgressBar() {\n        if (progressState.timerId) clearInterval(progressState.timerId);\n        elements.progressFill.style.width = '100%';\n        elements.progressText.innerText = '100%';\n    }\n\n    function updateProgressTarget(text) {\n        if (!text) return;\n        \n        const lastLog = elements.logConsole.lastElementChild;\n        if (!lastLog || lastLog.innerText.indexOf(text) === -1) {\n            log(text, \"log-progress\");\n        }\n\n        const t = text.toLowerCase();\n        let foundPercent = 0;\n\n        // Check against the Hitster map\n        for (const [key, percent] of Object.entries(progressSteps)) {\n            if (t.includes(key) && percent > foundPercent) {\n                foundPercent = percent;\n            }\n        }\n\n        // Only update if greater (never move target backwards)\n        if (foundPercent > progressState.target) {\n            progressState.target = foundPercent;\n        }\n    }\n\n    // --- API Logic ---\n\n    function log(msg, type = 'log-info') {\n        const div = document.createElement('div');\n        div.className = type;\n        div.innerText = `[${new Date().toLocaleTimeString()}] ${msg}`;\n        elements.logConsole.appendChild(div);\n        elements.logConsole.scrollTop = elements.logConsole.scrollHeight;\n    }\n\n    function getBaseUrl() {\n        return elements.apiBase.value.trim().replace(/\\/+$/, '');\n    }\n\n    elements.submitBtn.addEventListener('click', async () => {\n        const taskType = elements.taskType.value;\n        if (taskType !== 'text2music' && !uploadedFile) {\n            alert(\"Upload an audio file first!\");\n            return;\n        }\n\n        elements.submitBtn.disabled = true;\n        elements.progressContainer.style.display = 'block';\n        elements.logConsole.innerHTML = '';\n        log(\"Preparing task...\", \"log-info\");\n        \n        // Start the smart animator\n        startSmartProgressBar();\n\n        try {\n            const formData = new FormData();\n            formData.append('task_type', taskType);\n            formData.append('prompt', elements.prompt.value);\n            formData.append('lyrics', elements.lyrics.value);\n            formData.append('vocal_language', elements.language.value);\n            formData.append('thinking', elements.thinking.checked);\n            formData.append('batch_size', 1);\n            formData.append('inference_steps', elements.steps.value);\n            formData.append('guidance_scale', elements.guidance.value);\n            formData.append('audio_duration', elements.duration.value);\n            \n            if (taskType === 'cover' || taskType === 'lego') {\n                formData.append('audio_cover_strength', elements.strength.value / 100);\n            } else {\n                formData.append('audio_cover_strength', 1.0);\n            }\n\n            if (taskType === 'lego' || taskType === 'extract') {\n                formData.append('track_name', elements.trackName.value);\n            }\n\n            if (uploadedFile) {\n                formData.append('src_audio', uploadedFile);\n            }\n\n            if (taskType === 'repaint' || taskType === 'lego') {\n                formData.append('repainting_start', elements.regionStart.value);\n                formData.append('repainting_end', elements.regionEnd.value);\n            }\n\n            log(\"Uploading...\", \"log-info\");\n            const releaseRes = await fetch(`${getBaseUrl()}/release_task`, {\n                method: 'POST',\n                body: formData \n            });\n            const releaseData = await releaseRes.json();\n\n            if (releaseData.code !== 200 || !releaseData.data || !releaseData.data.task_id) {\n                throw new Error(releaseData.error || 'Failed to start task');\n            }\n\n            const taskId = releaseData.data.task_id;\n            log(`Task Started: ${taskId}`, \"log-success\");\n            startPolling(taskId);\n\n        } catch (e) {\n            log(`Error: ${e.message}`, \"log-error\");\n            stopSmartProgressBar();\n            elements.submitBtn.disabled = false;\n        }\n    });\n\n    async function startPolling(taskId) {\n        const pollInterval = 1500;\n        const maxTime = 900000; // 15 mins (increased for diffusion)\n        const startTime = Date.now();\n\n        const timer = setInterval(async () => {\n            if (Date.now() - startTime > maxTime) {\n                clearInterval(timer);\n                log(\"Timed out.\", \"log-error\");\n                stopSmartProgressBar();\n                elements.submitBtn.disabled = false;\n                return;\n            }\n\n            try {\n                const res = await fetch(`${getBaseUrl()}/query_result`, {\n                    method: 'POST',\n                    headers: { 'Content-Type': 'application/json' },\n                    body: JSON.stringify({ task_id_list: [taskId] })\n                });\n                const data = await res.json();\n\n                if (data.code === 200 && data.data && data.data.length > 0) {\n                    const task = data.data[0];\n                    \n                    // Update Smart Target\n                    updateProgressTarget(task.progress_text);\n\n                    if (task.status === 1) { // Success\n                        clearInterval(timer);\n                        stopSmartProgressBar(); // Force to 100%\n                        log(\"Done!\", \"log-success\");\n                        handleSuccess(task);\n                        elements.submitBtn.disabled = false;\n                    } else if (task.status === 2) { // Failed\n                        clearInterval(timer);\n                        stopSmartProgressBar();\n                        log(\"Task Failed.\", \"log-error\");\n                        elements.submitBtn.disabled = false;\n                    }\n                }\n            } catch (e) {\n                console.error(\"Poll error\", e);\n            }\n        }, pollInterval);\n    }\n\n    function handleSuccess(task) {\n        try {\n            let result = task.result;\n            if (typeof result === 'string') result = JSON.parse(result);\n            if (Array.isArray(result)) result = result[0];\n\n            const baseUrl = getBaseUrl();\n            const fileUrl = result.url || result.file;\n            const fullUrl = fileUrl.startsWith('http') ? fileUrl : `${baseUrl}/${fileUrl.replace(/^\\//, '')}`;\n\n            const card = document.createElement('div');\n            card.className = 'result-card';\n            \n            const metas = result.metas || {};\n            const metaHtml = `\n                <div class=\"result-meta\">\n                    <strong>${(result.prompt || elements.prompt.value).substring(0, 50)}...</strong><br>\n                    <span>BPM: ${metas.bpm || '-'} | Key: ${metas.keyscale || '-'} | Dur: ${metas.duration || '-'}s</span>\n                </div>\n            `;\n\n            card.innerHTML = `\n                ${metaHtml}\n                <audio controls src=\"${fullUrl}\"></audio>\n                <div style=\"margin-top:12px; display:flex; gap:10px;\">\n                    <a href=\"${fullUrl}\" download class=\"btn\" style=\"padding:10px; font-size:0.8rem; background:#333; text-decoration:none; color:white; text-align:center;\">Download</a>\n                </div>\n            `;\n\n            elements.resultsGrid.prepend(card);\n            scanAndRegisterAudioPlayers();\n        } catch (e) {\n            log(\"Parsing error: \" + e.message, \"log-error\");\n        }\n    }\n</script>\n\n</body>\n</html>\n"
  },
  {
    "path": "ui/studio_html_test.py",
    "content": "\"\"\"Unit tests for studio HTML audio volume persistence guards.\"\"\"\n\nfrom pathlib import Path\nimport unittest\n\n\nclass StudioHtmlVolumeGuardTests(unittest.TestCase):\n    \"\"\"Tests for trusted-event gating in studio volume persistence logic.\"\"\"\n\n    @classmethod\n    def setUpClass(cls):\n        \"\"\"Load studio HTML content once for all assertions.\"\"\"\n        cls._html = Path(__file__).with_name(\"studio.html\").read_text(encoding=\"utf-8\")\n\n    def test_contains_trusted_event_helper(self):\n        \"\"\"Success path: trusted-event helper should exist.\"\"\"\n        self.assertIn(\"function isTrustedUserEvent(event)\", self._html)\n        self.assertIn(\"event && event.isTrusted\", self._html)\n\n    def test_volumechange_listener_guards_non_trusted_events(self):\n        \"\"\"Regression path: listener should reject non-user volumechange events.\"\"\"\n        self.assertIn(\"audioEl.addEventListener('volumechange', (event) => {\", self._html)\n        self.assertIn(\"if (!isTrustedUserEvent(event)) {\", self._html)\n        self.assertIn(\"applyPreferredVolumeToAudio(audioEl);\", self._html)\n\n    def test_volume_defaults_on_missing_storage(self):\n        \"\"\"Missing localStorage value should seed and persist a sane default volume.\"\"\"\n        self.assertIn(\"const DEFAULT_AUDIO_VOLUME = 0.5;\", self._html)\n        self.assertIn(\"const raw = window.localStorage.getItem(AUDIO_VOLUME_STORAGE_KEY);\", self._html)\n        self.assertIn(\"if (raw === null || raw === undefined || raw === '') return DEFAULT_AUDIO_VOLUME;\", self._html)\n        self.assertIn(\"savePreferredAudioVolume(preferredAudioVolume);\", self._html)\n\n\nif __name__ == \"__main__\":\n    unittest.main()\n"
  }
]